[
  {
    "path": ".bazelignore",
    "content": ".git\n.github\ncompiler/compiler/Compiler/.build\nnpm_modules\nnode_modules\nbzl/valdi/npm/node_modules\ncompiler/companion/node_modules\ncompiler/companion/remotedebug-ios-webkit-adapter/node_modules\n\n# Ignore bazel output and symlink directory. Required by bazel-diff.\nbazel-bin\nbazel-client\nbazel-out\nbazel-testlogs\n"
  },
  {
    "path": ".bazelrc",
    "content": "try-import %workspace%/.bazelrc.internal\n\n# No bzlmod yet\ncommon --noenable_bzlmod\ncommon --enable_workspace\n\ncommon --bes_instance_name=client\ncommon --enable_platform_specific_config\n\n# Disable workers for repo fetching to prevent OOM\ncommon --experimental_worker_for_repo_fetching=off\n\n# android configuration\n# Expose AndroidResourceInfo provider to Kotlin rules\ncommon --experimental_google_legacy_api=true\ncommon --experimental_enable_android_migration_apis=true\ncommon --incompatible_java_common_parameters=false\n\n# Flags for compilation\ncommon --define enable_web=true\n\nbuild --tool_java_language_version=11\nbuild --java_language_version=11\n\n## Disable sandboxing for macs, both laptops and in CI; the performance hit is much too high.\nbuild:macos --spawn_strategy=local\nbuild:linux --sandbox_writable_path=/var/tmp\n\n# common cc configuration\nbuild --cxxopt=-std=c++20\nbuild --cxxopt=-Wno-ambiguous-reversed-operator\nbuild --cxxopt=-Wno-gcc-compat\nbuild --cxxopt=-Wno-nullability-extension\nbuild --cxxopt=-D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS\nbuild --host_cxxopt=-std=c++20\nbuild --host_cxxopt=-Wno-nullability-extension\n\n## we need to disable this due to a bug in bazel\n## see https://github.com/bazelbuild/bazel/issues/12381\nbuild --incompatible_use_specific_tool_files=false\nbuild --incompatible_enable_cc_toolchain_resolution\n\n# iOS and Apple cc changes and hacks\n## For Objective-C source files\nbuild --per_file_copt=.*\\.mm\\$@-std=c++20\nbuild --host_per_file_copt=.*\\.mm\\$@-std=c++20\nbuild --ios_minimum_os=12.0\n\n## TODO: (dchapp) this is currently needed otherwise -O0 and -DDEBUG=1 get passed to compilations of .mm/.m for production flavor builds\nbuild --experimental_objc_fastbuild_options=\"\"\n## HACK inject this in the default toolchain which is only used on macos until we switch to bazel_toolchains\nbuild:macos --copt=-fvisibility=hidden\n\n# java configuration\n## Disable some java checks for now, djinni generates code that errors out\nbuild --javacopt=-XepDisableAllChecks\nbuild --java_runtime_version=remotejdk_11\nbuild --tool_java_runtime_version=remotejdk_17\n\nbuild --flag_alias=snap_flavor=@snap_platforms//flavors:snap_flavor\nbuild --snap_flavor=client_development\n\nbuild --android_crosstool_top=@androidndk//:toolchain\nbuild --define=android_dexmerger_tool=d8_dexmerger\nbuild --define=android_incremental_dexing_tool=d8_dexbuilder\nbuild --define=android_standalone_dexing_tool=d8_compat_dx\nbuild --incremental_dexing\n\n# Disable 3rd party libs warnings\nbuild --per_file_copt=external/com_github_grpc_grpc/.*\\$@-Wno-everything\nbuild --per_file_copt=external/snap_protobuf/.*\\$@-Wno-everything\nbuild --per_file_copt=external/boringssl/.*\\$@-Wno-everything\nbuild --per_file_copt=external/com_github_google_flatbuffers/.*\\$@-Wno-everything\n\n# Enable persistent worker for Valdi compilation\nbuild --strategy=ValdiCompile=worker\n\n## Disable sandboxing for macs, both laptops and in CI; the performance hit is much too high.\nbuild:macos --spawn_strategy=local\nbuild:linux --sandbox_writable_path=/var/tmp\n\n# Disable disk cache to save disk space\n# https://docs.google.com/document/d/1N8W_M83n9jhMi7pgUhXuEuxypb3dmlHBu_CG_eXipXI/edit?usp=sharing\nbuild --disk_cache=\"\"\n\n# common build configuration\nbuild --experimental_generate_json_trace_profile\n# enable grpc log\nbuild --remote_grpc_log=/tmp/snap_client_grpc.log\nbuild --experimental_reuse_sandbox_directories\n\n# Default JS engine\nbuild --flag_alias=valdi_js_engine=@valdi//bzl/valdi:js_engine\nbuild --valdi_js_engine=hermes\n\n# Valdi Open Source Flags\nbuild --define=open_source_build=true\n\ncommon --@aspect_rules_ts//ts:skipLibCheck=always\n"
  },
  {
    "path": ".bazelversion",
    "content": "7.2.1"
  },
  {
    "path": ".cursorrules",
    "content": "# Valdi Open Source - Cursor Rules\n\n## ⚠️ Open Source Project\n\nThis is an open source project. Never commit secrets, API keys, or proprietary information.\n\n## 🚨 CRITICAL: This is NOT React!\n\nValdi uses TSX/JSX syntax but is **fundamentally different from React**. \n\n**Common AI mistakes:**\n- ❌ Suggesting `useState`, `useEffect`, `useContext` (don't exist!)\n- ❌ Functional components (don't exist!)\n- ❌ `this.props` (should be `this.viewModel`)\n- ❌ `markNeedsRender()`, `onMount()`, `onUpdate()` (wrong names/don't exist!)\n\n**Correct Valdi:**\n- ✅ `class MyComponent extends StatefulComponent`\n- ✅ `state = {}` + `this.setState()`\n- ✅ `this.viewModel` for props\n- ✅ `onCreate()`, `onViewModelUpdate()`, `onDestroy()` lifecycle\n\n## 📁 Context-Specific Rules\n\nCursor automatically loads additional rules based on where you're working:\n\n| Working In | See |\n|-----------|-----|\n| TypeScript/TSX components | `.cursor/rules/typescript-tsx.md` |\n| Swift compiler | `.cursor/rules/compiler.md` |\n| C++ runtime | `.cursor/rules/cpp-runtime.md` |\n| Android (Kotlin) | `.cursor/rules/android.md` |\n| iOS (Objective-C) | `.cursor/rules/ios.md` |\n| Bazel files | `.cursor/rules/bazel.md` |\n| Tests | `.cursor/rules/testing.md` |\n\n**→ Check `.cursor/rules/README.md` for the full list**\n\n## Quick Commands\n\n```bash\nbazel build //...          # Build everything\nbazel test //...           # Run all tests\nvaldi install ios          # Build & install iOS app\nvaldi hotreload            # Start hot reload\n```\n\n## More Information\n\n- **Comprehensive guide**: `/AGENTS.md` (621 lines)\n- **AI tooling**: `/docs/docs/ai-tooling.md`\n- **Support**: `/SUPPORT.md`\n- **Discord**: https://discord.gg/uJyNEeYX2U\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{ts,tsx,js,jsx}]\nindent_style = space\nindent_size = 2\n\n[*.{cpp,hpp,h,cc}]\nindent_style = space\nindent_size = 4\n\n[*.{swift,kt,java}]\nindent_style = space\nindent_size = 4\n\n[*.{yml,yaml,json}]\nindent_style = space\nindent_size = 2\n\n[*.{bzl,bazel,BUILD}]\nindent_style = space\nindent_size = 4\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[*.{mm,m}]\nindent_style = space\nindent_size = 4\n\n[Makefile]\nindent_style = tab\n"
  },
  {
    "path": ".gitattributes",
    "content": "third-party/** linguist-generated=true\n\n# Git LFS for open source\nbin/compiler/** filter=lfs diff=lfs merge=lfs -text\nbin/clientsql/** filter=lfs diff=lfs merge=lfs -text\nbin/compiler_companion/** filter=lfs diff=lfs merge=lfs -text\nbin/valdi_standalone filter=lfs diff=lfs merge=lfs -text\nbin/pngquant/** filter=lfs diff=lfs merge=lfs -text\nthird-party/skia/libs/** filter=lfs diff=lfs merge=lfs -text\nthird-party/jscore/libs/** filter=lfs diff=lfs merge=lfs -text\nthird-party/v8/libs/** filter=lfs diff=lfs merge=lfs -text\nthird-party/resvg/resvg_libs/libs/** filter=lfs diff=lfs merge=lfs -text\n\n# Ensure incompatible files are not tracked for git-lfs\nthird-party/skia/libs/.gitattributes !filter !diff !merge text\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Development platform (please complete the following information):**\n - OS: [e.g. iOS]\n - Valdi version [e.g. beta-0.0.1, main]\n\n**Target platform (please complete the following information):**\n - Device: [e.g. iPhone6]\n - OS: [e.g. iOS8.1]\n - Version [e.g. 22]\n\n**Additional context**\nAdd any other context about the problem here."
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation.md",
    "content": "---\nname: Documentation Improvement\nabout: Suggest improvements to documentation\ntitle: '[DOCS] '\nlabels: documentation\nassignees: ''\n\n---\n\n**What documentation needs improvement?**\n<!-- Specify the file, section, or topic that needs improvement -->\n\n**What's unclear or missing?**\n<!-- Describe what's confusing, incomplete, or missing -->\n\n**Suggested changes:**\n<!-- If you have specific suggestions for how to improve the documentation, please share them here -->\n\n**Additional context:**\n<!-- Add any other context, screenshots, or examples that would help -->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here."
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "## Description\n<!-- Provide a clear and concise description of your changes -->\n\n## Type of Change\n- [ ] Bug fix (non-breaking change that fixes an issue)\n- [ ] Documentation improvement\n- [ ] Performance optimization\n- [ ] Test improvement\n- [ ] Other (please describe)\n\n## Testing\n- [ ] Tests pass locally (`bazel test //...`)\n- [ ] Added/updated tests for changes (if applicable)\n- [ ] Tested on multiple platforms (iOS/Android/Web/macOS as applicable)\n- [ ] Manual testing performed (describe below)\n\n### Testing Details\n<!-- Describe the testing you performed -->\n\n## Checklist\n- [ ] Code follows project style guidelines\n- [ ] Documentation updated (if needed)\n- [ ] No breaking changes (or documented in description)\n- [ ] Commit messages follow [conventional format](../CONTRIBUTING.md#commit-messages)\n- [ ] No secrets, API keys, or internal URLs included\n\n## Related Issues\n<!-- Link related issues using: Closes #(issue), Fixes #(issue), Relates to #(issue) -->\n\n## Additional Context\n<!-- Add any other context, screenshots, or information that would help reviewers -->\n"
  },
  {
    "path": ".github/workflows/README.md",
    "content": "# GitHub Workflows\n\n## Testing workflows locally\n\nYou can run GitHub Actions locally in two ways.\n\n### 1. Run the script directly (recommended when a job is script-based)\n\nMany workflows just run a script. Run that script on your machine with the same env (Node, Java, Bazel, etc.):\n\n| Workflow / job | Local command (from repo root) |\n|----------------|----------------------------------|\n| **Release Test** | `./tools/ci/release_test.sh` |\n| **Bazel smoke test** | `./tools/ci/bootstrap_app.sh` (set `OPEN_SOURCE_DIR=$(pwd)`, `PROJECT_ROOT=/tmp/valdi_app`) |\n\nNo Docker required; same as CI except for runner OS (e.g. macOS for iOS build).\n\n### 2. Use [act](https://github.com/nektos/act) to run the workflow in Docker\n\n[act](https://github.com/nektos/act) runs GitHub Actions locally using Docker images for the runner environment.\n\n**Install (macOS):** `brew install act`\n\n**List workflows and jobs:**\n```bash\nact -l\n```\n\n**Run a specific workflow (e.g. Release Test):**\n```bash\nact release-test -j release-test\n```\n\n**Run a specific workflow by event (e.g. push):**\n```bash\nact push -W .github/workflows/release-test.yml -j release-test\n```\n\n**Limitations:**\n\n- **macOS runner**: `act` runs jobs in Linux containers by default. The Release Test and Bazel smoke jobs use `runs-on: macos-latest` (for Xcode / iOS build). To run those as in CI you either:\n  - Run the script directly on your Mac (see above), or\n  - Use `act` with a macOS image if your act version supports it (experimental).\n- **Secrets**: Use `act -s NPM_TOKEN=...` (or a `.secrets` file) for workflows that need secrets; they are not pulled from GitHub.\n- **Services / caches**: Some actions (e.g. `actions/cache`, `actions/checkout`) work in act; others may differ from GitHub.\n\nFor the **Release Test** workflow, running `./tools/ci/release_test.sh` on a Mac is the closest to CI and usually the easiest.\n\n---\n\n## Release Test (Public GitHub)\n\nThe `release-test.yml` workflow verifies that the **bleeding edge (main branch)** of the public GitHub Valdi and Valdi_Widgets repos can be bootstrapped, built, and tested. Run it before cutting a release to answer: \"if we cut a release now, will things fail?\"\n\n### What it does\n\n1. Builds the Valdi CLI from source in this repo\n2. Bootstraps a new app **without** a local Valdi path (uses `--valdiVersion=main --valdiWidgetsVersion=main`, i.e. bleeding edge from `https://github.com/Snapchat/Valdi` and `Valdi_Widgets`)\n3. Builds the iOS app and runs the module test\n\n### When it runs\n\n- **Manual**: Actions → \"Release Test (Public GitHub)\" → Run workflow\n- **On release**: When a GitHub release is published\n- **On version tags**: Push `v*` or `beta-*` (e.g. `v1.0.1`, `beta-0.0.2`)\n- **On PR**: When bootstrap/release-test files change (`npm_modules/cli` bootstrap, `tools/ci/release_test.sh`, or this workflow)\n\n### Running locally\n\nFrom the repo root (open_source):\n\n```bash\n./tools/ci/release_test.sh\n```\n\nRequires Node, Java 17, Bazel (or Bazelisk), and watchman. On macOS, the script builds the iOS app; set `SKIP_BUILD=1` to only run bootstrap + unit test. The script uses bleeding edge (main) by default; the workflow does the same.\n\n---\n\n## NPM Package Publishing\n\nThe `publish-npm.yml` workflow automatically publishes npm packages to the public npm registry when their `package.json` files are updated.\n\n### Packages\n\nThis workflow handles publishing for:\n- **@snap/valdi** (`npm_modules/cli/`) - CLI tools for Valdi development (available as `valdi` command)\n- **@snap/eslint-plugin-valdi** (`npm_modules/eslint-plugin-valdi/`) - ESLint rules for Valdi\n\n### Trigger Conditions\n\nThe workflow runs when:\n1. Changes are pushed to `main` or `master` branch\n2. The changes include modifications to `npm_modules/*/package.json`\n3. Manual trigger via workflow_dispatch\n\n### How It Works\n\n1. **Detect Changes**: Determines which package.json files were modified\n2. **Test CLI (before publish only)**: For `@snap/valdi`, two jobs run first. Both must succeed before publish:\n   - **test-cli** (Ubuntu): install, build, smoke tests (`valdi --version`, `--help`, `bootstrap --help`, `doctor --help`).\n   - **test-cli-build** (macOS): full release test — bootstrap an app from bleeding edge (main), build the iOS app, run the module test (`./tools/ci/release_test.sh`). Ensures the CLI can bootstrap and build before we publish.\n3. **Build & Publish**: For each changed package:\n   - Checks out the code\n   - Sets up Node.js 20\n   - Installs dependencies with `npm ci`\n   - Builds the package with `npm run build`\n   - Publishes to npm registry with `npm publish --access public`\n\n### Setup Requirements\n\n#### NPM Token\n\nYou must configure an `NPM_TOKEN` secret in your GitHub repository:\n\n1. **Create an NPM Access Token**:\n   - Log in to [npmjs.com](https://www.npmjs.com/)\n   - Go to Account Settings → Access Tokens\n   - Click \"Generate New Token\" → \"Classic Token\"\n   - Select \"Automation\" type\n   - Copy the generated token\n\n2. **Add Secret to GitHub**:\n   - Go to your GitHub repository\n   - Navigate to Settings → Secrets and variables → Actions\n   - Click \"New repository secret\"\n   - Name: `NPM_TOKEN`\n   - Value: Paste your npm access token\n   - Click \"Add secret\"\n\n#### Package Publishing Permissions\n\nEnsure the npm account associated with the token has:\n- Publishing rights for the `@snap` organization (for both `@snap/valdi` and `@snap/eslint-plugin-valdi`)\n\n### Usage\n\nTo publish a new version of a package:\n\n1. Update the version in the package's `package.json`:\n   ```bash\n   cd npm_modules/cli  # or eslint-plugin-valdi\n   npm version patch   # or minor, major\n   ```\n\n2. Commit and push the changes:\n   ```bash\n   git add package.json\n   git commit -m \"Bump @snap/valdi version to X.Y.Z\"\n   git push origin main\n   ```\n\n3. The workflow will automatically:\n   - Detect the package.json change\n   - Build the package\n   - Publish it to npm\n\n### Manual Trigger\n\nYou can also manually trigger the workflow:\n1. Go to Actions tab in GitHub\n2. Select \"Publish NPM Packages\" workflow\n3. Click \"Run workflow\"\n4. Select the branch and click \"Run workflow\"\n\nNote: Manual triggers will attempt to publish all packages, so ensure versions have been updated to avoid npm publish errors.\n\n### Troubleshooting\n\n- **401 Unauthorized**: Check that the `NPM_TOKEN` secret is correctly configured\n- **403 Forbidden**: Ensure the npm account has publishing permissions for the package\n- **Version already exists**: Update the version number in package.json before publishing\n- **Build failures**: Check that the package builds successfully locally before pushing\n\n---\n\n## PR Size Labeler\n\nThe `pr-size-labeler.yml` workflow labels pull requests by change size (XS, S, M, L, XL) and optionally posts a size comment.\n\n### Required repo labels\n\nFor the workflow to apply labels, create these labels in the repo (Settings → Labels):\n\n- `size/XS` (e.g. &lt;10 lines)\n- `size/S` (e.g. &lt;50)\n- `size/M` (e.g. &lt;250)\n- `size/L` (e.g. &lt;1000)\n- `size/XL` (1000+)\n\nIf the labels do not exist, the workflow will log a message and continue (it no longer fails with 422).\n\n---\n\n## Bazel Config & CI Tests\n\nThe `bzl-changes.yml` workflow runs on pushes to `main` and on PRs when Bazel/config/CI files change. It has two main jobs:\n\n- **Valdi Smoke Tests** (macOS): checkout, install CLI, run `./tools/ci/bootstrap_app.sh`.\n- **Validate Bazel Build** (Ubuntu): checkout, Android SDK + Bazel setup, install Valdi CLI, then `./tools/ci/test_exported_lib.sh` and `./tools/ci/bazel_build.sh`.\n\n### Troubleshooting Validate Bazel Build failures\n\n- **CLI install step**: The job runs `npm run cli:install` in `npm_modules/cli`, which runs `npm ci && npm link`. `npm ci` requires a committed `package-lock.json` in that directory. If the lock file is missing, the step fails; consider committing a lock file or having the workflow use `npm install` for that job.\n- **Test exported library**: `test_exported_lib.sh` runs `valdi export android ...` for the helloworld app (and on macOS only `valdi export ios ...`, then verifies the XCFramework layout). Failures can be due to Bazel/Android SDK/NDK setup or the export target not building.\n- **Build core targets**: `bazel_build.sh` runs `build_core_targets.sh`, `run_tests.sh`, `install_cli.sh`, and `bootstrap_app.sh`. It also switches to Java 8 on Linux; ensure the runner’s Java/SDK setup matches what the script expects.\n\nCheck the failed run’s logs in the Actions tab to see which step failed and the exact error.\n\n**\"No space left on device\"**: The Ubuntu runner has limited disk. The workflow runs a **Free disk space** step right after checkout (removing .NET, GHC, CodeQL, pre-installed Android, Docker images, apt cache) so there is room for the Android SDK, NDK, and Bazel build. If you still hit out-of-disk errors, consider reducing what gets built or cached, or splitting the job.\n\n"
  },
  {
    "path": ".github/workflows/bzl-changes.yml",
    "content": "name: Bazel Config & CI Tools Tests\n\non:\n  pull_request:\n    paths:\n      - '**/*.bzl'\n      - '**/BUILD.bazel'\n      - '**/BUILD'\n      - 'MODULE.bazel'\n      - 'WORKSPACE'\n      - 'tools/ci/**'\n      - 'npm_modules/cli/test/**'\n      - '.github/workflows/bzl-changes.yml'\n  push:\n    branches:\n      - main\n    paths:\n      - '**/*.bzl'\n      - '**/BUILD.bazel'\n      - '**/BUILD'\n      - 'MODULE.bazel'\n      - 'WORKSPACE'\n      - 'tools/ci/**'\n      - 'npm_modules/cli/test/**'\n      - '.github/workflows/bzl-changes.yml'\n\njobs:\n  smoke-test:\n    name: Valdi Smoke Tests\n    runs-on: macos-latest\n    \n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          lfs: true\n      \n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '22'\n      \n      - name: Setup Java 17\n        uses: actions/setup-java@v4\n        with:\n          distribution: 'zulu'\n          java-version: '17'\n      \n      - name: Install Bazel and watchman\n        run: |\n          brew install bazelisk watchman\n          bazel --version\n          watchman --version\n      \n      - name: Install Valdi CLI\n        run: |\n          cd npm_modules/cli\n          npm install\n          npm run cli:install\n      \n      - name: Run smoke tests\n        run: ./tools/ci/bootstrap_app.sh\n        env:\n          OPEN_SOURCE_DIR: ${{ github.workspace }}\n          PROJECT_ROOT: /tmp/valdi_app\n      \n      - name: Upload test results\n        if: failure()\n        uses: actions/upload-artifact@v4\n        with:\n          name: test-results-macos\n          path: |\n            /tmp/valdi_app/*.log\n            /tmp/valdi_app/config.yaml\n            /tmp/valdi_app/WORKSPACE\n            /tmp/valdi_app/.bazelrc\n          retention-days: 5\n\n  # Note: Linux CLI distribution tests moved to dedicated workflow:\n  # .github/workflows/test-cli-linux.yml\n  # This avoids duplication and provides better test organization.\n\n  validate-bazel:\n    name: Validate Bazel Build\n    runs-on: ubuntu-latest\n    \n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          lfs: true\n      \n      - name: Free disk space\n        run: |\n          # Free space before heavy installs to avoid \"No space left on device\" during build\n          sudo rm -rf /usr/share/dotnet\n          sudo rm -rf /opt/ghc\n          sudo rm -rf /opt/hostedtoolcache/CodeQL\n          sudo rm -rf /usr/local/share/boost\n          sudo rm -rf /opt/pip\n          sudo apt-get clean\n          df -h\n      \n      - name: Mount Bazel cache\n        uses: actions/cache@v4\n        with:\n          path: |\n            ~/.cache/bazel\n            ~/.cache/bazelisk\n          # Include run_id to make key unique (enables incremental caching)\n          # restore-keys will find the most recent cache with matching config\n          key: bazel-${{ runner.os }}-${{ hashFiles('WORKSPACE', 'MODULE.bazel', '**/*.bzl') }}-${{ github.run_id }}\n          restore-keys: |\n            bazel-${{ runner.os }}-${{ hashFiles('WORKSPACE', 'MODULE.bazel', '**/*.bzl') }}-\n            bazel-${{ runner.os }}-\n      \n      - name: Setup Java 17\n        uses: actions/setup-java@v4\n        with:\n          distribution: 'zulu'\n          java-version: '17'\n      \n      - name: Setup Android SDK\n        run: |\n          # Install to a writable path (android-actions/setup-android@v3 uses /usr/local/lib/android which fails with EACCES on hosted runners)\n          export ANDROID_HOME=$HOME/Android/Sdk\n          mkdir -p \"$ANDROID_HOME/cmdline-tools\"\n          curl -sS -o /tmp/cmdline-tools.zip \"https://dl.google.com/android/repository/commandlinetools-linux-12266719_latest.zip\"\n          unzip -q -o /tmp/cmdline-tools.zip -d \"$ANDROID_HOME/cmdline-tools\"\n          mv \"$ANDROID_HOME/cmdline-tools/cmdline-tools\" \"$ANDROID_HOME/cmdline-tools/latest\"\n          rm /tmp/cmdline-tools.zip\n          echo \"ANDROID_HOME=$ANDROID_HOME\" >> $GITHUB_ENV\n          echo \"ANDROID_SDK_ROOT=$ANDROID_HOME\" >> $GITHUB_ENV\n          echo \"$ANDROID_HOME/cmdline-tools/latest/bin\" >> $GITHUB_PATH\n      \n      - name: Install Android SDK components and set NDK path\n        run: |\n          # Install required SDK components\n          yes | sdkmanager --licenses || true\n          sdkmanager \"platforms;android-36\"\n          sdkmanager \"build-tools;34.0.0\"\n          sdkmanager \"ndk;23.0.7599858\"\n          echo \"ANDROID_NDK_HOME=$ANDROID_HOME/ndk/23.0.7599858\" >> $GITHUB_ENV\n      \n      - name: Setup Bazel\n        run: |\n          wget https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64\n          chmod +x bazelisk-linux-amd64\n          sudo mv bazelisk-linux-amd64 /usr/local/bin/bazel\n          sudo ln -s /usr/local/bin/bazel /usr/local/bin/bzl\n          bazel --version\n      \n      - name: Configure Bazel cache\n        run: |\n          # Use same paths as actions/cache so build outputs are saved and restored between runs\n          echo \"build --disk_cache=$HOME/.cache/bazel/disk\" >> .bazelrc.local\n          echo \"build --repository_cache=$HOME/.cache/bazel/repo\" >> .bazelrc.local\n          echo \"Bazel cache configured (disk + repo); actions/cache will persist both\"\n      \n      - name: Install system dependencies\n        run: |\n          sudo apt-get update -y\n          # Core dependencies (matching valdi dev_setup for Linux)\n          sudo apt-get install -y \\\n            libboost-all-dev \\\n            git-lfs \\\n            libfontconfig1-dev \\\n            zlib1g-dev\n          \n          # Install libtinfo5 for LLVM/Clang toolchain (Ubuntu 24.04+ doesn't have it in apt)\n          if ! sudo apt-get install -y libtinfo5 2>/dev/null; then\n            echo \"libtinfo5 not available in apt, downloading from Ubuntu 22.04 archive...\"\n            wget http://archive.ubuntu.com/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb\n            sudo apt install -y ./libtinfo5_6.3-2ubuntu0.1_amd64.deb\n            rm libtinfo5_6.3-2ubuntu0.1_amd64.deb\n          fi\n          \n          # Initialize git-lfs\n          git lfs install\n      \n      - name: Setup environment and install Valdi CLI\n        run: |\n          # Setup npm global directory\n          mkdir -p ~/.npm-global/lib\n          npm config set prefix '~/.npm-global'\n          npm install -g npm@8\n          export PATH=~/.npm-global/bin:$PATH\n          \n          # Install Valdi CLI\n          cd npm_modules/cli\n          npm run cli:install\n          valdi --help\n        \n      - name: Test exported library\n        run: ./tools/ci/test_exported_lib.sh\n      \n      - name: Build core targets and run tests\n        run: ./tools/ci/bazel_build.sh\n  \n  comment-results:\n    name: Comment Test Results\n    needs: [smoke-test, validate-bazel]\n    if: always()\n    uses: ./.github/workflows/comment-test-results.yml\n    permissions:\n      pull-requests: write\n    with:\n      workflow_name: \"Bazel & CI Test Results\"\n      success_message: \"**All Bazel configuration and CI tests passed!** ✨\\n\\nThe build system and core tooling are working correctly.\"\n      additional_info: \"🚀 _Bazel remote cache is now enabled - future builds will be faster!_\"\n"
  },
  {
    "path": ".github/workflows/comment-test-results.yml",
    "content": "name: Comment Test Results\n\non:\n  workflow_call:\n    inputs:\n      workflow_name:\n        description: 'Name of the calling workflow for the comment header'\n        required: true\n        type: string\n      success_message:\n        description: 'Message to show when all tests pass'\n        required: false\n        type: string\n        default: '**All tests passed!** ✨'\n      failure_message:\n        description: 'Message to show when tests fail'\n        required: false\n        type: string\n        default: '**Some tests failed.** Please check the workflow logs for details.'\n      additional_info:\n        description: 'Optional additional information to include in the comment'\n        required: false\n        type: string\n        default: ''\n\npermissions:\n  pull-requests: write\n\njobs:\n  comment:\n    name: Post Results Comment\n    runs-on: ubuntu-latest\n    if: github.event_name == 'pull_request'\n    \n    steps:\n      - name: Auto-detect jobs and comment on PR\n        uses: actions/github-script@v7\n        with:\n          script: |\n            // Fetch all jobs for this workflow run\n            const jobs = await github.rest.actions.listJobsForWorkflowRun({\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              run_id: context.runId,\n            });\n            \n            // Build results table (exclude this comment job itself)\n            let tableRows = [];\n            let allPassed = true;\n            \n            for (const job of jobs.data.jobs) {\n              // Skip the comment job itself\n              if (job.name === 'Post Results Comment' || job.name === 'Comment Test Results') {\n                continue;\n              }\n              \n              const icon = job.conclusion === 'success' ? '✅' : '❌';\n              tableRows.push(`| ${job.name} | ${icon} ${job.conclusion} |`);\n              \n              if (job.conclusion !== 'success') {\n                allPassed = false;\n              }\n            }\n            \n            const emoji = allPassed ? '🎉' : '⚠️';\n            const message = allPassed \n              ? `${{ inputs.success_message }}`\n              : `${{ inputs.failure_message }}`;\n            \n            const additionalInfo = `${{ inputs.additional_info }}`;\n            \n            const body = `## ${emoji} ${{ inputs.workflow_name }}\n            \n            | Test Suite | Result |\n            |------------|--------|\n            ${tableRows.join('\\n')}\n            \n            ${message}\n            \n            ${additionalInfo ? additionalInfo + '\\n\\n' : ''}\n            <sub>Workflow: [${context.workflow}](${context.payload.repository.html_url}/actions/runs/${context.runId})</sub>`;\n            \n            github.rest.issues.createComment({\n              issue_number: context.issue.number,\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              body: body\n            });\n"
  },
  {
    "path": ".github/workflows/pr-size-labeler.yml",
    "content": "name: PR Size Labeler\n\non:\n  pull_request:\n    types: [opened, reopened, synchronize]\n\npermissions:\n  contents: read\n  pull-requests: write\n\njobs:\n  size-label:\n    name: Label PR by Size\n    runs-on: ubuntu-latest\n    \n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n      \n      - name: Calculate PR size and apply label\n        uses: actions/github-script@v7\n        with:\n          script: |\n            if (context.eventName !== 'pull_request' || !context.payload.pull_request) {\n              console.log('Skipping: not a pull_request event or no pull_request in payload');\n              return;\n            }\n            const pr = context.payload.pull_request;\n            const repo = { owner: context.repo.owner, repo: context.repo.repo };\n\n            // GITHUB_TOKEN is read-only for PRs from forks; skip so the job still succeeds\n            const isFork = pr.head.repo && (pr.head.repo.full_name !== `${repo.owner}/${repo.repo}`);\n            if (isFork) {\n              console.log('Skipping: PR is from a fork. Labels cannot be applied (token has read-only access).');\n              return;\n            }\n            \n            // Get ALL files changed in the PR (handles pagination automatically)\n            const files = await github.paginate(github.rest.pulls.listFiles, {\n              ...repo,\n              pull_number: pr.number,\n            });\n            \n            console.log(`Found ${files.length} changed files`);\n            \n            // Calculate total lines changed (additions + deletions)\n            let totalChanges = 0;\n            for (const file of files) {\n              totalChanges += file.additions + file.deletions;\n            }\n            \n            // Determine size category\n            let sizeLabel;\n            if (totalChanges < 10) {\n              sizeLabel = 'size/XS';\n            } else if (totalChanges < 50) {\n              sizeLabel = 'size/S';\n            } else if (totalChanges < 250) {\n              sizeLabel = 'size/M';\n            } else if (totalChanges < 1000) {\n              sizeLabel = 'size/L';\n            } else {\n              sizeLabel = 'size/XL';\n            }\n            \n            console.log(`Total changes: ${totalChanges} lines`);\n            console.log(`Size label: ${sizeLabel}`);\n            \n            // Get existing labels\n            const existingLabels = pr.labels.map(label => label.name);\n            \n            // Remove old size labels (ignore 404 — label may already be gone)\n            const sizeLabels = ['size/XS', 'size/S', 'size/M', 'size/L', 'size/XL'];\n            const labelsToRemove = existingLabels.filter(label => \n              sizeLabels.includes(label) && label !== sizeLabel\n            );\n            \n            for (const label of labelsToRemove) {\n              try {\n                await github.rest.issues.removeLabel({\n                  ...repo,\n                  issue_number: pr.number,\n                  name: label,\n                });\n                console.log(`Removed label: ${label}`);\n              } catch (err) {\n                if (err.status === 404) {\n                  console.log(`Label ${label} not on PR (already removed or race), skipping`);\n                } else {\n                  throw err;\n                }\n              }\n            }\n            \n            // Add new size label if not already present\n            if (!existingLabels.includes(sizeLabel)) {\n              try {\n                await github.rest.issues.addLabels({\n                  ...repo,\n                  issue_number: pr.number,\n                  labels: [sizeLabel],\n                });\n                console.log(`Added label: ${sizeLabel}`);\n              } catch (err) {\n                if (err.status === 403 || err.status === 404) {\n                  console.log(`Could not add label (${err.status}): ${err.message}`);\n                } else if (err.status === 422) {\n                  console.log(`Could not add label (422): label \"${sizeLabel}\" may not exist in repo. Create labels size/XS, size/S, size/M, size/L, size/XL in repo settings.`);\n                } else {\n                  throw err;\n                }\n              }\n            }\n            \n            // Add a comment with size breakdown (only on first run)\n            if (context.payload.action === 'opened') {\n              const filesList = files\n                .sort((a, b) => (b.additions + b.deletions) - (a.additions + a.deletions))\n                .slice(0, 10)\n                .map(f => `- \\`${f.filename}\\`: +${f.additions} -${f.deletions}`)\n                .join('\\n');\n              const moreFiles = files.length > 10 ? '\\n\\n_...and ' + (files.length - 10) + ' more files_' : '';\n              const comment = '## 📊 PR Size: **' + sizeLabel + '**\\n\\n'\n                + '**Total changes:** ' + totalChanges + ' lines (' + files.length + ' files)\\n\\n'\n                + '**Top files changed:**\\n' + filesList + moreFiles\n                + '\\n\\n<sub>Size calculated as additions + deletions. Labels: XS (<10), S (<50), M (<250), L (<1000), XL (1000+)</sub>';\n              \n              try {\n                await github.rest.issues.createComment({\n                  ...repo,\n                  issue_number: pr.number,\n                  body: comment,\n                });\n              } catch (err) {\n                if (err.status === 403 || err.status === 404 || err.status === 422) {\n                  console.log(`Could not create comment (${err.status}): ${err.message}`);\n                } else {\n                  throw err;\n                }\n              }\n            }\n"
  },
  {
    "path": ".github/workflows/publish-npm.yml",
    "content": "name: Publish NPM Packages\n\non:\n  push:\n    branches:\n      - main\n      - master\n    paths:\n      - 'npm_modules/*/package.json'\n  workflow_dispatch:\n\njobs:\n  detect-changes:\n    runs-on: ubuntu-latest\n    outputs:\n      cli: ${{ steps.filter.outputs.cli }}\n      eslint-plugin: ${{ steps.filter.outputs.eslint-plugin }}\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 2\n\n      - name: Check which packages changed\n        id: filter\n        run: |\n          if git diff HEAD^ HEAD --name-only | grep -q \"npm_modules/cli/package.json\"; then\n            echo \"cli=true\" >> $GITHUB_OUTPUT\n          else\n            echo \"cli=false\" >> $GITHUB_OUTPUT\n          fi\n          \n          if git diff HEAD^ HEAD --name-only | grep -q \"npm_modules/eslint-plugin-valdi/package.json\"; then\n            echo \"eslint-plugin=true\" >> $GITHUB_OUTPUT\n          else\n            echo \"eslint-plugin=false\" >> $GITHUB_OUTPUT\n          fi\n\n  test-cli:\n    name: Test CLI before publish\n    needs: detect-changes\n    if: needs.detect-changes.outputs.cli == 'true'\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: npm_modules/cli\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Build package\n        run: npm run build\n\n      - name: Smoke tests (CLI runs)\n        run: |\n          node dist/index.js --version\n          node dist/index.js --help\n          node dist/index.js bootstrap --help\n          node dist/index.js doctor --help\n\n  test-cli-build:\n    name: Build bootstrapped app (release test)\n    needs: detect-changes\n    if: needs.detect-changes.outputs.cli == 'true'\n    runs-on: macos-latest\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          lfs: true\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '22'\n\n      - name: Setup Java 17\n        uses: actions/setup-java@v4\n        with:\n          distribution: 'zulu'\n          java-version: '17'\n\n      - name: Install Bazel and watchman\n        run: |\n          brew install bazelisk watchman\n          bazel --version\n          watchman --version\n\n      - name: Run release test (bootstrap from main, build iOS, test)\n        run: ./tools/ci/release_test.sh\n\n  publish-cli:\n    needs: [detect-changes, test-cli, test-cli-build]\n    if: needs.detect-changes.outputs.cli == 'true'\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: npm_modules/cli\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n          registry-url: 'https://registry.npmjs.org'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Build package\n        run: npm run build\n\n      - name: Publish @snap/valdi to npm\n        run: npm publish --access public\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n\n  publish-eslint-plugin:\n    needs: detect-changes\n    if: needs.detect-changes.outputs.eslint-plugin == 'true'\n    runs-on: ubuntu-latest\n    defaults:\n      run:\n        working-directory: npm_modules/eslint-plugin-valdi\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n          registry-url: 'https://registry.npmjs.org'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Build package\n        run: npm run build\n\n      - name: Publish @snap/eslint-plugin-valdi to npm\n        run: npm publish --access public\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n\n"
  },
  {
    "path": ".github/workflows/release-test.yml",
    "content": "# Run before cutting a release: bootstrap an app from bleeding edge (main) of\n# the public GitHub Valdi/Valdi_Widgets, build and test. Ensures \"if we cut a\n# release now, things won't fail.\"\nname: Release Test (Public GitHub)\n\non:\n  workflow_dispatch:\n  release:\n    types: [published]\n  push:\n    tags:\n      - 'v*'\n      - 'beta-*'\n  pull_request:\n    paths:\n      - 'npm_modules/cli/src/commands/bootstrap.ts'\n      - 'npm_modules/cli/src/utils/githubUtils.ts'\n      - 'tools/ci/release_test.sh'\n      - '.github/workflows/release-test.yml'\n\njobs:\n  release-test:\n    name: Bootstrap from main (bleeding edge), build & test\n    runs-on: macos-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n        with:\n          lfs: true\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '22'\n\n      - name: Setup Java 17\n        uses: actions/setup-java@v4\n        with:\n          distribution: 'zulu'\n          java-version: '17'\n\n      - name: Install Bazel and watchman\n        run: |\n          brew install bazelisk watchman\n          bazel --version\n          watchman --version\n\n      - name: Run release test\n        run: ./tools/ci/release_test.sh\n\n      - name: Upload artifacts on failure\n        if: failure()\n        uses: actions/upload-artifact@v4\n        with:\n          name: release-test-failure\n          path: |\n            /tmp/valdi_release_test/WORKSPACE\n            /tmp/valdi_release_test/.bazelrc\n            /tmp/valdi_release_test/BUILD.bazel\n          retention-days: 7\n"
  },
  {
    "path": ".github/workflows/test-cli-linux.yml",
    "content": "name: Test CLI on Linux Distributions\n\non:\n  pull_request:\n    paths:\n      - 'npm_modules/cli/src/**'\n      - 'npm_modules/cli/test/**'\n      - 'npm_modules/cli/package.json'\n      - '.github/workflows/test-cli-linux.yml'\n  push:\n    branches:\n      - main\n    paths:\n      - 'npm_modules/cli/src/**'\n      - 'npm_modules/cli/test/**'\n      - 'npm_modules/cli/package.json'\n      - '.github/workflows/test-cli-linux.yml'\n  workflow_dispatch:\n\njobs:\n  test-distribution-detection:\n    name: Test on ${{ matrix.distro }}\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        distro:\n          - ubuntu-22.04\n          - ubuntu-24.04\n          - fedora-39\n          - fedora-40\n        include:\n          - distro: ubuntu-22.04\n            container: ubuntu:22.04\n            expected_type: debian\n            expected_pm: apt\n            expected_name_pattern: Ubuntu\n          - distro: ubuntu-24.04\n            container: ubuntu:24.04\n            expected_type: debian\n            expected_pm: apt\n            expected_name_pattern: Ubuntu\n          - distro: fedora-39\n            container: fedora:39\n            expected_type: redhat\n            expected_pm: dnf\n            expected_name_pattern: Fedora\n          - distro: fedora-40\n            container: fedora:40\n            expected_type: redhat\n            expected_pm: dnf\n            expected_name_pattern: Fedora\n    \n    container:\n      image: ${{ matrix.container }}\n    \n    steps:\n      - name: Install git (required for checkout)\n        run: |\n          if command -v apt-get &> /dev/null; then\n            apt-get update -qq && apt-get install -y -qq git curl ca-certificates\n          elif command -v dnf &> /dev/null; then\n            dnf install -y -q git curl ca-certificates\n          elif command -v yum &> /dev/null; then\n            yum install -y -q git curl ca-certificates\n          fi\n      \n      - name: Checkout code\n        uses: actions/checkout@v4\n      \n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '22'\n      \n      - name: Build Valdi CLI\n        run: |\n          cd npm_modules/cli\n          npm ci\n          npm run build\n      \n      - name: Test distribution detection\n        run: |\n          echo \"============================================================\"\n          echo \"Testing Linux Distribution Detection\"\n          echo \"============================================================\"\n          echo \"\"\n          echo \"Expected:\"\n          echo \"  Distribution type: ${{ matrix.expected_type }}\"\n          echo \"  Package manager:   ${{ matrix.expected_pm }}\"\n          echo \"  Distribution name: ${{ matrix.expected_name_pattern }}\"\n          echo \"\"\n          \n          node -e \"\n            const distro = require('./npm_modules/cli/dist/utils/linuxDistro');\n            \n            console.log('Testing distribution detection...');\n            const detected = distro.detectLinuxDistro();\n            \n            console.log('');\n            console.log('✓ Detected distribution:', detected.name);\n            console.log('  Type:', detected.type);\n            console.log('  Version:', detected.version || 'N/A');\n            console.log('  Package Manager:', detected.packageManager.name);\n            console.log('  Install Command:', detected.packageManager.installCommand);\n            console.log('  Requires Sudo:', detected.packageManager.requiresSudo);\n            \n            // Verify detection matches expected\n            const expectedType = '${{ matrix.expected_type }}';\n            const expectedPm = '${{ matrix.expected_pm }}';\n            const expectedNamePattern = '${{ matrix.expected_name_pattern }}';\n            \n            if (detected.type !== expectedType) {\n              throw new Error(\\`Expected type '\\${expectedType}', got '\\${detected.type}'\\`);\n            }\n            console.log('✓ Distribution type correct');\n            \n            if (detected.packageManager.name !== expectedPm) {\n              throw new Error(\\`Expected package manager '\\${expectedPm}', got '\\${detected.packageManager.name}'\\`);\n            }\n            console.log('✓ Package manager correct');\n            \n            if (!detected.name.includes(expectedNamePattern)) {\n              throw new Error(\\`Expected name to contain '\\${expectedNamePattern}', got '\\${detected.name}'\\`);\n            }\n            console.log('✓ Distribution name correct');\n            \n            console.log('');\n            console.log('All distribution detection checks passed! ✓');\n          \"\n      \n      - name: Test package mappings\n        run: |\n          echo \"\"\n          echo \"============================================================\"\n          echo \"Testing Package Name Mappings\"\n          echo \"============================================================\"\n          echo \"\"\n          \n          node -e \"\n            const distro = require('./npm_modules/cli/dist/utils/linuxDistro');\n            const detected = distro.detectLinuxDistro();\n            const mappings = distro.getCommonPackageMappings();\n            \n            console.log('Package mappings loaded:', Object.keys(mappings).length, 'packages');\n            console.log('');\n            \n            // Test all common packages have correct mappings\n            const testPackages = [\n              'git',\n              'git-lfs',\n              'npm',\n              'openjdk-17',\n              'watchman',\n              'adb',\n              'fontconfig',\n              'zlib'\n            ];\n            \n            for (const pkg of testPackages) {\n              const mapping = mappings[pkg];\n              if (!mapping) {\n                throw new Error(\\`Missing mapping for \\${pkg}\\`);\n              }\n              \n              const packageName = distro.getPackageName(mapping, detected);\n              console.log(\\`  \\${pkg.padEnd(15)} -> \\${packageName}\\`);\n              \n              if (!packageName || packageName === '') {\n                throw new Error(\\`Empty package name for \\${pkg}\\`);\n              }\n            }\n            \n            console.log('');\n            console.log('All package mappings validated! ✓');\n          \"\n      \n      - name: Test install command generation\n        run: |\n          echo \"\"\n          echo \"============================================================\"\n          echo \"Testing Install Command Generation\"\n          echo \"============================================================\"\n          echo \"\"\n          \n          node -e \"\n            const distro = require('./npm_modules/cli/dist/utils/linuxDistro');\n            const detected = distro.detectLinuxDistro();\n            const expectedPm = '${{ matrix.expected_pm }}';\n            \n            // Test single package\n            const singleCmd = distro.buildInstallCommand(['git'], detected);\n            console.log('Single package:');\n            console.log('  ' + singleCmd);\n            \n            if (!singleCmd.includes(expectedPm)) {\n              throw new Error(\\`Command should use \\${expectedPm}\\`);\n            }\n            if (!singleCmd.includes('git')) {\n              throw new Error('Command should include git package');\n            }\n            console.log('  ✓ Correct');\n            console.log('');\n            \n            // Test multiple packages\n            const multiCmd = distro.buildInstallCommand(['git', 'npm', 'watchman'], detected);\n            console.log('Multiple packages:');\n            console.log('  ' + multiCmd);\n            \n            if (!multiCmd.includes(expectedPm)) {\n              throw new Error(\\`Command should use \\${expectedPm}\\`);\n            }\n            if (!multiCmd.includes('git') || !multiCmd.includes('npm') || !multiCmd.includes('watchman')) {\n              throw new Error('Command should include all packages');\n            }\n            console.log('  ✓ Correct');\n            console.log('');\n            \n            // Test distribution-specific Java package\n            const mappings = distro.getCommonPackageMappings();\n            const javaPackage = distro.getPackageName(mappings['openjdk-17'], detected);\n            const javaCmd = distro.buildInstallCommand([javaPackage], detected);\n            console.log('Java package (distribution-specific):');\n            console.log('  Package: ' + javaPackage);\n            console.log('  Command: ' + javaCmd);\n            console.log('  ✓ Correct');\n            console.log('');\n            \n            console.log('All install command generation tests passed! ✓');\n          \"\n      \n      - name: Test git-lfs setup detection\n        run: |\n          echo \"\"\n          echo \"============================================================\"\n          echo \"Testing Git-LFS Repository Setup Detection\"\n          echo \"============================================================\"\n          echo \"\"\n          \n          node -e \"\n            const distro = require('./npm_modules/cli/dist/utils/linuxDistro');\n            const detected = distro.detectLinuxDistro();\n            \n            const needsSetup = distro.needsGitLfsRepoSetup(detected);\n            const setupCmd = distro.getGitLfsRepoSetupCommand(detected);\n            \n            console.log('Distribution:', detected.name);\n            console.log('Needs git-lfs repo setup:', needsSetup);\n            console.log('Setup command:', setupCmd || 'N/A (uses standard repos)');\n            console.log('');\n            \n            // Verify logic is consistent\n            if (needsSetup && !setupCmd) {\n              throw new Error('If setup is needed, command should be provided');\n            }\n            \n            // Verify Debian/Ubuntu needs packagecloud setup\n            if (detected.type === 'debian' && !needsSetup) {\n              throw new Error('Debian/Ubuntu should need git-lfs repo setup');\n            }\n            \n            // Verify setup command format\n            if (setupCmd) {\n              if (!setupCmd.includes('packagecloud.io')) {\n                throw new Error('Setup command should use packagecloud.io');\n              }\n              \n              if (detected.type === 'debian' && !setupCmd.includes('script.deb.sh')) {\n                throw new Error('Debian setup should use .deb script');\n              }\n              \n              if (detected.type === 'redhat' && !setupCmd.includes('script.rpm.sh')) {\n                throw new Error('RedHat setup should use .rpm script');\n              }\n            }\n            \n            console.log('Git-LFS setup detection validated! ✓');\n          \"\n      \n      - name: Install CLI and test valdi doctor\n        run: |\n          echo \"\"\n          echo \"============================================================\"\n          echo \"Testing 'valdi doctor' Command\"\n          echo \"============================================================\"\n          echo \"\"\n          \n          cd npm_modules/cli\n          npm link\n          \n          # Run valdi doctor and capture output\n          # Note: valdi doctor will report missing dependencies (expected in CI)\n          # We're testing that it runs without crashing and generates correct commands\n          echo \"Running valdi doctor...\"\n          set +e  # Don't exit on error\n          valdi doctor --verbose > /tmp/doctor_output.txt 2>&1\n          DOCTOR_EXIT_CODE=$?\n          set -e  # Re-enable exit on error\n          \n          # Show the output\n          cat /tmp/doctor_output.txt\n          \n          # Verify doctor ran and generated distribution-specific commands\n          echo \"\"\n          echo \"Verifying distribution-specific fix commands...\"\n          \n          # Check that doctor output contains distribution-appropriate package manager\n          if grep -q \"sudo dnf install\\|sudo yum install\" /tmp/doctor_output.txt; then\n            echo \"✓ Contains dnf/yum commands (correct for Fedora/RHEL)\"\n          elif grep -q \"sudo apt-get install\\|sudo apt install\" /tmp/doctor_output.txt; then\n            echo \"✓ Contains apt commands (correct for Debian/Ubuntu)\"\n          else\n            echo \"✗ No distribution-specific install commands found\"\n            exit 1\n          fi\n          \n          echo \"\"\n          echo \"✓ valdi doctor executed successfully with distribution detection\"\n      \n      - name: Test doctor fix commands\n        run: |\n          echo \"\"\n          echo \"============================================================\"\n          echo \"Testing Doctor Fix Command Generation\"\n          echo \"============================================================\"\n          echo \"\"\n          \n          node -e \"\n            const fs = require('fs');\n            const distro = require('./npm_modules/cli/dist/utils/linuxDistro');\n            const detected = distro.detectLinuxDistro();\n            \n            console.log('Distribution:', detected.name, '(' + detected.type + ')');\n            console.log('');\n            \n            // The doctor command should be using our distribution detection\n            const doctorCode = fs.readFileSync('./npm_modules/cli/dist/commands/doctor.js', 'utf8');\n            \n            // Verify the doctor has the required methods\n            if (!doctorCode.includes('getJavaInstallCommand')) {\n              throw new Error('Doctor command missing getJavaInstallCommand method');\n            }\n            if (!doctorCode.includes('getFixCommandForDependency')) {\n              throw new Error('Doctor command missing getFixCommandForDependency method');\n            }\n            if (!doctorCode.includes('detectLinuxDistro')) {\n              throw new Error('Doctor command not using distribution detection');\n            }\n            \n            console.log('✓ Doctor command uses distribution detection');\n            console.log('✓ Doctor command has fix command methods');\n            console.log('');\n            console.log('Doctor fix commands validated! ✓');\n          \"\n      \n      - name: Summary\n        if: success()\n        run: |\n          echo \"\"\n          echo \"============================================================\"\n          echo \"✓ ALL TESTS PASSED FOR ${{ matrix.distro }}\"\n          echo \"============================================================\"\n          echo \"\"\n          echo \"Distribution detection:     ✓\"\n          echo \"Package mappings:           ✓\"\n          echo \"Install command generation: ✓\"\n          echo \"Git-LFS setup detection:    ✓\"\n          echo \"valdi doctor integration:   ✓\"\n          echo \"Doctor fix commands:        ✓\"\n          echo \"\"\n\n  test-unit-tests:\n    name: Run Unit Tests\n    runs-on: ubuntu-latest\n    \n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n      \n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: '22'\n      \n      - name: Install dependencies\n        run: |\n          cd npm_modules/cli\n          npm ci\n      \n      - name: Build\n        run: |\n          cd npm_modules/cli\n          npm run build\n      \n      - name: Run linuxDistro unit tests\n        run: |\n          cd npm_modules/cli\n          # Run Jasmine tests for linuxDistro\n          npx jasmine dist/utils/linuxDistro.spec.js\n      \n      - name: Verify no linter errors in modified files\n        run: |\n          cd npm_modules/cli\n          # Only lint the files we actually modified for Linux compatibility\n          npx eslint \\\n            src/utils/linuxDistro.ts \\\n            src/utils/linuxDistro.spec.ts \\\n            src/setup/linuxSetup.ts \\\n            src/commands/doctor.ts\n"
  },
  {
    "path": ".github/workflows/welcome.yml",
    "content": "name: Welcome\n\non:\n  pull_request_target:\n    types: [opened]\n  issues:\n    types: [opened]\n\njobs:\n  welcome:\n    runs-on: ubuntu-latest\n    permissions:\n      issues: write\n      pull-requests: write\n    steps:\n      - uses: actions/first-interaction@v1\n        with:\n          repo-token: ${{ secrets.GITHUB_TOKEN }}\n          issue-message: |\n            👋 Thanks for opening your first issue! \n            \n            A maintainer will review your issue and respond as soon as possible. \n            \n            In the meantime, please make sure you've provided all the necessary information in the issue template.\n            \n            If you have questions while waiting, feel free to join our [Discord community](https://discord.gg/uJyNEeYX2U).\n          pr-message: |\n            🎉 Thanks for your first contribution to Valdi!\n            \n            A maintainer will review your PR soon. Here are a few things to check while you wait:\n            \n            - ✅ All tests pass (`bazel test //...`)\n            - ✅ Your changes follow our [coding standards](../CONTRIBUTING.md)\n            - ✅ You've added tests for your changes (if applicable)\n            - ✅ You've updated documentation (if needed)\n            \n            Join our [Discord community](https://discord.gg/uJyNEeYX2U) if you have questions!\n"
  },
  {
    "path": ".gitignore",
    "content": "*.DS_Store\n\n/bazel-*\n\n**/archive-url\n\nscripts/valdi-swift-toolchain\n\n# Binaries\nscripts/mirroring/bin\n.nlo-venv\n**deploy_manifest.txt"
  },
  {
    "path": ".prettierrc.json",
    "content": "{\n  \"printWidth\": 120,\n  \"singleQuote\": true,\n  \"jsxSingleQuote\": true,\n  \"arrowParens\": \"avoid\",\n  \"trailingComma\": \"all\"\n}\n"
  },
  {
    "path": "AGENTS.md",
    "content": "# AGENTS.md - Guide for AI Coding Assistants\n\nThis document provides context and guidelines for AI coding assistants working with the Valdi codebase.\n\n## Overview\n\nValdi is a cross-platform UI framework that compiles declarative TypeScript components to native views on iOS, Android, and macOS. Write your UI once, and it runs natively on multiple platforms without web views or JavaScript bridges.\n\nValdi has been used in production at Snap for 8 years and is now available as open source under the MIT license.\n\n### How Valdi Works\n\nThe Valdi compiler takes TypeScript source files (using TSX/JSX syntax) and compiles them into `.valdimodule` files. These compiled modules are read by the Valdi runtime on each platform to render native views. **This is not TypeScript rendered in a WebView** - Valdi generates true native UI components.\n\n## 🚨 AI Anti-Hallucination: This is NOT React!\n\n**CRITICAL**: Valdi uses TSX/JSX syntax but **is fundamentally different from React**. The most common AI error is suggesting React patterns that do not exist in Valdi.\n\n### ❌ FORBIDDEN React Patterns (Do NOT use these)\n\nThese React APIs **DO NOT EXIST** in Valdi and will cause compilation errors:\n\n```typescript\n// ❌ WRONG - useState does not exist in Valdi\nconst [count, setCount] = useState(0);\n\n// ❌ WRONG - useEffect does not exist in Valdi  \nuseEffect(() => { ... }, []);\n\n// ❌ WRONG - useContext does not exist in Valdi\nconst value = useContext(MyContext);\n\n// ❌ WRONG - useMemo, useCallback, useRef do not exist\nconst memoized = useMemo(() => ..., []);\nconst callback = useCallback(() => ..., []);\nconst ref = useRef(null);\n\n// ❌ WRONG - React.Component does not exist\nclass MyComponent extends React.Component { ... }\n\n// ❌ WRONG - Functional components do not exist\nfunction MyComponent(props) { return <view />; }\nconst MyComponent = () => <view />;\n```\n\n### ⚠️ COMMON AI MISTAKES (Even advanced models make these errors!)\n\n**These patterns DO NOT EXIST in Valdi** but are commonly suggested by AI models:\n\n```typescript\n// ❌ WRONG - markNeedsRender() does NOT exist\nclass MyComponent extends Component {\n  count = 0;\n  handleClick() {\n    this.count++;\n    this.markNeedsRender(); // ERROR: This method doesn't exist!\n  }\n}\n\n// ❌ WRONG - scheduleRender() exists but is DEPRECATED\nclass MyComponent extends Component {\n  count = 0;\n  handleClick() {\n    this.count++;\n    this.scheduleRender(); // DEPRECATED: Use StatefulComponent with setState() instead\n  }\n}\n\n// ❌ WRONG - onMount/onUpdate/onUnmount do NOT exist (React-like names)\nclass MyComponent extends Component {\n  onMount() { }        // Should be: onCreate()\n  onUpdate() { }       // Should be: onViewModelUpdate(previousViewModel)\n  onUnmount() { }      // Should be: onDestroy()\n}\n\n// ❌ WRONG - this.props does NOT exist\nclass MyComponent extends Component {\n  onRender() {\n    <label value={this.props.title} />; // Should be: this.viewModel.title\n  }\n}\n\n// ❌ WRONG - this.context.get() does NOT exist\nclass MyComponent extends Component {\n  onRender() {\n    const service = this.context.get(MyService); // This API doesn't exist!\n  }\n}\n\n// ❌ WRONG - Returning JSX from onRender()\nclass MyComponent extends Component {\n  onRender() {\n    return <view />; // onRender() returns void, not JSX!\n  }\n}\n```\n\n**Why these errors happen**: AI models are heavily trained on React code, and Valdi's TSX syntax triggers incorrect React pattern suggestions. Always verify against actual Valdi APIs.\n\n### ✅ CORRECT Valdi Patterns (Use these instead)\n\nValdi uses a **class-based component model** with explicit lifecycle methods:\n\n```typescript\n// ✅ CORRECT - Stateful Valdi component pattern\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\nclass MyComponent extends StatefulComponent<ViewModel, State> {\n  // State management via StatefulComponent\n  state = { count: 0 };\n  \n  // Lifecycle: Called when component is first created\n  onCreate() {\n    console.log('Component created');\n  }\n  \n  // Lifecycle: Called when viewModel changes\n  onViewModelUpdate(previousViewModel: ViewModel) {\n    console.log('ViewModel changed');\n  }\n  \n  // Lifecycle: Called before component is removed\n  onDestroy() {\n    console.log('Component destroying');\n  }\n  \n  // Required: Render method returns void (not JSX!)\n  onRender() {\n    // Note: onRender returns VOID, not JSX\n    // JSX is written as a statement, not returned\n    <view>\n      <label value={`Count: ${this.state.count}`} />\n      <button \n        title=\"Increment\"\n        onPress={() => {\n          this.setState({ count: this.state.count + 1 }); // setState triggers re-render\n        }}\n      />\n    </view>;\n  }\n}\n\n// For components without state, use Component\nimport { Component } from 'valdi_core/src/Component';\n\nclass SimpleComponent extends Component<ViewModel> {\n  onRender() {\n    <label value={this.viewModel.title} />;\n  }\n}\n```\n\n### Key Valdi Concepts\n\n1. **State Management**: Use `StatefulComponent` with `setState()`, not `useState`\n2. **Props Access**: Use `this.viewModel`, not `this.props`\n3. **Re-rendering**: `setState()` automatically triggers re-render\n4. **Lifecycle Methods**: `onCreate()`, `onViewModelUpdate()`, `onDestroy()`\n5. **Dependency Injection**: Use `createProviderComponent()` + `withProviders()` HOC pattern\n6. **Return Type**: `onRender()` returns `void`, not JSX (JSX is written as a statement)\n7. **Component Definition**: Always use `class` extending `Component` or `StatefulComponent`, never functions\n\n### State Management with StatefulComponent\n\n```typescript\n// ✅ CORRECT - Use StatefulComponent with setState()\nclass Counter extends StatefulComponent<ViewModel, State> {\n  state = { count: 0 };\n  \n  handleClick = () => {\n    this.setState({ count: this.state.count + 1 }); // Automatically triggers re-render\n  };\n  \n  onRender() {\n    <button title={`Count: ${this.state.count}`} onPress={this.handleClick} />;\n  }\n}\n\n// ❌ WRONG - Using markNeedsRender() doesn't exist\nhandleClick() {\n  this.count++;\n  this.markNeedsRender(); // ERROR: markNeedsRender is not a function!\n}\n```\n\n### Provider Pattern (Not useContext)\n\n```typescript\n// ✅ CORRECT - Valdi provider pattern\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nimport { withProviders } from 'valdi_core/src/provider/withProviders';\nimport { ProvidersValuesViewModel } from 'valdi_core/src/provider/withProviders';\nimport { Component } from 'valdi_core/src/Component';\n\n// Step 1: Define service\nclass MyService {\n  getData() { return 'data'; }\n}\n\n// Step 2: Create provider component\nconst MyServiceProvider = createProviderComponentWithKeyName<MyService>('MyServiceProvider');\n\n// Step 3: Provide value in parent\nclass ParentComponent extends Component {\n  private service = new MyService();\n  \n  onRender() {\n    <MyServiceProvider value={this.service}>\n      <ChildComponentWithProvider />\n    </MyServiceProvider>;\n  }\n}\n\n// Step 4: Consume in child - extend viewModel from ProvidersValuesViewModel\ninterface ChildViewModel extends ProvidersValuesViewModel<[MyService]> {\n  // other props if needed\n}\n\nclass ChildComponent extends Component<ChildViewModel> {\n  onRender() {\n    // Access provider via viewModel.providersValues\n    const [myService] = this.viewModel.providersValues;\n    const data = myService.getData();\n    \n    <label value={data} />;\n  }\n}\n\n// Step 5: Wrap component with provider HOC\nconst ChildComponentWithProvider = withProviders(MyServiceProvider)(ChildComponent);\n```\n\n## Key Technologies\n\n- **Valdi**: TypeScript-based declarative UI framework that compiles to native code\n- **TSX/JSX**: React-like syntax for declarative UI (but this is **NOT React** - Valdi compiles to native)\n- **Bazel**: Primary build system for reproducible builds\n- **TypeScript/JavaScript**: Application and UI layer\n- **C++**: Cross-platform runtime and layout engine\n- **Swift**: Compiler implementation\n- **Kotlin/Java**: Android runtime\n- **Objective-C/C++**: iOS runtime\n- **Flexbox**: Layout system with automatic RTL support\n\n## Directory Structure\n\n### `/apps/`\nExample applications demonstrating Valdi features:\n- `helloworld/` - Basic getting started example\n- `valdi_gpt/` - More complex demo application\n- `benchmark/` - Performance testing app\n- `*_example/` - Various feature demonstrations (navigation, managed context, etc.)\n\n### `/compiler/`\nThe Valdi compiler and companion tools:\n- `compiler/` - Swift-based main compiler that transforms TypeScript to native code\n- `companion/` - TypeScript-based companion tools for the build process\n\n### `/valdi/`, `/valdi_core/`, `/valdi_protobuf/`\nCore Valdi runtime implementations:\n- Platform-specific implementations (iOS, Android, macOS)\n- Cross-platform C++ core with layout engine\n- Protobuf integration for efficient serialization\n- Generated code from Djinni interfaces for cross-language bindings\n\n### `/src/valdi_modules/`\nCore Valdi TypeScript modules and standard library:\n- `valdi_core/` - Core component and runtime APIs (Component, Provider, etc.)\n- `valdi_protobuf/` - Protobuf serialization support\n- `valdi_http/` - HTTP client module (promise-based network requests)\n- `valdi_navigation/` - Navigation utilities\n- `valdi_rxjs/` - RxJS integration for reactive programming\n- `persistence/` - Key-value storage with encryption and TTL support\n- `drawing/` - Managed context for graphics and drawing operations\n- `file_system/` - Low-level file I/O operations\n- `valdi_web/`, `web_renderer/` - Web runtime implementations\n- `foundation/`, `coreutils/` - Common utilities (arrays, Base64, LRU cache, UUID, etc.)\n- `worker/` - Worker service support for background JavaScript execution\n- Other standard library modules\n\n### `/npm_modules/`\nNode.js packages:\n- `cli/` - Command-line interface for Valdi development (`valdi` command)\n- `eslint-plugin-valdi/` - ESLint rules for Valdi code\n\n### `/bzl/`\nBazel build rules and macros for the Valdi build system\n\n### `/docs/`\nComprehensive documentation:\n- Codelabs for learning\n- API documentation\n- Setup and installation guides\n\n### `/third-party/`\nExternal dependencies and their Bazel build configurations\n\n## Important Conventions\n\n### Build System\n\n1. **Bazel is the primary build system** - Use `bazel build`, `bazel test`, etc.\n   - Note: `bzl` is an alias for `bazel` - both commands work interchangeably\n   - The CLI looks for `bazel`, `bzl`, or `bazelisk` executables\n2. **MODULE.bazel and WORKSPACE** - Bazel module system is in use\n3. **Cross-platform builds** - Code must work on iOS, Android, Linux, and macOS\n4. **Platform transitions** - Build rules handle platform-specific compilation automatically\n\n### Code Style\n\n1. **C++**: Follow the project's C++ style conventions\n2. **TypeScript**: Use ESLint with Valdi-specific rules\n3. **Swift**: Follow Swift conventions for compiler code\n4. **Kotlin**: Follow Kotlin conventions for Android runtime\n5. **Indentation**: Always match existing file conventions\n\n### Testing\n\n1. Test files are typically in `test/` subdirectories\n2. Run tests with `bazel test //path/to:target`\n3. All changes should include appropriate tests\n4. Use the built-in Valdi testing framework for component tests\n\n### Generated Code\n\n1. **Djinni interfaces** - Some code is generated from `.djinni` files for cross-language bindings\n2. **Don't modify generated code** - Change the source `.djinni` file instead\n3. Generated files are typically in `generated-src/` directories\n\n## Common Tasks\n\n### Building the Compiler\n\n```bash\n# Build the compiler\nbazel build //compiler/compiler:valdi-compiler\n\n# After building, move the binary to bin/ directory for use by the toolchain\n# The exact path depends on your platform (macos/linux and architecture)\n# Example for macOS ARM64:\ncp bazel-bin/compiler/compiler/valdi-compiler bin/compiler/macos/arm64/\n```\n\nNote: Pre-built compiler binaries are checked in to `/bin/compiler/` for convenience, but you can build and use your own version during development.\n\n### Running Tests\n\n```bash\n# Run all tests\nbazel test //...\n\n# Run specific test\nbazel test //valdi/test:some_test\n```\n\n### Installing and Using the CLI\n\n```bash\ncd npm_modules/cli\n\n# Install the valdi command-line tool globally\nnpm run cli:install\n\n# After installation, use the CLI\nvaldi --help\n```\n\n### Creating New Examples\n\nUse existing apps in `/apps/` as templates. Each app needs:\n- `BUILD.bazel` file defining build targets\n- `package.json` for npm dependencies\n- Entry point file (typically `.tsx` for TypeScript JSX)\n- Source files in `src/` directory\n\n## Important Files to Review\n\n- `/README.md` - Main project documentation\n- `/docs/INSTALL.md` - Installation and setup instructions\n- `/docs/DEV_SETUP.md` - Developer environment setup\n- `/CONTRIBUTING.md` - Contribution guidelines\n- `/CODE_OF_CONDUCT.md` - Community standards\n- `/LICENSE.md` - MIT License information\n\n## Toolchain Locations\n\nPre-built binaries are stored in `/bin/`:\n- Compiler binaries for Linux/macOS\n- SQLite compiler for data persistence\n- Other build tools\n\n## Platform-Specific Notes\n\n### iOS\n- Uses Objective-C++ bridge layer for TypeScript-native communication\n- Metal for GPU-accelerated rendering\n- See `/valdi/src/ios/` for platform implementations\n\n### Android\n- Kotlin/Java implementations\n- Uses Android NDK for C++ integration\n- See `/valdi/src/android/` for platform implementations\n\n### Web\n- TypeScript runtime for web targets\n- See `/src/valdi_modules/src/valdi/web_renderer/` for web implementation\n\n### Desktop (macOS)\n- Native macOS implementation\n- See `/valdi/src/valdi/macos/` for desktop implementations\n\n## Development Workflow\n\n1. **Setup environment** - Follow `/docs/DEV_SETUP.md`\n2. **Make changes** in appropriate directory\n3. **Build locally** with Bazel\n4. **Run tests** to verify changes\n5. **Run linters** with appropriate tools\n6. **Test on multiple platforms** - Changes may affect iOS, Android, and web\n7. **Update documentation** if adding features\n\n## Common Patterns\n\n### Component Development\n\nValdi components follow a class-based pattern with lifecycle methods:\n\n```typescript\nimport { Component } from 'valdi_core/src/Component';\n\nclass MyComponent extends Component {\n  // Required: Render the component's UI\n  onRender() {\n    <view>\n      <label value=\"Hello\" />\n    </view>;\n  }\n  \n  // Optional lifecycle methods:\n  // onCreate() - Called when component is first created\n  // onDestroy() - Called before component is removed\n  // onViewModelUpdate(previousViewModel) - Called when viewModel updates\n}\n```\n\n**Key Valdi Concepts:**\n- Components use TSX/JSX syntax (similar to React but compiles to native)\n- State management via component properties\n- Event handlers for user interactions\n- Flexbox layout system for positioning\n\n### Native Polyglot Modules\n\nFor performance-critical code, write native implementations with TypeScript bindings:\n- Define interfaces in TypeScript\n- Specify polyglot modules in build files (BUILD.bazel)\n- Implement in C++, Swift, Kotlin, or Objective-C\n- Compiler generates type-safe bindings\n\n### Worker Services\n\nFor background processing:\n- Create worker services that run in separate JavaScript contexts\n- Communicate via message passing\n- See `/docs/docs/advanced-worker-service.md`\n\n### Component Context & Native Integration\n\nPass data and services between native code and Valdi:\n- **Component Context**: Pass native data to Valdi components when instantiating them\n- **Native Annotations**: Use TypeScript comments to export components to native platforms\n- **Example**: `@Component` and `@ExportModel` annotations define how components are exposed\n- See `/docs/docs/native-annotations.md` and `/docs/docs/native-context.md`\n\n### Provider Pattern\n\nDependency injection for Valdi components:\n- Use `Provider` to pass services and data down the component tree\n- Similar to React Context but Valdi-specific\n- Enables loose coupling and testability\n- See `/docs/docs/advanced-provider.md`\n\n### Localization\n\nString management for multi-language support:\n- String resources defined in JSON files\n- Automatic locale switching based on device settings\n- See `/docs/docs/advanced-localization.md`\n\n## Common Pitfalls\n\n1. **Don't skip cross-platform testing** - Changes affect multiple platforms\n2. **Don't modify generated code** - Change the source instead\n3. **Don't ignore Bazel cache** - Use `bazel clean` sparingly\n4. **Don't hardcode platform assumptions** - Use appropriate abstractions\n5. **Performance matters** - Valdi is a UI framework where rendering performance is critical\n\n## Architecture Overview\n\n### Compilation Pipeline\n\n1. **TypeScript source** → Valdi compiler (Swift)\n2. **Compiler output** → Platform-specific code generation\n3. **Native builds** → iOS/Android/macOS apps\n4. **Runtime** → C++ layout engine + platform-specific renderers\n\n### Hot Reload System\n\n- Valdi includes instant hot reload during development\n- Changes to TypeScript components are reflected in milliseconds\n- No need to recompile native code for UI changes\n- Use `valdi hotreload` command\n\n### Performance Features\n\n- **View recycling** - Global view pooling reuses native views\n- **Viewport-aware rendering** - Only visible views are inflated\n- **Independent component rendering** - Components update without parent re-renders\n- **Optimized layout** - C++ layout engine with minimal marshalling\n\n## Key Points for AI Assistants\n\n1. **Cross-platform compatibility is critical** - Test implications across iOS, Android, and web\n2. **Bazel is non-negotiable** - Don't suggest alternative build systems\n3. **Generated code exists** - Some files are auto-generated from Djinni interfaces\n4. **Performance is paramount** - This is a production UI framework used at scale\n5. **Follow existing patterns** - This is a mature codebase with established conventions\n6. **TypeScript is compiled** - Unlike React Native, this doesn't run JavaScript at runtime\n7. **Native integration is deep** - Direct access to platform APIs via polyglot modules\n\n## Quick Reference Commands\n\n### For App Development\n\n```bash\n# Install Valdi CLI (first time)\ncd npm_modules/cli && npm run cli:install\n\n# Setup development environment\nvaldi dev_setup\n\n# Bootstrap a new project\nmkdir my_project && cd my_project\nvaldi bootstrap\n\n# Install dependencies and build\nvaldi install ios    # or android\n\n# Start hot reload\nvaldi hotreload\n```\n\n### For Platform Development (Contributing to Valdi)\n\n```bash\n# Setup development environment (first time)\nscripts/dev_setup.sh\n\n# Build everything\nbazel build //...\n\n# Run all tests\nbazel test //...\n\n# Build and run example app\ncd apps/helloworld\nvaldi install ios    # or android\n```\n\n## Testing Framework\n\nValdi includes a built-in testing framework:\n- Component-level unit tests\n- Mock services and dependencies\n- See `/docs/docs/workflow-testing.md`\n\n```typescript\nimport { TestRunner } from 'valdi_core/src/TestRunner';\n\nTestRunner.test('component renders correctly', () => {\n  const component = new MyComponent();\n  // Test assertions\n});\n```\n\n## Debugging\n\n- **VSCode integration** - Full debugging support with breakpoints\n- **Hermes debugger** - For JavaScript debugging\n- **Native debugging** - Xcode/Android Studio for platform-specific issues\n- See `/docs/docs/workflow-hermes-debugger.md`\n\n## Related Documentation\n\nFor more details on specific topics, see the `/docs/` directory:\n- Architecture overview\n- API reference\n- Codelabs for hands-on learning\n- Advanced features (animations, gestures, protobuf)\n- Native bindings and custom views\n\n## AI Skills (Context for AI Agents)\n\nThe Valdi CLI ships context files (\"skills\") that give AI agents accurate knowledge about Valdi APIs, patterns, and conventions. Install them once to reduce hallucinations:\n\n```bash\nnpm install -g @snap/valdi\nvaldi skills install          # installs all skills for detected AI agents\n# or install by category:\nvaldi skills install --category=client     # module development skills\nvaldi skills install --category=framework  # framework internals skills\n```\n\nSkills are bundled inside the npm package — no network access required after install.\n\n## Contributing\n\nThis is an open-source project. When contributing:\n1. Follow the style guides\n2. Include tests for new features\n3. Update documentation\n4. Ensure cross-platform compatibility\n5. See `CONTRIBUTING.md` for full guidelines\n\n## Community & Support\n\n- **Discord**: Join the [Valdi Discord community](https://discord.gg/uJyNEeYX2U) for support and discussions\n- **Documentation**: Comprehensive docs in `/docs/` directory\n- **Examples**: Working examples in `/apps/` directory\n- **Issues**: Report bugs and request features via GitHub issues\n- **Discussions**: Ask questions and share ideas in GitHub Discussions\n\n---\n\n*This document is intended for AI coding assistants to quickly understand the structure and conventions of the Valdi codebase. For human developers, please refer to the main README.md and comprehensive documentation in `/docs/`.*\n"
  },
  {
    "path": "BUILD.bazel",
    "content": "load(\"@aspect_rules_js//npm:defs.bzl\", \"npm_link_package\")\n\n# tsc demands that these be defined in the root of the workspace\nnpm_link_package(\n    name = \"valdi_tsx_link\",\n    src = \"@valdi//src/valdi_modules/src/valdi/valdi_tsx:valdi_tsx_dts\",\n    visibility = [\"//visibility:public\"],\n)\n\nnpm_link_package(\n    name = \"valdi_core_link\",\n    src = \"@valdi//src/valdi_modules/src/valdi/valdi_core:valdi_core_dts\",\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders of the Valdi community pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our community include:\n\n- Demonstrating empathy and kindness toward other people\n- Being respectful of differing opinions, viewpoints, and experiences\n- Giving and gracefully accepting constructive feedback\n- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience\n- Focusing on what is best not just for us as individuals, but for the overall community\n\nExamples of unacceptable behavior include:\n\n- The use of sexualized language or imagery, and sexual attention or advances of any kind\n- Trolling, insulting or derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others’ private information, such as a physical or email address, without their explicit permission\n- Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Enforcement Responsibilities\n\nValdi community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.\n\nValdi community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at opensource@snap.com. All complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the reporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\nCommunity Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.\n\nConsequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\nCommunity Impact: A violation through a single incident or series of actions.\n\nConsequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.\n\n### 3. Temporary Ban\n\nCommunity Impact: A serious violation of community standards, including sustained inappropriate behavior.\n\nConsequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\nCommunity Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.\n\nConsequence: A permanent ban from any sort of public interaction within the community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.\n\nFor answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. \n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to Valdi\n\nThank you for your interest in Valdi. We welcome community contributions and appreciate your time and effort in helping improve the project. Before getting started, please take a moment to review these guidelines.\n\n## 1. [Code of Conduct](./CODE_OF_CONDUCT.md)\n\nWe want this project to be a welcoming space for everyone. By contributing, you agree to follow our [Code of Conduct](./CODE_OF_CONDUCT.md) and help keep the community respectful and inclusive.\n\n## 2. How to Contribute\n\nWe welcome contributions in various forms, including:\n\n- Bug fixes\n- Documentation improvements\n- Tests and performance optimizations\n\nIf you would like to add new features, please reach out to the Valdi team on [Discord](https://discord.gg/uJyNEeYX2U) to discuss. \n\nTo contribute, follow these steps:\n\n- **Fork** the repository and create a new branch.\n- **Make your changes**, ensuring they align with our coding standards (§4 below).\n- **Run tests** to ensure your changes do not break existing functionality.\n- **Submit a pull request (PR)** with a clear description of the changes.\n- A maintainer will review your PR, suggest any necessary changes, and merge it once approved.\n\n### Commit Messages\n\nUse clear and descriptive commit messages. Follow the conventional commit format when possible:\n\nfeat: Add new authentication method  \nfix: Resolve issue with session timeout  \ndocs: Update README with new installation steps  \n\n## 3.  Legal Terms\n\nBy submitting a contribution, you represent and warrant that:\n\n- It is your original work, or you have sufficient rights to submit it.\n- You grant the Valdi maintainers and users the right to use, modify, and distribute it under the MIT license (see LICENSE file); and\n- To the extent your contribution is covered by patents, you grant a perpetual, worldwide, non-exclusive, royalty-free, irrevocable license to the Valdi maintainers and users to make, use, sell, offer for sale, import, and otherwise transfer your contribution as part of the project.\n\nWe do not require a Contributor License Agreement (CLA). However, by contributing, you agree to license your submission under terms compatible with the MIT License and to grant the patent rights described above. If your contribution includes third-party code, you are responsible for ensuring it is MIT-compatible and properly attributed.\n\nWhere permitted by law, you waive any moral rights in your contribution (e.g., the right to object to modifications). If such rights cannot be waived, you agree not to assert them in a way that interferes with the project’s use of your contribution.\n\n## 4.  Coding Standards\n\nTo maintain a consistent codebase, please follow these guidelines:\n\n- Use the existing coding style and conventions.\n- Ensure all code changes are well-documented.\n- Write tests for new features and bug fixes.\n- Avoid introducing unnecessary dependencies.\n\n## 5.  Reporting Issues\n\nIf you find a bug or have a feature request, please open an issue and provide as much detail as possible:\n\n- Steps to reproduce, including operating system, and Valdi version\n- Expected and actual behavior\n- Suspected cause (if any)\n\n## 6.  Recognition\n\nWe use the All Contributors specification to recognize community members. If your contribution is merged, you will be added to the project's list of contributors. This includes contributions of all kinds—code, documentation, design, testing, and more.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "Copyright © 2025 Snap Inc.\n\nValdi is made available under the MIT License.\n\n**MIT License**\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n**Third-Party Software**\n\nValdi includes or interacts with third-party software. A detailed report of the third-party software used, including their respective licenses, can be found at the following link.\n\nhttps://portal.fossa.com/p/snap/release/2857/23669\n\nWe aim to maintain transparency and compliance with all third-party license requirements. If you spot an issue or believe attribution is missing, please reach out to us at opensource@snap.com.\n"
  },
  {
    "path": "MODULE.bazel",
    "content": "module(name = \"valdi\", version = \"0.1\")\n\nhttp_archive = use_repo_rule(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\nbazel_dep(name = \"toolchains_llvm\", version = \"1.3.0\")\nbazel_dep(name = \"apple_support\", version = \"1.21.0\", repo_name = \"build_bazel_apple_support\")\n\nbazel_dep(name = \"protobuf\", version = \"27.0\", repo_name = \"protobuf_cpp\")\nsingle_version_override(\n    module_name = \"protobuf\",\n    version = \"27.0\",\n)\nbazel_dep(name = \"rules_pkg\", version = \"0.9.1\")\nsingle_version_override(\n    module_name = \"rules_pkg\",\n    version = \"0.9.1\",\n)\nbazel_dep(name = \"rules_proto\", version = \"6.0.2\")\nbazel_dep(name = \"rules_python\", version = \"1.4.1\")\n\nbazel_dep(name = \"rules_cc\", version = \"0.0.17\")\nbazel_dep(name = \"googletest\", version = \"1.13.0\", repo_name = \"gtest\")\nsingle_version_override(\n    module_name = \"zlib\",\n    version = \"1.3.2\",\n)\n\nbazel_dep(name = \"bazel_skylib\", version = \"1.2.0\")\nbazel_dep(name = \"rules_java\", version = \"7.4.0\")\n\nbazel_dep(name = \"rules_android\", version = \"0.5.1\")\nbazel_dep(name = \"rules_android_ndk\", version = \"0.1.3\")\nsingle_version_override(module_name = \"rules_android_ndk\", patches = [\n    \"@valdi//third-party/rules_android_ndk/patches:expose_bins.patch\",\n])\n\nremote_android_extensions = use_extension(\n    \"@rules_android//bzlmod_extensions:android_extensions.bzl\",\n    \"remote_android_tools_extensions\",\n)\nuse_repo(remote_android_extensions, \"android_gmaven_r8\", \"android_tools\")\n\nandroid_sdk_repository_extension = use_extension(\"@rules_android//rules/android_sdk_repository:rule.bzl\", \"android_sdk_repository_extension\")\nandroid_sdk_repository_extension.configure(\n    api_level = 36,\n    build_tools_version = \"34.0.0\",\n)\nuse_repo(android_sdk_repository_extension, \"androidsdk\")\n\nregister_toolchains(\n    \"@rules_android//toolchains/android:all\",\n    \"@rules_android//toolchains/android_sdk:all\",\n)\nregister_toolchains(\"@androidsdk//:sdk-toolchain\", \"@androidsdk//:all\")\n\nandroid_ndk_repository_extension = use_extension(\"@rules_android_ndk//:extension.bzl\", \"android_ndk_repository_extension\")\nuse_repo(android_ndk_repository_extension, \"androidndk\")\n\nregister_toolchains(\"@androidndk//:all\")\n\nbazel_dep(name = \"rules_kotlin\", version = \"1.9.0\")\nsingle_version_override(\n    module_name = \"rules_kotlin\",\n    patches = [\"@valdi//third-party/rules_kotlin:fix_manifest_custom_package.patch\"],\n)\nbazel_dep(name = \"rules_jvm_external\", version = \"6.2\")\n\nbazel_dep(name = \"rules_xcodeproj\", version = \"3.2.0\")\n\nbazel_dep(name = \"rules_swift\", version = \"3.1.2\", repo_name = \"build_bazel_rules_swift\")\nsingle_version_override(\n    module_name = \"rules_swift\",\n    patches = [\"@valdi//third-party/rules_swift/patches:rules_swift.patch\"],\n    patch_strip = 1,\n)\n\nbazel_dep(name = \"rules_apple\", version = \"4.0.0\", repo_name = \"build_bazel_rules_apple\")\nsingle_version_override(\n    module_name = \"rules_apple\",\n    version = \"4.0.0\",\n)\n\nbazel_dep(name = \"bazel_features\", version = \"1.10.0\")\n\nbazel_dep(name = \"platforms\", version = \"0.0.11\")\n\nbazel_dep(name = \"aspect_rules_js\", version = \"2.0.0\")\nbazel_dep(name = \"aspect_bazel_lib\", version = \"2.14.0\")\n\nbazel_dep(name = \"aspect_rules_ts\", version = \"3.7.0\")\n\nrules_ts_ext = use_extension(\"@aspect_rules_ts//ts:extensions.bzl\", \"ext\")\nrules_ts_ext.deps(ts_version = \"5.3.3\")\nuse_repo(rules_ts_ext, \"npm_typescript\")\n\nhttp_archive(\n    name = \"zoo\",\n    url = \"https://github.com/thecppzoo/zoo/archive/33b868300145773d8c433b6b3d6643eba6334f7d.zip\",\n    build_file = \"@valdi//third-party/zoo:zoo.BUILD\",\n    integrity = \"sha256-9GIWp7GyVdZn24mvsMGtzhDD2N+W5L5AO3o2tYHtnVk=\",\n    strip_prefix = \"zoo-33b868300145773d8c433b6b3d6643eba6334f7d\",\n)\n\nhttp_archive(\n    name = \"hermes\",\n    url = \"https://github.com/facebook/hermes/archive/880b1645b5dca974f4329dc4108692d301abee0d.zip\",\n    integrity = \"sha256-+GQiTtN6H8TQz/+YkVz73dHeYAZ86/9hAUwTlkISx48=\",\n    strip_prefix = \"hermes-880b1645b5dca974f4329dc4108692d301abee0d\",\n    build_file = \"@valdi//third-party/hermes:hermes.BUILD\",\n)\n\nbazel_dep(name = \"boringssl\", version = \"0.20250415.0\")\n\n# TODO(simon): See if we can use upstream\nhttp_archive(\n    name = \"boost\",\n    build_file = \"@valdi//third-party/boost:boost.BUILD\",\n    patches = [\n        \"@valdi//third-party/boost/patches:asio.patch\",\n        \"@valdi//third-party/boost/patches:global_asio_initializers.patch\",\n        \"@valdi//third-party/boost/patches:interprocess_emscripten.patch\",\n        \"@valdi//third-party/boost/patches:remove_invalid_file_1_78.patch\",\n    ],\n    strip_prefix = \"boost_1_78_0\",\n    integrity = \"sha256-hoHxddS9smxSIiZleT7vCEkNd1hSkzD5jTsp3Qc1vMw=\",\n    url = \"https://archives.boost.io/release/1.78.0/source/boost_1_78_0.tar.bz2\",\n)\n\nhttp_archive(\n    name = \"phmap\",\n    build_file = \"@valdi//third-party/phmap:phmap.BUILD\",\n    strip_prefix = \"parallel-hashmap-1.3.12\",\n    integrity = \"sha256-DMIDFEMhkkz7/MQB9C2CBMDdJOJ2DHocCRuqFtl3fAg=\",\n    url = \"https://github.com/greg7mdp/parallel-hashmap/archive/refs/tags/v1.3.12.tar.gz\",\n)\n\nhttp_archive(\n    name = \"fmt\",\n    build_file = \"@valdi//third-party/fmt:fmt.BUILD\",\n    integrity = \"sha256-XZjFBNAgX5EuIkSezep3a3jOC7CWknM0+AeB5yAITJ8=\",\n    strip_prefix = \"fmt-7.1.3\",\n    url = \"https://github.com/fmtlib/fmt/releases/download/7.1.3/fmt-7.1.3.zip\",\n)\n\nbazel_dep(name = \"android_macros\")\nlocal_path_override(\n    module_name = \"android_macros\",\n    path = \"bzl/macros\",\n)\n\nbazel_dep(name = \"snap_macros\")\nlocal_path_override(\n    module_name = \"snap_macros\",\n    path = \"bzl/valdi/snap_macros\",\n)\n\nbazel_dep(name = \"snap_client_toolchains\")\nlocal_path_override(\n    module_name = \"snap_client_toolchains\",\n    path = \"bzl/toolchains\",\n)\n\nbazel_dep(name = \"snap_platforms\")\nlocal_path_override(\n    module_name = \"snap_platforms\",\n    path = \"bzl/platforms\",\n)\n\nbazel_dep(name = \"skia_user_config\")\nlocal_path_override(\n    module_name = \"skia_user_config\",\n    path = \"third-party/skia_user_config\",\n)\n\nbazel_dep(name = \"rules_hdrs\")\nlocal_path_override(\n    module_name = \"rules_hdrs\",\n    path = \"third-party/rules_hdrs\",\n)\n\nbazel_dep(name = \"valdi_toolchain\")\nlocal_path_override(\n    module_name = \"valdi_toolchain\",\n    path = \"bin\",\n)\n\nbazel_dep(name = \"resvg_libs\")\nlocal_path_override(\n    module_name = \"resvg_libs\",\n    path = \"third-party/resvg/resvg_libs\",\n)\n\nbazel_dep(name = \"jsoncpp\", version = \"1.9.6\")\n\nhttp_archive(\n    name = \"harfbuzz\",\n    strip_prefix = \"harfbuzz-12.2.0\",\n    build_file = \"@valdi//third-party/harfbuzz:harfbuzz.BUILD\",\n    integrity = \"sha256-7LYDqkJqiyRmVxhme9pkqEwVBNt0VO5Mrb02Lupk5UU=\",\n    urls = [\"https://github.com/harfbuzz/harfbuzz/releases/download/12.2.0/harfbuzz-12.2.0.tar.xz\"],\n)\n\nbazel_dep(name = \"backward-cpp\", version = \"1.6\")\n\nbazel_dep(name = \"xxhash\", version = \"0.8.3\")\n\nhttp_archive(\n    name = \"zlib_chromium\",\n    url = \"https://github.com/simonis/zlib-chromium/archive/93867c6db67801f74c2d0840a271c7aa7fd6716c.zip\",\n    build_file = \"@valdi//third-party/zlib_chromium:zlib_chromium.BUILD\",\n    integrity = \"sha256-aybDRpEOnvUrCW8/wTFSuduz5Rk+YxYGdCUZYVY5G9g=\",\n    strip_prefix = \"zlib-chromium-93867c6db67801f74c2d0840a271c7aa7fd6716c\",\n    patch_args = [\"-p1\"],\n    patches = [\n        \"@valdi//third-party/zlib_chromium/patches:apple.patch\",\n    ],\n)\n\nbazel_dep(name = \"zstd\", version = \"1.5.7\")\n\nhttp_archive(\n    name = \"icu\",\n    build_file = \"@valdi//third-party/icu:icu.BUILD\",\n    url = \"https://github.com/unicode-org/icu/releases/download/release-68-1/icu4c-68_1-src.tgz\",\n    strip_prefix = \"icu\",\n    integrity = \"sha256-qfLj2LRDS45Th4tDCL0ebuUcnHBC4rGjdqvvtvuyny0=\",\n)\n\nbazel_dep(name = \"websocketpp\", version = \"0.8.2.bcr.3\")\nsingle_version_override(\n    module_name = \"websocketpp\",\n    patches = [\"@valdi//third-party/websocketpp/patches:fix_ios_lrt.patch\"],\n    patch_strip = 1,\n)\n\nhttp_archive(\n    name = \"test262\",\n    url = \"https://github.com/tc39/test262/archive/refs/heads/main.zip\",\n    build_file = \"@valdi//third-party/test262:test262.BUILD\",\n    strip_prefix = \"test262-main\",\n    integrity = \"sha256-Lv/ZdXIV5f0n11oFTKBq22r0aLGF6HsDp36B1afgVDo=\",\n)\n\nhttp_archive(\n    name = \"resvg\",\n    url = \"https://github.com/RazrFalcon/resvg/archive/a739aef5d01360ec238c886bc50674f31458df00.zip\",\n    build_file = \"@valdi//third-party/resvg:resvg.BUILD\",\n    strip_prefix = \"resvg-a739aef5d01360ec238c886bc50674f31458df00\",\n    integrity = \"sha256-kohUhIYyFoaeIHLBhYwq6g7+h34r3i9/IIQoWyJAmSE=\",\n)\n\nbazel_dep(name = \"rules_license\", version = \"1.0.0\")\n\nbazel_dep(name = \"rules_fuzzing\", version = \"0.5.2\")\n\nSKIA_URL = \"https://github.com/google/skia/archive/8d5c6efb04514a31f09a2e865940f99cdf60ce21.zip\"\nSKIA_STRIP_PREFIX = \"skia-8d5c6efb04514a31f09a2e865940f99cdf60ce21\"\nSKIA_INTEGRITY = \"sha256-piM7FfzT3xekYxvwEDlejJ8Zj+zaxa3oIKpDsx1y6eQ=\"\n\nhttp_archive(\n    name = \"skia\",\n    url = SKIA_URL,\n    strip_prefix = SKIA_STRIP_PREFIX,\n    integrity = SKIA_INTEGRITY,\n)\n\nhttp_archive(\n    name = \"libjpeg_turbo\",\n    build_file = \"@skia//bazel/external/libjpeg_turbo:BUILD.bazel\",\n    url = \"https://chromium.googlesource.com/chromium/deps/libjpeg_turbo/+archive/e14cbfaa85529d47f9f55b0f104a579c1061f9ad.tar.gz\",\n    patches = [\n        \"@valdi//third-party/libjpeg_turbo:warning_fix.patch\",\n        \"@valdi//third-party/libjpeg_turbo:include_fix.patch\",\n    ],\n)\n\nhttp_archive(\n    name = \"libpng\",\n    build_file = \"@skia//bazel/external/libpng:BUILD.bazel\",\n    url = \"https://skia.googlesource.com/third_party/libpng.git/+archive/ed217e3e601d8e462f7fd1e04bed43ac42212429.tar.gz\",\n    patch_args = [\"-p1\"],\n    patches = [\n        \"@valdi//third-party/libpng:fix_armv7.patch\",\n    ],\n)\n\nhttp_archive(\n    name = \"libwebp\",\n    build_file = \"@skia//bazel/external/libwebp:BUILD.bazel\",\n    url = \"https://github.com/webmproject/libwebp/archive/845d5476a866141ba35ac133f856fa62f0b7445f.tar.gz\",\n    strip_prefix = \"libwebp-845d5476a866141ba35ac133f856fa62f0b7445f\",\n)\n\nhttp_archive(\n    name = \"zlib_skia\",\n    build_file = \"@skia//bazel/external/zlib_skia:BUILD.bazel\",\n    url = \"https://chromium.googlesource.com/chromium/src/third_party/zlib/+archive/646b7f569718921d7d4b5b8e22572ff6c76f2596.tar.gz\",\n    patch_args = [\"-p1\"],\n    patches = [\n        \"@valdi//third-party/zlib_skia:android_ios_x86_64.patch\",\n    ],\n)\n\nhttp_archive(\n    name = \"freetype\",\n    build_file = \"@skia//bazel/external/freetype:BUILD.bazel\",\n    url = \"https://github.com/freetype/freetype/archive/5d4e649f740c675426fbe4cdaffc53ee2a4cb954.tar.gz\",\n    strip_prefix = \"freetype-5d4e649f740c675426fbe4cdaffc53ee2a4cb954\",\n)\n\nhttp_archive(\n    name = \"expat\",\n    build_file = \"@skia//bazel/external/expat:BUILD.bazel\",\n    url = \"https://github.com/libexpat/libexpat/archive/624da0f593bb8d7e146b9f42b06d8e6c80d032a3.tar.gz\",\n    strip_prefix = \"libexpat-624da0f593bb8d7e146b9f42b06d8e6c80d032a3\",\n)\n\nnpm = use_extension(\"@aspect_rules_js//npm:extensions.bzl\", \"npm\")\nnpm.npm_translate_lock(\n    name = \"valdi_npm\",\n    pnpm_lock = \"//bzl/valdi/npm:pnpm-lock.yaml\",\n    lifecycle_hooks = {\n        \"better-sqlite3@9.6.0\": [],\n        \"remotedebug-ios-webkit-adapter@0.4.2\": [],\n    },\n    link_workspace = \"valdi\",\n)\nuse_repo(npm, \"valdi_npm\")\n\nmaven = use_extension(\"@rules_jvm_external//:extensions.bzl\", \"maven\")\n\nmaven.install(\n    name = \"android_mvn\",\n    artifacts = [\n        \"androidx.annotation:annotation:1.1.0\",\n        \"androidx.appcompat:appcompat:1.2.0\",\n        \"androidx.appcompat:appcompat-resources:1.2.0\",\n        \"androidx.collection:collection:1.1.0\",\n        \"androidx.constraintlayout:constraintlayout:2.1.4\",\n        \"androidx.customview:customview:1.1.0\",\n        \"androidx.dynamicanimation:dynamicanimation:1.0.0\",\n        \"androidx.fragment:fragment:1.1.0\",\n        \"androidx.interpolator:interpolator:1.0.0\",\n        \"androidx.lifecycle:lifecycle-common:2.2.0\",\n        \"androidx.lifecycle:lifecycle-process:2.2.0\",\n        \"androidx.lifecycle:lifecycle-viewmodel:2.2.0\",\n        \"androidx.recyclerview:recyclerview:1.2.1\",\n        \"androidx.test:core:1.5.0\",\n        \"androidx.test.ext:junit:1.1.3\",\n        \"androidx.test:monitor:1.5.0\",\n        \"androidx.test:runner:1.5.0\",\n        \"com.google.android.material:material:1.2.0\",\n        \"com.google.code.findbugs:jsr305:3.0.2\",\n        \"com.google.code.gson:gson:2.8.6\",\n        \"com.google.protobuf.nano:protobuf-javanano:3.1.0\",\n        \"com.jakewharton.timber:timber:4.7.1\",\n        \"com.squareup.leakcanary:leakcanary-android:2.10\",\n        \"com.squareup.okhttp3:okhttp:4.9.0\",\n        \"com.squareup.okio:okio:2.10.0\",\n        \"io.reactivex.rxjava3:rxandroid:3.0.0\",\n        \"io.reactivex.rxjava3:rxjava:3.1.0\",\n        \"io.reactivex.rxjava3:rxkotlin:3.0.0\",\n        \"javax.inject:javax.inject:1\",\n        \"junit:junit:4.13.2\",\n        \"org.junit.jupiter:junit-jupiter-api:5.9.3\",\n        \"org.junit.jupiter:junit-jupiter-engine:5.9.3\",\n        \"org.junit.jupiter:junit-jupiter-params:5.9.3\",\n        \"org.junit.platform:junit-platform-console:1.9.2\",\n        \"org.junit.platform:junit-platform-launcher:1.9.2\",\n        \"org.junit.platform:junit-platform-reporting:1.9.2\",\n        \"org.junit.vintage:junit-vintage-engine:5.9.3\",\n        \"org.robolectric:android-all:10-robolectric-5803371\",\n        \"org.robolectric:annotations:4.10.3\",\n        \"org.robolectric:robolectric:4.10.3\",\n    ],\n    repositories = [\n        \"https://repo1.maven.org/maven2\",\n        \"https://maven.google.com\",\n    ],\n    aar_import_bzl_label = \"@rules_android//rules:rules.bzl\",\n    use_starlark_android_rules = True,\n    version_conflict_policy = \"pinned\",\n)\n\nuse_repo(maven, \"android_mvn\")\n\nhttp_archive(\n    name = \"expat_config\",\n    url = SKIA_URL,\n    strip_prefix = \"{}/third_party/expat/include\".format(SKIA_STRIP_PREFIX),\n    integrity = SKIA_INTEGRITY,\n)\n\nhttp_archive(\n    name = \"freetype_config\",\n    url = SKIA_URL,\n    strip_prefix = \"{}/third_party/freetype2/include\".format(SKIA_STRIP_PREFIX),\n    integrity = SKIA_INTEGRITY,\n)\n\nhttp_archive(\n    name = \"ocmock\",\n    build_file = \"@valdi//third-party/ocmock:OCMock.build\",\n    integrity = \"sha256-PC3Gc8g0GKYhPmOmQ9lmw/eQaTtOhXjg309oriiuP+o=\",\n    strip_prefix = \"ocmock-3.9.4\",\n    url = \"https://github.com/erikdoe/ocmock/archive/refs/tags/v3.9.4.tar.gz\",\n)\n\nregister_toolchains(\"@valdi//bzl/valdi:valdi_toolchain\")\n\n# C++ toolchains: register both Apple CC and LLVM for standalone bzlmod builds.\n# Apple CC toolchains (from @local_config_apple_cc_toolchains) are registered first so they\n# win on macOS/iOS/tvOS targets — they declare target_compatible_with including\n# @build_bazel_apple_support//constraints:apple and support the \"objc-compile\" action needed by\n# objc_library. LLVM is registered second: on Linux, Apple CC toolchains require exec=macOS so\n# they never match, and LLVM's linux toolchain is selected instead (providing C++ stdlib headers).\napple_cc_configure = use_extension(\"@build_bazel_apple_support//crosstool:setup.bzl\", \"apple_cc_configure_extension\")\nuse_repo(apple_cc_configure, \"local_config_apple_cc_toolchains\", \"local_config_apple_cc\")\nregister_toolchains(\"@local_config_apple_cc_toolchains//:all\")\n\nllvm = use_extension(\"@toolchains_llvm//toolchain/extensions:llvm.bzl\", \"llvm\")\nllvm.toolchain(name = \"llvm_toolchain\", llvm_version = \"16.0.0\")\nuse_repo(llvm, \"llvm_toolchain\")\nregister_toolchains(\"@llvm_toolchain//:all\")\n"
  },
  {
    "path": "README.md",
    "content": "# Valdi\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE.md)\n[![Platforms](https://img.shields.io/badge/platform-iOS%20%7C%20Android%20%7C%20macOS-lightgrey)](./docs/INSTALL.md)\n[![Status](https://img.shields.io/badge/status-beta-yellow)]()\n[![Discord](https://img.shields.io/discord/1285677307163574322?color=7289da&label=Discord&logo=discord&logoColor=white)](https://discord.gg/uJyNEeYX2U)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue?logo=typescript)](https://www.typescriptlang.org/)\n[![Documentation](https://img.shields.io/badge/docs-available-brightgreen)](./docs/README.md)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](./CONTRIBUTING.md)\n\n> [!NOTE]\n> **Beta Status:** Valdi has been widely used in Snap's production apps for the last 8 years. We're calling this a beta because our tools and documentation need more battle testing in the open source world. Valdi will exit beta when we're happy with the developer experience.\n\n**Valdi is a cross-platform UI framework that delivers native performance without sacrificing developer velocity.** Write your UI once in declarative TypeScript, and it compiles directly to native views on iOS, Android, and macOS—no web views, no JavaScript bridges. \n\n## Quick Example\n\nA basic Valdi component:\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nclass HelloWorld extends Component {\n  onRender() {\n    const message = 'Hello World! 👻';\n    <view backgroundColor='#FFFC00' padding={30}>\n      <label color='black' value={message} />\n    </view>;\n  }\n}\n```\n\n<p align=\"center\">\n  <img src=\"./docs/docs/assets/start-about/IMG_1445.jpg\" width=\"400\" alt=\"Hello World example running on iOS\" />\n</p>\n\n## Quick Start\n\n**Prerequisites:** Xcode (macOS only) - everything else is automatic!\n\n```bash\n# Install Valdi CLI\nnpm install -g @snap/valdi\n\n# One-command setup (installs all dependencies)\nvaldi dev_setup\n\n# Create your first project\nmkdir my_project && cd my_project\nvaldi bootstrap\nvaldi install ios  # or android\n```\n\n> [!TIP]\n> **Editor Extensions:** For the best development experience, install the [Valdi VSCode/Cursor extensions](./docs/INSTALL.md#vscodecursor-setup-optional-but-recommended) for syntax highlighting, debugging, and device logs during hot reload.\n\n## Quick Links\n\n- [Getting Started Guide](./docs/INSTALL.md)\n- [Documentation](./docs/README.md)\n- [Codelabs](./docs/docs/start-code-lab.md)\n- [API Reference](./docs/api/api-quick-reference.md)\n- [Frequently Asked Questions](./docs/docs/faq.md)\n- [Component Library](https://github.com/Snapchat/Valdi_Widgets)\n\n## Why Choose Valdi?\n\nValdi is a cross-platform UI framework designed to solve the fundamental problem of cross-platform development: velocity vs. runtime performance. For 8 years, it has powered a large portion of Snap's production apps.\n\n### True Native Performance\n\nUnlike frameworks that rely on web views or JavaScript bridges, Valdi compiles declaratively rendered TypeScript components into platform-native views. Valdi also includes several other performance advantages:\n\n- **[Automatic view recycling](./docs/docs/performance-view-recycling.md)** - Global view pooling system reuses native views across all screens, dramatically reducing inflation latency\n- **Optimized component rendering** - Components re-render independently without triggering parent re-renders, enabling fast incremental updates\n- **Optimized layout engine** - C++ layout engine runs on the main thread with minimal marshalling overhead\n- **Viewport-aware rendering** - Only visible views are inflated, making infinite scrolling performant by default\n\nLearn more in our [Performance Optimization Guide](./docs/docs/performance-optimization.md).\n\n### Developer Experience Built for Speed\n\nValdi eliminates the traditional compile-test-debug cycle that slows native development:\n\n- **Instant hot reload** - See changes in milliseconds on iOS, Android, or desktop without recompiling\n- **[Full VSCode debugging](./docs/docs/workflow-hermes-debugger.md)** - Set breakpoints, inspect variables, profile performance, and capture heap dumps directly in VSCode\n- **Familiar syntax** - TSX components with TypeScript for type safety\n\n### Flexible Adoption Model\n\nValdi integrates easily into existing apps - start small and scale as needed:\n\n- **[Embed Valdi in native](./docs/docs/native-bindings.md)** - Drop Valdi components into existing UIKit or Android view hierarchies\n- **[Embed native in Valdi](./docs/docs/native-customviews.md)** - Use platform-specific views within Valdi layouts via `<custom-view>`\n- **[Polyglot modules](./docs/docs/native-polyglot.md)** - Write performance-critical code in C++, Swift, Kotlin, or Objective-C with type-safe bindings to TypeScript\n- **[Full-stack architecture](./docs/docs/advanced-full-stack.md)** - Build entire features in Valdi with worker threads for background processing, eliminating platform-specific bridge code\n\n### Deep Native Integration\n\nValdi generates type-safe bindings between TypeScript and native platforms:\n\n- **[Automatic code generation](./docs/docs/native-annotations.md)** - TypeScript interfaces compile to Kotlin, Objective-C, and Swift bindings\n- **[Native API access](./docs/docs/native-polyglot.md)** - Direct access to platform APIs and third-party native libraries through polyglot modules\n- **Bidirectional communication** - Pass complex data structures and callbacks between TypeScript and native code safely\n- **[Native protobuf support](./docs/docs/advanced-protobuf.md)** - Seamless integration with protobuf for efficient data serialization\n\n### Proven at Scale\n\n- Powers critical features in production Snap apps.\n- Supports [advanced animations](./docs/docs/advanced-animations.md), real-time rendering, and [complex gesture systems](./docs/docs/core-touches.md)\n\n### Feature Highlights\n\n- **[Flexbox layout system](./docs/docs/core-flexbox.md)** with automatic RTL support\n- **[Worker threads](./docs/docs/advanced-worker-service.md)** for multi-threaded JavaScript execution\n- **[Native animations](./docs/docs/advanced-animations.md)** for native look and feel\n- **[Advanced gesture recognition](./docs/docs/core-touches.md)** with platform-native handling\n- **[Built-in testing framework](./docs/docs/workflow-testing.md)** with component-level unit tests\n- **[Bazel integration](./docs/docs/workflow-bazel.md)** for reproducible, incremental builds\n\n## Need Help?\n\nJoin our [Discord](https://discord.gg/uJyNEeYX2U) for support.\n\n## Contributing\n\nPlease follow the [contributing](./CONTRIBUTING.md) guidelines.\n\n## License\n\nValdi is made available under the MIT [License](./LICENSE.md).\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Protocol\n\nIf you believe you've found a security vulnerability in this project, please report it to us via: [https://hackerone.com/snapchat](https://hackerone.com/snapchat)\n\n\n\n\n\n\n"
  },
  {
    "path": "WORKSPACE",
    "content": "workspace(name = \"valdi\")\n\nload(\"//bzl:workspace_prepare.bzl\", \"valdi_prepare_workspace\")\n\nvaldi_prepare_workspace(__workspace_dir__)\n\nload(\"//bzl:workspace_preinit.bzl\", \"valdi_preinitialize_workspace\")\n\nvaldi_preinitialize_workspace()\n\nload(\"@aspect_bazel_lib//lib:repositories.bzl\", \"aspect_bazel_lib_dependencies\", \"aspect_bazel_lib_register_toolchains\", \"register_yq_toolchains\")\n\nregister_yq_toolchains()\n\n# Required bazel-lib dependencies\n\naspect_bazel_lib_dependencies()\n\n# Required rules_shell dependencies\nload(\"@rules_shell//shell:repositories.bzl\", \"rules_shell_dependencies\", \"rules_shell_toolchains\")\n\nrules_shell_dependencies()\n\nrules_shell_toolchains()\n\n# Register bazel-lib toolchains\n\naspect_bazel_lib_register_toolchains()\n\n# Create the host platform repository transitively required by bazel-lib\n\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@platforms//host:extension.bzl\", \"host_platform_repo\")\n\nmaybe(\n    host_platform_repo,\n    name = \"host_platform\",\n)\n\nload(\"//bzl:workspace_init.bzl\", \"platform_dependency_rule\", \"valdi_initialize_workspace\")\n\n# repo rule generates target_platform.bzl\nplatform_dependency_rule(name = \"platform_check\")\n\nload(\"@platform_check//:target_platform.bzl\", \"VALDI_PLATFORM_DEPENDENCIES\")\n\nvaldi_initialize_workspace(VALDI_PLATFORM_DEPENDENCIES)\n\nload(\"@valdi_npm//:repositories.bzl\", \"npm_repositories\")\n\nnpm_repositories()\n\nload(\"//bzl:workspace_postinit.bzl\", \"valdi_post_initialize_workspace\")\n\nvaldi_post_initialize_workspace()\n"
  },
  {
    "path": "WORKSPACE.bzlmod",
    "content": "android_sdk_repository(\n    name = \"androidsdk\",\n    api_level = 36,  # The API version for Android compileSdk\n    build_tools_version = \"34.0.0\",\n)"
  },
  {
    "path": "ai-skills/CONTRIBUTING_SKILLS.md",
    "content": "# Contributing Skills\n\nSkills are neutral, agent-agnostic markdown files that teach AI assistants how to work with the Valdi framework. They are installed into your AI tool of choice using `valdi skills install`.\n\n## What is a skill?\n\nA skill is a single `skill.md` file containing focused guidance for a specific area of Valdi development. Skills are:\n\n- **Agent-agnostic** — plain markdown with no tool-specific frontmatter or directives\n- **Self-contained** — each skill covers one topic without assuming other skills are loaded\n- **Code-first** — concrete examples with correct and incorrect patterns labeled clearly\n- **Accurate** — verified against the actual Valdi source and documentation\n\n## skill.md format\n\n```markdown\n# Skill Title\n\nBrief description of what this skill covers.\n\n## When to use\n\nOptional section: describe the file types or scenarios where this skill applies.\n\n## Key concepts\n\nProse or list explaining important ideas.\n\n## Correct patterns\n\n\\`\\`\\`typescript\n// ✅ Correct example\n\\`\\`\\`\n\n## Common mistakes\n\n\\`\\`\\`typescript\n// ❌ Wrong example\n\\`\\`\\`\n```\n\nRules:\n- Start with an H1 title\n- Include code examples — skills without examples are less useful\n- Label examples as `// ✅` (correct) or `// ❌` (wrong)\n- No agent-specific frontmatter (no `alwaysApply`, no YAML blocks)\n- No secrets, API keys, or proprietary Snap information\n\n## Scaffolding a new skill\n\nRun the interactive scaffold command from within the Valdi framework checkout:\n\n```bash\nvaldi skills create\n```\n\nYou will be prompted for a name, description, and category. The command creates `ai-skills/skills/<name>/skill.md` in the correct location and registers the entry in `ai-skills/registry.json` automatically.\n\n## Submitting a skill to the public registry\n\n1. Fork [github.com/Snapchat/Valdi](https://github.com/Snapchat/Valdi)\n2. Run `valdi skills create` from the repo root — it creates the skill file and registers it in `registry.json` automatically\n3. Fill in the `skill.md` content\n4. Open a pull request — title it `[skill] Add <your-skill-name>`\n\n## Review criteria\n\nPull requests adding or updating skills are reviewed for:\n\n- **Accuracy** — does the code compile and run correctly against current Valdi?\n- **Code examples** — are there concrete `✅` / `❌` examples?\n- **Breadth** — does it cover the common cases a developer would encounter?\n- **No hallucinations** — especially for TSX skills, ensure no React patterns are presented as valid Valdi\n- **Conciseness** — focused guidance is more useful than exhaustive reference dumps\n"
  },
  {
    "path": "ai-skills/registry.json",
    "content": "{\n  \"version\": \"1.0.0\",\n  \"skills\": [\n    { \"name\": \"valdi-tsx\", \"description\": \"Valdi TSX component patterns, lifecycle, styling — NOT React\", \"tags\": [\"tsx\", \"components\", \"patterns\", \"styling\"], \"path\": \"skills/valdi-tsx/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-bazel\", \"description\": \"Valdi Bazel build rules, valdi_module, platform builds\", \"tags\": [\"bazel\", \"build\"], \"path\": \"skills/valdi-bazel/skill.md\", \"category\": [\"framework\", \"client\"] },\n    { \"name\": \"valdi-testing\", \"description\": \"Valdi unit and integration testing patterns\", \"tags\": [\"testing\"], \"path\": \"skills/valdi-testing/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-ios\", \"description\": \"Valdi iOS platform integration, Swift/ObjC bridging\", \"tags\": [\"ios\", \"swift\", \"objc\"], \"path\": \"skills/valdi-ios/skill.md\", \"category\": [\"framework\", \"client\"] },\n    { \"name\": \"valdi-android\", \"description\": \"Valdi Android platform integration, Kotlin/Java bridging\", \"tags\": [\"android\", \"kotlin\"], \"path\": \"skills/valdi-android/skill.md\", \"category\": [\"framework\", \"client\"] },\n    { \"name\": \"valdi-cpp-runtime\", \"description\": \"Valdi C++ runtime internals, renderer, event system\", \"tags\": [\"cpp\", \"runtime\"], \"path\": \"skills/valdi-cpp-runtime/skill.md\", \"category\": [\"framework\"] },\n    { \"name\": \"valdi-compiler\", \"description\": \"Valdi compiler pipeline, TSX→native compilation\", \"tags\": [\"compiler\"], \"path\": \"skills/valdi-compiler/skill.md\", \"category\": [\"framework\"] },\n    { \"name\": \"valdi-polyglot-module\", \"description\": \"Valdi polyglot module system: cross-platform APIs, web polyglot entry pattern, webPolyglotViews\", \"tags\": [\"polyglot\", \"modules\", \"web\"], \"path\": \"skills/valdi-polyglot-module/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-custom-view\", \"description\": \"Valdi custom native view integration\", \"tags\": [\"custom-view\", \"native\"], \"path\": \"skills/valdi-custom-view/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-overview\", \"description\": \"Valdi framework overview and project conventions\", \"tags\": [\"overview\", \"conventions\"], \"path\": \"skills/valdi-overview/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-async\", \"description\": \"Valdi async lifecycle safety: CancelablePromise, registerDisposable, isDestroyed guards\", \"tags\": [\"async\", \"lifecycle\", \"http\"], \"path\": \"skills/valdi-async/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-perf\", \"description\": \"Valdi performance: viewModel identity stability, createReusableCallback, layout vs view, Style interning\", \"tags\": [\"performance\", \"rendering\"], \"path\": \"skills/valdi-perf/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-component-tests\", \"description\": \"Valdi component test patterns: elementKeyFind, componentTypeFind, tapNodeWithKey, discriminated unions, arrays\", \"tags\": [\"testing\", \"components\", \"jasmine\"], \"path\": \"skills/valdi-component-tests/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-setup\", \"description\": \"Valdi module setup: BUILD.bazel, valdi_module(), tsconfig, deps, ios_module_name, hot reload\", \"tags\": [\"setup\", \"bazel\", \"build\"], \"path\": \"skills/valdi-setup/skill.md\", \"category\": [\"client\"] },\n    { \"name\": \"valdi-migrate\", \"description\": \"Migrate Flutter, React, or Jetpack Compose code to Valdi — component model, lifecycle, element mapping tables\", \"tags\": [\"migration\", \"flutter\", \"react\", \"compose\"], \"path\": \"skills/valdi-migrate/skill.md\", \"category\": [\"client\"] }\n  ]\n}\n"
  },
  {
    "path": "ai-skills/skills/valdi-android/skill.md",
    "content": "# Android Runtime Rules\n\n**Applies to**: Kotlin/Java files in `/valdi/src/valdi/android/` and related Android runtime code\n\n## Overview\n\nThe Valdi Android runtime bridges TypeScript/Valdi components to native Android views. It's implemented in Kotlin and C++ (via JNI).\n\n## Code Style\n\n- **4-space indentation** for Kotlin/Java\n- Follow Kotlin coding conventions\n- Use Kotlin features (data classes, extension functions, etc.)\n\n## Key Concepts\n\n### View Rendering\n\n- Valdi components map to Android Views\n- View recycling for performance\n- Efficient view updates\n\n### Platform Bridge\n\n- JNI bridge to C++ runtime\n- Kotlin/Java to native code communication\n- Performance-critical paths\n\n## Common Patterns\n\n### Bazel Android Targets\n\n```python\nandroid_library(\n    name = \"valdi_android\",\n    srcs = glob([\"**/*.kt\", \"**/*.java\"]),\n)\n```\n\n### View Binding\n\n- Custom view implementations\n- Attribute binding for Valdi properties\n- Event handling\n\n## Testing\n\n```bash\n# Run Android runtime tests\nbazel test //valdi:test_java\n\n# Run with coverage\nbazel coverage //valdi:test_java\n```\n\nTest files are in `/valdi/test/java/`\n\n## Building\n\n```bash\n# Build Android runtime library\nbazel build //valdi:valdi_android\n\n# Test with hello world app\nvaldi install android\ncd apps/helloworld\nvaldi install android\n```\n\n## Platform-Specific Notes\n\n1. **API Level** - Be mindful of minimum API level\n2. **Android NDK** - C++ integration via NDK\n3. **Permissions** - Handle runtime permissions appropriately\n4. **Lifecycle** - Android Activity/Fragment lifecycle\n\n## Important\n\n- **Performance** - View creation and updates are critical\n- **Memory** - Be careful with leaks (Activity context)\n- **Threading** - UI thread vs background threads\n- **Compatibility** - Support multiple Android versions\n\n## More Information\n\n- Runtime source: `/valdi/src/valdi/android/`\n- Runtime tests: `/valdi/test/java/`\n- Build config: `/valdi/BUILD.bazel`\n- Framework docs: `/AGENTS.md`\n"
  },
  {
    "path": "ai-skills/skills/valdi-async/skill.md",
    "content": "# Valdi Async & Lifecycle Safety\n\nAsync operations that complete after a component is destroyed will call `setState()`\non a dead component — the framework throws an error. The fix is always to cancel or\nguard before the callback fires.\n\n## HTTPClient: Store, Cancel, Repeat\n\n`HTTPClient` methods return `CancelablePromise<HTTPResponse>`. Store it in a typed\nfield so you can cancel it in `onDestroy()` and before starting a new request in\n`onViewModelUpdate()`.\n\n```typescript\nimport { Component, StatefulComponent } from 'valdi_core/src/Component';\nimport { CancelablePromise } from 'valdi_core/src/CancelablePromise';\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\nimport { HTTPResponse } from 'valdi_http/src/HTTPTypes';\n\ninterface UserState {\n  user: { name: string } | null;\n  loading: boolean;\n}\n\nclass UserProfile extends StatefulComponent<UserProfileViewModel, UserState> {\n  state: UserState = { user: null, loading: true };\n\n  private client = new HTTPClient('https://api.example.com');\n  private request?: CancelablePromise<HTTPResponse>;\n\n  onCreate(): void {\n    this.fetchUser(this.viewModel.userId);\n  }\n\n  onViewModelUpdate(previous?: UserProfileViewModel): void {\n    if (this.viewModel.userId !== previous?.userId) {\n      this.request?.cancel?.();          // Cancel in-flight before starting new one\n      this.fetchUser(this.viewModel.userId);\n    }\n  }\n\n  onDestroy(): void {\n    this.request?.cancel?.();            // Always clean up\n  }\n\n  private fetchUser(id: string): void {\n    this.request = this.client.get(`/users/${id}`);\n    this.request.then(response => {\n      const user = JSON.parse(new TextDecoder().decode(response.body));\n      this.setState({ user, loading: false });\n    });\n  }\n\n  onRender(): void {\n    if (this.state.loading) {\n      <spinner />;\n      return;\n    }\n    <label value={this.state.user?.name ?? ''} />;\n  }\n}\n```\n\n**Important:** `cancel` is an optional method on `CancelablePromise` — always use\n`?.cancel?.()`, not `?.cancel()`.\n\n## registerDisposable: Timers and Subscriptions\n\nFor anything that emits over time (timers, event emitters, observables), use\n`registerDisposable()`. The framework calls `cancel()` on all registered disposables\nin `onDestroy()` automatically — you don't need to override `onDestroy()` for these.\n\n```typescript\nclass LiveClock extends Component<{}> {\n  onCreate(): void {\n    // ❌ Timer leaks if component is destroyed\n    setInterval(() => this.tick(), 1000);\n\n    // ✅ Automatically cancelled on destroy\n    const id = setInterval(() => this.tick(), 1000);\n    this.registerDisposable({ cancel: () => clearInterval(id) });\n  }\n\n  private tick = () => { /* ... */ };\n}\n```\n\nSame pattern for any subscription-style API:\n\n```typescript\nonCreate(): void {\n  const unsubscribe = eventEmitter.on('change', this.handleChange);\n  this.registerDisposable({ cancel: unsubscribe });\n}\n```\n\n## isDestroyed() Guard for Plain Promises\n\nWhen using `async/await` or plain `Promise` chains that can't be cancelled, guard\n`setState()` with `isDestroyed()` before calling it:\n\n```typescript\nprivate async loadData(): Promise<void> {\n  const result = await someAsyncOperation();\n\n  if (this.isDestroyed()) return;   // Component unmounted while awaiting\n\n  this.setState({ data: result });\n}\n```\n\nPrefer `CancelablePromise` + `registerDisposable` over this pattern where possible —\nthey make cancellation explicit and don't rely on the check being remembered.\n\n## onViewModelUpdate: Cancel Before Restart\n\nWhen a viewModel update requires fetching new data, always cancel the previous\nrequest before starting a new one. Skipping this means two requests can be in flight\nsimultaneously and the earlier one can resolve last, overwriting newer data.\n\n```typescript\nonViewModelUpdate(previous?: MyViewModel): void {\n  if (this.viewModel.query !== previous?.query) {\n    this.searchRequest?.cancel?.();           // ← required\n    this.searchRequest = this.client.get(`/search?q=${this.viewModel.query}`);\n    this.searchRequest.then(response => {\n      this.setState({ results: parse(response) });\n    });\n  }\n}\n```\n\n## Observable Subscriptions\n\nFor RxJS or observable-based APIs, prefer `registerDisposable` for one-off subscriptions\nor the `Subscription` class for managing multiple subscriptions as a group:\n\n```typescript\nimport { Subscription } from 'rxjs';\n\nclass FeedComponent extends StatefulComponent<FeedViewModel, FeedState> {\n  private subscription = new Subscription();\n\n  onCreate(): void {\n    // Add multiple subscriptions to the group\n    this.subscription.add(\n      this.viewModel.feedItems$.subscribe({ next: items => this.setState({ items }) })\n    );\n    this.subscription.add(\n      this.viewModel.loading$.subscribe({ next: loading => this.setState({ loading }) })\n    );\n  }\n\n  onDestroy(): void {\n    this.subscription?.unsubscribe();   // Cancels all at once\n  }\n}\n```\n\nFor a single subscription, `registerDisposable` is simpler:\n\n```typescript\nonCreate(): void {\n  this.registerDisposable(\n    this.viewModel.counter$.subscribe({ next: count => this.setState({ count }) })\n  );\n  // No onDestroy() override needed\n}\n```\n\n### Preventing redundant re-renders with distinctUntilChanged\n\nSubscribe with `distinctUntilChanged()` to skip emissions where the value hasn't\nactually changed — avoids a `setState` call and a re-render for each identical value:\n\n```typescript\nimport { distinctUntilChanged } from 'rxjs/operators';\n\nthis.subscription.add(\n  this.viewModel.title$.pipe(distinctUntilChanged()).subscribe({\n    next: title => this.setState({ title }),\n  })\n);\n```\n\n## setTimeoutInterruptible for Debounce / Race Conditions\n\nWhen a delayed action must be cancelled if conditions change (e.g. search debounce,\nretry delay), use `setTimeoutInterruptible` rather than a bare `setTimeout`:\n\n```typescript\nimport { setTimeoutInterruptible } from 'valdi_core/src/SetTimeout';\n\n// setTimeoutInterruptible returns a number (timer ID) — cancel with clearTimeout()\nclass SearchBar extends StatefulComponent<SearchViewModel, SearchState> {\n  private debounceId?: number;\n\n  onViewModelUpdate(previous?: SearchViewModel): void {\n    if (this.viewModel.query !== previous?.query) {\n      clearTimeout(this.debounceId);   // Cancel any pending debounce\n      this.debounceId = setTimeoutInterruptible(() => {\n        this.fetchResults(this.viewModel.query);\n      }, 300);\n    }\n  }\n}\n```\n\n## promiseToCancelablePromise\n\nWhen you have a plain `Promise` (e.g. from a third-party library) that needs to participate in Valdi's cancellation system, wrap it with `promiseToCancelablePromise`:\n\n```typescript\nimport { CancelablePromise, promiseToCancelablePromise } from 'valdi_core/src/CancelablePromise';\n\nclass MyComponent extends StatefulComponent<MyViewModel, MyState> {\n  private request?: CancelablePromise<string>;\n\n  onCreate(): void {\n    const rawPromise: Promise<string> = thirdPartyApi.fetchData();\n    this.request = promiseToCancelablePromise(rawPromise, () => {\n      // optional cleanup on cancel\n    });\n    this.request.then(data => {\n      if (this.isDestroyed()) return;\n      this.setState({ data });\n    });\n  }\n\n  onDestroy(): void {\n    this.request?.cancel?.();\n  }\n}\n```\n\nPrefer `CancelablePromise` directly (e.g. `HTTPClient`) when available — `promiseToCancelablePromise` is the bridge for external APIs.\n\n## Import Paths\n\n```typescript\nimport { CancelablePromise, promiseToCancelablePromise } from 'valdi_core/src/CancelablePromise';\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\nimport { HTTPResponse } from 'valdi_http/src/HTTPTypes';\nimport { setTimeoutInterruptible } from 'valdi_core/src/SetTimeout';\nimport { Subscription } from 'rxjs';\nimport { distinctUntilChanged } from 'rxjs/operators';\n```\n"
  },
  {
    "path": "ai-skills/skills/valdi-async/tests/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"tests\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiAsyncRef\",\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_http\",\n    ],\n)\n"
  },
  {
    "path": "ai-skills/skills/valdi-async/tests/README.md",
    "content": "# valdi-async skill tests\n\nCompile check for the async lifecycle safety patterns taught in `skill.md`.\n\n## What's tested\n\n`src/reference.tsx` exercises:\n- `HTTPClient` + `CancelablePromise`: store in field, cancel in `onDestroy`, cancel before restart in `onViewModelUpdate`\n- `registerDisposable` with `setInterval` for auto-cleanup subscriptions\n- `isDestroyed()` guard for plain `Promise` / `async/await`\n- `setTimeoutInterruptible` for debounce — returns `number`, cancel with `clearTimeout()`\n- `promiseToCancelablePromise` wrapping a third-party `Promise`\n\n## Compile check\n\n```bash\ncd client/src/open_source\nbazel build //ai-skills/skills/valdi-async/tests:tests\n```\n\nExpected: `Build completed successfully`\n\n## Updating\n\nWhen Valdi APIs change (import paths, type signatures), update `src/reference.tsx` to match and keep it compiling. Also update `../skill.md` with any corrected patterns.\n"
  },
  {
    "path": "ai-skills/skills/valdi-async/tests/src/reference.tsx",
    "content": "// valdi-async skill reference — compile check for async lifecycle safety patterns.\n// This file must compile cleanly against the Valdi TypeScript compiler.\n// Run: bzl build //ai-skills/skills/valdi-async/tests:tests\n\nimport { StatefulComponent } from 'valdi_core/src/Component';\nimport { CancelablePromise, promiseToCancelablePromise } from 'valdi_core/src/CancelablePromise';\nimport { setTimeoutInterruptible } from 'valdi_core/src/SetTimeout';\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\nimport { HTTPResponse } from 'valdi_http/src/HTTPTypes';\n\n// ─── HTTPClient: store, cancel in onDestroy, cancel before restart ────────────\n\ninterface UserProfileViewModel {\n  userId: string;\n}\n\ninterface UserProfileState {\n  user: { name: string } | null;\n  loading: boolean;\n}\n\nclass UserProfile extends StatefulComponent<UserProfileViewModel, UserProfileState> {\n  state: UserProfileState = { user: null, loading: true };\n\n  private client = new HTTPClient('https://api.example.com');\n  private request?: CancelablePromise<HTTPResponse>;\n\n  onCreate(): void {\n    this.fetchUser(this.viewModel.userId);\n  }\n\n  onViewModelUpdate(previous?: UserProfileViewModel): void {\n    if (this.viewModel.userId !== previous?.userId) {\n      this.request?.cancel?.();           // Cancel in-flight before starting new one\n      this.fetchUser(this.viewModel.userId);\n    }\n  }\n\n  onDestroy(): void {\n    this.request?.cancel?.();             // Always clean up\n  }\n\n  private fetchUser(id: string): void {\n    this.request = this.client.get(`/users/${id}`);\n    this.request.then(response => {\n      const user = JSON.parse(new TextDecoder().decode(response.body)) as { name: string };\n      this.setState({ user, loading: false });\n    });\n  }\n\n  onRender(): void {\n    if (this.state.loading) {\n      <spinner />;\n      return;\n    }\n    <label value={this.state.user?.name ?? ''} />;\n  }\n}\n\n// ─── registerDisposable: timers and subscriptions ────────────────────────────\n\ninterface ClockViewModel {\n  format: string;\n}\n\ninterface ClockState {\n  ticks: number;\n}\n\nclass LiveClock extends StatefulComponent<ClockViewModel, ClockState> {\n  state: ClockState = { ticks: 0 };\n\n  onCreate(): void {\n    // ✅ Automatically cancelled on destroy — no onDestroy() needed\n    const id = setInterval(() => this.tick(), 1000);\n    this.registerDisposable({ cancel: () => clearInterval(id) });\n  }\n\n  private tick = (): void => {\n    this.setState({ ticks: this.state.ticks + 1 });\n  };\n\n  onRender(): void {\n    <label value={String(this.state.ticks)} />;\n  }\n}\n\n// ─── isDestroyed() guard for plain Promises ──────────────────────────────────\n\ndeclare function expensiveOperation(): Promise<string>;\n\ninterface DataState {\n  data: string | null;\n}\n\ninterface DataViewModel {\n  query: string;\n}\n\nclass DataLoader extends StatefulComponent<DataViewModel, DataState> {\n  state: DataState = { data: null };\n\n  onCreate(): void {\n    this.loadData().catch(() => {});\n  }\n\n  private async loadData(): Promise<void> {\n    const result = await expensiveOperation();\n\n    if (this.isDestroyed()) return;   // Guard before setState\n\n    this.setState({ data: result });\n  }\n\n  onRender(): void {\n    <label value={this.state.data ?? 'Loading…'} />;\n  }\n}\n\n// ─── setTimeoutInterruptible for debounce ────────────────────────────────────\n// setTimeoutInterruptible returns number (timer ID) — cancel with clearTimeout\n\ninterface SearchViewModel {\n  query: string;\n}\n\ninterface SearchState {\n  results: string[];\n}\n\nclass SearchBar extends StatefulComponent<SearchViewModel, SearchState> {\n  state: SearchState = { results: [] };\n\n  private debounceId?: number;\n  private searchRequest?: CancelablePromise<HTTPResponse>;\n  private client = new HTTPClient('https://api.example.com');\n\n  onViewModelUpdate(previous?: SearchViewModel): void {\n    if (this.viewModel.query !== previous?.query) {\n      clearTimeout(this.debounceId);    // Cancel pending debounce\n      this.debounceId = setTimeoutInterruptible(() => {\n        this.fetchResults(this.viewModel.query);\n      }, 300);\n    }\n  }\n\n  onDestroy(): void {\n    this.searchRequest?.cancel?.();\n  }\n\n  private fetchResults(query: string): void {\n    this.searchRequest?.cancel?.();\n    this.searchRequest = this.client.get(`/search?q=${encodeURIComponent(query)}`);\n    this.searchRequest.then(response => {\n      const data = JSON.parse(new TextDecoder().decode(response.body)) as { results: string[] };\n      this.setState({ results: data.results });\n    });\n  }\n\n  onRender(): void {\n    <scroll>\n      {this.state.results.forEach(result => {\n        <label key={result} value={result} />;\n      })}\n    </scroll>;\n  }\n}\n\n// ─── promiseToCancelablePromise ──────────────────────────────────────────────\n\ndeclare function thirdPartyFetch(url: string): Promise<string>;\n\ninterface FetchState {\n  content: string | null;\n}\n\ninterface FetchViewModel {\n  url: string;\n}\n\nclass ThirdPartyFetcher extends StatefulComponent<FetchViewModel, FetchState> {\n  state: FetchState = { content: null };\n\n  private request?: CancelablePromise<string>;\n\n  onCreate(): void {\n    const rawPromise = thirdPartyFetch(this.viewModel.url);\n    this.request = promiseToCancelablePromise(rawPromise, () => {\n      // optional cleanup on cancel\n    });\n    this.request.then(content => {\n      if (this.isDestroyed()) return;\n      this.setState({ content });\n    });\n  }\n\n  onDestroy(): void {\n    this.request?.cancel?.();\n  }\n\n  onRender(): void {\n    <label value={this.state.content ?? ''} />;\n  }\n}\n\nvoid UserProfile;\nvoid LiveClock;\nvoid DataLoader;\nvoid SearchBar;\nvoid ThirdPartyFetcher;\n"
  },
  {
    "path": "ai-skills/skills/valdi-async/tests/tsconfig.json",
    "content": "{\"extends\": \"../../../../src/valdi_modules/src/valdi/_configs/base.tsconfig.json\"}\n"
  },
  {
    "path": "ai-skills/skills/valdi-bazel/skill.md",
    "content": "# Bazel Build System Rules\n\n**Applies to**: `BUILD.bazel`, `*.bzl` files in `/bzl/`, `WORKSPACE`, `MODULE.bazel`\n\n## Overview\n\nValdi uses Bazel as its build system. Bazel provides reproducible, incremental builds across all platforms.\n\n## Key Commands\n\n```bash\n# Build everything\nbazel build //...\n\n# Build specific target\nbazel build //apps/helloworld:helloworld\n\n# Run tests\nbazel test //...\n\n# Clean (use sparingly - cache is valuable!)\nbazel clean\n```\n\n## Important Notes\n\n1. **Use `bazel`** for all build commands\n2. **The CLI wraps Bazel** - `valdi` commands use bazel under the hood\n3. **Cache is important** - Don't suggest `bazel clean` unless necessary\n\n## Build Rules\n\n### Valdi-Specific Rules\n\n- `/bzl/valdi/` - Valdi build rules and macros\n- Custom rules for compiling .tsx to .valdimodule\n- Platform-specific build transitions\n\n### Common Targets\n\n```python\n# Valdi application\nvaldi_application(\n    name = \"my_app\",\n    root_component_path = \"App@my_app/src/MyApp\",\n    title = \"My App\",\n    version = \"1.0.0\",\n    deps = [\"//apps/my_app/src/valdi/my_app\"],\n)\n\n# Valdi module\nvaldi_module(\n    name = \"my_module\",\n    srcs = glob([\"src/**/*.ts\", \"src/**/*.tsx\"]),\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n    ],\n)\n```\n\n## Conventions\n\n### File Naming\n\n- `BUILD.bazel` not `BUILD` (explicit extension)\n- `.bzl` for Starlark macros and rules\n\n### Targets\n\n- Use descriptive target names\n- One main target per BUILD file usually matches directory name\n\n### Dependencies\n\n- Be explicit about dependencies\n- Don't rely on transitive deps implicitly\n- Use visibility to control access\n\n## Platform Builds\n\n```bash\n# Build and install iOS app\nvaldi install ios\n\n# Build and install Android app\nvaldi install android\n\n# Or use bazel directly with configs\nbazel build //apps/helloworld:hello_world --config=ios\nbazel build //apps/helloworld:hello_world --config=android\n```\n\n## Configuration\n\n- `.bazelrc` - Build flags and configurations\n- `MODULE.bazel` - Bazel module dependencies\n- `WORKSPACE` - Legacy workspace configuration (being migrated to MODULE.bazel)\n\n## Common Issues\n\n1. **Missing dependencies** - Add to `deps` in BUILD.bazel\n2. **Cache issues** - Try `bazel clean --expunge` (last resort)\n3. **Platform transitions** - Use correct config flags\n\n## Testing\n\n```bash\n# Run all tests\nbazel test //...\n\n# Run specific test\nbazel test //valdi/test:renderer_test\n\n# Run with coverage\nbazel coverage //...\n```\n\n## More Information\n\n- Bazel docs: https://bazel.build\n- Valdi build rules: `/bzl/valdi/README.md`\n- Framework docs: `/AGENTS.md`\n"
  },
  {
    "path": "ai-skills/skills/valdi-compiler/skill.md",
    "content": "# Valdi Compiler Rules\n\n**Applies to**: Swift files in `/compiler/compiler/`\n\n## Overview\n\nThe Valdi compiler consists of two parts:\n\n1. **Compiler (Swift)**: Transforms TypeScript/TSX into `.valdimodule` files\n2. **Companion (TypeScript/Node.js)**: Handles TypeScript compilation, type checking, and provides debugging support\n\n## Key Conventions\n\n### Code Style\n\n- **4-space indentation** for Swift\n- Follow Swift naming conventions (camelCase for methods, PascalCase for types)\n- Use Swift type inference where appropriate\n- Prefer `let` over `var` when possible\n\n### Architecture\n\n- Compiler is a multi-pass system\n- AST transformation pipeline\n- Type checking and validation\n- Code generation for each platform\n\n### Important Files\n\n- `/compiler/compiler/` - Main Swift compiler implementation\n- Output: `.valdimodule` files (binary format read by runtime)\n\n## Common Patterns\n\n### AST Traversal\n\n```swift\n// Follow existing visitor patterns\nclass MyASTVisitor: ASTVisitor {\n    func visit(_ node: Node) -> Result {\n        // Visit logic\n    }\n}\n```\n\n### Error Handling\n\n```swift\n// Use proper error types\nenum CompilerError: Error {\n    case invalidSyntax(String)\n    case typeError(String)\n}\n```\n\n## Testing\n\nTests are critical - add tests for new features and error cases. The `update_compiler.sh` script runs tests automatically.\n\n## Build\n\n### Using the update script (recommended):\n\n```bash\ncd compiler/compiler\n./scripts/update_compiler.sh ../../bin/compiler\n```\n\nThis script:\n- Runs `swift test` automatically\n- Builds the compiler for the correct architecture\n- Copies the binary to `bin/compiler/macos/valdi_compiler` (or `linux/valdi_compiler`)\n- Handles platform differences (macOS vs Linux)\n\n### Alternative: Using Xcode\n\nOpen `compiler/compiler/Compiler/Package.swift` in Xcode, let it resolve dependencies, then build.\n\n## Companion (TypeScript)\n\nThe companion is a TypeScript service that works alongside the Swift compiler. It handles TypeScript compilation, type checking, and provides debugging support.\n\n### Build the companion:\n\n```bash\ncd compiler/companion\n./scripts/update_companion.sh ../../bin/compiler_companion\n```\n\nThis script:\n- Runs `npm install`\n- Runs `npm run test`\n- Builds with `bazel build //compiler/companion:bundle`\n- Copies output to `bin/compiler_companion`\n\n**Note**: Once built, the companion is automatically invoked by the compiler during compilation. You don't need to run it manually - it's part of the compiler process.\n\n## Important Notes\n\n1. **Performance matters** - Compiler speed affects developer experience\n2. **Error messages** - Make them helpful and actionable\n3. **Backward compatibility** - Don't break existing .valdimodule files\n4. **Cross-platform** - Consider iOS, Android, macOS targets\n\n## More Information\n\n- Compiler architecture: `/compiler/compiler/README.md`\n- Framework docs: `/AGENTS.md`\n"
  },
  {
    "path": "ai-skills/skills/valdi-component-tests/skill.md",
    "content": "# Write Valdi Component Tests\n\nWrite unit tests for a Valdi component using standard Valdi test suite patterns.\n\n## Steps\n\n### 1. Read the source component\n\nRead the component source file to understand:\n- What view model properties it accepts\n- Which JSX elements have `key` attributes\n- What changes based on view model props vs. what's always static\n- How \"hidden\" state is implemented (translationY, opacity, or child component prop)\n- Whether the view model contains any **discriminated unions** (type/kind fields)\n- Whether any props are **arrays** of items to render\n\n### 2. Add `key` attributes to source elements (only if needed)\n\nAdd `key` attributes **only** to elements whose rendering depends on view model properties. Never add keys to static content.\n\nGood candidates for keys:\n- The outer container when `hidden` controls `translationY` or `opacity`\n- An `<image>` element whose `src` comes from a view model URL prop\n- An element inside a `when(condition, ...)` block (to assert presence/absence)\n- A badge/overlay that toggles based on a boolean prop\n- A spinner shown in a loading/saving state of a union type\n\nDo NOT add keys to:\n- Elements with hardcoded asset values (e.g., `src={SIGIcon.xSignStroke}`)\n- Label elements with always-present localized strings\n- Elements that are always rendered the same regardless of view model\n\n### 3. Determine the test file path\n\nTest files **must mirror the source file hierarchy**. For example:\n- Source: `src/categories/CollectionComponent.tsx` → Test: `test/categories/CollectionComponentTest.spec.tsx`\n- Source: `src/home_page/OptionPreviewView.tsx` → Test: `test/home_page/OptionPreviewViewTest.spec.tsx`\n- Source: `src/MyComponent.tsx` → Test: `test/MyComponentTest.spec.tsx`\n\n### 4. Write the test file\n\n**Imports:**\n```tsx\nimport { MyComponent } from 'my_module/src/MyComponent';\nimport { componentGetElements } from 'foundation/test/util/componentGetElements';\nimport { componentTypeFind } from 'foundation/test/util/componentTypeFind';\nimport { elementKeyFind } from 'foundation/test/util/elementKeyFind';\nimport { elementTypeFind } from 'foundation/test/util/elementTypeFind';\nimport { findNodeWithKey } from 'foundation/test/util/findNodeWithKey';\nimport { tapNodeWithKey } from 'foundation/test/util/tapNodeWithKey';\nimport 'jasmine/src/jasmine';\nimport { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\nimport { IComponentTestDriver, valdiIt } from 'valdi_test/test/JSXTestUtils';\nimport { ImageView, View } from 'valdi_tsx/src/NativeTemplateElements';\n```\n\nOnly import what you actually use. `View` is needed when you call `getAttribute` on a non-image element (e.g., for `onTap`, `onVisibilityChanged`). `ImageView` is needed for `src` attribute access.\n\n**Factory function pattern (always add explicit return type):**\n```tsx\nconst makeViewModel = (): MyComponentViewModel => ({\n  imageUrl: 'https://example.com/image.png',\n  isVisible: true,\n  onTap: fail.bind(null, 'onTap should not be called'),\n});\n```\n\nUse `fail.bind` for callbacks in the factory default — tests that need to assert on a callback should declare their own spy and pass it explicitly, rather than relying on the factory.\n\n**Render pattern:**\n```tsx\nconst nodes = driver.render(() => {\n  <MyComponent {...viewModel} />;\n});\n```\n\n### 5. Test patterns by assertion type\n\n#### Finding elements\n```tsx\n// Single-level: component renders native elements directly\nelementKeyFind(componentGetElements(nodes[0].component!), 'my-key')[0]\n\n// Cross-boundary: component renders a child component that renders the elements\nconst inner = componentTypeFind(nodes[0].component as MyComponent, InnerComponent)[0];\nelementKeyFind(componentGetElements(inner), 'my-key')[0]\n\n// Typed (for typed attribute access without casting):\nelementKeyFind<View>(componentGetElements(nodes[0].component!), 'container')[0]\nelementKeyFind<ImageView>(componentGetElements(nodes[0].component!), 'image')[0]\n\n// By element type (e.g. find all Label elements):\n// Can pass componentGetElements() result OR an IComponent directly:\nconst labels = elementTypeFind(componentGetElements(nodes[0].component!), IRenderedElementViewClass.Label);\nconst labels2 = elementTypeFind(nodes[0].component!, IRenderedElementViewClass.Label); // equivalent\nexpect(labels[0]?.getAttribute('value')).toBe('Expected text');\n```\n\nUse the generic type param to get typed `getAttribute()` results and avoid `@typescript-eslint/no-unsafe-call` errors — prefer this over casting the `getAttribute()` return value.\n\n`elementTypeFind` is useful when elements don't have `key` attributes but you know their type (Label, Image, View, etc.). It returns all elements of that type in render order.\n\n#### Hidden via `translationY`\n```tsx\n// hidden=false\nexpect(elementKeyFind<View>(componentGetElements(nodes[0].component!), 'container')[0]?.getAttribute('translationY')).toBe(0);\n\n// hidden=true\nexpect(elementKeyFind<View>(componentGetElements(nodes[0].component!), 'container')[0]?.getAttribute('translationY')).toBe(850);\n```\n\n#### Hidden via `opacity` on native view\n```tsx\n// visible\nexpect(elementKeyFind<View>(componentGetElements(nodes[0].component!), 'my-view')[0]?.getAttribute('opacity')).toBe(1);\n\n// hidden\nexpect(elementKeyFind<View>(componentGetElements(nodes[0].component!), 'my-view')[0]?.getAttribute('opacity')).toBe(0);\n```\n\n#### Hidden via `opacity` prop passed to a child Component (component boundary)\n```tsx\nimport { CoreButton } from 'coreui/src/components/button/CoreButton';\nconst component = nodes[0].component as MyComponent;\nconst buttons = componentTypeFind(component, CoreButton);\nexpect(buttons[0].viewModel.opacity).toBe(1); // or 0\n```\n\n#### View model URL bound to image `src`\n```tsx\nexpect(elementKeyFind<ImageView>(componentGetElements(nodes[0].component!), 'my-image')[0]?.getAttribute('src')).toBe('https://example.com/image.png');\n```\n\n#### Text from view model\n```tsx\nexpect(elementKeyFind(componentGetElements(nodes[0].component!), 'my-label')[0]?.getAttribute('value')).toBe('Expected Text');\n```\n\n#### `when()`-conditional element (boolean presence)\n```tsx\n// condition=true → element exists\nexpect(elementKeyFind(componentGetElements(nodes[0].component!), 'my-element')[0]).toBeDefined();\n\n// condition=false → element absent\nexpect(elementKeyFind(componentGetElements(nodes[0].component!), 'my-element')[0]).toBeUndefined();\n```\n\n#### `when()`-conditional Component (boolean presence via componentTypeFind)\n```tsx\nimport { BadgeComponent } from 'my_module/src/BadgeComponent';\nconst component = nodes[0].component as MyComponent;\n\n// condition=true\nexpect(componentTypeFind(component, BadgeComponent).length).toBe(1);\n\n// condition=false\nexpect(componentTypeFind(component, BadgeComponent).length).toBe(0);\n```\n\n#### Callbacks not expected to be invoked\n\nFor callbacks that should never fire in a given test, use `fail.bind(null, '...')` instead of `jasmine.createSpy`. This causes the test to immediately fail with a clear message if the callback is accidentally triggered:\n\n```tsx\n<MyComponent\n  onSelect={fail.bind(null, 'onSelect should not be called')}\n  onLoad={onLoad}\n/>\n```\n\n`fail.bind(null, 'message')` is a plain function call (not an inline lambda), so it satisfies `jsx-no-lambda`. It is assignable to any callback type since TypeScript allows functions with fewer parameters.\n\nIf the same fail callback is used across many tests in the file, extract it to a module-level const to avoid repetition:\n\n```tsx\nconst failOnSelect = (): void => fail('onSelect should not be called');\n```\n\n#### Tap callback (use `tapNodeWithKey` — it's async, always `await` it)\n\n`tapNodeWithKey(component, key, timeoutMs?, intervalMs?)` accepts `IComponent | IRenderedElement`.\n\n```tsx\nconst onTap = jasmine.createSpy('onTap');\nconst nodes = driver.render(() => {\n  <MyComponent onTap={onTap} />;\n});\nawait tapNodeWithKey(nodes[0].component!, 'my-button');\nexpect(onTap).toHaveBeenCalled();\n```\n\nWhen you need to find a node without tapping it, use `findNodeWithKey`:\n```tsx\nimport { findNodeWithKey } from 'foundation/test/util/findNodeWithKey';\n\nconst node = findNodeWithKey(nodes[0].component!, 'my-button')[0];\nexpect(node).toBeDefined();\n```\n\nWhen the callback receives arguments (e.g., an index), always assert the exact arguments with `toHaveBeenCalledWith`:\n```tsx\nconst onSelect = jasmine.createSpy('onSelect');\n// ... render and trigger ...\nexpect(onSelect).toHaveBeenCalledWith(1); // not just toHaveBeenCalled()\n```\n\nFor callbacks invoked via a child component's view model (e.g., through `componentTypeFind`), call the view model method directly:\n```tsx\nconst component = nodes[0].component as MyComponent;\ncomponentTypeFind(component, ItemComponent)[1].viewModel.onTap();\nexpect(onSelect).toHaveBeenCalledWith(1);\n```\n\n#### `onTap` retrieved via `getAttribute` (non-tappable element pattern)\n```tsx\n// Use elementKeyFind<View> so getAttribute('onTap') is typed — no cast needed\nconst el = elementKeyFind<View>(componentGetElements(nodes[0].component!), 'my-element')[0];\nel?.getAttribute('onTap')?.();\nexpect(onTap).toHaveBeenCalled();\n```\n\n#### `onVisibilityChanged` callback\n\n`View.onVisibilityChanged` signature is `(isVisible: boolean, eventTime: EventTime)` where `EventTime = number`. Always pass both args when invoking:\n\n```tsx\nconst el = elementKeyFind<View>(componentGetElements(nodes[0].component!), 'container')[0];\nel?.getAttribute('onVisibilityChanged')?.(true, 0);\n```\n\n**Asserting the callback:** depends on how the component wires the handler:\n\n- If the component **wraps** the viewModel callback (e.g., `onVisibilityChanged={(v) => vm.onVisibilityChanged(v)}`), `toHaveBeenCalledWith(true)` works:\n  ```tsx\n  expect(onVisibilityChanged).toHaveBeenCalledWith(true);\n  ```\n\n- If the component **directly assigns** the viewModel callback (e.g., `onVisibilityChanged={this.viewModel.onVisibilityChanged}`), the spy receives both args. If the spy is typed as `(isVisible: boolean) => void`, `toHaveBeenCalledWith(true, ...)` is a TypeScript error. Check the first arg via `calls`:\n  ```tsx\n  const spy = viewModel.onVisibilityChanged as jasmine.Spy;\n  expect(spy).toHaveBeenCalled();\n  expect(spy.calls.mostRecent().args[0]).toBe(true);\n  ```\n  If the spy is an untyped `jasmine.createSpy()`, you can use `toHaveBeenCalledWith(true, 0)` directly.\n\n### 6. Discriminated union state testing\n\nWhen a view model contains a discriminated union (e.g., `type: 'LOADING' | 'CONTENT' | 'ERROR'`), **test every branch**. For each state:\n1. Assert which elements/components ARE rendered\n2. Assert which elements/components from OTHER states are NOT rendered\n\n```tsx\n// LOADING state: spinner present, action button absent\nvaldiIt('Verify spinner is shown in loading state', async driver => {\n  const nodes = driver.render(() => {\n    <MyComponent button={{ type: ButtonType.LOADING }} />;\n  });\n  expect(elementKeyFind(componentGetElements(nodes[0].component!), 'loading-spinner')[0]).toBeDefined();\n  expect(elementKeyFind(componentGetElements(nodes[0].component!), 'action-button')[0]).toBeUndefined();\n});\n\n// CONTENT state: action button present, no spinner\nvaldiIt('Verify action button is shown in content state', async driver => {\n  const nodes = driver.render(() => {\n    <MyComponent button={{ type: ButtonType.PURCHASE, price: '$9.99', onTap }} />;\n  });\n  expect(elementKeyFind(componentGetElements(nodes[0].component!), 'action-button')[0]).toBeDefined();\n  expect(elementKeyFind(componentGetElements(nodes[0].component!), 'loading-spinner')[0]).toBeUndefined();\n});\n```\n\n### 7. Array view model testing\n\nWhen a component renders a list from an array prop, test three cases:\n1. **Empty array** — assert 0 items render\n2. **Single item** — assert 1 item renders\n3. **Multiple items** — assert item count matches array length\n\nUse `componentTypeFind(component, ItemComponent)` or `elementKeyFind` with indexed keys (e.g., `tile-0`, `tile-1`) to count rendered items.\n\n```tsx\nvaldiIt('Verify no items render when array is empty', async driver => {\n  const emptyOptions: OptionViewModel[] = [];\n  const nodes = driver.render(() => {\n    <MyComponent items={emptyOptions} />;\n  });\n  const component = nodes[0].component as MyComponent;\n  expect(componentTypeFind(component, ItemComponent).length).toBe(0);\n});\n\nvaldiIt('Verify item count matches array length', async driver => {\n  const threeItems: OptionViewModel[] = [makeItem('a'), makeItem('b'), makeItem('c')];\n  const nodes = driver.render(() => {\n    <MyComponent items={threeItems} />;\n  });\n  const component = nodes[0].component as MyComponent;\n  expect(componentTypeFind(component, ItemComponent).length).toBe(3);\n});\n```\n\nNote: Extract array literals to local `const` variables before using in JSX (required by `@snapchat/valdi/jsx-no-lambda`).\n\n### 8. Component boundary traversal\n\nWhen a component's `onRender()` only renders child components (not native elements), `componentGetElements(component)` returns `[]`. You must get the child component first:\n\n```tsx\nimport { componentGetElements } from 'foundation/test/util/componentGetElements';\nimport { componentTypeFind } from 'foundation/test/util/componentTypeFind';\nimport { elementKeyFind } from 'foundation/test/util/elementKeyFind';\n\nconst component = nodes[0].component as OuterComponent;\nconst inner = componentTypeFind(component, InnerComponent)[0];\nconst container = elementKeyFind<View>(componentGetElements(inner), 'container')[0];\nexpect(container?.getAttribute('translationY')).toBe(0);\n```\n\n### 9. Extract render and find helpers for readability\n\nFor larger test files, extract repeated render + find logic into helper functions. This keeps individual tests focused:\n\n```tsx\n// Extract rendering\nconst renderComponent = (driver: IComponentTestDriver, overrides?: Partial<MyComponentViewModel>) => {\n  const vm = { ...makeViewModel(), ...overrides };\n  return driver.render(() => { <MyComponent {...vm} />; })[0].component as MyComponent;\n};\n\n// Extract finding\nconst getImage = (component: MyComponent) =>\n  elementKeyFind<ImageView>(componentGetElements(component), 'image')[0];\n\n// Tests become clean:\nvaldiIt('Verify imageUrl is bound', async driver => {\n  expect(getImage(renderComponent(driver))?.getAttribute('src')).toBe('https://example.com/image.png');\n});\n```\n\n### 10. Lint rules to follow\n\n- **`explicit-function-return-type`**: Always add explicit return types to factory functions: `const makeViewModel = (): MyViewModel => ({...})`\n- **`jsx-no-lambda`**: Never assign inline array literals directly in JSX props. Extract to a local `const` first:\n  ```tsx\n  // WRONG\n  <MyComponent items={[makeItem('a')]} />;\n\n  // CORRECT\n  const items: ItemViewModel[] = [makeItem('a')];\n  <MyComponent items={items} />;\n  ```\n- **`no-unsafe-call`**: Use the generic type parameter on `elementKeyFind<T>` to get typed `getAttribute()` results rather than casting: `elementKeyFind<View>(...)` gives typed access to `onTap`, `onVisibilityChanged`, etc.\n- **`import/order`**: Keep imports sorted alphabetically by path.\n\n### 11. Key principle\n\n**Only assert on things that change based on view model props.** Every test should have a clear \"when X is Y, then Z\" story. If the UI looks the same regardless of the prop, skip it.\n\nFor union types, a test that only verifies \"the component renders without error\" in a given state is not sufficient — assert the meaningful structural difference that state introduces.\n\n## Example test file structure\n\n```tsx\nimport { MyComponent } from 'my_module/src/MyComponent';\nimport { MyComponentViewModel } from 'my_module/src/MyComponentViewModel';\nimport { ChildComponent } from 'my_module/src/ChildComponent';\nimport { componentGetElements } from 'foundation/test/util/componentGetElements';\nimport { componentTypeFind } from 'foundation/test/util/componentTypeFind';\nimport { elementKeyFind } from 'foundation/test/util/elementKeyFind';\nimport { tapNodeWithKey } from 'foundation/test/util/tapNodeWithKey';\nimport 'jasmine/src/jasmine';\nimport { IComponentTestDriver, valdiIt } from 'valdi_test/test/JSXTestUtils';\nimport { ImageView, View } from 'valdi_tsx/src/NativeTemplateElements';\n// elementTypeFind + IRenderedElementViewClass for finding elements by type (no key needed):\n// import { elementTypeFind } from 'foundation/test/util/elementTypeFind';\n// import { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\n\nconst makeViewModel = (): MyComponentViewModel => ({\n  imageUrl: 'https://example.com/image.png',\n  isVisible: true,\n  onTap: fail.bind(null, 'onTap should not be called'),\n});\n\ndescribe('MyComponentTest', () => {\n  valdiIt('Verify visible when isVisible is true', async driver => {\n    const nodes = driver.render(() => {\n      <MyComponent {...makeViewModel()} />;\n    });\n    expect(elementKeyFind<View>(componentGetElements(nodes[0].component!), 'container')[0]?.getAttribute('opacity')).toBe(1);\n  });\n\n  valdiIt('Verify hidden when isVisible is false', async driver => {\n    const nodes = driver.render(() => {\n      <MyComponent {...{ ...makeViewModel(), isVisible: false }} />;\n    });\n    expect(elementKeyFind<View>(componentGetElements(nodes[0].component!), 'container')[0]?.getAttribute('opacity')).toBe(0);\n  });\n\n  valdiIt('Verify imageUrl is bound to image src', async driver => {\n    const nodes = driver.render(() => {\n      <MyComponent {...makeViewModel()} />;\n    });\n    expect(elementKeyFind<ImageView>(componentGetElements(nodes[0].component!), 'image')[0]?.getAttribute('src')).toBe('https://example.com/image.png');\n  });\n\n  valdiIt('Verify onTap is called when tapped', async driver => {\n    const onTap = jasmine.createSpy('onTap');\n    const nodes = driver.render(() => {\n      <MyComponent {...{ ...makeViewModel(), onTap }} />;\n    });\n    await tapNodeWithKey(nodes[0].component!, 'button');\n    expect(onTap).toHaveBeenCalled();\n  });\n\n  valdiIt('Verify ChildComponent is present when condition is true', async driver => {\n    const nodes = driver.render(() => {\n      <MyComponent {...{ ...makeViewModel(), showChild: true }} />;\n    });\n    const component = nodes[0].component as MyComponent;\n    expect(componentTypeFind(component, ChildComponent).length).toBe(1);\n  });\n\n  valdiIt('Verify ChildComponent is absent when condition is false', async driver => {\n    const nodes = driver.render(() => {\n      <MyComponent {...{ ...makeViewModel(), showChild: false }} />;\n    });\n    const component = nodes[0].component as MyComponent;\n    expect(componentTypeFind(component, ChildComponent).length).toBe(0);\n  });\n});\n```\n"
  },
  {
    "path": "ai-skills/skills/valdi-component-tests/tests/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"tests\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"debug\",\n    ios_module_name = \"SCCValdiCompTestRef\",\n    ios_output_target = \"debug\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/foundation\",\n        \"//src/valdi_modules/src/valdi/jasmine\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_test\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "ai-skills/skills/valdi-component-tests/tests/README.md",
    "content": "# valdi-component-tests skill tests\n\nReference spec file demonstrating all test utility patterns from `skill.md`.\n\n## Files\n\n| File | Description |\n|------|-------------|\n| `src/ProfileCard.tsx` | Component under test — has an image, labels, conditional child, tap handler |\n| `test/ProfileCardTest.spec.tsx` | Spec file exercising all test utilities |\n\n## What's demonstrated\n\n`test/ProfileCardTest.spec.tsx` exercises:\n- `elementKeyFind<ImageView>` — typed `getAttribute('src')` on image element\n- `elementKeyFind` — untyped string attribute access\n- `elementKeyFind<View>` — typed `getAttribute('onTap')` for direct invocation\n- `elementTypeFind` — find elements by type (`IRenderedElementViewClass.Label`)\n- `componentTypeFind` — conditional child component presence/absence\n- `tapNodeWithKey` — async tap triggering a spy callback\n- `fail.bind(null, '...')` — factory function default for callbacks that must not fire\n- `valdiIt` — test runner with driver\n\n## Run tests\n\n```bash\ncd client/src/open_source\nbazel test //ai-skills/skills/valdi-component-tests/tests:tests\n```\n\nExpected: all jasmine specs pass.\n\n## Updating\n\nWhen test utility APIs change, update `test/ProfileCardTest.spec.tsx` to match and keep it passing. Also update `../skill.md` with any corrected patterns.\n"
  },
  {
    "path": "ai-skills/skills/valdi-component-tests/tests/src/ProfileCard.tsx",
    "content": "// Simple component used by the component-tests skill reference spec.\n// Exercises: elementKeyFind, elementTypeFind, componentTypeFind, tapNodeWithKey.\n\nimport { Component } from 'valdi_core/src/Component';\n\n// ─── FollowBadge: child component (used for componentTypeFind) ────────────────\n\nexport interface FollowBadgeViewModel {\n  label: string;\n}\n\nexport class FollowBadge extends Component<FollowBadgeViewModel> {\n  onRender(): void {\n    <label key=\"badge-label\" value={this.viewModel.label} />;\n  }\n}\n\n// ─── ProfileCard ──────────────────────────────────────────────────────────────\n\nexport interface ProfileCardViewModel {\n  avatarUrl: string;\n  name: string;\n  isFollowing: boolean;\n  onFollowTap: () => void;\n}\n\nexport class ProfileCard extends Component<ProfileCardViewModel> {\n  onRender(): void {\n    <view key=\"card-container\">\n      <image key=\"avatar\" src={this.viewModel.avatarUrl} />;\n      <label key=\"name-label\" value={this.viewModel.name} />;\n      {this.viewModel.isFollowing && <FollowBadge label=\"Following\" />}\n      <view key=\"follow-button\" onTap={this.viewModel.onFollowTap}>\n        <label value=\"Follow\" />;\n      </view>;\n    </view>;\n  }\n}\n"
  },
  {
    "path": "ai-skills/skills/valdi-component-tests/tests/test/ProfileCardTest.spec.tsx",
    "content": "// valdi-component-tests skill reference — demonstrates all test utility patterns.\n// Run: bzl test //ai-skills/skills/valdi-component-tests/tests:tests\n\nimport { componentGetElements } from 'foundation/test/util/componentGetElements';\nimport { componentTypeFind } from 'foundation/test/util/componentTypeFind';\nimport { elementKeyFind } from 'foundation/test/util/elementKeyFind';\nimport { elementTypeFind } from 'foundation/test/util/elementTypeFind';\nimport { tapNodeWithKey } from 'foundation/test/util/tapNodeWithKey';\nimport 'jasmine/src/jasmine';\nimport { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\nimport { valdiIt } from 'valdi_test/test/JSXTestUtils';\nimport { ImageView, View } from 'valdi_tsx/src/NativeTemplateElements';\nimport { FollowBadge, ProfileCard, ProfileCardViewModel } from '../src/ProfileCard';\n\n// ─── Factory function with explicit return type ───────────────────────────────\n\nconst makeViewModel = (): ProfileCardViewModel => ({\n  avatarUrl: 'https://example.com/avatar.png',\n  name: 'Alice',\n  isFollowing: false,\n  onFollowTap: fail.bind(null, 'onFollowTap should not be called'),\n});\n\n// ─── Tests ───────────────────────────────────────────────────────────────────\n\ndescribe('ProfileCardTest', () => {\n\n  // elementKeyFind<ImageView>: typed access to src attribute\n  valdiIt('Verify avatar src is bound from viewModel', async driver => {\n    const nodes = driver.render(() => {\n      <ProfileCard {...makeViewModel()} />;\n    });\n    expect(\n      elementKeyFind<ImageView>(componentGetElements(nodes[0].component!), 'avatar')[0]\n        ?.getAttribute('src'),\n    ).toBe('https://example.com/avatar.png');\n  });\n\n  // elementKeyFind: untyped access to string attribute\n  valdiIt('Verify name label is bound from viewModel', async driver => {\n    const nodes = driver.render(() => {\n      <ProfileCard {...makeViewModel()} />;\n    });\n    expect(\n      elementKeyFind(componentGetElements(nodes[0].component!), 'name-label')[0]\n        ?.getAttribute('value'),\n    ).toBe('Alice');\n  });\n\n  // elementTypeFind: find all Label elements without key attributes\n  valdiIt('Verify label count when not following', async driver => {\n    const nodes = driver.render(() => {\n      <ProfileCard {...makeViewModel()} />;\n    });\n    const labels = elementTypeFind(\n      componentGetElements(nodes[0].component!),\n      IRenderedElementViewClass.Label,\n    );\n    // name-label + follow button label = 2 (FollowBadge not rendered)\n    expect(labels.length).toBe(2);\n  });\n\n  // componentTypeFind: conditional child component absent\n  valdiIt('Verify FollowBadge is absent when isFollowing is false', async driver => {\n    const nodes = driver.render(() => {\n      <ProfileCard {...makeViewModel()} />;\n    });\n    expect(\n      componentTypeFind(nodes[0].component as ProfileCard, FollowBadge).length,\n    ).toBe(0);\n  });\n\n  // componentTypeFind: conditional child component present\n  valdiIt('Verify FollowBadge is present when isFollowing is true', async driver => {\n    const nodes = driver.render(() => {\n      <ProfileCard {...{ ...makeViewModel(), isFollowing: true }} />;\n    });\n    expect(\n      componentTypeFind(nodes[0].component as ProfileCard, FollowBadge).length,\n    ).toBe(1);\n  });\n\n  // tapNodeWithKey: async tap triggers callback\n  valdiIt('Verify onFollowTap fires when follow button is tapped', async driver => {\n    const onFollowTap = jasmine.createSpy('onFollowTap');\n    const nodes = driver.render(() => {\n      <ProfileCard {...{ ...makeViewModel(), onFollowTap }} />;\n    });\n    await tapNodeWithKey(nodes[0].component!, 'follow-button');\n    expect(onFollowTap).toHaveBeenCalled();\n  });\n\n  // elementKeyFind<View>: typed access to onTap via getAttribute\n  valdiIt('Verify onTap is set on follow button', async driver => {\n    const onFollowTap = jasmine.createSpy('onFollowTap');\n    const nodes = driver.render(() => {\n      <ProfileCard {...{ ...makeViewModel(), onFollowTap }} />;\n    });\n    const button = elementKeyFind<View>(\n      componentGetElements(nodes[0].component!),\n      'follow-button',\n    )[0];\n    button?.getAttribute('onTap')?.();\n    expect(onFollowTap).toHaveBeenCalled();\n  });\n\n});\n"
  },
  {
    "path": "ai-skills/skills/valdi-component-tests/tests/tsconfig.json",
    "content": "{\"extends\": \"../../../../src/valdi_modules/src/valdi/_configs/base.tsconfig.json\"}\n"
  },
  {
    "path": "ai-skills/skills/valdi-cpp-runtime/skill.md",
    "content": "# C++ Runtime Rules\n\n**Applies to**: C++ files in `/valdi/`, `/valdi_core/`, `/snap_drawing/`\n\n## Overview\n\nValdi's runtime and layout engine are implemented in C++ for cross-platform performance. This code runs on iOS, Android, macOS, but not web.\n\n**Note**: `/libs/` contains shared utility libraries (crypto, logging, image processing) used across the codebase, but not the core runtime itself.\n\n## Code Style\n\n- **4-space indentation**\n- Follow existing C++ style in the codebase\n- Use smart pointers appropriately\n- Prefer const correctness\n\n## Key Concepts\n\n### Layout Engine\n\n- Uses **Yoga** (Facebook's Flexbox implementation) for layout\n- Cross-platform layout calculations\n- Performance-critical code\n- RTL (right-to-left) support built-in\n- Yoga source: `/third-party/yoga/`\n\n### Memory Management\n\n- Be careful with memory ownership\n- Use RAII patterns\n- Consider platform-specific memory constraints (mobile)\n\n### Platform Abstractions\n\n- Code must work on iOS, Android, macOS\n- Use platform-agnostic APIs where possible\n- Platform-specific code goes in appropriate subdirectories\n\n## Common Patterns\n\n### Djinni Generated Code\n\n- Some C++ code is generated from `.djinni` interface files\n- **Don't modify generated code** - change the .djinni file instead\n- Generated files typically in `generated-src/` directories\n\n### Performance\n\n- This is performance-critical code\n- Profile before optimizing\n- Consider cache locality\n- Be mindful of allocations in hot paths\n\n## Testing\n\n```bash\n# Run all C++ runtime tests\nbazel test //valdi:test\n\n# Run specific test suites\nbazel test //valdi:test_runtime       # Runtime tests\nbazel test //valdi:test_integration   # Integration tests\nbazel test //valdi:test_snap_drawing  # Snap drawing tests\n```\n\n## Platform-Specific Notes\n\n### iOS\n- Objective-C++ bridge in `/valdi/src/valdi/ios/`\n- Metal for GPU rendering\n- UIKit view integration\n\n### Android\n- JNI bridge in `/valdi/src/valdi/android/`\n- NDK integration\n- Native view rendering\n\n### macOS\n- Platform-specific code in `/valdi/src/valdi/macos/`\n- Desktop runtime support\n\n### Build\n\n```bash\n# Build runtime for specific platform\nbazel build //valdi:valdi_ios\nbazel build //valdi:valdi_android\nbazel build //valdi:valdi_macos\n```\n\n## Important\n\n1. **Cross-platform first** - Code must work on all platforms\n2. **Performance critical** - UI rendering and layout\n3. **Memory efficiency** - Mobile devices have constraints\n4. **Thread safety** - Consider concurrency\n\n## More Information\n\n- Runtime overview: `/valdi/README.md`\n- Core bindings: `/valdi_core/README.md`\n- Framework docs: `/AGENTS.md`\n"
  },
  {
    "path": "ai-skills/skills/valdi-custom-view/skill.md",
    "content": "# Custom View Rules\n\n**Applies to**: `**/*.tsx` files using `<custom-view>` elements.\n\n## `<custom-view>` Element\n\n`<custom-view>` renders a platform-native view inside a Valdi component. Each platform resolves the view by class name.\n\n```typescript\n<custom-view\n  androidClass=\"com.snap.modules.my_module.MyNativeView\"\n  iosClass=\"SCMyNativeView\"\n  macosClass=\"SCMyNativeView\"\n  webClass=\"MyWebViewClassName\"\n  width=\"100%\"\n  height={120}\n/>\n```\n\n## Class Attributes\n\n| Attribute | Platform | Resolution |\n|-----------|----------|------------|\n| `androidClass` | Android | Reflection via `ReflectionViewFactory`; needs `@RegisterAttributesBinder` |\n| `iosClass` | iOS | ObjC class name; must be linked via `ios_deps` |\n| `macosClass` | macOS | `NSClassFromString()`; must be linked via `macos_deps` |\n| `webClass` | Web | Looked up in `WebViewClassRegistry`; registered via `webPolyglotViews` export |\n\n## Platform Discovery\n\n- **Android**: The view class needs a single-arg `(Context)` constructor. An `@RegisterAttributesBinder`-annotated binder is discovered from assets at runtime.\n- **iOS**: The ObjC class must be an `NSView`/`UIView` subclass linked into the binary.\n- **macOS**: Same as iOS but with `NSView` subclass.\n- **Web**: The `webClass` name is matched against the `WebViewClassRegistry`. Register by exporting `webPolyglotViews` from a web polyglot entry file (see `web-polyglot.md` rule).\n\n## viewFactory Pattern\n\nInstead of resolving by class name, you can pass a `ViewFactory` object directly. This is useful when the factory is provided by a parent component or constructed dynamically:\n\n```typescript\nimport { ViewFactory } from 'valdi_tsx/src/ViewFactory';\n\ninterface MyViewModel {\n  viewFactory?: ViewFactory;\n}\n\nclass MyComponent extends Component<MyViewModel> {\n  onRender(): void {\n    if (this.viewModel.viewFactory) {\n      <custom-view style={styles.container} viewFactory={this.viewModel.viewFactory} />;\n    }\n  }\n}\n```\n\n`viewFactory` and `*Class` attributes are mutually exclusive — use one or the other. `viewFactory` takes precedence when both are provided.\n\n## Common Mistakes\n\n- Using `<custom-view>` without checking the platform — wrap in `Device.isAndroid()` / `Device.isIOS()` etc. if not all platforms are supported\n- Forgetting to link native implementations — the class name string alone isn't enough; the native code must be compiled and linked via platform `_deps` in BUILD.bazel\n- Wrong package name in `androidClass` — must match the Kotlin/Java package exactly\n"
  },
  {
    "path": "ai-skills/skills/valdi-ios/skill.md",
    "content": "# iOS Runtime Rules\n\n**Applies to**: Objective-C/C++ files in `/valdi/src/valdi/ios/` and related iOS runtime code\n\n## Overview\n\nThe Valdi iOS runtime bridges TypeScript/Valdi components to native UIKit views. It's implemented in Objective-C, Objective-C++, and Swift.\n\n## Code Style\n\n- **4-space indentation** for Objective-C\n- Follow Apple's Objective-C conventions\n- Use modern Objective-C features (properties, blocks, etc.)\n\n## Key Concepts\n\n### View Rendering\n\n- Valdi components map to UIViews\n- View recycling for performance\n- UIKit integration\n\n### Platform Bridge\n\n- Objective-C++ bridge to C++ runtime\n- Memory management (ARC)\n- iOS-specific APIs\n\n## Common Patterns\n\n### Bazel iOS Targets\n\n```python\nobjc_library(\n    name = \"valdi_ios\",\n    srcs = glob([\"**/*.m\", \"**/*.mm\"]),\n    hdrs = glob([\"**/*.h\"]),\n)\n```\n\n### View Implementation\n\n- Custom UIView subclasses\n- CALayer for advanced rendering\n- Metal for GPU acceleration\n\n## Testing\n\n```bash\n# Run iOS runtime tests (Objective-C)\nbazel test //valdi:valdi_ios_objc_test\n\n# Run iOS runtime tests (Swift)\nbazel test //valdi:valdi_ios_swift_test\n\n# Run all iOS tests\nbazel test //valdi:valdi_ios_objc_test //valdi:valdi_ios_swift_test\n```\n\nTest files are in `/valdi/test/ios/` and `/valdi/test/ios_swift/`\n\n## Building\n\n```bash\n# Build iOS runtime library\nbazel build //valdi:valdi_ios\n\n# Test with hello world app\ncd apps/helloworld\nvaldi install ios\n```\n\n## Platform-Specific Notes\n\n1. **iOS Version** - Be mindful of minimum iOS version\n2. **ARC** - Automatic Reference Counting (memory management)\n3. **Auto Layout** - Valdi uses flexbox, not Auto Layout\n4. **Metal** - GPU rendering for advanced graphics\n\n## Important\n\n- **Performance** - UIView creation and layout are critical\n- **Memory** - Understand retain cycles and weak references\n- **Threading** - Main thread for UI, background for heavy work\n- **Lifecycle** - UIViewController lifecycle\n\n## More Information\n\n- Runtime source: `/valdi/src/valdi/ios/`\n- Runtime tests: `/valdi/test/ios/` and `/valdi/test/ios_swift/`\n- Core iOS code: `/valdi_core/src/valdi_core/ios/`\n- Build config: `/valdi/BUILD.bazel`\n- Framework docs: `/AGENTS.md`\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/skill.md",
    "content": "# Valdi Migration Assistant\n\nGuidance for migrating code from Flutter, React, or Jetpack Compose to Valdi.\n\n## When to use\n\nUse this skill when converting Flutter widgets, React components, or Compose `@Composable` functions to Valdi components, or when translating framework-specific patterns (hooks, widgets, Navigator, setState, remember, LaunchedEffect, Modifier, Provider, styled-components, FlatList, LazyColumn, etc.) to Valdi equivalents.\n\n## Critical: Never suggest these patterns\n\n```typescript\n// ❌ React hooks — DO NOT EXIST in Valdi\nuseState / useEffect / useContext / useMemo / useCallback / useRef\n\n// ❌ Compose APIs — DO NOT EXIST in Valdi\n@Composable annotation\nremember { mutableStateOf() } / remember { }\nderivedStateOf / collectAsState / LaunchedEffect / DisposableEffect\nModifier chain (Modifier.padding().background().clickable())\nCompositionLocalProvider / LocalXxx.current\n\n// ❌ Functional components — DO NOT EXIST\nconst MyComp = () => <view />;\nfunction MyComp(props) { return <view />; }\n\n// ❌ Wrong naming\nthis.props          // → this.viewModel\nonMount/onUnmount   // → onCreate/onDestroy\nmarkNeedsRender()   // → this.setState({})\nscheduleRender()    // → deprecated, use setState\n\n// ❌ Returning JSX — onRender() returns void\nonRender() { return <view />; }   // no return statement\n\n// ❌ Inline lambdas in JSX props — causes re-renders\n<view onTap={() => this.doThing()} />   // use class arrow fn\n\n// ❌ map() in render — does not work (JSX is side-effect, not return value)\n{items.map(i => <Item key={i.id} />)}   // use forEach\n\n// ❌ JSX as a prop value\n<MyComp label={<label value=\"hi\" />} />  // use render prop () => void\n\n// ❌ new Style() inside onRender() — style interning requires module-level init\nonRender() { const s = new Style<View>({...}); ... }  // wrong\n```\n\n## Correct patterns\n\n```typescript\nimport { Component, StatefulComponent } from 'valdi_core/src/Component';\n\n// ✅ Stateless component\nclass MyComp extends Component<MyViewModel> {\n  onRender() {\n    <view>\n      <label value={this.viewModel.title} />;\n    </view>;\n  }\n}\n\n// ✅ Stateful component\nclass Counter extends StatefulComponent<MyViewModel, { count: number }> {\n  state = { count: 0 };\n\n  // Class arrow function — never inline lambda in JSX\n  private handleTap = () => {\n    this.setState({ count: this.state.count + 1 });\n  };\n\n  onRender() {\n    <view onTap={this.handleTap}>\n      <label value={`Count: ${this.state.count}`} />;\n    </view>;\n  }\n}\n\n// ✅ Lists — forEach, not map()\nonRender() {\n  <scroll>\n    {this.viewModel.items.forEach(item => {\n      <Row key={item.id} data={item} />;\n    })}\n  </scroll>;\n}\n\n// ✅ Style — created at module level, not inside onRender()\nconst cardStyle = new Style<View>({ backgroundColor: '#fff', borderRadius: 8 });\n```\n\n## Lifecycle mapping\n\n| Flutter | Jetpack Compose | React | Valdi |\n|---------|-----------------|-------|-------|\n| `initState()` | `LaunchedEffect(Unit) { }` | `componentDidMount` / `useEffect(fn, [])` | `onCreate()` |\n| `dispose()` | `DisposableEffect { onDispose { } }` | `componentWillUnmount` / `useEffect(() => fn, [])` | `onDestroy()` |\n| `didUpdateWidget(old)` | `LaunchedEffect(key) { }` | `componentDidUpdate(prev)` / `useEffect(fn, [dep])` | `onViewModelUpdate(previous?)` |\n| `build(context)` | `@Composable fun` recomposition | `render(): JSX.Element` | `onRender(): void` |\n| `setState(() {...})` | `mutableStateOf` + state write | `this.setState({...})` | `this.setState({...})` |\n\n## Component and element mapping\n\n| Flutter | Jetpack Compose | React | Valdi |\n|---------|-----------------|-------|-------|\n| `StatelessWidget` | `@Composable fun` (stateless) | Function component | `class X extends Component<VM>` |\n| `StatefulWidget` + `State` | `@Composable fun` + `remember { mutableStateOf() }` | Class component + state | `class X extends StatefulComponent<VM, State>` |\n| `Container` / `SizedBox` (visual) | `Box` / `Surface` | `<div>` with styles | `<view>` |\n| `SizedBox` (invisible spacer) | `Spacer` | Layout-only `<div>` | `<layout>` (no native view, faster) |\n| `Text` | `Text(text)` | `<span>` / `<p>` | `<label value=\"...\">` |\n| `TextField` | `TextField` / `OutlinedTextField` | `<input>` | `<textfield>` (single-line) |\n| `TextFormField` | `BasicTextField` (multi) | `<textarea>` | `<textview>` (multi-line) |\n| `Image.network` | `AsyncImage` (Coil) | `<img>` | `<image src={url}>` |\n| `ListView` / `FlatList` | `LazyColumn` / `LazyRow` | `<FlatList>` | `<scroll>` + `forEach` |\n| `SingleChildScrollView` | `Column` + `verticalScroll` | `<ScrollView>` | `<scroll>` |\n| `PageView` | `HorizontalPager` | `<ViewPager>` | `<scroll pagingEnabled={true}>` |\n| `CircularProgressIndicator` | `CircularProgressIndicator` | `<ActivityIndicator>` | `<spinner>` |\n| `GestureDetector` | `Modifier.clickable { }` | `onClick` / `onPress` | `onTap` on `<view>` |\n| `Column` | `Column` | `flexDirection: 'column'` | `<view flexDirection=\"column\">` (default) |\n| `Row` | `Row` | `flexDirection: 'row'` | `<view flexDirection=\"row\">` |\n| `Stack` | `Box` with `align` | `position: absolute` | `<view>` + children with `position=\"absolute\"` |\n| `Modifier.padding(16.dp)` | `Modifier.padding(16.dp)` | `style={{padding:16}}` | `padding={16}` on any element |\n| `Navigator.push` | `navController.navigate(\"route\")` | `navigate()` / `router.push` | `navigationController.push(Page, vm, ctx)` |\n| `Navigator.pop` | `navController.popBackStack()` | `goBack()` / `router.back` | `navigationController.pop()` |\n| `showModalBottomSheet` | `ModalBottomSheet` / `Dialog` | `<Modal>` | `navigationController.present(Page, vm, ctx)` |\n| `InheritedWidget` / `Provider` | `CompositionLocalProvider` | `React.Context` + `useContext` | `createProviderComponentWithKeyName<T>()` + `withProviders()` |\n| `SharedPreferences` | `SharedPreferences` / `DataStore` | `AsyncStorage` / `localStorage` | `PersistentStore` (valdi persistence) |\n| `http.get()` / `dio` | `viewModelScope.launch { api.get() }` | `fetch()` / `axios` | `HTTPClient.get()` (valdi_http) |\n| `Lottie` | `LottieAnimation` | `<Lottie>` | `<animatedimage>` |\n| `BackdropFilter` | `BlurMaskFilter` | CSS `backdrop-filter` | `<blur>` (iOS only) |\n\n## Key import paths\n\n```typescript\nimport { Component, StatefulComponent } from 'valdi_core/src/Component';\nimport { Style } from 'valdi_core/src/Style';\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nimport { withProviders, ProvidersValuesViewModel } from 'valdi_core/src/provider/withProviders';\nimport { createReusableCallback } from 'valdi_core/src/utils/Callback';\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\nimport { PersistentStore } from 'persistence/src/PersistentStore';\nimport { Layout, View } from 'valdi_tsx/src/NativeTemplateElements';\n```\n\n## Provider pattern (replaces React Context / Flutter InheritedWidget)\n\n```typescript\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nimport { ProvidersValuesViewModel, withProviders } from 'valdi_core/src/provider/withProviders';\n\nconst ThemeProvider = createProviderComponentWithKeyName<ThemeService>('ThemeProvider');\n\n// ✅ Root provides value\nclass AppRoot extends Component {\n  private theme = new ThemeService();\n  onRender() {\n    <ThemeProvider value={this.theme}><App /></ThemeProvider>;\n  }\n}\n\n// ✅ Consumer wraps with HOC\ninterface MyViewModel extends ProvidersValuesViewModel<[ThemeService]> {}\nclass MyComp extends Component<MyViewModel> {\n  onRender() {\n    const [theme] = this.viewModel.providersValues;\n    <view backgroundColor={theme.primary} />;\n  }\n}\nconst MyCompWithProvider = withProviders(ThemeProvider)(MyComp);\n```\n\n## Further reading\n\n- [Migrating from React](../../../docs/docs/start-from-react.md)\n- [Migrating from Flutter](../../../docs/docs/migrate-from-flutter.md)\n- [Migrating from Jetpack Compose](../../../docs/docs/migrate-from-compose.md)\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/.gitignore",
    "content": "# Generated by integration tests — run `bazel build` after regenerating\noutput/\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"tests\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"output/**/*.ts\",\n        \"output/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiMigrateTest\",\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/persistence\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_http\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/README.md",
    "content": "# valdi-migrate skill tests\n\nValidates that code migrated to Valdi using the `valdi-migrate` skill is free of\nanti-patterns (React hooks, Compose APIs, inline lambdas, `map()` in render loops, etc.)\nand that the output actually compiles.\n\n## Files\n\n| File | Description |\n|------|-------------|\n| `BUILD.bazel` | Bazel build target — compiles `src/` and `output/` together |\n| `tsconfig.json` | TypeScript config |\n| `check_antipatterns.py` | Linter — exits 0 if clean, 1 if violations found |\n| `flutter_example.dart` | Source Flutter code to migrate |\n| `compose_example.kt` | Source Jetpack Compose code to migrate |\n| `react_example.tsx` | Source React code to migrate |\n| `src/expected_valdi.tsx` | Reference correct Valdi output (canonical ground truth) |\n| `output/` | Skill-generated migrations — checked in after running integration tests |\n\n## Integration tests\n\nThese tests verify the skill produces correct, compilable Valdi from each source framework.\n\n### 1. Generate migrations\n\nAsk Claude (with the `valdi-migrate` skill active) to migrate each source file:\n\n```\nMigrate flutter_example.dart to Valdi\nMigrate compose_example.kt to Valdi\nMigrate react_example.tsx to Valdi\n```\n\nSave each output to the `output/` directory:\n- `output/flutter_migrated.tsx`\n- `output/compose_migrated.tsx`\n- `output/react_migrated.tsx`\n\n### 2. Anti-pattern check\n\nVerify none of the outputs contain framework-specific patterns:\n\n```bash\ncd client/src/open_source/ai-skills/skills/valdi-migrate/tests\n\npython3 check_antipatterns.py output/flutter_migrated.tsx   # must pass\npython3 check_antipatterns.py output/compose_migrated.tsx   # must pass\npython3 check_antipatterns.py output/react_migrated.tsx     # must pass\n\n# Sanity check — source files should still fail\npython3 check_antipatterns.py react_example.tsx             # expected: fail\npython3 check_antipatterns.py compose_example.kt            # expected: fail\n```\n\n### 3. Compile check\n\nVerify all outputs (reference + migrations) build with the Valdi compiler:\n\n```bash\ncd client/src/open_source\nbazel build //ai-skills/skills/valdi-migrate/tests:tests\n```\n\nExpected: `Build completed successfully`\n\n## Updating the tests\n\n- **Source examples** (`flutter_example.dart`, `compose_example.kt`, `react_example.tsx`): add new patterns you want the skill to handle correctly.\n- **Reference output** (`src/expected_valdi.tsx`): update when Valdi APIs change (import paths, type signatures, etc.). Must always compile and pass the linter.\n- **Skill** (`../skill.md`): update when adding new source frameworks or fixing incorrect migration guidance.\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/check_antipatterns.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nValidates a Valdi TSX file for known anti-patterns.\nUsage: python3 check_antipatterns.py <file.tsx>\nReturns exit code 0 if clean, 1 if violations found.\n\"\"\"\n\nimport sys\nimport re\n\nANTI_PATTERNS = [\n    # React hooks\n    (r'\\buseState\\b',           'React hook: useState'),\n    (r'\\buseEffect\\b',          'React hook: useEffect'),\n    (r'\\buseContext\\b',         'React hook: useContext'),\n    (r'\\buseMemo\\b',            'React hook: useMemo'),\n    (r'\\buseCallback\\b',        'React hook: useCallback'),\n    (r'\\buseRef\\b',             'React hook: useRef'),\n\n    # Compose APIs\n    (r'@Composable',            'Compose: @Composable annotation'),\n    (r'\\bremember\\s*\\{',        'Compose: remember { }'),\n    (r'\\bmutableStateOf\\b',     'Compose: mutableStateOf'),\n    (r'\\bLaunchedEffect\\b',     'Compose: LaunchedEffect'),\n    (r'\\bDisposableEffect\\b',   'Compose: DisposableEffect'),\n\n    # Functional components\n    (r'const\\s+\\w+\\s*=\\s*\\([^)]*\\)\\s*=>\\s*[<(]',  'Functional component arrow fn'),\n    (r'function\\s+\\w+\\s*\\([^)]*\\)\\s*\\{[^}]*return\\s*<',  'Functional component with return JSX'),\n\n    # Wrong naming\n    (r'\\bthis\\.props\\b',        'Wrong: this.props (should be this.viewModel)'),\n    (r'\\bonMount\\b',            'Wrong: onMount (should be onCreate)'),\n    (r'\\bonUnmount\\b',          'Wrong: onUnmount (should be onDestroy)'),\n    (r'\\bmarkNeedsRender\\b',    'Wrong: markNeedsRender (use this.setState)'),\n    (r'\\bscheduleRender\\b',     'Wrong: scheduleRender (deprecated)'),\n\n    # return JSX in onRender\n    (r'onRender\\s*\\(\\s*\\)\\s*\\{[^}]*return\\s*<', 'onRender() should not return JSX'),\n\n    # Inline lambdas in JSX props (e.g. onTap={() => ...})\n    (r'on\\w+\\s*=\\s*\\{\\s*\\(\\s*\\)\\s*=>',  'Inline lambda in JSX prop (use class arrow fn)'),\n\n    # map() in JSX context\n    (r'\\.map\\s*\\([^)]*=>\\s*[^)]*<\\w',   'map() returns array (use forEach in onRender)'),\n\n    # new Style inside onRender\n    (r'onRender\\s*\\(\\s*\\)\\s*\\{(?:[^}]|\\{[^}]*\\})*new\\s+Style\\s*<', 'new Style() inside onRender()'),\n\n    # Wrong import paths (discovered by build failures)\n    # Provider is two separate files, not a directory import\n    (r\"from 'valdi_core/src/provider'\",\n     \"Wrong import: use 'valdi_core/src/provider/createProvider' and/or 'valdi_core/src/provider/withProviders'\"),\n]\n\ndef check_file(path: str) -> list[tuple[int, str, str]]:\n    violations = []\n    with open(path) as f:\n        lines = f.readlines()\n    for lineno, line in enumerate(lines, 1):\n        stripped = line.lstrip()\n        # Skip comment lines\n        if stripped.startswith('//') or stripped.startswith('*') or stripped.startswith('#'):\n            continue\n        for pattern, description in ANTI_PATTERNS:\n            if re.search(pattern, line):\n                violations.append((lineno, description, line.rstrip()))\n    return violations\n\ndef main():\n    if len(sys.argv) < 2:\n        print(f'Usage: {sys.argv[0]} <file.tsx>', file=sys.stderr)\n        sys.exit(2)\n\n    path = sys.argv[1]\n    violations = check_file(path)\n\n    if not violations:\n        print(f'✅  {path}: no anti-patterns found')\n        sys.exit(0)\n    else:\n        print(f'❌  {path}: {len(violations)} violation(s) found')\n        for lineno, desc, text in violations:\n            print(f'  Line {lineno}: [{desc}]')\n            print(f'    {text}')\n        sys.exit(1)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/compose_example.kt",
    "content": "// Jetpack Compose example — @Composable functions, remember, LaunchedEffect,\n// LazyColumn, navigation, CompositionLocal.\n// Goal: migrate this to Valdi.\n\nimport androidx.compose.foundation.layout.*\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.*\nimport androidx.compose.runtime.*\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport androidx.navigation.NavController\n\n// --- CompositionLocal theme ---\nval LocalAppTheme = compositionLocalOf { AppTheme() }\ndata class AppTheme(val primary: String = \"#FFFC00\")\n\n// --- Stateless greeting ---\n@Composable\nfun Greeting(name: String) {\n    Text(\"Hello, $name\")\n}\n\n// --- Stateful counter ---\n@Composable\nfun Counter(label: String) {\n    var count by remember { mutableStateOf(0) }\n    Button(onClick = { count++ }) {\n        Text(\"$label: $count\")\n    }\n}\n\n// --- Data loading with LaunchedEffect ---\n@Composable\nfun UserProfile(userId: String) {\n    var profile by remember { mutableStateOf<Profile?>(null) }\n\n    LaunchedEffect(userId) {\n        profile = fetchProfile(userId)   // suspend fun\n    }\n\n    if (profile == null) {\n        CircularProgressIndicator()\n    } else {\n        Text(profile!!.name)\n    }\n}\n\n// --- LazyColumn list ---\n@Composable\nfun UserList(users: List<User>) {\n    LazyColumn {\n        items(users, key = { it.id }) { user ->\n            UserRow(user = user)\n        }\n    }\n}\n\n// --- Layout with Column / Row / Modifier ---\n@Composable\nfun ProfileCard(user: User) {\n    Column(\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(16.dp)\n    ) {\n        Row(modifier = Modifier.fillMaxWidth()) {\n            Text(user.name, style = MaterialTheme.typography.headlineSmall)\n            Spacer(Modifier.weight(1f))\n            Text(user.handle)\n        }\n        Spacer(modifier = Modifier.height(8.dp))\n        Text(user.bio)\n    }\n}\n\n// --- Navigation ---\n@Composable\nfun HomeScreen(navController: NavController) {\n    Button(onClick = { navController.navigate(\"detail/42\") }) {\n        Text(\"Go to Detail\")\n    }\n}\n\n// --- CompositionLocal consumer ---\n@Composable\nfun ThemedBadge(text: String) {\n    val theme = LocalAppTheme.current\n    Box(\n        modifier = Modifier.background(Color(android.graphics.Color.parseColor(theme.primary)))\n    ) {\n        Text(text)\n    }\n}\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/flutter_example.dart",
    "content": "// Flutter example — mix of StatelessWidget, StatefulWidget, ListView.builder,\n// navigation, SharedPreferences, and a Provider consumer.\n// Goal: migrate this to Valdi.\n\nimport 'package:flutter/material.dart';\nimport 'package:provider/provider.dart';\nimport 'package:shared_preferences/shared_preferences.dart';\n\n// --- Theme service (ChangeNotifier) ---\nclass ThemeService extends ChangeNotifier {\n  Color primary = Colors.yellow;\n}\n\n// --- Stateless greeting ---\nclass Greeting extends StatelessWidget {\n  final String name;\n  const Greeting({required this.name});\n\n  @override\n  Widget build(BuildContext context) {\n    return Text('Hello, $name');\n  }\n}\n\n// --- Stateful counter ---\nclass Counter extends StatefulWidget {\n  final String label;\n  const Counter({required this.label});\n  @override\n  State<Counter> createState() => _CounterState();\n}\n\nclass _CounterState extends State<Counter> {\n  int _count = 0;\n\n  void _increment() {\n    setState(() { _count++; });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return GestureDetector(\n      onTap: _increment,\n      child: Text('${widget.label}: $_count'),\n    );\n  }\n}\n\n// --- User list with async fetch and cancellation ---\nclass UserList extends StatefulWidget {\n  @override\n  State<UserList> createState() => _UserListState();\n}\n\nclass _UserListState extends State<UserList> {\n  List<String> _users = [];\n\n  @override\n  void initState() {\n    super.initState();\n    _loadUsers();\n  }\n\n  Future<void> _loadUsers() async {\n    // simulated network fetch\n    await Future.delayed(Duration(milliseconds: 500));\n    setState(() { _users = ['Alice', 'Bob', 'Carol']; });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return ListView.builder(\n      itemCount: _users.length,\n      itemBuilder: (context, index) {\n        return ListTile(title: Text(_users[index]));\n      },\n    );\n  }\n}\n\n// --- Settings screen using SharedPreferences ---\nclass SettingsScreen extends StatefulWidget {\n  @override\n  State<SettingsScreen> createState() => _SettingsScreenState();\n}\n\nclass _SettingsScreenState extends State<SettingsScreen> {\n  bool _notifications = false;\n\n  @override\n  void initState() {\n    super.initState();\n    _load();\n  }\n\n  Future<void> _load() async {\n    final prefs = await SharedPreferences.getInstance();\n    setState(() { _notifications = prefs.getBool('notifications') ?? false; });\n  }\n\n  Future<void> _toggle() async {\n    final prefs = await SharedPreferences.getInstance();\n    final next = !_notifications;\n    await prefs.setBool('notifications', next);\n    setState(() { _notifications = next; });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Column(\n      children: [\n        Text('Notifications: $_notifications'),\n        ElevatedButton(onPressed: _toggle, child: Text('Toggle')),\n      ],\n    );\n  }\n}\n\n// --- Provider consumer ---\nclass ThemedButton extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    final theme = context.watch<ThemeService>();\n    return Container(\n      color: theme.primary,\n      child: Text('Themed'),\n    );\n  }\n}\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/react_example.tsx",
    "content": "// React example — hooks, Context, FlatList, fetch, styled-components.\n// Goal: migrate this to Valdi.\n\nimport React, { useState, useEffect, useContext, createContext } from 'react';\nimport { View, Text, FlatList, TouchableOpacity, StyleSheet } from 'react-native';\nimport styled from 'styled-components/native';\n\n// --- Context / theme ---\nconst ThemeContext = createContext({ primary: '#FFFC00' });\n\n// --- Stateless greeting ---\nconst Greeting: React.FC<{ name: string }> = ({ name }) => {\n  return <Text>Hello, {name}</Text>;\n};\n\n// --- Stateful counter ---\nconst Counter: React.FC<{ label: string }> = ({ label }) => {\n  const [count, setCount] = useState(0);\n  return (\n    <TouchableOpacity onPress={() => setCount(c => c + 1)}>\n      <Text>{label}: {count}</Text>\n    </TouchableOpacity>\n  );\n};\n\n// --- Data fetching with useEffect ---\ninterface User { id: string; name: string; }\n\nconst UserList: React.FC = () => {\n  const [users, setUsers] = useState<User[]>([]);\n  const [loading, setLoading] = useState(true);\n\n  useEffect(() => {\n    let cancelled = false;\n    fetch('https://api.example.com/users')\n      .then(r => r.json())\n      .then(data => {\n        if (!cancelled) {\n          setUsers(data);\n          setLoading(false);\n        }\n      });\n    return () => { cancelled = true; };\n  }, []);\n\n  if (loading) return <Text>Loading...</Text>;\n\n  return (\n    <FlatList\n      data={users}\n      keyExtractor={u => u.id}\n      renderItem={({ item }) => <Text>{item.name}</Text>}\n    />\n  );\n};\n\n// --- styled-components ---\nconst Card = styled.View`\n  background-color: #ffffff;\n  border-radius: 12px;\n  padding: 16px;\n  shadow-color: #000;\n  shadow-opacity: 0.15;\n  shadow-radius: 8px;\n`;\n\nconst CardTitle = styled.Text`\n  font-size: 18px;\n  font-weight: bold;\n`;\n\nconst ProfileCard: React.FC<{ name: string; bio: string }> = ({ name, bio }) => (\n  <Card>\n    <CardTitle>{name}</CardTitle>\n    <Text>{bio}</Text>\n  </Card>\n);\n\n// --- Context consumer ---\nconst ThemedBadge: React.FC<{ text: string }> = ({ text }) => {\n  const theme = useContext(ThemeContext);\n  return (\n    <View style={{ backgroundColor: theme.primary }}>\n      <Text>{text}</Text>\n    </View>\n  );\n};\n\n// --- Re-render bug: inline lambda + map() ---\nconst BadList: React.FC<{ items: { id: string; label: string }[] }> = ({ items }) => (\n  <View>\n    {items.map(item => (\n      <TouchableOpacity key={item.id} onPress={() => console.log(item.id)}>\n        <Text>{item.label}</Text>\n      </TouchableOpacity>\n    ))}\n  </View>\n);\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/src/expected_valdi.tsx",
    "content": "// Expected Valdi migrations — used to validate skill output correctness.\n// Each section corresponds to a source snippet in flutter/compose/react examples.\n\nimport { Component, StatefulComponent } from 'valdi_core/src/Component';\nimport { Style } from 'valdi_core/src/Style';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nimport {\n  ProvidersValuesViewModel,\n  withProviders,\n} from 'valdi_core/src/provider/withProviders';\nimport { CancelablePromise } from 'valdi_core/src/CancelablePromise';\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\nimport { HTTPResponse } from 'valdi_http/src/HTTPTypes';\nimport { PersistentStore } from 'persistence/src/PersistentStore';\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\n// Stub for the async data-fetching function referenced in examples\ndeclare function fetchProfile(id: string): Promise<{ name: string }>;\n\n// ============================================================\n// Theme service + Provider\n// ============================================================\n\nclass AppThemeService {\n  primary = '#FFFC00';\n}\nconst ThemeProvider = createProviderComponentWithKeyName<AppThemeService>('ThemeProvider');\n\n// ============================================================\n// Stateless greeting (Flutter Greeting / Compose Greeting / React Greeting)\n// ============================================================\n\ninterface GreetingViewModel {\n  name: string;\n}\n\nclass Greeting extends Component<GreetingViewModel> {\n  onRender(): void {\n    <label value={`Hello, ${this.viewModel.name}`} />;\n  }\n}\n\n// ============================================================\n// Stateful counter (Flutter Counter / Compose Counter / React Counter)\n// ============================================================\n\ninterface CounterViewModel {\n  label: string;\n}\n\ninterface CounterState {\n  count: number;\n}\n\nclass Counter extends StatefulComponent<CounterViewModel, CounterState> {\n  state = { count: 0 };\n\n  // Class arrow function — never inline lambda in JSX props\n  private increment = () => {\n    this.setState({ count: this.state.count + 1 });\n  };\n\n  onRender(): void {\n    <view onTap={this.increment}>\n      <label value={`${this.viewModel.label}: ${this.state.count}`} />;\n    </view>;\n  }\n}\n\n// ============================================================\n// Data loading (Flutter _UserListState / Compose UserProfile / React UserList)\n// ============================================================\n\ninterface UserProfileViewModel {\n  userId: string;\n}\ninterface UserProfileState {\n  profile: { name: string } | null;\n}\n\nclass UserProfile extends StatefulComponent<UserProfileViewModel, UserProfileState> {\n  state: UserProfileState = { profile: null };\n\n  onCreate(): void {\n    this.loadProfile(this.viewModel.userId);\n  }\n\n  onViewModelUpdate(previous?: UserProfileViewModel): void {\n    if (this.viewModel.userId !== previous?.userId) {\n      this.loadProfile(this.viewModel.userId);\n    }\n  }\n\n  private async loadProfile(id: string) {\n    const profile = await fetchProfile(id);\n    this.setState({ profile });\n  }\n\n  onRender(): void {\n    if (!this.state.profile) {\n      <spinner />;\n      return;\n    }\n    <label value={this.state.profile.name} />;\n  }\n}\n\n// ============================================================\n// List (Flutter ListView.builder / Compose LazyColumn / React FlatList)\n// ============================================================\n\ninterface User { id: string; name: string; }\n\ninterface UserListViewModel {\n  users: User[];\n}\n\nclass UserList extends Component<UserListViewModel> {\n  onRender(): void {\n    // forEach, not map() — JSX is emitted as side-effects\n    <scroll>\n      {this.viewModel.users.forEach(user => {\n        <label key={user.id} value={user.name} />;\n      })}\n    </scroll>;\n  }\n}\n\n// ============================================================\n// Layout (Flutter ProfileCard / Compose ProfileCard)\n// ============================================================\n\ninterface ProfileCardViewModel {\n  name: string;\n  handle: string;\n  bio: string;\n}\n\nclass ProfileCard extends Component<ProfileCardViewModel> {\n  onRender(): void {\n    <view flexDirection=\"column\" width=\"100%\" padding={16}>\n      <view flexDirection=\"row\" width=\"100%\">\n        <label value={this.viewModel.name} font={systemFont(20)} />;\n        <layout flexGrow={1} />;\n        <label value={this.viewModel.handle} />;\n      </view>;\n      <layout height={8} />;\n      <label value={this.viewModel.bio} />;\n    </view>;\n  }\n}\n\n// ============================================================\n// Styled card (React styled-components Card)\n// Style objects defined after the class, grouped in a const styles object\n// ============================================================\n\ninterface CardViewModel {\n  name: string;\n  bio: string;\n}\n\nclass ProfileCardStyled extends Component<CardViewModel> {\n  onRender(): void {\n    <view style={styles.card}>\n      <label value={this.viewModel.name} font={systemFont(18)} />;\n      <label value={this.viewModel.bio} />;\n    </view>;\n  }\n}\n\nconst styles = {\n  card: new Style<View>({\n    backgroundColor: '#ffffff',\n    borderRadius: 12,\n    boxShadow: '0 2 8 rgba(0,0,0,0.15)',\n    padding: 16,\n  }),\n};\n\n// ============================================================\n// Provider consumer (Flutter ThemedButton / Compose ThemedBadge / React ThemedBadge)\n// ============================================================\n\ninterface ThemedBadgeViewModel extends ProvidersValuesViewModel<[AppThemeService]> {\n  text: string;\n}\n\nclass ThemedBadge extends Component<ThemedBadgeViewModel> {\n  onRender(): void {\n    const [theme] = this.viewModel.providersValues;\n    <view backgroundColor={theme.primary}>\n      <label value={this.viewModel.text} />;\n    </view>;\n  }\n}\nconst ThemedBadgeWithProvider = withProviders(ThemeProvider)(ThemedBadge);\n\n// ============================================================\n// Persistent storage (Flutter SharedPreferences / React AsyncStorage)\n// ============================================================\n\nconst settingsStore = new PersistentStore('settings');\n\ninterface SettingsState {\n  notifications: boolean;\n}\n\nclass SettingsScreen extends StatefulComponent<{}, SettingsState> {\n  state = { notifications: false };\n\n  async onCreate() {\n    const raw = await settingsStore.fetchString('notifications');\n    this.setState({ notifications: raw === 'true' });\n  }\n\n  private toggle = async () => {\n    const next = !this.state.notifications;\n    await settingsStore.storeString('notifications', String(next));\n    this.setState({ notifications: next });\n  };\n\n  onRender(): void {\n    <view flexDirection=\"column\">\n      <label value={`Notifications: ${this.state.notifications}`} />;\n      <view onTap={this.toggle}>\n        <label value=\"Toggle\" />;\n      </view>;\n    </view>;\n  }\n}\n\n// ============================================================\n// HTTP fetch (React UserList with fetch / Flutter _loadUsers)\n// ============================================================\n\ninterface FetchState {\n  users: User[];\n}\n\nclass UserListFetch extends StatefulComponent<{}, FetchState> {\n  state: FetchState = { users: [] };\n\n  private client = new HTTPClient('https://api.example.com');\n  private request?: CancelablePromise<HTTPResponse>;\n\n  onCreate(): void {\n    this.request = this.client.get('/users');\n    this.request.then(response => {\n      const users = JSON.parse(new TextDecoder().decode(response.body));\n      this.setState({ users });\n    });\n  }\n\n  onDestroy(): void {\n    this.request?.cancel?.();\n  }\n\n  onRender(): void {\n    <scroll>\n      {this.state.users.forEach(u => {\n        <label key={u.id} value={u.name} />;\n      })}\n    </scroll>;\n  }\n}\n"
  },
  {
    "path": "ai-skills/skills/valdi-migrate/tests/tsconfig.json",
    "content": "{\n    \"extends\": \"../../../../src/valdi_modules/src/valdi/_configs/base.tsconfig.json\"\n}\n"
  },
  {
    "path": "ai-skills/skills/valdi-overview/skill.md",
    "content": "# Valdi Open Source - Cursor Rules\n\n## ⚠️ Open Source Project\n\nThis is an open source project. Never commit secrets, API keys, or proprietary information.\n\n## 🚨 CRITICAL: This is NOT React!\n\nValdi uses TSX/JSX syntax but is **fundamentally different from React**. \n\n**Common AI mistakes:**\n- ❌ Suggesting `useState`, `useEffect`, `useContext` (don't exist!)\n- ❌ Functional components (don't exist!)\n- ❌ `this.props` (should be `this.viewModel`)\n- ❌ `markNeedsRender()`, `onMount()`, `onUpdate()` (wrong names/don't exist!)\n\n**Correct Valdi:**\n- ✅ `class MyComponent extends StatefulComponent`\n- ✅ `state = {}` + `this.setState()`\n- ✅ `this.viewModel` for props\n- ✅ `onCreate()`, `onViewModelUpdate()`, `onDestroy()` lifecycle\n\n## 📦 AI Skills\n\nInstall Valdi skills for your AI tool to get context-specific guidance:\n\n```bash\nnpm install -g @snap/valdi\nvaldi skills install\n```\n\nSkills available (`valdi skills list`):\n\n| Skill | Coverage |\n|-------|----------|\n| `valdi-tsx` | TSX component patterns, lifecycle, styling |\n| `valdi-setup` | Module BUILD.bazel, tsconfig, hot reload |\n| `valdi-async` | CancelablePromise, HTTPClient, lifecycle safety |\n| `valdi-perf` | ViewModel stability, createReusableCallback, Style interning |\n| `valdi-component-tests` | elementKeyFind, tapNodeWithKey, discriminated unions |\n| `valdi-ios` | Swift/ObjC platform bridging |\n| `valdi-android` | Kotlin platform bridging |\n| `valdi-bazel` | Build rules, platform builds |\n| `valdi-compiler` | Compiler pipeline internals |\n| `valdi-cpp-runtime` | C++ runtime and renderer |\n| `valdi-polyglot-module` | Cross-platform polyglot APIs, web polyglot entry pattern |\n| `valdi-custom-view` | Native view integration, viewFactory |\n\n## Quick Commands\n\n```bash\nbazel build //...          # Build everything\nbazel test //...           # Run all tests\nvaldi install ios          # Build & install iOS app\nvaldi hotreload            # Start hot reload\n```\n\n## More Information\n\n- **Comprehensive guide**: `/AGENTS.md`\n- **AI tooling**: `/docs/docs/ai-tooling.md`\n- **Support**: `/SUPPORT.md`\n- **Discord**: https://discord.gg/uJyNEeYX2U\n"
  },
  {
    "path": "ai-skills/skills/valdi-perf/skill.md",
    "content": "# Valdi Performance Patterns\n\nValdi re-renders a child component whenever its viewModel reference changes. Most\nunnecessary re-renders come from creating new object/array/function references in\n`onRender()`. Fix the reference — fix the re-render.\n\n## ViewModel Identity Stability\n\n**The #1 performance problem in Valdi apps.** Every object or array literal created\ninside `onRender()` is a new reference. Child components will always re-render, even\nwhen the actual values haven't changed.\n\n```typescript\n// ❌ New object every render — child always re-renders\nonRender(): void {\n  <UserRow vm={{ name: this.viewModel.user.name, age: this.viewModel.user.age }} />;\n}\n\n// ❌ New array every render\nonRender(): void {\n  <TabBar tabs={['Home', 'Profile', 'Settings']} />;\n}\n\n// ✅ Stable class property for constants\nprivate tabs = ['Home', 'Profile', 'Settings'];\nonRender(): void {\n  <TabBar tabs={this.tabs} />;\n}\n\n// ✅ Pre-compute derived viewModels in onViewModelUpdate\nprivate userRowVM: UserRowViewModel = { name: '', age: 0 };\n\nonViewModelUpdate(): void {\n  this.userRowVM = { name: this.viewModel.user.name, age: this.viewModel.user.age };\n}\n\nonRender(): void {\n  <UserRow vm={this.userRowVM} />;\n}\n```\n\nOnly update the pre-computed VM when the relevant input actually changes:\n\n```typescript\nonViewModelUpdate(previous?: UserProfileViewModel): void {\n  if (this.viewModel.userId !== previous?.userId) {\n    this.userRowVM = buildUserRowVM(this.viewModel.user);\n  }\n}\n```\n\n## Navigation Callbacks\n\nNavigation callbacks passed into child viewModels have the same identity problem:\n`() => this.navigationController.push(...)` creates a new function each render.\nUse a class arrow function — it is defined once and has a stable reference:\n\n```typescript\n// ❌ New function every render\nonRender(): void {\n  <UserCard onTap={() => this.navigationController.push(DetailPage, { id: this.viewModel.userId })} />;\n}\n\n// ✅ Class arrow function — stable reference, viewModel.userId read at tap time\nprivate goToDetail = (): void => {\n  this.navigationController.push(DetailPage, { id: this.viewModel.userId });\n};\n\nonRender(): void {\n  <UserCard onTap={this.goToDetail} />;\n}\n```\n\n## `<layout>` vs `<view>`\n\n`<view>` allocates a native platform view. `<layout>` is virtual — it participates in\nflexbox layout but creates no native view, which is faster and uses less memory.\n\n```typescript\n// ❌ Native view wasted on an invisible spacer\n<view height={16} />\n\n// ✅ No native view allocated\n<layout height={16} />\n\n// ❌ Wrapper with no visual properties or tap handler\n<view flexDirection=\"column\">\n  <label value=\"A\" />;\n  <label value=\"B\" />;\n</view>;\n\n// ✅ Virtual layout node\n<layout flexDirection=\"column\">\n  <label value=\"A\" />;\n  <label value=\"B\" />;\n</layout>;\n```\n\n**Use `<view>` when you need:** `onTap`, `backgroundColor`, `borderRadius`, `style`,\n`overflow`, `opacity`, or any visual/interactive property.\n**Use `<layout>` for everything else:** spacers, invisible wrappers, structural containers.\n\n## Keys in Lists\n\nKeys determine element identity across re-renders. Without a key (or with an index\nkey), reordering or inserting items causes the wrong component instances to receive\nthe wrong viewModels.\n\n```typescript\n// ❌ No key — identity lost on reorder\n{this.viewModel.items.forEach(item => {\n  <ItemRow value={item.name} />;\n})}\n\n// ❌ Index key — breaks on insert/remove\n{this.viewModel.items.forEach((item, index) => {\n  <ItemRow key={String(index)} value={item.name} />;\n})}\n\n// ✅ Stable data ID\n{this.viewModel.items.forEach(item => {\n  <ItemRow key={item.id} value={item.name} />;\n})}\n```\n\n## Render Props as Class Arrow Functions\n\nWhen a parent needs to pass a render function to a child (e.g. a list row renderer),\ndefine it as a class arrow function property so it has a stable reference:\n\n```typescript\n// ❌ New function every render — child's renderItem prop always changes\nonRender(): void {\n  <List renderItem={(item) => { <Row data={item} />; }} />;\n}\n\n// ✅ Stable class arrow function\nprivate renderItem = (item: Item): void => {\n  <Row data={item} />;\n};\n\nonRender(): void {\n  <List renderItem={this.renderItem} />;\n}\n```\n\nFor loop closures that must capture a loop variable, use `createReusableCallback`\ninline in `onRender()`. Valdi's diffing engine recognises `Callback` objects and\nupdates the internal function reference without treating it as a prop change, so the\nchild does not re-render:\n\n```typescript\nimport { createReusableCallback } from 'valdi_core/src/utils/Callback';\n\n// ❌ New plain function every render — child always re-renders\nonRender(): void {\n  {this.viewModel.sections.forEach((section, i) => {\n    <Section onTap={() => this.handleTap(i)} />;\n  })}\n}\n\n// ✅ Inline Callback — identity-merged by Valdi's diffing engine\nonRender(): void {\n  {this.viewModel.sections.forEach((section, i) => {\n    <Section onTap={createReusableCallback(() => this.handleTap(i))} />;\n  })}\n}\n```\n\n## Style Objects at Module Level\n\n`new Style<T>({...})` interns style objects — the same property values always produce\nthe same cached object. This interning only works at module initialization time.\nInside `onRender()` the cache is bypassed and a new allocation happens every render.\n\n```typescript\n// ❌ Defeats interning — new allocation every render\nonRender(): void {\n  const s = new Style<View>({ backgroundColor: '#fff', borderRadius: 8 });\n  <view style={s} />;\n}\n\n// ✅ Interned at module level\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst styles = {\n  card: new Style<View>({ backgroundColor: '#fff', borderRadius: 8 }),\n};\n\nclass MyCard extends Component<MyViewModel> {\n  onRender(): void {\n    <view style={styles.card} />;\n  }\n}\n```\n\nGroup styles in a `const styles = {}` object after the class definition.\n"
  },
  {
    "path": "ai-skills/skills/valdi-perf/tests/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"tests\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiPerfRef\",\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "ai-skills/skills/valdi-perf/tests/README.md",
    "content": "# valdi-perf skill tests\n\nCompile check for the performance patterns taught in `skill.md`.\n\n## What's tested\n\n`src/reference.tsx` exercises:\n- Pre-computed viewModels in `onViewModelUpdate` (stable child references)\n- `createReusableCallback` for memoized callbacks by argument\n- `<layout>` vs `<view>` for invisible containers and spacers\n- Stable class arrow functions for render props\n- Module-level `Style` objects (not created inside `onRender`)\n- `key={item.id}` with stable data IDs in lists (not array indices)\n\n## Compile check\n\n```bash\ncd client/src/open_source\nbazel build //ai-skills/skills/valdi-perf/tests:tests\n```\n\nExpected: `Build completed successfully`\n\n## Updating\n\nWhen Valdi APIs change (import paths, type signatures), update `src/reference.tsx` to match and keep it compiling. Also update `../skill.md` with any corrected patterns.\n"
  },
  {
    "path": "ai-skills/skills/valdi-perf/tests/src/reference.tsx",
    "content": "// valdi-perf skill reference — compile check for performance patterns.\n// This file must compile cleanly against the Valdi TypeScript compiler.\n// Run: bzl build //ai-skills/skills/valdi-perf/tests:tests\n\nimport { Component, StatefulComponent } from 'valdi_core/src/Component';\nimport { Style } from 'valdi_core/src/Style';\nimport { createReusableCallback } from 'valdi_core/src/utils/Callback';\nimport { Layout, View } from 'valdi_tsx/src/NativeTemplateElements';\n\n// ─── Module-level styles (defeats interning if created inside onRender) ───────\n\nconst styles = {\n  card: new Style<View>({ backgroundColor: '#fff', borderRadius: 8, padding: 12 }),\n  spacer: new Style<Layout>({ height: 16 }),\n  row: new Style<View>({ flexDirection: 'row', alignItems: 'center' }),\n};\n\n// ─── Stable class property for constant arrays ───────────────────────────────\n\ninterface TabBarViewModel {\n  tabs: string[];\n}\n\nclass TabBar extends Component<TabBarViewModel> {\n  onRender(): void {\n    <view style={styles.row}>\n      {this.viewModel.tabs.forEach(tab => {\n        <label key={tab} value={tab} />;\n      })}\n    </view>;\n  }\n}\n\n// ─── Pre-computed viewModel in onViewModelUpdate ─────────────────────────────\n\ninterface UserRowViewModel {\n  name: string;\n  subtitle: string;\n}\n\nclass UserRow extends Component<UserRowViewModel> {\n  onRender(): void {\n    <view style={styles.card}>\n      <label value={this.viewModel.name} />;\n      <label value={this.viewModel.subtitle} />;\n    </view>;\n  }\n}\n\ninterface UserListViewModel {\n  user: { id: string; name: string; bio: string };\n}\n\ninterface UserListState {\n  selectedIndex: number;\n}\n\nclass UserList extends StatefulComponent<UserListViewModel, UserListState> {\n  state: UserListState = { selectedIndex: 0 };\n\n  // Pre-computed to avoid new object on every render\n  private userRowVM: UserRowViewModel = { name: '', subtitle: '' };\n\n  onViewModelUpdate(previous?: UserListViewModel): void {\n    if (this.viewModel.user.id !== previous?.user.id) {\n      this.userRowVM = {\n        name: this.viewModel.user.name,\n        subtitle: this.viewModel.user.bio,\n      };\n    }\n  }\n\n  onRender(): void {\n    // ✅ Stable reference — UserRow only re-renders when user.id changes\n    <UserRow {...this.userRowVM} />;\n  }\n}\n\n// ─── createReusableCallback: stable function for same arguments ───────────────\n\ninterface SectionViewModel {\n  id: string;\n  title: string;\n}\n\ninterface SectionListViewModel {\n  sections: SectionViewModel[];\n}\n\ninterface SectionListState {\n  selectedId: string | null;\n}\n\nclass SectionList extends StatefulComponent<SectionListViewModel, SectionListState> {\n  state: SectionListState = { selectedId: null };\n\n  private handleSectionTap(id: string): void {\n    this.setState({ selectedId: id });\n  }\n\n  onRender(): void {\n    <view>\n      {this.viewModel.sections.forEach(section => {\n        // ✅ Inline Callback — Valdi merges identity, child doesn't re-render\n        <view key={section.id} onTap={createReusableCallback(() => this.handleSectionTap(section.id))}>\n          <label value={section.title} />;\n        </view>;\n      })}\n    </view>;\n  }\n}\n\n// ─── Stable render props as class arrow functions ────────────────────────────\n\ninterface Item {\n  id: string;\n  label: string;\n}\n\ninterface FlatListViewModel {\n  items: Item[];\n  renderItem: (item: Item) => void;\n}\n\nclass FlatList extends Component<FlatListViewModel> {\n  onRender(): void {\n    <scroll>\n      {this.viewModel.items.forEach(item => {\n        this.viewModel.renderItem(item);\n      })}\n    </scroll>;\n  }\n}\n\ninterface FeedViewModel {\n  items: Item[];\n}\n\nclass Feed extends Component<FeedViewModel> {\n  // ✅ Stable reference — defined as class property, not inline in onRender\n  private renderItem = (item: Item): void => {\n    <view key={item.id}>\n      <label value={item.label} />;\n    </view>;\n  };\n\n  onRender(): void {\n    <FlatList items={this.viewModel.items} renderItem={this.renderItem} />;\n  }\n}\n\n// ─── <layout> vs <view>: no native view for invisible containers ──────────────\n\ninterface CardViewModel {\n  title: string;\n  subtitle: string;\n}\n\nclass Card extends Component<CardViewModel> {\n  onRender(): void {\n    <view style={styles.card}>\n      <label value={this.viewModel.title} />;\n      {/* ✅ layout: no native view allocated for spacer */}\n      <layout style={styles.spacer} />;\n      {/* ✅ layout: invisible structural wrapper */}\n      <layout flexDirection=\"row\" alignItems=\"center\">\n        <label value={this.viewModel.subtitle} />;\n      </layout>;\n    </view>;\n  }\n}\n\n// ─── Keys in lists: stable data ID, not index ────────────────────────────────\n\ninterface ListItem {\n  id: string;\n  text: string;\n}\n\ninterface StableListViewModel {\n  items: ListItem[];\n}\n\nclass StableList extends Component<StableListViewModel> {\n  onRender(): void {\n    <scroll>\n      {this.viewModel.items.forEach(item => {\n        // ✅ Stable key from data ID — reorder/insert/remove works correctly\n        <view key={item.id}>\n          <label value={item.text} />;\n        </view>;\n      })}\n    </scroll>;\n  }\n}\n\nvoid TabBar;\nvoid UserList;\nvoid SectionList;\nvoid Feed;\nvoid Card;\nvoid StableList;\n"
  },
  {
    "path": "ai-skills/skills/valdi-perf/tests/tsconfig.json",
    "content": "{\"extends\": \"../../../../src/valdi_modules/src/valdi/_configs/base.tsconfig.json\"}\n"
  },
  {
    "path": "ai-skills/skills/valdi-polyglot-module/skill.md",
    "content": "# Polyglot Module Rules\n\n**Applies to**: `**/BUILD.bazel` and source files in modules with platform-specific implementations (`android/`, `ios/`, `macos/`, `web/` directories).\n\n## Module Structure\n\nA polyglot module contains platform-native implementations alongside Valdi TSX source:\n\n```\nmy_module/\n  src/           # Valdi TSX components (compiled by Valdi compiler)\n  android/       # Kotlin/Java native implementation\n  ios/           # Objective-C native implementation\n  macos/         # Objective-C native implementation (macOS desktop)\n  web/           # TypeScript web implementation (compiled by ts_project, NOT Valdi compiler)\n  strings/       # Localization\n  module.yaml\n  tsconfig.json\n  BUILD.bazel\n```\n\n## BUILD.bazel Pattern\n\n```python\nts_project(\n    name = \"my_module_web\",\n    srcs = glob([\"web/**/*.ts\", \"web/**/*.d.ts\"]),\n    tsconfig = \"web/tsconfig.json\",\n    visibility = [\"//visibility:public\"],\n)\n\nvaldi_module(\n    name = \"my_module\",\n    srcs = glob([\"src/**/*.ts\", \"src/**/*.tsx\"]) + [\"tsconfig.json\"],\n    android_deps = [\":android_impl\"],\n    ios_deps = [\":ios_impl\"],\n    macos_deps = [\":macos_impl\"],\n    web_deps = [\":my_module_web\"],\n    deps = [...],\n)\n```\n\n- `web_deps`: makes `web/` outputs available to the web bundle. Any file in `web_deps` that exports `webPolyglotViews` is automatically registered with the `WebViewClassRegistry` at bundle time — no extra configuration needed.\n- After changing `module.yaml` deps, run: `./scripts/regenerate_valdi_modules_build_bazel_files.sh`\n\n## Web Polyglot Entry Pattern\n\nWeb entry files export view factories that are auto-registered with the `WebViewClassRegistry` at bundle time. Export a `webPolyglotViews` record mapping class names to factory functions:\n\n```typescript\nexport const webPolyglotViews: Record<string, (container: HTMLElement) => void> = {\n  MyCustomViewClass: createMyViewFactory(),\n};\n```\n\nEach key must match the `webClass` attribute used in `<custom-view webClass=\"MyCustomViewClass\">`.\n\nA factory receives an `HTMLElement` container and populates it with DOM content:\n\n```typescript\nfunction createMyViewFactory(): (container: HTMLElement) => void {\n  return (container: HTMLElement) => {\n    const element = document.createElement('div');\n    container.appendChild(element);\n  };\n}\n```\n\n### Key constraints for `web/` files\n- Compiled by `tsc` via `ts_project`, **not** the Valdi compiler\n- Do **NOT** use Valdi imports (`valdi_core/`, `valdi_tsx/`) — web files run in the browser, not the Valdi runtime\n- Do **NOT** manually call `globalThis.moduleLoader.resolveRequire()` — build system handles registration\n- The `tsconfig.json` in `web/` should target `DOM` + `ES2020` with `module: \"commonjs\"`\n\n## Canonical Example\n\nSee `valdi_polyglot` module for a complete working example with all four platforms:\n- `src/composer_modules/src/composer/valdi_polyglot/` (in the Snap monorepo)\n- Or the equivalent path in your project\n\n## Common Mistakes\n\n- Putting `web/` files in `srcs` — they must go through `ts_project` + `web_deps`, not the Valdi compiler\n- Missing platform `_deps` — each platform impl must be wired via `android_deps`, `ios_deps`, `macos_deps`\n- Using Valdi imports in `web/` — they don't exist in the browser bundle\n"
  },
  {
    "path": "ai-skills/skills/valdi-setup/skill.md",
    "content": "# Valdi Module Setup\n\n## BUILD.bazel — valdi_module()\n\n```python\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"my_module\",              # Must match the directory name exactly\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",             # tsconfig must be listed in srcs\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCMyModule\", # SCC prefix + PascalCase module name\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n        # Add as needed — see dependency table below\n    ],\n)\n```\n\n**Common mistakes that cause build failures:**\n\n- `name` must equal the Bazel package directory name. The Valdi compiler derives\n  module identity from this — mismatches cause a build error.\n- `tsconfig.json` must be in `srcs`. It won't be picked up automatically even if\n  it's in the directory.\n- Missing a dep (e.g. using `HTTPClient` without `valdi_http`) produces a TypeScript\n  path resolution error, not a missing import error — can be confusing.\n\n## tsconfig.json\n\n```json\n{\n    \"extends\": \"../../../../src/valdi_modules/src/valdi/_configs/base.tsconfig.json\"\n}\n```\n\nAdjust the `../../../../` prefix to match how many directories deep your module is\nfrom the repo root. The base config sets up `paths` aliases so `'valdi_core/src/...'`\nimports resolve correctly.\n\n## Dependency Table\n\n| You're using | Add this dep |\n|---|---|\n| `Component`, `StatefulComponent`, `Style`, providers, `CancelablePromise` | `//src/valdi_modules/src/valdi/valdi_core` |\n| JSX elements (`<view>`, `<label>`, etc.), `NativeTemplateElements` | `//src/valdi_modules/src/valdi/valdi_tsx` |\n| `HTTPClient`, `HTTPResponse` | `//src/valdi_modules/src/valdi/valdi_http` |\n| `PersistentStore` | `//src/valdi_modules/src/valdi/persistence` |\n| Pre-built UI components (buttons, cards, etc.) | `//src/valdi_modules/src/valdi/valdi_widgets_core` |\n\n## ios_module_name Convention\n\nMust start with `SCC` followed by the module name in PascalCase:\n\n| Directory name | ios_module_name |\n|---|---|\n| `chat_thread` | `SCCChatThread` |\n| `profile_editor` | `SCCProfileEditor` |\n| `story_viewer` | `SCCStoryViewer` |\n\nThis becomes the Swift module name on iOS. Conflicts with other `SCCXxx` modules in\nthe same app target will cause a linker error.\n\n## New Component File Template\n\n```typescript\nimport { Component } from 'valdi_core/src/Component';\n\ninterface MyComponentViewModel {\n  // viewModel properties\n}\n\nexport class MyComponent extends Component<MyComponentViewModel> {\n  onRender(): void {\n    <view>\n      <label value={this.viewModel.someText} />;\n    </view>;\n  }\n}\n```\n\nFor stateful components:\n\n```typescript\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\ninterface MyState {\n  // state properties\n}\n\nexport class MyComponent extends StatefulComponent<MyComponentViewModel, MyState> {\n  state: MyState = { /* initial values */ };\n\n  onRender(): void {\n    // ...\n  }\n}\n```\n\n## Building\n\n```bash\nbazel build //path/to/my_module:my_module\n```\n\n## Hot Reload\n\n```bash\nvaldi hotreload\n```\n\nRun from your module directory. The CLI watches for file changes, recompiles, and\npushes the updated module to a connected simulator or device over USB (or network\nwith `--network`).\n\n```bash\nvaldi hotreload --network   # Discover device over Wi-Fi instead of USB\n```\n\nIf hot reload stops reflecting changes, stop with `Ctrl+C` and restart — the CLI\nwill clean stale build artifacts automatically.\n"
  },
  {
    "path": "ai-skills/skills/valdi-testing/skill.md",
    "content": "# Valdi Testing\n\n## Component Tests (most common)\n\nUse `valdiIt` from `valdi_test/test/JSXTestUtils` as the test wrapper. It provides a `driver` that renders components synchronously.\n\nSee **`valdi-component-tests`** skill for the full guide on:\n- `elementKeyFind`, `elementTypeFind`, `componentTypeFind`, `componentGetElements`\n- `tapNodeWithKey` for tap callbacks\n- Discriminated union and array view model testing\n- Lint rules (`jsx-no-lambda`, `explicit-function-return-type`, etc.)\n\n## Running Tests\n\n```bash\n# Run a specific module's tests\nbazel test //modules/my_module:tests\n\n# Run with output on failure\nbazel test //modules/my_module:tests --test_output=errors\n\n# Run all tests in the repo\nbazel test //...\n\n# Filter to a specific test class\nbazel test //modules/my_module:tests --test_filter=MyComponentTest\n```\n\n## Test File Location\n\nTest files must mirror the source file hierarchy:\n\n```\nmy_module/\n├── src/\n│   └── categories/\n│       └── CollectionComponent.tsx\n└── test/\n    └── categories/\n        └── CollectionComponentTest.spec.tsx\n```\n\n## BUILD.bazel for Tests\n\nAdd a `ts_project` or `valdi_module` test target. The test target lists test spec files in `srcs` and shares `deps` with the main module:\n\n```python\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"my_module_tests\",\n    srcs = glob([\"test/**/*.spec.tsx\", \"test/**/*.spec.ts\"]),\n    testonly = True,\n    deps = [\n        \":my_module\",\n        \"//src/valdi_modules/src/valdi/valdi_test\",\n        \"//src/valdi_modules/src/foundation/test/util\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n```\n\n## Platform Tests\n\nFor C++, iOS, and Android platform layer tests, see the `valdi-cpp-runtime`, `valdi-ios`, and `valdi-android` skills respectively.\n"
  },
  {
    "path": "ai-skills/skills/valdi-tsx/skill.md",
    "content": "# Valdi TypeScript/TSX Component Rules\n\n**Applies to**: TypeScript and TSX files in `/src/valdi_modules/`, `/apps/`, `/modules/`, `/npm_modules/`\n\n## 🚨 CRITICAL: Valdi is NOT React!\n\n**AI assistants frequently suggest React patterns that DON'T EXIST in Valdi.** Despite using TSX/JSX syntax, Valdi compiles to native code.\n\n### Most Common Mistakes\n\n```typescript\n// ❌ NEVER use React hooks (don't exist!)\nconst [count, setCount] = useState(0);  // ❌\nuseEffect(() => { ... }, []);           // ❌\n\n// ❌ NEVER use functional components (don't exist!)\nconst MyComponent = () => <view />;     // ❌\n\n// ❌ Common hallucinations\nthis.props.title;           // Should be: this.viewModel.title\nthis.markNeedsRender();     // Doesn't exist! Use setState()\nonMount() { }               // Should be: onCreate()\nreturn <view />;            // onRender() returns void!\n```\n\n> **📖 Full list**: See `/AGENTS.md` → \"AI Anti-Hallucination\" section for comprehensive examples\n\n### ✅ Correct Valdi Patterns\n\n```typescript\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\nclass MyComponent extends StatefulComponent<ViewModel, State> {\n  state = { count: 0 };\n  \n  onCreate() { }                           // Component created\n  onViewModelUpdate(prev: ViewModel) { }   // Props changed\n  onDestroy() { }                          // Before removal\n  \n  handleClick = () => {\n    this.setState({ count: this.state.count + 1 });  // Auto re-renders\n  };\n  \n  onRender() {  // Returns void, not JSX!\n    <button title={`Count: ${this.state.count}`} onPress={this.handleClick} />;\n  }\n}\n```\n\n## Quick Reference\n\n| What | React | Valdi |\n|------|-------|-------|\n| **Component** | Function or class | Class only (Component or StatefulComponent) |\n| **State** | `useState(0)` | `state = { count: 0 }` + `setState()` |\n| **Props** | `this.props.title` | `this.viewModel.title` |\n| **Mount** | `useEffect(() => {}, [])` | `onCreate()` |\n| **Update** | `useEffect(() => {}, [dep])` | `onViewModelUpdate(prev)` |\n| **Unmount** | `useEffect(() => () => {}, [])` | `onDestroy()` |\n| **Re-render** | `setCount(...)` | `this.setState(...)` |\n| **Return** | `return <view />` | `<view />;` (statement) |\n\n## Provider Pattern (Dependency Injection)\n\n```typescript\n// ✅ CORRECT - Create provider\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nconst MyServiceProvider = createProviderComponentWithKeyName<MyService>('MyServiceProvider');\n\n// ✅ CORRECT - Provide value\n<MyServiceProvider value={myService}>\n  <App />\n</MyServiceProvider>\n\n// ✅ CORRECT - Consume with HOC\nimport { withProviders, ProvidersValuesViewModel } from 'valdi_core/src/provider/withProviders';\n\ninterface MyViewModel extends ProvidersValuesViewModel<[MyService]> {}\n\nclass MyComponent extends Component<MyViewModel> {\n  onRender() {\n    const [service] = this.viewModel.providersValues;\n  }\n}\n\nconst MyComponentWithProvider = withProviders(MyServiceProvider)(MyComponent);\n```\n\n## Event Handling\n\n```typescript\n// ✅ CORRECT - Use onTap for interactive elements\n<view onTap={this.handleClick}>\n  <label value=\"Click me\" />\n</view>\n\n<button title=\"Press me\" onPress={this.handleAction} />\n\n// ❌ WRONG - No global keyboard events\nwindow.addEventListener('keydown', ...);  // Doesn't work!\ndocument.addEventListener('click', ...);  // Doesn't work!\n\n// ✅ CORRECT - For text input, use TextField callbacks\n<textfield \n  value={this.state.text}\n  onChange={this.handleTextChange}\n  onEditEnd={this.handleSubmit}\n/>\n```\n\n**Important**: Valdi doesn't support `addEventListener`, `keydown`, or other global DOM events. Use element-specific callbacks like `onTap`, `onPress`, `onChange`, etc.\n\n## Timers and Scheduling\n\n```typescript\n// ✅ CORRECT - Use component's setTimeoutDisposable\nclass MyComponent extends StatefulComponent<ViewModel, State> {\n  onCreate() {\n    // Timer auto-cancels when component destroys\n    this.setTimeoutDisposable(() => {\n      console.log('Delayed action');\n    }, 1000);\n  }\n  \n  // ✅ CORRECT - Recurring task pattern (use recursive setTimeout)\n  private scheduleLoop() {\n    this.setTimeoutDisposable(() => {\n      this.doSomething();\n      this.scheduleLoop();  // Schedule next iteration\n    }, 100);\n  }\n}\n\n// ❌ WRONG - Don't use setInterval directly\nsetInterval(() => { ... }, 100);  // Won't auto-cleanup!\n\n// ❌ WRONG - Don't use setTimeout directly\nsetTimeout(() => { ... }, 100);  // Won't auto-cleanup!\n```\n\n**Important**: Always use `this.setTimeoutDisposable()` in components. It automatically cleans up when the component is destroyed, preventing memory leaks.\n\n## Styling\n\n### Basic Style Usage\n\n```typescript\nimport { Style } from 'valdi_core/src/Style';\nimport { View, Label } from 'valdi_tsx/src/NativeTemplateElements';\nimport { systemBoldFont } from 'valdi_core/src/SystemFont';\n\n// ✅ CORRECT - Type-safe styles\nconst styles = {\n  // Style<View> can only be used on <view> elements\n  container: new Style<View>({\n    backgroundColor: '#fff',\n    padding: 10,\n    borderRadius: 8,\n    flexDirection: 'row',\n    justifyContent: 'center',\n    alignItems: 'center',\n  }),\n  \n  // Style<Label> can only be used on <label> elements\n  // Label uses font (string) NOT fontSize. Format: 'FontName Size [scaling] [maxSize]'\n  title: new Style<Label>({\n    color: '#000',\n    font: 'system 20',         // size via font string, NOT fontSize!\n    // font: systemBoldFont(20),  // or use SystemFont helper\n  }),\n};\n\n// Use in render\nonRender() {\n  <view style={styles.container}>\n    <label style={styles.title} value=\"Hello\" />\n  </view>;\n}\n```\n\n### Style Composition\n\n```typescript\n// ✅ CORRECT - Merge multiple styles\nconst combined = Style.merge(styles.base, styles.primary);\n\n// ✅ CORRECT - Extend a style with overrides\nconst largeButton = styles.button.extend({\n  width: 200,\n  height: 60,\n});\n\n// ✅ CORRECT - Dynamic styling with extend\n<view style={styles.container.extend({\n  backgroundColor: isActive ? 'blue' : 'gray',\n})} />\n\n// ❌ WRONG - Can't merge incompatible types\nStyle.merge(styles.viewStyle, styles.labelStyle);  // Type error!\n```\n\n### Spacing: Padding & Margin\n\n```typescript\n// ✅ CORRECT - Valdi spacing syntax\nnew Style<View>({\n  // Single value - all sides\n  padding: 10,\n  margin: 5,\n  \n  // String shorthand - vertical horizontal\n  padding: '10 20',    // 10pt top/bottom, 20pt left/right\n  margin: '5 10',\n  \n  // Individual sides\n  paddingTop: 5,\n  paddingRight: 10,\n  paddingBottom: 5,\n  paddingLeft: 10,\n  \n  // Percentages (relative to parent)\n  padding: '5%',       // 5% of parent width/height\n  marginLeft: '10%',   // 10% of parent width\n})\n\n// ❌ WRONG - These don't exist in Valdi\nnew Style<View>({\n  gap: 10,                  // ❌ Use margin on children\n  paddingHorizontal: 20,    // ❌ Use padding: '0 20'\n  paddingVertical: 10,      // ❌ Use padding: '10 0'\n  paddingInline: 15,        // ❌ Doesn't exist\n})\n```\n\n### Layout: Flexbox (Yoga)\n\n```typescript\n// ✅ CORRECT - Valdi uses Yoga flexbox\nnew Style<View>({\n  // Container properties\n  flexDirection: 'row',          // 'row' | 'column' | 'row-reverse' | 'column-reverse'\n  justifyContent: 'center',      // 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly'\n  alignItems: 'center',          // 'flex-start' | 'center' | 'flex-end' | 'stretch' | 'baseline'\n  alignContent: 'flex-start',    // For multi-line flex containers\n  flexWrap: 'wrap',              // 'wrap' | 'nowrap' | 'wrap-reverse'\n  \n  // Child properties\n  flexGrow: 1,                   // Grow to fill space (NOTE: use flexGrow, not flex)\n  flexShrink: 1,                 // How much to shrink\n  flexBasis: 100,                // Base size before flex\n  alignSelf: 'center',           // Override parent's alignItems\n})\n\n// ❌ WRONG - These don't exist\nnew Style<View>({\n  display: 'grid',               // ❌ Only 'flex' supported\n  gridTemplateColumns: '1fr 1fr', // ❌ No CSS Grid\n  flex: 1,                       // ❌ Use flexGrow: 1 instead!\n})\n```\n\n### Position & Size\n\n```typescript\n// ✅ CORRECT - Positioning\nnew Style<View>({\n  // Size\n  width: 200,           // Points\n  width: '50%',         // Percentage of parent\n  width: 'auto',        // Auto-size\n  height: 100,\n  minWidth: 50,\n  maxWidth: 500,\n  aspectRatio: 16/9,    // Width:height ratio\n  \n  // Position\n  position: 'relative', // 'relative' | 'absolute'\n  top: 10,\n  right: 10,\n  bottom: 10,\n  left: 10,\n})\n```\n\n### Common Properties\n\n```typescript\n// ✅ CORRECT - Frequently used properties\nnew Style<View>({\n  backgroundColor: '#fff',\n  opacity: 0.8,\n  \n  // Borders\n  borderRadius: 8,\n  borderWidth: 1,\n  borderColor: '#ccc',\n  borderTopWidth: 2,\n  \n  // Shadow\n  boxShadow: '0 2 4 rgba(0, 0, 0, 0.1)',\n  \n  // Overflow — only 'visible' | 'scroll' (NOT 'hidden'!)\n  overflow: 'scroll',   // 'visible' | 'scroll'\n})\n```\n\n### Type Safety\n\n```typescript\n// ✅ CORRECT - Style types match element types\nconst viewStyle = new Style<View>({ backgroundColor: 'red' });\nconst labelStyle = new Style<Label>({ color: 'blue' });\n\n<view style={viewStyle} />      // ✅ Works\n<label style={labelStyle} />    // ✅ Works\n\n// ❌ WRONG - Type mismatch\n<label style={viewStyle} />     // ❌ Type error!\n<view style={labelStyle} />     // ❌ Type error!\n\n// ✅ CORRECT - Layout styles work on any layout element\nconst layoutStyle = new Style<Layout>({ padding: 10 });\n<view style={layoutStyle} />    // ✅ view extends Layout\n<label style={layoutStyle} />   // ✅ label extends Layout\n```\n\n> **📖 Complete reference**: See `/docs/api/api-style-attributes.md` for all 1290+ style properties\n> \n> **📖 Best practices**: See `/docs/docs/core-styling.md` for styling patterns and examples\n\n## Common Mistakes to Avoid\n\n1. **Returning JSX from onRender()** - It returns void, JSX is a statement\n2. **Forgetting setState()** - Direct mutation won't trigger re-render\n3. **Using this.props** - Should be this.viewModel\n4. **Wrong lifecycle names** - onCreate/onViewModelUpdate/onDestroy (not mount/update/unmount)\n5. **Suggesting scheduleRender()** - Deprecated, use StatefulComponent + setState()\n6. **Using addEventListener** - Use element callbacks like onTap, onPress, onChange\n7. **Using setInterval/setTimeout directly** - Use this.setTimeoutDisposable()\n8. **Using CSS properties that don't exist** - No gap, paddingHorizontal, paddingVertical\n9. **Using `flex: 1`** - `flex` doesn't exist on `View`; use `flexGrow: 1` instead\n10. **Using `fontSize` on Label** - Labels use `font: 'system 20'` (string), not `fontSize`\n11. **Using `overflow: 'hidden'`** - `View` only accepts `'visible' | 'scroll'`; remove overflow or use 'scroll'\n\n## Platform Detection\n\nUse `Device` for platform-conditional rendering:\n\n```typescript\nimport { Device } from 'valdi_core/src/Device';\n\nclass MyComponent extends Component<MyViewModel> {\n  onRender(): void {\n    <view>\n      {Device.isIOS() && <IOSOnlyView />}\n      {Device.isAndroid() && <AndroidOnlyView />}\n      {Device.isMacOS() && <MacOSOnlyView />}\n      {Device.isWeb() && <WebOnlyView />}\n    </view>;\n  }\n}\n```\n\nAlso use `Device.isIOS()` / `Device.isAndroid()` guards before using `<custom-view>` elements that don't have implementations on all platforms.\n\n## Imports\n\n```typescript\n// ✅ CORRECT imports\nimport { Component, StatefulComponent } from 'valdi_core/src/Component';\nimport { Device } from 'valdi_core/src/Device';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { Style } from 'valdi_core/src/Style';\n\n// ❌ WRONG - React imports don't exist\nimport React from 'react';  // Error!\nimport { useState } from 'react';  // Error!\n```\n\n## More Information\n\n- **Full anti-hallucination guide**: `/AGENTS.md` (comprehensive React vs Valdi comparison)\n- **AI tooling**: `/docs/docs/ai-tooling.md`\n- **Provider pattern**: `/docs/docs/advanced-provider.md`\n- **Valdi GitHub**: https://github.com/Snapchat/Valdi\n"
  },
  {
    "path": "ai-skills/skills/valdi-tsx/tests/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"tests\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiTsxRef\",\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "ai-skills/skills/valdi-tsx/tests/README.md",
    "content": "# valdi-tsx skill tests\n\nCompile check for the core TSX component patterns taught in `skill.md`.\n\n## What's tested\n\n`src/reference.tsx` exercises:\n- Stateless `Component<VM>` with `onRender()` void pattern\n- `StatefulComponent` with `state`, `setState`, and all lifecycle methods\n- Class arrow functions for event handlers (not inline lambdas)\n- `setTimeoutDisposable` for auto-cleanup timers\n- `forEach` for list rendering (not `map`)\n- `<layout>` spacer (no native view)\n- Module-level `Style` objects (`new Style<View>(...)`)\n- Provider pattern: `createProviderComponentWithKeyName`, `withProviders`\n- `Device.isIOS()` / `isAndroid()` platform detection\n\n## Compile check\n\n```bash\ncd client/src/open_source\nbazel build //ai-skills/skills/valdi-tsx/tests:tests\n```\n\nExpected: `Build completed successfully`\n\n## Updating\n\nWhen Valdi APIs change (import paths, type signatures), update `src/reference.tsx` to match and keep it compiling. Also update `../skill.md` with any corrected patterns.\n"
  },
  {
    "path": "ai-skills/skills/valdi-tsx/tests/src/reference.tsx",
    "content": "// valdi-tsx skill reference — compile check for core component patterns.\n// This file must compile cleanly against the Valdi TypeScript compiler.\n// Run: bzl build //ai-skills/skills/valdi-tsx/tests:tests\n\nimport { Component, StatefulComponent } from 'valdi_core/src/Component';\nimport { Device } from 'valdi_core/src/Device';\nimport { Style } from 'valdi_core/src/Style';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nimport { ProvidersValuesViewModel, withProviders } from 'valdi_core/src/provider/withProviders';\nimport { Label, Layout, View } from 'valdi_tsx/src/NativeTemplateElements';\n\n// ─── Module-level styles (NOT inside onRender) ──────────────────────────────\n\nconst styles = {\n  card: new Style<View>({\n    backgroundColor: '#fff',\n    borderRadius: 8,\n    padding: 12,\n    flexDirection: 'column',\n  }),\n  spacer: new Style<Layout>({ height: 8 }),\n  title: new Style<Label>({\n    color: '#000',\n    font: systemFont(16),  // Label uses font string, NOT fontSize\n  }),\n};\n\n// ─── Stateless component ─────────────────────────────────────────────────────\n\ninterface GreetingViewModel {\n  name: string;\n}\n\nclass Greeting extends Component<GreetingViewModel> {\n  onRender(): void {\n    // onRender returns void — no return statement\n    <label value={`Hello, ${this.viewModel.name}`} />;\n  }\n}\n\n// ─── Stateful component with full lifecycle ───────────────────────────────────\n\ninterface CounterViewModel {\n  label: string;\n}\n\ninterface CounterState {\n  count: number;\n  inputText: string;\n}\n\nclass Counter extends StatefulComponent<CounterViewModel, CounterState> {\n  state: CounterState = { count: 0, inputText: '' };\n\n  onCreate(): void {\n    // Timer auto-cancels on destroy\n    this.setTimeoutDisposable(() => {\n      this.setState({ count: 1 });\n    }, 5000);\n  }\n\n  onViewModelUpdate(previous?: CounterViewModel): void {\n    if (this.viewModel.label !== previous?.label) {\n      this.setState({ count: 0 });\n    }\n  }\n\n  onDestroy(): void {\n    // cleanup\n  }\n\n  // Class arrow functions — never inline lambdas in JSX props\n  private handleIncrement = (): void => {\n    this.setState({ count: this.state.count + 1 });\n  };\n\n  private handleTextChange = (text: string): void => {\n    this.setState({ inputText: text });\n  };\n\n  onRender(): void {\n    <view style={styles.card}>\n      <label value={`${this.viewModel.label}: ${this.state.count}`} />;\n      <layout style={styles.spacer} />;\n      <textfield\n        value={this.state.inputText}\n        onChange={this.handleTextChange}\n      />;\n      <button title=\"Increment\" onPress={this.handleIncrement} />;\n    </view>;\n  }\n}\n\n// ─── List rendering with forEach ─────────────────────────────────────────────\n\ninterface ItemViewModel {\n  id: string;\n  title: string;\n}\n\ninterface ItemListViewModel {\n  items: ItemViewModel[];\n}\n\nclass ItemList extends Component<ItemListViewModel> {\n  onRender(): void {\n    <scroll>\n      {this.viewModel.items.forEach(item => {\n        // Stable key from data ID — not array index\n        <view key={item.id}>\n          <label value={item.title} />;\n        </view>;\n      })}\n    </scroll>;\n  }\n}\n\n// ─── Platform detection ──────────────────────────────────────────────────────\n\ninterface MediaPlayerViewModel {\n  videoUrl: string;\n}\n\nclass MediaPlayer extends Component<MediaPlayerViewModel> {\n  onRender(): void {\n    <view>\n      {Device.isIOS() && <label value=\"iOS player\" />}\n      {Device.isAndroid() && <label value=\"Android player\" />}\n      {Device.isMacOS() && <label value=\"macOS player\" />}\n    </view>;\n  }\n}\n\n// ─── Provider pattern ────────────────────────────────────────────────────────\n\nclass ThemeService {\n  primaryColor = '#FFFC00';\n  fontSize = 16;\n}\n\nconst ThemeProvider = createProviderComponentWithKeyName<ThemeService>('ThemeProvider');\n\ninterface ThemedViewModel extends ProvidersValuesViewModel<[ThemeService]> {\n  text: string;\n}\n\nclass ThemedLabel extends Component<ThemedViewModel> {\n  onRender(): void {\n    const [theme] = this.viewModel.providersValues;\n    <label value={this.viewModel.text} />;\n    void theme; // reference theme to satisfy compiler\n  }\n}\n\nconst ThemedLabelWithProvider = withProviders(ThemeProvider)(ThemedLabel);\n\nclass AppRoot extends Component {\n  private theme = new ThemeService();\n\n  onRender(): void {\n    <ThemeProvider value={this.theme}>\n      <ThemedLabelWithProvider text=\"Hello\" />;\n    </ThemeProvider>;\n  }\n}\n\n// Suppress unused-variable warnings for top-level declarations\nvoid Counter;\nvoid ItemList;\nvoid Greeting;\nvoid MediaPlayer;\nvoid AppRoot;\n"
  },
  {
    "path": "ai-skills/skills/valdi-tsx/tests/tsconfig.json",
    "content": "{\"extends\": \"../../../../src/valdi_modules/src/valdi/_configs/base.tsconfig.json\"}\n"
  },
  {
    "path": "apps/.prettierrc.json",
    "content": "{\n  \"printWidth\": 120,\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"arrowParens\": \"avoid\",\n  \"tabWidth\": 2\n}\n"
  },
  {
    "path": "apps/benchmark/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_application.bzl\", \"valdi_application\")\nload(\"//bzl/valdi:valdi_cli_application.bzl\", \"valdi_cli_application\")\n\nvaldi_cli_application(\n    name = \"benchmark_cli\",\n    script_path = \"benchmark/src/main\",\n    deps = [\"//apps/benchmark/src/valdi/benchmark\"],\n)\n\nvaldi_application(\n    name = \"benchmark\",\n    android_activity_theme_name = \"Theme.MyApp.Launch\",\n    android_app_icon_name = \"app_icon\",\n    android_resource_files = glob([\"app_assets/android/**\"]),\n    ios_app_icons = glob([\"app_assets/ios/Icons.xcassets/**\"]),\n    ios_bundle_id = \"com.snap.valdi.benchmark\",\n    ios_families = [\"iphone\"],\n    root_component_path = \"App@benchmark/src/BenchmarkApp\",\n    title = \"Valdi Benchmark\",\n    version = \"1.0.0\",\n    deps = [\"//apps/benchmark/src/valdi/benchmark\"],\n)\n"
  },
  {
    "path": "apps/benchmark/app_assets/android/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"splash_bg\">#FFFFFF</color>\n</resources>\n"
  },
  {
    "path": "apps/benchmark/app_assets/android/values/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <style name=\"Theme.MyApp.Launch\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"android:windowBackground\">@drawable/splash</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "apps/benchmark/app_assets/ios/Icons.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\": [\n    {\n      \"size\": \"60x60\",\n      \"expected-size\": \"180\",\n      \"filename\": \"180.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"expected-size\": \"80\",\n      \"filename\": \"80.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"expected-size\": \"120\",\n      \"filename\": \"120.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"60x60\",\n      \"expected-size\": \"120\",\n      \"filename\": \"120.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"58\",\n      \"filename\": \"58.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"29\",\n      \"filename\": \"29.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"87\",\n      \"filename\": \"87.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"expected-size\": \"40\",\n      \"filename\": \"40.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"expected-size\": \"60\",\n      \"filename\": \"60.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"1024x1024\",\n      \"filename\": \"1024.png\",\n      \"expected-size\": \"1024\",\n      \"idiom\": \"ios-marketing\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"expected-size\": \"80\",\n      \"filename\": \"80.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"76x76\",\n      \"expected-size\": \"152\",\n      \"filename\": \"152.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"58\",\n      \"filename\": \"58.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"29\",\n      \"filename\": \"29.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"expected-size\": \"40\",\n      \"filename\": \"40.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"83.5x83.5\",\n      \"expected-size\": \"167\",\n      \"filename\": \"167.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"expected-size\": \"20\",\n      \"filename\": \"20.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"expected-size\": \"40\",\n      \"filename\": \"40.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    }\n  ]\n}\n"
  },
  {
    "path": "apps/benchmark/src/android/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_android_library.bzl\", \"valdi_android_library\")\n\nvaldi_android_library(\n    name = \"native_module_android\",\n    srcs = glob([\n        \"**/*.kt\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//apps/benchmark/src/valdi/benchmark:benchmark_api_kt\",\n        \"//valdi:valdi_android_support\",\n    ],\n)\n"
  },
  {
    "path": "apps/benchmark/src/android/MyNativeModuleFactory.kt",
    "content": "package com.snap.valdi.benchmark\nimport com.snapchat.client.valdi_core.ModuleFactory\nimport com.snap.valdi.modules.RegisterValdiModule\nimport com.snap.valdi.modules.benchmark.NativeHelperModuleFactory\nimport com.snap.valdi.modules.benchmark.NativeHelperModule\nimport com.snap.valdi.modules.benchmark.FunctionTiming\nimport android.os.SystemClock\n\n@RegisterValdiModule\nclass NativeHelperFactoryImpl: NativeHelperModuleFactory() {\n\n    override fun onLoadModule(): NativeHelperModule {\n        return object: NativeHelperModule {\n\n            var nativeTiming = mutableListOf<FunctionTiming>()\n            \n            override fun measureStrings(data: List<String>): List<String> {\n                val ts = SystemClock.uptimeMillis()\n                nativeTiming.add(FunctionTiming(ts.toDouble(), ts.toDouble()))\n                return data\n            }\n\n            override fun measureStringMaps(data: List<Map<String, Any?>>): List<Map<String, Any?>> {\n                val ts = SystemClock.uptimeMillis()\n                nativeTiming.add(FunctionTiming(ts.toDouble(), ts.toDouble()))\n                return data\n            }\n            \n            override fun clearNativeFunctionTiming() {\n                nativeTiming.clear()\n            }\n\n            override fun getNativeFunctionTiming(): List<FunctionTiming> {\n                return nativeTiming\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "apps/benchmark/src/cpp/BUILD.bazel",
    "content": "cc_library(\n    name = \"native_module_cpp\",\n    srcs = [\"CppModule.cpp\"],\n    hdrs = [],\n    includes = [],\n    visibility = [\"//visibility:public\"],\n    deps = [\"@valdi//valdi_core\"],\n    alwayslink = 1,\n)\n"
  },
  {
    "path": "apps/benchmark/src/cpp/CppModule.cpp",
    "content": "#include \"valdi_core/cpp/JavaScript/ModuleFactoryRegistry.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n#include \"valdi_core/cpp/Utils/ValueFunctionWithCallable.hpp\"\n\n#include <ctime>\n#include <iostream>\n#include <string>\n\nnamespace snap::valdi::benchmark {\n\n#ifdef __APPLE__\n#define BENCHMARK_CLOCK CLOCK_UPTIME_RAW\n#else\n#define BENCHMARK_CLOCK CLOCK_MONOTONIC\n#endif\n\nclass CppHelperModule : public valdi_core::ModuleFactory {\npublic:\n    Valdi::StringBox getModulePath() final {\n        return Valdi::StringBox::fromCString(\"benchmark/src/cpp\");\n    }\n\n    Valdi::Value loadModule() final {\n        return Valdi::Value()\n            .setMapValue(\"now\",\n                         Valdi::Value(Valdi::makeShared<Valdi::ValueFunctionWithCallable>(\n                             [](const Valdi::ValueFunctionCallContext& callContext) -> Valdi::Value {\n                                 struct timespec ts;\n                                 clock_gettime(BENCHMARK_CLOCK, &ts);\n                                 uint64_t nano_since_epoch = (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec;\n                                 return Valdi::Value(nano_since_epoch / 1000000.0);\n                             })))\n            .setMapValue(\"question\",\n                         Valdi::Value(Valdi::makeShared<Valdi::ValueFunctionWithCallable>(\n                             [](const Valdi::ValueFunctionCallContext& callContext) -> Valdi::Value {\n                                 auto q = callContext.getParameter(0).toString(false);\n                                 std::cout << q;\n                                 std::string line;\n                                 std::getline(std::cin, line);\n                                 return Valdi::Value(line);\n                             })))\n            .setMapValue(\"print\",\n                         Valdi::Value(Valdi::makeShared<Valdi::ValueFunctionWithCallable>(\n                             [](const Valdi::ValueFunctionCallContext& callContext) -> Valdi::Value {\n                                 auto s = callContext.getParameter(0).toString(false);\n                                 std::cout << s << std::endl;\n                                 return Valdi::Value();\n                             })));\n    }\n};\n\nauto kRegisterCppHelperModule = Valdi::RegisterModuleFactory::registerTyped<CppHelperModule>();\n\n} // namespace snap::valdi::benchmark\n"
  },
  {
    "path": "apps/benchmark/src/ios/BUILD.bazel",
    "content": "objc_library(\n    name = \"native_module_ios\",\n    srcs = glob([\n        \"**/*.m\",\n    ]),\n    hdrs = [],\n    copts = [\"-I.\"],\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//apps/benchmark/src/valdi/benchmark:benchmark_api_objc\",\n    ],\n)\n"
  },
  {
    "path": "apps/benchmark/src/ios/SCMyNativeModuleFactory.m",
    "content": "#import \"valdi_core/SCValdiModuleFactoryRegistry.h\"\n#import <BenchmarkTypes/BenchmarkTypes.h>\n#import <Foundation/Foundation.h>\n#include <time.h>\n\n@interface NativeHelperImpl: NSObject<BenchmarkNativeHelperModule>\n\n@end\n\n@implementation NativeHelperImpl {\n    NSMutableArray<BenchmarkFunctionTiming*>* _nativeTiming;\n}\n\n- (instancetype)init {\n    self = [super init];\n    if (self) {\n        _nativeTiming = [[NSMutableArray alloc] init];\n    }\n    return self;\n}\n\n- (void)recordTiming {\n    struct timespec ts;\n    clock_gettime(CLOCK_UPTIME_RAW, &ts);\n    uint64_t nanosSinceEpoch = (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec;\n    BenchmarkFunctionTiming* nativeTiming = [[BenchmarkFunctionTiming alloc] init];\n    nativeTiming.enterTime = nanosSinceEpoch / 1000000.0;\n    nativeTiming.leaveTime = nativeTiming.enterTime;\n    [_nativeTiming addObject:nativeTiming];\n}\n\n- (NSArray<NSString*>*)measureStringsWithData:(NSArray<NSString*>*)data\n{\n    [self recordTiming];\n    return data;\n}\n\n- (NSArray<NSDictionary<NSString*, id>*>* _Nonnull)measureStringMapsWithData:(NSArray<NSDictionary<NSString*, id>*>* _Nonnull)data\n{\n    [self recordTiming];\n    return data;\n}\n\n- (void)clearNativeFunctionTiming\n{\n    [_nativeTiming removeAllObjects];\n}\n\n- (NSArray<BenchmarkFunctionTiming*>*)getNativeFunctionTiming\n{\n    return _nativeTiming;\n}\n\n@end\n\n@interface NativeHelperFactoryImpl : BenchmarkNativeHelperModuleFactory\n\n@end\n\n@implementation NativeHelperFactoryImpl\n\nVALDI_REGISTER_MODULE()\n\n- (id<BenchmarkNativeHelperModule>)onLoadModule\n{\n    return [NativeHelperImpl new];\n}\n\n@end\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"benchmark\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"src/**/*.js\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_class_path = \"com.snap.valdi.modules.benchmark\",\n    android_deps = [\"//apps/benchmark/src/android:native_module_android\"],\n    android_output_target = \"release\",\n    ios_deps = [\"//apps/benchmark/src/ios:native_module_ios\"],\n    ios_module_name = \"Benchmark\",\n    ios_output_target = \"release\",\n    native_deps = [\"//apps/benchmark/src/cpp:native_module_cpp\"],\n    protodecl_srcs = glob([\n        \"src/**/*.protodecl\",\n    ]),\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/coreutils\",\n        \"//src/valdi_modules/src/valdi/drawing\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_navigation\",\n        \"//src/valdi_modules/src/valdi/valdi_protobuf\",\n        \"//src/valdi_modules/src/valdi/valdi_standalone\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/BenchmarkApp.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { ComponentConstructor, IComponent } from 'valdi_core/src/IComponent';\nimport { systemBoldFont } from 'valdi_core/src/SystemFont';\nimport { NavigationRoot } from 'valdi_navigation/src/NavigationRoot';\nimport { NavigationController } from 'valdi_navigation/src/NavigationController';\nimport { $slot } from 'valdi_core/src/CompilerIntrinsics';\nimport { createReusableCallback } from 'valdi_core/src/utils/Callback';\nimport { MicroBenchTest } from './MicroBenchTest';\nimport { MarshallingTest } from './MarshallingTest';\nimport { RenderTest } from './RenderTest';\nimport { DrawFrameBenchmark } from './DrawFrameBenchmark';\nimport { ProtoImportTest } from './ProtoImportTest';\n\n// Bechmarks\n// - Quickjs microbench\n// - Marshalling various data\n// - Rendering many shapes\n\nexport class App extends Component {\n  onRender(): void {\n    <NavigationRoot>\n      {$slot(navigationController => {\n        <view backgroundColor=\"white\" width=\"100%\" height=\"100%\" alignItems=\"center\" justifyContent=\"center\">\n          {this.renderButtons(navigationController)}\n        </view>;\n      })}\n    </NavigationRoot>;\n  }\n\n  private renderButtons(navigationController: NavigationController): void {\n    this.renderButton('MicroBench', MicroBenchTest, navigationController);\n    this.renderButton('Marshalling', MarshallingTest, navigationController);\n    this.renderButton('Rendering', RenderTest, navigationController);\n    this.renderButton('DrawFrame', DrawFrameBenchmark, navigationController);\n    this.renderButton('Protobuf Import', ProtoImportTest, navigationController);\n  }\n\n  private renderButton(\n    name: string,\n    componentCtor: ComponentConstructor<IComponent>,\n    navigationController: NavigationController,\n  ): void {\n    <PageButton\n      title={`${name}`}\n      onTap={createReusableCallback(() => {\n        this.presentPage(name, componentCtor, navigationController);\n      })}\n    />;\n  }\n  private presentPage(\n    title: string,\n    componentCtor: ComponentConstructor<IComponent>,\n    navigationController: NavigationController,\n  ): void {\n    navigationController.present(componentCtor, {}, {});\n  }\n}\n\ninterface PageButtonViewModel {\n  title: string;\n  onTap: () => void;\n}\n\nclass PageButton extends Component<PageButtonViewModel> {\n  onRender(): void {\n    <view\n      backgroundColor=\"lightgray\"\n      padding={16}\n      alignSelf=\"stretch\"\n      margin={8}\n      marginLeft={24}\n      marginRight={24}\n      borderRadius={'50%'}\n      boxShadow={'0 0 3 rgba(0, 0, 0, 0.15)'}\n      alignItems=\"center\"\n      onTap={this.viewModel.onTap}\n    >\n      <label color=\"black\" value={this.viewModel.title} font={systemBoldFont(17)} />\n    </view>;\n  }\n}\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/BenchmarkSingleRunComponent.tsx",
    "content": "import { StatefulComponent } from 'valdi_core/src/Component';\nimport { IComponent } from 'valdi_core/src/IComponent';\nimport { IComponentRenderObserver } from 'valdi_core/src/IComponentRenderObserver';\nimport { onIdleInterruptible } from 'valdi_core/src/utils/OnIdle';\n\nexport type BenchmarkCompleteVerifierCallback = (component: IComponent) => boolean;\nexport type BenchmarkCompleteCallback = () => void;\n\nexport interface BenchmarkResult {}\n\nexport interface BenchmarkRunner {\n  start(): void;\n  incrementRunCount(): void;\n  measureAsync(metricName: string): () => void;\n  stop(): BenchmarkResult;\n}\n\nexport interface BenchmarkSingleRunComponentViewModel {\n  benchmarkRunner: BenchmarkRunner;\n\n  /**\n   * Verify that the component fully finished rendering.\n   * @param component\n   */\n  verifyCompleted: BenchmarkCompleteVerifierCallback;\n\n  /**\n   * Called whenever the component has fully finished rendering.\n   * @param result\n   */\n  onComplete: BenchmarkCompleteCallback;\n}\n\ninterface State {\n  didSettleOnce: boolean;\n}\n\n/**\n * A component which takes care of inflating a component through its slot,\n * and calls an `onComplete` callback with timing informations about how\n * long it took for the app to fully settle after the rendering.\n * For more accurate measures, the benchmark component waits until an initial settle before\n * starting to render the component.\n */\nexport class BenchmarkSingleRunComponent\n  extends StatefulComponent<BenchmarkSingleRunComponentViewModel, State>\n  implements IComponentRenderObserver\n{\n  state: State = { didSettleOnce: false };\n\n  private onIdleSequence = 0;\n  private benchmarkedComponent?: IComponent;\n  private onSettleCompletion?: () => void;\n  private didComplete = false;\n\n  onCreate() {\n    this.viewModel.benchmarkRunner.incrementRunCount();\n    this.onSettleCompletion = this.viewModel.benchmarkRunner.measureAsync('Settle');\n\n    this.renderer.addObserver(this);\n\n    onIdleInterruptible(() => {\n      this.setState({ didSettleOnce: true });\n    });\n  }\n\n  onDestroy() {\n    this.renderer.removeObserver(this);\n  }\n\n  onRender() {\n    if (!this.state.didSettleOnce) {\n      return;\n    }\n\n    const onDone = this.viewModel.benchmarkRunner.measureAsync('Render Component');\n\n    <slot />;\n\n    const emittedComponents = this.renderer.getComponentChildren(this);\n    if (emittedComponents.length !== 1) {\n      throw new Error(\n        `Only one component should be inflated inside the slot of BenchmarkComponent, we got ${emittedComponents.length}`,\n      );\n    }\n\n    const benchmarkedComponent = emittedComponents[0];\n    this.benchmarkedComponent = benchmarkedComponent;\n\n    this.scheduleOnRenderEnd(onDone, benchmarkedComponent);\n  }\n\n  private isComponentIsBenchmarkedComponentSubtree(component: IComponent): boolean {\n    const benchmarkedComponent = this.benchmarkedComponent;\n    if (!benchmarkedComponent) {\n      return false;\n    }\n\n    let current: IComponent | undefined = component;\n    while (current) {\n      if (current === benchmarkedComponent) {\n        return true;\n      }\n\n      current = this.renderer.getComponentParent(current);\n    }\n\n    return false;\n  }\n\n  onComponentWillRerender(component: IComponent) {\n    if (!this.isComponentIsBenchmarkedComponentSubtree(component)) {\n      return;\n    }\n    const onDone = this.viewModel.benchmarkRunner.measureAsync('Render Component');\n\n    this.scheduleOnRenderEnd(onDone, component);\n  }\n\n  private scheduleOnRenderEnd(onDone: () => void, component: IComponent) {\n    this.renderer.onRenderComplete(() => {\n      onDone();\n\n      const sequence = ++this.onIdleSequence;\n      onIdleInterruptible(() => {\n        this.onMainThreadIdle(sequence);\n      });\n    });\n  }\n\n  private onMainThreadIdle(sequence: number) {\n    if (this.isDestroyed() || sequence !== this.onIdleSequence) {\n      return;\n    }\n\n    if (this.viewModel.verifyCompleted(this.benchmarkedComponent!)) {\n      this.notifyBenchmarkCompleted(new Date());\n    }\n  }\n\n  private notifyBenchmarkCompleted(idleDate: Date) {\n    if (this.didComplete) {\n      return;\n    }\n\n    this.didComplete = true;\n    const settleCompletion = this.onSettleCompletion;\n    this.onSettleCompletion = undefined;\n    if (settleCompletion) {\n      settleCompletion();\n    }\n\n    this.viewModel.onComplete();\n  }\n}\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/DrawFrameBenchmark.tsx",
    "content": "import { NavigationPage } from 'valdi_navigation/src/NavigationPage';\nimport { NavigationPageStatefulComponent } from 'valdi_navigation/src/NavigationPageComponent';\nimport { Style } from 'valdi_core/src/Style';\nimport { Component } from 'valdi_core/src/Component';\nimport { systemBoldFont, systemFont } from 'valdi_core/src/SystemFont';\nimport { Device } from 'valdi_core/src/Device';\nimport { Label, ScrollView } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Stopwatch } from 'valdi_core/src/utils/Stopwatch';\nimport { GeometricPathBuilder, GeometricPathScaleType } from 'valdi_core/src/GeometricPath';\nimport { createManagedContext } from 'drawing/src/ManagedContextFactory';\nimport { createBitmap } from 'drawing/src/BitmapFactory';\nimport { BitmapAlphaType, BitmapColorType } from 'drawing/src/IBitmap';\nimport { IManagedContext } from 'drawing/src/IManagedContext';\nimport { IBitmap } from 'drawing/src/IBitmap';\nimport { setTimeoutInterruptible } from 'valdi_core/src/SetTimeout';\n\n// ---------------------------------------------------------------------------\n// Complex synthetic scene -- approximates SnapEditor-level complexity\n// ~100-150 nodes, 8-10 levels deep, exercises all major drawing primitives\n// ---------------------------------------------------------------------------\n\ninterface ComplexBenchmarkSceneViewModel {\n  frameIndex: number;\n}\n\nconst ds = Device.getDisplayScale();\nconst titleFont = systemBoldFont(34 * ds);\nconst bodyFont = systemFont(20 * ds);\nconst smallFont = systemFont(12 * ds);\nconst tinyFont = systemFont(9 * ds);\n\n/**\n * Convert HSL+alpha to an rgba() string, since Valdi doesn't support hsla().\n * h: 0-360, s: 0-100, l: 0-100, a: 0-1\n */\nfunction hsla(h: number, s: number, l: number, a: number): string {\n  h = ((h % 360) + 360) % 360;\n  const sn = s / 100;\n  const ln = l / 100;\n  const c = (1 - Math.abs(2 * ln - 1)) * sn;\n  const x = c * (1 - Math.abs(((h / 60) % 2) - 1));\n  const m = ln - c / 2;\n  let r = 0;\n  let g = 0;\n  let b = 0;\n  if (h < 60) { r = c; g = x; b = 0; }\n  else if (h < 120) { r = x; g = c; b = 0; }\n  else if (h < 180) { r = 0; g = c; b = x; }\n  else if (h < 240) { r = 0; g = x; b = c; }\n  else if (h < 300) { r = x; g = 0; b = c; }\n  else { r = c; g = 0; b = x; }\n  const ri = Math.round((r + m) * 255);\n  const gi = Math.round((g + m) * 255);\n  const bi = Math.round((b + m) * 255);\n  return `rgba(${ri},${gi},${bi},${a})`;\n}\n\n/**\n * Generates a unique geometric path for each frame to defeat draw caching.\n */\nfunction makeAnimatedPath(frameIndex: number, variant: number): ReturnType<GeometricPathBuilder['build']> {\n  const phase = ((frameIndex + variant * 17) % 60) / 60;\n  const builder = new GeometricPathBuilder(1, 1, GeometricPathScaleType.Contain);\n\n  // Varying arc sweep\n  builder.arcTo(0.5, 0.5, 0.4, Math.PI * phase, Math.PI * 2 * (0.3 + phase * 0.7));\n\n  // Additional line segments for complexity\n  const points = 5 + (variant % 4);\n  for (let i = 0; i < points; i++) {\n    const angle = (Math.PI * 2 * i) / points + phase * Math.PI;\n    const r = 0.3 + 0.15 * Math.sin(angle * 2 + variant);\n    builder.lineTo(0.5 + r * Math.cos(angle), 0.5 + r * Math.sin(angle));\n  }\n  return builder.build();\n}\n\n/**\n * Generates drawing stroke paths that vary per frame (for the \"drawing\" entity).\n */\nfunction makeStrokePath(frameIndex: number, strokeIdx: number): ReturnType<GeometricPathBuilder['build']> {\n  const seed = frameIndex * 13 + strokeIdx * 7;\n  const phase = (seed % 100) / 100;\n  const builder = new GeometricPathBuilder(1, 1, GeometricPathScaleType.Contain);\n\n  const segments = 4 + (strokeIdx % 3);\n  const startX = 0.05 + phase * 0.1;\n  const startY = 0.1 + (strokeIdx / 20) * 0.8;\n  builder.moveTo(startX, startY);\n\n  for (let j = 1; j <= segments; j++) {\n    const t = j / segments;\n    const x = startX + t * 0.9;\n    const y = startY + 0.05 * Math.sin(t * Math.PI * 3 + phase * Math.PI * 2);\n    builder.lineTo(x, y);\n  }\n  return builder.build();\n}\n\nconst STROKE_COLORS = [\n  'red', 'blue', 'green', 'orange', 'purple',\n  'cyan', 'magenta', 'yellow', '#FF6B6B', '#4ECDC4',\n  '#45B7D1', '#96CEB4', '#FFEAA7', '#DFE6E9', '#6C5CE7',\n  '#FD79A8', '#00B894', '#E17055', '#0984E3', '#636E72',\n];\n\nconst STROKE_CAPS: Array<'round' | 'butt' | 'square'> = ['round', 'butt', 'square'];\n\nclass ComplexBenchmarkScene extends Component<ComplexBenchmarkSceneViewModel> {\n  onRender(): void {\n    const idx = this.viewModel.frameIndex;\n    const bgHue = (idx * 6) % 360;\n\n    // -- Root container with clipping (like playback bounds) --\n    <view\n      backgroundColor=\"black\"\n      width=\"100%\"\n      height=\"100%\"\n      slowClipping\n      borderRadius={20 * ds}\n    >\n      {/* Background layer: solid color + gradient overlay */}\n      <view\n        position=\"absolute\"\n        top={0} left={0} right={0} bottom={0}\n        background={`linear-gradient(180deg, ${hsla(bgHue, 50, 20, 1)}, ${hsla((bgHue + 60) % 360, 40, 10, 1)})`}\n      />\n\n      {/* Semi-transparent gradient overlay */}\n      <view\n        position=\"absolute\"\n        top={0} left={0} right={0} bottom={0}\n        background={`linear-gradient(45deg, rgba(255,255,255,0.05), rgba(255,255,255,0.15), rgba(255,255,255,0.05))`}\n      />\n\n      {/* --- Entity stack (absolute positioned layers, like ZStack) --- */}\n\n      {/* Sticker entity 1: rotated shape with nested containers */}\n      {this.renderStickerEntity(idx, 0, '10%', '10%', 0.8)}\n\n      {/* Sticker entity 2 */}\n      {this.renderStickerEntity(idx, 1, '55%', '5%', 0.7)}\n\n      {/* Sticker entity 3 */}\n      {this.renderStickerEntity(idx, 2, '5%', '45%', 0.9)}\n\n      {/* Sticker entity 4 */}\n      {this.renderStickerEntity(idx, 3, '60%', '40%', 0.6)}\n\n      {/* Sticker entity 5 */}\n      {this.renderStickerEntity(idx, 4, '30%', '65%', 0.75)}\n\n      {/* Caption entity: styled text with background, border, rotation */}\n      {this.renderCaptionEntity(idx)}\n\n      {/* Drawing entity: many stroke paths */}\n      {this.renderDrawingEntity(idx)}\n\n      {/* Filter overlay: semi-transparent gradient with text */}\n      {this.renderFilterOverlay(idx)}\n\n      {/* Bottom bar: nested flex layout with 8 items */}\n      {this.renderBottomBar(idx)}\n\n      {/* Additional nested clipping regions */}\n      {this.renderClippingRegions(idx)}\n    </view>;\n  }\n\n  private renderStickerEntity(\n    idx: number, variant: number,\n    leftPos: string, topPos: string, scaleFactor: number,\n  ): void {\n    const rotation = (Math.PI / 6) * Math.sin((idx + variant * 20) * 0.05);\n    const scale = scaleFactor + 0.1 * Math.sin(idx * 0.1 + variant);\n    const size = 25 + variant * 3;\n    const path = makeAnimatedPath(idx, variant);\n    const hue = (idx * 11 + variant * 73) % 360;\n\n    <view\n      position=\"absolute\"\n      left={leftPos}\n      top={topPos}\n      rotation={rotation}\n      scaleX={scale}\n      scaleY={scale}\n    >\n      {/* Level 1: outer container */}\n      <view\n        width={`${size}%`}\n        aspectRatio={1}\n        backgroundColor={hsla(hue, 60, 50, 0.3)}\n        borderRadius={12 * ds}\n        padding={4 * ds}\n      >\n        {/* Level 2: inner container */}\n        <view\n          width=\"100%\"\n          height=\"100%\"\n          backgroundColor={hsla((hue + 120) % 360, 50, 60, 0.4)}\n          borderRadius={8 * ds}\n          alignItems=\"center\"\n          justifyContent=\"center\"\n          slowClipping\n        >\n          {/* Level 3: shape content */}\n          <shape\n            width=\"80%\"\n            aspectRatio={1}\n            strokeColor={hsla((hue + 240) % 360, 80, 70, 0.9)}\n            strokeWidth={(3 + variant) * ds}\n            strokeCap=\"round\"\n            path={path}\n          />\n          <view\n            position=\"absolute\"\n            width=\"60%\"\n            aspectRatio={1}\n            backgroundColor={hsla((hue + 60) % 360, 70, 50, 0.25)}\n            borderRadius={'50%'}\n            slowClipping\n          />\n        </view>\n      </view>\n    </view>;\n  }\n\n  private renderCaptionEntity(idx: number): void {\n    const rotation = Math.PI / 24 * Math.sin(idx * 0.08);\n    const hue = (idx * 4 + 200) % 360;\n\n    <view\n      position=\"absolute\"\n      left=\"10%\"\n      right=\"10%\"\n      top=\"30%\"\n      rotation={rotation}\n    >\n      <view\n        backgroundColor={hsla(hue, 40, 15, 0.75)}\n        borderRadius={16 * ds}\n        padding={12 * ds}\n        alignItems=\"center\"\n      >\n        <view\n          width=\"100%\"\n          borderRadius={12 * ds}\n          padding={8 * ds}\n          backgroundColor={hsla(hue, 30, 20, 0.5)}\n        >\n          <label\n            font={titleFont}\n            color={hsla((hue + 180) % 360, 80, 80, 1)}\n            value={`Caption #${idx}`}\n          />\n          <label\n            font={bodyFont}\n            color=\"rgba(255,255,255,0.7)\"\n            value={`Frame ${idx} | ${new Date().toISOString().slice(11, 19)}`}\n            numberOfLines={2}\n          />\n        </view>\n      </view>\n    </view>;\n  }\n\n  private renderDrawingEntity(idx: number): void {\n    const NUM_STROKES = 20;\n\n    <view\n      position=\"absolute\"\n      top=\"15%\"\n      left=\"5%\"\n      right=\"5%\"\n      height=\"70%\"\n    >\n      {Array.from({ length: NUM_STROKES }, (_, i) => {\n        const strokePath = makeStrokePath(idx, i);\n        const color = STROKE_COLORS[i % STROKE_COLORS.length];\n        const width = (2 + (i % 5) * 1.5) * ds;\n        const cap = STROKE_CAPS[i % STROKE_CAPS.length];\n\n        <shape\n          position=\"absolute\"\n          width=\"100%\"\n          height=\"100%\"\n          strokeColor={color}\n          strokeWidth={width}\n          strokeCap={cap}\n          path={strokePath}\n          opacity={0.4 + 0.3 * Math.sin(idx * 0.1 + i)}\n        />;\n      })}\n    </view>;\n  }\n\n  private renderFilterOverlay(idx: number): void {\n    const hue = (idx * 3 + 100) % 360;\n\n    <view\n      position=\"absolute\"\n      top={0} left={0} right={0} bottom={0}\n      background={`linear-gradient(180deg, ${hsla(hue, 50, 50, 0.1)}, ${hsla((hue + 180) % 360, 50, 30, 0.15)})`}\n    >\n      <view\n        position=\"absolute\"\n        bottom=\"15%\"\n        left=\"5%\"\n        right=\"5%\"\n        alignItems=\"center\"\n      >\n        <label\n          font={smallFont}\n          color=\"rgba(255,255,255,0.5)\"\n          value={`Filter: Vivid #${idx % 12}`}\n        />\n      </view>\n    </view>;\n  }\n\n  private renderBottomBar(idx: number): void {\n    const barHue = (idx * 5) % 360;\n\n    <view\n      position=\"absolute\"\n      bottom={10 * ds}\n      left={8 * ds}\n      right={8 * ds}\n      height={48 * ds}\n      flexDirection=\"row\"\n      borderRadius={12 * ds}\n      background={`linear-gradient(90deg, ${hsla(barHue, 30, 15, 0.8)}, ${hsla((barHue + 60) % 360, 30, 20, 0.8)})`}\n      padding={4 * ds}\n      slowClipping\n    >\n      {Array.from({ length: 8 }, (_, i) => {\n        const itemHue = (barHue + i * 40) % 360;\n        <view\n          flexGrow={1}\n          marginLeft={i > 0 ? 3 * ds : 0}\n          backgroundColor={hsla(itemHue, 50, 50 + (idx + i) % 20, 0.7)}\n          borderRadius={6 * ds}\n          alignItems=\"center\"\n          justifyContent=\"center\"\n        >\n          <label\n            font={tinyFont}\n            color=\"white\"\n            value={`${i + 1}`}\n          />\n        </view>;\n      })}\n    </view>;\n  }\n\n  private renderClippingRegions(idx: number): void {\n    const hue1 = (idx * 7 + 30) % 360;\n    const hue2 = (idx * 7 + 150) % 360;\n\n    {/* Clipping region 1 */}\n    <view\n      position=\"absolute\"\n      right=\"5%\"\n      top=\"8%\"\n      width=\"18%\"\n      aspectRatio={1}\n      slowClipping\n      borderRadius={'50%'}\n      backgroundColor={hsla(hue1, 60, 50, 0.3)}\n    >\n      <view\n        width=\"100%\"\n        height=\"100%\"\n        background={`linear-gradient(135deg, ${hsla(hue1, 70, 60, 0.6)}, ${hsla(hue1, 70, 30, 0.6)})`}\n        alignItems=\"center\"\n        justifyContent=\"center\"\n      >\n        <label font={smallFont} color=\"white\" value={`${idx}`} />\n      </view>\n    </view>;\n\n    {/* Clipping region 2 */}\n    <view\n      position=\"absolute\"\n      left=\"3%\"\n      bottom=\"18%\"\n      width=\"15%\"\n      aspectRatio={1.5}\n      slowClipping\n      borderRadius={10 * ds}\n      backgroundColor={hsla(hue2, 50, 40, 0.3)}\n    >\n      <view\n        width=\"100%\"\n        height=\"100%\"\n        flexDirection=\"column\"\n      >\n        <view flexGrow={1} backgroundColor={hsla(hue2, 60, 60, 0.4)} />\n        <view flexGrow={1} backgroundColor={hsla((hue2 + 90) % 360, 60, 60, 0.4)} />\n      </view>\n    </view>;\n\n    {/* Clipping region 3: nested circles */}\n    <view\n      position=\"absolute\"\n      right=\"8%\"\n      bottom=\"25%\"\n      width=\"12%\"\n      aspectRatio={1}\n      slowClipping\n      borderRadius={'50%'}\n      backgroundColor={hsla((hue1 + 90) % 360, 50, 50, 0.25)}\n    >\n      <view\n        width=\"100%\"\n        height=\"100%\"\n        alignItems=\"center\"\n        justifyContent=\"center\"\n      >\n        <view\n          width=\"60%\"\n          aspectRatio={1}\n          slowClipping\n          borderRadius={'50%'}\n          backgroundColor={hsla((hue1 + 180) % 360, 60, 60, 0.4)}\n        />\n      </view>\n    </view>;\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Stats helpers\n// ---------------------------------------------------------------------------\n\ninterface PhaseStats {\n  name: string;\n  min: number;\n  max: number;\n  avg: number;\n  p50: number;\n  p95: number;\n  total: number;\n}\n\nfunction computeStats(name: string, values: number[]): PhaseStats {\n  if (values.length === 0) {\n    return { name, min: 0, max: 0, avg: 0, p50: 0, p95: 0, total: 0 };\n  }\n  const sorted = [...values].sort((a, b) => a - b);\n  const total = sorted.reduce((s, v) => s + v, 0);\n  const avg = total / sorted.length;\n  const p50 = sorted[Math.floor(sorted.length * 0.5)];\n  const p95 = sorted[Math.floor(sorted.length * 0.95)];\n  return {\n    name,\n    min: sorted[0],\n    max: sorted[sorted.length - 1],\n    avg,\n    p50,\n    p95,\n    total,\n  };\n}\n\nfunction formatMs(ms: number): string {\n  return ms.toFixed(2);\n}\n\nfunction statsBlock(s: PhaseStats): string {\n  const f = formatMs;\n  return [\n    `[${s.name}]`,\n    `  avg ${f(s.avg)}  p50 ${f(s.p50)}  p95 ${f(s.p95)}`,\n    `  min ${f(s.min)}  max ${f(s.max)}  tot ${f(s.total)}`,\n  ].join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Benchmark page\n// ---------------------------------------------------------------------------\n\nconst FRAME_COUNTS = [30, 60, 120];\nconst BENCHMARK_WIDTH = 1080;\nconst BENCHMARK_HEIGHT = 1920;\n\ninterface FrameTiming {\n  render: number;\n  layout: number;\n  drawTotal: number;\n  drawMainThread: number;\n  drawOverhead: number;\n  raster: number;\n  jsThread: number;\n  mainThread: number;\n  total: number;\n}\n\ninterface State {\n  frameCountIndex: number;\n  running: boolean;\n  resultText: string;\n}\n\nexport interface ViewModel {}\nexport interface ComponentContext {}\n\n@NavigationPage(module)\nexport class DrawFrameBenchmark extends NavigationPageStatefulComponent<ViewModel, ComponentContext> {\n  state: State = {\n    frameCountIndex: 1, // default 60\n    running: false,\n    resultText: 'Tap \"Run Benchmark\" to start.',\n  };\n\n  onRender(): void {\n    const frameCount = FRAME_COUNTS[this.state.frameCountIndex];\n    <view backgroundColor=\"white\" width=\"100%\" height=\"100%\">\n      <scroll style={styles.scroll} padding={16}>\n        <layout flexDirection=\"column\" width=\"100%\">\n          <label\n            style={styles.title}\n            value=\"DrawFrame Benchmark\"\n            font={systemBoldFont(20)}\n          />\n\n          <layout flexDirection=\"row\" marginTop={12} marginBottom={12}>\n            <view\n              backgroundColor=\"cornflowerblue\"\n              padding={12}\n              borderRadius={12}\n              marginRight={8}\n              onTap={this.cycleFrameCount}\n            >\n              <label value={`Frames: ${frameCount}`} font={systemBoldFont(14)} color=\"white\" />\n            </view>\n\n            <view\n              backgroundColor={this.state.running ? 'gray' : 'green'}\n              padding={12}\n              borderRadius={12}\n              onTap={this.state.running ? undefined : this.runBenchmark}\n            >\n              <label\n                value={this.state.running ? 'Running...' : 'Run Benchmark'}\n                font={systemBoldFont(14)}\n                color=\"white\"\n              />\n            </view>\n          </layout>\n\n          <label\n            value={this.state.resultText}\n            font={monoSpaceFont(8)}\n            color=\"black\"\n            numberOfLines={0}\n          />\n        </layout>\n      </scroll>\n    </view>;\n  }\n\n  private cycleFrameCount = (): void => {\n    if (this.state.running) return;\n    this.setState({\n      frameCountIndex: (this.state.frameCountIndex + 1) % FRAME_COUNTS.length,\n    });\n  };\n\n  private runBenchmark = (): void => {\n    this.setState({ running: true, resultText: 'Starting benchmark...\\n' });\n    setTimeoutInterruptible(() => {\n      void this.executeBenchmark();\n    });\n  };\n\n  private async executeBenchmark(): Promise<void> {\n    const frameCount = FRAME_COUNTS[this.state.frameCountIndex];\n    const width = BENCHMARK_WIDTH;\n    const height = BENCHMARK_HEIGHT;\n    const bytesPerPixel = 4;\n\n    const context: IManagedContext = createManagedContext();\n    const bitmap: IBitmap = createBitmap({\n      width,\n      height,\n      colorType: BitmapColorType.RGBA8888,\n      alphaType: BitmapAlphaType.OPAQUE,\n      rowBytes: width * bytesPerPixel,\n    });\n\n    const timings: FrameTiming[] = [];\n\n    const overallSw = Stopwatch.createAndStart();\n\n    for (let i = 0; i < frameCount; i++) {\n      const frameSw = Stopwatch.createAndStart();\n\n      // -- Render phase (JS thread) --\n      const renderSw = Stopwatch.createAndStart();\n      context.render(() => {\n        <ComplexBenchmarkScene frameIndex={i} />;\n      });\n      const renderMs = renderSw.elapsedMs();\n\n      // -- Layout phase (async: JS -> main thread -> callback) --\n      const layoutSw = Stopwatch.createAndStart();\n      await context.layout(width, height, false);\n      const layoutMs = layoutSw.elapsedMs();\n\n      // -- Draw phase (async: JS -> main thread -> callback) --\n      const drawSw = Stopwatch.createAndStart();\n      const { frame, mainThreadMs } = await context.draw();\n      const drawTotalMs = drawSw.elapsedMs();\n      const drawOverheadMs = Math.max(0, drawTotalMs - mainThreadMs);\n\n      // -- Raster phase (JS thread) --\n      const rasterSw = Stopwatch.createAndStart();\n      frame.rasterInto(bitmap, true);\n      const rasterMs = rasterSw.elapsedMs();\n\n      frame.dispose();\n\n      const totalMs = frameSw.elapsedMs();\n\n      // JS thread = render + layout + raster + draw overhead (scheduling)\n      const jsThreadMs = renderMs + layoutMs + rasterMs + drawOverheadMs;\n\n      timings.push({\n        render: renderMs,\n        layout: layoutMs,\n        drawTotal: drawTotalMs,\n        drawMainThread: mainThreadMs,\n        drawOverhead: drawOverheadMs,\n        raster: rasterMs,\n        jsThread: jsThreadMs,\n        mainThread: mainThreadMs,\n        total: totalMs,\n      });\n\n      if (i % 10 === 0 || i === frameCount - 1) {\n        console.log(\n          `[Benchmark] #${i}/${frameCount}: ` +\n          `js=${formatMs(jsThreadMs)} main=${formatMs(mainThreadMs)} total=${formatMs(totalMs)}`,\n        );\n      }\n    }\n\n    const overallMs = overallSw.elapsedMs();\n\n    bitmap.dispose();\n    context.dispose();\n\n    // Compute aggregate stats per phase\n    const renderStats = computeStats('Render(JS)', timings.map(t => t.render));\n    const layoutStats = computeStats('Layout(JS)', timings.map(t => t.layout));\n    const drawTotalStats = computeStats('Draw total', timings.map(t => t.drawTotal));\n    const drawMainStats = computeStats('Draw(main)', timings.map(t => t.drawMainThread));\n    const drawOhStats = computeStats('Draw sched', timings.map(t => t.drawOverhead));\n    const rasterStats = computeStats('Raster(JS)', timings.map(t => t.raster));\n    const jsStats = computeStats('JS thread', timings.map(t => t.jsThread));\n    const mainStats = computeStats('Main thrd', timings.map(t => t.mainThread));\n    const totalStats = computeStats('Frame tot', timings.map(t => t.total));\n\n    const fps = frameCount / (overallMs / 1000);\n\n    const f = formatMs;\n    const lines = [\n      `DrawFrame Benchmark (complex scene)`,\n      `${frameCount} frames @ ${width}x${height}`,\n      `${f(overallMs)}ms total | ~${fps.toFixed(1)} fps`,\n      ``,\n      `=== Thread summary (ms) ===`,\n      statsBlock(jsStats),\n      statsBlock(mainStats),\n      ``,\n      `=== Phase breakdown (ms) ===`,\n      statsBlock(renderStats),\n      statsBlock(layoutStats),\n      statsBlock(drawTotalStats),\n      statsBlock(drawMainStats),\n      statsBlock(drawOhStats),\n      statsBlock(rasterStats),\n      statsBlock(totalStats),\n      ``,\n      `=== Per frame (ms) ===`,\n      ` #  Rndr  Lyot DrTot DrMn DrOh Rstr  JS  Main Total`,\n    ];\n\n    for (let i = 0; i < frameCount; i++) {\n      const t = timings[i];\n      lines.push(\n        `${String(i).padStart(2)}` +\n        ` ${f(t.render).padStart(5)}` +\n        ` ${f(t.layout).padStart(5)}` +\n        ` ${f(t.drawTotal).padStart(5)}` +\n        ` ${f(t.drawMainThread).padStart(4)}` +\n        ` ${f(t.drawOverhead).padStart(4)}` +\n        ` ${f(t.raster).padStart(5)}` +\n        ` ${f(t.jsThread).padStart(4)}` +\n        ` ${f(t.mainThread).padStart(4)}` +\n        ` ${f(t.total).padStart(5)}`,\n      );\n    }\n\n    const resultText = lines.join('\\n');\n    console.log(resultText);\n\n    if (!this.isDestroyed()) {\n      this.setState({ running: false, resultText });\n    }\n  }\n}\n\nconst styles = {\n  scroll: new Style<ScrollView>({\n    alignItems: 'center',\n    height: '100%',\n  }),\n\n  title: new Style<Label>({\n    color: 'black',\n    accessibilityCategory: 'header',\n    width: '100%',\n  }),\n};\n\nfunction monoSpaceFont(size: number): string {\n  if (Device.isIOS()) {\n    return `Menlo ${size}`;\n  } else {\n    return `monospace ${size}`;\n  }\n}\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/MarshallingTest.tsx",
    "content": "// TS call native and record\n// - TS enter time (1)\n// - native enter time (2)\n// - native leave time (3)\n// - TS leave time (4)\n//\n// TS to native marshalling time = (2) - (1)\n// Native to TS marshalling time = (4) - (3)\n\nimport { NavigationPage } from 'valdi_navigation/src/NavigationPage';\nimport { NavigationPageStatefulComponent } from 'valdi_navigation/src/NavigationPageComponent';\nimport { Style } from 'valdi_core/src/Style';\nimport { Label, ScrollView } from 'valdi_tsx/src/NativeTemplateElements';\nimport { systemBoldFont, systemFont } from 'valdi_core/src/SystemFont';\nimport {\n  FunctionTiming,\n  measureStrings,\n  clearNativeFunctionTiming,\n  getNativeFunctionTiming,\n  measureStringMaps,\n} from './NativeHelper';\nimport { StringMap } from 'coreutils/src/StringMap';\nimport { setTimeoutInterruptible } from 'valdi_core/src/SetTimeout';\nimport { now } from './cpp';\n\ninterface Result {\n  avgJsToNative: number;\n  p10JsToNative: number;\n  p50JsToNative: number;\n  p90JsToNative: number;\n\n  avgNativeToJs: number;\n  p10NativeToJs: number;\n  p50NativeToJs: number;\n  p90NativeToJs: number;\n}\n\nfunction runTest(body: (data: any) => any, data: any, iterations: number) {\n  clearNativeFunctionTiming();\n  const jsTiming: FunctionTiming[] = [];\n  for (let i = 0; i < iterations; ++i) {\n    const jsEnter = now();\n    const ret = body(data);\n    const jsLeave = now();\n    jsTiming.push({ enterTime: jsEnter, leaveTime: jsLeave });\n  }\n  const nativeTiming = getNativeFunctionTiming();\n\n  const jsToNativeTimes: number[] = [];\n  const nativeToJsTimes: number[] = [];\n  for (let i = 0; i < iterations; ++i) {\n    jsToNativeTimes.push(nativeTiming[i].enterTime - jsTiming[i].enterTime);\n    nativeToJsTimes.push(jsTiming[i].leaveTime - nativeTiming[i].leaveTime);\n  }\n  jsToNativeTimes.sort((a, b) => a - b);\n  nativeToJsTimes.sort((a, b) => a - b);\n  return {\n    avgJsToNative: average(jsToNativeTimes),\n    p10JsToNative: pvalue(jsToNativeTimes, 10),\n    p50JsToNative: pvalue(jsToNativeTimes, 50),\n    p90JsToNative: pvalue(jsToNativeTimes, 90),\n\n    avgNativeToJs: average(nativeToJsTimes),\n    p10NativeToJs: pvalue(nativeToJsTimes, 10),\n    p50NativeToJs: pvalue(nativeToJsTimes, 50),\n    p90NativeToJs: pvalue(nativeToJsTimes, 90),\n  };\n}\n\nfunction pvalue(times: number[], p: number): number {\n  if (times.length === 0 || p < 0 || p > 100) {\n    throw new Error('Invalid input');\n  }\n  const rank = (p / 100) * (times.length - 1);\n  const lower = Math.floor(rank);\n  const upper = Math.ceil(rank);\n  if (lower === upper) {\n    return times[lower];\n  } else {\n    // Linear interpolation between closest ranks\n    const weight = rank - lower;\n    return times[lower] * (1 - weight) + times[upper] * weight;\n  }\n}\n\nfunction average(numbers: number[]): number {\n  if (numbers.length === 0) {\n    throw new Error('Cannot compute average of an empty array');\n  }\n  const sum = numbers.reduce((acc, value) => acc + value, 0);\n  return sum / numbers.length;\n}\n\nconst allTests = [\n  {\n    name: 'Small Strings',\n    func: measureStrings,\n    data: Array.from({ length: 1000 }, () => 'Hello'),\n    iterations: 100,\n  },\n  {\n    name: 'Large Strings',\n    func: measureStrings,\n    data: Array.from({ length: 1000 }, () => 'Hello'.repeat(1000)),\n    iterations: 100,\n  },\n  {\n    name: 'String Maps',\n    func: measureStringMaps,\n    data: Array.from({ length: 2500 }, () =>\n      Object.fromEntries(Array.from({ length: 20 }, (_, i) => [`key${i}`, `$value${i}`])),\n    ),\n    iterations: 10,\n  },\n] as const;\n\nexport interface ViewModel {}\nexport interface ComponentContext {}\n\ninterface State {\n  results: Result[];\n}\n\n@NavigationPage(module)\nexport class MarshallingTest extends NavigationPageStatefulComponent<ViewModel, ComponentContext> {\n  state: State = {\n    results: [],\n  };\n\n  onCreate() {\n    setTimeoutInterruptible(() => {\n      const results: Result[] = [];\n      for (const t of allTests) {\n        results.push(runTest(t.func, t.data, t.iterations));\n        this.setState({ results: [...results] });\n      }\n    });\n  }\n\n  onRender(): void {\n    <view backgroundColor=\"white\">\n      <scroll style={styles.scroll} padding={16}>\n        <layout flexDirection=\"column\">\n          <label style={styles.title} value={`Marshalling Benchmark!`} font={systemFont(20)} />\n          {this.renderResults()}\n        </layout>\n      </scroll>\n    </view>;\n  }\n\n  private renderResults() {\n    for (let i = 0; i < this.state.results.length; i++) {\n      <label marginTop={15} value={allTests[i].name} font={systemBoldFont(12)} />;\n      const r = this.state.results[i];\n      const jsToNative = `JS=> Avg: ${r.avgJsToNative.toFixed(2)} P10: ${r.p10JsToNative.toFixed(2)} P50 ${r.p50JsToNative.toFixed(2)} P90 ${r.p90JsToNative.toFixed(2)}`;\n      <label value={jsToNative} font={systemFont(10)} />;\n      const nativeToJs = `=>JS Avg: ${r.avgNativeToJs.toFixed(2)} P10: ${r.p10NativeToJs.toFixed(2)} P50 ${r.p50NativeToJs.toFixed(2)} P90 ${r.p90NativeToJs.toFixed(2)}`;\n      <label value={nativeToJs} font={systemFont(10)} />;\n    }\n  }\n}\n\nconst styles = {\n  scroll: new Style<ScrollView>({\n    alignItems: 'center',\n    height: '100%',\n  }),\n\n  title: new Style<Label>({\n    color: 'black',\n    accessibilityCategory: 'header',\n    width: '100%',\n  }),\n};\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/MicroBenchTest.tsx",
    "content": "import { NavigationPage } from 'valdi_navigation/src/NavigationPage';\nimport { NavigationPageStatefulComponent } from 'valdi_navigation/src/NavigationPageComponent';\nimport { Style } from 'valdi_core/src/Style';\nimport { Label, ScrollView } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Device } from 'valdi_core/src/Device';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { setTimeoutInterruptible } from 'valdi_core/src/SetTimeout';\n\nimport { RequireFunc } from 'valdi_core/src/IModuleLoader';\ndeclare const require: RequireFunc;\nconst microbench = require('./microbench');\n\nexport interface ViewModel {}\nexport interface ComponentContext {}\n\n@NavigationPage(module)\nexport class MicroBenchTest extends NavigationPageStatefulComponent<ViewModel, ComponentContext> {\n  state = {\n    text: '',\n  };\n\n  onCreate() {\n    setTimeoutInterruptible(() => {\n      this.setState({ text: '' });\n      const self = this;\n      microbench.setConsole({\n        log(s: string) {\n          console.log(s);\n          const text = self.state.text + '\\n' + s;\n          self.setState({ text: text });\n        },\n      });\n      const args = ['microbench'];\n      microbench.main(args.length, args, globalThis);\n    });\n  }\n\n  onRender(): void {\n    <view backgroundColor=\"white\">\n      <scroll style={styles.scroll} padding={16}>\n        <layout flexDirection=\"column\">\n          <label style={styles.title} value={`QuickJS MicroBench!`} font={systemFont(20)} />\n          <label marginTop={20} value={this.state.text} font={monoSpaceFont(10)} numberOfLines={0} />\n        </layout>\n      </scroll>\n    </view>;\n  }\n}\n\nconst styles = {\n  scroll: new Style<ScrollView>({\n    alignItems: 'center',\n    height: '100%',\n  }),\n\n  title: new Style<Label>({\n    color: 'black',\n    accessibilityCategory: 'header',\n    width: '100%',\n  }),\n};\n\nfunction monoSpaceFont(size: number): string {\n  if (Device.isIOS()) {\n    return `Menlo ${size}`;\n    // } else if (Device.isAndroid()) {\n    //   return `Roboto Mono ${size}`;\n  } else {\n    return `monospace ${size}`;\n  }\n}\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/NativeHelper.d.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\n\n/**\n * @ExportModule\n */\n\n// @ExportModel\nexport interface FunctionTiming {\n  // milliseoncs since epoch in doubles\n  enterTime: number;\n  leaveTime: number;\n}\n\n// @ExportFunction\nexport function measureStrings(data: string[]): string[];\n// @ExportFunction\nexport function measureStringMaps(data: StringMap<unknown>[]): StringMap<unknown>[];\n\n// @ExportFunction\nexport function clearNativeFunctionTiming(): void;\n\n// @ExportFunction\nexport function getNativeFunctionTiming(): FunctionTiming[];\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/ProtoImportTest.tsx",
    "content": "import { NavigationPage } from 'valdi_navigation/src/NavigationPage';\nimport { NavigationPageStatefulComponent } from 'valdi_navigation/src/NavigationPageComponent';\nimport { Style } from 'valdi_core/src/Style';\nimport { Label } from 'valdi_tsx/src/NativeTemplateElements';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { now } from './cpp';\n\nimport { load } from 'valdi_protobuf/src/ProtobufBuilder';\n\nexport function runProtoImport(src: string): number {\n  const start = now();\n  load(src);\n  const end = now();\n  return end - start;\n}\n\nexport interface ViewModel {}\nexport interface ComponentContext {}\n\ninterface State {\n  importLatency: number;\n  importLatencyNoIndex: number;\n}\n\n@NavigationPage(module)\nexport class ProtoImportTest extends NavigationPageStatefulComponent<ViewModel, ComponentContext> {\n  state: State = {\n    importLatency: 0,\n    importLatencyNoIndex: 0,\n  };\n\n  onCreate() {\n    const importLatency = runProtoImport('benchmark/src/proto.protodecl');\n    const importLatencyNoIndex = runProtoImport('benchmark/src/proto_noidx.protodecl');\n    this.setState({ importLatency: importLatency, importLatencyNoIndex: importLatencyNoIndex });\n  }\n\n  onRender(): void {\n    <view backgroundColor=\"white\" flexDirection=\"column\">\n      <label marginTop={20} style={styles.text} value=\"1000 messages and 200 enums imported in\"></label>\n      <label style={styles.text} value={`${this.state.importLatency.toFixed(2)} ms`} />\n      <label style={styles.text} value={`${this.state.importLatencyNoIndex.toFixed(2)} ms`} />\n    </view>;\n  }\n}\n\nconst styles = {\n  text: new Style<Label>({\n    font: systemFont(12),\n  }),\n};\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/RenderTest.tsx",
    "content": "import { NavigationPage } from 'valdi_navigation/src/NavigationPage';\nimport { NavigationPageStatefulComponent } from 'valdi_navigation/src/NavigationPageComponent';\nimport { Style } from 'valdi_core/src/Style';\nimport { Component } from 'valdi_core/src/Component';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { Label, ScrollView } from 'valdi_tsx/src/NativeTemplateElements';\nimport { BenchmarkRunner, BenchmarkSingleRunComponent } from './BenchmarkSingleRunComponent';\nimport { IComponent } from 'valdi_core/src/IComponent';\nimport { now } from './cpp';\n\nexport interface ViewModel {}\nexport interface ComponentContext {}\n\nclass TestPage extends Component {\n  onRender() {\n    <scroll height=\"100%\" width=\"100%\" backgroundColor=\"lightblue\">\n      {[...Array(1000).keys()].map(i => {\n        <label value={`Hello! ${i}`} />;\n      })}\n    </scroll>;\n  }\n}\n\n@NavigationPage(module)\nexport class RenderTest extends NavigationPageStatefulComponent<ViewModel, ComponentContext> {\n  state = {};\n\n  benchmarkRunner: BenchmarkRunner = {\n    start: () => {},\n    incrementRunCount: () => {},\n    measureAsync: (metricName: string) => {\n      const start = now();\n      return () => {\n        let newState: any = { ...this.state, [metricName]: (now() - start).toFixed(2) };\n        this.setState(newState);\n      };\n    },\n    stop: () => {\n      return {};\n    },\n  };\n\n  onRender(): void {\n    <view backgroundColor=\"white\" flexDirection=\"column\">\n      <BenchmarkSingleRunComponent\n        benchmarkRunner={this.benchmarkRunner}\n        onComplete={this.onComplete}\n        verifyCompleted={this.verifyCompleted}\n      >\n        <TestPage />;\n      </BenchmarkSingleRunComponent>\n      <label\n        style={styles.bottom}\n        value={`${Object.entries(this.state)\n          .map(([key, value]) => `${key}:${value}`)\n          .join(', ')} ms`}\n      />\n    </view>;\n  }\n\n  private verifyCompleted = (component: IComponent) => {\n    return !!component;\n  };\n\n  private onComplete = () => {};\n}\n\nconst styles = {\n  scroll: new Style<ScrollView>({\n    alignItems: 'center',\n    height: '100%',\n  }),\n\n  title: new Style<Label>({\n    color: 'black',\n    accessibilityCategory: 'header',\n    width: '100%',\n  }),\n\n  bottom: new Style<Label>({\n    marginTop: 'auto',\n    marginLeft: '40',\n    marginBottom: '10',\n    font: systemFont(9),\n    color: 'red',\n  }),\n};\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/complex_test.proto",
    "content": "// Auto-generated complex Protobuf schema for testing (no WKT imports; prefixed enum values)\n// Contains 200 enums and 1000 messages with cross references\nsyntax = \"proto3\";\npackage complex.test.v1;\n\nmessage LocalTimestamp {\n  int64 seconds = 1;  // Unix epoch seconds\n  int32 nanos = 2;    // Fractional seconds, 0-999,999,999\n}\n\nenum Enum0 {\n  // Values for Enum0 (prefixed to ensure package-level uniqueness)\n  Enum0_UNSPECIFIED = 0;\n  Enum0_ONE = 1;\n  Enum0_TWO = 2;\n  Enum0_THREE = 3;\n  Enum0_FOUR = 4;\n}\n\nenum Enum1 {\n  // Values for Enum1 (prefixed to ensure package-level uniqueness)\n  Enum1_UNSPECIFIED = 0;\n  Enum1_ONE = 1;\n  Enum1_TWO = 2;\n  Enum1_THREE = 3;\n  Enum1_FOUR = 4;\n}\n\nenum Enum2 {\n  // Values for Enum2 (prefixed to ensure package-level uniqueness)\n  Enum2_UNSPECIFIED = 0;\n  Enum2_ONE = 1;\n  Enum2_TWO = 2;\n  Enum2_THREE = 3;\n  Enum2_FOUR = 4;\n}\n\nenum Enum3 {\n  // Values for Enum3 (prefixed to ensure package-level uniqueness)\n  Enum3_UNSPECIFIED = 0;\n  Enum3_ONE = 1;\n  Enum3_TWO = 2;\n  Enum3_THREE = 3;\n  Enum3_FOUR = 4;\n}\n\nenum Enum4 {\n  // Values for Enum4 (prefixed to ensure package-level uniqueness)\n  Enum4_UNSPECIFIED = 0;\n  Enum4_ONE = 1;\n  Enum4_TWO = 2;\n  Enum4_THREE = 3;\n  Enum4_FOUR = 4;\n}\n\nenum Enum5 {\n  // Values for Enum5 (prefixed to ensure package-level uniqueness)\n  Enum5_UNSPECIFIED = 0;\n  Enum5_ONE = 1;\n  Enum5_TWO = 2;\n  Enum5_THREE = 3;\n  Enum5_FOUR = 4;\n}\n\nenum Enum6 {\n  // Values for Enum6 (prefixed to ensure package-level uniqueness)\n  Enum6_UNSPECIFIED = 0;\n  Enum6_ONE = 1;\n  Enum6_TWO = 2;\n  Enum6_THREE = 3;\n  Enum6_FOUR = 4;\n}\n\nenum Enum7 {\n  // Values for Enum7 (prefixed to ensure package-level uniqueness)\n  Enum7_UNSPECIFIED = 0;\n  Enum7_ONE = 1;\n  Enum7_TWO = 2;\n  Enum7_THREE = 3;\n  Enum7_FOUR = 4;\n}\n\nenum Enum8 {\n  // Values for Enum8 (prefixed to ensure package-level uniqueness)\n  Enum8_UNSPECIFIED = 0;\n  Enum8_ONE = 1;\n  Enum8_TWO = 2;\n  Enum8_THREE = 3;\n  Enum8_FOUR = 4;\n}\n\nenum Enum9 {\n  // Values for Enum9 (prefixed to ensure package-level uniqueness)\n  Enum9_UNSPECIFIED = 0;\n  Enum9_ONE = 1;\n  Enum9_TWO = 2;\n  Enum9_THREE = 3;\n  Enum9_FOUR = 4;\n}\n\nenum Enum10 {\n  // Values for Enum10 (prefixed to ensure package-level uniqueness)\n  Enum10_UNSPECIFIED = 0;\n  Enum10_ONE = 1;\n  Enum10_TWO = 2;\n  Enum10_THREE = 3;\n  Enum10_FOUR = 4;\n}\n\nenum Enum11 {\n  // Values for Enum11 (prefixed to ensure package-level uniqueness)\n  Enum11_UNSPECIFIED = 0;\n  Enum11_ONE = 1;\n  Enum11_TWO = 2;\n  Enum11_THREE = 3;\n  Enum11_FOUR = 4;\n}\n\nenum Enum12 {\n  // Values for Enum12 (prefixed to ensure package-level uniqueness)\n  Enum12_UNSPECIFIED = 0;\n  Enum12_ONE = 1;\n  Enum12_TWO = 2;\n  Enum12_THREE = 3;\n  Enum12_FOUR = 4;\n}\n\nenum Enum13 {\n  // Values for Enum13 (prefixed to ensure package-level uniqueness)\n  Enum13_UNSPECIFIED = 0;\n  Enum13_ONE = 1;\n  Enum13_TWO = 2;\n  Enum13_THREE = 3;\n  Enum13_FOUR = 4;\n}\n\nenum Enum14 {\n  // Values for Enum14 (prefixed to ensure package-level uniqueness)\n  Enum14_UNSPECIFIED = 0;\n  Enum14_ONE = 1;\n  Enum14_TWO = 2;\n  Enum14_THREE = 3;\n  Enum14_FOUR = 4;\n}\n\nenum Enum15 {\n  // Values for Enum15 (prefixed to ensure package-level uniqueness)\n  Enum15_UNSPECIFIED = 0;\n  Enum15_ONE = 1;\n  Enum15_TWO = 2;\n  Enum15_THREE = 3;\n  Enum15_FOUR = 4;\n}\n\nenum Enum16 {\n  // Values for Enum16 (prefixed to ensure package-level uniqueness)\n  Enum16_UNSPECIFIED = 0;\n  Enum16_ONE = 1;\n  Enum16_TWO = 2;\n  Enum16_THREE = 3;\n  Enum16_FOUR = 4;\n}\n\nenum Enum17 {\n  // Values for Enum17 (prefixed to ensure package-level uniqueness)\n  Enum17_UNSPECIFIED = 0;\n  Enum17_ONE = 1;\n  Enum17_TWO = 2;\n  Enum17_THREE = 3;\n  Enum17_FOUR = 4;\n}\n\nenum Enum18 {\n  // Values for Enum18 (prefixed to ensure package-level uniqueness)\n  Enum18_UNSPECIFIED = 0;\n  Enum18_ONE = 1;\n  Enum18_TWO = 2;\n  Enum18_THREE = 3;\n  Enum18_FOUR = 4;\n}\n\nenum Enum19 {\n  // Values for Enum19 (prefixed to ensure package-level uniqueness)\n  Enum19_UNSPECIFIED = 0;\n  Enum19_ONE = 1;\n  Enum19_TWO = 2;\n  Enum19_THREE = 3;\n  Enum19_FOUR = 4;\n}\n\nenum Enum20 {\n  // Values for Enum20 (prefixed to ensure package-level uniqueness)\n  Enum20_UNSPECIFIED = 0;\n  Enum20_ONE = 1;\n  Enum20_TWO = 2;\n  Enum20_THREE = 3;\n  Enum20_FOUR = 4;\n}\n\nenum Enum21 {\n  // Values for Enum21 (prefixed to ensure package-level uniqueness)\n  Enum21_UNSPECIFIED = 0;\n  Enum21_ONE = 1;\n  Enum21_TWO = 2;\n  Enum21_THREE = 3;\n  Enum21_FOUR = 4;\n}\n\nenum Enum22 {\n  // Values for Enum22 (prefixed to ensure package-level uniqueness)\n  Enum22_UNSPECIFIED = 0;\n  Enum22_ONE = 1;\n  Enum22_TWO = 2;\n  Enum22_THREE = 3;\n  Enum22_FOUR = 4;\n}\n\nenum Enum23 {\n  // Values for Enum23 (prefixed to ensure package-level uniqueness)\n  Enum23_UNSPECIFIED = 0;\n  Enum23_ONE = 1;\n  Enum23_TWO = 2;\n  Enum23_THREE = 3;\n  Enum23_FOUR = 4;\n}\n\nenum Enum24 {\n  // Values for Enum24 (prefixed to ensure package-level uniqueness)\n  Enum24_UNSPECIFIED = 0;\n  Enum24_ONE = 1;\n  Enum24_TWO = 2;\n  Enum24_THREE = 3;\n  Enum24_FOUR = 4;\n}\n\nenum Enum25 {\n  // Values for Enum25 (prefixed to ensure package-level uniqueness)\n  Enum25_UNSPECIFIED = 0;\n  Enum25_ONE = 1;\n  Enum25_TWO = 2;\n  Enum25_THREE = 3;\n  Enum25_FOUR = 4;\n}\n\nenum Enum26 {\n  // Values for Enum26 (prefixed to ensure package-level uniqueness)\n  Enum26_UNSPECIFIED = 0;\n  Enum26_ONE = 1;\n  Enum26_TWO = 2;\n  Enum26_THREE = 3;\n  Enum26_FOUR = 4;\n}\n\nenum Enum27 {\n  // Values for Enum27 (prefixed to ensure package-level uniqueness)\n  Enum27_UNSPECIFIED = 0;\n  Enum27_ONE = 1;\n  Enum27_TWO = 2;\n  Enum27_THREE = 3;\n  Enum27_FOUR = 4;\n}\n\nenum Enum28 {\n  // Values for Enum28 (prefixed to ensure package-level uniqueness)\n  Enum28_UNSPECIFIED = 0;\n  Enum28_ONE = 1;\n  Enum28_TWO = 2;\n  Enum28_THREE = 3;\n  Enum28_FOUR = 4;\n}\n\nenum Enum29 {\n  // Values for Enum29 (prefixed to ensure package-level uniqueness)\n  Enum29_UNSPECIFIED = 0;\n  Enum29_ONE = 1;\n  Enum29_TWO = 2;\n  Enum29_THREE = 3;\n  Enum29_FOUR = 4;\n}\n\nenum Enum30 {\n  // Values for Enum30 (prefixed to ensure package-level uniqueness)\n  Enum30_UNSPECIFIED = 0;\n  Enum30_ONE = 1;\n  Enum30_TWO = 2;\n  Enum30_THREE = 3;\n  Enum30_FOUR = 4;\n}\n\nenum Enum31 {\n  // Values for Enum31 (prefixed to ensure package-level uniqueness)\n  Enum31_UNSPECIFIED = 0;\n  Enum31_ONE = 1;\n  Enum31_TWO = 2;\n  Enum31_THREE = 3;\n  Enum31_FOUR = 4;\n}\n\nenum Enum32 {\n  // Values for Enum32 (prefixed to ensure package-level uniqueness)\n  Enum32_UNSPECIFIED = 0;\n  Enum32_ONE = 1;\n  Enum32_TWO = 2;\n  Enum32_THREE = 3;\n  Enum32_FOUR = 4;\n}\n\nenum Enum33 {\n  // Values for Enum33 (prefixed to ensure package-level uniqueness)\n  Enum33_UNSPECIFIED = 0;\n  Enum33_ONE = 1;\n  Enum33_TWO = 2;\n  Enum33_THREE = 3;\n  Enum33_FOUR = 4;\n}\n\nenum Enum34 {\n  // Values for Enum34 (prefixed to ensure package-level uniqueness)\n  Enum34_UNSPECIFIED = 0;\n  Enum34_ONE = 1;\n  Enum34_TWO = 2;\n  Enum34_THREE = 3;\n  Enum34_FOUR = 4;\n}\n\nenum Enum35 {\n  // Values for Enum35 (prefixed to ensure package-level uniqueness)\n  Enum35_UNSPECIFIED = 0;\n  Enum35_ONE = 1;\n  Enum35_TWO = 2;\n  Enum35_THREE = 3;\n  Enum35_FOUR = 4;\n}\n\nenum Enum36 {\n  // Values for Enum36 (prefixed to ensure package-level uniqueness)\n  Enum36_UNSPECIFIED = 0;\n  Enum36_ONE = 1;\n  Enum36_TWO = 2;\n  Enum36_THREE = 3;\n  Enum36_FOUR = 4;\n}\n\nenum Enum37 {\n  // Values for Enum37 (prefixed to ensure package-level uniqueness)\n  Enum37_UNSPECIFIED = 0;\n  Enum37_ONE = 1;\n  Enum37_TWO = 2;\n  Enum37_THREE = 3;\n  Enum37_FOUR = 4;\n}\n\nenum Enum38 {\n  // Values for Enum38 (prefixed to ensure package-level uniqueness)\n  Enum38_UNSPECIFIED = 0;\n  Enum38_ONE = 1;\n  Enum38_TWO = 2;\n  Enum38_THREE = 3;\n  Enum38_FOUR = 4;\n}\n\nenum Enum39 {\n  // Values for Enum39 (prefixed to ensure package-level uniqueness)\n  Enum39_UNSPECIFIED = 0;\n  Enum39_ONE = 1;\n  Enum39_TWO = 2;\n  Enum39_THREE = 3;\n  Enum39_FOUR = 4;\n}\n\nenum Enum40 {\n  // Values for Enum40 (prefixed to ensure package-level uniqueness)\n  Enum40_UNSPECIFIED = 0;\n  Enum40_ONE = 1;\n  Enum40_TWO = 2;\n  Enum40_THREE = 3;\n  Enum40_FOUR = 4;\n}\n\nenum Enum41 {\n  // Values for Enum41 (prefixed to ensure package-level uniqueness)\n  Enum41_UNSPECIFIED = 0;\n  Enum41_ONE = 1;\n  Enum41_TWO = 2;\n  Enum41_THREE = 3;\n  Enum41_FOUR = 4;\n}\n\nenum Enum42 {\n  // Values for Enum42 (prefixed to ensure package-level uniqueness)\n  Enum42_UNSPECIFIED = 0;\n  Enum42_ONE = 1;\n  Enum42_TWO = 2;\n  Enum42_THREE = 3;\n  Enum42_FOUR = 4;\n}\n\nenum Enum43 {\n  // Values for Enum43 (prefixed to ensure package-level uniqueness)\n  Enum43_UNSPECIFIED = 0;\n  Enum43_ONE = 1;\n  Enum43_TWO = 2;\n  Enum43_THREE = 3;\n  Enum43_FOUR = 4;\n}\n\nenum Enum44 {\n  // Values for Enum44 (prefixed to ensure package-level uniqueness)\n  Enum44_UNSPECIFIED = 0;\n  Enum44_ONE = 1;\n  Enum44_TWO = 2;\n  Enum44_THREE = 3;\n  Enum44_FOUR = 4;\n}\n\nenum Enum45 {\n  // Values for Enum45 (prefixed to ensure package-level uniqueness)\n  Enum45_UNSPECIFIED = 0;\n  Enum45_ONE = 1;\n  Enum45_TWO = 2;\n  Enum45_THREE = 3;\n  Enum45_FOUR = 4;\n}\n\nenum Enum46 {\n  // Values for Enum46 (prefixed to ensure package-level uniqueness)\n  Enum46_UNSPECIFIED = 0;\n  Enum46_ONE = 1;\n  Enum46_TWO = 2;\n  Enum46_THREE = 3;\n  Enum46_FOUR = 4;\n}\n\nenum Enum47 {\n  // Values for Enum47 (prefixed to ensure package-level uniqueness)\n  Enum47_UNSPECIFIED = 0;\n  Enum47_ONE = 1;\n  Enum47_TWO = 2;\n  Enum47_THREE = 3;\n  Enum47_FOUR = 4;\n}\n\nenum Enum48 {\n  // Values for Enum48 (prefixed to ensure package-level uniqueness)\n  Enum48_UNSPECIFIED = 0;\n  Enum48_ONE = 1;\n  Enum48_TWO = 2;\n  Enum48_THREE = 3;\n  Enum48_FOUR = 4;\n}\n\nenum Enum49 {\n  // Values for Enum49 (prefixed to ensure package-level uniqueness)\n  Enum49_UNSPECIFIED = 0;\n  Enum49_ONE = 1;\n  Enum49_TWO = 2;\n  Enum49_THREE = 3;\n  Enum49_FOUR = 4;\n}\n\nenum Enum50 {\n  // Values for Enum50 (prefixed to ensure package-level uniqueness)\n  Enum50_UNSPECIFIED = 0;\n  Enum50_ONE = 1;\n  Enum50_TWO = 2;\n  Enum50_THREE = 3;\n  Enum50_FOUR = 4;\n}\n\nenum Enum51 {\n  // Values for Enum51 (prefixed to ensure package-level uniqueness)\n  Enum51_UNSPECIFIED = 0;\n  Enum51_ONE = 1;\n  Enum51_TWO = 2;\n  Enum51_THREE = 3;\n  Enum51_FOUR = 4;\n}\n\nenum Enum52 {\n  // Values for Enum52 (prefixed to ensure package-level uniqueness)\n  Enum52_UNSPECIFIED = 0;\n  Enum52_ONE = 1;\n  Enum52_TWO = 2;\n  Enum52_THREE = 3;\n  Enum52_FOUR = 4;\n}\n\nenum Enum53 {\n  // Values for Enum53 (prefixed to ensure package-level uniqueness)\n  Enum53_UNSPECIFIED = 0;\n  Enum53_ONE = 1;\n  Enum53_TWO = 2;\n  Enum53_THREE = 3;\n  Enum53_FOUR = 4;\n}\n\nenum Enum54 {\n  // Values for Enum54 (prefixed to ensure package-level uniqueness)\n  Enum54_UNSPECIFIED = 0;\n  Enum54_ONE = 1;\n  Enum54_TWO = 2;\n  Enum54_THREE = 3;\n  Enum54_FOUR = 4;\n}\n\nenum Enum55 {\n  // Values for Enum55 (prefixed to ensure package-level uniqueness)\n  Enum55_UNSPECIFIED = 0;\n  Enum55_ONE = 1;\n  Enum55_TWO = 2;\n  Enum55_THREE = 3;\n  Enum55_FOUR = 4;\n}\n\nenum Enum56 {\n  // Values for Enum56 (prefixed to ensure package-level uniqueness)\n  Enum56_UNSPECIFIED = 0;\n  Enum56_ONE = 1;\n  Enum56_TWO = 2;\n  Enum56_THREE = 3;\n  Enum56_FOUR = 4;\n}\n\nenum Enum57 {\n  // Values for Enum57 (prefixed to ensure package-level uniqueness)\n  Enum57_UNSPECIFIED = 0;\n  Enum57_ONE = 1;\n  Enum57_TWO = 2;\n  Enum57_THREE = 3;\n  Enum57_FOUR = 4;\n}\n\nenum Enum58 {\n  // Values for Enum58 (prefixed to ensure package-level uniqueness)\n  Enum58_UNSPECIFIED = 0;\n  Enum58_ONE = 1;\n  Enum58_TWO = 2;\n  Enum58_THREE = 3;\n  Enum58_FOUR = 4;\n}\n\nenum Enum59 {\n  // Values for Enum59 (prefixed to ensure package-level uniqueness)\n  Enum59_UNSPECIFIED = 0;\n  Enum59_ONE = 1;\n  Enum59_TWO = 2;\n  Enum59_THREE = 3;\n  Enum59_FOUR = 4;\n}\n\nenum Enum60 {\n  // Values for Enum60 (prefixed to ensure package-level uniqueness)\n  Enum60_UNSPECIFIED = 0;\n  Enum60_ONE = 1;\n  Enum60_TWO = 2;\n  Enum60_THREE = 3;\n  Enum60_FOUR = 4;\n}\n\nenum Enum61 {\n  // Values for Enum61 (prefixed to ensure package-level uniqueness)\n  Enum61_UNSPECIFIED = 0;\n  Enum61_ONE = 1;\n  Enum61_TWO = 2;\n  Enum61_THREE = 3;\n  Enum61_FOUR = 4;\n}\n\nenum Enum62 {\n  // Values for Enum62 (prefixed to ensure package-level uniqueness)\n  Enum62_UNSPECIFIED = 0;\n  Enum62_ONE = 1;\n  Enum62_TWO = 2;\n  Enum62_THREE = 3;\n  Enum62_FOUR = 4;\n}\n\nenum Enum63 {\n  // Values for Enum63 (prefixed to ensure package-level uniqueness)\n  Enum63_UNSPECIFIED = 0;\n  Enum63_ONE = 1;\n  Enum63_TWO = 2;\n  Enum63_THREE = 3;\n  Enum63_FOUR = 4;\n}\n\nenum Enum64 {\n  // Values for Enum64 (prefixed to ensure package-level uniqueness)\n  Enum64_UNSPECIFIED = 0;\n  Enum64_ONE = 1;\n  Enum64_TWO = 2;\n  Enum64_THREE = 3;\n  Enum64_FOUR = 4;\n}\n\nenum Enum65 {\n  // Values for Enum65 (prefixed to ensure package-level uniqueness)\n  Enum65_UNSPECIFIED = 0;\n  Enum65_ONE = 1;\n  Enum65_TWO = 2;\n  Enum65_THREE = 3;\n  Enum65_FOUR = 4;\n}\n\nenum Enum66 {\n  // Values for Enum66 (prefixed to ensure package-level uniqueness)\n  Enum66_UNSPECIFIED = 0;\n  Enum66_ONE = 1;\n  Enum66_TWO = 2;\n  Enum66_THREE = 3;\n  Enum66_FOUR = 4;\n}\n\nenum Enum67 {\n  // Values for Enum67 (prefixed to ensure package-level uniqueness)\n  Enum67_UNSPECIFIED = 0;\n  Enum67_ONE = 1;\n  Enum67_TWO = 2;\n  Enum67_THREE = 3;\n  Enum67_FOUR = 4;\n}\n\nenum Enum68 {\n  // Values for Enum68 (prefixed to ensure package-level uniqueness)\n  Enum68_UNSPECIFIED = 0;\n  Enum68_ONE = 1;\n  Enum68_TWO = 2;\n  Enum68_THREE = 3;\n  Enum68_FOUR = 4;\n}\n\nenum Enum69 {\n  // Values for Enum69 (prefixed to ensure package-level uniqueness)\n  Enum69_UNSPECIFIED = 0;\n  Enum69_ONE = 1;\n  Enum69_TWO = 2;\n  Enum69_THREE = 3;\n  Enum69_FOUR = 4;\n}\n\nenum Enum70 {\n  // Values for Enum70 (prefixed to ensure package-level uniqueness)\n  Enum70_UNSPECIFIED = 0;\n  Enum70_ONE = 1;\n  Enum70_TWO = 2;\n  Enum70_THREE = 3;\n  Enum70_FOUR = 4;\n}\n\nenum Enum71 {\n  // Values for Enum71 (prefixed to ensure package-level uniqueness)\n  Enum71_UNSPECIFIED = 0;\n  Enum71_ONE = 1;\n  Enum71_TWO = 2;\n  Enum71_THREE = 3;\n  Enum71_FOUR = 4;\n}\n\nenum Enum72 {\n  // Values for Enum72 (prefixed to ensure package-level uniqueness)\n  Enum72_UNSPECIFIED = 0;\n  Enum72_ONE = 1;\n  Enum72_TWO = 2;\n  Enum72_THREE = 3;\n  Enum72_FOUR = 4;\n}\n\nenum Enum73 {\n  // Values for Enum73 (prefixed to ensure package-level uniqueness)\n  Enum73_UNSPECIFIED = 0;\n  Enum73_ONE = 1;\n  Enum73_TWO = 2;\n  Enum73_THREE = 3;\n  Enum73_FOUR = 4;\n}\n\nenum Enum74 {\n  // Values for Enum74 (prefixed to ensure package-level uniqueness)\n  Enum74_UNSPECIFIED = 0;\n  Enum74_ONE = 1;\n  Enum74_TWO = 2;\n  Enum74_THREE = 3;\n  Enum74_FOUR = 4;\n}\n\nenum Enum75 {\n  // Values for Enum75 (prefixed to ensure package-level uniqueness)\n  Enum75_UNSPECIFIED = 0;\n  Enum75_ONE = 1;\n  Enum75_TWO = 2;\n  Enum75_THREE = 3;\n  Enum75_FOUR = 4;\n}\n\nenum Enum76 {\n  // Values for Enum76 (prefixed to ensure package-level uniqueness)\n  Enum76_UNSPECIFIED = 0;\n  Enum76_ONE = 1;\n  Enum76_TWO = 2;\n  Enum76_THREE = 3;\n  Enum76_FOUR = 4;\n}\n\nenum Enum77 {\n  // Values for Enum77 (prefixed to ensure package-level uniqueness)\n  Enum77_UNSPECIFIED = 0;\n  Enum77_ONE = 1;\n  Enum77_TWO = 2;\n  Enum77_THREE = 3;\n  Enum77_FOUR = 4;\n}\n\nenum Enum78 {\n  // Values for Enum78 (prefixed to ensure package-level uniqueness)\n  Enum78_UNSPECIFIED = 0;\n  Enum78_ONE = 1;\n  Enum78_TWO = 2;\n  Enum78_THREE = 3;\n  Enum78_FOUR = 4;\n}\n\nenum Enum79 {\n  // Values for Enum79 (prefixed to ensure package-level uniqueness)\n  Enum79_UNSPECIFIED = 0;\n  Enum79_ONE = 1;\n  Enum79_TWO = 2;\n  Enum79_THREE = 3;\n  Enum79_FOUR = 4;\n}\n\nenum Enum80 {\n  // Values for Enum80 (prefixed to ensure package-level uniqueness)\n  Enum80_UNSPECIFIED = 0;\n  Enum80_ONE = 1;\n  Enum80_TWO = 2;\n  Enum80_THREE = 3;\n  Enum80_FOUR = 4;\n}\n\nenum Enum81 {\n  // Values for Enum81 (prefixed to ensure package-level uniqueness)\n  Enum81_UNSPECIFIED = 0;\n  Enum81_ONE = 1;\n  Enum81_TWO = 2;\n  Enum81_THREE = 3;\n  Enum81_FOUR = 4;\n}\n\nenum Enum82 {\n  // Values for Enum82 (prefixed to ensure package-level uniqueness)\n  Enum82_UNSPECIFIED = 0;\n  Enum82_ONE = 1;\n  Enum82_TWO = 2;\n  Enum82_THREE = 3;\n  Enum82_FOUR = 4;\n}\n\nenum Enum83 {\n  // Values for Enum83 (prefixed to ensure package-level uniqueness)\n  Enum83_UNSPECIFIED = 0;\n  Enum83_ONE = 1;\n  Enum83_TWO = 2;\n  Enum83_THREE = 3;\n  Enum83_FOUR = 4;\n}\n\nenum Enum84 {\n  // Values for Enum84 (prefixed to ensure package-level uniqueness)\n  Enum84_UNSPECIFIED = 0;\n  Enum84_ONE = 1;\n  Enum84_TWO = 2;\n  Enum84_THREE = 3;\n  Enum84_FOUR = 4;\n}\n\nenum Enum85 {\n  // Values for Enum85 (prefixed to ensure package-level uniqueness)\n  Enum85_UNSPECIFIED = 0;\n  Enum85_ONE = 1;\n  Enum85_TWO = 2;\n  Enum85_THREE = 3;\n  Enum85_FOUR = 4;\n}\n\nenum Enum86 {\n  // Values for Enum86 (prefixed to ensure package-level uniqueness)\n  Enum86_UNSPECIFIED = 0;\n  Enum86_ONE = 1;\n  Enum86_TWO = 2;\n  Enum86_THREE = 3;\n  Enum86_FOUR = 4;\n}\n\nenum Enum87 {\n  // Values for Enum87 (prefixed to ensure package-level uniqueness)\n  Enum87_UNSPECIFIED = 0;\n  Enum87_ONE = 1;\n  Enum87_TWO = 2;\n  Enum87_THREE = 3;\n  Enum87_FOUR = 4;\n}\n\nenum Enum88 {\n  // Values for Enum88 (prefixed to ensure package-level uniqueness)\n  Enum88_UNSPECIFIED = 0;\n  Enum88_ONE = 1;\n  Enum88_TWO = 2;\n  Enum88_THREE = 3;\n  Enum88_FOUR = 4;\n}\n\nenum Enum89 {\n  // Values for Enum89 (prefixed to ensure package-level uniqueness)\n  Enum89_UNSPECIFIED = 0;\n  Enum89_ONE = 1;\n  Enum89_TWO = 2;\n  Enum89_THREE = 3;\n  Enum89_FOUR = 4;\n}\n\nenum Enum90 {\n  // Values for Enum90 (prefixed to ensure package-level uniqueness)\n  Enum90_UNSPECIFIED = 0;\n  Enum90_ONE = 1;\n  Enum90_TWO = 2;\n  Enum90_THREE = 3;\n  Enum90_FOUR = 4;\n}\n\nenum Enum91 {\n  // Values for Enum91 (prefixed to ensure package-level uniqueness)\n  Enum91_UNSPECIFIED = 0;\n  Enum91_ONE = 1;\n  Enum91_TWO = 2;\n  Enum91_THREE = 3;\n  Enum91_FOUR = 4;\n}\n\nenum Enum92 {\n  // Values for Enum92 (prefixed to ensure package-level uniqueness)\n  Enum92_UNSPECIFIED = 0;\n  Enum92_ONE = 1;\n  Enum92_TWO = 2;\n  Enum92_THREE = 3;\n  Enum92_FOUR = 4;\n}\n\nenum Enum93 {\n  // Values for Enum93 (prefixed to ensure package-level uniqueness)\n  Enum93_UNSPECIFIED = 0;\n  Enum93_ONE = 1;\n  Enum93_TWO = 2;\n  Enum93_THREE = 3;\n  Enum93_FOUR = 4;\n}\n\nenum Enum94 {\n  // Values for Enum94 (prefixed to ensure package-level uniqueness)\n  Enum94_UNSPECIFIED = 0;\n  Enum94_ONE = 1;\n  Enum94_TWO = 2;\n  Enum94_THREE = 3;\n  Enum94_FOUR = 4;\n}\n\nenum Enum95 {\n  // Values for Enum95 (prefixed to ensure package-level uniqueness)\n  Enum95_UNSPECIFIED = 0;\n  Enum95_ONE = 1;\n  Enum95_TWO = 2;\n  Enum95_THREE = 3;\n  Enum95_FOUR = 4;\n}\n\nenum Enum96 {\n  // Values for Enum96 (prefixed to ensure package-level uniqueness)\n  Enum96_UNSPECIFIED = 0;\n  Enum96_ONE = 1;\n  Enum96_TWO = 2;\n  Enum96_THREE = 3;\n  Enum96_FOUR = 4;\n}\n\nenum Enum97 {\n  // Values for Enum97 (prefixed to ensure package-level uniqueness)\n  Enum97_UNSPECIFIED = 0;\n  Enum97_ONE = 1;\n  Enum97_TWO = 2;\n  Enum97_THREE = 3;\n  Enum97_FOUR = 4;\n}\n\nenum Enum98 {\n  // Values for Enum98 (prefixed to ensure package-level uniqueness)\n  Enum98_UNSPECIFIED = 0;\n  Enum98_ONE = 1;\n  Enum98_TWO = 2;\n  Enum98_THREE = 3;\n  Enum98_FOUR = 4;\n}\n\nenum Enum99 {\n  // Values for Enum99 (prefixed to ensure package-level uniqueness)\n  Enum99_UNSPECIFIED = 0;\n  Enum99_ONE = 1;\n  Enum99_TWO = 2;\n  Enum99_THREE = 3;\n  Enum99_FOUR = 4;\n}\n\nenum Enum100 {\n  // Values for Enum100 (prefixed to ensure package-level uniqueness)\n  Enum100_UNSPECIFIED = 0;\n  Enum100_ONE = 1;\n  Enum100_TWO = 2;\n  Enum100_THREE = 3;\n  Enum100_FOUR = 4;\n}\n\nenum Enum101 {\n  // Values for Enum101 (prefixed to ensure package-level uniqueness)\n  Enum101_UNSPECIFIED = 0;\n  Enum101_ONE = 1;\n  Enum101_TWO = 2;\n  Enum101_THREE = 3;\n  Enum101_FOUR = 4;\n}\n\nenum Enum102 {\n  // Values for Enum102 (prefixed to ensure package-level uniqueness)\n  Enum102_UNSPECIFIED = 0;\n  Enum102_ONE = 1;\n  Enum102_TWO = 2;\n  Enum102_THREE = 3;\n  Enum102_FOUR = 4;\n}\n\nenum Enum103 {\n  // Values for Enum103 (prefixed to ensure package-level uniqueness)\n  Enum103_UNSPECIFIED = 0;\n  Enum103_ONE = 1;\n  Enum103_TWO = 2;\n  Enum103_THREE = 3;\n  Enum103_FOUR = 4;\n}\n\nenum Enum104 {\n  // Values for Enum104 (prefixed to ensure package-level uniqueness)\n  Enum104_UNSPECIFIED = 0;\n  Enum104_ONE = 1;\n  Enum104_TWO = 2;\n  Enum104_THREE = 3;\n  Enum104_FOUR = 4;\n}\n\nenum Enum105 {\n  // Values for Enum105 (prefixed to ensure package-level uniqueness)\n  Enum105_UNSPECIFIED = 0;\n  Enum105_ONE = 1;\n  Enum105_TWO = 2;\n  Enum105_THREE = 3;\n  Enum105_FOUR = 4;\n}\n\nenum Enum106 {\n  // Values for Enum106 (prefixed to ensure package-level uniqueness)\n  Enum106_UNSPECIFIED = 0;\n  Enum106_ONE = 1;\n  Enum106_TWO = 2;\n  Enum106_THREE = 3;\n  Enum106_FOUR = 4;\n}\n\nenum Enum107 {\n  // Values for Enum107 (prefixed to ensure package-level uniqueness)\n  Enum107_UNSPECIFIED = 0;\n  Enum107_ONE = 1;\n  Enum107_TWO = 2;\n  Enum107_THREE = 3;\n  Enum107_FOUR = 4;\n}\n\nenum Enum108 {\n  // Values for Enum108 (prefixed to ensure package-level uniqueness)\n  Enum108_UNSPECIFIED = 0;\n  Enum108_ONE = 1;\n  Enum108_TWO = 2;\n  Enum108_THREE = 3;\n  Enum108_FOUR = 4;\n}\n\nenum Enum109 {\n  // Values for Enum109 (prefixed to ensure package-level uniqueness)\n  Enum109_UNSPECIFIED = 0;\n  Enum109_ONE = 1;\n  Enum109_TWO = 2;\n  Enum109_THREE = 3;\n  Enum109_FOUR = 4;\n}\n\nenum Enum110 {\n  // Values for Enum110 (prefixed to ensure package-level uniqueness)\n  Enum110_UNSPECIFIED = 0;\n  Enum110_ONE = 1;\n  Enum110_TWO = 2;\n  Enum110_THREE = 3;\n  Enum110_FOUR = 4;\n}\n\nenum Enum111 {\n  // Values for Enum111 (prefixed to ensure package-level uniqueness)\n  Enum111_UNSPECIFIED = 0;\n  Enum111_ONE = 1;\n  Enum111_TWO = 2;\n  Enum111_THREE = 3;\n  Enum111_FOUR = 4;\n}\n\nenum Enum112 {\n  // Values for Enum112 (prefixed to ensure package-level uniqueness)\n  Enum112_UNSPECIFIED = 0;\n  Enum112_ONE = 1;\n  Enum112_TWO = 2;\n  Enum112_THREE = 3;\n  Enum112_FOUR = 4;\n}\n\nenum Enum113 {\n  // Values for Enum113 (prefixed to ensure package-level uniqueness)\n  Enum113_UNSPECIFIED = 0;\n  Enum113_ONE = 1;\n  Enum113_TWO = 2;\n  Enum113_THREE = 3;\n  Enum113_FOUR = 4;\n}\n\nenum Enum114 {\n  // Values for Enum114 (prefixed to ensure package-level uniqueness)\n  Enum114_UNSPECIFIED = 0;\n  Enum114_ONE = 1;\n  Enum114_TWO = 2;\n  Enum114_THREE = 3;\n  Enum114_FOUR = 4;\n}\n\nenum Enum115 {\n  // Values for Enum115 (prefixed to ensure package-level uniqueness)\n  Enum115_UNSPECIFIED = 0;\n  Enum115_ONE = 1;\n  Enum115_TWO = 2;\n  Enum115_THREE = 3;\n  Enum115_FOUR = 4;\n}\n\nenum Enum116 {\n  // Values for Enum116 (prefixed to ensure package-level uniqueness)\n  Enum116_UNSPECIFIED = 0;\n  Enum116_ONE = 1;\n  Enum116_TWO = 2;\n  Enum116_THREE = 3;\n  Enum116_FOUR = 4;\n}\n\nenum Enum117 {\n  // Values for Enum117 (prefixed to ensure package-level uniqueness)\n  Enum117_UNSPECIFIED = 0;\n  Enum117_ONE = 1;\n  Enum117_TWO = 2;\n  Enum117_THREE = 3;\n  Enum117_FOUR = 4;\n}\n\nenum Enum118 {\n  // Values for Enum118 (prefixed to ensure package-level uniqueness)\n  Enum118_UNSPECIFIED = 0;\n  Enum118_ONE = 1;\n  Enum118_TWO = 2;\n  Enum118_THREE = 3;\n  Enum118_FOUR = 4;\n}\n\nenum Enum119 {\n  // Values for Enum119 (prefixed to ensure package-level uniqueness)\n  Enum119_UNSPECIFIED = 0;\n  Enum119_ONE = 1;\n  Enum119_TWO = 2;\n  Enum119_THREE = 3;\n  Enum119_FOUR = 4;\n}\n\nenum Enum120 {\n  // Values for Enum120 (prefixed to ensure package-level uniqueness)\n  Enum120_UNSPECIFIED = 0;\n  Enum120_ONE = 1;\n  Enum120_TWO = 2;\n  Enum120_THREE = 3;\n  Enum120_FOUR = 4;\n}\n\nenum Enum121 {\n  // Values for Enum121 (prefixed to ensure package-level uniqueness)\n  Enum121_UNSPECIFIED = 0;\n  Enum121_ONE = 1;\n  Enum121_TWO = 2;\n  Enum121_THREE = 3;\n  Enum121_FOUR = 4;\n}\n\nenum Enum122 {\n  // Values for Enum122 (prefixed to ensure package-level uniqueness)\n  Enum122_UNSPECIFIED = 0;\n  Enum122_ONE = 1;\n  Enum122_TWO = 2;\n  Enum122_THREE = 3;\n  Enum122_FOUR = 4;\n}\n\nenum Enum123 {\n  // Values for Enum123 (prefixed to ensure package-level uniqueness)\n  Enum123_UNSPECIFIED = 0;\n  Enum123_ONE = 1;\n  Enum123_TWO = 2;\n  Enum123_THREE = 3;\n  Enum123_FOUR = 4;\n}\n\nenum Enum124 {\n  // Values for Enum124 (prefixed to ensure package-level uniqueness)\n  Enum124_UNSPECIFIED = 0;\n  Enum124_ONE = 1;\n  Enum124_TWO = 2;\n  Enum124_THREE = 3;\n  Enum124_FOUR = 4;\n}\n\nenum Enum125 {\n  // Values for Enum125 (prefixed to ensure package-level uniqueness)\n  Enum125_UNSPECIFIED = 0;\n  Enum125_ONE = 1;\n  Enum125_TWO = 2;\n  Enum125_THREE = 3;\n  Enum125_FOUR = 4;\n}\n\nenum Enum126 {\n  // Values for Enum126 (prefixed to ensure package-level uniqueness)\n  Enum126_UNSPECIFIED = 0;\n  Enum126_ONE = 1;\n  Enum126_TWO = 2;\n  Enum126_THREE = 3;\n  Enum126_FOUR = 4;\n}\n\nenum Enum127 {\n  // Values for Enum127 (prefixed to ensure package-level uniqueness)\n  Enum127_UNSPECIFIED = 0;\n  Enum127_ONE = 1;\n  Enum127_TWO = 2;\n  Enum127_THREE = 3;\n  Enum127_FOUR = 4;\n}\n\nenum Enum128 {\n  // Values for Enum128 (prefixed to ensure package-level uniqueness)\n  Enum128_UNSPECIFIED = 0;\n  Enum128_ONE = 1;\n  Enum128_TWO = 2;\n  Enum128_THREE = 3;\n  Enum128_FOUR = 4;\n}\n\nenum Enum129 {\n  // Values for Enum129 (prefixed to ensure package-level uniqueness)\n  Enum129_UNSPECIFIED = 0;\n  Enum129_ONE = 1;\n  Enum129_TWO = 2;\n  Enum129_THREE = 3;\n  Enum129_FOUR = 4;\n}\n\nenum Enum130 {\n  // Values for Enum130 (prefixed to ensure package-level uniqueness)\n  Enum130_UNSPECIFIED = 0;\n  Enum130_ONE = 1;\n  Enum130_TWO = 2;\n  Enum130_THREE = 3;\n  Enum130_FOUR = 4;\n}\n\nenum Enum131 {\n  // Values for Enum131 (prefixed to ensure package-level uniqueness)\n  Enum131_UNSPECIFIED = 0;\n  Enum131_ONE = 1;\n  Enum131_TWO = 2;\n  Enum131_THREE = 3;\n  Enum131_FOUR = 4;\n}\n\nenum Enum132 {\n  // Values for Enum132 (prefixed to ensure package-level uniqueness)\n  Enum132_UNSPECIFIED = 0;\n  Enum132_ONE = 1;\n  Enum132_TWO = 2;\n  Enum132_THREE = 3;\n  Enum132_FOUR = 4;\n}\n\nenum Enum133 {\n  // Values for Enum133 (prefixed to ensure package-level uniqueness)\n  Enum133_UNSPECIFIED = 0;\n  Enum133_ONE = 1;\n  Enum133_TWO = 2;\n  Enum133_THREE = 3;\n  Enum133_FOUR = 4;\n}\n\nenum Enum134 {\n  // Values for Enum134 (prefixed to ensure package-level uniqueness)\n  Enum134_UNSPECIFIED = 0;\n  Enum134_ONE = 1;\n  Enum134_TWO = 2;\n  Enum134_THREE = 3;\n  Enum134_FOUR = 4;\n}\n\nenum Enum135 {\n  // Values for Enum135 (prefixed to ensure package-level uniqueness)\n  Enum135_UNSPECIFIED = 0;\n  Enum135_ONE = 1;\n  Enum135_TWO = 2;\n  Enum135_THREE = 3;\n  Enum135_FOUR = 4;\n}\n\nenum Enum136 {\n  // Values for Enum136 (prefixed to ensure package-level uniqueness)\n  Enum136_UNSPECIFIED = 0;\n  Enum136_ONE = 1;\n  Enum136_TWO = 2;\n  Enum136_THREE = 3;\n  Enum136_FOUR = 4;\n}\n\nenum Enum137 {\n  // Values for Enum137 (prefixed to ensure package-level uniqueness)\n  Enum137_UNSPECIFIED = 0;\n  Enum137_ONE = 1;\n  Enum137_TWO = 2;\n  Enum137_THREE = 3;\n  Enum137_FOUR = 4;\n}\n\nenum Enum138 {\n  // Values for Enum138 (prefixed to ensure package-level uniqueness)\n  Enum138_UNSPECIFIED = 0;\n  Enum138_ONE = 1;\n  Enum138_TWO = 2;\n  Enum138_THREE = 3;\n  Enum138_FOUR = 4;\n}\n\nenum Enum139 {\n  // Values for Enum139 (prefixed to ensure package-level uniqueness)\n  Enum139_UNSPECIFIED = 0;\n  Enum139_ONE = 1;\n  Enum139_TWO = 2;\n  Enum139_THREE = 3;\n  Enum139_FOUR = 4;\n}\n\nenum Enum140 {\n  // Values for Enum140 (prefixed to ensure package-level uniqueness)\n  Enum140_UNSPECIFIED = 0;\n  Enum140_ONE = 1;\n  Enum140_TWO = 2;\n  Enum140_THREE = 3;\n  Enum140_FOUR = 4;\n}\n\nenum Enum141 {\n  // Values for Enum141 (prefixed to ensure package-level uniqueness)\n  Enum141_UNSPECIFIED = 0;\n  Enum141_ONE = 1;\n  Enum141_TWO = 2;\n  Enum141_THREE = 3;\n  Enum141_FOUR = 4;\n}\n\nenum Enum142 {\n  // Values for Enum142 (prefixed to ensure package-level uniqueness)\n  Enum142_UNSPECIFIED = 0;\n  Enum142_ONE = 1;\n  Enum142_TWO = 2;\n  Enum142_THREE = 3;\n  Enum142_FOUR = 4;\n}\n\nenum Enum143 {\n  // Values for Enum143 (prefixed to ensure package-level uniqueness)\n  Enum143_UNSPECIFIED = 0;\n  Enum143_ONE = 1;\n  Enum143_TWO = 2;\n  Enum143_THREE = 3;\n  Enum143_FOUR = 4;\n}\n\nenum Enum144 {\n  // Values for Enum144 (prefixed to ensure package-level uniqueness)\n  Enum144_UNSPECIFIED = 0;\n  Enum144_ONE = 1;\n  Enum144_TWO = 2;\n  Enum144_THREE = 3;\n  Enum144_FOUR = 4;\n}\n\nenum Enum145 {\n  // Values for Enum145 (prefixed to ensure package-level uniqueness)\n  Enum145_UNSPECIFIED = 0;\n  Enum145_ONE = 1;\n  Enum145_TWO = 2;\n  Enum145_THREE = 3;\n  Enum145_FOUR = 4;\n}\n\nenum Enum146 {\n  // Values for Enum146 (prefixed to ensure package-level uniqueness)\n  Enum146_UNSPECIFIED = 0;\n  Enum146_ONE = 1;\n  Enum146_TWO = 2;\n  Enum146_THREE = 3;\n  Enum146_FOUR = 4;\n}\n\nenum Enum147 {\n  // Values for Enum147 (prefixed to ensure package-level uniqueness)\n  Enum147_UNSPECIFIED = 0;\n  Enum147_ONE = 1;\n  Enum147_TWO = 2;\n  Enum147_THREE = 3;\n  Enum147_FOUR = 4;\n}\n\nenum Enum148 {\n  // Values for Enum148 (prefixed to ensure package-level uniqueness)\n  Enum148_UNSPECIFIED = 0;\n  Enum148_ONE = 1;\n  Enum148_TWO = 2;\n  Enum148_THREE = 3;\n  Enum148_FOUR = 4;\n}\n\nenum Enum149 {\n  // Values for Enum149 (prefixed to ensure package-level uniqueness)\n  Enum149_UNSPECIFIED = 0;\n  Enum149_ONE = 1;\n  Enum149_TWO = 2;\n  Enum149_THREE = 3;\n  Enum149_FOUR = 4;\n}\n\nenum Enum150 {\n  // Values for Enum150 (prefixed to ensure package-level uniqueness)\n  Enum150_UNSPECIFIED = 0;\n  Enum150_ONE = 1;\n  Enum150_TWO = 2;\n  Enum150_THREE = 3;\n  Enum150_FOUR = 4;\n}\n\nenum Enum151 {\n  // Values for Enum151 (prefixed to ensure package-level uniqueness)\n  Enum151_UNSPECIFIED = 0;\n  Enum151_ONE = 1;\n  Enum151_TWO = 2;\n  Enum151_THREE = 3;\n  Enum151_FOUR = 4;\n}\n\nenum Enum152 {\n  // Values for Enum152 (prefixed to ensure package-level uniqueness)\n  Enum152_UNSPECIFIED = 0;\n  Enum152_ONE = 1;\n  Enum152_TWO = 2;\n  Enum152_THREE = 3;\n  Enum152_FOUR = 4;\n}\n\nenum Enum153 {\n  // Values for Enum153 (prefixed to ensure package-level uniqueness)\n  Enum153_UNSPECIFIED = 0;\n  Enum153_ONE = 1;\n  Enum153_TWO = 2;\n  Enum153_THREE = 3;\n  Enum153_FOUR = 4;\n}\n\nenum Enum154 {\n  // Values for Enum154 (prefixed to ensure package-level uniqueness)\n  Enum154_UNSPECIFIED = 0;\n  Enum154_ONE = 1;\n  Enum154_TWO = 2;\n  Enum154_THREE = 3;\n  Enum154_FOUR = 4;\n}\n\nenum Enum155 {\n  // Values for Enum155 (prefixed to ensure package-level uniqueness)\n  Enum155_UNSPECIFIED = 0;\n  Enum155_ONE = 1;\n  Enum155_TWO = 2;\n  Enum155_THREE = 3;\n  Enum155_FOUR = 4;\n}\n\nenum Enum156 {\n  // Values for Enum156 (prefixed to ensure package-level uniqueness)\n  Enum156_UNSPECIFIED = 0;\n  Enum156_ONE = 1;\n  Enum156_TWO = 2;\n  Enum156_THREE = 3;\n  Enum156_FOUR = 4;\n}\n\nenum Enum157 {\n  // Values for Enum157 (prefixed to ensure package-level uniqueness)\n  Enum157_UNSPECIFIED = 0;\n  Enum157_ONE = 1;\n  Enum157_TWO = 2;\n  Enum157_THREE = 3;\n  Enum157_FOUR = 4;\n}\n\nenum Enum158 {\n  // Values for Enum158 (prefixed to ensure package-level uniqueness)\n  Enum158_UNSPECIFIED = 0;\n  Enum158_ONE = 1;\n  Enum158_TWO = 2;\n  Enum158_THREE = 3;\n  Enum158_FOUR = 4;\n}\n\nenum Enum159 {\n  // Values for Enum159 (prefixed to ensure package-level uniqueness)\n  Enum159_UNSPECIFIED = 0;\n  Enum159_ONE = 1;\n  Enum159_TWO = 2;\n  Enum159_THREE = 3;\n  Enum159_FOUR = 4;\n}\n\nenum Enum160 {\n  // Values for Enum160 (prefixed to ensure package-level uniqueness)\n  Enum160_UNSPECIFIED = 0;\n  Enum160_ONE = 1;\n  Enum160_TWO = 2;\n  Enum160_THREE = 3;\n  Enum160_FOUR = 4;\n}\n\nenum Enum161 {\n  // Values for Enum161 (prefixed to ensure package-level uniqueness)\n  Enum161_UNSPECIFIED = 0;\n  Enum161_ONE = 1;\n  Enum161_TWO = 2;\n  Enum161_THREE = 3;\n  Enum161_FOUR = 4;\n}\n\nenum Enum162 {\n  // Values for Enum162 (prefixed to ensure package-level uniqueness)\n  Enum162_UNSPECIFIED = 0;\n  Enum162_ONE = 1;\n  Enum162_TWO = 2;\n  Enum162_THREE = 3;\n  Enum162_FOUR = 4;\n}\n\nenum Enum163 {\n  // Values for Enum163 (prefixed to ensure package-level uniqueness)\n  Enum163_UNSPECIFIED = 0;\n  Enum163_ONE = 1;\n  Enum163_TWO = 2;\n  Enum163_THREE = 3;\n  Enum163_FOUR = 4;\n}\n\nenum Enum164 {\n  // Values for Enum164 (prefixed to ensure package-level uniqueness)\n  Enum164_UNSPECIFIED = 0;\n  Enum164_ONE = 1;\n  Enum164_TWO = 2;\n  Enum164_THREE = 3;\n  Enum164_FOUR = 4;\n}\n\nenum Enum165 {\n  // Values for Enum165 (prefixed to ensure package-level uniqueness)\n  Enum165_UNSPECIFIED = 0;\n  Enum165_ONE = 1;\n  Enum165_TWO = 2;\n  Enum165_THREE = 3;\n  Enum165_FOUR = 4;\n}\n\nenum Enum166 {\n  // Values for Enum166 (prefixed to ensure package-level uniqueness)\n  Enum166_UNSPECIFIED = 0;\n  Enum166_ONE = 1;\n  Enum166_TWO = 2;\n  Enum166_THREE = 3;\n  Enum166_FOUR = 4;\n}\n\nenum Enum167 {\n  // Values for Enum167 (prefixed to ensure package-level uniqueness)\n  Enum167_UNSPECIFIED = 0;\n  Enum167_ONE = 1;\n  Enum167_TWO = 2;\n  Enum167_THREE = 3;\n  Enum167_FOUR = 4;\n}\n\nenum Enum168 {\n  // Values for Enum168 (prefixed to ensure package-level uniqueness)\n  Enum168_UNSPECIFIED = 0;\n  Enum168_ONE = 1;\n  Enum168_TWO = 2;\n  Enum168_THREE = 3;\n  Enum168_FOUR = 4;\n}\n\nenum Enum169 {\n  // Values for Enum169 (prefixed to ensure package-level uniqueness)\n  Enum169_UNSPECIFIED = 0;\n  Enum169_ONE = 1;\n  Enum169_TWO = 2;\n  Enum169_THREE = 3;\n  Enum169_FOUR = 4;\n}\n\nenum Enum170 {\n  // Values for Enum170 (prefixed to ensure package-level uniqueness)\n  Enum170_UNSPECIFIED = 0;\n  Enum170_ONE = 1;\n  Enum170_TWO = 2;\n  Enum170_THREE = 3;\n  Enum170_FOUR = 4;\n}\n\nenum Enum171 {\n  // Values for Enum171 (prefixed to ensure package-level uniqueness)\n  Enum171_UNSPECIFIED = 0;\n  Enum171_ONE = 1;\n  Enum171_TWO = 2;\n  Enum171_THREE = 3;\n  Enum171_FOUR = 4;\n}\n\nenum Enum172 {\n  // Values for Enum172 (prefixed to ensure package-level uniqueness)\n  Enum172_UNSPECIFIED = 0;\n  Enum172_ONE = 1;\n  Enum172_TWO = 2;\n  Enum172_THREE = 3;\n  Enum172_FOUR = 4;\n}\n\nenum Enum173 {\n  // Values for Enum173 (prefixed to ensure package-level uniqueness)\n  Enum173_UNSPECIFIED = 0;\n  Enum173_ONE = 1;\n  Enum173_TWO = 2;\n  Enum173_THREE = 3;\n  Enum173_FOUR = 4;\n}\n\nenum Enum174 {\n  // Values for Enum174 (prefixed to ensure package-level uniqueness)\n  Enum174_UNSPECIFIED = 0;\n  Enum174_ONE = 1;\n  Enum174_TWO = 2;\n  Enum174_THREE = 3;\n  Enum174_FOUR = 4;\n}\n\nenum Enum175 {\n  // Values for Enum175 (prefixed to ensure package-level uniqueness)\n  Enum175_UNSPECIFIED = 0;\n  Enum175_ONE = 1;\n  Enum175_TWO = 2;\n  Enum175_THREE = 3;\n  Enum175_FOUR = 4;\n}\n\nenum Enum176 {\n  // Values for Enum176 (prefixed to ensure package-level uniqueness)\n  Enum176_UNSPECIFIED = 0;\n  Enum176_ONE = 1;\n  Enum176_TWO = 2;\n  Enum176_THREE = 3;\n  Enum176_FOUR = 4;\n}\n\nenum Enum177 {\n  // Values for Enum177 (prefixed to ensure package-level uniqueness)\n  Enum177_UNSPECIFIED = 0;\n  Enum177_ONE = 1;\n  Enum177_TWO = 2;\n  Enum177_THREE = 3;\n  Enum177_FOUR = 4;\n}\n\nenum Enum178 {\n  // Values for Enum178 (prefixed to ensure package-level uniqueness)\n  Enum178_UNSPECIFIED = 0;\n  Enum178_ONE = 1;\n  Enum178_TWO = 2;\n  Enum178_THREE = 3;\n  Enum178_FOUR = 4;\n}\n\nenum Enum179 {\n  // Values for Enum179 (prefixed to ensure package-level uniqueness)\n  Enum179_UNSPECIFIED = 0;\n  Enum179_ONE = 1;\n  Enum179_TWO = 2;\n  Enum179_THREE = 3;\n  Enum179_FOUR = 4;\n}\n\nenum Enum180 {\n  // Values for Enum180 (prefixed to ensure package-level uniqueness)\n  Enum180_UNSPECIFIED = 0;\n  Enum180_ONE = 1;\n  Enum180_TWO = 2;\n  Enum180_THREE = 3;\n  Enum180_FOUR = 4;\n}\n\nenum Enum181 {\n  // Values for Enum181 (prefixed to ensure package-level uniqueness)\n  Enum181_UNSPECIFIED = 0;\n  Enum181_ONE = 1;\n  Enum181_TWO = 2;\n  Enum181_THREE = 3;\n  Enum181_FOUR = 4;\n}\n\nenum Enum182 {\n  // Values for Enum182 (prefixed to ensure package-level uniqueness)\n  Enum182_UNSPECIFIED = 0;\n  Enum182_ONE = 1;\n  Enum182_TWO = 2;\n  Enum182_THREE = 3;\n  Enum182_FOUR = 4;\n}\n\nenum Enum183 {\n  // Values for Enum183 (prefixed to ensure package-level uniqueness)\n  Enum183_UNSPECIFIED = 0;\n  Enum183_ONE = 1;\n  Enum183_TWO = 2;\n  Enum183_THREE = 3;\n  Enum183_FOUR = 4;\n}\n\nenum Enum184 {\n  // Values for Enum184 (prefixed to ensure package-level uniqueness)\n  Enum184_UNSPECIFIED = 0;\n  Enum184_ONE = 1;\n  Enum184_TWO = 2;\n  Enum184_THREE = 3;\n  Enum184_FOUR = 4;\n}\n\nenum Enum185 {\n  // Values for Enum185 (prefixed to ensure package-level uniqueness)\n  Enum185_UNSPECIFIED = 0;\n  Enum185_ONE = 1;\n  Enum185_TWO = 2;\n  Enum185_THREE = 3;\n  Enum185_FOUR = 4;\n}\n\nenum Enum186 {\n  // Values for Enum186 (prefixed to ensure package-level uniqueness)\n  Enum186_UNSPECIFIED = 0;\n  Enum186_ONE = 1;\n  Enum186_TWO = 2;\n  Enum186_THREE = 3;\n  Enum186_FOUR = 4;\n}\n\nenum Enum187 {\n  // Values for Enum187 (prefixed to ensure package-level uniqueness)\n  Enum187_UNSPECIFIED = 0;\n  Enum187_ONE = 1;\n  Enum187_TWO = 2;\n  Enum187_THREE = 3;\n  Enum187_FOUR = 4;\n}\n\nenum Enum188 {\n  // Values for Enum188 (prefixed to ensure package-level uniqueness)\n  Enum188_UNSPECIFIED = 0;\n  Enum188_ONE = 1;\n  Enum188_TWO = 2;\n  Enum188_THREE = 3;\n  Enum188_FOUR = 4;\n}\n\nenum Enum189 {\n  // Values for Enum189 (prefixed to ensure package-level uniqueness)\n  Enum189_UNSPECIFIED = 0;\n  Enum189_ONE = 1;\n  Enum189_TWO = 2;\n  Enum189_THREE = 3;\n  Enum189_FOUR = 4;\n}\n\nenum Enum190 {\n  // Values for Enum190 (prefixed to ensure package-level uniqueness)\n  Enum190_UNSPECIFIED = 0;\n  Enum190_ONE = 1;\n  Enum190_TWO = 2;\n  Enum190_THREE = 3;\n  Enum190_FOUR = 4;\n}\n\nenum Enum191 {\n  // Values for Enum191 (prefixed to ensure package-level uniqueness)\n  Enum191_UNSPECIFIED = 0;\n  Enum191_ONE = 1;\n  Enum191_TWO = 2;\n  Enum191_THREE = 3;\n  Enum191_FOUR = 4;\n}\n\nenum Enum192 {\n  // Values for Enum192 (prefixed to ensure package-level uniqueness)\n  Enum192_UNSPECIFIED = 0;\n  Enum192_ONE = 1;\n  Enum192_TWO = 2;\n  Enum192_THREE = 3;\n  Enum192_FOUR = 4;\n}\n\nenum Enum193 {\n  // Values for Enum193 (prefixed to ensure package-level uniqueness)\n  Enum193_UNSPECIFIED = 0;\n  Enum193_ONE = 1;\n  Enum193_TWO = 2;\n  Enum193_THREE = 3;\n  Enum193_FOUR = 4;\n}\n\nenum Enum194 {\n  // Values for Enum194 (prefixed to ensure package-level uniqueness)\n  Enum194_UNSPECIFIED = 0;\n  Enum194_ONE = 1;\n  Enum194_TWO = 2;\n  Enum194_THREE = 3;\n  Enum194_FOUR = 4;\n}\n\nenum Enum195 {\n  // Values for Enum195 (prefixed to ensure package-level uniqueness)\n  Enum195_UNSPECIFIED = 0;\n  Enum195_ONE = 1;\n  Enum195_TWO = 2;\n  Enum195_THREE = 3;\n  Enum195_FOUR = 4;\n}\n\nenum Enum196 {\n  // Values for Enum196 (prefixed to ensure package-level uniqueness)\n  Enum196_UNSPECIFIED = 0;\n  Enum196_ONE = 1;\n  Enum196_TWO = 2;\n  Enum196_THREE = 3;\n  Enum196_FOUR = 4;\n}\n\nenum Enum197 {\n  // Values for Enum197 (prefixed to ensure package-level uniqueness)\n  Enum197_UNSPECIFIED = 0;\n  Enum197_ONE = 1;\n  Enum197_TWO = 2;\n  Enum197_THREE = 3;\n  Enum197_FOUR = 4;\n}\n\nenum Enum198 {\n  // Values for Enum198 (prefixed to ensure package-level uniqueness)\n  Enum198_UNSPECIFIED = 0;\n  Enum198_ONE = 1;\n  Enum198_TWO = 2;\n  Enum198_THREE = 3;\n  Enum198_FOUR = 4;\n}\n\nenum Enum199 {\n  // Values for Enum199 (prefixed to ensure package-level uniqueness)\n  Enum199_UNSPECIFIED = 0;\n  Enum199_ONE = 1;\n  Enum199_TWO = 2;\n  Enum199_THREE = 3;\n  Enum199_FOUR = 4;\n}\n\nmessage Message0 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum0> enum_map = 5;\n  Enum0 status = 6;\n  repeated Enum1 flags = 7;\n  Message1 next = 8;\n  repeated Message2 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message3 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum2 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message1.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message1 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum1> enum_map = 5;\n  Enum1 status = 6;\n  repeated Enum2 flags = 7;\n  Message2 next = 8;\n  repeated Message3 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message4 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum3 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message2.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message2 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum2> enum_map = 5;\n  Enum2 status = 6;\n  repeated Enum3 flags = 7;\n  Message3 next = 8;\n  repeated Message4 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message5 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum4 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message3.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message3 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum3> enum_map = 5;\n  Enum3 status = 6;\n  repeated Enum4 flags = 7;\n  Message4 next = 8;\n  repeated Message5 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message6 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum5 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message4.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message4 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum4> enum_map = 5;\n  Enum4 status = 6;\n  repeated Enum5 flags = 7;\n  Message5 next = 8;\n  repeated Message6 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message7 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum6 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message5.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message5 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum5> enum_map = 5;\n  Enum5 status = 6;\n  repeated Enum6 flags = 7;\n  Message6 next = 8;\n  repeated Message7 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message8 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum7 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message6.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message6 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum6> enum_map = 5;\n  Enum6 status = 6;\n  repeated Enum7 flags = 7;\n  Message7 next = 8;\n  repeated Message8 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message9 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum8 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message7.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message7 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum7> enum_map = 5;\n  Enum7 status = 6;\n  repeated Enum8 flags = 7;\n  Message8 next = 8;\n  repeated Message9 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message10 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum9 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message8.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message8 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum8> enum_map = 5;\n  Enum8 status = 6;\n  repeated Enum9 flags = 7;\n  Message9 next = 8;\n  repeated Message10 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message11 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum10 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message9.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message9 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum9> enum_map = 5;\n  Enum9 status = 6;\n  repeated Enum10 flags = 7;\n  Message10 next = 8;\n  repeated Message11 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message12 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum11 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message10.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message10 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum10> enum_map = 5;\n  Enum10 status = 6;\n  repeated Enum11 flags = 7;\n  Message11 next = 8;\n  repeated Message12 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message13 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum12 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message11.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message11 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum11> enum_map = 5;\n  Enum11 status = 6;\n  repeated Enum12 flags = 7;\n  Message12 next = 8;\n  repeated Message13 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message14 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum13 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message12.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message12 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum12> enum_map = 5;\n  Enum12 status = 6;\n  repeated Enum13 flags = 7;\n  Message13 next = 8;\n  repeated Message14 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message15 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum14 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message13.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message13 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum13> enum_map = 5;\n  Enum13 status = 6;\n  repeated Enum14 flags = 7;\n  Message14 next = 8;\n  repeated Message15 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message16 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum15 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message14.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message14 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum14> enum_map = 5;\n  Enum14 status = 6;\n  repeated Enum15 flags = 7;\n  Message15 next = 8;\n  repeated Message16 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message17 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum16 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message15.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message15 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum15> enum_map = 5;\n  Enum15 status = 6;\n  repeated Enum16 flags = 7;\n  Message16 next = 8;\n  repeated Message17 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message18 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum17 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message16.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message16 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum16> enum_map = 5;\n  Enum16 status = 6;\n  repeated Enum17 flags = 7;\n  Message17 next = 8;\n  repeated Message18 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message19 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum18 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message17.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message17 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum17> enum_map = 5;\n  Enum17 status = 6;\n  repeated Enum18 flags = 7;\n  Message18 next = 8;\n  repeated Message19 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message20 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum19 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message18.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message18 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum18> enum_map = 5;\n  Enum18 status = 6;\n  repeated Enum19 flags = 7;\n  Message19 next = 8;\n  repeated Message20 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message21 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum20 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message19.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message19 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum19> enum_map = 5;\n  Enum19 status = 6;\n  repeated Enum20 flags = 7;\n  Message20 next = 8;\n  repeated Message21 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message22 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum21 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message20.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message20 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum20> enum_map = 5;\n  Enum20 status = 6;\n  repeated Enum21 flags = 7;\n  Message21 next = 8;\n  repeated Message22 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message23 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum22 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message21.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message21 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum21> enum_map = 5;\n  Enum21 status = 6;\n  repeated Enum22 flags = 7;\n  Message22 next = 8;\n  repeated Message23 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message24 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum23 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message22.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message22 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum22> enum_map = 5;\n  Enum22 status = 6;\n  repeated Enum23 flags = 7;\n  Message23 next = 8;\n  repeated Message24 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message25 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum24 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message23.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message23 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum23> enum_map = 5;\n  Enum23 status = 6;\n  repeated Enum24 flags = 7;\n  Message24 next = 8;\n  repeated Message25 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message26 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum25 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message24.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message24 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum24> enum_map = 5;\n  Enum24 status = 6;\n  repeated Enum25 flags = 7;\n  Message25 next = 8;\n  repeated Message26 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message27 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum26 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message25.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message25 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum25> enum_map = 5;\n  Enum25 status = 6;\n  repeated Enum26 flags = 7;\n  Message26 next = 8;\n  repeated Message27 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message28 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum27 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message26.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message26 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum26> enum_map = 5;\n  Enum26 status = 6;\n  repeated Enum27 flags = 7;\n  Message27 next = 8;\n  repeated Message28 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message29 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum28 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message27.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message27 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum27> enum_map = 5;\n  Enum27 status = 6;\n  repeated Enum28 flags = 7;\n  Message28 next = 8;\n  repeated Message29 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message30 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum29 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message28.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message28 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum28> enum_map = 5;\n  Enum28 status = 6;\n  repeated Enum29 flags = 7;\n  Message29 next = 8;\n  repeated Message30 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message31 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum30 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message29.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message29 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum29> enum_map = 5;\n  Enum29 status = 6;\n  repeated Enum30 flags = 7;\n  Message30 next = 8;\n  repeated Message31 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message32 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum31 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message30.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message30 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum30> enum_map = 5;\n  Enum30 status = 6;\n  repeated Enum31 flags = 7;\n  Message31 next = 8;\n  repeated Message32 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message33 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum32 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message31.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message31 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum31> enum_map = 5;\n  Enum31 status = 6;\n  repeated Enum32 flags = 7;\n  Message32 next = 8;\n  repeated Message33 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message34 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum33 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message32.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message32 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum32> enum_map = 5;\n  Enum32 status = 6;\n  repeated Enum33 flags = 7;\n  Message33 next = 8;\n  repeated Message34 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message35 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum34 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message33.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message33 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum33> enum_map = 5;\n  Enum33 status = 6;\n  repeated Enum34 flags = 7;\n  Message34 next = 8;\n  repeated Message35 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message36 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum35 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message34.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message34 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum34> enum_map = 5;\n  Enum34 status = 6;\n  repeated Enum35 flags = 7;\n  Message35 next = 8;\n  repeated Message36 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message37 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum36 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message35.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message35 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum35> enum_map = 5;\n  Enum35 status = 6;\n  repeated Enum36 flags = 7;\n  Message36 next = 8;\n  repeated Message37 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message38 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum37 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message36.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message36 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum36> enum_map = 5;\n  Enum36 status = 6;\n  repeated Enum37 flags = 7;\n  Message37 next = 8;\n  repeated Message38 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message39 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum38 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message37.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message37 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum37> enum_map = 5;\n  Enum37 status = 6;\n  repeated Enum38 flags = 7;\n  Message38 next = 8;\n  repeated Message39 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message40 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum39 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message38.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message38 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum38> enum_map = 5;\n  Enum38 status = 6;\n  repeated Enum39 flags = 7;\n  Message39 next = 8;\n  repeated Message40 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message41 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum40 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message39.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message39 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum39> enum_map = 5;\n  Enum39 status = 6;\n  repeated Enum40 flags = 7;\n  Message40 next = 8;\n  repeated Message41 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message42 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum41 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message40.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message40 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum40> enum_map = 5;\n  Enum40 status = 6;\n  repeated Enum41 flags = 7;\n  Message41 next = 8;\n  repeated Message42 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message43 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum42 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message41.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message41 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum41> enum_map = 5;\n  Enum41 status = 6;\n  repeated Enum42 flags = 7;\n  Message42 next = 8;\n  repeated Message43 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message44 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum43 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message42.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message42 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum42> enum_map = 5;\n  Enum42 status = 6;\n  repeated Enum43 flags = 7;\n  Message43 next = 8;\n  repeated Message44 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message45 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum44 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message43.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message43 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum43> enum_map = 5;\n  Enum43 status = 6;\n  repeated Enum44 flags = 7;\n  Message44 next = 8;\n  repeated Message45 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message46 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum45 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message44.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message44 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum44> enum_map = 5;\n  Enum44 status = 6;\n  repeated Enum45 flags = 7;\n  Message45 next = 8;\n  repeated Message46 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message47 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum46 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message45.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message45 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum45> enum_map = 5;\n  Enum45 status = 6;\n  repeated Enum46 flags = 7;\n  Message46 next = 8;\n  repeated Message47 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message48 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum47 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message46.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message46 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum46> enum_map = 5;\n  Enum46 status = 6;\n  repeated Enum47 flags = 7;\n  Message47 next = 8;\n  repeated Message48 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message49 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum48 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message47.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message47 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum47> enum_map = 5;\n  Enum47 status = 6;\n  repeated Enum48 flags = 7;\n  Message48 next = 8;\n  repeated Message49 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message50 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum49 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message48.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message48 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum48> enum_map = 5;\n  Enum48 status = 6;\n  repeated Enum49 flags = 7;\n  Message49 next = 8;\n  repeated Message50 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message51 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum50 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message49.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message49 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum49> enum_map = 5;\n  Enum49 status = 6;\n  repeated Enum50 flags = 7;\n  Message50 next = 8;\n  repeated Message51 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message52 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum51 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message50.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message50 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum50> enum_map = 5;\n  Enum50 status = 6;\n  repeated Enum51 flags = 7;\n  Message51 next = 8;\n  repeated Message52 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message53 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum52 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message51.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message51 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum51> enum_map = 5;\n  Enum51 status = 6;\n  repeated Enum52 flags = 7;\n  Message52 next = 8;\n  repeated Message53 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message54 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum53 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message52.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message52 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum52> enum_map = 5;\n  Enum52 status = 6;\n  repeated Enum53 flags = 7;\n  Message53 next = 8;\n  repeated Message54 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message55 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum54 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message53.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message53 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum53> enum_map = 5;\n  Enum53 status = 6;\n  repeated Enum54 flags = 7;\n  Message54 next = 8;\n  repeated Message55 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message56 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum55 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message54.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message54 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum54> enum_map = 5;\n  Enum54 status = 6;\n  repeated Enum55 flags = 7;\n  Message55 next = 8;\n  repeated Message56 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message57 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum56 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message55.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message55 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum55> enum_map = 5;\n  Enum55 status = 6;\n  repeated Enum56 flags = 7;\n  Message56 next = 8;\n  repeated Message57 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message58 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum57 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message56.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message56 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum56> enum_map = 5;\n  Enum56 status = 6;\n  repeated Enum57 flags = 7;\n  Message57 next = 8;\n  repeated Message58 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message59 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum58 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message57.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message57 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum57> enum_map = 5;\n  Enum57 status = 6;\n  repeated Enum58 flags = 7;\n  Message58 next = 8;\n  repeated Message59 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message60 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum59 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message58.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message58 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum58> enum_map = 5;\n  Enum58 status = 6;\n  repeated Enum59 flags = 7;\n  Message59 next = 8;\n  repeated Message60 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message61 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum60 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message59.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message59 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum59> enum_map = 5;\n  Enum59 status = 6;\n  repeated Enum60 flags = 7;\n  Message60 next = 8;\n  repeated Message61 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message62 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum61 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message60.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message60 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum60> enum_map = 5;\n  Enum60 status = 6;\n  repeated Enum61 flags = 7;\n  Message61 next = 8;\n  repeated Message62 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message63 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum62 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message61.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message61 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum61> enum_map = 5;\n  Enum61 status = 6;\n  repeated Enum62 flags = 7;\n  Message62 next = 8;\n  repeated Message63 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message64 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum63 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message62.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message62 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum62> enum_map = 5;\n  Enum62 status = 6;\n  repeated Enum63 flags = 7;\n  Message63 next = 8;\n  repeated Message64 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message65 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum64 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message63.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message63 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum63> enum_map = 5;\n  Enum63 status = 6;\n  repeated Enum64 flags = 7;\n  Message64 next = 8;\n  repeated Message65 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message66 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum65 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message64.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message64 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum64> enum_map = 5;\n  Enum64 status = 6;\n  repeated Enum65 flags = 7;\n  Message65 next = 8;\n  repeated Message66 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message67 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum66 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message65.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message65 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum65> enum_map = 5;\n  Enum65 status = 6;\n  repeated Enum66 flags = 7;\n  Message66 next = 8;\n  repeated Message67 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message68 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum67 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message66.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message66 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum66> enum_map = 5;\n  Enum66 status = 6;\n  repeated Enum67 flags = 7;\n  Message67 next = 8;\n  repeated Message68 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message69 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum68 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message67.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message67 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum67> enum_map = 5;\n  Enum67 status = 6;\n  repeated Enum68 flags = 7;\n  Message68 next = 8;\n  repeated Message69 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message70 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum69 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message68.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message68 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum68> enum_map = 5;\n  Enum68 status = 6;\n  repeated Enum69 flags = 7;\n  Message69 next = 8;\n  repeated Message70 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message71 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum70 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message69.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message69 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum69> enum_map = 5;\n  Enum69 status = 6;\n  repeated Enum70 flags = 7;\n  Message70 next = 8;\n  repeated Message71 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message72 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum71 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message70.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message70 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum70> enum_map = 5;\n  Enum70 status = 6;\n  repeated Enum71 flags = 7;\n  Message71 next = 8;\n  repeated Message72 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message73 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum72 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message71.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message71 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum71> enum_map = 5;\n  Enum71 status = 6;\n  repeated Enum72 flags = 7;\n  Message72 next = 8;\n  repeated Message73 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message74 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum73 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message72.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message72 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum72> enum_map = 5;\n  Enum72 status = 6;\n  repeated Enum73 flags = 7;\n  Message73 next = 8;\n  repeated Message74 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message75 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum74 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message73.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message73 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum73> enum_map = 5;\n  Enum73 status = 6;\n  repeated Enum74 flags = 7;\n  Message74 next = 8;\n  repeated Message75 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message76 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum75 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message74.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message74 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum74> enum_map = 5;\n  Enum74 status = 6;\n  repeated Enum75 flags = 7;\n  Message75 next = 8;\n  repeated Message76 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message77 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum76 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message75.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message75 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum75> enum_map = 5;\n  Enum75 status = 6;\n  repeated Enum76 flags = 7;\n  Message76 next = 8;\n  repeated Message77 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message78 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum77 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message76.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message76 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum76> enum_map = 5;\n  Enum76 status = 6;\n  repeated Enum77 flags = 7;\n  Message77 next = 8;\n  repeated Message78 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message79 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum78 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message77.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message77 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum77> enum_map = 5;\n  Enum77 status = 6;\n  repeated Enum78 flags = 7;\n  Message78 next = 8;\n  repeated Message79 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message80 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum79 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message78.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message78 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum78> enum_map = 5;\n  Enum78 status = 6;\n  repeated Enum79 flags = 7;\n  Message79 next = 8;\n  repeated Message80 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message81 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum80 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message79.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message79 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum79> enum_map = 5;\n  Enum79 status = 6;\n  repeated Enum80 flags = 7;\n  Message80 next = 8;\n  repeated Message81 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message82 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum81 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message80.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message80 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum80> enum_map = 5;\n  Enum80 status = 6;\n  repeated Enum81 flags = 7;\n  Message81 next = 8;\n  repeated Message82 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message83 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum82 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message81.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message81 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum81> enum_map = 5;\n  Enum81 status = 6;\n  repeated Enum82 flags = 7;\n  Message82 next = 8;\n  repeated Message83 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message84 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum83 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message82.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message82 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum82> enum_map = 5;\n  Enum82 status = 6;\n  repeated Enum83 flags = 7;\n  Message83 next = 8;\n  repeated Message84 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message85 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum84 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message83.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message83 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum83> enum_map = 5;\n  Enum83 status = 6;\n  repeated Enum84 flags = 7;\n  Message84 next = 8;\n  repeated Message85 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message86 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum85 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message84.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message84 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum84> enum_map = 5;\n  Enum84 status = 6;\n  repeated Enum85 flags = 7;\n  Message85 next = 8;\n  repeated Message86 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message87 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum86 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message85.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message85 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum85> enum_map = 5;\n  Enum85 status = 6;\n  repeated Enum86 flags = 7;\n  Message86 next = 8;\n  repeated Message87 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message88 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum87 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message86.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message86 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum86> enum_map = 5;\n  Enum86 status = 6;\n  repeated Enum87 flags = 7;\n  Message87 next = 8;\n  repeated Message88 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message89 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum88 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message87.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message87 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum87> enum_map = 5;\n  Enum87 status = 6;\n  repeated Enum88 flags = 7;\n  Message88 next = 8;\n  repeated Message89 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message90 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum89 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message88.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message88 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum88> enum_map = 5;\n  Enum88 status = 6;\n  repeated Enum89 flags = 7;\n  Message89 next = 8;\n  repeated Message90 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message91 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum90 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message89.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message89 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum89> enum_map = 5;\n  Enum89 status = 6;\n  repeated Enum90 flags = 7;\n  Message90 next = 8;\n  repeated Message91 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message92 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum91 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message90.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message90 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum90> enum_map = 5;\n  Enum90 status = 6;\n  repeated Enum91 flags = 7;\n  Message91 next = 8;\n  repeated Message92 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message93 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum92 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message91.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message91 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum91> enum_map = 5;\n  Enum91 status = 6;\n  repeated Enum92 flags = 7;\n  Message92 next = 8;\n  repeated Message93 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message94 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum93 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message92.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message92 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum92> enum_map = 5;\n  Enum92 status = 6;\n  repeated Enum93 flags = 7;\n  Message93 next = 8;\n  repeated Message94 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message95 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum94 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message93.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message93 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum93> enum_map = 5;\n  Enum93 status = 6;\n  repeated Enum94 flags = 7;\n  Message94 next = 8;\n  repeated Message95 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message96 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum95 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message94.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message94 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum94> enum_map = 5;\n  Enum94 status = 6;\n  repeated Enum95 flags = 7;\n  Message95 next = 8;\n  repeated Message96 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message97 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum96 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message95.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message95 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum95> enum_map = 5;\n  Enum95 status = 6;\n  repeated Enum96 flags = 7;\n  Message96 next = 8;\n  repeated Message97 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message98 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum97 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message96.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message96 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum96> enum_map = 5;\n  Enum96 status = 6;\n  repeated Enum97 flags = 7;\n  Message97 next = 8;\n  repeated Message98 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message99 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum98 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message97.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message97 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum97> enum_map = 5;\n  Enum97 status = 6;\n  repeated Enum98 flags = 7;\n  Message98 next = 8;\n  repeated Message99 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message100 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum99 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message98.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message98 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum98> enum_map = 5;\n  Enum98 status = 6;\n  repeated Enum99 flags = 7;\n  Message99 next = 8;\n  repeated Message100 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message101 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum100 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message99.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message99 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum99> enum_map = 5;\n  Enum99 status = 6;\n  repeated Enum100 flags = 7;\n  Message100 next = 8;\n  repeated Message101 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message102 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum101 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message100.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message100 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum100> enum_map = 5;\n  Enum100 status = 6;\n  repeated Enum101 flags = 7;\n  Message101 next = 8;\n  repeated Message102 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message103 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum102 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message101.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message101 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum101> enum_map = 5;\n  Enum101 status = 6;\n  repeated Enum102 flags = 7;\n  Message102 next = 8;\n  repeated Message103 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message104 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum103 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message102.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message102 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum102> enum_map = 5;\n  Enum102 status = 6;\n  repeated Enum103 flags = 7;\n  Message103 next = 8;\n  repeated Message104 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message105 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum104 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message103.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message103 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum103> enum_map = 5;\n  Enum103 status = 6;\n  repeated Enum104 flags = 7;\n  Message104 next = 8;\n  repeated Message105 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message106 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum105 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message104.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message104 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum104> enum_map = 5;\n  Enum104 status = 6;\n  repeated Enum105 flags = 7;\n  Message105 next = 8;\n  repeated Message106 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message107 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum106 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message105.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message105 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum105> enum_map = 5;\n  Enum105 status = 6;\n  repeated Enum106 flags = 7;\n  Message106 next = 8;\n  repeated Message107 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message108 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum107 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message106.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message106 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum106> enum_map = 5;\n  Enum106 status = 6;\n  repeated Enum107 flags = 7;\n  Message107 next = 8;\n  repeated Message108 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message109 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum108 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message107.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message107 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum107> enum_map = 5;\n  Enum107 status = 6;\n  repeated Enum108 flags = 7;\n  Message108 next = 8;\n  repeated Message109 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message110 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum109 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message108.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message108 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum108> enum_map = 5;\n  Enum108 status = 6;\n  repeated Enum109 flags = 7;\n  Message109 next = 8;\n  repeated Message110 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message111 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum110 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message109.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message109 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum109> enum_map = 5;\n  Enum109 status = 6;\n  repeated Enum110 flags = 7;\n  Message110 next = 8;\n  repeated Message111 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message112 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum111 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message110.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message110 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum110> enum_map = 5;\n  Enum110 status = 6;\n  repeated Enum111 flags = 7;\n  Message111 next = 8;\n  repeated Message112 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message113 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum112 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message111.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message111 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum111> enum_map = 5;\n  Enum111 status = 6;\n  repeated Enum112 flags = 7;\n  Message112 next = 8;\n  repeated Message113 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message114 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum113 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message112.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message112 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum112> enum_map = 5;\n  Enum112 status = 6;\n  repeated Enum113 flags = 7;\n  Message113 next = 8;\n  repeated Message114 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message115 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum114 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message113.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message113 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum113> enum_map = 5;\n  Enum113 status = 6;\n  repeated Enum114 flags = 7;\n  Message114 next = 8;\n  repeated Message115 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message116 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum115 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message114.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message114 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum114> enum_map = 5;\n  Enum114 status = 6;\n  repeated Enum115 flags = 7;\n  Message115 next = 8;\n  repeated Message116 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message117 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum116 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message115.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message115 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum115> enum_map = 5;\n  Enum115 status = 6;\n  repeated Enum116 flags = 7;\n  Message116 next = 8;\n  repeated Message117 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message118 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum117 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message116.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message116 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum116> enum_map = 5;\n  Enum116 status = 6;\n  repeated Enum117 flags = 7;\n  Message117 next = 8;\n  repeated Message118 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message119 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum118 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message117.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message117 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum117> enum_map = 5;\n  Enum117 status = 6;\n  repeated Enum118 flags = 7;\n  Message118 next = 8;\n  repeated Message119 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message120 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum119 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message118.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message118 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum118> enum_map = 5;\n  Enum118 status = 6;\n  repeated Enum119 flags = 7;\n  Message119 next = 8;\n  repeated Message120 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message121 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum120 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message119.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message119 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum119> enum_map = 5;\n  Enum119 status = 6;\n  repeated Enum120 flags = 7;\n  Message120 next = 8;\n  repeated Message121 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message122 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum121 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message120.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message120 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum120> enum_map = 5;\n  Enum120 status = 6;\n  repeated Enum121 flags = 7;\n  Message121 next = 8;\n  repeated Message122 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message123 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum122 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message121.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message121 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum121> enum_map = 5;\n  Enum121 status = 6;\n  repeated Enum122 flags = 7;\n  Message122 next = 8;\n  repeated Message123 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message124 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum123 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message122.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message122 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum122> enum_map = 5;\n  Enum122 status = 6;\n  repeated Enum123 flags = 7;\n  Message123 next = 8;\n  repeated Message124 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message125 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum124 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message123.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message123 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum123> enum_map = 5;\n  Enum123 status = 6;\n  repeated Enum124 flags = 7;\n  Message124 next = 8;\n  repeated Message125 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message126 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum125 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message124.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message124 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum124> enum_map = 5;\n  Enum124 status = 6;\n  repeated Enum125 flags = 7;\n  Message125 next = 8;\n  repeated Message126 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message127 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum126 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message125.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message125 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum125> enum_map = 5;\n  Enum125 status = 6;\n  repeated Enum126 flags = 7;\n  Message126 next = 8;\n  repeated Message127 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message128 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum127 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message126.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message126 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum126> enum_map = 5;\n  Enum126 status = 6;\n  repeated Enum127 flags = 7;\n  Message127 next = 8;\n  repeated Message128 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message129 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum128 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message127.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message127 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum127> enum_map = 5;\n  Enum127 status = 6;\n  repeated Enum128 flags = 7;\n  Message128 next = 8;\n  repeated Message129 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message130 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum129 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message128.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message128 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum128> enum_map = 5;\n  Enum128 status = 6;\n  repeated Enum129 flags = 7;\n  Message129 next = 8;\n  repeated Message130 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message131 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum130 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message129.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message129 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum129> enum_map = 5;\n  Enum129 status = 6;\n  repeated Enum130 flags = 7;\n  Message130 next = 8;\n  repeated Message131 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message132 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum131 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message130.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message130 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum130> enum_map = 5;\n  Enum130 status = 6;\n  repeated Enum131 flags = 7;\n  Message131 next = 8;\n  repeated Message132 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message133 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum132 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message131.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message131 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum131> enum_map = 5;\n  Enum131 status = 6;\n  repeated Enum132 flags = 7;\n  Message132 next = 8;\n  repeated Message133 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message134 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum133 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message132.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message132 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum132> enum_map = 5;\n  Enum132 status = 6;\n  repeated Enum133 flags = 7;\n  Message133 next = 8;\n  repeated Message134 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message135 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum134 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message133.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message133 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum133> enum_map = 5;\n  Enum133 status = 6;\n  repeated Enum134 flags = 7;\n  Message134 next = 8;\n  repeated Message135 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message136 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum135 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message134.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message134 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum134> enum_map = 5;\n  Enum134 status = 6;\n  repeated Enum135 flags = 7;\n  Message135 next = 8;\n  repeated Message136 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message137 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum136 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message135.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message135 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum135> enum_map = 5;\n  Enum135 status = 6;\n  repeated Enum136 flags = 7;\n  Message136 next = 8;\n  repeated Message137 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message138 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum137 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message136.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message136 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum136> enum_map = 5;\n  Enum136 status = 6;\n  repeated Enum137 flags = 7;\n  Message137 next = 8;\n  repeated Message138 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message139 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum138 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message137.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message137 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum137> enum_map = 5;\n  Enum137 status = 6;\n  repeated Enum138 flags = 7;\n  Message138 next = 8;\n  repeated Message139 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message140 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum139 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message138.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message138 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum138> enum_map = 5;\n  Enum138 status = 6;\n  repeated Enum139 flags = 7;\n  Message139 next = 8;\n  repeated Message140 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message141 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum140 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message139.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message139 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum139> enum_map = 5;\n  Enum139 status = 6;\n  repeated Enum140 flags = 7;\n  Message140 next = 8;\n  repeated Message141 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message142 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum141 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message140.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message140 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum140> enum_map = 5;\n  Enum140 status = 6;\n  repeated Enum141 flags = 7;\n  Message141 next = 8;\n  repeated Message142 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message143 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum142 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message141.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message141 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum141> enum_map = 5;\n  Enum141 status = 6;\n  repeated Enum142 flags = 7;\n  Message142 next = 8;\n  repeated Message143 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message144 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum143 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message142.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message142 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum142> enum_map = 5;\n  Enum142 status = 6;\n  repeated Enum143 flags = 7;\n  Message143 next = 8;\n  repeated Message144 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message145 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum144 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message143.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message143 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum143> enum_map = 5;\n  Enum143 status = 6;\n  repeated Enum144 flags = 7;\n  Message144 next = 8;\n  repeated Message145 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message146 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum145 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message144.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message144 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum144> enum_map = 5;\n  Enum144 status = 6;\n  repeated Enum145 flags = 7;\n  Message145 next = 8;\n  repeated Message146 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message147 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum146 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message145.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message145 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum145> enum_map = 5;\n  Enum145 status = 6;\n  repeated Enum146 flags = 7;\n  Message146 next = 8;\n  repeated Message147 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message148 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum147 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message146.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message146 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum146> enum_map = 5;\n  Enum146 status = 6;\n  repeated Enum147 flags = 7;\n  Message147 next = 8;\n  repeated Message148 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message149 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum148 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message147.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message147 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum147> enum_map = 5;\n  Enum147 status = 6;\n  repeated Enum148 flags = 7;\n  Message148 next = 8;\n  repeated Message149 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message150 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum149 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message148.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message148 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum148> enum_map = 5;\n  Enum148 status = 6;\n  repeated Enum149 flags = 7;\n  Message149 next = 8;\n  repeated Message150 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message151 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum150 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message149.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message149 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum149> enum_map = 5;\n  Enum149 status = 6;\n  repeated Enum150 flags = 7;\n  Message150 next = 8;\n  repeated Message151 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message152 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum151 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message150.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message150 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum150> enum_map = 5;\n  Enum150 status = 6;\n  repeated Enum151 flags = 7;\n  Message151 next = 8;\n  repeated Message152 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message153 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum152 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message151.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message151 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum151> enum_map = 5;\n  Enum151 status = 6;\n  repeated Enum152 flags = 7;\n  Message152 next = 8;\n  repeated Message153 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message154 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum153 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message152.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message152 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum152> enum_map = 5;\n  Enum152 status = 6;\n  repeated Enum153 flags = 7;\n  Message153 next = 8;\n  repeated Message154 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message155 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum154 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message153.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message153 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum153> enum_map = 5;\n  Enum153 status = 6;\n  repeated Enum154 flags = 7;\n  Message154 next = 8;\n  repeated Message155 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message156 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum155 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message154.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message154 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum154> enum_map = 5;\n  Enum154 status = 6;\n  repeated Enum155 flags = 7;\n  Message155 next = 8;\n  repeated Message156 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message157 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum156 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message155.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message155 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum155> enum_map = 5;\n  Enum155 status = 6;\n  repeated Enum156 flags = 7;\n  Message156 next = 8;\n  repeated Message157 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message158 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum157 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message156.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message156 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum156> enum_map = 5;\n  Enum156 status = 6;\n  repeated Enum157 flags = 7;\n  Message157 next = 8;\n  repeated Message158 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message159 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum158 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message157.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message157 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum157> enum_map = 5;\n  Enum157 status = 6;\n  repeated Enum158 flags = 7;\n  Message158 next = 8;\n  repeated Message159 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message160 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum159 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message158.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message158 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum158> enum_map = 5;\n  Enum158 status = 6;\n  repeated Enum159 flags = 7;\n  Message159 next = 8;\n  repeated Message160 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message161 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum160 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message159.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message159 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum159> enum_map = 5;\n  Enum159 status = 6;\n  repeated Enum160 flags = 7;\n  Message160 next = 8;\n  repeated Message161 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message162 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum161 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message160.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message160 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum160> enum_map = 5;\n  Enum160 status = 6;\n  repeated Enum161 flags = 7;\n  Message161 next = 8;\n  repeated Message162 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message163 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum162 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message161.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message161 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum161> enum_map = 5;\n  Enum161 status = 6;\n  repeated Enum162 flags = 7;\n  Message162 next = 8;\n  repeated Message163 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message164 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum163 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message162.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message162 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum162> enum_map = 5;\n  Enum162 status = 6;\n  repeated Enum163 flags = 7;\n  Message163 next = 8;\n  repeated Message164 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message165 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum164 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message163.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message163 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum163> enum_map = 5;\n  Enum163 status = 6;\n  repeated Enum164 flags = 7;\n  Message164 next = 8;\n  repeated Message165 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message166 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum165 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message164.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message164 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum164> enum_map = 5;\n  Enum164 status = 6;\n  repeated Enum165 flags = 7;\n  Message165 next = 8;\n  repeated Message166 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message167 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum166 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message165.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message165 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum165> enum_map = 5;\n  Enum165 status = 6;\n  repeated Enum166 flags = 7;\n  Message166 next = 8;\n  repeated Message167 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message168 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum167 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message166.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message166 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum166> enum_map = 5;\n  Enum166 status = 6;\n  repeated Enum167 flags = 7;\n  Message167 next = 8;\n  repeated Message168 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message169 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum168 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message167.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message167 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum167> enum_map = 5;\n  Enum167 status = 6;\n  repeated Enum168 flags = 7;\n  Message168 next = 8;\n  repeated Message169 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message170 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum169 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message168.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message168 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum168> enum_map = 5;\n  Enum168 status = 6;\n  repeated Enum169 flags = 7;\n  Message169 next = 8;\n  repeated Message170 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message171 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum170 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message169.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message169 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum169> enum_map = 5;\n  Enum169 status = 6;\n  repeated Enum170 flags = 7;\n  Message170 next = 8;\n  repeated Message171 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message172 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum171 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message170.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message170 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum170> enum_map = 5;\n  Enum170 status = 6;\n  repeated Enum171 flags = 7;\n  Message171 next = 8;\n  repeated Message172 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message173 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum172 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message171.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message171 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum171> enum_map = 5;\n  Enum171 status = 6;\n  repeated Enum172 flags = 7;\n  Message172 next = 8;\n  repeated Message173 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message174 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum173 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message172.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message172 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum172> enum_map = 5;\n  Enum172 status = 6;\n  repeated Enum173 flags = 7;\n  Message173 next = 8;\n  repeated Message174 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message175 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum174 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message173.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message173 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum173> enum_map = 5;\n  Enum173 status = 6;\n  repeated Enum174 flags = 7;\n  Message174 next = 8;\n  repeated Message175 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message176 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum175 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message174.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message174 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum174> enum_map = 5;\n  Enum174 status = 6;\n  repeated Enum175 flags = 7;\n  Message175 next = 8;\n  repeated Message176 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message177 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum176 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message175.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message175 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum175> enum_map = 5;\n  Enum175 status = 6;\n  repeated Enum176 flags = 7;\n  Message176 next = 8;\n  repeated Message177 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message178 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum177 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message176.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message176 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum176> enum_map = 5;\n  Enum176 status = 6;\n  repeated Enum177 flags = 7;\n  Message177 next = 8;\n  repeated Message178 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message179 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum178 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message177.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message177 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum177> enum_map = 5;\n  Enum177 status = 6;\n  repeated Enum178 flags = 7;\n  Message178 next = 8;\n  repeated Message179 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message180 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum179 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message178.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message178 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum178> enum_map = 5;\n  Enum178 status = 6;\n  repeated Enum179 flags = 7;\n  Message179 next = 8;\n  repeated Message180 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message181 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum180 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message179.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message179 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum179> enum_map = 5;\n  Enum179 status = 6;\n  repeated Enum180 flags = 7;\n  Message180 next = 8;\n  repeated Message181 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message182 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum181 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message180.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message180 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum180> enum_map = 5;\n  Enum180 status = 6;\n  repeated Enum181 flags = 7;\n  Message181 next = 8;\n  repeated Message182 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message183 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum182 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message181.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message181 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum181> enum_map = 5;\n  Enum181 status = 6;\n  repeated Enum182 flags = 7;\n  Message182 next = 8;\n  repeated Message183 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message184 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum183 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message182.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message182 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum182> enum_map = 5;\n  Enum182 status = 6;\n  repeated Enum183 flags = 7;\n  Message183 next = 8;\n  repeated Message184 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message185 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum184 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message183.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message183 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum183> enum_map = 5;\n  Enum183 status = 6;\n  repeated Enum184 flags = 7;\n  Message184 next = 8;\n  repeated Message185 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message186 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum185 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message184.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message184 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum184> enum_map = 5;\n  Enum184 status = 6;\n  repeated Enum185 flags = 7;\n  Message185 next = 8;\n  repeated Message186 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message187 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum186 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message185.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message185 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum185> enum_map = 5;\n  Enum185 status = 6;\n  repeated Enum186 flags = 7;\n  Message186 next = 8;\n  repeated Message187 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message188 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum187 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message186.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message186 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum186> enum_map = 5;\n  Enum186 status = 6;\n  repeated Enum187 flags = 7;\n  Message187 next = 8;\n  repeated Message188 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message189 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum188 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message187.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message187 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum187> enum_map = 5;\n  Enum187 status = 6;\n  repeated Enum188 flags = 7;\n  Message188 next = 8;\n  repeated Message189 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message190 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum189 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message188.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message188 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum188> enum_map = 5;\n  Enum188 status = 6;\n  repeated Enum189 flags = 7;\n  Message189 next = 8;\n  repeated Message190 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message191 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum190 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message189.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message189 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum189> enum_map = 5;\n  Enum189 status = 6;\n  repeated Enum190 flags = 7;\n  Message190 next = 8;\n  repeated Message191 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message192 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum191 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message190.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message190 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum190> enum_map = 5;\n  Enum190 status = 6;\n  repeated Enum191 flags = 7;\n  Message191 next = 8;\n  repeated Message192 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message193 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum192 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message191.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message191 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum191> enum_map = 5;\n  Enum191 status = 6;\n  repeated Enum192 flags = 7;\n  Message192 next = 8;\n  repeated Message193 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message194 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum193 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message192.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message192 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum192> enum_map = 5;\n  Enum192 status = 6;\n  repeated Enum193 flags = 7;\n  Message193 next = 8;\n  repeated Message194 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message195 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum194 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message193.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message193 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum193> enum_map = 5;\n  Enum193 status = 6;\n  repeated Enum194 flags = 7;\n  Message194 next = 8;\n  repeated Message195 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message196 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum195 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message194.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message194 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum194> enum_map = 5;\n  Enum194 status = 6;\n  repeated Enum195 flags = 7;\n  Message195 next = 8;\n  repeated Message196 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message197 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum196 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message195.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message195 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum195> enum_map = 5;\n  Enum195 status = 6;\n  repeated Enum196 flags = 7;\n  Message196 next = 8;\n  repeated Message197 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message198 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum197 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message196.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message196 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum196> enum_map = 5;\n  Enum196 status = 6;\n  repeated Enum197 flags = 7;\n  Message197 next = 8;\n  repeated Message198 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message199 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum198 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message197.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message197 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum197> enum_map = 5;\n  Enum197 status = 6;\n  repeated Enum198 flags = 7;\n  Message198 next = 8;\n  repeated Message199 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message200 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum199 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message198.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message198 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum198> enum_map = 5;\n  Enum198 status = 6;\n  repeated Enum199 flags = 7;\n  Message199 next = 8;\n  repeated Message200 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message201 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum0 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message199.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message199 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum199> enum_map = 5;\n  Enum199 status = 6;\n  repeated Enum0 flags = 7;\n  Message200 next = 8;\n  repeated Message201 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message202 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum1 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message200.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message200 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum0> enum_map = 5;\n  Enum0 status = 6;\n  repeated Enum1 flags = 7;\n  Message201 next = 8;\n  repeated Message202 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message203 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum2 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message201.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message201 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum1> enum_map = 5;\n  Enum1 status = 6;\n  repeated Enum2 flags = 7;\n  Message202 next = 8;\n  repeated Message203 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message204 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum3 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message202.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message202 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum2> enum_map = 5;\n  Enum2 status = 6;\n  repeated Enum3 flags = 7;\n  Message203 next = 8;\n  repeated Message204 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message205 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum4 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message203.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message203 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum3> enum_map = 5;\n  Enum3 status = 6;\n  repeated Enum4 flags = 7;\n  Message204 next = 8;\n  repeated Message205 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message206 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum5 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message204.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message204 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum4> enum_map = 5;\n  Enum4 status = 6;\n  repeated Enum5 flags = 7;\n  Message205 next = 8;\n  repeated Message206 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message207 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum6 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message205.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message205 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum5> enum_map = 5;\n  Enum5 status = 6;\n  repeated Enum6 flags = 7;\n  Message206 next = 8;\n  repeated Message207 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message208 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum7 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message206.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message206 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum6> enum_map = 5;\n  Enum6 status = 6;\n  repeated Enum7 flags = 7;\n  Message207 next = 8;\n  repeated Message208 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message209 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum8 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message207.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message207 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum7> enum_map = 5;\n  Enum7 status = 6;\n  repeated Enum8 flags = 7;\n  Message208 next = 8;\n  repeated Message209 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message210 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum9 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message208.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message208 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum8> enum_map = 5;\n  Enum8 status = 6;\n  repeated Enum9 flags = 7;\n  Message209 next = 8;\n  repeated Message210 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message211 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum10 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message209.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message209 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum9> enum_map = 5;\n  Enum9 status = 6;\n  repeated Enum10 flags = 7;\n  Message210 next = 8;\n  repeated Message211 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message212 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum11 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message210.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message210 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum10> enum_map = 5;\n  Enum10 status = 6;\n  repeated Enum11 flags = 7;\n  Message211 next = 8;\n  repeated Message212 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message213 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum12 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message211.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message211 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum11> enum_map = 5;\n  Enum11 status = 6;\n  repeated Enum12 flags = 7;\n  Message212 next = 8;\n  repeated Message213 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message214 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum13 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message212.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message212 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum12> enum_map = 5;\n  Enum12 status = 6;\n  repeated Enum13 flags = 7;\n  Message213 next = 8;\n  repeated Message214 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message215 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum14 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message213.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message213 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum13> enum_map = 5;\n  Enum13 status = 6;\n  repeated Enum14 flags = 7;\n  Message214 next = 8;\n  repeated Message215 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message216 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum15 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message214.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message214 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum14> enum_map = 5;\n  Enum14 status = 6;\n  repeated Enum15 flags = 7;\n  Message215 next = 8;\n  repeated Message216 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message217 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum16 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message215.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message215 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum15> enum_map = 5;\n  Enum15 status = 6;\n  repeated Enum16 flags = 7;\n  Message216 next = 8;\n  repeated Message217 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message218 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum17 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message216.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message216 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum16> enum_map = 5;\n  Enum16 status = 6;\n  repeated Enum17 flags = 7;\n  Message217 next = 8;\n  repeated Message218 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message219 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum18 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message217.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message217 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum17> enum_map = 5;\n  Enum17 status = 6;\n  repeated Enum18 flags = 7;\n  Message218 next = 8;\n  repeated Message219 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message220 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum19 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message218.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message218 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum18> enum_map = 5;\n  Enum18 status = 6;\n  repeated Enum19 flags = 7;\n  Message219 next = 8;\n  repeated Message220 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message221 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum20 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message219.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message219 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum19> enum_map = 5;\n  Enum19 status = 6;\n  repeated Enum20 flags = 7;\n  Message220 next = 8;\n  repeated Message221 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message222 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum21 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message220.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message220 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum20> enum_map = 5;\n  Enum20 status = 6;\n  repeated Enum21 flags = 7;\n  Message221 next = 8;\n  repeated Message222 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message223 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum22 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message221.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message221 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum21> enum_map = 5;\n  Enum21 status = 6;\n  repeated Enum22 flags = 7;\n  Message222 next = 8;\n  repeated Message223 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message224 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum23 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message222.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message222 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum22> enum_map = 5;\n  Enum22 status = 6;\n  repeated Enum23 flags = 7;\n  Message223 next = 8;\n  repeated Message224 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message225 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum24 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message223.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message223 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum23> enum_map = 5;\n  Enum23 status = 6;\n  repeated Enum24 flags = 7;\n  Message224 next = 8;\n  repeated Message225 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message226 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum25 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message224.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message224 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum24> enum_map = 5;\n  Enum24 status = 6;\n  repeated Enum25 flags = 7;\n  Message225 next = 8;\n  repeated Message226 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message227 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum26 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message225.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message225 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum25> enum_map = 5;\n  Enum25 status = 6;\n  repeated Enum26 flags = 7;\n  Message226 next = 8;\n  repeated Message227 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message228 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum27 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message226.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message226 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum26> enum_map = 5;\n  Enum26 status = 6;\n  repeated Enum27 flags = 7;\n  Message227 next = 8;\n  repeated Message228 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message229 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum28 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message227.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message227 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum27> enum_map = 5;\n  Enum27 status = 6;\n  repeated Enum28 flags = 7;\n  Message228 next = 8;\n  repeated Message229 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message230 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum29 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message228.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message228 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum28> enum_map = 5;\n  Enum28 status = 6;\n  repeated Enum29 flags = 7;\n  Message229 next = 8;\n  repeated Message230 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message231 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum30 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message229.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message229 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum29> enum_map = 5;\n  Enum29 status = 6;\n  repeated Enum30 flags = 7;\n  Message230 next = 8;\n  repeated Message231 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message232 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum31 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message230.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message230 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum30> enum_map = 5;\n  Enum30 status = 6;\n  repeated Enum31 flags = 7;\n  Message231 next = 8;\n  repeated Message232 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message233 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum32 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message231.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message231 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum31> enum_map = 5;\n  Enum31 status = 6;\n  repeated Enum32 flags = 7;\n  Message232 next = 8;\n  repeated Message233 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message234 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum33 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message232.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message232 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum32> enum_map = 5;\n  Enum32 status = 6;\n  repeated Enum33 flags = 7;\n  Message233 next = 8;\n  repeated Message234 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message235 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum34 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message233.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message233 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum33> enum_map = 5;\n  Enum33 status = 6;\n  repeated Enum34 flags = 7;\n  Message234 next = 8;\n  repeated Message235 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message236 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum35 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message234.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message234 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum34> enum_map = 5;\n  Enum34 status = 6;\n  repeated Enum35 flags = 7;\n  Message235 next = 8;\n  repeated Message236 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message237 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum36 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message235.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message235 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum35> enum_map = 5;\n  Enum35 status = 6;\n  repeated Enum36 flags = 7;\n  Message236 next = 8;\n  repeated Message237 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message238 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum37 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message236.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message236 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum36> enum_map = 5;\n  Enum36 status = 6;\n  repeated Enum37 flags = 7;\n  Message237 next = 8;\n  repeated Message238 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message239 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum38 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message237.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message237 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum37> enum_map = 5;\n  Enum37 status = 6;\n  repeated Enum38 flags = 7;\n  Message238 next = 8;\n  repeated Message239 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message240 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum39 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message238.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message238 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum38> enum_map = 5;\n  Enum38 status = 6;\n  repeated Enum39 flags = 7;\n  Message239 next = 8;\n  repeated Message240 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message241 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum40 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message239.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message239 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum39> enum_map = 5;\n  Enum39 status = 6;\n  repeated Enum40 flags = 7;\n  Message240 next = 8;\n  repeated Message241 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message242 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum41 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message240.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message240 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum40> enum_map = 5;\n  Enum40 status = 6;\n  repeated Enum41 flags = 7;\n  Message241 next = 8;\n  repeated Message242 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message243 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum42 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message241.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message241 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum41> enum_map = 5;\n  Enum41 status = 6;\n  repeated Enum42 flags = 7;\n  Message242 next = 8;\n  repeated Message243 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message244 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum43 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message242.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message242 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum42> enum_map = 5;\n  Enum42 status = 6;\n  repeated Enum43 flags = 7;\n  Message243 next = 8;\n  repeated Message244 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message245 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum44 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message243.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message243 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum43> enum_map = 5;\n  Enum43 status = 6;\n  repeated Enum44 flags = 7;\n  Message244 next = 8;\n  repeated Message245 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message246 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum45 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message244.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message244 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum44> enum_map = 5;\n  Enum44 status = 6;\n  repeated Enum45 flags = 7;\n  Message245 next = 8;\n  repeated Message246 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message247 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum46 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message245.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message245 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum45> enum_map = 5;\n  Enum45 status = 6;\n  repeated Enum46 flags = 7;\n  Message246 next = 8;\n  repeated Message247 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message248 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum47 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message246.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message246 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum46> enum_map = 5;\n  Enum46 status = 6;\n  repeated Enum47 flags = 7;\n  Message247 next = 8;\n  repeated Message248 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message249 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum48 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message247.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message247 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum47> enum_map = 5;\n  Enum47 status = 6;\n  repeated Enum48 flags = 7;\n  Message248 next = 8;\n  repeated Message249 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message250 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum49 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message248.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message248 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum48> enum_map = 5;\n  Enum48 status = 6;\n  repeated Enum49 flags = 7;\n  Message249 next = 8;\n  repeated Message250 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message251 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum50 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message249.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message249 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum49> enum_map = 5;\n  Enum49 status = 6;\n  repeated Enum50 flags = 7;\n  Message250 next = 8;\n  repeated Message251 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message252 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum51 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message250.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message250 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum50> enum_map = 5;\n  Enum50 status = 6;\n  repeated Enum51 flags = 7;\n  Message251 next = 8;\n  repeated Message252 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message253 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum52 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message251.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message251 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum51> enum_map = 5;\n  Enum51 status = 6;\n  repeated Enum52 flags = 7;\n  Message252 next = 8;\n  repeated Message253 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message254 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum53 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message252.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message252 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum52> enum_map = 5;\n  Enum52 status = 6;\n  repeated Enum53 flags = 7;\n  Message253 next = 8;\n  repeated Message254 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message255 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum54 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message253.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message253 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum53> enum_map = 5;\n  Enum53 status = 6;\n  repeated Enum54 flags = 7;\n  Message254 next = 8;\n  repeated Message255 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message256 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum55 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message254.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message254 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum54> enum_map = 5;\n  Enum54 status = 6;\n  repeated Enum55 flags = 7;\n  Message255 next = 8;\n  repeated Message256 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message257 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum56 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message255.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message255 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum55> enum_map = 5;\n  Enum55 status = 6;\n  repeated Enum56 flags = 7;\n  Message256 next = 8;\n  repeated Message257 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message258 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum57 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message256.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message256 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum56> enum_map = 5;\n  Enum56 status = 6;\n  repeated Enum57 flags = 7;\n  Message257 next = 8;\n  repeated Message258 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message259 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum58 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message257.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message257 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum57> enum_map = 5;\n  Enum57 status = 6;\n  repeated Enum58 flags = 7;\n  Message258 next = 8;\n  repeated Message259 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message260 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum59 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message258.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message258 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum58> enum_map = 5;\n  Enum58 status = 6;\n  repeated Enum59 flags = 7;\n  Message259 next = 8;\n  repeated Message260 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message261 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum60 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message259.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message259 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum59> enum_map = 5;\n  Enum59 status = 6;\n  repeated Enum60 flags = 7;\n  Message260 next = 8;\n  repeated Message261 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message262 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum61 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message260.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message260 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum60> enum_map = 5;\n  Enum60 status = 6;\n  repeated Enum61 flags = 7;\n  Message261 next = 8;\n  repeated Message262 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message263 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum62 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message261.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message261 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum61> enum_map = 5;\n  Enum61 status = 6;\n  repeated Enum62 flags = 7;\n  Message262 next = 8;\n  repeated Message263 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message264 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum63 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message262.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message262 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum62> enum_map = 5;\n  Enum62 status = 6;\n  repeated Enum63 flags = 7;\n  Message263 next = 8;\n  repeated Message264 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message265 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum64 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message263.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message263 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum63> enum_map = 5;\n  Enum63 status = 6;\n  repeated Enum64 flags = 7;\n  Message264 next = 8;\n  repeated Message265 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message266 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum65 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message264.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message264 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum64> enum_map = 5;\n  Enum64 status = 6;\n  repeated Enum65 flags = 7;\n  Message265 next = 8;\n  repeated Message266 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message267 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum66 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message265.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message265 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum65> enum_map = 5;\n  Enum65 status = 6;\n  repeated Enum66 flags = 7;\n  Message266 next = 8;\n  repeated Message267 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message268 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum67 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message266.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message266 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum66> enum_map = 5;\n  Enum66 status = 6;\n  repeated Enum67 flags = 7;\n  Message267 next = 8;\n  repeated Message268 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message269 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum68 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message267.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message267 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum67> enum_map = 5;\n  Enum67 status = 6;\n  repeated Enum68 flags = 7;\n  Message268 next = 8;\n  repeated Message269 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message270 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum69 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message268.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message268 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum68> enum_map = 5;\n  Enum68 status = 6;\n  repeated Enum69 flags = 7;\n  Message269 next = 8;\n  repeated Message270 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message271 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum70 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message269.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message269 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum69> enum_map = 5;\n  Enum69 status = 6;\n  repeated Enum70 flags = 7;\n  Message270 next = 8;\n  repeated Message271 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message272 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum71 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message270.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message270 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum70> enum_map = 5;\n  Enum70 status = 6;\n  repeated Enum71 flags = 7;\n  Message271 next = 8;\n  repeated Message272 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message273 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum72 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message271.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message271 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum71> enum_map = 5;\n  Enum71 status = 6;\n  repeated Enum72 flags = 7;\n  Message272 next = 8;\n  repeated Message273 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message274 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum73 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message272.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message272 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum72> enum_map = 5;\n  Enum72 status = 6;\n  repeated Enum73 flags = 7;\n  Message273 next = 8;\n  repeated Message274 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message275 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum74 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message273.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message273 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum73> enum_map = 5;\n  Enum73 status = 6;\n  repeated Enum74 flags = 7;\n  Message274 next = 8;\n  repeated Message275 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message276 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum75 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message274.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message274 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum74> enum_map = 5;\n  Enum74 status = 6;\n  repeated Enum75 flags = 7;\n  Message275 next = 8;\n  repeated Message276 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message277 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum76 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message275.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message275 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum75> enum_map = 5;\n  Enum75 status = 6;\n  repeated Enum76 flags = 7;\n  Message276 next = 8;\n  repeated Message277 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message278 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum77 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message276.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message276 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum76> enum_map = 5;\n  Enum76 status = 6;\n  repeated Enum77 flags = 7;\n  Message277 next = 8;\n  repeated Message278 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message279 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum78 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message277.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message277 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum77> enum_map = 5;\n  Enum77 status = 6;\n  repeated Enum78 flags = 7;\n  Message278 next = 8;\n  repeated Message279 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message280 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum79 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message278.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message278 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum78> enum_map = 5;\n  Enum78 status = 6;\n  repeated Enum79 flags = 7;\n  Message279 next = 8;\n  repeated Message280 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message281 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum80 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message279.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message279 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum79> enum_map = 5;\n  Enum79 status = 6;\n  repeated Enum80 flags = 7;\n  Message280 next = 8;\n  repeated Message281 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message282 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum81 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message280.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message280 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum80> enum_map = 5;\n  Enum80 status = 6;\n  repeated Enum81 flags = 7;\n  Message281 next = 8;\n  repeated Message282 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message283 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum82 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message281.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message281 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum81> enum_map = 5;\n  Enum81 status = 6;\n  repeated Enum82 flags = 7;\n  Message282 next = 8;\n  repeated Message283 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message284 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum83 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message282.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message282 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum82> enum_map = 5;\n  Enum82 status = 6;\n  repeated Enum83 flags = 7;\n  Message283 next = 8;\n  repeated Message284 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message285 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum84 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message283.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message283 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum83> enum_map = 5;\n  Enum83 status = 6;\n  repeated Enum84 flags = 7;\n  Message284 next = 8;\n  repeated Message285 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message286 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum85 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message284.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message284 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum84> enum_map = 5;\n  Enum84 status = 6;\n  repeated Enum85 flags = 7;\n  Message285 next = 8;\n  repeated Message286 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message287 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum86 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message285.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message285 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum85> enum_map = 5;\n  Enum85 status = 6;\n  repeated Enum86 flags = 7;\n  Message286 next = 8;\n  repeated Message287 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message288 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum87 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message286.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message286 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum86> enum_map = 5;\n  Enum86 status = 6;\n  repeated Enum87 flags = 7;\n  Message287 next = 8;\n  repeated Message288 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message289 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum88 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message287.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message287 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum87> enum_map = 5;\n  Enum87 status = 6;\n  repeated Enum88 flags = 7;\n  Message288 next = 8;\n  repeated Message289 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message290 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum89 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message288.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message288 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum88> enum_map = 5;\n  Enum88 status = 6;\n  repeated Enum89 flags = 7;\n  Message289 next = 8;\n  repeated Message290 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message291 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum90 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message289.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message289 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum89> enum_map = 5;\n  Enum89 status = 6;\n  repeated Enum90 flags = 7;\n  Message290 next = 8;\n  repeated Message291 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message292 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum91 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message290.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message290 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum90> enum_map = 5;\n  Enum90 status = 6;\n  repeated Enum91 flags = 7;\n  Message291 next = 8;\n  repeated Message292 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message293 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum92 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message291.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message291 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum91> enum_map = 5;\n  Enum91 status = 6;\n  repeated Enum92 flags = 7;\n  Message292 next = 8;\n  repeated Message293 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message294 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum93 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message292.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message292 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum92> enum_map = 5;\n  Enum92 status = 6;\n  repeated Enum93 flags = 7;\n  Message293 next = 8;\n  repeated Message294 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message295 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum94 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message293.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message293 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum93> enum_map = 5;\n  Enum93 status = 6;\n  repeated Enum94 flags = 7;\n  Message294 next = 8;\n  repeated Message295 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message296 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum95 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message294.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message294 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum94> enum_map = 5;\n  Enum94 status = 6;\n  repeated Enum95 flags = 7;\n  Message295 next = 8;\n  repeated Message296 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message297 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum96 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message295.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message295 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum95> enum_map = 5;\n  Enum95 status = 6;\n  repeated Enum96 flags = 7;\n  Message296 next = 8;\n  repeated Message297 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message298 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum97 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message296.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message296 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum96> enum_map = 5;\n  Enum96 status = 6;\n  repeated Enum97 flags = 7;\n  Message297 next = 8;\n  repeated Message298 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message299 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum98 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message297.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message297 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum97> enum_map = 5;\n  Enum97 status = 6;\n  repeated Enum98 flags = 7;\n  Message298 next = 8;\n  repeated Message299 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message300 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum99 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message298.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message298 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum98> enum_map = 5;\n  Enum98 status = 6;\n  repeated Enum99 flags = 7;\n  Message299 next = 8;\n  repeated Message300 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message301 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum100 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message299.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message299 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum99> enum_map = 5;\n  Enum99 status = 6;\n  repeated Enum100 flags = 7;\n  Message300 next = 8;\n  repeated Message301 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message302 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum101 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message300.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message300 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum100> enum_map = 5;\n  Enum100 status = 6;\n  repeated Enum101 flags = 7;\n  Message301 next = 8;\n  repeated Message302 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message303 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum102 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message301.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message301 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum101> enum_map = 5;\n  Enum101 status = 6;\n  repeated Enum102 flags = 7;\n  Message302 next = 8;\n  repeated Message303 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message304 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum103 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message302.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message302 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum102> enum_map = 5;\n  Enum102 status = 6;\n  repeated Enum103 flags = 7;\n  Message303 next = 8;\n  repeated Message304 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message305 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum104 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message303.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message303 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum103> enum_map = 5;\n  Enum103 status = 6;\n  repeated Enum104 flags = 7;\n  Message304 next = 8;\n  repeated Message305 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message306 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum105 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message304.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message304 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum104> enum_map = 5;\n  Enum104 status = 6;\n  repeated Enum105 flags = 7;\n  Message305 next = 8;\n  repeated Message306 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message307 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum106 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message305.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message305 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum105> enum_map = 5;\n  Enum105 status = 6;\n  repeated Enum106 flags = 7;\n  Message306 next = 8;\n  repeated Message307 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message308 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum107 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message306.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message306 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum106> enum_map = 5;\n  Enum106 status = 6;\n  repeated Enum107 flags = 7;\n  Message307 next = 8;\n  repeated Message308 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message309 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum108 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message307.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message307 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum107> enum_map = 5;\n  Enum107 status = 6;\n  repeated Enum108 flags = 7;\n  Message308 next = 8;\n  repeated Message309 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message310 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum109 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message308.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message308 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum108> enum_map = 5;\n  Enum108 status = 6;\n  repeated Enum109 flags = 7;\n  Message309 next = 8;\n  repeated Message310 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message311 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum110 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message309.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message309 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum109> enum_map = 5;\n  Enum109 status = 6;\n  repeated Enum110 flags = 7;\n  Message310 next = 8;\n  repeated Message311 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message312 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum111 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message310.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message310 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum110> enum_map = 5;\n  Enum110 status = 6;\n  repeated Enum111 flags = 7;\n  Message311 next = 8;\n  repeated Message312 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message313 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum112 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message311.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message311 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum111> enum_map = 5;\n  Enum111 status = 6;\n  repeated Enum112 flags = 7;\n  Message312 next = 8;\n  repeated Message313 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message314 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum113 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message312.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message312 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum112> enum_map = 5;\n  Enum112 status = 6;\n  repeated Enum113 flags = 7;\n  Message313 next = 8;\n  repeated Message314 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message315 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum114 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message313.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message313 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum113> enum_map = 5;\n  Enum113 status = 6;\n  repeated Enum114 flags = 7;\n  Message314 next = 8;\n  repeated Message315 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message316 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum115 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message314.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message314 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum114> enum_map = 5;\n  Enum114 status = 6;\n  repeated Enum115 flags = 7;\n  Message315 next = 8;\n  repeated Message316 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message317 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum116 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message315.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message315 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum115> enum_map = 5;\n  Enum115 status = 6;\n  repeated Enum116 flags = 7;\n  Message316 next = 8;\n  repeated Message317 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message318 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum117 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message316.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message316 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum116> enum_map = 5;\n  Enum116 status = 6;\n  repeated Enum117 flags = 7;\n  Message317 next = 8;\n  repeated Message318 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message319 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum118 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message317.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message317 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum117> enum_map = 5;\n  Enum117 status = 6;\n  repeated Enum118 flags = 7;\n  Message318 next = 8;\n  repeated Message319 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message320 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum119 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message318.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message318 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum118> enum_map = 5;\n  Enum118 status = 6;\n  repeated Enum119 flags = 7;\n  Message319 next = 8;\n  repeated Message320 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message321 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum120 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message319.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message319 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum119> enum_map = 5;\n  Enum119 status = 6;\n  repeated Enum120 flags = 7;\n  Message320 next = 8;\n  repeated Message321 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message322 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum121 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message320.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message320 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum120> enum_map = 5;\n  Enum120 status = 6;\n  repeated Enum121 flags = 7;\n  Message321 next = 8;\n  repeated Message322 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message323 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum122 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message321.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message321 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum121> enum_map = 5;\n  Enum121 status = 6;\n  repeated Enum122 flags = 7;\n  Message322 next = 8;\n  repeated Message323 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message324 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum123 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message322.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message322 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum122> enum_map = 5;\n  Enum122 status = 6;\n  repeated Enum123 flags = 7;\n  Message323 next = 8;\n  repeated Message324 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message325 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum124 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message323.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message323 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum123> enum_map = 5;\n  Enum123 status = 6;\n  repeated Enum124 flags = 7;\n  Message324 next = 8;\n  repeated Message325 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message326 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum125 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message324.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message324 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum124> enum_map = 5;\n  Enum124 status = 6;\n  repeated Enum125 flags = 7;\n  Message325 next = 8;\n  repeated Message326 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message327 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum126 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message325.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message325 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum125> enum_map = 5;\n  Enum125 status = 6;\n  repeated Enum126 flags = 7;\n  Message326 next = 8;\n  repeated Message327 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message328 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum127 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message326.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message326 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum126> enum_map = 5;\n  Enum126 status = 6;\n  repeated Enum127 flags = 7;\n  Message327 next = 8;\n  repeated Message328 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message329 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum128 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message327.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message327 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum127> enum_map = 5;\n  Enum127 status = 6;\n  repeated Enum128 flags = 7;\n  Message328 next = 8;\n  repeated Message329 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message330 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum129 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message328.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message328 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum128> enum_map = 5;\n  Enum128 status = 6;\n  repeated Enum129 flags = 7;\n  Message329 next = 8;\n  repeated Message330 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message331 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum130 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message329.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message329 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum129> enum_map = 5;\n  Enum129 status = 6;\n  repeated Enum130 flags = 7;\n  Message330 next = 8;\n  repeated Message331 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message332 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum131 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message330.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message330 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum130> enum_map = 5;\n  Enum130 status = 6;\n  repeated Enum131 flags = 7;\n  Message331 next = 8;\n  repeated Message332 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message333 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum132 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message331.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message331 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum131> enum_map = 5;\n  Enum131 status = 6;\n  repeated Enum132 flags = 7;\n  Message332 next = 8;\n  repeated Message333 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message334 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum133 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message332.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message332 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum132> enum_map = 5;\n  Enum132 status = 6;\n  repeated Enum133 flags = 7;\n  Message333 next = 8;\n  repeated Message334 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message335 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum134 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message333.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message333 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum133> enum_map = 5;\n  Enum133 status = 6;\n  repeated Enum134 flags = 7;\n  Message334 next = 8;\n  repeated Message335 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message336 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum135 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message334.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message334 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum134> enum_map = 5;\n  Enum134 status = 6;\n  repeated Enum135 flags = 7;\n  Message335 next = 8;\n  repeated Message336 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message337 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum136 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message335.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message335 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum135> enum_map = 5;\n  Enum135 status = 6;\n  repeated Enum136 flags = 7;\n  Message336 next = 8;\n  repeated Message337 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message338 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum137 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message336.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message336 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum136> enum_map = 5;\n  Enum136 status = 6;\n  repeated Enum137 flags = 7;\n  Message337 next = 8;\n  repeated Message338 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message339 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum138 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message337.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message337 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum137> enum_map = 5;\n  Enum137 status = 6;\n  repeated Enum138 flags = 7;\n  Message338 next = 8;\n  repeated Message339 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message340 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum139 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message338.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message338 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum138> enum_map = 5;\n  Enum138 status = 6;\n  repeated Enum139 flags = 7;\n  Message339 next = 8;\n  repeated Message340 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message341 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum140 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message339.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message339 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum139> enum_map = 5;\n  Enum139 status = 6;\n  repeated Enum140 flags = 7;\n  Message340 next = 8;\n  repeated Message341 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message342 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum141 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message340.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message340 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum140> enum_map = 5;\n  Enum140 status = 6;\n  repeated Enum141 flags = 7;\n  Message341 next = 8;\n  repeated Message342 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message343 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum142 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message341.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message341 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum141> enum_map = 5;\n  Enum141 status = 6;\n  repeated Enum142 flags = 7;\n  Message342 next = 8;\n  repeated Message343 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message344 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum143 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message342.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message342 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum142> enum_map = 5;\n  Enum142 status = 6;\n  repeated Enum143 flags = 7;\n  Message343 next = 8;\n  repeated Message344 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message345 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum144 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message343.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message343 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum143> enum_map = 5;\n  Enum143 status = 6;\n  repeated Enum144 flags = 7;\n  Message344 next = 8;\n  repeated Message345 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message346 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum145 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message344.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message344 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum144> enum_map = 5;\n  Enum144 status = 6;\n  repeated Enum145 flags = 7;\n  Message345 next = 8;\n  repeated Message346 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message347 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum146 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message345.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message345 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum145> enum_map = 5;\n  Enum145 status = 6;\n  repeated Enum146 flags = 7;\n  Message346 next = 8;\n  repeated Message347 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message348 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum147 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message346.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message346 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum146> enum_map = 5;\n  Enum146 status = 6;\n  repeated Enum147 flags = 7;\n  Message347 next = 8;\n  repeated Message348 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message349 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum148 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message347.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message347 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum147> enum_map = 5;\n  Enum147 status = 6;\n  repeated Enum148 flags = 7;\n  Message348 next = 8;\n  repeated Message349 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message350 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum149 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message348.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message348 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum148> enum_map = 5;\n  Enum148 status = 6;\n  repeated Enum149 flags = 7;\n  Message349 next = 8;\n  repeated Message350 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message351 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum150 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message349.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message349 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum149> enum_map = 5;\n  Enum149 status = 6;\n  repeated Enum150 flags = 7;\n  Message350 next = 8;\n  repeated Message351 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message352 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum151 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message350.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message350 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum150> enum_map = 5;\n  Enum150 status = 6;\n  repeated Enum151 flags = 7;\n  Message351 next = 8;\n  repeated Message352 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message353 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum152 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message351.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message351 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum151> enum_map = 5;\n  Enum151 status = 6;\n  repeated Enum152 flags = 7;\n  Message352 next = 8;\n  repeated Message353 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message354 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum153 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message352.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message352 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum152> enum_map = 5;\n  Enum152 status = 6;\n  repeated Enum153 flags = 7;\n  Message353 next = 8;\n  repeated Message354 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message355 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum154 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message353.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message353 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum153> enum_map = 5;\n  Enum153 status = 6;\n  repeated Enum154 flags = 7;\n  Message354 next = 8;\n  repeated Message355 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message356 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum155 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message354.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message354 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum154> enum_map = 5;\n  Enum154 status = 6;\n  repeated Enum155 flags = 7;\n  Message355 next = 8;\n  repeated Message356 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message357 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum156 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message355.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message355 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum155> enum_map = 5;\n  Enum155 status = 6;\n  repeated Enum156 flags = 7;\n  Message356 next = 8;\n  repeated Message357 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message358 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum157 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message356.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message356 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum156> enum_map = 5;\n  Enum156 status = 6;\n  repeated Enum157 flags = 7;\n  Message357 next = 8;\n  repeated Message358 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message359 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum158 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message357.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message357 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum157> enum_map = 5;\n  Enum157 status = 6;\n  repeated Enum158 flags = 7;\n  Message358 next = 8;\n  repeated Message359 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message360 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum159 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message358.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message358 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum158> enum_map = 5;\n  Enum158 status = 6;\n  repeated Enum159 flags = 7;\n  Message359 next = 8;\n  repeated Message360 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message361 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum160 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message359.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message359 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum159> enum_map = 5;\n  Enum159 status = 6;\n  repeated Enum160 flags = 7;\n  Message360 next = 8;\n  repeated Message361 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message362 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum161 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message360.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message360 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum160> enum_map = 5;\n  Enum160 status = 6;\n  repeated Enum161 flags = 7;\n  Message361 next = 8;\n  repeated Message362 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message363 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum162 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message361.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message361 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum161> enum_map = 5;\n  Enum161 status = 6;\n  repeated Enum162 flags = 7;\n  Message362 next = 8;\n  repeated Message363 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message364 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum163 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message362.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message362 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum162> enum_map = 5;\n  Enum162 status = 6;\n  repeated Enum163 flags = 7;\n  Message363 next = 8;\n  repeated Message364 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message365 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum164 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message363.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message363 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum163> enum_map = 5;\n  Enum163 status = 6;\n  repeated Enum164 flags = 7;\n  Message364 next = 8;\n  repeated Message365 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message366 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum165 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message364.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message364 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum164> enum_map = 5;\n  Enum164 status = 6;\n  repeated Enum165 flags = 7;\n  Message365 next = 8;\n  repeated Message366 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message367 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum166 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message365.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message365 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum165> enum_map = 5;\n  Enum165 status = 6;\n  repeated Enum166 flags = 7;\n  Message366 next = 8;\n  repeated Message367 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message368 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum167 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message366.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message366 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum166> enum_map = 5;\n  Enum166 status = 6;\n  repeated Enum167 flags = 7;\n  Message367 next = 8;\n  repeated Message368 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message369 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum168 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message367.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message367 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum167> enum_map = 5;\n  Enum167 status = 6;\n  repeated Enum168 flags = 7;\n  Message368 next = 8;\n  repeated Message369 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message370 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum169 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message368.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message368 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum168> enum_map = 5;\n  Enum168 status = 6;\n  repeated Enum169 flags = 7;\n  Message369 next = 8;\n  repeated Message370 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message371 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum170 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message369.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message369 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum169> enum_map = 5;\n  Enum169 status = 6;\n  repeated Enum170 flags = 7;\n  Message370 next = 8;\n  repeated Message371 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message372 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum171 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message370.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message370 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum170> enum_map = 5;\n  Enum170 status = 6;\n  repeated Enum171 flags = 7;\n  Message371 next = 8;\n  repeated Message372 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message373 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum172 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message371.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message371 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum171> enum_map = 5;\n  Enum171 status = 6;\n  repeated Enum172 flags = 7;\n  Message372 next = 8;\n  repeated Message373 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message374 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum173 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message372.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message372 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum172> enum_map = 5;\n  Enum172 status = 6;\n  repeated Enum173 flags = 7;\n  Message373 next = 8;\n  repeated Message374 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message375 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum174 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message373.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message373 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum173> enum_map = 5;\n  Enum173 status = 6;\n  repeated Enum174 flags = 7;\n  Message374 next = 8;\n  repeated Message375 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message376 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum175 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message374.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message374 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum174> enum_map = 5;\n  Enum174 status = 6;\n  repeated Enum175 flags = 7;\n  Message375 next = 8;\n  repeated Message376 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message377 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum176 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message375.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message375 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum175> enum_map = 5;\n  Enum175 status = 6;\n  repeated Enum176 flags = 7;\n  Message376 next = 8;\n  repeated Message377 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message378 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum177 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message376.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message376 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum176> enum_map = 5;\n  Enum176 status = 6;\n  repeated Enum177 flags = 7;\n  Message377 next = 8;\n  repeated Message378 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message379 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum178 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message377.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message377 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum177> enum_map = 5;\n  Enum177 status = 6;\n  repeated Enum178 flags = 7;\n  Message378 next = 8;\n  repeated Message379 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message380 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum179 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message378.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message378 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum178> enum_map = 5;\n  Enum178 status = 6;\n  repeated Enum179 flags = 7;\n  Message379 next = 8;\n  repeated Message380 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message381 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum180 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message379.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message379 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum179> enum_map = 5;\n  Enum179 status = 6;\n  repeated Enum180 flags = 7;\n  Message380 next = 8;\n  repeated Message381 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message382 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum181 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message380.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message380 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum180> enum_map = 5;\n  Enum180 status = 6;\n  repeated Enum181 flags = 7;\n  Message381 next = 8;\n  repeated Message382 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message383 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum182 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message381.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message381 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum181> enum_map = 5;\n  Enum181 status = 6;\n  repeated Enum182 flags = 7;\n  Message382 next = 8;\n  repeated Message383 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message384 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum183 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message382.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message382 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum182> enum_map = 5;\n  Enum182 status = 6;\n  repeated Enum183 flags = 7;\n  Message383 next = 8;\n  repeated Message384 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message385 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum184 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message383.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message383 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum183> enum_map = 5;\n  Enum183 status = 6;\n  repeated Enum184 flags = 7;\n  Message384 next = 8;\n  repeated Message385 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message386 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum185 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message384.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message384 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum184> enum_map = 5;\n  Enum184 status = 6;\n  repeated Enum185 flags = 7;\n  Message385 next = 8;\n  repeated Message386 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message387 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum186 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message385.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message385 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum185> enum_map = 5;\n  Enum185 status = 6;\n  repeated Enum186 flags = 7;\n  Message386 next = 8;\n  repeated Message387 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message388 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum187 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message386.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message386 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum186> enum_map = 5;\n  Enum186 status = 6;\n  repeated Enum187 flags = 7;\n  Message387 next = 8;\n  repeated Message388 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message389 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum188 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message387.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message387 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum187> enum_map = 5;\n  Enum187 status = 6;\n  repeated Enum188 flags = 7;\n  Message388 next = 8;\n  repeated Message389 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message390 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum189 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message388.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message388 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum188> enum_map = 5;\n  Enum188 status = 6;\n  repeated Enum189 flags = 7;\n  Message389 next = 8;\n  repeated Message390 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message391 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum190 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message389.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message389 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum189> enum_map = 5;\n  Enum189 status = 6;\n  repeated Enum190 flags = 7;\n  Message390 next = 8;\n  repeated Message391 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message392 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum191 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message390.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message390 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum190> enum_map = 5;\n  Enum190 status = 6;\n  repeated Enum191 flags = 7;\n  Message391 next = 8;\n  repeated Message392 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message393 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum192 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message391.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message391 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum191> enum_map = 5;\n  Enum191 status = 6;\n  repeated Enum192 flags = 7;\n  Message392 next = 8;\n  repeated Message393 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message394 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum193 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message392.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message392 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum192> enum_map = 5;\n  Enum192 status = 6;\n  repeated Enum193 flags = 7;\n  Message393 next = 8;\n  repeated Message394 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message395 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum194 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message393.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message393 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum193> enum_map = 5;\n  Enum193 status = 6;\n  repeated Enum194 flags = 7;\n  Message394 next = 8;\n  repeated Message395 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message396 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum195 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message394.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message394 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum194> enum_map = 5;\n  Enum194 status = 6;\n  repeated Enum195 flags = 7;\n  Message395 next = 8;\n  repeated Message396 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message397 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum196 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message395.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message395 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum195> enum_map = 5;\n  Enum195 status = 6;\n  repeated Enum196 flags = 7;\n  Message396 next = 8;\n  repeated Message397 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message398 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum197 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message396.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message396 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum196> enum_map = 5;\n  Enum196 status = 6;\n  repeated Enum197 flags = 7;\n  Message397 next = 8;\n  repeated Message398 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message399 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum198 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message397.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message397 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum197> enum_map = 5;\n  Enum197 status = 6;\n  repeated Enum198 flags = 7;\n  Message398 next = 8;\n  repeated Message399 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message400 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum199 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message398.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message398 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum198> enum_map = 5;\n  Enum198 status = 6;\n  repeated Enum199 flags = 7;\n  Message399 next = 8;\n  repeated Message400 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message401 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum0 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message399.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message399 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum199> enum_map = 5;\n  Enum199 status = 6;\n  repeated Enum0 flags = 7;\n  Message400 next = 8;\n  repeated Message401 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message402 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum1 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message400.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message400 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum0> enum_map = 5;\n  Enum0 status = 6;\n  repeated Enum1 flags = 7;\n  Message401 next = 8;\n  repeated Message402 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message403 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum2 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message401.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message401 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum1> enum_map = 5;\n  Enum1 status = 6;\n  repeated Enum2 flags = 7;\n  Message402 next = 8;\n  repeated Message403 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message404 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum3 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message402.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message402 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum2> enum_map = 5;\n  Enum2 status = 6;\n  repeated Enum3 flags = 7;\n  Message403 next = 8;\n  repeated Message404 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message405 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum4 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message403.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message403 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum3> enum_map = 5;\n  Enum3 status = 6;\n  repeated Enum4 flags = 7;\n  Message404 next = 8;\n  repeated Message405 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message406 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum5 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message404.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message404 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum4> enum_map = 5;\n  Enum4 status = 6;\n  repeated Enum5 flags = 7;\n  Message405 next = 8;\n  repeated Message406 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message407 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum6 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message405.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message405 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum5> enum_map = 5;\n  Enum5 status = 6;\n  repeated Enum6 flags = 7;\n  Message406 next = 8;\n  repeated Message407 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message408 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum7 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message406.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message406 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum6> enum_map = 5;\n  Enum6 status = 6;\n  repeated Enum7 flags = 7;\n  Message407 next = 8;\n  repeated Message408 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message409 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum8 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message407.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message407 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum7> enum_map = 5;\n  Enum7 status = 6;\n  repeated Enum8 flags = 7;\n  Message408 next = 8;\n  repeated Message409 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message410 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum9 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message408.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message408 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum8> enum_map = 5;\n  Enum8 status = 6;\n  repeated Enum9 flags = 7;\n  Message409 next = 8;\n  repeated Message410 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message411 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum10 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message409.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message409 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum9> enum_map = 5;\n  Enum9 status = 6;\n  repeated Enum10 flags = 7;\n  Message410 next = 8;\n  repeated Message411 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message412 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum11 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message410.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message410 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum10> enum_map = 5;\n  Enum10 status = 6;\n  repeated Enum11 flags = 7;\n  Message411 next = 8;\n  repeated Message412 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message413 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum12 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message411.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message411 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum11> enum_map = 5;\n  Enum11 status = 6;\n  repeated Enum12 flags = 7;\n  Message412 next = 8;\n  repeated Message413 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message414 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum13 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message412.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message412 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum12> enum_map = 5;\n  Enum12 status = 6;\n  repeated Enum13 flags = 7;\n  Message413 next = 8;\n  repeated Message414 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message415 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum14 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message413.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message413 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum13> enum_map = 5;\n  Enum13 status = 6;\n  repeated Enum14 flags = 7;\n  Message414 next = 8;\n  repeated Message415 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message416 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum15 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message414.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message414 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum14> enum_map = 5;\n  Enum14 status = 6;\n  repeated Enum15 flags = 7;\n  Message415 next = 8;\n  repeated Message416 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message417 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum16 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message415.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message415 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum15> enum_map = 5;\n  Enum15 status = 6;\n  repeated Enum16 flags = 7;\n  Message416 next = 8;\n  repeated Message417 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message418 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum17 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message416.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message416 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum16> enum_map = 5;\n  Enum16 status = 6;\n  repeated Enum17 flags = 7;\n  Message417 next = 8;\n  repeated Message418 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message419 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum18 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message417.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message417 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum17> enum_map = 5;\n  Enum17 status = 6;\n  repeated Enum18 flags = 7;\n  Message418 next = 8;\n  repeated Message419 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message420 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum19 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message418.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message418 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum18> enum_map = 5;\n  Enum18 status = 6;\n  repeated Enum19 flags = 7;\n  Message419 next = 8;\n  repeated Message420 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message421 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum20 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message419.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message419 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum19> enum_map = 5;\n  Enum19 status = 6;\n  repeated Enum20 flags = 7;\n  Message420 next = 8;\n  repeated Message421 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message422 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum21 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message420.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message420 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum20> enum_map = 5;\n  Enum20 status = 6;\n  repeated Enum21 flags = 7;\n  Message421 next = 8;\n  repeated Message422 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message423 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum22 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message421.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message421 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum21> enum_map = 5;\n  Enum21 status = 6;\n  repeated Enum22 flags = 7;\n  Message422 next = 8;\n  repeated Message423 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message424 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum23 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message422.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message422 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum22> enum_map = 5;\n  Enum22 status = 6;\n  repeated Enum23 flags = 7;\n  Message423 next = 8;\n  repeated Message424 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message425 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum24 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message423.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message423 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum23> enum_map = 5;\n  Enum23 status = 6;\n  repeated Enum24 flags = 7;\n  Message424 next = 8;\n  repeated Message425 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message426 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum25 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message424.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message424 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum24> enum_map = 5;\n  Enum24 status = 6;\n  repeated Enum25 flags = 7;\n  Message425 next = 8;\n  repeated Message426 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message427 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum26 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message425.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message425 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum25> enum_map = 5;\n  Enum25 status = 6;\n  repeated Enum26 flags = 7;\n  Message426 next = 8;\n  repeated Message427 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message428 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum27 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message426.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message426 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum26> enum_map = 5;\n  Enum26 status = 6;\n  repeated Enum27 flags = 7;\n  Message427 next = 8;\n  repeated Message428 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message429 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum28 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message427.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message427 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum27> enum_map = 5;\n  Enum27 status = 6;\n  repeated Enum28 flags = 7;\n  Message428 next = 8;\n  repeated Message429 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message430 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum29 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message428.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message428 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum28> enum_map = 5;\n  Enum28 status = 6;\n  repeated Enum29 flags = 7;\n  Message429 next = 8;\n  repeated Message430 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message431 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum30 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message429.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message429 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum29> enum_map = 5;\n  Enum29 status = 6;\n  repeated Enum30 flags = 7;\n  Message430 next = 8;\n  repeated Message431 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message432 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum31 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message430.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message430 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum30> enum_map = 5;\n  Enum30 status = 6;\n  repeated Enum31 flags = 7;\n  Message431 next = 8;\n  repeated Message432 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message433 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum32 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message431.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message431 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum31> enum_map = 5;\n  Enum31 status = 6;\n  repeated Enum32 flags = 7;\n  Message432 next = 8;\n  repeated Message433 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message434 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum33 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message432.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message432 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum32> enum_map = 5;\n  Enum32 status = 6;\n  repeated Enum33 flags = 7;\n  Message433 next = 8;\n  repeated Message434 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message435 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum34 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message433.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message433 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum33> enum_map = 5;\n  Enum33 status = 6;\n  repeated Enum34 flags = 7;\n  Message434 next = 8;\n  repeated Message435 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message436 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum35 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message434.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message434 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum34> enum_map = 5;\n  Enum34 status = 6;\n  repeated Enum35 flags = 7;\n  Message435 next = 8;\n  repeated Message436 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message437 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum36 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message435.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message435 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum35> enum_map = 5;\n  Enum35 status = 6;\n  repeated Enum36 flags = 7;\n  Message436 next = 8;\n  repeated Message437 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message438 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum37 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message436.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message436 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum36> enum_map = 5;\n  Enum36 status = 6;\n  repeated Enum37 flags = 7;\n  Message437 next = 8;\n  repeated Message438 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message439 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum38 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message437.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message437 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum37> enum_map = 5;\n  Enum37 status = 6;\n  repeated Enum38 flags = 7;\n  Message438 next = 8;\n  repeated Message439 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message440 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum39 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message438.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message438 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum38> enum_map = 5;\n  Enum38 status = 6;\n  repeated Enum39 flags = 7;\n  Message439 next = 8;\n  repeated Message440 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message441 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum40 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message439.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message439 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum39> enum_map = 5;\n  Enum39 status = 6;\n  repeated Enum40 flags = 7;\n  Message440 next = 8;\n  repeated Message441 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message442 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum41 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message440.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message440 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum40> enum_map = 5;\n  Enum40 status = 6;\n  repeated Enum41 flags = 7;\n  Message441 next = 8;\n  repeated Message442 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message443 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum42 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message441.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message441 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum41> enum_map = 5;\n  Enum41 status = 6;\n  repeated Enum42 flags = 7;\n  Message442 next = 8;\n  repeated Message443 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message444 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum43 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message442.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message442 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum42> enum_map = 5;\n  Enum42 status = 6;\n  repeated Enum43 flags = 7;\n  Message443 next = 8;\n  repeated Message444 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message445 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum44 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message443.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message443 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum43> enum_map = 5;\n  Enum43 status = 6;\n  repeated Enum44 flags = 7;\n  Message444 next = 8;\n  repeated Message445 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message446 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum45 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message444.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message444 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum44> enum_map = 5;\n  Enum44 status = 6;\n  repeated Enum45 flags = 7;\n  Message445 next = 8;\n  repeated Message446 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message447 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum46 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message445.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message445 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum45> enum_map = 5;\n  Enum45 status = 6;\n  repeated Enum46 flags = 7;\n  Message446 next = 8;\n  repeated Message447 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message448 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum47 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message446.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message446 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum46> enum_map = 5;\n  Enum46 status = 6;\n  repeated Enum47 flags = 7;\n  Message447 next = 8;\n  repeated Message448 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message449 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum48 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message447.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message447 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum47> enum_map = 5;\n  Enum47 status = 6;\n  repeated Enum48 flags = 7;\n  Message448 next = 8;\n  repeated Message449 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message450 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum49 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message448.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message448 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum48> enum_map = 5;\n  Enum48 status = 6;\n  repeated Enum49 flags = 7;\n  Message449 next = 8;\n  repeated Message450 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message451 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum50 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message449.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message449 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum49> enum_map = 5;\n  Enum49 status = 6;\n  repeated Enum50 flags = 7;\n  Message450 next = 8;\n  repeated Message451 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message452 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum51 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message450.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message450 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum50> enum_map = 5;\n  Enum50 status = 6;\n  repeated Enum51 flags = 7;\n  Message451 next = 8;\n  repeated Message452 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message453 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum52 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message451.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message451 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum51> enum_map = 5;\n  Enum51 status = 6;\n  repeated Enum52 flags = 7;\n  Message452 next = 8;\n  repeated Message453 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message454 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum53 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message452.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message452 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum52> enum_map = 5;\n  Enum52 status = 6;\n  repeated Enum53 flags = 7;\n  Message453 next = 8;\n  repeated Message454 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message455 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum54 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message453.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message453 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum53> enum_map = 5;\n  Enum53 status = 6;\n  repeated Enum54 flags = 7;\n  Message454 next = 8;\n  repeated Message455 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message456 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum55 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message454.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message454 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum54> enum_map = 5;\n  Enum54 status = 6;\n  repeated Enum55 flags = 7;\n  Message455 next = 8;\n  repeated Message456 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message457 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum56 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message455.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message455 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum55> enum_map = 5;\n  Enum55 status = 6;\n  repeated Enum56 flags = 7;\n  Message456 next = 8;\n  repeated Message457 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message458 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum57 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message456.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message456 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum56> enum_map = 5;\n  Enum56 status = 6;\n  repeated Enum57 flags = 7;\n  Message457 next = 8;\n  repeated Message458 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message459 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum58 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message457.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message457 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum57> enum_map = 5;\n  Enum57 status = 6;\n  repeated Enum58 flags = 7;\n  Message458 next = 8;\n  repeated Message459 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message460 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum59 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message458.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message458 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum58> enum_map = 5;\n  Enum58 status = 6;\n  repeated Enum59 flags = 7;\n  Message459 next = 8;\n  repeated Message460 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message461 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum60 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message459.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message459 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum59> enum_map = 5;\n  Enum59 status = 6;\n  repeated Enum60 flags = 7;\n  Message460 next = 8;\n  repeated Message461 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message462 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum61 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message460.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message460 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum60> enum_map = 5;\n  Enum60 status = 6;\n  repeated Enum61 flags = 7;\n  Message461 next = 8;\n  repeated Message462 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message463 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum62 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message461.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message461 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum61> enum_map = 5;\n  Enum61 status = 6;\n  repeated Enum62 flags = 7;\n  Message462 next = 8;\n  repeated Message463 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message464 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum63 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message462.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message462 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum62> enum_map = 5;\n  Enum62 status = 6;\n  repeated Enum63 flags = 7;\n  Message463 next = 8;\n  repeated Message464 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message465 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum64 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message463.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message463 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum63> enum_map = 5;\n  Enum63 status = 6;\n  repeated Enum64 flags = 7;\n  Message464 next = 8;\n  repeated Message465 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message466 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum65 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message464.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message464 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum64> enum_map = 5;\n  Enum64 status = 6;\n  repeated Enum65 flags = 7;\n  Message465 next = 8;\n  repeated Message466 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message467 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum66 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message465.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message465 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum65> enum_map = 5;\n  Enum65 status = 6;\n  repeated Enum66 flags = 7;\n  Message466 next = 8;\n  repeated Message467 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message468 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum67 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message466.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message466 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum66> enum_map = 5;\n  Enum66 status = 6;\n  repeated Enum67 flags = 7;\n  Message467 next = 8;\n  repeated Message468 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message469 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum68 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message467.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message467 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum67> enum_map = 5;\n  Enum67 status = 6;\n  repeated Enum68 flags = 7;\n  Message468 next = 8;\n  repeated Message469 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message470 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum69 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message468.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message468 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum68> enum_map = 5;\n  Enum68 status = 6;\n  repeated Enum69 flags = 7;\n  Message469 next = 8;\n  repeated Message470 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message471 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum70 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message469.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message469 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum69> enum_map = 5;\n  Enum69 status = 6;\n  repeated Enum70 flags = 7;\n  Message470 next = 8;\n  repeated Message471 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message472 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum71 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message470.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message470 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum70> enum_map = 5;\n  Enum70 status = 6;\n  repeated Enum71 flags = 7;\n  Message471 next = 8;\n  repeated Message472 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message473 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum72 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message471.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message471 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum71> enum_map = 5;\n  Enum71 status = 6;\n  repeated Enum72 flags = 7;\n  Message472 next = 8;\n  repeated Message473 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message474 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum73 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message472.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message472 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum72> enum_map = 5;\n  Enum72 status = 6;\n  repeated Enum73 flags = 7;\n  Message473 next = 8;\n  repeated Message474 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message475 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum74 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message473.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message473 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum73> enum_map = 5;\n  Enum73 status = 6;\n  repeated Enum74 flags = 7;\n  Message474 next = 8;\n  repeated Message475 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message476 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum75 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message474.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message474 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum74> enum_map = 5;\n  Enum74 status = 6;\n  repeated Enum75 flags = 7;\n  Message475 next = 8;\n  repeated Message476 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message477 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum76 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message475.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message475 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum75> enum_map = 5;\n  Enum75 status = 6;\n  repeated Enum76 flags = 7;\n  Message476 next = 8;\n  repeated Message477 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message478 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum77 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message476.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message476 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum76> enum_map = 5;\n  Enum76 status = 6;\n  repeated Enum77 flags = 7;\n  Message477 next = 8;\n  repeated Message478 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message479 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum78 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message477.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message477 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum77> enum_map = 5;\n  Enum77 status = 6;\n  repeated Enum78 flags = 7;\n  Message478 next = 8;\n  repeated Message479 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message480 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum79 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message478.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message478 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum78> enum_map = 5;\n  Enum78 status = 6;\n  repeated Enum79 flags = 7;\n  Message479 next = 8;\n  repeated Message480 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message481 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum80 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message479.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message479 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum79> enum_map = 5;\n  Enum79 status = 6;\n  repeated Enum80 flags = 7;\n  Message480 next = 8;\n  repeated Message481 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message482 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum81 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message480.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message480 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum80> enum_map = 5;\n  Enum80 status = 6;\n  repeated Enum81 flags = 7;\n  Message481 next = 8;\n  repeated Message482 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message483 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum82 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message481.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message481 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum81> enum_map = 5;\n  Enum81 status = 6;\n  repeated Enum82 flags = 7;\n  Message482 next = 8;\n  repeated Message483 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message484 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum83 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message482.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message482 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum82> enum_map = 5;\n  Enum82 status = 6;\n  repeated Enum83 flags = 7;\n  Message483 next = 8;\n  repeated Message484 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message485 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum84 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message483.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message483 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum83> enum_map = 5;\n  Enum83 status = 6;\n  repeated Enum84 flags = 7;\n  Message484 next = 8;\n  repeated Message485 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message486 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum85 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message484.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message484 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum84> enum_map = 5;\n  Enum84 status = 6;\n  repeated Enum85 flags = 7;\n  Message485 next = 8;\n  repeated Message486 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message487 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum86 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message485.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message485 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum85> enum_map = 5;\n  Enum85 status = 6;\n  repeated Enum86 flags = 7;\n  Message486 next = 8;\n  repeated Message487 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message488 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum87 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message486.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message486 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum86> enum_map = 5;\n  Enum86 status = 6;\n  repeated Enum87 flags = 7;\n  Message487 next = 8;\n  repeated Message488 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message489 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum88 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message487.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message487 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum87> enum_map = 5;\n  Enum87 status = 6;\n  repeated Enum88 flags = 7;\n  Message488 next = 8;\n  repeated Message489 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message490 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum89 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message488.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message488 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum88> enum_map = 5;\n  Enum88 status = 6;\n  repeated Enum89 flags = 7;\n  Message489 next = 8;\n  repeated Message490 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message491 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum90 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message489.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message489 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum89> enum_map = 5;\n  Enum89 status = 6;\n  repeated Enum90 flags = 7;\n  Message490 next = 8;\n  repeated Message491 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message492 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum91 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message490.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message490 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum90> enum_map = 5;\n  Enum90 status = 6;\n  repeated Enum91 flags = 7;\n  Message491 next = 8;\n  repeated Message492 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message493 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum92 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message491.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message491 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum91> enum_map = 5;\n  Enum91 status = 6;\n  repeated Enum92 flags = 7;\n  Message492 next = 8;\n  repeated Message493 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message494 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum93 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message492.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message492 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum92> enum_map = 5;\n  Enum92 status = 6;\n  repeated Enum93 flags = 7;\n  Message493 next = 8;\n  repeated Message494 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message495 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum94 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message493.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message493 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum93> enum_map = 5;\n  Enum93 status = 6;\n  repeated Enum94 flags = 7;\n  Message494 next = 8;\n  repeated Message495 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message496 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum95 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message494.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message494 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum94> enum_map = 5;\n  Enum94 status = 6;\n  repeated Enum95 flags = 7;\n  Message495 next = 8;\n  repeated Message496 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message497 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum96 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message495.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message495 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum95> enum_map = 5;\n  Enum95 status = 6;\n  repeated Enum96 flags = 7;\n  Message496 next = 8;\n  repeated Message497 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message498 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum97 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message496.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message496 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum96> enum_map = 5;\n  Enum96 status = 6;\n  repeated Enum97 flags = 7;\n  Message497 next = 8;\n  repeated Message498 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message499 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum98 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message497.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message497 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum97> enum_map = 5;\n  Enum97 status = 6;\n  repeated Enum98 flags = 7;\n  Message498 next = 8;\n  repeated Message499 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message500 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum99 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message498.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message498 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum98> enum_map = 5;\n  Enum98 status = 6;\n  repeated Enum99 flags = 7;\n  Message499 next = 8;\n  repeated Message500 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message501 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum100 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message499.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message499 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum99> enum_map = 5;\n  Enum99 status = 6;\n  repeated Enum100 flags = 7;\n  Message500 next = 8;\n  repeated Message501 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message502 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum101 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message500.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message500 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum100> enum_map = 5;\n  Enum100 status = 6;\n  repeated Enum101 flags = 7;\n  Message501 next = 8;\n  repeated Message502 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message503 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum102 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message501.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message501 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum101> enum_map = 5;\n  Enum101 status = 6;\n  repeated Enum102 flags = 7;\n  Message502 next = 8;\n  repeated Message503 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message504 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum103 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message502.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message502 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum102> enum_map = 5;\n  Enum102 status = 6;\n  repeated Enum103 flags = 7;\n  Message503 next = 8;\n  repeated Message504 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message505 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum104 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message503.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message503 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum103> enum_map = 5;\n  Enum103 status = 6;\n  repeated Enum104 flags = 7;\n  Message504 next = 8;\n  repeated Message505 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message506 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum105 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message504.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message504 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum104> enum_map = 5;\n  Enum104 status = 6;\n  repeated Enum105 flags = 7;\n  Message505 next = 8;\n  repeated Message506 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message507 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum106 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message505.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message505 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum105> enum_map = 5;\n  Enum105 status = 6;\n  repeated Enum106 flags = 7;\n  Message506 next = 8;\n  repeated Message507 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message508 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum107 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message506.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message506 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum106> enum_map = 5;\n  Enum106 status = 6;\n  repeated Enum107 flags = 7;\n  Message507 next = 8;\n  repeated Message508 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message509 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum108 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message507.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message507 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum107> enum_map = 5;\n  Enum107 status = 6;\n  repeated Enum108 flags = 7;\n  Message508 next = 8;\n  repeated Message509 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message510 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum109 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message508.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message508 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum108> enum_map = 5;\n  Enum108 status = 6;\n  repeated Enum109 flags = 7;\n  Message509 next = 8;\n  repeated Message510 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message511 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum110 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message509.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message509 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum109> enum_map = 5;\n  Enum109 status = 6;\n  repeated Enum110 flags = 7;\n  Message510 next = 8;\n  repeated Message511 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message512 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum111 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message510.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message510 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum110> enum_map = 5;\n  Enum110 status = 6;\n  repeated Enum111 flags = 7;\n  Message511 next = 8;\n  repeated Message512 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message513 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum112 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message511.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message511 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum111> enum_map = 5;\n  Enum111 status = 6;\n  repeated Enum112 flags = 7;\n  Message512 next = 8;\n  repeated Message513 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message514 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum113 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message512.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message512 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum112> enum_map = 5;\n  Enum112 status = 6;\n  repeated Enum113 flags = 7;\n  Message513 next = 8;\n  repeated Message514 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message515 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum114 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message513.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message513 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum113> enum_map = 5;\n  Enum113 status = 6;\n  repeated Enum114 flags = 7;\n  Message514 next = 8;\n  repeated Message515 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message516 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum115 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message514.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message514 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum114> enum_map = 5;\n  Enum114 status = 6;\n  repeated Enum115 flags = 7;\n  Message515 next = 8;\n  repeated Message516 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message517 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum116 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message515.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message515 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum115> enum_map = 5;\n  Enum115 status = 6;\n  repeated Enum116 flags = 7;\n  Message516 next = 8;\n  repeated Message517 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message518 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum117 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message516.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message516 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum116> enum_map = 5;\n  Enum116 status = 6;\n  repeated Enum117 flags = 7;\n  Message517 next = 8;\n  repeated Message518 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message519 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum118 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message517.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message517 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum117> enum_map = 5;\n  Enum117 status = 6;\n  repeated Enum118 flags = 7;\n  Message518 next = 8;\n  repeated Message519 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message520 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum119 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message518.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message518 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum118> enum_map = 5;\n  Enum118 status = 6;\n  repeated Enum119 flags = 7;\n  Message519 next = 8;\n  repeated Message520 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message521 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum120 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message519.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message519 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum119> enum_map = 5;\n  Enum119 status = 6;\n  repeated Enum120 flags = 7;\n  Message520 next = 8;\n  repeated Message521 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message522 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum121 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message520.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message520 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum120> enum_map = 5;\n  Enum120 status = 6;\n  repeated Enum121 flags = 7;\n  Message521 next = 8;\n  repeated Message522 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message523 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum122 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message521.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message521 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum121> enum_map = 5;\n  Enum121 status = 6;\n  repeated Enum122 flags = 7;\n  Message522 next = 8;\n  repeated Message523 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message524 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum123 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message522.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message522 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum122> enum_map = 5;\n  Enum122 status = 6;\n  repeated Enum123 flags = 7;\n  Message523 next = 8;\n  repeated Message524 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message525 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum124 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message523.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message523 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum123> enum_map = 5;\n  Enum123 status = 6;\n  repeated Enum124 flags = 7;\n  Message524 next = 8;\n  repeated Message525 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message526 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum125 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message524.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message524 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum124> enum_map = 5;\n  Enum124 status = 6;\n  repeated Enum125 flags = 7;\n  Message525 next = 8;\n  repeated Message526 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message527 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum126 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message525.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message525 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum125> enum_map = 5;\n  Enum125 status = 6;\n  repeated Enum126 flags = 7;\n  Message526 next = 8;\n  repeated Message527 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message528 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum127 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message526.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message526 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum126> enum_map = 5;\n  Enum126 status = 6;\n  repeated Enum127 flags = 7;\n  Message527 next = 8;\n  repeated Message528 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message529 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum128 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message527.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message527 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum127> enum_map = 5;\n  Enum127 status = 6;\n  repeated Enum128 flags = 7;\n  Message528 next = 8;\n  repeated Message529 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message530 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum129 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message528.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message528 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum128> enum_map = 5;\n  Enum128 status = 6;\n  repeated Enum129 flags = 7;\n  Message529 next = 8;\n  repeated Message530 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message531 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum130 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message529.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message529 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum129> enum_map = 5;\n  Enum129 status = 6;\n  repeated Enum130 flags = 7;\n  Message530 next = 8;\n  repeated Message531 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message532 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum131 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message530.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message530 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum130> enum_map = 5;\n  Enum130 status = 6;\n  repeated Enum131 flags = 7;\n  Message531 next = 8;\n  repeated Message532 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message533 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum132 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message531.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message531 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum131> enum_map = 5;\n  Enum131 status = 6;\n  repeated Enum132 flags = 7;\n  Message532 next = 8;\n  repeated Message533 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message534 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum133 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message532.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message532 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum132> enum_map = 5;\n  Enum132 status = 6;\n  repeated Enum133 flags = 7;\n  Message533 next = 8;\n  repeated Message534 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message535 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum134 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message533.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message533 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum133> enum_map = 5;\n  Enum133 status = 6;\n  repeated Enum134 flags = 7;\n  Message534 next = 8;\n  repeated Message535 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message536 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum135 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message534.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message534 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum134> enum_map = 5;\n  Enum134 status = 6;\n  repeated Enum135 flags = 7;\n  Message535 next = 8;\n  repeated Message536 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message537 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum136 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message535.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message535 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum135> enum_map = 5;\n  Enum135 status = 6;\n  repeated Enum136 flags = 7;\n  Message536 next = 8;\n  repeated Message537 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message538 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum137 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message536.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message536 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum136> enum_map = 5;\n  Enum136 status = 6;\n  repeated Enum137 flags = 7;\n  Message537 next = 8;\n  repeated Message538 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message539 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum138 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message537.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message537 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum137> enum_map = 5;\n  Enum137 status = 6;\n  repeated Enum138 flags = 7;\n  Message538 next = 8;\n  repeated Message539 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message540 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum139 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message538.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message538 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum138> enum_map = 5;\n  Enum138 status = 6;\n  repeated Enum139 flags = 7;\n  Message539 next = 8;\n  repeated Message540 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message541 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum140 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message539.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message539 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum139> enum_map = 5;\n  Enum139 status = 6;\n  repeated Enum140 flags = 7;\n  Message540 next = 8;\n  repeated Message541 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message542 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum141 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message540.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message540 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum140> enum_map = 5;\n  Enum140 status = 6;\n  repeated Enum141 flags = 7;\n  Message541 next = 8;\n  repeated Message542 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message543 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum142 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message541.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message541 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum141> enum_map = 5;\n  Enum141 status = 6;\n  repeated Enum142 flags = 7;\n  Message542 next = 8;\n  repeated Message543 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message544 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum143 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message542.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message542 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum142> enum_map = 5;\n  Enum142 status = 6;\n  repeated Enum143 flags = 7;\n  Message543 next = 8;\n  repeated Message544 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message545 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum144 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message543.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message543 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum143> enum_map = 5;\n  Enum143 status = 6;\n  repeated Enum144 flags = 7;\n  Message544 next = 8;\n  repeated Message545 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message546 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum145 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message544.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message544 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum144> enum_map = 5;\n  Enum144 status = 6;\n  repeated Enum145 flags = 7;\n  Message545 next = 8;\n  repeated Message546 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message547 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum146 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message545.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message545 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum145> enum_map = 5;\n  Enum145 status = 6;\n  repeated Enum146 flags = 7;\n  Message546 next = 8;\n  repeated Message547 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message548 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum147 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message546.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message546 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum146> enum_map = 5;\n  Enum146 status = 6;\n  repeated Enum147 flags = 7;\n  Message547 next = 8;\n  repeated Message548 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message549 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum148 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message547.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message547 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum147> enum_map = 5;\n  Enum147 status = 6;\n  repeated Enum148 flags = 7;\n  Message548 next = 8;\n  repeated Message549 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message550 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum149 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message548.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message548 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum148> enum_map = 5;\n  Enum148 status = 6;\n  repeated Enum149 flags = 7;\n  Message549 next = 8;\n  repeated Message550 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message551 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum150 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message549.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message549 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum149> enum_map = 5;\n  Enum149 status = 6;\n  repeated Enum150 flags = 7;\n  Message550 next = 8;\n  repeated Message551 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message552 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum151 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message550.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message550 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum150> enum_map = 5;\n  Enum150 status = 6;\n  repeated Enum151 flags = 7;\n  Message551 next = 8;\n  repeated Message552 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message553 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum152 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message551.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message551 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum151> enum_map = 5;\n  Enum151 status = 6;\n  repeated Enum152 flags = 7;\n  Message552 next = 8;\n  repeated Message553 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message554 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum153 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message552.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message552 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum152> enum_map = 5;\n  Enum152 status = 6;\n  repeated Enum153 flags = 7;\n  Message553 next = 8;\n  repeated Message554 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message555 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum154 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message553.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message553 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum153> enum_map = 5;\n  Enum153 status = 6;\n  repeated Enum154 flags = 7;\n  Message554 next = 8;\n  repeated Message555 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message556 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum155 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message554.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message554 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum154> enum_map = 5;\n  Enum154 status = 6;\n  repeated Enum155 flags = 7;\n  Message555 next = 8;\n  repeated Message556 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message557 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum156 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message555.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message555 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum155> enum_map = 5;\n  Enum155 status = 6;\n  repeated Enum156 flags = 7;\n  Message556 next = 8;\n  repeated Message557 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message558 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum157 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message556.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message556 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum156> enum_map = 5;\n  Enum156 status = 6;\n  repeated Enum157 flags = 7;\n  Message557 next = 8;\n  repeated Message558 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message559 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum158 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message557.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message557 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum157> enum_map = 5;\n  Enum157 status = 6;\n  repeated Enum158 flags = 7;\n  Message558 next = 8;\n  repeated Message559 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message560 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum159 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message558.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message558 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum158> enum_map = 5;\n  Enum158 status = 6;\n  repeated Enum159 flags = 7;\n  Message559 next = 8;\n  repeated Message560 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message561 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum160 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message559.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message559 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum159> enum_map = 5;\n  Enum159 status = 6;\n  repeated Enum160 flags = 7;\n  Message560 next = 8;\n  repeated Message561 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message562 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum161 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message560.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message560 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum160> enum_map = 5;\n  Enum160 status = 6;\n  repeated Enum161 flags = 7;\n  Message561 next = 8;\n  repeated Message562 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message563 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum162 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message561.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message561 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum161> enum_map = 5;\n  Enum161 status = 6;\n  repeated Enum162 flags = 7;\n  Message562 next = 8;\n  repeated Message563 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message564 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum163 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message562.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message562 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum162> enum_map = 5;\n  Enum162 status = 6;\n  repeated Enum163 flags = 7;\n  Message563 next = 8;\n  repeated Message564 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message565 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum164 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message563.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message563 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum163> enum_map = 5;\n  Enum163 status = 6;\n  repeated Enum164 flags = 7;\n  Message564 next = 8;\n  repeated Message565 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message566 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum165 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message564.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message564 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum164> enum_map = 5;\n  Enum164 status = 6;\n  repeated Enum165 flags = 7;\n  Message565 next = 8;\n  repeated Message566 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message567 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum166 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message565.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message565 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum165> enum_map = 5;\n  Enum165 status = 6;\n  repeated Enum166 flags = 7;\n  Message566 next = 8;\n  repeated Message567 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message568 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum167 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message566.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message566 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum166> enum_map = 5;\n  Enum166 status = 6;\n  repeated Enum167 flags = 7;\n  Message567 next = 8;\n  repeated Message568 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message569 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum168 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message567.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message567 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum167> enum_map = 5;\n  Enum167 status = 6;\n  repeated Enum168 flags = 7;\n  Message568 next = 8;\n  repeated Message569 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message570 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum169 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message568.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message568 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum168> enum_map = 5;\n  Enum168 status = 6;\n  repeated Enum169 flags = 7;\n  Message569 next = 8;\n  repeated Message570 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message571 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum170 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message569.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message569 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum169> enum_map = 5;\n  Enum169 status = 6;\n  repeated Enum170 flags = 7;\n  Message570 next = 8;\n  repeated Message571 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message572 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum171 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message570.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message570 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum170> enum_map = 5;\n  Enum170 status = 6;\n  repeated Enum171 flags = 7;\n  Message571 next = 8;\n  repeated Message572 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message573 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum172 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message571.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message571 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum171> enum_map = 5;\n  Enum171 status = 6;\n  repeated Enum172 flags = 7;\n  Message572 next = 8;\n  repeated Message573 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message574 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum173 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message572.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message572 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum172> enum_map = 5;\n  Enum172 status = 6;\n  repeated Enum173 flags = 7;\n  Message573 next = 8;\n  repeated Message574 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message575 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum174 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message573.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message573 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum173> enum_map = 5;\n  Enum173 status = 6;\n  repeated Enum174 flags = 7;\n  Message574 next = 8;\n  repeated Message575 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message576 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum175 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message574.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message574 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum174> enum_map = 5;\n  Enum174 status = 6;\n  repeated Enum175 flags = 7;\n  Message575 next = 8;\n  repeated Message576 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message577 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum176 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message575.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message575 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum175> enum_map = 5;\n  Enum175 status = 6;\n  repeated Enum176 flags = 7;\n  Message576 next = 8;\n  repeated Message577 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message578 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum177 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message576.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message576 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum176> enum_map = 5;\n  Enum176 status = 6;\n  repeated Enum177 flags = 7;\n  Message577 next = 8;\n  repeated Message578 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message579 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum178 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message577.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message577 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum177> enum_map = 5;\n  Enum177 status = 6;\n  repeated Enum178 flags = 7;\n  Message578 next = 8;\n  repeated Message579 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message580 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum179 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message578.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message578 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum178> enum_map = 5;\n  Enum178 status = 6;\n  repeated Enum179 flags = 7;\n  Message579 next = 8;\n  repeated Message580 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message581 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum180 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message579.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message579 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum179> enum_map = 5;\n  Enum179 status = 6;\n  repeated Enum180 flags = 7;\n  Message580 next = 8;\n  repeated Message581 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message582 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum181 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message580.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message580 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum180> enum_map = 5;\n  Enum180 status = 6;\n  repeated Enum181 flags = 7;\n  Message581 next = 8;\n  repeated Message582 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message583 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum182 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message581.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message581 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum181> enum_map = 5;\n  Enum181 status = 6;\n  repeated Enum182 flags = 7;\n  Message582 next = 8;\n  repeated Message583 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message584 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum183 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message582.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message582 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum182> enum_map = 5;\n  Enum182 status = 6;\n  repeated Enum183 flags = 7;\n  Message583 next = 8;\n  repeated Message584 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message585 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum184 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message583.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message583 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum183> enum_map = 5;\n  Enum183 status = 6;\n  repeated Enum184 flags = 7;\n  Message584 next = 8;\n  repeated Message585 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message586 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum185 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message584.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message584 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum184> enum_map = 5;\n  Enum184 status = 6;\n  repeated Enum185 flags = 7;\n  Message585 next = 8;\n  repeated Message586 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message587 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum186 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message585.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message585 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum185> enum_map = 5;\n  Enum185 status = 6;\n  repeated Enum186 flags = 7;\n  Message586 next = 8;\n  repeated Message587 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message588 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum187 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message586.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message586 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum186> enum_map = 5;\n  Enum186 status = 6;\n  repeated Enum187 flags = 7;\n  Message587 next = 8;\n  repeated Message588 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message589 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum188 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message587.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message587 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum187> enum_map = 5;\n  Enum187 status = 6;\n  repeated Enum188 flags = 7;\n  Message588 next = 8;\n  repeated Message589 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message590 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum189 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message588.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message588 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum188> enum_map = 5;\n  Enum188 status = 6;\n  repeated Enum189 flags = 7;\n  Message589 next = 8;\n  repeated Message590 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message591 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum190 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message589.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message589 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum189> enum_map = 5;\n  Enum189 status = 6;\n  repeated Enum190 flags = 7;\n  Message590 next = 8;\n  repeated Message591 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message592 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum191 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message590.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message590 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum190> enum_map = 5;\n  Enum190 status = 6;\n  repeated Enum191 flags = 7;\n  Message591 next = 8;\n  repeated Message592 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message593 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum192 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message591.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message591 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum191> enum_map = 5;\n  Enum191 status = 6;\n  repeated Enum192 flags = 7;\n  Message592 next = 8;\n  repeated Message593 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message594 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum193 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message592.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message592 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum192> enum_map = 5;\n  Enum192 status = 6;\n  repeated Enum193 flags = 7;\n  Message593 next = 8;\n  repeated Message594 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message595 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum194 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message593.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message593 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum193> enum_map = 5;\n  Enum193 status = 6;\n  repeated Enum194 flags = 7;\n  Message594 next = 8;\n  repeated Message595 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message596 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum195 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message594.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message594 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum194> enum_map = 5;\n  Enum194 status = 6;\n  repeated Enum195 flags = 7;\n  Message595 next = 8;\n  repeated Message596 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message597 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum196 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message595.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message595 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum195> enum_map = 5;\n  Enum195 status = 6;\n  repeated Enum196 flags = 7;\n  Message596 next = 8;\n  repeated Message597 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message598 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum197 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message596.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message596 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum196> enum_map = 5;\n  Enum196 status = 6;\n  repeated Enum197 flags = 7;\n  Message597 next = 8;\n  repeated Message598 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message599 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum198 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message597.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message597 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum197> enum_map = 5;\n  Enum197 status = 6;\n  repeated Enum198 flags = 7;\n  Message598 next = 8;\n  repeated Message599 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message600 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum199 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message598.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message598 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum198> enum_map = 5;\n  Enum198 status = 6;\n  repeated Enum199 flags = 7;\n  Message599 next = 8;\n  repeated Message600 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message601 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum0 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message599.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message599 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum199> enum_map = 5;\n  Enum199 status = 6;\n  repeated Enum0 flags = 7;\n  Message600 next = 8;\n  repeated Message601 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message602 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum1 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message600.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message600 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum0> enum_map = 5;\n  Enum0 status = 6;\n  repeated Enum1 flags = 7;\n  Message601 next = 8;\n  repeated Message602 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message603 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum2 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message601.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message601 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum1> enum_map = 5;\n  Enum1 status = 6;\n  repeated Enum2 flags = 7;\n  Message602 next = 8;\n  repeated Message603 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message604 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum3 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message602.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message602 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum2> enum_map = 5;\n  Enum2 status = 6;\n  repeated Enum3 flags = 7;\n  Message603 next = 8;\n  repeated Message604 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message605 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum4 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message603.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message603 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum3> enum_map = 5;\n  Enum3 status = 6;\n  repeated Enum4 flags = 7;\n  Message604 next = 8;\n  repeated Message605 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message606 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum5 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message604.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message604 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum4> enum_map = 5;\n  Enum4 status = 6;\n  repeated Enum5 flags = 7;\n  Message605 next = 8;\n  repeated Message606 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message607 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum6 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message605.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message605 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum5> enum_map = 5;\n  Enum5 status = 6;\n  repeated Enum6 flags = 7;\n  Message606 next = 8;\n  repeated Message607 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message608 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum7 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message606.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message606 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum6> enum_map = 5;\n  Enum6 status = 6;\n  repeated Enum7 flags = 7;\n  Message607 next = 8;\n  repeated Message608 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message609 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum8 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message607.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message607 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum7> enum_map = 5;\n  Enum7 status = 6;\n  repeated Enum8 flags = 7;\n  Message608 next = 8;\n  repeated Message609 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message610 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum9 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message608.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message608 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum8> enum_map = 5;\n  Enum8 status = 6;\n  repeated Enum9 flags = 7;\n  Message609 next = 8;\n  repeated Message610 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message611 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum10 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message609.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message609 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum9> enum_map = 5;\n  Enum9 status = 6;\n  repeated Enum10 flags = 7;\n  Message610 next = 8;\n  repeated Message611 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message612 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum11 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message610.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message610 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum10> enum_map = 5;\n  Enum10 status = 6;\n  repeated Enum11 flags = 7;\n  Message611 next = 8;\n  repeated Message612 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message613 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum12 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message611.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message611 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum11> enum_map = 5;\n  Enum11 status = 6;\n  repeated Enum12 flags = 7;\n  Message612 next = 8;\n  repeated Message613 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message614 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum13 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message612.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message612 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum12> enum_map = 5;\n  Enum12 status = 6;\n  repeated Enum13 flags = 7;\n  Message613 next = 8;\n  repeated Message614 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message615 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum14 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message613.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message613 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum13> enum_map = 5;\n  Enum13 status = 6;\n  repeated Enum14 flags = 7;\n  Message614 next = 8;\n  repeated Message615 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message616 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum15 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message614.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message614 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum14> enum_map = 5;\n  Enum14 status = 6;\n  repeated Enum15 flags = 7;\n  Message615 next = 8;\n  repeated Message616 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message617 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum16 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message615.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message615 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum15> enum_map = 5;\n  Enum15 status = 6;\n  repeated Enum16 flags = 7;\n  Message616 next = 8;\n  repeated Message617 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message618 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum17 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message616.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message616 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum16> enum_map = 5;\n  Enum16 status = 6;\n  repeated Enum17 flags = 7;\n  Message617 next = 8;\n  repeated Message618 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message619 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum18 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message617.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message617 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum17> enum_map = 5;\n  Enum17 status = 6;\n  repeated Enum18 flags = 7;\n  Message618 next = 8;\n  repeated Message619 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message620 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum19 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message618.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message618 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum18> enum_map = 5;\n  Enum18 status = 6;\n  repeated Enum19 flags = 7;\n  Message619 next = 8;\n  repeated Message620 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message621 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum20 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message619.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message619 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum19> enum_map = 5;\n  Enum19 status = 6;\n  repeated Enum20 flags = 7;\n  Message620 next = 8;\n  repeated Message621 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message622 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum21 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message620.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message620 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum20> enum_map = 5;\n  Enum20 status = 6;\n  repeated Enum21 flags = 7;\n  Message621 next = 8;\n  repeated Message622 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message623 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum22 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message621.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message621 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum21> enum_map = 5;\n  Enum21 status = 6;\n  repeated Enum22 flags = 7;\n  Message622 next = 8;\n  repeated Message623 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message624 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum23 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message622.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message622 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum22> enum_map = 5;\n  Enum22 status = 6;\n  repeated Enum23 flags = 7;\n  Message623 next = 8;\n  repeated Message624 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message625 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum24 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message623.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message623 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum23> enum_map = 5;\n  Enum23 status = 6;\n  repeated Enum24 flags = 7;\n  Message624 next = 8;\n  repeated Message625 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message626 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum25 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message624.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message624 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum24> enum_map = 5;\n  Enum24 status = 6;\n  repeated Enum25 flags = 7;\n  Message625 next = 8;\n  repeated Message626 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message627 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum26 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message625.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message625 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum25> enum_map = 5;\n  Enum25 status = 6;\n  repeated Enum26 flags = 7;\n  Message626 next = 8;\n  repeated Message627 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message628 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum27 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message626.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message626 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum26> enum_map = 5;\n  Enum26 status = 6;\n  repeated Enum27 flags = 7;\n  Message627 next = 8;\n  repeated Message628 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message629 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum28 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message627.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message627 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum27> enum_map = 5;\n  Enum27 status = 6;\n  repeated Enum28 flags = 7;\n  Message628 next = 8;\n  repeated Message629 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message630 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum29 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message628.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message628 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum28> enum_map = 5;\n  Enum28 status = 6;\n  repeated Enum29 flags = 7;\n  Message629 next = 8;\n  repeated Message630 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message631 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum30 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message629.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message629 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum29> enum_map = 5;\n  Enum29 status = 6;\n  repeated Enum30 flags = 7;\n  Message630 next = 8;\n  repeated Message631 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message632 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum31 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message630.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message630 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum30> enum_map = 5;\n  Enum30 status = 6;\n  repeated Enum31 flags = 7;\n  Message631 next = 8;\n  repeated Message632 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message633 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum32 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message631.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message631 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum31> enum_map = 5;\n  Enum31 status = 6;\n  repeated Enum32 flags = 7;\n  Message632 next = 8;\n  repeated Message633 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message634 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum33 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message632.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message632 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum32> enum_map = 5;\n  Enum32 status = 6;\n  repeated Enum33 flags = 7;\n  Message633 next = 8;\n  repeated Message634 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message635 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum34 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message633.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message633 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum33> enum_map = 5;\n  Enum33 status = 6;\n  repeated Enum34 flags = 7;\n  Message634 next = 8;\n  repeated Message635 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message636 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum35 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message634.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message634 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum34> enum_map = 5;\n  Enum34 status = 6;\n  repeated Enum35 flags = 7;\n  Message635 next = 8;\n  repeated Message636 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message637 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum36 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message635.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message635 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum35> enum_map = 5;\n  Enum35 status = 6;\n  repeated Enum36 flags = 7;\n  Message636 next = 8;\n  repeated Message637 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message638 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum37 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message636.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message636 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum36> enum_map = 5;\n  Enum36 status = 6;\n  repeated Enum37 flags = 7;\n  Message637 next = 8;\n  repeated Message638 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message639 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum38 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message637.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message637 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum37> enum_map = 5;\n  Enum37 status = 6;\n  repeated Enum38 flags = 7;\n  Message638 next = 8;\n  repeated Message639 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message640 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum39 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message638.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message638 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum38> enum_map = 5;\n  Enum38 status = 6;\n  repeated Enum39 flags = 7;\n  Message639 next = 8;\n  repeated Message640 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message641 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum40 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message639.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message639 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum39> enum_map = 5;\n  Enum39 status = 6;\n  repeated Enum40 flags = 7;\n  Message640 next = 8;\n  repeated Message641 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message642 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum41 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message640.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message640 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum40> enum_map = 5;\n  Enum40 status = 6;\n  repeated Enum41 flags = 7;\n  Message641 next = 8;\n  repeated Message642 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message643 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum42 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message641.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message641 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum41> enum_map = 5;\n  Enum41 status = 6;\n  repeated Enum42 flags = 7;\n  Message642 next = 8;\n  repeated Message643 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message644 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum43 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message642.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message642 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum42> enum_map = 5;\n  Enum42 status = 6;\n  repeated Enum43 flags = 7;\n  Message643 next = 8;\n  repeated Message644 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message645 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum44 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message643.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message643 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum43> enum_map = 5;\n  Enum43 status = 6;\n  repeated Enum44 flags = 7;\n  Message644 next = 8;\n  repeated Message645 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message646 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum45 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message644.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message644 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum44> enum_map = 5;\n  Enum44 status = 6;\n  repeated Enum45 flags = 7;\n  Message645 next = 8;\n  repeated Message646 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message647 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum46 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message645.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message645 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum45> enum_map = 5;\n  Enum45 status = 6;\n  repeated Enum46 flags = 7;\n  Message646 next = 8;\n  repeated Message647 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message648 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum47 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message646.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message646 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum46> enum_map = 5;\n  Enum46 status = 6;\n  repeated Enum47 flags = 7;\n  Message647 next = 8;\n  repeated Message648 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message649 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum48 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message647.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message647 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum47> enum_map = 5;\n  Enum47 status = 6;\n  repeated Enum48 flags = 7;\n  Message648 next = 8;\n  repeated Message649 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message650 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum49 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message648.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message648 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum48> enum_map = 5;\n  Enum48 status = 6;\n  repeated Enum49 flags = 7;\n  Message649 next = 8;\n  repeated Message650 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message651 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum50 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message649.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message649 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum49> enum_map = 5;\n  Enum49 status = 6;\n  repeated Enum50 flags = 7;\n  Message650 next = 8;\n  repeated Message651 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message652 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum51 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message650.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message650 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum50> enum_map = 5;\n  Enum50 status = 6;\n  repeated Enum51 flags = 7;\n  Message651 next = 8;\n  repeated Message652 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message653 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum52 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message651.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message651 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum51> enum_map = 5;\n  Enum51 status = 6;\n  repeated Enum52 flags = 7;\n  Message652 next = 8;\n  repeated Message653 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message654 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum53 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message652.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message652 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum52> enum_map = 5;\n  Enum52 status = 6;\n  repeated Enum53 flags = 7;\n  Message653 next = 8;\n  repeated Message654 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message655 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum54 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message653.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message653 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum53> enum_map = 5;\n  Enum53 status = 6;\n  repeated Enum54 flags = 7;\n  Message654 next = 8;\n  repeated Message655 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message656 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum55 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message654.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message654 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum54> enum_map = 5;\n  Enum54 status = 6;\n  repeated Enum55 flags = 7;\n  Message655 next = 8;\n  repeated Message656 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message657 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum56 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message655.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message655 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum55> enum_map = 5;\n  Enum55 status = 6;\n  repeated Enum56 flags = 7;\n  Message656 next = 8;\n  repeated Message657 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message658 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum57 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message656.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message656 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum56> enum_map = 5;\n  Enum56 status = 6;\n  repeated Enum57 flags = 7;\n  Message657 next = 8;\n  repeated Message658 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message659 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum58 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message657.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message657 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum57> enum_map = 5;\n  Enum57 status = 6;\n  repeated Enum58 flags = 7;\n  Message658 next = 8;\n  repeated Message659 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message660 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum59 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message658.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message658 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum58> enum_map = 5;\n  Enum58 status = 6;\n  repeated Enum59 flags = 7;\n  Message659 next = 8;\n  repeated Message660 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message661 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum60 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message659.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message659 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum59> enum_map = 5;\n  Enum59 status = 6;\n  repeated Enum60 flags = 7;\n  Message660 next = 8;\n  repeated Message661 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message662 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum61 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message660.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message660 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum60> enum_map = 5;\n  Enum60 status = 6;\n  repeated Enum61 flags = 7;\n  Message661 next = 8;\n  repeated Message662 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message663 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum62 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message661.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message661 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum61> enum_map = 5;\n  Enum61 status = 6;\n  repeated Enum62 flags = 7;\n  Message662 next = 8;\n  repeated Message663 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message664 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum63 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message662.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message662 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum62> enum_map = 5;\n  Enum62 status = 6;\n  repeated Enum63 flags = 7;\n  Message663 next = 8;\n  repeated Message664 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message665 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum64 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message663.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message663 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum63> enum_map = 5;\n  Enum63 status = 6;\n  repeated Enum64 flags = 7;\n  Message664 next = 8;\n  repeated Message665 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message666 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum65 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message664.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message664 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum64> enum_map = 5;\n  Enum64 status = 6;\n  repeated Enum65 flags = 7;\n  Message665 next = 8;\n  repeated Message666 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message667 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum66 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message665.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message665 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum65> enum_map = 5;\n  Enum65 status = 6;\n  repeated Enum66 flags = 7;\n  Message666 next = 8;\n  repeated Message667 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message668 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum67 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message666.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message666 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum66> enum_map = 5;\n  Enum66 status = 6;\n  repeated Enum67 flags = 7;\n  Message667 next = 8;\n  repeated Message668 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message669 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum68 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message667.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message667 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum67> enum_map = 5;\n  Enum67 status = 6;\n  repeated Enum68 flags = 7;\n  Message668 next = 8;\n  repeated Message669 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message670 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum69 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message668.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message668 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum68> enum_map = 5;\n  Enum68 status = 6;\n  repeated Enum69 flags = 7;\n  Message669 next = 8;\n  repeated Message670 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message671 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum70 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message669.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message669 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum69> enum_map = 5;\n  Enum69 status = 6;\n  repeated Enum70 flags = 7;\n  Message670 next = 8;\n  repeated Message671 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message672 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum71 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message670.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message670 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum70> enum_map = 5;\n  Enum70 status = 6;\n  repeated Enum71 flags = 7;\n  Message671 next = 8;\n  repeated Message672 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message673 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum72 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message671.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message671 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum71> enum_map = 5;\n  Enum71 status = 6;\n  repeated Enum72 flags = 7;\n  Message672 next = 8;\n  repeated Message673 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message674 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum73 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message672.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message672 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum72> enum_map = 5;\n  Enum72 status = 6;\n  repeated Enum73 flags = 7;\n  Message673 next = 8;\n  repeated Message674 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message675 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum74 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message673.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message673 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum73> enum_map = 5;\n  Enum73 status = 6;\n  repeated Enum74 flags = 7;\n  Message674 next = 8;\n  repeated Message675 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message676 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum75 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message674.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message674 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum74> enum_map = 5;\n  Enum74 status = 6;\n  repeated Enum75 flags = 7;\n  Message675 next = 8;\n  repeated Message676 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message677 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum76 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message675.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message675 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum75> enum_map = 5;\n  Enum75 status = 6;\n  repeated Enum76 flags = 7;\n  Message676 next = 8;\n  repeated Message677 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message678 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum77 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message676.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message676 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum76> enum_map = 5;\n  Enum76 status = 6;\n  repeated Enum77 flags = 7;\n  Message677 next = 8;\n  repeated Message678 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message679 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum78 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message677.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message677 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum77> enum_map = 5;\n  Enum77 status = 6;\n  repeated Enum78 flags = 7;\n  Message678 next = 8;\n  repeated Message679 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message680 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum79 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message678.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message678 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum78> enum_map = 5;\n  Enum78 status = 6;\n  repeated Enum79 flags = 7;\n  Message679 next = 8;\n  repeated Message680 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message681 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum80 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message679.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message679 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum79> enum_map = 5;\n  Enum79 status = 6;\n  repeated Enum80 flags = 7;\n  Message680 next = 8;\n  repeated Message681 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message682 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum81 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message680.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message680 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum80> enum_map = 5;\n  Enum80 status = 6;\n  repeated Enum81 flags = 7;\n  Message681 next = 8;\n  repeated Message682 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message683 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum82 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message681.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message681 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum81> enum_map = 5;\n  Enum81 status = 6;\n  repeated Enum82 flags = 7;\n  Message682 next = 8;\n  repeated Message683 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message684 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum83 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message682.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message682 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum82> enum_map = 5;\n  Enum82 status = 6;\n  repeated Enum83 flags = 7;\n  Message683 next = 8;\n  repeated Message684 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message685 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum84 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message683.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message683 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum83> enum_map = 5;\n  Enum83 status = 6;\n  repeated Enum84 flags = 7;\n  Message684 next = 8;\n  repeated Message685 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message686 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum85 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message684.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message684 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum84> enum_map = 5;\n  Enum84 status = 6;\n  repeated Enum85 flags = 7;\n  Message685 next = 8;\n  repeated Message686 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message687 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum86 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message685.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message685 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum85> enum_map = 5;\n  Enum85 status = 6;\n  repeated Enum86 flags = 7;\n  Message686 next = 8;\n  repeated Message687 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message688 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum87 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message686.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message686 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum86> enum_map = 5;\n  Enum86 status = 6;\n  repeated Enum87 flags = 7;\n  Message687 next = 8;\n  repeated Message688 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message689 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum88 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message687.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message687 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum87> enum_map = 5;\n  Enum87 status = 6;\n  repeated Enum88 flags = 7;\n  Message688 next = 8;\n  repeated Message689 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message690 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum89 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message688.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message688 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum88> enum_map = 5;\n  Enum88 status = 6;\n  repeated Enum89 flags = 7;\n  Message689 next = 8;\n  repeated Message690 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message691 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum90 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message689.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message689 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum89> enum_map = 5;\n  Enum89 status = 6;\n  repeated Enum90 flags = 7;\n  Message690 next = 8;\n  repeated Message691 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message692 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum91 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message690.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message690 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum90> enum_map = 5;\n  Enum90 status = 6;\n  repeated Enum91 flags = 7;\n  Message691 next = 8;\n  repeated Message692 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message693 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum92 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message691.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message691 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum91> enum_map = 5;\n  Enum91 status = 6;\n  repeated Enum92 flags = 7;\n  Message692 next = 8;\n  repeated Message693 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message694 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum93 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message692.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message692 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum92> enum_map = 5;\n  Enum92 status = 6;\n  repeated Enum93 flags = 7;\n  Message693 next = 8;\n  repeated Message694 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message695 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum94 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message693.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message693 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum93> enum_map = 5;\n  Enum93 status = 6;\n  repeated Enum94 flags = 7;\n  Message694 next = 8;\n  repeated Message695 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message696 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum95 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message694.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message694 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum94> enum_map = 5;\n  Enum94 status = 6;\n  repeated Enum95 flags = 7;\n  Message695 next = 8;\n  repeated Message696 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message697 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum96 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message695.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message695 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum95> enum_map = 5;\n  Enum95 status = 6;\n  repeated Enum96 flags = 7;\n  Message696 next = 8;\n  repeated Message697 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message698 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum97 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message696.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message696 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum96> enum_map = 5;\n  Enum96 status = 6;\n  repeated Enum97 flags = 7;\n  Message697 next = 8;\n  repeated Message698 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message699 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum98 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message697.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message697 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum97> enum_map = 5;\n  Enum97 status = 6;\n  repeated Enum98 flags = 7;\n  Message698 next = 8;\n  repeated Message699 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message700 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum99 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message698.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message698 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum98> enum_map = 5;\n  Enum98 status = 6;\n  repeated Enum99 flags = 7;\n  Message699 next = 8;\n  repeated Message700 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message701 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum100 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message699.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message699 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum99> enum_map = 5;\n  Enum99 status = 6;\n  repeated Enum100 flags = 7;\n  Message700 next = 8;\n  repeated Message701 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message702 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum101 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message700.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message700 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum100> enum_map = 5;\n  Enum100 status = 6;\n  repeated Enum101 flags = 7;\n  Message701 next = 8;\n  repeated Message702 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message703 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum102 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message701.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message701 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum101> enum_map = 5;\n  Enum101 status = 6;\n  repeated Enum102 flags = 7;\n  Message702 next = 8;\n  repeated Message703 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message704 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum103 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message702.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message702 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum102> enum_map = 5;\n  Enum102 status = 6;\n  repeated Enum103 flags = 7;\n  Message703 next = 8;\n  repeated Message704 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message705 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum104 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message703.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message703 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum103> enum_map = 5;\n  Enum103 status = 6;\n  repeated Enum104 flags = 7;\n  Message704 next = 8;\n  repeated Message705 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message706 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum105 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message704.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message704 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum104> enum_map = 5;\n  Enum104 status = 6;\n  repeated Enum105 flags = 7;\n  Message705 next = 8;\n  repeated Message706 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message707 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum106 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message705.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message705 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum105> enum_map = 5;\n  Enum105 status = 6;\n  repeated Enum106 flags = 7;\n  Message706 next = 8;\n  repeated Message707 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message708 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum107 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message706.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message706 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum106> enum_map = 5;\n  Enum106 status = 6;\n  repeated Enum107 flags = 7;\n  Message707 next = 8;\n  repeated Message708 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message709 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum108 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message707.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message707 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum107> enum_map = 5;\n  Enum107 status = 6;\n  repeated Enum108 flags = 7;\n  Message708 next = 8;\n  repeated Message709 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message710 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum109 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message708.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message708 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum108> enum_map = 5;\n  Enum108 status = 6;\n  repeated Enum109 flags = 7;\n  Message709 next = 8;\n  repeated Message710 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message711 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum110 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message709.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message709 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum109> enum_map = 5;\n  Enum109 status = 6;\n  repeated Enum110 flags = 7;\n  Message710 next = 8;\n  repeated Message711 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message712 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum111 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message710.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message710 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum110> enum_map = 5;\n  Enum110 status = 6;\n  repeated Enum111 flags = 7;\n  Message711 next = 8;\n  repeated Message712 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message713 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum112 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message711.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message711 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum111> enum_map = 5;\n  Enum111 status = 6;\n  repeated Enum112 flags = 7;\n  Message712 next = 8;\n  repeated Message713 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message714 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum113 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message712.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message712 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum112> enum_map = 5;\n  Enum112 status = 6;\n  repeated Enum113 flags = 7;\n  Message713 next = 8;\n  repeated Message714 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message715 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum114 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message713.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message713 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum113> enum_map = 5;\n  Enum113 status = 6;\n  repeated Enum114 flags = 7;\n  Message714 next = 8;\n  repeated Message715 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message716 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum115 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message714.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message714 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum114> enum_map = 5;\n  Enum114 status = 6;\n  repeated Enum115 flags = 7;\n  Message715 next = 8;\n  repeated Message716 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message717 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum116 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message715.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message715 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum115> enum_map = 5;\n  Enum115 status = 6;\n  repeated Enum116 flags = 7;\n  Message716 next = 8;\n  repeated Message717 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message718 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum117 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message716.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message716 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum116> enum_map = 5;\n  Enum116 status = 6;\n  repeated Enum117 flags = 7;\n  Message717 next = 8;\n  repeated Message718 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message719 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum118 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message717.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message717 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum117> enum_map = 5;\n  Enum117 status = 6;\n  repeated Enum118 flags = 7;\n  Message718 next = 8;\n  repeated Message719 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message720 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum119 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message718.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message718 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum118> enum_map = 5;\n  Enum118 status = 6;\n  repeated Enum119 flags = 7;\n  Message719 next = 8;\n  repeated Message720 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message721 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum120 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message719.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message719 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum119> enum_map = 5;\n  Enum119 status = 6;\n  repeated Enum120 flags = 7;\n  Message720 next = 8;\n  repeated Message721 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message722 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum121 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message720.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message720 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum120> enum_map = 5;\n  Enum120 status = 6;\n  repeated Enum121 flags = 7;\n  Message721 next = 8;\n  repeated Message722 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message723 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum122 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message721.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message721 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum121> enum_map = 5;\n  Enum121 status = 6;\n  repeated Enum122 flags = 7;\n  Message722 next = 8;\n  repeated Message723 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message724 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum123 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message722.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message722 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum122> enum_map = 5;\n  Enum122 status = 6;\n  repeated Enum123 flags = 7;\n  Message723 next = 8;\n  repeated Message724 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message725 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum124 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message723.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message723 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum123> enum_map = 5;\n  Enum123 status = 6;\n  repeated Enum124 flags = 7;\n  Message724 next = 8;\n  repeated Message725 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message726 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum125 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message724.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message724 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum124> enum_map = 5;\n  Enum124 status = 6;\n  repeated Enum125 flags = 7;\n  Message725 next = 8;\n  repeated Message726 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message727 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum126 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message725.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message725 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum125> enum_map = 5;\n  Enum125 status = 6;\n  repeated Enum126 flags = 7;\n  Message726 next = 8;\n  repeated Message727 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message728 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum127 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message726.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message726 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum126> enum_map = 5;\n  Enum126 status = 6;\n  repeated Enum127 flags = 7;\n  Message727 next = 8;\n  repeated Message728 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message729 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum128 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message727.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message727 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum127> enum_map = 5;\n  Enum127 status = 6;\n  repeated Enum128 flags = 7;\n  Message728 next = 8;\n  repeated Message729 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message730 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum129 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message728.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message728 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum128> enum_map = 5;\n  Enum128 status = 6;\n  repeated Enum129 flags = 7;\n  Message729 next = 8;\n  repeated Message730 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message731 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum130 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message729.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message729 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum129> enum_map = 5;\n  Enum129 status = 6;\n  repeated Enum130 flags = 7;\n  Message730 next = 8;\n  repeated Message731 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message732 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum131 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message730.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message730 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum130> enum_map = 5;\n  Enum130 status = 6;\n  repeated Enum131 flags = 7;\n  Message731 next = 8;\n  repeated Message732 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message733 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum132 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message731.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message731 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum131> enum_map = 5;\n  Enum131 status = 6;\n  repeated Enum132 flags = 7;\n  Message732 next = 8;\n  repeated Message733 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message734 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum133 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message732.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message732 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum132> enum_map = 5;\n  Enum132 status = 6;\n  repeated Enum133 flags = 7;\n  Message733 next = 8;\n  repeated Message734 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message735 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum134 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message733.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message733 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum133> enum_map = 5;\n  Enum133 status = 6;\n  repeated Enum134 flags = 7;\n  Message734 next = 8;\n  repeated Message735 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message736 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum135 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message734.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message734 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum134> enum_map = 5;\n  Enum134 status = 6;\n  repeated Enum135 flags = 7;\n  Message735 next = 8;\n  repeated Message736 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message737 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum136 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message735.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message735 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum135> enum_map = 5;\n  Enum135 status = 6;\n  repeated Enum136 flags = 7;\n  Message736 next = 8;\n  repeated Message737 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message738 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum137 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message736.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message736 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum136> enum_map = 5;\n  Enum136 status = 6;\n  repeated Enum137 flags = 7;\n  Message737 next = 8;\n  repeated Message738 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message739 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum138 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message737.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message737 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum137> enum_map = 5;\n  Enum137 status = 6;\n  repeated Enum138 flags = 7;\n  Message738 next = 8;\n  repeated Message739 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message740 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum139 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message738.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message738 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum138> enum_map = 5;\n  Enum138 status = 6;\n  repeated Enum139 flags = 7;\n  Message739 next = 8;\n  repeated Message740 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message741 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum140 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message739.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message739 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum139> enum_map = 5;\n  Enum139 status = 6;\n  repeated Enum140 flags = 7;\n  Message740 next = 8;\n  repeated Message741 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message742 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum141 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message740.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message740 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum140> enum_map = 5;\n  Enum140 status = 6;\n  repeated Enum141 flags = 7;\n  Message741 next = 8;\n  repeated Message742 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message743 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum142 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message741.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message741 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum141> enum_map = 5;\n  Enum141 status = 6;\n  repeated Enum142 flags = 7;\n  Message742 next = 8;\n  repeated Message743 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message744 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum143 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message742.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message742 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum142> enum_map = 5;\n  Enum142 status = 6;\n  repeated Enum143 flags = 7;\n  Message743 next = 8;\n  repeated Message744 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message745 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum144 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message743.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message743 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum143> enum_map = 5;\n  Enum143 status = 6;\n  repeated Enum144 flags = 7;\n  Message744 next = 8;\n  repeated Message745 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message746 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum145 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message744.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message744 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum144> enum_map = 5;\n  Enum144 status = 6;\n  repeated Enum145 flags = 7;\n  Message745 next = 8;\n  repeated Message746 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message747 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum146 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message745.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message745 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum145> enum_map = 5;\n  Enum145 status = 6;\n  repeated Enum146 flags = 7;\n  Message746 next = 8;\n  repeated Message747 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message748 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum147 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message746.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message746 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum146> enum_map = 5;\n  Enum146 status = 6;\n  repeated Enum147 flags = 7;\n  Message747 next = 8;\n  repeated Message748 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message749 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum148 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message747.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message747 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum147> enum_map = 5;\n  Enum147 status = 6;\n  repeated Enum148 flags = 7;\n  Message748 next = 8;\n  repeated Message749 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message750 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum149 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message748.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message748 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum148> enum_map = 5;\n  Enum148 status = 6;\n  repeated Enum149 flags = 7;\n  Message749 next = 8;\n  repeated Message750 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message751 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum150 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message749.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message749 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum149> enum_map = 5;\n  Enum149 status = 6;\n  repeated Enum150 flags = 7;\n  Message750 next = 8;\n  repeated Message751 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message752 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum151 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message750.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message750 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum150> enum_map = 5;\n  Enum150 status = 6;\n  repeated Enum151 flags = 7;\n  Message751 next = 8;\n  repeated Message752 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message753 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum152 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message751.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message751 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum151> enum_map = 5;\n  Enum151 status = 6;\n  repeated Enum152 flags = 7;\n  Message752 next = 8;\n  repeated Message753 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message754 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum153 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message752.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message752 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum152> enum_map = 5;\n  Enum152 status = 6;\n  repeated Enum153 flags = 7;\n  Message753 next = 8;\n  repeated Message754 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message755 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum154 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message753.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message753 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum153> enum_map = 5;\n  Enum153 status = 6;\n  repeated Enum154 flags = 7;\n  Message754 next = 8;\n  repeated Message755 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message756 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum155 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message754.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message754 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum154> enum_map = 5;\n  Enum154 status = 6;\n  repeated Enum155 flags = 7;\n  Message755 next = 8;\n  repeated Message756 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message757 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum156 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message755.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message755 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum155> enum_map = 5;\n  Enum155 status = 6;\n  repeated Enum156 flags = 7;\n  Message756 next = 8;\n  repeated Message757 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message758 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum157 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message756.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message756 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum156> enum_map = 5;\n  Enum156 status = 6;\n  repeated Enum157 flags = 7;\n  Message757 next = 8;\n  repeated Message758 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message759 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum158 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message757.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message757 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum157> enum_map = 5;\n  Enum157 status = 6;\n  repeated Enum158 flags = 7;\n  Message758 next = 8;\n  repeated Message759 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message760 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum159 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message758.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message758 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum158> enum_map = 5;\n  Enum158 status = 6;\n  repeated Enum159 flags = 7;\n  Message759 next = 8;\n  repeated Message760 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message761 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum160 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message759.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message759 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum159> enum_map = 5;\n  Enum159 status = 6;\n  repeated Enum160 flags = 7;\n  Message760 next = 8;\n  repeated Message761 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message762 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum161 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message760.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message760 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum160> enum_map = 5;\n  Enum160 status = 6;\n  repeated Enum161 flags = 7;\n  Message761 next = 8;\n  repeated Message762 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message763 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum162 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message761.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message761 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum161> enum_map = 5;\n  Enum161 status = 6;\n  repeated Enum162 flags = 7;\n  Message762 next = 8;\n  repeated Message763 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message764 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum163 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message762.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message762 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum162> enum_map = 5;\n  Enum162 status = 6;\n  repeated Enum163 flags = 7;\n  Message763 next = 8;\n  repeated Message764 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message765 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum164 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message763.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message763 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum163> enum_map = 5;\n  Enum163 status = 6;\n  repeated Enum164 flags = 7;\n  Message764 next = 8;\n  repeated Message765 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message766 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum165 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message764.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message764 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum164> enum_map = 5;\n  Enum164 status = 6;\n  repeated Enum165 flags = 7;\n  Message765 next = 8;\n  repeated Message766 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message767 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum166 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message765.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message765 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum165> enum_map = 5;\n  Enum165 status = 6;\n  repeated Enum166 flags = 7;\n  Message766 next = 8;\n  repeated Message767 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message768 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum167 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message766.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message766 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum166> enum_map = 5;\n  Enum166 status = 6;\n  repeated Enum167 flags = 7;\n  Message767 next = 8;\n  repeated Message768 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message769 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum168 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message767.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message767 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum167> enum_map = 5;\n  Enum167 status = 6;\n  repeated Enum168 flags = 7;\n  Message768 next = 8;\n  repeated Message769 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message770 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum169 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message768.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message768 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum168> enum_map = 5;\n  Enum168 status = 6;\n  repeated Enum169 flags = 7;\n  Message769 next = 8;\n  repeated Message770 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message771 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum170 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message769.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message769 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum169> enum_map = 5;\n  Enum169 status = 6;\n  repeated Enum170 flags = 7;\n  Message770 next = 8;\n  repeated Message771 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message772 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum171 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message770.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message770 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum170> enum_map = 5;\n  Enum170 status = 6;\n  repeated Enum171 flags = 7;\n  Message771 next = 8;\n  repeated Message772 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message773 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum172 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message771.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message771 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum171> enum_map = 5;\n  Enum171 status = 6;\n  repeated Enum172 flags = 7;\n  Message772 next = 8;\n  repeated Message773 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message774 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum173 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message772.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message772 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum172> enum_map = 5;\n  Enum172 status = 6;\n  repeated Enum173 flags = 7;\n  Message773 next = 8;\n  repeated Message774 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message775 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum174 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message773.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message773 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum173> enum_map = 5;\n  Enum173 status = 6;\n  repeated Enum174 flags = 7;\n  Message774 next = 8;\n  repeated Message775 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message776 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum175 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message774.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message774 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum174> enum_map = 5;\n  Enum174 status = 6;\n  repeated Enum175 flags = 7;\n  Message775 next = 8;\n  repeated Message776 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message777 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum176 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message775.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message775 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum175> enum_map = 5;\n  Enum175 status = 6;\n  repeated Enum176 flags = 7;\n  Message776 next = 8;\n  repeated Message777 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message778 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum177 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message776.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message776 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum176> enum_map = 5;\n  Enum176 status = 6;\n  repeated Enum177 flags = 7;\n  Message777 next = 8;\n  repeated Message778 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message779 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum178 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message777.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message777 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum177> enum_map = 5;\n  Enum177 status = 6;\n  repeated Enum178 flags = 7;\n  Message778 next = 8;\n  repeated Message779 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message780 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum179 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message778.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message778 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum178> enum_map = 5;\n  Enum178 status = 6;\n  repeated Enum179 flags = 7;\n  Message779 next = 8;\n  repeated Message780 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message781 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum180 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message779.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message779 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum179> enum_map = 5;\n  Enum179 status = 6;\n  repeated Enum180 flags = 7;\n  Message780 next = 8;\n  repeated Message781 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message782 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum181 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message780.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message780 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum180> enum_map = 5;\n  Enum180 status = 6;\n  repeated Enum181 flags = 7;\n  Message781 next = 8;\n  repeated Message782 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message783 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum182 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message781.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message781 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum181> enum_map = 5;\n  Enum181 status = 6;\n  repeated Enum182 flags = 7;\n  Message782 next = 8;\n  repeated Message783 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message784 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum183 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message782.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message782 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum182> enum_map = 5;\n  Enum182 status = 6;\n  repeated Enum183 flags = 7;\n  Message783 next = 8;\n  repeated Message784 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message785 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum184 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message783.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message783 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum183> enum_map = 5;\n  Enum183 status = 6;\n  repeated Enum184 flags = 7;\n  Message784 next = 8;\n  repeated Message785 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message786 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum185 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message784.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message784 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum184> enum_map = 5;\n  Enum184 status = 6;\n  repeated Enum185 flags = 7;\n  Message785 next = 8;\n  repeated Message786 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message787 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum186 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message785.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message785 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum185> enum_map = 5;\n  Enum185 status = 6;\n  repeated Enum186 flags = 7;\n  Message786 next = 8;\n  repeated Message787 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message788 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum187 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message786.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message786 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum186> enum_map = 5;\n  Enum186 status = 6;\n  repeated Enum187 flags = 7;\n  Message787 next = 8;\n  repeated Message788 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message789 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum188 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message787.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message787 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum187> enum_map = 5;\n  Enum187 status = 6;\n  repeated Enum188 flags = 7;\n  Message788 next = 8;\n  repeated Message789 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message790 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum189 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message788.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message788 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum188> enum_map = 5;\n  Enum188 status = 6;\n  repeated Enum189 flags = 7;\n  Message789 next = 8;\n  repeated Message790 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message791 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum190 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message789.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message789 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum189> enum_map = 5;\n  Enum189 status = 6;\n  repeated Enum190 flags = 7;\n  Message790 next = 8;\n  repeated Message791 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message792 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum191 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message790.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message790 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum190> enum_map = 5;\n  Enum190 status = 6;\n  repeated Enum191 flags = 7;\n  Message791 next = 8;\n  repeated Message792 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message793 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum192 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message791.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message791 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum191> enum_map = 5;\n  Enum191 status = 6;\n  repeated Enum192 flags = 7;\n  Message792 next = 8;\n  repeated Message793 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message794 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum193 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message792.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message792 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum192> enum_map = 5;\n  Enum192 status = 6;\n  repeated Enum193 flags = 7;\n  Message793 next = 8;\n  repeated Message794 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message795 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum194 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message793.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message793 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum193> enum_map = 5;\n  Enum193 status = 6;\n  repeated Enum194 flags = 7;\n  Message794 next = 8;\n  repeated Message795 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message796 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum195 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message794.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message794 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum194> enum_map = 5;\n  Enum194 status = 6;\n  repeated Enum195 flags = 7;\n  Message795 next = 8;\n  repeated Message796 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message797 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum196 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message795.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message795 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum195> enum_map = 5;\n  Enum195 status = 6;\n  repeated Enum196 flags = 7;\n  Message796 next = 8;\n  repeated Message797 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message798 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum197 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message796.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message796 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum196> enum_map = 5;\n  Enum196 status = 6;\n  repeated Enum197 flags = 7;\n  Message797 next = 8;\n  repeated Message798 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message799 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum198 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message797.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message797 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum197> enum_map = 5;\n  Enum197 status = 6;\n  repeated Enum198 flags = 7;\n  Message798 next = 8;\n  repeated Message799 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message800 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum199 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message798.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message798 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum198> enum_map = 5;\n  Enum198 status = 6;\n  repeated Enum199 flags = 7;\n  Message799 next = 8;\n  repeated Message800 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message801 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum0 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message799.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message799 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum199> enum_map = 5;\n  Enum199 status = 6;\n  repeated Enum0 flags = 7;\n  Message800 next = 8;\n  repeated Message801 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message802 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum1 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message800.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message800 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum0> enum_map = 5;\n  Enum0 status = 6;\n  repeated Enum1 flags = 7;\n  Message801 next = 8;\n  repeated Message802 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message803 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum2 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message801.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message801 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum1> enum_map = 5;\n  Enum1 status = 6;\n  repeated Enum2 flags = 7;\n  Message802 next = 8;\n  repeated Message803 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message804 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum3 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message802.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message802 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum2> enum_map = 5;\n  Enum2 status = 6;\n  repeated Enum3 flags = 7;\n  Message803 next = 8;\n  repeated Message804 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message805 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum4 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message803.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message803 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum3> enum_map = 5;\n  Enum3 status = 6;\n  repeated Enum4 flags = 7;\n  Message804 next = 8;\n  repeated Message805 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message806 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum5 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message804.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message804 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum4> enum_map = 5;\n  Enum4 status = 6;\n  repeated Enum5 flags = 7;\n  Message805 next = 8;\n  repeated Message806 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message807 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum6 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message805.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message805 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum5> enum_map = 5;\n  Enum5 status = 6;\n  repeated Enum6 flags = 7;\n  Message806 next = 8;\n  repeated Message807 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message808 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum7 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message806.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message806 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum6> enum_map = 5;\n  Enum6 status = 6;\n  repeated Enum7 flags = 7;\n  Message807 next = 8;\n  repeated Message808 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message809 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum8 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message807.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message807 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum7> enum_map = 5;\n  Enum7 status = 6;\n  repeated Enum8 flags = 7;\n  Message808 next = 8;\n  repeated Message809 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message810 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum9 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message808.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message808 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum8> enum_map = 5;\n  Enum8 status = 6;\n  repeated Enum9 flags = 7;\n  Message809 next = 8;\n  repeated Message810 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message811 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum10 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message809.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message809 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum9> enum_map = 5;\n  Enum9 status = 6;\n  repeated Enum10 flags = 7;\n  Message810 next = 8;\n  repeated Message811 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message812 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum11 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message810.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message810 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum10> enum_map = 5;\n  Enum10 status = 6;\n  repeated Enum11 flags = 7;\n  Message811 next = 8;\n  repeated Message812 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message813 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum12 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message811.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message811 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum11> enum_map = 5;\n  Enum11 status = 6;\n  repeated Enum12 flags = 7;\n  Message812 next = 8;\n  repeated Message813 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message814 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum13 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message812.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message812 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum12> enum_map = 5;\n  Enum12 status = 6;\n  repeated Enum13 flags = 7;\n  Message813 next = 8;\n  repeated Message814 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message815 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum14 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message813.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message813 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum13> enum_map = 5;\n  Enum13 status = 6;\n  repeated Enum14 flags = 7;\n  Message814 next = 8;\n  repeated Message815 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message816 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum15 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message814.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message814 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum14> enum_map = 5;\n  Enum14 status = 6;\n  repeated Enum15 flags = 7;\n  Message815 next = 8;\n  repeated Message816 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message817 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum16 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message815.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message815 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum15> enum_map = 5;\n  Enum15 status = 6;\n  repeated Enum16 flags = 7;\n  Message816 next = 8;\n  repeated Message817 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message818 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum17 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message816.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message816 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum16> enum_map = 5;\n  Enum16 status = 6;\n  repeated Enum17 flags = 7;\n  Message817 next = 8;\n  repeated Message818 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message819 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum18 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message817.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message817 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum17> enum_map = 5;\n  Enum17 status = 6;\n  repeated Enum18 flags = 7;\n  Message818 next = 8;\n  repeated Message819 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message820 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum19 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message818.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message818 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum18> enum_map = 5;\n  Enum18 status = 6;\n  repeated Enum19 flags = 7;\n  Message819 next = 8;\n  repeated Message820 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message821 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum20 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message819.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message819 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum19> enum_map = 5;\n  Enum19 status = 6;\n  repeated Enum20 flags = 7;\n  Message820 next = 8;\n  repeated Message821 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message822 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum21 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message820.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message820 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum20> enum_map = 5;\n  Enum20 status = 6;\n  repeated Enum21 flags = 7;\n  Message821 next = 8;\n  repeated Message822 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message823 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum22 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message821.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message821 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum21> enum_map = 5;\n  Enum21 status = 6;\n  repeated Enum22 flags = 7;\n  Message822 next = 8;\n  repeated Message823 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message824 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum23 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message822.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message822 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum22> enum_map = 5;\n  Enum22 status = 6;\n  repeated Enum23 flags = 7;\n  Message823 next = 8;\n  repeated Message824 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message825 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum24 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message823.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message823 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum23> enum_map = 5;\n  Enum23 status = 6;\n  repeated Enum24 flags = 7;\n  Message824 next = 8;\n  repeated Message825 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message826 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum25 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message824.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message824 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum24> enum_map = 5;\n  Enum24 status = 6;\n  repeated Enum25 flags = 7;\n  Message825 next = 8;\n  repeated Message826 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message827 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum26 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message825.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message825 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum25> enum_map = 5;\n  Enum25 status = 6;\n  repeated Enum26 flags = 7;\n  Message826 next = 8;\n  repeated Message827 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message828 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum27 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message826.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message826 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum26> enum_map = 5;\n  Enum26 status = 6;\n  repeated Enum27 flags = 7;\n  Message827 next = 8;\n  repeated Message828 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message829 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum28 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message827.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message827 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum27> enum_map = 5;\n  Enum27 status = 6;\n  repeated Enum28 flags = 7;\n  Message828 next = 8;\n  repeated Message829 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message830 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum29 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message828.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message828 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum28> enum_map = 5;\n  Enum28 status = 6;\n  repeated Enum29 flags = 7;\n  Message829 next = 8;\n  repeated Message830 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message831 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum30 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message829.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message829 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum29> enum_map = 5;\n  Enum29 status = 6;\n  repeated Enum30 flags = 7;\n  Message830 next = 8;\n  repeated Message831 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message832 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum31 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message830.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message830 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum30> enum_map = 5;\n  Enum30 status = 6;\n  repeated Enum31 flags = 7;\n  Message831 next = 8;\n  repeated Message832 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message833 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum32 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message831.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message831 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum31> enum_map = 5;\n  Enum31 status = 6;\n  repeated Enum32 flags = 7;\n  Message832 next = 8;\n  repeated Message833 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message834 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum33 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message832.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message832 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum32> enum_map = 5;\n  Enum32 status = 6;\n  repeated Enum33 flags = 7;\n  Message833 next = 8;\n  repeated Message834 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message835 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum34 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message833.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message833 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum33> enum_map = 5;\n  Enum33 status = 6;\n  repeated Enum34 flags = 7;\n  Message834 next = 8;\n  repeated Message835 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message836 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum35 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message834.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message834 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum34> enum_map = 5;\n  Enum34 status = 6;\n  repeated Enum35 flags = 7;\n  Message835 next = 8;\n  repeated Message836 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message837 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum36 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message835.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message835 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum35> enum_map = 5;\n  Enum35 status = 6;\n  repeated Enum36 flags = 7;\n  Message836 next = 8;\n  repeated Message837 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message838 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum37 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message836.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message836 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum36> enum_map = 5;\n  Enum36 status = 6;\n  repeated Enum37 flags = 7;\n  Message837 next = 8;\n  repeated Message838 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message839 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum38 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message837.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message837 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum37> enum_map = 5;\n  Enum37 status = 6;\n  repeated Enum38 flags = 7;\n  Message838 next = 8;\n  repeated Message839 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message840 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum39 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message838.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message838 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum38> enum_map = 5;\n  Enum38 status = 6;\n  repeated Enum39 flags = 7;\n  Message839 next = 8;\n  repeated Message840 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message841 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum40 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message839.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message839 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum39> enum_map = 5;\n  Enum39 status = 6;\n  repeated Enum40 flags = 7;\n  Message840 next = 8;\n  repeated Message841 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message842 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum41 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message840.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message840 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum40> enum_map = 5;\n  Enum40 status = 6;\n  repeated Enum41 flags = 7;\n  Message841 next = 8;\n  repeated Message842 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message843 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum42 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message841.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message841 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum41> enum_map = 5;\n  Enum41 status = 6;\n  repeated Enum42 flags = 7;\n  Message842 next = 8;\n  repeated Message843 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message844 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum43 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message842.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message842 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum42> enum_map = 5;\n  Enum42 status = 6;\n  repeated Enum43 flags = 7;\n  Message843 next = 8;\n  repeated Message844 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message845 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum44 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message843.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message843 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum43> enum_map = 5;\n  Enum43 status = 6;\n  repeated Enum44 flags = 7;\n  Message844 next = 8;\n  repeated Message845 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message846 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum45 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message844.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message844 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum44> enum_map = 5;\n  Enum44 status = 6;\n  repeated Enum45 flags = 7;\n  Message845 next = 8;\n  repeated Message846 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message847 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum46 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message845.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message845 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum45> enum_map = 5;\n  Enum45 status = 6;\n  repeated Enum46 flags = 7;\n  Message846 next = 8;\n  repeated Message847 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message848 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum47 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message846.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message846 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum46> enum_map = 5;\n  Enum46 status = 6;\n  repeated Enum47 flags = 7;\n  Message847 next = 8;\n  repeated Message848 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message849 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum48 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message847.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message847 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum47> enum_map = 5;\n  Enum47 status = 6;\n  repeated Enum48 flags = 7;\n  Message848 next = 8;\n  repeated Message849 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message850 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum49 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message848.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message848 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum48> enum_map = 5;\n  Enum48 status = 6;\n  repeated Enum49 flags = 7;\n  Message849 next = 8;\n  repeated Message850 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message851 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum50 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message849.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message849 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum49> enum_map = 5;\n  Enum49 status = 6;\n  repeated Enum50 flags = 7;\n  Message850 next = 8;\n  repeated Message851 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message852 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum51 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message850.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message850 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum50> enum_map = 5;\n  Enum50 status = 6;\n  repeated Enum51 flags = 7;\n  Message851 next = 8;\n  repeated Message852 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message853 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum52 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message851.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message851 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum51> enum_map = 5;\n  Enum51 status = 6;\n  repeated Enum52 flags = 7;\n  Message852 next = 8;\n  repeated Message853 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message854 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum53 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message852.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message852 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum52> enum_map = 5;\n  Enum52 status = 6;\n  repeated Enum53 flags = 7;\n  Message853 next = 8;\n  repeated Message854 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message855 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum54 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message853.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message853 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum53> enum_map = 5;\n  Enum53 status = 6;\n  repeated Enum54 flags = 7;\n  Message854 next = 8;\n  repeated Message855 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message856 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum55 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message854.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message854 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum54> enum_map = 5;\n  Enum54 status = 6;\n  repeated Enum55 flags = 7;\n  Message855 next = 8;\n  repeated Message856 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message857 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum56 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message855.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message855 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum55> enum_map = 5;\n  Enum55 status = 6;\n  repeated Enum56 flags = 7;\n  Message856 next = 8;\n  repeated Message857 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message858 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum57 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message856.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message856 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum56> enum_map = 5;\n  Enum56 status = 6;\n  repeated Enum57 flags = 7;\n  Message857 next = 8;\n  repeated Message858 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message859 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum58 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message857.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message857 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum57> enum_map = 5;\n  Enum57 status = 6;\n  repeated Enum58 flags = 7;\n  Message858 next = 8;\n  repeated Message859 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message860 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum59 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message858.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message858 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum58> enum_map = 5;\n  Enum58 status = 6;\n  repeated Enum59 flags = 7;\n  Message859 next = 8;\n  repeated Message860 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message861 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum60 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message859.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message859 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum59> enum_map = 5;\n  Enum59 status = 6;\n  repeated Enum60 flags = 7;\n  Message860 next = 8;\n  repeated Message861 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message862 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum61 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message860.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message860 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum60> enum_map = 5;\n  Enum60 status = 6;\n  repeated Enum61 flags = 7;\n  Message861 next = 8;\n  repeated Message862 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message863 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum62 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message861.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message861 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum61> enum_map = 5;\n  Enum61 status = 6;\n  repeated Enum62 flags = 7;\n  Message862 next = 8;\n  repeated Message863 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message864 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum63 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message862.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message862 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum62> enum_map = 5;\n  Enum62 status = 6;\n  repeated Enum63 flags = 7;\n  Message863 next = 8;\n  repeated Message864 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message865 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum64 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message863.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message863 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum63> enum_map = 5;\n  Enum63 status = 6;\n  repeated Enum64 flags = 7;\n  Message864 next = 8;\n  repeated Message865 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message866 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum65 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message864.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message864 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum64> enum_map = 5;\n  Enum64 status = 6;\n  repeated Enum65 flags = 7;\n  Message865 next = 8;\n  repeated Message866 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message867 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum66 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message865.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message865 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum65> enum_map = 5;\n  Enum65 status = 6;\n  repeated Enum66 flags = 7;\n  Message866 next = 8;\n  repeated Message867 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message868 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum67 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message866.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message866 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum66> enum_map = 5;\n  Enum66 status = 6;\n  repeated Enum67 flags = 7;\n  Message867 next = 8;\n  repeated Message868 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message869 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum68 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message867.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message867 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum67> enum_map = 5;\n  Enum67 status = 6;\n  repeated Enum68 flags = 7;\n  Message868 next = 8;\n  repeated Message869 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message870 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum69 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message868.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message868 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum68> enum_map = 5;\n  Enum68 status = 6;\n  repeated Enum69 flags = 7;\n  Message869 next = 8;\n  repeated Message870 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message871 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum70 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message869.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message869 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum69> enum_map = 5;\n  Enum69 status = 6;\n  repeated Enum70 flags = 7;\n  Message870 next = 8;\n  repeated Message871 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message872 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum71 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message870.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message870 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum70> enum_map = 5;\n  Enum70 status = 6;\n  repeated Enum71 flags = 7;\n  Message871 next = 8;\n  repeated Message872 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message873 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum72 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message871.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message871 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum71> enum_map = 5;\n  Enum71 status = 6;\n  repeated Enum72 flags = 7;\n  Message872 next = 8;\n  repeated Message873 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message874 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum73 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message872.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message872 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum72> enum_map = 5;\n  Enum72 status = 6;\n  repeated Enum73 flags = 7;\n  Message873 next = 8;\n  repeated Message874 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message875 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum74 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message873.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message873 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum73> enum_map = 5;\n  Enum73 status = 6;\n  repeated Enum74 flags = 7;\n  Message874 next = 8;\n  repeated Message875 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message876 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum75 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message874.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message874 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum74> enum_map = 5;\n  Enum74 status = 6;\n  repeated Enum75 flags = 7;\n  Message875 next = 8;\n  repeated Message876 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message877 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum76 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message875.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message875 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum75> enum_map = 5;\n  Enum75 status = 6;\n  repeated Enum76 flags = 7;\n  Message876 next = 8;\n  repeated Message877 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message878 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum77 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message876.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message876 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum76> enum_map = 5;\n  Enum76 status = 6;\n  repeated Enum77 flags = 7;\n  Message877 next = 8;\n  repeated Message878 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message879 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum78 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message877.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message877 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum77> enum_map = 5;\n  Enum77 status = 6;\n  repeated Enum78 flags = 7;\n  Message878 next = 8;\n  repeated Message879 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message880 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum79 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message878.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message878 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum78> enum_map = 5;\n  Enum78 status = 6;\n  repeated Enum79 flags = 7;\n  Message879 next = 8;\n  repeated Message880 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message881 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum80 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message879.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message879 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum79> enum_map = 5;\n  Enum79 status = 6;\n  repeated Enum80 flags = 7;\n  Message880 next = 8;\n  repeated Message881 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message882 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum81 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message880.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message880 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum80> enum_map = 5;\n  Enum80 status = 6;\n  repeated Enum81 flags = 7;\n  Message881 next = 8;\n  repeated Message882 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message883 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum82 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message881.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message881 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum81> enum_map = 5;\n  Enum81 status = 6;\n  repeated Enum82 flags = 7;\n  Message882 next = 8;\n  repeated Message883 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message884 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum83 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message882.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message882 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum82> enum_map = 5;\n  Enum82 status = 6;\n  repeated Enum83 flags = 7;\n  Message883 next = 8;\n  repeated Message884 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message885 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum84 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message883.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message883 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum83> enum_map = 5;\n  Enum83 status = 6;\n  repeated Enum84 flags = 7;\n  Message884 next = 8;\n  repeated Message885 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message886 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum85 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message884.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message884 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum84> enum_map = 5;\n  Enum84 status = 6;\n  repeated Enum85 flags = 7;\n  Message885 next = 8;\n  repeated Message886 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message887 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum86 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message885.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message885 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum85> enum_map = 5;\n  Enum85 status = 6;\n  repeated Enum86 flags = 7;\n  Message886 next = 8;\n  repeated Message887 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message888 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum87 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message886.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message886 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum86> enum_map = 5;\n  Enum86 status = 6;\n  repeated Enum87 flags = 7;\n  Message887 next = 8;\n  repeated Message888 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message889 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum88 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message887.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message887 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum87> enum_map = 5;\n  Enum87 status = 6;\n  repeated Enum88 flags = 7;\n  Message888 next = 8;\n  repeated Message889 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message890 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum89 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message888.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message888 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum88> enum_map = 5;\n  Enum88 status = 6;\n  repeated Enum89 flags = 7;\n  Message889 next = 8;\n  repeated Message890 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message891 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum90 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message889.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message889 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum89> enum_map = 5;\n  Enum89 status = 6;\n  repeated Enum90 flags = 7;\n  Message890 next = 8;\n  repeated Message891 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message892 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum91 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message890.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message890 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum90> enum_map = 5;\n  Enum90 status = 6;\n  repeated Enum91 flags = 7;\n  Message891 next = 8;\n  repeated Message892 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message893 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum92 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message891.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message891 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum91> enum_map = 5;\n  Enum91 status = 6;\n  repeated Enum92 flags = 7;\n  Message892 next = 8;\n  repeated Message893 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message894 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum93 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message892.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message892 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum92> enum_map = 5;\n  Enum92 status = 6;\n  repeated Enum93 flags = 7;\n  Message893 next = 8;\n  repeated Message894 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message895 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum94 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message893.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message893 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum93> enum_map = 5;\n  Enum93 status = 6;\n  repeated Enum94 flags = 7;\n  Message894 next = 8;\n  repeated Message895 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message896 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum95 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message894.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message894 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum94> enum_map = 5;\n  Enum94 status = 6;\n  repeated Enum95 flags = 7;\n  Message895 next = 8;\n  repeated Message896 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message897 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum96 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message895.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message895 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum95> enum_map = 5;\n  Enum95 status = 6;\n  repeated Enum96 flags = 7;\n  Message896 next = 8;\n  repeated Message897 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message898 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum97 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message896.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message896 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum96> enum_map = 5;\n  Enum96 status = 6;\n  repeated Enum97 flags = 7;\n  Message897 next = 8;\n  repeated Message898 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message899 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum98 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message897.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message897 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum97> enum_map = 5;\n  Enum97 status = 6;\n  repeated Enum98 flags = 7;\n  Message898 next = 8;\n  repeated Message899 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message900 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum99 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message898.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message898 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum98> enum_map = 5;\n  Enum98 status = 6;\n  repeated Enum99 flags = 7;\n  Message899 next = 8;\n  repeated Message900 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message901 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum100 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message899.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message899 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum99> enum_map = 5;\n  Enum99 status = 6;\n  repeated Enum100 flags = 7;\n  Message900 next = 8;\n  repeated Message901 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message902 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum101 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message900.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message900 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum100> enum_map = 5;\n  Enum100 status = 6;\n  repeated Enum101 flags = 7;\n  Message901 next = 8;\n  repeated Message902 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message903 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum102 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message901.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message901 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum101> enum_map = 5;\n  Enum101 status = 6;\n  repeated Enum102 flags = 7;\n  Message902 next = 8;\n  repeated Message903 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message904 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum103 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message902.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message902 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum102> enum_map = 5;\n  Enum102 status = 6;\n  repeated Enum103 flags = 7;\n  Message903 next = 8;\n  repeated Message904 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message905 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum104 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message903.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message903 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum103> enum_map = 5;\n  Enum103 status = 6;\n  repeated Enum104 flags = 7;\n  Message904 next = 8;\n  repeated Message905 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message906 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum105 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message904.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message904 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum104> enum_map = 5;\n  Enum104 status = 6;\n  repeated Enum105 flags = 7;\n  Message905 next = 8;\n  repeated Message906 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message907 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum106 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message905.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message905 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum105> enum_map = 5;\n  Enum105 status = 6;\n  repeated Enum106 flags = 7;\n  Message906 next = 8;\n  repeated Message907 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message908 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum107 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message906.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message906 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum106> enum_map = 5;\n  Enum106 status = 6;\n  repeated Enum107 flags = 7;\n  Message907 next = 8;\n  repeated Message908 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message909 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum108 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message907.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message907 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum107> enum_map = 5;\n  Enum107 status = 6;\n  repeated Enum108 flags = 7;\n  Message908 next = 8;\n  repeated Message909 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message910 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum109 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message908.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message908 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum108> enum_map = 5;\n  Enum108 status = 6;\n  repeated Enum109 flags = 7;\n  Message909 next = 8;\n  repeated Message910 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message911 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum110 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message909.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message909 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum109> enum_map = 5;\n  Enum109 status = 6;\n  repeated Enum110 flags = 7;\n  Message910 next = 8;\n  repeated Message911 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message912 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum111 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message910.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message910 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum110> enum_map = 5;\n  Enum110 status = 6;\n  repeated Enum111 flags = 7;\n  Message911 next = 8;\n  repeated Message912 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message913 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum112 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message911.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message911 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum111> enum_map = 5;\n  Enum111 status = 6;\n  repeated Enum112 flags = 7;\n  Message912 next = 8;\n  repeated Message913 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message914 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum113 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message912.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message912 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum112> enum_map = 5;\n  Enum112 status = 6;\n  repeated Enum113 flags = 7;\n  Message913 next = 8;\n  repeated Message914 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message915 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum114 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message913.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message913 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum113> enum_map = 5;\n  Enum113 status = 6;\n  repeated Enum114 flags = 7;\n  Message914 next = 8;\n  repeated Message915 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message916 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum115 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message914.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message914 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum114> enum_map = 5;\n  Enum114 status = 6;\n  repeated Enum115 flags = 7;\n  Message915 next = 8;\n  repeated Message916 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message917 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum116 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message915.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message915 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum115> enum_map = 5;\n  Enum115 status = 6;\n  repeated Enum116 flags = 7;\n  Message916 next = 8;\n  repeated Message917 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message918 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum117 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message916.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message916 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum116> enum_map = 5;\n  Enum116 status = 6;\n  repeated Enum117 flags = 7;\n  Message917 next = 8;\n  repeated Message918 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message919 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum118 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message917.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message917 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum117> enum_map = 5;\n  Enum117 status = 6;\n  repeated Enum118 flags = 7;\n  Message918 next = 8;\n  repeated Message919 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message920 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum119 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message918.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message918 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum118> enum_map = 5;\n  Enum118 status = 6;\n  repeated Enum119 flags = 7;\n  Message919 next = 8;\n  repeated Message920 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message921 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum120 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message919.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message919 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum119> enum_map = 5;\n  Enum119 status = 6;\n  repeated Enum120 flags = 7;\n  Message920 next = 8;\n  repeated Message921 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message922 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum121 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message920.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message920 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum120> enum_map = 5;\n  Enum120 status = 6;\n  repeated Enum121 flags = 7;\n  Message921 next = 8;\n  repeated Message922 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message923 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum122 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message921.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message921 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum121> enum_map = 5;\n  Enum121 status = 6;\n  repeated Enum122 flags = 7;\n  Message922 next = 8;\n  repeated Message923 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message924 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum123 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message922.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message922 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum122> enum_map = 5;\n  Enum122 status = 6;\n  repeated Enum123 flags = 7;\n  Message923 next = 8;\n  repeated Message924 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message925 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum124 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message923.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message923 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum123> enum_map = 5;\n  Enum123 status = 6;\n  repeated Enum124 flags = 7;\n  Message924 next = 8;\n  repeated Message925 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message926 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum125 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message924.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message924 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum124> enum_map = 5;\n  Enum124 status = 6;\n  repeated Enum125 flags = 7;\n  Message925 next = 8;\n  repeated Message926 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message927 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum126 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message925.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message925 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum125> enum_map = 5;\n  Enum125 status = 6;\n  repeated Enum126 flags = 7;\n  Message926 next = 8;\n  repeated Message927 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message928 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum127 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message926.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message926 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum126> enum_map = 5;\n  Enum126 status = 6;\n  repeated Enum127 flags = 7;\n  Message927 next = 8;\n  repeated Message928 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message929 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum128 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message927.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message927 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum127> enum_map = 5;\n  Enum127 status = 6;\n  repeated Enum128 flags = 7;\n  Message928 next = 8;\n  repeated Message929 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message930 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum129 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message928.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message928 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum128> enum_map = 5;\n  Enum128 status = 6;\n  repeated Enum129 flags = 7;\n  Message929 next = 8;\n  repeated Message930 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message931 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum130 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message929.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message929 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum129> enum_map = 5;\n  Enum129 status = 6;\n  repeated Enum130 flags = 7;\n  Message930 next = 8;\n  repeated Message931 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message932 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum131 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message930.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message930 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum130> enum_map = 5;\n  Enum130 status = 6;\n  repeated Enum131 flags = 7;\n  Message931 next = 8;\n  repeated Message932 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message933 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum132 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message931.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message931 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum131> enum_map = 5;\n  Enum131 status = 6;\n  repeated Enum132 flags = 7;\n  Message932 next = 8;\n  repeated Message933 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message934 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum133 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message932.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message932 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum132> enum_map = 5;\n  Enum132 status = 6;\n  repeated Enum133 flags = 7;\n  Message933 next = 8;\n  repeated Message934 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message935 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum134 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message933.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message933 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum133> enum_map = 5;\n  Enum133 status = 6;\n  repeated Enum134 flags = 7;\n  Message934 next = 8;\n  repeated Message935 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message936 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum135 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message934.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message934 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum134> enum_map = 5;\n  Enum134 status = 6;\n  repeated Enum135 flags = 7;\n  Message935 next = 8;\n  repeated Message936 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message937 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum136 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message935.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message935 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum135> enum_map = 5;\n  Enum135 status = 6;\n  repeated Enum136 flags = 7;\n  Message936 next = 8;\n  repeated Message937 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message938 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum137 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message936.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message936 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum136> enum_map = 5;\n  Enum136 status = 6;\n  repeated Enum137 flags = 7;\n  Message937 next = 8;\n  repeated Message938 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message939 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum138 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message937.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message937 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum137> enum_map = 5;\n  Enum137 status = 6;\n  repeated Enum138 flags = 7;\n  Message938 next = 8;\n  repeated Message939 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message940 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum139 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message938.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message938 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum138> enum_map = 5;\n  Enum138 status = 6;\n  repeated Enum139 flags = 7;\n  Message939 next = 8;\n  repeated Message940 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message941 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum140 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message939.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message939 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum139> enum_map = 5;\n  Enum139 status = 6;\n  repeated Enum140 flags = 7;\n  Message940 next = 8;\n  repeated Message941 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message942 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum141 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message940.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message940 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum140> enum_map = 5;\n  Enum140 status = 6;\n  repeated Enum141 flags = 7;\n  Message941 next = 8;\n  repeated Message942 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message943 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum142 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message941.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message941 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum141> enum_map = 5;\n  Enum141 status = 6;\n  repeated Enum142 flags = 7;\n  Message942 next = 8;\n  repeated Message943 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message944 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum143 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message942.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message942 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum142> enum_map = 5;\n  Enum142 status = 6;\n  repeated Enum143 flags = 7;\n  Message943 next = 8;\n  repeated Message944 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message945 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum144 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message943.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message943 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum143> enum_map = 5;\n  Enum143 status = 6;\n  repeated Enum144 flags = 7;\n  Message944 next = 8;\n  repeated Message945 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message946 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum145 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message944.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message944 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum144> enum_map = 5;\n  Enum144 status = 6;\n  repeated Enum145 flags = 7;\n  Message945 next = 8;\n  repeated Message946 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message947 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum146 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message945.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message945 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum145> enum_map = 5;\n  Enum145 status = 6;\n  repeated Enum146 flags = 7;\n  Message946 next = 8;\n  repeated Message947 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message948 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum147 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message946.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message946 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum146> enum_map = 5;\n  Enum146 status = 6;\n  repeated Enum147 flags = 7;\n  Message947 next = 8;\n  repeated Message948 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message949 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum148 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message947.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message947 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum147> enum_map = 5;\n  Enum147 status = 6;\n  repeated Enum148 flags = 7;\n  Message948 next = 8;\n  repeated Message949 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message950 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum149 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message948.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message948 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum148> enum_map = 5;\n  Enum148 status = 6;\n  repeated Enum149 flags = 7;\n  Message949 next = 8;\n  repeated Message950 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message951 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum150 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message949.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message949 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum149> enum_map = 5;\n  Enum149 status = 6;\n  repeated Enum150 flags = 7;\n  Message950 next = 8;\n  repeated Message951 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message952 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum151 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message950.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message950 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum150> enum_map = 5;\n  Enum150 status = 6;\n  repeated Enum151 flags = 7;\n  Message951 next = 8;\n  repeated Message952 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message953 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum152 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message951.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message951 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum151> enum_map = 5;\n  Enum151 status = 6;\n  repeated Enum152 flags = 7;\n  Message952 next = 8;\n  repeated Message953 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message954 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum153 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message952.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message952 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum152> enum_map = 5;\n  Enum152 status = 6;\n  repeated Enum153 flags = 7;\n  Message953 next = 8;\n  repeated Message954 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message955 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum154 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message953.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message953 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum153> enum_map = 5;\n  Enum153 status = 6;\n  repeated Enum154 flags = 7;\n  Message954 next = 8;\n  repeated Message955 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message956 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum155 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message954.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message954 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum154> enum_map = 5;\n  Enum154 status = 6;\n  repeated Enum155 flags = 7;\n  Message955 next = 8;\n  repeated Message956 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message957 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum156 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message955.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message955 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum155> enum_map = 5;\n  Enum155 status = 6;\n  repeated Enum156 flags = 7;\n  Message956 next = 8;\n  repeated Message957 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message958 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum157 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message956.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message956 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum156> enum_map = 5;\n  Enum156 status = 6;\n  repeated Enum157 flags = 7;\n  Message957 next = 8;\n  repeated Message958 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message959 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum158 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message957.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message957 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum157> enum_map = 5;\n  Enum157 status = 6;\n  repeated Enum158 flags = 7;\n  Message958 next = 8;\n  repeated Message959 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message960 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum159 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message958.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message958 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum158> enum_map = 5;\n  Enum158 status = 6;\n  repeated Enum159 flags = 7;\n  Message959 next = 8;\n  repeated Message960 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message961 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum160 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message959.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message959 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum159> enum_map = 5;\n  Enum159 status = 6;\n  repeated Enum160 flags = 7;\n  Message960 next = 8;\n  repeated Message961 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message962 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum161 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message960.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message960 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum160> enum_map = 5;\n  Enum160 status = 6;\n  repeated Enum161 flags = 7;\n  Message961 next = 8;\n  repeated Message962 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message963 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum162 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message961.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message961 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum161> enum_map = 5;\n  Enum161 status = 6;\n  repeated Enum162 flags = 7;\n  Message962 next = 8;\n  repeated Message963 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message964 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum163 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message962.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message962 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum162> enum_map = 5;\n  Enum162 status = 6;\n  repeated Enum163 flags = 7;\n  Message963 next = 8;\n  repeated Message964 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message965 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum164 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message963.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message963 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum163> enum_map = 5;\n  Enum163 status = 6;\n  repeated Enum164 flags = 7;\n  Message964 next = 8;\n  repeated Message965 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message966 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum165 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message964.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message964 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum164> enum_map = 5;\n  Enum164 status = 6;\n  repeated Enum165 flags = 7;\n  Message965 next = 8;\n  repeated Message966 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message967 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum166 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message965.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message965 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum165> enum_map = 5;\n  Enum165 status = 6;\n  repeated Enum166 flags = 7;\n  Message966 next = 8;\n  repeated Message967 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message968 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum167 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message966.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message966 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum166> enum_map = 5;\n  Enum166 status = 6;\n  repeated Enum167 flags = 7;\n  Message967 next = 8;\n  repeated Message968 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message969 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum168 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message967.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message967 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum167> enum_map = 5;\n  Enum167 status = 6;\n  repeated Enum168 flags = 7;\n  Message968 next = 8;\n  repeated Message969 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message970 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum169 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message968.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message968 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum168> enum_map = 5;\n  Enum168 status = 6;\n  repeated Enum169 flags = 7;\n  Message969 next = 8;\n  repeated Message970 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message971 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum170 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message969.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message969 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum169> enum_map = 5;\n  Enum169 status = 6;\n  repeated Enum170 flags = 7;\n  Message970 next = 8;\n  repeated Message971 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message972 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum171 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message970.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message970 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum170> enum_map = 5;\n  Enum170 status = 6;\n  repeated Enum171 flags = 7;\n  Message971 next = 8;\n  repeated Message972 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message973 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum172 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message971.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message971 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum171> enum_map = 5;\n  Enum171 status = 6;\n  repeated Enum172 flags = 7;\n  Message972 next = 8;\n  repeated Message973 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message974 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum173 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message972.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message972 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum172> enum_map = 5;\n  Enum172 status = 6;\n  repeated Enum173 flags = 7;\n  Message973 next = 8;\n  repeated Message974 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message975 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum174 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message973.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message973 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum173> enum_map = 5;\n  Enum173 status = 6;\n  repeated Enum174 flags = 7;\n  Message974 next = 8;\n  repeated Message975 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message976 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum175 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message974.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message974 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum174> enum_map = 5;\n  Enum174 status = 6;\n  repeated Enum175 flags = 7;\n  Message975 next = 8;\n  repeated Message976 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message977 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum176 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message975.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message975 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum175> enum_map = 5;\n  Enum175 status = 6;\n  repeated Enum176 flags = 7;\n  Message976 next = 8;\n  repeated Message977 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message978 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum177 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message976.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message976 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum176> enum_map = 5;\n  Enum176 status = 6;\n  repeated Enum177 flags = 7;\n  Message977 next = 8;\n  repeated Message978 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message979 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum178 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message977.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message977 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum177> enum_map = 5;\n  Enum177 status = 6;\n  repeated Enum178 flags = 7;\n  Message978 next = 8;\n  repeated Message979 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message980 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum179 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message978.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message978 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum178> enum_map = 5;\n  Enum178 status = 6;\n  repeated Enum179 flags = 7;\n  Message979 next = 8;\n  repeated Message980 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message981 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum180 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message979.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message979 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum179> enum_map = 5;\n  Enum179 status = 6;\n  repeated Enum180 flags = 7;\n  Message980 next = 8;\n  repeated Message981 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message982 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum181 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message980.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message980 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum180> enum_map = 5;\n  Enum180 status = 6;\n  repeated Enum181 flags = 7;\n  Message981 next = 8;\n  repeated Message982 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message983 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum182 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message981.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message981 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum181> enum_map = 5;\n  Enum181 status = 6;\n  repeated Enum182 flags = 7;\n  Message982 next = 8;\n  repeated Message983 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message984 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum183 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message982.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message982 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum182> enum_map = 5;\n  Enum182 status = 6;\n  repeated Enum183 flags = 7;\n  Message983 next = 8;\n  repeated Message984 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message985 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum184 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message983.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message983 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum183> enum_map = 5;\n  Enum183 status = 6;\n  repeated Enum184 flags = 7;\n  Message984 next = 8;\n  repeated Message985 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message986 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum185 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message984.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message984 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum184> enum_map = 5;\n  Enum184 status = 6;\n  repeated Enum185 flags = 7;\n  Message985 next = 8;\n  repeated Message986 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message987 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum186 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message985.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message985 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum185> enum_map = 5;\n  Enum185 status = 6;\n  repeated Enum186 flags = 7;\n  Message986 next = 8;\n  repeated Message987 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message988 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum187 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message986.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message986 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum186> enum_map = 5;\n  Enum186 status = 6;\n  repeated Enum187 flags = 7;\n  Message987 next = 8;\n  repeated Message988 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message989 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum188 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message987.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message987 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum187> enum_map = 5;\n  Enum187 status = 6;\n  repeated Enum188 flags = 7;\n  Message988 next = 8;\n  repeated Message989 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message990 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum189 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message988.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message988 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum188> enum_map = 5;\n  Enum188 status = 6;\n  repeated Enum189 flags = 7;\n  Message989 next = 8;\n  repeated Message990 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message991 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum190 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message989.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message989 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum189> enum_map = 5;\n  Enum189 status = 6;\n  repeated Enum190 flags = 7;\n  Message990 next = 8;\n  repeated Message991 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message992 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum191 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message990.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message990 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum190> enum_map = 5;\n  Enum190 status = 6;\n  repeated Enum191 flags = 7;\n  Message991 next = 8;\n  repeated Message992 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message993 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum192 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message991.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message991 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum191> enum_map = 5;\n  Enum191 status = 6;\n  repeated Enum192 flags = 7;\n  Message992 next = 8;\n  repeated Message993 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message994 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum193 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message992.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message992 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum192> enum_map = 5;\n  Enum192 status = 6;\n  repeated Enum193 flags = 7;\n  Message993 next = 8;\n  repeated Message994 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message995 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum194 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message993.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message993 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum193> enum_map = 5;\n  Enum193 status = 6;\n  repeated Enum194 flags = 7;\n  Message994 next = 8;\n  repeated Message995 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message996 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum195 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message994.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message994 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum194> enum_map = 5;\n  Enum194 status = 6;\n  repeated Enum195 flags = 7;\n  Message995 next = 8;\n  repeated Message996 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message997 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum196 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message995.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message995 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum195> enum_map = 5;\n  Enum195 status = 6;\n  repeated Enum196 flags = 7;\n  Message996 next = 8;\n  repeated Message997 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message998 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum197 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message996.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message996 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum196> enum_map = 5;\n  Enum196 status = 6;\n  repeated Enum197 flags = 7;\n  Message997 next = 8;\n  repeated Message998 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message999 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum198 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message997.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message997 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum197> enum_map = 5;\n  Enum197 status = 6;\n  repeated Enum198 flags = 7;\n  Message998 next = 8;\n  repeated Message999 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message0 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum199 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message998.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message998 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum198> enum_map = 5;\n  Enum198 status = 6;\n  repeated Enum199 flags = 7;\n  Message999 next = 8;\n  repeated Message0 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message1 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum0 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message999.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n\nmessage Message999 {\n  // A variety of field types to exercise encoders/decoders\n  string name = 1;\n  repeated int32 numbers = 2;\n  bytes data = 3;\n  map<string, int32> tags = 4;\n  map<int32, Enum199> enum_map = 5;\n  Enum199 status = 6;\n  repeated Enum0 flags = 7;\n  Message0 next = 8;\n  repeated Message1 neighbors = 9;\n  LocalTimestamp updated_at = 10;\n  oneof payload {\n    int64 id = 11;\n    string note = 12;\n    Message2 embedded = 13;\n  }\n  fixed32 checksum = 14;\n  sfixed64 delta = 15;\n  double ratio = 16;\n  float temperature = 17;\n  bool active = 18;\n  message Nested {\n    string foo = 1;\n    Enum1 kind = 2;\n    map<string, string> meta = 3;\n  }\n  Nested nested = 19;\n  map<string, Message0.Nested> nested_map = 20;\n  reserved 100 to 110;\n  reserved \"reserved_field_a\", \"reserved_field_b\";\n}\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/cpp.d.ts",
    "content": "export function question(q: string): string;\nexport function print(s: string): void;\nexport function now(): number;\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/main.tsx",
    "content": "import { question, print } from './cpp';\nimport { runProtoImport } from './ProtoImportTest';\n\nimport { RequireFunc } from 'valdi_core/src/IModuleLoader';\ndeclare const require: RequireFunc;\nconst microbench = require('benchmark/src/microbench');\n\ndeclare const global: any;\n\nconst tests = [\n  {\n    name: 'MicroBench',\n    body: () => {\n      const argv = ['microbench'];\n      microbench.setConsole({ log: print });\n      microbench.main(argv.length, argv, global);\n    },\n  },\n  {\n    name: 'Proto Import',\n    body: () => {\n      const importTime = runProtoImport('benchmark/src/proto.protodecl');\n      const importTimeNoIndex = runProtoImport('benchmark/src/proto_noidx.protodecl');\n      print(`Proto (indexed) imported in ${importTime} ms`);\n      print(`Proto (noindex) imported in ${importTimeNoIndex} ms`);\n    },\n  },\n];\n\nfunction readChoice(): string {\n  print(`Choose the test to run ('q' to exit):`);\n  tests.forEach((t, i) => {\n    print(`${i + 1}. ${t.name}`);\n  });\n  return question(': ');\n}\n\nwhile (true) {\n  const choice = readChoice();\n  if (choice == 'q') break;\n  const n = Math.floor(Number(choice) - 1);\n  if (n >= 0 && n < tests.length) {\n    tests[n].body();\n  } else {\n    print('Invalid choice.');\n  }\n}\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/src/microbench.js",
    "content": "/*\n * Javascript Micro benchmark\n *\n * Copyright (c) 2017-2019 Fabrice Bellard\n * Copyright (c) 2017-2019 Charlie Gordon\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// Modified by Snap to run in Valdi runtime\n\nvar fs = require('FileSystem')\nvar os = require('benchmark/src/cpp') // for 'now'\nvar console = global.console\n\nfunction pad(str, n) {\n    str += \"\";\n    while (str.length < n)\n        str += \" \";\n    return str;\n}\n\nfunction pad_left(str, n) {\n    str += \"\";\n    while (str.length < n)\n        str = \" \" + str;\n    return str;\n}\n\nfunction pad_center(str, n) {\n    str += \"\";\n    while (str.length < n) {\n        if ((n - str.length) & 1)\n            str = str + \" \";\n        else\n            str = \" \" + str;\n    }\n    return str;\n}\n\nfunction toPrec(n, prec) {\n    var i, s;\n    for (i = 0; i < prec; i++)\n        n *= 10;\n    s = \"\" + Math.round(n);\n    for (i = s.length - prec; i <= 0; i++)\n        s = \"0\" + s;\n    if (prec > 0)\n        s = s.substring(0, i) + \".\" + s.substring(i);\n    return s;\n}\n\nvar ref_data;\nvar log_data;\n\nvar heads  = [ \"TEST\", \"N\", \"TIME (ns)\", \"REF (ns)\", \"SCORE (1000)\" ];\nvar widths = [    22,   10,          9,     9,       9 ];\nvar precs  = [     0,   0,           2,     2,       0 ];\nvar total  = [     0,   0,           0,     0,       0 ];\nvar total_score = 0;\nvar total_scale = 0;\n\nfunction log_line() {\n    var i, n, s, a;\n    s = \"\";\n    for (i = 0, n = arguments.length; i < n; i++) {\n        if (i > 0)\n            s += \" \";\n        a = arguments[i];\n        if (typeof a === \"number\") {\n            total[i] += a;\n            a = toPrec(a, precs[i]);\n            s += pad_left(a, widths[i]);\n        } else {\n            s += pad_left(a, widths[i]);\n        }\n    }\n    console.log(s);\n}\n\nvar clocks_per_sec = 1000;\nvar max_iterations = 100;\nvar clock_threshold = 2;  /* favoring short measuring spans */\nvar min_n_argument = 1;\nvar get_clock;\nif (typeof performance !== \"undefined\") {\n    // use more precise clock on NodeJS\n    // need a method call on performance object\n    get_clock = () => performance.now();\n} else\nif (typeof os !== \"undefined\") {\n    // use more precise clock on QuickJS\n    get_clock = os.now;\n} else {\n    // use Date.now and round up to the next millisecond\n    get_clock = () => {\n        var t0 = Date.now();\n        var t;\n        while ((t = Date.now()) == t0)\n            continue;\n        return t;\n    }\n}\n\nfunction log_one(text, n, ti) {\n    var ref;\n\n    if (ref_data)\n        ref = ref_data[text];\n    else\n        ref = null;\n\n    ti = Math.round(ti * 100) / 100;\n    log_data[text] = ti;\n    if (typeof ref === \"number\") {\n        log_line(text, n, ti, ref, Math.round(ref * 1000 / ti));\n        total_score += ti * 100 / ref;\n        total_scale += 100;\n    } else {\n        log_line(text, n, ti);\n        total_score += 100;\n        total_scale += 100;\n    }\n}\n\nfunction bench(f, text)\n{\n    var i, j, n, t, ti, nb_its, ref, ti_n, ti_n1;\n\n    nb_its = n = 1;\n    if (f.bench) {\n        ti_n = f(text);\n    } else {\n        // measure ti_n: the shortest time for an individual operation\n        ti_n = 1000000000;\n        for(i = 0; i < 30; i++) {\n            // measure ti: the shortest time for max_iterations iterations\n            ti = 1000000000;\n            for (j = 0; j < max_iterations; j++) {\n                t = get_clock();\n                nb_its = f(n);\n                t = get_clock() - t;\n                if (nb_its < 0)\n                    return; // test failure\n                if (ti > t)\n                    ti = t;\n            }\n            if (ti >= clock_threshold / 10) {\n                ti_n1 = ti / nb_its;\n                if (ti_n > ti_n1)\n                    ti_n = ti_n1;\n            }\n            if (ti >= clock_threshold && n >= min_n_argument)\n                break;\n\n            n = n * [ 2, 2.5, 2 ][i % 3];\n        }\n        // to use only the best timing from the last loop, uncomment below\n        //ti_n = ti / nb_its;\n    }\n    /* nano seconds per iteration */\n    log_one(text, n, ti_n * 1e9 / clocks_per_sec);\n}\n\nvar global_res; /* to be sure the code is not optimized */\n\nfunction empty_loop(n) {\n    var j;\n    for(j = 0; j < n; j++) {\n    }\n    return n;\n}\n\nfunction empty_down_loop(n) {\n    var j;\n    for(j = n; j > 0; j--) {\n    }\n    return n;\n}\n\nfunction empty_down_loop2(n) {\n    var j;\n    for(j = n; j --> 0;) {\n    }\n    return n;\n}\n\nfunction empty_do_loop(n) {\n    var j = n;\n    do { } while (--j > 0);\n    return n;\n}\n\nfunction date_now(n) {\n    var j;\n    for(j = 0; j < n; j++) {\n        Date.now();\n    }\n    return n;\n}\n\nfunction date_parse(n) {\n    var x0 = 0, dx = 0;\n    var j;\n    for(j = 0; j < n; j++) {\n        var x1 = x0 - x0 % 1000;\n        var x2 = -x0;\n        var x3 = -x1;\n        var d0 = new Date(x0);\n        var d1 = new Date(x1);\n        var d2 = new Date(x2);\n        var d3 = new Date(x3);\n        if (Date.parse(d0.toISOString()) != x0\n        ||  Date.parse(d1.toGMTString()) != x1\n        ||  Date.parse(d1.toString()) != x1\n        ||  Date.parse(d2.toISOString()) != x2\n        ||  Date.parse(d3.toGMTString()) != x3\n        ||  Date.parse(d3.toString()) != x3) {\n            console.log(\"Date.parse error for \" + x0);\n            return -1;\n        }\n        dx = (dx * 1.1 + 1) >> 0;\n        x0 = (x0 + dx) % 8.64e15;\n    }\n    return n * 6;\n}\n\nfunction prop_read(n)\n{\n    var obj, sum, j;\n    obj = {a: 1, b: 2, c:3, d:4 };\n    sum = 0;\n    for(j = 0; j < n; j++) {\n        sum += obj.a;\n        sum += obj.b;\n        sum += obj.c;\n        sum += obj.d;\n    }\n    global_res = sum;\n    return n * 4;\n}\n\nfunction prop_write(n)\n{\n    var obj, j;\n    obj = {a: 1, b: 2, c:3, d:4 };\n    for(j = 0; j < n; j++) {\n        obj.a = j;\n        obj.b = j;\n        obj.c = j;\n        obj.d = j;\n    }\n    return n * 4;\n}\n\nfunction prop_update(n)\n{\n    var obj, j;\n    obj = {a: 1, b: 2, c:3, d:4 };\n    for(j = 0; j < n; j++) {\n        obj.a += j;\n        obj.b += j;\n        obj.c += j;\n        obj.d += j;\n    }\n    return n * 4;\n}\n\nfunction prop_create(n)\n{\n    var obj, i, j;\n    for(j = 0; j < n; j++) {\n        obj = {};\n        obj.a = 1;\n        obj.b = 2;\n        obj.c = 3;\n        obj.d = 4;\n        obj.e = 5;\n        obj.f = 6;\n        obj.g = 7;\n        obj.h = 8;\n        obj.i = 9;\n        obj.j = 10;\n        for(i = 0; i < 10; i++) {\n            obj[i] = i;\n        }\n    }\n    return n * 20;\n}\n\nfunction prop_clone(n)\n{\n    var ref, obj, j, k;\n    ref = { a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10 };\n    for(k = 0; k < 10; k++) {\n        ref[k] = k;\n    }\n    for (j = 0; j < n; j++) {\n        global_res = { ...ref };\n    }\n    return n * 20;\n}\n\nfunction prop_delete(n)\n{\n    var ref, obj, j, k;\n    ref = { a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10 };\n    for(k = 0; k < 10; k++) {\n        ref[k] = k;\n    }\n    for (j = 0; j < n; j++) {\n        obj = { ...ref };\n        delete obj.a;\n        delete obj.b;\n        delete obj.c;\n        delete obj.d;\n        delete obj.e;\n        delete obj.f;\n        delete obj.g;\n        delete obj.h;\n        delete obj.i;\n        delete obj.j;\n        for(k = 0; k < 10; k++) {\n            delete obj[k];\n        }\n    }\n    return n * 20;\n}\n\nfunction array_read(n)\n{\n    var tab, len, sum, i, j;\n    tab = [];\n    len = 10;\n    for(i = 0; i < len; i++)\n        tab[i] = i;\n    sum = 0;\n    for(j = 0; j < n; j++) {\n        sum += tab[0];\n        sum += tab[1];\n        sum += tab[2];\n        sum += tab[3];\n        sum += tab[4];\n        sum += tab[5];\n        sum += tab[6];\n        sum += tab[7];\n        sum += tab[8];\n        sum += tab[9];\n    }\n    global_res = sum;\n    return len * n;\n}\n\nfunction array_write(n)\n{\n    var tab, len, i, j;\n    tab = [];\n    len = 10;\n    for(i = 0; i < len; i++)\n        tab[i] = i;\n    for(j = 0; j < n; j++) {\n        tab[0] = j;\n        tab[1] = j;\n        tab[2] = j;\n        tab[3] = j;\n        tab[4] = j;\n        tab[5] = j;\n        tab[6] = j;\n        tab[7] = j;\n        tab[8] = j;\n        tab[9] = j;\n    }\n    return len * n;\n}\n\nfunction array_prop_create(n)\n{\n    var tab, i, j, len;\n    len = 1000;\n    for(j = 0; j < n; j++) {\n        tab = [];\n        for(i = 0; i < len; i++)\n            tab[i] = i;\n    }\n    return len * n;\n}\n\nfunction array_slice(n)\n{\n    var ref, a, i, j, len;\n    len = 1000;\n    ref = [];\n    for(i = 0; i < len; i++)\n        ref[i] = i;\n    for(j = 0; j < n; j++) {\n        ref[0] = j;\n        a = ref.slice();\n        a[0] = 0;\n        global_res = a;\n    }\n    return len * n;\n}\n\nfunction array_length_decr(n)\n{\n    var tab, ref, i, j, len;\n    len = 1000;\n    ref = [];\n    for(i = 0; i < len; i++)\n        ref[i] = i;\n    for(j = 0; j < n; j++) {\n        tab = ref.slice();\n        for(i = len; i --> 0;)\n            tab.length = i;\n    }\n    return len * n;\n}\n\nfunction array_hole_length_decr(n)\n{\n    var tab, ref, i, j, len;\n    len = 1000;\n    ref = [];\n    for(i = 0; i < len; i++) {\n        if (i % 10 == 9)\n            ref[i] = i;\n    }\n    for(j = 0; j < n; j++) {\n        tab = ref.slice();\n        for(i = len; i --> 0;)\n            tab.length = i;\n    }\n    return len * n;\n}\n\nfunction array_push(n)\n{\n    var tab, i, j, len;\n    len = 500;\n    for(j = 0; j < n; j++) {\n        tab = [];\n        for(i = 0; i < len; i++)\n            tab.push(i);\n    }\n    return len * n;\n}\n\nfunction array_pop(n)\n{\n    var tab, ref, i, j, len, sum;\n    len = 500;\n    ref = [];\n    for(i = 0; i < len; i++)\n        ref[i] = i;\n    for(j = 0; j < n; j++) {\n        tab = ref.slice();\n        sum = 0;\n        for(i = 0; i < len; i++)\n            sum += tab.pop();\n        global_res = sum;\n    }\n    return len * n;\n}\n\nfunction typed_array_read(n)\n{\n    var tab, len, sum, i, j;\n    len = 10;\n    tab = new Int32Array(len);\n    for(i = 0; i < len; i++)\n        tab[i] = i;\n    sum = 0;\n    for(j = 0; j < n; j++) {\n        sum += tab[0];\n        sum += tab[1];\n        sum += tab[2];\n        sum += tab[3];\n        sum += tab[4];\n        sum += tab[5];\n        sum += tab[6];\n        sum += tab[7];\n        sum += tab[8];\n        sum += tab[9];\n    }\n    global_res = sum;\n    return len * n;\n}\n\nfunction typed_array_write(n)\n{\n    var tab, len, i, j;\n    len = 10;\n    tab = new Int32Array(len);\n    for(i = 0; i < len; i++)\n        tab[i] = i;\n    for(j = 0; j < n; j++) {\n        tab[0] = j;\n        tab[1] = j;\n        tab[2] = j;\n        tab[3] = j;\n        tab[4] = j;\n        tab[5] = j;\n        tab[6] = j;\n        tab[7] = j;\n        tab[8] = j;\n        tab[9] = j;\n    }\n    return len * n;\n}\n\nvar global_var0;\n\nfunction global_read(n)\n{\n    var sum, j;\n    global_var0 = 0;\n    sum = 0;\n    for(j = 0; j < n; j++) {\n        sum += global_var0;\n        sum += global_var0;\n        sum += global_var0;\n        sum += global_var0;\n    }\n    global_res = sum;\n    return n * 4;\n}\n\n// non strict version\nvar global_write =\n    (1, eval)(`(function global_write(n)\n           {\n               var j;\n               for(j = 0; j < n; j++) {\n                   global_var0 = j;\n                   global_var0 = j;\n                   global_var0 = j;\n                   global_var0 = j;\n               }\n               return n * 4;\n           })`);\n\nfunction global_write_strict(n)\n{\n    var j;\n    for(j = 0; j < n; j++) {\n        global_var0 = j;\n        global_var0 = j;\n        global_var0 = j;\n        global_var0 = j;\n    }\n    return n * 4;\n}\n\nfunction local_destruct(n)\n{\n    var j, v1, v2, v3, v4;\n    var array = [ 1, 2, 3, 4, 5];\n    var o = { a:1, b:2, c:3, d:4 };\n    var a, b, c, d;\n    for(j = 0; j < n; j++) {\n        [ v1, v2,, v3, ...v4] = array;\n        ({ a, b, c, d } = o);\n        ({ a: a, b: b, c: c, d: d } = o);\n    }\n    return n * 12;\n}\n\nvar global_v1, global_v2, global_v3, global_v4;\nvar global_a, global_b, global_c, global_d;\n\n// non strict version\nvar global_destruct =\n    (1, eval)(`(function global_destruct(n)\n           {\n               var j, v1, v2, v3, v4;\n               var array = [ 1, 2, 3, 4, 5 ];\n               var o = { a:1, b:2, c:3, d:4 };\n               var a, b, c, d;\n               for(j = 0; j < n; j++) {\n                   [ global_v1, global_v2,, global_v3, ...global_v4] = array;\n                   ({ a: global_a, b: global_b, c: global_c, d: global_d } = o);\n               }\n               return n * 8;\n          })`);\n\nfunction global_destruct_strict(n)\n{\n    var j, v1, v2, v3, v4;\n    var array = [ 1, 2, 3, 4, 5 ];\n    var o = { a:1, b:2, c:3, d:4 };\n    var a, b, c, d;\n    for(j = 0; j < n; j++) {\n        [ global_v1, global_v2,, global_v3, ...global_v4] = array;\n        ({ a: global_a, b: global_b, c: global_c, d: global_d } = o);\n    }\n    return n * 8;\n}\n\nfunction g(a)\n{\n    return 1;\n}\n\nfunction global_func_call(n)\n{\n    var j, sum;\n    sum = 0;\n    for(j = 0; j < n; j++) {\n        sum += g(j);\n        sum += g(j);\n        sum += g(j);\n        sum += g(j);\n    }\n    global_res = sum;\n    return n * 4;\n}\n\nfunction func_call(n)\n{\n    function f(a)\n    {\n        return 1;\n    }\n\n    var j, sum;\n    sum = 0;\n    for(j = 0; j < n; j++) {\n        sum += f(j);\n        sum += f(j);\n        sum += f(j);\n        sum += f(j);\n    }\n    global_res = sum;\n    return n * 4;\n}\n\nfunction func_closure_call(n)\n{\n    function f(a)\n    {\n        sum++;\n    }\n\n    var j, sum;\n    sum = 0;\n    for(j = 0; j < n; j++) {\n        f(j);\n        f(j);\n        f(j);\n        f(j);\n    }\n    global_res = sum;\n    return n * 4;\n}\n\nfunction int_arith(n)\n{\n    var i, j, sum;\n    global_res = 0;\n    for(j = 0; j < n; j++) {\n        sum = 0;\n        for(i = 0; i < 1000; i++) {\n            sum += i * i;\n        }\n        global_res += sum;\n    }\n    return n * 1000;\n}\n\nfunction float_arith(n)\n{\n    var i, j, sum, a, incr, a0;\n    global_res = 0;\n    a0 = 0.1;\n    incr = 1.1;\n    for(j = 0; j < n; j++) {\n        sum = 0;\n        a = a0;\n        for(i = 0; i < 1000; i++) {\n            sum += a * a;\n            a += incr;\n        }\n        global_res += sum;\n    }\n    return n * 1000;\n}\n\nfunction bigfloat_arith(n)\n{\n    var i, j, sum, a, incr, a0;\n    global_res = 0;\n    a0 = BigFloat(\"0.1\");\n    incr = BigFloat(\"1.1\");\n    for(j = 0; j < n; j++) {\n        sum = 0;\n        a = a0;\n        for(i = 0; i < 1000; i++) {\n            sum += a * a;\n            a += incr;\n        }\n        global_res += sum;\n    }\n    return n * 1000;\n}\n\nfunction float256_arith(n)\n{\n    return BigFloatEnv.setPrec(bigfloat_arith.bind(null, n), 237, 19);\n}\n\nfunction bigint_arith(n, bits)\n{\n    var i, j, sum, a, incr, a0, sum0;\n    sum0 = global_res = BigInt(0);\n    a0 = BigInt(1) << BigInt(Math.floor((bits - 10) * 0.5));\n    incr = BigInt(1);\n    for(j = 0; j < n; j++) {\n        sum = sum0;\n        a = a0;\n        for(i = 0; i < 1000; i++) {\n            sum += a * a;\n            a += incr;\n        }\n        global_res += sum;\n    }\n    return n * 1000;\n}\n\nfunction bigint64_arith(n)\n{\n    return bigint_arith(n, 64);\n}\n\nfunction bigint256_arith(n)\n{\n    return bigint_arith(n, 256);\n}\n\nfunction set_collection_add(n)\n{\n    var s, i, j, len = 100;\n    for(j = 0; j < n; j++) {\n        s = new Set();\n        for(i = 0; i < len; i++) {\n            s.add(String(i), i);\n        }\n        for(i = 0; i < len; i++) {\n            if (!s.has(String(i)))\n                throw Error(\"bug in Set\");\n        }\n    }\n    return n * len;\n}\n\nfunction array_for(n)\n{\n    var r, i, j, sum, len = 100;\n    r = [];\n    for(i = 0; i < len; i++)\n        r[i] = i;\n    for(j = 0; j < n; j++) {\n        sum = 0;\n        for(i = 0; i < len; i++) {\n            sum += r[i];\n        }\n        global_res = sum;\n    }\n    return n * len;\n}\n\nfunction array_for_in(n)\n{\n    var r, i, j, sum, len = 100;\n    r = [];\n    for(i = 0; i < len; i++)\n        r[i] = i;\n    for(j = 0; j < n; j++) {\n        sum = 0;\n        for(i in r) {\n            sum += r[i];\n        }\n        global_res = sum;\n    }\n    return n * len;\n}\n\nfunction array_for_of(n)\n{\n    var r, i, j, sum, len = 100;\n    r = [];\n    for(i = 0; i < len; i++)\n        r[i] = i;\n    for(j = 0; j < n; j++) {\n        sum = 0;\n        for(i of r) {\n            sum += i;\n        }\n        global_res = sum;\n    }\n    return n * len;\n}\n\nfunction math_min(n)\n{\n    var i, j, r;\n    r = 0;\n    for(j = 0; j < n; j++) {\n        for(i = 0; i < 1000; i++)\n            r = Math.min(i, 500);\n        global_res = r;\n    }\n    return n * 1000;\n}\n\nfunction regexp_ascii(n)\n{\n    var i, j, r, s;\n    s = \"the quick brown fox jumped over the lazy dog\"\n    for(j = 0; j < n; j++) {\n        for(i = 0; i < 1000; i++)\n            r = /the quick brown fox/.exec(s)\n        global_res = r;\n    }\n    return n * 1000;\n}\n\nfunction regexp_utf16(n)\n{\n    var i, j, r, s;\n    s = \"the quick brown ᶠᵒˣ jumped over the lazy ᵈᵒᵍ\"\n    for(j = 0; j < n; j++) {\n        for(i = 0; i < 1000; i++)\n            r = /the quick brown ᶠᵒˣ/.exec(s)\n        global_res = r;\n    }\n    return n * 1000;\n}\n\n/* incremental string contruction as local var */\nfunction string_build1(n)\n{\n    var i, j, r;\n    for(j = 0; j < n; j++) {\n        r = \"\";\n        for(i = 0; i < 1000; i++)\n            r += \"x\";\n        global_res = r;\n    }\n    return n * 1000;\n}\n\n/* incremental string contruction using + */\nfunction string_build1x(n)\n{\n    var i, j, r;\n    for(j = 0; j < n; j++) {\n        r = \"\";\n        for(i = 0; i < 1000; i++)\n            r = r + \"x\";\n        global_res = r;\n    }\n    return n * 1000;\n}\n\n/* incremental string contruction using +2c */\nfunction string_build2c(n)\n{\n    var i, j;\n    for(j = 0; j < n; j++) {\n        var r = \"\";\n        for(i = 0; i < 1000; i++)\n            r += \"xy\";\n        global_res = r;\n    }\n    return n * 1000;\n}\n\n/* incremental string contruction as arg */\nfunction string_build2(n, r)\n{\n    var i, j;\n    for(j = 0; j < n; j++) {\n        r = \"\";\n        for(i = 0; i < 1000; i++)\n            r += \"x\";\n        global_res = r;\n    }\n    return n * 1000;\n}\n\n/* incremental string contruction by prepending */\nfunction string_build3(n)\n{\n    var i, j, r;\n    for(j = 0; j < n; j++) {\n        r = \"\";\n        for(i = 0; i < 1000; i++)\n            r = \"x\" + r;\n        global_res = r;\n    }\n    return n * 1000;\n}\n\n/* incremental string contruction with multiple reference */\nfunction string_build4(n)\n{\n    var i, j, r, s;\n    for(j = 0; j < n; j++) {\n        r = \"\";\n        for(i = 0; i < 1000; i++) {\n            s = r;\n            r += \"x\";\n        }\n        global_res = r;\n    }\n    return n * 1000;\n}\n\n/* sort bench */\n\nfunction sort_bench(text) {\n    function random(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[(Math.random() * n) >> 0];\n    }\n    function random8(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[(Math.random() * 256) >> 0];\n    }\n    function random1(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[(Math.random() * 2) >> 0];\n    }\n    function hill(arr, n, def) {\n        var mid = n >> 1;\n        for (var i = 0; i < mid; i++)\n            arr[i] = def[i];\n        for (var i = mid; i < n; i++)\n            arr[i] = def[n - i];\n    }\n    function comb(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[(i & 1) * i];\n    }\n    function crisscross(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[(i & 1) ? n - i : i];\n    }\n    function zero(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[0];\n    }\n    function increasing(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[i];\n    }\n    function decreasing(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[n - 1 - i];\n    }\n    function alternate(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[i ^ 1];\n    }\n    function jigsaw(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[i % (n >> 4)];\n    }\n    function incbutone(arr, n, def) {\n        for (var i = 0; i < n; i++)\n            arr[i] = def[i];\n        if (n > 0)\n            arr[n >> 2] = def[n];\n    }\n    function incbutfirst(arr, n, def) {\n        if (n > 0)\n            arr[0] = def[n];\n        for (var i = 1; i < n; i++)\n            arr[i] = def[i];\n    }\n    function incbutlast(arr, n, def) {\n        for (var i = 0; i < n - 1; i++)\n            arr[i] = def[i + 1];\n        if (n > 0)\n            arr[n - 1] = def[0];\n    }\n\n    var sort_cases = [ random, random8, random1, jigsaw, hill, comb,\n                      crisscross, zero, increasing, decreasing, alternate,\n                      incbutone, incbutlast, incbutfirst ];\n\n    var n = sort_bench.array_size || 10000;\n    var array_type = sort_bench.array_type || Array;\n    var def, arr;\n    var i, j, x, y;\n    var total = 0;\n\n    var save_total_score = total_score;\n    var save_total_scale = total_scale;\n\n    // initialize default sorted array (n + 1 elements)\n    def = new array_type(n + 1);\n    if (array_type == Array) {\n        for (i = 0; i <= n; i++) {\n            def[i] = i + \"\";\n        }\n    } else {\n        for (i = 0; i <= n; i++) {\n            def[i] = i;\n        }\n    }\n    def.sort();\n    for (var f of sort_cases) {\n        var ti = 0, tx = 0;\n        for (j = 0; j < 100; j++) {\n            arr = new array_type(n);\n            f(arr, n, def);\n            var t1 = get_clock();\n            arr.sort();\n            t1 = get_clock() - t1;\n            tx += t1;\n            if (!ti || ti > t1)\n                ti = t1;\n            if (tx >= clocks_per_sec)\n                break;\n        }\n        total += ti;\n\n        i = 0;\n        x = arr[0];\n        if (x !== void 0) {\n            for (i = 1; i < n; i++) {\n                y = arr[i];\n                if (y === void 0)\n                    break;\n                if (x > y)\n                    break;\n                x = y;\n            }\n        }\n        while (i < n && arr[i] === void 0)\n            i++;\n        if (i < n) {\n            console.log(\"sort_bench: out of order error for \" + f.name +\n                        \" at offset \" + (i - 1) +\n                        \": \" + arr[i - 1] + \" > \" + arr[i]);\n        }\n        if (sort_bench.verbose)\n            log_one(\"sort_\" + f.name, 1, ti / 100);\n    }\n    total_score = save_total_score;\n    total_scale = save_total_scale;\n    return total / n / 100;\n}\nsort_bench.bench = true;\nsort_bench.verbose = false;\n\nfunction int_to_string(n)\n{\n    var s, j;\n    for(j = 0; j < n; j++) {\n        s = (j % 1000).toString();\n        s = (1234000 + j % 1000).toString();\n    }\n    global_res = s;\n    return n * 2;\n}\n\nfunction float_to_string(n)\n{\n    var s, j;\n    for(j = 0; j < n; j++) {\n        s = (j + 0.1).toString();\n    }\n    global_res = s;\n    return n;\n}\n\nfunction string_to_int(n)\n{\n    var s, r, j;\n    r = 0;\n    s = \"12345\";\n    for(j = 0; j < n; j++) {\n        r += (s | 0);\n    }\n    global_res = r;\n    return n;\n}\n\nfunction string_to_float(n)\n{\n    var s, r, j;\n    r = 0;\n    s = \"12345.6\";\n    for(j = 0; j < n; j++) {\n        r -= s;\n    }\n    global_res = r;\n    return n;\n}\n\nfunction load_result(filename)\n{\n    var has_filename = filename;\n    var has_error = false;\n    var str, res;\n\n    if (!filename)\n        filename = \"microbench.txt\";\n\n    if (typeof fs !== \"undefined\") {\n        // read the file in Node.js\n        try {\n            str = fs.readFileSync(filename, { encoding: \"utf8\" });\n        } catch {\n            has_error = true;\n        }\n    } else\n    if (typeof std !== \"undefined\") {\n        // read the file in QuickJS\n        var f = std.open(filename, \"r\");\n        if (f) {\n            str = f.readAsString();\n            f.close();\n        } else {\n            has_error = true;\n        }\n    } else {\n        return null;\n    }\n    if (has_error) {\n        if (has_filename) {\n            // Should throw exception?\n            console.log(\"cannot load \" + filename);\n        }\n        return null;\n    }\n    res = JSON.parse(str);\n    return res;\n}\n\nfunction save_result(filename, obj)\n{\n    var str = JSON.stringify(obj, null, 2) + \"\\n\";\n    var has_error = false;\n\n    if (typeof fs !== \"undefined\") {\n        // save the file in Node.js\n        try {\n            str = fs.writeFileSync(filename, str, { encoding: \"utf8\" });\n        } catch {\n            has_error = true;\n        }\n    } else\n    if (typeof std !== \"undefined\") {\n        // save the file in QuickJS\n        var f = std.open(filename, \"w\");\n        if (f) {\n            f.puts(str);\n            f.close();\n        } else {\n            has_error = 'true';\n        }\n    } else {\n        return;\n    }\n    if (has_error)\n        console.log(\"cannot save \" + filename);\n}\n\nfunction main(argc, argv, g)\n{\n    var test_list = [\n        empty_loop,\n        empty_down_loop,\n        empty_down_loop2,\n        empty_do_loop,\n        date_now,\n        date_parse,\n        prop_read,\n        prop_write,\n        prop_update,\n        prop_create,\n        prop_clone,\n        prop_delete,\n        array_read,\n        array_write,\n        array_prop_create,\n        array_slice,\n        array_length_decr,\n        array_hole_length_decr,\n        array_push,\n        array_pop,\n        typed_array_read,\n        typed_array_write,\n        global_read,\n        global_write,\n        global_write_strict,\n        local_destruct,\n        global_destruct,\n        global_destruct_strict,\n        global_func_call,\n        func_call,\n        func_closure_call,\n        int_arith,\n        float_arith,\n        set_collection_add,\n        array_for,\n        array_for_in,\n        array_for_of,\n        math_min,\n        regexp_ascii,\n        regexp_utf16,\n        string_build1,\n        string_build1x,\n        string_build2c,\n        string_build2,\n        string_build3,\n        string_build4,\n        int_to_string,\n        float_to_string,\n        string_to_int,\n        string_to_float,\n    ];\n    var tests = [];\n    var i, j, n, f, name, found;\n    var ref_file, new_ref_file = \"microbench-new.txt\";\n\n    if (typeof BigInt === \"function\") {\n        /* BigInt test */\n        test_list.push(bigint64_arith);\n        test_list.push(bigint256_arith);\n    }\n    if (typeof BigFloat === \"function\") {\n        /* BigFloat test */\n        test_list.push(float256_arith);\n    }\n    test_list.push(sort_bench);\n\n    console.log('parsing command line');\n    for (i = 1; i < argc;) {\n        name = argv[i++];\n        if (name == \"-a\") {\n            sort_bench.verbose = true;\n            continue;\n        }\n        if (name == \"-t\") {\n            name = argv[i++];\n            sort_bench.array_type = g[name];\n            if (typeof sort_bench.array_type !== \"function\") {\n                console.log(\"unknown array type: \" + name);\n                return 1;\n            }\n            continue;\n        }\n        if (name == \"-n\") {\n            sort_bench.array_size = +argv[i++];\n            continue;\n        }\n        if (name == \"-r\") {\n            ref_file = argv[i++];\n            log_line(\"use ref file > \" + new_ref_file);\n            continue;\n        }\n        if (name == \"-s\") {\n            new_ref_file = argv[i++];\n            continue;\n        }\n        console.log('looking for test ' + name);\n        for (j = 0, found = false; j < test_list.length; j++) {\n            f = test_list[j];\n            if (f.name.startsWith(name)) {\n                tests.push(f);\n                found = true;\n            }\n        }\n        if (!found) {\n            console.log(\"unknown benchmark: \" + name);\n            return 1;\n        }\n    }\n    if (tests.length == 0)\n        tests = test_list;\n\n    if (ref_file) {\n        ref_data = load_result(ref_file);\n    }\n    log_data = {};\n    log_line.apply(null, heads);\n    n = 0;\n\n    for(i = 0; i < tests.length; i++) {\n        f = tests[i];\n        bench(f, f.name, ref_data, log_data);\n        if (ref_data && ref_data[f.name])\n            n++;\n    }\n    if (ref_data)\n        log_line(\"total\", \"\", total[2], total[3], Math.round(total_scale * 1000 / total_score));\n    else\n        log_line(\"total\", \"\", total[2]);\n\n    if (tests == test_list && new_ref_file)\n        save_result(new_ref_file, log_data);\n}\n\nmodule.exports.main = main\nmodule.exports.setConsole = function (c) {\n    console = c\n}\n"
  },
  {
    "path": "apps/benchmark/src/valdi/benchmark/tsconfig.json",
    "content": "{\n  \"extends\": \"../../../../../modules/_configs/base.tsconfig.json\",\n  \"compilerOptions\": {\n    \"types\": [\"../../../../../modules/types/Long\", \"../../../../../modules/types/globals\"],\n    \"paths\": {\n      \"benchmark/*\": [\"./src/*\"],\n      \"valdi_tsx/*\": [\"../../../../../src/valdi_modules/src/valdi/valdi_tsx/*\"],\n      \"valdi_navigation/*\": [\n        \"../../../../../src/valdi_modules/src/valdi/valdi_navigation/*\"\n      ],\n      \"valdi_core/*\": [\n        \"../../../../../src/valdi_modules/src/valdi/valdi_core/*\"\n      ],\n      \"valdi_protobuf/*\": [\n        \"../../../../../src/valdi_modules/src/valdi/valdi_protobuf/*\"\n      ],\n      \"tslib\": [\n        \"../../../../../src/valdi_modules/src/valdi/valdi_core/src/tslib.d.ts\"\n      ],\n      \"coreutils/*\": [\n        \"../../../../../src/valdi_modules/src/valdi/coreutils/*\"\n      ],\n    }\n  }\n}\n"
  },
  {
    "path": "apps/cli_example/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_cli_application.bzl\", \"valdi_cli_application\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"cli_example\",\n    srcs = glob([\n        \"**/*.ts\",\n        \"**/*.tsx\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [],\n)\n\nvaldi_cli_application(\n    name = \"cli_example_app\",\n    script_path = \"cli_example/index\",\n    deps = [\":cli_example\"],\n)\n"
  },
  {
    "path": "apps/cli_example/index.tsx",
    "content": "console.log('Hello world!');"
  },
  {
    "path": "apps/helloworld/.eslintrc.js",
    "content": "\nmodule.exports = {\n  root: true,\n  parser: '@typescript-eslint/parser',\n  parserOptions: {\n    tsconfigRootDir: __dirname,\n    project: ['./src/valdi/_configs/eslint.tsconfig.json'],\n  },\n  plugins: ['@typescript-eslint', 'unused-imports', 'rxjs', 'prettier', '@snap/eslint-plugin-valdi'],\n  extends: [\n    'eslint:recommended',\n    'plugin:@typescript-eslint/recommended',\n    'plugin:import/recommended',\n    'plugin:import/typescript',\n    'prettier',\n  ],\n  rules: { \n    '@snap/valdi/attributed-text-no-array-assignment': 'error',\n    '@snap/valdi/jsx-no-lambda': 'error',\n    '@snap/valdi/assign-timer-id': 'error',\n    '@snap/valdi/only-const-enum': 'off',\n    '@snap/valdi/no-implicit-index-import': 'error',\n    '@snap/valdi/mutate-state-without-set-state': 'error',\n    '@snap/valdi/no-import-from-test-outside-test-dir': 'error',\n    '@snap/valdi/no-declare-test-without-describe': 'error', \n  },\n};\n"
  },
  {
    "path": "apps/helloworld/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_application.bzl\", \"valdi_application\")\nload(\"//bzl/valdi:valdi_exported_library.bzl\", \"valdi_exported_library\")\n\nvaldi_application(\n    name = \"hello_world\",\n    android_activity_theme_name = \"Theme.MyApp.Launch\",\n    android_app_icon_name = \"app_icon\",\n    android_resource_files = glob([\"app_assets/android/**\"]),\n    ios_app_icons = glob([\"app_assets/ios/Icons.xcassets/**\"]),\n    ios_bundle_id = \"com.snap.valdi.helloworld\",\n    ios_families = [\"iphone\"],\n    root_component_path = \"App@hello_world/src/HelloWorldApp\",\n    title = \"Valdi Hello World\",\n    version = \"1.0.0\",\n    deps = [\"//apps/helloworld/src/valdi/hello_world\"],\n)\n\nvaldi_exported_library(\n    name = \"hello_world_export\",\n    ios_bundle_id = \"com.snap.hello_world.lib\",\n    ios_bundle_name = \"HelloWorld\",\n    deps = [\"//apps/helloworld/src/valdi/hello_world\"],\n)\n"
  },
  {
    "path": "apps/helloworld/app_assets/android/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"splash_bg\">#FFFFFF</color>\n</resources>\n"
  },
  {
    "path": "apps/helloworld/app_assets/android/values/themes.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <style name=\"Theme.MyApp.Launch\" parent=\"Theme.AppCompat.Light.NoActionBar\">\n        <item name=\"android:windowBackground\">@drawable/splash</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "apps/helloworld/app_assets/ios/Icons.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\": [\n    {\n      \"size\": \"60x60\",\n      \"expected-size\": \"180\",\n      \"filename\": \"180.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"expected-size\": \"80\",\n      \"filename\": \"80.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"expected-size\": \"120\",\n      \"filename\": \"120.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"60x60\",\n      \"expected-size\": \"120\",\n      \"filename\": \"120.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"58\",\n      \"filename\": \"58.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"29\",\n      \"filename\": \"29.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"87\",\n      \"filename\": \"87.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"expected-size\": \"40\",\n      \"filename\": \"40.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"expected-size\": \"60\",\n      \"filename\": \"60.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"iphone\",\n      \"scale\": \"3x\"\n    },\n    {\n      \"size\": \"1024x1024\",\n      \"filename\": \"1024.png\",\n      \"expected-size\": \"1024\",\n      \"idiom\": \"ios-marketing\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"expected-size\": \"80\",\n      \"filename\": \"80.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"76x76\",\n      \"expected-size\": \"152\",\n      \"filename\": \"152.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"58\",\n      \"filename\": \"58.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"29x29\",\n      \"expected-size\": \"29\",\n      \"filename\": \"29.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"40x40\",\n      \"expected-size\": \"40\",\n      \"filename\": \"40.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"83.5x83.5\",\n      \"expected-size\": \"167\",\n      \"filename\": \"167.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"expected-size\": \"20\",\n      \"filename\": \"20.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"1x\"\n    },\n    {\n      \"size\": \"20x20\",\n      \"expected-size\": \"40\",\n      \"filename\": \"40.png\",\n      \"folder\": \"Assets.xcassets/AppIcon.appiconset/\",\n      \"idiom\": \"ipad\",\n      \"scale\": \"2x\"\n    }\n  ]\n}\n"
  },
  {
    "path": "apps/helloworld/package.json",
    "content": "{\n  \"name\": \"hello_world\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Valdi Helloworld app\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@snap/eslint-plugin-valdi\": \"1.0.1\",\n    \"@types/eslint\": \"^9.6.1\",\n    \"@types/jasmine\": \"^5.1.7\",\n    \"@typescript-eslint/eslint-plugin\": \"^6.21.0\",\n    \"@typescript-eslint/parser\": \"^6.21.0\",\n    \"@typescript-eslint/utils\": \"^6.21.0\",\n    \"eslint\": \"^8.27.0\",\n    \"eslint-config-prettier\": \"^8.5.0\",\n    \"eslint-plugin-import\": \"^2.26.0\",\n    \"eslint-plugin-prettier\": \"^4.2.1\",\n    \"eslint-plugin-rxjs\": \"^5.0.2\",\n    \"eslint-plugin-unused-imports\": \"^3.2.0\",\n    \"jasmine\": \"^5.6.0\",\n    \"ts-node\": \"^10.9.2\",\n    \"typescript\": \"5.3.3\"\n  }\n}\n"
  },
  {
    "path": "apps/helloworld/src/android/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_android_library.bzl\", \"valdi_android_library\")\n\nvaldi_android_library(\n    name = \"native_module_android\",\n    srcs = glob([\n        \"**/*.kt\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//apps/helloworld/src/valdi/hello_world:hello_world_api_kt\",\n        \"//valdi:valdi_android_support\",\n    ],\n)\n"
  },
  {
    "path": "apps/helloworld/src/android/MyNativeModuleFactory.kt",
    "content": "package com.snap.valdi.helloworld\n\nimport com.snapchat.client.valdi_core.ModuleFactory\nimport com.snap.valdi.modules.RegisterValdiModule\nimport com.snap.valdi.modules.hello_world.NativeModuleModuleFactory\nimport com.snap.valdi.modules.hello_world.NativeModuleModule\n\n@RegisterValdiModule\nclass MyNativeModuleFactory: NativeModuleModuleFactory() {\n\n    override fun onLoadModule(): NativeModuleModule {\n        return object: NativeModuleModule {\n            override val APP_NAME = \"Valdi Android\"\n        }\n    }\n}"
  },
  {
    "path": "apps/helloworld/src/cpp/BUILD.bazel",
    "content": "cc_library(\n    name = \"native_module_cpp\",\n    srcs = [\"CppModule.cpp\"] + select({\n        \"@valdi//bzl/conditions:macos\": [\"DesktopMyNativeModule.cpp\"],\n        \"@valdi//bzl/conditions:linux\": [\"DesktopMyNativeModule.cpp\"],\n        \"//conditions:default\": [],\n    }),\n    hdrs = [],\n    includes = [],\n    visibility = [\"//visibility:public\"],\n    deps = [\"@valdi//valdi_core\"],\n    alwayslink = 1,\n)\n"
  },
  {
    "path": "apps/helloworld/src/cpp/CppModule.cpp",
    "content": "#include \"valdi_core/cpp/JavaScript/ModuleFactoryRegistry.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n#include \"valdi_core/cpp/Utils/ValueFunctionWithCallable.hpp\"\n\nnamespace snap::valdi::hello_world {\n\nclass CppModule : public valdi_core::ModuleFactory {\npublic:\n    CppModule() = default;\n    ~CppModule() override = default;\n\n    Valdi::StringBox getModulePath() final {\n        return Valdi::StringBox::fromCString(\"hello_world/src/CppModule\");\n    }\n\n    Valdi::Value loadModule() final {\n        return Valdi::Value().setMapValue(\"onRootComponentCreated\",\n                                          Valdi::Value(Valdi::makeShared<Valdi::ValueFunctionWithCallable>(\n                                              [](const Valdi::ValueFunctionCallContext& callContext) -> Valdi::Value {\n                                                  VALDI_INFO(Valdi::ConsoleLogger::getLogger(),\n                                                             \"From C++: Root component created with contextId '{}'\",\n                                                             callContext.getParameter(0).toString(false));\n                                                  return Valdi::Value();\n                                              })));\n    }\n};\n\nauto kRegisterModule = Valdi::RegisterModuleFactory::registerTyped<CppModule>();\n\n} // namespace snap::valdi::hello_world"
  },
  {
    "path": "apps/helloworld/src/cpp/DesktopMyNativeModule.cpp",
    "content": "#include \"valdi_core/cpp/JavaScript/ModuleFactoryRegistry.hpp\"\n\nnamespace snap::valdi::hello_world {\n\nclass DesktopMyNativeModule : public valdi_core::ModuleFactory {\npublic:\n    DesktopMyNativeModule() = default;\n    ~DesktopMyNativeModule() override = default;\n\n    Valdi::StringBox getModulePath() final {\n        return Valdi::StringBox::fromCString(\"hello_world/src/NativeModule\");\n    }\n\n    Valdi::Value loadModule() final {\n        return Valdi::Value().setMapValue(\"APP_NAME\", Valdi::Value(\"Valdi Desktop\"));\n    }\n};\n\nauto kRegisterDesktopModule = Valdi::RegisterModuleFactory::registerTyped<DesktopMyNativeModule>();\n\n} // namespace snap::valdi::hello_world"
  },
  {
    "path": "apps/helloworld/src/ios/BUILD.bazel",
    "content": "objc_library(\n    name = \"native_module_ios\",\n    srcs = glob([\n        \"**/*.m\",\n    ]),\n    hdrs = [],\n    copts = [\"-I.\"],\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//apps/helloworld/src/valdi/hello_world:hello_world_api_objc\",\n    ],\n)\n"
  },
  {
    "path": "apps/helloworld/src/ios/SCMyNativeModuleFactory.m",
    "content": "#import \"valdi_core/SCValdiModuleFactoryRegistry.h\"\n#import <SCCHelloWorldTypes/SCCHelloWorldTypes.h>\n#import <Foundation/Foundation.h>\n\n@interface SCMyNativeModule: NSObject<SCCHelloWorldNativeModuleModule>\n\n@end\n\n@implementation SCMyNativeModule\n\n- (NSString *)APP_NAME\n{\n    return @\"Valdi iOS\";\n}\n\n- (void)setAPP_NAME:(NSString *)appName\n{\n\n}\n\n@end\n\n@interface SCMyNativeModuleFactory : SCCHelloWorldNativeModuleModuleFactory\n\n@end\n\n@implementation SCMyNativeModuleFactory\n\nVALDI_REGISTER_MODULE()\n\n- (id<SCCHelloWorldNativeModuleModule>)onLoadModule\n{\n    return [SCMyNativeModule new];\n}\n\n@end"
  },
  {
    "path": "apps/helloworld/src/valdi/.terserrc.json",
    "content": "{\n  \"ecma\": \"ES2016\",\n  \"safari10\": true,\n  \"mangle\": {\n    \"toplevel\": true,\n    \"keep_classnames\": true\n  },\n  \"compress\": {\n    \"keep_classnames\": true\n  },\n  \"sourceMap\": {\n    \"content\": \"inline\",\n    \"url\": \"inline\"\n  }\n}\n"
  },
  {
    "path": "apps/helloworld/src/valdi/_configs/base.tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"target\": \"ES2016\",\n    \"module\": \"commonjs\",\n    \"baseUrl\": \"../../../../\",\n    \"paths\": {\n      \"tslib\": [\n        \"./valdi_core/src/tslib.d.ts\",\n        \"../src/valdi_modules/src/valdi/valdi_core/src/tslib.d.ts\"\n      ],\n      \"jasmine\": [\n        \"./jasmine/src/jasmine.d.ts\",\n        \"../src/valdi_modules/src/valdi/jasmine/src/jasmine.d.ts\"\n      ],\n      \"*\": [\n        \"*\",\n        \"../src/valdi_modules/src/valdi/*\",\n        \"../../.valdi_build/hotreload/generated_ts/*\",\n        \"../../.valdi_build/compile/generated_ts/*\"\n      ]\n    },\n    \"lib\": [\"dom\", \"ES2019\"],\n    \"noImplicitReturns\": true,\n    \"noImplicitAny\": true,\n    \"importHelpers\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"jsx\": \"preserve\",\n    \"rootDirs\": [\n      \"..\",\n      \"../../../.valdi_build/hotreload/generated_ts\",\n      \"../../../.valdi_build/compile/generated_ts\"\n    ],\n    \"types\": [\"../types/Long\", \"../types/globals\"],\n    \"typeRoots\": [\".\"]\n  }\n}\n"
  },
  {
    "path": "apps/helloworld/src/valdi/_configs/eslint.tsconfig.json",
    "content": "{\n  \"extends\": \"./base.tsconfig.json\",\n  \"include\": [\"../**/*.ts\", \"../**/*.tsx\"]\n}\n"
  },
  {
    "path": "apps/helloworld/src/valdi/hello_world/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"hello_world\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_class_path = \"com.snap.valdi.modules.hello_world\",\n    android_deps = [\"//apps/helloworld/src/android:native_module_android\"],\n    android_output_target = \"release\",\n    ios_deps = [\"//apps/helloworld/src/ios:native_module_ios\"],\n    ios_module_name = \"SCCHelloWorld\",\n    ios_output_target = \"release\",\n    native_deps = [\"//apps/helloworld/src/cpp:native_module_cpp\"],\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "apps/helloworld/src/valdi/hello_world/src/CppModule.d.ts",
    "content": "export function onRootComponentCreated(contextId: string): void;\n"
  },
  {
    "path": "apps/helloworld/src/valdi/hello_world/src/GettingStartedCodelab.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { systemBoldFont, systemFont } from 'valdi_core/src/SystemFont';\n\nexport class GettingStartedCodelab extends Component {\n  onRender() {\n    <layout padding={24} paddingTop={80}>\n      <label value=\"Getting started codelab!\" font={systemBoldFont(16)} />\n      <label value=\"gitub.com/Snapchat/Valdi\" font={systemFont(12)} />\n    </layout>;\n  }\n}\n"
  },
  {
    "path": "apps/helloworld/src/valdi/hello_world/src/HelloWorldApp.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { Style } from 'valdi_core/src/Style';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { Label, ScrollView } from 'valdi_tsx/src/NativeTemplateElements';\n\nimport res from '../res';\nimport { onRootComponentCreated } from './CppModule';\nimport { APP_NAME } from './NativeModule';\n\n/**\n * @ViewModel\n * @ExportModel\n */\nexport interface ViewModel {}\n\n/**\n * @Context\n * @ExportModel\n */\nexport interface ComponentContext {}\n\n/**\n * @Component\n * @ExportModel\n */\nexport class App extends Component<ViewModel, ComponentContext> {\n  onCreate(): void {\n    onRootComponentCreated(this.renderer.contextId);\n    console.log('Hello World onCreate!');\n  }\n\n  onRender(): void {\n    console.log('Hello World onRender!!!');\n    <view backgroundColor=\"white\">\n      <scroll style={styles.scroll} padding={16}>\n        <layout marginTop={100} flexDirection=\"row\" width=\"100%\" minHeight={10}>\n          <image src={res.emoji} height=\"100%\" tint=\"gray\" marginRight={10} />\n          <label style={styles.title} value={`Welcome to ${APP_NAME}!`} font={systemFont(20)} />\n        </layout>\n      </scroll>\n    </view>;\n  }\n}\n\nconst styles = {\n  scroll: new Style<ScrollView>({\n    alignItems: 'center',\n    height: '100%',\n  }),\n\n  title: new Style<Label>({\n    color: 'black',\n    accessibilityCategory: 'header',\n    width: '100%',\n  }),\n};\n"
  },
  {
    "path": "apps/helloworld/src/valdi/hello_world/src/NativeModule.d.ts",
    "content": "/**\n * @ExportModule\n */\n\n// Returns the name of the app suffixed with the platform\n// Used to show case how a native module can be implemented and\n// used within TypeScript.\nexport const APP_NAME: string;\n"
  },
  {
    "path": "apps/helloworld/src/valdi/hello_world/src/index.ts",
    "content": "console.log('Hello World!');\n"
  },
  {
    "path": "apps/helloworld/src/valdi/hello_world/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\"\n}\n"
  },
  {
    "path": "apps/helloworld/src/valdi/tsconfig.json",
    "content": "{\n    \"extends\": \"./_configs/base.tsconfig.json\",\n}\n"
  },
  {
    "path": "apps/helloworld/standalone_app/BUILD.bazel",
    "content": "# HelloWorld Standalone App - Integration Test for valdi_exported_library\n\nload(\"@rules_android//rules:rules.bzl\", \"aar_import\", \"android_binary\")\nload(\"@rules_kotlin//kotlin:android.bzl\", \"kt_android_library\")\nload(\"//bzl:expand_template.bzl\", \"expand_template\")\n\naar_import(\n    name = \"hello_world_aar\",\n    aar = \"@valdi//apps/helloworld:hello_world_export_android\",\n)\n\nkt_android_library(\n    name = \"start_activity\",\n    srcs = glob([\"android/**/*.kt\"]),\n    custom_package = \"com.snap.helloworld\",\n    deps = [\n        \":hello_world_aar\",\n        \"@valdi//valdi:valdi_android_support\",\n    ],\n)\n\nexpand_template(\n    name = \"hello_world_manifest\",\n    src = \"@valdi//bzl/valdi/app_templates:AndroidDebugAppManifest.xml.tpl\",\n    output = \"AndroidAppManifest.xml\",\n    substitutions = {\n        \"@VALDI_APP_PACKAGE@\": \"com.snap.helloworld\",\n        \"@VALDI_APP_NAME@\": \"helloworld\",\n        \"@VALDI_APPLICATION_ATTRIBUTES@\": \"\",\n        \"@VALDI_ACTIVITY_ATTRIBUTES@\": \"\",\n    },\n)\n\nandroid_binary(\n    name = \"hello_world_standalone\",\n    custom_package = \"com.snap.helloworld\",\n    manifest = \":hello_world_manifest\",\n    multidex = \"native\",\n    tags = [\"valdi_android_application\"],\n    deps = [\n        \":hello_world_aar\",\n        \":start_activity\",\n        \"@android_mvn//:androidx_appcompat_appcompat\",\n    ],\n)\n\n# Instrumentation Tests (not run in CI yet)\n\nkt_android_library(\n    name = \"launch_test_lib\",\n    testonly = True,\n    srcs = glob([\"androidTest/**/*.kt\"]),\n    custom_package = \"com.snap.helloworld.test\",\n    deps = [\n        \":hello_world_aar\",\n        \":start_activity\",\n        \"@android_mvn//:androidx_test_ext_junit\",\n        \"@android_mvn//:androidx_test_runner\",\n        \"@android_mvn//:junit_junit\",\n    ],\n)\n\nandroid_binary(\n    name = \"hello_world_instrumentation_test_apk\",\n    testonly = True,\n    custom_package = \"com.snap.helloworld.test\",\n    instruments = \":hello_world_standalone\",\n    manifest = \"androidTest/AndroidManifest.xml\",\n    deps = [\n        \":launch_test_lib\",\n    ],\n)\n"
  },
  {
    "path": "apps/helloworld/standalone_app/README.md",
    "content": "# HelloWorld Standalone App\n\nApp to test valdi library export.\n\n"
  },
  {
    "path": "apps/helloworld/standalone_app/android/Main.kt",
    "content": "package com.snap.helloworld\n\nimport android.app.Activity\nimport android.os.Bundle\nimport com.snap.valdi.ValdiRuntimeManager\nimport com.snap.valdi.support.SupportValdiRuntimeManager\nimport com.snap.valdi.modules.hello_world.App\n\n/**\n * Standalone HelloWorld app that uses the exported AAR.\n * \n * For full integration documentation, see:\n * ../../../../docs/docs/workflow-external-build-system.md#gradle\n */\nclass StartActivity : Activity() {\n    var runtimeManager: ValdiRuntimeManager? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        // This needs to execute at least once\n        // The name of the library will match the name of\n        // your valdi_exported_library() target.\n        System.loadLibrary(\"hello_world_export\")\n\n        // For best performance, your app should maintain a singleton\n        // of the Valdi runtime manager.\n        val runtimeManager = SupportValdiRuntimeManager.createWithSupportLibs(this.applicationContext)\n        this.runtimeManager = runtimeManager\n\n        setContentView(App.create(runtimeManager.mainRuntime))\n    }\n}"
  },
  {
    "path": "apps/helloworld/standalone_app/androidTest/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.snap.helloworld.test\">\n\n    <uses-sdk android:minSdkVersion=\"24\"\n        android:targetSdkVersion=\"34\"/>\n\n    <instrumentation\n        android:name=\"androidx.test.runner.AndroidJUnitRunner\"\n        android:targetPackage=\"com.snap.helloworld\" />\n\n</manifest>\n\n"
  },
  {
    "path": "apps/helloworld/standalone_app/androidTest/LaunchTest.kt",
    "content": "package com.snap.helloworld.test\n\nimport androidx.test.ext.junit.rules.ActivityScenarioRule\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport androidx.test.platform.app.InstrumentationRegistry\nimport com.snap.helloworld.StartActivity\nimport org.junit.Assert.assertEquals\nimport org.junit.Assert.assertNotNull\nimport org.junit.Assert.assertTrue\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n/**\n * Instrumentation test to verify exported library integration.\n */\n@RunWith(AndroidJUnit4::class)\nclass LaunchTest {\n    \n    @get:Rule\n    val activityRule = ActivityScenarioRule(StartActivity::class.java)\n\n    @Test\n    fun testAppLaunchesSuccessfully() {\n        // Verify the app context is correct\n        val appContext = InstrumentationRegistry.getInstrumentation().targetContext\n        assertEquals(\"com.snap.helloworld\", appContext.packageName)\n        \n        // If we get here, the activity launched successfully and didn't crash\n        // The ActivityScenarioRule would have failed if the activity crashed on launch\n        activityRule.scenario.onActivity { activity ->\n            // Verify the activity is in a valid state\n            assert(!activity.isFinishing) { \"Activity should not be finishing\" }\n            assert(!activity.isDestroyed) { \"Activity should not be destroyed\" }\n        }\n    }\n    \n    @Test\n    fun testNativeLibraryLoaded() {\n        activityRule.scenario.onActivity { activity ->\n            // If we get here, it means System.loadLibrary(\"hello_world_export\") succeeded\n            // in StartActivity.onCreate() without throwing UnsatisfiedLinkError\n            \n            // Verify the activity is still alive (didn't crash from native library issues)\n            assert(!activity.isFinishing) { \"Activity should not be finishing after native lib load\" }\n            assert(!activity.isDestroyed) { \"Activity should not be destroyed after native lib load\" }\n            \n            // Verify runtime manager was created (requires native library to be loaded)\n            assertNotNull(\"RuntimeManager should exist after native library load\", activity.runtimeManager)\n        }\n    }\n    \n    @Test\n    fun testValdiRuntimeInitialized() {\n        activityRule.scenario.onActivity { activity ->\n            // Verify the Valdi runtime manager exists and is initialized\n            val runtimeManager = activity.runtimeManager\n            assertNotNull(\"ValdiRuntimeManager should be initialized\", runtimeManager)\n            \n            // If the main runtime is accessible, the Valdi runtime initialized successfully\n            // This requires both the native library and the Valdi core module to be loaded\n            val mainRuntime = runtimeManager?.mainRuntime\n            assertNotNull(\"Main Valdi runtime should be accessible\", mainRuntime)\n        }\n    }\n    \n}\n\n"
  },
  {
    "path": "apps/managed_context_example/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_application.bzl\", \"valdi_application\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"managed_context_example\",\n    srcs = glob([\n        \"**/*.ts\",\n        \"**/*.tsx\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/drawing\",\n        \"//src/valdi_modules/src/valdi/valdi_navigation\",\n    ],\n)\n\nvaldi_application(\n    name = \"managed_context_example_app\",\n    root_component_path = \"App@managed_context_example/ManagedContextExample\",\n    title = \"Valdi Managed Context Example\",\n    deps = [\":managed_context_example\"],\n)\n"
  },
  {
    "path": "apps/managed_context_example/ManagedContextExample.tsx",
    "content": "import { Component, StatefulComponent } from 'valdi_core/src/Component';\nimport { systemBoldFont, systemFont } from 'valdi_core/src/SystemFont';\nimport { AnyRenderFunction } from 'valdi_core/src/AnyRenderFunction';\nimport { createManagedContext, EmbeddedPlatformViewRasterMethod } from 'drawing/src/ManagedContextFactory';\nimport { BitmapAlphaType, BitmapColorType, ImageEncoding } from 'drawing/src/IBitmap';\nimport { createBitmap, createBitmapWithBuffer } from 'drawing/src/BitmapFactory';\nimport { Asset } from 'valdi_tsx/src/Asset';\nimport { makeAssetFromBytes } from 'valdi_core/src/Asset';\nimport { Device } from 'valdi_core/src/Device';\n\nconst COMPONENT_HEIGHT = 200;\n\nclass InnerComponent extends Component {\n  onRender(): void {\n    <view width={'100%'} height={'100%'} backgroundColor=\"black\" padding={60} touchEnabled={false} slowClipping>\n      <view\n        padding={8}\n        background=\"linear-gradient(90deg, lightgray, gray)\"\n        borderRadius={16}\n        alignSelf=\"center\"\n        rotation={Math.PI / -8}\n        borderWidth={1}\n        borderColor=\"red\"\n      >\n        <view marginLeft={8} marginRight={8} width={200} height={60} borderRadius={'50%'}>\n          <textfield\n            width={230}\n            height={60}\n            limitToViewport={false}\n            position=\"absolute\"\n            value={'Hello, World!'}\n            color=\"red\"\n            font={systemBoldFont(40)}\n            touchEnabled={false}\n          />\n        </view>\n      </view>\n    </view>;\n  }\n}\n\nfunction Section(viewModel: { name: string; children?: AnyRenderFunction | void }) {\n  <layout flexDirection=\"column\">\n    <layout padding={16}>\n      <label value={viewModel.name} font={systemBoldFont(17)} color=\"black\" />\n    </layout>\n    {viewModel.children?.()}\n  </layout>;\n}\n\nfunction Button(viewModel: { title: string; onTap: () => void }) {\n  <view\n    backgroundColor=\"cornflowerblue\"\n    padding={16}\n    borderRadius={16}\n    boxShadow={'1 1 3 rgba(0, 0, 0, 0.16)'}\n    onTap={viewModel.onTap}\n    marginBottom={8}\n  >\n    <label value={viewModel.title} font={systemBoldFont(14)} color=\"black\" />\n  </view>;\n}\n\nconst DOWNSCALE_RATIO = [1, 2, 4, 8];\n\ninterface State {\n  rasterMethod: EmbeddedPlatformViewRasterMethod;\n  rasterizedAsset?: Asset;\n  downscaleRatioIndex: number;\n}\n\nexport class App extends StatefulComponent<{}, State> {\n  state: State = {\n    rasterMethod: EmbeddedPlatformViewRasterMethod.FAST,\n    downscaleRatioIndex: 0,\n  };\n\n  onRender(): void {\n    <view width={'100%'} height={'100%'} paddingTop={Device.getDisplayTopInset()} backgroundColor=\"white\">\n      <Section name=\"Preview\">\n        {\n          <layout height={COMPONENT_HEIGHT}>\n            <InnerComponent />\n          </layout>\n        }\n      </Section>\n      <Section name=\"Rasterized\">\n        {<image src={this.state.rasterizedAsset} width={'100%'} height={COMPONENT_HEIGHT} />}\n      </Section>\n      <Section name=\"Controls\">\n        <layout flexDirection=\"column\" padding={8}>\n          <Button\n            title={`Raster method: ${\n              this.state.rasterMethod === EmbeddedPlatformViewRasterMethod.FAST ? 'Fast' : 'Accurate'\n            }`}\n            onTap={this.toggleRasterMethod}\n          />\n          <Button\n            title={`Downscale ratio: ${DOWNSCALE_RATIO[this.state.downscaleRatioIndex]}`}\n            onTap={this.toggleDownscaleRatio}\n          />\n          <Button title=\"Rasterize\" onTap={this.rasterize} />\n        </layout>\n      </Section>\n    </view>;\n  }\n\n  toggleDownscaleRatio = () => {\n    const nextDownscaleRatioIndex = (this.state.downscaleRatioIndex + 1) % DOWNSCALE_RATIO.length;\n    this.setState({\n      downscaleRatioIndex: nextDownscaleRatioIndex,\n    });\n  };\n\n  toggleRasterMethod = () => {\n    this.setState({\n      rasterMethod:\n        this.state.rasterMethod === EmbeddedPlatformViewRasterMethod.FAST\n          ? EmbeddedPlatformViewRasterMethod.ACCURATE\n          : EmbeddedPlatformViewRasterMethod.FAST,\n    });\n  };\n\n  rasterize = () => {\n    this.doRasterize()\n      .then(asset => {\n        console.log('Rasterized asset:', asset);\n        this.setState({ rasterizedAsset: asset });\n      })\n      .catch(error => {\n        console.error('Error rasterizing:', error);\n      });\n  };\n\n  private getComponentSize(): [number, number] {\n    const width = this.renderer.getComponentRootElements(this, true)[0].frame.width;\n    const height = COMPONENT_HEIGHT;\n    return [width, height];\n  }\n\n  private async doRasterize(): Promise<Asset> {\n    const [componentWidth, componentHeight] = this.getComponentSize();\n    const context = createManagedContext({\n      useNewExternalSurfaceRasterMethod: this.state.rasterMethod,\n      enableDeltaRasterization: true,\n    });\n    context.render(() => {\n      <InnerComponent />;\n    });\n\n    await context.onAllAssetsLoaded();\n\n    await context.layout(componentWidth, componentHeight, false);\n\n    const { frame } = await context.draw();\n\n    const scale = Device.getDisplayScale() / DOWNSCALE_RATIO[this.state.downscaleRatioIndex];\n    const rasterWidth = Math.floor(scale * componentWidth);\n    const rasterHeight = Math.floor(scale * componentHeight);\n\n    const bytesPerPixel = 4;\n\n    const bitmap = createBitmap({\n      width: rasterWidth,\n      height: rasterHeight,\n      colorType: BitmapColorType.RGBA8888,\n      alphaType: BitmapAlphaType.OPAQUE,\n      rowBytes: rasterWidth * bytesPerPixel,\n    });\n\n    frame.rasterInto(bitmap, true);\n\n    const buffer = bitmap.encode(ImageEncoding.PNG, 1.0);\n\n    frame.dispose();\n    bitmap.dispose();\n    context.dispose();\n\n    return makeAssetFromBytes(buffer);\n  }\n}\n\nconst styles = {};\n"
  },
  {
    "path": "apps/navigation_example/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_application.bzl\", \"valdi_application\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"navigation_example\",\n    srcs = glob([\n        \"**/*.ts\",\n        \"**/*.tsx\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_navigation\",\n    ],\n)\n\nvaldi_application(\n    name = \"navigation_example_app\",\n    root_component_path = \"App@navigation_example/NavigationExample\",\n    title = \"Valdi Navigation\",\n    deps = [\":navigation_example\"],\n)\n"
  },
  {
    "path": "apps/navigation_example/NavigationExample.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { NavigationPage } from 'valdi_navigation/src/NavigationPage';\nimport { systemBoldFont } from 'valdi_core/src/SystemFont';\nimport { ComponentConstructor, IComponent } from 'valdi_core/src/IComponent';\nimport { createReusableCallback } from 'valdi_core/src/utils/Callback';\nimport { NavigationRoot } from 'valdi_navigation/src/NavigationRoot';\nimport { NavigationPageComponent } from 'valdi_navigation/src/NavigationPageComponent';\nimport { $slot } from 'valdi_core/src/CompilerIntrinsics';\nimport { NavigationController } from 'valdi_navigation/src/NavigationController';\nimport { AnyRenderFunction } from 'valdi_core/src/AnyRenderFunction';\n\ninterface PageButtonViewModel {\n  title: string;\n  onTap: () => void;\n}\n\nclass PageButton extends Component<PageButtonViewModel> {\n  onRender(): void {\n    <view\n      backgroundColor=\"lightgray\"\n      padding={16}\n      alignSelf=\"stretch\"\n      margin={8}\n      marginLeft={24}\n      marginRight={24}\n      borderRadius={'50%'}\n      boxShadow={'0 0 3 rgba(0, 0, 0, 0.15)'}\n      alignItems=\"center\"\n      onTap={this.viewModel.onTap}\n    >\n      <label color=\"black\" value={this.viewModel.title} font={systemBoldFont(17)} />\n    </view>;\n  }\n}\n\nfunction PageBackground(viewModel: { children?: AnyRenderFunction | void }) {\n  <view backgroundColor=\"white\" width=\"100%\" height=\"100%\" alignItems=\"center\" justifyContent=\"center\">\n    {viewModel.children?.()}\n  </view>;\n}\n\n@NavigationPage(module)\nexport class Page1 extends NavigationPageComponent<{}> {\n  onRender(): void {\n    <PageBackground>\n      <PageButton\n        title={`Go To Page #2`}\n        onTap={createReusableCallback(() => {\n          this.navigationController.push(Page2, {}, {});\n        })}\n      />\n    </PageBackground>;\n  }\n}\n\n@NavigationPage(module)\nexport class Page2 extends NavigationPageComponent<{}> {\n  onRender(): void {\n    <PageBackground>\n      <PageButton\n        title={`Go To Page #3`}\n        onTap={createReusableCallback(() => {\n          this.navigationController.push(Page3, {}, {});\n        })}\n      />\n    </PageBackground>;\n  }\n}\n\n@NavigationPage(module)\nexport class Page3 extends NavigationPageComponent<{}> {\n  onRender(): void {\n    <PageBackground>{this.renderChildren()}</PageBackground>;\n  }\n\n  private renderChildren() {\n    <PageButton\n      title={`Present nested`}\n      onTap={createReusableCallback(() => {\n        this.navigationController.present(Page1, {}, {});\n      })}\n    />;\n    <PageButton\n      title={`Dismiss`}\n      onTap={createReusableCallback(() => {\n        this.navigationController.dismiss(true);\n      })}\n    />;\n  }\n}\n\nexport class App extends Component {\n  onRender(): void {\n    <NavigationRoot>\n      {$slot(navigationController => {\n        <view backgroundColor=\"white\" width=\"100%\" height=\"100%\" alignItems=\"center\" justifyContent=\"center\">\n          {this.renderButtons(navigationController)}\n        </view>;\n      })}\n    </NavigationRoot>;\n  }\n\n  private renderButtons(navigationController: NavigationController): void {\n    this.renderButton('Page #1', Page1, navigationController);\n    this.renderButton('Page #2', Page2, navigationController);\n    this.renderButton('Page #3', Page3, navigationController);\n  }\n\n  private presentPage(\n    title: string,\n    componentCtor: ComponentConstructor<IComponent>,\n    navigationController: NavigationController,\n  ): void {\n    navigationController.present(componentCtor, {}, {});\n  }\n\n  private renderButton(\n    name: string,\n    componentCtor: ComponentConstructor<IComponent>,\n    navigationController: NavigationController,\n  ): void {\n    <PageButton\n      title={`Present ${name}`}\n      onTap={createReusableCallback(() => {\n        this.presentPage(name, componentCtor, navigationController);\n      })}\n    />;\n  }\n}\n"
  },
  {
    "path": "apps/navigation_example/tsconfig.json",
    "content": "{\n  \"extends\": \"../../modules/_configs/base.tsconfig.json\",\n  \"compilerOptions\": {\n    \"types\": [\"../../modules/types/Long\", \"../../modules/types/globals\"],\n    \"paths\": {\n      \"navigation_example/*\": [\"./*\"],\n      \"valdi_tsx/*\": [\"../../src/valdi_modules/src/valdi/valdi_tsx/*\"],\n      \"valdi_navigation/*\": [\n        \"../../src/valdi_modules/src/valdi/valdi_navigation/*\"\n      ],\n      \"valdi_core/*\": [\n        \"../../src/valdi_modules/src/valdi/valdi_core/*\"\n      ],\n      \"valdi_core\": [\n        \"../../src/valdi_modules/src/valdi/valdi_core/src/tslib.d.ts\"\n      ],\n    }\n  }\n}\n"
  },
  {
    "path": "apps/valdi_gpt/.eslintrc.js",
    "content": "\nmodule.exports = {\n  root: true,\n  parser: '@typescript-eslint/parser',\n  parserOptions: {\n    tsconfigRootDir: __dirname,\n    project: ['./src/valdi/_configs/eslint.tsconfig.json'],\n  },\n  plugins: ['@typescript-eslint', 'unused-imports', 'rxjs', 'prettier', '@snap/eslint-plugin-valdi'],\n  extends: [\n    'eslint:recommended',\n    'plugin:@typescript-eslint/recommended',\n    'plugin:import/recommended',\n    'plugin:import/typescript',\n    'prettier',\n  ],\n  rules: { \n    '@snap/valdi/attributed-text-no-array-assignment': 'error',\n    '@snap/valdi/jsx-no-lambda': 'error',\n    '@snap/valdi/assign-timer-id': 'error',\n    '@snap/valdi/only-const-enum': 'off',\n    '@snap/valdi/no-implicit-index-import': 'error',\n    '@snap/valdi/mutate-state-without-set-state': 'error',\n    '@snap/valdi/no-import-from-test-outside-test-dir': 'error',\n    '@snap/valdi/no-declare-test-without-describe': 'error', \n  },\n};\n"
  },
  {
    "path": "apps/valdi_gpt/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_application.bzl\", \"valdi_application\")\nload(\"//bzl/valdi:valdi_exported_library.bzl\", \"valdi_exported_library\")\n\nvaldi_application(\n    name = \"valdi_gpt\",\n    root_component_path = \"ValdiGptApp@valdi_gpt/src/ValdiGptApp\",\n    title = \"ValdiGPT\",\n    deps = [\"//apps/valdi_gpt/src/valdi/valdi_gpt\"],\n)\n\nvaldi_exported_library(\n    name = \"valdi_gpt_export\",\n    ios_bundle_id = \"com.snap.valdi_gpt.lib\",\n    ios_bundle_name = \"ValdiGPT\",\n    web_package_name = \"valdi_gpt_npm\",\n    deps = [\"//apps/valdi_gpt/src/valdi/valdi_gpt\"],\n)\n"
  },
  {
    "path": "apps/valdi_gpt/package.json",
    "content": "{\n  \"name\": \"hello_world\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Valdi Helloworld app\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@snap/eslint-plugin-valdi\": \"1.0.1\",\n    \"@types/eslint\": \"^9.6.1\",\n    \"@types/jasmine\": \"^5.1.7\",\n    \"@typescript-eslint/eslint-plugin\": \"^6.21.0\",\n    \"@typescript-eslint/parser\": \"^6.21.0\",\n    \"@typescript-eslint/utils\": \"^6.21.0\",\n    \"eslint\": \"^8.27.0\",\n    \"eslint-config-prettier\": \"^8.5.0\",\n    \"eslint-plugin-import\": \"^2.26.0\",\n    \"eslint-plugin-prettier\": \"^4.2.1\",\n    \"eslint-plugin-rxjs\": \"^5.0.2\",\n    \"eslint-plugin-unused-imports\": \"^3.2.0\",\n    \"jasmine\": \"^5.6.0\",\n    \"ts-node\": \"^10.9.2\",\n    \"typescript\": \"5.3.3\"\n  }\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/.terserrc.json",
    "content": "{\n  \"ecma\": \"ES2016\",\n  \"safari10\": true,\n  \"mangle\": {\n    \"toplevel\": true,\n    \"keep_classnames\": true\n  },\n  \"compress\": {\n    \"keep_classnames\": true\n  },\n  \"sourceMap\": {\n    \"content\": \"inline\",\n    \"url\": \"inline\"\n  }\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/_configs/base.tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"target\": \"ES2016\",\n    \"module\": \"commonjs\",\n    \"baseUrl\": \"../../../../\",\n    \"paths\": {\n      \"tslib\": [\n        \"./valdi_core/src/tslib.d.ts\",\n        \"../src/valdi_modules/src/valdi/valdi_core/src/tslib.d.ts\"\n      ],\n      \"jasmine\": [\n        \"./jasmine/src/jasmine.d.ts\",\n        \"../src/valdi_modules/src/valdi/jasmine/src/jasmine.d.ts\"\n      ],\n      \"*\": [\n        \"*\",\n        \"../src/valdi_modules/src/valdi/*\",\n        \"../../.valdi_build/hotreload/generated_ts/*\",\n        \"../../.valdi_build/compile/generated_ts/*\",\n        \"valdi_gpt/src/valdi/*\"\n      ]\n    },\n    \"lib\": [\"dom\", \"ES2019\"],\n    \"noImplicitReturns\": true,\n    \"noImplicitAny\": true,\n    \"importHelpers\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"jsx\": \"preserve\",\n    \"rootDirs\": [\n      \"..\",\n      \"../../../.valdi_build/hotreload/generated_ts\",\n      \"../../../.valdi_build/compile/generated_ts\"\n    ],\n    \"types\": [\"../types/Long\", \"../types/globals\"],\n    \"typeRoots\": [\".\"]\n  }\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/_configs/eslint.tsconfig.json",
    "content": "{\n  \"extends\": \"./base.tsconfig.json\",\n  \"include\": [\"../**/*.ts\", \"../**/*.tsx\"]\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/ai_service/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"ai_service\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCAiService\",\n    ios_output_target = \"release\",\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_http\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/ai_service/src/AiService.ts",
    "content": "export enum GptRole {\n  USER = 'user',\n  ASSISTANT = 'assistant',\n  SYSTEM = 'system',\n}\n\nexport interface GptMessage {\n  role: GptRole;\n  content: string;\n}\n\nexport interface AiService {\n  addSystemPrompt(message: string): void;\n  getResponse(messages: GptMessage[]): Promise<string>;\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/ai_service/src/OpenAi.ts",
    "content": "import { HTTPClient } from 'valdi_http/src/HTTPClient';\nimport { AiService, GptMessage, GptRole } from './AiService';\n\nconst OPENAI_MODEL = 'gpt-4o-mini';\nconst OPENAI_API_KEY = 'YOUR_API_KEY_HERE';\n\n/**\n * Provides barebones access to OpenAI, using direct HTTP requests.\n * A much better implementation would use the OpenAI SDK:\n *    https://github.com/openai/openai-node\n * but Valdi currently isn't compatible with Node modules.\n *\n * API reference: https://platform.openai.com/docs/api-reference/making-requests\n */\nexport class OpenAi implements AiService {\n  private systemMessage: GptMessage[] = [];\n  private client = new HTTPClient('https://api.openai.com/v1');\n\n  public addSystemPrompt(message: string): void {\n    this.systemMessage.push({\n      role: GptRole.SYSTEM,\n      content: message,\n    });\n  }\n\n  public async getResponse(messages: GptMessage[]): Promise<string> {\n    const requestBody = JSON.stringify({\n      model: OPENAI_MODEL,\n      messages: this.systemMessage.concat(messages),\n    });\n\n    console.log('Request:', requestBody);\n\n    const encodedRequestBody = new TextEncoder().encode(requestBody);\n\n    try {\n      const response = await this.client.post('/chat/completions', encodedRequestBody, {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${OPENAI_API_KEY}`,\n      });\n      const body = response.body;\n      if (body) {\n        const text = new TextDecoder().decode(body);\n        const results = JSON.parse(text);\n        if (results.choices) {\n          return results.choices[0].message.content;\n        } else {\n          return `Error: ${text}\\n\\nRequest:\\n\\n ${requestBody}`;\n        }\n      } else {\n        return '????';\n      }\n    } catch (err: any) {\n      return err.toString();\n    }\n  }\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/ai_service/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\"\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/conversation/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"conversation\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCConversation\",\n    ios_output_target = \"release\",\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//apps/valdi_gpt/src/valdi/ai_service\",\n        \"//src/valdi_modules/src/valdi/foundation\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_test\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/conversation/src/Conversation.tsx",
    "content": "import { StatefulComponent } from 'valdi_core/src/Component';\nimport { OpenAi } from 'ai_service/src/OpenAi';\nimport { Message, MesssageViewModel } from './Message';\nimport { InputBar } from './InputBar';\nimport { AiService, GptRole } from '../../ai_service/src/AiService';\n\nexport interface ConversationViewModel {}\n\nexport interface ConversationContext {}\n\ninterface ConversationState {\n  results: MesssageViewModel[];\n  awaitingResponse: boolean;\n}\n\nexport class Conversation extends StatefulComponent<ConversationViewModel, ConversationState, ConversationContext> {\n  aiService: AiService = new OpenAi();\n\n  onCreate(): void {\n    this.aiService.addSystemPrompt('You are a text message companion. Reply concisely.');\n    this.setState({\n      results: [],\n      awaitingResponse: false,\n    });\n  }\n\n  onRender(): void {\n    <layout width=\"100%\" height=\"100%\" flexDirection=\"column-reverse\" padding={16}>\n      <InputBar onSubmit={this.onSubmit} />\n      <scroll>\n        <view flexDirection=\"column-reverse\" paddingTop={20}>\n          {[...this.state!.results].reverse().forEach(message => (\n            <Message text={message.text} outbound={message.outbound} />\n          ))}\n        </view>\n      </scroll>\n    </layout>;\n  }\n\n  onSubmit: (text: string) => void = async (text: string) => {\n    const messages = this.state!.results.concat([{ text: text, outbound: true }]);\n    this.setState({\n      results: messages,\n      awaitingResponse: true,\n    });\n\n    const gptMessages = messages.map(message => ({\n      role: message.outbound ? GptRole.USER : GptRole.ASSISTANT,\n      content: message.text,\n    }));\n\n    let results: MesssageViewModel[];\n    try {\n      const response = await this.aiService.getResponse(gptMessages);\n      results = messages.concat([{ text: response, outbound: false }]);\n    } catch (e) {\n      results = messages.concat([{ text: `Error, ${e}`, outbound: false }]);\n    }\n\n    this.setState({\n      results: results,\n      awaitingResponse: false,\n    });\n  };\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/conversation/src/InputBar.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { ElementRef } from 'valdi_core/src/ElementRef';\nimport { Style } from 'valdi_core/src/Style';\nimport { TextField } from 'valdi_tsx/src/NativeTemplateElements';\n\nexport interface InputBarViewModel {\n  onSubmit?: (text: string) => void;\n}\n\nexport class InputBar extends Component<InputBarViewModel> {\n  textInput = new ElementRef<TextField>();\n\n  onRender(): void {\n    <textfield\n      ref={this.textInput}\n      width=\"80%\"\n      placeholder=\"Ask anything...\"\n      style={styles.textfield}\n      onEditEnd={this.onSubmit}\n    />;\n  }\n\n  onSubmit: () => void = async () => {\n    const ref = this.textInput.single()!;\n    const text = ref.getAttribute('value')?.toString() ?? '';\n    if (text.length === 0) {\n      return;\n    }\n\n    ref.setAttribute('value', '');\n    this.viewModel.onSubmit?.call(undefined, text);\n  };\n}\n\nconst styles = {\n  textfield: new Style<TextField>({\n    font: 'AvenirNext-Demibold 20',\n  }),\n};\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/conversation/src/Message.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { Style } from 'valdi_core/src/Style';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { Label } from 'valdi_tsx/src/NativeTemplateElements';\n\nexport interface MesssageViewModel {\n  text: string;\n  outbound: boolean;\n}\n\nexport class Message extends Component<MesssageViewModel> {\n  onRender(): void {\n    const direction = this.viewModel.outbound ? 'row-reverse' : 'row';\n    <layout width=\"100%\" flexDirection={direction}>\n      <view backgroundColor={this.viewModel.outbound ? '#e3e3e3' : 'white'} borderRadius={6} padding={8} width=\"80%\">\n        <label\n          numberOfLines={0}\n          style={this.viewModel.outbound ? styles.outbound : styles.inbound}\n          value={this.viewModel.text}\n          textAlign=\"left\"\n        />\n      </view>\n    </layout>;\n  }\n}\n\nconst styles = {\n  outbound: new Style<Label>({\n    color: 'black',\n    textAlign: 'right',\n    backgroundColor: '#e3e3e3',\n    borderRadius: 6,\n    font: systemFont(18),\n  }),\n\n  inbound: new Style<Label>({\n    color: 'black',\n    backgroundColor: 'white',\n    textAlign: 'left',\n    borderRadius: undefined,\n    font: systemFont(18),\n  }),\n};\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/conversation/src/index.ts",
    "content": "console.log('Hello World!');\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/conversation/test/Conversation.spec.tsx",
    "content": "import 'jasmine/src/jasmine';\nimport { IComponentTestDriver, withValdiRenderer } from 'valdi_test/test/JSXTestUtils';\nimport { AiService, GptMessage } from '../../ai_service/src/AiService';\nimport { Conversation, ConversationContext } from '../src/Conversation';\nimport { Message } from '../src/Message';\nimport { componentTypeFind } from 'foundation/test/util/componentTypeFind';\nimport { DeferredPromise } from 'foundation/src/DeferredPromise';\n\nclass TestAiService implements AiService {\n  nextResponse: Promise<string> = Promise.resolve('response');\n\n  addSystemPrompt(message: string): void {}\n\n  getResponse(messages: GptMessage[]): Promise<string> {\n    return this.nextResponse;\n  }\n}\n\ndescribe('Conversation', () => {\n  const aiService = new TestAiService();\n  const layoutParams = { width: 600, height: 1800 };\n\n  describe('render', () => {\n    it(\n      'sanity check',\n      withValdiRenderer(async driver => {\n        const component = renderRoot(driver);\n\n        await driver.performLayout(layoutParams);\n        expect(component instanceof Conversation).toEqual(true);\n      }),\n    );\n\n    it(\n      'response is appended',\n      withValdiRenderer(async driver => {\n        const component = renderRoot(driver);\n        component.aiService = aiService;\n\n        await driver.performLayout(layoutParams);\n        // verify simple layout\n        expect(component instanceof Conversation).toEqual(true);\n\n        // Verify no messages\n        let messages = componentTypeFind(component, Message);\n        expect(messages.length).toEqual(0);\n\n        // Send a message but defer response\n        const nextResponse = new DeferredPromise<string>();\n        aiService.nextResponse = nextResponse.promise;\n        component.onSubmit('knock knock.');\n\n        // Verify one message appended\n        await driver.performLayout(layoutParams);\n        messages = componentTypeFind(component, Message);\n        expect(messages.length).toEqual(1);\n        const outboundViewModel = messages[0].viewModel;\n        expect(outboundViewModel.outbound).toEqual(true);\n        expect(outboundViewModel.text).toEqual('knock knock.');\n\n        // Release response\n        nextResponse.resolve(\"who's there?\");\n        await driver.performLayout(layoutParams);\n        messages = componentTypeFind(component, Message);\n\n        // Verify response appended\n        expect(messages.length).toEqual(2);\n        expect(messages[0].viewModel.outbound).toEqual(false);\n        expect(messages[0].viewModel.text).toEqual(\"who's there?\");\n\n        // Also make sure our outbound message is the same\n        expect(messages[1].viewModel).toEqual(outboundViewModel);\n      }),\n    );\n  });\n});\n\n/**\n * Helper function to render the root component and ensure its a\n * Conversation\n *\n * @param driver driver to render\n * @param context Uses a default mock context\n */\nfunction renderRoot(driver: IComponentTestDriver, context = mockContext()): Conversation {\n  const nodes = driver.render(() => {\n    <Conversation context={context} />;\n  });\n  if (nodes[0]?.component instanceof Conversation) {\n    return nodes[0].component;\n  }\n  throw new Error('could not render Conversation');\n}\n\n/**\n * Helper function to return a mock context object for ContentDiscoverComponent\n * @returns {ConversationContext}\n */\nfunction mockContext(): ConversationContext {\n  return {};\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/conversation/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\"\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/tsconfig.json",
    "content": "{\n    \"extends\": \"./_configs/base.tsconfig.json\",\n}\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/valdi_gpt/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"valdi_gpt\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiGPT\",\n    ios_output_target = \"release\",\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//apps/valdi_gpt/src/valdi/conversation\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n        # Needed for web support\n        # TODO: Fix this so it's only needed in the exported lib\n        \"//src/valdi_modules/src/valdi/web_renderer\",\n    ],\n)\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/valdi_gpt/src/ValdiGptApp.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { Conversation } from 'conversation/src/Conversation';\nimport { Style } from 'valdi_core/src/Style';\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\n/**\n * @ViewModel\n * @ExportModel({ ios: 'ValdiStartViewComponentViewModel', android: 'com.snap.valdi.helloworld.StartViewComponentViewModel'})\n */\nexport interface ValdiGptAppViewModel {}\n\n/**\n * @Context\n * @ExportModel({ios: 'ValdiStartViewComponentContext', android: 'com.snap.valdi.helloworld.StartViewComponentContext'})\n */\nexport interface ValdiGptAppContext {}\n\n/**\n * @Component\n * @ExportModel({ios: 'ValdiStartView', android: 'com.snap.valdi.helloworld.StartView'})\n */\nexport class ValdiGptApp extends Component<ValdiGptAppViewModel, ValdiGptAppContext> {\n  onRender(): void {\n    <view style={styles.page}>\n      <Conversation />\n    </view>;\n  }\n}\n\nconst styles = {\n  page: new Style<View>({\n    backgroundColor: 'white',\n    width: '100%',\n    height: '100%',\n  }),\n};\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/valdi_gpt/src/types/Long.d.ts",
    "content": "/* eslint-disable */\n// Type definitions for long.js 4.0.0\n// Project: https://github.com/dcodeIO/long.js\n// Definitions by: Peter Kooijmans <https://github.com/peterkooijmans>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// Definitions by: Denis Cappellin <https://github.com/cappellin>\n\ndeclare global {\n  class Long {\n    /**\n     * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as signed integers. See the from* functions below for more convenient ways of constructing Longs.\n     */\n    constructor(low: number, high?: number, unsigned?: boolean);\n\n    /**\n     * Maximum unsigned value.\n     */\n    static MAX_UNSIGNED_VALUE: Long;\n\n    /**\n     * Maximum signed value.\n     */\n    static MAX_VALUE: Long;\n\n    /**\n     * Minimum signed value.\n     */\n    static MIN_VALUE: Long;\n\n    /**\n     * Signed negative one.\n     */\n    static NEG_ONE: Long;\n\n    /**\n     * Signed one.\n     */\n    static ONE: Long;\n\n    /**\n     * Unsigned one.\n     */\n    static UONE: Long;\n\n    /**\n     * Unsigned zero.\n     */\n    static UZERO: Long;\n\n    /**\n     * Signed zero\n     */\n    static ZERO: Long;\n\n    /**\n     * The high 32 bits as a signed value.\n     */\n    high: number;\n\n    /**\n     * The low 32 bits as a signed value.\n     */\n    low: number;\n\n    /**\n     * Whether unsigned or not.\n     */\n    unsigned: boolean;\n\n    /**\n     * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is assumed to use 32 bits.\n     */\n    static fromBits(lowBits: number, highBits: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representing the given 32 bit integer value.\n     */\n    static fromInt(value: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.\n     */\n    static fromNumber(value: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representation of the given string, written using the specified radix.\n     */\n    static fromString(str: string, unsigned?: boolean | number, radix?: number): Long;\n\n    /**\n     * Creates a Long from its byte representation.\n     */\n    static fromBytes(bytes: number[], unsigned?: boolean, le?: boolean): Long;\n\n    /**\n     * Creates a Long from its little endian byte representation.\n     */\n    static fromBytesLE(bytes: number[], unsigned?: boolean): Long;\n\n    /**\n     * Creates a Long from its little endian byte representation.\n     */\n    static fromBytesBE(bytes: number[], unsigned?: boolean): Long;\n\n    /**\n     * Tests if the specified object is a Long.\n     */\n    static isLong(obj: any): boolean;\n\n    /**\n     * Converts the specified value to a Long.\n     */\n    static fromValue(val: Long | number | string | { low: number; high: number; unsigned: boolean }): Long;\n\n    /**\n     * Returns the sum of this and the specified Long.\n     */\n    add(addend: number | Long | string): Long;\n\n    /**\n     * Returns the bitwise AND of this Long and the specified.\n     */\n    and(other: Long | number | string): Long;\n\n    /**\n     * Compares this Long's value with the specified's.\n     */\n    compare(other: Long | number | string): number;\n\n    /**\n     * Compares this Long's value with the specified's.\n     */\n    comp(other: Long | number | string): number;\n\n    /**\n     * Returns this Long divided by the specified.\n     */\n    divide(divisor: Long | number | string): Long;\n\n    /**\n     * Returns this Long divided by the specified.\n     */\n    div(divisor: Long | number | string): Long;\n\n    /**\n     * Tests if this Long's value equals the specified's.\n     */\n    equals(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value equals the specified's.\n     */\n    eq(other: Long | number | string): boolean;\n\n    /**\n     * Gets the high 32 bits as a signed integer.\n     */\n    getHighBits(): number;\n\n    /**\n     * Gets the high 32 bits as an unsigned integer.\n     */\n    getHighBitsUnsigned(): number;\n\n    /**\n     * Gets the low 32 bits as a signed integer.\n     */\n    getLowBits(): number;\n\n    /**\n     * Gets the low 32 bits as an unsigned integer.\n     */\n    getLowBitsUnsigned(): number;\n\n    /**\n     * Gets the number of bits needed to represent the absolute value of this Long.\n     */\n    getNumBitsAbs(): number;\n\n    /**\n     * Tests if this Long's value is greater than the specified's.\n     */\n    greaterThan(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than the specified's.\n     */\n    gt(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than or equal the specified's.\n     */\n    greaterThanOrEqual(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than or equal the specified's.\n     */\n    gte(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is even.\n     */\n    isEven(): boolean;\n\n    /**\n     * Tests if this Long's value is negative.\n     */\n    isNegative(): boolean;\n\n    /**\n     * Tests if this Long's value is odd.\n     */\n    isOdd(): boolean;\n\n    /**\n     * Tests if this Long's value is positive.\n     */\n    isPositive(): boolean;\n\n    /**\n     * Tests if this Long's value equals zero.\n     */\n    isZero(): boolean;\n\n    /**\n     * Tests if this Long's value is less than the specified's.\n     */\n    lessThan(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than the specified's.\n     */\n    lt(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than or equal the specified's.\n     */\n    lessThanOrEqual(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than or equal the specified's.\n     */\n    lte(other: Long | number | string): boolean;\n\n    /**\n     * Returns this Long modulo the specified.\n     */\n    modulo(other: Long | number | string): Long;\n\n    /**\n     * Returns this Long modulo the specified.\n     */\n    mod(other: Long | number | string): Long;\n\n    /**\n     * Returns the product of this and the specified Long.\n     */\n    multiply(multiplier: Long | number | string): Long;\n\n    /**\n     * Returns the product of this and the specified Long.\n     */\n    mul(multiplier: Long | number | string): Long;\n\n    /**\n     * Negates this Long's value.\n     */\n    negate(): Long;\n\n    /**\n     * Negates this Long's value.\n     */\n    neg(): Long;\n\n    /**\n     * Returns the bitwise NOT of this Long.\n     */\n    not(): Long;\n\n    /**\n     * Tests if this Long's value differs from the specified's.\n     */\n    notEquals(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value differs from the specified's.\n     */\n    neq(other: Long | number | string): boolean;\n\n    /**\n     * Returns the bitwise OR of this Long and the specified.\n     */\n    or(other: Long | number | string): Long;\n\n    /**\n     * Returns this Long with bits shifted to the left by the given amount.\n     */\n    shiftLeft(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits shifted to the left by the given amount.\n     */\n    shl(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits arithmetically shifted to the right by the given amount.\n     */\n    shiftRight(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits arithmetically shifted to the right by the given amount.\n     */\n    shr(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits logically shifted to the right by the given amount.\n     */\n    shiftRightUnsigned(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits logically shifted to the right by the given amount.\n     */\n    shru(numBits: number | Long): Long;\n\n    /**\n     * Returns the difference of this and the specified Long.\n     */\n    subtract(subtrahend: number | Long | string): Long;\n\n    /**\n     * Returns the difference of this and the specified Long.\n     */\n    sub(subtrahend: number | Long | string): Long;\n\n    /**\n     * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.\n     */\n    toInt(): number;\n\n    /**\n     * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).\n     */\n    toNumber(): number;\n\n    /**\n     * Converts this Long to its byte representation.\n     */\n\n    toBytes(le?: boolean): number[];\n\n    /**\n     * Converts this Long to its little endian byte representation.\n     */\n\n    toBytesLE(): number[];\n\n    /**\n     * Converts this Long to its big endian byte representation.\n     */\n\n    toBytesBE(): number[];\n\n    /**\n     * Converts this Long to signed.\n     */\n    toSigned(): Long;\n\n    /**\n     * Converts the Long to a string written in the specified radix.\n     */\n    toString(radix?: number): string;\n\n    /**\n     * Converts this Long to unsigned.\n     */\n    toUnsigned(): Long;\n\n    /**\n     * Returns the bitwise XOR of this Long and the given one.\n     */\n    xor(other: Long | number | string): Long;\n  }\n}\n\nexport {};\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/valdi_gpt/src/types/globals.d.ts",
    "content": "// This is a global declarations file that's referenced by valdi_core/src/Valdi.ts\n\ndeclare const module: { path: string; exports: unknown };\n"
  },
  {
    "path": "apps/valdi_gpt/src/valdi/valdi_gpt/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\"\n}\n"
  },
  {
    "path": "apps/valdi_gpt/web_demo/README.md",
    "content": "# Valdi GPT web demo\n\nThis demo app is for the ongoing development of Valdi Web.\n\n## Build the web dependencies\n\n```\nbazel build //apps/valdi_gpt:valdi_gpt_npm\n```\n\n```\ncd bazel-bin/apps/valdi_gpt/valdi_gpt_npm \nnpm link\n```\n\n```\ncd apps/valdi_gpt/web_demo\nnpm install\nnpm link valdi_gpt_npm\n```\n\n`link` has to be run after install because it modifies the `node_modules` folder\n\n## Run the dev app\n\nFrom the `web_demo` directory.\n\n```\nnpm run serve\n```\n\nOpen up `http://localhost:3030/` in a web browser.\n\nThe app should hotreload.\n"
  },
  {
    "path": "apps/valdi_gpt/web_demo/package.json",
    "content": "{\n  \"name\": \"react-webpack\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"serve\": \"webpack serve --mode development\",\n    \"build\": \"webpack --mode production\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"react\": \"^17.0.2\",\n    \"react-dom\": \"^17.0.2\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.27.4\",\n    \"@babel/preset-env\": \"^7.27.2\",\n    \"@babel/preset-react\": \"^7.27.1\",\n    \"babel-loader\": \"^8.4.1\",\n    \"css-loader\": \"^6.2.0\",\n    \"html-webpack-plugin\": \"^5.3.2\",\n    \"path-browserify\": \"^1.0.1\",\n    \"sass\": \"^1.38.1\",\n    \"sass-loader\": \"^12.1.0\",\n    \"style-loader\": \"^3.2.1\",\n    \"url-loader\": \"^4.1.1\",\n    \"webpack\": \"^5.51.1\",\n    \"webpack-cli\": \"^4.8.0\",\n    \"webpack-dev-server\": \"^4.15.1\"\n  }\n}\n"
  },
  {
    "path": "apps/valdi_gpt/web_demo/src/App.js",
    "content": "import React from \"react\";\n\n// Must be the first Valdi import, does a bunch of setup\nimport { ValdiWebRenderer } from 'valdi_gpt_npm/src/web_renderer/src/ValdiWebRenderer';\n\n// Register native modules so they'll be available to the runtime\nrequire('./RegisterNativeModules');\n\nimport { ValdiGptApp } from 'valdi_gpt_npm/src/valdi_gpt/src/ValdiGptApp';\n\n\nclass ValdiGPTDemo extends React.Component {\n  constructor(props) {\n    super(props);\n    this.elementRef = React.createRef();\n  }\n\n  componentDidMount() {\n    if (this.elementRef.current) {\n      console.log('DIV mounted:', this.elementRef.current);\n      const webRenderer = new ValdiWebRenderer(this.elementRef.current);\n      webRenderer.renderRootComponent(\n        ValdiGptApp,\n        {},\n        {},\n        {},\n      );\n    }\n  }\n\n  render() {\n    return (\n      <div>\n        <h2>A placeholder React component for development</h2>\n        <div ref={this.elementRef}></div>\n      </div>\n    );\n  }\n}\n\nconst App = () => {\n  return <ValdiGPTDemo />;\n};\n\nexport default App;"
  },
  {
    "path": "apps/valdi_gpt/web_demo/src/App.scss",
    "content": "h1 {\n  color: red;\n}"
  },
  {
    "path": "apps/valdi_gpt/web_demo/src/RegisterNativeModules.js",
    "content": "/**\n * ALL NATIVE MODULES MUST BE REGISTERED\n * \n * Native module files get output to valdi_core/src/ModuleName\n * But can be referenced in multiple ways:\n *      require('ModuleName') => registerModule('ModuleName')\n *      import { Thing } from './ModuleName' => registerModule('path/to/parent/ModuleName')\n */\n\nvar valdiTsx = require('valdi_gpt_npm/native/valdi_tsx/web/JSX')\nglobal.moduleLoader.registerModule('valdi_tsx/src/JSX', () => {\n  return valdiTsx;\n});\n\n"
  },
  {
    "path": "apps/valdi_gpt/web_demo/src/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Valdi_gpt web demo - React with Webpack</title>\n  </head>\n  <body>\n    <div id=\"app\"></div>\n\n    <!-- Notice we are pointing to `bundle.js` file -->\n    <script src=\"bundle.js\"></script>\n  </body>\n</html>"
  },
  {
    "path": "apps/valdi_gpt/web_demo/src/index.js",
    "content": "import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport App from \"./App\";\nimport \"./App.scss\";\n\nconst el = document.getElementById(\"app\");\n\nReactDOM.render(<App />, el);"
  },
  {
    "path": "apps/valdi_gpt/web_demo/webpack.config.js",
    "content": "const path = require('path');\nconst HtmlWebpackPlugin = require(\"html-webpack-plugin\");\nconst webpack = require('webpack');\n\nmodule.exports = {\n  entry: './src/index.js',\n  output: {\n    filename: 'bundle.js',\n    path: path.resolve(__dirname, 'dist'),\n    clean: true,\n  },\n  mode: 'development',\n  devtool: 'source-map',\n  ignoreWarnings: [{ message: /Cannot statically analyse 'require/ }],\n  plugins: [\n    new HtmlWebpackPlugin({ template: \"src/index.html\" }),\n    new webpack.IgnorePlugin({\n      resourceRegExp: /foundation[\\\\\\/]test[\\\\\\/]util[\\\\\\/]lib[\\\\\\/]faker\\.js$/\n    }),\n  ],\n  devServer: { port: 3030, hot: true },\n  resolve: {\n    extensions: ['.js', '.jsx', '.ts', '.tsx'],\n    modules: [path.resolve(__dirname, 'node_modules')],\n  },\n  module: {\n    rules: [\n      { test: /\\.(sa|sc|c)ss$/, use: [\"style-loader\", \"css-loader\", \"sass-loader\"] },\n      {\n        test: /\\.jsx?$/,\n        exclude: /node_modules/,\n        use: { \n          loader: 'babel-loader',\n          options: {\n            presets: [\n              ['@babel/preset-env', { targets: { esmodules: true } }],\n              ['@babel/preset-react', { runtime: 'automatic' }],\n            ],\n          },\n        },\n      },\n      // BEGIN REQUIRED FOR VALDI WEB\n      // (url-loader is deprecated in webpack 5; asset modules work too, but keeping as-is if you need)\n      { test: /\\.(png|woff|woff2|eot|ttf|svg)$/, loader: \"url-loader\", options: { limit: false } },\n      { test: /\\.protodecl$/, type: 'asset/resource' },\n      {\n        test: /\\.tsx?$/,\n        loader: 'ts-loader',\n        exclude: /node_modules/,\n        options: { appendTsxSuffixTo: [/\\.vue$/], transpileOnly: true },\n      },\n      // END REQUIRED FOR VALDI WEB\n    ],\n  },\n};"
  },
  {
    "path": "bin/BUILD.bazel",
    "content": "load(\"@aspect_rules_js//js:defs.bzl\", \"js_binary\")\nload(\"@bazel_skylib//rules:native_binary.bzl\", \"native_binary\")\nload(\n    \"@valdi//bzl:prebuilt_tools.bzl\",\n    \"bundle_js\",\n    \"pngquant_linux\",\n    \"pngquant_macos\",\n    \"valdi_compiler_companion_files\",\n)\n\nfilegroup(\n    name = \"sqldelight_compiler\",\n    srcs = [],\n    visibility = [\"//visibility:public\"],\n)\n\nnative_binary(\n    name = \"valdi_compiler\",\n    src = select(\n        {\n            \"@bazel_tools//src/conditions:darwin\": \"@valdi_compiler_macos//:valdi_compiler\",\n            \"@bazel_tools//src/conditions:linux_x86_64\": \"@valdi_compiler_linux//:valdi_compiler\",\n        },\n    ),\n    out = \"valdi_compiler\",\n    visibility = [\"//visibility:public\"],\n)\n\nalias(\n    name = \"valdi_compiler_toolbox\",\n    actual = \"@valdi//valdi/compiler/toolbox:valdi_compiler_toolbox\",\n    visibility = [\"//visibility:public\"],\n)\n\nnative_binary(\n    name = \"pngquant\",\n    src = select(\n        {\n            \"@bazel_tools//src/conditions:darwin\": pngquant_macos(),\n            \"@bazel_tools//src/conditions:linux_x86_64\": pngquant_linux(),\n        },\n    ),\n    out = \"pngquant\",\n    visibility = [\"//visibility:public\"],\n)\n\nalias(\n    name = \"valdi_standalone\",\n    actual = \"@valdi//valdi:valdi_standalone\",\n    visibility = [\"//visibility:public\"],\n)\n\njs_binary(\n    name = \"valdi_compiler_companion\",\n    copy_data_to_bin = False,\n    data = valdi_compiler_companion_files(),\n    entry_point = bundle_js(),\n    env = {\n        \"NODE_ENV\": \"production\",\n    },\n    node_options = [\n        # \"--inspect-brk\", # allows you to debug the companion using chrome://inspect in Chrome\n        \"--max-old-space-size=4096\",\n        \"--enable-source-maps\",\n    ],\n    visibility = [\"//visibility:public\"],\n    # log_level = \"debug\", # increase verbosity of logs if you need to debug anything\n)\n"
  },
  {
    "path": "bin/MODULE.bazel",
    "content": "module(name = \"valdi_toolchain\")\n\nbazel_dep(name = \"valdi\", version = \"0.1\")\n\nbazel_dep(name = \"bazel_skylib\", version = \"1.2.0\")\nbazel_dep(name = \"aspect_rules_js\", version = \"1.37.0\")\n\n# In bzlmod mode, WORKSPACE.bzlmod replaces WORKSPACE, so the compiler repos\n# that workspace_prepare.bzl would normally create are never set up.\n# This extension creates them and makes them visible to this module.\nvaldi_tools = use_extension(\"@valdi//bzl:valdi_compiler_repos_extension.bzl\", \"valdi_compiler_repos\")\nuse_repo(valdi_tools, \"valdi_compiler_macos\", \"valdi_compiler_linux\", \"valdi_pngquant_macos\", \"valdi_pngquant_linux\", \"jscore_libs\")"
  },
  {
    "path": "bin/WORKSPACE",
    "content": ""
  },
  {
    "path": "bin/compiler/linux/valdi_compiler",
    "content": "version https://git-lfs.github.com/spec/v1\noid sha256:e1966217b779807d46df30f6371f08d0e003f602a33bd3a964a566ee17fface1\nsize 64378976\n"
  },
  {
    "path": "bin/compiler/macos/valdi_compiler",
    "content": "version https://git-lfs.github.com/spec/v1\noid sha256:2c5a7738cec8f204d214fc05e5fa5b9b660b8527773bf58c5e93871433bcb839\nsize 48507424\n"
  },
  {
    "path": "bin/pngquant/linux/pngquant",
    "content": "version https://git-lfs.github.com/spec/v1\noid sha256:a3dc681320002d23137aaddcd5ba9f76f225f0c574bfa3e51fa2ddf0b02d4508\nsize 1156248\n"
  },
  {
    "path": "bin/pngquant/macos/pngquant",
    "content": "version https://git-lfs.github.com/spec/v1\noid sha256:1072cf0f9fcdda478fc10c81acce30394e41016ca2dc281ffb95d4b89266f9ef\nsize 2219414\n"
  },
  {
    "path": "bzl/BUILD.bazel",
    "content": ""
  },
  {
    "path": "bzl/additional_dependencies.bzl",
    "content": "load(\"//bzl:nested_repository.bzl\", \"nested_repository\")\n\n# Additional Node.js download mirrors for internal Snap builds\n# This gets prepended to the standard mirrors in nodejs_info.bzl\nADDITIONAL_NODE_URLS = []\n\nSOURCES_FILEGROUP_BUILD_FILE_CONTENT = \"\"\"\nexports_files(glob([\"**\"]))\nfilegroup(\n    name = \"all_files\",\n    srcs = glob([\"**/*\"]),\n    visibility = [\"//visibility:public\"],\n)\n\"\"\"\n\ndef setup_additional_dependencies(bzlmod = False):\n    # Create repositories that point to local files stored in git LFS within the @valdi repository.\n    # These binaries are stored locally in the bin/ directory structure.\n    #\n    # In bzlmod-based internal repo: @valdi is an external repository, so we use nested_repository\n    # to point to subdirectories within it.\n    #\n    # In WORKSPACE-based mirrored repo: \"valdi\" is the main workspace itself, so we use\n    # native.new_local_repository to point to local directories within the workspace.\n    #\n    # bzlmod: pass True when calling from a bzlmod module extension to skip the\n    # native.existing_rule() check, which is only available in WORKSPACE context.\n\n    if bzlmod:\n        is_main_workspace = False\n    else:\n        # Detect if we're in the main workspace or if @valdi is external.\n        # In WORKSPACE files, native.existing_rule(\"valdi\") exists when valdi is external.\n        is_main_workspace = (native.existing_rule(\"valdi\") == None)\n    \n    if is_main_workspace:\n        # WORKSPACE-based repo: use new_local_repository to reference local directories\n        native.new_local_repository(\n            name = \"valdi_compiler_linux\",\n            path = \"bin/compiler/linux\",\n            build_file_content = SOURCES_FILEGROUP_BUILD_FILE_CONTENT,\n        )\n        \n        native.new_local_repository(\n            name = \"valdi_compiler_macos\",\n            path = \"bin/compiler/macos\",\n            build_file_content = SOURCES_FILEGROUP_BUILD_FILE_CONTENT,\n        )\n        \n        native.new_local_repository(\n            name = \"valdi_pngquant_macos\",\n            path = \"bin/pngquant/macos\",\n            build_file_content = SOURCES_FILEGROUP_BUILD_FILE_CONTENT,\n        )\n        \n        native.new_local_repository(\n            name = \"valdi_pngquant_linux\",\n            path = \"bin/pngquant/linux\",\n            build_file_content = SOURCES_FILEGROUP_BUILD_FILE_CONTENT,\n        )\n        \n        native.new_local_repository(\n            name = \"valdi_compiler_companion\",\n            path = \"bin/compiler_companion\",\n            build_file_content = SOURCES_FILEGROUP_BUILD_FILE_CONTENT,\n        )\n        \n        native.new_local_repository(\n            name = \"clientsql\",\n            path = \"bin/clientsql\",\n            build_file_content = SOURCES_FILEGROUP_BUILD_FILE_CONTENT,\n        )\n        \n        native.new_local_repository(\n            name = \"jscore_libs\",\n            path = \"third-party/jscore/libs\",\n            build_file_content = SOURCES_FILEGROUP_BUILD_FILE_CONTENT,\n        )\n    else:\n        # Bzlmod-based internal repo: use nested_repository\n        nested_repository(\n            name = \"valdi_compiler_linux\",\n            source_repo = \"valdi\",\n            target_dir = \"bin/compiler/linux\",\n        )\n\n        nested_repository(\n            name = \"valdi_compiler_macos\",\n            source_repo = \"valdi\",\n            target_dir = \"bin/compiler/macos\",\n        )\n\n        nested_repository(\n            name = \"valdi_pngquant_macos\",\n            source_repo = \"valdi\",\n            target_dir = \"bin/pngquant/macos\",\n        )\n\n        nested_repository(\n            name = \"valdi_pngquant_linux\",\n            source_repo = \"valdi\",\n            target_dir = \"bin/pngquant/linux\",\n        )\n\n        nested_repository(\n            name = \"valdi_compiler_companion\",\n            source_repo = \"valdi\",\n            target_dir = \"bin/compiler_companion\",\n        )\n\n        nested_repository(\n            name = \"clientsql\",\n            source_repo = \"valdi\",\n            target_dir = \"bin/clientsql\",\n        )\n\n        nested_repository(\n            name = \"jscore_libs\",\n            source_repo = \"valdi\",\n            target_dir = \"third-party/jscore/libs\",\n        )\n\n    # Note: valdi_standalone and valdi_compiler_toolbox are built from source,\n    # so they don't need separate repositories - they're referenced via @valdi// targets\n"
  },
  {
    "path": "bzl/android/BUILD.bazel",
    "content": "sh_binary(\n    name = \"zip_relative\",\n    srcs = [\"zip_relative.sh\"],\n    visibility = [\"//visibility:public\"],\n)\n\n# For use in package_aar to generate a stub_jar for JavaInfo.\ngenrule(\n    name = \"empty_jar\",\n    outs = [\"empty.jar\"],\n    cmd = \"echo UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA== | base64 -d > $@\",\n)\n"
  },
  {
    "path": "bzl/android/collect_android_assets.bzl",
    "content": "load(\"//bzl/valdi:valdi_compiled.bzl\", \"ValdiModuleInfo\")\n\ndef _collect_valdimodules_from_valdi_deps(valdi_deps, output_target):\n    \"\"\"Extract valdimodules and sourcemaps transitively from Valdi modules.\n\n    Args:\n        valdi_deps: List of Valdi module targets with ValdiModuleInfo\n        output_target: \"debug\" or \"release\" - which outputs to extract\n    \"\"\"\n\n    # Collect all modules (current + transitive via ValdiModuleInfo.deps)\n    all_modules = []\n    for module in valdi_deps:\n        if ValdiModuleInfo not in module:\n            continue\n\n        module_info = module[ValdiModuleInfo]\n\n        # Add transitive dependencies\n        if hasattr(module_info, \"deps\") and module_info.deps:\n            all_modules.extend(module_info.deps.to_list())\n\n        # Include current module\n        all_modules.append(module)\n\n    # Determine which fields to extract based on output_target\n    valdimodule_field = \"android_{}_valdimodule\".format(output_target)\n    sourcemaps_field = \"android_{}_sourcemaps\".format(output_target)\n\n    # Extract assets from each module\n    assets = []\n    for module in all_modules:\n        if ValdiModuleInfo in module:\n            module_info = module[ValdiModuleInfo]\n\n            # Add valdimodule\n            valdimodule = getattr(module_info, valdimodule_field, None)\n            if valdimodule:\n                assets.append(valdimodule)\n\n            # Add sourcemaps (only for debug builds)\n            if output_target == \"debug\":\n                sourcemaps = getattr(module_info, sourcemaps_field, None)\n                if sourcemaps:\n                    assets.append(sourcemaps)\n\n    return assets\n\ndef _collect_assets_impl(ctx):\n    # Collect valdimodules from valdi compiled modules (includes transitive deps)\n    all_assets = _collect_valdimodules_from_valdi_deps(ctx.attr.valdi_deps, ctx.attr.output_target)\n\n    # Ensure we have at least one asset (AAR requires assets directory)\n    if not all_assets:\n        empty = ctx.actions.declare_file(\"empty\")\n        ctx.actions.write(empty, \"\")\n        all_assets.append(empty)\n\n    # Package assets into a zip file\n    out_zip = ctx.actions.declare_file(\"{}_assets.zip\".format(ctx.label.name))\n    scratch = ctx.actions.declare_directory(\"{}_assets_dir\".format(ctx.label.name))\n\n    script = ctx.actions.declare_file(\"{}_pack_assets.sh\".format(ctx.label.name))\n    ctx.actions.write(\n        script,\n        is_executable = True,\n        content = \"\"\"\nset -euo pipefail\nITEMS=( {items} )\nDEST='{dst}'\n\nfor src in \"${{ITEMS[@]}}\"; do\n    if [[ -d \"$src\" ]]; then\n        # Copy directory contents, preferring assets/ subdirectory if it exists\n        [[ -d \"$src\"/assets ]] && src=\"$src\"/assets\n        cp -R \"$src\"/. \"$DEST\"/\n    else\n        # Copy individual file\n        cp \"$src\" \"$DEST\"/\n    fi\n    chmod -R u+w \"$DEST\"\ndone\n\n# Create zip from staging directory\nABS_DEST=\"$PWD/{zip}\"\ncd \"$DEST\" && zip -qqr \"$ABS_DEST\" .\n\"\"\".format(\n            items = \" \".join(['\"{}\"'.format(f.path) for f in all_assets]),\n            dst = scratch.path,\n            zip = out_zip.path,\n        ),\n    )\n\n    ctx.actions.run_shell(\n        inputs = depset(all_assets),\n        tools = [script],\n        outputs = [out_zip, scratch],\n        command = script.path,\n        progress_message = \"Packaging Android assets for %{label}\",\n    )\n\n    return [DefaultInfo(files = depset([out_zip]))]\n\ncollect_android_assets = rule(\n    implementation = _collect_assets_impl,\n    attrs = {\n        \"valdi_deps\": attr.label_list(\n            providers = [ValdiModuleInfo],\n            mandatory = True,\n            doc = \"Valdi compiled module targets (extracts valdimodules transitively via ValdiModuleInfo)\",\n        ),\n        \"output_target\": attr.string(\n            mandatory = True,\n            doc = \"Output target to extract (debug or release), determined by build configuration\",\n        ),\n        \"deps\": attr.label_list(\n            allow_rules = [\"android_library\", \"aar_import\", \"kt_android_library\"],\n            allow_files = False,\n            default = [],\n            doc = \"Android library dependencies (unused, kept for compatibility)\",\n        ),\n    },\n    outputs = {\"assets_zip\": \"%{name}_assets.zip\"},\n    doc = \"\"\"Collects .valdimodule and .map.json files from Valdi modules for Android AARs.\n    \nExtracts valdimodules and sourcemaps from each Valdi module and its transitive\ndependencies via ValdiModuleInfo.deps. The output_target (debug/release) is \nautomatically determined based on the build configuration.\n\"\"\",\n)\n"
  },
  {
    "path": "bzl/android/filter_jar.bzl",
    "content": "# filter_jar.bzl\ndef _filter_jar_impl(ctx):\n    in_jar = ctx.file.jar\n    out_jar = ctx.actions.declare_file(ctx.label.name + \".jar\")\n    pattern_f = ctx.actions.declare_file(ctx.label.name + \"_patterns.txt\")\n    scratch = ctx.actions.declare_directory(\"{}_tempdir\".format(ctx.label.name))\n\n    # 1. Write the user-supplied regex list to a file (one per line)\n    ctx.actions.write(\n        output = pattern_f,\n        content = \"\\n\".join(ctx.attr.excluded_class_path_patterns),\n        is_executable = False,\n    )\n\n    # 2. Shell action that:\n    #    a) unzips the JAR to a temp dir\n    #    b) deletes every .class whose path matches any regex\n    #    c) re-zips the remainder into the output JAR\n    #       (zip -q ensures deterministic order)\n    ctx.actions.run_shell(\n        inputs = [in_jar, pattern_f],\n        outputs = [out_jar, scratch],\n        command = \"\"\"\nset -euo pipefail\ntmp=\"$4\"\n\n# Expand the input jar\nunzip -qq \"$1\" -d \"$tmp\"\n\nchmod -R u+rwX \"$tmp\"\n\n# Build a single alternation pattern:  (rx1)|(rx2)|...\npat=$(paste -sd'|' \"$2\")\n\n# Remove .class files whose INTERNAL path matches the regex\n# (grep works on \"/\" paths; users can write com/android/.* or com\\\\.android\\\\..*)\nfind \"$tmp\" -type f | grep -E \"$pat\" | xargs -r rm -f\nfind \"$tmp\" -depth -type d -empty -exec rmdir -- \"{}\" +\n\n# Re-create the jar\nabs_dest=\"$PWD/$3\"\necho $abs_dest\n(cd \"$tmp\" && zip -qqr \"$abs_dest\" .)\n\"\"\",\n        arguments = [\n            in_jar.path,  # $1\n            pattern_f.path,  # $2\n            out_jar.path,  # $3\n            scratch.path,  # $4\n        ],\n        mnemonic = \"FilterJar\",\n        progress_message = \"Filtering JAR %s\" % (in_jar.basename),\n    )\n\n    return [DefaultInfo(files = depset([out_jar]))]\n\nfilter_jar = rule(\n    implementation = _filter_jar_impl,\n    attrs = {\n        \"jar\": attr.label(\n            allow_single_file = [\".jar\"],\n            doc = \"Input JAR to be filtered\",\n            mandatory = True,\n        ),\n        \"excluded_class_path_patterns\": attr.string_list(\n            doc = \"Regexes (applied to internal /.class paths) to exclude\",\n            mandatory = True,\n        ),\n    },\n    doc = \"Produces a JAR with classes **not** matching any excluded_class_path_patterns.\",\n)\n"
  },
  {
    "path": "bzl/android/package_aar.bzl",
    "content": "# The design of the android_library aar target is not the same as buck's.\n# It doesn't create a monolithic package but instead create a single aar\n# designed to be packaged with it's dependencies externally...i.e. we'd have\n# to deploy packages for every single dependency to maven. Instead we\n# package this aar monolithically using this custom rule. It takes a base AAR,\n# we use valdi one since it's the only one with actual resources, and inject\n# the native libraries and replace the class jar with a monolithic one.\n# Probably a good idea to write a better rule for this in the future.\n\nload(\"//bzl/android:platform_transition.bzl\", \"platform_transition\")\n\n# From developer.android.com/studio/projects/android-library#aar-contents.\nAAR_KNOWN_FILES = [\n    \"classes.jar\",\n    \"R.txt\",\n    \"public.txt\",\n    \"proguard.txt\",\n    \"lint.jar\",\n    \"api.jar\",\n]\n\nAAR_KNOWN_DIRS = [\n    \"res\",\n    \"assets\",\n    \"libs\",\n    \"prefab\",\n]\n\ndef _impl(ctx):\n    dso_inputs = []\n    cp_dsos_commands = []\n\n    aar_dir = ctx.actions.declare_directory(\"{}_aar_dir\".format(ctx.label.name))\n\n    for arch, targets in ctx.split_attr.native_libs.items():\n        for target in targets:\n            dsos = target.default_runfiles.files.to_list()\n            dso_inputs.extend(dsos)\n\n            compilation_mode = getattr(ctx.fragments.cpp, \"compilation_mode\", \"fastbuild\")\n            strip_cmd = \"{strip} {input_file} -o {target_folder}/{basename}\"\n            native_lib_placement_cmd = strip_cmd\n            if ctx.attr._strip_native_libs == \"never\" or compilation_mode == \"dbg\":\n                native_lib_placement_cmd = \"cp {input_file} {target_folder}/{basename}\"\n\n            copy_workflow = [\n                \"mkdir -p {target_folder}\",\n                native_lib_placement_cmd,\n            ]\n\n            if (ctx.attr.compress_dsos):\n                copy_workflow.append(\n                    \"{compressor} {compression_args} \" +\n                    \"-o {target_folder}/{compressed_basename} --rm \" +\n                    \"{target_folder}/{basename}\",\n                )\n\n            for f in dsos:\n                target_folder = \"{aar_dir}/jni/{arch}\".format(\n                    aar_dir = aar_dir.path,\n                    arch = arch,\n                )\n\n                # This is temporary (so.zst would make much more sense, but\n                # is used in phase 0 implementation).\n                compressed_basename = f.basename.replace(\".so\", \".zst.so\")\n\n                cp_dsos_commands.append(\" && \".join(copy_workflow).format(\n                    target_folder = target_folder,\n                    input_file = f.path,\n                    basename = f.basename,\n                    compressed_basename = compressed_basename,\n                    strip = ctx.file._stripper.path,\n                    compressor = ctx.executable._compressor.path,\n                    compression_args = \" \".join(ctx.attr.compression_args),\n                ))\n\n    inputs = [ctx.file.aar, ctx.file.classes_jar] + dso_inputs\n\n    if ctx.file.proguard_spec:\n        proguard_spec_command = \"cp {proguard_spec} {output_dir}/proguard.txt\".format(\n            output_dir = aar_dir.path,\n            proguard_spec = ctx.file.proguard_spec.path,\n        )\n        inputs.append(ctx.file.proguard_spec)\n    else:\n        proguard_spec_command = \"echo 'no proguard spec specified'\"\n\n    # copy any additional files provided into the rule\n    extra_cp_commands = []\n    extra_mkdir_commands = []\n    mkdirs = {}\n    for additional_file, additional_file_output_path in ctx.attr.additional_files.items():\n        additional_files = additional_file.files.to_list()\n        if len(additional_files) > 1:\n            fail(\"package_aar: additional_files item with output path {} has more than 1 item: {}\"\n                .format(additional_file_output_path, additional_file))\n\n        if _is_known_aar_file(additional_file_output_path):\n            fail(\"package_aar: additional_files item with output path {} is a known aar file: {}\"\n                .format(additional_file_output_path, additional_file))\n\n        first_file = additional_files[0]\n        inputs.append(first_file)\n\n        if \"/\" in additional_file_output_path:\n            mkdirs[additional_file_output_path.rsplit(\"/\", 1)[0]] = True\n\n        extra_cp_commands.append(\"cp {additional_file} {output_dir}/{output_path}\".format(\n            additional_file = first_file.path,\n            output_dir = aar_dir.path,\n            output_path = additional_file_output_path,\n        ))\n\n    mkdirs[\"libs\"] = True\n    for additional_jar in ctx.attr.additional_jars:\n        additional_jars = additional_jar.files.to_list()\n\n        first_file = additional_jars[0]\n        inputs.append(first_file)\n\n        extra_cp_commands.append(\"cp {additional_jar} {output_dir}/libs/\".format(\n            additional_jar = first_file.path,\n            output_dir = aar_dir.path,\n        ))\n\n    mkdirs[\"assets\"] = True\n    for additional_asset in ctx.attr.additional_assets:\n        additional_assets = additional_asset.files.to_list()\n\n        for file in additional_assets:\n            inputs.append(file)\n            extra_cp_commands.append(\"unzip -qq {additional_asset} -d {output_dir}/assets/\".format(\n                additional_asset = file.path,\n                output_dir = aar_dir.path,\n            ))\n\n    for d in mkdirs:\n        extra_mkdir_commands.append(\"mkdir -p {output_dir}/{additional_file_dir}\".format(\n            output_dir = aar_dir.path,\n            additional_file_dir = d,\n        ))\n\n    ctx.actions.run_shell(\n        outputs = [aar_dir],\n        inputs = inputs,\n        tools = [ctx.executable._zipper, ctx.file._stripper, ctx.executable._compressor] + ctx.files._stripper_libs,\n        command = \"\"\"\nset -euo pipefail\n{zipper} x {input_aar} -d {output_dir}\ncp {deploy_jar} {output_dir}/classes.jar\n{proguard_spec_command}\n{extra_mkdir_commands}\n{extra_cp_commands}\n{cp_commands}\n\"\"\".format(\n            zipper = ctx.executable._zipper.path,\n            input_aar = ctx.file.aar.path,\n            output_dir = aar_dir.path,\n            deploy_jar = ctx.file.classes_jar.path,\n            proguard_spec_command = proguard_spec_command,\n            extra_mkdir_commands = \"\\n\".join(extra_mkdir_commands),\n            extra_cp_commands = \"\\n\".join(extra_cp_commands),\n            cp_commands = \"\\n\".join(cp_dsos_commands),\n        ),\n    )\n\n    output_aar_file = ctx.actions.declare_file(\"{name}.aar\".format(name = ctx.attr.name))\n    args = ctx.actions.args()\n    args.add(ctx.executable._zipper.path)\n    args.add(aar_dir.path)\n    args.add(output_aar_file.path)\n    args.add_all([aar_dir])\n\n    ctx.actions.run(\n        outputs = [output_aar_file],\n        inputs = [aar_dir],\n        executable = ctx.executable._zip_relative,\n        tools = [ctx.executable._zipper],\n        arguments = [args],\n    )\n\n    # Use an empty jar to satisfy the JavaInfo provider. We could use the\n    # classes.jar from the original aar, but that would be a behavior change\n    # since the rule currently does not propagate it and doing would mean\n    # potentially invalidating caches when the classes.jar is changed.\n    return [\n        DefaultInfo(files = depset([output_aar_file])),\n        JavaInfo(ctx.file._empty_jar, ctx.file._empty_jar),\n    ]\n\ndef _is_known_aar_file(path):\n    # disallow any file listed in developer.android.com/studio/projects/android-library#aar-contents.\n    # Pushing files under those directories can create conflicts with preexisting files or other tools.\n    if path in AAR_KNOWN_FILES:\n        return True\n\n    base_dir = path.split(\"/\")[0]\n    return base_dir in AAR_KNOWN_DIRS\n\n# IMPORTANT NOTE: If you are renaming this, make sure to update the constant from the CLI\n# in cli/src/core/constants.ts .\n_package_aar_internal = rule(\n    implementation = _impl,\n    attrs = {\n        \"aar\": attr.label(allow_single_file = True, mandatory = True),\n        \"platforms\": attr.label_list(mandatory = True),\n        \"classes_jar\": attr.label(allow_single_file = True, mandatory = True),\n        \"native_libs\": attr.label_list(\n            cfg = platform_transition,\n            providers = [],\n        ),\n\n        # This is an internal private attr overriden by the the rule macro.\n        # It is a hack in order to make the native libraries visible to the ijwb aspect\n        # which is not aware of the `native_libs` attr so it does not propagate through it.\n        \"deps\": attr.label_list(\n            cfg = platform_transition,\n            providers = [],\n            mandatory = False,\n        ),\n        \"proguard_spec\": attr.label(\n            default = None,\n            mandatory = False,\n            allow_single_file = True,\n        ),\n        \"compress_dsos\": attr.bool(\n            default = False,\n            doc = \"Whether or not DSO files should be compressed in the generated AAR.\",\n            mandatory = False,\n        ),\n        \"compression_args\": attr.string_list(\n            default = [\"-f\", \"--ultra\", \"-22\"],\n            doc = \"Settings for compression tool.\",\n            mandatory = False,\n            allow_empty = True,\n        ),\n        \"_strip_native_libs\": attr.string(\n            default = \"always\",\n            doc = \"Whether or not native libraries should be stripped of debug symbols in the generated AAR.\",\n            mandatory = False,\n        ),\n        \"additional_files\": attr.label_keyed_string_dict(\n            mandatory = False,\n            default = {},\n            allow_files = True,\n            doc = (\n                \"Additional files to package in the aar. \" +\n                \"Note that any file listed in developer.android.com/studio/projects/android-library#aar-contents \" +\n                \"is explicitly disallowd to avoid conflicts with other tools.\"\n            ),\n        ),\n        \"additional_jars\": attr.label_list(),\n        \"additional_assets\": attr.label_list(),\n        \"_zip_relative\": attr.label(\n            default = \"//bzl/android:zip_relative\",\n            executable = True,\n            cfg = \"exec\",\n        ),\n        \"_zipper\": attr.label(\n            default = \"@bazel_tools//tools/zip:zipper\",\n            allow_single_file = True,\n            executable = True,\n            cfg = \"exec\",\n        ),\n        # This is bad form, and regrettably fragile; it means that we have to touch\n        # this anytime we want to update the toolchain.  More elegant solutions might be:\n        # 1) We could depend directly on the \"<target>.stripped\" output.  If we\n        #    pursue that path, remember also to set --stripopts; the default strip\n        #    settings are not right for us.\n        # 2) We could perhaps get strip from the toolchain indirectly, so that\n        #    we would always have the right stripper for the active toolchain.  One\n        #    example is https://github.com/bazelbuild/rules_cc/blob/master/examples/my_c_archive/my_c_archive.bzl,\n        #    except that it doesn't handle the transition - we want the android stripper,\n        #    not the host's.\n        \"_stripper\": attr.label(\n            default = \"@snap_client_toolchains//:llvm_ndk_28_0_13004108_strip\",\n            allow_single_file = True,\n        ),\n        \"_stripper_libs\": attr.label(\n            default = \"@snap_client_toolchains//:llvm_ndk_28_0_13004108_strip_libs\",\n            allow_files = True,\n        ),\n        \"_allowlist_function_transition\": attr.label(\n            default = \"@bazel_tools//tools/allowlists/function_transition_allowlist\",\n        ),\n        \"_compressor\": attr.label(\n            default = \"//tools/zstd:zstd\",\n            executable = True,\n            cfg = \"exec\",\n        ),\n        \"_empty_jar\": attr.label(\n            default = \"//bzl/android:empty_jar\",\n            allow_single_file = True,\n        ),\n    },\n    fragments = [\"cpp\"],\n)\n\ndef package_aar(**kwargs):\n    if \"deps\" in kwargs:\n        fail(\"The deps attribute in package_aar should not be used directly.\")\n    patched_kwargs = dict(**kwargs)\n    patched_kwargs[\"$strip_native_libs\"] = select({\n        \"@valdi//bzl/conditions:strip_always\": \"always\",\n        \"@valdi//bzl/conditions:strip_never\": \"never\",\n        \"@valdi//bzl/conditions:strip_sometimes\": \"sometimes\",\n        \"//conditions:default\": \"always\",\n    })\n    patched_kwargs[\"deps\"] = kwargs.get(\"native_libs\", [])\n    _package_aar_internal(\n        **patched_kwargs\n    )\n"
  },
  {
    "path": "bzl/android/platform_transition.bzl",
    "content": "def android_aar_platforms():\n    return select({\n        \"@snap_platforms//conditions:client_repo_arm64\": [\"@snap_platforms//os:android_arm64\"],\n        \"//conditions:default\": [],\n    }) + select({\n        \"@snap_platforms//conditions:client_repo_x86_64\": [\"@snap_platforms//os:android_x86_64\"],\n        \"//conditions:default\": [],\n    }) + select({\n        \"@snap_platforms//conditions:client_repo_arm32\": [\"@snap_platforms//os:android_arm32\"],\n        \"//conditions:default\": [],\n    })\n\ndef _impl(settings, attr):\n    _ignore = settings\n\n    result = {}\n\n    cpus = {\n        Label(\"@snap_platforms//os:android_arm32\"): \"armeabi-v7a\",\n        Label(\"@snap_platforms//os:android_arm64\"): \"arm64-v8a\",\n        Label(\"@snap_platforms//os:android_x86_64\"): \"x86_64\",\n    }\n\n    for platform in attr.platforms:\n        result[cpus[platform]] = {\n            \"//command_line_option:platforms\": [platform],\n        }\n\n    return result\n\n# Transition for the native libs into desired arches\nplatform_transition = transition(\n    implementation = _impl,\n    inputs = [],\n    outputs = [\n        \"//command_line_option:platforms\",\n    ],\n)\n"
  },
  {
    "path": "bzl/android/zip_relative.sh",
    "content": "#!/bin/bash\nset -eu\n\n# First argument is a path to the bazel zipper\nzipper=$1\n\n# Second argument is the prefix we want to strip from each file\nrelative_dir=$2\n\n# Third argument is the output zip file\noutput_file=$3\n\nshift 3\n\nargs=()\nfor path in $@; do\n    args+=( \"${path#\"$relative_dir/\"}=$path\" )\ndone\n\n${zipper} cC \"$output_file\" \"${args[@]}\"\n"
  },
  {
    "path": "bzl/asset_package.bzl",
    "content": "# asset_package can be used to bundle arbitary assets as Valdi modules.\n# Package's `data` will be packaged as `clien/res` files in the Valdi archive. Applies to unlinked (archived) Valdi builds only.\n# It's meant to be used as a dep module of client_objc_library, cc_library, or any other module type supported by package_ios.bzl.\n#\n# asset_package(\n#     name = \"module_assets\",\n#     data = [...],\n# )\n#\n# client_objc_library(\n#   ...,\n#   deps = [\":module_assets\"]\n# )\n\nAssetPackage = provider(fields = [\"data\", \"deps\"])\n\ndef _asset_package_impl(ctx):\n    compilation_context = cc_common.create_compilation_context()\n    cc_info = CcInfo(compilation_context = compilation_context)\n\n    return [\n        AssetPackage(data = depset(ctx.files.data), deps = depset()),\n        cc_info,\n    ]\n\nasset_package = rule(\n    implementation = _asset_package_impl,\n    attrs = {\n        \"data\": attr.label_list(allow_files = True),\n    },\n)\n"
  },
  {
    "path": "bzl/client_objc_library.bzl",
    "content": "load(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_interop_hint\")\nload(\"@rules_hdrs//hmap:hmap.bzl\", \"headermap\")\nload(\"@rules_hdrs//umbrella_header:umbrella_header.bzl\", \"umbrella_header\")\nload(\"@snap_macros//:library/snap_client_ios_library.bzl\", \"snap_client_ios_library\")\n\nOBJC_ONLY_FLAGS = [\n    \"-fdiagnostics-color\",\n    \"-fno-aligned-allocation\",\n]\n\nOBJCPP_ONLY_FLAGS = [\n    \"-ObjC++\",\n    \"-std=c++20\",\n    \"-fno-c++-static-destructors\",\n]\n\nOBJC_FLAGS = OBJC_ONLY_FLAGS + OBJCPP_ONLY_FLAGS\n\ndef client_objc_library(\n        *,\n        name,\n        deps = [],\n        implementation_deps = [],\n        generated_objects = [],\n        srcs = [],\n        hdrs = [],\n        copts = [],\n        includes = [],\n        data = [],\n        sdk_frameworks = [],\n        enable_swift_interop = False,\n        module_name = None,\n        alwayslink = False,\n        tags = [],\n        visibility = [],\n        enable_objcpp = True,\n        defines = [],\n        generate_hmaps = True,\n        generate_umbrella_header = True):\n    base_copts = OBJC_FLAGS if enable_objcpp else OBJC_ONLY_FLAGS\n\n    hmap_deps = []\n    private_hmap_deps = []\n    hmap_copts = []\n    if hdrs:\n        module_name = module_name or name\n        if generate_hmaps:\n            # setup headermaps\n            hmap_name = name + \"_hmap\"\n            headermap(\n                name = hmap_name,\n                cc_hdrs = hdrs,\n                cc_includes = includes,\n                tags = [\"manual\"],\n            )\n            hmap_deps.append(native.package_relative_label(hmap_name))\n\n        if generate_umbrella_header:\n            internal_umbrella_header_name = name + \"_umbrella.h\"\n            umbrella_header(\n                name = internal_umbrella_header_name,\n                hdrs = hdrs,\n                umbrella_header_name = module_name + \"-Swift\",\n                tags = [\"manual\"],\n            )\n            umbrella_headers = [\":\" + internal_umbrella_header_name]\n        else:\n            umbrella_headers = []\n\n        # The umbrella header is a public header\n        hdrs += umbrella_headers\n\n    if srcs and generate_hmaps:\n        private_hmap_name = name + \"_private_hmap\"\n        headermap(\n            name = private_hmap_name,\n            cc_hdrs = srcs,  # srcs include private headers (filtering by extension is done on headermap rule level)\n            cc_includes = includes,\n            add_to_includes = False,\n            tags = [\"manual\"],\n        )\n        private_hmap_deps.append(native.package_relative_label(private_hmap_name))\n        hmap_copts.append(\"-I$(execpath :{})\".format(private_hmap_name))\n\n    hmap_copts.append(\"-I.\")\n\n    if enable_swift_interop:\n        swift_interop_name = name + \"_swift_interop_hint\"\n        swift_interop_hint(\n            name = swift_interop_name,\n            module_name = module_name,\n            system_pcms = select({\n                \"@valdi//bzl/conditions:explicit_modules\": [\n                    \"@build_bazel_rules_swift//system_sdks:system_sdks\",\n                ],\n                \"//conditions:default\": [],\n            }),\n        )\n        aspect_hints = [\":\" + swift_interop_name]\n        clang_module_name = module_name or name\n    else:\n        aspect_hints = [\"@build_bazel_rules_swift//swift:no_module\"]\n        clang_module_name = None\n\n    snap_client_ios_library(\n        name = name,\n        deps = deps + hmap_deps,\n        implementation_deps = implementation_deps + private_hmap_deps,\n        generated_objects = generated_objects,\n        srcs = srcs,\n        hdrs = hdrs,\n        copts = base_copts + copts + hmap_copts,\n        data = data,\n        sdk_frameworks = sdk_frameworks,\n        aspect_hints = aspect_hints,\n        module_name = clang_module_name,\n        defines = defines,\n        tags = tags,\n        alwayslink = alwayslink,\n        visibility = visibility,\n    )\n"
  },
  {
    "path": "bzl/common/BUILD.bazel",
    "content": ""
  },
  {
    "path": "bzl/common/application_names.bzl",
    "content": "# Replaced when running valdi bootstrap\n# This default exists to allow building in open_source without invoking bootstrap\nANDROID_APPLICATION_NAME = \"New Valdi\"\nIOS_APPLICATION_NAME = \"New Valdi\"\n"
  },
  {
    "path": "bzl/common/nodejs_info.bzl",
    "content": "\"\"\"\nConstants for the current Node version and major version that is\nused by bazel in this WORKSPACE\n\"\"\"\n\nload(\"//bzl:additional_dependencies.bzl\", \"ADDITIONAL_NODE_URLS\")\n\nCURRENT_NODE_VERSION = \"22.12.0\"\nCURRENT_NODE_MAJOR_VERSION = \"22\"\n\n# These repositories specification are necessary until we update to the latest release of\n# the @rules_nodejs bazel rule that supports v22.12.10.\nEXTRA_NODE_REPOSITORIES = {\n    \"22.12.0-darwin_arm64\": (\"node-v22.12.0-darwin-arm64.tar.gz\", \"node-v22.12.0-darwin-arm64\", \"293dcc6c2408da21562d135b0412525e381bb6fe150d688edb58fe850d0f3e13\"),\n    \"22.12.0-darwin_amd64\": (\"node-v22.12.0-darwin-x64.tar.gz\", \"node-v22.12.0-darwin-x64\", \"52bc25dd026db7247c3c00439afdb83e95087248267f02d6c1a7250d1f896173\"),\n    \"22.12.0-linux_arm64\": (\"node-v22.12.0-linux-arm64.tar.xz\", \"node-v22.12.0-linux-arm64\", \"8cfd5a8b9afae5a2e0bd86b0148ca31d2589c0ea669c2d0b11c132e35d90ed68\"),\n    \"22.12.0-linux_ppc64le\": (\"node-v22.12.0-linux-ppc64le.tar.xz\", \"node-v22.12.0-linux-ppc64le\", \"199a606ba1ee86cce6d6b369c71f9d00873d2836a6662592afc3b6a5923e2004\"),\n    \"22.12.0-linux_s390x\": (\"node-v22.12.0-linux-s390x.tar.xz\", \"node-v22.12.0-linux-s390x\", \"9b517f8006eb4b451d40c461cbe64f93c6455566dbe2613387ab02412bc06d35\"),\n    \"22.12.0-linux_amd64\": (\"node-v22.12.0-linux-x64.tar.xz\", \"node-v22.12.0-linux-x64\", \"22982235e1b71fa8850f82edd09cdae7e3f32df1764a9ec298c72d25ef2c164f\"),\n    \"22.12.0-windows_amd64\": (\"node-v22.12.0-win-x64.zip\", \"node-v22.12.0-win-x64\", \"2b8f2256382f97ad51e29ff71f702961af466c4616393f767455501e6aece9b8\"),\n}\n\n# URLS in priority order of where to download nodejs from.\n# We keep nodejs.org in the list for local builds which can't see the\n# jenkins mirror; it will fallback with a warning.\nNODE_URLS = ADDITIONAL_NODE_URLS + [\n    \"https://nodejs.org.mirror.proxy.local/dist/v{version}/{filename}\",  # Proxy mirror\n    \"https://nodejs.org/dist/v{version}/{filename}\",  # Public fallback\n]\n"
  },
  {
    "path": "bzl/conditions/BUILD.bazel",
    "content": "load(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@build_bazel_rules_swift//swift/internal:feature_names.bzl\", \"SWIFT_FEATURE_USE_C_MODULES\")\nload(\":custom_selects.bzl\", \"custom_selects\")\n\nconfig_setting(\n    name = \"android_arm32\",\n    constraint_values = [\n        \"@platforms//cpu:armv7\",\n        \"@platforms//os:android\",\n    ],\n)\n\nconfig_setting(\n    name = \"android_arm64\",\n    constraint_values = [\n        \"@platforms//cpu:aarch64\",\n        \"@platforms//os:android\",\n    ],\n)\n\nconfig_setting(\n    name = \"android_x64\",\n    constraint_values = [\n        \"@platforms//cpu:x86_64\",\n        \"@platforms//os:android\",\n    ],\n)\n\nselects.config_setting_group(\n    name = \"linux\",\n    match_all = [\n        \"@platforms//os:linux\",\n        \":not_wasm\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nselects.config_setting_group(\n    \"linux_arm64\",\n    match_all = [\n        \"@platforms//cpu:aarch64\",\n        \"@platforms//os:linux\",\n        \":not_wasm\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nselects.config_setting_group(\n    \"linux_x64\",\n    match_all = [\n        \"@platforms//cpu:x86_64\",\n        \"@platforms//os:linux\",\n        \":not_wasm\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"android\",\n    constraint_values = [\n        \"@platforms//os:android\",\n    ],\n)\n\n# disable JNI. Only relevant for Android builds.\nconfig_setting(\n    name = \"jni_disabled\",\n    define_values = {\n        \"jni_disabled\": \"true\",\n    },\n    visibility = [\"//visibility:public\"],\n)\n\ncustom_selects.config_setting_inverse(\n    name = \"jni_enabled\",\n    inverse_of = \":jni_disabled\",\n    visibility = [\"//visibility:public\"],\n)\n\n# build for android assuming this will be loaded in an apk with a jni env\nselects.config_setting_group(\n    \"android_with_jni\",\n    match_all = [\n        \":android\",\n        \":jni_enabled\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nselects.config_setting_group(\n    \"macos\",\n    match_all = [\n        \"@platforms//os:macos\",\n        \":not_wasm\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"arm64\",\n    constraint_values = [\n        \"@platforms//cpu:aarch64\",\n    ],\n)\n\nconfig_setting(\n    name = \"x64\",\n    constraint_values = [\n        \"@platforms//cpu:x86_64\",\n    ],\n)\n\nselects.config_setting_group(\n    \"macos_arm64\",\n    match_all = [\n        \":macos\",\n        \":arm64\",\n        \":not_wasm\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nselects.config_setting_group(\n    \"macos_x86_64\",\n    match_all = [\n        \":macos\",\n        \":x64\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"ios_arm64\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n        \"@platforms//cpu:arm64\",\n        \"@build_bazel_apple_support//constraints:device\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"ios_x86_64\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n        \"@platforms//cpu:x86_64\",\n        \"@build_bazel_apple_support//constraints:simulator\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"ios_arm64_sim\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n        \"@platforms//cpu:arm64\",\n        \"@build_bazel_apple_support//constraints:simulator\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"ios\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"link_shared_libcxx\",\n    constraint_values = [\n        # Currently only supported on linux, but could be extended to android if ever needed.\n        \"@platforms//os:linux\",\n        \"@platforms//cpu:x86_64\",\n    ],\n    define_values = {\n        \"libcxx\": \"shared\",\n    },\n)\n\n# The emscripten toolchain sets cpu=wasm here\n# https://github.com/emscripten-core/emsdk/blob/main/bazel/emscripten_toolchain/BUILD.bazel#L51\n# This setting allows conditions in the form of \"//bzl/conditions:wasm\", that will be triggered\n# when the emscripten toolchain is set.\nconfig_setting(\n    name = \"wasm\",\n    values = {\n        \"cpu\": \"wasm\",\n    },\n)\n\ncustom_selects.config_setting_inverse(\n    name = \"not_wasm\",\n    inverse_of = \":wasm\",\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"open_source_build\",\n    define_values = {\n        \"open_source_build\": \"true\",\n    },\n)\n\n# Following config flags correspond to the values of the --strip Bazel flag.\n# see https://bazel.build/docs/user-manual#strip\nconfig_setting(\n    name = \"strip_always\",\n    values = {\n        \"strip\": \"always\",\n    },\n)\n\nconfig_setting(\n    name = \"strip_never\",\n    values = {\n        \"strip\": \"never\",\n    },\n)\n\n# This setting is used to enable the use of explicit modules in Swift.\nconfig_setting(\n    name = \"explicit_modules\",\n    values = {\n        \"features\": SWIFT_FEATURE_USE_C_MODULES,\n    },\n)\n\n# strip when compilation_mode is fastbuild\nconfig_setting(\n    name = \"strip_sometimes\",\n    values = {\n        \"strip\": \"sometimes\",\n    },\n)\n"
  },
  {
    "path": "bzl/conditions/custom_selects.bzl",
    "content": "def _config_setting_inverse(name, inverse_of, visibility = None):\n    \"\"\"Returns the logical inverse of the provided config_setting.\"\"\"\n    native.alias(\n        name = name,\n        actual = select({\n            inverse_of: \"@valdi//bzl/constants:false\",\n            \"//conditions:default\": \"@valdi//bzl/constants:true\",\n        }),\n        visibility = visibility,\n    )\n\ncustom_selects = struct(\n    config_setting_inverse = _config_setting_inverse,\n)\n"
  },
  {
    "path": "bzl/conditions/selects.bzl",
    "content": "load(\"@bazel_skylib//lib:selects.bzl\", bzl_selects = \"selects\")\nload(\":custom_selects.bzl\", \"custom_selects\")\n\ndef _config_setting_combinations(\n        prefix = \"\",\n        settings = [],\n        constants = [],\n        visibility = None):\n    \"\"\"Creates a config_setting_group for every combination of the provided config_settings.\n\n    The provided settings are a list of dictionaries where keys are config_settings and values\n    are \"tags\". Each dictionary forms a group of mutually-exclusive config_settings. One\n    config_setting is chosen from each dictionary to AND together a config_setting_group. In this\n    way, this function creates a config_setting_group for every possible combination of ANDing\n    together one config_setting from each dictionary. The name for each resulting\n    config_setting_group is the concatenation of all of the \"tags\" mapped to by the config_settings\n    that were selected to form it, in the order in which they appear in the list of dictionaries.\n    If a prefix is provided, the prefix is prepended to each name.\n\n    For simplicity, a dictionary is allowed to contain only 1 config_setting/tag pair. This implies\n    a dictionary of size 2 where the second element is the logical inverse of the first, and the\n    \"tag\" is empty, meaning when the inverse is selected, it does not contributed to the resulting\n    config_setting_group name.\n\n    Example 1:\n      config_setting_combinations(\n          [\n              {\n                  \"@snap_platforms//conditions:android_arm32\": \"android_arm32\",\n                  \"@snap_platforms//conditions:android_arm64\": \"android_arm64\",\n                  \"@snap_platforms//conditions:ios\": \"ios\",\n              },\n              {\n                  \"@snap_client_toolchains//:sc_build_flag_lto\": \"lto\",\n              },\n          ],\n          prefix = \"example1\"\n      )\n\n      creates the following config_setting_groups:\n\n      \":example1_android_arm32_lto\"\n      \":example1_android_arm32\"\n      \":example1_android_arm64_lto\"\n      \":example1_android_arm64\"\n      \":example1_ios_lto\"\n      \":example1_ios\"\n\n    Example 2:\n      config_setting_combinations(\n          [\n              {\n                  \"@snap_client_toolchains//:sc_build_flag_lto\": \"lto\",\n              },\n              {\n                  \"//bzl/conditions/grpc:tracers_disabled\": \"tracers_off\",\n              },\n          ],\n          prefix = \"example2\"\n      )\n\n      creates the following config_setting_groups:\n\n      \":example2_lto_tracers_off\"\n      \":example2_lto\"\n      \":example2_tracers_off\"\n      \":example2\"\n\n    Args:\n      prefix: The prefix to prepend to each resulting config_setting_group name.\n      settings: A list of dictionaries each representing a group of mutually-exclusive configs,\n        mapping config_setting to the \"tag\" that should appear in the config_setting_group names\n        that it is used to construct.\n      constants: A list of config_settings that are ANDed into every resulting config_setting_group\n        combination.\n      visibility: The visibility of the resulting config_setting_groups.\n      \"\"\"\n    if not settings:\n        fail(\"config_setting_combinations: the settings list cannot be empty.\")\n    name = prefix\n    selections = [0] * len(settings)\n    num_combinations = 1\n    for setting_group in settings:\n        # If there is only 1 config_setting in the group, add an inverse config_setting with empty tag.\n        if not setting_group:\n            fail(\"config_setting_combinations: the settings list cannot contain empty dicts.\")\n        if len(setting_group) == 1:\n            setting = setting_group.keys()[0]\n            scratch_inverse_name = setting.split(\":\")[1] + \"_inverse\" + \\\n                                   \"\".join([str(len(dict)) for dict in settings]) + prefix\n            custom_selects.config_setting_inverse(\n                scratch_inverse_name,\n                inverse_of = setting,\n                visibility = visibility,\n            )\n            setting_group[\":\" + scratch_inverse_name] = \"\"\n        num_combinations *= len(setting_group)\n\n    for i in range(num_combinations):\n        _config_setting_combination(prefix, settings, selections, constants, visibility)\n        _increment_selections(selections, settings)\n\ndef _increment_selections(selections, settings):\n    for i in reversed(range(len(selections))):\n        num_options = len(settings[i]) if len(settings[i]) > 1 else 2\n        if selections[i] == num_options - 1:\n            selections[i] = 0\n        else:\n            selections[i] += 1\n            return\n\ndef _config_setting_combination(prefix, settings, selections, constants, visibility):\n    name = prefix\n    applied_settings = list(constants)\n    for i in range(len(settings)):\n        setting = settings[i].keys()[selections[i]]\n        tag = settings[i].values()[selections[i]]\n        name += (\"_\" if name != \"\" and tag != \"\" else \"\") + tag\n        applied_settings.append(setting)\n    bzl_selects.config_setting_group(\n        name,\n        match_all = applied_settings,\n        visibility = visibility,\n    )\n\nselects = struct(\n    config_setting_inverse = custom_selects.config_setting_inverse,\n    config_setting_combinations = _config_setting_combinations,\n    # re-exports bazel-skylib's selects\n    with_or = bzl_selects.with_or,\n    with_or_dict = bzl_selects.with_or_dict,\n    config_setting_group = bzl_selects.config_setting_group,\n)\n"
  },
  {
    "path": "bzl/constants/BUILD.bazel",
    "content": "load(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\n\n# config_setting which is always \"true\"\nselects.config_setting_group(\n    \"true\",\n    match_any = [\n        \":stamp_binary_on\",\n        \":stamp_binary_off\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\n# config_setting which is always \"false\"\nselects.config_setting_group(\n    \"false\",\n    match_all = [\n        \":stamp_binary_on\",\n        \":stamp_binary_off\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"stamp_binary_on\",\n    values = {\"stamp\": \"1\"},\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"stamp_binary_off\",\n    values = {\"stamp\": \"0\"},\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "bzl/dependencies.bzl",
    "content": "load(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\nload(\"//bzl:nested_repository.bzl\", \"nested_repository\")\n\ndef local_or_nested_repository(workspace_root, name, path):\n    if workspace_root:\n        native.local_repository(\n            name = name,\n            path = workspace_root + \"/\" + path,\n        )\n    else:\n        nested_repository(\n            name = name,\n            source_repo = \"valdi\",\n            target_dir = path,\n        )\n\ndef setup_dependencies(workspace_root = None):\n    native.android_sdk_repository(\n        name = \"androidsdk\",\n        api_level = 36,  # The API version for Android compileSdk\n        build_tools_version = \"34.0.0\",\n    )\n\n    http_archive(\n        name = \"toolchains_llvm\",\n        canonical_id = \"v1.3.0\",\n        sha256 = \"d3c255b2ceec9eaebb6b5a44c904a48429b8dcb71e630de2f103e7b4aab9f073\",\n        strip_prefix = \"toolchains_llvm-v1.3.0\",\n        url = \"https://github.com/bazel-contrib/toolchains_llvm/releases/download/v1.3.0/toolchains_llvm-v1.3.0.tar.gz\",\n    )\n\n    http_archive(\n        name = \"com_google_protobuf\",\n        #sha256 = \"\",\n        strip_prefix = \"protobuf-27.0\",\n        url = \"https://github.com/protocolbuffers/protobuf/releases/download/v27.0/protobuf-27.0.tar.gz\",\n    )\n\n    http_archive(\n        name = \"rules_cc\",\n        #sha256 = \"\",\n        strip_prefix = \"rules_cc-0.0.12\",\n        urls = [\"https://github.com/bazelbuild/rules_cc/releases/download/0.0.12/rules_cc-0.0.12.tar.gz\"],\n    )\n\n    http_archive(\n        name = \"rules_android_ndk\",\n        sha256 = \"89bf5012567a5bade4c78eac5ac56c336695c3bfd281a9b0894ff6605328d2d5\",\n        strip_prefix = \"rules_android_ndk-0.1.3\",\n        url = \"https://github.com/bazelbuild/rules_android_ndk/releases/download/v0.1.3/rules_android_ndk-v0.1.3.tar.gz\",\n        patches = [\n            \"@valdi//third-party/rules_android_ndk/patches:expose_bins.patch\",\n        ],\n    )\n\n    http_archive(\n        name = \"bazel_skylib\",\n        sha256 = \"af87959afe497dc8dfd4c6cb66e1279cb98ccc84284619ebfec27d9c09a903de\",\n        urls = [\n            \"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.2.0/bazel-skylib-1.2.0.tar.gz\",\n            \"https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.0/bazel-skylib-1.2.0.tar.gz\",\n        ],\n    )\n\n    http_archive(\n        name = \"rules_android\",\n        url = \"https://github.com/bazelbuild/rules_android/archive/5e74650496dff30e97b8eee5a8b12968de3bdec3.zip\",\n        sha256 = \"89f8698e7afa76c6eb60907d1200c33594866c8263a9ef0161e81dc0d397a9e9\",\n        strip_prefix = \"rules_android-5e74650496dff30e97b8eee5a8b12968de3bdec3\",\n        patch_args = [\"-p1\"],\n        patches = [\n            \"@valdi//third-party/build_bazel_rules_android/patches:rules_android_rules_attrs.patch\",\n            \"@valdi//third-party/build_bazel_rules_android/patches:rules_android_rules_android_local_test.patch\",\n            \"@valdi//third-party/build_bazel_rules_android/patches:rules_android_android_rules.patch\",\n            \"@valdi//third-party/build_bazel_rules_android/patches:rules_android_rules_aar_import.patch\",\n        ],\n    )\n\n    http_archive(\n        name = \"rules_kotlin\",\n        url = \"https://github.com/bazelbuild/rules_kotlin/releases/download/v1.9.0/rules_kotlin-v1.9.0.tar.gz\",\n        sha256 = \"5766f1e599acf551aa56f49dab9ab9108269b03c557496c54acaf41f98e2b8d6\",\n        patches = [\"@valdi//third-party/rules_kotlin:fix_manifest_custom_package.patch\"],\n    )\n\n    http_archive(\n        name = \"rules_java\",\n        sha256 = \"976ef08b49c929741f201790e59e3807c72ad81f428c8bc953cdbeff5fed15eb\",\n        url = \"https://github.com/bazelbuild/rules_java/releases/download/7.4.0/rules_java-7.4.0.tar.gz\",\n    )\n\n    http_archive(\n        name = \"rules_jvm_external\",\n        strip_prefix = \"rules_jvm_external-6.2\",\n        sha256 = \"808cb5c30b5f70d12a2a745a29edc46728fd35fa195c1762a596b63ae9cebe05\",\n        url = \"https://github.com/bazelbuild/rules_jvm_external/releases/download/6.2/rules_jvm_external-6.2.tar.gz\",\n    )\n\n    http_archive(\n        name = \"rules_xcodeproj\",\n        integrity = \"sha256-bNMpoLSjy1hpeFYYKDgliM6pYqyBMb7IRlkjkvPlBJE=\",\n        url = \"https://github.com/MobileNativeFoundation/rules_xcodeproj/releases/download/3.2.0/release.tar.gz\",\n    )\n\n    http_archive(\n        name = \"build_bazel_rules_swift\",\n        sha256 = \"5eff717c18bb513285b499add68f2331509cd4e411ff085e96a86b3342c1e5aa\",\n        url = \"https://github.com/bazelbuild/rules_swift/releases/download/3.1.2/rules_swift.3.1.2.tar.gz\",\n        patch_args = [\"-p1\"],\n        patches = [\"@valdi//third-party/rules_swift/patches:rules_swift.patch\"],\n    )\n\n    # rules_apple relies on rules_shell starting with 4.0.0. For bzlmod users,\n    # this dependency is automatically handled. However, to prevent build failures\n    # for WORKSPACE usage, we explicitly define the rules_shell dependency here.\n    http_archive(\n        name = \"rules_shell\",\n        sha256 = \"d8cd4a3a91fc1dc68d4c7d6b655f09def109f7186437e3f50a9b60ab436a0c53\",\n        strip_prefix = \"rules_shell-0.3.0\",\n        url = \"https://github.com/bazelbuild/rules_shell/releases/download/v0.3.0/rules_shell-v0.3.0.tar.gz\",\n    )\n\n    http_archive(\n        name = \"build_bazel_rules_apple\",\n        sha256 = \"70b0fb2aec1055c978109199bf58ccb5008aba8e242f3305194045c271ca3cae\",\n        url = \"https://github.com/bazelbuild/rules_apple/releases/download/4.0.0/rules_apple.4.0.0.tar.gz\",\n    )\n\n    # Apple support setup from https://github.com/bazelbuild/apple_support/releases/tag/1.21.0\n    http_archive(\n        name = \"build_bazel_apple_support\",\n        sha256 = \"293f5fe430787f3a995b2703440d27498523df119de00b84002deac9525bea55\",\n        url = \"https://github.com/bazelbuild/apple_support/releases/download/1.21.0/apple_support.1.21.0.tar.gz\",\n    )\n\n    http_archive(\n        name = \"bazel_features\",\n        sha256 = \"95fb3cfd11466b4cad6565e3647a76f89886d875556a4b827c021525cb2482bb\",\n        strip_prefix = \"bazel_features-1.10.0\",\n        url = \"https://github.com/bazel-contrib/bazel_features/releases/download/v1.10.0/bazel_features-v1.10.0.tar.gz\",\n        patches = [\"@valdi//third-party/bazel_features:fix_bazel_version.patch\"],\n    )\n\n    # zoo library\n    # Used for its more efficient anonymous Function implementation than std::function\n    # https://github.com/thecppzoo/zoo\n    # Doesn't do releases\n    http_archive(\n        name = \"zoo\",\n        url = \"https://github.com/thecppzoo/zoo/archive/33b868300145773d8c433b6b3d6643eba6334f7d.zip\",\n        build_file = \"@valdi//third-party/zoo:zoo.BUILD\",\n        integrity = \"sha256-9GIWp7GyVdZn24mvsMGtzhDD2N+W5L5AO3o2tYHtnVk=\",\n        strip_prefix = \"zoo-33b868300145773d8c433b6b3d6643eba6334f7d\",\n    )\n\n    http_archive(\n        name = \"hermes\",\n        url = \"https://github.com/facebook/hermes/archive/880b1645b5dca974f4329dc4108692d301abee0d.zip\",\n        integrity = \"sha256-+GQiTtN6H8TQz/+YkVz73dHeYAZ86/9hAUwTlkISx48=\",\n        strip_prefix = \"hermes-880b1645b5dca974f4329dc4108692d301abee0d\",\n        build_file = \"@valdi//third-party/hermes:hermes.BUILD\",\n    )\n\n    http_archive(\n        name = \"gtest\",\n        strip_prefix = \"googletest-1.13.0\",\n        url = \"https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz\",\n        integrity = \"sha256-rX/boR6gEcHZJbMonPSvLGajUuGNTHJkOS/q116Rk2M=\",\n    )\n\n    http_archive(\n        name = \"boringssl\",\n        url = \"https://github.com/google/boringssl/archive/82f9853fc7d7360ae44f1e1357a6422c5244bbd8.tar.gz\",\n        strip_prefix = \"boringssl-82f9853fc7d7360ae44f1e1357a6422c5244bbd8\",\n        integrity = \"sha256-Q+jJ5SofjJ1PbWAvAwI7jZ9o1f//x7+ZxV5sLE1XTa0=\",\n    )\n\n    # Used for networking, and other utilities like small_vector\n    # TODO: Make the public boost repo compatible with open_source builds\n    http_archive(\n        name = \"boost\",\n        build_file = \"@valdi//third-party/boost:boost.BUILD\",\n        patches = [\n            \"@valdi//third-party/boost/patches:asio.patch\",\n            \"@valdi//third-party/boost/patches:global_asio_initializers.patch\",\n            \"@valdi//third-party/boost/patches:interprocess_emscripten.patch\",\n            \"@valdi//third-party/boost/patches:remove_invalid_file_1_78.patch\",\n        ],\n        strip_prefix = \"boost_1_78_0\",\n        integrity = \"sha256-hoHxddS9smxSIiZleT7vCEkNd1hSkzD5jTsp3Qc1vMw=\",\n        url = \"https://archives.boost.io/release/1.78.0/source/boost_1_78_0.tar.bz2\",\n    )\n\n    # phmap library\n    # Used for its efficient flat_map implementation\n    # https://github.com/greg7mdp/parallel-hashmap/\n    http_archive(\n        name = \"phmap\",\n        build_file = \"@valdi//third-party/phmap:phmap.BUILD\",\n        strip_prefix = \"parallel-hashmap-1.3.12\",\n        integrity = \"sha256-DMIDFEMhkkz7/MQB9C2CBMDdJOJ2DHocCRuqFtl3fAg=\",\n        url = \"https://github.com/greg7mdp/parallel-hashmap/archive/refs/tags/v1.3.12.tar.gz\",\n    )\n\n    # Local upstream dependencies that are overwritten in parent WORKSPACES\n\n    # From https://github.com/fmtlib/fmt/releases/tag/7.0.3\n    http_archive(\n        name = \"fmt\",\n        build_file = \"@valdi//third-party/fmt:fmt.BUILD\",\n        integrity = \"sha256-XZjFBNAgX5EuIkSezep3a3jOC7CWknM0+AeB5yAITJ8=\",\n        strip_prefix = \"fmt-7.1.3\",\n        url = \"https://github.com/fmtlib/fmt/releases/download/7.1.3/fmt-7.1.3.zip\",\n    )\n\n    local_or_nested_repository(\n        workspace_root = workspace_root,\n        name = \"android_macros\",\n        path = \"bzl/macros\",\n    )\n\n    local_or_nested_repository(\n        workspace_root = workspace_root,\n        name = \"snap_macros\",\n        path = \"bzl/valdi/snap_macros\",\n    )\n\n    local_or_nested_repository(\n        workspace_root = workspace_root,\n        name = \"snap_client_toolchains\",\n        path = \"/bzl/toolchains\",\n    )\n\n    local_or_nested_repository(\n        workspace_root = workspace_root,\n        name = \"snap_platforms\",\n        path = \"/bzl/platforms\",\n    )\n\n    local_or_nested_repository(\n        workspace_root = workspace_root,\n        name = \"skia_user_config\",\n        path = \"/third-party/skia_user_config\",\n    )\n\n    local_or_nested_repository(\n        workspace_root = workspace_root,\n        name = \"rules_hdrs\",\n        path = \"/third-party/rules_hdrs\",\n    )\n\n    local_or_nested_repository(\n        workspace_root = workspace_root,\n        name = \"valdi_toolchain\",\n        path = \"/bin\",\n    )\n\n    local_or_nested_repository(\n        workspace_root = workspace_root,\n        name = \"resvg_libs\",\n        path = \"/third-party/resvg/resvg_libs\",\n    )\n\n    # From https://github.com/open-source-parsers/jsoncpp/releases/tag/1.8.0\n    http_archive(\n        name = \"jsoncpp\",\n        strip_prefix = \"jsoncpp-1.8.0\",\n        build_file = \"@valdi//third-party/jsoncpp:jsoncpp.BUILD\",\n        integrity = \"sha256-TdYW0kzlN9+8IrTdgb9v+NgFd6a7tHzamvuEReRmH5s=\",\n        url = \"https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/1.8.0.zip\",\n    )\n\n    # From https://github.com/harfbuzz/harfbuzz/releases/tag/12.2.0\n    http_archive(\n        name = \"harfbuzz\",\n        strip_prefix = \"harfbuzz-12.2.0\",\n        build_file = \"@valdi//third-party/harfbuzz:harfbuzz.BUILD\",\n        integrity = \"sha256-7LYDqkJqiyRmVxhme9pkqEwVBNt0VO5Mrb02Lupk5UU=\",\n        urls = [\"https://github.com/harfbuzz/harfbuzz/releases/download/12.2.0/harfbuzz-12.2.0.tar.xz\"],\n    )\n\n    http_archive(\n        name = \"com_google_absl\",\n        type = \"tar.gz\",\n        strip_prefix = \"abseil-cpp-20230802.0\",\n        url = \"https://github.com/abseil/abseil-cpp/archive/refs/tags/20230802.0.tar.gz\",\n        sha256 = \"59d2976af9d6ecf001a81a35749a6e551a335b949d34918cfade07737b9d93c5\",\n    )\n\n    # From https://github.com/protocolbuffers/protobuf/releases/tag/v27.0\n    http_archive(\n        name = \"protobuf_cpp\",\n        strip_prefix = \"protobuf-27.0\",\n        #build_file = \"@valdi//third-party/protobuf_cpp:protobuf_cpp.BUILD\",\n        url = \"https://github.com/protocolbuffers/protobuf/releases/download/v27.0/protobuf-27.0.tar.gz\",\n        #integrity = \"sha256-ocB26D9FtkueMK6JqZC6Sq6ffcGKypD3aQ9FjcWuBoE=\",\n    )\n\n    http_archive(\n        name = \"backward-cpp\",\n        build_file = \"@valdi//third-party/backward:backward.BUILD\",\n        strip_prefix = \"backward-cpp-1.6\",\n        integrity = \"sha256-xlTQkj1D8c6iPQhnKWc0mOR0H7JFfoBs+urqeyDJfBA=\",\n        url = \"https://github.com/bombela/backward-cpp/archive/refs/tags/v1.6.tar.gz\",\n    )\n\n    http_archive(\n        name = \"xxhash\",\n        build_file = \"@valdi//third-party/xxhash:xxhash.BUILD\",\n        integrity = \"sha256-uu4Mav1PAxZd56TmeYjRbw8rJXtR0OPLkZCTAqJqecQ=\",\n        url = \"https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.2.tar.gz\",\n    )\n\n    http_archive(\n        name = \"zlib\",\n        build_file = Label(\"@valdi//third-party/zlib:zlib.BUILD\"),\n        #sha256 = \"d14c38e313afc35a9a8760dadf26042f51ea0f5d154b0630a31da0540107fb98\",\n        strip_prefix = \"zlib-1.3.1\",\n        urls = [\n            \"https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.xz\",\n        ],\n    )\n\n    # Transitive dependency of skia\n    http_archive(\n        name = \"zlib_chromium\",\n        url = \"https://github.com/simonis/zlib-chromium/archive/93867c6db67801f74c2d0840a271c7aa7fd6716c.zip\",\n        build_file = \"@valdi//third-party/zlib_chromium:zlib_chromium.BUILD\",\n        integrity = \"sha256-aybDRpEOnvUrCW8/wTFSuduz5Rk+YxYGdCUZYVY5G9g=\",\n        strip_prefix = \"zlib-chromium-93867c6db67801f74c2d0840a271c7aa7fd6716c\",\n        patch_args = [\"-p1\"],\n        patches = [\n            \"@valdi//third-party/zlib_chromium/patches:apple.patch\",\n        ],\n    )\n\n    # From https://github.com/facebook/zstd/releases/tag/v1.5.6\n    http_archive(\n        name = \"zstd\",\n        build_file = \"@valdi//third-party/zstd:zstd.BUILD\",\n        url = \"https://github.com/facebook/zstd/releases/download/v1.5.6/zstd-1.5.6.tar.gz\",\n        strip_prefix = \"zstd-1.5.6\",\n        integrity = \"sha256-jCngbPQqrMHq/EB3ri7Gxvy5amJhV+BZPV6Co0/UA8E=\",\n    )\n\n    # From https://github.com/unicode-org/icu/releases/tag/release-68-1\n    # Downstream uses a modified 61.1 but the upstream version of 61.1\n    # does not compile with C++20\n    http_archive(\n        name = \"icu\",\n        build_file = \"@valdi//third-party/icu:icu.BUILD\",\n        url = \"https://github.com/unicode-org/icu/releases/download/release-68-1/icu4c-68_1-src.tgz\",\n        strip_prefix = \"icu\",\n        integrity = \"sha256-qfLj2LRDS45Th4tDCL0ebuUcnHBC4rGjdqvvtvuyny0=\",\n    )\n\n    http_archive(\n        name = \"websocketpp\",\n        strip_prefix = \"websocketpp-0.8.2\",\n        url = \"https://github.com/zaphoyd/websocketpp/archive/refs/tags/0.8.2.tar.gz\",\n        build_file = \"@valdi//third-party/websocketpp:websocketpp.BUILD\",\n        integrity = \"sha256-bOiJ2F7Nwtj6B0CNZ4fnNSUQdQ2qZrWtRKrLR76nZ1U=\",\n    )\n\n    http_archive(\n        name = \"test262\",\n        url = \"https://github.com/tc39/test262/archive/refs/heads/main.zip\",\n        build_file = \"@valdi//third-party/test262:test262.BUILD\",\n        strip_prefix = \"test262-main\",\n        integrity = \"sha256-Lv/ZdXIV5f0n11oFTKBq22r0aLGF6HsDp36B1afgVDo=\",\n    )\n\n    # Deps to support the deps\n\n    http_archive(\n        name = \"rules_pkg\",\n        sha256 = \"8f9ee2dc10c1ae514ee599a8b42ed99fa262b757058f65ad3c384289ff70c4b8\",\n        urls = [\n            \"https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz\",\n            \"https://github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz\",\n        ],\n    )\n\n    http_archive(\n        name = \"rules_nodejs\",\n        sha256 = \"8fc8e300cb67b89ceebd5b8ba6896ff273c84f6099fc88d23f24e7102319d8fd\",\n        urls = [\"https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.4/rules_nodejs-core-5.8.4.tar.gz\"],\n    )\n\n    http_archive(\n        name = \"build_bazel_rules_nodejs\",\n        sha256 = \"709cc0dcb51cf9028dd57c268066e5bc8f03a119ded410a13b5c3925d6e43c48\",\n        urls = [\"https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.4/rules_nodejs-5.8.4.tar.gz\"],\n    )\n\n    http_archive(\n        name = \"aspect_rules_js\",\n        sha256 = \"6b7e73c35b97615a09281090da3645d9f03b2a09e8caa791377ad9022c88e2e6\",\n        strip_prefix = \"rules_js-2.0.0\",\n        url = \"https://github.com/aspect-build/rules_js/releases/download/v2.0.0/rules_js-v2.0.0.tar.gz\",\n    )\n\n    http_archive(\n        name = \"aspect_rules_ts\",\n        sha256 = \"6fd16aa24c2e8547b72561ece1c7d307b77a5f98f0402934396f6eefbac59aa2\",\n        strip_prefix = \"rules_ts-3.7.0\",\n        url = \"https://github.com/aspect-build/rules_ts/releases/download/v3.7.0/rules_ts-v3.7.0.tar.gz\",\n    )\n\n    http_archive(\n        name = \"aspect_rules_esbuild\",\n        sha256 = \"530adfeae30bbbd097e8af845a44a04b641b680c5703b3bf885cbd384ffec779\",\n        strip_prefix = \"rules_esbuild-0.22.1\",\n        url = \"https://github.com/aspect-build/rules_esbuild/releases/download/v0.22.1/rules_esbuild-v0.22.1.tar.gz\",\n    )\n\n    http_archive(\n        name = \"aspect_bazel_lib\",\n        sha256 = \"53cadea9109e646a93ed4dc90c9bbcaa8073c7c3df745b92f6a5000daf7aa3da\",\n        strip_prefix = \"bazel-lib-2.21.2\",\n        url = \"https://github.com/bazel-contrib/bazel-lib/releases/download/v2.21.2/bazel-lib-v2.21.2.tar.gz\",\n    )\n\n    # fuzzing rules directly copied from https://github.com/bazelbuild/rules_fuzzing/tree/1dbcd9167300ad226d29972f5f9c925d6d81f441?tab=readme-ov-file#configuring-the-workspace\n    http_archive(\n        name = \"rules_fuzzing\",\n        sha256 = \"e6bc219bfac9e1f83b327dd090f728a9f973ee99b9b5d8e5a184a2732ef08623\",\n        strip_prefix = \"rules_fuzzing-0.5.2\",\n        urls = [\"https://github.com/bazelbuild/rules_fuzzing/archive/v0.5.2.zip\"],\n    )\n\n    http_archive(\n        name = \"rules_python\",\n        sha256 = \"a644da969b6824cc87f8fe7b18101a8a6c57da5db39caa6566ec6109f37d2141\",\n        strip_prefix = \"rules_python-0.20.0\",\n        url = \"https://github.com/bazelbuild/rules_python/releases/download/0.20.0/rules_python-0.20.0.tar.gz\",\n    )\n\n    http_archive(\n        name = \"resvg\",\n        url = \"https://github.com/RazrFalcon/resvg/archive/a739aef5d01360ec238c886bc50674f31458df00.zip\",\n        build_file = \"@valdi//third-party/resvg:resvg.BUILD\",\n        strip_prefix = \"resvg-a739aef5d01360ec238c886bc50674f31458df00\",\n        integrity = \"sha256-kohUhIYyFoaeIHLBhYwq6g7+h34r3i9/IIQoWyJAmSE=\",\n    )\n\n    http_archive(\n        name = \"skia\",\n        url = \"https://github.com/google/skia/archive/8d5c6efb04514a31f09a2e865940f99cdf60ce21.zip\",\n        strip_prefix = \"skia-8d5c6efb04514a31f09a2e865940f99cdf60ce21\",\n        integrity = \"sha256-piM7FfzT3xekYxvwEDlejJ8Zj+zaxa3oIKpDsx1y6eQ=\",\n    )\n\n    http_archive(\n        name = \"libjpeg_turbo\",\n        build_file = \"@skia//bazel/external/libjpeg_turbo:BUILD.bazel\",\n        url = \"https://chromium.googlesource.com/chromium/deps/libjpeg_turbo/+archive/e14cbfaa85529d47f9f55b0f104a579c1061f9ad.tar.gz\",\n        patches = [\n            \"@valdi//third-party/libjpeg_turbo:warning_fix.patch\",\n        ],\n    )\n\n    http_archive(\n        name = \"libpng\",\n        build_file = \"@skia//bazel/external/libpng:BUILD.bazel\",\n        url = \"https://skia.googlesource.com/third_party/libpng.git/+archive/ed217e3e601d8e462f7fd1e04bed43ac42212429.tar.gz\",\n        patch_args = [\"-p1\"],\n        patches = [\n            \"@valdi//third-party/libpng:fix_armv7.patch\",\n        ],\n    )\n\n    http_archive(\n        name = \"libwebp\",\n        build_file = \"@skia//bazel/external/libwebp:BUILD.bazel\",\n        url = \"https://github.com/webmproject/libwebp/archive/845d5476a866141ba35ac133f856fa62f0b7445f.tar.gz\",\n        strip_prefix = \"libwebp-845d5476a866141ba35ac133f856fa62f0b7445f\",\n    )\n\n    http_archive(\n        name = \"zlib_skia\",\n        build_file = \"@skia//bazel/external/zlib_skia:BUILD.bazel\",\n        url = \"https://chromium.googlesource.com/chromium/src/third_party/zlib/+archive/646b7f569718921d7d4b5b8e22572ff6c76f2596.tar.gz\",\n        patch_args = [\"-p1\"],\n        patches = [\n            \"@valdi//third-party/zlib_skia:android_ios_x86_64.patch\",\n        ],\n    )\n\n    http_archive(\n        name = \"freetype\",\n        build_file = \"@skia//bazel/external/freetype:BUILD.bazel\",\n        url = \"https://github.com/freetype/freetype/archive/5d4e649f740c675426fbe4cdaffc53ee2a4cb954.tar.gz\",\n        strip_prefix = \"freetype-5d4e649f740c675426fbe4cdaffc53ee2a4cb954\",\n    )\n\n    http_archive(\n        name = \"expat\",\n        build_file = \"@skia//bazel/external/expat:BUILD.bazel\",\n        url = \"https://github.com/libexpat/libexpat/archive/624da0f593bb8d7e146b9f42b06d8e6c80d032a3.tar.gz\",\n        strip_prefix = \"libexpat-624da0f593bb8d7e146b9f42b06d8e6c80d032a3\",\n    )\n\n    nested_repository(\n        name = \"expat_config\",\n        source_repo = \"skia\",\n        target_dir = \"/third_party/expat/include\",\n    )\n\n    nested_repository(\n        name = \"freetype_config\",\n        source_repo = \"skia\",\n        target_dir = \"/third_party/freetype2/include\",\n    )\n\n    http_archive(\n        name = \"ocmock\",\n        build_file = \"//third-party/ocmock:OCMock.build\",\n        sha256 = \"3c2dc673c83418a6213e63a643d966c3f790693b4e8578e0df4f68ae28ae3fea\",\n        strip_prefix = \"ocmock-3.9.4\",\n        url = \"https://github.com/erikdoe/ocmock/archive/refs/tags/v3.9.4.tar.gz\",\n    )\n"
  },
  {
    "path": "bzl/expand_template.bzl",
    "content": "def _impl(ctx):\n    out = ctx.actions.declare_file(ctx.attr.output)\n    substitutions = dict(zip(ctx.attr.substitution_keys, ctx.attr.substitution_values))\n    ctx.actions.expand_template(\n        output = out,\n        template = ctx.file.src,\n        substitutions = substitutions,\n    )\n    return [DefaultInfo(files = depset([out]))]\n\n_expand_template = rule(\n    implementation = _impl,\n    attrs = {\n        \"src\": attr.label(\n            allow_single_file = True,\n            mandatory = True,\n        ),\n        \"output\": attr.string(mandatory = True),\n        \"substitution_keys\": attr.string_list(mandatory = True),\n        \"substitution_values\": attr.string_list(mandatory = True),\n    },\n)\n\ndef expand_template(name, src, output, substitutions = dict(), select_based_substitutions = dict()):\n    # this dance is necessary because select() doesn't get resolved when we\n    # would like it to; see:\n    # https://github.com/bazelbuild/bazel/issues/8171\n    # https://github.com/bazelbuild/bazel/issues/3902#issuecomment-424934188\n    # the solution is to split the keys and values into separate attrs,\n    # so that we can use select's special treatment of '+', which allows\n    # select to work directly at the rule invocation, and then zip them\n    # back together inside the rule.\n\n    substitution_keys = list(select_based_substitutions)\n    substitution_values = list(select_based_substitutions.values())\n\n    selected = []\n    for select_dict in substitution_values:\n        selected = selected + select(select_dict)\n\n    _expand_template(\n        name = name,\n        src = src,\n        output = output,\n        substitution_keys = substitution_keys + list(substitutions),\n        substitution_values = selected + list(substitutions.values()),\n    )\n"
  },
  {
    "path": "bzl/ide/open_source.bazelproject",
    "content": "directories:\n  # Add the directories you want added as source here\n  # By default, we've added your entire workspace ('.')\n  .\n\n# Automatically includes all relevant targets under the 'directories' above\nderive_targets_from_directories: false\n\ntargets:\n  # If source code isn't resolving, add additional targets that compile it here\n  //valdi\n  //valdi:valdi_java\n  //valdi_core\n  //snap_drawing\n\ntest_sources:\n  # A list of workspace-relative glob patterns, matching directories.\n  # Determines which sources IntelliJ treats as test sources.\n  */javatests/*\n  */src/test/*\n\nadditional_languages:\n  c\n  kotlin\n  android\n\nworkspace_type: android\n\n# Please uncomment an android-SDK platform. Available SDKs are:\n# Selects which android platform from your SDK directory to use.\n# Corresponds to a subdirectory in ~/<sdk>/platforms.\nandroid_sdk_platform: android-36\nandroid_min_sdk: 21\n"
  },
  {
    "path": "bzl/macros/BUILD.bazel",
    "content": ""
  },
  {
    "path": "bzl/macros/MODULE.bazel",
    "content": "module(name = \"android_macros\")\n\nbazel_dep(name = \"rules_android\", version = \"0.5.1\")\n"
  },
  {
    "path": "bzl/macros/WORKSPACE",
    "content": ""
  },
  {
    "path": "bzl/macros/android.bzl",
    "content": "load(\n    \"@rules_android//rules:rules.bzl\",\n    _aar_import = \"aar_import\",\n)\n\ndef aar_import(**kwargs):\n    patched_kwargs = dict(kwargs)\n    existing = patched_kwargs.get(\"deps\", [])\n    patched_kwargs[\"deps\"] = existing + [\n        \"@rules_kotlin//kotlin/compiler:kotlin-stdlib\",\n    ]\n\n    _aar_import(**patched_kwargs)\n"
  },
  {
    "path": "bzl/modulemap.bzl",
    "content": "def _modulemap_command(modulemap, module_name):\n    \"\"\" Generate a shell script to create modulemap.\n\n        The modulemap format is specified at: https://clang.llvm.org/docs/Modules.html#header-declaration\n\n        Example:\n        module {ModuleName} {\n            header \"header1.h\"\n            header \"header2.h\"\n            export *\n        }\n    \"\"\"\n\n    # A header path inside a modulemap should be relative to the modulemap file\n    slashes_count = modulemap.path.count(\"/\")\n    relative_path = \"\".join([\"../\"] * slashes_count)\n\n    command = \"\"\"\necho \"module {module_name} {{\" >> \"{output_file}\"\n\nfor arg in \"$@\"; do\n    if [[ \"$arg\" == *.h ]]; then\n        echo \"  header \\\\\"{relative_path}$arg\\\\\"\" >> \"{output_file}\"\n    fi\ndone\n\necho \"  export *\" >> \"{output_file}\"\necho \"}}\" >> \"{output_file}\"\n\n\"\"\".format(\n        module_name = module_name,\n        output_file = modulemap.path,\n        relative_path = relative_path,\n    )\n\n    return command\n\ndef _modulemap_impl(ctx):\n    modulemap = ctx.outputs.out\n\n    # Collect all header files and folders\n    inputs = []\n    for hdr in ctx.attr.hdrs:\n        for f in hdr.files.to_list():\n            # Unfortunately Bazel rules don't support label_list which would allow files and folders filters\n            # Filter here explicitly to mimic the behavior\n            if f.is_directory or f.basename.endswith(\".h\"):\n                inputs.append(f)\n\n    inputs = depset(inputs).to_list()\n\n    # Pass them as arguments to the generated shell command\n    args = ctx.actions.args()\n    args.add_all(inputs, expand_directories = True)\n    ctx.actions.run_shell(\n        command = _modulemap_command(modulemap, ctx.attr.module_name),\n        arguments = [args],\n        inputs = inputs,\n        outputs = [modulemap],\n        mnemonic = \"ModuleMapGen\",\n        progress_message = \"Generating modulemap for {}\".format(ctx.attr.module_name),\n    )\n\n    objc_provider = apple_common.new_objc_provider(\n        module_map = depset([modulemap]),\n    )\n    outputs = [modulemap]\n    compilation_context = cc_common.create_compilation_context(\n        headers = depset(transitive = [depset(outputs)]),\n    )\n    cc_info = CcInfo(\n        compilation_context = compilation_context,\n    )\n\n    return [\n        DefaultInfo(\n            files = depset([modulemap]),\n        ),\n        objc_provider,\n        cc_info,\n    ]\n\n_modulemap = rule(\n    implementation = _modulemap_impl,\n    attrs = {\n        \"module_name\": attr.string(\n            mandatory = True,\n            doc = \"The name of the module.\",\n        ),\n        \"hdrs\": attr.label_list(\n            allow_files = True,\n            doc = \"The list Objective-C header files used to construct the module map.\",\n        ),\n        \"out\": attr.output(\n            doc = \"The name of the output module map file.\",\n        ),\n    },\n)\n\ndef modulemap(name, **kwargs):\n    _modulemap(\n        name = name,\n        out = name + \".modulemap\",\n        **kwargs\n    )\n"
  },
  {
    "path": "bzl/nested_repository.bzl",
    "content": "def _nested_repository_impl(ctx):\n    # Try to resolve using relative path (works when source_repo is external)\n    relative_dir = \"../{}\".format(ctx.attr.source_repo)\n    check = ctx.execute([\"test\", \"-d\", relative_dir])\n\n    if check.return_code == 0:\n        # External repository exists (internal bzlmod setup)\n        target_path = \"{}/{}\".format(relative_dir, ctx.attr.target_dir)\n    else:\n        # We're in the main workspace (WORKSPACE-based repo)\n        # The source_repo is \"valdi\" which is the workspace itself\n\n        # If workspace_dir is provided, use it\n        if ctx.attr.workspace_dir:\n            workspace_root = ctx.attr.workspace_dir\n        else:\n            # For WORKSPACE-based repos, we need to find the workspace root\n            # The best way is to parse it from the current path structure\n            # We're in: .../external/<repo_name>\n            # We need to find where Bazel was originally invoked from\n\n            # Get the current working directory\n            pwd_result = ctx.execute([\"pwd\"])\n            current_dir = pwd_result.stdout.strip()\n\n            # Try to find a directory that contains WORKSPACE by going up from a known location\n            # We know the output_base path structure, so we can look for workspace metadata\n            find_ws = ctx.execute([\n                \"sh\",\n                \"-c\",\n                # Look for a file that might have workspace path info\n                \"cat ../../server/command.log 2>/dev/null | grep -o 'Starting local .* server.*' | head -1\",\n            ])\n\n            # For now, fail with a helpful message\n            fail(\"nested_repository: Cannot auto-detect workspace root in WORKSPACE-based repos during fetch phase. \" +\n                 \"Current dir: {}. Please pass workspace_dir attribute explicitly, e.g. workspace_dir = '/Users/cholgate/Projects/valdi_staging'. \" +\n                 \"Find output: '{}'\".format(current_dir, find_ws.stdout))\n\n        target_path = \"{}/{}\".format(workspace_root, ctx.attr.target_dir)\n\n    res = ctx.execute([\n        \"sh\",\n        \"-c\",\n        \"ls -1 {}\".format(target_path),\n    ])\n    if res.return_code != 0:\n        fail(\"Failed to resolve files in target dir {}: {}\".format(target_path, res.stderr))\n\n    file_list = res.stdout.strip().split(\"\\n\")\n\n    # Check if a BUILD file already exists in the target directory\n    has_build_file = False\n    for f in file_list:\n        if f in [\"BUILD\", \"BUILD.bazel\"]:\n            has_build_file = True\n            break\n\n    # Create symlinks for all files\n    for f in file_list:\n        ctx.symlink(\"{}/{}\".format(target_path, f), f)\n\n        # Only generate a BUILD file if one doesn't already exist\n    if not has_build_file:\n        build_content = \"# Auto-generated BUILD file for nested_repository\\n\"\n        build_content += \"package(default_visibility = [\\\"//visibility:public\\\"])\\n\\n\"\n\n        # Export all files so they can be referenced as targets\n        build_content += \"exports_files([\"\n        for f in file_list:\n            build_content += \"\\n    \\\"{}\\\",\".format(f)\n        build_content += \"\\n])\\n\"\n\n        ctx.file(\"BUILD.bazel\", build_content)\n\nnested_repository = repository_rule(\n    implementation = _nested_repository_impl,\n    attrs = {\n        \"source_repo\": attr.string(mandatory = True),\n        \"target_dir\": attr.string(mandatory = True),\n        \"workspace_dir\": attr.string(default = \"\"),\n    },\n    local = True,\n)\n"
  },
  {
    "path": "bzl/platforms/BUILD.bazel",
    "content": "platform(\n    name = \"ios_arm64\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n        \"@platforms//cpu:aarch64\",\n        \"@build_bazel_apple_support//constraints:device\",\n    ],\n)\n\nplatform(\n    name = \"ios_x64\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n        \"@platforms//cpu:x86_64\",\n        \"@build_bazel_apple_support//constraints:simulator\",\n    ],\n)\n\nplatform(\n    name = \"ios_sim_arm64\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n        \"@platforms//cpu:arm64\",\n        \"@build_bazel_apple_support//constraints:simulator\",\n    ],\n)\n"
  },
  {
    "path": "bzl/platforms/MODULE.bazel",
    "content": "module(name = \"snap_platforms\")\n\nbazel_dep(name = \"bazel_skylib\", version = \"1.2.0\")\nbazel_dep(name = \"platforms\", version = \"0.0.11\")"
  },
  {
    "path": "bzl/platforms/WORKSPACE",
    "content": ""
  },
  {
    "path": "bzl/platforms/conditions/BUILD.bazel",
    "content": "config_setting(\n    name = \"client_repo_arm64\",\n    define_values = {\n        \"client_repo_arm64\": \"true\",\n    },\n)\n\nconfig_setting(\n    name = \"client_repo_arm32\",\n    define_values = {\n        \"client_repo_arm32\": \"true\",\n    },\n)\n\nconfig_setting(\n    name = \"client_repo_x86_64\",\n    define_values = {\n        \"client_repo_x86_64\": \"true\",\n    },\n)\n\nconfig_setting(\n    name = \"android_arm32\",\n    constraint_values = [\n        \"@platforms//cpu:armv7\",\n        \"@platforms//os:android\",\n    ],\n)\n\nconfig_setting(\n    name = \"android_arm64\",\n    constraint_values = [\n        \"@platforms//cpu:aarch64\",\n        \"@platforms//os:android\",\n    ],\n)\n\nconfig_setting(\n    name = \"android\",\n    constraint_values = [\n        \"@platforms//os:android\",\n    ],\n)\n\nconfig_setting(\n    name = \"ios\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n    ],\n)\n\nconfig_setting(\n    name = \"linux\",\n    constraint_values = [\n        \"@platforms//os:linux\",\n    ],\n)\n\nconfig_setting(\n    name = \"macos\",\n    constraint_values = [\n        \"@platforms//os:macos\",\n    ],\n)\n\nconfig_setting(\n    name = \"arm\",\n    constraint_values = [\n        \"@platforms//cpu:armv7\",\n    ],\n)\n\nconfig_setting(\n    name = \"arm64\",\n    constraint_values = [\n        \"@platforms//cpu:aarch64\",\n    ],\n)\n\nconfig_setting(\n    name = \"x86\",\n    constraint_values = [\n        \"@platforms//cpu:x86_32\",\n    ],\n)\n\nconfig_setting(\n    name = \"x64\",\n    constraint_values = [\n        \"@platforms//cpu:x86_64\",\n    ],\n)\n"
  },
  {
    "path": "bzl/platforms/flavors/BUILD.bazel",
    "content": "# Borrowed from downstream\n\nload(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@bazel_skylib//rules:common_settings.bzl\", \"string_flag\")\n\nUNDEFINED_SNAP_FLAVOR = \"undefined\"\n\nFLAVORS = [\n    \"client_development\",\n    \"platform_development\",\n    \"platform_address_sanitizer\",\n    \"master\",\n    \"gold\",\n    \"alpha\",\n    \"production\",\n    \"diagnostic_production\",\n    \"sanitizer\",\n    \"sanitizer_debug\",\n    \"coverage\",\n    \"code_coverage\",\n    \"addlive_streamer\",\n    \"addlive_streamer_asserts\",\n    \"production_snapos\",\n    \"development_native_snapos\",\n    \"production_native_snapos\",\n]\n\nstring_flag(\n    name = \"snap_flavor\",\n    build_setting_default = UNDEFINED_SNAP_FLAVOR,\n    values = FLAVORS + [UNDEFINED_SNAP_FLAVOR],\n    visibility = [\"//visibility:public\"],\n)\n\n[config_setting(\n    name = flavor + \"_flag\",\n    flag_values = {\n        \":snap_flavor\": flavor,\n    },\n    visibility = [\"//visibility:public\"],\n) for flavor in FLAVORS]\n\n[config_setting(\n    name = flavor + \"_define\",\n    define_values = {\n        \"snap_flavor\": flavor,\n    },\n    visibility = [\"//visibility:public\"],\n) for flavor in FLAVORS]\n\n[selects.config_setting_group(\n    flavor,\n    match_any = [\n        flavor + \"_define\",\n        flavor + \"_flag\",\n    ],\n    visibility = [\"//visibility:public\"],\n) for flavor in FLAVORS]\n\nselects.config_setting_group(\n    name = \"test_setting\",\n    match_any = [\n        \":production\",\n        \":client_development\",\n    ],\n)\n"
  },
  {
    "path": "bzl/platforms/os/BUILD.bazel",
    "content": "package(default_visibility = [\"//visibility:public\"])\n\nplatform(\n    name = \"android_x86\",\n    constraint_values = [\n        \"@platforms//os:android\",\n        \"@platforms//cpu:x86_32\",\n    ],\n)\n\nplatform(\n    name = \"android_x86_64\",\n    constraint_values = [\n        \"@platforms//os:android\",\n        \"@platforms//cpu:x86_64\",\n    ],\n)\n\nplatform(\n    name = \"android_arm32\",\n    constraint_values = [\n        \"@platforms//os:android\",\n        \"@platforms//cpu:armv7\",\n    ],\n)\n\nplatform(\n    name = \"android_arm64\",\n    constraint_values = [\n        \"@platforms//os:android\",\n        \"@platforms//cpu:aarch64\",\n    ],\n)\n\nalias(\n    name = \"arm64-v8a\",\n    actual = \":android_arm64\",\n)\n\nplatform(\n    name = \"ios_arm64\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n        \"@platforms//cpu:aarch64\",\n    ],\n)\n\nplatform(\n    name = \"ios_x64\",\n    constraint_values = [\n        \"@platforms//os:ios\",\n        \"@platforms//cpu:x86_64\",\n    ],\n)\n\nplatform(\n    name = \"linux_x86_64\",\n    constraint_values = [\n        \"@platforms//os:linux\",\n        \"@platforms//cpu:x86_64\",\n    ],\n)\n\nplatform(\n    name = \"linux_arm64\",\n    constraint_values = [\n        \"@platforms//os:linux\",\n        \"@platforms//cpu:aarch64\",\n    ],\n)\n\nplatform(\n    name = \"macos_x86_64\",\n    constraint_values = [\n        \"@platforms//os:macos\",\n        \"@platforms//cpu:x86_64\",\n    ],\n)\n\nplatform(\n    name = \"macos_arm64\",\n    constraint_values = [\n        \"@platforms//os:macos\",\n        \"@platforms//cpu:arm64\",\n    ],\n)\n\nalias(\n    name = \"linux_x64\",\n    actual = \":linux_x86_64\",\n)\n\nalias(\n    name = \"macos_x64\",\n    actual = \":macos_x86_64\",\n)\n\nalias(\n    name = \"android_x64\",\n    actual = \":android_x86_64\",\n)\n"
  },
  {
    "path": "bzl/platforms/toggles/BUILD.bazel",
    "content": "config_setting(\n    name = \"ztrace_bare_enabled\",\n    define_values = {\n        \"enable_ztrace\": \"true\",\n    },\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "bzl/prebuilt_tools.bzl",
    "content": "# Shim to use different dependencies for open source and internal valdi\n\nINTERNAL_BUILD = False\n\ndef pngquant_linux():\n    if INTERNAL_BUILD:\n        return \"@valdi_pngquant_linux//:pngquant\"\n    return \"pngquant/linux/pngquant\"\n\ndef pngquant_macos():\n    if INTERNAL_BUILD:\n        return \"@valdi_pngquant_macos//:pngquant\"\n    return \"pngquant/macos/pngquant\"\n\ndef valdi_compiler_companion_files():\n    if INTERNAL_BUILD:\n        return [\"@valdi_compiler_companion//:all_files\"]\n    return native.glob([\n        \"compiler_companion/**/*.js\",\n        \"compiler_companion/**/*.js.map\",\n        \"compiler_companion/**/*.node\",\n    ])\n\ndef bundle_js():\n    if INTERNAL_BUILD:\n        return \"@valdi_compiler_companion//:bundle.js\"\n    return \"//compiler_companion:bundle.js\"\n\ndef jscore_library():\n    if INTERNAL_BUILD:\n        return \"@jscore_libs//:linux/x86_64/libjsc.so\"\n    return \"libs/linux/x86_64/libjsc.so\"\n"
  },
  {
    "path": "bzl/runtime_flags/BUILD.bazel",
    "content": "load(\"@bazel_skylib//rules:common_settings.bzl\", \"bool_flag\")\n\nbool_flag(\n    name = \"enable_asserts\",\n    build_setting_default = False,\n    visibility = [\"//visibility:public\"],\n)\n\nbool_flag(\n    name = \"enable_logging\",\n    build_setting_default = False,\n    visibility = [\"//visibility:public\"],\n)\n\nbool_flag(\n    name = \"enable_tracing\",\n    build_setting_default = False,\n    visibility = [\"//visibility:public\"],\n)\n\nbool_flag(\n    name = \"enable_debug\",\n    build_setting_default = False,\n    visibility = [\"//visibility:public\"],\n)\n\nbool_flag(\n    name = \"disable_rtti\",\n    build_setting_default = False,\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "bzl/toolchains/BUILD.bazel",
    "content": "load(\"@rules_kotlin//kotlin:kotlin.bzl\", \"define_kt_toolchain\")\n\nKOTLIN_LANGUAGE_LEVEL = \"1.8\"\n\ndefine_kt_toolchain(\n    name = \"kotlin_toolchain\",\n    api_version = KOTLIN_LANGUAGE_LEVEL,\n    jvm_target = \"1.8\",\n    language_version = KOTLIN_LANGUAGE_LEVEL,\n)\n\nconfig_setting(\n    name = \"sc_build_flag_assert\",\n    flag_values = {\n        \"@valdi//bzl/runtime_flags:enable_asserts\": \"true\",\n    },\n)\n\nconfig_setting(\n    name = \"sc_build_flag_logging\",\n    flag_values = {\n        \"@valdi//bzl/runtime_flags:enable_logging\": \"true\",\n    },\n)\n\nconfig_setting(\n    name = \"sc_build_flag_tracing\",\n    flag_values = {\n        \"@valdi//bzl/runtime_flags:enable_tracing\": \"true\",\n    },\n)\n\nconfig_setting(\n    name = \"sc_build_flag_debug\",\n    flag_values = {\n        \"@valdi//bzl/runtime_flags:enable_debug\": \"true\",\n    },\n)\n\nconfig_setting(\n    name = \"sc_build_flag_libcxx_rtti_disabled\",\n    flag_values = {\n        \"@valdi//bzl/runtime_flags:disable_rtti\": \"true\",\n    },\n)\n\nalias(\n    name = \"llvm_ndk_28_0_13004108_strip\",\n    actual = \"@androidndk//:strip\",\n    visibility = [\"//visibility:public\"],\n)\n\nalias(\n    name = \"llvm_ndk_28_0_13004108_strip_libs\",\n    actual = \"@androidndk//:strip_libs\",\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "bzl/toolchains/MODULE.bazel",
    "content": "module(name = \"snap_client_toolchains\")\n\nbazel_dep(name = \"valdi\")\nbazel_dep(name = \"bazel_skylib\", version = \"1.2.0\")\nbazel_dep(name = \"rules_kotlin\", version = \"1.9.0\", repo_name = \"rules_kotlin\")\n\nbazel_dep(name = \"rules_android_ndk\", version = \"0.1.3\")\n\nandroid_ndk_repository_extension = use_extension(\"@rules_android_ndk//:extension.bzl\", \"android_ndk_repository_extension\")\nuse_repo(android_ndk_repository_extension, \"androidndk\")"
  },
  {
    "path": "bzl/toolchains/WORKSPACE",
    "content": "workspace(name = \"snap_client_toolchains\")\n\nprint(\"Hello our workspace!\")\n"
  },
  {
    "path": "bzl/valdi/AndroidManifest.xml.tpl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"{PACKAGE}\">\n    <uses-sdk android:minSdkVersion=\"19\" />\n</manifest>\n"
  },
  {
    "path": "bzl/valdi/BUILD.bazel",
    "content": "load(\"@bazel_skylib//rules:common_settings.bzl\", \"bool_flag\", \"string_flag\")\nload(\"@valdi//bzl/conditions:selects.bzl\", \"selects\")\nload(\"@valdi//bzl/valdi:valdi_toolchain.bzl\", \"valdi_toolchain\")\n\nexports_files([\n    \"AndroidManifest.xml.tpl\",\n    \"valdi_config.yaml.tpl\",\n    \"empty.c\",\n    \"empty.swift\",\n    \"empty.kt\",\n    \"empty.js\",\n    \"Empty.bundle/Info.plist\",\n    \"Info.plist\",\n    \"package.json.tmpl\",\n    \"tsconfig.json\",\n])\n\n# No-op fallback for extract_valdi_module_output when no empty fallback is needed.\n# Must be public: any package that uses extract_valdi_module_output (e.g. valdi_module in jasmine, apps, etc.) depends on this default when not passing empty_bundle_fallback.\nfilegroup(\n    name = \"empty_bundle_fallback_none\",\n    srcs = [],\n    visibility = [\"//visibility:public\"],\n)\n\n# Placeholder so resource_bundle extract targets never produce zero files (apple_bundle_import requires path containing \".bundle\").\n# Must be public: valdi_module.bzl references this from arbitrary packages when has_resource_bundle is True.\nfilegroup(\n    name = \"empty_bundle\",\n    srcs = [\"Empty.bundle/Info.plist\"],\n    visibility = [\"//visibility:public\"],\n)\n\n# Flag to control the valdi compilation log level\nstring_flag(\n    name = \"compilation_log_level\",\n    build_setting_default = \"error\",\n    values = [\n        \"verbose\",\n        \"debug\",\n        \"info\",\n        \"warn\",\n        \"error\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nstring_flag(\n    name = \"assets_mode\",\n    build_setting_default = \"bundle\",\n    values = [\n        # Assets are uploaded remotely, unless the\n        # module configuration itself opts out.\n        \"upload\",\n        # Assets are always bundled within the app\n        \"bundle\",\n        # Assets are omitted from the build\n        \"strip\",\n        # Assets are bundled inline within the .valdimodule\n        \"inline\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nstring_flag(\n    name = \"localization_mode\",\n    build_setting_default = \"inline\",\n    values = [\n        # Localized strings are exported into a platform native format,\n        # using Localizable.strings files on iOS and strings.xml files\n        # on Android.\n        \"external\",\n        # Localized strings are bundled inline within the .valdimodule .\n        \"inline\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nstring_flag(\n    name = \"js_bytecode_format\",\n    build_setting_default = \"quickjs\",\n    values = [\n        \"none\",\n        \"hermes\",\n        \"quickjs\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"js_bytecode_format_none\",\n    flag_values = {\n        \":js_bytecode_format\": \"none\",\n    },\n)\n\nconfig_setting(\n    name = \"js_bytecode_format_hermes\",\n    flag_values = {\n        \":js_bytecode_format\": \"hermes\",\n    },\n)\n\nconfig_setting(\n    name = \"js_bytecode_format_quickjs\",\n    flag_values = {\n        \":js_bytecode_format\": \"quickjs\",\n    },\n)\n\nconfig_setting(\n    name = \"upload_assets\",\n    flag_values = {\n        \":assets_mode\": \"upload\",\n    },\n)\n\nconfig_setting(\n    name = \"bundle_assets\",\n    flag_values = {\n        \":assets_mode\": \"bundle\",\n    },\n)\n\nconfig_setting(\n    name = \"strip_assets\",\n    flag_values = {\n        \":assets_mode\": \"strip\",\n    },\n)\n\nconfig_setting(\n    name = \"inline_assets\",\n    flag_values = {\n        \":assets_mode\": \"inline\",\n    },\n)\n\nstring_flag(\n    name = \"js_engine\",\n    build_setting_default = \"auto\",\n    values = [\n        \"auto\",\n        \"hermes\",\n        \"quickjs\",\n        \"jscore\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"js_engine_auto\",\n    flag_values = {\n        \":js_engine\": \"auto\",\n    },\n)\n\nconfig_setting(\n    name = \"js_engine_hermes\",\n    flag_values = {\n        \":js_engine\": \"hermes\",\n    },\n)\n\nconfig_setting(\n    name = \"js_engine_quickjs\",\n    flag_values = {\n        \":js_engine\": \"quickjs\",\n    },\n)\n\nconfig_setting(\n    name = \"js_engine_jscore\",\n    flag_values = {\n        \":js_engine\": \"jscore\",\n    },\n)\n\nbool_flag(\n    name = \"hot_reload_enabled\",\n    build_setting_default = False,\n)\n\nconfig_setting(\n    name = \"valdi_hot_reload_enabled\",\n    flag_values = {\n        \":hot_reload_enabled\": \"true\",\n    },\n)\n\nbool_flag(\n    name = \"code_coverage_enabled\",\n    build_setting_default = False,\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"valdi_code_coverage_enabled\",\n    flag_values = {\n        \":code_coverage_enabled\": \"true\",\n    },\n)\n\n# Create an exhaustive set of configurations because Bazel doesn't support nested selects.\n# Not having nested selects means we have to list all possible conditions in a single flat select.\n# User by valdi_module.bzl to conditionally include apple_resource_bundles in the Valdi objc library.\n\nselects.config_setting_group(\n    name = \"debug\",\n    match_any = [\n        \"//bzl/valdi/source_set:debug\",\n        \"//bzl/valdi/source_set:infer_debug\",\n    ],\n)\n\nselects.config_setting_group(\n    name = \"release\",\n    match_any = [\n        \"//bzl/valdi/source_set:release\",\n        \"//bzl/valdi/source_set:infer_release\",\n    ],\n)\n\nselects.config_setting_combinations(\n    settings = [\n        {\n            \":debug\": \"debug\",\n            \":release\": \"release\",\n        },\n        {\n            \":upload_assets\": \"upload_assets\",\n            \":bundle_assets\": \"bundle_assets\",\n            \":strip_assets\": \"strip_assets\",\n        },\n    ],\n)\n\n# Toolchain for compiling Bazel modules.\ntoolchain_type(name = \"toolchain_type\")\n\n# Flag to control whether to use prebuilt companion binary or build from source\nbool_flag(\n    name = \"use_prebuilt_companion\",\n    build_setting_default = False,\n)\n\nconfig_setting(\n    name = \"use_prebuilt_companion_enabled\",\n    flag_values = {\n        \":use_prebuilt_companion\": \"true\",\n    },\n)\n\n# Flag to use a locally built compiler binary instead of the prebuilt from the toolchain.\n# Build the compiler with: compiler/compiler/scripts/update_compiler.sh -o compiler/compiler/out\n# Then build with: --//bzl/valdi:use_local_compiler=true\nbool_flag(\n    name = \"use_local_compiler\",\n    build_setting_default = False,\n    visibility = [\"//visibility:public\"],\n)\n\nconfig_setting(\n    name = \"use_local_compiler_enabled\",\n    flag_values = {\n        \":use_local_compiler\": \"true\",\n    },\n)\n\n# Alias to choose between prebuilt binary and source-built companion\nalias(\n    name = \"compiler_companion_source\",\n    actual = select({\n        \":use_prebuilt_companion_enabled\": \"@valdi_toolchain//:valdi_compiler_companion\",\n        \"//conditions:default\": \"//compiler/companion:ts_bin_wrapper\",\n    }),\n    visibility = [\"//visibility:public\"],\n)\n\n# Compiler: prebuilt from toolchain or local binary (see use_local_compiler)\nalias(\n    name = \"compiler_source\",\n    actual = select({\n        \":use_local_compiler_enabled\": \"//compiler/compiler:local_valdi_compiler\",\n        \"//conditions:default\": \"@valdi_toolchain//:valdi_compiler\",\n    }),\n    visibility = [\"//visibility:private\"],\n)\n\n# Platform-specific rule definition, for macos\nvaldi_toolchain(\n    name = \"valdi\",\n    compiler = \":compiler_source\",\n    compiler_companion = \":compiler_companion_source\",\n    compiler_toolbox = \"@valdi_toolchain//:valdi_compiler_toolbox\",\n    pngquant = \"@valdi_toolchain//:pngquant\",\n    sqldelight_compiler = \"@valdi_toolchain//:sqldelight_compiler\",\n)\n\ntoolchain(\n    name = \"valdi_toolchain\",\n    toolchain = \":valdi\",\n    toolchain_type = \":toolchain_type\",\n)\n"
  },
  {
    "path": "bzl/valdi/Empty.bundle/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\"><dict/></plist>\n"
  },
  {
    "path": "bzl/valdi/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "bzl/valdi/app_templates/AndroidDebugAppManifest.xml.tpl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"@VALDI_APP_PACKAGE@\"\n>\n    <uses-sdk\n        android:minSdkVersion=\"19\"\n        android:targetSdkVersion=\"34\"\n    />\n\n    <application\n        android:allowBackup=\"true\"\n        android:label=\"@VALDI_APP_NAME@\"\n        android:supportsRtl=\"true\"\n        android:debuggable=\"true\"\n        android:theme=\"@style/Theme.AppCompat.Light.NoActionBar\"\n        @VALDI_APPLICATION_ATTRIBUTES@\n    >\n        <profileable android:shell=\"true\" />\n\n        <activity\n            android:name=\"@VALDI_APP_PACKAGE@.StartActivity\"\n            android:screenOrientation=\"portrait\"\n            android:exported=\"true\"\n            @VALDI_ACTIVITY_ATTRIBUTES@\n        >\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n    <uses-permission android:name=\"android.permission.CHANGE_WIFI_MULTICAST_STATE\" />\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.VIBRATE\" />\n</manifest>\n"
  },
  {
    "path": "bzl/valdi/app_templates/AndroidLibManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\" package=\"com.snap.valdi.lib\">\n    <uses-sdk android:minSdkVersion=\"19\" android:targetSdkVersion=\"34\"/>\n</manifest>\n"
  },
  {
    "path": "bzl/valdi/app_templates/AndroidReleaseAppManifest.xml.tpl",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    package=\"@VALDI_APP_PACKAGE@\"\n>\n    <uses-sdk\n        android:minSdkVersion=\"19\"\n        android:targetSdkVersion=\"34\"\n    />\n\n    <application\n        android:allowBackup=\"true\"\n        android:label=\"@VALDI_APP_NAME@\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.AppCompat.Light.NoActionBar\"\n        @VALDI_APPLICATION_ATTRIBUTES@\n    >\n        <activity\n            android:name=\"@VALDI_APP_PACKAGE@.StartActivity\"\n            android:screenOrientation=\"portrait\"\n            android:exported=\"true\"\n            @VALDI_ACTIVITY_ATTRIBUTES@\n        >\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n    <uses-permission android:name=\"android.permission.CHANGE_WIFI_MULTICAST_STATE\" />\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.VIBRATE\" />\n</manifest>\n"
  },
  {
    "path": "bzl/valdi/app_templates/BUILD.bazel",
    "content": "exports_files([\n    \"Info.plist.tpl\",\n    \"ios_main.m.tpl\",\n    \"macos_main.m.tpl\",\n    \"AndroidDebugAppManifest.xml.tpl\",\n    \"AndroidReleaseAppManifest.xml.tpl\",\n    \"AndroidLibManifest.xml\",\n    \"StartActivity.kt.tpl\",\n    \"cli_main.cpp.tpl\",\n])\n"
  },
  {
    "path": "bzl/valdi/app_templates/Info.plist.tpl",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSAllowsLocalNetworking</key>\n\t\t<true/>\n\t</dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>@VALDI_BUNDLE_IDENTIFIER@</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>arm64</string>\n\t</array>\n\t<key>UIRequiresFullScreen</key>\n\t<false/>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "bzl/valdi/app_templates/StartActivity.kt.tpl",
    "content": "package @VALDI_APP_PACKAGE@\n\nimport com.snap.valdi.support.AppBootstrapper\nimport com.snap.valdi.support.AppBootstrapActivity\n\nimport com.snap.valdi.views.ValdiRootView\n\nclass StartActivity : AppBootstrapActivity() {\n    override fun createRootView(bootstrapper: AppBootstrapper): ValdiRootView {\n        return bootstrapper.setComponentPath(\"@VALDI_ROOT_COMPONENT_PATH@\").createRootView()\n    }\n}\n"
  },
  {
    "path": "bzl/valdi/app_templates/cli_main.cpp.tpl",
    "content": "#include \"valdi/cli_runner/CLIRunner.hpp\"\n\nint main(int argc, const char** argv) {\n    return Valdi::valdiCLIRun(\"@VALDI_SCRIPT_PATH@\", argc, argv);\n}\n"
  },
  {
    "path": "bzl/valdi/app_templates/ios_main.m.tpl",
    "content": "#import \"valdi/ios/Bootstrap/SCValdiAppMain.h\"\n\nint main(int argc, char *argv[])\n{\n    @autoreleasepool {\n        return SCValdiAppMain(argc, argv, @\"@VALDI_ROOT_COMPONENT_PATH@\");\n    }\n}\n"
  },
  {
    "path": "bzl/valdi/app_templates/macos_main.m.tpl",
    "content": "#import \"valdi/macos/Bootstrap/SCValdiAppMain.h\"\n\nint main(int argc, const char * argv[]) {\n    @autoreleasepool {\n        SCValdiAppMain(argc,\n                       argv,\n                       @\"@VALDI_ROOT_COMPONENT_PATH@\",\n                       @\"@VALDI_TITLE@\",\n                       @VALDI_WINDOW_WIDTH@,\n                       @VALDI_WINDOW_HEIGHT@,\n                       @VALDI_WINDOW_RESIZABLE@\n                    );\n    }\n    return 0;\n}"
  },
  {
    "path": "bzl/valdi/common.bzl",
    "content": "load(\"@bazel_skylib//lib:paths.bzl\", \"paths\")\n\n# These paths let us find/declare the expected output locations\n\n_ANDROID_OUTPUT_BASE = \"android\"\n_ANDROID_DEBUG_ONLY_BASE = paths.join(_ANDROID_OUTPUT_BASE, \"debug\")\n_ANDROID_RELEASE_READY_BASE = paths.join(_ANDROID_OUTPUT_BASE, \"release\")\n_ANDROID_METADATA_BASE = _ANDROID_OUTPUT_BASE  # metadata is written to the base directory for Android\n\n_ANDROID_OUTPUT_STRINGS_BASE_DIR = paths.join(_ANDROID_OUTPUT_BASE, \"strings\")\n\n_IOS_OUTPUT_BASE = \"ios\"\n_IOS_DEBUG_ONLY_BASE = paths.join(_IOS_OUTPUT_BASE, \"debug\")\n_IOS_RELEASE_READY_BASE = paths.join(_IOS_OUTPUT_BASE, \"release\")\n_IOS_METADATA_BASE = paths.join(_IOS_OUTPUT_BASE, \"metadata\")\n\n_IOS_OUTPUT_STRINGS_BASE_DIR = paths.join(_IOS_OUTPUT_BASE, \"strings\")\n\n_IOS_API_NAME_SUFFIX = \"Types\"\n\n_IOS_SWIFT_SUFFIX = \"Swift\"\n\n_WEB_OUTPUT_BASE = \"web\"\n_WEB_DEBUG_ONLY_BASE = paths.join(_WEB_OUTPUT_BASE, \"debug\")\n_WEB_RELEASE_READY_BASE = paths.join(_WEB_OUTPUT_BASE, \"release\")\n\n_CPP_OUTPUT_BASE = \"cpp\"\n_CPP_DEBUG_ONLY_BASE = paths.join(_CPP_OUTPUT_BASE, \"debug\")\n_CPP_RELEASE_READY_BASE = paths.join(_CPP_OUTPUT_BASE, \"release\")\n_CPP_METADATA_BASE = _CPP_OUTPUT_BASE  # metadata is written to the base directory for C++\n\n# NOTE(vfomin): this should probably go into the config file\n_IOS_DEFAULT_MODULE_PREFIX = \"SCC\"\n\n_NODE_MODULES_BASE = \"src/valdi_modules/node_modules\"\n\n################\n##\n## Exported symbols\n##\n################\n\nIOS_OUTPUT_BASE = _IOS_OUTPUT_BASE\nANDROID_OUTPUT_STRINGS_BASE_DIR = _ANDROID_OUTPUT_STRINGS_BASE_DIR\nIOS_OUTPUT_STRINGS_BASE_DIR = _IOS_OUTPUT_STRINGS_BASE_DIR\n\nIOS_API_NAME_SUFFIX = _IOS_API_NAME_SUFFIX\nIOS_SWIFT_SUFFIX = _IOS_SWIFT_SUFFIX\nIOS_DEFAULT_MODULE_NAME_PREFIX = _IOS_DEFAULT_MODULE_PREFIX\n\nNODE_MODULES_BASE = _NODE_MODULES_BASE\n\n# Contains all supported variant directories\n# Reference ImageResolver for the correct list - https://github.com/Snapchat/Valdi/blob/main/compiler/compiler/Compiler/Sources/Images/ImageVariantResolver.swift\nANDROID_RESOURCE_VARIANT_DIRECTORIES = [\n    \"drawable-mdpi\",\n    \"drawable-hdpi\",\n    \"drawable-xhdpi\",\n    \"drawable-xxhdpi\",\n    \"drawable-xxxhdpi\",\n]\n\nBUILD_DIR = \".valdi_build/compile\"\nTYPESCRIPT_OUTPUT_DIR = paths.join(BUILD_DIR, \"typescript/output\")\nTYPESCRIPT_GENERATED_TS_DIR = paths.join(BUILD_DIR, \"generated_ts\")\nTYPESCRIPT_DUMPED_SYMBOLS_DIR = paths.join(BUILD_DIR, \"typescript/dumped_symbols\")\n\ndef base_relative_dir(platform, output_target, relative_dir):\n    \"\"\"Helper function for constructing paths relative to the _BASE_DIR.\n\n    Args:\n        platform: The platform (android, ios, web, or cpp).\n        output_target: The output target (debug or release).\n        relative_dir: The relative directory.\n\n    Returns:\n        The constructed path relative to the _BASE_DIR.\n    \"\"\"\n    if platform not in [\"android\", \"ios\", \"web\", \"cpp\"]:\n        fail(\"Unexpected platform: {platform}\".format(platform = platform))\n\n    if output_target not in [\"debug\", \"release\", \"metadata\"]:\n        fail(\"Unexpected output_target: {output_target}\".format(output_target = output_target))\n\n    if output_target == \"debug\":\n        base = _IOS_DEBUG_ONLY_BASE\n        if platform == \"android\":\n            base = _ANDROID_DEBUG_ONLY_BASE\n        elif platform == \"web\":\n            base = _WEB_DEBUG_ONLY_BASE\n        elif platform == \"cpp\":\n            base = _CPP_DEBUG_ONLY_BASE\n    elif output_target == \"release\":\n        base = _IOS_RELEASE_READY_BASE\n        if platform == \"android\":\n            base = _ANDROID_RELEASE_READY_BASE\n        elif platform == \"web\":\n            base = _WEB_RELEASE_READY_BASE\n        elif platform == \"cpp\":\n            base = _CPP_RELEASE_READY_BASE\n    elif platform == \"android\":\n        base = _ANDROID_METADATA_BASE\n    elif platform == \"cpp\":\n        base = _CPP_METADATA_BASE\n    else:\n        base = _IOS_METADATA_BASE\n    return paths.join(base, relative_dir)\n"
  },
  {
    "path": "bzl/valdi/empty.c",
    "content": "// This is an empty source file passed to cc_library/objc_library valdi targets\n// to make the build system happy when the target doesn't define its own sources\n// or generates sources that are not known to the build system ahead of time.\n"
  },
  {
    "path": "bzl/valdi/empty.js",
    "content": "// This exists for packaging purposes"
  },
  {
    "path": "bzl/valdi/empty.kt",
    "content": ""
  },
  {
    "path": "bzl/valdi/empty.swift",
    "content": "// Placeholder for Valdi modules with no Swift output (ios_language = \"objc\").\n// Required so swift_library always has non-empty srcs.\n"
  },
  {
    "path": "bzl/valdi/extract_cpp_srcs.bzl",
    "content": "\"\"\" Helper rule to extract C++ generated sources from valdi_compiled targets. \"\"\"\n\nload(\":valdi_compiled.bzl\", \"ValdiModuleInfo\")\nload(\":valdi_extract_output_rule_helper.bzl\", \"extract_valdi_output_rule\")\n\n# Extracts the generated C++ sources directory tree artifact from the compiled_module target's providers and\n# filters by extension (.cpp or .hpp), exposing the filtered files via the DefaultInfo provider.\n#\n# This is needed because when single_file_codegen is disabled, the compiler generates multiple files\n# in the same directory, and we need to separate .cpp files (for srcs) from .hpp files (for hdrs).\n#\n# C++ codegen always outputs to release configuration.\ndef _extract_cpp_srcs_impl(ctx):\n    module = ctx.attr.compiled_module[ValdiModuleInfo]\n\n    # C++ codegen always outputs to release configuration\n    cpp_srcs = module.cpp_srcs\n\n    output = ctx.actions.declare_directory(ctx.attr.name)\n\n    # Build the strip prefix pattern for shell (add trailing slash if non-empty)\n    strip_prefix = ctx.attr.strip_prefix\n    if strip_prefix and not strip_prefix.endswith(\"/\"):\n        strip_prefix = strip_prefix + \"/\"\n\n    # For .cpp files, generate a dummy file if no sources are found\n    # This prevents cc_library from failing when there are no C++ sources\n    #\n    # Note: We use -L with find to follow symlinks, as tree artifacts may contain symlinks\n    # to files in other configurations, and -L with cp to dereference when copying.\n    if ctx.attr.extension == \".cpp\":\n        command = \"\"\"\n        mkdir -p {output}\n        find -L {input}/ -type f -name \"*{extension}\" -print0 | while IFS= read -r -d '' file; do\n            rel=\"${{file#\"{input}/\"}}\"\n            stripped=\"${{rel#{strip_prefix}}}\"\n            dest_dir=\"{output}/$(dirname \"$stripped\")\"\n            mkdir -p \"$dest_dir\"\n            cp -L \"$file\" \"$dest_dir/\"\n        done\n        if [ -z \"$(find {output} -type f -name \"*{extension}\" -print -quit)\" ]; then\n            echo \"// Empty dummy C++ file generated because no sources were found\" > {output}/empty_dummy.cpp\n        fi\n        \"\"\".format(\n            input = cpp_srcs.path,\n            extension = ctx.attr.extension,\n            output = output.path,\n            strip_prefix = strip_prefix,\n        )\n    else:\n        command = \"\"\"\n        mkdir -p {output}\n        find -L {input}/ -type f -name \"*{extension}\" -print0 | while IFS= read -r -d '' file; do\n            rel=\"${{file#\"{input}/\"}}\"\n            stripped=\"${{rel#{strip_prefix}}}\"\n            dest_dir=\"{output}/$(dirname \"$stripped\")\"\n            mkdir -p \"$dest_dir\"\n            cp -L \"$file\" \"$dest_dir/\"\n        done\n        \"\"\".format(\n            input = cpp_srcs.path,\n            extension = ctx.attr.extension,\n            output = output.path,\n            strip_prefix = strip_prefix,\n        )\n\n    ctx.actions.run_shell(\n        inputs = [cpp_srcs],\n        outputs = [output],\n        command = command,\n        mnemonic = \"PrepValdiCppSrcs\",\n    )\n\n    return [\n        DefaultInfo(\n            files = depset(\n                [output],\n            ),\n        ),\n    ]\n\nextract_cpp_srcs = extract_valdi_output_rule(\n    implementation = _extract_cpp_srcs_impl,\n    attrs = {\n        \"extension\": attr.string(\n            mandatory = True,\n            values = [\".cpp\", \".hpp\"],\n        ),\n        \"strip_prefix\": attr.string(\n            default = \"\",\n            doc = \"Prefix to strip from file paths when extracting (e.g., 'cpp/release/src')\",\n        ),\n        \"_empty_source\": attr.label(\n            default = Label(\"//bzl/valdi:empty.c\"),\n            allow_single_file = True,\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/extract_objc_srcs.bzl",
    "content": "load(\":valdi_compiled.bzl\", \"ValdiModuleInfo\")\nload(\":valdi_extract_output_rule_helper.bzl\", \"extract_valdi_output_rule\")\n\n# Extracts the generated sources directory tree artifact from the compiled_module target's providers and\n# exposes it as using this target's `DefaultInfo` provider, so it can be consumed by the rule that generates\n# the kt_android_library/objc_library target.\n#\n# NOTE: we might not need this if we start using named outputs for the iOS side of things, just like we do on android.\n#       see comment inside valdi_compiled.bzl\ndef _extract_objc_srcs_impl(ctx):\n    module = ctx.attr.compiled_module[ValdiModuleInfo]\n    selected_source_set = ctx.attr.selected_source_set\n    api_objc_srcs = None\n    objc_srcs = None\n\n    if selected_source_set == \"debug\":\n        api_objc_srcs = module.ios_debug_api_generated_srcs\n        objc_srcs = module.ios_debug_generated_srcs\n    else:\n        api_objc_srcs = module.ios_release_api_generated_srcs\n        objc_srcs = module.ios_release_generated_srcs\n\n    # NOTE: Some modules will not have generated Obj-C/Kotlin sources, but the\n    #       Bazel rule has no way of knowing that ahead of time.\n    #       If we try to configure an objc_library target without sources that will fail\n    #       to build when using the objc_srcs.m hack (see below).\n    #\n    #       So, we add an empty .c implementation file just to make the build system happy.\n    #\n    #       We can make builds faster if the BUILD.bazel files specify some flags\n    #       for modules that are guaranteed not to generate native sources.\n    #       In those cases we could just not emit anything, including the objc_srcs.m hack\n    empty_source_files = [] if ctx.attr.extension == \".h\" else ctx.files._empty_source\n\n    if ctx.attr.api_only:\n        # objc_library rule expects the srcs to have certain extensions (.m, .h, etc.) So this hack add a .m extension\n        # to the directory that contains the generated files to trigger processing all the files within that directory.\n        hack_ios_dir = _prep_hack_ios_dir(\n            ctx,\n            selected_source_set,\n            for_api = True,\n            api_objc_srcs = api_objc_srcs,\n            objc_srcs = objc_srcs,\n        )\n\n    else:\n        hack_ios_dir = _prep_hack_ios_dir(\n            ctx,\n            selected_source_set,\n            for_api = False,\n            api_objc_srcs = api_objc_srcs,\n            objc_srcs = objc_srcs,\n        )\n\n    return [\n        DefaultInfo(\n            files = depset(\n                [hack_ios_dir] + empty_source_files,\n            ),\n        ),\n    ]\n\ndef _prep_hack_ios_dir(ctx, selected_source_set, for_api, api_objc_srcs, objc_srcs):\n    if for_api:\n        input = api_objc_srcs\n        output = ctx.actions.declare_directory(\"{}_api_objc_srcs{}\".format(selected_source_set, ctx.attr.extension))\n    else:\n        input = objc_srcs\n        output = ctx.actions.declare_directory(\"{}_objc_srcs{}\".format(selected_source_set, ctx.attr.extension))\n\n    if input:\n        ctx.actions.run_shell(\n            inputs = [input],\n            outputs = [output],\n            command = \"\"\"\nmkdir -p {output}; find -L {input} -type f -name \"*{extension}\" -exec cp -a {{}} {output} \\\\;\n\"\"\".format(input = input.path, extension = ctx.attr.extension, output = output.path),\n            mnemonic = \"PrepValdiObjCSrcs\",\n        )\n    else:\n        # Generate empty directory if the module provides no sources\n        ctx.actions.run_shell(\n            inputs = [],\n            outputs = [output],\n            command = \"mkdir -p {out}\".format(\n                out = output.path,\n            ),\n            mnemonic = \"PrepValdiObjCDir\",\n        )\n    return output\n\nextract_objc_srcs = extract_valdi_output_rule(\n    implementation = _extract_objc_srcs_impl,\n    attrs = {\n        \"extension\": attr.string(\n            mandatory = True,\n            values = [\".m\", \".h\"],\n        ),\n        \"api_only\": attr.bool(\n            mandatory = True,\n        ),\n        \"selected_source_set\": attr.string(\n            mandatory = True,\n        ),\n        \"_empty_source\": attr.label(\n            default = Label(\"//bzl/valdi:empty.c\"),\n            allow_single_file = True,\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/extract_swift_srcs.bzl",
    "content": "load(\":valdi_compiled.bzl\", \"ValdiModuleInfo\")\nload(\":valdi_extract_output_rule_helper.bzl\", \"extract_valdi_output_rule\")\n\ndef _extract_swift_srcs_impl(ctx):\n    module = ctx.attr.compiled_module[ValdiModuleInfo]\n    module_name = module.name\n    selected_source_set = ctx.attr.selected_source_set\n    swift_srcs = []\n\n    if selected_source_set == \"debug\":\n        swift_srcs.extend([\n            module.ios_debug_generated_srcs,\n            module.ios_debug_api_generated_srcs,\n        ])\n    else:\n        swift_srcs.extend([\n            module.ios_release_generated_srcs,\n            module.ios_release_api_generated_srcs,\n        ])\n\n    if not swift_srcs:\n        return [DefaultInfo(files = depset([]))]\n\n    merged_swift_src = _merge_swift_srcs(\n        ctx,\n        module_name,\n        selected_source_set,\n        swift_srcs,\n    )\n\n    return [\n        DefaultInfo(files = depset([\n            merged_swift_src,\n        ])),\n    ]\n\ndef _swift_concat_command(output):\n    \"\"\" Generate a shell script to concatenate all .swift files in a directory.\n    \"\"\"\n    command = \"\"\"\ntext=\"//THIS IS AN AUTOGENERATED FILE. DO NOT EDIT\\n\\n\"\ndestination_filename=$(basename \"{output_file}\")\n\nfor source_dir in \"$@\"; do\n    for swift in `find $source_dir ! -name \"$destination_filename\" -name \"*.swift\"`; do\n        text=\"$text\\n// ----------------------------\";\n        text=\"$text\\n//\";\n        text=\"$text\\n// $(basename \"$swift\")\";\n        text=\"$text\\n//\";\n        text=\"$text\\n// ----------------------------\\n\\n\";\n        text=\"$text$(cat \"${{swift}}\";)\\n\\n\";\n    done;\ndone;\necho -e \"$text\" > \"{output_file}\"\n\"\"\".format(\n        output_file = output.path,\n    )\n\n    return command\n\ndef _merge_swift_srcs(ctx, module_name, selected_source_set, swift_srcs):\n    output = ctx.actions.declare_file(\"{}_{}_concat.swift\".format(module_name, selected_source_set))\n\n    # Pass them as arguments to the generated shell command\n    args = ctx.actions.args()\n    for swift_src in swift_srcs:\n        args.add(swift_src.path)  # Add each directory as an argument\n    ctx.actions.run_shell(\n        command = _swift_concat_command(output),\n        arguments = [args],\n        inputs = swift_srcs,\n        outputs = [output],\n        mnemonic = \"SwiftConcatGen\",\n        progress_message = \"Concatenating Swift files for module {}\".format(module_name),\n    )\n    return output\n\nextract_swift_srcs = extract_valdi_output_rule(\n    implementation = _extract_swift_srcs_impl,\n    attrs = {\n        \"selected_source_set\": attr.string(\n            mandatory = True,\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/generate_android_manifest.bzl",
    "content": "# Generates the AndroidManifest.xml for the Valdi module's kt_android_library target\ndef _generate_android_manifest_impl(ctx):\n    out = ctx.actions.declare_file(\"AndroidManifest.xml\")\n    ctx.actions.expand_template(\n        output = out,\n        template = ctx.file._manifest_template,\n        substitutions = {\n            \"{PACKAGE}\": ctx.attr.package,\n        },\n    )\n    return [DefaultInfo(files = depset([out]))]\n\ngenerate_android_manifest = rule(\n    implementation = _generate_android_manifest_impl,\n    attrs = {\n        \"_manifest_template\": attr.label(\n            allow_single_file = True,\n            default = \"AndroidManifest.xml.tpl\",\n        ),\n        \"package\": attr.string(),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/localizable_strings.bzl",
    "content": "json_supported_langs = [\n    \"strings-ar.json\",\n    \"strings-bn-BD.json\",\n    \"strings-bn-IN.json\",\n    \"strings-da-DK.json\",\n    \"strings-de-DE.json\",\n    \"strings-el-GR.json\",\n    \"strings-en-GB.json\",\n    \"strings-en.json\",\n    \"strings-es-AR.json\",\n    \"strings-es-ES.json\",\n    \"strings-es-MX.json\",\n    \"strings-es.json\",\n    \"strings-fi-FI.json\",\n    \"strings-fil-PH.json\",\n    \"strings-fr-FR.json\",\n    \"strings-gu-IN.json\",\n    \"strings-hi-IN.json\",\n    \"strings-id-ID.json\",\n    \"strings-it-IT.json\",\n    \"strings-ja-JP.json\",\n    \"strings-kn-IN.json\",\n    \"strings-ko-KR.json\",\n    \"strings-ml-IN.json\",\n    \"strings-mr-IN.json\",\n    \"strings-ms-MY.json\",\n    \"strings-nb-NO.json\",\n    \"strings-nl-NL.json\",\n    \"strings-pa.json\",\n    \"strings-pl-PL.json\",\n    \"strings-pt-BR.json\",\n    \"strings-pt-PT.json\",\n    \"strings-ro-RO.json\",\n    \"strings-ru-RU.json\",\n    \"strings-sv-SE.json\",\n    \"strings-ta-IN.json\",\n    \"strings-te-IN.json\",\n    \"strings-th-TH.json\",\n    \"strings-tr-TR.json\",\n    \"strings-ur-PK.json\",\n    \"strings-vi-VN.json\",\n    \"strings-zh-Hans.json\",\n    \"strings-zh-Hant.json\",\n]\n\nios_supported_langs = [\n    \"ar.lproj\",\n    \"bn-BD.lproj\",\n    \"bn-IN.lproj\",\n    \"da.lproj\",\n    \"de.lproj\",\n    \"el.lproj\",\n    \"en-GB.lproj\",\n    \"en.lproj\",\n    \"es-AR.lproj\",\n    \"es-ES.lproj\",\n    \"es-MX.lproj\",\n    \"es.lproj\",\n    \"fi.lproj\",\n    \"fil-PH.lproj\",\n    \"fr.lproj\",\n    \"gu-IN.lproj\",\n    \"hi-IN.lproj\",\n    \"id.lproj\",\n    \"it.lproj\",\n    \"ja.lproj\",\n    \"kn-IN.lproj\",\n    \"ko.lproj\",\n    \"ml-IN.lproj\",\n    \"mr-IN.lproj\",\n    \"ms-MY.lproj\",\n    \"nb.lproj\",\n    \"nl.lproj\",\n    \"pa-IN.lproj\",\n    \"pl.lproj\",\n    \"pt-PT.lproj\",\n    \"pt.lproj\",\n    \"ro.lproj\",\n    \"ru.lproj\",\n    \"sv.lproj\",\n    \"ta-IN.lproj\",\n    \"te-IN.lproj\",\n    \"th-TH.lproj\",\n    \"tr.lproj\",\n    \"ur-PK.lproj\",\n    \"vi-VN.lproj\",\n    \"zh-Hans.lproj\",\n    \"zh-Hant.lproj\",\n]\n\nandroid_supported_langs = [\n    \"values-ar\",\n    \"values-bn-rBD\",\n    \"values-bn-rIN\",\n    \"values-da\",\n    \"values-de\",\n    \"values-el\",\n    \"values-en-rGB\",\n    \"values\",\n    \"values-es\",\n    \"values-es-rAR\",\n    \"values-es-rES\",\n    \"values-es-rMX\",\n    \"values-fi\",\n    \"values-fil-rPH\",\n    \"values-fr\",\n    \"values-gu-rIN\",\n    \"values-hi-rIN\",\n    \"values-in\",\n    \"values-it\",\n    \"values-ja\",\n    \"values-kn-rIN\",\n    \"values-ko\",\n    \"values-ml-rIN\",\n    \"values-mr-rIN\",\n    \"values-ms-rMY\",\n    \"values-nb\",\n    \"values-nl\",\n    \"values-pa-rIN\",\n    \"values-pl\",\n    \"values-pt\",\n    \"values-pt-rPT\",\n    \"values-ro\",\n    \"values-ru\",\n    \"values-sv\",\n    \"values-ta-rIN\",\n    \"values-te-rIN\",\n    \"values-th-rTH\",\n    \"values-tr\",\n    \"values-ur-rPK\",\n    \"values-vi-rVN\",\n    \"values-zh\",\n    \"values-zh-rTW\",\n]\n\nsupported_langs_mapping = {json_supported_langs[i]: (ios_supported_langs[i], android_supported_langs[i]) for i in range(len(json_supported_langs))}\n"
  },
  {
    "path": "bzl/valdi/npm/BUILD.bazel",
    "content": "load(\"@valdi_npm//:defs.bzl\", \"npm_link_all_packages\")\n\nnpm_link_all_packages(name = \"node_modules\")\n"
  },
  {
    "path": "bzl/valdi/npm/README.md",
    "content": "# Valdi NPM Module Dependencies\n\nConfigures the `@valdi` workspace's npm dependency tree using `aspect_rules_js`. The dependencies store configuration in the `@valdi_npm` repository (see [`link_workspace`][link_workspace]).\n\n[link_workspace]: https://github.com/aspect-build/rules_js/blob/03bde54fd8e3de4c57e84247dffef9c450d956d5/docs/npm_translate_lock.md#npm_translate_lock-link_workspace\n\n## Updating Dependencies\n\nThe `rules_js` macros use the PNPM dependency resolution system to manage npm dependencies.\n\nEach package that needs its npm dependencies to be available in `bazel` will need to be listed in `pnpm-workspace.yaml`.\n\nIf the dependencies for one of those packages changes (e.g. `\"express\"` is added to `\"dependencies\":` in a `package.json`), the `pnpm-lock.yaml` file will need to be updated.\n\n```\nbzl run -- @pnpm//:pnpm --dir $PWD install --lockfile-only\n```\n\n## Using `@valdi` Bazel Workspace Dependencies\n\nIn order to use the `bazel` targets from `@valdi` from outside the `@valdi` workspace, it will be necessary to run the macros to set up the `npm` dependency configuration.\n\nIn another Bazel `WORKSPACE`:\n\n```python\n# Load the configuration macro from the @valdi workspace\nload(\"@valdi//bzl/valdi/npm:repositories.bzl\", \"valdi_repositories\")\n# Sets up the @valdi_npm dependencies in their own namespace\nvaldi_repositories()\n\n# Load npm_repositories macro for the @valdi_npm namespace\nload(\"@valdi_npm//:repositories.bzl\", valdi_npm_repositories = \"npm_repositories\")\n\n# Call the repository macro that sets up the npm dependency tree\nvaldi_npm_repositories()\n```"
  },
  {
    "path": "bzl/valdi/npm/package.json",
    "content": "{\n  \"name\": \"valdi\",\n  \"dependencies\": {\n    \"@protobuf-ts/runtime\": \"^2.11.1\",\n    \"@puppeteer/browsers\": \"^2.4.1\",\n    \"@types/jest\": \"^29.5.14\",\n    \"@types/node\": \"^20.14.10\",\n    \"jest\": \"^29.7.0\",\n    \"puppeteer\": \"^22.0.0\"\n  },\n  \"pnpm\": {\n    \"onlyBuiltDependencies\": [\n      \"better-sqlite3\",\n      \"bufferutil\",\n      \"es5-ext\",\n      \"fsevents\",\n      \"typemoq\",\n      \"utf-8-validate\"\n    ],\n    \"packageExtensions\": {\n      \"@babel/core\": {\n        \"peerDependencies\": {\n          \"@babel/preset-typescript\": \"*\"\n        }\n      },\n      \"gulp-typescript\": {\n        \"peerDependencies\": {\n          \"source-map\": \"*\",\n          \"@types/source-map\": \"*\"\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "bzl/valdi/npm/pnpm-workspace.yaml",
    "content": "packages:\n - .\n - ../../../compiler/companion\n - ../../../compiler/companion/remotedebug-ios-webkit-adapter\n - ../../../src/valdi_modules/src/valdi/valdi_protobuf\n"
  },
  {
    "path": "bzl/valdi/npm/repositories.bzl",
    "content": "\"Configure the npm dependencies used by valdi npm modules in the @valdi_npm repository\"\n\nload(\"@aspect_rules_js//npm:repositories.bzl\", _npm_translate_lock = \"npm_translate_lock\")\n\ndef valdi_repositories():\n    _npm_translate_lock(\n        name = \"valdi_npm\",\n        pnpm_lock = \"@valdi//bzl/valdi/npm:pnpm-lock.yaml\",\n        lifecycle_hooks = {\n            \"better-sqlite3@9.6.0\": [],\n            \"remotedebug-ios-webkit-adapter@0.4.2\": [],\n        },\n        link_workspace = \"valdi\",\n    )\n"
  },
  {
    "path": "bzl/valdi/package.json.tmpl",
    "content": "{\n  \"name\": \"${name}\",\n  \"version\": \"${version}\",\n  \"main\": \"index.js\",\n  \"type\": \"commonjs\",\n  \"dependencies\": {\n    \"@protobuf-ts/runtime\": \"^2.11.1\",\n    \"long\": \"4.0.0\",\n    \"path-browserify\": \"^1.0.1\"\n  },\n  \"imports\": {\n    \"#root/*\": \"./*\"\n  }\n}"
  },
  {
    "path": "bzl/valdi/rewrite_hdrs.bzl",
    "content": "def _rewrite_hdrs_impl(ctx):\n    \"\"\"\n    Rewrites headers into a given module name\n    \"\"\"\n    output_files = []\n    transformer_exe = ctx.executable._transformer\n\n    for header in ctx.files.srcs:\n        out = ctx.actions.declare_file(\"output/{}\".format(header.basename))\n\n        args = [\n            \"rewrite_header\",\n            \"-m\",\n            ctx.attr.module_name,\n            \"-i\",\n            header.path,\n            \"-o\",\n            out.path,\n        ]\n\n        if ctx.attr.flatten_paths:\n            args.append(\"-f\")\n\n        for preserved_module_name in ctx.attr.preserved_module_names:\n            args.append(\"-p\")\n            args.append(preserved_module_name)\n\n        ctx.actions.run(\n            inputs = [header, transformer_exe],\n            outputs = [out],\n            arguments = args,\n            progress_message = \"Transforming header: %s\" % header.path,\n            executable = transformer_exe,\n        )\n\n        output_files.append(out)\n\n    return [\n        DefaultInfo(\n            files = depset(output_files),\n        ),\n    ]\n\nrewrite_hdrs = rule(\n    implementation = _rewrite_hdrs_impl,\n    attrs = {\n        \"srcs\": attr.label_list(\n            cfg = \"exec\",\n        ),\n        \"module_name\": attr.string(),\n        \"preserved_module_names\": attr.string_list(),\n        \"flatten_paths\": attr.bool(),\n        \"_transformer\": attr.label(\n            executable = True,\n            cfg = \"exec\",\n            default = Label(\"@valdi_toolchain//:valdi_compiler_toolbox\"),\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/snap_macros/BUILD.bazel",
    "content": ""
  },
  {
    "path": "bzl/valdi/snap_macros/MODULE.bazel",
    "content": "module(name = \"snap_macros\")"
  },
  {
    "path": "bzl/valdi/snap_macros/WORKSPACE",
    "content": ""
  },
  {
    "path": "bzl/valdi/snap_macros/internal/sourcegen/valdi_context_factory.bzl",
    "content": "def valdi_context_factory_headers(context_name, public = True):\n    return None\n\ndef valdi_context_factory_impl(api_module_name, context_name, public = False):\n    return None\n"
  },
  {
    "path": "bzl/valdi/snap_macros/library/snap_client_ios_library.bzl",
    "content": "def snap_client_ios_library(\n        name,\n        hdrs,\n        srcs,\n        deps = [],\n        implementation_deps = [],\n        tags = [],\n        generated_objects = [],\n        **kwargs):\n    native.objc_library(\n        name = name,\n        deps = deps,\n        implementation_deps = implementation_deps,\n        srcs = srcs,\n        hdrs = hdrs,\n        tags = tags,\n        **kwargs\n    )\n"
  },
  {
    "path": "bzl/valdi/source_set/BUILD.bazel",
    "content": "load(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"//bzl/valdi/source_set:source_set.bzl\", \"source_set\")\n\npackage(default_visibility = [\"//visibility:public\"])\n\nsource_set(\n    name = \"source_set\",\n    build_setting_default = \"infer\",\n)\n\n# Build explicitly configured to use the debug source set\nconfig_setting(\n    name = \"debug\",\n    flag_values = {\":source_set\": \"debug\"},\n)\n\n# Build explicitly configured to use the release source set\nconfig_setting(\n    name = \"release\",\n    flag_values = {\":source_set\": \"release\"},\n)\n\nconfig_setting(\n    name = \"infer\",\n    flag_values = {\":source_set\": \"infer\"},\n)\n\n# Infer debug source set based on the debugish snap flavors\nselects.config_setting_group(\n    name = \"infer_debug\",\n    match_all = [\n        \":infer\",\n        \":snap_flavors_debugish\",\n    ],\n)\n\n# Infer release source set based on the releaseish snap flavors\nselects.config_setting_group(\n    name = \"infer_release\",\n    match_all = [\n        \":infer\",\n        \":snap_flavors_releaseish\",\n    ],\n)\n\nselects.config_setting_group(\n    name = \"snap_flavors_debugish\",\n    match_any = [\n        \"@snap_platforms//flavors:client_development\",\n        \"@snap_platforms//flavors:platform_development\",\n        \"@snap_platforms//flavors:platform_address_sanitizer\",\n        \"@snap_platforms//flavors:master\",\n        \"@snap_platforms//flavors:sanitizer\",\n        \"@snap_platforms//flavors:sanitizer_debug\",\n        \"@snap_platforms//flavors:development_native_snapos\",\n    ],\n)\n\nselects.config_setting_group(\n    name = \"snap_flavors_releaseish\",\n    match_any = [\n        \"@snap_platforms//flavors:alpha\",\n        \"@snap_platforms//flavors:gold\",\n        \"@snap_platforms//flavors:production\",\n        \"@snap_platforms//flavors:diagnostic_production\",\n        \"@snap_platforms//flavors:coverage\",\n        \"@snap_platforms//flavors:code_coverage\",\n        \"@snap_platforms//flavors:addlive_streamer\",\n        \"@snap_platforms//flavors:addlive_streamer_asserts\",\n        \"@snap_platforms//flavors:production_snapos\",\n        \"@snap_platforms//flavors:production_native_snapos\",\n    ],\n)\n"
  },
  {
    "path": "bzl/valdi/source_set/source_set.bzl",
    "content": "# Boy, Bazel's way of defining custom bzl build flags is verbose...\nValdiModulesSourceSetProvider = provider(fields = [\"source_set\"])\n\nvalues = [\n    \"debug\",\n    \"release\",\n    \"infer\",\n]\n\ndef _impl(ctx):\n    raw_value = ctx.build_setting_value\n    if raw_value not in values:\n        fail(str(ctx.label) + \" build setting allowed to take values {\" +\n             \", \".join(values) + \"} but was set to unallowed value \" +\n             raw_value)\n    return ValdiModulesSourceSetProvider(source_set = raw_value)\n\nsource_set = rule(\n    implementation = _impl,\n    build_setting = config.string(flag = True),\n)\n"
  },
  {
    "path": "bzl/valdi/source_set/utils.bzl",
    "content": "# Valdi Modules-specific helper functions for configuring a Starlark select({...}) with string values\n# that include a {source_set} format placeholder.\n#\n# Additional format substitutions should be provided via the `substitutions` parameter\n#\n# For example:\n# _source_set_pattern([ \"{source_set}/some_path/to/file\" ]) will configure a select that picks\n# the formatted path with {source_set} replaced by the currently configured Valdi Modules source set.\n# E.g. if current Bazel build/run invocation is configured for the 'debug' source set, the selected\n# value would be \"debug/some_path/to/file\"\ndef source_set_patterns(pattern_formats, should_glob, exclude = [], release_exclude = [], **substitutions):\n    debug_patterns = []\n    release_patterns = []\n    for pattern_format in pattern_formats:\n        debug_pattern = pattern_format.format(source_set = \"debug\", **substitutions)\n        debug_patterns.append(debug_pattern)\n        release_pattern = pattern_format.format(source_set = \"release\", **substitutions)\n        release_patterns.append(release_pattern)\n\n    if should_glob:\n        debug_patterns = native.glob(debug_patterns, exclude = exclude)\n        release_patterns = native.glob(release_patterns, exclude = exclude + release_exclude)\n\n    return source_set_select(\n        debug = debug_patterns,\n        release = release_patterns,\n    )\n\n# Convenience around source_set_patterns allowing it to be a drop-in replacement for native.glob\ndef source_set_glob(pattern_formats, exclude = [], release_exclude = [], **substitutions):\n    return source_set_patterns(pattern_formats, should_glob = True, exclude = exclude, release_exclude = release_exclude, **substitutions)\n\n# Helper function wrapping Starlark select(...)\ndef source_set_select(debug, release):\n    return select({\n        \"@valdi//bzl/valdi/source_set:debug\": debug,\n        \"@valdi//bzl/valdi/source_set:release\": release,\n        \"@valdi//bzl/valdi/source_set:infer_debug\": debug,\n        \"@valdi//bzl/valdi/source_set:infer_release\": release,\n    })\n"
  },
  {
    "path": "bzl/valdi/suffixed_deps.bzl",
    "content": "def get_suffixed_deps(deps, suffix):\n    out = []\n    for d in deps:\n        label = native.package_relative_label(d)\n        out.append(label.same_package_label(label.name + suffix))\n    return out\n"
  },
  {
    "path": "bzl/valdi/toolchains.bzl",
    "content": "def register_valdi_toolchains():\n    native.register_toolchains(\n        \"@valdi//bzl/valdi:valdi_toolchain\",\n    )\n"
  },
  {
    "path": "bzl/valdi/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"node\",\n    \"esModuleInterop\": true,\n    \"allowJs\": false,\n    \"composite\": true,\n    \"jsx\": \"preserve\"\n  },\n}"
  },
  {
    "path": "bzl/valdi/valdi_android_application.bzl",
    "content": "load(\"@rules_android//rules:rules.bzl\", \"android_binary\")\nload(\"@rules_kotlin//kotlin:android.bzl\", \"kt_android_library\")\nload(\"@valdi//valdi:valdi.bzl\", \"valdi_android_aar\")\nload(\"//bzl:expand_template.bzl\", \"expand_template\")\nload(\"//bzl/valdi/source_set:utils.bzl\", \"source_set_select\")\n\ndef _make_xml_compound_substitution(key_values):\n    output = []\n\n    for keyval in key_values:\n        output.append('{}=\"{}\"'.format(keyval[0], keyval[1]))\n\n    return \" \".join(output)\n\ndef valdi_android_application(\n        name,\n        title,\n        root_component_path,\n        package,\n        app_manifest = None,\n        assets = None,\n        assets_dir = None,\n        resource_files = None,\n        icon_name = None,\n        round_icon_name = None,\n        activity_theme_name = None,\n        deps = [],\n        native_deps = []):\n    src_target = \"{}_src\".format(name)\n    src_activity_target = \"{}_activitygen\".format(name)\n    aar_target = \"{}_aar\".format(name)\n\n    expand_template(\n        name = src_activity_target,\n        src = \"@valdi//bzl/valdi/app_templates:StartActivity.kt.tpl\",\n        output = \"StartActivity.kt\",\n        substitutions = {\n            \"@VALDI_APP_PACKAGE@\": package,\n            \"@VALDI_ROOT_COMPONENT_PATH@\": root_component_path,\n        },\n    )\n\n    resolved_app_manifest = app_manifest\n\n    if not app_manifest:\n        app_attributes = []\n\n        if icon_name:\n            app_attributes.append((\"android:icon\", \"@mipmap/{}\".format(icon_name)))\n        if round_icon_name:\n            app_attributes.append((\"android:roundIcon\", \"@mipmap/{}\".format(round_icon_name)))\n\n        activity_attributes = []\n\n        if activity_theme_name:\n            activity_attributes.append((\"android:theme\", \"@style/{}\".format(activity_theme_name)))\n\n        app_manifest_target = \"{}_app_manifest\".format(name)\n        resolved_app_manifest = \":{}\".format(app_manifest_target)\n        expand_template(\n            name = app_manifest_target,\n            src = source_set_select(\n                debug = \"@valdi//bzl/valdi/app_templates:AndroidDebugAppManifest.xml.tpl\",\n                release = \"@valdi//bzl/valdi/app_templates:AndroidReleaseAppManifest.xml.tpl\",\n            ),\n            output = \"AndroidAppManifest.xml\",\n            substitutions = {\n                \"@VALDI_APP_PACKAGE@\": package,\n                \"@VALDI_APP_NAME@\": title,\n                \"@VALDI_APPLICATION_ATTRIBUTES@\": _make_xml_compound_substitution(app_attributes),\n                \"@VALDI_ACTIVITY_ATTRIBUTES@\": _make_xml_compound_substitution(activity_attributes),\n            },\n        )\n\n    kt_android_library(\n        name = src_target,\n        srcs = [\":{}\".format(src_activity_target)],\n        custom_package = package,\n        manifest = \"@valdi//bzl/valdi/app_templates:AndroidLibManifest.xml\",\n        deps = [\n            \"@valdi//valdi:valdi_android_support\",\n            \"@android_mvn//:androidx_appcompat_appcompat\",\n        ] + deps,\n    )\n\n    valdi_android_aar(\n        name = aar_target,\n        native_deps = [\n            \"@valdi//valdi\",\n        ] + native_deps,\n        so_name = \"libvaldi.so\",\n    )\n\n    android_binary(\n        name = name,\n        custom_package = package,\n        manifest = resolved_app_manifest,\n        multidex = \"native\",\n        assets = assets,\n        assets_dir = assets_dir,\n        resource_files = resource_files,\n        tags = [\"valdi_android_application\"],\n        deps = [\n            \":{}\".format(src_target),\n            \":{}_import\".format(aar_target),\n        ],\n    )\n"
  },
  {
    "path": "bzl/valdi/valdi_android_library.bzl",
    "content": "load(\"@rules_kotlin//kotlin:android.bzl\", \"kt_android_library\")\n\ndef valdi_android_library(\n        name,\n        **kwargs):\n    kt_android_library(name = name, plugins = [\n        \"@valdi//valdi:annotation_processor\",\n    ], **kwargs)\n"
  },
  {
    "path": "bzl/valdi/valdi_application.bzl",
    "content": "load(\"//bzl/valdi:suffixed_deps.bzl\", \"get_suffixed_deps\")\nload(\"//bzl/valdi:valdi_android_application.bzl\", \"valdi_android_application\")\nload(\"//bzl/valdi:valdi_ios_application.bzl\", \"valdi_ios_application\")\nload(\"//bzl/valdi:valdi_macos_application.bzl\", \"valdi_macos_application\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_hotreload\")\n\ndef valdi_application(\n        name,\n        title,\n        root_component_path,\n        ios_bundle_id = None,\n        ios_info_plist = None,\n        ios_families = None,\n        ios_minimum_os_version = None,\n        ios_provisioning_profile = None,\n        ios_app_icons = None,\n        android_package = None,\n        android_assets = None,\n        android_assets_dir = None,\n        android_resource_files = None,\n        android_app_manifest = None,\n        android_app_icon_name = None,\n        android_round_app_icon_name = None,\n        android_activity_theme_name = None,\n        desktop_window_width = 600,\n        desktop_window_height = 800,\n        desktop_window_resizable = True,\n        version = None,\n        deps = []):\n    resolved_ios_bundle_id = ios_bundle_id if ios_bundle_id else \"com.snap.valdi.{}\".format(name)\n    resolved_android_package = android_package if android_package else \"com.snap.valdi.{}\".format(name)\n\n    valdi_ios_application(\n        name = \"{}_ios\".format(name),\n        title = title,\n        root_component_path = root_component_path,\n        bundle_id = resolved_ios_bundle_id,\n        info_plist = ios_info_plist,\n        families = ios_families,\n        minimum_os_version = ios_minimum_os_version,\n        provisioning_profile = ios_provisioning_profile,\n        app_icons = ios_app_icons,\n        version = version,\n        deps = get_suffixed_deps(deps, \"_objc\"),\n    )\n\n    valdi_android_application(\n        name = \"{}_android\".format(name),\n        title = title,\n        root_component_path = root_component_path,\n        package = resolved_android_package,\n        assets = android_assets,\n        assets_dir = android_assets_dir,\n        app_manifest = android_app_manifest,\n        resource_files = android_resource_files,\n        icon_name = android_app_icon_name,\n        round_icon_name = android_round_app_icon_name,\n        activity_theme_name = android_activity_theme_name,\n        deps = get_suffixed_deps(deps, \"_kt\"),\n        native_deps = get_suffixed_deps(deps, \"_native\"),\n    )\n\n    valdi_macos_application(\n        name = \"{}_macos\".format(name),\n        title = title,\n        root_component_path = root_component_path,\n        bundle_id = resolved_ios_bundle_id,\n        window_width = desktop_window_width,\n        window_height = desktop_window_height,\n        window_resizable = desktop_window_resizable,\n        deps = get_suffixed_deps(deps, \"_native\"),\n    )\n\n    valdi_hotreload(\n        name = \"{}_hotreload\".format(name),\n        targets = deps,\n        tags = [\"valdi_application\"],\n    )\n"
  },
  {
    "path": "bzl/valdi/valdi_cli_application.bzl",
    "content": "load(\"//bzl:expand_template.bzl\", \"expand_template\")\nload(\"//bzl/valdi:suffixed_deps.bzl\", \"get_suffixed_deps\")\n\ndef valdi_cli_application(\n        name,\n        script_path,\n        visibility = [\"//visibility:public\"],\n        deps = []):\n    main_target = \"{}_main\".format(name)\n\n    expand_template(\n        name = main_target,\n        src = \"@valdi//bzl/valdi/app_templates:cli_main.cpp.tpl\",\n        output = \"main.cpp\",\n        substitutions = {\n            \"@VALDI_SCRIPT_PATH@\": script_path,\n        },\n    )\n\n    native.cc_binary(\n        name = name,\n        linkshared = False,\n        visibility = visibility,\n        srcs = [\":{}\".format(main_target)],\n        tags = [\"valdi_cli_application\"],\n        deps = [\n            \"@valdi//valdi:cli_runner\",\n            \"@valdi//src/valdi_modules/src/valdi/valdi_core:valdi_core_native\",\n        ] + get_suffixed_deps(deps, \"_native\"),\n    )\n"
  },
  {
    "path": "bzl/valdi/valdi_collapse_web_paths.bzl",
    "content": "load(\":valdi_compiled.bzl\", \"ValdiModuleInfo\")\n\ndef _dest_native(rel):\n    \"\"\"Canonical path for a file in the native/ tree: <module>/web/<file> or module path.\n\n    Used by both collapse_web_paths (where to put the file) and generate_register_native_modules\n    (require path). Must be the single source of truth for native layout.\"\"\"\n    parts = rel.split(\"/\")\n    for i, seg in enumerate(parts):\n        if seg == \"web\":\n            parent = parts[i - 1] if i > 0 else \"\"\n            tail = \"/\".join(parts[i + 1:])\n            base = (parent + \"/web\") if parent else \"web\"\n            return base + (\"/\" + tail if tail else \"\")\n    return \"/\".join(parts)\n\n# Dest path substrings that should not be registered (test files, etc).\n# Shared by collapse_web_paths and generate_register_native_modules so native layout stays in sync.\n_REGISTER_NATIVE_EXCLUDE_SUBSTRINGS = [\n    \"/test/\",\n    \".test.\",\n    \".spec.\",\n    \"_debugging/\",  # Optional/debug-only modules (e.g. ..._debugging/web/); not bundled in web package\n]\n\ndef _should_register_native_module(dest_path):\n    \"\"\"Exclude test files and modules that are not suitable for web bundle.\"\"\"\n    for sub in _REGISTER_NATIVE_EXCLUDE_SUBSTRINGS:\n        if sub in dest_path:\n            return False\n    return True\n\ndef _is_native_module_js(rel):\n    \"\"\"True if this short_path is a native module .js that gets require(pkg/native/...) in RegisterNativeModules.js.\"\"\"\n    d = _dest_native(rel)\n    if not d.endswith(\".js\"):\n        return False\n    if \"/web/debug/\" in d or \"/web/release/\" in d:\n        return False\n    return _should_register_native_module(d)\n\ndef _should_exclude_from_package(short_path):\n    \"\"\"True if this file should not be copied into the collapsed package (test files, tree root, or unregistered native .js).\"\"\"\n    for sub in _REGISTER_NATIVE_EXCLUDE_SUBSTRINGS:\n        if sub in short_path:\n            return True\n\n    # web_native tree root (directory): skip so we only copy expanded files, not the whole tree\n    idx = short_path.rfind(\"web_native\")\n    if idx >= 0 and not short_path[idx + len(\"web_native\"):].lstrip(\"/\"):\n        return True\n    d = _dest_native(short_path)\n    if d.endswith(\".js\") and not _should_register_native_module(d):\n        return True\n    return False\n\ndef _dest(rel):\n    \"\"\"Maps a source short_path to its destination path in the collapsed npm package.\"\"\"\n\n    # Handle package.json - keep it at root\n    if rel.endswith(\"package.json\"):\n        return \"package.json\"\n\n    # Generated RegisterNativeModules.js goes at src/ for NPM package consumers\n    if rel.endswith(\"RegisterNativeModules.js\"):\n        return \"src/RegisterNativeModules.js\"\n\n    if \"protodecl_collapsed\" in rel:\n        return \"src\"\n\n    # Single source of truth for native module .js: same predicate as generate_register_native_modules.\n    # Any path that would get a require(pkg/native/...) there goes to native/<dest_native> here.\n    if _is_native_module_js(rel):\n        return \"native/\" + _dest_native(rel)\n\n    # Handle external repository paths (short_path starts with ../ for external repos)\n    # and regular source paths. Extract everything after /src/valdi_modules/src/valdi/\n    # Works with any external repo name (e.g., ../<repo>/src/valdi_modules/src/valdi/...)\n    valdi_marker = \"/src/valdi_modules/src/valdi/\"\n\n    # Try to find and strip the valdi marker from the path\n    rel2 = rel\n    if valdi_marker in rel:\n        idx = rel.find(valdi_marker)\n        rel2 = rel[idx + len(valdi_marker):]\n    elif rel.startswith(\"src/valdi_modules/src/valdi/\"):\n        # Handle direct paths (non-external)\n        rel2 = rel[len(\"src/valdi_modules/src/valdi/\"):]\n\n    parts = rel2.split(\"/\")\n\n    # Handle TypeScript declaration files (.d.ts) from .valdi_build/compile/typescript/output/\n    # These should go into src/<module_name>/...\n    for i in range(len(parts)):\n        if parts[i] == \".valdi_build\" and i + 3 < len(parts):\n            if parts[i + 1] == \"compile\" and parts[i + 2] == \"typescript\" and parts[i + 3] == \"output\":\n                # Skip to the module name and path after \"output\"\n                if i + 4 < len(parts):\n                    tail = \"/\".join(parts[i + 4:])\n                    return \"src/{}\".format(tail)\n\n    for i in range(len(parts) - 3):\n        if (parts[i + 1] == \"web\" and\n            parts[i + 2] in [\"debug\", \"release\"] and\n            parts[i + 3] in [\"assets\", \"res\"]):\n            tail = \"/\".join(parts[i + 4:])\n            return \"src/{}\".format(tail)\n\n    # Handle source .d.ts files from any path containing /src/valdi_modules/src/valdi/\n    # These should go into src/<module_name>/src/...\n    if rel.endswith(\".d.ts\") and valdi_marker in rel:\n        # rel2 already has the marker stripped, so it's <module_name>/src/...\n        # Return it as src/<module_name>/src/...\n        return \"src/{}\".format(rel2)\n\n    return rel\n\ndef _impl(ctx):\n    outdir = ctx.actions.declare_directory(ctx.label.name)\n    package_name = ctx.attr.package_name\n    exclude_jsx = ctx.attr.exclude_jsx_global_declaration\n\n    # Build manifest src → dest. Deduplicate by dest (first source wins) so the same logical file\n    # from tree artifact and filegroup doesn't trigger duplicate copies.\n    manifest = ctx.actions.declare_file(ctx.label.name + \".manifest\")\n    seen_dest = {}\n    lines = []\n    for f in ctx.files.srcs:\n        if exclude_jsx and \"valdi_tsx/src/JSX.d.ts\" in f.short_path:\n            continue\n        if _should_exclude_from_package(f.short_path):\n            continue\n        d = _dest(f.short_path)\n        if d not in seen_dest:\n            seen_dest[d] = True\n            lines.append(\"{}\\t{}\".format(f.path, d))\n\n    # If excluding JSX global declaration, add stub file from valdi_tsx/web\n    if exclude_jsx:\n        stub = ctx.file.jsx_stub_file\n        lines.append(\"{}\\tsrc/valdi_tsx/src/JSX.d.ts\".format(stub.path))\n\n    ctx.actions.write(manifest, \"\\n\".join(lines) + \"\\n\")\n\n    # tiny shell copier with .d.ts import rewriting\n    sh = ctx.actions.declare_file(ctx.label.name + \".sh\")\n    ctx.actions.write(\n        output = sh,\n        is_executable = True,\n        content = \"\"\"#!/usr/bin/env bash\n        set -euo pipefail\n        OUT=\"$1\"; MAN=\"$2\"; PKG_NAME=\"$3\"\n        rm -rf \"$OUT\"; mkdir -p \"$OUT\"\n\n        while IFS=$'\\\\t' read -r SRC DEST; do\n        [ -z \"$SRC\" ] && continue\n\n        # If SRC is a directory (tree artifact), copy its *contents* into DEST\n        if [ -d \"$SRC\" ]; then\n            mkdir -p \"$OUT/$DEST\"\n            # copy contents, not the top-level dir\n            cp -R \"$SRC/.\" \"$OUT/$DEST/\"\n        else\n            D=\"$OUT/$(dirname \"$DEST\")\"\n            mkdir -p \"$D\"\n            cp -f \"$SRC\" \"$OUT/$DEST\"\n        fi\n        done < \"$MAN\"\n        \n        # Rewrite imports in .d.ts files to use full package paths\n        # Converts module_name/src/... → PACKAGE_NAME/src/module_name/src/...\n        find \"$OUT\" -name \"*.d.ts\" -type f | while read -r file; do\n            if [[ \"$OSTYPE\" == \"darwin\"* ]]; then\n                # macOS\n                sed -i '' -E \"s|from '([a-zA-Z0-9_.-]+/src/[^']+)'|from '${PKG_NAME}/src/\\\\1'|g\" \"$file\"\n                sed -i '' -E \"s|from \\\\\"([a-zA-Z0-9_.-]+/src/[^\\\\\"]+)\\\\\"|from \\\\\"${PKG_NAME}/src/\\\\1\\\\\"|g\" \"$file\"\n                sed -i '' -E \"s|import '([a-zA-Z0-9_.-]+/src/[^']+)'|import '${PKG_NAME}/src/\\\\1'|g\" \"$file\"\n                sed -i '' -E \"s|import \\\\\"([a-zA-Z0-9_.-]+/src/[^\\\\\"]+)\\\\\"|import \\\\\"${PKG_NAME}/src/\\\\1\\\\\"|g\" \"$file\"\n            else\n                # Linux\n                sed -i -E \"s|from '([a-zA-Z0-9_.-]+/src/[^']+)'|from '${PKG_NAME}/src/\\\\1'|g\" \"$file\"\n                sed -i -E \"s|from \\\\\"([a-zA-Z0-9_.-]+/src/[^\\\\\"]+)\\\\\"|from \\\\\"${PKG_NAME}/src/\\\\1\\\\\"|g\" \"$file\"\n                sed -i -E \"s|import '([a-zA-Z0-9_.-]+/src/[^']+)'|import '${PKG_NAME}/src/\\\\1'|g\" \"$file\"\n                sed -i -E \"s|import \\\\\"([a-zA-Z0-9_.-]+/src/[^\\\\\"]+)\\\\\"|import \\\\\"${PKG_NAME}/src/\\\\1\\\\\"|g\" \"$file\"\n            fi\n        done\n        \"\"\",\n    )\n\n    ctx.actions.run(\n        inputs = [manifest] + ctx.files.srcs,\n        outputs = [outdir],\n        tools = [sh],\n        executable = sh,\n        arguments = [outdir.path, manifest.path, package_name],\n        progress_message = \"Collapsing web paths and rewriting .d.ts imports into {}\".format(outdir.path),\n    )\n    return [DefaultInfo(files = depset([outdir]))]\n\ncollapse_web_paths = rule(\n    implementation = _impl,\n    attrs = {\n        \"srcs\": attr.label_list(allow_files = True),\n        \"package_name\": attr.string(mandatory = True, doc = \"The NPM package name\"),\n        \"exclude_jsx_global_declaration\": attr.bool(default = False, doc = \"Exclude valdi_tsx/src/JSX.d.ts and replace with stub to prevent global namespace pollution\"),\n        \"jsx_stub_file\": attr.label(\n            default = \"@valdi//src/valdi_modules/src/valdi/valdi_tsx:web/JSX.stub.d.ts\",\n            allow_single_file = True,\n            doc = \"Stub file to use when exclude_jsx_global_declaration is True\",\n        ),\n    },\n)\n\ndef _impl_native(ctx):\n    outdir = ctx.actions.declare_directory(ctx.label.name)\n\n    # Build a manifest of: SRC \\t DEST\n    manifest = ctx.actions.declare_file(ctx.label.name + \".manifest\")\n    lines = []\n    for f in ctx.files.srcs:\n        lines.append(\"{}\\t{}\".format(f.path, _dest_native(f.short_path)))\n    ctx.actions.write(manifest, \"\\n\".join(lines))\n\n    # Tiny shell that copies into the declared directory\n    sh = ctx.actions.declare_file(ctx.label.name + \".sh\")\n    ctx.actions.write(\n        output = sh,\n        is_executable = True,\n        content = \"\"\"#!/usr/bin/env bash\n            set -euo pipefail\n            OUT=\"$1\"; MAN=\"$2\"\n            rm -rf \"$OUT\"; mkdir -p \"$OUT\"\n            while IFS=$'\\\\t' read -r SRC DEST; do\n            [ -z \"$SRC\" ] && continue\n            D=\"$OUT/$(dirname \"$DEST\")\"\n            mkdir -p \"$D\"\n            cp -rf \"$SRC\" \"$OUT/$DEST\"\n            done < \"$MAN\"\n        \"\"\",\n    )\n\n    ctx.actions.run(\n        inputs = [manifest] + ctx.files.srcs,\n        outputs = [outdir],\n        tools = [sh],\n        executable = sh,\n        arguments = [outdir.path, manifest.path],\n        progress_message = \"Collapsing native paths into {}\".format(outdir.path),\n    )\n    return [DefaultInfo(files = depset([outdir]))]\n\ncollapse_native_paths = rule(\n    implementation = _impl_native,\n    attrs = {\n        \"srcs\": attr.label_list(allow_files = True),\n    },\n)\n\ndef _module_id_from_native_dest(dest_path):\n    \"\"\"Derive the Valdi module ID from native path like 'valdi_tsx/web/JSX.js' or 'cof/web/Cof.js'.\n    Convention: parent/web/File.js -> if parent equals filename (case-insensitive) use filename else parent/src/filename.\n    For paths without /web/ (e.g. my_module/utils/helper.js), insert /src/ only after the first segment: my_module/src/utils/helper.\n    \"\"\"\n    if \"/web/\" not in dest_path:\n        no_ext = dest_path[:-3] if dest_path.endswith(\".js\") else dest_path\n        first_slash = no_ext.find(\"/\")\n        if first_slash == -1:\n            return no_ext\n        return no_ext[:first_slash] + \"/src/\" + no_ext[first_slash + 1:]\n    idx = dest_path.index(\"/web/\")\n    parent = dest_path[:idx]\n    file_part = dest_path[idx + 5:]  # after \"/web/\"\n    if file_part.endswith(\".js\"):\n        file_part = file_part[:-3]\n    if parent.split(\"/\")[-1].lower() == file_part.lower():\n        return file_part\n    return parent + \"/src/\" + file_part\n\ndef _merge_module_id_overrides_from_modules(modules):\n    \"\"\"Collect web_register_native_module_id_overrides from all transitive Valdi modules.\"\"\"\n    all_modules = depset(direct = modules, transitive = [m[ValdiModuleInfo].deps for m in modules])\n    merged = {}\n    for m in all_modules.to_list():\n        overrides = getattr(m[ValdiModuleInfo], \"web_register_native_module_id_overrides\", None)\n        if overrides:\n            merged.update(overrides)\n    return merged\n\ndef _generate_register_native_modules_impl(ctx):\n    package_name = ctx.attr.package_name\n\n    # Overrides: first from each module's ValdiModuleInfo, then BUILD-level overrides on top\n    module_id_overrides = dict(_merge_module_id_overrides_from_modules(ctx.attr.modules))\n    module_id_overrides.update(ctx.attr.module_id_overrides)\n\n    out = ctx.actions.declare_file(\"RegisterNativeModules.js\")\n    lines = [\n        \"\",\n        \"/**\",\n        \" * AUTO-GENERATED - Do not edit. Native module registrations for web runtime.\",\n        \" * Generated from _all_web_deps.\",\n        \" */\",\n        \"\",\n        \"var _cbs = globalThis.__valdiWebViewClassRegistryCallbacks =\",\n        \"  globalThis.__valdiWebViewClassRegistryCallbacks || [];\",\n        \"\",\n    ]\n    seen_dest = {}\n    n = 0\n    for f in ctx.files.srcs:\n        dest = _dest_native(f.short_path)\n        if not dest.endswith(\".js\"):\n            continue\n        if not _should_register_native_module(dest):\n            continue\n        if dest in seen_dest:\n            continue\n        seen_dest[dest] = True\n        raw_id = module_id_overrides.get(dest, _module_id_from_native_dest(dest))\n        module_ids = [s.strip() for s in raw_id.split(\",\") if s.strip()]\n        if not module_ids:\n            module_ids = [raw_id]\n        require_path = package_name + \"/native/\" + dest[:-3]  # strip .js for require()\n        var_name = \"_n\" + str(n)\n        n += 1\n        lines.append(\"var {} = require('{}');\".format(var_name, require_path))\n        for mid in module_ids:\n            lines.append(\"global.moduleLoader.registerModule('{}', () => {});\".format(mid, var_name))\n        lines.append(\"if ({v}.webPolyglotViews) {{\".format(v = var_name))\n        lines.append(\"  _cbs.push(function(registry) {\")\n        lines.append(\"    Object.entries({v}.webPolyglotViews).forEach(function(e) {{ registry.set(e[0], e[1]); }});\".format(v = var_name))\n        lines.append(\"  });\")\n        lines.append(\"}\")\n        lines.append(\"\")\n    ctx.actions.write(output = out, content = \"\\n\".join(lines))\n    return [DefaultInfo(files = depset([out]))]\n\ngenerate_register_native_modules = rule(\n    implementation = _generate_register_native_modules_impl,\n    attrs = {\n        \"srcs\": attr.label_list(allow_files = True),\n        \"package_name\": attr.string(mandatory = True, doc = \"NPM package name (e.g. @snapchat/valdi_web_snapchat_web_npm)\"),\n        \"modules\": attr.label_list(\n            default = [],\n            providers = [ValdiModuleInfo],\n            doc = \"Valdi module targets (e.g. deps of valdi_exported_library). Their web_register_native_module_id_overrides are merged to form the module ID map.\",\n        ),\n        \"module_id_overrides\": attr.string_dict(\n            default = {},\n            doc = \"Optional BUILD-level overrides (native dest path -> runtime module ID). Applied after module-declared overrides.\",\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_compiled.bzl",
    "content": "\"\"\"\nBazel rules for invoking the Valdi compiler and generating .valdimodule and source files.\n\nEach valdi module should have a BUILD.bazel file that invokes the valdi_module() macro\ninstead of invoking this rule directly. The macro invokes this rule and takes care of properly\nwrapping generated artifacts.\n\"\"\"\n\nload(\"@bazel_skylib//lib:paths.bzl\", \"paths\")\nload(\"@bazel_skylib//rules:common_settings.bzl\", \"BuildSettingInfo\")\nload(\n    \"common.bzl\",\n    \"ANDROID_RESOURCE_VARIANT_DIRECTORIES\",\n    \"BUILD_DIR\",\n    \"IOS_API_NAME_SUFFIX\",\n    \"IOS_DEFAULT_MODULE_NAME_PREFIX\",\n    \"IOS_OUTPUT_BASE\",\n    \"NODE_MODULES_BASE\",\n    \"TYPESCRIPT_DUMPED_SYMBOLS_DIR\",\n    \"TYPESCRIPT_GENERATED_TS_DIR\",\n    \"base_relative_dir\",\n)\nload(\":localizable_strings.bzl\", \"supported_langs_mapping\")\nload(\":valdi_paths.bzl\", \"get_ids_yaml_dts_path\", \"get_legacy_vue_srcs_dts_paths\", \"get_resources_dts_paths\", \"get_sql_dts_paths\", \"get_strings_dts_path\", \"infer_base_output_dir\", \"output_declaration_compiled_file_path_for_source_file\", \"output_declaration_file_path_for_source_file\", \"replace_prefix\", \"resolve_module_dir_and_name\", \"resolve_relative_project_path\")\nload(\":valdi_run_compiler.bzl\", \"generate_config\", \"resolve_compiler_executable\", \"run_valdi_compiler\")\nload(\":valdi_toolchain_type.bzl\", \"VALDI_TOOLCHAIN_TYPE\")\n\n# These paths let us find/declare the expected output locations\n\n_ANDROID_ASSETS_DIR = \"assets\"\n_ANDROID_RESOURCES_DIR = \"res\"\n_ANDROID_SOURCE_MAPS_DIR = \"source-maps\"\n_ANDROID_GENERATED_SRC_DIR = \"src\"\n_ANDROID_GENERATED_NATIVE_SRC_DIR = \"native\"\n\n_IOS_ASSETS_DIR = \"assets\"\n_IOS_SOURCE_MAPS_DIR = \"source-maps\"\n_IOS_GENERATED_SRC_DIR = \"src\"\n_IOS_GENERATED_NATIVE_SRC_DIR = \"native\"\n\n_WEB_RESOURCES_DIR = \"res\"\n\n# Kill the compiler after 15 minutes\nCOMPILER_TIMEOUT_SECONDS = 15 * 60\n# We don't include the temporary directory here - that should only be used for hot reloading\n\n_VALDI_BASE_MODULE_NAME = \"__valdi_base__\"\n\nValdiModuleInfo = provider(\n    doc = \"Outputs of valdi module compilation\",\n    fields = {\n        \"name\": \"The name of this valdi module. Usually it's snake_cased (e.g. your_module)\",\n        \"deps\": \"The deps of the modules\",\n        \"disable_annotation_processing\": \"When set to true, will not expect any Valdi annotation processing to occur for this module. In practice, that means that the .dumped-symbols.json output will not be created\",\n        \"async_strict_mode\": \"When set to true, raise exceptions for sync calls made by native code in this module\",\n        \"android_debug_resource_files\": \"Android debug resources\",\n        \"android_release_resource_files\": \"Android release resources\",\n        \"android_debug_valdimodule\": \"generated .valdimodule file for this Valdi module\",\n        \"android_release_valdimodule\": \"generated .valdimodule file for this Valdi module\",\n        \"android_debug_srcjar\": \"generated .srcjar file for this Valdi module\",\n        \"android_release_srcjar\": \"generated .srcjar file for this Valdi module\",\n        \"android_debug_nativesrc\": \"generated .c file containing all the generated C code\",\n        \"android_release_nativesrc\": \"generated .c file containing all the generated C code\",\n        \"android_debug_sourcemaps\": \"generated .map.json files for this Valdi module\",\n        \"android_debug_sourcemap_archive\": \"A tree artifact containing archive of source and source maps\",\n        \"android_release_sourcemap_archive\": \"A tree artifact containing archive of source and source maps\",\n        \"prepared_upload_artifact\": \"Generated prepared artifact meant for uploading the assets\",\n        \"exported_deps\": \"Dependencies that this module's API depends on and, as such, are exported as dependencies together with the module.\",\n        \"ios_module_name\": \"The name of the iOS module based on module.yaml content\",\n        \"ios_debug_resource_files\": \"iOS debug resources\",\n        \"ios_debug_bundle_resources\": \"iOS debug resources bundle\",\n        \"ios_release_resource_files\": \"iOS release resources\",\n        \"ios_release_bundle_resources\": \"iOS release resources bundle\",\n        \"ios_debug_valdimodule\": \"generated .valdimodule file for this Valdi module\",\n        \"ios_release_valdimodule\": \"generated .valdimodule file for this Valdi module\",\n        \"ios_debug_sourcemaps\": \"generated .map.json files for this Valdi module\",\n        \"ios_debug_generated_hdrs\": \"Will contain the generated Objective-C header file, only if single_file_codegen is enabled\",\n        \"ios_debug_generated_srcs\": \"A tree artifact containing all the generated objective-c/swift code\",\n        \"ios_debug_api_generated_hdrs\": \"Will contain the generated Objective-C API header file, only if single_file_codegen is enabled\",\n        \"ios_debug_api_generated_srcs\": \"A tree artifact containing all the generated objective-c/swift code (for the API-only module)\",\n        \"ios_release_generated_hdrs\": \"Will contain the generated Objective-C header file, only if single_file_codegen is enabled\",\n        \"ios_release_generated_srcs\": \"A tree artifact containing all the generated objective-c/swift code\",\n        \"ios_release_api_generated_hdrs\": \"Will contain the generated Objective-C API header file, only if single_file_codegen is enabled\",\n        \"ios_release_api_generated_srcs\": \"A tree artifact containing all the generated objective-c/swift code (for the API-only module)\",\n        \"ios_debug_generated_swift_srcs\": \"The generated Swift source file for single_file_codegen modules with Swift output\",\n        \"ios_release_generated_swift_srcs\": \"The generated Swift source file for single_file_codegen modules with Swift output\",\n        \"ios_debug_api_generated_swift_srcs\": \"The generated Swift API source file for single_file_codegen modules with Swift output\",\n        \"ios_release_api_generated_swift_srcs\": \"The generated Swift API source file for single_file_codegen modules with Swift output\",\n        \"ios_debug_nativesrc\": \"generated .c file containing all the generated C code\",\n        \"ios_release_nativesrc\": \"generated .c file containing all the generated C code\",\n        \"cpp_srcs\": \"generated .cpp files containing all the generated C++ code\",\n        \"cpp_hdrs\": \"generated .hpp files containing all the generated C++ header files\",\n        \"ios_debug_sourcemap_archive\": \"A tree artifact containing archive of source and source maps\",\n        \"ios_release_sourcemap_archive\": \"A tree artifact containing archive of source and source maps\",\n        \"ios_sql_assets\": \"generated files for .sql files for this Valdi module\",\n        \"ios_dependency_data\": \"generated dependency data for this Valdi module\",\n        \"protodecl_srcs\": \".protodecl\",\n        \"intermediates\": \"The intermediates files that should be used to compile another module that depends on this module\",\n        \"base_path\": \"The base path to the module\",\n        \"module_definition\": \"The generated content of the module definition.\",\n        \"web_debug_sources\": \"A tree artifact containing all the generated web sources\",\n        \"web_release_sources\": \"A tree artifact containing all the generated web sources\",\n        \"web_debug_resource_files\": \"Web resource files\",\n        \"web_release_resource_files\": \"Web resource files\",\n        \"web_debug_strings\": \"Web debug strings\",\n        \"web_release_strings\": \"Web release strings\",\n        \"web_deps\": \"Web ts/js dependencies\",\n        \"web_dts_files\": \"TypeScript declaration files (.d.ts) for web\",\n        \"web_register_native_module_id_overrides\": \"Optional dict: native dest path (e.g. 'valdi_core/web/DeviceBridge.js') -> runtime module ID (e.g. 'DeviceBridge'). Declared by the module that owns the web stub.\",\n    },\n)\n\ndef _valdi_compiled_impl(ctx):\n    \"\"\" Invokes the Valdi compiler for a module and generates all outputs.\n\n    Args:\n        ctx: The context of the current rule invocation\n\n    Returns:\n        A list of providers consisting of:\n            DefaultInfo provider with all outputs\n            ValdiModuleInfo provider\n    \"\"\"\n    module_name = ctx.attr.module\n\n    directory_name = paths.basename(ctx.label.package)\n    if directory_name != ctx.label.name:\n        fail(\"Valdi module name must match the name of the directory where the valdi_module() target is defined (expected directory name '{}', found '{}')\".format(ctx.label.name, directory_name))\n\n    (module_yaml, module_definition) = _resolve_module_yaml(ctx, module_name)\n\n    # NPM scoped module names are postfixed with its scope during compilation\n    # to avoid namespace conflicts.\n    module_scope = _get_module_scope(ctx.label.package)\n    if module_scope:\n        module_name += module_scope\n\n    outputs = _invoke_valdi_compiler(ctx, module_name, module_yaml)\n\n    # Check if code coverage is enabled via `bazel coverage` command or explicit flag\n    code_coverage = ctx.configuration.coverage_enabled or ctx.attr.code_coverage[BuildSettingInfo].value\n\n    if not ctx.attr.single_file_codegen and ctx.attr.has_android_exports:\n        outputs += _compress_generated_android_srcs(ctx, module_name, outputs, code_coverage)\n\n    return [\n        DefaultInfo(files = depset([o for o in outputs if o.path.endswith(\".valdimodule\")])),\n        _create_valdi_module_info(ctx, module_name, module_yaml, module_definition, outputs, code_coverage),\n    ]\n\n# valdi_compiled rule:\n#\n# Compiles a valdi module, generating:\n# - a .valdimodule file asset bundle which can be included in an Android/iOS app\n# - any native classes/interfaces for Android or iOS\n# - a resource with images for any modules with non-downloadable images\n# - compiled TypeScript declaration (.d.ts) files that can be used to compile other Valdi modules\nvaldi_compiled = rule(\n    implementation = _valdi_compiled_impl,\n    toolchains = [VALDI_TOOLCHAIN_TYPE],\n    fragments = [\"coverage\"],\n    attrs = {\n        \"module\": attr.string(\n            doc = \"The module name\",\n            mandatory = True,\n        ),\n        \"module_yaml\": attr.label(\n            doc = \"The module.yaml file of this module\",\n            allow_single_file = [\"module.yaml\"],\n        ),\n        \"ids_yaml\": attr.label(\n            doc = \"Optional ids.yaml file for this module\",\n            allow_single_file = [\"ids.yaml\"],\n        ),\n        \"strings_dir\": attr.string(\n            doc = \"The directory where the strings are located\",\n        ),\n        \"strings_json_srcs\": attr.label_list(\n            doc = \"String source files for this module\",\n            allow_files = True,\n        ),\n        \"android_output_target\": attr.string(\n            doc = \"The Android build type to build for\",\n            mandatory = True,\n            values = [\"debug\", \"release\"],\n        ),\n        \"android_export_strings\": attr.bool(\n            doc = \"Export Android string resources\",\n            default = True,\n        ),\n        \"ios_module_name\": attr.string(\n            mandatory = True,\n        ),\n        \"ios_output_target\": attr.string(\n            doc = \"The iOS build type to build for\",\n            mandatory = True,\n            values = [\"debug\", \"release\"],\n        ),\n        \"compilation_mode\": attr.string(\n            doc = \"The compilation mode to use for the module\",\n            mandatory = True,\n            values = [\"js\", \"js_bytecode\", \"native\"],\n        ),\n        \"android_class_path\": attr.string(\n            doc = \"The class path to use on Android for generated classes\",\n        ),\n        \"srcs\": attr.label_list(\n            doc = \"List of sources for this module\",\n            mandatory = True,\n            allow_files = [\".js\", \".ts\", \".tsx\", \".json\"],\n        ),\n        \"legacy_vue_srcs\": attr.label_list(\n            doc = \"List of legacy .vue sources for this module\",\n            allow_files = [\".vue\"],\n        ),\n        \"legacy_style_srcs\": attr.label_list(\n            doc = \"List of legacy .css sources for this module\",\n            allow_files = [\".css\", \".scss\"],\n        ),\n        \"protodecl_srcs\": attr.label_list(\n            doc = \"List of Protobuf files for this module\",\n            allow_files = [\".protodecl\"],\n        ),\n        \"res\": attr.label_list(\n            doc = \"List of resources for this module\",\n            allow_files = True,\n        ),\n        \"deps\": attr.label_list(\n            doc = \"List of other Valdi modules this module depends on\",\n            providers = [[ValdiModuleInfo]],\n        ),\n        \"web_deps\": attr.label_list(\n            doc = \"List of web dependencies for web\",\n        ),\n        \"web_register_native_module_id_overrides\": attr.string_dict(\n            default = {},\n            doc = \"Map of native dest path (e.g. 'valdi_core/web/DeviceBridge.js') to runtime module ID. Declared by the module that owns the web stub.\",\n        ),\n        \"disable_annotation_processing\": attr.bool(\n            doc = \"When set to true, will not expect any Valdi annotation processing to occur for this module.\",\n            default = False,\n        ),\n        \"async_strict_mode\": attr.bool(\n            doc = \"When set to true, raise exceptions for sync calls made by native code in this module.\",\n            default = False,\n        ),\n        \"sql_srcs\": attr.label_list(\n            doc = \"List of SQL files for this module\",\n            allow_files = [\".sql\", \".sq\", \".sqm\", \"sql_types.yaml\", \"sql_manifest.yaml\"],\n        ),\n        \"sql_db_names\": attr.string_list(),\n        \"has_dependency_data\": attr.bool(\n            doc = \"True if the module has associated dependency data\",\n            default = False,\n        ),\n        \"downloadable_assets\": attr.bool(\n            doc = \"Controls how module's assets are acquired: downloaded from Bolt or bundled with the module\",\n            default = True,\n        ),\n        \"strip_assets\": attr.bool(\n            doc = \"Whether assets should be stripped from the output\",\n            default = False,\n        ),\n        \"inline_assets\": attr.bool(\n            doc = \"Sets whether assets should be bundled inline within the .valdimodule\",\n            default = False,\n        ),\n        \"log_level\": attr.label(\n            doc = \"The log level for the Valdi compiler\",\n            default = \"@valdi//bzl/valdi:compilation_log_level\",\n        ),\n        \"localization_mode\": attr.label(\n            doc = \"Defines how the localized strings should be processed\",\n            default = \"@valdi//bzl/valdi:localization_mode\",\n        ),\n        \"js_bytecode_format\": attr.label(\n            doc = \"The JavaScript Bytecode format to use for the module\",\n            default = \"@valdi//bzl/valdi:js_bytecode_format\",\n        ),\n        \"code_coverage\": attr.label(\n            doc = \"Enable code coverage instrumentation\",\n            default = \"@valdi//bzl/valdi:code_coverage_enabled\",\n        ),\n        \"prepared_upload_artifact_name\": attr.string(\n            doc = \"The name for a prepared artifact meant for uploading the assets\",\n        ),\n        \"valdi_copts\": attr.string_list(\n            doc = \"Additional options to provide to the Valdi compiler\",\n        ),\n        \"single_file_codegen\": attr.bool(\n            doc = \"Whether codegen should occur in a single file or one file per type\",\n            default = True,\n        ),\n        \"ios_language\": attr.string_list(\n            doc = \"The languages for iOS output (e.g., ['objc'] or ['objc', 'swift'])\",\n            default = [\"objc\"],\n        ),\n        \"disable_code_coverage\": attr.bool(\n            doc = \"Disable code-coverage reporting for this module\",\n            default = False,\n        ),\n        \"disable_dependency_verification\": attr.bool(\n            doc = \"Disable dependency verifications for this module\",\n            default = False,\n        ),\n        \"disable_hotreload\": attr.bool(\n            doc = \"Disable hotreload from rebuilding this module\",\n            default = False,\n        ),\n        \"has_ios_exports\": attr.bool(\n            doc = \"Whether the module has iOS native exports\",\n            default = True,\n        ),\n        \"has_android_exports\": attr.bool(\n            doc = \"Whether the module has Android native exports\",\n            default = True,\n        ),\n        \"exclude_patterns\": attr.string_list(\n            doc = \"Exclude files that match the listed patterns\",\n        ),\n        \"exclude_globs\": attr.string_list(\n            doc = \"Exclude files that match the listed globs\",\n        ),\n        # NOTE: Valdi base should probably be moved to its own directory\n        \"_valdi_base\": attr.label(\n            doc = \"The base module that all Valdi modules depend on\",\n            default = \"@valdi//modules:valdi_base\",\n        ),\n        \"_template\": attr.label(\n            doc = \"The template config.yaml file\",\n            allow_single_file = True,\n            default = \"valdi_config.yaml.tpl\",\n        ),\n    },\n)\n\ndef _invoke_valdi_compiler(ctx, module_name, module_yaml):\n    \"\"\" Invoke valdi Compiler for the requested module.\n\n        This function takes care of reproducing the required directory structure which Valdi expects\n        (source files should live in subdirectories relative to where the config.yaml files lives, for example).\n\n    Args:\n        ctx: The context of the current rule invocation\n        module_name: The name of the module to compile\n\n    Returns:\n        A list of files that are produced by the Valdi compiler\n    \"\"\"\n\n    # Get command line flags\n    # Set on command line as:\n    # --define flag_name=\"flag_value\"\n    # Set in .bazelrc as:\n    # common --define flag_name=flag_value\n    module_upload_base_url = ctx.var.get(\"module_upload_base_url\")\n    enable_web = ctx.var.get(\"enable_web\")\n    disable_minify_web = ctx.var.get(\"disable_minify_web\", False)\n\n    #############\n    # 1. Generate the project config file that is currently required by the Valdi compiler.\n    #    The Valdi compiler uses the project config file location as the initial base directory\n    #    (the base_dir read from the config is then resolved relative to the project config file's location)\n    config_yaml_file = generate_config(ctx)\n\n    #############\n    # 2. Prepare the explicit input list file for the compiler.\n    (explicit_input_list_file, all_inputs, module_directory) = _prepare_explicit_input_list_file(ctx, module_yaml)\n\n    localization_mode = ctx.attr.localization_mode[BuildSettingInfo].value\n    js_bytecode_format = ctx.attr.js_bytecode_format[BuildSettingInfo].value\n\n    # Check if code coverage is enabled via `bazel coverage` command or explicit flag\n    code_coverage = ctx.configuration.coverage_enabled or ctx.attr.code_coverage[BuildSettingInfo].value\n\n    #############\n    # 3. Gather all outputs produced by the Valdi compiler\n    (base_output_dir, outputs) = _declare_compiler_outputs(ctx, module_name, module_directory, localization_mode, enable_web, code_coverage)\n\n    prepared_upload_artifact_file = None\n    if ctx.attr.prepared_upload_artifact_name:\n        prepared_upload_artifact_file = ctx.actions.declare_file(ctx.attr.prepared_upload_artifact_name)\n        outputs.append(prepared_upload_artifact_file)\n\n    #############\n    # 4. Prepare the Valdi compiler arguments\n    disable_downloadable_assets = not ctx.attr.downloadable_assets\n\n    valdi_copts = ctx.attr.valdi_copts\n\n    if module_upload_base_url:\n        # Make a mutable copy\n        valdi_copts = valdi_copts[:]\n        valdi_copts.append(\"--config-value\")\n        valdi_copts.append(\"module_upload_base_url={}\".format(module_upload_base_url))\n\n    args = _prepare_arguments(ctx.actions.args(), ctx.attr.log_level[BuildSettingInfo].value, localization_mode, js_bytecode_format, config_yaml_file, explicit_input_list_file, module_name, base_output_dir, disable_downloadable_assets, ctx.configuration.default_shell_env, prepared_upload_artifact_file, ctx.attr.inline_assets, valdi_copts, enable_web, disable_minify_web, code_coverage)\n\n    #############\n    # 5. Set up the action that executes the Valdi compiler\n\n    run_valdi_compiler(\n        ctx = ctx,\n        args = args,\n        outputs = outputs,\n        inputs = all_inputs + [config_yaml_file, explicit_input_list_file],\n        mnemonic = \"ValdiCompile\",\n        progress_message = \"Compiling Valdi module: \" + str(ctx.label),\n        use_worker = True,\n    )\n\n    return outputs\n\ndef _get_direct_dependencies(file, files, module_yaml):\n    \"\"\" Return a list of files that are direct dependencies of the current module.\n\n    Args:\n        file: The file struct from the ctx.attr object\n        files: The files struct from the ctx.attr object\n    \"\"\"\n    output_files = [module_yaml]\n\n    output_files += files.srcs\n    output_files += files.legacy_vue_srcs\n    output_files += files.legacy_style_srcs\n    output_files += files.protodecl_srcs\n    output_files += files.sql_srcs\n    output_files += files.strings_json_srcs\n    output_files += files.res\n\n    if file.ids_yaml:\n        output_files.append(file.ids_yaml)\n\n    return output_files\n\ndef _get_transitive_intermediates(deps):\n    return [dep[ValdiModuleInfo].intermediates for dep in deps]\n\ndef _resolve_valdi_base_entry(valdi_base_files, for_hotreloading):\n    all_files = []\n    tsconfig_file_entry = None\n    for e in valdi_base_files:\n        all_files.append(e)\n\n        if e.path.endswith(\"/tsconfig.json\"):\n            if tsconfig_file_entry:\n                fail(\"Found multiple tsconfig.json file in valdi_base target\")\n            tsconfig_file_entry = e\n\n    if not tsconfig_file_entry:\n        fail(\"Could not resolve tsconfig.json in valdi_base target\")\n    valdi_base_dir, _ = resolve_module_dir_and_name(tsconfig_file_entry.owner)\n\n    resolved_files = []\n    for e in all_files:\n        dep_path = e.path\n        relative_project_path = replace_prefix(dep_path, valdi_base_dir + \"/\", \"\")\n        if for_hotreloading:\n            dep_path = _resolve_hotreload_path(dep_path)[0]\n        resolved_files.append({\"file\": dep_path, \"relative_project_path\": relative_project_path})\n\n    module_definition = \"\"\"\nname: {}\n\nios:\n  output_target: release\n\nandroid:\n  output_target: release\n\nweb:\n  output_target: release\n\npath_prefix: ''\n\"\"\".format(_VALDI_BASE_MODULE_NAME)\n\n    if for_hotreloading:\n        valdi_base_dir = _resolve_hotreload_path(valdi_base_dir)[0]\n\n    return {\"module_name\": _VALDI_BASE_MODULE_NAME, \"module_path\": valdi_base_dir, \"files\": resolved_files, \"module_content\": module_definition}\n\ndef _prepare_explicit_input_list_file(ctx, module_yaml):\n    \"\"\" Write a JSON file with the list of all files that should be passed to the Valdi compiler. \"\"\"\n\n    direct_dependencies = _get_direct_dependencies(ctx.file, ctx.files, module_yaml)\n    transitive_dependencies = _get_transitive_intermediates(ctx.attr.deps)\n\n    dependencies = depset(direct = direct_dependencies, transitive = transitive_dependencies)\n    dependencies_list = dependencies.to_list()\n\n    json_entries = []\n    current_files = []\n    direct_module_directory = None\n    current_module_directory = None\n    current_module_name = None\n\n    json_entries.append(_resolve_valdi_base_entry(ctx.files._valdi_base, False))\n\n    for dep in dependencies_list:\n        dep_path = dep.path\n        file_name = paths.basename(dep_path)\n\n        if file_name == \"module.yaml\":\n            current_files = []\n\n            current_module_directory, current_module_name = resolve_module_dir_and_name(dep.owner)\n\n            if dep == module_yaml:\n                direct_module_directory = current_module_directory\n\n            scope_name = _get_module_scope(current_module_directory)\n            if scope_name:\n                current_module_name = current_module_name + scope_name\n\n            json_entries.append({\n                \"module_name\": current_module_name,\n                \"module_path\": current_module_directory,\n                \"files\": current_files,  # Subsequent files will append to that array reference\n            })\n\n        if not current_module_directory:\n            fail(\"First entry in the list should be a module.yaml. Got {}\".format(dep.path))\n        relative_project_path = resolve_relative_project_path(dep, current_module_name, current_module_directory)\n\n        current_files.append({\"file\": dep_path, \"relative_project_path\": relative_project_path})\n\n    if not direct_module_directory:\n        fail(\"Could not resolve module directory\")\n\n    explicit_input_list_file = ctx.actions.declare_file(\"explicit_input_list.json\")\n\n    content = json.encode_indent({\"entries\": json_entries}, indent = \"  \")\n    ctx.actions.write(output = explicit_input_list_file, content = content)\n\n    return (explicit_input_list_file, ctx.files._valdi_base + dependencies_list, direct_module_directory)\n\ndef _declare_compiler_outputs(ctx, module_name, module_directory, localization_mode, enable_web, code_coverage):\n    files_output_paths = _get_files_output_paths(ctx, module_name, module_directory, localization_mode, enable_web, code_coverage)\n    directories_output_paths = _get_directories_output_paths(ctx, code_coverage)\n    outputs = []\n    outputs += _declare_files(ctx, files_output_paths)\n    outputs += _declare_directories(ctx, directories_output_paths)\n\n    return (infer_base_output_dir(files_output_paths + directories_output_paths, outputs), outputs)\n\ndef _get_files_output_paths(ctx, module_name, module_directory, localization_mode, enable_web, code_coverage):\n    filtered_srcs = _get_compiled_srcs(ctx)\n    outputs = _get_srcs_dts_paths(filtered_srcs, module_name, module_directory)\n\n    if enable_web:\n        outputs += _get_srcs_js_paths(filtered_srcs + ctx.files.protodecl_srcs, module_name, module_directory, bool(ctx.files.res), bool(ctx.file.ids_yaml), bool(ctx.attr.strings_dir))\n        outputs += _get_srcs_vue_paths(ctx.files.legacy_vue_srcs, module_name, module_directory)\n\n    outputs += get_legacy_vue_srcs_dts_paths(ctx.files.legacy_vue_srcs, module_name, module_directory)\n\n    # When code coverage is enabled, the compiler only outputs debug builds\n    android_output_target = \"debug\" if code_coverage else ctx.attr.android_output_target\n    ios_output_target = \"debug\" if code_coverage else ctx.attr.ios_output_target\n\n    if _will_generate_valdimodule(ctx):\n        # Gather .valdimodule which are only generated if there are source files\n        outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_valdi_module_paths(module_name))\n        outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_valdi_module_paths(module_name))\n\n        # Gather .map.json, which are only generated if there are source files\n        # Note: sourcemaps are not generated when code coverage is enabled\n        if not code_coverage:\n            outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_valdi_module_map_paths(module_name))\n            outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_valdi_module_map_paths(module_name))\n\n    # Gather .c files (only if module has native exports)\n    if ctx.attr.has_android_exports:\n        outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_generated_native_src_paths(module_name))\n    if ctx.attr.has_ios_exports:\n        outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_generated_native_src_paths(ctx.attr.ios_module_name, module_name))\n\n    # tablename.d.ts files\n    outputs += get_sql_dts_paths(ctx.attr.sql_db_names, ctx.files.sql_srcs, module_name, module_directory)\n\n    # ids.d.ts\n    outputs += get_ids_yaml_dts_path(TYPESCRIPT_GENERATED_TS_DIR, module_name, ctx.file.ids_yaml)\n\n    # ids.xml\n    outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_ids_xml_paths(module_name, ctx.file.ids_yaml))\n\n    # Strings.d.ts\n    strings_json_srcs = ctx.files.strings_json_srcs\n    outputs += get_strings_dts_path(TYPESCRIPT_GENERATED_TS_DIR, module_name, strings_json_srcs)\n\n    if enable_web:\n        # Just debug for now\n        outputs = _append_debug_and_maybe_release(outputs, \"debug\", _get_web_string_resource_paths(module_name, strings_json_srcs, ctx.attr.strings_dir))\n\n    if localization_mode == \"external\":\n        # Android strings-xx.xml\n        outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_string_resource_paths(module_name, strings_json_srcs))\n\n        # iOS Localizable.strings\n        outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_string_resource_paths(module_name, strings_json_srcs))\n\n    # res.d.ts\n    outputs += get_resources_dts_paths(module_name, ctx.files.res)\n\n    if ctx.files.res and not ctx.attr.downloadable_assets and not ctx.attr.strip_assets and not ctx.attr.inline_assets:\n        basenames = _extract_image_resources_basenames(ctx.files.res)\n\n        outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_image_resources_paths(module_name, basenames))\n        outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_image_resources_paths(module_name, basenames))\n        if enable_web:\n            # Just debug for now\n            renamed_resources = _extract_renamed_resources(ctx.files.res)\n            outputs += _get_web_resource_paths(module_name, renamed_resources)[0]\n            outputs += _get_web_generated_resource_paths(module_name, outputs)\n\n    outputs.append(_get_dumped_compilation_metadata(module_name))\n\n    if ctx.attr.has_dependency_data:\n        outputs.append(_get_dependency_data_path(module_name))\n\n    if ctx.attr.single_file_codegen:\n        if ctx.attr.has_android_exports:\n            outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_generated_src(module_name))\n        if ctx.attr.has_ios_exports:\n            outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_generated_src(ctx.attr.ios_module_name, ctx.attr.ios_language))\n            outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_generated_api_src(ctx.attr.ios_module_name, ctx.attr.ios_language))\n\n        # C++ always outputs to release configuration\n        # However, when code coverage is enabled (--output-target debug), C++ outputs are not generated\n        if not code_coverage:\n            outputs += _get_cpp_generated_src(module_name)\n\n    # Add code coverage output file\n    if code_coverage:\n        outputs.append(\"coverage/files.json\")\n\n    return outputs\n\ndef _get_directories_output_paths(ctx, code_coverage):\n    outputs = []\n\n    # When code coverage is enabled, the compiler only outputs debug builds\n    android_output_target = \"debug\" if code_coverage else ctx.attr.android_output_target\n    ios_output_target = \"debug\" if code_coverage else ctx.attr.ios_output_target\n\n    # Android source maps.\n    # Note: sourcemap directories are not created when code coverage is enabled\n    if not code_coverage:\n        outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_source_map_dir())\n\n    # iOS generated sources. Debug is always generated\n    ios_module_name = ctx.attr.ios_module_name\n\n    if not ctx.attr.single_file_codegen:\n        # Android generated sources. Debug is always generated (only if module has Android exports)\n        if ctx.attr.has_android_exports:\n            outputs = _append_debug_and_maybe_release(outputs, android_output_target, _get_android_generated_src_dir())\n\n        # iOS generated sources (only if module has iOS exports)\n        if ctx.attr.has_ios_exports:\n            outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_generated_src_dir(ios_module_name))\n            outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_generated_api_src_dir(ios_module_name))\n\n        # C++ generated sources when single_file_codegen is disabled\n        # C++ always outputs to release configuration\n        # However, when code coverage is enabled (--output-target debug), C++ outputs are not generated\n        if not code_coverage:\n            outputs.append(_get_cpp_generated_src_dir())\n\n    # Ios source maps.\n    # Note: sourcemap directories are not created when code coverage is enabled\n    if not code_coverage:\n        outputs = _append_debug_and_maybe_release(outputs, ios_output_target, _get_ios_source_map_dir())\n\n    # iOS SQL assets used by Buck\n    if ctx.attr.sql_db_names:\n        outputs.append(paths.join(IOS_OUTPUT_BASE, ios_module_name, \"sql\"))\n\n    return outputs\n\ndef _will_generate_valdimodule(ctx):\n    \"\"\" Returns true if the module is expected to generate a .valdimodule file\n\n    Will be true if source code files are found, a source file is defined as any of .ts,\n    .tsx, .js, .vue, .sql, .sq, .sqm files.\n\n    Will be true if assets are found as well, as the module will end up having a res.js file\n    generated.\n\n    Args:\n        ctx: The context of the current rule invocation\n    \"\"\"\n    if len(ctx.files.res) > 0:\n        return True\n    valid_extensions = [\"tsx\", \"ts\", \"js\", \"vue\", \"sql\", \"sq\", \"sqm\"]\n    potential_sources = ctx.files.srcs + ctx.files.legacy_vue_srcs + ctx.files.sql_srcs\n    matching_files = [f for f in potential_sources if f.extension in valid_extensions and not f.basename.endswith(\".d.ts\")]\n\n    return len(matching_files) != 0\n\ndef _get_compiled_srcs(ctx):\n    return [src for src in ctx.files.srcs if src.basename != \"tsconfig.json\"]\n\ndef _get_srcs_dts_paths(srcs, module_name, module_directory):\n    return [\n        output_declaration_file_path_for_source_file(f, module_name, module_directory)\n        for f in srcs\n        if f.extension in [\"tsx\", \"ts\"] and not f.basename.endswith(\".d.ts\")\n    ]\n\ndef _get_srcs_js_paths(srcs, module_name, module_directory, has_resources, has_ids, has_strings):\n    out = []\n\n    for f in srcs:\n        if f.extension in [\"tsx\", \"ts\", \"js\"] and not f.basename.endswith(\".d.ts\") and not \".spec.\" in f.basename:\n            out.append(output_declaration_compiled_file_path_for_source_file(f, module_name, module_directory))\n\n    # Generated by the compiler but only if there are resources\n    if has_resources:\n        out.append(paths.join(\"web/debug/assets/\", module_name, \"res.js\"))\n\n    if has_ids:\n        out.append(paths.join(\"web/debug/assets/\", module_name, \"ids.js\"))\n\n    return out\n\ndef _get_srcs_vue_paths(srcs, module_name, module_directory):\n    out = []\n\n    for f in srcs:\n        if f.extension in [\"vue\"] and not f.basename.endswith(\".d.ts\"):\n            out.append(output_declaration_compiled_file_path_for_source_file(f, module_name, module_directory, replacement_suffix = \".vue.js\"))\n\n    return out\n\ndef _get_web_resource_paths(module_name, resources_basenames):\n    debug_res_dir, release_res_dir = _get_web_res_dir(\"debug\"), _get_web_res_dir(\"release\")\n    debug_images, release_images = [], []\n\n    for basename in resources_basenames:\n        debug_images.append(paths.join(debug_res_dir, module_name, \"res\", basename))\n        release_images.append(paths.join(release_res_dir, module_name, \"res\", basename))\n\n    return [debug_images, release_images]\n\ndef _get_web_generated_resource_paths(module_name, srcs):\n    out = []\n\n    for f in srcs:\n        if \"header.\" in f:\n            out.append(f)\n\n    return out\n\ndef _append_debug_and_maybe_release(lst, output_target, items_lst):\n    \"\"\" Append the debug and possible release item to the list.\n\n    Args:\n        lst: The list to append to\n        output_target: The output target to append to. Can be \"debug\" or \"release\"\n        items_lst: Array[2]: The array of size 2 where lst[0] is the debug item and lst[1] is the release item\n\n    Returns:\n        The new list with appended item(s)\n    \"\"\"\n    if output_target not in [\"debug\", \"release\"]:\n        fail(\"output_target should be either 'debug' or 'release'\")\n\n    if len(items_lst) != 2:\n        fail(\"items_lst should have exactly 2 items\")\n\n    def concat(lst, item):\n        if type(item) == \"list\":\n            return lst + item\n        else:\n            return lst + [item]\n\n    debug_item, release_item = items_lst\n\n    lst = concat(lst, debug_item)\n    if output_target == \"release\":\n        lst = concat(lst, release_item)\n    return lst\n\ndef _get_valdimodule_file_name(module_name):\n    return module_name + \".valdimodule\"\n\ndef _get_valdimodule_map_file_name(module_name):\n    return module_name + \".map.json\"\n\ndef _get_path_to_android_asset(output_target, asset_name):\n    return base_relative_dir(\"android\", output_target, paths.join(_ANDROID_ASSETS_DIR, asset_name))\n\ndef _get_android_valdi_module_paths(module_name):\n    return [\n        _get_path_to_android_asset(\"debug\", _get_valdimodule_file_name(module_name)),\n        _get_path_to_android_asset(\"release\", _get_valdimodule_file_name(module_name)),\n    ]\n\ndef _get_android_valdi_module_map_paths(module_name):\n    return [\n        _get_path_to_android_asset(\"debug\", _get_valdimodule_map_file_name(module_name)),\n        _get_path_to_android_asset(\"release\", _get_valdimodule_map_file_name(module_name)),\n    ]\n\ndef _get_android_generated_src_dir():\n    return [\n        base_relative_dir(\"android\", \"debug\", _ANDROID_GENERATED_SRC_DIR),\n        base_relative_dir(\"android\", \"release\", _ANDROID_GENERATED_SRC_DIR),\n    ]\n\ndef _get_android_generated_src(module_name):\n    file_path = paths.join(_ANDROID_GENERATED_SRC_DIR, \"{}.kt\".format(module_name))\n\n    return [\n        base_relative_dir(\"android\", \"debug\", file_path),\n        base_relative_dir(\"android\", \"release\", file_path),\n    ]\n\ndef _get_android_source_map_dir():\n    return [\n        base_relative_dir(\"android\", \"debug\", _ANDROID_SOURCE_MAPS_DIR),\n        base_relative_dir(\"android\", \"release\", _ANDROID_SOURCE_MAPS_DIR),\n    ]\n\ndef _get_native_module_filename(module_name):\n    return \"{}_native.c\".format(module_name)\n\ndef _get_android_generated_native_src_paths(module_name):\n    filename = _get_native_module_filename(module_name)\n\n    return [\n        base_relative_dir(\"android\", \"debug\", paths.join(_ANDROID_GENERATED_NATIVE_SRC_DIR, filename)),\n        base_relative_dir(\"android\", \"release\", paths.join(_ANDROID_GENERATED_NATIVE_SRC_DIR, filename)),\n    ]\n\ndef _get_web_generated_js_paths(module_name):\n    return [\n        base_relative_dir(\"web\", \"debug\", \"assets\", module_name, \"src\"),\n        base_relative_dir(\"web\", \"release\", \"assets\", module_name, \"src\"),\n    ]\n\ndef _get_ios_generated_native_src_paths(ios_module_name, module_name):\n    filename = _get_native_module_filename(module_name)\n\n    return [\n        base_relative_dir(\"ios\", \"debug\", paths.join(_IOS_GENERATED_NATIVE_SRC_DIR, ios_module_name, filename)),\n        base_relative_dir(\"ios\", \"release\", paths.join(_IOS_GENERATED_NATIVE_SRC_DIR, ios_module_name, filename)),\n    ]\n\ndef _get_android_res_dir(output_target):\n    return base_relative_dir(\"android\", output_target, _ANDROID_RESOURCES_DIR)\n\ndef _get_web_res_dir(output_target):\n    return base_relative_dir(\"web\", output_target, _WEB_RESOURCES_DIR)\n\ndef _get_ios_generated_src_dir(ios_module_name):\n    return [\n        base_relative_dir(\"ios\", \"debug\", paths.join(_IOS_GENERATED_SRC_DIR, ios_module_name)),\n        base_relative_dir(\"ios\", \"release\", paths.join(_IOS_GENERATED_SRC_DIR, ios_module_name)),\n    ]\n\ndef _get_ios_generated_api_src_dir(ios_module_name):\n    return [\n        base_relative_dir(\"ios\", \"debug\", paths.join(_IOS_GENERATED_SRC_DIR, ios_module_name + IOS_API_NAME_SUFFIX)),\n        base_relative_dir(\"ios\", \"release\", paths.join(_IOS_GENERATED_SRC_DIR, ios_module_name + IOS_API_NAME_SUFFIX)),\n    ]\n\ndef _get_ios_generated_src_helper(output_target, ios_module_name, suffix, ext):\n    return base_relative_dir(\"ios\", output_target, paths.join(_IOS_GENERATED_SRC_DIR, ios_module_name + suffix, \"{}.{}\".format(ios_module_name + suffix, ext)))\n\ndef _get_ios_generated_src(ios_module_name, ios_language = [\"objc\"]):\n    debug_srcs = [\n        _get_ios_generated_src_helper(\"debug\", ios_module_name, \"\", \"h\"),\n        _get_ios_generated_src_helper(\"debug\", ios_module_name, \"\", \"m\"),\n    ]\n\n    release_srcs = [\n        _get_ios_generated_src_helper(\"release\", ios_module_name, \"\", \"h\"),\n        _get_ios_generated_src_helper(\"release\", ios_module_name, \"\", \"m\"),\n    ]\n\n    if \"swift\" in ios_language:\n        debug_srcs.append(_get_ios_generated_src_helper(\"debug\", ios_module_name, \"\", \"swift\"))\n        release_srcs.append(_get_ios_generated_src_helper(\"release\", ios_module_name, \"\", \"swift\"))\n\n    return [debug_srcs, release_srcs]\n\ndef _get_ios_generated_api_src(ios_module_name, ios_language = [\"objc\"]):\n    debug_srcs = [\n        _get_ios_generated_src_helper(\"debug\", ios_module_name, IOS_API_NAME_SUFFIX, \"h\"),\n        _get_ios_generated_src_helper(\"debug\", ios_module_name, IOS_API_NAME_SUFFIX, \"m\"),\n    ]\n\n    release_srcs = [\n        _get_ios_generated_src_helper(\"release\", ios_module_name, IOS_API_NAME_SUFFIX, \"h\"),\n        _get_ios_generated_src_helper(\"release\", ios_module_name, IOS_API_NAME_SUFFIX, \"m\"),\n    ]\n\n    if \"swift\" in ios_language:\n        debug_srcs.append(_get_ios_generated_src_helper(\"debug\", ios_module_name, IOS_API_NAME_SUFFIX, \"swift\"))\n        release_srcs.append(_get_ios_generated_src_helper(\"release\", ios_module_name, IOS_API_NAME_SUFFIX, \"swift\"))\n\n    return [debug_srcs, release_srcs]\n\ndef _get_cpp_generated_src_dir():\n    \"\"\"Get C++ generated source directory for multi-file codegen mode.\n\n    C++ codegen always outputs to release configuration.\n    \"\"\"\n    return base_relative_dir(\"cpp\", \"release\", \"src\")\n\ndef _get_cpp_generated_src(module_name):\n    \"\"\"Get C++ generated source file paths for single_file_codegen mode.\n\n    C++ codegen always outputs to release configuration.\n    \"\"\"\n    return [\n        base_relative_dir(\"cpp\", \"release\", \"src/valdi_modules/{}/{}.hpp\".format(module_name, module_name)),\n        base_relative_dir(\"cpp\", \"release\", \"src/valdi_modules/{}/{}.cpp\".format(module_name, module_name)),\n    ]\n\ndef _get_ios_source_map_dir():\n    return [\n        base_relative_dir(\"ios\", \"debug\", _IOS_SOURCE_MAPS_DIR),\n        base_relative_dir(\"ios\", \"release\", _IOS_SOURCE_MAPS_DIR),\n    ]\n\ndef _get_path_to_ios_asset(output_target, asset_name):\n    return base_relative_dir(\"ios\", output_target, paths.join(_IOS_ASSETS_DIR, asset_name))\n\ndef _get_ios_valdi_module_paths(module_name):\n    return [\n        _get_path_to_ios_asset(\"debug\", _get_valdimodule_file_name(module_name)),\n        _get_path_to_ios_asset(\"release\", _get_valdimodule_file_name(module_name)),\n    ]\n\ndef _get_ios_valdi_module_map_paths(module_name):\n    return [\n        _get_path_to_ios_asset(\"debug\", _get_valdimodule_map_file_name(module_name)),\n        _get_path_to_ios_asset(\"release\", _get_valdimodule_map_file_name(module_name)),\n    ]\n\ndef _get_ios_strings_dir(output_target):\n    return base_relative_dir(\"ios\", output_target, \"strings\")\n\ndef _get_web_strings_dir(output_target):\n    return base_relative_dir(\"web\", output_target, \"strings\")\n\ndef _get_ios_bundle_dir(module_name, output_target):\n    return base_relative_dir(\"ios\", output_target, paths.join(_IOS_ASSETS_DIR, module_name + \".bundle\"))\n\ndef _get_ios_debug_sourcemap_path(ios_module_name):\n    return base_relative_dir(\"ios\", \"debug\", paths.join(_IOS_ASSETS_DIR, _get_valdimodule_map_file_name(ios_module_name)))\n\ndef _get_android_debug_sourcemap_path(android_module_name):\n    return base_relative_dir(\"android\", \"debug\", paths.join(_ANDROID_ASSETS_DIR, _get_valdimodule_map_file_name(android_module_name)))\n\ndef _get_android_ids_xml_paths(module_name, ids_yaml):\n    if not ids_yaml:\n        return ([], [])\n\n    ids_xml_name = \"{}_ids.xml\".format(module_name)\n\n    return [\n        paths.join(_get_android_res_dir(\"debug\"), \"values\", ids_xml_name),\n        paths.join(_get_android_res_dir(\"release\"), \"values\", ids_xml_name),\n    ]\n\ndef _get_android_string_resource_paths(module_name, strings_srcs):\n    debug_dir, release_dir = _get_android_res_dir(\"debug\"), _get_android_res_dir(\"release\")\n\n    # This has to match exportStringsFiles.ts#androidStringsXMLName in the companion\n    strings_xml_name = \"valdi-strings-{}.xml\".format(module_name)\n\n    debug_strings_xmls, release_strings_xml = [], []\n    strings_jsons_names = [paths.basename(s.path) for s in strings_srcs]\n    for strings_json in strings_jsons_names:\n        (_, android_values_dir) = supported_langs_mapping[strings_json]\n\n        debug_strings_xmls.append(paths.join(debug_dir, android_values_dir, strings_xml_name))\n        release_strings_xml.append(paths.join(release_dir, android_values_dir, strings_xml_name))\n\n    return [debug_strings_xmls, release_strings_xml]\n\ndef _get_ios_string_resource_paths(module_name, strings_srcs):\n    debug_strings_dir, release_strings_dir = _get_ios_strings_dir(\"debug\"), _get_ios_strings_dir(\"release\")\n\n    # This has to match exportStringsFiles.ts#iosLocalizableStringName in the companion\n    string_resource_name = \"valdi_modules_{}.strings\".format(module_name)\n\n    debug_strings, release_strings = [], []\n    strings_jsons_names = [paths.basename(s.path) for s in strings_srcs]\n    for strings_json in strings_jsons_names:\n        (ios_values_dir, _) = supported_langs_mapping[strings_json]\n\n        debug_strings.append(paths.join(debug_strings_dir, ios_values_dir, string_resource_name))\n        release_strings.append(paths.join(release_strings_dir, ios_values_dir, string_resource_name))\n\n    return [debug_strings, release_strings]\n\ndef _get_web_string_resource_paths(module_name, strings_srcs, strings_dir):\n    debug_strings_dir, release_strings_dir = _get_web_strings_dir(\"debug\"), _get_web_strings_dir(\"release\")\n\n    # This has to match exportStringsFiles.ts#iosLocalizableStringName in the companion\n    string_resource_name = \"valdi_modules_{}.strings\".format(module_name)\n\n    debug_strings, release_strings = [], []\n    strings_jsons_names = [paths.basename(s.path) for s in strings_srcs]\n    for strings_json in strings_jsons_names:\n        (ios_values_dir, _) = supported_langs_mapping[strings_json]\n\n        debug_strings.append(paths.join(\"web\", \"debug\", \"assets\", module_name, strings_dir, strings_json))\n        release_strings.append(paths.join(\"web\", \"release\", \"assets\", module_name, strings_dir, strings_json))\n\n    # Grab the generated files if they exist\n    if strings_dir:\n        debug_strings.append(paths.join(\"web\", \"debug\", \"assets\", module_name, \"src\", \"Strings.js\"))\n        release_strings.append(paths.join(\"web\", \"release\", \"assets\", module_name, \"src\", \"Strings.js\"))\n    return [debug_strings, release_strings]\n\ndef _is_image_ext(ext):\n    return ext in [\".png\", \".webp\", \".svg\", \".jpg\", \".jpeg\"]\n\ndef _clean_image_file_name(root):\n    basename = paths.basename(root).replace(\"-\", \"_\")\n    if \"@2x\" in basename:\n        basename = basename.replace(\"@2x\", \"\")\n    if \"@3x\" in basename:\n        basename = basename.replace(\"@3x\", \"\")\n\n    return basename\n\ndef _extract_image_resources_basenames(resources):\n    result = []\n    for resource in resources:\n        root, ext = paths.split_extension(resource.path)\n        if not _is_image_ext(ext):\n            continue\n\n        basename = _clean_image_file_name(root)\n\n        result.append(basename)\n\n    return result\n\ndef _extract_renamed_resources(resources):\n    result = []\n    for resource in resources:\n        root, ext = paths.split_extension(resource.path)\n        if not _is_image_ext(ext):\n            continue\n\n        basename = _clean_image_file_name(root)\n\n        web_ext = ext.replace(\"svg\", \"png\")\n        web_name = \"{}{}\".format(basename, web_ext)\n\n        # This will break if there's a res/res/ folder\n        subfolder = resource.path.split(\"res/\", 1)[1] if \"/res/\" in resource.path else \"\"\n\n        result.append(paths.join(paths.dirname(subfolder), web_name))\n    return result\n\ndef _get_android_image_resources_paths(module_name, resources_basenames):\n    debug_res_dir, release_res_dir = _get_android_res_dir(\"debug\"), _get_android_res_dir(\"release\")\n    debug_images, release_images = [], []\n    for basename in resources_basenames:\n        # All files end up being converted into webp\n        resource_name = \"{}_{}.webp\".format(module_name, basename)\n\n        for variant in ANDROID_RESOURCE_VARIANT_DIRECTORIES:\n            debug_images.append(paths.join(debug_res_dir, variant, resource_name))\n            release_images.append(paths.join(release_res_dir, variant, resource_name))\n\n    if len(resources_basenames):\n        keep_filename = \"valdi_{}_keep.xml\".format(module_name)\n        debug_images.append(paths.join(debug_res_dir, \"raw\", keep_filename))\n        release_images.append(paths.join(release_res_dir, \"raw\", keep_filename))\n\n    return [debug_images, release_images]\n\ndef _get_ios_image_resources_paths(module_name, resources_basenames):\n    debug_bundle_dir, release_bundle_dir = _get_ios_bundle_dir(module_name, \"debug\"), _get_ios_bundle_dir(module_name, \"release\")\n\n    debug_images, release_images = [], []\n    for basename in resources_basenames:\n        # All files end up being converted into png\n        resources = [\n            \"{}@2x.png\".format(basename),\n            \"{}@3x.png\".format(basename),\n        ]\n\n        for resource_name in resources:\n            debug_images.append(paths.join(debug_bundle_dir, resource_name))\n            release_images.append(paths.join(release_bundle_dir, resource_name))\n\n    return [debug_images, release_images]\n\ndef _get_dumped_compilation_metadata(module_name):\n    return paths.join(TYPESCRIPT_DUMPED_SYMBOLS_DIR, module_name, \"compilation-metadata.json\")\n\ndef _get_dependency_data_path(module_name):\n    return base_relative_dir(\"ios\", \"metadata\", \"dependencyData.json\")\n\ndef _declare_files(ctx, paths):\n    return [ctx.actions.declare_file(path) for path in paths]\n\ndef _declare_directories(ctx, paths):\n    return [ctx.actions.declare_directory(path) for path in paths]\n\ndef _prepare_arguments(args, log_level, localization_mode, js_bytecode_format, config_yaml_file, explicit_input_list_file, module_name, base_output_dir, disable_downloadable_assets, shell_env, prepared_upload_artifact_file, inline_assets, additional_copts, enable_web, disable_minify_web, code_coverage):\n    \"\"\" Prepare arguments for the Valdi compiler invocation. \"\"\"\n\n    args.use_param_file(\"@%s\", use_always = True)\n    args.set_param_file_format(\"multiline\")\n\n    args.add(\"--config\", config_yaml_file)\n    args.add(\"--explicit-input-list-file\", explicit_input_list_file)\n\n    args.add(\"--build-dir\", paths.join(\"$PWD\", base_output_dir, BUILD_DIR))\n\n    args.add(\"--module\", module_name)\n    args.add(\"--module\", _VALDI_BASE_MODULE_NAME)\n    args.add(\"--output-dumped-symbols-dir\", paths.join(explicit_input_list_file.dirname, TYPESCRIPT_DUMPED_SYMBOLS_DIR))\n\n    args.add(\"--only-compile-ts-for-module\", module_name)\n    args.add(\"--only-process-resources-for-module\", module_name)\n    args.add(\"--only-generate-native-code-for-module\", module_name)\n    args.add(\"--only-focus-processing-for-module\", module_name)\n    args.add(\"--ts-emit-declaration-files\")\n    args.add(\"--ts-keep-comments\")\n\n    if localization_mode == \"inline\":\n        args.add(\"--inline-translations\")\n\n    if code_coverage:\n        args.add(\"--code-coverage\")\n\n        # Force compiler to only generate debug outputs when code coverage is enabled\n        args.add(\"--output-target\", \"debug\")\n\n    # args.add(\"--ts-skip-verifying-imports\")\n    args.add(\"--disable-disk-cache\")\n    args.add(\"--skip-remove-orphan-files\")\n\n    args.add(\"--log-level\", log_level)\n    args.add(\"--compile\")\n    args.add(\"--android\")\n    args.add(\"--ios\")\n\n    if enable_web:\n        args.add(\"--web\")\n        if disable_minify_web:\n            args.add(\"--disable-minify-web\")\n\n    # Allow to pass the timeout via --action_env parameter\n    args.add(\"--timeout\", shell_env.get(\"VALDI_COMPILER_TIMEOUT_SECONDS\", COMPILER_TIMEOUT_SECONDS))\n\n    # Disable concurrency, to free CPU cores to do the actual build.\n    # Valdi compiler is fast enough to keep up with Bazel parallelization.\n    args.add(\"--disable-concurrency\")\n\n    if prepared_upload_artifact_file:\n        args.add(\"--prepared-upload-artifact-output\", prepared_upload_artifact_file.path)\n\n    # Configure compilation\n    # TODO: should we create a Bazel rule for this configuration?\n    args.add(\"--config-value\", \"build_dir=\" + explicit_input_list_file.dirname)\n    args.add(\"--config-value\", \"project_name=\" + module_name)\n    args.add(\"--config-value\", \"build_file_generation_enabled=false\")\n\n    # Android\n    args.add(\"--config-value\", \"android.codegen_enabled=true\")\n    args.add(\"--config-value\", \"android.output.base={}\".format(paths.join(\"$PWD\", base_output_dir, \"android\")))\n    args.add(\"--config-value\", \"android.output.debug_path=debug\")\n    args.add(\"--config-value\", \"android.output.release_path=release\")\n    args.add(\"--config-value\", \"android.output.metadata_path=.\")\n    args.add(\"--config-value\", \"android.output.build_file_enabled=false\")\n    if js_bytecode_format != \"none\":\n        args.add(\"--config-value\", \"android.js_bytecode_format={}\".format(js_bytecode_format))\n\n    # iOS\n    args.add(\"--config-value\", \"ios.codegen_enabled=true\")\n    args.add(\"--config-value\", \"ios.default_module_name_prefix=\" + IOS_DEFAULT_MODULE_NAME_PREFIX)\n    args.add(\"--config-value\", \"ios.output.base={}\".format(paths.join(\"$PWD\", base_output_dir, \"ios\")))\n    args.add(\"--config-value\", \"ios.output.debug_path=debug\")\n    args.add(\"--config-value\", \"ios.output.release_path=release\")\n    args.add(\"--config-value\", \"ios.output.metadata_path=metadata\")\n    args.add(\"--config-value\", \"ios.output.build_file_enabled=false\")\n\n    # C++\n    args.add(\"--config-value\", \"cpp.codegen_enabled=true\")\n    args.add(\"--config-value\", \"cpp.output.base={}\".format(paths.join(\"$PWD\", base_output_dir, \"cpp\")))\n    args.add(\"--config-value\", \"cpp.output.debug_path=debug\")\n    args.add(\"--config-value\", \"cpp.output.release_path=release\")\n    args.add(\"--config-value\", \"cpp.output.metadata_path=.\")\n\n    # Web\n    if enable_web:\n        args.add(\"--config-value\", \"web.output.base={}\".format(paths.join(\"$PWD\", base_output_dir, \"web\")))\n        args.add(\"--config-value\", \"web.output.debug_path=debug\")\n        args.add(\"--config-value\", \"web.output.release_path=release\")\n        args.add(\"--config-value\", \"web.output.metadata_path=metadata\")\n\n    # Code Coverage\n    if code_coverage:\n        args.add(\"--config-value\", \"instrumented_files_result={}\".format(\n            paths.join(\"$PWD\", base_output_dir, \"coverage/files.json\"),\n        ))\n\n    if disable_downloadable_assets:\n        args.add(\"--disable-downloadable-modules\")\n\n    if inline_assets:\n        args.add(\"--inline-assets\")\n\n        # Limit to only the highest variant, mostly to limit valdimodule size, we don't need\n        # more at the moment.\n        args.add(\"--image-variants-filter\", \"android=4.0;ios=3.0\")\n\n    for additional_copt in additional_copts:\n        args.add(additional_copt)\n\n    return args\n\ndef _compress_generated_android_srcs(ctx, module_name, outputs, code_coverage):\n    \"\"\" Compress the generated Android sources into .srcjar files.\n\n    Args:\n        ctx: The context of the current rule invocation\n        module_name: The name of the module to compile\n        outputs(List[File]): The list of outputs produce by the Valdi compiler\n        code_coverage: Whether code coverage is enabled (only debug outputs when true)\n    \"\"\"\n    result = []\n\n    debug_path, release_path = _get_android_generated_src_dir()\n    directories = [f for f in outputs if f.is_directory]\n\n    # Debug directory is always present\n    debug_dir = [d for d in directories if d.path.endswith(debug_path)][0]\n\n    # TODO: perhaps we should let compiler generate srcjars for us?\n    debug_srcjar = ctx.actions.declare_file(\"{}.debug.srcjar\".format(module_name))\n    _zip_dir(ctx, debug_dir, debug_srcjar)\n    result.append(debug_srcjar)\n\n    # Only create release srcjar if we're building for release AND code coverage is not enabled\n    # (code coverage only generates debug outputs)\n    if ctx.attr.android_output_target == \"release\" and not code_coverage:\n        release_dir = [d for d in directories if d.path.endswith(release_path)][0]\n        release_srcjar = ctx.actions.declare_file(\"{}.release.srcjar\".format(module_name))\n        _zip_dir(ctx, release_dir, release_srcjar)\n        result.append(release_srcjar)\n\n    return result\n\ndef _zip_dir(ctx, in_dir, out_file):\n    \"\"\" Create a zip archive of a directory and store the result in the provided file.\n\n    Note:\n        @bazel_tools//tools/zip:zipper can't be used here because it doesn't support recursive zipping\n    \"\"\"\n    ctx.actions.run_shell(\n        outputs = [out_file],\n        inputs = [in_dir],\n        # Set all file and directory timestamps to a fixed value before zipping for reproducibility.\n        # 199609240000 = 1996-09-24 00:00 (arbitrary, but fixed)\n        command = \"\"\"\nfind {in_dir} -exec touch -t 199609240000 {{}} +\nzip -qr {out_file} {in_dir}\n\"\"\".format(in_dir = in_dir.path, out_file = out_file.path),\n        progress_message = \"Zipping {in_dir} into {out_file}\".format(in_dir = in_dir.path, out_file = out_file.path),\n        mnemonic = \"ValdiCompileZipDir\",\n    )\n\ndef _generate_module_definition(ctx, name):\n    attr = ctx.attr\n\n    dependencies_str = \"\\n\".join([\"  - {}\".format(dep[ValdiModuleInfo].name) for dep in attr.deps])\n\n    # When global code coverage is enabled, force ALL modules (even those with disable_code_coverage=true)\n    # to build in debug mode to maintain dependency consistency\n    # Check if code coverage is enabled via `bazel coverage` command or explicit flag\n    code_coverage = ctx.configuration.coverage_enabled or ctx.attr.code_coverage[BuildSettingInfo].value\n    android_output_target = \"debug\" if code_coverage else attr.android_output_target\n    ios_output_target = \"debug\" if code_coverage else attr.ios_output_target\n\n    ios_language_str = \",\".join(attr.ios_language)\n\n    module_def = \"\"\"\nname: {name}\n\nios:\n  output_target: {ios_output_target}\n  module_name: {ios_module_name}\n  language: {ios_language}\n\nandroid:\n  output_target: {android_output_target}\n  {android_class_path}\n  export_strings: {android_export_strings}\n\nweb:\n  output_target: release\n\nsingle_file_codegen: {single_file_codegen}\n\nallowed_debug_dependencies:\n{dependencies_str}\n\ndisable_code_coverage: {disable_code_coverage}\ndisable_hotreload: {disable_hotreload}\ndisable_annotation_processing: {disable_annotation_processing}\ndisable_dependency_verification: {disable_dependency_verification}\nasync_strict_mode: {async_strict_mode}\n\n{exclude_patterns}\n{exclude_globs}\n\ncompilation_mode: {compilation_mode}\n  \"\"\".format(\n        name = name,\n        ios_output_target = ios_output_target,\n        ios_module_name = attr.ios_module_name,\n        ios_language = ios_language_str,\n        android_output_target = android_output_target,\n        android_export_strings = \"true\" if attr.android_export_strings else \"false\",\n        compilation_mode = attr.compilation_mode,\n        single_file_codegen = \"true\" if attr.single_file_codegen else \"false\",\n        disable_code_coverage = \"true\" if attr.disable_code_coverage else \"false\",\n        disable_hotreload = \"true\" if attr.disable_hotreload else \"false\",\n        disable_annotation_processing = \"true\" if attr.disable_annotation_processing else \"false\",\n        disable_dependency_verification = \"true\" if attr.disable_dependency_verification else \"false\",\n        async_strict_mode = \"true\" if attr.async_strict_mode else \"false\",\n        dependencies_str = dependencies_str,\n        android_class_path = \"class_path: {}\".format(attr.android_class_path) if attr.android_class_path else \"\",\n        exclude_patterns = _yaml_named_list(\"exclude_patterns\", attr.exclude_patterns),\n        exclude_globs = _yaml_named_list(\"exclude_globs\", attr.exclude_globs),\n    )\n\n    if attr.strings_dir:\n        module_def += \"\\nstrings_dir: {}\".format(attr.strings_dir)\n\n    return module_def\n\ndef _yaml_named_list(name, items):\n    if not items:\n        return \"\"\n\n    list = \"\\n\".join([\"  - {item}\".format(item = item) for item in items])\n\n    return \"{name}:\\n{list}\".format(name = name, list = list)\n\ndef _resolve_module_yaml(ctx, module_name):\n    module_definition = _generate_module_definition(ctx, module_name)\n\n    # When code coverage is enabled, always generate a new module.yaml with debug output targets\n    # even if the module has its own module.yaml file, because we need to override output_target\n    # Check if code coverage is enabled via `bazel coverage` command or explicit flag\n    code_coverage = ctx.configuration.coverage_enabled or ctx.attr.code_coverage[BuildSettingInfo].value\n\n    if ctx.file.module_yaml and not code_coverage:\n        return (ctx.file.module_yaml, module_definition)\n    else:\n        module_yaml = ctx.actions.declare_file(\"module.yaml\")\n        ctx.actions.write(output = module_yaml, content = module_definition)\n        return (module_yaml, module_definition)\n\ndef _create_valdi_module_info(ctx, module_name, module_yaml, module_definition, outputs, code_coverage):\n    in_declarations = _extract_dts_files(_get_compiled_srcs(ctx))\n    out_declarations = _extract_dts_files(outputs)\n    dumped_compilation_metadata = _extract_dumped_compilation_metadata(outputs)\n    ios_module_name = ctx.attr.ios_module_name\n    has_valdimodule = _will_generate_valdimodule(ctx)\n\n    # When code coverage is enabled, only debug outputs are generated (no release)\n    is_android_release = ctx.attr.android_output_target == \"release\" and not code_coverage\n    is_ios_release = ctx.attr.ios_output_target == \"release\" and not code_coverage\n\n    # The order matter here. It should always starts with module_yaml\n    direct_intermediates = [module_yaml] + in_declarations + out_declarations + ctx.files.legacy_style_srcs + dumped_compilation_metadata\n\n    base_path = paths.join(ctx.label.workspace_root, ctx.label.package)\n    single_file_codegen = ctx.attr.single_file_codegen\n\n    return ValdiModuleInfo(\n        # Depsets to enable other modules compilation\n        name = module_name,\n        intermediates = depset(direct = direct_intermediates, transitive = _get_transitive_intermediates(ctx.attr.deps)),\n        module_definition = module_definition,\n        base_path = base_path,\n        deps = depset(direct = ctx.attr.deps, transitive = [d[ValdiModuleInfo].deps for d in ctx.attr.deps]),\n        disable_annotation_processing = ctx.attr.disable_annotation_processing,\n        async_strict_mode = ctx.attr.async_strict_mode,\n\n        # Prepared upload artifact\n        prepared_upload_artifact = _extract_prepared_upload_artifact(ctx.attr.prepared_upload_artifact_name, outputs) if ctx.attr.prepared_upload_artifact_name else None,\n\n        # Android outputs\n        android_debug_resource_files = depset(_extract_android_resources(\"debug\", outputs)),\n        android_release_resource_files = depset(_extract_android_resources(\"release\", outputs)),\n        android_debug_valdimodule = _extract_valdi_module_android(\"debug\", module_name, outputs) if has_valdimodule else None,\n        android_release_valdimodule = _extract_valdi_module_android(\"release\", module_name, outputs) if has_valdimodule and is_android_release else None,\n        android_debug_srcjar = _extract_android_srcjar(\"debug\", module_name, single_file_codegen, outputs) if ctx.attr.has_android_exports else None,\n        android_release_srcjar = _extract_android_srcjar(\"release\", module_name, single_file_codegen, outputs) if is_android_release and ctx.attr.has_android_exports else None,\n        android_debug_nativesrc = _extract_android_native_srcs(\"debug\", module_name, outputs) if ctx.attr.has_android_exports else None,\n        android_release_nativesrc = _extract_android_native_srcs(\"release\", module_name, outputs) if is_android_release and ctx.attr.has_android_exports else None,\n        android_debug_sourcemaps = _extract_android_debug_sourcemaps(module_name, outputs) if has_valdimodule and not code_coverage else None,\n        android_debug_sourcemap_archive = _extract_android_sourcemap_archive(\"debug\", outputs) if has_valdimodule and not code_coverage else None,\n        android_release_sourcemap_archive = _extract_android_sourcemap_archive(\"release\", outputs) if has_valdimodule and not code_coverage else None,\n\n        # iOS outputs\n        ios_module_name = ios_module_name,\n        ios_debug_valdimodule = _extract_valdi_module_ios(\"debug\", module_name, outputs) if has_valdimodule else None,\n        ios_release_valdimodule = _extract_valdi_module_ios(\"release\", module_name, outputs) if has_valdimodule and is_ios_release else None,\n        ios_debug_resource_files = depset(_extract_ios_unstructured_resources(\"debug\", outputs)),\n        ios_release_resource_files = depset(_extract_ios_unstructured_resources(\"release\", outputs)),\n        ios_debug_bundle_resources = depset(_extract_ios_resource_bundles(module_name, \"debug\", outputs)),\n        ios_release_bundle_resources = depset(_extract_ios_resource_bundles(module_name, \"release\", outputs)),\n        ios_debug_generated_hdrs = _extract_ios_generated_hdrs(\"debug\", outputs, ios_module_name) if single_file_codegen and ctx.attr.has_ios_exports else None,\n        ios_debug_generated_srcs = _extract_ios_generated_srcs(\"debug\", outputs, ios_module_name, single_file_codegen, ctx.attr.ios_language) if ctx.attr.has_ios_exports else None,\n        ios_release_generated_hdrs = _extract_ios_generated_hdrs(\"release\", outputs, ios_module_name) if single_file_codegen and ctx.attr.has_ios_exports else None,\n        ios_release_generated_srcs = _extract_ios_generated_srcs(\"release\", outputs, ios_module_name, single_file_codegen, ctx.attr.ios_language) if ctx.attr.has_ios_exports else None,\n        ios_debug_api_generated_hdrs = _extract_ios_api_generated_hdrs(\"debug\", outputs, ios_module_name) if single_file_codegen and ctx.attr.has_ios_exports else None,\n        ios_debug_api_generated_srcs = _extract_ios_api_generated_srcs(\"debug\", outputs, ios_module_name, single_file_codegen, ctx.attr.ios_language) if ctx.attr.has_ios_exports else None,\n        ios_release_api_generated_hdrs = _extract_ios_api_generated_hdrs(\"release\", outputs, ios_module_name) if single_file_codegen and ctx.attr.has_ios_exports else None,\n        ios_release_api_generated_srcs = _extract_ios_api_generated_srcs(\"release\", outputs, ios_module_name, single_file_codegen, ctx.attr.ios_language) if ctx.attr.has_ios_exports else None,\n        ios_debug_generated_swift_srcs = _extract_ios_generated_swift_srcs(\"debug\", outputs, ios_module_name, ctx.attr.ios_language) if single_file_codegen and ctx.attr.has_ios_exports else None,\n        ios_release_generated_swift_srcs = _extract_ios_generated_swift_srcs(\"release\", outputs, ios_module_name, ctx.attr.ios_language) if single_file_codegen and ctx.attr.has_ios_exports else None,\n        ios_debug_api_generated_swift_srcs = _extract_ios_api_generated_swift_srcs(\"debug\", outputs, ios_module_name, ctx.attr.ios_language) if single_file_codegen and ctx.attr.has_ios_exports else None,\n        ios_release_api_generated_swift_srcs = _extract_ios_api_generated_swift_srcs(\"release\", outputs, ios_module_name, ctx.attr.ios_language) if single_file_codegen and ctx.attr.has_ios_exports else None,\n        ios_debug_nativesrc = _extract_ios_native_srcs(\"debug\", ios_module_name, module_name, outputs) if ctx.attr.has_ios_exports else None,\n        ios_release_nativesrc = _extract_ios_native_srcs(\"release\", ios_module_name, module_name, outputs) if is_ios_release and ctx.attr.has_ios_exports else None,\n        ios_debug_sourcemaps = _extract_ios_debug_sourcemaps(module_name, outputs) if has_valdimodule and not code_coverage else None,\n        ios_debug_sourcemap_archive = _extract_ios_sourcemap_archive(\"debug\", outputs) if has_valdimodule and not code_coverage else None,\n        ios_release_sourcemap_archive = _extract_ios_sourcemap_archive(\"release\", outputs) if has_valdimodule and not code_coverage else None,\n        ios_sql_assets = _extract_ios_sql_assets(ios_module_name, outputs),\n        ios_dependency_data = _extract_ios_dependency_data(outputs),\n\n        # C++ outputs (always in release configuration)\n        # However, when code coverage is enabled (--output-target debug), C++ outputs are not generated\n        cpp_srcs = _extract_cpp_generated_srcs(outputs, module_name, single_file_codegen) if not code_coverage else None,\n        cpp_hdrs = _extract_cpp_generated_hdrs(outputs, module_name, single_file_codegen) if not code_coverage else None,\n\n        # web outputs\n        protodecl_srcs = ctx.files.protodecl_srcs,\n        web_debug_sources = _extract_js_files(module_name, \"debug\", outputs),\n        web_release_sources = _extract_js_files(module_name, \"release\", outputs),\n        web_debug_resource_files = _extract_web_resources(\"debug\", outputs),\n        web_release_resource_files = _extract_web_resources(\"release\", outputs),\n        web_debug_strings = _extract_web_strings(\"debug\", outputs),\n        web_release_strings = _extract_web_strings(\"release\", outputs),\n        web_deps = _extract_npm_package_files(ctx.attr.web_deps),\n        web_dts_files = in_declarations + out_declarations,\n        web_register_native_module_id_overrides = ctx.attr.web_register_native_module_id_overrides,\n    )\n\ndef _extract_npm_package_files(pkgs):\n    # Normalize pkgs to a Python list of targets\n    if type(pkgs) == \"depset\":\n        pkgs = pkgs.to_list()\n\n    out = []\n    for p in pkgs:\n        # DefaultInfo.files is a depset[File]; flatten to list\n        out.extend(p[DefaultInfo].files.to_list())\n    return out\n\ndef _is_test_file(file_obj):\n    \"\"\"Check if a file is a test file that should be excluded from npm packages.\n\n    Test files are identified by:\n    - Filename containing '.spec.' or '.test.'\n    - Path containing '/test/' directory\n    \"\"\"\n    basename = file_obj.basename\n    path = file_obj.path\n\n    if \".spec.\" in basename or \".test.\" in basename:\n        return True\n\n    if \"/test/\" in path:\n        return True\n\n    return False\n\ndef _extract_js_files(module_name, output_target, outputs):\n    \"\"\"Extract JavaScript files from compiler outputs, excluding test files.\"\"\"\n    return [\n        f\n        for f in outputs\n        if f.basename.endswith(\".js\") and not _is_test_file(f)\n    ]\n\ndef _extract_web_strings(output_target, outputs):\n    return [\n        f\n        for f in outputs\n        if \"strings/\" in f.path and f.basename.endswith(\".json\") or f.basename.endswith(\"Strings.js\")\n    ]\n\ndef _extract_dts_files(srcs):\n    \"\"\" Extract declaration(d.ts) files from the list of source files. \"\"\"\n    return [f for f in srcs if f.basename.endswith(\".d.ts\")]\n\ndef _extract_dumped_compilation_metadata(files):\n    return [f for f in files if f.basename.endswith(\"compilation-metadata.json\")]\n\ndef _extract_valdi_module_android(output_target, module_name, outputs):\n    debug_path, release_path = _get_android_valdi_module_paths(module_name)\n    if output_target == \"debug\":\n        return _extract_valdi_module(debug_path, outputs)\n    else:\n        return _extract_valdi_module(release_path, outputs)\n\ndef _extract_valdi_module_ios(output_target, module_name, outputs):\n    debug_path, release_path = _get_ios_valdi_module_paths(module_name)\n    if output_target == \"debug\":\n        return _extract_valdi_module(debug_path, outputs)\n    else:\n        return _extract_valdi_module(release_path, outputs)\n\ndef _extract_valdi_module(file_path, outputs):\n    found = [f for f in outputs if f.path.endswith(file_path)]\n\n    if not found:\n        fail(\"Expected to find {} in outputs\".format(file_path))\n\n    return found[0]\n\ndef _extract_android_srcjar(output_target, module_name, single_file_codegen, outputs):\n    if single_file_codegen:\n        file_path = \"{}.kt\".format(module_name)\n    else:\n        file_path = \"{}.{}.srcjar\".format(module_name, output_target)\n    found = [f for f in outputs if f.path.endswith(file_path)]\n\n    if not found:\n        fail(\"Expected to find {} in outputs\".format(file_path))\n\n    return found[0]\n\ndef _extract_android_resources(output_target, outputs):\n    res_dir_path = _get_android_res_dir(output_target)\n\n    return [\n        f\n        for f in outputs\n        if res_dir_path in f.path and not f.is_directory\n    ]\n\ndef _extract_web_resources(output_target, outputs):\n    res_dir_path = _get_web_res_dir(output_target)\n\n    out = [\n        f\n        for f in outputs\n        if res_dir_path in f.path and not f.is_directory\n    ]\n\n    return out\n\ndef _extract_prepared_upload_artifact(name, outputs):\n    found = [f for f in outputs if f.path.endswith(name)]\n\n    if not found:\n        fail(\"Expected to find {} in outputs\".format(name))\n\n    return found[0]\n\ndef _extract_android_native_srcs(output_target, module_name, outputs):\n    debug_path, release_path = _get_android_generated_native_src_paths(module_name)\n    if output_target == \"debug\":\n        found = [f for f in outputs if f.path.endswith(debug_path)]\n    else:\n        found = [f for f in outputs if f.path.endswith(release_path)]\n\n    if not found:\n        fail(\"Expected to find generated native c file in outputs\")\n\n    return found[0]\n\ndef _extract_ios_native_srcs(output_target, ios_module_name, module_name, outputs):\n    debug_path, release_path = _get_ios_generated_native_src_paths(ios_module_name, module_name)\n    if output_target == \"debug\":\n        found = [f for f in outputs if f.path.endswith(debug_path)]\n    else:\n        found = [f for f in outputs if f.path.endswith(release_path)]\n\n    if not found:\n        fail(\"Expected to find generated native c file in outputs\")\n\n    return found[0]\n\ndef _extract_ios_unstructured_resources(output_target, outputs):\n    strings_dir = _get_ios_strings_dir(output_target)\n    return [\n        f\n        for f in outputs\n        if strings_dir in f.path and not f.is_directory\n    ]\n\ndef _extract_ios_resource_bundles(module_name, output_target, outputs):\n    bundle_dir = _get_ios_bundle_dir(module_name, output_target)\n    bundled_resources = [\n        f\n        for f in outputs\n        if bundle_dir in f.path and not f.is_directory\n    ]\n    return bundled_resources\n\ndef _filter_ios_src(outputs, output_target, debug_srcs, release_srcs, ext):\n    srcs = debug_srcs if output_target == \"debug\" else release_srcs\n\n    src_to_check = [f for f in srcs if f.endswith(ext)]\n    if len(src_to_check) != 1:\n        fail(\"Expecting to find exactly 1 entry with extension {}. Found {}\".format(ext, srcs))\n\n    found = [output for output in outputs if output.path.endswith(src_to_check[0])]\n    return found[0] if found else None\n\ndef _extract_ios_generated_hdrs(output_target, outputs, ios_module_name):\n    debug_src, release_src = _get_ios_generated_src(ios_module_name)\n\n    return _filter_ios_src(outputs, output_target, debug_src, release_src, \".h\")\n\ndef _extract_ios_api_generated_hdrs(output_target, outputs, ios_module_name):\n    debug_src, release_src = _get_ios_generated_api_src(ios_module_name)\n\n    return _filter_ios_src(outputs, output_target, debug_src, release_src, \".h\")\n\ndef _extract_ios_generated_srcs(output_target, outputs, ios_module_name, single_file_codegen, ios_language = [\"objc\"]):\n    if single_file_codegen:\n        debug_src, release_src = _get_ios_generated_src(ios_module_name, ios_language)\n\n        return _filter_ios_src(outputs, output_target, debug_src, release_src, \".m\")\n    else:\n        debug_src_dir, release_src_dir = _get_ios_generated_src_dir(ios_module_name)\n\n        if output_target == \"debug\":\n            found = [f for f in outputs if f.is_directory and f.path.endswith(debug_src_dir)]\n        else:\n            found = [f for f in outputs if f.is_directory and f.path.endswith(release_src_dir)]\n\n        return found[0] if found else None\n\ndef _extract_ios_generated_swift_srcs(output_target, outputs, ios_module_name, ios_language = [\"objc\"]):\n    if \"swift\" not in ios_language:\n        return None\n    debug_src, release_src = _get_ios_generated_src(ios_module_name, ios_language)\n    return _filter_ios_src(outputs, output_target, debug_src, release_src, \".swift\")\n\ndef _extract_ios_api_generated_srcs(output_target, outputs, ios_module_name, single_file_codegen, ios_language = [\"objc\"]):\n    if single_file_codegen:\n        debug_api_src, release_api_src = _get_ios_generated_api_src(ios_module_name, ios_language)\n\n        return _filter_ios_src(outputs, output_target, debug_api_src, release_api_src, \".m\")\n    else:\n        debug_api_src_dir, release_api_src_dir = _get_ios_generated_api_src_dir(ios_module_name)\n\n        if output_target == \"debug\":\n            found = [f for f in outputs if f.is_directory and f.path.endswith(debug_api_src_dir)]\n        else:\n            found = [f for f in outputs if f.is_directory and f.path.endswith(release_api_src_dir)]\n        return found[0] if found else None\n\ndef _extract_ios_api_generated_swift_srcs(output_target, outputs, ios_module_name, ios_language = [\"objc\"]):\n    if \"swift\" not in ios_language:\n        return None\n    debug_api_src, release_api_src = _get_ios_generated_api_src(ios_module_name, ios_language)\n    return _filter_ios_src(outputs, output_target, debug_api_src, release_api_src, \".swift\")\n\ndef _extract_cpp_generated_srcs(outputs, module_name, single_file_codegen):\n    \"\"\"Extract C++ generated source files (.cpp) from outputs.\n\n    C++ codegen always outputs to release configuration.\n    \"\"\"\n    if single_file_codegen:\n        srcs = _get_cpp_generated_src(module_name)\n\n        # Filter for .cpp files\n        src_to_check = [f for f in srcs if f.endswith(\".cpp\")]\n\n        if len(src_to_check) != 1:\n            fail(\"Expecting to find exactly 1 .cpp file. Found {}\".format(srcs))\n\n        found = [output for output in outputs if output.path.endswith(src_to_check[0])]\n        return found[0] if found else None\n    else:\n        src_dir = _get_cpp_generated_src_dir()\n        found = [f for f in outputs if f.is_directory and f.path.endswith(src_dir)]\n        return found[0] if found else None\n\ndef _extract_cpp_generated_hdrs(outputs, module_name, single_file_codegen):\n    \"\"\"Extract C++ generated header files (.hpp) from outputs.\n\n    C++ codegen always outputs to release configuration.\n    \"\"\"\n    if single_file_codegen:\n        srcs = _get_cpp_generated_src(module_name)\n\n        # Filter for .hpp files\n        src_to_check = [f for f in srcs if f.endswith(\".hpp\")]\n\n        if len(src_to_check) != 1:\n            fail(\"Expecting to find exactly 1 .hpp file. Found {}\".format(srcs))\n\n        found = [output for output in outputs if output.path.endswith(src_to_check[0])]\n        return found[0] if found else None\n    else:\n        # For multi-file codegen, headers are in the same directory as sources\n        src_dir = _get_cpp_generated_src_dir()\n        found = [f for f in outputs if f.is_directory and f.path.endswith(src_dir)]\n        return found[0] if found else None\n\ndef _extract_android_debug_sourcemaps(module_name, outputs):\n    \"\"\" Extract android debug sourcemap(map.json) files from the list of source files. \"\"\"\n    android_debug_sourcemap_path = _get_android_debug_sourcemap_path(module_name)\n    found = [f for f in outputs if f.path.endswith(android_debug_sourcemap_path)]\n\n    if not found:\n        fail(\"Expected to find {}.map.json in debug outputs\".format(module_name))\n\n    return found[0]\n\ndef _extract_android_sourcemap_archive(output_target, outputs):\n    debug_sourcemap_archive_dir, release_sourcemap_archive_dir = _get_android_source_map_dir()\n    if output_target == \"debug\":\n        found = [f for f in outputs if f.is_directory and f.path.endswith(debug_sourcemap_archive_dir)]\n    else:\n        found = [f for f in outputs if f.is_directory and f.path.endswith(release_sourcemap_archive_dir)]\n    return found[0] if found else None\n\ndef _extract_ios_sourcemap_archive(output_target, outputs):\n    debug_sourcemap_archive_dir, release_sourcemap_archive_dir = _get_ios_source_map_dir()\n    if output_target == \"debug\":\n        found = [f for f in outputs if f.is_directory and f.path.endswith(debug_sourcemap_archive_dir)]\n    else:\n        found = [f for f in outputs if f.is_directory and f.path.endswith(release_sourcemap_archive_dir)]\n    return found[0] if found else None\n\ndef _extract_ios_debug_sourcemaps(module_name, outputs):\n    \"\"\" Extract ios debug sourcemap(map.json) files from the list of source files. \"\"\"\n    ios_debug_sourcemap_path = _get_ios_debug_sourcemap_path(module_name)\n    found = [f for f in outputs if f.path.endswith(ios_debug_sourcemap_path)]\n\n    if not found:\n        fail(\"Expected to find {}.map.json in debug outputs\".format(module_name))\n\n    return found[0]\n\ndef _extract_ios_sql_assets(ios_module_name, outputs):\n    \"\"\" Extract iOS SQL assets used by Bazel. \"\"\"\n    found = [f for f in outputs if f.is_directory and f.path.endswith(paths.join(ios_module_name, \"sql\"))]\n    if found:\n        return found[0]\n    return None\n\ndef _extract_ios_dependency_data(outputs):\n    \"\"\" Extract iOS dependency data used by Bazel. \"\"\"\n    for f in outputs:\n        if f.path.endswith(\"dependencyData.json\"):\n            return f\n    return None\n\n#############\n##\n## Private helpers for transforming path strings\n##\n#############\n\ndef _get_module_scope(path_str):\n    # Returns @<scope>\n    scope_start_idx = path_str.find(\"@\")\n    if scope_start_idx < 0:\n        # Scope not found\n        return \"\"\n    elif scope_start_idx > 0 and path_str[scope_start_idx - 1] != \"/\":\n        # Invalid format, scope should start with '@'\n        return \"\"\n\n    scope_end_idx = path_str.find(\"/\", scope_start_idx)\n    if scope_end_idx < 0:\n        # Scope should never be the last component of path\n        return \"\"\n\n    return path_str[scope_start_idx:scope_end_idx]\n\ndef _resolve_hotreload_path(path):\n    if path.startswith(\"external/\"):\n        # For external references, we reference the base_path to the\n        # exec_root, as Bazel will copy the files there.\n        return (paths.join(\"$BAZEL_EXECROOT\", path), True)\n    else:\n        return (path, False)\n\ndef _append_hotreload_explicit_input_list_entry(target, json_entries):\n    (base_path, is_external_ref) = _resolve_hotreload_path(target[ValdiModuleInfo].base_path)\n\n    json_entries.append({\n        \"module_name\": target[ValdiModuleInfo].name,\n        \"module_path\": base_path,\n        \"module_content\": target[ValdiModuleInfo].module_definition,\n        \"monitor\": is_external_ref == False,\n        \"auto_discover\": is_external_ref,\n        \"files\": [],\n    })\n\ndef _prepare_hotreload_explicit_input_list_file(ctx, all_targets):\n    json_entries = []\n\n    json_entries.append(_resolve_valdi_base_entry(ctx.files._valdi_base, True))\n    for target in all_targets:\n        _append_hotreload_explicit_input_list_entry(target, json_entries)\n\n    content = json.encode_indent({\"entries\": json_entries}, indent = \"  \")\n\n    file_list = ctx.actions.declare_file(\"input_file_list.json\")\n    ctx.actions.write(output = file_list, content = content)\n\n    return file_list\n\ndef _prepare_hotreload_arguments(module_names, config_yaml_file, explicit_input_list_file, toolchain, base_project_path):\n    \"\"\" Prepare arguments for the Valdi compiler invocation. \"\"\"\n\n    companion_bin_wrapper = toolchain.companion.files.to_list()[0]\n    compiler_toolbox = toolchain.compiler_toolbox.files.to_list()[0]\n    pngquant = toolchain.pngquant.files.to_list()[0]\n    minify_config = toolchain.minify_config.files.to_list()[0]\n    client_sql = toolchain.sqldelight_compiler.files.to_list()\n\n    args = []\n\n    for module_name in module_names:\n        args.append(\"--module\")\n        args.append(module_name)\n    args.append(\"--config\")\n    args.append(config_yaml_file.path)\n    args.append(\"--explicit-input-list-file\")\n    args.append(explicit_input_list_file.path)\n    args.append(\"--direct-companion-path\")\n    args.append(companion_bin_wrapper.path)\n    args.append(\"--direct-compiler-toolbox-path\")\n    args.append(compiler_toolbox.path)\n    args.append(\"--direct-pngquant-path\")\n    args.append(pngquant.path)\n    args.append(\"--direct-minify-config-path\")\n    args.append(minify_config.path)\n\n    if client_sql:\n        args.append(\"--direct-client-sql-path\")\n        args.append(client_sql[0].path)\n\n    args.append(\"--module\")\n    args.append(_VALDI_BASE_MODULE_NAME)\n    args.append(\"--log-level\")\n    args.append(\"info\")\n    args.append(\"--monitor\")\n    args.append(\"--usb\")\n    args.append(\"--inline-translations\")\n\n    # Probably need to cd to the base_project_path as part of the script\n    args.append(\"--config-value\")\n    args.append(\"base_dir=$PWD/{}\".format(base_project_path))\n\n    args.append(\"--config-value\")\n    args.append(\"node_modules_dir=$PWD/{}\".format(NODE_MODULES_BASE))\n\n    args.append(\"--config-value\")\n    args.append(\"android.codegen_enabled=false\")\n    args.append(\"--config-value\")\n    args.append(\"ios.codegen_enabled=false\")\n\n    return \" \".join(args)\n\ndef __common_path(left, right):\n    left_components = left.split(\"/\")\n    right_components = right.split(\"/\")\n    common_components = []\n\n    index = 0\n    for l in left_components:\n        if index >= len(right_components) or right_components[index] != l:\n            break\n        index += 1\n        common_components.append(l)\n\n    return \"/\".join(common_components)\n\ndef __infer_base_project_path(targets):\n    common_path = None\n    for t in targets:\n        base_path = t[ValdiModuleInfo].base_path\n        if not common_path:\n            common_path = base_path\n        else:\n            common_path = __common_path(common_path, base_path)\n    return common_path\n\ndef _invoke_valdi_hotreloader(ctx):\n    toolchain = ctx.toolchains[VALDI_TOOLCHAIN_TYPE].info\n\n    config_yaml_file = generate_config(ctx)\n    (executable, tools, input_manifests) = resolve_compiler_executable(ctx, toolchain, include_tools = True)\n\n    all_targets = depset(direct = ctx.attr.targets, transitive = [target[ValdiModuleInfo].deps for target in ctx.attr.targets]).to_list()\n\n    base_project_path = __infer_base_project_path(all_targets)\n    explicit_input_list_file = _prepare_hotreload_explicit_input_list_file(ctx, all_targets)\n\n    run_hotreloader = ctx.actions.declare_file(\"run_hotreloader.sh\")\n\n    args = _prepare_hotreload_arguments([target[ValdiModuleInfo].name for target in ctx.attr.targets], config_yaml_file, explicit_input_list_file, toolchain, base_project_path)\n\n    # Here we run a command that outputs commands into run_hotreloader.sh.\n    # We do this so that Bazel can resolve the tools and input_manifests of the\n    # compiler and its dependencies.\n    cmd = \"\"\"\necho 'export BAZEL_BINDIR={bin_dir}' > {script_path}\necho \"export BAZEL_EXECROOT=$PWD\" >> {script_path}\necho '{executable} {args}' >> {script_path}\n    \"\"\".format(bin_dir = ctx.bin_dir.path, executable = executable.path, args = args, script_path = run_hotreloader.path)\n\n    ctx.actions.run_shell(\n        outputs = [run_hotreloader],\n        inputs = [executable, config_yaml_file, explicit_input_list_file],\n        tools = tools,\n        command = cmd,\n        input_manifests = input_manifests,\n        arguments = [],\n        env = {},\n        toolchain = VALDI_TOOLCHAIN_TYPE,\n        mnemonic = \"ValdiHotreload\",\n        progress_message = \"Generating hotreloader.sh\",\n    )\n\n    return (run_hotreloader, [])\n\ndef _valdi_hotreload_impl(ctx):\n    \"\"\"Generates a shell script that can start the Compiler in hotreload mode\n    \"\"\"\n    (output, transitive_outputs) = _invoke_valdi_hotreloader(ctx)\n\n    return [\n        DefaultInfo(executable = output, files = depset([output])),\n    ]\n\nvaldi_hotreload = rule(\n    implementation = _valdi_hotreload_impl,\n    toolchains = [VALDI_TOOLCHAIN_TYPE],\n    executable = True,\n    attrs = {\n        \"targets\": attr.label_list(\n            mandatory = True,\n            doc = \"The targets to hotreload\",\n        ),\n        \"_valdi_base\": attr.label(\n            doc = \"The base module that all Valdi modules depend on\",\n            default = \"@valdi//modules:valdi_base\",\n        ),\n        \"_template\": attr.label(\n            doc = \"The template config.yaml file\",\n            allow_single_file = True,\n            default = \"valdi_config.yaml.tpl\",\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_config.yaml.tpl",
    "content": "base_dir: .\nproject_name: valdi_snapchat\n\nignored_files:\n  - proto_config.json\n  - proto_config.yaml\n  - tslint.json\n  - unicode_script.ts\n  - OWNERS\n  - README.md\n  - \\.DS_Store\n  - package.json\n  - package-lock.json\n  - settings\\.json\n  - yarn.lock\n  - .*\\.proto\n  - .*\\.bzl\n\nios:\n  codegen_enabled: true\n  default_module_name_prefix: SCC\n  default_language: objc\n  output:\n    base: {IOS_OUTPUT_BASE}\n    debug_path: debug\n    release_path: release\n    metadata_path: metadata\n\nandroid:\n  class_path: com.snap.modules\n  output:\n    base: {ANDROID_OUTPUT_BASE}\n    debug_path: debug\n    release_path: release\n    metadata_path: '.'\n\ncpp:\n  codegen_enabled: true\n  default_class_prefix: 'snap::valdi_modules::'\n  import_path_prefix: 'valdi_modules/'\n  output:\n    base: cpp\n    debug_path: debug\n    release_path: release\n    metadata_path: '.'\n\n\ncompiler_companion_binary: {COMPANION_BINARY}\n\ncompiler_toolbox_path:\n  linux: {COMPILER_TOOLBOX_PATH}\n  macos: {COMPILER_TOOLBOX_PATH}\n\npngquant_bin_path:\n  linux: {PNGQUANT_PATH}\n  macos: {PNGQUANT_PATH}\n\nminify_config_path: {MINIFY_CONFIG_PATH}\n\nnode_modules_dir: {NODE_MODULES_DIR}\nnode_modules_target: {NODE_MODULES_TARGET}\nnode_modules_workspace: {NODE_MODULES_WORKSPACE}\nexternal_modules_target: {EXTERNAL_MODULES_TARGET}\nexternal_modules_workspace: {EXTERNAL_MODULES_WORKSPACE}\n"
  },
  {
    "path": "bzl/valdi/valdi_exported_library.bzl",
    "content": "load(\"@build_bazel_rules_apple//apple:apple.bzl\", \"apple_xcframework\")\nload(\"//bzl:expand_template.bzl\", \"expand_template\")\nload(\"//bzl/android:collect_android_assets.bzl\", \"collect_android_assets\")\nload(\"//bzl/valdi:rewrite_hdrs.bzl\", \"rewrite_hdrs\")\nload(\"//bzl/valdi:suffixed_deps.bzl\", \"get_suffixed_deps\")\nload(\"//bzl/valdi:valdi_collapse_web_paths.bzl\", \"collapse_native_paths\", \"collapse_web_paths\", \"generate_register_native_modules\")\nload(\"//bzl/valdi:valdi_protodecl_to_js.bzl\", \"collapse_protodecl_paths\", \"protodecl_to_js_dir\")\nload(\"//bzl/valdi/source_set:utils.bzl\", \"source_set_select\")\nload(\"//valdi:valdi.bzl\", \"valdi_android_aar\")\n\n_PRESERVED_MODULE_NAMES = [\"UIKit\", \"Foundation\", \"CoreFoundation\", \"CoreGraphics\", \"QuartzCore\"]\n\nDEFAULT_ANDROID_EXCLUDED_CLASS_PATTERNS = [\n    \"org/intellij/.*\",\n    \"org/jetbrains/.*\",\n    \"kotlin/.*\",\n    # TODO(simon): Figure out why this is needed\n    \"com/snap/valdi/support/R\\\\.class\",\n    \"com/snap/valdi/support/R\\\\$.*\\\\.class\",\n    \"android/support/.*\",\n    \"androidx/.*\",\n    \"META-INF\",\n]\n\nDEFAULT_JAVA_DEPS = [\"@valdi//valdi:valdi_android_support\"]\n\ndef valdi_exported_library(\n        name,\n        ios_bundle_id,\n        ios_bundle_name,\n        deps,\n        android_excluded_class_path_patterns = DEFAULT_ANDROID_EXCLUDED_CLASS_PATTERNS,\n        java_deps = DEFAULT_JAVA_DEPS,\n        web_package_name = None,\n        npm_scope = \"\",\n        npm_version = \"1.0.0\",\n        web_exclude_jsx_global_declaration = False):\n    if not web_package_name:\n        web_package_name = \"{}_npm\".format(name)\n\n    ios_public_hdrs_name = \"{}_ios_hdrs\".format(name)\n    rewrite_hdrs(\n        name = ios_public_hdrs_name,\n        module_name = ios_bundle_name,\n        preserved_module_names = _PRESERVED_MODULE_NAMES,\n        flatten_paths = True,\n        srcs = [\n            \"@valdi//valdi:valdi_ios_public_hdrs\",\n            \"@valdi//valdi_core:valdi_core_ios_public_hdrs\",\n        ] + get_suffixed_deps(deps, \"_api_objc_hdrs\") + get_suffixed_deps(deps, \"_objc_hdrs\"),\n    )\n\n    apple_xcframework(\n        name = \"{}_ios\".format(name),\n        bundle_name = ios_bundle_name,\n        deps = [\"@valdi//valdi\"] + get_suffixed_deps(deps, \"_objc\"),\n        infoplists = [\n            \"@valdi//bzl/valdi:Info.plist\",\n        ],\n        minimum_os_versions = {\n            \"ios\": \"12.0\",\n        },\n        families_required = {\n            \"ios\": [\n                \"iphone\",\n                \"ipad\",\n            ],\n        },\n        ios = {\n            \"device\": [\"arm64\"],\n            \"simulator\": [\"arm64\", \"x86_64\"],\n        },\n        tags = [\"valdi_ios_exported_library\"],\n        bundle_id = ios_bundle_id,\n        public_hdrs = [\":{}\".format(ios_public_hdrs_name)],\n    )\n\n    java_deps = java_deps + get_suffixed_deps(deps, \"_kt\")\n\n    collect_android_assets(\n        name = \"{}_android_assets\".format(name),\n        valdi_deps = deps,\n        deps = java_deps,\n        output_target = source_set_select(\n            debug = \"debug\",\n            release = \"release\",\n        ),\n    )\n\n    valdi_android_aar(\n        name = \"{}_android\".format(name),\n        java_deps = java_deps,\n        native_deps = [\n            \"@valdi//valdi\",\n        ] + get_suffixed_deps(deps, \"_native\"),\n        additional_assets = [\":{}_android_assets\".format(name)],\n        excluded_class_path_patterns = android_excluded_class_path_patterns,\n        so_name = \"lib{}.so\".format(name),\n        tags = [\"valdi_android_exported_library\"],\n    )\n\n    package_name = web_package_name\n    if npm_scope:\n        package_name = npm_scope + \"/\" + package_name\n\n    expand_template(\n        name = \"generate_package_json\",\n        src = \"@valdi//bzl/valdi:package.json.tmpl\",\n        output = \"package.json\",\n        substitutions = {\n            \"${name}\": package_name,\n            \"${version}\": npm_version,\n        },\n    )\n\n    protodecl_to_js_dir(\n        name = \"{}_protodecl_js\".format(web_package_name),\n        srcs = get_suffixed_deps(deps, \"_web_protodecl\"),\n    )\n\n    collapse_protodecl_paths(\n        name = \"{}_protodecl_collapsed\".format(web_package_name),\n        srcs = [\":{}_protodecl_js\".format(web_package_name)],\n    )\n\n    collapse_native_paths(\n        name = \"{}_web_native\".format(web_package_name),\n        srcs = get_suffixed_deps(deps, \"_all_web_deps\"),\n    )\n\n    generate_register_native_modules(\n        name = \"{}_register_native_modules\".format(web_package_name),\n        srcs = get_suffixed_deps(deps, \"_all_web_deps\"),\n        package_name = package_name,\n        modules = deps,\n    )\n\n    native.filegroup(\n        name = \"{}_glob\".format(web_package_name),\n        srcs = get_suffixed_deps(deps, \"_web_srcs_filegroup\") + [\n            \":{}_protodecl_collapsed\".format(web_package_name),\n            \":{}_web_native\".format(web_package_name),\n            \":{}_register_native_modules\".format(web_package_name),\n            \":generate_package_json\",  # package.json to root\n        ],\n    )\n\n    collapse_web_paths(\n        name = web_package_name,\n        srcs = [\":{}_glob\".format(web_package_name)],\n        package_name = package_name,\n        exclude_jsx_global_declaration = web_exclude_jsx_global_declaration,\n    )\n"
  },
  {
    "path": "bzl/valdi/valdi_extract_output_rule_helper.bzl",
    "content": "load(\":valdi_compiled.bzl\", \"ValdiModuleInfo\")\n\ndef extract_valdi_output_rule(implementation, attrs):\n    # TODO(simon): We use cfg = \"exec\" to avoid compiling multiple\n    # times for each platform as Valdi compilation is already cross-platform.\n    # This eliminates the need for compiling a Valdi module 3 times on Android:\n    # once for the Kotlin output, once for C output meant to compile for arm64,\n    # once for C output meant to compile for armv7. It might be better to use a\n    # Bazel transition instead at some point.\n\n    attrs[\"compiled_module\"] = attr.label(\n        mandatory = True,\n        cfg = \"exec\",\n        providers = [ValdiModuleInfo],\n    )\n\n    return rule(implementation = implementation, attrs = attrs)\n"
  },
  {
    "path": "bzl/valdi/valdi_ios_application.bzl",
    "content": "load(\"@build_bazel_rules_apple//apple:ios.bzl\", \"ios_application\")\nload(\"@build_bazel_rules_apple//apple:versioning.bzl\", \"apple_bundle_version\")\nload(\"//bzl:expand_template.bzl\", \"expand_template\")\n\ndef make_short_version(version):\n    components = version.split(\".\")\n\n    if len(components) > 2:\n        return \"{}.{}\".format(components[0], components[1])\n\n    return version\n\ndef valdi_ios_application(\n        name,\n        title,\n        root_component_path,\n        bundle_id,\n        info_plist = None,\n        families = None,\n        minimum_os_version = None,\n        provisioning_profile = None,\n        app_icons = None,\n        version = None,\n        deps = []):\n    main_target = \"{}_maingen\".format(name)\n    src_target = \"{}_src\".format(name)\n\n    if not families:\n        families = [\n            \"iphone\",\n            \"ipad\",\n        ]\n\n    if not minimum_os_version:\n        minimum_os_version = \"12.0\"\n\n    infoplists = []\n    if info_plist:\n        infoplists.append(info_plist)\n    else:\n        plist_target = \"{}_plist\".format(name)\n\n        expand_template(\n            name = plist_target,\n            src = \"@valdi//bzl/valdi/app_templates:Info.plist.tpl\",\n            output = \"Info.plist\",\n            substitutions = {\n                \"@VALDI_BUNDLE_IDENTIFIER@\": bundle_id,\n            },\n        )\n\n        infoplists.append(\":{}\".format(plist_target))\n\n    expand_template(\n        name = main_target,\n        src = \"@valdi//bzl/valdi/app_templates:ios_main.m.tpl\",\n        output = \"main_ios.m\",\n        substitutions = {\n            \"@VALDI_ROOT_COMPONENT_PATH@\": root_component_path,\n        },\n    )\n\n    native.objc_library(\n        name = src_target,\n        deps = [\n            \"@valdi//valdi\",\n        ] + deps,\n        srcs = [\":{}\".format(main_target)],\n    )\n\n    resolved_version = None\n    if version:\n        version_name = \"{}_version\".format(name)\n        apple_bundle_version(\n            name = version_name,\n            build_version = version,\n            short_version_string = make_short_version(version),\n        )\n        resolved_version = \":{}\".format(version_name)\n\n    ios_application(\n        name = name,\n        bundle_id = bundle_id,\n        bundle_name = title,\n        families = families,\n        infoplists = infoplists,\n        deps = [\":{}\".format(src_target)],\n        minimum_os_version = minimum_os_version,\n        provisioning_profile = provisioning_profile,\n        app_icons = app_icons,\n        version = resolved_version,\n        tags = [\"valdi_ios_application\"],\n        visibility = [\"//visibility:public\"],\n    )\n"
  },
  {
    "path": "bzl/valdi/valdi_macos_application.bzl",
    "content": "load(\"@build_bazel_rules_apple//apple:macos.bzl\", \"macos_application\")\nload(\"//bzl:expand_template.bzl\", \"expand_template\")\n\ndef valdi_macos_application(\n        name,\n        title,\n        root_component_path,\n        bundle_id,\n        window_width,\n        window_height,\n        window_resizable,\n        deps = []):\n    main_target = \"{}_maingen\".format(name)\n    plist_target = \"{}_plist\".format(name)\n    src_target = \"{}_src\".format(name)\n\n    expand_template(\n        name = plist_target,\n        src = \"@valdi//bzl/valdi/app_templates:Info.plist.tpl\",\n        output = \"Info.plist\",\n        substitutions = {\n            \"@VALDI_BUNDLE_IDENTIFIER@\": bundle_id,\n        },\n    )\n\n    expand_template(\n        name = main_target,\n        src = \"@valdi//bzl/valdi/app_templates:macos_main.m.tpl\",\n        output = \"main_macos.m\",\n        substitutions = {\n            \"@VALDI_ROOT_COMPONENT_PATH@\": root_component_path,\n            \"@VALDI_TITLE@\": title,\n            \"@VALDI_WINDOW_WIDTH@\": str(window_width),\n            \"@VALDI_WINDOW_HEIGHT@\": str(window_height),\n            \"@VALDI_WINDOW_RESIZABLE@\": \"true\" if (window_resizable) else \"false\",\n        },\n    )\n\n    native.objc_library(\n        name = src_target,\n        deps = [\n            \"@valdi//valdi\",\n        ] + deps,\n        srcs = [\":{}\".format(main_target)],\n    )\n\n    macos_application(\n        name = name,\n        bundle_id = bundle_id,\n        bundle_name = title,\n        infoplists = [\":{}\".format(plist_target)],\n        deps = [\":{}\".format(src_target)],\n        minimum_os_version = \"15.0\",\n        tags = [\"valdi_macos_application\"],\n        visibility = [\"//visibility:public\"],\n    )\n"
  },
  {
    "path": "bzl/valdi/valdi_module.bzl",
    "content": "\"\"\" This file contains a convenient macro to wrap valdi_compiled rule. Use this macro instead of direct valdi_compiled rule invocation. \"\"\"\n\nload(\"@bazel_skylib//lib:new_sets.bzl\", \"sets\")\nload(\"@build_bazel_rules_apple//apple:resources.bzl\", \"apple_bundle_import\", \"apple_resource_group\")\nload(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_library\")\nload(\"@rules_android//rules:rules.bzl\", \"android_library\")\nload(\"@rules_hdrs//hmap:hmap.bzl\", \"headermap\")\nload(\"@rules_hdrs//umbrella_header:umbrella_header.bzl\", \"umbrella_header\")\nload(\"@rules_kotlin//kotlin:android.bzl\", \"kt_android_library\")\nload(\"@snap_macros//:internal/sourcegen/valdi_context_factory.bzl\", \"valdi_context_factory_headers\", \"valdi_context_factory_impl\")\nload(\"//bzl:asset_package.bzl\", \"asset_package\")\nload(\"//bzl:client_objc_library.bzl\", \"client_objc_library\")\nload(\"//bzl/valdi:valdi_module_android_common.bzl\", \"COMMON_ANDROIDX_DEPS\", \"COMMON_FRAMEWORK_DEPS\")\nload(\"//bzl/valdi:valdi_module_native.bzl\", \"valdi_module_native\")\nload(\"//bzl/valdi/source_set:utils.bzl\", \"source_set_select\")\nload(\n    \"common.bzl\",\n    \"IOS_API_NAME_SUFFIX\",\n    \"IOS_OUTPUT_BASE\",\n    \"IOS_SWIFT_SUFFIX\",\n)\nload(\":extract_cpp_srcs.bzl\", \"extract_cpp_srcs\")\nload(\":extract_objc_srcs.bzl\", \"extract_objc_srcs\")\nload(\":extract_swift_srcs.bzl\", \"extract_swift_srcs\")\nload(\":generate_android_manifest.bzl\", \"generate_android_manifest\")\nload(\":valdi_compiled.bzl\", \"valdi_compiled\", _valdi_hotreload = \"valdi_hotreload\")\nload(\":valdi_module_info_extractor.bzl\", \"extract_transitive_valdi_module_output\", \"extract_valdi_module_native_output\", \"extract_valdi_module_output\")\nload(\":valdi_projectsync.bzl\", \"valdi_projectsync\")\nload(\":valdi_static_resource.bzl\", \"valdi_static_resource\")\nload(\":valdi_test.bzl\", \"valdi_test\")\n\nCOMPILER_FLAGS = [\n    # '-Os', # Uncomment to enable optimizations\n    \"-Wno-c11-extensions\",\n    \"-Wno-c99-extensions\",\n    \"-Wno-keyword-macro\",\n    \"-Wno-vla-extension\",\n    \"-Wno-zero-length-array\",\n    \"-Wno-gnu-statement-expression\",\n    \"-Wno-gnu-conditional-omitted-operand\",\n    \"-Wno-pedantic\",\n    \"-fno-exceptions\",\n    \"-fvisibility=default\",\n]\n\ndef valdi_module(\n        name,\n        srcs,\n        ios_module_name = None,\n        ios_output_target = \"release\",\n        android_output_target = \"release\",\n        res = [],\n        protodecl_srcs = [],\n        deps = [],\n        module_yaml = None,\n        strings_dir = None,\n        disable_annotation_processing = False,\n        async_strict_mode = False,\n        ids_yaml = None,\n        sql_db_names = None,\n        sql_srcs = [],\n        downloadable_assets = None,\n        test_target_name = \"test\",\n        compilation_mode = \"js_bytecode\",\n        # class path of generated files\n        android_class_path = None,\n        android_export_strings = None,\n        prepared_upload_artifact_name = None,\n        # TODO: start using this\n        no_compiled_valdimodule_output = False,\n        inline_assets = False,\n        single_file_codegen = True,\n        has_ios_exports = True,\n        has_android_exports = True,\n        disable_code_coverage = False,\n        disable_dependency_verification = False,\n        disable_hotreload = False,\n        visibility = visibility,\n        ios_language = \"objc\",\n        ios_generated_context_factories = [],\n        ios_deps = [],\n        android_deps = [],\n        native_deps = [],\n        macos_deps = [],\n        web_deps = [],\n        web_register_native_module_id_overrides = None,\n        exclude_patterns = None,\n        exclude_globs = None,\n        **kwargs):\n    \"\"\" A convenient macro to wrap valdi_compiled rule. Use this macro instead of direct valdi_compiled rule invocation.\n\n    The macro generates a few targets:\n        - {name}_compiled: the main target, which invokes Valdi compiler and generates .valdimodule file\n        - {name}_kt: the kt_android_library target, which wraps the generated Kotlin files\n        - {name}_objc: the Objective-C library target, which wraps the generated Objective-C files\n        - {name}_objc_api: the Objective-C API library target, which wraps the generated Objective-C API files\n        - {name}_resource_group: the apple_resource_group target, which wraps the generated resources for a MacOS application\n\n    The macro also creates a few aliases:\n        - {name}: a convenience alias to the {name}_compiled target\n        - {ModuleName}: a convenience alias to the {name}_objc target\n        - {ModuleName}Types: a convenience alias to the {name}_objc_api target\n\n    Args:\n        name: The name of the valdi module.\n        module_yaml: The module.yaml file containing the module configuration.\n        ios_module_name: The name of the iOS module from module.yaml\n        ios_output_target: The iOS output target: \"release\" or \"debug\".\n        android_class_path: Class path to use when generating Android source files.\n        android_output_target: The Android output target: \"release\" or \"debug\".\n        android_export_strings: Flag to indicate if string resources will be exported.\n        srcs: The source files for the valdi module.\n        res: The resource files for the valdi module.\n        protodecl_srcs: The proto declaration source files.\n        deps: The dependencies of the valdi module.\n        strings_dir: The directory containing the strings files.\n        disable_annotation_processing: Flag to disable annotation processing.\n        async_strict_mode: When true, raise exceptions for sync calls made by native code.\n        disable_dependency_verification: Flag to disable verification of module dependencies\n        disable_code_coverage: Flag to disable code coverage reporting.\n        disable_hotreload: Flag to disable hotreload\n        ids_yaml: The YAML file containing the IDs.\n        sql_db_names: The names of the SQL databases.\n        sql_srcs: The SQL source files.\n        single_file_codegen: Flag to indicate if the module should use single file codegen mde\n        has_ios_exports: Flag to indicate if the module has iOS native exports (default True).\n        has_android_exports: Flag to indicate if the module has Android native exports (default True).\n        downloadable_assets: Flag to indicate if the module resources are downloaded remotely or bundled with the app.\n        compilation_mode: The JavaScript compilation mode of the valdi module. Can be \"js_bytecode\", \"native\" or \"js\".\n        no_compiled_valdimodule_output: Flag to indicate that the module doesn't produce compiled valdi module output.\n        visibility: The visibility of the Bazel target\n        ios_language: The language of the iOS target: \"objc\", \"swift\" or \"objc, swift\".\n        native_deps: C++ deps for the module's _desktop native target (SnapDrawing path; macOS and Linux).\n        macos_deps: Obj-C/C++ deps for the module's _desktop native target on macOS only (e.g. NSOpenPanel). Ignored on Linux.\n        exclude_patterns: file patterns to exclude from the module\n        exclude_globs: glob patterns to exclude from the module\n        **kwargs: Additional keyword arguments.\n    \"\"\"\n    downloadable_assets = True if downloadable_assets == None else downloadable_assets\n\n    if not ios_module_name:\n        ios_module_name = name\n\n    ### 1. Collect strings files\n    strings_json_srcs = []\n    if strings_dir:\n        strings_json_srcs = native.glob([strings_dir + \"/strings-*.json\"])\n\n        if not strings_json_srcs:\n            fail(\"you provided a strings_dir, but there were no strings-*.json files in there\")\n\n    ### 2. Compile the valdi module\n    valdi_compiled(\n        name = name,\n        ios_module_name = ios_module_name,\n        ios_output_target = ios_output_target,\n        android_output_target = android_output_target,\n        android_export_strings = android_export_strings,\n        module = name,\n        module_yaml = module_yaml,\n        deps = [_valdi_compiled_target_for_target(dep) for dep in deps],\n        web_deps = web_deps,\n        web_register_native_module_id_overrides = web_register_native_module_id_overrides or {},\n        srcs = srcs,\n        res = res,\n        protodecl_srcs = protodecl_srcs,\n        ids_yaml = ids_yaml,\n        strings_json_srcs = strings_json_srcs,\n        disable_annotation_processing = disable_annotation_processing,\n        async_strict_mode = async_strict_mode,\n        sql_db_names = sql_db_names,\n        sql_srcs = sql_srcs,\n        has_ios_exports = has_ios_exports,\n        has_android_exports = has_android_exports,\n        has_dependency_data = len(ios_generated_context_factories) > 0,\n        prepared_upload_artifact_name = prepared_upload_artifact_name,\n        # TODO(simon): We should figure out a way to get these flags to be automatically resolved\n        # based on the target platform. That would require getting rid of cfg = \"exec , but we would\n        # need to prevent modules to be compiled 3 times or more when targetting Android.\n        downloadable_assets = True if prepared_upload_artifact_name else select({\n            \"@valdi//bzl/valdi:upload_assets\": downloadable_assets,\n            \"@valdi//bzl/valdi:bundle_assets\": False,\n            \"@valdi//bzl/valdi:strip_assets\": False,\n            \"@valdi//bzl/valdi:inline_assets\": False,\n        }),\n        strip_assets = False if prepared_upload_artifact_name else select({\n            \"@valdi//bzl/valdi:strip_assets\": downloadable_assets,\n            \"@valdi//bzl/valdi:upload_assets\": False,\n            \"@valdi//bzl/valdi:bundle_assets\": False,\n            \"@valdi//bzl/valdi:inline_assets\": False,\n        }),\n        inline_assets = True if inline_assets else select({\n            \"@valdi//bzl/valdi:strip_assets\": False,\n            \"@valdi//bzl/valdi:upload_assets\": False,\n            \"@valdi//bzl/valdi:bundle_assets\": False,\n            \"@valdi//bzl/valdi:inline_assets\": True,\n        }),\n        compilation_mode = compilation_mode,\n        visibility = visibility,\n        tags = [\n            \"valdi_compiled\",\n        ],\n        strings_dir = strings_dir,\n        android_class_path = android_class_path,\n        single_file_codegen = single_file_codegen,\n        ios_language = ios_language if type(ios_language) == \"list\" else [ios_language],\n        disable_code_coverage = disable_code_coverage,\n        disable_dependency_verification = disable_dependency_verification,\n        disable_hotreload = disable_hotreload,\n        exclude_patterns = exclude_patterns,\n        exclude_globs = exclude_globs,\n        **kwargs\n    )\n\n    # ### 2.1  Create a convenience alias to the compiled valdi module to build it by default\n    compiled_module_target = native.package_relative_label(name)\n\n    all_valdi_module_deps = sets.to_list(sets.make(deps))\n\n    ### 3. Setup the Android target named {name}_kt\n    _setup_android_target(name, all_valdi_module_deps, android_deps, compiled_module_target, visibility, android_output_target, has_android_exports)\n\n    ### 4. Setup the iOS target named {name}_objc\n    # A module has resource bundle if there are resources on the disk and resources are not downloaded remotely at runtime.\n    _setup_ios_target(name, all_valdi_module_deps, ios_deps, compiled_module_target, ios_module_name, sql_db_names, ios_generated_context_factories, bool(res), downloadable_assets, ios_output_target, visibility, ios_language, single_file_codegen, has_ios_exports)\n\n    ### 5. Setup the C++ target named {name}_cpp\n    _setup_cpp_target(name, all_valdi_module_deps, compiled_module_target, visibility, single_file_codegen)\n\n    #### 6. Setup Web target\n    _setup_web_target(name, all_valdi_module_deps, compiled_module_target, visibility, compilation_mode, web_deps)\n\n    ### 7. Setup the native targets named {name}_native\n    _setup_native_target(name, all_valdi_module_deps, native_deps, macos_deps, compiled_module_target, visibility)\n\n    ### 8. Setup the test target\n    _setup_test_target(name, test_target_name, srcs)\n\n    ### 9. Setup the prepared upload artifact if set\n    if prepared_upload_artifact_name:\n        _setup_prepared_upload_artifact(name, prepared_upload_artifact_name, compiled_module_target, visibility)\n\n    ### 10. Setup the hotreload target\n    _valdi_hotreload(\n        name = name + \"_hotreload\",\n        targets = [\":{}\".format(name)],\n    )\n\n    ### 11: Setup projectsync target, used for VSCode autocompletion\n    _setup_projectsync_target(\n        name = name + \"_projectsync\",\n        target = \":{}\".format(name),\n        res = res,\n        ids_yaml = ids_yaml,\n        strings_json_srcs = strings_json_srcs,\n        sql_db_names = sql_db_names,\n        sql_srcs = sql_srcs,\n        visibility = visibility,\n    )\n\ndef valdi_hotreload(**kwargs):\n    _valdi_hotreload(\n        **kwargs\n    )\n\ndef _setup_test_target(name, test_target_name, srcs):\n    target = \":{}\".format(name)\n    valdi_test(name = test_target_name, srcs = srcs, target = target, hot_reload = select({\n        \"@valdi//bzl/valdi:valdi_hot_reload_enabled\": True,\n        \"//conditions:default\": False,\n    }), tags = [\n        \"valdi_test\",\n    ])\n\ndef _setup_projectsync_target(\n        name,\n        target,\n        res,\n        strings_json_srcs,\n        ids_yaml,\n        sql_db_names,\n        sql_srcs,\n        visibility = visibility):\n    valdi_projectsync(\n        name = name,\n        target = target,\n        res = res,\n        strings_json_srcs = strings_json_srcs,\n        ids_yaml = ids_yaml,\n        sql_db_names = sql_db_names,\n        sql_srcs = sql_srcs,\n        visibility = visibility,\n    )\n\ndef _setup_prepared_upload_artifact(name, prepared_upload_artifact_name, compiled_module_target, visibility):\n    extract_valdi_module_output(\n        name = prepared_upload_artifact_name,\n        compiled_module = compiled_module_target,\n        output_name = \"prepared_upload_artifact\",\n        visibility = visibility,\n    )\n\ndef _valdi_source_set_select(debug, release, is_release_output_target, release_default_value = []):\n    \"\"\" Selects the source set based on the source set and module's output target.\n\n    Conceptually, there's output target on Valdi module level which is either \"release\" or \"debug\".\n    Then, there are source sets, aka build flavors, introduced at build time, which can be *mapped* into either \"release\" or \"debug\".\n\n    Typically a \"debug\" module is only used by other \"debug\" targets,\n    but there are \"release\" targets that depend on \"debug\" modules via excplicit \"allowed_debug_dependencies\" list.\n\n    To align with the existing behavior, such \"debug\" targets, in \"release\" build flavor should expose an \"empty\" Android/iOS targets.\n    We achieve that by providing an empty value for the \"release\" source set.\n    \"\"\"\n\n    return source_set_select(\n        debug = debug,\n        release = release if is_release_output_target else release_default_value,\n    )\n\ndef _setup_android_target(name, deps, android_deps, compiled_module_target, visibility, android_output_target, has_android_exports):\n    ################\n    ####\n    #### Configure the Android library target\n    ####\n    ################\n    is_release = android_output_target == \"release\"\n\n    # Android resources\n    extract_valdi_module_output(\n        name = \"android.debug.valdimodule\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_debug_valdimodule\",\n        visibility = visibility,\n    )\n\n    extract_valdi_module_output(\n        name = \"android.release.valdimodule\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_release_valdimodule\",\n        visibility = visibility,\n    )\n\n    # Only extract srcjars if the module has Android exports\n    if has_android_exports:\n        extract_valdi_module_output(\n            name = \"android.debug.srcjar\",\n            compiled_module = compiled_module_target,\n            output_name = \"android_debug_srcjar\",\n            visibility = visibility,\n        )\n\n        extract_valdi_module_output(\n            name = \"android.release.srcjar\",\n            compiled_module = compiled_module_target,\n            output_name = \"android_release_srcjar\",\n            visibility = visibility,\n        )\n\n    extract_valdi_module_output(\n        name = \"android.debug.resource_files\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_debug_resource_files\",\n        visibility = visibility,\n    )\n\n    extract_valdi_module_output(\n        name = \"android.release.resource_files\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_release_resource_files\",\n        visibility = visibility,\n    )\n\n    extract_valdi_module_output(\n        name = \"android.debug.sourcemaps\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_debug_sourcemaps\",\n        visibility = visibility,\n    )\n\n    extract_valdi_module_output(\n        name = \"android.debug.sourcemaparchive\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_debug_sourcemap_archive\",\n        visibility = visibility,\n    )\n\n    extract_valdi_module_output(\n        name = \"android.release.sourcemaparchive\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_release_sourcemap_archive\",\n        visibility = visibility,\n    )\n\n    kt_deps = [_kt_target_for_target(dep) for dep in deps]\n\n    package_name = \"com.snap.valdi.modules.{name}\".format(name = name)\n    generate_android_manifest(\n        name = name + \"_manifest\",\n        package = package_name,\n    )\n\n    # Wrap all of the generated Kotlin files in a library that can be used from other Android targets.\n    # We use \"android_library\" here instead of \"jvm_library\" because the\n    # generated code depends on Android classes such as Context.\n    kt_android_library(\n        name = name + \"_api_kt\",\n        srcs = _valdi_source_set_select(\n            debug = [\":android.debug.srcjar\"] if has_android_exports else [\"@valdi//bzl/valdi:empty.kt\"],\n            release = [\":android.release.srcjar\"] if has_android_exports else [\"@valdi//bzl/valdi:empty.kt\"],\n            is_release_output_target = is_release,\n            release_default_value = [\"@valdi//bzl/valdi:empty.kt\"],\n        ),\n        # Both direct and transitive dependencies must be listed because Android repo explicitly forbids transitive dependencies.\n        deps = kt_deps + COMMON_ANDROIDX_DEPS + COMMON_FRAMEWORK_DEPS,\n        # Export all dependencies for now, but change in the future once we have a way to enforce \"no transitive dependencies\"\n        # rule in the module.yaml\n        exports = kt_deps + COMMON_FRAMEWORK_DEPS,\n        visibility = visibility,\n    )\n\n    android_library(\n        name = \"{}_kt\".format(name),\n        tags = [\n            \"valdi_kt\",\n        ],\n        exports = [\":{}_api_kt\".format(name)] + android_deps,\n        custom_package = package_name,\n        manifest = native.package_relative_label(name + \"_manifest\"),\n        assets = _valdi_source_set_select(\n            debug = [\n                \":android.debug.valdimodule\",\n                \":android.debug.sourcemaps\",\n            ],\n            release = [\":android.release.valdimodule\"],\n            is_release_output_target = is_release,\n        ),\n        assets_dir = _valdi_source_set_select(\n            debug = \"android/debug/assets\",\n            release = \"android/release/assets\",\n            is_release_output_target = is_release,\n            release_default_value = \"\",\n        ),\n        resource_files = _valdi_source_set_select(\n            debug = [\":android.debug.resource_files\"],\n            release = [\":android.release.resource_files\"],\n            is_release_output_target = is_release,\n        ),\n        visibility = visibility,\n    )\n\ndef _setup_ios_target(name, module_deps, ios_deps, compiled_module_target, ios_module_name, sql_db_names, ios_generated_context_factories, has_resource_bundle, downloadable_assets, ios_output_target, visibility, ios_language, single_file_codegen, has_ios_exports):\n    ################\n    ####\n    #### Configure the objc_library targets\n    ####\n    ################\n    api_objc_deps = [_objc_api_target_for_target(dep) for dep in module_deps]\n    objc_deps = [_objc_target_for_target(dep) for dep in module_deps]\n    swift_deps = [_ios_target_for_target(dep) for dep in module_deps]\n\n    # iOS resources\n    extract_valdi_module_output(\n        name = \"ios.debug.resource_files\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_debug_resource_files\",\n    )\n\n    extract_valdi_module_output(\n        name = \"ios.release.resource_files\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_release_resource_files\",\n    )\n\n    extract_valdi_module_output(\n        name = \"ios.debug.valdimodule\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_debug_valdimodule\",\n    )\n\n    extract_valdi_module_output(\n        name = \"ios.release.valdimodule\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_release_valdimodule\",\n    )\n\n    extract_valdi_module_native_output(\n        name = \"ios.debug.srcs\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_debug_generated_srcs\",\n    )\n\n    extract_valdi_module_native_output(\n        name = \"ios.release.srcs\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_release_generated_srcs\",\n    )\n\n    extract_valdi_module_native_output(\n        name = \"ios.debug.api.srcs\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_debug_api_generated_srcs\",\n    )\n\n    extract_valdi_module_native_output(\n        name = \"ios.release.api.srcs\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_release_api_generated_srcs\",\n    )\n\n    extract_valdi_module_output(\n        name = \"ios.debug.sourcemaps\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_debug_sourcemaps\",\n    )\n\n    extract_valdi_module_output(\n        name = \"ios.debug.sourcemaparchive\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_debug_sourcemap_archive\",\n        visibility = visibility,\n    )\n\n    extract_valdi_module_output(\n        name = \"ios.release.sourcemaparchive\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_release_sourcemap_archive\",\n        visibility = visibility,\n    )\n\n    selected_source_set = source_set_select(\n        debug = \"debug\",\n        release = \"release\",\n    )\n\n    if single_file_codegen:\n        extract_valdi_module_output(\n            name = \"ios.debug.hdrs\",\n            compiled_module = compiled_module_target,\n            output_name = \"ios_debug_generated_hdrs\",\n        )\n\n        extract_valdi_module_output(\n            name = \"ios.release.hdrs\",\n            compiled_module = compiled_module_target,\n            output_name = \"ios_release_generated_hdrs\",\n        )\n\n        extract_valdi_module_output(\n            name = \"ios.debug.api.hdrs\",\n            compiled_module = compiled_module_target,\n            output_name = \"ios_debug_api_generated_hdrs\",\n        )\n\n        extract_valdi_module_output(\n            name = \"ios.release.api.hdrs\",\n            compiled_module = compiled_module_target,\n            output_name = \"ios_release_api_generated_hdrs\",\n        )\n\n        api_objc_hdrs = []\n        api_objc_srcs = []\n        objc_hdrs = []\n        objc_srcs = []\n        swift_srcs = []\n\n        if \"swift\" in ios_language:\n            extract_valdi_module_native_output(\n                name = \"ios.debug.swift_srcs\",\n                compiled_module = compiled_module_target,\n                output_name = \"ios_debug_generated_swift_srcs\",\n            )\n\n            extract_valdi_module_native_output(\n                name = \"ios.release.swift_srcs\",\n                compiled_module = compiled_module_target,\n                output_name = \"ios_release_generated_swift_srcs\",\n            )\n\n            extract_valdi_module_native_output(\n                name = \"ios.debug.api.swift_srcs\",\n                compiled_module = compiled_module_target,\n                output_name = \"ios_debug_api_generated_swift_srcs\",\n            )\n\n            extract_valdi_module_native_output(\n                name = \"ios.release.api.swift_srcs\",\n                compiled_module = compiled_module_target,\n                output_name = \"ios_release_api_generated_swift_srcs\",\n            )\n\n            swift_srcs = source_set_select(\n                debug = [\":ios.debug.swift_srcs\", \":ios.debug.api.swift_srcs\"],\n                release = [\":ios.release.swift_srcs\", \":ios.release.api.swift_srcs\"],\n            )\n        else:\n            swift_srcs = [\"@valdi//bzl/valdi:empty.swift\"]\n        if \"objc\" in ios_language:\n            api_objc_hdrs = source_set_select(\n                debug = [\":ios.debug.api.hdrs\"],\n                release = [\":ios.release.api.hdrs\"],\n            )\n            api_objc_srcs = source_set_select(\n                debug = [\":ios.debug.api.srcs\"],\n                release = [\":ios.release.api.srcs\"],\n            )\n            objc_hdrs = source_set_select(\n                debug = [\":ios.debug.hdrs\"],\n                release = [\":ios.release.hdrs\"],\n            )\n            objc_srcs = source_set_select(\n                debug = [\":ios.debug.srcs\"],\n                release = [\":ios.release.srcs\"],\n            )\n\n        native.filegroup(\n            name = name + \"_api_objc_hdrs\",\n            srcs = api_objc_hdrs,\n            visibility = visibility,\n        )\n\n        native.filegroup(\n            name = name + \"_objc_hdrs\",\n            srcs = objc_hdrs,\n            visibility = visibility,\n        )\n    else:\n        api_objc_hdrs_name = name + \"_api_objc_hdrs\"\n        api_objc_srcs_name = name + \"_api_objc_srcs\"\n        objc_hdrs_name = name + \"_objc_hdrs\"\n        objc_srcs_name = name + \"_objc_srcs\"\n        swift_srcs_name = name + \"_swift_srcs\"\n\n        api_objc_hdrs = [native.package_relative_label(api_objc_hdrs_name)]\n        api_objc_srcs = [native.package_relative_label(api_objc_srcs_name)]\n        objc_hdrs = [native.package_relative_label(objc_hdrs_name)]\n        objc_srcs = [native.package_relative_label(objc_srcs_name)]\n        swift_srcs = [native.package_relative_label(swift_srcs_name)]\n\n        # Only extract native sources if the module has iOS exports\n        if has_ios_exports:\n            extract_objc_srcs(\n                name = api_objc_hdrs_name,\n                compiled_module = compiled_module_target,\n                extension = \".h\",\n                api_only = True,\n                selected_source_set = selected_source_set,\n                visibility = visibility,\n            )\n\n            extract_objc_srcs(\n                name = api_objc_srcs_name,\n                compiled_module = compiled_module_target,\n                extension = \".m\",\n                api_only = True,\n                selected_source_set = selected_source_set,\n            )\n\n            extract_objc_srcs(\n                name = objc_hdrs_name,\n                compiled_module = compiled_module_target,\n                extension = \".h\",\n                api_only = False,\n                selected_source_set = selected_source_set,\n                visibility = visibility,\n            )\n\n            extract_objc_srcs(\n                name = objc_srcs_name,\n                compiled_module = compiled_module_target,\n                extension = \".m\",\n                api_only = False,\n                selected_source_set = selected_source_set,\n            )\n\n            extract_swift_srcs(\n                name = swift_srcs_name,\n                compiled_module = compiled_module_target,\n                selected_source_set = selected_source_set,\n            )\n        else:\n            # Create empty filegroups when there are no exports\n            native.filegroup(\n                name = api_objc_hdrs_name,\n                srcs = [],\n                visibility = visibility,\n            )\n            native.filegroup(\n                name = api_objc_srcs_name,\n                srcs = [],\n            )\n            native.filegroup(\n                name = objc_hdrs_name,\n                srcs = [],\n                visibility = visibility,\n            )\n            native.filegroup(\n                name = objc_srcs_name,\n                srcs = [],\n            )\n            native.filegroup(\n                name = swift_srcs_name,\n                srcs = [],\n            )\n\n    # iOS target named {ios_module_name}\n    resources = source_set_select(\n        debug = [\n            \":ios.debug.valdimodule\",\n            \":ios.debug.resource_files\",\n            \":ios.debug.sourcemaps\",\n        ],\n        release = [\n            \":ios.release.valdimodule\",\n            \":ios.release.resource_files\",\n        ],\n    )\n\n    if has_resource_bundle:\n        extract_valdi_module_output(\n            name = \"ios.debug.resource_bundle\",\n            compiled_module = compiled_module_target,\n            output_name = \"ios_debug_bundle_resources\",\n            empty_bundle_fallback = \"@valdi//bzl/valdi:empty_bundle\",\n        )\n\n        extract_valdi_module_output(\n            name = \"ios.release.resource_bundle\",\n            compiled_module = compiled_module_target,\n            output_name = \"ios_release_bundle_resources\",\n            empty_bundle_fallback = \"@valdi//bzl/valdi:empty_bundle\",\n        )\n\n        apple_bundle_import(\n            name = \"ios.debug.resource_bundle_import\",\n            bundle_imports = [\":ios.debug.resource_bundle\"],\n        )\n\n        apple_bundle_import(\n            name = \"ios.release.resource_bundle_import\",\n            bundle_imports = [\":ios.release.resource_bundle\"],\n        )\n\n        resources += select({\n            \"@valdi//bzl/valdi:debug_upload_assets\": [] if downloadable_assets else [\":ios.debug.resource_bundle_import\"],\n            \"@valdi//bzl/valdi:debug_strip_assets\": [] if downloadable_assets else [\":ios.debug.resource_bundle_import\"],\n            \"@valdi//bzl/valdi:debug_bundle_assets\": [\":ios.debug.resource_bundle_import\"],\n            \"@valdi//bzl/valdi:release_upload_assets\": [] if downloadable_assets else [\":ios.release.resource_bundle_import\"],\n            \"@valdi//bzl/valdi:release_strip_assets\": [] if downloadable_assets else [\":ios.release.resource_bundle_import\"],\n            # By design, debug only builds don't produce resource bundles in the release mode as such there's nothing to bundle.\n            \"@valdi//bzl/valdi:release_bundle_assets\": [\":ios.release.resource_bundle_import\"] if ios_output_target == \"release\" else [],\n        })\n\n    deps = objc_deps + [native.package_relative_label(name + \"_api_objc\")] + ios_deps + [native.package_relative_label(name + \"_native\")]\n\n    # Only for Buck\n    # TODO(2954): remove Buck hacks\n    if sql_db_names:\n        extract_valdi_module_output(\n            name = \"ios.sql_assets\",\n            compiled_module = compiled_module_target,\n            output_name = \"ios_sql_assets\",\n        )\n\n        # The name has to align with the expected name in Buck\n        sql_srcs_name = ios_module_name + \"Db\"\n        asset_package(\n            name = sql_srcs_name,\n            data = [\":ios.sql_assets\"],\n        )\n        deps += select({\n            \"//conditions:default\": [],\n        })\n\n    ios_api_module_name = ios_module_name + IOS_API_NAME_SUFFIX\n\n    # Generated API objects\n    api_generated_objects = []\n    for context_name in ios_generated_context_factories:\n        context_factory_headers = valdi_context_factory_headers(\n            api_module_name = ios_api_module_name,\n            context_name = context_name,\n        )\n        api_generated_objects.append(context_factory_headers)\n\n    # Generated Implementation objects\n    impl_generated_objects = []\n    for context_name in ios_generated_context_factories:\n        context_factory_impl = valdi_context_factory_impl(\n            module_name = ios_module_name,\n            api_module_name = ios_api_module_name,\n            context_name = context_name,\n        )\n        impl_generated_objects.append(context_factory_impl)\n\n    if ios_generated_context_factories:\n        extract_valdi_module_output(\n            name = \"dependencyData.json\",\n            compiled_module = compiled_module_target,\n            output_name = \"ios_dependency_data\",\n        )\n\n    _exported_objc_lib(\n        name = name + \"_objc\",\n        ios_module_name = ios_module_name,\n        deps = deps,\n        objc_hdrs = objc_hdrs,\n        objc_srcs = objc_srcs,\n        data = resources,\n        visibility = visibility,\n        generated_objects = impl_generated_objects,\n        single_file_codegen = single_file_codegen,\n        has_ios_exports = has_ios_exports,\n        tags = [\n            \"valdi_objc\",\n        ],\n    )\n\n    should_add_alias = name != ios_module_name\n\n    if should_add_alias:\n        # iOS target names {ios_module_name}\n        native.alias(\n            name = ios_module_name,\n            actual = native.package_relative_label(name + \"_objc\"),\n            visibility = visibility,\n        )\n\n    _exported_objc_lib(\n        name = name + \"_api_objc\",\n        ios_module_name = ios_api_module_name,\n        deps = api_objc_deps,\n        objc_hdrs = api_objc_hdrs,\n        objc_srcs = api_objc_srcs,\n        generated_objects = api_generated_objects,\n        single_file_codegen = single_file_codegen,\n        has_ios_exports = has_ios_exports,\n        visibility = visibility,\n    )\n\n    if should_add_alias:\n        # iOS API target named {ios_module_name}Types\n        native.alias(\n            name = ios_module_name + IOS_API_NAME_SUFFIX,\n            actual = native.package_relative_label(name + \"_api_objc\"),\n            visibility = visibility,\n        )\n\n    # Add a _Swift suffix to the Swift module name when both ObjC and Swift\n    # codegen is enabled.  This suffix is not added when there is only Swift\n    # codegen. We expect only a small amount of modules to have dual codegen so\n    # this choice aims to optimize for the user experience of the most common\n    # cases (ObjC only or Swift only).\n    swift_suffix = \"_Swift\" if (\"swift\" in ios_language) and (\"objc\" in ios_language) else \"\"\n    swift_library(\n        name = name + \"_swift\",\n        module_name = ios_module_name + swift_suffix,\n        srcs = swift_srcs,\n        deps = swift_deps + [\"@valdi//valdi_core:valdi_core_swift_marshaller\"],\n        data = resources,\n        copts = [\"-Osize\", \"-Xfrontend\", \"-internalize-at-link\", \"-Xcc\", \"-I.\"],\n        linkopts = [\"-dead_strip\"],\n        visibility = visibility,\n    )\n\n    if should_add_alias:\n        # iOS API target named {ios_module_name}Swift\n        native.alias(\n            name = ios_module_name + IOS_SWIFT_SUFFIX,\n            actual = native.package_relative_label(name + \"_swift\"),\n            visibility = visibility,\n        )\n\n    # Target named {name}_ios that will be either the ObjC or Swift depending on\n    # the language that was selected. If the language is \"objc, swift\", then\n    # choose _swift. This is because only Swift targets depend on the \"_ios\"\n    # targets. ObjC targets directly depend on \"_objc\" targets.\n    if \"swift\" in ios_language:\n        ios_target = \"_swift\"\n    elif \"objc\" in ios_language:\n        ios_target = \"_objc\"\n    else:\n        ios_target = None\n    if ios_target:\n        native.alias(\n            name = name + \"_ios\",\n            actual = native.package_relative_label(name + ios_target),\n            visibility = visibility,\n        )\n\n    # Provide resource dependencies for MacOS application builds\n    resource_deps = [_resource_target_for_target(dep) for dep in module_deps]\n    apple_resource_group(\n        name = name + \"_resource_group\",\n        resources = resource_deps + resources,\n        visibility = visibility,\n    )\n\ndef _setup_web_target(name, deps, compiled_module_target, visibility, compilation_mode, web_deps):\n    is_release = compilation_mode == \"release\"\n\n    # All transitive dependencies for a monolithic npm\n    extract_transitive_valdi_module_output(\n        name = \"web.debug.srcs.all\",\n        modules = [compiled_module_target],\n        output_name = \"web_debug_sources\",\n        visibility = visibility,\n    )\n\n    extract_transitive_valdi_module_output(\n        name = \"web.release.srcs.all\",\n        modules = [compiled_module_target],\n        output_name = \"web_release_sources\",\n        visibility = visibility,\n    )\n\n    web_srcs_all = _valdi_source_set_select(\n        debug = [\":web.debug.srcs.all\"],\n        release = [\":web.release.srcs.all\"],\n        is_release_output_target = is_release,\n    )\n\n    # All transitive dependencies for a monolithic npm\n    extract_transitive_valdi_module_output(\n        name = \"web.debug.resource_files.all\",\n        modules = [compiled_module_target],\n        output_name = \"web_debug_resource_files\",\n        visibility = visibility,\n    )\n\n    extract_transitive_valdi_module_output(\n        name = \"web.release.resource_files.all\",\n        modules = [compiled_module_target],\n        output_name = \"web_release_resource_files\",\n        visibility = visibility,\n    )\n\n    web_resource_files_all = _valdi_source_set_select(\n        debug = [\":web.debug.resource_files.all\"],\n        release = [\":web.release.resource_files.all\"],\n        is_release_output_target = is_release,\n    )\n\n    # All transitive strings for a monolithic npm\n    extract_transitive_valdi_module_output(\n        name = \"web.debug.strings.all\",\n        modules = [compiled_module_target],\n        output_name = \"web_debug_strings\",\n        visibility = visibility,\n    )\n\n    extract_transitive_valdi_module_output(\n        name = \"web.release.strings.all\",\n        modules = [compiled_module_target],\n        output_name = \"web_release_strings\",\n        visibility = visibility,\n    )\n\n    web_strings_all = _valdi_source_set_select(\n        debug = [\":web.debug.strings.all\"],\n        release = [\":web.release.strings.all\"],\n        is_release_output_target = is_release,\n    )\n\n    # All transitive protodecl for a monolithic npm\n    extract_transitive_valdi_module_output(\n        name = \"web.protodecl.all\",\n        modules = [compiled_module_target],\n        output_name = \"protodecl_srcs\",\n        visibility = visibility,\n    )\n\n    # All web deps\n    extract_transitive_valdi_module_output(\n        name = \"web.deps.all\",\n        modules = [compiled_module_target],\n        output_name = \"web_deps\",\n        visibility = visibility,\n    )\n\n    # All TypeScript declaration files\n    extract_transitive_valdi_module_output(\n        name = \"web.dts.all\",\n        modules = [compiled_module_target],\n        output_name = \"web_dts_files\",\n        visibility = visibility,\n    )\n\n    native.filegroup(\n        name = \"{}_all_web_deps\".format(name),\n        srcs = [\":web.deps.all\"],\n        visibility = visibility,\n    )\n\n    native.filegroup(\n        name = \"{}_web_protodecl\".format(name),\n        srcs = [\":web.protodecl.all\"],\n        visibility = visibility,\n    )\n\n    native.filegroup(\n        name = \"{}_web_srcs_filegroup\".format(name),\n        srcs = web_srcs_all + web_resource_files_all + web_strings_all + [\":web.protodecl.all\", \":web.deps.all\", \":web.dts.all\"],\n        visibility = visibility,\n    )\n\ndef _web_target_for_target(target):\n    label = native.package_relative_label(target)\n    return label.relative(\":\" + label.name + \"_web\")\n\ndef npm_package_target_name(name):\n    return \"{}_npm_package\".format(name)\n\ndef npm_package_target_for_target(name):\n    label = native.package_relative_label(name)\n    return label.relative(\":\" + npm_package_target_name(label.name))\n\ndef _exported_objc_lib(name, ios_module_name, objc_hdrs, objc_srcs, single_file_codegen, has_ios_exports = True, **kwargs):\n    # setup headermaps\n    # When has_ios_exports is False, we use empty hdrs instead of header_tree_artifact_providers\n    # because the headermap rule requires at least one tree artifact when using header_tree_artifact_providers\n    if single_file_codegen or not has_ios_exports:\n        hmap_hdrs = objc_hdrs if has_ios_exports else []\n        hmap_header_tree_providers = []\n    else:\n        hmap_hdrs = []\n        hmap_header_tree_providers = objc_hdrs\n\n    hmap_name = name + \"_valdi_module_hmap\"\n    headermap(\n        name = hmap_name,\n        hdrs = hmap_hdrs,\n        header_tree_artifact_providers = hmap_header_tree_providers,\n        namespace = ios_module_name,\n        tags = [\"manual\"],\n    )\n    hmap_deps = [native.package_relative_label(hmap_name)]\n    hmap_copts = []\n\n    if single_file_codegen or not has_ios_exports:\n        private_hmap_hdrs = objc_hdrs if has_ios_exports else []\n        private_hmap_header_tree_providers = []\n    else:\n        private_hmap_hdrs = []\n        private_hmap_header_tree_providers = objc_hdrs\n\n    private_hmap_name = name + \"_valdi_module_private_hmap\"\n    headermap(\n        name = private_hmap_name,\n        hdrs = private_hmap_hdrs,\n        header_tree_artifact_providers = private_hmap_header_tree_providers,\n        add_to_includes = False,\n        tags = [\"manual\"],\n    )\n    private_hmap_deps = [native.package_relative_label(private_hmap_name)]\n    hmap_copts.append(\"-I$(execpath :{})\".format(private_hmap_name))\n\n    # headermap values, representing paths to headers, are paths relative to\n    # execroot, so we pass '-I.' to correctly resolve hmap header paths.\n    # -I. needs to come last after all .hmap includes\n    hmap_copts.append(\"-I.\")\n\n    # The umbrella header is a public header\n    # Umbrella headers for ObjC libraries are meant to only be imported\n    # from -Swift.h generated headers (replacing modular @import).\n    # The -Swift.h headers use workspace-relative imports of umbrella\n    # headers and exposing it via headermap is not necessary.\n    internal_umbrella_header_name = name + \"_umbrella.h\"\n    umbrella_header(\n        name = internal_umbrella_header_name,\n        hdrs = objc_hdrs if has_ios_exports else [],\n        umbrella_header_name = ios_module_name + \"-Swift\",\n        tags = [\"manual\"],\n    )\n    umbrella_headers = [\":\" + internal_umbrella_header_name]\n\n    # When has_ios_exports is False, use empty.c as a fallback source\n    # because objc_library requires at least one source file\n    actual_objc_srcs = objc_srcs if has_ios_exports else [\"@valdi//bzl/valdi:empty.c\"]\n    actual_objc_hdrs = objc_hdrs if has_ios_exports else []\n\n    client_objc_library(\n        name = name,\n        hdrs = [] + actual_objc_hdrs + umbrella_headers,\n        srcs = [] + actual_objc_srcs,\n        enable_swift_interop = True,\n        module_name = ios_module_name,\n        copts = COMPILER_FLAGS + hmap_copts,\n        sdk_frameworks = select({\n            \"@snap_platforms//conditions:macos\": [\"AppKit\"],\n            \"//conditions:default\": [\"UIKit\"],\n        }) + [\n            \"JavaScriptCore\",\n            \"QuartzCore\",\n            \"CoreGraphics\",\n            \"Security\",\n        ],\n        deps = kwargs.pop(\"deps\", []) + [\n            \"@valdi//valdi_core:valdi_core_objc\",\n        ] + hmap_deps,\n        implementation_deps = [] + private_hmap_deps,\n        tags = kwargs.pop(\"tags\", []) + [\n            \"exported\",\n            \"objc\",\n            \"app_size_owners=VALDI\",\n            \"res_drop_prefix=\" + IOS_OUTPUT_BASE,\n        ],\n        enable_objcpp = False,\n        generate_hmaps = False,\n        generate_umbrella_header = False,\n        **kwargs\n    )\n\ndef _setup_cpp_target(name, deps, compiled_module_target, visibility, single_file_codegen):\n    cpp_strip_prefix = \"cpp/release/src\"\n\n    # C++ codegen always outputs to release configuration\n    if single_file_codegen:\n        # For single file codegen, extract individual .cpp and .hpp files\n        extract_valdi_module_output(\n            name = \"cpp.srcs\",\n            compiled_module = compiled_module_target,\n            output_name = \"cpp_srcs\",\n        )\n\n        extract_valdi_module_output(\n            name = \"cpp.hdrs\",\n            compiled_module = compiled_module_target,\n            output_name = \"cpp_hdrs\",\n        )\n\n        cpp_srcs = [\":cpp.srcs\"]\n        cpp_hdrs = [\":cpp.hdrs\"]\n    else:\n        # For multi-file codegen, use extract_cpp_srcs to filter by extension\n        cpp_srcs_name = name + \"_cpp_srcs\"\n        cpp_hdrs_name = name + \"_cpp_hdrs\"\n\n        extract_cpp_srcs(\n            name = cpp_srcs_name,\n            compiled_module = compiled_module_target,\n            extension = \".cpp\",\n            strip_prefix = cpp_strip_prefix,\n        )\n\n        extract_cpp_srcs(\n            name = cpp_hdrs_name,\n            compiled_module = compiled_module_target,\n            extension = \".hpp\",\n            strip_prefix = cpp_strip_prefix,\n        )\n\n        cpp_srcs = [native.package_relative_label(cpp_srcs_name)]\n        cpp_hdrs = [native.package_relative_label(cpp_hdrs_name)]\n\n    # C++ codegen always outputs to release configuration.\n    # Both single_file_codegen and multi-file codegen strip the cpp/release/src/ prefix\n    # so that #include \"valdi_modules/...\" works correctly.\n    cc_library_kwargs = {\n        \"name\": name + \"_cpp\",\n        \"srcs\": cpp_srcs,\n        \"hdrs\": cpp_hdrs,\n        \"deps\": [_cpp_target_for_target(dep) for dep in deps] + [\"@valdi//valdi_core:valdi_core_cc\"],\n        \"visibility\": visibility,\n    }\n\n    if single_file_codegen:\n        # For single file mode, strip via cc_library's strip_include_prefix\n        cc_library_kwargs[\"strip_include_prefix\"] = cpp_strip_prefix\n    else:\n        # For multi-file mode, the extracted directory contains subdirectories\n        # We need to add it as an include path\n        cc_library_kwargs[\"includes\"] = [name + \"_cpp_hdrs\"]\n\n    native.cc_library(**cc_library_kwargs)\n\ndef _setup_native_target(name, deps, additional_native_deps, macos_deps, compiled_module_target, visibility):\n    ################\n    ####\n    #### Configure the native library target\n    ####\n    ################\n    extract_valdi_module_native_output(\n        name = \"android.debug.c\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_debug_nativesrc\",\n    )\n\n    extract_valdi_module_native_output(\n        name = \"android.release.c\",\n        compiled_module = compiled_module_target,\n        output_name = \"android_release_nativesrc\",\n    )\n\n    extract_valdi_module_native_output(\n        name = \"ios.debug.c\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_debug_nativesrc\",\n    )\n\n    extract_valdi_module_native_output(\n        name = \"ios.release.c\",\n        compiled_module = compiled_module_target,\n        output_name = \"ios_release_nativesrc\",\n    )\n\n    native_deps = [_native_target_for_target(dep) for dep in deps]\n\n    static_res_lib_name = \"{}_static_res\".format(name)\n\n    valdi_static_resource(\n        name = static_res_lib_name,\n        srcs = source_set_select(\n            debug = [\n                \":android.debug.valdimodule\",\n                \":android.debug.sourcemaps\",\n            ],\n            release = [\":android.release.valdimodule\"],\n        ),\n    )\n\n    native_lib_name = \"{}_native\".format(name)\n    android_native_lib_name = \"{}_android\".format(native_lib_name)\n    ios_native_lib_name = \"{}_ios\".format(native_lib_name)\n    desktop_native_lib_name = \"{}_desktop\".format(native_lib_name)\n\n    valdi_module_native(\n        name = android_native_lib_name,\n        srcs = source_set_select(\n            debug = [\":android.debug.c\"],\n            release = [\":android.release.c\"],\n        ),\n        deps = [\"{}_android\".format(dep) for dep in native_deps] + additional_native_deps,\n    )\n\n    valdi_module_native(\n        name = ios_native_lib_name,\n        # TODO(simon): Make native compilation configurable on a per platform basis\n        # Disable on iOS for now to unblock.\n        srcs = [],\n        # srcs = source_set_select(\n        #     debug = [\":ios.debug.c\"],\n        #     release = [\":ios.release.c\"],\n        # ),\n        deps = [\"{}_ios\".format(dep) for dep in native_deps] + additional_native_deps,\n    )\n\n    desktop_deps = [\"{}_desktop\".format(dep) for dep in native_deps] + additional_native_deps\n    if macos_deps:\n        desktop_deps = desktop_deps + select({\n            \"@snap_platforms//conditions:macos\": macos_deps,\n            \"//conditions:default\": [],\n        })\n\n    valdi_module_native(\n        name = desktop_native_lib_name,\n        srcs = source_set_select(\n            debug = [\":android.debug.c\"],\n            release = [\":android.release.c\"],\n        ) + [\":{}\".format(static_res_lib_name)],\n        deps = desktop_deps,\n    )\n\n    native.alias(\n        name = native_lib_name,\n        actual = select({\n            \"@snap_platforms//conditions:ios\": ios_native_lib_name,\n            \"@snap_platforms//conditions:android\": android_native_lib_name,\n            \"@snap_platforms//conditions:macos\": desktop_native_lib_name,\n            \"@snap_platforms//conditions:linux\": desktop_native_lib_name,\n        }),\n        visibility = visibility,\n    )\n\n# Helpers to construct related target label from the original valdi module label\ndef _valdi_compiled_target_for_target(target):\n    label = native.package_relative_label(target)\n    return label.relative(\":\" + label.name)\n\ndef _kt_target_for_target(target):\n    label = native.package_relative_label(target)\n    return label.relative(\":\" + label.name + \"_kt\")\n\ndef _native_target_for_target(target):\n    label = native.package_relative_label(target)\n    return label.relative(\":\" + label.name + \"_native\")\n\ndef _cpp_target_for_target(target):\n    label = native.package_relative_label(target)\n    return label.relative(\":\" + label.name + \"_cpp\")\n\ndef _objc_target_for_target(target, target_suffix = \"\"):\n    label = native.package_relative_label(target)\n    return label.relative(\":\" + label.name + target_suffix + \"_objc\")\n\ndef _objc_api_target_for_target(target):\n    return _objc_target_for_target(target, target_suffix = \"_api\")\n\ndef _ios_target_for_target(target, target_suffix = \"\"):\n    label = native.package_relative_label(target)\n    return label.relative(\":\" + label.name + target_suffix + \"_ios\")\n\ndef _resource_target_for_target(target):\n    label = native.package_relative_label(target)\n    return label.relative(\":\" + label.name + \"_resource_group\")\n"
  },
  {
    "path": "bzl/valdi/valdi_module_android_common.bzl",
    "content": "# Deps every Valdi module target depends on.\n\nCOMMON_ANDROIDX_DEPS = [\n    \"@android_mvn//:androidx_annotation_annotation\",\n    \"@android_mvn//:androidx_appcompat_appcompat\",\n    \"@android_mvn//:androidx_core_core\",\n    \"@android_mvn//:javax_inject_javax_inject\",\n]\n\nCOMMON_FRAMEWORK_DEPS = [\n    \"@valdi//valdi_core:valdi_core_java\",\n    \"@valdi//valdi:valdi_java\",\n]\n"
  },
  {
    "path": "bzl/valdi/valdi_module_info_extractor.bzl",
    "content": "load(\":valdi_compiled.bzl\", \"ValdiModuleInfo\")\nload(\":valdi_extract_output_rule_helper.bzl\", \"extract_valdi_output_rule\")\n\ndef empty_bundle_directory(name, src, visibility = [\"//visibility:private\"]):\n    \"\"\"Valid empty .bundle for apple_bundle_import when a valdi module has no bundle resources. Creates a filegroup.\"\"\"\n    native.filegroup(name = name, srcs = [src], visibility = visibility)\n\ndef _get_info_or_none(ctx):\n    module_info = ctx.attr.compiled_module[ValdiModuleInfo]\n    if not hasattr(module_info, ctx.attr.output_name):\n        fail(\"Module {} does not have an output named {}\".format(module_info.name, ctx.attr.output_name))\n\n    value = getattr(module_info, ctx.attr.output_name)\n    if value:\n        if type(value) == \"depset\":\n            return DefaultInfo(files = value)\n        elif type(value) == \"list\":\n            return DefaultInfo(files = depset(value))\n        else:\n            return DefaultInfo(files = depset([value]))\n\n    return None\n\ndef _extract_valdi_module_output_impl(ctx):\n    info = _get_info_or_none(ctx)\n    if info:\n        return info\n\n    # When output is empty, use fallback if provided (e.g. for resource bundles so apple_bundle_import gets at least one file).\n    fallback_files = ctx.attr.empty_bundle_fallback.files\n    if fallback_files.to_list():\n        return DefaultInfo(files = fallback_files)\n    return DefaultInfo()\n\ndef _extract_valdi_module_native_output_impl(ctx):\n    info = _get_info_or_none(ctx)\n    if info:\n        return info\n\n    # If we don't have output sources, we pass an empty source so that we can\n    # use the rule in cc_library\n    empty_source_depset = ctx.attr._empty_source.files\n\n    return DefaultInfo(\n        files = empty_source_depset,\n    )\n\ndef _get_deps_or_none(module):\n    module_info = module[ValdiModuleInfo]\n    if not hasattr(module_info, \"deps\"):\n        return None\n\n    return getattr(module_info, \"deps\")\n\ndef _extract_transitive_valdi_module_output_impl(ctx):\n    deps = []\n    for module in ctx.attr.modules:\n        module_deps = _get_deps_or_none(module)\n\n        if module_deps:\n            deps.extend(module_deps.to_list())\n\n        # Include current module\n        deps.append(module)\n\n    values = []\n    for dep in deps:\n        value = getattr(dep[ValdiModuleInfo], ctx.attr.output_name)\n        if value:\n            values.extend(value)\n\n    if values:\n        return DefaultInfo(files = depset(values))\n    else:\n        return DefaultInfo()\n\nextract_valdi_module_output = extract_valdi_output_rule(\n    implementation = _extract_valdi_module_output_impl,\n    attrs = {\n        \"output_name\": attr.string(\n            mandatory = True,\n        ),\n        \"empty_bundle_fallback\": attr.label(\n            default = Label(\"//bzl/valdi:empty_bundle_fallback_none\"),\n            allow_files = True,\n        ),\n    },\n)\n\nextract_valdi_module_native_output = extract_valdi_output_rule(\n    implementation = _extract_valdi_module_native_output_impl,\n    attrs = {\n        \"output_name\": attr.string(\n            mandatory = True,\n        ),\n        \"_empty_source\": attr.label(\n            default = Label(\"//bzl/valdi:empty.c\"),\n            allow_single_file = True,\n        ),\n    },\n)\n\nextract_transitive_valdi_module_output = rule(\n    implementation = _extract_transitive_valdi_module_output_impl,\n    attrs = {\n        \"output_name\": attr.string(mandatory = True),\n        \"modules\": attr.label_list(\n            mandatory = True,\n            cfg = \"exec\",\n            providers = [ValdiModuleInfo],\n        ),\n        \"_empty_source\": attr.label(\n            default = Label(\"//bzl/valdi:empty.c\"),\n            allow_single_file = True,\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_module_native.bzl",
    "content": "COMPILER_FLAGS = [\n    \"-Wno-unused-label\",\n    \"-Wno-unused-variable\",\n    \"-fno-exceptions\",\n    \"-Wno-unused-but-set-variable\",\n    \"-Wno-unknown-warning-option\",\n    \"-Os\",  # TSN generated code needs more optimization than the default -Oz\n]\n\ndef valdi_module_native(name, srcs, deps):\n    native.cc_library(\n        name = name,\n        hdrs = [],\n        includes = [],\n        copts = COMPILER_FLAGS,\n        alwayslink = 1,\n        srcs = srcs if srcs else [],\n        deps = [\"@valdi//tsn\"] + deps,\n        visibility = [\"//visibility:public\"],\n    )\n"
  },
  {
    "path": "bzl/valdi/valdi_paths.bzl",
    "content": "load(\"@bazel_skylib//lib:paths.bzl\", \"paths\")\nload(\"@bazel_skylib//lib:sets.bzl\", \"sets\")\nload(\n    \"common.bzl\",\n    \"ANDROID_RESOURCE_VARIANT_DIRECTORIES\",\n    \"TYPESCRIPT_DUMPED_SYMBOLS_DIR\",\n    \"TYPESCRIPT_GENERATED_TS_DIR\",\n    \"TYPESCRIPT_OUTPUT_DIR\",\n)\n\ndef replace_prefix(text, prefix_to_drop, replacement_prefix):\n    without_prefix = text.removeprefix(prefix_to_drop)\n    with_new_prefix = replacement_prefix + without_prefix\n    return with_new_prefix\n\ndef replace_suffix(text, suffix_to_drop, replacement_suffix):\n    without_suffix = text.removesuffix(suffix_to_drop)\n    with_new_suffix = without_suffix + replacement_suffix\n    return with_new_suffix\n\ndef _resolve_module_name_for_path(module_path, module_name):\n    if \"@\" in module_name and \"node_modules\" in module_path:\n        # Scoped modules are in the form of <module_name>@<scope>\n        # Need to re-format it into @<scope>/<module_name> when performing path related operations\n        module_components = module_name.split(\"@\")\n        name = module_components[0]\n        scope = \"@\" + module_components[1]\n\n        return paths.join(scope, name)\n\n    return module_name\n\ndef _fix_base_dir_path(f, path):\n    # Under linked build conditions, the path is relative to the linked workspace root.\n    # Fix up the path to ensure the rules work correctly.\n    owner_package = f.owner.package\n    base_dir_idx = path.find(owner_package + \"/\")\n    if base_dir_idx < 0:\n        fail(\"Expecting {} to contain path {}\".format(path, owner_package))\n    return path[base_dir_idx:]\n\ndef _get_all_unique_directories(files):\n    directories = sets.make()\n\n    for file in files:\n        directory = paths.dirname(file.path)\n        sets.insert(directories, directory)\n\n    return sets.to_list(directories)\n\ndef _get_relative_project_path_for_source_file(f, module_name, module_directory):\n    fixed_path = _fix_base_dir_path(f, f.path)\n    module_name = _resolve_module_name_for_path(fixed_path, module_name)\n\n    if f.path.startswith(module_directory):\n        # Note: This is fragile and this breaks if there are two directories nested like\n        # module_name/module_name/file .\n        # Handle items that are within the module we are currently processing\n        relative_project_path = replace_prefix(fixed_path, f.owner.package, module_name)\n    else:\n        # handles items outside of the module\n        relative_project_path = replace_prefix(fixed_path, f.owner.package + \"/\", \"\")\n\n    return relative_project_path\n\n# File path processing utility for transforming the file path of a module's source file\n# into the expected output file path.\ndef _expected_output_file_path_for_own_source_file(relative_project_path, suffix_to_drop, replacement_suffix, output_dir):\n    replacement_prefix = output_dir + \"/\"\n    with_new_prefix = paths.join(replacement_prefix, relative_project_path)\n    output_file_path = replace_suffix(with_new_prefix, suffix_to_drop, replacement_suffix)\n\n    return output_file_path\n\ndef _get_base_output_dir(declared_output_path, resolved_output_path):\n    path_len_diff = len(resolved_output_path) - len(declared_output_path)\n\n    if path_len_diff and resolved_output_path[path_len_diff - 1] == \"/\":\n        path_len_diff -= 1\n\n    return resolved_output_path[:path_len_diff]\n\ndef _get_current_directory(path):\n    return path[path.rfind(\"/\") + 1:]\n\n# For a given .ts, .tsx, .js source file, return the expected path to the output compiled JS file.\ndef output_declaration_compiled_file_path_for_source_file(f, module_name, module_directory, replacement_suffix = \".js\"):\n    suffix_to_drop = \".\" + f.extension\n    output_dir = \"web/debug/assets/\"\n\n    # For now, this needs to be fixed eventually\n    # src/valdi_modules/src/valdi/<module_name>/debug/assets/<module_name>/src\n    js_output_path = _expected_output_file_path_for_own_source_file(\n        _get_relative_project_path_for_source_file(f, module_name, module_directory),\n        suffix_to_drop = suffix_to_drop,\n        replacement_suffix = replacement_suffix,\n        output_dir = output_dir,\n    )\n    return js_output_path\n\n# For a given .ts, .tsx, .vue, .module.css, .module.scss source file, return\n# the expected path to the output .d.ts file.\ndef output_declaration_file_path_for_source_file(f, module_name, module_directory):\n    suffix_to_drop = \".\" + f.extension\n    replacement_suffix = \".d.ts\"\n    output_dir = TYPESCRIPT_OUTPUT_DIR\n\n    # 1. src/valdi_modules/src/valdi/coreutils/src/ArrayUtils.ts\n    # 2. coreutils/src/ArrayUtils.ts\n    # 3. .valdi_build/compile/typescript/output/coreutils/src/ArrayUtils.ts\n    # 4. .valdi_build/compile/typescript/output/coreutils/src/ArrayUtils.d.ts\n    dts_output_path = _expected_output_file_path_for_own_source_file(\n        _get_relative_project_path_for_source_file(f, module_name, module_directory),\n        suffix_to_drop = suffix_to_drop,\n        replacement_suffix = replacement_suffix,\n        output_dir = output_dir,\n    )\n    return dts_output_path\n\ndef _output_declaration_file_path_for_legacy_source_file(f, module_name, module_directory):\n    if (f.basename.endswith(\".module.css\") or f.basename.endswith(\".module.scss\")):\n        suffix_to_drop = \".module.\" + f.extension\n        replacement_suffix = \".module.\" + f.extension + \".d.ts\"\n        output_dir = TYPESCRIPT_GENERATED_TS_DIR\n    elif (f.basename.endswith(\".vue\")):\n        suffix_to_drop = \".vue\"\n        replacement_suffix = \".vue.d.ts\"\n        output_dir = TYPESCRIPT_OUTPUT_DIR\n    else:\n        fail(\"Unknown extension, can't infer location for cote generated .d.ts file: {}\".format(f.path))\n\n    # 1. src/valdi_modules/src/valdi/snapchatter_selection/src/components/SelectionSelector.module.scss\n    # 2. snapchatter_selection/src/components/SelectionSelector.module.scss\n    # 3. .valdi_build/compile/typescript/output/snapchatter_selection/src/components/SelectionSelector.module.scss\n    # 4. .valdi_build/compile/typescript/output/snapchatter_selection/src/components/SelectionSelector.module.scss.d.ts\n    dts_output_path = _expected_output_file_path_for_own_source_file(\n        _get_relative_project_path_for_source_file(f, module_name, module_directory),\n        suffix_to_drop = suffix_to_drop,\n        replacement_suffix = replacement_suffix,\n        output_dir = output_dir,\n    )\n    return dts_output_path\n\ndef get_sql_dts_paths(db_names, sql_srcs, module_name, module_directory):\n    if not db_names:\n        return []\n    result = []\n    sq_srcs = [_get_relative_project_path_for_source_file(src, module_name, module_directory) for src in sql_srcs if src.path.endswith(\".sq\")]\n    for sql_file_path in sq_srcs:\n        # The logic below mimics the one used by the SQL Compiler which drops the DB name and outputs everything in the same directory\n        # 1. src/valdi_modules/src/valdi/creative_tools_platform/sql/CTPStorage/FeedTree.sq\n        # 2. src/valdi_modules/src/valdi/creative_tools_platform/sql/CTPStorage/\n        # 3. .valdi_build/compile/generated_ts/creative_tools_platform/src/sqlgen/\n        # 4. .valdi_build/compile/generated_ts/creative_tools_platform/src/sqlgen/FeedTreeTypes.d.ts\n        # 5. .valdi_build/compile/generated_ts/creative_tools_platform/src/sqlgen/FeedTreeQueries.d.ts\n        prefix_to_drop = paths.join(module_name, \"sql/\")\n        db_name = replace_prefix(sql_file_path, prefix_to_drop, \"\").split(\"/\")[0]\n\n        prefix_to_drop = paths.join(prefix_to_drop, db_name) + \"/\"\n        prefix_to_add = paths.join(TYPESCRIPT_OUTPUT_DIR, module_name, \"src/sqlgen/\")\n\n        suffix = sql_file_path.removeprefix(prefix_to_drop).removesuffix(\".sq\")\n        output_location = paths.join(prefix_to_add, suffix)\n\n        result.append(output_location + \"Types.d.ts\")\n        result.append(output_location + \"Queries.d.ts\")\n\n    # Also add database dts files\n    for db_name in db_names:\n        result.append(paths.join(TYPESCRIPT_OUTPUT_DIR, module_name, \"src/sqlgen\", db_name + \".d.ts\"))\n\n    return result\n\ndef get_legacy_vue_srcs_dts_paths(legacy_vue_srcs, module_name, module_directory):\n    result = []\n    for f in legacy_vue_srcs:\n        dts_output_path = _output_declaration_file_path_for_legacy_source_file(f, module_name, module_directory)\n        result.append(dts_output_path)\n        result.append(replace_suffix(dts_output_path, \".d.ts\", \".generated.d.ts\"))\n\n    return result\n\ndef get_ids_yaml_dts_path(ts_generated_ts_dir, module_name, ids_yaml):\n    \"\"\" Returns the path to the generated ids.d.ts file. \"\"\"\n    return [paths.join(ts_generated_ts_dir, module_name, \"ids.d.ts\")] if ids_yaml else []\n\ndef get_strings_dts_path(ts_generated_ts_dir, module_name, strings_srcs):\n    \"\"\" Returns the path to the generated Strings.d.ts file, if any strings_srcs are provided. \"\"\"\n    return [paths.join(ts_generated_ts_dir, module_name, \"src\", \"Strings.d.ts\")] if strings_srcs else []\n\ndef resolve_relative_project_path(f, module_name, module_directory):\n    if f.is_source:\n        return _get_relative_project_path_for_source_file(f, module_name, module_directory)\n    else:\n        # declaration file was generated\n        fixed_path = _fix_base_dir_path(f, f.short_path)\n        module_name = _resolve_module_name_for_path(fixed_path, module_name)\n        short_path = replace_prefix(fixed_path, f.owner.package, module_name)\n\n        output_dir = TYPESCRIPT_OUTPUT_DIR\n        if short_path.endswith(\".module.css.d.ts\") or short_path.endswith(\".module.scss.d.ts\"):\n            output_dir = TYPESCRIPT_GENERATED_TS_DIR\n        elif short_path.endswith(\"/ids.d.ts\"):\n            output_dir = TYPESCRIPT_GENERATED_TS_DIR\n        elif short_path.endswith(\"/Strings.d.ts\"):\n            # TODO: wire up the generated Strings.d.ts separately from other declarations?\n            #       this way we wouldn't need to detect this just using an .endswith\n            output_dir = TYPESCRIPT_GENERATED_TS_DIR\n        elif short_path.endswith(\"/compilation-metadata.json\"):\n            output_dir = TYPESCRIPT_DUMPED_SYMBOLS_DIR\n\n        # Converts from \"src/valdi_modules/src/valdi/test_module_generated_types/.valdi_build/typescript/output/test_module_generated_types/src/dummy.d.ts\"\n        # to \"test_module_generated_types/src/dummy.d.ts\"\n        # For scoped modules, the path will contain @<scope>/<module_name> which should shorten to\n        # \"@<scope>/<module_name>/src/dummy.d.ts\"\n        prefix_to_drop = paths.join(module_name, output_dir) + \"/\"\n\n        return replace_prefix(short_path, prefix_to_drop, \"\")\n\ndef get_resources_dirs(resources):\n    directories = _get_all_unique_directories(resources)\n\n    filtered_variant_directories = []\n\n    for directory in directories:\n        # explicitly exclude any of the image variations that valdi accepts\n        current_directory = _get_current_directory(directory)\n\n        if current_directory not in ANDROID_RESOURCE_VARIANT_DIRECTORIES:\n            filtered_variant_directories.append(current_directory)\n\n    return filtered_variant_directories\n\ndef get_resources_dts_paths(module_name, resources):\n    filtered_variant_directories = get_resources_dirs(resources)\n\n    resources_paths = []\n    for current_directory in filtered_variant_directories:\n        # by default, we use res.ts\n        # nested subfolders use the name of the folder as the name of their generated typescript file, inside a res directory\n        if current_directory == \"res\":\n            output_basename = \"res.d.ts\"\n        else:\n            output_basename = paths.join(\"res\", current_directory + \".d.ts\")\n\n        resources_paths.append(paths.join(TYPESCRIPT_OUTPUT_DIR, module_name, output_basename))\n\n    return resources_paths\n\ndef infer_base_output_dir(declared_output_paths, resolved_outputs):\n    \"\"\" Resolves the base output directory given the declared outputs\n\n     When using actions.declare_file() or actions.declare_directory(), Bazel will\n     give us a relative path from PWD where we can write the file or directory. That\n     relative path will have some arbitrary path components that we can't know in advance,\n     for example: actions.declare_file('test.txt') might return 'bazel-out/bla/foo/bar/test.txt'\n     _infer_base_output_dir aims to resolve that directory, in this example that would be\n     'bazel-out/bla/foo/bar'. We pass that directory to the compiler so that it can write\n     files into it.\n    \"\"\"\n\n    base_output_dir = None\n\n    for (declared_output_path, resolved_output) in zip(declared_output_paths, resolved_outputs):\n        resolved_base_output_dir = _get_base_output_dir(declared_output_path, resolved_output.path)\n        if not base_output_dir:\n            base_output_dir = resolved_base_output_dir\n        elif base_output_dir != resolved_base_output_dir:\n            fail(\"Base output dir mismatch between {} and {}\".format(base_output_dir, resolved_base_output_dir))\n\n    return base_output_dir\n\ndef resolve_module_dir_and_name(label):\n    module_directory = None\n    if label.workspace_root:\n        module_directory = paths.join(label.workspace_root, label.package)\n    else:\n        module_directory = label.package\n\n    # TODO(simon): Remove this assumption. We here resolve the module name\n    # based on its directory.\n    module_name = paths.basename(module_directory)\n\n    return (module_directory, module_name)\n"
  },
  {
    "path": "bzl/valdi/valdi_projectsync.bzl",
    "content": "load(\"@bazel_skylib//lib:paths.bzl\", \"paths\")\nload(\"@bazel_skylib//rules:common_settings.bzl\", \"BuildSettingInfo\")\nload(\":valdi_compiled.bzl\", \"ValdiModuleInfo\")\nload(\":valdi_paths.bzl\", \"get_ids_yaml_dts_path\", \"get_resources_dirs\", \"get_sql_dts_paths\", \"get_strings_dts_path\", \"infer_base_output_dir\", \"resolve_module_dir_and_name\", \"resolve_relative_project_path\")\nload(\":valdi_run_compiler.bzl\", \"generate_config\", \"run_valdi_compiler\")\nload(\":valdi_toolchain_type.bzl\", \"VALDI_TOOLCHAIN_TYPE\")\n\n_BUILD_DIR = \".valdi_build/projectsync\"\n_TYPESCRIPT_GENERATED_TS_DIR = paths.join(_BUILD_DIR, \"generated_ts\")\n\ndef _prepare_explicit_input_list_file(ctx, module_name):\n    \"\"\" Write a JSON file with the list of all files that should be passed to the Valdi compiler. \"\"\"\n\n    all_inputs = []\n    all_inputs += ctx.files.sql_srcs\n    all_inputs += ctx.files.strings_json_srcs\n    all_inputs += ctx.files.res\n\n    if ctx.file.ids_yaml:\n        all_inputs.append(ctx.file.ids_yaml)\n\n    dependencies = depset(direct = all_inputs)\n    dependencies_list = dependencies.to_list()\n\n    files = []\n    (module_directory, _) = resolve_module_dir_and_name(ctx.label)\n\n    for dep in dependencies_list:\n        dep_path = dep.path\n\n        relative_project_path = resolve_relative_project_path(dep, module_name, module_directory)\n\n        files.append({\"file\": dep_path, \"relative_project_path\": relative_project_path})\n\n    explicit_input_list_file = ctx.actions.declare_file(\"projectsync_explicit_input_list.json\")\n\n    module_content = ctx.attr.target[ValdiModuleInfo].module_definition\n\n    content = json.encode_indent({\"entries\": [\n        {\n            \"module_name\": module_name,\n            \"module_path\": module_directory,\n            \"module_content\": module_content,\n            \"files\": files,\n        },\n    ]}, indent = \"  \")\n    ctx.actions.write(output = explicit_input_list_file, content = content)\n\n    return (explicit_input_list_file, dependencies_list, module_directory)\n\ndef _get_files_output_paths(ctx, module_name, module_directory):\n    outputs = []\n\n    # tablename.d.ts files\n    outputs += get_sql_dts_paths(ctx.attr.sql_db_names, ctx.files.sql_srcs, module_name, module_directory)\n\n    # ids.d.ts\n    outputs += get_ids_yaml_dts_path(_TYPESCRIPT_GENERATED_TS_DIR, module_name, ctx.file.ids_yaml)\n\n    # Strings.d.ts\n    strings_json_srcs = ctx.files.strings_json_srcs\n    outputs += get_strings_dts_path(_TYPESCRIPT_GENERATED_TS_DIR, module_name, strings_json_srcs)\n\n    # res.ts\n    for res_dir in get_resources_dirs(ctx.files.res):\n        res_file = paths.join(_TYPESCRIPT_GENERATED_TS_DIR, module_name, \"{}.ts\".format(res_dir))\n        outputs.append(res_file)\n\n    return outputs\n\ndef _declare_compiler_outputs(ctx, module_name, module_directory):\n    files_output_paths = _get_files_output_paths(ctx, module_name, module_directory)\n\n    outputs = [ctx.actions.declare_file(path) for path in files_output_paths]\n\n    return (infer_base_output_dir(files_output_paths, outputs), outputs)\n\ndef _prepare_arguments(args, log_level, config_yaml_file, explicit_input_list_file, module_name, base_output_dir):\n    \"\"\" Prepare arguments for the Valdi compiler invocation. \"\"\"\n\n    args.use_param_file(\"@%s\", use_always = True)\n    args.set_param_file_format(\"multiline\")\n\n    args.add(\"--config\", config_yaml_file)\n    args.add(\"--explicit-input-list-file\", explicit_input_list_file)\n\n    args.add(\"--build-dir\", paths.join(\"$PWD\", base_output_dir, _BUILD_DIR))\n\n    args.add(\"--module\", module_name)\n\n    args.add(\"--disable-disk-cache\")\n    args.add(\"--skip-remove-orphan-files\")\n\n    args.add(\"--log-level\", log_level)\n    args.add(\"--compile\")\n    args.add(\"--generate-ts-res-files\")\n\n    # Disable concurrency, to free CPU cores to do the actual build.\n    # Valdi compiler is fast enough to keep up with Bazel parallelization.\n    args.add(\"--disable-concurrency\")\n\n    # Configure compilation\n    # TODO: should we create a Bazel rule for this configuration?\n    args.add(\"--config-value\", \"build_dir=\" + explicit_input_list_file.dirname)\n    args.add(\"--config-value\", \"project_name=\" + module_name)\n\n    return args\n\ndef _invoke_valdi_compiler(ctx, module_name):\n    \"\"\" Invoke valdi Compiler for the requested module.\n\n        This function takes care of reproducing the required directory structure which Valdi expects\n        (source files should live in subdirectories relative to where the config.yaml files lives, for example).\n\n    Args:\n        ctx: The context of the current rule invocation\n        module_name: The name of the module to compile\n\n    Returns:\n        A list of files that are produced by the Valdi compiler\n    \"\"\"\n\n    #############\n    # 1. Generate the project config file that is currently required by the Valdi compiler.\n    #    The Valdi compiler uses the project config file location as the initial base directory\n    #    (the base_dir read from the config is then resolved relative to the project config file's location)\n    config_yaml_file = generate_config(ctx)\n\n    #############\n    # 2. Prepare the explicit input list file for the compiler.\n    (explicit_input_list_file, all_inputs, module_directory) = _prepare_explicit_input_list_file(ctx, module_name)\n\n    #############\n    # 3. Gather all outputs produced by the Valdi compiler\n    (base_output_dir, outputs) = _declare_compiler_outputs(ctx, module_name, module_directory)\n\n    #############\n    # 5. Set up the action that executes the Valdi compiler\n\n    if len(outputs) > 0:\n        args = _prepare_arguments(config_yaml_file = config_yaml_file, base_output_dir = base_output_dir, module_name = module_name, explicit_input_list_file = explicit_input_list_file, args = ctx.actions.args(), log_level = ctx.attr.log_level[BuildSettingInfo].value)\n\n        run_valdi_compiler(\n            ctx = ctx,\n            args = args,\n            outputs = outputs,\n            inputs = all_inputs + [config_yaml_file, explicit_input_list_file],\n            mnemonic = \"ValdiProjectSync\",\n            progress_message = \"Running projectsync for module: \" + module_name,\n            use_worker = False,\n            include_tools = False,\n        )\n\n    return outputs\n\ndef _to_bazel_str(label):\n    if label.repo_name:\n        return \"@{}//{}:{}\".format(label.repo_name, label.package, label.name)\n    else:\n        return \"//{}:{}\".format(label.package, label.name)\n\ndef _valdi_projectsync_impl(ctx):\n    module_name = ctx.attr.target[ValdiModuleInfo].name\n    outputs = _invoke_valdi_compiler(ctx, module_name)\n\n    projectsync_json = ctx.actions.declare_file(\"projectsync.json\")\n\n    all_deps = []\n    for dep in ctx.attr.target[ValdiModuleInfo].deps.to_list():\n        all_deps.append(_to_bazel_str(dep.label))\n\n    projectsync_json_dict = {\n        \"target\": _to_bazel_str(ctx.attr.target.label),\n        \"dependencies\": all_deps,\n    }\n\n    if len(outputs) > 0:\n        projectsync_json_dict[\"ts_generated_dir\"] = paths.join(\n            _TYPESCRIPT_GENERATED_TS_DIR,\n            module_name,\n        )\n\n    projectsync_json_content = json.encode_indent(projectsync_json_dict, indent = \"  \")\n    ctx.actions.write(output = projectsync_json, content = projectsync_json_content)\n\n    return [\n        DefaultInfo(files = depset(outputs + [projectsync_json])),\n    ]\n\nvaldi_projectsync = rule(\n    implementation = _valdi_projectsync_impl,\n    toolchains = [VALDI_TOOLCHAIN_TYPE],\n    attrs = {\n        \"target\": attr.label(\n            doc = \"The module target\",\n            mandatory = True,\n            providers = [[ValdiModuleInfo]],\n        ),\n        \"ids_yaml\": attr.label(\n            doc = \"Optional ids.yaml file for this module\",\n            allow_single_file = [\"ids.yaml\"],\n        ),\n        \"strings_json_srcs\": attr.label_list(\n            doc = \"String source files for this module\",\n            allow_files = True,\n        ),\n        \"res\": attr.label_list(\n            doc = \"List of resources for this module\",\n            allow_files = True,\n        ),\n        \"sql_srcs\": attr.label_list(\n            doc = \"List of SQL files for this module\",\n            allow_files = [\".sql\", \".sq\", \".sqm\", \"sql_types.yaml\", \"sql_manifest.yaml\"],\n        ),\n        \"sql_db_names\": attr.string_list(),\n        \"log_level\": attr.label(\n            doc = \"The log level for the Valdi compiler\",\n            default = \"@valdi//bzl/valdi:compilation_log_level\",\n        ),\n        \"_template\": attr.label(\n            doc = \"The template config.yaml file\",\n            allow_single_file = True,\n            default = \"valdi_config.yaml.tpl\",\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_protodecl_to_js.bzl",
    "content": "def _protodecl_to_js_dir_impl(ctx):\n    # Emits under: bazel-bin/<pkg>/<target>/__protodecl__/\n    outdir = ctx.actions.declare_directory(\"%s/__protodecl__\" % ctx.label.name)\n\n    script = ctx.actions.declare_file(ctx.label.name + \"_emit.sh\")\n    ctx.actions.write(\n        output = script,\n        is_executable = True,\n        content = r\"\"\"#!/usr/bin/env bash\n        set -euo pipefail\n        OUT=\"$1\"; shift\n        rm -rf \"$OUT\"; mkdir -p \"$OUT\"\n\n        node=\"$NODE\"\n\n        # For each input .protodecl, emit OUT/<rewritten path>.protodecl.js exporting a Uint8Array\n        for f in \"$@\"; do\n          # <SEG_BEFORE_LAST_SRC>/src/<AFTER_LAST_SRC>  (fallback: drop first segment)\n          if [[ \"$f\" == *src/* ]]; then\n            prefix=\"${f%src/*}\"           # before LAST \"src/<...>\"\n            prefix=\"${prefix%/}\"          # drop trailing slash\n            seg=\"${prefix##*/}\"           # segment before that last src/\n            after=\"${f##*src/}\"           # AFTER the last \"src/\"\n            rel=\"${seg:+$seg/}src/$after\"\n          else\n            rel=\"${f#*/}\"\n          fi\n\n          base=\"${rel%.*}\"\n          dest=\"$OUT/$base.protodecl.js\"\n          mkdir -p \"$(dirname \"$dest\")\"\n\n          # Emit CommonJS that exports a base64 string of the raw bytes\n          \"$node\" -e 'const fs=require(\"fs\");const b=fs.readFileSync(process.argv[1]);process.stdout.write(\"module.exports=\"+JSON.stringify(b.toString(\"base64\"))+\";\");' \"$f\" > \"$dest\"\n        done\n        \"\"\",\n    )\n\n    inputs = depset(transitive = [t[DefaultInfo].files for t in ctx.attr.srcs])\n    args = [outdir.path] + [f.path for f in inputs.to_list()]\n\n    ctx.actions.run(\n        inputs = depset([script], transitive = [inputs]),\n        outputs = [outdir],\n        tools = [ctx.file._node],\n        executable = script,\n        arguments = args,\n        env = {\"NODE\": ctx.file._node.path},\n        progress_message = \"protodecl → js into %s\" % outdir.path,\n    )\n    return [DefaultInfo(files = depset([outdir]))]\n\nprotodecl_to_js_dir = rule(\n    implementation = _protodecl_to_js_dir_impl,\n    attrs = {\n        \"srcs\": attr.label_list(allow_files = True),\n        \"_node\": attr.label(\n            default = Label(\"@@nodejs//:node_bin\"),\n            allow_single_file = True,\n            cfg = \"exec\",\n        ),\n    },\n)\n\ndef _collapse_protodecl_paths_impl(ctx):\n    # Final collapsed tree\n    outdir = ctx.actions.declare_directory(ctx.label.name)\n\n    script = ctx.actions.declare_file(ctx.label.name + \"_collapse.sh\")\n    ctx.actions.write(\n        output = script,\n        is_executable = True,\n        content = r\"\"\"#!/usr/bin/env bash\nset -euo pipefail\nOUT=\"$1\"; shift\nrm -rf \"$OUT\"; mkdir -p \"$OUT\"\n\nrewrite_and_copy() {\n  local src=\"$1\" core rel\n\n  # If coming from .../__protodecl__/..., drop that segment first\n  if [[ \"$src\" == *\"/__protodecl__/\"* ]]; then\n    core=\"${src#*__protodecl__/}\"\n  else\n    core=\"$src\"\n  fi\n\n  # Rewrite to: <SEG_BEFORE_LAST_SRC>/src/<AFTER_LAST_SRC>\n  if [[ \"$core\" == *src/* ]]; then\n    prefix=\"${core%src/*}\"        # before LAST \"src/<...>\"\n    prefix=\"${prefix%/}\"\n    seg=\"${prefix##*/}\"           # segment before that last src/\n    after=\"${core##*src/}\"        # AFTER the last \"src/\"\n    rel=\"${seg:+$seg/}src/$after\"\n  else\n    # Fallback: drop first path segment\n    rel=\"${core#*/}\"\n  fi\n\n  local dest=\"$OUT/$rel\"\n  mkdir -p \"$(dirname \"$dest\")\"\n  cp -f \"$src\" \"$dest\"\n}\n\nfor p in \"$@\"; do\n  if [[ -d \"$p\" ]]; then\n    # Tree artifact: walk all files\n    while IFS= read -r -d '' f; do\n      rewrite_and_copy \"$f\"\n    done < <(find \"$p\" -type f -print0)\n  else\n    rewrite_and_copy \"$p\"\n  fi\ndone\n\"\"\",\n    )\n\n    inputs = depset(transitive = [t[DefaultInfo].files for t in ctx.attr.srcs])\n    args = [outdir.path] + [f.path for f in inputs.to_list()]\n\n    ctx.actions.run(\n        inputs = depset([script], transitive = [inputs]),\n        outputs = [outdir],\n        executable = script,\n        arguments = args,\n        progress_message = \"Collapsing protodecl paths into %s\" % outdir.path,\n    )\n    return [DefaultInfo(files = depset([outdir]))]\n\ncollapse_protodecl_paths = rule(\n    implementation = _collapse_protodecl_paths_impl,\n    attrs = {\n        \"srcs\": attr.label_list(allow_files = True),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_run_compiler.bzl",
    "content": "load(\n    \"common.bzl\",\n    \"NODE_MODULES_BASE\",\n)\nload(\":valdi_toolchain_type.bzl\", \"VALDI_TOOLCHAIN_TYPE\")\n\n# TODO: modify the compiler so that we don't need to pass in the config file and instead can just pass in all of these options as arguments\n# Generates a config.yaml file on the fly from a template,\n# so that we can customize the input and output paths for Bazel.\n# Eventually the parts of the yaml file we need to customize should be passed directly\n# to the Valdi compiler and then we won't need to tweak the yaml file anymore.\n# TODO(vasily): we could probably remove these completely and just symlink the source config + overrides\ndef generate_config(ctx):\n    config_file = \"valdi_config.yaml\"\n    out = ctx.actions.declare_file(config_file)\n    toolchain = ctx.toolchains[VALDI_TOOLCHAIN_TYPE].info\n\n    companion_path = toolchain.companion.files.to_list()[0].path\n    minify_config_path = toolchain.minify_config.files.to_list()[0].path\n    compiler_toolbox_path = toolchain.compiler_toolbox.files.to_list()[0].path\n    pngquant_path = toolchain.pngquant.files.to_list()[0].path\n\n    ctx.actions.expand_template(\n        output = out,\n        template = ctx.file._template,\n        substitutions = {\n            \"{IOS_OUTPUT_BASE}\": \"ios\",\n            \"{ANDROID_OUTPUT_BASE}\": \"android\",\n            \"{COMPANION_BINARY}\": companion_path + \"/scripts/run.sh\",\n            \"{MINIFY_CONFIG_PATH}\": \"$PWD/\" + minify_config_path,\n            \"{COMPILER_TOOLBOX_PATH}\": \"$PWD/\" + compiler_toolbox_path,\n            \"{PNGQUANT_PATH}\": \"$PWD/\" + pngquant_path,\n            \"{NODE_MODULES_DIR}\": NODE_MODULES_BASE,\n        },\n    )\n    return out\n\ndef resolve_compiler_executable(ctx, toolchain, include_tools):\n    \"\"\" Resolves the tools required to run the Valdi compiler action.\n\n        * compiler binary\n        * compiler_toolbox binary\n        * companion tool (see //src/valdi_internal/compiler/companion:bin_wrapper)\n        * minify config file\n        * pngquant binary\n        * sqldelight compiler binary\n\n    Args:\n        ctx: The context of the current rule invocation\n        toolchain: The toolchain info for the current rule invocation\n\n    Returns:\n        A tuple of (executable: File, tools: depset, input_manifests: List[RunfilesManifest])\n    \"\"\"\n\n    inputs_depsets = []\n    inputs_depsets.append(toolchain.compiler.files)\n\n    inputs_depsets.append(toolchain.companion.files)\n    companion = toolchain.companion\n    (companion_inputs, companion_runfile_manifests) = ctx.resolve_tools(tools = [companion])\n    inputs_depsets.append(companion_inputs)\n\n    manifests = []\n    manifests += companion_runfile_manifests\n    if include_tools:\n        inputs_depsets.append(toolchain.compiler_toolbox.files)\n        inputs_depsets.append(toolchain.minify_config.files)\n        inputs_depsets.append(toolchain.pngquant.files)\n        inputs_depsets.append(toolchain.sqldelight_compiler.files)\n\n        sqldelight_compiler = toolchain.sqldelight_compiler\n        (sqldelight_compiler_inputs, sqldelight_compiler_runfile_manifests) = ctx.resolve_tools(tools = [sqldelight_compiler])\n        inputs_depsets.append(sqldelight_compiler_inputs)\n\n        manifests += sqldelight_compiler_runfile_manifests\n\n    return (toolchain.compiler.files.to_list()[0], depset(transitive = inputs_depsets), manifests)\n\ndef run_valdi_compiler(ctx, args, outputs, inputs, mnemonic, progress_message, use_worker, include_tools = True):\n    \"\"\" Run the Valdi compiler with the provided arguments.\n    This will resolve the Valdi toolchain with the compiler executable\n    and emits outputs.\n    \"\"\"\n    toolchain = ctx.toolchains[VALDI_TOOLCHAIN_TYPE].info\n    (executable, tools, input_manifests) = resolve_compiler_executable(ctx, toolchain, include_tools)\n\n    companion_bin_wrapper = toolchain.companion.files.to_list()[0]\n    compiler_toolbox = toolchain.compiler_toolbox.files.to_list()[0]\n    pngquant = toolchain.pngquant.files.to_list()[0]\n    minify_config = toolchain.minify_config.files.to_list()[0]\n    client_sql = toolchain.sqldelight_compiler.files.to_list()\n\n    args.add(\"--bazel\")\n    args.add(\"--direct-companion-path\", companion_bin_wrapper)\n    args.add(\"--direct-compiler-toolbox-path\", compiler_toolbox)\n    args.add(\"--direct-pngquant-path\", pngquant)\n    args.add(\"--direct-minify-config-path\", minify_config)\n\n    if client_sql:\n        args.add(\"--direct-client-sql-path\", client_sql[0])\n\n    env = {\n        # required for the companion app execution under Bazel\n        \"BAZEL_BINDIR\": ctx.bin_dir.path,\n        # Enable Swift backtracing support to get stacktraces (see https://github.com/apple/swift/blob/main/docs/Backtracing.rst#how-do-i-configure-backtracing)\n        # \"SWIFT_BACKTRACE\": \"enable=yes,threads=all\", Disabled due to crash on MacOS 15.4 Compiler Toolbox error: swift runtime: backtrace-on-crash is not supported for privileged executables.\n    }\n\n    # Allow to pass the GCP service account via --action_env parameter\n    if \"VALDI_COMPILER_GCP_SERVICE_ACCOUNT\" in ctx.configuration.default_shell_env:\n        env[\"VALDI_COMPILER_GCP_SERVICE_ACCOUNT\"] = ctx.configuration.default_shell_env[\"VALDI_COMPILER_GCP_SERVICE_ACCOUNT\"]\n\n    ctx.actions.run(\n        outputs = outputs,\n        inputs = inputs,\n        executable = executable,\n        tools = tools,\n        input_manifests = input_manifests,\n        arguments = [args],\n        env = env,\n        use_default_shell_env = True,\n        toolchain = VALDI_TOOLCHAIN_TYPE,\n        mnemonic = mnemonic,\n        progress_message = progress_message,\n        execution_requirements = {\"supports-workers\": \"1\" if use_worker else \"0\", \"requires-worker-protocol\": \"json\"},\n    )\n"
  },
  {
    "path": "bzl/valdi/valdi_static_resource.bzl",
    "content": "load(\":valdi_run_compiler.bzl\", \"run_valdi_compiler\")\nload(\":valdi_toolchain_type.bzl\", \"VALDI_TOOLCHAIN_TYPE\")\n\ndef _valdi_static_resource_impl(ctx):\n    output_file = ctx.actions.declare_file(\"{}.cpp\".format(ctx.label.name))\n\n    args = ctx.actions.args()\n\n    args.add(\"--gen-static-res\")\n\n    for f in ctx.files.srcs:\n        args.add(\"--input\", f)\n    args.add(\"--out\", output_file)\n\n    run_valdi_compiler(\n        ctx = ctx,\n        args = args,\n        outputs = [output_file],\n        inputs = ctx.files.srcs,\n        mnemonic = \"ValdiGenStaticResource\",\n        progress_message = \"Generating static Valdi resource\",\n        use_worker = False,\n    )\n\n    return [\n        DefaultInfo(\n            files = depset([output_file]),\n        ),\n    ]\n\nvaldi_static_resource = rule(\n    implementation = _valdi_static_resource_impl,\n    toolchains = [VALDI_TOOLCHAIN_TYPE],\n    attrs = {\n        \"srcs\": attr.label_list(\n            cfg = \"exec\",\n            doc = \"List of files to package as static resources\",\n            mandatory = True,\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_test.bzl",
    "content": "load(\"@bazel_skylib//rules:common_settings.bzl\", \"BuildSettingInfo\")\nload(\":valdi_compiled.bzl\", \"ValdiModuleInfo\")\n\ndef _collect_target_runfiles(target):\n    # Collect target and its dependencies module infos\n    module_infos = [target[ValdiModuleInfo]]\n    module_infos += [d[ValdiModuleInfo] for d in target[ValdiModuleInfo].deps.to_list()]\n\n    # Extract valdi modules and source maps\n    valdi_modules = [m.android_debug_valdimodule for m in module_infos if m.android_debug_valdimodule]\n    source_maps = [m.android_debug_sourcemaps for m in module_infos if m.android_debug_sourcemaps]\n    return valdi_modules + source_maps\n\ndef _is_test_file(f, path_to_module):\n    \"\"\"Check if a file is in a 'test' directory relative to the module.\"\"\"\n\n    # Simple check: file path contains /test/ segment or dirname ends with /test\n    path = f.path\n    return \"/test/\" in path or path.endswith(\"/test\")\n\ndef _valdi_test_impl(ctx):\n    standalone_binary = ctx.executable._valdi_standalone_binary\n\n    path_to_module = ctx.label.package\n    test_paths = [f for f in ctx.files.srcs if _is_test_file(f, path_to_module)]\n\n    has_tests = len(test_paths) > 0\n\n    # Check if code coverage is enabled via `bazel coverage` command or explicit flag\n    code_coverage_enabled = ctx.configuration.coverage_enabled or ctx.attr.code_coverage[BuildSettingInfo].value\n\n    # Always include standalone module runfiles\n    valdimodules = _collect_target_runfiles(ctx.attr.target)\n    valdimodules += _collect_target_runfiles(ctx.attr._valdi_standalone)\n    module_paths = [\"--module_path {}\".format(f.short_path) for f in valdimodules]\n\n    test_script = ctx.actions.declare_file(\"test_wrapper.sh\")\n    if has_tests:\n        js_engine = ctx.attr.js_engine[BuildSettingInfo].value\n        cmd = \"{} --js_engine {} --script_path {}\".format(standalone_binary.short_path, js_engine, ctx.attr.test_runner)\n        if ctx.attr.hot_reload:\n            cmd += \" --debugger_service --hot_reload\"\n\n        if module_paths:\n            cmd += \" \" + \" \".join(module_paths)\n\n        cmd += \" -- --allow_incomplete_test_run --include_module {}\".format(ctx.attr.target[ValdiModuleInfo].name)\n        cmd += \" --junit_report_filename `basename $XML_OUTPUT_FILE` --junit_report_output_dir `dirname $XML_OUTPUT_FILE`\"\n\n        # Add code coverage flags when enabled\n        if code_coverage_enabled:\n            cmd += \" --code_coverage\"\n\n            # Use COVERAGE_OUTPUT_FILE if set by Bazel (when using `bazel coverage`),\n            # otherwise fallback to a file in TEST_UNDECLARED_OUTPUTS_DIR\n            cmd += \" --code_coverage_result \\\"${COVERAGE_OUTPUT_FILE:-$TEST_UNDECLARED_OUTPUTS_DIR/coverage.dat}\\\"\"\n    else:\n        cmd = \"echo 'No tests to run'\"\n\n    ctx.actions.write(\n        output = test_script,\n        content = cmd,\n        is_executable = True,\n    )\n\n    runfiles = ctx.runfiles(\n        files = [standalone_binary] + valdimodules,\n    )\n\n    return [DefaultInfo(executable = test_script, files = depset([standalone_binary] + valdimodules), runfiles = runfiles)]\n\nvaldi_test = rule(\n    implementation = _valdi_test_impl,\n    test = True,\n    fragments = [\"coverage\"],\n    attrs = {\n        \"target\": attr.label(\n            mandatory = True,\n            doc = \"The target to test\",\n        ),\n        \"test_runner\": attr.string(\n            default = \"valdi_standalone/src/TestsRunner\",\n            doc = \"The test runner script to evaluate\",\n        ),\n        \"hot_reload\": attr.bool(\n            default = False,\n            doc = \"Whether to enable hot reload and debugger service\",\n        ),\n        \"srcs\": attr.label_list(\n            doc = \"List of sources for this module\",\n            mandatory = True,\n            allow_files = [\".js\", \".ts\", \".tsx\", \".json\"],\n        ),\n        \"js_engine\": attr.label(\n            default = Label(\"@valdi//bzl/valdi:js_engine\"),\n            doc = \"The JS engine to use to run the tests\",\n        ),\n        \"code_coverage\": attr.label(\n            default = Label(\"@valdi//bzl/valdi:code_coverage_enabled\"),\n            doc = \"Enable code coverage collection during tests\",\n        ),\n        \"_valdi_standalone\": attr.label(\n            default = Label(\"@valdi//src/valdi_modules/src/valdi/valdi_standalone\"),\n            doc = \"The Valdi Standalone target to be added to all Valdi targets\",\n        ),\n        \"_valdi_standalone_binary\": attr.label(\n            executable = True,\n            cfg = \"exec\",\n            default = Label(\"@valdi_toolchain//:valdi_standalone\"),\n            doc = \"The Valdi Standalone binary used to run the test\",\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_toolchain.bzl",
    "content": "\"\"\" The file contains Bazel helper rules to register Valdi toolchains. \"\"\"\n\nValdiCompilerInfo = provider(\n    doc = \"Information about how to invoke the valdi compiler.\",\n    fields = [\n        \"compiler\",\n        \"compiler_toolbox\",\n        \"pngquant\",\n        \"companion\",\n        \"minify_config\",\n        \"sqldelight_compiler\",\n    ],\n)\n\ndef _valdi_toolchain_impl(ctx):\n    info = platform_common.ToolchainInfo(\n        info = ValdiCompilerInfo(\n            compiler = ctx.attr.compiler,\n            compiler_toolbox = ctx.attr.compiler_toolbox,\n            pngquant = ctx.attr.pngquant,\n            companion = ctx.attr.compiler_companion,\n            minify_config = ctx.attr.minify_config,\n            sqldelight_compiler = ctx.attr.sqldelight_compiler,\n        ),\n    )\n    return [info]\n\n# Generic rule definition.\nvaldi_toolchain = rule(\n    implementation = _valdi_toolchain_impl,\n    toolchains = [],\n    attrs = {\n        \"compiler\": attr.label(\n            executable = True,\n            cfg = \"exec\",\n            allow_single_file = True,\n            doc = \"The Valdi compiler to use. Must be a single-file executable (native_binary). For local development, see //compiler/compiler:local_valdi_compiler.\",\n        ),\n        \"compiler_toolbox\": attr.label(\n            executable = True,\n            cfg = \"exec\",\n            allow_single_file = True,\n            doc = \"The toolbox to use with the compiler.\",\n        ),\n        \"compiler_companion\": attr.label(\n            executable = True,\n            cfg = \"exec\",\n            doc = \"The companion to use with the compiler.\",\n        ),\n        \"minify_config\": attr.label(\n            default = \"//modules:minify_config\",\n        ),\n        \"pngquant\": attr.label(\n            executable = True,\n            cfg = \"exec\",\n            allow_single_file = True,\n            doc = \"The pngquant executable to use.\",\n        ),\n        \"sqldelight_compiler\": attr.label(\n            cfg = \"exec\",\n            doc = \"The sqldelight compiler to use.\",\n        ),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_toolchain_binary.bzl",
    "content": "def _transition_impl(settings, attr):\n    return {\n        \"@snap_platforms//flavors:snap_flavor\": \"production\",\n        \"@valdi//bzl/runtime_flags:enable_asserts\": False,\n        \"@valdi//bzl/runtime_flags:enable_logging\": False,\n        \"@valdi//bzl/runtime_flags:enable_tracing\": False,\n        \"@valdi//bzl/runtime_flags:enable_debug\": False,\n    }\n\nvaldi_toolchain_transition = transition(\n    implementation = _transition_impl,\n    inputs = [],\n    outputs = [\n        \"@snap_platforms//flavors:snap_flavor\",\n        \"@valdi//bzl/runtime_flags:enable_asserts\",\n        \"@valdi//bzl/runtime_flags:enable_logging\",\n        \"@valdi//bzl/runtime_flags:enable_tracing\",\n        \"@valdi//bzl/runtime_flags:enable_debug\",\n    ],\n)\n\ndef _valdi_toolchain_binary_impl(ctx):\n    bin_file = ctx.attr.name\n    files = ctx.attr.bin[DefaultInfo].files\n\n    f = ctx.actions.declare_file(bin_file)\n    ctx.actions.symlink(output = f, target_file = files.to_list()[0], is_executable = True)\n\n    return [DefaultInfo(executable = f, files = files)]\n\nvaldi_toolchain_binary = rule(\n    implementation = _valdi_toolchain_binary_impl,\n    executable = True,\n    cfg = valdi_toolchain_transition,\n    attrs = {\n        \"bin\": attr.label(),\n    },\n)\n"
  },
  {
    "path": "bzl/valdi/valdi_toolchain_type.bzl",
    "content": "VALDI_TOOLCHAIN_TYPE = \"//bzl/valdi:toolchain_type\"\n"
  },
  {
    "path": "bzl/valdi_compiler_repos_extension.bzl",
    "content": "# Module extension to expose compiler tool repos to the valdi_toolchain sub-module.\n#\n# In WORKSPACE mode, these repos are created by setup_additional_dependencies() in\n# workspace_prepare.bzl. In bzlmod mode, WORKSPACE.bzlmod is used instead, so\n# setup_additional_dependencies() is never called. This extension fills that gap by\n# creating the same repos and making them visible to @@valdi_toolchain~.\n\nSOURCES_FILEGROUP_BUILD_FILE_CONTENT = \"\"\"\nexports_files(glob([\"**\"]))\nfilegroup(\n    name = \"all_files\",\n    srcs = glob([\"**/*\"]),\n    visibility = [\"//visibility:public\"],\n)\n\"\"\"\n\ndef _compiler_local_dir_impl(ctx):\n    # Resolve the valdi workspace root via a known label.\n    # Works whether @valdi is the main workspace or an external dep.\n    valdi_root = ctx.path(Label(\"@valdi//:MODULE.bazel\")).dirname\n    target_path = valdi_root.get_child(ctx.attr.target_dir)\n\n    # Check if the directory exists (binaries may not be fetched yet)\n    check = ctx.execute([\"test\", \"-d\", str(target_path)])\n    if check.return_code != 0:\n        # Create an empty repo so the build doesn't fail during analysis.\n        # Actual builds that need the binary will fail at execution time.\n        ctx.file(\"BUILD.bazel\", SOURCES_FILEGROUP_BUILD_FILE_CONTENT)\n        return\n\n    result = ctx.execute([\"ls\", \"-1\", str(target_path)])\n    file_list = [f for f in result.stdout.strip().split(\"\\n\") if f]\n\n    has_build_file = False\n    for f in file_list:\n        if f in [\"BUILD\", \"BUILD.bazel\"]:\n            has_build_file = True\n            break\n\n    for f in file_list:\n        ctx.symlink(str(target_path) + \"/\" + f, f)\n\n    if not has_build_file:\n        ctx.file(\"BUILD.bazel\", SOURCES_FILEGROUP_BUILD_FILE_CONTENT)\n\n_compiler_local_dir = repository_rule(\n    implementation = _compiler_local_dir_impl,\n    attrs = {\"target_dir\": attr.string(mandatory = True)},\n    local = True,\n)\n\ndef _valdi_compiler_repos_impl(module_ctx):\n    _compiler_local_dir(name = \"valdi_compiler_macos\", target_dir = \"bin/compiler/macos\")\n    _compiler_local_dir(name = \"valdi_compiler_linux\", target_dir = \"bin/compiler/linux\")\n    _compiler_local_dir(name = \"valdi_pngquant_macos\", target_dir = \"bin/pngquant/macos\")\n    _compiler_local_dir(name = \"valdi_pngquant_linux\", target_dir = \"bin/pngquant/linux\")\n    _compiler_local_dir(name = \"jscore_libs\", target_dir = \"third-party/jscore/libs\")\n\nvaldi_compiler_repos = module_extension(\n    implementation = _valdi_compiler_repos_impl,\n)\n"
  },
  {
    "path": "bzl/valdi_library.bzl",
    "content": "WARNING_FLAGS = [\n    # All warnings are errors\n    \"-Werror\",\n    # Enable most warnings:\n    \"-Wall\",\n    \"-Wextra\",\n    \"-pedantic\",\n    \"-Wformat\",\n    \"-Wformat-security\",\n    \"-Wimplicit-fallthrough\",\n    \"-Wshorten-64-to-32\",\n    \"-Wstring-conversion\",\n    \"-Wunreachable-code\",\n\n    # Disable for a lot of code:\n    \"-Wno-gnu-anonymous-struct\",\n    \"-Wno-nested-anon-types\",\n    \"-Wno-unused-parameter\",\n    # Disable for SC_PICK_ASSERTION_ARGS:\n    \"-Wno-gnu-zero-variadic-macro-arguments\",\n    # Disable errors for deprecation warnings\n    \"-Wno-error=deprecated-declarations\",\n    # Disable generally\n    \"-Wno-unused-command-line-argument\",\n    # Disable for gtest MOCK_METHOD():\n    \"-Wno-extra-semi\",\n    # Disable for fmt (FMT_STRING)\n    \"-Wno-unused-local-typedef\",\n    # Disable for json.h when used with NDK r23\n    \"-Wno-deprecated-volatile\",\n    # Disable, used widely e.g. gtest\n    \"-Wno-deprecated-copy\",\n    # Can be removed after updating libc++\n    \"-Wno-deprecated-experimental-coroutine\",\n\n    # clang-tidy uses android build flags but a mismatching llvm/clang version.\n    # This option suppresses error triggered by -Wno-deprecated-experimental-coroutine which is\n    # not available for NDK 23 clang. TODO: remove when updated to NDK 25 or later versions or when libc++ is updated.\n    \"-Wno-unknown-warning-option\",\n\n    # Only disable warnings here that have wide effect; prefer to set copts at the module level\n    # when possible.\n\n    # Temporary solution for zlib build errors\n    \"-Wno-implicit-fallthrough\",\n    # Third-party headers (e.g. phmap) use [[nodiscard]] patterns that trigger\n    # this warning under newer Clang toolchains\n    \"-Wno-unused-result\",\n] + select({\n    # some protobuf headers trigger a very noisy warning from sysroot about major/minor\n    # macros :(\n    \"@platforms//os:linux\": [\"-Wno-#pragma-messages\"],\n    \"//conditions:default\": [],\n})\n\nDJINNI_DESCRIPTION_METHOD_COMPILE_FLAGS = select({\n    \"@snap_platforms//flavors:production\": [\"-DDJINNI_DISABLE_DESCRIPTION_METHODS\"],\n    \"//conditions:default\": [],\n})\n\nTRACE_COMPILE_FLAGS = select({\n    \"@snap_platforms//toggles:ztrace_bare_enabled\": [\"-finstrument-function-entry-bare\"],\n    \"//conditions:default\": [],\n}) + select({\n    \"@snap_platforms//flavors:diagnostic_production\": [\"-fsanitize-coverage=func,trace-pc-guard\"],\n    \"//conditions:default\": [],\n})\n\nGRPC_PROTO_LITE_COMPILE_FLAGS = [\n    # Most protos are lite protos and require the types in graphene to be MessageLite:\n    \"-DGRPC_USE_PROTO_LITE\",\n]\n\nPLATFORM_COMPILE_FLAGS = select({\n    \"@platforms//os:linux\": [\n        \"-DBOOST_ASIO_HAS_STD_CHRONO\",\n    ],\n    \"//conditions:default\": [],\n})\n\nCOMMON_COMPILE_FLAGS = (\n    WARNING_FLAGS +\n    DJINNI_DESCRIPTION_METHOD_COMPILE_FLAGS +\n    TRACE_COMPILE_FLAGS +\n    GRPC_PROTO_LITE_COMPILE_FLAGS +\n    PLATFORM_COMPILE_FLAGS\n)\n\nOBJC_ONLY_FLAGS = [\n    \"-fdiagnostics-color\",\n    \"-fno-aligned-allocation\",\n    \"-fvisibility=default\",\n]\n\nOBJCPP_ONLY_FLAGS = [\n    \"-ObjC++\",\n    \"-std=c++20\",\n    \"-fno-c++-static-destructors\",\n]\n\nOBJC_FLAGS = OBJC_ONLY_FLAGS + OBJCPP_ONLY_FLAGS\n"
  },
  {
    "path": "bzl/workspace_init.bzl",
    "content": "load(\"@aspect_rules_esbuild//esbuild:repositories.bzl\", \"LATEST_ESBUILD_VERSION\", \"esbuild_register_toolchains\")\nload(\"@aspect_rules_ts//ts:repositories.bzl\", \"rules_ts_dependencies\")\nload(\"@bazel_features//:deps.bzl\", \"bazel_features_deps\")\nload(\n    \"@build_bazel_apple_support//lib:repositories.bzl\",\n    \"apple_support_dependencies\",\n)\nload(\n    \"@build_bazel_rules_apple//apple:repositories.bzl\",\n    \"apple_rules_dependencies\",\n)\nload(\n    \"@build_bazel_rules_swift//swift:repositories.bzl\",\n    \"swift_rules_dependencies\",\n)\nload(\"@rules_android//:defs.bzl\", \"rules_android_workspace\")\nload(\"@rules_android_ndk//:rules.bzl\", \"android_ndk_repository\")\nload(\"@rules_cc//cc:repositories.bzl\", \"rules_cc_dependencies\")\nload(\"@rules_fuzzing//fuzzing:init.bzl\", \"rules_fuzzing_init\")\nload(\"@rules_fuzzing//fuzzing:repositories.bzl\", \"rules_fuzzing_dependencies\")\nload(\"@rules_jvm_external//:defs.bzl\", \"maven_install\")\nload(\"@rules_jvm_external//:repositories.bzl\", \"rules_jvm_external_deps\")\nload(\"@rules_kotlin//kotlin:core.bzl\", \"kt_register_toolchains\")\nload(\"@rules_nodejs//nodejs:repositories.bzl\", \"nodejs_register_toolchains\")\nload(\n    \"@rules_shell//shell:repositories.bzl\",\n    \"rules_shell_dependencies\",\n    \"rules_shell_toolchains\",\n)\nload(\n    \"@rules_xcodeproj//xcodeproj:repositories.bzl\",\n    \"xcodeproj_rules_dependencies\",\n)\nload(\"@toolchains_llvm//toolchain:deps.bzl\", \"bazel_toolchain_dependencies\")\nload(\"@toolchains_llvm//toolchain:rules.bzl\", \"llvm_toolchain\")\nload(\"@valdi//bzl/common:nodejs_info.bzl\", \"CURRENT_NODE_VERSION\", \"EXTRA_NODE_REPOSITORIES\", \"NODE_URLS\")\nload(\"@valdi//bzl/valdi:toolchains.bzl\", \"register_valdi_toolchains\")\nload(\"@valdi//bzl/valdi/npm:repositories.bzl\", \"valdi_repositories\")\n\n# WORKSPACE files are very limited in what they can do. Ideally, platform-specific command line\n# flags would be read directly from the WORKSPACE file to determine platform-specific depenencies.\n#\n# Unfortunately, command line flags are accessible in Bazel through the select() function, which\n# is only available in BUILD files and constructs during Bazel's analysis phase.\n# WORKSPACE is parsed before that, during the loading phase, so it cannot access select()\n#\n# WORKSPACES can load repositories and environment variables during the loading phase, so this helper\n# works around phase limitations by creating a wrapper \"repository\" that stores the environment\n# variable value. Values stored in this \"repository\" can then be loaded and used during any phase.\n#\n# One final quirk is that Bazel requires all repositories to have a BUILD file.\n# For this wrapper \"repository\" to be considered a valid target, a dummy BUILD file is created.\n#\ndef _platform_dependency_rule_impl(repository_ctx):\n    config = repository_ctx.os.environ.get(\"VALDI_PLATFORM_DEPENDENCIES\", \"\")\n\n    # all bazel repos require a BUILD file, make one for this \"repo\"\n    repository_ctx.file(\"BUILD\")\n\n    # this \"repo\" will have a single file with the environment flag value saved in it\n    repository_ctx.file(\"target_platform.bzl\", content = \"\"\"VALDI_PLATFORM_DEPENDENCIES = {}\"\"\".format(repr(config)))\n\nplatform_dependency_rule = repository_rule(\n    implementation = _platform_dependency_rule_impl,\n    environ = [\"VALDI_PLATFORM_DEPENDENCIES\"],\n)\n\ndef _register_android_deps():\n    rules_android_workspace()\n\n    native.register_toolchains(\n        \"@rules_android//toolchains/android:android_default_toolchain\",\n        \"@rules_android//toolchains/android_sdk:android_sdk_tools\",\n    )\n\n    android_ndk_repository(name = \"androidndk\")\n\n    native.register_toolchains(\"@androidndk//:all\")\n\n    kt_register_toolchains()\n\n    maven_install(\n        name = \"android_mvn\",\n        aar_import_bzl_label = \"@rules_android//rules:rules.bzl\",\n        artifacts = [\n            \"androidx.annotation:annotation:1.1.0\",\n            \"androidx.appcompat:appcompat:1.2.0\",\n            \"androidx.appcompat:appcompat-resources:1.2.0\",\n            \"androidx.collection:collection:1.1.0\",\n            \"androidx.constraintlayout:constraintlayout:2.1.4\",\n            \"androidx.customview:customview:1.1.0\",\n            \"androidx.dynamicanimation:dynamicanimation:1.0.0\",\n            \"androidx.fragment:fragment:1.1.0\",\n            \"androidx.interpolator:interpolator:1.0.0\",\n            \"androidx.lifecycle:lifecycle-common:2.2.0\",\n            \"androidx.lifecycle:lifecycle-process:2.2.0\",\n            \"androidx.lifecycle:lifecycle-viewmodel:2.2.0\",\n            \"androidx.recyclerview:recyclerview:1.2.1\",\n            \"androidx.test:core:1.5.0\",\n            \"androidx.test.ext:junit:1.1.3\",\n            \"androidx.test:monitor:1.5.0\",\n            \"androidx.test:runner:1.5.0\",\n            \"com.google.android.material:material:1.2.0\",\n            \"com.google.code.findbugs:jsr305:3.0.2\",\n            \"com.google.code.gson:gson:2.8.6\",\n            \"com.google.protobuf.nano:protobuf-javanano:3.1.0\",\n            \"com.jakewharton.timber:timber:4.7.1\",\n            \"com.squareup.leakcanary:leakcanary-android:2.10\",\n            \"com.squareup.okhttp3:okhttp:4.9.0\",\n            \"com.squareup.okio:okio:2.10.0\",\n            \"io.reactivex.rxjava3:rxandroid:3.0.0\",\n            \"io.reactivex.rxjava3:rxjava:3.1.0\",\n            \"io.reactivex.rxjava3:rxkotlin:3.0.0\",\n            \"javax.inject:javax.inject:1\",\n            \"junit:junit:4.13.2\",\n            \"org.junit.jupiter:junit-jupiter-api:5.9.3\",\n            \"org.junit.jupiter:junit-jupiter-engine:5.9.3\",\n            \"org.junit.jupiter:junit-jupiter-params:5.9.3\",\n            \"org.junit.platform:junit-platform-console:1.9.2\",\n            \"org.junit.platform:junit-platform-launcher:1.9.2\",\n            \"org.junit.platform:junit-platform-reporting:1.9.2\",\n            \"org.junit.vintage:junit-vintage-engine:5.9.3\",\n            \"org.robolectric:android-all:10-robolectric-5803371\",\n            \"org.robolectric:annotations:4.10.3\",\n            \"org.robolectric:robolectric:4.10.3\",\n        ],\n        repositories = [\n            \"https://repo1.maven.org/maven2\",\n            \"https://maven.google.com\",\n        ],\n        use_starlark_android_rules = True,\n        # Let's force the pinned version:\n        # https://github.com/bazelbuild/rules_jvm_external#resolving-user-specified-and-transitive-dependency-version-conflicts\n        version_conflict_policy = \"pinned\",\n    )\n\ndef _register_apple_deps():\n    xcodeproj_rules_dependencies(ignore_version_differences = True)\n    rules_shell_dependencies()\n    rules_shell_toolchains()\n    apple_rules_dependencies(ignore_version_differences = True)\n    apple_support_dependencies()\n    swift_rules_dependencies()\n\ndef _register_nodejs_deps():\n    rules_fuzzing_dependencies()\n    rules_fuzzing_init()\n    nodejs_register_toolchains(\n        name = \"nodejs\",\n        node_repositories = EXTRA_NODE_REPOSITORIES,\n        node_urls = NODE_URLS,\n        node_version = CURRENT_NODE_VERSION,\n    )\n\ndef valdi_initialize_workspace(target_platform = \"\"):\n    # platform strings expected to match BUILD_FLAGS in constants.ts\n    is_apple = (target_platform == \"ios\") or (target_platform == \"macos\")\n    if is_apple or target_platform == \"\":\n        _register_apple_deps()\n\n    rules_jvm_external_deps()\n    rules_cc_dependencies()\n    llvm_toolchain(\n        name = \"llvm_toolchain\",\n        llvm_version = \"16.0.0\",\n    )\n\n    # Required for the objc_library targets. Roughly, the dependency chain is:\n    # valdi_core > valdi_compiler_toolbox > valdi_protobuf > utils_core_cc\n    # then objc_library from djinni or jscore, etc. depending on build target\n    apple_support_dependencies()\n\n    # platform string expected to match BUILD_FLAGS in constants.ts\n    if target_platform == \"android\" or target_platform == \"\":\n        _register_android_deps()\n\n    bazel_features_deps()\n\n    # This is loadbearing for now, removing this breaks copy_to_directory\n    # TODO, figure out why\n    esbuild_register_toolchains(\n        name = \"esbuild\",\n        esbuild_version = LATEST_ESBUILD_VERSION,\n    )\n\n    register_valdi_toolchains()\n    _register_nodejs_deps()\n    bazel_toolchain_dependencies()\n\n    rules_ts_dependencies(\n        ts_version = \"5.1.3\",\n    )\n\n    valdi_repositories()\n"
  },
  {
    "path": "bzl/workspace_postinit.bzl",
    "content": "load(\"@llvm_toolchain//:toolchains.bzl\", \"llvm_register_toolchains\")\nload(\"@rules_jvm_external//:setup.bzl\", \"rules_jvm_external_setup\")\n\ndef valdi_post_initialize_workspace():\n    llvm_register_toolchains()\n    rules_jvm_external_setup()\n"
  },
  {
    "path": "bzl/workspace_preinit.bzl",
    "content": "load(\"@rules_android//:prereqs.bzl\", \"rules_android_prereqs\")\nload(\"@rules_java//java:repositories.bzl\", \"rules_java_dependencies\", \"rules_java_toolchains\")\nload(\"@rules_kotlin//kotlin:repositories.bzl\", \"kotlin_repositories\", \"kotlinc_version\")\n\ndef valdi_preinitialize_workspace():\n    rules_android_prereqs()\n\n    kotlin_repositories(compiler_release = kotlinc_version(\n        release = \"1.8.10\",\n        sha256 = \"4c3fa7bc1bb9ef3058a2319d8bcc3b7196079f88e92fdcd8d304a46f4b6b5787\",\n    ))\n\n    rules_java_dependencies()\n    rules_java_toolchains()\n"
  },
  {
    "path": "bzl/workspace_prepare.bzl",
    "content": "load(\"//bzl:additional_dependencies.bzl\", \"setup_additional_dependencies\")\nload(\"//bzl:dependencies.bzl\", \"setup_dependencies\")\n\ndef valdi_prepare_workspace(self_workspace_root = None):\n    setup_dependencies(self_workspace_root)\n    setup_additional_dependencies()\n"
  },
  {
    "path": "compiler/companion/.gitignore",
    "content": "node_modules/\n!.vscode\nout\ndist\ndist_dev\n"
  },
  {
    "path": "compiler/companion/.npmrc",
    "content": "# Better compatibility between rules_js and pnpm\n# https://docs.aspect.build/guides/rules_js_migration/#translate-your-lockfile-to-pnpm-format-optional\nhoist=false"
  },
  {
    "path": "compiler/companion/.nvmrc",
    "content": "v22\n"
  },
  {
    "path": "compiler/companion/.prettierignore",
    "content": "remotedebug-ios-webkit-adapter\ndist\nnode_modules\nout\nscripts\n.vscode\nsrc/artifact_uploader/generated\ntslibs"
  },
  {
    "path": "compiler/companion/.prettierrc.json",
    "content": "{\n  \"printWidth\": 120,\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\"\n}\n"
  },
  {
    "path": "compiler/companion/.vscode/settings.json",
    "content": "{\n  \"editor.defaultFormatter\": \"esbenp.prettier-vscode\",\n  \"editor.formatOnSave\": true,\n\n  \"typescript.tsdk\": \"node_modules/typescript/lib\",\n  \"typescript.enablePromptUseWorkspaceTsdk\": true,\n  \"typescript.preferences.jsxAttributeCompletionStyle\": \"auto\",\n  \"javascript.preferences.jsxAttributeCompletionStyle\": \"auto\",\n  \"typescript.suggest.classMemberSnippets.enabled\": true,\n  \"javascript.suggest.classMemberSnippets.enabled\": true\n}\n"
  },
  {
    "path": "compiler/companion/BUILD.bazel",
    "content": "load(\"@aspect_rules_js//js:defs.bzl\", \"js_binary\")\nload(\"@aspect_rules_js//npm:defs.bzl\", \"npm_link_package\", \"npm_package\")\nload(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_config\", \"ts_project\")\nload(\"@bazel_skylib//rules:common_settings.bzl\", \"bool_flag\")\nload(\"@valdi_npm//:defs.bzl\", \"npm_link_all_packages\")\nload(\"@valdi_npm//compiler/companion:webpack/package_json.bzl\", webpack_bin = \"bin\")\n\nnpm_link_all_packages(name = \"node_modules\")\n\nnpm_link_package(\n    name = \"remotedebug-ios-webkit-adapter-package\",\n    src = \"//compiler/companion/remotedebug-ios-webkit-adapter:package\",\n    package = \"remotedebug-ios-webkit-adapter\",\n    root_package = package_name(),\n)\n\nbool_flag(\n    name = \"dev_mode\",\n    build_setting_default = False,\n)\n\nconfig_setting(\n    name = \"dev_mode_enabled\",\n    flag_values = {\n        \":dev_mode\": \"true\",\n    },\n)\n\njs_binary(\n    name = \"bin_wrapper\",\n    copy_data_to_bin = False,\n    data = select({\n        \":dev_mode_enabled\": glob([\n            \"dist_dev/**/*.js\",\n            \"dist_dev/**/*.js.map\",\n            \"dist_dev/**/*.node\",\n        ]),\n        \"//conditions:default\": glob([\n            \"dist/**/*.js\",\n            \"dist/**/*.js.map\",\n            \"dist/**/*.node\",\n        ]),\n    }),\n    entry_point = select({\n        \":dev_mode_enabled\": \"dist_dev/bundle.js\",\n        \"//conditions:default\": \"dist/bundle.js\",\n    }),\n    env = {\n        \"NODE_ENV\": \"production\",\n        \"UV_THREADPOOL_SIZE\": \"1\",\n    },\n    node_options = [\n        # \"--inspect-brk\", # allows you to debug the companion using chrome://inspect in Chrome\n        \"--max-old-space-size=4096\",\n        \"--enable-source-maps\",\n        \"--v8-pool-size=1\",\n    ],\n    visibility = [\"//visibility:public\"],\n    # log_level = \"debug\", # increase verbosity of logs if you need to debug anything\n)\n\nts_project(\n    name = \"locales\",\n    srcs = glob([\n        \"supported-locales/src/**/*.ts\",\n    ]),\n    composite = True,\n    declaration = True,\n    out_dir = \"supported-locales/out\",\n    resolve_json_module = True,\n    root_dir = \"supported-locales/src\",\n    transpiler = \"tsc\",\n    tsconfig = \"supported-locales/tsconfig.json\",\n    deps = [\n        \":node_modules/@types/better-sqlite3\",\n        \":node_modules/@types/convert-source-map\",\n        \":node_modules/@types/istanbul-lib-coverage\",\n        \":node_modules/@types/js-yaml\",\n        \":node_modules/@types/lodash\",\n        \":node_modules/@types/node\",\n        \":node_modules/@types/source-map\",\n    ],\n)\n\nts_project(\n    name = \"lib\",\n    srcs = glob(\n        [\"src/**/*.ts\"],\n        # excludes\n        [\"src/**/*.spec.ts\"],\n    ),\n    allow_js = True,\n    assets = glob([\n        \"src/**/*.node\",\n        \"src/**/*.json\",\n    ]),\n    composite = True,\n    data = [\n        \":locales\",\n        \":node_modules/@babel/preset-typescript\",\n        \":node_modules/better-sqlite3\",\n        \":node_modules/convert-source-map\",\n        \":node_modules/express\",\n        \":node_modules/fast-glob\",\n        \":node_modules/istanbul-lib-coverage\",\n        \":node_modules/istanbul-lib-instrument\",\n        \":node_modules/js-yaml\",\n        \":node_modules/lodash\",\n        \":node_modules/source-map\",\n        \":node_modules/terser\",\n        \":node_modules/typescript\",\n        \":node_modules/xml-js\",\n    ],\n    declaration = True,\n    out_dir = \"src\",\n    root_dir = \"src\",\n    source_map = True,\n    transpiler = \"tsc\",\n    tsconfig = \":tsconfig\",\n    deps = [\n        \":locales\",\n        \":node_modules/@babel/preset-typescript\",\n        \":node_modules/@babel/types\",\n        \":node_modules/@types/better-sqlite3\",\n        \":node_modules/@types/convert-source-map\",\n        \":node_modules/@types/istanbul-lib-coverage\",\n        \":node_modules/@types/js-yaml\",\n        \":node_modules/@types/lodash\",\n        \":node_modules/@types/node\",\n        \":node_modules/@types/source-map\",\n        \":node_modules/express\",\n        \":node_modules/fast-glob\",\n        \":node_modules/terser\",\n        \":node_modules/typescript\",\n        \":node_modules/xml-js\",\n        \":remotedebug-ios-webkit-adapter-package\",\n    ],\n)\n\nts_config(\n    name = \"tsconfig\",\n    src = \"tsconfig.bazel.json\",\n    visibility = [\"//compiler/companion:__subpackages__\"],\n    deps = [\"tsconfig.base.json\"],\n)\n\njs_binary(\n    name = \"ts_bin_wrapper\",\n    copy_data_to_bin = False,\n    data = [\":lib\"],\n    entry_point = \"src/index.js\",\n    env = {\n        \"NODE_ENV\": \"production\",\n        \"UV_THREADPOOL_SIZE\": \"1\",\n    },\n    node_options = [\n        # \"--inspect-brk\", # allows you to debug the companion using chrome://inspect in Chrome\n        \"--max-old-space-size=4096\",\n        \"--enable-source-maps\",\n        \"--v8-pool-size=1\",\n    ],\n    visibility = [\"//visibility:public\"],\n    # log_level = \"debug\", # increase verbosity of logs if you need to debug anything\n)\n\nnpm_package(\n    name = \"package\",\n    srcs = [\n        \"package.json\",\n        \":lib\",\n    ],\n    package = \"valdi-compiler-js\",\n    root_paths = [package_name()],\n    visibility = [\"//visibility:public\"],\n)\n\nexports_files(\n    glob([\"src/sqlite_bindings/*.node\"]),\n    visibility = [\"//visibility:public\"],\n)\n\nwebpack_bin.webpack(\n    name = \"bundle_js\",\n    srcs = [\n        \"COMMIT_HASH\",\n        \"webpack.config.js\",\n        \":lib\",\n        \":node_modules/@types/ws\",\n        \":node_modules/better-sqlite3\",\n        \":node_modules/convert-source-map\",\n        \":node_modules/fast-glob\",\n        \":node_modules/istanbul-lib-coverage\",\n        \":node_modules/istanbul-lib-instrument\",\n        \":node_modules/js-yaml\",\n        \":node_modules/lodash\",\n        \":node_modules/node-loader\",\n        \":node_modules/source-map\",\n        \":node_modules/terser\",\n        \":node_modules/ts-loader\",\n        \":node_modules/typescript\",\n        \":node_modules/webpack\",\n        \":node_modules/ws\",\n        \":node_modules/xml-js\",\n        \":remotedebug-ios-webkit-adapter-package\",\n    ],\n    outs = [\"dist/bundle.js\"],\n    chdir = package_name(),\n)\n\ngenrule(\n    name = \"sqlite_binaries\",\n    srcs = [\n        \":src/sqlite_bindings/better_sqlite3_macos_arm64.node\",\n        \":src/sqlite_bindings/better_sqlite3_linux_x86_64.node\",\n    ],\n    outs = [\n        \"dist/better_sqlite3_macos_arm64.node\",\n        \"dist/better_sqlite3_linux_x86_64.node\",\n    ],\n    cmd = \"\"\"\n    mkdir -p $(RULEDIR)/dist && \\\n        cp $(location :src/sqlite_bindings/better_sqlite3_macos_arm64.node) $(RULEDIR)/dist/ && \\\n        cp $(location :src/sqlite_bindings/better_sqlite3_linux_x86_64.node) $(RULEDIR)/dist/\n    \"\"\",\n)\n\nfilegroup(\n    name = \"bundle\",\n    srcs = [\n        \":bundle_js\",\n        \":sqlite_binaries\",\n    ],\n)\n"
  },
  {
    "path": "compiler/companion/GIT_HASH",
    "content": "develop"
  },
  {
    "path": "compiler/companion/README.md",
    "content": "# Valdi Companion\n\nThis is the source for the Valdi Companion. It's written in TypeScript.\n\n## Development\n\nInstall the necessary dependencies\n\n```sh\nnpm install\n```\n\nRun the app without compilation\n\n```sh\nnpm run main\n```\n\nBundle into single JS file\n\n```sh\nnpm run build\n```\n\nBundle for development and use compiler with development build\n\n```sh\n# Bundle into dev package\nnpm run build-dev\n# Build valdi_core with Bazel and instruct Bazel to use our previously built dev package\nbzl build valdi_modules/src/valdi/valdi_core --//src/valdi/compiler/companion:dev_mode\n```\n\n## Testing\n\nTests are written using Jest\n\n```sh\nnpm run test\n```\n\nor to enter the watch more:\n\n```sh\nnpm run test-watch\n```\n\n## Code-style\n\nWe use [prettier](https://prettier.io/), to reformat all code:\n\n```sh\nnpm run format\n```\n"
  },
  {
    "path": "compiler/companion/jest.config.js",
    "content": "// jest.config.js\n//Sync object\nmodule.exports = {\n  //verbose: true,\n  preset: 'ts-jest',\n  testEnvironment: 'node',\n  testPathIgnorePatterns: ['remotedebug-ios-webkit-adapter'],\n  modulePathIgnorePatterns: ['remotedebug-ios-webkit-adapter'],\n};\n"
  },
  {
    "path": "compiler/companion/package.json",
    "content": "{\n  \"name\": \"valdi-compiler-js\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Contains the JS support app for the Valdi compiler\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Snapchat/Valdi.git\"\n  },\n  \"license\": \"ISC\",\n  \"bin\": \"bin/valdi-compiler-js\",\n  \"pkg\": {\n    \"assets\": [\n      \"./node_modules/@types\",\n      \"./node_modules/typescript/lib/*.d.ts\",\n      \"./tsconfig.json\"\n    ]\n  },\n  \"main\": \"src/index.js\",\n  \"scripts\": {\n    \"build\": \"webpack\",\n    \"build-dev\": \"webpack --config webpack.dev.config.js\",\n    \"format\": \"prettier . --write\",\n    \"test\": \"jest --no-watchman\",\n    \"test-watch\": \"jest --watch\",\n    \"generate-tslibs\": \"ts-node src/tslibs/GenerateTSLibs.ts\",\n    \"main\": \"ts-node src/index.ts\",\n    \"compile\": \"tsc --project remotedebug-ios-webkit-adapter/tsconfig.json && tsc\"\n  },\n  \"dependencies\": {\n    \"@babel/runtime\": \"^7.20.1\",\n    \"@babel/types\": \"^7.22.5\",\n    \"@types/convert-source-map\": \"^2.0.0\",\n    \"@types/debug\": \"^4.1.8\",\n    \"@types/express\": \"^4.17.6\",\n    \"@types/js-yaml\": \"4.0.5\",\n    \"@types/lodash\": \"^4.14.149\",\n    \"@types/node\": \"^16.18.36\",\n    \"@types/request\": \"^2.48.5\",\n    \"@types/source-map\": \"^0.1.29\",\n    \"@types/terser\": \"^3.12.0\",\n    \"@types/which\": \"^1.3.2\",\n    \"@types/ws\": \"^7.2.5\",\n    \"better-sqlite3\": \"^9.5.0\",\n    \"bufferutil\": \"^4.0.8\",\n    \"convert-source-map\": \"^2.0.0\",\n    \"debug\": \"^4.3.4\",\n    \"express\": \"^4.17.1\",\n    \"fast-glob\": \"^3.2.12\",\n    \"istanbul-lib-coverage\": \"^3.2.0\",\n    \"istanbul-lib-instrument\": \"4.0.3\",\n    \"js-yaml\": \"^4.0.5\",\n    \"lodash\": \"^4.17.15\",\n    \"optimist\": \"^0.6.1\",\n    \"prettier\": \"^2.7.1\",\n    \"request\": \"^2.88.0\",\n    \"source-map\": \"^0.5.7\",\n    \"terser\": \"4.6.10\",\n    \"typescript\": \"5.3.3\",\n    \"underscore\": \"^1.8.3\",\n    \"utf-8-validate\": \"^5.0.10\",\n    \"which\": \"^1.3.1\",\n    \"ws\": \"^7.1.2\",\n    \"xml-js\": \"^1.6.11\",\n    \"yaml\": \"^2.1.1\",\n    \"remotedebug-ios-webkit-adapter\":\"file:./remotedebug-ios-webkit-adapter\"\n  },\n  \"devDependencies\": {\n    \"@types/istanbul-lib-coverage\": \"^2.0.4\",\n    \"@babel/preset-typescript\": \"^7.21.5\",\n    \"@types/better-sqlite3\": \"^7.6.10\",\n    \"@types/jest\": \"^26.0.14\",\n    \"@types/microsoft__typescript-etw\": \"^0.1.2\",\n    \"@types/underscore\": \"^1.7.33\",\n    \"jest\": \"^29.0.0\",\n    \"node-loader\": \"^2.0.0\",\n    \"ts-jest\": \"^29.1.2\",\n    \"ts-loader\": \"^9.5.1\",\n    \"ts-node\": \"^10.9.2\",\n    \"tsconfig-paths-webpack-plugin\": \"^4.1.0\",\n    \"webpack\": \"^5.90.3\",\n    \"webpack-cli\": \"^5.1.4\"\n  }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/.editorconfig",
    "content": "# EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs\n# editorconfig.org\n\nroot = true\n\n[*]\nindent_style = space\nindent_size = 4\n\n# We recommend you to keep these unchanged\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.json]\nindent_size = 2"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/.github/workflows/auto_tags.yml",
    "content": "name: Auto tags\n\non:\n  push:\n    branches:\n      - master\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: butlerlogic/action-autotag@stable\n      with:\n        GITHUB_TOKEN: \"${{ secrets.GITHUB_TOKEN }}\"\n        tag_prefix: \"v\"\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/.github/workflows/build.yml",
    "content": "name: Build\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n      \n    - name: Use Node.js ${{ env.NODE_VERSION }}\n      uses: actions/setup-node@v1\n      with:\n        node-version: ${{ env.NODE_VERSION }}      \n\n    - name: npm install, build, and test\n      run: |\n        npm install\n        npm run build --if-present\n        npm run test --if-present\n\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/.github/workflows/publish.yml",
    "content": "name: Publish\n\non:\n  release:\n    types:\n      - published\n      # - created\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n      \n    - name: Use Node.js ${{ env.NODE_VERSION }}\n      uses: actions/setup-node@v1\n      with:\n        node-version: ${{ env.NODE_VERSION }}      \n\n    - name: npm install, build, and test\n      run: |\n        npm install\n        npm run build --if-present\n        npm run test --if-present\n    - uses: author/action-publish@stable\n      env:\n        # Typically an npm token\n        REGISTRY_TOKEN: \"${{ secrets.NPM_TOKEN }}\"\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/.gitignore",
    "content": "node_modules\nout\ntypings\nnpm-debug.log\n/.vs\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/.npmignore",
    "content": "test/\ntypings/\n.readme/\n.vscode\n# SNAP: we included remotedebug-ios-webkit-adapter by just dropping its sources in the companion\n#       source tree. We need this src to _not_ be ignored by a package manager in this case,\n#       because it needs to be available to e.g. src/valdi_modules via its node_modules dir\n# src/"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/.nvmrc",
    "content": "v22\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/BUILD.bazel",
    "content": "load(\"@aspect_rules_js//js:defs.bzl\", \"js_library\")\nload(\"@aspect_rules_js//npm:defs.bzl\", \"npm_package\")\nload(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_config\", \"ts_project\")\nload(\"@valdi_npm//:defs.bzl\", \"npm_link_all_packages\")\n\npackage(default_visibility = [\"//compiler/companion:__subpackages__\"])\n\nnpm_link_all_packages(name = \"node_modules\")\n\nts_config(\n    name = \"config\",\n    src = \"tsconfig.json\",\n    deps = [\n        \"//compiler/companion:tsconfig\",\n    ],\n)\n\nts_project(\n    name = \"lib\",\n    srcs = glob(\n        [\"src/**/*.ts\"],\n        [\"src/**/*.d.ts\"],\n    ),\n    allow_js = True,\n    composite = True,\n    data = [\n        \":node_modules/@types/express\",\n        \":node_modules/@types/ws\",\n    ],\n    declaration = True,\n    extends = \"//compiler/companion:tsconfig\",\n    out_dir = \"src\",\n    resolve_json_module = True,\n    root_dir = \"src\",\n    source_map = True,\n    transpiler = \"tsc\",\n    tsconfig = \":config\",\n    deps = [\n        \":node_modules/@types/debug\",\n        \":node_modules/@types/express\",\n        \":node_modules/@types/optimist\",\n        \":node_modules/@types/request\",\n        \":node_modules/@types/which\",\n        \":node_modules/@types/ws\",\n        \":node_modules/gulp-typescript\",\n        \":node_modules/optimist\",\n    ],\n)\n\njs_library(\n    name = \"js\",\n    srcs = [\n        \"package.json\",\n        \":lib\",\n    ],\n    data = [\n        \":node_modules/debug\",\n        \":node_modules/express\",\n        \":node_modules/optimist\",\n        \":node_modules/request\",\n        \":node_modules/which\",\n        \":node_modules/ws\",\n    ],\n)\n\nnpm_package(\n    name = \"package\",\n    srcs = [\":js\"],\n    package = \"remotedebug-ios-webkit-adapter\",\n    visibility = [\"//visibility:public\"],\n)\n\nalias(\n    name = \"pkg\",\n    actual = \":package\",\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/README.md",
    "content": "# RemoteDebug iOS WebKit Adapter\n\n![Build](https://github.com/RemoteDebug/remotedebug-ios-webkit-adapter/workflows/Build/badge.svg)\n<a href=\"https://github.com/RemoteDebug/remotedebug-ios-webkit-adapter/releases\"><img src=\"https://img.shields.io/github/release/RemoteDebug/remotedebug-ios-webkit-adapter.svg\" alt=\"Release\"></a>\n\nRemoteDebug iOS WebKit Adapter is an protocol adapter that Safari and WebViews on iOS to be debugged from tools like VS Code, Chrome DevTools, Mozilla Debugger.html and other tools compatible with the Chrome Debugging Protocol.\n\n![](.readme/overview.png)\n\nRead more in the introduction blog post on Medium: [Hello RemoteDebug iOS WebKit Adapter: iOS web debugging with Chrome DevTools, VS Code & Mozilla Debugger.html 📡📱](https://medium.com/@auchenberg/hello-remotedebug-ios-webkit-adapter-ios-web-debugging-with-chrome-devtools-vs-code-mozilla-2a8553df7465)\n\n## Getting Started\n\n### 1) Install dependencies\n\nBefore you use this adapter you need to make sure you have the [latest version of iTunes](http://www.apple.com/itunes/download/) installed, as we need a few libraries provided by iTunes to talk to the iOS devices.\n\n#### Linux\n\nFollow the instructions to install [ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy#installation)  and [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice)\n\n#### Windows\n\nInstall [ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy#installation)  and [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice). On Windows you can use [scoop](http://scoop.sh/):\n\n```\nscoop bucket add extras\nscoop install ios-webkit-debug-proxy\n```\n\n\n\n#### OSX/Mac\nMake sure you have Homebrew installed, and run the following command to install [ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy) and [libimobiledevice](https://github.com/libimobiledevice/libimobiledevice)\n\n```\nbrew update\nbrew unlink libimobiledevice ios-webkit-debug-proxy usbmuxd\nbrew uninstall --force libimobiledevice ios-webkit-debug-proxy usbmuxd\nbrew install --HEAD usbmuxd\nbrew install --HEAD libimobiledevice\nbrew install --HEAD ios-webkit-debug-proxy\n```\n\n### 2) Install latest version of the adapter\n\n```\nnpm install remotedebug-ios-webkit-adapter -g\n```\n\n### 3) Enable remote debugging in Safari\nIn order for your iOS targets to show up, you need to enable remote debugging.\n\nOpen iOS Settings => Safari preferences => enable \"Web Inspector\"\n\n### 4) Make your computer trust your iOS device.\n\nOn MacOS you can use Safari to inspect an iOS Safari tab. This will ensure the device is trusted.\n\nOn Windows starting iTunes could prompt the \"Trust this computer\" dialog.\n\n### 5) Run the adapter from your favorite command line\n\n```\nremotedebug_ios_webkit_adapter --port=9000\n```\n\nBTW: `ios-webkit-debug-proxy` will be run automatically for you, no need to start it separately.\n\n\n### 6) Open your favorite tool\n\nOpen your favorite tool such as Chrome DevTools or Visual Studio Code and configure the tool to connect to the protocol adapter.\n\n## Configuration\n\n```\nUsage: remotedebug_ios_webkit_adapter --port [num]\n\nOptions:\n  -p, --port  the adapter listerning post  [default: 9000]\n  --version   prints current version\n\n```\n\n## Usage\n### Usage with Chrome (Canary) and Chrome DevTools\n\nYou can have your iOS targets show up in Chrome's `chrome://inspect` page by leveraging the new network discoverbility feature where you simple add the IP of computer running the adapter ala `localhost:9000`.\n\n![](.readme/chrome_inspect.png)\n\n### Using with Mozilla debugger.html\n\nYou can have your iOS targets show up in [Mozila debugger.html](https://github.com/devtools-html/debugger.html), by starting `remotedebug_ios_webkit_adapter --port=9222` and selecting the Chrome tab.\n\n![](.readme/debugger_html.png)\n\n### Using with Microsoft VS Code\n\nInstall [VS Code](https:/code.visualstudio.com), and the [VS Code Chrome Debugger](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome), then create a `launch.json` configuration where `port` is set to 9000, like below:\n\n```json\n{\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"iOS Web\",\n            \"type\": \"chrome\",\n            \"request\": \"attach\",\n            \"port\": 9000,\n            \"url\": \"http://localhost:8080/*\",\n            \"webRoot\": \"${workspaceRoot}/src\"\n        }\n    ]\n}\n```\n\n## Architecture\nThe protocol adapter is implemented in TypeScript as Node-based CLI tool which starts an instance of [ios-webkit-debug-proxy](https://github.com/google/ios-webkit-debug-proxy), detects the connected iOS devices, and then starts up an instance of the correct protocol adapter depending on the iOS version.\n\n![](.readme/architecture.png)\n\n## How to contribute\n\n```\nnpm install\nnpm start\n```\n\n## Diagnostics logging\n\n```\nDEBUG=remotedebug npm start\n```\n\n### License\nMIT\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/bin/remotedebug-ios-webkit-adapter",
    "content": "#!/usr/bin/env node\n\nrequire('ts-node').register({\n    project: `${__dirname}/../tsconfig.json`,\n});\n\nrequire('../src/index.ts');\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/gulpfile.js",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\n'use strict'\n\nconst gulp = require('gulp')\nconst mocha = require('gulp-mocha')\nconst gtslint = require('gulp-tslint')\nconst ts = require('gulp-typescript')\nconst log = require('fancy-log')\nconst tslint = require('tslint');\n\nconst program = tslint.Linter.createProgram(\"./tsconfig.json\", \".\");\n\nconst shellSources = [\n  'src/**/*.ts',\n  'test/**/*.ts',\n  'test/*.ts',\n  'typings/globals/**/*.ts',\n  '!src/**/*.json'\n]\n\nconst lintSources = [\n  'src/**/*.ts',\n  'test/**/*.ts'\n]\n\nlet isWatch = false\n\ngulp.task('build', function () {\n  var tsProject = ts.createProject('tsconfig.json')\n  return gulp.src(shellSources, { base: '' })\n    .pipe(tsProject())\n    .pipe(gulp.dest('./out'))\n})\n\ngulp.task('build-tests', function () {\n  const sources = [\n    'test/**/*.ts',\n    'test/*.ts'\n  ]\n\n  var tsProject = ts.createProject('tsconfig.json')\n  return gulp.src(shellSources, { base: '' })\n    .pipe(tsProject())\n    .pipe(gulp.dest('./out/test'))\n})\n\ngulp.task('lint', function () {\n  return gulp.src(lintSources)\n    .pipe(gtslint({\n      formatter: 'verbose',\n      program: program\n    }))\n    // .pipe(gtslint.report())\n})\n\ngulp.task('test', gulp.series('build-tests', function () {\n  process.env.NODE_ENV = 'development'\n  return gulp.src('out/test/**/*.test.js', { read: false })\n    .pipe(mocha({ ui: 'tdd' }))\n    .on('error', function (e) {\n      log(e ? e.toString() : 'error in test task!')\n      this.emit('end')\n    })\n}))\n\ngulp.task('watch-test', gulp.series('build-tests', function () {\n  return gulp.watch(shellSources, gulp.task('test'))\n}))\n\ngulp.task('watch', gulp.series('build', function () {\n  const all = shellSources\n  gulp.watch(all, gulp.task('build'))\n}))\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/package.json",
    "content": "{\n  \"name\": \"remotedebug-ios-webkit-adapter\",\n  \"productName\": \"RemoteDebug iOS WebKit Adapter\",\n  \"version\": \"0.4.2\",\n  \"bin\": \"bin/remotedebug-ios-webkit-adapter\",\n  \"main\": \"out/server.js\",\n  \"types\": \"out/index.d.ts\",\n  \"scripts\": {\n    \"start\": \"node -r ts-node/register ./src/index.ts\",\n    \"build\": \"gulp build\",\n    \"watch\": \"gulp watch\",\n    \"test\": \"gulp test\",\n    \"lint\": \"gulp lint\"\n  },\n  \"dependencies\": {\n    \"@types/debug\": \"^4.1.5\",\n    \"@types/request\": \"^2.48.5\",\n    \"@types/which\": \"^1.3.2\",\n    \"@types/ws\": \"^7.2.5\",\n    \"debug\": \"^4.1.1\",\n    \"express\": \"^4.17.1\",\n    \"optimist\": \"^0.6.1\",\n    \"request\": \"^2.88.0\",\n    \"ts-node\": \"^8.10.2\",\n    \"which\": \"^1.3.1\",\n    \"ws\": \"^7.1.2\"\n  },\n  \"devDependencies\": {\n    \"@types/express\": \"^4.17.1\",\n    \"@types/mocha\": \"^5.2.7\",\n    \"@types/optimist\": \"0.0.29\",\n    \"fancy-log\": \"^1.3.3\",\n    \"gulp\": \"^4.0.2\",\n    \"gulp-mocha\": \"^6.0.0\",\n    \"gulp-sourcemaps\": \"^2.6.5\",\n    \"gulp-tslint\": \"^8.1.4\",\n    \"gulp-typescript\": \"^5.0.1\",\n    \"mocha\": \"^6.2.0\",\n    \"mock-socket\": \"^3.0.1\",\n    \"mockery\": \"^2.1.0\",\n    \"tslint\": \"^5.19.0\",\n    \"typemoq\": \"^2.1.0\",\n    \"typescript\": \"^5.3.3\"\n  },\n  \"overrides\": {\n    \"fsevents\": \"^2.3.2\",\n    \"chokidar\": \"^3.5.3\"\n  }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/adapters/adapter.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as request from 'request';\nimport * as http from 'http';\nimport * as WebSocket from 'ws';\nimport { EventEmitter } from 'events';\nimport { spawn, ChildProcess, exec } from 'child_process';\nimport { ITarget, IAdapterOptions } from './adapterInterfaces';\nimport { Logger, debug } from '../logger';\nimport { AdapterTarget } from '../protocols/target';\n\nexport class Adapter<TargetType extends AdapterTarget> extends EventEmitter {\n    protected _id: string;\n    protected _adapterType: string;\n    protected _proxyUrl: string;\n    protected _options: IAdapterOptions;\n    protected _url: string;\n    protected _proxyProc?: ChildProcess;\n    protected _targetMap: Map<string, TargetType>;\n    protected _targetIdToTargetDataMap: Map<string, ITarget>;\n\n    constructor(\n        id: string,\n        socket: string,\n        options: IAdapterOptions,\n        protected targetFactory: (targetId: string, targetData: ITarget) => TargetType,\n        protected targetsDetailsOverride?: () => ITarget[],\n    ) {\n        super();\n\n        this._id = id;\n        this._proxyUrl = socket;\n        this._targetMap = new Map<string, TargetType>();\n        this._targetIdToTargetDataMap = new Map<string, ITarget>();\n\n        // Apply default options\n        options.pollingInterval = options.pollingInterval || 3000;\n        options.baseUrl = options.baseUrl || 'http://127.0.0.1';\n        options.path = options.path || '/json';\n        options.port = options.port || 9222;\n        this._options = options;\n\n        this._url = `${this._options.baseUrl}:${this._options.port}${this._options.path}`;\n\n        const index = this._id.indexOf('/', 1);\n        if (index >= 0) {\n            this._adapterType = '_' + this._id.substr(1, index - 1);\n        } else {\n            this._adapterType = this._id.replace('/', '_');\n        }\n    }\n\n    public get id(): string {\n        debug(`adapter.id`);\n        return this._id;\n    }\n\n    public async start(): Promise<any> {\n        debug(`adapter.start`, this._options);\n\n        if (!this._options.proxyExePath) {\n            debug(`adapter.start: Skip spawnProcess, no proxyExePath available`);\n            return Promise.resolve(`skipped`);\n        }\n\n        const args = this._options.proxyExeArgsProvider ? await this._options.proxyExeArgsProvider() : [];\n        return this.spawnProcess(this._options.proxyExePath, args);\n    }\n\n    public stop(): void {\n        debug(`adapter.stop`);\n        if (this._proxyProc) {\n            // Terminate the proxy process\n            this._proxyProc.kill('SIGTERM');\n            this._proxyProc = undefined;\n        }\n        const currentlyKnownTargets = this._targetMap.values();\n        for (const knownTarget of currentlyKnownTargets) {\n            knownTarget.kill();\n        }\n    }\n\n    public closeConnectionTo(url: string): void {\n        for (const target of this._targetMap.values()) {\n            if (target.data.url === url) {\n                target.kill();\n                break;\n            }\n        }\n    }\n\n    public getTargets(metadata?: any): Promise<ITarget[]> {\n        debug(`adapter.getTargets, metadata=${metadata}`);\n        return new Promise<ITarget[]>((resolve, reject) => {\n            if (this.targetsDetailsOverride) {\n                const targets = this.targetsDetailsOverride();\n                const enhancedTargets = targets.map(t => this.setTargetInfo(t, metadata));\n                resolve(targets);\n            } else {\n                request(this._url, (error: any, response: http.IncomingMessage, body: any) => {\n                    if (error) {\n                        resolve([]);\n                        return;\n                    }\n\n                    const targets: ITarget[] = [];\n                    const rawTargets: ITarget[] = JSON.parse(body);\n                    rawTargets.forEach((t: ITarget) => {\n                        targets.push(this.setTargetInfo(t, metadata));\n                    });\n\n                    resolve(targets);\n                });\n            }\n        }).then((foundTargets: ITarget[]) => {\n            // Now get the targets for each device adapter in our list\n            const foundTargetIds = new Set(foundTargets.map(t => t.id));\n            const currentlyKnownTargets = this._targetMap.values();\n            for (const target of currentlyKnownTargets) {\n                const id = target.data.id;\n                if (!foundTargetIds.has(id)) {\n                    // Unknown target, kill it\n                    target.kill();\n                    this._targetIdToTargetDataMap.delete(id);\n                    this._targetMap.delete(id);\n                }\n            }\n            return foundTargets;\n        });\n    }\n\n    public connectTo(targetId: string, wsFrom: WebSocket): TargetType | undefined {\n        debug(`adapter.connectTo, targetId=${targetId}`);\n        if (!this._targetIdToTargetDataMap.has(targetId)) {\n            Logger.error(`No endpoint url found for id ${targetId}`);\n            return undefined;\n        } else if (this._targetMap.has(targetId)) {\n            debug(`Existing target found for id ${targetId}`);\n            const existingTarget = this._targetMap.get(targetId);\n            if (!existingTarget) {\n                return undefined\n            }\n            existingTarget.updateClient(wsFrom);\n            return existingTarget;\n        }\n\n        const targetData = this._targetIdToTargetDataMap.get(targetId)\n        if (!targetData) {\n            return undefined;\n        }\n        const target = this.targetFactory(targetId, targetData);\n        target.connectTo(targetData.webSocketDebuggerUrl, wsFrom);\n\n        // When the VS Code -> remotedebug-ios-webkit-adapter socket is closed,\n        // kill the Adapter.\n        wsFrom.on('close', code => {\n            target.callTarget('Debugger.disable', {}).then(() => {\n                target.kill();\n                this.emit('socketClosed', code);\n            });\n        });\n\n        // Store the tools websocket for this target\n        this._targetMap.set(targetId, target);\n\n        // When the remotedebug-ios-webkit-adapter -> iOS device socket is closed,\n        // kill the Adapter.\n        target.on('socketClosed', id => {\n            this.emit('socketClosed', id);\n        });\n\n        return target;\n    }\n\n    public forwardTo(targetId: string, message: string): void {\n        debug(`adapter.forwardTo, targetId=${targetId}`);\n        if (!this._targetMap.has(targetId)) {\n            Logger.error(`No target found for id ${targetId}`);\n            return;\n        }\n\n        this._targetMap.get(targetId)?.forward(message);\n    }\n\n    public forceRefresh() {\n        debug('adapter.forceRefresh');\n        if (this._proxyProc && this._options.proxyExePath && this._options.proxyExeArgsProvider) {\n            this._options.proxyExeArgsProvider().then(args => {\n                if (this._proxyProc) {\n                    const child = this._proxyProc;\n                    this._proxyProc = undefined;\n                    this.refreshProcess(child, this._options.proxyExePath || \"\", args);\n                }\n            });\n        }\n    }\n\n    protected setTargetInfo(t: ITarget, metadata?: any): ITarget {\n        debug('adapter.setTargetInfo', t, metadata);\n\n        // Ensure there is a valid id\n        const id: string = t.id || t.webSocketDebuggerUrl;\n        t.id = id;\n\n        // Set the adapter type\n        t.adapterType = this._adapterType;\n        t.type = t.type;\n        if (!t.type) {\n            if (t.title.startsWith('Valdi')) {\n                t.type = 'javascript';\n            } else {\n                t.type = 'page';\n            }\n        }\n\n        // Append the metadata\n        t.metadata = metadata;\n\n        // Store the real endpoint\n        const targetData = JSON.parse(JSON.stringify(t));\n        this._targetIdToTargetDataMap.set(t.id, targetData);\n\n        // Overwrite the real endpoint with the url of our proxy multiplexor\n        t.webSocketDebuggerUrl = `${this._proxyUrl}${this._id}/${t.id}`;\n        let wsUrl = `${this._proxyUrl.replace('ws://', '')}${this._id}/${t.id}`;\n        t.devtoolsFrontendUrl = `https://chrome-devtools-frontend.appspot.com/serve_file/@fcea73228632975e052eb90fcf6cd1752d3b42b4/inspector.html?experiments=true&remoteFrontend=screencast&ws=${wsUrl}`;\n\n        return t;\n    }\n\n    timeout(ms: number) {\n        return new Promise(resolve => setTimeout(resolve, ms));\n    }\n\n    childParameters?: { path: string; args: string[] };\n    protected async refreshProcess(child: ChildProcess, path: string, args: string[]) {\n        debug('adapter.refreshProcess');\n        child.kill('SIGTERM');\n        const childParameters = { path, args };\n        this.childParameters = childParameters;\n        await this.timeout(3000);\n        if (this.childParameters !== childParameters) {\n            // Means we scheduled a different spawn already\n            return;\n        }\n        this.spawnProcess(path, args);\n    }\n\n    protected spawnProcess(path: string, args: string[]): Promise<ChildProcess> {\n        debug(`adapter.spawnProcess, path=${path}`);\n\n        return new Promise((resolve, reject) => {\n            if (this._proxyProc) {\n                reject('adapter.spawnProcess.error, err=process already started');\n            }\n\n            const child = spawn(path, args, {\n                detached: false,\n                stdio: ['ignore'],\n            });\n            this._proxyProc = child;\n\n            child.on('error', err => {\n                debug(`adapter.spawnProcess.error, err=${err}`);\n                reject(`adapter.spawnProcess.error, err=${err}`);\n            });\n\n            child.on('close', code => {\n                debug(`adapter.spawnProcess.close, code=${code}`);\n                reject(`adapter.spawnProcess.close, code=${code}`);\n            });\n\n            child.stdout?.on('data', data => {\n                debug(`adapter.spawnProcess.stdout, data=${data.toString()}`);\n            });\n\n            child.stderr?.on('data', data => {\n                debug(`adapter.spawnProcess.stderr, data=${data.toString()}`);\n            });\n\n            setTimeout(() => {\n                resolve(child);\n            }, 200);\n        });\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/adapters/adapterCollection.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as WebSocket from 'ws';\nimport { debug } from '../logger';\nimport { AdapterTarget } from '../protocols/target';\nimport { Adapter } from './adapter';\nimport { IAdapterOptions, ITarget } from './adapterInterfaces';\n\nexport class AdapterCollection<TargetType extends AdapterTarget> extends Adapter<TargetType> {\n    protected _adapters: Map<string, Adapter<TargetType>>;\n\n    constructor(\n        id: string,\n        proxyUrl: string,\n        options: IAdapterOptions,\n        targetFactory: (targetId : any, targetData : any) => TargetType,\n    ) {\n        super(id, proxyUrl, options, targetFactory);\n\n        this._adapters = new Map<string, Adapter<TargetType>>();\n    }\n\n    public start(): Promise<any> {\n        debug(`adapterCollection.start`, this._adapters);\n\n        const startPromises = [super.start()];\n\n        this._adapters.forEach(adapter => {\n            startPromises.push(adapter.start());\n        });\n\n        return Promise.all(startPromises);\n    }\n\n    public stop(): void {\n        debug(`adapterCollection.stop`);\n        super.stop();\n        this._adapters.forEach(adapter => {\n            adapter.stop();\n        });\n    }\n\n    public forceRefresh() {\n        debug(`adapterCollection.forceRefresh`);\n        super.forceRefresh();\n        this._adapters.forEach(adapter => {\n            adapter.forceRefresh();\n        });\n    }\n\n    public getTargets(metadata?: any): Promise<ITarget[]> {\n        return new Promise((resolve, reject) => {\n            const promises: Promise<ITarget[]>[] = [];\n\n            let index = 0;\n            this._adapters.forEach(adapter => {\n                let targetMetadata = null;\n                if (metadata) {\n                    targetMetadata = metadata.constructor === Array ? metadata[index] : metadata;\n                }\n                promises.push(adapter.getTargets(targetMetadata));\n                index++;\n            });\n\n            Promise.all(promises).then((results: ITarget[][]) => {\n                let allTargets : any[] = [];\n                results.forEach(targets => {\n                    allTargets = allTargets.concat(targets);\n                });\n                resolve(allTargets);\n            });\n        });\n    }\n\n    public connectTo(url: string, wsFrom: WebSocket): TargetType | undefined {\n        debug(`adapterCollection.connectTo, url=${url}`);\n        const id = this.getWebSocketId(url);\n\n        let target: TargetType | undefined = undefined;\n        if (this._adapters.has(id.adapterId)) {\n            target = this._adapters.get(id.adapterId)?.connectTo(id.targetId, wsFrom);\n        }\n\n        return target;\n    }\n\n    public closeConnectionTo(url: string): void {\n        debug(`adapterCollection.closeConnectionTo, url=${url}`);\n        const id = this.getWebSocketId(url);\n        if (this._adapters.has(id.adapterId)) {\n            this._adapters.get(id.adapterId)?.stop();\n        }\n    }\n\n    public forwardTo(url: string, message: string): void {\n        debug(`adapterCollection.forwardTo, url=${url}`);\n        const id = this.getWebSocketId(url);\n\n        if (this._adapters.has(id.adapterId)) {\n            this._adapters.get(id.adapterId)?.forwardTo(id.targetId, message);\n        }\n    }\n\n    private getWebSocketId(url: string): { adapterId: string; targetId: string } {\n        debug(`adapterCollection.getWebSocketId, url=${url}`);\n        const index = url.indexOf('/', 1);\n        const adapterId = url.substr(0, index);\n        const targetId = url.substr(index + 1);\n\n        return { adapterId: adapterId, targetId: targetId };\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/adapters/adapterInterfaces.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\ninterface IDeviceTarget {\n    deviceId: string;\n    deviceName: string;\n    deviceOSVersion: string;\n    url: string;\n    version: string;\n}\nexport interface ITarget {\n    appId?: string;\n    description: string;\n    devtoolsFrontendUrl: string;\n    faviconUrl: string;\n    id: string;\n    title: string;\n    type: string;\n    url: string;\n    webSocketDebuggerUrl: string;\n    adapterType: string;\n    metadata?: IDeviceTarget;\n}\n\nexport interface IAdapterOptions {\n    pollingInterval?: number;\n    baseUrl?: string;\n    path?: string;\n    port?: number;\n    proxyExePath?: string;\n    proxyExeArgsProvider?: () => Promise<string[]>;\n}\n\nexport interface IIOSDeviceTarget extends IDeviceTarget {}\n\nexport interface IIOSProxySettings {\n    proxyPath: string;\n    proxyPort: number;\n    proxyExeArgsProvider: () => Promise<string[]>;\n}\n\nexport interface IAndroidDeviceTarget extends IDeviceTarget {}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/adapters/androidAdapter.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as WebSocket from 'ws';\nimport { debug } from '../logger';\nimport { AndroidTarget } from '../protocols/androidTarget';\nimport { IOSProtocol } from '../protocols/ios/ios';\nimport { IOS9Protocol } from '../protocols/ios/ios9';\nimport { Adapter } from './adapter';\nimport { AdapterCollection } from './adapterCollection';\nimport { IAndroidDeviceTarget, ITarget } from './adapterInterfaces';\n\nexport type AndroidDevice = { deviceId: string; endpoint: string };\n\nexport class AndroidAdapter extends AdapterCollection<AndroidTarget> {\n    private _protocolMap: Map<AndroidTarget, IOSProtocol>;\n    private _devices: AndroidDevice[] = [];\n\n    constructor(id: string, socket: string) {\n        super(id, socket, {}, (targetId, targetData) => new AndroidTarget(targetId, targetData));\n        this._protocolMap = new Map<AndroidTarget, IOSProtocol>();\n    }\n\n    public updateKnownDevices(devices: AndroidDevice[]) {\n        this._devices = devices;\n    }\n\n    public getTargets(): Promise<ITarget[]> {\n        debug(`androidAdapter.getTargets`);\n\n        return new Promise<IAndroidDeviceTarget[]>(resolve => {\n            const targets = this._devices.map(device => {\n                const target: IAndroidDeviceTarget = {\n                    deviceId: device.deviceId,\n                    deviceName: 'Android',\n                    deviceOSVersion: 'Android 999',\n                    url: device.endpoint,\n                    version: '9.3.0',\n                };\n                return target;\n            });\n            resolve(targets);\n        })\n            .then((devices: IAndroidDeviceTarget[]) => {\n                // Now start up all the adapters\n                devices.forEach(d => {\n                    const adapterId = `${this._id}_${d.deviceId}`;\n\n                    if (!this._adapters.has(adapterId)) {\n                        const parts = d.url.split(':');\n                        if (parts.length > 1) {\n                            // Get the port that the ios proxy exe is forwarding for this device\n                            const port = parseInt(parts[1], 10);\n\n                            // Create a new adapter for this device and add it to our list\n                            const adapter = new Adapter(\n                                adapterId,\n                                this._proxyUrl,\n                                { port: port },\n                                this.targetFactory,\n                                () => {\n                                    const targets: ITarget[] = devices.map(device => {\n                                        const fakeAndroidData = {\n                                            appId: device.deviceId,\n                                            description: '',\n                                            devtoolsFrontendUrl: '',\n                                            faviconUrl: '',\n                                            id: '1',\n                                            title: device.deviceId,\n                                            type: 'javascript',\n                                            url: device.url,\n                                            webSocketDebuggerUrl: '',\n                                            adapterType: 'android',\n                                            metadata: device,\n                                        };\n                                        const target = this.setTargetInfo(fakeAndroidData, device);\n                                        return target;\n                                    });\n                                    return targets;\n                                },\n                            );\n                            adapter.start();\n                            adapter.on('socketClosed', id => {\n                                this.emit('socketClosed', id);\n                                adapter.stop();\n                                this._adapters.delete(adapterId);\n                            });\n                            this._adapters.set(adapterId, adapter);\n                        }\n                    }\n                });\n                return Promise.resolve(devices);\n            })\n            .then((devices: IAndroidDeviceTarget[]) => {\n                // Now get the targets for each device adapter in our list\n                return super.getTargets(devices);\n            });\n    }\n\n    public connectTo(url: string, wsFrom: WebSocket): AndroidTarget | undefined {\n        const target = super.connectTo(url, wsFrom);\n\n        if (!target) {\n            return undefined;\n        }\n\n        if (!this._protocolMap.has(target)) {\n            const version = (target.data.metadata as IAndroidDeviceTarget).version;\n            const protocol = this.getProtocolFor(version, target);\n            this._protocolMap.set(target, protocol);\n        }\n        return target;\n    }\n\n    private getProtocolFor(version: string, target: AndroidTarget): IOSProtocol {\n        return new IOS9Protocol(target);\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/adapters/hermesAdapter.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as WebSocket from 'ws';\nimport { Logger, debug } from '../logger';\nimport { AndroidTarget } from '../protocols/androidTarget';\nimport { HermesProtocol } from '../protocols/hermes/hermes';\nimport { Adapter } from './adapter';\nimport { AdapterCollection } from './adapterCollection';\nimport { IAndroidDeviceTarget, ITarget } from './adapterInterfaces';\n\nexport type HermesDevice = { port: number };\n\nfunction promiseWithTimeout<T>(\n    promise: Promise<T>,\n    ms: number,\n    timeoutError = new Error('Promise timed out'),\n): Promise<T> {\n    const timeout = new Promise<never>((_, reject) => {\n        setTimeout(() => {\n            reject(timeoutError);\n        }, ms);\n    });\n    return Promise.race<T>([promise, timeout]);\n}\n\nexport class HermesAdapter extends AdapterCollection<AndroidTarget> {\n    private _deviceMap: Map<number, AndroidTarget> = new Map<number, AndroidTarget>();\n\n    constructor(id: string, socket: string) {\n        super(id, socket, {}, (targetId, targetData) => new AndroidTarget(targetId, targetData));\n        this._deviceMap = new Map<number, AndroidTarget>();\n    }\n\n    private targetClose(port: number) {\n        Logger.error(`Closing Hermes debug device on port ${port}`);\n        this._deviceMap.get(port)?.kill();\n        this._deviceMap.delete(port);\n        this._adapters.forEach((adapter, adapterId) => {\n            if (adapterId.includes(`${this.id}_${port}`)) {\n                this._adapters.delete(adapterId);\n            }\n        });\n    }\n\n    public updateKnownDevices(devices: HermesDevice[]) {\n        for (const device of devices) {\n            if (this._deviceMap.has(device.port)) {\n                continue;\n            }\n\n            const targetData: ITarget = {\n                description: '',\n                devtoolsFrontendUrl: '',\n                faviconUrl: '',\n                id: '',\n                title: '',\n                type: '',\n                url: `localhost:${device.port}`,\n                webSocketDebuggerUrl: '',\n                adapterType: '',\n            };\n            const target = this.targetFactory('', targetData);\n            target.on('socketClosed', (id) => {\n                this.targetClose(device.port);\n            });\n            target.directConnectTo(`localhost:${device.port}`);\n            this._deviceMap.set(device.port, target);\n        }\n    }\n\n    private getTargetsOnDevice(device: AndroidTarget, port: number): Promise<IAndroidDeviceTarget[]> {\n        return promiseWithTimeout(\n            new Promise<IAndroidDeviceTarget[]>((resolve, reject) => {\n                device\n                    .callTarget('Valdi.enumerateDebuggableDevices', {})\n                    .then((result) => {\n                        const targets: IAndroidDeviceTarget[] = result.map((device: any) => {\n                            const targetData: IAndroidDeviceTarget = {\n                                deviceId: String(device.id),\n                                deviceName: `${this._id}_${port}_${device.id}`,\n                                deviceOSVersion: device.protocol,\n                                url: `localhost:${port}`,\n                                version: device.version,\n                            };\n                            return targetData;\n                        });\n                        resolve(targets);\n                    })\n                    .catch((err) => {\n                        console.error('Valdi.enumerateDebuggableDevices returned error ' + err.message);\n                        reject(err);\n                    });\n            }),\n            5000,\n        )\n            .then((targets: IAndroidDeviceTarget[]) => {\n                return targets;\n            })\n            .catch((err) => {\n                this.targetClose(port);\n                return [];\n            });\n    }\n\n    public getTargets(): Promise<ITarget[]> {\n        debug(`hermesAdapter.getTargets`);\n        const targetPromises: Promise<IAndroidDeviceTarget[]>[] = [];\n        this._deviceMap.forEach((target, port) => targetPromises.push(this.getTargetsOnDevice(target, port)));\n        return Promise.all(targetPromises)\n            .then((targets) => targets.flat())\n            .then((devices: IAndroidDeviceTarget[]) => {\n                // Now start up all the adapters\n                devices.forEach((d) => {\n                    const adapterId = d.deviceName;\n                    if (!this._adapters.has(adapterId)) {\n                        const parts = d.url.split(':');\n                        if (parts.length > 1) {\n                            // Get the port that the ios proxy exe is forwarding for this device\n                            const port = parseInt(parts[1], 10);\n\n                            // Create a new adapter for this device and add it to our list\n                            const adapter = new Adapter(\n                                adapterId,\n                                this._proxyUrl,\n                                { port: port },\n                                this.targetFactory,\n                                () => {\n                                    const targets: ITarget[] = devices.map((device) => {\n                                        const fakeAndroidData = {\n                                            appId: device.deviceId,\n                                            description: '',\n                                            devtoolsFrontendUrl: '',\n                                            faviconUrl: '',\n                                            id: device.deviceId,\n                                            title: device.deviceId,\n                                            type: 'javascript',\n                                            url: device.url,\n                                            webSocketDebuggerUrl: '',\n                                            adapterType: 'android',\n                                            metadata: device,\n                                        };\n                                        const target = this.setTargetInfo(fakeAndroidData, device);\n                                        return target;\n                                    });\n                                    return targets;\n                                },\n                            );\n                            adapter.start();\n                            adapter.on('socketClosed', (id) => {\n                                this.emit('socketClosed', id);\n                                adapter.stop();\n                                this._adapters.delete(adapterId);\n                            });\n                            this._adapters.set(adapterId, adapter);\n                        }\n                    }\n                });\n                return Promise.resolve(devices);\n            })\n            .then((devices: IAndroidDeviceTarget[]) => {\n                // Now get the targets for each device adapter in our list\n                return super.getTargets(devices);\n            });\n    }\n\n    public connectTo(url: string, wsFrom: WebSocket): AndroidTarget | undefined {\n        const target = super.connectTo(url, wsFrom);\n        if (!target) {\n            return undefined;\n        }\n        const version = (target.data.metadata as IAndroidDeviceTarget).version;\n        this.setProtocolFor(version, target);\n        return target;\n    }\n\n    private setProtocolFor(version: string, target: AndroidTarget): HermesProtocol {\n        return new HermesProtocol(target, version);\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/adapters/iosAdapter.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as request from 'request';\nimport * as http from 'http';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport * as WebSocket from 'ws';\nimport * as which from 'which';\nimport { Logger, debug } from '../logger';\nimport { Adapter } from './adapter';\nimport { IOSTarget } from '../protocols/iosTarget';\nimport { AdapterCollection } from './adapterCollection';\nimport { ITarget, IIOSDeviceTarget, IIOSProxySettings } from './adapterInterfaces';\nimport { IOSProtocol } from '../protocols/ios/ios';\nimport { IOS8Protocol } from '../protocols/ios/ios8';\nimport { IOS9Protocol } from '../protocols/ios/ios9';\nimport { IOS12Protocol } from '../protocols/ios/ios12';\nimport { IOSSimulatorSocketFinder } from '../iosSimulatorSocketFinder';\n\nexport class IOSAdapter extends AdapterCollection<IOSTarget> {\n    private _proxySettings: IIOSProxySettings;\n    private _protocolMap: Map<IOSTarget, IOSProtocol>;\n\n    constructor(id: string, socket: string, proxySettings: IIOSProxySettings) {\n        super(\n            id,\n            socket,\n            {\n                port: proxySettings.proxyPort,\n                proxyExePath: proxySettings.proxyPath,\n                proxyExeArgsProvider: proxySettings.proxyExeArgsProvider,\n            },\n            (targetId, targetData) => new IOSTarget(targetId, targetData),\n        );\n\n        this._proxySettings = proxySettings;\n        this._protocolMap = new Map<IOSTarget, IOSProtocol>();\n    }\n\n    public getTargets(): Promise<ITarget[]> {\n        debug(`iOSAdapter.getTargets`);\n\n        return new Promise<IIOSDeviceTarget[]>(resolve => {\n            request(this._url, (error: any, response: http.IncomingMessage, body: any) => {\n                if (error) {\n                    resolve([]);\n                    return;\n                }\n\n                const devices: IIOSDeviceTarget[] = JSON.parse(body);\n                resolve(devices);\n            });\n        })\n            .then((devices: IIOSDeviceTarget[]) => {\n                devices.forEach(d => {\n                    if (d.deviceId.startsWith('SIMULATOR')) {\n                        d.version = '9.3.0'; // TODO: Find a way to auto detect version. Currently hardcoding it.\n                    } else if (d.deviceOSVersion) {\n                        d.version = d.deviceOSVersion;\n                    } else {\n                        debug(\n                            `error.iosAdapter.getTargets.getDeviceVersion.failed.fallback, device=${d}. Please update ios-webkit-debug-proxy to version 1.8.5`,\n                        );\n                        d.version = '9.3.0';\n                    }\n                });\n                return Promise.resolve(devices);\n            })\n            .then((devices: IIOSDeviceTarget[]) => {\n                // Now start up all the adapters\n                devices.forEach(d => {\n                    const adapterId = `${this._id}_${d.deviceId}`;\n\n                    if (!this._adapters.has(adapterId)) {\n                        const parts = d.url.split(':');\n                        if (parts.length > 1) {\n                            // Get the port that the ios proxy exe is forwarding for this device\n                            const port = parseInt(parts[1], 10);\n\n                            // Create a new adapter for this device and add it to our list\n                            const adapter = new Adapter(adapterId, this._proxyUrl, { port: port }, this.targetFactory);\n                            adapter.start();\n                            adapter.on('socketClosed', id => {\n                                this.emit('socketClosed', id);\n                                adapter.stop();\n                                this._adapters.delete(adapterId);\n                            });\n                            this._adapters.set(adapterId, adapter);\n                        }\n                    }\n                });\n                return Promise.resolve(devices);\n            })\n            .then((devices: IIOSDeviceTarget[]) => {\n                // Now get the targets for each device adapter in our list\n                return super.getTargets(devices);\n            });\n    }\n\n    public connectTo(url: string, wsFrom: WebSocket): IOSTarget | undefined {\n        const target = super.connectTo(url, wsFrom);\n\n        if (!target) {\n            return undefined;\n        }\n\n        if (!this._protocolMap.has(target)) {\n            const version = (target.data.metadata as IIOSDeviceTarget).version;\n            const protocol = this.getProtocolFor(version, target);\n            this._protocolMap.set(target, protocol);\n        }\n        return target;\n    }\n\n    public closeConnectionTo(url: string): void {\n    }\n\n    public static async getProxySettings({\n        proxyPort,\n        simulatorSocketFinder,\n    }: {\n        proxyPort: number;\n        simulatorSocketFinder: IOSSimulatorSocketFinder;\n    }): Promise<IIOSProxySettings> {\n        debug(`iOSAdapter.getProxySettings`);\n\n        // Check that the proxy exists\n        const proxyPath = await IOSAdapter.getProxyPath();\n\n        // Start with remote debugging enabled\n        // Use default parameters for the ios_webkit_debug_proxy executable\n\n        let settings : IIOSProxySettings = {\n            proxyPath: proxyPath,\n            proxyPort: proxyPort,\n            proxyExeArgsProvider: async () => {\n                const socketString = await this.getProxySimulatorSocketString(simulatorSocketFinder);\n                const proxyArgs = [\n                    '--no-frontend',\n                    '--config=null:' + proxyPort + ',:' + (proxyPort + 1) + '-' + (proxyPort + 101),\n                    '-s',\n                    socketString,\n                ];\n                return proxyArgs;\n            },\n        };\n\n        return settings;\n    }\n\n    private static async getProxySimulatorSocketString(\n        simulatorSocketFinder: IOSSimulatorSocketFinder,\n    ): Promise<string> {\n        const sockets = await simulatorSocketFinder.listKnownSockets();\n        const joined = sockets.map(s => `unix:${s}`).join(',');\n        return joined;\n    }\n\n    private static getProxyPath(): Promise<string> {\n        debug(`iOSAdapter.getProxyPath`);\n        return new Promise((resolve, reject) => {\n            if (os.platform() === 'win32') {\n                const proxy = process.env.SCOOP\n                    ? path.resolve(\n                          __dirname,\n                          process.env.SCOOP + '/apps/ios-webkit-debug-proxy/current/ios_webkit_debug_proxy.exe',\n                      )\n                    : path.resolve(\n                          __dirname,\n                          process.env.USERPROFILE +\n                              '/scoop/apps/ios-webkit-debug-proxy/current/ios_webkit_debug_proxy.exe',\n                      );\n                try {\n                    fs.statSync(proxy);\n                    resolve(proxy);\n                } catch (err) {\n                    let message = `ios_webkit_debug_proxy.exe not found. Please install 'scoop install ios-webkit-debug-proxy'`;\n                    reject(message);\n                }\n            } else if (os.platform() === 'darwin' || os.platform() === 'linux') {\n                which('ios_webkit_debug_proxy', function(err, resolvedPath) {\n                    if (err) {\n                        // TODO(3521): Update to valdi_modules\n                        reject(\n                            'ios_webkit_debug_proxy not found. Please run dev_setup.sh and check the full output of the script.',\n                        );\n                    } else {\n                        resolve(resolvedPath || \"\");\n                    }\n                });\n            }\n        });\n    }\n\n    private getProtocolFor(version: string, target: IOSTarget): IOSProtocol {\n        debug(`iOSAdapter.getProtocolFor`);\n        if (target.data.url === '' || target.data.type === 'javascript') {\n            // This is a JavaScriptCore context\n            return new IOS9Protocol(target);\n        }\n        const parts = version.split('.');\n        if (parts.length > 0) {\n            const major = parseInt(parts[0], 10);\n            if (major <= 8) {\n                return new IOS8Protocol(target);\n            }\n            const minor = parseInt(parts[1], 10);\n            if (major > 12 || (major >= 12 && minor >= 2)) {\n                return new IOS12Protocol(target);\n            }\n        }\n\n        return new IOS9Protocol(target);\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/adapters/testAdapter.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as fs from 'fs';\nimport { Adapter } from './adapter';\nimport * as path from 'path';\nimport { ITarget } from './adapterInterfaces';\nimport { IOSTarget } from '../protocols/iosTarget';\n\nexport class TestAdapter extends Adapter<IOSTarget> {\n    private _jsonPath: string;\n\n    constructor(id: string, proxyUrl: string) {\n        super(id, proxyUrl, {}, (targetId, targetData) => new IOSTarget(targetId, targetData));\n\n        this._jsonPath = path.join(__dirname, '../../src/lib/test-targets.json');\n    }\n\n    public getTargets(): Promise<ITarget[]> {\n        const count = 10;\n        return new Promise((resolve, reject) => {\n            fs.readFile(this._jsonPath, 'utf8', (error: any, data: string) => {\n                if (error) {\n                    resolve([]);\n                    return;\n                }\n\n                const targets: ITarget[] = [];\n                const rawTargets: ITarget[] = JSON.parse(data);\n                for (let i = 0; i < count; i++) {\n                    let t = (i < rawTargets.length ? rawTargets[i] : rawTargets[0]);\n                    targets.push(this.setTargetInfo(t));\n                }\n\n                resolve(targets);\n            });\n        });\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/adapters/universalAdapter.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as WebSocket from 'ws';\nimport { AdapterTarget } from '../protocols/target';\nimport { ITarget } from './adapterInterfaces';\nimport { EventEmitter } from 'ws';\nimport { Adapter } from './adapter';\n\nexport class UniversalAdapter extends EventEmitter {\n    constructor(private adapters: Adapter<any>[]) {\n        super();\n        for (const adapter of adapters) {\n            adapter.on('socketClosed', id => {\n                this.emit('socketClosed', id);\n            });\n        }\n    }\n\n    public async getTargets(): Promise<ITarget[]> {\n        const allTargets: ITarget[] = [];\n        for (const adapter of this.adapters) {\n            allTargets.push(...await adapter.getTargets());\n        }\n\n        return allTargets;\n    }\n\n    public connectTo(url: string, wsFrom: WebSocket): AdapterTarget | undefined {\n        for (const adapter of this.adapters) {\n            const target = adapter.connectTo(url, wsFrom);\n            if (target) {\n                return target;\n            }\n        }\n\n        throw new Error(`Target not found for ${url}`);\n    }\n\n    public closeConnectionTo(url: string): void {\n        for (const adapter of this.adapters) {\n            adapter.closeConnectionTo(url);\n        }\n    }\n\n    public async start() {\n        for (const adapter of this.adapters) {\n            await adapter.start();\n        }\n    }\n\n    public stop() {\n        for (const adapter of this.adapters) {\n            adapter.stop();\n        }\n    }\n\n    public forwardTo(targetId: string, message: string): void {\n        for (const adapter of this.adapters) {\n            adapter.forwardTo(targetId, message);\n        }\n    }\n\n    public forceRefresh() {\n        for (const adapter of this.adapters) {\n            adapter.forceRefresh();\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/index.ts",
    "content": "import { ProxyServer } from './server';\nimport * as optimist from 'optimist';\n// @ts-ignore - no longer included in tsconfig.json include, but we expect it to exist\nimport * as info from '../package.json';\n\nexport { ProxyServer } from './server';\n\nprocess.title = 'remotedebug-ios-webkit-adapter';\n\nlet argv = optimist\n    .usage('Usage: $0 -p [num]')\n    .alias('p', 'port').describe('p', 'the adapter listerning post').default('p', 9000)\n    .describe('version', 'prints current version').boolean('boolean')\n    .argv;\n\nif (argv.version) {\n    console.error(info.version);\n    process.exit(0);\n}\n\nif (argv.help) {\n    console.log(optimist.help());\n    process.exit(0);\n}\n\nconst server = new ProxyServer();\n\nserver.run(argv.port).then(port => {\n    console.log(`remotedebug-ios-webkit-adapter is listening on port ${port}`);\n}).catch(err => {\n    console.error('remotedebug-ios-webkit-adapter failed to run with the following error:', err);\n    process.exit();\n});\n\nprocess.on('SIGINT', function () {\n    server.stop();\n    process.exit();\n});\n\nprocess.on('SIGTERM', function () {\n    server.stop();\n    process.exit();\n});\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/iosSimulatorSocketFinder.ts",
    "content": "import { spawn, ChildProcess, exec } from 'child_process';\n\nexport class IOSSimulatorSocketFinder {\n    private timer?: NodeJS.Timeout;\n    private knownSockets: string[] | undefined;\n    private waitingQueries: ((sockets: string[]) => void)[] = [];\n    private onSocketsChanged?: (sockets: string[]) => void;\n\n    public observeSockets(callback: (sockets: string[]) => void) {\n        this.onSocketsChanged = callback;\n    }\n\n    public start() {\n        this.scheduleTick();\n    }\n\n    public stop() {\n        clearTimeout(this.timer);\n        this.timer = undefined;\n    }\n\n    public async listKnownSockets(): Promise<string[]> {\n        if (this.knownSockets) {\n            return new Promise(resolve => resolve(this.knownSockets || []));\n        } else {\n            return new Promise(resolve => {\n                this.waitingQueries.push(resolve);\n            });\n        }\n    }\n\n    private arraysEqual<T>(a: Array<T>, b: Array<T>) {\n        if (a === b) return true;\n        if (a == null || b == null) return false;\n        if (a.length !== b.length) return false;\n\n        for (let i = 0; i < a.length; ++i) {\n            if (a[i] !== b[i]) return false;\n        }\n        return true;\n    }\n\n    private updateKnownSockets(knownSockets: string[]) {\n        if (this.knownSockets) {\n            if (this.arraysEqual(this.knownSockets, knownSockets)) {\n                return;\n            }\n        }\n\n        this.knownSockets = knownSockets;\n        this.waitingQueries.forEach(resolve => {\n            resolve(knownSockets);\n        });\n        this.waitingQueries = [];\n\n        this.onSocketsChanged?.(this.knownSockets);\n    }\n\n    private scheduleTick() {\n        this.timer = setTimeout(() => {\n            this.tick();\n        }, 1000);\n    }\n\n    private tick() {\n        exec('lsof -U -F | grep com.apple.webinspectord_sim.socket | uniq', (error, stdout, stderr) => {\n            if (error) {\n                console.log(`error: ${error.message}`);\n                return;\n            }\n            if (stderr) {\n                console.error(`stderr: ${stderr}`);\n                return;\n            }\n            const sockets = stdout\n                .split('\\n')\n                .filter(line => line.length > 1)\n                .map(line => line.substr(1));\n\n            const uniquedSockets = Array.from(new Set(sockets)).sort();\n            this.updateKnownSockets(uniquedSockets);\n\n            if (this.timer) {\n                this.scheduleTick();\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/lib/mock-socket.d.ts",
    "content": "declare module 'mock-socket' {\n    export const Server : any;\n    export const WebSocket : any;\n    export const SocketIO : any;\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/lib/test-targets.json",
    "content": "[ {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/A03CDDF6-3B45-4EC1-A1EA-0B70C320DF1C\",\n   \"faviconUrl\": \"https://www.google.dk/favicon.ico\",\n   \"id\": \"A03CDDF6-3B45-4EC1-A1EA-0B70C320DF1C\",\n   \"title\": \"New Tab\",\n   \"type\": \"page\",\n   \"url\": \"chrome://newtab/\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/A03CDDF6-3B45-4EC1-A1EA-0B70C320DF1C\"\n}, {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/29734472-D8E3-4292-A20B-527AA497C522\",\n   \"faviconUrl\": \"https://kenneth.io/favicon.ico\",\n   \"id\": \"29734472-D8E3-4292-A20B-527AA497C522\",\n   \"title\": \"Kenneth Auchenberg\",\n   \"type\": \"page\",\n   \"url\": \"https://kenneth.io/\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/29734472-D8E3-4292-A20B-527AA497C522\"\n}, {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/B8EC6EE2-411D-4A1A-A9DE-7990933B9607\",\n   \"faviconUrl\": \"chrome://extension-icon/pgphcomnlaojlmmcjmiddhdapjpbgeoc/24/1\",\n   \"id\": \"B8EC6EE2-411D-4A1A-A9DE-7990933B9607\",\n   \"title\": \"Send from Gmail (by Google)\",\n   \"type\": \"background_page\",\n   \"url\": \"chrome-extension://pgphcomnlaojlmmcjmiddhdapjpbgeoc/_generated_background_page.html\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/B8EC6EE2-411D-4A1A-A9DE-7990933B9607\"\n}, {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/A36C6530-24A6-4C1D-ACA1-9458AC8A4114\",\n   \"faviconUrl\": \"chrome://extension-icon/niloccemoadcdkdjlinkgdfekeahmflj/24/1\",\n   \"id\": \"A36C6530-24A6-4C1D-ACA1-9458AC8A4114\",\n   \"title\": \"Save to Pocket\",\n   \"type\": \"background_page\",\n   \"url\": \"chrome-extension://niloccemoadcdkdjlinkgdfekeahmflj/html/background.html\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/A36C6530-24A6-4C1D-ACA1-9458AC8A4114\"\n}, {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/F608DC23-EC90-419E-B28D-E7748FBB7112\",\n   \"faviconUrl\": \"chrome://extension-icon/mpbpobfflnpcgagjijhmgnchggcjblin/24/1\",\n   \"id\": \"F608DC23-EC90-419E-B28D-E7748FBB7112\",\n   \"title\": \"SPDY indicator\",\n   \"type\": \"background_page\",\n   \"url\": \"chrome-extension://mpbpobfflnpcgagjijhmgnchggcjblin/_generated_background_page.html\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/F608DC23-EC90-419E-B28D-E7748FBB7112\"\n}, {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/DECE11A7-BE3E-4186-A09D-FD3121CE2638\",\n   \"faviconUrl\": \"chrome://extension-icon/jnkmfdileelhofjcijamephohjechhna/24/1\",\n   \"id\": \"DECE11A7-BE3E-4186-A09D-FD3121CE2638\",\n   \"title\": \"Google Analytics Debugger\",\n   \"type\": \"background_page\",\n   \"url\": \"chrome-extension://jnkmfdileelhofjcijamephohjechhna/_generated_background_page.html\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/DECE11A7-BE3E-4186-A09D-FD3121CE2638\"\n}, {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/868AB849-8007-495E-AD3F-34B412683ED4\",\n   \"faviconUrl\": \"chrome://extension-icon/gplegfbjlmmehdoakndmohflojccocli/24/1\",\n   \"id\": \"868AB849-8007-495E-AD3F-34B412683ED4\",\n   \"title\": \"PageSpeed Insights (by Google)\",\n   \"type\": \"background_page\",\n   \"url\": \"chrome-extension://gplegfbjlmmehdoakndmohflojccocli/BackgroundPage.html\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/868AB849-8007-495E-AD3F-34B412683ED4\"\n}, {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/3F0EE4CC-E378-4312-8F59-0A14DDC6702E\",\n   \"faviconUrl\": \"chrome://extension-icon/chklaanhfefbnpoihckbnefhakgolnmc/24/1\",\n   \"id\": \"3F0EE4CC-E378-4312-8F59-0A14DDC6702E\",\n   \"title\": \"JSONView\",\n   \"type\": \"background_page\",\n   \"url\": \"chrome-extension://chklaanhfefbnpoihckbnefhakgolnmc/_generated_background_page.html\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/3F0EE4CC-E378-4312-8F59-0A14DDC6702E\"\n}, {\n   \"description\": \"\",\n   \"devtoolsFrontendUrl\": \"/devtools/inspector.html?ws=localhost:9222/devtools/page/8162468F-33D2-4E39-B5D4-8B81DE74B49E\",\n   \"faviconUrl\": \"chrome://extension-icon/boadgeojelhgndaghljhdicfkmllpafd/24/1\",\n   \"id\": \"8162468F-33D2-4E39-B5D4-8B81DE74B49E\",\n   \"title\": \"Google Cast\",\n   \"type\": \"background_page\",\n   \"url\": \"chrome-extension://boadgeojelhgndaghljhdicfkmllpafd/background.html\",\n   \"webSocketDebuggerUrl\": \"ws://localhost:9222/devtools/page/8162468F-33D2-4E39-B5D4-8B81DE74B49E\"\n} ]\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/logger.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as createDebug from 'debug';\n\nclass LoggerUtil {\n\n    constructor() {\n    }\n\n    public log(msg: string): void {\n        console.log.apply(this, Array.prototype.slice.call(arguments));\n    }\n\n    public error(msg: string): void {\n        console.error(msg);\n    }\n}\n\nexport const debug = createDebug('remotedebug');\nexport const Logger = new LoggerUtil();\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/androidTarget.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as WebSocket from 'ws';\nimport { EventEmitter } from 'events';\nimport { Logger, debug } from '../logger';\nimport { ITarget } from '../adapters/adapterInterfaces';\nimport * as net from 'net';\nimport { raw } from 'express';\nimport { AdapterTarget } from './target';\n\nexport class AndroidTarget extends EventEmitter implements AdapterTarget {\n    private _data: ITarget;\n    private _url: string = \"\";\n    private _target?: net.Socket;\n    private _wsTools?: WebSocket;\n    private _isConnected: boolean = false;\n    private _messageBuffer: string[];\n    private _messageFilters: Map<string, ((msg: any) => Promise<any>)[]>;\n    private _toolRequestMap: Map<number, string>;\n    private _adapterRequestMap: Map<number, { resolve: (arg0: any) => void; reject: (arg0: any) => void }>;\n    private _requestId: number;\n    private _id: string;\n    private _targetBased: boolean;\n    private _targetId: string;\n\n    private _buffer = new Uint8Array();\n\n    constructor(targetId: string, data?: ITarget) {\n        super();\n        this._data = data || <ITarget>{};\n        this._messageBuffer = [];\n        this._messageFilters = new Map<string, ((msg: any) => Promise<any>)[]>();\n        this._toolRequestMap = new Map<number, string>();\n        this._adapterRequestMap = new Map<number, { resolve: (arg0: any) => void; reject: (arg0: any) => void }>();\n        this._requestId = 0;\n        this._targetBased = false;\n        this._targetId = \"\";\n\n        // Chrome currently uses id, iOS usies appId\n        this._id = targetId;\n    }\n\n    public get data(): ITarget {\n        return this._data;\n    }\n\n    public set targetBased(isTargetBased: boolean) {\n        this._targetBased = isTargetBased;\n    }\n\n    public set targetId(targetId: string) {\n        this._targetId = targetId;\n    }\n\n    public kill() {\n        this._target?.end();\n    }\n\n    public connectTo(url: string, wsFrom: WebSocket): void {\n        if (this._target) {\n            Logger.error(`Already connected`);\n            return;\n        }\n        this._wsTools = wsFrom;\n        this.directConnectTo(url);\n    }\n\n    public directConnectTo(url: string): void {\n        if (this._target) {\n            Logger.error(`Already connected`);\n            return;\n        }\n\n        this._url = url;\n\n        const parsedURL = new URL(`tcp://${this._data.url}`);\n        this._target = net.createConnection(Number(parsedURL.port), parsedURL.hostname);\n        this._target.on('error', err => {\n            Logger.error(err.message);\n            this.emit('socketClosed', this._id);\n        });\n\n        this._target.on('data', data => {\n            this.receivedDataFromTarget(data);\n        });\n\n        this._target.on('connect', () => {\n            debug(`Connection established to ${url}`);\n            this._isConnected = true;\n            for (let i = 0; i < this._messageBuffer.length; i++) {\n                this.onMessageFromTools(this._messageBuffer[i]);\n            }\n            this._messageBuffer = [];\n        });\n        this._target.on('end', () => {\n            debug('Socket is closed');\n            this.emit('socketClosed', this._id);\n        });\n    }\n\n    public forward(message: string): void {\n        if (!this._target) {\n            Logger.error('No websocket endpoint found');\n            return;\n        }\n\n        this.onMessageFromTools(message);\n    }\n\n    public updateClient(wsFrom: WebSocket): void {\n        if (this._target) {\n            this._target.destroy();\n        }\n        this._target = undefined;\n        this.connectTo(this._url, wsFrom);\n    }\n\n    public addMessageFilter(method: string, filter: (msg: any) => Promise<any>): void {\n        if (!this._messageFilters.has(method)) {\n            this._messageFilters.set(method, []);\n        }\n\n        this._messageFilters.get(method)?.push(filter);\n    }\n\n    public callTarget(method: string, params: any): Promise<any> {\n        return new Promise((resolve, reject) => {\n            const request = {\n                id: --this._requestId,\n                method: method,\n                params: params,\n            };\n\n            this._adapterRequestMap.set(request.id, { resolve: resolve, reject: reject });\n            this.sendToTarget(JSON.stringify(request));\n        });\n    }\n\n    public fireEventToTools(method: string, params: any): void {\n        const response = {\n            method: method,\n            params: params,\n        };\n\n        this.sendToTools(JSON.stringify(response));\n    }\n\n    public fireResultToTools(id: number, params: any): void {\n        const response = {\n            id: id,\n            result: params,\n        };\n\n        this.sendToTools(JSON.stringify(response));\n    }\n\n    public replyWithEmpty(msg: any): Promise<any> {\n        this.fireResultToTools(msg.id, {});\n        return Promise.resolve(null);\n    }\n\n    private onMessageFromTools(rawMessage: string): void {\n        if (!this._isConnected) {\n            debug('Connection not yet open, buffering message.');\n            this._messageBuffer.push(rawMessage);\n            return;\n        }\n\n        // console.log('Received Tools message:', rawMessage);\n\n        const msg = JSON.parse(rawMessage);\n        const eventName = `tools::${msg.method}`;\n\n        this._toolRequestMap.set(msg.id, msg.method);\n        this.emit(eventName, msg.params);\n\n        if (this._messageFilters.has(eventName)) {\n            let sequence = Promise.resolve(msg);\n\n            this._messageFilters.get(eventName)?.forEach(filter => {\n                sequence = sequence.then(filteredMessage => {\n                    return filter(filteredMessage);\n                });\n            });\n\n            sequence.then(filteredMessage => {\n                // Only send on the message if it wasn't completely filtered out\n                if (filteredMessage) {\n                    rawMessage = JSON.stringify(filteredMessage);\n                    this.sendToTarget(rawMessage);\n                }\n            });\n        } else {\n            // Pass it on to the target\n            this.sendToTarget(rawMessage);\n        }\n    }\n\n    private receivedDataFromTarget(data: Uint8Array) {\n        if (!this._buffer.length) {\n            this._buffer = data;\n        } else {\n            const newBuffer = new Uint8Array(data.length + this._buffer.length);\n            newBuffer.set(this._buffer, 0);\n            newBuffer.set(data, this._buffer.length);\n            this._buffer = newBuffer;\n        }\n\n        this.processBuffer();\n    }\n\n    private processBuffer() {\n        for (;;) {\n            if (this._buffer.length < 4) {\n                return;\n            }\n\n            const view = new DataView(this._buffer.buffer);\n            const size = view.getUint32(0, false);\n\n            if (size > this._buffer.length - 4) {\n                // Not enough data yet\n                return;\n            }\n\n            const jsonData = new Uint8Array(this._buffer.buffer, 4, size);\n\n            const jsonString = new TextDecoder('utf-8').decode(jsonData);\n\n            const newBuffer = new Uint8Array(this._buffer.length - jsonData.length - 4);\n            newBuffer.set(this._buffer.subarray(jsonData.length + 4), 0);\n            this._buffer = newBuffer;\n\n            this.onMessageFromTarget(jsonString);\n        }\n    }\n\n    private onMessageFromTarget(rawMessage: string): void {\n        // console.error('Received JS message:', rawMessage);\n\n        let msg = JSON.parse(rawMessage);\n\n        if (this._targetBased) {\n            if (!msg.method || !msg.method.match(/^Target/)) {\n                return;\n            }\n            if (msg.method === 'Target.dispatchMessageFromTarget') {\n                rawMessage = msg.params.message;\n                msg = JSON.parse(rawMessage);\n            }\n        }\n\n        if ('id' in msg) {\n            if (this._toolRequestMap.has(msg.id)) {\n                // Reply to tool request\n                let eventName = `target::${this._toolRequestMap.get(msg.id)}`;\n                this.emit(eventName, msg.params);\n\n                this._toolRequestMap.delete(msg.id);\n\n                if ('error' in msg && this._messageFilters.has('target::error')) {\n                    eventName = 'target::error';\n                }\n\n                if (this._messageFilters.has(eventName)) {\n                    let sequence = Promise.resolve(msg);\n\n                    this._messageFilters.get(eventName)?.forEach(filter => {\n                        sequence = sequence.then(filteredMessage => {\n                            return filter(filteredMessage);\n                        });\n                    });\n\n                    sequence.then(filteredMessage => {\n                        rawMessage = JSON.stringify(filteredMessage);\n                        this.sendToTools(rawMessage);\n                    });\n                } else {\n                    // Pass it on to the tools\n                    this.sendToTools(rawMessage);\n                }\n            } else if (this._adapterRequestMap.has(msg.id)) {\n                // Reply to adapter request\n                const resultPromise = this._adapterRequestMap.get(msg.id);\n                this._adapterRequestMap.delete(msg.id);\n\n                if ('result' in msg) {\n                    resultPromise?.resolve(msg.result);\n                } else if ('error' in msg) {\n                    resultPromise?.reject(msg.error);\n                } else {\n                    Logger.error(`Unhandled type of request message from target ${rawMessage}`);\n                }\n            } else {\n                Logger.error(`Unhandled message from target ${rawMessage}`);\n            }\n        } else {\n            const eventName = `target::${msg.method}`;\n            this.emit(eventName, msg);\n\n            if (this._messageFilters.has(eventName)) {\n                let sequence = Promise.resolve(msg);\n\n                this._messageFilters.get(eventName)?.forEach(filter => {\n                    sequence = sequence.then(filteredMessage => {\n                        return filter(filteredMessage);\n                    });\n                });\n\n                sequence.then(filteredMessage => {\n                    rawMessage = JSON.stringify(filteredMessage);\n                    this.sendToTools(rawMessage);\n                });\n            } else {\n                // Pass it on to the tools\n                this.sendToTools(rawMessage);\n            }\n        }\n    }\n\n    private sendToTools(rawMessage: string): void {\n        debug(`sendToTools.${rawMessage}`);\n        // Make sure the tools socket can receive messages\n        // console.log('Sending message to tool:', rawMessage);\n        if (this._wsTools && this.isSocketConnected(this._wsTools)) {\n            this._wsTools.send(rawMessage);\n        }\n    }\n\n    private sendToTarget(rawMessage: string): void {\n        debug(`sendToTarget.${rawMessage}`);\n        if (this._targetBased) {\n            const message = JSON.parse(rawMessage);\n            if (!message.method.match(/^Target/)) {\n                const newMessage = {\n                    id: message.id,\n                    method: 'Target.sendMessageToTarget',\n                    params: {\n                        id: message.id,\n                        message: JSON.stringify(message),\n                        targetId: this._targetId,\n                    },\n                };\n                rawMessage = JSON.stringify(newMessage);\n                debug(`sendToTarget.targeted.${rawMessage}`);\n            }\n        }\n\n        const data = new TextEncoder().encode(rawMessage);\n\n        const packet = new ArrayBuffer(data.length + 4);\n        const view = new DataView(packet);\n        view.setUint32(0, data.length, false);\n\n        let i = 4;\n        for (const b of data) {\n            view.setUint8(i, b);\n            i++;\n        }\n\n        // Make sure the target socket can receive messages\n        if (this._target) {\n            this._target.write(new Uint8Array(packet));\n        } else {\n            // this._target.send(rawMessage);\n            // The socket has closed, we should send this message up to the parent\n            this._target = undefined;\n            this.emit('socketClosed', this._id);\n        }\n    }\n\n    private isSocketConnected(ws: WebSocket): boolean {\n        return ws && ws.readyState === WebSocket.OPEN;\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/hermes/hermes.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport { Logger } from '../../logger';\nimport { ProtocolAdapter } from '../protocol';\nimport { AdapterTarget } from '../target';\nimport { IAndroidDeviceTarget } from '../../adapters/adapterInterfaces';\n\nexport class HermesProtocol extends ProtocolAdapter {\n    protected shouldDeferScriptParsed: boolean = true;\n    protected deferredScriptParsedCalls: (() => void)[] = [];\n    protected runtimeEnabled: boolean = false;\n\n    constructor(target: AdapterTarget, version: String) {\n        super(target);\n\n        const id = (target.data.metadata as IAndroidDeviceTarget).deviceId;\n        target\n            .callTarget('Valdi.connectDebuggerTo', { id: id })\n            .then((result) => {})\n            .catch((err) => {\n                console.error('[HermesProtocol] Unable to connect debugger to id ' + id, err.message);\n                target.kill();\n            });\n\n        this._target.addMessageFilter('tools::Runtime.enable', (msg) => this.onRuntimeEnable(msg));\n        this._target.addMessageFilter('target::Runtime.enable', (msg) => this.onDidRuntimeEnable(msg));\n\n        this._target.addMessageFilter('target::Runtime.runIfWaitingForDebugger', (msg) =>\n            this.onTargetRunIfWaitingForDebugger(msg),\n        );\n        this._target.addMessageFilter('tools::Runtime.callFunctionOn', (msg) => this.callFunctionOn(msg));\n        this._target.addMessageFilter('target::Debugger.scriptParsed', (msg) => this.onScriptParsed(msg));\n    }\n    private callFunctionOn(msg: any): Promise<any> {\n        const result = {\n            result: {\n                type: 'undefined',\n            },\n        };\n        this._target.fireResultToTools(msg.id, result);\n        return Promise.resolve();\n    }\n\n    private onRuntimeEnable(msg: any): Promise<any> {\n        return Promise.resolve(msg);\n    }\n\n    private onDidRuntimeEnable(msg: any): Promise<any> {\n        this.runtimeEnabled = true;\n        return Promise.resolve(msg);\n    }\n\n    private onTargetRunIfWaitingForDebugger(msg: any): Promise<any> {\n        if (this.runtimeEnabled) {\n            this.shouldDeferScriptParsed = false;\n            this.deferredScriptParsedCalls.forEach((callback) => {\n                callback();\n            });\n            this.deferredScriptParsedCalls = [];\n        }\n        return Promise.resolve(msg);\n    }\n\n    private onScriptParsed(msg: any): Promise<any> {\n        return new Promise((resolve) => {\n            if (this.shouldDeferScriptParsed) {\n                // We're sending the response after a delay, otherwise this seems to be sent\n                // too early for VS Code to pick up the parsed sources\n                this.deferredScriptParsedCalls.push(() => {\n                    resolve(msg);\n                });\n                return;\n            }\n            resolve(msg);\n        });\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/ios/ios.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport { Logger } from '../../logger';\nimport { ProtocolAdapter } from '../protocol';\nimport { ScreencastSession } from './screencast';\nimport { AdapterTarget } from '../target';\n\ndeclare var document: any;\ndeclare var MouseEvent: any;\n\ninterface IRange {\n    startLine: number;\n    startColumn: number;\n    endLine: number;\n    endColumn: number;\n}\n\ninterface IDisabledStyle {\n    content: string;\n    range: IRange;\n}\n\nexport abstract class IOSProtocol extends ProtocolAdapter {\n    public static BEGIN_COMMENT: string = '/* ';\n    public static END_COMMENT: string = ' */';\n    public static SEPARATOR: string = ': ';\n\n    protected _styleMap: Map<string, any>;\n    protected _isEvaluating: boolean = false;\n    protected _lastScriptEval: string = \"\";\n    protected _lastNodeId: number = 0;\n    protected _lastPageExecutionContextId: number = 0;\n    protected _screencastSession?: ScreencastSession;\n\n    protected runtimeEnabled: boolean = false;\n    protected shouldDeferScriptParsed: boolean = true;\n    protected deferredScriptParsedCalls: (() => void)[] = [];\n\n    constructor(target: AdapterTarget) {\n        super(target);\n\n        this._styleMap = new Map<string, any>();\n\n        this._target.on('tools::DOM.getDocument', () => this.onDomGetDocument());\n\n        this._target.addMessageFilter('tools::CSS.setStyleTexts', msg => this.onSetStyleTexts(msg));\n        this._target.addMessageFilter('tools::CSS.getMatchedStylesForNode', msg => this.onGetMatchedStylesForNode(msg));\n        this._target.addMessageFilter('tools::CSS.getBackgroundColors', msg => this.onGetBackgroundColors(msg));\n        this._target.addMessageFilter('tools::CSS.addRule', msg => this.onAddRule(msg));\n        this._target.addMessageFilter('tools::CSS.getPlatformFontsForNode', msg => this.onGetPlatformFontsForNode(msg));\n        this._target.addMessageFilter('target::CSS.getMatchedStylesForNode', msg =>\n            this.onGetMatchedStylesForNodeResult(msg),\n        );\n\n        this._target.addMessageFilter('tools::Page.startScreencast', msg => this.onStartScreencast(msg));\n        this._target.addMessageFilter('tools::Page.stopScreencast', msg => this.onStopScreencast(msg));\n        this._target.addMessageFilter('tools::Page.screencastFrameAck', msg => this.onScreencastFrameAck(msg));\n        this._target.addMessageFilter('tools::Page.getNavigationHistory', msg => this.onGetNavigationHistory(msg));\n        this._target.addMessageFilter('tools::Page.setOverlayMessage', msg => {\n            msg.method = 'Debugger.setOverlayMessage';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::Page.configureOverlay', msg => {\n            msg.method = 'Debugger.setOverlayMessage';\n            return Promise.resolve(msg);\n        });\n\n        this._target.addMessageFilter('tools::DOM.enable', msg => this.onDomEnable(msg));\n        this._target.addMessageFilter('tools::DOM.setInspectMode', msg => this.onSetInspectMode(msg));\n        this._target.addMessageFilter('tools::DOM.setInspectedNode', msg => {\n            msg.method = 'Console.addInspectedNode';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::DOM.pushNodesByBackendIdsToFrontend', msg =>\n            this.onPushNodesByBackendIdsToFrontend(msg),\n        );\n        this._target.addMessageFilter('tools::DOM.getBoxModel', msg => this.onGetBoxModel(msg));\n        this._target.addMessageFilter('tools::DOM.getNodeForLocation', msg => this.onGetNodeForLocation(msg));\n\n        this._target.addMessageFilter('tools::DOMDebugger.getEventListeners', msg =>\n            this.DOMDebuggerOnGetEventListeners(msg),\n        );\n\n        this._target.addMessageFilter('tools::Debugger.canSetScriptSource', msg => this.onCanSetScriptSource(msg));\n        this._target.addMessageFilter('tools::Debugger.setBlackboxPatterns', msg => this.onSetBlackboxPatterns(msg));\n        this._target.addMessageFilter('tools::Debugger.setAsyncCallStackDepth', msg =>\n            this.onSetAsyncCallStackDepth(msg),\n        );\n        this._target.addMessageFilter('tools::Debugger.enable', msg => this.onDebuggerEnable(msg));\n        this._target.addMessageFilter('target::Debugger.enable', msg => this.onDidDebuggerEnable(msg));\n        this._target.addMessageFilter('target::Debugger.scriptParsed', msg => this.onScriptParsed(msg));\n\n        this._target.addMessageFilter('tools::Emulation.canEmulate', msg => this.onCanEmulate(msg));\n        this._target.addMessageFilter('tools::Emulation.setTouchEmulationEnabled', msg => {\n            msg.method = 'Page.setTouchEmulationEnabled';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::Emulation.setScriptExecutionDisabled', msg => {\n            msg.method = 'Page.setScriptExecutionDisabled';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::Emulation.setEmulatedMedia', msg => {\n            msg.method = 'Page.setEmulatedMedia';\n            return Promise.resolve(msg);\n        });\n\n        this._target.addMessageFilter('tools::Rendering.setShowPaintRects', msg => {\n            msg.method = 'Page.setShowPaintRects';\n            return Promise.resolve(msg);\n        });\n\n        this._target.addMessageFilter('tools::Input.emulateTouchFromMouseEvent', msg =>\n            this.onEmulateTouchFromMouseEvent(msg),\n        );\n\n        this._target.addMessageFilter('tools::Log.clear', msg => {\n            msg.method = 'Console.clearMessages';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::Log.disable', msg => {\n            msg.method = 'Console.disable';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::Log.enable', msg => {\n            msg.method = 'Console.enable';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('target::Console.messageAdded', msg => this.onConsoleMessageAdded(msg));\n\n        this._target.addMessageFilter('tools::Network.getCookies', msg => {\n            msg.method = 'Page.getCookies';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::Network.deleteCookie', msg => {\n            msg.method = 'Page.deleteCookie';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::Network.setMonitoringXHREnabled', msg => {\n            msg.method = 'Console.setMonitoringXHREnabled';\n            return Promise.resolve(msg);\n        });\n        this._target.addMessageFilter('tools::Network.canEmulateNetworkConditions', msg =>\n            this.onCanEmulateNetworkConditions(msg),\n        );\n\n        this._target.addMessageFilter('tools::Runtime.compileScript', msg => this.onRuntimeOnCompileScript(msg));\n        this._target.addMessageFilter('target::Runtime.executionContextCreated', msg =>\n            this.onExecutionContextCreated(msg),\n        );\n        this._target.addMessageFilter('tools::Runtime.enable', msg => this.onRuntimeEnable(msg));\n        this._target.addMessageFilter('target::Runtime.enable', msg => this.onDidRuntimeEnable(msg));\n\n        this._target.addMessageFilter('target::Runtime.runIfWaitingForDebugger', msg =>\n            this.onTargetRunIfWaitingForDebugger(msg),\n        );\n\n        this._target.addMessageFilter('target::Runtime.evaluate', msg => this.onEvaluate(msg));\n        this._target.addMessageFilter('target::Runtime.getProperties', msg => this.onRuntimeGetProperties(msg));\n\n        this._target.addMessageFilter('target::Inspector.inspect', msg => this.onInspect(msg));\n    }\n\n    private onDomGetDocument(): void {\n        // Rundown the stylesheets when the page navigates\n        this.enumerateStyleSheets();\n    }\n\n    private onSetStyleTexts(msg: any): Promise<any> {\n        const resultId = msg.id;\n        const promises: Promise<any>[] = [];\n\n        // Convert all the requests into individual calls to setStyleText\n        for (let i = 0; i < msg.params.edits.length; i++) {\n            const edit = msg.params.edits[i];\n            const paramsGetStyleSheet = {\n                styleSheetId: edit.styleSheetId,\n            };\n\n            // iOS uses ordinals to map CSSRules to a location in the document. Chromium uses ranges.\n            // Fortunately, if we get the style sheet, we can with minimal effort find the existing range that matches the Chromium edit range and return that ordinal in the rules listen\n            // We make the assumption that a rule location can only match once and return the first instance.\n            const setStyleText = this._target.callTarget('CSS.getStyleSheet', paramsGetStyleSheet).then(result => {\n                if (!result.styleSheet || !result.styleSheet.rules) {\n                    Logger.error('iOS returned a value we were not expecting for getStyleSheet');\n                    return Promise.resolve(null);\n                }\n\n                const length = result.styleSheet.rules.length;\n                for (let ordinal = 0; ordinal < length; ordinal++) {\n                    let rule = result.styleSheet.rules[ordinal];\n                    if (this.compareRanges(rule.style.range, edit.range)) {\n                        const params = {\n                            styleId: {\n                                styleSheetId: edit.styleSheetId,\n                                ordinal: ordinal,\n                            },\n                            text: edit.text,\n                        };\n\n                        return this._target.callTarget('CSS.setStyleText', params).then(setStyleResult => {\n                            this.mapStyle(setStyleResult.style, '');\n                            return setStyleResult.style;\n                        });\n                    }\n                }\n                return Promise.resolve(null);\n            });\n\n            promises.push(setStyleText);\n        }\n\n        // Combine all the setStyleText calls into a single result\n        Promise.all(promises).then(allResults => {\n            const result = {\n                styles: allResults,\n            };\n\n            this._target.fireResultToTools(resultId, result);\n        });\n\n        // Resolve the original promise with null to prevent 'setStyleTexts' from going to the target\n        return Promise.resolve(null);\n    }\n\n    // Called on a Chrome range and an iOS range\n    private compareRanges(rangeLeft: any, rangeRight: any) {\n        return (\n            rangeLeft.startLine === rangeRight.startLine &&\n            rangeLeft.endLine === rangeRight.endLine &&\n            rangeLeft.startColumn === rangeRight.startColumn &&\n            rangeLeft.endColumn === rangeRight.endColumn\n        );\n    }\n\n    private onGetMatchedStylesForNode(msg: any): Promise<any> {\n        // Store the last selected nodeId so we can add new rules to this node\n        this._lastNodeId = msg.params.nodeId;\n        return Promise.resolve(msg);\n    }\n\n    private onCanEmulate(msg: any): Promise<any> {\n        const result = {\n            result: true,\n        };\n        this._target.fireResultToTools(msg.id, result);\n        return Promise.resolve(null);\n    }\n\n    private onGetPlatformFontsForNode(msg: any): Promise<any> {\n        const result = {\n            fonts: [],\n        };\n\n        this._target.fireResultToTools(msg.id, result);\n        return Promise.resolve(null);\n    }\n\n    private onGetBackgroundColors(msg: any): Promise<any> {\n        const result = {\n            backgroundColors: [],\n        };\n\n        this._target.fireResultToTools(msg.id, result);\n        return Promise.resolve(null);\n    }\n\n    private onAddRule(msg: any): Promise<any> {\n        // Convert the chrome new rule into an ios rule on the current node\n        const selector = msg.params.ruleText.trim().replace('{}', '');\n        const params = {\n            contextNodeId: this._lastNodeId,\n            selector: selector,\n        };\n\n        this._target.callTarget('CSS.addRule', params).then(result => {\n            this.mapRule(result.rule);\n            this._target.fireResultToTools(msg.id, result);\n        });\n\n        return Promise.resolve(null);\n    }\n\n    private onCanSetScriptSource(msg: any): Promise<any> {\n        const result = {\n            result: false,\n        };\n\n        this._target.fireResultToTools(msg.id, result);\n        return Promise.resolve(null);\n    }\n\n    private onSetBlackboxPatterns(msg: any): Promise<any> {\n        const result = {};\n\n        this._target.fireResultToTools(msg.id, result);\n        return Promise.resolve(null);\n    }\n\n    private onSetAsyncCallStackDepth(msg: any): Promise<any> {\n        const result = {\n            result: true,\n        };\n\n        this._target.fireResultToTools(msg.id, result);\n        return Promise.resolve(null);\n    }\n\n    private onDebuggerEnable(msg: any): Promise<any> {\n        this._target.callTarget('Debugger.setBreakpointsActive', { active: true });\n        return Promise.resolve(msg);\n    }\n\n    private onDidDebuggerEnable(msg: any): Promise<any> {\n        return Promise.resolve(msg);\n    }\n\n    private onGetMatchedStylesForNodeResult(msg: any): Promise<any> {\n        const result = msg.result;\n\n        if (result) {\n            // Convert all the rules into the chrome format\n            for (let i in result.matchedCSSRules) {\n                if (result.matchedCSSRules[i].rule) {\n                    this.mapRule(result.matchedCSSRules[i].rule);\n                }\n            }\n\n            for (let i in result.inherited) {\n                if (result.inherited[i].matchedCSSRules) {\n                    for (let j in result.inherited[i].matchedCSSRules) {\n                        if (result.inherited[i].matchedCSSRules[j].rule) {\n                            this.mapRule(result.inherited[i].matchedCSSRules[j].rule);\n                        }\n                    }\n                }\n            }\n        }\n\n        return Promise.resolve(msg);\n    }\n\n    private onExecutionContextCreated(msg: any): Promise<any> {\n        if (msg.params && msg.params.context) {\n            if (!msg.params.context.origin) {\n                msg.params.context.origin = msg.params.context.name;\n            }\n\n            if (msg.params.context.isPageContext) {\n                this._lastPageExecutionContextId = msg.params.context.id;\n            }\n\n            if (msg.params.context.frameId) {\n                msg.params.context.auxData = {\n                    frameId: msg.params.context.frameId,\n                    isDefault: true,\n                };\n                delete msg.params.context.frameId;\n            }\n        }\n\n        return Promise.resolve(msg);\n    }\n\n    private onEvaluate(msg: any): Promise<any> {\n        if (msg.result && msg.result.wasThrown) {\n            msg.result.result.subtype = 'error';\n            msg.result.exceptionDetails = {\n                text: msg.result.result.description,\n                url: '',\n                scriptId: this._lastScriptEval,\n                line: 1,\n                column: 0,\n                stack: {\n                    callFrames: [\n                        {\n                            functionName: '',\n                            scriptId: this._lastScriptEval,\n                            url: '',\n                            lineNumber: 1,\n                            columnNumber: 1,\n                        },\n                    ],\n                },\n            };\n        } else if (msg.result && msg.result.result && msg.result.result.preview) {\n            msg.result.result.preview.description = msg.result.result.description;\n            msg.result.result.preview.type = 'object';\n        }\n\n        return Promise.resolve(msg);\n    }\n\n    private onRuntimeOnCompileScript(msg: any): Promise<any> {\n        const params = {\n            expression: msg.params.expression,\n            contextId: msg.params.executionContextId,\n        };\n\n        this._target.callTarget('Runtime.evaluate', params).then(obj => {\n            const results = {\n                scriptId: null,\n                exceptionDetails: null,\n            };\n            this._target.fireResultToTools(msg.id, results);\n        });\n\n        return Promise.resolve(null);\n    }\n\n    private onRuntimeGetProperties(msg: any): Promise<any> {\n        const newPropertyDescriptors = [];\n\n        if (msg.result.result) {\n            for (let i = 0; i < msg.result.result.length; i++) {\n                if (msg.result.result[i].isOwn || msg.result.result[i].nativeGetter) {\n                    msg.result.result[i].isOwn = true;\n                    newPropertyDescriptors.push(msg.result.result[i]);\n                }\n            }\n        }\n\n        msg.result.result = null;\n        msg.result.result = newPropertyDescriptors;\n\n        return Promise.resolve(msg);\n    }\n\n    private onRuntimeEnable(msg: any): Promise<any> {\n        return Promise.resolve(msg);\n    }\n\n    private onDidRuntimeEnable(msg: any): Promise<any> {\n        this.runtimeEnabled = true;\n        return Promise.resolve(msg);\n    }\n\n    private onTargetRunIfWaitingForDebugger(msg: any): Promise<any> {\n        if (this.runtimeEnabled) {\n            this.shouldDeferScriptParsed = false;\n            this.deferredScriptParsedCalls.forEach(callback => {\n                callback();\n            });\n        }\n        return Promise.resolve(msg);\n    }\n\n    private onScriptParsed(msg: any): Promise<any> {\n        this._lastScriptEval = msg.params.scriptId;\n        return new Promise(resolve => {\n            if (this.shouldDeferScriptParsed) {\n                // We're sending the response after a delay, otherwise this seems to be sent\n                // too early for VS Code to pick up the parsed sources\n                this.deferredScriptParsedCalls.push(() => {\n                    resolve(msg);\n                });\n                return;\n            }\n\n            resolve(msg);\n        });\n    }\n\n    private onDomEnable(msg: any): Promise<any> {\n        this._target.fireResultToTools(msg.id, {});\n        return Promise.resolve(null);\n    }\n\n    private onSetInspectMode(msg: any): Promise<any> {\n        msg.method = 'DOM.setInspectModeEnabled';\n        msg.params.enabled = msg.params.mode === 'searchForNode';\n        delete msg.params.mode;\n        return Promise.resolve(msg);\n    }\n\n    private onInspect(msg: any): Promise<any> {\n        msg.method = 'DOM.inspectNodeRequested';\n        msg.params.backendNodeId = msg.params.object.objectId;\n        delete msg.params.object;\n        delete msg.params.hints;\n        return Promise.resolve(msg);\n    }\n\n    private DOMDebuggerOnGetEventListeners(msg: any): Promise<any> {\n        const requestNodeParams = {\n            objectId: msg.params.objectId,\n        };\n\n        this._target\n            .callTarget('DOM.requestNode', requestNodeParams)\n            .then(result => {\n                const getEventListenersForNodeParams = {\n                    nodeId: result.nodeId,\n                    objectGroup: 'event-listeners-panel',\n                };\n\n                return this._target.callTarget('DOM.getEventListenersForNode', getEventListenersForNodeParams);\n            })\n            .then(result => {\n                const mappedListeners = result.listeners.map((listener: any) => {\n                    return {\n                        type: listener.type,\n                        useCapture: listener.useCapture,\n                        passive: false, // iOS doesn't support this property, http://compatibility.remotedebug.org/DOM/Safari%20iOS%209.3/types/EventListener,\n                        location: listener.location,\n                        hander: listener.hander,\n                    };\n                });\n\n                const mappedResult = {\n                    listeners: mappedListeners,\n                };\n\n                this._target.fireResultToTools(msg.id, mappedResult);\n            });\n\n        return Promise.resolve(null);\n    }\n\n    private onPushNodesByBackendIdsToFrontend(msg: any): Promise<any> {\n        const resultId = msg.id;\n        const promises: Promise<any>[] = [];\n\n        // Convert all the requests into individual calls to pushNodeByBackendIdToFrontend\n        for (let i = 0; i < msg.params.backendNodeIds.length; i++) {\n            let params = {\n                backendNodeId: msg.params.backendNodeIds[i],\n            };\n\n            const pushNode = this._target.callTarget('DOM.pushNodeByBackendIdToFrontend', params).then(result => {\n                return result.nodeId;\n            });\n\n            promises.push(pushNode);\n        }\n\n        // Combine all the pushNodeByBackendIdToFrontend calls into a single result\n        Promise.all(promises).then(allResults => {\n            const result = {\n                nodeIds: allResults,\n            };\n\n            this._target.fireResultToTools(resultId, result);\n        });\n\n        // Resolve the original promise with null to prevent 'setStyleTexts' from going to the target\n        return Promise.resolve(null);\n    }\n\n    private onGetBoxModel(msg: any): Promise<any> {\n        const params = {\n            highlightConfig: {\n                showInfo: true,\n                showRulers: false,\n                showExtensionLines: false,\n                contentColor: { r: 111, g: 168, b: 220, a: 0.66 },\n                paddingColor: { r: 147, g: 196, b: 125, a: 0.55 },\n                borderColor: { r: 255, g: 229, b: 153, a: 0.66 },\n                marginColor: { r: 246, g: 178, b: 107, a: 0.66 },\n                eventTargetColor: { r: 255, g: 196, b: 196, a: 0.66 },\n                shapeColor: { r: 96, g: 82, b: 177, a: 0.8 },\n                shapeMarginColor: { r: 96, g: 82, b: 127, a: 0.6 },\n                displayAsMaterial: true,\n            },\n            nodeId: msg.params.nodeId,\n        };\n\n        this._target.callTarget('DOM.highlightNode', params);\n\n        return Promise.resolve(null);\n    }\n\n    private onGetNodeForLocation(msg: any): Promise<any> {\n        this._target\n            .callTarget('Runtime.evaluate', {\n                expression: 'document.elementFromPoint(' + msg.params.x + ',' + msg.params.y + ')',\n            })\n            .then(obj => {\n                this._target.callTarget('DOM.requestNode', { objectId: obj.result.objectId }).then(result => {\n                    this._target.fireResultToTools(msg.id, { nodeId: result.nodeId });\n                });\n            });\n\n        return Promise.resolve(null);\n    }\n\n    private onStartScreencast(msg: any): Promise<any> {\n        const format: string = msg.params.format;\n        const quality: number = msg.params.quality;\n        const maxWidth: number = msg.params.maxWidth;\n        const maxHeight: number = msg.params.maxHeight;\n\n        if (this._screencastSession) {\n            // Session has already started so dispose of the current one\n            this._screencastSession.dispose();\n        }\n\n        this._screencastSession = new ScreencastSession(this._target, format, quality, maxWidth, maxHeight);\n        this._screencastSession.start();\n\n        this._target.fireResultToTools(msg.id, {});\n        return Promise.resolve(null);\n    }\n\n    private onStopScreencast(msg: any): Promise<any> {\n        if (this._screencastSession) {\n            this._screencastSession.stop();\n            this._screencastSession = undefined;\n        }\n\n        this._target.fireResultToTools(msg.id, {});\n        return Promise.resolve(null);\n    }\n\n    private onScreencastFrameAck(msg: any): Promise<any> {\n        if (this._screencastSession) {\n            const frameNumber: number = msg.params.sessionId;\n            this._screencastSession.ackFrame(frameNumber);\n        }\n\n        this._target.fireResultToTools(msg.id, {});\n        return Promise.resolve(null);\n    }\n\n    private onGetNavigationHistory(msg: any): Promise<any> {\n        let href = '';\n        this._target\n            .callTarget('Runtime.evaluate', { expression: 'window.location.href' })\n            .then(result => {\n                href = result.result.value;\n                return this._target.callTarget('Runtime.evaluate', { expression: 'window.title' });\n            })\n            .then(result => {\n                const title = result.result.value;\n                this._target.fireResultToTools(msg.id, {\n                    currentIndex: 0,\n                    entries: [{ id: 0, url: href, title: title }],\n                });\n            });\n\n        return Promise.resolve(null);\n    }\n\n    private onEmulateTouchFromMouseEvent(msg: any): Promise<any> {\n        /* tslint:disable */\n        function simulate(params: any) {\n            const element = document.elementFromPoint(params.x, params.y);\n            const e = new MouseEvent(params.type, {\n                screenX: params.x,\n                screenY: params.y,\n                clientX: 0,\n                clientY: 0,\n                ctrlKey: (params.modifiers & 2) === 2,\n                shiftKey: (params.modifiers & 8) === 8,\n                altKey: (params.modifiers & 1) === 1,\n                metaKey: (params.modifiers & 4) === 4,\n                button: params.button,\n                bubbles: true,\n                cancelable: false,\n            });\n            element.dispatchEvent(e);\n            return element;\n        }\n        /* tslint:enable */\n\n        switch (msg.params.type) {\n            case 'mousePressed':\n                msg.params.type = 'mousedown';\n                break;\n            case 'mouseReleased':\n                msg.params.type = 'click';\n                break;\n            case 'mouseMoved':\n                msg.params.type = 'mousemove';\n                break;\n            default:\n                Logger.error(`Unknown emulate mouse event name '${msg.params.type}'`);\n                break;\n        }\n\n        const exp = `(${simulate.toString()})(${JSON.stringify(msg.params)})`;\n        this._target.callTarget('Runtime.evaluate', { expression: exp }).then(result => {\n            if (msg.params.type === 'click') {\n                msg.params.type = 'mouseup';\n                this._target.callTarget('Runtime.evaluate', { expression: exp });\n            }\n        });\n\n        return this._target.replyWithEmpty(msg);\n    }\n\n    private onCanEmulateNetworkConditions(msg: any): Promise<any> {\n        const result = {\n            result: false,\n        };\n        this._target.fireResultToTools(msg.id, result);\n        return Promise.resolve(null);\n    }\n\n    private onConsoleMessageAdded(msg: any): Promise<any> {\n        let message = msg.params.message;\n        let type;\n        if (message.type === 'log') {\n            switch (message.level) {\n                case 'log':\n                    type = 'log';\n                    break;\n                case 'info':\n                    type = 'info';\n                    break;\n                case 'error':\n                    type = 'error';\n                    break;\n                default:\n                    type = 'log';\n            }\n        } else {\n            type = message.type;\n        }\n\n        const consoleMessage = {\n            source: message.source,\n            level: type,\n            text: message.text,\n            lineNumber: message.line,\n            timestamp: new Date().getTime(),\n            url: message.url,\n            stackTrace: message.stackTrace\n                ? {\n                      callFrames: message.stackTrace,\n                  }\n                : undefined,\n            networkRequestId: message.networkRequestId,\n        };\n\n        this._target.fireEventToTools('Log.entryAdded', {\n            entry: consoleMessage,\n        });\n\n        return Promise.resolve(null);\n    }\n\n    protected enumerateStyleSheets(): void {\n        this._target.callTarget('CSS.getAllStyleSheets', {}).then(msg => {\n            if (msg.headers) {\n                for (let header of msg.headers) {\n                    header.isInline = false;\n                    header.startLine = 0;\n                    header.startColumn = 0;\n                    this._target.fireEventToTools('CSS.styleSheetAdded', { header: header });\n                }\n            }\n        });\n    }\n\n    protected mapSelectorList(selectorList : any): void {\n        // Each iOS version needs to map this differently\n    }\n\n    protected mapRule(cssRule : any): void {\n        if ('ruleId' in cssRule) {\n            cssRule.styleSheetId = cssRule.ruleId.styleSheetId;\n            delete cssRule.ruleId;\n        }\n\n        this.mapSelectorList(cssRule.selectorList);\n        this.mapStyle(cssRule.style, cssRule.origin);\n\n        delete cssRule.sourceLine;\n    }\n\n    protected mapStyle(cssStyle : any, ruleOrigin : any): void {\n        if (cssStyle.cssText) {\n            const disabled = IOSProtocol.extractDisabledStyles(cssStyle.cssText, cssStyle.range);\n            for (let i = 0; i < disabled.length; i++) {\n                const text = disabled[i].content\n                    .trim()\n                    .replace(/^\\/\\*\\s*/, '')\n                    .replace(/;\\s*\\*\\/$/, '');\n                const parts = text.split(':');\n\n                if (cssStyle.cssProperties) {\n                    let index = cssStyle.cssProperties.length;\n                    for (let j = 0; j < cssStyle.cssProperties.length; j++) {\n                        if (\n                            cssStyle.cssProperties[j].range &&\n                            (cssStyle.cssProperties[j].range.startLine > disabled[i].range.startLine ||\n                                (cssStyle.cssProperties[j].range.startLine === disabled[i].range.startLine &&\n                                    cssStyle.cssProperties[j].range.startColumn > disabled[i].range.startColumn))\n                        ) {\n                            index = j;\n                            break;\n                        }\n                    }\n\n                    cssStyle.cssProperties.splice(index, 0, {\n                        implicit: false,\n                        name: parts[0],\n                        range: disabled[i].range,\n                        status: 'disabled',\n                        text: disabled[i].content,\n                        value: parts[1],\n                    });\n                }\n            }\n        }\n\n        for (let cssProperty of cssStyle.cssProperties) {\n            this.mapCssProperty(cssProperty);\n        }\n\n        if (ruleOrigin !== 'user-agent') {\n            cssStyle.styleSheetId = cssStyle.styleId.styleSheetId;\n            const styleKey = `${cssStyle.styleSheetId}_${JSON.stringify(cssStyle.range)}`;\n            this._styleMap.set(styleKey, cssStyle.styleId);\n        }\n\n        delete cssStyle.styleId;\n        delete cssStyle.sourceLine;\n        delete cssStyle.sourceURL;\n        delete cssStyle.width;\n        delete cssStyle.height;\n    }\n\n    protected mapCssProperty(cssProperty : any): void {\n        if (cssProperty.status === 'disabled') {\n            cssProperty.disabled = true;\n        } else if (cssProperty.status === 'active') {\n            cssProperty.disabled = false;\n        }\n\n        delete cssProperty.status;\n\n        cssProperty.important = !!cssProperty.priority;\n        delete cssProperty.priority;\n    }\n\n    /**\n     * Converts a given index to line and column, offset from a given range otherwise from 0.\n     * @returns Line column converted from the given index and offset start range.\n     */\n    private static getLineColumnFromIndex(\n        text: string,\n        index: number,\n        startRange?: IRange,\n    ): { line: number; column: number } {\n        if (text === null || typeof text === 'undefined' || index < 0 || index > text.length) {\n            return { line: -1, column: -1};\n        }\n\n        let line = startRange ? startRange.startLine : 0;\n        let column = startRange ? startRange.startColumn : 0;\n        for (let i = 0, length = text.length; i < length && i < index; i++) {\n            if (text[i] === '\\r' && i + 1 < text.length && text[i + 1] === '\\n') {\n                i++;\n                line++;\n                column = 0;\n            } else if (text[i] === '\\n' || text[i] === '\\r') {\n                line++;\n                column = 0;\n            } else {\n                column++;\n            }\n        }\n\n        return { line: line, column: column };\n    }\n\n    /**\n     * Extract a sequence of texts with ranges corresponding to block comments in the CSS.\n     * The texts may or may not contain CSS properties.\n     * @returns An array of the disabled styles\n     */\n    private static extractDisabledStyles(styleText: string, range: IRange): IDisabledStyle[] {\n        const startIndices: number[] = [];\n        const styles: IDisabledStyle[] = [];\n\n        for (let index = 0, length = styleText.length; index < length; index++) {\n            if (styleText.substr(index, IOSProtocol.BEGIN_COMMENT.length) === IOSProtocol.BEGIN_COMMENT) {\n                startIndices.push(index);\n                index = index + IOSProtocol.BEGIN_COMMENT.length - 1;\n            } else if (styleText.substr(index, IOSProtocol.END_COMMENT.length) === IOSProtocol.END_COMMENT) {\n                if (startIndices.length === 0) {\n                    // Invalid state\n                    return [];\n                }\n\n                const startIndex = startIndices.pop() || -1;\n                const endIndex = index + IOSProtocol.END_COMMENT.length;\n                const startRange = IOSProtocol.getLineColumnFromIndex(styleText, startIndex, range);\n                const endRange = IOSProtocol.getLineColumnFromIndex(styleText, endIndex, range);\n\n                const propertyItem: IDisabledStyle = {\n                    content: styleText.substring(startIndex, endIndex),\n                    range: {\n                        startLine: startRange.line,\n                        startColumn: startRange.column,\n                        endLine: endRange.line,\n                        endColumn: endRange.column,\n                    },\n                };\n\n                styles.push(propertyItem);\n                index = endIndex - 1;\n            }\n        }\n\n        if (startIndices.length !== 0) {\n            // Invalid state\n            return [];\n        }\n\n        return styles;\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/ios/ios12.ts",
    "content": "import { IOS9Protocol } from './ios9';\nimport { IOSTarget } from '../iosTarget';\n\nexport class IOS12Protocol extends IOS9Protocol {\n\n    constructor(target: IOSTarget) {\n        super(target);\n        target.targetBased = true;\n\n        target.addMessageFilter('target::Target.targetCreated', (msg) => this.onTargetCreated(msg));\n    }\n\n    private onTargetCreated(msg: any): Promise<any> {\n        this._target.targetId = msg.params.targetInfo.targetId;\n\n        return Promise.resolve(msg);\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/ios/ios8.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport { IOSProtocol} from './ios';\nimport { IOSTarget } from '../iosTarget';\nimport { Logger } from '../../logger';\n\nexport class IOS8Protocol extends IOSProtocol {\n\n    constructor(target: IOSTarget) {\n        super(target);\n\n        this._target.addMessageFilter('target::error', (msg) => {\n            Logger.error('Error received (overriding) ' + JSON.stringify(msg));\n            msg = {\n                id: msg.id,\n                result: {}\n            };\n\n            return Promise.resolve(msg);\n        });\n    }\n\n    protected mapSelectorList (selectorList : any): void {\n        const range = selectorList.range;\n\n        for (let i = 0; i < selectorList.selectors.length; i++) {\n            selectorList.selectors[i] = {text: selectorList.selectors[i]};\n\n            if (range !== undefined) {\n                selectorList.selectors[i].range = range;\n            }\n        }\n\n        delete selectorList.range;\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/ios/ios9.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport { IOSProtocol } from './ios';\nimport { IOSTarget } from '../iosTarget';\nimport { AdapterTarget } from '../target';\n\nexport class IOS9Protocol extends IOSProtocol {\n\n    constructor(target: AdapterTarget) {\n        super(target);\n    }\n\n    protected mapSelectorList (selectorList : any): void {\n        const range = selectorList.range;\n\n        for (let i = 0; i < selectorList.selectors.length; i++) {\n            if (range !== undefined) {\n                selectorList.selectors[i].range = range;\n            }\n        }\n\n        delete selectorList.range;\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/ios/screencast.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport { IOSTarget } from '../iosTarget';\nimport { AdapterTarget } from '../target';\n\nexport class ScreencastSession {\n    private _target: AdapterTarget;\n    private _frameId: number = 0;\n    private _framesAcked: boolean[] = new Array();\n    private _frameInterval: number = 250; // 60 fps is 16ms\n    private _format: string;\n    private _quality: number;\n    private _maxWidth: number;\n    private _maxHeight: number;\n    private _timerCookie: any;\n    private _deviceWidth: number = 0;\n    private _deviceHeight: number = 0;\n    private _offsetTop: number = 0;\n    private _pageScaleFactor: number = 0;\n    private _scrollOffsetX: number = 0;\n    private _scrollOffsetY: number = 0;\n\n    constructor(target: AdapterTarget, format?: string, quality?: number, maxWidth?: number, maxHeight?: number) {\n        this._target = target;\n        this._format = format || 'jpg';\n        this._quality = quality || 100;\n        this._maxHeight = maxHeight || 1024;\n        this._maxWidth = maxWidth || 1024;\n    }\n\n    public dispose(): void {\n        this.stop();\n    }\n\n    public start(): void {\n        this._framesAcked = new Array();\n        this._frameId = 1; // CDT seems to be 1 based and won't ack when 0\n\n        this._target.callTarget('Runtime.evaluate', {\n                expression: '(window.innerWidth > 0 ? window.innerWidth : screen.width) + \",\" + (window.innerHeight > 0 ? window.innerHeight : screen.height) + \",\" + window.devicePixelRatio'\n            }).then((msg) => {\n                const parts = msg.result.value.split(',');\n                this._deviceWidth = parseInt(parts[0], 10);\n                this._deviceHeight = parseInt(parts[1], 10);\n                this._pageScaleFactor = parseInt(parts[2], 10);\n\n                this._timerCookie = setInterval(() => this.recordingLoop(), this._frameInterval);\n            });\n    }\n\n    public stop(): void {\n        clearInterval(this._timerCookie);\n    }\n\n    public ackFrame(frameNumber: number): void {\n        this._framesAcked[frameNumber] = true;\n    }\n\n    private recordingLoop(): void {\n        const currentFrame = this._frameId;\n        if (currentFrame > 1 && !this._framesAcked[currentFrame - 1]) {\n            return;\n        }\n\n        this._frameId++;\n\n        this._target.callTarget('Runtime.evaluate', { expression: 'window.document.body.offsetTop + \",\" + window.pageXOffset + \",\" + window.pageYOffset' }).then((msg) => {\n            if (msg.wasThrown) {\n                return Promise.reject('');\n            }\n            const parts = msg.result.value.split(',');\n            this._offsetTop = parseInt(parts[0], 10);\n            this._scrollOffsetX = parseInt(parts[1], 10);\n            this._scrollOffsetY = parseInt(parts[2], 10);\n            return Promise.resolve();\n        }).then(() => {\n            this._target.callTarget('Page.snapshotRect', { x: 0, y: 0, width: this._deviceWidth, height: this._deviceHeight, coordinateSystem: 'Viewport' }).then((msg) => {\n                const index = msg.dataURL.indexOf('base64,');\n\n                const frame = {\n                    data: msg.dataURL.substr(index + 7),\n                    metadata: {\n                        pageScaleFactor: this._pageScaleFactor,\n                        offsetTop: this._offsetTop,\n                        deviceWidth: this._deviceWidth,\n                        deviceHeight: this._deviceHeight,\n                        scrollOffsetX: this._scrollOffsetX,\n                        scrollOffsetY: this._scrollOffsetY,\n                        timestamp: new Date()\n                    },\n                    sessionId: currentFrame\n                };\n                this._target.fireEventToTools('Page.screencastFrame', frame);\n            });\n        }, () => {\n            // Do nothing\n        });\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/iosTarget.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as WebSocket from 'ws';\nimport { EventEmitter } from 'events';\nimport { Logger, debug } from '../logger';\nimport { ITarget } from '../adapters/adapterInterfaces';\nimport { AdapterTarget } from './target';\nimport { raw } from 'express';\n\nexport class IOSTarget extends EventEmitter implements AdapterTarget {\n    private _data: ITarget;\n    private _url: string = \"\";\n    private _wsTarget?: WebSocket;\n    private _wsTools?: WebSocket;\n    private _isConnected: boolean = false;\n    private _messageBuffer: string[];\n    private _messageFilters: Map<string, ((msg: any) => Promise<any>)[]>;\n    private _toolRequestMap: Map<number, string>;\n    private _adapterRequestMap: Map<number, { resolve: (arg0: any) => void; reject: (arg0: any) => void }>;\n    private _requestId: number;\n    private _id: string;\n    private _targetBased: boolean;\n    private _targetId: string;\n\n    constructor(targetId: string, data?: ITarget) {\n        super();\n        this._data = data || <ITarget>{};\n        this._messageBuffer = [];\n        this._messageFilters = new Map<string, ((msg: any) => Promise<any>)[]>();\n        this._toolRequestMap = new Map<number, string>();\n        this._adapterRequestMap = new Map<number, { resolve: (arg0: any) => void; reject: (arg0: any) => void }>();\n        this._requestId = 0;\n        this._targetBased = false;\n        this._targetId = \"\";\n\n        // Chrome currently uses id, iOS usies appId\n        this._id = targetId;\n    }\n\n    public get data(): ITarget {\n        return this._data;\n    }\n\n    public set targetBased(isTargetBased: boolean) {\n        this._targetBased = isTargetBased;\n    }\n\n    public set targetId(targetId: string) {\n        this._targetId = targetId;\n    }\n\n    public kill() {\n        if (this._wsTarget) {\n            this._wsTarget.close();\n        }\n    }\n\n    public connectTo(url: string, wsFrom: WebSocket): void {\n        if (this._wsTarget) {\n            Logger.error(`Already connected`);\n            return;\n        }\n\n        this._url = url;\n        this._wsTools = wsFrom;\n\n        // Create a connection to the real websocket endpoint\n        this._wsTarget = new WebSocket(url);\n        this._wsTarget.on('error', err => {\n            Logger.error(err.toString());\n        });\n\n        this._wsTarget.on('message', message => {\n            this.onMessageFromTarget(message.toString());\n        });\n        this._wsTarget.on('open', () => {\n            debug(`Connection established to ${url}`);\n            this._isConnected = true;\n            for (let i = 0; i < this._messageBuffer.length; i++) {\n                this.onMessageFromTools(this._messageBuffer[i]);\n            }\n            this._messageBuffer = [];\n        });\n        this._wsTarget.on('close', () => {\n            debug('Socket is closed');\n            // The socket has closed, we should send this message up to the parent\n            this._wsTarget = undefined;\n            this.emit('socketClosed', this._id);\n        });\n    }\n\n    public forward(message: string): void {\n        if (!this._wsTarget) {\n            Logger.error('No websocket endpoint found');\n            return;\n        }\n\n        this.onMessageFromTools(message);\n    }\n\n    public updateClient(wsFrom: WebSocket): void {\n        if (this._wsTarget) {\n            this._wsTarget.close();\n        }\n        this._wsTarget = undefined;\n        this.connectTo(this._url, wsFrom);\n    }\n\n    public addMessageFilter(method: string, filter: (msg: any) => Promise<any>): void {\n        if (!this._messageFilters.has(method)) {\n            this._messageFilters.set(method, []);\n        }\n\n        this._messageFilters.get(method)?.push(filter);\n    }\n\n    public callTarget(method: string, params: any): Promise<any> {\n        return new Promise((resolve, reject) => {\n            const request = {\n                id: --this._requestId,\n                method: method,\n                params: params,\n            };\n\n            this._adapterRequestMap.set(request.id, { resolve: resolve, reject: reject });\n            this.sendToTarget(JSON.stringify(request));\n        });\n    }\n\n    public fireEventToTools(method: string, params: any): void {\n        const response = {\n            method: method,\n            params: params,\n        };\n\n        this.sendToTools(JSON.stringify(response));\n    }\n\n    public fireResultToTools(id: number, params: any): void {\n        const response = {\n            id: id,\n            result: params,\n        };\n\n        this.sendToTools(JSON.stringify(response));\n    }\n\n    public replyWithEmpty(msg: any): Promise<any> {\n        this.fireResultToTools(msg.id, {});\n        return Promise.resolve(null);\n    }\n\n    private onMessageFromTools(rawMessage: string): void {\n        if (!this._isConnected) {\n            debug('Connection not yet open, buffering message.');\n            this._messageBuffer.push(rawMessage);\n            return;\n        }\n\n        const msg = JSON.parse(rawMessage);\n        const eventName = `tools::${msg.method}`;\n\n        this._toolRequestMap.set(msg.id, msg.method);\n        this.emit(eventName, msg.params);\n\n        if (this._messageFilters.has(eventName)) {\n            let sequence = Promise.resolve(msg);\n\n            this._messageFilters.get(eventName)?.forEach(filter => {\n                sequence = sequence.then(filteredMessage => {\n                    return filter(filteredMessage);\n                });\n            });\n\n            sequence.then(filteredMessage => {\n                // Only send on the message if it wasn't completely filtered out\n                if (filteredMessage) {\n                    rawMessage = JSON.stringify(filteredMessage);\n                    this.sendToTarget(rawMessage);\n                }\n            });\n        } else {\n            // Pass it on to the target\n            this.sendToTarget(rawMessage);\n        }\n    }\n\n    private onMessageFromTarget(rawMessage: string): void {\n        let msg = JSON.parse(rawMessage);\n        if (this._targetBased) {\n            if (!msg.method || !msg.method.match(/^Target/)) {\n                return;\n            }\n            if (msg.method === 'Target.dispatchMessageFromTarget') {\n                rawMessage = msg.params.message;\n                msg = JSON.parse(rawMessage);\n            }\n        }\n\n        if ('id' in msg) {\n            if (this._toolRequestMap.has(msg.id)) {\n                // Reply to tool request\n                let eventName = `target::${this._toolRequestMap.get(msg.id)}`;\n                this.emit(eventName, msg.params);\n\n                this._toolRequestMap.delete(msg.id);\n\n                if ('error' in msg && this._messageFilters.has('target::error')) {\n                    eventName = 'target::error';\n                }\n\n                if (this._messageFilters.has(eventName)) {\n                    let sequence = Promise.resolve(msg);\n\n                    this._messageFilters.get(eventName)?.forEach(filter => {\n                        sequence = sequence.then(filteredMessage => {\n                            return filter(filteredMessage);\n                        });\n                    });\n\n                    sequence.then(filteredMessage => {\n                        rawMessage = JSON.stringify(filteredMessage);\n                        this.sendToTools(rawMessage);\n                    });\n                } else {\n                    // Pass it on to the tools\n                    this.sendToTools(rawMessage);\n                }\n            } else if (this._adapterRequestMap.has(msg.id)) {\n                // Reply to adapter request\n                const resultPromise = this._adapterRequestMap.get(msg.id);\n                this._adapterRequestMap.delete(msg.id);\n\n                if ('result' in msg) {\n                    resultPromise?.resolve(msg.result);\n                } else if ('error' in msg) {\n                    resultPromise?.reject(msg.error);\n                } else {\n                    Logger.error(`Unhandled type of request message from target ${rawMessage}`);\n                }\n            } else {\n                Logger.error(`Unhandled message from target ${rawMessage}`);\n            }\n        } else {\n            const eventName = `target::${msg.method}`;\n            this.emit(eventName, msg);\n\n            if (this._messageFilters.has(eventName)) {\n                let sequence = Promise.resolve(msg);\n\n                this._messageFilters.get(eventName)?.forEach(filter => {\n                    sequence = sequence.then(filteredMessage => {\n                        return filter(filteredMessage);\n                    });\n                });\n\n                sequence.then(filteredMessage => {\n                    rawMessage = JSON.stringify(filteredMessage);\n                    this.sendToTools(rawMessage);\n                });\n            } else {\n                // Pass it on to the tools\n                this.sendToTools(rawMessage);\n            }\n        }\n    }\n\n    private sendToTools(rawMessage: string): void {\n        debug(`sendToTools.${rawMessage}`);\n        // Make sure the tools socket can receive messages\n\n        if (this._wsTools && this.isSocketConnected(this._wsTools)) {\n            this._wsTools.send(rawMessage);\n        }\n    }\n\n    private sendToTarget(rawMessage: string): void {\n        debug(`sendToTarget.${rawMessage}`);\n        if (this._targetBased) {\n            const message = JSON.parse(rawMessage);\n            if (!message.method.match(/^Target/)) {\n                const newMessage = {\n                    id: message.id,\n                    method: 'Target.sendMessageToTarget',\n                    params: {\n                        id: message.id,\n                        message: JSON.stringify(message),\n                        targetId: this._targetId,\n                    },\n                };\n                rawMessage = JSON.stringify(newMessage);\n                debug(`sendToTarget.targeted.${rawMessage}`);\n            }\n        }\n\n        // Make sure the target socket can receive messages\n        if (this._wsTarget && this.isSocketConnected(this._wsTarget)) {\n            this._wsTarget.send(rawMessage);\n        } else {\n            // The socket has closed, we should send this message up to the parent\n            this._wsTarget = undefined;\n            this.emit('socketClosed', this._id);\n        }\n    }\n\n    private isSocketConnected(ws: WebSocket): boolean {\n        return ws && ws.readyState === WebSocket.OPEN;\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/protocol.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport { AdapterTarget } from './target';\n\nexport class ProtocolAdapter {\n    protected _target: AdapterTarget;\n\n    constructor(target: AdapterTarget) {\n        this._target = target;\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/protocols/target.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as WebSocket from 'ws';\nimport { EventEmitter } from 'events';\nimport { Logger, debug } from '../logger';\nimport { ITarget } from '../adapters/adapterInterfaces';\n\nexport interface AdapterTarget extends EventEmitter {\n    data: ITarget;\n    targetBased: boolean;\n    targetId: string;\n\n    // constructor(targetId: string, data?: ITarget): AdapterTarget;\n\n    kill() : void;\n\n    connectTo(url: string, wsFrom: WebSocket): void;\n\n    forward(message: string): void;\n\n    updateClient(wsFrom: WebSocket): void;\n\n    addMessageFilter(method: string, filter: (msg: any) => Promise<any>): void;\n\n    callTarget(method: string, params: any): Promise<any>;\n\n    fireEventToTools(method: string, params: any): void;\n\n    fireResultToTools(id: number, params: any): void;\n\n    replyWithEmpty(msg: any): Promise<any>;\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/src/server.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as http from 'http';\nimport * as express from 'express';\nimport * as ws from 'ws';\nimport { Server as WebSocketServer } from 'ws';\nimport { EventEmitter } from 'events';\nimport { Logger, debug } from './logger';\n\nimport { Adapter } from './adapters/adapter';\nimport { IOSAdapter } from './adapters/iosAdapter';\nimport { IIOSProxySettings } from './adapters/adapterInterfaces';\nimport { AddressInfo } from 'net';\nimport { AdapterCollection } from './adapters/adapterCollection';\nimport { UniversalAdapter } from './adapters/universalAdapter';\nimport { AndroidAdapter, AndroidDevice } from './adapters/androidAdapter';\nimport { IOSSimulatorSocketFinder } from './iosSimulatorSocketFinder';\nimport { HermesAdapter, HermesDevice } from './adapters/hermesAdapter';\n// import { TestAdapter } from './adapters/testAdapter';\n\nexport class ProxyServer extends EventEmitter {\n    private _hs?: http.Server;\n    private _es?: express.Application;\n    private _wss?: WebSocketServer;\n    private _serverPort?: number;\n    private _ios?: IOSAdapter;\n    private _android?: AndroidAdapter;\n    private _hermes?: HermesAdapter;\n    private _adapter?: UniversalAdapter;\n    private _targetFetcherInterval?: NodeJS.Timer;\n    private _simulatorSocketFinder = new IOSSimulatorSocketFinder();\n\n    private _injectedTargets = new Array();\n\n    constructor() {\n        super();\n    }\n\n    public updateKnownHermesDevices(devices: HermesDevice[]) {\n        this._hermes?.updateKnownDevices(devices);\n    }\n\n    public updateKnownAndroidDevices(devices: AndroidDevice[]) {\n        this._android?.updateKnownDevices(devices);\n    }\n\n    public async run(serverPort: number): Promise<number> {\n        this._serverPort = serverPort;\n\n        debug('server.run, port=%s', serverPort);\n\n        this._simulatorSocketFinder.start();\n\n        this._es = express();\n        this._hs = http.createServer(this._es);\n        this._wss = new WebSocketServer({\n            server: this._hs,\n        });\n        this._wss.on('connection', (a, req) => {\n            this.onWSSConnection(a, req);\n        });\n\n        this.setupHttpHandlers();\n\n        // Start server and return the port number\n        this._hs.listen(this._serverPort);\n        const port = (<AddressInfo>this._hs.address()).port;\n\n        if (process.platform !== \"linux\") {\n            const settings = await IOSAdapter.getProxySettings({\n                proxyPort: port + 100,\n                simulatorSocketFinder: this._simulatorSocketFinder,\n            });\n            this._ios = new IOSAdapter(`/ios`, `ws://localhost:${port}`, settings);\n        }\n        this._simulatorSocketFinder.observeSockets(simulatorSockets => {\n            this._ios?.forceRefresh();\n        });\n        this._android = new AndroidAdapter(`/android`, `ws://localhost:${port}`);\n        this._hermes = new HermesAdapter(`/hermes`, `ws://localhost:${port}`)\n\n        const allAdapters: Adapter<any>[] = [];\n        if (this._ios){\n            allAdapters.push(this._ios);\n        }\n        allAdapters.push(this._hermes);\n        allAdapters.push(this._android);\n        this._adapter = new UniversalAdapter(allAdapters);\n\n        return this._adapter\n            .start()\n            .then(() => {\n                this.startTargetFetcher();\n            })\n            .then(() => {\n                return port;\n            });\n    }\n\n    public stop(): void {\n        debug('server.stop');\n        this._simulatorSocketFinder.stop();\n\n        if (this._hs) {\n            this._hs.close();\n            this._hs = undefined;\n        }\n\n        this.stopTargetFetcher();\n        this._adapter?.stop();\n    }\n\n    private startTargetFetcher(): void {\n        debug('server.startTargetFetcher');\n\n        let fetch = () => {\n            this._adapter?.getTargets().then(\n                targets => {\n                    debug(`server.startTargetFetcher.fetched.${targets.length}`);\n                },\n                err => {\n                    debug(`server.startTargetFetcher.error`, err);\n                },\n            );\n        };\n\n        this._targetFetcherInterval = setInterval(fetch, 5000);\n    }\n\n    private stopTargetFetcher(): void {\n        debug('server.stopTargetFetcher');\n        if (!this._targetFetcherInterval) {\n            return;\n        }\n        clearInterval(this._targetFetcherInterval);\n    }\n\n    private setupHttpHandlers(): void {\n        debug('server.setupHttpHandlers');\n\n        this._es?.get('/', (req, res) => {\n            debug('server.http.endpoint/');\n            res.json({\n                msg: 'Hello from RemoteDebug iOS WebKit Adapter',\n            });\n        });\n\n        this._es?.get('/refresh', (req, res) => {\n            this._adapter?.forceRefresh();\n            this.emit('forceRefresh');\n            res.json({\n                status: 'ok',\n            });\n        });\n\n        this._es?.get('/json', (req, res) => {\n            debug('server.http.endpoint/json');\n            this._adapter?.getTargets().then(targets => {\n                res.json(targets);\n            });\n        });\n\n        this._es?.get('/json/list', (req, res) => {\n            debug('server.http.endpoint/json/list');\n            this._adapter?.getTargets().then(targets => {\n                res.json(targets);\n            });\n        });\n\n        this._es?.get('/json/version', (req, res) => {\n            debug('server.http.endpoint/json/version');\n            res.json({\n                Browser: 'Safari/RemoteDebug iOS Webkit Adapter',\n                'Protocol-Version': '1.2',\n                'User-Agent':\n                    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2926.0 Safari/537.36',\n                'WebKit-Version': '537.36 (@da59d418f54604ba2451cd0ef3a9cd42c05ca530)',\n            });\n        });\n\n        this._es?.get('/json/protocol', (req, res) => {\n            debug('server.http.endpoint/json/protocol');\n            res.json();\n        });\n    }\n\n    private onWSSConnection(websocket: ws, req: http.IncomingMessage): void {\n        const url = req.url || '';\n\n        debug('server.ws.onWSSConnection', url);\n\n        let connection = <EventEmitter>websocket;\n\n        try {\n            this._adapter?.on('socketClosed', id => {\n                websocket.close();\n            });\n            this._adapter?.connectTo(url, websocket);\n        } catch (err) {\n            debug(`server.onWSSConnection.connectTo.error.${err}`);\n        }\n\n        connection.on('close', () => {\n            this._adapter?.closeConnectionTo(url);\n        });\n        connection.on('message', msg => {\n            this._adapter?.forwardTo(url, msg);\n        });\n    }\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/test/helperMocks.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nexport class ProxyServerMock {\n\n}\n\nexport class LoggerMock {\n    public log(msg: string): void {};\n    public error(msg: string): void {};\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/test/protocols/target.test.ts",
    "content": "//\n// Copyright (C) Microsoft. All rights reserved.\n//\n\nimport * as assert from 'assert';\nimport * as mockery from 'mockery';\nimport * as mocha from \"mocha\";\nimport { Server, SocketIO } from 'mock-socket';\nimport { LoggerMock } from '../helperMocks';\nimport { IOSTarget } from '../../src/protocols/iosTarget';\n\n// As of 0.1.0, the included .d.ts is not in the right format to use the import syntax here\n// https://github.com/florinn/typemoq/issues/4\n// const typemoq: ITypeMoqStatic = require('typemoq');\nimport * as TypeMoq from \"typemoq\";\n\nconst MODULE_UNDER_TEST = '../../protocols/target';\n\nfunction CreateTarget(): IOSTarget {\n    const target: IOSTarget = new ((require(MODULE_UNDER_TEST)).Target)();\n    return target;\n}\n\nsuite('Proxy/Protocol/Target', () => {\n    const targetUrl = 'ws://localhost:8080';\n    const toolsUrl = 'ws://localhost:9090';\n    let loggerMock: TypeMoq.IMock<LoggerMock>\n    let targetServer: any;\n    let toolsServer: any;\n    let toolSocket: any;\n    let targetReady: Promise<void>;\n    let toolsReady: Promise<void>;\n\n    function setupTargetAndTools() {\n        toolSocket = new SocketIO(toolsUrl);\n\n        targetReady = new Promise<void>((resolve, reject) => {\n            targetServer.on('connection', server => {\n                server.emit('open');\n                resolve();\n            });\n        });\n\n        toolsReady = new Promise<void>((resolve, reject) => {\n            toolSocket.on('connect', () => {\n                resolve();\n            });\n        });\n    }\n\n    setup(() => {\n        mockery.enable({ useCleanCache: true, warnOnReplace: false, warnOnUnregistered: false });\n        mockery.registerMock('ws', SocketIO);\n\n        // The mock websocket class does not have all the necessary functions to mock.\n        // SocketIO has most of them minus the OPEN/CLOSED boolean. We only care about OPEN so lets just add this functionality on here.\n        SocketIO.OPEN = 1;\n\n        loggerMock = TypeMoq.Mock.ofType(LoggerMock, TypeMoq.MockBehavior.Loose);\n        mockery.registerMock('../../shell/logger', { Logger: loggerMock.object });\n\n        targetServer = new Server(targetUrl);\n\n        toolsServer = new Server(toolsUrl);\n        toolsServer.on('connection', server => {\n            server.emit('open');\n        });\n    });\n\n    teardown(() => {\n        mockery.deregisterAll();\n        mockery.disable();\n\n        loggerMock.verifyAll();\n\n        targetServer.stop();\n        toolsServer.stop();\n    });\n\n    suite('connectTo()', () => {\n        test('establishes a connection to the real target websocket', (done) => {\n            targetServer.on('connection', server => {\n                done();\n            });\n\n            const target = CreateTarget();\n            target.connectTo(targetUrl, null);\n        });\n\n        test('buffers messages to target before connect and then sends them on connect', (done) => {\n            const target = CreateTarget();\n            const newToolSocket = new SocketIO(toolsUrl);\n            newToolSocket.on('connect', () => {\n                target.connectTo(targetUrl, newToolSocket);\n\n                let messages = ['test', 'test2'];\n                let receivedCount = 0;\n\n                messages.forEach((i) => {\n                    target.on(`tools::${i}`, () => {\n                        receivedCount++;\n                        if (receivedCount === messages.length) {\n                            done();\n                        }\n                    });\n                    target.forward(JSON.stringify({ method: i }));\n                });\n\n                assert.equal(receivedCount, 0, 'tools should not have received a message before connecting');\n\n                // Establish the target connection now\n                targetServer.on('connection', server => {\n                    server.emit('open');\n                });\n            });\n        });\n    });\n\n    suite('forward()', () => {\n        setup(() => {\n            setupTargetAndTools();\n        });\n\n        test('emits message from tools to target', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                let messageEmitted = false;\n                target.on('tools::test', () => {\n                    messageEmitted = true;\n                });\n\n                targetServer.on('message', () => {\n                    assert.equal(messageEmitted, true, 'message should have been emitted by the target');\n                    done();\n                });\n\n                target.forward(JSON.stringify({ method: 'test' }));\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n\n        test('emits message from target to tools', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                let messageEmitted = false;\n                target.on('target::test', () => {\n                    messageEmitted = true;\n                });\n\n                toolsServer.on('message', () => {\n                    assert.equal(messageEmitted, true, 'message should have been emitted by the target');\n                    done();\n                });\n\n                targetServer.emit('message', JSON.stringify({ method: 'test' }));\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n    });\n\n    suite('fireEventToTools()', () => {\n        setup(() => {\n            setupTargetAndTools();\n        });\n\n        test('sends the correct data format', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                const expectedMethod = 'testEventName';\n                const expectedParams = { someParam: true, more: { name: 'test', value: 1 } };\n\n                toolsServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    assert.equal(data.method, expectedMethod, 'message.method should match what was fired');\n                    assert.deepEqual(data.params, expectedParams, 'message.params should match what was fired');\n                    done();\n                });\n\n                target.fireEventToTools(expectedMethod, expectedParams);\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n    });\n\n    suite('fireResultToTools()', () => {\n        setup(() => {\n            setupTargetAndTools();\n        });\n\n        test('sends the correct data format', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                const expectedId = 102;\n                const expectedResult = { method: 'css.Enable', someParam: true, more: { name: 'test', value: 1 } };\n\n                toolsServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    assert.equal(data.id, expectedId, 'message.id should match what was fired');\n                    assert.deepEqual(data.result, expectedResult, 'message.result should match what was fired');\n                    done();\n                });\n\n                target.fireResultToTools(expectedId, expectedResult);\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n    });\n\n    suite('callTarget()', () => {\n        setup(() => {\n            setupTargetAndTools();\n        });\n\n        test('sends a request to the target without calling back to the tools', (done) => {\n            const target = CreateTarget();\n\n            toolsServer.on('message', () => {\n                assert.fail('the adapter calling the target should not have sent a message to the tools', '', '', '');\n            });\n\n            target.on('target::Debugger.Enable', () => {\n                assert.fail('the adapter calling the target should not have emitted an event, it should resolve the promise instead', '', '', '');\n            });\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                const expectedMethod = 'Debugger.Enable';\n                const expectedParams = { someParam: true, more: { name: 'test', value: 1 } };\n                const expectedResponse = { id: 0, result: expectedParams };\n\n                targetServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    assert.equal(data.method, expectedMethod, 'message.method should match what was fired');\n                    assert.deepEqual(data.params, expectedParams, 'message.params should match what was fired');\n\n                    expectedResponse.id = data.id;\n                    targetServer.emit('message', JSON.stringify(expectedResponse));\n                });\n\n                target.callTarget(expectedMethod, expectedParams).then((result) => {\n                    assert.deepEqual(result, expectedParams, 'result should match what was returned from the target server');\n                    done();\n                });\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n\n        test('rejects the promise on an error from the target', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                const expectedError = { someErrorProperty: 'yes', moreInfo: { test: 1, pokemon: true } };\n                const expectedResponse = { id: 0, error: expectedError };\n\n                targetServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    expectedResponse.id = data.id;\n                    targetServer.emit('message', JSON.stringify(expectedResponse));\n                });\n\n                target.callTarget('anything', null).then((result) => {\n                    assert.fail('promise should not have succeeded', '', '', '');\n                }, (error) => {\n                    assert.deepEqual(error, expectedError, 'error should match what was returned from the target server');\n                    done();\n                });\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n    });\n\n    suite('addMessageFilter()', () => {\n        setup(() => {\n            setupTargetAndTools();\n        });\n\n        test('filter is called and modified on message from tools', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                const expectedModifiedMessage = { method: 'CSS.EnableModified', params: { someNewParams: true } };\n\n                target.addMessageFilter('tools::CSS.Enable', (msg) => {\n                    return Promise.resolve(expectedModifiedMessage);\n                });\n\n                targetServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    assert.deepEqual(data, expectedModifiedMessage, 'message should have been modified by the filter before it reached the target');\n                    done();\n                });\n\n                target.forward(JSON.stringify({ method: 'CSS.Enable' }));\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n\n        test('filter is called and modified on message from target', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                const expectedModifiedMessage = { method: 'Console.newLog', params: { someNewParams: true } };\n\n                target.addMessageFilter('target::Console.log', (msg) => {\n                    return Promise.resolve(expectedModifiedMessage);\n                });\n\n                toolsServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    assert.deepEqual(data, expectedModifiedMessage, 'message should have been modified by the filter before it reached the target');\n                    done();\n                });\n\n                targetServer.emit('message', JSON.stringify({ method: 'Console.log' }));\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n\n        test('filter is called and modifies the response to a request from tools', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                const expectedResult = { id: 10, result: { sheets: [1, 2, 3] } };\n                const expectedModifiedResult = { id: 10, result: { sheets: [1, 2, 3, 5, 6, 7, 8, 345, 534], newParam: true } };\n\n                target.addMessageFilter('target::CSS.setStyleSheets', (msg) => {\n                    assert.deepEqual(msg, expectedResult);\n                    return Promise.resolve(expectedModifiedResult);\n                });\n\n                targetServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    expectedResult.id = data.id;\n                    targetServer.emit('message', JSON.stringify(expectedResult));\n                });\n\n                toolsServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    assert.deepEqual(data, expectedModifiedResult, 'result should have been modified by the filter before it was returned back to the tools');\n                    done();\n                });\n\n                target.forward(JSON.stringify({ id: 101, method: 'CSS.setStyleSheets' }));\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n    });\n\n    suite('updateClient()', () => {\n        setup(() => {\n            setupTargetAndTools();\n        });\n\n        test('message is sent to new tools', (done) => {\n            const target = CreateTarget();\n\n            const updatedToolSocket = new SocketIO(toolsUrl);\n            const updatedToolsReady = new Promise<void>((resolve, reject) => {\n                updatedToolSocket.on('connect', () => {\n                    resolve();\n                });\n            });\n\n            Promise.all([targetReady, toolsReady, updatedToolsReady]).then(() => {\n                toolSocket.send = (msg) => {\n                    assert.fail('message should have been sent to the new server', '', '', '');\n                };\n\n                updatedToolSocket.send = (msg) => {\n                    done();\n                };\n\n                target.updateClient(updatedToolSocket);\n\n                targetServer.emit('message', JSON.stringify({ method: 'Console.log' }));\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n    });\n\n    suite('replyWithEmpty()', () => {\n        setup(() => {\n            setupTargetAndTools();\n        });\n\n        test('empty message is sent to tools', (done) => {\n            const target = CreateTarget();\n\n            Promise.all([targetReady, toolsReady]).then(() => {\n                const expectedId = 101;\n                let actualId = 0;\n\n                target.addMessageFilter('tools::DOM.apithatneedsareply', (msg) => {\n                    actualId = msg.id;\n                    return target.replyWithEmpty(msg);\n                });\n\n                toolsServer.on('message', (msg) => {\n                    const data = JSON.parse(msg);\n                    const expectedEmptyMessage = { id: actualId, result: {} };\n                    assert.deepEqual(data, expectedEmptyMessage, 'message should have been an empty result with the correct id');\n                    done();\n                });\n\n                target.forward(JSON.stringify({ id: expectedId, method: 'DOM.apithatneedsareply' }));\n            });\n\n            target.connectTo(targetUrl, toolSocket);\n        });\n    });\n});\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/test.css",
    "content": "body {\n    background: red;\n}"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/tsconfig.json",
    "content": "{\n  \"extends\": \"../tsconfig.base.json\",\n  \"compilerOptions\": {\n    \"resolveJsonModule\": true,\n    \"skipLibCheck\": true,\n    \"composite\": true,\n    \"declaration\": true,\n    \"outDir\": \"src\",\n    \"rootDir\": \"src\"\n  },\n  \"include\": [\"src/**/*.ts\", \"package.json\"],\n  \"exclude\": [\"src/**/*.json\", \"node_modules\"]\n}\n"
  },
  {
    "path": "compiler/companion/remotedebug-ios-webkit-adapter/tslint.json",
    "content": "{\n  \"rules\": {\n    \"align\": [true, \"parameters\", \"statements\"],\n    \"ban\": false,\n    \"class-name\": true,\n    \"comment-format\": [true, \"check-space\"],\n    \"curly\": false,\n    \"forin\": true,\n    \"indent\": [true, \"spaces\"],\n    \"jsdoc-format\": true,\n    \"label-position\": true,\n    \"max-line-length\": [false, 140],\n    \"member-access\": true,\n    \"member-ordering\": [true, \"variables-before-functions\"],\n    \"no-any\": false,\n    \"no-arg\": true,\n    \"no-bitwise\": true,\n    \"no-conditional-assignment\": true,\n    \"no-console\": [true, \"debug\", \"info\", \"time\", \"timeEnd\", \"trace\"],\n    \"no-construct\": true,\n    \"no-debugger\": true,\n    \"no-duplicate-variable\": true,\n    \"no-empty\": false,\n    \"no-eval\": true,\n    \"no-inferrable-types\": false,\n    \"no-internal-module\": true,\n    \"no-require-imports\": false,\n    \"no-shadowed-variable\": true,\n    \"no-string-literal\": true,\n    \"no-switch-case-fall-through\": true,\n    \"no-trailing-whitespace\": true,\n    \"no-unused-expression\": true,\n    \"no-var-keyword\": true,\n    \"no-var-requires\": true,\n    \"object-literal-sort-keys\": false,\n    \"no-consecutive-blank-lines\": true,\n    \"one-line\": [true, \"check-open-brace\", \"check-catch\", \"check-else\", \"check-whitespace\"],\n    \"quotemark\": [true, \"single\"],\n    \"radix\": true,\n    \"semicolon\": true,\n    \"switch-default\": true,\n    \"triple-equals\": [true, \"allow-null-check\"],\n    \"typedef-whitespace\": [\n      true,\n      {\n        \"call-signature\": \"nospace\",\n        \"index-signature\": \"nospace\",\n        \"parameter\": \"nospace\",\n        \"property-declaration\": \"nospace\",\n        \"variable-declaration\": \"nospace\"\n      }\n    ],\n    \"variable-name\": false,\n    \"whitespace\": [true, \"check-branch\", \"check-decl\", \"check-operator\", \"check-separator\", \"check-type\"]\n  }\n}\n"
  },
  {
    "path": "compiler/companion/scripts/run.sh",
    "content": "#!/bin/bash\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\ncd $SCRIPT_DIR/../dist\nnode --enable-source-maps --max-old-space-size=8000 bundle.js \"${@:1}\"\n"
  },
  {
    "path": "compiler/companion/scripts/run_dev.sh",
    "content": "#!/usr/bin/env bash\n\nset -o errexit  # Exit on most errors (see the manual)\nset -o nounset  # Disallow expansion of unset variables\nset -o pipefail # Use last non-zero exit code in a pipeline\nset -o xtrace   # Print commands as they are executed\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\n\ncd $SCRIPT_DIR/..\nnode src/index_tsnode.js \"${@:1}\"\n"
  },
  {
    "path": "compiler/companion/scripts/update_companion.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\nset -x\n\necho \"Updating Valdi companion...\"\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" >/dev/null 2>&1 && pwd)\" \nBASE_PATH=\"${SCRIPT_DIR}/../\"\nPROJECT_ROOT_PATH=\"${SCRIPT_DIR}/../../../\"\n\nskip_analytics=false\ncompanion_output_path=\"\"\n\nusage() {\n  echo \"Usage: $0 [-o companion_output_path] [-s] [companion_output_path]\"\n  exit 1\n}\n\n# Parse simple command line options\nwhile getopts \":o:s\" opt; do\n  case \"$opt\" in\n    s)\n      skip_analytics=true\n      ;;\n    o)\n      companion_output_path=$OPTARG\n      ;;\n    \\? )\n      echo \"Invalid option: $OPTARG\" 1>&2\n      usage\n      ;;\n    : )\n      echo \"Invalid option: $OPTARG requires an argument\" 1>&2\n      usage\n      ;;\n  esac\ndone\n\nshift $((OPTIND -1))\n\nif [[ ! -z $ENV_SKIP_ANALYTICS ]] && [ \"$ENV_SKIP_ANALYTICS\" = true ]; then\n    skip_analytics=true\nfi\n\n# Assign positional arguments if options were not provided\nif [ -z \"$companion_output_path\" ] && [ $# -ge 1 ]; then\n  companion_output_path=$1\n  shift\nfi\n\n# Main\npushd \"$BASE_PATH\"\n\ngit rev-parse HEAD > ./COMMIT_HASH\n\nrm -rf dist\nnpm install\nnpm run test\npopd\n\npushd \"$PROJECT_ROOT_PATH\"\n\nbzl build //compiler/companion:bundle\n\nreal_companion_path=$(realpath bazel-bin/compiler/companion/dist/)\n\npopd\n\n\n\n# Move companion to output path if specified\nif [ ! -z \"$companion_output_path\" ] && [ ! $real_companion_path -ef $companion_output_path ]; then\n  echo \"Companion output path is: $companion_output_path\"\n  rm -rf \"$companion_output_path\"\n  mkdir -p \"$companion_output_path\"\n  cp -rf $real_companion_path/* \"$companion_output_path\"\nfi\n\nif $skip_analytics; then\n    echo \"Analytic uploading for this run will be skipped...\"\n    exit 0\nfi\n"
  },
  {
    "path": "compiler/companion/src/AST.spec.ts",
    "content": "import 'ts-jest';\nimport {\n  AST,\n  dumpInterface,\n  dumpRootNodes,\n  getImportStringLiteralsFromSourceFile,\n  isNonModuleWithAmbiantDeclarations,\n} from './AST';\nimport { findNode, getNodeComments } from './TSUtils';\nimport * as ts from 'typescript';\nimport { Project } from './project/Project';\n\ninterface CompiledFile {\n  sourceFile: ts.SourceFile;\n  typeChecker: ts.TypeChecker;\n}\n\nfunction compile(str: string): CompiledFile {\n  const project = new Project('/', {});\n  const sourceFile = project.createSourceFile('File.ts', str);\n  return {\n    sourceFile: sourceFile,\n    typeChecker: project.typeChecker,\n  };\n}\n\ndescribe('AST', () => {\n  it('can find types to dump', () => {\n    const result = compile(\n      `class Component<VM> {\n\n      }\n\n      // @ExportProxy({ios: 'SCTCallGridParticipant', android: 'com.snap.talk.SCTCallGridParticipant'})\n      interface Participant {\n        displayName: string;\n        color: string;\n        hasVideo: boolean;\n      }\n\n      /* @ViewModel\n      @ExportModel({ios: 'SCTCallGridViewModel', android: 'com.snap.talk.CallGridViewModel'}) */\n      interface CallGridViewModel {\n        participants: Participant[];\n        foo: number;\n        bar: string;\n      }\n\n      /**\n       * @Component\n       * @ExportModel({ios: 'SCTCallGrid, android: 'com.snap.talk.CallGrid'})\n       */\n      export class CallGrid extends Component<CallGridViewModel> {\n        // @Action\n        someAction() {\n\n        }\n\n        onRender() {\n          <layout></layout>;\n        }\n      }\n    `,\n    );\n\n    const dumpedNodes = dumpRootNodes(result.sourceFile, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    expect(dumpedNodes.length).toEqual(3);\n\n    const firstMemberOfComponent = dumpedNodes[2]!.interface!.members[0];\n    expect(firstMemberOfComponent.name).toEqual('someAction');\n    expect(firstMemberOfComponent.leadingComments?.text).toContain('@Action');\n  });\n\n  it('can dump enums', () => {\n    const result = compile(\n      `\n      // @ExportEnum\n      enum MyEnum {\n        // This is a String\n        aString = 'Hello',\n        /**\n         * This is a number\n         */\n        aNumber = 42,\n      }\n    `,\n    );\n\n    const dumpedNodes = dumpRootNodes(result.sourceFile, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    expect(dumpedNodes.length).toEqual(1);\n\n    const enumNode = dumpedNodes[0];\n    expect(enumNode.leadingComments?.text).toContain('@ExportEnum');\n    expect(enumNode.enum).toBeTruthy();\n    expect(enumNode.enum!.name).toEqual('MyEnum');\n    expect(enumNode.enum!.members?.length).toEqual(2);\n\n    const firstEnumMember = enumNode.enum!.members[0]!;\n    expect(firstEnumMember.name).toEqual('aString');\n    expect(firstEnumMember.leadingComments?.text).toContain('This is a String');\n    expect(firstEnumMember.stringValue).toEqual('Hello');\n\n    const secondEnumMember = enumNode.enum!.members[1]!;\n    expect(secondEnumMember.name).toEqual('aNumber');\n    expect(secondEnumMember.numberValue).toContain('42');\n    expect(secondEnumMember.leadingComments?.text).toContain('This is a number');\n  });\n\n  it('can dump simple interface', () => {\n    const result = compile(\n      `\n    export interface GroupRecipient {\n      recipientType: number;\n      groupId: string;\n      displayName?: string;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'GroupRecipient',\n      start: 0,\n      end: 119,\n      typeParameters: undefined,\n      members: [\n        {\n          name: 'recipientType',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 40,\n          end: 62,\n          type: { name: 'number' },\n        },\n        {\n          name: 'groupId',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 69,\n          end: 85,\n          type: { name: 'string' },\n        },\n        {\n          name: 'displayName',\n          isOptional: true,\n          leadingComments: undefined,\n          start: 92,\n          end: 113,\n          type: { name: 'string' },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump interface with simple arrays', () => {\n    const result = compile(\n      `\n    export interface SomeInterface {\n      someNumbers: number[];\n      someStrings: string[];\n      someOptionalNumbers?: number[];\n      someOptionalStrings?: string[];\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'SomeInterface',\n      start: 0,\n      end: expect.anything(),\n      typeParameters: undefined,\n      members: [\n        {\n          name: 'someNumbers',\n          isOptional: false,\n          leadingComments: undefined,\n          start: expect.anything(),\n          end: expect.anything(),\n          type: {\n            name: 'array',\n            array: {\n              name: 'number',\n            },\n          },\n        },\n        {\n          name: 'someStrings',\n          isOptional: false,\n          leadingComments: undefined,\n          start: expect.anything(),\n          end: expect.anything(),\n          type: {\n            name: 'array',\n            array: {\n              name: 'string',\n            },\n          },\n        },\n        {\n          name: 'someOptionalNumbers',\n          isOptional: true,\n          leadingComments: undefined,\n          start: expect.anything(),\n          end: expect.anything(),\n          type: {\n            name: 'array',\n            array: { name: 'number' },\n          },\n        },\n        {\n          name: 'someOptionalStrings',\n          isOptional: true,\n          leadingComments: undefined,\n          start: expect.anything(),\n          end: expect.anything(),\n          type: {\n            name: 'array',\n            array: { name: 'string' },\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump interface with generic arrays', () => {\n    const result = compile(\n      `\n    export interface SomeInterface {\n      someNumbers: Array<number>;\n      someStrings: Array<string>;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const references: AST.TypeReferences = {\n      typeChecker: result.typeChecker,\n      references: [],\n    };\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, references);\n\n    const expectedOutput: AST.Interface = {\n      name: 'SomeInterface',\n      start: expect.anything(),\n      end: expect.anything(),\n      typeParameters: undefined,\n      members: [\n        {\n          name: 'someNumbers',\n          isOptional: false,\n          leadingComments: undefined,\n          start: expect.anything(),\n          end: expect.anything(),\n          type: {\n            name: 'array',\n            array: {\n              name: 'number',\n            },\n          },\n        },\n        {\n          name: 'someStrings',\n          isOptional: false,\n          leadingComments: undefined,\n          start: expect.anything(),\n          end: expect.anything(),\n          type: {\n            name: 'array',\n            array: {\n              name: 'string',\n            },\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n\n    expect(references.references).toEqual([]);\n  });\n\n  it('can dump interface with functions', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      aLambda: (param1: number) => string;\n      aFunction(str: string): number;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 117,\n      typeParameters: undefined,\n      members: [\n        {\n          name: 'aLambda',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 37,\n          end: 73,\n          type: {\n            name: 'function',\n            function: {\n              parameters: [\n                {\n                  start: 47,\n                  end: 61,\n                  isOptional: false,\n                  name: 'param1',\n                  type: {\n                    name: 'number',\n                  },\n                },\n              ],\n              returnValue: {\n                name: 'string',\n              },\n            },\n          },\n        },\n        {\n          name: 'aFunction',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 80,\n          end: 111,\n          type: {\n            name: 'function',\n            function: {\n              parameters: [\n                {\n                  name: 'str',\n                  isOptional: false,\n                  start: 90,\n                  end: 101,\n                  type: {\n                    name: 'string',\n                  },\n                },\n              ],\n              returnValue: {\n                name: 'number',\n              },\n            },\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump interface with nested lambdas', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      aComplexLambda: (param1: (nested: number) => void, param2: (((() => void))),) => () => void;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 135,\n      typeParameters: undefined,\n      members: [\n        {\n          name: 'aComplexLambda',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 37,\n          end: 129,\n          type: {\n            name: 'function',\n            function: {\n              parameters: [\n                {\n                  start: 54,\n                  end: 86,\n                  isOptional: false,\n                  name: 'param1',\n                  type: {\n                    name: 'function',\n                    function: {\n                      parameters: [\n                        {\n                          name: 'nested',\n                          start: 63,\n                          end: 77,\n                          isOptional: false,\n                          type: {\n                            name: 'number',\n                          },\n                        },\n                      ],\n                      returnValue: {\n                        name: 'void',\n                      },\n                    },\n                  },\n                },\n                {\n                  start: 88,\n                  end: 112,\n                  isOptional: false,\n                  name: 'param2',\n                  type: {\n                    name: 'function',\n                    function: {\n                      parameters: [],\n                      returnValue: {\n                        name: 'void',\n                      },\n                    },\n                  },\n                },\n              ],\n              returnValue: {\n                name: 'function',\n                function: {\n                  parameters: [],\n                  returnValue: {\n                    name: 'void',\n                  },\n                },\n              },\n            },\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump comments on types', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      fetch(cb: /* Parameter comment */ () => void): /* Return comment */ () => void;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 122,\n      typeParameters: undefined,\n      members: [\n        {\n          name: 'fetch',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 37,\n          end: 116,\n          type: {\n            name: 'function',\n            function: {\n              parameters: [\n                {\n                  start: 43,\n                  end: 81,\n                  isOptional: false,\n                  name: 'cb',\n                  type: {\n                    name: 'function',\n                    leadingComments: {\n                      text: '/* Parameter comment */',\n                      start: 47,\n                      end: 70,\n                    },\n                    function: {\n                      parameters: [],\n                      returnValue: {\n                        name: 'void',\n                      },\n                    },\n                  },\n                },\n              ],\n              returnValue: {\n                name: 'function',\n                leadingComments: { text: '/* Return comment */', start: 84, end: 104 },\n                function: {\n                  parameters: [],\n                  returnValue: {\n                    name: 'void',\n                  },\n                },\n              },\n            },\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump interface with lambda returning nullable type', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      anOptionalLambda?: () => string | undefined;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 87,\n      members: [\n        {\n          name: 'anOptionalLambda',\n          isOptional: true,\n          leadingComments: undefined,\n          start: 37,\n          end: 81,\n          type: {\n            name: 'function',\n            function: {\n              parameters: [],\n              returnValue: {\n                name: 'union',\n                unions: [{ name: 'string' }, { name: 'undefined' }],\n              },\n            },\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump interface with union', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      unionType: number | string | undefined;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 82,\n      members: [\n        {\n          name: 'unionType',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 37,\n          end: 76,\n          type: { name: 'union', unions: [{ name: 'number' }, { name: 'string' }, { name: 'undefined' }] },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump interface with related types', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      value: Interface2;\n    }\n\n    interface Interface2 {\n\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const references: AST.TypeReferences = {\n      typeChecker: result.typeChecker,\n      references: [],\n    };\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, references);\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 61,\n      members: [\n        {\n          name: 'value',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 37,\n          end: 55,\n          type: {\n            name: 'reference',\n            typeReferenceIndex: 0,\n            isTypeParameter: false,\n            typeArguments: undefined,\n          },\n        },\n      ],\n      typeParameters: undefined,\n    };\n\n    expect(output).toEqual(expectedOutput);\n\n    const expectedFileName = '/File.ts';\n    expect(references.references).toEqual([{ name: 'Interface2', fileName: expectedFileName }]);\n  });\n\n  it('can dump interface with related enum', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      value: MyEnum;\n    }\n\n    const enum MyEnum {\n\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const references: AST.TypeReferences = {\n      typeChecker: result.typeChecker,\n      references: [],\n    };\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, references);\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 57,\n      members: [\n        {\n          name: 'value',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 37,\n          end: 51,\n          type: {\n            name: 'reference',\n            typeReferenceIndex: 0,\n            isTypeParameter: false,\n            typeArguments: undefined,\n          },\n        },\n      ],\n      typeParameters: undefined,\n    };\n\n    expect(output).toEqual(expectedOutput);\n\n    const expectedFileName = '/File.ts';\n    expect(references.references).toEqual([{ name: 'MyEnum', fileName: expectedFileName }]);\n  });\n\n  it('can dump interface with enum value', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      value: MyEnum.HEY;\n    }\n\n    const enum MyEnum {\n      HEY = 1,\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const references: AST.TypeReferences = {\n      typeChecker: result.typeChecker,\n      references: [],\n    };\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, references);\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 61,\n      members: [\n        {\n          name: 'value',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 37,\n          end: 55,\n          type: {\n            name: 'reference',\n            typeReferenceIndex: 0,\n            isTypeParameter: false,\n            typeArguments: undefined,\n          },\n        },\n      ],\n      typeParameters: undefined,\n    };\n\n    expect(output).toEqual(expectedOutput);\n\n    const expectedFileName = '/File.ts';\n    expect(references.references).toEqual([{ name: 'MyEnum', fileName: expectedFileName }]);\n  });\n\n  it('can dump interface with null', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      aFunction(str: string | null): number;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: 0,\n      end: 81,\n      members: [\n        {\n          name: 'aFunction',\n          isOptional: false,\n          leadingComments: undefined,\n          start: 37,\n          end: 75,\n          type: {\n            name: 'function',\n            function: {\n              parameters: [\n                {\n                  name: 'str',\n                  isOptional: false,\n                  start: 47,\n                  end: 65,\n                  type: {\n                    name: 'union',\n                    unions: [{ name: 'string' }, { name: 'null' }],\n                  },\n                },\n              ],\n              returnValue: {\n                name: 'number',\n              },\n            },\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump interface with generic type parameters', () => {\n    const result = compile(\n      `\n    export interface MyInterface<T> {\n      value: T;\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const references: AST.TypeReferences = {\n      typeChecker: result.typeChecker,\n      references: [],\n    };\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, references);\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: expect.anything(),\n      end: expect.anything(),\n      members: [\n        {\n          name: 'value',\n          isOptional: false,\n          leadingComments: undefined,\n          start: expect.anything(),\n          end: expect.anything(),\n          type: {\n            name: 'reference',\n            typeReferenceIndex: 0,\n            isTypeParameter: true,\n            typeArguments: undefined,\n          },\n        },\n      ],\n      typeParameters: [\n        {\n          start: expect.anything(),\n          end: expect.anything(),\n          name: 'T',\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n\n    const expectedFileName = '/File.ts';\n    expect(references.references).toEqual([\n      {\n        fileName: expectedFileName,\n        name: 'T',\n      },\n    ]);\n  });\n\n  it('can dump interface with generic property', () => {\n    const result = compile(\n      `\n    export interface MyInterface {\n      value: GenericContainer<ReferenceInterface>;\n    }\n\n    interface GenericContainer<T> {\n      boxedValue: T\n    }\n\n    interface ReferenceInterface {\n\n    }\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(result.sourceFile, 0, (node) => ts.isInterfaceDeclaration(node));\n    expect(interfaceNode).toBeDefined();\n\n    const references: AST.TypeReferences = {\n      typeChecker: result.typeChecker,\n      references: [],\n    };\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, references);\n\n    const expectedOutput: AST.Interface = {\n      name: 'MyInterface',\n      start: expect.anything(),\n      end: expect.anything(),\n      members: [\n        {\n          name: 'value',\n          isOptional: false,\n          leadingComments: undefined,\n          start: expect.anything(),\n          end: expect.anything(),\n          type: {\n            name: 'reference',\n            typeReferenceIndex: 1,\n            isTypeParameter: false,\n            typeArguments: [\n              {\n                type: {\n                  name: 'reference',\n                  isTypeParameter: false,\n                  typeArguments: undefined,\n                  typeReferenceIndex: 0,\n                },\n              },\n            ],\n          },\n        },\n      ],\n      typeParameters: undefined,\n    };\n\n    expect(output).toEqual(expectedOutput);\n\n    const expectedFileName = '/File.ts';\n    expect(references.references).toEqual([\n      {\n        name: 'ReferenceInterface',\n        fileName: expectedFileName,\n      },\n      {\n        name: 'GenericContainer',\n        fileName: expectedFileName,\n      },\n    ]);\n  });\n\n  it('can dump interface with super type', () => {\n    const result = compile(\n      `\n    export interface Base {}\n    export interface Parent extends Base {}\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(\n      result.sourceFile,\n      undefined,\n      (node) => ts.isInterfaceDeclaration(node) && node.name.getText() === 'Parent',\n    );\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'Parent',\n      start: 29,\n      end: 68,\n      typeParameters: undefined,\n      members: [],\n      supertypes: [\n        {\n          end: 65,\n          isImplements: false,\n          start: 61,\n          type: {\n            isTypeParameter: false,\n            leadingComments: undefined,\n            name: 'reference',\n            typeArguments: undefined,\n            typeReferenceIndex: 0,\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can dump module', () => {\n    const result = compile(\n      `\n// @ExportModule\n\n export function function1(): void;\n export const VARIABLE_2: number;\n    `.trim(),\n    );\n\n    const dumpedNodes = dumpRootNodes(result.sourceFile, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    expect(dumpedNodes.length).toEqual(2);\n    expect(dumpedNodes[0].function?.name).toBe('function1');\n    expect(dumpedNodes[1].variable).toEqual({\n      start: 55,\n      end: 87,\n      name: 'VARIABLE_2',\n      type: {\n        name: 'number',\n      },\n    });\n  });\n\n  it('can dump interface with complex type references', () => {\n    const result = compile(\n      `\n    export interface ViewModelBase {\n      propA: boolean;\n    }\n    export type ViewModel = ViewModelBase & {\n      propB: string;\n    };\n\n    export interface Base<T> {}\n    export interface Parent extends Base<ViewModel> {}\n    `.trim(),\n    );\n\n    const interfaceNode = findNode(\n      result.sourceFile,\n      undefined,\n      (node) => ts.isInterfaceDeclaration(node) && node.name.getText() === 'Parent',\n    );\n    expect(interfaceNode).toBeDefined();\n\n    const output = dumpInterface(interfaceNode as ts.InterfaceDeclaration, {\n      typeChecker: result.typeChecker,\n      references: [],\n    });\n\n    const expectedOutput: AST.Interface = {\n      name: 'Parent',\n      start: 172,\n      end: 222,\n      typeParameters: undefined,\n      members: [],\n      supertypes: [\n        {\n          end: 219,\n          isImplements: false,\n          start: 204,\n          type: {\n            isTypeParameter: false,\n            leadingComments: undefined,\n            name: 'reference',\n            typeArguments: [\n              {\n                type: {\n                  name: 'intersection',\n                  leadingComments: undefined,\n                  intersections: [\n                    {\n                      isTypeParameter: false,\n                      leadingComments: undefined,\n                      name: 'reference',\n                      typeReferenceIndex: 0,\n                      typeArguments: undefined,\n                    },\n                    {\n                      name: 'reference',\n                      typeReferenceIndex: 1,\n                      isTypeParameter: false,\n                      leadingComments: undefined,\n                      typeArguments: undefined,\n                    },\n                  ],\n                },\n              },\n            ],\n            typeReferenceIndex: 2,\n          },\n        },\n      ],\n    };\n\n    expect(output).toEqual(expectedOutput);\n  });\n\n  it('can resolve import paths', () => {\n    const result = compile(\n      `\n      import resources from './res';\n      import { Number } from './Number';\n      import 'ts-jest';\n\n    `.trim(),\n    );\n\n    const imports = getImportStringLiteralsFromSourceFile(result.sourceFile)\n      .map((st) => st.text)\n      .sort();\n\n    expect(imports).toEqual(['./Number', './res', 'ts-jest']);\n  });\n\n  it('can detect non module files with ambiant declaration', () => {\n    let result = compile(`\n    import resources from './res';\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeFalsy();\n\n    result = compile(`\n    import resources from './res';\n\n    declare function myFn(): void {}\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeFalsy();\n\n    result = compile(`\n    import resources from './res';\n\n    declare module \"mod\" {\n      interface Test {}\n    }\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeTruthy();\n\n    result = compile(`\n    import resources from './res';\n\n    declare module \"mod\" {\n      interface Test {}\n    }\n\n    export const VALUE = 42;\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeTruthy();\n\n    result = compile(`\n    import resources from './res';\n\n    declare module \"mod\" {\n      interface Test {}\n    }\n\n    export { resources };\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeTruthy();\n\n    result = compile(`\n    import resources from './res';\n\n    declare module \"mod\" {\n      interface Test {}\n    }\n\n    export = resources;\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeTruthy();\n\n    result = compile(`\n    interface MyInterface {}\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeTruthy();\n\n    result = compile(`\n    export interface MyInterface {}\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeFalsy();\n\n    result = compile(`\n    declare namespace moment {}\n    export { moment };\n    `);\n\n    expect(isNonModuleWithAmbiantDeclarations(result.sourceFile)).toBeFalsy();\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/AST.ts",
    "content": "import * as ts from 'typescript';\nimport {\n  getNodeComments,\n  getNodeDebugDescription,\n  getRootNodesToDump,\n  isNodeExported,\n  NodeComments,\n  NodeToDump,\n} from './TSUtils';\n\nexport type ASTNodeKind = 'interface';\n\nexport namespace AST {\n  export interface Node {\n    start: number;\n    end: number;\n  }\n\n  export interface NamedNode extends Node {\n    name: string;\n  }\n\n  export interface Comments {\n    text: string;\n    start: number;\n    end: number;\n  }\n\n  export interface EnumMember extends NamedNode {\n    numberValue?: string;\n    stringValue?: string;\n    leadingComments?: Comments;\n  }\n\n  export interface Enum extends NamedNode {\n    members: EnumMember[];\n  }\n\n  export interface FunctionType {\n    parameters: PropertyLikeDeclaration[];\n    returnValue: Type;\n  }\n\n  export interface TypeArgument {\n    type: Type;\n  }\n\n  export interface Type {\n    name: string;\n    leadingComments?: Comments;\n    function?: FunctionType;\n    unions?: Type[];\n    intersections?: Type[];\n    typeReferenceIndex?: number;\n    array?: Type;\n    typeArguments?: TypeArgument[];\n    isTypeParameter?: boolean;\n  }\n\n  export interface SuperTypeClause extends Node {\n    isImplements: boolean;\n    type: Type;\n  }\n\n  export interface PropertyLikeDeclaration extends NamedNode {\n    isOptional: boolean;\n    type: Type;\n    leadingComments?: Comments;\n  }\n\n  export interface TypeParameterLikeDeclaration extends NamedNode {}\n\n  export interface Interface extends NamedNode {\n    members: PropertyLikeDeclaration[];\n    typeParameters?: TypeParameterLikeDeclaration[];\n    leadingComments?: Comments;\n    supertypes?: SuperTypeClause[];\n  }\n\n  export interface Function extends NamedNode {\n    type: FunctionType;\n    leadingComments?: Comments;\n  }\n\n  export interface Variable extends NamedNode {\n    type: Type;\n    leadingComments?: Comments;\n  }\n\n  export interface TypeReference {\n    name: string;\n    fileName: string;\n  }\n\n  export interface TypeReferences {\n    typeChecker: ts.TypeChecker;\n    references: TypeReference[];\n  }\n}\n\nfunction getIdentifierString(node: ts.Node): string {\n  return node.getText();\n}\n\nfunction parseFunctionType(node: ts.SignatureDeclarationBase, references: AST.TypeReferences): AST.FunctionType {\n  const parameters: AST.PropertyLikeDeclaration[] = [];\n\n  if (node.parameters) {\n    for (const parameter of node.parameters) {\n      const parameterName = getIdentifierString(parameter.name);\n      const parameterType = parseType(parameter.type, references);\n\n      parameters.push({\n        start: parameter.getStart(),\n        end: parameter.getEnd(),\n        isOptional: !!parameter.questionToken,\n        name: parameterName,\n        type: parameterType,\n      });\n    }\n  }\n\n  return {\n    returnValue: parseType(node.type, references),\n    parameters,\n  };\n}\n\ninterface ResolvedSymbol {\n  name: string;\n  sourceFile?: ts.SourceFile;\n  isTypeParameter: boolean;\n}\n\ninterface SymbolGroup {\n  symbol?: ResolvedSymbol;\n  unions?: SymbolGroup[];\n  intersections?: SymbolGroup[];\n}\n\nfunction makeResolvedSymbol(symbol: ts.Symbol, isTypeParameter: boolean = false): SymbolGroup {\n  return {\n    symbol: {\n      name: symbol.name,\n      sourceFile: symbol.declarations?.[0]?.getSourceFile(),\n      isTypeParameter,\n    },\n  };\n}\n\nfunction resolveSymbolFromTypeName(typeName: ts.Type, typeChecker: ts.TypeChecker): SymbolGroup | undefined {\n  // Weird TypeScript bug, if typeName.isTypeParameter() is in the `if ` expression, then the compiler\n  // seems to sometimes think this always evaluates to true, which is not correct.\n  const isTypeParameter = typeName.isTypeParameter() as any;\n  if (isTypeParameter) {\n    const symbol = typeName.getSymbol();\n    if (!symbol) {\n      return undefined;\n    }\n    return makeResolvedSymbol(symbol, true);\n  }\n\n  const typeNameSymbol = typeName.getSymbol();\n  if (typeNameSymbol && typeNameSymbol.valueDeclaration) {\n    if (ts.isEnumDeclaration(typeNameSymbol.valueDeclaration)) {\n      return makeResolvedSymbol(typeNameSymbol);\n    }\n\n    if (ts.isEnumMember(typeNameSymbol.valueDeclaration)) {\n      // Hack to expose the enum values as enum types\n      const enumDeclaration = typeNameSymbol.valueDeclaration.parent;\n\n      return {\n        symbol: {\n          name: getIdentifierString(enumDeclaration.name),\n          sourceFile: enumDeclaration.getSourceFile(),\n          isTypeParameter: false,\n        },\n      };\n    }\n  }\n\n  if (typeName.isUnion()) {\n    const unions: SymbolGroup[] = [];\n    for (const t of typeName.types) {\n      const resolvedSymbol = resolveSymbolFromTypeName(t, typeChecker);\n      if (!resolvedSymbol) {\n        return undefined;\n      }\n      unions.push(resolvedSymbol);\n    }\n    return {\n      unions,\n    };\n  }\n\n  if (typeName.isIntersection()) {\n    const intersections: SymbolGroup[] = [];\n    for (const t of typeName.types) {\n      const resolvedSymbol = resolveSymbolFromTypeName(t, typeChecker);\n      if (!resolvedSymbol) {\n        return undefined;\n      }\n      intersections.push(resolvedSymbol);\n    }\n    return {\n      intersections,\n    };\n  }\n\n  const resolvedType = typeChecker.getApparentType(typeName);\n  const symbol = resolvedType.getSymbol();\n  if (!symbol) {\n    return undefined;\n  }\n  return makeResolvedSymbol(symbol);\n}\n\nfunction resolveSymbol(type: ts.TypeNode, typeChecker: ts.TypeChecker): SymbolGroup | undefined {\n  const typeName = typeChecker.getTypeAtLocation(type);\n  return resolveSymbolFromTypeName(typeName, typeChecker);\n}\n\nfunction resolveTypeReference(\n  type: ts.NodeWithTypeArguments,\n  resolvedSymbol: ResolvedSymbol,\n  references: AST.TypeReferences,\n): number {\n  if (!resolvedSymbol.sourceFile) {\n    throw new Error(`No declarations for resolve symbol ${getNodeDebugDescription(type)}`);\n  }\n\n  const symbolName = resolvedSymbol.name;\n  const sourceFile = resolvedSymbol.sourceFile;\n  const sourceFileLocation = sourceFile.fileName;\n\n  const typeReferences = references.references;\n\n  for (let i = 0; i < typeReferences.length; i++) {\n    const existingReference = typeReferences[i];\n    if (existingReference.name === symbolName && existingReference.fileName === sourceFileLocation) {\n      return i;\n    }\n  }\n\n  const index = typeReferences.length;\n  typeReferences.push({ name: symbolName, fileName: sourceFileLocation });\n\n  return index;\n}\n\nfunction parseTypeFromSymbolGroup(\n  type: ts.NodeWithTypeArguments,\n  symbolGroup: SymbolGroup,\n  leadingComments: NodeComments | undefined,\n  references: AST.TypeReferences,\n): AST.Type {\n  if (symbolGroup.symbol) {\n    const resolvedSymbol = symbolGroup.symbol;\n    if (resolvedSymbol.name === 'Array') {\n      if (!type.typeArguments || type.typeArguments.length !== 1) {\n        throw new Error(\n          `Resolved a generic Array reference with invalid type arguments ${getNodeDebugDescription(type)}`,\n        );\n      }\n\n      const elementTypeNode = type.typeArguments[0];\n      const elementType = parseType(elementTypeNode, references);\n      return { name: 'array', leadingComments, array: elementType };\n    }\n\n    const typeArguments = type.typeArguments?.map((typeArgTypeNode) => {\n      const parsedType = parseType(typeArgTypeNode, references);\n      return { type: parsedType };\n    });\n\n    const typeReferenceIndex = resolveTypeReference(type, resolvedSymbol, references);\n    return {\n      name: 'reference',\n      leadingComments,\n      typeReferenceIndex,\n      typeArguments,\n      isTypeParameter: resolvedSymbol.isTypeParameter,\n    };\n  }\n\n  if (symbolGroup.intersections) {\n    return {\n      name: 'intersection',\n      leadingComments,\n      intersections: symbolGroup.intersections.map((u) => parseTypeFromSymbolGroup(type, u, undefined, references)),\n    };\n  }\n\n  if (symbolGroup.unions) {\n    return {\n      name: 'union',\n      leadingComments,\n      unions: symbolGroup.unions.map((u) => parseTypeFromSymbolGroup(type, u, undefined, references)),\n    };\n  }\n\n  throw new Error('Invalid symbolGroup');\n}\n\nfunction parseType(type: ts.TypeNode | undefined, references: AST.TypeReferences): AST.Type {\n  if (!type) {\n    return {\n      name: 'void',\n    };\n  }\n\n  const leadingComments = getNodeComments(type);\n\n  if (ts.isFunctionTypeNode(type)) {\n    return {\n      name: 'function',\n      leadingComments,\n      function: parseFunctionType(type, references),\n    };\n  }\n\n  if (ts.isUnionTypeNode(type)) {\n    const unions: AST.Type[] = [];\n    for (const unionType of type.types) {\n      unions.push(parseType(unionType, references));\n    }\n\n    return {\n      name: 'union',\n      leadingComments,\n      unions,\n    };\n  }\n\n  if (ts.isIntersectionTypeNode(type)) {\n    const intersections: AST.Type[] = [];\n    for (const unionType of type.types) {\n      intersections.push(parseType(unionType, references));\n    }\n\n    return {\n      name: 'intersection',\n      leadingComments,\n      intersections,\n    };\n  }\n\n  if (ts.isArrayTypeNode(type)) {\n    return {\n      name: 'array',\n      leadingComments,\n      array: parseType(type.elementType, references),\n    };\n  }\n\n  if (ts.isTypeReferenceNode(type) || ts.isExpressionWithTypeArguments(type)) {\n    const resolvedSymbol = resolveSymbol(type, references.typeChecker);\n    if (!resolvedSymbol) {\n      throw new Error(`Could not resolve symbol ${getNodeDebugDescription(type)}`);\n    }\n\n    return parseTypeFromSymbolGroup(type, resolvedSymbol, leadingComments, references);\n  }\n\n  if (ts.isParenthesizedTypeNode(type)) {\n    return parseType(type.type, references);\n  }\n\n  if (ts.isTypeLiteralNode(type)) {\n    // TODO(simon): Provide members. Not yet needed today\n    return {\n      name: 'literal',\n    };\n  }\n\n  switch (type.kind) {\n    case ts.SyntaxKind.StringKeyword:\n      return { name: 'string' };\n    case ts.SyntaxKind.NumberKeyword:\n      return { name: 'number' };\n    case ts.SyntaxKind.BooleanKeyword:\n      return { name: 'boolean' };\n    case ts.SyntaxKind.VoidKeyword:\n      return { name: 'void' };\n    case ts.SyntaxKind.UndefinedKeyword:\n      return { name: 'undefined' };\n    case ts.SyntaxKind.NullKeyword:\n      return { name: 'null' };\n    case ts.SyntaxKind.AnyKeyword:\n      return { name: 'any' };\n    case ts.SyntaxKind.ObjectKeyword:\n      return { name: 'object' };\n    case ts.SyntaxKind.LiteralType:\n      if (type.getText() === 'null') {\n        return { name: 'null' };\n      }\n    case ts.SyntaxKind.ThisType:\n    case ts.SyntaxKind.UnknownKeyword:\n      return { name: 'any' };\n    default:\n      throw new Error(`Could not resolve type ${getNodeDebugDescription(type)}`);\n  }\n}\n\nfunction parsePropertyLike(\n  node: ts.TypeElement | ts.ClassElement,\n  references: AST.TypeReferences,\n): AST.PropertyLikeDeclaration {\n  const memberName = node.name && getIdentifierString(node.name);\n  const isOptional = !!(node as ts.TypeElement)?.questionToken;\n\n  let type: AST.Type;\n\n  if (ts.isPropertySignature(node) || ts.isPropertyDeclaration(node)) {\n    type = parseType(node.type, references);\n  } else if (\n    ts.isMethodSignature(node) ||\n    ts.isMethodDeclaration(node) ||\n    ts.isGetAccessor(node) ||\n    ts.isGetAccessorDeclaration(node)\n  ) {\n    const functionType = parseFunctionType(node, references);\n    type = {\n      name: 'function',\n      function: functionType,\n    };\n  } else {\n    throw new Error(`Could not resolve kind ${getNodeDebugDescription(node)}`);\n  }\n\n  const result: AST.PropertyLikeDeclaration = {\n    start: node.getStart(),\n    end: node.getEnd(),\n    isOptional,\n    name: memberName ?? '',\n    type,\n    leadingComments: getNodeComments(node),\n  };\n\n  return result;\n}\n\nexport interface DumpedRootNode {\n  nodeType: 'enum' | 'function' | 'interface' | 'variable' | 'exportedTypeAlias';\n  start: number;\n  leadingComments: AST.Comments | undefined;\n  text: string;\n  kind: ts.SyntaxKind;\n  modifiers: string[] | undefined;\n  function?: AST.Function;\n  enum?: AST.Enum;\n  interface?: AST.Interface;\n  variable?: AST.Variable;\n  exportedTypeAlias?: string;\n}\n\nfunction isExportedSymbolOrHasAnnotation(nodeToDump: NodeToDump, shouldDumpAllExportedSymbols: boolean): boolean {\n  if (shouldDumpAllExportedSymbols && isNodeExported(nodeToDump.node)) {\n    return true;\n  }\n\n  // Otherwise, only interested in symbols annotated with Valdi annotations\n  if (!nodeToDump.leadingComments) {\n    return false;\n  }\n  const comments = nodeToDump.leadingComments.text;\n  const hasMatch = !!comments.match(/@Generate|@Export|@Component|@ViewModel|@Context|@Native/g);\n\n  return hasMatch;\n}\n\nfunction hasExportModuleAnnotation(nodeToDump: NodeToDump): boolean {\n  if (!nodeToDump.leadingComments) {\n    return false;\n  }\n\n  return !!nodeToDump.leadingComments.text.match(/@ExportModule/g);\n}\n\nfunction shouldDumpNodeMember(nodeToDump: NodeToDump, memberNode: ts.TypeElement | ts.ClassElement): boolean {\n  const nodeComments = nodeToDump.leadingComments?.text;\n  if (!nodeComments) {\n    return false;\n  }\n\n  if (nodeComments.match(/@NativeTemplateElement/)) {\n    return false;\n  } else if (nodeComments.match(/@Component/)) {\n    return !!(getNodeComments(memberNode)?.text ?? '').match(/@Action|@ConstructorOmitted/g);\n  } else if (nodeComments.match(/@Generate|@Export/)) {\n    return true;\n  } else {\n    return false;\n  }\n}\n\nexport function getImportStringLiteralsFromSourceFile(sourceFile: ts.SourceFile): ts.StringLiteral[] {\n  const output: ts.StringLiteral[] = [];\n  for (const statement of sourceFile.statements) {\n    if (ts.isImportDeclaration(statement)) {\n      const importDeclaration: ts.ImportDeclaration = statement;\n      if (ts.isStringLiteral(importDeclaration.moduleSpecifier)) {\n        output.push(importDeclaration.moduleSpecifier);\n      }\n    }\n  }\n  return output;\n}\n\nfunction isGlobalScopeAugmentation(module: ts.ModuleDeclaration): boolean {\n  return !!(module.flags & ts.NodeFlags.GlobalAugmentation);\n}\n\nfunction containsGlobalScopeAugmentation(sourceFile: ts.SourceFile): boolean {\n  // Taken from the TS compiler source code\n  const moduleAugmentations: (ts.StringLiteral | ts.Identifier)[] = (sourceFile as any).moduleAugmentations;\n  if (!moduleAugmentations) {\n    return false;\n  }\n  for (const augmentation of moduleAugmentations) {\n    if (isGlobalScopeAugmentation(augmentation.parent as ts.ModuleDeclaration)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\nfunction isExternalOrCommonJsModule(file: ts.SourceFile): boolean {\n  return ((file as any).externalModuleIndicator || (file as any).commonJsModuleIndicator) !== undefined;\n}\n\nfunction isJsonSourceFile(file: ts.SourceFile): boolean {\n  return (file as any).scriptKind === ts.ScriptKind.JSON;\n}\n\nfunction isModuleWithStringLiteralName(node: ts.Node): node is ts.ModuleDeclaration {\n  return ts.isModuleDeclaration(node) && node.name.kind === ts.SyntaxKind.StringLiteral;\n}\n\nfunction containsOnlyAmbientModules(sourceFile: ts.SourceFile): boolean {\n  for (const statement of sourceFile.statements) {\n    if (!isModuleWithStringLiteralName(statement)) {\n      return false;\n    }\n  }\n  return true;\n}\n\nfunction isFileAffectingGlobalScope(sourceFile: ts.SourceFile): boolean {\n  return (\n    containsGlobalScopeAugmentation(sourceFile) ||\n    (!isExternalOrCommonJsModule(sourceFile) &&\n      !isJsonSourceFile(sourceFile) &&\n      !containsOnlyAmbientModules(sourceFile))\n  );\n}\n\nexport function isNonModuleWithAmbiantDeclarations(sourceFile: ts.SourceFile): boolean {\n  const statements = sourceFile.statements;\n\n  if (!statements.length) {\n    return false;\n  }\n\n  let hasAmbiantModuleDeclarations = false;\n  let hasImport = false;\n  let hasExports = false;\n\n  for (const statement of statements) {\n    const modifiers = ts.getCombinedModifierFlags(statement as unknown as ts.Declaration);\n    const isAmbiant = (modifiers & ts.ModifierFlags.Ambient) != 0;\n    const isExports = (modifiers & ts.ModifierFlags.Export) !== 0;\n\n    if (isAmbiant) {\n      if (ts.isModuleDeclaration(statement) && ts.isStringLiteral(statement.name)) {\n        hasAmbiantModuleDeclarations = true;\n      }\n    }\n    if (isExports) {\n      hasExports = true;\n    }\n\n    if (ts.isExportDeclaration(statement) || ts.isExportAssignment(statement)) {\n      hasExports = true;\n    }\n\n    if (ts.isImportDeclaration(statement) || ts.isImportEqualsDeclaration(statement)) {\n      hasImport = true;\n    }\n  }\n\n  return hasAmbiantModuleDeclarations || (!hasImport && !hasExports);\n}\n\nexport function dumpRootNodes(sourceFile: ts.SourceFile, astReferences: AST.TypeReferences): DumpedRootNode[] {\n  const rootNodes = getRootNodesToDump(sourceFile, undefined);\n  const nodesToDump: NodeToDump[] = [];\n\n  if (rootNodes.length) {\n    // Need to dump all exported symbols for .vue user scripts, or for modules\n    // annotated with @ExportModule\n    const shouldDumpAllExportedSymbols =\n      !!sourceFile.fileName.match(/\\.vue\\.ts(x)?$/g) || hasExportModuleAnnotation(rootNodes[0]);\n    for (const rootNode of rootNodes) {\n      if (isExportedSymbolOrHasAnnotation(rootNode, shouldDumpAllExportedSymbols)) {\n        nodesToDump.push(rootNode);\n      }\n    }\n  }\n\n  const dumpedNodes: DumpedRootNode[] = [];\n\n  for (const nodeToDump of nodesToDump) {\n    const node = nodeToDump.node;\n    const kind = nodeToDump.node.kind;\n    const modifiers = ts.canHaveModifiers(nodeToDump.node)\n      ? nodeToDump.node.modifiers?.map((modifier) => modifier.getText())\n      : undefined;\n\n    const common = {\n      start: nodeToDump.node.getStart(),\n      leadingComments: nodeToDump.leadingComments,\n      kind,\n      modifiers,\n    };\n\n    let result: DumpedRootNode;\n\n    if (ts.isEnumDeclaration(node)) {\n      const dumpedEnum = dumpEnum(node);\n      result = {\n        ...common,\n        nodeType: 'enum',\n        text: dumpedEnum.name,\n        enum: dumpedEnum,\n      };\n    } else if (ts.isFunctionDeclaration(node)) {\n      const dumpedFunction = dumpFunction(node, astReferences);\n      result = {\n        ...common,\n        nodeType: 'function',\n        text: dumpedFunction.name,\n        function: dumpedFunction,\n      };\n    } else if (ts.isInterfaceDeclaration(node) || ts.isClassDeclaration(node)) {\n      const coercedNode = nodeToDump.node as ts.InterfaceDeclaration | ts.ClassDeclaration;\n      const dumpedInterface = dumpInterface(coercedNode, astReferences, (memberNode) =>\n        shouldDumpNodeMember(nodeToDump, memberNode),\n      );\n      if (!dumpedInterface) {\n        continue;\n      }\n\n      result = {\n        ...common,\n        nodeType: 'interface',\n        text: dumpedInterface.name,\n        interface: dumpedInterface,\n      };\n    } else if (ts.isVariableStatement(node)) {\n      if (!modifiers?.includes('export')) {\n        continue;\n      }\n      const exportedVariable = dumpVariable(node, astReferences);\n      result = {\n        ...common,\n        nodeType: 'variable',\n        text: exportedVariable.name,\n        variable: exportedVariable,\n      };\n    } else if (ts.isTypeAliasDeclaration(node)) {\n      if (!modifiers?.includes('export')) {\n        continue;\n      }\n      const exportedVariableName = node.name.getText();\n      result = {\n        ...common,\n        nodeType: 'exportedTypeAlias',\n        text: exportedVariableName,\n        exportedTypeAlias: exportedVariableName,\n      };\n    } else {\n      continue;\n    }\n\n    dumpedNodes.push(result);\n  }\n\n  return dumpedNodes.filter((node) => {\n    // should have either interface, function, or enum\n    return (node.interface || node.function || node.enum || node.variable || node.exportedTypeAlias) && node.kind;\n  });\n}\n\nexport function dumpInterface(\n  node: ts.InterfaceDeclaration | ts.ClassDeclaration,\n  references: AST.TypeReferences,\n  dumpMemberPredicate: (memberNode: ts.TypeElement | ts.ClassElement) => boolean = () => true,\n): AST.Interface | undefined {\n  if (!node.name) {\n    return undefined;\n  }\n\n  const name = getIdentifierString(node.name);\n\n  const members: AST.PropertyLikeDeclaration[] = [];\n\n  const typeParameters = node.typeParameters?.map((tsTypeParam) => {\n    return {\n      start: node.getStart(),\n      end: node.getEnd(),\n      name: getIdentifierString(tsTypeParam.name),\n    };\n  });\n\n  for (const member of node.members) {\n    if (!member.name) {\n      continue;\n    }\n\n    if (!dumpMemberPredicate(member)) {\n      continue;\n    }\n\n    const propertyLike = parsePropertyLike(member, references);\n    members.push(propertyLike);\n  }\n\n  const result: AST.Interface = {\n    start: node.getStart(),\n    end: node.getEnd(),\n    name,\n    members,\n    typeParameters,\n  };\n\n  if (node.heritageClauses?.length) {\n    const supertypes: AST.SuperTypeClause[] = [];\n    for (const heritageClause of node.heritageClauses) {\n      for (const type of heritageClause.types) {\n        const outputType = parseType(type, references);\n\n        supertypes.push({\n          start: type.getStart(),\n          end: type.getEnd(),\n          isImplements: heritageClause.token === ts.SyntaxKind.ImplementsKeyword,\n          type: outputType,\n        });\n      }\n    }\n\n    result.supertypes = supertypes;\n  }\n\n  const leadingComments = getNodeComments(node);\n  if (leadingComments) {\n    result.leadingComments = leadingComments;\n  }\n\n  return result;\n}\n\nexport function dumpFunction(node: ts.FunctionDeclaration, references: AST.TypeReferences): AST.Function {\n  const functionType = parseFunctionType(node, references);\n\n  return {\n    start: node.getStart(),\n    end: node.getEnd(),\n    name: (node.name && getIdentifierString(node.name)) ?? '',\n    type: functionType,\n    leadingComments: getNodeComments(node),\n  };\n}\n\nexport function dumpVariable(node: ts.VariableStatement, references: AST.TypeReferences): AST.Variable {\n  if (node.declarationList.declarations.length !== 1) {\n    throw new Error('Only declaration of single variables are currently supported');\n  }\n\n  const declaration = node.declarationList.declarations[0];\n  return {\n    start: node.getStart(),\n    end: node.getEnd(),\n    name: getIdentifierString(declaration.name),\n    type: parseType(declaration.type, references),\n    leadingComments: getNodeComments(node),\n  };\n}\n\nexport function dumpEnum(node: ts.EnumDeclaration): AST.Enum {\n  const members: AST.EnumMember[] = [];\n\n  for (const member of node.members) {\n    const memberComments = getNodeComments(member);\n    const enumMember: AST.EnumMember = {\n      start: member.getStart(),\n      end: member.getEnd(),\n      name: getIdentifierString(member.name),\n    };\n\n    if (memberComments) {\n      enumMember.leadingComments = memberComments;\n    }\n\n    if (member.initializer) {\n      if (ts.isNumericLiteral(member.initializer)) {\n        enumMember.numberValue = member.initializer.text;\n      } else if (ts.isStringLiteralLike(member.initializer)) {\n        enumMember.stringValue = member.initializer.text;\n      }\n    }\n\n    members.push(enumMember);\n  }\n\n  return {\n    start: node.getStart(),\n    end: node.getEnd(),\n    name: getIdentifierString(node.name),\n    members: members,\n  };\n}\n"
  },
  {
    "path": "compiler/companion/src/BatchMinifier.ts",
    "content": "import * as fs from 'fs';\n\nif (typeof btoa !== 'undefined') {\n  // Replace btoa function before loading terser as it is broken on node js v16\n  global.btoa = function btoa(str: string): string {\n    return Buffer.from(str).toString('base64');\n  };\n}\n\nimport * as terser from 'terser';\nimport * as _url from 'url';\n\nexport interface BatchMinifyResult {\n  fileURL: string;\n  uglified?: string;\n  error?: string;\n}\n\nexport type CommonMinifyOptions = terser.MinifyOptions;\n\ninterface MinifyOutput {\n  code?: string;\n  error?: Error;\n}\n\nconst defaultOptions: CommonMinifyOptions = {\n  ecma: 6,\n  safari10: true,\n  mangle: {\n    toplevel: true,\n    keep_classnames: true,\n  },\n};\n\nexport const batchMinify = (minifierName: 'terser', fileURLs: string[], providedOptions?: CommonMinifyOptions) => {\n  let minifier: Minifier<CommonMinifyOptions>;\n  switch (minifierName) {\n    case 'terser':\n      minifier = terser;\n      break;\n    default:\n      throw new Error('Unknown minifier');\n  }\n\n  const options = providedOptions ?? defaultOptions;\n  return doBatchMinify(minifier, fileURLs, options);\n};\n\ninterface Minifier<MinifyOptionsT> {\n  minify(\n    files:\n      | string\n      | string[]\n      | {\n          [file: string]: string;\n        },\n    options?: MinifyOptionsT | undefined,\n  ): MinifyOutput;\n}\n\nfunction deepCopy(obj: any): any {\n  if (typeof obj !== 'object') {\n    return obj;\n  }\n\n  if (Array.isArray(obj)) {\n    return obj.map(deepCopy);\n  } else {\n    const out: any = {};\n\n    for (const key in obj) {\n      out[key] = deepCopy(obj[key]);\n    }\n\n    return out;\n  }\n}\n\nconst doBatchMinify = <MinifyOptionsT>(\n  minifier: Minifier<MinifyOptionsT>,\n  fileURLs: string[],\n  options: MinifyOptionsT | undefined,\n): Promise<BatchMinifyResult[]> => {\n  const promises = fileURLs.map((fileURL) => {\n    const promise = new Promise((resolve: (value: BatchMinifyResult) => void, reject) => {\n      const path = _url.fileURLToPath(fileURL);\n      fs.readFile(path, (err, buffer) => {\n        if (err) {\n          resolve({ fileURL, error: err.toString() });\n          return;\n        }\n\n        const original = buffer.toString();\n\n        // terser sometimes modifies the input options, this makes sure\n        // we give a unique options instance each time.\n        const minifyOptions = deepCopy(options);\n        const result = minifier.minify(original, minifyOptions);\n\n        if (result.error) {\n          resolve({ fileURL, error: result.error.toString() });\n          return;\n        }\n\n        const uglified = result.code;\n\n        resolve({ fileURL, uglified });\n      });\n    });\n    return promise;\n  });\n  return Promise.all(promises);\n};\n"
  },
  {
    "path": "compiler/companion/src/CodeInstrumentation.ts",
    "content": "import { createInstrumenter, Instrumenter, InstrumenterOptions } from 'istanbul-lib-instrument';\nimport { getRawSourceMap, SOURCE_MAP_PREFIX } from './SourceMapUtils';\nimport { RawSourceMap } from 'source-map';\nimport { fromObject } from 'convert-source-map';\nimport { AddCodeInstrumentationResponseBody } from './protocol';\n\nexport interface CodeInstrumentationFileConfig {\n  sourceFilePath: string;\n  fileContent: string;\n}\n\nexport interface CodeInstrumentationResult {\n  sourceFilePath: string;\n  instrumentedFileContent: string | undefined;\n  fileCoverage: string | undefined;\n}\n\n// CodeInstrumentation Class is responsible for adding the code instrumentation for the picked files from compiler\n// Under that it uses istanbul-lib-instrument lib which adds the actual code instrumentation to the file\n// design doc: https://docs.google.com/document/d/1YiwyxQfKgL_h5KGn4NPcePX8zCQeS1HXF14a-47Tk98\nexport class CodeInstrumentation {\n  private static instance: CodeInstrumentation;\n  private readonly instrumenter: Instrumenter;\n\n  private constructor() {\n    this.instrumenter = createInstrumenter({\n      ignoreClassMethods: undefined,\n      autoWrap: false,\n      esModules: true,\n      parserPlugins: [\n        'asyncGenerators',\n        'bigInt',\n        'classProperties',\n        'classPrivateProperties',\n        'classPrivateMethods',\n        'dynamicImport',\n        'importMeta',\n        'numericSeparator',\n        'objectRestSpread',\n        'optionalCatchBinding',\n        'topLevelAwait',\n        'typescript',\n        'jsx',\n      ],\n      compact: true,\n      preserveComments: true,\n      produceSourceMap: true,\n    } as Partial<InstrumenterOptions>);\n  }\n\n  public static getInstance(): CodeInstrumentation {\n    if (!CodeInstrumentation.instance) {\n      CodeInstrumentation.instance = new CodeInstrumentation();\n    }\n\n    return CodeInstrumentation.instance;\n  }\n\n  public instrumentFiles(files: [CodeInstrumentationFileConfig]): AddCodeInstrumentationResponseBody {\n    const codeInstrumentationExecution = files.map((file) => this.instrumentFile(file));\n\n    return { results: codeInstrumentationExecution };\n  }\n\n  public instrumentFile(file: CodeInstrumentationFileConfig): CodeInstrumentationResult {\n    let data = file.fileContent;\n    const sourceMap = getRawSourceMap(data);\n\n    if (data.includes(SOURCE_MAP_PREFIX)) {\n      data = data.split(SOURCE_MAP_PREFIX)[0];\n    }\n\n    let rawSourceMap: Partial<RawSourceMap> | undefined = undefined;\n\n    if (sourceMap?.mappings) {\n      rawSourceMap = {\n        version: 3,\n        sources: [file.sourceFilePath],\n        mappings: sourceMap.mappings,\n      };\n    }\n\n    let instrumented = this.instrumenter.instrumentSync(data, file.sourceFilePath, rawSourceMap as any);\n    let lastSourceMap = this.instrumenter.lastSourceMap();\n    let lastFileCoverage = this.instrumenter.lastFileCoverage();\n\n    if (lastSourceMap) {\n      instrumented += '\\n' + fromObject(lastSourceMap).toComment();\n    }\n\n    let fileCoverage: string | undefined;\n    if (lastFileCoverage) {\n      fileCoverage = JSON.stringify(lastFileCoverage);\n    }\n\n    return { sourceFilePath: file.sourceFilePath, instrumentedFileContent: instrumented, fileCoverage };\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/CompanionServiceBase.ts",
    "content": "import { createInterface } from 'readline';\nimport { Command, Request, RequestBody, ResponseBody } from './protocol';\nimport { ZombieKiller } from './ZombieKiller';\nimport { ILogger } from './logger/ILogger';\nimport { StreamLogger } from './logger/StreamLogger';\nimport { getArgumentValue } from './utils/getArgumentValue';\nimport { sendError, sendResponse } from './utils/companionTransport';\nimport { ProtocolLogger } from './logger/ProtocolLogger';\n\n// MARK: - Exit handling\n\nexport const enum ExitKind {\n  GRACEFUL,\n  UNGRACEFUL,\n}\n\nexport class CompanionServiceBase {\n  private zombieKiller: ZombieKiller | undefined;\n  private requestHandlerByCommandName: { [name: string]: (body: any) => Promise<ResponseBody> } = {};\n\n  protected logger: ILogger;\n\n  constructor(readonly options: Set<string>) {\n    if (options.has('--log-output')) {\n      this.logger = StreamLogger.forOutputFile(getArgumentValue('--log-output'));\n    } else if (options.has('--log-to-stderr')) {\n      this.logger = StreamLogger.forStderr();\n    } else if (options.has('--command')) {\n      this.logger = StreamLogger.forStdOut();\n    } else {\n      this.logger = new ProtocolLogger();\n    }\n  }\n\n  addEndpoint<Request, Response extends ResponseBody>(\n    name: string,\n    callback: (body: Request) => Promise<Response>,\n  ): void {\n    this.requestHandlerByCommandName[name] = callback;\n  }\n\n  start(): void {\n    this.setupSignals();\n\n    if (this.options.has('--command')) {\n      const commandType = getArgumentValue('--command');\n\n      if (!this.options.has('--body')) {\n        throw new Error('--body should be provided when passing --command');\n      }\n\n      const bodyJson = getArgumentValue('--body');\n\n      const body = JSON.parse(bodyJson);\n      this.processCommand(commandType as Command, body as RequestBody).then((output) => {\n        console.log(JSON.stringify(output, undefined, 2));\n      });\n    } else {\n      this.logger.info?.('Started Compiler Companion');\n      console.error('Node version:', process.version);\n      this.zombieKiller = new ZombieKiller(() => {\n        this.handleExit(ExitKind.UNGRACEFUL);\n      });\n      this.zombieKiller.start();\n\n      const it = createInterface({\n        input: process.stdin,\n        output: process.stdout,\n        terminal: false,\n      });\n\n      it.on('line', (line: string) => this.processLine(line));\n      it.on('close', () => {\n        console.error('Main interface close...');\n        this.handleExit(ExitKind.GRACEFUL);\n      });\n    }\n  }\n\n  private async processCommand(command: string, body: RequestBody): Promise<ResponseBody> {\n    const handler = this.requestHandlerByCommandName[command];\n    if (!handler) {\n      throw Error(`Unrecognized command '${command}'`);\n    }\n\n    return await handler(body);\n  }\n\n  private async processLine(l: string): Promise<void> {\n    let requestId: string | undefined;\n    try {\n      const request: Request = JSON.parse(l);\n\n      requestId = request.id;\n      if (!requestId) {\n        throw Error('Missing request id');\n      }\n\n      const response = await this.processCommand(request.command, request.body);\n\n      sendResponse(requestId, response);\n    } catch (err: any) {\n      if (requestId) {\n        this.logger.error?.(err);\n        sendError(requestId, err);\n      } else {\n        console.error(`Unmatched error: ${err.message}`);\n      }\n    }\n  }\n\n  protected handleExit(exitKind: ExitKind): void {\n    switch (exitKind) {\n      case ExitKind.GRACEFUL:\n        process.exitCode = 0;\n      case ExitKind.UNGRACEFUL:\n        process.exitCode = 1;\n    }\n\n    this.zombieKiller?.stop();\n    process.stdin.unref();\n  }\n\n  private setupSignals(): void {\n    const handleExitSignal = (signal: NodeJS.Signals, exitKind: ExitKind) => {\n      console.error(`Companion received signal ${signal}, dying...`);\n      this.handleExit(exitKind);\n    };\n\n    process.on('SIGINT', (signal) => {\n      handleExitSignal(signal, ExitKind.UNGRACEFUL);\n    });\n\n    process.on('SIGTERM', (signal) => {\n      handleExitSignal(signal, ExitKind.GRACEFUL);\n    });\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/CompilerCompanion.ts",
    "content": "import { batchMinify, CommonMinifyOptions } from './BatchMinifier';\nimport {\n  AddCodeInstrumentationRequestBody,\n  BatchMinifyJSRequestBody,\n  Command,\n  CompileNativeRequestBody,\n  DumpEnumRequestBody,\n  DumpFunctionRequestBody,\n  DumpInterfaceRequestBody,\n  DumpSymbolsWithCommentsRequestBody,\n  EmitFileRequestBody,\n  EmitFileResponseBody,\n  EmittedFile,\n  ExportStringsFilesBatchRequestBody,\n  ExportStringsFilesBatchResponseBody,\n  ExportStringsFilesRequestBody,\n  ExportTranslationStringsRequestBody,\n  ExportStringsFilesResponseBody,\n  GenerateGhostOwnershipMapRequestBody,\n  GenerateIdsFilesRequestBody,\n  GenerateIdsFilesResponseBody,\n  GetDiagnosticsRequestBody,\n  GetDiagnosticsResponseBody,\n  InitializeWorkspaceRequestBody,\n  OpenFileRequestBody,\n  RegisterFileRequestBody,\n  RewriteImportsRequestBody,\n  RewriteImportsResponseBody,\n  StartDebuggingProxyResponseBody,\n  UpdatedAndroidTargetsRequestBody,\n  UpdatedDebuggerPorts,\n  CreateWorkspaceRequestBody,\n  CreateWorkspaceResponseBody,\n  DestroyWorkspaceRequestBody,\n  DestroyWorkspaceResponseBody,\n  BatchMinifyJSResponseBody,\n  InitializeWorkspaceResponseBody,\n  RegisterFileResponseBody,\n  OpenFileResponseBody,\n  AddCodeInstrumentationResponseBody,\n  UpdatedAndroidTargetsResponseBody,\n  DumpSymbolsWithCommentsResponseBody,\n  DumpInterfaceResponseBody,\n  DumpEnumResponseBody,\n  DumpFunctionResponseBody,\n  ExportTranslationStringsResponseBody,\n  StartDebuggingProxyRequestBody,\n  CompileNativeResponseBody,\n  GenerateGhostOwnershipMapResponseBody,\n} from './protocol';\nimport { DebuggingProxy } from './DebuggingProxy';\nimport { generateIdsFromPath } from './GenerateIds';\nimport { exportStringsFiles, exportTranslationStrings } from './strings/exportStringsFiles';\nimport { getArgumentValue } from './utils/getArgumentValue';\nimport { compileNative } from './native/CompileNativeCommand';\nimport { CodeInstrumentation } from './CodeInstrumentation';\nimport { generateGhostOwnershipMap } from './cli/generateGhostOwnershipMap';\nimport { rewriteImports } from './cli/rewriteImports';\nimport { WorkspaceStore } from './WorkspaceStore';\nimport { CompanionServiceBase, ExitKind } from './CompanionServiceBase';\n\nexport class CompilerCompanion extends CompanionServiceBase {\n  private workspaceStore: WorkspaceStore;\n  private debuggingProxy: DebuggingProxy;\n\n  constructor(options: Set<string>) {\n    super(options);\n    let shouldDebounceOpenFile = true;\n    if (options.has('--command')) {\n      shouldDebounceOpenFile = false;\n    }\n\n    this.debuggingProxy = new DebuggingProxy(this.logger);\n\n    let cacheDir: string | undefined;\n    if (options.has('--cache-dir')) {\n      cacheDir = getArgumentValue('--cache-dir');\n    }\n\n    this.workspaceStore = new WorkspaceStore(this.logger, cacheDir, shouldDebounceOpenFile);\n\n    this.addBaseEndpoints();\n  }\n\n  private addBaseEndpoints(): void {\n    this.addEndpoint<BatchMinifyJSRequestBody, BatchMinifyJSResponseBody>(Command.batchMinifyJS, async (body) => {\n      const inputFiles: string[] = body.inputFiles;\n      if (!inputFiles) {\n        throw Error('Missing inputFiles in request');\n      }\n\n      let options: CommonMinifyOptions;\n      try {\n        options = JSON.parse(body.options);\n      } catch (err) {\n        throw Error(`Error while parsing minifying options: ${err}`);\n      }\n\n      try {\n        const batchMinifyResults = await batchMinify(body.minifier, inputFiles, options);\n        return { results: batchMinifyResults };\n      } catch (err) {\n        throw Error(`Error while minifying: ${err}`);\n      }\n    });\n\n    this.addEndpoint<CreateWorkspaceRequestBody, CreateWorkspaceResponseBody>(Command.createWorkspace, async (body) => {\n      const workspaceId = this.workspaceStore.createWorkspace().workspaceId;\n      return { workspaceId };\n    });\n\n    this.addEndpoint<DestroyWorkspaceRequestBody, DestroyWorkspaceResponseBody>(\n      Command.destroyWorkspace,\n      async (body) => {\n        this.workspaceStore.destroyWorkspace(body.workspaceId);\n        const response: DestroyWorkspaceResponseBody = {};\n        return response;\n      },\n    );\n\n    this.addEndpoint<InitializeWorkspaceRequestBody, InitializeWorkspaceResponseBody>(\n      Command.initializeWorkspace,\n      async (body) => {\n        const workspace = this.workspaceStore.getWorkspace(body.workspaceId);\n        if (!workspace.initialized) {\n          workspace.initialize();\n        }\n        return {};\n      },\n    );\n\n    this.addEndpoint<RegisterFileRequestBody, RegisterFileResponseBody>(Command.register, async (body) => {\n      const workspace = this.workspaceStore.getWorkspace(body.workspaceId);\n      if (body.fileContent) {\n        workspace.registerInMemoryFile(body.fileName, body.fileContent);\n      } else if (body.absoluteDiskPath) {\n        workspace.registerDiskFile(body.fileName, body.absoluteDiskPath);\n      } else {\n        throw new Error('Should have either fileContent or absoluteDiskPath set');\n      }\n      return {};\n    });\n\n    this.addEndpoint<OpenFileRequestBody, OpenFileResponseBody>(Command.open, async (body) => {\n      const workspace = this.workspaceStore.getInitializedWorkspace(body.workspaceId);\n      const openResult = await workspace.openFile(body.fileName);\n      return { openResult: { importPaths: openResult.importPaths } };\n    });\n\n    this.addEndpoint<EmitFileRequestBody, EmitFileResponseBody>(Command.emit, async (body) => {\n      const workspace = this.workspaceStore.getInitializedWorkspace(body.workspaceId);\n\n      const emitResult = await workspace.emitFile(body.fileName);\n      const output: EmitFileResponseBody = {\n        emitted: emitResult.emitted,\n        files: emitResult.entries.map((e): EmittedFile => {\n          return { fileName: e.fileName, content: e.content };\n        }),\n      };\n\n      return output;\n    });\n\n    this.addEndpoint<AddCodeInstrumentationRequestBody, AddCodeInstrumentationResponseBody>(\n      Command.addCodeInstrumentation,\n      async (body) => {\n        const codeInstrumentation = CodeInstrumentation.getInstance();\n\n        return codeInstrumentation.instrumentFiles(body.files);\n      },\n    );\n\n    this.addEndpoint<GetDiagnosticsRequestBody, GetDiagnosticsResponseBody>(Command.getDiagnostics, async (body) => {\n      const workspace = this.workspaceStore.getInitializedWorkspace(body.workspaceId);\n      const diagnostics = await workspace.getDiagnostics(body.fileName);\n      const output: GetDiagnosticsResponseBody = diagnostics;\n      return output;\n    });\n\n    this.addEndpoint<UpdatedAndroidTargetsRequestBody, UpdatedAndroidTargetsResponseBody>(\n      Command.updatedAndroidTargets,\n      async (body) => {\n        const mapped = body.targets.map(({ deviceId, target }) => {\n          return { deviceId, endpoint: target };\n        });\n        this.debuggingProxy.updateAvailableAndroidDevices(mapped);\n        return {};\n      },\n    );\n\n    this.addEndpoint<DumpSymbolsWithCommentsRequestBody, DumpSymbolsWithCommentsResponseBody>(\n      Command.dumpSymbolsWithComments,\n      async (body) => {\n        const workspace = this.workspaceStore.getInitializedWorkspace(body.workspaceId);\n        const result = await workspace.dumpSymbolsWithComments(body.fileName);\n        return { dumpedSymbols: result };\n      },\n    );\n\n    this.addEndpoint<DumpInterfaceRequestBody, DumpInterfaceResponseBody>(Command.dumpInterface, async (body) => {\n      const workspace = this.workspaceStore.getInitializedWorkspace(body.workspaceId);\n      const result = await workspace.getInterfaceAST(body.fileName, body.position);\n      return { interface: result };\n    });\n\n    this.addEndpoint<DumpEnumRequestBody, DumpEnumResponseBody>(Command.dumpEnum, async (body) => {\n      const workspace = this.workspaceStore.getInitializedWorkspace(body.workspaceId);\n      return await workspace.getEnumAST(body.fileName, body.position);\n    });\n\n    this.addEndpoint<DumpFunctionRequestBody, DumpFunctionResponseBody>(Command.dumpFunction, async (body) => {\n      const workspace = this.workspaceStore.getInitializedWorkspace(body.workspaceId);\n      return await workspace.getFunctionAST(body.fileName, body.position);\n    });\n\n    this.addEndpoint<GenerateIdsFilesRequestBody, GenerateIdsFilesResponseBody>(\n      Command.generateIdsFiles,\n      async (body) => {\n        const result = await generateIdsFromPath(body.moduleName, body.iosHeaderImportPath, body.filePath);\n        const typedResponse: GenerateIdsFilesResponseBody = {\n          android: result.android,\n          iosHeader: result.ios.header,\n          iosImplementation: result.ios.impl,\n          typescriptDefinition: result.typescript.definition,\n          typescriptImplementation: result.typescript.implementation,\n        };\n        return typedResponse;\n      },\n    );\n\n    this.addEndpoint<ExportStringsFilesRequestBody, ExportStringsFilesResponseBody>(\n      Command.exportStringsFiles,\n      async (body) => {\n        await exportStringsFiles(body.moduleName, body.inputPath, body.iosOutputPath, body.androidOutputPath);\n        const typedResponse: ExportStringsFilesResponseBody = {};\n        return typedResponse;\n      },\n    );\n\n    this.addEndpoint<ExportTranslationStringsRequestBody, ExportTranslationStringsResponseBody>(\n      Command.exportTranslationStrings,\n      async (body) => {\n        const result = await exportTranslationStrings(body, this.logger);\n        return result;\n      },\n    );\n\n    this.addEndpoint<ExportStringsFilesBatchRequestBody, ExportStringsFilesBatchResponseBody>(\n      Command.exportStringsFilesBatch,\n      async (body) => {\n        const promises = body.batch.map((body) => {\n          exportStringsFiles(body.moduleName, body.inputPath, body.iosOutputPath, body.androidOutputPath);\n        });\n\n        await Promise.all(promises);\n\n        const typedResponse: ExportStringsFilesBatchResponseBody = {};\n        return typedResponse;\n      },\n    );\n\n    this.addEndpoint<StartDebuggingProxyRequestBody, StartDebuggingProxyResponseBody>(\n      Command.startDebuggingProxy,\n      async (body) => {\n        const actualPort = await this.debuggingProxy.start();\n        const typedResponse: StartDebuggingProxyResponseBody = {\n          actualPort,\n        };\n        return typedResponse;\n      },\n    );\n\n    this.addEndpoint<CompileNativeRequestBody, CompileNativeResponseBody>(Command.compileNative, async (body) => {\n      let workspaceId: number;\n      if (!body.workspaceId && body.registerInputFiles) {\n        workspaceId = this.workspaceStore.createWorkspace().workspaceId;\n      } else {\n        workspaceId = body.workspaceId;\n      }\n      const uncachedWorkspace = this.workspaceStore.getUncachedWorkspace(workspaceId);\n      return await compileNative(uncachedWorkspace, this.logger, body);\n    });\n\n    this.addEndpoint<UpdatedDebuggerPorts, {}>(Command.updatedDebuggerPorts, async (body) => {\n      const mapped = body.ports.map((port) => {\n        return { port: port };\n      });\n      this.debuggingProxy.updateAvailableHermesDevices(mapped);\n      return {};\n    });\n\n    this.addEndpoint<GenerateGhostOwnershipMapRequestBody, GenerateGhostOwnershipMapResponseBody>(\n      Command.generateGhostOwnershipMap,\n      async (body) => {\n        return await generateGhostOwnershipMap(this.logger, body.outputDir);\n      },\n    );\n\n    this.addEndpoint<RewriteImportsRequestBody, RewriteImportsResponseBody>(Command.rewriteImports, async (body) => {\n      await rewriteImports(\n        this.logger,\n        body.projectDirectory,\n        body.oldTypeName,\n        body.newTypeName,\n        body.oldImportPath,\n        body.newImportPath,\n      );\n      const response: RewriteImportsResponseBody = {};\n      return response;\n    });\n  }\n\n  protected override handleExit(exitKind: ExitKind): void {\n    this.debuggingProxy?.stop();\n    this.workspaceStore?.destroyAllWorkspaces();\n\n    super.handleExit(exitKind);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/ConsoleLogTransformer.spec.ts",
    "content": "import 'ts-jest';\nimport * as ts from 'typescript';\nimport { createConsoleLogTransformer } from './ConsoleLogTransformer';\nimport { trimAllLines } from './utils/StringUtils';\n\nfunction sanitize(text: string): string {\n  return trimAllLines(text);\n}\n\n/**\n * Compiles TypeScript source through the ConsoleLogTransformer and returns the output.\n */\nfunction transform(input: string): string {\n  const result = ts.transpileModule(input, {\n    compilerOptions: {\n      target: ts.ScriptTarget.ES2019,\n      module: ts.ModuleKind.CommonJS,\n      removeComments: false,\n    },\n    transformers: {\n      before: [createConsoleLogTransformer()],\n    },\n  });\n  return sanitize(result.outputText);\n}\n\ndescribe('ConsoleLogTransformer', () => {\n  describe('wraps direct console calls', () => {\n    it('wraps console.log', () => {\n      const result = transform(`console.log(\"hello\");`);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n      expect(result).toContain('console.log(\"hello\")');\n    });\n\n    it('wraps console.warn', () => {\n      const result = transform(`console.warn(\"warning\");`);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n      expect(result).toContain('console.warn(\"warning\")');\n    });\n\n    it('wraps console.error', () => {\n      const result = transform(`console.error(\"error\");`);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n      expect(result).toContain('console.error(\"error\")');\n    });\n\n    it('wraps console.info', () => {\n      const result = transform(`console.info(\"info\");`);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n      expect(result).toContain('console.info(\"info\")');\n    });\n\n    it('wraps console.debug', () => {\n      const result = transform(`console.debug(\"debug\");`);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n      expect(result).toContain('console.debug(\"debug\")');\n    });\n  });\n\n  describe('wraps calls with complex arguments', () => {\n    it('wraps calls with template literals', () => {\n      const input = 'const x = 42;\\nconsole.log(`value is ${x}`);';\n      const result = transform(input);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n    });\n\n    it('wraps calls with multiple arguments', () => {\n      const result = transform(`console.log(\"a\", someObj, 123);`);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n      expect(result).toContain('console.log(\"a\", someObj, 123)');\n    });\n\n    it('wraps calls with function call arguments', () => {\n      const result = transform(`console.log(JSON.stringify(obj));`);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n      expect(result).toContain('JSON.stringify(obj)');\n    });\n  });\n\n  describe('wraps multiple console calls in the same file', () => {\n    it('wraps each call independently', () => {\n      const input = `\n        console.log(\"first\");\n        console.warn(\"second\");\n        console.error(\"third\");\n      `;\n      const result = transform(input);\n      // Should have 3 separate if guards\n      const guardCount = (result.match(/runtime\\.isLoggingEnabled/g) || []).length;\n      expect(guardCount).toBe(3);\n    });\n  });\n\n  describe('wraps console calls inside functions', () => {\n    it('wraps calls inside a function body', () => {\n      const input = `\n        function doSomething() {\n          console.log(\"inside function\");\n        }\n      `;\n      const result = transform(input);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n      expect(result).toContain('console.log(\"inside function\")');\n    });\n\n    it('wraps calls inside arrow function with block body', () => {\n      const input = `\n        const fn = () => {\n          console.log(\"inside arrow\");\n        };\n      `;\n      const result = transform(input);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n    });\n\n    it('wraps calls inside class methods', () => {\n      const input = `\n        class MyClass {\n          doWork() {\n            console.log(\"class method\");\n          }\n        }\n      `;\n      const result = transform(input);\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n    });\n  });\n\n  describe('handles non-ExpressionStatement console usage', () => {\n    it('does not wrap console.error used as a callback reference', () => {\n      const input = `promise.catch(console.error);`;\n      const result = transform(input);\n      expect(result).not.toContain('runtime.isLoggingEnabled');\n      expect(result).toContain('promise.catch(console.error)');\n    });\n\n    it('does not wrap console.log assigned to a variable', () => {\n      const input = `const result = console.log(\"test\");`;\n      const result = transform(input);\n      expect(result).not.toContain('runtime.isLoggingEnabled');\n    });\n\n    it('wraps console.log in expression-bodied arrow', () => {\n      const input = `const fn = (x: any) => console.log(x);`;\n      const result = transform(input);\n      expect(result).toContain('runtime.isLoggingEnabled');\n      expect(result).toContain('const fn = (x) => {');\n      expect(result).toContain('console.log(x)');\n    });\n\n    it('wraps parenthesized console.log in expression-bodied arrow', () => {\n      const input = `const fn = (x: any) => (console.log(x));`;\n      const result = transform(input);\n      expect(result).toContain('runtime.isLoggingEnabled');\n      expect(result).toContain('console.log(x)');\n    });\n\n    it('does not wrap non-direct console usage in expression-bodied arrow', () => {\n      const input = `const fn = (x: any) => doSomething(console.log(x));`;\n      const result = transform(input);\n      expect(result).not.toContain('runtime.isLoggingEnabled');\n      expect(result).toContain('doSomething(console.log(x))');\n    });\n\n    it('wraps nested expression-bodied arrow console calls in default parameters', () => {\n      const input = `const fn = (x: any = (() => console.log(\"param\"))()) => console.log(x);`;\n      const result = transform(input);\n      const guardCount = (result.match(/runtime\\.isLoggingEnabled/g) || []).length;\n      expect(guardCount).toBe(2);\n      expect(result).toContain('console.log(\"param\")');\n      expect(result).toContain('console.log(x)');\n    });\n  });\n\n  describe('does NOT wrap non-console methods', () => {\n    it('does not wrap console.trace', () => {\n      const input = `console.trace(\"trace\");`;\n      const result = transform(input);\n      expect(result).not.toContain('runtime.isLoggingEnabled');\n    });\n\n    it('does not wrap other objects with log method', () => {\n      const input = `logger.log(\"test\");`;\n      const result = transform(input);\n      expect(result).not.toContain('runtime.isLoggingEnabled');\n    });\n\n    it('does not wrap runtime.outputLog', () => {\n      const input = `runtime.outputLog(2, \"test\");`;\n      const result = transform(input);\n      expect(result).not.toContain('runtime.isLoggingEnabled');\n    });\n  });\n\n  describe('preserves non-console code', () => {\n    it('leaves other statements untouched', () => {\n      const input = `\n        const x = 1;\n        console.log(\"hello\");\n        const y = 2;\n      `;\n      const result = transform(input);\n      expect(result).toContain('const x = 1');\n      expect(result).toContain('const y = 2');\n      expect(result).toContain('if (runtime.isLoggingEnabled)');\n    });\n  });\n\n});\n"
  },
  {
    "path": "compiler/companion/src/ConsoleLogTransformer.ts",
    "content": "import * as ts from 'typescript';\n\n/**\n * Creates a TypeScript transformer that wraps console.log/warn/error/info/debug\n * call expressions in `if (runtime.isLoggingEnabled) { ... }` guards.\n *\n * This eliminates the cost of console logging in production builds:\n * - Argument evaluation at the call site is skipped\n * - debugStringify in Console.ts is skipped\n * - The JS-to-C++ bridge call is skipped\n *\n * The transform targets:\n * - `ExpressionStatement` nodes whose expression is a direct `console.X(...)` call\n * - expression-bodied arrow functions whose body is a direct `console.X(...)` call\n *\n * This means:\n *\n * - `console.log(a, b);` -> wrapped\n * - `.catch(console.error)` -> NOT wrapped (function reference, not a call)\n * - `.catch(err => console.error(err))` -> wrapped\n * - `const x = console.log(...)` -> NOT wrapped (not an ExpressionStatement)\n *\n * Known caveats:\n * - Arguments with side effects (e.g., `console.log(counter++)`) will have\n *   those side effects suppressed when logging is disabled. No instances of\n *   this pattern exist in the codebase today.\n * - `console.*` used in expression position is not transformed.\n * - Expression-bodied arrows with non-direct console usage are not transformed\n *   (e.g., `x => doSomething(console.log(x))`).\n */\n\nconst CONSOLE_METHODS = new Set(['log', 'warn', 'error', 'info', 'debug']);\n\n/**\n * Returns true if the given CallExpression is a `console.X(...)` call\n * where X is one of log, warn, error, info, debug.\n */\nfunction isConsoleCall(node: ts.CallExpression): boolean {\n  const expr = node.expression;\n  if (!ts.isPropertyAccessExpression(expr)) {\n    return false;\n  }\n  if (!ts.isIdentifier(expr.expression) || expr.expression.text !== 'console') {\n    return false;\n  }\n  return CONSOLE_METHODS.has(expr.name.text);\n}\n\n/**\n * Creates the guard expression: `runtime.isLoggingEnabled`\n */\nfunction createGuardExpression(factory: ts.NodeFactory): ts.Expression {\n  return factory.createPropertyAccessExpression(\n    factory.createIdentifier('runtime'),\n    factory.createIdentifier('isLoggingEnabled'),\n  );\n}\n\nfunction unwrapParenthesizedExpression(node: ts.Expression): ts.Expression {\n  let expr = node;\n  while (ts.isParenthesizedExpression(expr)) {\n    expr = expr.expression;\n  }\n  return expr;\n}\n\n/**\n * Creates a TypeScript transformer factory for wrapping console calls.\n *\n */\nexport function createConsoleLogTransformer(): ts.TransformerFactory<ts.SourceFile> {\n  return (context: ts.TransformationContext): ts.Transformer<ts.SourceFile> => {\n    const factory = context.factory;\n\n    return (sourceFile: ts.SourceFile): ts.SourceFile => {\n      const visitor: ts.Visitor = (node: ts.Node): ts.Node => {\n        const visitedNode = ts.visitEachChild(node, visitor, context);\n\n        // Match ExpressionStatement nodes with direct console calls.\n        if (\n          ts.isExpressionStatement(visitedNode) &&\n          ts.isCallExpression(visitedNode.expression) &&\n          isConsoleCall(visitedNode.expression)\n        ) {\n          // Wrap in: if (runtime.isLoggingEnabled) { <original statement> }\n          return factory.createIfStatement(\n            createGuardExpression(factory),\n            factory.createBlock([visitedNode], /* multiLine */ true),\n          );\n        }\n\n        // Match expression-bodied arrow functions with direct console calls.\n        if (ts.isArrowFunction(visitedNode) && !ts.isBlock(visitedNode.body)) {\n          const bodyExpression = unwrapParenthesizedExpression(visitedNode.body);\n          if (ts.isCallExpression(bodyExpression) && isConsoleCall(bodyExpression)) {\n            const guardedCall = factory.createIfStatement(\n              createGuardExpression(factory),\n              factory.createBlock([factory.createExpressionStatement(bodyExpression)], /* multiLine */ true),\n            );\n            return factory.updateArrowFunction(\n              visitedNode,\n              visitedNode.modifiers,\n              visitedNode.typeParameters,\n              visitedNode.parameters,\n              visitedNode.type,\n              visitedNode.equalsGreaterThanToken,\n              factory.createBlock([guardedCall], /* multiLine */ true),\n            );\n          }\n        }\n\n        return visitedNode;\n      };\n\n      return ts.visitNode(sourceFile, visitor) as ts.SourceFile;\n    };\n  };\n}\n"
  },
  {
    "path": "compiler/companion/src/DebuggingProxy.ts",
    "content": "import { HermesDevice } from 'remotedebug-ios-webkit-adapter/src/adapters/hermesAdapter';\nimport { ProxyServer } from 'remotedebug-ios-webkit-adapter/src/server';\nimport { ILogger } from './logger/ILogger';\nimport { rethrow } from './utils/rethrow';\n\nconst port = 9010;\n\ntype AndroidDevice = { deviceId: string; endpoint: string };\n\nexport class DebuggingProxy {\n  private knownAndroidDevices: AndroidDevice[] = [];\n  private knownHermesDevices: HermesDevice[] = [];\n  private server: ProxyServer | undefined;\n\n  constructor(private logger: ILogger | undefined) {}\n\n  async start() {\n    if (this.server) {\n      throw new Error(\"Cannot start debugging proxy while it's already started\");\n    }\n    this.server = new ProxyServer();\n    try {\n      const actualPort = await this.server.run(port);\n      this.logger?.debug?.(`Valdi debugging proxy is listening on port ${actualPort}`);\n      this.server.updateKnownAndroidDevices(this.knownAndroidDevices);\n      this.server.updateKnownHermesDevices(this.knownHermesDevices);\n\n      return actualPort;\n    } catch (err: any) {\n      this.server = undefined;\n      let message = `\n⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️\n⚠️ Valdi debugging proxy failed to start with error:\n⚠️ ${err.message || err}\n⚠️\n⚠️ 'Valdi Attach' debug configuration in VS Code will not work.\n⚠️ To avoid this error, re-run the hotreloader script with --no-debugging-proxy:\n⚠️\n⚠️ Consider using 'Hermes Attach' debug configuration in VS Code for a more stable\n⚠️ debugging environment. Additional info at:\n⚠️ https://github.com/Snapchat/Valdi/blob/main/docs/docs/workflow-hermes-debugger.md\n⚠️\n⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️\n`;\n      rethrow(message, err);\n    }\n  }\n\n  stop() {\n    this.server?.stop();\n    this.server = undefined;\n  }\n\n  updateAvailableAndroidDevices(androidDevices: AndroidDevice[]) {\n    this.knownAndroidDevices = androidDevices;\n    this.server?.updateKnownAndroidDevices(androidDevices);\n  }\n  updateAvailableHermesDevices(hermesDevices: HermesDevice[]) {\n    this.knownHermesDevices = hermesDevices;\n    this.server?.updateKnownHermesDevices(hermesDevices);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/GenerateIds.spec.ts",
    "content": "import 'ts-jest';\nimport { generateIds } from './GenerateIds';\n\nconst TEST_ID_FILES = `\nids:\n  my_first_id:\n    description: This is my first id\n  my_second_id:\n`;\n\ndescribe('Ids Files Geneerator', () => {\n  it('can generate Android resource file', () => {\n    const android = generateIds('hello_world', '\"SCHelloWorld/Ids.h\"', TEST_ID_FILES).android;\n\n    expect(android).toBe(\n      `\n<resources>\n  <item type=\"id\" name=\"hello_world__my_first_id\"/>\n  <item type=\"id\" name=\"hello_world__my_second_id\"/>\n</resources>\n    `.trim(),\n    );\n  });\n\n  it('can generate Objective-C header file', () => {\n    const iosHeader = generateIds('hello_world', '\"SCHelloWorld/Ids.h\"', TEST_ID_FILES).ios.header;\n\n    expect(iosHeader).toBe(\n      `/**\n * Generated from ids.yaml by the Valdi compiler.\n * Please do not edit this file directly.\n */\n\n#import <Foundation/Foundation.h>\n\n/**\n * This is my first id\n */\nextern NSString *SCValdiIdHelloWorldMyFirstId();\n\nextern NSString *SCValdiIdHelloWorldMySecondId();\n`,\n    );\n  });\n\n  it('can generate Objective-C impl file', () => {\n    const iosImpl = generateIds('hello_world', '\"SCHelloWorld/Ids.h\"', TEST_ID_FILES).ios.impl;\n\n    expect(iosImpl).toBe(\n      `/**\n * Generated from ids.yaml by the Valdi compiler.\n * Please do not edit this file directly.\n */\n\n#import <Foundation/Foundation.h>\n#import \"SCHelloWorld/Ids.h\"\n\nNSString *SCValdiIdHelloWorldMyFirstId() {\n    return @\"hello_world/my_first_id\";\n}\n\nNSString *SCValdiIdHelloWorldMySecondId() {\n    return @\"hello_world/my_second_id\";\n}\n`,\n    );\n  });\n\n  it('can generate TypeScript definition file', () => {\n    const tsDefinition = generateIds('hello_world', '\"SCHelloWorld/Ids.h\"', TEST_ID_FILES).typescript.definition;\n\n    expect(tsDefinition).toBe(\n      `export class Ids {\n  /**\n   * This is my first id\n   */\n  static myFirstId(): string;\n\n  static mySecondId(): string;\n}\n`,\n    );\n  });\n\n  it('can generate JavaScript implementation file', () => {\n    const jsImplementation = generateIds('hello_world', '\"SCHelloWorld/Ids.h\"', TEST_ID_FILES).typescript\n      .implementation;\n\n    expect(jsImplementation).toBe(\n      `module.exports.Ids = {\n  myFirstId: () => 'hello_world/my_first_id',\n  mySecondId: () => 'hello_world/my_second_id',\n}\n`,\n    );\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/GenerateIds.ts",
    "content": "import * as fs from 'fs';\nimport { promisify } from 'util';\nimport * as yaml from 'js-yaml';\nimport * as xml from 'xml-js';\nimport { OutputWriter } from './OutputWriter';\nimport { Identifier } from './Identifier';\nimport { GeneratedFileHeader } from './GeneratedFileHeader';\nimport { ObjectiveCWriter } from './ObjectiveCWriter';\n\ninterface ObjectiveCFile {\n  header: string;\n  impl: string;\n}\n\ninterface TypeScriptFile {\n  definition: string;\n  implementation: string;\n}\n\ninterface GenerateIds {\n  android: string;\n  ios: ObjectiveCFile;\n  typescript: TypeScriptFile;\n}\n\ninterface IdYaml {\n  description?: string;\n}\n\ninterface IdsYaml {\n  ids?: { [id: string]: IdYaml };\n}\n\ninterface Id {\n  name: string;\n  identifier: string;\n  androidCompatibleIdentifier: string;\n  description?: string;\n}\n\nfunction parseIds(moduleName: string, fileContent: string): Id[] {\n  const idsYaml = yaml.load(fileContent.toString()) as IdsYaml;\n\n  if (!idsYaml || !idsYaml.ids) {\n    throw new Error(`Ids Yaml file does not have an 'ids' section`);\n  }\n  const unprocessedIds = idsYaml.ids;\n\n  const ids = Object.keys(unprocessedIds).map((id) => {\n    return { name: id, description: unprocessedIds[id]?.description };\n  });\n\n  ids.sort((l, r) => l.name.localeCompare(r.name));\n\n  return ids.map((id) => {\n    const identifier = new Identifier(id.name);\n    return {\n      name: identifier.toCamelCase(),\n      identifier: `${moduleName}/${identifier.toSnakeCase()}`,\n      androidCompatibleIdentifier: `${moduleName}__${identifier.toSnakeCase()}`,\n      description: id.description,\n    };\n  });\n}\n\nfunction generateHeaderComment(): string {\n  return GeneratedFileHeader.generateMultilineComment(\n    `Generated from ids.yaml by the Valdi compiler.\nPlease do not edit this file directly.`,\n  );\n}\n\nfunction generateAndroidResourceFile(ids: Id[]): string {\n  const androidItems: object[] = ids.map((id) => {\n    return { _attributes: { type: 'id', name: id.androidCompatibleIdentifier } };\n  });\n\n  return xml.js2xml(\n    {\n      resources: {\n        item: androidItems,\n      },\n    },\n    { compact: true, spaces: 2 },\n  );\n}\n\nfunction generateIOSIds(ids: Id[], iosHeaderImportPath: string): ObjectiveCFile {\n  const header = new ObjectiveCWriter();\n  const impl = new ObjectiveCWriter();\n\n  header.append(generateHeaderComment());\n  impl.append(generateHeaderComment());\n\n  header.appendImport('<Foundation/Foundation.h>');\n  impl.appendImport('<Foundation/Foundation.h>');\n  impl.appendImport(iosHeaderImportPath);\n\n  let first = true;\n\n  for (const id of ids) {\n    if (!first) {\n      impl.append('\\n');\n      header.append('\\n');\n    }\n    first = false;\n\n    const functionNameSuffix = new Identifier(id.identifier).toPascalCase();\n    const functionName = `SCValdiId${functionNameSuffix}`;\n\n    const functionSignature = `NSString *${functionName}()`;\n\n    if (id.description) {\n      header.append(GeneratedFileHeader.generateMultilineComment(id.description));\n    }\n\n    header.append(`extern ${functionSignature};\\n`);\n    impl.append(`${functionSignature} {\\n`);\n    impl.withIndentation('    ', () => {\n      impl.append(`return @\"${id.identifier}\";\\n`);\n    });\n    impl.append('}\\n');\n  }\n\n  return {\n    header: header.content(),\n    impl: impl.content(),\n  };\n}\n\nfunction generateTypeScriptIds(ids: Id[]): TypeScriptFile {\n  const definition = new OutputWriter();\n  const implementation = new OutputWriter();\n\n  definition.append('export class Ids {\\n');\n  implementation.append('module.exports.Ids = {\\n');\n\n  definition.beginIndent('  ');\n  implementation.beginIndent('  ');\n\n  let first = true;\n  for (const id of ids) {\n    if (!first) {\n      definition.append('\\n');\n    }\n    first = false;\n\n    if (id.description) {\n      definition.append(GeneratedFileHeader.generateMultilineComment(id.description));\n    }\n    definition.append(`static ${id.name}(): string;\\n`);\n\n    implementation.append(`${id.name}: () => '${id.identifier}',\\n`);\n  }\n\n  definition.endIndent();\n  implementation.endIndent();\n\n  implementation.append('}\\n');\n  definition.append('}\\n');\n\n  return {\n    definition: definition.content(),\n    implementation: implementation.content(),\n  };\n}\n\nexport function generateIds(moduleName: string, iosHeaderImportPath: string, fileContent: string): GenerateIds {\n  const ids = parseIds(moduleName, fileContent);\n\n  const androidIds = generateAndroidResourceFile(ids);\n  const iosFiles = generateIOSIds(ids, iosHeaderImportPath);\n  const tsFile = generateTypeScriptIds(ids);\n\n  return {\n    android: androidIds,\n    ios: iosFiles,\n    typescript: tsFile,\n  };\n}\n\nexport async function generateIdsFromPath(\n  moduleName: string,\n  iosHeaderImportPath: string,\n  filePath: string,\n): Promise<GenerateIds> {\n  const fileContent = await promisify(fs.readFile)(filePath);\n  return generateIds(moduleName, iosHeaderImportPath, fileContent.toString());\n}\n"
  },
  {
    "path": "compiler/companion/src/GeneratedFileHeader.ts",
    "content": "export class GeneratedFileHeader {\n  static generateMultilineComment(comment: string): string {\n    const commentLines = comment\n      .split('\\n')\n      .map((line) => ` * ${line}`)\n      .join('\\n');\n    return `/**\\n${commentLines}\\n */\\n`;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/IWorkspace.d.ts",
    "content": "import {\n  Diagnostic,\n  DumpedInterface,\n  DumpedSymbolsWithComments,\n  DumpEnumResponseBody,\n  DumpFunctionResponseBody,\n} from './protocol';\nimport { AST, DumpedRootNode } from './AST';\n\nexport interface EmitResultEntry {\n  fileName: string;\n  content: string;\n}\n\nexport interface EmitResult {\n  entries: EmitResultEntry[];\n  emitted: boolean;\n}\n\nexport interface GetDiagnosticsResult {\n  diagnostics: Diagnostic[];\n  fileContent: string | undefined;\n  hasError: boolean;\n  timeTakenMs: number;\n}\n\nexport interface DumpSymbolsWithCommentsResult {\n  dumpedSymbols: DumpedRootNode[];\n  references: AST.TypeReference[];\n}\n\nexport interface OpenFileImportPath {\n  relative: string;\n  absolute: string;\n}\n\nexport interface OpenFileResult {\n  importPaths: OpenFileImportPath[];\n  isNonModuleWithAmbiantDeclarations: boolean;\n}\n\nexport interface IWorkspace {\n  initialized: boolean;\n\n  readonly workspaceRoot: string;\n\n  initialize(): void;\n\n  destroy(): void;\n\n  registerInMemoryFile(fileName: string, fileContent: string): void;\n\n  registerDiskFile(fileName: string, absoluteDiskPath: string): void;\n\n  openFile(fileName: string): Promise<OpenFileResult>;\n\n  emitFile(fileName: string): Promise<EmitResult>;\n\n  getDiagnostics(fileName: string): Promise<GetDiagnosticsResult>;\n\n  dumpSymbolsWithComments(fileName: string): Promise<DumpedSymbolsWithComments>;\n\n  getInterfaceAST(fileName: string, position: number): Promise<DumpedInterface>;\n\n  getEnumAST(fileName: string, position: number): Promise<DumpEnumResponseBody>;\n\n  getFunctionAST(fileName: string, position: number): Promise<DumpFunctionResponseBody>;\n\n  resolveImportPath(fromPath: string, toPath: string): string;\n\n  getFileNameForImportPath(importPath: string): string;\n}\n"
  },
  {
    "path": "compiler/companion/src/Identifier.ts",
    "content": "function makeRangeCheck(fromChar: string, toChar: string): (charCode: number) => boolean {\n  const from = fromChar.charCodeAt(0);\n  const to = toChar.charCodeAt(0);\n\n  return (charNode) => charNode >= from && charNode <= to;\n}\n\nconst isUppercaseLetter = makeRangeCheck('A', 'Z');\nconst isDigit = makeRangeCheck('a', 'z');\nconst isLowercaseLetter = makeRangeCheck('a', 'z');\n\nexport class Identifier {\n  private components: string[] = [];\n\n  constructor(str: string) {\n    let current = '';\n\n    const flush = () => {\n      if (current) {\n        this.components.push(current);\n        current = '';\n      }\n    };\n\n    for (let i = 0; i < str.length; i++) {\n      const code = str.charCodeAt(i);\n\n      if (isUppercaseLetter(code)) {\n        flush();\n        current += str.charAt(i).toLowerCase();\n      } else if (isDigit(code) || isLowercaseLetter(code)) {\n        current += str.charAt(i);\n      } else {\n        flush();\n      }\n    }\n\n    flush();\n  }\n\n  toCamelCase(): string {\n    if (this.components.length < 2) {\n      return this.components.join('');\n    }\n\n    return (\n      this.components[0] +\n      this.components\n        .slice(1)\n        .map((c) => c.charAt(0).toUpperCase() + c.substring(1))\n        .join('')\n    );\n  }\n\n  toPascalCase(): string {\n    return this.components.map((c) => c.charAt(0).toUpperCase() + c.substring(1)).join('');\n  }\n\n  toSnakeCase(): string {\n    return this.components.join('_');\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/JSXProcessor.spec.ts",
    "content": "import { JSXProcessor } from './JSXProcessor';\nimport 'ts-jest';\nimport * as ts from 'typescript';\nimport { getSourceMap } from './SourceMapUtils';\nimport { trimAllLines } from './utils/StringUtils';\n\nfunction sanitize(text: string): string {\n  return trimAllLines(text);\n}\n\nfunction compile(text: string, includeSourceMapping?: boolean): string {\n  const processor = JSXProcessor.createFromFile('File.jsx', text, !!includeSourceMapping);\n  let result = processor.process();\n\n  if (!includeSourceMapping) {\n    result = sanitize(result);\n  }\n\n  return result;\n}\n\n// TODO(3521): Update module names to valdi\n\ndescribe('JSXProcessor', () => {\n  it('supports single element', () => {\n    const result = compile(`<layout/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element with static number attribute', () => {\n    const result = compile(`<layout width={42}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout', ['width', 42]);\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element with static string attribute', () => {\n    const result = compile(`<layout width={'42'}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout', ['width', '42']);\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element with static bool attribute', () => {\n    const result = compile(`<layout enableFeature/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout', ['enableFeature', true]);\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element with dynamic attribute', () => {\n    const result = compile(`<layout width={42 * 2}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.setAttributeNumber('width', 42 * 2);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element with dynamic and static attributes', () => {\n    const result = compile(`<layout width={42 * 2} height={30}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout', ['height', 30]);\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.setAttributeNumber('width', 42 * 2);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element children', () => {\n    const result = compile(`\n    <layout>\n     <view/>\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.endRender();\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element children with attributes', () => {\n    const result = compile(`\n    <layout width={42 * 2}>\n     <view height={84 / 2}/>\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.setAttributeNumber('width', 42 * 2);\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.setAttributeNumber('height', 84 / 2);\n    __Renderer.endRender();\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('throws when adding non empty JSX Text', () => {\n    expect(() => {\n      compile(`\n      <layout>\n        some text\n        <view/>\n      </layout>\n      `);\n    }).toThrow();\n  });\n  it('supports component', () => {\n    const result = compile(`\n    <MyComponent/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element key', () => {\n    const result = compile(`<layout key={'myKey'}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, 'myKey');\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component key', () => {\n    const result = compile(`<MyComponent key={'myKey'}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, 'myKey', undefined);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element key from identifier', () => {\n    const result = compile(`<layout key={myLayoutKey}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, myLayoutKey);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element key from expression', () => {\n    const result = compile(`<layout key={viewModel.myLayoutKey}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, viewModel.myLayoutKey);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports element key from complex expression', () => {\n    const result = compile(`\n    const getKey = (obj) => { return obj.myLayoutKey; };\n    <layout key={getKey(this.viewModel)}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const getKey = (obj) => { return obj.myLayoutKey; };\n    __Renderer.beginRender(__nodeLayout1, getKey(this.viewModel));\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component key from identifier', () => {\n    const result = compile(`<MyComponent key={myLayoutKey}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, myLayoutKey, undefined);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component key from expression', () => {\n    const result = compile(`<MyComponent key={viewModel.myLayoutKey}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, viewModel.myLayoutKey, undefined);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component key from complex expression', () => {\n    const result = compile(`\n    const getKey = (obj) => { return obj.myLayoutKey; };\n    <MyComponent key={getKey(this.viewModel)}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const getKey = (obj) => { return obj.myLayoutKey; };\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, getKey(this.viewModel), undefined);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component ref from identifier', () => {\n    const result = compile(`<MyComponent ref={someComponentRef}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, someComponentRef);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component ref from expression', () => {\n    const result = compile(`<MyComponent ref={viewModel.someComponentRef}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, viewModel.someComponentRef);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component ref from complex expression', () => {\n    const result = compile(`\n    const getRef = (obj) => { return obj.myRef; };\n    <MyComponent ref={getRef(this.viewModel)}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const getRef = (obj) => { return obj.myRef; };\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, getRef(this.viewModel));\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component context from identifier', () => {\n    const result = compile(`<MyComponent context={someContext}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    if (!__Renderer.hasContext()) {\n      __Renderer.setContext(someContext);\n    }\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component context from expression', () => {\n    const result = compile(`<MyComponent context={this.context}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    if (!__Renderer.hasContext()) {\n      __Renderer.setContext(this.context);\n    }\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component context from complex expression', () => {\n    const result = compile(`\n    const getContext = (obj) => { return obj.context; };\n    <MyComponent context={getContext(this.viewModel)}/>;\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const getContext = (obj) => { return obj.context; };\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    if (!__Renderer.hasContext()) {\n      __Renderer.setContext(getContext(this.viewModel));\n    }\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports default slotted', () => {\n    const result = compile(`\n    <MyComponent>\n      <layout/>\n    </MyComponent>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setUnnamedSlot(() => {\n      __Renderer.beginRender(__nodeLayout1, undefined);\n      __Renderer.endRender();\n    });\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports explicit slotted', () => {\n    const result = compile(`\n    <MyComponent>\n      <slotted slot='mySlot'>\n        <layout/>\n      </slotted>\n    </MyComponent>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setNamedSlot('mySlot', () => {\n      __Renderer.beginRender(__nodeLayout1, undefined);\n      __Renderer.endRender();\n    });\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports expression in slotted', () => {\n    const result = compile(`\n    <MyComponent>\n      <slotted slot={viewModel.destSlot}>\n        <layout/>\n      </slotted>\n    </MyComponent>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setNamedSlot(viewModel.destSlot, () => {\n      __Renderer.beginRender(__nodeLayout1, undefined);\n      __Renderer.endRender();\n    });\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports slot passed as expression', () => {\n    const result = compile(`\n    const name = 'header';\n    <MyComponent>\n    {\n      $namedSlots({\n        [name]: () => {\n          <layout/>\n        }\n      })\n    }\n    </MyComponent>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const name = 'header';\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setNamedSlots({\n      [name]: () => {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        __Renderer.endRender();\n      }\n    });\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports slot passed as expression with comments', () => {\n    const result = compile(`\n    const name = 'header';\n    <MyComponent>\n    {\n      /* Pass back the header */\n      $namedSlots({\n        [name]: () => {\n          <layout/>\n        }\n      })\n    }\n    </MyComponent>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const name = 'header';\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n      /* Pass back the header */\n      __Renderer.setNamedSlots({\n      [name]: () => {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        __Renderer.endRender();\n      }\n    });\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('optimizes named slots', () => {\n    const result = compile(`\n    <MyComponent>\n    {\n      $namedSlots({\n        header: () => {\n          <layout/>\n        },\n        body: () => {\n          <view/>\n        }\n      })\n    }\n    </MyComponent>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setNamedSlot('header', () => {\n      __Renderer.beginRender(__nodeLayout1, undefined);\n      __Renderer.endRender();\n    });\n    __Renderer.setNamedSlot('body', () => {\n      __Renderer.beginRender(__nodeView1, undefined);\n      __Renderer.endRender();\n    });\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports slot passed as lambda', () => {\n    const result = compile(`\n    <MyComponent>\n    {\n      $slot((text) => {\n        <label value={text}/>\n      })\n    }\n    </MyComponent>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const __nodeLabel1 = __Renderer.makeNodePrototype('label');\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setUnnamedSlot((text) => {\n      __Renderer.beginRender(__nodeLabel1, undefined);\n      __Renderer.setAttribute('value', text);\n      __Renderer.endRender();\n    });\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('throws on orphan slotted elements', () => {\n    expect(() => {\n      compile(`\n      <slotted slot='mySlot'>\n        <layout/>\n      </slotted>\n      `);\n    }).toThrow();\n  });\n  it('throws when mixing explicit and default slotted', () => {\n    expect(() => {\n      compile(`\n      <MyComponent>\n        <slotted slot={viewModel.destSlot}>\n          <layout/>\n        </slotted>\n        <label/>\n        <view/>\n        <slotted slot='nice'>\n          <scroll/>\n        </slotted>\n      </MyComponent>\n      `);\n    }).toThrow();\n  });\n\n  it('supports default slot', () => {\n    const result = compile(`\n    <slot/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    __Renderer.renderUnnamedSlot(this);\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports explicit slot', () => {\n    const result = compile(`\n    <slot name='mySlot'/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    __Renderer.renderNamedSlot('mySlot', this);\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports slot with expressions', () => {\n    const result = compile(`\n    <slot name={viewModel.aSlot}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    __Renderer.renderNamedSlot(viewModel.aSlot, this);\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports unnamed slot with key', () => {\n    const result = compile(`\n    <slot key={'myKey'}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    __Renderer.renderUnnamedSlot(this, undefined, 'myKey');\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports named slot with key', () => {\n    const result = compile(`\n    <slot name='mySlot' key={'myKey'}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    __Renderer.renderNamedSlot('mySlot', this, undefined, 'myKey');\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('throws when adding child to slot', () => {\n    expect(() => {\n      compile(`\n        <slot>\n          <layout/>\n        </slot>\n        `);\n    }).toThrow();\n  });\n  it('throws when using dash in attribute', () => {\n    expect(() => {\n      compile(`\n        <layout some-attribute={true}/>\n        `);\n    }).toThrow();\n  });\n  it('supports static viewModel property', () => {\n    const result = compile(`\n    <MyComponent hello='world' welcome={42}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype(['hello', 'world', 'welcome', 42]);\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports dynamic viewModel property', () => {\n    const result = compile(`\n    <MyComponent welcome={42 * 2}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setViewModelProperty('welcome', 42 * 2);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports combined static and dynamic viewModel properties', () => {\n    const result = compile(`\n    <MyComponent hello='world' welcome={42 * 2}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype(['hello', 'world']);\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setViewModelProperty('welcome', 42 * 2);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports viewModel spread', () => {\n    const result = compile(`\n    <MyComponent {...myProps}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setViewModelProperties(myProps);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports viewModel spread with appended property', () => {\n    const result = compile(`\n    <MyComponent {...myProps} nice='42'/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setViewModelProperties(myProps);\n    __Renderer.setViewModelProperty('nice', '42');\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports viewModel spread with prepended property', () => {\n    const result = compile(`\n    <MyComponent nice='42' {...myProps}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype(['nice', '42']);\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setViewModelProperties(myProps);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports attributes spread', () => {\n    const result = compile(`<layout {...myProps}/>`);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.setAttributes(myProps);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports attributes spread with appended property', () => {\n    const result = compile(`\n    <layout {...myProps} nice='42'/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.setAttributes(myProps);\n    __Renderer.setAttribute('nice', '42');\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports attributes spread with prepended property', () => {\n    const result = compile(`\n    <layout nice='42' {...myProps}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout', ['nice', '42']);\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.setAttributes(myProps);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports inner expression in element', () => {\n    const result = compile(`\n    <layout>\n      {when(someValue, () => {})}\n      <view/>\n      {when(someOtherValue, () => {})}\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    {when(someValue, () => { })}\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.endRender();\n    {when(someOtherValue, () => { })}\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports JSX inside inner expressions', () => {\n    const result = compile(`\n    <layout>\n      {when(someValue, () => {\n        <label/>\n      })}\n      <view/>\n      {when(someOtherValue, () => {\n        <label/>\n      })}\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeLabel1 = __Renderer.makeNodePrototype('label');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    const __nodeLabel2 = __Renderer.makeNodePrototype('label');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    {when(someValue, () => {\n    __Renderer.beginRender(__nodeLabel1, undefined);\n    __Renderer.endRender();\n    })}\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.endRender();\n    {when(someOtherValue, () => {\n    __Renderer.beginRender(__nodeLabel2, undefined);\n    __Renderer.endRender();\n    })}\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('automatically injects block in single expression lambda', () => {\n    const result = compile(`\n    <layout>\n      {when(someValue, () => <label/> )}\n      <view/>\n      {when(someOtherValue, () => <label/> )}\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeLabel1 = __Renderer.makeNodePrototype('label');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    const __nodeLabel2 = __Renderer.makeNodePrototype('label');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    {when(someValue, () => {\n    __Renderer.beginRender(__nodeLabel1, undefined);\n    __Renderer.endRender();\n    })}\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.endRender();\n    {when(someOtherValue, () => {\n    __Renderer.beginRender(__nodeLabel2, undefined);\n    __Renderer.endRender();\n    })}\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('transform JSX in element attributes', () => {\n    const result = compile(`\n    const items = ['a', 'b', 'c'];\n    <element sections={items.map((section) => {\n      return {\n        key: section,\n        onRenderBody: () => {\n          <layout/>\n        }\n      }\n    })}>\n    </element>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeElement1 = __Renderer.makeNodePrototype('element');\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const items = ['a', 'b', 'c'];\n    __Renderer.beginRender(__nodeElement1, undefined);\n    __Renderer.setAttribute('sections', items.map((section) => {\n      return {\n        key: section,\n        onRenderBody: () => {\n          __Renderer.beginRender(__nodeLayout1, undefined);\n          __Renderer.endRender();\n        }\n      };\n    }));\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('transform JSX in viewModel properties', () => {\n    const result = compile(`\n    const items = ['a', 'b', 'c'];\n    <MyComponent>\n      <SectionList sections={items.map((section) => {\n        return {\n          key: section,\n          onRenderHeader: () => {\n            <SectionHeader title={section}/>\n          },\n          onRenderBody: () => {\n            <layout/>\n          }\n        }\n      })}/>\n    </MyComponent>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    const __componentSectionList1 = __Renderer.makeComponentPrototype();\n    const __componentSectionHeader1 = __Renderer.makeComponentPrototype();\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const items = ['a', 'b', 'c'];\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setUnnamedSlot(() => {\n      __Renderer.beginComponent(SectionList, __componentSectionList1, undefined, undefined);\n      __Renderer.setViewModelProperty('sections', items.map((section) => {\n        return {\n          key: section,\n          onRenderHeader: () => {\n            __Renderer.beginComponent(SectionHeader, __componentSectionHeader1, undefined, undefined);\n            __Renderer.setViewModelProperty('title', section);\n            __Renderer.endComponent();\n          },\n          onRenderBody: () => {\n            __Renderer.beginRender(__nodeLayout1, undefined);\n            __Renderer.endRender();\n          }\n        };\n      }));\n      __Renderer.endComponent();\n    });\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports JSX in ternary', () => {\n    const result = compile(`\n    <layout>\n      {someValue ? <layout/> : undefined}\n      {someValue ? undefined : <view/>}\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeLayout2 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    {someValue ? (() => {\n    __Renderer.beginRender(__nodeLayout2, undefined);\n    __Renderer.endRender();\n    })() : undefined}\n    {someValue ? undefined : (() => {\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.endRender();\n    })()}\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('avoids wrapping in pure JSX expressions', () => {\n    const result = compile(`\n    <layout>\n      {<layout/>}\n      <view/>\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeLayout2 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.beginRender(__nodeLayout2, undefined);\n    __Renderer.endRender();\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.endRender();\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('removes parenthesized expressions', () => {\n    const result = compile(`\n    (\n      <layout>\n        <view/>\n      </layout>\n    );\n    ('this should be kept')\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.endRender();\n    __Renderer.endRender();\n    ('this should be kept');\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports component class from expression', () => {\n    const result = compile(`\n    <viewModel.componentClass {...viewModel.properties}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentViewModelcomponentClass1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(viewModel.componentClass, __componentViewModelcomponentClass1, undefined, undefined);\n    __Renderer.setViewModelProperties(viewModel.properties);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('can render in functions', () => {\n    const result = compile(`\n    function onRender() {\n      const text = this.viewModel.text;\n      <layout>\n        <label value={text}/>\n      </layout>;\n      return true;\n    }\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeLabel1 = __Renderer.makeNodePrototype('label');\n    function onRender() {\n    const text = this.viewModel.text;\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.beginRender(__nodeLabel1, undefined);\n    __Renderer.setAttribute('value', text);\n    __Renderer.endRender();\n    __Renderer.endRender();\n    return true;\n    }\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('supports complex nested hierarchy', () => {\n    const result = compile(`\n    function onRender() {\n      <MyComponent height={42}>\n        <layout>\n          {!this.viewModel.showTitle || <label/>}\n          <ChildComponent someProp={this.viewModel.prop}/>\n          {renderBody()}\n        </layout>\n        <view/>\n      </MyComponent>\n    }\n    function renderBody() {\n      <layout>\n        <view/>\n      </layout>\n    }\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype(['height', 42]);\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeLabel1 = __Renderer.makeNodePrototype('label');\n    const __componentChildComponent1 = __Renderer.makeComponentPrototype();\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    const __nodeLayout2 = __Renderer.makeNodePrototype('layout');\n    const __nodeView2 = __Renderer.makeNodePrototype('view');\n    function onRender() {\n      __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n      __Renderer.setUnnamedSlot(() => {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        {!this.viewModel.showTitle || (() => {\n          __Renderer.beginRender(__nodeLabel1, undefined);\n          __Renderer.endRender();\n        })()}\n        __Renderer.beginComponent(ChildComponent, __componentChildComponent1, undefined, undefined);\n        __Renderer.setViewModelProperty('someProp', this.viewModel.prop);\n        __Renderer.endComponent();\n        {renderBody()}\n        __Renderer.endRender();\n        __Renderer.beginRender(__nodeView1, undefined);\n        __Renderer.endRender();\n      });\n      __Renderer.endComponent();\n    }\n    function renderBody() {\n    __Renderer.beginRender(__nodeLayout2, undefined);\n    __Renderer.beginRender(__nodeView2, undefined);\n    __Renderer.endRender();\n    __Renderer.endRender();\n    }\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('append declarations after use strict', () => {\n    const result = compile(`\n    'use strict';\n    <layout/>\n    `);\n    const expected = `\n    'use strict';\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports lazy', () => {\n    const result = compile(`\n    <layout lazy>\n      <map/>\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout', ['lazy', true]);\n    const __nodeMap1 = __Renderer.makeNodePrototype('map');\n    if (__Renderer.beginRenderIfNeeded(__nodeLayout1, undefined)) {\n      __Renderer.beginRender(__nodeMap1, undefined);\n      __Renderer.endRender();\n      __Renderer.endRender();\n    }\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('ignores JSX text with semicolon', () => {\n    const result = compile(`\n    <layout>\n      <view/>;\n      <layout/>; ;;; ;\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    const __nodeLayout2 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.beginRender(__nodeView1, undefined);\n    __Renderer.endRender();\n    __Renderer.beginRender(__nodeLayout2, undefined);\n    __Renderer.endRender();\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports element ref', () => {\n    const result = compile(`\n    <layout ref={someRefSomewhere}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    __Renderer.setAttributeRef(someRefSomewhere);\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports element ref in slot', () => {\n    const result = compile(`\n    <slot ref={someRefSomewhere}/>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    __Renderer.renderUnnamedSlot(this, someRefSomewhere);\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports function component', () => {\n    const result = compile(`\n    function MyCard() {\n\n    }\n    class MyCardComponent {\n\n    }\n\n    <MyCard/>;\n    <MyCardComponent />;\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyCardComponent1 = __Renderer.makeComponentPrototype();\n    function MyCard() {\n\n    }\n    class MyCardComponent {\n\n    }\n\n    __Renderer.renderFnComponent(MyCard, {});\n    __Renderer.beginComponent(MyCardComponent, __componentMyCardComponent1, undefined, undefined);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports inline function components via a variable', () => {\n    const result = compile(`\n    function MyCardOriginal() {\n\n    }\n\n    const MyCard = MyCardOriginal;\n\n    class MyCardComponent {\n\n    }\n\n    <MyCard/>;\n    <MyCardComponent />;\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyCardComponent1 = __Renderer.makeComponentPrototype();\n    function MyCardOriginal() {\n\n    }\n    const MyCard = MyCardOriginal;\n    class MyCardComponent {\n\n    }\n\n    __Renderer.renderFnComponent(MyCard, {});\n    __Renderer.beginComponent(MyCardComponent, __componentMyCardComponent1, undefined, undefined);\n    __Renderer.endComponent();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports inline function component through declare', () => {\n    const result = compile(`\n    interface ViewModel {\n      text: string;\n      numberOfLines?: number;\n      marginBottom?: number;\n  }\n  export declare const DialogTitle: ({ text, numberOfLines, marginBottom }: ViewModel) => void;\n\n  export const PublishingDialog = (): void => {\n      <DialogTitle text={'Hello world'} />\n  };\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n\n    export const PublishingDialog = () => {\n      __Renderer.renderFnComponent(DialogTitle, {\n        text: 'Hello world'\n      });\n    };\n\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('can pass children to function component', () => {\n    const result = compile(`\n    function MyCard(viewModel) {\n      viewModel.children();\n    }\n\n    <MyCard>\n      <layout/>\n    </MyCard>\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    function MyCard(viewModel) {\n      viewModel.children();\n    }\n\n    __Renderer.renderFnComponent(MyCard, {\n      children: () => {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        __Renderer.endRender();\n      }\n    });\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('can pass attribute to function component', () => {\n    const result = compile(`\n    function MyCard(viewModel) {\n    }\n\n    <MyCard hello={'world'}/>\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    function MyCard(viewModel) {\n    }\n\n    __Renderer.renderFnComponent(MyCard, {\n      hello: 'world'\n    });\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('can pass attribute and children combined to a function component', () => {\n    const result = compile(`\n    function MyCard(viewModel) {\n      viewModel.children();\n    }\n\n    <MyCard hello={'world'}>\n      <layout/>\n    </MyCard>\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    function MyCard(viewModel) {\n      viewModel.children();\n    }\n\n    __Renderer.renderFnComponent(MyCard, {\n      hello: 'world',\n      children: () => {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        __Renderer.endRender();\n      }\n    });\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports jsx in function component body', () => {\n    const result = compile(`\n    function MyCard(viewModel) {\n      <view backgroundColor='red'>\n        {viewModel.children()}\n      </view>\n    }\n\n    <MyCard hello={'world'}>\n      <layout/>\n    </MyCard>\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeView1 = __Renderer.makeNodePrototype('view', ['backgroundColor', 'red']);\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    function MyCard(viewModel) {\n      __Renderer.beginRender(__nodeView1, undefined);\n      {viewModel.children()}\n      __Renderer.endRender();\n    }\n\n    __Renderer.renderFnComponent(MyCard, {\n      hello: 'world',\n      children: () => {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        __Renderer.endRender();\n      }\n    });\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports higher order function components', () => {\n    const result = compile(`\n    const withRedBackground = (innerFunctionComponent: () => void) => (viewModel) => {\n      <view backgroundColor='red'>\n        {innerFunctionComponent(viewModel)}\n      </view>\n    }\n\n    function MyCardOriginal(viewModel) {\n      viewModel.children()\n    }\n\n    const MyCard = withRedBackground(MyCardOriginal);\n\n    <MyCard hello={'world'}>\n      <layout/>\n    </MyCard>\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeView1 = __Renderer.makeNodePrototype('view', ['backgroundColor', 'red']);\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const withRedBackground = (innerFunctionComponent) => (viewModel) => {\n      __Renderer.beginRender(__nodeView1, undefined);\n      {innerFunctionComponent(viewModel)}\n      __Renderer.endRender();\n    };\n    function MyCardOriginal(viewModel) {\n      viewModel.children();\n    }\n    const MyCard = withRedBackground(MyCardOriginal);\n    __Renderer.renderFnComponent(MyCard, {\n      hello: 'world',\n      children: () => {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        __Renderer.endRender();\n      }\n    });\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('can pass spread attributes to function component', () => {\n    const result = compile(`\n    function MyCard(viewModel) {\n    }\n\n    <MyCard hello='world' {...someObject} welcome='to_paradise'/>\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    function MyCard(viewModel) {\n    }\n\n    __Renderer.renderFnComponent(MyCard, {\n      hello: 'world',\n      ...someObject,\n      welcome: 'to_paradise'\n    });\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('can generate source maps', () => {\n    const jsxToCompile = `\nfunction onRender(width, height) {\n  <layout width={width}>\n    <view height={height}/>\n  </layout>\n}\n  `.trim();\n\n    const result = compile(jsxToCompile, true);\n\n    const sourceMapConsumer = getSourceMap(result)!;\n    expect(sourceMapConsumer).toBeTruthy();\n\n    /**\n     * Emitted source file:\n     *\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    function onRender(width, height) {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        __Renderer.setAttribute('width', width);\n        __Renderer.beginRender(__nodeView1, undefined);\n        __Renderer.setAttribute('height', height);\n        __Renderer.endRender();\n        __Renderer.endRender();\n    }\n     */\n\n    // Check that source maps point back to the original JSX\n\n    // get location of onRender()\n    let position = sourceMapConsumer.originalPositionFor({ line: 4, column: 9 });\n    expect(position.line).toBe(1);\n    expect(position.column).toBe(9);\n\n    // Get location of the first beginRender()\n    position = sourceMapConsumer.originalPositionFor({ line: 5, column: 4 });\n    expect(position.line).toBe(2);\n    expect(position.column).toBe(3);\n\n    // Get location of the last endRender()\n    position = sourceMapConsumer.originalPositionFor({ line: 10, column: 4 });\n    expect(position.line).toBe(4);\n    expect(position.column).toBe(4);\n\n    // Get location of width attribute\n    position = sourceMapConsumer.originalPositionFor({ line: 6, column: 4 });\n    expect(position.line).toBe(2);\n    expect(position.column).toBe(10);\n\n    // Get location of height attribute\n    position = sourceMapConsumer.originalPositionFor({ line: 8, column: 4 });\n    expect(position.line).toBe(3);\n    expect(position.column).toBe(10);\n  });\n\n  it('merges sources map', () => {\n    // We first compile a tsx into jsx\n    const tsx = `\nenum Size {\n  SMALL = 40,\n  LARGE = 100,\n}\n\ninterface ViewModel {\n  size: Size;\n  height: number;\n}\n\nfunction onRender(viewModel: ViewModel) {\n  <layout width={viewModel.size}>\n    <view height={viewModel.height}/>\n  </layout>\n}\n    `.trim();\n\n    let compilerOptions: ts.CompilerOptions = {\n      target: ts.ScriptTarget.ES2015,\n      jsx: ts.JsxEmit.Preserve,\n      removeComments: false,\n      sourceMap: true,\n      sourceRoot: '/',\n      inlineSourceMap: true,\n      inlineSources: true,\n    };\n\n    const jsx = ts.transpileModule(tsx, {\n      compilerOptions: compilerOptions,\n      fileName: 'MyFile.tsx',\n    }).outputText;\n\n    // We now compile the JSX into JS\n    const result = compile(jsx, true);\n\n    /**\n     * Emitted source file:\n     *\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    const __nodeView1 = __Renderer.makeNodePrototype('view');\n    const Size;\n    (function (Size) {\n        Size[Size[\"SMALL\"] = 40] = \"SMALL\";\n        Size[Size[\"LARGE\"] = 100] = \"LARGE\";\n    })(Size || (Size = {}));\n    function onRender(viewModel) {\n        __Renderer.beginRender(__nodeLayout1, undefined);\n        __Renderer.setAttribute('width', viewModel.size);\n        __Renderer.beginRender(__nodeView1, undefined);\n        __Renderer.setAttribute('height', viewModel.height);\n        __Renderer.endRender();\n        __Renderer.endRender();\n    }\n     */\n\n    const sourceMap = getSourceMap(result)!;\n    expect(sourceMap).toBeTruthy();\n\n    // We should be able to map a beginRender back to the original TS file\n\n    let position = sourceMap.originalPositionFor({ line: 10, column: 4 });\n    expect(position.line).toBe(12);\n    expect(position.column).toBe(3);\n\n    // We should also be able to map a TS value back to the original TS file\n\n    position = sourceMap.originalPositionFor({ line: 6, column: 32 });\n    expect(position.line).toBe(2);\n    expect(position.column).toBe(2);\n  });\n\n  it('ignores comments in slotted', () => {\n    const result = compile(`\n    <MyComponent>\n      {/* Header */}\n      <slotted slot='header'/>\n      {/* Body */}\n      <slotted slot='body'/>\n    </MyComponent>\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setNamedSlot('header', () => {\n    });\n    __Renderer.setNamedSlot('body', () => {\n    });\n    __Renderer.endComponent();\n    `;\n\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('supports injected attributes', () => {\n    const result = compile(`\n    <MyComponent $width={42}/>\n    `);\n\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __componentMyComponent1 = __Renderer.makeComponentPrototype();\n    __Renderer.beginComponent(MyComponent, __componentMyComponent1, undefined, undefined);\n    __Renderer.setInjectedAttribute('$width', 42);\n    __Renderer.endComponent();\n    `;\n\n    expect(result).toBe(sanitize(expected));\n  });\n\n  it('fails when passing unbound function', () => {\n    expect(() => {\n      compile(`\n      class MyComponent {\n        onRender() {\n          <view onTap={this.myCallback}/>\n        }\n        myCallback() {\n        }\n      }\n      `);\n    }).toThrow();\n  });\n\n  it('succeeds when passing bound function', () => {\n    compile(`\n      class MyComponent {\n        onRender() {\n          <view onTap={this.myCallback}/>\n        }\n        myCallback = () => {\n        }\n      }\n    `);\n  });\n\n  it('preserves comments', () => {\n    const result = compile(`\n    // The following is a JSX expression:\n    <layout>\n      {/* This is a JSX comment */}\n    </layout>\n    `);\n    const expected = `\n    const __Renderer = require('valdi_core/src/JSX').jsx;\n    const __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n    __Renderer.beginRender(__nodeLayout1, undefined);\n    {/* This is a JSX comment */}\n    __Renderer.endRender();\n    `;\n    expect(result).toBe(sanitize(expected));\n  });\n  it('emits setAttributeString for custom-view androidClass and webClass', () => {\n    const result = compile(`\n    const AC = 'com.example.FooView';\n    const WC = 'WebFooView';\n    <custom-view androidClass={AC} webClass={WC} width=\"100%\" height={120}/>\n    `);\n    expect(result).toContain(\"__Renderer.setAttributeString('androidClass', AC)\");\n    expect(result).toContain(\"__Renderer.setAttributeString('webClass', WC)\");\n    expect(result).toContain(\"makeNodePrototype('custom-view'\");\n  });\n\n  it('emits setAttributeString for all custom-view class attrs (androidClass, iosClass, macosClass, webClass)', () => {\n    const result = compile(`\n    const AC = 'com.snap.modules.valdi_polyglot.FilePickerView';\n    const IC = 'SCFilePickerView';\n    const MC = 'SCFilePickerView';\n    const WC = 'ValdiPolyglotFilePicker';\n    <custom-view androidClass={AC} iosClass={IC} macosClass={MC} webClass={WC} width=\"100%\" height={120}/>\n    `);\n    expect(result).toContain(\"__Renderer.setAttributeString('androidClass', AC)\");\n    expect(result).toContain(\"__Renderer.setAttributeString('iosClass', IC)\");\n    expect(result).toContain(\"__Renderer.setAttributeString('macosClass', MC)\");\n    expect(result).toContain(\"__Renderer.setAttributeString('webClass', WC)\");\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/JSXProcessor.ts",
    "content": "import * as ts from 'typescript';\nimport { isExpressionNode, resolveTypeOfExpression, SymbolType, Transpiler } from './TSUtils';\nimport { mergeSourceMaps } from './SourceMapUtils';\nimport { ILogger } from './logger/ILogger';\nimport { createConsoleLogTransformer } from './ConsoleLogTransformer';\n\nenum JSXAttributeValueKind {\n  dynamic = 1,\n  static = 2,\n  spread = 3,\n}\n\ninterface JSXAttributeValue {\n  kind: JSXAttributeValueKind;\n  value: ts.Expression;\n}\n\ninterface JSXAttribute {\n  node: ts.Node;\n  name: string | undefined;\n  value: JSXAttributeValue;\n}\n\ninterface JSXElement {\n  element: ts.JsxOpeningElement | ts.JsxSelfClosingElement;\n  closingElement: ts.JsxClosingElement | undefined;\n  nodeType: ts.JsxTagNameExpression;\n  attributes: JSXAttribute[];\n  children: ts.JsxChild[];\n}\n\ninterface JSXOutputState {\n  nodePrototypeDeclarations: ts.Statement[];\n  idSequence: { [nodeType: string]: number };\n  nodeDepth: number;\n  typeChecker: ts.TypeChecker;\n}\n\ninterface JSXAttributeStatements {\n  slot?: JSXAttributeValue;\n  key: ts.Expression | undefined;\n  nodeRef: ts.Expression | undefined;\n  componentContext: ts.Expression | undefined;\n  lazy: boolean;\n  staticAttributesLiteral?: ts.Expression;\n  dynamicAttributes: JSXAttribute[];\n  injectedAttributes: JSXAttribute[];\n  allAttributes: JSXAttribute[];\n}\n\ninterface Slotted {\n  slotName: ts.Expression | undefined;\n  expressions: ts.JsxChild[];\n}\n\nconst enum JSXNodeKind {\n  element = 1,\n  component = 2,\n  functionComponent = 3,\n  slot = 4,\n}\n\ninterface JSXNodeOutput {\n  beginRenderStatement: ts.Statement;\n  endRenderStatement: ts.Statement | undefined;\n  statements: ts.Statement[];\n}\n\n// TODO(3521): update to valdi\nconst rendererModulePath = 'valdi_core/src/JSX';\n\nfunction createStringLiteral(value: string, transformContext: ts.TransformationContext): ts.StringLiteral {\n  const literal = transformContext.factory.createStringLiteral(value);\n  (literal as any).singleQuote = true;\n  return literal;\n}\n\nexport class JSXProcessor {\n  constructor(readonly logger?: ILogger) {}\n\n  makeTransformers(typeChecker: ts.TypeChecker): ts.TransformerFactory<ts.SourceFile>[] {\n    const state: JSXOutputState = { nodePrototypeDeclarations: [], idSequence: {}, nodeDepth: 0, typeChecker };\n\n    const transforms: ts.TransformerFactory<ts.SourceFile>[] = [\n      (context) => (node) => this.transformSourceFile(node, state, context),\n      (context) => (node) => this.injectDeclarations(node, state, context),\n    ];\n\n    return transforms;\n  }\n\n  private isAlphaNum(char: number): boolean {\n    if (char >= 48 && char <= 57) {\n      return true;\n    }\n\n    if (char >= 65 && char <= 90) {\n      return true;\n    }\n\n    if (char >= 97 && char <= 122) {\n      return true;\n    }\n\n    return false;\n  }\n\n  private toPascalCase(key: string): string {\n    for (let i = 0; i < key.length; i++) {\n      const charCode = key.charCodeAt(i);\n\n      if (!this.isAlphaNum(charCode)) {\n        const prefix = key.substr(0, i);\n        const suffix = key.substr(i + 1);\n        key = prefix + suffix;\n        i--;\n      }\n    }\n\n    return key.substr(0, 1).toUpperCase() + key.substr(1);\n  }\n\n  private resolveJSXAttributeStatements(\n    jsxNodeKind: JSXNodeKind,\n    jsxElement: JSXElement,\n    transformContext: ts.TransformationContext,\n  ): JSXAttributeStatements {\n    const nodeTypeStr = jsxElement.nodeType.getText();\n    const attributes = jsxElement.attributes;\n\n    let key: ts.Expression | undefined;\n    let slot: JSXAttributeValue | undefined;\n    const dynamicAttributes: JSXAttribute[] = [];\n    const injectedAttributes: JSXAttribute[] = [];\n    const allAttributes: JSXAttribute[] = [];\n    const staticAttributes: ts.Expression[] = [];\n    let foundSpread = false;\n    let lazy = false;\n    let nodeRef: ts.Expression | undefined;\n    let componentContext: ts.Expression | undefined;\n\n    for (const attribute of attributes) {\n      if (attribute.name === 'slot') {\n        if (nodeTypeStr != 'slotted') {\n          this.onError(jsxElement.element, `'slot' attribute is only supported in <slotted> elements`);\n        }\n        slot = attribute.value;\n        continue;\n      }\n      if (attribute.name === 'key') {\n        key = attribute.value.value;\n        continue;\n      }\n\n      if (attribute.name === 'ref') {\n        nodeRef = attribute.value.value;\n        continue;\n      }\n\n      if (attribute.name === 'context' && jsxNodeKind === JSXNodeKind.component) {\n        componentContext = attribute.value.value;\n        continue;\n      }\n      if (attribute.name === 'lazy') {\n        lazy = true;\n      }\n\n      allAttributes.push(attribute);\n\n      if (attribute.value.kind === JSXAttributeValueKind.spread) {\n        foundSpread = true;\n        dynamicAttributes.push(attribute);\n      } else if (attribute.name?.[0] === '$' && jsxNodeKind === JSXNodeKind.component) {\n        injectedAttributes.push(attribute);\n      } else if (attribute.value.kind === JSXAttributeValueKind.static && !foundSpread) {\n        staticAttributes.push(createStringLiteral(attribute.name!, transformContext));\n        staticAttributes.push(attribute.value.value);\n      } else {\n        dynamicAttributes.push(attribute);\n      }\n    }\n\n    let staticAttributesLiteral: ts.Expression | undefined;\n    if (staticAttributes.length) {\n      staticAttributesLiteral = transformContext.factory.createArrayLiteralExpression(staticAttributes);\n    }\n\n    return {\n      dynamicAttributes,\n      injectedAttributes,\n      allAttributes,\n      slot,\n      lazy,\n      key,\n      nodeRef,\n      componentContext,\n      staticAttributesLiteral,\n    };\n  }\n\n  private makeIdentifier(prefix: string, type: string, output: JSXOutputState): string {\n    let humanReadableIdPrefix = prefix + this.toPascalCase(type);\n\n    let currentSequence = (output.idSequence[humanReadableIdPrefix] | 0) + 1;\n    output.idSequence[humanReadableIdPrefix] = currentSequence;\n\n    return `${humanReadableIdPrefix}${currentSequence}`;\n  }\n\n  private getSlotValueExpr(\n    jsxAttributes: ts.JsxAttributes,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Expression | undefined {\n    const attributes = this.extractJSXAttributes(jsxAttributes, output, transformContext);\n\n    if (attributes.length === 0) {\n      return undefined;\n    }\n\n    if (attributes.length > 1 || attributes[0].name !== 'slot') {\n      this.onError(jsxAttributes, `slotted only support the 'slot' attribute`);\n    }\n\n    return attributes[0].value.value;\n  }\n\n  private toStatement(node: ts.Node, transformContext: ts.TransformationContext): ts.Statement {\n    if (isExpressionNode(node)) {\n      return transformContext.factory.createExpressionStatement(node);\n    }\n\n    // TODO(simon): Any edge cases here?\n    return node as ts.Statement;\n  }\n\n  private toExpression(node: ts.Node, transformContext: ts.TransformationContext): ts.Expression {\n    if (isExpressionNode(node)) {\n      return node;\n    }\n\n    if (ts.isExpressionStatement(node)) {\n      return node.expression;\n    }\n\n    // Convert to an immediately called lambda\n\n    const arrowFunction = transformContext.factory.createArrowFunction(\n      undefined,\n      undefined,\n      [],\n      undefined,\n      undefined,\n      this.toBlock([this.toStatement(node, transformContext)], transformContext),\n    );\n\n    return transformContext.factory.createCallExpression(arrowFunction, [], []);\n  }\n\n  private toBlock(statements: ts.Statement[], transformContext: ts.TransformationContext): ts.Block {\n    if (statements.length === 1 && ts.isBlock(statements[0])) {\n      return statements[0] as ts.Block;\n    }\n\n    return transformContext.factory.createBlock(statements, true);\n  }\n\n  private mergeStatements(statements: ts.Statement[], transformContext: ts.TransformationContext): ts.Statement {\n    if (!statements.length) {\n      return transformContext.factory.createEmptyStatement();\n    }\n\n    return this.toBlock(statements, transformContext);\n  }\n\n  private outputJSXChildren(\n    node: ts.Node,\n    children: ts.JsxChild[],\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    const processedStatements: ts.JsxChild[] = [];\n    const statements: ts.Statement[] = [];\n\n    for (const child of children) {\n      if (this.isJsxText(child)) {\n        continue;\n      }\n\n      processedStatements.push(child);\n\n      const resultNode = this.transformNode(child, output, transformContext);\n      statements.push(this.toStatement(resultNode, transformContext));\n    }\n\n    return this.flattenBlocks(node, processedStatements, statements);\n  }\n\n  private createRendererCallExpr(\n    functionName: string,\n    callArguments: ts.Expression[],\n    transformContext: ts.TransformationContext,\n  ): ts.Expression {\n    const propertyAccess = transformContext.factory.createPropertyAccessExpression(\n      transformContext.factory.createIdentifier('__Renderer'),\n      functionName,\n    );\n    return transformContext.factory.createCallExpression(propertyAccess, undefined, callArguments);\n  }\n\n  private createRendererCall(\n    functionName: string,\n    callArguments: ts.Expression[],\n    originalNode: ts.Node | undefined,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement {\n    const callExpression = this.createRendererCallExpr(functionName, callArguments, transformContext);\n    const expressionStatement = transformContext.factory.createExpressionStatement(callExpression);\n\n    if (originalNode) {\n      ts.setTextRange(expressionStatement, originalNode);\n    }\n    return expressionStatement;\n  }\n\n  private isCompilerIntrinsicCall(node: ts.Node, intrisicCallName: string): node is ts.CallExpression {\n    if (!ts.isCallExpression(node)) {\n      return false;\n    }\n\n    if (!ts.isIdentifier(node.expression)) {\n      return false;\n    }\n\n    return node.expression.text === intrisicCallName;\n  }\n\n  private isNamedSlotsExpression(expression: ts.Node): expression is ts.CallExpression {\n    return this.isCompilerIntrinsicCall(expression, '$namedSlots');\n  }\n\n  private isUnnamedSlotsExpression(expression: ts.Node): expression is ts.CallExpression {\n    return this.isCompilerIntrinsicCall(expression, '$slot');\n  }\n\n  private outputSlotExpression(\n    sourceNode: ts.Node,\n    intrinsicCallArguments: ts.NodeArray<ts.Node>,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement {\n    if (intrinsicCallArguments.length !== 1) {\n      this.onError(sourceNode, `Intrinsic slot call should have 1 argument`);\n    }\n    const node = this.transformNode(intrinsicCallArguments[0], output, transformContext);\n\n    return this.createRendererCall(\n      'setUnnamedSlot',\n      [this.toExpression(node, transformContext)],\n      undefined,\n      transformContext,\n    );\n  }\n\n  private isOptimizableNamedSlots(\n    properties: ts.NodeArray<ts.ObjectLiteralElementLike>,\n  ): properties is ts.NodeArray<ts.PropertyAssignment> {\n    for (const property of properties) {\n      if (!ts.isPropertyAssignment(property)) {\n        return false;\n      }\n      if (!(ts.isIdentifier(property.name) || ts.isStringLiteral(property.name))) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  private toStringLiteral(node: ts.PropertyName, transformContext: ts.TransformationContext): ts.Expression {\n    if (ts.isStringLiteral(node)) {\n      return node;\n    }\n    if (ts.isIdentifier(node)) {\n      return transformContext.factory.createStringLiteral(node.text, true);\n    }\n\n    this.onError(node, 'Cannot convert node to string literal');\n  }\n\n  private outputNamedSlotsExpression(\n    sourceNode: ts.Node,\n    intrinsicCallArguments: ts.NodeArray<ts.Node>,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    if (intrinsicCallArguments.length !== 1) {\n      this.onError(sourceNode, `Intrinsic named slots call should have 1 argument`);\n    }\n\n    const arg = intrinsicCallArguments[0];\n\n    if (ts.isObjectLiteralExpression(arg) && this.isOptimizableNamedSlots(arg.properties)) {\n      return arg.properties.map((property: ts.PropertyAssignment) => {\n        const node = this.transformNode(property.initializer, output, transformContext);\n\n        return this.createRendererCall(\n          'setNamedSlot',\n          [this.toStringLiteral(property.name, transformContext), this.toExpression(node, transformContext)],\n          sourceNode,\n          transformContext,\n        );\n      });\n    } else {\n      const node = this.transformNode(arg, output, transformContext);\n\n      return [\n        this.createRendererCall(\n          'setNamedSlots',\n          [this.toExpression(node, transformContext)],\n          sourceNode,\n          transformContext,\n        ),\n      ];\n    }\n  }\n\n  private getSingleJsxExpression(children: ts.JsxChild[]): ts.Expression | undefined {\n    if (children.length !== 1) {\n      return undefined;\n    }\n\n    const uniqueChild = children[0];\n    if (!ts.isJsxExpression(uniqueChild)) {\n      return undefined;\n    }\n\n    return uniqueChild.expression;\n  }\n\n  private outputSlot(\n    node: ts.Node,\n    children: ts.JsxChild[],\n    slotName: ts.Expression | undefined,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    const childrenWithoutTexts = children.filter(\n      (child) => !(this.isEmptyJsxExpression(child) || this.isJsxText(child)),\n    );\n    const singleExpr = this.getSingleJsxExpression(childrenWithoutTexts);\n\n    if (singleExpr && this.isNamedSlotsExpression(singleExpr)) {\n      return this.outputNamedSlotsExpression(singleExpr, singleExpr.arguments, output, transformContext);\n    } else if (singleExpr && this.isUnnamedSlotsExpression(singleExpr)) {\n      return [this.outputSlotExpression(singleExpr, singleExpr.arguments, output, transformContext)];\n    } else {\n      const innerStatements = this.outputJSXChildren(node, childrenWithoutTexts, output, transformContext);\n      const lambdaInner = transformContext.factory.createArrowFunction(\n        undefined,\n        undefined,\n        [],\n        undefined,\n        undefined,\n        this.toBlock(innerStatements, transformContext),\n      );\n\n      if (slotName) {\n        return [this.createRendererCall('setNamedSlot', [slotName, lambdaInner], undefined, transformContext)];\n      } else {\n        return [this.createRendererCall('setUnnamedSlot', [lambdaInner], undefined, transformContext)];\n      }\n    }\n  }\n\n  private createConstVariable(\n    variableName: string,\n    expr: ts.Expression,\n    transformContext: ts.TransformationContext,\n  ): ts.VariableStatement {\n    const variable = transformContext.factory.createVariableDeclaration(variableName, undefined, undefined, expr);\n    const declarationList = transformContext.factory.createVariableDeclarationList([variable], ts.NodeFlags.Const);\n    return transformContext.factory.createVariableStatement(undefined, declarationList);\n  }\n\n  private appendInitializedVariable(\n    variablePrefix: string,\n    variableSuffix: string,\n    expr: ts.Expression,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Expression {\n    const variableName = this.makeIdentifier(variablePrefix, variableSuffix, output);\n\n    output.nodePrototypeDeclarations.push(this.createConstVariable(variableName, expr, transformContext));\n\n    return transformContext.factory.createIdentifier(variableName);\n  }\n\n  private resolveSetAttributeCall(node: ts.Expression, output: JSXOutputState): string {\n    const resolvedType = resolveTypeOfExpression(node, output.typeChecker);\n\n    if (resolvedType.effectiveType === SymbolType.boolean) {\n      return 'setAttributeBool';\n    } else if (resolvedType.effectiveType === SymbolType.number) {\n      return 'setAttributeNumber';\n    } else if (resolvedType.effectiveType === SymbolType.string) {\n      return 'setAttributeString';\n    } else if (resolvedType.effectiveType === SymbolType.function) {\n      return 'setAttributeFunction';\n    } else if (resolvedType.effectiveType === SymbolType.object && resolvedType.effectiveObjectInfo?.name === 'Style') {\n      return 'setAttributeStyle';\n    }\n\n    return 'setAttribute';\n  }\n\n  private outputElementInner(\n    jsxElement: JSXElement,\n    attributeStatements: JSXAttributeStatements,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    const statements: ts.Statement[] = [];\n\n    if (attributeStatements.nodeRef) {\n      const transformedValueNode = this.transformNode(attributeStatements.nodeRef, output, transformContext);\n      const transformedValue = this.toExpression(transformedValueNode, transformContext);\n\n      statements.push(\n        this.createRendererCall('setAttributeRef', [transformedValue], attributeStatements.nodeRef, transformContext),\n      );\n    }\n\n    for (const attribute of attributeStatements.dynamicAttributes) {\n      if (attribute.value.kind === JSXAttributeValueKind.spread) {\n        statements.push(\n          this.createRendererCall('setAttributes', [attribute.value.value], attribute.node, transformContext),\n        );\n      } else {\n        const transformedValueNode = this.transformNode(attribute.value.value, output, transformContext);\n        const transformedValue = this.toExpression(transformedValueNode, transformContext);\n        const setAttributeCall = this.resolveSetAttributeCall(attribute.value.value, output);\n        statements.push(\n          this.createRendererCall(\n            setAttributeCall,\n            [createStringLiteral(attribute.name!, transformContext), transformedValue],\n            attribute.node,\n            transformContext,\n          ),\n        );\n      }\n    }\n\n    statements.push(...this.outputJSXChildren(jsxElement.element, jsxElement.children, output, transformContext));\n\n    statements.push(this.createRendererCall('endRender', [], undefined, transformContext));\n    return statements;\n  }\n\n  private outputComponentViewModelProperties(\n    attributeStatements: JSXAttributeStatements,\n    nodeTypeStr: string,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    const statements: ts.Statement[] = [];\n\n    for (const attribute of attributeStatements.dynamicAttributes) {\n      if (attribute.value.kind === JSXAttributeValueKind.spread) {\n        statements.push(\n          this.createRendererCall('setViewModelProperties', [attribute.value.value], attribute.node, transformContext),\n        );\n      } else {\n        const transformedValueNode = this.transformNode(attribute.value.value, output, transformContext);\n        const transformedValue = this.toExpression(transformedValueNode, transformContext);\n        statements.push(\n          this.createRendererCall(\n            'setViewModelProperty',\n            [createStringLiteral(attribute.name!, transformContext), transformedValue],\n            attribute.node,\n            transformContext,\n          ),\n        );\n      }\n    }\n\n    return statements;\n  }\n\n  private insertChildrenToUnnamedSlot(children: ts.JsxChild[], slotteds: Slotted[]) {\n    for (const slot of slotteds) {\n      if (!slot.slotName) {\n        if (slotteds[slotteds.length - 1] !== slot) {\n          this.onError(\n            children[children.length - 1],\n            'All Elements or Components slotted into the default slot need to be direct siblings',\n          );\n        }\n\n        slot.expressions.push(...children);\n        return;\n      }\n    }\n\n    slotteds.push({\n      slotName: undefined,\n      expressions: children,\n    });\n  }\n\n  private isJsxText(child: ts.JsxChild): boolean {\n    if (!ts.isJsxText(child)) {\n      return false;\n    }\n\n    // Tolerance for `;` and whitespace characters in text, we just ignore them.\n    let value = child.text.replace(/(\\s|;)+/, '');\n\n    if (value) {\n      this.onError(child, 'Text elements are not supported in JSX. Use <label/> to render a text node.');\n    }\n\n    return true;\n  }\n\n  private isEmptyJsxExpression(child: ts.JsxChild): boolean {\n    if (!ts.isJsxExpression(child)) {\n      return false;\n    }\n\n    if (child.expression) {\n      return false;\n    }\n\n    return true;\n  }\n\n  private ensureImplicitSlottedNotUsedWithExplicit(\n    node: ts.Node,\n    hasExplicitSlotted: boolean,\n    hasImplicitSlotted: boolean,\n  ) {\n    if (hasExplicitSlotted && hasImplicitSlotted) {\n      this.onError(\n        node,\n        'Cannot mix implicitly slotted elements with explicitly slotted elements. Please either use <slotted/> for all children of the component, or remove <slotted/> from all children.',\n      );\n    }\n  }\n\n  private outputComponentChildren(\n    node: ts.Node,\n    children: ts.JsxChild[],\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    const slotteds: Slotted[] = [];\n    let hasExplicitSlotted = false;\n    let hasImplicitSlotted = false;\n\n    for (const child of children) {\n      if (this.isEmptyJsxExpression(child) || this.isJsxText(child)) {\n        continue;\n      }\n\n      if (ts.isJsxElement(child) && child.openingElement.tagName.getText() === 'slotted') {\n        hasExplicitSlotted = true;\n\n        const slotName = this.getSlotValueExpr(child.openingElement.attributes, output, transformContext);\n        if (slotName) {\n          slotteds.push({ slotName, expressions: child.children.map((item) => item) });\n        } else {\n          this.insertChildrenToUnnamedSlot(\n            child.children.map((item) => item),\n            slotteds,\n          );\n        }\n      } else if (ts.isJsxSelfClosingElement(child) && child.tagName.getText() === 'slotted') {\n        hasExplicitSlotted = true;\n\n        const slotName = this.getSlotValueExpr(child.attributes, output, transformContext);\n        if (slotName) {\n          slotteds.push({ slotName, expressions: [] });\n        } else {\n          this.insertChildrenToUnnamedSlot([], slotteds);\n        }\n      } else {\n        hasImplicitSlotted = true;\n\n        this.insertChildrenToUnnamedSlot([child], slotteds);\n      }\n\n      this.ensureImplicitSlottedNotUsedWithExplicit(node, hasExplicitSlotted, hasImplicitSlotted);\n    }\n\n    const statements: ts.Statement[] = [];\n\n    for (const slotted of slotteds) {\n      statements.push(...this.outputSlot(node, slotted.expressions, slotted.slotName, output, transformContext));\n    }\n\n    return statements;\n  }\n\n  private toParametersArray(\n    parameters: readonly (ts.Expression | undefined)[],\n    transformContext: ts.TransformationContext,\n  ): ts.Expression[] {\n    const trimmedParameters = [...parameters];\n    while (trimmedParameters.length && !trimmedParameters[trimmedParameters.length - 1]) {\n      trimmedParameters.pop();\n    }\n\n    return trimmedParameters.map((p) => p ?? transformContext.factory.createIdentifier('undefined'));\n  }\n\n  private outputRenderSlot(jsxElement: JSXElement, transformContext: ts.TransformationContext): ts.Statement {\n    let slotName: ts.Expression | undefined;\n    let slotRef: ts.Expression | undefined;\n    let slotKey: ts.Expression | undefined;\n    for (const attribute of jsxElement.attributes) {\n      if (attribute.name === 'name') {\n        slotName = attribute.value.value;\n      } else if (attribute.name === 'ref') {\n        slotRef = attribute.value.value;\n      } else if (attribute.name === 'key') {\n        slotKey = attribute.value.value;\n      } else {\n        this.onError(jsxElement.element, `Unsupported attribute '${attribute.name}' in slot`);\n      }\n    }\n\n    if (jsxElement.children.length) {\n      this.onError(jsxElement.element, 'Cannot declare children in a slot');\n    }\n\n    const thisParameter = transformContext.factory.createThis();\n\n    if (slotName) {\n      const parameters = [slotName, thisParameter, slotRef, slotKey];\n\n      return this.createRendererCall(\n        'renderNamedSlot',\n        this.toParametersArray(parameters, transformContext),\n        jsxElement.element,\n        transformContext,\n      );\n    } else {\n      const parameters = [thisParameter, slotRef, slotKey];\n\n      return this.createRendererCall(\n        'renderUnnamedSlot',\n        this.toParametersArray(parameters, transformContext),\n        jsxElement.element,\n        transformContext,\n      );\n    }\n  }\n\n  private getJsxNodeKind(tag: ts.JsxTagNameExpression, nodeTypeStr: string, output: JSXOutputState): JSXNodeKind {\n    if (ts.isIdentifier(tag)) {\n      const isIntrinsic = nodeTypeStr[0].toLowerCase() === nodeTypeStr[0];\n      if (isIntrinsic) {\n        if (nodeTypeStr === 'slot') {\n          return JSXNodeKind.slot;\n        } else {\n          if (nodeTypeStr === 'slotted') {\n            this.onError(tag, '\"slotted\" elements must be direct children of components');\n          }\n          return JSXNodeKind.element;\n        }\n      }\n    }\n\n    if (tag.kind === ts.SyntaxKind.JsxNamespacedName) {\n      this.onError(tag, 'JSX Namespaced Names are not supported');\n    }\n\n    const resolvedType = resolveTypeOfExpression(tag, output.typeChecker);\n\n    const symbol = resolvedType.effectiveObjectInfo?.symbol;\n    if ((symbol && symbol.flags & ts.SymbolFlags.Function) || resolvedType.effectiveType === SymbolType.function) {\n      return JSXNodeKind.functionComponent;\n    }\n\n    // Consider any expressions as constructors\n    return JSXNodeKind.component;\n  }\n\n  private outputJSXElement(\n    jsxElement: JSXElement,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n    nodeTypeStr: string,\n    attributeStatements: JSXAttributeStatements,\n  ): JSXNodeOutput {\n    let makeNodePrototypeParams: ts.Expression[] = [createStringLiteral(nodeTypeStr, transformContext)];\n\n    if (attributeStatements.staticAttributesLiteral) {\n      makeNodePrototypeParams.push(attributeStatements.staticAttributesLiteral);\n    }\n\n    const nodeIdentifier = this.appendInitializedVariable(\n      '__node',\n      nodeTypeStr,\n      this.createRendererCallExpr('makeNodePrototype', makeNodePrototypeParams, transformContext),\n      output,\n      transformContext,\n    );\n\n    const keyOrUndefined = attributeStatements.key || transformContext.factory.createIdentifier('undefined');\n\n    if (attributeStatements.lazy) {\n      const beginIfNeeded = this.createRendererCallExpr(\n        'beginRenderIfNeeded',\n        [nodeIdentifier, keyOrUndefined],\n        transformContext,\n      );\n\n      const innerStatements = this.outputElementInner(jsxElement, attributeStatements, output, transformContext);\n      const endRenderStatement = innerStatements[innerStatements.length - 1];\n\n      const beginRenderStatement = transformContext.factory.createIfStatement(\n        beginIfNeeded,\n        transformContext.factory.createBlock(innerStatements),\n      );\n      return {\n        beginRenderStatement,\n        endRenderStatement,\n        statements: [beginRenderStatement],\n      };\n    } else {\n      const beginRenderStatement = this.createRendererCall(\n        'beginRender',\n        [nodeIdentifier, keyOrUndefined],\n        undefined,\n        transformContext,\n      );\n      const statements: ts.Statement[] = [];\n      statements.push(beginRenderStatement);\n      statements.push(...this.outputElementInner(jsxElement, attributeStatements, output, transformContext));\n      const endRenderStatement = statements[statements.length - 1];\n\n      return {\n        beginRenderStatement,\n        endRenderStatement,\n        statements,\n      };\n    }\n  }\n\n  private outputJSXSlot(\n    jsxElement: JSXElement,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n    nodeTypeStr: string,\n    attributeStatements: JSXAttributeStatements,\n  ): JSXNodeOutput {\n    const beginRenderStatement = this.outputRenderSlot(jsxElement, transformContext);\n    return {\n      beginRenderStatement,\n      endRenderStatement: undefined,\n      statements: [beginRenderStatement],\n    };\n  }\n\n  private throwInvalidJSXFunctionComponentAttribute(jsxElement: JSXElement, attributeName: string) {\n    this.onError(jsxElement.element, `'${attributeName}' attribute is not supported in Inline Function Components`);\n  }\n\n  private outputJSXFunctionComponent(\n    jsxElement: JSXElement,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n    nodeTypeStr: string,\n    attributeStatements: JSXAttributeStatements,\n  ): JSXNodeOutput {\n    if (attributeStatements.key) {\n      this.throwInvalidJSXFunctionComponentAttribute(jsxElement, 'key');\n    }\n    if (attributeStatements.lazy) {\n      this.throwInvalidJSXFunctionComponentAttribute(jsxElement, 'lazy');\n    }\n    if (attributeStatements.slot) {\n      this.throwInvalidJSXFunctionComponentAttribute(jsxElement, 'slot');\n    }\n    if (attributeStatements.nodeRef) {\n      this.throwInvalidJSXFunctionComponentAttribute(jsxElement, 'ref');\n    }\n\n    const transformedNodes = jsxElement.children\n      .filter((child) => !(this.isEmptyJsxExpression(child) || this.isJsxText(child)))\n      .map((child) => this.transformNode(child, output, transformContext));\n\n    const viewModelProperties: ts.ObjectLiteralElementLike[] = [];\n\n    for (const attribute of attributeStatements.allAttributes) {\n      if (attribute.name) {\n        viewModelProperties.push(\n          transformContext.factory.createPropertyAssignment(\n            transformContext.factory.createIdentifier(attribute.name),\n            attribute.value.value,\n          ),\n        );\n      } else {\n        if (attribute.value.kind !== JSXAttributeValueKind.spread) {\n          this.onError(attribute.node, 'Unexpectedly got attribute without a name');\n        }\n\n        viewModelProperties.push(transformContext.factory.createSpreadAssignment(attribute.value.value));\n      }\n    }\n\n    if (transformedNodes.length) {\n      const renderFunction = transformContext.factory.createArrowFunction(\n        undefined,\n        undefined,\n        [],\n        undefined,\n        undefined,\n        this.toBlock(\n          transformedNodes.map((node) => this.toStatement(node, transformContext)),\n          transformContext,\n        ),\n      );\n      viewModelProperties.push(\n        transformContext.factory.createPropertyAssignment(\n          transformContext.factory.createIdentifier('children'),\n          renderFunction,\n        ),\n      );\n    }\n\n    const viewModelLiteral = transformContext.factory.createObjectLiteralExpression(viewModelProperties, true);\n\n    if (jsxElement.element.tagName.kind === ts.SyntaxKind.JsxNamespacedName) {\n      this.onError(jsxElement.nodeType, 'JSX Namespaced Names are not supported');\n    }\n\n    const statement = this.createRendererCall(\n      'renderFnComponent',\n      [jsxElement.element.tagName, viewModelLiteral],\n      jsxElement.element,\n      transformContext,\n    );\n\n    return {\n      beginRenderStatement: statement,\n      endRenderStatement: undefined,\n      statements: [statement],\n    };\n  }\n\n  private outputJSXComponent(\n    jsxElement: JSXElement,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n    nodeTypeStr: string,\n    attributeStatements: JSXAttributeStatements,\n  ): JSXNodeOutput {\n    let makeComponentPrototypeParams: ts.Expression[] = [];\n\n    if (attributeStatements.staticAttributesLiteral) {\n      makeComponentPrototypeParams.push(attributeStatements.staticAttributesLiteral);\n    }\n\n    const componentIdentifier = this.appendInitializedVariable(\n      '__component',\n      nodeTypeStr,\n      this.createRendererCallExpr('makeComponentPrototype', makeComponentPrototypeParams, transformContext),\n      output,\n      transformContext,\n    );\n\n    const componentRef = attributeStatements.nodeRef ?? transformContext.factory.createIdentifier('undefined');\n    if (jsxElement.nodeType.kind === ts.SyntaxKind.JsxNamespacedName) {\n      this.onError(jsxElement.nodeType, 'JSX Namespaced Names are not supported');\n    }\n    const beginRenderStatement = this.createRendererCall(\n      'beginComponent',\n      [\n        jsxElement.nodeType,\n        componentIdentifier,\n        attributeStatements.key || transformContext.factory.createIdentifier('undefined'),\n        componentRef,\n      ],\n      undefined,\n      transformContext,\n    );\n\n    const statements: ts.Statement[] = [];\n    statements.push(beginRenderStatement);\n\n    if (attributeStatements.componentContext) {\n      let foundComponentContext: boolean;\n      if (ts.isIdentifier(attributeStatements.componentContext)) {\n        foundComponentContext = attributeStatements.componentContext.text !== 'undefined';\n      } else {\n        foundComponentContext = isExpressionNode(attributeStatements.componentContext);\n      }\n\n      if (foundComponentContext) {\n        const hasContextCallExpr = this.createRendererCallExpr('hasContext', [], transformContext);\n        const setContextCall = this.createRendererCall(\n          'setContext',\n          [attributeStatements.componentContext],\n          attributeStatements.componentContext,\n          transformContext,\n        );\n\n        const ifStatement = transformContext.factory.createIfStatement(\n          transformContext.factory.createPrefixUnaryExpression(ts.SyntaxKind.ExclamationToken, hasContextCallExpr),\n          transformContext.factory.createBlock([setContextCall]),\n        );\n        statements.push(ifStatement);\n      }\n    }\n\n    statements.push(\n      ...this.outputComponentViewModelProperties(attributeStatements, nodeTypeStr, output, transformContext),\n    );\n\n    for (const injectedAttribute of attributeStatements.injectedAttributes) {\n      const transformedValueNode = this.transformNode(injectedAttribute.value.value, output, transformContext);\n      const transformedValue = this.toExpression(transformedValueNode, transformContext);\n      statements.push(\n        this.createRendererCall(\n          'setInjectedAttribute',\n          [createStringLiteral(injectedAttribute.name!, transformContext), transformedValue],\n          injectedAttribute.node,\n          transformContext,\n        ),\n      );\n    }\n\n    statements.push(...this.outputComponentChildren(jsxElement.element, jsxElement.children, output, transformContext));\n\n    const endRenderStatement = this.createRendererCall('endComponent', [], undefined, transformContext);\n    statements.push(endRenderStatement);\n\n    return {\n      beginRenderStatement,\n      endRenderStatement,\n      statements,\n    };\n  }\n\n  private outputJSX(\n    jsxElement: JSXElement,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    const nodeTypeStr = jsxElement.nodeType.getText();\n\n    const nodeKind = this.getJsxNodeKind(jsxElement.nodeType, nodeTypeStr, output);\n    const attributeStatements = this.resolveJSXAttributeStatements(nodeKind, jsxElement, transformContext);\n\n    let nodeOutput: JSXNodeOutput;\n\n    switch (nodeKind) {\n      case JSXNodeKind.element:\n        nodeOutput = this.outputJSXElement(jsxElement, output, transformContext, nodeTypeStr, attributeStatements);\n        break;\n      case JSXNodeKind.slot:\n        nodeOutput = this.outputJSXSlot(jsxElement, output, transformContext, nodeTypeStr, attributeStatements);\n        break;\n      case JSXNodeKind.component:\n        nodeOutput = this.outputJSXComponent(jsxElement, output, transformContext, nodeTypeStr, attributeStatements);\n        break;\n      case JSXNodeKind.functionComponent:\n        nodeOutput = this.outputJSXFunctionComponent(\n          jsxElement,\n          output,\n          transformContext,\n          nodeTypeStr,\n          attributeStatements,\n        );\n        break;\n    }\n\n    ts.setTextRange(nodeOutput.beginRenderStatement, jsxElement.element.tagName);\n    if (nodeOutput.endRenderStatement) {\n      if (jsxElement.closingElement) {\n        ts.setTextRange(nodeOutput.endRenderStatement, jsxElement.closingElement.tagName);\n      } else if (ts.isJsxSelfClosingElement(jsxElement.element)) {\n        // We set the text range of the endComponent/endRender on the slash element\n        // of the self closing element.\n        let slashElement: ts.Node | undefined;\n        for (const child of jsxElement.element.getChildren()) {\n          if (child.kind === ts.SyntaxKind.SlashToken) {\n            slashElement = child;\n          }\n        }\n\n        if (slashElement) {\n          ts.setTextRange(nodeOutput.endRenderStatement, slashElement);\n        } else {\n          this.logger?.error?.('Could not find Slash element in JSX self closing element');\n        }\n      }\n    }\n\n    return nodeOutput.statements;\n  }\n\n  private findDeclarationsInsertionIndex(previousStatements: ts.NodeArray<ts.Statement>): number {\n    for (let i = 0; i < previousStatements.length; i++) {\n      const statement = previousStatements[i];\n\n      if (\n        ts.isExpressionStatement(statement) &&\n        ts.isStringLiteral(statement.expression) &&\n        statement.expression.text === 'use strict'\n      ) {\n        return i + 1;\n      }\n    }\n\n    return 0;\n  }\n\n  private injectDeclarations(\n    node: ts.SourceFile,\n    outputState: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.SourceFile {\n    const requireCall = transformContext.factory.createCallExpression(\n      transformContext.factory.createIdentifier('require'),\n      undefined,\n      [createStringLiteral(rendererModulePath, transformContext)],\n    );\n    const accessToJsx = transformContext.factory.createPropertyAccessExpression(requireCall, 'jsx');\n\n    const rendererVariableStatement = this.createConstVariable('__Renderer', accessToJsx, transformContext);\n    outputState.nodePrototypeDeclarations.splice(0, 0, rendererVariableStatement);\n\n    const allStatements: ts.Statement[] = [];\n\n    const insertionIndex = this.findDeclarationsInsertionIndex(node.statements);\n\n    for (const oldStatement of node.statements) {\n      allStatements.push(oldStatement);\n    }\n\n    allStatements.splice(insertionIndex, 0, ...outputState.nodePrototypeDeclarations);\n\n    return this.doUpdateSourceFileNode(node, allStatements, transformContext);\n  }\n\n  private processJSXElement(\n    node: ts.JsxElement,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    const attributes = this.extractJSXAttributes(node.openingElement.attributes, output, transformContext);\n\n    const children: ts.JsxChild[] = [];\n    for (const child of node.children) {\n      children.push(child);\n    }\n\n    return this.outputJSX(\n      {\n        element: node.openingElement,\n        closingElement: node.closingElement,\n        nodeType: node.openingElement.tagName,\n        attributes,\n        children,\n      },\n      output,\n      transformContext,\n    );\n  }\n\n  private processSelfClosingJSXElement(\n    node: ts.JsxSelfClosingElement,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Statement[] {\n    const attributes = this.extractJSXAttributes(node.attributes, output, transformContext);\n\n    return this.outputJSX(\n      {\n        element: node,\n        closingElement: undefined,\n        nodeType: node.tagName,\n        attributes,\n        children: [],\n      },\n      output,\n      transformContext,\n    );\n  }\n\n  private logNode(node: ts.Node, state: JSXOutputState) {\n    let indent = '';\n    for (let i = 0; i < state.nodeDepth; i++) {\n      indent += '  ';\n    }\n    console.log(`${indent}Processing node: ${node.kind}`);\n  }\n\n  /**\n   * Merge any added blocks into the statements list\n   */\n  private flattenBlocks(\n    node: ts.Node,\n    previousStatements: ts.NodeArray<ts.Node> | ts.Node[],\n    newStatements: ts.Statement[],\n  ): ts.Statement[] {\n    if (newStatements.length !== previousStatements.length) {\n      this.onError(\n        node,\n        `Invalid output statements, had length ${previousStatements.length} new length ${newStatements.length}`,\n      );\n    }\n\n    const out: ts.Statement[] = [];\n\n    for (let i = 0; i < previousStatements.length; i++) {\n      const oldStatement = previousStatements[i];\n      const newStatement = newStatements[i];\n\n      if (ts.isBlock(newStatement) && !ts.isBlock(oldStatement)) {\n        // We created a block, merge its content into the statements\n        out.push(...newStatement.statements);\n      } else {\n        out.push(newStatement);\n      }\n    }\n\n    return out;\n  }\n\n  private doUpdateSourceFileNode(\n    node: ts.SourceFile,\n    newStatements: ts.Statement[],\n    transformContext: ts.TransformationContext,\n  ): ts.SourceFile {\n    const newNode = transformContext.factory.updateSourceFile(\n      node,\n      newStatements,\n      undefined,\n      undefined,\n      undefined,\n      undefined,\n      undefined,\n    );\n    ts.addEmitHelpers(newNode, transformContext.readEmitHelpers());\n    return newNode;\n  }\n\n  private transformSourceFile(\n    node: ts.SourceFile,\n    outputState: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.SourceFile {\n    const newStatements: ts.Statement[] = [];\n\n    for (const statement of node.statements) {\n      const result = this.transformNode(statement, outputState, transformContext);\n      newStatements.push(this.toStatement(result, transformContext));\n    }\n\n    return this.doUpdateSourceFileNode(\n      node,\n      this.flattenBlocks(node, node.statements, newStatements),\n      transformContext,\n    );\n  }\n\n  private transformNode(\n    node: ts.Node,\n    outputState: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Node {\n    // this.logNode(node, outputState);\n\n    outputState.nodeDepth++;\n\n    try {\n      if (ts.isJsxElement(node)) {\n        const result = this.processJSXElement(node, outputState, transformContext);\n        return this.mergeStatements(result, transformContext);\n      } else if (ts.isJsxSelfClosingElement(node)) {\n        const result = this.processSelfClosingJSXElement(node, outputState, transformContext);\n        return this.mergeStatements(result, transformContext);\n      }\n\n      if (ts.isExpressionStatement(node)) {\n        const result = this.transformNode(node.expression, outputState, transformContext);\n        if (isExpressionNode(result)) {\n          return transformContext.factory.updateExpressionStatement(node, result);\n        }\n        // We are not an expression anymore\n        return result;\n      }\n\n      if (ts.isJsxExpression(node) && node.expression) {\n        const result = this.transformNode(node.expression, outputState, transformContext);\n        if (isExpressionNode(result)) {\n          return transformContext.factory.updateJsxExpression(node, result);\n        }\n        return result;\n      }\n\n      if (ts.isParenthesizedExpression(node)) {\n        const result = this.transformNode(node.expression, outputState, transformContext);\n        if (isExpressionNode(result)) {\n          return transformContext.factory.updateParenthesizedExpression(node, result);\n        }\n\n        return result;\n      }\n\n      if (ts.isBlock(node)) {\n        const statements = node.statements.map((statement) =>\n          this.toStatement(this.transformNode(statement, outputState, transformContext), transformContext),\n        );\n\n        const newStatements = this.flattenBlocks(node, node.statements, statements);\n        return transformContext.factory.updateBlock(node, newStatements);\n      }\n\n      return ts.visitEachChild(\n        node,\n        (childNode) => this.transformNodeGeneric(node, childNode, outputState, transformContext),\n        transformContext,\n      );\n    } finally {\n      outputState.nodeDepth--;\n    }\n  }\n\n  // A version of transformNode which which will ensure that we transform statements into expressions\n  // if our node was an expression\n  private transformNodeGeneric(\n    parent: ts.Node,\n    node: ts.Node,\n    outputState: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): ts.Node {\n    const result = this.transformNode(node, outputState, transformContext);\n\n    if (isExpressionNode(node) && !isExpressionNode(result)) {\n      if (ts.isArrowFunction(parent) && parent.body === node) {\n        // Special case for arrow functions, we don't need to convert them to expression since\n        // the body can be a statement\n        return result;\n      }\n\n      // We were an expression but we are not anymore, convert to an expression\n      return this.toExpression(result, transformContext);\n    }\n\n    return result;\n  }\n\n  private onError(node: ts.Node, message: string): never {\n    const { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());\n    throw new Error(`${message} at (${line + 1},${character + 1}) (node content: ${node.getText()})`);\n  }\n\n  private log(node: ts.Node, message: string) {\n    const { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());\n    console.log(`(${line + 1},${character + 1}) with type '${node.kind}' (node content: ${node.getText()}: ${message}`);\n  }\n\n  private onUnexpectedNodeKind(node: ts.Node) {\n    this.onError(node, `Unexpectedly got node kind ${node.kind}`);\n  }\n\n  private checkNodeKind(node: ts.Node, expectedKind: ts.SyntaxKind) {\n    if (node.kind !== expectedKind) {\n      this.onError(node, `Unexpectedly got node kind ${node.kind} (expected ${expectedKind})`);\n    }\n  }\n\n  private isExpressionNonStaticMethodDeclaration(expression: ts.Expression, output: JSXOutputState): boolean {\n    const resolvedType = resolveTypeOfExpression(expression, output.typeChecker);\n\n    return (\n      resolvedType.effectiveType === SymbolType.function &&\n      resolvedType.effectiveObjectInfo?.declaration?.kind === ts.SyntaxKind.MethodDeclaration &&\n      (ts.getCombinedModifierFlags(resolvedType.effectiveObjectInfo.declaration) & ts.ModifierFlags.Static) === 0\n    );\n  }\n\n  private getJSXAttributeValue(value: ts.Node, output: JSXOutputState): JSXAttributeValue {\n    if (value.kind === ts.SyntaxKind.JsxExpression) {\n      const children = value.getChildren();\n\n      if (children.length !== 3) {\n        this.onError(value, `Should have 3 tokens (got ${children.length})`);\n      }\n\n      const expression = children[1];\n\n      if (expression.kind === ts.SyntaxKind.NumericLiteral || expression.kind === ts.SyntaxKind.StringLiteral) {\n        // Shortcut for numeric and string literals, they are never changing so we can consider them constants\n        return {\n          value: expression as ts.LiteralExpression,\n          kind: JSXAttributeValueKind.static,\n        };\n      }\n\n      if (\n        ts.isPropertyAccessExpression(expression) &&\n        this.isExpressionNonStaticMethodDeclaration(expression, output)\n      ) {\n        this.onError(\n          value,\n          'Resolved TSX attribute value is a method declaration. Please make sure to use a lambda as a stored property to avoid unintentional scoping of `this`, for example `private yourLambdaProperty = () => { ... }`',\n        );\n      }\n\n      return {\n        value: expression as ts.Expression,\n        kind: JSXAttributeValueKind.dynamic,\n      };\n    } else {\n      return {\n        value: value as ts.Expression,\n        kind: JSXAttributeValueKind.static,\n      };\n    }\n  }\n\n  private extractJSXAttribute(\n    attribute: ts.Node,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): JSXAttribute {\n    const children = attribute.getChildren();\n    if (!children.length) {\n      this.onError(attribute, 'Could not resolve JSX attribute');\n    }\n\n    this.checkNodeKind(children[0], ts.SyntaxKind.Identifier);\n    if (children.length != 1 && children.length !== 3) {\n      this.onError(attribute, `Should have 1 or 3 tokens (got ${children.length})`);\n    }\n\n    const name = children[0].getText();\n\n    if (name.indexOf('-') >= 0) {\n      this.onError(attribute, `JSX attributes cannot contain dashes`);\n    }\n\n    let value: JSXAttributeValue;\n\n    if (children.length === 3) {\n      value = this.getJSXAttributeValue(children[2], output);\n    } else {\n      value = {\n        value: transformContext.factory.createTrue(),\n        kind: JSXAttributeValueKind.static,\n      };\n    }\n\n    return {\n      node: attribute,\n      name,\n      value,\n    };\n  }\n\n  private extractJSXSpreadAttribute(node: ts.Node): JSXAttributeValue {\n    const children = node.getChildren();\n    if (children.length !== 4) {\n      this.onError(node, `Should have 4 tokens (got ${children.length})`);\n    }\n\n    const object = children[2];\n    return {\n      value: object as ts.Expression,\n      kind: JSXAttributeValueKind.spread,\n    };\n  }\n\n  private extractJSXAttributes(\n    node: ts.Node,\n    output: JSXOutputState,\n    transformContext: ts.TransformationContext,\n  ): JSXAttribute[] {\n    const jsxAttributes: JSXAttribute[] = [];\n    ts.forEachChild(node, (attribute) => {\n      switch (attribute.kind) {\n        case ts.SyntaxKind.JsxAttribute:\n          {\n            let jsxAttribute = this.extractJSXAttribute(attribute, output, transformContext);\n            jsxAttributes.push(jsxAttribute);\n          }\n          break;\n        case ts.SyntaxKind.JsxSpreadAttribute:\n          {\n            let jsxAttribute = this.extractJSXSpreadAttribute(attribute);\n            jsxAttributes.push({\n              node: attribute,\n              name: undefined,\n              value: jsxAttribute,\n            });\n          }\n          break;\n        default:\n          this.onUnexpectedNodeKind(node);\n      }\n    });\n\n    return jsxAttributes;\n  }\n\n  static createFromFile(fileName: string, fileContent: string, includeSourceMapping: boolean): JSXFileProcessor {\n    return new JSXFileProcessor(fileName, fileContent, includeSourceMapping);\n  }\n}\n\nexport class JSXFileProcessor extends JSXProcessor {\n  private fileName: string;\n  private fileContent: string;\n  private includeSourceMapping: boolean;\n\n  constructor(fileName: string, fileContent: string, includeSourceMapping: boolean) {\n    super();\n    this.fileName = fileName;\n    this.fileContent = fileContent;\n    this.includeSourceMapping = includeSourceMapping;\n  }\n\n  process(): string {\n    let compilerOptions: ts.CompilerOptions = {\n      target: ts.ScriptTarget.ES2019,\n      jsx: ts.JsxEmit.Preserve,\n      removeComments: false,\n    };\n\n    if (this.includeSourceMapping) {\n      compilerOptions.sourceMap = true;\n      compilerOptions.sourceRoot = '/';\n      compilerOptions.inlineSourceMap = true;\n      // Uncomment to enable show sources in safari debugger\n      // compilerOptions.inlineSources = true;\n    }\n\n    const transpiler = new Transpiler(this.fileContent, {\n      compilerOptions: compilerOptions,\n      fileName: this.fileName,\n    });\n\n    const transforms = this.makeTransformers(transpiler.program.getTypeChecker());\n    transforms.push(createConsoleLogTransformer());\n    const result = transpiler.transpile({ before: transforms });\n\n    let compiledJs = result.outputText;\n\n    if (this.includeSourceMapping) {\n      compiledJs = mergeSourceMaps(this.fileContent, compiledJs);\n    }\n\n    return compiledJs;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/ObjectiveCWriter.ts",
    "content": "import { IOutputWriter, OutputWriter } from './OutputWriter';\n\nclass ObjectiveCImports implements IOutputWriter {\n  private imports = new Set<string>();\n  private allImports: string[] = [];\n\n  append(importPath: string): boolean {\n    if (this.imports.has(importPath)) {\n      return false;\n    }\n    this.imports.add(importPath);\n\n    this.allImports.push(`#import ${importPath}`);\n\n    return true;\n  }\n\n  content(): string {\n    if (!this.allImports.length) {\n      return '';\n    }\n\n    const importsStatemenents = this.allImports.join('\\n');\n\n    return `\\n${importsStatemenents}\\n\\n`;\n  }\n}\n\nexport class ObjectiveCWriter extends OutputWriter {\n  private imports = new ObjectiveCImports();\n  private didAddImport = false;\n\n  appendImport(importPath: string): boolean {\n    if (!this.didAddImport) {\n      this.didAddImport = true;\n      this.append(this.imports);\n    }\n\n    return this.imports.append(importPath);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/OutputWriter.ts",
    "content": "function makeIndent(indent: number): string {\n  let out = '';\n\n  for (let i = 0; i < indent; i++) {\n    out += '  ';\n  }\n\n  return out;\n}\n\nexport interface IOutputWriter {\n  content(): string;\n}\n\ntype OutputWriterContent = string | IOutputWriter;\n\nfunction outputContent(contents: OutputWriterContent[]): string {\n  let output = '';\n\n  for (const content of contents) {\n    if ((content as IOutputWriter).content) {\n      output += (content as IOutputWriter).content();\n    } else {\n      output += content;\n    }\n  }\n\n  return output;\n}\n\nclass IndentedContent implements IOutputWriter {\n  constructor(readonly written: OutputWriterContent[], readonly indentation: string) {}\n\n  content(): string {\n    let content = outputContent(this.written);\n    const lines = content.split('\\n');\n\n    const processedLines = lines.map((line) => (line ? this.indentation + line : line));\n    return processedLines.join('\\n');\n  }\n}\n\ninterface Indentation {\n  indentation: string;\n  previouslyWritten: OutputWriterContent[];\n}\n\nexport class OutputWriter implements IOutputWriter {\n  private written: OutputWriterContent[] = [];\n  private indentations: Indentation[] = [];\n\n  get writtenLength(): number {\n    return this.written.length;\n  }\n\n  append(str: string | IOutputWriter) {\n    this.written.push(str);\n  }\n\n  content(): string {\n    return outputContent(this.written);\n  }\n\n  beginIndent(indentation: string) {\n    const written = this.written;\n    this.written = [];\n    this.indentations.push({ indentation, previouslyWritten: written });\n  }\n\n  endIndent() {\n    const indentation = this.indentations.pop();\n    if (!indentation) {\n      throw new Error('Unbalanced beginIndent/endIndent');\n    }\n    const writtenWithIdentation = this.written;\n    this.written = indentation.previouslyWritten;\n    if (writtenWithIdentation.length) {\n      this.append(new IndentedContent(writtenWithIdentation, indentation.indentation));\n    }\n  }\n\n  withIndentation(indentation: string, cb: () => void) {\n    this.beginIndent(indentation);\n    cb();\n    this.endIndent();\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/SourceMapUtils.ts",
    "content": "import * as SourceMapModule from 'source-map';\nimport * as path from 'path';\n\nexport const SOURCE_MAP_PREFIX = `//# sourceMappingURL=data:application/json;base64,`;\n\nexport function getRawSourceMap(fileContent: string): SourceMapModule.RawSourceMap | undefined {\n  const index = fileContent.indexOf(SOURCE_MAP_PREFIX);\n  if (index < 0) {\n    return undefined;\n  }\n\n  const str = fileContent.substr(SOURCE_MAP_PREFIX.length + index);\n  const sourceMapJson = Buffer.from(str, 'base64').toString('utf8');\n  return JSON.parse(sourceMapJson) as SourceMapModule.RawSourceMap;\n}\n\nexport function getSourceMap(fileContent: string): SourceMapModule.SourceMapConsumer | undefined {\n  const rawSourceMap = getRawSourceMap(fileContent);\n  if (!rawSourceMap) {\n    return undefined;\n  }\n  return new SourceMapModule.SourceMapConsumer(rawSourceMap);\n}\n\nfunction insertGeneratedPosition(line: number, column: number, generatedKeys: { [key: string]: boolean }): boolean {\n  const key = `${line}:${column}`;\n  if (generatedKeys[key]) {\n    return false;\n  }\n  generatedKeys[key] = true;\n  return true;\n}\n\nexport function mergeSourceMaps(originalFile: string, generatedFile: string): string {\n  const rawOriginalSourceMap = getRawSourceMap(originalFile);\n  if (!rawOriginalSourceMap) {\n    return generatedFile;\n  }\n\n  const rawGeneratedSourceMap = getRawSourceMap(generatedFile);\n  if (!rawGeneratedSourceMap) {\n    return generatedFile;\n  }\n\n  if (rawOriginalSourceMap.sources.length !== 1 || rawGeneratedSourceMap.sources.length !== 1) {\n    throw new Error(\n      `Can only merge source maps from a single source. Got ${rawOriginalSourceMap.sources} and ${rawGeneratedSourceMap.sources}`,\n    );\n  }\n\n  let originalFileName = rawOriginalSourceMap.sources[0];\n  let intermediateFileName = rawGeneratedSourceMap.sources[0];\n  const sourceToUse = originalFileName;\n\n  if (rawOriginalSourceMap.sourceRoot) {\n    originalFileName = path.resolve(rawOriginalSourceMap.sourceRoot, originalFileName);\n  }\n\n  if (rawGeneratedSourceMap.sourceRoot) {\n    intermediateFileName = path.resolve(rawGeneratedSourceMap.sourceRoot, intermediateFileName);\n  }\n\n  const originalSourceMap = new SourceMapModule.SourceMapConsumer(rawOriginalSourceMap);\n  const generatedSourceMap = new SourceMapModule.SourceMapConsumer(rawGeneratedSourceMap);\n\n  let generator = new SourceMapModule.SourceMapGenerator({\n    file: rawGeneratedSourceMap.file,\n    sourceRoot: rawGeneratedSourceMap.sourceRoot,\n  });\n\n  let generatedKeys: { [key: string]: boolean } = {};\n\n  // Add the new mappings, potentially updating the original position\n  generatedSourceMap.eachMapping((mapping) => {\n    const originalPosition = originalSourceMap.originalPositionFor({\n      line: mapping.originalLine,\n      column: mapping.originalColumn,\n    });\n\n    if (originalPosition.line) {\n      if (!insertGeneratedPosition(mapping.generatedLine, mapping.generatedColumn, generatedKeys)) {\n        return;\n      }\n\n      generator.addMapping({\n        original: { line: originalPosition.line, column: originalPosition.column },\n        generated: { line: mapping.generatedLine, column: mapping.generatedColumn },\n        source: sourceToUse,\n        name: mapping.name,\n      });\n    }\n  });\n\n  // Add the original mappings, potentially updating the generated position\n  originalSourceMap.eachMapping((mapping) => {\n    const generatedPosition = generatedSourceMap.generatedPositionFor({\n      line: mapping.generatedLine,\n      column: mapping.generatedColumn,\n      source: intermediateFileName,\n    });\n\n    if (generatedPosition.line) {\n      if (!insertGeneratedPosition(generatedPosition.line, generatedPosition.column, generatedKeys)) {\n        return;\n      }\n\n      generator.addMapping({\n        original: { line: mapping.originalLine, column: mapping.originalColumn },\n        generated: {\n          line: generatedPosition.line,\n          column: generatedPosition.column,\n        },\n        source: sourceToUse,\n        name: mapping.name,\n      });\n    }\n  });\n\n  if (rawOriginalSourceMap.sourcesContent && rawOriginalSourceMap.sourcesContent.length === 1) {\n    generator.setSourceContent(sourceToUse, rawOriginalSourceMap.sourcesContent[0]);\n  }\n\n  const index = generatedFile.indexOf(SOURCE_MAP_PREFIX);\n\n  let buffer = Buffer.from(generator.toString());\n  let base64data = buffer.toString('base64');\n\n  const filePrefix = generatedFile.substr(0, index);\n\n  return `${filePrefix}${SOURCE_MAP_PREFIX}${base64data}`;\n}\n"
  },
  {
    "path": "compiler/companion/src/TSUtils.spec.ts",
    "content": "import 'ts-jest';\nimport * as ts from 'typescript';\nimport { findNode, resolveTypeOfExpression, isExpressionNode, SymbolType, getRootNodesToDump } from './TSUtils';\nimport { Project } from './project/Project';\n\ninterface CompiledFile {\n  sourceFile: ts.Node;\n  expression: ts.Expression;\n  typeChecker: ts.TypeChecker;\n}\n\nfunction compile(str: string): CompiledFile {\n  const project = new Project('/', {\n    strict: true,\n    strictNullChecks: true,\n  });\n  const sourceFile = project.createSourceFile('File.ts', str);\n\n  const node = findNode(sourceFile, undefined, (node) => isExpressionNode(node));\n  if (!node) {\n    throw new Error('Cannot resolve expression node');\n  }\n\n  return {\n    sourceFile: sourceFile,\n    expression: node as ts.Expression,\n    typeChecker: project.typeChecker,\n  };\n}\n\ndescribe('TSUtils', () => {\n  it('can find types to dump', () => {\n    const result = compile(\n      `class Component<VM> {\n\n      }\n\n      // @ExportProxy({ios: 'SCTCallGridParticipant', android: 'com.snap.talk.SCTCallGridParticipant'})\n      interface Participant {\n        displayName: string;\n        color: string;\n        hasVideo: boolean;\n      }\n\n      /* @ViewModel\n      @ExportModel({ios: 'SCTCallGridViewModel', android: 'com.snap.talk.CallGridViewModel'}) */\n      interface CallGridViewModel {\n        participants: Participant[];\n        foo: number;\n        bar: string;\n      }\n\n      /**\n       * @Component\n       * @ExportModel({ios: 'SCTCallGrid, android: 'com.snap.talk.CallGrid'})\n       */\n      export class CallGrid extends Component<CallGridViewModel> {\n        // @Action\n        someAction() {\n\n        }\n\n        onRender() {\n          <layout></layout>;\n        }\n      }\n    `,\n    );\n\n    const typesToDump = getRootNodesToDump(result.sourceFile, (nodeToDump) => {\n      if (!nodeToDump.leadingComments) {\n        return false;\n      }\n\n      return nodeToDump.leadingComments.text?.trim().length > 0;\n    });\n    expect(typesToDump.length).toEqual(3);\n  });\n\n  it('can resolve type of number literals', () => {\n    const result = compile(`42`);\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.number);\n    expect(resolvedType.isNullable).toEqual(false);\n  });\n\n  it('can resolve type of string literals', () => {\n    const result = compile(`'42'`);\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.string);\n    expect(resolvedType.isNullable).toEqual(false);\n  });\n\n  it('can resolve type of compound number expressions', () => {\n    const result = compile(`(42 * 2 / 9)`);\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.number);\n    expect(resolvedType.isNullable).toEqual(false);\n  });\n\n  it('can resolve type of optional numbers', () => {\n    const result = compile(\n      `\n    declare function getMeANumber(): number | undefined;\n    getMeANumber();\n    `,\n    );\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.number);\n    expect(resolvedType.isNullable).toEqual(true);\n  });\n\n  it('can resolve type of optional strings', () => {\n    const result = compile(\n      `\n    declare function getMeAString(): string | undefined;\n    getMeAString();\n    `,\n    );\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.string);\n    expect(resolvedType.isNullable).toEqual(true);\n  });\n\n  it('resolves union unrelated types to any', () => {\n    const result = compile(\n      `\n    declare function getMeAStringOrNumber(): string | number | undefined;\n    getMeAStringOrNumber();\n    `,\n    );\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.any);\n    expect(resolvedType.isNullable).toEqual(true);\n  });\n\n  it('resolves object type', () => {\n    const result = compile(\n      `\n    interface MyObject {}\n    declare function getMeAnObject(): MyObject;\n    getMeAnObject();\n    `,\n    );\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.object);\n    expect(resolvedType.isNullable).toEqual(false);\n\n    const objectInfo = resolvedType.resolvedSymbols[0]?.objectInfo!;\n    expect(objectInfo).toBeDefined();\n    expect(objectInfo.name).toBe('MyObject');\n\n    const fileName = objectInfo.declaration?.getSourceFile()?.fileName!;\n    expect(fileName).toBeDefined();\n\n    expect(fileName.endsWith('/File.ts')).toBeTruthy();\n  });\n\n  it('resolves function type from lambda', () => {\n    const result = compile(\n      `\n    declare function getMeAFunction(): () => void;\n    getMeAFunction();\n    `,\n    );\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.function);\n    expect(resolvedType.isNullable).toEqual(false);\n  });\n\n  it('resolves function type from function class', () => {\n    const result = compile(\n      `\n    declare function getMeAFunction(): Function;\n    getMeAFunction();\n    `,\n    );\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.function);\n    expect(resolvedType.isNullable).toEqual(false);\n  });\n\n  it('resolves type references', () => {\n    const result = compile(\n      `\n    declare class Hello {}\n    declare function getMeAnObject(): Hello;\n    getMeAnObject();\n    `,\n    );\n\n    const resolvedType = resolveTypeOfExpression(result.expression, result.typeChecker);\n\n    expect(resolvedType.effectiveType).toEqual(SymbolType.object);\n    expect(resolvedType.isNullable).toEqual(false);\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/TSUtils.ts",
    "content": "import * as ts from 'typescript';\n\nexport function isExpressionNode(node: ts.Node): node is ts.Expression {\n  switch (node.kind) {\n    case ts.SyntaxKind.SuperKeyword:\n    case ts.SyntaxKind.NullKeyword:\n    case ts.SyntaxKind.TrueKeyword:\n    case ts.SyntaxKind.FalseKeyword:\n    case ts.SyntaxKind.RegularExpressionLiteral:\n    case ts.SyntaxKind.ArrayLiteralExpression:\n    case ts.SyntaxKind.ObjectLiteralExpression:\n    case ts.SyntaxKind.PropertyAccessExpression:\n    case ts.SyntaxKind.ElementAccessExpression:\n    case ts.SyntaxKind.CallExpression:\n    case ts.SyntaxKind.NewExpression:\n    case ts.SyntaxKind.TaggedTemplateExpression:\n    case ts.SyntaxKind.AsExpression:\n    case ts.SyntaxKind.TypeAssertionExpression:\n    case ts.SyntaxKind.NonNullExpression:\n    case ts.SyntaxKind.ParenthesizedExpression:\n    case ts.SyntaxKind.FunctionExpression:\n    case ts.SyntaxKind.ClassExpression:\n    case ts.SyntaxKind.ArrowFunction:\n    case ts.SyntaxKind.VoidExpression:\n    case ts.SyntaxKind.DeleteExpression:\n    case ts.SyntaxKind.TypeOfExpression:\n    case ts.SyntaxKind.PrefixUnaryExpression:\n    case ts.SyntaxKind.PostfixUnaryExpression:\n    case ts.SyntaxKind.BinaryExpression:\n    case ts.SyntaxKind.ConditionalExpression:\n    case ts.SyntaxKind.SpreadElement:\n    case ts.SyntaxKind.TemplateExpression:\n    case ts.SyntaxKind.OmittedExpression:\n    case ts.SyntaxKind.JsxElement:\n    case ts.SyntaxKind.JsxSelfClosingElement:\n    case ts.SyntaxKind.JsxFragment:\n    case ts.SyntaxKind.YieldExpression:\n    case ts.SyntaxKind.AwaitExpression:\n    case ts.SyntaxKind.MetaProperty:\n      return true;\n    case ts.SyntaxKind.QualifiedName:\n      while (node.parent.kind === ts.SyntaxKind.QualifiedName) {\n        node = node.parent;\n      }\n      return node.parent.kind === ts.SyntaxKind.TypeQuery || isJSXTagName(node);\n    case ts.SyntaxKind.Identifier:\n      if (node.parent.kind === ts.SyntaxKind.TypeQuery || isJSXTagName(node)) {\n        return true;\n      }\n    // falls through\n\n    case ts.SyntaxKind.NumericLiteral:\n    case ts.SyntaxKind.BigIntLiteral:\n    case ts.SyntaxKind.StringLiteral:\n    case ts.SyntaxKind.NoSubstitutionTemplateLiteral:\n    case ts.SyntaxKind.ThisKeyword:\n      return isInExpressionContext(node);\n    default:\n      return false;\n  }\n}\n\nexport function isInExpressionContext(node: ts.Node): boolean {\n  const { parent } = node;\n  switch (parent.kind) {\n    case ts.SyntaxKind.VariableDeclaration:\n    case ts.SyntaxKind.Parameter:\n    case ts.SyntaxKind.PropertyDeclaration:\n    case ts.SyntaxKind.PropertySignature:\n    case ts.SyntaxKind.EnumMember:\n    case ts.SyntaxKind.PropertyAssignment:\n    case ts.SyntaxKind.BindingElement:\n      return (parent as ts.HasInitializer).initializer === node;\n    case ts.SyntaxKind.ExpressionStatement:\n    case ts.SyntaxKind.IfStatement:\n    case ts.SyntaxKind.DoStatement:\n    case ts.SyntaxKind.WhileStatement:\n    case ts.SyntaxKind.ReturnStatement:\n    case ts.SyntaxKind.WithStatement:\n    case ts.SyntaxKind.SwitchStatement:\n    case ts.SyntaxKind.CaseClause:\n    case ts.SyntaxKind.ThrowStatement:\n      return (<ts.ExpressionStatement>parent).expression === node;\n    case ts.SyntaxKind.ForStatement:\n      const forStatement = <ts.ForStatement>parent;\n      return (\n        (forStatement.initializer === node &&\n          forStatement.initializer.kind !== ts.SyntaxKind.VariableDeclarationList) ||\n        forStatement.condition === node ||\n        forStatement.incrementor === node\n      );\n    case ts.SyntaxKind.ForInStatement:\n    case ts.SyntaxKind.ForOfStatement:\n      const forInStatement = <ts.ForInStatement | ts.ForOfStatement>parent;\n      return (\n        (forInStatement.initializer === node &&\n          forInStatement.initializer.kind !== ts.SyntaxKind.VariableDeclarationList) ||\n        forInStatement.expression === node\n      );\n    case ts.SyntaxKind.TypeAssertionExpression:\n    case ts.SyntaxKind.AsExpression:\n      return node === (<ts.AssertionExpression>parent).expression;\n    case ts.SyntaxKind.TemplateSpan:\n      return node === (<ts.TemplateSpan>parent).expression;\n    case ts.SyntaxKind.ComputedPropertyName:\n      return node === (<ts.ComputedPropertyName>parent).expression;\n    case ts.SyntaxKind.Decorator:\n    case ts.SyntaxKind.JsxExpression:\n    case ts.SyntaxKind.JsxAttribute:\n    case ts.SyntaxKind.JsxSpreadAttribute:\n    case ts.SyntaxKind.SpreadAssignment:\n      return true;\n    case ts.SyntaxKind.ExpressionWithTypeArguments:\n      return (<ts.ExpressionWithTypeArguments>parent).expression === node;\n    case ts.SyntaxKind.ShorthandPropertyAssignment:\n      return (<ts.ShorthandPropertyAssignment>parent).objectAssignmentInitializer === node;\n    default:\n      return isExpressionNode(parent);\n  }\n}\n\nexport function isJSXTagName(node: ts.Node) {\n  const { parent } = node;\n  if (\n    parent.kind === ts.SyntaxKind.JsxOpeningElement ||\n    parent.kind === ts.SyntaxKind.JsxSelfClosingElement ||\n    parent.kind === ts.SyntaxKind.JsxClosingElement\n  ) {\n    return (<ts.JsxOpeningLikeElement>parent).tagName === node;\n  }\n  return false;\n}\n\nexport interface NodeComments {\n  text: string;\n  start: number;\n  end: number;\n}\n\nexport function getNodeComments(node: ts.Node): NodeComments | undefined {\n  const leadingTriviaWidth = node.getLeadingTriviaWidth();\n  if (leadingTriviaWidth === 0) {\n    return undefined;\n  }\n  const nodeStart = node.getFullStart();\n  const sourceFileText = node.getSourceFile().text;\n\n  const leadingTriva = sourceFileText.substring(nodeStart, nodeStart + leadingTriviaWidth);\n  const trimmedLeft = leadingTriva.trimStart();\n\n  const trimLeftShrunkSize = leadingTriva.length - trimmedLeft.length;\n\n  let resolvedStart = nodeStart + trimLeftShrunkSize;\n  let resolvedWidth = leadingTriviaWidth - trimLeftShrunkSize;\n\n  const trimmedRight = trimmedLeft.trimEnd();\n\n  const trimRightShrunkSize = trimmedLeft.length - trimmedRight.length;\n  resolvedWidth -= trimRightShrunkSize;\n\n  if (!trimmedRight) {\n    return undefined;\n  }\n\n  return {\n    text: trimmedRight,\n    start: resolvedStart,\n    end: resolvedStart + resolvedWidth,\n  };\n}\n\nexport interface NodeToDump {\n  node: ts.Node;\n  leadingComments: NodeComments | undefined;\n}\n\nexport function isNodeExported(node: ts.Node): boolean {\n  const modifiers = ts.getCombinedModifierFlags(node as ts.Declaration);\n\n  return (modifiers & ts.ModifierFlags.Export) !== 0;\n}\n\nexport function getRootNodesToDump(\n  sourceFileNode: ts.Node,\n  predicate: ((node: NodeToDump) => boolean) | undefined,\n): NodeToDump[] {\n  const children = sourceFileNode.getChildAt(0).getChildren();\n\n  const result: NodeToDump[] = [];\n  for (const child of children) {\n    const leadingTriva = getNodeComments(child);\n    const nodeToDump: NodeToDump = {\n      node: child,\n      leadingComments: leadingTriva,\n    };\n    if (!predicate || predicate(nodeToDump)) {\n      result.push(nodeToDump);\n    }\n  }\n  return result;\n}\n\nexport function findNode(\n  node: ts.Node,\n  position: number | undefined,\n  visit: (node: ts.Node) => boolean,\n): ts.Node | undefined {\n  const start = node.getStart();\n  const end = node.getEnd();\n\n  if (position !== undefined && (position < start || position > end)) {\n    return undefined;\n  }\n\n  if (visit(node)) {\n    return node;\n  }\n\n  const childCount = node.getChildCount();\n  for (let i = 0; i < childCount; i++) {\n    const child = node.getChildAt(i);\n    const bestNode = findNode(child, position, visit);\n    if (bestNode) {\n      return bestNode;\n    }\n  }\n\n  return undefined;\n}\n\nexport const enum SymbolType {\n  any = 1,\n  undefined,\n  null,\n  number,\n  boolean,\n  string,\n  object,\n  function,\n}\n\nexport interface SymbolObjectInfo {\n  readonly name: string;\n  readonly declaration?: ts.Declaration;\n  readonly symbol?: ts.Symbol;\n}\n\nexport interface ResolvedSymbol {\n  readonly type: SymbolType;\n  readonly objectInfo?: SymbolObjectInfo;\n}\n\nfunction symbolObjectInfoEquals(left: SymbolObjectInfo | undefined, right: SymbolObjectInfo | undefined): boolean {\n  if (!left || !right) {\n    return left === right;\n  }\n\n  return left.declaration === right.declaration;\n}\n\nfunction appendResolvedSymbolIfNeeded(resolvedSymbol: ResolvedSymbol, output: ResolvedSymbol[]): boolean {\n  for (const existingSymbol of output) {\n    if (\n      resolvedSymbol.type === existingSymbol.type &&\n      symbolObjectInfoEquals(resolvedSymbol.objectInfo, existingSymbol.objectInfo)\n    ) {\n      return false;\n    }\n  }\n\n  output.push(resolvedSymbol);\n  return true;\n}\n\nfunction getResolvedSymbolForType(type: ts.Type): ResolvedSymbol[] {\n  if (type.isUnionOrIntersection()) {\n    const out: ResolvedSymbol[] = [];\n\n    for (const childType of type.types) {\n      const childSymbols = getResolvedSymbolForType(childType);\n      for (const childSymbol of childSymbols) {\n        appendResolvedSymbolIfNeeded(childSymbol, out);\n      }\n    }\n\n    return out;\n  }\n\n  const typeFlags = type.getFlags();\n\n  if (typeFlags & ts.TypeFlags.NumberLike) {\n    return [{ type: SymbolType.number }];\n  }\n\n  if (typeFlags & ts.TypeFlags.StringLike) {\n    return [{ type: SymbolType.string }];\n  }\n\n  if (typeFlags & ts.TypeFlags.Undefined) {\n    return [{ type: SymbolType.undefined }];\n  }\n\n  if (typeFlags & ts.TypeFlags.Null) {\n    return [{ type: SymbolType.null }];\n  }\n\n  if (typeFlags & ts.TypeFlags.Object) {\n    const objectType = type as ts.ObjectType;\n    if (objectType.objectFlags & ts.ObjectFlags.Reference) {\n      const reference = objectType as ts.TypeReference;\n      if (reference.target !== reference) {\n        return getResolvedSymbolForType(reference.target);\n      }\n    }\n\n    const symbol = type.getSymbol();\n    if (symbol) {\n      const declaration = symbol.declarations?.[0];\n      const symbolName = symbol.getName();\n      const type =\n        declaration && (ts.isFunctionLike(declaration) || symbolName === 'Function')\n          ? SymbolType.function\n          : SymbolType.object;\n\n      return [{ type, objectInfo: { name: symbolName, declaration, symbol } }];\n    }\n  }\n\n  return [{ type: SymbolType.any }];\n}\n\nexport function resolvedSymbolsOfExpression(expression: ts.Expression, typeChecker: ts.TypeChecker): ResolvedSymbol[] {\n  const type = typeChecker.getTypeAtLocation(expression);\n  return getResolvedSymbolForType(type);\n}\n\nexport interface ResolvedType {\n  readonly resolvedSymbols: ResolvedSymbol[];\n  readonly isNullable: boolean;\n  readonly effectiveType: SymbolType;\n  readonly effectiveObjectInfo: SymbolObjectInfo | undefined;\n}\n\nexport function getSyntaxKindString(syntaxKind: ts.SyntaxKind): string {\n  return ts.SyntaxKind[syntaxKind];\n}\n\nconst MAX_NODE_DEBUG_LENGTH = 50;\n\nexport function getNodeDebugDescription(node: ts.Node): string {\n  const sourceFile = node.getSourceFile();\n  const position = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n\n  let text = node.getText();\n  if (text.length > MAX_NODE_DEBUG_LENGTH) {\n    text = text.substr(0, MAX_NODE_DEBUG_LENGTH);\n  }\n\n  return `(node kind ${getSyntaxKindString(node.kind)}, content '${text}') at ${sourceFile.fileName}:${\n    position.line + 1\n  }:${position.character + 1}`;\n}\n\nexport function resolveTypeOfExpression(expression: ts.Expression, typeChecker: ts.TypeChecker): ResolvedType {\n  let effectiveType: SymbolType | undefined;\n  let effectiveObjectInfo: SymbolObjectInfo | undefined;\n  let isNullable = false;\n\n  const resolvedSymbols = resolvedSymbolsOfExpression(expression, typeChecker);\n\n  for (const resolvedSymbol of resolvedSymbols) {\n    if (resolvedSymbol.type === SymbolType.any) {\n      effectiveType = SymbolType.any;\n    } else if (resolvedSymbol.type === SymbolType.undefined || resolvedSymbol.type === SymbolType.null) {\n      isNullable = true;\n    } else {\n      if (effectiveType === undefined) {\n        effectiveType = resolvedSymbol.type;\n        effectiveObjectInfo = resolvedSymbol.objectInfo;\n      } else {\n        effectiveType = SymbolType.any;\n      }\n    }\n  }\n\n  if (effectiveType === undefined) {\n    effectiveType = SymbolType.any;\n  }\n\n  if (effectiveType === SymbolType.any) {\n    isNullable = true;\n    effectiveObjectInfo = undefined;\n  }\n\n  return { effectiveType, isNullable, resolvedSymbols, effectiveObjectInfo };\n}\n\nexport class Transpiler {\n  readonly diagnostics: ts.Diagnostic[] = [];\n  readonly program: ts.Program;\n  readonly sourceFile: ts.SourceFile;\n\n  private outputText: string | undefined;\n  private sourceMapText: string | undefined;\n\n  constructor(input: string, transpileOptions: ts.TranspileOptions) {\n    const options = { ...(transpileOptions.compilerOptions ?? {}) };\n    // mix in default options\n\n    const defaultOptions = ts.getDefaultCompilerOptions();\n    for (const key in defaultOptions) {\n      if (defaultOptions[key] !== undefined && options[key] === undefined) {\n        options[key] = defaultOptions[key];\n      }\n    }\n\n    // transpileModule does not write anything to disk so there is no need to verify that there are no conflicts between input and output paths.\n    options.suppressOutputPathCheck = true;\n\n    // Filename can be non-ts file.\n    options.allowNonTsExtensions = true;\n\n    // if jsx is specified then treat file as .tsx\n    const inputFileName =\n      transpileOptions.fileName ||\n      (transpileOptions.compilerOptions && transpileOptions.compilerOptions.jsx ? 'module.tsx' : 'module.ts');\n    this.sourceFile = ts.createSourceFile(inputFileName, input, options.target!); // TODO: GH#18217\n    if (transpileOptions.moduleName) {\n      this.sourceFile.moduleName = transpileOptions.moduleName;\n    }\n\n    const newLine = '\\n';\n\n    // Create a compilerHost object to allow the compiler to read and write files\n    const compilerHost: ts.CompilerHost = {\n      getSourceFile: (fileName) => (fileName === inputFileName ? this.sourceFile : undefined),\n      writeFile: (name, text) => {\n        if (name.endsWith('.map')) {\n          this.sourceMapText = text;\n        } else {\n          this.outputText = text;\n        }\n      },\n      getDefaultLibFileName: () => 'lib.d.ts',\n      useCaseSensitiveFileNames: () => false,\n      getCanonicalFileName: (fileName) => fileName,\n      getCurrentDirectory: () => '',\n      getNewLine: () => newLine,\n      fileExists: (fileName): boolean => fileName === inputFileName,\n      readFile: () => '',\n      directoryExists: () => true,\n      getDirectories: () => [],\n    };\n\n    this.program = ts.createProgram([inputFileName], options, compilerHost);\n\n    if (transpileOptions.reportDiagnostics) {\n      this.diagnostics.push(...this.program.getSyntacticDiagnostics(this.sourceFile));\n      this.diagnostics.push(...this.program.getOptionsDiagnostics());\n    }\n  }\n\n  transpile(transformers?: ts.CustomTransformers): ts.TranspileOutput {\n    // Emit\n    this.program.emit(\n      /*targetSourceFile*/ undefined,\n      /*writeFile*/ undefined,\n      /*cancellationToken*/ undefined,\n      /*emitOnlyDtsFiles*/ undefined,\n      transformers,\n    );\n\n    if (this.outputText === undefined) {\n      throw new Error('Output generation failed');\n    }\n\n    return { outputText: this.outputText, diagnostics: this.diagnostics, sourceMapText: this.sourceMapText };\n  }\n}\n\nexport const enum OuterExpressionKinds {\n  Parentheses = 1 << 0,\n  TypeAssertions = 1 << 1,\n  NonNullAssertions = 1 << 2,\n  PartiallyEmittedExpressions = 1 << 3,\n\n  Assertions = TypeAssertions | NonNullAssertions,\n  All = Parentheses | Assertions | PartiallyEmittedExpressions,\n\n  ExcludeJSDocTypeAssertion = 1 << 4,\n}\n\nexport type OuterExpression =\n  | ts.ParenthesizedExpression\n  | ts.TypeAssertion\n  | ts.AsExpression\n  | ts.NonNullExpression\n  | ts.PartiallyEmittedExpression;\n\nexport function isOuterExpression(node: ts.Node, kinds = OuterExpressionKinds.All): node is OuterExpression {\n  switch (node.kind) {\n    case ts.SyntaxKind.ParenthesizedExpression:\n      return (kinds & OuterExpressionKinds.Parentheses) !== 0;\n    case ts.SyntaxKind.TypeAssertionExpression:\n    case ts.SyntaxKind.AsExpression:\n      return (kinds & OuterExpressionKinds.TypeAssertions) !== 0;\n    case ts.SyntaxKind.NonNullExpression:\n      return (kinds & OuterExpressionKinds.NonNullAssertions) !== 0;\n    case ts.SyntaxKind.PartiallyEmittedExpression:\n      return (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) !== 0;\n  }\n  return false;\n}\n\nexport function skipOuterExpressions(node: ts.Node, kinds = OuterExpressionKinds.All) {\n  while (isOuterExpression(node, kinds)) {\n    node = node.expression;\n  }\n  return node;\n}\n\nexport function skipParentheses(node: ts.Node, excludeJSDocTypeAssertions?: boolean): ts.Node {\n  return skipOuterExpressions(node, OuterExpressionKinds.Parentheses);\n}\n\nexport function isSuperCall(n: ts.Node): n is ts.SuperCall {\n  return (\n    n.kind === ts.SyntaxKind.CallExpression && (n as ts.CallExpression).expression.kind === ts.SyntaxKind.SuperKeyword\n  );\n}\n\nexport function getSuperCallFromStatement(statement: ts.Statement): ts.Expression | undefined {\n  if (!ts.isExpressionStatement(statement)) {\n    return undefined;\n  }\n\n  const expression = skipParentheses(statement.expression);\n  return isSuperCall(expression) ? expression : undefined;\n}\n\nexport function findSuperStatementIndex(\n  statements: ts.NodeArray<ts.Statement>,\n  indexAfterLastPrologueStatement: number,\n): number {\n  for (let i = indexAfterLastPrologueStatement; i < statements.length; i += 1) {\n    const statement = statements[i];\n\n    if (getSuperCallFromStatement(statement)) {\n      return i;\n    }\n  }\n\n  return -1;\n}\n\n// If the (potentially composite) statement contains a super call\nexport function statementHasSuperCall(node: ts.Node): boolean {\n  if (isSuperCall(node)) {\n    return true;\n  }\n  for (const child of node.getChildren()) {\n    if (statementHasSuperCall(child)) {\n      return true;\n    }\n  }\n  return false;\n}\n"
  },
  {
    "path": "compiler/companion/src/Workspace.ts",
    "content": "import * as path from 'path';\nimport {\n  AST,\n  dumpEnum,\n  dumpFunction,\n  dumpInterface,\n  dumpRootNodes,\n  getImportStringLiteralsFromSourceFile,\n  isNonModuleWithAmbiantDeclarations,\n} from './AST';\nimport { ILogger } from './logger/ILogger';\nimport { JSXProcessor } from './JSXProcessor';\nimport { createConsoleLogTransformer } from './ConsoleLogTransformer';\nimport {\n  Diagnostic,\n  DumpedInterface,\n  DumpedSymbolsWithComments,\n  DumpEnumResponseBody,\n  DumpFunctionResponseBody,\n  Location,\n} from './protocol';\nimport { findNode } from './TSUtils';\nimport { IProjectListener, Project } from './project/Project';\nimport * as ts from 'typescript';\nimport { Stopwatch } from './utils/Stopwatch';\nimport { IWorkspace, OpenFileImportPath, OpenFileResult } from './IWorkspace';\nimport * as _path from 'path';\nimport { ImportPathResolver } from './utils/ImportPathResolver';\nimport { debounce } from 'lodash';\n\nexport interface OpenedFile {\n  sourceFile: ts.SourceFile;\n  workspaceProject: Project;\n}\n\nexport interface EmitResultEntry {\n  fileName: string;\n  content: string;\n}\n\nexport interface EmitResult {\n  entries: EmitResultEntry[];\n  emitted: boolean;\n}\n\nexport interface GetDiagnosticsResult {\n  diagnostics: Diagnostic[];\n  fileContent: string | undefined;\n  hasError: boolean;\n  timeTakenMs: number;\n}\n\ninterface PendingFileToOpen {\n  fileName: string;\n  resolve: (result: OpenFileResult) => void;\n  reject: (error: unknown) => void;\n}\n\nfunction mergeCustomTransformers(\n  transformers: ts.CustomTransformers,\n  newTransformers: ts.CustomTransformers | undefined,\n): ts.CustomTransformers {\n  if (!newTransformers) {\n    return transformers;\n  }\n\n  const out = { ...transformers };\n\n  if (newTransformers.after) {\n    if (!out.after) {\n      out.after = [];\n    }\n    out.after.push(...newTransformers.after);\n  }\n\n  if (newTransformers.before) {\n    if (!out.before) {\n      out.before = [];\n    }\n\n    out.before.push(...newTransformers.before);\n  }\n\n  return out;\n}\n\nclass ProjectListener implements IProjectListener {\n  private stopWatch = new Stopwatch();\n  constructor(private readonly logger: ILogger) {}\n\n  onProgramWillChange(): void {\n    this.stopWatch.start();\n    this.logger.debug?.('Creating TypeScript program...');\n  }\n\n  onProgramChanged(): void {\n    const elapsed = this.stopWatch.elapsedString;\n    this.logger.debug?.(`Created TypeScript program in ${elapsed}`);\n  }\n\n  onCompilerOptionsResolved(): void {}\n  onFileContentLoaded(path: string): void {}\n  onSourceFileCreated(path: string): void {}\n  onSourceFileInvalidated(path: string): void {}\n}\n\nexport class Workspace implements IWorkspace {\n  workspaceRoot: string;\n  initialized: boolean = false;\n\n  private project: Project;\n  private importPathResolver: ImportPathResolver;\n\n  private pendingFilesToOpen: PendingFileToOpen[] = [];\n  private scheduleFlushOpenQueuedFiles: () => void;\n\n  constructor(\n    workspaceRoot: string,\n    shouldDebounceOpenFile: boolean,\n    readonly logger: ILogger | undefined,\n    readonly compilerOptions: ts.CompilerOptions | undefined,\n  ) {\n    this.workspaceRoot = workspaceRoot;\n    const project = new Project(workspaceRoot, compilerOptions, logger ? new ProjectListener(logger) : undefined);\n    this.project = project;\n    this.importPathResolver = new ImportPathResolver(() => project.compilerOptions);\n\n    const flushOpenQueuedFiles = () => {\n      this.openQueuedFiles();\n    };\n    if (shouldDebounceOpenFile) {\n      this.scheduleFlushOpenQueuedFiles = debounce(flushOpenQueuedFiles, 20, { trailing: true });\n    } else {\n      this.scheduleFlushOpenQueuedFiles = flushOpenQueuedFiles;\n    }\n  }\n\n  initialize(): void {\n    const tsConfigCompilerOptions = this.project.compilerOptions;\n    // Doing this to make sure we automatically \"open\" any files referred to in\n    // tsconfig.compilerOptions.types _if they are present_.\n    //\n    // Note: we seem to be using tsconfig.compilerOptions.types in a _very_\n    // unexpected way (see docs: https://www.typescriptlang.org/tsconfig#types)\n    //\n    // It seems likely that the fact that this lets us make Long.d.ts available globally\n    // is accidental.\n    const typesFiles = tsConfigCompilerOptions.types ?? [];\n    const basePath = (tsConfigCompilerOptions.typeRoots ?? [''])[0];\n    const presentTypesFiles = typesFiles\n      .map((unresolvedTypesFilePath) => path.resolve(basePath, unresolvedTypesFilePath + '.d.ts'))\n      .filter((f) => this.project.fileExists(f));\n\n    presentTypesFiles.forEach((typesFilePath) => this.doOpenFile(typesFilePath));\n    this.initialized = true;\n  }\n\n  destroy(): void {\n    this.project.destroy();\n  }\n\n  addSourceFileAtPath(fileName: string) {\n    this.project.openSourceFile(fileName);\n  }\n\n  async openFile(fileName: string): Promise<OpenFileResult> {\n    return new Promise((resolve, reject) => {\n      const pendingFile: PendingFileToOpen = {\n        fileName: fileName,\n        resolve,\n        reject,\n      };\n      this.pendingFilesToOpen.push(pendingFile);\n      this.scheduleFlushOpenQueuedFiles();\n    });\n  }\n\n  private doOpenFile(fileName: string): OpenFileResult {\n    this.logger?.debug?.(`Opening file ${fileName}`);\n    const sourceFile = this.project.openSourceFile(fileName);\n    const relativeImportPaths = getImportStringLiteralsFromSourceFile(sourceFile).map((lit) => lit.text);\n    const isTypeScriptFile = fileName.endsWith('.ts') || fileName.endsWith('.tsx');\n    const importPaths: OpenFileImportPath[] = relativeImportPaths.map((i) => {\n      return { relative: i, absolute: this.resolveImportPath(sourceFile.fileName, i) };\n    });\n\n    return {\n      importPaths,\n      isNonModuleWithAmbiantDeclarations: isTypeScriptFile && isNonModuleWithAmbiantDeclarations(sourceFile),\n    };\n  }\n\n  private openQueuedFiles(): void {\n    while (this.pendingFilesToOpen.length > 0) {\n      const fileToOpen = this.pendingFilesToOpen.shift()!;\n\n      try {\n        fileToOpen.resolve(this.doOpenFile(fileToOpen.fileName));\n      } catch (err: unknown) {\n        fileToOpen.reject(err);\n      }\n    }\n  }\n\n  getOpenedFile(fileName: string): OpenedFile {\n    const sourceFile = this.project.getOpenedSourceFile(fileName);\n    if (sourceFile) {\n      return { workspaceProject: this.project, sourceFile };\n    }\n\n    throw new Error(`File '${fileName}' is not loaded`);\n  }\n\n  registerInMemoryFile(fileName: string, fileContent: string): void {\n    const resolvedPath = this.project.resolvePath(fileName);\n    this.importPathResolver.registerAlias(resolvedPath);\n    this.project.setFileContentAtResolvedPath(resolvedPath, fileContent);\n  }\n\n  registerDiskFile(fileName: string, absoluteDiskPath: string): void {\n    const resolvedPath = this.project.resolvePath(fileName);\n    this.importPathResolver.registerAlias(resolvedPath);\n    this.project.setFileFromDiskAtResolvedPath(resolvedPath, absoluteDiskPath);\n  }\n\n  static requiresTSXProcessor(fileName: string): boolean {\n    return fileName.endsWith('.tsx') || fileName.endsWith('.jsx');\n  }\n\n  doEmitFile(\n    fileName: string,\n    cancellationToken: ts.CancellationToken | undefined,\n    customTransformers: ts.CustomTransformers | undefined,\n  ): EmitResult {\n    const openedFile = this.getOpenedFile(fileName);\n    const program = openedFile.workspaceProject.program;\n\n    let resolvedCustomTransformers: ts.CustomTransformers = {\n      before: [],\n    };\n\n    if (Workspace.requiresTSXProcessor(fileName)) {\n      const jsxProcessor = new JSXProcessor(this.logger);\n      resolvedCustomTransformers.before!.push(\n        ...jsxProcessor.makeTransformers(openedFile.workspaceProject.typeChecker),\n      );\n    }\n\n    // Wrap console.log/warn/error/info/debug calls in runtime.isLoggingEnabled guards.\n    // This is safe in dev builds because runtime.isLoggingEnabled is always true.\n    resolvedCustomTransformers.before!.push(createConsoleLogTransformer());\n\n    resolvedCustomTransformers = mergeCustomTransformers(resolvedCustomTransformers, customTransformers);\n\n    const output: EmitResult = { entries: [], emitted: false };\n    const programResult = program.emit(\n      openedFile.sourceFile,\n      (fileName: string, text: string, writeByteOrderMark: boolean) => {\n        output.entries.push({\n          fileName,\n          content: text,\n        });\n      },\n      cancellationToken,\n      undefined,\n      resolvedCustomTransformers,\n    );\n\n    output.emitted = !programResult.emitSkipped;\n\n    return output;\n  }\n\n  async emitFile(fileName: string): Promise<EmitResult> {\n    return this.doEmitFile(fileName, undefined, undefined);\n  }\n\n  transformDiagnostic(project: Project, original: ts.DiagnosticWithLocation | ts.Diagnostic): Diagnostic {\n    const text = project.formatDiagnostic(original);\n\n    let category: string;\n    switch (original.category) {\n      case ts.DiagnosticCategory.Warning:\n        category = 'warning';\n        break;\n      case ts.DiagnosticCategory.Error:\n        category = 'error';\n        break;\n      case ts.DiagnosticCategory.Suggestion:\n        category = 'suggestion';\n        break;\n      case ts.DiagnosticCategory.Message:\n        category = 'message';\n        break;\n    }\n\n    let file = original.file ?? (original.source && project.getOpenedSourceFile(original.source));\n\n    let start: Location;\n    let end: Location;\n    if (file && original.start) {\n      start = this.getLocationOfPositionInFile(file, original.start);\n      end = this.getLocationOfPositionInFile(file, original.start + (original.length ?? 0));\n    } else {\n      start = { line: 0, offset: 0 };\n      end = { line: 0, offset: 0 };\n    }\n\n    const transformed = {\n      start,\n      end,\n      text,\n      category,\n    };\n    return transformed;\n  }\n\n  getLocationOfPositionInFile(file: ts.SourceFile, position: number): Location {\n    const lac = file.getLineAndCharacterOfPosition(position);\n    // Location is 1-indexed\n    return { line: lac.line + 1, offset: lac.character + 1 };\n  }\n\n  private doGetDiagnostics(openedFile: OpenedFile, syntactic: boolean, output: Diagnostic[]): boolean {\n    const program = openedFile.workspaceProject.program;\n    const diagnostics = syntactic\n      ? program.getSyntacticDiagnostics(openedFile.sourceFile)\n      : program.getSemanticDiagnostics(openedFile.sourceFile);\n    let success = true;\n    for (const diagnostic of diagnostics) {\n      const transformedDiagnostic = this.transformDiagnostic(openedFile.workspaceProject, diagnostic);\n      output.push(transformedDiagnostic);\n\n      if (transformedDiagnostic.category === 'error') {\n        success = false;\n      }\n    }\n\n    return success;\n  }\n\n  private makeDiagnostic(sourceFile: ts.SourceFile, node: ts.Node, text: string): Diagnostic {\n    const fullStart = node.getFullStart();\n    const start = this.getLocationOfPositionInFile(sourceFile, fullStart);\n    const end = this.getLocationOfPositionInFile(sourceFile, fullStart + node.getFullWidth());\n\n    return { start, end, text, category: 'error' };\n  }\n\n  private validateImports(openedFile: OpenedFile, output: Diagnostic[]): boolean {\n    const importPaths = getImportStringLiteralsFromSourceFile(openedFile.sourceFile);\n    let success = true;\n\n    for (const importPath of importPaths) {\n      const resolvedImportPath = this.resolveImportPath(openedFile.sourceFile.fileName, importPath.text);\n      const resolvedPath = this.project.resolvePath(resolvedImportPath);\n      const pathToCheck = this.importPathResolver.getAlias(resolvedPath) ?? resolvedPath;\n\n      if (!this.project.fileExists(pathToCheck.absolutePath)) {\n        const errorMessage = `File '${importPath.text}' does not exist`;\n        output.push(this.makeDiagnostic(openedFile.sourceFile, importPath, errorMessage));\n        success = false;\n      }\n    }\n\n    return success;\n  }\n\n  async getDiagnostics(fileName: string): Promise<GetDiagnosticsResult> {\n    return this.getDiagnosticsSync(fileName);\n  }\n\n  getDiagnosticsSync(fileName: string): GetDiagnosticsResult {\n    const sw = new Stopwatch();\n    const openedFile = this.getOpenedFile(fileName);\n    const diagnostics: Diagnostic[] = [];\n\n    if (!this.doGetDiagnostics(openedFile, true, diagnostics)) {\n      return {\n        diagnostics,\n        fileContent: openedFile.sourceFile.text,\n        hasError: true,\n        timeTakenMs: sw.elapsedMilliseconds,\n      };\n    }\n\n    if (!this.validateImports(openedFile, diagnostics)) {\n      return {\n        diagnostics,\n        fileContent: openedFile.sourceFile.text,\n        hasError: true,\n        timeTakenMs: sw.elapsedMilliseconds,\n      };\n    }\n\n    if (!fileName.endsWith('.js')) {\n      if (!this.doGetDiagnostics(openedFile, false, diagnostics)) {\n        return {\n          diagnostics,\n          fileContent: openedFile.sourceFile.text,\n          hasError: true,\n          timeTakenMs: sw.elapsedMilliseconds,\n        };\n      }\n    }\n\n    return {\n      diagnostics,\n      fileContent: undefined,\n      hasError: false,\n      timeTakenMs: sw.elapsedMilliseconds,\n    };\n  }\n\n  async dumpSymbolsWithComments(fileName: string): Promise<DumpedSymbolsWithComments> {\n    const openedFile = this.getOpenedFile(fileName);\n\n    const references: AST.TypeReference[] = [];\n\n    const astReferences: AST.TypeReferences = {\n      typeChecker: openedFile.workspaceProject.typeChecker,\n      references: references,\n    };\n\n    const dumpedSymbols = dumpRootNodes(openedFile.sourceFile, astReferences);\n\n    return {\n      dumpedSymbols,\n      references,\n    };\n  }\n\n  async getInterfaceAST(fileName: string, position: number): Promise<DumpedInterface> {\n    const openedFile = this.getOpenedFile(fileName);\n    const node = findNode(openedFile.sourceFile, position, (node) => ts.isInterfaceDeclaration(node));\n    if (!node) {\n      throw new Error(`Could not resolve interface declaration at position ${position}`);\n    }\n\n    const references: AST.TypeReference[] = [];\n\n    const dumpedInterface = dumpInterface(node as ts.InterfaceDeclaration, {\n      typeChecker: openedFile.workspaceProject.typeChecker,\n      references,\n    });\n\n    return {\n      interface: dumpedInterface,\n      references,\n    };\n  }\n\n  async getFunctionAST(fileName: string, position: number): Promise<DumpFunctionResponseBody> {\n    const openedFile = this.getOpenedFile(fileName);\n    const node = findNode(openedFile.sourceFile, position, (node) => ts.isFunctionDeclaration(node));\n    if (!node) {\n      throw new Error(`Could not resolve function declaration at position ${position}`);\n    }\n\n    const references: AST.TypeReference[] = [];\n\n    const dumpedFunction = dumpFunction(node as ts.FunctionDeclaration, {\n      typeChecker: openedFile.workspaceProject.typeChecker,\n      references,\n    });\n\n    return {\n      function: dumpedFunction,\n      references,\n    };\n  }\n\n  async getEnumAST(fileName: string, position: number): Promise<DumpEnumResponseBody> {\n    const openedFile = this.getOpenedFile(fileName);\n    const node = findNode(openedFile.sourceFile, position, (node) => ts.isEnumDeclaration(node));\n    if (!node) {\n      throw new Error(`Could not resolve enum declaration at position ${position}`);\n    }\n\n    const dumpedEnum = dumpEnum(node as ts.EnumDeclaration);\n\n    return {\n      enum: dumpedEnum,\n    };\n  }\n\n  resolveImportPath(fromPath: string, toPath: string): string {\n    return this.importPathResolver.resolveImportPath(fromPath, toPath);\n  }\n\n  getFileNameForImportPath(importPath: string): string {\n    const resolvedPath = this.project.resolvePath(importPath);\n    return this.importPathResolver.getAlias(resolvedPath)?.absolutePath ?? resolvedPath.absolutePath;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/WorkspaceStore.ts",
    "content": "import { createCachingWorkspace } from './cache/CachingWorkspaceFactory';\nimport { IWorkspace } from './IWorkspace';\nimport { ILogger } from './logger/ILogger';\nimport { Workspace } from './Workspace';\n\nexport interface CreateWorkspaceResult {\n  workspaceId: number;\n  workspace: IWorkspace;\n}\n\ninterface StoreEntry {\n  uncachedWorkspace: Workspace;\n  activeWorkspace: IWorkspace;\n}\n\nexport class WorkspaceStore {\n  private store = new Map<number, StoreEntry>();\n  private sequence = 0;\n\n  constructor(\n    readonly logger: ILogger,\n    readonly cacheDir: string | undefined,\n    readonly shouldDebounceOpenFile: boolean,\n  ) {}\n\n  createWorkspace(): CreateWorkspaceResult {\n    const uncachedWorkspace = new Workspace('/', this.shouldDebounceOpenFile, this.logger, undefined);\n    let workspace: IWorkspace;\n    if (this.cacheDir) {\n      workspace = createCachingWorkspace(this.cacheDir, uncachedWorkspace, this.logger);\n    } else {\n      workspace = uncachedWorkspace;\n    }\n\n    const workspaceId = ++this.sequence;\n    this.store.set(workspaceId, { uncachedWorkspace, activeWorkspace: workspace });\n\n    return { workspaceId, workspace };\n  }\n\n  destroyWorkspace(workspaceId: number): boolean {\n    const entry = this.store.get(workspaceId);\n    if (!entry) {\n      return false;\n    }\n    this.store.delete(workspaceId);\n    entry.activeWorkspace.destroy();\n    return true;\n  }\n\n  destroyAllWorkspaces(): void {\n    const allWorkspaceIds = [...this.store.keys()];\n    allWorkspaceIds.forEach((workspaceId) => this.destroyWorkspace(workspaceId));\n  }\n\n  private getEntry(workspaceId: number): StoreEntry {\n    if (workspaceId === undefined) {\n      throw new Error('workspaceId was not provided');\n    }\n\n    const entry = this.store.get(workspaceId);\n    if (!entry) {\n      throw new Error(`No Workspace for id ${workspaceId}`);\n    }\n    return entry;\n  }\n\n  getWorkspace(workspaceId: number): IWorkspace {\n    return this.getEntry(workspaceId).activeWorkspace;\n  }\n\n  getInitializedWorkspace(workspaceId: number): IWorkspace {\n    const workspace = this.getWorkspace(workspaceId);\n    if (!workspace.initialized) {\n      throw new Error(`Workspace ${workspaceId} was not initialized`);\n    }\n    return workspace;\n  }\n\n  getUncachedWorkspace(workspaceId: number): Workspace {\n    return this.getEntry(workspaceId).uncachedWorkspace;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/ZombieKiller.ts",
    "content": "const isProcessRunning = function (pid: number) {\n  try {\n    // yes, this really is the way to check if a process is running\n    return process.kill(pid, 0);\n  } catch (e: any) {\n    return e.code === 'EPERM';\n  }\n};\n\nexport class ZombieKiller {\n  constructor(private shutdownCallback: () => void) {}\n\n  private intervalHandle?: NodeJS.Timeout;\n\n  private stopAndNotify() {\n    this.stop();\n    this.shutdownCallback();\n  }\n\n  stop() {\n    clearInterval(this.intervalHandle);\n    this.intervalHandle = undefined;\n  }\n\n  start() {\n    this.intervalHandle = setInterval(() => {\n      const parentPID = process.ppid;\n      if (parentPID === 1) {\n        console.error('Parent pid is 1, that means the parent has died. Killing self');\n        this.stopAndNotify();\n        return;\n      }\n\n      const isParentRunning = isProcessRunning(parentPID);\n      if (!isParentRunning) {\n        console.error('Parent died, killing self');\n        this.stopAndNotify();\n        return;\n      }\n    }, 1000);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/cache/CachingWorkspace.spec.ts",
    "content": "import 'ts-jest';\nimport { EmitResult, GetDiagnosticsResult, IWorkspace, OpenFileResult } from '../IWorkspace';\nimport {\n  DumpEnumResponseBody,\n  DumpFunctionResponseBody,\n  DumpedInterface,\n  DumpedSymbolsWithComments,\n} from '../protocol';\nimport { ICompilationCache } from './ICompilationCache';\nimport { CachingWorkspace } from './CachingWorkspace';\nimport { ImportPathResolver } from '../utils/ImportPathResolver';\nimport { FileManager } from '../project/FileManager';\n\ninterface TestWorkspaceResponseHandler {\n  method: string;\n  fileName: string;\n  position: number | undefined;\n  response: unknown;\n}\n\nclass TestWorkspace implements IWorkspace {\n  initialized: boolean = true;\n  workspaceRoot: string = '/';\n\n  responseHandlers: TestWorkspaceResponseHandler[] = [];\n  private fileManager = new FileManager(this.workspaceRoot);\n  private importPathResolver = new ImportPathResolver(() => {\n    return {};\n  });\n\n  initialize(): void {}\n\n  destroy(): void {}\n\n  registerInMemoryFile(fileName: string, fileContent: string): void {\n    this.importPathResolver.registerAlias(this.fileManager.resolvePath(fileName));\n  }\n\n  registerDiskFile(fileName: string, absoluteDiskPath: string): void {\n    this.importPathResolver.registerAlias(this.fileManager.resolvePath(fileName));\n  }\n\n  resolveImportPath(fromPath: string, toPath: string): string {\n    return this.importPathResolver.resolveImportPath(fromPath, toPath);\n  }\n\n  getFileNameForImportPath(importPath: string): string {\n    return this.importPathResolver.getAlias(this.fileManager.resolvePath(importPath))?.absolutePath ?? importPath;\n  }\n\n  appendNextRequestHandler<T>(method: string, fileName: string, position: number | undefined, response: T): void {\n    this.responseHandlers.push({ method, fileName, position, response });\n  }\n\n  private async handleRequest<T>(method: string, fileName: string, position?: number): Promise<T> {\n    for (let i = 0; i < this.responseHandlers.length; i++) {\n      const responseHandler = this.responseHandlers[i];\n      if (\n        responseHandler.method === method &&\n        responseHandler.fileName === fileName &&\n        responseHandler.position === position\n      ) {\n        const response = responseHandler.response;\n        this.responseHandlers.splice(i, 1);\n        return response as T;\n      }\n    }\n\n    throw new Error(`No request handler for method '${method}' with fileName '${fileName}'`);\n  }\n\n  openFile(fileName: string): Promise<OpenFileResult> {\n    return this.handleRequest<OpenFileResult>('openFile', fileName);\n  }\n\n  emitFile(fileName: string): Promise<EmitResult> {\n    return this.handleRequest<EmitResult>('emitFile', fileName);\n  }\n\n  getDiagnostics(fileName: string): Promise<GetDiagnosticsResult> {\n    return this.handleRequest<GetDiagnosticsResult>('getDiagnostics', fileName);\n  }\n\n  dumpSymbolsWithComments(fileName: string): Promise<DumpedSymbolsWithComments> {\n    return this.handleRequest<DumpedSymbolsWithComments>('dumpSymbolsWithComments', fileName);\n  }\n\n  getInterfaceAST(fileName: string, position: number): Promise<DumpedInterface> {\n    return this.handleRequest<DumpedInterface>('getInterfaceAST', fileName, position);\n  }\n\n  getEnumAST(fileName: string, position: number): Promise<DumpEnumResponseBody> {\n    return this.handleRequest<DumpEnumResponseBody>('getEnumAST', fileName, position);\n  }\n\n  getFunctionAST(fileName: string, position: number): Promise<DumpFunctionResponseBody> {\n    return this.handleRequest<DumpFunctionResponseBody>('getFunctionAST', fileName, position);\n  }\n}\n\ninterface TestCompilationCacheEntry {\n  container: string;\n  hash: string;\n  data: string;\n}\n\nclass TestCompilationCache implements ICompilationCache {\n  entriesByPath: { [key: string]: TestCompilationCacheEntry[] } = {};\n\n  private doResolveEntry(path: string, container: string, hash: string): TestCompilationCacheEntry | undefined {\n    const entries = this.entriesByPath[path];\n    if (!entries) {\n      return undefined;\n    }\n    for (const entry of entries) {\n      if (entry.container === container) {\n        if (entry.hash === hash) {\n          return entry;\n        } else {\n          return undefined;\n        }\n      }\n    }\n\n    return undefined;\n  }\n\n  close(): void {}\n\n  evictEntriesBeforeTime(lastUsedTimestamp: number): void {}\n\n  async getCachedEntry(path: string, container: string, hash: string): Promise<string | undefined> {\n    return this.doResolveEntry(path, container, hash)?.data;\n  }\n\n  async setCachedEntry(path: string, container: string, hash: string, data: string): Promise<void> {\n    let entry = this.doResolveEntry(path, container, hash);\n    if (!entry) {\n      entry = { container, hash, data };\n      let entries = this.entriesByPath[path];\n      if (!entries) {\n        entries = [];\n        this.entriesByPath[path] = entries;\n      }\n      entries.push(entry);\n    } else {\n      entry.data = data;\n    }\n  }\n}\n\ndescribe('CachingWorkspace', () => {\n  it('stores open file in cache', async () => {\n    const innerWorkspace = new TestWorkspace();\n    const cache = new TestCompilationCache();\n\n    let workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'Hello World');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: 'Bar', absolute: '/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    let result = await workspace.openFile('Foo.ts');\n\n    expect(result.importPaths).toEqual([{ relative: 'Bar', absolute: '/Bar' }]);\n\n    // now recreate the workspace and perform the request again. It should hit the cache\n    workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'Hello World');\n\n    result = await workspace.openFile('Foo.ts');\n\n    expect(result.importPaths).toEqual([{ relative: 'Bar', absolute: '/Bar' }]);\n\n    // Recreate the workspace and change the file content. It should not hit the cache.\n    workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'Goodbye World');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: 'Bar2', absolute: '/Bar2' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    result = await workspace.openFile('Foo.ts');\n\n    expect(result.importPaths).toEqual([{ relative: 'Bar2', absolute: '/Bar2' }]);\n  });\n\n  it('uses dependent files to compute hash', async () => {\n    const innerWorkspace = new TestWorkspace();\n    const cache = new TestCompilationCache();\n\n    let workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'A');\n    workspace.registerInMemoryFile('Bar.ts', 'B');\n    workspace.registerInMemoryFile('Last.ts', 'C');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: 'Bar', absolute: '/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Bar.ts', undefined, {\n      importPaths: [{ relative: 'Last', absolute: '/Last' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Last.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    await workspace.openFile('Foo.ts');\n\n    // We should not have asked to open Bar.ts and Last.ts yet\n    expect(innerWorkspace.responseHandlers.length).toBe(2);\n    expect(cache.entriesByPath).toEqual({\n      '/Foo.ts': [\n        {\n          container: 'import_paths',\n          hash: '559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd',\n          data: '{\"importPaths\":[{\"relative\":\"Bar\",\"absolute\":\"/Bar\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n      ],\n    });\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    // Now we ask to emit the file\n\n    let result = await workspace.emitFile('/Foo.ts');\n    expect(result).toEqual({\n      entries: [],\n      emitted: true,\n    });\n\n    // All the request handlers should have been exhausted. It should have requested\n    // to open all the dependent files\n    expect(innerWorkspace.responseHandlers.length).toBe(0);\n    expect(cache.entriesByPath).toEqual({\n      '/Foo.ts': [\n        {\n          container: 'import_paths',\n          hash: '559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd',\n          data: '{\"importPaths\":[{\"relative\":\"Bar\",\"absolute\":\"/Bar\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n        {\n          container: 'emit_file',\n          hash: 'a06f2a8faa0695f12035b9ca694f1a430aa2a4f374f1639ed218db2d2962acfe',\n          data: '{\"entries\":[],\"emitted\":true}',\n        },\n      ],\n      '/Bar.ts': [\n        {\n          container: 'import_paths',\n          hash: 'df7e70e5021544f4834bbee64a9e3789febc4be81470df629cad6ddb03320a5c',\n          data: '{\"importPaths\":[{\"relative\":\"Last\",\"absolute\":\"/Last\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n      ],\n      '/Last.ts': [\n        {\n          container: 'import_paths',\n          hash: '6b23c0d5f35d1b11f9b683f0b0a617355deb11277d91ae091d399c655b87940d',\n          data: '{\"importPaths\":[],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n      ],\n    });\n\n    // Re-create workspace with same files\n    workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'A');\n    workspace.registerInMemoryFile('Bar.ts', 'B');\n    workspace.registerInMemoryFile('Last.ts', 'C');\n\n    await workspace.openFile('Foo.ts');\n    // Should be able to retrieve info from cache\n    result = await workspace.emitFile('/Foo.ts');\n    expect(result).toEqual({\n      entries: [],\n      emitted: true,\n    });\n\n    // Re-create workspace and change Last.ts content\n    workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'A');\n    workspace.registerInMemoryFile('Bar.ts', 'B');\n    workspace.registerInMemoryFile('Last.ts', 'D');\n\n    await workspace.openFile('Foo.ts');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: 'Bar', absolute: '/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Last.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    result = await workspace.emitFile('/Foo.ts');\n\n    expect(cache.entriesByPath).toEqual({\n      '/Foo.ts': [\n        {\n          container: 'import_paths',\n          hash: '559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd',\n          data: '{\"importPaths\":[{\"relative\":\"Bar\",\"absolute\":\"/Bar\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n        {\n          container: 'emit_file',\n          hash: 'a06f2a8faa0695f12035b9ca694f1a430aa2a4f374f1639ed218db2d2962acfe',\n          data: '{\"entries\":[],\"emitted\":true}',\n        },\n        {\n          data: '{\"entries\":[],\"emitted\":true}',\n          hash: 'a5d0cb5e3d68c7dc768033126974223f7a6fb4a3ed67821cc41436d93b76300c',\n          container: 'emit_file',\n        },\n      ],\n      '/Bar.ts': [\n        {\n          container: 'import_paths',\n          hash: 'df7e70e5021544f4834bbee64a9e3789febc4be81470df629cad6ddb03320a5c',\n          data: '{\"importPaths\":[{\"relative\":\"Last\",\"absolute\":\"/Last\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n      ],\n      '/Last.ts': [\n        {\n          container: 'import_paths',\n          hash: '6b23c0d5f35d1b11f9b683f0b0a617355deb11277d91ae091d399c655b87940d',\n          data: '{\"importPaths\":[],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n        {\n          data: '{\"importPaths\":[],\"isNonModuleWithAmbiantDeclarations\":false}',\n          hash: '3f39d5c348e5b79d06e842c114e6cc571583bbf44e4b0ebfda1a01ec05745d43',\n          container: 'import_paths',\n        },\n      ],\n    });\n  });\n\n  it('resolves relative import paths', async () => {\n    const innerWorkspace = new TestWorkspace();\n    const cache = new TestCompilationCache();\n\n    let workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('dir/a/Foo.ts', 'A');\n    workspace.registerInMemoryFile('other/b/Bar.ts', 'B');\n    workspace.registerInMemoryFile('other/b/Last.ts', 'C');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/dir/a/Foo.ts', undefined, {\n      importPaths: [{ relative: '../../other/b/Bar', absolute: '/other/b/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/other/b/Bar.ts', undefined, {\n      importPaths: [{ relative: './Last', absolute: '/other/b/Last' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/other/b/Last.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/dir/a/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    await workspace.openFile('dir/a/Foo.ts');\n    const result = await workspace.emitFile('/dir/a/Foo.ts');\n    expect(result).toEqual({\n      entries: [],\n      emitted: true,\n    });\n\n    expect(cache.entriesByPath).toEqual({\n      '/dir/a/Foo.ts': [\n        {\n          container: 'import_paths',\n          hash: '559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd',\n          data: '{\"importPaths\":[{\"relative\":\"../../other/b/Bar\",\"absolute\":\"/other/b/Bar\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n        {\n          container: 'emit_file',\n          hash: 'a06f2a8faa0695f12035b9ca694f1a430aa2a4f374f1639ed218db2d2962acfe',\n          data: '{\"entries\":[],\"emitted\":true}',\n        },\n      ],\n      '/other/b/Bar.ts': [\n        {\n          container: 'import_paths',\n          hash: 'df7e70e5021544f4834bbee64a9e3789febc4be81470df629cad6ddb03320a5c',\n          data: '{\"importPaths\":[{\"relative\":\"./Last\",\"absolute\":\"/other/b/Last\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n      ],\n      '/other/b/Last.ts': [\n        {\n          container: 'import_paths',\n          hash: '6b23c0d5f35d1b11f9b683f0b0a617355deb11277d91ae091d399c655b87940d',\n          data: '{\"importPaths\":[],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n      ],\n    });\n  });\n\n  it('resolves absolute import paths', async () => {\n    const innerWorkspace = new TestWorkspace();\n    const cache = new TestCompilationCache();\n\n    let workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('dir/a/Foo.ts', 'A');\n    workspace.registerInMemoryFile('other/b/Bar.ts', 'B');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/dir/a/Foo.ts', undefined, {\n      importPaths: [{ relative: 'other/b/Bar', absolute: '/other/b/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/other/b/Bar.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/dir/a/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    await workspace.openFile('dir/a/Foo.ts');\n    const result = await workspace.emitFile('/dir/a/Foo.ts');\n    expect(result).toEqual({\n      entries: [],\n      emitted: true,\n    });\n\n    expect(cache.entriesByPath).toEqual({\n      '/dir/a/Foo.ts': [\n        {\n          container: 'import_paths',\n          hash: '559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd',\n          data: '{\"importPaths\":[{\"relative\":\"other/b/Bar\",\"absolute\":\"/other/b/Bar\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n        {\n          container: 'emit_file',\n          hash: '5b5554131b95d5d7362050de7fe6545c94927b23dde06a0a7565d6d82d6a526c',\n          data: '{\"entries\":[],\"emitted\":true}',\n        },\n      ],\n      '/other/b/Bar.ts': [\n        {\n          container: 'import_paths',\n          hash: 'df7e70e5021544f4834bbee64a9e3789febc4be81470df629cad6ddb03320a5c',\n          data: '{\"importPaths\":[],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n      ],\n    });\n  });\n\n  it('resolves definition ts files', async () => {\n    const innerWorkspace = new TestWorkspace();\n    const cache = new TestCompilationCache();\n\n    let workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'A');\n    workspace.registerInMemoryFile('Bar.d.ts', 'B');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: 'Bar', absolute: '/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Bar.d.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    await workspace.openFile('Foo.ts');\n    const result = await workspace.emitFile('/Foo.ts');\n    expect(result).toEqual({\n      entries: [],\n      emitted: true,\n    });\n\n    expect(cache.entriesByPath).toEqual({\n      '/Foo.ts': [\n        {\n          container: 'import_paths',\n          hash: '559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd',\n          data: '{\"importPaths\":[{\"relative\":\"Bar\",\"absolute\":\"/Bar\"}],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n        {\n          container: 'emit_file',\n          hash: '5b5554131b95d5d7362050de7fe6545c94927b23dde06a0a7565d6d82d6a526c',\n          data: '{\"entries\":[],\"emitted\":true}',\n        },\n      ],\n      '/Bar.d.ts': [\n        {\n          container: 'import_paths',\n          hash: 'df7e70e5021544f4834bbee64a9e3789febc4be81470df629cad6ddb03320a5c',\n          data: '{\"importPaths\":[],\"isNonModuleWithAmbiantDeclarations\":false}',\n        },\n      ],\n    });\n  });\n\n  it('supports circular imports', async () => {\n    const innerWorkspace = new TestWorkspace();\n    const cache = new TestCompilationCache();\n\n    let workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'A');\n    workspace.registerInMemoryFile('Bar.ts', 'B');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: './Bar', absolute: '/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Bar.ts', undefined, {\n      importPaths: [{ relative: './Foo', absolute: '/Foo' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    await workspace.openFile('Foo.ts');\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Bar.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    await workspace.emitFile('/Foo.ts');\n    await workspace.emitFile('/Bar.ts');\n\n    expect(innerWorkspace.responseHandlers.length).toBe(0);\n\n    // Invalidating Foo should invalidate both files\n    workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'C');\n    workspace.registerInMemoryFile('Bar.ts', 'B');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: './Bar', absolute: '/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Bar.ts', undefined, {\n      importPaths: [{ relative: './Foo', absolute: '/Foo' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Bar.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    await workspace.openFile('Foo.ts');\n    await workspace.emitFile('/Foo.ts');\n    await workspace.emitFile('/Bar.ts');\n\n    expect(innerWorkspace.responseHandlers.length).toBe(0);\n\n    // Invalidating Bar should invalidate both files as well\n    workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'C');\n    workspace.registerInMemoryFile('Bar.ts', 'D');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: './Bar', absolute: '/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Bar.ts', undefined, {\n      importPaths: [{ relative: './Foo', absolute: '/Foo' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Bar.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    await workspace.openFile('Bar.ts');\n    await workspace.emitFile('/Foo.ts');\n    await workspace.emitFile('/Bar.ts');\n\n    expect(innerWorkspace.responseHandlers.length).toBe(0);\n  });\n\n  it('invalidates files on hot reload', async () => {\n    const innerWorkspace = new TestWorkspace();\n    const cache = new TestCompilationCache();\n\n    let workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'A');\n    workspace.registerInMemoryFile('Bar.ts', 'B');\n    workspace.registerInMemoryFile('Last.ts', 'C');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: 'Bar', absolute: '/Bar' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Bar.ts', undefined, {\n      importPaths: [{ relative: 'Last', absolute: '/Last' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Last.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    await workspace.openFile('Foo.ts');\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    // Now we ask to emit the file\n\n    await workspace.emitFile('/Foo.ts');\n\n    expect(innerWorkspace.responseHandlers.length).toBe(0);\n\n    // Invalidate with same files\n    workspace.registerInMemoryFile('Foo.ts', 'A');\n    workspace.registerInMemoryFile('Bar.ts', 'B');\n    workspace.registerInMemoryFile('Last.ts', 'C');\n\n    await workspace.openFile('Foo.ts');\n    // Should be able to retrieve info from cache\n    await workspace.emitFile('/Foo.ts');\n\n    // Change Last.ts content\n    workspace.registerInMemoryFile('Last.ts', 'D');\n\n    await workspace.openFile('Foo.ts');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [{ relative: 'Bar.ts', absolute: '/Bar.ts' }],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Last.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: false,\n    });\n\n    innerWorkspace.appendNextRequestHandler<EmitResult>('emitFile', '/Foo.ts', undefined, {\n      entries: [],\n      emitted: true,\n    });\n\n    await workspace.emitFile('/Foo.ts');\n\n    expect(innerWorkspace.responseHandlers.length).toBe(0);\n  });\n\n  it('always open file with ambiant declarations in nested workspace', async () => {\n    const innerWorkspace = new TestWorkspace();\n    const cache = new TestCompilationCache();\n\n    let workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'Hello World');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: true,\n    });\n\n    await workspace.openFile('Foo.ts');\n\n    expect(innerWorkspace.responseHandlers.length).toEqual(0);\n\n    // now recreate the workspace and perform the request again. It should hit the inner workspace\n    // since isNonModuleWithAmbiantDeclarations is true\n    workspace = new CachingWorkspace(innerWorkspace, cache, undefined);\n    workspace.registerInMemoryFile('Foo.ts', 'Hello World');\n\n    innerWorkspace.appendNextRequestHandler<OpenFileResult>('openFile', '/Foo.ts', undefined, {\n      importPaths: [],\n      isNonModuleWithAmbiantDeclarations: true,\n    });\n\n    await workspace.openFile('Foo.ts');\n\n    expect(innerWorkspace.responseHandlers.length).toEqual(0);\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/cache/CachingWorkspace.ts",
    "content": "import ts = require('typescript');\nimport { ILogger } from '../logger/ILogger';\nimport { EmitResult, GetDiagnosticsResult, IWorkspace, OpenFileImportPath, OpenFileResult } from '../IWorkspace';\nimport { FileManager, FilePath } from '../project/FileManager';\nimport {\n  DumpEnumResponseBody,\n  DumpFunctionResponseBody,\n  DumpedSymbolsWithComments,\n  DumpedInterface,\n} from '../protocol';\nimport { rethrow } from '../utils/rethrow';\nimport { generateSHA256HashFromString, generateSHA256HashFromStrings } from '../utils/sha256';\nimport { ICompilationCache } from './ICompilationCache';\nimport * as _path from 'path';\nimport { Stopwatch } from '../utils/Stopwatch';\nimport { SerialTaskQueue } from '../utils/SerialTaskQueue';\nimport { CircularLoopTracker, CircularLoopTrackerPushResult } from './CircularLoopTracker';\n\ninterface ImportPaths {\n  relatives: string[];\n  absolutes: string[];\n  isNonModuleWithAmbiantDeclarations: boolean;\n}\n\ninterface CachedImportPaths {\n  importPaths: OpenFileImportPath[];\n  isNonModuleWithAmbiantDeclarations: boolean;\n}\n\ninterface CachedFileInfo {\n  shallowHash: string;\n  filePath: FilePath;\n  recursiveHash: string | undefined;\n  importPaths: ImportPaths | undefined;\n  dependentFiles: Set<string> | undefined;\n  openedInInnerWorkspace: boolean;\n}\n\ninterface RecursiveHashEntry {\n  entry: CachedFileInfo;\n  hashPrefixes: string[];\n  importsToInclude: CachedFileInfo[];\n}\n\ninterface OnCacheMissResult<T> {\n  value: T;\n  shouldCache: boolean;\n}\n\nconst enum CacheKey {\n  importPaths = 'import_paths',\n  emitFile = 'emit_file',\n  getDiagnostics = 'get_diagnostics',\n  dumpSymbols = 'dump_symbols',\n  getInterfaceAST = 'get_interface_ast',\n  getEnumAST = 'get_enum_ast',\n  getFunctionAST = 'get_function_ast',\n}\n\nconst CACHE_TTL_MS = 1000 * 60 * 60 * 24 * 30; // 30 days\n\nexport class CachingWorkspace implements IWorkspace {\n  get initialized(): boolean {\n    return this.workspace.initialized;\n  }\n\n  get workspaceRoot(): string {\n    return this.workspace.workspaceRoot;\n  }\n\n  private fileManager: FileManager;\n  private fileInfoCache = new Map<string, CachedFileInfo>();\n  private taskQueue = new SerialTaskQueue();\n\n  constructor(\n    private readonly workspace: IWorkspace,\n    private readonly cache: ICompilationCache,\n    private readonly logger: ILogger | undefined,\n  ) {\n    this.fileManager = new FileManager(workspace.workspaceRoot);\n  }\n\n  initialize(): void {\n    this.workspace.initialize();\n    this.cache.evictEntriesBeforeTime(Date.now() - CACHE_TTL_MS);\n  }\n\n  destroy(): void {\n    this.workspace.destroy();\n    this.cache.close();\n  }\n\n  private async measureAndLog<T>(command: string, path: string, work: () => Promise<T>): Promise<T> {\n    if (!this.logger) {\n      return await work();\n    }\n\n    const sw = new Stopwatch();\n    this.logger?.debug?.(`Begin ${command} on '${path}'`);\n    const result = await work();\n\n    this.logger?.debug?.(`End ${command} on '${path}' in ${sw.elapsedString}`);\n    return result;\n  }\n\n  private invalidateFileInfo(absolutePath: string): void {\n    const fileInfo = this.fileInfoCache.get(absolutePath);\n    if (fileInfo) {\n      this.fileInfoCache.delete(absolutePath);\n\n      if (fileInfo.dependentFiles) {\n        for (const dependentFile of fileInfo.dependentFiles) {\n          this.invalidateFileInfo(dependentFile);\n        }\n      }\n    }\n  }\n\n  registerInMemoryFile(fileName: string, fileContent: string): void {\n    const filePath = this.fileManager.resolvePath(fileName);\n    this.fileManager.addFileInMemory(filePath, fileContent);\n\n    this.workspace.registerInMemoryFile(fileName, fileContent);\n\n    this.invalidateFileInfo(filePath.absolutePath);\n  }\n\n  registerDiskFile(fileName: string, absoluteDiskCachePath: string): void {\n    const filePath = this.fileManager.resolvePath(fileName);\n    this.fileManager.addFileInDisk(filePath, absoluteDiskCachePath);\n\n    this.workspace.registerDiskFile(fileName, absoluteDiskCachePath);\n\n    this.invalidateFileInfo(filePath.absolutePath);\n  }\n\n  async openFile(fileName: string): Promise<OpenFileResult> {\n    const cachedFileInfo = this.getCachedFileInfo(fileName);\n    const importPaths = await this.resolveImportPaths(cachedFileInfo);\n\n    return {\n      importPaths: importPaths.relatives.map((i, index) => {\n        return { absolute: importPaths.absolutes[index], relative: i };\n      }),\n      isNonModuleWithAmbiantDeclarations: importPaths.isNonModuleWithAmbiantDeclarations,\n    };\n  }\n\n  async emitFile(fileName: string): Promise<EmitResult> {\n    return this.processAndCacheRequest(fileName, CacheKey.emitFile, (workspace, fileName) =>\n      workspace.emitFile(fileName),\n    );\n  }\n\n  async getDiagnostics(fileName: string): Promise<GetDiagnosticsResult> {\n    return this.processRequest(fileName, CacheKey.getDiagnostics, (workspace, fileName) =>\n      workspace.getDiagnostics(fileName).then((value) => {\n        const shouldCache = !value.hasError;\n        return { shouldCache, value };\n      }),\n    );\n  }\n\n  async dumpSymbolsWithComments(fileName: string): Promise<DumpedSymbolsWithComments> {\n    return this.processAndCacheRequest(fileName, CacheKey.dumpSymbols, (workspace, fileName) =>\n      workspace.dumpSymbolsWithComments(fileName),\n    );\n  }\n\n  async getInterfaceAST(fileName: string, position: number): Promise<DumpedInterface> {\n    return this.processAndCacheRequest(fileName, `${CacheKey.getInterfaceAST}-${position}`, (workspace, fileName) =>\n      workspace.getInterfaceAST(fileName, position),\n    );\n  }\n\n  async getEnumAST(fileName: string, position: number): Promise<DumpEnumResponseBody> {\n    return this.processAndCacheRequest(fileName, `${CacheKey.getEnumAST}-${position}`, (workspace, fileName) =>\n      workspace.getEnumAST(fileName, position),\n    );\n  }\n\n  async getFunctionAST(fileName: string, position: number): Promise<DumpFunctionResponseBody> {\n    return this.processAndCacheRequest(fileName, `${CacheKey.getFunctionAST}-${position}`, (workspace, fileName) =>\n      workspace.getFunctionAST(fileName, position),\n    );\n  }\n\n  resolveImportPath(fromPath: string, toPath: string): string {\n    return this.workspace.resolveImportPath(fromPath, toPath);\n  }\n\n  getFileNameForImportPath(importPath: string): string {\n    return this.workspace.getFileNameForImportPath(importPath);\n  }\n\n  private processRequest<T>(\n    fileName: string,\n    cacheKey: string,\n    onCacheMiss: (workspace: IWorkspace, fileName: string) => Promise<OnCacheMissResult<T>>,\n  ): Promise<T> {\n    return this.measureAndLog(cacheKey, fileName, async () => {\n      const fileInfo = await this.getResolvedCachedFileInfo(fileName);\n      const cachedRequestEntry = await this.getCachedItemForFile(fileInfo, cacheKey);\n      if (cachedRequestEntry) {\n        return cachedRequestEntry as T;\n      }\n\n      await this.openFileInInnerWorkspaceIfNeeded(fileInfo);\n\n      this.logger?.debug?.(`Cache miss for ${cacheKey} on file ${fileName} (recursiveKey: ${fileInfo.recursiveHash})`);\n\n      const newResult = await onCacheMiss(this.workspace, fileName);\n\n      if (newResult.shouldCache) {\n        this.setCachedItemForFile(fileInfo, cacheKey, newResult.value);\n      }\n\n      return newResult.value;\n    });\n  }\n\n  private processAndCacheRequest<T>(\n    fileName: string,\n    cacheKey: string,\n    onCacheMiss: (workspace: IWorkspace, fileName: string) => Promise<T>,\n  ): Promise<T> {\n    return this.processRequest(fileName, cacheKey, (workspace, filename) => {\n      return onCacheMiss(workspace, fileName).then((value) => {\n        return { shouldCache: true, value };\n      });\n    });\n  }\n\n  private getCachedItemForFile(cacheInfo: CachedFileInfo, cacheKey: string): Promise<unknown | undefined> {\n    if (!cacheInfo.recursiveHash) {\n      throw new Error('Cannot get a cache entry without resolving the recursive hash first');\n    }\n\n    return this.getCachedItemForFileAndHash(cacheInfo, cacheInfo.recursiveHash, cacheKey);\n  }\n\n  private async getCachedItemForFileAndHash(\n    cacheInfo: CachedFileInfo,\n    hash: string,\n    cacheKey: string,\n  ): Promise<unknown | undefined> {\n    try {\n      const entry = await this.cache.getCachedEntry(cacheInfo.filePath.absolutePath, cacheKey, hash);\n      if (!entry) {\n        return undefined;\n      }\n\n      return JSON.parse(entry);\n    } catch {\n      return undefined;\n    }\n  }\n\n  private setCachedItemForFile(cacheInfo: CachedFileInfo, cacheKey: string, item: unknown): void {\n    if (!cacheInfo.recursiveHash) {\n      throw new Error('Cannot get a cache entry without resolving the recursive hash first');\n    }\n\n    this.setCachedItemForFileAndHash(cacheInfo, cacheInfo.recursiveHash, cacheKey, item);\n  }\n\n  private setCachedItemForFileAndHash(cacheInfo: CachedFileInfo, hash: string, cacheKey: string, item: unknown): void {\n    const json = JSON.stringify(item);\n\n    try {\n      this.cache.setCachedEntry(cacheInfo.filePath.absolutePath, cacheKey, hash, json);\n    } catch (err) {\n      this.logger?.error?.(`Failed to set cached entry`, err);\n    }\n  }\n\n  private async getImportPathsFromCache(cacheInfo: CachedFileInfo): Promise<CachedImportPaths | undefined> {\n    const importPaths = await this.getCachedItemForFileAndHash(cacheInfo, cacheInfo.shallowHash, CacheKey.importPaths);\n    if (!importPaths) {\n      return undefined;\n    }\n\n    if (typeof importPaths !== 'object') {\n      return undefined;\n    }\n\n    const cachedImportPaths = importPaths as CachedImportPaths;\n\n    if (\n      !Array.isArray(cachedImportPaths.importPaths) ||\n      (cachedImportPaths.importPaths.length > 0 && typeof cachedImportPaths.importPaths[0] !== 'object')\n    ) {\n      return undefined;\n    }\n\n    return cachedImportPaths;\n  }\n\n  private async doOpenFileInInnerWorkspace(cacheFileInfo: CachedFileInfo): Promise<ImportPaths> {\n    const openedFile = await this.workspace.openFile(cacheFileInfo.filePath.absolutePath);\n    const importPaths = openedFile.importPaths;\n    cacheFileInfo.importPaths = this.makeImportPaths(importPaths, openedFile.isNonModuleWithAmbiantDeclarations);\n    cacheFileInfo.openedInInnerWorkspace = true;\n\n    const cachedImportPaths: CachedImportPaths = {\n      importPaths,\n      isNonModuleWithAmbiantDeclarations: openedFile.isNonModuleWithAmbiantDeclarations,\n    };\n\n    this.setCachedItemForFileAndHash(cacheFileInfo, cacheFileInfo.shallowHash, CacheKey.importPaths, cachedImportPaths);\n\n    return cacheFileInfo.importPaths;\n  }\n\n  private async openFileInInnerWorkspaceIfNeeded(cacheFileInfo: CachedFileInfo): Promise<void> {\n    if (!cacheFileInfo.openedInInnerWorkspace) {\n      await this.doOpenFileInInnerWorkspace(cacheFileInfo);\n    }\n  }\n\n  private makeImportPaths(importPaths: OpenFileImportPath[], isNonModuleWithAmbiantDeclarations: boolean): ImportPaths {\n    const relativeImportPaths = importPaths.map((i) => i.relative);\n    const absoluteImportPaths = importPaths.map((i) => i.absolute);\n\n    return {\n      relatives: relativeImportPaths,\n      absolutes: absoluteImportPaths,\n      isNonModuleWithAmbiantDeclarations,\n    };\n  }\n\n  private async resolveImportPaths(cacheFileInfo: CachedFileInfo): Promise<ImportPaths> {\n    // First we need to resolve the import paths\n    // Use the compilation cache to see if it exists\n\n    if (cacheFileInfo.importPaths) {\n      return cacheFileInfo.importPaths;\n    }\n\n    const importPaths = await this.getImportPathsFromCache(cacheFileInfo);\n    if (importPaths) {\n      cacheFileInfo.importPaths = this.makeImportPaths(\n        importPaths.importPaths,\n        importPaths.isNonModuleWithAmbiantDeclarations,\n      );\n\n      if (importPaths.isNonModuleWithAmbiantDeclarations) {\n        this.logger?.debug?.(\n          `Opening non module file with ambiant declarations ${cacheFileInfo.filePath.absolutePath}`,\n        );\n      } else {\n        return cacheFileInfo.importPaths;\n      }\n    } else {\n      this.logger?.debug?.(\n        `Could not resolve import paths from cache ${cacheFileInfo.filePath.absolutePath} (shallowKey: ${cacheFileInfo.shallowHash})`,\n      );\n    }\n\n    // We don't have import paths for the file.\n    // We need to load the file inside the attached workspace\n    return this.doOpenFileInInnerWorkspace(cacheFileInfo);\n  }\n\n  private async resolveImportedFiles(fileInfo: CachedFileInfo): Promise<CachedFileInfo[]> {\n    const output: CachedFileInfo[] = [];\n    const absoluteImportPaths = (await this.resolveImportPaths(fileInfo)).absolutes;\n\n    for (const absoluteImportPath of absoluteImportPaths) {\n      try {\n        const importedFileInfo = this.getCachedFileInfo(absoluteImportPath);\n        output.push(importedFileInfo);\n      } catch (error: unknown) {\n        this.logger?.warn?.(\n          `Could not import file ${absoluteImportPath} from ${fileInfo.filePath.absolutePath} (${\n            (error as Error).message\n          })`,\n        );\n      }\n    }\n\n    return output;\n  }\n\n  private computeAndSaveRecursiveHash(\n    fileInfo: CachedFileInfo,\n    startingHashes: string[],\n    importedFiles: CachedFileInfo[],\n  ): boolean {\n    const allHashes = [...startingHashes];\n\n    for (const importedFile of importedFiles) {\n      if (!importedFile.recursiveHash) {\n        return false;\n      }\n      allHashes.push(importedFile.recursiveHash);\n    }\n\n    fileInfo.recursiveHash = generateSHA256HashFromStrings(allHashes);\n    this.logger?.debug?.(`Resolved recursive hash of ${fileInfo.filePath.absolutePath} as ${fileInfo.recursiveHash}`);\n\n    return true;\n  }\n\n  private async gatherFileDependencies(\n    fileInfo: CachedFileInfo,\n    importedFilesByFileInfo: Map<string, CachedFileInfo[]>,\n    circularLoopTracker: CircularLoopTracker,\n  ): Promise<void> {\n    if (fileInfo.recursiveHash) {\n      return;\n    }\n\n    switch (circularLoopTracker.push(fileInfo.filePath.absolutePath)) {\n      case CircularLoopTrackerPushResult.alreadyVisited:\n      case CircularLoopTrackerPushResult.circular:\n        return;\n      case CircularLoopTrackerPushResult.nonCircular:\n        break;\n    }\n\n    this.logger?.debug?.(`Resolving recursive hash of ${fileInfo.filePath.absolutePath}`);\n    try {\n      const importedFiles = await this.resolveImportedFiles(fileInfo);\n      importedFilesByFileInfo.set(fileInfo.filePath.absolutePath, importedFiles);\n\n      for (const importedFile of importedFiles) {\n        if (!importedFile.dependentFiles) {\n          importedFile.dependentFiles = new Set();\n        }\n\n        importedFile.dependentFiles.add(fileInfo.filePath.absolutePath);\n\n        await this.gatherFileDependencies(importedFile, importedFilesByFileInfo, circularLoopTracker);\n      }\n    } catch (err) {\n      rethrow(`While gathering dependencies of '${fileInfo.filePath.absolutePath}'`, err);\n    } finally {\n      circularLoopTracker.pop();\n    }\n  }\n\n  private makeRecursiveHashEntries(\n    fileInfo: CachedFileInfo,\n    circularLoopTracker: CircularLoopTracker,\n    importedFilesByFileInfo: Map<string, CachedFileInfo[]>,\n    seen: Set<string>,\n    output: RecursiveHashEntry[],\n  ): void {\n    const path = fileInfo.filePath.absolutePath;\n    if (fileInfo.recursiveHash || seen.has(path)) {\n      return;\n    }\n\n    seen.add(path);\n\n    const circularEntries = circularLoopTracker.getCircularEntriesForEntry(path);\n\n    const hashPrefixes: string[] = [fileInfo.shallowHash];\n    const imports = importedFilesByFileInfo.get(fileInfo.filePath.absolutePath)!;\n    let importsToInclude: CachedFileInfo[];\n\n    if (circularEntries) {\n      const sortedEntries = [...circularEntries].sort();\n      for (const entry of sortedEntries) {\n        hashPrefixes.push(this.getCachedFileInfo(entry).shallowHash);\n      }\n      importsToInclude = [];\n      for (const importedFile of imports) {\n        if (!circularEntries.has(importedFile.filePath.absolutePath)) {\n          importsToInclude.push(importedFile);\n        }\n      }\n    } else {\n      importsToInclude = imports;\n    }\n    output.push({ entry: fileInfo, hashPrefixes, importsToInclude });\n\n    for (const importedFile of imports) {\n      this.makeRecursiveHashEntries(importedFile, circularLoopTracker, importedFilesByFileInfo, seen, output);\n    }\n  }\n\n  private computeRecursiveHashes(entries: RecursiveHashEntry[]): number {\n    let entriesToRetry: RecursiveHashEntry[] | undefined;\n    let updatedCount = 0;\n    for (let i = entries.length; i > 0; i--) {\n      const j = i - 1;\n      const entry = entries[j];\n      if (this.computeAndSaveRecursiveHash(entry.entry, entry.hashPrefixes, entry.importsToInclude)) {\n        updatedCount++;\n      } else {\n        if (!entriesToRetry) {\n          entriesToRetry = [];\n        }\n        entriesToRetry.push(entry);\n      }\n      entries.pop();\n    }\n\n    if (entriesToRetry) {\n      for (let i = entriesToRetry.length; i > 0; i--) {\n        entries.push(entriesToRetry[i - 1]);\n      }\n    }\n\n    return updatedCount;\n  }\n\n  private async resolveRecursiveHash(fileInfo: CachedFileInfo): Promise<void> {\n    const circularLoopTracker = new CircularLoopTracker();\n    const importedFilesByFileInfo = new Map<string, CachedFileInfo[]>();\n    await this.gatherFileDependencies(fileInfo, importedFilesByFileInfo, circularLoopTracker);\n\n    let recursiveHashEntries: RecursiveHashEntry[] = [];\n\n    this.makeRecursiveHashEntries(\n      fileInfo,\n      circularLoopTracker,\n      importedFilesByFileInfo,\n      new Set(),\n      recursiveHashEntries,\n    );\n\n    while (recursiveHashEntries.length) {\n      if (this.computeRecursiveHashes(recursiveHashEntries) === 0) {\n        throw new Error('Could not resolve recursive hashes');\n      }\n    }\n  }\n\n  private getResolvedCachedFileInfo(fileName: string): Promise<CachedFileInfo> {\n    // We can only resolve one cache file info at a given time.\n    // The task queue makes sure that the processing is serial, even if we use async operations\n    // underneath.\n    return this.taskQueue.enqueueAsyncTask(async () => {\n      const cacheFileInfo = this.getCachedFileInfo(fileName);\n\n      if (!cacheFileInfo.recursiveHash) {\n        await this.resolveRecursiveHash(cacheFileInfo);\n      }\n\n      return cacheFileInfo;\n    });\n  }\n\n  private resolvePath(fileName: string): FilePath {\n    const resolvedFileName = this.workspace.getFileNameForImportPath(fileName) ?? fileName;\n    return this.fileManager.resolvePath(resolvedFileName);\n  }\n\n  private getCachedFileInfo(fileName: string): CachedFileInfo {\n    const resolvedPath = this.resolvePath(fileName);\n    const existingCachedFileInfo = this.fileInfoCache.get(resolvedPath.absolutePath);\n    if (existingCachedFileInfo) {\n      return existingCachedFileInfo;\n    }\n\n    const fileContent = this.fileManager.getFile(resolvedPath).content;\n    const shallowHash = generateSHA256HashFromString(fileContent);\n\n    this.logger?.debug?.(`Resolved shallow hash of ${resolvedPath.absolutePath} as ${shallowHash}`);\n\n    const cachedFileInfo: CachedFileInfo = {\n      shallowHash,\n      filePath: resolvedPath,\n      recursiveHash: undefined,\n      importPaths: undefined,\n      dependentFiles: undefined,\n      openedInInnerWorkspace: false,\n    };\n    this.fileInfoCache.set(resolvedPath.absolutePath, cachedFileInfo);\n\n    return cachedFileInfo;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/cache/CachingWorkspaceFactory.ts",
    "content": "import path = require('path');\nimport { IWorkspace } from '../IWorkspace';\nimport { SQLiteCompilationCache } from './SQLiteCompilationCache';\nimport { CachingWorkspace } from './CachingWorkspace';\nimport { ILogger } from '../logger/ILogger';\n\n/**\n * Should be incremented every time the workspace implementation changes.\n */\nconst CACHE_VERSION = '2';\n\nexport function createCachingWorkspace(\n  cacheDir: string,\n  sourceWorkspace: IWorkspace,\n  logger: ILogger | undefined,\n): IWorkspace {\n  const dbPath = path.resolve(cacheDir, 'compilecache.db');\n  const compilationCache = new SQLiteCompilationCache(\n    dbPath,\n    CACHE_VERSION,\n    {\n      getCurrentTimestamp() {\n        return Date.now();\n      },\n    },\n    logger,\n  );\n\n  return new CachingWorkspace(sourceWorkspace, compilationCache, logger);\n}\n"
  },
  {
    "path": "compiler/companion/src/cache/CircularLoopTracker.spec.ts",
    "content": "import 'ts-jest';\nimport { CircularLoopTracker, CircularLoopTrackerPushResult } from './CircularLoopTracker';\n\ndescribe('CircularLoopTracker', () => {\n  it('doesnt detect circular loops on non circular visit', () => {\n    const tracker = new CircularLoopTracker();\n    // 1 -> 2 -> 3\n\n    expect(tracker.push('1')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('2')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('3')).toBe(CircularLoopTrackerPushResult.nonCircular);\n\n    tracker.pop();\n    tracker.pop();\n    tracker.pop();\n\n    expect(tracker.getResolvedCircularLoops()).toBeUndefined();\n  });\n\n  it('detects already visited entries', () => {\n    const tracker = new CircularLoopTracker();\n    // 1 -> 2 -> 3\n    // 1 -> 3\n\n    expect(tracker.push('1')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('2')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('3')).toBe(CircularLoopTrackerPushResult.nonCircular);\n\n    expect(tracker.stackSize).toBe(3);\n    tracker.pop();\n    tracker.pop();\n\n    expect(tracker.stackSize).toBe(1);\n    expect(tracker.push('3')).toBe(CircularLoopTrackerPushResult.alreadyVisited);\n    tracker.pop();\n    expect(tracker.stackSize).toBe(0);\n\n    expect(tracker.getResolvedCircularLoops()).toBeUndefined();\n  });\n\n  it('detects single circular loops', () => {\n    const tracker = new CircularLoopTracker();\n    // 1 -> 2 -> 3 -> 1\n\n    expect(tracker.push('1')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('2')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('3')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('1')).toBe(CircularLoopTrackerPushResult.circular);\n\n    expect(tracker.stackSize).toBe(3);\n\n    tracker.pop();\n    tracker.pop();\n    tracker.pop();\n\n    expect(tracker.getResolvedCircularLoops()).toEqual([['1', '2', '3']]);\n  });\n\n  it('detects complex circular loops', () => {\n    const tracker = new CircularLoopTracker();\n    // 1 -> 2 -> 3 -> 1\n    // 1 -> 2 -> 4 -> 2\n    // 1 -> 5 -> 6 -> 5\n    // 1 -> 9 -> 2\n    // 1 -> 7 -> 8\n\n    expect(tracker.push('1')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('2')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('3')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('1')).toBe(CircularLoopTrackerPushResult.circular);\n\n    expect(tracker.stackSize).toBe(3);\n    tracker.pop();\n\n    expect(tracker.push('4')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('2')).toBe(CircularLoopTrackerPushResult.circular);\n\n    expect(tracker.stackSize).toBe(3);\n    tracker.pop();\n    tracker.pop();\n\n    expect(tracker.push('5')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('6')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('5')).toBe(CircularLoopTrackerPushResult.circular);\n\n    expect(tracker.stackSize).toBe(3);\n    tracker.pop();\n    tracker.pop();\n\n    expect(tracker.push('9')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('2')).toBe(CircularLoopTrackerPushResult.circular);\n    tracker.pop();\n\n    expect(tracker.push('7')).toBe(CircularLoopTrackerPushResult.nonCircular);\n    expect(tracker.push('8')).toBe(CircularLoopTrackerPushResult.nonCircular);\n\n    expect(tracker.stackSize).toBe(3);\n    tracker.pop();\n    tracker.pop();\n    tracker.pop();\n\n    expect(tracker.getResolvedCircularLoops()).toEqual([\n      ['5', '6'],\n      ['1', '2', '3', '4', '9'],\n    ]);\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/cache/CircularLoopTracker.ts",
    "content": "export type ICircularLoop = string[];\n\nexport const enum CircularLoopTrackerPushResult {\n  /**\n   * First time the entry was visited. The entry is not circular\n   */\n  nonCircular,\n\n  /**\n   * The entry was already visited and is in the stack. A circular loop\n   * was detected.\n   */\n  circular,\n\n  /**\n   * The entry was already visited but is not in the stack.\n   */\n  alreadyVisited,\n}\n\nexport class CircularLoopTracker {\n  get stackSize(): number {\n    return this.stack.length;\n  }\n\n  private stack: string[] = [];\n  private allVisited = new Set<string>();\n  private loopsByEntry: Map<string, Set<string>> | undefined = undefined;\n\n  private handleAlreadyVisited(entry: string): CircularLoopTrackerPushResult {\n    const existingLoops = this.loopsByEntry?.get(entry);\n    let pendingConnections: string[] | undefined;\n\n    if (existingLoops) {\n      for (const innerEntry of existingLoops) {\n        if (this.stack.indexOf(innerEntry) >= 0) {\n          if (!pendingConnections) {\n            pendingConnections = [];\n          }\n          pendingConnections.push(innerEntry);\n        }\n      }\n    }\n\n    if (!pendingConnections) {\n      return CircularLoopTrackerPushResult.alreadyVisited;\n    }\n\n    // We are attempting pushing an item that is already visited and is part of a circle\n    // that is on the stack. We need to treat the push as a circular loop\n\n    for (const entryToProcess of pendingConnections) {\n      const index = this.stack.indexOf(entryToProcess);\n      this.handleCircularLoop(index);\n    }\n\n    return CircularLoopTrackerPushResult.circular;\n  }\n\n  push(entry: string): CircularLoopTrackerPushResult {\n    if (this.allVisited.has(entry)) {\n      const indexOfEntry = this.stack.indexOf(entry);\n      if (indexOfEntry >= 0) {\n        this.handleCircularLoop(indexOfEntry);\n        return CircularLoopTrackerPushResult.circular;\n      } else {\n        return this.handleAlreadyVisited(entry);\n      }\n    }\n\n    this.allVisited.add(entry);\n    this.stack.push(entry);\n\n    return CircularLoopTrackerPushResult.nonCircular;\n  }\n\n  pop(): void {\n    this.stack.pop();\n  }\n\n  getCircularEntriesForEntry(entry: string): Set<string> | undefined {\n    return this.loopsByEntry?.get(entry);\n  }\n\n  getResolvedCircularLoops(): ICircularLoop[] | undefined {\n    if (!this.loopsByEntry) {\n      return undefined;\n    }\n\n    const allLoops: Set<string>[] = [];\n\n    for (const loop of this.loopsByEntry.values()) {\n      if (allLoops.indexOf(loop) < 0) {\n        allLoops.push(loop);\n      }\n    }\n\n    return allLoops.map((loop) => [...loop.values()].sort()).sort((l, r) => l.length - r.length);\n  }\n\n  private addEntriesToLoop(left: string, right: string, loopsByEntry: Map<string, Set<string>>) {\n    let existingLeftLoop = loopsByEntry.get(left);\n    let existingRightLoop = loopsByEntry.get(right);\n\n    if (existingLeftLoop === existingRightLoop) {\n      if (!existingLeftLoop) {\n        // First time we see both entries\n        const loop = new Set<string>([left, right]);\n        loopsByEntry.set(left, loop);\n        loopsByEntry.set(right, loop);\n      } else {\n        // Both entries have already been seen and been connected\n        return;\n      }\n    }\n\n    if (existingLeftLoop) {\n      if (existingRightLoop) {\n        // Each one of the entries is already in a loop. we will take the entries from right\n        // and move them into the loop from left\n        const entriesInRight = [...existingRightLoop.values()];\n\n        for (const rightEntry of entriesInRight) {\n          loopsByEntry.delete(rightEntry);\n        }\n        for (const rightEntry of entriesInRight) {\n          this.addEntriesToLoop(left, rightEntry, loopsByEntry);\n        }\n      } else {\n        // Add 'right' to the loop\n        existingLeftLoop.add(right);\n        loopsByEntry.set(right, existingLeftLoop);\n      }\n    } else if (existingRightLoop) {\n      // Add 'left' to the loop\n      existingRightLoop.add(left);\n      loopsByEntry.set(left, existingRightLoop);\n    }\n  }\n\n  private handleCircularLoop(startStackIndex: number): void {\n    let loopsByEntry = this.loopsByEntry;\n    if (!loopsByEntry) {\n      loopsByEntry = new Map();\n      this.loopsByEntry = loopsByEntry;\n    }\n\n    for (let i = startStackIndex; i < this.stack.length - 1; i++) {\n      const left = this.stack[i];\n      const right = this.stack[i + 1];\n\n      this.addEntriesToLoop(left, right, loopsByEntry);\n    }\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/cache/ICompilationCache.d.ts",
    "content": "export interface ICompilationCache {\n  close(): void;\n\n  evictEntriesBeforeTime(lastUsedTimestamp: number): void;\n\n  getCachedEntry(path: string, container: string, hash: string): Promise<string | undefined>;\n  setCachedEntry(path: string, container: string, hash: string, data: string): Promise<void>;\n}\n"
  },
  {
    "path": "compiler/companion/src/cache/SQLiteCompilationCache.spec.ts",
    "content": "import 'ts-jest';\nimport {\n  COMPRESSION_BYTES_THRESHOLD,\n  SQLiteCompilationCache,\n  SQLiteCompilationCacheTimestampProvider,\n} from './SQLiteCompilationCache';\nclass TestTimestampProvider implements SQLiteCompilationCacheTimestampProvider {\n  currentTimestamp = 0;\n\n  getCurrentTimestamp(): number {\n    return this.currentTimestamp;\n  }\n}\n\ndescribe('SQLiteCompilationCache', () => {\n  function cacheIt(\n    name: string,\n    cb: (cache: SQLiteCompilationCache, timestampProvider: TestTimestampProvider) => Promise<void>,\n  ): void {\n    it(name, async () => {\n      const timestampProvider = new TestTimestampProvider();\n      const cache = SQLiteCompilationCache.newInMemoryInstance(timestampProvider);\n\n      try {\n        await cb(cache, timestampProvider);\n      } finally {\n        cache.close();\n      }\n    });\n  }\n\n  cacheIt('can insert and get values', async (cache) => {\n    let result = await cache.getCachedEntry('files', 'file.ts', 'xxx');\n    expect(result).toBeUndefined();\n\n    await cache.setCachedEntry('files', 'file.ts', 'xxx', 'Hello World');\n    await cache.setCachedEntry('files', 'file.ts', 'yyy', 'Goodbye World');\n\n    result = await cache.getCachedEntry('files', 'file.ts', 'xxx');\n    expect(result).toEqual('Hello World');\n    result = await cache.getCachedEntry('files', 'file.ts', 'yyy');\n    expect(result).toEqual('Goodbye World');\n  });\n\n  cacheIt('updates last access timestamp on get', async (cache, timestampProvider) => {\n    timestampProvider.currentTimestamp = 1;\n\n    await cache.setCachedEntry('files', 'file.ts', 'xxx', 'Hello World');\n\n    let entries = cache.getAllCachedEntries();\n    expect(entries.length).toBe(1);\n\n    expect(entries[0].last_access_date).toBe(1);\n\n    timestampProvider.currentTimestamp = 2;\n\n    const entry = await cache.getCachedEntry('files', 'file.ts', 'xxx');\n    expect(entry).toEqual('Hello World');\n\n    cache.flushDeferredStatements();\n\n    entries = cache.getAllCachedEntries();\n    expect(entries.length).toBe(1);\n\n    expect(entries[0].last_access_date).toBe(2);\n  });\n\n  cacheIt('can evict old entries', async (cache, timestampProvider) => {\n    timestampProvider.currentTimestamp = 1;\n    await cache.setCachedEntry('files', 'file.ts', 'xxx', 'Hello World');\n    timestampProvider.currentTimestamp = 2;\n    await cache.setCachedEntry('files', 'file.ts', 'yyy', 'Goodbye World');\n    timestampProvider.currentTimestamp = 3;\n    await cache.setCachedEntry('files', 'file.ts', 'zzz', 'Yepyep');\n\n    let entries = cache.getAllCachedEntries();\n    expect(entries.length).toBe(3);\n\n    cache.evictEntriesBeforeTime(2);\n\n    entries = cache.getAllCachedEntries();\n    expect(entries.length).toBe(2);\n\n    cache.evictEntriesBeforeTime(3);\n\n    entries = cache.getAllCachedEntries();\n    expect(entries.length).toBe(1);\n    expect(entries[0].data.toString('utf-8')).toEqual('Yepyep');\n\n    cache.evictEntriesBeforeTime(4);\n\n    entries = cache.getAllCachedEntries();\n    expect(entries.length).toBe(0);\n  });\n\n  cacheIt('compresses when data goes beyond the compression threshold', async (cache) => {\n    let data = '';\n    for (let i = 0; i < COMPRESSION_BYTES_THRESHOLD; i++) {\n      data += 'a';\n    }\n    await cache.setCachedEntry('files', 'file.ts', 'xxx', data);\n\n    let entries = cache.getAllCachedEntries();\n    expect(entries.length).toBe(1);\n\n    expect(entries[0].data.toString('utf-8')).toEqual(data);\n\n    // Go beyond the threshold where we start compressing\n    data += 'z';\n    await cache.setCachedEntry('files', 'file.ts', 'xxx', data);\n\n    entries = cache.getAllCachedEntries();\n    expect(entries.length).toBe(1);\n\n    expect(entries[0].data.toString('utf-8')).not.toEqual(data);\n\n    const fetched = await cache.getCachedEntry('files', 'file.ts', 'xxx');\n    expect(fetched).toBeDefined();\n    expect(fetched).toEqual(data);\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/cache/SQLiteCompilationCache.ts",
    "content": "import type { ICompilationCache } from './ICompilationCache';\nimport * as sqlite from 'better-sqlite3';\nimport * as fs from 'fs';\nimport { ILogger } from '../logger/ILogger';\nimport { deflate, inflate } from 'zlib';\nimport * as os from 'os';\n\nexport interface CompilationCacheEntry {\n  container: string;\n  path: string;\n  hash: string;\n  last_access_date: number;\n  compressed: number;\n  data: Buffer;\n}\n\ninterface CompilationCacheMetadata {\n  version: string;\n}\n\nexport interface SQLiteCompilationCacheTimestampProvider {\n  getCurrentTimestamp(): number;\n}\n\n/**\n * Should be updated every time the compilation cache implementation changes.\n */\nconst SCHEMA_VERSION = '1';\nexport const COMPRESSION_BYTES_THRESHOLD = 500;\n\nfunction prepareDatabase(db: sqlite.Database, resolvedVersion: string): sqlite.Database {\n  db.exec(`CREATE TABLE metadata(\n    version STRING NOT NULL,\n    PRIMARY KEY(version)\n  )`);\n\n  db.exec(`CREATE TABLE entries(\n    path STRING NOT NULL,\n    container STRING NOT NULL,\n    hash STRING NOT NULL,\n    last_access_date TIMESTAMP NOT NULL,\n    compressed BOOLEAN NOT NULL,\n    data BINARY,\n    PRIMARY KEY(container, path, hash)\n  )`);\n\n  const insertMetadataStmt = db.prepare(\n    `INSERT INTO metadata VALUES (?)\n      `,\n  );\n\n  insertMetadataStmt.run(resolvedVersion);\n\n  return db;\n}\n\nfunction createUnpreparedDatabase(filename: string): sqlite.Database {\n  let nativeBinding: string;\n\n  const platform = os.platform();\n  const arch = os.arch();\n\n  if (platform === 'darwin' && arch === 'arm64') {\n    nativeBinding = require('../sqlite_bindings/better_sqlite3_macos_arm64.node');\n  } else if (platform === 'linux' && arch === 'x64') {\n    nativeBinding = require('../sqlite_bindings/better_sqlite3_linux_x86_64.node');\n  } else {\n    throw new Error(`Unspported platform and arch combination (${platform} on arch ${arch})`);\n  }\n\n  return sqlite(filename, { nativeBinding: nativeBinding });\n}\n\nfunction createDatabase(\n  databasePath: string | undefined,\n  workspaceVersion: string,\n  logger: ILogger | undefined,\n): sqlite.Database {\n  const resolvedVersion = `${SCHEMA_VERSION}/${workspaceVersion}`;\n  if (!databasePath) {\n    return prepareDatabase(createUnpreparedDatabase(':memory:'), resolvedVersion);\n  }\n\n  if (!fs.existsSync(databasePath)) {\n    logger?.debug?.('Creating new compilation cache database.');\n    return prepareDatabase(createUnpreparedDatabase(databasePath), resolvedVersion);\n  }\n\n  const db = createUnpreparedDatabase(databasePath);\n\n  try {\n    const stmt = db.prepare('SELECT version FROM metadata');\n    const metadata = stmt.get() as CompilationCacheMetadata;\n    if (metadata.version !== resolvedVersion) {\n      throw new Error('Schema is out of date');\n    }\n  } catch (err: any) {\n    logger?.debug?.(`Compilation cache database needs wipe (${err.message}).`);\n    db.close();\n    fs.rmSync(databasePath);\n\n    return prepareDatabase(createUnpreparedDatabase(databasePath), resolvedVersion);\n  }\n\n  return db;\n}\n\n// Flush after 5 seconds\nconst FLUSH_DEFERRED_STATEMENTS_DELAY_MS = 6000;\n\nexport class SQLiteCompilationCache implements ICompilationCache {\n  private db: sqlite.Database;\n  private getCachedEntryStmt: sqlite.Statement;\n  private setCachedEntryStmt: sqlite.Statement;\n  private updateLastAccessDate: sqlite.Statement;\n  private evictEntriesBeforeTimeStmt: sqlite.Statement;\n  private getAllCachedEntriesStmt: sqlite.Statement;\n\n  private deferredStatements: (() => void)[] = [];\n  private scheduledDeferredStatementTimeout: NodeJS.Timeout | undefined = undefined;\n\n  constructor(\n    databasePath: string | undefined,\n    workspaceVersion: string,\n    readonly timestampProvider: SQLiteCompilationCacheTimestampProvider,\n    logger: ILogger | undefined,\n  ) {\n    this.db = createDatabase(databasePath, workspaceVersion, logger);\n\n    this.getCachedEntryStmt = this.db.prepare(`\n    SELECT data, compressed FROM entries\n    WHERE path = ? AND container = ? AND hash = ?`);\n    this.setCachedEntryStmt = this.db.prepare(\n      `INSERT INTO entries VALUES (?, ?, ?, ?, ?, ?)\n      ON CONFLICT(path, container, hash) DO UPDATE SET\n        last_access_date=excluded.last_access_date,\n        compressed=excluded.compressed,\n        data=excluded.data\n        `,\n    );\n\n    this.updateLastAccessDate = this.db.prepare(`\n    UPDATE entries\n    SET last_access_date = ?\n    WHERE path = ? AND container = ? AND hash = ?\n    `);\n    this.evictEntriesBeforeTimeStmt = this.db.prepare(`\n    DELETE FROM entries\n    WHERE last_access_date < ?`);\n    this.getAllCachedEntriesStmt = this.db.prepare(`\n    SELECT * FROM entries`);\n  }\n\n  close(): void {\n    this.flushDeferredStatements();\n    this.db.close();\n  }\n\n  flushDeferredStatements(): void {\n    if (this.scheduledDeferredStatementTimeout) {\n      clearTimeout(this.scheduledDeferredStatementTimeout);\n      this.scheduledDeferredStatementTimeout = undefined;\n    }\n\n    if (!this.deferredStatements.length) {\n      return;\n    }\n    const deferredStatements = this.deferredStatements;\n    this.deferredStatements = [];\n\n    this.db.transaction((cbs) => {\n      for (const cb of cbs) {\n        cb();\n      }\n    })(deferredStatements);\n  }\n\n  evictEntriesBeforeTime(lastUsedTimestamp: number): void {\n    this.flushDeferredStatements();\n    this.evictEntriesBeforeTimeStmt.run(lastUsedTimestamp);\n  }\n\n  getAllCachedEntries(): CompilationCacheEntry[] {\n    return this.getAllCachedEntriesStmt.all() as CompilationCacheEntry[];\n  }\n\n  private enqueueDeferredStatement(cb: () => void) {\n    this.deferredStatements.push(cb);\n\n    if (this.scheduledDeferredStatementTimeout) {\n      clearTimeout(this.scheduledDeferredStatementTimeout);\n    }\n\n    this.scheduledDeferredStatementTimeout = setTimeout(\n      () => this.flushDeferredStatements(),\n      FLUSH_DEFERRED_STATEMENTS_DELAY_MS,\n    );\n  }\n\n  async getCachedEntry(path: string, container: string, hash: string): Promise<string | undefined> {\n    const timestamp = this.timestampProvider.getCurrentTimestamp();\n    const result = this.getCachedEntryStmt.get(path, container, hash) as CompilationCacheEntry;\n\n    if (!result) {\n      return undefined;\n    }\n\n    this.enqueueDeferredStatement(() => {\n      this.updateLastAccessDate.run(timestamp, path, container, hash);\n    });\n\n    if (result.compressed) {\n      return new Promise((resolve, reject) => {\n        inflate(result.data, (error, result) => {\n          if (error) {\n            reject(error);\n          } else {\n            resolve(result.toString('utf-8'));\n          }\n        });\n      });\n    } else {\n      return result.data.toString('utf-8');\n    }\n  }\n\n  async setCachedEntry(path: string, container: string, hash: string, data: string): Promise<void> {\n    const timestamp = this.timestampProvider.getCurrentTimestamp();\n\n    const buffer = Buffer.from(data, 'utf-8');\n\n    if (buffer.length > COMPRESSION_BYTES_THRESHOLD) {\n      return new Promise((resolve, reject) => {\n        deflate(buffer, (error, result) => {\n          if (error) {\n            reject(error);\n          } else {\n            this.setCachedEntryStmt.run(path, container, hash, timestamp, 1, result);\n            resolve();\n          }\n        });\n      });\n    } else {\n      this.setCachedEntryStmt.run(path, container, hash, timestamp, 0, buffer);\n    }\n  }\n\n  static newInMemoryInstance(timestampProvider: SQLiteCompilationCacheTimestampProvider): SQLiteCompilationCache {\n    return new SQLiteCompilationCache(undefined, '1', timestampProvider, undefined);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/cli/generateGhostOwnershipMap.ts",
    "content": "import * as fs from 'fs/promises';\nimport * as path from 'path';\n\nimport * as fg from 'fast-glob';\nimport { ILogger } from '../logger/ILogger';\n\nexport type GenerateGhostOwnershipMapResult = { [key: string]: string };\n\nexport async function generateGhostOwnershipMap(\n  logger: ILogger | undefined,\n  outputDir: string,\n): Promise<GenerateGhostOwnershipMapResult> {\n  logger?.info?.('Generating ghost team attribution map...');\n  const allModulesAndDepsPath = path.join(outputDir, 'android/ALL_MODULES_AND_DEPS.bzl');\n  const outputPath = path.join(outputDir, 'android/ghost-team-attribution.json');\n  let allModulesAndDepsContents = await fs.readFile(allModulesAndDepsPath, { encoding: 'utf-8' });\n  allModulesAndDepsContents = allModulesAndDepsContents.slice('ALL_MODULES_AND_DEPS ='.length);\n  const allModulesAndDeps = JSON.parse(allModulesAndDepsContents);\n\n  const result: GenerateGhostOwnershipMapResult = {};\n\n  for (let module in allModulesAndDeps) {\n    const owner = allModulesAndDeps[module].owner;\n    const moduledir = path.join(outputDir, `android/modules/${module}`);\n    const debugdir = path.join(moduledir, `debug`);\n    const srcdir = path.join(debugdir, 'src');\n    const kotlinFiles = fg.sync([`${srcdir}/**/*.kt`], { dot: true });\n    const classArtifactNames = kotlinFiles.map((file) => {\n      // In: /Users/sahmed2/Snapchat/Dev/client/src/valdi_modules/generated-src/android/modules/context_cards/debug/src/com/snap/contextcards/valdi/model/ContextV2ErrorCardViewModel.kt\n      // Out: com.snap.contextcards.valdi.model.ContextV2ErrorCardViewModel\n      const withoutPrefix = file.slice(srcdir.length + 1);\n      const withoutSuffix = withoutPrefix.slice(0, -'.kt'.length);\n      const packageName = withoutSuffix.replace(/\\//g, '.');\n      return packageName;\n    });\n\n    const assets = fg.sync([`${moduledir}/*/assets/*`], { dot: true });\n    const assetsArtifacts = assets.map((file) => {\n      return `/assets/${path.basename(file)}`;\n    });\n\n    const idsXml = fg.sync([`${debugdir}/res/values/*_ids.xml`], { dot: true });\n    const idsArtifacts = [];\n    const idRegex = /<item type=\"id\" name=\"(\\w+)\"/g;\n    for (const idFile of idsXml) {\n      const contents = await fs.readFile(idFile, { encoding: 'utf-8' });\n      const matches = contents.matchAll(idRegex);\n      for (const match of matches) {\n        if (match[1]) {\n          idsArtifacts.push(`R.id.${match[1]}`);\n        }\n      }\n    }\n\n    const stringsXml = fg.sync([`${moduledir}/*/res/values/valdi-strings*.xml`], { dot: true });\n    const stringsArtifacts = [];\n    const stringRegex = /<string name=\"(\\w+)\"/g;\n    for (const stringsFile of stringsXml) {\n      const contents = await fs.readFile(stringsFile, { encoding: 'utf-8' });\n      const matches = contents.matchAll(stringRegex);\n      for (const match of matches) {\n        if (match[1]) {\n          stringsArtifacts.push(`R.string.${match[1]}`);\n        }\n      }\n    }\n\n    const drawables = fg.sync([`${debugdir}/res/*/*`], { dot: true });\n    const drawablesArtifactNames = drawables.flatMap((file) => {\n      // In: /Users/sahmed2/Snapchat/Dev/client/src/valdi_modules/generated-src/android/modules/context_cards/debug/res/drawable-hdpi/context_cards_context_loading_placeholder.webp\n      // Out: R.drawable.context_cards_context_loading_placeholder\n      // Out (for every display density): /res/drawable-hdpi-v4/drawable.context_cards_context_loading_placeholder.webp\n      const displayDensity = path.basename(path.dirname(file));\n      const filename = path.basename(file);\n      const filenameWithoutExtension = path.parse(filename).name;\n      return [`/res/${displayDensity}-v4/${filename}`, `R.drawable.${filenameWithoutExtension}`];\n    });\n    const allArtifacts = [\n      ...classArtifactNames,\n      ...assetsArtifacts,\n      ...idsArtifacts,\n      ...stringsArtifacts,\n      ...drawablesArtifactNames,\n    ].sort((a, b) => {\n      return a.localeCompare(b);\n    });\n    for (const artifact of allArtifacts) {\n      result[artifact] = owner;\n    }\n  }\n\n  fs.writeFile(outputPath, JSON.stringify(result));\n\n  logger?.info?.(`Done! Count: ${Object.values(result).length}`);\n  return result;\n}\n"
  },
  {
    "path": "compiler/companion/src/cli/rewriteImports.ts",
    "content": "import { forEachFile } from '../utils/fileUtils';\nimport { ILogger } from '../logger/ILogger';\nimport { readFile, writeFile } from 'fs/promises';\nimport { CharCode, TextParser } from '../utils/TextParser';\nimport path = require('path');\n\ninterface ImportedSymbol {\n  symbolName: string;\n  symbolAlias?: string;\n}\n\ninterface ImportStatement {\n  filePositionStart: number;\n  filePositionEnd: number;\n\n  importPath: string | undefined;\n  isTypeImport: boolean;\n  namespaceSource?: string;\n  symbolsList?: ImportedSymbol[];\n  singleSymbol?: ImportedSymbol;\n}\n\ninterface FileContentChunk {\n  content: string;\n  start: number;\n  end: number;\n  importStatement?: ImportStatement;\n}\n\nfunction resolveImportPath(projectDirectory: string, directory: string, importPath: string): string {\n  if (importPath.startsWith('.')) {\n    // Relative import\n    return path.resolve(directory, importPath);\n  } else {\n    // Absolute import\n    return path.join(projectDirectory, importPath);\n  }\n}\n\nconst enum VisitImportResult {\n  noop,\n  delete,\n}\n\nclass ParsedFile {\n  readonly directory: string;\n\n  constructor(\n    readonly filePath: string,\n    readonly chunks: FileContentChunk[],\n    readonly importStatements: ImportStatement[],\n  ) {\n    this.directory = path.dirname(filePath);\n  }\n\n  private visitImports(\n    visitor: (importStatement: ImportStatement, importedSymbol: ImportedSymbol) => VisitImportResult,\n  ): void {\n    for (let i = 0; i < this.importStatements.length; i++) {\n      const importStatement = this.importStatements[i];\n\n      let removed = false;\n      if (importStatement.singleSymbol) {\n        const result = visitor(importStatement, importStatement.singleSymbol);\n        if (result === VisitImportResult.delete) {\n          importStatement.singleSymbol = undefined;\n          removed = true;\n        }\n      }\n\n      if (importStatement.symbolsList) {\n        for (let j = 0; j < importStatement.symbolsList.length; j++) {\n          const importedSymbol = importStatement.symbolsList[j];\n          const result = visitor(importStatement, importedSymbol);\n          if (result === VisitImportResult.delete) {\n            importStatement.symbolsList.splice(j, 1);\n            removed = true;\n            break;\n          }\n        }\n      }\n\n      if (removed) {\n        if (\n          !importStatement.singleSymbol &&\n          (!importStatement.symbolsList || importStatement.symbolsList.length === 0)\n        ) {\n          // Remove entire statement\n          this.importStatements.slice(i, 1);\n          const chunkIndex = this.chunks.findIndex((v) => v.importStatement === importStatement);\n          this.chunks.splice(chunkIndex, 1);\n          const newChunkAtIndex = this.chunks[chunkIndex];\n          if (newChunkAtIndex && newChunkAtIndex.content[0] === '\\n') {\n            // Remove newline after removing our chunk if we have one\n            newChunkAtIndex.content = newChunkAtIndex.content.substring(1);\n          }\n          i--;\n        }\n      }\n    }\n  }\n\n  updateImportForSymbolName(\n    importBaseDirectory: string,\n    oldSymbolName: string,\n    newSymbolName: string,\n    oldImportPath: string,\n    newImportPath: string,\n  ): boolean {\n    const oldAbsoluteImportPath = resolveImportPath(importBaseDirectory, importBaseDirectory, oldImportPath);\n    let removed = false;\n    this.visitImports((importStatement, importedSymbol): VisitImportResult => {\n      if (!importStatement.importPath || importedSymbol.symbolName !== oldSymbolName) {\n        return VisitImportResult.noop;\n      }\n      const absoluteImportPath = resolveImportPath(importBaseDirectory, this.directory, importStatement.importPath);\n      if (absoluteImportPath !== oldAbsoluteImportPath) {\n        return VisitImportResult.noop;\n      }\n\n      removed = true;\n      return VisitImportResult.delete;\n    });\n\n    if (!removed) {\n      return false;\n    }\n\n    const newAbsoluteImportPath = resolveImportPath(importBaseDirectory, importBaseDirectory, newImportPath);\n    let updated = false;\n\n    for (const importStatement of this.importStatements) {\n      if (!importStatement.importPath) {\n        continue;\n      }\n\n      const absoluteImportPath = resolveImportPath(importBaseDirectory, this.directory, importStatement.importPath);\n      if (absoluteImportPath === newAbsoluteImportPath) {\n        if (!importStatement.symbolsList) {\n          importStatement.symbolsList = [];\n        }\n\n        importStatement.symbolsList.push({\n          symbolName: newSymbolName,\n        });\n        updated = true;\n        break;\n      }\n    }\n\n    if (!updated) {\n      // Add import statement\n      this.insertImport(newSymbolName, newImportPath);\n    }\n\n    return true;\n  }\n\n  private insertImport(symbolName: string, importPath: string) {\n    const newImportStatement: ImportStatement = {\n      filePositionStart: 0,\n      filePositionEnd: 0,\n      importPath: importPath,\n      isTypeImport: false,\n      namespaceSource: undefined,\n      symbolsList: [\n        {\n          symbolName: symbolName,\n        },\n      ],\n      singleSymbol: undefined,\n    };\n\n    let insertionIndex: number;\n    if (this.importStatements.length) {\n      insertionIndex =\n        this.chunks.findIndex((c) => c.importStatement === this.importStatements[this.importStatements.length - 1]) + 1;\n    } else {\n      insertionIndex = 0;\n    }\n\n    this.importStatements.push(newImportStatement);\n    this.chunks.splice(insertionIndex, 0, { content: '', start: 0, end: 0, importStatement: newImportStatement });\n    this.chunks.splice(insertionIndex, 0, { content: '\\n', start: 0, end: 0, importStatement: undefined });\n  }\n\n  regenerateFileContent(): string {\n    let out = '';\n\n    for (const chunk of this.chunks) {\n      if (chunk.importStatement) {\n        out += this.generateImportStatement(chunk.importStatement);\n      } else {\n        out += chunk.content;\n      }\n    }\n\n    return out;\n  }\n\n  private generateImportedSymbol(importedSymbol: ImportedSymbol): string {\n    let out = importedSymbol.symbolName;\n    if (importedSymbol.symbolAlias) {\n      out += ' as ';\n      out += importedSymbol.symbolAlias;\n    }\n\n    return out;\n  }\n\n  private generateImportedSymbolList(importedSymbolList: ImportedSymbol[]): string {\n    const content = importedSymbolList.map((importedSymbol) => this.generateImportedSymbol(importedSymbol)).join(', ');\n    return `{ ${content} }`;\n  }\n\n  private generateImportStatement(importStatement: ImportStatement): string {\n    let out = 'import ';\n    if (importStatement.isTypeImport) {\n      out += 'type ';\n    }\n\n    if (!importStatement.singleSymbol && !importStatement.symbolsList) {\n      if (importStatement.importPath) {\n        out += `'${importStatement.importPath}'`;\n      }\n    } else {\n      if (importStatement.singleSymbol) {\n        out += this.generateImportedSymbol(importStatement.singleSymbol);\n\n        if (importStatement.symbolsList) {\n          out += ', ';\n          out += this.generateImportedSymbolList(importStatement.symbolsList);\n        }\n      } else if (importStatement.symbolsList) {\n        out += this.generateImportedSymbolList(importStatement.symbolsList);\n      }\n\n      if (importStatement.importPath) {\n        out += ' from ';\n        out += `'${importStatement.importPath}'`;\n      } else if (importStatement.namespaceSource) {\n        out += ' =';\n        out += importStatement.namespaceSource;\n      }\n    }\n\n    out += ';';\n    return out;\n  }\n}\n\nfunction makeImportedSymbol(symbolName: string, parser: TextParser): ImportedSymbol {\n  if (parser.tryParse('as')) {\n    return {\n      symbolName,\n      symbolAlias: parser.parseIdentifier(),\n    };\n  } else {\n    return {\n      symbolName,\n    };\n  }\n}\n\nfunction parseImportedSymbol(parser: TextParser): ImportedSymbol {\n  const symbolName = parser.parseIdentifier();\n  return makeImportedSymbol(symbolName, parser);\n}\n\nfunction parseImportedSymbolsList(parser: TextParser): ImportedSymbol[] {\n  const symbolsList: ImportedSymbol[] = [];\n  while (!parser.tryParse('}')) {\n    symbolsList.push(parseImportedSymbol(parser));\n    parser.tryParse(',');\n  }\n\n  return symbolsList;\n}\n\nfunction parseImport(parser: TextParser): ImportStatement {\n  let symbolsList: ImportedSymbol[] | undefined;\n  let singleSymbol: ImportedSymbol | undefined;\n\n  const filePositionStart = parser.position;\n\n  parser.parse('import ');\n\n  // Ignore type keyword\n  const isTypeImport = parser.tryParse('type ');\n\n  if (parser.tryParse('*')) {\n    singleSymbol = makeImportedSymbol('*', parser);\n  } else if (parser.isAtIdentifier()) {\n    singleSymbol = parseImportedSymbol(parser);\n\n    if (parser.tryParse(',')) {\n      parser.parse('{');\n      symbolsList = parseImportedSymbolsList(parser);\n    }\n  } else if (parser.tryParse('{')) {\n    symbolsList = parseImportedSymbolsList(parser);\n  }\n\n  if (symbolsList || singleSymbol) {\n    if (parser.tryParse('=')) {\n      const filePositionEnd = parser.position;\n      const namespaceSource = parser.parseUntilCharCode(CharCode.semiColon);\n      return {\n        filePositionStart,\n        filePositionEnd,\n        isTypeImport,\n        importPath: undefined,\n        namespaceSource,\n        symbolsList,\n        singleSymbol,\n      };\n    } else {\n      parser.parse('from');\n    }\n  }\n\n  const importPath = parser.parseQuotedString();\n  const filePositionEnd = parser.position;\n\n  parser.tryParse(';');\n\n  return {\n    filePositionStart,\n    filePositionEnd,\n    isTypeImport,\n    importPath,\n    namespaceSource: undefined,\n    symbolsList,\n    singleSymbol,\n  };\n}\n\nfunction appendChunkIfNeeded(parser: TextParser, output: FileContentChunk[]) {\n  let lastEndPosition = 0;\n\n  if (output.length > 0) {\n    lastEndPosition = output[output.length - 1].end;\n  }\n\n  if (parser.position === lastEndPosition) {\n    return;\n  }\n\n  output.push({\n    start: lastEndPosition,\n    end: parser.position,\n    content: parser.text.substring(lastEndPosition, parser.position),\n  });\n}\n\nasync function parseFile(filePath: string): Promise<ParsedFile> {\n  try {\n    const fileContent = await readFile(filePath, { encoding: 'utf-8' });\n    const parser = new TextParser(fileContent);\n\n    const chunks: FileContentChunk[] = [];\n\n    const imports: ImportStatement[] = [];\n\n    while (!parser.isAtEnd()) {\n      if (parser.peek('import ')) {\n        appendChunkIfNeeded(parser, chunks);\n        const importStatement = parseImport(parser);\n        imports.push(importStatement);\n        appendChunkIfNeeded(parser, chunks);\n        chunks[chunks.length - 1].importStatement = importStatement;\n      } else {\n        parser.skipCurrentLine();\n      }\n    }\n\n    appendChunkIfNeeded(parser, chunks);\n\n    return new ParsedFile(filePath, chunks, imports);\n  } catch (err: any) {\n    err.message = `While parsing: ${filePath}: ${err.message}`;\n    throw err;\n  }\n}\n\nexport async function rewriteImports(\n  logger: ILogger | undefined,\n  projectDirectory: string,\n  oldTypeName: string,\n  newTypeName: string,\n  oldImportPath: string,\n  newImportPath: string,\n): Promise<void> {\n  const allTypeScriptFiles: string[] = [];\n  await forEachFile(projectDirectory, (filePath) => {\n    if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {\n      allTypeScriptFiles.push(filePath);\n    }\n  });\n\n  logger?.info?.(`Parsing ${allTypeScriptFiles.length} files...`);\n\n  const parsedFiles = await Promise.all(allTypeScriptFiles.map((f) => parseFile(f)));\n\n  logger?.info?.(\n    `Rewriting type ${newTypeName} in import path '${newImportPath}' (from ${oldTypeName} with import path '${oldImportPath}'))`,\n  );\n\n  const pendingPromises: Promise<void>[] = [];\n\n  for (const parsedFile of parsedFiles) {\n    if (\n      parsedFile.updateImportForSymbolName(projectDirectory, oldTypeName, newTypeName, oldImportPath, newImportPath)\n    ) {\n      logger?.info?.(`Found import in ${parsedFile.filePath}`);\n      const updatedFileContent = parsedFile.regenerateFileContent();\n      pendingPromises.push(writeFile(parsedFile.filePath, updatedFileContent, { encoding: 'utf-8' }));\n    }\n  }\n\n  await Promise.all(pendingPromises);\n}\n"
  },
  {
    "path": "compiler/companion/src/index.ts",
    "content": "import { CompilerCompanion } from './CompilerCompanion';\n\nconst companion = new CompilerCompanion(new Set(process.argv));\ncompanion.start();\n"
  },
  {
    "path": "compiler/companion/src/index_tsnode.js",
    "content": "require('ts-node').register({\n    project: `${__dirname}/../tsconfig.json`,\n    transpileOnly: true,\n  });\n\nrequire('./index');\n"
  },
  {
    "path": "compiler/companion/src/logger/ILogger.ts",
    "content": "export type ILoggerStream = (...messages: any[]) => void;\n\nexport interface ILogger {\n  debug: ILoggerStream | undefined;\n  info: ILoggerStream | undefined;\n  warn: ILoggerStream | undefined;\n  error: ILoggerStream | undefined;\n}\n"
  },
  {
    "path": "compiler/companion/src/logger/LoggerUtils.ts",
    "content": "function formatValue(value: any): any {\n  if (value instanceof Error) {\n    return `${value}: ${value.stack}`;\n  }\n  return value;\n}\n\nexport function formatMessages(messages: any[]): string {\n  return messages.map(formatValue).join(' ');\n}\n"
  },
  {
    "path": "compiler/companion/src/logger/ProtocolLogger.ts",
    "content": "import { sendEvent } from '../utils/companionTransport';\nimport { ILogger, ILoggerStream } from './ILogger';\nimport { formatMessages } from './LoggerUtils';\n\nexport class ProtocolLogger implements ILogger {\n  debug: ILoggerStream | undefined = undefined;\n  info = (...messages: any[]) => {\n    this.writeLogs('info', messages);\n  };\n\n  warn = (...messages: any[]) => {\n    this.writeLogs('warn', messages);\n  };\n\n  error = (...messages: any[]) => {\n    this.writeLogs('error', messages);\n  };\n\n  private writeLogs(type: string, messages: any[]): void {\n    sendEvent(type, formatMessages(messages));\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/logger/StreamLogger.ts",
    "content": "import { ILogger } from './ILogger';\nimport * as fs from 'fs';\nimport { formatMessages } from './LoggerUtils';\n\nexport class StreamLogger implements ILogger {\n  constructor(readonly stream: NodeJS.WritableStream) {}\n\n  debug = (...messages: any[]) => {\n    this.enqueueLog('DEBUG', messages);\n  };\n\n  info = (...messages: any[]) => {\n    this.enqueueLog('INFO', messages);\n  };\n\n  warn = (...messages: any[]) => {\n    this.enqueueLog('WARN', messages);\n  };\n\n  error = (...messages: any[]) => {\n    this.enqueueLog('ERROR', messages);\n  };\n\n  private enqueueLog(type: string, messages: any[]): void {\n    const logDate = new Date();\n    const formatted = formatMessages(messages);\n    this.stream.write(`${logDate} [${type}]: ${formatted}\\n`);\n  }\n\n  static forOutputFile(outputPath: string): StreamLogger {\n    return new StreamLogger(fs.createWriteStream(outputPath));\n  }\n\n  static forStderr(): StreamLogger {\n    return new StreamLogger(process.stderr);\n  }\n\n  static forStdOut(): StreamLogger {\n    return new StreamLogger(process.stdout);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/CompileNativeCommand.ts",
    "content": "import { ILogger } from '../logger/ILogger';\nimport { CompileNativeRequestBody, CompileNativeResponseBody, EmittedFile } from '../protocol';\nimport { Workspace } from '../Workspace';\nimport * as path from 'path';\nimport { NativeCompiler, compileIRsToC } from './NativeCompiler';\nimport { Diagnostic } from '../protocol';\nimport * as ts from 'typescript';\nimport { writeFile } from 'fs/promises';\nimport * as fs from 'fs';\nimport { NativeCompilerIR } from './builder/NativeCompilerBuilderIR';\nimport { NativeCompilerOptions } from './NativeCompilerOptions';\n\nfunction checkErrors(sourceFile: ts.SourceFile, diagnostics: Diagnostic[]) {\n  for (const diagnostic of diagnostics) {\n    if (diagnostic.category === 'error') {\n      const diagnosticStart = diagnostic.start!;\n      const errorPosition = sourceFile.getPositionOfLineAndCharacter(diagnosticStart.line - 1, diagnosticStart.offset);\n      const fullText = sourceFile.getFullText();\n      const sourceError = fullText.substring(errorPosition, Math.min(errorPosition + 50, fullText.length)).trim();\n      throw Error(\n        `TypeScript Error: ${diagnostic.text.trim()}\\nAt line ${diagnostic.start?.line} and column ${\n          diagnostic.start?.offset\n        }:\\n${sourceError}`,\n      );\n    }\n  }\n}\n\nclass CancelationTokenImpl implements ts.CancellationToken {\n  private cancelled = false;\n\n  requestCancellation(): void {\n    this.cancelled = true;\n  }\n\n  isCancellationRequested(): boolean {\n    return this.cancelled;\n  }\n\n  throwIfCancellationRequested(): void {\n    if (this.isCancellationRequested()) {\n      throw new ts.OperationCanceledException();\n    }\n  }\n}\n\nexport function compileFile(\n  workspace: Workspace,\n  syntaxCheck: boolean,\n  options: NativeCompilerOptions,\n  inputFile: string,\n  modulePath: string,\n): NativeCompilerIR.Base[] {\n  const openedFile = workspace.getOpenedFile(inputFile);\n  const sourceFile = openedFile.sourceFile;\n  const typeChecker = openedFile.workspaceProject.typeChecker;\n\n  if (syntaxCheck) {\n    const diagnostics = workspace.getDiagnosticsSync(inputFile);\n    checkErrors(sourceFile, diagnostics.diagnostics);\n  }\n\n  if (Workspace.requiresTSXProcessor(inputFile)) {\n    // If we need the TSX processor, we need to go through the regular TS compiler\n    // to transpile the TSX AST before we compile the output using the NativeCompiler\n\n    const cancelToken = new CancelationTokenImpl();\n\n    const outputIR: NativeCompilerIR.Base[] = [];\n    const transforms: ts.TransformerFactory<ts.SourceFile>[] = [\n      (context) => (node) => {\n        const compiler = new NativeCompiler(node, inputFile, modulePath, typeChecker, options);\n        outputIR.push(...compiler.compile());\n\n        // Once we are done compiled with the NativeCompiler, we can ask the TS compiler to stop\n        // processing this file. We don't need TS to JS compilation.\n        cancelToken.requestCancellation();\n\n        // Return empty source file as we finished the processing\n        return context.factory.updateSourceFile(\n          node,\n          [],\n          node.isDeclarationFile,\n          undefined,\n          undefined,\n          undefined,\n          undefined,\n        );\n        return node;\n      },\n    ];\n\n    workspace.doEmitFile(inputFile, cancelToken, {\n      before: transforms,\n    });\n\n    return outputIR;\n  } else {\n    const compiler = new NativeCompiler(sourceFile, inputFile, modulePath, typeChecker, options);\n    return compiler.compile();\n  }\n}\n\nfunction generateNativeModuleName(relativePaths: string[]): string {\n  if (relativePaths.length) {\n    const possibleModuleName = relativePaths[0].split('/')[0];\n\n    if (relativePaths.filter((v) => !v.startsWith(possibleModuleName)).length === 0) {\n      // All modules start with the same folder, we use that as the name\n      return `${possibleModuleName}_ts_native.c`;\n    }\n  }\n\n  return 'module_ts_native.c';\n}\n\nexport async function compileNative(\n  workspace: Workspace,\n  logger: ILogger | undefined,\n  request: CompileNativeRequestBody,\n): Promise<CompileNativeResponseBody> {\n  const filesToOpen: string[] = [];\n\n  for (const inputFile of request.inputFiles) {\n    let relativePath: string;\n    if (request.registerInputFiles) {\n      const stripIndex = inputFile.indexOf(request.stripIncludePrefix);\n      if (stripIndex < 0) {\n        throw new Error(`Invalid strip include prefix '${request.stripIncludePrefix}' for file path ${inputFile}`);\n      }\n      relativePath = inputFile.substring(stripIndex + request.stripIncludePrefix.length + 1);\n\n      workspace.registerDiskFile(relativePath, inputFile);\n    } else {\n      relativePath = inputFile;\n    }\n\n    if (\n      (inputFile.endsWith('.ts') && !inputFile.endsWith('.d.ts')) ||\n      inputFile.endsWith('.tsx') ||\n      inputFile.endsWith('.js')\n    ) {\n      filesToOpen.push(relativePath);\n    }\n  }\n\n  if (!workspace.initialized) {\n    await workspace.initialize();\n  }\n\n  const openedFiles = await Promise.all(filesToOpen.map((file) => workspace.openFile(file)));\n  const allIRs: NativeCompilerIR.Base[] = [];\n  const shouldCheckSyntax = !!request.registerInputFiles;\n\n  const options = {\n    optimizeSlots: true,\n    optimizeVarRefs: true,\n\n    // smaller code size and faster\n    optimizeNullChecks: true,\n    mergeSetProperties: true,\n    foldConstants: true,\n    optimizeVarRefLoads: true,\n    optimizeAssignments: true,\n    inlinePropertyCache: true,\n    enableIntrinsics: true, // unsafe, replace some builtin functions with intrinsics\n\n    mergeReleases: false, // smaller code size, very slightly slower\n    autoRelease: false, // smaller code size, slightly slower\n    noinlineRetainRelease: false, // smaller code size, slower\n  };\n  let fileIndex = 0;\n  for (const openedFile of openedFiles) {\n    const relativePath = filesToOpen[fileIndex];\n\n    // Remove file extension for the module loading path\n    const parsedRelativePath = path.parse(relativePath);\n\n    const moduleLoadingPath = path.format({\n      root: parsedRelativePath.root,\n      dir: parsedRelativePath.dir,\n      base: undefined,\n      ext: undefined,\n      name: parsedRelativePath.name,\n    });\n\n    try {\n      const result = compileFile(workspace, shouldCheckSyntax, options, relativePath, moduleLoadingPath);\n      logger?.debug?.(`File ${relativePath} compiled succesfully`);\n\n      allIRs.push(...result);\n    } catch (error: any) {\n      logger?.error?.(`File ${moduleLoadingPath} failed to compile: ${error.message}\\nStack: ${error.stack}`);\n      throw error;\n    }\n\n    fileIndex++;\n  }\n\n  const generatedCCode = compileIRsToC(allIRs, options);\n  let emittedFileContent: string | undefined;\n\n  if (request.outputFile) {\n    const outputDirectoryPath = path.dirname(request.outputFile);\n    if (!fs.existsSync(outputDirectoryPath)) {\n      fs.mkdirSync(outputDirectoryPath, { recursive: true });\n    }\n    await writeFile(request.outputFile, generatedCCode.source);\n  } else {\n    emittedFileContent = generatedCCode.source;\n  }\n\n  const emittedFile: EmittedFile = {\n    fileName: generateNativeModuleName(filesToOpen),\n    content: emittedFileContent,\n  };\n\n  return { files: [emittedFile] };\n}\n"
  },
  {
    "path": "compiler/companion/src/native/IRtoString.ts",
    "content": "import { OutputWriter } from '../OutputWriter';\nimport { NativeCodeWriter } from './NativeCodeWriter';\nimport {\n  NativeCompilerBuilderAtomID,\n  NativeCompilerBuilderBranchType,\n  NativeCompilerBuilderJumpTargetID,\n  NativeCompilerBuilderVariableID,\n} from './builder/INativeCompilerBuilder';\nimport { NativeCompilerIR } from './builder/NativeCompilerBuilderIR';\n\nfunction getUnaryOperatorName(unaryOpKind: NativeCompilerIR.UnaryOperator): string {\n  switch (unaryOpKind) {\n    case NativeCompilerIR.UnaryOperator.Neg:\n      return 'neg';\n    case NativeCompilerIR.UnaryOperator.Plus:\n      return 'plus';\n    case NativeCompilerIR.UnaryOperator.Inc:\n      return 'inc';\n    case NativeCompilerIR.UnaryOperator.Dec:\n      return 'dec';\n    case NativeCompilerIR.UnaryOperator.BitwiseNot:\n      return 'bitwisenot';\n    case NativeCompilerIR.UnaryOperator.LogicalNot:\n      return 'logicalnot';\n    case NativeCompilerIR.UnaryOperator.TypeOf:\n      return 'typeof';\n  }\n}\n\nfunction getBinaryOpOperatorName(binaryOpKind: NativeCompilerIR.BinaryOperator): string {\n  switch (binaryOpKind) {\n    case NativeCompilerIR.BinaryOperator.Mult:\n      return 'mult';\n    case NativeCompilerIR.BinaryOperator.Add:\n      return 'add';\n    case NativeCompilerIR.BinaryOperator.Sub:\n      return 'sub';\n    case NativeCompilerIR.BinaryOperator.Div:\n      return 'div';\n    case NativeCompilerIR.BinaryOperator.LeftShift:\n      return 'leftshift';\n    case NativeCompilerIR.BinaryOperator.RightShift:\n      return 'rightshift';\n    case NativeCompilerIR.BinaryOperator.UnsignedRightShift:\n      return 'urightshift';\n    case NativeCompilerIR.BinaryOperator.BitwiseXOR:\n      return 'xor';\n    case NativeCompilerIR.BinaryOperator.BitwiseAND:\n      return 'and';\n    case NativeCompilerIR.BinaryOperator.BitwiseOR:\n      return 'or';\n    case NativeCompilerIR.BinaryOperator.LessThan:\n      return 'lt';\n    case NativeCompilerIR.BinaryOperator.LessThanOrEqual:\n      return 'lte';\n    case NativeCompilerIR.BinaryOperator.LessThanOrEqualEqual:\n      return 'ltee';\n    case NativeCompilerIR.BinaryOperator.GreaterThan:\n      return 'gt';\n    case NativeCompilerIR.BinaryOperator.GreaterThanOrEqual:\n      return 'gte';\n    case NativeCompilerIR.BinaryOperator.GreaterThanOrEqualEqual:\n      return 'gtee';\n    case NativeCompilerIR.BinaryOperator.EqualEqual:\n      return 'eq';\n    case NativeCompilerIR.BinaryOperator.EqualEqualEqual:\n      return 'eqstrict';\n    case NativeCompilerIR.BinaryOperator.DifferentThan:\n      return 'ne';\n    case NativeCompilerIR.BinaryOperator.DifferentThanStrict:\n      return 'nestrict';\n    case NativeCompilerIR.BinaryOperator.Modulo:\n      return 'mod';\n    case NativeCompilerIR.BinaryOperator.Exponentiation:\n      return 'exp';\n    case NativeCompilerIR.BinaryOperator.InstanceOf:\n      return 'instanceof';\n    case NativeCompilerIR.BinaryOperator.In:\n      return 'in';\n  }\n}\n\nfunction getBranchTypeName(branchType: NativeCompilerBuilderBranchType): string {\n  switch (branchType) {\n    case NativeCompilerBuilderBranchType.Truthy:\n      return 'branch';\n    case NativeCompilerBuilderBranchType.NotUndefinedOrNull:\n      return 'nullable_branch';\n  }\n}\n\nfunction variableToString(variable: NativeCompilerBuilderVariableID): string {\n  return variable.variable.toString();\n}\n\nclass IRStringWriter {\n  constructor(readonly writer: OutputWriter) {}\n\n  append(str: string): IRStringWriter {\n    this.writer.append(str);\n    return this;\n  }\n\n  appendQuotedString(str: string | undefined): IRStringWriter {\n    if (str === undefined) {\n      return this.append(' <null>');\n    } else {\n      // TODO(simon): Escape quotes\n      return this.append(` '${str}'`);\n    }\n  }\n\n  appendVariable(variable: NativeCompilerBuilderVariableID): IRStringWriter {\n    return this.append(` @${variable.variable}`);\n  }\n\n  appendVariables(variables: NativeCompilerBuilderVariableID[]): IRStringWriter {\n    this.append(' [');\n    for (let i = 0; i < variables.length; i++) {\n      if (i > 0) {\n        this.append(',');\n      }\n      this.appendVariable(variables[i]);\n    }\n    this.append(' ]');\n    return this;\n  }\n\n  appendAtom(atom: NativeCompilerBuilderAtomID): IRStringWriter {\n    return this.appendQuotedString(atom.identifier);\n  }\n\n  appendAtoms(atoms: NativeCompilerBuilderAtomID[]): IRStringWriter {\n    this.append(' [');\n    for (let i = 0; i < atoms.length; i++) {\n      if (i > 0) {\n        this.append(',');\n      }\n      this.appendAtom(atoms[i]);\n    }\n    this.append(' ]');\n    return this;\n  }\n\n  appendJumpTarget(jumpTarget: NativeCompilerBuilderJumpTargetID): IRStringWriter {\n    return this.appendQuotedString(jumpTarget.tag);\n  }\n}\n\nfunction outputIR(ir: NativeCompilerIR.Base, output: IRStringWriter): IRStringWriter {\n  switch (ir.kind) {\n    case NativeCompilerIR.Kind.Slot: {\n      const typedIR = ir as NativeCompilerIR.Slot;\n      // slot '<type>' <variable>\n      return output.append('slot').appendQuotedString(typedIR.value.getTypeString()).appendVariable(typedIR.value);\n    }\n    case NativeCompilerIR.Kind.Global: {\n      const typedIR = ir as NativeCompilerIR.Global;\n\n      // getglobal <output_variable>\n\n      return output.append(`getglobal`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.Keyword: {\n      const typedIR = ir as NativeCompilerIR.Keyword;\n      // storeundefined <output_variable>\n      // storenull <output_variable>\n      // storethis <output_variable>\n\n      switch (typedIR.keyword) {\n        case NativeCompilerIR.KeywordKind.Undefined:\n          return output.append(`storeundefined`).appendVariable(typedIR.variable);\n        case NativeCompilerIR.KeywordKind.Null:\n          return output.append(`storenull`).appendVariable(typedIR.variable);\n        case NativeCompilerIR.KeywordKind.This:\n          return output.append(`storethis`).appendVariable(typedIR.variable);\n      }\n    }\n    case NativeCompilerIR.Kind.Exception: {\n      const typedIR = ir as NativeCompilerIR.Exception;\n\n      // storeexception <output_variable>\n\n      return output.append(`storeexception`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.SetProperty: {\n      const typedIR = ir as NativeCompilerIR.SetProperty;\n\n      // setprop <object> <prop> <value>\n\n      if (typedIR.properties.length == 1) {\n        return output\n          .append('setprop')\n          .appendVariable(typedIR.object)\n          .appendAtom(typedIR.properties[0])\n          .appendVariable(typedIR.values[0]);\n      } else {\n        return output\n          .append('setprops')\n          .appendVariable(typedIR.object)\n          .appendAtoms(typedIR.properties)\n          .appendVariables(typedIR.values);\n      }\n    }\n    case NativeCompilerIR.Kind.SetPropertyValue: {\n      const typedIR = ir as NativeCompilerIR.SetPropertyValue;\n      // setpropv <object> <prop> <value>\n      return output\n        .append('setpropv')\n        .appendVariable(typedIR.object)\n        .appendVariable(typedIR.property)\n        .appendVariable(typedIR.value);\n    }\n    case NativeCompilerIR.Kind.SetPropertyIndex: {\n      const typedIR = ir as NativeCompilerIR.SetPropertyIndex;\n      // setpropi <object> <index> <value>\n      return output\n        .append('setpropi')\n        .appendVariable(typedIR.object)\n        .append(` ${typedIR.index}`)\n        .appendVariable(typedIR.value);\n    }\n    case NativeCompilerIR.Kind.CopyPropertiesFrom: {\n      const typedIR = ir as NativeCompilerIR.CopyPropertiesFrom;\n\n      // copyprops <src> <target>\n\n      output.append('copyprops').appendVariable(typedIR.value).appendVariable(typedIR.object);\n      if (typedIR.propertiesToIgnore) {\n        return output.appendAtoms(typedIR.propertiesToIgnore);\n      } else {\n        return output;\n      }\n    }\n    case NativeCompilerIR.Kind.GetProperty: {\n      const typedIR = ir as NativeCompilerIR.GetProperty;\n\n      // getprop <object> <property_name> <output_variable>\n\n      return output\n        .append(`getprop`)\n        .appendVariable(typedIR.object)\n        .appendAtom(typedIR.property)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.GetPropertyFree: {\n      const typedIR = ir as NativeCompilerIR.GetPropertyFree;\n\n      // getpropfree <object> <property_name> <output_variable>\n\n      return output\n        .append(`getpropfree`)\n        .appendVariable(typedIR.object)\n        .appendAtom(typedIR.property)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.GetPropertyValue: {\n      const typedIR = ir as NativeCompilerIR.GetPropertyValue;\n\n      // getpropvalue <object> <property_name_from_variable> <output_variable>\n\n      return output\n        .append(`getpropvalue`)\n        .appendVariable(typedIR.object)\n        .appendVariable(typedIR.property)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.DeleteProperty: {\n      const typedIR = ir as NativeCompilerIR.DeleteProperty;\n\n      // delprop <object> <property_name> <output_variable>\n\n      return output\n        .append(`delprop`)\n        .appendVariable(typedIR.object)\n        .appendAtom(typedIR.property)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.DeletePropertyValue: {\n      const typedIR = ir as NativeCompilerIR.DeletePropertyValue;\n\n      // delpropvalue <object> <property_name_from_variable> <output_variable>\n\n      return output\n        .append(`delpropvalue`)\n        .appendVariable(typedIR.object)\n        .appendVariable(typedIR.property)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.GetFunctionArg: {\n      const typedIR = ir as NativeCompilerIR.GetFunctionArg;\n\n      // getfnarg <arg_index> <output_variable>\n\n      return output.append(`getfnarg ${typedIR.index}`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.GetFunctionArgumentsObject: {\n      const typedIR = ir as NativeCompilerIR.GetFunctionArgumentsObject;\n\n      // getfnarguments <start_index> <output_variable>\n\n      return output.append(`getfnarguments ${typedIR.startIndex}`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.GetSuper: {\n      const typedIR = ir as NativeCompilerIR.GetSuper;\n\n      // getsuper <output_variable>\n\n      return output.append(`getsuper`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.GetSuperConstructor: {\n      const typedIR = ir as NativeCompilerIR.GetSuperConstructor;\n\n      // getsuperctor <output_variable>\n\n      return output.append(`getsuperctor`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.GetClosureArg: {\n      const typedIR = ir as NativeCompilerIR.GetClosureArg;\n\n      // getclosurearg <arg_index> <output_variable>\n\n      return output.append(`getclosurearg ${typedIR.index}`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.GetModuleConst: {\n      const typedIR = ir as NativeCompilerIR.GetModuleConst;\n\n      // getmoduleconst <const_index> <output_variable>\n\n      return output.append(`getmoduleconst ${typedIR.index}`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.LiteralInteger: {\n      const typedIR = ir as NativeCompilerIR.LiteralInteger;\n\n      // storeint <int_value> <output_variable>\n\n      return output.append(`storeint ${typedIR.value}`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.LiteralLong: {\n      const typedIR = ir as NativeCompilerIR.LiteralLong;\n\n      // storelong <long_value> <output_variable>\n\n      return output.append(`storelong ${typedIR.value}`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.LiteralDouble: {\n      const typedIR = ir as NativeCompilerIR.LiteralDouble;\n\n      // storedouble <double_value> <output_variable>\n\n      return output.append(`storedouble ${typedIR.value}`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.LiteralString: {\n      const typedIR = ir as NativeCompilerIR.LiteralString;\n\n      // storestring '<string_value>' <output_variable>\n\n      return output.append(`storestring '${typedIR.value}'`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.LiteralBool: {\n      const typedIR = ir as NativeCompilerIR.LiteralBool;\n\n      // storebool <bool_value> <output_variable>\n\n      return output.append(`storebool ${typedIR.value ? 'true' : 'false'}`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.UnaryOp: {\n      const typedIR = ir as NativeCompilerIR.UnaryOp;\n\n      // <operator_name> <object> <output_variable>\n\n      return output\n        .append(getUnaryOperatorName(typedIR.operator))\n        .appendVariable(typedIR.operand)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.BinaryOp: {\n      const typedIR = ir as NativeCompilerIR.BinaryOp;\n\n      // <operator_name> <left_variable> <right_variable> <output_variable>\n\n      return output\n        .append(getBinaryOpOperatorName(typedIR.operator))\n        .appendVariable(typedIR.left)\n        .appendVariable(typedIR.right)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.NewObject: {\n      const typedIR = ir as NativeCompilerIR.NewObject;\n\n      // newobject <output_variable>\n\n      return output.append(`newobject`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.NewArray: {\n      const typedIR = ir as NativeCompilerIR.NewArray;\n\n      // newarray <output_variable>\n\n      return output.append(`newarray`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.NewArrowFunctionValue: {\n      const typedIR = ir as NativeCompilerIR.NewArrowFunctionValue;\n\n      // newarrowfn <name> [<closure_args>] <output_variable>\n\n      return output\n        .append(`newarrowfn`)\n        .appendQuotedString(typedIR.functionName)\n        .appendVariables(typedIR.closureArgs)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.NewFunctionValue: {\n      const typedIR = ir as NativeCompilerIR.NewFunctionValue;\n\n      // newfn <name> [<closure_args>] <output_variable>\n\n      return output\n        .append(`newfn`)\n        .appendQuotedString(typedIR.functionName)\n        .appendAtom(typedIR.name)\n        .appendVariables(typedIR.closureArgs)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.NewClassValue: {\n      const typedIR = ir as NativeCompilerIR.NewClassValue;\n\n      // newclass <name> <ctor_name> <parent_ctor> [<closure_args>] <output_variable>\n\n      output.append(`newclass`).appendQuotedString(typedIR.functionName).appendAtom(typedIR.name);\n\n      if (typedIR.parentClass) {\n        output.appendVariable(typedIR.parentClass);\n      } else {\n        output.append(' <null>');\n      }\n\n      return output.appendVariables(typedIR.closureArgs).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.SetClassElement: {\n      const typedIR = ir as NativeCompilerIR.SetClassElement;\n      let irName: string;\n\n      switch (typedIR.type) {\n        case NativeCompilerIR.ClassElementType.Method:\n          irName = typedIR.static ? 'setclassstaticmethod' : 'setclassmethod';\n          break;\n        case NativeCompilerIR.ClassElementType.Getter:\n          irName = typedIR.static ? 'setclassstaticgetter' : 'setclassgetter';\n          break;\n        case NativeCompilerIR.ClassElementType.Setter:\n          irName = typedIR.static ? 'setclassstaticsetter' : 'setclasssetter';\n          break;\n      }\n\n      return output.append(irName).appendVariable(typedIR.cls).appendAtom(typedIR.name).appendVariable(typedIR.value);\n    }\n    case NativeCompilerIR.Kind.SetClassElementValue: {\n      const typedIR = ir as NativeCompilerIR.SetClassElementValue;\n      let irName: string;\n\n      switch (typedIR.type) {\n        case NativeCompilerIR.ClassElementType.Method:\n          irName = typedIR.static ? 'setclassstaticmethodv' : 'setclassmethodv';\n          break;\n        case NativeCompilerIR.ClassElementType.Getter:\n          irName = typedIR.static ? 'setclassstaticgetter' : 'setclassgetterv';\n          break;\n        case NativeCompilerIR.ClassElementType.Setter:\n          irName = typedIR.static ? 'setclassstaticsetterv' : 'setclasssetterv';\n          break;\n      }\n\n      return output\n        .append(irName)\n        .appendVariable(typedIR.cls)\n        .appendVariable(typedIR.name)\n        .appendVariable(typedIR.value);\n    }\n    case NativeCompilerIR.Kind.Retain: {\n      const typedIR = ir as NativeCompilerIR.Retain;\n      // retain <value>\n      return output.append('retain').appendVariable(typedIR.value);\n    }\n    case NativeCompilerIR.Kind.Free: {\n      const typedIR = ir as NativeCompilerIR.Free;\n\n      // release <variable>\n\n      return output.append('release').appendVariable(typedIR.value);\n    }\n    case NativeCompilerIR.Kind.FreeV: {\n      const typedIR = ir as NativeCompilerIR.FreeV;\n\n      // release_v <variables...>\n\n      return output.append('release_v').appendVariables(typedIR.values);\n    }\n    case NativeCompilerIR.Kind.NewVariableRef: {\n      const typedIR = ir as NativeCompilerIR.NewVariableRef;\n\n      // newvref '<name>' <out>\n      return output.append('newvref').appendQuotedString(typedIR.name).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.LoadVariableRef: {\n      const typedIR = ir as NativeCompilerIR.LoadVariableRef;\n\n      // loadvref <target> <out>\n      return output.append('loadvref').appendVariable(typedIR.target).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.SetVariableRef: {\n      const typedIR = ir as NativeCompilerIR.SetVariableRef;\n\n      // setvref <value> <target>\n      return output.append('setvref').appendVariable(typedIR.value).appendVariable(typedIR.target);\n    }\n    case NativeCompilerIR.Kind.IntrinsicCall: {\n      const typedIR = ir as NativeCompilerIR.IntrinsicCall;\n      return output\n        .append('intrinsic')\n        .appendQuotedString(typedIR.func)\n        .appendVariables(typedIR.args)\n        .appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.FunctionInvocation: {\n      const typedIR = ir as NativeCompilerIR.FunctionInvocation;\n\n      switch (typedIR.argsType) {\n        case NativeCompilerIR.FunctionArgumentsType.Direct:\n          // call <fn> <this> [<parameters>] <out>\n          return output\n            .append('call')\n            .appendVariable(typedIR.func)\n            .appendVariable(typedIR.obj)\n            .appendVariables(typedIR.args)\n            .appendVariable(typedIR.variable);\n        case NativeCompilerIR.FunctionArgumentsType.Indirect:\n          // callv <fn> <this> <parameters_array> <out>\n          return output\n            .append('callv')\n            .appendVariable(typedIR.func)\n            .appendVariable(typedIR.obj)\n            .appendVariable(typedIR.args[0])\n            .appendVariable(typedIR.variable);\n        case NativeCompilerIR.FunctionArgumentsType.ForwardFromCurrentCall:\n          // callf <fn> <this> <out>\n          return output\n            .append('callf')\n            .appendVariable(typedIR.func)\n            .appendVariable(typedIR.obj)\n            .appendVariable(typedIR.variable);\n      }\n    }\n    case NativeCompilerIR.Kind.ConstructorInvocation: {\n      const typedIR = ir as NativeCompilerIR.ConstructorInvocation;\n\n      switch (typedIR.argsType) {\n        case NativeCompilerIR.FunctionArgumentsType.Direct:\n          // new <fn> [<parameters>] <out>\n          return output\n            .append('new')\n            .appendVariable(typedIR.func)\n            .appendVariables(typedIR.args)\n            .appendVariable(typedIR.variable);\n        case NativeCompilerIR.FunctionArgumentsType.Indirect:\n          // newv <fn> <parameters_array> <out>\n          return output\n            .append('newv')\n            .appendVariable(typedIR.func)\n            .appendVariable(typedIR.args[0])\n            .appendVariable(typedIR.variable);\n        case NativeCompilerIR.FunctionArgumentsType.ForwardFromCurrentCall:\n          // newv <fn> <parameters_array> <out>\n          return output.append('newf').appendVariable(typedIR.func).appendVariable(typedIR.variable);\n      }\n    }\n    case NativeCompilerIR.Kind.BindJumpTarget: {\n      const typedIR = ir as NativeCompilerIR.BindJumpTarget;\n\n      // jumptarget <jump_target>\n      return output.append('jumptarget').appendJumpTarget(typedIR.target);\n    }\n    case NativeCompilerIR.Kind.Jump: {\n      const typedIR = ir as NativeCompilerIR.Jump;\n\n      // jump <jump_target>\n\n      return output.append('jump').appendJumpTarget(typedIR.target);\n    }\n    case NativeCompilerIR.Kind.Branch: {\n      const typedIR = ir as NativeCompilerIR.Branch;\n\n      // branch <variable> <jump_target_if_true> <jump_target_if_false>\n\n      output\n        .append(getBranchTypeName(typedIR.type))\n        .appendVariable(typedIR.conditionVariable)\n        .appendJumpTarget(typedIR.trueTarget);\n      if (typedIR.falseTarget) {\n        return output.appendJumpTarget(typedIR.falseTarget);\n      } else {\n        return output.append(' <null>');\n      }\n    }\n\n    case NativeCompilerIR.Kind.Iterator: {\n      const typedIR = ir as NativeCompilerIR.Iterator;\n\n      // iterator <variable> <out>\n      return output.append('iterator').appendVariable(typedIR.arg).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.IteratorNext: {\n      const typedIR = ir as NativeCompilerIR.IteratorNext;\n\n      // iteratornext <iterator> <out>\n\n      return output.append('iteratornext').appendVariable(typedIR.iterator).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.KeysIterator: {\n      const typedIR = ir as NativeCompilerIR.KeysIterator;\n\n      // keysiterator <variable> <out>\n      return output.append('keysiterator').appendVariable(typedIR.arg).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.KeysIteratorNext: {\n      const typedIR = ir as NativeCompilerIR.KeysIteratorNext;\n\n      // keysiteratornext <iterator> <out>\n\n      return output.append('keysiteratornext').appendVariable(typedIR.iterator).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.Generator: {\n      const typedIR = ir as NativeCompilerIR.Generator;\n      return output.append('generator').appendVariable(typedIR.arg).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.Resume: {\n      const typedIR = ir as NativeCompilerIR.Resume;\n      return output.append('resume').appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.Reentry: {\n      const typedIR = ir as NativeCompilerIR.Reentry;\n      output.append('reentry');\n      for (const rp of typedIR.resumePoints) {\n        output.appendJumpTarget(rp);\n      }\n      return output;\n    }\n    case NativeCompilerIR.Kind.SetResumePoint: {\n      const typedIR = ir as NativeCompilerIR.SetResumePoint;\n      return output.append('setresumepoint').appendJumpTarget(typedIR.resumePoint);\n    }\n    case NativeCompilerIR.Kind.Assignment: {\n      const typedIR = ir as NativeCompilerIR.Assignment;\n\n      // assign <variable> <output_variable>\n      return output.append('assign').appendVariable(typedIR.right).appendVariable(typedIR.left);\n    }\n    case NativeCompilerIR.Kind.GetException: {\n      const typedIR = ir as NativeCompilerIR.GetException;\n\n      // getexception <output_variable>\n\n      return output.append(`getexception`).appendVariable(typedIR.variable);\n    }\n    case NativeCompilerIR.Kind.CheckException: {\n      const typedIR = ir as NativeCompilerIR.CheckException;\n\n      // checkexception <jump_target>\n\n      return output.append(`checkexception`).appendJumpTarget(typedIR.exceptionTarget);\n    }\n    case NativeCompilerIR.Kind.Throw: {\n      const typedIR = ir as NativeCompilerIR.Throw;\n\n      // throwexception <variable> <jump_target>\n\n      return output.append('throwexception').appendVariable(typedIR.value).appendJumpTarget(typedIR.target);\n    }\n    case NativeCompilerIR.Kind.StartFunction: {\n      const typedIR = ir as NativeCompilerIR.StartFunction;\n\n      // function_begin '<name>'\n\n      return output.append('function_begin').appendQuotedString(typedIR.name);\n    }\n    case NativeCompilerIR.Kind.EndFunction: {\n      const typedIR = ir as NativeCompilerIR.EndFunction;\n\n      // function_end <output_variable>\n      return output.append('function_end').appendVariable(typedIR.returnVariable).append('\\n');\n    }\n    case NativeCompilerIR.Kind.Comments:\n    case NativeCompilerIR.Kind.ProgramCounterInfo:\n    case NativeCompilerIR.Kind.BuilderStub:\n    case NativeCompilerIR.Kind.BoilerplatePrologue:\n    case NativeCompilerIR.Kind.BoilerplateEpilogue:\n      return output;\n  }\n}\n\nexport function IRtoString(irs: NativeCompilerIR.Base[]): string {\n  const writer = new OutputWriter();\n  const irWriter = new IRStringWriter(writer);\n\n  for (const ir of irs) {\n    const writtenLength = writer.writtenLength;\n    outputIR(ir, irWriter);\n    if (writtenLength !== writer.writtenLength) {\n      writer.append('\\n');\n    }\n  }\n\n  return writer.content();\n}\n"
  },
  {
    "path": "compiler/companion/src/native/NativeCodeWriter.ts",
    "content": "import { IOutputWriter, OutputWriter } from '../OutputWriter';\n\nexport class NativeCodeWriter extends OutputWriter {\n  private static INDENT = '    ';\n\n  appendWithNewLine(str: string | IOutputWriter | undefined = undefined): void {\n    if (str !== undefined) {\n      this.append(str);\n    }\n    this.append('\\n');\n  }\n\n  appendAssignment(variable: string, str: string): void {\n    this.startAssignment(variable);\n    this.append(str);\n    this.endAssignment();\n  }\n\n  appendLabel(label: string) {\n    this.appendWithNewLine(`${label}:`);\n  }\n\n  appendAssignmentWithFunctionCall(variable: string, func: string, args: string[]) {\n    this.startAssignment(variable);\n    this.appendFunctionCall(func, args, false);\n    this.endAssignment();\n  }\n\n  appendFunctionCall(func: string, args: Array<string>, endStatement: boolean = true) {\n    this.startFunctionCall(func);\n    this.appendParameterList(args);\n    this.endFunctionCall(endStatement);\n  }\n\n  private startAssignment(variable: string) {\n    this.append(`${variable} = `);\n  }\n\n  private endAssignment() {\n    this.appendWithNewLine(';');\n  }\n\n  private startFunctionCall(funcName: string) {\n    this.append(`${funcName}(`);\n  }\n\n  private endFunctionCall(endStatement: boolean = false) {\n    this.append(')');\n    if (endStatement) {\n      this.appendWithNewLine(';');\n    }\n  }\n\n  appendParameterList(args: Array<string>) {\n    if (args.length == 0) {\n      return;\n    }\n\n    this.append(args.join(', '));\n  }\n\n  appendGoto(label: string) {\n    this.appendWithNewLine(`goto ${label};`);\n  }\n\n  beginIfStatement() {\n    this.append(`if (`);\n  }\n\n  endEndifStatement() {\n    this.append(`)`);\n  }\n\n  beginInitialization() {\n    this.beginScope();\n  }\n\n  endInitialization() {\n    this.endScope(false);\n    this.appendWithNewLine(';');\n  }\n\n  beginScope() {\n    this.appendWithNewLine(` {`);\n    this.beginIndent(NativeCodeWriter.INDENT);\n  }\n\n  endScope(withNewLine: boolean = true) {\n    this.endIndent();\n    this.append('}');\n    if (withNewLine) {\n      this.appendWithNewLine();\n    }\n  }\n\n  beginComment() {\n    this.appendWithNewLine(`/*`);\n    this.beginIndent(NativeCodeWriter.INDENT);\n  }\n\n  endComment() {\n    this.endIndent();\n    this.appendWithNewLine(`*/`);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/NativeCompiler.spec.ts",
    "content": "import 'ts-jest';\nimport { Workspace } from '../Workspace';\nimport { compileFile } from './CompileNativeCommand';\nimport { IRtoString } from './IRtoString';\nimport { NativeCompilerIR } from './builder/NativeCompilerBuilderIR';\nimport * as ts from 'typescript';\n\nimport { trimAllLines } from '../utils/StringUtils';\nimport { NativeCompilerOptions } from './NativeCompilerOptions';\nimport { compileIRsToC } from './NativeCompiler';\n\nfunction sanitize(text: string): string {\n  return trimAllLines(text);\n}\n\nfunction compileAsIRString(\n  text: string,\n  options: NativeCompilerOptions,\n  setupWorkspace: ((workpace: Workspace) => void) | undefined,\n  filterIR: (ir: NativeCompilerIR.Base) => boolean,\n): string {\n  const workspace = new Workspace('/', false, undefined, {\n    target: ts.ScriptTarget.ESNext,\n    module: ts.ModuleKind.CommonJS,\n    lib: ['lib.es2015.d.ts'],\n  });\n\n  const filePath = 'file.ts';\n  workspace.registerInMemoryFile(filePath, text);\n  workspace.addSourceFileAtPath(filePath);\n  if (setupWorkspace) {\n    setupWorkspace(workspace);\n  }\n  const irs = compileFile(workspace, true, options, filePath, filePath);\n\n  const filteredIRs = irs.filter(filterIR);\n  return IRtoString(filteredIRs).trim();\n}\n\nfunction compileAsC(\n  text: string,\n  options: NativeCompilerOptions,\n  selectFunction: string | undefined,\n  setupWorkspace: ((workpace: Workspace) => void) | undefined,\n): string {\n  const workspace = new Workspace('/', false, undefined, {\n    target: ts.ScriptTarget.ESNext,\n    module: ts.ModuleKind.CommonJS,\n    lib: ['lib.es2015.d.ts'],\n  });\n\n  const filePath = 'file.ts';\n  workspace.registerInMemoryFile(filePath, text);\n  workspace.addSourceFileAtPath(filePath);\n  if (setupWorkspace) {\n    setupWorkspace(workspace);\n  }\n  const irs = compileFile(workspace, true, options, filePath, filePath);\n  const c_code = compileIRsToC(irs, options).source;\n\n  if (selectFunction) {\n    const functionStart = `static tsn_value file_ts_${selectFunction}(tsn_vm *ctx,`;\n    const lines = c_code.split('\\n');\n    const output: string[] = [];\n    let inFunction = false;\n    let inComment = false;\n    for (const line of lines) {\n      if (line.startsWith(functionStart) && !line.endsWith(';')) {\n        inFunction = true;\n      }\n      if (line.trimStart().startsWith('/*')) {\n        inComment = true;\n      }\n      if (line.trimStart().startsWith('*/')) {\n        inComment = false;\n      }\n      if (inFunction && !inComment) {\n        output.push(line);\n      }\n      if (line.startsWith('}')) {\n        inFunction = false;\n      }\n    }\n    return output.join('\\n');\n  }\n  return c_code;\n}\n\nfunction configuredCompile(\n  text: string,\n  options: NativeCompilerOptions,\n  includeFunctionArguments: boolean,\n  includeRetainRelease: boolean,\n  includeSlots: boolean,\n  includeExceptionHandling: boolean,\n  functionsToKeep: string[] | undefined,\n  setupWorkspace?: ((workpace: Workspace) => void) | undefined,\n): string {\n  let inExceptionJumpTarget = false;\n  let inRemovedFunction = false;\n  return compileAsIRString(text, options, setupWorkspace, (ir) => {\n    switch (ir.kind) {\n      case NativeCompilerIR.Kind.StartFunction: {\n        const typedIR = ir as NativeCompilerIR.StartFunction;\n        if (functionsToKeep === undefined || functionsToKeep.includes(typedIR.name)) {\n          return true;\n        } else {\n          inRemovedFunction = true;\n          return false;\n        }\n      }\n      case NativeCompilerIR.Kind.EndFunction: {\n        if (inRemovedFunction) {\n          inRemovedFunction = false;\n          return false;\n        } else {\n          return true;\n        }\n      }\n      case NativeCompilerIR.Kind.Slot:\n        return !inRemovedFunction && includeSlots;\n      case NativeCompilerIR.Kind.Retain:\n        return !inRemovedFunction && includeRetainRelease;\n      case NativeCompilerIR.Kind.Free:\n        return !inRemovedFunction && includeRetainRelease;\n      case NativeCompilerIR.Kind.GetFunctionArg:\n        return !inRemovedFunction && includeFunctionArguments;\n      case NativeCompilerIR.Kind.BindJumpTarget: {\n        const typedIR = ir as NativeCompilerIR.BindJumpTarget;\n\n        inExceptionJumpTarget = typedIR.target.tag === 'exception';\n      }\n      default: {\n        if (inRemovedFunction) {\n          return false;\n        }\n\n        if (includeExceptionHandling) {\n          return true;\n        } else {\n          return !inExceptionJumpTarget;\n        }\n      }\n    }\n  });\n}\n\nfunction compileSimplified(text: string, functionsToKeep?: string[]): string {\n  return configuredCompile(\n    text,\n    { optimizeSlots: false, optimizeVarRefs: true },\n    false,\n    false,\n    false,\n    false,\n    functionsToKeep,\n  );\n}\n\ndescribe('NativeCompiler', () => {\n  it('supports var ref', () => {\n    const result = configuredCompile(\n      `\n      let value = 42;\n      value = 43;\n      `,\n      { optimizeSlots: false, optimizeVarRefs: false },\n      true,\n      false,\n      false,\n      false,\n      undefined,\n    );\n\n    expect(result).toBe(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'exports' @4\ngetfnarg 2 @3\nsetvref @3 @4\nnewvref 'value' @5\nstoreint 42 @6\nsetvref @6 @5\nstoreint 43 @7\nsetvref @7 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('can optimize var refs', () => {\n    const result = configuredCompile(\n      `\n      let value = 42;\n      value = 43;\n      `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      false,\n      undefined,\n    );\n\n    expect(result).toBe(\n      `\nfunction_begin 'file_ts__module_init__'\ngetfnarg 2 @3\nstoreint 42 @6\nassign @6 @5\nstoreint 43 @7\nassign @7 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('can optimize var refs and slots', () => {\n    const result = configuredCompile(\n      `\n    let value = 42;\n    value = 43;\n    `,\n      { optimizeSlots: true, optimizeVarRefs: true },\n      true,\n      true,\n      true,\n      false,\n      undefined,\n    );\n\n    expect(result).toBe(\n      `\nfunction_begin 'file_ts__module_init__'\nslot 'retval' @1\nslot 'object' @2\nslot 'number' @3\nslot 'number' @4\ngetfnarg 2 @2\nstoreint 42 @3\nassign @3 @4\nstoreint 43 @3\nassign @3 @4\njump 'return'\nrelease @2\nretain @1\njumptarget 'return'\nrelease @2\nfunction_end @1\n    `.trim(),\n    );\n  });\n\n  it('reconciles types on captured variable refs', () => {\n    const result = configuredCompile(\n      `\n      declare function build(cb: () => void): void;\n\n      let array: string[] | undefined;\n      build(() => {\n          array = [];\n      });\n\n      const arrayLength = array.length;\n    `,\n      { optimizeSlots: true, optimizeVarRefs: true },\n      true,\n      true,\n      false,\n      false,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toBe(\n      `\nfunction_begin 'file_ts__module_init__'\ngetfnarg 2 @2\nnewvref 'array' @3\nsetvref @4 @3\nrelease @2\ngetglobal @2\ngetprop @2 'build' @5\nrelease @2\nnewarrowfn 'file_ts_anon' [ @3 ] @2\ncall @5 @5 [ @2 ] @6\nrelease @5\nloadvref @3 @5\nrelease @2\ngetprop @5 'length' @2\nrelease @6\nassign @2 @6\nretain @6\njump 'return'\nrelease @5\nretain @1\njumptarget 'return'\nrelease @6\nrelease @5\nrelease @3\nrelease @2\nfunction_end @1\n    `.trim(),\n    );\n  });\n\n  it('can optimize var refs of function arguments', () => {\n    const result = configuredCompile(\n      `\n      function myFn(value: number): number {\n        const value2 = value;\n        return value2;\n      }\n      `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      false,\n      ['file_ts_myFn'],\n    );\n\n    expect(result).toBe(\n      `\nfunction_begin 'file_ts_myFn'\ngetfnarg 0 @4\nassign @4 @5\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('supports int literals', () => {\n    const result = compileSimplified(`const value = 42;`);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 42 @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('supports long literals', () => {\n    const result = compileSimplified(`const value = 123456789012;`);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstorelong 123456789012 @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('supports double literals', () => {\n    const result = compileSimplified(`const value = 42.5;`);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoredouble 42.5 @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('supports double with scientific notation', () => {\n    const result = compileSimplified(`const value = 17976931348623157e292;`);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoredouble 1.7976931348623157e+308 @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('supports string literals', () => {\n    const result = compileSimplified(`const value = 'Hello World';`);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetmoduleconst 0 @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('supports variable', () => {\n    const result = compileSimplified(`\n        let value = 42;\n        let value2 = 43;\n        value = value2;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 42 @7\nassign @7 @5\nstoreint 43 @8\nassign @8 @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles function', () => {\n    const result = configuredCompile(\n      `\n        function myFunction(input: number): number {\n          return input;\n        }\n        `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      false,\n      undefined,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetfnarg 2 @3\nnewfn 'file_ts_myFunction' 'myFunction' [ ] @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_myFunction'\ngetfnarg 0 @4\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles unary operators', () => {\n    const result = compileSimplified(`\n        let value = 1;\n        let value2: any = +value;\n        value2 = -value;\n        value2++;\n        value2--;\n        value2 = ~value;\n        value2 = !value;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @7\nassign @7 @5\nplus @5 @9\nassign @9 @6\nneg @5 @11\nassign @11 @6\nassign @6 @13\ninc @6 @14\nassign @14 @6\nassign @6 @16\ndec @6 @17\nassign @17 @6\nbitwisenot @5 @19\nassign @19 @6\nlogicalnot @5 @21\nassign @21 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n  it('compiles arith binary operators', () => {\n    const result = compileSimplified(`\n        let value = 1;\n        let value2 = 42;\n        let value3 = value + value2;\n        value3 = value - value2;\n        value3 = value * value2;\n        value3 = value / value2;\n        value3 = value % value2;\n        value3 = value ** value2;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @8\nassign @8 @5\nstoreint 42 @9\nassign @9 @6\nadd @5 @6 @12\nassign @12 @7\nsub @5 @6 @15\nassign @15 @7\nmult @5 @6 @18\nassign @18 @7\ndiv @5 @6 @21\nassign @21 @7\nmod @5 @6 @24\nassign @24 @7\nexp @5 @6 @27\nassign @27 @7\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles shift binary operators', () => {\n    const result = compileSimplified(`\n        let value = 1;\n        let value2 = 42;\n        let value3 = value >> value2;\n        value3 = value << value2;\n        value3 = value >>> value2;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @8\nassign @8 @5\nstoreint 42 @9\nassign @9 @6\nrightshift @5 @6 @12\nassign @12 @7\nleftshift @5 @6 @15\nassign @15 @7\nurightshift @5 @6 @18\nassign @18 @7\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles bitwise binary operators', () => {\n    const result = compileSimplified(`\n        let value = 1;\n        let value2 = 42;\n        let value3 = value ^ value2;\n        value3 = value & value2;\n        value3 = value | value2;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @8\nassign @8 @5\nstoreint 42 @9\nassign @9 @6\nxor @5 @6 @12\nassign @12 @7\nand @5 @6 @15\nassign @15 @7\nor @5 @6 @18\nassign @18 @7\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles assignment operators', () => {\n    const result = compileSimplified(`\n        let value = 1;\n        value += 1;\n        value -= 2;\n        value *= 3;\n        value /= 4;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @6\nassign @6 @5\nstoreint 1 @7\nadd @5 @7 @9\nassign @9 @5\nstoreint 2 @10\nsub @5 @10 @12\nassign @12 @5\nstoreint 3 @13\nmult @5 @13 @15\nassign @15 @5\nstoreint 4 @16\ndiv @5 @16 @18\nassign @18 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles comma operator', () => {\n    const result = compileSimplified(`\n      let value1 = 1;\n      let value2 = 2;\n      let value3 = 3;\n\n      let result = 0;\n      result = value1 = 3, value2 = 2, value3 = 1;\n    `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @9\nassign @9 @5\nstoreint 2 @10\nassign @10 @6\nstoreint 3 @11\nassign @11 @7\nstoreint 0 @12\nassign @12 @8\nstoreint 1 @13\nassign @13 @7\nstoreint 2 @14\nassign @14 @6\nstoreint 3 @15\nassign @15 @5\nassign @15 @8\njump 'return'\njumptarget 'return'\nfunction_end @1\n    `.trim(),\n    );\n  });\n\n  it('compiles assignment expression operators', () => {\n    const result = compileSimplified(`\n        let value = 1;\n        let value2 = value += 1;\n        value2 = value -= 1;\n        value2 = value *= 1;\n        value2 = value /= 1;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @7\nassign @7 @5\nstoreint 1 @8\nadd @5 @8 @10\nassign @10 @5\nassign @10 @6\nstoreint 1 @11\nsub @5 @11 @13\nassign @13 @5\nassign @13 @6\nstoreint 1 @14\nmult @5 @14 @16\nassign @16 @5\nassign @16 @6\nstoreint 1 @17\ndiv @5 @17 @19\nassign @19 @5\nassign @19 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles instancesof', () => {\n    const result = compileSimplified(`\n        let value: any = 1;\n        let value2 = value instanceof value.prototype;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @7\nassign @7 @5\ngetprop @5 'prototype' @9\ninstanceof @5 @9 @11\nassign @11 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n              `.trim(),\n    );\n  });\n\n  it('compiles typeof', () => {\n    const result = compileSimplified(`\n        let value = 1;\n        let value2 = typeof value;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @7\nassign @7 @5\ntypeof @5 @9\nassign @9 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles get property', () => {\n    const result = compileSimplified(`\n        let value = 'hello';\n        const value2 = value.length;\n        const value3 = value['length'];\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetmoduleconst 0 @8\nassign @8 @5\ngetprop @5 'length' @10\nassign @10 @6\ngetmoduleconst 1 @12\ngetpropvalue @5 @12 @13\nassign @13 @7\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles get property index', () => {\n    const result = compileSimplified(`\n        let value = [42, 43];\n        const value2 = value[1];\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewarray @7\nstoreint 0 @8\nstoreint 42 @9\nsetpropv @7 @8 @9\ninc @8 @10\nstoreint 43 @11\nsetpropv @7 @10 @11\ninc @10 @12\nassign @7 @5\nstoreint 1 @14\ngetpropvalue @5 @14 @15\nassign @15 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles object literals', () => {\n    const result = compileSimplified(`\n        const value = {};\n        const value2 = {hello: value};\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @7\nassign @7 @5\nnewobject @8\nsetprop @8 'hello' @5\nassign @8 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles object literals with int key', () => {\n    const result = compileSimplified(`\n        const value = {};\n        const value2 = {1: value, 2: false};\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @7\nassign @7 @5\nnewobject @8\nstoreint 1 @9\nsetpropv @8 @9 @5\nstoreint 2 @11\nstorebool false @12\nsetpropv @8 @11 @12\nassign @8 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('comiles object literal with string key', () => {\n    const result = compileSimplified(`\n        const value = {'hello': 'world'};\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @6\ngetmoduleconst 0 @7\ngetmoduleconst 1 @8\nsetpropv @6 @7 @8\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('comiles object literal with method', () => {\n    const result = compileSimplified(\n      `\n        const value = {\n          name(): string {\n            return 'Hello World';\n          }\n        };\n        `,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @6\nnewfn 'file_ts_value_name' 'name' [ ] @7\nsetprop @6 'name' @7\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles array literals', () => {\n    const result = compileSimplified(`\n        const value = [];\n        const value2 = [value];\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewarray @7\nassign @7 @5\nnewarray @8\nstoreint 0 @9\nsetpropv @8 @9 @5\ninc @9 @11\nassign @8 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles array spread operator', () => {\n    const result = compileSimplified(`\n        const value = [];\n        const value2 = [...value];\n        const value3 = [...value, 42];\n        const value4 = [42, ...value];\n        const value5 = [42, ...value, 43];\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewarray @10\nassign @10 @5\nnewarray @11\nstoreint 0 @12\ncopyprops @5 @11\nadd @12 @14 @15\nassign @11 @6\nnewarray @16\nstoreint 0 @17\ncopyprops @5 @16\nadd @17 @19 @20\nstoreint 42 @21\nsetpropv @16 @20 @21\ninc @20 @22\nassign @16 @7\nnewarray @23\nstoreint 0 @24\nstoreint 42 @25\nsetpropv @23 @24 @25\ninc @24 @26\ncopyprops @5 @23\nadd @26 @28 @29\nassign @23 @8\nnewarray @30\nstoreint 0 @31\nstoreint 42 @32\nsetpropv @30 @31 @32\ninc @31 @33\ncopyprops @5 @30\nadd @33 @35 @36\nstoreint 43 @37\nsetpropv @30 @36 @37\ninc @36 @38\nassign @30 @9\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles object spread operator', () => {\n    const result = compileSimplified(`\n        const value = {};\n        const value2 = {...value};\n        const value3 = {...value, prop: 42};\n        const value4 = {propA: 42, ...value};\n        const value5 = {propA: 42, ...value, propB: 43};\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @10\nassign @10 @5\nnewobject @11\ncopyprops @5 @11\nassign @11 @6\nnewobject @14\ncopyprops @5 @14\nstoreint 42 @17\nsetprop @14 'prop' @17\nassign @14 @7\nnewobject @18\nstoreint 42 @19\nsetprop @18 'propA' @19\ncopyprops @5 @18\nassign @18 @8\nnewobject @22\nstoreint 42 @23\nsetprop @22 'propA' @23\ncopyprops @5 @22\nstoreint 43 @26\nsetprop @22 'propB' @26\nassign @22 @9\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles for of loops', () => {\n    const result = compileSimplified(`\n        const array = [42];\n        let current = 0;\n        for (const item of array) {\n          current += item;\n        }\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewarray @7\nstoreint 0 @8\nstoreint 42 @9\nsetpropv @7 @8 @9\ninc @8 @10\nassign @7 @5\nstoreint 0 @11\nassign @11 @6\niterator @5 @13\njumptarget 'cond'\niteratornext @13 @14\nbranch @13 'body' 'exit'\njumptarget 'body'\nassign @14 @15\nadd @6 @15 @18\nassign @18 @6\njump 'cond'\njumptarget 'exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles for of loops with no variable', () => {\n    const result = compileSimplified(`\n        const array = [42];\n        let current = 0;\n        let item: number;\n        for (item of array) {\n          current += item;\n        }\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewarray @8\nstoreint 0 @9\nstoreint 42 @10\nsetpropv @8 @9 @10\ninc @9 @11\nassign @8 @5\nstoreint 0 @12\nassign @12 @6\nassign @13 @7\niterator @5 @15\njumptarget 'cond'\niteratornext @15 @16\nbranch @15 'body' 'exit'\njumptarget 'body'\nadd @6 @7 @19\nassign @19 @6\njump 'cond'\njumptarget 'exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles for loops', () => {\n    const result = compileSimplified(`\n        const array = [42];\n        let current = 0;\n        for (let i = 0; i < array.length; i++) {\n          current += array[i];\n        }\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewarray @7\nstoreint 0 @8\nstoreint 42 @9\nsetpropv @7 @8 @9\ninc @8 @10\nassign @7 @5\nstoreint 0 @11\nassign @11 @6\nstoreint 0 @13\nassign @13 @12\njumptarget 'cond'\ngetprop @5 'length' @15\nlt @12 @15 @17\nbranch @17 'body' 'exit'\njumptarget 'body'\ngetpropvalue @5 @12 @20\nadd @6 @20 @22\nassign @22 @6\nassign @12 @24\ninc @12 @25\nassign @25 @12\njump 'cond'\njumptarget 'exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles for in loops', () => {\n    expect(() => {\n      const result = compileSimplified(`\n          const object = {};\n          const allKeys: string[] = [];\n          for (const key in object) {\n            allKeys.push(key);\n          }\n          `);\n\n      expect(result).toEqual(\n        `\nfunction_begin 'file_ts__module_init__'\nnewarray @6\nstoreint 0 @7\nstoreint 42 @8\nsetpropv @6 @7 @8\ninc @7 @9\nassign @6 @5\nstoreint 0 @11\nassign @11 @10\nstoreint 0 @13\nassign @13 @12\njumptarget 'cond'\ngetprop @5 'length' @16\nlt @12 @16 @17\nbranch @17 'body' 'exit'\njumptarget 'body'\ngetpropvalue @5 @12 @20\nadd @10 @20 @22\nassign @22 @10\nassign @12 @24\ninc @12 @25\nassign @25 @12\njump 'cond'\njumptarget 'exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n      );\n    }).toThrow(); // not implemented yet\n  });\n\n  it('compiles continue statement', () => {\n    const result = compileSimplified(\n      `\n    function process(input: number[]): number {\n      let output = 0;\n      for (let i = 0; i < input.length; i++) {\n        if (i % 2 === 0) {\n          continue;\n        }\n        output += input[i];\n      }\n\n\n      return output;\n    }\n        `,\n      ['file_ts_process'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_process'\nstoreint 0 @6\nassign @6 @5\nstoreint 0 @8\nassign @8 @7\njumptarget 'cond'\ngetprop @4 'length' @10\nlt @7 @10 @12\nbranch @12 'body' 'exit'\njumptarget 'body'\njumptarget 'condition'\nstoreint 0 @13\nstoreint 2 @14\nmod @7 @14 @16\neqstrict @16 @13 @17\nbranch @17 'true' 'false'\njumptarget 'true'\njump 'cond'\njump 'exit'\njumptarget 'false'\njumptarget 'exit'\ngetpropvalue @4 @7 @20\nadd @5 @20 @22\nassign @22 @5\nassign @7 @24\ninc @7 @25\nassign @25 @7\njump 'cond'\njumptarget 'exit'\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles while loops', () => {\n    const result = compileSimplified(`\n        let current = 0;\n        while (current < 0) {\n          current++;\n        }\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 0 @6\nassign @6 @5\njumptarget 'cond'\nstoreint 0 @7\nlt @5 @7 @9\nbranch @9 'body' 'exit'\njumptarget 'body'\nassign @5 @11\ninc @5 @12\nassign @12 @5\njump 'cond'\njumptarget 'exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compile do while loops', () => {\n    const result = compileSimplified(`\n        let current = 0;\n        do {\n          current++;\n        } while (current < 0);\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 0 @6\nassign @6 @5\njumptarget 'body'\nassign @5 @8\ninc @5 @9\nassign @9 @5\njumptarget 'cond'\nstoreint 0 @10\nlt @5 @10 @12\nbranch @12 'body' 'exit'\njumptarget 'exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles function calls', () => {\n    const result = configuredCompile(\n      `\n        function multiply(left: number, right: number): number {\n          return left * right;\n        }\n        multiply(2, 4);\n        `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      false,\n      false,\n      false,\n      false,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewfn 'file_ts_multiply' 'multiply' [ ] @6\nassign @6 @5\nstoreint 2 @8\nstoreint 4 @9\ncall @5 @5 [ @8, @9 ] @10\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles lambda', () => {\n    const result = compileSimplified(`\n        declare function reduce(input: number[], initial: number, acc: (cur: number, input: number) => number): number;\n\n        reduce([1, 2, 3], 0, (c, i) => c + i);\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetglobal @5\ngetprop @5 'reduce' @6\nnewarray @7\nstoreint 0 @8\nstoreint 1 @9\nsetpropv @7 @8 @9\ninc @8 @10\nstoreint 2 @11\nsetpropv @7 @10 @11\ninc @10 @12\nstoreint 3 @13\nsetpropv @7 @12 @13\ninc @12 @14\nstoreint 0 @15\nnewarrowfn 'file_ts_anon' [ ] @16\ncall @6 @6 [ @7, @15, @16 ] @17\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_anon'\nadd @5 @6 @9\nassign @9 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles lambda with immutable captured values', () => {\n    const result = compileSimplified(`\n        declare function reduce(input: number[], initial: number, acc: (cur: number, input: number) => number): number;\n\n        const additional = 10;\n        reduce([1, 2, 3], 0, (c, i) => c + i + additional);\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'additional' @5\nstoreint 10 @6\nsetvref @6 @5\ngetglobal @7\ngetprop @7 'reduce' @8\nnewarray @9\nstoreint 0 @10\nstoreint 1 @11\nsetpropv @9 @10 @11\ninc @10 @12\nstoreint 2 @13\nsetpropv @9 @12 @13\ninc @12 @14\nstoreint 3 @15\nsetpropv @9 @14 @15\ninc @14 @16\nstoreint 0 @17\nnewarrowfn 'file_ts_anon' [ @5 ] @18\ncall @8 @8 [ @9, @17, @18 ] @19\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_anon'\ngetclosurearg 0 @7\nloadvref @7 @8\nadd @5 @6 @11\nadd @11 @8 @12\nassign @12 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles lambda with mutable captured values', () => {\n    const result = compileSimplified(`\n        declare function reduce(input: number[], initial: number, acc: (cur: number, input: number) => number): number;\n\n        let additional = 10;\n        reduce([1, 2, 3], 0, (c, i) => {\n          const result = c + i + additional;\n          additional++;\n          return result;\n        });\n        additional++;\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'additional' @5\nstoreint 10 @6\nsetvref @6 @5\ngetglobal @7\ngetprop @7 'reduce' @8\nnewarray @9\nstoreint 0 @10\nstoreint 1 @11\nsetpropv @9 @10 @11\ninc @10 @12\nstoreint 2 @13\nsetpropv @9 @12 @13\ninc @12 @14\nstoreint 3 @15\nsetpropv @9 @14 @15\ninc @14 @16\nstoreint 0 @17\nnewarrowfn 'file_ts_anon' [ @5 ] @18\ncall @8 @8 [ @9, @17, @18 ] @19\nloadvref @5 @20\nassign @20 @21\ninc @20 @22\nsetvref @22 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_anon'\ngetclosurearg 0 @8\nloadvref @8 @9\nadd @5 @6 @12\nadd @12 @9 @13\nassign @13 @7\nloadvref @8 @14\nassign @14 @15\ninc @14 @16\nsetvref @16 @8\nassign @7 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles lambda with nested immutable captured values', () => {\n    const result = compileSimplified(`\n        declare function visit(input: number[], getVisitor: () => (input: number) => number);\n\n        const additional = 10;\n        visit([1, 2, 3], () => {\n          return (i) => i + additional;\n        })\n        `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'additional' @5\nstoreint 10 @6\nsetvref @6 @5\ngetglobal @7\ngetprop @7 'visit' @8\nnewarray @9\nstoreint 0 @10\nstoreint 1 @11\nsetpropv @9 @10 @11\ninc @10 @12\nstoreint 2 @13\nsetpropv @9 @12 @13\ninc @12 @14\nstoreint 3 @15\nsetpropv @9 @14 @15\ninc @14 @16\nnewarrowfn 'file_ts_anon' [ @5 ] @17\ncall @8 @8 [ @9, @17 ] @18\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_anon'\ngetclosurearg 0 @3\nnewarrowfn 'file_ts_anon_0' [ @3 ] @4\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_anon_0'\ngetclosurearg 0 @5\nloadvref @5 @6\nadd @4 @6 @8\nassign @8 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles self referencing functions', () => {\n    const result = configuredCompile(\n      `\n      function add(input: number, max: number): number {\n        return input < max ? add(input + 1, max) : input;\n      }\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'add' @3\nnewfn 'file_ts_add' 'add' [ @3 ] @2\nsetvref @2 @3\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_add'\ngetclosurearg 0 @2\njumptarget 'condition'\nlt @3 @4 @5\nbranch @5 'condition_true' 'condition_false'\njumptarget 'condition_true'\nloadvref @2 @6\nstoreint 1 @7\nadd @3 @7 @8\ncall @6 @6 [ @8, @4 ] @9\nassign @9 @4\njump 'exit'\njumptarget 'condition_false'\nassign @3 @4\njump 'exit'\njumptarget 'exit'\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n            `.trim(),\n    );\n  });\n\n  it('compiles for of loops', () => {\n    const result = compileSimplified(\n      `\n      function add(items: number[]): number {\n        let output = 0;\n        for (const item of items) {\n          output += item;\n        }\n\n        return output;\n      }\n        `,\n      ['file_ts_add'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_add'\nstoreint 0 @6\nassign @6 @5\niterator @4 @8\njumptarget 'cond'\niteratornext @8 @9\nbranch @8 'body' 'exit'\njumptarget 'body'\nassign @9 @10\nadd @5 @10 @13\nassign @13 @5\njump 'cond'\njumptarget 'exit'\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n    `.trim(),\n    );\n  });\n\n  it('compiles for in loops', () => {\n    const result = compileSimplified(\n      `\n      function add(items: number[]): number {\n        let output = 0;\n        for (const k in items) {\n          output += items[k];\n        }\n\n        return output;\n      }\n        `,\n      ['file_ts_add'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_add'\nstoreint 0 @6\nassign @6 @5\nkeysiterator @4 @8\njumptarget 'cond'\nkeysiteratornext @8 @9\nbranch @8 'body' 'exit'\njumptarget 'body'\nassign @9 @10\ngetpropvalue @4 @10 @13\nadd @5 @13 @15\nassign @15 @5\njump 'cond'\njumptarget 'exit'\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n    `.trim(),\n    );\n  });\n\n  it('compiles namespace', () => {\n    const result = compileSimplified(\n      `\n        export namespace MyNamespace {\n          export const VALUE = 42;\n        }\n        `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @6\nassign @6 @5\nsetprop @3 'MyNamespace' @6\nstoreint 42 @9\nassign @9 @8\nsetprop @5 'VALUE' @9\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles class', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n      }\n        `,\n      undefined,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_MyClass' 'MyClass' @6 [ ] @7\nassign @7 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_MyClass'\nassign @3 @4\nstoreexception @5\nnew @3 [ ] @6\nassign @6 @4\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles class with initialized property', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        value = 42;\n      }\n        `,\n      ['file_ts_MyClass'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_MyClass'\nassign @3 @4\nstoreexception @5\nnew @3 [ ] @6\nassign @6 @4\nstoreint 42 @9\nsetprop @4 'value' @9\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles class with static initialized property', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        static value = 42;\n      }\n        `,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_MyClass' 'MyClass' @6 [ ] @7\nassign @7 @5\nstoreint 42 @8\nsetprop @7 'value' @8\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles class with method', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        sayHello(): void {\n\n        }\n      }\n        `,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_MyClass' 'MyClass' @6 [ ] @7\nassign @7 @5\nnewfn 'file_ts_MyClass_sayHello' 'sayHello' [ ] @8\nsetclassmethod @7 'sayHello' @8\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles class with static method', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        static sayHello(): void {\n\n        }\n      }\n        `,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_MyClass' 'MyClass' @6 [ ] @7\nassign @7 @5\nnewfn 'file_ts_MyClass_sayHello' 'sayHello' [ ] @8\nsetclassstaticmethod @7 'sayHello' @8\njump 'return'\njumptarget 'return'\nfunction_end @1\n    `.trim(),\n    );\n  });\n\n  it('compiles class with getter', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        get value(): string {\n          return this.toString();\n        }\n      }\n        `,\n      ['file_ts__module_init__', 'file_ts_MyClass__get__value'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_MyClass' 'MyClass' @6 [ ] @7\nassign @7 @5\nnewfn 'file_ts_MyClass__get__value' 'value' [ ] @8\nsetclassgetter @7 'value' @8\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_MyClass__get__value'\nstorethis @3\nassign @3 @4\ngetprop @4 'toString' @6\ncall @6 @4 [ ] @7\nassign @7 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles class with setter', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        private _value?: string;\n        set value(v: string) {\n          this._value = v;\n        }\n      }\n        `,\n      ['file_ts__module_init__', 'file_ts_MyClass__set__value'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_MyClass' 'MyClass' @6 [ ] @7\nassign @7 @5\nnewfn 'file_ts_MyClass__set__value' 'value' [ ] @8\nsetclasssetter @7 'value' @8\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_MyClass__set__value'\nstorethis @6\nassign @6 @7\nsetprop @7 '_value' @4\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles class with static getter', () => {\n    const result = compileSimplified(\n      `\n      let value = 'Hello World';\n      class MyClass {\n        static get value(): string {\n          return value;\n        }\n      }\n        `,\n      ['file_ts__module_init__', 'file_ts_MyClass__get__value'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'value' @5\ngetmoduleconst 0 @7\nsetvref @7 @5\nnewclass 'file_ts_MyClass' 'MyClass' @8 [ ] @9\nassign @9 @6\nnewfn 'file_ts_MyClass__get__value' 'value' [ @5 ] @10\nsetclassstaticgetter @9 'value' @10\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_MyClass__get__value'\ngetclosurearg 0 @3\nloadvref @3 @4\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles class with static setter', () => {\n    const result = compileSimplified(\n      `\n      let value = 'Hello World';\n      class MyClass {\n        static set value(v: string) {\n          value = v;\n        }\n      }\n        `,\n      ['file_ts__module_init__', 'file_ts_MyClass__set__value'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'value' @5\ngetmoduleconst 0 @7\nsetvref @7 @5\nnewclass 'file_ts_MyClass' 'MyClass' @8 [ ] @9\nassign @9 @6\nnewfn 'file_ts_MyClass__set__value' 'value' [ @5 ] @10\nsetclassstaticsetter @9 'value' @10\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_MyClass__set__value'\ngetclosurearg 0 @6\nsetvref @4 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles class with getter/setter from value', () => {\n    const result = compileSimplified(\n      `\n      const key = Symbol();\n      class MyClass {\n        get [key]() {\n          return undefined;\n        }\n\n        set [key](v) {\n        }\n      }\n        `,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetglobal @7\ngetprop @7 'Symbol' @8\ncall @8 @8 [ ] @9\nassign @9 @5\nnewclass 'file_ts_MyClass' 'MyClass' @10 [ ] @11\nassign @11 @6\nnewfn 'file_ts_MyClass__get__anon' 'anonymous' [ ] @13\nsetclassgetterv @11 @5 @13\nnewfn 'file_ts_MyClass__set__anon' 'anonymous' [ ] @15\nsetclasssetterv @11 @5 @15\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles class with constructor', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        value: number;\n\n        constructor(value: number) {\n          this.value = value;\n        }\n      }\n        `,\n      ['file_ts_MyClass'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_MyClass'\nassign @3 @4\nstoreexception @7\nnew @3 [ ] @8\nassign @8 @4\nsetprop @4 'value' @6\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('initializes class property first before evaluating constructor block', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        value = 42;\n\n        constructor(value: number) {\n          this.value = value;\n        }\n      }\n        `,\n      ['file_ts_MyClass'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_MyClass'\nassign @3 @4\nstoreexception @7\nnew @3 [ ] @8\nassign @8 @4\nstoreint 42 @11\nsetprop @4 'value' @11\nsetprop @4 'value' @6\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles class with parameter property', () => {\n    const result = compileSimplified(\n      `\n      class MyClass {\n        constructor(readonly value: number) {\n        }\n      }\n        `,\n      ['file_ts_MyClass'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_MyClass'\nassign @3 @4\nstoreexception @7\nnew @3 [ ] @8\nassign @8 @4\nsetprop @4 'value' @6\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles class with inheritance', () => {\n    const result = compileSimplified(\n      `\n      class Parent {\n        value: number;\n\n        constructor(value: number) {\n          this.value = value;\n        }\n      }\n\n      class Child extends Parent {\n        value2 = 42;\n\n        constructor(value: number) {\n          super(value);\n\n          this.value++;\n        }\n      }\n        `,\n      ['file_ts__module_init__', 'file_ts_Child'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_Parent' 'Parent' @7 [ ] @8\nassign @8 @5\nnewclass 'file_ts_Child' 'Child' @5 [ ] @10\nassign @10 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_Child'\nassign @3 @4\ngetsuperctor @7\nstoreexception @10\nnew @7 [ @6 ] @11\nassign @11 @4\nstoreint 42 @14\nsetprop @4 'value2' @14\ngetprop @4 'value' @16\nassign @16 @17\ninc @16 @18\nassign @18 @16\nsetprop @4 'value' @18\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('respects class init ordering', () => {\n    const result = compileSimplified(\n      `\n      class Parent {\n        value: number;\n\n        constructor(value: number) {\n          this.value = value;\n        }\n      }\n\n      class Child extends Parent {\n        value = 42;\n      }\n        `,\n      ['file_ts_Child'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_Child'\nassign @3 @4\ngetsuperctor @5\nstoreexception @6\ngetfnarguments 0 @7\nnewv @5 @7 @8\nassign @8 @4\nstoreint 42 @11\nsetprop @4 'value' @11\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles class expression', () => {\n    const result = compileSimplified(\n      `\n      const MyClass = class {\n        value: number;\n\n        constructor(value: number) {\n          this.value = value;\n        }\n      }\n\n      const test = new MyClass(42);\n        `,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_MyClass_anon' 'anonymous' @7 [ ] @8\nassign @8 @5\nstoreint 42 @10\nnew @5 [ @10 ] @11\nassign @11 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles directly initialized class expression', () => {\n    const result = compileSimplified(\n      `\n      const test = new (class {\n        value: number;\n\n        constructor(value: number) {\n          this.value = value;\n        }\n      })(42);\n        `,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewclass 'file_ts_test_anon' 'anonymous' @6 [ ] @7\nstoreint 42 @8\nnew @7 [ @8 ] @9\nassign @9 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('class expression can reference self', () => {\n    const result = compileSimplified(\n      `\n      const MyClass = class MyName {\n        static lastValue?: number;\n\n        constructor(value: number) {\n          MyName.lastValue = value;\n          MyClass.lastValue = value;\n        }\n      }\n        `,\n      undefined,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'MyClass' @5\nnewvref 'MyName' @6\nnewclass 'file_ts_MyClass_MyName' 'MyName' @7 [ @6, @5 ] @8\nsetvref @8 @6\nsetvref @8 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_MyClass_MyName'\ngetclosurearg 0 @11\ngetclosurearg 1 @14\nassign @3 @4\nstoreexception @7\nnew @3 [ ] @8\nassign @8 @4\nloadvref @11 @12\nsetprop @12 'lastValue' @6\nloadvref @14 @15\nsetprop @15 'lastValue' @6\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles nested lambda accessing this', () => {\n    const result = compileSimplified(\n      `function myFunction(this: any): void {\n        const fn = () => {\n          return this.value;\n        }\n      }\n        `,\n      ['file_ts_myFunction', 'file_ts_myFunction_fn_anon'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFunction'\nnewvref 'this' @5\nstorethis @4\nsetvref @4 @5\nnewarrowfn 'file_ts_myFunction_fn_anon' [ @5 ] @6\nassign @6 @3\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_myFunction_fn_anon'\ngetclosurearg 0 @3\nloadvref @3 @4\ngetprop @4 'value' @5\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n    `.trim(),\n    );\n  });\n\n  it('compiles regex', () => {\n    const result = compileSimplified(`\n    const regex = /-/g;\n    `);\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetglobal @6\ngetprop @6 'RegExp' @7\ngetmoduleconst 0 @8\ngetmoduleconst 1 @9\nnew @7 [ @8, @9 ] @10\nassign @10 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles object binding pattern', () => {\n    const result = compileSimplified(\n      `\n    function myFunction(input: any): any {\n      const {title, subtitle} = input;\n      return title;\n    }\n    `,\n      ['file_ts_myFunction'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFunction'\ngetprop @4 'title' @8\nassign @8 @5\ngetprop @4 'subtitle' @9\nassign @9 @6\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles object binding pattern with rename', () => {\n    const result = compileSimplified(\n      `\n    function myFunction(input: any): any {\n      const {TITLE: title} = input;\n      return title;\n    }\n    `,\n      ['file_ts_myFunction'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFunction'\ngetprop @4 'TITLE' @7\nassign @7 @5\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles object binding pattern with rest', () => {\n    const result = compileSimplified(\n      `\n    function myFunction(input: any): any {\n      const {title, ...rest} = input;\n      return rest;\n    }\n    `,\n      ['file_ts_myFunction'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFunction'\ngetprop @4 'title' @8\nassign @8 @5\nnewobject @9\ncopyprops @4 @9 [ 'title' ]\nassign @9 @6\nassign @6 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles array binding pattern', () => {\n    const result = compileSimplified(\n      `\n    function myFunction(input: string[]): any {\n      const [title, subtitle] = input;\n      return title;\n    }\n    `,\n      ['file_ts_myFunction'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFunction'\nstoreint 0 @8\ngetpropvalue @4 @8 @9\nassign @9 @5\nstoreint 1 @10\ngetpropvalue @4 @10 @11\nassign @11 @6\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles array binding pattern with rest', () => {\n    const result = compileSimplified(\n      `\n    function myFunction(input: string[]): any {\n      const [title, ...subtitle] = input;\n      return subtitle;\n    }\n    `,\n      ['file_ts_myFunction'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFunction'\nstoreint 0 @8\ngetpropvalue @4 @8 @9\nassign @9 @5\ngetprop @4 'slice' @10\nstoreint 1 @11\ncall @10 @4 [ @11 ] @12\nassign @12 @6\nassign @6 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles binding pattern with default value', () => {\n    const result = compileSimplified(\n      `\n    function myFunction(input: any): any {\n      const {title, subtitle = 'Nice'} = input;\n      return subtitle;\n    }\n    `,\n      ['file_ts_myFunction'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFunction'\ngetprop @4 'title' @8\nassign @8 @5\ngetprop @4 'subtitle' @9\njumptarget 'condition'\nnestrict @9 @11 @12\nbranch @12 'condition_true' 'condition_false'\njumptarget 'condition_true'\nassign @9 @10\njump 'exit'\njumptarget 'condition_false'\ngetmoduleconst 0 @13\nassign @13 @10\njump 'exit'\njumptarget 'exit'\nassign @10 @6\nassign @6 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles binding pattern in method arguments', () => {\n    const result = compileSimplified(\n      `\n\n      const lambda: (items: string[]) => string = ([first, second]) => {\n        return first + second;\n      };\n    `,\n      ['file_ts_lambda_anon'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_lambda_anon'\nstoreint 0 @6\ngetpropvalue @5 @6 @7\nassign @7 @3\nstoreint 1 @8\ngetpropvalue @5 @8 @9\nassign @9 @4\nadd @3 @4 @12\nassign @12 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles nested binding pattern', () => {\n    const result = compileSimplified(\n      `\n    function myFunction(input: any): any {\n      const {a, b: {c: d}} = input;\n      return d;\n    }\n    `,\n      ['file_ts_myFunction'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFunction'\ngetprop @4 'b' @8\ngetprop @8 'c' @9\nassign @9 @6\ngetprop @4 'a' @10\nassign @10 @5\nassign @6 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles void expression', () => {\n    const result = compileSimplified(\n      `\n      const test = void {};\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @6\nassign @7 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles type assertion', () => {\n    const result = compileSimplified(\n      `\n      const test = <any> {};\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles arguments parameter', () => {\n    const result = compileSimplified(\n      `\n      function countArguments(): number {\n        return arguments.length;\n      }\n    `,\n      ['file_ts_countArguments'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_countArguments'\ngetfnarguments 0 @4\nassign @4 @3\ngetprop @3 'length' @6\nassign @6 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles spread arguments in calls', () => {\n    const result = compileSimplified(\n      `\n      declare function join(...strs: string[]): string;\n\n      const items = ['Hello', 'World'];\n      const result = join(...items);\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewarray @7\nstoreint 0 @8\ngetmoduleconst 0 @9\nsetpropv @7 @8 @9\ninc @8 @10\ngetmoduleconst 1 @11\nsetpropv @7 @10 @11\ninc @10 @12\nassign @7 @5\ngetglobal @13\ngetprop @13 'join' @14\nnewarray @15\nstoreint 0 @16\ncopyprops @5 @15\nadd @16 @18 @19\ncallv @14 @14 @15 @20\nassign @20 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles spread arguments in new expression', () => {\n    const result = compileSimplified(\n      `\n      declare class Components {\n        constructor(initial: string, ...rest: string[]);\n      }\n\n      const components = new Components('Prefix', ...['Hello', 'World']);\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetglobal @6\ngetprop @6 'Components' @7\nnewarray @8\nstoreint 0 @9\ngetmoduleconst 0 @10\nsetpropv @8 @9 @10\ninc @9 @11\nnewarray @12\nstoreint 0 @13\ngetmoduleconst 1 @14\nsetpropv @12 @13 @14\ninc @13 @15\ngetmoduleconst 2 @16\nsetpropv @12 @15 @16\ninc @15 @17\ncopyprops @12 @8\nadd @11 @18 @19\nnewv @7 @8 @20\nassign @20 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles spread arguments in function', () => {\n    const result = compileSimplified(\n      `\n      declare class Components {\n        constructor(initial: string, ...rest: string[]);\n      }\n\n      function join(separator: string, ...rest: string[]): string {\n        return rest.join(separator);\n      }\n    `,\n      ['file_ts_join'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_join'\ngetfnarguments 1 @6\nassign @6 @4\ngetprop @4 'join' @8\ncall @8 @4 [ @5 ] @10\nassign @10 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('respects scope in variables', () => {\n    const result = compileSimplified(\n      `\n      {\n        const value = 42;\n      }\n      {\n        const value = 43;\n      }\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 42 @6\nassign @6 @5\nstoreint 43 @8\nassign @8 @7\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles delete expression', () => {\n    const result = compileSimplified(\n      `\n      const obj: any = {title: {name: 'Hello'}};\n      delete obj.title.name;\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @6\nnewobject @7\ngetmoduleconst 0 @8\nsetprop @7 'name' @8\nsetprop @6 'title' @7\nassign @6 @5\ngetprop @5 'title' @10\ndelprop @10 'name' @11\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles function with default parameter value', () => {\n    const result = compileSimplified(\n      `\n      function mutate(animated: boolean = false): boolean {\n        return animated;\n      }\n    `,\n      ['file_ts_mutate'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_mutate'\njumptarget 'condition'\nnestrict @4 @6 @7\nbranch @7 'condition_true' 'condition_false'\njumptarget 'condition_true'\nassign @4 @5\njump 'exit'\njumptarget 'condition_false'\nstorebool false @8\nassign @8 @5\njump 'exit'\njumptarget 'exit'\nassign @5 @3\nassign @3 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles export declaration', () => {\n    const result = configuredCompile(\n      `\n      const VALUE = 42;\n      export { VALUE };\n    `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      false,\n      undefined,\n      undefined,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetfnarg 2 @3\nstoreint 42 @6\nassign @6 @5\nsetprop @3 'VALUE' @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles export declaration binding', () => {\n    const result = configuredCompile(\n      `\n      export { VALUE } from './other';\n    `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      false,\n      undefined,\n      (workspace) => {\n        workspace.registerInMemoryFile(\n          'other.ts',\n          `\n        export const VALUE = 42;\n        `,\n        );\n      },\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetfnarg 0 @5\ngetfnarg 2 @3\ngetmoduleconst 0 @8\ncall @5 @9 [ @8 ] @10\ngetprop @10 'VALUE' @11\nsetprop @3 'VALUE' @11\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles import module expression within lambda', () => {\n    const result = configuredCompile(\n      `\n      const getValue = () => import('./other');\n    `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      false,\n      undefined,\n      (workspace) => {\n        workspace.registerInMemoryFile(\n          'other.ts',\n          `\n        export const VALUE = 42;\n        `,\n        );\n      },\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'require' @7\ngetfnarg 0 @6\nsetvref @6 @7\ngetfnarg 2 @3\nnewarrowfn 'file_ts_getValue_anon' [ @7 ] @8\nassign @8 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_getValue_anon'\ngetclosurearg 0 @3\nloadvref @3 @4\ngetmoduleconst 0 @5\ncall @4 @6 [ @5 ] @7\ngetglobal @8\ngetprop @8 'Promise' @9\ngetprop @9 'resolve' @10\ncall @10 @9 [ @7 ] @11\nassign @11 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles optional element access expression', () => {\n    const result = compileSimplified(\n      `\n      declare const global: any;\n      const value = global.errorHandlersByContextId?.[42];\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\njumptarget 'optional_chain'\ngetglobal @7\ngetprop @7 'global' @8\ngetprop @8 'errorHandlersByContextId' @9\njumptarget 'value_condition'\nnullable_branch @9 'value_true' 'value_false'\njumptarget 'value_true'\nstoreint 42 @11\ngetpropvalue @9 @11 @12\nassign @12 @10\njump 'value_exit'\njumptarget 'value_false'\nassign @13 @10\njump 'value_exit'\njumptarget 'value_exit'\njumptarget 'optional_chain_exit'\nassign @10 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles optional property access expression within if', () => {\n    const result = compileSimplified(\n      `\n      let component: any = {};\n      if (component?.onError) {\n        component.onError();\n      } else {\n        component = {};\n      }\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @6\nassign @6 @5\njumptarget 'condition'\njumptarget 'optional_chain'\njumptarget 'value_condition'\nnullable_branch @5 'value_true' 'value_false'\njumptarget 'value_true'\ngetprop @5 'onError' @10\nassign @10 @9\njump 'value_exit'\njumptarget 'value_false'\nassign @11 @9\njump 'value_exit'\njumptarget 'value_exit'\nassign @9 @7\njumptarget 'optional_chain_exit'\nbranch @7 'true' 'false'\njumptarget 'true'\ngetprop @5 'onError' @13\ncall @13 @5 [ ] @14\njump 'exit'\njumptarget 'false'\nnewobject @15\nassign @15 @5\njumptarget 'exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles optional property access expression within call expression', () => {\n    const result = compileSimplified(\n      `\n      let component: any = {};\n      component.ref?.onError();\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @6\nassign @6 @5\njumptarget 'optional_chain'\ngetprop @5 'ref' @9\njumptarget 'value_condition'\nnullable_branch @9 'value_true' 'value_false'\njumptarget 'value_true'\ngetprop @9 'onError' @11\ncall @11 @9 [ ] @12\nassign @12 @10\njump 'value_exit'\njumptarget 'value_false'\nassign @13 @10\njump 'value_exit'\njumptarget 'value_exit'\nassign @10 @7\njumptarget 'optional_chain_exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('compiles default export', () => {\n    const result = compileSimplified(\n      `\n      const TEST = 42;\n      export default TEST;\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 42 @6\nassign @6 @5\nsetprop @3 'default' @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles default export on function', () => {\n    const result = compileSimplified(\n      `\n      export default function myFn() {};\n    `,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewfn 'file_ts_myFn' 'myFn' [ ] @6\nassign @6 @5\nsetprop @3 'default' @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles default export as assignment', () => {\n    const result = compileSimplified(\n      `\n      const TEST = 42;\n      export = TEST;\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 42 @6\nassign @6 @5\nsetprop @8 'exports' @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('compiles import equal statement', () => {\n    const result = compileSimplified(\n      `\n        declare namespace Outer {\n          export namespace Nested {\n            export const VALUE: number;\n          }\n        }\n\n        import VALUE = Outer.Nested.VALUE;\n        const result = VALUE * 2;\n        `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetglobal @7\ngetprop @7 'Outer' @8\ngetprop @8 'Nested' @9\ngetprop @9 'VALUE' @10\nassign @10 @5\nstoreint 2 @11\nmult @5 @11 @13\nassign @13 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles default import statement', () => {\n    const result = configuredCompile(\n      `\n      import resources from './res';\n\n      resources.value = 42;\n    `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n      (workspace) => {\n        workspace.registerInMemoryFile(\n          'res.ts',\n          `\n          const obj = {\n            value: 0\n          };\n          export default obj;\n        `,\n        );\n      },\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetmoduleconst 0 @10\ncall @7 @11 [ @10 ] @12\nassign @12 @6\nstoreint 42 @5\ngetprop @6 'default' @14\nsetprop @14 'value' @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('does not emit import for type import', () => {\n    const result = configuredCompile(\n      `\n      import { Number } from './Number';\n\n      const nb: Number = 42;\n    `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n      (workspace) => {\n        workspace.registerInMemoryFile(\n          'Number.ts',\n          `\n          export type Number = number;\n        `,\n        );\n      },\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 42 @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('does not emit export for type export', () => {\n    const result = configuredCompile(\n      `\n      export { Number } from './Number';\n    `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n      (workspace) => {\n        workspace.registerInMemoryFile(\n          'Number.ts',\n          `\n          export type Number = number;\n        `,\n        );\n      },\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('can use imported symbols in functions', () => {\n    const result = configuredCompile(\n      `\n      import { VALUE } from './Config';\n\n      function resolve(): () => number {\n        return () => VALUE;\n      }\n    `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n      (workspace) => {\n        workspace.registerInMemoryFile(\n          'Config.ts',\n          `\n          export const VALUE = 42;\n        `,\n        );\n      },\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref '$imported_module' @6\ngetmoduleconst 0 @10\ncall @7 @11 [ @10 ] @12\nsetvref @12 @6\nnewfn 'file_ts_resolve' 'resolve' [ @6 ] @13\nassign @13 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_resolve'\ngetclosurearg 0 @3\nnewarrowfn 'file_ts_resolve_anon' [ @3 ] @4\nassign @4 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_resolve_anon'\ngetclosurearg 0 @3\nloadvref @3 @4\ngetprop @4 'VALUE' @5\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('compiles in operator', () => {\n    const result = compileSimplified(\n      `\n      const obj: any = {};\n      const result = 'hello' in obj;\n    `,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @7\nassign @7 @5\ngetmoduleconst 0 @9\nin @9 @5 @10\nassign @10 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('respects var scoping rules', () => {\n    const result = compileSimplified(\n      `\n      function count(items: number[]): number {\n        for (var i = 0; i < items.length; i++) {}\n\n        return i;\n      }\n        `,\n      ['file_ts_count'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_count'\nstoreint 0 @6\nassign @6 @5\njumptarget 'cond'\ngetprop @4 'length' @8\nlt @5 @8 @10\nbranch @10 'body' 'exit'\njumptarget 'body'\nassign @5 @12\ninc @5 @13\nassign @13 @5\njump 'cond'\njumptarget 'exit'\nassign @5 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('allows var reassignment', () => {\n    const result = compileSimplified(\n      `\n      var p = 42;\n      var p: number;\n        `,\n    );\n\n    // TODO(simon): This is not compliant to the spec, the 'var' shouldn't technically\n    // be re-assigned to undefined in this case.\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 42 @6\nassign @6 @5\nassign @7 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('respects initialization order', () => {\n    /**\n     * Order should be:\n     * - Var refs are initialized\n     * - Functions are initialized\n     * - Rest of the code is evaluated\n     */\n    const result = configuredCompile(\n      `\n        const myConst = 42;\n        var myVar = 41;\n\n        class MyClass {\n\n        }\n\n        function MyFunction() {\n          MyClass.toString();\n        }\n    `,\n      { optimizeSlots: false, optimizeVarRefs: false },\n      false,\n      false,\n      false,\n      false,\n      ['file_ts__module_init__'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'exports' @4\nnewvref 'myVar' @6\nsetvref @3 @4\nnewvref 'myConst' @5\nnewvref 'MyClass' @7\nnewvref 'MyFunction' @8\nnewfn 'file_ts_MyFunction' 'MyFunction' [ @7 ] @9\nsetvref @9 @8\nstoreint 42 @10\nsetvref @10 @5\nstoreint 41 @11\nsetvref @11 @6\nnewclass 'file_ts_MyClass' 'MyClass' @12 [ ] @13\nsetvref @13 @7\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('allows function args to override closures', () => {\n    const result = configuredCompile(\n      `\n      let myObject = {};\n      function myFn(myObject: any) {\n        myObject.value = 42;\n      }\n\n    `,\n      { optimizeSlots: true, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      false,\n      ['file_ts_myFn'],\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts_myFn'\ngetfnarg 0 @2\nstoreint 42 @3\nsetprop @2 'value' @3\njump 'return'\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('replaces const enum values by their constants', () => {\n    const result = configuredCompile(\n      `\n      import { Enum } from './Enum';\n\n      const value = Enum.VALUE;\n    `,\n      { optimizeSlots: false, optimizeVarRefs: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n      (workspace) => {\n        workspace.registerInMemoryFile(\n          'Enum.d.ts',\n          `\n          export const enum Enum {\n            VALUE = 42,\n          };\n        `,\n        );\n      },\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 42 @6\nassign @6 @5\njump 'return'\njumptarget 'return'\nfunction_end @1\n        `.trim(),\n    );\n  });\n\n  it('supports try finally', () => {\n    const result = configuredCompile(\n      `\n      const obj: any = {};\n      try {\n        obj.inTry = true;\n      } finally {\n        obj.inFinally = true;\n      }\n      obj.inOuter = true;\n    `,\n      { optimizeSlots: true, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      true,\n      undefined,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetfnarg 2 @2\nnewobject @2\nassign @2 @3\njumptarget 'try'\nstorebool true @4\nsetprop @3 'inTry' @4\njump 'finally'\njumptarget 'finally'\nstorebool true @4\nsetprop @3 'inFinally' @4\ncheckexception 'exception'\nstorebool true @4\nsetprop @3 'inOuter' @4\njump 'return'\njumptarget 'exception'\nstoreexception @2\nassign @2 @1\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('supports try catch', () => {\n    const result = configuredCompile(\n      `\n      const obj: any = {};\n      try {\n        obj.inTry = true;\n      } catch {\n        obj.inCatch = true;\n      }\n      obj.inOuter = true;\n    `,\n      { optimizeSlots: true, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      true,\n      undefined,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetfnarg 2 @2\nnewobject @2\nassign @2 @3\njumptarget 'try'\nstorebool true @4\nsetprop @3 'inTry' @4\njump 'finally'\njumptarget 'catch'\ngetexception @2\nstorebool true @4\nsetprop @3 'inCatch' @4\njump 'finally'\njumptarget 'finally'\nstorebool true @4\nsetprop @3 'inOuter' @4\njump 'return'\njumptarget 'exception'\nstoreexception @2\nassign @2 @1\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('supports try catch finally', () => {\n    const result = configuredCompile(\n      `\n      const obj: any = {};\n      try {\n        obj.inTry = true;\n      } catch {\n        obj.inCatch = true;\n      } finally {\n        obj.inFinally = true;\n      }\n      obj.inOuter = true;\n    `,\n      { optimizeSlots: true, optimizeVarRefs: true },\n      true,\n      false,\n      false,\n      true,\n      undefined,\n    );\n\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetfnarg 2 @2\nnewobject @2\nassign @2 @3\njumptarget 'try'\nstorebool true @4\nsetprop @3 'inTry' @4\njump 'finally'\njumptarget 'catch'\ngetexception @2\nstorebool true @4\nsetprop @3 'inCatch' @4\njump 'finally'\njumptarget 'finally'\nstorebool true @4\nsetprop @3 'inFinally' @4\ncheckexception 'exception'\nstorebool true @4\nsetprop @3 'inOuter' @4\njump 'return'\njumptarget 'exception'\nstoreexception @2\nassign @2 @1\njumptarget 'return'\nfunction_end @1\n          `.trim(),\n    );\n  });\n\n  it('optimize null checks', () => {\n    const c_code = compileAsC(\n      `\n      function foo(v: any): boolean {\n        return v == undefined;\n      }\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true, optimizeNullChecks: true },\n      'foo',\n      undefined,\n    );\n    expect(c_code.includes('tsn_is_undefined_or_null')).toBeTruthy();\n    expect(c_code.includes('tsn_op_eq')).toBeFalsy();\n  });\n\n  it('optimize boolean conditions', () => {\n    const c_code = compileAsC(\n      `\n      function foo(x: number, y: number): number {\n        if (x < y) {\n          return y - x;\n        } else {\n          return x - y;\n        }\n      }\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true },\n      'foo',\n      undefined,\n    );\n    expect(c_code.includes('tsn_truthy_bool')).toBeTruthy();\n    expect(c_code.includes('tsn_to_bool')).toBeFalsy();\n  });\n\n  it('batch set properties', () => {\n    const result = configuredCompile(\n      `\n      const o = {x: 1, y: 2, z: 3};\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true, mergeSetProperties: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewobject @2\nstoreint 1 @3\nstoreint 2 @4\nstoreint 3 @5\nsetprops @2 [ 'x', 'y', 'z' ] [ @3, @4, @5 ]\nassign @2 @6\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('optimize var ref loading', () => {\n    const result = configuredCompile(\n      `\n      const o = 1;\n      const x = o + o;\n      `,\n      { optimizeSlots: true, optimizeVarRefs: false, optimizeVarRefLoads: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'exports' @2\nsetvref @3 @2\nnewvref 'o' @2\nnewvref 'x' @4\nstoreint 1 @5\nsetvref @5 @2\nadd @5 @5 @6\nsetvref @6 @4\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n  it('optimize var ref loading alias invalidating', () => {\n    const result = configuredCompile(\n      `\n      const o = 1;\n      let x = o + 1;\n      if (1 < 2) {\n        x = o + 2;\n      }\n      `,\n      { optimizeSlots: true, optimizeVarRefs: false, optimizeVarRefLoads: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'exports' @2\nsetvref @3 @2\nnewvref 'o' @2\nnewvref 'x' @4\nstoreint 1 @5\nsetvref @5 @2\nstoreint 1 @6\nadd @5 @6 @7\nsetvref @7 @4\njumptarget 'condition'\nstoreint 2 @5\nstoreint 1 @6\nlt @6 @5 @8\nbranch @8 'true' 'false'\njumptarget 'true'\nstoreint 2 @7\nloadvref @2 @5\nadd @5 @7 @6\nsetvref @6 @4\njump 'exit'\njumptarget 'false'\njumptarget 'exit'\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('optimize assignments', () => {\n    const result = configuredCompile(\n      `\n      const o1 = 1;\n      const o2 = o1;\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true, optimizeAssignments: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoreint 1 @3\nassign @3 @4\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('self-ref retainable assignments', () => {\n    const result = configuredCompile(\n      `\n      let a = 'hello';\n      let b = 'world';\n      b += a;\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true, optimizeAssignments: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\ngetmoduleconst 0 @2\nassign @2 @3\ngetmoduleconst 1 @2\nassign @2 @4\nadd @4 @3 @2\nassign @2 @4\njump 'return'\njumptarget 'return'\nfunction_end @1`.trim(),\n    );\n  });\n\n  it('constant folding', () => {\n    const result = configuredCompile(\n      `\n      const PI = 3.14;\n      const TwoPISquare = 2 * PI * PI;\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true, foldConstants: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nstoredouble 3.14 @3\nassign @3 @4\nstoredouble 19.7192 @3\nassign @3 @4\njump 'return'\njumptarget 'return'\nfunction_end @1\n      `.trim(),\n    );\n  });\n\n  it('constant folding in closure', () => {\n    const result = configuredCompile(\n      `\n      const PI = 3.14;\n      function foo() {\n        const TwoPISquare = 2 * PI * PI;\n      }\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true, foldConstants: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewvref 'PI' @3\nnewfn 'file_ts_foo' 'foo' [ @3 ] @2\nassign @2 @4\nstoredouble 3.14 @5\nsetvref @5 @3\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_foo'\nstoredouble 19.7192 @2\nassign @2 @3\njump 'return'\njumptarget 'return'\nfunction_end @1 \n      `.trim(),\n    );\n  });\n\n  it('generator', () => {\n    const result = configuredCompile(\n      `\n      function* foo() {\n      let a = 42;\n      {\n        let a = 12\n        yield a;\n      }\n      return a;\n      }\n      `,\n      { optimizeSlots: true, optimizeVarRefs: true, foldConstants: true },\n      false,\n      false,\n      false,\n      false,\n      undefined,\n    );\n    expect(result).toEqual(\n      `\nfunction_begin 'file_ts__module_init__'\nnewfn 'file_ts_foo' 'foo' [ ] @2\nassign @2 @3\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_foo'\nnewarrowfn 'file_ts_foo_anon' [ ] @2\ngenerator @2 @3\nassign @3 @1\njump 'return'\njump 'return'\njumptarget 'return'\nfunction_end @1\n\nfunction_begin 'file_ts_foo_anon'\nreentry 'resume_point'\nstoreint 42 @2\nassign @2 @3\nstoreint 12 @2\nassign @2 @4\nsetresumepoint 'resume_point'\nassign @4 @1\njump 'yield'\njumptarget 'resume_point'\nresume @5\nassign @3 @1\njump 'return'\njump 'return'\njumptarget 'return'\nsetresumepoint 'end_of_func'\njumptarget 'yield'\nfunction_end @1\n      `.trim(),\n    );\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/native/NativeCompiler.ts",
    "content": "import * as ts from 'typescript';\nimport * as NativeHelper from './NativeHelper';\nimport { NativeCompilerModuleBuilder } from './builder/NativeCompilerBuilder';\nimport {\n  INativeCompilerBlockBuilder,\n  INativeCompilerJumpTargetBuilder,\n  IVariableDelegate,\n  NativeCompilerBuilderAtomID,\n  NativeCompilerBuilderBranchType,\n  NativeCompilerBuilderJumpTargetID,\n  NativeCompilerBuilderVariableID,\n  NativeCompilerBuilderVariableRef,\n  NativeCompilerBuilderVariableType,\n  VariableRefScope,\n} from './builder/INativeCompilerBuilder';\nimport { CompilerNativeCEmitter } from './emitter/CompilerNativeCEmitter';\nimport { emitterWalk, NativeCompilerEmitterOutput } from './emitter/INativeCompilerEmitter';\nimport { NativeCompilerIR } from './builder/NativeCompilerBuilderIR';\nimport { NamePath } from './utils/NamePath';\nimport { AssignmentTracker } from './utils/AssignmentTracker';\nimport { NativeCompilerOptions } from './NativeCompilerOptions';\nimport { Lazy } from '../utils/Lazy';\nimport { isSuperCall, statementHasSuperCall, getSuperCallFromStatement } from '../TSUtils';\nimport { NameAllocator } from './utils/NameAllocator';\nimport { EmitResolver, getEmitResolver } from '../utils/EmitResolver';\n\ninterface NativeCompilerVariableIDWithParent {\n  variable: NativeCompilerBuilderVariableID;\n  parentVariable: NativeCompilerBuilderVariableID | undefined;\n}\n\ninterface NativeCompilerVariableIDValueDelegate {\n  getValue: () => NativeCompilerVariableIDWithParent;\n  setValue: (value: NativeCompilerBuilderVariableID) => void;\n}\n\ninterface BindingElementVariable {\n  propertyName: NativeCompilerBuilderAtomID | undefined;\n  variableRef: NativeCompilerBuilderVariableRef;\n  resolveValue?: (input: NativeCompilerBuilderVariableID) => NativeCompilerBuilderVariableID;\n  isRest: boolean;\n}\n\ninterface AssignmentElementVariable {\n  variable: NativeCompilerBuilderVariableID;\n  defaultValue?: (input: NativeCompilerBuilderVariableID) => NativeCompilerBuilderVariableID;\n  isRest: boolean;\n}\n\ninterface CompilationPlan {\n  functionDeclarationInsertionIndex: number;\n  readonly statementsToProcess: ts.Statement[];\n}\n\nfunction makeValidModuleName(name: string) {\n  if (name.match(/^[^a-z_]/gi) !== null) {\n    name += '_' + name;\n  }\n  return name.replace(/[^a-z0-9_]/gi, '_');\n}\n\nconst CONSTRUCTOR_NAME = '__ctor__';\n\nclass NativeCompilerContext {\n  constructor(\n    readonly namePath: NamePath,\n    readonly assignmentTracker: AssignmentTracker | undefined,\n    readonly emitResolver: EmitResolver | undefined,\n    readonly isGenerator: boolean,\n    readonly isAsync: boolean,\n  ) {}\n\n  optionalChainExit?: NativeCompilerBuilderJumpTargetID = undefined;\n  optionalChainResult?: NativeCompilerBuilderVariableID = undefined;\n\n  withNamePath(namePath: NamePath, isGenerator?: boolean, isAsync?: boolean): NativeCompilerContext {\n    if (isGenerator === undefined) {\n      isGenerator = this.isGenerator;\n    }\n    if (isAsync === undefined) {\n      isAsync = this.isAsync;\n    }\n    if (namePath === this.namePath && isGenerator === this.isGenerator && isAsync === this.isAsync) {\n      return this;\n    }\n    return new NativeCompilerContext(namePath, this.assignmentTracker, this.emitResolver, isGenerator, isAsync);\n  }\n\n  withAssignmentTracker(assignmentTracker: AssignmentTracker | undefined): NativeCompilerContext {\n    if (assignmentTracker === this.assignmentTracker) {\n      return this;\n    }\n\n    return new NativeCompilerContext(\n      this.namePath,\n      assignmentTracker,\n      this.emitResolver,\n      this.isGenerator,\n      this.isAsync,\n    );\n  }\n}\n\nconst MAX_DEBUG_INFO_LENGTH = 50;\n\ntype DeferredStatementCb = (context: NativeCompilerContext, builder: INativeCompilerBlockBuilder) => void;\ntype EnqueueDeferredStatementFunc = (cb: DeferredStatementCb) => void;\n\nexport class NativeCompiler {\n  private moduleName: string;\n  private moduleBuilder: NativeCompilerModuleBuilder;\n  private allocatedFunctionNames = new NameAllocator();\n  private allocatedVariableRefNames = new NameAllocator();\n  private moduleVariableNameByPosition: { [key: number]: string } = {};\n  private loadedModules = new Set<string>();\n  private lastProcessingDeclaration: ts.Node | undefined = undefined;\n\n  constructor(\n    readonly sourceFile: ts.SourceFile,\n    readonly filePath: string,\n    readonly modulePath: string,\n    readonly typeChecker: ts.TypeChecker,\n    readonly options: NativeCompilerOptions,\n  ) {\n    this.moduleName = makeValidModuleName(modulePath);\n    this.moduleBuilder = new NativeCompilerModuleBuilder(this.moduleName, modulePath);\n  }\n\n  private allocateFunctionName(nameInitial: string): string {\n    return this.allocatedFunctionNames.allocate(nameInitial);\n  }\n\n  private getFunctionName(namePath: NamePath): string {\n    return this.allocateFunctionName(namePath.toString());\n  }\n\n  private allocateUniqueVariableRefName(name: string): string {\n    return this.allocatedVariableRefNames.allocate(name);\n  }\n\n  private onError(node: ts.Node, message: string): never {\n    NativeHelper.onError(this.filePath, this.sourceFile, node, message);\n  }\n\n  private processBindingElement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.BindingElement,\n    includePropertyName: boolean,\n  ): BindingElementVariable {\n    if (ts.isIdentifier(node.name)) {\n      const isRest = !!node.dotDotDotToken;\n      const variableName = node.name;\n      let propertyName: NativeCompilerBuilderAtomID | undefined;\n      if (includePropertyName) {\n        if (node.propertyName) {\n          const resolvedPropertyName = this.processPropertyName(context, builder, node.propertyName);\n          if (!(resolvedPropertyName instanceof NativeCompilerBuilderAtomID)) {\n            this.onError(node, 'alias in binding element can only be identifiers');\n          }\n          propertyName = resolvedPropertyName;\n        } else {\n          propertyName = this.processIdentifierAsAtom(builder, variableName);\n        }\n      }\n\n      let resolveValue: ((input: NativeCompilerBuilderVariableID) => NativeCompilerBuilderVariableID) | undefined;\n\n      if (node.initializer) {\n        const initializer = node.initializer;\n        resolveValue = (input: NativeCompilerBuilderVariableID) => {\n          return this.processDeclarationWithDefaultInitializer(context, builder, initializer, input);\n        };\n      }\n\n      const variableRef = this.resolveRegisteredVariableRefForIdentifier(context, builder, variableName);\n\n      return { propertyName, variableRef, resolveValue, isRest };\n    } else {\n      this.onError(node.name, 'Unsupported destructuring binding');\n    }\n  }\n\n  private processBindingName(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    name: ts.BindingName,\n    declaration: ts.Declaration | undefined,\n    buildInitialValue: (context: NativeCompilerContext) => NativeCompilerBuilderVariableID,\n  ): void {\n    if (ts.isIdentifier(name)) {\n      const variableName = name.text;\n      const newNamePath = context.namePath.appending(variableName);\n\n      const variableRef = this.resolveRegisteredVariableRefForIdentifier(context, builder, name);\n\n      const initializerVariable = buildInitialValue(context.withNamePath(newNamePath));\n      if (initializerVariable) {\n        builder.buildSetVariableRef(variableRef, initializerVariable);\n      }\n      if (declaration) {\n        this.appendExportedDeclarationIfNeeded(context, builder, declaration, name, initializerVariable);\n      }\n    } else if (ts.isObjectBindingPattern(name)) {\n      const objectBindingPattern: ts.ObjectBindingPattern = name;\n      const bindingElements: BindingElementVariable[] = [];\n\n      const initializerVariable = buildInitialValue(context.withNamePath(context.namePath.appending('__destruct__')));\n\n      for (const element of objectBindingPattern.elements) {\n        if (ts.isIdentifier(element.name)) {\n          bindingElements.push(this.processBindingElement(context, builder, element, true));\n        } else if (element.propertyName && ts.isIdentifier(element.propertyName)) {\n          this.processBindingName(context, builder, element.name, undefined, (ctx) => {\n            return builder.buildGetProperty(\n              initializerVariable,\n              this.processIdentifierAsAtom(builder, element.propertyName! as ts.Identifier),\n              initializerVariable,\n            );\n          });\n        }\n      }\n\n      for (const bindingElement of bindingElements) {\n        let propertyValue: NativeCompilerBuilderVariableID;\n        if (bindingElement.isRest) {\n          // Gather referenced properties that shouldn't be included\n          const propertiesToIgnore: NativeCompilerBuilderAtomID[] = [];\n          for (const otherBindingElement of bindingElements) {\n            if (otherBindingElement === bindingElement) {\n              break;\n            }\n            propertiesToIgnore.push(otherBindingElement.propertyName!);\n          }\n\n          propertyValue = builder.buildNewObject();\n          builder.buildCopyPropertiesFrom(propertyValue, initializerVariable, propertiesToIgnore);\n        } else {\n          propertyValue = builder.buildGetProperty(\n            initializerVariable,\n            bindingElement.propertyName!,\n            initializerVariable,\n          );\n        }\n\n        if (bindingElement.resolveValue) {\n          builder.buildSetVariableRef(bindingElement.variableRef, bindingElement.resolveValue(propertyValue));\n        } else {\n          builder.buildSetVariableRef(bindingElement.variableRef, propertyValue);\n        }\n      }\n    } else if (ts.isArrayBindingPattern(name)) {\n      const arrayBindingPattern: ts.ArrayBindingPattern = name;\n      const allVariableRefs: [number, BindingElementVariable][] = [];\n\n      const initializerVariable = buildInitialValue(context.withNamePath(context.namePath.appending('__destruct__')));\n\n      let elementIndex = 0;\n      for (const element of arrayBindingPattern.elements) {\n        const currentElementIndex = elementIndex++;\n\n        if (ts.isOmittedExpression(element)) {\n          continue;\n        }\n\n        if (ts.isArrayBindingPattern(element.name) || ts.isObjectBindingPattern(element.name)) {\n          const isRest = !!element.dotDotDotToken;\n          if (isRest) {\n            this.processBindingName(context, builder, element.name, undefined, (ctx) => {\n              const sliceMethod = builder.buildGetProperty(\n                initializerVariable,\n                this.processIdentifierStringAsAtom(builder, 'slice'),\n                initializerVariable,\n              );\n              return builder.buildFunctionInvocation(\n                sliceMethod,\n                [builder.buildLiteralInteger(currentElementIndex.toString())],\n                initializerVariable,\n              );\n            });\n          } else {\n            this.processBindingName(context, builder, element.name, undefined, (ctx) => {\n              return builder.buildGetPropertyValue(\n                initializerVariable,\n                builder.buildLiteralInteger(currentElementIndex.toString()),\n                initializerVariable,\n              );\n            });\n          }\n        } else {\n          const variableRef = this.processBindingElement(context, builder, element, false);\n          allVariableRefs.push([currentElementIndex, variableRef]);\n        }\n      }\n\n      for (const [elementIndex, bindingElement] of allVariableRefs) {\n        let propertyValue: NativeCompilerBuilderVariableID;\n\n        if (bindingElement.isRest) {\n          // Call object.slice(elementIndex)\n          const sliceMethod = builder.buildGetProperty(\n            initializerVariable,\n            this.processIdentifierStringAsAtom(builder, 'slice'),\n            initializerVariable,\n          );\n\n          propertyValue = builder.buildFunctionInvocation(\n            sliceMethod,\n            [builder.buildLiteralInteger(elementIndex.toString())],\n            initializerVariable,\n          );\n        } else {\n          propertyValue = builder.buildGetPropertyValue(\n            initializerVariable,\n            builder.buildLiteralInteger(elementIndex.toString()),\n            initializerVariable,\n          );\n        }\n\n        if (bindingElement.resolveValue) {\n          builder.buildSetVariableRef(bindingElement.variableRef, bindingElement.resolveValue(propertyValue));\n        } else {\n          builder.buildSetVariableRef(bindingElement.variableRef, propertyValue);\n        }\n      }\n    } else {\n      this.onError(name, 'Unsupported variable declaration type');\n    }\n  }\n\n  private processVariableDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.VariableDeclaration,\n    buildInitialValue: (context: NativeCompilerContext) => NativeCompilerBuilderVariableID,\n  ): void {\n    this.appendNodeDebugInfo(builder, node);\n\n    this.processBindingName(context, builder, node.name, node, buildInitialValue);\n  }\n\n  private registerAndGetStringLiteralValue(\n    builder: INativeCompilerBlockBuilder,\n    text: string,\n  ): NativeCompilerBuilderVariableID {\n    const constantIndex = this.moduleBuilder.registerStringConstant(text);\n    return builder.buildGetModuleConst(constantIndex);\n  }\n\n  private processStringLiteral(\n    builder: INativeCompilerBlockBuilder,\n    node: ts.StringLiteral,\n  ): NativeCompilerBuilderVariableID {\n    return this.registerAndGetStringLiteralValue(builder, node.text);\n  }\n\n  private processNumericalLiteral(\n    builder: INativeCompilerBlockBuilder,\n    node: ts.NumericLiteral,\n  ): NativeCompilerBuilderVariableID {\n    const numString = node.text;\n    const numericalStringType = NativeHelper.getNumericalStringType(numString);\n\n    switch (numericalStringType) {\n      case NativeHelper.NumberType.Integer:\n        return builder.buildLiteralInteger(numString);\n      case NativeHelper.NumberType.Long:\n        return builder.buildLiteralLong(numString);\n      case NativeHelper.NumberType.Float:\n        return builder.buildLiteralDouble(numString);\n    }\n  }\n\n  private processPropertyAccessExpressionForCallExpressionEpilogue(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    expressionVariable: NativeCompilerBuilderVariableID,\n    nameVariable: NativeCompilerBuilderAtomID,\n    variableToUseAsThis: NativeCompilerBuilderVariableID,\n    buildCall: (\n      context: NativeCompilerContext,\n      builder: INativeCompilerBlockBuilder,\n      callee: NativeCompilerVariableIDWithParent,\n    ) => NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    const resolvedVariable = builder.buildGetProperty(expressionVariable, nameVariable, variableToUseAsThis);\n    const callee: NativeCompilerVariableIDWithParent = {\n      variable: resolvedVariable,\n      parentVariable: variableToUseAsThis,\n    };\n    return buildCall(context, builder, callee);\n  }\n\n  processPropertyAccessExpressionForCallExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PropertyAccessExpression,\n    buildCall: (\n      context: NativeCompilerContext,\n      builder: INativeCompilerBlockBuilder,\n      callee: NativeCompilerVariableIDWithParent,\n    ) => NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    return this.doProcessPropertyAccessExpression(\n      context,\n      builder,\n      node,\n      (context, builder, expressionVariable, nameVariable) => {\n        const variableToUseAsThis = this.resolveVariableToUseAsThis(context, builder, expressionVariable, node);\n        return this.processPropertyAccessExpressionForCallExpressionEpilogue(\n          context,\n          builder,\n          expressionVariable,\n          nameVariable,\n          variableToUseAsThis,\n          buildCall,\n        );\n      },\n    );\n  }\n\n  private resolveVariableToUseAsThis(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    variableID: NativeCompilerBuilderVariableID,\n    node: ts.Node,\n  ): NativeCompilerBuilderVariableID {\n    if ((variableID.type & NativeCompilerBuilderVariableType.Super) != 0) {\n      // The variable is a 'super' reference. The \"thisObject\" needs to be\n      // the \"this\"\n      return this.processThis(context, builder, node);\n    }\n    return variableID;\n  }\n\n  processPropertyAccessExpressionAsAssignment(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    propertyName: ts.PropertyName,\n    expression: ts.Expression,\n    variableID: NativeCompilerBuilderVariableID,\n  ) {\n    const nameVariable = this.processPropertyName(context, builder, propertyName);\n\n    const newNamePath = context.namePath.appendingTSNode(propertyName);\n\n    const expressionVariable = this.processExpression(context.withNamePath(newNamePath), builder, expression);\n\n    this.doBuildSetProperty(context, builder, nameVariable, expressionVariable, variableID);\n  }\n\n  processElementAccessExpressionAsAssignment(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ElementAccessExpression,\n    variableID: NativeCompilerBuilderVariableID,\n  ) {\n    const expressionVariable = this.processExpression(context, builder, node.expression);\n\n    if (ts.isNumericLiteral(node.argumentExpression)) {\n      const index = Number.parseInt(node.argumentExpression.text);\n      builder.buildSetPropertyIndex(expressionVariable, index, variableID);\n    } else {\n      const nameVariable = this.processExpression(context, builder, node.argumentExpression);\n\n      builder.buildSetPropertyValue(expressionVariable, nameVariable, variableID);\n    }\n  }\n\n  private buildQuestionDotExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    expressionVariable: NativeCompilerBuilderVariableID,\n    onTrue: (context: NativeCompilerContext, builder: INativeCompilerBlockBuilder) => NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    const cond = builder.buildJumpTarget('value_condition');\n    const condTrue = builder.buildJumpTarget('value_true');\n    const condFalse = builder.buildJumpTarget('value_false');\n    const condExit = builder.buildJumpTarget('value_exit');\n\n    // use whole expression result and exit target if this is part of an optional chain\n    const result: NativeCompilerBuilderVariableID = context.optionalChainResult ?? builder.buildAssignableUndefined();\n    const exitTarget = context.optionalChainExit ?? condExit.target;\n\n    const trueValue = onTrue(context, condTrue.builder);\n    condTrue.builder.buildAssignment(result, trueValue);\n    condTrue.builder.buildJump(condExit.target);\n\n    condFalse.builder.buildAssignment(result, condFalse.builder.buildUndefined());\n    condFalse.builder.buildJump(exitTarget);\n\n    cond.builder.buildBranch(\n      expressionVariable,\n      NativeCompilerBuilderBranchType.NotUndefinedOrNull,\n      condTrue.target,\n      condFalse.target,\n    );\n\n    return result;\n  }\n\n  private doProcessPropertyAccessExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PropertyAccessExpression,\n    doBuild: (\n      context: NativeCompilerContext,\n      builder: INativeCompilerBlockBuilder,\n      expressionVariable: NativeCompilerBuilderVariableID,\n      nameVariable: NativeCompilerBuilderAtomID,\n    ) => NativeCompilerBuilderVariableID,\n  ) {\n    let nameVariable: NativeCompilerBuilderAtomID;\n    if (ts.isIdentifier(node.name)) {\n      nameVariable = this.processIdentifierAsAtom(builder, node.name);\n    } else {\n      this.onError(node.name, 'expecting identifier');\n    }\n\n    const newNamePath = context.namePath.appending(nameVariable.identifier);\n    const parentExpressionContext = context.withNamePath(newNamePath);\n\n    if (ts.isOptionalChain(node)) {\n      // if this is part of an optional chain, share the whole expression's result\n      const result = context.optionalChainResult ?? builder.buildAssignableUndefined();\n      if (context.optionalChainExit) {\n        // parent expression share the whole expression's exit and result\n        parentExpressionContext.optionalChainExit = context.optionalChainExit;\n        parentExpressionContext.optionalChainResult = context.optionalChainResult;\n      } else {\n        // start of a new optional chain, create the short circuit jump target\n        const optionalChain = builder.buildJumpTarget('optional_chain');\n        const optionalChainExit = builder.buildJumpTarget('optional_chain_exit');\n        parentExpressionContext.optionalChainExit = optionalChainExit.target;\n        parentExpressionContext.optionalChainResult = result;\n        builder = optionalChain.builder;\n      }\n      // evaluate the parent expression with chain result and exit set\n      const expressionVariable = this.processExpression(parentExpressionContext, builder, node.expression);\n      if (context.assignmentTracker) {\n        context.assignmentTracker.onGetProperty(expressionVariable, nameVariable);\n      }\n      if (node.questionDotToken) {\n        builder.buildAssignment(\n          result,\n          this.buildQuestionDotExpression(context, builder, expressionVariable, (context, builder) => {\n            return doBuild(context, builder, expressionVariable, nameVariable);\n          }),\n        );\n        return result;\n      } else {\n        // this expression is not optional but it's part of an optional chain\n        builder.buildAssignment(result, doBuild(context, builder, expressionVariable, nameVariable));\n        return result;\n      }\n    } else {\n      // not in optional chain\n      const expressionVariable = this.processExpression(parentExpressionContext, builder, node.expression);\n      if (context.assignmentTracker) {\n        context.assignmentTracker.onGetProperty(expressionVariable, nameVariable);\n      }\n      return doBuild(context, builder, expressionVariable, nameVariable);\n    }\n  }\n\n  private tryProcessEnumConstantValuePrologue(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.EnumMember,\n  ): string | number | undefined {\n    if (!context.emitResolver) {\n      return undefined;\n    }\n    return context.emitResolver.getConstantValue(node);\n  }\n\n  private processEnumConstantValueEpilogue(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    value: string | number,\n  ): NativeCompilerBuilderVariableID {\n    if (typeof value === 'string') {\n      return builder.buildLiteralString(value);\n    } else {\n      const numericalStringType = NativeHelper.getNumericalStringTypeFromNumber(value);\n      switch (numericalStringType) {\n        case NativeHelper.NumberType.Integer:\n          return builder.buildLiteralInteger(value.toString());\n        case NativeHelper.NumberType.Long:\n          return builder.buildLiteralLong(value.toString());\n        case NativeHelper.NumberType.Float:\n          return builder.buildLiteralDouble(value.toString());\n      }\n    }\n  }\n\n  private tryProcessEnumConstantValue(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PropertyAccessExpression | ts.ElementAccessExpression | ts.EnumMember,\n  ): NativeCompilerBuilderVariableID | undefined {\n    const value = this.tryProcessEnumConstantValuePrologue(context, builder, node);\n    if (value === undefined) {\n      return undefined;\n    }\n\n    return this.processEnumConstantValueEpilogue(context, builder, value);\n  }\n\n  processPropertyAccessExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PropertyAccessExpression,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n\n    // try shortcut builtin constants (e.g. Math.PI)\n    if (this.options.enableIntrinsics && ts.isIdentifier(node.expression)) {\n      const intrinsicConstant = builder.getIntrinsicConstant(`${node.expression.text}.${node.name.text}`);\n      if (typeof intrinsicConstant === 'number') {\n        return builder.buildLiteralDouble(String(intrinsicConstant));\n      } else if (typeof intrinsicConstant === 'string') {\n        return builder.buildLiteralString(intrinsicConstant);\n      }\n    }\n\n    const constantValue = this.tryProcessEnumConstantValue(context, builder, node);\n    if (constantValue !== undefined) {\n      return constantValue;\n    }\n\n    return this.doProcessPropertyAccessExpression(\n      context,\n      builder,\n      node,\n      (context, builder, expressionVariable, nameVariable) => {\n        return builder.buildGetProperty(\n          expressionVariable,\n          nameVariable,\n          this.resolveVariableToUseAsThis(context, builder, expressionVariable, node),\n        );\n      },\n    );\n  }\n\n  processVariableDeclarationList(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.VariableDeclarationList,\n  ) {\n    node.declarations.forEach((d) => {\n      this.processVariableDeclaration(context, builder, d, (context) => {\n        const initializer = d.initializer;\n        if (initializer) {\n          return this.processExpression(context, builder, initializer);\n        } else {\n          return builder.buildUndefined();\n        }\n      });\n    });\n  }\n\n  processVariableStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.VariableStatement,\n  ) {\n    this.processVariableDeclarationList(context, builder, node.declarationList);\n  }\n\n  processIdentifier(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Identifier,\n  ): NativeCompilerBuilderVariableID {\n    return this.processIdentifierAsValueDelegate(context, builder, node).getValue().variable;\n  }\n\n  processThis(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Node,\n  ): NativeCompilerBuilderVariableID {\n    // the name 'this' is registered by buildFunction()\n    const valueDelegate = this.resolveValueDelegate(context, builder, 'this', node);\n    return valueDelegate.getValue().variable;\n  }\n\n  processNullKeyword(builder: INativeCompilerBlockBuilder, node: ts.Node): NativeCompilerBuilderVariableID {\n    return builder.buildNull();\n  }\n\n  processUndefinedKeyword(builder: INativeCompilerBlockBuilder, node: ts.Node): NativeCompilerBuilderVariableID {\n    return builder.buildUndefined();\n  }\n\n  procssTrueKeyword(buildr: INativeCompilerBlockBuilder, node: ts.Node): NativeCompilerBuilderVariableID {\n    return buildr.buildLiteralBool(true);\n  }\n\n  processFalseKeyword(buildr: INativeCompilerBlockBuilder, node: ts.Node): NativeCompilerBuilderVariableID {\n    return buildr.buildLiteralBool(false);\n  }\n\n  processSuperKeyword(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Node,\n  ): NativeCompilerBuilderVariableID {\n    if (context.namePath.name === CONSTRUCTOR_NAME) {\n      // We are in a constructor, the super keyword should reference the super constructor\n      return builder.buildGetSuperConstructor();\n    } else {\n      return builder.buildGetSuper();\n    }\n  }\n\n  processIdentifierAsAtom(builder: INativeCompilerBlockBuilder, node: ts.Identifier): NativeCompilerBuilderAtomID {\n    return this.processIdentifierStringAsAtom(builder, node.text);\n  }\n\n  processIdentifierStringAsAtom(builder: INativeCompilerBlockBuilder, text: string): NativeCompilerBuilderAtomID {\n    return this.moduleBuilder.registerAtom(text);\n  }\n\n  private resolveRegisteredVariableRefForIdentifierName(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Node,\n    name: string,\n  ): NativeCompilerBuilderVariableRef {\n    const variableRef = builder.resolveVariableRefOrDelegateInScope(name);\n    if (!(variableRef instanceof NativeCompilerBuilderVariableRef)) {\n      this.onError(node, 'Declaration was not registered');\n    }\n\n    return variableRef;\n  }\n  private resolveRegisteredVariableRefForIdentifier(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Identifier,\n  ): NativeCompilerBuilderVariableRef {\n    return this.resolveRegisteredVariableRefForIdentifierName(context, builder, node, node.text);\n  }\n\n  private getVariableRefNameForImportedModule(node: ts.Expression): string {\n    const moduleVariableName = this.moduleVariableNameByPosition[node.pos];\n    if (!moduleVariableName) {\n      this.onError(node, 'Variable ref name not registered for import clause');\n    }\n\n    return moduleVariableName;\n  }\n\n  private createVariableRefNameForImportedModule(node: ts.Expression): string {\n    const variableRefName = this.allocateUniqueVariableRefName('$imported_module');\n    if (this.moduleVariableNameByPosition[node.pos]) {\n      this.onError(node, 'Duplicated module variable name for import clause');\n    }\n\n    this.moduleVariableNameByPosition[node.pos] = variableRefName;\n\n    return variableRefName;\n  }\n\n  private static makeValueDelegate(\n    builder: INativeCompilerBlockBuilder,\n    variableName: string,\n    variableRefOrDelegate: NativeCompilerBuilderVariableRef | IVariableDelegate,\n  ): NativeCompilerVariableIDValueDelegate {\n    if (variableRefOrDelegate instanceof NativeCompilerBuilderVariableRef) {\n      return {\n        getValue: () => {\n          return { variable: builder.buildLoadVariableRef(variableRefOrDelegate), parentVariable: undefined };\n        },\n        setValue: (value) => {\n          builder.buildSetVariableRef(variableRefOrDelegate, value);\n        },\n      };\n    } else {\n      return {\n        getValue: () => {\n          return { variable: variableRefOrDelegate.onGetValue(builder), parentVariable: undefined };\n        },\n        setValue: (value) => {\n          if (variableRefOrDelegate.onSetValue) {\n            variableRefOrDelegate.onSetValue(builder, value);\n          } else {\n            throw new Error(`Variable from identifier '${variableName}' is read-only`);\n          }\n        },\n      };\n    }\n  }\n\n  private resolveValueDelegate(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    variableName: string,\n    node: ts.Node,\n  ): NativeCompilerVariableIDValueDelegate {\n    if (variableName === 'undefined') {\n      return {\n        getValue: () => {\n          return { variable: builder.buildUndefined(), parentVariable: undefined };\n        },\n        setValue: (value) => {\n          this.onError(node, 'undefined cannot be set');\n        },\n      };\n    }\n\n    const resolvedVar = builder.resolveVariableRefOrDelegateInScope(variableName);\n    if (resolvedVar !== undefined) {\n      return NativeCompiler.makeValueDelegate(builder, variableName, resolvedVar);\n    }\n\n    return {\n      getValue: () => {\n        return this.getGlobalVariable(context, builder, variableName);\n      },\n      setValue: (value) => {\n        const parentObject = builder.buildGlobal();\n        const atomID = this.processIdentifierStringAsAtom(builder, variableName);\n        builder.buildSetProperty(parentObject, atomID, value);\n      },\n    };\n  }\n\n  private processIdentifierAsValueDelegate(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Identifier,\n  ): NativeCompilerVariableIDValueDelegate {\n    return this.resolveValueDelegate(context, builder, node.text, node);\n  }\n\n  private getGlobalVariable(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    variableName: string,\n  ): NativeCompilerVariableIDWithParent {\n    const parentObject = builder.buildGlobal();\n    const atomID = this.processIdentifierStringAsAtom(builder, variableName);\n\n    if (context.assignmentTracker) {\n      context.assignmentTracker.onGetProperty(parentObject, atomID);\n    }\n\n    return { variable: builder.buildGetProperty(parentObject, atomID, parentObject), parentVariable: parentObject };\n  }\n\n  private resolveNamePath(node: ts.Node, initialNamePath: NamePath): NamePath {\n    if (ts.isIdentifier(node)) {\n      return initialNamePath.appending(node.text);\n    } else if (ts.isPropertyAccessExpression(node)) {\n      const newNamePath = this.resolveNamePath(node.expression, initialNamePath);\n      return this.resolveNamePath(node.name, newNamePath);\n    } else {\n      return initialNamePath;\n    }\n  }\n\n  private processBinaryExpressionAsAssignment(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    operatorType: NativeCompilerIR.BinaryOperator,\n    leftNode: ts.Node,\n    leftVariable: Lazy<NativeCompilerBuilderVariableID>,\n    rightVariable: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    const resultVariable = builder.buildBinaryOp(operatorType, leftVariable.target, rightVariable);\n\n    return this.processBinaryExpressionResultAsAssignment(context, builder, leftNode, leftVariable, resultVariable);\n  }\n\n  private processAssignmentElement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    name: ts.Identifier,\n    initializer?: ts.Expression,\n  ): AssignmentElementVariable {\n    const resolvedVar = builder.resolveVariableInScope(name.text);\n    if (!resolvedVar) {\n      // the requested variable name must already exist\n      this.onError(name, 'Unknown variable: ' + name.text);\n    }\n    return {\n      variable: resolvedVar,\n      defaultValue: initializer\n        ? (input: NativeCompilerBuilderVariableID) =>\n            this.buildConditionalVariable(\n              context,\n              builder,\n              (context, builder) =>\n                builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.EqualEqualEqual, input, builder.buildUndefined()),\n              (context, builder) => this.processExpression(context, builder, initializer),\n              (context, builder) => input,\n            )\n        : undefined,\n      isRest: false,\n    };\n  }\n\n  private processArrayAssignment(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    pattern: ts.ArrayLiteralExpression,\n    resultVariable: NativeCompilerBuilderVariableID,\n  ) {\n    const allVariables: [number, AssignmentElementVariable][] = [];\n    let elementIndex = 0;\n    for (const element of pattern.elements) {\n      const currentElementIndex = elementIndex++;\n      if (ts.isOmittedExpression(element)) {\n        continue;\n      }\n      if (ts.isIdentifier(element)) {\n        // simple element\n        allVariables.push([currentElementIndex, this.processAssignmentElement(context, builder, element)]);\n      } else if (\n        ts.isBinaryExpression(element) &&\n        element.operatorToken.kind === ts.SyntaxKind.EqualsToken &&\n        ts.isIdentifier(element.left)\n      ) {\n        // element with default\n        allVariables.push([\n          currentElementIndex,\n          this.processAssignmentElement(context, builder, element.left, element.right),\n        ]);\n      } else if (ts.isObjectLiteralExpression(element)) {\n        // object pattern in array\n        const elementValue = builder.buildGetPropertyValue(\n          resultVariable,\n          builder.buildLiteralInteger(currentElementIndex.toString()),\n          resultVariable,\n        );\n        this.processObjectAssignment(context, builder, element, elementValue);\n      } else if (ts.isArrayLiteralExpression(element)) {\n        // object pattern in array\n        const elementValue = builder.buildGetPropertyValue(\n          resultVariable,\n          builder.buildLiteralInteger(currentElementIndex.toString()),\n          resultVariable,\n        );\n        this.processArrayAssignment(context, builder, element, elementValue);\n      } else if (ts.isSpreadElement(element) && ts.isIdentifier(element.expression)) {\n        // ...rest\n        const restElement: AssignmentElementVariable = {\n          ...this.processAssignmentElement(context, builder, element.expression),\n          isRest: true,\n        };\n        allVariables.push([currentElementIndex, restElement]);\n      } else if (ts.isSpreadElement(element)) {\n        // Call object.slice(elementIndex)\n        const sliceMethod = builder.buildGetProperty(\n          resultVariable,\n          this.processIdentifierStringAsAtom(builder, 'slice'),\n          resultVariable,\n        );\n        const elementValue = builder.buildFunctionInvocation(\n          sliceMethod,\n          [builder.buildLiteralInteger(currentElementIndex.toString())],\n          resultVariable,\n        );\n        if (ts.isArrayLiteralExpression(element.expression)) {\n          this.processArrayAssignment(context, builder, element.expression, elementValue);\n        } else if (ts.isObjectLiteralExpression(element.expression)) {\n          this.processObjectAssignment(context, builder, element.expression, elementValue);\n        } else {\n          this.onError(element, 'Unsupported spread assignment');\n        }\n      } else {\n        this.onError(element, 'Unsupported assignment');\n      }\n    }\n    for (const [elementIndex, element] of allVariables) {\n      let elementValue: NativeCompilerBuilderVariableID;\n      if (element.isRest) {\n        // Call object.slice(elementIndex)\n        const sliceMethod = builder.buildGetProperty(\n          resultVariable,\n          this.processIdentifierStringAsAtom(builder, 'slice'),\n          resultVariable,\n        );\n        elementValue = builder.buildFunctionInvocation(\n          sliceMethod,\n          [builder.buildLiteralInteger(elementIndex.toString())],\n          resultVariable,\n        );\n      } else {\n        elementValue = builder.buildGetPropertyValue(\n          resultVariable,\n          builder.buildLiteralInteger(elementIndex.toString()),\n          resultVariable,\n        );\n        if (element.defaultValue) {\n          elementValue = element.defaultValue(elementValue);\n        }\n      }\n      builder.buildAssignment(element.variable, elementValue);\n    }\n  }\n\n  private processObjectAssignment(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    pattern: ts.ObjectLiteralExpression,\n    resultVariable: NativeCompilerBuilderVariableID,\n  ) {\n    const allVariables: [ts.Identifier, AssignmentElementVariable][] = [];\n    for (const element of pattern.properties) {\n      if (ts.isShorthandPropertyAssignment(element)) {\n        allVariables.push([\n          element.name,\n          this.processAssignmentElement(context, builder, element.name, element.objectAssignmentInitializer),\n        ]);\n      } else if (\n        ts.isPropertyAssignment(element) &&\n        ts.isIdentifier(element.name) &&\n        ts.isIdentifier(element.initializer)\n      ) {\n        allVariables.push([\n          element.name,\n          this.processAssignmentElement(context, builder, element.initializer, undefined),\n        ]);\n      } else if (\n        ts.isPropertyAssignment(element) &&\n        ts.isIdentifier(element.name) &&\n        ts.isBinaryExpression(element.initializer) &&\n        ts.isIdentifier(element.initializer.left)\n      ) {\n        allVariables.push([\n          element.name,\n          this.processAssignmentElement(context, builder, element.initializer.left, element.initializer.right),\n        ]);\n      } else if (ts.isSpreadAssignment(element) && ts.isIdentifier(element.expression)) {\n        // ...rest\n        const restElement: AssignmentElementVariable = {\n          ...this.processAssignmentElement(context, builder, element.expression),\n          isRest: true,\n        };\n        allVariables.push([element.expression, restElement]);\n      } else if (\n        ts.isPropertyAssignment(element) &&\n        ts.isIdentifier(element.name) &&\n        ts.isObjectLiteralExpression(element.initializer)\n      ) {\n        // recursive assignment\n        const propertyValue = builder.buildGetProperty(\n          resultVariable,\n          this.processIdentifierAsAtom(builder, element.name),\n          resultVariable,\n        );\n        this.processObjectAssignment(context, builder, element.initializer, propertyValue);\n      } else {\n        this.onError(element, 'Unsupported assignment');\n      }\n    }\n    const propertiesToIgnore: NativeCompilerBuilderAtomID[] = [];\n    for (const [identifier, element] of allVariables) {\n      let elementValue: NativeCompilerBuilderVariableID;\n      if (element.isRest) {\n        // ...rest can only be the last element so propertiesToIgnore should already have been populated\n        elementValue = builder.buildNewObject();\n        builder.buildCopyPropertiesFrom(elementValue, resultVariable, propertiesToIgnore);\n      } else {\n        elementValue = builder.buildGetProperty(\n          resultVariable,\n          this.processIdentifierAsAtom(builder, identifier),\n          resultVariable,\n        );\n        if (element.defaultValue) {\n          elementValue = element.defaultValue(elementValue);\n        }\n      }\n      builder.buildAssignment(element.variable, elementValue);\n      propertiesToIgnore.push(this.processIdentifierAsAtom(builder, identifier));\n    }\n  }\n\n  private processBinaryExpressionResultAsAssignment(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    leftNode: ts.Node,\n    leftVariable: Lazy<NativeCompilerBuilderVariableID>,\n    resultVariable: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    if (ts.isPropertyAccessExpression(leftNode)) {\n      this.processPropertyAccessExpressionAsAssignment(\n        context,\n        builder,\n        leftNode.name,\n        leftNode.expression,\n        resultVariable,\n      );\n    } else if (ts.isIdentifier(leftNode)) {\n      const valueDelegate = this.processIdentifierAsValueDelegate(context, builder, leftNode);\n      valueDelegate.setValue(resultVariable);\n    } else if (ts.isElementAccessExpression(leftNode)) {\n      this.processElementAccessExpressionAsAssignment(context, builder, leftNode, resultVariable);\n    } else if (ts.isArrayLiteralExpression(leftNode)) {\n      this.processArrayAssignment(context, builder, leftNode, resultVariable);\n    } else if (ts.isObjectLiteralExpression(leftNode)) {\n      this.processObjectAssignment(context, builder, leftNode, resultVariable);\n    } else {\n      this.onError(leftNode, 'Unsupported assignment');\n    }\n    return resultVariable;\n  }\n\n  processBinaryExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.BinaryExpression,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n\n    let rightContext = context.withNamePath(this.resolveNamePath(node.left, context.namePath));\n\n    if (node.operatorToken.kind === ts.SyntaxKind.BarBarToken) {\n      const result = builder.buildAssignableUndefined();\n\n      const leftCondition = builder.buildJumpTarget('lhs_condition');\n      const leftConditionTrue = builder.buildJumpTarget('lhs_true');\n      const leftConditionFalse = builder.buildJumpTarget('lhs_false');\n      const exitTarget = builder.buildJumpTarget('exit');\n\n      const lhs = this.processExpression(context, leftCondition.builder, node.left);\n\n      // If lhs is truthy, assign lhs to result\n      leftConditionTrue.builder.buildAssignment(result, lhs);\n      leftConditionTrue.builder.buildJump(exitTarget.target);\n\n      // If lhs is falsy, assign rhs to result\n      const rhs = this.processExpression(rightContext, leftConditionFalse.builder, node.right);\n      leftConditionFalse.builder.buildAssignment(result, rhs);\n      leftConditionFalse.builder.buildJump(exitTarget.target);\n\n      leftCondition.builder.buildBranch(\n        lhs,\n        NativeCompilerBuilderBranchType.Truthy,\n        leftConditionTrue.target,\n        leftConditionFalse.target,\n      );\n\n      return result;\n    } else if (node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {\n      const result = builder.buildAssignableUndefined();\n\n      const leftCondition = builder.buildJumpTarget('lhs_condition');\n      const leftConditionTrue = builder.buildJumpTarget('lhs_true');\n      const leftConditionFalse = builder.buildJumpTarget('lhs_false');\n      const exitTarget = builder.buildJumpTarget('exit');\n\n      const lhs = this.processExpression(context, leftCondition.builder, node.left);\n\n      // If lhs is truthy, assign rhs to result\n      const rhs = this.processExpression(rightContext, leftConditionTrue.builder, node.right);\n      leftConditionTrue.builder.buildAssignment(result, rhs);\n      leftConditionTrue.builder.buildJump(exitTarget.target);\n\n      // If lhs is falsy, assign lhs to result\n      leftConditionFalse.builder.buildAssignment(result, lhs);\n      leftConditionFalse.builder.buildJump(exitTarget.target);\n\n      leftCondition.builder.buildBranch(\n        lhs,\n        NativeCompilerBuilderBranchType.Truthy,\n        leftConditionTrue.target,\n        leftConditionFalse.target,\n      );\n\n      return result;\n    } else if (node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {\n      const result = builder.buildAssignableUndefined();\n\n      const lhsValue = builder.buildJumpTarget('lhs_value');\n      const lhsAssign = builder.buildJumpTarget('lhs_assign');\n      const rhsValue = builder.buildJumpTarget('rhs_value');\n      const rhsAssign = builder.buildJumpTarget('rhs_assign');\n      const exitTarget = builder.buildJumpTarget('exit');\n\n      const lhs = this.processExpression(context, lhsValue.builder, node.left);\n\n      // lhs_assign will be evaluated if lhs is not null or undefined, and will assign the result\n      lhsAssign.builder.buildAssignment(result, lhs);\n      lhsAssign.builder.buildJump(exitTarget.target);\n\n      // rhs_value will be evaluated if lhs_value is null or undefined\n      const rhs = this.processExpression(rightContext, rhsValue.builder, node.right);\n      rhsValue.builder.buildJump(rhsAssign.target);\n\n      // rhs_assign will be evaluated right after rhs_value is evaluated, and will assign the result\n      rhsAssign.builder.buildAssignment(result, rhs);\n      rhsAssign.builder.buildJump(exitTarget.target);\n\n      lhsValue.builder.buildBranch(\n        lhs,\n        NativeCompilerBuilderBranchType.NotUndefinedOrNull,\n        lhsAssign.target,\n        rhsValue.target,\n      );\n\n      return result;\n    } else if (node.operatorToken.kind === ts.SyntaxKind.QuestionQuestionEqualsToken) {\n      const lhsValue = builder.buildJumpTarget('lhs_value');\n      const rhsValue = builder.buildJumpTarget('rhs_value');\n      const rhsAssign = builder.buildJumpTarget('rhs_assign');\n      const exitTarget = builder.buildJumpTarget('exit');\n\n      const lhs = this.processExpression(context, lhsValue.builder, node.left);\n\n      // rhs_value will be evaluated if lhs_value is null or undefined\n      const rhs = this.processExpression(rightContext, rhsValue.builder, node.right);\n      rhsValue.builder.buildJump(rhsAssign.target);\n\n      // rhs_assign will be evaluated right after rhs_value is evaluated, and will assign to lhs\n      rhsAssign.builder.buildAssignment(\n        lhs,\n        this.processBinaryExpressionResultAsAssignment(context, rhsAssign.builder, node.left, new Lazy(() => lhs), rhs),\n      );\n      rhsAssign.builder.buildJump(exitTarget.target);\n\n      lhsValue.builder.buildBranch(\n        lhs,\n        NativeCompilerBuilderBranchType.NotUndefinedOrNull,\n        exitTarget.target, // no assignment if lhs is not nullish\n        rhsValue.target,\n      );\n\n      return lhs;\n    } else if (node.operatorToken.kind === ts.SyntaxKind.BarBarEqualsToken) {\n      const leftCondition = builder.buildJumpTarget('lhs_condition');\n      const leftConditionFalse = builder.buildJumpTarget('lhs_false');\n      const exitTarget = builder.buildJumpTarget('exit');\n\n      const lhs = this.processExpression(context, leftCondition.builder, node.left);\n\n      // If lhs is falsy, assign rhs to lhs\n      const rhs = this.processExpression(rightContext, leftConditionFalse.builder, node.right);\n      leftConditionFalse.builder.buildAssignment(\n        lhs,\n        this.processBinaryExpressionResultAsAssignment(\n          context,\n          leftConditionFalse.builder,\n          node.left,\n          new Lazy(() => lhs),\n          rhs,\n        ),\n      );\n      leftConditionFalse.builder.buildJump(exitTarget.target);\n\n      leftCondition.builder.buildBranch(\n        lhs,\n        NativeCompilerBuilderBranchType.Truthy,\n        exitTarget.target, // If lhs is truthy, return lhs\n        leftConditionFalse.target,\n      );\n\n      return lhs;\n    }\n\n    const leftVariable = new Lazy(() => this.processExpression(context, builder, node.left));\n    const rightVariable = this.processExpression(rightContext, builder, node.right);\n\n    switch (node.operatorToken.kind) {\n      case ts.SyntaxKind.AsteriskToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.Mult, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.SlashToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.Div, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.LessThanToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.LessThan, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.LessThanEqualsToken:\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.LessThanOrEqual,\n          leftVariable.target,\n          rightVariable,\n        );\n      case ts.SyntaxKind.LessThanLessThanEqualsToken:\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.LessThanOrEqualEqual,\n          leftVariable.target,\n          rightVariable,\n        );\n      case ts.SyntaxKind.GreaterThanToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.GreaterThan, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.GreaterThanEqualsToken:\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.GreaterThanOrEqual,\n          leftVariable.target,\n          rightVariable,\n        );\n      case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken:\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.GreaterThanOrEqualEqual,\n          leftVariable.target,\n          rightVariable,\n        );\n      case ts.SyntaxKind.EqualsEqualsToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.EqualEqual, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.EqualsEqualsEqualsToken:\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.EqualEqualEqual,\n          leftVariable.target,\n          rightVariable,\n        );\n      case ts.SyntaxKind.ExclamationEqualsToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.DifferentThan, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.ExclamationEqualsEqualsToken:\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.DifferentThanStrict,\n          leftVariable.target,\n          rightVariable,\n        );\n      case ts.SyntaxKind.MinusToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.Sub, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.PlusToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.Add, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.GreaterThanGreaterThanToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.RightShift, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.UnsignedRightShift,\n          leftVariable.target,\n          rightVariable,\n        );\n      case ts.SyntaxKind.LessThanLessThanToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.LeftShift, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.BarToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.BitwiseOR, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.CaretToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.BitwiseXOR, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.AmpersandToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.BitwiseAND, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.PercentToken:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.Modulo, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.AsteriskAsteriskToken:\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.Exponentiation,\n          leftVariable.target,\n          rightVariable,\n        );\n      case ts.SyntaxKind.InstanceOfKeyword:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.InstanceOf, leftVariable.target, rightVariable);\n      case ts.SyntaxKind.CommaToken:\n        leftVariable.loadIfNeeded();\n        return rightVariable;\n      case ts.SyntaxKind.InKeyword:\n        return builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.In, leftVariable.target, rightVariable);\n      /**\n       * Start of binary assignment operators\n       */\n      case ts.SyntaxKind.EqualsToken:\n        return this.processBinaryExpressionResultAsAssignment(context, builder, node.left, leftVariable, rightVariable);\n      case ts.SyntaxKind.PlusEqualsToken:\n        return this.processBinaryExpressionAsAssignment(\n          context,\n          builder,\n          NativeCompilerIR.BinaryOperator.Add,\n          node.left,\n          leftVariable,\n          rightVariable,\n        );\n      case ts.SyntaxKind.MinusEqualsToken:\n        return this.processBinaryExpressionAsAssignment(\n          context,\n          builder,\n          NativeCompilerIR.BinaryOperator.Sub,\n          node.left,\n          leftVariable,\n          rightVariable,\n        );\n      case ts.SyntaxKind.AsteriskEqualsToken:\n        return this.processBinaryExpressionAsAssignment(\n          context,\n          builder,\n          NativeCompilerIR.BinaryOperator.Mult,\n          node.left,\n          leftVariable,\n          rightVariable,\n        );\n      case ts.SyntaxKind.SlashEqualsToken:\n        return this.processBinaryExpressionAsAssignment(\n          context,\n          builder,\n          NativeCompilerIR.BinaryOperator.Div,\n          node.left,\n          leftVariable,\n          rightVariable,\n        );\n      case ts.SyntaxKind.AmpersandEqualsToken:\n        return this.processBinaryExpressionAsAssignment(\n          context,\n          builder,\n          NativeCompilerIR.BinaryOperator.BitwiseAND,\n          node.left,\n          leftVariable,\n          rightVariable,\n        );\n      case ts.SyntaxKind.BarEqualsToken:\n        return this.processBinaryExpressionAsAssignment(\n          context,\n          builder,\n          NativeCompilerIR.BinaryOperator.BitwiseOR,\n          node.left,\n          leftVariable,\n          rightVariable,\n        );\n      case ts.SyntaxKind.CaretEqualsToken:\n        return this.processBinaryExpressionAsAssignment(\n          context,\n          builder,\n          NativeCompilerIR.BinaryOperator.BitwiseXOR,\n          node.left,\n          leftVariable,\n          rightVariable,\n        );\n      case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken:\n        return this.processBinaryExpressionAsAssignment(\n          context,\n          builder,\n          NativeCompilerIR.BinaryOperator.UnsignedRightShift,\n          node.left,\n          leftVariable,\n          rightVariable,\n        );\n      default:\n        this.onError(\n          node,\n          `Operator not supported in processBinaryExpression (operator id: ${node.operatorToken.kind})`,\n        );\n    }\n  }\n\n  processInterfaceDeclaration(builder: INativeCompilerBlockBuilder, node: ts.InterfaceDeclaration) {\n    //NOOP\n  }\n\n  private processDeclarationWithDefaultInitializer(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Expression,\n    inputVariable: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    return this.buildConditionalVariable(\n      context,\n      builder,\n      (context, builder) => {\n        return builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.DifferentThanStrict,\n          inputVariable,\n          builder.buildUndefined(),\n        );\n      },\n      (context, builder) => {\n        return inputVariable;\n      },\n      (context, builder) => {\n        return this.processExpression(context, builder, node);\n      },\n    );\n  }\n\n  processParameterDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ParameterDeclaration,\n    parentNode: ts.Node,\n    index: number,\n  ): ((context: NativeCompilerContext, builder: INativeCompilerBlockBuilder) => void) | undefined {\n    if (!ts.isIdentifier(node.name)) {\n      if (ts.isParameterPropertyDeclaration(node, parentNode)) {\n        this.onError(node, 'Parameter property declaration not yet supported');\n      }\n\n      this.processBindingName(context, builder, node.name, undefined, (context) => {\n        if (node.dotDotDotToken) {\n          return builder.buildGetFunctionArgumentsObject(index);\n        } else {\n          return builder.buildGetFunctionArg(index);\n        }\n      });\n\n      return;\n    }\n\n    let paramVariable: NativeCompilerBuilderVariableID;\n    if (node.dotDotDotToken) {\n      paramVariable = builder.buildGetFunctionArgumentsObject(index);\n    } else {\n      paramVariable = builder.buildGetFunctionArg(index);\n    }\n\n    const variableRef = this.resolveRegisteredVariableRefForIdentifier(context, builder, node.name);\n    let resolvedVariable: NativeCompilerBuilderVariableID;\n\n    const defaultParameterValue = node.initializer;\n    if (defaultParameterValue) {\n      resolvedVariable = this.processDeclarationWithDefaultInitializer(\n        context,\n        builder,\n        defaultParameterValue,\n        paramVariable,\n      );\n    } else {\n      resolvedVariable = paramVariable;\n    }\n\n    builder.buildSetVariableRef(variableRef, resolvedVariable);\n\n    if (ts.isParameterPropertyDeclaration(node, parentNode)) {\n      return (context: NativeCompilerContext, builder: INativeCompilerBlockBuilder) => {\n        const thisVariable = this.processThis(context, builder, node);\n        const propertyName = this.processIdentifierAsAtom(builder, node.name);\n\n        this.doBuildSetProperty(\n          context,\n          builder,\n          propertyName,\n          thisVariable,\n          builder.resolveVariableInScope(node.name.text)!,\n        );\n      };\n    }\n    return undefined;\n  }\n\n  private isThisParameter(node: ts.ParameterDeclaration): boolean {\n    if (!ts.isIdentifier(node.name)) {\n      return false;\n    }\n\n    return node.name.text === 'this';\n  }\n\n  private processParameterDeclarations(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    parameters: ts.NodeArray<ts.ParameterDeclaration>,\n    parentNode: ts.Node,\n    isArrowFunction: boolean,\n    enqueueDeferredStatement: EnqueueDeferredStatementFunc | undefined,\n  ) {\n    if (!isArrowFunction) {\n      builder.registerLazyVariableRef('arguments', VariableRefScope.Function, (builder) => {\n        const parametersVariableRef = builder.buildVariableRef(\n          'arguments',\n          NativeCompilerBuilderVariableType.Object,\n          VariableRefScope.Function,\n        );\n        const parametersVariable = builder.buildGetFunctionArgumentsObject(0);\n        builder.buildSetVariableRef(parametersVariableRef, parametersVariable);\n        return parametersVariableRef;\n      });\n    }\n\n    let parametersToProcess: ts.NodeArray<ts.ParameterDeclaration> | ts.ParameterDeclaration[];\n\n    if (parameters.length && this.isThisParameter(parameters[0])) {\n      // Ignore 'this' parameter\n      parametersToProcess = parameters.slice(1);\n    } else {\n      parametersToProcess = parameters;\n    }\n\n    for (const parameter of parametersToProcess) {\n      this.prepareBindingName(builder, parameter.name, VariableRefScope.Function);\n    }\n\n    parametersToProcess.forEach((p, i) => {\n      const deferredStatement = this.processParameterDeclaration(context, builder, p, parentNode, i);\n      if (deferredStatement) {\n        if (enqueueDeferredStatement) {\n          enqueueDeferredStatement(deferredStatement);\n        } else {\n          deferredStatement(context, builder);\n        }\n      }\n    });\n  }\n\n  private isAmbientDeclaration(node: ts.Node): boolean {\n    const modifiers = ts.getCombinedModifierFlags(node as ts.Declaration);\n    return (modifiers & ts.ModifierFlags.Ambient) != 0;\n  }\n\n  processFunctionBody(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    body: ts.FunctionBody | ts.Expression,\n    isGenerator: boolean,\n    isAsync: boolean,\n  ) {\n    if (isGenerator && isAsync) {\n      const generator = this.processGenerator(context, builder, body, isGenerator, isAsync);\n      const helper = this.getGlobalVariable(context, builder, '__tsn_async_generator_helper').variable;\n      const asyncGenenerator = builder.buildFunctionInvocation(helper, [generator], builder.buildUndefined());\n      builder.buildReturn(asyncGenenerator);\n    } else if (isGenerator) {\n      // generator: build an iterator on the closure and return it\n      const generator = this.processGenerator(context, builder, body, isGenerator, isAsync);\n      builder.buildReturn(generator);\n    } else if (isAsync) {\n      // convert the async function body into a generator\n      // the `await` keyword will produce the same code as `yield`\n      const generator = this.processGenerator(context, builder, body, isGenerator, isAsync);\n      // the helper function is defined in \"tsn/rtl/rtl/tsn.ts\"\n      // and is expected to be present in the global namespace\n      const helper = this.getGlobalVariable(context, builder, '__tsn_async_helper').variable;\n      // async function returns a promise from the helper\n      const promise = builder.buildFunctionInvocation(helper, [generator], builder.buildUndefined());\n      builder.buildReturn(promise);\n    } else {\n      // regular function: build function body\n      if (ts.isBlock(body)) {\n        this.processBlock(context, builder, body);\n      } else {\n        const returnValue = this.processExpression(context, builder, body);\n        builder.buildReturn(returnValue);\n      }\n    }\n  }\n\n  processFunctionDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.FunctionDeclaration,\n    isArrowFunction: boolean,\n  ) {\n    if (!node.body) {\n      return;\n    }\n\n    this.appendNodeDebugInfo(builder, node);\n\n    const functionVariableId = this.doProcessFunctionDeclaration(\n      context,\n      builder,\n      node.name,\n      undefined,\n      false,\n      false,\n      false,\n      undefined,\n      (context, builder) => {\n        this.processParameterDeclarations(context, builder, node.parameters, node, isArrowFunction, undefined);\n        if (node.body) {\n          const isGenerator = !!node.asteriskToken;\n          const isAsync = !!node.modifiers?.some((m) => m.kind == ts.SyntaxKind.AsyncKeyword);\n          this.processFunctionBody(context, builder, node.body, isGenerator, isAsync);\n        }\n        return node.parameters.length;\n      },\n    );\n\n    this.appendExportedDeclarationIfNeeded(context, builder, node, node.name, functionVariableId);\n\n    return functionVariableId;\n  }\n\n  private processGenerator(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    body: ts.FunctionBody | ts.Expression,\n    isGenerator: boolean,\n    isAsync: boolean,\n  ) {\n    const functionName = this.getFunctionName(context.namePath.appendingTSNode(undefined));\n    // build the generator closure\n    const functionBuilder = this.moduleBuilder.buildFunction(\n      functionName,\n      builder,\n      true,\n      true /* async are processed as generators at builder level */,\n      false,\n    );\n    const functionContext = context.withNamePath(context.namePath, isGenerator, isAsync);\n    if (ts.isBlock(body)) {\n      this.processBlock(functionContext, functionBuilder.builder, body);\n    } else {\n      const returnValue = this.processExpression(functionContext, functionBuilder.builder, body);\n      functionBuilder.builder.buildReturn(returnValue);\n    }\n    const closure = builder.buildNewArrowFunctionValue(functionName, 1, functionBuilder.closureArguments, true);\n    return builder.buildGenerator(closure);\n  }\n\n  private doProcessFunctionDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    name: ts.Identifier | undefined,\n    namePathPrefx: string | undefined,\n    isMethod: boolean,\n    isClass: boolean,\n    isExpression: boolean,\n    parentClass: NativeCompilerBuilderVariableID | undefined,\n    doBuild: (context: NativeCompilerContext, builder: INativeCompilerBlockBuilder) => number,\n  ): NativeCompilerBuilderVariableID {\n    let newNamePath = context.namePath.appendingTSNode(name, namePathPrefx);\n    const functionName = this.getFunctionName(newNamePath);\n\n    let localFunctionName: ts.Identifier | undefined;\n    let constructorName: NativeCompilerBuilderAtomID;\n    if (name && ts.isIdentifier(name)) {\n      localFunctionName = name;\n      constructorName = this.moduleBuilder.registerAtom(localFunctionName.text);\n    } else {\n      constructorName = this.moduleBuilder.registerAtom('anonymous');\n    }\n\n    let variableRef: NativeCompilerBuilderVariableRef | undefined;\n    if (localFunctionName && !isMethod) {\n      if (isExpression) {\n        builder = builder.buildSubBuilder(true);\n        variableRef = builder.buildVariableRef(\n          localFunctionName.text,\n          NativeCompilerBuilderVariableType.Object,\n          VariableRefScope.Block,\n        );\n      } else {\n        variableRef = this.resolveRegisteredVariableRefForIdentifier(context, builder, localFunctionName);\n      }\n    }\n\n    const functionBuilder = this.moduleBuilder.buildFunction(functionName, builder, false, false, isClass);\n\n    const argc = doBuild(context.withNamePath(newNamePath), functionBuilder.builder);\n\n    let variable: NativeCompilerBuilderVariableID;\n\n    if (isClass) {\n      const resolvedParentClass = parentClass ?? builder.buildUndefined();\n      variable = builder.buildNewClassValue(\n        functionName,\n        constructorName,\n        argc,\n        resolvedParentClass,\n        functionBuilder.closureArguments,\n      );\n    } else {\n      variable = builder.buildNewFunctionValue(functionName, constructorName, argc, functionBuilder.closureArguments);\n    }\n\n    if (variableRef) {\n      builder.buildSetVariableRef(variableRef, variable);\n    }\n\n    return variable;\n  }\n\n  processFunctionExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.FunctionExpression,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n\n    let newNamePath = context.namePath.appendingTSNode(node.name);\n    const functionName = this.getFunctionName(newNamePath);\n    let constructorName: NativeCompilerBuilderAtomID;\n    let variableRef: NativeCompilerBuilderVariableRef | undefined;\n    if (node.name) {\n      // If we have a name, we need to register a variable ref for our function expression scoped\n      // to the inner function. The inner function will have access to the variable ref of itself\n      builder = builder.buildSubBuilder(true);\n      constructorName = this.processIdentifierAsAtom(builder, node.name);\n      variableRef = builder.buildVariableRef(\n        node.name.text,\n        NativeCompilerBuilderVariableType.Object,\n        VariableRefScope.Block,\n      );\n    } else {\n      constructorName = this.moduleBuilder.registerAtom(newNamePath.name);\n    }\n\n    const functionBuilder = this.moduleBuilder.buildFunction(functionName, builder, false, false, false);\n    const childContext = context.withNamePath(newNamePath);\n    this.processParameterDeclarations(childContext, functionBuilder.builder, node.parameters, node, false, undefined);\n\n    const isGenerator = !!node.asteriskToken;\n    const isAsync = !!node.modifiers?.some((m) => m.kind == ts.SyntaxKind.AsyncKeyword);\n    this.processFunctionBody(context, functionBuilder.builder, node.body, isGenerator, isAsync);\n\n    const variableId = builder.buildNewFunctionValue(\n      functionName,\n      constructorName,\n      node.parameters.length,\n      functionBuilder.closureArguments,\n    );\n\n    if (variableRef) {\n      builder.buildSetVariableRef(variableRef, variableId);\n    }\n\n    return variableId;\n  }\n\n  processArrowFunction(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ArrowFunction,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n    const functionName = this.getFunctionName(context.namePath.appendingTSNode(undefined));\n\n    const functionBuilder = this.moduleBuilder.buildFunction(functionName, builder, true, false, false);\n    this.processParameterDeclarations(context, functionBuilder.builder, node.parameters, node, true, undefined);\n    const isGenerator = !!node.asteriskToken;\n    const isAsync = !!node.modifiers?.some((m) => m.kind == ts.SyntaxKind.AsyncKeyword);\n    this.processFunctionBody(context, functionBuilder.builder, node.body, isGenerator, isAsync);\n    return builder.buildNewArrowFunctionValue(\n      functionName,\n      node.parameters.length,\n      functionBuilder.closureArguments,\n      false,\n    );\n  }\n\n  buildArrayWithElements(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    elements: ts.NodeArray<ts.Expression>,\n  ): NativeCompilerBuilderVariableID {\n    const arrayVariableID = builder.buildNewArray();\n\n    if (elements.length > 0) {\n      let index = builder.buildLiteralInteger('0');\n      for (const element of elements) {\n        if (ts.isSpreadElement(element)) {\n          const spreadElement: ts.SpreadElement = element;\n          const sourceObject = this.processExpression(context, builder, spreadElement.expression);\n          const addedPropertiesVariableId = builder.buildCopyPropertiesFrom(arrayVariableID, sourceObject, undefined);\n          index = builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.Add, index, addedPropertiesVariableId);\n        } else {\n          const variable = this.processExpression(context, builder, element);\n          builder.buildSetPropertyValue(arrayVariableID, index, variable);\n          index = builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.Inc, index);\n        }\n      }\n    }\n\n    return arrayVariableID;\n  }\n\n  processArrayLiteralExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ArrayLiteralExpression,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n    return this.buildArrayWithElements(context, builder, node.elements);\n  }\n\n  processNewExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.NewExpression,\n  ): NativeCompilerBuilderVariableID {\n    const variable = this.processExpression(context, builder, node.expression);\n    this.appendNodeDebugInfo(builder, node);\n\n    if (node.arguments && this.hasSpreadElement(node.arguments)) {\n      const arrayArguments = this.buildArrayWithElements(context, builder, node.arguments);\n      return builder.buildConstructorInvocationWithArgsArray(variable, variable, arrayArguments);\n    } else {\n      const inputArgs: NativeCompilerBuilderVariableID[] = [];\n\n      if (node.arguments) {\n        node.arguments.forEach((e) => {\n          let variable = this.processExpression(context, builder, e);\n          inputArgs.push(variable);\n        });\n      }\n      return builder.buildConstructorInvocation(variable, variable, inputArgs);\n    }\n  }\n\n  private buildConditionalVariable(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    buildConditionVariable: (\n      context: NativeCompilerContext,\n      builder: INativeCompilerBlockBuilder,\n    ) => NativeCompilerBuilderVariableID,\n    buildTrueResult: (\n      context: NativeCompilerContext,\n      builder: INativeCompilerBlockBuilder,\n    ) => NativeCompilerBuilderVariableID,\n    buildFalseResult: (\n      context: NativeCompilerContext,\n      builder: INativeCompilerBlockBuilder,\n    ) => NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    const outputVariable = builder.buildAssignableUndefined();\n    const condition = builder.buildJumpTarget('condition');\n    const trueTarget = builder.buildJumpTarget('condition_true');\n    const falseTarget = builder.buildJumpTarget('condition_false');\n    const exit = builder.buildJumpTarget('exit');\n\n    const conditionVariable = buildConditionVariable(context, condition.builder);\n\n    const whenTrueVariable = buildTrueResult(context, trueTarget.builder);\n    trueTarget.builder.buildAssignment(outputVariable, whenTrueVariable);\n    trueTarget.builder.buildJump(exit.target);\n\n    const whenFalseVariable = buildFalseResult(context, falseTarget.builder);\n    falseTarget.builder.buildAssignment(outputVariable, whenFalseVariable);\n    falseTarget.builder.buildJump(exit.target);\n\n    condition.builder.buildBranch(\n      conditionVariable,\n      NativeCompilerBuilderBranchType.Truthy,\n      trueTarget.target,\n      falseTarget.target,\n    );\n\n    return outputVariable;\n  }\n\n  processConditionalExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ConditionalExpression,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n\n    return this.buildConditionalVariable(\n      context,\n      builder,\n      (context, builder) => {\n        return this.processExpression(context, builder, node.condition);\n      },\n      (context, builder) => {\n        return this.processExpression(context, builder, node.whenTrue);\n      },\n      (context, builder) => {\n        return this.processExpression(context, builder, node.whenFalse);\n      },\n    );\n  }\n\n  processAsExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.AsExpression,\n  ): NativeCompilerBuilderVariableID {\n    return this.processExpression(context, builder, node.expression);\n  }\n\n  processTypeOfExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.TypeOfExpression,\n  ): NativeCompilerBuilderVariableID {\n    const variable = this.processExpression(context, builder, node.expression);\n    return builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.TypeOf, variable);\n  }\n\n  processRegularExpressionLiteral(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.RegularExpressionLiteral,\n  ): NativeCompilerBuilderVariableID {\n    const regexCtor = this.getGlobalVariable(context, builder, 'RegExp');\n\n    const inputRegEx = node.text;\n\n    if (inputRegEx[0] !== '/') {\n      this.onError(node, 'Expecting RegEx literal to start with /');\n    }\n\n    let regExToString = inputRegEx.substring(1);\n    let flags = '';\n    for (;;) {\n      if (!regExToString.length) {\n        this.onError(node, 'Expecting RegEx literal to end with /');\n      }\n\n      const trailing = regExToString[regExToString.length - 1];\n      regExToString = regExToString.substring(0, regExToString.length - 1);\n      if (trailing === '/') {\n        break;\n      } else {\n        flags = trailing + flags;\n      }\n    }\n\n    regExToString = regExToString.replace(/\\\\/g, '\\\\\\\\');\n\n    const literalString = this.registerAndGetStringLiteralValue(builder, regExToString);\n\n    if (flags) {\n      const flagsLiteral = this.registerAndGetStringLiteralValue(builder, flags);\n      return builder.buildConstructorInvocation(regexCtor.variable, regexCtor.variable, [literalString, flagsLiteral]);\n    } else {\n      return builder.buildConstructorInvocation(regexCtor.variable, regexCtor.variable, [literalString]);\n    }\n  }\n\n  processReturnStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ReturnStatement,\n  ) {\n    let returnVariableID: NativeCompilerBuilderVariableID;\n    if (node.expression) {\n      returnVariableID = this.processExpression(context, builder, node.expression);\n    } else {\n      returnVariableID = builder.buildUndefined();\n    }\n    builder.buildReturn(returnVariableID);\n  }\n\n  processThrowStatement(context: NativeCompilerContext, builder: INativeCompilerBlockBuilder, node: ts.ThrowStatement) {\n    const exceptionObject = this.processExpression(context, builder, node.expression);\n    builder.buildThrow(exceptionObject);\n  }\n\n  processBreakStatement(builder: INativeCompilerBlockBuilder, node: ts.BreakStatement) {\n    const exitTarget = builder.resolveExitTargetInScope();\n    if (exitTarget === undefined) {\n      this.onError(node, 'Could not resolve exit target to process break statement');\n    }\n\n    builder.buildJump(exitTarget);\n  }\n\n  processTryStatement(context: NativeCompilerContext, builder: INativeCompilerBlockBuilder, node: ts.TryStatement) {\n    const hasCatchClause = !!node.catchClause;\n    const hasFinallyBlock = !!node.finallyBlock;\n    const tryCatch = builder.buildTryCatch(hasCatchClause, hasFinallyBlock);\n\n    this.processBlock(context, tryCatch.tryBuilder, node.tryBlock);\n\n    if (hasCatchClause) {\n      const catchBuilder = tryCatch.catchBuilder!;\n      this.appendNodeDebugInfo(catchBuilder, node.catchClause);\n      const exceptionVariable = catchBuilder.buildGetException();\n\n      if (node.catchClause.variableDeclaration) {\n        const variableDeclaration = node.catchClause.variableDeclaration;\n        if (!ts.isIdentifier(variableDeclaration.name)) {\n          this.onError(variableDeclaration.name, 'Parsers does not currently support statement type');\n        }\n\n        const variableName = variableDeclaration.name.text;\n\n        catchBuilder.buildInitializedVariableRef(variableName, exceptionVariable, VariableRefScope.Block);\n      }\n\n      this.processBlock(context, catchBuilder, node.catchClause.block);\n    }\n\n    if (hasFinallyBlock) {\n      this.processBlock(context, tryCatch.finallyBuilder!, node.finallyBlock);\n    }\n  }\n\n  processSwitchStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.SwitchStatement,\n  ) {\n    this.appendNodeDebugInfo(builder, node);\n    builder = builder.buildSubBuilder(true);\n    const switchStartJumpTarget = builder.buildJumpTarget('switch_enter');\n    const jumpTargets: INativeCompilerJumpTargetBuilder[] = [];\n    let defaultClauseJumpTarget: INativeCompilerJumpTargetBuilder | undefined;\n\n    let switchCaseIndex = 0;\n    for (const switchClause of node.caseBlock.clauses) {\n      if (ts.isDefaultClause(switchClause)) {\n        defaultClauseJumpTarget = builder.buildJumpTarget('switch_clause_default');\n      } else {\n        jumpTargets.push(builder.buildJumpTarget(`switch_clause_${switchCaseIndex}`));\n        switchCaseIndex++;\n      }\n    }\n\n    const exitJumpTarget = builder.buildJumpTarget('switch_exit');\n\n    this.appendNodeDebugInfo(switchStartJumpTarget.builder, node.expression);\n    const lhs = this.processExpression(context, switchStartJumpTarget.builder, node.expression);\n\n    switchCaseIndex = 0;\n\n    for (const switchClause of node.caseBlock.clauses) {\n      if (ts.isDefaultClause(switchClause)) {\n        const jumpTarget = defaultClauseJumpTarget!;\n\n        jumpTarget.builder.registerExitTargetInScope(exitJumpTarget.target);\n\n        this.appendNodeDebugInfo(switchStartJumpTarget.builder, switchClause);\n\n        this.processStatementsInBlock(context, jumpTarget.builder, switchClause.statements);\n      } else {\n        const jumpTarget = jumpTargets[switchCaseIndex];\n\n        jumpTarget.builder.registerExitTargetInScope(exitJumpTarget.target);\n\n        this.appendNodeDebugInfo(switchStartJumpTarget.builder, switchClause);\n\n        const rhs = this.processExpression(context, switchStartJumpTarget.builder, switchClause.expression);\n        const conditionVariable = switchStartJumpTarget.builder.buildBinaryOp(\n          NativeCompilerIR.BinaryOperator.EqualEqualEqual,\n          lhs,\n          rhs,\n        );\n\n        this.processStatementsInBlock(context, jumpTarget.builder, switchClause.statements);\n\n        switchStartJumpTarget.builder.buildBranch(\n          conditionVariable,\n          NativeCompilerBuilderBranchType.Truthy,\n          jumpTarget.target,\n          undefined,\n        );\n\n        switchCaseIndex++;\n      }\n    }\n\n    if (defaultClauseJumpTarget) {\n      switchStartJumpTarget.builder.buildJump(defaultClauseJumpTarget.target);\n    } else {\n      switchStartJumpTarget.builder.buildJump(exitJumpTarget.target);\n    }\n  }\n\n  processStatementsInBlock(\n    context: NativeCompilerContext,\n    scopedBuilder: INativeCompilerBlockBuilder,\n    statements: ts.NodeArray<ts.Statement> | ts.Statement[],\n    cb?: (statement: ts.Statement) => void,\n  ): void {\n    const compilationPlan: CompilationPlan = {\n      functionDeclarationInsertionIndex: 0,\n      statementsToProcess: [],\n    };\n    // Process all the statements that require to emit variable refs\n    for (const statement of statements) {\n      this.prepareStatement(compilationPlan, scopedBuilder, statement);\n    }\n\n    for (const statement of compilationPlan.statementsToProcess) {\n      this.processStatement(context, scopedBuilder, statement);\n      cb?.(statement);\n    }\n  }\n\n  processBlock(context: NativeCompilerContext, builder: INativeCompilerBlockBuilder, node: ts.Block) {\n    const subBuilder = builder.buildSubBuilder(true);\n\n    this.processStatementsInBlock(context, subBuilder, node.statements);\n  }\n\n  processSourceFile(initFunctionName: string, node: ts.SourceFile) {\n    const functionBuilder = this.moduleBuilder.buildFunction(initFunctionName, undefined, true, false, false);\n    const builder = functionBuilder.builder;\n\n    // require is passed as first parameter\n    builder.registerLazyVariableRef('require', VariableRefScope.Function, (builder) =>\n      builder.buildInitializedVariableRef('require', builder.buildGetFunctionArg(0), VariableRefScope.Function),\n    );\n    // module is passed as second parameter\n    builder.registerLazyVariableRef('module', VariableRefScope.Function, (builder) =>\n      builder.buildInitializedVariableRef('module', builder.buildGetFunctionArg(1), VariableRefScope.Function),\n    );\n    // exports is passed as third parameter\n    const exportsVarRef = builder.buildInitializedVariableRef(\n      'exports',\n      builder.buildGetFunctionArg(2),\n      VariableRefScope.Function,\n    );\n    builder.registerExportsVariableRef(exportsVarRef);\n\n    let emitResolver: EmitResolver | undefined;\n    if (this.filePath.endsWith('.ts') || this.filePath.endsWith('.tsx')) {\n      emitResolver = getEmitResolver(this.typeChecker, node, undefined);\n    }\n\n    const context = new NativeCompilerContext(new NamePath(this.moduleName), undefined, emitResolver, false, false);\n\n    this.processStatementsInBlock(context, builder, node.statements);\n  }\n\n  processObjectLiteralExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ObjectLiteralExpression,\n  ) {\n    this.appendNodeDebugInfo(builder, node);\n    const objectVariableID = builder.buildNewObject();\n\n    interface BatchedProp {\n      propId: NativeCompilerBuilderAtomID | NativeCompilerBuilderVariableID;\n      thisVar: NativeCompilerBuilderVariableID;\n      valueVar: NativeCompilerBuilderVariableID;\n    }\n\n    let batchedProps: BatchedProp[] = [];\n    const flush = () => {\n      if (batchedProps.length > 1 && batchedProps.every((p) => p.propId instanceof NativeCompilerBuilderAtomID)) {\n        const propNames = batchedProps.map((p) => p.propId as NativeCompilerBuilderAtomID);\n        const propVals = batchedProps.map((p) => p.valueVar);\n        builder.buildSetProperties(batchedProps[0].thisVar, propNames, propVals);\n      } else {\n        for (const prop of batchedProps) {\n          this.doBuildSetProperty(context, builder, prop.propId, prop.thisVar, prop.valueVar);\n        }\n      }\n      batchedProps = [];\n    };\n\n    for (const property of node.properties) {\n      if (ts.isPropertyAssignment(property)) {\n        const { propertyVariableID, propertyInitVariableID } = this.processPropertyAssignment(\n          context,\n          builder,\n          property,\n        );\n        batchedProps.push({ propId: propertyVariableID, thisVar: objectVariableID, valueVar: propertyInitVariableID });\n        if (!this.options.mergeSetProperties) {\n          flush();\n        }\n      } else if (ts.isShorthandPropertyAssignment(property)) {\n        const propertyVariableID = this.processPropertyName(context, builder, property.name);\n        const propertyInitVariableID = this.processIdentifier(context, builder, property.name);\n        batchedProps.push({ propId: propertyVariableID, thisVar: objectVariableID, valueVar: propertyInitVariableID });\n        if (!this.options.mergeSetProperties) {\n          flush();\n        }\n      } else if (ts.isSpreadAssignment(property)) {\n        const spreadAssigment: ts.SpreadAssignment = property;\n        const sourceObject = this.processExpression(context, builder, spreadAssigment.expression);\n        flush();\n        builder.buildCopyPropertiesFrom(objectVariableID, sourceObject, undefined);\n      } else if (ts.isMethodDeclaration(property)) {\n        const propertyName = this.processPropertyName(context, builder, property.name);\n\n        const functionVariableID = this.doProcessFunctionDeclaration(\n          context,\n          builder,\n          ts.isIdentifier(property.name) ? property.name : undefined,\n          undefined,\n          true,\n          false,\n          false,\n          undefined,\n          (context, builder) => {\n            this.processParameterDeclarations(context, builder, property.parameters, property, false, undefined);\n            const isGenerator = !!property.asteriskToken;\n            const isAsync = !!property.modifiers?.some((m) => m.kind == ts.SyntaxKind.AsyncKeyword);\n            if (property.body) {\n              this.processFunctionBody(context, builder, property.body, isGenerator, isAsync);\n            }\n            return property.parameters.length;\n          },\n        );\n        batchedProps.push({ propId: propertyName, thisVar: objectVariableID, valueVar: functionVariableID });\n        if (!this.options.mergeSetProperties) {\n          flush();\n        }\n      } else {\n        this.onError(property, 'Failed to process literal object expression');\n      }\n    }\n    flush();\n\n    return objectVariableID;\n  }\n\n  processPropertyAssignment(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PropertyAssignment,\n  ) {\n    const newNamePath = context.namePath.appendingTSNode(node.name);\n    const propertyVariableID = this.processPropertyName(context, builder, node.name);\n    const propertyInitVariableID = this.processExpression(context.withNamePath(newNamePath), builder, node.initializer);\n\n    return { propertyVariableID: propertyVariableID, propertyInitVariableID: propertyInitVariableID };\n  }\n\n  processPropertyName(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PropertyName,\n  ): NativeCompilerBuilderAtomID | NativeCompilerBuilderVariableID {\n    if (ts.isIdentifier(node)) {\n      return this.processIdentifierAsAtom(builder, node);\n    } else if (ts.isStringLiteralLike(node)) {\n      return this.processStringLiteral(builder, node as ts.StringLiteral);\n    } else if (ts.isComputedPropertyName(node)) {\n      return this.processExpression(context, builder, node.expression);\n    } else if (ts.isNumericLiteral(node)) {\n      return this.processNumericalLiteral(builder, node);\n    } else {\n      this.onError(node, 'Failed to process property name');\n    }\n  }\n\n  private appendSetPropertyIfNeeded(\n    assignmentTracker: AssignmentTracker,\n    builder: INativeCompilerBlockBuilder,\n    variable: NativeCompilerBuilderVariableID,\n  ) {\n    const assignments = assignmentTracker.assignments;\n    if (!assignments.length) {\n      return;\n    }\n\n    const lastAssigment = assignments[assignments.length - 1];\n    if (lastAssigment.property instanceof NativeCompilerBuilderAtomID) {\n      builder.buildSetProperty(lastAssigment.object, lastAssigment.property, variable);\n    } else {\n      builder.buildSetPropertyValue(lastAssigment.object, lastAssigment.property, variable);\n    }\n  }\n\n  processPrefixUnaryExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PrefixUnaryExpression,\n  ) {\n    this.appendNodeDebugInfo(builder, node);\n    const assignmentTracker = new AssignmentTracker();\n    const operandVariableID = this.processExpression(\n      context.withAssignmentTracker(assignmentTracker),\n      builder,\n      node.operand,\n    );\n    if (node.operator == ts.SyntaxKind.MinusToken) {\n      return builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.Neg, operandVariableID);\n    } else if (node.operator === ts.SyntaxKind.TildeToken) {\n      return builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.BitwiseNot, operandVariableID);\n    } else if (node.operator === ts.SyntaxKind.MinusMinusToken) {\n      const resultVariable = builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.Dec, operandVariableID);\n      builder.buildAssignment(operandVariableID, resultVariable);\n      this.appendSetPropertyIfNeeded(assignmentTracker, builder, resultVariable);\n      return resultVariable;\n    } else if (node.operator === ts.SyntaxKind.PlusPlusToken) {\n      const resultVariable = builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.Inc, operandVariableID);\n      builder.buildAssignment(operandVariableID, resultVariable);\n      this.appendSetPropertyIfNeeded(assignmentTracker, builder, resultVariable);\n      return resultVariable;\n    } else if (node.operator === ts.SyntaxKind.PlusToken) {\n      return builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.Plus, operandVariableID);\n    } else if (node.operator === ts.SyntaxKind.ExclamationToken) {\n      return builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.LogicalNot, operandVariableID);\n    } else {\n      this.onError(node, 'prefixUnary operator is not supported');\n    }\n  }\n\n  private hasSpreadElement(args: ts.NodeArray<ts.Expression>): boolean {\n    for (const arg of args) {\n      if (ts.isSpreadElement(arg)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  private doProcessCall(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Node,\n    fn: NativeCompilerVariableIDWithParent,\n    args: ts.NodeArray<ts.Expression>,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n\n    let retval;\n    if (this.hasSpreadElement(args)) {\n      const arrayArgument = this.buildArrayWithElements(context, builder, args);\n\n      if (isSuperCall(node)) {\n        retval = builder.buildConstructorInvocationWithArgsArray(fn.variable, builder.buildNewTarget(), arrayArgument);\n        builder.buildAssignment(this.processThis(context, builder, node), retval);\n      } else {\n        retval = builder.buildFunctionInvocationWithArgsArray(\n          fn.variable,\n          arrayArgument,\n          fn.parentVariable ?? builder.buildUndefined(),\n        );\n      }\n    } else {\n      if (isSuperCall(node)) {\n        const inputArgs = args.map((arg) => this.processExpression(context, builder, arg));\n        retval = builder.buildConstructorInvocation(fn.variable, builder.buildNewTarget(), inputArgs);\n        builder.buildAssignment(this.processThis(context, builder, node), retval);\n      } else {\n        const inputArgs = args.map((arg) => this.processExpression(context, builder, arg));\n        retval = builder.buildFunctionInvocation(fn.variable, inputArgs, fn.parentVariable ?? builder.buildUndefined());\n      }\n    }\n    return retval;\n  }\n\n  private processCallExpressionEpilogue(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.CallExpression,\n    callee: NativeCompilerVariableIDWithParent,\n  ): NativeCompilerBuilderVariableID {\n    if (node.questionDotToken) {\n      return this.buildQuestionDotExpression(context, builder, callee.variable, (context, builder) => {\n        return this.doProcessCall(context, builder, node, callee, node.arguments);\n      });\n    } else {\n      return this.doProcessCall(context, builder, node, callee, node.arguments);\n    }\n  }\n\n  processCallExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.CallExpression,\n  ): NativeCompilerBuilderVariableID {\n    if (node.expression.kind === ts.SyntaxKind.ImportKeyword) {\n      // Import statement.\n      if (node.arguments.length !== 1) {\n        this.onError(node, 'Expected 1 argument for import expression');\n      }\n\n      // Import module\n      const importedModuleVariable = this.doImportModule(context, builder, node.expression, node.arguments[0]);\n\n      // Return result of Promise.resolve(<imported module>)\n      const promiseCtor = this.getGlobalVariable(context, builder, 'Promise');\n      const resolveFn = builder.buildGetProperty(\n        promiseCtor.variable,\n        this.processIdentifierStringAsAtom(builder, 'resolve'),\n        promiseCtor.variable,\n      );\n      return builder.buildFunctionInvocation(resolveFn, [importedModuleVariable], promiseCtor.variable);\n    }\n\n    if (ts.isPropertyAccessExpression(node.expression)) {\n      // try shortcut builtin functions (e.g. Math.pow)\n      if (this.options.enableIntrinsics && ts.isIdentifier(node.expression.expression)) {\n        const intrinsic = node.expression.expression.text + '.' + node.expression.name.text;\n        if (builder.hasIntrinsicFunction(intrinsic)) {\n          const args = node.arguments.map((a) => this.processExpression(context, builder, a));\n          return builder.buildIntrinsicCall(intrinsic, args);\n        }\n      }\n\n      return this.processPropertyAccessExpressionForCallExpression(\n        context,\n        builder,\n        node.expression,\n        (context, builder, callee) => {\n          return this.processCallExpressionEpilogue(context, builder, node, callee);\n        },\n      );\n    } else {\n      const variable = this.processExpression(context, builder, node.expression);\n      const callee: NativeCompilerVariableIDWithParent = {\n        variable,\n        parentVariable: this.resolveVariableToUseAsThis(context, builder, variable, node.expression),\n      };\n\n      return this.processCallExpressionEpilogue(context, builder, node, callee);\n    }\n  }\n\n  processDeleteExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.DeleteExpression,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n\n    const expression = node.expression;\n    if (ts.isElementAccessExpression(expression)) {\n      let expressionVariable = this.processExpression(context, builder, expression.expression);\n      let argumentExpressionVariable = this.processExpression(context, builder, expression.argumentExpression);\n\n      return builder.buildDeletePropertyValue(expressionVariable, argumentExpressionVariable);\n    } else if (ts.isPropertyAccessExpression(expression)) {\n      return this.doProcessPropertyAccessExpression(\n        context,\n        builder,\n        expression,\n        (context, builder, expressionVariable, nameVariable) => {\n          return builder.buildDeleteProperty(expressionVariable, nameVariable);\n        },\n      );\n    } else {\n      this.onError(expression, 'Expecting element or property access expression');\n    }\n  }\n\n  processAwaitExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.AwaitExpression,\n  ): NativeCompilerBuilderVariableID {\n    let retVal = this.processExpression(context, builder, node.expression);\n    if (context.isAsync && context.isGenerator) {\n      const awaitRet = builder.buildNewObject();\n      builder.buildSetProperty(awaitRet, this.moduleBuilder.registerAtom('await'), retVal);\n      retVal = awaitRet;\n    }\n    return this.processSuspendResume(context, builder, retVal);\n  }\n\n  private processYieldStarExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.YieldExpression,\n  ): NativeCompilerBuilderVariableID {\n    if (node.expression === undefined) {\n      this.onError(node, 'Expecting expression after yield*');\n    }\n    const helper = this.getGlobalVariable(\n      context,\n      builder,\n      context.isAsync ? '__tsn_get_async_iterator' : '__tsn_get_iterator',\n    ).variable;\n    const builderLoop = builder.buildLoop();\n    const iterator = builderLoop.initBuilder.buildFunctionInvocation(\n      helper,\n      [this.processExpression(context, builderLoop.initBuilder, node.expression)],\n      builderLoop.initBuilder.buildUndefined(),\n    );\n    const nextFunc = builderLoop.condBuilder.buildGetProperty(\n      iterator,\n      this.moduleBuilder.registerAtom('next'),\n      iterator,\n    );\n    let iteratorResult;\n    if (context.isAsync) {\n      const promise = builderLoop.condBuilder.buildFunctionInvocation(nextFunc, [], iterator);\n      const awaitable = builderLoop.condBuilder.buildNewObject();\n      builderLoop.condBuilder.buildSetProperty(awaitable, this.moduleBuilder.registerAtom('await'), promise);\n      iteratorResult = this.processSuspendResume(context, builderLoop.condBuilder, awaitable);\n    } else {\n      iteratorResult = builderLoop.condBuilder.buildFunctionInvocation(nextFunc, [], iterator);\n    }\n    builderLoop.condBuilder.buildBranch(\n      builderLoop.condBuilder.buildGetProperty(iteratorResult, this.moduleBuilder.registerAtom('done'), iteratorResult),\n      NativeCompilerBuilderBranchType.Truthy,\n      builderLoop.exitTarget,\n      builderLoop.bodyJumpTargetBuilder.target,\n    );\n    const iteratorValue = builderLoop.bodyJumpTargetBuilder.builder.buildGetProperty(\n      iteratorResult,\n      this.moduleBuilder.registerAtom('value'),\n      iteratorResult,\n    );\n    if (context.isAsync) {\n      const yieldRet = builderLoop.bodyJumpTargetBuilder.builder.buildNewObject();\n      builderLoop.bodyJumpTargetBuilder.builder.buildSetProperty(\n        yieldRet,\n        this.moduleBuilder.registerAtom('yield'),\n        iteratorValue,\n      );\n      return this.processSuspendResume(context, builderLoop.bodyJumpTargetBuilder.builder, yieldRet);\n    } else {\n      return this.processSuspendResume(context, builderLoop.bodyJumpTargetBuilder.builder, iteratorValue);\n    }\n  }\n\n  processYieldExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.YieldExpression,\n  ): NativeCompilerBuilderVariableID {\n    if (node.asteriskToken) {\n      return this.processYieldStarExpression(context, builder, node);\n    }\n    let retVal = node.expression ? this.processExpression(context, builder, node.expression) : builder.buildUndefined();\n    if (context.isAsync && context.isGenerator) {\n      const yieldRet = builder.buildNewObject();\n      builder.buildSetProperty(yieldRet, this.moduleBuilder.registerAtom('yield'), retVal);\n      retVal = yieldRet;\n    }\n    return this.processSuspendResume(context, builder, retVal);\n  }\n\n  private processSuspendResume(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    retVal: NativeCompilerBuilderVariableID,\n  ) {\n    // build a suspend return\n    const suspendBlock = builder.buildSubBuilder(false);\n    const rp = builder.buildJumpTarget('resume_point');\n    suspendBlock.buildSuspend(retVal, rp.target);\n    // and resume with arg\n    return builder.buildResume();\n  }\n\n  processJsxExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.JsxExpression,\n  ): NativeCompilerBuilderVariableID {\n    if (node.expression) {\n      return this.processExpression(context, builder, node.expression);\n    } else {\n      return builder.buildUndefined();\n    }\n  }\n\n  processExpressionStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ExpressionStatement,\n  ) {\n    if (ts.isBinaryExpression(node.expression)) {\n      this.processBinaryExpression(context, builder, node.expression);\n    } else {\n      this.processExpression(context, builder, node.expression);\n    }\n  }\n\n  processElementAccessExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ElementAccessExpression,\n  ) {\n    this.appendNodeDebugInfo(builder, node);\n\n    const constantValue = this.tryProcessEnumConstantValue(context, builder, node);\n    if (constantValue !== undefined) {\n      return constantValue;\n    }\n\n    const doBuild = (\n      context: NativeCompilerContext,\n      builder: INativeCompilerBlockBuilder,\n      expressionVariable: NativeCompilerBuilderVariableID,\n    ) => {\n      let argumentExpressionVariable = this.processExpression(context, builder, node.argumentExpression);\n      if (context.assignmentTracker) {\n        context.assignmentTracker.onGetPropertyValue(expressionVariable, argumentExpressionVariable);\n      }\n      return builder.buildGetPropertyValue(expressionVariable, argumentExpressionVariable, expressionVariable);\n    };\n\n    // use a separate context for the optional chain (call ctor directly to make sure we get a copy)\n    const parentExpressionContext = new NativeCompilerContext(\n      context.namePath,\n      context.assignmentTracker,\n      context.emitResolver,\n      context.isGenerator,\n      context.isAsync,\n    );\n    if (ts.isOptionalChain(node)) {\n      const result = context.optionalChainResult ?? builder.buildAssignableUndefined();\n      if (context.optionalChainExit) {\n        // parent expression share the whole expression's exit and result\n        parentExpressionContext.optionalChainExit = context.optionalChainExit;\n        parentExpressionContext.optionalChainResult = context.optionalChainResult;\n      } else {\n        // start of a new optional chain, create the short circuit jump target\n        const optionalChain = builder.buildJumpTarget('optional_chain');\n        const optionalChainExit = builder.buildJumpTarget('optional_chain_exit');\n        parentExpressionContext.optionalChainExit = optionalChainExit.target;\n        parentExpressionContext.optionalChainResult = result;\n        builder = optionalChain.builder;\n      }\n      let expressionVariable = this.processExpression(parentExpressionContext, builder, node.expression);\n      parentExpressionContext.optionalChainExit = undefined;\n      parentExpressionContext.optionalChainResult = undefined;\n\n      if (node.questionDotToken) {\n        return this.buildQuestionDotExpression(context, builder, expressionVariable, (context, builder) => {\n          return doBuild(context, builder, expressionVariable);\n        });\n      } else {\n        builder.buildAssignment(result, doBuild(context, builder, expressionVariable));\n        return result;\n      }\n    } else {\n      let expressionVariable = this.processExpression(context, builder, node.expression);\n      return doBuild(context, builder, expressionVariable);\n    }\n  }\n\n  processForStatement(context: NativeCompilerContext, builder: INativeCompilerBlockBuilder, node: ts.ForStatement) {\n    this.appendNodeDebugInfo(builder, node);\n\n    const builderLoop = builder.buildLoop();\n\n    if (node.initializer) {\n      if (ts.isVariableDeclarationList(node.initializer)) {\n        this.prepareVariableDeclarationList(builderLoop.initBuilder, node.initializer);\n        this.processVariableDeclarationList(context, builderLoop.initBuilder, node.initializer);\n      } else {\n        this.processExpression(context, builderLoop.initBuilder, node.initializer);\n      }\n    }\n\n    if (node.condition) {\n      let conditionVariable = this.processExpression(context, builderLoop.condBuilder, node.condition);\n      builderLoop.condBuilder.buildBranch(\n        conditionVariable,\n        NativeCompilerBuilderBranchType.Truthy,\n        builderLoop.bodyJumpTargetBuilder.target,\n        builderLoop.exitTarget,\n      );\n    }\n\n    this.processStatement(context, builderLoop.bodyJumpTargetBuilder.builder, node.statement);\n\n    if (node.incrementor) {\n      this.processExpression(context, builderLoop.bodyJumpTargetBuilder.builder, node.incrementor);\n    }\n  }\n\n  processIfStatement(context: NativeCompilerContext, builder: INativeCompilerBlockBuilder, node: ts.IfStatement) {\n    this.appendNodeDebugInfo(builder, node);\n    const condition = builder.buildJumpTarget('condition');\n    const conditionVariable = this.processExpression(context, condition.builder, node.expression);\n\n    const trueTarget = builder.buildJumpTarget('true');\n    const elseTarget = builder.buildJumpTarget('false');\n    const exit = builder.buildJumpTarget('exit');\n\n    this.processStatement(context, trueTarget.builder, node.thenStatement);\n\n    if (node.elseStatement) {\n      this.processStatement(context, elseTarget.builder, node.elseStatement);\n    }\n\n    condition.builder.buildBranch(\n      conditionVariable,\n      NativeCompilerBuilderBranchType.Truthy,\n      trueTarget.target,\n      elseTarget.target,\n    );\n    trueTarget.builder.buildJump(exit.target);\n  }\n\n  processWhileStatement(context: NativeCompilerContext, builder: INativeCompilerBlockBuilder, node: ts.WhileStatement) {\n    this.appendNodeDebugInfo(builder, node);\n\n    const builderLoop = builder.buildLoop();\n\n    const conditionVariable = this.processExpression(context, builderLoop.condBuilder, node.expression);\n    builderLoop.condBuilder.buildBranch(\n      conditionVariable,\n      NativeCompilerBuilderBranchType.Truthy,\n      builderLoop.bodyJumpTargetBuilder.target,\n      builderLoop.exitTarget,\n    );\n\n    this.processStatement(context, builderLoop.bodyJumpTargetBuilder.builder, node.statement);\n  }\n\n  processPostfixUnaryExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PostfixUnaryExpression,\n  ) {\n    this.appendNodeDebugInfo(builder, node);\n    const assignmentTracker = new AssignmentTracker();\n    const operandVariableID = this.processExpression(\n      context.withAssignmentTracker(assignmentTracker),\n      builder,\n      node.operand,\n    );\n    const copiedVariable = builder.buildCopy(operandVariableID);\n    let intermediate: NativeCompilerBuilderVariableID;\n\n    if (node.operator == ts.SyntaxKind.PlusPlusToken) {\n      intermediate = builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.Inc, operandVariableID);\n    } else if (node.operator === ts.SyntaxKind.MinusMinusToken) {\n      intermediate = builder.buildUnaryOp(NativeCompilerIR.UnaryOperator.Dec, operandVariableID);\n    } else {\n      this.onError(node, 'prefixUnary operator is not supported');\n    }\n    builder.buildAssignment(operandVariableID, intermediate);\n    this.appendSetPropertyIfNeeded(assignmentTracker, builder, intermediate);\n    return copiedVariable;\n  }\n\n  processParenthesizedExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ParenthesizedExpression,\n  ) {\n    this.appendNodeDebugInfo(builder, node);\n    return this.processExpression(context, builder, node.expression);\n  }\n\n  processTemplateLiteralToken(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.TemplateLiteralToken,\n  ): NativeCompilerBuilderVariableID {\n    if (node.rawText) {\n      return this.registerAndGetStringLiteralValue(builder, node.rawText);\n    } else {\n      return this.registerAndGetStringLiteralValue(builder, '');\n    }\n  }\n\n  processTemplateExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.TemplateExpression,\n  ): NativeCompilerBuilderVariableID {\n    this.appendNodeDebugInfo(builder, node);\n    let stringVariableId = this.processTemplateLiteralToken(context, builder, node.head);\n\n    for (const span of node.templateSpans) {\n      const expressionVariable = this.processExpression(context, builder, span.expression);\n      stringVariableId = builder.buildBinaryOp(\n        NativeCompilerIR.BinaryOperator.Add,\n        stringVariableId,\n        expressionVariable,\n      );\n\n      if (span.literal.rawText) {\n        const spanValue = this.processTemplateLiteralToken(context, builder, span.literal);\n        stringVariableId = builder.buildBinaryOp(NativeCompilerIR.BinaryOperator.Add, stringVariableId, spanValue);\n      }\n    }\n\n    return stringVariableId;\n  }\n\n  processNonNullExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.NonNullExpression,\n  ): NativeCompilerBuilderVariableID {\n    return this.processExpression(context, builder, node.expression);\n  }\n\n  processVoidExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.VoidExpression,\n  ): NativeCompilerBuilderVariableID {\n    this.processExpression(context, builder, node.expression);\n    return builder.buildUndefined();\n  }\n\n  processTypeAssertion(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.TypeAssertion,\n  ): NativeCompilerBuilderVariableID {\n    return this.processExpression(context, builder, node.expression);\n  }\n\n  processExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Expression,\n  ): NativeCompilerBuilderVariableID {\n    if (node.kind === ts.SyntaxKind.NullKeyword) {\n      return this.processNullKeyword(builder, node);\n    } else if (node.kind === ts.SyntaxKind.UndefinedKeyword) {\n      return this.processUndefinedKeyword(builder, node);\n    } else if (node.kind === ts.SyntaxKind.FalseKeyword) {\n      return this.processFalseKeyword(builder, node);\n    } else if (node.kind === ts.SyntaxKind.TrueKeyword) {\n      return this.procssTrueKeyword(builder, node);\n    } else if (node.kind === ts.SyntaxKind.ThisKeyword) {\n      return this.processThis(context, builder, node as ts.ThisExpression);\n    } else if (node.kind === ts.SyntaxKind.SuperKeyword) {\n      return this.processSuperKeyword(context, builder, node);\n    } else if (ts.isIdentifier(node)) {\n      return this.processIdentifier(context, builder, node);\n    } else if (ts.isNumericLiteral(node)) {\n      return this.processNumericalLiteral(builder, node);\n    } else if (ts.isStringLiteral(node)) {\n      return this.processStringLiteral(builder, node);\n    } else if (ts.isPropertyAccessExpression(node)) {\n      return this.processPropertyAccessExpression(context, builder, node);\n    } else if (ts.isBinaryExpression(node)) {\n      return this.processBinaryExpression(context, builder, node);\n    } else if (ts.isObjectLiteralExpression(node)) {\n      return this.processObjectLiteralExpression(context, builder, node);\n    } else if (ts.isPrefixUnaryExpression(node)) {\n      return this.processPrefixUnaryExpression(context, builder, node);\n    } else if (ts.isCallExpression(node)) {\n      return this.processCallExpression(context, builder, node);\n    } else if (ts.isElementAccessExpression(node)) {\n      return this.processElementAccessExpression(context, builder, node);\n    } else if (ts.isPostfixUnaryExpression(node)) {\n      return this.processPostfixUnaryExpression(context, builder, node);\n    } else if (ts.isParenthesizedExpression(node)) {\n      return this.processParenthesizedExpression(context, builder, node);\n    } else if (ts.isArrowFunction(node)) {\n      return this.processArrowFunction(context, builder, node);\n    } else if (ts.isArrayLiteralExpression(node)) {\n      return this.processArrayLiteralExpression(context, builder, node);\n    } else if (ts.isNewExpression(node)) {\n      return this.processNewExpression(context, builder, node);\n    } else if (ts.isFunctionExpression(node)) {\n      return this.processFunctionExpression(context, builder, node);\n    } else if (ts.isConditionalExpression(node)) {\n      return this.processConditionalExpression(context, builder, node);\n    } else if (ts.isAsExpression(node)) {\n      return this.processAsExpression(context, builder, node);\n    } else if (ts.isTypeOfExpression(node)) {\n      return this.processTypeOfExpression(context, builder, node);\n    } else if (ts.isRegularExpressionLiteral(node)) {\n      return this.processRegularExpressionLiteral(context, builder, node);\n    } else if (ts.isTemplateLiteralToken(node)) {\n      return this.processTemplateLiteralToken(context, builder, node);\n    } else if (ts.isTemplateExpression(node)) {\n      return this.processTemplateExpression(context, builder, node);\n    } else if (ts.isNonNullExpression(node)) {\n      return this.processNonNullExpression(context, builder, node);\n    } else if (ts.isClassExpression(node)) {\n      return this.processClassExpression(context, builder, node);\n    } else if (ts.isVoidExpression(node)) {\n      return this.processVoidExpression(context, builder, node);\n    } else if (ts.isTypeAssertionExpression(node)) {\n      return this.processTypeAssertion(context, builder, node);\n    } else if (ts.isDeleteExpression(node)) {\n      return this.processDeleteExpression(context, builder, node);\n    } else if (ts.isAwaitExpression(node)) {\n      return this.processAwaitExpression(context, builder, node);\n    } else if (ts.isYieldExpression(node)) {\n      return this.processYieldExpression(context, builder, node);\n    } else if (ts.isJsxExpression(node)) {\n      return this.processJsxExpression(context, builder, node);\n    } else if (\n      ts.isMetaProperty(node) &&\n      node.keywordToken === ts.SyntaxKind.NewKeyword &&\n      node.name.text === 'target'\n    ) {\n      // new.target\n      return builder.buildNewTarget();\n    } else {\n      this.onError(node, 'Expression not supported');\n    }\n  }\n\n  processClassLikeDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ClassLikeDeclaration,\n    isExpression: boolean,\n  ): NativeCompilerBuilderVariableID {\n    let parentClass: NativeCompilerBuilderVariableID | undefined;\n    if (node.heritageClauses) {\n      for (const heritageClause of node.heritageClauses) {\n        if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword) {\n          if (parentClass || heritageClause.types.length !== 1) {\n            this.onError(heritageClause, `Found more than one inherited type`);\n          }\n\n          const inheritedType = heritageClause.types[0];\n          parentClass = this.processExpression(context, builder, inheritedType.expression);\n        }\n      }\n    }\n\n    let ctorDeclaration: ts.ConstructorDeclaration | undefined;\n    const propertiesToInitialize: [Boolean, ts.PropertyDeclaration][] = [];\n    const pendingClassElementsToProcess: [boolean, ts.ClassElement][] = [];\n\n    for (const classElement of node.members) {\n      const modifiers = ts.getCombinedModifierFlags(classElement);\n      if (modifiers & ts.ModifierFlags.Abstract) {\n        continue;\n      }\n\n      const isStatic = (modifiers & ts.ModifierFlags.Static) != 0;\n\n      if (ts.isConstructorDeclaration(classElement)) {\n        ctorDeclaration = classElement;\n        continue;\n      }\n      if (ts.isPropertyDeclaration(classElement)) {\n        if (classElement.initializer) {\n          propertiesToInitialize.push([isStatic, classElement]);\n        }\n        continue;\n      }\n\n      pendingClassElementsToProcess.push([isStatic, classElement]);\n    }\n\n    this.appendNodeDebugInfo(builder, node);\n\n    let methodNamePath = context.namePath;\n\n    const constructorVariableID = this.doProcessFunctionDeclaration(\n      context,\n      builder,\n      node.name,\n      undefined,\n      false,\n      true,\n      isExpression,\n      parentClass,\n      (context, builder) => {\n        methodNamePath = context.namePath;\n\n        let ctorStatements: ts.Statement[] = [];\n        if (ctorDeclaration && ctorDeclaration.body) {\n          const ctorBodyStatements = ctorDeclaration.body.statements;\n          for (const ctorBodyStatement of ctorBodyStatements) {\n            ctorStatements.push(ctorBodyStatement);\n          }\n        }\n\n        const propertyInitializers: Array<\n          (context: NativeCompilerContext, builder: INativeCompilerBlockBuilder) => void\n        > = [];\n\n        // ctor parameters\n        if (ctorDeclaration) {\n          this.processParameterDeclarations(\n            context,\n            builder,\n            ctorDeclaration.parameters,\n            ctorDeclaration,\n            false,\n            (deferredStatement) => {\n              propertyInitializers.push(deferredStatement);\n            },\n          );\n        }\n        // Properties\n        for (const [isStatic, propertyDeclaration] of propertiesToInitialize) {\n          if (!isStatic) {\n            propertyInitializers.push((context, builder) => {\n              this.processPropertyDeclaration(\n                context,\n                builder,\n                propertyDeclaration,\n                this.processThis(context, builder, propertyDeclaration),\n              );\n            });\n          }\n        }\n\n        // There is no super call in the constructor\n        if (!ctorStatements.some(statementHasSuperCall)) {\n          let thisValue;\n          if (parentClass) {\n            // class has base but no super call\n            // synthetize a super() call\n            const superCtor = builder.buildGetSuperConstructor();\n            thisValue = builder.buildConstructorInvocationWithArgsArray(\n              superCtor,\n              builder.buildNewTarget(),\n              builder.buildGetFunctionArgumentsObject(0),\n            );\n          } else {\n            // no base class\n            // create empty object from prototype\n            thisValue = builder.buildConstructorInvocation(\n              this.processUndefinedKeyword(builder, node),\n              builder.buildNewTarget(),\n              [],\n            );\n          }\n          // init the 'this' reference\n          builder.buildAssignment(this.processThis(context, builder, node), thisValue);\n          // init members\n          for (const initializer of propertyInitializers) {\n            initializer(context, builder);\n          }\n        }\n\n        const ctorContext = context.withNamePath(context.namePath.appending(CONSTRUCTOR_NAME));\n\n        // Process the body of the constructor method\n        this.processStatementsInBlock(ctorContext, builder, ctorStatements, (statement) => {\n          // Run initializers after processing a top level super call\n          // (non-toplevel super calls cannot have initialized properties, so no need to worry aobut them)\n          if (getSuperCallFromStatement(statement) !== undefined) {\n            for (const initializer of propertyInitializers) {\n              initializer(context, builder);\n            }\n          }\n        });\n\n        builder.buildReturn(this.processThis(context, builder, node));\n        return ctorDeclaration?.parameters.length ?? 0;\n      },\n    );\n\n    const methodContext = context.withNamePath(methodNamePath);\n\n    // Append method and property getters and setters\n    for (const [isStatic, classElement] of pendingClassElementsToProcess) {\n      if (ts.isGetAccessorDeclaration(classElement)) {\n        this.processGetAccessorDeclaration(methodContext, builder, classElement, constructorVariableID, isStatic);\n      } else if (ts.isSetAccessorDeclaration(classElement)) {\n        this.processSetAccessorDeclaration(methodContext, builder, classElement, constructorVariableID, isStatic);\n      } else if (ts.isMethodDeclaration(classElement)) {\n        this.processMethodDeclaration(methodContext, builder, classElement, constructorVariableID, isStatic);\n      } else if (ts.isSemicolonClassElement(classElement)) {\n        // semicolon is allowed in class but does nothing\n      } else {\n        this.onError(classElement, 'Unrecognized class element type');\n      }\n    }\n\n    this.appendExportedDeclarationIfNeeded(context, builder, node, node.name, constructorVariableID);\n\n    // Append static properties\n\n    for (const [isStatic, propertyDeclaration] of propertiesToInitialize) {\n      if (isStatic) {\n        this.processPropertyDeclaration(methodContext, builder, propertyDeclaration, constructorVariableID);\n      }\n    }\n\n    return constructorVariableID;\n  }\n\n  processClassDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ClassDeclaration,\n  ): void {\n    this.processClassLikeDeclaration(context, builder, node, false);\n  }\n\n  processClassExpression(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ClassExpression,\n  ): NativeCompilerBuilderVariableID {\n    return this.processClassLikeDeclaration(context, builder, node, true);\n  }\n\n  private processClassElement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.MethodDeclaration | ts.GetAccessorDeclaration | ts.SetAccessorDeclaration,\n    type: NativeCompilerIR.ClassElementType,\n    namePathPrefix: string | undefined,\n    classVariable: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    name: ts.PropertyName,\n  ): void {\n    if (!node.body) {\n      return;\n    }\n\n    const propertyName = this.processPropertyName(context, builder, name);\n\n    this.appendNodeDebugInfo(builder, node);\n\n    const functionVariableID = this.doProcessFunctionDeclaration(\n      context,\n      builder,\n      ts.isIdentifier(name) ? name : undefined,\n      namePathPrefix,\n      true,\n      false,\n      false,\n      undefined,\n      (context, builder) => {\n        this.processParameterDeclarations(context, builder, node.parameters, node, false, undefined);\n        if (node.body) {\n          const isGenerator = !!node.asteriskToken;\n          const isAsync = !!node.modifiers?.some((m) => m.kind == ts.SyntaxKind.AsyncKeyword);\n          this.processFunctionBody(context, builder, node.body, isGenerator, isAsync);\n        }\n        return node.parameters.length;\n      },\n    );\n\n    if (propertyName instanceof NativeCompilerBuilderVariableID) {\n      builder.buildSetClassElementValue(type, classVariable, propertyName, functionVariableID, isStatic);\n    } else {\n      builder.buildSetClassElement(type, classVariable, propertyName, functionVariableID, isStatic);\n    }\n  }\n\n  private processMethodDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.MethodDeclaration,\n    classVariable: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n  ) {\n    this.processClassElement(\n      context,\n      builder,\n      node,\n      NativeCompilerIR.ClassElementType.Method,\n      undefined,\n      classVariable,\n      isStatic,\n      node.name,\n    );\n  }\n\n  private processGetAccessorDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.GetAccessorDeclaration,\n    classVariable: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n  ): void {\n    this.processClassElement(\n      context,\n      builder,\n      node,\n      NativeCompilerIR.ClassElementType.Getter,\n      '_get__',\n      classVariable,\n      isStatic,\n      node.name,\n    );\n  }\n\n  private processSetAccessorDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.SetAccessorDeclaration,\n    classVariable: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n  ): void {\n    this.processClassElement(\n      context,\n      builder,\n      node,\n      NativeCompilerIR.ClassElementType.Setter,\n      '_set__',\n      classVariable,\n      isStatic,\n      node.name,\n    );\n  }\n\n  private processPropertyDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.PropertyDeclaration,\n    thisVariable: NativeCompilerBuilderVariableID,\n  ): void {\n    if (!node.initializer) {\n      // Nothing to do for a property that is declared but is not initialized\n      return;\n    }\n\n    this.appendNodeDebugInfo(builder, node);\n\n    const propertyName = node.name;\n    const nameVariable = this.processPropertyName(context, builder, propertyName);\n\n    const newNamePath = context.namePath.appendingTSNode(propertyName);\n    const expressionVariable = this.processExpression(context.withNamePath(newNamePath), builder, node.initializer);\n\n    this.doBuildSetProperty(context, builder, nameVariable, thisVariable, expressionVariable);\n  }\n\n  private doBuildSetProperty(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    propertyName: NativeCompilerBuilderAtomID | NativeCompilerBuilderVariableID,\n    thisVariable: NativeCompilerBuilderVariableID,\n    valueVariable: NativeCompilerBuilderVariableID,\n  ) {\n    if (propertyName instanceof NativeCompilerBuilderAtomID) {\n      builder.buildSetProperty(thisVariable, propertyName, valueVariable);\n    } else {\n      builder.buildSetPropertyValue(thisVariable, propertyName, valueVariable);\n    }\n  }\n\n  private appendNodeDebugInfo(builder: INativeCompilerBlockBuilder, node: ts.Node) {\n    const sourceFile = node.getSourceFile();\n    if (!sourceFile) {\n      return;\n    }\n\n    const lineAndCharacter = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n    let nodeComments = node.getText().trim();\n    if (nodeComments.length > MAX_DEBUG_INFO_LENGTH) {\n      nodeComments = nodeComments.substring(0, MAX_DEBUG_INFO_LENGTH) + '\\n[...]';\n    }\n\n    let comments = `At line ${lineAndCharacter.line + 1}:${lineAndCharacter.character}\\n` + nodeComments + '\\n';\n    builder.buildComments(comments);\n\n    builder.buildProgramCounterInfo(lineAndCharacter.line + 1, lineAndCharacter.character);\n  }\n\n  processEnumDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.EnumDeclaration,\n  ) {\n    // TODO(simon): Const enum\n    this.appendNodeDebugInfo(builder, node);\n    const enumName = this.processIdentifierAsAtom(builder, node.name);\n    const enumObject = builder.buildNewObject();\n    const variableRef = this.resolveRegisteredVariableRefForIdentifier(context, builder, node.name);\n    builder.buildSetVariableRef(variableRef, enumObject);\n\n    this.appendExportedDeclarationIfNeeded(context, builder, node, node.name, enumObject);\n\n    let enumValueSequence = 0;\n    for (const enumMember of node.members) {\n      this.appendNodeDebugInfo(builder, enumMember);\n      const enumName = this.processPropertyName(context, builder, enumMember.name);\n      let enumValue: NativeCompilerBuilderVariableID;\n      if (enumMember.initializer) {\n        const constantValue = this.tryProcessEnumConstantValuePrologue(context, builder, enumMember);\n        if (constantValue !== undefined) {\n          enumValue = this.processEnumConstantValueEpilogue(context, builder, constantValue);\n          if (typeof constantValue === 'number') {\n            enumValueSequence = Math.floor(constantValue) + 1;\n          }\n        } else {\n          const enumInitializer = enumMember.initializer;\n          enumValue = this.processExpression(context, builder, enumInitializer);\n          if (ts.isNumericLiteral(enumInitializer)) {\n            enumValueSequence = Number.parseInt(enumInitializer.text) + 1;\n          }\n        }\n      } else {\n        enumValue = builder.buildLiteralInteger(enumValueSequence.toString());\n        enumValueSequence++;\n      }\n      // TODO: set_properties\n      this.doBuildSetProperty(context, builder, enumName, enumObject, enumValue);\n    }\n  }\n\n  private appendExportedVariable(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Node,\n    exportedName: string,\n    isDefaultExport: boolean,\n    variable: NativeCompilerBuilderVariableID,\n  ) {\n    const exportsVariable = builder.resolveExportsVariable();\n\n    if (isDefaultExport) {\n      const exportedNameAtom = this.processIdentifierStringAsAtom(builder, 'default');\n\n      builder.buildSetProperty(exportsVariable, exportedNameAtom, variable);\n    } else {\n      const exportedNameAtom = this.processIdentifierStringAsAtom(builder, exportedName);\n\n      builder.buildSetProperty(exportsVariable, exportedNameAtom, variable);\n    }\n  }\n\n  private isExportedDeclaration(node: ts.Declaration): boolean {\n    const modifiers = ts.getCombinedModifierFlags(node);\n    if ((modifiers & ts.ModifierFlags.ExportDefault) === ts.ModifierFlags.ExportDefault) {\n      this.onError(node, 'Default exports not yet supported');\n    }\n    return (modifiers & ts.ModifierFlags.Export) !== 0;\n  }\n\n  private appendExportedDeclarationIfNeeded(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Declaration,\n    declarationName: ts.Identifier | undefined,\n    variable: NativeCompilerBuilderVariableID,\n  ): boolean {\n    const modifiers = ts.getCombinedModifierFlags(node);\n    const isDefaultExport = (modifiers & ts.ModifierFlags.ExportDefault) === ts.ModifierFlags.ExportDefault;\n\n    if ((modifiers & ts.ModifierFlags.Export) === 0) {\n      return false;\n    }\n\n    if (!declarationName) {\n      this.onError(node, 'Expected declaration name');\n    }\n\n    const declarationNameString = declarationName.text;\n\n    this.appendExportedVariable(context, builder, node, declarationNameString, isDefaultExport, variable);\n\n    return true;\n  }\n\n  private isNodeResolvingToValue(context: NativeCompilerContext, node: ts.Node): boolean {\n    if (!context.emitResolver) {\n      return true;\n    }\n\n    return context.emitResolver.isValueAliasDeclaration(node);\n  }\n\n  processExportDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ExportDeclaration,\n  ) {\n    if (node.isTypeOnly) {\n      return;\n    }\n    if (!node.exportClause) {\n      this.onError(node, 'Unsupported export statement type');\n    }\n\n    if (ts.isNamedExports(node.exportClause)) {\n      let importedModuleVariable: NativeCompilerBuilderVariableID | undefined;\n\n      for (const exportSpecifier of node.exportClause.elements) {\n        if (exportSpecifier.isTypeOnly || !this.isNodeResolvingToValue(context, exportSpecifier)) {\n          continue;\n        }\n\n        const exportedVariableName = exportSpecifier.name.text;\n        let variableName: string;\n        if (exportSpecifier.propertyName) {\n          variableName = exportSpecifier.propertyName.text;\n        } else {\n          variableName = exportedVariableName;\n        }\n\n        if (node.moduleSpecifier && !importedModuleVariable) {\n          importedModuleVariable = this.doImportModule(context, builder, node, node.moduleSpecifier);\n        }\n\n        let resolvedVar: NativeCompilerBuilderVariableID | undefined;\n        if (importedModuleVariable) {\n          const exportedVariableAtom = this.processIdentifierStringAsAtom(builder, variableName);\n          resolvedVar = builder.buildGetProperty(importedModuleVariable, exportedVariableAtom, importedModuleVariable);\n        } else {\n          resolvedVar = builder.resolveVariableInScope(variableName);\n          if (resolvedVar === undefined) {\n            this.onError(exportSpecifier, `Could not resolve exported variable '${variableName}' `);\n          }\n        }\n\n        this.appendExportedVariable(context, builder, exportSpecifier, exportedVariableName, false, resolvedVar);\n      }\n    } else {\n      this.onError(node, 'Unsupported export clause');\n    }\n  }\n\n  private doImportModule(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Node,\n    modulePathExpression: ts.Expression,\n  ) {\n    const requireVariable = this.resolveValueDelegate(context, builder, 'require', node).getValue().variable;\n    const modulePathString = this.processExpression(context, builder, modulePathExpression);\n\n    return builder.buildFunctionInvocation(requireVariable, [modulePathString], builder.buildUndefined());\n  }\n\n  private processImportModule(\n    context: NativeCompilerContext,\n    importModuleBuilder: INativeCompilerBlockBuilder,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.Node,\n    modulePathExpression: ts.Expression,\n    variableRefName: string,\n  ): NativeCompilerBuilderVariableID {\n    const variableRef = this.resolveRegisteredVariableRefForIdentifierName(\n      context,\n      importModuleBuilder,\n      node,\n      variableRefName,\n    );\n    // Emit the require() call the first time we actually use a symbol from the module\n    if (!this.loadedModules.has(variableRefName)) {\n      this.loadedModules.add(variableRefName);\n\n      const loadedModuleVariable = this.doImportModule(context, importModuleBuilder, node, modulePathExpression);\n      importModuleBuilder.buildSetVariableRef(variableRef, loadedModuleVariable);\n    }\n\n    const outputVariable = builder.resolveVariableInScope(variableRefName);\n    if (!outputVariable) {\n      throw new Error('Could not resolve imported module variable');\n    }\n\n    return outputVariable;\n  }\n\n  private processForAwaitOfStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ForOfStatement,\n  ): void {\n    this.appendNodeDebugInfo(builder, node);\n    const builderLoop = builder.buildLoop();\n    const helper = this.getGlobalVariable(context, builderLoop.initBuilder, '__tsn_get_async_iterator').variable;\n    const iterator = builderLoop.initBuilder.buildFunctionInvocation(\n      helper,\n      [this.processExpression(context, builderLoop.initBuilder, node.expression)],\n      builderLoop.initBuilder.buildUndefined(),\n    );\n    const nextFunc = builderLoop.condBuilder.buildGetProperty(\n      iterator,\n      this.moduleBuilder.registerAtom('next'),\n      iterator,\n    );\n    const promise = builderLoop.condBuilder.buildFunctionInvocation(nextFunc, [], iterator);\n    const suspendBlock = builderLoop.condBuilder.buildSubBuilder(false);\n    const rp = builderLoop.condBuilder.buildJumpTarget('resume_point');\n    suspendBlock.buildSuspend(promise, rp.target);\n    const iteratorResult = builderLoop.condBuilder.buildResume();\n    const iteratorValue = builderLoop.condBuilder.buildGetProperty(\n      iteratorResult,\n      this.moduleBuilder.registerAtom('value'),\n      iteratorResult,\n    );\n    builderLoop.condBuilder.buildBranch(\n      builderLoop.condBuilder.buildGetProperty(iteratorResult, this.moduleBuilder.registerAtom('done'), iteratorResult),\n      NativeCompilerBuilderBranchType.Truthy,\n      builderLoop.exitTarget,\n      builderLoop.bodyJumpTargetBuilder.target,\n    );\n    if (ts.isVariableDeclarationList(node.initializer)) {\n      const variableDeclarations = node.initializer.declarations;\n      if (variableDeclarations.length !== 1) {\n        this.onError(node.initializer, 'Expecting only one variable declaration inside \"for of\" or \"for in\" statement');\n      }\n\n      this.prepareVariableDeclarationList(builderLoop.bodyJumpTargetBuilder.builder, node.initializer);\n\n      this.processVariableDeclaration(\n        context,\n        builderLoop.bodyJumpTargetBuilder.builder,\n        variableDeclarations[0],\n        (context) => {\n          return iteratorValue;\n        },\n      );\n    } else {\n      if (ts.isIdentifier(node.initializer)) {\n        // no-op\n      } else {\n        this.onError(\n          node.initializer,\n          'Expecting variable declaration list or identifier in \"for of\" or \"for in\" statement',\n        );\n      }\n    }\n\n    this.processStatement(context, builderLoop.bodyJumpTargetBuilder.builder, node.statement);\n  }\n\n  private processForInOrOfStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ForOfStatement | ts.ForInStatement,\n    isForOf: boolean,\n  ): void {\n    this.appendNodeDebugInfo(builder, node);\n\n    const builderLoop = builder.buildLoop();\n\n    const iteratorArgument = this.processExpression(context, builderLoop.initBuilder, node.expression);\n    const iterator = isForOf\n      ? builderLoop.initBuilder.buildIterator(iteratorArgument)\n      : builderLoop.initBuilder.buildKeysIterator(iteratorArgument);\n    const iteratorValue = isForOf\n      ? builderLoop.condBuilder.buildIteratorNext(iterator, NativeCompilerBuilderVariableType.Object)\n      : builderLoop.condBuilder.buildKeysIteratorNext(iterator, NativeCompilerBuilderVariableType.Object);\n\n    builderLoop.condBuilder.buildBranch(\n      iterator,\n      NativeCompilerBuilderBranchType.Truthy,\n      builderLoop.bodyJumpTargetBuilder.target,\n      builderLoop.exitTarget,\n    );\n\n    if (ts.isVariableDeclarationList(node.initializer)) {\n      const variableDeclarations = node.initializer.declarations;\n      if (variableDeclarations.length !== 1) {\n        this.onError(node.initializer, 'Expecting only one variable declaration inside \"for of\" or \"for in\" statement');\n      }\n\n      this.prepareVariableDeclarationList(builderLoop.bodyJumpTargetBuilder.builder, node.initializer);\n\n      this.processVariableDeclaration(\n        context,\n        builderLoop.bodyJumpTargetBuilder.builder,\n        variableDeclarations[0],\n        (context) => {\n          return iteratorValue;\n        },\n      );\n    } else {\n      if (ts.isIdentifier(node.initializer)) {\n        // no-op\n      } else {\n        this.onError(\n          node.initializer,\n          'Expecting variable declaration list or identifier in \"for of\" or \"for in\" statement',\n        );\n      }\n    }\n\n    this.processStatement(context, builderLoop.bodyJumpTargetBuilder.builder, node.statement);\n  }\n\n  processForOfStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ForOfStatement,\n  ): void {\n    if (node.awaitModifier) {\n      this.processForAwaitOfStatement(context, builder, node);\n    } else {\n      this.processForInOrOfStatement(context, builder, node, true);\n    }\n  }\n\n  processForInStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ForInStatement,\n  ): void {\n    this.processForInOrOfStatement(context, builder, node, false);\n  }\n\n  processImportDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ImportDeclaration,\n  ) {\n    if (!node.importClause) {\n      return;\n    }\n\n    if (node.importClause.isTypeOnly) {\n      return;\n    }\n\n    const importVariableRefName = this.getVariableRefNameForImportedModule(node.moduleSpecifier);\n    const importModuleBuilder = builder.buildSubBuilder(false);\n\n    if (node.importClause.name) {\n      builder.registerVariableDelegate(node.importClause.name.text, {\n        onGetValue: (builder) => {\n          const importedModuleVariable = this.processImportModule(\n            context,\n            importModuleBuilder,\n            builder,\n            node,\n            node.moduleSpecifier,\n            importVariableRefName,\n          );\n\n          return builder.buildGetProperty(\n            importedModuleVariable,\n            this.processIdentifierStringAsAtom(builder, 'default'),\n            importedModuleVariable,\n          );\n        },\n      });\n    }\n\n    if (node.importClause.namedBindings) {\n      if (ts.isNamedImports(node.importClause.namedBindings)) {\n        for (const importSpecifier of node.importClause.namedBindings.elements) {\n          if (importSpecifier.isTypeOnly) {\n            continue;\n          }\n\n          const variableName = importSpecifier.name;\n\n          builder.registerVariableDelegate(variableName.text, {\n            onGetValue: (builder) => {\n              const importedModuleVariable = this.processImportModule(\n                context,\n                importModuleBuilder,\n                builder,\n                node,\n                node.moduleSpecifier,\n                importVariableRefName,\n              );\n\n              let importedVariableName: NativeCompilerBuilderAtomID;\n              if (importSpecifier.propertyName) {\n                importedVariableName = this.processIdentifierAsAtom(builder, importSpecifier.propertyName);\n              } else {\n                importedVariableName = this.processIdentifierAsAtom(builder, variableName);\n              }\n\n              return builder.buildGetProperty(importedModuleVariable, importedVariableName, importedModuleVariable);\n            },\n          });\n        }\n      } else if (ts.isNamespaceImport(node.importClause.namedBindings)) {\n        const variableName = node.importClause.namedBindings.name;\n\n        builder.registerVariableDelegate(variableName.text, {\n          onGetValue: (builder) => {\n            return this.processImportModule(\n              context,\n              importModuleBuilder,\n              builder,\n              node,\n              node.moduleSpecifier,\n              importVariableRefName,\n            );\n          },\n        });\n      } else {\n        this.onError(node, 'Unsupported import clause');\n      }\n    }\n  }\n\n  processModuleDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ModuleDeclaration,\n  ): void {\n    if (!ts.isIdentifier(node.name)) {\n      this.onError(node, 'Module declaration named with strings are not yet supported');\n    }\n\n    const moduleName = node.name;\n\n    const variableRef = this.resolveRegisteredVariableRefForIdentifier(context, builder, moduleName);\n    const moduleVariableId = builder.buildNewObject();\n    builder.buildSetVariableRef(variableRef, moduleVariableId);\n    this.appendExportedDeclarationIfNeeded(context, builder, node, node.name, moduleVariableId);\n\n    if (node.body) {\n      if (ts.isModuleBlock(node.body)) {\n        const moduleBlock = node.body as ts.ModuleBlock;\n        const namespaceBlockBuilder = builder.buildSubBuilder(true);\n        // Any exports now should refer to the namespace instead of the 'exports' of the module\n        namespaceBlockBuilder.registerExportsVariableRef(variableRef);\n        this.processStatementsInBlock(context, namespaceBlockBuilder, moduleBlock.statements);\n      } else {\n        this.onError(node.body, `Only module blocks are currently supported`);\n      }\n    }\n  }\n\n  processContinueStatement(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ContinueStatement,\n  ): void {\n    if (node.label) {\n      this.onError(node, 'Continue labels are not yet supported');\n    }\n\n    this.appendNodeDebugInfo(builder, node);\n\n    const continueTarget = builder.resolveContinueTargetInScope();\n    if (!continueTarget) {\n      this.onError(node, 'Could not resolve outer jump target for processing continue statement');\n    }\n\n    builder.buildJump(continueTarget);\n  }\n\n  processDoStatement(context: NativeCompilerContext, builder: INativeCompilerBlockBuilder, node: ts.DoStatement): void {\n    this.appendNodeDebugInfo(builder, node);\n\n    const builderLoop = builder.buildSubBuilder(true);\n\n    const builderLoopMain = builderLoop.buildSubBuilder(true);\n    const builderLoopMainBody = builderLoopMain.buildJumpTarget('body');\n    const builderLoopMainCondition = builderLoopMain.buildJumpTarget('cond');\n    const exitBuilder = builderLoop.buildJumpTarget('exit');\n\n    builderLoopMainBody.builder.registerExitTargetInScope(exitBuilder.target);\n    builderLoopMainBody.builder.registerContinueTargetInScope(builderLoopMainCondition.target);\n\n    this.processStatement(context, builderLoopMainBody.builder, node.statement);\n\n    let conditionVariable = this.processExpression(context, builderLoopMainCondition.builder, node.expression);\n    builderLoopMainCondition.builder.buildBranch(\n      conditionVariable,\n      NativeCompilerBuilderBranchType.Truthy,\n      builderLoopMainBody.target,\n      exitBuilder.target,\n    );\n  }\n\n  processExportAssignment(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ExportAssignment,\n  ): void {\n    const result = this.processExpression(context, builder, node.expression);\n    if (node.isExportEquals) {\n      // export = <expr>\n      // Emit as module.exports = <expr>\n      const moduleVariable = this.resolveValueDelegate(context, builder, 'module', node).getValue().variable;\n      builder.buildSetProperty(moduleVariable, this.processIdentifierStringAsAtom(builder, 'exports'), result);\n    } else {\n      // export default <expr>\n      // Emit as exports.default = <expr>\n      const exportsVariable = this.resolveValueDelegate(context, builder, 'exports', node).getValue().variable;\n      builder.buildSetProperty(exportsVariable, this.processIdentifierStringAsAtom(builder, 'default'), result);\n    }\n  }\n\n  processEntityName(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.EntityName,\n  ): NativeCompilerBuilderVariableID {\n    if (ts.isIdentifier(node)) {\n      return this.processIdentifierAsValueDelegate(context, builder, node).getValue().variable;\n    } else {\n      const qualifiedName: ts.QualifiedName = node;\n      const leftVariable = this.processEntityName(context, builder, qualifiedName.left);\n      return builder.buildGetProperty(\n        leftVariable,\n        this.processIdentifierAsAtom(builder, qualifiedName.right),\n        leftVariable,\n      );\n    }\n  }\n\n  processImportEqualsDeclaration(\n    context: NativeCompilerContext,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ImportEqualsDeclaration,\n  ): void {\n    if (node.isTypeOnly) {\n      return;\n    }\n\n    const variableRef = this.resolveRegisteredVariableRefForIdentifier(context, builder, node.name);\n\n    let variableId: NativeCompilerBuilderVariableID;\n    const moduleReference = node.moduleReference;\n    if (ts.isExternalModuleReference(moduleReference)) {\n      variableId = this.processExpression(context, builder, moduleReference.expression);\n    } else {\n      variableId = this.processEntityName(context, builder, moduleReference);\n    }\n\n    builder.buildSetVariableRef(variableRef, variableId);\n  }\n\n  private prepareBindingElement(\n    builder: INativeCompilerBlockBuilder,\n    node: ts.BindingElement,\n    scope: VariableRefScope,\n  ): void {\n    if (ts.isIdentifier(node.name)) {\n      const variableName = node.name;\n      builder.buildVariableRef(variableName.text, NativeCompilerBuilderVariableType.Empty, scope);\n    } else if (ts.isObjectBindingPattern(node.name)) {\n      for (const element of node.name.elements) {\n        this.prepareBindingElement(builder, element, scope);\n      }\n    } else if (ts.isArrayBindingPattern(node.name)) {\n      for (const element of node.name.elements) {\n        if (ts.isOmittedExpression(element)) {\n          continue;\n        }\n        this.prepareBindingElement(builder, element, scope);\n      }\n    }\n  }\n\n  private prepareBindingName(\n    builder: INativeCompilerBlockBuilder,\n    name: ts.BindingName,\n    scope: VariableRefScope,\n    isConst?: boolean,\n  ): void {\n    if (ts.isIdentifier(name)) {\n      builder.buildVariableRef(name.text, NativeCompilerBuilderVariableType.Empty, scope, isConst);\n    } else if (ts.isObjectBindingPattern(name)) {\n      const objectBindingPattern: ts.ObjectBindingPattern = name;\n\n      for (const element of objectBindingPattern.elements) {\n        this.prepareBindingElement(builder, element, scope);\n      }\n    } else if (ts.isArrayBindingPattern(name)) {\n      const arrayBindingPattern: ts.ArrayBindingPattern = name;\n\n      for (const element of arrayBindingPattern.elements) {\n        if (ts.isOmittedExpression(element)) {\n          continue;\n        }\n\n        this.prepareBindingElement(builder, element, scope);\n      }\n    } else {\n      this.onError(name, 'Unsupported variable declaration type');\n    }\n  }\n\n  private prepareVariableDeclaration(\n    builder: INativeCompilerBlockBuilder,\n    node: ts.VariableDeclaration,\n    scope: VariableRefScope,\n    isConst?: boolean,\n  ) {\n    this.prepareBindingName(builder, node.name, scope, isConst);\n  }\n\n  private prepareVariableDeclarationList(builder: INativeCompilerBlockBuilder, node: ts.VariableDeclarationList) {\n    const isLet = (node.flags & ts.NodeFlags.Let) != 0;\n    const isConst = (node.flags & ts.NodeFlags.Const) != 0;\n    const scope: VariableRefScope = isLet || isConst ? VariableRefScope.Block : VariableRefScope.Function;\n\n    for (const declaration of node.declarations) {\n      this.prepareVariableDeclaration(builder, declaration, scope, isConst);\n    }\n  }\n\n  private prepareVariableStatement(\n    plan: CompilationPlan,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.VariableStatement,\n  ): boolean {\n    this.prepareVariableDeclarationList(builder, node.declarationList);\n    return false;\n  }\n\n  private prepareFunctionDeclaration(\n    plan: CompilationPlan,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.FunctionDeclaration,\n  ): boolean {\n    if (!node.body) {\n      return false;\n    }\n\n    if (node.name) {\n      builder.buildVariableRef(node.name.text, NativeCompilerBuilderVariableType.Object, VariableRefScope.Block);\n    }\n\n    // Function declaration should be hoisted at the beginning of the block\n    plan.statementsToProcess.splice(plan.functionDeclarationInsertionIndex, 0, node);\n    plan.functionDeclarationInsertionIndex++;\n\n    return true;\n  }\n\n  private prepareClassDeclaration(\n    plan: CompilationPlan,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ClassDeclaration,\n  ): boolean {\n    if (node.name) {\n      builder.buildVariableRef(node.name.text, NativeCompilerBuilderVariableType.Object, VariableRefScope.Block);\n    }\n\n    return false;\n  }\n\n  private prepareEnumDeclaration(\n    plan: CompilationPlan,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.EnumDeclaration,\n  ): boolean {\n    builder.buildVariableRef(node.name.text, NativeCompilerBuilderVariableType.Object, VariableRefScope.Block);\n\n    return false;\n  }\n\n  private prepareModuleDeclaration(\n    plan: CompilationPlan,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ModuleDeclaration,\n  ): boolean {\n    if (ts.isIdentifier(node.name)) {\n      builder.buildVariableRef(node.name.text, NativeCompilerBuilderVariableType.Object, VariableRefScope.Block);\n    }\n    return false;\n  }\n\n  private prepareImportDeclaration(\n    plan: CompilationPlan,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ImportDeclaration,\n  ): boolean {\n    if (!node.importClause) {\n      return true;\n    }\n\n    if (node.importClause.isTypeOnly) {\n      return true;\n    }\n\n    const importVariableRefName = this.createVariableRefNameForImportedModule(node.moduleSpecifier);\n    builder.registerLazyVariableRef(importVariableRefName, VariableRefScope.Block, (builder) =>\n      builder.buildVariableRef(importVariableRefName, NativeCompilerBuilderVariableType.Empty, VariableRefScope.Block),\n    );\n\n    // We should process the next function declarations after our import\n    plan.functionDeclarationInsertionIndex = plan.statementsToProcess.length + 1;\n\n    return false;\n  }\n\n  private prepareImportEqualsDeclaration(\n    plan: CompilationPlan,\n    builder: INativeCompilerBlockBuilder,\n    node: ts.ImportEqualsDeclaration,\n  ): boolean {\n    if (node.isTypeOnly) {\n      return true;\n    }\n\n    builder.buildVariableRef(node.name.text, NativeCompilerBuilderVariableType.Empty, VariableRefScope.Block);\n\n    return false;\n  }\n\n  private prepareStatement(plan: CompilationPlan, builder: INativeCompilerBlockBuilder, node: ts.Statement): void {\n    if (this.isAmbientDeclaration(node)) {\n      // Nothing to do for ambiant declarations\n      return;\n    }\n\n    let fullyProcessed = false;\n\n    if (ts.isVariableStatement(node)) {\n      fullyProcessed = this.prepareVariableStatement(plan, builder, node);\n    } else if (ts.isFunctionDeclaration(node)) {\n      fullyProcessed = this.prepareFunctionDeclaration(plan, builder, node);\n    } else if (ts.isClassDeclaration(node)) {\n      fullyProcessed = this.prepareClassDeclaration(plan, builder, node);\n    } else if (ts.isEnumDeclaration(node)) {\n      fullyProcessed = this.prepareEnumDeclaration(plan, builder, node);\n    } else if (ts.isModuleDeclaration(node)) {\n      fullyProcessed = this.prepareModuleDeclaration(plan, builder, node);\n    } else if (ts.isImportDeclaration(node)) {\n      fullyProcessed = this.prepareImportDeclaration(plan, builder, node);\n    } else if (ts.isImportEqualsDeclaration(node)) {\n      fullyProcessed = this.prepareImportEqualsDeclaration(plan, builder, node);\n    }\n\n    if (!fullyProcessed) {\n      plan.statementsToProcess.push(node);\n    }\n  }\n\n  processStatement(context: NativeCompilerContext, builder: INativeCompilerBlockBuilder, node: ts.Statement) {\n    if (!node) {\n      return;\n    }\n\n    this.lastProcessingDeclaration = node;\n\n    if (ts.isInterfaceDeclaration(node)) {\n      this.processInterfaceDeclaration(builder, node);\n    } else if (ts.isFunctionDeclaration(node)) {\n      this.processFunctionDeclaration(context, builder, node, false);\n    } else if (ts.isBlock(node)) {\n      this.processBlock(context, builder, node);\n    } else if (ts.isReturnStatement(node)) {\n      this.processReturnStatement(context, builder, node);\n    } else if (ts.isExpressionStatement(node)) {\n      this.processExpressionStatement(context, builder, node);\n    } else if (ts.isForStatement(node)) {\n      this.processForStatement(context, builder, node);\n    } else if (ts.isForOfStatement(node)) {\n      this.processForOfStatement(context, builder, node);\n    } else if (ts.isForInStatement(node)) {\n      this.processForInStatement(context, builder, node);\n    } else if (ts.isIfStatement(node)) {\n      this.processIfStatement(context, builder, node);\n    } else if (ts.isWhileStatement(node)) {\n      this.processWhileStatement(context, builder, node);\n    } else if (ts.isDoStatement(node)) {\n      this.processDoStatement(context, builder, node);\n    } else if (ts.isThrowStatement(node)) {\n      this.processThrowStatement(context, builder, node);\n    } else if (ts.isBreakStatement(node)) {\n      this.processBreakStatement(builder, node);\n    } else if (ts.isContinueStatement(node)) {\n      this.processContinueStatement(context, builder, node);\n    } else if (ts.isTryStatement(node)) {\n      this.processTryStatement(context, builder, node);\n    } else if (ts.isSwitchStatement(node)) {\n      this.processSwitchStatement(context, builder, node);\n    } else if (ts.isEmptyStatement(node)) {\n      // no-op\n    } else if (ts.isClassDeclaration(node)) {\n      this.processClassDeclaration(context, builder, node);\n    } else if (ts.isEnumDeclaration(node)) {\n      this.processEnumDeclaration(context, builder, node);\n    } else if (ts.isExportDeclaration(node)) {\n      this.processExportDeclaration(context, builder, node);\n    } else if (ts.isVariableStatement(node)) {\n      this.processVariableStatement(context, builder, node);\n    } else if (ts.isImportDeclaration(node)) {\n      this.processImportDeclaration(context, builder, node);\n    } else if (ts.isModuleDeclaration(node)) {\n      this.processModuleDeclaration(context, builder, node);\n    } else if (ts.isExportAssignment(node)) {\n      this.processExportAssignment(context, builder, node);\n    } else if (ts.isImportEqualsDeclaration(node)) {\n      this.processImportEqualsDeclaration(context, builder, node);\n    } else if (ts.isJsxExpression(node)) {\n      this.processJsxExpression(context, builder, node);\n    } else if (ts.isTypeAliasDeclaration(node)) {\n      // no-op\n    } else {\n      this.onError(node, 'Cannot process statement');\n    }\n  }\n\n  compile(): NativeCompilerIR.Base[] {\n    try {\n      const initFunctionName = this.allocateFunctionName(`${this.moduleName}__module_init__`);\n\n      this.processSourceFile(initFunctionName, this.sourceFile);\n      return this.moduleBuilder.finalize(initFunctionName, this.options);\n    } catch (exc: any) {\n      if (!(exc instanceof NativeHelper.NativeCompilerError)) {\n        if (this.lastProcessingDeclaration) {\n          // Decorate error with last processing declaration\n          try {\n            const resolvedError = new NativeHelper.NativeCompilerError(\n              this.filePath,\n              this.sourceFile,\n              this.lastProcessingDeclaration,\n              exc.message,\n            );\n\n            resolvedError.stack = exc.stack;\n\n            throw resolvedError;\n          } catch (e: any) {\n            throw exc;\n          }\n        } else {\n          throw exc;\n        }\n      } else {\n        throw exc;\n      }\n    }\n  }\n}\n\nexport function compileIRsToC(\n  ir: NativeCompilerIR.Base[],\n  options: NativeCompilerOptions,\n): NativeCompilerEmitterOutput {\n  const emitter = new CompilerNativeCEmitter(options);\n  emitterWalk(emitter, ir);\n  return emitter.finalize();\n}\n"
  },
  {
    "path": "compiler/companion/src/native/NativeCompilerOptions.ts",
    "content": "export interface NativeCompilerOptions {\n  optimizeSlots: boolean;\n  optimizeVarRefs: boolean;\n\n  // Smaller code size and faster\n  optimizeNullChecks?: boolean;\n  mergeSetProperties?: boolean;\n  foldConstants?: boolean;\n  optimizeVarRefLoads?: boolean;\n  optimizeAssignments?: boolean;\n  inlinePropertyCache?: boolean;\n  enableIntrinsics?: boolean;\n\n  // Smaller code size but slower\n  noinlineRetainRelease?: boolean;\n  mergeReleases?: boolean;\n  autoRelease?: boolean;\n}\n"
  },
  {
    "path": "compiler/companion/src/native/NativeHelper.ts",
    "content": "import * as ts from 'typescript';\nimport { getSyntaxKindString } from '../TSUtils';\n\nexport enum NumberType {\n  Integer,\n  Long,\n  Float,\n}\n\nconst INT32_MAX = 2147483647;\nconst INT32_MIN = -INT32_MAX - 1;\n\nexport class NativeCompilerError extends Error {\n  constructor(filename: string, sourceFile: ts.SourceFile, node: ts.Node, message: string) {\n    const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n    const resolvedErrorMessage = `in ${filename} at ${line + 1},${\n      character + 1\n    }: ${message} of kind ${getSyntaxKindString(node.kind)} at (${line + 1},${\n      character + 1\n    }) (node content: ${node.getText()})`;\n\n    super(resolvedErrorMessage);\n  }\n}\n\nexport function getNumericalStringTypeFromNumber(numberValue: number): NumberType {\n  if (Number.isInteger(numberValue)) {\n    if (numberValue > INT32_MAX || numberValue < INT32_MIN) {\n      return NumberType.Long;\n    } else {\n      return NumberType.Integer;\n    }\n  } else {\n    return NumberType.Float;\n  }\n}\n\nexport function getNumericalStringType(value: string): NumberType {\n  if (value.includes('.') || value.includes('e')) {\n    return NumberType.Float;\n  }\n\n  const numberValue = parseFloat(value);\n\n  return getNumericalStringTypeFromNumber(numberValue);\n}\n\nexport function getModuleName(filePath: string) {\n  const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);\n  const fileNameNoExtension = fileName.split('.')[0];\n  return fileNameNoExtension;\n}\n\nexport function onError(filename: string, sourceFile: ts.SourceFile, node: ts.Node, message: string): never {\n  throw new NativeCompilerError(filename, sourceFile, node, message);\n}\n\nexport function logNodeInfo(node: ts.Node): void {\n  console.log(`kind: ${getSyntaxKindString(node.kind)} text: ${node.getFullText()}`);\n}\n\nexport function uniqueNameFromNode(moduleName: string, node: ts.Node): string {\n  return `tsn_${moduleName}_node_${node.getStart()}_${node.getEnd()}`;\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/INativeCompilerBuilder.ts",
    "content": "import { NativeCompilerIR } from './NativeCompilerBuilderIR';\nimport { VariableContext } from './VariableContext';\n\nexport const enum NativeCompilerBuilderVariableType {\n  Empty = 0,\n  Undefined = 1 << 0,\n  Null = 1 << 1,\n  Number = 1 << 2,\n  Bool = 1 << 3,\n  Object = 1 << 4,\n  ReturnValue = 1 << 7,\n  Super = 1 << 8,\n  VariableRef = 1 << 9,\n  Iterator = 1 << 10,\n}\n\nexport const enum NativeCompilerBuilderBranchType {\n  /**\n   * Condition evaluates to true if the value is:\n   * - the boolean 'true' value\n   * - a non zero number\n   * - a non empty string\n   * - an object or array\n   */\n  Truthy,\n\n  /**\n   * Condition evaluates to true if the value is anything\n   * but undefined or null.\n   */\n  NotUndefinedOrNull,\n}\n\nexport class NativeCompilerBuilderVariableBase {\n  get type(): NativeCompilerBuilderVariableType {\n    return this._type;\n  }\n\n  private _type: NativeCompilerBuilderVariableType;\n\n  constructor(type: NativeCompilerBuilderVariableType) {\n    this._type = type;\n  }\n\n  isRetainable(): boolean {\n    return (\n      (this._type & NativeCompilerBuilderVariableType.Object) !== 0 ||\n      (this._type & NativeCompilerBuilderVariableType.VariableRef) !== 0 ||\n      (this._type & NativeCompilerBuilderVariableType.Iterator) !== 0\n    );\n  }\n\n  getTypeString(): string {\n    const type = this._type;\n    if (type === NativeCompilerBuilderVariableType.Empty) {\n      return 'empty';\n    }\n\n    const components: string[] = [];\n\n    if (type & NativeCompilerBuilderVariableType.Undefined) {\n      components.push('undefined');\n    }\n    if (type & NativeCompilerBuilderVariableType.Null) {\n      components.push('null');\n    }\n    if (type & NativeCompilerBuilderVariableType.Number) {\n      components.push('number');\n    }\n    if (type & NativeCompilerBuilderVariableType.Bool) {\n      components.push('bool');\n    }\n    if (type & NativeCompilerBuilderVariableType.Object) {\n      components.push('object');\n    }\n    if (type & NativeCompilerBuilderVariableType.ReturnValue) {\n      components.push('retval');\n    }\n    if (type & NativeCompilerBuilderVariableType.Super) {\n      components.push('super');\n    }\n    if (type & NativeCompilerBuilderVariableType.VariableRef) {\n      components.push('vref');\n    }\n    if (type & NativeCompilerBuilderVariableType.Iterator) {\n      components.push('iterator');\n    }\n\n    return components.join('_');\n  }\n\n  addType(type: NativeCompilerBuilderVariableType): void {\n    this._type = NativeCompilerBuilderVariableBase.combineTypes(this._type, type);\n  }\n\n  static combineTypes(\n    left: NativeCompilerBuilderVariableType,\n    right: NativeCompilerBuilderVariableType,\n  ): NativeCompilerBuilderVariableType {\n    let result = left;\n\n    if (left === NativeCompilerBuilderVariableType.ReturnValue) {\n      // Keep return value as is\n      return result;\n    }\n\n    if (left === NativeCompilerBuilderVariableType.Undefined || left === NativeCompilerBuilderVariableType.Empty) {\n      // If the type is undefined, just set the type\n      return right;\n    } else {\n      result |= right;\n    }\n\n    if ((result & NativeCompilerBuilderVariableType.Object) != 0) {\n      // Decay the type to object once it becomes an object\n      result = NativeCompilerBuilderVariableType.Object;\n    }\n\n    return result;\n  }\n}\n\nexport class NativeCompilerBuilderVariableID extends NativeCompilerBuilderVariableBase {\n  constructor(\n    public readonly functionId: number,\n    public readonly variable: number,\n    type: NativeCompilerBuilderVariableType,\n    readonly assignable: boolean,\n  ) {\n    super(type);\n  }\n\n  toString(): string {\n    return `${this.getTypeString()}_var${this.variable}`;\n  }\n}\n\nexport enum ConstantType {\n  Bool,\n  Integer,\n  Long,\n  Double,\n  String,\n}\nexport class ConstValue {\n  constructor(\n    public type: NativeCompilerBuilderVariableType = NativeCompilerBuilderVariableType.Empty,\n    public ctype: ConstantType | undefined = undefined,\n    public value: string | undefined = undefined,\n  ) {}\n}\n\nexport class NativeCompilerBuilderVariableRef extends NativeCompilerBuilderVariableBase {\n  constructor(\n    readonly name: string,\n    type: NativeCompilerBuilderVariableType,\n    readonly variableId: NativeCompilerBuilderVariableID,\n    readonly constValue?: ConstValue,\n  ) {\n    super(type);\n  }\n  addType(type: NativeCompilerBuilderVariableType): void {\n    super.addType(type);\n    if (this.constValue) {\n      this.constValue.type = type;\n    }\n  }\n}\n\nexport class NativeCompilerBuilderAtomID {\n  constructor(public readonly atom: number, readonly identifier: string) {}\n}\n\nexport class NativeCompilerBuilderJumpTargetID {\n  constructor(public readonly label: number, public readonly tag: string) {}\n}\n\nexport interface INativeCompilerJumpTargetBuilder {\n  readonly target: NativeCompilerBuilderJumpTargetID;\n  readonly builder: INativeCompilerBlockBuilder;\n}\n\nexport interface INativeCompilerLoopBuilder {\n  readonly initBuilder: INativeCompilerBlockBuilder;\n  readonly condBuilder: INativeCompilerBlockBuilder;\n  readonly bodyJumpTargetBuilder: INativeCompilerJumpTargetBuilder;\n  readonly exitTarget: NativeCompilerBuilderJumpTargetID;\n}\n\nexport interface INativeCompilerTryCatchBuilder {\n  readonly tryBuilder: INativeCompilerBlockBuilder;\n  readonly catchBuilder: INativeCompilerBlockBuilder | undefined;\n  readonly finallyBuilder: INativeCompilerBlockBuilder | undefined;\n}\n\nexport interface INativeCompilerFunctionBuilder {\n  readonly name: string;\n  readonly builder: INativeCompilerBlockBuilder;\n  // Will be populated while the function is being built\n  readonly closureArguments: NativeCompilerBuilderVariableRef[];\n}\n\nexport const enum VariableRefScope {\n  Block,\n  Function,\n}\n\nexport interface IVariableDelegate {\n  onGetValue: (builder: INativeCompilerBlockBuilder) => NativeCompilerBuilderVariableID;\n  onSetValue?: (\n    builder: INativeCompilerBlockBuilder,\n    value: NativeCompilerBuilderVariableID,\n  ) => NativeCompilerBuilderVariableID;\n}\n\nexport interface INativeCompilerBlockBuilder {\n  readonly variableContext: VariableContext;\n\n  buildSubBuilder(scoped: boolean): INativeCompilerBlockBuilder;\n\n  buildGlobal(): NativeCompilerBuilderVariableID;\n  buildSetProperty(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    value: NativeCompilerBuilderVariableID,\n  ): void;\n  buildSetProperties(\n    object: NativeCompilerBuilderVariableID,\n    properties: NativeCompilerBuilderAtomID[],\n    values: NativeCompilerBuilderVariableID[],\n  ): void;\n\n  buildSetPropertyValue(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    value: NativeCompilerBuilderVariableID,\n  ): void;\n\n  buildSetPropertyIndex(\n    object: NativeCompilerBuilderVariableID,\n    index: number,\n    value: NativeCompilerBuilderVariableID,\n  ): void;\n\n  buildCopyPropertiesFrom(\n    destObject: NativeCompilerBuilderVariableID,\n    sourceObject: NativeCompilerBuilderVariableID,\n    propertiesToIgnore: NativeCompilerBuilderAtomID[] | undefined,\n  ): NativeCompilerBuilderVariableID;\n\n  buildGetProperty(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    thisObject: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID;\n\n  buildGetPropertyValue(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    thisObject: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID;\n\n  buildDeleteProperty(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n  ): NativeCompilerBuilderVariableID;\n\n  buildDeletePropertyValue(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID;\n\n  buildGetClosureVariableRef(\n    variableName: string,\n    closureIndex: number,\n    source: NativeCompilerBuilderVariableRef,\n  ): NativeCompilerBuilderVariableRef;\n\n  buildGetModuleConst(index: number): NativeCompilerBuilderVariableID;\n\n  buildGetFunctionArg(index: number): NativeCompilerBuilderVariableID;\n  buildGetFunctionArgumentsObject(startIndex: number): NativeCompilerBuilderVariableID;\n\n  buildGetSuper(): NativeCompilerBuilderVariableID;\n  buildGetSuperConstructor(): NativeCompilerBuilderVariableID;\n\n  buildAssignableUndefined(): NativeCompilerBuilderVariableID;\n\n  buildUndefined(): NativeCompilerBuilderVariableID;\n  buildNull(): NativeCompilerBuilderVariableID;\n  buildThis(): NativeCompilerBuilderVariableID;\n  buildNewTarget(): NativeCompilerBuilderVariableID;\n  buildCopy(value: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID;\n\n  buildException(retVal?: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID;\n  buildLiteralInteger(value: string): NativeCompilerBuilderVariableID;\n  buildLiteralLong(value: string): NativeCompilerBuilderVariableID;\n  buildLiteralDouble(value: string): NativeCompilerBuilderVariableID;\n  buildLiteralString(value: string): NativeCompilerBuilderVariableID;\n  buildLiteralBool(value: boolean): NativeCompilerBuilderVariableID;\n  buildGetException(): NativeCompilerBuilderVariableID;\n  buildCheckException(jumpTarget: NativeCompilerBuilderJumpTargetID): void;\n  buildUnaryOp(\n    operator: NativeCompilerIR.UnaryOperator,\n    variable: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID;\n  buildBinaryOp(\n    operator: NativeCompilerIR.BinaryOperator,\n    left: NativeCompilerBuilderVariableID,\n    right: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID;\n\n  /**\n   * Look up an intrinsic constant\n   */\n  getIntrinsicConstant(name: string): number | string | undefined;\n  /**\n   * Whether an intrinsic function is available\n   */\n  hasIntrinsicFunction(func: string): boolean;\n  /**\n   * Build an intrisic call\n   */\n  buildIntrinsicCall(func: string, args: Array<NativeCompilerBuilderVariableID>): NativeCompilerBuilderVariableID;\n\n  /**\n   * Build a function call that passes the given arguments\n   */\n  buildFunctionInvocation(\n    func: NativeCompilerBuilderVariableID,\n    args: Array<NativeCompilerBuilderVariableID>,\n    obj: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID;\n\n  /**\n   * Build a function call that uses an array as the arguments to pass.\n   */\n  buildFunctionInvocationWithArgsArray(\n    func: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID,\n    obj: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID;\n\n  buildConstructorInvocation(\n    func: NativeCompilerBuilderVariableID,\n    new_target: NativeCompilerBuilderVariableID,\n    args: Array<NativeCompilerBuilderVariableID>,\n  ): NativeCompilerBuilderVariableID;\n\n  buildConstructorInvocationWithArgsArray(\n    func: NativeCompilerBuilderVariableID,\n    new_target: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID;\n\n  buildNewObject(): NativeCompilerBuilderVariableID;\n  buildNewArray(): NativeCompilerBuilderVariableID;\n  buildNewArrowFunctionValue(\n    functionName: string,\n    argc: number,\n    closureArguments: NativeCompilerBuilderVariableRef[],\n    stackOnHeap: boolean,\n  ): NativeCompilerBuilderVariableID;\n  buildNewFunctionValue(\n    functionName: string,\n    name: NativeCompilerBuilderAtomID,\n    argc: number,\n    closureArguments: NativeCompilerBuilderVariableRef[],\n  ): NativeCompilerBuilderVariableID;\n\n  buildNewClassValue(\n    functionName: string,\n    name: NativeCompilerBuilderAtomID,\n    argc: number,\n    parentClass: NativeCompilerBuilderVariableID,\n    closureArguments: NativeCompilerBuilderVariableRef[],\n  ): NativeCompilerBuilderVariableID;\n\n  buildSetClassElement(\n    type: NativeCompilerIR.ClassElementType,\n    classVariable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderAtomID,\n    value: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n  ): void;\n\n  buildSetClassElementValue(\n    type: NativeCompilerIR.ClassElementType,\n    classVariable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderVariableID,\n    value: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n  ): void;\n\n  //TODO(5173): Find a way to manage variable reassignment, and loops without this function\n  buildAssignment(left: NativeCompilerBuilderVariableID, right: NativeCompilerBuilderVariableID): void;\n  buildReturn(value: NativeCompilerBuilderVariableID): void;\n\n  buildJumpTarget(tag: string): INativeCompilerJumpTargetBuilder;\n\n  buildJump(target: NativeCompilerBuilderJumpTargetID): void;\n  buildBranch(\n    conditions: NativeCompilerBuilderVariableID,\n    type: NativeCompilerBuilderBranchType,\n    trueTarget: NativeCompilerBuilderJumpTargetID,\n    falseTarget: NativeCompilerBuilderJumpTargetID | undefined,\n  ): void;\n\n  buildLoop(): INativeCompilerLoopBuilder;\n  buildTryCatch(hasCatchBlock: boolean, hasFinallyBlock: boolean): INativeCompilerTryCatchBuilder;\n\n  buildIterator(value: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID;\n  buildKeysIterator(value: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID;\n  buildIteratorNext(\n    value: NativeCompilerBuilderVariableID,\n    type: NativeCompilerBuilderVariableType,\n  ): NativeCompilerBuilderVariableID;\n  buildKeysIteratorNext(\n    value: NativeCompilerBuilderVariableID,\n    type: NativeCompilerBuilderVariableType,\n  ): NativeCompilerBuilderVariableID;\n\n  buildGenerator(closure: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID;\n  buildResume(): NativeCompilerBuilderVariableID;\n  buildSetResumePoint(resumePoint?: NativeCompilerBuilderJumpTargetID): void;\n  buildSuspend(value: NativeCompilerBuilderVariableID, resumePoint: NativeCompilerBuilderJumpTargetID): void;\n\n  buildThrow(value: NativeCompilerBuilderVariableID): void;\n\n  buildComments(text: string): void;\n\n  buildProgramCounterInfo(lineNumber: number, columnNumber: number): void;\n\n  registerExitTargetInScope(target: NativeCompilerBuilderJumpTargetID): void;\n  resolveExitTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined;\n\n  registerContinueTargetInScope(target: NativeCompilerBuilderJumpTargetID): void;\n  resolveContinueTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined;\n\n  registerExceptionTargetInScope(target: NativeCompilerBuilderJumpTargetID): void;\n  resolveExceptionTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined;\n\n  buildVariableRef(\n    variableName: string,\n    type: NativeCompilerBuilderVariableType,\n    scope: VariableRefScope,\n    isConst?: boolean,\n  ): NativeCompilerBuilderVariableRef;\n  buildInitializedVariableRef(\n    variableName: string,\n    value: NativeCompilerBuilderVariableID,\n    scope: VariableRefScope,\n  ): NativeCompilerBuilderVariableRef;\n  buildLoadVariableRef(variableRef: NativeCompilerBuilderVariableRef): NativeCompilerBuilderVariableID;\n  buildSetVariableRef(variableRef: NativeCompilerBuilderVariableRef, value: NativeCompilerBuilderVariableID): void;\n\n  resolveVariableRefOrDelegateInScope(\n    variableName: string,\n  ): NativeCompilerBuilderVariableRef | IVariableDelegate | undefined;\n  resolveVariableInScope(variableName: string): NativeCompilerBuilderVariableID | undefined;\n\n  // Register the variable ref that should be used to exports symbols through the 'export' modifiers\n  registerExportsVariableRef(variableRef: NativeCompilerBuilderVariableRef): void;\n  resolveExportsVariableRef(): NativeCompilerBuilderVariableRef;\n  resolveExportsVariable(): NativeCompilerBuilderVariableID;\n\n  /**\n   * Register a variable ref that will only be built if it is explicitly accessed through resolveVariableRefInScope().\n   */\n  registerLazyVariableRef(\n    variableName: string,\n    scope: VariableRefScope,\n    doBuild: (builder: INativeCompilerBlockBuilder) => NativeCompilerBuilderVariableRef,\n  ): void;\n\n  /**\n   * Builds a variable ref alias that maps to another variable ref.\n   * Calls the given delegate whenever the value is requested to be read or set.\n   */\n  registerVariableDelegate(variableName: string, delegate: IVariableDelegate): void;\n}\n\nexport interface INativeCompilerBlockBuilderFunctionContext {\n  readonly requestedClosureArguments: NativeCompilerBuilderVariableRef[];\n\n  requestClosureArgument(\n    variableName: string,\n    source: NativeCompilerBuilderVariableRef,\n  ): NativeCompilerBuilderVariableRef;\n\n  registerVariable(type: NativeCompilerBuilderVariableType, assignable: boolean): NativeCompilerBuilderVariableID;\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/NativeCompilerBuilder.ts",
    "content": "import {\n  INativeCompilerBlockBuilder,\n  NativeCompilerBuilderVariableID,\n  NativeCompilerBuilderAtomID,\n  NativeCompilerBuilderJumpTargetID,\n  INativeCompilerJumpTargetBuilder,\n  INativeCompilerLoopBuilder,\n  INativeCompilerFunctionBuilder,\n  INativeCompilerTryCatchBuilder,\n  NativeCompilerBuilderVariableType,\n  NativeCompilerBuilderBranchType,\n  ConstValue,\n  NativeCompilerBuilderVariableRef,\n  VariableRefScope,\n  IVariableDelegate,\n} from './INativeCompilerBuilder';\nimport {\n  INativeCompilerBlockBuilderFunctionContextListener,\n  NativeCompilerBlockBuilderFunctionContext,\n  NativeCompilerBlockBuilderScopeContext,\n} from './internal/NativeCompilerBlockBuilderContext';\nimport { NativeCompilerIR } from './NativeCompilerBuilderIR';\nimport { NativeCompilerTransformerResolveBuilderStubs } from './internal/transformers/NativeCompilerTransformerResolveBuilderStubs';\nimport { NativeCompilerTransformerResolveSlots } from './internal/transformers/NativeCompilerTransformerResolveSlots';\nimport { NativeCompilerTransformerInsertRetainRelease } from './internal/transformers/NativeCompilerTransformerInsertRetainRelease';\nimport { NativeCompilerOptions } from '../NativeCompilerOptions';\nimport { NativeCompilerTransformerOptimizeVarRefs } from './internal/transformers/NativeCompilerTransformerOptimizeVarRefs';\nimport { NativeCompilerTransformerOptimizeLoads } from './internal/transformers/NativeCompilerTransformerOptimizeLoads';\nimport { NativeCompilerTransformerMergeRelease } from './internal/transformers/NativeCompilerTransformerMergeRelease';\nimport { NativeCompilerTransformerOptimizeAssignments } from './internal/transformers/NativeCompilerTransformerOptimizeAssignments';\nimport { NativeCompilerTransformerConstantFolding } from './internal/transformers/NativeCompilerTransformerConstantFolding';\nimport { NativeCompilerTransformerAutoRelease } from './internal/transformers/NativeCompilerTransformerAutoRelease';\n\nimport {\n  VariableContext,\n  VariableResolvingMode,\n  variableResultIsVariableDelegate,\n  variableResultIsVariableRef,\n} from './VariableContext';\n\nconst intrinsicFunctionNames = new Map<string, string>([\n  ['Math.log', 'tsn_math_log'],\n  ['Math.pow', 'tsn_math_pow'],\n  ['Math.floor', 'tsn_math_floor'],\n  // ['Math.max', 'tsn_math_max_v'],\n]);\n\nconst intrinsicConstants = new Map<string, number | string>([\n  ['Math.PI', Math.PI],\n  ['Math.E', Math.E],\n  ['Math.LN10', Math.LN10],\n  ['Math.LN2', Math.LN2],\n  ['Math.LOG10E', Math.LOG10E],\n  ['Math.LOG2E', Math.LOG2E],\n  ['Math.SQRT1_2', Math.SQRT1_2],\n  ['Math.SQRT2', Math.SQRT2],\n]);\n\n//TODO(5174):Should make variables read only this will allow for optimizations down the road\nexport class NativeCompilerBlockBuilder implements INativeCompilerBlockBuilder {\n  private ir = new Array<NativeCompilerIR.Base>();\n  private subbuilder = new Array<NativeCompilerBlockBuilder>();\n\n  private globalVariable: NativeCompilerBuilderVariableID | undefined;\n  private variableRefIRInsertionIndex = 0;\n  private lastLineNumber = 0;\n\n  constructor(\n    private readonly context: NativeCompilerBlockBuilderFunctionContext,\n    readonly scopeContext: NativeCompilerBlockBuilderScopeContext,\n    readonly variableContext: VariableContext,\n    public closureBlock: INativeCompilerBlockBuilder | undefined,\n  ) {}\n\n  private internalBuildSubBuilder(\n    parentScope: NativeCompilerBlockBuilderScopeContext,\n    variableContext: VariableContext,\n  ): NativeCompilerBlockBuilder {\n    const retval = new NativeCompilerBlockBuilder(this.context, parentScope, variableContext, this.closureBlock);\n    const ir: NativeCompilerIR.BuilderStub = {\n      kind: NativeCompilerIR.Kind.BuilderStub,\n      index: this.subbuilder.length,\n    };\n    this.ir.push(ir);\n    this.subbuilder.push(retval);\n    return retval;\n  }\n\n  registerExceptionTargetInScope(target: NativeCompilerBuilderJumpTargetID): void {\n    this.scopeContext.registerExceptionTargetInScope(target);\n  }\n\n  resolveExceptionTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined {\n    return this.scopeContext.resolveExceptionTargetInScope();\n  }\n\n  resolveExceptionTargetInScopeOrThrow(): NativeCompilerBuilderJumpTargetID {\n    const jumpTarget = this.resolveExceptionTargetInScope();\n    if (jumpTarget === undefined) {\n      throw new Error('Could not resolve exception jump target');\n    }\n\n    return jumpTarget;\n  }\n\n  registerLazyVariableRef(\n    variableName: string,\n    scope: VariableRefScope,\n    doBuild: (builder: INativeCompilerBlockBuilder) => NativeCompilerBuilderVariableRef,\n  ): void {\n    const irEnd = this.ir.length;\n\n    this.variableContext.registerLazyVariableRef(variableName, () => {\n      return this.buildWithIRInsertionIndex(irEnd, doBuild);\n    });\n  }\n\n  private buildWithIRInsertionIndex<T>(\n    insertionIndex: number,\n    doBuild: (builder: INativeCompilerBlockBuilder) => T,\n  ): T {\n    const savedIR = this.ir;\n    this.ir = [];\n    const result = doBuild(this);\n    // Restore IR\n    const newIR = this.ir;\n    this.ir = [...savedIR.slice(0, insertionIndex), ...newIR, ...savedIR.slice(insertionIndex)];\n\n    return result;\n  }\n\n  private checkVariableId(variableId: NativeCompilerBuilderVariableID) {\n    if (variableId.functionId !== this.context.functionId) {\n      throw new Error('Attempting to manipulate variables from a different function id');\n    }\n  }\n\n  private checkVariableRef(variableRef: NativeCompilerBuilderVariableRef) {\n    this.checkVariableId(variableRef.variableId);\n  }\n\n  buildUninitializedVariableRef(\n    variableName: string,\n    type: NativeCompilerBuilderVariableType,\n    constValue?: ConstValue,\n  ): NativeCompilerBuilderVariableRef {\n    const variableRef = new NativeCompilerBuilderVariableRef(\n      variableName,\n      type,\n      this.context.registerVariable(NativeCompilerBuilderVariableType.VariableRef),\n      constValue,\n    );\n\n    this.variableContext.registerVariableRefInScope(variableRef);\n\n    return variableRef;\n  }\n\n  private doBuildVariableRef(\n    variableName: string,\n    type: NativeCompilerBuilderVariableType,\n    isConst?: boolean,\n  ): NativeCompilerBuilderVariableRef {\n    const variableRef = this.buildUninitializedVariableRef(\n      variableName,\n      type,\n      isConst ? new ConstValue(type) : undefined,\n    );\n\n    const ir: NativeCompilerIR.NewVariableRef = {\n      kind: NativeCompilerIR.Kind.NewVariableRef,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variableRef.variableId!,\n      name: variableName,\n      constValue: variableRef.constValue,\n    };\n    this.ir.push(ir);\n\n    return variableRef;\n  }\n\n  buildVariableRef(\n    variableName: string,\n    type: NativeCompilerBuilderVariableType,\n    scope: VariableRefScope,\n    isConst?: boolean,\n  ): NativeCompilerBuilderVariableRef {\n    switch (scope) {\n      case VariableRefScope.Block: {\n        return this.doBuildVariableRef(variableName, type, isConst);\n      }\n      case VariableRefScope.Function: {\n        if (this.closureBlock) {\n          return this.closureBlock.buildVariableRef(variableName, type, scope, isConst);\n        }\n\n        const irLengthBefore = this.ir.length;\n        const variableRef = this.buildWithIRInsertionIndex(this.variableRefIRInsertionIndex, () => {\n          // 'var' declarations can be re-declared. We should re-use the existing variable in that case.\n          let existingVariable = this.doResolveVariableRefOrDelegate(variableName, VariableResolvingMode.shallow);\n          if (existingVariable instanceof NativeCompilerBuilderVariableRef) {\n            return existingVariable;\n          }\n\n          return this.doBuildVariableRef(variableName, type, isConst);\n        });\n\n        this.variableRefIRInsertionIndex += this.ir.length - irLengthBefore;\n\n        return variableRef;\n      }\n    }\n  }\n\n  buildInitializedVariableRef(\n    variableName: string,\n    value: NativeCompilerBuilderVariableID,\n    scope: VariableRefScope,\n  ): NativeCompilerBuilderVariableRef {\n    this.checkVariableId(value);\n    const variableRef = this.buildVariableRef(variableName, value.type, scope);\n    this.buildSetVariableRef(variableRef, value);\n    return variableRef;\n  }\n\n  buildLoadVariableRef(variableRef: NativeCompilerBuilderVariableRef): NativeCompilerBuilderVariableID {\n    this.checkVariableRef(variableRef);\n\n    const variable = this.context.registerVariable(variableRef.type);\n    const ir: NativeCompilerIR.LoadVariableRef = {\n      kind: NativeCompilerIR.Kind.LoadVariableRef,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable,\n      target: variableRef.variableId,\n    };\n    this.ir.push(ir);\n    this.variableContext.registerVariableRefAlias(variableRef, variable);\n    return variable;\n  }\n\n  buildSetVariableRef(variableRef: NativeCompilerBuilderVariableRef, value: NativeCompilerBuilderVariableID): void {\n    this.checkVariableRef(variableRef);\n\n    variableRef.addType(value.type);\n\n    const ir: NativeCompilerIR.SetVariableRef = {\n      kind: NativeCompilerIR.Kind.SetVariableRef,\n      target: variableRef.variableId,\n      value: value,\n    };\n\n    this.ir.push(ir);\n  }\n\n  registerVariableDelegate(variableName: string, delegate: IVariableDelegate): void {\n    this.variableContext.registerVariableDelegate(variableName, delegate);\n  }\n\n  private doResolveVariableRefOrDelegate(\n    variableName: string,\n    scope: VariableResolvingMode,\n  ): NativeCompilerBuilderVariableRef | IVariableDelegate | undefined {\n    return this.variableContext.resolveVariable(variableName, scope);\n  }\n\n  resolveVariableRefOrDelegateInScope(\n    variableName: string,\n  ): NativeCompilerBuilderVariableRef | IVariableDelegate | undefined {\n    return this.doResolveVariableRefOrDelegate(variableName, VariableResolvingMode.full);\n  }\n\n  resolveVariableInScope(variableName: string): NativeCompilerBuilderVariableID | undefined {\n    const variableRefOrDelegate = this.resolveVariableRefOrDelegateInScope(variableName);\n    if (!variableRefOrDelegate) {\n      return undefined;\n    }\n\n    if (variableRefOrDelegate instanceof NativeCompilerBuilderVariableRef) {\n      return this.buildLoadVariableRef(variableRefOrDelegate);\n    } else {\n      return variableRefOrDelegate.onGetValue(this);\n    }\n  }\n\n  registerExitTargetInScope(target: NativeCompilerBuilderJumpTargetID): void {\n    this.scopeContext.registerExitTargetInScope(target);\n  }\n\n  resolveExitTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined {\n    return this.scopeContext.resolveExitTargetInScope();\n  }\n\n  registerContinueTargetInScope(target: NativeCompilerBuilderJumpTargetID): void {\n    this.scopeContext.registerContinueTargetInScope(target);\n  }\n\n  resolveContinueTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined {\n    return this.scopeContext.resolveContinueTargetInScope();\n  }\n\n  buildFunctionBodySubBuilder(closureBlockBuilder: INativeCompilerBlockBuilder): NativeCompilerBlockBuilder {\n    const ret = this.buildSubBuilder(false);\n    ret.closureBlock = closureBlockBuilder;\n\n    return ret;\n  }\n\n  buildSubBuilder(scoped: boolean): NativeCompilerBlockBuilder {\n    const parentScope = this.scopeContext;\n    let retval: NativeCompilerBlockBuilder;\n    if (scoped) {\n      retval = this.internalBuildSubBuilder(parentScope.createSubScopeContext(), this.variableContext.scoped());\n    } else {\n      retval = this.internalBuildSubBuilder(parentScope, this.variableContext);\n    }\n    return retval;\n  }\n\n  buildJumpTarget(tag: string): INativeCompilerJumpTargetBuilder {\n    const jumpTarget = this.context.registerJumpTarget(tag);\n    const ir: NativeCompilerIR.BindJumpTarget = {\n      kind: NativeCompilerIR.Kind.BindJumpTarget,\n      target: jumpTarget,\n    };\n    this.ir.push(ir);\n    return { target: jumpTarget, builder: this.buildSubBuilder(false) };\n  }\n\n  buildJump(jumpTarget: NativeCompilerBuilderJumpTargetID): void {\n    const ir: NativeCompilerIR.Jump = {\n      kind: NativeCompilerIR.Kind.Jump,\n      target: jumpTarget,\n    };\n    this.ir.push(ir);\n  }\n\n  buildBranch(\n    variable: NativeCompilerBuilderVariableID,\n    type: NativeCompilerBuilderBranchType,\n    trueTarget: NativeCompilerBuilderJumpTargetID,\n    falseTarget: NativeCompilerBuilderJumpTargetID | undefined,\n  ): void {\n    this.checkVariableId(variable);\n    const ir: NativeCompilerIR.Branch = {\n      kind: NativeCompilerIR.Kind.Branch,\n      conditionVariable: variable,\n      type: type,\n      trueTarget: trueTarget,\n      falseTarget: falseTarget,\n    };\n    this.ir.push(ir);\n  }\n\n  buildThrow(value: NativeCompilerBuilderVariableID): void {\n    this.checkVariableId(value);\n    const ir: NativeCompilerIR.Throw = {\n      kind: NativeCompilerIR.Kind.Throw,\n      target: this.resolveExceptionTargetInScopeOrThrow(),\n      value: value,\n    };\n    this.ir.push(ir);\n  }\n\n  buildSetProperty(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    value: NativeCompilerBuilderVariableID,\n  ): void {\n    this.checkVariableId(object);\n    this.checkVariableId(value);\n\n    const ir: NativeCompilerIR.SetProperty = {\n      kind: NativeCompilerIR.Kind.SetProperty,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: object,\n      properties: [property],\n      values: [value],\n    };\n    this.ir.push(ir);\n  }\n\n  buildSetProperties(\n    object: NativeCompilerBuilderVariableID,\n    properties: NativeCompilerBuilderAtomID[],\n    values: NativeCompilerBuilderVariableID[],\n  ): void {\n    this.checkVariableId(object);\n    values.forEach((v) => this.checkVariableId(v));\n\n    const ir: NativeCompilerIR.SetProperty = {\n      kind: NativeCompilerIR.Kind.SetProperty,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: object,\n      properties: properties,\n      values: values,\n    };\n    this.ir.push(ir);\n  }\n\n  buildSetPropertyValue(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    value: NativeCompilerBuilderVariableID,\n  ): void {\n    this.checkVariableId(object);\n    this.checkVariableId(property);\n    this.checkVariableId(value);\n\n    const ir: NativeCompilerIR.SetPropertyValue = {\n      kind: NativeCompilerIR.Kind.SetPropertyValue,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: object,\n      property: property,\n      value: value,\n    };\n    this.ir.push(ir);\n  }\n\n  buildSetPropertyIndex(\n    object: NativeCompilerBuilderVariableID,\n    index: number,\n    value: NativeCompilerBuilderVariableID,\n  ): void {\n    this.checkVariableId(object);\n    this.checkVariableId(value);\n\n    const ir: NativeCompilerIR.SetPropertyIndex = {\n      kind: NativeCompilerIR.Kind.SetPropertyIndex,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: object,\n      index,\n      value: value,\n    };\n    this.ir.push(ir);\n  }\n\n  buildCopyPropertiesFrom(\n    destObject: NativeCompilerBuilderVariableID,\n    sourceObject: NativeCompilerBuilderVariableID,\n    propertiesToIgnore: NativeCompilerBuilderAtomID[] | undefined,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(destObject);\n    this.checkVariableId(sourceObject);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Number);\n    const ir: NativeCompilerIR.CopyPropertiesFrom = {\n      kind: NativeCompilerIR.Kind.CopyPropertiesFrom,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: destObject,\n      value: sourceObject,\n      propertiesToIgnore,\n      copiedPropertiesCount: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildGetPropertyValue(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    thisObject: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(object);\n    this.checkVariableId(property);\n    this.checkVariableId(thisObject);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.GetPropertyValue = {\n      kind: NativeCompilerIR.Kind.GetPropertyValue,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: object,\n      property: property,\n      variable: variable,\n      thisObject: thisObject,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildDeleteProperty(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(object);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Bool);\n    const ir: NativeCompilerIR.DeleteProperty = {\n      kind: NativeCompilerIR.Kind.DeleteProperty,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: object,\n      property: property,\n      variable,\n    };\n\n    this.ir.push(ir);\n\n    return variable;\n  }\n\n  buildDeletePropertyValue(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(object);\n    this.checkVariableId(property);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Bool);\n    const ir: NativeCompilerIR.DeletePropertyValue = {\n      kind: NativeCompilerIR.Kind.DeletePropertyValue,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: object,\n      property: property,\n      variable,\n    };\n\n    this.ir.push(ir);\n\n    return variable;\n  }\n\n  buildGetClosureVariableRef(\n    variableName: string,\n    closureIndex: number,\n    source: NativeCompilerBuilderVariableRef,\n  ): NativeCompilerBuilderVariableRef {\n    const variableRef = this.buildUninitializedVariableRef(\n      variableName,\n      // leave type as empty for const var ref so that we can add type later\n      source.constValue ? NativeCompilerBuilderVariableType.Empty : NativeCompilerBuilderVariableType.Object,\n      // inherit the source's const definition\n      source.constValue,\n    );\n\n    const ir: NativeCompilerIR.GetClosureArg = {\n      kind: NativeCompilerIR.Kind.GetClosureArg,\n      index: closureIndex,\n      variable: variableRef.variableId!,\n      constValue: source.constValue,\n    };\n    this.ir.push(ir);\n\n    return variableRef;\n  }\n\n  buildGetModuleConst(index: number): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n\n    const ir: NativeCompilerIR.GetModuleConst = {\n      kind: NativeCompilerIR.Kind.GetModuleConst,\n      index,\n      variable,\n    };\n\n    this.ir.push(ir);\n\n    return variable;\n  }\n\n  buildGetProperty(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    thisObject: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(object);\n    this.checkVariableId(thisObject);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.GetProperty = {\n      kind: NativeCompilerIR.Kind.GetProperty,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      object: object,\n      property: property,\n      variable: variable,\n      thisObject: thisObject,\n      propCacheSlot: 0,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  getIntrinsicConstant(name: string): number | string | undefined {\n    return intrinsicConstants.get(name);\n  }\n\n  hasIntrinsicFunction(func: string): boolean {\n    return intrinsicFunctionNames.has(func);\n  }\n\n  buildIntrinsicCall(func: string, args: Array<NativeCompilerBuilderVariableID>): NativeCompilerBuilderVariableID {\n    for (const arg of args) {\n      this.checkVariableId(arg);\n    }\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Number);\n    const ir: NativeCompilerIR.IntrinsicCall = {\n      kind: NativeCompilerIR.Kind.IntrinsicCall,\n      func: intrinsicFunctionNames.get(func)!,\n      args: args,\n      variable: variable,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildFunctionInvocation(\n    func: NativeCompilerBuilderVariableID,\n    args: Array<NativeCompilerBuilderVariableID>,\n    obj: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(func);\n    this.checkVariableId(obj);\n\n    for (const arg of args) {\n      this.checkVariableId(arg);\n    }\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.FunctionInvocation = {\n      kind: NativeCompilerIR.Kind.FunctionInvocation,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      func: func,\n      args: args,\n      obj: obj,\n      variable: variable,\n      argsType: NativeCompilerIR.FunctionArgumentsType.Direct,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildFunctionInvocationWithArgsArray(\n    func: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID,\n    obj: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(func);\n    this.checkVariableId(args);\n    this.checkVariableId(obj);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.FunctionInvocation = {\n      kind: NativeCompilerIR.Kind.FunctionInvocation,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      func: func,\n      args: [args],\n      obj: obj,\n      variable: variable,\n      argsType: NativeCompilerIR.FunctionArgumentsType.Indirect,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildConstructorInvocation(\n    func: NativeCompilerBuilderVariableID,\n    new_target: NativeCompilerBuilderVariableID,\n    args: Array<NativeCompilerBuilderVariableID>,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(func);\n    for (const arg of args) {\n      this.checkVariableId(arg);\n    }\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.ConstructorInvocation = {\n      kind: NativeCompilerIR.Kind.ConstructorInvocation,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      func: func,\n      new_target: new_target,\n      args: args,\n      variable: variable,\n      argsType: NativeCompilerIR.FunctionArgumentsType.Direct,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildConstructorInvocationWithArgsArray(\n    func: NativeCompilerBuilderVariableID,\n    new_target: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(func);\n    this.checkVariableId(args);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.ConstructorInvocation = {\n      kind: NativeCompilerIR.Kind.ConstructorInvocation,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      func: func,\n      new_target: new_target,\n      args: [args],\n      variable: variable,\n      argsType: NativeCompilerIR.FunctionArgumentsType.Indirect,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildGetFunctionArg(index: number): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.GetFunctionArg = {\n      kind: NativeCompilerIR.Kind.GetFunctionArg,\n      index: index,\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildGetFunctionArgumentsObject(startIndex: number): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.GetFunctionArgumentsObject = {\n      kind: NativeCompilerIR.Kind.GetFunctionArgumentsObject,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      startIndex,\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildKeyword(keywordKind: NativeCompilerIR.KeywordKind) {\n    let variableType: NativeCompilerBuilderVariableType;\n    switch (keywordKind) {\n      case NativeCompilerIR.KeywordKind.Undefined:\n        variableType = NativeCompilerBuilderVariableType.Undefined;\n        break;\n      case NativeCompilerIR.KeywordKind.Null:\n        variableType = NativeCompilerBuilderVariableType.Null;\n        break;\n      case NativeCompilerIR.KeywordKind.This:\n        variableType = NativeCompilerBuilderVariableType.Object;\n        break;\n      case NativeCompilerIR.KeywordKind.NewTarget:\n        variableType = NativeCompilerBuilderVariableType.Object;\n        break;\n    }\n\n    const variable = this.context.registerVariable(variableType, false);\n    const ir: NativeCompilerIR.Keyword = {\n      kind: NativeCompilerIR.Kind.Keyword,\n      variable: variable,\n      keyword: keywordKind,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildGetSuper(): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(\n      NativeCompilerBuilderVariableType.Object | NativeCompilerBuilderVariableType.Super,\n    );\n\n    const ir: NativeCompilerIR.GetSuper = {\n      kind: NativeCompilerIR.Kind.GetSuper,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildGetSuperConstructor(): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(\n      NativeCompilerBuilderVariableType.Object | NativeCompilerBuilderVariableType.Super,\n    );\n\n    const ir: NativeCompilerIR.GetSuperConstructor = {\n      kind: NativeCompilerIR.Kind.GetSuperConstructor,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildAssignableUndefined(): NativeCompilerBuilderVariableID {\n    return this.context.registerVariable(NativeCompilerBuilderVariableType.Undefined);\n  }\n\n  buildUndefined(): NativeCompilerBuilderVariableID {\n    if (!this.context.undefinedVariable) {\n      this.context.undefinedVariable = this.context.registerVariable(\n        NativeCompilerBuilderVariableType.Undefined,\n        false,\n      );\n    }\n    return this.context.undefinedVariable;\n  }\n\n  buildNull(): NativeCompilerBuilderVariableID {\n    if (!this.context.nullVariable) {\n      this.context.nullVariable = this.context.registerVariable(NativeCompilerBuilderVariableType.Null, false);\n    }\n    return this.context.nullVariable;\n  }\n\n  buildThis(): NativeCompilerBuilderVariableID {\n    return this.buildKeyword(NativeCompilerIR.KeywordKind.This);\n  }\n\n  buildNewTarget(): NativeCompilerBuilderVariableID {\n    return this.buildKeyword(NativeCompilerIR.KeywordKind.NewTarget);\n  }\n\n  buildCopy(value: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID {\n    this.checkVariableId(value);\n\n    const variable = this.context.registerVariable(value.type);\n    this.buildAssignment(variable, value);\n\n    return variable;\n  }\n\n  buildException(retVar?: NativeCompilerBuilderVariableID) {\n    const variable = retVar ?? this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.Exception = {\n      kind: NativeCompilerIR.Kind.Exception,\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildLiteralInteger(value: string): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Number);\n    const ir: NativeCompilerIR.LiteralInteger = {\n      kind: NativeCompilerIR.Kind.LiteralInteger,\n      variable: variable,\n      value: value,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildLiteralLong(value: string): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Number);\n    const ir: NativeCompilerIR.LiteralLong = {\n      kind: NativeCompilerIR.Kind.LiteralLong,\n      variable: variable,\n      value: value,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildLiteralDouble(value: string): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Number);\n    const ir: NativeCompilerIR.LiteralDouble = {\n      kind: NativeCompilerIR.Kind.LiteralDouble,\n      variable: variable,\n      value: value,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildLiteralString(value: string): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.LiteralString = {\n      kind: NativeCompilerIR.Kind.LiteralString,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n      value: value,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildLiteralBool(value: boolean): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Bool);\n    const ir: NativeCompilerIR.LiteralBool = {\n      kind: NativeCompilerIR.Kind.LiteralBool,\n      variable: variable,\n      value: value,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildGetException(): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.GetException = {\n      kind: NativeCompilerIR.Kind.GetException,\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildCheckException(jumpTarget: NativeCompilerBuilderJumpTargetID): void {\n    const ir: NativeCompilerIR.CheckException = {\n      kind: NativeCompilerIR.Kind.CheckException,\n      exceptionTarget: jumpTarget,\n    };\n    this.ir.push(ir);\n  }\n\n  buildGlobal(): NativeCompilerBuilderVariableID {\n    if (this.globalVariable === undefined) {\n      const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n      const ir: NativeCompilerIR.Global = {\n        kind: NativeCompilerIR.Kind.Global,\n        variable: variable,\n      };\n      this.ir.push(ir);\n      this.globalVariable = variable;\n    }\n    return this.globalVariable;\n  }\n\n  buildBinaryOp(\n    operator: NativeCompilerIR.BinaryOperator,\n    left: NativeCompilerBuilderVariableID,\n    right: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(left);\n    this.checkVariableId(right);\n\n    let variableType: NativeCompilerBuilderVariableType;\n    switch (operator) {\n      case NativeCompilerIR.BinaryOperator.Mult:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.Add:\n        if (\n          left.type & NativeCompilerBuilderVariableType.Object ||\n          right.type & NativeCompilerBuilderVariableType.Object\n        ) {\n          variableType = NativeCompilerBuilderVariableType.Object;\n        } else {\n          variableType = NativeCompilerBuilderVariableType.Number;\n        }\n        break;\n      case NativeCompilerIR.BinaryOperator.Sub:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.Div:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.LeftShift:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.RightShift:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.UnsignedRightShift:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.BitwiseXOR:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.BitwiseAND:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.BitwiseOR:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.LessThan:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.LessThanOrEqual:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.LessThanOrEqualEqual:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.GreaterThan:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.GreaterThanOrEqual:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.GreaterThanOrEqualEqual:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.EqualEqual:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.EqualEqualEqual:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.DifferentThan:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.DifferentThanStrict:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.Modulo:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.Exponentiation:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.BinaryOperator.InstanceOf:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.BinaryOperator.In:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n    }\n\n    const variable = this.context.registerVariable(variableType);\n    const ir: NativeCompilerIR.BinaryOp = {\n      kind: NativeCompilerIR.Kind.BinaryOp,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      operator,\n      variable: variable,\n      left: left,\n      right: right,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildReturn(value: NativeCompilerBuilderVariableID): void {\n    this.checkVariableId(value);\n    this.buildAssignment(this.context.returnVariable, value);\n    this.buildJump(this.context.returnJumpTarget);\n  }\n\n  buildNewObject() {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.NewObject = {\n      kind: NativeCompilerIR.Kind.NewObject,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildNewArray(): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.NewArray = {\n      kind: NativeCompilerIR.Kind.NewArray,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildLoop(): INativeCompilerLoopBuilder {\n    const builderLoop = this.buildSubBuilder(true);\n\n    const builderLoopInitializer = builderLoop.buildSubBuilder(false);\n    const builderLoopMain = builderLoop.buildSubBuilder(true);\n    const builderLoopMainCondition = builderLoopMain.buildJumpTarget('cond');\n    const builderLoopMainBody = builderLoopMain.buildJumpTarget('body');\n    builderLoop.buildJump(builderLoopMainCondition.target);\n    const exitBuilder = builderLoop.buildJumpTarget('exit');\n\n    builderLoopMainBody.builder.registerExitTargetInScope(exitBuilder.target);\n    builderLoopMainBody.builder.registerContinueTargetInScope(builderLoopMainCondition.target);\n\n    return {\n      initBuilder: builderLoopInitializer,\n      condBuilder: builderLoopMainCondition.builder,\n      bodyJumpTargetBuilder: {\n        builder: builderLoopMainBody.builder,\n        target: builderLoopMainBody.target,\n      },\n      exitTarget: exitBuilder.target,\n    };\n  }\n\n  buildIterator(value: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID {\n    this.checkVariableId(value);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Iterator);\n    const ir: NativeCompilerIR.Iterator = {\n      kind: NativeCompilerIR.Kind.Iterator,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      arg: value,\n      variable: variable,\n    };\n    this.ir.push(ir);\n\n    return variable;\n  }\n\n  buildKeysIterator(value: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID {\n    this.checkVariableId(value);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Iterator);\n    const ir: NativeCompilerIR.KeysIterator = {\n      kind: NativeCompilerIR.Kind.KeysIterator,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      arg: value,\n      variable: variable,\n    };\n    this.ir.push(ir);\n\n    return variable;\n  }\n\n  buildIteratorNext(\n    value: NativeCompilerBuilderVariableID,\n    type: NativeCompilerBuilderVariableType,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(value);\n\n    const variable = this.context.registerVariable(type);\n\n    const ir: NativeCompilerIR.IteratorNext = {\n      kind: NativeCompilerIR.Kind.IteratorNext,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      iterator: value,\n      variable: variable,\n    };\n    this.ir.push(ir);\n\n    return variable;\n  }\n\n  buildKeysIteratorNext(\n    value: NativeCompilerBuilderVariableID,\n    type: NativeCompilerBuilderVariableType,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(value);\n\n    const variable = this.context.registerVariable(type);\n\n    const ir: NativeCompilerIR.KeysIteratorNext = {\n      kind: NativeCompilerIR.Kind.KeysIteratorNext,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      iterator: value,\n      variable: variable,\n    };\n    this.ir.push(ir);\n\n    return variable;\n  }\n\n  buildGenerator(closure: NativeCompilerBuilderVariableID): NativeCompilerBuilderVariableID {\n    this.checkVariableId(closure);\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.Generator = {\n      kind: NativeCompilerIR.Kind.Generator,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      arg: closure,\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildResume(): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.Resume = {\n      kind: NativeCompilerIR.Kind.Resume,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildSetResumePoint(resumePoint?: NativeCompilerBuilderJumpTargetID): void {\n    const ir: NativeCompilerIR.SetResumePoint = {\n      kind: NativeCompilerIR.Kind.SetResumePoint,\n      resumePoint: resumePoint || new NativeCompilerBuilderJumpTargetID(-1, 'end_of_func'),\n    };\n    this.ir.push(ir);\n  }\n\n  buildSuspend(value: NativeCompilerBuilderVariableID, resumePoint: NativeCompilerBuilderJumpTargetID): void {\n    this.checkVariableId(value);\n    this.buildSetResumePoint(resumePoint);\n    this.buildAssignment(this.context.returnVariable, value);\n    this.buildJump(this.context.yieldJumpTarget);\n  }\n\n  buildTryCatch(hasCatchBlock: boolean, hasFinallyBlock: boolean): INativeCompilerTryCatchBuilder {\n    const tryJumpTarget = this.buildJumpTarget('try');\n    const catchJumpTarget = hasCatchBlock ? this.buildJumpTarget('catch') : undefined;\n    const finallyJumpTarget = this.buildJumpTarget('finally');\n\n    const tryBuilder = tryJumpTarget.builder.buildSubBuilder(true);\n    if (catchJumpTarget) {\n      // If we have a catch block, we will jump to our catch block within ou try statement\n      // when an exception is thrown\n      tryBuilder.registerExceptionTargetInScope(catchJumpTarget.target);\n    } else if (hasFinallyBlock) {\n      // Otherwise, we will jump to the finally block if it's provided\n      tryBuilder.registerExceptionTargetInScope(finallyJumpTarget.target);\n    }\n    // Jump to finally at the end of the try\n    tryJumpTarget.builder.buildJump(finallyJumpTarget.target);\n\n    const catchBuilder = catchJumpTarget && catchJumpTarget.builder.buildSubBuilder(true);\n    if (catchBuilder) {\n      if (hasFinallyBlock) {\n        // On nested exceptions thrown within the catch, we jump to the finally block\n        catchBuilder.registerExceptionTargetInScope(finallyJumpTarget.target);\n      }\n      catchJumpTarget.builder.buildJump(finallyJumpTarget.target);\n    }\n\n    let finallyBuilder: INativeCompilerBlockBuilder | undefined;\n    if (hasFinallyBlock) {\n      const finallyBuilderOuter = finallyJumpTarget.builder.buildSubBuilder(true);\n      finallyBuilder = finallyBuilderOuter.buildSubBuilder(false);\n      const finallyBuilderPostCheckBuilder = finallyBuilderOuter.buildSubBuilder(false);\n      // Handle case where exception was not handled, or a nested exception was thrown inside the catch.\n      // In this case we want to jump to our outer exception target at the end of the finally block\n      finallyBuilderPostCheckBuilder.buildCheckException(this.resolveExceptionTargetInScopeOrThrow());\n    }\n\n    return {\n      tryBuilder,\n      catchBuilder,\n      finallyBuilder,\n    };\n  }\n\n  buildComments(text: string): void {\n    const ir: NativeCompilerIR.Comments = {\n      kind: NativeCompilerIR.Kind.Comments,\n      text,\n    };\n    this.ir.push(ir);\n  }\n\n  buildProgramCounterInfo(lineNumber: number, columnNumber: number): void {\n    if (this.lastLineNumber === lineNumber) {\n      // Only emit when line number is changing\n      return;\n    }\n\n    this.lastLineNumber = lineNumber;\n\n    const ir: NativeCompilerIR.ProgramCounterInfo = {\n      kind: NativeCompilerIR.Kind.ProgramCounterInfo,\n      lineNumber: lineNumber,\n      columnNumber: columnNumber,\n    };\n\n    this.ir.push(ir);\n  }\n\n  buildNewFunctionValue(\n    functionName: string,\n    name: NativeCompilerBuilderAtomID,\n    argc: number,\n    closureArguments: NativeCompilerBuilderVariableRef[],\n  ): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.NewFunctionValue = {\n      kind: NativeCompilerIR.Kind.NewFunctionValue,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n      functionName: functionName,\n      name,\n      argc,\n      closureArgs: this.resolveClosureArguments(closureArguments),\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildNewClassValue(\n    functionName: string,\n    constructorName: NativeCompilerBuilderAtomID,\n    argc: number,\n    parentClass: NativeCompilerBuilderVariableID,\n    closureArguments: NativeCompilerBuilderVariableRef[],\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(parentClass);\n\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.NewClassValue = {\n      kind: NativeCompilerIR.Kind.NewClassValue,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n      functionName: functionName,\n      argc,\n      parentClass,\n      name: constructorName,\n      closureArgs: this.resolveClosureArguments(closureArguments),\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildSetClassElement(\n    type: NativeCompilerIR.ClassElementType,\n    classVariable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderAtomID,\n    value: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n  ): void {\n    this.checkVariableId(classVariable);\n    this.checkVariableId(value);\n\n    const ir: NativeCompilerIR.SetClassElement = {\n      kind: NativeCompilerIR.Kind.SetClassElement,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      type,\n      cls: classVariable,\n      name,\n      value,\n      static: isStatic,\n    };\n    this.ir.push(ir);\n  }\n\n  buildSetClassElementValue(\n    type: NativeCompilerIR.ClassElementType,\n    classVariable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderVariableID,\n    value: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n  ): void {\n    this.checkVariableId(classVariable);\n    this.checkVariableId(name);\n    this.checkVariableId(value);\n\n    const ir: NativeCompilerIR.SetClassElementValue = {\n      kind: NativeCompilerIR.Kind.SetClassElementValue,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      type,\n      cls: classVariable,\n      name,\n      value,\n      static: isStatic,\n    };\n    this.ir.push(ir);\n  }\n\n  private resolveClosureArguments(\n    closureArguments: NativeCompilerBuilderVariableRef[],\n  ): NativeCompilerBuilderVariableID[] {\n    const resolvedClosureArguments: NativeCompilerBuilderVariableID[] = [];\n    for (const reference of closureArguments) {\n      const variableRef = this.resolveVariableRefOrDelegateInScope(reference.name);\n      if (variableRef instanceof NativeCompilerBuilderVariableRef) {\n        resolvedClosureArguments.push(variableRef.variableId);\n        // Reconcile types from captured variable ref\n        variableRef.addType(reference.type);\n      } else {\n        throw new Error(`Unrecognized local variable ${reference}`);\n      }\n    }\n\n    return resolvedClosureArguments;\n  }\n\n  buildNewArrowFunctionValue(\n    functionName: string,\n    argc: number,\n    closureArguments: NativeCompilerBuilderVariableRef[],\n    stackOnHeap: boolean,\n  ): NativeCompilerBuilderVariableID {\n    const variable = this.context.registerVariable(NativeCompilerBuilderVariableType.Object);\n    const ir: NativeCompilerIR.NewArrowFunctionValue = {\n      kind: NativeCompilerIR.Kind.NewArrowFunctionValue,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      variable: variable,\n      functionName: functionName,\n      argc,\n      closureArgs: this.resolveClosureArguments(closureArguments),\n      stackOnHeap: stackOnHeap,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  buildAssignment(left: NativeCompilerBuilderVariableID, right: NativeCompilerBuilderVariableID): void {\n    //TODO(rjaber): Get rid of this on phi instruction brah\n    this.checkVariableId(left);\n    this.checkVariableId(right);\n\n    if (!left.assignable) {\n      throw new Error(`Variable ${left.toString()} is not assignable`);\n    }\n\n    left.addType(right.type);\n\n    const variableRef = this.variableContext.getVariableRefForAlias(left);\n    if (variableRef) {\n      // We are assigning to an alias of a variable ref. Replace to a SetVariableRef instead\n      this.buildSetVariableRef(variableRef, right);\n    } else {\n      const ir: NativeCompilerIR.Assignment = {\n        kind: NativeCompilerIR.Kind.Assignment,\n        left: left,\n        right: right,\n      };\n      this.ir.push(ir);\n    }\n  }\n\n  buildUnaryOp(\n    operator: NativeCompilerIR.UnaryOperator,\n    operand: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableID {\n    this.checkVariableId(operand);\n\n    let variableType: NativeCompilerBuilderVariableType;\n    switch (operator) {\n      case NativeCompilerIR.UnaryOperator.Neg:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.UnaryOperator.Plus:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.UnaryOperator.Inc:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.UnaryOperator.Dec:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.UnaryOperator.BitwiseNot:\n        variableType = NativeCompilerBuilderVariableType.Number;\n        break;\n      case NativeCompilerIR.UnaryOperator.LogicalNot:\n        variableType = NativeCompilerBuilderVariableType.Bool;\n        break;\n      case NativeCompilerIR.UnaryOperator.TypeOf:\n        variableType = NativeCompilerBuilderVariableType.Object;\n        break;\n    }\n\n    const variable = this.context.registerVariable(variableType);\n    const ir: NativeCompilerIR.UnaryOp = {\n      kind: NativeCompilerIR.Kind.UnaryOp,\n      exceptionTarget: this.resolveExceptionTargetInScopeOrThrow(),\n      operator,\n      variable: variable,\n      operand: operand,\n    };\n    this.ir.push(ir);\n    return variable;\n  }\n\n  registerExportsVariableRef(variableRef: NativeCompilerBuilderVariableRef): void {\n    this.checkVariableRef(variableRef);\n\n    this.scopeContext.registerExportsVariableRef(variableRef);\n  }\n\n  resolveExportsVariableRef(): NativeCompilerBuilderVariableRef {\n    const variableRef = this.scopeContext.resolveExportsVariableRef();\n    if (!variableRef) {\n      throw new Error('Could not resolve exports variable ref in current scope');\n    }\n\n    return variableRef;\n  }\n\n  resolveExportsVariable(): NativeCompilerBuilderVariableID {\n    const variableRef = this.resolveExportsVariableRef();\n    return this.buildLoadVariableRef(variableRef);\n  }\n\n  finalize(options: NativeCompilerOptions) {\n    const out: NativeCompilerIR.Base[] = [];\n    for (const ir of this.ir) {\n      switch (ir.kind) {\n        case NativeCompilerIR.Kind.LoadVariableRef: {\n          const oldIR = ir as NativeCompilerIR.LoadVariableRef;\n          let vref = this.variableContext.getVariableRefForAlias(oldIR.variable);\n          if (vref?.constValue) {\n            // patch const ref type to its original source type.\n            // const variables must be initialized so the source must have it.\n            let newIR = { ...oldIR };\n            newIR.variable.addType(vref.constValue.type);\n            if (newIR.variable.type === NativeCompilerBuilderVariableType.Empty) {\n              // variable is const but not assigned to a primitive, assume Object\n              newIR.variable.addType(NativeCompilerBuilderVariableType.Object);\n            }\n            out.push(newIR);\n          } else {\n            out.push(oldIR);\n          }\n          break;\n        }\n        default:\n          out.push(ir);\n          break;\n      }\n    }\n    return NativeCompilerTransformerResolveBuilderStubs.transform(out, this.subbuilder, options);\n  }\n}\n\nclass NativeCompilerFunctionBuilder implements INativeCompilerBlockBuilderFunctionContextListener {\n  private parentBlock: NativeCompilerBlockBuilder;\n  private builder: INativeCompilerBlockBuilder;\n\n  readonly context: NativeCompilerBlockBuilderFunctionContext;\n  private closureBlock: INativeCompilerBlockBuilder;\n  private exceptionJumpTarget: NativeCompilerBuilderJumpTargetID;\n\n  constructor(\n    functionId: number,\n    public readonly name: string,\n    readonly type: NativeCompilerIR.FunctionType,\n    readonly parentVariableContext: VariableContext | undefined,\n    isGenerator: boolean,\n  ) {\n    this.context = new NativeCompilerBlockBuilderFunctionContext(functionId, this.name, this, isGenerator);\n    const variableContext = new VariableContext(this.context, parentVariableContext);\n    this.parentBlock = new NativeCompilerBlockBuilder(\n      this.context,\n      new NativeCompilerBlockBuilderScopeContext(undefined),\n      variableContext,\n      undefined,\n    );\n    this.context.returnVariable = this.context.registerVariable(NativeCompilerBuilderVariableType.ReturnValue);\n\n    const scopedBlock = this.parentBlock.buildSubBuilder(true);\n    this.closureBlock = scopedBlock.buildSubBuilder(false);\n    const bodyBlock = scopedBlock.buildSubBuilder(false);\n    const exceptionBlock = scopedBlock.buildJumpTarget('exception');\n    const returnBlock = scopedBlock.buildJumpTarget('return');\n\n    this.builder = bodyBlock.buildFunctionBodySubBuilder(this.closureBlock);\n    bodyBlock.buildJump(returnBlock.target);\n    const exceptionVariable = exceptionBlock.builder.buildException();\n    exceptionBlock.builder.buildAssignment(this.context.returnVariable, exceptionVariable);\n    this.exceptionJumpTarget = exceptionBlock.target;\n    this.closureBlock.registerExceptionTargetInScope(this.exceptionJumpTarget);\n    this.context.returnJumpTarget = returnBlock.target;\n    if (isGenerator) {\n      // set state to 'done' before final return\n      returnBlock.builder.buildSetResumePoint();\n      //\n      const yieldBlock = scopedBlock.buildJumpTarget('yield');\n      this.context.yieldJumpTarget = yieldBlock.target;\n    }\n  }\n\n  onClosureVariableRequested(\n    name: string,\n    index: number,\n    source: NativeCompilerBuilderVariableRef,\n  ): NativeCompilerBuilderVariableRef {\n    return this.closureBlock.buildGetClosureVariableRef(name, index, source);\n  }\n\n  getBuilder(): INativeCompilerBlockBuilder {\n    return this.builder;\n  }\n\n  finalizeReentryBlock(irs: NativeCompilerIR.Base[]) {\n    const reentry: NativeCompilerIR.Reentry = {\n      kind: NativeCompilerIR.Kind.Reentry,\n      resumePoints: [],\n    };\n    // find all resume points in the function body and add to the re-entry IR\n    for (const ir of irs) {\n      if (ir.kind === NativeCompilerIR.Kind.BindJumpTarget) {\n        const jumpTarget = ir as NativeCompilerIR.BindJumpTarget;\n        if (jumpTarget.target.tag == 'resume_point') {\n          reentry.resumePoints.push(jumpTarget.target);\n        }\n      }\n    }\n    irs.unshift(reentry);\n  }\n\n  // move the yield jump target to the last (after slot releases)\n  finalizeYieldJumpTarget(irs: NativeCompilerIR.Base[]) {\n    for (let i = irs.length - 1; i >= 0; --i) {\n      if (irs[i].kind === NativeCompilerIR.Kind.BindJumpTarget) {\n        const jumpTarget = irs[i] as NativeCompilerIR.BindJumpTarget;\n        if (jumpTarget.target.tag == 'yield') {\n          irs.splice(i, 1);\n          irs.push(jumpTarget);\n          return;\n        }\n      }\n    }\n  }\n\n  finalize(options: NativeCompilerOptions, moduleBuilder: NativeCompilerModuleBuilder): NativeCompilerIR.Base[] {\n    const startFunction: NativeCompilerIR.StartFunction = {\n      kind: NativeCompilerIR.Kind.StartFunction,\n      name: this.name,\n      type: this.type,\n      exceptionJumpTarget: this.exceptionJumpTarget,\n      returnJumpTarget: this.context.returnJumpTarget,\n      returnVariable: this.context.returnVariable,\n      localVars: [],\n    };\n    const endFunction: NativeCompilerIR.EndFunction = {\n      kind: NativeCompilerIR.Kind.EndFunction,\n      returnVariable: this.context.returnVariable,\n    };\n\n    let functionBodyIR = this.parentBlock.finalize(options);\n\n    if (options.foldConstants) {\n      let changes = 0;\n      do {\n        const res = NativeCompilerTransformerConstantFolding.transform(functionBodyIR, moduleBuilder);\n        changes = res.changes;\n        functionBodyIR = res.irs;\n      } while (changes > 0);\n    }\n\n    if (options.optimizeVarRefs) {\n      functionBodyIR = NativeCompilerTransformerOptimizeVarRefs.transform(functionBodyIR);\n    }\n\n    if (options.optimizeVarRefLoads) {\n      functionBodyIR = NativeCompilerTransformerOptimizeLoads.transform(functionBodyIR);\n    }\n\n    if (options.optimizeAssignments) {\n      functionBodyIR = NativeCompilerTransformerOptimizeAssignments.transform(functionBodyIR);\n    }\n\n    functionBodyIR = NativeCompilerTransformerResolveSlots.transform(\n      startFunction,\n      functionBodyIR,\n      endFunction,\n      options.optimizeSlots,\n      this.context.isGenerator,\n    );\n\n    functionBodyIR = NativeCompilerTransformerInsertRetainRelease.transform(startFunction, functionBodyIR, endFunction);\n\n    if (options.autoRelease) {\n      functionBodyIR = NativeCompilerTransformerAutoRelease.transform(functionBodyIR);\n    }\n\n    if (options.mergeReleases) {\n      functionBodyIR = NativeCompilerTransformerMergeRelease.transform(functionBodyIR);\n    }\n\n    if (this.context.isGenerator) {\n      this.finalizeReentryBlock(functionBodyIR);\n      this.finalizeYieldJumpTarget(functionBodyIR);\n    }\n\n    return [startFunction, ...functionBodyIR, endFunction];\n  }\n}\n\nclass NativeCompilerInitModuleBuilder {\n  private atomIdentifierToIDTable = new Map<string, NativeCompilerBuilderAtomID>();\n  private stringConstantsTable = new Map<string, number>();\n  private allAtoms: NativeCompilerBuilderAtomID[] = [];\n  private allStringConstants: string[] = [];\n  private atomIDTracker = 0;\n\n  registerAtom(identifierName: string): NativeCompilerBuilderAtomID {\n    let atomID = this.atomIdentifierToIDTable.get(identifierName);\n    if (atomID === undefined) {\n      atomID = new NativeCompilerBuilderAtomID(this.atomIDTracker++, identifierName);\n      this.atomIdentifierToIDTable.set(identifierName, atomID);\n\n      this.allAtoms.push(atomID);\n    }\n    return atomID;\n  }\n\n  registerStringConstant(value: string): number {\n    let index = this.stringConstantsTable.get(value);\n    if (index === undefined) {\n      index = this.allStringConstants.length;\n      this.stringConstantsTable.set(value, index);\n      this.allStringConstants.push(value);\n    }\n\n    return index;\n  }\n\n  get atomCount() {\n    return this.atomIdentifierToIDTable.size;\n  }\n\n  get atoms(): NativeCompilerBuilderAtomID[] {\n    return this.allAtoms;\n  }\n\n  get stringConstants(): readonly string[] {\n    return this.allStringConstants;\n  }\n}\n\nexport class NativeCompilerModuleBuilder {\n  private moduleInitBuilder: NativeCompilerInitModuleBuilder;\n  private functionBuilders = new Array<NativeCompilerFunctionBuilder>();\n  private functionIdSequence = 0;\n  private propCacheSlots = 0;\n\n  constructor(private moduleName: string, private modulePath: string) {\n    this.moduleInitBuilder = new NativeCompilerInitModuleBuilder();\n  }\n\n  registerAtom(identifierName: string): NativeCompilerBuilderAtomID {\n    return this.moduleInitBuilder.registerAtom(identifierName);\n  }\n\n  registerStringConstant(value: string): number {\n    return this.moduleInitBuilder.registerStringConstant(value);\n  }\n\n  get stringConstants(): readonly string[] {\n    return this.moduleInitBuilder.stringConstants;\n  }\n\n  buildFunction(\n    name: string,\n    sourceBuilder: INativeCompilerBlockBuilder | undefined,\n    isArrowFunction: boolean,\n    isGenerator: boolean,\n    isClass: boolean,\n  ): INativeCompilerFunctionBuilder {\n    const functionBuilder = new NativeCompilerFunctionBuilder(\n      ++this.functionIdSequence,\n      name,\n      isClass ? NativeCompilerIR.FunctionType.ClassConstructor : NativeCompilerIR.FunctionType.ModuleGenericFunction,\n      sourceBuilder?.variableContext,\n      isGenerator,\n    );\n    this.functionBuilders.push(functionBuilder);\n\n    if (!isArrowFunction) {\n      if (isClass) {\n        // 'this' is not a constant in class constructors.\n        functionBuilder\n          .getBuilder()\n          .buildInitializedVariableRef(\n            'this',\n            functionBuilder.getBuilder().buildUndefined(),\n            VariableRefScope.Function,\n          );\n      } else {\n        functionBuilder.getBuilder().registerLazyVariableRef('this', VariableRefScope.Function, (builder) => {\n          const thisVariable = builder.buildThis();\n          return functionBuilder\n            .getBuilder()\n            .buildInitializedVariableRef('this', thisVariable, VariableRefScope.Function);\n        });\n      }\n    }\n\n    return {\n      name: functionBuilder.name,\n      builder: functionBuilder.getBuilder(),\n      closureArguments: functionBuilder.context.requestedClosureArguments,\n    };\n  }\n\n  // go through the IR sequence and allocate a slot number for each get_property call\n  private assignPropertyCacheSlots(irs: NativeCompilerIR.Base[]) {\n    for (let i = 0; i < irs.length; ++i) {\n      const ir = irs[i];\n      if (ir.kind === NativeCompilerIR.Kind.GetProperty) {\n        const typedIR = ir as NativeCompilerIR.GetProperty;\n        const newIR = { ...typedIR, propCacheSlot: this.propCacheSlots++ };\n        irs[i] = newIR;\n      } else if (ir.kind === NativeCompilerIR.Kind.GetPropertyFree) {\n        const typedIR = ir as NativeCompilerIR.GetProperty;\n        const newIR = { ...typedIR, propCacheSlot: this.propCacheSlots++ };\n        irs[i] = newIR;\n      }\n    }\n  }\n\n  finalize(moduleInitFunctionName: string, options: NativeCompilerOptions): NativeCompilerIR.Base[] {\n    let retval: NativeCompilerIR.Base[] = [];\n    const prologue: NativeCompilerIR.BoilerplatePrologue = {\n      kind: NativeCompilerIR.Kind.BoilerplatePrologue,\n      atoms: this.moduleInitBuilder.atoms,\n    };\n    retval.push(prologue);\n\n    this.functionBuilders.forEach((v) => {\n      retval = retval.concat(v.finalize(options, this));\n    });\n\n    if (options.inlinePropertyCache) {\n      this.assignPropertyCacheSlots(retval);\n    }\n\n    const epilogue: NativeCompilerIR.BoilerplateEpilogue = {\n      kind: NativeCompilerIR.Kind.BoilerplateEpilogue,\n      moduleName: this.moduleName,\n      modulePath: this.modulePath,\n      moduleInitFunctionName,\n      atoms: this.moduleInitBuilder.atoms,\n      stringConstants: this.moduleInitBuilder.stringConstants,\n      propCacheSlots: this.propCacheSlots,\n    };\n\n    retval.push(epilogue);\n\n    return retval;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/NativeCompilerBuilderIR.ts",
    "content": "import {\n  ConstValue,\n  NativeCompilerBuilderAtomID,\n  NativeCompilerBuilderBranchType,\n  NativeCompilerBuilderJumpTargetID,\n  NativeCompilerBuilderVariableID,\n} from './INativeCompilerBuilder';\n\nexport namespace NativeCompilerIR {\n  export enum Kind {\n    Slot,\n    Global,\n    Keyword,\n    Exception,\n\n    SetProperty,\n    SetPropertyValue,\n    SetPropertyIndex,\n    CopyPropertiesFrom,\n    GetProperty,\n    GetPropertyFree,\n    GetPropertyValue,\n    DeleteProperty,\n    DeletePropertyValue,\n\n    GetFunctionArg,\n    GetFunctionArgumentsObject,\n\n    GetSuper,\n    GetSuperConstructor,\n\n    GetClosureArg,\n\n    GetModuleConst,\n\n    LiteralInteger,\n    LiteralLong,\n    LiteralDouble,\n    LiteralString,\n    LiteralBool,\n\n    UnaryOp,\n    BinaryOp,\n\n    NewObject,\n    NewArray,\n    NewFunctionValue,\n    NewArrowFunctionValue,\n    NewClassValue,\n\n    SetClassElement,\n    SetClassElementValue,\n\n    Retain,\n    Free,\n    FreeV,\n\n    NewVariableRef,\n    LoadVariableRef,\n    SetVariableRef,\n\n    IntrinsicCall,\n\n    FunctionInvocation,\n    ConstructorInvocation,\n    BindJumpTarget,\n    Jump,\n    Branch,\n\n    Iterator,\n    IteratorNext,\n    KeysIterator,\n    KeysIteratorNext,\n\n    Generator,\n    Resume,\n    Reentry,\n    SetResumePoint,\n\n    Assignment,\n    GetException,\n    CheckException,\n    Throw,\n\n    StartFunction,\n    EndFunction,\n\n    Comments,\n    ProgramCounterInfo,\n\n    BuilderStub,\n\n    BoilerplatePrologue,\n    BoilerplateEpilogue,\n  }\n\n  export enum KeywordKind {\n    Undefined,\n    Null,\n    This,\n    NewTarget,\n  }\n\n  export enum UnaryOperator {\n    Neg,\n    Plus,\n    Inc,\n    Dec,\n    BitwiseNot,\n    LogicalNot,\n    TypeOf,\n  }\n\n  export enum BinaryOperator {\n    Mult,\n    Add,\n    Sub,\n    Div,\n    LeftShift,\n    RightShift,\n    UnsignedRightShift,\n    BitwiseXOR,\n    BitwiseAND,\n    BitwiseOR,\n    LessThan,\n    LessThanOrEqual,\n    LessThanOrEqualEqual,\n    GreaterThan,\n    GreaterThanOrEqual,\n    GreaterThanOrEqualEqual,\n    EqualEqual,\n    EqualEqualEqual,\n    DifferentThan,\n    DifferentThanStrict,\n    Modulo,\n    Exponentiation,\n    InstanceOf,\n    In,\n  }\n\n  export enum FunctionType {\n    ModuleGenericFunction,\n    ClassConstructor,\n  }\n\n  export enum FunctionTypeArgs {\n    Context,\n    This,\n    StackFrame,\n    Argc,\n    Argv,\n    Closure,\n    NewTarget,\n  }\n\n  export const enum FunctionArgumentsType {\n    /**\n     * Arguments are passed directly.\n     */\n    Direct,\n    /**\n     * Arguments are passed through a TS array that\n     * represents the arguments.\n     */\n    Indirect,\n    /**\n     * Arguments are forwarded from the arguments\n     * that exists in the current call.\n     */\n    ForwardFromCurrentCall,\n  }\n\n  export enum ClassElementType {\n    Method,\n    Getter,\n    Setter,\n  }\n\n  const FUNCTION_ARGS_BY_TYPE = {\n    [NativeCompilerIR.FunctionType.ModuleGenericFunction]: [\n      NativeCompilerIR.FunctionTypeArgs.Context,\n      NativeCompilerIR.FunctionTypeArgs.This,\n      NativeCompilerIR.FunctionTypeArgs.StackFrame,\n      NativeCompilerIR.FunctionTypeArgs.Argc,\n      NativeCompilerIR.FunctionTypeArgs.Argv,\n      NativeCompilerIR.FunctionTypeArgs.Closure,\n    ],\n    [NativeCompilerIR.FunctionType.ClassConstructor]: [\n      NativeCompilerIR.FunctionTypeArgs.Context,\n      NativeCompilerIR.FunctionTypeArgs.NewTarget,\n      NativeCompilerIR.FunctionTypeArgs.StackFrame,\n      NativeCompilerIR.FunctionTypeArgs.Argc,\n      NativeCompilerIR.FunctionTypeArgs.Argv,\n      NativeCompilerIR.FunctionTypeArgs.Closure,\n    ],\n  };\n\n  export function getFunctionArgsFromType(type: NativeCompilerIR.FunctionType): Array<FunctionTypeArgs> {\n    return FUNCTION_ARGS_BY_TYPE[type];\n  }\n\n  export interface Base {\n    readonly kind: Kind;\n  }\n\n  export interface BaseWithReturn extends Base {\n    readonly variable: NativeCompilerBuilderVariableID;\n  }\n\n  export interface BaseWithExceptionTarget extends Base {\n    readonly exceptionTarget: NativeCompilerBuilderJumpTargetID;\n  }\n\n  export interface BaseWithReturnAndExceptionTarget extends BaseWithReturn, BaseWithExceptionTarget {}\n\n  interface LiteralBase extends BaseWithReturn {\n    readonly value: string;\n  }\n\n  interface UnaryOPBase extends BaseWithReturnAndExceptionTarget {\n    readonly operand: NativeCompilerBuilderVariableID;\n  }\n\n  interface BinaryOpBase extends BaseWithReturnAndExceptionTarget {\n    readonly left: NativeCompilerBuilderVariableID;\n    readonly right: NativeCompilerBuilderVariableID;\n  }\n\n  export interface Slot extends Base {\n    readonly kind: Kind.Slot;\n    readonly value: NativeCompilerBuilderVariableID;\n  }\n\n  export interface Global extends BaseWithReturn {\n    readonly kind: Kind.Global;\n  }\n\n  export interface SetProperty extends BaseWithExceptionTarget {\n    readonly kind: Kind.SetProperty;\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly properties: NativeCompilerBuilderAtomID[];\n    readonly values: NativeCompilerBuilderVariableID[];\n  }\n\n  export interface SetPropertyValue extends BaseWithExceptionTarget {\n    readonly kind: Kind.SetPropertyValue;\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly property: NativeCompilerBuilderVariableID;\n    readonly value: NativeCompilerBuilderVariableID;\n  }\n\n  export interface SetPropertyIndex extends BaseWithExceptionTarget {\n    readonly kind: Kind.SetPropertyIndex;\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly index: number;\n    readonly value: NativeCompilerBuilderVariableID;\n  }\n\n  export interface CopyPropertiesFrom extends BaseWithExceptionTarget {\n    readonly kind: Kind.CopyPropertiesFrom;\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly value: NativeCompilerBuilderVariableID;\n    readonly propertiesToIgnore: NativeCompilerBuilderAtomID[] | undefined;\n    readonly copiedPropertiesCount: NativeCompilerBuilderVariableID;\n  }\n\n  export interface Throw extends Base {\n    readonly kind: Kind.Throw;\n    readonly value: NativeCompilerBuilderVariableID;\n    readonly target: NativeCompilerBuilderJumpTargetID;\n  }\n\n  export interface Retain extends Base {\n    readonly kind: Kind.Retain;\n    readonly value: NativeCompilerBuilderVariableID;\n  }\n\n  export interface Free extends Base {\n    readonly kind: Kind.Free;\n    readonly value: NativeCompilerBuilderVariableID;\n  }\n\n  export interface FreeV extends Base {\n    readonly kind: Kind.FreeV;\n    readonly values: NativeCompilerBuilderVariableID[];\n  }\n\n  /**\n   * Creates a new variable ref which can hold variables that can be mutated\n   * arbitrarily within closures.\n   */\n  export interface NewVariableRef extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.NewVariableRef;\n    readonly name: string | undefined;\n    readonly constValue?: ConstValue;\n  }\n\n  /**\n   * Loads the content of a variable ref.\n   */\n  export interface LoadVariableRef extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.LoadVariableRef;\n    readonly target: NativeCompilerBuilderVariableID;\n  }\n\n  /**\n   * Sets the content of a variable ref.\n   */\n  export interface SetVariableRef extends Base {\n    readonly kind: Kind.SetVariableRef;\n    readonly target: NativeCompilerBuilderVariableID;\n    readonly value: NativeCompilerBuilderVariableID;\n  }\n\n  export interface GetProperty extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.GetProperty;\n\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly property: NativeCompilerBuilderAtomID;\n    readonly thisObject: NativeCompilerBuilderVariableID;\n    readonly propCacheSlot: number;\n  }\n\n  export interface GetPropertyFree extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.GetPropertyFree;\n\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly property: NativeCompilerBuilderAtomID;\n    readonly thisObject: NativeCompilerBuilderVariableID;\n    readonly propCacheSlot: number;\n  }\n\n  export interface GetPropertyValue extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.GetPropertyValue;\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly property: NativeCompilerBuilderVariableID;\n    readonly thisObject: NativeCompilerBuilderVariableID;\n  }\n\n  export interface DeleteProperty extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.DeleteProperty;\n\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly property: NativeCompilerBuilderAtomID;\n  }\n\n  export interface DeletePropertyValue extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.DeletePropertyValue;\n    readonly object: NativeCompilerBuilderVariableID;\n    readonly property: NativeCompilerBuilderVariableID;\n  }\n\n  export interface GetFunctionArg extends BaseWithReturn {\n    readonly kind: Kind.GetFunctionArg;\n    readonly index: number;\n  }\n\n  export interface GetFunctionArgumentsObject extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.GetFunctionArgumentsObject;\n    readonly startIndex: number;\n  }\n\n  export interface GetSuper extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.GetSuper;\n  }\n\n  export interface GetSuperConstructor extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.GetSuperConstructor;\n  }\n\n  export interface GetClosureArg extends BaseWithReturn {\n    readonly kind: Kind.GetClosureArg;\n    readonly index: number;\n    readonly constValue?: ConstValue;\n  }\n\n  export interface GetModuleConst extends BaseWithReturn {\n    readonly kind: Kind.GetModuleConst;\n    readonly index: number;\n  }\n\n  export interface GetException extends BaseWithReturn {\n    readonly kind: Kind.GetException;\n  }\n\n  export interface CheckException extends BaseWithExceptionTarget {\n    readonly kind: Kind.CheckException;\n  }\n\n  export interface Keyword extends BaseWithReturn {\n    readonly kind: Kind.Keyword;\n    readonly keyword: KeywordKind;\n  }\n\n  export interface Exception extends BaseWithReturn {\n    readonly kind: Kind.Exception;\n  }\n\n  export interface LiteralInteger extends LiteralBase {\n    readonly kind: Kind.LiteralInteger;\n  }\n\n  export interface LiteralLong extends LiteralBase {\n    readonly kind: Kind.LiteralLong;\n  }\n\n  export interface LiteralDouble extends LiteralBase {\n    readonly kind: Kind.LiteralDouble;\n  }\n\n  export interface LiteralString extends LiteralBase, BaseWithExceptionTarget {\n    readonly kind: Kind.LiteralString;\n  }\n\n  export interface LiteralBool extends BaseWithReturn {\n    readonly kind: Kind.LiteralBool;\n    readonly value: boolean;\n  }\n\n  export interface UnaryOp extends UnaryOPBase {\n    readonly kind: Kind.UnaryOp;\n    readonly operator: UnaryOperator;\n  }\n\n  export interface BinaryOp extends BinaryOpBase {\n    readonly kind: Kind.BinaryOp;\n    readonly operator: BinaryOperator;\n  }\n\n  export interface Assignment extends Base {\n    readonly kind: Kind.Assignment;\n    readonly left: NativeCompilerBuilderVariableID;\n    readonly right: NativeCompilerBuilderVariableID;\n  }\n\n  export interface IntrinsicCall extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.IntrinsicCall;\n    readonly func: string;\n    readonly args: Array<NativeCompilerBuilderVariableID>;\n  }\n\n  export interface FunctionInvocation extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.FunctionInvocation;\n    readonly func: NativeCompilerBuilderVariableID;\n    readonly args: Array<NativeCompilerBuilderVariableID>;\n    readonly obj: NativeCompilerBuilderVariableID;\n    readonly argsType: FunctionArgumentsType;\n  }\n\n  export interface ConstructorInvocation extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.ConstructorInvocation;\n    readonly func: NativeCompilerBuilderVariableID;\n    readonly new_target: NativeCompilerBuilderVariableID;\n    readonly args: Array<NativeCompilerBuilderVariableID>;\n    readonly argsType: FunctionArgumentsType;\n  }\n\n  export interface NewObject extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.NewObject;\n  }\n\n  export interface NewArray extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.NewArray;\n  }\n\n  export interface NewFunctionValueBase extends BaseWithReturnAndExceptionTarget {\n    readonly functionName: string;\n    readonly argc: number;\n    readonly closureArgs: NativeCompilerBuilderVariableID[];\n  }\n\n  export interface NewArrowFunctionValue extends NewFunctionValueBase {\n    readonly kind: Kind.NewArrowFunctionValue;\n    readonly stackOnHeap: boolean;\n  }\n\n  export interface NewFunctionValue extends NewFunctionValueBase {\n    readonly kind: Kind.NewFunctionValue;\n    readonly name: NativeCompilerBuilderAtomID;\n  }\n\n  export interface NewClassValue extends NewFunctionValueBase {\n    readonly kind: Kind.NewClassValue;\n    readonly name: NativeCompilerBuilderAtomID;\n    readonly parentClass: NativeCompilerBuilderVariableID;\n  }\n\n  export interface SetClassElement extends BaseWithExceptionTarget {\n    readonly kind: Kind.SetClassElement;\n    readonly type: ClassElementType;\n    readonly cls: NativeCompilerBuilderVariableID;\n    readonly name: NativeCompilerBuilderAtomID;\n    readonly value: NativeCompilerBuilderVariableID;\n    readonly static: boolean;\n  }\n\n  export interface SetClassElementValue extends BaseWithExceptionTarget {\n    readonly kind: Kind.SetClassElementValue;\n    readonly type: ClassElementType;\n    readonly cls: NativeCompilerBuilderVariableID;\n    readonly name: NativeCompilerBuilderVariableID;\n    readonly value: NativeCompilerBuilderVariableID;\n    readonly static: boolean;\n  }\n\n  export interface Iterator extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.Iterator;\n    readonly arg: NativeCompilerBuilderVariableID;\n  }\n\n  export interface IteratorNext extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.IteratorNext;\n    readonly iterator: NativeCompilerBuilderVariableID;\n  }\n\n  export interface KeysIterator extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.KeysIterator;\n    readonly arg: NativeCompilerBuilderVariableID;\n  }\n\n  export interface KeysIteratorNext extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.KeysIteratorNext;\n    readonly iterator: NativeCompilerBuilderVariableID;\n  }\n\n  export interface Generator extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.Generator;\n    readonly arg: NativeCompilerBuilderVariableID;\n  }\n\n  export interface Resume extends BaseWithReturnAndExceptionTarget {\n    readonly kind: Kind.Resume;\n  }\n\n  export interface Reentry extends Base {\n    readonly kind: Kind.Reentry;\n    readonly resumePoints: NativeCompilerBuilderJumpTargetID[];\n  }\n\n  export interface SetResumePoint extends Base {\n    readonly kind: Kind.SetResumePoint;\n    readonly resumePoint: NativeCompilerBuilderJumpTargetID;\n  }\n\n  export interface BindJumpTarget extends Base {\n    readonly kind: Kind.BindJumpTarget;\n    readonly target: NativeCompilerBuilderJumpTargetID;\n  }\n\n  export interface Jump extends Base {\n    readonly kind: Kind.Jump;\n    readonly target: NativeCompilerBuilderJumpTargetID;\n  }\n\n  export interface Branch extends Base {\n    readonly kind: Kind.Branch;\n    readonly conditionVariable: NativeCompilerBuilderVariableID;\n    readonly type: NativeCompilerBuilderBranchType;\n    readonly trueTarget: NativeCompilerBuilderJumpTargetID;\n    readonly falseTarget: NativeCompilerBuilderJumpTargetID | undefined;\n  }\n\n  export interface StartFunction extends Base {\n    readonly kind: Kind.StartFunction;\n    readonly name: string;\n    readonly type: FunctionType;\n    readonly exceptionJumpTarget: NativeCompilerBuilderJumpTargetID;\n    readonly returnJumpTarget: NativeCompilerBuilderJumpTargetID;\n    readonly returnVariable: NativeCompilerBuilderVariableID;\n    readonly localVars: NativeCompilerBuilderVariableID[];\n  }\n\n  export interface EndFunction extends Base {\n    readonly kind: Kind.EndFunction;\n    readonly returnVariable: NativeCompilerBuilderVariableID;\n  }\n\n  export interface Comments extends Base {\n    readonly kind: Kind.Comments;\n    readonly text: string;\n  }\n\n  export interface ProgramCounterInfo extends Base {\n    readonly kind: Kind.ProgramCounterInfo;\n    readonly lineNumber: number;\n    readonly columnNumber: number;\n  }\n\n  export interface BoilerplateEpilogue extends Base {\n    readonly kind: Kind.BoilerplateEpilogue;\n    readonly moduleName: string;\n    readonly modulePath: string;\n    readonly moduleInitFunctionName: string;\n    readonly atoms: readonly NativeCompilerBuilderAtomID[];\n    readonly stringConstants: readonly string[];\n    readonly propCacheSlots: number;\n  }\n\n  export interface BoilerplatePrologue extends Base {\n    readonly kind: Kind.BoilerplatePrologue;\n    readonly atoms: NativeCompilerBuilderAtomID[];\n  }\n\n  export interface BuilderStub extends Base {\n    readonly kind: Kind.BuilderStub;\n    readonly index: number;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/VariableContext.ts",
    "content": "import { VariableIdMap } from '../utils/VariableIdMap';\nimport {\n  INativeCompilerBlockBuilderFunctionContext,\n  IVariableDelegate,\n  NativeCompilerBuilderVariableID,\n  NativeCompilerBuilderVariableRef,\n} from './INativeCompilerBuilder';\n\nexport type LazyNativeCompilerBuilderVariableRef = () => NativeCompilerBuilderVariableRef;\n\nexport type VariableResolveResult = NativeCompilerBuilderVariableRef | IVariableDelegate;\n\nexport function variableResultIsVariableRef(result: VariableResolveResult): result is NativeCompilerBuilderVariableRef {\n  return result instanceof NativeCompilerBuilderVariableRef;\n}\n\nexport function variableResultIsVariableDelegate(result: VariableResolveResult): result is IVariableDelegate {\n  return (result as IVariableDelegate).onGetValue !== undefined;\n}\n\nexport const enum VariableResolvingMode {\n  /**\n   * Look up all the way to the root VariableContext to resolve the variable,\n   * potentially emitting a closure argument along the way.\n   */\n  full,\n\n  /**\n   * Look up up to the current function scope, without emitting closure or\n   * triggering lazy variable creation.\n   */\n  shallow,\n}\n\nexport class VariableContext {\n  private scopeVariable = new Map<\n    string,\n    NativeCompilerBuilderVariableRef | LazyNativeCompilerBuilderVariableRef | IVariableDelegate\n  >();\n  private variableRefByAliasVariableId = new VariableIdMap<NativeCompilerBuilderVariableRef>();\n\n  constructor(\n    readonly functionContext: INativeCompilerBlockBuilderFunctionContext,\n    readonly parent: VariableContext | undefined,\n  ) {}\n\n  /**\n   * Creates a new VariableContext that shares the scope of this variable context,\n   * but will emit variables that are scoped to the returned variable context.\n   */\n  scoped(): VariableContext {\n    return new VariableContext(this.functionContext, this);\n  }\n\n  /**\n   * Creates a new VariableContext on a new function context, that can resolve variables as closures\n   * from this variable context.\n   */\n  detached(functionContext: INativeCompilerBlockBuilderFunctionContext): VariableContext {\n    return new VariableContext(functionContext, this);\n  }\n\n  registerVariableRefInScope(variableRef: NativeCompilerBuilderVariableRef): void {\n    const existingVariableRef = this.scopeVariable.get(variableRef.name);\n    if (existingVariableRef && existingVariableRef instanceof NativeCompilerBuilderVariableRef) {\n      throw new Error(`Variable ${variableRef.name} identifier already exists in scope`);\n    }\n    this.scopeVariable.set(variableRef.name, variableRef);\n  }\n\n  registerVariableDelegate(name: string, delegate: IVariableDelegate): void {\n    if (this.scopeVariable.has(name)) {\n      throw new Error(`Variable ${name} identifier already exists in scope`);\n    }\n    this.scopeVariable.set(name, delegate);\n  }\n\n  registerLazyVariableRef(name: string, lazy: LazyNativeCompilerBuilderVariableRef): void {\n    if (this.scopeVariable.has(name)) {\n      throw new Error(`Variable ${name} identifier already exists in scope`);\n    }\n    this.scopeVariable.set(name, lazy);\n  }\n\n  resolveVariable(variableName: string, mode: VariableResolvingMode): VariableResolveResult | undefined {\n    let variable = this.scopeVariable.get(variableName);\n    if (variable !== undefined) {\n      if (variable instanceof NativeCompilerBuilderVariableRef || typeof variable === 'object') {\n        return variable;\n      } else {\n        if (mode === VariableResolvingMode.shallow) {\n          return undefined;\n        }\n\n        const resolvedVariable = variable();\n        if (this.scopeVariable.get(variableName) !== resolvedVariable) {\n          throw new Error(`Variable ${variableName} should have been registered after being instantiated`);\n        }\n        return resolvedVariable;\n      }\n    }\n\n    const parent = this.parent;\n    if (!parent) {\n      return undefined;\n    }\n\n    if (parent.functionContext === this.functionContext) {\n      return parent.resolveVariable(variableName, mode);\n    } else {\n      if (mode !== VariableResolvingMode.full) {\n        return undefined;\n      }\n\n      const parentResult = parent.resolveVariable(variableName, mode);\n\n      // Our parent is from a different function context. We turn the return value as a closure here\n      // if the returned value is not a variable delegate\n\n      if (!parentResult) {\n        // Was not found, this should be treated as a global variable\n        return undefined;\n      }\n\n      if (variableResultIsVariableRef(parentResult)) {\n        const resolvedVariable = this.functionContext.requestClosureArgument(variableName, parentResult);\n        if (!this.scopeVariable.has(variableName)) {\n          this.scopeVariable.set(variableName, resolvedVariable);\n        }\n\n        return resolvedVariable;\n      }\n\n      // If we are here, the returned result is a variable delegate\n\n      return parentResult;\n    }\n  }\n\n  registerVariableRefAlias(\n    variableRef: NativeCompilerBuilderVariableRef,\n    aliasVariableId: NativeCompilerBuilderVariableID,\n  ): void {\n    this.variableRefByAliasVariableId.set(aliasVariableId, variableRef);\n  }\n\n  getVariableRefForAlias(\n    aliasVariableId: NativeCompilerBuilderVariableID,\n  ): NativeCompilerBuilderVariableRef | undefined {\n    return this.variableRefByAliasVariableId.get(aliasVariableId);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/NativeCompilerBlockBuilderContext.ts",
    "content": "import {\n  INativeCompilerBlockBuilder,\n  INativeCompilerBlockBuilderFunctionContext,\n  NativeCompilerBuilderJumpTargetID,\n  NativeCompilerBuilderVariableID,\n  NativeCompilerBuilderVariableRef,\n  NativeCompilerBuilderVariableType,\n} from '../INativeCompilerBuilder';\n\nexport interface INativeCompilerBlockBuilderFunctionContextListener {\n  onClosureVariableRequested(\n    name: string,\n    index: number,\n    source: NativeCompilerBuilderVariableRef,\n  ): NativeCompilerBuilderVariableRef;\n}\n\nexport class NativeCompilerBlockBuilderFunctionContext implements INativeCompilerBlockBuilderFunctionContext {\n  undefinedVariable: NativeCompilerBuilderVariableID | undefined;\n  nullVariable: NativeCompilerBuilderVariableID | undefined;\n  requestedClosureArguments: NativeCompilerBuilderVariableRef[] = [];\n\n  private variableIDTracker = 0;\n  private variables: NativeCompilerBuilderVariableID[] = [];\n  private jumpTargetCounter = 0;\n  private _returnJumpTarget: NativeCompilerBuilderJumpTargetID | undefined;\n  private _returnVariable: NativeCompilerBuilderVariableID | undefined;\n  private _yieldJumpTarget: NativeCompilerBuilderJumpTargetID | undefined;\n\n  constructor(\n    readonly functionId: number,\n    private readonly name: string,\n    private readonly listener: INativeCompilerBlockBuilderFunctionContextListener,\n    readonly isGenerator: boolean,\n  ) {}\n\n  get returnVariable(): NativeCompilerBuilderVariableID {\n    if (this._returnVariable === undefined) {\n      throw Error('Return Variable was not defined');\n    } else {\n      return this._returnVariable;\n    }\n  }\n\n  set returnVariable(target: NativeCompilerBuilderVariableID) {\n    if (this._returnVariable === undefined) {\n      this._returnVariable = target;\n    } else {\n      throw Error('Return Variable was defined');\n    }\n  }\n\n  get returnJumpTarget(): NativeCompilerBuilderJumpTargetID {\n    if (this._returnJumpTarget === undefined) {\n      throw Error('Return Jump Target was not defined');\n    } else {\n      return this._returnJumpTarget;\n    }\n  }\n\n  set returnJumpTarget(target: NativeCompilerBuilderJumpTargetID) {\n    if (this._returnJumpTarget === undefined) {\n      this._returnJumpTarget = target;\n    } else {\n      throw Error('Return Jump Target was defined');\n    }\n  }\n\n  get yieldJumpTarget(): NativeCompilerBuilderJumpTargetID {\n    if (this._yieldJumpTarget === undefined) {\n      throw Error(`Yield Jump Target was not defined in function ${this.name}`);\n    } else {\n      return this._yieldJumpTarget;\n    }\n  }\n\n  set yieldJumpTarget(target: NativeCompilerBuilderJumpTargetID) {\n    if (this._yieldJumpTarget === undefined) {\n      this._yieldJumpTarget = target;\n    } else {\n      throw Error('Yield Jump Target was defined');\n    }\n  }\n  get variableCount() {\n    return this.variableIDTracker;\n  }\n\n  requestClosureArgument(\n    variableName: string,\n    source: NativeCompilerBuilderVariableRef,\n  ): NativeCompilerBuilderVariableRef {\n    const index = this.requestedClosureArguments.length;\n    const variableRef = this.listener.onClosureVariableRequested(variableName, index, source);\n    this.requestedClosureArguments.push(variableRef);\n\n    return variableRef;\n  }\n\n  registerVariable(\n    type: NativeCompilerBuilderVariableType,\n    assignable: boolean = true,\n  ): NativeCompilerBuilderVariableID {\n    const variable = new NativeCompilerBuilderVariableID(this.functionId, ++this.variableIDTracker, type, assignable);\n    this.variables.push(variable);\n\n    return variable;\n  }\n\n  registerJumpTarget(tag: string): NativeCompilerBuilderJumpTargetID {\n    return new NativeCompilerBuilderJumpTargetID(this.jumpTargetCounter++, tag);\n  }\n}\n\nexport class NativeCompilerBlockBuilderScopeContext {\n  private exitTarget?: NativeCompilerBuilderJumpTargetID;\n  private continueTarget?: NativeCompilerBuilderJumpTargetID;\n  private exceptionTarget?: NativeCompilerBuilderJumpTargetID;\n  private exportsVariableRef?: NativeCompilerBuilderVariableRef;\n\n  constructor(private readonly parentcontext: NativeCompilerBlockBuilderScopeContext | undefined) {}\n\n  registerExitTargetInScope(exitTarget: NativeCompilerBuilderJumpTargetID) {\n    this.exitTarget = exitTarget;\n  }\n\n  resolveExitTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined {\n    if (this.exitTarget !== undefined) {\n      return this.exitTarget;\n    }\n    return this.parentcontext?.resolveExitTargetInScope();\n  }\n\n  registerContinueTargetInScope(continueTarget: NativeCompilerBuilderJumpTargetID) {\n    if (this.continueTarget) {\n      throw new Error('Already has a continue jump target in current scope');\n    }\n    this.continueTarget = continueTarget;\n  }\n\n  resolveContinueTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined {\n    if (this.continueTarget !== undefined) {\n      return this.continueTarget;\n    }\n    return this.parentcontext?.resolveContinueTargetInScope();\n  }\n\n  registerExceptionTargetInScope(exitTarget: NativeCompilerBuilderJumpTargetID) {\n    this.exceptionTarget = exitTarget;\n  }\n\n  resolveExceptionTargetInScope(): NativeCompilerBuilderJumpTargetID | undefined {\n    if (this.exceptionTarget !== undefined) {\n      return this.exceptionTarget;\n    }\n\n    return this.parentcontext?.resolveExceptionTargetInScope();\n  }\n\n  resolveExportsVariableRef(): NativeCompilerBuilderVariableRef | undefined {\n    if (this.exportsVariableRef) {\n      return this.exportsVariableRef;\n    }\n\n    return this.parentcontext?.resolveExportsVariableRef();\n  }\n\n  registerExportsVariableRef(exportsVariableRef: NativeCompilerBuilderVariableRef): void {\n    if (this.exportsVariableRef) {\n      throw new Error(`Exports variable already exists in scope`);\n    }\n\n    this.exportsVariableRef = exportsVariableRef;\n  }\n\n  createSubScopeContext(): NativeCompilerBlockBuilderScopeContext {\n    return new NativeCompilerBlockBuilderScopeContext(this);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerAutoRelease.ts",
    "content": "import { NativeCompilerIR } from '../../NativeCompilerBuilderIR';\n\n/**\n * Replace the sequence\n *   free @X\n *   @x = get_prop(...)\n * with\n *   get_prop_free(@X, ...)\n */\nexport namespace NativeCompilerTransformerAutoRelease {\n  export function transform(irs: NativeCompilerIR.Base[]): NativeCompilerIR.Base[] {\n    const output: NativeCompilerIR.Base[] = [];\n\n    for (const ir of irs) {\n      switch (ir.kind) {\n        case NativeCompilerIR.Kind.GetProperty: {\n          const typedIR = ir as NativeCompilerIR.GetProperty;\n          const lastIR = output.pop();\n          if (lastIR?.kind === NativeCompilerIR.Kind.Free) {\n            const lastFree = lastIR as NativeCompilerIR.Free;\n            if (lastFree.value.variable == typedIR.variable.variable) {\n              // last IR is freeing the target of this IR\n              // replace this IR with GetPropertyFree\n              const newIR: NativeCompilerIR.GetPropertyFree = {\n                ...typedIR,\n                kind: NativeCompilerIR.Kind.GetPropertyFree,\n              };\n              output.push(newIR);\n              continue; // skip the old IR\n            }\n          }\n          if (lastIR) {\n            output.push(lastIR);\n          }\n          output.push(ir);\n          break;\n        }\n        default:\n          output.push(ir);\n          break;\n      }\n    }\n\n    return output;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerConstantFolding.ts",
    "content": "import { NativeCompilerIR } from '../../NativeCompilerBuilderIR';\nimport { ConstantType, ConstValue, NativeCompilerBuilderVariableID } from '../../INativeCompilerBuilder';\nimport { visitVariables } from './utils/IRVisitors';\nimport { NativeCompilerModuleBuilder } from '../../NativeCompilerBuilder';\n\nexport namespace NativeCompilerTransformerConstantFolding {\n  interface ConstantDef {\n    type: ConstantType;\n    value: string;\n    index: number; // where does this constant start to come into effect\n  }\n\n  const numericalTypes = [ConstantType.Integer, ConstantType.Long, ConstantType.Double];\n\n  function buildLiteralInteger(\n    variable: NativeCompilerBuilderVariableID,\n    value: string,\n  ): NativeCompilerIR.LiteralInteger {\n    return {\n      kind: NativeCompilerIR.Kind.LiteralInteger,\n      variable: variable,\n      value: value,\n    };\n  }\n\n  function buildLiteralLong(variable: NativeCompilerBuilderVariableID, value: string): NativeCompilerIR.LiteralLong {\n    return {\n      kind: NativeCompilerIR.Kind.LiteralLong,\n      variable: variable,\n      value: value,\n    };\n  }\n  function buildLiteralDouble(\n    variable: NativeCompilerBuilderVariableID,\n    value: string,\n  ): NativeCompilerIR.LiteralDouble {\n    return {\n      kind: NativeCompilerIR.Kind.LiteralDouble,\n      variable: variable,\n      value: value,\n    };\n  }\n  function buildLiteralBool(variable: NativeCompilerBuilderVariableID, value: boolean): NativeCompilerIR.LiteralBool {\n    return {\n      kind: NativeCompilerIR.Kind.LiteralBool,\n      variable: variable,\n      value: value,\n    };\n  }\n\n  type UnaryOp = (variable: NativeCompilerBuilderVariableID, c: ConstantDef) => NativeCompilerIR.Base | undefined;\n  type BinaryOp = (\n    variable: NativeCompilerBuilderVariableID,\n    moduleBuilder: NativeCompilerModuleBuilder,\n    left: ConstantDef,\n    right: ConstantDef,\n  ) => NativeCompilerIR.Base | undefined;\n\n  function doNeg(variable: NativeCompilerBuilderVariableID, c: ConstantDef): NativeCompilerIR.Base | undefined {\n    switch (c.type) {\n      case ConstantType.Double:\n        return buildLiteralDouble(variable, (-Number(c.value)).toString());\n      case ConstantType.Integer:\n        return buildLiteralInteger(variable, (-Number(c.value)).toString());\n      case ConstantType.Long:\n        return buildLiteralLong(variable, (-Number(c.value)).toString());\n      default:\n        return undefined;\n    }\n  }\n  function doPlus(variable: NativeCompilerBuilderVariableID, c: ConstantDef): NativeCompilerIR.Base | undefined {\n    switch (c.type) {\n      case ConstantType.Double:\n        return buildLiteralDouble(variable, c.value);\n      case ConstantType.Integer:\n        return buildLiteralInteger(variable, c.value);\n      case ConstantType.Long:\n        return buildLiteralLong(variable, c.value);\n      default:\n        return undefined;\n    }\n  }\n  function doBitwiseNot(variable: NativeCompilerBuilderVariableID, c: ConstantDef): NativeCompilerIR.Base | undefined {\n    switch (c.type) {\n      case ConstantType.Integer:\n        return buildLiteralInteger(variable, String(~Number(c.value)));\n      case ConstantType.Long:\n        return buildLiteralLong(variable, String(~Number(c.value)));\n      default:\n        return undefined;\n    }\n  }\n  function doLogicalNot(variable: NativeCompilerBuilderVariableID, c: ConstantDef): NativeCompilerIR.Base | undefined {\n    switch (c.type) {\n      case ConstantType.Bool:\n        return buildLiteralBool(variable, !(c.value == 'true'));\n      default:\n        return undefined;\n    }\n  }\n\n  const maxInt32 = 0x7fffffff;\n  const minInt32 = -2147483648;\n\n  function isSafeInt32(x: number): boolean {\n    return x <= maxInt32 && x >= minInt32 && x % 1 === 0;\n  }\n\n  function doBinary(\n    variable: NativeCompilerBuilderVariableID,\n    operator: (left: number, right: number) => number,\n    left: ConstantDef,\n    right: ConstantDef,\n  ) {\n    if (numericalTypes.includes(left.type) && numericalTypes.includes(right.type)) {\n      const [smallerType, largerType] = left.type <= right.type ? [left.type, right.type] : [right.type, left.type];\n      const res = operator(Number(left.value), Number(right.value));\n      // int + int\n      if (smallerType === ConstantType.Integer && largerType === ConstantType.Integer) {\n        if (isSafeInt32(res)) {\n          return buildLiteralInteger(variable, String(res));\n        } else {\n          return buildLiteralDouble(variable, String(res));\n        }\n      }\n      // long + long\n      if (smallerType === ConstantType.Long && largerType === ConstantType.Long) {\n        return buildLiteralLong(variable, String(res));\n      }\n      // double + double\n      if (smallerType === ConstantType.Double && largerType === ConstantType.Double) {\n        return buildLiteralDouble(variable, String(res));\n      }\n      // int + long\n      if (smallerType === ConstantType.Integer && largerType === ConstantType.Long) {\n        return buildLiteralLong(variable, String(res));\n      }\n      // int + double\n      if (smallerType === ConstantType.Integer && largerType === ConstantType.Double) {\n        return buildLiteralDouble(variable, String(res));\n      }\n      // long + double\n      if (smallerType === ConstantType.Long && largerType === ConstantType.Double) {\n        return buildLiteralDouble(variable, String(res));\n      }\n    }\n    return undefined;\n  }\n\n  function doBand(\n    variable: NativeCompilerBuilderVariableID,\n    moduleBuilder: NativeCompilerModuleBuilder,\n    left: ConstantDef,\n    right: ConstantDef,\n  ): NativeCompilerIR.Base | undefined {\n    return doBinary(variable, (x, y) => x & y, left, right);\n  }\n  function doBor(\n    variable: NativeCompilerBuilderVariableID,\n    moduleBuilder: NativeCompilerModuleBuilder,\n    left: ConstantDef,\n    right: ConstantDef,\n  ): NativeCompilerIR.Base | undefined {\n    return doBinary(variable, (x, y) => x | y, left, right);\n  }\n\n  function doAdd(\n    variable: NativeCompilerBuilderVariableID,\n    moduleBuilder: NativeCompilerModuleBuilder,\n    left: ConstantDef,\n    right: ConstantDef,\n  ): NativeCompilerIR.Base | undefined {\n    // str + str\n    if (left.type === ConstantType.String && right.type === ConstantType.String) {\n      const constantIndex = moduleBuilder.registerStringConstant(left.value + right.value);\n      const newIR: NativeCompilerIR.GetModuleConst = {\n        kind: NativeCompilerIR.Kind.GetModuleConst,\n        variable: variable,\n        index: constantIndex,\n      };\n      return newIR;\n    }\n    // Number types\n    return doBinary(variable, (x, y) => x + y, left, right);\n  }\n\n  function doMulti(\n    variable: NativeCompilerBuilderVariableID,\n    moduleBuilder: NativeCompilerModuleBuilder,\n    left: ConstantDef,\n    right: ConstantDef,\n  ): NativeCompilerIR.Base | undefined {\n    return doBinary(variable, (x, y) => x * y, left, right);\n  }\n\n  function doSub(\n    variable: NativeCompilerBuilderVariableID,\n    moduleBuilder: NativeCompilerModuleBuilder,\n    left: ConstantDef,\n    right: ConstantDef,\n  ): NativeCompilerIR.Base | undefined {\n    return doBinary(variable, (x, y) => x - y, left, right);\n  }\n\n  function doDiv(\n    variable: NativeCompilerBuilderVariableID,\n    moduleBuilder: NativeCompilerModuleBuilder,\n    left: ConstantDef,\n    right: ConstantDef,\n  ): NativeCompilerIR.Base | undefined {\n    return doBinary(variable, (x, y) => x / y, left, right);\n  }\n\n  interface TransformResult {\n    irs: NativeCompilerIR.Base[];\n    changes: number;\n  }\n\n  function addNewIR(output: TransformResult, newIR: NativeCompilerIR.Base) {\n    output.irs.push(newIR);\n    output.changes++;\n  }\n\n  export function transform(irs: NativeCompilerIR.Base[], moduleBuilder: NativeCompilerModuleBuilder): TransformResult {\n    const output: TransformResult = { irs: [], changes: 0 };\n    const constants = new Map<number, ConstantDef>();\n    const unused = new Set<number>();\n    const constVarRefs = new Map<number, ConstValue>();\n\n    // pass 1:\n    // * identify all constants. constants are created from literal and then never assigned.\n    // * mark all unused constants\n    // * find assignments of constants to vrefs and update the vref's const value\n    irs.forEach((ir, idx) => {\n      // if variable is touched, remove from unused candidate\n      visitVariables(ir, false, (v) => {\n        unused.delete(v.variable);\n        return v;\n      });\n      switch (ir.kind) {\n        // Create constant candidates when we see literals\n        case NativeCompilerIR.Kind.LiteralBool: {\n          const typedIR = ir as NativeCompilerIR.LiteralBool;\n          constants.set(typedIR.variable.variable, {\n            type: ConstantType.Bool,\n            value: typedIR.value ? 'true' : 'false',\n            index: idx,\n          });\n          unused.add(typedIR.variable.variable);\n          break;\n        }\n        case NativeCompilerIR.Kind.LiteralDouble: {\n          const typedIR = ir as NativeCompilerIR.LiteralDouble;\n          constants.set(typedIR.variable.variable, {\n            type: ConstantType.Double,\n            value: typedIR.value,\n            index: idx,\n          });\n          unused.add(typedIR.variable.variable);\n          break;\n        }\n        case NativeCompilerIR.Kind.LiteralInteger: {\n          const typedIR = ir as NativeCompilerIR.LiteralInteger;\n          constants.set(typedIR.variable.variable, {\n            type: ConstantType.Integer,\n            value: typedIR.value,\n            index: idx,\n          });\n          unused.add(typedIR.variable.variable);\n          break;\n        }\n        case NativeCompilerIR.Kind.LiteralLong: {\n          const typedIR = ir as NativeCompilerIR.LiteralLong;\n          constants.set(typedIR.variable.variable, {\n            type: ConstantType.Long,\n            value: typedIR.value,\n            index: idx,\n          });\n          unused.add(typedIR.variable.variable);\n          break;\n        }\n        case NativeCompilerIR.Kind.LiteralString: {\n          const typedIR = ir as NativeCompilerIR.LiteralString;\n          constants.set(typedIR.variable.variable, {\n            type: ConstantType.String,\n            value: typedIR.value,\n            index: idx,\n          });\n          unused.add(typedIR.variable.variable);\n          break;\n        }\n        case NativeCompilerIR.Kind.GetModuleConst: {\n          const typedIR = ir as NativeCompilerIR.GetModuleConst;\n          constants.set(typedIR.variable.variable, {\n            type: ConstantType.String,\n            value: moduleBuilder.stringConstants[typedIR.index],\n            index: idx,\n          });\n          unused.add(typedIR.variable.variable);\n          break;\n        }\n        // If a candidate is assigned, it's no longer a constant\n        case NativeCompilerIR.Kind.Assignment: {\n          const typedIR = ir as NativeCompilerIR.Assignment;\n          if (constants.has(typedIR.left.variable)) {\n            constants.delete(typedIR.left.variable);\n          }\n          break;\n        }\n        // find const vrefs defined in this function\n        case NativeCompilerIR.Kind.NewVariableRef: {\n          const typedIR = ir as NativeCompilerIR.NewVariableRef;\n          if (typedIR.constValue) {\n            constVarRefs.set(typedIR.variable.variable, typedIR.constValue);\n          }\n          break;\n        }\n        // find const vrefs captured from parent\n        case NativeCompilerIR.Kind.GetClosureArg: {\n          const typedIR = ir as NativeCompilerIR.GetClosureArg;\n          if (typedIR.constValue) {\n            constVarRefs.set(typedIR.variable.variable, typedIR.constValue);\n          }\n          break;\n        }\n        // update const vref's value\n        case NativeCompilerIR.Kind.SetVariableRef: {\n          const typedIR = ir as NativeCompilerIR.SetVariableRef;\n          const c = constants.get(typedIR.value.variable);\n          const vref = constVarRefs.get(typedIR.target.variable);\n          if (vref && vref.value === undefined && c) {\n            //console.log(`found assignment to const vref ${typedIR.target.variable} with ${c.value}`);\n            vref.value = c.value;\n            vref.ctype = c.type;\n          }\n          break;\n        }\n      }\n    });\n    // pass 2:\n    // * replace computations that entirely depends on constants with end result\n    // * delete unused literals\n    // * replace load vref with constant when available\n    irs.forEach((ir, idx) => {\n      switch (ir.kind) {\n        case NativeCompilerIR.Kind.LiteralBool:\n        case NativeCompilerIR.Kind.LiteralInteger:\n        case NativeCompilerIR.Kind.LiteralLong:\n        case NativeCompilerIR.Kind.LiteralDouble:\n        case NativeCompilerIR.Kind.LiteralString:\n        case NativeCompilerIR.Kind.GetModuleConst: {\n          const typedIR = ir as NativeCompilerIR.BaseWithReturn;\n          if (unused.has(typedIR.variable.variable)) {\n            // skip unused literal\n            return;\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.UnaryOp: {\n          const typedIR = ir as NativeCompilerIR.UnaryOp;\n          const c = constants.get(typedIR.operand.variable);\n          if (c && idx > c.index) {\n            const dispatcher = new Map<NativeCompilerIR.UnaryOperator, UnaryOp>([\n              [NativeCompilerIR.UnaryOperator.Neg, doNeg],\n              [NativeCompilerIR.UnaryOperator.Plus, doPlus],\n              [NativeCompilerIR.UnaryOperator.BitwiseNot, doBitwiseNot],\n              [NativeCompilerIR.UnaryOperator.LogicalNot, doLogicalNot],\n            ]);\n            const newIR = dispatcher.get(typedIR.operator)?.(typedIR.variable, c);\n            if (newIR) {\n              addNewIR(output, newIR);\n              return; // skip original IR\n            }\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.BinaryOp: {\n          const typedIR = ir as NativeCompilerIR.BinaryOp;\n          const c1 = constants.get(typedIR.left.variable);\n          const c2 = constants.get(typedIR.right.variable);\n          if (c1 && c2 && idx > c1.index && idx > c2.index) {\n            const dispatcher = new Map<NativeCompilerIR.BinaryOperator, BinaryOp>([\n              [NativeCompilerIR.BinaryOperator.Add, doAdd],\n              [NativeCompilerIR.BinaryOperator.Sub, doSub],\n              [NativeCompilerIR.BinaryOperator.Mult, doMulti],\n              [NativeCompilerIR.BinaryOperator.Div, doDiv],\n              [NativeCompilerIR.BinaryOperator.BitwiseAND, doBand],\n              [NativeCompilerIR.BinaryOperator.BitwiseOR, doBor],\n            ]);\n            const newIR = dispatcher.get(typedIR.operator)?.(typedIR.variable, moduleBuilder, c1, c2);\n            if (newIR) {\n              addNewIR(output, newIR);\n              return; // skip original IR\n            }\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.LoadVariableRef: {\n          const typedIR = ir as NativeCompilerIR.LoadVariableRef;\n          const vref = constVarRefs.get(typedIR.target.variable);\n          if (vref && vref.value && vref.ctype !== undefined) {\n            //console.log(`replace const vref with value ${vref.value}`);\n            switch (vref.ctype) {\n              case ConstantType.Bool: {\n                const newIR: NativeCompilerIR.LiteralBool = {\n                  kind: NativeCompilerIR.Kind.LiteralBool,\n                  value: vref.value == 'true',\n                  variable: typedIR.variable,\n                };\n                output.irs.push(newIR);\n                break;\n              }\n              case ConstantType.Integer: {\n                const newIR: NativeCompilerIR.LiteralInteger = {\n                  kind: NativeCompilerIR.Kind.LiteralInteger,\n                  value: vref.value,\n                  variable: typedIR.variable,\n                };\n                output.irs.push(newIR);\n                break;\n              }\n              case ConstantType.Long: {\n                const newIR: NativeCompilerIR.LiteralLong = {\n                  kind: NativeCompilerIR.Kind.LiteralLong,\n                  value: vref.value,\n                  variable: typedIR.variable,\n                };\n                output.irs.push(newIR);\n                break;\n              }\n              case ConstantType.Double: {\n                const newIR: NativeCompilerIR.LiteralDouble = {\n                  kind: NativeCompilerIR.Kind.LiteralDouble,\n                  value: vref.value,\n                  variable: typedIR.variable,\n                };\n                output.irs.push(newIR);\n                break;\n              }\n              case ConstantType.String: {\n                const constantIndex = moduleBuilder.registerStringConstant(vref.value);\n                const newIR: NativeCompilerIR.GetModuleConst = {\n                  kind: NativeCompilerIR.Kind.GetModuleConst,\n                  variable: typedIR.variable,\n                  index: constantIndex,\n                };\n                output.irs.push(newIR);\n                break;\n              }\n            }\n            output.changes++;\n            return; // skip original IR\n          }\n          break;\n        }\n      }\n      output.irs.push(ir);\n    });\n\n    // pass 3:\n    // Remove unused closure captures (replaced by constants)\n    const unusedVarRefs = new Map<number /*vref*/, number /*idx*/>();\n    output.irs.forEach((ir, idx) => {\n      switch (ir.kind) {\n        case NativeCompilerIR.Kind.GetClosureArg:\n          unusedVarRefs.set((ir as NativeCompilerIR.BaseWithReturn).variable.variable, idx);\n          break;\n        default:\n          visitVariables(ir, false, (v) => {\n            unusedVarRefs.delete(v.variable);\n            return v;\n          });\n          break;\n      }\n    });\n    unusedVarRefs.forEach((idx, _) => {\n      const comment: NativeCompilerIR.Comments = {\n        kind: NativeCompilerIR.Kind.Comments,\n        text: 'unused vref removed',\n      };\n      output.irs[idx] = comment;\n    });\n    return output;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerInsertRetainRelease.ts",
    "content": "import { NativeCompilerBuilderVariableID } from '../../INativeCompilerBuilder';\nimport { NativeCompilerIR } from '../../NativeCompilerBuilderIR';\nimport { JumpIndexer } from './utils/JumpIndexer';\nimport { isBaseWithReturn } from './utils/IRVisitors';\n\nfunction insertFreeIfNeeded(\n  value: NativeCompilerBuilderVariableID,\n  lastIR: NativeCompilerIR.Base | undefined,\n  outputIRs: NativeCompilerIR.Base[],\n): boolean {\n  if (!value.isRetainable()) {\n    return false;\n  }\n\n  if (lastIR && lastIR.kind === NativeCompilerIR.Kind.Free && (lastIR as NativeCompilerIR.Free).value === value) {\n    // We just had a free before, no need to insert a release it\n    return false;\n  }\n\n  const release: NativeCompilerIR.Free = {\n    kind: NativeCompilerIR.Kind.Free,\n    value: value,\n  };\n  outputIRs.push(release);\n  return true;\n}\n\nexport namespace NativeCompilerTransformerInsertRetainRelease {\n  export function transform(\n    startFunctionIR: NativeCompilerIR.StartFunction,\n    irs: NativeCompilerIR.Base[],\n    endFunctionIR: NativeCompilerIR.EndFunction,\n  ): NativeCompilerIR.Base[] {\n    // Keep an array of boolean where each index tells\n    // whether the IR is reentrant, meaning that it is\n    // possible that the IR gets evaluated multiple times\n    // at runtime. We use this to know whether we should insert an additional\n    // free before the instruction.\n    const reentrantIRIndexes: boolean[] = [];\n\n    // Keep track of assigned variables\n    // There is no need to emit a release before the first assignment\n    const assignedVariables: number[] = [];\n\n    for (let i = 0; i < irs.length; i++) {\n      reentrantIRIndexes.push(false);\n    }\n\n    const jumpIndexer = new JumpIndexer(irs);\n    jumpIndexer.forEachBackwardJump((jumpIRIndex, irIndex) => {\n      for (let i = jumpIRIndex; i < irIndex; i++) {\n        reentrantIRIndexes![i] = true;\n      }\n    });\n\n    let retval: NativeCompilerIR.Base[] = [];\n    const releaseIRs: NativeCompilerIR.Free[] = [];\n\n    let lastIR: NativeCompilerIR.Base | undefined;\n    let irIndex = 0;\n    for (const ir of irs) {\n      switch (ir.kind) {\n        case NativeCompilerIR.Kind.Slot:\n          {\n            let typedIR = ir as NativeCompilerIR.Slot;\n\n            if (typedIR.value.isRetainable()) {\n              const release: NativeCompilerIR.Free = {\n                kind: NativeCompilerIR.Kind.Free,\n                value: typedIR.value,\n              };\n              releaseIRs.push(release);\n            }\n\n            retval.push(ir);\n          }\n          break;\n        case NativeCompilerIR.Kind.Assignment:\n          {\n            let typedIR = ir as NativeCompilerIR.Assignment;\n\n            const assigned = typedIR.left.variable in assignedVariables;\n            if (!assigned) {\n              // record first assign\n              assignedVariables.push(typedIR.left.variable);\n            }\n            // skip release when safe\n            // 1. not assigned\n            // 2. not in reentrant region\n            if (assigned || reentrantIRIndexes[irIndex]) {\n              insertFreeIfNeeded(typedIR.left, lastIR, retval);\n            }\n\n            retval.push(typedIR);\n\n            if (typedIR.right.isRetainable()) {\n              const retain: NativeCompilerIR.Retain = {\n                kind: NativeCompilerIR.Kind.Retain,\n                value: typedIR.left,\n              };\n              retval.push(retain);\n            }\n          }\n          break;\n        default: {\n          if (isBaseWithReturn(ir) && !(ir.variable.variable in assignedVariables)) {\n            // record first assign\n            assignedVariables.push(ir.variable.variable);\n          }\n          if (reentrantIRIndexes[irIndex] && isBaseWithReturn(ir)) {\n            // Our IR is re-entrant, so we should insert a free before\n            // assigning the variable\n            insertFreeIfNeeded(ir.variable, lastIR, retval);\n          }\n\n          retval.push(ir);\n        }\n      }\n\n      irIndex++;\n      lastIR = ir;\n    }\n\n    // Release in the reverse order in which they were declared\n    releaseIRs.reverse();\n\n    return [...retval, ...releaseIRs];\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerMergeRelease.ts",
    "content": "import { NativeCompilerIR } from '../..//NativeCompilerBuilderIR';\nimport { NativeCompilerBuilderVariableID } from '../../INativeCompilerBuilder';\n\n/**\n * Transformer that replaces multiple successive release operations with one variadic release.\n */\nexport namespace NativeCompilerTransformerMergeRelease {\n  function emitFree(output: NativeCompilerIR.Base[], vars: NativeCompilerBuilderVariableID[]) {\n    if (vars.length > 1) {\n      // emit a FreeV to replace multipe Free\n      const freev: NativeCompilerIR.FreeV = {\n        kind: NativeCompilerIR.Kind.FreeV,\n        values: vars,\n      };\n      output.push(freev);\n    } else if (vars.length == 1) {\n      // emit the normal Free if there is a single item to free\n      const free: NativeCompilerIR.Free = {\n        kind: NativeCompilerIR.Kind.Free,\n        value: vars[0],\n      };\n      output.push(free);\n    }\n  }\n\n  export function transform(irs: NativeCompilerIR.Base[]): NativeCompilerIR.Base[] {\n    const output: NativeCompilerIR.Base[] = [];\n    var variablesToFree: NativeCompilerBuilderVariableID[] = [];\n    for (let ir of irs) {\n      if (ir.kind == NativeCompilerIR.Kind.Free) {\n        // store variables to free\n        // don't emit anything\n        const free = ir as NativeCompilerIR.Free;\n        variablesToFree.push(free.value);\n      } else {\n        // flush stored variables if present\n        emitFree(output, variablesToFree);\n        variablesToFree = [];\n        // copy input to output\n        output.push(ir);\n      }\n    }\n    // check again at the end\n    emitFree(output, variablesToFree);\n    variablesToFree = [];\n    return output;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerOptimizeAssignments.ts",
    "content": "import { NativeCompilerIR } from '../../NativeCompilerBuilderIR';\nimport { visitVariables, isBaseWithReturn } from './utils/IRVisitors';\n\n/**\n * This is a peephole optimization that looks for the pattern:\n *   X <= foo()\n *   Y <= X\n * and then X is never used again in the function body. This is often caused by\n * optimizing VariableRefs into Variables.\n *\n * In this case we can replace the sequence with just\n *  Y <= foo()\n * This often saves a retain/release pair too.\n */\nexport namespace NativeCompilerTransformerOptimizeAssignments {\n  export function transform(irs: NativeCompilerIR.Base[]): NativeCompilerIR.Base[] {\n    const functionBodyIR = [...irs];\n    let window: NativeCompilerIR.Base[] = [];\n    const candidates = new Map<number, number>();\n    functionBodyIR.forEach((ir, irIndex) => {\n      visitVariables(ir, false, (v) => {\n        if (candidates.has(v.variable)) {\n          candidates.delete(v.variable);\n        }\n        return v;\n      });\n      window.push(ir);\n      if (window.length > 2) {\n        window.shift();\n      }\n      if (window.length == 2) {\n        if (!isBaseWithReturn(window[0])) {\n          return;\n        }\n        const loadTarget = window[0].variable;\n        if (window[1].kind != NativeCompilerIR.Kind.Assignment) {\n          return;\n        }\n        const assignment = window[1] as NativeCompilerIR.Assignment;\n        if (loadTarget != assignment.right) {\n          return;\n        }\n        if (assignment.left.isRetainable()) {\n          // don't optimize assignment to retainables. after optimization assignments are turned into BaseWithReturn and\n          // the insert-retain-release pass does not insert a release for BaseWithReturn IRs unless in reentrant code.\n          return;\n        }\n        candidates.set(loadTarget.variable, irIndex - 1);\n      }\n    });\n    candidates.forEach((i, v) => {\n      const ir = functionBodyIR[i] as NativeCompilerIR.BaseWithReturn;\n      const newIR1 = visitVariables(ir, true, (irv) => {\n        if (irv.variable == v) {\n          const assignmentOnNextLine = functionBodyIR[i + 1] as NativeCompilerIR.Assignment;\n          return assignmentOnNextLine.left;\n        }\n        return irv;\n      });\n      const newIR2: NativeCompilerIR.Comments = {\n        kind: NativeCompilerIR.Kind.Comments,\n        text: 'eliminated assignment',\n      };\n      functionBodyIR[i] = newIR1;\n      functionBodyIR[i + 1] = newIR2;\n    });\n    return functionBodyIR;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerOptimizeLoads.ts",
    "content": "import { NativeCompilerBuilderVariableID } from '../../INativeCompilerBuilder';\nimport { NativeCompilerIR } from '../../NativeCompilerBuilderIR';\nimport { visitVariables } from './utils/IRVisitors';\n\nexport namespace NativeCompilerTransformerOptimizeLoads {\n  export function transform(irs: NativeCompilerIR.Base[]): NativeCompilerIR.Base[] {\n    // Keep track of effective aliases of VarRefs\n    // VarRef => Var\n    const varRefsToAliases = new Map<Number, NativeCompilerBuilderVariableID>();\n    // Var => VarRef\n    const aliasesToVarRefs = new Map<Number, NativeCompilerBuilderVariableID>();\n    // Remember const variables\n    // No need to invalidate these after calling functions\n    const constVarRefs = new Set<Number>();\n\n    const output: NativeCompilerIR.Base[] = [];\n\n    const variableIdsToReplace = new Map<Number, NativeCompilerBuilderVariableID>();\n\n    for (const ir of irs) {\n      const newIR = visitVariables(ir, true, (variable) => {\n        return variableIdsToReplace.get(variable.variable) ?? variable;\n      });\n      switch (newIR.kind) {\n        case NativeCompilerIR.Kind.GetClosureArg: {\n          const typedIR = newIR as NativeCompilerIR.GetClosureArg;\n          if (typedIR.constValue) {\n            constVarRefs.add(typedIR.variable.variable);\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.NewVariableRef: {\n          const typedIR = newIR as NativeCompilerIR.NewVariableRef;\n          if (typedIR.constValue) {\n            constVarRefs.add(typedIR.variable.variable);\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.LoadVariableRef: {\n          const typedIR = newIR as NativeCompilerIR.LoadVariableRef;\n          if (!varRefsToAliases.has(typedIR.target.variable)) {\n            // A new loadvref establishes an alias\n            varRefsToAliases.set(typedIR.target.variable, typedIR.variable);\n            aliasesToVarRefs.set(typedIR.variable.variable, typedIR.target);\n          } else {\n            // Alias exists, skip the loadref\n            // And record a replacement\n            variableIdsToReplace.set(typedIR.variable.variable, varRefsToAliases.get(typedIR.target.variable)!);\n            continue;\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.SetVariableRef: {\n          const typedIR = newIR as NativeCompilerIR.SetVariableRef;\n          if (varRefsToAliases.has(typedIR.target.variable)) {\n            if (constVarRefs.has(typedIR.target.variable)) {\n              throw new Error(`Assigning to const VarRef ${typedIR.target.variable}`);\n            }\n            // Assigning to an already aliased VarRef refreshes the alias\n            const existingAlias = varRefsToAliases.get(typedIR.target.variable)!;\n            // check if we are assigning alias back, skip if this is the case\n            if (existingAlias.variable !== typedIR.value.variable) {\n              aliasesToVarRefs.delete(existingAlias.variable);\n              varRefsToAliases.set(typedIR.target.variable, typedIR.value);\n              aliasesToVarRefs.set(typedIR.value.variable, typedIR.target);\n            } else {\n              continue;\n            }\n          } else {\n            // establish new alias if assigning to unaliased varref\n            varRefsToAliases.set(typedIR.target.variable, typedIR.value);\n            aliasesToVarRefs.set(typedIR.value.variable, typedIR.target);\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.Assignment: {\n          // Assigning to an alias invalidates it\n          const typedIR = newIR as NativeCompilerIR.Assignment;\n          if (aliasesToVarRefs.has(typedIR.left.variable)) {\n            const targetVarRef = aliasesToVarRefs.get(typedIR.left.variable)!;\n            varRefsToAliases.delete(targetVarRef.variable);\n            aliasesToVarRefs.delete(typedIR.left.variable);\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.BindJumpTarget: {\n          // hitting a jumptarget invalidates all aliases\n          varRefsToAliases.clear();\n          aliasesToVarRefs.clear();\n          break;\n        }\n        case NativeCompilerIR.Kind.GetProperty:\n        case NativeCompilerIR.Kind.GetPropertyValue:\n        case NativeCompilerIR.Kind.ConstructorInvocation:\n        case NativeCompilerIR.Kind.FunctionInvocation: {\n          // Calling a function invalidates all non-const aliases\n          const varRefsToInvalidate = [...varRefsToAliases.keys()].filter((x) => !constVarRefs.has(x));\n          for (const v of varRefsToInvalidate) {\n            const alias = varRefsToAliases.get(v)!.variable;\n            aliasesToVarRefs.delete(alias);\n            varRefsToAliases.delete(v);\n          }\n          break;\n        }\n        default:\n          break;\n      }\n      output.push(newIR);\n    }\n    return output;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerOptimizeVarRefs.ts",
    "content": "import { VariableIdMap } from '../../../utils/VariableIdMap';\nimport { NativeCompilerBuilderVariableID, NativeCompilerBuilderVariableType } from '../../INativeCompilerBuilder';\nimport { NativeCompilerIR } from '../../NativeCompilerBuilderIR';\nimport { visitVariables } from './utils/IRVisitors';\n\n/**\n * Transformer that eliminates variable references for variables that end up not being\n * captured in closures.\n */\nexport namespace NativeCompilerTransformerOptimizeVarRefs {\n  export function transform(irs: NativeCompilerIR.Base[]): NativeCompilerIR.Base[] {\n    // map of variable ref id to variable id replacement.\n    const variableRefsToEliminate = new VariableIdMap<NativeCompilerBuilderVariableID>();\n    // map of getfnarg result to var ref. Used to eliminate unnecessary assigns for function parameters\n    const fnArgToVRef = new VariableIdMap<NativeCompilerBuilderVariableID | undefined>();\n\n    // getfnarg 0 @3\n    // newvref 'require' @4\n    // setvref @3 @4\n    // getfnarg 1 @5\n    // newvref 'module' @6\n    // setvref @5 @6\n\n    // Step 1: We go over all the variable refs and see which ones are not used in closures\n    for (const ir of irs) {\n      switch (ir.kind) {\n        case NativeCompilerIR.Kind.NewVariableRef: {\n          const typedIR = ir as NativeCompilerIR.NewVariableRef;\n          variableRefsToEliminate.set(\n            typedIR.variable,\n            new NativeCompilerBuilderVariableID(\n              typedIR.variable.functionId,\n              typedIR.variable.variable,\n              NativeCompilerBuilderVariableType.Empty,\n              true,\n            ),\n          );\n          break;\n        }\n        case NativeCompilerIR.Kind.GetFunctionArg: {\n          const typedIR = ir as NativeCompilerIR.GetFunctionArg;\n          fnArgToVRef.set(typedIR.variable, undefined);\n          break;\n        }\n        case NativeCompilerIR.Kind.SetVariableRef: {\n          const typedIR = ir as NativeCompilerIR.SetVariableRef;\n\n          if (variableRefsToEliminate.has(typedIR.target)) {\n            const variableReplacement = variableRefsToEliminate.get(typedIR.target)!;\n            if (fnArgToVRef.has(typedIR.value)) {\n              variableRefsToEliminate.set(typedIR.target, typedIR.value);\n            } else {\n              variableReplacement.addType(typedIR.value.type);\n            }\n          }\n\n          break;\n        }\n        case NativeCompilerIR.Kind.NewArrowFunctionValue:\n        case NativeCompilerIR.Kind.NewFunctionValue:\n        case NativeCompilerIR.Kind.NewClassValue: {\n          const typedIR = ir as NativeCompilerIR.NewFunctionValueBase;\n          for (const closureArg of typedIR.closureArgs) {\n            variableRefsToEliminate.delete(closureArg);\n          }\n          break;\n        }\n        default:\n          break;\n      }\n    }\n\n    if (variableRefsToEliminate.size === 0) {\n      // nothing to do\n      return irs;\n    }\n\n    const out: NativeCompilerIR.Base[] = [];\n\n    // Step 2: We eliminate the NewVariableRef, LoadVariableRef, SetVariableRef\n\n    const variableIdsToReplace = new VariableIdMap<NativeCompilerBuilderVariableID>();\n\n    for (const ir of irs) {\n      switch (ir.kind) {\n        case NativeCompilerIR.Kind.NewVariableRef: {\n          const typedIR = ir as NativeCompilerIR.NewVariableRef;\n          if (variableRefsToEliminate.has(typedIR.variable)) {\n            const variableIdReplacement =\n              variableRefsToEliminate.get(typedIR.variable) ??\n              new NativeCompilerBuilderVariableID(\n                typedIR.variable.functionId,\n                typedIR.variable.variable,\n                NativeCompilerBuilderVariableType.Empty,\n                true,\n              );\n            variableIdsToReplace.set(typedIR.variable, variableIdReplacement);\n            continue;\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.LoadVariableRef: {\n          const typedIR = ir as NativeCompilerIR.LoadVariableRef;\n          if (variableRefsToEliminate.has(typedIR.target)) {\n            const variableIdReplacement = variableIdsToReplace.get(typedIR.target)!;\n\n            // Also make sure that the output of this LoadVariableRef maps to our replacement\n            variableIdReplacement.addType(typedIR.variable.type);\n            variableIdsToReplace.set(typedIR.variable, variableIdReplacement);\n            continue;\n          }\n          break;\n        }\n        case NativeCompilerIR.Kind.SetVariableRef: {\n          const typedIR = ir as NativeCompilerIR.SetVariableRef;\n\n          if (variableRefsToEliminate.has(typedIR.target)) {\n            // Replace to assignment\n\n            const assignmentLeft = variableIdsToReplace.get(typedIR.target);\n            if (!assignmentLeft) {\n              throw new Error(\n                `Invalid state: ${typedIR.target.toString()} was not found in map: ${variableIdsToReplace.toString()}`,\n              );\n            }\n            const assignmentRight = variableIdsToReplace.get(typedIR.value) ?? typedIR.value;\n\n            if (assignmentLeft.variable !== typedIR.value.variable) {\n              const assignmentIR: NativeCompilerIR.Assignment = {\n                kind: NativeCompilerIR.Kind.Assignment,\n                left: assignmentLeft,\n                right: assignmentRight,\n              };\n\n              out.push(assignmentIR);\n            }\n\n            continue;\n          }\n          break;\n        }\n        default:\n          break;\n      }\n\n      const newIR = visitVariables(ir, true, (variable) => {\n        return variableIdsToReplace.get(variable) ?? variable;\n      });\n\n      out.push(newIR);\n    }\n\n    return out;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerResolveBuilderStubs.ts",
    "content": "import { NativeCompilerBlockBuilder } from '../../NativeCompilerBuilder';\nimport { NativeCompilerIR } from '../../NativeCompilerBuilderIR';\nimport { NativeCompilerOptions } from '../../../NativeCompilerOptions';\n\nexport namespace NativeCompilerTransformerResolveBuilderStubs {\n  export function transform(\n    ir: Array<NativeCompilerIR.Base>,\n    subbuilder: Array<NativeCompilerBlockBuilder>,\n    options: NativeCompilerOptions,\n  ): Array<NativeCompilerIR.Base> {\n    let retval = new Array<NativeCompilerIR.Base>();\n\n    ir.forEach((ir_) => {\n      switch (ir_.kind) {\n        case NativeCompilerIR.Kind.BuilderStub: {\n          const ir = ir_ as NativeCompilerIR.BuilderStub;\n          const subblock = subbuilder[ir.index];\n          retval = retval.concat(subblock.finalize(options));\n          break;\n        }\n        default:\n          retval.push(ir_);\n          break;\n      }\n    });\n    return retval;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/NativeCompilerTransformerResolveSlots.ts",
    "content": "import { NativeCompilerBuilderVariableID, NativeCompilerBuilderVariableType } from '../../INativeCompilerBuilder';\nimport { NativeCompilerIR } from '../../NativeCompilerBuilderIR';\nimport { visitVariables } from './utils/IRVisitors';\nimport { JumpIndexer } from './utils/JumpIndexer';\n\ninterface VariableLifetime {\n  variable: NativeCompilerBuilderVariableID;\n  firstUseIndex: number;\n  lastUseIndex: number;\n}\n\ninterface VariableLifetimeByID {\n  [key: number]: VariableLifetime;\n}\n\nclass VariablesLifetimeTracker {\n  get allVariables(): readonly NativeCompilerBuilderVariableID[] {\n    return this._allVariables;\n  }\n\n  private variableLifetimeById: VariableLifetimeByID = {};\n  private _allVariables: NativeCompilerBuilderVariableID[] = [];\n\n  constructor() {}\n\n  addVariable(variable: NativeCompilerBuilderVariableID, index: number) {\n    let lifetime = this.variableLifetimeById[variable.variable];\n    if (lifetime === undefined) {\n      this.variableLifetimeById[variable.variable] = { variable, firstUseIndex: index, lastUseIndex: index };\n      this._allVariables.push(variable);\n    } else {\n      lifetime.lastUseIndex = Math.max(lifetime.lastUseIndex, index);\n    }\n  }\n\n  forEachVariableInRange(\n    startIndex: number,\n    endIndex: number,\n    cb: (variable: NativeCompilerBuilderVariableID) => void,\n  ) {\n    for (const variable of this._allVariables) {\n      const lifetime = this.variableLifetimeById[variable.variable]!;\n      if (startIndex > lifetime.lastUseIndex || endIndex < lifetime.firstUseIndex) {\n        continue;\n      }\n\n      cb(variable);\n    }\n  }\n\n  forEachVariableLifetime(cb: (variableLifetime: VariableLifetime) => void) {\n    for (const variable of this._allVariables) {\n      const lifetime = this.variableLifetimeById[variable.variable]!;\n      cb(lifetime);\n    }\n  }\n}\n\ninterface AllocatedVariable {\n  variable: NativeCompilerBuilderVariableID;\n}\n\nclass VariableAllocator {\n  get allVariables(): readonly AllocatedVariable[] {\n    return this._allVariables;\n  }\n\n  private _allVariables: AllocatedVariable[] = [];\n  private _freeVariablesByType: { [type: number]: AllocatedVariable[] } = {};\n  private _allocatedVariableById: { [id: number]: AllocatedVariable | undefined } = {};\n  private _variableCounter = 0;\n\n  getAllocatedVariable(variable: NativeCompilerBuilderVariableID): AllocatedVariable | undefined {\n    return this._allocatedVariableById[variable.variable];\n  }\n\n  tryReuseAllocatedVariable(variable: NativeCompilerBuilderVariableID): AllocatedVariable | undefined {\n    let availableVariables = this._freeVariablesByType[variable.type];\n    if (!availableVariables || !availableVariables.length) {\n      return undefined;\n    }\n\n    const reusedVariable = availableVariables[0];\n    availableVariables.splice(0, 1);\n\n    this._allocatedVariableById[variable.variable] = reusedVariable;\n\n    return reusedVariable;\n  }\n\n  allocateNewVariable(variable: NativeCompilerBuilderVariableID): AllocatedVariable {\n    const newVariable: AllocatedVariable = {\n      variable: new NativeCompilerBuilderVariableID(\n        variable.functionId,\n        ++this._variableCounter,\n        variable.type,\n        variable.assignable,\n      ),\n    };\n\n    this._allVariables.push(newVariable);\n    this._allocatedVariableById[variable.variable] = newVariable;\n    return newVariable;\n  }\n\n  freeAllocatedVariable(variable: NativeCompilerBuilderVariableID) {\n    const allocatedVariable = this._allocatedVariableById[variable.variable];\n    if (!allocatedVariable) {\n      throw new Error(`Variable ${variable.toString()} was not allocated`);\n    }\n\n    let availableVariables = this._freeVariablesByType[allocatedVariable.variable.type];\n    if (!availableVariables) {\n      availableVariables = [];\n      this._freeVariablesByType[allocatedVariable.variable.type] = availableVariables;\n    }\n    availableVariables.push(allocatedVariable);\n    this._allocatedVariableById[variable.variable] = undefined;\n  }\n}\n\nexport namespace NativeCompilerTransformerResolveSlots {\n  export function transform(\n    startFunctionIR: NativeCompilerIR.StartFunction,\n    irs: NativeCompilerIR.Base[],\n    endFunctionIR: NativeCompilerIR.EndFunction,\n    optimize: boolean,\n    stackOnHeap: boolean,\n  ): NativeCompilerIR.Base[] {\n    const lifetimeTracker = new VariablesLifetimeTracker();\n\n    // Track all of the variables\n    irs.forEach((ir, rIndex) => {\n      visitVariables(ir, false, (variable) => {\n        lifetimeTracker.addVariable(variable, rIndex);\n        return variable;\n      });\n    });\n    lifetimeTracker.addVariable(endFunctionIR.returnVariable, irs.length);\n\n    let allVariables: readonly NativeCompilerBuilderVariableID[];\n    let bodyIRs: NativeCompilerIR.Base[];\n\n    if (optimize) {\n      // Index all of the jump targets\n      const jumpIndexer = new JumpIndexer(irs);\n\n      // Extend lifecycles of variables when processing a jump\n      jumpIndexer.forEachBackwardJump((jumpIRIndex, irIndex) => {\n        // We need to extend all the variables used between the jump target\n        // until this IR.\n        lifetimeTracker.forEachVariableInRange(jumpIRIndex, irIndex, (variable) => {\n          lifetimeTracker.addVariable(variable, irIndex);\n        });\n      });\n\n      // Mark the list of variables that are about to stop being used for each IR index.\n      const endingVariablesByIRIndex: { [key: number]: NativeCompilerBuilderVariableID[] } = {};\n      lifetimeTracker.forEachVariableLifetime((variableLifetime) => {\n        let variables = endingVariablesByIRIndex[variableLifetime.lastUseIndex];\n        if (!variables) {\n          variables = [];\n          endingVariablesByIRIndex[variableLifetime.lastUseIndex] = variables;\n        }\n        variables.push(variableLifetime.variable);\n      });\n\n      // Now re-allocates variables\n      const variableAllocator = new VariableAllocator();\n\n      bodyIRs = [];\n\n      variableAllocator.allocateNewVariable(endFunctionIR.returnVariable);\n\n      irs.forEach((ir, rIndex) => {\n        const output = visitVariables(ir, true, (variable) => {\n          const allocatedVariable = variableAllocator.getAllocatedVariable(variable);\n          if (allocatedVariable) {\n            // Already have an allocated variable, use it\n            return allocatedVariable.variable;\n          }\n\n          const reusedVariable = variableAllocator.tryReuseAllocatedVariable(variable);\n          if (reusedVariable) {\n            // We managed to re-use a variable that was marked as unused\n            // If the variable held an object, we need to release it first\n            // before using it\n            if (reusedVariable.variable.isRetainable()) {\n              const free: NativeCompilerIR.Free = {\n                kind: NativeCompilerIR.Kind.Free,\n                value: reusedVariable.variable,\n              };\n              bodyIRs.push(free);\n            }\n            return reusedVariable.variable;\n          }\n\n          // No variable available, allocate a new one\n          return variableAllocator.allocateNewVariable(variable).variable;\n        });\n\n        bodyIRs.push(output);\n\n        // Release variables at this IR index\n        const endingVariables = endingVariablesByIRIndex[rIndex];\n        if (endingVariables) {\n          for (const endingVariable of endingVariables) {\n            variableAllocator.freeAllocatedVariable(endingVariable);\n          }\n        }\n      });\n      allVariables = variableAllocator.allVariables.map((allocatedVariable) => allocatedVariable.variable);\n    } else {\n      bodyIRs = irs;\n      allVariables = lifetimeTracker.allVariables;\n    }\n\n    const slots: NativeCompilerIR.Slot[] = [];\n\n    for (const variable of allVariables) {\n      slots.push({\n        kind: NativeCompilerIR.Kind.Slot,\n        value: variable,\n      });\n      if (stackOnHeap) {\n        startFunctionIR.localVars.push(variable);\n      }\n    }\n\n    return [...slots, ...bodyIRs];\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/utils/IRVisitors.ts",
    "content": "import { NativeCompilerBuilderJumpTargetID, NativeCompilerBuilderVariableID } from '../../../INativeCompilerBuilder';\nimport { NativeCompilerIR } from '../../../NativeCompilerBuilderIR';\n\nexport function isBaseWithReturn(ir: NativeCompilerIR.Base): ir is NativeCompilerIR.BaseWithReturn {\n  switch (ir.kind) {\n    case NativeCompilerIR.Kind.GetFunctionArg:\n    case NativeCompilerIR.Kind.GetFunctionArgumentsObject:\n    case NativeCompilerIR.Kind.GetClosureArg:\n    case NativeCompilerIR.Kind.GetModuleConst:\n    case NativeCompilerIR.Kind.GetSuper:\n    case NativeCompilerIR.Kind.GetSuperConstructor:\n    case NativeCompilerIR.Kind.LiteralInteger:\n    case NativeCompilerIR.Kind.LiteralLong:\n    case NativeCompilerIR.Kind.LiteralDouble:\n    case NativeCompilerIR.Kind.LiteralString:\n    case NativeCompilerIR.Kind.LiteralBool:\n    case NativeCompilerIR.Kind.NewObject:\n    case NativeCompilerIR.Kind.NewArray:\n    case NativeCompilerIR.Kind.Global:\n    case NativeCompilerIR.Kind.Keyword:\n    case NativeCompilerIR.Kind.GetException:\n    case NativeCompilerIR.Kind.Exception:\n    case NativeCompilerIR.Kind.GetProperty:\n    case NativeCompilerIR.Kind.GetPropertyValue:\n    case NativeCompilerIR.Kind.DeleteProperty:\n    case NativeCompilerIR.Kind.DeletePropertyValue:\n    case NativeCompilerIR.Kind.UnaryOp:\n    case NativeCompilerIR.Kind.BinaryOp:\n    case NativeCompilerIR.Kind.NewArrowFunctionValue:\n    case NativeCompilerIR.Kind.NewFunctionValue:\n    case NativeCompilerIR.Kind.NewClassValue:\n    case NativeCompilerIR.Kind.IntrinsicCall:\n    case NativeCompilerIR.Kind.FunctionInvocation:\n    case NativeCompilerIR.Kind.ConstructorInvocation:\n    case NativeCompilerIR.Kind.NewVariableRef:\n    case NativeCompilerIR.Kind.LoadVariableRef:\n    case NativeCompilerIR.Kind.Iterator:\n    case NativeCompilerIR.Kind.KeysIterator:\n    case NativeCompilerIR.Kind.IteratorNext:\n    case NativeCompilerIR.Kind.KeysIteratorNext:\n    case NativeCompilerIR.Kind.Generator:\n    case NativeCompilerIR.Kind.Resume:\n      return true;\n    case NativeCompilerIR.Kind.SetProperty:\n    case NativeCompilerIR.Kind.SetPropertyValue:\n    case NativeCompilerIR.Kind.SetPropertyIndex:\n    case NativeCompilerIR.Kind.CopyPropertiesFrom:\n    case NativeCompilerIR.Kind.Retain:\n    case NativeCompilerIR.Kind.Branch:\n    case NativeCompilerIR.Kind.Throw:\n    case NativeCompilerIR.Kind.Free:\n    case NativeCompilerIR.Kind.Assignment:\n    case NativeCompilerIR.Kind.Jump:\n    case NativeCompilerIR.Kind.Comments:\n    case NativeCompilerIR.Kind.ProgramCounterInfo:\n    case NativeCompilerIR.Kind.BindJumpTarget:\n    case NativeCompilerIR.Kind.SetVariableRef:\n    case NativeCompilerIR.Kind.SetClassElement:\n    case NativeCompilerIR.Kind.SetClassElementValue:\n    case NativeCompilerIR.Kind.CheckException:\n    case NativeCompilerIR.Kind.Reentry:\n    case NativeCompilerIR.Kind.SetResumePoint:\n      return false;\n    default:\n      throw new Error(`Not all IRs are supported: ${ir.kind}`);\n  }\n}\n\nexport function isBaseWithExceptionTarget(ir: NativeCompilerIR.Base): ir is NativeCompilerIR.BaseWithExceptionTarget {\n  if ((ir as unknown as NativeCompilerIR.BaseWithExceptionTarget).exceptionTarget) {\n    return true;\n  }\n  return false;\n}\n\nfunction visitVariableArray(\n  variables: NativeCompilerBuilderVariableID[],\n  transform: boolean,\n  visitor: (variable: NativeCompilerBuilderVariableID) => NativeCompilerBuilderVariableID,\n): NativeCompilerBuilderVariableID[] {\n  if (transform) {\n    const out: NativeCompilerBuilderVariableID[] = [];\n\n    for (const variable of variables) {\n      out.push(visitor(variable));\n    }\n\n    return out;\n  } else {\n    for (const variable of variables) {\n      visitor(variable);\n    }\n    return variables;\n  }\n}\n\nexport function visitVariables(\n  ir: NativeCompilerIR.Base,\n  transform: boolean,\n  visitor: (variable: NativeCompilerBuilderVariableID) => NativeCompilerBuilderVariableID,\n): NativeCompilerIR.Base {\n  switch (ir.kind) {\n    case NativeCompilerIR.Kind.GetFunctionArg:\n    case NativeCompilerIR.Kind.GetFunctionArgumentsObject:\n    case NativeCompilerIR.Kind.GetClosureArg:\n    case NativeCompilerIR.Kind.GetModuleConst:\n    case NativeCompilerIR.Kind.LiteralInteger:\n    case NativeCompilerIR.Kind.LiteralLong:\n    case NativeCompilerIR.Kind.LiteralDouble:\n    case NativeCompilerIR.Kind.LiteralString:\n    case NativeCompilerIR.Kind.LiteralBool:\n    case NativeCompilerIR.Kind.NewObject:\n    case NativeCompilerIR.Kind.NewArray:\n    case NativeCompilerIR.Kind.Global:\n    case NativeCompilerIR.Kind.Keyword:\n    case NativeCompilerIR.Kind.GetException:\n    case NativeCompilerIR.Kind.NewVariableRef:\n    case NativeCompilerIR.Kind.Exception: {\n      let typedIR = ir as NativeCompilerIR.BaseWithReturn;\n      const variable = visitor(typedIR.variable);\n\n      if (transform) {\n        typedIR = { ...typedIR, variable };\n      }\n\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.GetSuper: {\n      let typedIR = ir as NativeCompilerIR.GetSuper;\n      const variable = visitor(typedIR.variable);\n      if (transform) {\n        typedIR = { ...typedIR, variable };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.GetSuperConstructor: {\n      let typedIR = ir as NativeCompilerIR.GetSuperConstructor;\n      const variable = visitor(typedIR.variable);\n      if (transform) {\n        typedIR = { ...typedIR, variable };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.SetProperty: {\n      let typedIR = ir as NativeCompilerIR.SetProperty;\n      const object = visitor(typedIR.object);\n      const values = typedIR.values.map((v) => {\n        return visitor(v);\n      });\n      if (transform) {\n        typedIR = { ...typedIR, object, values };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.SetPropertyValue: {\n      let typedIR = ir as NativeCompilerIR.SetPropertyValue;\n      const object = visitor(typedIR.object);\n      const property = visitor(typedIR.property);\n      const value = visitor(typedIR.value);\n      if (transform) {\n        typedIR = { ...typedIR, object, property, value };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.SetPropertyIndex: {\n      let typedIR = ir as NativeCompilerIR.SetPropertyIndex;\n      const object = visitor(typedIR.object);\n      const value = visitor(typedIR.value);\n      if (transform) {\n        typedIR = { ...typedIR, object, value };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.CopyPropertiesFrom: {\n      let typedIR = ir as NativeCompilerIR.CopyPropertiesFrom;\n      const object = visitor(typedIR.object);\n      const value = visitor(typedIR.value);\n      const copiedPropertiesCount = visitor(typedIR.copiedPropertiesCount);\n      if (transform) {\n        typedIR = { ...typedIR, object, value, copiedPropertiesCount };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.Retain: {\n      let typedIR = ir as NativeCompilerIR.Retain;\n      const value = visitor(typedIR.value);\n      if (transform) {\n        typedIR = { ...typedIR, value };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.Branch: {\n      let typedIR = ir as NativeCompilerIR.Branch;\n      const conditionVariable = visitor(typedIR.conditionVariable);\n      if (transform) {\n        typedIR = { ...typedIR, conditionVariable };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.Throw: {\n      let typedIR = ir as NativeCompilerIR.Throw;\n      const value = visitor(typedIR.value);\n      if (transform) {\n        typedIR = { ...typedIR, value };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.Free: {\n      let typedIR = ir as NativeCompilerIR.Free;\n      const value = visitor(typedIR.value);\n      if (transform) {\n        typedIR = { ...typedIR, value };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.FreeV: {\n      let typedIR = ir as NativeCompilerIR.FreeV;\n      const values = typedIR.values.map((v) => {\n        return visitor(v);\n      });\n      if (transform) {\n        typedIR = { ...typedIR, values };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.GetProperty: {\n      let typedIR = ir as NativeCompilerIR.GetProperty;\n      const variable = visitor(typedIR.variable);\n      const object = visitor(typedIR.object);\n      const thisObject = visitor(typedIR.thisObject);\n      if (transform) {\n        typedIR = { ...typedIR, variable, object, thisObject };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.GetPropertyFree: {\n      let typedIR = ir as NativeCompilerIR.GetPropertyFree;\n      const variable = visitor(typedIR.variable);\n      const object = visitor(typedIR.object);\n      const thisObject = visitor(typedIR.thisObject);\n      if (transform) {\n        typedIR = { ...typedIR, variable, object, thisObject };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.GetPropertyValue: {\n      let typedIR = ir as NativeCompilerIR.GetPropertyValue;\n      const variable = visitor(typedIR.variable);\n      const property = visitor(typedIR.property);\n      const object = visitor(typedIR.object);\n      const thisObject = visitor(typedIR.thisObject);\n      if (transform) {\n        typedIR = { ...typedIR, variable, object, property, thisObject };\n      }\n\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.DeleteProperty: {\n      let typedIR = ir as NativeCompilerIR.DeleteProperty;\n      const variable = visitor(typedIR.variable);\n      const object = visitor(typedIR.object);\n      if (transform) {\n        typedIR = { ...typedIR, variable, object };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.DeletePropertyValue: {\n      let typedIR = ir as NativeCompilerIR.DeletePropertyValue;\n      const variable = visitor(typedIR.variable);\n      const property = visitor(typedIR.property);\n      const object = visitor(typedIR.object);\n      if (transform) {\n        typedIR = { ...typedIR, variable, object, property };\n      }\n\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.UnaryOp: {\n      let typedIR = ir as NativeCompilerIR.UnaryOp;\n      const variable = visitor(typedIR.variable);\n      const operand = visitor(typedIR.operand);\n\n      if (transform) {\n        typedIR = { ...typedIR, variable, operand };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.BinaryOp: {\n      let typedIR = ir as NativeCompilerIR.BinaryOp;\n      const variable = visitor(typedIR.variable);\n      const left = visitor(typedIR.left);\n      const right = visitor(typedIR.right);\n\n      if (transform) {\n        typedIR = { ...typedIR, variable, left, right };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.NewArrowFunctionValue:\n    case NativeCompilerIR.Kind.NewFunctionValue: {\n      let typedIR = ir as NativeCompilerIR.NewArrowFunctionValue | NativeCompilerIR.NewFunctionValue;\n      const variable = visitor(typedIR.variable);\n      const closureArgs = visitVariableArray(typedIR.closureArgs, transform, visitor);\n\n      if (transform) {\n        typedIR = { ...typedIR, variable, closureArgs };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.NewClassValue: {\n      let typedIR = ir as NativeCompilerIR.NewClassValue;\n      const variable = visitor(typedIR.variable);\n      const parentClass = visitor(typedIR.parentClass);\n      const closureArgs = visitVariableArray(typedIR.closureArgs, transform, visitor);\n\n      if (transform) {\n        typedIR = { ...typedIR, variable, parentClass, closureArgs };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.SetClassElement: {\n      let typedIR = ir as NativeCompilerIR.SetClassElement;\n      const cls = visitor(typedIR.cls);\n      const value = visitor(typedIR.value);\n\n      if (transform) {\n        typedIR = { ...typedIR, cls, value };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.SetClassElementValue: {\n      let typedIR = ir as NativeCompilerIR.SetClassElementValue;\n      const cls = visitor(typedIR.cls);\n      const name = visitor(typedIR.name);\n      const value = visitor(typedIR.value);\n\n      if (transform) {\n        typedIR = { ...typedIR, cls, name, value };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.IntrinsicCall: {\n      let typedIR = ir as NativeCompilerIR.FunctionInvocation;\n      const variable = visitor(typedIR.variable);\n      const args = visitVariableArray(typedIR.args, transform, visitor);\n      if (transform) {\n        typedIR = { ...typedIR, variable, args };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.FunctionInvocation: {\n      let typedIR = ir as NativeCompilerIR.FunctionInvocation;\n      const variable = visitor(typedIR.variable);\n      const func = visitor(typedIR.func);\n      const obj = visitor(typedIR.obj);\n      const args = visitVariableArray(typedIR.args, transform, visitor);\n\n      if (transform) {\n        typedIR = { ...typedIR, variable, func, obj, args };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.ConstructorInvocation: {\n      let typedIR = ir as NativeCompilerIR.ConstructorInvocation;\n      const variable = visitor(typedIR.variable);\n      const func = visitor(typedIR.func);\n      const new_target = visitor(typedIR.new_target);\n      const args = visitVariableArray(typedIR.args, transform, visitor);\n\n      if (transform) {\n        typedIR = { ...typedIR, variable, func, new_target, args };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.Assignment: {\n      let typedIR = ir as NativeCompilerIR.Assignment;\n      const left = visitor(typedIR.left);\n      const right = visitor(typedIR.right);\n      if (transform) {\n        typedIR = { ...typedIR, left, right };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.LoadVariableRef: {\n      let typedIR = ir as NativeCompilerIR.LoadVariableRef;\n      const target = visitor(typedIR.target);\n      const variable = visitor(typedIR.variable);\n      if (transform) {\n        typedIR = { ...typedIR, target, variable };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.SetVariableRef: {\n      let typedIR = ir as NativeCompilerIR.SetVariableRef;\n      const target = visitor(typedIR.target);\n      const value = visitor(typedIR.value);\n      if (transform) {\n        typedIR = { ...typedIR, target, value };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.Iterator:\n    case NativeCompilerIR.Kind.KeysIterator: {\n      let typedIR = ir as NativeCompilerIR.Iterator | NativeCompilerIR.KeysIterator;\n      const arg = visitor(typedIR.arg);\n      const variable = visitor(typedIR.variable);\n      if (transform) {\n        typedIR = { ...typedIR, arg, variable };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.IteratorNext:\n    case NativeCompilerIR.Kind.KeysIteratorNext: {\n      let typedIR = ir as NativeCompilerIR.IteratorNext | NativeCompilerIR.KeysIteratorNext;\n      const iterator = visitor(typedIR.iterator);\n      const variable = visitor(typedIR.variable);\n      if (transform) {\n        typedIR = { ...typedIR, iterator, variable };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.Generator: {\n      let typedIR = ir as NativeCompilerIR.Generator;\n      const arg = visitor(typedIR.arg);\n      const variable = visitor(typedIR.variable);\n      if (transform) {\n        typedIR = { ...typedIR, arg, variable };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.Resume: {\n      let typedIR = ir as NativeCompilerIR.Resume;\n      const variable = visitor(typedIR.variable);\n      if (transform) {\n        typedIR = { ...typedIR, variable };\n      }\n      return typedIR;\n    }\n    case NativeCompilerIR.Kind.CheckException:\n    case NativeCompilerIR.Kind.Jump:\n    case NativeCompilerIR.Kind.Comments:\n    case NativeCompilerIR.Kind.ProgramCounterInfo:\n    case NativeCompilerIR.Kind.BindJumpTarget:\n    case NativeCompilerIR.Kind.Reentry:\n    case NativeCompilerIR.Kind.SetResumePoint:\n      return ir;\n    default:\n      throw new Error(`Not all IRs are supported: ${ir.kind}`);\n  }\n}\n\nexport function visitJump(ir: NativeCompilerIR.Base, visitor: (jump: NativeCompilerBuilderJumpTargetID) => void) {\n  switch (ir.kind) {\n    case NativeCompilerIR.Kind.Throw:\n      {\n        const typedIR = ir as NativeCompilerIR.Throw;\n        visitor(typedIR.target);\n      }\n      break;\n    case NativeCompilerIR.Kind.Jump:\n      {\n        const typedIR = ir as NativeCompilerIR.Jump;\n        visitor(typedIR.target);\n      }\n      break;\n    case NativeCompilerIR.Kind.Branch:\n      {\n        const typedIR = ir as NativeCompilerIR.Branch;\n        visitor(typedIR.trueTarget);\n        if (typedIR.falseTarget) {\n          visitor(typedIR.falseTarget);\n        }\n      }\n      break;\n    case NativeCompilerIR.Kind.Reentry:\n      {\n        const typedIR = ir as NativeCompilerIR.Reentry;\n        for (const rp of typedIR.resumePoints) {\n          visitor(rp);\n        }\n      }\n      break;\n    default:\n      {\n        if (isBaseWithExceptionTarget(ir)) {\n          const typedIr = ir as NativeCompilerIR.BaseWithExceptionTarget;\n          visitor(typedIr.exceptionTarget);\n        }\n      }\n      break;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/builder/internal/transformers/utils/JumpIndexer.ts",
    "content": "import { NativeCompilerIR } from '../../../NativeCompilerBuilderIR';\nimport { visitJump } from './IRVisitors';\n\nexport class JumpIndexer {\n  private irIndexByJumpTarget: { [key: number]: number } = {};\n\n  constructor(readonly irs: NativeCompilerIR.Base[]) {\n    irs.forEach((ir, rIndex) => {\n      if (ir.kind === NativeCompilerIR.Kind.BindJumpTarget) {\n        const jumpTarget = ir as NativeCompilerIR.BindJumpTarget;\n        this.irIndexByJumpTarget[jumpTarget.target.label] = rIndex;\n      }\n    });\n  }\n\n  /**\n   * Call the given callback for each jump to a jump target to an instruction\n   * that is before the jump instruction.\n   * @param cb\n   */\n  forEachBackwardJump(cb: (jumpIRIndex: number, irIndex: number) => void) {\n    this.irs.forEach((ir, irIndex) => {\n      visitJump(ir, (jump) => {\n        const jumpIRIndex = this.irIndexByJumpTarget[jump.label]!;\n        if (jumpIRIndex > irIndex) {\n          // Forward Jump\n          return;\n        }\n\n        cb(jumpIRIndex, irIndex);\n      });\n    });\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/emitter/CompilerNativeCEmitter.ts",
    "content": "import {\n  NativeCompilerBuilderVariableID,\n  NativeCompilerBuilderJumpTargetID,\n  NativeCompilerBuilderAtomID,\n  NativeCompilerBuilderBranchType,\n  NativeCompilerBuilderVariableType,\n} from '../builder/INativeCompilerBuilder';\nimport { NativeCompilerIR } from '../builder/NativeCompilerBuilderIR';\nimport { NativeCodeWriter } from '../NativeCodeWriter';\nimport { escapeCComment, toCString } from '../utils/StringEscape';\nimport { NativeCompilerOptions } from '../NativeCompilerOptions';\n\nimport { INativeCompilerIREmitter, NativeCompilerEmitterOutput } from './INativeCompilerEmitter';\n\nconst getNativeCompilerFunctionArgToStringLUT = {\n  [NativeCompilerIR.FunctionTypeArgs.Context]: 'ctx',\n  [NativeCompilerIR.FunctionTypeArgs.This]: 'this_val',\n  [NativeCompilerIR.FunctionTypeArgs.StackFrame]: 'stackframe',\n  [NativeCompilerIR.FunctionTypeArgs.Argc]: 'argc',\n  [NativeCompilerIR.FunctionTypeArgs.Argv]: 'argv',\n  [NativeCompilerIR.FunctionTypeArgs.Closure]: 'closure',\n  [NativeCompilerIR.FunctionTypeArgs.NewTarget]: 'new_target',\n};\n\nconst getNativeFunctionArguementDeclarationStringLUT = {\n  [NativeCompilerIR.FunctionTypeArgs.Context]:\n    'tsn_vm *' + getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n  [NativeCompilerIR.FunctionTypeArgs.This]:\n    'tsn_value_const ' + getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.This),\n  [NativeCompilerIR.FunctionTypeArgs.Argc]:\n    'int ' + getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Argc),\n  [NativeCompilerIR.FunctionTypeArgs.StackFrame]:\n    'tsn_stackframe *' + getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.StackFrame),\n  [NativeCompilerIR.FunctionTypeArgs.Argv]:\n    'tsn_value_const *' + getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Argv),\n  [NativeCompilerIR.FunctionTypeArgs.Closure]:\n    'tsn_closure *' + getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Closure),\n  [NativeCompilerIR.FunctionTypeArgs.NewTarget]:\n    'tsn_value_const ' + getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.NewTarget),\n};\n\nfunction getNativeCompilerFunctionArgToString(arg: NativeCompilerIR.FunctionTypeArgs): string {\n  return getNativeCompilerFunctionArgToStringLUT[arg];\n}\n\nfunction getJumpTargetName(name: string, jumpTarget: NativeCompilerBuilderJumpTargetID) {\n  return `target_${name}_${jumpTarget.label}_${jumpTarget.tag}`;\n}\n\nfunction convertFunctionArgsToString(type: NativeCompilerIR.FunctionType) {\n  const args = NativeCompilerIR.getFunctionArgsFromType(type);\n  return args.map((arg) => getNativeFunctionArguementDeclarationString(arg));\n}\n\nfunction getNativeFunctionArguementDeclarationString(arg: NativeCompilerIR.FunctionTypeArgs): string {\n  return getNativeFunctionArguementDeclarationStringLUT[arg];\n}\n\ninterface CompilerNativeCEmitterFunctionContext {\n  readonly name: string;\n  readonly type: NativeCompilerIR.FunctionType;\n  readonly exceptionJumpTarget: NativeCompilerBuilderJumpTargetID;\n  readonly returnJumpTarget: NativeCompilerBuilderJumpTargetID;\n  readonly stackOnHeap: boolean;\n}\n\nconst enum VariadicCallArgumentType {\n  Atom,\n  VarRef,\n  Value,\n}\n\nfunction getVariadicCallArgumentTypeString(argumentType: VariadicCallArgumentType): string {\n  switch (argumentType) {\n    case VariadicCallArgumentType.Atom:\n      return 'tsn_atom';\n    case VariadicCallArgumentType.VarRef:\n      return 'tsn_var_ref';\n    case VariadicCallArgumentType.Value:\n      return 'tsn_value';\n  }\n}\n\nfunction generateVariadicCallArguments(argumentType: VariadicCallArgumentType, input: string[]): string[] {\n  if (input.length === 0) {\n    return ['0', `NULL`];\n  } else {\n    return [input.length.toString(), `(${getVariadicCallArgumentTypeString(argumentType)}[]){${input.join(', ')}}`];\n  }\n}\n\nexport class CompilerNativeCEmitter implements INativeCompilerIREmitter {\n  private _functionContext: CompilerNativeCEmitterFunctionContext | undefined;\n  private _functionPrototypeBlock: NativeCodeWriter | undefined;\n  private writer = new NativeCodeWriter();\n  private _symbol: string | undefined;\n  private atomDefineNameById: string[] = [];\n  private allocatedAtomDefineNames = new Set<string>();\n  private pendingRegisterCalls: [string, string][] = [];\n\n  private get functionContext(): CompilerNativeCEmitterFunctionContext {\n    if (this._functionContext === undefined) {\n      throw new Error('_functionContext needs to be initialized');\n    }\n    return this._functionContext;\n  }\n\n  private get functionPrototypeBlock(): NativeCodeWriter {\n    if (this._functionPrototypeBlock === undefined) {\n      throw new Error('_functionPrototypeBlock needs to be initialized');\n    }\n    return this._functionPrototypeBlock;\n  }\n\n  private set functionContext(context: CompilerNativeCEmitterFunctionContext | undefined) {\n    this._functionContext = context;\n  }\n\n  private getVariableName(variableID: NativeCompilerBuilderVariableID) {\n    const prefix =\n      variableID.type !== NativeCompilerBuilderVariableType.ReturnValue && this.functionContext.stackOnHeap\n        ? 'stack->'\n        : '';\n    return prefix + variableID.toString();\n  }\n\n  constructor(readonly options: NativeCompilerOptions) {\n    this.emitPrologue();\n  }\n\n  private allocateAtom(atom: NativeCompilerBuilderAtomID): string {\n    const baseName = `TSN_ATOM_${atom.identifier.toUpperCase()}`;\n    let name = baseName;\n\n    let i = 0;\n    while (this.allocatedAtomDefineNames.has(name)) {\n      name = `${baseName}_${i + 1}`;\n      i++;\n    }\n    this.allocatedAtomDefineNames.add(name);\n    this.atomDefineNameById[atom.atom] = name;\n\n    return name;\n  }\n\n  private resolveAtomDefineName(atom: NativeCompilerBuilderAtomID): string {\n    const atomDefineName = this.atomDefineNameById[atom.atom];\n    if (!atomDefineName) {\n      throw new Error(`Atom ${atom.identifier} with id ${atom.atom} was not allocated`);\n    }\n\n    return atomDefineName;\n  }\n\n  private resolveAtomString(atom: NativeCompilerBuilderAtomID): string {\n    const atomDefineName = this.resolveAtomDefineName(atom);\n    return `module->atoms[${atomDefineName}]`;\n  }\n\n  private emitPrologue() {\n    this.writer.appendWithNewLine(`#include \"tsn/tsn.h\"`);\n    this.writer.appendWithNewLine(`#include <math.h>`);\n  }\n\n  emitBoilerplatePrologue(atoms: NativeCompilerBuilderAtomID[]) {\n    this.writer.appendWithNewLine('\\n // BEGIN ATOMS');\n    for (const atom of atoms) {\n      const defineName = this.allocateAtom(atom);\n      this.writer.appendWithNewLine(`#define ${defineName} ${atom.atom}`);\n    }\n    this.writer.appendWithNewLine('// END ATOMS\\n');\n\n    this._functionPrototypeBlock = new NativeCodeWriter();\n    this.writer.appendWithNewLine(this.functionPrototypeBlock);\n  }\n\n  emitBoilerplateEpilogue(\n    moduleName: string,\n    modulePath: string,\n    moduleInitFunctionName: string,\n    atoms: readonly NativeCompilerBuilderAtomID[],\n    stringConstants: readonly string[],\n    propCacheSlots: number,\n  ) {\n    this.writer.appendWithNewLine(`\\n // BEGIN MODULE DEFINITION '${moduleName}'`);\n    this.writer.append(`static const tsn_string_def ${moduleName}_module_atoms[] = `);\n    this.writer.beginInitialization();\n    for (const atom of atoms) {\n      const cString = toCString(atom.identifier);\n      this.writer.appendWithNewLine(`{${cString.literalContent}, ${cString.length}},`);\n    }\n    this.writer.endInitialization();\n    this.writer.append(`static const tsn_string_def ${moduleName}_module_constants[] = `);\n    this.writer.beginInitialization();\n    for (const stringConstant of stringConstants) {\n      const cString = toCString(stringConstant);\n      this.writer.appendWithNewLine(`{${cString.literalContent}, ${cString.length}},`);\n    }\n    this.writer.endInitialization();\n\n    const functionName = `${moduleName}_create_module_func`;\n    this.writer.append(\n      `static tsn_value ${functionName}(tsn_vm *${getNativeCompilerFunctionArgToString(\n        NativeCompilerIR.FunctionTypeArgs.Context,\n      )})`,\n    );\n\n    this.writer.beginScope();\n\n    const moduleVarName = 'module';\n\n    this.writer.appendWithNewLine(`tsn_module *${moduleVarName};`);\n    this.writer.appendAssignmentWithFunctionCall(moduleVarName, 'tsn_new_module', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      atoms.length.toString(),\n      stringConstants.length.toString(),\n      propCacheSlots.toString(),\n    ]);\n\n    this.writer.appendFunctionCall('tsn_assign_module_atoms', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      'module',\n      `${moduleName}_module_atoms`,\n      atoms.length.toString(),\n    ]);\n    this.writer.appendFunctionCall('tsn_assign_module_strings', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      'module',\n      `${moduleName}_module_constants`,\n      stringConstants.length.toString(),\n    ]);\n    this.writer.appendWithNewLine(`tsn_value output;`);\n    this.writer.appendAssignmentWithFunctionCall('output', 'tsn_new_module_init_fn', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      moduleVarName,\n      `&${moduleInitFunctionName}`,\n    ]);\n\n    this.writer.appendFunctionCall('tsn_free_module', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      moduleVarName,\n    ]);\n\n    this.writer.appendWithNewLine(`return output;`);\n\n    this.writer.endScope();\n\n    this.pendingRegisterCalls.push([modulePath, functionName]);\n  }\n\n  emitStartFunction(\n    name: string,\n    type: NativeCompilerIR.FunctionType,\n    exceptionJumpTarget: NativeCompilerBuilderJumpTargetID,\n    returnJumpTarget: NativeCompilerBuilderJumpTargetID,\n    returnVariable: NativeCompilerBuilderVariableID,\n    localVars: NativeCompilerBuilderVariableID[],\n  ) {\n    this.functionContext = {\n      name: name,\n      type: type,\n      exceptionJumpTarget: exceptionJumpTarget,\n      returnJumpTarget: returnJumpTarget,\n      stackOnHeap: localVars.length > 0,\n    };\n\n    if (this.functionContext.stackOnHeap) {\n      this.functionPrototypeBlock.appendWithNewLine(`typedef struct {`);\n      let numberOfValues = 0;\n      let numberOfVRefs = 0;\n      let numberOfIterators = 0;\n      this.functionPrototypeBlock.withIndentation('    ', () => {\n        // all var_refs first\n        for (let v of localVars) {\n          if (v.type === NativeCompilerBuilderVariableType.VariableRef) {\n            this.functionPrototypeBlock.appendWithNewLine(`tsn_var_ref ${v.toString()};`);\n            ++numberOfVRefs;\n          }\n        }\n        // followed by values\n        for (let v of localVars) {\n          if (\n            v.type !== NativeCompilerBuilderVariableType.VariableRef &&\n            v.type !== NativeCompilerBuilderVariableType.ReturnValue &&\n            v.type !== NativeCompilerBuilderVariableType.Iterator\n          ) {\n            this.functionPrototypeBlock.appendWithNewLine(`tsn_value ${v.toString()};`);\n            ++numberOfValues;\n          }\n        }\n        // followed by iterators\n        for (let v of localVars) {\n          if (v.type === NativeCompilerBuilderVariableType.Iterator) {\n            this.functionPrototypeBlock.appendWithNewLine(`tsn_iterator ${v.toString()};`);\n            ++numberOfIterators;\n          }\n        }\n      });\n      this.functionPrototypeBlock.appendWithNewLine(`} ${name}_stack_vars;`);\n      this.functionPrototypeBlock.appendWithNewLine(\n        `enum { ${name}_stack_vars_vrefs = ${numberOfVRefs}, ${name}_stack_vars_values = ${numberOfValues}, ${name}_stack_vars_iterators = ${numberOfIterators} };`,\n      );\n    }\n\n    [this.writer, this.functionPrototypeBlock].forEach((writer) => {\n      writer.append('static tsn_value');\n      writer.append(` ${name}(`);\n      writer.appendParameterList(convertFunctionArgsToString(type));\n      writer.append(`)`);\n    });\n    this.functionPrototypeBlock.appendWithNewLine(';');\n\n    this.writer.appendWithNewLine();\n    this.writer.beginScope();\n\n    this.writer.appendWithNewLine(\n      `tsn_module *module = ${getNativeCompilerFunctionArgToString(\n        NativeCompilerIR.FunctionTypeArgs.Closure,\n      )}->module;`,\n    );\n\n    this.writer.appendWithNewLine(\n      `tsn_value ${this.getVariableName(returnVariable)} = tsn_undefined(${getNativeCompilerFunctionArgToString(\n        NativeCompilerIR.FunctionTypeArgs.Context,\n      )});`,\n    );\n\n    if (this.functionContext.stackOnHeap) {\n      this.writer.appendWithNewLine(`${name}_stack_vars* stack = (${name}_stack_vars*)get_closure_stack(closure);`);\n    }\n  }\n\n  emitEndFunction(returnVariable: NativeCompilerBuilderVariableID) {\n    this.writer.appendWithNewLine(`return ${this.getVariableName(returnVariable)};`);\n    this.writer.endScope();\n    this.writer.appendWithNewLine();\n    this.functionContext = undefined;\n  }\n\n  emitSlot(value: NativeCompilerBuilderVariableID) {\n    if (value.type === NativeCompilerBuilderVariableType.VariableRef) {\n      const prefix = this.functionContext.stackOnHeap ? '' : 'tsn_var_ref ';\n      this.writer.appendWithNewLine(\n        `${prefix}${this.getVariableName(value)} = tsn_empty_var_ref(${getNativeCompilerFunctionArgToString(\n          NativeCompilerIR.FunctionTypeArgs.Context,\n        )});`,\n      );\n    } else if (value.type === NativeCompilerBuilderVariableType.Iterator) {\n      const prefix = this.functionContext.stackOnHeap ? '' : 'tsn_iterator ';\n      this.writer.appendWithNewLine(\n        `${prefix}${this.getVariableName(value)} = tsn_empty_iterator(${getNativeCompilerFunctionArgToString(\n          NativeCompilerIR.FunctionTypeArgs.Context,\n        )});`,\n      );\n    } else if (value.type === NativeCompilerBuilderVariableType.Null) {\n      const prefix = this.functionContext.stackOnHeap ? '' : 'tsn_value ';\n      this.writer.appendWithNewLine(\n        `${prefix}${this.getVariableName(value)} = tsn_null(${getNativeCompilerFunctionArgToString(\n          NativeCompilerIR.FunctionTypeArgs.Context,\n        )});`,\n      );\n    } else if (value.type !== NativeCompilerBuilderVariableType.ReturnValue) {\n      const prefix = this.functionContext.stackOnHeap ? '' : 'tsn_value ';\n      this.writer.appendWithNewLine(\n        `${prefix}${this.getVariableName(value)} = tsn_undefined(${getNativeCompilerFunctionArgToString(\n          NativeCompilerIR.FunctionTypeArgs.Context,\n        )});`,\n      );\n    }\n  }\n\n  emitGlobal(variable: NativeCompilerBuilderVariableID) {\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), `tsn_get_global`, [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n    ]);\n  }\n\n  emitUndefined(variable: NativeCompilerBuilderVariableID) {\n    this.writeAssign(\n      variable,\n      `tsn_undefined(${getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)})`,\n    );\n  }\n\n  emitNull(variable: NativeCompilerBuilderVariableID): void {\n    this.writeAssign(\n      variable,\n      `tsn_null(${getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)})`,\n    );\n  }\n\n  emitThis(variable: NativeCompilerBuilderVariableID): void {\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), 'tsn_retain', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.This),\n    ]);\n  }\n\n  emitNewTarget(variable: NativeCompilerBuilderVariableID): void {\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), 'tsn_retain', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.NewTarget),\n    ]);\n  }\n\n  emitException(variable: NativeCompilerBuilderVariableID) {\n    this.writeAssign(\n      variable,\n      `tsn_exception(${getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)})`,\n    );\n  }\n\n  emitGetException(variable: NativeCompilerBuilderVariableID): void {\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), 'tsn_get_exception', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n    ]);\n  }\n\n  emitCheckException(exceptionTarget: NativeCompilerBuilderJumpTargetID): void {\n    this.appendCheckedFunctionCall(\n      'tsn_has_exception',\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)],\n      exceptionTarget,\n    );\n  }\n\n  private generateMonoOperandOp(\n    retval: NativeCompilerBuilderVariableID,\n    operand: NativeCompilerBuilderVariableID,\n    funcName: string,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ) {\n    // if operand is number or bool, we can omit exception check\n    const safeOp =\n      operand.type == NativeCompilerBuilderVariableType.Number ||\n      operand.type == NativeCompilerBuilderVariableType.Bool;\n    const args = [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      this.getVariableName(operand),\n    ];\n    if (safeOp) {\n      this.writer.appendAssignmentWithFunctionCall(this.getVariableName(retval), funcName, args);\n    } else {\n      this.appendCheckedInOutFunctionCall(retval, funcName, args, exceptionTarget);\n    }\n  }\n\n  private generateUndefOrNullCheck(\n    retval: NativeCompilerBuilderVariableID,\n    operand: NativeCompilerBuilderVariableID,\n    funcName: string,\n  ) {\n    const ctx = getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context);\n    this.writeAssign(retval, `tsn_new_bool(${ctx}, ${funcName}(${ctx}, ${this.getVariableName(operand)}))`);\n  }\n\n  private generateTwoOperandOp(\n    retval: NativeCompilerBuilderVariableID,\n    left: NativeCompilerBuilderVariableID,\n    right: NativeCompilerBuilderVariableID,\n    funcName: string,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ) {\n    // if both sides are same type of either number or bool, we can omit exception check\n    const safeOp =\n      left.type == right.type &&\n      (left.type == NativeCompilerBuilderVariableType.Number || left.type == NativeCompilerBuilderVariableType.Bool);\n\n    const args = [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      this.getVariableName(left),\n      this.getVariableName(right),\n    ];\n\n    if (safeOp) {\n      this.writer.appendAssignmentWithFunctionCall(this.getVariableName(retval), funcName, args);\n    } else {\n      this.appendCheckedInOutFunctionCall(retval, funcName, args, exceptionTarget);\n    }\n  }\n\n  private appendCheckedInOutFunctionCall(\n    variable: NativeCompilerBuilderVariableID,\n    func: string,\n    args: Array<string>,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    const functionContext = this.functionContext;\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), func, args);\n\n    this.writer.beginIfStatement();\n\n    let functionName: string;\n    let byPointer = false;\n    switch (variable.type) {\n      case NativeCompilerBuilderVariableType.VariableRef:\n        functionName = 'tsn_var_ref_is_exception';\n        break;\n      case NativeCompilerBuilderVariableType.Iterator:\n        functionName = 'tsn_iterator_is_exception';\n        byPointer = true;\n        break;\n      default:\n        functionName = 'tsn_is_exception';\n        break;\n    }\n\n    this.writer.appendFunctionCall(\n      functionName,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        byPointer ? '&' + this.getVariableName(variable) : this.getVariableName(variable),\n      ],\n      false,\n    );\n    this.writer.endEndifStatement();\n    this.writer.beginScope();\n    this.writer.appendGoto(getJumpTargetName(functionContext.name, exceptionTarget));\n    this.writer.endScope();\n  }\n\n  private appendCheckedFunctionCall(\n    func: string,\n    args: Array<string>,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    const functionContext = this.functionContext;\n    this.writer.beginIfStatement();\n    this.writer.appendFunctionCall(func, args, false);\n    this.writer.endEndifStatement();\n    this.writer.beginScope();\n    this.writer.appendGoto(getJumpTargetName(functionContext.name, exceptionTarget));\n    this.writer.endScope();\n  }\n\n  emitSetProperty(\n    object: NativeCompilerBuilderVariableID,\n    properties: NativeCompilerBuilderAtomID[],\n    values: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ) {\n    if (properties.length == 1) {\n      this.appendCheckedFunctionCall(\n        'tsn_set_property',\n        [\n          getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n          '&' + this.getVariableName(object),\n          this.resolveAtomString(properties[0]),\n          '&' + this.getVariableName(values[0]),\n        ],\n        exceptionTarget,\n      );\n    } else {\n      const atoms = properties.map((a) => this.resolveAtomDefineName(a)).join(', ');\n      const vals = values.map((v) => this.getVariableName(v)).join(', ');\n      this.appendCheckedFunctionCall(\n        'tsn_set_properties',\n        [\n          getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n          '&' + this.getVariableName(object),\n          properties.length.toString(),\n          `(int[]){${atoms}}`,\n          `(tsn_value[]){${vals}}`,\n          'module',\n        ],\n        exceptionTarget,\n      );\n    }\n  }\n\n  emitSetPropertyValue(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    value: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedFunctionCall(\n      `tsn_set_property_value`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(object),\n        this.getVariableName(property),\n        this.getVariableName(value),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitSetPropertyIndex(\n    object: NativeCompilerBuilderVariableID,\n    index: number,\n    value: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedFunctionCall(\n      `tsn_set_property_index`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(object),\n        index.toString(),\n        this.getVariableName(value),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitCopyPropertiesFrom(\n    object: NativeCompilerBuilderVariableID,\n    value: NativeCompilerBuilderVariableID,\n    propertiesToIgnore: NativeCompilerBuilderAtomID[] | undefined,\n    copiedPropertiesCount: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    const args: string[] = [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      this.getVariableName(object),\n      this.getVariableName(value),\n    ];\n    if (propertiesToIgnore && propertiesToIgnore.length > 0) {\n      args.push(\n        ...generateVariadicCallArguments(\n          VariadicCallArgumentType.Atom,\n          propertiesToIgnore.map((p) => this.resolveAtomString(p)),\n        ),\n      );\n\n      this.appendCheckedInOutFunctionCall(copiedPropertiesCount, `tsn_copy_filtered_properties`, args, exceptionTarget);\n    } else {\n      this.appendCheckedInOutFunctionCall(copiedPropertiesCount, `tsn_copy_properties`, args, exceptionTarget);\n    }\n  }\n\n  emitGetProperty(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    thisObject: NativeCompilerBuilderVariableID,\n    propCacheSlot: number,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ) {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_get_property`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        '&' + this.getVariableName(object),\n        this.resolveAtomString(property),\n        '&' + this.getVariableName(thisObject),\n        this.options.inlinePropertyCache ? `module->prop_cache + ${propCacheSlot}` : '0',\n      ],\n      exceptionTarget,\n    );\n  }\n  emitGetPropertyFree(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    thisObject: NativeCompilerBuilderVariableID,\n    propCacheSlot: number,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ) {\n    this.appendCheckedFunctionCall(\n      `tsn_get_property_free`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        '&' + this.getVariableName(variable),\n        '&' + this.getVariableName(object),\n        this.resolveAtomString(property),\n        '&' + this.getVariableName(thisObject),\n        this.options.inlinePropertyCache ? `module->prop_cache + ${propCacheSlot}` : '0',\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitGetPropertyValue(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    thisObject: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ) {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_get_property_value`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(object),\n        this.getVariableName(property),\n        this.getVariableName(thisObject),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitDeleteProperty(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_delete_property`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(object),\n        this.resolveAtomString(property),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitDeletePropertyValue(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_delete_property_value`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(object),\n        this.getVariableName(property),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitGetFunctionArg(variable: NativeCompilerBuilderVariableID, index: number) {\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), 'tsn_get_func_arg', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Argc),\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Argv),\n      index.toString(),\n    ]);\n  }\n\n  emitGetFunctionArgumentsObject(\n    variable: NativeCompilerBuilderVariableID,\n    startIndex: number,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      'tsn_get_func_args_object',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Argc),\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Argv),\n        startIndex.toString(),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitGetSuper(\n    targetVariable: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      targetVariable,\n      'tsn_get_super',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.StackFrame),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitGetSuperConstructor(\n    targetVariable: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      targetVariable,\n      'tsn_get_super_constructor',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.StackFrame),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitGetClosureArg(variable: NativeCompilerBuilderVariableID, index: number): void {\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), 'tsn_get_closure_var', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Closure),\n      index.toString(),\n    ]);\n  }\n\n  emitGetModuleConst(variable: NativeCompilerBuilderVariableID, index: number): void {\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), 'tsn_get_module_const', [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      'module',\n      index.toString(),\n    ]);\n  }\n\n  emitLiteralInteger(variable: NativeCompilerBuilderVariableID, value: string) {\n    this.writeAssign(\n      variable,\n      `tsn_int32(${getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)}, ${value})`,\n    );\n  }\n\n  emitLiteralLong(variable: NativeCompilerBuilderVariableID, value: string): void {\n    this.writeAssign(\n      variable,\n      `tsn_int64(${getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)}, ${value})`,\n    );\n  }\n\n  emitLiteralDouble(variable: NativeCompilerBuilderVariableID, value: string) {\n    value = value.toUpperCase();\n\n    this.writeAssign(\n      variable,\n      `tsn_double(${getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)}, ${value})`,\n    );\n  }\n\n  emitLiteralString(\n    variable: NativeCompilerBuilderVariableID,\n    value: string,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ) {\n    const cString = toCString(value);\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_new_string_with_len`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        cString.literalContent,\n        cString.length.toString(),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitLiteralBool(variable: NativeCompilerBuilderVariableID, value: boolean): void {\n    this.writeAssign(\n      variable,\n      `tsn_new_bool(${getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)}, ${\n        value ? 'true' : 'false'\n      })`,\n    );\n  }\n\n  emitUnaryOp(\n    operator: NativeCompilerIR.UnaryOperator,\n    variable: NativeCompilerBuilderVariableID,\n    operand: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    switch (operator) {\n      case NativeCompilerIR.UnaryOperator.Neg:\n        this.generateMonoOperandOp(variable, operand, `tsn_op_neg`, exceptionTarget);\n        break;\n      case NativeCompilerIR.UnaryOperator.Plus:\n        this.generateMonoOperandOp(variable, operand, `tsn_op_plus`, exceptionTarget);\n        break;\n      case NativeCompilerIR.UnaryOperator.Inc:\n        this.generateMonoOperandOp(variable, operand, `tsn_op_inc`, exceptionTarget);\n        break;\n      case NativeCompilerIR.UnaryOperator.Dec:\n        this.generateMonoOperandOp(variable, operand, `tsn_op_dec`, exceptionTarget);\n        break;\n      case NativeCompilerIR.UnaryOperator.BitwiseNot:\n        this.generateMonoOperandOp(variable, operand, `tsn_op_bnot`, exceptionTarget);\n        break;\n      case NativeCompilerIR.UnaryOperator.LogicalNot:\n        this.generateMonoOperandOp(variable, operand, `tsn_op_lnot`, exceptionTarget);\n        break;\n      case NativeCompilerIR.UnaryOperator.TypeOf:\n        this.generateMonoOperandOp(variable, operand, `tsn_op_typeof`, exceptionTarget);\n        break;\n      default:\n        throw new Error(`Unsupported operator ${operator}`);\n    }\n  }\n\n  emitBinaryOp(\n    variable: NativeCompilerBuilderVariableID,\n    operator: NativeCompilerIR.BinaryOperator,\n    left: NativeCompilerBuilderVariableID,\n    right: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    switch (operator) {\n      case NativeCompilerIR.BinaryOperator.Mult:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_mult`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.Add:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_add`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.Sub:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_sub`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.Div:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_div`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.LeftShift:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_ls`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.RightShift:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_rs`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.UnsignedRightShift:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_urs`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.BitwiseOR:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_bor`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.BitwiseXOR:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_bxor`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.BitwiseAND:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_band`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.LessThan:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_lt`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.LessThanOrEqual:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_lte`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.LessThanOrEqualEqual:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_lte_strict`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.GreaterThan:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_gt`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.GreaterThanOrEqual:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_gte`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.GreaterThanOrEqualEqual:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_gte_strict`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.EqualEqual:\n        if (this.options.optimizeNullChecks) {\n          if (\n            right.type === NativeCompilerBuilderVariableType.Undefined ||\n            right.type === NativeCompilerBuilderVariableType.Null\n          ) {\n            return this.generateUndefOrNullCheck(variable, left, `tsn_is_undefined_or_null`);\n          } else if (\n            left.type === NativeCompilerBuilderVariableType.Undefined ||\n            left.type === NativeCompilerBuilderVariableType.Null\n          ) {\n            return this.generateUndefOrNullCheck(variable, right, `tsn_is_undefined_or_null`);\n          }\n        }\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_eq`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.EqualEqualEqual:\n        if (this.options.optimizeNullChecks) {\n          if (right.type === NativeCompilerBuilderVariableType.Undefined) {\n            return this.generateUndefOrNullCheck(variable, left, `tsn_is_undefined`);\n          } else if (left.type === NativeCompilerBuilderVariableType.Undefined) {\n            return this.generateUndefOrNullCheck(variable, right, `tsn_is_undefined`);\n          } else if (right.type === NativeCompilerBuilderVariableType.Null) {\n            return this.generateUndefOrNullCheck(variable, left, `tsn_is_null`);\n          } else if (left.type === NativeCompilerBuilderVariableType.Null) {\n            return this.generateUndefOrNullCheck(variable, right, `tsn_is_null`);\n          }\n        }\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_eq_strict`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.DifferentThan:\n        if (this.options.optimizeNullChecks) {\n          if (\n            right.type === NativeCompilerBuilderVariableType.Undefined ||\n            right.type === NativeCompilerBuilderVariableType.Null\n          ) {\n            return this.generateUndefOrNullCheck(variable, left, `tsn_not_undefined_or_null`);\n          } else if (\n            left.type === NativeCompilerBuilderVariableType.Undefined ||\n            left.type === NativeCompilerBuilderVariableType.Null\n          ) {\n            return this.generateUndefOrNullCheck(variable, right, `tsn_not_undefined_or_null`);\n          }\n        }\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_ne`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.DifferentThanStrict:\n        if (this.options.optimizeNullChecks) {\n          if (right.type === NativeCompilerBuilderVariableType.Undefined) {\n            return this.generateUndefOrNullCheck(variable, left, `tsn_not_undefined`);\n          } else if (left.type === NativeCompilerBuilderVariableType.Undefined) {\n            return this.generateUndefOrNullCheck(variable, right, `tsn_not_undefined`);\n          } else if (right.type === NativeCompilerBuilderVariableType.Null) {\n            return this.generateUndefOrNullCheck(variable, left, `tsn_not_null`);\n          } else if (left.type === NativeCompilerBuilderVariableType.Null) {\n            return this.generateUndefOrNullCheck(variable, right, `tsn_not_null`);\n          }\n        }\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_ne_strict`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.Modulo:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_mod`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.Exponentiation:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_exp`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.InstanceOf:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_instanceof`, exceptionTarget);\n        return;\n      case NativeCompilerIR.BinaryOperator.In:\n        this.generateTwoOperandOp(variable, left, right, `tsn_op_in`, exceptionTarget);\n        return;\n    }\n    throw new Error(`Unhandled binary operator type ${operator}`);\n  }\n\n  emitNewObject(variable: NativeCompilerBuilderVariableID, exceptionTarget: NativeCompilerBuilderJumpTargetID) {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_new_object`,\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)],\n      exceptionTarget,\n    );\n  }\n\n  emitNewArray(variable: NativeCompilerBuilderVariableID, exceptionTarget: NativeCompilerBuilderJumpTargetID): void {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_new_array`,\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)],\n      exceptionTarget,\n    );\n  }\n\n  emitNewArrowFunctionValue(\n    variable: NativeCompilerBuilderVariableID,\n    functionName: string,\n    argc: number,\n    closureVariables: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n    stackOnHeap: boolean,\n  ): void {\n    const stackOnHeapSize = stackOnHeap\n      ? [\n          `${functionName}_stack_vars_vrefs`,\n          `${functionName}_stack_vars_values`,\n          `${functionName}_stack_vars_iterators`,\n        ]\n      : ['0', '0', '0'];\n    if (!closureVariables.length) {\n      this.appendCheckedInOutFunctionCall(\n        variable,\n        `tsn_new_arrow_function`,\n        [\n          getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n          'module',\n          `&${functionName}`,\n          `${argc}`,\n          ...stackOnHeapSize,\n        ],\n        exceptionTarget,\n      );\n    } else {\n      this.appendCheckedInOutFunctionCall(\n        variable,\n        `tsn_new_arrow_function_closure`,\n        [\n          getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n          'module',\n          `&${functionName}`,\n          `${argc}`,\n          ...generateVariadicCallArguments(\n            VariadicCallArgumentType.VarRef,\n            closureVariables.map(this.getVariableName, this),\n          ),\n          ...stackOnHeapSize,\n        ],\n        exceptionTarget,\n      );\n    }\n  }\n\n  emitNewFunctionValue(\n    variable: NativeCompilerBuilderVariableID,\n    functionName: string,\n    constructorName: NativeCompilerBuilderAtomID,\n    argc: number,\n    closureVariables: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    let tsnFunctionName = 'tsn_new_function';\n    const trailingArguments: string[] = [];\n\n    if (closureVariables.length) {\n      tsnFunctionName += '_closure';\n      trailingArguments.push(\n        ...generateVariadicCallArguments(\n          VariadicCallArgumentType.VarRef,\n          closureVariables.map(this.getVariableName, this),\n        ),\n      );\n    }\n\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      tsnFunctionName,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        'module',\n        this.resolveAtomString(constructorName),\n        `&${functionName}`,\n        `${argc}`,\n      ].concat(...trailingArguments),\n      exceptionTarget,\n    );\n  }\n\n  emitNewClassValue(\n    variable: NativeCompilerBuilderVariableID,\n    functionName: string,\n    constructorName: NativeCompilerBuilderAtomID,\n    argc: number,\n    parentClass: NativeCompilerBuilderVariableID,\n    closureVariables: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    let tsnFunctionName: string;\n    const trailingArguments: string[] = [];\n\n    tsnFunctionName = 'tsn_new_class';\n    trailingArguments.push(this.getVariableName(parentClass));\n\n    if (closureVariables.length) {\n      tsnFunctionName += '_closure';\n      trailingArguments.push(\n        ...generateVariadicCallArguments(\n          VariadicCallArgumentType.VarRef,\n          closureVariables.map(this.getVariableName, this),\n        ),\n      );\n    }\n\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      tsnFunctionName,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        'module',\n        this.resolveAtomString(constructorName),\n        `&${functionName}`,\n        `${argc}`,\n      ].concat(...trailingArguments),\n      exceptionTarget,\n    );\n  }\n\n  emitSetClassMethod(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderAtomID,\n    method: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedFunctionCall(\n      isStatic ? 'tsn_set_class_static_method' : 'tsn_set_class_method',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(variable),\n        this.resolveAtomString(name),\n        this.getVariableName(method),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitSetClassMethodValue(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderVariableID,\n    method: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedFunctionCall(\n      isStatic ? 'tsn_set_class_static_method_value' : 'tsn_set_class_method_value',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(variable),\n        this.getVariableName(name),\n        this.getVariableName(method),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitSetClassPropertyGetter(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderAtomID,\n    getter: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedFunctionCall(\n      isStatic ? 'tsn_set_class_static_property_getter' : 'tsn_set_class_property_getter',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(variable),\n        this.resolveAtomString(name),\n        this.getVariableName(getter),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitSetClassPropertyGetterValue(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderVariableID,\n    getter: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedFunctionCall(\n      isStatic ? 'tsn_set_class_static_property_getter_value' : 'tsn_set_class_property_getter_value',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(variable),\n        this.getVariableName(name),\n        this.getVariableName(getter),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitSetClassPropertySetter(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderAtomID,\n    setter: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedFunctionCall(\n      isStatic ? 'tsn_set_class_static_property_setter' : 'tsn_set_class_property_setter',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(variable),\n        this.resolveAtomString(name),\n        this.getVariableName(setter),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitSetClassPropertySetterValue(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderVariableID,\n    setter: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedFunctionCall(\n      isStatic ? 'tsn_set_class_static_property_getter_value' : 'tsn_set_class_property_getter_value',\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(variable),\n        this.getVariableName(name),\n        this.getVariableName(setter),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitNewVariableRef(value: NativeCompilerBuilderVariableID, exceptionTarget: NativeCompilerBuilderJumpTargetID): void {\n    this.appendCheckedInOutFunctionCall(\n      value,\n      `tsn_new_var_ref`,\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context)],\n      exceptionTarget,\n    );\n  }\n\n  emitLoadVariableRef(\n    variable: NativeCompilerBuilderVariableID,\n    variableRefId: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_load_var_ref`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(variableRefId),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitSetVariableRef(value: NativeCompilerBuilderVariableID, variableRefId: NativeCompilerBuilderVariableID): void {\n    this.writer.appendFunctionCall(`tsn_set_var_ref`, [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      this.getVariableName(variableRefId),\n      this.getVariableName(value),\n    ]);\n  }\n\n  emitIterator(\n    value: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      output,\n      `tsn_new_iterator`,\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context), this.getVariableName(value)],\n      exceptionTarget,\n    );\n  }\n\n  emitKeysIterator(\n    value: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      output,\n      `tsn_new_keys_iterator`,\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context), this.getVariableName(value)],\n      exceptionTarget,\n    );\n  }\n\n  emitIteratorNext(\n    iterator: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      output,\n      `tsn_iterator_next`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        '&' + this.getVariableName(iterator),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitKeysIteratorNext(\n    iterator: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      output,\n      `tsn_keys_iterator_next`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        '&' + this.getVariableName(iterator),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitGenerator(\n    arg: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      output,\n      `tsn_new_generator`,\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context), this.getVariableName(arg)],\n      exceptionTarget,\n    );\n  }\n\n  private retainFunctionName() {\n    return this.options.noinlineRetainRelease ? 'tsn_retain' : 'tsn_retain_inline';\n  }\n  private releaseFunctionName() {\n    return this.options.noinlineRetainRelease ? 'tsn_release' : 'tsn_release_inline';\n  }\n\n  emitResume(variable: NativeCompilerBuilderVariableID, exceptionTarget: NativeCompilerBuilderJumpTargetID): void {\n    const ctx = getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context);\n    this.appendCheckedInOutFunctionCall(variable, 'tsn_resume', [ctx, 'closure', 'argc', 'argv'], exceptionTarget);\n  }\n\n  emitReentry(resumePoints: NativeCompilerBuilderJumpTargetID[]): void {\n    if (resumePoints.length > 0) {\n      this.writer.appendWithNewLine('switch(closure->resume_point) {');\n      const functionContext = this.functionContext;\n      for (const rp of resumePoints) {\n        this.writer.appendWithNewLine(`case ${rp.label}: goto ${getJumpTargetName(functionContext.name, rp)};`);\n      }\n      this.writer.appendWithNewLine('}');\n    }\n  }\n\n  emitSetResumePoint(resumePoint: NativeCompilerBuilderJumpTargetID): void {\n    this.writer.appendWithNewLine(`closure->resume_point = ${resumePoint.label};`);\n  }\n\n  emitRetain(value: NativeCompilerBuilderVariableID) {\n    // retain always follows assignment\n    // we emit a combined retain and assignment call in emitAssignment\n  }\n\n  private doEmitRetain(variable: NativeCompilerBuilderVariableID, value: NativeCompilerBuilderVariableID) {\n    let functionName: string;\n    let byPointer = false;\n    switch (value.type) {\n      case NativeCompilerBuilderVariableType.VariableRef:\n        functionName = 'tsn_retain_var_ref';\n        break;\n      case NativeCompilerBuilderVariableType.Iterator:\n        functionName = 'tsn_retain_iterator';\n        byPointer = true;\n        break;\n      default:\n        functionName = this.retainFunctionName();\n        break;\n    }\n    const args = [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      byPointer ? '&' + this.getVariableName(value) : this.getVariableName(value),\n    ];\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), functionName, args);\n  }\n\n  emitFree(value: NativeCompilerBuilderVariableID) {\n    let functionName: string;\n    let byPointer = false;\n    switch (value.type) {\n      case NativeCompilerBuilderVariableType.VariableRef:\n        functionName = 'tsn_release_var_ref';\n        break;\n      case NativeCompilerBuilderVariableType.Iterator:\n        functionName = 'tsn_release_iterator';\n        byPointer = true;\n        break;\n      default:\n        functionName = this.releaseFunctionName();\n        break;\n    }\n    const variableName = this.getVariableName(value);\n    this.writer.appendFunctionCall(functionName, [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      byPointer ? '&' + variableName : variableName,\n    ]);\n  }\n\n  emitFreeV(values: NativeCompilerBuilderVariableID[]) {\n    const vars = values.filter(\n      (v) =>\n        v.type != NativeCompilerBuilderVariableType.VariableRef && v.type != NativeCompilerBuilderVariableType.Iterator,\n    );\n    const varRefs = values.filter((v) => v.type == NativeCompilerBuilderVariableType.VariableRef);\n    const iterators = values.filter((v) => v.type == NativeCompilerBuilderVariableType.Iterator);\n    const ctx = getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context);\n    if (vars.length > 0) {\n      this.writer.appendFunctionCall('tsn_release_vars', [\n        ctx,\n        vars.length.toString(),\n        `(tsn_value*[]){${vars.map((v) => '&' + this.getVariableName(v)).join(', ')}}`,\n      ]);\n    }\n    if (varRefs.length > 0) {\n      this.writer.appendFunctionCall('tsn_release_var_refs', [\n        ctx,\n        varRefs.length.toString(),\n        `(tsn_var_ref[]){${varRefs.map((v) => this.getVariableName(v)).join(', ')}}`,\n      ]);\n    }\n    if (iterators.length > 0) {\n      this.writer.appendFunctionCall('tsn_release_iterators', [\n        ctx,\n        iterators.length.toString(),\n        `(tsn_iterator*[]){${iterators.map((v) => '&' + this.getVariableName(v)).join(', ')}}`,\n      ]);\n    }\n  }\n\n  emitIntrinsicCall(\n    variable: NativeCompilerBuilderVariableID,\n    func: string,\n    args: Array<NativeCompilerBuilderVariableID>,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    const functionContext = this.functionContext;\n    let argList;\n    if (func.endsWith('_v')) {\n      argList = [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        args.length.toString(),\n        `(tsn_value[]){${args.map((v) => this.getVariableName(v)).join(', ')}}`,\n      ];\n    } else {\n      argList = [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        ...args.map(this.getVariableName, this),\n      ];\n    }\n    this.writer.appendAssignmentWithFunctionCall(this.getVariableName(variable), func, argList);\n    this.writer.beginIfStatement();\n    this.writer.appendFunctionCall(\n      'tsn_is_exception',\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context), this.getVariableName(variable)],\n      false,\n    );\n    this.writer.endEndifStatement();\n    this.writer.beginScope();\n    this.writer.appendGoto(getJumpTargetName(functionContext.name, exceptionTarget));\n    this.writer.endScope();\n  }\n\n  emitFunctionInvocation(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    args: Array<NativeCompilerBuilderVariableID>,\n    obj: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ) {\n    let argList = [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      this.getVariableName(func),\n      this.getVariableName(obj),\n      ...generateVariadicCallArguments(VariadicCallArgumentType.Value, args.map(this.getVariableName, this)),\n    ];\n\n    this.appendCheckedInOutFunctionCall(variable, `tsn_call`, argList, exceptionTarget);\n  }\n\n  emitFunctionInvocationWithArgsArray(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID,\n    obj: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_call_vargs`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(func),\n        this.getVariableName(obj),\n        this.getVariableName(args),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitFunctionInvocationWithForwardedArgs(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    obj: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_call_fargs`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(func),\n        this.getVariableName(obj),\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Argc),\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Argv),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitConstructorInvocation(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    new_target: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    let argList = [\n      getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n      this.getVariableName(func),\n      this.getVariableName(new_target),\n      ...generateVariadicCallArguments(VariadicCallArgumentType.Value, args.map(this.getVariableName, this)),\n    ];\n\n    this.appendCheckedInOutFunctionCall(variable, `tsn_call_constructor`, argList, exceptionTarget);\n  }\n\n  emitConstructorInvocationWithArgsArray(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    new_target: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void {\n    this.appendCheckedInOutFunctionCall(\n      variable,\n      `tsn_call_constructor_vargs`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        this.getVariableName(func),\n        this.getVariableName(new_target),\n        this.getVariableName(args),\n      ],\n      exceptionTarget,\n    );\n  }\n\n  emitBindJumpTarget(target: NativeCompilerBuilderJumpTargetID) {\n    const functionContext = this.functionContext;\n    this.writer.appendLabel(getJumpTargetName(functionContext.name, target));\n  }\n\n  emitJump(target: NativeCompilerBuilderJumpTargetID) {\n    const functionContext = this.functionContext;\n    this.writer.appendGoto(getJumpTargetName(functionContext.name, target));\n  }\n\n  emitBranch(\n    conditionVariable: NativeCompilerBuilderVariableID,\n    type: NativeCompilerBuilderBranchType,\n    trueTarget: NativeCompilerBuilderJumpTargetID,\n    falseTarget: NativeCompilerBuilderJumpTargetID | undefined,\n  ) {\n    const functionContext = this.functionContext;\n\n    this.writer.beginIfStatement();\n    let functionCallName: string;\n    let byPointer = false;\n    if (conditionVariable.type === NativeCompilerBuilderVariableType.Iterator) {\n      functionCallName = 'tsn_iterator_has_value';\n      byPointer = true;\n    } else {\n      switch (type) {\n        case NativeCompilerBuilderBranchType.Truthy:\n          if (conditionVariable.type == NativeCompilerBuilderVariableType.Bool) {\n            functionCallName = 'tsn_truthy_bool';\n          } else {\n            functionCallName = 'tsn_to_bool';\n          }\n          break;\n        case NativeCompilerBuilderBranchType.NotUndefinedOrNull:\n          functionCallName = 'tsn_not_undefined_or_null';\n          break;\n      }\n    }\n\n    this.writer.appendFunctionCall(\n      functionCallName,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context),\n        byPointer ? '&' + this.getVariableName(conditionVariable) : this.getVariableName(conditionVariable),\n      ],\n      false,\n    );\n    this.writer.endEndifStatement();\n    this.writer.beginScope();\n    this.writer.appendGoto(getJumpTargetName(functionContext.name, trueTarget));\n    this.writer.endScope();\n\n    if (falseTarget !== undefined) {\n      this.writer.append(`else`);\n      this.writer.beginScope();\n      this.writer.appendGoto(getJumpTargetName(functionContext.name, falseTarget));\n      this.writer.endScope();\n    }\n  }\n\n  private writeAssign(target: NativeCompilerBuilderVariableID, inputArgument: string): void {\n    this.writer.appendAssignment(this.getVariableName(target), inputArgument);\n  }\n\n  emitAssignment(left: NativeCompilerBuilderVariableID, right: NativeCompilerBuilderVariableID) {\n    if (right.isRetainable()) {\n      this.doEmitRetain(left, right);\n    } else {\n      this.writeAssign(left, this.getVariableName(right));\n    }\n  }\n\n  emitThrow(value: NativeCompilerBuilderVariableID, target: NativeCompilerBuilderJumpTargetID): void {\n    const functionContext = this.functionContext;\n    this.writer.appendFunctionCall(\n      `tsn_throw`,\n      [getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.Context), this.getVariableName(value)],\n      false,\n    );\n    this.writer.appendWithNewLine(';');\n    this.writer.appendGoto(getJumpTargetName(functionContext.name, target));\n  }\n\n  emitComments(text: string): void {\n    // Escape comment string\n    const resolvedText = escapeCComment(text.trim());\n    this.writer.beginComment();\n    this.writer.appendWithNewLine(resolvedText);\n    this.writer.endComment();\n  }\n\n  emitProgramCounterInfo(lineNumber: number, columnNumber: number): void {\n    this.writer.appendFunctionCall(\n      `tsn_set_pc`,\n      [\n        getNativeCompilerFunctionArgToString(NativeCompilerIR.FunctionTypeArgs.StackFrame),\n        lineNumber.toString(),\n        columnNumber.toString(),\n      ],\n      true,\n    );\n  }\n\n  finalize(): NativeCompilerEmitterOutput {\n    this.writer.append('\\n__attribute__((constructor)) static void __do_register_module()');\n    this.writer.beginScope();\n    for (const [modulePath, functionName] of this.pendingRegisterCalls) {\n      this.writer.appendFunctionCall(`tsn_register_module`, [toCString(modulePath).literalContent, functionName]);\n    }\n    this.writer.endScope();\n    this.writer.append('\\n');\n\n    const source = this.writer.content();\n    return { source: source };\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/emitter/INativeCompilerEmitter.ts",
    "content": "import {\n  NativeCompilerBuilderVariableID,\n  NativeCompilerBuilderJumpTargetID,\n  NativeCompilerBuilderAtomID,\n  NativeCompilerBuilderBranchType,\n} from '../builder/INativeCompilerBuilder';\nimport { NativeCompilerIR } from '../builder/NativeCompilerBuilderIR';\n\nexport interface INativeCompilerIREmitter {\n  emitBoilerplatePrologue(atoms: NativeCompilerBuilderAtomID[]): void;\n  emitBoilerplateEpilogue(\n    moduleName: string,\n    modulePath: string,\n    moduleInitFunctionName: string,\n    atoms: readonly NativeCompilerBuilderAtomID[],\n    stringConstants: readonly string[],\n    propCacheSlots: number,\n  ): void;\n\n  emitStartFunction(\n    name: string,\n    type: NativeCompilerIR.FunctionType,\n    exceptionJumpTarget: NativeCompilerBuilderJumpTargetID,\n    returnJumpTarget: NativeCompilerBuilderJumpTargetID,\n    returnVariable: NativeCompilerBuilderVariableID,\n    localVars: NativeCompilerBuilderVariableID[],\n  ): void;\n\n  emitEndFunction(returnVariable: NativeCompilerBuilderVariableID): void;\n\n  emitSlot(value: NativeCompilerBuilderVariableID): void;\n\n  emitGlobal(variable: NativeCompilerBuilderVariableID): void;\n\n  emitUndefined(variable: NativeCompilerBuilderVariableID): void;\n\n  emitNull(variable: NativeCompilerBuilderVariableID): void;\n\n  emitThis(variable: NativeCompilerBuilderVariableID): void;\n\n  emitNewTarget(variable: NativeCompilerBuilderVariableID): void;\n\n  emitException(variable: NativeCompilerBuilderVariableID): void;\n\n  emitGetException(variable: NativeCompilerBuilderVariableID): void;\n\n  emitCheckException(exceptionTarget: NativeCompilerBuilderJumpTargetID): void;\n\n  emitSetProperty(\n    object: NativeCompilerBuilderVariableID,\n    properties: NativeCompilerBuilderAtomID[],\n    valuees: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitSetPropertyValue(\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    value: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitSetPropertyIndex(\n    object: NativeCompilerBuilderVariableID,\n    index: number,\n    value: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitCopyPropertiesFrom(\n    object: NativeCompilerBuilderVariableID,\n    value: NativeCompilerBuilderVariableID,\n    propertiesToIgnore: NativeCompilerBuilderAtomID[] | undefined,\n    copiedPropertiesCount: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitGetProperty(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    thisObject: NativeCompilerBuilderVariableID,\n    propCacheSlot: number,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n  emitGetPropertyFree(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    thisObject: NativeCompilerBuilderVariableID,\n    propCacheSlot: number,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitGetPropertyValue(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    thisObject: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitDeleteProperty(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderAtomID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitDeletePropertyValue(\n    variable: NativeCompilerBuilderVariableID,\n    object: NativeCompilerBuilderVariableID,\n    property: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitGetFunctionArg(variable: NativeCompilerBuilderVariableID, index: number): void;\n\n  emitGetFunctionArgumentsObject(\n    variable: NativeCompilerBuilderVariableID,\n    startIndex: number,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitGetSuper(\n    targetVariable: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n  emitGetSuperConstructor(\n    targetVariable: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitGetClosureArg(variable: NativeCompilerBuilderVariableID, index: number): void;\n\n  emitGetModuleConst(variable: NativeCompilerBuilderVariableID, index: number): void;\n\n  emitLiteralInteger(variable: NativeCompilerBuilderVariableID, value: string): void;\n\n  emitLiteralLong(variable: NativeCompilerBuilderVariableID, value: string): void;\n\n  emitLiteralDouble(variable: NativeCompilerBuilderVariableID, value: string): void;\n\n  emitLiteralString(\n    variable: NativeCompilerBuilderVariableID,\n    value: string,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitLiteralBool(variable: NativeCompilerBuilderVariableID, value: boolean): void;\n\n  emitUnaryOp(\n    operator: NativeCompilerIR.UnaryOperator,\n    variable: NativeCompilerBuilderVariableID,\n    operand: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitBinaryOp(\n    variable: NativeCompilerBuilderVariableID,\n    operator: NativeCompilerIR.BinaryOperator,\n    left: NativeCompilerBuilderVariableID,\n    right: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitNewObject(variable: NativeCompilerBuilderVariableID, exceptionTarget: NativeCompilerBuilderJumpTargetID): void;\n\n  emitNewArray(variable: NativeCompilerBuilderVariableID, exceptionTarget: NativeCompilerBuilderJumpTargetID): void;\n\n  emitNewArrowFunctionValue(\n    variable: NativeCompilerBuilderVariableID,\n    functionName: string,\n    argc: number,\n    closureVariables: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n    stackOnHeap: boolean,\n  ): void;\n\n  emitNewFunctionValue(\n    variable: NativeCompilerBuilderVariableID,\n    functionName: string,\n    name: NativeCompilerBuilderAtomID | undefined,\n    argc: number,\n    closureVariables: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitNewClassValue(\n    variable: NativeCompilerBuilderVariableID,\n    functionName: string,\n    constructorName: NativeCompilerBuilderAtomID | undefined,\n    argc: number,\n    parentClass: NativeCompilerBuilderVariableID,\n    closureVariables: NativeCompilerBuilderVariableID[],\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitSetClassMethod(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderAtomID,\n    method: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitSetClassMethodValue(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderVariableID,\n    method: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitSetClassPropertyGetter(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderAtomID,\n    getter: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitSetClassPropertyGetterValue(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderVariableID,\n    getter: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitSetClassPropertySetter(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderAtomID,\n    setter: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitSetClassPropertySetterValue(\n    variable: NativeCompilerBuilderVariableID,\n    name: NativeCompilerBuilderVariableID,\n    setter: NativeCompilerBuilderVariableID,\n    isStatic: boolean,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitRetain(value: NativeCompilerBuilderVariableID): void;\n\n  emitFree(value: NativeCompilerBuilderVariableID): void;\n  emitFreeV(values: NativeCompilerBuilderVariableID[]): void;\n\n  emitIntrinsicCall(\n    variable: NativeCompilerBuilderVariableID,\n    func: string,\n    args: Array<NativeCompilerBuilderVariableID>,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitFunctionInvocation(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    args: Array<NativeCompilerBuilderVariableID>,\n    obj: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitFunctionInvocationWithArgsArray(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID,\n    obj: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitFunctionInvocationWithForwardedArgs(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    obj: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitConstructorInvocation(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    new_target: NativeCompilerBuilderVariableID,\n    args: Array<NativeCompilerBuilderVariableID>,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitConstructorInvocationWithArgsArray(\n    variable: NativeCompilerBuilderVariableID,\n    func: NativeCompilerBuilderVariableID,\n    new_target: NativeCompilerBuilderVariableID,\n    args: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitBindJumpTarget(target: NativeCompilerBuilderJumpTargetID): void;\n\n  emitJump(target: NativeCompilerBuilderJumpTargetID): void;\n\n  emitBranch(\n    conditionVariable: NativeCompilerBuilderVariableID,\n    branchType: NativeCompilerBuilderBranchType,\n    trueTarget: NativeCompilerBuilderJumpTargetID,\n    falseTarget: NativeCompilerBuilderJumpTargetID | undefined,\n  ): void;\n\n  emitAssignment(left: NativeCompilerBuilderVariableID, right: NativeCompilerBuilderVariableID): void;\n\n  emitThrow(value: NativeCompilerBuilderVariableID, target: NativeCompilerBuilderJumpTargetID): void;\n\n  emitComments(text: string): void;\n\n  emitProgramCounterInfo(lineNumber: number, columnNumber: number): void;\n\n  emitNewVariableRef(value: NativeCompilerBuilderVariableID, exceptionTarget: NativeCompilerBuilderJumpTargetID): void;\n  emitLoadVariableRef(\n    variable: NativeCompilerBuilderVariableID,\n    variableRefId: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n  emitSetVariableRef(value: NativeCompilerBuilderVariableID, variableRefId: NativeCompilerBuilderVariableID): void;\n\n  emitIterator(\n    value: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n  emitKeysIterator(\n    value: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n  emitIteratorNext(\n    iterator: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n  emitKeysIteratorNext(\n    iterator: NativeCompilerBuilderVariableID,\n    output: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n\n  emitGenerator(\n    arg: NativeCompilerBuilderVariableID,\n    variable: NativeCompilerBuilderVariableID,\n    exceptionTarget: NativeCompilerBuilderJumpTargetID,\n  ): void;\n  emitResume(variable: NativeCompilerBuilderVariableID, exceptionTarget: NativeCompilerBuilderJumpTargetID): void;\n  emitReentry(resumePoints: NativeCompilerBuilderJumpTargetID[]): void;\n  emitSetResumePoint(resumePoint: NativeCompilerBuilderJumpTargetID): void;\n\n  finalize(): NativeCompilerEmitterOutput;\n}\n\nexport interface NativeCompilerEmitterOutput {\n  source: string;\n}\n\nexport function emitterWalk(emitter: INativeCompilerIREmitter, ir: Array<NativeCompilerIR.Base>): void {\n  ir.forEach((ir_) => {\n    switch (ir_.kind) {\n      case NativeCompilerIR.Kind.BoilerplatePrologue: {\n        const ir = ir_ as NativeCompilerIR.BoilerplatePrologue;\n        emitter.emitBoilerplatePrologue(ir.atoms);\n        break;\n      }\n      case NativeCompilerIR.Kind.BoilerplateEpilogue: {\n        const ir = ir_ as NativeCompilerIR.BoilerplateEpilogue;\n        emitter.emitBoilerplateEpilogue(\n          ir.moduleName,\n          ir.modulePath,\n          ir.moduleInitFunctionName,\n          ir.atoms,\n          ir.stringConstants,\n          ir.propCacheSlots,\n        );\n        break;\n      }\n      case NativeCompilerIR.Kind.StartFunction: {\n        const ir = ir_ as NativeCompilerIR.StartFunction;\n        emitter.emitStartFunction(\n          ir.name,\n          ir.type,\n          ir.exceptionJumpTarget,\n          ir.returnJumpTarget,\n          ir.returnVariable,\n          ir.localVars,\n        );\n        break;\n      }\n      case NativeCompilerIR.Kind.EndFunction: {\n        const ir = ir_ as NativeCompilerIR.EndFunction;\n        emitter.emitEndFunction(ir.returnVariable);\n        break;\n      }\n      case NativeCompilerIR.Kind.Slot: {\n        const ir = ir_ as NativeCompilerIR.Slot;\n        emitter.emitSlot(ir.value);\n        break;\n      }\n      case NativeCompilerIR.Kind.Global: {\n        const ir = ir_ as NativeCompilerIR.Global;\n        emitter.emitGlobal(ir.variable);\n        break;\n      }\n      case NativeCompilerIR.Kind.Keyword: {\n        const ir = ir_ as NativeCompilerIR.Keyword;\n        switch (ir.keyword) {\n          case NativeCompilerIR.KeywordKind.Undefined:\n            emitter.emitUndefined(ir.variable);\n            break;\n          case NativeCompilerIR.KeywordKind.Null:\n            emitter.emitNull(ir.variable);\n            break;\n          case NativeCompilerIR.KeywordKind.This:\n            emitter.emitThis(ir.variable);\n            break;\n          case NativeCompilerIR.KeywordKind.NewTarget:\n            emitter.emitNewTarget(ir.variable);\n            break;\n        }\n        break;\n      }\n      case NativeCompilerIR.Kind.Exception: {\n        const ir = ir_ as NativeCompilerIR.Exception;\n        emitter.emitException(ir.variable);\n        break;\n      }\n      case NativeCompilerIR.Kind.SetProperty: {\n        const ir = ir_ as NativeCompilerIR.SetProperty;\n        emitter.emitSetProperty(ir.object, ir.properties, ir.values, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.SetPropertyValue: {\n        const ir = ir_ as NativeCompilerIR.SetPropertyValue;\n        emitter.emitSetPropertyValue(ir.object, ir.property, ir.value, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.SetPropertyIndex: {\n        const ir = ir_ as NativeCompilerIR.SetPropertyIndex;\n        emitter.emitSetPropertyIndex(ir.object, ir.index, ir.value, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.CopyPropertiesFrom: {\n        const ir = ir_ as NativeCompilerIR.CopyPropertiesFrom;\n        emitter.emitCopyPropertiesFrom(\n          ir.object,\n          ir.value,\n          ir.propertiesToIgnore,\n          ir.copiedPropertiesCount,\n          ir.exceptionTarget,\n        );\n        break;\n      }\n      case NativeCompilerIR.Kind.GetProperty: {\n        const ir = ir_ as NativeCompilerIR.GetProperty;\n        emitter.emitGetProperty(\n          ir.variable,\n          ir.object,\n          ir.property,\n          ir.thisObject,\n          ir.propCacheSlot,\n          ir.exceptionTarget,\n        );\n        break;\n      }\n      case NativeCompilerIR.Kind.GetPropertyFree: {\n        const ir = ir_ as NativeCompilerIR.GetPropertyFree;\n        emitter.emitGetPropertyFree(\n          ir.variable,\n          ir.object,\n          ir.property,\n          ir.thisObject,\n          ir.propCacheSlot,\n          ir.exceptionTarget,\n        );\n        break;\n      }\n      case NativeCompilerIR.Kind.GetPropertyValue: {\n        const ir = ir_ as NativeCompilerIR.GetPropertyValue;\n        emitter.emitGetPropertyValue(ir.variable, ir.object, ir.property, ir.thisObject, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.DeleteProperty: {\n        const ir = ir_ as NativeCompilerIR.DeleteProperty;\n        emitter.emitDeleteProperty(ir.variable, ir.object, ir.property, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.DeletePropertyValue: {\n        const ir = ir_ as NativeCompilerIR.DeletePropertyValue;\n        emitter.emitDeletePropertyValue(ir.variable, ir.object, ir.property, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.GetFunctionArg: {\n        const ir = ir_ as NativeCompilerIR.GetFunctionArg;\n        emitter.emitGetFunctionArg(ir.variable, ir.index);\n        break;\n      }\n      case NativeCompilerIR.Kind.GetFunctionArgumentsObject: {\n        const ir = ir_ as NativeCompilerIR.GetFunctionArgumentsObject;\n        emitter.emitGetFunctionArgumentsObject(ir.variable, ir.startIndex, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.GetSuper: {\n        const ir = ir_ as NativeCompilerIR.GetSuper;\n        emitter.emitGetSuper(ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.GetSuperConstructor: {\n        const ir = ir_ as NativeCompilerIR.GetSuperConstructor;\n        emitter.emitGetSuperConstructor(ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.GetClosureArg: {\n        const ir = ir_ as NativeCompilerIR.GetClosureArg;\n        emitter.emitGetClosureArg(ir.variable, ir.index);\n        break;\n      }\n      case NativeCompilerIR.Kind.GetModuleConst: {\n        const ir = ir_ as NativeCompilerIR.GetModuleConst;\n        emitter.emitGetModuleConst(ir.variable, ir.index);\n        break;\n      }\n      case NativeCompilerIR.Kind.LiteralInteger: {\n        const ir = ir_ as NativeCompilerIR.LiteralInteger;\n        emitter.emitLiteralInteger(ir.variable, ir.value);\n        break;\n      }\n      case NativeCompilerIR.Kind.LiteralLong: {\n        const ir = ir_ as NativeCompilerIR.LiteralInteger;\n        emitter.emitLiteralLong(ir.variable, ir.value);\n        break;\n      }\n      case NativeCompilerIR.Kind.LiteralDouble: {\n        const ir = ir_ as NativeCompilerIR.LiteralDouble;\n        emitter.emitLiteralDouble(ir.variable, ir.value);\n        break;\n      }\n      case NativeCompilerIR.Kind.LiteralString: {\n        const ir = ir_ as NativeCompilerIR.LiteralString;\n        emitter.emitLiteralString(ir.variable, ir.value, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.LiteralBool: {\n        const ir = ir_ as NativeCompilerIR.LiteralBool;\n        emitter.emitLiteralBool(ir.variable, ir.value);\n        break;\n      }\n      case NativeCompilerIR.Kind.UnaryOp: {\n        const ir = ir_ as NativeCompilerIR.UnaryOp;\n        emitter.emitUnaryOp(ir.operator, ir.variable, ir.operand, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.BinaryOp: {\n        const ir = ir_ as NativeCompilerIR.BinaryOp;\n        emitter.emitBinaryOp(ir.variable, ir.operator, ir.left, ir.right, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.NewObject: {\n        const ir = ir_ as NativeCompilerIR.NewObject;\n        emitter.emitNewObject(ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.NewArray: {\n        const ir = ir_ as NativeCompilerIR.NewArray;\n        emitter.emitNewArray(ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.NewArrowFunctionValue: {\n        const ir = ir_ as NativeCompilerIR.NewArrowFunctionValue;\n        emitter.emitNewArrowFunctionValue(\n          ir.variable,\n          ir.functionName,\n          ir.argc,\n          ir.closureArgs,\n          ir.exceptionTarget,\n          ir.stackOnHeap,\n        );\n        break;\n      }\n      case NativeCompilerIR.Kind.NewFunctionValue: {\n        const ir = ir_ as NativeCompilerIR.NewFunctionValue;\n        emitter.emitNewFunctionValue(\n          ir.variable,\n          ir.functionName,\n          ir.name,\n          ir.argc,\n          ir.closureArgs,\n          ir.exceptionTarget,\n        );\n        break;\n      }\n      case NativeCompilerIR.Kind.NewClassValue: {\n        const ir = ir_ as NativeCompilerIR.NewClassValue;\n        emitter.emitNewClassValue(\n          ir.variable,\n          ir.functionName,\n          ir.name,\n          ir.argc,\n          ir.parentClass,\n          ir.closureArgs,\n          ir.exceptionTarget,\n        );\n        break;\n      }\n      case NativeCompilerIR.Kind.SetClassElement: {\n        const ir = ir_ as NativeCompilerIR.SetClassElement;\n        switch (ir.type) {\n          case NativeCompilerIR.ClassElementType.Method:\n            emitter.emitSetClassMethod(ir.cls, ir.name, ir.value, ir.static, ir.exceptionTarget);\n            break;\n          case NativeCompilerIR.ClassElementType.Getter:\n            emitter.emitSetClassPropertyGetter(ir.cls, ir.name, ir.value, ir.static, ir.exceptionTarget);\n            break;\n          case NativeCompilerIR.ClassElementType.Setter:\n            emitter.emitSetClassPropertySetter(ir.cls, ir.name, ir.value, ir.static, ir.exceptionTarget);\n            break;\n        }\n        break;\n      }\n      case NativeCompilerIR.Kind.SetClassElementValue: {\n        const ir = ir_ as NativeCompilerIR.SetClassElementValue;\n        switch (ir.type) {\n          case NativeCompilerIR.ClassElementType.Method:\n            emitter.emitSetClassMethodValue(ir.cls, ir.name, ir.value, ir.static, ir.exceptionTarget);\n            break;\n          case NativeCompilerIR.ClassElementType.Getter:\n            emitter.emitSetClassPropertyGetterValue(ir.cls, ir.name, ir.value, ir.static, ir.exceptionTarget);\n            break;\n          case NativeCompilerIR.ClassElementType.Setter:\n            emitter.emitSetClassPropertySetterValue(ir.cls, ir.name, ir.value, ir.static, ir.exceptionTarget);\n            break;\n        }\n        break;\n      }\n      case NativeCompilerIR.Kind.Retain: {\n        const ir = ir_ as NativeCompilerIR.Retain;\n        emitter.emitRetain(ir.value);\n        break;\n      }\n\n      case NativeCompilerIR.Kind.Free: {\n        const ir = ir_ as NativeCompilerIR.Free;\n        emitter.emitFree(ir.value);\n        break;\n      }\n      case NativeCompilerIR.Kind.FreeV: {\n        const ir = ir_ as NativeCompilerIR.FreeV;\n        emitter.emitFreeV(ir.values);\n        break;\n      }\n      case NativeCompilerIR.Kind.IntrinsicCall: {\n        const ir = ir_ as NativeCompilerIR.IntrinsicCall;\n        emitter.emitIntrinsicCall(ir.variable, ir.func, ir.args, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.FunctionInvocation: {\n        const ir = ir_ as NativeCompilerIR.FunctionInvocation;\n        switch (ir.argsType) {\n          case NativeCompilerIR.FunctionArgumentsType.Direct:\n            emitter.emitFunctionInvocation(ir.variable, ir.func, ir.args, ir.obj, ir.exceptionTarget);\n            break;\n          case NativeCompilerIR.FunctionArgumentsType.Indirect:\n            emitter.emitFunctionInvocationWithArgsArray(ir.variable, ir.func, ir.args[0], ir.obj, ir.exceptionTarget);\n            break;\n          case NativeCompilerIR.FunctionArgumentsType.ForwardFromCurrentCall:\n            emitter.emitFunctionInvocationWithForwardedArgs(ir.variable, ir.func, ir.obj, ir.exceptionTarget);\n            break;\n        }\n        break;\n      }\n      case NativeCompilerIR.Kind.ConstructorInvocation: {\n        const ir = ir_ as NativeCompilerIR.ConstructorInvocation;\n\n        switch (ir.argsType) {\n          case NativeCompilerIR.FunctionArgumentsType.Direct:\n            emitter.emitConstructorInvocation(ir.variable, ir.func, ir.new_target, ir.args, ir.exceptionTarget);\n            break;\n          case NativeCompilerIR.FunctionArgumentsType.Indirect:\n            emitter.emitConstructorInvocationWithArgsArray(\n              ir.variable,\n              ir.func,\n              ir.new_target,\n              ir.args[0],\n              ir.exceptionTarget,\n            );\n            break;\n          case NativeCompilerIR.FunctionArgumentsType.ForwardFromCurrentCall:\n            throw new Error('Unexpectedly got constructor invocation with forwarded args');\n        }\n        break;\n      }\n      case NativeCompilerIR.Kind.BindJumpTarget: {\n        const ir = ir_ as NativeCompilerIR.BindJumpTarget;\n        emitter.emitBindJumpTarget(ir.target);\n        break;\n      }\n      case NativeCompilerIR.Kind.Jump: {\n        const ir = ir_ as NativeCompilerIR.Jump;\n        emitter.emitJump(ir.target);\n        break;\n      }\n      case NativeCompilerIR.Kind.Branch: {\n        const ir = ir_ as NativeCompilerIR.Branch;\n        emitter.emitBranch(ir.conditionVariable, ir.type, ir.trueTarget, ir.falseTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.Assignment: {\n        const ir = ir_ as NativeCompilerIR.Assignment;\n        emitter.emitAssignment(ir.left, ir.right);\n        break;\n      }\n      case NativeCompilerIR.Kind.Throw: {\n        const ir = ir_ as NativeCompilerIR.Throw;\n        emitter.emitThrow(ir.value, ir.target);\n        break;\n      }\n      case NativeCompilerIR.Kind.GetException: {\n        const ir = ir_ as NativeCompilerIR.GetException;\n        emitter.emitGetException(ir.variable);\n        break;\n      }\n      case NativeCompilerIR.Kind.CheckException: {\n        const ir = ir_ as NativeCompilerIR.CheckException;\n        emitter.emitCheckException(ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.Comments: {\n        const ir = ir_ as NativeCompilerIR.Comments;\n        emitter.emitComments(ir.text);\n        break;\n      }\n      case NativeCompilerIR.Kind.ProgramCounterInfo: {\n        const ir = ir_ as NativeCompilerIR.ProgramCounterInfo;\n        emitter.emitProgramCounterInfo(ir.lineNumber, ir.columnNumber);\n        break;\n      }\n      case NativeCompilerIR.Kind.NewVariableRef: {\n        const ir = ir_ as NativeCompilerIR.NewVariableRef;\n        emitter.emitNewVariableRef(ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.LoadVariableRef: {\n        const ir = ir_ as NativeCompilerIR.LoadVariableRef;\n        emitter.emitLoadVariableRef(ir.variable, ir.target, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.SetVariableRef: {\n        const ir = ir_ as NativeCompilerIR.SetVariableRef;\n        emitter.emitSetVariableRef(ir.value, ir.target);\n        break;\n      }\n      case NativeCompilerIR.Kind.Iterator: {\n        const ir = ir_ as NativeCompilerIR.Iterator;\n        emitter.emitIterator(ir.arg, ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.KeysIterator: {\n        const ir = ir_ as NativeCompilerIR.KeysIterator;\n        emitter.emitKeysIterator(ir.arg, ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.IteratorNext: {\n        const ir = ir_ as NativeCompilerIR.IteratorNext;\n        emitter.emitIteratorNext(ir.iterator, ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.KeysIteratorNext: {\n        const ir = ir_ as NativeCompilerIR.KeysIteratorNext;\n        emitter.emitKeysIteratorNext(ir.iterator, ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.Generator: {\n        const ir = ir_ as NativeCompilerIR.Generator;\n        emitter.emitGenerator(ir.arg, ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.Resume: {\n        const ir = ir_ as NativeCompilerIR.Resume;\n        emitter.emitResume(ir.variable, ir.exceptionTarget);\n        break;\n      }\n      case NativeCompilerIR.Kind.Reentry: {\n        const ir = ir_ as NativeCompilerIR.Reentry;\n        emitter.emitReentry(ir.resumePoints);\n        break;\n      }\n      case NativeCompilerIR.Kind.SetResumePoint: {\n        const ir = ir_ as NativeCompilerIR.SetResumePoint;\n        emitter.emitSetResumePoint(ir.resumePoint);\n        break;\n      }\n      default:\n        throw new Error(`Not all IRs are supported: ${ir_.kind}`);\n    }\n  });\n}\n"
  },
  {
    "path": "compiler/companion/src/native/utils/AssignmentTracker.ts",
    "content": "import { NativeCompilerBuilderAtomID, NativeCompilerBuilderVariableID } from '../builder/INativeCompilerBuilder';\n\ninterface Assignment {\n  readonly object: NativeCompilerBuilderVariableID;\n  readonly property: NativeCompilerBuilderAtomID | NativeCompilerBuilderVariableID;\n}\n\nexport class AssignmentTracker {\n  get assignments(): readonly Assignment[] {\n    return this._assignemnts;\n  }\n\n  private _assignemnts: Assignment[] = [];\n\n  onGetProperty(object: NativeCompilerBuilderVariableID, property: NativeCompilerBuilderAtomID): void {\n    this._assignemnts.push({ object, property });\n  }\n\n  onGetPropertyValue(object: NativeCompilerBuilderVariableID, property: NativeCompilerBuilderVariableID): void {\n    this._assignemnts.push({ object, property });\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/utils/NameAllocator.ts",
    "content": "export class NameAllocator {\n  private allocatedNames = new Set<string>();\n\n  allocate(nameInitial: string): string {\n    let name = nameInitial;\n\n    let index = 0;\n    for (;;) {\n      if (!this.allocatedNames.has(name)) {\n        this.allocatedNames.add(name);\n        return name;\n      }\n\n      name = `${nameInitial}_${index}`;\n\n      index++;\n    }\n\n    return name;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/utils/NamePath.ts",
    "content": "import ts = require('typescript');\n\nexport class NamePath {\n  constructor(readonly name: string, readonly parent?: NamePath) {}\n\n  appending(name: string): NamePath {\n    return new NamePath(name, this);\n  }\n\n  appendingTSNode(node: ts.Node | undefined, prefix?: string | undefined): NamePath {\n    if (!node || !ts.isIdentifier(node)) {\n      return this.appending((prefix ?? '') + 'anon');\n    }\n\n    return this.appending((prefix ?? '') + node.text);\n  }\n\n  toString(): string {\n    const components: string[] = [];\n    let current: NamePath | undefined = this;\n    while (current) {\n      components.push(current.name);\n      current = current.parent;\n    }\n\n    return components.reverse().join('_');\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/native/utils/StringEscape.ts",
    "content": "export interface CString {\n  literalContent: string;\n  length: number;\n}\n\nexport function toCString(str: string): CString {\n  const buffer = Buffer.from(str, 'utf-8');\n  let literalContent = '\"';\n\n  for (let i = 0; i < buffer.length; i++) {\n    const c = buffer[i];\n\n    if (c >= 32 && c <= 126) {\n      // Visible character\n      if (c === 0x22) {\n        literalContent += '\\\\\"';\n      } else if (c === 0x5c) {\n        literalContent += '\\\\\\\\';\n      } else {\n        literalContent += String.fromCharCode(c);\n      }\n    } else if (c === 0x0a) {\n      literalContent += '\\\\n';\n    } else if (c === 0x09) {\n      literalContent += '\\\\t';\n    } else {\n      literalContent += '\\\\x';\n      literalContent += c.toString(16);\n    }\n  }\n\n  literalContent += '\"';\n\n  return {\n    literalContent,\n    length: buffer.length,\n  };\n}\n\nexport function escapeCComment(str: string): string {\n  return str.replace(/\\*\\//g, '*\\\\/').replace('/*', '/\\\\*');\n}\n"
  },
  {
    "path": "compiler/companion/src/native/utils/VariableIdMap.ts",
    "content": "import { NativeCompilerBuilderVariableID } from '../builder/INativeCompilerBuilder';\n\nexport class VariableIdMap<V extends Object | undefined> {\n  get size(): number {\n    return this.map.size;\n  }\n\n  private map = new Map<number, V>();\n\n  has(key: NativeCompilerBuilderVariableID): boolean {\n    return this.map.has(key.variable);\n  }\n\n  set(key: NativeCompilerBuilderVariableID, value: V): void {\n    this.map.set(key.variable, value);\n  }\n\n  get(key: NativeCompilerBuilderVariableID): V | undefined {\n    return this.map.get(key.variable);\n  }\n\n  delete(key: NativeCompilerBuilderVariableID): void {\n    this.map.delete(key.variable);\n  }\n\n  toString(): string {\n    let items: string[] = [];\n    for (const [key, item] of this.map) {\n      if (item) {\n        items.push(item.toString());\n      }\n    }\n\n    return items.toString();\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/project/FileManager.ts",
    "content": "import path = require('path');\nimport * as fs from 'fs';\nimport { VirtualFileSystem } from './VirtualFileSystem';\nimport { Lazy } from '../utils/Lazy';\n\nexport interface FilePath {\n  absolutePath: string;\n  pathComponents: readonly string[];\n  pathExtension: string;\n}\n\nexport interface File {\n  readonly content: string;\n}\n\nexport interface IFileManagerListener {\n  onFileLoaded(path: FilePath): void;\n}\n\nexport class FileManager {\n  private virtualFileSystem = new VirtualFileSystem<() => File>();\n\n  private rootPath: string;\n\n  constructor(rootPath: string, readonly listener?: IFileManagerListener) {\n    this.rootPath = rootPath;\n  }\n\n  clear(): void {\n    this.virtualFileSystem.clear();\n  }\n\n  getCurrentDirectory(): string {\n    return this.rootPath;\n  }\n\n  getRootPath(): string {\n    return this.rootPath;\n  }\n\n  resolvePath(relativePath: string): FilePath {\n    const absolutePath = path.resolve(this.rootPath, relativePath);\n    let pathComponents: string[];\n    if (absolutePath === path.sep) {\n      // Special case for / : we don't use absolutePath.split() as it will\n      // return two components\n      pathComponents = [''];\n    } else {\n      pathComponents = absolutePath.split(path.sep);\n    }\n\n    const pathExtension = path.extname(relativePath);\n    return {\n      absolutePath,\n      pathComponents,\n      pathExtension,\n    };\n  }\n\n  getDirectories(path: FilePath): FilePath[] {\n    let entryNames = this.virtualFileSystem.getDirectoryEntryNames(path.pathComponents);\n    if (!entryNames) {\n      throw new Error(`Directory ${path.absolutePath} does not exist`);\n    }\n\n    return entryNames.map((e) => this.resolvePath(e));\n  }\n\n  fileExists(path: FilePath): boolean {\n    return this.virtualFileSystem.fileExists(path.pathComponents);\n  }\n\n  directoryExists(path: FilePath): boolean {\n    return this.virtualFileSystem.directoryExists(path.pathComponents);\n  }\n\n  addFileInMemory(path: FilePath, fileContent: string): void {\n    this.virtualFileSystem.addFile(path.pathComponents, () => {\n      return {\n        content: fileContent,\n      };\n    });\n  }\n\n  addFileInDisk(path: FilePath, absolutePathOnDisk: string, cacheAfterReading: boolean = false): void {\n    const reader: () => File = () => {\n      const content = fs.readFileSync(absolutePathOnDisk, 'utf-8');\n      return {\n        content,\n      };\n    };\n\n    if (cacheAfterReading) {\n      const lazy = new Lazy(reader);\n      this.virtualFileSystem.addFile(path.pathComponents, () => lazy.target);\n    } else {\n      this.virtualFileSystem.addFile(path.pathComponents, reader);\n    }\n  }\n\n  getFile(path: FilePath): File {\n    let fileProvider = this.virtualFileSystem.getFile(path.pathComponents);\n    if (!fileProvider) {\n      throw new Error(`File ${path.absolutePath} does not exist`);\n    }\n\n    const file = fileProvider();\n\n    this.listener?.onFileLoaded(path);\n\n    return file;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/project/Project.spec.ts",
    "content": "import 'ts-jest';\nimport * as ts from 'typescript';\nimport { IProjectListener, Project } from './Project';\n\nclass TestProjectListener implements IProjectListener {\n  programChangedEventsCount = 0;\n  compilerOptionsResolvedEventsCount = 0;\n  fileContentLoadedEvents: string[] = [];\n  sourceFileCreatedEvents: string[] = [];\n  sourceFileInvalidatedEvents: string[] = [];\n\n  onProgramChanged(): void {\n    this.programChangedEventsCount++;\n  }\n\n  onProgramWillChange(): void {}\n\n  onCompilerOptionsResolved(): void {\n    this.compilerOptionsResolvedEventsCount++;\n  }\n\n  onFileContentLoaded(path: string): void {\n    this.fileContentLoadedEvents.push(path);\n  }\n\n  onSourceFileCreated(path: string): void {\n    this.sourceFileCreatedEvents.push(path);\n  }\n\n  onSourceFileInvalidated(path: string): void {\n    this.sourceFileInvalidatedEvents.push(path);\n  }\n}\n\nfunction createDefaultCompilerOptions(): ts.CompilerOptions {\n  return {\n    target: ts.ScriptTarget.ESNext,\n    module: ts.ModuleKind.NodeNext,\n    lib: ['lib.es2015.d.ts'],\n  };\n}\n\ndescribe('Project', () => {\n  it('can resolves tsconfig json from file', () => {\n    const listener = new TestProjectListener();\n    const project = new Project('/', undefined, listener);\n\n    project.setFileContentAtPath(\n      'tsconfig.json',\n      `\n      {\n        \"compilerOptions\": {\n          \"target\": \"es6\",\n          \"module\": \"commonjs\",\n          \"lib\": [\"es6\"],\n          \"strict\": true,\n          \"moduleResolution\": \"node\",\n        }\n      }\n    `,\n    );\n\n    const compilerOptions = project.compilerOptions;\n\n    expect(listener.compilerOptionsResolvedEventsCount).toBe(1);\n\n    expect(compilerOptions.target).toBe(ts.ScriptTarget.ES2015);\n    expect(compilerOptions.module).toBe(ts.ModuleKind.CommonJS);\n    expect(compilerOptions.lib).toEqual(['lib.es2015.d.ts']);\n    expect(compilerOptions.strict).toBeTruthy();\n    expect(compilerOptions.moduleResolution).toBe(ts.ModuleResolutionKind.NodeJs);\n\n    const newCompilerOptions = project.compilerOptions;\n\n    expect(newCompilerOptions).toBe(compilerOptions);\n    expect(listener.compilerOptionsResolvedEventsCount).toBe(1);\n  });\n\n  it('doesnt resolve tsconfig json from file when provided through ctor', () => {\n    const compilerOptions: ts.CompilerOptions = {\n      target: ts.ScriptTarget.ESNext,\n      module: ts.ModuleKind.NodeNext,\n      lib: ['es6'],\n    };\n    const listener = new TestProjectListener();\n    const project = new Project('/', compilerOptions, listener);\n\n    const newCompilerOptions = project.compilerOptions;\n\n    expect(newCompilerOptions).toBe(compilerOptions);\n    expect(listener.compilerOptionsResolvedEventsCount).toBe(0);\n  });\n\n  it('can create source file', () => {\n    const listener = new TestProjectListener();\n    const project = new Project('/', createDefaultCompilerOptions(), listener);\n\n    const sourceFile = project.createSourceFile(\n      'file.ts',\n      `\n    export interface MyInterface {\n      value: Array<string>\n    }\n    `,\n    );\n\n    expect(sourceFile.statements.length).toBe(1);\n    expect(ts.isInterfaceDeclaration(sourceFile.statements[0])).toBeTruthy();\n\n    const interfaceDeclaration = sourceFile.statements[0] as ts.InterfaceDeclaration;\n    expect(interfaceDeclaration.name.text).toBe('MyInterface');\n    expect(interfaceDeclaration.members.length).toBe(1);\n\n    expect(listener.programChangedEventsCount).toBe(0);\n    expect(listener.fileContentLoadedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileCreatedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileInvalidatedEvents).toEqual([]);\n  });\n\n  it('can open source file', () => {\n    const listener = new TestProjectListener();\n    const project = new Project('/', createDefaultCompilerOptions(), listener);\n\n    project.setFileContentAtPath('file.ts', `export const MY_NUMBER = 42;`);\n\n    expect(listener.programChangedEventsCount).toBe(0);\n    expect(listener.fileContentLoadedEvents).toEqual([]);\n    expect(listener.sourceFileCreatedEvents).toEqual([]);\n    expect(listener.sourceFileInvalidatedEvents).toEqual([]);\n\n    expect(project.getOpenedSourceFile('file.ts')).toBeUndefined();\n    const sourceFile = project.openSourceFile('file.ts');\n\n    expect(sourceFile.statements.length).toBe(1);\n    expect(sourceFile.statements[0].kind).toBe(ts.SyntaxKind.FirstStatement);\n\n    expect(project.getOpenedSourceFile('file.ts')).toBe(sourceFile);\n\n    expect(listener.programChangedEventsCount).toBe(0);\n    expect(listener.fileContentLoadedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileCreatedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileInvalidatedEvents).toEqual([]);\n  });\n\n  it('returns same source file when no change is found', () => {\n    const listener = new TestProjectListener();\n    const project = new Project('/', createDefaultCompilerOptions(), listener);\n\n    project.setFileContentAtPath('file.ts', `export const MY_NUMBER = 42;`);\n\n    const sourceFile = project.openSourceFile('file.ts');\n    const newSourceFile = project.openSourceFile('file.ts');\n\n    expect(sourceFile).toBe(newSourceFile);\n    expect(listener.programChangedEventsCount).toBe(0);\n    expect(listener.fileContentLoadedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileCreatedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileInvalidatedEvents).toEqual([]);\n  });\n\n  it('returns different source file on change', () => {\n    const listener = new TestProjectListener();\n    const project = new Project('/', createDefaultCompilerOptions(), listener);\n\n    project.setFileContentAtPath('file.ts', `export const MY_NUMBER = 42;`);\n\n    const sourceFile = project.openSourceFile('file.ts');\n    expect(sourceFile.statements.length).toBe(1);\n    expect(sourceFile.statements[0].kind).toBe(ts.SyntaxKind.FirstStatement);\n\n    expect(listener.programChangedEventsCount).toBe(0);\n    expect(listener.fileContentLoadedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileCreatedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileInvalidatedEvents).toEqual([]);\n\n    project.setFileContentAtPath(\n      'file.ts',\n      `\n    export interface MyInterface {\n      value: Array<string>\n    }    `,\n    );\n\n    expect(listener.programChangedEventsCount).toBe(0);\n    expect(listener.fileContentLoadedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileCreatedEvents).toEqual(['/file.ts']);\n    expect(listener.sourceFileInvalidatedEvents).toEqual(['/file.ts']);\n\n    const newSourceFile = project.openSourceFile('file.ts');\n\n    expect(newSourceFile).not.toBe(sourceFile);\n    expect(newSourceFile.statements.length).toBe(1);\n    expect(newSourceFile.statements[0].kind).toBe(ts.SyntaxKind.InterfaceDeclaration);\n\n    expect(listener.programChangedEventsCount).toBe(0);\n    expect(listener.fileContentLoadedEvents).toEqual(['/file.ts', '/file.ts']);\n    expect(listener.sourceFileCreatedEvents).toEqual(['/file.ts', '/file.ts']);\n    expect(listener.sourceFileInvalidatedEvents).toEqual(['/file.ts']);\n  });\n\n  it('loads tslib when program loads', () => {\n    const listener = new TestProjectListener();\n    const project = new Project('/', createDefaultCompilerOptions(), listener);\n\n    project.setFileContentAtPath('file.ts', `export const MY_NUMBER = 42;`);\n\n    project.openSourceFile('file.ts');\n    project.loadProgramIfNeeded();\n\n    expect(listener.programChangedEventsCount).toBe(1);\n    expect(listener.fileContentLoadedEvents).toEqual([\n      '/file.ts',\n      '/__tslibs__/lib.es2015.d.ts',\n      '/__tslibs__/lib.es5.d.ts',\n      '/__tslibs__/lib.decorators.d.ts',\n      '/__tslibs__/lib.decorators.legacy.d.ts',\n      '/__tslibs__/lib.es2015.core.d.ts',\n      '/__tslibs__/lib.es2015.collection.d.ts',\n      '/__tslibs__/lib.es2015.iterable.d.ts',\n      '/__tslibs__/lib.es2015.symbol.d.ts',\n      '/__tslibs__/lib.es2015.generator.d.ts',\n      '/__tslibs__/lib.es2015.promise.d.ts',\n      '/__tslibs__/lib.es2015.proxy.d.ts',\n      '/__tslibs__/lib.es2015.reflect.d.ts',\n      '/__tslibs__/lib.es2015.symbol.wellknown.d.ts',\n    ]);\n    expect(listener.sourceFileCreatedEvents).toEqual([\n      '/file.ts',\n      '/__tslibs__/lib.es2015.d.ts',\n      '/__tslibs__/lib.es5.d.ts',\n      '/__tslibs__/lib.decorators.d.ts',\n      '/__tslibs__/lib.decorators.legacy.d.ts',\n      '/__tslibs__/lib.es2015.core.d.ts',\n      '/__tslibs__/lib.es2015.collection.d.ts',\n      '/__tslibs__/lib.es2015.iterable.d.ts',\n      '/__tslibs__/lib.es2015.symbol.d.ts',\n      '/__tslibs__/lib.es2015.generator.d.ts',\n      '/__tslibs__/lib.es2015.promise.d.ts',\n      '/__tslibs__/lib.es2015.proxy.d.ts',\n      '/__tslibs__/lib.es2015.reflect.d.ts',\n      '/__tslibs__/lib.es2015.symbol.wellknown.d.ts',\n    ]);\n    expect(listener.sourceFileInvalidatedEvents).toEqual([]);\n  });\n\n  it('can open source file with dependent file', () => {\n    const listener = new TestProjectListener();\n    const project = new Project('/', createDefaultCompilerOptions(), listener);\n\n    project.setFileContentAtPath(\n      'utils/format.ts',\n      `\n    export function format(input: string): string {\n      return input.toUpperCase();\n    }\n    `,\n    );\n\n    project.setFileContentAtPath(\n      'file.ts',\n      `\n      import { format } from './utils/format';\n\n      export function showSomething(): string {\n        return format('This is sparta');\n      }\n    `,\n    );\n\n    expect(project.getOpenedSourceFile('utils/format.ts')).toBeUndefined();\n\n    project.openSourceFile('file.ts');\n    project.loadProgramIfNeeded();\n\n    expect(project.getOpenedSourceFile('utils/format.ts')).not.toBeUndefined();\n\n    expect(listener.programChangedEventsCount).toBe(1);\n    expect(listener.fileContentLoadedEvents).toEqual([\n      '/file.ts',\n      '/utils/format.ts',\n      '/__tslibs__/lib.es2015.d.ts',\n      '/__tslibs__/lib.es5.d.ts',\n      '/__tslibs__/lib.decorators.d.ts',\n      '/__tslibs__/lib.decorators.legacy.d.ts',\n      '/__tslibs__/lib.es2015.core.d.ts',\n      '/__tslibs__/lib.es2015.collection.d.ts',\n      '/__tslibs__/lib.es2015.iterable.d.ts',\n      '/__tslibs__/lib.es2015.symbol.d.ts',\n      '/__tslibs__/lib.es2015.generator.d.ts',\n      '/__tslibs__/lib.es2015.promise.d.ts',\n      '/__tslibs__/lib.es2015.proxy.d.ts',\n      '/__tslibs__/lib.es2015.reflect.d.ts',\n      '/__tslibs__/lib.es2015.symbol.wellknown.d.ts',\n    ]);\n    expect(listener.sourceFileCreatedEvents).toEqual([\n      '/file.ts',\n      '/utils/format.ts',\n      '/__tslibs__/lib.es2015.d.ts',\n      '/__tslibs__/lib.es5.d.ts',\n      '/__tslibs__/lib.decorators.d.ts',\n      '/__tslibs__/lib.decorators.legacy.d.ts',\n      '/__tslibs__/lib.es2015.core.d.ts',\n      '/__tslibs__/lib.es2015.collection.d.ts',\n      '/__tslibs__/lib.es2015.iterable.d.ts',\n      '/__tslibs__/lib.es2015.symbol.d.ts',\n      '/__tslibs__/lib.es2015.generator.d.ts',\n      '/__tslibs__/lib.es2015.promise.d.ts',\n      '/__tslibs__/lib.es2015.proxy.d.ts',\n      '/__tslibs__/lib.es2015.reflect.d.ts',\n      '/__tslibs__/lib.es2015.symbol.wellknown.d.ts',\n    ]);\n    expect(listener.sourceFileInvalidatedEvents).toEqual([]);\n  });\n\n  it('can reload source file', () => {\n    const listener = new TestProjectListener();\n    const project = new Project('/', createDefaultCompilerOptions(), listener);\n\n    project.setFileContentAtPath(\n      'utils/format.ts',\n      `\n    export function format(input: string): string {\n      return input.toUpperCase();\n    }\n    `,\n    );\n\n    project.setFileContentAtPath(\n      'file.ts',\n      `\n      import { format } from './utils/format';\n\n      export function showSomething(): string {\n        return format('This is sparta');\n      }\n    `,\n    );\n\n    const fileDotTs = project.openSourceFile('file.ts');\n    project.loadProgramIfNeeded();\n    const formatDotTs = project.getOpenedSourceFile('utils/format.ts');\n\n    expect(formatDotTs).not.toBeUndefined();\n\n    listener.fileContentLoadedEvents = [];\n    listener.sourceFileCreatedEvents = [];\n    listener.sourceFileInvalidatedEvents = [];\n\n    expect(listener.programChangedEventsCount).toBe(1);\n\n    project.setFileContentAtPath(\n      'utils/format.ts',\n      `\n    export function format(input: string): string {\n      return input.toLowerCase();\n    }\n    `,\n    );\n\n    project.loadProgramIfNeeded();\n\n    const newFileDotTs = project.getOpenedSourceFile('file.ts');\n    const newFormatDotTs = project.getOpenedSourceFile('utils/format.ts');\n\n    expect(newFileDotTs).toBe(fileDotTs);\n    expect(newFormatDotTs).not.toBe(formatDotTs);\n    expect(newFormatDotTs).not.toBeUndefined();\n\n    expect(listener.programChangedEventsCount).toBe(2);\n    expect(listener.fileContentLoadedEvents).toEqual(['/utils/format.ts']);\n    expect(listener.sourceFileCreatedEvents).toEqual(['/utils/format.ts']);\n    expect(listener.sourceFileInvalidatedEvents).toEqual(['/utils/format.ts']);\n\n    project.loadProgramIfNeeded();\n    project.loadProgramIfNeeded();\n\n    // Should not change if no changes were detected\n    expect(listener.programChangedEventsCount).toBe(2);\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/project/Project.ts",
    "content": "import * as ts from 'typescript';\nimport { FileManager, FilePath, IFileManagerListener } from './FileManager';\nimport { CompilerHost, FormatDiagnosticsHost, ParseConfigHost, TS_LIBS_VIRTUAL_DIRECTORY } from './TypeScriptHosts';\nimport { ISourceFileManagerListener, SourceFileManager } from './SourceFileManager';\nimport { TSLibsDatabase } from '../tslibs/TSLibsDatabase';\nimport * as path from 'path';\n\nexport interface IProjectListener {\n  onProgramWillChange(): void;\n  onProgramChanged(): void;\n  onCompilerOptionsResolved(): void;\n  onFileContentLoaded(path: string): void;\n  onSourceFileCreated(path: string): void;\n  onSourceFileInvalidated(path: string): void;\n}\n\nexport class Project implements ISourceFileManagerListener, IFileManagerListener {\n  get typeChecker(): ts.TypeChecker {\n    return this.program.getTypeChecker();\n  }\n\n  get program(): ts.Program {\n    return this.loadProgramIfNeeded();\n  }\n\n  get compilerOptions(): ts.CompilerOptions {\n    if (!this.resolvedCompilerOptions) {\n      this.resolvedCompilerOptions = this.resolveCompilerOptions();\n      this.listener?.onCompilerOptionsResolved();\n    }\n    return this.resolvedCompilerOptions;\n  }\n\n  private currentProgram: ts.Program | undefined = undefined;\n  private resolvedCompilerOptions: ts.CompilerOptions | undefined = undefined;\n\n  private fileManager: FileManager;\n  private sourceFileManager: SourceFileManager;\n  private programDirty = false;\n  private updatingProgram = false;\n\n  constructor(readonly rootPath: string, compilerOptions?: ts.CompilerOptions, readonly listener?: IProjectListener) {\n    this.fileManager = new FileManager(rootPath, this);\n    this.sourceFileManager = new SourceFileManager(this.fileManager, this);\n\n    this.resolvedCompilerOptions = compilerOptions;\n\n    // Populate TSLibs\n    const database = TSLibsDatabase.get();\n    for (const entry of database.entries) {\n      const resolvedPath = this.fileManager.resolvePath(path.join(TS_LIBS_VIRTUAL_DIRECTORY, entry.fileName));\n      this.fileManager.addFileInMemory(resolvedPath, entry.content);\n    }\n  }\n\n  destroy(): void {\n    this.fileManager.clear();\n    this.sourceFileManager.clear();\n    this.currentProgram = undefined;\n    this.resolvedCompilerOptions = undefined;\n  }\n\n  fileExists(path: string): boolean {\n    return this.fileManager.fileExists(this.fileManager.resolvePath(path));\n  }\n\n  createSourceFile(path: string, content: string): ts.SourceFile {\n    this.setFileContentAtPath(path, content);\n    return this.openSourceFile(path);\n  }\n\n  openSourceFile(path: string): ts.SourceFile {\n    return this.sourceFileManager.getOrCreateSourceFile(path, this.compilerOptions.target ?? ts.ScriptTarget.Latest);\n  }\n\n  getOpenedSourceFile(path: string): ts.SourceFile | undefined {\n    return this.sourceFileManager.getSourceFile(path);\n  }\n\n  removeSourceFile(path: string) {\n    this.sourceFileManager.removeSourceFile(path);\n  }\n\n  resolvePath(path: string): FilePath {\n    return this.fileManager.resolvePath(path);\n  }\n\n  setFileContentAtPath(path: string, content: string): void {\n    this.setFileContentAtResolvedPath(this.resolvePath(path), content);\n  }\n\n  setFileFromDiskAtPath(path: string, absoluteDiskPath: string): void {\n    this.setFileFromDiskAtResolvedPath(this.resolvePath(path), absoluteDiskPath);\n  }\n\n  setFileContentAtResolvedPath(resolvedPath: FilePath, content: string): void {\n    this.fileManager.addFileInMemory(resolvedPath, content);\n    this.sourceFileManager.invalidateSourceFile(resolvedPath);\n  }\n\n  setFileFromDiskAtResolvedPath(resolvedPath: FilePath, absoluteDiskPath: string): void {\n    this.fileManager.addFileInDisk(resolvedPath, absoluteDiskPath);\n    this.sourceFileManager.invalidateSourceFile(resolvedPath);\n  }\n\n  formatDiagnostics(diagnostics: readonly ts.Diagnostic[]): string {\n    return ts.formatDiagnostics(diagnostics, new FormatDiagnosticsHost(this.fileManager));\n  }\n\n  formatDiagnostic(diagnostic: ts.Diagnostic): string {\n    return ts.formatDiagnostic(diagnostic, new FormatDiagnosticsHost(this.fileManager));\n  }\n\n  onSourceFileCreated(path: FilePath): void {\n    this.setProgramDirty();\n    this.listener?.onSourceFileCreated(path.absolutePath);\n  }\n\n  onSourceFileInvalidated(path: FilePath): void {\n    this.setProgramDirty();\n    this.listener?.onSourceFileInvalidated(path.absolutePath);\n  }\n\n  onFileLoaded(path: FilePath): void {\n    this.listener?.onFileContentLoaded(path.absolutePath);\n  }\n\n  loadProgramIfNeeded(): ts.Program {\n    if (!this.currentProgram || this.programDirty) {\n      this.updatingProgram = true;\n\n      const oldProgram = this.currentProgram;\n\n      this.listener?.onProgramWillChange();\n\n      this.currentProgram = ts.createProgram(\n        this.sourceFileManager.getScriptFileNames(),\n        this.compilerOptions,\n        new CompilerHost(this.fileManager, this.sourceFileManager),\n        oldProgram,\n      );\n\n      this.updatingProgram = false;\n      this.programDirty = false;\n\n      this.listener?.onProgramChanged();\n    }\n\n    return this.currentProgram;\n  }\n\n  private setProgramDirty(): void {\n    if (!this.updatingProgram) {\n      this.programDirty = true;\n    }\n  }\n\n  private resolveCompilerOptions(): ts.CompilerOptions {\n    const tsConfigPath = this.fileManager.resolvePath('tsconfig.json');\n    const tsConfigJsonFile = this.fileManager.getFile(tsConfigPath);\n    const parseResult = ts.parseConfigFileTextToJson(tsConfigPath.absolutePath, tsConfigJsonFile.content);\n    if (parseResult.error) {\n      throw new Error(this.formatDiagnostic(parseResult.error));\n    }\n\n    const parsedCommandLine = ts.parseJsonConfigFileContent(\n      parseResult.config!,\n      new ParseConfigHost(this.fileManager),\n      this.fileManager.getRootPath(),\n      undefined,\n      tsConfigPath.absolutePath,\n    );\n\n    if (parsedCommandLine.errors?.length) {\n      // Ignore ts config errors for now\n      // throw new Error(this.formatDiagnostics(parsedCommandLine.errors));\n    }\n\n    return parsedCommandLine.options;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/project/SourceFileManager.ts",
    "content": "import * as ts from 'typescript';\nimport { FileManager, FilePath } from './FileManager';\n\nclass SourceFileEntry {\n  private scriptSnapshot: ts.IScriptSnapshot | undefined = undefined;\n  private sourceFile: ts.SourceFile | undefined = undefined;\n  private version = 0;\n\n  constructor(readonly path: FilePath) {}\n\n  getVersion(): string {\n    return this.version.toString();\n  }\n\n  getScriptKind(): ts.ScriptKind {\n    switch (this.path.pathExtension) {\n      case 'js':\n        return ts.ScriptKind.JS;\n      case 'json':\n        return ts.ScriptKind.JSON;\n      case 'ts':\n        return ts.ScriptKind.TS;\n      case 'tsx':\n        return ts.ScriptKind.TSX;\n      default:\n        return ts.ScriptKind.Unknown;\n    }\n  }\n\n  getSnapshot(fileManager: FileManager): ts.IScriptSnapshot {\n    if (!this.scriptSnapshot) {\n      const file = fileManager.getFile(this.path);\n      this.scriptSnapshot = ts.ScriptSnapshot.fromString(file.content);\n    }\n\n    return this.scriptSnapshot;\n  }\n\n  getSourceFile(): ts.SourceFile | undefined {\n    return this.sourceFile;\n  }\n\n  createSourceFile(\n    fileManager: FileManager,\n    languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions,\n  ): ts.SourceFile {\n    this.sourceFile = ts.createLanguageServiceSourceFile(\n      this.path.absolutePath,\n      this.getSnapshot(fileManager),\n      languageVersionOrOptions,\n      this.getVersion(),\n      true,\n      this.getScriptKind(),\n    );\n\n    return this.sourceFile;\n  }\n\n  invalidate(): boolean {\n    if (this.scriptSnapshot || this.sourceFile) {\n      this.version++;\n      this.scriptSnapshot = undefined;\n      this.sourceFile = undefined;\n\n      return true;\n    } else {\n      return false;\n    }\n  }\n}\n\nexport interface ISourceFileManagerListener {\n  onSourceFileInvalidated(path: FilePath): void;\n  onSourceFileCreated(path: FilePath): void;\n}\n\nexport class SourceFileManager {\n  private entries = new Map<string, SourceFileEntry>();\n  private version = 0;\n\n  constructor(readonly fileManager: FileManager, readonly listener?: ISourceFileManagerListener) {}\n\n  clear(): void {\n    this.entries.clear();\n  }\n\n  getVersion(): number {\n    return this.version++;\n  }\n\n  getScriptFileNames(): string[] {\n    const output: string[] = [];\n\n    for (const [key, value] of this.entries) {\n      if (value.getSourceFile()) {\n        output.push(key);\n      }\n    }\n\n    return output.sort();\n  }\n\n  getScriptVersion(filePath: string): string {\n    const resolvedFilePath = this.fileManager.resolvePath(filePath);\n    return this.getOrCreateEntry(resolvedFilePath).getVersion();\n  }\n\n  getScriptSnapshot(filePath: string) {\n    const resolvedFilePath = this.fileManager.resolvePath(filePath);\n    return this.getOrCreateEntry(resolvedFilePath).getSnapshot(this.fileManager);\n  }\n\n  getScriptKind(filePath: string): ts.ScriptKind {\n    const resolvedFilePath = this.fileManager.resolvePath(filePath);\n    return this.getOrCreateEntry(resolvedFilePath).getScriptKind();\n  }\n\n  getOrCreateSourceFile(\n    filePath: string,\n    languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions,\n  ): ts.SourceFile {\n    const resolvedFilePath = this.fileManager.resolvePath(filePath);\n    const entry = this.getOrCreateEntry(resolvedFilePath);\n\n    let sourceFile = entry.getSourceFile();\n    if (!sourceFile) {\n      sourceFile = entry.createSourceFile(this.fileManager, languageVersionOrOptions);\n\n      this.listener?.onSourceFileCreated(resolvedFilePath);\n    }\n\n    return sourceFile;\n  }\n\n  getSourceFile(filePath: string): ts.SourceFile | undefined {\n    const resolvedFilePath = this.fileManager.resolvePath(filePath);\n    const entry = this.getOrCreateEntry(resolvedFilePath);\n    return entry.getSourceFile();\n  }\n\n  removeSourceFile(filePath: string) {\n    const resolvedFilePath = this.fileManager.resolvePath(filePath);\n\n    this.invalidateSourceFile(resolvedFilePath);\n  }\n\n  invalidateSourceFile(filePath: FilePath) {\n    const entry = this.entries.get(filePath.absolutePath);\n    if (!entry) {\n      return;\n    }\n\n    if (entry.invalidate()) {\n      this.listener?.onSourceFileInvalidated(filePath);\n    }\n  }\n\n  private getOrCreateEntry(filePath: FilePath): SourceFileEntry {\n    let entry = this.entries.get(filePath.absolutePath);\n    if (!entry) {\n      entry = new SourceFileEntry(filePath);\n    }\n    this.entries.set(filePath.absolutePath, entry);\n\n    return entry;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/project/TypeScriptHosts.ts",
    "content": "import path = require('path');\nimport * as ts from 'typescript';\nimport { FileManager, FilePath } from './FileManager';\nimport { SourceFileManager } from './SourceFileManager';\nimport { FileSystemEntries, matchFiles } from './tsInternals';\n\nexport const TS_LIBS_VIRTUAL_DIRECTORY = '/__tslibs__';\n\nfunction throwUnimplemented(parameters: any): never {\n  const error = Error(`Methods unimplemented. Parameters given: ${JSON.stringify(parameters, null, 2)}`);\n\n  console.error(error);\n\n  throw error;\n}\n\nfunction getFileSystemEntries(path: FilePath, fileManager: FileManager): FileSystemEntries {\n  const files: string[] = [];\n  const directories: string[] = [];\n  const entries = fileManager.getDirectories(path);\n\n  for (const entry of entries) {\n    if (fileManager.fileExists(entry)) {\n      files.push(entry.absolutePath);\n    } else if (fileManager.directoryExists(entry)) {\n      directories.push(entry.absolutePath);\n    }\n  }\n\n  return { files, directories };\n}\n\nclass HostBase implements ts.FormatDiagnosticsHost {\n  constructor(readonly fileManager: FileManager) {}\n\n  getCurrentDirectory(): string {\n    return this.fileManager.getCurrentDirectory();\n  }\n\n  getNewLine(): string {\n    return '\\n';\n  }\n\n  getCanonicalFileName(fileName: string): string {\n    return this.fileManager.resolvePath(fileName).absolutePath;\n  }\n\n  readDirectory(\n    rootDir: string,\n    extensions: readonly string[],\n    excludes: readonly string[] | undefined,\n    includes: readonly string[],\n    depth?: number,\n  ): string[] {\n    const currentDirectory = this.fileManager.getCurrentDirectory();\n\n    const output = matchFiles(\n      rootDir,\n      extensions,\n      excludes || [],\n      includes,\n      true,\n      currentDirectory,\n      depth,\n      (path) => {\n        // const includeDir = dirPathMatches(path);\n        const standardizedPath = this.fileManager.resolvePath(path);\n        return getFileSystemEntries(standardizedPath, this.fileManager);\n      },\n      (path) => this.fileManager.resolvePath(path).absolutePath,\n      (path) => this.fileManager.directoryExists(this.fileManager.resolvePath(path)),\n    );\n\n    return output;\n  }\n\n  getDirectories?(directoryName: string): string[] {\n    return this.fileManager.getDirectories(this.fileManager.resolvePath(directoryName)).map((p) => p.absolutePath);\n  }\n\n  realpath?(path: string): string {\n    return this.fileManager.resolvePath(path).absolutePath;\n  }\n\n  directoryExists?(directoryName: string): boolean {\n    if (directoryName.endsWith('node_modules/@types')) {\n      return false;\n    }\n\n    return this.fileManager.directoryExists(this.fileManager.resolvePath(directoryName));\n  }\n\n  fileExists(path: string): boolean {\n    return this.fileManager.fileExists(this.fileManager.resolvePath(path));\n  }\n\n  readFile(path: string): string | undefined {\n    const resolvedPath = this.fileManager.resolvePath(path);\n    try {\n      return this.fileManager.getFile(resolvedPath).content;\n    } catch {\n      return undefined;\n    }\n  }\n}\n\nclass SourceFileHostBase extends HostBase {\n  constructor(fileManager: FileManager, readonly sourceFileManager: SourceFileManager) {\n    super(fileManager);\n  }\n\n  getDefaultLibFileName(options: ts.CompilerOptions): string {\n    return path.resolve(TS_LIBS_VIRTUAL_DIRECTORY, ts.getDefaultLibFileName(options));\n  }\n\n  useCaseSensitiveFileNames(): boolean {\n    return true;\n  }\n}\n\nexport class ParseConfigHost extends HostBase implements ts.ParseConfigHost {\n  useCaseSensitiveFileNames = true;\n}\n\nexport class CompilerHost extends SourceFileHostBase implements ts.CompilerHost {\n  constructor(fileManager: FileManager, sourceFileManager: SourceFileManager) {\n    super(fileManager, sourceFileManager);\n  }\n  getSourceFile(\n    fileName: string,\n    languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions,\n    onError?: ((message: string) => void) | undefined,\n    shouldCreateNewSourceFile?: boolean | undefined,\n  ): ts.SourceFile | undefined {\n    return this.sourceFileManager.getOrCreateSourceFile(fileName, languageVersionOrOptions);\n  }\n\n  writeFile: ts.WriteFileCallback = (\n    fileName: string,\n    text: string,\n    writeByteOrderMark: boolean,\n    onError?: (message: string) => void,\n    sourceFiles?: readonly ts.SourceFile[],\n    data?: ts.WriteFileCallbackData,\n  ) => {\n    throwUnimplemented({ fileName, text, writeByteOrderMark });\n  };\n\n  getEnvironmentVariable?(name: string): string | undefined {\n    return process.env[name];\n  }\n}\n\nexport class FormatDiagnosticsHost extends HostBase implements ts.FormatDiagnosticsHost {}\n"
  },
  {
    "path": "compiler/companion/src/project/VirtualFileSystem.spec.ts",
    "content": "import 'ts-jest';\nimport { VirtualFileSystem } from './VirtualFileSystem';\n\ndescribe('VirtualFileSystem', () => {\n  it('can insert directories', () => {\n    const fs = new VirtualFileSystem<string>();\n\n    expect(fs.directoryExists(['hello'])).toBeFalsy();\n    expect(fs.directoryExists(['hello', 'world'])).toBeFalsy();\n    expect(fs.directoryExists(['hello', 'world', 'nested'])).toBeFalsy();\n\n    fs.addDirectory(['hello', 'world']);\n\n    expect(fs.directoryExists(['hello'])).toBeTruthy();\n    expect(fs.directoryExists(['hello', 'world'])).toBeTruthy();\n    expect(fs.directoryExists(['hello', 'world', 'nested'])).toBeFalsy();\n  });\n\n  it('can insert files', () => {\n    const fs = new VirtualFileSystem<string>();\n\n    expect(fs.fileExists(['hello'])).toBeFalsy();\n    expect(fs.fileExists(['hello', 'world'])).toBeFalsy();\n    expect(fs.fileExists(['hello', 'world', 'nested'])).toBeFalsy();\n\n    expect(fs.directoryExists(['hello'])).toBeFalsy();\n    expect(fs.directoryExists(['hello', 'world'])).toBeFalsy();\n    expect(fs.directoryExists(['hello', 'world', 'nested'])).toBeFalsy();\n\n    fs.addFile(['hello', 'world', 'nested'], 'Nice!');\n\n    expect(fs.fileExists(['hello'])).toBeFalsy();\n    expect(fs.fileExists(['hello', 'world'])).toBeFalsy();\n    expect(fs.fileExists(['hello', 'world', 'nested'])).toBeTruthy();\n\n    expect(fs.directoryExists(['hello'])).toBeTruthy();\n    expect(fs.directoryExists(['hello', 'world'])).toBeTruthy();\n    expect(fs.directoryExists(['hello', 'world', 'nested'])).toBeFalsy();\n\n    expect(fs.getFile(['hello', 'world', 'nested'])).toEqual('Nice!');\n  });\n\n  it('can rm file', () => {\n    const fs = new VirtualFileSystem<string>();\n\n    fs.addFile(['hello', 'world', 'nested'], 'Nice!');\n\n    expect(fs.fileExists(['hello', 'world', 'nested'])).toBeTruthy();\n\n    fs.remove(['hello', 'world', 'nested']);\n\n    expect(fs.fileExists(['hello', 'world', 'nested'])).toBeFalsy();\n    expect(fs.getFile(['hello', 'world', 'nested'])).toBeUndefined();\n\n    expect(fs.directoryExists(['hello'])).toBeTruthy();\n    expect(fs.directoryExists(['hello', 'world'])).toBeTruthy();\n    expect(fs.directoryExists(['hello', 'world', 'nested'])).toBeFalsy();\n  });\n\n  it('can rm directory', () => {\n    const fs = new VirtualFileSystem<string>();\n\n    fs.addDirectory(['hello', 'world', 'nested']);\n\n    expect(fs.directoryExists(['hello', 'world', 'nested'])).toBeTruthy();\n\n    expect(fs.remove(['hello', 'world'])).toBeTruthy();\n\n    expect(fs.directoryExists(['hello'])).toBeTruthy();\n    expect(fs.directoryExists(['hello', 'world'])).toBeFalsy();\n    expect(fs.directoryExists(['hello', 'world', 'nested'])).toBeFalsy();\n  });\n\n  it('can get directory entry names', () => {\n    const fs = new VirtualFileSystem<string>();\n\n    fs.addDirectory(['hello', 'world', 'nested']);\n    fs.addFile(['hello', 'world', 'nested', 'cool'], 'Nice!');\n    fs.addFile(['hello', 'world', 'a file'], 'Great');\n\n    expect(fs.getDirectoryEntryNames([])).toEqual(['hello']);\n    expect(fs.getDirectoryEntryNames(['hello'])).toEqual(['world']);\n    expect(fs.getDirectoryEntryNames(['hello', 'world'])).toEqual(['nested', 'a file']);\n    expect(fs.getDirectoryEntryNames(['hello', 'world', 'nested'])).toEqual(['cool']);\n  });\n\n  it('returns directory entry names when adding file', () => {\n    const fs = new VirtualFileSystem<string>();\n\n    fs.addFile(['hello', 'world', 'a file'], 'Great');\n\n    expect(fs.getDirectoryEntryNames([])).toEqual(['hello']);\n    expect(fs.getDirectoryEntryNames(['hello'])).toEqual(['world']);\n    expect(fs.getDirectoryEntryNames(['hello', 'world'])).toEqual(['a file']);\n  });\n\n  it('throws when inserting directory with a file', () => {\n    const fs = new VirtualFileSystem<string>();\n\n    fs.addFile(['hello', 'world', 'nested'], 'Nice!');\n\n    expect(fs.addDirectory(['hello'])).toBeFalsy();\n\n    expect(fs.addDirectory(['hello', 'world'])).toBeFalsy();\n\n    expect(() => {\n      fs.addDirectory(['hello', 'world', 'nested']);\n    }).toThrowError('Cannot create directory \"nested\": \"/hello/world/nested\" is a file');\n\n    expect(() => {\n      fs.addDirectory(['hello', 'world', 'nested', 'more']);\n    }).toThrowError('Cannot create directory \"nested\": \"/hello/world/nested\" is a file');\n  });\n\n  it('throws when inserting file to replace directory', () => {\n    const fs = new VirtualFileSystem<string>();\n\n    fs.addDirectory(['hello', 'world', 'nested']);\n\n    expect(() => {\n      fs.addFile(['hello'], 'Nope');\n    }).toThrowError('Cannot create file \"hello\": \"/hello\" is a directory');\n\n    expect(() => {\n      fs.addFile(['hello', 'world'], 'Nope');\n    }).toThrowError('Cannot create file \"world\": \"/hello/world\" is a directory');\n\n    expect(() => {\n      fs.addFile(['hello', 'world', 'nested'], 'Nope');\n    }).toThrowError('Cannot create file \"nested\": \"/hello/world/nested\" is a directory');\n\n    fs.addFile(['hello', 'world', 'nested', 'more'], 'Nope');\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/project/VirtualFileSystem.ts",
    "content": "import path = require('path');\n\nclass VirtualFileSystemEntry<T> {\n  readonly parent: VirtualFileSystemEntry<T> | undefined;\n  readonly name: string;\n\n  private directory: Map<string, VirtualFileSystemEntry<T>> | undefined;\n  private file: T | undefined;\n\n  constructor(parent: VirtualFileSystemEntry<T> | undefined, name: string) {\n    this.parent = parent;\n    this.name = name;\n    this.directory = parent ? undefined : new Map();\n    this.file = undefined;\n  }\n\n  clear(): void {\n    if (this.directory) {\n      this.directory.clear();\n      this.directory = undefined;\n    }\n    this.file = undefined;\n  }\n\n  getAbsoluteName(): string {\n    let components: string[] = [];\n\n    let current: VirtualFileSystemEntry<T> | undefined = this;\n    while (current) {\n      components.push(current.name);\n      current = current.parent;\n    }\n\n    return components.reverse().join(path.sep);\n  }\n\n  emplaceNested(name: string): VirtualFileSystemEntry<T> {\n    const directory = this.setAsDirectory();\n\n    let nestedEntry = directory.get(name);\n    if (!nestedEntry) {\n      nestedEntry = new VirtualFileSystemEntry(this, name);\n      directory.set(name, nestedEntry);\n    }\n\n    return nestedEntry;\n  }\n\n  private setAsDirectory(): Map<string, VirtualFileSystemEntry<T>> {\n    if (!this.directory) {\n      if (this.file) {\n        throw new Error(`Cannot create directory \"${this.name}\": \"${this.getAbsoluteName()}\" is a file`);\n      }\n\n      this.directory = new Map();\n    }\n\n    return this.directory;\n  }\n\n  getNested(name: string): VirtualFileSystemEntry<T> | undefined {\n    return this.directory?.get(name);\n  }\n\n  remove(): void {\n    if (!this.parent) {\n      throw new Error('Cannot remove root entry');\n    }\n\n    this.parent.directory!.delete(this.name);\n  }\n\n  setFile(file: T): void {\n    if (this.directory) {\n      throw new Error(`Cannot create file \"${this.name}\": \"${this.getAbsoluteName()}\" is a directory`);\n    }\n\n    this.file = file;\n  }\n\n  setDirectory(): boolean {\n    if (this.directory) {\n      return false;\n    }\n    this.setAsDirectory();\n    return true;\n  }\n\n  getFile(): T | undefined {\n    return this.file;\n  }\n\n  isFile(): boolean {\n    return !!this.file;\n  }\n\n  isDirectory(): boolean {\n    return !!this.directory;\n  }\n\n  getEntryNames(): string[] | undefined {\n    const keys = this.directory?.keys();\n    if (!keys) {\n      return undefined;\n    }\n\n    return [...keys];\n  }\n}\n\nexport class VirtualFileSystem<T> {\n  private root = new VirtualFileSystemEntry<T>(undefined, '');\n\n  clear(): void {\n    this.root.clear();\n  }\n\n  addFile(pathComponents: readonly string[], file: T) {\n    const entry = this.emplaceEntry(pathComponents);\n\n    entry.setFile(file);\n  }\n\n  addDirectory(pathComponents: readonly string[]): boolean {\n    const entry = this.emplaceEntry(pathComponents);\n\n    return entry.setDirectory();\n  }\n\n  getFile(pathComponent: readonly string[]): T | undefined {\n    return this.getEntry(pathComponent)?.getFile();\n  }\n\n  remove(pathComponents: readonly string[]): boolean {\n    const entry = this.getEntry(pathComponents);\n\n    if (!entry) {\n      return false;\n    }\n\n    entry.remove();\n    return true;\n  }\n\n  fileExists(pathComponents: readonly string[]): boolean {\n    return this.getEntry(pathComponents)?.isFile() ?? false;\n  }\n\n  directoryExists(pathComponents: readonly string[]): boolean {\n    return this.getEntry(pathComponents)?.isDirectory() ?? false;\n  }\n\n  getDirectoryEntryNames(pathComponents: readonly string[]): string[] | undefined {\n    return this.getEntry(pathComponents)?.getEntryNames();\n  }\n\n  private getEntry(pathComponents: readonly string[]): VirtualFileSystemEntry<T> | undefined {\n    let current = this.root;\n\n    for (const pathComponent of pathComponents) {\n      const newCurrent = current.getNested(pathComponent);\n      if (!newCurrent) {\n        return undefined;\n      }\n\n      current = newCurrent;\n    }\n\n    return current;\n  }\n\n  private emplaceEntry(pathComponents: readonly string[]): VirtualFileSystemEntry<T> {\n    let current = this.root;\n\n    for (const pathComponent of pathComponents) {\n      current = current.emplaceNested(pathComponent);\n    }\n\n    return current;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/project/tsInternals.ts",
    "content": "import * as ts from 'typescript';\n\n// Taken from ts-morph\n// These are hacks are re-use some private utilities\n// from typescript\n\nexport function matchFiles(\n  this: any,\n  path: string,\n  extensions: ReadonlyArray<string>,\n  excludes: ReadonlyArray<string>,\n  includes: ReadonlyArray<string>,\n  useCaseSensitiveFileNames: boolean,\n  currentDirectory: string,\n  depth: number | undefined,\n  getEntries: (path: string) => FileSystemEntries,\n  realpath: (path: string) => string,\n  directoryExists: (path: string) => boolean,\n): string[] {\n  return (ts as any).matchFiles.apply(this, arguments);\n}\n\nexport interface FileSystemEntries {\n  readonly files: ReadonlyArray<string>;\n  readonly directories: ReadonlyArray<string>;\n}\n"
  },
  {
    "path": "compiler/companion/src/protocol.ts",
    "content": "import { AST } from './AST';\nimport { BatchMinifyResult } from './BatchMinifier';\nimport { CodeInstrumentationFileConfig, CodeInstrumentationResult } from './CodeInstrumentation';\n\nexport enum Command {\n  batchMinifyJS = 'batchMinifyJS',\n  register = 'registerFile',\n  open = 'openFile',\n  emit = 'emitFile',\n  addCodeInstrumentation = 'addCodeInstrumentation',\n  getDiagnostics = 'getDiagnostics',\n  createWorkspace = 'createWorkspace',\n  destroyWorkspace = 'destroyWorkspace',\n  initializeWorkspace = 'initializeWorkspace',\n  updatedAndroidTargets = 'updatedAndroidTargets',\n  dumpSymbolsWithComments = 'dumpSymbolsWithComments',\n  dumpInterface = 'dumpInterface',\n  dumpFunction = 'dumpFunction',\n  dumpEnum = 'dumpEnum',\n  generateIdsFiles = 'generateIdsFiles',\n  exportStringsFiles = 'exportStringsFiles',\n  exportTranslationStrings = 'exportTranslationStrings',\n  exportStringsFilesBatch = 'exportStringsFilesBatch',\n  startDebuggingProxy = 'startDebuggingProxy',\n  compileNative = 'compileNative',\n  uploadArtifact = 'uploadArtifact',\n  updatedDebuggerPorts = 'updatedDebuggerPorts',\n  generateGhostOwnershipMap = 'generateGhostOwnershipMap',\n  rewriteImports = 'rewriteImports',\n}\n\nexport interface Request {\n  id: string;\n  command: Command;\n  body: RequestBody;\n}\n\nexport interface SuccessPayload {\n  id: string;\n  body: ResponseBody;\n}\n\nexport interface ErrorPayload {\n  id: string;\n  error: string;\n}\n\nexport interface EventBody {\n  type: string;\n  message: string;\n}\n\nexport interface EventPayload {\n  event: EventBody;\n}\n\nexport type TransportPayload = SuccessPayload | ErrorPayload | EventPayload;\n\nexport interface BatchMinifyJSRequestBody {\n  inputFiles: string[];\n  minifier: 'terser';\n  options: string;\n}\n\nexport interface CreateWorkspaceRequestBody {}\n\nexport interface DestroyWorkspaceRequestBody {\n  workspaceId: number;\n}\n\nexport interface WorkspaceScopedRequestBodyBase {\n  workspaceId: number;\n}\n\nexport interface InitializeWorkspaceRequestBody extends WorkspaceScopedRequestBodyBase {}\n\nexport interface RegisterFileRequestBody extends WorkspaceScopedRequestBodyBase {\n  fileName: string;\n  // If set, the file will be registered as a disk file\n  // where the content can be read from this path.\n  absoluteDiskPath?: string;\n  // If set, the file will be registered as an in-memory file\n  // where the content will be read from this property.\n  fileContent?: string;\n}\n\nexport interface OpenFileRequestBody extends WorkspaceScopedRequestBodyBase {\n  fileName: string;\n}\n\nexport interface EmitFileRequestBody extends WorkspaceScopedRequestBodyBase {\n  fileName: string;\n}\n\nexport interface AddCodeInstrumentationRequestBody {\n  files: [CodeInstrumentationFileConfig];\n}\n\nexport interface GetDiagnosticsRequestBody extends WorkspaceScopedRequestBodyBase {\n  fileName: string;\n}\n\nexport interface DumpSymbolsWithCommentsRequestBody extends WorkspaceScopedRequestBodyBase {\n  fileName: string;\n}\n\nexport interface DumpInterfaceRequestBody extends WorkspaceScopedRequestBodyBase {\n  fileName: string;\n  position: number;\n}\n\nexport interface DumpFunctionRequestBody extends WorkspaceScopedRequestBodyBase {\n  fileName: string;\n  position: number;\n}\n\nexport interface DumpEnumRequestBody extends WorkspaceScopedRequestBodyBase {\n  fileName: string;\n  position: number;\n}\n\nexport interface UpdatedAndroidTargetsRequestBody {\n  targets: { deviceId: string; target: string }[];\n}\n\nexport interface GenerateIdsFilesRequestBody {\n  moduleName: string;\n  iosHeaderImportPath: string;\n  filePath: string;\n}\n\nexport interface ExportStringsFilesRequestBody {\n  moduleName: string;\n  inputPath: string;\n  iosOutputPath?: string;\n  androidOutputPath?: string;\n}\n\nexport interface ExportTranslationStringsRequestBody {\n  /** Module name */\n  moduleName: string;\n  /** Path to the base locale, \"en\", file */\n  baseLocaleStringsPath: string;\n  /** Path to the locale file to be converted */\n  inputLocaleStringsPath: string;\n  /** Are we exporting strings for Android or iOS? */\n  platform: 'android' | 'ios';\n}\n\nexport interface ExportStringsFilesBatchRequestBody {\n  batch: ExportStringsFilesRequestBody[];\n}\n\nexport interface StartDebuggingProxyRequestBody {}\n\nexport interface CompileNativeRequestBody extends WorkspaceScopedRequestBodyBase {\n  stripIncludePrefix: string;\n  inputFiles: string[];\n  // Whether the input files should be registered into the workspace as\n  // references to files on disk\n  registerInputFiles?: boolean;\n  // If set, will store the output into the given path.\n  outputFile?: string;\n}\n\nexport interface UploadArtifactRequestBody {\n  artifactName: string;\n  artifactData: string;\n  sha256: string;\n}\n\nexport interface UpdatedDebuggerPorts {\n  ports: number[];\n}\n\nexport interface GenerateGhostOwnershipMapRequestBody {\n  outputDir: string;\n}\n\nexport interface RewriteImportsRequestBody {\n  projectDirectory: string;\n  oldTypeName: string;\n  newTypeName: string;\n  oldImportPath: string;\n  newImportPath: string;\n}\n\nexport type RequestBody =\n  | BatchMinifyJSRequestBody\n  | RegisterFileRequestBody\n  | OpenFileRequestBody\n  | EmitFileRequestBody\n  | GetDiagnosticsRequestBody\n  | CreateWorkspaceRequestBody\n  | DestroyWorkspaceRequestBody\n  | InitializeWorkspaceRequestBody\n  | UpdatedAndroidTargetsRequestBody\n  | GenerateIdsFilesRequestBody\n  | ExportStringsFilesRequestBody\n  | ExportStringsFilesBatchRequestBody\n  | StartDebuggingProxyRequestBody\n  | CompileNativeRequestBody\n  | AddCodeInstrumentationRequestBody\n  | UploadArtifactRequestBody\n  | UpdatedDebuggerPorts\n  | GenerateGhostOwnershipMapRequestBody\n  | RewriteImportsRequestBody;\n\nexport interface BatchMinifyJSResponseBody {\n  results: BatchMinifyResult[];\n}\n\nexport interface RegisterFileResponseBody {}\n\nexport interface OpenFileResponseBody {\n  openResult: {\n    importPaths: {\n      relative: string;\n      absolute: string;\n    }[];\n  };\n}\n\nexport interface EmittedFile {\n  fileName: string;\n  content?: string;\n}\n\nexport interface EmitFileResponseBody {\n  emitted: boolean;\n  files: EmittedFile[];\n}\n\nexport interface Location {\n  line: number;\n  offset: number;\n}\n\nexport interface Diagnostic {\n  start?: Location | undefined;\n  end?: Location | undefined;\n  text: string;\n  category: string;\n  code?: number;\n  source?: string;\n}\n\nexport interface GetDiagnosticsResponseBody {\n  diagnostics: Diagnostic[];\n  fileContent: string | undefined;\n  hasError: boolean;\n  timeTakenMs: number;\n}\n\nexport interface DumpedSymbolsWithComments {\n  leadingComments?: AST.Comments;\n  dumpedSymbols: {\n    interface?: AST.Interface;\n    leadingComments?: AST.Comments;\n  }[];\n  references: AST.TypeReference[];\n}\n\nexport interface DumpSymbolsWithCommentsResponseBody {\n  dumpedSymbols: DumpedSymbolsWithComments;\n}\n\nexport interface DumpedInterface {\n  interface: AST.Interface | undefined;\n  references: AST.TypeReference[];\n}\n\nexport interface DumpInterfaceResponseBody {\n  interface: DumpedInterface;\n}\n\nexport interface DumpFunctionResponseBody {\n  function: AST.Function;\n  references: AST.TypeReference[];\n}\n\nexport interface DumpEnumResponseBody {\n  enum: AST.Enum;\n}\n\nexport interface CreateWorkspaceResponseBody {\n  workspaceId: number;\n}\n\nexport interface DestroyWorkspaceResponseBody {}\n\nexport interface InitializeWorkspaceResponseBody {}\n\nexport interface UpdatedAndroidTargetsResponseBody {}\n\nexport interface GenerateIdsFilesResponseBody {\n  android: string;\n  iosHeader: string;\n  iosImplementation: string;\n  typescriptDefinition: string;\n  typescriptImplementation: string;\n}\n\nexport interface ExportStringsFilesResponseBody {}\n\nexport interface ExportTranslationStringsResponseBody {\n  /** Locale name used in the input locale file.\n   *\n   * iOS and Android use different locale names.\n   * Valdi uses its own locale names to unify across platforms,\n   * this is the valdi locale name.\n   */\n  inputLocale: string;\n  /** Platform specific locale name. */\n  platformLocale: string;\n  /** Platform specific translation file representation. */\n  content: string;\n  /** Platform specific file name. */\n  outputFileName: string;\n}\n\nexport interface ExportStringsFilesBatchResponseBody {}\n\nexport interface StartDebuggingProxyResponseBody {\n  actualPort: number;\n}\n\nexport interface CompileNativeResponseBody {\n  files: EmittedFile[];\n}\n\nexport interface AddCodeInstrumentationResponseBody {\n  results: CodeInstrumentationResult[];\n}\n\nexport interface UploadArtifactResponseBody {\n  url: string;\n  sha256: string;\n}\n\nexport interface GenerateGhostOwnershipMapResponseBody {}\n\nexport interface RewriteImportsResponseBody {}\n\nexport type ResponseBody =\n  | BatchMinifyJSResponseBody\n  | RegisterFileResponseBody\n  | OpenFileResponseBody\n  | EmitFileResponseBody\n  | GetDiagnosticsResponseBody\n  | DumpSymbolsWithCommentsResponseBody\n  | CreateWorkspaceResponseBody\n  | DestroyWorkspaceResponseBody\n  | InitializeWorkspaceResponseBody\n  | UpdatedAndroidTargetsResponseBody\n  | DumpInterfaceResponseBody\n  | DumpFunctionResponseBody\n  | DumpEnumResponseBody\n  | GenerateIdsFilesResponseBody\n  | ExportStringsFilesResponseBody\n  | ExportStringsFilesBatchResponseBody\n  | StartDebuggingProxyResponseBody\n  | CompileNativeResponseBody\n  | AddCodeInstrumentationResponseBody\n  | GenerateGhostOwnershipMapResponseBody\n  | RewriteImportsResponseBody;\n"
  },
  {
    "path": "compiler/companion/src/sqlite_bindings/README.md",
    "content": "# Better SQLite-3 Bindings\n\nWe ship the companion code as a single dist folder with a bundle.js file. This bundle needs to support all platforms we support, which include Linux x86_64, MacOS arm64 and MacOS x86_64.\nWhen running `npm install`, it will install and build the better-sqlite3 bindings for the platform it is running on only. In order to support all platforms, we include in this folder the .node files for every platform, which were copied then from `node_modules/better-sqlite3/build/Release/better_sqlite3.node`.\nTo update the bindings, you need to run `npm install` on all platforms we support and copy the files from `node_modules/better-sqlite3/build/Release/better_sqlite3.node`.\n"
  },
  {
    "path": "compiler/companion/src/strings/GenerateStringsFiles.spec.ts",
    "content": "import 'ts-jest';\nimport {\n  generateAndroidStringsXMLFromStringsJSON,\n  generateIOSLocalizableStringsFromStringsJSON,\n  LocalizationServiceDirectiveParsingMode,\n  parseStringsJSON,\n} from './GenerateStringsFiles';\n\ndescribe('Strings JSON File Generator', () => {\n  describe('translation with different placeholder order', () => {\n    const moduleName = 'empty_module';\n    const baseEnglishJSONString = `\n{\n  \"some_key\": {\n    \"defaultMessage\": \"Sent {sentCount} out of {totalCount} total items\"\n  }\n}\n`;\n\n    const inputJSONString = `\n{\n  \"some_key\": {\n    \"defaultMessage\": \"Из {totalCount} штук уже отправлено {sentCount}\"\n  }\n}\n`;\n    const baseEnglishJSON = parseStringsJSON(\n      moduleName,\n      baseEnglishJSONString,\n      LocalizationServiceDirectiveParsingMode.Ignore,\n    );\n    const inputJSON = parseStringsJSON(moduleName, inputJSONString, LocalizationServiceDirectiveParsingMode.Ignore);\n    it('should work for iOS', () => {\n      const english = generateIOSLocalizableStringsFromStringsJSON(moduleName, undefined, baseEnglishJSON, 'en');\n      const russian = generateIOSLocalizableStringsFromStringsJSON(moduleName, baseEnglishJSON, inputJSON, 'ru');\n      expect(english).toMatchInlineSnapshot(`\n        \"\n        // BEGIN VALDI AUTOGENERATED see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md\n        \\\"some_key\\\" = \\\"Sent $0 out of $1 total items\\\";\n        \"\n      `);\n      expect(russian).toMatchInlineSnapshot(`\n        \"\n        // BEGIN VALDI AUTOGENERATED see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md\n        \\\"some_key\\\" = \\\"Из $1 штук уже отправлено $0\\\";\n        \"\n      `);\n    });\n\n    it('should work for Android', async () => {\n      const english = await generateAndroidStringsXMLFromStringsJSON(moduleName, undefined, baseEnglishJSON, 'en');\n      const russian = await generateAndroidStringsXMLFromStringsJSON(moduleName, baseEnglishJSON, inputJSON, 'ru');\n      expect(english).toMatchInlineSnapshot(`\n        \"<?xml version=\"1.0\" encoding=\"UTF-8\"?><resources>\n            <!-- VALDI GENERATED STRINGS, see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md -->\n            <string name=\"empty_module_some_key\">Sent $0 out of $1 total items</string>\n        </resources>\n        \"\n      `);\n      expect(russian).toMatchInlineSnapshot(`\n        \"<?xml version=\"1.0\" encoding=\"UTF-8\"?><resources>\n            <!-- VALDI GENERATED STRINGS, see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md -->\n            <string name=\"empty_module_some_key\">Из $1 штук уже отправлено $0</string>\n        </resources>\n        \"\n      `);\n    });\n  });\n\n  describe('silly private_profile strings.json with xml entities', () => {\n    const moduleName = 'private_profile';\n    const baseEnglishJSONString = `\n{\n    \"friendBirthdayPillDialogSubBodyTimeDiffFuture\": {\n      \"defaultMessage\": \"That's only <b>{numberOfDays} days</b> away!\"\n    },\n    \"friendmojiPillDialogBFF\": {\n      \"defaultMessage\": \"You and {friendFirstName} have been each other’s #1 Best Friend\\\\nfor <b>2 weeks in a row</b>!\"\n    },\n    \"friendmojiPillDialogSuperBFF\": {\n      \"defaultMessage\": \"You and {friendFirstName} have been each other’s #1 Best Friend\\\\nfor <b>2 months in a row</b>!\"\n    }\n}\n`;\n\n    const inputJSONString = `\n{\n  \"friendBirthdayPillDialogSubBodyTimeDiffFuture\": {\n    \"defaultMessage\": \"¡Solo faltan \\u003cb\\u003e{numberOfDays}\\u0026nbsp;días\\u003c/b\\u003e!\"\n  },\n  \"friendmojiPillDialogBFF\": {\n    \"defaultMessage\": \"Tu e {friendFirstName} são o Melhor Amigo N.\\u0026ordm; 1 um do outro\\\\nhá \\u003cb\\u003e2 semanas seguidas\\u003c/b\\u003e!\"\n  },\n  \"friendmojiPillDialogSuperBFF\": {\n    \"defaultMessage\": \"Vos y {friendFirstName} fueron mejores amigos n.\\u0026deg;\\u0026nbsp;1\\\\ndurante \\u003cb\\u003edos meses seguidos\\u003c/b\\u003e.\"\n  }\n}\n`;\n    const baseEnglishJSON = parseStringsJSON(\n      moduleName,\n      baseEnglishJSONString,\n      LocalizationServiceDirectiveParsingMode.Ignore,\n    );\n    const inputJSON = parseStringsJSON(moduleName, inputJSONString, LocalizationServiceDirectiveParsingMode.Ignore);\n    it('should work for iOS', () => {\n      const esAR = generateIOSLocalizableStringsFromStringsJSON(moduleName, baseEnglishJSON, inputJSON, 'es-AR');\n      expect(esAR).toMatchInlineSnapshot(`\n        \"\n        // BEGIN VALDI AUTOGENERATED see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md\n        \\\"friendBirthdayPillDialogSubBodyTimeDiffFuture\\\" = \\\"¡Solo faltan <b>$0 días</b>!\\\";\n        \\\"friendmojiPillDialogBFF\\\" = \\\"Tu e $0 são o Melhor Amigo N.º 1 um do outro\n        há <b>2 semanas seguidas</b>!\\\";\n        \\\"friendmojiPillDialogSuperBFF\\\" = \\\"Vos y $0 fueron mejores amigos n.° 1\n        durante <b>dos meses seguidos</b>.\\\";\n        \"\n      `);\n    });\n\n    it('should work for Android', async () => {\n      const esAR = await generateAndroidStringsXMLFromStringsJSON(moduleName, baseEnglishJSON, inputJSON, 'es-AR');\n      expect(esAR).toMatchInlineSnapshot(`\n        \"<?xml version=\"1.0\" encoding=\"UTF-8\"?><resources>\n            <!-- VALDI GENERATED STRINGS, see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md -->\n            <string name=\"private_profile_friendBirthdayPillDialogSubBodyTimeDiffFuture\">¡Solo faltan &lt;b&gt;$0 días&lt;/b&gt;!</string>\n            <string name=\"private_profile_friendmojiPillDialogBFF\">Tu e $0 são o Melhor Amigo N.º 1 um do outro\n        há &lt;b&gt;2 semanas seguidas&lt;/b&gt;!</string>\n            <string name=\"private_profile_friendmojiPillDialogSuperBFF\">Vos y $0 fueron mejores amigos n.° 1\n        durante &lt;b&gt;dos meses seguidos&lt;/b&gt;.</string>\n        </resources>\n        \"\n      `);\n    });\n  });\n\n  describe('empty strings.json', () => {\n    const moduleName = 'empty_module';\n    const emptyStringsJSON = parseStringsJSON(moduleName, '{}', LocalizationServiceDirectiveParsingMode.Ignore);\n    it('should not output any iOS strings', () => {\n      const ios = generateIOSLocalizableStringsFromStringsJSON(moduleName, undefined, emptyStringsJSON, 'en');\n      expect(ios).toBe(\n        '\\n// BEGIN VALDI AUTOGENERATED see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md\\n\\n',\n      );\n    });\n\n    it('should not output any Android strings', async () => {\n      const android = await generateAndroidStringsXMLFromStringsJSON(moduleName, undefined, emptyStringsJSON, 'en');\n      expect(android).toBe(\n        `<?xml version=\"1.0\" encoding=\"UTF-8\"?><resources>\n    <!-- VALDI GENERATED STRINGS, see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md -->\n\n</resources>\n`,\n      );\n    });\n  });\n\n  describe('strings.json with duplicate ios_key values', () => {\n    // We want to kill the ability to specify custom ios_key values,\n    // but since we currently support it we should guard against misuse\n    const moduleName = 'test_module';\n    const stringsJSONWithDupeIOSKeys = `{\n      \"first\": {\n        \"defaultMessage\": \"Good morning\",\n        \"iosKey\": \"some_ios_key\"\n      },\n      \"second\": {\n        \"defaultMessage\": \"Another good morning\",\n        \"iosKey\": \"some_ios_key\"\n      }\n    }`;\n\n    it('should be ignored on iOS', () => {\n      const parsedStringsJSON = parseStringsJSON(\n        moduleName,\n        stringsJSONWithDupeIOSKeys,\n        LocalizationServiceDirectiveParsingMode.Ignore,\n      );\n\n      const result = generateIOSLocalizableStringsFromStringsJSON(moduleName, undefined, parsedStringsJSON, 'en');\n      expect(result).toMatchInlineSnapshot(`\n        \"\n        // BEGIN VALDI AUTOGENERATED see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md\n        \\\"first\\\" = \\\"Good morning\\\";\n        \\\"second\\\" = \\\"Another good morning\\\";\n        \"\n      `);\n    });\n\n    it('should not fail for Android', async () => {\n      const parsedStringsJSON = parseStringsJSON(\n        moduleName,\n        stringsJSONWithDupeIOSKeys,\n        LocalizationServiceDirectiveParsingMode.Ignore,\n      );\n\n      const result = await generateAndroidStringsXMLFromStringsJSON(\n        moduleName,\n        undefined,\n        parsedStringsJSON,\n\n        'en',\n      );\n      expect(result).toMatchInlineSnapshot(`\n        \"<?xml version=\"1.0\" encoding=\"UTF-8\"?><resources>\n            <!-- VALDI GENERATED STRINGS, see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md -->\n            <string name=\"test_module_first\">Good morning</string>\n            <string name=\"test_module_second\">Another good morning</string>\n        </resources>\n        \"\n      `);\n    });\n  });\n\n  describe('strings.json with whitespace', () => {\n    const moduleName = 'test_module';\n    const stringsJSONWithWhiteSpace = `{\n      \"first_key\": {\n        \"defaultMessage\": \"   FIRST!!!!\"\n      },\n      \"second_key\": {\n        \"defaultMessage\": \"SECOND!!!!   \"\n      },\n      \"third_key\": {\n        \"defaultMessage\": \"third\\\\n\"\n      },\n      \"fourth\": {\n        \"defaultMessage\": \"fourth \\\\t\"\n      }\n    }`;\n\n    it('should succeed for iOS', () => {\n      const parsedStringsJSON = parseStringsJSON(\n        moduleName,\n        stringsJSONWithWhiteSpace,\n        LocalizationServiceDirectiveParsingMode.Ignore,\n      );\n\n      const result = generateIOSLocalizableStringsFromStringsJSON(moduleName, undefined, parsedStringsJSON, 'en');\n      expect(result).toMatchInlineSnapshot(`\n        \"\n        // BEGIN VALDI AUTOGENERATED see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md\n        \\\"first_key\\\" = \\\"   FIRST!!!!\\\";\n        \\\"fourth\\\" = \\\"fourth \t\\\";\n        \\\"second_key\\\" = \\\"SECOND!!!!   \\\";\n        \\\"third_key\\\" = \\\"third\n        \\\";\n        \"\n      `);\n    });\n\n    it('should work for Android', async () => {\n      const parsedStringsJSON = parseStringsJSON(\n        moduleName,\n        stringsJSONWithWhiteSpace,\n        LocalizationServiceDirectiveParsingMode.Ignore,\n      );\n\n      const result = await generateAndroidStringsXMLFromStringsJSON(moduleName, undefined, parsedStringsJSON, 'en');\n      expect(result).toMatchInlineSnapshot(`\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><resources>\n            <!-- VALDI GENERATED STRINGS, see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md -->\n            <string name=\\\"test_module_first_key\\\">   FIRST!!!!</string>\n            <string name=\\\"test_module_fourth\\\">fourth \t</string>\n            <string name=\\\"test_module_second_key\\\">SECOND!!!!   </string>\n            <string name=\\\"test_module_third_key\\\">third\n        </string>\n        </resources>\n        \"\n      `);\n    });\n  });\n\n  describe('strings.json with duplicate keys', () => {\n    // We use JSON.parse, which doesn't let us validate against duplicate keys.\n    // What ends up happening is the later instance wins.\n    //\n    // Ideally, we'd introdue a JSON string validation stage, but I don't want\n    // to pay the cost of yet another npm dependency just yet... But adding a test to capture\n    // the current behaviour and detect any changes in it in the future.\n    const moduleName = 'test_module';\n    const stringsJSONWithDupeKeys = `{\n      \"first_key\": {\n        \"defaultMessage\": \"FIRST!!!!\"\n      },\n      \"second_key\": {\n        \"defaultMessage\": \"SECOND!!!!\"\n      },\n      \"first_key\": {\n        \"defaultMessage\": \"another first\"\n      }\n    }`;\n\n    it('should succeed for iOS', () => {\n      const parsedStringsJSON = parseStringsJSON(\n        moduleName,\n        stringsJSONWithDupeKeys,\n        LocalizationServiceDirectiveParsingMode.Ignore,\n      );\n\n      const result = generateIOSLocalizableStringsFromStringsJSON(moduleName, undefined, parsedStringsJSON, 'en');\n      expect(result).toMatchInlineSnapshot(`\n        \"\n        // BEGIN VALDI AUTOGENERATED see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md\n        \\\"first_key\\\" = \\\"another first\\\";\n        \\\"second_key\\\" = \\\"SECOND!!!!\\\";\n        \"\n      `);\n    });\n\n    it('should fail for Android', async () => {\n      const parsedStringsJSON = parseStringsJSON(\n        moduleName,\n        stringsJSONWithDupeKeys,\n        LocalizationServiceDirectiveParsingMode.Ignore,\n      );\n\n      const result = await generateAndroidStringsXMLFromStringsJSON(moduleName, undefined, parsedStringsJSON, 'en');\n      expect(result).toMatchInlineSnapshot(`\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><resources>\n            <!-- VALDI GENERATED STRINGS, see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md -->\n            <string name=\\\"test_module_first_key\\\">another first</string>\n            <string name=\\\"test_module_second_key\\\">SECOND!!!!</string>\n        </resources>\n        \"\n      `);\n    });\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/strings/GenerateStringsFiles.ts",
    "content": "import { readFile } from 'fs/promises';\nimport {\n  compareKeys,\n  escapeForAndroidXML,\n  formatForIOSLocalizableStrings,\n  hack_privateProfile_replaceXMLEntities,\n  messageToFormat,\n} from './utils';\n\ninterface StringsJSONRecord {\n  defaultMessage: string;\n  description?: string;\n  example?: string;\n}\n\ninterface GenerateStringsJSONResult {\n  [key: string]: StringsJSONRecord;\n}\n\nexport enum LocalizationServiceDirectiveParsingMode {\n  Ignore,\n  Require,\n}\n\ntype _iOSKey = string;\ntype _AndroidKey = string;\n\ninterface LocalizableKeyPath {\n  moduleName: string;\n  key: string;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n//\n// Parsing existing strings.yaml\n//\n///////////////////////////////////////////////////////////////////////////////\n\nexport async function parseStringsJSONAtPath(\n  moduleName: string,\n  path: string,\n  l10nsvcDirectiveParsingMode: LocalizationServiceDirectiveParsingMode,\n) {\n  const fileContents = await readFile(path);\n  const stringsJSON = parseStringsJSON(moduleName, fileContents.toString(), l10nsvcDirectiveParsingMode);\n  return stringsJSON;\n}\n\nexport function parseStringsJSON(\n  moduleName: string,\n  fileContent: string,\n  l10nsvcDirectiveMode: LocalizationServiceDirectiveParsingMode,\n) {\n  const parsed = JSON.parse(fileContent);\n  // Snap-specific: a \"l10nsvc\": \"sourcefile\" key/value pair is used as an annotation required by the Snap Localization Service:\n  // We ignore it when processing the strings.json file\n  const keyToIgnore = 'l10nsvc';\n  if (parsed.hasOwnProperty(keyToIgnore)) {\n    delete parsed[keyToIgnore];\n  } else {\n    switch (l10nsvcDirectiveMode) {\n      case LocalizationServiceDirectiveParsingMode.Ignore:\n        break;\n      case LocalizationServiceDirectiveParsingMode.Require:\n        throw new Error(\n          `Expected l10nsvc directive not found in strings.json for ${moduleName}.\\n\\n ⚠️ ⚠️ ⚠️\\nPlease update ${moduleName}'s strings-en.json to include a \"l10nsvc\": \"sourcefile\" key/value pair.\\n ⚠️ ⚠️ ⚠️\\n`,\n        );\n    }\n  }\n\n  const ordered = sortStringsJSON(parsed);\n  return ordered;\n}\n\nfunction sortStringsJSON(stringsJSON: GenerateStringsJSONResult): GenerateStringsJSONResult {\n  const ordered = Object.keys(stringsJSON)\n    .sort((l, r) => {\n      return compareKeys(l, r);\n    })\n    .reduce((obj, key) => {\n      obj[key] = stringsJSON[key];\n      return obj;\n    }, {} as GenerateStringsJSONResult);\n  return ordered;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n//\n// Generating Android strings.xml\n//\n///////////////////////////////////////////////////////////////////////////////\n\nexport async function generateAndroidStringsXMLFromStringsJSON(\n  moduleName: string,\n  baseEnglishStringsJSON: GenerateStringsJSONResult | undefined,\n  inputStringsJSON: GenerateStringsJSONResult,\n  stringsJSONLocale: string,\n): Promise<string> {\n  if (!baseEnglishStringsJSON && stringsJSONLocale !== 'en') {\n    throw new Error('Must provide base English strings JSON when generating Android strings for a translation');\n  }\n\n  const indent = `    `;\n\n  const header = `<?xml version=\"1.0\" encoding=\"UTF-8\"?><resources>`;\n\n  const prelude = `${header}\n${indent}<!-- VALDI GENERATED STRINGS, see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md -->`;\n  // TODO: ^ IMO we should add the Valdi module name to this comment (and maybe a link to the Valdi module in the client repo)\n  //         but the export_strings.py does not do this currently\n\n  const postlude = `</resources>\\n`;\n\n  let encounteredKeyMap = new Map<_AndroidKey, LocalizableKeyPath>();\n  let contents: [string, string][] = [];\n  for (const key in inputStringsJSON) {\n    const record = inputStringsJSON[key];\n    let comment = '';\n    if (record.description) {\n      // TODO: comment should include the example and should be sanitized\n      const cleanedComment = record.description;\n      comment = `<!-- ${cleanedComment} -->\\n`;\n    }\n    // TODO: should emit the comment too, but export_strings.py currently doesn't\n\n    // Note: we are _intentionally_ not using record.androidKey here. That is the current behaviour of export_strings.py.\n    //       With this migration we can remove all usages of android_key.\n    const jsKey = `${moduleName}_${key}`;\n    const cleanedKey = jsKey;\n\n    guardAgainstEmittingDuplicateKeys({ moduleName, key }, cleanedKey, encounteredKeyMap);\n\n    let baseEnglishRecord = baseEnglishStringsJSON && baseEnglishStringsJSON[key];\n    if (!baseEnglishRecord) {\n      if (stringsJSONLocale !== 'en') {\n        // Base (English) strings JSON doesn't have the same key as what we're trying to export\n        // from the translation.\n        //\n        // Skipping.\n        continue;\n      }\n      baseEnglishRecord = record;\n    }\n\n    const format = messageToFormat(baseEnglishRecord.defaultMessage, record.defaultMessage);\n    // HACK: some translated strings JSON files in private_profile include XML entities...\n    const hackedFormat = hack_privateProfile_replaceXMLEntities(format);\n    const cleanedFormat = await escapeForAndroidXML(hackedFormat, stringsJSONLocale);\n\n    let formatted = '';\n    // HACK: this reproduces an existing bug in export_strings.py where we look at the resulting format\n    //       I'm not currently sure _when_ we should actually specify formatted=\"false\", so just reproducing quirk-for-quirk\n    if (cleanedFormat.indexOf('%') >= 0) {\n      formatted = ' formatted=\"false\"';\n    }\n\n    const line = `<string name=\"${cleanedKey}\"${formatted}>${cleanedFormat}</string>`;\n    contents.push([cleanedKey, line]);\n  }\n\n  const sortedContents = contents\n    .sort(([lkey], [rkey]) => {\n      return compareKeys(lkey, rkey);\n    })\n    .map(([key, line]) => {\n      return line;\n    });\n\n  const prettyContents = sortedContents.map((line) => `${indent}${line}`).join('\\n');\n  return `${prelude}\n${prettyContents}\n${postlude}`;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n//\n// Generating iOS Localizable.strings\n//\n///////////////////////////////////////////////////////////////////////////////\n\nexport function generateIOSLocalizableStringsFromStringsJSON(\n  moduleName: string,\n  baseEnglishStringsJSON: GenerateStringsJSONResult | undefined,\n  inputStringsJSON: GenerateStringsJSONResult,\n  stringsJSONLocale: string,\n): string {\n  if (!baseEnglishStringsJSON && stringsJSONLocale !== 'en') {\n    throw new Error('Must provide base English strings JSON when generating iOS strings for a translation');\n  }\n\n  const prelude = `\n// BEGIN VALDI AUTOGENERATED see https://github.com/Snapchat/Valdi/blob/main/docs/docs/advanced-localization.md`;\n  // TODO: ^ l10nscv comment should be on the next line, but the export_strings.py does not do this currently\n  //\n  // TODO: ^ IMO we should add the Valdi module name to this comment (and maybe a link to the Valdi module in the client repo)\n  //         but the export_strings.py does not do this currently\n\n  const postlude = ``;\n  // TODO: ^ // END VALDI AUTOGENERATED, but the export_strings.py does not do this currently\n\n  let encounteredKeyMap = new Map<_iOSKey, LocalizableKeyPath>();\n  let contents: [string, string][] = [];\n  for (const key in inputStringsJSON) {\n    const record = inputStringsJSON[key];\n    let comment = '';\n    if (record.description) {\n      // TODO: comment should include the example and should be sanitized\n      const cleanedComment = record.description;\n      comment = `/* ${cleanedComment} */`;\n    }\n    // TODO: should emit the comment too, but the export_strings.py does not do this currently\n\n    guardAgainstEmittingDuplicateKeys({ moduleName, key }, key, encounteredKeyMap);\n\n    let baseEnglishRecord = baseEnglishStringsJSON && baseEnglishStringsJSON[key];\n    if (!baseEnglishRecord) {\n      if (stringsJSONLocale !== 'en') {\n        // Base (English) strings JSON doesn't have the same key as what we're trying to export\n        // from the translation.\n        //\n        // Skipping.\n        continue;\n      }\n      baseEnglishRecord = record;\n    }\n\n    const format = messageToFormat(baseEnglishRecord.defaultMessage, record.defaultMessage);\n    // HACK: some translated strings JSON files in private_profile include XML entities...\n    const hackedFormat = hack_privateProfile_replaceXMLEntities(format);\n    const cleanedFormat = formatForIOSLocalizableStrings(hackedFormat);\n\n    // TODO: should emit the comment too, but the export_strings.py does not do this currently\n    const line = `\"${key}\" = \"${cleanedFormat}\";`;\n    contents.push([key, line]);\n  }\n\n  const sortedContents = contents\n    .sort(([lkey], [rkey]) => {\n      return compareKeys(lkey, rkey);\n    })\n    .map(([key, line]) => {\n      return line;\n    });\n\n  const prettyContents = sortedContents.join('\\n');\n  return `${prelude}\n${prettyContents}\n${postlude}`;\n}\n\n///////////////////////////////////////////////////////////////////////////////\n//\n// Internal utilities\n//\n///////////////////////////////////////////////////////////////////////////////\n\nfunction guardAgainstEmittingDuplicateKeys(\n  current: LocalizableKeyPath,\n  generatedPlatformKey: _iOSKey | _AndroidKey,\n  encounteredKeyMap: Map<_iOSKey | _AndroidKey, LocalizableKeyPath>,\n) {\n  const previouslyEncountered = encounteredKeyMap.get(generatedPlatformKey);\n  if (previouslyEncountered) {\n    throw new Error(\n      `Platform string key ${generatedPlatformKey} already encountered. Currently processing module: ${current.moduleName} key: ${current.key}. Previously encountered in module: ${previouslyEncountered.moduleName} key: ${previouslyEncountered.key}`,\n    );\n  }\n  encounteredKeyMap.set(generatedPlatformKey, current);\n}\n"
  },
  {
    "path": "compiler/companion/src/strings/exportStringsFiles.ts",
    "content": "///////////////////////////////////////////////////////////////////////////////\n//\n// Command\n//\n///////////////////////////////////////////////////////////////////////////////\n\nimport { fullLocaleMap } from '../../supported-locales/out';\nimport { mkdir, unlink, writeFile } from 'fs/promises';\nimport * as path from 'path';\nimport { ILogger } from '../logger/ILogger';\nimport { ExportTranslationStringsRequestBody, ExportTranslationStringsResponseBody } from '../protocol';\nimport { fileExists } from '../utils/fileUtils';\nimport {\n  generateAndroidStringsXMLFromStringsJSON,\n  generateIOSLocalizableStringsFromStringsJSON,\n  LocalizationServiceDirectiveParsingMode,\n  parseStringsJSONAtPath,\n} from './GenerateStringsFiles';\n\nexport async function exportStringsFiles(\n  moduleName: string,\n  inputStringsDir: string,\n  iosOutputPath?: string,\n  androidOutputPath?: string,\n) {\n  const exists = await fileExists(inputStringsDir);\n  if (!exists) {\n    throw new Error(`Expected strings directory at ${inputStringsDir}, but it doesn't exist`);\n  }\n\n  if (!iosOutputPath && !androidOutputPath) {\n    throw new Error('Asked to export strings, but no output paths provided');\n  }\n\n  const promises = [];\n\n  let localeMap = fullLocaleMap;\n  for (const inputLocale of localeMap.keys()) {\n    const outputLocales = localeMap.get(inputLocale);\n    if (!outputLocales) {\n      throw new Error(`No known output locales for input locale ${inputLocale}`);\n    }\n\n    const baseStringsJSONPath = inputJSONPath(inputStringsDir, 'en');\n\n    const inputStringsJSONPath = inputJSONPath(inputStringsDir, inputLocale);\n    const outputIOSLocalizableStringsPath =\n      iosOutputPath && iosLocalizableStringsPath(iosOutputPath, outputLocales.ios, moduleName);\n    const outputAndroidStringsXMLPath =\n      androidOutputPath && androidStringsXMLPath(androidOutputPath, outputLocales.android, moduleName);\n\n    const promise = exportStringsFile(\n      moduleName,\n      inputLocale,\n      baseStringsJSONPath,\n      inputStringsJSONPath,\n      outputIOSLocalizableStringsPath,\n      outputAndroidStringsXMLPath,\n    ).catch((reason) => {\n      throw new Error(`Failed to export strings file for module '${moduleName}': ${reason}`);\n    });\n    promises.push(promise);\n  }\n\n  await Promise.all(promises);\n}\n\nasync function exportStringsFile(\n  moduleName: string,\n  inputLocale: string,\n  baseStringsJSONPath: string,\n  inputStringsJSONPath: string,\n  outputIOSLocalizableStringsPath: string | undefined,\n  outputAndroidStringsXMLPath: string | undefined,\n) {\n  const isExportingBaseLocale = inputLocale === 'en';\n\n  // Translation happens in the repo with the valdi_modules sources.\n\n  const exists = await fileExists(inputStringsJSONPath);\n  if (!exists) {\n    if (isExportingBaseLocale) {\n      throw new Error(`Expected base localization file at ${inputStringsJSONPath}, but it doesn't exist`);\n    } else {\n      // Translation file for that locale doesn't exist\n      return;\n    }\n  }\n\n  const baseEnglishStringsJSON = await parseStringsJSONAtPath(\n    moduleName,\n    baseStringsJSONPath,\n    LocalizationServiceDirectiveParsingMode.Ignore,\n  );\n  let l10nsvcDirectiveParsingMode = LocalizationServiceDirectiveParsingMode.Ignore;\n  if (isExportingBaseLocale) {\n    l10nsvcDirectiveParsingMode = LocalizationServiceDirectiveParsingMode.Require;\n  }\n  const inputStringsJSON = await parseStringsJSONAtPath(moduleName, inputStringsJSONPath, l10nsvcDirectiveParsingMode);\n  if (outputAndroidStringsXMLPath) {\n    await unlink(outputAndroidStringsXMLPath).catch((e) => undefined); // ignore errors\n    const androidOutput = await generateAndroidStringsXMLFromStringsJSON(\n      moduleName,\n      baseEnglishStringsJSON,\n      inputStringsJSON,\n      inputLocale,\n    );\n    if (androidOutput) {\n      const dirname = path.dirname(outputAndroidStringsXMLPath);\n      await mkdir(dirname, { recursive: true });\n      await writeFile(outputAndroidStringsXMLPath, androidOutput);\n    }\n  }\n\n  if (outputIOSLocalizableStringsPath) {\n    await unlink(outputIOSLocalizableStringsPath).catch((e) => undefined); // ignore errors\n    const iosOutput = generateIOSLocalizableStringsFromStringsJSON(\n      moduleName,\n      baseEnglishStringsJSON,\n      inputStringsJSON,\n      inputLocale,\n    );\n    if (iosOutput) {\n      const dirname = path.dirname(outputIOSLocalizableStringsPath);\n      await mkdir(dirname, { recursive: true });\n      await writeFile(outputIOSLocalizableStringsPath, iosOutput);\n    }\n  }\n}\n\nfunction stringsJSONName(locale: string): string {\n  return `strings-${locale}.json`;\n}\n\nfunction inputJSONPath(inputStringsDir: string, inputLocale: string) {\n  return path.join(inputStringsDir, stringsJSONName(inputLocale));\n}\n\nfunction iosLocalizableStringName(moduleName: string, outputLocale: string) {\n  return path.join(`${outputLocale}.lproj`, `valdi_modules_${moduleName}.strings`);\n}\n\nfunction iosLocalizableStringsPath(iosOutputPath: string, outputLocale: string, moduleName: string) {\n  return path.join(iosOutputPath, iosLocalizableStringName(moduleName, outputLocale));\n}\n\nfunction androidStringsXMLName(moduleName: string, outputLocale: string) {\n  let valuesDirname = `values-${outputLocale}`;\n  if (outputLocale === 'en') {\n    valuesDirname = 'values';\n  }\n  return path.join(valuesDirname, `valdi-strings-${moduleName}.xml`);\n}\n\nfunction androidStringsXMLPath(androidOutputPath: string, outputLocale: string, moduleName: string) {\n  return path.join(androidOutputPath, androidStringsXMLName(moduleName, outputLocale));\n}\n\nexport async function exportTranslationStrings(\n  request: ExportTranslationStringsRequestBody,\n  logger: ILogger | undefined,\n): Promise<ExportTranslationStringsResponseBody> {\n  const moduleName = request.moduleName;\n  if (!(await fileExists(request.baseLocaleStringsPath))) {\n    throw new Error(`Expected base localization file at ${request.baseLocaleStringsPath}, but it doesn't exist`);\n  }\n  if (!(await fileExists(request.inputLocaleStringsPath))) {\n    throw new Error(`Expected input localization file at ${request.inputLocaleStringsPath}, but it doesn't exist`);\n  }\n  if (path.basename(request.baseLocaleStringsPath) !== stringsJSONName('en')) {\n    throw new Error(\n      `Expected base localization file strings-en.json, but got ${path.basename(request.baseLocaleStringsPath)}`,\n    );\n  }\n\n  // Find input locale\n  const inputLocale = Array.from(fullLocaleMap.keys()).find((locale: string) => {\n    return stringsJSONName(locale) === path.basename(request.inputLocaleStringsPath);\n  });\n  if (!inputLocale) {\n    throw new Error(`Could not find input locale for ${request.inputLocaleStringsPath}`);\n  }\n\n  const outputLocales = fullLocaleMap.get(inputLocale);\n  if (!outputLocales) {\n    throw new Error(`No known output locales for input locale ${inputLocale}`);\n  }\n\n  const isExportingBaseLocale = inputLocale === 'en';\n  logger?.debug?.(\n    `Exporting translation strings for module ${moduleName} and locale ${inputLocale} for ${request.platform}`,\n  );\n\n  // Translation happens in the repo with the valdi_modules sources.\n\n  const baseLocaleStringsJSON = await parseStringsJSONAtPath(\n    moduleName,\n    request.baseLocaleStringsPath,\n    LocalizationServiceDirectiveParsingMode.Require,\n  );\n  const l10nsvcDirectiveParsingMode = isExportingBaseLocale\n    ? LocalizationServiceDirectiveParsingMode.Require\n    : LocalizationServiceDirectiveParsingMode.Ignore;\n  const inputLocaleJSON = await parseStringsJSONAtPath(\n    moduleName,\n    request.inputLocaleStringsPath,\n    l10nsvcDirectiveParsingMode,\n  );\n\n  if (request.platform === 'android') {\n    const androidOutput = await generateAndroidStringsXMLFromStringsJSON(\n      moduleName,\n      baseLocaleStringsJSON,\n      inputLocaleJSON,\n      inputLocale,\n    );\n\n    return {\n      inputLocale: inputLocale,\n      platformLocale: outputLocales.android,\n      content: androidOutput,\n      outputFileName: androidStringsXMLName(moduleName, outputLocales.android),\n    };\n  } else if (request.platform === 'ios') {\n    const iosOutput = generateIOSLocalizableStringsFromStringsJSON(\n      moduleName,\n      baseLocaleStringsJSON,\n      inputLocaleJSON,\n      inputLocale,\n    );\n\n    return {\n      inputLocale: inputLocale,\n      platformLocale: outputLocales.ios,\n      content: iosOutput,\n      outputFileName: iosLocalizableStringName(moduleName, outputLocales.ios),\n    };\n  } else {\n    throw new Error(`Unknown platform ${request.platform}`);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/strings/utils.spec.ts",
    "content": "import 'ts-jest';\nimport { escapeForAndroidXML, formatForIOSLocalizableStrings } from './utils';\n\nimport { messageToFormat } from './utils';\n\ndescribe('parsing message params', () => {\n  it('works with integer placeholder', () => {\n    const message = 'Field number {fieldNumber%d} is required.';\n    const format = messageToFormat(message, message);\n    expect(format).toBe('Field number $0 is required.');\n  });\n\n  it('works with string placeholder without specifier', () => {\n    const message = '{field} is required.';\n    const format = messageToFormat(message, message);\n    expect(format).toBe('$0 is required.');\n  });\n\n  it('works with string placeholder with specifier', () => {\n    const message = '{field%s} is required.';\n    const format = messageToFormat(message, message);\n    expect(format).toBe('$0 is required.');\n  });\n\n  it('works with multiple placeholders', () => {\n    const message = '{field1} and {field2} are required.';\n    const format = messageToFormat(message, message);\n    expect(format).toBe('$0 and $1 are required.');\n  });\n\n  it('works with multiple placeholders with the same name', () => {\n    const message =\n      'Snap will share the information entered above with {BrandName}. {BrandName} may also be able to infer that you are in the group of users to which the ad was targeted. {BrandName}’s use of this data is subject to their privacy policy.';\n    const format = messageToFormat(message, message);\n    expect(format).toBe(\n      'Snap will share the information entered above with $0. $0 may also be able to infer that you are in the group of users to which the ad was targeted. $0’s use of this data is subject to their privacy policy.',\n    );\n  });\n});\n\ndescribe('escapeForAndroidXML', () => {\n  it('handles less than', async () => {\n    const result = await escapeForAndroidXML('string with two < symbols <');\n    expect(result).toStrictEqual('string with two &lt; symbols &lt;');\n  });\n\n  it('handles greater than', async () => {\n    const result = await escapeForAndroidXML('string with two > symbols >');\n    expect(result).toStrictEqual('string with two &gt; symbols &gt;');\n  });\n\n  it('handles ampersand', async () => {\n    const result = await escapeForAndroidXML('string with two & symbols &');\n    expect(result).toStrictEqual('string with two &amp; symbols &amp;');\n  });\n\n  it('handles single quotes', async () => {\n    const result = await escapeForAndroidXML(\"string with two ' single ' quotes\");\n    expect(result).toStrictEqual(\"string with two \\\\' single \\\\' quotes\");\n  });\n\n  it('handles double quotes', async () => {\n    const result = await escapeForAndroidXML('string with two \" double \" quotes');\n    expect(result).toStrictEqual('string with two \" double \" quotes');\n  });\n\n  it('handles double quotes', async () => {\n    const result = await escapeForAndroidXML('string with two \" double \" quotes');\n    expect(result).toStrictEqual('string with two \" double \" quotes');\n  });\n\n  it('handles unicode', async () => {\n    const result = await escapeForAndroidXML('строчка с кириллицей · и · юникодом');\n    expect(result).toStrictEqual('строчка с кириллицей · и · юникодом');\n  });\n\n  it('handles escaped unicode', async () => {\n    const result = await escapeForAndroidXML('Remind on\\u0020');\n    expect(result).toStrictEqual('Remind on\\u0020');\n  });\n});\n\ndescribe('emojiToHTMLEntityForAndroidXML', () => {\n  it('handles emoji', async () => {\n    const result = await escapeForAndroidXML('Sadface 😞', 'en');\n    expect(result).toStrictEqual('Sadface &#128542;');\n  });\n\n  it('handles emoji then text', async () => {\n    const result = await escapeForAndroidXML('Apple 🍏 and some text, and some more text!', 'en');\n    expect(result).toStrictEqual('Apple &#127823; and some text, and some more text!');\n  });\n\n  it('handles emoji then unicode', async () => {\n    const result = await escapeForAndroidXML('Map 🗺️地图', 'zh-Hant');\n    expect(result).toStrictEqual('Map &#128506;&#65039;地图');\n  });\n\n  it('handles emoji then unicode then text', async () => {\n    const result = await escapeForAndroidXML('Red flag 🚩☝️ and some more things and stuff', 'en');\n    expect(result).toStrictEqual('Red flag &#128681;&#9757;&#65039; and some more things and stuff');\n  });\n\n  it('handles specific case', async () => {\n    const result = await escapeForAndroidXML('Add $0 to your Favorites?', 'en');\n    expect(result).toStrictEqual('Add $0 to your Favorites?');\n  });\n\n  it('handles speak no evil emoji', async () => {\n    const result = await escapeForAndroidXML('🙊', 'en');\n    expect(result).toStrictEqual('&#128586;');\n  });\n\n  describe(\"doesn't convert south asian scripts\", () => {\n    it('bn-BD', async () => {\n      // ad_format/strings/strings-bn-BD.json\n      // ad_info\n      const result = await escapeForAndroidXML('বিজ্ঞাপনের তথ্য', 'bn-BD');\n      expect(result).toStrictEqual('বিজ্ঞাপনের তথ্য');\n    });\n\n    it('ml-IN', async () => {\n      // account_challenge/strings/strings-ml-IN.json\n      // challenge_page_title\n      const result = await escapeForAndroidXML('പാസ്‍വേഡ് പുനഃസജ്ജീകരിക്കുക', 'bn-BD');\n      expect(result).toStrictEqual('പാസ്‍വേഡ് പുനഃസജ്ജീകരിക്കുക');\n    });\n  });\n\n  it('handles flowers', async () => {\n    const result = await escapeForAndroidXML('flowers 🌼🌺🌸', 'en');\n    expect(result).toStrictEqual('flowers &#127804;&#127802;&#127800;');\n  });\n\n  it('handles family emoji', async () => {\n    const result = await escapeForAndroidXML('this is a family 👩‍👩‍👧‍👧 with four people', 'en');\n    expect(result).toStrictEqual(\n      'this is a family &#128105;&#8205;&#128105;&#8205;&#128103;&#8205;&#128103; with four people',\n    );\n  });\n\n  it('handles emoji with skin tone', async () => {\n    const result = await escapeForAndroidXML('person 👩🏾', 'en');\n    expect(result).toStrictEqual('person &#128105;&#127998;');\n  });\n\n  it('handles emoji with ZWJ and skin tone', async () => {\n    const result = await escapeForAndroidXML('people 👩‍👩🏾', 'en');\n    expect(result).toStrictEqual('people &#128105;&#8205;&#128105;&#127998;');\n  });\n});\n\ndescribe('formatForIOSLocalizableStrings', () => {\n  it('handles single quotes', () => {\n    const result = formatForIOSLocalizableStrings(\"string with two ' single ' quotes\");\n    expect(result).toStrictEqual(\"string with two ' single ' quotes\");\n  });\n\n  it('handles double quotes', () => {\n    const result = formatForIOSLocalizableStrings('string with two \" double \" quotes');\n    expect(result).toStrictEqual('string with two \\\\\" double \\\\\" quotes');\n  });\n\n  it('handles unicode', () => {\n    const result = formatForIOSLocalizableStrings('строчка с кириллицей · и · юникодом');\n    expect(result).toStrictEqual('строчка с кириллицей · и · юникодом');\n  });\n\n  it('handles escaped unicode', () => {\n    const result = formatForIOSLocalizableStrings('Remind on\\u0020');\n    expect(result).toStrictEqual('Remind on ');\n  });\n});\n"
  },
  {
    "path": "compiler/companion/src/strings/utils.ts",
    "content": "const MESSAGE_PARAMS_REGEX = /({([a-zA-Z0-9_]+)(%.*?)?})/g;\n\nenum LocalizableParamType {\n  STRING,\n  INTEGER,\n}\ninterface LocalizableParam {\n  placeholder: string;\n  name: string;\n  type: LocalizableParamType;\n}\n\nfunction parseMessageParams(message: string) {\n  const params: LocalizableParam[] = [];\n  const seenParams = new Set<string>();\n\n  const matches = message.matchAll(MESSAGE_PARAMS_REGEX);\n  for (const match of matches) {\n    if (match.length == 0) {\n      continue;\n    }\n    const placeholder = match[1];\n    const name = match[2];\n\n    // Handles the same key being used more than once in the format\n    if (seenParams.has(name)) {\n      continue;\n    }\n    seenParams.add(name);\n\n    const format = match[3];\n    let type: LocalizableParamType;\n    if (!format || format === '' || format === '%s') {\n      type = LocalizableParamType.STRING;\n    } else if (format === '%d') {\n      type = LocalizableParamType.INTEGER;\n    } else {\n      throw new Error(`Unsupported format type: ${format}`);\n    }\n    const param: LocalizableParam = {\n      placeholder,\n      name,\n      type,\n    };\n    params.push(param);\n  }\n  return params;\n}\n\nexport function messageToFormat(baseEnglishMessage: string, localizedMessage: string) {\n  const baseEnglishParams = parseMessageParams(baseEnglishMessage);\n  const localizedMessageParams = parseMessageParams(localizedMessage);\n  if (baseEnglishParams.length !== localizedMessageParams.length) {\n    throw new Error(\n      `Number of placeholders in English string ${baseEnglishMessage} doesn't match the number of placeholders in localized string ${localizedMessage}`,\n    );\n  }\n\n  let i = 0;\n  for (const param of baseEnglishParams) {\n    let regexp = RegExp(param.placeholder, 'g');\n    localizedMessage = localizedMessage.replace(regexp, `$${i}`);\n    i += 1;\n  }\n  return localizedMessage;\n}\n\nexport function compareKeys(l: string, r: string) {\n  return l > r ? 1 : -1;\n}\n\nexport function formatForIOSLocalizableStrings(string: string) {\n  let result = string.replace(/\"/g, '\\\\\"').replace(/\\\\u0020/g, ' '); // Existing hack to allow spaces to be added at the beginning or end of the string\n  return result;\n}\n\n// HACK: some translate strings JSON files in private_profile include a limited set of XML\n//       entities.\n//\n// Doing this hack to ensure we're good before branch promo\nexport function hack_privateProfile_replaceXMLEntities(input: string) {\n  const result = input\n    .replace(/\\u0026nbsp;/g, '\\u00A0')\n    .replace(/\\u0026ordm;/g, 'º')\n    .replace(/\\u0026deg;/g, '°');\n  return result;\n}\n\nexport async function escapeForAndroidXML(string: string, lang: string = 'en') {\n  const segmenter = new Intl.Segmenter(lang, { granularity: 'grapheme' });\n  const segmentContainers = segmenter.segment(string);\n\n  let result = '';\n  for (const segmentContainer of segmentContainers) {\n    // A detailed explanation of this regex that is attempting to find just emoji and characters\n    // that aren't valid in XML\n    // [<>&'] - specific characters that cause problems in XML\n    // | - logical or\n    // Emoji-matching pattern (see https://github.com/tc39/proposal-regexp-unicode-property-escapes#matching-emoji)\n    const regex = /[<>&']|(\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F)/gu;\n    if (!segmentContainer.segment.match(regex)) {\n      result += segmentContainer.segment;\n      continue;\n    }\n\n    let codepoints = '';\n    for (const element of segmentContainer.segment) {\n      codepoints += _escapeForAndroidXML(element);\n    }\n    result += codepoints;\n  }\n  return result;\n}\n\nfunction _escapeForAndroidXML(c: string) {\n  switch (c) {\n    case '<':\n      return '&lt;';\n    case '>':\n      return '&gt;';\n    case '&':\n      return '&amp;';\n    case \"'\":\n      // TODO: IMO should replace with &apos, but export_strings.py does _this_ currently\n      return \"\\\\'\";\n    // TODO: IMO should replace quotes too, but export_strings.py does not do this currently\n    // case '\"':\n    //   return '&quot;';\n    default:\n      return '&#' + c.codePointAt(0) + ';';\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/tslibs/.gitattributes",
    "content": "tslibs.json linguist-vendored\n"
  },
  {
    "path": "compiler/companion/src/tslibs/GenerateTSLibs.ts",
    "content": "import { forEachFile } from '../utils/fileUtils';\nimport path = require('path');\nimport fs = require('fs');\nimport { DB_FILENAME, TSLibEntry } from './TSLibsDatabase';\n\nconst INPUT_DIRECTORY = path.resolve(__dirname, '../../node_modules/typescript/lib');\nconst OUTPUT_DIRECTORY = path.resolve(__dirname);\nconst OUTPUT_FILE = path.join(OUTPUT_DIRECTORY, DB_FILENAME);\n\nasync function generateTSLibEntry(inputDirectory: string, filePath: string): Promise<TSLibEntry> {\n  const fileContent = await fs.promises.readFile(filePath, 'utf-8');\n  return {\n    fileName: path.relative(inputDirectory, filePath),\n    content: fileContent,\n  };\n}\n\nexport async function generateTSLibsFile(): Promise<void> {\n  const entryPromises: Promise<TSLibEntry>[] = [];\n  await forEachFile(INPUT_DIRECTORY, (filePath) => {\n    const fileName = path.basename(filePath);\n    if (fileName.startsWith('lib.') && fileName.endsWith('.d.ts')) {\n      entryPromises.push(generateTSLibEntry(INPUT_DIRECTORY, filePath));\n    }\n  });\n\n  const entries = await Promise.all(entryPromises);\n  entries.sort((l, r) => l.fileName.localeCompare(r.fileName));\n\n  const json = JSON.stringify(entries, null, 2);\n\n  if (fs.existsSync(OUTPUT_FILE)) {\n    await fs.promises.rm(OUTPUT_FILE);\n  }\n\n  await fs.promises.writeFile(OUTPUT_FILE, json);\n}\n\ngenerateTSLibsFile();\n"
  },
  {
    "path": "compiler/companion/src/tslibs/TSLibsDatabase.ts",
    "content": "export interface TSLibEntry {\n  fileName: string;\n  content: string;\n}\n\nexport const DB_FILENAME = 'tslibs.json';\n\nlet sharedInstance: TSLibsDatabase | undefined;\n\nexport class TSLibsDatabase {\n  constructor(readonly entries: TSLibEntry[]) {}\n\n  static get(): TSLibsDatabase {\n    if (!sharedInstance) {\n      sharedInstance = new TSLibsDatabase(require('./tslibs.json') as TSLibEntry[]);\n    }\n\n    return sharedInstance;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/tslibs/tslibs.json",
    "content": "[\n  {\n    \"fileName\": \"lib.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es5\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.decorators.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/**\\n * The decorator context types provided to class element decorators.\\n */\\ntype ClassMemberDecoratorContext =\\n    | ClassMethodDecoratorContext\\n    | ClassGetterDecoratorContext\\n    | ClassSetterDecoratorContext\\n    | ClassFieldDecoratorContext\\n    | ClassAccessorDecoratorContext;\\n\\n/**\\n * The decorator context types provided to any decorator.\\n */\\ntype DecoratorContext =\\n    | ClassDecoratorContext\\n    | ClassMemberDecoratorContext;\\n\\ntype DecoratorMetadataObject = Record<PropertyKey, unknown> & object;\\n\\ntype DecoratorMetadata = typeof globalThis extends { Symbol: { readonly metadata: symbol; }; } ? DecoratorMetadataObject : DecoratorMetadataObject | undefined;\\n\\n/**\\n * Context provided to a class decorator.\\n * @template Class The type of the decorated class associated with this context.\\n */\\ninterface ClassDecoratorContext<\\n    Class extends abstract new (...args: any) => any = abstract new (...args: any) => any,\\n> {\\n    /** The kind of element that was decorated. */\\n    readonly kind: \\\"class\\\";\\n\\n    /** The name of the decorated class. */\\n    readonly name: string | undefined;\\n\\n    /**\\n     * Adds a callback to be invoked after the class definition has been finalized.\\n     *\\n     * @example\\n     * ```ts\\n     * function customElement(name: string): ClassDecoratorFunction {\\n     *   return (target, context) => {\\n     *     context.addInitializer(function () {\\n     *       customElements.define(name, this);\\n     *     });\\n     *   }\\n     * }\\n     *\\n     * @customElement(\\\"my-element\\\")\\n     * class MyElement {}\\n     * ```\\n     */\\n    addInitializer(initializer: (this: Class) => void): void;\\n\\n    readonly metadata: DecoratorMetadata;\\n}\\n\\n/**\\n * Context provided to a class method decorator.\\n * @template This The type on which the class element will be defined. For a static class element, this will be\\n * the type of the constructor. For a non-static class element, this will be the type of the instance.\\n * @template Value The type of the decorated class method.\\n */\\ninterface ClassMethodDecoratorContext<\\n    This = unknown,\\n    Value extends (this: This, ...args: any) => any = (this: This, ...args: any) => any,\\n> {\\n    /** The kind of class element that was decorated. */\\n    readonly kind: \\\"method\\\";\\n\\n    /** The name of the decorated class element. */\\n    readonly name: string | symbol;\\n\\n    /** A value indicating whether the class element is a static (`true`) or instance (`false`) element. */\\n    readonly static: boolean;\\n\\n    /** A value indicating whether the class element has a private name. */\\n    readonly private: boolean;\\n\\n    /** An object that can be used to access the current value of the class element at runtime. */\\n    readonly access: {\\n        /**\\n         * Determines whether an object has a property with the same name as the decorated element.\\n         */\\n        has(object: This): boolean;\\n        /**\\n         * Gets the current value of the method from the provided object.\\n         *\\n         * @example\\n         * let fn = context.access.get(instance);\\n         */\\n        get(object: This): Value;\\n    };\\n\\n    /**\\n     * Adds a callback to be invoked either before static initializers are run (when\\n     * decorating a `static` element), or before instance initializers are run (when\\n     * decorating a non-`static` element).\\n     *\\n     * @example\\n     * ```ts\\n     * const bound: ClassMethodDecoratorFunction = (value, context) {\\n     *   if (context.private) throw new TypeError(\\\"Not supported on private methods.\\\");\\n     *   context.addInitializer(function () {\\n     *     this[context.name] = this[context.name].bind(this);\\n     *   });\\n     * }\\n     *\\n     * class C {\\n     *   message = \\\"Hello\\\";\\n     *\\n     *   @bound\\n     *   m() {\\n     *     console.log(this.message);\\n     *   }\\n     * }\\n     * ```\\n     */\\n    addInitializer(initializer: (this: This) => void): void;\\n\\n    readonly metadata: DecoratorMetadata;\\n}\\n\\n/**\\n * Context provided to a class getter decorator.\\n * @template This The type on which the class element will be defined. For a static class element, this will be\\n * the type of the constructor. For a non-static class element, this will be the type of the instance.\\n * @template Value The property type of the decorated class getter.\\n */\\ninterface ClassGetterDecoratorContext<\\n    This = unknown,\\n    Value = unknown,\\n> {\\n    /** The kind of class element that was decorated. */\\n    readonly kind: \\\"getter\\\";\\n\\n    /** The name of the decorated class element. */\\n    readonly name: string | symbol;\\n\\n    /** A value indicating whether the class element is a static (`true`) or instance (`false`) element. */\\n    readonly static: boolean;\\n\\n    /** A value indicating whether the class element has a private name. */\\n    readonly private: boolean;\\n\\n    /** An object that can be used to access the current value of the class element at runtime. */\\n    readonly access: {\\n        /**\\n         * Determines whether an object has a property with the same name as the decorated element.\\n         */\\n        has(object: This): boolean;\\n        /**\\n         * Invokes the getter on the provided object.\\n         *\\n         * @example\\n         * let value = context.access.get(instance);\\n         */\\n        get(object: This): Value;\\n    };\\n\\n    /**\\n     * Adds a callback to be invoked either before static initializers are run (when\\n     * decorating a `static` element), or before instance initializers are run (when\\n     * decorating a non-`static` element).\\n     */\\n    addInitializer(initializer: (this: This) => void): void;\\n\\n    readonly metadata: DecoratorMetadata;\\n}\\n\\n/**\\n * Context provided to a class setter decorator.\\n * @template This The type on which the class element will be defined. For a static class element, this will be\\n * the type of the constructor. For a non-static class element, this will be the type of the instance.\\n * @template Value The type of the decorated class setter.\\n */\\ninterface ClassSetterDecoratorContext<\\n    This = unknown,\\n    Value = unknown,\\n> {\\n    /** The kind of class element that was decorated. */\\n    readonly kind: \\\"setter\\\";\\n\\n    /** The name of the decorated class element. */\\n    readonly name: string | symbol;\\n\\n    /** A value indicating whether the class element is a static (`true`) or instance (`false`) element. */\\n    readonly static: boolean;\\n\\n    /** A value indicating whether the class element has a private name. */\\n    readonly private: boolean;\\n\\n    /** An object that can be used to access the current value of the class element at runtime. */\\n    readonly access: {\\n        /**\\n         * Determines whether an object has a property with the same name as the decorated element.\\n         */\\n        has(object: This): boolean;\\n        /**\\n         * Invokes the setter on the provided object.\\n         *\\n         * @example\\n         * context.access.set(instance, value);\\n         */\\n        set(object: This, value: Value): void;\\n    };\\n\\n    /**\\n     * Adds a callback to be invoked either before static initializers are run (when\\n     * decorating a `static` element), or before instance initializers are run (when\\n     * decorating a non-`static` element).\\n     */\\n    addInitializer(initializer: (this: This) => void): void;\\n\\n    readonly metadata: DecoratorMetadata;\\n}\\n\\n/**\\n * Context provided to a class `accessor` field decorator.\\n * @template This The type on which the class element will be defined. For a static class element, this will be\\n * the type of the constructor. For a non-static class element, this will be the type of the instance.\\n * @template Value The type of decorated class field.\\n */\\ninterface ClassAccessorDecoratorContext<\\n    This = unknown,\\n    Value = unknown,\\n> {\\n    /** The kind of class element that was decorated. */\\n    readonly kind: \\\"accessor\\\";\\n\\n    /** The name of the decorated class element. */\\n    readonly name: string | symbol;\\n\\n    /** A value indicating whether the class element is a static (`true`) or instance (`false`) element. */\\n    readonly static: boolean;\\n\\n    /** A value indicating whether the class element has a private name. */\\n    readonly private: boolean;\\n\\n    /** An object that can be used to access the current value of the class element at runtime. */\\n    readonly access: {\\n        /**\\n         * Determines whether an object has a property with the same name as the decorated element.\\n         */\\n        has(object: This): boolean;\\n\\n        /**\\n         * Invokes the getter on the provided object.\\n         *\\n         * @example\\n         * let value = context.access.get(instance);\\n         */\\n        get(object: This): Value;\\n\\n        /**\\n         * Invokes the setter on the provided object.\\n         *\\n         * @example\\n         * context.access.set(instance, value);\\n         */\\n        set(object: This, value: Value): void;\\n    };\\n\\n    /**\\n     * Adds a callback to be invoked either before static initializers are run (when\\n     * decorating a `static` element), or before instance initializers are run (when\\n     * decorating a non-`static` element).\\n     */\\n    addInitializer(initializer: (this: This) => void): void;\\n\\n    readonly metadata: DecoratorMetadata;\\n}\\n\\n/**\\n * Describes the target provided to class `accessor` field decorators.\\n * @template This The `this` type to which the target applies.\\n * @template Value The property type for the class `accessor` field.\\n */\\ninterface ClassAccessorDecoratorTarget<This, Value> {\\n    /**\\n     * Invokes the getter that was defined prior to decorator application.\\n     *\\n     * @example\\n     * let value = target.get.call(instance);\\n     */\\n    get(this: This): Value;\\n\\n    /**\\n     * Invokes the setter that was defined prior to decorator application.\\n     *\\n     * @example\\n     * target.set.call(instance, value);\\n     */\\n    set(this: This, value: Value): void;\\n}\\n\\n/**\\n * Describes the allowed return value from a class `accessor` field decorator.\\n * @template This The `this` type to which the target applies.\\n * @template Value The property type for the class `accessor` field.\\n */\\ninterface ClassAccessorDecoratorResult<This, Value> {\\n    /**\\n     * An optional replacement getter function. If not provided, the existing getter function is used instead.\\n     */\\n    get?(this: This): Value;\\n\\n    /**\\n     * An optional replacement setter function. If not provided, the existing setter function is used instead.\\n     */\\n    set?(this: This, value: Value): void;\\n\\n    /**\\n     * An optional initializer mutator that is invoked when the underlying field initializer is evaluated.\\n     * @param value The incoming initializer value.\\n     * @returns The replacement initializer value.\\n     */\\n    init?(this: This, value: Value): Value;\\n}\\n\\n/**\\n * Context provided to a class field decorator.\\n * @template This The type on which the class element will be defined. For a static class element, this will be\\n * the type of the constructor. For a non-static class element, this will be the type of the instance.\\n * @template Value The type of the decorated class field.\\n */\\ninterface ClassFieldDecoratorContext<\\n    This = unknown,\\n    Value = unknown,\\n> {\\n    /** The kind of class element that was decorated. */\\n    readonly kind: \\\"field\\\";\\n\\n    /** The name of the decorated class element. */\\n    readonly name: string | symbol;\\n\\n    /** A value indicating whether the class element is a static (`true`) or instance (`false`) element. */\\n    readonly static: boolean;\\n\\n    /** A value indicating whether the class element has a private name. */\\n    readonly private: boolean;\\n\\n    /** An object that can be used to access the current value of the class element at runtime. */\\n    readonly access: {\\n        /**\\n         * Determines whether an object has a property with the same name as the decorated element.\\n         */\\n        has(object: This): boolean;\\n\\n        /**\\n         * Gets the value of the field on the provided object.\\n         */\\n        get(object: This): Value;\\n\\n        /**\\n         * Sets the value of the field on the provided object.\\n         */\\n        set(object: This, value: Value): void;\\n    };\\n\\n    /**\\n     * Adds a callback to be invoked either before static initializers are run (when\\n     * decorating a `static` element), or before instance initializers are run (when\\n     * decorating a non-`static` element).\\n     */\\n    addInitializer(initializer: (this: This) => void): void;\\n\\n    readonly metadata: DecoratorMetadata;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.decorators.legacy.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ndeclare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;\\ndeclare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;\\ndeclare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;\\ndeclare type ParameterDecorator = (target: Object, propertyKey: string | symbol | undefined, parameterIndex: number) => void;\\n\"\n  },\n  {\n    \"fileName\": \"lib.dom.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/////////////////////////////\\n/// Window APIs\\n/////////////////////////////\\n\\ninterface AddEventListenerOptions extends EventListenerOptions {\\n    once?: boolean;\\n    passive?: boolean;\\n    signal?: AbortSignal;\\n}\\n\\ninterface AesCbcParams extends Algorithm {\\n    iv: BufferSource;\\n}\\n\\ninterface AesCtrParams extends Algorithm {\\n    counter: BufferSource;\\n    length: number;\\n}\\n\\ninterface AesDerivedKeyParams extends Algorithm {\\n    length: number;\\n}\\n\\ninterface AesGcmParams extends Algorithm {\\n    additionalData?: BufferSource;\\n    iv: BufferSource;\\n    tagLength?: number;\\n}\\n\\ninterface AesKeyAlgorithm extends KeyAlgorithm {\\n    length: number;\\n}\\n\\ninterface AesKeyGenParams extends Algorithm {\\n    length: number;\\n}\\n\\ninterface Algorithm {\\n    name: string;\\n}\\n\\ninterface AnalyserOptions extends AudioNodeOptions {\\n    fftSize?: number;\\n    maxDecibels?: number;\\n    minDecibels?: number;\\n    smoothingTimeConstant?: number;\\n}\\n\\ninterface AnimationEventInit extends EventInit {\\n    animationName?: string;\\n    elapsedTime?: number;\\n    pseudoElement?: string;\\n}\\n\\ninterface AnimationPlaybackEventInit extends EventInit {\\n    currentTime?: CSSNumberish | null;\\n    timelineTime?: CSSNumberish | null;\\n}\\n\\ninterface AssignedNodesOptions {\\n    flatten?: boolean;\\n}\\n\\ninterface AudioBufferOptions {\\n    length: number;\\n    numberOfChannels?: number;\\n    sampleRate: number;\\n}\\n\\ninterface AudioBufferSourceOptions {\\n    buffer?: AudioBuffer | null;\\n    detune?: number;\\n    loop?: boolean;\\n    loopEnd?: number;\\n    loopStart?: number;\\n    playbackRate?: number;\\n}\\n\\ninterface AudioConfiguration {\\n    bitrate?: number;\\n    channels?: string;\\n    contentType: string;\\n    samplerate?: number;\\n    spatialRendering?: boolean;\\n}\\n\\ninterface AudioContextOptions {\\n    latencyHint?: AudioContextLatencyCategory | number;\\n    sampleRate?: number;\\n}\\n\\ninterface AudioNodeOptions {\\n    channelCount?: number;\\n    channelCountMode?: ChannelCountMode;\\n    channelInterpretation?: ChannelInterpretation;\\n}\\n\\ninterface AudioProcessingEventInit extends EventInit {\\n    inputBuffer: AudioBuffer;\\n    outputBuffer: AudioBuffer;\\n    playbackTime: number;\\n}\\n\\ninterface AudioTimestamp {\\n    contextTime?: number;\\n    performanceTime?: DOMHighResTimeStamp;\\n}\\n\\ninterface AudioWorkletNodeOptions extends AudioNodeOptions {\\n    numberOfInputs?: number;\\n    numberOfOutputs?: number;\\n    outputChannelCount?: number[];\\n    parameterData?: Record<string, number>;\\n    processorOptions?: any;\\n}\\n\\ninterface AuthenticationExtensionsClientInputs {\\n    appid?: string;\\n    credProps?: boolean;\\n    hmacCreateSecret?: boolean;\\n}\\n\\ninterface AuthenticationExtensionsClientOutputs {\\n    appid?: boolean;\\n    credProps?: CredentialPropertiesOutput;\\n    hmacCreateSecret?: boolean;\\n}\\n\\ninterface AuthenticatorSelectionCriteria {\\n    authenticatorAttachment?: AuthenticatorAttachment;\\n    requireResidentKey?: boolean;\\n    residentKey?: ResidentKeyRequirement;\\n    userVerification?: UserVerificationRequirement;\\n}\\n\\ninterface AvcEncoderConfig {\\n    format?: AvcBitstreamFormat;\\n}\\n\\ninterface BiquadFilterOptions extends AudioNodeOptions {\\n    Q?: number;\\n    detune?: number;\\n    frequency?: number;\\n    gain?: number;\\n    type?: BiquadFilterType;\\n}\\n\\ninterface BlobEventInit {\\n    data: Blob;\\n    timecode?: DOMHighResTimeStamp;\\n}\\n\\ninterface BlobPropertyBag {\\n    endings?: EndingType;\\n    type?: string;\\n}\\n\\ninterface CSSMatrixComponentOptions {\\n    is2D?: boolean;\\n}\\n\\ninterface CSSNumericType {\\n    angle?: number;\\n    flex?: number;\\n    frequency?: number;\\n    length?: number;\\n    percent?: number;\\n    percentHint?: CSSNumericBaseType;\\n    resolution?: number;\\n    time?: number;\\n}\\n\\ninterface CSSStyleSheetInit {\\n    baseURL?: string;\\n    disabled?: boolean;\\n    media?: MediaList | string;\\n}\\n\\ninterface CacheQueryOptions {\\n    ignoreMethod?: boolean;\\n    ignoreSearch?: boolean;\\n    ignoreVary?: boolean;\\n}\\n\\ninterface CanvasRenderingContext2DSettings {\\n    alpha?: boolean;\\n    colorSpace?: PredefinedColorSpace;\\n    desynchronized?: boolean;\\n    willReadFrequently?: boolean;\\n}\\n\\ninterface ChannelMergerOptions extends AudioNodeOptions {\\n    numberOfInputs?: number;\\n}\\n\\ninterface ChannelSplitterOptions extends AudioNodeOptions {\\n    numberOfOutputs?: number;\\n}\\n\\ninterface CheckVisibilityOptions {\\n    checkOpacity?: boolean;\\n    checkVisibilityCSS?: boolean;\\n}\\n\\ninterface ClientQueryOptions {\\n    includeUncontrolled?: boolean;\\n    type?: ClientTypes;\\n}\\n\\ninterface ClipboardEventInit extends EventInit {\\n    clipboardData?: DataTransfer | null;\\n}\\n\\ninterface ClipboardItemOptions {\\n    presentationStyle?: PresentationStyle;\\n}\\n\\ninterface CloseEventInit extends EventInit {\\n    code?: number;\\n    reason?: string;\\n    wasClean?: boolean;\\n}\\n\\ninterface CompositionEventInit extends UIEventInit {\\n    data?: string;\\n}\\n\\ninterface ComputedEffectTiming extends EffectTiming {\\n    activeDuration?: CSSNumberish;\\n    currentIteration?: number | null;\\n    endTime?: CSSNumberish;\\n    localTime?: CSSNumberish | null;\\n    progress?: number | null;\\n    startTime?: CSSNumberish;\\n}\\n\\ninterface ComputedKeyframe {\\n    composite: CompositeOperationOrAuto;\\n    computedOffset: number;\\n    easing: string;\\n    offset: number | null;\\n    [property: string]: string | number | null | undefined;\\n}\\n\\ninterface ConstantSourceOptions {\\n    offset?: number;\\n}\\n\\ninterface ConstrainBooleanParameters {\\n    exact?: boolean;\\n    ideal?: boolean;\\n}\\n\\ninterface ConstrainDOMStringParameters {\\n    exact?: string | string[];\\n    ideal?: string | string[];\\n}\\n\\ninterface ConstrainDoubleRange extends DoubleRange {\\n    exact?: number;\\n    ideal?: number;\\n}\\n\\ninterface ConstrainULongRange extends ULongRange {\\n    exact?: number;\\n    ideal?: number;\\n}\\n\\ninterface ConvolverOptions extends AudioNodeOptions {\\n    buffer?: AudioBuffer | null;\\n    disableNormalization?: boolean;\\n}\\n\\ninterface CredentialCreationOptions {\\n    publicKey?: PublicKeyCredentialCreationOptions;\\n    signal?: AbortSignal;\\n}\\n\\ninterface CredentialPropertiesOutput {\\n    rk?: boolean;\\n}\\n\\ninterface CredentialRequestOptions {\\n    mediation?: CredentialMediationRequirement;\\n    publicKey?: PublicKeyCredentialRequestOptions;\\n    signal?: AbortSignal;\\n}\\n\\ninterface CryptoKeyPair {\\n    privateKey: CryptoKey;\\n    publicKey: CryptoKey;\\n}\\n\\ninterface CustomEventInit<T = any> extends EventInit {\\n    detail?: T;\\n}\\n\\ninterface DOMMatrix2DInit {\\n    a?: number;\\n    b?: number;\\n    c?: number;\\n    d?: number;\\n    e?: number;\\n    f?: number;\\n    m11?: number;\\n    m12?: number;\\n    m21?: number;\\n    m22?: number;\\n    m41?: number;\\n    m42?: number;\\n}\\n\\ninterface DOMMatrixInit extends DOMMatrix2DInit {\\n    is2D?: boolean;\\n    m13?: number;\\n    m14?: number;\\n    m23?: number;\\n    m24?: number;\\n    m31?: number;\\n    m32?: number;\\n    m33?: number;\\n    m34?: number;\\n    m43?: number;\\n    m44?: number;\\n}\\n\\ninterface DOMPointInit {\\n    w?: number;\\n    x?: number;\\n    y?: number;\\n    z?: number;\\n}\\n\\ninterface DOMQuadInit {\\n    p1?: DOMPointInit;\\n    p2?: DOMPointInit;\\n    p3?: DOMPointInit;\\n    p4?: DOMPointInit;\\n}\\n\\ninterface DOMRectInit {\\n    height?: number;\\n    width?: number;\\n    x?: number;\\n    y?: number;\\n}\\n\\ninterface DelayOptions extends AudioNodeOptions {\\n    delayTime?: number;\\n    maxDelayTime?: number;\\n}\\n\\ninterface DeviceMotionEventAccelerationInit {\\n    x?: number | null;\\n    y?: number | null;\\n    z?: number | null;\\n}\\n\\ninterface DeviceMotionEventInit extends EventInit {\\n    acceleration?: DeviceMotionEventAccelerationInit;\\n    accelerationIncludingGravity?: DeviceMotionEventAccelerationInit;\\n    interval?: number;\\n    rotationRate?: DeviceMotionEventRotationRateInit;\\n}\\n\\ninterface DeviceMotionEventRotationRateInit {\\n    alpha?: number | null;\\n    beta?: number | null;\\n    gamma?: number | null;\\n}\\n\\ninterface DeviceOrientationEventInit extends EventInit {\\n    absolute?: boolean;\\n    alpha?: number | null;\\n    beta?: number | null;\\n    gamma?: number | null;\\n}\\n\\ninterface DisplayMediaStreamOptions {\\n    audio?: boolean | MediaTrackConstraints;\\n    video?: boolean | MediaTrackConstraints;\\n}\\n\\ninterface DocumentTimelineOptions {\\n    originTime?: DOMHighResTimeStamp;\\n}\\n\\ninterface DoubleRange {\\n    max?: number;\\n    min?: number;\\n}\\n\\ninterface DragEventInit extends MouseEventInit {\\n    dataTransfer?: DataTransfer | null;\\n}\\n\\ninterface DynamicsCompressorOptions extends AudioNodeOptions {\\n    attack?: number;\\n    knee?: number;\\n    ratio?: number;\\n    release?: number;\\n    threshold?: number;\\n}\\n\\ninterface EcKeyAlgorithm extends KeyAlgorithm {\\n    namedCurve: NamedCurve;\\n}\\n\\ninterface EcKeyGenParams extends Algorithm {\\n    namedCurve: NamedCurve;\\n}\\n\\ninterface EcKeyImportParams extends Algorithm {\\n    namedCurve: NamedCurve;\\n}\\n\\ninterface EcdhKeyDeriveParams extends Algorithm {\\n    public: CryptoKey;\\n}\\n\\ninterface EcdsaParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n}\\n\\ninterface EffectTiming {\\n    delay?: number;\\n    direction?: PlaybackDirection;\\n    duration?: number | CSSNumericValue | string;\\n    easing?: string;\\n    endDelay?: number;\\n    fill?: FillMode;\\n    iterationStart?: number;\\n    iterations?: number;\\n    playbackRate?: number;\\n}\\n\\ninterface ElementCreationOptions {\\n    is?: string;\\n}\\n\\ninterface ElementDefinitionOptions {\\n    extends?: string;\\n}\\n\\ninterface EncodedVideoChunkInit {\\n    data: BufferSource;\\n    duration?: number;\\n    timestamp: number;\\n    type: EncodedVideoChunkType;\\n}\\n\\ninterface EncodedVideoChunkMetadata {\\n    decoderConfig?: VideoDecoderConfig;\\n}\\n\\ninterface ErrorEventInit extends EventInit {\\n    colno?: number;\\n    error?: any;\\n    filename?: string;\\n    lineno?: number;\\n    message?: string;\\n}\\n\\ninterface EventInit {\\n    bubbles?: boolean;\\n    cancelable?: boolean;\\n    composed?: boolean;\\n}\\n\\ninterface EventListenerOptions {\\n    capture?: boolean;\\n}\\n\\ninterface EventModifierInit extends UIEventInit {\\n    altKey?: boolean;\\n    ctrlKey?: boolean;\\n    metaKey?: boolean;\\n    modifierAltGraph?: boolean;\\n    modifierCapsLock?: boolean;\\n    modifierFn?: boolean;\\n    modifierFnLock?: boolean;\\n    modifierHyper?: boolean;\\n    modifierNumLock?: boolean;\\n    modifierScrollLock?: boolean;\\n    modifierSuper?: boolean;\\n    modifierSymbol?: boolean;\\n    modifierSymbolLock?: boolean;\\n    shiftKey?: boolean;\\n}\\n\\ninterface EventSourceInit {\\n    withCredentials?: boolean;\\n}\\n\\ninterface FilePropertyBag extends BlobPropertyBag {\\n    lastModified?: number;\\n}\\n\\ninterface FileSystemCreateWritableOptions {\\n    keepExistingData?: boolean;\\n}\\n\\ninterface FileSystemFlags {\\n    create?: boolean;\\n    exclusive?: boolean;\\n}\\n\\ninterface FileSystemGetDirectoryOptions {\\n    create?: boolean;\\n}\\n\\ninterface FileSystemGetFileOptions {\\n    create?: boolean;\\n}\\n\\ninterface FileSystemRemoveOptions {\\n    recursive?: boolean;\\n}\\n\\ninterface FocusEventInit extends UIEventInit {\\n    relatedTarget?: EventTarget | null;\\n}\\n\\ninterface FocusOptions {\\n    preventScroll?: boolean;\\n}\\n\\ninterface FontFaceDescriptors {\\n    ascentOverride?: string;\\n    descentOverride?: string;\\n    display?: FontDisplay;\\n    featureSettings?: string;\\n    lineGapOverride?: string;\\n    stretch?: string;\\n    style?: string;\\n    unicodeRange?: string;\\n    variant?: string;\\n    weight?: string;\\n}\\n\\ninterface FontFaceSetLoadEventInit extends EventInit {\\n    fontfaces?: FontFace[];\\n}\\n\\ninterface FormDataEventInit extends EventInit {\\n    formData: FormData;\\n}\\n\\ninterface FullscreenOptions {\\n    navigationUI?: FullscreenNavigationUI;\\n}\\n\\ninterface GainOptions extends AudioNodeOptions {\\n    gain?: number;\\n}\\n\\ninterface GamepadEffectParameters {\\n    duration?: number;\\n    startDelay?: number;\\n    strongMagnitude?: number;\\n    weakMagnitude?: number;\\n}\\n\\ninterface GamepadEventInit extends EventInit {\\n    gamepad: Gamepad;\\n}\\n\\ninterface GetAnimationsOptions {\\n    subtree?: boolean;\\n}\\n\\ninterface GetNotificationOptions {\\n    tag?: string;\\n}\\n\\ninterface GetRootNodeOptions {\\n    composed?: boolean;\\n}\\n\\ninterface HashChangeEventInit extends EventInit {\\n    newURL?: string;\\n    oldURL?: string;\\n}\\n\\ninterface HkdfParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n    info: BufferSource;\\n    salt: BufferSource;\\n}\\n\\ninterface HmacImportParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n    length?: number;\\n}\\n\\ninterface HmacKeyAlgorithm extends KeyAlgorithm {\\n    hash: KeyAlgorithm;\\n    length: number;\\n}\\n\\ninterface HmacKeyGenParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n    length?: number;\\n}\\n\\ninterface IDBDatabaseInfo {\\n    name?: string;\\n    version?: number;\\n}\\n\\ninterface IDBIndexParameters {\\n    multiEntry?: boolean;\\n    unique?: boolean;\\n}\\n\\ninterface IDBObjectStoreParameters {\\n    autoIncrement?: boolean;\\n    keyPath?: string | string[] | null;\\n}\\n\\ninterface IDBTransactionOptions {\\n    durability?: IDBTransactionDurability;\\n}\\n\\ninterface IDBVersionChangeEventInit extends EventInit {\\n    newVersion?: number | null;\\n    oldVersion?: number;\\n}\\n\\ninterface IIRFilterOptions extends AudioNodeOptions {\\n    feedback: number[];\\n    feedforward: number[];\\n}\\n\\ninterface IdleRequestOptions {\\n    timeout?: number;\\n}\\n\\ninterface ImageBitmapOptions {\\n    colorSpaceConversion?: ColorSpaceConversion;\\n    imageOrientation?: ImageOrientation;\\n    premultiplyAlpha?: PremultiplyAlpha;\\n    resizeHeight?: number;\\n    resizeQuality?: ResizeQuality;\\n    resizeWidth?: number;\\n}\\n\\ninterface ImageBitmapRenderingContextSettings {\\n    alpha?: boolean;\\n}\\n\\ninterface ImageDataSettings {\\n    colorSpace?: PredefinedColorSpace;\\n}\\n\\ninterface ImageEncodeOptions {\\n    quality?: number;\\n    type?: string;\\n}\\n\\ninterface ImportMeta {\\n    url: string;\\n}\\n\\ninterface InputEventInit extends UIEventInit {\\n    data?: string | null;\\n    dataTransfer?: DataTransfer | null;\\n    inputType?: string;\\n    isComposing?: boolean;\\n    targetRanges?: StaticRange[];\\n}\\n\\ninterface IntersectionObserverEntryInit {\\n    boundingClientRect: DOMRectInit;\\n    intersectionRatio: number;\\n    intersectionRect: DOMRectInit;\\n    isIntersecting: boolean;\\n    rootBounds: DOMRectInit | null;\\n    target: Element;\\n    time: DOMHighResTimeStamp;\\n}\\n\\ninterface IntersectionObserverInit {\\n    root?: Element | Document | null;\\n    rootMargin?: string;\\n    threshold?: number | number[];\\n}\\n\\ninterface JsonWebKey {\\n    alg?: string;\\n    crv?: string;\\n    d?: string;\\n    dp?: string;\\n    dq?: string;\\n    e?: string;\\n    ext?: boolean;\\n    k?: string;\\n    key_ops?: string[];\\n    kty?: string;\\n    n?: string;\\n    oth?: RsaOtherPrimesInfo[];\\n    p?: string;\\n    q?: string;\\n    qi?: string;\\n    use?: string;\\n    x?: string;\\n    y?: string;\\n}\\n\\ninterface KeyAlgorithm {\\n    name: string;\\n}\\n\\ninterface KeyboardEventInit extends EventModifierInit {\\n    /** @deprecated */\\n    charCode?: number;\\n    code?: string;\\n    isComposing?: boolean;\\n    key?: string;\\n    /** @deprecated */\\n    keyCode?: number;\\n    location?: number;\\n    repeat?: boolean;\\n}\\n\\ninterface Keyframe {\\n    composite?: CompositeOperationOrAuto;\\n    easing?: string;\\n    offset?: number | null;\\n    [property: string]: string | number | null | undefined;\\n}\\n\\ninterface KeyframeAnimationOptions extends KeyframeEffectOptions {\\n    id?: string;\\n    timeline?: AnimationTimeline | null;\\n}\\n\\ninterface KeyframeEffectOptions extends EffectTiming {\\n    composite?: CompositeOperation;\\n    iterationComposite?: IterationCompositeOperation;\\n    pseudoElement?: string | null;\\n}\\n\\ninterface LockInfo {\\n    clientId?: string;\\n    mode?: LockMode;\\n    name?: string;\\n}\\n\\ninterface LockManagerSnapshot {\\n    held?: LockInfo[];\\n    pending?: LockInfo[];\\n}\\n\\ninterface LockOptions {\\n    ifAvailable?: boolean;\\n    mode?: LockMode;\\n    signal?: AbortSignal;\\n    steal?: boolean;\\n}\\n\\ninterface MIDIConnectionEventInit extends EventInit {\\n    port?: MIDIPort;\\n}\\n\\ninterface MIDIMessageEventInit extends EventInit {\\n    data?: Uint8Array;\\n}\\n\\ninterface MIDIOptions {\\n    software?: boolean;\\n    sysex?: boolean;\\n}\\n\\ninterface MediaCapabilitiesDecodingInfo extends MediaCapabilitiesInfo {\\n    configuration?: MediaDecodingConfiguration;\\n}\\n\\ninterface MediaCapabilitiesEncodingInfo extends MediaCapabilitiesInfo {\\n    configuration?: MediaEncodingConfiguration;\\n}\\n\\ninterface MediaCapabilitiesInfo {\\n    powerEfficient: boolean;\\n    smooth: boolean;\\n    supported: boolean;\\n}\\n\\ninterface MediaConfiguration {\\n    audio?: AudioConfiguration;\\n    video?: VideoConfiguration;\\n}\\n\\ninterface MediaDecodingConfiguration extends MediaConfiguration {\\n    type: MediaDecodingType;\\n}\\n\\ninterface MediaElementAudioSourceOptions {\\n    mediaElement: HTMLMediaElement;\\n}\\n\\ninterface MediaEncodingConfiguration extends MediaConfiguration {\\n    type: MediaEncodingType;\\n}\\n\\ninterface MediaEncryptedEventInit extends EventInit {\\n    initData?: ArrayBuffer | null;\\n    initDataType?: string;\\n}\\n\\ninterface MediaImage {\\n    sizes?: string;\\n    src: string;\\n    type?: string;\\n}\\n\\ninterface MediaKeyMessageEventInit extends EventInit {\\n    message: ArrayBuffer;\\n    messageType: MediaKeyMessageType;\\n}\\n\\ninterface MediaKeySystemConfiguration {\\n    audioCapabilities?: MediaKeySystemMediaCapability[];\\n    distinctiveIdentifier?: MediaKeysRequirement;\\n    initDataTypes?: string[];\\n    label?: string;\\n    persistentState?: MediaKeysRequirement;\\n    sessionTypes?: string[];\\n    videoCapabilities?: MediaKeySystemMediaCapability[];\\n}\\n\\ninterface MediaKeySystemMediaCapability {\\n    contentType?: string;\\n    encryptionScheme?: string | null;\\n    robustness?: string;\\n}\\n\\ninterface MediaMetadataInit {\\n    album?: string;\\n    artist?: string;\\n    artwork?: MediaImage[];\\n    title?: string;\\n}\\n\\ninterface MediaPositionState {\\n    duration?: number;\\n    playbackRate?: number;\\n    position?: number;\\n}\\n\\ninterface MediaQueryListEventInit extends EventInit {\\n    matches?: boolean;\\n    media?: string;\\n}\\n\\ninterface MediaRecorderOptions {\\n    audioBitsPerSecond?: number;\\n    bitsPerSecond?: number;\\n    mimeType?: string;\\n    videoBitsPerSecond?: number;\\n}\\n\\ninterface MediaSessionActionDetails {\\n    action: MediaSessionAction;\\n    fastSeek?: boolean;\\n    seekOffset?: number;\\n    seekTime?: number;\\n}\\n\\ninterface MediaStreamAudioSourceOptions {\\n    mediaStream: MediaStream;\\n}\\n\\ninterface MediaStreamConstraints {\\n    audio?: boolean | MediaTrackConstraints;\\n    peerIdentity?: string;\\n    preferCurrentTab?: boolean;\\n    video?: boolean | MediaTrackConstraints;\\n}\\n\\ninterface MediaStreamTrackEventInit extends EventInit {\\n    track: MediaStreamTrack;\\n}\\n\\ninterface MediaTrackCapabilities {\\n    aspectRatio?: DoubleRange;\\n    autoGainControl?: boolean[];\\n    channelCount?: ULongRange;\\n    deviceId?: string;\\n    displaySurface?: string;\\n    echoCancellation?: boolean[];\\n    facingMode?: string[];\\n    frameRate?: DoubleRange;\\n    groupId?: string;\\n    height?: ULongRange;\\n    noiseSuppression?: boolean[];\\n    sampleRate?: ULongRange;\\n    sampleSize?: ULongRange;\\n    width?: ULongRange;\\n}\\n\\ninterface MediaTrackConstraintSet {\\n    aspectRatio?: ConstrainDouble;\\n    autoGainControl?: ConstrainBoolean;\\n    channelCount?: ConstrainULong;\\n    deviceId?: ConstrainDOMString;\\n    displaySurface?: ConstrainDOMString;\\n    echoCancellation?: ConstrainBoolean;\\n    facingMode?: ConstrainDOMString;\\n    frameRate?: ConstrainDouble;\\n    groupId?: ConstrainDOMString;\\n    height?: ConstrainULong;\\n    noiseSuppression?: ConstrainBoolean;\\n    sampleRate?: ConstrainULong;\\n    sampleSize?: ConstrainULong;\\n    width?: ConstrainULong;\\n}\\n\\ninterface MediaTrackConstraints extends MediaTrackConstraintSet {\\n    advanced?: MediaTrackConstraintSet[];\\n}\\n\\ninterface MediaTrackSettings {\\n    aspectRatio?: number;\\n    autoGainControl?: boolean;\\n    channelCount?: number;\\n    deviceId?: string;\\n    displaySurface?: string;\\n    echoCancellation?: boolean;\\n    facingMode?: string;\\n    frameRate?: number;\\n    groupId?: string;\\n    height?: number;\\n    noiseSuppression?: boolean;\\n    sampleRate?: number;\\n    sampleSize?: number;\\n    width?: number;\\n}\\n\\ninterface MediaTrackSupportedConstraints {\\n    aspectRatio?: boolean;\\n    autoGainControl?: boolean;\\n    channelCount?: boolean;\\n    deviceId?: boolean;\\n    displaySurface?: boolean;\\n    echoCancellation?: boolean;\\n    facingMode?: boolean;\\n    frameRate?: boolean;\\n    groupId?: boolean;\\n    height?: boolean;\\n    noiseSuppression?: boolean;\\n    sampleRate?: boolean;\\n    sampleSize?: boolean;\\n    width?: boolean;\\n}\\n\\ninterface MessageEventInit<T = any> extends EventInit {\\n    data?: T;\\n    lastEventId?: string;\\n    origin?: string;\\n    ports?: MessagePort[];\\n    source?: MessageEventSource | null;\\n}\\n\\ninterface MouseEventInit extends EventModifierInit {\\n    button?: number;\\n    buttons?: number;\\n    clientX?: number;\\n    clientY?: number;\\n    movementX?: number;\\n    movementY?: number;\\n    relatedTarget?: EventTarget | null;\\n    screenX?: number;\\n    screenY?: number;\\n}\\n\\ninterface MultiCacheQueryOptions extends CacheQueryOptions {\\n    cacheName?: string;\\n}\\n\\ninterface MutationObserverInit {\\n    /** Set to a list of attribute local names (without namespace) if not all attribute mutations need to be observed and attributes is true or omitted. */\\n    attributeFilter?: string[];\\n    /** Set to true if attributes is true or omitted and target's attribute value before the mutation needs to be recorded. */\\n    attributeOldValue?: boolean;\\n    /** Set to true if mutations to target's attributes are to be observed. Can be omitted if attributeOldValue or attributeFilter is specified. */\\n    attributes?: boolean;\\n    /** Set to true if mutations to target's data are to be observed. Can be omitted if characterDataOldValue is specified. */\\n    characterData?: boolean;\\n    /** Set to true if characterData is set to true or omitted and target's data before the mutation needs to be recorded. */\\n    characterDataOldValue?: boolean;\\n    /** Set to true if mutations to target's children are to be observed. */\\n    childList?: boolean;\\n    /** Set to true if mutations to not just target, but also target's descendants are to be observed. */\\n    subtree?: boolean;\\n}\\n\\ninterface NavigationPreloadState {\\n    enabled?: boolean;\\n    headerValue?: string;\\n}\\n\\ninterface NotificationAction {\\n    action: string;\\n    icon?: string;\\n    title: string;\\n}\\n\\ninterface NotificationOptions {\\n    actions?: NotificationAction[];\\n    badge?: string;\\n    body?: string;\\n    data?: any;\\n    dir?: NotificationDirection;\\n    icon?: string;\\n    image?: string;\\n    lang?: string;\\n    renotify?: boolean;\\n    requireInteraction?: boolean;\\n    silent?: boolean | null;\\n    tag?: string;\\n    timestamp?: EpochTimeStamp;\\n    vibrate?: VibratePattern;\\n}\\n\\ninterface OfflineAudioCompletionEventInit extends EventInit {\\n    renderedBuffer: AudioBuffer;\\n}\\n\\ninterface OfflineAudioContextOptions {\\n    length: number;\\n    numberOfChannels?: number;\\n    sampleRate: number;\\n}\\n\\ninterface OptionalEffectTiming {\\n    delay?: number;\\n    direction?: PlaybackDirection;\\n    duration?: number | string;\\n    easing?: string;\\n    endDelay?: number;\\n    fill?: FillMode;\\n    iterationStart?: number;\\n    iterations?: number;\\n    playbackRate?: number;\\n}\\n\\ninterface OscillatorOptions extends AudioNodeOptions {\\n    detune?: number;\\n    frequency?: number;\\n    periodicWave?: PeriodicWave;\\n    type?: OscillatorType;\\n}\\n\\ninterface PageTransitionEventInit extends EventInit {\\n    persisted?: boolean;\\n}\\n\\ninterface PannerOptions extends AudioNodeOptions {\\n    coneInnerAngle?: number;\\n    coneOuterAngle?: number;\\n    coneOuterGain?: number;\\n    distanceModel?: DistanceModelType;\\n    maxDistance?: number;\\n    orientationX?: number;\\n    orientationY?: number;\\n    orientationZ?: number;\\n    panningModel?: PanningModelType;\\n    positionX?: number;\\n    positionY?: number;\\n    positionZ?: number;\\n    refDistance?: number;\\n    rolloffFactor?: number;\\n}\\n\\ninterface PaymentCurrencyAmount {\\n    currency: string;\\n    value: string;\\n}\\n\\ninterface PaymentDetailsBase {\\n    displayItems?: PaymentItem[];\\n    modifiers?: PaymentDetailsModifier[];\\n}\\n\\ninterface PaymentDetailsInit extends PaymentDetailsBase {\\n    id?: string;\\n    total: PaymentItem;\\n}\\n\\ninterface PaymentDetailsModifier {\\n    additionalDisplayItems?: PaymentItem[];\\n    data?: any;\\n    supportedMethods: string;\\n    total?: PaymentItem;\\n}\\n\\ninterface PaymentDetailsUpdate extends PaymentDetailsBase {\\n    paymentMethodErrors?: any;\\n    total?: PaymentItem;\\n}\\n\\ninterface PaymentItem {\\n    amount: PaymentCurrencyAmount;\\n    label: string;\\n    pending?: boolean;\\n}\\n\\ninterface PaymentMethodChangeEventInit extends PaymentRequestUpdateEventInit {\\n    methodDetails?: any;\\n    methodName?: string;\\n}\\n\\ninterface PaymentMethodData {\\n    data?: any;\\n    supportedMethods: string;\\n}\\n\\ninterface PaymentRequestUpdateEventInit extends EventInit {\\n}\\n\\ninterface PaymentValidationErrors {\\n    error?: string;\\n    paymentMethod?: any;\\n}\\n\\ninterface Pbkdf2Params extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n    iterations: number;\\n    salt: BufferSource;\\n}\\n\\ninterface PerformanceMarkOptions {\\n    detail?: any;\\n    startTime?: DOMHighResTimeStamp;\\n}\\n\\ninterface PerformanceMeasureOptions {\\n    detail?: any;\\n    duration?: DOMHighResTimeStamp;\\n    end?: string | DOMHighResTimeStamp;\\n    start?: string | DOMHighResTimeStamp;\\n}\\n\\ninterface PerformanceObserverInit {\\n    buffered?: boolean;\\n    entryTypes?: string[];\\n    type?: string;\\n}\\n\\ninterface PeriodicWaveConstraints {\\n    disableNormalization?: boolean;\\n}\\n\\ninterface PeriodicWaveOptions extends PeriodicWaveConstraints {\\n    imag?: number[] | Float32Array;\\n    real?: number[] | Float32Array;\\n}\\n\\ninterface PermissionDescriptor {\\n    name: PermissionName;\\n}\\n\\ninterface PictureInPictureEventInit extends EventInit {\\n    pictureInPictureWindow: PictureInPictureWindow;\\n}\\n\\ninterface PlaneLayout {\\n    offset: number;\\n    stride: number;\\n}\\n\\ninterface PointerEventInit extends MouseEventInit {\\n    coalescedEvents?: PointerEvent[];\\n    height?: number;\\n    isPrimary?: boolean;\\n    pointerId?: number;\\n    pointerType?: string;\\n    predictedEvents?: PointerEvent[];\\n    pressure?: number;\\n    tangentialPressure?: number;\\n    tiltX?: number;\\n    tiltY?: number;\\n    twist?: number;\\n    width?: number;\\n}\\n\\ninterface PopStateEventInit extends EventInit {\\n    state?: any;\\n}\\n\\ninterface PositionOptions {\\n    enableHighAccuracy?: boolean;\\n    maximumAge?: number;\\n    timeout?: number;\\n}\\n\\ninterface ProgressEventInit extends EventInit {\\n    lengthComputable?: boolean;\\n    loaded?: number;\\n    total?: number;\\n}\\n\\ninterface PromiseRejectionEventInit extends EventInit {\\n    promise: Promise<any>;\\n    reason?: any;\\n}\\n\\ninterface PropertyDefinition {\\n    inherits: boolean;\\n    initialValue?: string;\\n    name: string;\\n    syntax?: string;\\n}\\n\\ninterface PropertyIndexedKeyframes {\\n    composite?: CompositeOperationOrAuto | CompositeOperationOrAuto[];\\n    easing?: string | string[];\\n    offset?: number | (number | null)[];\\n    [property: string]: string | string[] | number | null | (number | null)[] | undefined;\\n}\\n\\ninterface PublicKeyCredentialCreationOptions {\\n    attestation?: AttestationConveyancePreference;\\n    authenticatorSelection?: AuthenticatorSelectionCriteria;\\n    challenge: BufferSource;\\n    excludeCredentials?: PublicKeyCredentialDescriptor[];\\n    extensions?: AuthenticationExtensionsClientInputs;\\n    pubKeyCredParams: PublicKeyCredentialParameters[];\\n    rp: PublicKeyCredentialRpEntity;\\n    timeout?: number;\\n    user: PublicKeyCredentialUserEntity;\\n}\\n\\ninterface PublicKeyCredentialDescriptor {\\n    id: BufferSource;\\n    transports?: AuthenticatorTransport[];\\n    type: PublicKeyCredentialType;\\n}\\n\\ninterface PublicKeyCredentialEntity {\\n    name: string;\\n}\\n\\ninterface PublicKeyCredentialParameters {\\n    alg: COSEAlgorithmIdentifier;\\n    type: PublicKeyCredentialType;\\n}\\n\\ninterface PublicKeyCredentialRequestOptions {\\n    allowCredentials?: PublicKeyCredentialDescriptor[];\\n    challenge: BufferSource;\\n    extensions?: AuthenticationExtensionsClientInputs;\\n    rpId?: string;\\n    timeout?: number;\\n    userVerification?: UserVerificationRequirement;\\n}\\n\\ninterface PublicKeyCredentialRpEntity extends PublicKeyCredentialEntity {\\n    id?: string;\\n}\\n\\ninterface PublicKeyCredentialUserEntity extends PublicKeyCredentialEntity {\\n    displayName: string;\\n    id: BufferSource;\\n}\\n\\ninterface PushSubscriptionJSON {\\n    endpoint?: string;\\n    expirationTime?: EpochTimeStamp | null;\\n    keys?: Record<string, string>;\\n}\\n\\ninterface PushSubscriptionOptionsInit {\\n    applicationServerKey?: BufferSource | string | null;\\n    userVisibleOnly?: boolean;\\n}\\n\\ninterface QueuingStrategy<T = any> {\\n    highWaterMark?: number;\\n    size?: QueuingStrategySize<T>;\\n}\\n\\ninterface QueuingStrategyInit {\\n    /**\\n     * Creates a new ByteLengthQueuingStrategy with the provided high water mark.\\n     *\\n     * Note that the provided high water mark will not be validated ahead of time. Instead, if it is negative, NaN, or not a number, the resulting ByteLengthQueuingStrategy will cause the corresponding stream constructor to throw.\\n     */\\n    highWaterMark: number;\\n}\\n\\ninterface RTCAnswerOptions extends RTCOfferAnswerOptions {\\n}\\n\\ninterface RTCCertificateExpiration {\\n    expires?: number;\\n}\\n\\ninterface RTCConfiguration {\\n    bundlePolicy?: RTCBundlePolicy;\\n    certificates?: RTCCertificate[];\\n    iceCandidatePoolSize?: number;\\n    iceServers?: RTCIceServer[];\\n    iceTransportPolicy?: RTCIceTransportPolicy;\\n    rtcpMuxPolicy?: RTCRtcpMuxPolicy;\\n}\\n\\ninterface RTCDTMFToneChangeEventInit extends EventInit {\\n    tone?: string;\\n}\\n\\ninterface RTCDataChannelEventInit extends EventInit {\\n    channel: RTCDataChannel;\\n}\\n\\ninterface RTCDataChannelInit {\\n    id?: number;\\n    maxPacketLifeTime?: number;\\n    maxRetransmits?: number;\\n    negotiated?: boolean;\\n    ordered?: boolean;\\n    protocol?: string;\\n}\\n\\ninterface RTCDtlsFingerprint {\\n    algorithm?: string;\\n    value?: string;\\n}\\n\\ninterface RTCEncodedAudioFrameMetadata {\\n    contributingSources?: number[];\\n    synchronizationSource?: number;\\n}\\n\\ninterface RTCEncodedVideoFrameMetadata {\\n    dependencies?: number[];\\n    frameId?: number;\\n    height?: number;\\n    spatialIndex?: number;\\n    synchronizationSource?: number;\\n    temporalIndex?: number;\\n    width?: number;\\n}\\n\\ninterface RTCErrorEventInit extends EventInit {\\n    error: RTCError;\\n}\\n\\ninterface RTCErrorInit {\\n    errorDetail: RTCErrorDetailType;\\n    httpRequestStatusCode?: number;\\n    receivedAlert?: number;\\n    sctpCauseCode?: number;\\n    sdpLineNumber?: number;\\n    sentAlert?: number;\\n}\\n\\ninterface RTCIceCandidateInit {\\n    candidate?: string;\\n    sdpMLineIndex?: number | null;\\n    sdpMid?: string | null;\\n    usernameFragment?: string | null;\\n}\\n\\ninterface RTCIceCandidatePair {\\n    local?: RTCIceCandidate;\\n    remote?: RTCIceCandidate;\\n}\\n\\ninterface RTCIceCandidatePairStats extends RTCStats {\\n    availableIncomingBitrate?: number;\\n    availableOutgoingBitrate?: number;\\n    bytesReceived?: number;\\n    bytesSent?: number;\\n    currentRoundTripTime?: number;\\n    lastPacketReceivedTimestamp?: DOMHighResTimeStamp;\\n    lastPacketSentTimestamp?: DOMHighResTimeStamp;\\n    localCandidateId: string;\\n    nominated?: boolean;\\n    remoteCandidateId: string;\\n    requestsReceived?: number;\\n    requestsSent?: number;\\n    responsesReceived?: number;\\n    responsesSent?: number;\\n    state: RTCStatsIceCandidatePairState;\\n    totalRoundTripTime?: number;\\n    transportId: string;\\n}\\n\\ninterface RTCIceServer {\\n    credential?: string;\\n    urls: string | string[];\\n    username?: string;\\n}\\n\\ninterface RTCInboundRtpStreamStats extends RTCReceivedRtpStreamStats {\\n    audioLevel?: number;\\n    bytesReceived?: number;\\n    concealedSamples?: number;\\n    concealmentEvents?: number;\\n    decoderImplementation?: string;\\n    estimatedPlayoutTimestamp?: DOMHighResTimeStamp;\\n    fecPacketsDiscarded?: number;\\n    fecPacketsReceived?: number;\\n    firCount?: number;\\n    frameHeight?: number;\\n    frameWidth?: number;\\n    framesDecoded?: number;\\n    framesDropped?: number;\\n    framesPerSecond?: number;\\n    framesReceived?: number;\\n    headerBytesReceived?: number;\\n    insertedSamplesForDeceleration?: number;\\n    jitterBufferDelay?: number;\\n    jitterBufferEmittedCount?: number;\\n    keyFramesDecoded?: number;\\n    kind: string;\\n    lastPacketReceivedTimestamp?: DOMHighResTimeStamp;\\n    mid?: string;\\n    nackCount?: number;\\n    packetsDiscarded?: number;\\n    pliCount?: number;\\n    qpSum?: number;\\n    remoteId?: string;\\n    removedSamplesForAcceleration?: number;\\n    silentConcealedSamples?: number;\\n    totalAudioEnergy?: number;\\n    totalDecodeTime?: number;\\n    totalInterFrameDelay?: number;\\n    totalProcessingDelay?: number;\\n    totalSamplesDuration?: number;\\n    totalSamplesReceived?: number;\\n    totalSquaredInterFrameDelay?: number;\\n    trackIdentifier: string;\\n}\\n\\ninterface RTCLocalSessionDescriptionInit {\\n    sdp?: string;\\n    type?: RTCSdpType;\\n}\\n\\ninterface RTCOfferAnswerOptions {\\n}\\n\\ninterface RTCOfferOptions extends RTCOfferAnswerOptions {\\n    iceRestart?: boolean;\\n    offerToReceiveAudio?: boolean;\\n    offerToReceiveVideo?: boolean;\\n}\\n\\ninterface RTCOutboundRtpStreamStats extends RTCSentRtpStreamStats {\\n    firCount?: number;\\n    frameHeight?: number;\\n    frameWidth?: number;\\n    framesEncoded?: number;\\n    framesPerSecond?: number;\\n    framesSent?: number;\\n    headerBytesSent?: number;\\n    hugeFramesSent?: number;\\n    keyFramesEncoded?: number;\\n    mediaSourceId?: string;\\n    nackCount?: number;\\n    pliCount?: number;\\n    qpSum?: number;\\n    qualityLimitationResolutionChanges?: number;\\n    remoteId?: string;\\n    retransmittedBytesSent?: number;\\n    retransmittedPacketsSent?: number;\\n    rid?: string;\\n    targetBitrate?: number;\\n    totalEncodeTime?: number;\\n    totalEncodedBytesTarget?: number;\\n    totalPacketSendDelay?: number;\\n}\\n\\ninterface RTCPeerConnectionIceErrorEventInit extends EventInit {\\n    address?: string | null;\\n    errorCode: number;\\n    errorText?: string;\\n    port?: number | null;\\n    url?: string;\\n}\\n\\ninterface RTCPeerConnectionIceEventInit extends EventInit {\\n    candidate?: RTCIceCandidate | null;\\n    url?: string | null;\\n}\\n\\ninterface RTCReceivedRtpStreamStats extends RTCRtpStreamStats {\\n    jitter?: number;\\n    packetsLost?: number;\\n    packetsReceived?: number;\\n}\\n\\ninterface RTCRtcpParameters {\\n    cname?: string;\\n    reducedSize?: boolean;\\n}\\n\\ninterface RTCRtpCapabilities {\\n    codecs: RTCRtpCodecCapability[];\\n    headerExtensions: RTCRtpHeaderExtensionCapability[];\\n}\\n\\ninterface RTCRtpCodec {\\n    channels?: number;\\n    clockRate: number;\\n    mimeType: string;\\n    sdpFmtpLine?: string;\\n}\\n\\ninterface RTCRtpCodecCapability extends RTCRtpCodec {\\n}\\n\\ninterface RTCRtpCodecParameters extends RTCRtpCodec {\\n    payloadType: number;\\n}\\n\\ninterface RTCRtpCodingParameters {\\n    rid?: string;\\n}\\n\\ninterface RTCRtpContributingSource {\\n    audioLevel?: number;\\n    rtpTimestamp: number;\\n    source: number;\\n    timestamp: DOMHighResTimeStamp;\\n}\\n\\ninterface RTCRtpEncodingParameters extends RTCRtpCodingParameters {\\n    active?: boolean;\\n    maxBitrate?: number;\\n    maxFramerate?: number;\\n    networkPriority?: RTCPriorityType;\\n    priority?: RTCPriorityType;\\n    scaleResolutionDownBy?: number;\\n}\\n\\ninterface RTCRtpHeaderExtensionCapability {\\n    uri: string;\\n}\\n\\ninterface RTCRtpHeaderExtensionParameters {\\n    encrypted?: boolean;\\n    id: number;\\n    uri: string;\\n}\\n\\ninterface RTCRtpParameters {\\n    codecs: RTCRtpCodecParameters[];\\n    headerExtensions: RTCRtpHeaderExtensionParameters[];\\n    rtcp: RTCRtcpParameters;\\n}\\n\\ninterface RTCRtpReceiveParameters extends RTCRtpParameters {\\n}\\n\\ninterface RTCRtpSendParameters extends RTCRtpParameters {\\n    degradationPreference?: RTCDegradationPreference;\\n    encodings: RTCRtpEncodingParameters[];\\n    transactionId: string;\\n}\\n\\ninterface RTCRtpStreamStats extends RTCStats {\\n    codecId?: string;\\n    kind: string;\\n    ssrc: number;\\n    transportId?: string;\\n}\\n\\ninterface RTCRtpSynchronizationSource extends RTCRtpContributingSource {\\n}\\n\\ninterface RTCRtpTransceiverInit {\\n    direction?: RTCRtpTransceiverDirection;\\n    sendEncodings?: RTCRtpEncodingParameters[];\\n    streams?: MediaStream[];\\n}\\n\\ninterface RTCSentRtpStreamStats extends RTCRtpStreamStats {\\n    bytesSent?: number;\\n    packetsSent?: number;\\n}\\n\\ninterface RTCSessionDescriptionInit {\\n    sdp?: string;\\n    type: RTCSdpType;\\n}\\n\\ninterface RTCStats {\\n    id: string;\\n    timestamp: DOMHighResTimeStamp;\\n    type: RTCStatsType;\\n}\\n\\ninterface RTCTrackEventInit extends EventInit {\\n    receiver: RTCRtpReceiver;\\n    streams?: MediaStream[];\\n    track: MediaStreamTrack;\\n    transceiver: RTCRtpTransceiver;\\n}\\n\\ninterface RTCTransportStats extends RTCStats {\\n    bytesReceived?: number;\\n    bytesSent?: number;\\n    dtlsCipher?: string;\\n    dtlsState: RTCDtlsTransportState;\\n    localCertificateId?: string;\\n    remoteCertificateId?: string;\\n    selectedCandidatePairId?: string;\\n    srtpCipher?: string;\\n    tlsVersion?: string;\\n}\\n\\ninterface ReadableStreamGetReaderOptions {\\n    /**\\n     * Creates a ReadableStreamBYOBReader and locks the stream to the new reader.\\n     *\\n     * This call behaves the same way as the no-argument variant, except that it only works on readable byte streams, i.e. streams which were constructed specifically with the ability to handle \\\"bring your own buffer\\\" reading. The returned BYOB reader provides the ability to directly read individual chunks from the stream via its read() method, into developer-supplied buffers, allowing more precise control over allocation.\\n     */\\n    mode?: ReadableStreamReaderMode;\\n}\\n\\ninterface ReadableStreamReadDoneResult<T> {\\n    done: true;\\n    value?: T;\\n}\\n\\ninterface ReadableStreamReadValueResult<T> {\\n    done: false;\\n    value: T;\\n}\\n\\ninterface ReadableWritablePair<R = any, W = any> {\\n    readable: ReadableStream<R>;\\n    /**\\n     * Provides a convenient, chainable way of piping this readable stream through a transform stream (or any other { writable, readable } pair). It simply pipes the stream into the writable side of the supplied pair, and returns the readable side for further use.\\n     *\\n     * Piping a stream will lock it for the duration of the pipe, preventing any other consumer from acquiring a reader.\\n     */\\n    writable: WritableStream<W>;\\n}\\n\\ninterface RegistrationOptions {\\n    scope?: string;\\n    type?: WorkerType;\\n    updateViaCache?: ServiceWorkerUpdateViaCache;\\n}\\n\\ninterface ReportingObserverOptions {\\n    buffered?: boolean;\\n    types?: string[];\\n}\\n\\ninterface RequestInit {\\n    /** A BodyInit object or null to set request's body. */\\n    body?: BodyInit | null;\\n    /** A string indicating how the request will interact with the browser's cache to set request's cache. */\\n    cache?: RequestCache;\\n    /** A string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL. Sets request's credentials. */\\n    credentials?: RequestCredentials;\\n    /** A Headers object, an object literal, or an array of two-item arrays to set request's headers. */\\n    headers?: HeadersInit;\\n    /** A cryptographic hash of the resource to be fetched by request. Sets request's integrity. */\\n    integrity?: string;\\n    /** A boolean to set request's keepalive. */\\n    keepalive?: boolean;\\n    /** A string to set request's method. */\\n    method?: string;\\n    /** A string to indicate whether the request will use CORS, or will be restricted to same-origin URLs. Sets request's mode. */\\n    mode?: RequestMode;\\n    /** A string indicating whether request follows redirects, results in an error upon encountering a redirect, or returns the redirect (in an opaque fashion). Sets request's redirect. */\\n    redirect?: RequestRedirect;\\n    /** A string whose value is a same-origin URL, \\\"about:client\\\", or the empty string, to set request's referrer. */\\n    referrer?: string;\\n    /** A referrer policy to set request's referrerPolicy. */\\n    referrerPolicy?: ReferrerPolicy;\\n    /** An AbortSignal to set request's signal. */\\n    signal?: AbortSignal | null;\\n    /** Can only be null. Used to disassociate request from any Window. */\\n    window?: null;\\n}\\n\\ninterface ResizeObserverOptions {\\n    box?: ResizeObserverBoxOptions;\\n}\\n\\ninterface ResponseInit {\\n    headers?: HeadersInit;\\n    status?: number;\\n    statusText?: string;\\n}\\n\\ninterface RsaHashedImportParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n}\\n\\ninterface RsaHashedKeyAlgorithm extends RsaKeyAlgorithm {\\n    hash: KeyAlgorithm;\\n}\\n\\ninterface RsaHashedKeyGenParams extends RsaKeyGenParams {\\n    hash: HashAlgorithmIdentifier;\\n}\\n\\ninterface RsaKeyAlgorithm extends KeyAlgorithm {\\n    modulusLength: number;\\n    publicExponent: BigInteger;\\n}\\n\\ninterface RsaKeyGenParams extends Algorithm {\\n    modulusLength: number;\\n    publicExponent: BigInteger;\\n}\\n\\ninterface RsaOaepParams extends Algorithm {\\n    label?: BufferSource;\\n}\\n\\ninterface RsaOtherPrimesInfo {\\n    d?: string;\\n    r?: string;\\n    t?: string;\\n}\\n\\ninterface RsaPssParams extends Algorithm {\\n    saltLength: number;\\n}\\n\\ninterface SVGBoundingBoxOptions {\\n    clipped?: boolean;\\n    fill?: boolean;\\n    markers?: boolean;\\n    stroke?: boolean;\\n}\\n\\ninterface ScrollIntoViewOptions extends ScrollOptions {\\n    block?: ScrollLogicalPosition;\\n    inline?: ScrollLogicalPosition;\\n}\\n\\ninterface ScrollOptions {\\n    behavior?: ScrollBehavior;\\n}\\n\\ninterface ScrollToOptions extends ScrollOptions {\\n    left?: number;\\n    top?: number;\\n}\\n\\ninterface SecurityPolicyViolationEventInit extends EventInit {\\n    blockedURI?: string;\\n    columnNumber?: number;\\n    disposition: SecurityPolicyViolationEventDisposition;\\n    documentURI: string;\\n    effectiveDirective: string;\\n    lineNumber?: number;\\n    originalPolicy: string;\\n    referrer?: string;\\n    sample?: string;\\n    sourceFile?: string;\\n    statusCode: number;\\n    violatedDirective: string;\\n}\\n\\ninterface ShadowRootInit {\\n    delegatesFocus?: boolean;\\n    mode: ShadowRootMode;\\n    slotAssignment?: SlotAssignmentMode;\\n}\\n\\ninterface ShareData {\\n    files?: File[];\\n    text?: string;\\n    title?: string;\\n    url?: string;\\n}\\n\\ninterface SpeechSynthesisErrorEventInit extends SpeechSynthesisEventInit {\\n    error: SpeechSynthesisErrorCode;\\n}\\n\\ninterface SpeechSynthesisEventInit extends EventInit {\\n    charIndex?: number;\\n    charLength?: number;\\n    elapsedTime?: number;\\n    name?: string;\\n    utterance: SpeechSynthesisUtterance;\\n}\\n\\ninterface StaticRangeInit {\\n    endContainer: Node;\\n    endOffset: number;\\n    startContainer: Node;\\n    startOffset: number;\\n}\\n\\ninterface StereoPannerOptions extends AudioNodeOptions {\\n    pan?: number;\\n}\\n\\ninterface StorageEstimate {\\n    quota?: number;\\n    usage?: number;\\n}\\n\\ninterface StorageEventInit extends EventInit {\\n    key?: string | null;\\n    newValue?: string | null;\\n    oldValue?: string | null;\\n    storageArea?: Storage | null;\\n    url?: string;\\n}\\n\\ninterface StreamPipeOptions {\\n    preventAbort?: boolean;\\n    preventCancel?: boolean;\\n    /**\\n     * Pipes this readable stream to a given writable stream destination. The way in which the piping process behaves under various error conditions can be customized with a number of passed options. It returns a promise that fulfills when the piping process completes successfully, or rejects if any errors were encountered.\\n     *\\n     * Piping a stream will lock it for the duration of the pipe, preventing any other consumer from acquiring a reader.\\n     *\\n     * Errors and closures of the source and destination streams propagate as follows:\\n     *\\n     * An error in this source readable stream will abort destination, unless preventAbort is truthy. The returned promise will be rejected with the source's error, or with any error that occurs during aborting the destination.\\n     *\\n     * An error in destination will cancel this source readable stream, unless preventCancel is truthy. The returned promise will be rejected with the destination's error, or with any error that occurs during canceling the source.\\n     *\\n     * When this source readable stream closes, destination will be closed, unless preventClose is truthy. The returned promise will be fulfilled once this process completes, unless an error is encountered while closing the destination, in which case it will be rejected with that error.\\n     *\\n     * If destination starts out closed or closing, this source readable stream will be canceled, unless preventCancel is true. The returned promise will be rejected with an error indicating piping to a closed stream failed, or with any error that occurs during canceling the source.\\n     *\\n     * The signal option can be set to an AbortSignal to allow aborting an ongoing pipe operation via the corresponding AbortController. In this case, this source readable stream will be canceled, and destination aborted, unless the respective options preventCancel or preventAbort are set.\\n     */\\n    preventClose?: boolean;\\n    signal?: AbortSignal;\\n}\\n\\ninterface StructuredSerializeOptions {\\n    transfer?: Transferable[];\\n}\\n\\ninterface SubmitEventInit extends EventInit {\\n    submitter?: HTMLElement | null;\\n}\\n\\ninterface TextDecodeOptions {\\n    stream?: boolean;\\n}\\n\\ninterface TextDecoderOptions {\\n    fatal?: boolean;\\n    ignoreBOM?: boolean;\\n}\\n\\ninterface TextEncoderEncodeIntoResult {\\n    read: number;\\n    written: number;\\n}\\n\\ninterface ToggleEventInit extends EventInit {\\n    newState?: string;\\n    oldState?: string;\\n}\\n\\ninterface TouchEventInit extends EventModifierInit {\\n    changedTouches?: Touch[];\\n    targetTouches?: Touch[];\\n    touches?: Touch[];\\n}\\n\\ninterface TouchInit {\\n    altitudeAngle?: number;\\n    azimuthAngle?: number;\\n    clientX?: number;\\n    clientY?: number;\\n    force?: number;\\n    identifier: number;\\n    pageX?: number;\\n    pageY?: number;\\n    radiusX?: number;\\n    radiusY?: number;\\n    rotationAngle?: number;\\n    screenX?: number;\\n    screenY?: number;\\n    target: EventTarget;\\n    touchType?: TouchType;\\n}\\n\\ninterface TrackEventInit extends EventInit {\\n    track?: TextTrack | null;\\n}\\n\\ninterface Transformer<I = any, O = any> {\\n    flush?: TransformerFlushCallback<O>;\\n    readableType?: undefined;\\n    start?: TransformerStartCallback<O>;\\n    transform?: TransformerTransformCallback<I, O>;\\n    writableType?: undefined;\\n}\\n\\ninterface TransitionEventInit extends EventInit {\\n    elapsedTime?: number;\\n    propertyName?: string;\\n    pseudoElement?: string;\\n}\\n\\ninterface UIEventInit extends EventInit {\\n    detail?: number;\\n    view?: Window | null;\\n    /** @deprecated */\\n    which?: number;\\n}\\n\\ninterface ULongRange {\\n    max?: number;\\n    min?: number;\\n}\\n\\ninterface UnderlyingByteSource {\\n    autoAllocateChunkSize?: number;\\n    cancel?: UnderlyingSourceCancelCallback;\\n    pull?: (controller: ReadableByteStreamController) => void | PromiseLike<void>;\\n    start?: (controller: ReadableByteStreamController) => any;\\n    type: \\\"bytes\\\";\\n}\\n\\ninterface UnderlyingDefaultSource<R = any> {\\n    cancel?: UnderlyingSourceCancelCallback;\\n    pull?: (controller: ReadableStreamDefaultController<R>) => void | PromiseLike<void>;\\n    start?: (controller: ReadableStreamDefaultController<R>) => any;\\n    type?: undefined;\\n}\\n\\ninterface UnderlyingSink<W = any> {\\n    abort?: UnderlyingSinkAbortCallback;\\n    close?: UnderlyingSinkCloseCallback;\\n    start?: UnderlyingSinkStartCallback;\\n    type?: undefined;\\n    write?: UnderlyingSinkWriteCallback<W>;\\n}\\n\\ninterface UnderlyingSource<R = any> {\\n    autoAllocateChunkSize?: number;\\n    cancel?: UnderlyingSourceCancelCallback;\\n    pull?: UnderlyingSourcePullCallback<R>;\\n    start?: UnderlyingSourceStartCallback<R>;\\n    type?: ReadableStreamType;\\n}\\n\\ninterface ValidityStateFlags {\\n    badInput?: boolean;\\n    customError?: boolean;\\n    patternMismatch?: boolean;\\n    rangeOverflow?: boolean;\\n    rangeUnderflow?: boolean;\\n    stepMismatch?: boolean;\\n    tooLong?: boolean;\\n    tooShort?: boolean;\\n    typeMismatch?: boolean;\\n    valueMissing?: boolean;\\n}\\n\\ninterface VideoColorSpaceInit {\\n    fullRange?: boolean | null;\\n    matrix?: VideoMatrixCoefficients | null;\\n    primaries?: VideoColorPrimaries | null;\\n    transfer?: VideoTransferCharacteristics | null;\\n}\\n\\ninterface VideoConfiguration {\\n    bitrate: number;\\n    colorGamut?: ColorGamut;\\n    contentType: string;\\n    framerate: number;\\n    hdrMetadataType?: HdrMetadataType;\\n    height: number;\\n    scalabilityMode?: string;\\n    transferFunction?: TransferFunction;\\n    width: number;\\n}\\n\\ninterface VideoDecoderConfig {\\n    codec: string;\\n    codedHeight?: number;\\n    codedWidth?: number;\\n    colorSpace?: VideoColorSpaceInit;\\n    description?: BufferSource;\\n    displayAspectHeight?: number;\\n    displayAspectWidth?: number;\\n    hardwareAcceleration?: HardwareAcceleration;\\n    optimizeForLatency?: boolean;\\n}\\n\\ninterface VideoDecoderInit {\\n    error: WebCodecsErrorCallback;\\n    output: VideoFrameOutputCallback;\\n}\\n\\ninterface VideoDecoderSupport {\\n    config?: VideoDecoderConfig;\\n    supported?: boolean;\\n}\\n\\ninterface VideoEncoderConfig {\\n    alpha?: AlphaOption;\\n    avc?: AvcEncoderConfig;\\n    bitrate?: number;\\n    bitrateMode?: VideoEncoderBitrateMode;\\n    codec: string;\\n    displayHeight?: number;\\n    displayWidth?: number;\\n    framerate?: number;\\n    hardwareAcceleration?: HardwareAcceleration;\\n    height: number;\\n    latencyMode?: LatencyMode;\\n    scalabilityMode?: string;\\n    width: number;\\n}\\n\\ninterface VideoEncoderEncodeOptions {\\n    keyFrame?: boolean;\\n}\\n\\ninterface VideoEncoderInit {\\n    error: WebCodecsErrorCallback;\\n    output: EncodedVideoChunkOutputCallback;\\n}\\n\\ninterface VideoEncoderSupport {\\n    config?: VideoEncoderConfig;\\n    supported?: boolean;\\n}\\n\\ninterface VideoFrameBufferInit {\\n    codedHeight: number;\\n    codedWidth: number;\\n    colorSpace?: VideoColorSpaceInit;\\n    displayHeight?: number;\\n    displayWidth?: number;\\n    duration?: number;\\n    format: VideoPixelFormat;\\n    layout?: PlaneLayout[];\\n    timestamp: number;\\n    visibleRect?: DOMRectInit;\\n}\\n\\ninterface VideoFrameCallbackMetadata {\\n    captureTime?: DOMHighResTimeStamp;\\n    expectedDisplayTime: DOMHighResTimeStamp;\\n    height: number;\\n    mediaTime: number;\\n    presentationTime: DOMHighResTimeStamp;\\n    presentedFrames: number;\\n    processingDuration?: number;\\n    receiveTime?: DOMHighResTimeStamp;\\n    rtpTimestamp?: number;\\n    width: number;\\n}\\n\\ninterface VideoFrameCopyToOptions {\\n    layout?: PlaneLayout[];\\n    rect?: DOMRectInit;\\n}\\n\\ninterface VideoFrameInit {\\n    alpha?: AlphaOption;\\n    displayHeight?: number;\\n    displayWidth?: number;\\n    duration?: number;\\n    timestamp?: number;\\n    visibleRect?: DOMRectInit;\\n}\\n\\ninterface WaveShaperOptions extends AudioNodeOptions {\\n    curve?: number[] | Float32Array;\\n    oversample?: OverSampleType;\\n}\\n\\ninterface WebGLContextAttributes {\\n    alpha?: boolean;\\n    antialias?: boolean;\\n    depth?: boolean;\\n    desynchronized?: boolean;\\n    failIfMajorPerformanceCaveat?: boolean;\\n    powerPreference?: WebGLPowerPreference;\\n    premultipliedAlpha?: boolean;\\n    preserveDrawingBuffer?: boolean;\\n    stencil?: boolean;\\n}\\n\\ninterface WebGLContextEventInit extends EventInit {\\n    statusMessage?: string;\\n}\\n\\ninterface WebTransportCloseInfo {\\n    closeCode?: number;\\n    reason?: string;\\n}\\n\\ninterface WebTransportErrorOptions {\\n    source?: WebTransportErrorSource;\\n    streamErrorCode?: number | null;\\n}\\n\\ninterface WebTransportHash {\\n    algorithm?: string;\\n    value?: BufferSource;\\n}\\n\\ninterface WebTransportOptions {\\n    allowPooling?: boolean;\\n    congestionControl?: WebTransportCongestionControl;\\n    requireUnreliable?: boolean;\\n    serverCertificateHashes?: WebTransportHash[];\\n}\\n\\ninterface WebTransportSendStreamOptions {\\n    sendOrder?: number | null;\\n}\\n\\ninterface WheelEventInit extends MouseEventInit {\\n    deltaMode?: number;\\n    deltaX?: number;\\n    deltaY?: number;\\n    deltaZ?: number;\\n}\\n\\ninterface WindowPostMessageOptions extends StructuredSerializeOptions {\\n    targetOrigin?: string;\\n}\\n\\ninterface WorkerOptions {\\n    credentials?: RequestCredentials;\\n    name?: string;\\n    type?: WorkerType;\\n}\\n\\ninterface WorkletOptions {\\n    credentials?: RequestCredentials;\\n}\\n\\ninterface WriteParams {\\n    data?: BufferSource | Blob | string | null;\\n    position?: number | null;\\n    size?: number | null;\\n    type: WriteCommandType;\\n}\\n\\ntype NodeFilter = ((node: Node) => number) | { acceptNode(node: Node): number; };\\n\\ndeclare var NodeFilter: {\\n    readonly FILTER_ACCEPT: 1;\\n    readonly FILTER_REJECT: 2;\\n    readonly FILTER_SKIP: 3;\\n    readonly SHOW_ALL: 0xFFFFFFFF;\\n    readonly SHOW_ELEMENT: 0x1;\\n    readonly SHOW_ATTRIBUTE: 0x2;\\n    readonly SHOW_TEXT: 0x4;\\n    readonly SHOW_CDATA_SECTION: 0x8;\\n    readonly SHOW_ENTITY_REFERENCE: 0x10;\\n    readonly SHOW_ENTITY: 0x20;\\n    readonly SHOW_PROCESSING_INSTRUCTION: 0x40;\\n    readonly SHOW_COMMENT: 0x80;\\n    readonly SHOW_DOCUMENT: 0x100;\\n    readonly SHOW_DOCUMENT_TYPE: 0x200;\\n    readonly SHOW_DOCUMENT_FRAGMENT: 0x400;\\n    readonly SHOW_NOTATION: 0x800;\\n};\\n\\ntype XPathNSResolver = ((prefix: string | null) => string | null) | { lookupNamespaceURI(prefix: string | null): string | null; };\\n\\n/**\\n * The ANGLE_instanced_arrays extension is part of the WebGL API and allows to draw the same object, or groups of similar objects multiple times, if they share the same vertex data, primitive count and type.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays)\\n */\\ninterface ANGLE_instanced_arrays {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/drawArraysInstancedANGLE) */\\n    drawArraysInstancedANGLE(mode: GLenum, first: GLint, count: GLsizei, primcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/drawElementsInstancedANGLE) */\\n    drawElementsInstancedANGLE(mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr, primcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/vertexAttribDivisorANGLE) */\\n    vertexAttribDivisorANGLE(index: GLuint, divisor: GLuint): void;\\n    readonly VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 0x88FE;\\n}\\n\\ninterface ARIAMixin {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaAtomic) */\\n    ariaAtomic: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaAutoComplete) */\\n    ariaAutoComplete: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaBusy) */\\n    ariaBusy: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaChecked) */\\n    ariaChecked: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaColCount) */\\n    ariaColCount: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaColIndex) */\\n    ariaColIndex: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaColSpan) */\\n    ariaColSpan: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaCurrent) */\\n    ariaCurrent: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaDisabled) */\\n    ariaDisabled: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaExpanded) */\\n    ariaExpanded: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaHasPopup) */\\n    ariaHasPopup: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaHidden) */\\n    ariaHidden: string | null;\\n    ariaInvalid: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaKeyShortcuts) */\\n    ariaKeyShortcuts: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaLabel) */\\n    ariaLabel: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaLevel) */\\n    ariaLevel: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaLive) */\\n    ariaLive: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaModal) */\\n    ariaModal: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaMultiLine) */\\n    ariaMultiLine: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaMultiSelectable) */\\n    ariaMultiSelectable: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaOrientation) */\\n    ariaOrientation: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaPlaceholder) */\\n    ariaPlaceholder: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaPosInSet) */\\n    ariaPosInSet: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaPressed) */\\n    ariaPressed: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaReadOnly) */\\n    ariaReadOnly: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaRequired) */\\n    ariaRequired: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaRoleDescription) */\\n    ariaRoleDescription: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaRowCount) */\\n    ariaRowCount: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaRowIndex) */\\n    ariaRowIndex: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaRowSpan) */\\n    ariaRowSpan: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaSelected) */\\n    ariaSelected: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaSetSize) */\\n    ariaSetSize: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaSort) */\\n    ariaSort: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaValueMax) */\\n    ariaValueMax: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaValueMin) */\\n    ariaValueMin: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaValueNow) */\\n    ariaValueNow: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaValueText) */\\n    ariaValueText: string | null;\\n    role: string | null;\\n}\\n\\n/**\\n * A controller object that allows you to abort one or more DOM requests as and when desired.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortController)\\n */\\ninterface AbortController {\\n    /**\\n     * Returns the AbortSignal object associated with this object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortController/signal)\\n     */\\n    readonly signal: AbortSignal;\\n    /**\\n     * Invoking this method will set this object's AbortSignal's aborted flag and signal to any observers that the associated activity is to be aborted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortController/abort)\\n     */\\n    abort(reason?: any): void;\\n}\\n\\ndeclare var AbortController: {\\n    prototype: AbortController;\\n    new(): AbortController;\\n};\\n\\ninterface AbortSignalEventMap {\\n    \\\"abort\\\": Event;\\n}\\n\\n/**\\n * A signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal)\\n */\\ninterface AbortSignal extends EventTarget {\\n    /**\\n     * Returns true if this AbortSignal's AbortController has signaled to abort, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/aborted)\\n     */\\n    readonly aborted: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/abort_event) */\\n    onabort: ((this: AbortSignal, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/reason) */\\n    readonly reason: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/throwIfAborted) */\\n    throwIfAborted(): void;\\n    addEventListener<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var AbortSignal: {\\n    prototype: AbortSignal;\\n    new(): AbortSignal;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/abort_static) */\\n    abort(reason?: any): AbortSignal;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/timeout_static) */\\n    timeout(milliseconds: number): AbortSignal;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbstractRange) */\\ninterface AbstractRange {\\n    /**\\n     * Returns true if range is collapsed, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbstractRange/collapsed)\\n     */\\n    readonly collapsed: boolean;\\n    /**\\n     * Returns range's end node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbstractRange/endContainer)\\n     */\\n    readonly endContainer: Node;\\n    /**\\n     * Returns range's end offset.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbstractRange/endOffset)\\n     */\\n    readonly endOffset: number;\\n    /**\\n     * Returns range's start node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbstractRange/startContainer)\\n     */\\n    readonly startContainer: Node;\\n    /**\\n     * Returns range's start offset.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbstractRange/startOffset)\\n     */\\n    readonly startOffset: number;\\n}\\n\\ndeclare var AbstractRange: {\\n    prototype: AbstractRange;\\n    new(): AbstractRange;\\n};\\n\\ninterface AbstractWorkerEventMap {\\n    \\\"error\\\": ErrorEvent;\\n}\\n\\ninterface AbstractWorker {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/error_event) */\\n    onerror: ((this: AbstractWorker, ev: ErrorEvent) => any) | null;\\n    addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/**\\n * A node able to provide real-time frequency and time-domain analysis information. It is an AudioNode that passes the audio stream unchanged from the input to the output, but allows you to take the generated data, process it, and create audio visualizations.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode)\\n */\\ninterface AnalyserNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/fftSize) */\\n    fftSize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/frequencyBinCount) */\\n    readonly frequencyBinCount: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/maxDecibels) */\\n    maxDecibels: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/minDecibels) */\\n    minDecibels: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/smoothingTimeConstant) */\\n    smoothingTimeConstant: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/getByteFrequencyData) */\\n    getByteFrequencyData(array: Uint8Array): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/getByteTimeDomainData) */\\n    getByteTimeDomainData(array: Uint8Array): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/getFloatFrequencyData) */\\n    getFloatFrequencyData(array: Float32Array): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnalyserNode/getFloatTimeDomainData) */\\n    getFloatTimeDomainData(array: Float32Array): void;\\n}\\n\\ndeclare var AnalyserNode: {\\n    prototype: AnalyserNode;\\n    new(context: BaseAudioContext, options?: AnalyserOptions): AnalyserNode;\\n};\\n\\ninterface Animatable {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animate) */\\n    animate(keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeAnimationOptions): Animation;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAnimations) */\\n    getAnimations(options?: GetAnimationsOptions): Animation[];\\n}\\n\\ninterface AnimationEventMap {\\n    \\\"cancel\\\": AnimationPlaybackEvent;\\n    \\\"finish\\\": AnimationPlaybackEvent;\\n    \\\"remove\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation) */\\ninterface Animation extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/currentTime) */\\n    currentTime: CSSNumberish | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/effect) */\\n    effect: AnimationEffect | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/finished) */\\n    readonly finished: Promise<Animation>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/id) */\\n    id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/cancel_event) */\\n    oncancel: ((this: Animation, ev: AnimationPlaybackEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/finish_event) */\\n    onfinish: ((this: Animation, ev: AnimationPlaybackEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/remove_event) */\\n    onremove: ((this: Animation, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/pending) */\\n    readonly pending: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/playState) */\\n    readonly playState: AnimationPlayState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/playbackRate) */\\n    playbackRate: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/ready) */\\n    readonly ready: Promise<Animation>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/replaceState) */\\n    readonly replaceState: AnimationReplaceState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/startTime) */\\n    startTime: CSSNumberish | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/timeline) */\\n    timeline: AnimationTimeline | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/cancel) */\\n    cancel(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/commitStyles) */\\n    commitStyles(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/finish) */\\n    finish(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/pause) */\\n    pause(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/persist) */\\n    persist(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/play) */\\n    play(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/reverse) */\\n    reverse(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Animation/updatePlaybackRate) */\\n    updatePlaybackRate(playbackRate: number): void;\\n    addEventListener<K extends keyof AnimationEventMap>(type: K, listener: (this: Animation, ev: AnimationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AnimationEventMap>(type: K, listener: (this: Animation, ev: AnimationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Animation: {\\n    prototype: Animation;\\n    new(effect?: AnimationEffect | null, timeline?: AnimationTimeline | null): Animation;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationEffect) */\\ninterface AnimationEffect {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationEffect/getComputedTiming) */\\n    getComputedTiming(): ComputedEffectTiming;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationEffect/getTiming) */\\n    getTiming(): EffectTiming;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationEffect/updateTiming) */\\n    updateTiming(timing?: OptionalEffectTiming): void;\\n}\\n\\ndeclare var AnimationEffect: {\\n    prototype: AnimationEffect;\\n    new(): AnimationEffect;\\n};\\n\\n/**\\n * Events providing information related to animations.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationEvent)\\n */\\ninterface AnimationEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationEvent/animationName) */\\n    readonly animationName: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationEvent/elapsedTime) */\\n    readonly elapsedTime: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationEvent/pseudoElement) */\\n    readonly pseudoElement: string;\\n}\\n\\ndeclare var AnimationEvent: {\\n    prototype: AnimationEvent;\\n    new(type: string, animationEventInitDict?: AnimationEventInit): AnimationEvent;\\n};\\n\\ninterface AnimationFrameProvider {\\n    cancelAnimationFrame(handle: number): void;\\n    requestAnimationFrame(callback: FrameRequestCallback): number;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationPlaybackEvent) */\\ninterface AnimationPlaybackEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationPlaybackEvent/currentTime) */\\n    readonly currentTime: CSSNumberish | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationPlaybackEvent/timelineTime) */\\n    readonly timelineTime: CSSNumberish | null;\\n}\\n\\ndeclare var AnimationPlaybackEvent: {\\n    prototype: AnimationPlaybackEvent;\\n    new(type: string, eventInitDict?: AnimationPlaybackEventInit): AnimationPlaybackEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationTimeline) */\\ninterface AnimationTimeline {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AnimationTimeline/currentTime) */\\n    readonly currentTime: CSSNumberish | null;\\n}\\n\\ndeclare var AnimationTimeline: {\\n    prototype: AnimationTimeline;\\n    new(): AnimationTimeline;\\n};\\n\\n/**\\n * A DOM element's attribute as an object. In most DOM methods, you will probably directly retrieve the attribute as a string (e.g., Element.getAttribute(), but certain functions (e.g., Element.getAttributeNode()) or means of iterating give Attr types.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr)\\n */\\ninterface Attr extends Node {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/localName) */\\n    readonly localName: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/namespaceURI) */\\n    readonly namespaceURI: string | null;\\n    readonly ownerDocument: Document;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/ownerElement) */\\n    readonly ownerElement: Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/prefix) */\\n    readonly prefix: string | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/specified)\\n     */\\n    readonly specified: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Attr/value) */\\n    value: string;\\n}\\n\\ndeclare var Attr: {\\n    prototype: Attr;\\n    new(): Attr;\\n};\\n\\n/**\\n * A short audio asset residing in memory, created from an audio file using the AudioContext.decodeAudioData() method, or from raw data using AudioContext.createBuffer(). Once put into an AudioBuffer, the audio can then be played by being passed into an AudioBufferSourceNode.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBuffer)\\n */\\ninterface AudioBuffer {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBuffer/duration) */\\n    readonly duration: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBuffer/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBuffer/numberOfChannels) */\\n    readonly numberOfChannels: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBuffer/sampleRate) */\\n    readonly sampleRate: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBuffer/copyFromChannel) */\\n    copyFromChannel(destination: Float32Array, channelNumber: number, bufferOffset?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBuffer/copyToChannel) */\\n    copyToChannel(source: Float32Array, channelNumber: number, bufferOffset?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBuffer/getChannelData) */\\n    getChannelData(channel: number): Float32Array;\\n}\\n\\ndeclare var AudioBuffer: {\\n    prototype: AudioBuffer;\\n    new(options: AudioBufferOptions): AudioBuffer;\\n};\\n\\n/**\\n * An AudioScheduledSourceNode which represents an audio source consisting of in-memory audio data, stored in an AudioBuffer. It's especially useful for playing back audio which has particularly stringent timing accuracy requirements, such as for sounds that must match a specific rhythm and can be kept in memory rather than being played from disk or the network.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBufferSourceNode)\\n */\\ninterface AudioBufferSourceNode extends AudioScheduledSourceNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBufferSourceNode/buffer) */\\n    buffer: AudioBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBufferSourceNode/detune) */\\n    readonly detune: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBufferSourceNode/loop) */\\n    loop: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBufferSourceNode/loopEnd) */\\n    loopEnd: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBufferSourceNode/loopStart) */\\n    loopStart: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBufferSourceNode/playbackRate) */\\n    readonly playbackRate: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioBufferSourceNode/start) */\\n    start(when?: number, offset?: number, duration?: number): void;\\n    addEventListener<K extends keyof AudioScheduledSourceNodeEventMap>(type: K, listener: (this: AudioBufferSourceNode, ev: AudioScheduledSourceNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AudioScheduledSourceNodeEventMap>(type: K, listener: (this: AudioBufferSourceNode, ev: AudioScheduledSourceNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var AudioBufferSourceNode: {\\n    prototype: AudioBufferSourceNode;\\n    new(context: BaseAudioContext, options?: AudioBufferSourceOptions): AudioBufferSourceNode;\\n};\\n\\n/**\\n * An audio-processing graph built from audio modules linked together, each represented by an AudioNode.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext)\\n */\\ninterface AudioContext extends BaseAudioContext {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/baseLatency) */\\n    readonly baseLatency: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/outputLatency) */\\n    readonly outputLatency: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/close) */\\n    close(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/createMediaElementSource) */\\n    createMediaElementSource(mediaElement: HTMLMediaElement): MediaElementAudioSourceNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/createMediaStreamDestination) */\\n    createMediaStreamDestination(): MediaStreamAudioDestinationNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/createMediaStreamSource) */\\n    createMediaStreamSource(mediaStream: MediaStream): MediaStreamAudioSourceNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/getOutputTimestamp) */\\n    getOutputTimestamp(): AudioTimestamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/resume) */\\n    resume(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioContext/suspend) */\\n    suspend(): Promise<void>;\\n    addEventListener<K extends keyof BaseAudioContextEventMap>(type: K, listener: (this: AudioContext, ev: BaseAudioContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof BaseAudioContextEventMap>(type: K, listener: (this: AudioContext, ev: BaseAudioContextEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var AudioContext: {\\n    prototype: AudioContext;\\n    new(contextOptions?: AudioContextOptions): AudioContext;\\n};\\n\\n/**\\n * AudioDestinationNode has no output (as it is the output, no more AudioNode can be linked after it in the audio graph) and one input. The number of channels in the input must be between 0 and the maxChannelCount value or an exception is raised.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioDestinationNode)\\n */\\ninterface AudioDestinationNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioDestinationNode/maxChannelCount) */\\n    readonly maxChannelCount: number;\\n}\\n\\ndeclare var AudioDestinationNode: {\\n    prototype: AudioDestinationNode;\\n    new(): AudioDestinationNode;\\n};\\n\\n/**\\n * The position and orientation of the unique person listening to the audio scene, and is used in audio spatialization. All PannerNodes spatialize in relation to the AudioListener stored in the BaseAudioContext.listener attribute.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener)\\n */\\ninterface AudioListener {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/forwardX) */\\n    readonly forwardX: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/forwardY) */\\n    readonly forwardY: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/forwardZ) */\\n    readonly forwardZ: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/positionX) */\\n    readonly positionX: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/positionY) */\\n    readonly positionY: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/positionZ) */\\n    readonly positionZ: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/upX) */\\n    readonly upX: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/upY) */\\n    readonly upY: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/upZ) */\\n    readonly upZ: AudioParam;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/setOrientation)\\n     */\\n    setOrientation(x: number, y: number, z: number, xUp: number, yUp: number, zUp: number): void;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioListener/setPosition)\\n     */\\n    setPosition(x: number, y: number, z: number): void;\\n}\\n\\ndeclare var AudioListener: {\\n    prototype: AudioListener;\\n    new(): AudioListener;\\n};\\n\\n/**\\n * A generic interface for representing an audio processing module. Examples include:\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode)\\n */\\ninterface AudioNode extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode/channelCount) */\\n    channelCount: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode/channelCountMode) */\\n    channelCountMode: ChannelCountMode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode/channelInterpretation) */\\n    channelInterpretation: ChannelInterpretation;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode/context) */\\n    readonly context: BaseAudioContext;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode/numberOfInputs) */\\n    readonly numberOfInputs: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode/numberOfOutputs) */\\n    readonly numberOfOutputs: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode/connect) */\\n    connect(destinationNode: AudioNode, output?: number, input?: number): AudioNode;\\n    connect(destinationParam: AudioParam, output?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioNode/disconnect) */\\n    disconnect(): void;\\n    disconnect(output: number): void;\\n    disconnect(destinationNode: AudioNode): void;\\n    disconnect(destinationNode: AudioNode, output: number): void;\\n    disconnect(destinationNode: AudioNode, output: number, input: number): void;\\n    disconnect(destinationParam: AudioParam): void;\\n    disconnect(destinationParam: AudioParam, output: number): void;\\n}\\n\\ndeclare var AudioNode: {\\n    prototype: AudioNode;\\n    new(): AudioNode;\\n};\\n\\n/**\\n * The Web Audio API's AudioParam interface represents an audio-related parameter, usually a parameter of an AudioNode (such as GainNode.gain).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam)\\n */\\ninterface AudioParam {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/automationRate) */\\n    automationRate: AutomationRate;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/defaultValue) */\\n    readonly defaultValue: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/maxValue) */\\n    readonly maxValue: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/minValue) */\\n    readonly minValue: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/value) */\\n    value: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/cancelAndHoldAtTime) */\\n    cancelAndHoldAtTime(cancelTime: number): AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/cancelScheduledValues) */\\n    cancelScheduledValues(cancelTime: number): AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/exponentialRampToValueAtTime) */\\n    exponentialRampToValueAtTime(value: number, endTime: number): AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/linearRampToValueAtTime) */\\n    linearRampToValueAtTime(value: number, endTime: number): AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/setTargetAtTime) */\\n    setTargetAtTime(target: number, startTime: number, timeConstant: number): AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/setValueAtTime) */\\n    setValueAtTime(value: number, startTime: number): AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/setValueCurveAtTime) */\\n    setValueCurveAtTime(values: number[] | Float32Array, startTime: number, duration: number): AudioParam;\\n}\\n\\ndeclare var AudioParam: {\\n    prototype: AudioParam;\\n    new(): AudioParam;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParamMap) */\\ninterface AudioParamMap {\\n    forEach(callbackfn: (value: AudioParam, key: string, parent: AudioParamMap) => void, thisArg?: any): void;\\n}\\n\\ndeclare var AudioParamMap: {\\n    prototype: AudioParamMap;\\n    new(): AudioParamMap;\\n};\\n\\n/**\\n * The Web Audio API events that occur when a ScriptProcessorNode input buffer is ready to be processed.\\n * @deprecated As of the August 29 2014 Web Audio API spec publication, this feature has been marked as deprecated, and is soon to be replaced by AudioWorklet.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioProcessingEvent)\\n */\\ninterface AudioProcessingEvent extends Event {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioProcessingEvent/inputBuffer)\\n     */\\n    readonly inputBuffer: AudioBuffer;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioProcessingEvent/outputBuffer)\\n     */\\n    readonly outputBuffer: AudioBuffer;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioProcessingEvent/playbackTime)\\n     */\\n    readonly playbackTime: number;\\n}\\n\\n/** @deprecated */\\ndeclare var AudioProcessingEvent: {\\n    prototype: AudioProcessingEvent;\\n    new(type: string, eventInitDict: AudioProcessingEventInit): AudioProcessingEvent;\\n};\\n\\ninterface AudioScheduledSourceNodeEventMap {\\n    \\\"ended\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioScheduledSourceNode) */\\ninterface AudioScheduledSourceNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioScheduledSourceNode/ended_event) */\\n    onended: ((this: AudioScheduledSourceNode, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioScheduledSourceNode/start) */\\n    start(when?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioScheduledSourceNode/stop) */\\n    stop(when?: number): void;\\n    addEventListener<K extends keyof AudioScheduledSourceNodeEventMap>(type: K, listener: (this: AudioScheduledSourceNode, ev: AudioScheduledSourceNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AudioScheduledSourceNodeEventMap>(type: K, listener: (this: AudioScheduledSourceNode, ev: AudioScheduledSourceNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var AudioScheduledSourceNode: {\\n    prototype: AudioScheduledSourceNode;\\n    new(): AudioScheduledSourceNode;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorklet)\\n */\\ninterface AudioWorklet extends Worklet {\\n}\\n\\ndeclare var AudioWorklet: {\\n    prototype: AudioWorklet;\\n    new(): AudioWorklet;\\n};\\n\\ninterface AudioWorkletNodeEventMap {\\n    \\\"processorerror\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorkletNode)\\n */\\ninterface AudioWorkletNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorkletNode/processorerror_event) */\\n    onprocessorerror: ((this: AudioWorkletNode, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorkletNode/parameters) */\\n    readonly parameters: AudioParamMap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioWorkletNode/port) */\\n    readonly port: MessagePort;\\n    addEventListener<K extends keyof AudioWorkletNodeEventMap>(type: K, listener: (this: AudioWorkletNode, ev: AudioWorkletNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AudioWorkletNodeEventMap>(type: K, listener: (this: AudioWorkletNode, ev: AudioWorkletNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var AudioWorkletNode: {\\n    prototype: AudioWorkletNode;\\n    new(context: BaseAudioContext, name: string, options?: AudioWorkletNodeOptions): AudioWorkletNode;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorAssertionResponse)\\n */\\ninterface AuthenticatorAssertionResponse extends AuthenticatorResponse {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorAssertionResponse/authenticatorData) */\\n    readonly authenticatorData: ArrayBuffer;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorAssertionResponse/signature) */\\n    readonly signature: ArrayBuffer;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorAssertionResponse/userHandle) */\\n    readonly userHandle: ArrayBuffer | null;\\n}\\n\\ndeclare var AuthenticatorAssertionResponse: {\\n    prototype: AuthenticatorAssertionResponse;\\n    new(): AuthenticatorAssertionResponse;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorAttestationResponse)\\n */\\ninterface AuthenticatorAttestationResponse extends AuthenticatorResponse {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorAttestationResponse/attestationObject) */\\n    readonly attestationObject: ArrayBuffer;\\n    getAuthenticatorData(): ArrayBuffer;\\n    getPublicKey(): ArrayBuffer | null;\\n    getPublicKeyAlgorithm(): COSEAlgorithmIdentifier;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorAttestationResponse/getTransports) */\\n    getTransports(): string[];\\n}\\n\\ndeclare var AuthenticatorAttestationResponse: {\\n    prototype: AuthenticatorAttestationResponse;\\n    new(): AuthenticatorAttestationResponse;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorResponse)\\n */\\ninterface AuthenticatorResponse {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AuthenticatorResponse/clientDataJSON) */\\n    readonly clientDataJSON: ArrayBuffer;\\n}\\n\\ndeclare var AuthenticatorResponse: {\\n    prototype: AuthenticatorResponse;\\n    new(): AuthenticatorResponse;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BarProp) */\\ninterface BarProp {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BarProp/visible) */\\n    readonly visible: boolean;\\n}\\n\\ndeclare var BarProp: {\\n    prototype: BarProp;\\n    new(): BarProp;\\n};\\n\\ninterface BaseAudioContextEventMap {\\n    \\\"statechange\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext) */\\ninterface BaseAudioContext extends EventTarget {\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/audioWorklet)\\n     */\\n    readonly audioWorklet: AudioWorklet;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/currentTime) */\\n    readonly currentTime: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/destination) */\\n    readonly destination: AudioDestinationNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/listener) */\\n    readonly listener: AudioListener;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/statechange_event) */\\n    onstatechange: ((this: BaseAudioContext, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/sampleRate) */\\n    readonly sampleRate: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/state) */\\n    readonly state: AudioContextState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createAnalyser) */\\n    createAnalyser(): AnalyserNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createBiquadFilter) */\\n    createBiquadFilter(): BiquadFilterNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createBuffer) */\\n    createBuffer(numberOfChannels: number, length: number, sampleRate: number): AudioBuffer;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createBufferSource) */\\n    createBufferSource(): AudioBufferSourceNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createChannelMerger) */\\n    createChannelMerger(numberOfInputs?: number): ChannelMergerNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createChannelSplitter) */\\n    createChannelSplitter(numberOfOutputs?: number): ChannelSplitterNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createConstantSource) */\\n    createConstantSource(): ConstantSourceNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createConvolver) */\\n    createConvolver(): ConvolverNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createDelay) */\\n    createDelay(maxDelayTime?: number): DelayNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createDynamicsCompressor) */\\n    createDynamicsCompressor(): DynamicsCompressorNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createGain) */\\n    createGain(): GainNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createIIRFilter) */\\n    createIIRFilter(feedforward: number[], feedback: number[]): IIRFilterNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createOscillator) */\\n    createOscillator(): OscillatorNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createPanner) */\\n    createPanner(): PannerNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createPeriodicWave) */\\n    createPeriodicWave(real: number[] | Float32Array, imag: number[] | Float32Array, constraints?: PeriodicWaveConstraints): PeriodicWave;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createScriptProcessor)\\n     */\\n    createScriptProcessor(bufferSize?: number, numberOfInputChannels?: number, numberOfOutputChannels?: number): ScriptProcessorNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createStereoPanner) */\\n    createStereoPanner(): StereoPannerNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createWaveShaper) */\\n    createWaveShaper(): WaveShaperNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/decodeAudioData) */\\n    decodeAudioData(audioData: ArrayBuffer, successCallback?: DecodeSuccessCallback | null, errorCallback?: DecodeErrorCallback | null): Promise<AudioBuffer>;\\n    addEventListener<K extends keyof BaseAudioContextEventMap>(type: K, listener: (this: BaseAudioContext, ev: BaseAudioContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof BaseAudioContextEventMap>(type: K, listener: (this: BaseAudioContext, ev: BaseAudioContextEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var BaseAudioContext: {\\n    prototype: BaseAudioContext;\\n    new(): BaseAudioContext;\\n};\\n\\n/**\\n * The beforeunload event is fired when the window, the document and its resources are about to be unloaded.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BeforeUnloadEvent)\\n */\\ninterface BeforeUnloadEvent extends Event {\\n    returnValue: any;\\n}\\n\\ndeclare var BeforeUnloadEvent: {\\n    prototype: BeforeUnloadEvent;\\n    new(): BeforeUnloadEvent;\\n};\\n\\n/**\\n * A simple low-order filter, and is created using the AudioContext.createBiquadFilter() method. It is an AudioNode that can represent different kinds of filters, tone control devices, and graphic equalizers.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BiquadFilterNode)\\n */\\ninterface BiquadFilterNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BiquadFilterNode/Q) */\\n    readonly Q: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BiquadFilterNode/detune) */\\n    readonly detune: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BiquadFilterNode/frequency) */\\n    readonly frequency: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BiquadFilterNode/gain) */\\n    readonly gain: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BiquadFilterNode/type) */\\n    type: BiquadFilterType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BiquadFilterNode/getFrequencyResponse) */\\n    getFrequencyResponse(frequencyHz: Float32Array, magResponse: Float32Array, phaseResponse: Float32Array): void;\\n}\\n\\ndeclare var BiquadFilterNode: {\\n    prototype: BiquadFilterNode;\\n    new(context: BaseAudioContext, options?: BiquadFilterOptions): BiquadFilterNode;\\n};\\n\\n/**\\n * A file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob)\\n */\\ninterface Blob {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */\\n    readonly size: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */\\n    readonly type: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/arrayBuffer) */\\n    arrayBuffer(): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */\\n    slice(start?: number, end?: number, contentType?: string): Blob;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/stream) */\\n    stream(): ReadableStream<Uint8Array>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */\\n    text(): Promise<string>;\\n}\\n\\ndeclare var Blob: {\\n    prototype: Blob;\\n    new(blobParts?: BlobPart[], options?: BlobPropertyBag): Blob;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BlobEvent) */\\ninterface BlobEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BlobEvent/data) */\\n    readonly data: Blob;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BlobEvent/timecode) */\\n    readonly timecode: DOMHighResTimeStamp;\\n}\\n\\ndeclare var BlobEvent: {\\n    prototype: BlobEvent;\\n    new(type: string, eventInitDict: BlobEventInit): BlobEvent;\\n};\\n\\ninterface Body {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/body) */\\n    readonly body: ReadableStream<Uint8Array> | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bodyUsed) */\\n    readonly bodyUsed: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/arrayBuffer) */\\n    arrayBuffer(): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */\\n    blob(): Promise<Blob>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/formData) */\\n    formData(): Promise<FormData>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/json) */\\n    json(): Promise<any>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/text) */\\n    text(): Promise<string>;\\n}\\n\\ninterface BroadcastChannelEventMap {\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel) */\\ninterface BroadcastChannel extends EventTarget {\\n    /**\\n     * Returns the channel name (as passed to the constructor).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/name)\\n     */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/message_event) */\\n    onmessage: ((this: BroadcastChannel, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/messageerror_event) */\\n    onmessageerror: ((this: BroadcastChannel, ev: MessageEvent) => any) | null;\\n    /**\\n     * Closes the BroadcastChannel object, opening it up to garbage collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/close)\\n     */\\n    close(): void;\\n    /**\\n     * Sends the given message to other BroadcastChannel objects set up for this channel. Messages can be structured objects, e.g. nested objects and arrays.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/postMessage)\\n     */\\n    postMessage(message: any): void;\\n    addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var BroadcastChannel: {\\n    prototype: BroadcastChannel;\\n    new(name: string): BroadcastChannel;\\n};\\n\\n/**\\n * This Streams API interface provides a built-in byte length queuing strategy that can be used when constructing streams.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ByteLengthQueuingStrategy)\\n */\\ninterface ByteLengthQueuingStrategy extends QueuingStrategy<ArrayBufferView> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ByteLengthQueuingStrategy/highWaterMark) */\\n    readonly highWaterMark: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ByteLengthQueuingStrategy/size) */\\n    readonly size: QueuingStrategySize<ArrayBufferView>;\\n}\\n\\ndeclare var ByteLengthQueuingStrategy: {\\n    prototype: ByteLengthQueuingStrategy;\\n    new(init: QueuingStrategyInit): ByteLengthQueuingStrategy;\\n};\\n\\n/**\\n * A CDATA section that can be used within XML to include extended portions of unescaped text. The symbols < and & don’t need escaping as they normally do when inside a CDATA section.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CDATASection)\\n */\\ninterface CDATASection extends Text {\\n}\\n\\ndeclare var CDATASection: {\\n    prototype: CDATASection;\\n    new(): CDATASection;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSAnimation) */\\ninterface CSSAnimation extends Animation {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSAnimation/animationName) */\\n    readonly animationName: string;\\n    addEventListener<K extends keyof AnimationEventMap>(type: K, listener: (this: CSSAnimation, ev: AnimationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AnimationEventMap>(type: K, listener: (this: CSSAnimation, ev: AnimationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var CSSAnimation: {\\n    prototype: CSSAnimation;\\n    new(): CSSAnimation;\\n};\\n\\n/**\\n * A single condition CSS at-rule, which consists of a condition and a statement block. It is a child of CSSGroupingRule.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSConditionRule)\\n */\\ninterface CSSConditionRule extends CSSGroupingRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSConditionRule/conditionText) */\\n    readonly conditionText: string;\\n}\\n\\ndeclare var CSSConditionRule: {\\n    prototype: CSSConditionRule;\\n    new(): CSSConditionRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSContainerRule) */\\ninterface CSSContainerRule extends CSSConditionRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSContainerRule/containerName) */\\n    readonly containerName: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSContainerRule/containerQuery) */\\n    readonly containerQuery: string;\\n}\\n\\ndeclare var CSSContainerRule: {\\n    prototype: CSSContainerRule;\\n    new(): CSSContainerRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule) */\\ninterface CSSCounterStyleRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/additiveSymbols) */\\n    additiveSymbols: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/fallback) */\\n    fallback: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/name) */\\n    name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/negative) */\\n    negative: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/pad) */\\n    pad: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/prefix) */\\n    prefix: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/range) */\\n    range: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/speakAs) */\\n    speakAs: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/suffix) */\\n    suffix: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/symbols) */\\n    symbols: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSCounterStyleRule/system) */\\n    system: string;\\n}\\n\\ndeclare var CSSCounterStyleRule: {\\n    prototype: CSSCounterStyleRule;\\n    new(): CSSCounterStyleRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontFaceRule) */\\ninterface CSSFontFaceRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontFaceRule/style) */\\n    readonly style: CSSStyleDeclaration;\\n}\\n\\ndeclare var CSSFontFaceRule: {\\n    prototype: CSSFontFaceRule;\\n    new(): CSSFontFaceRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontFeatureValuesRule) */\\ninterface CSSFontFeatureValuesRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontFeatureValuesRule/fontFamily) */\\n    fontFamily: string;\\n}\\n\\ndeclare var CSSFontFeatureValuesRule: {\\n    prototype: CSSFontFeatureValuesRule;\\n    new(): CSSFontFeatureValuesRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontPaletteValuesRule) */\\ninterface CSSFontPaletteValuesRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontPaletteValuesRule/basePalette) */\\n    readonly basePalette: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontPaletteValuesRule/fontFamily) */\\n    readonly fontFamily: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontPaletteValuesRule/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSFontPaletteValuesRule/overrideColors) */\\n    readonly overrideColors: string;\\n}\\n\\ndeclare var CSSFontPaletteValuesRule: {\\n    prototype: CSSFontPaletteValuesRule;\\n    new(): CSSFontPaletteValuesRule;\\n};\\n\\n/**\\n * Any CSS at-rule that contains other rules nested within it.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSGroupingRule)\\n */\\ninterface CSSGroupingRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSGroupingRule/cssRules) */\\n    readonly cssRules: CSSRuleList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSGroupingRule/deleteRule) */\\n    deleteRule(index: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSGroupingRule/insertRule) */\\n    insertRule(rule: string, index?: number): number;\\n}\\n\\ndeclare var CSSGroupingRule: {\\n    prototype: CSSGroupingRule;\\n    new(): CSSGroupingRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSImageValue) */\\ninterface CSSImageValue extends CSSStyleValue {\\n}\\n\\ndeclare var CSSImageValue: {\\n    prototype: CSSImageValue;\\n    new(): CSSImageValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSImportRule) */\\ninterface CSSImportRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSImportRule/href) */\\n    readonly href: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSImportRule/layerName) */\\n    readonly layerName: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSImportRule/media) */\\n    readonly media: MediaList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSImportRule/styleSheet) */\\n    readonly styleSheet: CSSStyleSheet | null;\\n}\\n\\ndeclare var CSSImportRule: {\\n    prototype: CSSImportRule;\\n    new(): CSSImportRule;\\n};\\n\\n/**\\n * An object representing a set of style for a given keyframe. It corresponds to the contains of a single keyframe of a @keyframes at-rule. It implements the CSSRule interface with a type value of 8 (CSSRule.KEYFRAME_RULE).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframeRule)\\n */\\ninterface CSSKeyframeRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframeRule/keyText) */\\n    keyText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframeRule/style) */\\n    readonly style: CSSStyleDeclaration;\\n}\\n\\ndeclare var CSSKeyframeRule: {\\n    prototype: CSSKeyframeRule;\\n    new(): CSSKeyframeRule;\\n};\\n\\n/**\\n * An object representing a complete set of keyframes for a CSS animation. It corresponds to the contains of a whole @keyframes at-rule. It implements the CSSRule interface with a type value of 7 (CSSRule.KEYFRAMES_RULE).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframesRule)\\n */\\ninterface CSSKeyframesRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframesRule/cssRules) */\\n    readonly cssRules: CSSRuleList;\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframesRule/name) */\\n    name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframesRule/appendRule) */\\n    appendRule(rule: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframesRule/deleteRule) */\\n    deleteRule(select: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeyframesRule/findRule) */\\n    findRule(select: string): CSSKeyframeRule | null;\\n    [index: number]: CSSKeyframeRule;\\n}\\n\\ndeclare var CSSKeyframesRule: {\\n    prototype: CSSKeyframesRule;\\n    new(): CSSKeyframesRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeywordValue) */\\ninterface CSSKeywordValue extends CSSStyleValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeywordValue/value) */\\n    value: string;\\n}\\n\\ndeclare var CSSKeywordValue: {\\n    prototype: CSSKeywordValue;\\n    new(value: string): CSSKeywordValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSLayerBlockRule) */\\ninterface CSSLayerBlockRule extends CSSGroupingRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSLayerBlockRule/name) */\\n    readonly name: string;\\n}\\n\\ndeclare var CSSLayerBlockRule: {\\n    prototype: CSSLayerBlockRule;\\n    new(): CSSLayerBlockRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSLayerStatementRule) */\\ninterface CSSLayerStatementRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSLayerStatementRule/nameList) */\\n    readonly nameList: ReadonlyArray<string>;\\n}\\n\\ndeclare var CSSLayerStatementRule: {\\n    prototype: CSSLayerStatementRule;\\n    new(): CSSLayerStatementRule;\\n};\\n\\ninterface CSSMathClamp extends CSSMathValue {\\n    readonly lower: CSSNumericValue;\\n    readonly upper: CSSNumericValue;\\n    readonly value: CSSNumericValue;\\n}\\n\\ndeclare var CSSMathClamp: {\\n    prototype: CSSMathClamp;\\n    new(lower: CSSNumberish, value: CSSNumberish, upper: CSSNumberish): CSSMathClamp;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathInvert) */\\ninterface CSSMathInvert extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathInvert/value) */\\n    readonly value: CSSNumericValue;\\n}\\n\\ndeclare var CSSMathInvert: {\\n    prototype: CSSMathInvert;\\n    new(arg: CSSNumberish): CSSMathInvert;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathMax) */\\ninterface CSSMathMax extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathMax/values) */\\n    readonly values: CSSNumericArray;\\n}\\n\\ndeclare var CSSMathMax: {\\n    prototype: CSSMathMax;\\n    new(...args: CSSNumberish[]): CSSMathMax;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathMin) */\\ninterface CSSMathMin extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathMin/values) */\\n    readonly values: CSSNumericArray;\\n}\\n\\ndeclare var CSSMathMin: {\\n    prototype: CSSMathMin;\\n    new(...args: CSSNumberish[]): CSSMathMin;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathNegate) */\\ninterface CSSMathNegate extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathNegate/value) */\\n    readonly value: CSSNumericValue;\\n}\\n\\ndeclare var CSSMathNegate: {\\n    prototype: CSSMathNegate;\\n    new(arg: CSSNumberish): CSSMathNegate;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathProduct) */\\ninterface CSSMathProduct extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathProduct/values) */\\n    readonly values: CSSNumericArray;\\n}\\n\\ndeclare var CSSMathProduct: {\\n    prototype: CSSMathProduct;\\n    new(...args: CSSNumberish[]): CSSMathProduct;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathSum) */\\ninterface CSSMathSum extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathSum/values) */\\n    readonly values: CSSNumericArray;\\n}\\n\\ndeclare var CSSMathSum: {\\n    prototype: CSSMathSum;\\n    new(...args: CSSNumberish[]): CSSMathSum;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathValue) */\\ninterface CSSMathValue extends CSSNumericValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathValue/operator) */\\n    readonly operator: CSSMathOperator;\\n}\\n\\ndeclare var CSSMathValue: {\\n    prototype: CSSMathValue;\\n    new(): CSSMathValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMatrixComponent) */\\ninterface CSSMatrixComponent extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMatrixComponent/matrix) */\\n    matrix: DOMMatrix;\\n}\\n\\ndeclare var CSSMatrixComponent: {\\n    prototype: CSSMatrixComponent;\\n    new(matrix: DOMMatrixReadOnly, options?: CSSMatrixComponentOptions): CSSMatrixComponent;\\n};\\n\\n/**\\n * A single CSS @media rule. It implements the CSSConditionRule interface, and therefore the CSSGroupingRule and the CSSRule interface with a type value of 4 (CSSRule.MEDIA_RULE).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMediaRule)\\n */\\ninterface CSSMediaRule extends CSSConditionRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMediaRule/media) */\\n    readonly media: MediaList;\\n}\\n\\ndeclare var CSSMediaRule: {\\n    prototype: CSSMediaRule;\\n    new(): CSSMediaRule;\\n};\\n\\n/**\\n * An object representing a single CSS @namespace at-rule. It implements the CSSRule interface, with a type value of 10 (CSSRule.NAMESPACE_RULE).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNamespaceRule)\\n */\\ninterface CSSNamespaceRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNamespaceRule/namespaceURI) */\\n    readonly namespaceURI: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNamespaceRule/prefix) */\\n    readonly prefix: string;\\n}\\n\\ndeclare var CSSNamespaceRule: {\\n    prototype: CSSNamespaceRule;\\n    new(): CSSNamespaceRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericArray) */\\ninterface CSSNumericArray {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericArray/length) */\\n    readonly length: number;\\n    forEach(callbackfn: (value: CSSNumericValue, key: number, parent: CSSNumericArray) => void, thisArg?: any): void;\\n    [index: number]: CSSNumericValue;\\n}\\n\\ndeclare var CSSNumericArray: {\\n    prototype: CSSNumericArray;\\n    new(): CSSNumericArray;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue) */\\ninterface CSSNumericValue extends CSSStyleValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/add) */\\n    add(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/div) */\\n    div(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/equals) */\\n    equals(...value: CSSNumberish[]): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/max) */\\n    max(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/min) */\\n    min(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/mul) */\\n    mul(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/sub) */\\n    sub(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/to) */\\n    to(unit: string): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/toSum) */\\n    toSum(...units: string[]): CSSMathSum;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/type) */\\n    type(): CSSNumericType;\\n}\\n\\ndeclare var CSSNumericValue: {\\n    prototype: CSSNumericValue;\\n    new(): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/parse_static) */\\n    parse(cssText: string): CSSNumericValue;\\n};\\n\\n/**\\n * CSSPageRule is an interface representing a single CSS @page rule. It implements the CSSRule interface with a type value of 6 (CSSRule.PAGE_RULE).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPageRule)\\n */\\ninterface CSSPageRule extends CSSGroupingRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPageRule/selectorText) */\\n    selectorText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPageRule/style) */\\n    readonly style: CSSStyleDeclaration;\\n}\\n\\ndeclare var CSSPageRule: {\\n    prototype: CSSPageRule;\\n    new(): CSSPageRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPerspective) */\\ninterface CSSPerspective extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPerspective/length) */\\n    length: CSSPerspectiveValue;\\n}\\n\\ndeclare var CSSPerspective: {\\n    prototype: CSSPerspective;\\n    new(length: CSSPerspectiveValue): CSSPerspective;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPropertyRule) */\\ninterface CSSPropertyRule extends CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPropertyRule/inherits) */\\n    readonly inherits: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPropertyRule/initialValue) */\\n    readonly initialValue: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPropertyRule/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPropertyRule/syntax) */\\n    readonly syntax: string;\\n}\\n\\ndeclare var CSSPropertyRule: {\\n    prototype: CSSPropertyRule;\\n    new(): CSSPropertyRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate) */\\ninterface CSSRotate extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate/angle) */\\n    angle: CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate/x) */\\n    x: CSSNumberish;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate/y) */\\n    y: CSSNumberish;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate/z) */\\n    z: CSSNumberish;\\n}\\n\\ndeclare var CSSRotate: {\\n    prototype: CSSRotate;\\n    new(angle: CSSNumericValue): CSSRotate;\\n    new(x: CSSNumberish, y: CSSNumberish, z: CSSNumberish, angle: CSSNumericValue): CSSRotate;\\n};\\n\\n/**\\n * A single CSS rule. There are several types of rules, listed in the Type constants section below.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRule)\\n */\\ninterface CSSRule {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRule/cssText) */\\n    cssText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRule/parentRule) */\\n    readonly parentRule: CSSRule | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRule/parentStyleSheet) */\\n    readonly parentStyleSheet: CSSStyleSheet | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRule/type)\\n     */\\n    readonly type: number;\\n    readonly STYLE_RULE: 1;\\n    readonly CHARSET_RULE: 2;\\n    readonly IMPORT_RULE: 3;\\n    readonly MEDIA_RULE: 4;\\n    readonly FONT_FACE_RULE: 5;\\n    readonly PAGE_RULE: 6;\\n    readonly NAMESPACE_RULE: 10;\\n    readonly KEYFRAMES_RULE: 7;\\n    readonly KEYFRAME_RULE: 8;\\n    readonly SUPPORTS_RULE: 12;\\n}\\n\\ndeclare var CSSRule: {\\n    prototype: CSSRule;\\n    new(): CSSRule;\\n    readonly STYLE_RULE: 1;\\n    readonly CHARSET_RULE: 2;\\n    readonly IMPORT_RULE: 3;\\n    readonly MEDIA_RULE: 4;\\n    readonly FONT_FACE_RULE: 5;\\n    readonly PAGE_RULE: 6;\\n    readonly NAMESPACE_RULE: 10;\\n    readonly KEYFRAMES_RULE: 7;\\n    readonly KEYFRAME_RULE: 8;\\n    readonly SUPPORTS_RULE: 12;\\n};\\n\\n/**\\n * A CSSRuleList is an (indirect-modify only) array-like object containing an ordered collection of CSSRule objects.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRuleList)\\n */\\ninterface CSSRuleList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRuleList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRuleList/item) */\\n    item(index: number): CSSRule | null;\\n    [index: number]: CSSRule;\\n}\\n\\ndeclare var CSSRuleList: {\\n    prototype: CSSRuleList;\\n    new(): CSSRuleList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSScale) */\\ninterface CSSScale extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSScale/x) */\\n    x: CSSNumberish;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSScale/y) */\\n    y: CSSNumberish;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSScale/z) */\\n    z: CSSNumberish;\\n}\\n\\ndeclare var CSSScale: {\\n    prototype: CSSScale;\\n    new(x: CSSNumberish, y: CSSNumberish, z?: CSSNumberish): CSSScale;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkew) */\\ninterface CSSSkew extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkew/ax) */\\n    ax: CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkew/ay) */\\n    ay: CSSNumericValue;\\n}\\n\\ndeclare var CSSSkew: {\\n    prototype: CSSSkew;\\n    new(ax: CSSNumericValue, ay: CSSNumericValue): CSSSkew;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkewX) */\\ninterface CSSSkewX extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkewX/ax) */\\n    ax: CSSNumericValue;\\n}\\n\\ndeclare var CSSSkewX: {\\n    prototype: CSSSkewX;\\n    new(ax: CSSNumericValue): CSSSkewX;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkewY) */\\ninterface CSSSkewY extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkewY/ay) */\\n    ay: CSSNumericValue;\\n}\\n\\ndeclare var CSSSkewY: {\\n    prototype: CSSSkewY;\\n    new(ay: CSSNumericValue): CSSSkewY;\\n};\\n\\n/**\\n * An object that is a CSS declaration block, and exposes style information and various style-related methods and properties.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration)\\n */\\ninterface CSSStyleDeclaration {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/accent-color) */\\n    accentColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/align-content) */\\n    alignContent: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/align-items) */\\n    alignItems: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/align-self) */\\n    alignSelf: string;\\n    alignmentBaseline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/all) */\\n    all: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation) */\\n    animation: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-composition) */\\n    animationComposition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-delay) */\\n    animationDelay: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-direction) */\\n    animationDirection: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-duration) */\\n    animationDuration: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-fill-mode) */\\n    animationFillMode: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-iteration-count) */\\n    animationIterationCount: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-name) */\\n    animationName: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-play-state) */\\n    animationPlayState: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-timing-function) */\\n    animationTimingFunction: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/appearance) */\\n    appearance: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/aspect-ratio) */\\n    aspectRatio: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/backdrop-filter) */\\n    backdropFilter: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/backface-visibility) */\\n    backfaceVisibility: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background) */\\n    background: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-attachment) */\\n    backgroundAttachment: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-blend-mode) */\\n    backgroundBlendMode: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-clip) */\\n    backgroundClip: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-color) */\\n    backgroundColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-image) */\\n    backgroundImage: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-origin) */\\n    backgroundOrigin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-position) */\\n    backgroundPosition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-position-x) */\\n    backgroundPositionX: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-position-y) */\\n    backgroundPositionY: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-repeat) */\\n    backgroundRepeat: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-size) */\\n    backgroundSize: string;\\n    baselineShift: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/block-size) */\\n    blockSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border) */\\n    border: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block) */\\n    borderBlock: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-color) */\\n    borderBlockColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-end) */\\n    borderBlockEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-end-color) */\\n    borderBlockEndColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-end-style) */\\n    borderBlockEndStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-end-width) */\\n    borderBlockEndWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-start) */\\n    borderBlockStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-start-color) */\\n    borderBlockStartColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-start-style) */\\n    borderBlockStartStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-start-width) */\\n    borderBlockStartWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-style) */\\n    borderBlockStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-block-width) */\\n    borderBlockWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-bottom) */\\n    borderBottom: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-bottom-color) */\\n    borderBottomColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-bottom-left-radius) */\\n    borderBottomLeftRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-bottom-right-radius) */\\n    borderBottomRightRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-bottom-style) */\\n    borderBottomStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-bottom-width) */\\n    borderBottomWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-collapse) */\\n    borderCollapse: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-color) */\\n    borderColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-end-end-radius) */\\n    borderEndEndRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-end-start-radius) */\\n    borderEndStartRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-image) */\\n    borderImage: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-image-outset) */\\n    borderImageOutset: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-image-repeat) */\\n    borderImageRepeat: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-image-slice) */\\n    borderImageSlice: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-image-source) */\\n    borderImageSource: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-image-width) */\\n    borderImageWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline) */\\n    borderInline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-color) */\\n    borderInlineColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-end) */\\n    borderInlineEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-end-color) */\\n    borderInlineEndColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-end-style) */\\n    borderInlineEndStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-end-width) */\\n    borderInlineEndWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-start) */\\n    borderInlineStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-start-color) */\\n    borderInlineStartColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-start-style) */\\n    borderInlineStartStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-start-width) */\\n    borderInlineStartWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-style) */\\n    borderInlineStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-inline-width) */\\n    borderInlineWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-left) */\\n    borderLeft: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-left-color) */\\n    borderLeftColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-left-style) */\\n    borderLeftStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-left-width) */\\n    borderLeftWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-radius) */\\n    borderRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-right) */\\n    borderRight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-right-color) */\\n    borderRightColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-right-style) */\\n    borderRightStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-right-width) */\\n    borderRightWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-spacing) */\\n    borderSpacing: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-start-end-radius) */\\n    borderStartEndRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-start-start-radius) */\\n    borderStartStartRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-style) */\\n    borderStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-top) */\\n    borderTop: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-top-color) */\\n    borderTopColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-top-left-radius) */\\n    borderTopLeftRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-top-right-radius) */\\n    borderTopRightRadius: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-top-style) */\\n    borderTopStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-top-width) */\\n    borderTopWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-width) */\\n    borderWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/bottom) */\\n    bottom: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-shadow) */\\n    boxShadow: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-sizing) */\\n    boxSizing: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/break-after) */\\n    breakAfter: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/break-before) */\\n    breakBefore: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/break-inside) */\\n    breakInside: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/caption-side) */\\n    captionSide: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/caret-color) */\\n    caretColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/clear) */\\n    clear: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/clip)\\n     */\\n    clip: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/clip-path) */\\n    clipPath: string;\\n    clipRule: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/color) */\\n    color: string;\\n    colorInterpolation: string;\\n    colorInterpolationFilters: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/color-scheme) */\\n    colorScheme: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-count) */\\n    columnCount: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-fill) */\\n    columnFill: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-gap) */\\n    columnGap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-rule) */\\n    columnRule: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-rule-color) */\\n    columnRuleColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-rule-style) */\\n    columnRuleStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-rule-width) */\\n    columnRuleWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-span) */\\n    columnSpan: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/column-width) */\\n    columnWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/columns) */\\n    columns: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/contain) */\\n    contain: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/contain-intrinsic-contain-intrinsic-block-size) */\\n    containIntrinsicBlockSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/contain-intrinsic-height) */\\n    containIntrinsicHeight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/contain-intrinsic-contain-intrinsic-inline-size) */\\n    containIntrinsicInlineSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/contain-intrinsic-size) */\\n    containIntrinsicSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/contain-intrinsic-width) */\\n    containIntrinsicWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/container) */\\n    container: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/container-name) */\\n    containerName: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/container-type) */\\n    containerType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/content) */\\n    content: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/counter-increment) */\\n    counterIncrement: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/counter-reset) */\\n    counterReset: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/counter-set) */\\n    counterSet: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/cssFloat) */\\n    cssFloat: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/cssText) */\\n    cssText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/cursor) */\\n    cursor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/direction) */\\n    direction: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/display) */\\n    display: string;\\n    dominantBaseline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/empty-cells) */\\n    emptyCells: string;\\n    fill: string;\\n    fillOpacity: string;\\n    fillRule: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/filter) */\\n    filter: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex) */\\n    flex: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-basis) */\\n    flexBasis: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-direction) */\\n    flexDirection: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-flow) */\\n    flexFlow: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-grow) */\\n    flexGrow: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-shrink) */\\n    flexShrink: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-wrap) */\\n    flexWrap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/float) */\\n    float: string;\\n    floodColor: string;\\n    floodOpacity: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font) */\\n    font: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-family) */\\n    fontFamily: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-feature-settings) */\\n    fontFeatureSettings: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-kerning) */\\n    fontKerning: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-optical-sizing) */\\n    fontOpticalSizing: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-palette) */\\n    fontPalette: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-size) */\\n    fontSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-size-adjust) */\\n    fontSizeAdjust: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-stretch) */\\n    fontStretch: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-style) */\\n    fontStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-synthesis) */\\n    fontSynthesis: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-synthesis-small-caps) */\\n    fontSynthesisSmallCaps: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-synthesis-style) */\\n    fontSynthesisStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-synthesis-weight) */\\n    fontSynthesisWeight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-variant) */\\n    fontVariant: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-variant-alternates) */\\n    fontVariantAlternates: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-variant-caps) */\\n    fontVariantCaps: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-variant-east-asian) */\\n    fontVariantEastAsian: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-variant-ligatures) */\\n    fontVariantLigatures: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-variant-numeric) */\\n    fontVariantNumeric: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-variant-position) */\\n    fontVariantPosition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-variation-settings) */\\n    fontVariationSettings: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/font-weight) */\\n    fontWeight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/forced-color-adjust) */\\n    forcedColorAdjust: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/gap) */\\n    gap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid) */\\n    grid: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-area) */\\n    gridArea: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-auto-columns) */\\n    gridAutoColumns: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-auto-flow) */\\n    gridAutoFlow: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-auto-rows) */\\n    gridAutoRows: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-column) */\\n    gridColumn: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-column-end) */\\n    gridColumnEnd: string;\\n    /** @deprecated This is a legacy alias of `columnGap`. */\\n    gridColumnGap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-column-start) */\\n    gridColumnStart: string;\\n    /** @deprecated This is a legacy alias of `gap`. */\\n    gridGap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-row) */\\n    gridRow: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-row-end) */\\n    gridRowEnd: string;\\n    /** @deprecated This is a legacy alias of `rowGap`. */\\n    gridRowGap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-row-start) */\\n    gridRowStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-template) */\\n    gridTemplate: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-template-areas) */\\n    gridTemplateAreas: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-template-columns) */\\n    gridTemplateColumns: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/grid-template-rows) */\\n    gridTemplateRows: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/height) */\\n    height: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/hyphenate-character) */\\n    hyphenateCharacter: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/hyphens) */\\n    hyphens: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/image-orientation)\\n     */\\n    imageOrientation: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/image-rendering) */\\n    imageRendering: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/inline-size) */\\n    inlineSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/inset) */\\n    inset: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/inset-block) */\\n    insetBlock: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/inset-block-end) */\\n    insetBlockEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/inset-block-start) */\\n    insetBlockStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/inset-inline) */\\n    insetInline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/inset-inline-end) */\\n    insetInlineEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/inset-inline-start) */\\n    insetInlineStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/isolation) */\\n    isolation: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/justify-content) */\\n    justifyContent: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/justify-items) */\\n    justifyItems: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/justify-self) */\\n    justifySelf: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/left) */\\n    left: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/letter-spacing) */\\n    letterSpacing: string;\\n    lightingColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/line-break) */\\n    lineBreak: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/line-height) */\\n    lineHeight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/list-style) */\\n    listStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/list-style-image) */\\n    listStyleImage: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/list-style-position) */\\n    listStylePosition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/list-style-type) */\\n    listStyleType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin) */\\n    margin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-block) */\\n    marginBlock: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-block-end) */\\n    marginBlockEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-block-start) */\\n    marginBlockStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-bottom) */\\n    marginBottom: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-inline) */\\n    marginInline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-inline-end) */\\n    marginInlineEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-inline-start) */\\n    marginInlineStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-left) */\\n    marginLeft: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-right) */\\n    marginRight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/margin-top) */\\n    marginTop: string;\\n    marker: string;\\n    markerEnd: string;\\n    markerMid: string;\\n    markerStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask) */\\n    mask: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-clip) */\\n    maskClip: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-composite) */\\n    maskComposite: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-image) */\\n    maskImage: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-mode) */\\n    maskMode: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-origin) */\\n    maskOrigin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-position) */\\n    maskPosition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-repeat) */\\n    maskRepeat: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-size) */\\n    maskSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-type) */\\n    maskType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/math-style) */\\n    mathStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/max-block-size) */\\n    maxBlockSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/max-height) */\\n    maxHeight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/max-inline-size) */\\n    maxInlineSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/max-width) */\\n    maxWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/min-block-size) */\\n    minBlockSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/min-height) */\\n    minHeight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/min-inline-size) */\\n    minInlineSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/min-width) */\\n    minWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mix-blend-mode) */\\n    mixBlendMode: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/object-fit) */\\n    objectFit: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/object-position) */\\n    objectPosition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/offset) */\\n    offset: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/offset-distance) */\\n    offsetDistance: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/offset-path) */\\n    offsetPath: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/offset-rotate) */\\n    offsetRotate: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/opacity) */\\n    opacity: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/order) */\\n    order: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/orphans) */\\n    orphans: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/outline) */\\n    outline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/outline-color) */\\n    outlineColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/outline-offset) */\\n    outlineOffset: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/outline-style) */\\n    outlineStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/outline-width) */\\n    outlineWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overflow) */\\n    overflow: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overflow-anchor) */\\n    overflowAnchor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overflow-clip-margin) */\\n    overflowClipMargin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overflow-wrap) */\\n    overflowWrap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overflow-x) */\\n    overflowX: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overflow-y) */\\n    overflowY: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior) */\\n    overscrollBehavior: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-block) */\\n    overscrollBehaviorBlock: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-inline) */\\n    overscrollBehaviorInline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-x) */\\n    overscrollBehaviorX: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overscroll-behavior-y) */\\n    overscrollBehaviorY: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding) */\\n    padding: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-block) */\\n    paddingBlock: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-block-end) */\\n    paddingBlockEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-block-start) */\\n    paddingBlockStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-bottom) */\\n    paddingBottom: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-inline) */\\n    paddingInline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-inline-end) */\\n    paddingInlineEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-inline-start) */\\n    paddingInlineStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-left) */\\n    paddingLeft: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-right) */\\n    paddingRight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/padding-top) */\\n    paddingTop: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/page) */\\n    page: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/page-break-after) */\\n    pageBreakAfter: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/page-break-before) */\\n    pageBreakBefore: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/page-break-inside) */\\n    pageBreakInside: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/paint-order) */\\n    paintOrder: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/parentRule) */\\n    readonly parentRule: CSSRule | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/perspective) */\\n    perspective: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/perspective-origin) */\\n    perspectiveOrigin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/place-content) */\\n    placeContent: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/place-items) */\\n    placeItems: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/place-self) */\\n    placeSelf: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/pointer-events) */\\n    pointerEvents: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/position) */\\n    position: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/print-color-adjust) */\\n    printColorAdjust: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/quotes) */\\n    quotes: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/resize) */\\n    resize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/right) */\\n    right: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/rotate) */\\n    rotate: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/row-gap) */\\n    rowGap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/ruby-position) */\\n    rubyPosition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scale) */\\n    scale: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-behavior) */\\n    scrollBehavior: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin) */\\n    scrollMargin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block) */\\n    scrollMarginBlock: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block-end) */\\n    scrollMarginBlockEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-block-start) */\\n    scrollMarginBlockStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-bottom) */\\n    scrollMarginBottom: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline) */\\n    scrollMarginInline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline-end) */\\n    scrollMarginInlineEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-inline-start) */\\n    scrollMarginInlineStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-left) */\\n    scrollMarginLeft: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-right) */\\n    scrollMarginRight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-margin-top) */\\n    scrollMarginTop: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding) */\\n    scrollPadding: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block) */\\n    scrollPaddingBlock: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block-end) */\\n    scrollPaddingBlockEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-block-start) */\\n    scrollPaddingBlockStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-bottom) */\\n    scrollPaddingBottom: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline) */\\n    scrollPaddingInline: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline-end) */\\n    scrollPaddingInlineEnd: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-inline-start) */\\n    scrollPaddingInlineStart: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-left) */\\n    scrollPaddingLeft: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-right) */\\n    scrollPaddingRight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-padding-top) */\\n    scrollPaddingTop: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-snap-align) */\\n    scrollSnapAlign: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-snap-stop) */\\n    scrollSnapStop: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scroll-snap-type) */\\n    scrollSnapType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/scrollbar-gutter) */\\n    scrollbarGutter: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/shape-image-threshold) */\\n    shapeImageThreshold: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/shape-margin) */\\n    shapeMargin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/shape-outside) */\\n    shapeOutside: string;\\n    shapeRendering: string;\\n    stopColor: string;\\n    stopOpacity: string;\\n    stroke: string;\\n    strokeDasharray: string;\\n    strokeDashoffset: string;\\n    strokeLinecap: string;\\n    strokeLinejoin: string;\\n    strokeMiterlimit: string;\\n    strokeOpacity: string;\\n    strokeWidth: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/tab-size) */\\n    tabSize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/table-layout) */\\n    tableLayout: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-align) */\\n    textAlign: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-align-last) */\\n    textAlignLast: string;\\n    textAnchor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-combine-upright) */\\n    textCombineUpright: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-decoration) */\\n    textDecoration: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-decoration-color) */\\n    textDecorationColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-decoration-line) */\\n    textDecorationLine: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-decoration-skip-ink) */\\n    textDecorationSkipInk: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-decoration-style) */\\n    textDecorationStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-decoration-thickness) */\\n    textDecorationThickness: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-emphasis) */\\n    textEmphasis: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-emphasis-color) */\\n    textEmphasisColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-emphasis-position) */\\n    textEmphasisPosition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-emphasis-style) */\\n    textEmphasisStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-indent) */\\n    textIndent: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-orientation) */\\n    textOrientation: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-overflow) */\\n    textOverflow: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-rendering) */\\n    textRendering: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-shadow) */\\n    textShadow: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-transform) */\\n    textTransform: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-underline-offset) */\\n    textUnderlineOffset: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-underline-position) */\\n    textUnderlinePosition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/top) */\\n    top: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/touch-action) */\\n    touchAction: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transform) */\\n    transform: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transform-box) */\\n    transformBox: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transform-origin) */\\n    transformOrigin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transform-style) */\\n    transformStyle: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition) */\\n    transition: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-delay) */\\n    transitionDelay: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-duration) */\\n    transitionDuration: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-property) */\\n    transitionProperty: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-timing-function) */\\n    transitionTimingFunction: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/translate) */\\n    translate: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/unicode-bidi) */\\n    unicodeBidi: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/user-select) */\\n    userSelect: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/vertical-align) */\\n    verticalAlign: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/visibility) */\\n    visibility: string;\\n    /**\\n     * @deprecated This is a legacy alias of `alignContent`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/align-content)\\n     */\\n    webkitAlignContent: string;\\n    /**\\n     * @deprecated This is a legacy alias of `alignItems`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/align-items)\\n     */\\n    webkitAlignItems: string;\\n    /**\\n     * @deprecated This is a legacy alias of `alignSelf`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/align-self)\\n     */\\n    webkitAlignSelf: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animation`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation)\\n     */\\n    webkitAnimation: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animationDelay`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-delay)\\n     */\\n    webkitAnimationDelay: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animationDirection`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-direction)\\n     */\\n    webkitAnimationDirection: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animationDuration`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-duration)\\n     */\\n    webkitAnimationDuration: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animationFillMode`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-fill-mode)\\n     */\\n    webkitAnimationFillMode: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animationIterationCount`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-iteration-count)\\n     */\\n    webkitAnimationIterationCount: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animationName`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-name)\\n     */\\n    webkitAnimationName: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animationPlayState`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-play-state)\\n     */\\n    webkitAnimationPlayState: string;\\n    /**\\n     * @deprecated This is a legacy alias of `animationTimingFunction`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/animation-timing-function)\\n     */\\n    webkitAnimationTimingFunction: string;\\n    /**\\n     * @deprecated This is a legacy alias of `appearance`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/appearance)\\n     */\\n    webkitAppearance: string;\\n    /**\\n     * @deprecated This is a legacy alias of `backfaceVisibility`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/backface-visibility)\\n     */\\n    webkitBackfaceVisibility: string;\\n    /**\\n     * @deprecated This is a legacy alias of `backgroundClip`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-clip)\\n     */\\n    webkitBackgroundClip: string;\\n    /**\\n     * @deprecated This is a legacy alias of `backgroundOrigin`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-origin)\\n     */\\n    webkitBackgroundOrigin: string;\\n    /**\\n     * @deprecated This is a legacy alias of `backgroundSize`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/background-size)\\n     */\\n    webkitBackgroundSize: string;\\n    /**\\n     * @deprecated This is a legacy alias of `borderBottomLeftRadius`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-bottom-left-radius)\\n     */\\n    webkitBorderBottomLeftRadius: string;\\n    /**\\n     * @deprecated This is a legacy alias of `borderBottomRightRadius`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-bottom-right-radius)\\n     */\\n    webkitBorderBottomRightRadius: string;\\n    /**\\n     * @deprecated This is a legacy alias of `borderRadius`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-radius)\\n     */\\n    webkitBorderRadius: string;\\n    /**\\n     * @deprecated This is a legacy alias of `borderTopLeftRadius`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-top-left-radius)\\n     */\\n    webkitBorderTopLeftRadius: string;\\n    /**\\n     * @deprecated This is a legacy alias of `borderTopRightRadius`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/border-top-right-radius)\\n     */\\n    webkitBorderTopRightRadius: string;\\n    /**\\n     * @deprecated This is a legacy alias of `boxAlign`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-align)\\n     */\\n    webkitBoxAlign: string;\\n    /**\\n     * @deprecated This is a legacy alias of `boxFlex`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-flex)\\n     */\\n    webkitBoxFlex: string;\\n    /**\\n     * @deprecated This is a legacy alias of `boxOrdinalGroup`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-ordinal-group)\\n     */\\n    webkitBoxOrdinalGroup: string;\\n    /**\\n     * @deprecated This is a legacy alias of `boxOrient`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-orient)\\n     */\\n    webkitBoxOrient: string;\\n    /**\\n     * @deprecated This is a legacy alias of `boxPack`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-pack)\\n     */\\n    webkitBoxPack: string;\\n    /**\\n     * @deprecated This is a legacy alias of `boxShadow`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-shadow)\\n     */\\n    webkitBoxShadow: string;\\n    /**\\n     * @deprecated This is a legacy alias of `boxSizing`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/box-sizing)\\n     */\\n    webkitBoxSizing: string;\\n    /**\\n     * @deprecated This is a legacy alias of `filter`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/filter)\\n     */\\n    webkitFilter: string;\\n    /**\\n     * @deprecated This is a legacy alias of `flex`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex)\\n     */\\n    webkitFlex: string;\\n    /**\\n     * @deprecated This is a legacy alias of `flexBasis`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-basis)\\n     */\\n    webkitFlexBasis: string;\\n    /**\\n     * @deprecated This is a legacy alias of `flexDirection`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-direction)\\n     */\\n    webkitFlexDirection: string;\\n    /**\\n     * @deprecated This is a legacy alias of `flexFlow`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-flow)\\n     */\\n    webkitFlexFlow: string;\\n    /**\\n     * @deprecated This is a legacy alias of `flexGrow`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-grow)\\n     */\\n    webkitFlexGrow: string;\\n    /**\\n     * @deprecated This is a legacy alias of `flexShrink`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-shrink)\\n     */\\n    webkitFlexShrink: string;\\n    /**\\n     * @deprecated This is a legacy alias of `flexWrap`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/flex-wrap)\\n     */\\n    webkitFlexWrap: string;\\n    /**\\n     * @deprecated This is a legacy alias of `justifyContent`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/justify-content)\\n     */\\n    webkitJustifyContent: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/-webkit-line-clamp) */\\n    webkitLineClamp: string;\\n    /**\\n     * @deprecated This is a legacy alias of `mask`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask)\\n     */\\n    webkitMask: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskBorder`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-border)\\n     */\\n    webkitMaskBoxImage: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskBorderOutset`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-border-outset)\\n     */\\n    webkitMaskBoxImageOutset: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskBorderRepeat`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-border-repeat)\\n     */\\n    webkitMaskBoxImageRepeat: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskBorderSlice`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-border-slice)\\n     */\\n    webkitMaskBoxImageSlice: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskBorderSource`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-border-source)\\n     */\\n    webkitMaskBoxImageSource: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskBorderWidth`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-border-width)\\n     */\\n    webkitMaskBoxImageWidth: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskClip`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-clip)\\n     */\\n    webkitMaskClip: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/-webkit-mask-composite) */\\n    webkitMaskComposite: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskImage`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-image)\\n     */\\n    webkitMaskImage: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskOrigin`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-origin)\\n     */\\n    webkitMaskOrigin: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskPosition`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-position)\\n     */\\n    webkitMaskPosition: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskRepeat`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-repeat)\\n     */\\n    webkitMaskRepeat: string;\\n    /**\\n     * @deprecated This is a legacy alias of `maskSize`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/mask-size)\\n     */\\n    webkitMaskSize: string;\\n    /**\\n     * @deprecated This is a legacy alias of `order`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/order)\\n     */\\n    webkitOrder: string;\\n    /**\\n     * @deprecated This is a legacy alias of `perspective`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/perspective)\\n     */\\n    webkitPerspective: string;\\n    /**\\n     * @deprecated This is a legacy alias of `perspectiveOrigin`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/perspective-origin)\\n     */\\n    webkitPerspectiveOrigin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/-webkit-text-fill-color) */\\n    webkitTextFillColor: string;\\n    /**\\n     * @deprecated This is a legacy alias of `textSizeAdjust`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-size-adjust)\\n     */\\n    webkitTextSizeAdjust: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke) */\\n    webkitTextStroke: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke-color) */\\n    webkitTextStrokeColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/-webkit-text-stroke-width) */\\n    webkitTextStrokeWidth: string;\\n    /**\\n     * @deprecated This is a legacy alias of `transform`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transform)\\n     */\\n    webkitTransform: string;\\n    /**\\n     * @deprecated This is a legacy alias of `transformOrigin`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transform-origin)\\n     */\\n    webkitTransformOrigin: string;\\n    /**\\n     * @deprecated This is a legacy alias of `transformStyle`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transform-style)\\n     */\\n    webkitTransformStyle: string;\\n    /**\\n     * @deprecated This is a legacy alias of `transition`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition)\\n     */\\n    webkitTransition: string;\\n    /**\\n     * @deprecated This is a legacy alias of `transitionDelay`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-delay)\\n     */\\n    webkitTransitionDelay: string;\\n    /**\\n     * @deprecated This is a legacy alias of `transitionDuration`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-duration)\\n     */\\n    webkitTransitionDuration: string;\\n    /**\\n     * @deprecated This is a legacy alias of `transitionProperty`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-property)\\n     */\\n    webkitTransitionProperty: string;\\n    /**\\n     * @deprecated This is a legacy alias of `transitionTimingFunction`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-timing-function)\\n     */\\n    webkitTransitionTimingFunction: string;\\n    /**\\n     * @deprecated This is a legacy alias of `userSelect`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/user-select)\\n     */\\n    webkitUserSelect: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/white-space) */\\n    whiteSpace: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/widows) */\\n    widows: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/width) */\\n    width: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/will-change) */\\n    willChange: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/word-break) */\\n    wordBreak: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/word-spacing) */\\n    wordSpacing: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/overflow-wrap)\\n     */\\n    wordWrap: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/writing-mode) */\\n    writingMode: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/z-index) */\\n    zIndex: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/getPropertyPriority) */\\n    getPropertyPriority(property: string): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/getPropertyValue) */\\n    getPropertyValue(property: string): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/item) */\\n    item(index: number): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/removeProperty) */\\n    removeProperty(property: string): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/setProperty) */\\n    setProperty(property: string, value: string | null, priority?: string): void;\\n    [index: number]: string;\\n}\\n\\ndeclare var CSSStyleDeclaration: {\\n    prototype: CSSStyleDeclaration;\\n    new(): CSSStyleDeclaration;\\n};\\n\\n/**\\n * CSSStyleRule represents a single CSS style rule. It implements the CSSRule interface with a type value of 1 (CSSRule.STYLE_RULE).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleRule)\\n */\\ninterface CSSStyleRule extends CSSRule {\\n    readonly cssRules: CSSRuleList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleRule/selectorText) */\\n    selectorText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleRule/style) */\\n    readonly style: CSSStyleDeclaration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleRule/styleMap) */\\n    readonly styleMap: StylePropertyMap;\\n    deleteRule(index: number): void;\\n    insertRule(rule: string, index?: number): number;\\n}\\n\\ndeclare var CSSStyleRule: {\\n    prototype: CSSStyleRule;\\n    new(): CSSStyleRule;\\n};\\n\\n/**\\n * A single CSS style sheet. It inherits properties and methods from its parent, StyleSheet.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet)\\n */\\ninterface CSSStyleSheet extends StyleSheet {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/cssRules) */\\n    readonly cssRules: CSSRuleList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/ownerRule) */\\n    readonly ownerRule: CSSRule | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/rules)\\n     */\\n    readonly rules: CSSRuleList;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/addRule)\\n     */\\n    addRule(selector?: string, style?: string, index?: number): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/deleteRule) */\\n    deleteRule(index: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/insertRule) */\\n    insertRule(rule: string, index?: number): number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/removeRule)\\n     */\\n    removeRule(index?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/replace) */\\n    replace(text: string): Promise<CSSStyleSheet>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleSheet/replaceSync) */\\n    replaceSync(text: string): void;\\n}\\n\\ndeclare var CSSStyleSheet: {\\n    prototype: CSSStyleSheet;\\n    new(options?: CSSStyleSheetInit): CSSStyleSheet;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleValue) */\\ninterface CSSStyleValue {\\n    toString(): string;\\n}\\n\\ndeclare var CSSStyleValue: {\\n    prototype: CSSStyleValue;\\n    new(): CSSStyleValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleValue/parse_static) */\\n    parse(property: string, cssText: string): CSSStyleValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleValue/parseAll_static) */\\n    parseAll(property: string, cssText: string): CSSStyleValue[];\\n};\\n\\n/**\\n * An object representing a single CSS @supports at-rule. It implements the CSSConditionRule interface, and therefore the CSSRule and CSSGroupingRule interfaces with a type value of 12 (CSSRule.SUPPORTS_RULE).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSupportsRule)\\n */\\ninterface CSSSupportsRule extends CSSConditionRule {\\n}\\n\\ndeclare var CSSSupportsRule: {\\n    prototype: CSSSupportsRule;\\n    new(): CSSSupportsRule;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformComponent) */\\ninterface CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformComponent/is2D) */\\n    is2D: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformComponent/toMatrix) */\\n    toMatrix(): DOMMatrix;\\n    toString(): string;\\n}\\n\\ndeclare var CSSTransformComponent: {\\n    prototype: CSSTransformComponent;\\n    new(): CSSTransformComponent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformValue) */\\ninterface CSSTransformValue extends CSSStyleValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformValue/is2D) */\\n    readonly is2D: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformValue/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformValue/toMatrix) */\\n    toMatrix(): DOMMatrix;\\n    forEach(callbackfn: (value: CSSTransformComponent, key: number, parent: CSSTransformValue) => void, thisArg?: any): void;\\n    [index: number]: CSSTransformComponent;\\n}\\n\\ndeclare var CSSTransformValue: {\\n    prototype: CSSTransformValue;\\n    new(transforms: CSSTransformComponent[]): CSSTransformValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransition) */\\ninterface CSSTransition extends Animation {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransition/transitionProperty) */\\n    readonly transitionProperty: string;\\n    addEventListener<K extends keyof AnimationEventMap>(type: K, listener: (this: CSSTransition, ev: AnimationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AnimationEventMap>(type: K, listener: (this: CSSTransition, ev: AnimationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var CSSTransition: {\\n    prototype: CSSTransition;\\n    new(): CSSTransition;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTranslate) */\\ninterface CSSTranslate extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTranslate/x) */\\n    x: CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTranslate/y) */\\n    y: CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTranslate/z) */\\n    z: CSSNumericValue;\\n}\\n\\ndeclare var CSSTranslate: {\\n    prototype: CSSTranslate;\\n    new(x: CSSNumericValue, y: CSSNumericValue, z?: CSSNumericValue): CSSTranslate;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnitValue) */\\ninterface CSSUnitValue extends CSSNumericValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnitValue/unit) */\\n    readonly unit: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnitValue/value) */\\n    value: number;\\n}\\n\\ndeclare var CSSUnitValue: {\\n    prototype: CSSUnitValue;\\n    new(value: number, unit: string): CSSUnitValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnparsedValue) */\\ninterface CSSUnparsedValue extends CSSStyleValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnparsedValue/length) */\\n    readonly length: number;\\n    forEach(callbackfn: (value: CSSUnparsedSegment, key: number, parent: CSSUnparsedValue) => void, thisArg?: any): void;\\n    [index: number]: CSSUnparsedSegment;\\n}\\n\\ndeclare var CSSUnparsedValue: {\\n    prototype: CSSUnparsedValue;\\n    new(members: CSSUnparsedSegment[]): CSSUnparsedValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSVariableReferenceValue) */\\ninterface CSSVariableReferenceValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSVariableReferenceValue/fallback) */\\n    readonly fallback: CSSUnparsedValue | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSVariableReferenceValue/variable) */\\n    variable: string;\\n}\\n\\ndeclare var CSSVariableReferenceValue: {\\n    prototype: CSSVariableReferenceValue;\\n    new(variable: string, fallback?: CSSUnparsedValue | null): CSSVariableReferenceValue;\\n};\\n\\n/**\\n * Provides a storage mechanism for Request / Response object pairs that are cached, for example as part of the ServiceWorker life cycle. Note that the Cache interface is exposed to windowed scopes as well as workers. You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache)\\n */\\ninterface Cache {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/add) */\\n    add(request: RequestInfo | URL): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/addAll) */\\n    addAll(requests: RequestInfo[]): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/delete) */\\n    delete(request: RequestInfo | URL, options?: CacheQueryOptions): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/keys) */\\n    keys(request?: RequestInfo | URL, options?: CacheQueryOptions): Promise<ReadonlyArray<Request>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/match) */\\n    match(request: RequestInfo | URL, options?: CacheQueryOptions): Promise<Response | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/matchAll) */\\n    matchAll(request?: RequestInfo | URL, options?: CacheQueryOptions): Promise<ReadonlyArray<Response>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/put) */\\n    put(request: RequestInfo | URL, response: Response): Promise<void>;\\n}\\n\\ndeclare var Cache: {\\n    prototype: Cache;\\n    new(): Cache;\\n};\\n\\n/**\\n * The storage for Cache objects.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage)\\n */\\ninterface CacheStorage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/delete) */\\n    delete(cacheName: string): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/has) */\\n    has(cacheName: string): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/keys) */\\n    keys(): Promise<string[]>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/match) */\\n    match(request: RequestInfo | URL, options?: MultiCacheQueryOptions): Promise<Response | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/open) */\\n    open(cacheName: string): Promise<Cache>;\\n}\\n\\ndeclare var CacheStorage: {\\n    prototype: CacheStorage;\\n    new(): CacheStorage;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasCaptureMediaStreamTrack) */\\ninterface CanvasCaptureMediaStreamTrack extends MediaStreamTrack {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasCaptureMediaStreamTrack/canvas) */\\n    readonly canvas: HTMLCanvasElement;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasCaptureMediaStreamTrack/requestFrame) */\\n    requestFrame(): void;\\n    addEventListener<K extends keyof MediaStreamTrackEventMap>(type: K, listener: (this: CanvasCaptureMediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MediaStreamTrackEventMap>(type: K, listener: (this: CanvasCaptureMediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var CanvasCaptureMediaStreamTrack: {\\n    prototype: CanvasCaptureMediaStreamTrack;\\n    new(): CanvasCaptureMediaStreamTrack;\\n};\\n\\ninterface CanvasCompositing {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/globalAlpha) */\\n    globalAlpha: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) */\\n    globalCompositeOperation: GlobalCompositeOperation;\\n}\\n\\ninterface CanvasDrawImage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/drawImage) */\\n    drawImage(image: CanvasImageSource, dx: number, dy: number): void;\\n    drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;\\n    drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;\\n}\\n\\ninterface CanvasDrawPath {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/beginPath) */\\n    beginPath(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/clip) */\\n    clip(fillRule?: CanvasFillRule): void;\\n    clip(path: Path2D, fillRule?: CanvasFillRule): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fill) */\\n    fill(fillRule?: CanvasFillRule): void;\\n    fill(path: Path2D, fillRule?: CanvasFillRule): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/isPointInPath) */\\n    isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean;\\n    isPointInPath(path: Path2D, x: number, y: number, fillRule?: CanvasFillRule): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/isPointInStroke) */\\n    isPointInStroke(x: number, y: number): boolean;\\n    isPointInStroke(path: Path2D, x: number, y: number): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/stroke) */\\n    stroke(): void;\\n    stroke(path: Path2D): void;\\n}\\n\\ninterface CanvasFillStrokeStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fillStyle) */\\n    fillStyle: string | CanvasGradient | CanvasPattern;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/strokeStyle) */\\n    strokeStyle: string | CanvasGradient | CanvasPattern;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createConicGradient) */\\n    createConicGradient(startAngle: number, x: number, y: number): CanvasGradient;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createLinearGradient) */\\n    createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createPattern) */\\n    createPattern(image: CanvasImageSource, repetition: string | null): CanvasPattern | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createRadialGradient) */\\n    createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;\\n}\\n\\ninterface CanvasFilters {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/filter) */\\n    filter: string;\\n}\\n\\n/**\\n * An opaque object describing a gradient. It is returned by the methods CanvasRenderingContext2D.createLinearGradient() or CanvasRenderingContext2D.createRadialGradient().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasGradient)\\n */\\ninterface CanvasGradient {\\n    /**\\n     * Adds a color stop with the given color to the gradient at the given offset. 0.0 is the offset at one end of the gradient, 1.0 is the offset at the other end.\\n     *\\n     * Throws an \\\"IndexSizeError\\\" DOMException if the offset is out of range. Throws a \\\"SyntaxError\\\" DOMException if the color cannot be parsed.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasGradient/addColorStop)\\n     */\\n    addColorStop(offset: number, color: string): void;\\n}\\n\\ndeclare var CanvasGradient: {\\n    prototype: CanvasGradient;\\n    new(): CanvasGradient;\\n};\\n\\ninterface CanvasImageData {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createImageData) */\\n    createImageData(sw: number, sh: number, settings?: ImageDataSettings): ImageData;\\n    createImageData(imagedata: ImageData): ImageData;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/getImageData) */\\n    getImageData(sx: number, sy: number, sw: number, sh: number, settings?: ImageDataSettings): ImageData;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/putImageData) */\\n    putImageData(imagedata: ImageData, dx: number, dy: number): void;\\n    putImageData(imagedata: ImageData, dx: number, dy: number, dirtyX: number, dirtyY: number, dirtyWidth: number, dirtyHeight: number): void;\\n}\\n\\ninterface CanvasImageSmoothing {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled) */\\n    imageSmoothingEnabled: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/imageSmoothingQuality) */\\n    imageSmoothingQuality: ImageSmoothingQuality;\\n}\\n\\ninterface CanvasPath {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/arc) */\\n    arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/arcTo) */\\n    arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo) */\\n    bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/closePath) */\\n    closePath(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/ellipse) */\\n    ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineTo) */\\n    lineTo(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/moveTo) */\\n    moveTo(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/quadraticCurveTo) */\\n    quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/rect) */\\n    rect(x: number, y: number, w: number, h: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/roundRect) */\\n    roundRect(x: number, y: number, w: number, h: number, radii?: number | DOMPointInit | (number | DOMPointInit)[]): void;\\n}\\n\\ninterface CanvasPathDrawingStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineCap) */\\n    lineCap: CanvasLineCap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineDashOffset) */\\n    lineDashOffset: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineJoin) */\\n    lineJoin: CanvasLineJoin;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineWidth) */\\n    lineWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/miterLimit) */\\n    miterLimit: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/getLineDash) */\\n    getLineDash(): number[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash) */\\n    setLineDash(segments: number[]): void;\\n}\\n\\n/**\\n * An opaque object describing a pattern, based on an image, a canvas, or a video, created by the CanvasRenderingContext2D.createPattern() method.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasPattern)\\n */\\ninterface CanvasPattern {\\n    /**\\n     * Sets the transformation matrix that will be used when rendering the pattern during a fill or stroke painting operation.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasPattern/setTransform)\\n     */\\n    setTransform(transform?: DOMMatrix2DInit): void;\\n}\\n\\ndeclare var CanvasPattern: {\\n    prototype: CanvasPattern;\\n    new(): CanvasPattern;\\n};\\n\\ninterface CanvasRect {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/clearRect) */\\n    clearRect(x: number, y: number, w: number, h: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fillRect) */\\n    fillRect(x: number, y: number, w: number, h: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/strokeRect) */\\n    strokeRect(x: number, y: number, w: number, h: number): void;\\n}\\n\\n/**\\n * The CanvasRenderingContext2D interface, part of the Canvas API, provides the 2D rendering context for the drawing surface of a <canvas> element. It is used for drawing shapes, text, images, and other objects.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D)\\n */\\ninterface CanvasRenderingContext2D extends CanvasCompositing, CanvasDrawImage, CanvasDrawPath, CanvasFillStrokeStyles, CanvasFilters, CanvasImageData, CanvasImageSmoothing, CanvasPath, CanvasPathDrawingStyles, CanvasRect, CanvasShadowStyles, CanvasState, CanvasText, CanvasTextDrawingStyles, CanvasTransform, CanvasUserInterface {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/canvas) */\\n    readonly canvas: HTMLCanvasElement;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/getContextAttributes) */\\n    getContextAttributes(): CanvasRenderingContext2DSettings;\\n}\\n\\ndeclare var CanvasRenderingContext2D: {\\n    prototype: CanvasRenderingContext2D;\\n    new(): CanvasRenderingContext2D;\\n};\\n\\ninterface CanvasShadowStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/shadowBlur) */\\n    shadowBlur: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/shadowColor) */\\n    shadowColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/shadowOffsetX) */\\n    shadowOffsetX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/shadowOffsetY) */\\n    shadowOffsetY: number;\\n}\\n\\ninterface CanvasState {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/reset) */\\n    reset(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/restore) */\\n    restore(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/save) */\\n    save(): void;\\n}\\n\\ninterface CanvasText {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fillText) */\\n    fillText(text: string, x: number, y: number, maxWidth?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/measureText) */\\n    measureText(text: string): TextMetrics;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/strokeText) */\\n    strokeText(text: string, x: number, y: number, maxWidth?: number): void;\\n}\\n\\ninterface CanvasTextDrawingStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/direction) */\\n    direction: CanvasDirection;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/font) */\\n    font: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fontKerning) */\\n    fontKerning: CanvasFontKerning;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/textAlign) */\\n    textAlign: CanvasTextAlign;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/textBaseline) */\\n    textBaseline: CanvasTextBaseline;\\n}\\n\\ninterface CanvasTransform {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/getTransform) */\\n    getTransform(): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/resetTransform) */\\n    resetTransform(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/rotate) */\\n    rotate(angle: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/scale) */\\n    scale(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setTransform) */\\n    setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;\\n    setTransform(transform?: DOMMatrix2DInit): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/transform) */\\n    transform(a: number, b: number, c: number, d: number, e: number, f: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/translate) */\\n    translate(x: number, y: number): void;\\n}\\n\\ninterface CanvasUserInterface {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/drawFocusIfNeeded) */\\n    drawFocusIfNeeded(element: Element): void;\\n    drawFocusIfNeeded(path: Path2D, element: Element): void;\\n}\\n\\n/**\\n * The ChannelMergerNode interface, often used in conjunction with its opposite, ChannelSplitterNode, reunites different mono inputs into a single output. Each input is used to fill a channel of the output. This is useful for accessing each channels separately, e.g. for performing channel mixing where gain must be separately controlled on each channel.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ChannelMergerNode)\\n */\\ninterface ChannelMergerNode extends AudioNode {\\n}\\n\\ndeclare var ChannelMergerNode: {\\n    prototype: ChannelMergerNode;\\n    new(context: BaseAudioContext, options?: ChannelMergerOptions): ChannelMergerNode;\\n};\\n\\n/**\\n * The ChannelSplitterNode interface, often used in conjunction with its opposite, ChannelMergerNode, separates the different channels of an audio source into a set of mono outputs. This is useful for accessing each channel separately, e.g. for performing channel mixing where gain must be separately controlled on each channel.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ChannelSplitterNode)\\n */\\ninterface ChannelSplitterNode extends AudioNode {\\n}\\n\\ndeclare var ChannelSplitterNode: {\\n    prototype: ChannelSplitterNode;\\n    new(context: BaseAudioContext, options?: ChannelSplitterOptions): ChannelSplitterNode;\\n};\\n\\n/**\\n * The CharacterData abstract interface represents a Node object that contains characters. This is an abstract interface, meaning there aren't any object of type CharacterData: it is implemented by other interfaces, like Text, Comment, or ProcessingInstruction which aren't abstract.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData)\\n */\\ninterface CharacterData extends Node, ChildNode, NonDocumentTypeChildNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/data) */\\n    data: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/length) */\\n    readonly length: number;\\n    readonly ownerDocument: Document;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/appendData) */\\n    appendData(data: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/deleteData) */\\n    deleteData(offset: number, count: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/insertData) */\\n    insertData(offset: number, data: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/replaceData) */\\n    replaceData(offset: number, count: number, data: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/substringData) */\\n    substringData(offset: number, count: number): string;\\n}\\n\\ndeclare var CharacterData: {\\n    prototype: CharacterData;\\n    new(): CharacterData;\\n};\\n\\ninterface ChildNode extends Node {\\n    /**\\n     * Inserts nodes just after node, while replacing strings in nodes with equivalent Text nodes.\\n     *\\n     * Throws a \\\"HierarchyRequestError\\\" DOMException if the constraints of the node tree are violated.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/after)\\n     */\\n    after(...nodes: (Node | string)[]): void;\\n    /**\\n     * Inserts nodes just before node, while replacing strings in nodes with equivalent Text nodes.\\n     *\\n     * Throws a \\\"HierarchyRequestError\\\" DOMException if the constraints of the node tree are violated.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/before)\\n     */\\n    before(...nodes: (Node | string)[]): void;\\n    /**\\n     * Removes node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/remove)\\n     */\\n    remove(): void;\\n    /**\\n     * Replaces node with nodes, while replacing strings in nodes with equivalent Text nodes.\\n     *\\n     * Throws a \\\"HierarchyRequestError\\\" DOMException if the constraints of the node tree are violated.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/replaceWith)\\n     */\\n    replaceWith(...nodes: (Node | string)[]): void;\\n}\\n\\n/** @deprecated */\\ninterface ClientRect extends DOMRect {\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clipboard)\\n */\\ninterface Clipboard extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clipboard/read) */\\n    read(): Promise<ClipboardItems>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clipboard/readText) */\\n    readText(): Promise<string>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clipboard/write) */\\n    write(data: ClipboardItems): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clipboard/writeText) */\\n    writeText(data: string): Promise<void>;\\n}\\n\\ndeclare var Clipboard: {\\n    prototype: Clipboard;\\n    new(): Clipboard;\\n};\\n\\n/**\\n * Events providing information related to modification of the clipboard, that is cut, copy, and paste events.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ClipboardEvent)\\n */\\ninterface ClipboardEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ClipboardEvent/clipboardData) */\\n    readonly clipboardData: DataTransfer | null;\\n}\\n\\ndeclare var ClipboardEvent: {\\n    prototype: ClipboardEvent;\\n    new(type: string, eventInitDict?: ClipboardEventInit): ClipboardEvent;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ClipboardItem)\\n */\\ninterface ClipboardItem {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ClipboardItem/types) */\\n    readonly types: ReadonlyArray<string>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ClipboardItem/getType) */\\n    getType(type: string): Promise<Blob>;\\n}\\n\\ndeclare var ClipboardItem: {\\n    prototype: ClipboardItem;\\n    new(items: Record<string, string | Blob | PromiseLike<string | Blob>>, options?: ClipboardItemOptions): ClipboardItem;\\n};\\n\\n/**\\n * A CloseEvent is sent to clients using WebSockets when the connection is closed. This is delivered to the listener indicated by the WebSocket object's onclose attribute.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CloseEvent)\\n */\\ninterface CloseEvent extends Event {\\n    /**\\n     * Returns the WebSocket connection close code provided by the server.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CloseEvent/code)\\n     */\\n    readonly code: number;\\n    /**\\n     * Returns the WebSocket connection close reason provided by the server.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CloseEvent/reason)\\n     */\\n    readonly reason: string;\\n    /**\\n     * Returns true if the connection closed cleanly; false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CloseEvent/wasClean)\\n     */\\n    readonly wasClean: boolean;\\n}\\n\\ndeclare var CloseEvent: {\\n    prototype: CloseEvent;\\n    new(type: string, eventInitDict?: CloseEventInit): CloseEvent;\\n};\\n\\n/**\\n * Textual notations within markup; although it is generally not visually shown, such comments are available to be read in the source view.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Comment)\\n */\\ninterface Comment extends CharacterData {\\n}\\n\\ndeclare var Comment: {\\n    prototype: Comment;\\n    new(data?: string): Comment;\\n};\\n\\n/**\\n * The DOM CompositionEvent represents events that occur due to the user indirectly entering text.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompositionEvent)\\n */\\ninterface CompositionEvent extends UIEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompositionEvent/data) */\\n    readonly data: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompositionEvent/initCompositionEvent)\\n     */\\n    initCompositionEvent(typeArg: string, bubblesArg?: boolean, cancelableArg?: boolean, viewArg?: WindowProxy | null, dataArg?: string): void;\\n}\\n\\ndeclare var CompositionEvent: {\\n    prototype: CompositionEvent;\\n    new(type: string, eventInitDict?: CompositionEventInit): CompositionEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompressionStream) */\\ninterface CompressionStream extends GenericTransformStream {\\n}\\n\\ndeclare var CompressionStream: {\\n    prototype: CompressionStream;\\n    new(format: CompressionFormat): CompressionStream;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ConstantSourceNode) */\\ninterface ConstantSourceNode extends AudioScheduledSourceNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ConstantSourceNode/offset) */\\n    readonly offset: AudioParam;\\n    addEventListener<K extends keyof AudioScheduledSourceNodeEventMap>(type: K, listener: (this: ConstantSourceNode, ev: AudioScheduledSourceNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AudioScheduledSourceNodeEventMap>(type: K, listener: (this: ConstantSourceNode, ev: AudioScheduledSourceNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ConstantSourceNode: {\\n    prototype: ConstantSourceNode;\\n    new(context: BaseAudioContext, options?: ConstantSourceOptions): ConstantSourceNode;\\n};\\n\\n/**\\n * An AudioNode that performs a Linear Convolution on a given AudioBuffer, often used to achieve a reverb effect. A ConvolverNode always has exactly one input and one output.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ConvolverNode)\\n */\\ninterface ConvolverNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ConvolverNode/buffer) */\\n    buffer: AudioBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ConvolverNode/normalize) */\\n    normalize: boolean;\\n}\\n\\ndeclare var ConvolverNode: {\\n    prototype: ConvolverNode;\\n    new(context: BaseAudioContext, options?: ConvolverOptions): ConvolverNode;\\n};\\n\\n/**\\n * This Streams API interface provides a built-in byte length queuing strategy that can be used when constructing streams.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CountQueuingStrategy)\\n */\\ninterface CountQueuingStrategy extends QueuingStrategy {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CountQueuingStrategy/highWaterMark) */\\n    readonly highWaterMark: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CountQueuingStrategy/size) */\\n    readonly size: QueuingStrategySize;\\n}\\n\\ndeclare var CountQueuingStrategy: {\\n    prototype: CountQueuingStrategy;\\n    new(init: QueuingStrategyInit): CountQueuingStrategy;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Credential)\\n */\\ninterface Credential {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Credential/id) */\\n    readonly id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Credential/type) */\\n    readonly type: string;\\n}\\n\\ndeclare var Credential: {\\n    prototype: Credential;\\n    new(): Credential;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CredentialsContainer)\\n */\\ninterface CredentialsContainer {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CredentialsContainer/create) */\\n    create(options?: CredentialCreationOptions): Promise<Credential | null>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CredentialsContainer/get) */\\n    get(options?: CredentialRequestOptions): Promise<Credential | null>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CredentialsContainer/preventSilentAccess) */\\n    preventSilentAccess(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CredentialsContainer/store) */\\n    store(credential: Credential): Promise<Credential>;\\n}\\n\\ndeclare var CredentialsContainer: {\\n    prototype: CredentialsContainer;\\n    new(): CredentialsContainer;\\n};\\n\\n/**\\n * Basic cryptography features available in the current context. It allows access to a cryptographically strong random number generator and to cryptographic primitives.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto)\\n */\\ninterface Crypto {\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/subtle)\\n     */\\n    readonly subtle: SubtleCrypto;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */\\n    getRandomValues<T extends ArrayBufferView | null>(array: T): T;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)\\n     */\\n    randomUUID(): `${string}-${string}-${string}-${string}-${string}`;\\n}\\n\\ndeclare var Crypto: {\\n    prototype: Crypto;\\n    new(): Crypto;\\n};\\n\\n/**\\n * The CryptoKey dictionary of the Web Crypto API represents a cryptographic key.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\n */\\ninterface CryptoKey {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/algorithm) */\\n    readonly algorithm: KeyAlgorithm;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/extractable) */\\n    readonly extractable: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/type) */\\n    readonly type: KeyType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/usages) */\\n    readonly usages: KeyUsage[];\\n}\\n\\ndeclare var CryptoKey: {\\n    prototype: CryptoKey;\\n    new(): CryptoKey;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomElementRegistry) */\\ninterface CustomElementRegistry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomElementRegistry/define) */\\n    define(name: string, constructor: CustomElementConstructor, options?: ElementDefinitionOptions): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomElementRegistry/get) */\\n    get(name: string): CustomElementConstructor | undefined;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomElementRegistry/upgrade) */\\n    upgrade(root: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomElementRegistry/whenDefined) */\\n    whenDefined(name: string): Promise<CustomElementConstructor>;\\n}\\n\\ndeclare var CustomElementRegistry: {\\n    prototype: CustomElementRegistry;\\n    new(): CustomElementRegistry;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomEvent) */\\ninterface CustomEvent<T = any> extends Event {\\n    /**\\n     * Returns any custom data event was created with. Typically used for synthetic events.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomEvent/detail)\\n     */\\n    readonly detail: T;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomEvent/initCustomEvent)\\n     */\\n    initCustomEvent(type: string, bubbles?: boolean, cancelable?: boolean, detail?: T): void;\\n}\\n\\ndeclare var CustomEvent: {\\n    prototype: CustomEvent;\\n    new<T>(type: string, eventInitDict?: CustomEventInit<T>): CustomEvent<T>;\\n};\\n\\n/**\\n * An abnormal event (called an exception) which occurs as a result of calling a method or accessing a property of a web API.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException)\\n */\\ninterface DOMException extends Error {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/code)\\n     */\\n    readonly code: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/message) */\\n    readonly message: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/name) */\\n    readonly name: string;\\n    readonly INDEX_SIZE_ERR: 1;\\n    readonly DOMSTRING_SIZE_ERR: 2;\\n    readonly HIERARCHY_REQUEST_ERR: 3;\\n    readonly WRONG_DOCUMENT_ERR: 4;\\n    readonly INVALID_CHARACTER_ERR: 5;\\n    readonly NO_DATA_ALLOWED_ERR: 6;\\n    readonly NO_MODIFICATION_ALLOWED_ERR: 7;\\n    readonly NOT_FOUND_ERR: 8;\\n    readonly NOT_SUPPORTED_ERR: 9;\\n    readonly INUSE_ATTRIBUTE_ERR: 10;\\n    readonly INVALID_STATE_ERR: 11;\\n    readonly SYNTAX_ERR: 12;\\n    readonly INVALID_MODIFICATION_ERR: 13;\\n    readonly NAMESPACE_ERR: 14;\\n    readonly INVALID_ACCESS_ERR: 15;\\n    readonly VALIDATION_ERR: 16;\\n    readonly TYPE_MISMATCH_ERR: 17;\\n    readonly SECURITY_ERR: 18;\\n    readonly NETWORK_ERR: 19;\\n    readonly ABORT_ERR: 20;\\n    readonly URL_MISMATCH_ERR: 21;\\n    readonly QUOTA_EXCEEDED_ERR: 22;\\n    readonly TIMEOUT_ERR: 23;\\n    readonly INVALID_NODE_TYPE_ERR: 24;\\n    readonly DATA_CLONE_ERR: 25;\\n}\\n\\ndeclare var DOMException: {\\n    prototype: DOMException;\\n    new(message?: string, name?: string): DOMException;\\n    readonly INDEX_SIZE_ERR: 1;\\n    readonly DOMSTRING_SIZE_ERR: 2;\\n    readonly HIERARCHY_REQUEST_ERR: 3;\\n    readonly WRONG_DOCUMENT_ERR: 4;\\n    readonly INVALID_CHARACTER_ERR: 5;\\n    readonly NO_DATA_ALLOWED_ERR: 6;\\n    readonly NO_MODIFICATION_ALLOWED_ERR: 7;\\n    readonly NOT_FOUND_ERR: 8;\\n    readonly NOT_SUPPORTED_ERR: 9;\\n    readonly INUSE_ATTRIBUTE_ERR: 10;\\n    readonly INVALID_STATE_ERR: 11;\\n    readonly SYNTAX_ERR: 12;\\n    readonly INVALID_MODIFICATION_ERR: 13;\\n    readonly NAMESPACE_ERR: 14;\\n    readonly INVALID_ACCESS_ERR: 15;\\n    readonly VALIDATION_ERR: 16;\\n    readonly TYPE_MISMATCH_ERR: 17;\\n    readonly SECURITY_ERR: 18;\\n    readonly NETWORK_ERR: 19;\\n    readonly ABORT_ERR: 20;\\n    readonly URL_MISMATCH_ERR: 21;\\n    readonly QUOTA_EXCEEDED_ERR: 22;\\n    readonly TIMEOUT_ERR: 23;\\n    readonly INVALID_NODE_TYPE_ERR: 24;\\n    readonly DATA_CLONE_ERR: 25;\\n};\\n\\n/**\\n * An object providing methods which are not dependent on any particular document. Such an object is returned by the Document.implementation property.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMImplementation)\\n */\\ninterface DOMImplementation {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMImplementation/createDocument) */\\n    createDocument(namespace: string | null, qualifiedName: string | null, doctype?: DocumentType | null): XMLDocument;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMImplementation/createDocumentType) */\\n    createDocumentType(qualifiedName: string, publicId: string, systemId: string): DocumentType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMImplementation/createHTMLDocument) */\\n    createHTMLDocument(title?: string): Document;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMImplementation/hasFeature)\\n     */\\n    hasFeature(...args: any[]): true;\\n}\\n\\ndeclare var DOMImplementation: {\\n    prototype: DOMImplementation;\\n    new(): DOMImplementation;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix) */\\ninterface DOMMatrix extends DOMMatrixReadOnly {\\n    a: number;\\n    b: number;\\n    c: number;\\n    d: number;\\n    e: number;\\n    f: number;\\n    m11: number;\\n    m12: number;\\n    m13: number;\\n    m14: number;\\n    m21: number;\\n    m22: number;\\n    m23: number;\\n    m24: number;\\n    m31: number;\\n    m32: number;\\n    m33: number;\\n    m34: number;\\n    m41: number;\\n    m42: number;\\n    m43: number;\\n    m44: number;\\n    invertSelf(): DOMMatrix;\\n    multiplySelf(other?: DOMMatrixInit): DOMMatrix;\\n    preMultiplySelf(other?: DOMMatrixInit): DOMMatrix;\\n    rotateAxisAngleSelf(x?: number, y?: number, z?: number, angle?: number): DOMMatrix;\\n    rotateFromVectorSelf(x?: number, y?: number): DOMMatrix;\\n    rotateSelf(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/scale3dSelf) */\\n    scale3dSelf(scale?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/scaleSelf) */\\n    scaleSelf(scaleX?: number, scaleY?: number, scaleZ?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;\\n    setMatrixValue(transformList: string): DOMMatrix;\\n    skewXSelf(sx?: number): DOMMatrix;\\n    skewYSelf(sy?: number): DOMMatrix;\\n    translateSelf(tx?: number, ty?: number, tz?: number): DOMMatrix;\\n}\\n\\ndeclare var DOMMatrix: {\\n    prototype: DOMMatrix;\\n    new(init?: string | number[]): DOMMatrix;\\n    fromFloat32Array(array32: Float32Array): DOMMatrix;\\n    fromFloat64Array(array64: Float64Array): DOMMatrix;\\n    fromMatrix(other?: DOMMatrixInit): DOMMatrix;\\n};\\n\\ntype SVGMatrix = DOMMatrix;\\ndeclare var SVGMatrix: typeof DOMMatrix;\\n\\ntype WebKitCSSMatrix = DOMMatrix;\\ndeclare var WebKitCSSMatrix: typeof DOMMatrix;\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly) */\\ninterface DOMMatrixReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/a) */\\n    readonly a: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/b) */\\n    readonly b: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/c) */\\n    readonly c: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/d) */\\n    readonly d: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/e) */\\n    readonly e: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/f) */\\n    readonly f: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/is2D) */\\n    readonly is2D: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/isIdentity) */\\n    readonly isIdentity: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m11) */\\n    readonly m11: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m12) */\\n    readonly m12: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m13) */\\n    readonly m13: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m14) */\\n    readonly m14: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m21) */\\n    readonly m21: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m22) */\\n    readonly m22: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m23) */\\n    readonly m23: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m24) */\\n    readonly m24: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m31) */\\n    readonly m31: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m32) */\\n    readonly m32: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m33) */\\n    readonly m33: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m34) */\\n    readonly m34: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m41) */\\n    readonly m41: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m42) */\\n    readonly m42: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m43) */\\n    readonly m43: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m44) */\\n    readonly m44: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/flipX) */\\n    flipX(): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/flipY) */\\n    flipY(): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/inverse) */\\n    inverse(): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/multiply) */\\n    multiply(other?: DOMMatrixInit): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotate) */\\n    rotate(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotateAxisAngle) */\\n    rotateAxisAngle(x?: number, y?: number, z?: number, angle?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotateFromVector) */\\n    rotateFromVector(x?: number, y?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/scale) */\\n    scale(scaleX?: number, scaleY?: number, scaleZ?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/scale3d) */\\n    scale3d(scale?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/scaleNonUniform)\\n     */\\n    scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/skewX) */\\n    skewX(sx?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/skewY) */\\n    skewY(sy?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/toFloat32Array) */\\n    toFloat32Array(): Float32Array;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/toFloat64Array) */\\n    toFloat64Array(): Float64Array;\\n    toJSON(): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/transformPoint) */\\n    transformPoint(point?: DOMPointInit): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/translate) */\\n    translate(tx?: number, ty?: number, tz?: number): DOMMatrix;\\n    toString(): string;\\n}\\n\\ndeclare var DOMMatrixReadOnly: {\\n    prototype: DOMMatrixReadOnly;\\n    new(init?: string | number[]): DOMMatrixReadOnly;\\n    fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly;\\n    fromFloat64Array(array64: Float64Array): DOMMatrixReadOnly;\\n    fromMatrix(other?: DOMMatrixInit): DOMMatrixReadOnly;\\n};\\n\\n/**\\n * Provides the ability to parse XML or HTML source code from a string into a DOM Document.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMParser)\\n */\\ninterface DOMParser {\\n    /**\\n     * Parses string using either the HTML or XML parser, according to type, and returns the resulting Document. type can be \\\"text/html\\\" (which will invoke the HTML parser), or any of \\\"text/xml\\\", \\\"application/xml\\\", \\\"application/xhtml+xml\\\", or \\\"image/svg+xml\\\" (which will invoke the XML parser).\\n     *\\n     * For the XML parser, if string cannot be parsed, then the returned Document will contain elements describing the resulting error.\\n     *\\n     * Note that script elements are not evaluated during parsing, and the resulting document's encoding will always be UTF-8.\\n     *\\n     * Values other than the above for type will cause a TypeError exception to be thrown.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMParser/parseFromString)\\n     */\\n    parseFromString(string: string, type: DOMParserSupportedType): Document;\\n}\\n\\ndeclare var DOMParser: {\\n    prototype: DOMParser;\\n    new(): DOMParser;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint) */\\ninterface DOMPoint extends DOMPointReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/w) */\\n    w: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/x) */\\n    x: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/y) */\\n    y: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/z) */\\n    z: number;\\n}\\n\\ndeclare var DOMPoint: {\\n    prototype: DOMPoint;\\n    new(x?: number, y?: number, z?: number, w?: number): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/fromPoint_static) */\\n    fromPoint(other?: DOMPointInit): DOMPoint;\\n};\\n\\ntype SVGPoint = DOMPoint;\\ndeclare var SVGPoint: typeof DOMPoint;\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) */\\ninterface DOMPointReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/w) */\\n    readonly w: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/x) */\\n    readonly x: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/y) */\\n    readonly y: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/z) */\\n    readonly z: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/matrixTransform) */\\n    matrixTransform(matrix?: DOMMatrixInit): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var DOMPointReadOnly: {\\n    prototype: DOMPointReadOnly;\\n    new(x?: number, y?: number, z?: number, w?: number): DOMPointReadOnly;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/fromPoint_static) */\\n    fromPoint(other?: DOMPointInit): DOMPointReadOnly;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad) */\\ninterface DOMQuad {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p1) */\\n    readonly p1: DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p2) */\\n    readonly p2: DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p3) */\\n    readonly p3: DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p4) */\\n    readonly p4: DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/getBounds) */\\n    getBounds(): DOMRect;\\n    toJSON(): any;\\n}\\n\\ndeclare var DOMQuad: {\\n    prototype: DOMQuad;\\n    new(p1?: DOMPointInit, p2?: DOMPointInit, p3?: DOMPointInit, p4?: DOMPointInit): DOMQuad;\\n    fromQuad(other?: DOMQuadInit): DOMQuad;\\n    fromRect(other?: DOMRectInit): DOMQuad;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRect) */\\ninterface DOMRect extends DOMRectReadOnly {\\n    height: number;\\n    width: number;\\n    x: number;\\n    y: number;\\n}\\n\\ndeclare var DOMRect: {\\n    prototype: DOMRect;\\n    new(x?: number, y?: number, width?: number, height?: number): DOMRect;\\n    fromRect(other?: DOMRectInit): DOMRect;\\n};\\n\\ntype SVGRect = DOMRect;\\ndeclare var SVGRect: typeof DOMRect;\\n\\ninterface DOMRectList {\\n    readonly length: number;\\n    item(index: number): DOMRect | null;\\n    [index: number]: DOMRect;\\n}\\n\\ndeclare var DOMRectList: {\\n    prototype: DOMRectList;\\n    new(): DOMRectList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) */\\ninterface DOMRectReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/bottom) */\\n    readonly bottom: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/height) */\\n    readonly height: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/left) */\\n    readonly left: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/right) */\\n    readonly right: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/top) */\\n    readonly top: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/width) */\\n    readonly width: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/x) */\\n    readonly x: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/y) */\\n    readonly y: number;\\n    toJSON(): any;\\n}\\n\\ndeclare var DOMRectReadOnly: {\\n    prototype: DOMRectReadOnly;\\n    new(x?: number, y?: number, width?: number, height?: number): DOMRectReadOnly;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/fromRect_static) */\\n    fromRect(other?: DOMRectInit): DOMRectReadOnly;\\n};\\n\\n/**\\n * A type returned by some APIs which contains a list of DOMString (strings).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringList)\\n */\\ninterface DOMStringList {\\n    /**\\n     * Returns the number of strings in strings.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringList/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns true if strings contains string, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringList/contains)\\n     */\\n    contains(string: string): boolean;\\n    /**\\n     * Returns the string with index index from strings.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringList/item)\\n     */\\n    item(index: number): string | null;\\n    [index: number]: string;\\n}\\n\\ndeclare var DOMStringList: {\\n    prototype: DOMStringList;\\n    new(): DOMStringList;\\n};\\n\\n/**\\n * Used by the dataset HTML attribute to represent data for custom attributes added to elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringMap)\\n */\\ninterface DOMStringMap {\\n    [name: string]: string | undefined;\\n}\\n\\ndeclare var DOMStringMap: {\\n    prototype: DOMStringMap;\\n    new(): DOMStringMap;\\n};\\n\\n/**\\n * A set of space-separated tokens. Such a set is returned by Element.classList, HTMLLinkElement.relList, HTMLAnchorElement.relList, HTMLAreaElement.relList, HTMLIframeElement.sandbox, or HTMLOutputElement.htmlFor. It is indexed beginning with 0 as with JavaScript Array objects. DOMTokenList is always case-sensitive.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList)\\n */\\ninterface DOMTokenList {\\n    /**\\n     * Returns the number of tokens.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the associated set as string.\\n     *\\n     * Can be set, to change the associated attribute.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/value)\\n     */\\n    value: string;\\n    toString(): string;\\n    /**\\n     * Adds all arguments passed, except those already present.\\n     *\\n     * Throws a \\\"SyntaxError\\\" DOMException if one of the arguments is the empty string.\\n     *\\n     * Throws an \\\"InvalidCharacterError\\\" DOMException if one of the arguments contains any ASCII whitespace.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/add)\\n     */\\n    add(...tokens: string[]): void;\\n    /**\\n     * Returns true if token is present, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/contains)\\n     */\\n    contains(token: string): boolean;\\n    /**\\n     * Returns the token with index index.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/item)\\n     */\\n    item(index: number): string | null;\\n    /**\\n     * Removes arguments passed, if they are present.\\n     *\\n     * Throws a \\\"SyntaxError\\\" DOMException if one of the arguments is the empty string.\\n     *\\n     * Throws an \\\"InvalidCharacterError\\\" DOMException if one of the arguments contains any ASCII whitespace.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/remove)\\n     */\\n    remove(...tokens: string[]): void;\\n    /**\\n     * Replaces token with newToken.\\n     *\\n     * Returns true if token was replaced with newToken, and false otherwise.\\n     *\\n     * Throws a \\\"SyntaxError\\\" DOMException if one of the arguments is the empty string.\\n     *\\n     * Throws an \\\"InvalidCharacterError\\\" DOMException if one of the arguments contains any ASCII whitespace.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/replace)\\n     */\\n    replace(token: string, newToken: string): boolean;\\n    /**\\n     * Returns true if token is in the associated attribute's supported tokens. Returns false otherwise.\\n     *\\n     * Throws a TypeError if the associated attribute has no supported tokens defined.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/supports)\\n     */\\n    supports(token: string): boolean;\\n    /**\\n     * If force is not given, \\\"toggles\\\" token, removing it if it's present and adding it if it's not present. If force is true, adds token (same as add()). If force is false, removes token (same as remove()).\\n     *\\n     * Returns true if token is now present, and false otherwise.\\n     *\\n     * Throws a \\\"SyntaxError\\\" DOMException if token is empty.\\n     *\\n     * Throws an \\\"InvalidCharacterError\\\" DOMException if token contains any spaces.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMTokenList/toggle)\\n     */\\n    toggle(token: string, force?: boolean): boolean;\\n    forEach(callbackfn: (value: string, key: number, parent: DOMTokenList) => void, thisArg?: any): void;\\n    [index: number]: string;\\n}\\n\\ndeclare var DOMTokenList: {\\n    prototype: DOMTokenList;\\n    new(): DOMTokenList;\\n};\\n\\n/**\\n * Used to hold the data that is being dragged during a drag and drop operation. It may hold one or more data items, each of one or more data types. For more information about drag and drop, see HTML Drag and Drop API.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer)\\n */\\ninterface DataTransfer {\\n    /**\\n     * Returns the kind of operation that is currently selected. If the kind of operation isn't one of those that is allowed by the effectAllowed attribute, then the operation will fail.\\n     *\\n     * Can be set, to change the selected operation.\\n     *\\n     * The possible values are \\\"none\\\", \\\"copy\\\", \\\"link\\\", and \\\"move\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/dropEffect)\\n     */\\n    dropEffect: \\\"none\\\" | \\\"copy\\\" | \\\"link\\\" | \\\"move\\\";\\n    /**\\n     * Returns the kinds of operations that are to be allowed.\\n     *\\n     * Can be set (during the dragstart event), to change the allowed operations.\\n     *\\n     * The possible values are \\\"none\\\", \\\"copy\\\", \\\"copyLink\\\", \\\"copyMove\\\", \\\"link\\\", \\\"linkMove\\\", \\\"move\\\", \\\"all\\\", and \\\"uninitialized\\\",\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/effectAllowed)\\n     */\\n    effectAllowed: \\\"none\\\" | \\\"copy\\\" | \\\"copyLink\\\" | \\\"copyMove\\\" | \\\"link\\\" | \\\"linkMove\\\" | \\\"move\\\" | \\\"all\\\" | \\\"uninitialized\\\";\\n    /**\\n     * Returns a FileList of the files being dragged, if any.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/files)\\n     */\\n    readonly files: FileList;\\n    /**\\n     * Returns a DataTransferItemList object, with the drag data.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/items)\\n     */\\n    readonly items: DataTransferItemList;\\n    /**\\n     * Returns a frozen array listing the formats that were set in the dragstart event. In addition, if any files are being dragged, then one of the types will be the string \\\"Files\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/types)\\n     */\\n    readonly types: ReadonlyArray<string>;\\n    /**\\n     * Removes the data of the specified formats. Removes all data if the argument is omitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/clearData)\\n     */\\n    clearData(format?: string): void;\\n    /**\\n     * Returns the specified data. If there is no such data, returns the empty string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/getData)\\n     */\\n    getData(format: string): string;\\n    /**\\n     * Adds the specified data.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/setData)\\n     */\\n    setData(format: string, data: string): void;\\n    /**\\n     * Uses the given element to update the drag feedback, replacing any previously specified feedback.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransfer/setDragImage)\\n     */\\n    setDragImage(image: Element, x: number, y: number): void;\\n}\\n\\ndeclare var DataTransfer: {\\n    prototype: DataTransfer;\\n    new(): DataTransfer;\\n};\\n\\n/**\\n * One drag data item. During a drag operation, each drag event has a dataTransfer property which contains a list of drag data items. Each item in the list is a DataTransferItem object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItem)\\n */\\ninterface DataTransferItem {\\n    /**\\n     * Returns the drag data item kind, one of: \\\"string\\\", \\\"file\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItem/kind)\\n     */\\n    readonly kind: string;\\n    /**\\n     * Returns the drag data item type string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItem/type)\\n     */\\n    readonly type: string;\\n    /**\\n     * Returns a File object, if the drag data item kind is File.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItem/getAsFile)\\n     */\\n    getAsFile(): File | null;\\n    /**\\n     * Invokes the callback with the string data as the argument, if the drag data item kind is text.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItem/getAsString)\\n     */\\n    getAsString(callback: FunctionStringCallback | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItem/webkitGetAsEntry) */\\n    webkitGetAsEntry(): FileSystemEntry | null;\\n}\\n\\ndeclare var DataTransferItem: {\\n    prototype: DataTransferItem;\\n    new(): DataTransferItem;\\n};\\n\\n/**\\n * A list of DataTransferItem objects representing items being dragged. During a drag operation, each DragEvent has a dataTransfer property and that property is a DataTransferItemList.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItemList)\\n */\\ninterface DataTransferItemList {\\n    /**\\n     * Returns the number of items in the drag data store.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItemList/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Adds a new entry for the given data to the drag data store. If the data is plain text then a type string has to be provided also.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItemList/add)\\n     */\\n    add(data: string, type: string): DataTransferItem | null;\\n    add(data: File): DataTransferItem | null;\\n    /**\\n     * Removes all the entries in the drag data store.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItemList/clear)\\n     */\\n    clear(): void;\\n    /**\\n     * Removes the indexth entry in the drag data store.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DataTransferItemList/remove)\\n     */\\n    remove(index: number): void;\\n    [index: number]: DataTransferItem;\\n}\\n\\ndeclare var DataTransferItemList: {\\n    prototype: DataTransferItemList;\\n    new(): DataTransferItemList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DecompressionStream) */\\ninterface DecompressionStream extends GenericTransformStream {\\n}\\n\\ndeclare var DecompressionStream: {\\n    prototype: DecompressionStream;\\n    new(format: CompressionFormat): DecompressionStream;\\n};\\n\\n/**\\n * A delay-line; an AudioNode audio-processing module that causes a delay between the arrival of an input data and its propagation to the output.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DelayNode)\\n */\\ninterface DelayNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DelayNode/delayTime) */\\n    readonly delayTime: AudioParam;\\n}\\n\\ndeclare var DelayNode: {\\n    prototype: DelayNode;\\n    new(context: BaseAudioContext, options?: DelayOptions): DelayNode;\\n};\\n\\n/**\\n * The DeviceMotionEvent provides web developers with information about the speed of changes for the device's position and orientation.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEvent)\\n */\\ninterface DeviceMotionEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEvent/acceleration) */\\n    readonly acceleration: DeviceMotionEventAcceleration | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEvent/accelerationIncludingGravity) */\\n    readonly accelerationIncludingGravity: DeviceMotionEventAcceleration | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEvent/interval) */\\n    readonly interval: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEvent/rotationRate) */\\n    readonly rotationRate: DeviceMotionEventRotationRate | null;\\n}\\n\\ndeclare var DeviceMotionEvent: {\\n    prototype: DeviceMotionEvent;\\n    new(type: string, eventInitDict?: DeviceMotionEventInit): DeviceMotionEvent;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEventAcceleration)\\n */\\ninterface DeviceMotionEventAcceleration {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEventAcceleration/x) */\\n    readonly x: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEventAcceleration/y) */\\n    readonly y: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEventAcceleration/z) */\\n    readonly z: number | null;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEventRotationRate)\\n */\\ninterface DeviceMotionEventRotationRate {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEventRotationRate/alpha) */\\n    readonly alpha: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEventRotationRate/beta) */\\n    readonly beta: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceMotionEventRotationRate/gamma) */\\n    readonly gamma: number | null;\\n}\\n\\n/**\\n * The DeviceOrientationEvent provides web developers with information from the physical orientation of the device running the web page.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceOrientationEvent)\\n */\\ninterface DeviceOrientationEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceOrientationEvent/absolute) */\\n    readonly absolute: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceOrientationEvent/alpha) */\\n    readonly alpha: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceOrientationEvent/beta) */\\n    readonly beta: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DeviceOrientationEvent/gamma) */\\n    readonly gamma: number | null;\\n}\\n\\ndeclare var DeviceOrientationEvent: {\\n    prototype: DeviceOrientationEvent;\\n    new(type: string, eventInitDict?: DeviceOrientationEventInit): DeviceOrientationEvent;\\n};\\n\\ninterface DocumentEventMap extends GlobalEventHandlersEventMap {\\n    \\\"DOMContentLoaded\\\": Event;\\n    \\\"fullscreenchange\\\": Event;\\n    \\\"fullscreenerror\\\": Event;\\n    \\\"pointerlockchange\\\": Event;\\n    \\\"pointerlockerror\\\": Event;\\n    \\\"readystatechange\\\": Event;\\n    \\\"visibilitychange\\\": Event;\\n}\\n\\n/**\\n * Any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document)\\n */\\ninterface Document extends Node, DocumentOrShadowRoot, FontFaceSource, GlobalEventHandlers, NonElementParentNode, ParentNode, XPathEvaluatorBase {\\n    /**\\n     * Sets or gets the URL for the current document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/URL)\\n     */\\n    readonly URL: string;\\n    /**\\n     * Sets or gets the color of all active links in the document.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/alinkColor)\\n     */\\n    alinkColor: string;\\n    /**\\n     * Returns a reference to the collection of elements contained by the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/all)\\n     */\\n    readonly all: HTMLAllCollection;\\n    /**\\n     * Retrieves a collection of all a objects that have a name and/or id property. Objects in this collection are in HTML source order.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/anchors)\\n     */\\n    readonly anchors: HTMLCollectionOf<HTMLAnchorElement>;\\n    /**\\n     * Retrieves a collection of all applet objects in the document.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/applets)\\n     */\\n    readonly applets: HTMLCollection;\\n    /**\\n     * Deprecated. Sets or retrieves a value that indicates the background color behind the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/bgColor)\\n     */\\n    bgColor: string;\\n    /**\\n     * Specifies the beginning and end of the document body.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/body)\\n     */\\n    body: HTMLElement;\\n    /**\\n     * Returns document's encoding.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/characterSet)\\n     */\\n    readonly characterSet: string;\\n    /**\\n     * Gets or sets the character set used to encode the object.\\n     * @deprecated This is a legacy alias of `characterSet`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/characterSet)\\n     */\\n    readonly charset: string;\\n    /**\\n     * Gets a value that indicates whether standards-compliant mode is switched on for the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/compatMode)\\n     */\\n    readonly compatMode: string;\\n    /**\\n     * Returns document's content type.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/contentType)\\n     */\\n    readonly contentType: string;\\n    /**\\n     * Returns the HTTP cookies that apply to the Document. If there are no cookies or cookies can't be applied to this resource, the empty string will be returned.\\n     *\\n     * Can be set, to add a new cookie to the element's set of HTTP cookies.\\n     *\\n     * If the contents are sandboxed into a unique origin (e.g. in an iframe with the sandbox attribute), a \\\"SecurityError\\\" DOMException will be thrown on getting and setting.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/cookie)\\n     */\\n    cookie: string;\\n    /**\\n     * Returns the script element, or the SVG script element, that is currently executing, as long as the element represents a classic script. In the case of reentrant script execution, returns the one that most recently started executing amongst those that have not yet finished executing.\\n     *\\n     * Returns null if the Document is not currently executing a script or SVG script element (e.g., because the running script is an event handler, or a timeout), or if the currently executing script or SVG script element represents a module script.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/currentScript)\\n     */\\n    readonly currentScript: HTMLOrSVGScriptElement | null;\\n    /**\\n     * Returns the Window object of the active document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/defaultView)\\n     */\\n    readonly defaultView: (WindowProxy & typeof globalThis) | null;\\n    /**\\n     * Sets or gets a value that indicates whether the document can be edited.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/designMode)\\n     */\\n    designMode: string;\\n    /**\\n     * Sets or retrieves a value that indicates the reading order of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/dir)\\n     */\\n    dir: string;\\n    /**\\n     * Gets an object representing the document type declaration associated with the current document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/doctype)\\n     */\\n    readonly doctype: DocumentType | null;\\n    /**\\n     * Gets a reference to the root node of the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/documentElement)\\n     */\\n    readonly documentElement: HTMLElement;\\n    /**\\n     * Returns document's URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/documentURI)\\n     */\\n    readonly documentURI: string;\\n    /**\\n     * Sets or gets the security domain of the document.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/domain)\\n     */\\n    domain: string;\\n    /**\\n     * Retrieves a collection of all embed objects in the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/embeds)\\n     */\\n    readonly embeds: HTMLCollectionOf<HTMLEmbedElement>;\\n    /**\\n     * Sets or gets the foreground (text) color of the document.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fgColor)\\n     */\\n    fgColor: string;\\n    /**\\n     * Retrieves a collection, in source order, of all form objects in the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/forms)\\n     */\\n    readonly forms: HTMLCollectionOf<HTMLFormElement>;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fullscreen)\\n     */\\n    readonly fullscreen: boolean;\\n    /**\\n     * Returns true if document has the ability to display elements fullscreen and fullscreen is supported, or false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fullscreenEnabled)\\n     */\\n    readonly fullscreenEnabled: boolean;\\n    /**\\n     * Returns the head element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/head)\\n     */\\n    readonly head: HTMLHeadElement;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/hidden) */\\n    readonly hidden: boolean;\\n    /**\\n     * Retrieves a collection, in source order, of img objects in the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/images)\\n     */\\n    readonly images: HTMLCollectionOf<HTMLImageElement>;\\n    /**\\n     * Gets the implementation object of the current document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/implementation)\\n     */\\n    readonly implementation: DOMImplementation;\\n    /**\\n     * Returns the character encoding used to create the webpage that is loaded into the document object.\\n     * @deprecated This is a legacy alias of `characterSet`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/characterSet)\\n     */\\n    readonly inputEncoding: string;\\n    /**\\n     * Gets the date that the page was last modified, if the page supplies one.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/lastModified)\\n     */\\n    readonly lastModified: string;\\n    /**\\n     * Sets or gets the color of the document links.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/linkColor)\\n     */\\n    linkColor: string;\\n    /**\\n     * Retrieves a collection of all a objects that specify the href property and all area objects in the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/links)\\n     */\\n    readonly links: HTMLCollectionOf<HTMLAnchorElement | HTMLAreaElement>;\\n    /**\\n     * Contains information about the current URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/location)\\n     */\\n    get location(): Location;\\n    set location(href: string | Location);\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fullscreenchange_event) */\\n    onfullscreenchange: ((this: Document, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fullscreenerror_event) */\\n    onfullscreenerror: ((this: Document, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/pointerlockchange_event) */\\n    onpointerlockchange: ((this: Document, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/pointerlockerror_event) */\\n    onpointerlockerror: ((this: Document, ev: Event) => any) | null;\\n    /**\\n     * Fires when the state of the object has changed.\\n     * @param ev The event\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/readystatechange_event)\\n     */\\n    onreadystatechange: ((this: Document, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/visibilitychange_event) */\\n    onvisibilitychange: ((this: Document, ev: Event) => any) | null;\\n    readonly ownerDocument: null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/pictureInPictureEnabled) */\\n    readonly pictureInPictureEnabled: boolean;\\n    /**\\n     * Return an HTMLCollection of the embed elements in the Document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/plugins)\\n     */\\n    readonly plugins: HTMLCollectionOf<HTMLEmbedElement>;\\n    /**\\n     * Retrieves a value that indicates the current state of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/readyState)\\n     */\\n    readonly readyState: DocumentReadyState;\\n    /**\\n     * Gets the URL of the location that referred the user to the current page.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/referrer)\\n     */\\n    readonly referrer: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/rootElement)\\n     */\\n    readonly rootElement: SVGSVGElement | null;\\n    /**\\n     * Retrieves a collection of all script objects in the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/scripts)\\n     */\\n    readonly scripts: HTMLCollectionOf<HTMLScriptElement>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/scrollingElement) */\\n    readonly scrollingElement: Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/timeline) */\\n    readonly timeline: DocumentTimeline;\\n    /**\\n     * Contains the title of the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/title)\\n     */\\n    title: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/visibilityState) */\\n    readonly visibilityState: DocumentVisibilityState;\\n    /**\\n     * Sets or gets the color of the links that the user has visited.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/vlinkColor)\\n     */\\n    vlinkColor: string;\\n    /**\\n     * Moves node from another document and returns it.\\n     *\\n     * If node is a document, throws a \\\"NotSupportedError\\\" DOMException or, if node is a shadow root, throws a \\\"HierarchyRequestError\\\" DOMException.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/adoptNode)\\n     */\\n    adoptNode<T extends Node>(node: T): T;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/captureEvents)\\n     */\\n    captureEvents(): void;\\n    /** @deprecated */\\n    caretRangeFromPoint(x: number, y: number): Range | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/clear)\\n     */\\n    clear(): void;\\n    /**\\n     * Closes an output stream and forces the sent data to display.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/close)\\n     */\\n    close(): void;\\n    /**\\n     * Creates an attribute object with a specified name.\\n     * @param name String that sets the attribute object's name.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createAttribute)\\n     */\\n    createAttribute(localName: string): Attr;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createAttributeNS) */\\n    createAttributeNS(namespace: string | null, qualifiedName: string): Attr;\\n    /**\\n     * Returns a CDATASection node whose data is data.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createCDATASection)\\n     */\\n    createCDATASection(data: string): CDATASection;\\n    /**\\n     * Creates a comment object with the specified data.\\n     * @param data Sets the comment object's data.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createComment)\\n     */\\n    createComment(data: string): Comment;\\n    /**\\n     * Creates a new document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createDocumentFragment)\\n     */\\n    createDocumentFragment(): DocumentFragment;\\n    /**\\n     * Creates an instance of the element for the specified tag.\\n     * @param tagName The name of an element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createElement)\\n     */\\n    createElement<K extends keyof HTMLElementTagNameMap>(tagName: K, options?: ElementCreationOptions): HTMLElementTagNameMap[K];\\n    /** @deprecated */\\n    createElement<K extends keyof HTMLElementDeprecatedTagNameMap>(tagName: K, options?: ElementCreationOptions): HTMLElementDeprecatedTagNameMap[K];\\n    createElement(tagName: string, options?: ElementCreationOptions): HTMLElement;\\n    /**\\n     * Returns an element with namespace namespace. Its namespace prefix will be everything before \\\":\\\" (U+003E) in qualifiedName or null. Its local name will be everything after \\\":\\\" (U+003E) in qualifiedName or qualifiedName.\\n     *\\n     * If localName does not match the Name production an \\\"InvalidCharacterError\\\" DOMException will be thrown.\\n     *\\n     * If one of the following conditions is true a \\\"NamespaceError\\\" DOMException will be thrown:\\n     *\\n     * localName does not match the QName production.\\n     * Namespace prefix is not null and namespace is the empty string.\\n     * Namespace prefix is \\\"xml\\\" and namespace is not the XML namespace.\\n     * qualifiedName or namespace prefix is \\\"xmlns\\\" and namespace is not the XMLNS namespace.\\n     * namespace is the XMLNS namespace and neither qualifiedName nor namespace prefix is \\\"xmlns\\\".\\n     *\\n     * When supplied, options's is can be used to create a customized built-in element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createElementNS)\\n     */\\n    createElementNS(namespaceURI: \\\"http://www.w3.org/1999/xhtml\\\", qualifiedName: string): HTMLElement;\\n    createElementNS<K extends keyof SVGElementTagNameMap>(namespaceURI: \\\"http://www.w3.org/2000/svg\\\", qualifiedName: K): SVGElementTagNameMap[K];\\n    createElementNS(namespaceURI: \\\"http://www.w3.org/2000/svg\\\", qualifiedName: string): SVGElement;\\n    createElementNS<K extends keyof MathMLElementTagNameMap>(namespaceURI: \\\"http://www.w3.org/1998/Math/MathML\\\", qualifiedName: K): MathMLElementTagNameMap[K];\\n    createElementNS(namespaceURI: \\\"http://www.w3.org/1998/Math/MathML\\\", qualifiedName: string): MathMLElement;\\n    createElementNS(namespaceURI: string | null, qualifiedName: string, options?: ElementCreationOptions): Element;\\n    createElementNS(namespace: string | null, qualifiedName: string, options?: string | ElementCreationOptions): Element;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createEvent) */\\n    createEvent(eventInterface: \\\"AnimationEvent\\\"): AnimationEvent;\\n    createEvent(eventInterface: \\\"AnimationPlaybackEvent\\\"): AnimationPlaybackEvent;\\n    createEvent(eventInterface: \\\"AudioProcessingEvent\\\"): AudioProcessingEvent;\\n    createEvent(eventInterface: \\\"BeforeUnloadEvent\\\"): BeforeUnloadEvent;\\n    createEvent(eventInterface: \\\"BlobEvent\\\"): BlobEvent;\\n    createEvent(eventInterface: \\\"ClipboardEvent\\\"): ClipboardEvent;\\n    createEvent(eventInterface: \\\"CloseEvent\\\"): CloseEvent;\\n    createEvent(eventInterface: \\\"CompositionEvent\\\"): CompositionEvent;\\n    createEvent(eventInterface: \\\"CustomEvent\\\"): CustomEvent;\\n    createEvent(eventInterface: \\\"DeviceMotionEvent\\\"): DeviceMotionEvent;\\n    createEvent(eventInterface: \\\"DeviceOrientationEvent\\\"): DeviceOrientationEvent;\\n    createEvent(eventInterface: \\\"DragEvent\\\"): DragEvent;\\n    createEvent(eventInterface: \\\"ErrorEvent\\\"): ErrorEvent;\\n    createEvent(eventInterface: \\\"Event\\\"): Event;\\n    createEvent(eventInterface: \\\"Events\\\"): Event;\\n    createEvent(eventInterface: \\\"FocusEvent\\\"): FocusEvent;\\n    createEvent(eventInterface: \\\"FontFaceSetLoadEvent\\\"): FontFaceSetLoadEvent;\\n    createEvent(eventInterface: \\\"FormDataEvent\\\"): FormDataEvent;\\n    createEvent(eventInterface: \\\"GamepadEvent\\\"): GamepadEvent;\\n    createEvent(eventInterface: \\\"HashChangeEvent\\\"): HashChangeEvent;\\n    createEvent(eventInterface: \\\"IDBVersionChangeEvent\\\"): IDBVersionChangeEvent;\\n    createEvent(eventInterface: \\\"InputEvent\\\"): InputEvent;\\n    createEvent(eventInterface: \\\"KeyboardEvent\\\"): KeyboardEvent;\\n    createEvent(eventInterface: \\\"MIDIConnectionEvent\\\"): MIDIConnectionEvent;\\n    createEvent(eventInterface: \\\"MIDIMessageEvent\\\"): MIDIMessageEvent;\\n    createEvent(eventInterface: \\\"MediaEncryptedEvent\\\"): MediaEncryptedEvent;\\n    createEvent(eventInterface: \\\"MediaKeyMessageEvent\\\"): MediaKeyMessageEvent;\\n    createEvent(eventInterface: \\\"MediaQueryListEvent\\\"): MediaQueryListEvent;\\n    createEvent(eventInterface: \\\"MediaStreamTrackEvent\\\"): MediaStreamTrackEvent;\\n    createEvent(eventInterface: \\\"MessageEvent\\\"): MessageEvent;\\n    createEvent(eventInterface: \\\"MouseEvent\\\"): MouseEvent;\\n    createEvent(eventInterface: \\\"MouseEvents\\\"): MouseEvent;\\n    createEvent(eventInterface: \\\"MutationEvent\\\"): MutationEvent;\\n    createEvent(eventInterface: \\\"MutationEvents\\\"): MutationEvent;\\n    createEvent(eventInterface: \\\"OfflineAudioCompletionEvent\\\"): OfflineAudioCompletionEvent;\\n    createEvent(eventInterface: \\\"PageTransitionEvent\\\"): PageTransitionEvent;\\n    createEvent(eventInterface: \\\"PaymentMethodChangeEvent\\\"): PaymentMethodChangeEvent;\\n    createEvent(eventInterface: \\\"PaymentRequestUpdateEvent\\\"): PaymentRequestUpdateEvent;\\n    createEvent(eventInterface: \\\"PictureInPictureEvent\\\"): PictureInPictureEvent;\\n    createEvent(eventInterface: \\\"PointerEvent\\\"): PointerEvent;\\n    createEvent(eventInterface: \\\"PopStateEvent\\\"): PopStateEvent;\\n    createEvent(eventInterface: \\\"ProgressEvent\\\"): ProgressEvent;\\n    createEvent(eventInterface: \\\"PromiseRejectionEvent\\\"): PromiseRejectionEvent;\\n    createEvent(eventInterface: \\\"RTCDTMFToneChangeEvent\\\"): RTCDTMFToneChangeEvent;\\n    createEvent(eventInterface: \\\"RTCDataChannelEvent\\\"): RTCDataChannelEvent;\\n    createEvent(eventInterface: \\\"RTCErrorEvent\\\"): RTCErrorEvent;\\n    createEvent(eventInterface: \\\"RTCPeerConnectionIceErrorEvent\\\"): RTCPeerConnectionIceErrorEvent;\\n    createEvent(eventInterface: \\\"RTCPeerConnectionIceEvent\\\"): RTCPeerConnectionIceEvent;\\n    createEvent(eventInterface: \\\"RTCTrackEvent\\\"): RTCTrackEvent;\\n    createEvent(eventInterface: \\\"SecurityPolicyViolationEvent\\\"): SecurityPolicyViolationEvent;\\n    createEvent(eventInterface: \\\"SpeechSynthesisErrorEvent\\\"): SpeechSynthesisErrorEvent;\\n    createEvent(eventInterface: \\\"SpeechSynthesisEvent\\\"): SpeechSynthesisEvent;\\n    createEvent(eventInterface: \\\"StorageEvent\\\"): StorageEvent;\\n    createEvent(eventInterface: \\\"SubmitEvent\\\"): SubmitEvent;\\n    createEvent(eventInterface: \\\"ToggleEvent\\\"): ToggleEvent;\\n    createEvent(eventInterface: \\\"TouchEvent\\\"): TouchEvent;\\n    createEvent(eventInterface: \\\"TrackEvent\\\"): TrackEvent;\\n    createEvent(eventInterface: \\\"TransitionEvent\\\"): TransitionEvent;\\n    createEvent(eventInterface: \\\"UIEvent\\\"): UIEvent;\\n    createEvent(eventInterface: \\\"UIEvents\\\"): UIEvent;\\n    createEvent(eventInterface: \\\"WebGLContextEvent\\\"): WebGLContextEvent;\\n    createEvent(eventInterface: \\\"WheelEvent\\\"): WheelEvent;\\n    createEvent(eventInterface: string): Event;\\n    /**\\n     * Creates a NodeIterator object that you can use to traverse filtered lists of nodes or elements in a document.\\n     * @param root The root element or node to start traversing on.\\n     * @param whatToShow The type of nodes or elements to appear in the node list\\n     * @param filter A custom NodeFilter function to use. For more information, see filter. Use null for no filter.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createNodeIterator)\\n     */\\n    createNodeIterator(root: Node, whatToShow?: number, filter?: NodeFilter | null): NodeIterator;\\n    /**\\n     * Returns a ProcessingInstruction node whose target is target and data is data. If target does not match the Name production an \\\"InvalidCharacterError\\\" DOMException will be thrown. If data contains \\\"?>\\\" an \\\"InvalidCharacterError\\\" DOMException will be thrown.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createProcessingInstruction)\\n     */\\n    createProcessingInstruction(target: string, data: string): ProcessingInstruction;\\n    /**\\n     *  Returns an empty range object that has both of its boundary points positioned at the beginning of the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createRange)\\n     */\\n    createRange(): Range;\\n    /**\\n     * Creates a text string from the specified value.\\n     * @param data String that specifies the nodeValue property of the text node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createTextNode)\\n     */\\n    createTextNode(data: string): Text;\\n    /**\\n     * Creates a TreeWalker object that you can use to traverse filtered lists of nodes or elements in a document.\\n     * @param root The root element or node to start traversing on.\\n     * @param whatToShow The type of nodes or elements to appear in the node list. For more information, see whatToShow.\\n     * @param filter A custom NodeFilter function to use.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createTreeWalker)\\n     */\\n    createTreeWalker(root: Node, whatToShow?: number, filter?: NodeFilter | null): TreeWalker;\\n    /**\\n     * Executes a command on the current document, current selection, or the given range.\\n     * @param commandId String that specifies the command to execute. This command can be any of the command identifiers that can be executed in script.\\n     * @param showUI Display the user interface, defaults to false.\\n     * @param value Value to assign.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/execCommand)\\n     */\\n    execCommand(commandId: string, showUI?: boolean, value?: string): boolean;\\n    /**\\n     * Stops document's fullscreen element from being displayed fullscreen and resolves promise when done.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/exitFullscreen)\\n     */\\n    exitFullscreen(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/exitPictureInPicture) */\\n    exitPictureInPicture(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/exitPointerLock) */\\n    exitPointerLock(): void;\\n    /**\\n     * Returns a reference to the first object with the specified value of the ID attribute.\\n     * @param elementId String that specifies the ID value.\\n     */\\n    getElementById(elementId: string): HTMLElement | null;\\n    /**\\n     * Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/getElementsByClassName)\\n     */\\n    getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;\\n    /**\\n     * Gets a collection of objects based on the value of the NAME or ID attribute.\\n     * @param elementName Gets a collection of objects based on the value of the NAME or ID attribute.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/getElementsByName)\\n     */\\n    getElementsByName(elementName: string): NodeListOf<HTMLElement>;\\n    /**\\n     * Retrieves a collection of objects based on the specified element name.\\n     * @param name Specifies the name of an element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/getElementsByTagName)\\n     */\\n    getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;\\n    getElementsByTagName<K extends keyof SVGElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<SVGElementTagNameMap[K]>;\\n    getElementsByTagName<K extends keyof MathMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<MathMLElementTagNameMap[K]>;\\n    /** @deprecated */\\n    getElementsByTagName<K extends keyof HTMLElementDeprecatedTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;\\n    getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;\\n    /**\\n     * If namespace and localName are \\\"*\\\" returns a HTMLCollection of all descendant elements.\\n     *\\n     * If only namespace is \\\"*\\\" returns a HTMLCollection of all descendant elements whose local name is localName.\\n     *\\n     * If only localName is \\\"*\\\" returns a HTMLCollection of all descendant elements whose namespace is namespace.\\n     *\\n     * Otherwise, returns a HTMLCollection of all descendant elements whose namespace is namespace and local name is localName.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/getElementsByTagNameNS)\\n     */\\n    getElementsByTagNameNS(namespaceURI: \\\"http://www.w3.org/1999/xhtml\\\", localName: string): HTMLCollectionOf<HTMLElement>;\\n    getElementsByTagNameNS(namespaceURI: \\\"http://www.w3.org/2000/svg\\\", localName: string): HTMLCollectionOf<SVGElement>;\\n    getElementsByTagNameNS(namespaceURI: \\\"http://www.w3.org/1998/Math/MathML\\\", localName: string): HTMLCollectionOf<MathMLElement>;\\n    getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf<Element>;\\n    /**\\n     * Returns an object representing the current selection of the document that is loaded into the object displaying a webpage.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/getSelection)\\n     */\\n    getSelection(): Selection | null;\\n    /**\\n     * Gets a value indicating whether the object currently has focus.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/hasFocus)\\n     */\\n    hasFocus(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/hasStorageAccess) */\\n    hasStorageAccess(): Promise<boolean>;\\n    /**\\n     * Returns a copy of node. If deep is true, the copy also includes the node's descendants.\\n     *\\n     * If node is a document or a shadow root, throws a \\\"NotSupportedError\\\" DOMException.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/importNode)\\n     */\\n    importNode<T extends Node>(node: T, deep?: boolean): T;\\n    /**\\n     * Opens a new window and loads a document specified by a given URL. Also, opens a new window that uses the url parameter and the name parameter to collect the output of the write method and the writeln method.\\n     * @param url Specifies a MIME type for the document.\\n     * @param name Specifies the name of the window. This name is used as the value for the TARGET attribute on a form or an anchor element.\\n     * @param features Contains a list of items separated by commas. Each item consists of an option and a value, separated by an equals sign (for example, \\\"fullscreen=yes, toolbar=yes\\\"). The following values are supported.\\n     * @param replace Specifies whether the existing entry for the document is replaced in the history list.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/open)\\n     */\\n    open(unused1?: string, unused2?: string): Document;\\n    open(url: string | URL, name: string, features: string): WindowProxy | null;\\n    /**\\n     * Returns a Boolean value that indicates whether a specified command can be successfully executed using execCommand, given the current state of the document.\\n     * @param commandId Specifies a command identifier.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/queryCommandEnabled)\\n     */\\n    queryCommandEnabled(commandId: string): boolean;\\n    /**\\n     * Returns a Boolean value that indicates whether the specified command is in the indeterminate state.\\n     * @param commandId String that specifies a command identifier.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/queryCommandIndeterm)\\n     */\\n    queryCommandIndeterm(commandId: string): boolean;\\n    /**\\n     * Returns a Boolean value that indicates the current state of the command.\\n     * @param commandId String that specifies a command identifier.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/queryCommandState)\\n     */\\n    queryCommandState(commandId: string): boolean;\\n    /**\\n     * Returns a Boolean value that indicates whether the current command is supported on the current range.\\n     * @param commandId Specifies a command identifier.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/queryCommandSupported)\\n     */\\n    queryCommandSupported(commandId: string): boolean;\\n    /**\\n     * Returns the current value of the document, range, or current selection for the given command.\\n     * @param commandId String that specifies a command identifier.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/queryCommandValue)\\n     */\\n    queryCommandValue(commandId: string): string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/releaseEvents)\\n     */\\n    releaseEvents(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/requestStorageAccess) */\\n    requestStorageAccess(): Promise<void>;\\n    /**\\n     * Writes one or more HTML expressions to a document in the specified window.\\n     * @param content Specifies the text and HTML tags to write.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/write)\\n     */\\n    write(...text: string[]): void;\\n    /**\\n     * Writes one or more HTML expressions, followed by a carriage return, to a document in the specified window.\\n     * @param content The text and HTML tags to write.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/writeln)\\n     */\\n    writeln(...text: string[]): void;\\n    addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Document: {\\n    prototype: Document;\\n    new(): Document;\\n};\\n\\n/**\\n * A minimal document object that has no parent. It is used as a lightweight version of Document that stores a segment of a document structure comprised of nodes just like a standard document. The key difference is that because the document fragment isn't part of the active document tree structure, changes made to the fragment don't affect the document, cause reflow, or incur any performance impact that can occur when changes are made.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentFragment)\\n */\\ninterface DocumentFragment extends Node, NonElementParentNode, ParentNode {\\n    readonly ownerDocument: Document;\\n    getElementById(elementId: string): HTMLElement | null;\\n}\\n\\ndeclare var DocumentFragment: {\\n    prototype: DocumentFragment;\\n    new(): DocumentFragment;\\n};\\n\\ninterface DocumentOrShadowRoot {\\n    /**\\n     * Returns the deepest element in the document through which or to which key events are being routed. This is, roughly speaking, the focused element in the document.\\n     *\\n     * For the purposes of this API, when a child browsing context is focused, its container is focused in the parent browsing context. For example, if the user moves the focus to a text control in an iframe, the iframe is the element returned by the activeElement API in the iframe's node document.\\n     *\\n     * Similarly, when the focused element is in a different node tree than documentOrShadowRoot, the element returned will be the host that's located in the same node tree as documentOrShadowRoot if documentOrShadowRoot is a shadow-including inclusive ancestor of the focused element, and null if not.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/activeElement)\\n     */\\n    readonly activeElement: Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/adoptedStyleSheets) */\\n    adoptedStyleSheets: CSSStyleSheet[];\\n    /**\\n     * Returns document's fullscreen element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fullscreenElement)\\n     */\\n    readonly fullscreenElement: Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/pictureInPictureElement) */\\n    readonly pictureInPictureElement: Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/pointerLockElement) */\\n    readonly pointerLockElement: Element | null;\\n    /**\\n     * Retrieves a collection of styleSheet objects representing the style sheets that correspond to each instance of a link or style object in the document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/styleSheets)\\n     */\\n    readonly styleSheets: StyleSheetList;\\n    /**\\n     * Returns the element for the specified x coordinate and the specified y coordinate.\\n     * @param x The x-offset\\n     * @param y The y-offset\\n     */\\n    elementFromPoint(x: number, y: number): Element | null;\\n    elementsFromPoint(x: number, y: number): Element[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/getAnimations) */\\n    getAnimations(): Animation[];\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentTimeline) */\\ninterface DocumentTimeline extends AnimationTimeline {\\n}\\n\\ndeclare var DocumentTimeline: {\\n    prototype: DocumentTimeline;\\n    new(options?: DocumentTimelineOptions): DocumentTimeline;\\n};\\n\\n/**\\n * A Node containing a doctype.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType)\\n */\\ninterface DocumentType extends Node, ChildNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/name) */\\n    readonly name: string;\\n    readonly ownerDocument: Document;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/publicId) */\\n    readonly publicId: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DocumentType/systemId) */\\n    readonly systemId: string;\\n}\\n\\ndeclare var DocumentType: {\\n    prototype: DocumentType;\\n    new(): DocumentType;\\n};\\n\\n/**\\n * A DOM event that represents a drag and drop interaction. The user initiates a drag by placing a pointer device (such as a mouse) on the touch surface and then dragging the pointer to a new location (such as another DOM element). Applications are free to interpret a drag and drop interaction in an application-specific way.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DragEvent)\\n */\\ninterface DragEvent extends MouseEvent {\\n    /**\\n     * Returns the DataTransfer object for the event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DragEvent/dataTransfer)\\n     */\\n    readonly dataTransfer: DataTransfer | null;\\n}\\n\\ndeclare var DragEvent: {\\n    prototype: DragEvent;\\n    new(type: string, eventInitDict?: DragEventInit): DragEvent;\\n};\\n\\n/**\\n * Inherits properties from its parent, AudioNode.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DynamicsCompressorNode)\\n */\\ninterface DynamicsCompressorNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DynamicsCompressorNode/attack) */\\n    readonly attack: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DynamicsCompressorNode/knee) */\\n    readonly knee: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DynamicsCompressorNode/ratio) */\\n    readonly ratio: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DynamicsCompressorNode/reduction) */\\n    readonly reduction: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DynamicsCompressorNode/release) */\\n    readonly release: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DynamicsCompressorNode/threshold) */\\n    readonly threshold: AudioParam;\\n}\\n\\ndeclare var DynamicsCompressorNode: {\\n    prototype: DynamicsCompressorNode;\\n    new(context: BaseAudioContext, options?: DynamicsCompressorOptions): DynamicsCompressorNode;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_blend_minmax) */\\ninterface EXT_blend_minmax {\\n    readonly MIN_EXT: 0x8007;\\n    readonly MAX_EXT: 0x8008;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_color_buffer_float) */\\ninterface EXT_color_buffer_float {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_color_buffer_half_float) */\\ninterface EXT_color_buffer_half_float {\\n    readonly RGBA16F_EXT: 0x881A;\\n    readonly RGB16F_EXT: 0x881B;\\n    readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211;\\n    readonly UNSIGNED_NORMALIZED_EXT: 0x8C17;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_float_blend) */\\ninterface EXT_float_blend {\\n}\\n\\n/**\\n * The EXT_frag_depth extension is part of the WebGL API and enables to set a depth value of a fragment from within the fragment shader.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_frag_depth)\\n */\\ninterface EXT_frag_depth {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_sRGB) */\\ninterface EXT_sRGB {\\n    readonly SRGB_EXT: 0x8C40;\\n    readonly SRGB_ALPHA_EXT: 0x8C42;\\n    readonly SRGB8_ALPHA8_EXT: 0x8C43;\\n    readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: 0x8210;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_shader_texture_lod) */\\ninterface EXT_shader_texture_lod {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_texture_compression_bptc) */\\ninterface EXT_texture_compression_bptc {\\n    readonly COMPRESSED_RGBA_BPTC_UNORM_EXT: 0x8E8C;\\n    readonly COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: 0x8E8D;\\n    readonly COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: 0x8E8E;\\n    readonly COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: 0x8E8F;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_texture_compression_rgtc) */\\ninterface EXT_texture_compression_rgtc {\\n    readonly COMPRESSED_RED_RGTC1_EXT: 0x8DBB;\\n    readonly COMPRESSED_SIGNED_RED_RGTC1_EXT: 0x8DBC;\\n    readonly COMPRESSED_RED_GREEN_RGTC2_EXT: 0x8DBD;\\n    readonly COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: 0x8DBE;\\n}\\n\\n/**\\n * The EXT_texture_filter_anisotropic extension is part of the WebGL API and exposes two constants for anisotropic filtering (AF).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_texture_filter_anisotropic)\\n */\\ninterface EXT_texture_filter_anisotropic {\\n    readonly TEXTURE_MAX_ANISOTROPY_EXT: 0x84FE;\\n    readonly MAX_TEXTURE_MAX_ANISOTROPY_EXT: 0x84FF;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_texture_norm16) */\\ninterface EXT_texture_norm16 {\\n    readonly R16_EXT: 0x822A;\\n    readonly RG16_EXT: 0x822C;\\n    readonly RGB16_EXT: 0x8054;\\n    readonly RGBA16_EXT: 0x805B;\\n    readonly R16_SNORM_EXT: 0x8F98;\\n    readonly RG16_SNORM_EXT: 0x8F99;\\n    readonly RGB16_SNORM_EXT: 0x8F9A;\\n    readonly RGBA16_SNORM_EXT: 0x8F9B;\\n}\\n\\ninterface ElementEventMap {\\n    \\\"fullscreenchange\\\": Event;\\n    \\\"fullscreenerror\\\": Event;\\n}\\n\\n/**\\n * Element is the most general base class from which all objects in a Document inherit. It only has methods and properties common to all kinds of elements. More specific classes inherit from Element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element)\\n */\\ninterface Element extends Node, ARIAMixin, Animatable, ChildNode, InnerHTML, NonDocumentTypeChildNode, ParentNode, Slottable {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/attributes) */\\n    readonly attributes: NamedNodeMap;\\n    /**\\n     * Allows for manipulation of element's class content attribute as a set of whitespace-separated tokens through a DOMTokenList object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/classList)\\n     */\\n    readonly classList: DOMTokenList;\\n    /**\\n     * Returns the value of element's class content attribute. Can be set to change it.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/className)\\n     */\\n    className: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/clientHeight) */\\n    readonly clientHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/clientLeft) */\\n    readonly clientLeft: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/clientTop) */\\n    readonly clientTop: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/clientWidth) */\\n    readonly clientWidth: number;\\n    /**\\n     * Returns the value of element's id content attribute. Can be set to change it.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/id)\\n     */\\n    id: string;\\n    /**\\n     * Returns the local name.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/localName)\\n     */\\n    readonly localName: string;\\n    /**\\n     * Returns the namespace.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/namespaceURI)\\n     */\\n    readonly namespaceURI: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/fullscreenchange_event) */\\n    onfullscreenchange: ((this: Element, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/fullscreenerror_event) */\\n    onfullscreenerror: ((this: Element, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/outerHTML) */\\n    outerHTML: string;\\n    readonly ownerDocument: Document;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/part) */\\n    readonly part: DOMTokenList;\\n    /**\\n     * Returns the namespace prefix.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/prefix)\\n     */\\n    readonly prefix: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scrollHeight) */\\n    readonly scrollHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scrollLeft) */\\n    scrollLeft: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scrollTop) */\\n    scrollTop: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scrollWidth) */\\n    readonly scrollWidth: number;\\n    /**\\n     * Returns element's shadow root, if any, and if shadow root's mode is \\\"open\\\", and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/shadowRoot)\\n     */\\n    readonly shadowRoot: ShadowRoot | null;\\n    /**\\n     * Returns the value of element's slot content attribute. Can be set to change it.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/slot)\\n     */\\n    slot: string;\\n    /**\\n     * Returns the HTML-uppercased qualified name.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/tagName)\\n     */\\n    readonly tagName: string;\\n    /**\\n     * Creates a shadow root for element and returns it.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/attachShadow)\\n     */\\n    attachShadow(init: ShadowRootInit): ShadowRoot;\\n    checkVisibility(options?: CheckVisibilityOptions): boolean;\\n    /**\\n     * Returns the first (starting at element) inclusive ancestor that matches selectors, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/closest)\\n     */\\n    closest<K extends keyof HTMLElementTagNameMap>(selector: K): HTMLElementTagNameMap[K] | null;\\n    closest<K extends keyof SVGElementTagNameMap>(selector: K): SVGElementTagNameMap[K] | null;\\n    closest<K extends keyof MathMLElementTagNameMap>(selector: K): MathMLElementTagNameMap[K] | null;\\n    closest<E extends Element = Element>(selectors: string): E | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/computedStyleMap) */\\n    computedStyleMap(): StylePropertyMapReadOnly;\\n    /**\\n     * Returns element's first attribute whose qualified name is qualifiedName, and null if there is no such attribute otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttribute)\\n     */\\n    getAttribute(qualifiedName: string): string | null;\\n    /**\\n     * Returns element's attribute whose namespace is namespace and local name is localName, and null if there is no such attribute otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNS)\\n     */\\n    getAttributeNS(namespace: string | null, localName: string): string | null;\\n    /**\\n     * Returns the qualified names of all element's attributes. Can contain duplicates.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNames)\\n     */\\n    getAttributeNames(): string[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNode) */\\n    getAttributeNode(qualifiedName: string): Attr | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getAttributeNodeNS) */\\n    getAttributeNodeNS(namespace: string | null, localName: string): Attr | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getBoundingClientRect) */\\n    getBoundingClientRect(): DOMRect;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getClientRects) */\\n    getClientRects(): DOMRectList;\\n    /**\\n     * Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getElementsByClassName)\\n     */\\n    getElementsByClassName(classNames: string): HTMLCollectionOf<Element>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getElementsByTagName) */\\n    getElementsByTagName<K extends keyof HTMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementTagNameMap[K]>;\\n    getElementsByTagName<K extends keyof SVGElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<SVGElementTagNameMap[K]>;\\n    getElementsByTagName<K extends keyof MathMLElementTagNameMap>(qualifiedName: K): HTMLCollectionOf<MathMLElementTagNameMap[K]>;\\n    /** @deprecated */\\n    getElementsByTagName<K extends keyof HTMLElementDeprecatedTagNameMap>(qualifiedName: K): HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;\\n    getElementsByTagName(qualifiedName: string): HTMLCollectionOf<Element>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/getElementsByTagNameNS) */\\n    getElementsByTagNameNS(namespaceURI: \\\"http://www.w3.org/1999/xhtml\\\", localName: string): HTMLCollectionOf<HTMLElement>;\\n    getElementsByTagNameNS(namespaceURI: \\\"http://www.w3.org/2000/svg\\\", localName: string): HTMLCollectionOf<SVGElement>;\\n    getElementsByTagNameNS(namespaceURI: \\\"http://www.w3.org/1998/Math/MathML\\\", localName: string): HTMLCollectionOf<MathMLElement>;\\n    getElementsByTagNameNS(namespace: string | null, localName: string): HTMLCollectionOf<Element>;\\n    /**\\n     * Returns true if element has an attribute whose qualified name is qualifiedName, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttribute)\\n     */\\n    hasAttribute(qualifiedName: string): boolean;\\n    /**\\n     * Returns true if element has an attribute whose namespace is namespace and local name is localName.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttributeNS)\\n     */\\n    hasAttributeNS(namespace: string | null, localName: string): boolean;\\n    /**\\n     * Returns true if element has attributes, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasAttributes)\\n     */\\n    hasAttributes(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/hasPointerCapture) */\\n    hasPointerCapture(pointerId: number): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/insertAdjacentElement) */\\n    insertAdjacentElement(where: InsertPosition, element: Element): Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/insertAdjacentHTML) */\\n    insertAdjacentHTML(position: InsertPosition, text: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/insertAdjacentText) */\\n    insertAdjacentText(where: InsertPosition, data: string): void;\\n    /**\\n     * Returns true if matching selectors against element's root yields element, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/matches)\\n     */\\n    matches(selectors: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/releasePointerCapture) */\\n    releasePointerCapture(pointerId: number): void;\\n    /**\\n     * Removes element's first attribute whose qualified name is qualifiedName.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttribute)\\n     */\\n    removeAttribute(qualifiedName: string): void;\\n    /**\\n     * Removes element's attribute whose namespace is namespace and local name is localName.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttributeNS)\\n     */\\n    removeAttributeNS(namespace: string | null, localName: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/removeAttributeNode) */\\n    removeAttributeNode(attr: Attr): Attr;\\n    /**\\n     * Displays element fullscreen and resolves promise when done.\\n     *\\n     * When supplied, options's navigationUI member indicates whether showing navigation UI while in fullscreen is preferred or not. If set to \\\"show\\\", navigation simplicity is preferred over screen space, and if set to \\\"hide\\\", more screen space is preferred. User agents are always free to honor user preference over the application's. The default value \\\"auto\\\" indicates no application preference.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/requestFullscreen)\\n     */\\n    requestFullscreen(options?: FullscreenOptions): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/requestPointerLock) */\\n    requestPointerLock(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scroll) */\\n    scroll(options?: ScrollToOptions): void;\\n    scroll(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scrollBy) */\\n    scrollBy(options?: ScrollToOptions): void;\\n    scrollBy(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scrollIntoView) */\\n    scrollIntoView(arg?: boolean | ScrollIntoViewOptions): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/scrollTo) */\\n    scrollTo(options?: ScrollToOptions): void;\\n    scrollTo(x: number, y: number): void;\\n    /**\\n     * Sets the value of element's first attribute whose qualified name is qualifiedName to value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttribute)\\n     */\\n    setAttribute(qualifiedName: string, value: string): void;\\n    /**\\n     * Sets the value of element's attribute whose namespace is namespace and local name is localName to value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNS)\\n     */\\n    setAttributeNS(namespace: string | null, qualifiedName: string, value: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNode) */\\n    setAttributeNode(attr: Attr): Attr | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNodeNS) */\\n    setAttributeNodeNS(attr: Attr): Attr | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setPointerCapture) */\\n    setPointerCapture(pointerId: number): void;\\n    /**\\n     * If force is not given, \\\"toggles\\\" qualifiedName, removing it if it is present and adding it if it is not present. If force is true, adds qualifiedName. If force is false, removes qualifiedName.\\n     *\\n     * Returns true if qualifiedName is now present, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/toggleAttribute)\\n     */\\n    toggleAttribute(qualifiedName: string, force?: boolean): boolean;\\n    /**\\n     * @deprecated This is a legacy alias of `matches`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/matches)\\n     */\\n    webkitMatchesSelector(selectors: string): boolean;\\n    addEventListener<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ElementEventMap>(type: K, listener: (this: Element, ev: ElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Element: {\\n    prototype: Element;\\n    new(): Element;\\n};\\n\\ninterface ElementCSSInlineStyle {\\n    readonly attributeStyleMap: StylePropertyMap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/style) */\\n    readonly style: CSSStyleDeclaration;\\n}\\n\\ninterface ElementContentEditable {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/contentEditable) */\\n    contentEditable: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/enterKeyHint) */\\n    enterKeyHint: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/inputMode) */\\n    inputMode: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/isContentEditable) */\\n    readonly isContentEditable: boolean;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals) */\\ninterface ElementInternals extends ARIAMixin {\\n    /**\\n     * Returns the form owner of internals's target element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/form)\\n     */\\n    readonly form: HTMLFormElement | null;\\n    /**\\n     * Returns a NodeList of all the label elements that internals's target element is associated with.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/labels)\\n     */\\n    readonly labels: NodeList;\\n    /**\\n     * Returns the ShadowRoot for internals's target element, if the target element is a shadow host, or null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/shadowRoot)\\n     */\\n    readonly shadowRoot: ShadowRoot | null;\\n    /**\\n     * Returns the error message that would be shown to the user if internals's target element was to be checked for validity.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/validationMessage)\\n     */\\n    readonly validationMessage: string;\\n    /**\\n     * Returns the ValidityState object for internals's target element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/validity)\\n     */\\n    readonly validity: ValidityState;\\n    /**\\n     * Returns true if internals's target element will be validated when the form is submitted; false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/willValidate)\\n     */\\n    readonly willValidate: boolean;\\n    /**\\n     * Returns true if internals's target element has no validity problems; false otherwise. Fires an invalid event at the element in the latter case.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/checkValidity)\\n     */\\n    checkValidity(): boolean;\\n    /**\\n     * Returns true if internals's target element has no validity problems; otherwise, returns false, fires an invalid event at the element, and (if the event isn't canceled) reports the problem to the user.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/reportValidity)\\n     */\\n    reportValidity(): boolean;\\n    /**\\n     * Sets both the state and submission value of internals's target element to value.\\n     *\\n     * If value is null, the element won't participate in form submission.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/setFormValue)\\n     */\\n    setFormValue(value: File | string | FormData | null, state?: File | string | FormData | null): void;\\n    /**\\n     * Marks internals's target element as suffering from the constraints indicated by the flags argument, and sets the element's validation message to message. If anchor is specified, the user agent might use it to indicate problems with the constraints of internals's target element when the form owner is validated interactively or reportValidity() is called.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/setValidity)\\n     */\\n    setValidity(flags?: ValidityStateFlags, message?: string, anchor?: HTMLElement): void;\\n}\\n\\ndeclare var ElementInternals: {\\n    prototype: ElementInternals;\\n    new(): ElementInternals;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk) */\\ninterface EncodedVideoChunk {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/byteLength) */\\n    readonly byteLength: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/duration) */\\n    readonly duration: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/timestamp) */\\n    readonly timestamp: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/type) */\\n    readonly type: EncodedVideoChunkType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/copyTo) */\\n    copyTo(destination: BufferSource): void;\\n}\\n\\ndeclare var EncodedVideoChunk: {\\n    prototype: EncodedVideoChunk;\\n    new(init: EncodedVideoChunkInit): EncodedVideoChunk;\\n};\\n\\n/**\\n * Events providing information related to errors in scripts or in files.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent)\\n */\\ninterface ErrorEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/colno) */\\n    readonly colno: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/error) */\\n    readonly error: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/filename) */\\n    readonly filename: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/lineno) */\\n    readonly lineno: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/message) */\\n    readonly message: string;\\n}\\n\\ndeclare var ErrorEvent: {\\n    prototype: ErrorEvent;\\n    new(type: string, eventInitDict?: ErrorEventInit): ErrorEvent;\\n};\\n\\n/**\\n * An event which takes place in the DOM.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event)\\n */\\ninterface Event {\\n    /**\\n     * Returns true or false depending on how event was initialized. True if event goes through its target's ancestors in reverse tree order, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/bubbles)\\n     */\\n    readonly bubbles: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/cancelBubble)\\n     */\\n    cancelBubble: boolean;\\n    /**\\n     * Returns true or false depending on how event was initialized. Its return value does not always carry meaning, but true can indicate that part of the operation during which event was dispatched, can be canceled by invoking the preventDefault() method.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/cancelable)\\n     */\\n    readonly cancelable: boolean;\\n    /**\\n     * Returns true or false depending on how event was initialized. True if event invokes listeners past a ShadowRoot node that is the root of its target, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/composed)\\n     */\\n    readonly composed: boolean;\\n    /**\\n     * Returns the object whose event listener's callback is currently being invoked.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/currentTarget)\\n     */\\n    readonly currentTarget: EventTarget | null;\\n    /**\\n     * Returns true if preventDefault() was invoked successfully to indicate cancelation, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/defaultPrevented)\\n     */\\n    readonly defaultPrevented: boolean;\\n    /**\\n     * Returns the event's phase, which is one of NONE, CAPTURING_PHASE, AT_TARGET, and BUBBLING_PHASE.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/eventPhase)\\n     */\\n    readonly eventPhase: number;\\n    /**\\n     * Returns true if event was dispatched by the user agent, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/isTrusted)\\n     */\\n    readonly isTrusted: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/returnValue)\\n     */\\n    returnValue: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/srcElement)\\n     */\\n    readonly srcElement: EventTarget | null;\\n    /**\\n     * Returns the object to which event is dispatched (its target).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/target)\\n     */\\n    readonly target: EventTarget | null;\\n    /**\\n     * Returns the event's timestamp as the number of milliseconds measured relative to the time origin.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/timeStamp)\\n     */\\n    readonly timeStamp: DOMHighResTimeStamp;\\n    /**\\n     * Returns the type of event, e.g. \\\"click\\\", \\\"hashchange\\\", or \\\"submit\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/type)\\n     */\\n    readonly type: string;\\n    /**\\n     * Returns the invocation target objects of event's path (objects on which listeners will be invoked), except for any nodes in shadow trees of which the shadow root's mode is \\\"closed\\\" that are not reachable from event's currentTarget.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/composedPath)\\n     */\\n    composedPath(): EventTarget[];\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/initEvent)\\n     */\\n    initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void;\\n    /**\\n     * If invoked when the cancelable attribute value is true, and while executing a listener for the event with passive set to false, signals to the operation that caused event to be dispatched that it needs to be canceled.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/preventDefault)\\n     */\\n    preventDefault(): void;\\n    /**\\n     * Invoking this method prevents event from reaching any registered event listeners after the current one finishes running and, when dispatched in a tree, also prevents event from reaching any other objects.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/stopImmediatePropagation)\\n     */\\n    stopImmediatePropagation(): void;\\n    /**\\n     * When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/stopPropagation)\\n     */\\n    stopPropagation(): void;\\n    readonly NONE: 0;\\n    readonly CAPTURING_PHASE: 1;\\n    readonly AT_TARGET: 2;\\n    readonly BUBBLING_PHASE: 3;\\n}\\n\\ndeclare var Event: {\\n    prototype: Event;\\n    new(type: string, eventInitDict?: EventInit): Event;\\n    readonly NONE: 0;\\n    readonly CAPTURING_PHASE: 1;\\n    readonly AT_TARGET: 2;\\n    readonly BUBBLING_PHASE: 3;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventCounts) */\\ninterface EventCounts {\\n    forEach(callbackfn: (value: number, key: string, parent: EventCounts) => void, thisArg?: any): void;\\n}\\n\\ndeclare var EventCounts: {\\n    prototype: EventCounts;\\n    new(): EventCounts;\\n};\\n\\ninterface EventListener {\\n    (evt: Event): void;\\n}\\n\\ninterface EventListenerObject {\\n    handleEvent(object: Event): void;\\n}\\n\\ninterface EventSourceEventMap {\\n    \\\"error\\\": Event;\\n    \\\"message\\\": MessageEvent;\\n    \\\"open\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource) */\\ninterface EventSource extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */\\n    onerror: ((this: EventSource, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */\\n    onmessage: ((this: EventSource, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */\\n    onopen: ((this: EventSource, ev: Event) => any) | null;\\n    /**\\n     * Returns the state of this EventSource object's connection. It can have the values described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)\\n     */\\n    readonly readyState: number;\\n    /**\\n     * Returns the URL providing the event stream.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)\\n     */\\n    readonly url: string;\\n    /**\\n     * Returns true if the credentials mode for connection requests to the URL providing the event stream is set to \\\"include\\\", and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)\\n     */\\n    readonly withCredentials: boolean;\\n    /**\\n     * Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)\\n     */\\n    close(): void;\\n    readonly CONNECTING: 0;\\n    readonly OPEN: 1;\\n    readonly CLOSED: 2;\\n    addEventListener<K extends keyof EventSourceEventMap>(type: K, listener: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: (this: EventSource, event: MessageEvent) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof EventSourceEventMap>(type: K, listener: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: (this: EventSource, event: MessageEvent) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var EventSource: {\\n    prototype: EventSource;\\n    new(url: string | URL, eventSourceInitDict?: EventSourceInit): EventSource;\\n    readonly CONNECTING: 0;\\n    readonly OPEN: 1;\\n    readonly CLOSED: 2;\\n};\\n\\n/**\\n * EventTarget is a DOM interface implemented by objects that can receive events and may have listeners for them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget)\\n */\\ninterface EventTarget {\\n    /**\\n     * Appends an event listener for events whose type attribute value is type. The callback argument sets the callback that will be invoked when the event is dispatched.\\n     *\\n     * The options argument sets listener-specific options. For compatibility this can be a boolean, in which case the method behaves exactly as if the value was specified as options's capture.\\n     *\\n     * When set to true, options's capture prevents callback from being invoked when the event's eventPhase attribute value is BUBBLING_PHASE. When false (or not present), callback will not be invoked when event's eventPhase attribute value is CAPTURING_PHASE. Either way, callback will be invoked if event's eventPhase attribute value is AT_TARGET.\\n     *\\n     * When set to true, options's passive indicates that the callback will not cancel the event by invoking preventDefault(). This is used to enable performance optimizations described in § 2.8 Observing event listeners.\\n     *\\n     * When set to true, options's once indicates that the callback will only be invoked once after which the event listener will be removed.\\n     *\\n     * If an AbortSignal is passed for options's signal, then the event listener will be removed when signal is aborted.\\n     *\\n     * The event listener is appended to target's event listener list and is not appended if it has the same type, callback, and capture.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)\\n     */\\n    addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void;\\n    /**\\n     * Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/dispatchEvent)\\n     */\\n    dispatchEvent(event: Event): boolean;\\n    /**\\n     * Removes the event listener in target's event listener list with the same type, callback, and options.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/removeEventListener)\\n     */\\n    removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;\\n}\\n\\ndeclare var EventTarget: {\\n    prototype: EventTarget;\\n    new(): EventTarget;\\n};\\n\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/External)\\n */\\ninterface External {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/External/AddSearchProvider)\\n     */\\n    AddSearchProvider(): void;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/External/IsSearchProviderInstalled)\\n     */\\n    IsSearchProviderInstalled(): void;\\n}\\n\\n/** @deprecated */\\ndeclare var External: {\\n    prototype: External;\\n    new(): External;\\n};\\n\\n/**\\n * Provides information about files and allows JavaScript in a web page to access their content.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/File)\\n */\\ninterface File extends Blob {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */\\n    readonly lastModified: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/webkitRelativePath) */\\n    readonly webkitRelativePath: string;\\n}\\n\\ndeclare var File: {\\n    prototype: File;\\n    new(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): File;\\n};\\n\\n/**\\n * An object of this type is returned by the files property of the HTML <input> element; this lets you access the list of files selected with the <input type=\\\"file\\\"> element. It's also used for a list of files dropped into web content when using the drag and drop API; see the DataTransfer object for details on this usage.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileList)\\n */\\ninterface FileList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileList/item) */\\n    item(index: number): File | null;\\n    [index: number]: File;\\n}\\n\\ndeclare var FileList: {\\n    prototype: FileList;\\n    new(): FileList;\\n};\\n\\ninterface FileReaderEventMap {\\n    \\\"abort\\\": ProgressEvent<FileReader>;\\n    \\\"error\\\": ProgressEvent<FileReader>;\\n    \\\"load\\\": ProgressEvent<FileReader>;\\n    \\\"loadend\\\": ProgressEvent<FileReader>;\\n    \\\"loadstart\\\": ProgressEvent<FileReader>;\\n    \\\"progress\\\": ProgressEvent<FileReader>;\\n}\\n\\n/**\\n * Lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using File or Blob objects to specify the file or data to read.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader)\\n */\\ninterface FileReader extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/error) */\\n    readonly error: DOMException | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/abort_event) */\\n    onabort: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/error_event) */\\n    onerror: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/load_event) */\\n    onload: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/loadend_event) */\\n    onloadend: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/loadstart_event) */\\n    onloadstart: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/progress_event) */\\n    onprogress: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readyState) */\\n    readonly readyState: typeof FileReader.EMPTY | typeof FileReader.LOADING | typeof FileReader.DONE;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/result) */\\n    readonly result: string | ArrayBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/abort) */\\n    abort(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readAsArrayBuffer) */\\n    readAsArrayBuffer(blob: Blob): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readAsBinaryString) */\\n    readAsBinaryString(blob: Blob): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readAsDataURL) */\\n    readAsDataURL(blob: Blob): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readAsText) */\\n    readAsText(blob: Blob, encoding?: string): void;\\n    readonly EMPTY: 0;\\n    readonly LOADING: 1;\\n    readonly DONE: 2;\\n    addEventListener<K extends keyof FileReaderEventMap>(type: K, listener: (this: FileReader, ev: FileReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof FileReaderEventMap>(type: K, listener: (this: FileReader, ev: FileReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var FileReader: {\\n    prototype: FileReader;\\n    new(): FileReader;\\n    readonly EMPTY: 0;\\n    readonly LOADING: 1;\\n    readonly DONE: 2;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystem) */\\ninterface FileSystem {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystem/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystem/root) */\\n    readonly root: FileSystemDirectoryEntry;\\n}\\n\\ndeclare var FileSystem: {\\n    prototype: FileSystem;\\n    new(): FileSystem;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryEntry) */\\ninterface FileSystemDirectoryEntry extends FileSystemEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryEntry/createReader) */\\n    createReader(): FileSystemDirectoryReader;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryEntry/getDirectory) */\\n    getDirectory(path?: string | null, options?: FileSystemFlags, successCallback?: FileSystemEntryCallback, errorCallback?: ErrorCallback): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryEntry/getFile) */\\n    getFile(path?: string | null, options?: FileSystemFlags, successCallback?: FileSystemEntryCallback, errorCallback?: ErrorCallback): void;\\n}\\n\\ndeclare var FileSystemDirectoryEntry: {\\n    prototype: FileSystemDirectoryEntry;\\n    new(): FileSystemDirectoryEntry;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle)\\n */\\ninterface FileSystemDirectoryHandle extends FileSystemHandle {\\n    readonly kind: \\\"directory\\\";\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle/getDirectoryHandle) */\\n    getDirectoryHandle(name: string, options?: FileSystemGetDirectoryOptions): Promise<FileSystemDirectoryHandle>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle/getFileHandle) */\\n    getFileHandle(name: string, options?: FileSystemGetFileOptions): Promise<FileSystemFileHandle>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle/removeEntry) */\\n    removeEntry(name: string, options?: FileSystemRemoveOptions): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle/resolve) */\\n    resolve(possibleDescendant: FileSystemHandle): Promise<string[] | null>;\\n}\\n\\ndeclare var FileSystemDirectoryHandle: {\\n    prototype: FileSystemDirectoryHandle;\\n    new(): FileSystemDirectoryHandle;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryReader) */\\ninterface FileSystemDirectoryReader {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryReader/readEntries) */\\n    readEntries(successCallback: FileSystemEntriesCallback, errorCallback?: ErrorCallback): void;\\n}\\n\\ndeclare var FileSystemDirectoryReader: {\\n    prototype: FileSystemDirectoryReader;\\n    new(): FileSystemDirectoryReader;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemEntry) */\\ninterface FileSystemEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemEntry/filesystem) */\\n    readonly filesystem: FileSystem;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemEntry/fullPath) */\\n    readonly fullPath: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemEntry/isDirectory) */\\n    readonly isDirectory: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemEntry/isFile) */\\n    readonly isFile: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemEntry/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemEntry/getParent) */\\n    getParent(successCallback?: FileSystemEntryCallback, errorCallback?: ErrorCallback): void;\\n}\\n\\ndeclare var FileSystemEntry: {\\n    prototype: FileSystemEntry;\\n    new(): FileSystemEntry;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileEntry) */\\ninterface FileSystemFileEntry extends FileSystemEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileEntry/file) */\\n    file(successCallback: FileCallback, errorCallback?: ErrorCallback): void;\\n}\\n\\ndeclare var FileSystemFileEntry: {\\n    prototype: FileSystemFileEntry;\\n    new(): FileSystemFileEntry;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle)\\n */\\ninterface FileSystemFileHandle extends FileSystemHandle {\\n    readonly kind: \\\"file\\\";\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/createWritable) */\\n    createWritable(options?: FileSystemCreateWritableOptions): Promise<FileSystemWritableFileStream>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/getFile) */\\n    getFile(): Promise<File>;\\n}\\n\\ndeclare var FileSystemFileHandle: {\\n    prototype: FileSystemFileHandle;\\n    new(): FileSystemFileHandle;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemHandle)\\n */\\ninterface FileSystemHandle {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/kind) */\\n    readonly kind: FileSystemHandleKind;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/isSameEntry) */\\n    isSameEntry(other: FileSystemHandle): Promise<boolean>;\\n}\\n\\ndeclare var FileSystemHandle: {\\n    prototype: FileSystemHandle;\\n    new(): FileSystemHandle;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemWritableFileStream)\\n */\\ninterface FileSystemWritableFileStream extends WritableStream {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemWritableFileStream/seek) */\\n    seek(position: number): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemWritableFileStream/truncate) */\\n    truncate(size: number): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemWritableFileStream/write) */\\n    write(data: FileSystemWriteChunkType): Promise<void>;\\n}\\n\\ndeclare var FileSystemWritableFileStream: {\\n    prototype: FileSystemWritableFileStream;\\n    new(): FileSystemWritableFileStream;\\n};\\n\\n/**\\n * Focus-related events like focus, blur, focusin, or focusout.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FocusEvent)\\n */\\ninterface FocusEvent extends UIEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FocusEvent/relatedTarget) */\\n    readonly relatedTarget: EventTarget | null;\\n}\\n\\ndeclare var FocusEvent: {\\n    prototype: FocusEvent;\\n    new(type: string, eventInitDict?: FocusEventInit): FocusEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace) */\\ninterface FontFace {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/ascentOverride) */\\n    ascentOverride: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/descentOverride) */\\n    descentOverride: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/display) */\\n    display: FontDisplay;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/family) */\\n    family: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/featureSettings) */\\n    featureSettings: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/lineGapOverride) */\\n    lineGapOverride: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/loaded) */\\n    readonly loaded: Promise<FontFace>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/status) */\\n    readonly status: FontFaceLoadStatus;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/stretch) */\\n    stretch: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/style) */\\n    style: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/unicodeRange) */\\n    unicodeRange: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/variant) */\\n    variant: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/weight) */\\n    weight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/load) */\\n    load(): Promise<FontFace>;\\n}\\n\\ndeclare var FontFace: {\\n    prototype: FontFace;\\n    new(family: string, source: string | BinaryData, descriptors?: FontFaceDescriptors): FontFace;\\n};\\n\\ninterface FontFaceSetEventMap {\\n    \\\"loading\\\": Event;\\n    \\\"loadingdone\\\": Event;\\n    \\\"loadingerror\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet) */\\ninterface FontFaceSet extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/loading_event) */\\n    onloading: ((this: FontFaceSet, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/loadingdone_event) */\\n    onloadingdone: ((this: FontFaceSet, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/loadingerror_event) */\\n    onloadingerror: ((this: FontFaceSet, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/ready) */\\n    readonly ready: Promise<FontFaceSet>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/status) */\\n    readonly status: FontFaceSetLoadStatus;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/check) */\\n    check(font: string, text?: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/load) */\\n    load(font: string, text?: string): Promise<FontFace[]>;\\n    forEach(callbackfn: (value: FontFace, key: FontFace, parent: FontFaceSet) => void, thisArg?: any): void;\\n    addEventListener<K extends keyof FontFaceSetEventMap>(type: K, listener: (this: FontFaceSet, ev: FontFaceSetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof FontFaceSetEventMap>(type: K, listener: (this: FontFaceSet, ev: FontFaceSetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var FontFaceSet: {\\n    prototype: FontFaceSet;\\n    new(initialFaces: FontFace[]): FontFaceSet;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSetLoadEvent) */\\ninterface FontFaceSetLoadEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSetLoadEvent/fontfaces) */\\n    readonly fontfaces: ReadonlyArray<FontFace>;\\n}\\n\\ndeclare var FontFaceSetLoadEvent: {\\n    prototype: FontFaceSetLoadEvent;\\n    new(type: string, eventInitDict?: FontFaceSetLoadEventInit): FontFaceSetLoadEvent;\\n};\\n\\ninterface FontFaceSource {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fonts) */\\n    readonly fonts: FontFaceSet;\\n}\\n\\n/**\\n * Provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to \\\"multipart/form-data\\\".\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData)\\n */\\ninterface FormData {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/append) */\\n    append(name: string, value: string | Blob): void;\\n    append(name: string, value: string): void;\\n    append(name: string, blobValue: Blob, filename?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/delete) */\\n    delete(name: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/get) */\\n    get(name: string): FormDataEntryValue | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/getAll) */\\n    getAll(name: string): FormDataEntryValue[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/has) */\\n    has(name: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/set) */\\n    set(name: string, value: string | Blob): void;\\n    set(name: string, value: string): void;\\n    set(name: string, blobValue: Blob, filename?: string): void;\\n    forEach(callbackfn: (value: FormDataEntryValue, key: string, parent: FormData) => void, thisArg?: any): void;\\n}\\n\\ndeclare var FormData: {\\n    prototype: FormData;\\n    new(form?: HTMLFormElement, submitter?: HTMLElement | null): FormData;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormDataEvent) */\\ninterface FormDataEvent extends Event {\\n    /**\\n     * Returns a FormData object representing names and values of elements associated to the target form. Operations on the FormData object will affect form data to be submitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormDataEvent/formData)\\n     */\\n    readonly formData: FormData;\\n}\\n\\ndeclare var FormDataEvent: {\\n    prototype: FormDataEvent;\\n    new(type: string, eventInitDict: FormDataEventInit): FormDataEvent;\\n};\\n\\n/**\\n * A change in volume. It is an AudioNode audio-processing module that causes a given gain to be applied to the input data before its propagation to the output. A GainNode always has exactly one input and one output, both with the same number of channels.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/GainNode)\\n */\\ninterface GainNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GainNode/gain) */\\n    readonly gain: AudioParam;\\n}\\n\\ndeclare var GainNode: {\\n    prototype: GainNode;\\n    new(context: BaseAudioContext, options?: GainOptions): GainNode;\\n};\\n\\n/**\\n * This Gamepad API interface defines an individual gamepad or other controller, allowing access to information such as button presses, axis positions, and id.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad)\\n */\\ninterface Gamepad {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/axes) */\\n    readonly axes: ReadonlyArray<number>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/buttons) */\\n    readonly buttons: ReadonlyArray<GamepadButton>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/connected) */\\n    readonly connected: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/hapticActuators) */\\n    readonly hapticActuators: ReadonlyArray<GamepadHapticActuator>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/id) */\\n    readonly id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/index) */\\n    readonly index: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/mapping) */\\n    readonly mapping: GamepadMappingType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/timestamp) */\\n    readonly timestamp: DOMHighResTimeStamp;\\n    readonly vibrationActuator: GamepadHapticActuator | null;\\n}\\n\\ndeclare var Gamepad: {\\n    prototype: Gamepad;\\n    new(): Gamepad;\\n};\\n\\n/**\\n * An individual button of a gamepad or other controller, allowing access to the current state of different types of buttons available on the control device.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadButton)\\n */\\ninterface GamepadButton {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadButton/pressed) */\\n    readonly pressed: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadButton/touched) */\\n    readonly touched: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadButton/value) */\\n    readonly value: number;\\n}\\n\\ndeclare var GamepadButton: {\\n    prototype: GamepadButton;\\n    new(): GamepadButton;\\n};\\n\\n/**\\n * This Gamepad API interface contains references to gamepads connected to the system, which is what the gamepad events Window.gamepadconnected and Window.gamepaddisconnected are fired in response to.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadEvent)\\n */\\ninterface GamepadEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadEvent/gamepad) */\\n    readonly gamepad: Gamepad;\\n}\\n\\ndeclare var GamepadEvent: {\\n    prototype: GamepadEvent;\\n    new(type: string, eventInitDict: GamepadEventInit): GamepadEvent;\\n};\\n\\n/**\\n * This Gamepad API interface represents hardware in the controller designed to provide haptic feedback to the user (if available), most commonly vibration hardware.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadHapticActuator)\\n */\\ninterface GamepadHapticActuator {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadHapticActuator/type) */\\n    readonly type: GamepadHapticActuatorType;\\n    playEffect(type: GamepadHapticEffectType, params?: GamepadEffectParameters): Promise<GamepadHapticsResult>;\\n    reset(): Promise<GamepadHapticsResult>;\\n}\\n\\ndeclare var GamepadHapticActuator: {\\n    prototype: GamepadHapticActuator;\\n    new(): GamepadHapticActuator;\\n};\\n\\ninterface GenericTransformStream {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompressionStream/readable) */\\n    readonly readable: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompressionStream/writable) */\\n    readonly writable: WritableStream;\\n}\\n\\n/**\\n * An object able to programmatically obtain the position of the device. It gives Web content access to the location of the device. This allows a Web site or app to offer customized results based on the user's location.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Geolocation)\\n */\\ninterface Geolocation {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Geolocation/clearWatch) */\\n    clearWatch(watchId: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Geolocation/getCurrentPosition) */\\n    getCurrentPosition(successCallback: PositionCallback, errorCallback?: PositionErrorCallback | null, options?: PositionOptions): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Geolocation/watchPosition) */\\n    watchPosition(successCallback: PositionCallback, errorCallback?: PositionErrorCallback | null, options?: PositionOptions): number;\\n}\\n\\ndeclare var Geolocation: {\\n    prototype: Geolocation;\\n    new(): Geolocation;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationCoordinates)\\n */\\ninterface GeolocationCoordinates {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationCoordinates/accuracy) */\\n    readonly accuracy: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationCoordinates/altitude) */\\n    readonly altitude: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationCoordinates/altitudeAccuracy) */\\n    readonly altitudeAccuracy: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationCoordinates/heading) */\\n    readonly heading: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationCoordinates/latitude) */\\n    readonly latitude: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationCoordinates/longitude) */\\n    readonly longitude: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationCoordinates/speed) */\\n    readonly speed: number | null;\\n}\\n\\ndeclare var GeolocationCoordinates: {\\n    prototype: GeolocationCoordinates;\\n    new(): GeolocationCoordinates;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationPosition)\\n */\\ninterface GeolocationPosition {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationPosition/coords) */\\n    readonly coords: GeolocationCoordinates;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationPosition/timestamp) */\\n    readonly timestamp: EpochTimeStamp;\\n}\\n\\ndeclare var GeolocationPosition: {\\n    prototype: GeolocationPosition;\\n    new(): GeolocationPosition;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationPositionError) */\\ninterface GeolocationPositionError {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationPositionError/code) */\\n    readonly code: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GeolocationPositionError/message) */\\n    readonly message: string;\\n    readonly PERMISSION_DENIED: 1;\\n    readonly POSITION_UNAVAILABLE: 2;\\n    readonly TIMEOUT: 3;\\n}\\n\\ndeclare var GeolocationPositionError: {\\n    prototype: GeolocationPositionError;\\n    new(): GeolocationPositionError;\\n    readonly PERMISSION_DENIED: 1;\\n    readonly POSITION_UNAVAILABLE: 2;\\n    readonly TIMEOUT: 3;\\n};\\n\\ninterface GlobalEventHandlersEventMap {\\n    \\\"abort\\\": UIEvent;\\n    \\\"animationcancel\\\": AnimationEvent;\\n    \\\"animationend\\\": AnimationEvent;\\n    \\\"animationiteration\\\": AnimationEvent;\\n    \\\"animationstart\\\": AnimationEvent;\\n    \\\"auxclick\\\": MouseEvent;\\n    \\\"beforeinput\\\": InputEvent;\\n    \\\"blur\\\": FocusEvent;\\n    \\\"cancel\\\": Event;\\n    \\\"canplay\\\": Event;\\n    \\\"canplaythrough\\\": Event;\\n    \\\"change\\\": Event;\\n    \\\"click\\\": MouseEvent;\\n    \\\"close\\\": Event;\\n    \\\"compositionend\\\": CompositionEvent;\\n    \\\"compositionstart\\\": CompositionEvent;\\n    \\\"compositionupdate\\\": CompositionEvent;\\n    \\\"contextmenu\\\": MouseEvent;\\n    \\\"copy\\\": ClipboardEvent;\\n    \\\"cuechange\\\": Event;\\n    \\\"cut\\\": ClipboardEvent;\\n    \\\"dblclick\\\": MouseEvent;\\n    \\\"drag\\\": DragEvent;\\n    \\\"dragend\\\": DragEvent;\\n    \\\"dragenter\\\": DragEvent;\\n    \\\"dragleave\\\": DragEvent;\\n    \\\"dragover\\\": DragEvent;\\n    \\\"dragstart\\\": DragEvent;\\n    \\\"drop\\\": DragEvent;\\n    \\\"durationchange\\\": Event;\\n    \\\"emptied\\\": Event;\\n    \\\"ended\\\": Event;\\n    \\\"error\\\": ErrorEvent;\\n    \\\"focus\\\": FocusEvent;\\n    \\\"focusin\\\": FocusEvent;\\n    \\\"focusout\\\": FocusEvent;\\n    \\\"formdata\\\": FormDataEvent;\\n    \\\"gotpointercapture\\\": PointerEvent;\\n    \\\"input\\\": Event;\\n    \\\"invalid\\\": Event;\\n    \\\"keydown\\\": KeyboardEvent;\\n    \\\"keypress\\\": KeyboardEvent;\\n    \\\"keyup\\\": KeyboardEvent;\\n    \\\"load\\\": Event;\\n    \\\"loadeddata\\\": Event;\\n    \\\"loadedmetadata\\\": Event;\\n    \\\"loadstart\\\": Event;\\n    \\\"lostpointercapture\\\": PointerEvent;\\n    \\\"mousedown\\\": MouseEvent;\\n    \\\"mouseenter\\\": MouseEvent;\\n    \\\"mouseleave\\\": MouseEvent;\\n    \\\"mousemove\\\": MouseEvent;\\n    \\\"mouseout\\\": MouseEvent;\\n    \\\"mouseover\\\": MouseEvent;\\n    \\\"mouseup\\\": MouseEvent;\\n    \\\"paste\\\": ClipboardEvent;\\n    \\\"pause\\\": Event;\\n    \\\"play\\\": Event;\\n    \\\"playing\\\": Event;\\n    \\\"pointercancel\\\": PointerEvent;\\n    \\\"pointerdown\\\": PointerEvent;\\n    \\\"pointerenter\\\": PointerEvent;\\n    \\\"pointerleave\\\": PointerEvent;\\n    \\\"pointermove\\\": PointerEvent;\\n    \\\"pointerout\\\": PointerEvent;\\n    \\\"pointerover\\\": PointerEvent;\\n    \\\"pointerup\\\": PointerEvent;\\n    \\\"progress\\\": ProgressEvent;\\n    \\\"ratechange\\\": Event;\\n    \\\"reset\\\": Event;\\n    \\\"resize\\\": UIEvent;\\n    \\\"scroll\\\": Event;\\n    \\\"scrollend\\\": Event;\\n    \\\"securitypolicyviolation\\\": SecurityPolicyViolationEvent;\\n    \\\"seeked\\\": Event;\\n    \\\"seeking\\\": Event;\\n    \\\"select\\\": Event;\\n    \\\"selectionchange\\\": Event;\\n    \\\"selectstart\\\": Event;\\n    \\\"slotchange\\\": Event;\\n    \\\"stalled\\\": Event;\\n    \\\"submit\\\": SubmitEvent;\\n    \\\"suspend\\\": Event;\\n    \\\"timeupdate\\\": Event;\\n    \\\"toggle\\\": Event;\\n    \\\"touchcancel\\\": TouchEvent;\\n    \\\"touchend\\\": TouchEvent;\\n    \\\"touchmove\\\": TouchEvent;\\n    \\\"touchstart\\\": TouchEvent;\\n    \\\"transitioncancel\\\": TransitionEvent;\\n    \\\"transitionend\\\": TransitionEvent;\\n    \\\"transitionrun\\\": TransitionEvent;\\n    \\\"transitionstart\\\": TransitionEvent;\\n    \\\"volumechange\\\": Event;\\n    \\\"waiting\\\": Event;\\n    \\\"webkitanimationend\\\": Event;\\n    \\\"webkitanimationiteration\\\": Event;\\n    \\\"webkitanimationstart\\\": Event;\\n    \\\"webkittransitionend\\\": Event;\\n    \\\"wheel\\\": WheelEvent;\\n}\\n\\ninterface GlobalEventHandlers {\\n    /**\\n     * Fires when the user aborts the download.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/abort_event)\\n     */\\n    onabort: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationcancel_event) */\\n    onanimationcancel: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationend_event) */\\n    onanimationend: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationiteration_event) */\\n    onanimationiteration: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationstart_event) */\\n    onanimationstart: ((this: GlobalEventHandlers, ev: AnimationEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/auxclick_event) */\\n    onauxclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/beforeinput_event) */\\n    onbeforeinput: ((this: GlobalEventHandlers, ev: InputEvent) => any) | null;\\n    /**\\n     * Fires when the object loses the input focus.\\n     * @param ev The focus event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/blur_event)\\n     */\\n    onblur: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/cancel_event) */\\n    oncancel: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when playback is possible, but would require further buffering.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/canplay_event)\\n     */\\n    oncanplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/canplaythrough_event) */\\n    oncanplaythrough: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Fires when the contents of the object or selection have changed.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/change_event)\\n     */\\n    onchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Fires when the user clicks the left mouse button on the object\\n     * @param ev The mouse event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/click_event)\\n     */\\n    onclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/close_event) */\\n    onclose: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Fires when the user clicks the right mouse button in the client area, opening the context menu.\\n     * @param ev The mouse event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event)\\n     */\\n    oncontextmenu: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/copy_event) */\\n    oncopy: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/cuechange_event) */\\n    oncuechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/cut_event) */\\n    oncut: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;\\n    /**\\n     * Fires when the user double-clicks the object.\\n     * @param ev The mouse event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/dblclick_event)\\n     */\\n    ondblclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /**\\n     * Fires on the source object continuously during a drag operation.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/drag_event)\\n     */\\n    ondrag: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;\\n    /**\\n     * Fires on the source object when the user releases the mouse at the close of a drag operation.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragend_event)\\n     */\\n    ondragend: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;\\n    /**\\n     * Fires on the target element when the user drags the object to a valid drop target.\\n     * @param ev The drag event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragenter_event)\\n     */\\n    ondragenter: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;\\n    /**\\n     * Fires on the target object when the user moves the mouse out of a valid drop target during a drag operation.\\n     * @param ev The drag event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragleave_event)\\n     */\\n    ondragleave: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;\\n    /**\\n     * Fires on the target element continuously while the user drags the object over a valid drop target.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragover_event)\\n     */\\n    ondragover: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;\\n    /**\\n     * Fires on the source object when the user starts to drag a text selection or selected object.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragstart_event)\\n     */\\n    ondragstart: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/drop_event) */\\n    ondrop: ((this: GlobalEventHandlers, ev: DragEvent) => any) | null;\\n    /**\\n     * Occurs when the duration attribute is updated.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/durationchange_event)\\n     */\\n    ondurationchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when the media element is reset to its initial state.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/emptied_event)\\n     */\\n    onemptied: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when the end of playback is reached.\\n     * @param ev The event\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/ended_event)\\n     */\\n    onended: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Fires when an error occurs during object loading.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/error_event)\\n     */\\n    onerror: OnErrorEventHandler;\\n    /**\\n     * Fires when the object receives focus.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/focus_event)\\n     */\\n    onfocus: ((this: GlobalEventHandlers, ev: FocusEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/formdata_event) */\\n    onformdata: ((this: GlobalEventHandlers, ev: FormDataEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/gotpointercapture_event) */\\n    ongotpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/input_event) */\\n    oninput: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/invalid_event) */\\n    oninvalid: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Fires when the user presses a key.\\n     * @param ev The keyboard event\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/keydown_event)\\n     */\\n    onkeydown: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;\\n    /**\\n     * Fires when the user presses an alphanumeric key.\\n     * @param ev The event.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/keypress_event)\\n     */\\n    onkeypress: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;\\n    /**\\n     * Fires when the user releases a key.\\n     * @param ev The keyboard event\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/keyup_event)\\n     */\\n    onkeyup: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null;\\n    /**\\n     * Fires immediately after the browser loads the object.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement/load_event)\\n     */\\n    onload: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when media data is loaded at the current playback position.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/loadeddata_event)\\n     */\\n    onloadeddata: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when the duration and dimensions of the media have been determined.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/loadedmetadata_event)\\n     */\\n    onloadedmetadata: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when Internet Explorer begins looking for media data.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/loadstart_event)\\n     */\\n    onloadstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/lostpointercapture_event) */\\n    onlostpointercapture: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /**\\n     * Fires when the user clicks the object with either mouse button.\\n     * @param ev The mouse event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mousedown_event)\\n     */\\n    onmousedown: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseenter_event) */\\n    onmouseenter: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseleave_event) */\\n    onmouseleave: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /**\\n     * Fires when the user moves the mouse over the object.\\n     * @param ev The mouse event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mousemove_event)\\n     */\\n    onmousemove: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /**\\n     * Fires when the user moves the mouse pointer outside the boundaries of the object.\\n     * @param ev The mouse event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseout_event)\\n     */\\n    onmouseout: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /**\\n     * Fires when the user moves the mouse pointer into the object.\\n     * @param ev The mouse event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseover_event)\\n     */\\n    onmouseover: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /**\\n     * Fires when the user releases a mouse button while the mouse is over the object.\\n     * @param ev The mouse event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseup_event)\\n     */\\n    onmouseup: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/paste_event) */\\n    onpaste: ((this: GlobalEventHandlers, ev: ClipboardEvent) => any) | null;\\n    /**\\n     * Occurs when playback is paused.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/pause_event)\\n     */\\n    onpause: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when the play method is requested.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/play_event)\\n     */\\n    onplay: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when the audio or video has started playing.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/playing_event)\\n     */\\n    onplaying: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointercancel_event) */\\n    onpointercancel: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerdown_event) */\\n    onpointerdown: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerenter_event) */\\n    onpointerenter: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerleave_event) */\\n    onpointerleave: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointermove_event) */\\n    onpointermove: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerout_event) */\\n    onpointerout: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerover_event) */\\n    onpointerover: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerup_event) */\\n    onpointerup: ((this: GlobalEventHandlers, ev: PointerEvent) => any) | null;\\n    /**\\n     * Occurs to indicate progress while downloading media data.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/progress_event)\\n     */\\n    onprogress: ((this: GlobalEventHandlers, ev: ProgressEvent) => any) | null;\\n    /**\\n     * Occurs when the playback rate is increased or decreased.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/ratechange_event)\\n     */\\n    onratechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Fires when the user resets a form.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/reset_event)\\n     */\\n    onreset: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/resize_event) */\\n    onresize: ((this: GlobalEventHandlers, ev: UIEvent) => any) | null;\\n    /**\\n     * Fires when the user repositions the scroll box in the scroll bar on the object.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/scroll_event)\\n     */\\n    onscroll: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/scrollend_event) */\\n    onscrollend: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/securitypolicyviolation_event) */\\n    onsecuritypolicyviolation: ((this: GlobalEventHandlers, ev: SecurityPolicyViolationEvent) => any) | null;\\n    /**\\n     * Occurs when the seek operation ends.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/seeked_event)\\n     */\\n    onseeked: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when the current playback position is moved.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/seeking_event)\\n     */\\n    onseeking: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Fires when the current selection changes.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/select_event)\\n     */\\n    onselect: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/selectionchange_event) */\\n    onselectionchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/selectstart_event) */\\n    onselectstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSlotElement/slotchange_event) */\\n    onslotchange: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when the download has stopped.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/stalled_event)\\n     */\\n    onstalled: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/submit_event) */\\n    onsubmit: ((this: GlobalEventHandlers, ev: SubmitEvent) => any) | null;\\n    /**\\n     * Occurs if the load operation has been intentionally halted.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/suspend_event)\\n     */\\n    onsuspend: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs to indicate the current playback position.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/timeupdate_event)\\n     */\\n    ontimeupdate: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDetailsElement/toggle_event) */\\n    ontoggle: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/touchcancel_event) */\\n    ontouchcancel?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/touchend_event) */\\n    ontouchend?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/touchmove_event) */\\n    ontouchmove?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/touchstart_event) */\\n    ontouchstart?: ((this: GlobalEventHandlers, ev: TouchEvent) => any) | null | undefined;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitioncancel_event) */\\n    ontransitioncancel: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitionend_event) */\\n    ontransitionend: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitionrun_event) */\\n    ontransitionrun: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitionstart_event) */\\n    ontransitionstart: ((this: GlobalEventHandlers, ev: TransitionEvent) => any) | null;\\n    /**\\n     * Occurs when the volume is changed, or playback is muted or unmuted.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/volumechange_event)\\n     */\\n    onvolumechange: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * Occurs when playback stops because the next frame of a video resource is not available.\\n     * @param ev The event.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/waiting_event)\\n     */\\n    onwaiting: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * @deprecated This is a legacy alias of `onanimationend`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationend_event)\\n     */\\n    onwebkitanimationend: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * @deprecated This is a legacy alias of `onanimationiteration`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationiteration_event)\\n     */\\n    onwebkitanimationiteration: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * @deprecated This is a legacy alias of `onanimationstart`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationstart_event)\\n     */\\n    onwebkitanimationstart: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /**\\n     * @deprecated This is a legacy alias of `ontransitionend`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitionend_event)\\n     */\\n    onwebkittransitionend: ((this: GlobalEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/wheel_event) */\\n    onwheel: ((this: GlobalEventHandlers, ev: WheelEvent) => any) | null;\\n    addEventListener<K extends keyof GlobalEventHandlersEventMap>(type: K, listener: (this: GlobalEventHandlers, ev: GlobalEventHandlersEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof GlobalEventHandlersEventMap>(type: K, listener: (this: GlobalEventHandlers, ev: GlobalEventHandlersEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAllCollection) */\\ninterface HTMLAllCollection {\\n    /**\\n     * Returns the number of elements in the collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAllCollection/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the item with index index from the collection (determined by tree order).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAllCollection/item)\\n     */\\n    item(nameOrIndex?: string): HTMLCollection | Element | null;\\n    /**\\n     * Returns the item with ID or name name from the collection.\\n     *\\n     * If there are multiple matching items, then an HTMLCollection object containing all those elements is returned.\\n     *\\n     * Only button, form, iframe, input, map, meta, object, select, and textarea elements can have a name for the purpose of this method; their name is given by the value of their name attribute.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAllCollection/namedItem)\\n     */\\n    namedItem(name: string): HTMLCollection | Element | null;\\n    [index: number]: Element;\\n}\\n\\ndeclare var HTMLAllCollection: {\\n    prototype: HTMLAllCollection;\\n    new(): HTMLAllCollection;\\n};\\n\\n/**\\n * Hyperlink elements and provides special properties and methods (beyond those of the regular HTMLElement object interface that they inherit from) for manipulating the layout and presentation of such elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement)\\n */\\ninterface HTMLAnchorElement extends HTMLElement, HTMLHyperlinkElementUtils {\\n    /**\\n     * Sets or retrieves the character set used to encode the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/charset)\\n     */\\n    charset: string;\\n    /**\\n     * Sets or retrieves the coordinates of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/coords)\\n     */\\n    coords: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/download) */\\n    download: string;\\n    /**\\n     * Sets or retrieves the language code of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/hreflang)\\n     */\\n    hreflang: string;\\n    /**\\n     * Sets or retrieves the shape of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/name)\\n     */\\n    name: string;\\n    ping: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/referrerPolicy) */\\n    referrerPolicy: string;\\n    /**\\n     * Sets or retrieves the relationship between the object and the destination of the link.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/rel)\\n     */\\n    rel: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/relList) */\\n    readonly relList: DOMTokenList;\\n    /**\\n     * Sets or retrieves the relationship between the object and the destination of the link.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/rev)\\n     */\\n    rev: string;\\n    /**\\n     * Sets or retrieves the shape of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/shape)\\n     */\\n    shape: string;\\n    /**\\n     * Sets or retrieves the window or frame at which to target content.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/target)\\n     */\\n    target: string;\\n    /**\\n     * Retrieves or sets the text of the object as a string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/text)\\n     */\\n    text: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/type) */\\n    type: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLAnchorElement: {\\n    prototype: HTMLAnchorElement;\\n    new(): HTMLAnchorElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond those of the regular object HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of <area> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement)\\n */\\ninterface HTMLAreaElement extends HTMLElement, HTMLHyperlinkElementUtils {\\n    /**\\n     * Sets or retrieves a text alternative to the graphic.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/alt)\\n     */\\n    alt: string;\\n    /**\\n     * Sets or retrieves the coordinates of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/coords)\\n     */\\n    coords: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/download) */\\n    download: string;\\n    /**\\n     * Sets or gets whether clicks in this region cause action.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/noHref)\\n     */\\n    noHref: boolean;\\n    ping: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/referrerPolicy) */\\n    referrerPolicy: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/rel) */\\n    rel: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/relList) */\\n    readonly relList: DOMTokenList;\\n    /**\\n     * Sets or retrieves the shape of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/shape)\\n     */\\n    shape: string;\\n    /**\\n     * Sets or retrieves the window or frame at which to target content.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/target)\\n     */\\n    target: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLAreaElement: {\\n    prototype: HTMLAreaElement;\\n    new(): HTMLAreaElement;\\n};\\n\\n/**\\n * Provides access to the properties of <audio> elements, as well as methods to manipulate them. It derives from the HTMLMediaElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAudioElement)\\n */\\ninterface HTMLAudioElement extends HTMLMediaElement {\\n    addEventListener<K extends keyof HTMLMediaElementEventMap>(type: K, listener: (this: HTMLAudioElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLMediaElementEventMap>(type: K, listener: (this: HTMLAudioElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLAudioElement: {\\n    prototype: HTMLAudioElement;\\n    new(): HTMLAudioElement;\\n};\\n\\n/**\\n * A HTML line break element (<br>). It inherits from HTMLElement.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBRElement)\\n */\\ninterface HTMLBRElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves the side on which floating objects are not to be positioned when any IHTMLBlockElement is inserted into the document.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBRElement/clear)\\n     */\\n    clear: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLBRElement: {\\n    prototype: HTMLBRElement;\\n    new(): HTMLBRElement;\\n};\\n\\n/**\\n * Contains the base URI for a document. This object inherits all of the properties and methods as described in the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBaseElement)\\n */\\ninterface HTMLBaseElement extends HTMLElement {\\n    /**\\n     * Gets or sets the baseline URL on which relative links are based.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBaseElement/href)\\n     */\\n    href: string;\\n    /**\\n     * Sets or retrieves the window or frame at which to target content.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBaseElement/target)\\n     */\\n    target: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLBaseElement: {\\n    prototype: HTMLBaseElement;\\n    new(): HTMLBaseElement;\\n};\\n\\ninterface HTMLBodyElementEventMap extends HTMLElementEventMap, WindowEventHandlersEventMap {\\n}\\n\\n/**\\n * Provides special properties (beyond those inherited from the regular HTMLElement interface) for manipulating <body> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBodyElement)\\n */\\ninterface HTMLBodyElement extends HTMLElement, WindowEventHandlers {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBodyElement/aLink)\\n     */\\n    aLink: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBodyElement/background)\\n     */\\n    background: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBodyElement/bgColor)\\n     */\\n    bgColor: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBodyElement/link)\\n     */\\n    link: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBodyElement/text)\\n     */\\n    text: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLBodyElement/vLink)\\n     */\\n    vLink: string;\\n    addEventListener<K extends keyof HTMLBodyElementEventMap>(type: K, listener: (this: HTMLBodyElement, ev: HTMLBodyElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLBodyElementEventMap>(type: K, listener: (this: HTMLBodyElement, ev: HTMLBodyElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLBodyElement: {\\n    prototype: HTMLBodyElement;\\n    new(): HTMLBodyElement;\\n};\\n\\n/**\\n * Provides properties and methods (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating <button> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement)\\n */\\ninterface HTMLButtonElement extends HTMLElement, PopoverInvokerElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/disabled) */\\n    disabled: boolean;\\n    /**\\n     * Retrieves a reference to the form that the object is embedded in.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/form)\\n     */\\n    readonly form: HTMLFormElement | null;\\n    /**\\n     * Overrides the action attribute (where the data on a form is sent) on the parent form element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/formAction)\\n     */\\n    formAction: string;\\n    /**\\n     * Used to override the encoding (formEnctype attribute) specified on the form element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/formEnctype)\\n     */\\n    formEnctype: string;\\n    /**\\n     * Overrides the submit method attribute previously specified on a form element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/formMethod)\\n     */\\n    formMethod: string;\\n    /**\\n     * Overrides any validation or required attributes on a form or form elements to allow it to be submitted without validation. This can be used to create a \\\"save draft\\\"-type submit option.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/formNoValidate)\\n     */\\n    formNoValidate: boolean;\\n    /**\\n     * Overrides the target attribute on a form element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/formTarget)\\n     */\\n    formTarget: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/labels) */\\n    readonly labels: NodeListOf<HTMLLabelElement>;\\n    /**\\n     * Sets or retrieves the name of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/name)\\n     */\\n    name: string;\\n    /**\\n     * Gets the classification and default behavior of the button.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/type)\\n     */\\n    type: \\\"submit\\\" | \\\"reset\\\" | \\\"button\\\";\\n    /**\\n     * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as \\\"this is a required field\\\". The result is that the user sees validation messages without actually submitting.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/validationMessage)\\n     */\\n    readonly validationMessage: string;\\n    /**\\n     * Returns a  ValidityState object that represents the validity states of an element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/validity)\\n     */\\n    readonly validity: ValidityState;\\n    /**\\n     * Sets or retrieves the default or selected value of the control.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/value)\\n     */\\n    value: string;\\n    /**\\n     * Returns whether an element will successfully validate based on forms validation rules and constraints.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/willValidate)\\n     */\\n    readonly willValidate: boolean;\\n    /** Returns whether a form will validate when it is submitted, without having to submit it. */\\n    checkValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/reportValidity) */\\n    reportValidity(): boolean;\\n    /**\\n     * Sets a custom error message that is displayed when a form is submitted.\\n     * @param error Sets a custom error message that is displayed when a form is submitted.\\n     */\\n    setCustomValidity(error: string): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLButtonElement: {\\n    prototype: HTMLButtonElement;\\n    new(): HTMLButtonElement;\\n};\\n\\n/**\\n * Provides properties and methods for manipulating the layout and presentation of <canvas> elements. The HTMLCanvasElement interface also inherits the properties and methods of the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement)\\n */\\ninterface HTMLCanvasElement extends HTMLElement {\\n    /**\\n     * Gets or sets the height of a canvas element on a document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/height)\\n     */\\n    height: number;\\n    /**\\n     * Gets or sets the width of a canvas element on a document.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/width)\\n     */\\n    width: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/captureStream) */\\n    captureStream(frameRequestRate?: number): MediaStream;\\n    /**\\n     * Returns an object that provides methods and properties for drawing and manipulating images and graphics on a canvas element in a document. A context object includes information about colors, line widths, fonts, and other graphic parameters that can be drawn on a canvas.\\n     * @param contextId The identifier (ID) of the type of canvas to create. Internet Explorer 9 and Internet Explorer 10 support only a 2-D context using canvas.getContext(\\\"2d\\\"); IE11 Preview also supports 3-D or WebGL context using canvas.getContext(\\\"experimental-webgl\\\");\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/getContext)\\n     */\\n    getContext(contextId: \\\"2d\\\", options?: CanvasRenderingContext2DSettings): CanvasRenderingContext2D | null;\\n    getContext(contextId: \\\"bitmaprenderer\\\", options?: ImageBitmapRenderingContextSettings): ImageBitmapRenderingContext | null;\\n    getContext(contextId: \\\"webgl\\\", options?: WebGLContextAttributes): WebGLRenderingContext | null;\\n    getContext(contextId: \\\"webgl2\\\", options?: WebGLContextAttributes): WebGL2RenderingContext | null;\\n    getContext(contextId: string, options?: any): RenderingContext | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/toBlob) */\\n    toBlob(callback: BlobCallback, type?: string, quality?: any): void;\\n    /**\\n     * Returns the content of the current canvas as an image that you can use as a source for another canvas or an HTML element.\\n     * @param type The standard MIME type for the image format to return. If you do not specify this parameter, the default value is a PNG format image.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/toDataURL)\\n     */\\n    toDataURL(type?: string, quality?: any): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCanvasElement/transferControlToOffscreen) */\\n    transferControlToOffscreen(): OffscreenCanvas;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLCanvasElement: {\\n    prototype: HTMLCanvasElement;\\n    new(): HTMLCanvasElement;\\n};\\n\\n/**\\n * A generic collection (array-like object similar to arguments) of elements (in document order) and offers methods and properties for selecting from the list.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCollection)\\n */\\ninterface HTMLCollectionBase {\\n    /**\\n     * Sets or retrieves the number of objects in a collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCollection/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Retrieves an object from various collections.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCollection/item)\\n     */\\n    item(index: number): Element | null;\\n    [index: number]: Element;\\n}\\n\\ninterface HTMLCollection extends HTMLCollectionBase {\\n    /**\\n     * Retrieves a select object or an object from an options collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLCollection/namedItem)\\n     */\\n    namedItem(name: string): Element | null;\\n}\\n\\ndeclare var HTMLCollection: {\\n    prototype: HTMLCollection;\\n    new(): HTMLCollection;\\n};\\n\\ninterface HTMLCollectionOf<T extends Element> extends HTMLCollectionBase {\\n    item(index: number): T | null;\\n    namedItem(name: string): T | null;\\n    [index: number]: T;\\n}\\n\\n/**\\n * Provides special properties (beyond those of the regular HTMLElement interface it also has available to it by inheritance) for manipulating definition list (<dl>) elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDListElement)\\n */\\ninterface HTMLDListElement extends HTMLElement {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDListElement/compact)\\n     */\\n    compact: boolean;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLDListElement: {\\n    prototype: HTMLDListElement;\\n    new(): HTMLDListElement;\\n};\\n\\n/**\\n * Provides special properties (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating <data> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDataElement)\\n */\\ninterface HTMLDataElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDataElement/value) */\\n    value: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLDataElement: {\\n    prototype: HTMLDataElement;\\n    new(): HTMLDataElement;\\n};\\n\\n/**\\n * Provides special properties (beyond the HTMLElement object interface it also has available to it by inheritance) to manipulate <datalist> elements and their content.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDataListElement)\\n */\\ninterface HTMLDataListElement extends HTMLElement {\\n    /**\\n     * Returns an HTMLCollection of the option elements of the datalist element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDataListElement/options)\\n     */\\n    readonly options: HTMLCollectionOf<HTMLOptionElement>;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLDataListElement: {\\n    prototype: HTMLDataListElement;\\n    new(): HTMLDataListElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDetailsElement) */\\ninterface HTMLDetailsElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDetailsElement/open) */\\n    open: boolean;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDetailsElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDetailsElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLDetailsElement: {\\n    prototype: HTMLDetailsElement;\\n    new(): HTMLDetailsElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement) */\\ninterface HTMLDialogElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/open) */\\n    open: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/returnValue) */\\n    returnValue: string;\\n    /**\\n     * Closes the dialog element.\\n     *\\n     * The argument, if provided, provides a return value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/close)\\n     */\\n    close(returnValue?: string): void;\\n    /**\\n     * Displays the dialog element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/show)\\n     */\\n    show(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/showModal) */\\n    showModal(): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDialogElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDialogElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLDialogElement: {\\n    prototype: HTMLDialogElement;\\n    new(): HTMLDialogElement;\\n};\\n\\n/** @deprecated */\\ninterface HTMLDirectoryElement extends HTMLElement {\\n    /** @deprecated */\\n    compact: boolean;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** @deprecated */\\ndeclare var HTMLDirectoryElement: {\\n    prototype: HTMLDirectoryElement;\\n    new(): HTMLDirectoryElement;\\n};\\n\\n/**\\n * Provides special properties (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating <div> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDivElement)\\n */\\ninterface HTMLDivElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves how the object is aligned with adjacent text.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDivElement/align)\\n     */\\n    align: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLDivElement: {\\n    prototype: HTMLDivElement;\\n    new(): HTMLDivElement;\\n};\\n\\n/** @deprecated use Document */\\ninterface HTMLDocument extends Document {\\n    addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** @deprecated */\\ndeclare var HTMLDocument: {\\n    prototype: HTMLDocument;\\n    new(): HTMLDocument;\\n};\\n\\ninterface HTMLElementEventMap extends ElementEventMap, GlobalEventHandlersEventMap {\\n}\\n\\n/**\\n * Any HTML element. Some elements directly implement this interface, while others implement it via an interface that inherits it.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement)\\n */\\ninterface HTMLElement extends Element, ElementCSSInlineStyle, ElementContentEditable, GlobalEventHandlers, HTMLOrSVGElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/accessKey) */\\n    accessKey: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/accessKeyLabel) */\\n    readonly accessKeyLabel: string;\\n    autocapitalize: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dir) */\\n    dir: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/draggable) */\\n    draggable: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/hidden) */\\n    hidden: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/inert) */\\n    inert: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/innerText) */\\n    innerText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/lang) */\\n    lang: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/offsetHeight) */\\n    readonly offsetHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/offsetLeft) */\\n    readonly offsetLeft: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/offsetParent) */\\n    readonly offsetParent: Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/offsetTop) */\\n    readonly offsetTop: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/offsetWidth) */\\n    readonly offsetWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/outerText) */\\n    outerText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/popover) */\\n    popover: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/spellcheck) */\\n    spellcheck: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/title) */\\n    title: string;\\n    translate: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/attachInternals) */\\n    attachInternals(): ElementInternals;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/click) */\\n    click(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/hidePopover) */\\n    hidePopover(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/showPopover) */\\n    showPopover(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/togglePopover) */\\n    togglePopover(force?: boolean): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLElement: {\\n    prototype: HTMLElement;\\n    new(): HTMLElement;\\n};\\n\\n/**\\n * Provides special properties (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating <embed> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLEmbedElement)\\n */\\ninterface HTMLEmbedElement extends HTMLElement {\\n    /** @deprecated */\\n    align: string;\\n    /** Sets or retrieves the height of the object. */\\n    height: string;\\n    /**\\n     * Sets or retrieves the name of the object.\\n     * @deprecated\\n     */\\n    name: string;\\n    /** Sets or retrieves a URL to be loaded by the object. */\\n    src: string;\\n    type: string;\\n    /** Sets or retrieves the width of the object. */\\n    width: string;\\n    getSVGDocument(): Document | null;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLEmbedElement: {\\n    prototype: HTMLEmbedElement;\\n    new(): HTMLEmbedElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of <fieldset> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement)\\n */\\ninterface HTMLFieldSetElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/disabled) */\\n    disabled: boolean;\\n    /**\\n     * Returns an HTMLCollection of the form controls in the element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/elements)\\n     */\\n    readonly elements: HTMLCollection;\\n    /**\\n     * Retrieves a reference to the form that the object is embedded in.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/form)\\n     */\\n    readonly form: HTMLFormElement | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/name) */\\n    name: string;\\n    /**\\n     * Returns the string \\\"fieldset\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/type)\\n     */\\n    readonly type: string;\\n    /**\\n     * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as \\\"this is a required field\\\". The result is that the user sees validation messages without actually submitting.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/validationMessage)\\n     */\\n    readonly validationMessage: string;\\n    /**\\n     * Returns a  ValidityState object that represents the validity states of an element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/validity)\\n     */\\n    readonly validity: ValidityState;\\n    /**\\n     * Returns whether an element will successfully validate based on forms validation rules and constraints.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/willValidate)\\n     */\\n    readonly willValidate: boolean;\\n    /** Returns whether a form will validate when it is submitted, without having to submit it. */\\n    checkValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFieldSetElement/reportValidity) */\\n    reportValidity(): boolean;\\n    /**\\n     * Sets a custom error message that is displayed when a form is submitted.\\n     * @param error Sets a custom error message that is displayed when a form is submitted.\\n     */\\n    setCustomValidity(error: string): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLFieldSetElement: {\\n    prototype: HTMLFieldSetElement;\\n    new(): HTMLFieldSetElement;\\n};\\n\\n/**\\n * Implements the document object model (DOM) representation of the font element. The HTML Font Element <font> defines the font size, font face and color of text.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFontElement)\\n */\\ninterface HTMLFontElement extends HTMLElement {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFontElement/color)\\n     */\\n    color: string;\\n    /**\\n     * Sets or retrieves the current typeface family.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFontElement/face)\\n     */\\n    face: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFontElement/size)\\n     */\\n    size: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** @deprecated */\\ndeclare var HTMLFontElement: {\\n    prototype: HTMLFontElement;\\n    new(): HTMLFontElement;\\n};\\n\\n/**\\n * A collection of HTML form control elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormControlsCollection)\\n */\\ninterface HTMLFormControlsCollection extends HTMLCollectionBase {\\n    /**\\n     * Returns the item with ID or name name from the collection.\\n     *\\n     * If there are multiple matching items, then a RadioNodeList object containing all those elements is returned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormControlsCollection/namedItem)\\n     */\\n    namedItem(name: string): RadioNodeList | Element | null;\\n}\\n\\ndeclare var HTMLFormControlsCollection: {\\n    prototype: HTMLFormControlsCollection;\\n    new(): HTMLFormControlsCollection;\\n};\\n\\n/**\\n * A <form> element in the DOM; it allows access to and in some cases modification of aspects of the form, as well as access to its component elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement)\\n */\\ninterface HTMLFormElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves a list of character encodings for input data that must be accepted by the server processing the form.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/acceptCharset)\\n     */\\n    acceptCharset: string;\\n    /**\\n     * Sets or retrieves the URL to which the form content is sent for processing.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/action)\\n     */\\n    action: string;\\n    /**\\n     * Specifies whether autocomplete is applied to an editable text field.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/autocomplete)\\n     */\\n    autocomplete: AutoFillBase;\\n    /**\\n     * Retrieves a collection, in source order, of all controls in a given form.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/elements)\\n     */\\n    readonly elements: HTMLFormControlsCollection;\\n    /**\\n     * Sets or retrieves the MIME encoding for the form.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/encoding)\\n     */\\n    encoding: string;\\n    /**\\n     * Sets or retrieves the encoding type for the form.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/enctype)\\n     */\\n    enctype: string;\\n    /**\\n     * Sets or retrieves the number of objects in a collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Sets or retrieves how to send the form data to the server.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/method)\\n     */\\n    method: string;\\n    /**\\n     * Sets or retrieves the name of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/name)\\n     */\\n    name: string;\\n    /**\\n     * Designates a form that is not validated when submitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/noValidate)\\n     */\\n    noValidate: boolean;\\n    rel: string;\\n    readonly relList: DOMTokenList;\\n    /**\\n     * Sets or retrieves the window or frame at which to target content.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/target)\\n     */\\n    target: string;\\n    /**\\n     * Returns whether a form will validate when it is submitted, without having to submit it.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/checkValidity)\\n     */\\n    checkValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/reportValidity) */\\n    reportValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/requestSubmit) */\\n    requestSubmit(submitter?: HTMLElement | null): void;\\n    /**\\n     * Fires when the user resets a form.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/reset)\\n     */\\n    reset(): void;\\n    /**\\n     * Fires when a FORM is about to be submitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/submit)\\n     */\\n    submit(): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n    [index: number]: Element;\\n    [name: string]: any;\\n}\\n\\ndeclare var HTMLFormElement: {\\n    prototype: HTMLFormElement;\\n    new(): HTMLFormElement;\\n};\\n\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement)\\n */\\ninterface HTMLFrameElement extends HTMLElement {\\n    /**\\n     * Retrieves the document object of the page or frame.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/contentDocument)\\n     */\\n    readonly contentDocument: Document | null;\\n    /**\\n     * Retrieves the object of the specified.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/contentWindow)\\n     */\\n    readonly contentWindow: WindowProxy | null;\\n    /**\\n     * Sets or retrieves whether to display a border for the frame.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/frameBorder)\\n     */\\n    frameBorder: string;\\n    /**\\n     * Sets or retrieves a URI to a long description of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/longDesc)\\n     */\\n    longDesc: string;\\n    /**\\n     * Sets or retrieves the top and bottom margin heights before displaying the text in a frame.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/marginHeight)\\n     */\\n    marginHeight: string;\\n    /**\\n     * Sets or retrieves the left and right margin widths before displaying the text in a frame.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/marginWidth)\\n     */\\n    marginWidth: string;\\n    /**\\n     * Sets or retrieves the frame name.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/name)\\n     */\\n    name: string;\\n    /**\\n     * Sets or retrieves whether the user can resize the frame.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/noResize)\\n     */\\n    noResize: boolean;\\n    /**\\n     * Sets or retrieves whether the frame can be scrolled.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/scrolling)\\n     */\\n    scrolling: string;\\n    /**\\n     * Sets or retrieves a URL to be loaded by the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameElement/src)\\n     */\\n    src: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLFrameElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLFrameElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** @deprecated */\\ndeclare var HTMLFrameElement: {\\n    prototype: HTMLFrameElement;\\n    new(): HTMLFrameElement;\\n};\\n\\ninterface HTMLFrameSetElementEventMap extends HTMLElementEventMap, WindowEventHandlersEventMap {\\n}\\n\\n/**\\n * Provides special properties (beyond those of the regular HTMLElement interface they also inherit) for manipulating <frameset> elements.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFrameSetElement)\\n */\\ninterface HTMLFrameSetElement extends HTMLElement, WindowEventHandlers {\\n    /**\\n     * Sets or retrieves the frame widths of the object.\\n     * @deprecated\\n     */\\n    cols: string;\\n    /**\\n     * Sets or retrieves the frame heights of the object.\\n     * @deprecated\\n     */\\n    rows: string;\\n    addEventListener<K extends keyof HTMLFrameSetElementEventMap>(type: K, listener: (this: HTMLFrameSetElement, ev: HTMLFrameSetElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLFrameSetElementEventMap>(type: K, listener: (this: HTMLFrameSetElement, ev: HTMLFrameSetElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** @deprecated */\\ndeclare var HTMLFrameSetElement: {\\n    prototype: HTMLFrameSetElement;\\n    new(): HTMLFrameSetElement;\\n};\\n\\n/**\\n * Provides special properties (beyond those of the HTMLElement interface it also has available to it by inheritance) for manipulating <hr> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLHRElement)\\n */\\ninterface HTMLHRElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves how the object is aligned with adjacent text.\\n     * @deprecated\\n     */\\n    align: string;\\n    /** @deprecated */\\n    color: string;\\n    /**\\n     * Sets or retrieves whether the horizontal rule is drawn with 3-D shading.\\n     * @deprecated\\n     */\\n    noShade: boolean;\\n    /** @deprecated */\\n    size: string;\\n    /**\\n     * Sets or retrieves the width of the object.\\n     * @deprecated\\n     */\\n    width: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLHRElement: {\\n    prototype: HTMLHRElement;\\n    new(): HTMLHRElement;\\n};\\n\\n/**\\n * Contains the descriptive information, or metadata, for a document. This object inherits all of the properties and methods described in the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLHeadElement)\\n */\\ninterface HTMLHeadElement extends HTMLElement {\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLHeadElement: {\\n    prototype: HTMLHeadElement;\\n    new(): HTMLHeadElement;\\n};\\n\\n/**\\n * The different heading elements. It inherits methods and properties from the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLHeadingElement)\\n */\\ninterface HTMLHeadingElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves a value that indicates the table alignment.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLHeadingElement/align)\\n     */\\n    align: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLHeadingElement: {\\n    prototype: HTMLHeadingElement;\\n    new(): HTMLHeadingElement;\\n};\\n\\n/**\\n * Serves as the root node for a given HTML document. This object inherits the properties and methods described in the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLHtmlElement)\\n */\\ninterface HTMLHtmlElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves the DTD version that governs the current document.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLHtmlElement/version)\\n     */\\n    version: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLHtmlElement: {\\n    prototype: HTMLHtmlElement;\\n    new(): HTMLHtmlElement;\\n};\\n\\ninterface HTMLHyperlinkElementUtils {\\n    /**\\n     * Returns the hyperlink's URL's fragment (includes leading \\\"#\\\" if non-empty).\\n     *\\n     * Can be set, to change the URL's fragment (ignores leading \\\"#\\\").\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/hash)\\n     */\\n    hash: string;\\n    /**\\n     * Returns the hyperlink's URL's host and port (if different from the default port for the scheme).\\n     *\\n     * Can be set, to change the URL's host and port.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/host)\\n     */\\n    host: string;\\n    /**\\n     * Returns the hyperlink's URL's host.\\n     *\\n     * Can be set, to change the URL's host.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/hostname)\\n     */\\n    hostname: string;\\n    /**\\n     * Returns the hyperlink's URL.\\n     *\\n     * Can be set, to change the URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/href)\\n     */\\n    href: string;\\n    toString(): string;\\n    /**\\n     * Returns the hyperlink's URL's origin.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/origin)\\n     */\\n    readonly origin: string;\\n    /**\\n     * Returns the hyperlink's URL's password.\\n     *\\n     * Can be set, to change the URL's password.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/password)\\n     */\\n    password: string;\\n    /**\\n     * Returns the hyperlink's URL's path.\\n     *\\n     * Can be set, to change the URL's path.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/pathname)\\n     */\\n    pathname: string;\\n    /**\\n     * Returns the hyperlink's URL's port.\\n     *\\n     * Can be set, to change the URL's port.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/port)\\n     */\\n    port: string;\\n    /**\\n     * Returns the hyperlink's URL's scheme.\\n     *\\n     * Can be set, to change the URL's scheme.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/protocol)\\n     */\\n    protocol: string;\\n    /**\\n     * Returns the hyperlink's URL's query (includes leading \\\"?\\\" if non-empty).\\n     *\\n     * Can be set, to change the URL's query (ignores leading \\\"?\\\").\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/search)\\n     */\\n    search: string;\\n    /**\\n     * Returns the hyperlink's URL's username.\\n     *\\n     * Can be set, to change the URL's username.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/username)\\n     */\\n    username: string;\\n}\\n\\n/**\\n * Provides special properties and methods (beyond those of the HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of inline frame elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement)\\n */\\ninterface HTMLIFrameElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves how the object is aligned with adjacent text.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/align)\\n     */\\n    align: string;\\n    allow: string;\\n    allowFullscreen: boolean;\\n    /**\\n     * Retrieves the document object of the page or frame.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/contentDocument)\\n     */\\n    readonly contentDocument: Document | null;\\n    /**\\n     * Retrieves the object of the specified.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/contentWindow)\\n     */\\n    readonly contentWindow: WindowProxy | null;\\n    /**\\n     * Sets or retrieves whether to display a border for the frame.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/frameBorder)\\n     */\\n    frameBorder: string;\\n    /**\\n     * Sets or retrieves the height of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/height)\\n     */\\n    height: string;\\n    loading: string;\\n    /**\\n     * Sets or retrieves a URI to a long description of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/longDesc)\\n     */\\n    longDesc: string;\\n    /**\\n     * Sets or retrieves the top and bottom margin heights before displaying the text in a frame.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/marginHeight)\\n     */\\n    marginHeight: string;\\n    /**\\n     * Sets or retrieves the left and right margin widths before displaying the text in a frame.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/marginWidth)\\n     */\\n    marginWidth: string;\\n    /**\\n     * Sets or retrieves the frame name.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/name)\\n     */\\n    name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/referrerPolicy) */\\n    referrerPolicy: ReferrerPolicy;\\n    readonly sandbox: DOMTokenList;\\n    /**\\n     * Sets or retrieves whether the frame can be scrolled.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/scrolling)\\n     */\\n    scrolling: string;\\n    /**\\n     * Sets or retrieves a URL to be loaded by the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/src)\\n     */\\n    src: string;\\n    /**\\n     * Sets or retrives the content of the page that is to contain.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/srcdoc)\\n     */\\n    srcdoc: string;\\n    /**\\n     * Sets or retrieves the width of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/width)\\n     */\\n    width: string;\\n    getSVGDocument(): Document | null;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLIFrameElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLIFrameElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLIFrameElement: {\\n    prototype: HTMLIFrameElement;\\n    new(): HTMLIFrameElement;\\n};\\n\\n/**\\n * Provides special properties and methods for manipulating <img> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement)\\n */\\ninterface HTMLImageElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves how the object is aligned with adjacent text.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/align)\\n     */\\n    align: string;\\n    /**\\n     * Sets or retrieves a text alternative to the graphic.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/alt)\\n     */\\n    alt: string;\\n    /**\\n     * Specifies the properties of a border drawn around an object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/border)\\n     */\\n    border: string;\\n    /**\\n     * Retrieves whether the object is fully loaded.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/complete)\\n     */\\n    readonly complete: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/crossOrigin) */\\n    crossOrigin: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/currentSrc) */\\n    readonly currentSrc: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/decoding) */\\n    decoding: \\\"async\\\" | \\\"sync\\\" | \\\"auto\\\";\\n    /**\\n     * Sets or retrieves the height of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/height)\\n     */\\n    height: number;\\n    /**\\n     * Sets or retrieves the width of the border to draw around the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/hspace)\\n     */\\n    hspace: number;\\n    /**\\n     * Sets or retrieves whether the image is a server-side image map.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/isMap)\\n     */\\n    isMap: boolean;\\n    /**\\n     * Sets or retrieves the policy for loading image elements that are outside the viewport.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/loading)\\n     */\\n    loading: \\\"eager\\\" | \\\"lazy\\\";\\n    /**\\n     * Sets or retrieves a Uniform Resource Identifier (URI) to a long description of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/longDesc)\\n     */\\n    longDesc: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/lowsrc)\\n     */\\n    lowsrc: string;\\n    /**\\n     * Sets or retrieves the name of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/name)\\n     */\\n    name: string;\\n    /**\\n     * The original height of the image resource before sizing.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/naturalHeight)\\n     */\\n    readonly naturalHeight: number;\\n    /**\\n     * The original width of the image resource before sizing.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/naturalWidth)\\n     */\\n    readonly naturalWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/referrerPolicy) */\\n    referrerPolicy: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/sizes) */\\n    sizes: string;\\n    /**\\n     * The address or URL of the a media resource that is to be considered.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/src)\\n     */\\n    src: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/srcset) */\\n    srcset: string;\\n    /**\\n     * Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/useMap)\\n     */\\n    useMap: string;\\n    /**\\n     * Sets or retrieves the vertical margin for the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/vspace)\\n     */\\n    vspace: number;\\n    /**\\n     * Sets or retrieves the width of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/width)\\n     */\\n    width: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/x) */\\n    readonly x: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/y) */\\n    readonly y: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLImageElement/decode) */\\n    decode(): Promise<void>;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLImageElement: {\\n    prototype: HTMLImageElement;\\n    new(): HTMLImageElement;\\n};\\n\\n/**\\n * Provides special properties and methods for manipulating the options, layout, and presentation of <input> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement)\\n */\\ninterface HTMLInputElement extends HTMLElement, PopoverInvokerElement {\\n    /** Sets or retrieves a comma-separated list of content types. */\\n    accept: string;\\n    /**\\n     * Sets or retrieves how the object is aligned with adjacent text.\\n     * @deprecated\\n     */\\n    align: string;\\n    /** Sets or retrieves a text alternative to the graphic. */\\n    alt: string;\\n    /**\\n     * Specifies whether autocomplete is applied to an editable text field.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/autocomplete)\\n     */\\n    autocomplete: AutoFill;\\n    capture: string;\\n    /** Sets or retrieves the state of the check box or radio button. */\\n    checked: boolean;\\n    /** Sets or retrieves the state of the check box or radio button. */\\n    defaultChecked: boolean;\\n    /** Sets or retrieves the initial contents of the object. */\\n    defaultValue: string;\\n    dirName: string;\\n    disabled: boolean;\\n    /**\\n     * Returns a FileList object on a file type input object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/files)\\n     */\\n    files: FileList | null;\\n    /** Retrieves a reference to the form that the object is embedded in. */\\n    readonly form: HTMLFormElement | null;\\n    /**\\n     * Overrides the action attribute (where the data on a form is sent) on the parent form element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/formAction)\\n     */\\n    formAction: string;\\n    /**\\n     * Used to override the encoding (formEnctype attribute) specified on the form element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/formEnctype)\\n     */\\n    formEnctype: string;\\n    /**\\n     * Overrides the submit method attribute previously specified on a form element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/formMethod)\\n     */\\n    formMethod: string;\\n    /**\\n     * Overrides any validation or required attributes on a form or form elements to allow it to be submitted without validation. This can be used to create a \\\"save draft\\\"-type submit option.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/formNoValidate)\\n     */\\n    formNoValidate: boolean;\\n    /**\\n     * Overrides the target attribute on a form element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/formTarget)\\n     */\\n    formTarget: string;\\n    /**\\n     * Sets or retrieves the height of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/height)\\n     */\\n    height: number;\\n    /**\\n     * When set, overrides the rendering of checkbox controls so that the current value is not visible.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/indeterminate)\\n     */\\n    indeterminate: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/labels) */\\n    readonly labels: NodeListOf<HTMLLabelElement> | null;\\n    /**\\n     * Specifies the ID of a pre-defined datalist of options for an input element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/list)\\n     */\\n    readonly list: HTMLDataListElement | null;\\n    /** Defines the maximum acceptable value for an input element with type=\\\"number\\\".When used with the min and step attributes, lets you control the range and increment (such as only even numbers) that the user can enter into an input field. */\\n    max: string;\\n    /** Sets or retrieves the maximum number of characters that the user can enter in a text control. */\\n    maxLength: number;\\n    /** Defines the minimum acceptable value for an input element with type=\\\"number\\\". When used with the max and step attributes, lets you control the range and increment (such as even numbers only) that the user can enter into an input field. */\\n    min: string;\\n    minLength: number;\\n    /**\\n     * Sets or retrieves the Boolean value indicating whether multiple items can be selected from a list.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/multiple)\\n     */\\n    multiple: boolean;\\n    /** Sets or retrieves the name of the object. */\\n    name: string;\\n    /**\\n     * Gets or sets a string containing a regular expression that the user's input must match.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/pattern)\\n     */\\n    pattern: string;\\n    /**\\n     * Gets or sets a text string that is displayed in an input field as a hint or prompt to users as the format or type of information they need to enter.The text appears in an input field until the user puts focus on the field.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/placeholder)\\n     */\\n    placeholder: string;\\n    readOnly: boolean;\\n    /**\\n     * When present, marks an element that can't be submitted without a value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/required)\\n     */\\n    required: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/selectionDirection) */\\n    selectionDirection: \\\"forward\\\" | \\\"backward\\\" | \\\"none\\\" | null;\\n    /** Gets or sets the end position or offset of a text selection. */\\n    selectionEnd: number | null;\\n    /** Gets or sets the starting position or offset of a text selection. */\\n    selectionStart: number | null;\\n    size: number;\\n    /** The address or URL of the a media resource that is to be considered. */\\n    src: string;\\n    /** Defines an increment or jump between values that you want to allow the user to enter. When used with the max and min attributes, lets you control the range and increment (for example, allow only even numbers) that the user can enter into an input field. */\\n    step: string;\\n    /** Returns the content type of the object. */\\n    type: string;\\n    /**\\n     * Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.\\n     * @deprecated\\n     */\\n    useMap: string;\\n    /**\\n     * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as \\\"this is a required field\\\". The result is that the user sees validation messages without actually submitting.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/validationMessage)\\n     */\\n    readonly validationMessage: string;\\n    /**\\n     * Returns a  ValidityState object that represents the validity states of an element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/validity)\\n     */\\n    readonly validity: ValidityState;\\n    /** Returns the value of the data at the cursor's current position. */\\n    value: string;\\n    /** Returns a Date object representing the form control's value, if applicable; otherwise, returns null. Can be set, to change the value. Throws an \\\"InvalidStateError\\\" DOMException if the control isn't date- or time-based. */\\n    valueAsDate: Date | null;\\n    /** Returns the input field value as a number. */\\n    valueAsNumber: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/webkitEntries) */\\n    readonly webkitEntries: ReadonlyArray<FileSystemEntry>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/webkitdirectory) */\\n    webkitdirectory: boolean;\\n    /**\\n     * Sets or retrieves the width of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/width)\\n     */\\n    width: number;\\n    /**\\n     * Returns whether an element will successfully validate based on forms validation rules and constraints.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/willValidate)\\n     */\\n    readonly willValidate: boolean;\\n    /**\\n     * Returns whether a form will validate when it is submitted, without having to submit it.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/checkValidity)\\n     */\\n    checkValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/reportValidity) */\\n    reportValidity(): boolean;\\n    /**\\n     * Makes the selection equal to the current object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/select)\\n     */\\n    select(): void;\\n    /**\\n     * Sets a custom error message that is displayed when a form is submitted.\\n     * @param error Sets a custom error message that is displayed when a form is submitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/setCustomValidity)\\n     */\\n    setCustomValidity(error: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/setRangeText) */\\n    setRangeText(replacement: string): void;\\n    setRangeText(replacement: string, start: number, end: number, selectionMode?: SelectionMode): void;\\n    /**\\n     * Sets the start and end positions of a selection in a text field.\\n     * @param start The offset into the text field for the start of the selection.\\n     * @param end The offset into the text field for the end of the selection.\\n     * @param direction The direction in which the selection is performed.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/setSelectionRange)\\n     */\\n    setSelectionRange(start: number | null, end: number | null, direction?: \\\"forward\\\" | \\\"backward\\\" | \\\"none\\\"): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/showPicker) */\\n    showPicker(): void;\\n    /**\\n     * Decrements a range input control's value by the value given by the Step attribute. If the optional parameter is used, it will decrement the input control's step value multiplied by the parameter's value.\\n     * @param n Value to decrement the value by.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/stepDown)\\n     */\\n    stepDown(n?: number): void;\\n    /**\\n     * Increments a range input control's value by the value given by the Step attribute. If the optional parameter is used, will increment the input control's value by that value.\\n     * @param n Value to increment the value by.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/stepUp)\\n     */\\n    stepUp(n?: number): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLInputElement: {\\n    prototype: HTMLInputElement;\\n    new(): HTMLInputElement;\\n};\\n\\n/**\\n * Exposes specific properties and methods (beyond those defined by regular HTMLElement interface it also has available to it by inheritance) for manipulating list elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLIElement)\\n */\\ninterface HTMLLIElement extends HTMLElement {\\n    /** @deprecated */\\n    type: string;\\n    /** Sets or retrieves the value of a list item. */\\n    value: number;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLLIElement: {\\n    prototype: HTMLLIElement;\\n    new(): HTMLLIElement;\\n};\\n\\n/**\\n * Gives access to properties specific to <label> elements. It inherits methods and properties from the base HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLabelElement)\\n */\\ninterface HTMLLabelElement extends HTMLElement {\\n    /**\\n     * Returns the form control that is associated with this element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLabelElement/control)\\n     */\\n    readonly control: HTMLElement | null;\\n    /**\\n     * Retrieves a reference to the form that the object is embedded in.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLabelElement/form)\\n     */\\n    readonly form: HTMLFormElement | null;\\n    /**\\n     * Sets or retrieves the object to which the given label object is assigned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLabelElement/htmlFor)\\n     */\\n    htmlFor: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLLabelElement: {\\n    prototype: HTMLLabelElement;\\n    new(): HTMLLabelElement;\\n};\\n\\n/**\\n * The HTMLLegendElement is an interface allowing to access properties of the <legend> elements. It inherits properties and methods from the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLegendElement)\\n */\\ninterface HTMLLegendElement extends HTMLElement {\\n    /** @deprecated */\\n    align: string;\\n    /** Retrieves a reference to the form that the object is embedded in. */\\n    readonly form: HTMLFormElement | null;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLLegendElement: {\\n    prototype: HTMLLegendElement;\\n    new(): HTMLLegendElement;\\n};\\n\\n/**\\n * Reference information for external resources and the relationship of those resources to a document and vice-versa. This object inherits all of the properties and methods of the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement)\\n */\\ninterface HTMLLinkElement extends HTMLElement, LinkStyle {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement/as) */\\n    as: string;\\n    /**\\n     * Sets or retrieves the character set used to encode the object.\\n     * @deprecated\\n     */\\n    charset: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement/crossOrigin) */\\n    crossOrigin: string | null;\\n    disabled: boolean;\\n    /** Sets or retrieves a destination URL or an anchor point. */\\n    href: string;\\n    /** Sets or retrieves the language code of the object. */\\n    hreflang: string;\\n    imageSizes: string;\\n    imageSrcset: string;\\n    integrity: string;\\n    /** Sets or retrieves the media type. */\\n    media: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement/referrerPolicy) */\\n    referrerPolicy: string;\\n    /**\\n     * Sets or retrieves the relationship between the object and the destination of the link.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement/rel)\\n     */\\n    rel: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement/relList) */\\n    readonly relList: DOMTokenList;\\n    /**\\n     * Sets or retrieves the relationship between the object and the destination of the link.\\n     * @deprecated\\n     */\\n    rev: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement/sizes) */\\n    readonly sizes: DOMTokenList;\\n    /**\\n     * Sets or retrieves the window or frame at which to target content.\\n     * @deprecated\\n     */\\n    target: string;\\n    /** Sets or retrieves the MIME type of the object. */\\n    type: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLLinkElement: {\\n    prototype: HTMLLinkElement;\\n    new(): HTMLLinkElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond those of the regular object HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of map elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMapElement)\\n */\\ninterface HTMLMapElement extends HTMLElement {\\n    /**\\n     * Retrieves a collection of the area objects defined for the given map object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMapElement/areas)\\n     */\\n    readonly areas: HTMLCollection;\\n    /**\\n     * Sets or retrieves the name of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMapElement/name)\\n     */\\n    name: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLMapElement: {\\n    prototype: HTMLMapElement;\\n    new(): HTMLMapElement;\\n};\\n\\n/**\\n * Provides methods to manipulate <marquee> elements.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMarqueeElement)\\n */\\ninterface HTMLMarqueeElement extends HTMLElement {\\n    /** @deprecated */\\n    behavior: string;\\n    /** @deprecated */\\n    bgColor: string;\\n    /** @deprecated */\\n    direction: string;\\n    /** @deprecated */\\n    height: string;\\n    /** @deprecated */\\n    hspace: number;\\n    /** @deprecated */\\n    loop: number;\\n    /** @deprecated */\\n    scrollAmount: number;\\n    /** @deprecated */\\n    scrollDelay: number;\\n    /** @deprecated */\\n    trueSpeed: boolean;\\n    /** @deprecated */\\n    vspace: number;\\n    /** @deprecated */\\n    width: string;\\n    /** @deprecated */\\n    start(): void;\\n    /** @deprecated */\\n    stop(): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMarqueeElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMarqueeElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** @deprecated */\\ndeclare var HTMLMarqueeElement: {\\n    prototype: HTMLMarqueeElement;\\n    new(): HTMLMarqueeElement;\\n};\\n\\ninterface HTMLMediaElementEventMap extends HTMLElementEventMap {\\n    \\\"encrypted\\\": MediaEncryptedEvent;\\n    \\\"waitingforkey\\\": Event;\\n}\\n\\n/**\\n * Adds to HTMLElement the properties and methods needed to support basic media-related capabilities that are common to audio and video.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement)\\n */\\ninterface HTMLMediaElement extends HTMLElement {\\n    /**\\n     * Gets or sets a value that indicates whether to start playing the media automatically.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/autoplay)\\n     */\\n    autoplay: boolean;\\n    /**\\n     * Gets a collection of buffered time ranges.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/buffered)\\n     */\\n    readonly buffered: TimeRanges;\\n    /**\\n     * Gets or sets a flag that indicates whether the client provides a set of controls for the media (in case the developer does not include controls for the player).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/controls)\\n     */\\n    controls: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/crossOrigin) */\\n    crossOrigin: string | null;\\n    /**\\n     * Gets the address or URL of the current media resource that is selected by IHTMLMediaElement.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/currentSrc)\\n     */\\n    readonly currentSrc: string;\\n    /**\\n     * Gets or sets the current playback position, in seconds.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/currentTime)\\n     */\\n    currentTime: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/defaultMuted) */\\n    defaultMuted: boolean;\\n    /**\\n     * Gets or sets the default playback rate when the user is not using fast forward or reverse for a video or audio resource.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/defaultPlaybackRate)\\n     */\\n    defaultPlaybackRate: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/disableRemotePlayback) */\\n    disableRemotePlayback: boolean;\\n    /**\\n     * Returns the duration in seconds of the current media resource. A NaN value is returned if duration is not available, or Infinity if the media resource is streaming.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/duration)\\n     */\\n    readonly duration: number;\\n    /**\\n     * Gets information about whether the playback has ended or not.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/ended)\\n     */\\n    readonly ended: boolean;\\n    /**\\n     * Returns an object representing the current error state of the audio or video element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/error)\\n     */\\n    readonly error: MediaError | null;\\n    /**\\n     * Gets or sets a flag to specify whether playback should restart after it completes.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/loop)\\n     */\\n    loop: boolean;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/mediaKeys)\\n     */\\n    readonly mediaKeys: MediaKeys | null;\\n    /**\\n     * Gets or sets a flag that indicates whether the audio (either audio or the audio track on video media) is muted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/muted)\\n     */\\n    muted: boolean;\\n    /**\\n     * Gets the current network activity for the element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/networkState)\\n     */\\n    readonly networkState: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/encrypted_event) */\\n    onencrypted: ((this: HTMLMediaElement, ev: MediaEncryptedEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/waitingforkey_event) */\\n    onwaitingforkey: ((this: HTMLMediaElement, ev: Event) => any) | null;\\n    /**\\n     * Gets a flag that specifies whether playback is paused.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/paused)\\n     */\\n    readonly paused: boolean;\\n    /**\\n     * Gets or sets the current rate of speed for the media resource to play. This speed is expressed as a multiple of the normal speed of the media resource.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/playbackRate)\\n     */\\n    playbackRate: number;\\n    /**\\n     * Gets TimeRanges for the current media resource that has been played.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/played)\\n     */\\n    readonly played: TimeRanges;\\n    /**\\n     * Gets or sets a value indicating what data should be preloaded, if any.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/preload)\\n     */\\n    preload: \\\"none\\\" | \\\"metadata\\\" | \\\"auto\\\" | \\\"\\\";\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/preservesPitch) */\\n    preservesPitch: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/readyState) */\\n    readonly readyState: number;\\n    readonly remote: RemotePlayback;\\n    /**\\n     * Returns a TimeRanges object that represents the ranges of the current media resource that can be seeked.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/seekable)\\n     */\\n    readonly seekable: TimeRanges;\\n    /**\\n     * Gets a flag that indicates whether the client is currently moving to a new playback position in the media resource.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/seeking)\\n     */\\n    readonly seeking: boolean;\\n    /**\\n     * The address or URL of the a media resource that is to be considered.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/src)\\n     */\\n    src: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/srcObject) */\\n    srcObject: MediaProvider | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/textTracks) */\\n    readonly textTracks: TextTrackList;\\n    /**\\n     * Gets or sets the volume level for audio portions of the media element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/volume)\\n     */\\n    volume: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/addTextTrack) */\\n    addTextTrack(kind: TextTrackKind, label?: string, language?: string): TextTrack;\\n    /**\\n     * Returns a string that specifies whether the client can play a given media resource type.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/canPlayType)\\n     */\\n    canPlayType(type: string): CanPlayTypeResult;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/fastSeek) */\\n    fastSeek(time: number): void;\\n    /**\\n     * Resets the audio or video object and loads a new media resource.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/load)\\n     */\\n    load(): void;\\n    /**\\n     * Pauses the current playback and sets paused to TRUE. This can be used to test whether the media is playing or paused. You can also use the pause or play events to tell whether the media is playing or not.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/pause)\\n     */\\n    pause(): void;\\n    /**\\n     * Loads and starts playback of a media resource.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/play)\\n     */\\n    play(): Promise<void>;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/setMediaKeys)\\n     */\\n    setMediaKeys(mediaKeys: MediaKeys | null): Promise<void>;\\n    readonly NETWORK_EMPTY: 0;\\n    readonly NETWORK_IDLE: 1;\\n    readonly NETWORK_LOADING: 2;\\n    readonly NETWORK_NO_SOURCE: 3;\\n    readonly HAVE_NOTHING: 0;\\n    readonly HAVE_METADATA: 1;\\n    readonly HAVE_CURRENT_DATA: 2;\\n    readonly HAVE_FUTURE_DATA: 3;\\n    readonly HAVE_ENOUGH_DATA: 4;\\n    addEventListener<K extends keyof HTMLMediaElementEventMap>(type: K, listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLMediaElementEventMap>(type: K, listener: (this: HTMLMediaElement, ev: HTMLMediaElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLMediaElement: {\\n    prototype: HTMLMediaElement;\\n    new(): HTMLMediaElement;\\n    readonly NETWORK_EMPTY: 0;\\n    readonly NETWORK_IDLE: 1;\\n    readonly NETWORK_LOADING: 2;\\n    readonly NETWORK_NO_SOURCE: 3;\\n    readonly HAVE_NOTHING: 0;\\n    readonly HAVE_METADATA: 1;\\n    readonly HAVE_CURRENT_DATA: 2;\\n    readonly HAVE_FUTURE_DATA: 3;\\n    readonly HAVE_ENOUGH_DATA: 4;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMenuElement) */\\ninterface HTMLMenuElement extends HTMLElement {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMenuElement/compact)\\n     */\\n    compact: boolean;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLMenuElement: {\\n    prototype: HTMLMenuElement;\\n    new(): HTMLMenuElement;\\n};\\n\\n/**\\n * Contains descriptive metadata about a document. It inherits all of the properties and methods described in the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMetaElement)\\n */\\ninterface HTMLMetaElement extends HTMLElement {\\n    /** Gets or sets meta-information to associate with httpEquiv or name. */\\n    content: string;\\n    /** Gets or sets information used to bind the value of a content attribute of a meta element to an HTTP response header. */\\n    httpEquiv: string;\\n    media: string;\\n    /** Sets or retrieves the value specified in the content attribute of the meta object. */\\n    name: string;\\n    /**\\n     * Sets or retrieves a scheme to be used in interpreting the value of a property specified for the object.\\n     * @deprecated\\n     */\\n    scheme: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLMetaElement: {\\n    prototype: HTMLMetaElement;\\n    new(): HTMLMetaElement;\\n};\\n\\n/**\\n * The HTML <meter> elements expose the HTMLMeterElement interface, which provides special properties and methods (beyond the HTMLElement object interface they also have available to them by inheritance) for manipulating the layout and presentation of <meter> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMeterElement)\\n */\\ninterface HTMLMeterElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMeterElement/high) */\\n    high: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMeterElement/labels) */\\n    readonly labels: NodeListOf<HTMLLabelElement>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMeterElement/low) */\\n    low: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMeterElement/max) */\\n    max: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMeterElement/min) */\\n    min: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMeterElement/optimum) */\\n    optimum: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMeterElement/value) */\\n    value: number;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLMeterElement: {\\n    prototype: HTMLMeterElement;\\n    new(): HTMLMeterElement;\\n};\\n\\n/**\\n * Provides special properties (beyond the regular methods and properties available through the HTMLElement interface they also have available to them by inheritance) for manipulating modification elements, that is <del> and <ins>.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLModElement)\\n */\\ninterface HTMLModElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves reference information about the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLModElement/cite)\\n     */\\n    cite: string;\\n    /**\\n     * Sets or retrieves the date and time of a modification to the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLModElement/dateTime)\\n     */\\n    dateTime: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLModElement: {\\n    prototype: HTMLModElement;\\n    new(): HTMLModElement;\\n};\\n\\n/**\\n * Provides special properties (beyond those defined on the regular HTMLElement interface it also has available to it by inheritance) for manipulating ordered list elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOListElement)\\n */\\ninterface HTMLOListElement extends HTMLElement {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOListElement/compact)\\n     */\\n    compact: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOListElement/reversed) */\\n    reversed: boolean;\\n    /**\\n     * The starting number.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOListElement/start)\\n     */\\n    start: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOListElement/type) */\\n    type: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLOListElement: {\\n    prototype: HTMLOListElement;\\n    new(): HTMLOListElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond those on the HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of <object> element, representing external resources.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement)\\n */\\ninterface HTMLObjectElement extends HTMLElement {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/align)\\n     */\\n    align: string;\\n    /**\\n     * Sets or retrieves a character string that can be used to implement your own archive functionality for the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/archive)\\n     */\\n    archive: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/border)\\n     */\\n    border: string;\\n    /**\\n     * Sets or retrieves the URL of the file containing the compiled Java class.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/code)\\n     */\\n    code: string;\\n    /**\\n     * Sets or retrieves the URL of the component.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/codeBase)\\n     */\\n    codeBase: string;\\n    /**\\n     * Sets or retrieves the Internet media type for the code associated with the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/codeType)\\n     */\\n    codeType: string;\\n    /**\\n     * Retrieves the document object of the page or frame.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/contentDocument)\\n     */\\n    readonly contentDocument: Document | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/contentWindow) */\\n    readonly contentWindow: WindowProxy | null;\\n    /**\\n     * Sets or retrieves the URL that references the data of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/data)\\n     */\\n    data: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/declare)\\n     */\\n    declare: boolean;\\n    /**\\n     * Retrieves a reference to the form that the object is embedded in.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/form)\\n     */\\n    readonly form: HTMLFormElement | null;\\n    /**\\n     * Sets or retrieves the height of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/height)\\n     */\\n    height: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/hspace)\\n     */\\n    hspace: number;\\n    /**\\n     * Sets or retrieves the name of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/name)\\n     */\\n    name: string;\\n    /**\\n     * Sets or retrieves a message to be displayed while an object is loading.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/standby)\\n     */\\n    standby: string;\\n    /**\\n     * Sets or retrieves the MIME type of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/type)\\n     */\\n    type: string;\\n    /**\\n     * Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/useMap)\\n     */\\n    useMap: string;\\n    /**\\n     * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as \\\"this is a required field\\\". The result is that the user sees validation messages without actually submitting.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/validationMessage)\\n     */\\n    readonly validationMessage: string;\\n    /**\\n     * Returns a  ValidityState object that represents the validity states of an element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/validity)\\n     */\\n    readonly validity: ValidityState;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/vspace)\\n     */\\n    vspace: number;\\n    /**\\n     * Sets or retrieves the width of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/width)\\n     */\\n    width: string;\\n    /**\\n     * Returns whether an element will successfully validate based on forms validation rules and constraints.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/willValidate)\\n     */\\n    readonly willValidate: boolean;\\n    /**\\n     * Returns whether a form will validate when it is submitted, without having to submit it.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/checkValidity)\\n     */\\n    checkValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/getSVGDocument) */\\n    getSVGDocument(): Document | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/reportValidity) */\\n    reportValidity(): boolean;\\n    /**\\n     * Sets a custom error message that is displayed when a form is submitted.\\n     * @param error Sets a custom error message that is displayed when a form is submitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/setCustomValidity)\\n     */\\n    setCustomValidity(error: string): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLObjectElement: {\\n    prototype: HTMLObjectElement;\\n    new(): HTMLObjectElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond the regular HTMLElement object interface they also have available to them by inheritance) for manipulating the layout and presentation of <optgroup> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptGroupElement)\\n */\\ninterface HTMLOptGroupElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptGroupElement/disabled) */\\n    disabled: boolean;\\n    /**\\n     * Sets or retrieves a value that you can use to implement your own label functionality for the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptGroupElement/label)\\n     */\\n    label: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLOptGroupElement: {\\n    prototype: HTMLOptGroupElement;\\n    new(): HTMLOptGroupElement;\\n};\\n\\n/**\\n * <option> elements and inherits all classes and methods of the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement)\\n */\\ninterface HTMLOptionElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves the status of an option.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement/defaultSelected)\\n     */\\n    defaultSelected: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement/disabled) */\\n    disabled: boolean;\\n    /**\\n     * Retrieves a reference to the form that the object is embedded in.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement/form)\\n     */\\n    readonly form: HTMLFormElement | null;\\n    /**\\n     * Sets or retrieves the ordinal position of an option in a list box.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement/index)\\n     */\\n    readonly index: number;\\n    /**\\n     * Sets or retrieves a value that you can use to implement your own label functionality for the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement/label)\\n     */\\n    label: string;\\n    /**\\n     * Sets or retrieves whether the option in the list box is the default item.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement/selected)\\n     */\\n    selected: boolean;\\n    /**\\n     * Sets or retrieves the text string specified by the option tag.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement/text)\\n     */\\n    text: string;\\n    /**\\n     * Sets or retrieves the value which is returned to the server when the form control is submitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionElement/value)\\n     */\\n    value: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLOptionElement: {\\n    prototype: HTMLOptionElement;\\n    new(): HTMLOptionElement;\\n};\\n\\n/**\\n * HTMLOptionsCollection is an interface representing a collection of HTML option elements (in document order) and offers methods and properties for traversing the list as well as optionally altering its items. This type is returned solely by the \\\"options\\\" property of select.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionsCollection)\\n */\\ninterface HTMLOptionsCollection extends HTMLCollectionOf<HTMLOptionElement> {\\n    /**\\n     * Returns the number of elements in the collection.\\n     *\\n     * When set to a smaller number, truncates the number of option elements in the corresponding container.\\n     *\\n     * When set to a greater number, adds new blank option elements to that container.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionsCollection/length)\\n     */\\n    length: number;\\n    /**\\n     * Returns the index of the first selected item, if any, or −1 if there is no selected item.\\n     *\\n     * Can be set, to change the selection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionsCollection/selectedIndex)\\n     */\\n    selectedIndex: number;\\n    /**\\n     * Inserts element before the node given by before.\\n     *\\n     * The before argument can be a number, in which case element is inserted before the item with that number, or an element from the collection, in which case element is inserted before that element.\\n     *\\n     * If before is omitted, null, or a number out of range, then element will be added at the end of the list.\\n     *\\n     * This method will throw a \\\"HierarchyRequestError\\\" DOMException if element is an ancestor of the element into which it is to be inserted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionsCollection/add)\\n     */\\n    add(element: HTMLOptionElement | HTMLOptGroupElement, before?: HTMLElement | number | null): void;\\n    /**\\n     * Removes the item with index index from the collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOptionsCollection/remove)\\n     */\\n    remove(index: number): void;\\n}\\n\\ndeclare var HTMLOptionsCollection: {\\n    prototype: HTMLOptionsCollection;\\n    new(): HTMLOptionsCollection;\\n};\\n\\ninterface HTMLOrSVGElement {\\n    autofocus: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dataset) */\\n    readonly dataset: DOMStringMap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/nonce) */\\n    nonce?: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/tabIndex) */\\n    tabIndex: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/blur) */\\n    blur(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/focus) */\\n    focus(options?: FocusOptions): void;\\n}\\n\\n/**\\n * Provides properties and methods (beyond those inherited from HTMLElement) for manipulating the layout and presentation of <output> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement)\\n */\\ninterface HTMLOutputElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/defaultValue) */\\n    defaultValue: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/form) */\\n    readonly form: HTMLFormElement | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/htmlFor) */\\n    readonly htmlFor: DOMTokenList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/labels) */\\n    readonly labels: NodeListOf<HTMLLabelElement>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/name) */\\n    name: string;\\n    /**\\n     * Returns the string \\\"output\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/type)\\n     */\\n    readonly type: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/validationMessage) */\\n    readonly validationMessage: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/validity) */\\n    readonly validity: ValidityState;\\n    /**\\n     * Returns the element's current value.\\n     *\\n     * Can be set, to change the value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/value)\\n     */\\n    value: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/willValidate) */\\n    readonly willValidate: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/checkValidity) */\\n    checkValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/reportValidity) */\\n    reportValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLOutputElement/setCustomValidity) */\\n    setCustomValidity(error: string): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLOutputElement: {\\n    prototype: HTMLOutputElement;\\n    new(): HTMLOutputElement;\\n};\\n\\n/**\\n * Provides special properties (beyond those of the regular HTMLElement object interface it inherits) for manipulating <p> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLParagraphElement)\\n */\\ninterface HTMLParagraphElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves how the object is aligned with adjacent text.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLParagraphElement/align)\\n     */\\n    align: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLParagraphElement: {\\n    prototype: HTMLParagraphElement;\\n    new(): HTMLParagraphElement;\\n};\\n\\n/**\\n * Provides special properties (beyond those of the regular HTMLElement object interface it inherits) for manipulating <param> elements, representing a pair of a key and a value that acts as a parameter for an <object> element.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLParamElement)\\n */\\ninterface HTMLParamElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves the name of an input parameter for an element.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLParamElement/name)\\n     */\\n    name: string;\\n    /**\\n     * Sets or retrieves the content type of the resource designated by the value attribute.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLParamElement/type)\\n     */\\n    type: string;\\n    /**\\n     * Sets or retrieves the value of an input parameter for an element.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLParamElement/value)\\n     */\\n    value: string;\\n    /**\\n     * Sets or retrieves the data type of the value attribute.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLParamElement/valueType)\\n     */\\n    valueType: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** @deprecated */\\ndeclare var HTMLParamElement: {\\n    prototype: HTMLParamElement;\\n    new(): HTMLParamElement;\\n};\\n\\n/**\\n * A <picture> HTML element. It doesn't implement specific properties or methods.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLPictureElement)\\n */\\ninterface HTMLPictureElement extends HTMLElement {\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLPictureElement: {\\n    prototype: HTMLPictureElement;\\n    new(): HTMLPictureElement;\\n};\\n\\n/**\\n * Exposes specific properties and methods (beyond those of the HTMLElement interface it also has available to it by inheritance) for manipulating a block of preformatted text (<pre>).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLPreElement)\\n */\\ninterface HTMLPreElement extends HTMLElement {\\n    /**\\n     * Sets or gets a value that you can use to implement your own width functionality for the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLPreElement/width)\\n     */\\n    width: number;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLPreElement: {\\n    prototype: HTMLPreElement;\\n    new(): HTMLPreElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of <progress> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLProgressElement)\\n */\\ninterface HTMLProgressElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLProgressElement/labels) */\\n    readonly labels: NodeListOf<HTMLLabelElement>;\\n    /**\\n     * Defines the maximum, or \\\"done\\\" value for a progress element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLProgressElement/max)\\n     */\\n    max: number;\\n    /**\\n     * Returns the quotient of value/max when the value attribute is set (determinate progress bar), or -1 when the value attribute is missing (indeterminate progress bar).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLProgressElement/position)\\n     */\\n    readonly position: number;\\n    /**\\n     * Sets or gets the current value of a progress element. The value must be a non-negative number between 0 and the max value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLProgressElement/value)\\n     */\\n    value: number;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLProgressElement: {\\n    prototype: HTMLProgressElement;\\n    new(): HTMLProgressElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating quoting elements, like <blockquote> and <q>, but not the <cite> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLQuoteElement)\\n */\\ninterface HTMLQuoteElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves reference information about the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLQuoteElement/cite)\\n     */\\n    cite: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLQuoteElement: {\\n    prototype: HTMLQuoteElement;\\n    new(): HTMLQuoteElement;\\n};\\n\\n/**\\n * HTML <script> elements expose the HTMLScriptElement interface, which provides special properties and methods for manipulating the behavior and execution of <script> elements (beyond the inherited HTMLElement interface).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLScriptElement)\\n */\\ninterface HTMLScriptElement extends HTMLElement {\\n    async: boolean;\\n    /**\\n     * Sets or retrieves the character set used to encode the object.\\n     * @deprecated\\n     */\\n    charset: string;\\n    crossOrigin: string | null;\\n    /** Sets or retrieves the status of the script. */\\n    defer: boolean;\\n    /**\\n     * Sets or retrieves the event for which the script is written.\\n     * @deprecated\\n     */\\n    event: string;\\n    /**\\n     * Sets or retrieves the object that is bound to the event script.\\n     * @deprecated\\n     */\\n    htmlFor: string;\\n    integrity: string;\\n    noModule: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLScriptElement/referrerPolicy) */\\n    referrerPolicy: string;\\n    /** Retrieves the URL to an external file that contains the source code or data. */\\n    src: string;\\n    /** Retrieves or sets the text of the object as a string. */\\n    text: string;\\n    /** Sets or retrieves the MIME type for the associated scripting engine. */\\n    type: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLScriptElement: {\\n    prototype: HTMLScriptElement;\\n    new(): HTMLScriptElement;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLScriptElement/supports_static) */\\n    supports(type: string): boolean;\\n};\\n\\n/**\\n * A <select> HTML Element. These elements also share all of the properties and methods of other HTML elements via the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement)\\n */\\ninterface HTMLSelectElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/autocomplete) */\\n    autocomplete: AutoFill;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/disabled) */\\n    disabled: boolean;\\n    /**\\n     * Retrieves a reference to the form that the object is embedded in.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/form)\\n     */\\n    readonly form: HTMLFormElement | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/labels) */\\n    readonly labels: NodeListOf<HTMLLabelElement>;\\n    /**\\n     * Sets or retrieves the number of objects in a collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/length)\\n     */\\n    length: number;\\n    /**\\n     * Sets or retrieves the Boolean value indicating whether multiple items can be selected from a list.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/multiple)\\n     */\\n    multiple: boolean;\\n    /**\\n     * Sets or retrieves the name of the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/name)\\n     */\\n    name: string;\\n    /**\\n     * Returns an HTMLOptionsCollection of the list of options.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/options)\\n     */\\n    readonly options: HTMLOptionsCollection;\\n    /**\\n     * When present, marks an element that can't be submitted without a value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/required)\\n     */\\n    required: boolean;\\n    /**\\n     * Sets or retrieves the index of the selected option in a select object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/selectedIndex)\\n     */\\n    selectedIndex: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/selectedOptions) */\\n    readonly selectedOptions: HTMLCollectionOf<HTMLOptionElement>;\\n    /**\\n     * Sets or retrieves the number of rows in the list box.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/size)\\n     */\\n    size: number;\\n    /**\\n     * Retrieves the type of select control based on the value of the MULTIPLE attribute.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/type)\\n     */\\n    readonly type: string;\\n    /**\\n     * Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as \\\"this is a required field\\\". The result is that the user sees validation messages without actually submitting.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/validationMessage)\\n     */\\n    readonly validationMessage: string;\\n    /**\\n     * Returns a  ValidityState object that represents the validity states of an element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/validity)\\n     */\\n    readonly validity: ValidityState;\\n    /**\\n     * Sets or retrieves the value which is returned to the server when the form control is submitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/value)\\n     */\\n    value: string;\\n    /**\\n     * Returns whether an element will successfully validate based on forms validation rules and constraints.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/willValidate)\\n     */\\n    readonly willValidate: boolean;\\n    /**\\n     * Adds an element to the areas, controlRange, or options collection.\\n     * @param element Variant of type Number that specifies the index position in the collection where the element is placed. If no value is given, the method places the element at the end of the collection.\\n     * @param before Variant of type Object that specifies an element to insert before, or null to append the object to the collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/add)\\n     */\\n    add(element: HTMLOptionElement | HTMLOptGroupElement, before?: HTMLElement | number | null): void;\\n    /**\\n     * Returns whether a form will validate when it is submitted, without having to submit it.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/checkValidity)\\n     */\\n    checkValidity(): boolean;\\n    /**\\n     * Retrieves a select object or an object from an options collection.\\n     * @param name Variant of type Number or String that specifies the object or collection to retrieve. If this parameter is an integer, it is the zero-based index of the object. If this parameter is a string, all objects with matching name or id properties are retrieved, and a collection is returned if more than one match is made.\\n     * @param index Variant of type Number that specifies the zero-based index of the object to retrieve when a collection is returned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/item)\\n     */\\n    item(index: number): HTMLOptionElement | null;\\n    /**\\n     * Retrieves a select object or an object from an options collection.\\n     * @param namedItem A String that specifies the name or id property of the object to retrieve. A collection is returned if more than one match is made.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/namedItem)\\n     */\\n    namedItem(name: string): HTMLOptionElement | null;\\n    /**\\n     * Removes an element from the collection.\\n     * @param index Number that specifies the zero-based index of the element to remove from the collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/remove)\\n     */\\n    remove(): void;\\n    remove(index: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/reportValidity) */\\n    reportValidity(): boolean;\\n    /**\\n     * Sets a custom error message that is displayed when a form is submitted.\\n     * @param error Sets a custom error message that is displayed when a form is submitted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/setCustomValidity)\\n     */\\n    setCustomValidity(error: string): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n    [name: number]: HTMLOptionElement | HTMLOptGroupElement;\\n}\\n\\ndeclare var HTMLSelectElement: {\\n    prototype: HTMLSelectElement;\\n    new(): HTMLSelectElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSlotElement) */\\ninterface HTMLSlotElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSlotElement/name) */\\n    name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSlotElement/assign) */\\n    assign(...nodes: (Element | Text)[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSlotElement/assignedElements) */\\n    assignedElements(options?: AssignedNodesOptions): Element[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSlotElement/assignedNodes) */\\n    assignedNodes(options?: AssignedNodesOptions): Node[];\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSlotElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSlotElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLSlotElement: {\\n    prototype: HTMLSlotElement;\\n    new(): HTMLSlotElement;\\n};\\n\\n/**\\n * Provides special properties (beyond the regular HTMLElement object interface it also has available to it by inheritance) for manipulating <source> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement)\\n */\\ninterface HTMLSourceElement extends HTMLElement {\\n    height: number;\\n    /**\\n     * Gets or sets the intended media type of the media source.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement/media)\\n     */\\n    media: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement/sizes) */\\n    sizes: string;\\n    /**\\n     * The address or URL of the a media resource that is to be considered.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement/src)\\n     */\\n    src: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement/srcset) */\\n    srcset: string;\\n    /**\\n     * Gets or sets the MIME type of a media resource.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement/type)\\n     */\\n    type: string;\\n    width: number;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLSourceElement: {\\n    prototype: HTMLSourceElement;\\n    new(): HTMLSourceElement;\\n};\\n\\n/**\\n * A <span> element and derives from the HTMLElement interface, but without implementing any additional properties or methods.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSpanElement)\\n */\\ninterface HTMLSpanElement extends HTMLElement {\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLSpanElement: {\\n    prototype: HTMLSpanElement;\\n    new(): HTMLSpanElement;\\n};\\n\\n/**\\n * A <style> element. It inherits properties and methods from its parent, HTMLElement, and from LinkStyle.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLStyleElement)\\n */\\ninterface HTMLStyleElement extends HTMLElement, LinkStyle {\\n    /**\\n     * Enables or disables the style sheet.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLStyleElement/disabled)\\n     */\\n    disabled: boolean;\\n    /**\\n     * Sets or retrieves the media type.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLStyleElement/media)\\n     */\\n    media: string;\\n    /**\\n     * Retrieves the CSS language in which the style sheet is written.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLStyleElement/type)\\n     */\\n    type: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLStyleElement: {\\n    prototype: HTMLStyleElement;\\n    new(): HTMLStyleElement;\\n};\\n\\n/**\\n * Special properties (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating table caption elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCaptionElement)\\n */\\ninterface HTMLTableCaptionElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves the alignment of the caption or legend.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCaptionElement/align)\\n     */\\n    align: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTableCaptionElement: {\\n    prototype: HTMLTableCaptionElement;\\n    new(): HTMLTableCaptionElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of table cells, either header or data cells, in an HTML document.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement)\\n */\\ninterface HTMLTableCellElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves abbreviated text for the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/abbr)\\n     */\\n    abbr: string;\\n    /**\\n     * Sets or retrieves how the object is aligned with adjacent text.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/align)\\n     */\\n    align: string;\\n    /**\\n     * Sets or retrieves a comma-delimited list of conceptual categories associated with the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/axis)\\n     */\\n    axis: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/bgColor)\\n     */\\n    bgColor: string;\\n    /**\\n     * Retrieves the position of the object in the cells collection of a row.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/cellIndex)\\n     */\\n    readonly cellIndex: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/ch)\\n     */\\n    ch: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/chOff)\\n     */\\n    chOff: string;\\n    /**\\n     * Sets or retrieves the number columns in the table that the object should span.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/colSpan)\\n     */\\n    colSpan: number;\\n    /**\\n     * Sets or retrieves a list of header cells that provide information for the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/headers)\\n     */\\n    headers: string;\\n    /**\\n     * Sets or retrieves the height of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/height)\\n     */\\n    height: string;\\n    /**\\n     * Sets or retrieves whether the browser automatically performs wordwrap.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/noWrap)\\n     */\\n    noWrap: boolean;\\n    /**\\n     * Sets or retrieves how many rows in a table the cell should span.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/rowSpan)\\n     */\\n    rowSpan: number;\\n    /**\\n     * Sets or retrieves the group of cells in a table to which the object's information applies.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/scope)\\n     */\\n    scope: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/vAlign)\\n     */\\n    vAlign: string;\\n    /**\\n     * Sets or retrieves the width of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableCellElement/width)\\n     */\\n    width: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTableCellElement: {\\n    prototype: HTMLTableCellElement;\\n    new(): HTMLTableCellElement;\\n};\\n\\n/**\\n * Provides special properties (beyond the HTMLElement interface it also has available to it inheritance) for manipulating single or grouped table column elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableColElement)\\n */\\ninterface HTMLTableColElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves the alignment of the object relative to the display or table.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableColElement/align)\\n     */\\n    align: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableColElement/ch)\\n     */\\n    ch: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableColElement/chOff)\\n     */\\n    chOff: string;\\n    /**\\n     * Sets or retrieves the number of columns in the group.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableColElement/span)\\n     */\\n    span: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableColElement/vAlign)\\n     */\\n    vAlign: string;\\n    /**\\n     * Sets or retrieves the width of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableColElement/width)\\n     */\\n    width: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTableColElement: {\\n    prototype: HTMLTableColElement;\\n    new(): HTMLTableColElement;\\n};\\n\\n/** @deprecated prefer HTMLTableCellElement */\\ninterface HTMLTableDataCellElement extends HTMLTableCellElement {\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/**\\n * Provides special properties and methods (beyond the regular HTMLElement object interface it also has available to it by inheritance) for manipulating the layout and presentation of tables in an HTML document.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement)\\n */\\ninterface HTMLTableElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves a value that indicates the table alignment.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/align)\\n     */\\n    align: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/bgColor)\\n     */\\n    bgColor: string;\\n    /**\\n     * Sets or retrieves the width of the border to draw around the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/border)\\n     */\\n    border: string;\\n    /**\\n     * Retrieves the caption object of a table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/caption)\\n     */\\n    caption: HTMLTableCaptionElement | null;\\n    /**\\n     * Sets or retrieves the amount of space between the border of the cell and the content of the cell.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/cellPadding)\\n     */\\n    cellPadding: string;\\n    /**\\n     * Sets or retrieves the amount of space between cells in a table.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/cellSpacing)\\n     */\\n    cellSpacing: string;\\n    /**\\n     * Sets or retrieves the way the border frame around the table is displayed.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/frame)\\n     */\\n    frame: string;\\n    /**\\n     * Sets or retrieves the number of horizontal rows contained in the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/rows)\\n     */\\n    readonly rows: HTMLCollectionOf<HTMLTableRowElement>;\\n    /**\\n     * Sets or retrieves which dividing lines (inner borders) are displayed.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/rules)\\n     */\\n    rules: string;\\n    /**\\n     * Sets or retrieves a description and/or structure of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/summary)\\n     */\\n    summary: string;\\n    /**\\n     * Retrieves a collection of all tBody objects in the table. Objects in this collection are in source order.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/tBodies)\\n     */\\n    readonly tBodies: HTMLCollectionOf<HTMLTableSectionElement>;\\n    /**\\n     * Retrieves the tFoot object of the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/tFoot)\\n     */\\n    tFoot: HTMLTableSectionElement | null;\\n    /**\\n     * Retrieves the tHead object of the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/tHead)\\n     */\\n    tHead: HTMLTableSectionElement | null;\\n    /**\\n     * Sets or retrieves the width of the object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/width)\\n     */\\n    width: string;\\n    /**\\n     * Creates an empty caption element in the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/createCaption)\\n     */\\n    createCaption(): HTMLTableCaptionElement;\\n    /**\\n     * Creates an empty tBody element in the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/createTBody)\\n     */\\n    createTBody(): HTMLTableSectionElement;\\n    /**\\n     * Creates an empty tFoot element in the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/createTFoot)\\n     */\\n    createTFoot(): HTMLTableSectionElement;\\n    /**\\n     * Returns the tHead element object if successful, or null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/createTHead)\\n     */\\n    createTHead(): HTMLTableSectionElement;\\n    /**\\n     * Deletes the caption element and its contents from the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/deleteCaption)\\n     */\\n    deleteCaption(): void;\\n    /**\\n     * Removes the specified row (tr) from the element and from the rows collection.\\n     * @param index Number that specifies the zero-based position in the rows collection of the row to remove.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/deleteRow)\\n     */\\n    deleteRow(index: number): void;\\n    /**\\n     * Deletes the tFoot element and its contents from the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/deleteTFoot)\\n     */\\n    deleteTFoot(): void;\\n    /**\\n     * Deletes the tHead element and its contents from the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/deleteTHead)\\n     */\\n    deleteTHead(): void;\\n    /**\\n     * Creates a new row (tr) in the table, and adds the row to the rows collection.\\n     * @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableElement/insertRow)\\n     */\\n    insertRow(index?: number): HTMLTableRowElement;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTableElement: {\\n    prototype: HTMLTableElement;\\n    new(): HTMLTableElement;\\n};\\n\\n/** @deprecated prefer HTMLTableCellElement */\\ninterface HTMLTableHeaderCellElement extends HTMLTableCellElement {\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/**\\n * Provides special properties and methods (beyond the HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of rows in an HTML table.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement)\\n */\\ninterface HTMLTableRowElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves how the object is aligned with adjacent text.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/align)\\n     */\\n    align: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/bgColor)\\n     */\\n    bgColor: string;\\n    /**\\n     * Retrieves a collection of all cells in the table row.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/cells)\\n     */\\n    readonly cells: HTMLCollectionOf<HTMLTableCellElement>;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/ch)\\n     */\\n    ch: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/chOff)\\n     */\\n    chOff: string;\\n    /**\\n     * Retrieves the position of the object in the rows collection for the table.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/rowIndex)\\n     */\\n    readonly rowIndex: number;\\n    /**\\n     * Retrieves the position of the object in the collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/sectionRowIndex)\\n     */\\n    readonly sectionRowIndex: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/vAlign)\\n     */\\n    vAlign: string;\\n    /**\\n     * Removes the specified cell from the table row, as well as from the cells collection.\\n     * @param index Number that specifies the zero-based position of the cell to remove from the table row. If no value is provided, the last cell in the cells collection is deleted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/deleteCell)\\n     */\\n    deleteCell(index: number): void;\\n    /**\\n     * Creates a new cell in the table row, and adds the cell to the cells collection.\\n     * @param index Number that specifies where to insert the cell in the tr. The default value is -1, which appends the new cell to the end of the cells collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableRowElement/insertCell)\\n     */\\n    insertCell(index?: number): HTMLTableCellElement;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTableRowElement: {\\n    prototype: HTMLTableRowElement;\\n    new(): HTMLTableRowElement;\\n};\\n\\n/**\\n * Provides special properties and methods (beyond the HTMLElement interface it also has available to it by inheritance) for manipulating the layout and presentation of sections, that is headers, footers and bodies, in an HTML table.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableSectionElement)\\n */\\ninterface HTMLTableSectionElement extends HTMLElement {\\n    /**\\n     * Sets or retrieves a value that indicates the table alignment.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableSectionElement/align)\\n     */\\n    align: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableSectionElement/ch)\\n     */\\n    ch: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableSectionElement/chOff)\\n     */\\n    chOff: string;\\n    /**\\n     * Sets or retrieves the number of horizontal rows contained in the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableSectionElement/rows)\\n     */\\n    readonly rows: HTMLCollectionOf<HTMLTableRowElement>;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableSectionElement/vAlign)\\n     */\\n    vAlign: string;\\n    /**\\n     * Removes the specified row (tr) from the element and from the rows collection.\\n     * @param index Number that specifies the zero-based position in the rows collection of the row to remove.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableSectionElement/deleteRow)\\n     */\\n    deleteRow(index: number): void;\\n    /**\\n     * Creates a new row (tr) in the table, and adds the row to the rows collection.\\n     * @param index Number that specifies where to insert the row in the rows collection. The default value is -1, which appends the new row to the end of the rows collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTableSectionElement/insertRow)\\n     */\\n    insertRow(index?: number): HTMLTableRowElement;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTableSectionElement: {\\n    prototype: HTMLTableSectionElement;\\n    new(): HTMLTableSectionElement;\\n};\\n\\n/**\\n * Enables access to the contents of an HTML <template> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTemplateElement)\\n */\\ninterface HTMLTemplateElement extends HTMLElement {\\n    /**\\n     * Returns the template contents (a DocumentFragment).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTemplateElement/content)\\n     */\\n    readonly content: DocumentFragment;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTemplateElement: {\\n    prototype: HTMLTemplateElement;\\n    new(): HTMLTemplateElement;\\n};\\n\\n/**\\n * Provides special properties and methods for manipulating the layout and presentation of <textarea> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTextAreaElement)\\n */\\ninterface HTMLTextAreaElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTextAreaElement/autocomplete) */\\n    autocomplete: AutoFill;\\n    /** Sets or retrieves the width of the object. */\\n    cols: number;\\n    /** Sets or retrieves the initial contents of the object. */\\n    defaultValue: string;\\n    dirName: string;\\n    disabled: boolean;\\n    /** Retrieves a reference to the form that the object is embedded in. */\\n    readonly form: HTMLFormElement | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTextAreaElement/labels) */\\n    readonly labels: NodeListOf<HTMLLabelElement>;\\n    /** Sets or retrieves the maximum number of characters that the user can enter in a text control. */\\n    maxLength: number;\\n    minLength: number;\\n    /** Sets or retrieves the name of the object. */\\n    name: string;\\n    /** Gets or sets a text string that is displayed in an input field as a hint or prompt to users as the format or type of information they need to enter.The text appears in an input field until the user puts focus on the field. */\\n    placeholder: string;\\n    /** Sets or retrieves the value indicated whether the content of the object is read-only. */\\n    readOnly: boolean;\\n    /** When present, marks an element that can't be submitted without a value. */\\n    required: boolean;\\n    /** Sets or retrieves the number of horizontal rows contained in the object. */\\n    rows: number;\\n    selectionDirection: \\\"forward\\\" | \\\"backward\\\" | \\\"none\\\";\\n    /** Gets or sets the end position or offset of a text selection. */\\n    selectionEnd: number;\\n    /** Gets or sets the starting position or offset of a text selection. */\\n    selectionStart: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTextAreaElement/textLength) */\\n    readonly textLength: number;\\n    /** Retrieves the type of control. */\\n    readonly type: string;\\n    /** Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as \\\"this is a required field\\\". The result is that the user sees validation messages without actually submitting. */\\n    readonly validationMessage: string;\\n    /** Returns a  ValidityState object that represents the validity states of an element. */\\n    readonly validity: ValidityState;\\n    /** Retrieves or sets the text in the entry field of the textArea element. */\\n    value: string;\\n    /** Returns whether an element will successfully validate based on forms validation rules and constraints. */\\n    readonly willValidate: boolean;\\n    /** Sets or retrieves how to handle wordwrapping in the object. */\\n    wrap: string;\\n    /** Returns whether a form will validate when it is submitted, without having to submit it. */\\n    checkValidity(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTextAreaElement/reportValidity) */\\n    reportValidity(): boolean;\\n    /** Highlights the input area of a form element. */\\n    select(): void;\\n    /**\\n     * Sets a custom error message that is displayed when a form is submitted.\\n     * @param error Sets a custom error message that is displayed when a form is submitted.\\n     */\\n    setCustomValidity(error: string): void;\\n    setRangeText(replacement: string): void;\\n    setRangeText(replacement: string, start: number, end: number, selectionMode?: SelectionMode): void;\\n    /**\\n     * Sets the start and end positions of a selection in a text field.\\n     * @param start The offset into the text field for the start of the selection.\\n     * @param end The offset into the text field for the end of the selection.\\n     * @param direction The direction in which the selection is performed.\\n     */\\n    setSelectionRange(start: number | null, end: number | null, direction?: \\\"forward\\\" | \\\"backward\\\" | \\\"none\\\"): void;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTextAreaElement: {\\n    prototype: HTMLTextAreaElement;\\n    new(): HTMLTextAreaElement;\\n};\\n\\n/**\\n * Provides special properties (beyond the regular HTMLElement interface it also has available to it by inheritance) for manipulating <time> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTimeElement)\\n */\\ninterface HTMLTimeElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTimeElement/dateTime) */\\n    dateTime: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTimeElement: {\\n    prototype: HTMLTimeElement;\\n    new(): HTMLTimeElement;\\n};\\n\\n/**\\n * Contains the title for a document. This element inherits all of the properties and methods of the HTMLElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTitleElement)\\n */\\ninterface HTMLTitleElement extends HTMLElement {\\n    /**\\n     * Retrieves or sets the text of the object as a string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTitleElement/text)\\n     */\\n    text: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTitleElement: {\\n    prototype: HTMLTitleElement;\\n    new(): HTMLTitleElement;\\n};\\n\\n/**\\n * The HTMLTrackElement\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement)\\n */\\ninterface HTMLTrackElement extends HTMLElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/default) */\\n    default: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/kind) */\\n    kind: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/label) */\\n    label: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/readyState) */\\n    readonly readyState: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/src) */\\n    src: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/srclang) */\\n    srclang: string;\\n    /**\\n     * Returns the TextTrack object corresponding to the text track of the track element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/track)\\n     */\\n    readonly track: TextTrack;\\n    readonly NONE: 0;\\n    readonly LOADING: 1;\\n    readonly LOADED: 2;\\n    readonly ERROR: 3;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLTrackElement: {\\n    prototype: HTMLTrackElement;\\n    new(): HTMLTrackElement;\\n    readonly NONE: 0;\\n    readonly LOADING: 1;\\n    readonly LOADED: 2;\\n    readonly ERROR: 3;\\n};\\n\\n/**\\n * Provides special properties (beyond those defined on the regular HTMLElement interface it also has available to it by inheritance) for manipulating unordered list elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLUListElement)\\n */\\ninterface HTMLUListElement extends HTMLElement {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLUListElement/compact)\\n     */\\n    compact: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLUListElement/type)\\n     */\\n    type: string;\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLUListElement: {\\n    prototype: HTMLUListElement;\\n    new(): HTMLUListElement;\\n};\\n\\n/**\\n * An invalid HTML element and derives from the HTMLElement interface, but without implementing any additional properties or methods.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLUnknownElement)\\n */\\ninterface HTMLUnknownElement extends HTMLElement {\\n    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLUnknownElement: {\\n    prototype: HTMLUnknownElement;\\n    new(): HTMLUnknownElement;\\n};\\n\\ninterface HTMLVideoElementEventMap extends HTMLMediaElementEventMap {\\n    \\\"enterpictureinpicture\\\": Event;\\n    \\\"leavepictureinpicture\\\": Event;\\n}\\n\\n/**\\n * Provides special properties and methods for manipulating video objects. It also inherits properties and methods of HTMLMediaElement and HTMLElement.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement)\\n */\\ninterface HTMLVideoElement extends HTMLMediaElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/disablePictureInPicture) */\\n    disablePictureInPicture: boolean;\\n    /**\\n     * Gets or sets the height of the video element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/height)\\n     */\\n    height: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/enterpictureinpicture_event) */\\n    onenterpictureinpicture: ((this: HTMLVideoElement, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/leavepictureinpicture_event) */\\n    onleavepictureinpicture: ((this: HTMLVideoElement, ev: Event) => any) | null;\\n    /** Gets or sets the playsinline of the video element. for example, On iPhone, video elements will now be allowed to play inline, and will not automatically enter fullscreen mode when playback begins. */\\n    playsInline: boolean;\\n    /**\\n     * Gets or sets a URL of an image to display, for example, like a movie poster. This can be a still frame from the video, or another image if no video data is available.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/poster)\\n     */\\n    poster: string;\\n    /**\\n     * Gets the intrinsic height of a video in CSS pixels, or zero if the dimensions are not known.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/videoHeight)\\n     */\\n    readonly videoHeight: number;\\n    /**\\n     * Gets the intrinsic width of a video in CSS pixels, or zero if the dimensions are not known.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/videoWidth)\\n     */\\n    readonly videoWidth: number;\\n    /**\\n     * Gets or sets the width of the video element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/width)\\n     */\\n    width: number;\\n    cancelVideoFrameCallback(handle: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/getVideoPlaybackQuality) */\\n    getVideoPlaybackQuality(): VideoPlaybackQuality;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/requestPictureInPicture) */\\n    requestPictureInPicture(): Promise<PictureInPictureWindow>;\\n    requestVideoFrameCallback(callback: VideoFrameRequestCallback): number;\\n    addEventListener<K extends keyof HTMLVideoElementEventMap>(type: K, listener: (this: HTMLVideoElement, ev: HTMLVideoElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof HTMLVideoElementEventMap>(type: K, listener: (this: HTMLVideoElement, ev: HTMLVideoElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var HTMLVideoElement: {\\n    prototype: HTMLVideoElement;\\n    new(): HTMLVideoElement;\\n};\\n\\n/**\\n * Events that fire when the fragment identifier of the URL has changed.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HashChangeEvent)\\n */\\ninterface HashChangeEvent extends Event {\\n    /**\\n     * Returns the URL of the session history entry that is now current.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HashChangeEvent/newURL)\\n     */\\n    readonly newURL: string;\\n    /**\\n     * Returns the URL of the session history entry that was previously current.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HashChangeEvent/oldURL)\\n     */\\n    readonly oldURL: string;\\n}\\n\\ndeclare var HashChangeEvent: {\\n    prototype: HashChangeEvent;\\n    new(type: string, eventInitDict?: HashChangeEventInit): HashChangeEvent;\\n};\\n\\n/**\\n * This Fetch API interface allows you to perform various actions on HTTP request and response headers. These actions include retrieving, setting, adding to, and removing. A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs.  You can add to this using methods like append() (see Examples.) In all methods of this interface, header names are matched by case-insensitive byte sequence.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers)\\n */\\ninterface Headers {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/append) */\\n    append(name: string, value: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/delete) */\\n    delete(name: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/get) */\\n    get(name: string): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/getSetCookie) */\\n    getSetCookie(): string[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/has) */\\n    has(name: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/set) */\\n    set(name: string, value: string): void;\\n    forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any): void;\\n}\\n\\ndeclare var Headers: {\\n    prototype: Headers;\\n    new(init?: HeadersInit): Headers;\\n};\\n\\n/**\\n * Allows manipulation of the browser session history, that is the pages visited in the tab or frame that the current page is loaded in.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/History)\\n */\\ninterface History {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/History/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/History/scrollRestoration) */\\n    scrollRestoration: ScrollRestoration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/History/state) */\\n    readonly state: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/History/back) */\\n    back(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/History/forward) */\\n    forward(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/History/go) */\\n    go(delta?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/History/pushState) */\\n    pushState(data: any, unused: string, url?: string | URL | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/History/replaceState) */\\n    replaceState(data: any, unused: string, url?: string | URL | null): void;\\n}\\n\\ndeclare var History: {\\n    prototype: History;\\n    new(): History;\\n};\\n\\n/**\\n * This IndexedDB API interface represents a cursor for traversing or iterating over multiple records in a database.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor)\\n */\\ninterface IDBCursor {\\n    /**\\n     * Returns the direction (\\\"next\\\", \\\"nextunique\\\", \\\"prev\\\" or \\\"prevunique\\\") of the cursor.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/direction)\\n     */\\n    readonly direction: IDBCursorDirection;\\n    /**\\n     * Returns the key of the cursor. Throws a \\\"InvalidStateError\\\" DOMException if the cursor is advancing or is finished.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/key)\\n     */\\n    readonly key: IDBValidKey;\\n    /**\\n     * Returns the effective key of the cursor. Throws a \\\"InvalidStateError\\\" DOMException if the cursor is advancing or is finished.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/primaryKey)\\n     */\\n    readonly primaryKey: IDBValidKey;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/request) */\\n    readonly request: IDBRequest;\\n    /**\\n     * Returns the IDBObjectStore or IDBIndex the cursor was opened from.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/source)\\n     */\\n    readonly source: IDBObjectStore | IDBIndex;\\n    /**\\n     * Advances the cursor through the next count records in range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/advance)\\n     */\\n    advance(count: number): void;\\n    /**\\n     * Advances the cursor to the next record in range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/continue)\\n     */\\n    continue(key?: IDBValidKey): void;\\n    /**\\n     * Advances the cursor to the next record in range matching or after key and primaryKey. Throws an \\\"InvalidAccessError\\\" DOMException if the source is not an index.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/continuePrimaryKey)\\n     */\\n    continuePrimaryKey(key: IDBValidKey, primaryKey: IDBValidKey): void;\\n    /**\\n     * Delete the record pointed at by the cursor with a new value.\\n     *\\n     * If successful, request's result will be undefined.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/delete)\\n     */\\n    delete(): IDBRequest<undefined>;\\n    /**\\n     * Updated the record pointed at by the cursor with a new value.\\n     *\\n     * Throws a \\\"DataError\\\" DOMException if the effective object store uses in-line keys and the key would have changed.\\n     *\\n     * If successful, request's result will be the record's key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/update)\\n     */\\n    update(value: any): IDBRequest<IDBValidKey>;\\n}\\n\\ndeclare var IDBCursor: {\\n    prototype: IDBCursor;\\n    new(): IDBCursor;\\n};\\n\\n/**\\n * This IndexedDB API interface represents a cursor for traversing or iterating over multiple records in a database. It is the same as the IDBCursor, except that it includes the value property.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursorWithValue)\\n */\\ninterface IDBCursorWithValue extends IDBCursor {\\n    /**\\n     * Returns the cursor's current value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursorWithValue/value)\\n     */\\n    readonly value: any;\\n}\\n\\ndeclare var IDBCursorWithValue: {\\n    prototype: IDBCursorWithValue;\\n    new(): IDBCursorWithValue;\\n};\\n\\ninterface IDBDatabaseEventMap {\\n    \\\"abort\\\": Event;\\n    \\\"close\\\": Event;\\n    \\\"error\\\": Event;\\n    \\\"versionchange\\\": IDBVersionChangeEvent;\\n}\\n\\n/**\\n * This IndexedDB API interface provides a connection to a database; you can use an IDBDatabase object to open a transaction on your database then create, manipulate, and delete objects (data) in that database. The interface provides the only way to get and manage versions of the database.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase)\\n */\\ninterface IDBDatabase extends EventTarget {\\n    /**\\n     * Returns the name of the database.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/name)\\n     */\\n    readonly name: string;\\n    /**\\n     * Returns a list of the names of object stores in the database.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/objectStoreNames)\\n     */\\n    readonly objectStoreNames: DOMStringList;\\n    onabort: ((this: IDBDatabase, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/close_event) */\\n    onclose: ((this: IDBDatabase, ev: Event) => any) | null;\\n    onerror: ((this: IDBDatabase, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/versionchange_event) */\\n    onversionchange: ((this: IDBDatabase, ev: IDBVersionChangeEvent) => any) | null;\\n    /**\\n     * Returns the version of the database.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/version)\\n     */\\n    readonly version: number;\\n    /**\\n     * Closes the connection once all running transactions have finished.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/close)\\n     */\\n    close(): void;\\n    /**\\n     * Creates a new object store with the given name and options and returns a new IDBObjectStore.\\n     *\\n     * Throws a \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/createObjectStore)\\n     */\\n    createObjectStore(name: string, options?: IDBObjectStoreParameters): IDBObjectStore;\\n    /**\\n     * Deletes the object store with the given name.\\n     *\\n     * Throws a \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/deleteObjectStore)\\n     */\\n    deleteObjectStore(name: string): void;\\n    /**\\n     * Returns a new transaction with the given mode (\\\"readonly\\\" or \\\"readwrite\\\") and scope which can be a single object store name or an array of names.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/transaction)\\n     */\\n    transaction(storeNames: string | string[], mode?: IDBTransactionMode, options?: IDBTransactionOptions): IDBTransaction;\\n    addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var IDBDatabase: {\\n    prototype: IDBDatabase;\\n    new(): IDBDatabase;\\n};\\n\\n/**\\n * In the following code snippet, we make a request to open a database, and include handlers for the success and error cases. For a full working example, see our To-do Notifications app (view example live.)\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory)\\n */\\ninterface IDBFactory {\\n    /**\\n     * Compares two values as keys. Returns -1 if key1 precedes key2, 1 if key2 precedes key1, and 0 if the keys are equal.\\n     *\\n     * Throws a \\\"DataError\\\" DOMException if either input is not a valid key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory/cmp)\\n     */\\n    cmp(first: any, second: any): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory/databases) */\\n    databases(): Promise<IDBDatabaseInfo[]>;\\n    /**\\n     * Attempts to delete the named database. If the database already exists and there are open connections that don't close in response to a versionchange event, the request will be blocked until all they close. If the request is successful request's result will be null.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory/deleteDatabase)\\n     */\\n    deleteDatabase(name: string): IDBOpenDBRequest;\\n    /**\\n     * Attempts to open a connection to the named database with the current version, or 1 if it does not already exist. If the request is successful request's result will be the connection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory/open)\\n     */\\n    open(name: string, version?: number): IDBOpenDBRequest;\\n}\\n\\ndeclare var IDBFactory: {\\n    prototype: IDBFactory;\\n    new(): IDBFactory;\\n};\\n\\n/**\\n * IDBIndex interface of the IndexedDB API provides asynchronous access to an index in a database. An index is a kind of object store for looking up records in another object store, called the referenced object store. You use this interface to retrieve data.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex)\\n */\\ninterface IDBIndex {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/keyPath) */\\n    readonly keyPath: string | string[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/multiEntry) */\\n    readonly multiEntry: boolean;\\n    /**\\n     * Returns the name of the index.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/name)\\n     */\\n    name: string;\\n    /**\\n     * Returns the IDBObjectStore the index belongs to.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/objectStore)\\n     */\\n    readonly objectStore: IDBObjectStore;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/unique) */\\n    readonly unique: boolean;\\n    /**\\n     * Retrieves the number of records matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the count.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/count)\\n     */\\n    count(query?: IDBValidKey | IDBKeyRange): IDBRequest<number>;\\n    /**\\n     * Retrieves the value of the first record matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the value, or undefined if there was no matching record.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/get)\\n     */\\n    get(query: IDBValidKey | IDBKeyRange): IDBRequest<any>;\\n    /**\\n     * Retrieves the values of the records matching the given key or key range in query (up to count if given).\\n     *\\n     * If successful, request's result will be an Array of the values.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/getAll)\\n     */\\n    getAll(query?: IDBValidKey | IDBKeyRange | null, count?: number): IDBRequest<any[]>;\\n    /**\\n     * Retrieves the keys of records matching the given key or key range in query (up to count if given).\\n     *\\n     * If successful, request's result will be an Array of the keys.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/getAllKeys)\\n     */\\n    getAllKeys(query?: IDBValidKey | IDBKeyRange | null, count?: number): IDBRequest<IDBValidKey[]>;\\n    /**\\n     * Retrieves the key of the first record matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the key, or undefined if there was no matching record.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/getKey)\\n     */\\n    getKey(query: IDBValidKey | IDBKeyRange): IDBRequest<IDBValidKey | undefined>;\\n    /**\\n     * Opens a cursor over the records matching query, ordered by direction. If query is null, all records in index are matched.\\n     *\\n     * If successful, request's result will be an IDBCursorWithValue, or null if there were no matching records.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/openCursor)\\n     */\\n    openCursor(query?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null>;\\n    /**\\n     * Opens a cursor with key only flag set over the records matching query, ordered by direction. If query is null, all records in index are matched.\\n     *\\n     * If successful, request's result will be an IDBCursor, or null if there were no matching records.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/openKeyCursor)\\n     */\\n    openKeyCursor(query?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection): IDBRequest<IDBCursor | null>;\\n}\\n\\ndeclare var IDBIndex: {\\n    prototype: IDBIndex;\\n    new(): IDBIndex;\\n};\\n\\n/**\\n * A key range can be a single value or a range with upper and lower bounds or endpoints. If the key range has both upper and lower bounds, then it is bounded; if it has no bounds, it is unbounded. A bounded key range can either be open (the endpoints are excluded) or closed (the endpoints are included). To retrieve all keys within a certain range, you can use the following code constructs:\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange)\\n */\\ninterface IDBKeyRange {\\n    /**\\n     * Returns lower bound, or undefined if none.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/lower)\\n     */\\n    readonly lower: any;\\n    /**\\n     * Returns true if the lower open flag is set, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/lowerOpen)\\n     */\\n    readonly lowerOpen: boolean;\\n    /**\\n     * Returns upper bound, or undefined if none.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/upper)\\n     */\\n    readonly upper: any;\\n    /**\\n     * Returns true if the upper open flag is set, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/upperOpen)\\n     */\\n    readonly upperOpen: boolean;\\n    /**\\n     * Returns true if key is included in the range, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/includes)\\n     */\\n    includes(key: any): boolean;\\n}\\n\\ndeclare var IDBKeyRange: {\\n    prototype: IDBKeyRange;\\n    new(): IDBKeyRange;\\n    /**\\n     * Returns a new IDBKeyRange spanning from lower to upper. If lowerOpen is true, lower is not included in the range. If upperOpen is true, upper is not included in the range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/bound_static)\\n     */\\n    bound(lower: any, upper: any, lowerOpen?: boolean, upperOpen?: boolean): IDBKeyRange;\\n    /**\\n     * Returns a new IDBKeyRange starting at key with no upper bound. If open is true, key is not included in the range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/lowerBound_static)\\n     */\\n    lowerBound(lower: any, open?: boolean): IDBKeyRange;\\n    /**\\n     * Returns a new IDBKeyRange spanning only key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/only_static)\\n     */\\n    only(value: any): IDBKeyRange;\\n    /**\\n     * Returns a new IDBKeyRange with no lower bound and ending at key. If open is true, key is not included in the range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/upperBound_static)\\n     */\\n    upperBound(upper: any, open?: boolean): IDBKeyRange;\\n};\\n\\n/**\\n * This example shows a variety of different uses of object stores, from updating the data structure with IDBObjectStore.createIndex inside an onupgradeneeded function, to adding a new item to our object store with IDBObjectStore.add. For a full working example, see our To-do Notifications app (view example live.)\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore)\\n */\\ninterface IDBObjectStore {\\n    /**\\n     * Returns true if the store has a key generator, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/autoIncrement)\\n     */\\n    readonly autoIncrement: boolean;\\n    /**\\n     * Returns a list of the names of indexes in the store.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/indexNames)\\n     */\\n    readonly indexNames: DOMStringList;\\n    /**\\n     * Returns the key path of the store, or null if none.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/keyPath)\\n     */\\n    readonly keyPath: string | string[];\\n    /**\\n     * Returns the name of the store.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/name)\\n     */\\n    name: string;\\n    /**\\n     * Returns the associated transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/transaction)\\n     */\\n    readonly transaction: IDBTransaction;\\n    /**\\n     * Adds or updates a record in store with the given value and key.\\n     *\\n     * If the store uses in-line keys and key is specified a \\\"DataError\\\" DOMException will be thrown.\\n     *\\n     * If put() is used, any existing record with the key will be replaced. If add() is used, and if a record with the key already exists the request will fail, with request's error set to a \\\"ConstraintError\\\" DOMException.\\n     *\\n     * If successful, request's result will be the record's key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/add)\\n     */\\n    add(value: any, key?: IDBValidKey): IDBRequest<IDBValidKey>;\\n    /**\\n     * Deletes all records in store.\\n     *\\n     * If successful, request's result will be undefined.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/clear)\\n     */\\n    clear(): IDBRequest<undefined>;\\n    /**\\n     * Retrieves the number of records matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the count.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/count)\\n     */\\n    count(query?: IDBValidKey | IDBKeyRange): IDBRequest<number>;\\n    /**\\n     * Creates a new index in store with the given name, keyPath and options and returns a new IDBIndex. If the keyPath and options define constraints that cannot be satisfied with the data already in store the upgrade transaction will abort with a \\\"ConstraintError\\\" DOMException.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/createIndex)\\n     */\\n    createIndex(name: string, keyPath: string | string[], options?: IDBIndexParameters): IDBIndex;\\n    /**\\n     * Deletes records in store with the given key or in the given key range in query.\\n     *\\n     * If successful, request's result will be undefined.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/delete)\\n     */\\n    delete(query: IDBValidKey | IDBKeyRange): IDBRequest<undefined>;\\n    /**\\n     * Deletes the index in store with the given name.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/deleteIndex)\\n     */\\n    deleteIndex(name: string): void;\\n    /**\\n     * Retrieves the value of the first record matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the value, or undefined if there was no matching record.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/get)\\n     */\\n    get(query: IDBValidKey | IDBKeyRange): IDBRequest<any>;\\n    /**\\n     * Retrieves the values of the records matching the given key or key range in query (up to count if given).\\n     *\\n     * If successful, request's result will be an Array of the values.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getAll)\\n     */\\n    getAll(query?: IDBValidKey | IDBKeyRange | null, count?: number): IDBRequest<any[]>;\\n    /**\\n     * Retrieves the keys of records matching the given key or key range in query (up to count if given).\\n     *\\n     * If successful, request's result will be an Array of the keys.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getAllKeys)\\n     */\\n    getAllKeys(query?: IDBValidKey | IDBKeyRange | null, count?: number): IDBRequest<IDBValidKey[]>;\\n    /**\\n     * Retrieves the key of the first record matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the key, or undefined if there was no matching record.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getKey)\\n     */\\n    getKey(query: IDBValidKey | IDBKeyRange): IDBRequest<IDBValidKey | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/index) */\\n    index(name: string): IDBIndex;\\n    /**\\n     * Opens a cursor over the records matching query, ordered by direction. If query is null, all records in store are matched.\\n     *\\n     * If successful, request's result will be an IDBCursorWithValue pointing at the first matching record, or null if there were no matching records.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/openCursor)\\n     */\\n    openCursor(query?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null>;\\n    /**\\n     * Opens a cursor with key only flag set over the records matching query, ordered by direction. If query is null, all records in store are matched.\\n     *\\n     * If successful, request's result will be an IDBCursor pointing at the first matching record, or null if there were no matching records.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/openKeyCursor)\\n     */\\n    openKeyCursor(query?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection): IDBRequest<IDBCursor | null>;\\n    /**\\n     * Adds or updates a record in store with the given value and key.\\n     *\\n     * If the store uses in-line keys and key is specified a \\\"DataError\\\" DOMException will be thrown.\\n     *\\n     * If put() is used, any existing record with the key will be replaced. If add() is used, and if a record with the key already exists the request will fail, with request's error set to a \\\"ConstraintError\\\" DOMException.\\n     *\\n     * If successful, request's result will be the record's key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/put)\\n     */\\n    put(value: any, key?: IDBValidKey): IDBRequest<IDBValidKey>;\\n}\\n\\ndeclare var IDBObjectStore: {\\n    prototype: IDBObjectStore;\\n    new(): IDBObjectStore;\\n};\\n\\ninterface IDBOpenDBRequestEventMap extends IDBRequestEventMap {\\n    \\\"blocked\\\": IDBVersionChangeEvent;\\n    \\\"upgradeneeded\\\": IDBVersionChangeEvent;\\n}\\n\\n/**\\n * Also inherits methods from its parents IDBRequest and EventTarget.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBOpenDBRequest)\\n */\\ninterface IDBOpenDBRequest extends IDBRequest<IDBDatabase> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBOpenDBRequest/blocked_event) */\\n    onblocked: ((this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBOpenDBRequest/upgradeneeded_event) */\\n    onupgradeneeded: ((this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any) | null;\\n    addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var IDBOpenDBRequest: {\\n    prototype: IDBOpenDBRequest;\\n    new(): IDBOpenDBRequest;\\n};\\n\\ninterface IDBRequestEventMap {\\n    \\\"error\\\": Event;\\n    \\\"success\\\": Event;\\n}\\n\\n/**\\n * The request object does not initially contain any information about the result of the operation, but once information becomes available, an event is fired on the request, and the information becomes available through the properties of the IDBRequest instance.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest)\\n */\\ninterface IDBRequest<T = any> extends EventTarget {\\n    /**\\n     * When a request is completed, returns the error (a DOMException), or null if the request succeeded. Throws a \\\"InvalidStateError\\\" DOMException if the request is still pending.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/error)\\n     */\\n    readonly error: DOMException | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/error_event) */\\n    onerror: ((this: IDBRequest<T>, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/success_event) */\\n    onsuccess: ((this: IDBRequest<T>, ev: Event) => any) | null;\\n    /**\\n     * Returns \\\"pending\\\" until a request is complete, then returns \\\"done\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/readyState)\\n     */\\n    readonly readyState: IDBRequestReadyState;\\n    /**\\n     * When a request is completed, returns the result, or undefined if the request failed. Throws a \\\"InvalidStateError\\\" DOMException if the request is still pending.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/result)\\n     */\\n    readonly result: T;\\n    /**\\n     * Returns the IDBObjectStore, IDBIndex, or IDBCursor the request was made against, or null if is was an open request.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/source)\\n     */\\n    readonly source: IDBObjectStore | IDBIndex | IDBCursor;\\n    /**\\n     * Returns the IDBTransaction the request was made within. If this as an open request, then it returns an upgrade transaction while it is running, or null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/transaction)\\n     */\\n    readonly transaction: IDBTransaction | null;\\n    addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest<T>, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest<T>, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var IDBRequest: {\\n    prototype: IDBRequest;\\n    new(): IDBRequest;\\n};\\n\\ninterface IDBTransactionEventMap {\\n    \\\"abort\\\": Event;\\n    \\\"complete\\\": Event;\\n    \\\"error\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction) */\\ninterface IDBTransaction extends EventTarget {\\n    /**\\n     * Returns the transaction's connection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/db)\\n     */\\n    readonly db: IDBDatabase;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/durability) */\\n    readonly durability: IDBTransactionDurability;\\n    /**\\n     * If the transaction was aborted, returns the error (a DOMException) providing the reason.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/error)\\n     */\\n    readonly error: DOMException | null;\\n    /**\\n     * Returns the mode the transaction was created with (\\\"readonly\\\" or \\\"readwrite\\\"), or \\\"versionchange\\\" for an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/mode)\\n     */\\n    readonly mode: IDBTransactionMode;\\n    /**\\n     * Returns a list of the names of object stores in the transaction's scope. For an upgrade transaction this is all object stores in the database.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/objectStoreNames)\\n     */\\n    readonly objectStoreNames: DOMStringList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/abort_event) */\\n    onabort: ((this: IDBTransaction, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/complete_event) */\\n    oncomplete: ((this: IDBTransaction, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/error_event) */\\n    onerror: ((this: IDBTransaction, ev: Event) => any) | null;\\n    /**\\n     * Aborts the transaction. All pending requests will fail with a \\\"AbortError\\\" DOMException and all changes made to the database will be reverted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/abort)\\n     */\\n    abort(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/commit) */\\n    commit(): void;\\n    /**\\n     * Returns an IDBObjectStore in the transaction's scope.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/objectStore)\\n     */\\n    objectStore(name: string): IDBObjectStore;\\n    addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var IDBTransaction: {\\n    prototype: IDBTransaction;\\n    new(): IDBTransaction;\\n};\\n\\n/**\\n * This IndexedDB API interface indicates that the version of the database has changed, as the result of an IDBOpenDBRequest.onupgradeneeded event handler function.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBVersionChangeEvent)\\n */\\ninterface IDBVersionChangeEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBVersionChangeEvent/newVersion) */\\n    readonly newVersion: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBVersionChangeEvent/oldVersion) */\\n    readonly oldVersion: number;\\n}\\n\\ndeclare var IDBVersionChangeEvent: {\\n    prototype: IDBVersionChangeEvent;\\n    new(type: string, eventInitDict?: IDBVersionChangeEventInit): IDBVersionChangeEvent;\\n};\\n\\n/**\\n * The IIRFilterNode interface of the Web Audio API is a AudioNode processor which implements a general infinite impulse response (IIR)  filter; this type of filter can be used to implement tone control devices and graphic equalizers as well. It lets the parameters of the filter response be specified, so that it can be tuned as needed.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IIRFilterNode)\\n */\\ninterface IIRFilterNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IIRFilterNode/getFrequencyResponse) */\\n    getFrequencyResponse(frequencyHz: Float32Array, magResponse: Float32Array, phaseResponse: Float32Array): void;\\n}\\n\\ndeclare var IIRFilterNode: {\\n    prototype: IIRFilterNode;\\n    new(context: BaseAudioContext, options: IIRFilterOptions): IIRFilterNode;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IdleDeadline) */\\ninterface IdleDeadline {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IdleDeadline/didTimeout) */\\n    readonly didTimeout: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IdleDeadline/timeRemaining) */\\n    timeRemaining(): DOMHighResTimeStamp;\\n}\\n\\ndeclare var IdleDeadline: {\\n    prototype: IdleDeadline;\\n    new(): IdleDeadline;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmap) */\\ninterface ImageBitmap {\\n    /**\\n     * Returns the intrinsic height of the image, in CSS pixels.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmap/height)\\n     */\\n    readonly height: number;\\n    /**\\n     * Returns the intrinsic width of the image, in CSS pixels.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmap/width)\\n     */\\n    readonly width: number;\\n    /**\\n     * Releases imageBitmap's underlying bitmap data.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmap/close)\\n     */\\n    close(): void;\\n}\\n\\ndeclare var ImageBitmap: {\\n    prototype: ImageBitmap;\\n    new(): ImageBitmap;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmapRenderingContext) */\\ninterface ImageBitmapRenderingContext {\\n    /** Returns the canvas element that the context is bound to. */\\n    readonly canvas: HTMLCanvasElement | OffscreenCanvas;\\n    /**\\n     * Transfers the underlying bitmap data from imageBitmap to context, and the bitmap becomes the contents of the canvas element to which context is bound.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmapRenderingContext/transferFromImageBitmap)\\n     */\\n    transferFromImageBitmap(bitmap: ImageBitmap | null): void;\\n}\\n\\ndeclare var ImageBitmapRenderingContext: {\\n    prototype: ImageBitmapRenderingContext;\\n    new(): ImageBitmapRenderingContext;\\n};\\n\\n/**\\n * The underlying pixel data of an area of a <canvas> element. It is created using the ImageData() constructor or creator methods on the CanvasRenderingContext2D object associated with a canvas: createImageData() and getImageData(). It can also be used to set a part of the canvas by using putImageData().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData)\\n */\\ninterface ImageData {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData/colorSpace) */\\n    readonly colorSpace: PredefinedColorSpace;\\n    /**\\n     * Returns the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData/data)\\n     */\\n    readonly data: Uint8ClampedArray;\\n    /**\\n     * Returns the actual dimensions of the data in the ImageData object, in pixels.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData/height)\\n     */\\n    readonly height: number;\\n    /**\\n     * Returns the actual dimensions of the data in the ImageData object, in pixels.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData/width)\\n     */\\n    readonly width: number;\\n}\\n\\ndeclare var ImageData: {\\n    prototype: ImageData;\\n    new(sw: number, sh: number, settings?: ImageDataSettings): ImageData;\\n    new(data: Uint8ClampedArray, sw: number, sh?: number, settings?: ImageDataSettings): ImageData;\\n};\\n\\ninterface InnerHTML {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) */\\n    innerHTML: string;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/InputDeviceInfo)\\n */\\ninterface InputDeviceInfo extends MediaDeviceInfo {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/InputDeviceInfo/getCapabilities) */\\n    getCapabilities(): MediaTrackCapabilities;\\n}\\n\\ndeclare var InputDeviceInfo: {\\n    prototype: InputDeviceInfo;\\n    new(): InputDeviceInfo;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/InputEvent) */\\ninterface InputEvent extends UIEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/InputEvent/data) */\\n    readonly data: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/InputEvent/dataTransfer) */\\n    readonly dataTransfer: DataTransfer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/InputEvent/inputType) */\\n    readonly inputType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/InputEvent/isComposing) */\\n    readonly isComposing: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/InputEvent/getTargetRanges) */\\n    getTargetRanges(): StaticRange[];\\n}\\n\\ndeclare var InputEvent: {\\n    prototype: InputEvent;\\n    new(type: string, eventInitDict?: InputEventInit): InputEvent;\\n};\\n\\n/**\\n * provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserver)\\n */\\ninterface IntersectionObserver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/root) */\\n    readonly root: Element | Document | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/rootMargin) */\\n    readonly rootMargin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/thresholds) */\\n    readonly thresholds: ReadonlyArray<number>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/disconnect) */\\n    disconnect(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/observe) */\\n    observe(target: Element): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/takeRecords) */\\n    takeRecords(): IntersectionObserverEntry[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserver/unobserve) */\\n    unobserve(target: Element): void;\\n}\\n\\ndeclare var IntersectionObserver: {\\n    prototype: IntersectionObserver;\\n    new(callback: IntersectionObserverCallback, options?: IntersectionObserverInit): IntersectionObserver;\\n};\\n\\n/**\\n * This Intersection Observer API interface describes the intersection between the target element and its root container at a specific moment of transition.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry)\\n */\\ninterface IntersectionObserverEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/boundingClientRect) */\\n    readonly boundingClientRect: DOMRectReadOnly;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/intersectionRatio) */\\n    readonly intersectionRatio: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/intersectionRect) */\\n    readonly intersectionRect: DOMRectReadOnly;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/isIntersecting) */\\n    readonly isIntersecting: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/rootBounds) */\\n    readonly rootBounds: DOMRectReadOnly | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/target) */\\n    readonly target: Element;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IntersectionObserverEntry/time) */\\n    readonly time: DOMHighResTimeStamp;\\n}\\n\\ndeclare var IntersectionObserverEntry: {\\n    prototype: IntersectionObserverEntry;\\n    new(intersectionObserverEntryInit: IntersectionObserverEntryInit): IntersectionObserverEntry;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KHR_parallel_shader_compile) */\\ninterface KHR_parallel_shader_compile {\\n    readonly COMPLETION_STATUS_KHR: 0x91B1;\\n}\\n\\n/**\\n * KeyboardEvent objects describe a user interaction with the keyboard; each event describes a single interaction between the user and a key (or combination of a key with modifier keys) on the keyboard.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent)\\n */\\ninterface KeyboardEvent extends UIEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/altKey) */\\n    readonly altKey: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/charCode)\\n     */\\n    readonly charCode: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/code) */\\n    readonly code: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/ctrlKey) */\\n    readonly ctrlKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/isComposing) */\\n    readonly isComposing: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/key) */\\n    readonly key: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/keyCode)\\n     */\\n    readonly keyCode: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/location) */\\n    readonly location: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/metaKey) */\\n    readonly metaKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/repeat) */\\n    readonly repeat: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/shiftKey) */\\n    readonly shiftKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyboardEvent/getModifierState) */\\n    getModifierState(keyArg: string): boolean;\\n    /** @deprecated */\\n    initKeyboardEvent(typeArg: string, bubblesArg?: boolean, cancelableArg?: boolean, viewArg?: Window | null, keyArg?: string, locationArg?: number, ctrlKey?: boolean, altKey?: boolean, shiftKey?: boolean, metaKey?: boolean): void;\\n    readonly DOM_KEY_LOCATION_STANDARD: 0x00;\\n    readonly DOM_KEY_LOCATION_LEFT: 0x01;\\n    readonly DOM_KEY_LOCATION_RIGHT: 0x02;\\n    readonly DOM_KEY_LOCATION_NUMPAD: 0x03;\\n}\\n\\ndeclare var KeyboardEvent: {\\n    prototype: KeyboardEvent;\\n    new(type: string, eventInitDict?: KeyboardEventInit): KeyboardEvent;\\n    readonly DOM_KEY_LOCATION_STANDARD: 0x00;\\n    readonly DOM_KEY_LOCATION_LEFT: 0x01;\\n    readonly DOM_KEY_LOCATION_RIGHT: 0x02;\\n    readonly DOM_KEY_LOCATION_NUMPAD: 0x03;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyframeEffect) */\\ninterface KeyframeEffect extends AnimationEffect {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyframeEffect/composite) */\\n    composite: CompositeOperation;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyframeEffect/iterationComposite) */\\n    iterationComposite: IterationCompositeOperation;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyframeEffect/pseudoElement) */\\n    pseudoElement: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyframeEffect/target) */\\n    target: Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyframeEffect/getKeyframes) */\\n    getKeyframes(): ComputedKeyframe[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KeyframeEffect/setKeyframes) */\\n    setKeyframes(keyframes: Keyframe[] | PropertyIndexedKeyframes | null): void;\\n}\\n\\ndeclare var KeyframeEffect: {\\n    prototype: KeyframeEffect;\\n    new(target: Element | null, keyframes: Keyframe[] | PropertyIndexedKeyframes | null, options?: number | KeyframeEffectOptions): KeyframeEffect;\\n    new(source: KeyframeEffect): KeyframeEffect;\\n};\\n\\ninterface LinkStyle {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement/sheet) */\\n    readonly sheet: CSSStyleSheet | null;\\n}\\n\\n/**\\n * The location (URL) of the object it is linked to. Changes done on it are reflected on the object it relates to. Both the Document and Window interface have such a linked Location, accessible via Document.location and Window.location respectively.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location)\\n */\\ninterface Location {\\n    /**\\n     * Returns a DOMStringList object listing the origins of the ancestor browsing contexts, from the parent browsing context to the top-level browsing context.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/ancestorOrigins)\\n     */\\n    readonly ancestorOrigins: DOMStringList;\\n    /**\\n     * Returns the Location object's URL's fragment (includes leading \\\"#\\\" if non-empty).\\n     *\\n     * Can be set, to navigate to the same URL with a changed fragment (ignores leading \\\"#\\\").\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/hash)\\n     */\\n    hash: string;\\n    /**\\n     * Returns the Location object's URL's host and port (if different from the default port for the scheme).\\n     *\\n     * Can be set, to navigate to the same URL with a changed host and port.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/host)\\n     */\\n    host: string;\\n    /**\\n     * Returns the Location object's URL's host.\\n     *\\n     * Can be set, to navigate to the same URL with a changed host.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/hostname)\\n     */\\n    hostname: string;\\n    /**\\n     * Returns the Location object's URL.\\n     *\\n     * Can be set, to navigate to the given URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/href)\\n     */\\n    href: string;\\n    toString(): string;\\n    /**\\n     * Returns the Location object's URL's origin.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/origin)\\n     */\\n    readonly origin: string;\\n    /**\\n     * Returns the Location object's URL's path.\\n     *\\n     * Can be set, to navigate to the same URL with a changed path.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/pathname)\\n     */\\n    pathname: string;\\n    /**\\n     * Returns the Location object's URL's port.\\n     *\\n     * Can be set, to navigate to the same URL with a changed port.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/port)\\n     */\\n    port: string;\\n    /**\\n     * Returns the Location object's URL's scheme.\\n     *\\n     * Can be set, to navigate to the same URL with a changed scheme.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/protocol)\\n     */\\n    protocol: string;\\n    /**\\n     * Returns the Location object's URL's query (includes leading \\\"?\\\" if non-empty).\\n     *\\n     * Can be set, to navigate to the same URL with a changed query (ignores leading \\\"?\\\").\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/search)\\n     */\\n    search: string;\\n    /**\\n     * Navigates to the given URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/assign)\\n     */\\n    assign(url: string | URL): void;\\n    /**\\n     * Reloads the current page.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/reload)\\n     */\\n    reload(): void;\\n    /**\\n     * Removes the current page from the session history and navigates to the given URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Location/replace)\\n     */\\n    replace(url: string | URL): void;\\n}\\n\\ndeclare var Location: {\\n    prototype: Location;\\n    new(): Location;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Lock)\\n */\\ninterface Lock {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Lock/mode) */\\n    readonly mode: LockMode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Lock/name) */\\n    readonly name: string;\\n}\\n\\ndeclare var Lock: {\\n    prototype: Lock;\\n    new(): Lock;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/LockManager)\\n */\\ninterface LockManager {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LockManager/query) */\\n    query(): Promise<LockManagerSnapshot>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LockManager/request) */\\n    request(name: string, callback: LockGrantedCallback): Promise<any>;\\n    request(name: string, options: LockOptions, callback: LockGrantedCallback): Promise<any>;\\n}\\n\\ndeclare var LockManager: {\\n    prototype: LockManager;\\n    new(): LockManager;\\n};\\n\\ninterface MIDIAccessEventMap {\\n    \\\"statechange\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIAccess)\\n */\\ninterface MIDIAccess extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIAccess/inputs) */\\n    readonly inputs: MIDIInputMap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIAccess/statechange_event) */\\n    onstatechange: ((this: MIDIAccess, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIAccess/outputs) */\\n    readonly outputs: MIDIOutputMap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIAccess/sysexEnabled) */\\n    readonly sysexEnabled: boolean;\\n    addEventListener<K extends keyof MIDIAccessEventMap>(type: K, listener: (this: MIDIAccess, ev: MIDIAccessEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MIDIAccessEventMap>(type: K, listener: (this: MIDIAccess, ev: MIDIAccessEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MIDIAccess: {\\n    prototype: MIDIAccess;\\n    new(): MIDIAccess;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIConnectionEvent)\\n */\\ninterface MIDIConnectionEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIConnectionEvent/port) */\\n    readonly port: MIDIPort;\\n}\\n\\ndeclare var MIDIConnectionEvent: {\\n    prototype: MIDIConnectionEvent;\\n    new(type: string, eventInitDict?: MIDIConnectionEventInit): MIDIConnectionEvent;\\n};\\n\\ninterface MIDIInputEventMap extends MIDIPortEventMap {\\n    \\\"midimessage\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIInput)\\n */\\ninterface MIDIInput extends MIDIPort {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIInput/midimessage_event) */\\n    onmidimessage: ((this: MIDIInput, ev: Event) => any) | null;\\n    addEventListener<K extends keyof MIDIInputEventMap>(type: K, listener: (this: MIDIInput, ev: MIDIInputEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MIDIInputEventMap>(type: K, listener: (this: MIDIInput, ev: MIDIInputEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MIDIInput: {\\n    prototype: MIDIInput;\\n    new(): MIDIInput;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIInputMap)\\n */\\ninterface MIDIInputMap {\\n    forEach(callbackfn: (value: MIDIInput, key: string, parent: MIDIInputMap) => void, thisArg?: any): void;\\n}\\n\\ndeclare var MIDIInputMap: {\\n    prototype: MIDIInputMap;\\n    new(): MIDIInputMap;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIMessageEvent)\\n */\\ninterface MIDIMessageEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIMessageEvent/data) */\\n    readonly data: Uint8Array;\\n}\\n\\ndeclare var MIDIMessageEvent: {\\n    prototype: MIDIMessageEvent;\\n    new(type: string, eventInitDict?: MIDIMessageEventInit): MIDIMessageEvent;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIOutput)\\n */\\ninterface MIDIOutput extends MIDIPort {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIOutput/send) */\\n    send(data: number[], timestamp?: DOMHighResTimeStamp): void;\\n    addEventListener<K extends keyof MIDIPortEventMap>(type: K, listener: (this: MIDIOutput, ev: MIDIPortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MIDIPortEventMap>(type: K, listener: (this: MIDIOutput, ev: MIDIPortEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MIDIOutput: {\\n    prototype: MIDIOutput;\\n    new(): MIDIOutput;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIOutputMap)\\n */\\ninterface MIDIOutputMap {\\n    forEach(callbackfn: (value: MIDIOutput, key: string, parent: MIDIOutputMap) => void, thisArg?: any): void;\\n}\\n\\ndeclare var MIDIOutputMap: {\\n    prototype: MIDIOutputMap;\\n    new(): MIDIOutputMap;\\n};\\n\\ninterface MIDIPortEventMap {\\n    \\\"statechange\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort)\\n */\\ninterface MIDIPort extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/connection) */\\n    readonly connection: MIDIPortConnectionState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/id) */\\n    readonly id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/manufacturer) */\\n    readonly manufacturer: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/name) */\\n    readonly name: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/statechange_event) */\\n    onstatechange: ((this: MIDIPort, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/state) */\\n    readonly state: MIDIPortDeviceState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/type) */\\n    readonly type: MIDIPortType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/version) */\\n    readonly version: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/close) */\\n    close(): Promise<MIDIPort>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIPort/open) */\\n    open(): Promise<MIDIPort>;\\n    addEventListener<K extends keyof MIDIPortEventMap>(type: K, listener: (this: MIDIPort, ev: MIDIPortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MIDIPortEventMap>(type: K, listener: (this: MIDIPort, ev: MIDIPortEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MIDIPort: {\\n    prototype: MIDIPort;\\n    new(): MIDIPort;\\n};\\n\\ninterface MathMLElementEventMap extends ElementEventMap, GlobalEventHandlersEventMap {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MathMLElement) */\\ninterface MathMLElement extends Element, ElementCSSInlineStyle, GlobalEventHandlers, HTMLOrSVGElement {\\n    addEventListener<K extends keyof MathMLElementEventMap>(type: K, listener: (this: MathMLElement, ev: MathMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MathMLElementEventMap>(type: K, listener: (this: MathMLElement, ev: MathMLElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MathMLElement: {\\n    prototype: MathMLElement;\\n    new(): MathMLElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaCapabilities) */\\ninterface MediaCapabilities {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaCapabilities/decodingInfo) */\\n    decodingInfo(configuration: MediaDecodingConfiguration): Promise<MediaCapabilitiesDecodingInfo>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaCapabilities/encodingInfo) */\\n    encodingInfo(configuration: MediaEncodingConfiguration): Promise<MediaCapabilitiesEncodingInfo>;\\n}\\n\\ndeclare var MediaCapabilities: {\\n    prototype: MediaCapabilities;\\n    new(): MediaCapabilities;\\n};\\n\\n/**\\n * The MediaDevicesInfo interface contains information that describes a single media input or output device.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDeviceInfo)\\n */\\ninterface MediaDeviceInfo {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDeviceInfo/deviceId) */\\n    readonly deviceId: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDeviceInfo/groupId) */\\n    readonly groupId: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDeviceInfo/kind) */\\n    readonly kind: MediaDeviceKind;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDeviceInfo/label) */\\n    readonly label: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDeviceInfo/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var MediaDeviceInfo: {\\n    prototype: MediaDeviceInfo;\\n    new(): MediaDeviceInfo;\\n};\\n\\ninterface MediaDevicesEventMap {\\n    \\\"devicechange\\\": Event;\\n}\\n\\n/**\\n * Provides access to connected media input devices like cameras and microphones, as well as screen sharing. In essence, it lets you obtain access to any hardware source of media data.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDevices)\\n */\\ninterface MediaDevices extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDevices/devicechange_event) */\\n    ondevicechange: ((this: MediaDevices, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDevices/enumerateDevices) */\\n    enumerateDevices(): Promise<MediaDeviceInfo[]>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDevices/getDisplayMedia) */\\n    getDisplayMedia(options?: DisplayMediaStreamOptions): Promise<MediaStream>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDevices/getSupportedConstraints) */\\n    getSupportedConstraints(): MediaTrackSupportedConstraints;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaDevices/getUserMedia) */\\n    getUserMedia(constraints?: MediaStreamConstraints): Promise<MediaStream>;\\n    addEventListener<K extends keyof MediaDevicesEventMap>(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MediaDevicesEventMap>(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MediaDevices: {\\n    prototype: MediaDevices;\\n    new(): MediaDevices;\\n};\\n\\n/**\\n * A MediaElementSourceNode has no inputs and exactly one output, and is created using the AudioContext.createMediaElementSource method. The amount of channels in the output equals the number of channels of the audio referenced by the HTMLMediaElement used in the creation of the node, or is 1 if the HTMLMediaElement has no audio.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaElementAudioSourceNode)\\n */\\ninterface MediaElementAudioSourceNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaElementAudioSourceNode/mediaElement) */\\n    readonly mediaElement: HTMLMediaElement;\\n}\\n\\ndeclare var MediaElementAudioSourceNode: {\\n    prototype: MediaElementAudioSourceNode;\\n    new(context: AudioContext, options: MediaElementAudioSourceOptions): MediaElementAudioSourceNode;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaEncryptedEvent) */\\ninterface MediaEncryptedEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaEncryptedEvent/initData) */\\n    readonly initData: ArrayBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaEncryptedEvent/initDataType) */\\n    readonly initDataType: string;\\n}\\n\\ndeclare var MediaEncryptedEvent: {\\n    prototype: MediaEncryptedEvent;\\n    new(type: string, eventInitDict?: MediaEncryptedEventInit): MediaEncryptedEvent;\\n};\\n\\n/**\\n * An error which occurred while handling media in an HTML media element based on HTMLMediaElement, such as <audio> or <video>.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaError)\\n */\\ninterface MediaError {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaError/code) */\\n    readonly code: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaError/message) */\\n    readonly message: string;\\n    readonly MEDIA_ERR_ABORTED: 1;\\n    readonly MEDIA_ERR_NETWORK: 2;\\n    readonly MEDIA_ERR_DECODE: 3;\\n    readonly MEDIA_ERR_SRC_NOT_SUPPORTED: 4;\\n}\\n\\ndeclare var MediaError: {\\n    prototype: MediaError;\\n    new(): MediaError;\\n    readonly MEDIA_ERR_ABORTED: 1;\\n    readonly MEDIA_ERR_NETWORK: 2;\\n    readonly MEDIA_ERR_DECODE: 3;\\n    readonly MEDIA_ERR_SRC_NOT_SUPPORTED: 4;\\n};\\n\\n/**\\n * This EncryptedMediaExtensions API interface contains the content and related data when the content decryption module generates a message for the session.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeyMessageEvent)\\n */\\ninterface MediaKeyMessageEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeyMessageEvent/message) */\\n    readonly message: ArrayBuffer;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeyMessageEvent/messageType) */\\n    readonly messageType: MediaKeyMessageType;\\n}\\n\\ndeclare var MediaKeyMessageEvent: {\\n    prototype: MediaKeyMessageEvent;\\n    new(type: string, eventInitDict: MediaKeyMessageEventInit): MediaKeyMessageEvent;\\n};\\n\\ninterface MediaKeySessionEventMap {\\n    \\\"keystatuseschange\\\": Event;\\n    \\\"message\\\": MediaKeyMessageEvent;\\n}\\n\\n/**\\n * This EncryptedMediaExtensions API interface represents a context for message exchange with a content decryption module (CDM).\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession)\\n */\\ninterface MediaKeySession extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/closed) */\\n    readonly closed: Promise<MediaKeySessionClosedReason>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/expiration) */\\n    readonly expiration: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/keyStatuses) */\\n    readonly keyStatuses: MediaKeyStatusMap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/keystatuseschange_event) */\\n    onkeystatuseschange: ((this: MediaKeySession, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/message_event) */\\n    onmessage: ((this: MediaKeySession, ev: MediaKeyMessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/sessionId) */\\n    readonly sessionId: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/close) */\\n    close(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/generateRequest) */\\n    generateRequest(initDataType: string, initData: BufferSource): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/load) */\\n    load(sessionId: string): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/remove) */\\n    remove(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySession/update) */\\n    update(response: BufferSource): Promise<void>;\\n    addEventListener<K extends keyof MediaKeySessionEventMap>(type: K, listener: (this: MediaKeySession, ev: MediaKeySessionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MediaKeySessionEventMap>(type: K, listener: (this: MediaKeySession, ev: MediaKeySessionEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MediaKeySession: {\\n    prototype: MediaKeySession;\\n    new(): MediaKeySession;\\n};\\n\\n/**\\n * This EncryptedMediaExtensions API interface is a read-only map of media key statuses by key IDs.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeyStatusMap)\\n */\\ninterface MediaKeyStatusMap {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeyStatusMap/size) */\\n    readonly size: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeyStatusMap/get) */\\n    get(keyId: BufferSource): MediaKeyStatus | undefined;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeyStatusMap/has) */\\n    has(keyId: BufferSource): boolean;\\n    forEach(callbackfn: (value: MediaKeyStatus, key: BufferSource, parent: MediaKeyStatusMap) => void, thisArg?: any): void;\\n}\\n\\ndeclare var MediaKeyStatusMap: {\\n    prototype: MediaKeyStatusMap;\\n    new(): MediaKeyStatusMap;\\n};\\n\\n/**\\n * This EncryptedMediaExtensions API interface provides access to a Key System for decryption and/or a content protection provider. You can request an instance of this object using the Navigator.requestMediaKeySystemAccess method.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySystemAccess)\\n */\\ninterface MediaKeySystemAccess {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySystemAccess/keySystem) */\\n    readonly keySystem: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySystemAccess/createMediaKeys) */\\n    createMediaKeys(): Promise<MediaKeys>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeySystemAccess/getConfiguration) */\\n    getConfiguration(): MediaKeySystemConfiguration;\\n}\\n\\ndeclare var MediaKeySystemAccess: {\\n    prototype: MediaKeySystemAccess;\\n    new(): MediaKeySystemAccess;\\n};\\n\\n/**\\n * This EncryptedMediaExtensions API interface the represents a set of keys that an associated HTMLMediaElement can use for decryption of media data during playback.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeys)\\n */\\ninterface MediaKeys {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeys/createSession) */\\n    createSession(sessionType?: MediaKeySessionType): MediaKeySession;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaKeys/setServerCertificate) */\\n    setServerCertificate(serverCertificate: BufferSource): Promise<boolean>;\\n}\\n\\ndeclare var MediaKeys: {\\n    prototype: MediaKeys;\\n    new(): MediaKeys;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaList) */\\ninterface MediaList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaList/mediaText) */\\n    mediaText: string;\\n    toString(): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaList/appendMedium) */\\n    appendMedium(medium: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaList/deleteMedium) */\\n    deleteMedium(medium: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaList/item) */\\n    item(index: number): string | null;\\n    [index: number]: string;\\n}\\n\\ndeclare var MediaList: {\\n    prototype: MediaList;\\n    new(): MediaList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaMetadata) */\\ninterface MediaMetadata {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaMetadata/album) */\\n    album: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaMetadata/artist) */\\n    artist: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaMetadata/artwork) */\\n    artwork: ReadonlyArray<MediaImage>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaMetadata/title) */\\n    title: string;\\n}\\n\\ndeclare var MediaMetadata: {\\n    prototype: MediaMetadata;\\n    new(init?: MediaMetadataInit): MediaMetadata;\\n};\\n\\ninterface MediaQueryListEventMap {\\n    \\\"change\\\": MediaQueryListEvent;\\n}\\n\\n/**\\n * Stores information on a media query applied to a document, and handles sending notifications to listeners when the media query state change (i.e. when the media query test starts or stops evaluating to true).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryList)\\n */\\ninterface MediaQueryList extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryList/matches) */\\n    readonly matches: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryList/media) */\\n    readonly media: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryList/change_event) */\\n    onchange: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryList/addListener)\\n     */\\n    addListener(callback: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null): void;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryList/removeListener)\\n     */\\n    removeListener(callback: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null): void;\\n    addEventListener<K extends keyof MediaQueryListEventMap>(type: K, listener: (this: MediaQueryList, ev: MediaQueryListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MediaQueryListEventMap>(type: K, listener: (this: MediaQueryList, ev: MediaQueryListEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MediaQueryList: {\\n    prototype: MediaQueryList;\\n    new(): MediaQueryList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryListEvent) */\\ninterface MediaQueryListEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryListEvent/matches) */\\n    readonly matches: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaQueryListEvent/media) */\\n    readonly media: string;\\n}\\n\\ndeclare var MediaQueryListEvent: {\\n    prototype: MediaQueryListEvent;\\n    new(type: string, eventInitDict?: MediaQueryListEventInit): MediaQueryListEvent;\\n};\\n\\ninterface MediaRecorderEventMap {\\n    \\\"dataavailable\\\": BlobEvent;\\n    \\\"error\\\": Event;\\n    \\\"pause\\\": Event;\\n    \\\"resume\\\": Event;\\n    \\\"start\\\": Event;\\n    \\\"stop\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder) */\\ninterface MediaRecorder extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/audioBitsPerSecond) */\\n    readonly audioBitsPerSecond: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/mimeType) */\\n    readonly mimeType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/dataavailable_event) */\\n    ondataavailable: ((this: MediaRecorder, ev: BlobEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/error_event) */\\n    onerror: ((this: MediaRecorder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/pause_event) */\\n    onpause: ((this: MediaRecorder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/resume_event) */\\n    onresume: ((this: MediaRecorder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/start_event) */\\n    onstart: ((this: MediaRecorder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/stop_event) */\\n    onstop: ((this: MediaRecorder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/state) */\\n    readonly state: RecordingState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/stream) */\\n    readonly stream: MediaStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/videoBitsPerSecond) */\\n    readonly videoBitsPerSecond: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/pause) */\\n    pause(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/requestData) */\\n    requestData(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/resume) */\\n    resume(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/start) */\\n    start(timeslice?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/stop) */\\n    stop(): void;\\n    addEventListener<K extends keyof MediaRecorderEventMap>(type: K, listener: (this: MediaRecorder, ev: MediaRecorderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MediaRecorderEventMap>(type: K, listener: (this: MediaRecorder, ev: MediaRecorderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MediaRecorder: {\\n    prototype: MediaRecorder;\\n    new(stream: MediaStream, options?: MediaRecorderOptions): MediaRecorder;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaRecorder/isTypeSupported_static) */\\n    isTypeSupported(type: string): boolean;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSession) */\\ninterface MediaSession {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSession/metadata) */\\n    metadata: MediaMetadata | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSession/playbackState) */\\n    playbackState: MediaSessionPlaybackState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSession/setActionHandler) */\\n    setActionHandler(action: MediaSessionAction, handler: MediaSessionActionHandler | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSession/setPositionState) */\\n    setPositionState(state?: MediaPositionState): void;\\n}\\n\\ndeclare var MediaSession: {\\n    prototype: MediaSession;\\n    new(): MediaSession;\\n};\\n\\ninterface MediaSourceEventMap {\\n    \\\"sourceclose\\\": Event;\\n    \\\"sourceended\\\": Event;\\n    \\\"sourceopen\\\": Event;\\n}\\n\\n/**\\n * This Media Source Extensions API interface represents a source of media data for an HTMLMediaElement object. A MediaSource object can be attached to a HTMLMediaElement to be played in the user agent.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource)\\n */\\ninterface MediaSource extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/activeSourceBuffers) */\\n    readonly activeSourceBuffers: SourceBufferList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/duration) */\\n    duration: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/sourceclose_event) */\\n    onsourceclose: ((this: MediaSource, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/sourceended_event) */\\n    onsourceended: ((this: MediaSource, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/sourceopen_event) */\\n    onsourceopen: ((this: MediaSource, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/readyState) */\\n    readonly readyState: ReadyState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/sourceBuffers) */\\n    readonly sourceBuffers: SourceBufferList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/addSourceBuffer) */\\n    addSourceBuffer(type: string): SourceBuffer;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/clearLiveSeekableRange) */\\n    clearLiveSeekableRange(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/endOfStream) */\\n    endOfStream(error?: EndOfStreamError): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/removeSourceBuffer) */\\n    removeSourceBuffer(sourceBuffer: SourceBuffer): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/setLiveSeekableRange) */\\n    setLiveSeekableRange(start: number, end: number): void;\\n    addEventListener<K extends keyof MediaSourceEventMap>(type: K, listener: (this: MediaSource, ev: MediaSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MediaSourceEventMap>(type: K, listener: (this: MediaSource, ev: MediaSourceEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MediaSource: {\\n    prototype: MediaSource;\\n    new(): MediaSource;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaSource/isTypeSupported_static) */\\n    isTypeSupported(type: string): boolean;\\n};\\n\\ninterface MediaStreamEventMap {\\n    \\\"addtrack\\\": MediaStreamTrackEvent;\\n    \\\"removetrack\\\": MediaStreamTrackEvent;\\n}\\n\\n/**\\n * A stream of media content. A stream consists of several tracks such as video or audio tracks. Each track is specified as an instance of MediaStreamTrack.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream)\\n */\\ninterface MediaStream extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/active) */\\n    readonly active: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/id) */\\n    readonly id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/addtrack_event) */\\n    onaddtrack: ((this: MediaStream, ev: MediaStreamTrackEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/removetrack_event) */\\n    onremovetrack: ((this: MediaStream, ev: MediaStreamTrackEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/addTrack) */\\n    addTrack(track: MediaStreamTrack): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/clone) */\\n    clone(): MediaStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/getAudioTracks) */\\n    getAudioTracks(): MediaStreamTrack[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/getTrackById) */\\n    getTrackById(trackId: string): MediaStreamTrack | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/getTracks) */\\n    getTracks(): MediaStreamTrack[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/getVideoTracks) */\\n    getVideoTracks(): MediaStreamTrack[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStream/removeTrack) */\\n    removeTrack(track: MediaStreamTrack): void;\\n    addEventListener<K extends keyof MediaStreamEventMap>(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MediaStreamEventMap>(type: K, listener: (this: MediaStream, ev: MediaStreamEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MediaStream: {\\n    prototype: MediaStream;\\n    new(): MediaStream;\\n    new(stream: MediaStream): MediaStream;\\n    new(tracks: MediaStreamTrack[]): MediaStream;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamAudioDestinationNode) */\\ninterface MediaStreamAudioDestinationNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamAudioDestinationNode/stream) */\\n    readonly stream: MediaStream;\\n}\\n\\ndeclare var MediaStreamAudioDestinationNode: {\\n    prototype: MediaStreamAudioDestinationNode;\\n    new(context: AudioContext, options?: AudioNodeOptions): MediaStreamAudioDestinationNode;\\n};\\n\\n/**\\n * A type of AudioNode which operates as an audio source whose media is received from a MediaStream obtained using the WebRTC or Media Capture and Streams APIs.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamAudioSourceNode)\\n */\\ninterface MediaStreamAudioSourceNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamAudioSourceNode/mediaStream) */\\n    readonly mediaStream: MediaStream;\\n}\\n\\ndeclare var MediaStreamAudioSourceNode: {\\n    prototype: MediaStreamAudioSourceNode;\\n    new(context: AudioContext, options: MediaStreamAudioSourceOptions): MediaStreamAudioSourceNode;\\n};\\n\\ninterface MediaStreamTrackEventMap {\\n    \\\"ended\\\": Event;\\n    \\\"mute\\\": Event;\\n    \\\"unmute\\\": Event;\\n}\\n\\n/**\\n * A single media track within a stream; typically, these are audio or video tracks, but other track types may exist as well.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack)\\n */\\ninterface MediaStreamTrack extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/contentHint) */\\n    contentHint: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/enabled) */\\n    enabled: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/id) */\\n    readonly id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/kind) */\\n    readonly kind: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/label) */\\n    readonly label: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/muted) */\\n    readonly muted: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/ended_event) */\\n    onended: ((this: MediaStreamTrack, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/mute_event) */\\n    onmute: ((this: MediaStreamTrack, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/unmute_event) */\\n    onunmute: ((this: MediaStreamTrack, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/readyState) */\\n    readonly readyState: MediaStreamTrackState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/applyConstraints) */\\n    applyConstraints(constraints?: MediaTrackConstraints): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/clone) */\\n    clone(): MediaStreamTrack;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/getCapabilities) */\\n    getCapabilities(): MediaTrackCapabilities;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/getConstraints) */\\n    getConstraints(): MediaTrackConstraints;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/getSettings) */\\n    getSettings(): MediaTrackSettings;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrack/stop) */\\n    stop(): void;\\n    addEventListener<K extends keyof MediaStreamTrackEventMap>(type: K, listener: (this: MediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MediaStreamTrackEventMap>(type: K, listener: (this: MediaStreamTrack, ev: MediaStreamTrackEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MediaStreamTrack: {\\n    prototype: MediaStreamTrack;\\n    new(): MediaStreamTrack;\\n};\\n\\n/**\\n * Events which indicate that a MediaStream has had tracks added to or removed from the stream through calls to Media Stream API methods. These events are sent to the stream when these changes occur.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrackEvent)\\n */\\ninterface MediaStreamTrackEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaStreamTrackEvent/track) */\\n    readonly track: MediaStreamTrack;\\n}\\n\\ndeclare var MediaStreamTrackEvent: {\\n    prototype: MediaStreamTrackEvent;\\n    new(type: string, eventInitDict: MediaStreamTrackEventInit): MediaStreamTrackEvent;\\n};\\n\\n/**\\n * This Channel Messaging API interface allows us to create a new message channel and send data through it via its two MessagePort properties.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageChannel)\\n */\\ninterface MessageChannel {\\n    /**\\n     * Returns the first MessagePort object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageChannel/port1)\\n     */\\n    readonly port1: MessagePort;\\n    /**\\n     * Returns the second MessagePort object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageChannel/port2)\\n     */\\n    readonly port2: MessagePort;\\n}\\n\\ndeclare var MessageChannel: {\\n    prototype: MessageChannel;\\n    new(): MessageChannel;\\n};\\n\\n/**\\n * A message received by a target object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent)\\n */\\ninterface MessageEvent<T = any> extends Event {\\n    /**\\n     * Returns the data of the message.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/data)\\n     */\\n    readonly data: T;\\n    /**\\n     * Returns the last event ID string, for server-sent events.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/lastEventId)\\n     */\\n    readonly lastEventId: string;\\n    /**\\n     * Returns the origin of the message, for server-sent events and cross-document messaging.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/origin)\\n     */\\n    readonly origin: string;\\n    /**\\n     * Returns the MessagePort array sent with the message, for cross-document messaging and channel messaging.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/ports)\\n     */\\n    readonly ports: ReadonlyArray<MessagePort>;\\n    /**\\n     * Returns the WindowProxy of the source window, for cross-document messaging, and the MessagePort being attached, in the connect event fired at SharedWorkerGlobalScope objects.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/source)\\n     */\\n    readonly source: MessageEventSource | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/initMessageEvent)\\n     */\\n    initMessageEvent(type: string, bubbles?: boolean, cancelable?: boolean, data?: any, origin?: string, lastEventId?: string, source?: MessageEventSource | null, ports?: MessagePort[]): void;\\n}\\n\\ndeclare var MessageEvent: {\\n    prototype: MessageEvent;\\n    new<T>(type: string, eventInitDict?: MessageEventInit<T>): MessageEvent<T>;\\n};\\n\\ninterface MessagePortEventMap {\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/**\\n * This Channel Messaging API interface represents one of the two ports of a MessageChannel, allowing messages to be sent from one port and listening out for them arriving at the other.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort)\\n */\\ninterface MessagePort extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/message_event) */\\n    onmessage: ((this: MessagePort, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/messageerror_event) */\\n    onmessageerror: ((this: MessagePort, ev: MessageEvent) => any) | null;\\n    /**\\n     * Disconnects the port, so that it is no longer active.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/close)\\n     */\\n    close(): void;\\n    /**\\n     * Posts a message through the channel. Objects listed in transfer are transferred, not just cloned, meaning that they are no longer usable on the sending side.\\n     *\\n     * Throws a \\\"DataCloneError\\\" DOMException if transfer contains duplicate objects or port, or if message could not be cloned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/postMessage)\\n     */\\n    postMessage(message: any, transfer: Transferable[]): void;\\n    postMessage(message: any, options?: StructuredSerializeOptions): void;\\n    /**\\n     * Begins dispatching messages received on the port.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/start)\\n     */\\n    start(): void;\\n    addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MessagePort: {\\n    prototype: MessagePort;\\n    new(): MessagePort;\\n};\\n\\n/**\\n * Provides contains information about a MIME type associated with a particular plugin. NavigatorPlugins.mimeTypes returns an array of this object.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeType)\\n */\\ninterface MimeType {\\n    /**\\n     * Returns the MIME type's description.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeType/description)\\n     */\\n    readonly description: string;\\n    /**\\n     * Returns the Plugin object that implements this MIME type.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeType/enabledPlugin)\\n     */\\n    readonly enabledPlugin: Plugin;\\n    /**\\n     * Returns the MIME type's typical file extensions, in a comma-separated list.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeType/suffixes)\\n     */\\n    readonly suffixes: string;\\n    /**\\n     * Returns the MIME type.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeType/type)\\n     */\\n    readonly type: string;\\n}\\n\\n/** @deprecated */\\ndeclare var MimeType: {\\n    prototype: MimeType;\\n    new(): MimeType;\\n};\\n\\n/**\\n * Returns an array of MimeType instances, each of which contains information about a supported browser plugins. This object is returned by NavigatorPlugins.mimeTypes.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeTypeArray)\\n */\\ninterface MimeTypeArray {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeTypeArray/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeTypeArray/item)\\n     */\\n    item(index: number): MimeType | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MimeTypeArray/namedItem)\\n     */\\n    namedItem(name: string): MimeType | null;\\n    [index: number]: MimeType;\\n}\\n\\n/** @deprecated */\\ndeclare var MimeTypeArray: {\\n    prototype: MimeTypeArray;\\n    new(): MimeTypeArray;\\n};\\n\\n/**\\n * Events that occur due to the user interacting with a pointing device (such as a mouse). Common events using this interface include click, dblclick, mouseup, mousedown.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent)\\n */\\ninterface MouseEvent extends UIEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/altKey) */\\n    readonly altKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/button) */\\n    readonly button: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/buttons) */\\n    readonly buttons: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/clientX) */\\n    readonly clientX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/clientY) */\\n    readonly clientY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/ctrlKey) */\\n    readonly ctrlKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/metaKey) */\\n    readonly metaKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/movementX) */\\n    readonly movementX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/movementY) */\\n    readonly movementY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/offsetX) */\\n    readonly offsetX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/offsetY) */\\n    readonly offsetY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/pageX) */\\n    readonly pageX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/pageY) */\\n    readonly pageY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/relatedTarget) */\\n    readonly relatedTarget: EventTarget | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/screenX) */\\n    readonly screenX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/screenY) */\\n    readonly screenY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/shiftKey) */\\n    readonly shiftKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/x) */\\n    readonly x: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/y) */\\n    readonly y: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/getModifierState) */\\n    getModifierState(keyArg: string): boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MouseEvent/initMouseEvent)\\n     */\\n    initMouseEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget | null): void;\\n}\\n\\ndeclare var MouseEvent: {\\n    prototype: MouseEvent;\\n    new(type: string, eventInitDict?: MouseEventInit): MouseEvent;\\n};\\n\\n/**\\n * Provides event properties that are specific to modifications to the Document Object Model (DOM) hierarchy and nodes.\\n * @deprecated DOM4 [DOM] provides a new mechanism using a MutationObserver interface which addresses the use cases that mutation events solve, but in a more performant manner. Thus, this specification describes mutation events for reference and completeness of legacy behavior, but deprecates the use of the MutationEvent interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationEvent)\\n */\\ninterface MutationEvent extends Event {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationEvent/attrChange)\\n     */\\n    readonly attrChange: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationEvent/attrName)\\n     */\\n    readonly attrName: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationEvent/newValue)\\n     */\\n    readonly newValue: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationEvent/prevValue)\\n     */\\n    readonly prevValue: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationEvent/relatedNode)\\n     */\\n    readonly relatedNode: Node | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationEvent/initMutationEvent)\\n     */\\n    initMutationEvent(typeArg: string, bubblesArg?: boolean, cancelableArg?: boolean, relatedNodeArg?: Node | null, prevValueArg?: string, newValueArg?: string, attrNameArg?: string, attrChangeArg?: number): void;\\n    readonly MODIFICATION: 1;\\n    readonly ADDITION: 2;\\n    readonly REMOVAL: 3;\\n}\\n\\n/** @deprecated */\\ndeclare var MutationEvent: {\\n    prototype: MutationEvent;\\n    new(): MutationEvent;\\n    readonly MODIFICATION: 1;\\n    readonly ADDITION: 2;\\n    readonly REMOVAL: 3;\\n};\\n\\n/**\\n * Provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature which was part of the DOM3 Events specification.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationObserver)\\n */\\ninterface MutationObserver {\\n    /**\\n     * Stops observer from observing any mutations. Until the observe() method is used again, observer's callback will not be invoked.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationObserver/disconnect)\\n     */\\n    disconnect(): void;\\n    /**\\n     * Instructs the user agent to observe a given target (a node) and report any mutations based on the criteria given by options (an object).\\n     *\\n     * The options argument allows for setting mutation observation options via object members.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationObserver/observe)\\n     */\\n    observe(target: Node, options?: MutationObserverInit): void;\\n    /**\\n     * Empties the record queue and returns what was in there.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationObserver/takeRecords)\\n     */\\n    takeRecords(): MutationRecord[];\\n}\\n\\ndeclare var MutationObserver: {\\n    prototype: MutationObserver;\\n    new(callback: MutationCallback): MutationObserver;\\n};\\n\\n/**\\n * A MutationRecord represents an individual DOM mutation. It is the object that is passed to MutationObserver's callback.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord)\\n */\\ninterface MutationRecord {\\n    /**\\n     * Return the nodes added and removed respectively.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/addedNodes)\\n     */\\n    readonly addedNodes: NodeList;\\n    /**\\n     * Returns the local name of the changed attribute, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/attributeName)\\n     */\\n    readonly attributeName: string | null;\\n    /**\\n     * Returns the namespace of the changed attribute, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/attributeNamespace)\\n     */\\n    readonly attributeNamespace: string | null;\\n    /**\\n     * Return the previous and next sibling respectively of the added or removed nodes, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/nextSibling)\\n     */\\n    readonly nextSibling: Node | null;\\n    /**\\n     * The return value depends on type. For \\\"attributes\\\", it is the value of the changed attribute before the change. For \\\"characterData\\\", it is the data of the changed node before the change. For \\\"childList\\\", it is null.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/oldValue)\\n     */\\n    readonly oldValue: string | null;\\n    /**\\n     * Return the previous and next sibling respectively of the added or removed nodes, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/previousSibling)\\n     */\\n    readonly previousSibling: Node | null;\\n    /**\\n     * Return the nodes added and removed respectively.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/removedNodes)\\n     */\\n    readonly removedNodes: NodeList;\\n    /**\\n     * Returns the node the mutation affected, depending on the type. For \\\"attributes\\\", it is the element whose attribute changed. For \\\"characterData\\\", it is the CharacterData node. For \\\"childList\\\", it is the node whose children changed.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/target)\\n     */\\n    readonly target: Node;\\n    /**\\n     * Returns \\\"attributes\\\" if it was an attribute mutation. \\\"characterData\\\" if it was a mutation to a CharacterData node. And \\\"childList\\\" if it was a mutation to the tree of nodes.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MutationRecord/type)\\n     */\\n    readonly type: MutationRecordType;\\n}\\n\\ndeclare var MutationRecord: {\\n    prototype: MutationRecord;\\n    new(): MutationRecord;\\n};\\n\\n/**\\n * A collection of Attr objects. Objects inside a NamedNodeMap are not in any particular order, unlike NodeList, although they may be accessed by an index as in an array.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap)\\n */\\ninterface NamedNodeMap {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/getNamedItem) */\\n    getNamedItem(qualifiedName: string): Attr | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/getNamedItemNS) */\\n    getNamedItemNS(namespace: string | null, localName: string): Attr | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/item) */\\n    item(index: number): Attr | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/removeNamedItem) */\\n    removeNamedItem(qualifiedName: string): Attr;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/removeNamedItemNS) */\\n    removeNamedItemNS(namespace: string | null, localName: string): Attr;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/setNamedItem) */\\n    setNamedItem(attr: Attr): Attr | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NamedNodeMap/setNamedItemNS) */\\n    setNamedItemNS(attr: Attr): Attr | null;\\n    [index: number]: Attr;\\n}\\n\\ndeclare var NamedNodeMap: {\\n    prototype: NamedNodeMap;\\n    new(): NamedNodeMap;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager)\\n */\\ninterface NavigationPreloadManager {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager/disable) */\\n    disable(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager/enable) */\\n    enable(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager/getState) */\\n    getState(): Promise<NavigationPreloadState>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager/setHeaderValue) */\\n    setHeaderValue(value: string): Promise<void>;\\n}\\n\\ndeclare var NavigationPreloadManager: {\\n    prototype: NavigationPreloadManager;\\n    new(): NavigationPreloadManager;\\n};\\n\\n/**\\n * The state and the identity of the user agent. It allows scripts to query it and to register themselves to carry on some activities.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator)\\n */\\ninterface Navigator extends NavigatorAutomationInformation, NavigatorBadge, NavigatorConcurrentHardware, NavigatorContentUtils, NavigatorCookies, NavigatorID, NavigatorLanguage, NavigatorLocks, NavigatorOnLine, NavigatorPlugins, NavigatorStorage {\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/clipboard)\\n     */\\n    readonly clipboard: Clipboard;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/credentials)\\n     */\\n    readonly credentials: CredentialsContainer;\\n    readonly doNotTrack: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/geolocation) */\\n    readonly geolocation: Geolocation;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/maxTouchPoints) */\\n    readonly maxTouchPoints: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/mediaCapabilities) */\\n    readonly mediaCapabilities: MediaCapabilities;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/mediaDevices)\\n     */\\n    readonly mediaDevices: MediaDevices;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/mediaSession) */\\n    readonly mediaSession: MediaSession;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/permissions) */\\n    readonly permissions: Permissions;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/serviceWorker)\\n     */\\n    readonly serviceWorker: ServiceWorkerContainer;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/userActivation) */\\n    readonly userActivation: UserActivation;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/wakeLock) */\\n    readonly wakeLock: WakeLock;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/canShare)\\n     */\\n    canShare(data?: ShareData): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/getGamepads) */\\n    getGamepads(): (Gamepad | null)[];\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/requestMIDIAccess)\\n     */\\n    requestMIDIAccess(options?: MIDIOptions): Promise<MIDIAccess>;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/requestMediaKeySystemAccess)\\n     */\\n    requestMediaKeySystemAccess(keySystem: string, supportedConfigurations: MediaKeySystemConfiguration[]): Promise<MediaKeySystemAccess>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/sendBeacon) */\\n    sendBeacon(url: string | URL, data?: BodyInit | null): boolean;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/share)\\n     */\\n    share(data?: ShareData): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/vibrate) */\\n    vibrate(pattern: VibratePattern): boolean;\\n}\\n\\ndeclare var Navigator: {\\n    prototype: Navigator;\\n    new(): Navigator;\\n};\\n\\ninterface NavigatorAutomationInformation {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/webdriver) */\\n    readonly webdriver: boolean;\\n}\\n\\n/** Available only in secure contexts. */\\ninterface NavigatorBadge {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/clearAppBadge) */\\n    clearAppBadge(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/setAppBadge) */\\n    setAppBadge(contents?: number): Promise<void>;\\n}\\n\\ninterface NavigatorConcurrentHardware {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/hardwareConcurrency) */\\n    readonly hardwareConcurrency: number;\\n}\\n\\ninterface NavigatorContentUtils {\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/registerProtocolHandler)\\n     */\\n    registerProtocolHandler(scheme: string, url: string | URL): void;\\n}\\n\\ninterface NavigatorCookies {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/cookieEnabled) */\\n    readonly cookieEnabled: boolean;\\n}\\n\\ninterface NavigatorID {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/appCodeName)\\n     */\\n    readonly appCodeName: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/appName)\\n     */\\n    readonly appName: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/appVersion)\\n     */\\n    readonly appVersion: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/platform)\\n     */\\n    readonly platform: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/product)\\n     */\\n    readonly product: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/productSub)\\n     */\\n    readonly productSub: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/userAgent) */\\n    readonly userAgent: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/vendor)\\n     */\\n    readonly vendor: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/vendorSub)\\n     */\\n    readonly vendorSub: string;\\n}\\n\\ninterface NavigatorLanguage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/language) */\\n    readonly language: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/languages) */\\n    readonly languages: ReadonlyArray<string>;\\n}\\n\\n/** Available only in secure contexts. */\\ninterface NavigatorLocks {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/locks) */\\n    readonly locks: LockManager;\\n}\\n\\ninterface NavigatorOnLine {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/onLine) */\\n    readonly onLine: boolean;\\n}\\n\\ninterface NavigatorPlugins {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigatorPlugins/mimeTypes)\\n     */\\n    readonly mimeTypes: MimeTypeArray;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/pdfViewerEnabled) */\\n    readonly pdfViewerEnabled: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/plugins)\\n     */\\n    readonly plugins: PluginArray;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/javaEnabled)\\n     */\\n    javaEnabled(): boolean;\\n}\\n\\n/** Available only in secure contexts. */\\ninterface NavigatorStorage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/storage) */\\n    readonly storage: StorageManager;\\n}\\n\\n/**\\n * Node is an interface from which a number of DOM API object types inherit. It allows those types to be treated similarly; for example, inheriting the same set of methods, or being tested in the same way.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node)\\n */\\ninterface Node extends EventTarget {\\n    /**\\n     * Returns node's node document's document base URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/baseURI)\\n     */\\n    readonly baseURI: string;\\n    /**\\n     * Returns the children.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/childNodes)\\n     */\\n    readonly childNodes: NodeListOf<ChildNode>;\\n    /**\\n     * Returns the first child.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/firstChild)\\n     */\\n    readonly firstChild: ChildNode | null;\\n    /**\\n     * Returns true if node is connected and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/isConnected)\\n     */\\n    readonly isConnected: boolean;\\n    /**\\n     * Returns the last child.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lastChild)\\n     */\\n    readonly lastChild: ChildNode | null;\\n    /**\\n     * Returns the next sibling.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nextSibling)\\n     */\\n    readonly nextSibling: ChildNode | null;\\n    /**\\n     * Returns a string appropriate for the type of node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeName)\\n     */\\n    readonly nodeName: string;\\n    /**\\n     * Returns the type of node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeType)\\n     */\\n    readonly nodeType: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/nodeValue) */\\n    nodeValue: string | null;\\n    /**\\n     * Returns the node document. Returns null for documents.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/ownerDocument)\\n     */\\n    readonly ownerDocument: Document | null;\\n    /**\\n     * Returns the parent element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/parentElement)\\n     */\\n    readonly parentElement: HTMLElement | null;\\n    /**\\n     * Returns the parent.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/parentNode)\\n     */\\n    readonly parentNode: ParentNode | null;\\n    /**\\n     * Returns the previous sibling.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/previousSibling)\\n     */\\n    readonly previousSibling: ChildNode | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/textContent) */\\n    textContent: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/appendChild) */\\n    appendChild<T extends Node>(node: T): T;\\n    /**\\n     * Returns a copy of node. If deep is true, the copy also includes the node's descendants.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/cloneNode)\\n     */\\n    cloneNode(deep?: boolean): Node;\\n    /**\\n     * Returns a bitmask indicating the position of other relative to node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/compareDocumentPosition)\\n     */\\n    compareDocumentPosition(other: Node): number;\\n    /**\\n     * Returns true if other is an inclusive descendant of node, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/contains)\\n     */\\n    contains(other: Node | null): boolean;\\n    /**\\n     * Returns node's root.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/getRootNode)\\n     */\\n    getRootNode(options?: GetRootNodeOptions): Node;\\n    /**\\n     * Returns whether node has children.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/hasChildNodes)\\n     */\\n    hasChildNodes(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/insertBefore) */\\n    insertBefore<T extends Node>(node: T, child: Node | null): T;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/isDefaultNamespace) */\\n    isDefaultNamespace(namespace: string | null): boolean;\\n    /**\\n     * Returns whether node and otherNode have the same properties.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/isEqualNode)\\n     */\\n    isEqualNode(otherNode: Node | null): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/isSameNode) */\\n    isSameNode(otherNode: Node | null): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lookupNamespaceURI) */\\n    lookupNamespaceURI(prefix: string | null): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/lookupPrefix) */\\n    lookupPrefix(namespace: string | null): string | null;\\n    /**\\n     * Removes empty exclusive Text nodes and concatenates the data of remaining contiguous exclusive Text nodes into the first of their nodes.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/normalize)\\n     */\\n    normalize(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/removeChild) */\\n    removeChild<T extends Node>(child: T): T;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/replaceChild) */\\n    replaceChild<T extends Node>(node: Node, child: T): T;\\n    /** node is an element. */\\n    readonly ELEMENT_NODE: 1;\\n    readonly ATTRIBUTE_NODE: 2;\\n    /** node is a Text node. */\\n    readonly TEXT_NODE: 3;\\n    /** node is a CDATASection node. */\\n    readonly CDATA_SECTION_NODE: 4;\\n    readonly ENTITY_REFERENCE_NODE: 5;\\n    readonly ENTITY_NODE: 6;\\n    /** node is a ProcessingInstruction node. */\\n    readonly PROCESSING_INSTRUCTION_NODE: 7;\\n    /** node is a Comment node. */\\n    readonly COMMENT_NODE: 8;\\n    /** node is a document. */\\n    readonly DOCUMENT_NODE: 9;\\n    /** node is a doctype. */\\n    readonly DOCUMENT_TYPE_NODE: 10;\\n    /** node is a DocumentFragment node. */\\n    readonly DOCUMENT_FRAGMENT_NODE: 11;\\n    readonly NOTATION_NODE: 12;\\n    /** Set when node and other are not in the same tree. */\\n    readonly DOCUMENT_POSITION_DISCONNECTED: 0x01;\\n    /** Set when other is preceding node. */\\n    readonly DOCUMENT_POSITION_PRECEDING: 0x02;\\n    /** Set when other is following node. */\\n    readonly DOCUMENT_POSITION_FOLLOWING: 0x04;\\n    /** Set when other is an ancestor of node. */\\n    readonly DOCUMENT_POSITION_CONTAINS: 0x08;\\n    /** Set when other is a descendant of node. */\\n    readonly DOCUMENT_POSITION_CONTAINED_BY: 0x10;\\n    readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 0x20;\\n}\\n\\ndeclare var Node: {\\n    prototype: Node;\\n    new(): Node;\\n    /** node is an element. */\\n    readonly ELEMENT_NODE: 1;\\n    readonly ATTRIBUTE_NODE: 2;\\n    /** node is a Text node. */\\n    readonly TEXT_NODE: 3;\\n    /** node is a CDATASection node. */\\n    readonly CDATA_SECTION_NODE: 4;\\n    readonly ENTITY_REFERENCE_NODE: 5;\\n    readonly ENTITY_NODE: 6;\\n    /** node is a ProcessingInstruction node. */\\n    readonly PROCESSING_INSTRUCTION_NODE: 7;\\n    /** node is a Comment node. */\\n    readonly COMMENT_NODE: 8;\\n    /** node is a document. */\\n    readonly DOCUMENT_NODE: 9;\\n    /** node is a doctype. */\\n    readonly DOCUMENT_TYPE_NODE: 10;\\n    /** node is a DocumentFragment node. */\\n    readonly DOCUMENT_FRAGMENT_NODE: 11;\\n    readonly NOTATION_NODE: 12;\\n    /** Set when node and other are not in the same tree. */\\n    readonly DOCUMENT_POSITION_DISCONNECTED: 0x01;\\n    /** Set when other is preceding node. */\\n    readonly DOCUMENT_POSITION_PRECEDING: 0x02;\\n    /** Set when other is following node. */\\n    readonly DOCUMENT_POSITION_FOLLOWING: 0x04;\\n    /** Set when other is an ancestor of node. */\\n    readonly DOCUMENT_POSITION_CONTAINS: 0x08;\\n    /** Set when other is a descendant of node. */\\n    readonly DOCUMENT_POSITION_CONTAINED_BY: 0x10;\\n    readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 0x20;\\n};\\n\\n/**\\n * An iterator over the members of a list of the nodes in a subtree of the DOM. The nodes will be returned in document order.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator)\\n */\\ninterface NodeIterator {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator/filter) */\\n    readonly filter: NodeFilter | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator/pointerBeforeReferenceNode) */\\n    readonly pointerBeforeReferenceNode: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator/referenceNode) */\\n    readonly referenceNode: Node;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator/root) */\\n    readonly root: Node;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator/whatToShow) */\\n    readonly whatToShow: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator/detach)\\n     */\\n    detach(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator/nextNode) */\\n    nextNode(): Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeIterator/previousNode) */\\n    previousNode(): Node | null;\\n}\\n\\ndeclare var NodeIterator: {\\n    prototype: NodeIterator;\\n    new(): NodeIterator;\\n};\\n\\n/**\\n * NodeList objects are collections of nodes, usually returned by properties such as Node.childNodes and methods such as document.querySelectorAll().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList)\\n */\\ninterface NodeList {\\n    /**\\n     * Returns the number of nodes in the collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the node with index index from the collection. The nodes are sorted in tree order.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NodeList/item)\\n     */\\n    item(index: number): Node | null;\\n    /**\\n     * Performs the specified action for each node in an list.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the list.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: Node, key: number, parent: NodeList) => void, thisArg?: any): void;\\n    [index: number]: Node;\\n}\\n\\ndeclare var NodeList: {\\n    prototype: NodeList;\\n    new(): NodeList;\\n};\\n\\ninterface NodeListOf<TNode extends Node> extends NodeList {\\n    item(index: number): TNode;\\n    /**\\n     * Performs the specified action for each node in an list.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the list.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: TNode, key: number, parent: NodeListOf<TNode>) => void, thisArg?: any): void;\\n    [index: number]: TNode;\\n}\\n\\ninterface NonDocumentTypeChildNode {\\n    /**\\n     * Returns the first following sibling that is an element, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/nextElementSibling)\\n     */\\n    readonly nextElementSibling: Element | null;\\n    /**\\n     * Returns the first preceding sibling that is an element, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CharacterData/previousElementSibling)\\n     */\\n    readonly previousElementSibling: Element | null;\\n}\\n\\ninterface NonElementParentNode {\\n    /**\\n     * Returns the first element within node's descendants whose ID is elementId.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/getElementById)\\n     */\\n    getElementById(elementId: string): Element | null;\\n}\\n\\ninterface NotificationEventMap {\\n    \\\"click\\\": Event;\\n    \\\"close\\\": Event;\\n    \\\"error\\\": Event;\\n    \\\"show\\\": Event;\\n}\\n\\n/**\\n * This Notifications API interface is used to configure and display desktop notifications to the user.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification)\\n */\\ninterface Notification extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/body) */\\n    readonly body: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/data) */\\n    readonly data: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/dir) */\\n    readonly dir: NotificationDirection;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/icon) */\\n    readonly icon: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/lang) */\\n    readonly lang: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/click_event) */\\n    onclick: ((this: Notification, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/close_event) */\\n    onclose: ((this: Notification, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/error_event) */\\n    onerror: ((this: Notification, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/show_event) */\\n    onshow: ((this: Notification, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/silent) */\\n    readonly silent: boolean | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/tag) */\\n    readonly tag: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/title) */\\n    readonly title: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/close) */\\n    close(): void;\\n    addEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Notification: {\\n    prototype: Notification;\\n    new(title: string, options?: NotificationOptions): Notification;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/permission_static) */\\n    readonly permission: NotificationPermission;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/requestPermission_static) */\\n    requestPermission(deprecatedCallback?: NotificationPermissionCallback): Promise<NotificationPermission>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed) */\\ninterface OES_draw_buffers_indexed {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/blendEquationSeparateiOES) */\\n    blendEquationSeparateiOES(buf: GLuint, modeRGB: GLenum, modeAlpha: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/blendEquationiOES) */\\n    blendEquationiOES(buf: GLuint, mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/blendFuncSeparateiOES) */\\n    blendFuncSeparateiOES(buf: GLuint, srcRGB: GLenum, dstRGB: GLenum, srcAlpha: GLenum, dstAlpha: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/blendFunciOES) */\\n    blendFunciOES(buf: GLuint, src: GLenum, dst: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/colorMaskiOES) */\\n    colorMaskiOES(buf: GLuint, r: GLboolean, g: GLboolean, b: GLboolean, a: GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/disableiOES) */\\n    disableiOES(target: GLenum, index: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/enableiOES) */\\n    enableiOES(target: GLenum, index: GLuint): void;\\n}\\n\\n/**\\n * The OES_element_index_uint extension is part of the WebGL API and adds support for gl.UNSIGNED_INT types to WebGLRenderingContext.drawElements().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_element_index_uint)\\n */\\ninterface OES_element_index_uint {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_fbo_render_mipmap) */\\ninterface OES_fbo_render_mipmap {\\n}\\n\\n/**\\n * The OES_standard_derivatives extension is part of the WebGL API and adds the GLSL derivative functions dFdx, dFdy, and fwidth.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_standard_derivatives)\\n */\\ninterface OES_standard_derivatives {\\n    readonly FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 0x8B8B;\\n}\\n\\n/**\\n * The OES_texture_float extension is part of the WebGL API and exposes floating-point pixel types for textures.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_texture_float)\\n */\\ninterface OES_texture_float {\\n}\\n\\n/**\\n * The OES_texture_float_linear extension is part of the WebGL API and allows linear filtering with floating-point pixel types for textures.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_texture_float_linear)\\n */\\ninterface OES_texture_float_linear {\\n}\\n\\n/**\\n * The OES_texture_half_float extension is part of the WebGL API and adds texture formats with 16- (aka half float) and 32-bit floating-point components.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_texture_half_float)\\n */\\ninterface OES_texture_half_float {\\n    readonly HALF_FLOAT_OES: 0x8D61;\\n}\\n\\n/**\\n * The OES_texture_half_float_linear extension is part of the WebGL API and allows linear filtering with half floating-point pixel types for textures.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_texture_half_float_linear)\\n */\\ninterface OES_texture_half_float_linear {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object) */\\ninterface OES_vertex_array_object {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object/bindVertexArrayOES) */\\n    bindVertexArrayOES(arrayObject: WebGLVertexArrayObjectOES | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object/createVertexArrayOES) */\\n    createVertexArrayOES(): WebGLVertexArrayObjectOES | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object/deleteVertexArrayOES) */\\n    deleteVertexArrayOES(arrayObject: WebGLVertexArrayObjectOES | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object/isVertexArrayOES) */\\n    isVertexArrayOES(arrayObject: WebGLVertexArrayObjectOES | null): GLboolean;\\n    readonly VERTEX_ARRAY_BINDING_OES: 0x85B5;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OVR_multiview2) */\\ninterface OVR_multiview2 {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OVR_multiview2/framebufferTextureMultiviewOVR) */\\n    framebufferTextureMultiviewOVR(target: GLenum, attachment: GLenum, texture: WebGLTexture | null, level: GLint, baseViewIndex: GLint, numViews: GLsizei): void;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: 0x9630;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR: 0x9632;\\n    readonly MAX_VIEWS_OVR: 0x9631;\\n    readonly FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR: 0x9633;\\n}\\n\\n/**\\n * The Web Audio API OfflineAudioCompletionEvent interface represents events that occur when the processing of an OfflineAudioContext is terminated. The complete event implements this interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OfflineAudioCompletionEvent)\\n */\\ninterface OfflineAudioCompletionEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OfflineAudioCompletionEvent/renderedBuffer) */\\n    readonly renderedBuffer: AudioBuffer;\\n}\\n\\ndeclare var OfflineAudioCompletionEvent: {\\n    prototype: OfflineAudioCompletionEvent;\\n    new(type: string, eventInitDict: OfflineAudioCompletionEventInit): OfflineAudioCompletionEvent;\\n};\\n\\ninterface OfflineAudioContextEventMap extends BaseAudioContextEventMap {\\n    \\\"complete\\\": OfflineAudioCompletionEvent;\\n}\\n\\n/**\\n * An AudioContext interface representing an audio-processing graph built from linked together AudioNodes. In contrast with a standard AudioContext, an OfflineAudioContext doesn't render the audio to the device hardware; instead, it generates it, as fast as it can, and outputs the result to an AudioBuffer.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OfflineAudioContext)\\n */\\ninterface OfflineAudioContext extends BaseAudioContext {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OfflineAudioContext/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OfflineAudioContext/complete_event) */\\n    oncomplete: ((this: OfflineAudioContext, ev: OfflineAudioCompletionEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OfflineAudioContext/resume) */\\n    resume(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OfflineAudioContext/startRendering) */\\n    startRendering(): Promise<AudioBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OfflineAudioContext/suspend) */\\n    suspend(suspendTime: number): Promise<void>;\\n    addEventListener<K extends keyof OfflineAudioContextEventMap>(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof OfflineAudioContextEventMap>(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var OfflineAudioContext: {\\n    prototype: OfflineAudioContext;\\n    new(contextOptions: OfflineAudioContextOptions): OfflineAudioContext;\\n    new(numberOfChannels: number, length: number, sampleRate: number): OfflineAudioContext;\\n};\\n\\ninterface OffscreenCanvasEventMap {\\n    \\\"contextlost\\\": Event;\\n    \\\"contextrestored\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas) */\\ninterface OffscreenCanvas extends EventTarget {\\n    /**\\n     * These attributes return the dimensions of the OffscreenCanvas object's bitmap.\\n     *\\n     * They can be set, to replace the bitmap with a new, transparent black bitmap of the specified dimensions (effectively resizing it).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/height)\\n     */\\n    height: number;\\n    oncontextlost: ((this: OffscreenCanvas, ev: Event) => any) | null;\\n    oncontextrestored: ((this: OffscreenCanvas, ev: Event) => any) | null;\\n    /**\\n     * These attributes return the dimensions of the OffscreenCanvas object's bitmap.\\n     *\\n     * They can be set, to replace the bitmap with a new, transparent black bitmap of the specified dimensions (effectively resizing it).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/width)\\n     */\\n    width: number;\\n    /**\\n     * Returns a promise that will fulfill with a new Blob object representing a file containing the image in the OffscreenCanvas object.\\n     *\\n     * The argument, if provided, is a dictionary that controls the encoding options of the image file to be created. The type field specifies the file format and has a default value of \\\"image/png\\\"; that type is also used if the requested type isn't supported. If the image format supports variable quality (such as \\\"image/jpeg\\\"), then the quality field is a number in the range 0.0 to 1.0 inclusive indicating the desired quality level for the resulting image.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/convertToBlob)\\n     */\\n    convertToBlob(options?: ImageEncodeOptions): Promise<Blob>;\\n    /**\\n     * Returns an object that exposes an API for drawing on the OffscreenCanvas object. contextId specifies the desired API: \\\"2d\\\", \\\"bitmaprenderer\\\", \\\"webgl\\\", or \\\"webgl2\\\". options is handled by that API.\\n     *\\n     * This specification defines the \\\"2d\\\" context below, which is similar but distinct from the \\\"2d\\\" context that is created from a canvas element. The WebGL specifications define the \\\"webgl\\\" and \\\"webgl2\\\" contexts. [WEBGL]\\n     *\\n     * Returns null if the canvas has already been initialized with another context type (e.g., trying to get a \\\"2d\\\" context after getting a \\\"webgl\\\" context).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/getContext)\\n     */\\n    getContext(contextId: \\\"2d\\\", options?: any): OffscreenCanvasRenderingContext2D | null;\\n    getContext(contextId: \\\"bitmaprenderer\\\", options?: any): ImageBitmapRenderingContext | null;\\n    getContext(contextId: \\\"webgl\\\", options?: any): WebGLRenderingContext | null;\\n    getContext(contextId: \\\"webgl2\\\", options?: any): WebGL2RenderingContext | null;\\n    getContext(contextId: OffscreenRenderingContextId, options?: any): OffscreenRenderingContext | null;\\n    /**\\n     * Returns a newly created ImageBitmap object with the image in the OffscreenCanvas object. The image in the OffscreenCanvas object is replaced with a new blank image.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/transferToImageBitmap)\\n     */\\n    transferToImageBitmap(): ImageBitmap;\\n    addEventListener<K extends keyof OffscreenCanvasEventMap>(type: K, listener: (this: OffscreenCanvas, ev: OffscreenCanvasEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof OffscreenCanvasEventMap>(type: K, listener: (this: OffscreenCanvas, ev: OffscreenCanvasEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var OffscreenCanvas: {\\n    prototype: OffscreenCanvas;\\n    new(width: number, height: number): OffscreenCanvas;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvasRenderingContext2D) */\\ninterface OffscreenCanvasRenderingContext2D extends CanvasCompositing, CanvasDrawImage, CanvasDrawPath, CanvasFillStrokeStyles, CanvasFilters, CanvasImageData, CanvasImageSmoothing, CanvasPath, CanvasPathDrawingStyles, CanvasRect, CanvasShadowStyles, CanvasState, CanvasText, CanvasTextDrawingStyles, CanvasTransform {\\n    readonly canvas: OffscreenCanvas;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvasRenderingContext2D/commit) */\\n    commit(): void;\\n}\\n\\ndeclare var OffscreenCanvasRenderingContext2D: {\\n    prototype: OffscreenCanvasRenderingContext2D;\\n    new(): OffscreenCanvasRenderingContext2D;\\n};\\n\\n/**\\n * The OscillatorNode interface represents a periodic waveform, such as a sine wave. It is an AudioScheduledSourceNode audio-processing module that causes a specified frequency of a given wave to be created—in effect, a constant tone.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OscillatorNode)\\n */\\ninterface OscillatorNode extends AudioScheduledSourceNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OscillatorNode/detune) */\\n    readonly detune: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OscillatorNode/frequency) */\\n    readonly frequency: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OscillatorNode/type) */\\n    type: OscillatorType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OscillatorNode/setPeriodicWave) */\\n    setPeriodicWave(periodicWave: PeriodicWave): void;\\n    addEventListener<K extends keyof AudioScheduledSourceNodeEventMap>(type: K, listener: (this: OscillatorNode, ev: AudioScheduledSourceNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AudioScheduledSourceNodeEventMap>(type: K, listener: (this: OscillatorNode, ev: AudioScheduledSourceNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var OscillatorNode: {\\n    prototype: OscillatorNode;\\n    new(context: BaseAudioContext, options?: OscillatorOptions): OscillatorNode;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OverconstrainedError) */\\ninterface OverconstrainedError extends Error {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OverconstrainedError/constraint) */\\n    readonly constraint: string;\\n}\\n\\ndeclare var OverconstrainedError: {\\n    prototype: OverconstrainedError;\\n    new(constraint: string, message?: string): OverconstrainedError;\\n};\\n\\n/**\\n * The PageTransitionEvent is fired when a document is being loaded or unloaded.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PageTransitionEvent)\\n */\\ninterface PageTransitionEvent extends Event {\\n    /**\\n     * For the pageshow event, returns false if the page is newly being loaded (and the load event will fire). Otherwise, returns true.\\n     *\\n     * For the pagehide event, returns false if the page is going away for the last time. Otherwise, returns true, meaning that (if nothing conspires to make the page unsalvageable) the page might be reused if the user navigates back to this page.\\n     *\\n     * Things that can cause the page to be unsalvageable include:\\n     *\\n     * The user agent decided to not keep the Document alive in a session history entry after unload\\n     * Having iframes that are not salvageable\\n     * Active WebSocket objects\\n     * Aborting a Document\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PageTransitionEvent/persisted)\\n     */\\n    readonly persisted: boolean;\\n}\\n\\ndeclare var PageTransitionEvent: {\\n    prototype: PageTransitionEvent;\\n    new(type: string, eventInitDict?: PageTransitionEventInit): PageTransitionEvent;\\n};\\n\\n/**\\n * A PannerNode always has exactly one input and one output: the input can be mono or stereo but the output is always stereo (2 channels); you can't have panning effects without at least two audio channels!\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode)\\n */\\ninterface PannerNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/coneInnerAngle) */\\n    coneInnerAngle: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/coneOuterAngle) */\\n    coneOuterAngle: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/coneOuterGain) */\\n    coneOuterGain: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/distanceModel) */\\n    distanceModel: DistanceModelType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/maxDistance) */\\n    maxDistance: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/orientationX) */\\n    readonly orientationX: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/orientationY) */\\n    readonly orientationY: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/orientationZ) */\\n    readonly orientationZ: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/panningModel) */\\n    panningModel: PanningModelType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/positionX) */\\n    readonly positionX: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/positionY) */\\n    readonly positionY: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/positionZ) */\\n    readonly positionZ: AudioParam;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/refDistance) */\\n    refDistance: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/rolloffFactor) */\\n    rolloffFactor: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/setOrientation)\\n     */\\n    setOrientation(x: number, y: number, z: number): void;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PannerNode/setPosition)\\n     */\\n    setPosition(x: number, y: number, z: number): void;\\n}\\n\\ndeclare var PannerNode: {\\n    prototype: PannerNode;\\n    new(context: BaseAudioContext, options?: PannerOptions): PannerNode;\\n};\\n\\ninterface ParentNode extends Node {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/childElementCount) */\\n    readonly childElementCount: number;\\n    /**\\n     * Returns the child elements.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/children)\\n     */\\n    readonly children: HTMLCollection;\\n    /**\\n     * Returns the first child that is an element, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/firstElementChild)\\n     */\\n    readonly firstElementChild: Element | null;\\n    /**\\n     * Returns the last child that is an element, and null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/lastElementChild)\\n     */\\n    readonly lastElementChild: Element | null;\\n    /**\\n     * Inserts nodes after the last child of node, while replacing strings in nodes with equivalent Text nodes.\\n     *\\n     * Throws a \\\"HierarchyRequestError\\\" DOMException if the constraints of the node tree are violated.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/append)\\n     */\\n    append(...nodes: (Node | string)[]): void;\\n    /**\\n     * Inserts nodes before the first child of node, while replacing strings in nodes with equivalent Text nodes.\\n     *\\n     * Throws a \\\"HierarchyRequestError\\\" DOMException if the constraints of the node tree are violated.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/prepend)\\n     */\\n    prepend(...nodes: (Node | string)[]): void;\\n    /**\\n     * Returns the first element that is a descendant of node that matches selectors.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/querySelector)\\n     */\\n    querySelector<K extends keyof HTMLElementTagNameMap>(selectors: K): HTMLElementTagNameMap[K] | null;\\n    querySelector<K extends keyof SVGElementTagNameMap>(selectors: K): SVGElementTagNameMap[K] | null;\\n    querySelector<K extends keyof MathMLElementTagNameMap>(selectors: K): MathMLElementTagNameMap[K] | null;\\n    /** @deprecated */\\n    querySelector<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): HTMLElementDeprecatedTagNameMap[K] | null;\\n    querySelector<E extends Element = Element>(selectors: string): E | null;\\n    /**\\n     * Returns all element descendants of node that match selectors.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/querySelectorAll)\\n     */\\n    querySelectorAll<K extends keyof HTMLElementTagNameMap>(selectors: K): NodeListOf<HTMLElementTagNameMap[K]>;\\n    querySelectorAll<K extends keyof SVGElementTagNameMap>(selectors: K): NodeListOf<SVGElementTagNameMap[K]>;\\n    querySelectorAll<K extends keyof MathMLElementTagNameMap>(selectors: K): NodeListOf<MathMLElementTagNameMap[K]>;\\n    /** @deprecated */\\n    querySelectorAll<K extends keyof HTMLElementDeprecatedTagNameMap>(selectors: K): NodeListOf<HTMLElementDeprecatedTagNameMap[K]>;\\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\\n    /**\\n     * Replace all children of node with nodes, while replacing strings in nodes with equivalent Text nodes.\\n     *\\n     * Throws a \\\"HierarchyRequestError\\\" DOMException if the constraints of the node tree are violated.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/replaceChildren)\\n     */\\n    replaceChildren(...nodes: (Node | string)[]): void;\\n}\\n\\n/**\\n * This Canvas 2D API interface is used to declare a path that can then be used on a CanvasRenderingContext2D object. The path methods of the CanvasRenderingContext2D interface are also present on this interface, which gives you the convenience of being able to retain and replay your path whenever desired.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Path2D)\\n */\\ninterface Path2D extends CanvasPath {\\n    /**\\n     * Adds to the path the path given by the argument.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Path2D/addPath)\\n     */\\n    addPath(path: Path2D, transform?: DOMMatrix2DInit): void;\\n}\\n\\ndeclare var Path2D: {\\n    prototype: Path2D;\\n    new(path?: Path2D | string): Path2D;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentMethodChangeEvent)\\n */\\ninterface PaymentMethodChangeEvent extends PaymentRequestUpdateEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentMethodChangeEvent/methodDetails) */\\n    readonly methodDetails: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentMethodChangeEvent/methodName) */\\n    readonly methodName: string;\\n}\\n\\ndeclare var PaymentMethodChangeEvent: {\\n    prototype: PaymentMethodChangeEvent;\\n    new(type: string, eventInitDict?: PaymentMethodChangeEventInit): PaymentMethodChangeEvent;\\n};\\n\\ninterface PaymentRequestEventMap {\\n    \\\"paymentmethodchange\\\": Event;\\n}\\n\\n/**\\n * This Payment Request API interface is the primary access point into the API, and lets web content and apps accept payments from the end user.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentRequest)\\n */\\ninterface PaymentRequest extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentRequest/id) */\\n    readonly id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentRequest/paymentmethodchange_event) */\\n    onpaymentmethodchange: ((this: PaymentRequest, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentRequest/abort) */\\n    abort(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentRequest/canMakePayment) */\\n    canMakePayment(): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentRequest/show) */\\n    show(detailsPromise?: PaymentDetailsUpdate | PromiseLike<PaymentDetailsUpdate>): Promise<PaymentResponse>;\\n    addEventListener<K extends keyof PaymentRequestEventMap>(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof PaymentRequestEventMap>(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var PaymentRequest: {\\n    prototype: PaymentRequest;\\n    new(methodData: PaymentMethodData[], details: PaymentDetailsInit): PaymentRequest;\\n};\\n\\n/**\\n * This Payment Request API interface enables a web page to update the details of a PaymentRequest in response to a user action.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentRequestUpdateEvent)\\n */\\ninterface PaymentRequestUpdateEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentRequestUpdateEvent/updateWith) */\\n    updateWith(detailsPromise: PaymentDetailsUpdate | PromiseLike<PaymentDetailsUpdate>): void;\\n}\\n\\ndeclare var PaymentRequestUpdateEvent: {\\n    prototype: PaymentRequestUpdateEvent;\\n    new(type: string, eventInitDict?: PaymentRequestUpdateEventInit): PaymentRequestUpdateEvent;\\n};\\n\\n/**\\n * This Payment Request API interface is returned after a user selects a payment method and approves a payment request.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentResponse)\\n */\\ninterface PaymentResponse extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentResponse/details) */\\n    readonly details: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentResponse/methodName) */\\n    readonly methodName: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentResponse/requestId) */\\n    readonly requestId: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentResponse/complete) */\\n    complete(result?: PaymentComplete): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentResponse/retry) */\\n    retry(errorFields?: PaymentValidationErrors): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PaymentResponse/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PaymentResponse: {\\n    prototype: PaymentResponse;\\n    new(): PaymentResponse;\\n};\\n\\ninterface PerformanceEventMap {\\n    \\\"resourcetimingbufferfull\\\": Event;\\n}\\n\\n/**\\n * Provides access to performance-related information for the current page. It's part of the High Resolution Time API, but is enhanced by the Performance Timeline API, the Navigation Timing API, the User Timing API, and the Resource Timing API.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance)\\n */\\ninterface Performance extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/eventCounts) */\\n    readonly eventCounts: EventCounts;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/navigation)\\n     */\\n    readonly navigation: PerformanceNavigation;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/resourcetimingbufferfull_event) */\\n    onresourcetimingbufferfull: ((this: Performance, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/timeOrigin) */\\n    readonly timeOrigin: DOMHighResTimeStamp;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/timing)\\n     */\\n    readonly timing: PerformanceTiming;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/clearMarks) */\\n    clearMarks(markName?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/clearMeasures) */\\n    clearMeasures(measureName?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/clearResourceTimings) */\\n    clearResourceTimings(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/getEntries) */\\n    getEntries(): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/getEntriesByName) */\\n    getEntriesByName(name: string, type?: string): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/getEntriesByType) */\\n    getEntriesByType(type: string): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/mark) */\\n    mark(markName: string, markOptions?: PerformanceMarkOptions): PerformanceMark;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/measure) */\\n    measure(measureName: string, startOrMeasureOptions?: string | PerformanceMeasureOptions, endMark?: string): PerformanceMeasure;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/now) */\\n    now(): DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/setResourceTimingBufferSize) */\\n    setResourceTimingBufferSize(maxSize: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/toJSON) */\\n    toJSON(): any;\\n    addEventListener<K extends keyof PerformanceEventMap>(type: K, listener: (this: Performance, ev: PerformanceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof PerformanceEventMap>(type: K, listener: (this: Performance, ev: PerformanceEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Performance: {\\n    prototype: Performance;\\n    new(): Performance;\\n};\\n\\n/**\\n * Encapsulates a single performance metric that is part of the performance timeline. A performance entry can be directly created by making a performance mark or measure (for example by calling the mark() method) at an explicit point in an application. Performance entries are also created in indirect ways such as loading a resource (such as an image).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry)\\n */\\ninterface PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/duration) */\\n    readonly duration: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/entryType) */\\n    readonly entryType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/startTime) */\\n    readonly startTime: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PerformanceEntry: {\\n    prototype: PerformanceEntry;\\n    new(): PerformanceEntry;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEventTiming) */\\ninterface PerformanceEventTiming extends PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEventTiming/cancelable) */\\n    readonly cancelable: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEventTiming/processingEnd) */\\n    readonly processingEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEventTiming/processingStart) */\\n    readonly processingStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEventTiming/target) */\\n    readonly target: Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEventTiming/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PerformanceEventTiming: {\\n    prototype: PerformanceEventTiming;\\n    new(): PerformanceEventTiming;\\n};\\n\\n/**\\n * PerformanceMark is an abstract interface for PerformanceEntry objects with an entryType of \\\"mark\\\". Entries of this type are created by calling performance.mark() to add a named DOMHighResTimeStamp (the mark) to the browser's performance timeline.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMark)\\n */\\ninterface PerformanceMark extends PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMark/detail) */\\n    readonly detail: any;\\n}\\n\\ndeclare var PerformanceMark: {\\n    prototype: PerformanceMark;\\n    new(markName: string, markOptions?: PerformanceMarkOptions): PerformanceMark;\\n};\\n\\n/**\\n * PerformanceMeasure is an abstract interface for PerformanceEntry objects with an entryType of \\\"measure\\\". Entries of this type are created by calling performance.measure() to add a named DOMHighResTimeStamp (the measure) between two marks to the browser's performance timeline.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMeasure)\\n */\\ninterface PerformanceMeasure extends PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMeasure/detail) */\\n    readonly detail: any;\\n}\\n\\ndeclare var PerformanceMeasure: {\\n    prototype: PerformanceMeasure;\\n    new(): PerformanceMeasure;\\n};\\n\\n/**\\n * The legacy PerformanceNavigation interface represents information about how the navigation to the current document was done.\\n * @deprecated This interface is deprecated in the Navigation Timing Level 2 specification. Please use the PerformanceNavigationTiming interface instead.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigation)\\n */\\ninterface PerformanceNavigation {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigation/redirectCount)\\n     */\\n    readonly redirectCount: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigation/type)\\n     */\\n    readonly type: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigation/toJSON)\\n     */\\n    toJSON(): any;\\n    readonly TYPE_NAVIGATE: 0;\\n    readonly TYPE_RELOAD: 1;\\n    readonly TYPE_BACK_FORWARD: 2;\\n    readonly TYPE_RESERVED: 255;\\n}\\n\\n/** @deprecated */\\ndeclare var PerformanceNavigation: {\\n    prototype: PerformanceNavigation;\\n    new(): PerformanceNavigation;\\n    readonly TYPE_NAVIGATE: 0;\\n    readonly TYPE_RELOAD: 1;\\n    readonly TYPE_BACK_FORWARD: 2;\\n    readonly TYPE_RESERVED: 255;\\n};\\n\\n/**\\n * Provides methods and properties to store and retrieve metrics regarding the browser's document navigation events. For example, this interface can be used to determine how much time it takes to load or unload a document.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming)\\n */\\ninterface PerformanceNavigationTiming extends PerformanceResourceTiming {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/domComplete) */\\n    readonly domComplete: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/domContentLoadedEventEnd) */\\n    readonly domContentLoadedEventEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/domContentLoadedEventStart) */\\n    readonly domContentLoadedEventStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/domInteractive) */\\n    readonly domInteractive: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/loadEventEnd) */\\n    readonly loadEventEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/loadEventStart) */\\n    readonly loadEventStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/redirectCount) */\\n    readonly redirectCount: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/type) */\\n    readonly type: NavigationTimingType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/unloadEventEnd) */\\n    readonly unloadEventEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/unloadEventStart) */\\n    readonly unloadEventStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceNavigationTiming/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PerformanceNavigationTiming: {\\n    prototype: PerformanceNavigationTiming;\\n    new(): PerformanceNavigationTiming;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver) */\\ninterface PerformanceObserver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver/disconnect) */\\n    disconnect(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver/observe) */\\n    observe(options?: PerformanceObserverInit): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver/takeRecords) */\\n    takeRecords(): PerformanceEntryList;\\n}\\n\\ndeclare var PerformanceObserver: {\\n    prototype: PerformanceObserver;\\n    new(callback: PerformanceObserverCallback): PerformanceObserver;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver/supportedEntryTypes_static) */\\n    readonly supportedEntryTypes: ReadonlyArray<string>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserverEntryList) */\\ninterface PerformanceObserverEntryList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserverEntryList/getEntries) */\\n    getEntries(): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserverEntryList/getEntriesByName) */\\n    getEntriesByName(name: string, type?: string): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserverEntryList/getEntriesByType) */\\n    getEntriesByType(type: string): PerformanceEntryList;\\n}\\n\\ndeclare var PerformanceObserverEntryList: {\\n    prototype: PerformanceObserverEntryList;\\n    new(): PerformanceObserverEntryList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformancePaintTiming) */\\ninterface PerformancePaintTiming extends PerformanceEntry {\\n}\\n\\ndeclare var PerformancePaintTiming: {\\n    prototype: PerformancePaintTiming;\\n    new(): PerformancePaintTiming;\\n};\\n\\n/**\\n * Enables retrieval and analysis of detailed network timing data regarding the loading of an application's resources. An application can use the timing metrics to determine, for example, the length of time it takes to fetch a specific resource, such as an XMLHttpRequest, <SVG>, image, or script.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming)\\n */\\ninterface PerformanceResourceTiming extends PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/connectEnd) */\\n    readonly connectEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/connectStart) */\\n    readonly connectStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/decodedBodySize) */\\n    readonly decodedBodySize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/domainLookupEnd) */\\n    readonly domainLookupEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/domainLookupStart) */\\n    readonly domainLookupStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/encodedBodySize) */\\n    readonly encodedBodySize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/fetchStart) */\\n    readonly fetchStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/initiatorType) */\\n    readonly initiatorType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/nextHopProtocol) */\\n    readonly nextHopProtocol: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/redirectEnd) */\\n    readonly redirectEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/redirectStart) */\\n    readonly redirectStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/requestStart) */\\n    readonly requestStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/responseEnd) */\\n    readonly responseEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/responseStart) */\\n    readonly responseStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/secureConnectionStart) */\\n    readonly secureConnectionStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/serverTiming) */\\n    readonly serverTiming: ReadonlyArray<PerformanceServerTiming>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/transferSize) */\\n    readonly transferSize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/workerStart) */\\n    readonly workerStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PerformanceResourceTiming: {\\n    prototype: PerformanceResourceTiming;\\n    new(): PerformanceResourceTiming;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming) */\\ninterface PerformanceServerTiming {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming/description) */\\n    readonly description: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming/duration) */\\n    readonly duration: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PerformanceServerTiming: {\\n    prototype: PerformanceServerTiming;\\n    new(): PerformanceServerTiming;\\n};\\n\\n/**\\n * A legacy interface kept for backwards compatibility and contains properties that offer performance timing information for various events which occur during the loading and use of the current page. You get a PerformanceTiming object describing your page using the window.performance.timing property.\\n * @deprecated This interface is deprecated in the Navigation Timing Level 2 specification. Please use the PerformanceNavigationTiming interface instead.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming)\\n */\\ninterface PerformanceTiming {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/connectEnd)\\n     */\\n    readonly connectEnd: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/connectStart)\\n     */\\n    readonly connectStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/domComplete)\\n     */\\n    readonly domComplete: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/domContentLoadedEventEnd)\\n     */\\n    readonly domContentLoadedEventEnd: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/domContentLoadedEventStart)\\n     */\\n    readonly domContentLoadedEventStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/domInteractive)\\n     */\\n    readonly domInteractive: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/domLoading)\\n     */\\n    readonly domLoading: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/domainLookupEnd)\\n     */\\n    readonly domainLookupEnd: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/domainLookupStart)\\n     */\\n    readonly domainLookupStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/fetchStart)\\n     */\\n    readonly fetchStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/loadEventEnd)\\n     */\\n    readonly loadEventEnd: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/loadEventStart)\\n     */\\n    readonly loadEventStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/navigationStart)\\n     */\\n    readonly navigationStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/redirectEnd)\\n     */\\n    readonly redirectEnd: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/redirectStart)\\n     */\\n    readonly redirectStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/requestStart)\\n     */\\n    readonly requestStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/responseEnd)\\n     */\\n    readonly responseEnd: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/responseStart)\\n     */\\n    readonly responseStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/secureConnectionStart)\\n     */\\n    readonly secureConnectionStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/unloadEventEnd)\\n     */\\n    readonly unloadEventEnd: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/unloadEventStart)\\n     */\\n    readonly unloadEventStart: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceTiming/toJSON)\\n     */\\n    toJSON(): any;\\n}\\n\\n/** @deprecated */\\ndeclare var PerformanceTiming: {\\n    prototype: PerformanceTiming;\\n    new(): PerformanceTiming;\\n};\\n\\n/**\\n * PeriodicWave has no inputs or outputs; it is used to define custom oscillators when calling OscillatorNode.setPeriodicWave(). The PeriodicWave itself is created/returned by AudioContext.createPeriodicWave().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PeriodicWave)\\n */\\ninterface PeriodicWave {\\n}\\n\\ndeclare var PeriodicWave: {\\n    prototype: PeriodicWave;\\n    new(context: BaseAudioContext, options?: PeriodicWaveOptions): PeriodicWave;\\n};\\n\\ninterface PermissionStatusEventMap {\\n    \\\"change\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PermissionStatus) */\\ninterface PermissionStatus extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PermissionStatus/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PermissionStatus/change_event) */\\n    onchange: ((this: PermissionStatus, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state) */\\n    readonly state: PermissionState;\\n    addEventListener<K extends keyof PermissionStatusEventMap>(type: K, listener: (this: PermissionStatus, ev: PermissionStatusEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof PermissionStatusEventMap>(type: K, listener: (this: PermissionStatus, ev: PermissionStatusEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var PermissionStatus: {\\n    prototype: PermissionStatus;\\n    new(): PermissionStatus;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Permissions) */\\ninterface Permissions {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Permissions/query) */\\n    query(permissionDesc: PermissionDescriptor): Promise<PermissionStatus>;\\n}\\n\\ndeclare var Permissions: {\\n    prototype: Permissions;\\n    new(): Permissions;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PictureInPictureEvent) */\\ninterface PictureInPictureEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PictureInPictureEvent/pictureInPictureWindow) */\\n    readonly pictureInPictureWindow: PictureInPictureWindow;\\n}\\n\\ndeclare var PictureInPictureEvent: {\\n    prototype: PictureInPictureEvent;\\n    new(type: string, eventInitDict: PictureInPictureEventInit): PictureInPictureEvent;\\n};\\n\\ninterface PictureInPictureWindowEventMap {\\n    \\\"resize\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PictureInPictureWindow) */\\ninterface PictureInPictureWindow extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PictureInPictureWindow/height) */\\n    readonly height: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PictureInPictureWindow/resize_event) */\\n    onresize: ((this: PictureInPictureWindow, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PictureInPictureWindow/width) */\\n    readonly width: number;\\n    addEventListener<K extends keyof PictureInPictureWindowEventMap>(type: K, listener: (this: PictureInPictureWindow, ev: PictureInPictureWindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof PictureInPictureWindowEventMap>(type: K, listener: (this: PictureInPictureWindow, ev: PictureInPictureWindowEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var PictureInPictureWindow: {\\n    prototype: PictureInPictureWindow;\\n    new(): PictureInPictureWindow;\\n};\\n\\n/**\\n * Provides information about a browser plugin.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Plugin)\\n */\\ninterface Plugin {\\n    /**\\n     * Returns the plugin's description.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Plugin/description)\\n     */\\n    readonly description: string;\\n    /**\\n     * Returns the plugin library's filename, if applicable on the current platform.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Plugin/filename)\\n     */\\n    readonly filename: string;\\n    /**\\n     * Returns the number of MIME types, represented by MimeType objects, supported by the plugin.\\n     * @deprecated\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the plugin's name.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Plugin/name)\\n     */\\n    readonly name: string;\\n    /**\\n     * Returns the specified MimeType object.\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Plugin/item)\\n     */\\n    item(index: number): MimeType | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Plugin/namedItem)\\n     */\\n    namedItem(name: string): MimeType | null;\\n    [index: number]: MimeType;\\n}\\n\\n/** @deprecated */\\ndeclare var Plugin: {\\n    prototype: Plugin;\\n    new(): Plugin;\\n};\\n\\n/**\\n * Used to store a list of Plugin objects describing the available plugins; it's returned by the window.navigator.plugins property. The PluginArray is not a JavaScript array, but has the length property and supports accessing individual items using bracket notation (plugins[2]), as well as via item(index) and namedItem(\\\"name\\\") methods.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PluginArray)\\n */\\ninterface PluginArray {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PluginArray/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PluginArray/item)\\n     */\\n    item(index: number): Plugin | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PluginArray/namedItem)\\n     */\\n    namedItem(name: string): Plugin | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PluginArray/refresh)\\n     */\\n    refresh(): void;\\n    [index: number]: Plugin;\\n}\\n\\n/** @deprecated */\\ndeclare var PluginArray: {\\n    prototype: PluginArray;\\n    new(): PluginArray;\\n};\\n\\n/**\\n * The state of a DOM event produced by a pointer such as the geometry of the contact point, the device type that generated the event, the amount of pressure that was applied on the contact surface, etc.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent)\\n */\\ninterface PointerEvent extends MouseEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/height) */\\n    readonly height: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/isPrimary) */\\n    readonly isPrimary: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/pointerId) */\\n    readonly pointerId: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/pointerType) */\\n    readonly pointerType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/pressure) */\\n    readonly pressure: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/tangentialPressure) */\\n    readonly tangentialPressure: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/tiltX) */\\n    readonly tiltX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/tiltY) */\\n    readonly tiltY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/twist) */\\n    readonly twist: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/width) */\\n    readonly width: number;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PointerEvent/getCoalescedEvents)\\n     */\\n    getCoalescedEvents(): PointerEvent[];\\n    getPredictedEvents(): PointerEvent[];\\n}\\n\\ndeclare var PointerEvent: {\\n    prototype: PointerEvent;\\n    new(type: string, eventInitDict?: PointerEventInit): PointerEvent;\\n};\\n\\n/**\\n * PopStateEvent is an event handler for the popstate event on the window.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PopStateEvent)\\n */\\ninterface PopStateEvent extends Event {\\n    /**\\n     * Returns a copy of the information that was provided to pushState() or replaceState().\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PopStateEvent/state)\\n     */\\n    readonly state: any;\\n}\\n\\ndeclare var PopStateEvent: {\\n    prototype: PopStateEvent;\\n    new(type: string, eventInitDict?: PopStateEventInit): PopStateEvent;\\n};\\n\\ninterface PopoverInvokerElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/popoverTargetAction) */\\n    popoverTargetAction: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLButtonElement/popoverTargetElement) */\\n    popoverTargetElement: Element | null;\\n}\\n\\n/**\\n * A processing instruction embeds application-specific instructions in XML which can be ignored by other applications that don't recognize them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProcessingInstruction)\\n */\\ninterface ProcessingInstruction extends CharacterData, LinkStyle {\\n    readonly ownerDocument: Document;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProcessingInstruction/target) */\\n    readonly target: string;\\n}\\n\\ndeclare var ProcessingInstruction: {\\n    prototype: ProcessingInstruction;\\n    new(): ProcessingInstruction;\\n};\\n\\n/**\\n * Events measuring progress of an underlying process, like an HTTP request (for an XMLHttpRequest, or the loading of the underlying resource of an <img>, <audio>, <video>, <style> or <link>).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent)\\n */\\ninterface ProgressEvent<T extends EventTarget = EventTarget> extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/lengthComputable) */\\n    readonly lengthComputable: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/loaded) */\\n    readonly loaded: number;\\n    readonly target: T | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/total) */\\n    readonly total: number;\\n}\\n\\ndeclare var ProgressEvent: {\\n    prototype: ProgressEvent;\\n    new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent) */\\ninterface PromiseRejectionEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent/promise) */\\n    readonly promise: Promise<any>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent/reason) */\\n    readonly reason: any;\\n}\\n\\ndeclare var PromiseRejectionEvent: {\\n    prototype: PromiseRejectionEvent;\\n    new(type: string, eventInitDict: PromiseRejectionEventInit): PromiseRejectionEvent;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PublicKeyCredential)\\n */\\ninterface PublicKeyCredential extends Credential {\\n    readonly authenticatorAttachment: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PublicKeyCredential/rawId) */\\n    readonly rawId: ArrayBuffer;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PublicKeyCredential/response) */\\n    readonly response: AuthenticatorResponse;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PublicKeyCredential/getClientExtensionResults) */\\n    getClientExtensionResults(): AuthenticationExtensionsClientOutputs;\\n}\\n\\ndeclare var PublicKeyCredential: {\\n    prototype: PublicKeyCredential;\\n    new(): PublicKeyCredential;\\n    isConditionalMediationAvailable(): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PublicKeyCredential/isUserVerifyingPlatformAuthenticatorAvailable_static) */\\n    isUserVerifyingPlatformAuthenticatorAvailable(): Promise<boolean>;\\n};\\n\\n/**\\n * This Push API interface provides a way to receive notifications from third-party servers as well as request URLs for push notifications.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager)\\n */\\ninterface PushManager {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager/getSubscription) */\\n    getSubscription(): Promise<PushSubscription | null>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager/permissionState) */\\n    permissionState(options?: PushSubscriptionOptionsInit): Promise<PermissionState>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager/subscribe) */\\n    subscribe(options?: PushSubscriptionOptionsInit): Promise<PushSubscription>;\\n}\\n\\ndeclare var PushManager: {\\n    prototype: PushManager;\\n    new(): PushManager;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager/supportedContentEncodings_static) */\\n    readonly supportedContentEncodings: ReadonlyArray<string>;\\n};\\n\\n/**\\n * This Push API interface provides a subcription's URL endpoint and allows unsubscription from a push service.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription)\\n */\\ninterface PushSubscription {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/endpoint) */\\n    readonly endpoint: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/expirationTime) */\\n    readonly expirationTime: EpochTimeStamp | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/options) */\\n    readonly options: PushSubscriptionOptions;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/getKey) */\\n    getKey(name: PushEncryptionKeyName): ArrayBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/toJSON) */\\n    toJSON(): PushSubscriptionJSON;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/unsubscribe) */\\n    unsubscribe(): Promise<boolean>;\\n}\\n\\ndeclare var PushSubscription: {\\n    prototype: PushSubscription;\\n    new(): PushSubscription;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscriptionOptions)\\n */\\ninterface PushSubscriptionOptions {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscriptionOptions/applicationServerKey) */\\n    readonly applicationServerKey: ArrayBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscriptionOptions/userVisibleOnly) */\\n    readonly userVisibleOnly: boolean;\\n}\\n\\ndeclare var PushSubscriptionOptions: {\\n    prototype: PushSubscriptionOptions;\\n    new(): PushSubscriptionOptions;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCCertificate) */\\ninterface RTCCertificate {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCCertificate/expires) */\\n    readonly expires: EpochTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCCertificate/getFingerprints) */\\n    getFingerprints(): RTCDtlsFingerprint[];\\n}\\n\\ndeclare var RTCCertificate: {\\n    prototype: RTCCertificate;\\n    new(): RTCCertificate;\\n};\\n\\ninterface RTCDTMFSenderEventMap {\\n    \\\"tonechange\\\": RTCDTMFToneChangeEvent;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDTMFSender) */\\ninterface RTCDTMFSender extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDTMFSender/canInsertDTMF) */\\n    readonly canInsertDTMF: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDTMFSender/tonechange_event) */\\n    ontonechange: ((this: RTCDTMFSender, ev: RTCDTMFToneChangeEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDTMFSender/toneBuffer) */\\n    readonly toneBuffer: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDTMFSender/insertDTMF) */\\n    insertDTMF(tones: string, duration?: number, interToneGap?: number): void;\\n    addEventListener<K extends keyof RTCDTMFSenderEventMap>(type: K, listener: (this: RTCDTMFSender, ev: RTCDTMFSenderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof RTCDTMFSenderEventMap>(type: K, listener: (this: RTCDTMFSender, ev: RTCDTMFSenderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var RTCDTMFSender: {\\n    prototype: RTCDTMFSender;\\n    new(): RTCDTMFSender;\\n};\\n\\n/**\\n * Events sent to indicate that DTMF tones have started or finished playing. This interface is used by the tonechange event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDTMFToneChangeEvent)\\n */\\ninterface RTCDTMFToneChangeEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDTMFToneChangeEvent/tone) */\\n    readonly tone: string;\\n}\\n\\ndeclare var RTCDTMFToneChangeEvent: {\\n    prototype: RTCDTMFToneChangeEvent;\\n    new(type: string, eventInitDict?: RTCDTMFToneChangeEventInit): RTCDTMFToneChangeEvent;\\n};\\n\\ninterface RTCDataChannelEventMap {\\n    \\\"bufferedamountlow\\\": Event;\\n    \\\"close\\\": Event;\\n    \\\"closing\\\": Event;\\n    \\\"error\\\": Event;\\n    \\\"message\\\": MessageEvent;\\n    \\\"open\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel) */\\ninterface RTCDataChannel extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/binaryType) */\\n    binaryType: BinaryType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/bufferedAmount) */\\n    readonly bufferedAmount: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/bufferedAmountLowThreshold) */\\n    bufferedAmountLowThreshold: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/id) */\\n    readonly id: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/label) */\\n    readonly label: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/maxPacketLifeTime) */\\n    readonly maxPacketLifeTime: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/maxRetransmits) */\\n    readonly maxRetransmits: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/negotiated) */\\n    readonly negotiated: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/bufferedamountlow_event) */\\n    onbufferedamountlow: ((this: RTCDataChannel, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/close_event) */\\n    onclose: ((this: RTCDataChannel, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/closing_event) */\\n    onclosing: ((this: RTCDataChannel, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/error_event) */\\n    onerror: ((this: RTCDataChannel, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/message_event) */\\n    onmessage: ((this: RTCDataChannel, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/open_event) */\\n    onopen: ((this: RTCDataChannel, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/ordered) */\\n    readonly ordered: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/protocol) */\\n    readonly protocol: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/readyState) */\\n    readonly readyState: RTCDataChannelState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannel/send) */\\n    send(data: string): void;\\n    send(data: Blob): void;\\n    send(data: ArrayBuffer): void;\\n    send(data: ArrayBufferView): void;\\n    addEventListener<K extends keyof RTCDataChannelEventMap>(type: K, listener: (this: RTCDataChannel, ev: RTCDataChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof RTCDataChannelEventMap>(type: K, listener: (this: RTCDataChannel, ev: RTCDataChannelEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var RTCDataChannel: {\\n    prototype: RTCDataChannel;\\n    new(): RTCDataChannel;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannelEvent) */\\ninterface RTCDataChannelEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDataChannelEvent/channel) */\\n    readonly channel: RTCDataChannel;\\n}\\n\\ndeclare var RTCDataChannelEvent: {\\n    prototype: RTCDataChannelEvent;\\n    new(type: string, eventInitDict: RTCDataChannelEventInit): RTCDataChannelEvent;\\n};\\n\\ninterface RTCDtlsTransportEventMap {\\n    \\\"error\\\": Event;\\n    \\\"statechange\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDtlsTransport) */\\ninterface RTCDtlsTransport extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDtlsTransport/iceTransport) */\\n    readonly iceTransport: RTCIceTransport;\\n    onerror: ((this: RTCDtlsTransport, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDtlsTransport/statechange_event) */\\n    onstatechange: ((this: RTCDtlsTransport, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDtlsTransport/state) */\\n    readonly state: RTCDtlsTransportState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCDtlsTransport/getRemoteCertificates) */\\n    getRemoteCertificates(): ArrayBuffer[];\\n    addEventListener<K extends keyof RTCDtlsTransportEventMap>(type: K, listener: (this: RTCDtlsTransport, ev: RTCDtlsTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof RTCDtlsTransportEventMap>(type: K, listener: (this: RTCDtlsTransport, ev: RTCDtlsTransportEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var RTCDtlsTransport: {\\n    prototype: RTCDtlsTransport;\\n    new(): RTCDtlsTransport;\\n};\\n\\ninterface RTCEncodedAudioFrame {\\n    data: ArrayBuffer;\\n    readonly timestamp: number;\\n    getMetadata(): RTCEncodedAudioFrameMetadata;\\n}\\n\\ndeclare var RTCEncodedAudioFrame: {\\n    prototype: RTCEncodedAudioFrame;\\n    new(): RTCEncodedAudioFrame;\\n};\\n\\ninterface RTCEncodedVideoFrame {\\n    data: ArrayBuffer;\\n    readonly timestamp: number;\\n    readonly type: RTCEncodedVideoFrameType;\\n    getMetadata(): RTCEncodedVideoFrameMetadata;\\n}\\n\\ndeclare var RTCEncodedVideoFrame: {\\n    prototype: RTCEncodedVideoFrame;\\n    new(): RTCEncodedVideoFrame;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCError) */\\ninterface RTCError extends DOMException {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCError/errorDetail) */\\n    readonly errorDetail: RTCErrorDetailType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCError/receivedAlert) */\\n    readonly receivedAlert: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCError/sctpCauseCode) */\\n    readonly sctpCauseCode: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCError/sdpLineNumber) */\\n    readonly sdpLineNumber: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCError/sentAlert) */\\n    readonly sentAlert: number | null;\\n}\\n\\ndeclare var RTCError: {\\n    prototype: RTCError;\\n    new(init: RTCErrorInit, message?: string): RTCError;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCErrorEvent) */\\ninterface RTCErrorEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCErrorEvent/error) */\\n    readonly error: RTCError;\\n}\\n\\ndeclare var RTCErrorEvent: {\\n    prototype: RTCErrorEvent;\\n    new(type: string, eventInitDict: RTCErrorEventInit): RTCErrorEvent;\\n};\\n\\n/**\\n * The RTCIceCandidate interface—part of the WebRTC API—represents a candidate Internet Connectivity Establishment (ICE) configuration which may be used to establish an RTCPeerConnection.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate)\\n */\\ninterface RTCIceCandidate {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/address) */\\n    readonly address: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/candidate) */\\n    readonly candidate: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/component) */\\n    readonly component: RTCIceComponent | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/foundation) */\\n    readonly foundation: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/port) */\\n    readonly port: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/priority) */\\n    readonly priority: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/protocol) */\\n    readonly protocol: RTCIceProtocol | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/relatedAddress) */\\n    readonly relatedAddress: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/relatedPort) */\\n    readonly relatedPort: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/sdpMLineIndex) */\\n    readonly sdpMLineIndex: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/sdpMid) */\\n    readonly sdpMid: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/tcpType) */\\n    readonly tcpType: RTCIceTcpCandidateType | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/type) */\\n    readonly type: RTCIceCandidateType | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/usernameFragment) */\\n    readonly usernameFragment: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceCandidate/toJSON) */\\n    toJSON(): RTCIceCandidateInit;\\n}\\n\\ndeclare var RTCIceCandidate: {\\n    prototype: RTCIceCandidate;\\n    new(candidateInitDict?: RTCIceCandidateInit): RTCIceCandidate;\\n};\\n\\ninterface RTCIceTransportEventMap {\\n    \\\"gatheringstatechange\\\": Event;\\n    \\\"selectedcandidatepairchange\\\": Event;\\n    \\\"statechange\\\": Event;\\n}\\n\\n/**\\n * Provides access to information about the ICE transport layer over which the data is being sent and received.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceTransport)\\n */\\ninterface RTCIceTransport extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceTransport/gatheringState) */\\n    readonly gatheringState: RTCIceGathererState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceTransport/gatheringstatechange_event) */\\n    ongatheringstatechange: ((this: RTCIceTransport, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceTransport/selectedcandidatepairchange_event) */\\n    onselectedcandidatepairchange: ((this: RTCIceTransport, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceTransport/statechange_event) */\\n    onstatechange: ((this: RTCIceTransport, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceTransport/state) */\\n    readonly state: RTCIceTransportState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCIceTransport/getSelectedCandidatePair) */\\n    getSelectedCandidatePair(): RTCIceCandidatePair | null;\\n    addEventListener<K extends keyof RTCIceTransportEventMap>(type: K, listener: (this: RTCIceTransport, ev: RTCIceTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof RTCIceTransportEventMap>(type: K, listener: (this: RTCIceTransport, ev: RTCIceTransportEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var RTCIceTransport: {\\n    prototype: RTCIceTransport;\\n    new(): RTCIceTransport;\\n};\\n\\ninterface RTCPeerConnectionEventMap {\\n    \\\"connectionstatechange\\\": Event;\\n    \\\"datachannel\\\": RTCDataChannelEvent;\\n    \\\"icecandidate\\\": RTCPeerConnectionIceEvent;\\n    \\\"icecandidateerror\\\": Event;\\n    \\\"iceconnectionstatechange\\\": Event;\\n    \\\"icegatheringstatechange\\\": Event;\\n    \\\"negotiationneeded\\\": Event;\\n    \\\"signalingstatechange\\\": Event;\\n    \\\"track\\\": RTCTrackEvent;\\n}\\n\\n/**\\n * A WebRTC connection between the local computer and a remote peer. It provides methods to connect to a remote peer, maintain and monitor the connection, and close the connection once it's no longer needed.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection)\\n */\\ninterface RTCPeerConnection extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/canTrickleIceCandidates) */\\n    readonly canTrickleIceCandidates: boolean | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/connectionState) */\\n    readonly connectionState: RTCPeerConnectionState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/currentLocalDescription) */\\n    readonly currentLocalDescription: RTCSessionDescription | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/currentRemoteDescription) */\\n    readonly currentRemoteDescription: RTCSessionDescription | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/iceConnectionState) */\\n    readonly iceConnectionState: RTCIceConnectionState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/iceGatheringState) */\\n    readonly iceGatheringState: RTCIceGatheringState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/localDescription) */\\n    readonly localDescription: RTCSessionDescription | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/connectionstatechange_event) */\\n    onconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/datachannel_event) */\\n    ondatachannel: ((this: RTCPeerConnection, ev: RTCDataChannelEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/icecandidate_event) */\\n    onicecandidate: ((this: RTCPeerConnection, ev: RTCPeerConnectionIceEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/icecandidateerror_event) */\\n    onicecandidateerror: ((this: RTCPeerConnection, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/iceconnectionstatechange_event) */\\n    oniceconnectionstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/icegatheringstatechange_event) */\\n    onicegatheringstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/negotiationneeded_event) */\\n    onnegotiationneeded: ((this: RTCPeerConnection, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/signalingstatechange_event) */\\n    onsignalingstatechange: ((this: RTCPeerConnection, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/track_event) */\\n    ontrack: ((this: RTCPeerConnection, ev: RTCTrackEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/pendingLocalDescription) */\\n    readonly pendingLocalDescription: RTCSessionDescription | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/pendingRemoteDescription) */\\n    readonly pendingRemoteDescription: RTCSessionDescription | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/remoteDescription) */\\n    readonly remoteDescription: RTCSessionDescription | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/sctp) */\\n    readonly sctp: RTCSctpTransport | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/signalingState) */\\n    readonly signalingState: RTCSignalingState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/addIceCandidate) */\\n    addIceCandidate(candidate?: RTCIceCandidateInit): Promise<void>;\\n    /** @deprecated */\\n    addIceCandidate(candidate: RTCIceCandidateInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/addTrack) */\\n    addTrack(track: MediaStreamTrack, ...streams: MediaStream[]): RTCRtpSender;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/addTransceiver) */\\n    addTransceiver(trackOrKind: MediaStreamTrack | string, init?: RTCRtpTransceiverInit): RTCRtpTransceiver;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/createAnswer) */\\n    createAnswer(options?: RTCAnswerOptions): Promise<RTCSessionDescriptionInit>;\\n    /** @deprecated */\\n    createAnswer(successCallback: RTCSessionDescriptionCallback, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/createDataChannel) */\\n    createDataChannel(label: string, dataChannelDict?: RTCDataChannelInit): RTCDataChannel;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/createOffer) */\\n    createOffer(options?: RTCOfferOptions): Promise<RTCSessionDescriptionInit>;\\n    /** @deprecated */\\n    createOffer(successCallback: RTCSessionDescriptionCallback, failureCallback: RTCPeerConnectionErrorCallback, options?: RTCOfferOptions): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/getConfiguration) */\\n    getConfiguration(): RTCConfiguration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/getReceivers) */\\n    getReceivers(): RTCRtpReceiver[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/getSenders) */\\n    getSenders(): RTCRtpSender[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/getStats) */\\n    getStats(selector?: MediaStreamTrack | null): Promise<RTCStatsReport>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/getTransceivers) */\\n    getTransceivers(): RTCRtpTransceiver[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/removeTrack) */\\n    removeTrack(sender: RTCRtpSender): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/restartIce) */\\n    restartIce(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/setConfiguration) */\\n    setConfiguration(configuration?: RTCConfiguration): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/setLocalDescription) */\\n    setLocalDescription(description?: RTCLocalSessionDescriptionInit): Promise<void>;\\n    /** @deprecated */\\n    setLocalDescription(description: RTCLocalSessionDescriptionInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/setRemoteDescription) */\\n    setRemoteDescription(description: RTCSessionDescriptionInit): Promise<void>;\\n    /** @deprecated */\\n    setRemoteDescription(description: RTCSessionDescriptionInit, successCallback: VoidFunction, failureCallback: RTCPeerConnectionErrorCallback): Promise<void>;\\n    addEventListener<K extends keyof RTCPeerConnectionEventMap>(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof RTCPeerConnectionEventMap>(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var RTCPeerConnection: {\\n    prototype: RTCPeerConnection;\\n    new(configuration?: RTCConfiguration): RTCPeerConnection;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnection/generateCertificate_static) */\\n    generateCertificate(keygenAlgorithm: AlgorithmIdentifier): Promise<RTCCertificate>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnectionIceErrorEvent) */\\ninterface RTCPeerConnectionIceErrorEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnectionIceErrorEvent/address) */\\n    readonly address: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnectionIceErrorEvent/errorCode) */\\n    readonly errorCode: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnectionIceErrorEvent/errorText) */\\n    readonly errorText: string;\\n    readonly port: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnectionIceErrorEvent/url) */\\n    readonly url: string;\\n}\\n\\ndeclare var RTCPeerConnectionIceErrorEvent: {\\n    prototype: RTCPeerConnectionIceErrorEvent;\\n    new(type: string, eventInitDict: RTCPeerConnectionIceErrorEventInit): RTCPeerConnectionIceErrorEvent;\\n};\\n\\n/**\\n * Events that occurs in relation to ICE candidates with the target, usually an RTCPeerConnection. Only one event is of this type: icecandidate.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnectionIceEvent)\\n */\\ninterface RTCPeerConnectionIceEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCPeerConnectionIceEvent/candidate) */\\n    readonly candidate: RTCIceCandidate | null;\\n}\\n\\ndeclare var RTCPeerConnectionIceEvent: {\\n    prototype: RTCPeerConnectionIceEvent;\\n    new(type: string, eventInitDict?: RTCPeerConnectionIceEventInit): RTCPeerConnectionIceEvent;\\n};\\n\\n/**\\n * This WebRTC API interface manages the reception and decoding of data for a MediaStreamTrack on an RTCPeerConnection.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpReceiver)\\n */\\ninterface RTCRtpReceiver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpReceiver/track) */\\n    readonly track: MediaStreamTrack;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpReceiver/transport) */\\n    readonly transport: RTCDtlsTransport | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpReceiver/getContributingSources) */\\n    getContributingSources(): RTCRtpContributingSource[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpReceiver/getParameters) */\\n    getParameters(): RTCRtpReceiveParameters;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpReceiver/getStats) */\\n    getStats(): Promise<RTCStatsReport>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpReceiver/getSynchronizationSources) */\\n    getSynchronizationSources(): RTCRtpSynchronizationSource[];\\n}\\n\\ndeclare var RTCRtpReceiver: {\\n    prototype: RTCRtpReceiver;\\n    new(): RTCRtpReceiver;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpReceiver/getCapabilities_static) */\\n    getCapabilities(kind: string): RTCRtpCapabilities | null;\\n};\\n\\n/**\\n * Provides the ability to control and obtain details about how a particular MediaStreamTrack is encoded and sent to a remote peer.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender)\\n */\\ninterface RTCRtpSender {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/dtmf) */\\n    readonly dtmf: RTCDTMFSender | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/track) */\\n    readonly track: MediaStreamTrack | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/transport) */\\n    readonly transport: RTCDtlsTransport | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/getParameters) */\\n    getParameters(): RTCRtpSendParameters;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/getStats) */\\n    getStats(): Promise<RTCStatsReport>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/replaceTrack) */\\n    replaceTrack(withTrack: MediaStreamTrack | null): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/setParameters) */\\n    setParameters(parameters: RTCRtpSendParameters): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/setStreams) */\\n    setStreams(...streams: MediaStream[]): void;\\n}\\n\\ndeclare var RTCRtpSender: {\\n    prototype: RTCRtpSender;\\n    new(): RTCRtpSender;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpSender/getCapabilities_static) */\\n    getCapabilities(kind: string): RTCRtpCapabilities | null;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver) */\\ninterface RTCRtpTransceiver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver/currentDirection) */\\n    readonly currentDirection: RTCRtpTransceiverDirection | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver/direction) */\\n    direction: RTCRtpTransceiverDirection;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver/mid) */\\n    readonly mid: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver/receiver) */\\n    readonly receiver: RTCRtpReceiver;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver/sender) */\\n    readonly sender: RTCRtpSender;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver/setCodecPreferences) */\\n    setCodecPreferences(codecs: RTCRtpCodecCapability[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver/stop) */\\n    stop(): void;\\n}\\n\\ndeclare var RTCRtpTransceiver: {\\n    prototype: RTCRtpTransceiver;\\n    new(): RTCRtpTransceiver;\\n};\\n\\ninterface RTCSctpTransportEventMap {\\n    \\\"statechange\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSctpTransport) */\\ninterface RTCSctpTransport extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSctpTransport/maxChannels) */\\n    readonly maxChannels: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSctpTransport/maxMessageSize) */\\n    readonly maxMessageSize: number;\\n    onstatechange: ((this: RTCSctpTransport, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSctpTransport/state) */\\n    readonly state: RTCSctpTransportState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSctpTransport/transport) */\\n    readonly transport: RTCDtlsTransport;\\n    addEventListener<K extends keyof RTCSctpTransportEventMap>(type: K, listener: (this: RTCSctpTransport, ev: RTCSctpTransportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof RTCSctpTransportEventMap>(type: K, listener: (this: RTCSctpTransport, ev: RTCSctpTransportEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var RTCSctpTransport: {\\n    prototype: RTCSctpTransport;\\n    new(): RTCSctpTransport;\\n};\\n\\n/**\\n * One end of a connection—or potential connection—and how it's configured. Each RTCSessionDescription consists of a description type indicating which part of the offer/answer negotiation process it describes and of the SDP descriptor of the session.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSessionDescription)\\n */\\ninterface RTCSessionDescription {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSessionDescription/sdp) */\\n    readonly sdp: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSessionDescription/type) */\\n    readonly type: RTCSdpType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCSessionDescription/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var RTCSessionDescription: {\\n    prototype: RTCSessionDescription;\\n    new(descriptionInitDict: RTCSessionDescriptionInit): RTCSessionDescription;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCStatsReport) */\\ninterface RTCStatsReport {\\n    forEach(callbackfn: (value: any, key: string, parent: RTCStatsReport) => void, thisArg?: any): void;\\n}\\n\\ndeclare var RTCStatsReport: {\\n    prototype: RTCStatsReport;\\n    new(): RTCStatsReport;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCTrackEvent) */\\ninterface RTCTrackEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCTrackEvent/receiver) */\\n    readonly receiver: RTCRtpReceiver;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCTrackEvent/streams) */\\n    readonly streams: ReadonlyArray<MediaStream>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCTrackEvent/track) */\\n    readonly track: MediaStreamTrack;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCTrackEvent/transceiver) */\\n    readonly transceiver: RTCRtpTransceiver;\\n}\\n\\ndeclare var RTCTrackEvent: {\\n    prototype: RTCTrackEvent;\\n    new(type: string, eventInitDict: RTCTrackEventInit): RTCTrackEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RadioNodeList) */\\ninterface RadioNodeList extends NodeList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RadioNodeList/value) */\\n    value: string;\\n}\\n\\ndeclare var RadioNodeList: {\\n    prototype: RadioNodeList;\\n    new(): RadioNodeList;\\n};\\n\\n/**\\n * A fragment of a document that can contain nodes and parts of text nodes.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range)\\n */\\ninterface Range extends AbstractRange {\\n    /**\\n     * Returns the node, furthest away from the document, that is an ancestor of both range's start node and end node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/commonAncestorContainer)\\n     */\\n    readonly commonAncestorContainer: Node;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/cloneContents) */\\n    cloneContents(): DocumentFragment;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/cloneRange) */\\n    cloneRange(): Range;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/collapse) */\\n    collapse(toStart?: boolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/compareBoundaryPoints) */\\n    compareBoundaryPoints(how: number, sourceRange: Range): number;\\n    /**\\n     * Returns −1 if the point is before the range, 0 if the point is in the range, and 1 if the point is after the range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/comparePoint)\\n     */\\n    comparePoint(node: Node, offset: number): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/createContextualFragment) */\\n    createContextualFragment(fragment: string): DocumentFragment;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/deleteContents) */\\n    deleteContents(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/detach) */\\n    detach(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/extractContents) */\\n    extractContents(): DocumentFragment;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/getBoundingClientRect) */\\n    getBoundingClientRect(): DOMRect;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/getClientRects) */\\n    getClientRects(): DOMRectList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/insertNode) */\\n    insertNode(node: Node): void;\\n    /**\\n     * Returns whether range intersects node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/intersectsNode)\\n     */\\n    intersectsNode(node: Node): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/isPointInRange) */\\n    isPointInRange(node: Node, offset: number): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/selectNode) */\\n    selectNode(node: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/selectNodeContents) */\\n    selectNodeContents(node: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/setEnd) */\\n    setEnd(node: Node, offset: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/setEndAfter) */\\n    setEndAfter(node: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/setEndBefore) */\\n    setEndBefore(node: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/setStart) */\\n    setStart(node: Node, offset: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/setStartAfter) */\\n    setStartAfter(node: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/setStartBefore) */\\n    setStartBefore(node: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Range/surroundContents) */\\n    surroundContents(newParent: Node): void;\\n    toString(): string;\\n    readonly START_TO_START: 0;\\n    readonly START_TO_END: 1;\\n    readonly END_TO_END: 2;\\n    readonly END_TO_START: 3;\\n}\\n\\ndeclare var Range: {\\n    prototype: Range;\\n    new(): Range;\\n    readonly START_TO_START: 0;\\n    readonly START_TO_END: 1;\\n    readonly END_TO_END: 2;\\n    readonly END_TO_START: 3;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController) */\\ninterface ReadableByteStreamController {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/byobRequest) */\\n    readonly byobRequest: ReadableStreamBYOBRequest | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/desiredSize) */\\n    readonly desiredSize: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/enqueue) */\\n    enqueue(chunk: ArrayBufferView): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/error) */\\n    error(e?: any): void;\\n}\\n\\ndeclare var ReadableByteStreamController: {\\n    prototype: ReadableByteStreamController;\\n    new(): ReadableByteStreamController;\\n};\\n\\n/**\\n * This Streams API interface represents a readable stream of byte data. The Fetch API offers a concrete instance of a ReadableStream through the body property of a Response object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream)\\n */\\ninterface ReadableStream<R = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/locked) */\\n    readonly locked: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/cancel) */\\n    cancel(reason?: any): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/getReader) */\\n    getReader(options: { mode: \\\"byob\\\" }): ReadableStreamBYOBReader;\\n    getReader(): ReadableStreamDefaultReader<R>;\\n    getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader<R>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/pipeThrough) */\\n    pipeThrough<T>(transform: ReadableWritablePair<T, R>, options?: StreamPipeOptions): ReadableStream<T>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/pipeTo) */\\n    pipeTo(destination: WritableStream<R>, options?: StreamPipeOptions): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/tee) */\\n    tee(): [ReadableStream<R>, ReadableStream<R>];\\n}\\n\\ndeclare var ReadableStream: {\\n    prototype: ReadableStream;\\n    new(underlyingSource: UnderlyingByteSource, strategy?: { highWaterMark?: number }): ReadableStream<Uint8Array>;\\n    new<R = any>(underlyingSource: UnderlyingDefaultSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;\\n    new<R = any>(underlyingSource?: UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader) */\\ninterface ReadableStreamBYOBReader extends ReadableStreamGenericReader {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/read) */\\n    read<T extends ArrayBufferView>(view: T): Promise<ReadableStreamReadResult<T>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/releaseLock) */\\n    releaseLock(): void;\\n}\\n\\ndeclare var ReadableStreamBYOBReader: {\\n    prototype: ReadableStreamBYOBReader;\\n    new(stream: ReadableStream): ReadableStreamBYOBReader;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest) */\\ninterface ReadableStreamBYOBRequest {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/view) */\\n    readonly view: ArrayBufferView | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/respond) */\\n    respond(bytesWritten: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/respondWithNewView) */\\n    respondWithNewView(view: ArrayBufferView): void;\\n}\\n\\ndeclare var ReadableStreamBYOBRequest: {\\n    prototype: ReadableStreamBYOBRequest;\\n    new(): ReadableStreamBYOBRequest;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController) */\\ninterface ReadableStreamDefaultController<R = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController/desiredSize) */\\n    readonly desiredSize: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController/enqueue) */\\n    enqueue(chunk?: R): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController/error) */\\n    error(e?: any): void;\\n}\\n\\ndeclare var ReadableStreamDefaultController: {\\n    prototype: ReadableStreamDefaultController;\\n    new(): ReadableStreamDefaultController;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultReader) */\\ninterface ReadableStreamDefaultReader<R = any> extends ReadableStreamGenericReader {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultReader/read) */\\n    read(): Promise<ReadableStreamReadResult<R>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultReader/releaseLock) */\\n    releaseLock(): void;\\n}\\n\\ndeclare var ReadableStreamDefaultReader: {\\n    prototype: ReadableStreamDefaultReader;\\n    new<R = any>(stream: ReadableStream<R>): ReadableStreamDefaultReader<R>;\\n};\\n\\ninterface ReadableStreamGenericReader {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/closed) */\\n    readonly closed: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/cancel) */\\n    cancel(reason?: any): Promise<void>;\\n}\\n\\ninterface RemotePlaybackEventMap {\\n    \\\"connect\\\": Event;\\n    \\\"connecting\\\": Event;\\n    \\\"disconnect\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RemotePlayback) */\\ninterface RemotePlayback extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RemotePlayback/connect_event) */\\n    onconnect: ((this: RemotePlayback, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RemotePlayback/connecting_event) */\\n    onconnecting: ((this: RemotePlayback, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RemotePlayback/disconnect_event) */\\n    ondisconnect: ((this: RemotePlayback, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RemotePlayback/state) */\\n    readonly state: RemotePlaybackState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RemotePlayback/cancelWatchAvailability) */\\n    cancelWatchAvailability(id?: number): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RemotePlayback/prompt) */\\n    prompt(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RemotePlayback/watchAvailability) */\\n    watchAvailability(callback: RemotePlaybackAvailabilityCallback): Promise<number>;\\n    addEventListener<K extends keyof RemotePlaybackEventMap>(type: K, listener: (this: RemotePlayback, ev: RemotePlaybackEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof RemotePlaybackEventMap>(type: K, listener: (this: RemotePlayback, ev: RemotePlaybackEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var RemotePlayback: {\\n    prototype: RemotePlayback;\\n    new(): RemotePlayback;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Report) */\\ninterface Report {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Report/body) */\\n    readonly body: ReportBody | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Report/type) */\\n    readonly type: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Report/url) */\\n    readonly url: string;\\n    toJSON(): any;\\n}\\n\\ndeclare var Report: {\\n    prototype: Report;\\n    new(): Report;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportBody) */\\ninterface ReportBody {\\n    toJSON(): any;\\n}\\n\\ndeclare var ReportBody: {\\n    prototype: ReportBody;\\n    new(): ReportBody;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportingObserver) */\\ninterface ReportingObserver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportingObserver/disconnect) */\\n    disconnect(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportingObserver/observe) */\\n    observe(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportingObserver/takeRecords) */\\n    takeRecords(): ReportList;\\n}\\n\\ndeclare var ReportingObserver: {\\n    prototype: ReportingObserver;\\n    new(callback: ReportingObserverCallback, options?: ReportingObserverOptions): ReportingObserver;\\n};\\n\\n/**\\n * This Fetch API interface represents a resource request.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request)\\n */\\ninterface Request extends Body {\\n    /**\\n     * Returns the cache mode associated with request, which is a string indicating how the request will interact with the browser's cache when fetching.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/cache)\\n     */\\n    readonly cache: RequestCache;\\n    /**\\n     * Returns the credentials mode associated with request, which is a string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/credentials)\\n     */\\n    readonly credentials: RequestCredentials;\\n    /**\\n     * Returns the kind of resource requested by request, e.g., \\\"document\\\" or \\\"script\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/destination)\\n     */\\n    readonly destination: RequestDestination;\\n    /**\\n     * Returns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the \\\"Host\\\" header.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/headers)\\n     */\\n    readonly headers: Headers;\\n    /**\\n     * Returns request's subresource integrity metadata, which is a cryptographic hash of the resource being fetched. Its value consists of multiple hashes separated by whitespace. [SRI]\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/integrity)\\n     */\\n    readonly integrity: string;\\n    /**\\n     * Returns a boolean indicating whether or not request can outlive the global in which it was created.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/keepalive)\\n     */\\n    readonly keepalive: boolean;\\n    /**\\n     * Returns request's HTTP method, which is \\\"GET\\\" by default.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/method)\\n     */\\n    readonly method: string;\\n    /**\\n     * Returns the mode associated with request, which is a string indicating whether the request will use CORS, or will be restricted to same-origin URLs.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/mode)\\n     */\\n    readonly mode: RequestMode;\\n    /**\\n     * Returns the redirect mode associated with request, which is a string indicating how redirects for the request will be handled during fetching. A request will follow redirects by default.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/redirect)\\n     */\\n    readonly redirect: RequestRedirect;\\n    /**\\n     * Returns the referrer of request. Its value can be a same-origin URL if explicitly set in init, the empty string to indicate no referrer, and \\\"about:client\\\" when defaulting to the global's default. This is used during fetching to determine the value of the `Referer` header of the request being made.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/referrer)\\n     */\\n    readonly referrer: string;\\n    /**\\n     * Returns the referrer policy associated with request. This is used during fetching to compute the value of the request's referrer.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/referrerPolicy)\\n     */\\n    readonly referrerPolicy: ReferrerPolicy;\\n    /**\\n     * Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort event handler.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/signal)\\n     */\\n    readonly signal: AbortSignal;\\n    /**\\n     * Returns the URL of request as a string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/url)\\n     */\\n    readonly url: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/clone) */\\n    clone(): Request;\\n}\\n\\ndeclare var Request: {\\n    prototype: Request;\\n    new(input: RequestInfo | URL, init?: RequestInit): Request;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserver) */\\ninterface ResizeObserver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserver/disconnect) */\\n    disconnect(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserver/observe) */\\n    observe(target: Element, options?: ResizeObserverOptions): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserver/unobserve) */\\n    unobserve(target: Element): void;\\n}\\n\\ndeclare var ResizeObserver: {\\n    prototype: ResizeObserver;\\n    new(callback: ResizeObserverCallback): ResizeObserver;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserverEntry) */\\ninterface ResizeObserverEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserverEntry/borderBoxSize) */\\n    readonly borderBoxSize: ReadonlyArray<ResizeObserverSize>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserverEntry/contentBoxSize) */\\n    readonly contentBoxSize: ReadonlyArray<ResizeObserverSize>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserverEntry/contentRect) */\\n    readonly contentRect: DOMRectReadOnly;\\n    readonly devicePixelContentBoxSize: ReadonlyArray<ResizeObserverSize>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserverEntry/target) */\\n    readonly target: Element;\\n}\\n\\ndeclare var ResizeObserverEntry: {\\n    prototype: ResizeObserverEntry;\\n    new(): ResizeObserverEntry;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserverSize) */\\ninterface ResizeObserverSize {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserverSize/blockSize) */\\n    readonly blockSize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ResizeObserverSize/inlineSize) */\\n    readonly inlineSize: number;\\n}\\n\\ndeclare var ResizeObserverSize: {\\n    prototype: ResizeObserverSize;\\n    new(): ResizeObserverSize;\\n};\\n\\n/**\\n * This Fetch API interface represents the response to a request.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response)\\n */\\ninterface Response extends Body {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/headers) */\\n    readonly headers: Headers;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/ok) */\\n    readonly ok: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/redirected) */\\n    readonly redirected: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/status) */\\n    readonly status: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/statusText) */\\n    readonly statusText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/type) */\\n    readonly type: ResponseType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/url) */\\n    readonly url: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/clone) */\\n    clone(): Response;\\n}\\n\\ndeclare var Response: {\\n    prototype: Response;\\n    new(body?: BodyInit | null, init?: ResponseInit): Response;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/error_static) */\\n    error(): Response;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/json_static) */\\n    json(data: any, init?: ResponseInit): Response;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/redirect_static) */\\n    redirect(url: string | URL, status?: number): Response;\\n};\\n\\n/**\\n * Provides access to the properties of <a> element, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAElement)\\n */\\ninterface SVGAElement extends SVGGraphicsElement, SVGURIReference {\\n    rel: string;\\n    readonly relList: DOMTokenList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAElement/target) */\\n    readonly target: SVGAnimatedString;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGAElement: {\\n    prototype: SVGAElement;\\n    new(): SVGAElement;\\n};\\n\\n/**\\n * Used to represent a value that can be an <angle> or <number> value. An SVGAngle reflected through the animVal attribute is always read only.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAngle)\\n */\\ninterface SVGAngle {\\n    readonly unitType: number;\\n    value: number;\\n    valueAsString: string;\\n    valueInSpecifiedUnits: number;\\n    convertToSpecifiedUnits(unitType: number): void;\\n    newValueSpecifiedUnits(unitType: number, valueInSpecifiedUnits: number): void;\\n    readonly SVG_ANGLETYPE_UNKNOWN: 0;\\n    readonly SVG_ANGLETYPE_UNSPECIFIED: 1;\\n    readonly SVG_ANGLETYPE_DEG: 2;\\n    readonly SVG_ANGLETYPE_RAD: 3;\\n    readonly SVG_ANGLETYPE_GRAD: 4;\\n}\\n\\ndeclare var SVGAngle: {\\n    prototype: SVGAngle;\\n    new(): SVGAngle;\\n    readonly SVG_ANGLETYPE_UNKNOWN: 0;\\n    readonly SVG_ANGLETYPE_UNSPECIFIED: 1;\\n    readonly SVG_ANGLETYPE_DEG: 2;\\n    readonly SVG_ANGLETYPE_RAD: 3;\\n    readonly SVG_ANGLETYPE_GRAD: 4;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimateElement) */\\ninterface SVGAnimateElement extends SVGAnimationElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAnimateElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAnimateElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGAnimateElement: {\\n    prototype: SVGAnimateElement;\\n    new(): SVGAnimateElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimateMotionElement) */\\ninterface SVGAnimateMotionElement extends SVGAnimationElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAnimateMotionElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAnimateMotionElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGAnimateMotionElement: {\\n    prototype: SVGAnimateMotionElement;\\n    new(): SVGAnimateMotionElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimateTransformElement) */\\ninterface SVGAnimateTransformElement extends SVGAnimationElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAnimateTransformElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAnimateTransformElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGAnimateTransformElement: {\\n    prototype: SVGAnimateTransformElement;\\n    new(): SVGAnimateTransformElement;\\n};\\n\\n/**\\n * Used for attributes of basic type <angle> which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedAngle)\\n */\\ninterface SVGAnimatedAngle {\\n    readonly animVal: SVGAngle;\\n    readonly baseVal: SVGAngle;\\n}\\n\\ndeclare var SVGAnimatedAngle: {\\n    prototype: SVGAnimatedAngle;\\n    new(): SVGAnimatedAngle;\\n};\\n\\n/**\\n * Used for attributes of type boolean which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedBoolean)\\n */\\ninterface SVGAnimatedBoolean {\\n    readonly animVal: boolean;\\n    baseVal: boolean;\\n}\\n\\ndeclare var SVGAnimatedBoolean: {\\n    prototype: SVGAnimatedBoolean;\\n    new(): SVGAnimatedBoolean;\\n};\\n\\n/**\\n * Used for attributes whose value must be a constant from a particular enumeration and which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedEnumeration)\\n */\\ninterface SVGAnimatedEnumeration {\\n    readonly animVal: number;\\n    baseVal: number;\\n}\\n\\ndeclare var SVGAnimatedEnumeration: {\\n    prototype: SVGAnimatedEnumeration;\\n    new(): SVGAnimatedEnumeration;\\n};\\n\\n/**\\n * Used for attributes of basic type <integer> which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedInteger)\\n */\\ninterface SVGAnimatedInteger {\\n    readonly animVal: number;\\n    baseVal: number;\\n}\\n\\ndeclare var SVGAnimatedInteger: {\\n    prototype: SVGAnimatedInteger;\\n    new(): SVGAnimatedInteger;\\n};\\n\\n/**\\n * Used for attributes of basic type <length> which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedLength)\\n */\\ninterface SVGAnimatedLength {\\n    readonly animVal: SVGLength;\\n    readonly baseVal: SVGLength;\\n}\\n\\ndeclare var SVGAnimatedLength: {\\n    prototype: SVGAnimatedLength;\\n    new(): SVGAnimatedLength;\\n};\\n\\n/**\\n * Used for attributes of type SVGLengthList which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedLengthList)\\n */\\ninterface SVGAnimatedLengthList {\\n    readonly animVal: SVGLengthList;\\n    readonly baseVal: SVGLengthList;\\n}\\n\\ndeclare var SVGAnimatedLengthList: {\\n    prototype: SVGAnimatedLengthList;\\n    new(): SVGAnimatedLengthList;\\n};\\n\\n/**\\n * Used for attributes of basic type <Number> which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedNumber)\\n */\\ninterface SVGAnimatedNumber {\\n    readonly animVal: number;\\n    baseVal: number;\\n}\\n\\ndeclare var SVGAnimatedNumber: {\\n    prototype: SVGAnimatedNumber;\\n    new(): SVGAnimatedNumber;\\n};\\n\\n/**\\n * The SVGAnimatedNumber interface is used for attributes which take a list of numbers and which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedNumberList)\\n */\\ninterface SVGAnimatedNumberList {\\n    readonly animVal: SVGNumberList;\\n    readonly baseVal: SVGNumberList;\\n}\\n\\ndeclare var SVGAnimatedNumberList: {\\n    prototype: SVGAnimatedNumberList;\\n    new(): SVGAnimatedNumberList;\\n};\\n\\ninterface SVGAnimatedPoints {\\n    readonly animatedPoints: SVGPointList;\\n    readonly points: SVGPointList;\\n}\\n\\n/**\\n * Used for attributes of type SVGPreserveAspectRatio which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedPreserveAspectRatio)\\n */\\ninterface SVGAnimatedPreserveAspectRatio {\\n    readonly animVal: SVGPreserveAspectRatio;\\n    readonly baseVal: SVGPreserveAspectRatio;\\n}\\n\\ndeclare var SVGAnimatedPreserveAspectRatio: {\\n    prototype: SVGAnimatedPreserveAspectRatio;\\n    new(): SVGAnimatedPreserveAspectRatio;\\n};\\n\\n/**\\n * Used for attributes of basic SVGRect which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedRect)\\n */\\ninterface SVGAnimatedRect {\\n    readonly animVal: DOMRectReadOnly;\\n    readonly baseVal: DOMRect;\\n}\\n\\ndeclare var SVGAnimatedRect: {\\n    prototype: SVGAnimatedRect;\\n    new(): SVGAnimatedRect;\\n};\\n\\n/**\\n * The SVGAnimatedString interface represents string attributes which can be animated from each SVG declaration. You need to create SVG attribute before doing anything else, everything should be declared inside this.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedString)\\n */\\ninterface SVGAnimatedString {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedString/animVal) */\\n    readonly animVal: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedString/baseVal) */\\n    baseVal: string;\\n}\\n\\ndeclare var SVGAnimatedString: {\\n    prototype: SVGAnimatedString;\\n    new(): SVGAnimatedString;\\n};\\n\\n/**\\n * Used for attributes which take a list of numbers and which can be animated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimatedTransformList)\\n */\\ninterface SVGAnimatedTransformList {\\n    readonly animVal: SVGTransformList;\\n    readonly baseVal: SVGTransformList;\\n}\\n\\ndeclare var SVGAnimatedTransformList: {\\n    prototype: SVGAnimatedTransformList;\\n    new(): SVGAnimatedTransformList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimationElement) */\\ninterface SVGAnimationElement extends SVGElement, SVGTests {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGAnimationElement/targetElement) */\\n    readonly targetElement: SVGElement | null;\\n    beginElement(): void;\\n    beginElementAt(offset: number): void;\\n    endElement(): void;\\n    endElementAt(offset: number): void;\\n    getCurrentTime(): number;\\n    getSimpleDuration(): number;\\n    getStartTime(): number;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAnimationElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGAnimationElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGAnimationElement: {\\n    prototype: SVGAnimationElement;\\n    new(): SVGAnimationElement;\\n};\\n\\n/**\\n * An interface for the <circle> element. The circle element is defined by the cx and cy attributes that denote the coordinates of the centre of the circle.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGCircleElement)\\n */\\ninterface SVGCircleElement extends SVGGeometryElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGCircleElement/cx) */\\n    readonly cx: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGCircleElement/cy) */\\n    readonly cy: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGCircleElement/r) */\\n    readonly r: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGCircleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGCircleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGCircleElement: {\\n    prototype: SVGCircleElement;\\n    new(): SVGCircleElement;\\n};\\n\\n/**\\n * Provides access to the properties of <clipPath> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGClipPathElement)\\n */\\ninterface SVGClipPathElement extends SVGElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGClipPathElement/clipPathUnits) */\\n    readonly clipPathUnits: SVGAnimatedEnumeration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGClipPathElement/transform) */\\n    readonly transform: SVGAnimatedTransformList;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGClipPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGClipPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGClipPathElement: {\\n    prototype: SVGClipPathElement;\\n    new(): SVGClipPathElement;\\n};\\n\\n/**\\n * A base interface used by the component transfer function interfaces.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGComponentTransferFunctionElement)\\n */\\ninterface SVGComponentTransferFunctionElement extends SVGElement {\\n    readonly amplitude: SVGAnimatedNumber;\\n    readonly exponent: SVGAnimatedNumber;\\n    readonly intercept: SVGAnimatedNumber;\\n    readonly offset: SVGAnimatedNumber;\\n    readonly slope: SVGAnimatedNumber;\\n    readonly tableValues: SVGAnimatedNumberList;\\n    readonly type: SVGAnimatedEnumeration;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: 0;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY: 1;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_TABLE: 2;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE: 3;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: 4;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_GAMMA: 5;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGComponentTransferFunctionElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGComponentTransferFunctionElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGComponentTransferFunctionElement: {\\n    prototype: SVGComponentTransferFunctionElement;\\n    new(): SVGComponentTransferFunctionElement;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN: 0;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY: 1;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_TABLE: 2;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE: 3;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_LINEAR: 4;\\n    readonly SVG_FECOMPONENTTRANSFER_TYPE_GAMMA: 5;\\n};\\n\\n/**\\n * Corresponds to the <defs> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGDefsElement)\\n */\\ninterface SVGDefsElement extends SVGGraphicsElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGDefsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGDefsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGDefsElement: {\\n    prototype: SVGDefsElement;\\n    new(): SVGDefsElement;\\n};\\n\\n/**\\n * Corresponds to the <desc> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGDescElement)\\n */\\ninterface SVGDescElement extends SVGElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGDescElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGDescElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGDescElement: {\\n    prototype: SVGDescElement;\\n    new(): SVGDescElement;\\n};\\n\\ninterface SVGElementEventMap extends ElementEventMap, GlobalEventHandlersEventMap {\\n}\\n\\n/**\\n * All of the SVG DOM interfaces that correspond directly to elements in the SVG language derive from the SVGElement interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement)\\n */\\ninterface SVGElement extends Element, ElementCSSInlineStyle, GlobalEventHandlers, HTMLOrSVGElement {\\n    /** @deprecated */\\n    readonly className: any;\\n    readonly ownerSVGElement: SVGSVGElement | null;\\n    readonly viewportElement: SVGElement | null;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGElement: {\\n    prototype: SVGElement;\\n    new(): SVGElement;\\n};\\n\\n/**\\n * Provides access to the properties of <ellipse> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGEllipseElement)\\n */\\ninterface SVGEllipseElement extends SVGGeometryElement {\\n    readonly cx: SVGAnimatedLength;\\n    readonly cy: SVGAnimatedLength;\\n    readonly rx: SVGAnimatedLength;\\n    readonly ry: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGEllipseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGEllipseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGEllipseElement: {\\n    prototype: SVGEllipseElement;\\n    new(): SVGEllipseElement;\\n};\\n\\n/**\\n * Corresponds to the <feBlend> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEBlendElement)\\n */\\ninterface SVGFEBlendElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly in1: SVGAnimatedString;\\n    readonly in2: SVGAnimatedString;\\n    readonly mode: SVGAnimatedEnumeration;\\n    readonly SVG_FEBLEND_MODE_UNKNOWN: 0;\\n    readonly SVG_FEBLEND_MODE_NORMAL: 1;\\n    readonly SVG_FEBLEND_MODE_MULTIPLY: 2;\\n    readonly SVG_FEBLEND_MODE_SCREEN: 3;\\n    readonly SVG_FEBLEND_MODE_DARKEN: 4;\\n    readonly SVG_FEBLEND_MODE_LIGHTEN: 5;\\n    readonly SVG_FEBLEND_MODE_OVERLAY: 6;\\n    readonly SVG_FEBLEND_MODE_COLOR_DODGE: 7;\\n    readonly SVG_FEBLEND_MODE_COLOR_BURN: 8;\\n    readonly SVG_FEBLEND_MODE_HARD_LIGHT: 9;\\n    readonly SVG_FEBLEND_MODE_SOFT_LIGHT: 10;\\n    readonly SVG_FEBLEND_MODE_DIFFERENCE: 11;\\n    readonly SVG_FEBLEND_MODE_EXCLUSION: 12;\\n    readonly SVG_FEBLEND_MODE_HUE: 13;\\n    readonly SVG_FEBLEND_MODE_SATURATION: 14;\\n    readonly SVG_FEBLEND_MODE_COLOR: 15;\\n    readonly SVG_FEBLEND_MODE_LUMINOSITY: 16;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEBlendElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEBlendElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEBlendElement: {\\n    prototype: SVGFEBlendElement;\\n    new(): SVGFEBlendElement;\\n    readonly SVG_FEBLEND_MODE_UNKNOWN: 0;\\n    readonly SVG_FEBLEND_MODE_NORMAL: 1;\\n    readonly SVG_FEBLEND_MODE_MULTIPLY: 2;\\n    readonly SVG_FEBLEND_MODE_SCREEN: 3;\\n    readonly SVG_FEBLEND_MODE_DARKEN: 4;\\n    readonly SVG_FEBLEND_MODE_LIGHTEN: 5;\\n    readonly SVG_FEBLEND_MODE_OVERLAY: 6;\\n    readonly SVG_FEBLEND_MODE_COLOR_DODGE: 7;\\n    readonly SVG_FEBLEND_MODE_COLOR_BURN: 8;\\n    readonly SVG_FEBLEND_MODE_HARD_LIGHT: 9;\\n    readonly SVG_FEBLEND_MODE_SOFT_LIGHT: 10;\\n    readonly SVG_FEBLEND_MODE_DIFFERENCE: 11;\\n    readonly SVG_FEBLEND_MODE_EXCLUSION: 12;\\n    readonly SVG_FEBLEND_MODE_HUE: 13;\\n    readonly SVG_FEBLEND_MODE_SATURATION: 14;\\n    readonly SVG_FEBLEND_MODE_COLOR: 15;\\n    readonly SVG_FEBLEND_MODE_LUMINOSITY: 16;\\n};\\n\\n/**\\n * Corresponds to the <feColorMatrix> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEColorMatrixElement)\\n */\\ninterface SVGFEColorMatrixElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEColorMatrixElement/in1) */\\n    readonly in1: SVGAnimatedString;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEColorMatrixElement/type) */\\n    readonly type: SVGAnimatedEnumeration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEColorMatrixElement/values) */\\n    readonly values: SVGAnimatedNumberList;\\n    readonly SVG_FECOLORMATRIX_TYPE_UNKNOWN: 0;\\n    readonly SVG_FECOLORMATRIX_TYPE_MATRIX: 1;\\n    readonly SVG_FECOLORMATRIX_TYPE_SATURATE: 2;\\n    readonly SVG_FECOLORMATRIX_TYPE_HUEROTATE: 3;\\n    readonly SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA: 4;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEColorMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEColorMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEColorMatrixElement: {\\n    prototype: SVGFEColorMatrixElement;\\n    new(): SVGFEColorMatrixElement;\\n    readonly SVG_FECOLORMATRIX_TYPE_UNKNOWN: 0;\\n    readonly SVG_FECOLORMATRIX_TYPE_MATRIX: 1;\\n    readonly SVG_FECOLORMATRIX_TYPE_SATURATE: 2;\\n    readonly SVG_FECOLORMATRIX_TYPE_HUEROTATE: 3;\\n    readonly SVG_FECOLORMATRIX_TYPE_LUMINANCETOALPHA: 4;\\n};\\n\\n/**\\n * Corresponds to the <feComponentTransfer> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEComponentTransferElement)\\n */\\ninterface SVGFEComponentTransferElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly in1: SVGAnimatedString;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEComponentTransferElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEComponentTransferElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEComponentTransferElement: {\\n    prototype: SVGFEComponentTransferElement;\\n    new(): SVGFEComponentTransferElement;\\n};\\n\\n/**\\n * Corresponds to the <feComposite> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFECompositeElement)\\n */\\ninterface SVGFECompositeElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly in1: SVGAnimatedString;\\n    readonly in2: SVGAnimatedString;\\n    readonly k1: SVGAnimatedNumber;\\n    readonly k2: SVGAnimatedNumber;\\n    readonly k3: SVGAnimatedNumber;\\n    readonly k4: SVGAnimatedNumber;\\n    readonly operator: SVGAnimatedEnumeration;\\n    readonly SVG_FECOMPOSITE_OPERATOR_UNKNOWN: 0;\\n    readonly SVG_FECOMPOSITE_OPERATOR_OVER: 1;\\n    readonly SVG_FECOMPOSITE_OPERATOR_IN: 2;\\n    readonly SVG_FECOMPOSITE_OPERATOR_OUT: 3;\\n    readonly SVG_FECOMPOSITE_OPERATOR_ATOP: 4;\\n    readonly SVG_FECOMPOSITE_OPERATOR_XOR: 5;\\n    readonly SVG_FECOMPOSITE_OPERATOR_ARITHMETIC: 6;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFECompositeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFECompositeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFECompositeElement: {\\n    prototype: SVGFECompositeElement;\\n    new(): SVGFECompositeElement;\\n    readonly SVG_FECOMPOSITE_OPERATOR_UNKNOWN: 0;\\n    readonly SVG_FECOMPOSITE_OPERATOR_OVER: 1;\\n    readonly SVG_FECOMPOSITE_OPERATOR_IN: 2;\\n    readonly SVG_FECOMPOSITE_OPERATOR_OUT: 3;\\n    readonly SVG_FECOMPOSITE_OPERATOR_ATOP: 4;\\n    readonly SVG_FECOMPOSITE_OPERATOR_XOR: 5;\\n    readonly SVG_FECOMPOSITE_OPERATOR_ARITHMETIC: 6;\\n};\\n\\n/**\\n * Corresponds to the <feConvolveMatrix> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEConvolveMatrixElement)\\n */\\ninterface SVGFEConvolveMatrixElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly bias: SVGAnimatedNumber;\\n    readonly divisor: SVGAnimatedNumber;\\n    readonly edgeMode: SVGAnimatedEnumeration;\\n    readonly in1: SVGAnimatedString;\\n    readonly kernelMatrix: SVGAnimatedNumberList;\\n    readonly kernelUnitLengthX: SVGAnimatedNumber;\\n    readonly kernelUnitLengthY: SVGAnimatedNumber;\\n    readonly orderX: SVGAnimatedInteger;\\n    readonly orderY: SVGAnimatedInteger;\\n    readonly preserveAlpha: SVGAnimatedBoolean;\\n    readonly targetX: SVGAnimatedInteger;\\n    readonly targetY: SVGAnimatedInteger;\\n    readonly SVG_EDGEMODE_UNKNOWN: 0;\\n    readonly SVG_EDGEMODE_DUPLICATE: 1;\\n    readonly SVG_EDGEMODE_WRAP: 2;\\n    readonly SVG_EDGEMODE_NONE: 3;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEConvolveMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEConvolveMatrixElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEConvolveMatrixElement: {\\n    prototype: SVGFEConvolveMatrixElement;\\n    new(): SVGFEConvolveMatrixElement;\\n    readonly SVG_EDGEMODE_UNKNOWN: 0;\\n    readonly SVG_EDGEMODE_DUPLICATE: 1;\\n    readonly SVG_EDGEMODE_WRAP: 2;\\n    readonly SVG_EDGEMODE_NONE: 3;\\n};\\n\\n/**\\n * Corresponds to the <feDiffuseLighting> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEDiffuseLightingElement)\\n */\\ninterface SVGFEDiffuseLightingElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly diffuseConstant: SVGAnimatedNumber;\\n    readonly in1: SVGAnimatedString;\\n    readonly kernelUnitLengthX: SVGAnimatedNumber;\\n    readonly kernelUnitLengthY: SVGAnimatedNumber;\\n    readonly surfaceScale: SVGAnimatedNumber;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEDiffuseLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEDiffuseLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEDiffuseLightingElement: {\\n    prototype: SVGFEDiffuseLightingElement;\\n    new(): SVGFEDiffuseLightingElement;\\n};\\n\\n/**\\n * Corresponds to the <feDisplacementMap> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEDisplacementMapElement)\\n */\\ninterface SVGFEDisplacementMapElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly in1: SVGAnimatedString;\\n    readonly in2: SVGAnimatedString;\\n    readonly scale: SVGAnimatedNumber;\\n    readonly xChannelSelector: SVGAnimatedEnumeration;\\n    readonly yChannelSelector: SVGAnimatedEnumeration;\\n    readonly SVG_CHANNEL_UNKNOWN: 0;\\n    readonly SVG_CHANNEL_R: 1;\\n    readonly SVG_CHANNEL_G: 2;\\n    readonly SVG_CHANNEL_B: 3;\\n    readonly SVG_CHANNEL_A: 4;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEDisplacementMapElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEDisplacementMapElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEDisplacementMapElement: {\\n    prototype: SVGFEDisplacementMapElement;\\n    new(): SVGFEDisplacementMapElement;\\n    readonly SVG_CHANNEL_UNKNOWN: 0;\\n    readonly SVG_CHANNEL_R: 1;\\n    readonly SVG_CHANNEL_G: 2;\\n    readonly SVG_CHANNEL_B: 3;\\n    readonly SVG_CHANNEL_A: 4;\\n};\\n\\n/**\\n * Corresponds to the <feDistantLight> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEDistantLightElement)\\n */\\ninterface SVGFEDistantLightElement extends SVGElement {\\n    readonly azimuth: SVGAnimatedNumber;\\n    readonly elevation: SVGAnimatedNumber;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEDistantLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEDistantLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEDistantLightElement: {\\n    prototype: SVGFEDistantLightElement;\\n    new(): SVGFEDistantLightElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEDropShadowElement) */\\ninterface SVGFEDropShadowElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly dx: SVGAnimatedNumber;\\n    readonly dy: SVGAnimatedNumber;\\n    readonly in1: SVGAnimatedString;\\n    readonly stdDeviationX: SVGAnimatedNumber;\\n    readonly stdDeviationY: SVGAnimatedNumber;\\n    setStdDeviation(stdDeviationX: number, stdDeviationY: number): void;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEDropShadowElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEDropShadowElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEDropShadowElement: {\\n    prototype: SVGFEDropShadowElement;\\n    new(): SVGFEDropShadowElement;\\n};\\n\\n/**\\n * Corresponds to the <feFlood> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEFloodElement)\\n */\\ninterface SVGFEFloodElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFloodElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFloodElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEFloodElement: {\\n    prototype: SVGFEFloodElement;\\n    new(): SVGFEFloodElement;\\n};\\n\\n/**\\n * Corresponds to the <feFuncA> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEFuncAElement)\\n */\\ninterface SVGFEFuncAElement extends SVGComponentTransferFunctionElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFuncAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFuncAElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEFuncAElement: {\\n    prototype: SVGFEFuncAElement;\\n    new(): SVGFEFuncAElement;\\n};\\n\\n/**\\n * Corresponds to the <feFuncB> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEFuncBElement)\\n */\\ninterface SVGFEFuncBElement extends SVGComponentTransferFunctionElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFuncBElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFuncBElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEFuncBElement: {\\n    prototype: SVGFEFuncBElement;\\n    new(): SVGFEFuncBElement;\\n};\\n\\n/**\\n * Corresponds to the <feFuncG> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEFuncGElement)\\n */\\ninterface SVGFEFuncGElement extends SVGComponentTransferFunctionElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFuncGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFuncGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEFuncGElement: {\\n    prototype: SVGFEFuncGElement;\\n    new(): SVGFEFuncGElement;\\n};\\n\\n/**\\n * Corresponds to the <feFuncR> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEFuncRElement)\\n */\\ninterface SVGFEFuncRElement extends SVGComponentTransferFunctionElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFuncRElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEFuncRElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEFuncRElement: {\\n    prototype: SVGFEFuncRElement;\\n    new(): SVGFEFuncRElement;\\n};\\n\\n/**\\n * Corresponds to the <feGaussianBlur> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEGaussianBlurElement)\\n */\\ninterface SVGFEGaussianBlurElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly in1: SVGAnimatedString;\\n    readonly stdDeviationX: SVGAnimatedNumber;\\n    readonly stdDeviationY: SVGAnimatedNumber;\\n    setStdDeviation(stdDeviationX: number, stdDeviationY: number): void;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEGaussianBlurElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEGaussianBlurElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEGaussianBlurElement: {\\n    prototype: SVGFEGaussianBlurElement;\\n    new(): SVGFEGaussianBlurElement;\\n};\\n\\n/**\\n * Corresponds to the <feImage> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEImageElement)\\n */\\ninterface SVGFEImageElement extends SVGElement, SVGFilterPrimitiveStandardAttributes, SVGURIReference {\\n    readonly preserveAspectRatio: SVGAnimatedPreserveAspectRatio;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEImageElement: {\\n    prototype: SVGFEImageElement;\\n    new(): SVGFEImageElement;\\n};\\n\\n/**\\n * Corresponds to the <feMerge> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEMergeElement)\\n */\\ninterface SVGFEMergeElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEMergeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEMergeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEMergeElement: {\\n    prototype: SVGFEMergeElement;\\n    new(): SVGFEMergeElement;\\n};\\n\\n/**\\n * Corresponds to the <feMergeNode> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEMergeNodeElement)\\n */\\ninterface SVGFEMergeNodeElement extends SVGElement {\\n    readonly in1: SVGAnimatedString;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEMergeNodeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEMergeNodeElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEMergeNodeElement: {\\n    prototype: SVGFEMergeNodeElement;\\n    new(): SVGFEMergeNodeElement;\\n};\\n\\n/**\\n * Corresponds to the <feMorphology> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEMorphologyElement)\\n */\\ninterface SVGFEMorphologyElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly in1: SVGAnimatedString;\\n    readonly operator: SVGAnimatedEnumeration;\\n    readonly radiusX: SVGAnimatedNumber;\\n    readonly radiusY: SVGAnimatedNumber;\\n    readonly SVG_MORPHOLOGY_OPERATOR_UNKNOWN: 0;\\n    readonly SVG_MORPHOLOGY_OPERATOR_ERODE: 1;\\n    readonly SVG_MORPHOLOGY_OPERATOR_DILATE: 2;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEMorphologyElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEMorphologyElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEMorphologyElement: {\\n    prototype: SVGFEMorphologyElement;\\n    new(): SVGFEMorphologyElement;\\n    readonly SVG_MORPHOLOGY_OPERATOR_UNKNOWN: 0;\\n    readonly SVG_MORPHOLOGY_OPERATOR_ERODE: 1;\\n    readonly SVG_MORPHOLOGY_OPERATOR_DILATE: 2;\\n};\\n\\n/**\\n * Corresponds to the <feOffset> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEOffsetElement)\\n */\\ninterface SVGFEOffsetElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly dx: SVGAnimatedNumber;\\n    readonly dy: SVGAnimatedNumber;\\n    readonly in1: SVGAnimatedString;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEOffsetElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEOffsetElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEOffsetElement: {\\n    prototype: SVGFEOffsetElement;\\n    new(): SVGFEOffsetElement;\\n};\\n\\n/**\\n * Corresponds to the <fePointLight> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFEPointLightElement)\\n */\\ninterface SVGFEPointLightElement extends SVGElement {\\n    readonly x: SVGAnimatedNumber;\\n    readonly y: SVGAnimatedNumber;\\n    readonly z: SVGAnimatedNumber;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEPointLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFEPointLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFEPointLightElement: {\\n    prototype: SVGFEPointLightElement;\\n    new(): SVGFEPointLightElement;\\n};\\n\\n/**\\n * Corresponds to the <feSpecularLighting> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFESpecularLightingElement)\\n */\\ninterface SVGFESpecularLightingElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly in1: SVGAnimatedString;\\n    readonly kernelUnitLengthX: SVGAnimatedNumber;\\n    readonly kernelUnitLengthY: SVGAnimatedNumber;\\n    readonly specularConstant: SVGAnimatedNumber;\\n    readonly specularExponent: SVGAnimatedNumber;\\n    readonly surfaceScale: SVGAnimatedNumber;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFESpecularLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFESpecularLightingElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFESpecularLightingElement: {\\n    prototype: SVGFESpecularLightingElement;\\n    new(): SVGFESpecularLightingElement;\\n};\\n\\n/**\\n * Corresponds to the <feSpotLight> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFESpotLightElement)\\n */\\ninterface SVGFESpotLightElement extends SVGElement {\\n    readonly limitingConeAngle: SVGAnimatedNumber;\\n    readonly pointsAtX: SVGAnimatedNumber;\\n    readonly pointsAtY: SVGAnimatedNumber;\\n    readonly pointsAtZ: SVGAnimatedNumber;\\n    readonly specularExponent: SVGAnimatedNumber;\\n    readonly x: SVGAnimatedNumber;\\n    readonly y: SVGAnimatedNumber;\\n    readonly z: SVGAnimatedNumber;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFESpotLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFESpotLightElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFESpotLightElement: {\\n    prototype: SVGFESpotLightElement;\\n    new(): SVGFESpotLightElement;\\n};\\n\\n/**\\n * Corresponds to the <feTile> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFETileElement)\\n */\\ninterface SVGFETileElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly in1: SVGAnimatedString;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFETileElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFETileElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFETileElement: {\\n    prototype: SVGFETileElement;\\n    new(): SVGFETileElement;\\n};\\n\\n/**\\n * Corresponds to the <feTurbulence> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFETurbulenceElement)\\n */\\ninterface SVGFETurbulenceElement extends SVGElement, SVGFilterPrimitiveStandardAttributes {\\n    readonly baseFrequencyX: SVGAnimatedNumber;\\n    readonly baseFrequencyY: SVGAnimatedNumber;\\n    readonly numOctaves: SVGAnimatedInteger;\\n    readonly seed: SVGAnimatedNumber;\\n    readonly stitchTiles: SVGAnimatedEnumeration;\\n    readonly type: SVGAnimatedEnumeration;\\n    readonly SVG_TURBULENCE_TYPE_UNKNOWN: 0;\\n    readonly SVG_TURBULENCE_TYPE_FRACTALNOISE: 1;\\n    readonly SVG_TURBULENCE_TYPE_TURBULENCE: 2;\\n    readonly SVG_STITCHTYPE_UNKNOWN: 0;\\n    readonly SVG_STITCHTYPE_STITCH: 1;\\n    readonly SVG_STITCHTYPE_NOSTITCH: 2;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFETurbulenceElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFETurbulenceElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFETurbulenceElement: {\\n    prototype: SVGFETurbulenceElement;\\n    new(): SVGFETurbulenceElement;\\n    readonly SVG_TURBULENCE_TYPE_UNKNOWN: 0;\\n    readonly SVG_TURBULENCE_TYPE_FRACTALNOISE: 1;\\n    readonly SVG_TURBULENCE_TYPE_TURBULENCE: 2;\\n    readonly SVG_STITCHTYPE_UNKNOWN: 0;\\n    readonly SVG_STITCHTYPE_STITCH: 1;\\n    readonly SVG_STITCHTYPE_NOSTITCH: 2;\\n};\\n\\n/**\\n * Provides access to the properties of <filter> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGFilterElement)\\n */\\ninterface SVGFilterElement extends SVGElement, SVGURIReference {\\n    readonly filterUnits: SVGAnimatedEnumeration;\\n    readonly height: SVGAnimatedLength;\\n    readonly primitiveUnits: SVGAnimatedEnumeration;\\n    readonly width: SVGAnimatedLength;\\n    readonly x: SVGAnimatedLength;\\n    readonly y: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFilterElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGFilterElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGFilterElement: {\\n    prototype: SVGFilterElement;\\n    new(): SVGFilterElement;\\n};\\n\\ninterface SVGFilterPrimitiveStandardAttributes {\\n    readonly height: SVGAnimatedLength;\\n    readonly result: SVGAnimatedString;\\n    readonly width: SVGAnimatedLength;\\n    readonly x: SVGAnimatedLength;\\n    readonly y: SVGAnimatedLength;\\n}\\n\\ninterface SVGFitToViewBox {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/preserveAspectRatio) */\\n    readonly preserveAspectRatio: SVGAnimatedPreserveAspectRatio;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/viewBox) */\\n    readonly viewBox: SVGAnimatedRect;\\n}\\n\\n/**\\n * Provides access to the properties of <foreignObject> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGForeignObjectElement)\\n */\\ninterface SVGForeignObjectElement extends SVGGraphicsElement {\\n    readonly height: SVGAnimatedLength;\\n    readonly width: SVGAnimatedLength;\\n    readonly x: SVGAnimatedLength;\\n    readonly y: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGForeignObjectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGForeignObjectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGForeignObjectElement: {\\n    prototype: SVGForeignObjectElement;\\n    new(): SVGForeignObjectElement;\\n};\\n\\n/**\\n * Corresponds to the <g> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGElement)\\n */\\ninterface SVGGElement extends SVGGraphicsElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGGElement: {\\n    prototype: SVGGElement;\\n    new(): SVGGElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGeometryElement) */\\ninterface SVGGeometryElement extends SVGGraphicsElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGeometryElement/pathLength) */\\n    readonly pathLength: SVGAnimatedNumber;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGeometryElement/getPointAtLength) */\\n    getPointAtLength(distance: number): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGeometryElement/getTotalLength) */\\n    getTotalLength(): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGeometryElement/isPointInFill) */\\n    isPointInFill(point?: DOMPointInit): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGeometryElement/isPointInStroke) */\\n    isPointInStroke(point?: DOMPointInit): boolean;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGeometryElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGeometryElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGGeometryElement: {\\n    prototype: SVGGeometryElement;\\n    new(): SVGGeometryElement;\\n};\\n\\n/**\\n * The SVGGradient interface is a base interface used by SVGLinearGradientElement and SVGRadialGradientElement.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGradientElement)\\n */\\ninterface SVGGradientElement extends SVGElement, SVGURIReference {\\n    readonly gradientTransform: SVGAnimatedTransformList;\\n    readonly gradientUnits: SVGAnimatedEnumeration;\\n    readonly spreadMethod: SVGAnimatedEnumeration;\\n    readonly SVG_SPREADMETHOD_UNKNOWN: 0;\\n    readonly SVG_SPREADMETHOD_PAD: 1;\\n    readonly SVG_SPREADMETHOD_REFLECT: 2;\\n    readonly SVG_SPREADMETHOD_REPEAT: 3;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGGradientElement: {\\n    prototype: SVGGradientElement;\\n    new(): SVGGradientElement;\\n    readonly SVG_SPREADMETHOD_UNKNOWN: 0;\\n    readonly SVG_SPREADMETHOD_PAD: 1;\\n    readonly SVG_SPREADMETHOD_REFLECT: 2;\\n    readonly SVG_SPREADMETHOD_REPEAT: 3;\\n};\\n\\n/**\\n * SVG elements whose primary purpose is to directly render graphics into a group.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGraphicsElement)\\n */\\ninterface SVGGraphicsElement extends SVGElement, SVGTests {\\n    readonly transform: SVGAnimatedTransformList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGGraphicsElement/getBBox) */\\n    getBBox(options?: SVGBoundingBoxOptions): DOMRect;\\n    getCTM(): DOMMatrix | null;\\n    getScreenCTM(): DOMMatrix | null;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGGraphicsElement: {\\n    prototype: SVGGraphicsElement;\\n    new(): SVGGraphicsElement;\\n};\\n\\n/**\\n * Corresponds to the <image> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGImageElement)\\n */\\ninterface SVGImageElement extends SVGGraphicsElement, SVGURIReference {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGImageElement/height) */\\n    readonly height: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGImageElement/preserveAspectRatio) */\\n    readonly preserveAspectRatio: SVGAnimatedPreserveAspectRatio;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGImageElement/width) */\\n    readonly width: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGImageElement/x) */\\n    readonly x: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGImageElement/y) */\\n    readonly y: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGImageElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGImageElement: {\\n    prototype: SVGImageElement;\\n    new(): SVGImageElement;\\n};\\n\\n/**\\n * Correspond to the <length> basic data type.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGLength)\\n */\\ninterface SVGLength {\\n    readonly unitType: number;\\n    value: number;\\n    valueAsString: string;\\n    valueInSpecifiedUnits: number;\\n    convertToSpecifiedUnits(unitType: number): void;\\n    newValueSpecifiedUnits(unitType: number, valueInSpecifiedUnits: number): void;\\n    readonly SVG_LENGTHTYPE_UNKNOWN: 0;\\n    readonly SVG_LENGTHTYPE_NUMBER: 1;\\n    readonly SVG_LENGTHTYPE_PERCENTAGE: 2;\\n    readonly SVG_LENGTHTYPE_EMS: 3;\\n    readonly SVG_LENGTHTYPE_EXS: 4;\\n    readonly SVG_LENGTHTYPE_PX: 5;\\n    readonly SVG_LENGTHTYPE_CM: 6;\\n    readonly SVG_LENGTHTYPE_MM: 7;\\n    readonly SVG_LENGTHTYPE_IN: 8;\\n    readonly SVG_LENGTHTYPE_PT: 9;\\n    readonly SVG_LENGTHTYPE_PC: 10;\\n}\\n\\ndeclare var SVGLength: {\\n    prototype: SVGLength;\\n    new(): SVGLength;\\n    readonly SVG_LENGTHTYPE_UNKNOWN: 0;\\n    readonly SVG_LENGTHTYPE_NUMBER: 1;\\n    readonly SVG_LENGTHTYPE_PERCENTAGE: 2;\\n    readonly SVG_LENGTHTYPE_EMS: 3;\\n    readonly SVG_LENGTHTYPE_EXS: 4;\\n    readonly SVG_LENGTHTYPE_PX: 5;\\n    readonly SVG_LENGTHTYPE_CM: 6;\\n    readonly SVG_LENGTHTYPE_MM: 7;\\n    readonly SVG_LENGTHTYPE_IN: 8;\\n    readonly SVG_LENGTHTYPE_PT: 9;\\n    readonly SVG_LENGTHTYPE_PC: 10;\\n};\\n\\n/**\\n * The SVGLengthList defines a list of SVGLength objects.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGLengthList)\\n */\\ninterface SVGLengthList {\\n    readonly length: number;\\n    readonly numberOfItems: number;\\n    appendItem(newItem: SVGLength): SVGLength;\\n    clear(): void;\\n    getItem(index: number): SVGLength;\\n    initialize(newItem: SVGLength): SVGLength;\\n    insertItemBefore(newItem: SVGLength, index: number): SVGLength;\\n    removeItem(index: number): SVGLength;\\n    replaceItem(newItem: SVGLength, index: number): SVGLength;\\n    [index: number]: SVGLength;\\n}\\n\\ndeclare var SVGLengthList: {\\n    prototype: SVGLengthList;\\n    new(): SVGLengthList;\\n};\\n\\n/**\\n * Provides access to the properties of <line> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGLineElement)\\n */\\ninterface SVGLineElement extends SVGGeometryElement {\\n    readonly x1: SVGAnimatedLength;\\n    readonly x2: SVGAnimatedLength;\\n    readonly y1: SVGAnimatedLength;\\n    readonly y2: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGLineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGLineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGLineElement: {\\n    prototype: SVGLineElement;\\n    new(): SVGLineElement;\\n};\\n\\n/**\\n * Corresponds to the <linearGradient> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGLinearGradientElement)\\n */\\ninterface SVGLinearGradientElement extends SVGGradientElement {\\n    readonly x1: SVGAnimatedLength;\\n    readonly x2: SVGAnimatedLength;\\n    readonly y1: SVGAnimatedLength;\\n    readonly y2: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGLinearGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGLinearGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGLinearGradientElement: {\\n    prototype: SVGLinearGradientElement;\\n    new(): SVGLinearGradientElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMPathElement) */\\ninterface SVGMPathElement extends SVGElement, SVGURIReference {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGMPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGMPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGMPathElement: {\\n    prototype: SVGMPathElement;\\n    new(): SVGMPathElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement) */\\ninterface SVGMarkerElement extends SVGElement, SVGFitToViewBox {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/markerHeight) */\\n    readonly markerHeight: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/markerUnits) */\\n    readonly markerUnits: SVGAnimatedEnumeration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/markerWidth) */\\n    readonly markerWidth: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/orientAngle) */\\n    readonly orientAngle: SVGAnimatedAngle;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/orientType) */\\n    readonly orientType: SVGAnimatedEnumeration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/refX) */\\n    readonly refX: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/refY) */\\n    readonly refY: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/setOrientToAngle) */\\n    setOrientToAngle(angle: SVGAngle): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMarkerElement/setOrientToAuto) */\\n    setOrientToAuto(): void;\\n    readonly SVG_MARKERUNITS_UNKNOWN: 0;\\n    readonly SVG_MARKERUNITS_USERSPACEONUSE: 1;\\n    readonly SVG_MARKERUNITS_STROKEWIDTH: 2;\\n    readonly SVG_MARKER_ORIENT_UNKNOWN: 0;\\n    readonly SVG_MARKER_ORIENT_AUTO: 1;\\n    readonly SVG_MARKER_ORIENT_ANGLE: 2;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGMarkerElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGMarkerElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGMarkerElement: {\\n    prototype: SVGMarkerElement;\\n    new(): SVGMarkerElement;\\n    readonly SVG_MARKERUNITS_UNKNOWN: 0;\\n    readonly SVG_MARKERUNITS_USERSPACEONUSE: 1;\\n    readonly SVG_MARKERUNITS_STROKEWIDTH: 2;\\n    readonly SVG_MARKER_ORIENT_UNKNOWN: 0;\\n    readonly SVG_MARKER_ORIENT_AUTO: 1;\\n    readonly SVG_MARKER_ORIENT_ANGLE: 2;\\n};\\n\\n/**\\n * Provides access to the properties of <mask> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMaskElement)\\n */\\ninterface SVGMaskElement extends SVGElement {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMaskElement/height) */\\n    readonly height: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMaskElement/maskContentUnits) */\\n    readonly maskContentUnits: SVGAnimatedEnumeration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMaskElement/maskUnits) */\\n    readonly maskUnits: SVGAnimatedEnumeration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMaskElement/width) */\\n    readonly width: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMaskElement/x) */\\n    readonly x: SVGAnimatedLength;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMaskElement/y) */\\n    readonly y: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGMaskElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGMaskElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGMaskElement: {\\n    prototype: SVGMaskElement;\\n    new(): SVGMaskElement;\\n};\\n\\n/**\\n * Corresponds to the <metadata> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGMetadataElement)\\n */\\ninterface SVGMetadataElement extends SVGElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGMetadataElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGMetadataElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGMetadataElement: {\\n    prototype: SVGMetadataElement;\\n    new(): SVGMetadataElement;\\n};\\n\\n/**\\n * Corresponds to the <number> basic data type.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGNumber)\\n */\\ninterface SVGNumber {\\n    value: number;\\n}\\n\\ndeclare var SVGNumber: {\\n    prototype: SVGNumber;\\n    new(): SVGNumber;\\n};\\n\\n/**\\n * The SVGNumberList defines a list of SVGNumber objects.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGNumberList)\\n */\\ninterface SVGNumberList {\\n    readonly length: number;\\n    readonly numberOfItems: number;\\n    appendItem(newItem: SVGNumber): SVGNumber;\\n    clear(): void;\\n    getItem(index: number): SVGNumber;\\n    initialize(newItem: SVGNumber): SVGNumber;\\n    insertItemBefore(newItem: SVGNumber, index: number): SVGNumber;\\n    removeItem(index: number): SVGNumber;\\n    replaceItem(newItem: SVGNumber, index: number): SVGNumber;\\n    [index: number]: SVGNumber;\\n}\\n\\ndeclare var SVGNumberList: {\\n    prototype: SVGNumberList;\\n    new(): SVGNumberList;\\n};\\n\\n/**\\n * Corresponds to the <path> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPathElement)\\n */\\ninterface SVGPathElement extends SVGGeometryElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGPathElement: {\\n    prototype: SVGPathElement;\\n    new(): SVGPathElement;\\n};\\n\\n/**\\n * Corresponds to the <pattern> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPatternElement)\\n */\\ninterface SVGPatternElement extends SVGElement, SVGFitToViewBox, SVGURIReference {\\n    readonly height: SVGAnimatedLength;\\n    readonly patternContentUnits: SVGAnimatedEnumeration;\\n    readonly patternTransform: SVGAnimatedTransformList;\\n    readonly patternUnits: SVGAnimatedEnumeration;\\n    readonly width: SVGAnimatedLength;\\n    readonly x: SVGAnimatedLength;\\n    readonly y: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGPatternElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGPatternElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGPatternElement: {\\n    prototype: SVGPatternElement;\\n    new(): SVGPatternElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList) */\\ninterface SVGPointList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/numberOfItems) */\\n    readonly numberOfItems: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/appendItem) */\\n    appendItem(newItem: DOMPoint): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/clear) */\\n    clear(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/getItem) */\\n    getItem(index: number): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/initialize) */\\n    initialize(newItem: DOMPoint): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/insertItemBefore) */\\n    insertItemBefore(newItem: DOMPoint, index: number): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/removeItem) */\\n    removeItem(index: number): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPointList/replaceItem) */\\n    replaceItem(newItem: DOMPoint, index: number): DOMPoint;\\n    [index: number]: DOMPoint;\\n}\\n\\ndeclare var SVGPointList: {\\n    prototype: SVGPointList;\\n    new(): SVGPointList;\\n};\\n\\n/**\\n * Provides access to the properties of <polygon> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPolygonElement)\\n */\\ninterface SVGPolygonElement extends SVGGeometryElement, SVGAnimatedPoints {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGPolygonElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGPolygonElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGPolygonElement: {\\n    prototype: SVGPolygonElement;\\n    new(): SVGPolygonElement;\\n};\\n\\n/**\\n * Provides access to the properties of <polyline> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPolylineElement)\\n */\\ninterface SVGPolylineElement extends SVGGeometryElement, SVGAnimatedPoints {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGPolylineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGPolylineElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGPolylineElement: {\\n    prototype: SVGPolylineElement;\\n    new(): SVGPolylineElement;\\n};\\n\\n/**\\n * Corresponds to the preserveAspectRatio attribute, which is available for some of SVG's elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGPreserveAspectRatio)\\n */\\ninterface SVGPreserveAspectRatio {\\n    align: number;\\n    meetOrSlice: number;\\n    readonly SVG_PRESERVEASPECTRATIO_UNKNOWN: 0;\\n    readonly SVG_PRESERVEASPECTRATIO_NONE: 1;\\n    readonly SVG_PRESERVEASPECTRATIO_XMINYMIN: 2;\\n    readonly SVG_PRESERVEASPECTRATIO_XMIDYMIN: 3;\\n    readonly SVG_PRESERVEASPECTRATIO_XMAXYMIN: 4;\\n    readonly SVG_PRESERVEASPECTRATIO_XMINYMID: 5;\\n    readonly SVG_PRESERVEASPECTRATIO_XMIDYMID: 6;\\n    readonly SVG_PRESERVEASPECTRATIO_XMAXYMID: 7;\\n    readonly SVG_PRESERVEASPECTRATIO_XMINYMAX: 8;\\n    readonly SVG_PRESERVEASPECTRATIO_XMIDYMAX: 9;\\n    readonly SVG_PRESERVEASPECTRATIO_XMAXYMAX: 10;\\n    readonly SVG_MEETORSLICE_UNKNOWN: 0;\\n    readonly SVG_MEETORSLICE_MEET: 1;\\n    readonly SVG_MEETORSLICE_SLICE: 2;\\n}\\n\\ndeclare var SVGPreserveAspectRatio: {\\n    prototype: SVGPreserveAspectRatio;\\n    new(): SVGPreserveAspectRatio;\\n    readonly SVG_PRESERVEASPECTRATIO_UNKNOWN: 0;\\n    readonly SVG_PRESERVEASPECTRATIO_NONE: 1;\\n    readonly SVG_PRESERVEASPECTRATIO_XMINYMIN: 2;\\n    readonly SVG_PRESERVEASPECTRATIO_XMIDYMIN: 3;\\n    readonly SVG_PRESERVEASPECTRATIO_XMAXYMIN: 4;\\n    readonly SVG_PRESERVEASPECTRATIO_XMINYMID: 5;\\n    readonly SVG_PRESERVEASPECTRATIO_XMIDYMID: 6;\\n    readonly SVG_PRESERVEASPECTRATIO_XMAXYMID: 7;\\n    readonly SVG_PRESERVEASPECTRATIO_XMINYMAX: 8;\\n    readonly SVG_PRESERVEASPECTRATIO_XMIDYMAX: 9;\\n    readonly SVG_PRESERVEASPECTRATIO_XMAXYMAX: 10;\\n    readonly SVG_MEETORSLICE_UNKNOWN: 0;\\n    readonly SVG_MEETORSLICE_MEET: 1;\\n    readonly SVG_MEETORSLICE_SLICE: 2;\\n};\\n\\n/**\\n * Corresponds to the <RadialGradient> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGRadialGradientElement)\\n */\\ninterface SVGRadialGradientElement extends SVGGradientElement {\\n    readonly cx: SVGAnimatedLength;\\n    readonly cy: SVGAnimatedLength;\\n    readonly fr: SVGAnimatedLength;\\n    readonly fx: SVGAnimatedLength;\\n    readonly fy: SVGAnimatedLength;\\n    readonly r: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGRadialGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGRadialGradientElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGRadialGradientElement: {\\n    prototype: SVGRadialGradientElement;\\n    new(): SVGRadialGradientElement;\\n};\\n\\n/**\\n * Provides access to the properties of <rect> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGRectElement)\\n */\\ninterface SVGRectElement extends SVGGeometryElement {\\n    readonly height: SVGAnimatedLength;\\n    readonly rx: SVGAnimatedLength;\\n    readonly ry: SVGAnimatedLength;\\n    readonly width: SVGAnimatedLength;\\n    readonly x: SVGAnimatedLength;\\n    readonly y: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGRectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGRectElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGRectElement: {\\n    prototype: SVGRectElement;\\n    new(): SVGRectElement;\\n};\\n\\ninterface SVGSVGElementEventMap extends SVGElementEventMap, WindowEventHandlersEventMap {\\n}\\n\\n/**\\n * Provides access to the properties of <svg> elements, as well as methods to manipulate them. This interface contains also various miscellaneous commonly-used utility methods, such as matrix operations and the ability to control the time of redraw on visual rendering devices.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGSVGElement)\\n */\\ninterface SVGSVGElement extends SVGGraphicsElement, SVGFitToViewBox, WindowEventHandlers {\\n    currentScale: number;\\n    readonly currentTranslate: DOMPointReadOnly;\\n    readonly height: SVGAnimatedLength;\\n    readonly width: SVGAnimatedLength;\\n    readonly x: SVGAnimatedLength;\\n    readonly y: SVGAnimatedLength;\\n    animationsPaused(): boolean;\\n    checkEnclosure(element: SVGElement, rect: DOMRectReadOnly): boolean;\\n    checkIntersection(element: SVGElement, rect: DOMRectReadOnly): boolean;\\n    createSVGAngle(): SVGAngle;\\n    createSVGLength(): SVGLength;\\n    createSVGMatrix(): DOMMatrix;\\n    createSVGNumber(): SVGNumber;\\n    createSVGPoint(): DOMPoint;\\n    createSVGRect(): DOMRect;\\n    createSVGTransform(): SVGTransform;\\n    createSVGTransformFromMatrix(matrix?: DOMMatrix2DInit): SVGTransform;\\n    deselectAll(): void;\\n    /** @deprecated */\\n    forceRedraw(): void;\\n    getCurrentTime(): number;\\n    getElementById(elementId: string): Element;\\n    getEnclosureList(rect: DOMRectReadOnly, referenceElement: SVGElement | null): NodeListOf<SVGCircleElement | SVGEllipseElement | SVGImageElement | SVGLineElement | SVGPathElement | SVGPolygonElement | SVGPolylineElement | SVGRectElement | SVGTextElement | SVGUseElement>;\\n    getIntersectionList(rect: DOMRectReadOnly, referenceElement: SVGElement | null): NodeListOf<SVGCircleElement | SVGEllipseElement | SVGImageElement | SVGLineElement | SVGPathElement | SVGPolygonElement | SVGPolylineElement | SVGRectElement | SVGTextElement | SVGUseElement>;\\n    pauseAnimations(): void;\\n    setCurrentTime(seconds: number): void;\\n    /** @deprecated */\\n    suspendRedraw(maxWaitMilliseconds: number): number;\\n    unpauseAnimations(): void;\\n    /** @deprecated */\\n    unsuspendRedraw(suspendHandleID: number): void;\\n    /** @deprecated */\\n    unsuspendRedrawAll(): void;\\n    addEventListener<K extends keyof SVGSVGElementEventMap>(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGSVGElementEventMap>(type: K, listener: (this: SVGSVGElement, ev: SVGSVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGSVGElement: {\\n    prototype: SVGSVGElement;\\n    new(): SVGSVGElement;\\n};\\n\\n/**\\n * Corresponds to the SVG <script> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGScriptElement)\\n */\\ninterface SVGScriptElement extends SVGElement, SVGURIReference {\\n    type: string;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGScriptElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGScriptElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGScriptElement: {\\n    prototype: SVGScriptElement;\\n    new(): SVGScriptElement;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGSetElement) */\\ninterface SVGSetElement extends SVGAnimationElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGSetElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGSetElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGSetElement: {\\n    prototype: SVGSetElement;\\n    new(): SVGSetElement;\\n};\\n\\n/**\\n * Corresponds to the <stop> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGStopElement)\\n */\\ninterface SVGStopElement extends SVGElement {\\n    readonly offset: SVGAnimatedNumber;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGStopElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGStopElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGStopElement: {\\n    prototype: SVGStopElement;\\n    new(): SVGStopElement;\\n};\\n\\n/**\\n * The SVGStringList defines a list of DOMString objects.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGStringList)\\n */\\ninterface SVGStringList {\\n    readonly length: number;\\n    readonly numberOfItems: number;\\n    appendItem(newItem: string): string;\\n    clear(): void;\\n    getItem(index: number): string;\\n    initialize(newItem: string): string;\\n    insertItemBefore(newItem: string, index: number): string;\\n    removeItem(index: number): string;\\n    replaceItem(newItem: string, index: number): string;\\n    [index: number]: string;\\n}\\n\\ndeclare var SVGStringList: {\\n    prototype: SVGStringList;\\n    new(): SVGStringList;\\n};\\n\\n/**\\n * Corresponds to the SVG <style> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGStyleElement)\\n */\\ninterface SVGStyleElement extends SVGElement, LinkStyle {\\n    disabled: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGStyleElement/media) */\\n    media: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGStyleElement/title) */\\n    title: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGStyleElement/type)\\n     */\\n    type: string;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGStyleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGStyleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGStyleElement: {\\n    prototype: SVGStyleElement;\\n    new(): SVGStyleElement;\\n};\\n\\n/**\\n * Corresponds to the <switch> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGSwitchElement)\\n */\\ninterface SVGSwitchElement extends SVGGraphicsElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGSwitchElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGSwitchElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGSwitchElement: {\\n    prototype: SVGSwitchElement;\\n    new(): SVGSwitchElement;\\n};\\n\\n/**\\n * Corresponds to the <symbol> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGSymbolElement)\\n */\\ninterface SVGSymbolElement extends SVGElement, SVGFitToViewBox {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGSymbolElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGSymbolElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGSymbolElement: {\\n    prototype: SVGSymbolElement;\\n    new(): SVGSymbolElement;\\n};\\n\\n/**\\n * A <tspan> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGTSpanElement)\\n */\\ninterface SVGTSpanElement extends SVGTextPositioningElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTSpanElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTSpanElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGTSpanElement: {\\n    prototype: SVGTSpanElement;\\n    new(): SVGTSpanElement;\\n};\\n\\ninterface SVGTests {\\n    readonly requiredExtensions: SVGStringList;\\n    readonly systemLanguage: SVGStringList;\\n}\\n\\n/**\\n * Implemented by elements that support rendering child text content. It is inherited by various text-related interfaces, such as SVGTextElement, SVGTSpanElement, SVGTRefElement, SVGAltGlyphElement and SVGTextPathElement.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGTextContentElement)\\n */\\ninterface SVGTextContentElement extends SVGGraphicsElement {\\n    readonly lengthAdjust: SVGAnimatedEnumeration;\\n    readonly textLength: SVGAnimatedLength;\\n    getCharNumAtPosition(point?: DOMPointInit): number;\\n    getComputedTextLength(): number;\\n    getEndPositionOfChar(charnum: number): DOMPoint;\\n    getExtentOfChar(charnum: number): DOMRect;\\n    getNumberOfChars(): number;\\n    getRotationOfChar(charnum: number): number;\\n    getStartPositionOfChar(charnum: number): DOMPoint;\\n    getSubStringLength(charnum: number, nchars: number): number;\\n    /** @deprecated */\\n    selectSubString(charnum: number, nchars: number): void;\\n    readonly LENGTHADJUST_UNKNOWN: 0;\\n    readonly LENGTHADJUST_SPACING: 1;\\n    readonly LENGTHADJUST_SPACINGANDGLYPHS: 2;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTextContentElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTextContentElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGTextContentElement: {\\n    prototype: SVGTextContentElement;\\n    new(): SVGTextContentElement;\\n    readonly LENGTHADJUST_UNKNOWN: 0;\\n    readonly LENGTHADJUST_SPACING: 1;\\n    readonly LENGTHADJUST_SPACINGANDGLYPHS: 2;\\n};\\n\\n/**\\n * Corresponds to the <text> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGTextElement)\\n */\\ninterface SVGTextElement extends SVGTextPositioningElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTextElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTextElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGTextElement: {\\n    prototype: SVGTextElement;\\n    new(): SVGTextElement;\\n};\\n\\n/**\\n * Corresponds to the <textPath> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGTextPathElement)\\n */\\ninterface SVGTextPathElement extends SVGTextContentElement, SVGURIReference {\\n    readonly method: SVGAnimatedEnumeration;\\n    readonly spacing: SVGAnimatedEnumeration;\\n    readonly startOffset: SVGAnimatedLength;\\n    readonly TEXTPATH_METHODTYPE_UNKNOWN: 0;\\n    readonly TEXTPATH_METHODTYPE_ALIGN: 1;\\n    readonly TEXTPATH_METHODTYPE_STRETCH: 2;\\n    readonly TEXTPATH_SPACINGTYPE_UNKNOWN: 0;\\n    readonly TEXTPATH_SPACINGTYPE_AUTO: 1;\\n    readonly TEXTPATH_SPACINGTYPE_EXACT: 2;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTextPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTextPathElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGTextPathElement: {\\n    prototype: SVGTextPathElement;\\n    new(): SVGTextPathElement;\\n    readonly TEXTPATH_METHODTYPE_UNKNOWN: 0;\\n    readonly TEXTPATH_METHODTYPE_ALIGN: 1;\\n    readonly TEXTPATH_METHODTYPE_STRETCH: 2;\\n    readonly TEXTPATH_SPACINGTYPE_UNKNOWN: 0;\\n    readonly TEXTPATH_SPACINGTYPE_AUTO: 1;\\n    readonly TEXTPATH_SPACINGTYPE_EXACT: 2;\\n};\\n\\n/**\\n * Implemented by elements that support attributes that position individual text glyphs. It is inherited by SVGTextElement, SVGTSpanElement, SVGTRefElement and SVGAltGlyphElement.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGTextPositioningElement)\\n */\\ninterface SVGTextPositioningElement extends SVGTextContentElement {\\n    readonly dx: SVGAnimatedLengthList;\\n    readonly dy: SVGAnimatedLengthList;\\n    readonly rotate: SVGAnimatedNumberList;\\n    readonly x: SVGAnimatedLengthList;\\n    readonly y: SVGAnimatedLengthList;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTextPositioningElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTextPositioningElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGTextPositioningElement: {\\n    prototype: SVGTextPositioningElement;\\n    new(): SVGTextPositioningElement;\\n};\\n\\n/**\\n * Corresponds to the <title> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGTitleElement)\\n */\\ninterface SVGTitleElement extends SVGElement {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTitleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGTitleElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGTitleElement: {\\n    prototype: SVGTitleElement;\\n    new(): SVGTitleElement;\\n};\\n\\n/**\\n * SVGTransform is the interface for one of the component transformations within an SVGTransformList; thus, an SVGTransform object corresponds to a single component (e.g., scale(…) or matrix(…)) within a transform attribute.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGTransform)\\n */\\ninterface SVGTransform {\\n    readonly angle: number;\\n    readonly matrix: DOMMatrix;\\n    readonly type: number;\\n    setMatrix(matrix?: DOMMatrix2DInit): void;\\n    setRotate(angle: number, cx: number, cy: number): void;\\n    setScale(sx: number, sy: number): void;\\n    setSkewX(angle: number): void;\\n    setSkewY(angle: number): void;\\n    setTranslate(tx: number, ty: number): void;\\n    readonly SVG_TRANSFORM_UNKNOWN: 0;\\n    readonly SVG_TRANSFORM_MATRIX: 1;\\n    readonly SVG_TRANSFORM_TRANSLATE: 2;\\n    readonly SVG_TRANSFORM_SCALE: 3;\\n    readonly SVG_TRANSFORM_ROTATE: 4;\\n    readonly SVG_TRANSFORM_SKEWX: 5;\\n    readonly SVG_TRANSFORM_SKEWY: 6;\\n}\\n\\ndeclare var SVGTransform: {\\n    prototype: SVGTransform;\\n    new(): SVGTransform;\\n    readonly SVG_TRANSFORM_UNKNOWN: 0;\\n    readonly SVG_TRANSFORM_MATRIX: 1;\\n    readonly SVG_TRANSFORM_TRANSLATE: 2;\\n    readonly SVG_TRANSFORM_SCALE: 3;\\n    readonly SVG_TRANSFORM_ROTATE: 4;\\n    readonly SVG_TRANSFORM_SKEWX: 5;\\n    readonly SVG_TRANSFORM_SKEWY: 6;\\n};\\n\\n/**\\n * The SVGTransformList defines a list of SVGTransform objects.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGTransformList)\\n */\\ninterface SVGTransformList {\\n    readonly length: number;\\n    readonly numberOfItems: number;\\n    appendItem(newItem: SVGTransform): SVGTransform;\\n    clear(): void;\\n    consolidate(): SVGTransform | null;\\n    createSVGTransformFromMatrix(matrix?: DOMMatrix2DInit): SVGTransform;\\n    getItem(index: number): SVGTransform;\\n    initialize(newItem: SVGTransform): SVGTransform;\\n    insertItemBefore(newItem: SVGTransform, index: number): SVGTransform;\\n    removeItem(index: number): SVGTransform;\\n    replaceItem(newItem: SVGTransform, index: number): SVGTransform;\\n    [index: number]: SVGTransform;\\n}\\n\\ndeclare var SVGTransformList: {\\n    prototype: SVGTransformList;\\n    new(): SVGTransformList;\\n};\\n\\ninterface SVGURIReference {\\n    readonly href: SVGAnimatedString;\\n}\\n\\n/**\\n * A commonly used set of constants used for reflecting gradientUnits, patternContentUnits and other similar attributes.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGUnitTypes)\\n */\\ninterface SVGUnitTypes {\\n    readonly SVG_UNIT_TYPE_UNKNOWN: 0;\\n    readonly SVG_UNIT_TYPE_USERSPACEONUSE: 1;\\n    readonly SVG_UNIT_TYPE_OBJECTBOUNDINGBOX: 2;\\n}\\n\\ndeclare var SVGUnitTypes: {\\n    prototype: SVGUnitTypes;\\n    new(): SVGUnitTypes;\\n    readonly SVG_UNIT_TYPE_UNKNOWN: 0;\\n    readonly SVG_UNIT_TYPE_USERSPACEONUSE: 1;\\n    readonly SVG_UNIT_TYPE_OBJECTBOUNDINGBOX: 2;\\n};\\n\\n/**\\n * Corresponds to the <use> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGUseElement)\\n */\\ninterface SVGUseElement extends SVGGraphicsElement, SVGURIReference {\\n    readonly height: SVGAnimatedLength;\\n    readonly width: SVGAnimatedLength;\\n    readonly x: SVGAnimatedLength;\\n    readonly y: SVGAnimatedLength;\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGUseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGUseElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGUseElement: {\\n    prototype: SVGUseElement;\\n    new(): SVGUseElement;\\n};\\n\\n/**\\n * Provides access to the properties of <view> elements, as well as methods to manipulate them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGViewElement)\\n */\\ninterface SVGViewElement extends SVGElement, SVGFitToViewBox {\\n    addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGViewElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGViewElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SVGViewElement: {\\n    prototype: SVGViewElement;\\n    new(): SVGViewElement;\\n};\\n\\n/**\\n * A screen, usually the one on which the current window is being rendered, and is obtained using window.screen.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Screen)\\n */\\ninterface Screen {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Screen/availHeight) */\\n    readonly availHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Screen/availWidth) */\\n    readonly availWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Screen/colorDepth) */\\n    readonly colorDepth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Screen/height) */\\n    readonly height: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Screen/orientation) */\\n    readonly orientation: ScreenOrientation;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Screen/pixelDepth) */\\n    readonly pixelDepth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Screen/width) */\\n    readonly width: number;\\n}\\n\\ndeclare var Screen: {\\n    prototype: Screen;\\n    new(): Screen;\\n};\\n\\ninterface ScreenOrientationEventMap {\\n    \\\"change\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ScreenOrientation) */\\ninterface ScreenOrientation extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ScreenOrientation/angle) */\\n    readonly angle: number;\\n    onchange: ((this: ScreenOrientation, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ScreenOrientation/type) */\\n    readonly type: OrientationType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ScreenOrientation/unlock) */\\n    unlock(): void;\\n    addEventListener<K extends keyof ScreenOrientationEventMap>(type: K, listener: (this: ScreenOrientation, ev: ScreenOrientationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ScreenOrientationEventMap>(type: K, listener: (this: ScreenOrientation, ev: ScreenOrientationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ScreenOrientation: {\\n    prototype: ScreenOrientation;\\n    new(): ScreenOrientation;\\n};\\n\\ninterface ScriptProcessorNodeEventMap {\\n    \\\"audioprocess\\\": AudioProcessingEvent;\\n}\\n\\n/**\\n * Allows the generation, processing, or analyzing of audio using JavaScript.\\n * @deprecated As of the August 29 2014 Web Audio API spec publication, this feature has been marked as deprecated, and was replaced by AudioWorklet (see AudioWorkletNode).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ScriptProcessorNode)\\n */\\ninterface ScriptProcessorNode extends AudioNode {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ScriptProcessorNode/bufferSize)\\n     */\\n    readonly bufferSize: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ScriptProcessorNode/audioprocess_event)\\n     */\\n    onaudioprocess: ((this: ScriptProcessorNode, ev: AudioProcessingEvent) => any) | null;\\n    addEventListener<K extends keyof ScriptProcessorNodeEventMap>(type: K, listener: (this: ScriptProcessorNode, ev: ScriptProcessorNodeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ScriptProcessorNodeEventMap>(type: K, listener: (this: ScriptProcessorNode, ev: ScriptProcessorNodeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\n/** @deprecated */\\ndeclare var ScriptProcessorNode: {\\n    prototype: ScriptProcessorNode;\\n    new(): ScriptProcessorNode;\\n};\\n\\n/**\\n * Inherits from Event, and represents the event object of an event sent on a document or worker when its content security policy is violated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent)\\n */\\ninterface SecurityPolicyViolationEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/blockedURI) */\\n    readonly blockedURI: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/columnNumber) */\\n    readonly columnNumber: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/disposition) */\\n    readonly disposition: SecurityPolicyViolationEventDisposition;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/documentURI) */\\n    readonly documentURI: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/effectiveDirective) */\\n    readonly effectiveDirective: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/lineNumber) */\\n    readonly lineNumber: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/originalPolicy) */\\n    readonly originalPolicy: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/referrer) */\\n    readonly referrer: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/sample) */\\n    readonly sample: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/sourceFile) */\\n    readonly sourceFile: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/statusCode) */\\n    readonly statusCode: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/violatedDirective) */\\n    readonly violatedDirective: string;\\n}\\n\\ndeclare var SecurityPolicyViolationEvent: {\\n    prototype: SecurityPolicyViolationEvent;\\n    new(type: string, eventInitDict?: SecurityPolicyViolationEventInit): SecurityPolicyViolationEvent;\\n};\\n\\n/**\\n * A Selection object represents the range of text selected by the user or the current position of the caret. To obtain a Selection object for examination or modification, call Window.getSelection().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection)\\n */\\ninterface Selection {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/anchorNode) */\\n    readonly anchorNode: Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/anchorOffset) */\\n    readonly anchorOffset: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/focusNode) */\\n    readonly focusNode: Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/focusOffset) */\\n    readonly focusOffset: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/isCollapsed) */\\n    readonly isCollapsed: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/rangeCount) */\\n    readonly rangeCount: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/type) */\\n    readonly type: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/addRange) */\\n    addRange(range: Range): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/collapse) */\\n    collapse(node: Node | null, offset?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/collapseToEnd) */\\n    collapseToEnd(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/collapseToStart) */\\n    collapseToStart(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/containsNode) */\\n    containsNode(node: Node, allowPartialContainment?: boolean): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/deleteFromDocument) */\\n    deleteFromDocument(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/removeAllRanges) */\\n    empty(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/extend) */\\n    extend(node: Node, offset?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/getRangeAt) */\\n    getRangeAt(index: number): Range;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/modify) */\\n    modify(alter?: string, direction?: string, granularity?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/removeAllRanges) */\\n    removeAllRanges(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/removeRange) */\\n    removeRange(range: Range): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/selectAllChildren) */\\n    selectAllChildren(node: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/setBaseAndExtent) */\\n    setBaseAndExtent(anchorNode: Node, anchorOffset: number, focusNode: Node, focusOffset: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Selection/collapse) */\\n    setPosition(node: Node | null, offset?: number): void;\\n    toString(): string;\\n}\\n\\ndeclare var Selection: {\\n    prototype: Selection;\\n    new(): Selection;\\n};\\n\\ninterface ServiceWorkerEventMap extends AbstractWorkerEventMap {\\n    \\\"statechange\\\": Event;\\n}\\n\\n/**\\n * This ServiceWorker API interface provides a reference to a service worker. Multiple browsing contexts (e.g. pages, workers, etc.) can be associated with the same service worker, each through a unique ServiceWorker object.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker)\\n */\\ninterface ServiceWorker extends EventTarget, AbstractWorker {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/statechange_event) */\\n    onstatechange: ((this: ServiceWorker, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/scriptURL) */\\n    readonly scriptURL: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/state) */\\n    readonly state: ServiceWorkerState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/postMessage) */\\n    postMessage(message: any, transfer: Transferable[]): void;\\n    postMessage(message: any, options?: StructuredSerializeOptions): void;\\n    addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ServiceWorker: {\\n    prototype: ServiceWorker;\\n    new(): ServiceWorker;\\n};\\n\\ninterface ServiceWorkerContainerEventMap {\\n    \\\"controllerchange\\\": Event;\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/**\\n * The ServiceWorkerContainer interface of the ServiceWorker API provides an object representing the service worker as an overall unit in the network ecosystem, including facilities to register, unregister and update service workers, and access the state of service workers and their registrations.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer)\\n */\\ninterface ServiceWorkerContainer extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/controller) */\\n    readonly controller: ServiceWorker | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/controllerchange_event) */\\n    oncontrollerchange: ((this: ServiceWorkerContainer, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/message_event) */\\n    onmessage: ((this: ServiceWorkerContainer, ev: MessageEvent) => any) | null;\\n    onmessageerror: ((this: ServiceWorkerContainer, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/ready) */\\n    readonly ready: Promise<ServiceWorkerRegistration>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/getRegistration) */\\n    getRegistration(clientURL?: string | URL): Promise<ServiceWorkerRegistration | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/getRegistrations) */\\n    getRegistrations(): Promise<ReadonlyArray<ServiceWorkerRegistration>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/register) */\\n    register(scriptURL: string | URL, options?: RegistrationOptions): Promise<ServiceWorkerRegistration>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/startMessages) */\\n    startMessages(): void;\\n    addEventListener<K extends keyof ServiceWorkerContainerEventMap>(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ServiceWorkerContainerEventMap>(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ServiceWorkerContainer: {\\n    prototype: ServiceWorkerContainer;\\n    new(): ServiceWorkerContainer;\\n};\\n\\ninterface ServiceWorkerRegistrationEventMap {\\n    \\\"updatefound\\\": Event;\\n}\\n\\n/**\\n * This ServiceWorker API interface represents the service worker registration. You register a service worker to control one or more pages that share the same origin.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration)\\n */\\ninterface ServiceWorkerRegistration extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/active) */\\n    readonly active: ServiceWorker | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/installing) */\\n    readonly installing: ServiceWorker | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/navigationPreload) */\\n    readonly navigationPreload: NavigationPreloadManager;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/updatefound_event) */\\n    onupdatefound: ((this: ServiceWorkerRegistration, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/pushManager) */\\n    readonly pushManager: PushManager;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/scope) */\\n    readonly scope: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/updateViaCache) */\\n    readonly updateViaCache: ServiceWorkerUpdateViaCache;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/waiting) */\\n    readonly waiting: ServiceWorker | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/getNotifications) */\\n    getNotifications(filter?: GetNotificationOptions): Promise<Notification[]>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/showNotification) */\\n    showNotification(title: string, options?: NotificationOptions): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/unregister) */\\n    unregister(): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/update) */\\n    update(): Promise<void>;\\n    addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ServiceWorkerRegistration: {\\n    prototype: ServiceWorkerRegistration;\\n    new(): ServiceWorkerRegistration;\\n};\\n\\ninterface ShadowRootEventMap {\\n    \\\"slotchange\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot) */\\ninterface ShadowRoot extends DocumentFragment, DocumentOrShadowRoot, InnerHTML {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot/delegatesFocus) */\\n    readonly delegatesFocus: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot/host) */\\n    readonly host: Element;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot/mode) */\\n    readonly mode: ShadowRootMode;\\n    onslotchange: ((this: ShadowRoot, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot/slotAssignment) */\\n    readonly slotAssignment: SlotAssignmentMode;\\n    /** Throws a \\\"NotSupportedError\\\" DOMException if context object is a shadow root. */\\n    addEventListener<K extends keyof ShadowRootEventMap>(type: K, listener: (this: ShadowRoot, ev: ShadowRootEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ShadowRootEventMap>(type: K, listener: (this: ShadowRoot, ev: ShadowRootEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ShadowRoot: {\\n    prototype: ShadowRoot;\\n    new(): ShadowRoot;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SharedWorker) */\\ninterface SharedWorker extends EventTarget, AbstractWorker {\\n    /**\\n     * Returns sharedWorker's MessagePort object which can be used to communicate with the global environment.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SharedWorker/port)\\n     */\\n    readonly port: MessagePort;\\n    addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: SharedWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: SharedWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SharedWorker: {\\n    prototype: SharedWorker;\\n    new(scriptURL: string | URL, options?: string | WorkerOptions): SharedWorker;\\n};\\n\\ninterface Slottable {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/assignedSlot) */\\n    readonly assignedSlot: HTMLSlotElement | null;\\n}\\n\\ninterface SourceBufferEventMap {\\n    \\\"abort\\\": Event;\\n    \\\"error\\\": Event;\\n    \\\"update\\\": Event;\\n    \\\"updateend\\\": Event;\\n    \\\"updatestart\\\": Event;\\n}\\n\\n/**\\n * A chunk of media to be passed into an HTMLMediaElement and played, via a MediaSource object. This can be made up of one or several media segments.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer)\\n */\\ninterface SourceBuffer extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/appendWindowEnd) */\\n    appendWindowEnd: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/appendWindowStart) */\\n    appendWindowStart: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/buffered) */\\n    readonly buffered: TimeRanges;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/mode) */\\n    mode: AppendMode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/abort_event) */\\n    onabort: ((this: SourceBuffer, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/error_event) */\\n    onerror: ((this: SourceBuffer, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/update_event) */\\n    onupdate: ((this: SourceBuffer, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/updateend_event) */\\n    onupdateend: ((this: SourceBuffer, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/updatestart_event) */\\n    onupdatestart: ((this: SourceBuffer, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/timestampOffset) */\\n    timestampOffset: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/updating) */\\n    readonly updating: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/abort) */\\n    abort(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/appendBuffer) */\\n    appendBuffer(data: BufferSource): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/changeType) */\\n    changeType(type: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBuffer/remove) */\\n    remove(start: number, end: number): void;\\n    addEventListener<K extends keyof SourceBufferEventMap>(type: K, listener: (this: SourceBuffer, ev: SourceBufferEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SourceBufferEventMap>(type: K, listener: (this: SourceBuffer, ev: SourceBufferEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SourceBuffer: {\\n    prototype: SourceBuffer;\\n    new(): SourceBuffer;\\n};\\n\\ninterface SourceBufferListEventMap {\\n    \\\"addsourcebuffer\\\": Event;\\n    \\\"removesourcebuffer\\\": Event;\\n}\\n\\n/**\\n * A simple container list for multiple SourceBuffer objects.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBufferList)\\n */\\ninterface SourceBufferList extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBufferList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBufferList/addsourcebuffer_event) */\\n    onaddsourcebuffer: ((this: SourceBufferList, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SourceBufferList/removesourcebuffer_event) */\\n    onremovesourcebuffer: ((this: SourceBufferList, ev: Event) => any) | null;\\n    addEventListener<K extends keyof SourceBufferListEventMap>(type: K, listener: (this: SourceBufferList, ev: SourceBufferListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SourceBufferListEventMap>(type: K, listener: (this: SourceBufferList, ev: SourceBufferListEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n    [index: number]: SourceBuffer;\\n}\\n\\ndeclare var SourceBufferList: {\\n    prototype: SourceBufferList;\\n    new(): SourceBufferList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionAlternative) */\\ninterface SpeechRecognitionAlternative {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionAlternative/confidence) */\\n    readonly confidence: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionAlternative/transcript) */\\n    readonly transcript: string;\\n}\\n\\ndeclare var SpeechRecognitionAlternative: {\\n    prototype: SpeechRecognitionAlternative;\\n    new(): SpeechRecognitionAlternative;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionResult) */\\ninterface SpeechRecognitionResult {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionResult/isFinal) */\\n    readonly isFinal: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionResult/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionResult/item) */\\n    item(index: number): SpeechRecognitionAlternative;\\n    [index: number]: SpeechRecognitionAlternative;\\n}\\n\\ndeclare var SpeechRecognitionResult: {\\n    prototype: SpeechRecognitionResult;\\n    new(): SpeechRecognitionResult;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionResultList) */\\ninterface SpeechRecognitionResultList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionResultList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechRecognitionResultList/item) */\\n    item(index: number): SpeechRecognitionResult;\\n    [index: number]: SpeechRecognitionResult;\\n}\\n\\ndeclare var SpeechRecognitionResultList: {\\n    prototype: SpeechRecognitionResultList;\\n    new(): SpeechRecognitionResultList;\\n};\\n\\ninterface SpeechSynthesisEventMap {\\n    \\\"voiceschanged\\\": Event;\\n}\\n\\n/**\\n * This Web Speech API interface is the controller interface for the speech service; this can be used to retrieve information about the synthesis voices available on the device, start and pause speech, and other commands besides.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis)\\n */\\ninterface SpeechSynthesis extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/voiceschanged_event) */\\n    onvoiceschanged: ((this: SpeechSynthesis, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/paused) */\\n    readonly paused: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/pending) */\\n    readonly pending: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/speaking) */\\n    readonly speaking: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/cancel) */\\n    cancel(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/getVoices) */\\n    getVoices(): SpeechSynthesisVoice[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/pause) */\\n    pause(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/resume) */\\n    resume(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesis/speak) */\\n    speak(utterance: SpeechSynthesisUtterance): void;\\n    addEventListener<K extends keyof SpeechSynthesisEventMap>(type: K, listener: (this: SpeechSynthesis, ev: SpeechSynthesisEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SpeechSynthesisEventMap>(type: K, listener: (this: SpeechSynthesis, ev: SpeechSynthesisEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SpeechSynthesis: {\\n    prototype: SpeechSynthesis;\\n    new(): SpeechSynthesis;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisErrorEvent) */\\ninterface SpeechSynthesisErrorEvent extends SpeechSynthesisEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisErrorEvent/error) */\\n    readonly error: SpeechSynthesisErrorCode;\\n}\\n\\ndeclare var SpeechSynthesisErrorEvent: {\\n    prototype: SpeechSynthesisErrorEvent;\\n    new(type: string, eventInitDict: SpeechSynthesisErrorEventInit): SpeechSynthesisErrorEvent;\\n};\\n\\n/**\\n * This Web Speech API interface contains information about the current state of SpeechSynthesisUtterance objects that have been processed in the speech service.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisEvent)\\n */\\ninterface SpeechSynthesisEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisEvent/charIndex) */\\n    readonly charIndex: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisEvent/charLength) */\\n    readonly charLength: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisEvent/elapsedTime) */\\n    readonly elapsedTime: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisEvent/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisEvent/utterance) */\\n    readonly utterance: SpeechSynthesisUtterance;\\n}\\n\\ndeclare var SpeechSynthesisEvent: {\\n    prototype: SpeechSynthesisEvent;\\n    new(type: string, eventInitDict: SpeechSynthesisEventInit): SpeechSynthesisEvent;\\n};\\n\\ninterface SpeechSynthesisUtteranceEventMap {\\n    \\\"boundary\\\": SpeechSynthesisEvent;\\n    \\\"end\\\": SpeechSynthesisEvent;\\n    \\\"error\\\": SpeechSynthesisErrorEvent;\\n    \\\"mark\\\": SpeechSynthesisEvent;\\n    \\\"pause\\\": SpeechSynthesisEvent;\\n    \\\"resume\\\": SpeechSynthesisEvent;\\n    \\\"start\\\": SpeechSynthesisEvent;\\n}\\n\\n/**\\n * This Web Speech API interface represents a speech request. It contains the content the speech service should read and information about how to read it (e.g. language, pitch and volume.)\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance)\\n */\\ninterface SpeechSynthesisUtterance extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/lang) */\\n    lang: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/boundary_event) */\\n    onboundary: ((this: SpeechSynthesisUtterance, ev: SpeechSynthesisEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/end_event) */\\n    onend: ((this: SpeechSynthesisUtterance, ev: SpeechSynthesisEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/error_event) */\\n    onerror: ((this: SpeechSynthesisUtterance, ev: SpeechSynthesisErrorEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/mark_event) */\\n    onmark: ((this: SpeechSynthesisUtterance, ev: SpeechSynthesisEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/pause_event) */\\n    onpause: ((this: SpeechSynthesisUtterance, ev: SpeechSynthesisEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/resume_event) */\\n    onresume: ((this: SpeechSynthesisUtterance, ev: SpeechSynthesisEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/start_event) */\\n    onstart: ((this: SpeechSynthesisUtterance, ev: SpeechSynthesisEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/pitch) */\\n    pitch: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/rate) */\\n    rate: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/text) */\\n    text: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/voice) */\\n    voice: SpeechSynthesisVoice | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisUtterance/volume) */\\n    volume: number;\\n    addEventListener<K extends keyof SpeechSynthesisUtteranceEventMap>(type: K, listener: (this: SpeechSynthesisUtterance, ev: SpeechSynthesisUtteranceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SpeechSynthesisUtteranceEventMap>(type: K, listener: (this: SpeechSynthesisUtterance, ev: SpeechSynthesisUtteranceEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SpeechSynthesisUtterance: {\\n    prototype: SpeechSynthesisUtterance;\\n    new(text?: string): SpeechSynthesisUtterance;\\n};\\n\\n/**\\n * This Web Speech API interface represents a voice that the system supports. Every SpeechSynthesisVoice has its own relative speech service including information about language, name and URI.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisVoice)\\n */\\ninterface SpeechSynthesisVoice {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisVoice/default) */\\n    readonly default: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisVoice/lang) */\\n    readonly lang: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisVoice/localService) */\\n    readonly localService: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisVoice/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SpeechSynthesisVoice/voiceURI) */\\n    readonly voiceURI: string;\\n}\\n\\ndeclare var SpeechSynthesisVoice: {\\n    prototype: SpeechSynthesisVoice;\\n    new(): SpeechSynthesisVoice;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StaticRange) */\\ninterface StaticRange extends AbstractRange {\\n}\\n\\ndeclare var StaticRange: {\\n    prototype: StaticRange;\\n    new(init: StaticRangeInit): StaticRange;\\n};\\n\\n/**\\n * The pan property takes a unitless value between -1 (full left pan) and 1 (full right pan). This interface was introduced as a much simpler way to apply a simple panning effect than having to use a full PannerNode.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StereoPannerNode)\\n */\\ninterface StereoPannerNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StereoPannerNode/pan) */\\n    readonly pan: AudioParam;\\n}\\n\\ndeclare var StereoPannerNode: {\\n    prototype: StereoPannerNode;\\n    new(context: BaseAudioContext, options?: StereoPannerOptions): StereoPannerNode;\\n};\\n\\n/**\\n * This Web Storage API interface provides access to a particular domain's session or local storage. It allows, for example, the addition, modification, or deletion of stored data items.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage)\\n */\\ninterface Storage {\\n    /**\\n     * Returns the number of key/value pairs.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Removes all key/value pairs, if there are any.\\n     *\\n     * Dispatches a storage event on Window objects holding an equivalent Storage object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage/clear)\\n     */\\n    clear(): void;\\n    /**\\n     * Returns the current value associated with the given key, or null if the given key does not exist.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage/getItem)\\n     */\\n    getItem(key: string): string | null;\\n    /**\\n     * Returns the name of the nth key, or null if n is greater than or equal to the number of key/value pairs.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage/key)\\n     */\\n    key(index: number): string | null;\\n    /**\\n     * Removes the key/value pair with the given key, if a key/value pair with the given key exists.\\n     *\\n     * Dispatches a storage event on Window objects holding an equivalent Storage object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage/removeItem)\\n     */\\n    removeItem(key: string): void;\\n    /**\\n     * Sets the value of the pair identified by key to value, creating a new key/value pair if none existed for key previously.\\n     *\\n     * Throws a \\\"QuotaExceededError\\\" DOMException exception if the new value couldn't be set. (Setting could fail if, e.g., the user has disabled storage for the site, or if the quota has been exceeded.)\\n     *\\n     * Dispatches a storage event on Window objects holding an equivalent Storage object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Storage/setItem)\\n     */\\n    setItem(key: string, value: string): void;\\n    [name: string]: any;\\n}\\n\\ndeclare var Storage: {\\n    prototype: Storage;\\n    new(): Storage;\\n};\\n\\n/**\\n * A StorageEvent is sent to a window when a storage area it has access to is changed within the context of another document.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageEvent)\\n */\\ninterface StorageEvent extends Event {\\n    /**\\n     * Returns the key of the storage item being changed.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageEvent/key)\\n     */\\n    readonly key: string | null;\\n    /**\\n     * Returns the new value of the key of the storage item whose value is being changed.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageEvent/newValue)\\n     */\\n    readonly newValue: string | null;\\n    /**\\n     * Returns the old value of the key of the storage item whose value is being changed.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageEvent/oldValue)\\n     */\\n    readonly oldValue: string | null;\\n    /**\\n     * Returns the Storage object that was affected.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageEvent/storageArea)\\n     */\\n    readonly storageArea: Storage | null;\\n    /**\\n     * Returns the URL of the document whose storage item changed.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageEvent/url)\\n     */\\n    readonly url: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageEvent/initStorageEvent)\\n     */\\n    initStorageEvent(type: string, bubbles?: boolean, cancelable?: boolean, key?: string | null, oldValue?: string | null, newValue?: string | null, url?: string | URL, storageArea?: Storage | null): void;\\n}\\n\\ndeclare var StorageEvent: {\\n    prototype: StorageEvent;\\n    new(type: string, eventInitDict?: StorageEventInit): StorageEvent;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager)\\n */\\ninterface StorageManager {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager/estimate) */\\n    estimate(): Promise<StorageEstimate>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager/getDirectory) */\\n    getDirectory(): Promise<FileSystemDirectoryHandle>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager/persist) */\\n    persist(): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager/persisted) */\\n    persisted(): Promise<boolean>;\\n}\\n\\ndeclare var StorageManager: {\\n    prototype: StorageManager;\\n    new(): StorageManager;\\n};\\n\\n/** @deprecated */\\ninterface StyleMedia {\\n    type: string;\\n    matchMedium(mediaquery: string): boolean;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMap) */\\ninterface StylePropertyMap extends StylePropertyMapReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMap/append) */\\n    append(property: string, ...values: (CSSStyleValue | string)[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMap/clear) */\\n    clear(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMap/delete) */\\n    delete(property: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMap/set) */\\n    set(property: string, ...values: (CSSStyleValue | string)[]): void;\\n}\\n\\ndeclare var StylePropertyMap: {\\n    prototype: StylePropertyMap;\\n    new(): StylePropertyMap;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly) */\\ninterface StylePropertyMapReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly/size) */\\n    readonly size: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly/get) */\\n    get(property: string): undefined | CSSStyleValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly/getAll) */\\n    getAll(property: string): CSSStyleValue[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly/has) */\\n    has(property: string): boolean;\\n    forEach(callbackfn: (value: CSSStyleValue[], key: string, parent: StylePropertyMapReadOnly) => void, thisArg?: any): void;\\n}\\n\\ndeclare var StylePropertyMapReadOnly: {\\n    prototype: StylePropertyMapReadOnly;\\n    new(): StylePropertyMapReadOnly;\\n};\\n\\n/**\\n * A single style sheet. CSS style sheets will further implement the more specialized CSSStyleSheet interface.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheet)\\n */\\ninterface StyleSheet {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheet/disabled) */\\n    disabled: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheet/href) */\\n    readonly href: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheet/media) */\\n    readonly media: MediaList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheet/ownerNode) */\\n    readonly ownerNode: Element | ProcessingInstruction | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheet/parentStyleSheet) */\\n    readonly parentStyleSheet: CSSStyleSheet | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheet/title) */\\n    readonly title: string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheet/type) */\\n    readonly type: string;\\n}\\n\\ndeclare var StyleSheet: {\\n    prototype: StyleSheet;\\n    new(): StyleSheet;\\n};\\n\\n/**\\n * A list of StyleSheet.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheetList)\\n */\\ninterface StyleSheetList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheetList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StyleSheetList/item) */\\n    item(index: number): CSSStyleSheet | null;\\n    [index: number]: CSSStyleSheet;\\n}\\n\\ndeclare var StyleSheetList: {\\n    prototype: StyleSheetList;\\n    new(): StyleSheetList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubmitEvent) */\\ninterface SubmitEvent extends Event {\\n    /**\\n     * Returns the element representing the submit button that triggered the form submission, or null if the submission was not triggered by a button.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubmitEvent/submitter)\\n     */\\n    readonly submitter: HTMLElement | null;\\n}\\n\\ndeclare var SubmitEvent: {\\n    prototype: SubmitEvent;\\n    new(type: string, eventInitDict?: SubmitEventInit): SubmitEvent;\\n};\\n\\n/**\\n * This Web Crypto API interface provides a number of low-level cryptographic functions. It is accessed via the Crypto.subtle properties available in a window context (via Window.crypto).\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto)\\n */\\ninterface SubtleCrypto {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/decrypt) */\\n    decrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveBits) */\\n    deriveBits(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, length: number): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveKey) */\\n    deriveKey(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | HkdfParams | Pbkdf2Params, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/digest) */\\n    digest(algorithm: AlgorithmIdentifier, data: BufferSource): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/encrypt) */\\n    encrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/exportKey) */\\n    exportKey(format: \\\"jwk\\\", key: CryptoKey): Promise<JsonWebKey>;\\n    exportKey(format: Exclude<KeyFormat, \\\"jwk\\\">, key: CryptoKey): Promise<ArrayBuffer>;\\n    exportKey(format: KeyFormat, key: CryptoKey): Promise<ArrayBuffer | JsonWebKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) */\\n    generateKey(algorithm: \\\"Ed25519\\\", extractable: boolean, keyUsages: ReadonlyArray<\\\"sign\\\" | \\\"verify\\\">): Promise<CryptoKeyPair>;\\n    generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKeyPair>;\\n    generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;\\n    generateKey(algorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKeyPair | CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) */\\n    importKey(format: \\\"jwk\\\", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;\\n    importKey(format: Exclude<KeyFormat, \\\"jwk\\\">, keyData: BufferSource, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/sign) */\\n    sign(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/unwrapKey) */\\n    unwrapKey(format: KeyFormat, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, unwrappedKeyAlgorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/verify) */\\n    verify(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, signature: BufferSource, data: BufferSource): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/wrapKey) */\\n    wrapKey(format: KeyFormat, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams): Promise<ArrayBuffer>;\\n}\\n\\ndeclare var SubtleCrypto: {\\n    prototype: SubtleCrypto;\\n    new(): SubtleCrypto;\\n};\\n\\n/**\\n * The textual content of Element or Attr. If an element has no markup within its content, it has a single child implementing Text that contains the element's text. However, if the element contains markup, it is parsed into information items and Text nodes that form its children.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text)\\n */\\ninterface Text extends CharacterData, Slottable {\\n    /**\\n     * Returns the combined data of all direct Text node siblings.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text/wholeText)\\n     */\\n    readonly wholeText: string;\\n    /**\\n     * Splits data at the given offset and returns the remainder as Text node.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Text/splitText)\\n     */\\n    splitText(offset: number): Text;\\n}\\n\\ndeclare var Text: {\\n    prototype: Text;\\n    new(data?: string): Text;\\n};\\n\\n/**\\n * A decoder for a specific method, that is a specific character encoding, like utf-8, iso-8859-2, koi8, cp1261, gbk, etc. A decoder takes a stream of bytes as input and emits a stream of code points. For a more scalable, non-native library, see StringView – a C-like representation of strings based on typed arrays.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder)\\n */\\ninterface TextDecoder extends TextDecoderCommon {\\n    /**\\n     * Returns the result of running encoding's decoder. The method can be invoked zero or more times with options's stream set to true, and then once without options's stream (or set to false), to process a fragmented input. If the invocation without options's stream (or set to false) has no input, it's clearest to omit both arguments.\\n     *\\n     * ```\\n     * var string = \\\"\\\", decoder = new TextDecoder(encoding), buffer;\\n     * while(buffer = next_chunk()) {\\n     *   string += decoder.decode(buffer, {stream:true});\\n     * }\\n     * string += decoder.decode(); // end-of-queue\\n     * ```\\n     *\\n     * If the error mode is \\\"fatal\\\" and encoding's decoder returns error, throws a TypeError.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/decode)\\n     */\\n    decode(input?: AllowSharedBufferSource, options?: TextDecodeOptions): string;\\n}\\n\\ndeclare var TextDecoder: {\\n    prototype: TextDecoder;\\n    new(label?: string, options?: TextDecoderOptions): TextDecoder;\\n};\\n\\ninterface TextDecoderCommon {\\n    /**\\n     * Returns encoding's name, lowercased.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/encoding)\\n     */\\n    readonly encoding: string;\\n    /**\\n     * Returns true if error mode is \\\"fatal\\\", otherwise false.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/fatal)\\n     */\\n    readonly fatal: boolean;\\n    /**\\n     * Returns the value of ignore BOM.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/ignoreBOM)\\n     */\\n    readonly ignoreBOM: boolean;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoderStream) */\\ninterface TextDecoderStream extends GenericTransformStream, TextDecoderCommon {\\n    readonly readable: ReadableStream<string>;\\n    readonly writable: WritableStream<BufferSource>;\\n}\\n\\ndeclare var TextDecoderStream: {\\n    prototype: TextDecoderStream;\\n    new(label?: string, options?: TextDecoderOptions): TextDecoderStream;\\n};\\n\\n/**\\n * TextEncoder takes a stream of code points as input and emits a stream of bytes. For a more scalable, non-native library, see StringView – a C-like representation of strings based on typed arrays.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder)\\n */\\ninterface TextEncoder extends TextEncoderCommon {\\n    /**\\n     * Returns the result of running UTF-8's encoder.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encode)\\n     */\\n    encode(input?: string): Uint8Array;\\n    /**\\n     * Runs the UTF-8 encoder on source, stores the result of that operation into destination, and returns the progress made as an object wherein read is the number of converted code units of source and written is the number of bytes modified in destination.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encodeInto)\\n     */\\n    encodeInto(source: string, destination: Uint8Array): TextEncoderEncodeIntoResult;\\n}\\n\\ndeclare var TextEncoder: {\\n    prototype: TextEncoder;\\n    new(): TextEncoder;\\n};\\n\\ninterface TextEncoderCommon {\\n    /**\\n     * Returns \\\"utf-8\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encoding)\\n     */\\n    readonly encoding: string;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoderStream) */\\ninterface TextEncoderStream extends GenericTransformStream, TextEncoderCommon {\\n    readonly readable: ReadableStream<Uint8Array>;\\n    readonly writable: WritableStream<string>;\\n}\\n\\ndeclare var TextEncoderStream: {\\n    prototype: TextEncoderStream;\\n    new(): TextEncoderStream;\\n};\\n\\n/**\\n * The dimensions of a piece of text in the canvas, as created by the CanvasRenderingContext2D.measureText() method.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics)\\n */\\ninterface TextMetrics {\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/actualBoundingBoxAscent)\\n     */\\n    readonly actualBoundingBoxAscent: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/actualBoundingBoxDescent)\\n     */\\n    readonly actualBoundingBoxDescent: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/actualBoundingBoxLeft)\\n     */\\n    readonly actualBoundingBoxLeft: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/actualBoundingBoxRight)\\n     */\\n    readonly actualBoundingBoxRight: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/fontBoundingBoxAscent)\\n     */\\n    readonly fontBoundingBoxAscent: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/fontBoundingBoxDescent)\\n     */\\n    readonly fontBoundingBoxDescent: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/width)\\n     */\\n    readonly width: number;\\n}\\n\\ndeclare var TextMetrics: {\\n    prototype: TextMetrics;\\n    new(): TextMetrics;\\n};\\n\\ninterface TextTrackEventMap {\\n    \\\"cuechange\\\": Event;\\n}\\n\\n/**\\n * This interface also inherits properties from EventTarget.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack)\\n */\\ninterface TextTrack extends EventTarget {\\n    /**\\n     * Returns the text track cues from the text track list of cues that are currently active (i.e. that start before the current playback position and end after it), as a TextTrackCueList object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/activeCues)\\n     */\\n    readonly activeCues: TextTrackCueList | null;\\n    /**\\n     * Returns the text track list of cues, as a TextTrackCueList object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/cues)\\n     */\\n    readonly cues: TextTrackCueList | null;\\n    /**\\n     * Returns the ID of the given track.\\n     *\\n     * For in-band tracks, this is the ID that can be used with a fragment if the format supports media fragment syntax, and that can be used with the getTrackById() method.\\n     *\\n     * For TextTrack objects corresponding to track elements, this is the ID of the track element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/id)\\n     */\\n    readonly id: string;\\n    /**\\n     * Returns the text track in-band metadata track dispatch type string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/inBandMetadataTrackDispatchType)\\n     */\\n    readonly inBandMetadataTrackDispatchType: string;\\n    /**\\n     * Returns the text track kind string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/kind)\\n     */\\n    readonly kind: TextTrackKind;\\n    /**\\n     * Returns the text track label, if there is one, or the empty string otherwise (indicating that a custom label probably needs to be generated from the other attributes of the object if the object is exposed to the user).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/label)\\n     */\\n    readonly label: string;\\n    /**\\n     * Returns the text track language string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/language)\\n     */\\n    readonly language: string;\\n    /**\\n     * Returns the text track mode, represented by a string from the following list:\\n     *\\n     * Can be set, to change the mode.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/mode)\\n     */\\n    mode: TextTrackMode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/cuechange_event) */\\n    oncuechange: ((this: TextTrack, ev: Event) => any) | null;\\n    /**\\n     * Adds the given cue to textTrack's text track list of cues.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/addCue)\\n     */\\n    addCue(cue: TextTrackCue): void;\\n    /**\\n     * Removes the given cue from textTrack's text track list of cues.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrack/removeCue)\\n     */\\n    removeCue(cue: TextTrackCue): void;\\n    addEventListener<K extends keyof TextTrackEventMap>(type: K, listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof TextTrackEventMap>(type: K, listener: (this: TextTrack, ev: TextTrackEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var TextTrack: {\\n    prototype: TextTrack;\\n    new(): TextTrack;\\n};\\n\\ninterface TextTrackCueEventMap {\\n    \\\"enter\\\": Event;\\n    \\\"exit\\\": Event;\\n}\\n\\n/**\\n * TextTrackCues represent a string of text that will be displayed for some duration of time on a TextTrack. This includes the start and end times that the cue will be displayed. A TextTrackCue cannot be used directly, instead one of the derived types (e.g. VTTCue) must be used.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCue)\\n */\\ninterface TextTrackCue extends EventTarget {\\n    /**\\n     * Returns the text track cue end time, in seconds.\\n     *\\n     * Can be set.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCue/endTime)\\n     */\\n    endTime: number;\\n    /**\\n     * Returns the text track cue identifier.\\n     *\\n     * Can be set.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCue/id)\\n     */\\n    id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCue/enter_event) */\\n    onenter: ((this: TextTrackCue, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCue/exit_event) */\\n    onexit: ((this: TextTrackCue, ev: Event) => any) | null;\\n    /**\\n     * Returns true if the text track cue pause-on-exit flag is set, false otherwise.\\n     *\\n     * Can be set.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCue/pauseOnExit)\\n     */\\n    pauseOnExit: boolean;\\n    /**\\n     * Returns the text track cue start time, in seconds.\\n     *\\n     * Can be set.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCue/startTime)\\n     */\\n    startTime: number;\\n    /**\\n     * Returns the TextTrack object to which this text track cue belongs, if any, or null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCue/track)\\n     */\\n    readonly track: TextTrack | null;\\n    addEventListener<K extends keyof TextTrackCueEventMap>(type: K, listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof TextTrackCueEventMap>(type: K, listener: (this: TextTrackCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var TextTrackCue: {\\n    prototype: TextTrackCue;\\n    new(): TextTrackCue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCueList) */\\ninterface TextTrackCueList {\\n    /**\\n     * Returns the number of cues in the list.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCueList/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the first text track cue (in text track cue order) with text track cue identifier id.\\n     *\\n     * Returns null if none of the cues have the given identifier or if the argument is the empty string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackCueList/getCueById)\\n     */\\n    getCueById(id: string): TextTrackCue | null;\\n    [index: number]: TextTrackCue;\\n}\\n\\ndeclare var TextTrackCueList: {\\n    prototype: TextTrackCueList;\\n    new(): TextTrackCueList;\\n};\\n\\ninterface TextTrackListEventMap {\\n    \\\"addtrack\\\": TrackEvent;\\n    \\\"change\\\": Event;\\n    \\\"removetrack\\\": TrackEvent;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackList) */\\ninterface TextTrackList extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackList/addtrack_event) */\\n    onaddtrack: ((this: TextTrackList, ev: TrackEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackList/change_event) */\\n    onchange: ((this: TextTrackList, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackList/removetrack_event) */\\n    onremovetrack: ((this: TextTrackList, ev: TrackEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextTrackList/getTrackById) */\\n    getTrackById(id: string): TextTrack | null;\\n    addEventListener<K extends keyof TextTrackListEventMap>(type: K, listener: (this: TextTrackList, ev: TextTrackListEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof TextTrackListEventMap>(type: K, listener: (this: TextTrackList, ev: TextTrackListEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n    [index: number]: TextTrack;\\n}\\n\\ndeclare var TextTrackList: {\\n    prototype: TextTrackList;\\n    new(): TextTrackList;\\n};\\n\\n/**\\n * Used to represent a set of time ranges, primarily for the purpose of tracking which portions of media have been buffered when loading it for use by the <audio> and <video> elements.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TimeRanges)\\n */\\ninterface TimeRanges {\\n    /**\\n     * Returns the number of ranges in the object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TimeRanges/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the time for the end of the range with the given index.\\n     *\\n     * Throws an \\\"IndexSizeError\\\" DOMException if the index is out of range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TimeRanges/end)\\n     */\\n    end(index: number): number;\\n    /**\\n     * Returns the time for the start of the range with the given index.\\n     *\\n     * Throws an \\\"IndexSizeError\\\" DOMException if the index is out of range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TimeRanges/start)\\n     */\\n    start(index: number): number;\\n}\\n\\ndeclare var TimeRanges: {\\n    prototype: TimeRanges;\\n    new(): TimeRanges;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ToggleEvent) */\\ninterface ToggleEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ToggleEvent/newState) */\\n    readonly newState: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ToggleEvent/oldState) */\\n    readonly oldState: string;\\n}\\n\\ndeclare var ToggleEvent: {\\n    prototype: ToggleEvent;\\n    new(type: string, eventInitDict?: ToggleEventInit): ToggleEvent;\\n};\\n\\n/**\\n * A single contact point on a touch-sensitive device. The contact point is commonly a finger or stylus and the device may be a touchscreen or trackpad.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch)\\n */\\ninterface Touch {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/clientX) */\\n    readonly clientX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/clientY) */\\n    readonly clientY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/force) */\\n    readonly force: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/identifier) */\\n    readonly identifier: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/pageX) */\\n    readonly pageX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/pageY) */\\n    readonly pageY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/radiusX) */\\n    readonly radiusX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/radiusY) */\\n    readonly radiusY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/rotationAngle) */\\n    readonly rotationAngle: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/screenX) */\\n    readonly screenX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/screenY) */\\n    readonly screenY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Touch/target) */\\n    readonly target: EventTarget;\\n}\\n\\ndeclare var Touch: {\\n    prototype: Touch;\\n    new(touchInitDict: TouchInit): Touch;\\n};\\n\\n/**\\n * An event sent when the state of contacts with a touch-sensitive surface changes. This surface can be a touch screen or trackpad, for example. The event can describe one or more points of contact with the screen and includes support for detecting movement, addition and removal of contact points, and so forth.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchEvent)\\n */\\ninterface TouchEvent extends UIEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchEvent/altKey) */\\n    readonly altKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchEvent/changedTouches) */\\n    readonly changedTouches: TouchList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchEvent/ctrlKey) */\\n    readonly ctrlKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchEvent/metaKey) */\\n    readonly metaKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchEvent/shiftKey) */\\n    readonly shiftKey: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchEvent/targetTouches) */\\n    readonly targetTouches: TouchList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchEvent/touches) */\\n    readonly touches: TouchList;\\n}\\n\\ndeclare var TouchEvent: {\\n    prototype: TouchEvent;\\n    new(type: string, eventInitDict?: TouchEventInit): TouchEvent;\\n};\\n\\n/**\\n * A list of contact points on a touch surface. For example, if the user has three fingers on the touch surface (such as a screen or trackpad), the corresponding TouchList object would have one Touch object for each finger, for a total of three entries.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchList)\\n */\\ninterface TouchList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TouchList/item) */\\n    item(index: number): Touch | null;\\n    [index: number]: Touch;\\n}\\n\\ndeclare var TouchList: {\\n    prototype: TouchList;\\n    new(): TouchList;\\n};\\n\\n/**\\n * The TrackEvent interface, part of the HTML DOM specification, is used for events which represent changes to the set of available tracks on an HTML media element; these events are addtrack and removetrack.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TrackEvent)\\n */\\ninterface TrackEvent extends Event {\\n    /**\\n     * Returns the track object (TextTrack, AudioTrack, or VideoTrack) to which the event relates.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TrackEvent/track)\\n     */\\n    readonly track: TextTrack | null;\\n}\\n\\ndeclare var TrackEvent: {\\n    prototype: TrackEvent;\\n    new(type: string, eventInitDict?: TrackEventInit): TrackEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStream) */\\ninterface TransformStream<I = any, O = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStream/readable) */\\n    readonly readable: ReadableStream<O>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStream/writable) */\\n    readonly writable: WritableStream<I>;\\n}\\n\\ndeclare var TransformStream: {\\n    prototype: TransformStream;\\n    new<I = any, O = any>(transformer?: Transformer<I, O>, writableStrategy?: QueuingStrategy<I>, readableStrategy?: QueuingStrategy<O>): TransformStream<I, O>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController) */\\ninterface TransformStreamDefaultController<O = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController/desiredSize) */\\n    readonly desiredSize: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController/enqueue) */\\n    enqueue(chunk?: O): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController/error) */\\n    error(reason?: any): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController/terminate) */\\n    terminate(): void;\\n}\\n\\ndeclare var TransformStreamDefaultController: {\\n    prototype: TransformStreamDefaultController;\\n    new(): TransformStreamDefaultController;\\n};\\n\\n/**\\n * Events providing information related to transitions.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransitionEvent)\\n */\\ninterface TransitionEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransitionEvent/elapsedTime) */\\n    readonly elapsedTime: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransitionEvent/propertyName) */\\n    readonly propertyName: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransitionEvent/pseudoElement) */\\n    readonly pseudoElement: string;\\n}\\n\\ndeclare var TransitionEvent: {\\n    prototype: TransitionEvent;\\n    new(type: string, transitionEventInitDict?: TransitionEventInit): TransitionEvent;\\n};\\n\\n/**\\n * The nodes of a document subtree and a position within them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker)\\n */\\ninterface TreeWalker {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/currentNode) */\\n    currentNode: Node;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/filter) */\\n    readonly filter: NodeFilter | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/root) */\\n    readonly root: Node;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/whatToShow) */\\n    readonly whatToShow: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/firstChild) */\\n    firstChild(): Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/lastChild) */\\n    lastChild(): Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/nextNode) */\\n    nextNode(): Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/nextSibling) */\\n    nextSibling(): Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/parentNode) */\\n    parentNode(): Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/previousNode) */\\n    previousNode(): Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TreeWalker/previousSibling) */\\n    previousSibling(): Node | null;\\n}\\n\\ndeclare var TreeWalker: {\\n    prototype: TreeWalker;\\n    new(): TreeWalker;\\n};\\n\\n/**\\n * Simple user interface events.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/UIEvent)\\n */\\ninterface UIEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/UIEvent/detail) */\\n    readonly detail: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/UIEvent/view) */\\n    readonly view: Window | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/UIEvent/which)\\n     */\\n    readonly which: number;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/UIEvent/initUIEvent)\\n     */\\n    initUIEvent(typeArg: string, bubblesArg?: boolean, cancelableArg?: boolean, viewArg?: Window | null, detailArg?: number): void;\\n}\\n\\ndeclare var UIEvent: {\\n    prototype: UIEvent;\\n    new(type: string, eventInitDict?: UIEventInit): UIEvent;\\n};\\n\\n/**\\n * The URL interface represents an object providing static methods used for creating object URLs.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL)\\n */\\ninterface URL {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/hash) */\\n    hash: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/host) */\\n    host: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/hostname) */\\n    hostname: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/href) */\\n    href: string;\\n    toString(): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/origin) */\\n    readonly origin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/password) */\\n    password: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/pathname) */\\n    pathname: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/port) */\\n    port: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/protocol) */\\n    protocol: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/search) */\\n    search: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/searchParams) */\\n    readonly searchParams: URLSearchParams;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/username) */\\n    username: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/toJSON) */\\n    toJSON(): string;\\n}\\n\\ndeclare var URL: {\\n    prototype: URL;\\n    new(url: string | URL, base?: string | URL): URL;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/canParse_static) */\\n    canParse(url: string | URL, base?: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/createObjectURL_static) */\\n    createObjectURL(obj: Blob | MediaSource): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/revokeObjectURL_static) */\\n    revokeObjectURL(url: string): void;\\n};\\n\\ntype webkitURL = URL;\\ndeclare var webkitURL: typeof URL;\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams) */\\ninterface URLSearchParams {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/size) */\\n    readonly size: number;\\n    /**\\n     * Appends a specified key/value pair as a new search parameter.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/append)\\n     */\\n    append(name: string, value: string): void;\\n    /**\\n     * Deletes the given search parameter, and its associated value, from the list of all search parameters.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/delete)\\n     */\\n    delete(name: string, value?: string): void;\\n    /**\\n     * Returns the first value associated to the given search parameter.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/get)\\n     */\\n    get(name: string): string | null;\\n    /**\\n     * Returns all the values association with a given search parameter.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/getAll)\\n     */\\n    getAll(name: string): string[];\\n    /**\\n     * Returns a Boolean indicating if such a search parameter exists.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/has)\\n     */\\n    has(name: string, value?: string): boolean;\\n    /**\\n     * Sets the value associated to a given search parameter to the given value. If there were several values, delete the others.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/set)\\n     */\\n    set(name: string, value: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/sort) */\\n    sort(): void;\\n    /** Returns a string containing a query string suitable for use in a URL. Does not include the question mark. */\\n    toString(): string;\\n    forEach(callbackfn: (value: string, key: string, parent: URLSearchParams) => void, thisArg?: any): void;\\n}\\n\\ndeclare var URLSearchParams: {\\n    prototype: URLSearchParams;\\n    new(init?: string[][] | Record<string, string> | string | URLSearchParams): URLSearchParams;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/UserActivation) */\\ninterface UserActivation {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/UserActivation/hasBeenActive) */\\n    readonly hasBeenActive: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/UserActivation/hasBeenActive) */\\n    readonly isActive: boolean;\\n}\\n\\ndeclare var UserActivation: {\\n    prototype: UserActivation;\\n    new(): UserActivation;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue) */\\ninterface VTTCue extends TextTrackCue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/align) */\\n    align: AlignSetting;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/line) */\\n    line: LineAndPositionSetting;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/lineAlign) */\\n    lineAlign: LineAlignSetting;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/position) */\\n    position: LineAndPositionSetting;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/positionAlign) */\\n    positionAlign: PositionAlignSetting;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/region) */\\n    region: VTTRegion | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/size) */\\n    size: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/snapToLines) */\\n    snapToLines: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/text) */\\n    text: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/vertical) */\\n    vertical: DirectionSetting;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTCue/getCueAsHTML) */\\n    getCueAsHTML(): DocumentFragment;\\n    addEventListener<K extends keyof TextTrackCueEventMap>(type: K, listener: (this: VTTCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof TextTrackCueEventMap>(type: K, listener: (this: VTTCue, ev: TextTrackCueEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var VTTCue: {\\n    prototype: VTTCue;\\n    new(startTime: number, endTime: number, text: string): VTTCue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion) */\\ninterface VTTRegion {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion/id) */\\n    id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion/lines) */\\n    lines: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion/regionAnchorX) */\\n    regionAnchorX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion/regionAnchorY) */\\n    regionAnchorY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion/scroll) */\\n    scroll: ScrollSetting;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion/viewportAnchorX) */\\n    viewportAnchorX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion/viewportAnchorY) */\\n    viewportAnchorY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VTTRegion/width) */\\n    width: number;\\n}\\n\\ndeclare var VTTRegion: {\\n    prototype: VTTRegion;\\n    new(): VTTRegion;\\n};\\n\\n/**\\n * The validity states that an element can be in, with respect to constraint validation. Together, they help explain why an element's value fails to validate, if it's not valid.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState)\\n */\\ninterface ValidityState {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/badInput) */\\n    readonly badInput: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/customError) */\\n    readonly customError: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/patternMismatch) */\\n    readonly patternMismatch: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/rangeOverflow) */\\n    readonly rangeOverflow: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/rangeUnderflow) */\\n    readonly rangeUnderflow: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/stepMismatch) */\\n    readonly stepMismatch: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/tooLong) */\\n    readonly tooLong: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/tooShort) */\\n    readonly tooShort: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/typeMismatch) */\\n    readonly typeMismatch: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/valid) */\\n    readonly valid: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ValidityState/valueMissing) */\\n    readonly valueMissing: boolean;\\n}\\n\\ndeclare var ValidityState: {\\n    prototype: ValidityState;\\n    new(): ValidityState;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace) */\\ninterface VideoColorSpace {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/fullRange) */\\n    readonly fullRange: boolean | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/matrix) */\\n    readonly matrix: VideoMatrixCoefficients | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/primaries) */\\n    readonly primaries: VideoColorPrimaries | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/transfer) */\\n    readonly transfer: VideoTransferCharacteristics | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/toJSON) */\\n    toJSON(): VideoColorSpaceInit;\\n}\\n\\ndeclare var VideoColorSpace: {\\n    prototype: VideoColorSpace;\\n    new(init?: VideoColorSpaceInit): VideoColorSpace;\\n};\\n\\ninterface VideoDecoderEventMap {\\n    \\\"dequeue\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder)\\n */\\ninterface VideoDecoder extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/decodeQueueSize) */\\n    readonly decodeQueueSize: number;\\n    ondequeue: ((this: VideoDecoder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/state) */\\n    readonly state: CodecState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/configure) */\\n    configure(config: VideoDecoderConfig): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/decode) */\\n    decode(chunk: EncodedVideoChunk): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/flush) */\\n    flush(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/reset) */\\n    reset(): void;\\n    addEventListener<K extends keyof VideoDecoderEventMap>(type: K, listener: (this: VideoDecoder, ev: VideoDecoderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof VideoDecoderEventMap>(type: K, listener: (this: VideoDecoder, ev: VideoDecoderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var VideoDecoder: {\\n    prototype: VideoDecoder;\\n    new(init: VideoDecoderInit): VideoDecoder;\\n    isConfigSupported(config: VideoDecoderConfig): Promise<VideoDecoderSupport>;\\n};\\n\\ninterface VideoEncoderEventMap {\\n    \\\"dequeue\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder)\\n */\\ninterface VideoEncoder extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/encodeQueueSize) */\\n    readonly encodeQueueSize: number;\\n    ondequeue: ((this: VideoEncoder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/state) */\\n    readonly state: CodecState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/configure) */\\n    configure(config: VideoEncoderConfig): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/encode) */\\n    encode(frame: VideoFrame, options?: VideoEncoderEncodeOptions): void;\\n    flush(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/reset) */\\n    reset(): void;\\n    addEventListener<K extends keyof VideoEncoderEventMap>(type: K, listener: (this: VideoEncoder, ev: VideoEncoderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof VideoEncoderEventMap>(type: K, listener: (this: VideoEncoder, ev: VideoEncoderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var VideoEncoder: {\\n    prototype: VideoEncoder;\\n    new(init: VideoEncoderInit): VideoEncoder;\\n    isConfigSupported(config: VideoEncoderConfig): Promise<VideoEncoderSupport>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame) */\\ninterface VideoFrame {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/codedHeight) */\\n    readonly codedHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/codedRect) */\\n    readonly codedRect: DOMRectReadOnly | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/codedWidth) */\\n    readonly codedWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/colorSpace) */\\n    readonly colorSpace: VideoColorSpace;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/displayHeight) */\\n    readonly displayHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/displayWidth) */\\n    readonly displayWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/duration) */\\n    readonly duration: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/format) */\\n    readonly format: VideoPixelFormat | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/timestamp) */\\n    readonly timestamp: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/visibleRect) */\\n    readonly visibleRect: DOMRectReadOnly | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/allocationSize) */\\n    allocationSize(options?: VideoFrameCopyToOptions): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/clone) */\\n    clone(): VideoFrame;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/close) */\\n    close(): void;\\n    copyTo(destination: BufferSource, options?: VideoFrameCopyToOptions): Promise<PlaneLayout[]>;\\n}\\n\\ndeclare var VideoFrame: {\\n    prototype: VideoFrame;\\n    new(image: CanvasImageSource, init?: VideoFrameInit): VideoFrame;\\n    new(data: BufferSource, init: VideoFrameBufferInit): VideoFrame;\\n};\\n\\n/**\\n * Returned by the HTMLVideoElement.getVideoPlaybackQuality() method and contains metrics that can be used to determine the playback quality of a video.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoPlaybackQuality)\\n */\\ninterface VideoPlaybackQuality {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoPlaybackQuality/corruptedVideoFrames)\\n     */\\n    readonly corruptedVideoFrames: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoPlaybackQuality/creationTime) */\\n    readonly creationTime: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoPlaybackQuality/droppedVideoFrames) */\\n    readonly droppedVideoFrames: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoPlaybackQuality/totalVideoFrames) */\\n    readonly totalVideoFrames: number;\\n}\\n\\ndeclare var VideoPlaybackQuality: {\\n    prototype: VideoPlaybackQuality;\\n    new(): VideoPlaybackQuality;\\n};\\n\\ninterface VisualViewportEventMap {\\n    \\\"resize\\\": Event;\\n    \\\"scroll\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport) */\\ninterface VisualViewport extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/height) */\\n    readonly height: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/offsetLeft) */\\n    readonly offsetLeft: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/offsetTop) */\\n    readonly offsetTop: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/resize_event) */\\n    onresize: ((this: VisualViewport, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/scroll_event) */\\n    onscroll: ((this: VisualViewport, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/pageLeft) */\\n    readonly pageLeft: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/pageTop) */\\n    readonly pageTop: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/scale) */\\n    readonly scale: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VisualViewport/width) */\\n    readonly width: number;\\n    addEventListener<K extends keyof VisualViewportEventMap>(type: K, listener: (this: VisualViewport, ev: VisualViewportEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof VisualViewportEventMap>(type: K, listener: (this: VisualViewport, ev: VisualViewportEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var VisualViewport: {\\n    prototype: VisualViewport;\\n    new(): VisualViewport;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_color_buffer_float) */\\ninterface WEBGL_color_buffer_float {\\n    readonly RGBA32F_EXT: 0x8814;\\n    readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211;\\n    readonly UNSIGNED_NORMALIZED_EXT: 0x8C17;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_astc) */\\ninterface WEBGL_compressed_texture_astc {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_astc/getSupportedProfiles) */\\n    getSupportedProfiles(): string[];\\n    readonly COMPRESSED_RGBA_ASTC_4x4_KHR: 0x93B0;\\n    readonly COMPRESSED_RGBA_ASTC_5x4_KHR: 0x93B1;\\n    readonly COMPRESSED_RGBA_ASTC_5x5_KHR: 0x93B2;\\n    readonly COMPRESSED_RGBA_ASTC_6x5_KHR: 0x93B3;\\n    readonly COMPRESSED_RGBA_ASTC_6x6_KHR: 0x93B4;\\n    readonly COMPRESSED_RGBA_ASTC_8x5_KHR: 0x93B5;\\n    readonly COMPRESSED_RGBA_ASTC_8x6_KHR: 0x93B6;\\n    readonly COMPRESSED_RGBA_ASTC_8x8_KHR: 0x93B7;\\n    readonly COMPRESSED_RGBA_ASTC_10x5_KHR: 0x93B8;\\n    readonly COMPRESSED_RGBA_ASTC_10x6_KHR: 0x93B9;\\n    readonly COMPRESSED_RGBA_ASTC_10x8_KHR: 0x93BA;\\n    readonly COMPRESSED_RGBA_ASTC_10x10_KHR: 0x93BB;\\n    readonly COMPRESSED_RGBA_ASTC_12x10_KHR: 0x93BC;\\n    readonly COMPRESSED_RGBA_ASTC_12x12_KHR: 0x93BD;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: 0x93D0;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: 0x93D1;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: 0x93D2;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: 0x93D3;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: 0x93D4;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: 0x93D5;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: 0x93D6;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: 0x93D7;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: 0x93D8;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: 0x93D9;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: 0x93DA;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: 0x93DB;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: 0x93DC;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: 0x93DD;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_etc) */\\ninterface WEBGL_compressed_texture_etc {\\n    readonly COMPRESSED_R11_EAC: 0x9270;\\n    readonly COMPRESSED_SIGNED_R11_EAC: 0x9271;\\n    readonly COMPRESSED_RG11_EAC: 0x9272;\\n    readonly COMPRESSED_SIGNED_RG11_EAC: 0x9273;\\n    readonly COMPRESSED_RGB8_ETC2: 0x9274;\\n    readonly COMPRESSED_SRGB8_ETC2: 0x9275;\\n    readonly COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 0x9276;\\n    readonly COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 0x9277;\\n    readonly COMPRESSED_RGBA8_ETC2_EAC: 0x9278;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 0x9279;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_etc1) */\\ninterface WEBGL_compressed_texture_etc1 {\\n    readonly COMPRESSED_RGB_ETC1_WEBGL: 0x8D64;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_pvrtc) */\\ninterface WEBGL_compressed_texture_pvrtc {\\n    readonly COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 0x8C00;\\n    readonly COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 0x8C01;\\n    readonly COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 0x8C02;\\n    readonly COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: 0x8C03;\\n}\\n\\n/**\\n * The WEBGL_compressed_texture_s3tc extension is part of the WebGL API and exposes four S3TC compressed texture formats.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_s3tc)\\n */\\ninterface WEBGL_compressed_texture_s3tc {\\n    readonly COMPRESSED_RGB_S3TC_DXT1_EXT: 0x83F0;\\n    readonly COMPRESSED_RGBA_S3TC_DXT1_EXT: 0x83F1;\\n    readonly COMPRESSED_RGBA_S3TC_DXT3_EXT: 0x83F2;\\n    readonly COMPRESSED_RGBA_S3TC_DXT5_EXT: 0x83F3;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_s3tc_srgb) */\\ninterface WEBGL_compressed_texture_s3tc_srgb {\\n    readonly COMPRESSED_SRGB_S3TC_DXT1_EXT: 0x8C4C;\\n    readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 0x8C4D;\\n    readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 0x8C4E;\\n    readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 0x8C4F;\\n}\\n\\n/**\\n * The WEBGL_debug_renderer_info extension is part of the WebGL API and exposes two constants with information about the graphics driver for debugging purposes.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_debug_renderer_info)\\n */\\ninterface WEBGL_debug_renderer_info {\\n    readonly UNMASKED_VENDOR_WEBGL: 0x9245;\\n    readonly UNMASKED_RENDERER_WEBGL: 0x9246;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_debug_shaders) */\\ninterface WEBGL_debug_shaders {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_debug_shaders/getTranslatedShaderSource) */\\n    getTranslatedShaderSource(shader: WebGLShader): string;\\n}\\n\\n/**\\n * The WEBGL_depth_texture extension is part of the WebGL API and defines 2D depth and depth-stencil textures.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_depth_texture)\\n */\\ninterface WEBGL_depth_texture {\\n    readonly UNSIGNED_INT_24_8_WEBGL: 0x84FA;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_draw_buffers) */\\ninterface WEBGL_draw_buffers {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_draw_buffers/drawBuffersWEBGL) */\\n    drawBuffersWEBGL(buffers: GLenum[]): void;\\n    readonly COLOR_ATTACHMENT0_WEBGL: 0x8CE0;\\n    readonly COLOR_ATTACHMENT1_WEBGL: 0x8CE1;\\n    readonly COLOR_ATTACHMENT2_WEBGL: 0x8CE2;\\n    readonly COLOR_ATTACHMENT3_WEBGL: 0x8CE3;\\n    readonly COLOR_ATTACHMENT4_WEBGL: 0x8CE4;\\n    readonly COLOR_ATTACHMENT5_WEBGL: 0x8CE5;\\n    readonly COLOR_ATTACHMENT6_WEBGL: 0x8CE6;\\n    readonly COLOR_ATTACHMENT7_WEBGL: 0x8CE7;\\n    readonly COLOR_ATTACHMENT8_WEBGL: 0x8CE8;\\n    readonly COLOR_ATTACHMENT9_WEBGL: 0x8CE9;\\n    readonly COLOR_ATTACHMENT10_WEBGL: 0x8CEA;\\n    readonly COLOR_ATTACHMENT11_WEBGL: 0x8CEB;\\n    readonly COLOR_ATTACHMENT12_WEBGL: 0x8CEC;\\n    readonly COLOR_ATTACHMENT13_WEBGL: 0x8CED;\\n    readonly COLOR_ATTACHMENT14_WEBGL: 0x8CEE;\\n    readonly COLOR_ATTACHMENT15_WEBGL: 0x8CEF;\\n    readonly DRAW_BUFFER0_WEBGL: 0x8825;\\n    readonly DRAW_BUFFER1_WEBGL: 0x8826;\\n    readonly DRAW_BUFFER2_WEBGL: 0x8827;\\n    readonly DRAW_BUFFER3_WEBGL: 0x8828;\\n    readonly DRAW_BUFFER4_WEBGL: 0x8829;\\n    readonly DRAW_BUFFER5_WEBGL: 0x882A;\\n    readonly DRAW_BUFFER6_WEBGL: 0x882B;\\n    readonly DRAW_BUFFER7_WEBGL: 0x882C;\\n    readonly DRAW_BUFFER8_WEBGL: 0x882D;\\n    readonly DRAW_BUFFER9_WEBGL: 0x882E;\\n    readonly DRAW_BUFFER10_WEBGL: 0x882F;\\n    readonly DRAW_BUFFER11_WEBGL: 0x8830;\\n    readonly DRAW_BUFFER12_WEBGL: 0x8831;\\n    readonly DRAW_BUFFER13_WEBGL: 0x8832;\\n    readonly DRAW_BUFFER14_WEBGL: 0x8833;\\n    readonly DRAW_BUFFER15_WEBGL: 0x8834;\\n    readonly MAX_COLOR_ATTACHMENTS_WEBGL: 0x8CDF;\\n    readonly MAX_DRAW_BUFFERS_WEBGL: 0x8824;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_lose_context) */\\ninterface WEBGL_lose_context {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_lose_context/loseContext) */\\n    loseContext(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_lose_context/restoreContext) */\\n    restoreContext(): void;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw) */\\ninterface WEBGL_multi_draw {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawArraysInstancedWEBGL) */\\n    multiDrawArraysInstancedWEBGL(mode: GLenum, firstsList: Int32Array | GLint[], firstsOffset: GLuint, countsList: Int32Array | GLsizei[], countsOffset: GLuint, instanceCountsList: Int32Array | GLsizei[], instanceCountsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawArraysWEBGL) */\\n    multiDrawArraysWEBGL(mode: GLenum, firstsList: Int32Array | GLint[], firstsOffset: GLuint, countsList: Int32Array | GLsizei[], countsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawElementsInstancedWEBGL) */\\n    multiDrawElementsInstancedWEBGL(mode: GLenum, countsList: Int32Array | GLsizei[], countsOffset: GLuint, type: GLenum, offsetsList: Int32Array | GLsizei[], offsetsOffset: GLuint, instanceCountsList: Int32Array | GLsizei[], instanceCountsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawElementsWEBGL) */\\n    multiDrawElementsWEBGL(mode: GLenum, countsList: Int32Array | GLsizei[], countsOffset: GLuint, type: GLenum, offsetsList: Int32Array | GLsizei[], offsetsOffset: GLuint, drawcount: GLsizei): void;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WakeLock)\\n */\\ninterface WakeLock {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WakeLock/request) */\\n    request(type?: WakeLockType): Promise<WakeLockSentinel>;\\n}\\n\\ndeclare var WakeLock: {\\n    prototype: WakeLock;\\n    new(): WakeLock;\\n};\\n\\ninterface WakeLockSentinelEventMap {\\n    \\\"release\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WakeLockSentinel)\\n */\\ninterface WakeLockSentinel extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WakeLockSentinel/release_event) */\\n    onrelease: ((this: WakeLockSentinel, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WakeLockSentinel/released) */\\n    readonly released: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WakeLockSentinel/type) */\\n    readonly type: WakeLockType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WakeLockSentinel/release) */\\n    release(): Promise<void>;\\n    addEventListener<K extends keyof WakeLockSentinelEventMap>(type: K, listener: (this: WakeLockSentinel, ev: WakeLockSentinelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof WakeLockSentinelEventMap>(type: K, listener: (this: WakeLockSentinel, ev: WakeLockSentinelEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var WakeLockSentinel: {\\n    prototype: WakeLockSentinel;\\n    new(): WakeLockSentinel;\\n};\\n\\n/**\\n * A WaveShaperNode always has exactly one input and one output.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WaveShaperNode)\\n */\\ninterface WaveShaperNode extends AudioNode {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WaveShaperNode/curve) */\\n    curve: Float32Array | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WaveShaperNode/oversample) */\\n    oversample: OverSampleType;\\n}\\n\\ndeclare var WaveShaperNode: {\\n    prototype: WaveShaperNode;\\n    new(context: BaseAudioContext, options?: WaveShaperOptions): WaveShaperNode;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext) */\\ninterface WebGL2RenderingContext extends WebGL2RenderingContextBase, WebGL2RenderingContextOverloads, WebGLRenderingContextBase {\\n}\\n\\ndeclare var WebGL2RenderingContext: {\\n    prototype: WebGL2RenderingContext;\\n    new(): WebGL2RenderingContext;\\n    readonly READ_BUFFER: 0x0C02;\\n    readonly UNPACK_ROW_LENGTH: 0x0CF2;\\n    readonly UNPACK_SKIP_ROWS: 0x0CF3;\\n    readonly UNPACK_SKIP_PIXELS: 0x0CF4;\\n    readonly PACK_ROW_LENGTH: 0x0D02;\\n    readonly PACK_SKIP_ROWS: 0x0D03;\\n    readonly PACK_SKIP_PIXELS: 0x0D04;\\n    readonly COLOR: 0x1800;\\n    readonly DEPTH: 0x1801;\\n    readonly STENCIL: 0x1802;\\n    readonly RED: 0x1903;\\n    readonly RGB8: 0x8051;\\n    readonly RGBA8: 0x8058;\\n    readonly RGB10_A2: 0x8059;\\n    readonly TEXTURE_BINDING_3D: 0x806A;\\n    readonly UNPACK_SKIP_IMAGES: 0x806D;\\n    readonly UNPACK_IMAGE_HEIGHT: 0x806E;\\n    readonly TEXTURE_3D: 0x806F;\\n    readonly TEXTURE_WRAP_R: 0x8072;\\n    readonly MAX_3D_TEXTURE_SIZE: 0x8073;\\n    readonly UNSIGNED_INT_2_10_10_10_REV: 0x8368;\\n    readonly MAX_ELEMENTS_VERTICES: 0x80E8;\\n    readonly MAX_ELEMENTS_INDICES: 0x80E9;\\n    readonly TEXTURE_MIN_LOD: 0x813A;\\n    readonly TEXTURE_MAX_LOD: 0x813B;\\n    readonly TEXTURE_BASE_LEVEL: 0x813C;\\n    readonly TEXTURE_MAX_LEVEL: 0x813D;\\n    readonly MIN: 0x8007;\\n    readonly MAX: 0x8008;\\n    readonly DEPTH_COMPONENT24: 0x81A6;\\n    readonly MAX_TEXTURE_LOD_BIAS: 0x84FD;\\n    readonly TEXTURE_COMPARE_MODE: 0x884C;\\n    readonly TEXTURE_COMPARE_FUNC: 0x884D;\\n    readonly CURRENT_QUERY: 0x8865;\\n    readonly QUERY_RESULT: 0x8866;\\n    readonly QUERY_RESULT_AVAILABLE: 0x8867;\\n    readonly STREAM_READ: 0x88E1;\\n    readonly STREAM_COPY: 0x88E2;\\n    readonly STATIC_READ: 0x88E5;\\n    readonly STATIC_COPY: 0x88E6;\\n    readonly DYNAMIC_READ: 0x88E9;\\n    readonly DYNAMIC_COPY: 0x88EA;\\n    readonly MAX_DRAW_BUFFERS: 0x8824;\\n    readonly DRAW_BUFFER0: 0x8825;\\n    readonly DRAW_BUFFER1: 0x8826;\\n    readonly DRAW_BUFFER2: 0x8827;\\n    readonly DRAW_BUFFER3: 0x8828;\\n    readonly DRAW_BUFFER4: 0x8829;\\n    readonly DRAW_BUFFER5: 0x882A;\\n    readonly DRAW_BUFFER6: 0x882B;\\n    readonly DRAW_BUFFER7: 0x882C;\\n    readonly DRAW_BUFFER8: 0x882D;\\n    readonly DRAW_BUFFER9: 0x882E;\\n    readonly DRAW_BUFFER10: 0x882F;\\n    readonly DRAW_BUFFER11: 0x8830;\\n    readonly DRAW_BUFFER12: 0x8831;\\n    readonly DRAW_BUFFER13: 0x8832;\\n    readonly DRAW_BUFFER14: 0x8833;\\n    readonly DRAW_BUFFER15: 0x8834;\\n    readonly MAX_FRAGMENT_UNIFORM_COMPONENTS: 0x8B49;\\n    readonly MAX_VERTEX_UNIFORM_COMPONENTS: 0x8B4A;\\n    readonly SAMPLER_3D: 0x8B5F;\\n    readonly SAMPLER_2D_SHADOW: 0x8B62;\\n    readonly FRAGMENT_SHADER_DERIVATIVE_HINT: 0x8B8B;\\n    readonly PIXEL_PACK_BUFFER: 0x88EB;\\n    readonly PIXEL_UNPACK_BUFFER: 0x88EC;\\n    readonly PIXEL_PACK_BUFFER_BINDING: 0x88ED;\\n    readonly PIXEL_UNPACK_BUFFER_BINDING: 0x88EF;\\n    readonly FLOAT_MAT2x3: 0x8B65;\\n    readonly FLOAT_MAT2x4: 0x8B66;\\n    readonly FLOAT_MAT3x2: 0x8B67;\\n    readonly FLOAT_MAT3x4: 0x8B68;\\n    readonly FLOAT_MAT4x2: 0x8B69;\\n    readonly FLOAT_MAT4x3: 0x8B6A;\\n    readonly SRGB: 0x8C40;\\n    readonly SRGB8: 0x8C41;\\n    readonly SRGB8_ALPHA8: 0x8C43;\\n    readonly COMPARE_REF_TO_TEXTURE: 0x884E;\\n    readonly RGBA32F: 0x8814;\\n    readonly RGB32F: 0x8815;\\n    readonly RGBA16F: 0x881A;\\n    readonly RGB16F: 0x881B;\\n    readonly VERTEX_ATTRIB_ARRAY_INTEGER: 0x88FD;\\n    readonly MAX_ARRAY_TEXTURE_LAYERS: 0x88FF;\\n    readonly MIN_PROGRAM_TEXEL_OFFSET: 0x8904;\\n    readonly MAX_PROGRAM_TEXEL_OFFSET: 0x8905;\\n    readonly MAX_VARYING_COMPONENTS: 0x8B4B;\\n    readonly TEXTURE_2D_ARRAY: 0x8C1A;\\n    readonly TEXTURE_BINDING_2D_ARRAY: 0x8C1D;\\n    readonly R11F_G11F_B10F: 0x8C3A;\\n    readonly UNSIGNED_INT_10F_11F_11F_REV: 0x8C3B;\\n    readonly RGB9_E5: 0x8C3D;\\n    readonly UNSIGNED_INT_5_9_9_9_REV: 0x8C3E;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_MODE: 0x8C7F;\\n    readonly MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 0x8C80;\\n    readonly TRANSFORM_FEEDBACK_VARYINGS: 0x8C83;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_START: 0x8C84;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_SIZE: 0x8C85;\\n    readonly TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: 0x8C88;\\n    readonly RASTERIZER_DISCARD: 0x8C89;\\n    readonly MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 0x8C8A;\\n    readonly MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 0x8C8B;\\n    readonly INTERLEAVED_ATTRIBS: 0x8C8C;\\n    readonly SEPARATE_ATTRIBS: 0x8C8D;\\n    readonly TRANSFORM_FEEDBACK_BUFFER: 0x8C8E;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_BINDING: 0x8C8F;\\n    readonly RGBA32UI: 0x8D70;\\n    readonly RGB32UI: 0x8D71;\\n    readonly RGBA16UI: 0x8D76;\\n    readonly RGB16UI: 0x8D77;\\n    readonly RGBA8UI: 0x8D7C;\\n    readonly RGB8UI: 0x8D7D;\\n    readonly RGBA32I: 0x8D82;\\n    readonly RGB32I: 0x8D83;\\n    readonly RGBA16I: 0x8D88;\\n    readonly RGB16I: 0x8D89;\\n    readonly RGBA8I: 0x8D8E;\\n    readonly RGB8I: 0x8D8F;\\n    readonly RED_INTEGER: 0x8D94;\\n    readonly RGB_INTEGER: 0x8D98;\\n    readonly RGBA_INTEGER: 0x8D99;\\n    readonly SAMPLER_2D_ARRAY: 0x8DC1;\\n    readonly SAMPLER_2D_ARRAY_SHADOW: 0x8DC4;\\n    readonly SAMPLER_CUBE_SHADOW: 0x8DC5;\\n    readonly UNSIGNED_INT_VEC2: 0x8DC6;\\n    readonly UNSIGNED_INT_VEC3: 0x8DC7;\\n    readonly UNSIGNED_INT_VEC4: 0x8DC8;\\n    readonly INT_SAMPLER_2D: 0x8DCA;\\n    readonly INT_SAMPLER_3D: 0x8DCB;\\n    readonly INT_SAMPLER_CUBE: 0x8DCC;\\n    readonly INT_SAMPLER_2D_ARRAY: 0x8DCF;\\n    readonly UNSIGNED_INT_SAMPLER_2D: 0x8DD2;\\n    readonly UNSIGNED_INT_SAMPLER_3D: 0x8DD3;\\n    readonly UNSIGNED_INT_SAMPLER_CUBE: 0x8DD4;\\n    readonly UNSIGNED_INT_SAMPLER_2D_ARRAY: 0x8DD7;\\n    readonly DEPTH_COMPONENT32F: 0x8CAC;\\n    readonly DEPTH32F_STENCIL8: 0x8CAD;\\n    readonly FLOAT_32_UNSIGNED_INT_24_8_REV: 0x8DAD;\\n    readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: 0x8210;\\n    readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: 0x8211;\\n    readonly FRAMEBUFFER_ATTACHMENT_RED_SIZE: 0x8212;\\n    readonly FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 0x8213;\\n    readonly FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 0x8214;\\n    readonly FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 0x8215;\\n    readonly FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 0x8216;\\n    readonly FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 0x8217;\\n    readonly FRAMEBUFFER_DEFAULT: 0x8218;\\n    readonly UNSIGNED_INT_24_8: 0x84FA;\\n    readonly DEPTH24_STENCIL8: 0x88F0;\\n    readonly UNSIGNED_NORMALIZED: 0x8C17;\\n    readonly DRAW_FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly READ_FRAMEBUFFER: 0x8CA8;\\n    readonly DRAW_FRAMEBUFFER: 0x8CA9;\\n    readonly READ_FRAMEBUFFER_BINDING: 0x8CAA;\\n    readonly RENDERBUFFER_SAMPLES: 0x8CAB;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: 0x8CD4;\\n    readonly MAX_COLOR_ATTACHMENTS: 0x8CDF;\\n    readonly COLOR_ATTACHMENT1: 0x8CE1;\\n    readonly COLOR_ATTACHMENT2: 0x8CE2;\\n    readonly COLOR_ATTACHMENT3: 0x8CE3;\\n    readonly COLOR_ATTACHMENT4: 0x8CE4;\\n    readonly COLOR_ATTACHMENT5: 0x8CE5;\\n    readonly COLOR_ATTACHMENT6: 0x8CE6;\\n    readonly COLOR_ATTACHMENT7: 0x8CE7;\\n    readonly COLOR_ATTACHMENT8: 0x8CE8;\\n    readonly COLOR_ATTACHMENT9: 0x8CE9;\\n    readonly COLOR_ATTACHMENT10: 0x8CEA;\\n    readonly COLOR_ATTACHMENT11: 0x8CEB;\\n    readonly COLOR_ATTACHMENT12: 0x8CEC;\\n    readonly COLOR_ATTACHMENT13: 0x8CED;\\n    readonly COLOR_ATTACHMENT14: 0x8CEE;\\n    readonly COLOR_ATTACHMENT15: 0x8CEF;\\n    readonly FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: 0x8D56;\\n    readonly MAX_SAMPLES: 0x8D57;\\n    readonly HALF_FLOAT: 0x140B;\\n    readonly RG: 0x8227;\\n    readonly RG_INTEGER: 0x8228;\\n    readonly R8: 0x8229;\\n    readonly RG8: 0x822B;\\n    readonly R16F: 0x822D;\\n    readonly R32F: 0x822E;\\n    readonly RG16F: 0x822F;\\n    readonly RG32F: 0x8230;\\n    readonly R8I: 0x8231;\\n    readonly R8UI: 0x8232;\\n    readonly R16I: 0x8233;\\n    readonly R16UI: 0x8234;\\n    readonly R32I: 0x8235;\\n    readonly R32UI: 0x8236;\\n    readonly RG8I: 0x8237;\\n    readonly RG8UI: 0x8238;\\n    readonly RG16I: 0x8239;\\n    readonly RG16UI: 0x823A;\\n    readonly RG32I: 0x823B;\\n    readonly RG32UI: 0x823C;\\n    readonly VERTEX_ARRAY_BINDING: 0x85B5;\\n    readonly R8_SNORM: 0x8F94;\\n    readonly RG8_SNORM: 0x8F95;\\n    readonly RGB8_SNORM: 0x8F96;\\n    readonly RGBA8_SNORM: 0x8F97;\\n    readonly SIGNED_NORMALIZED: 0x8F9C;\\n    readonly COPY_READ_BUFFER: 0x8F36;\\n    readonly COPY_WRITE_BUFFER: 0x8F37;\\n    readonly COPY_READ_BUFFER_BINDING: 0x8F36;\\n    readonly COPY_WRITE_BUFFER_BINDING: 0x8F37;\\n    readonly UNIFORM_BUFFER: 0x8A11;\\n    readonly UNIFORM_BUFFER_BINDING: 0x8A28;\\n    readonly UNIFORM_BUFFER_START: 0x8A29;\\n    readonly UNIFORM_BUFFER_SIZE: 0x8A2A;\\n    readonly MAX_VERTEX_UNIFORM_BLOCKS: 0x8A2B;\\n    readonly MAX_FRAGMENT_UNIFORM_BLOCKS: 0x8A2D;\\n    readonly MAX_COMBINED_UNIFORM_BLOCKS: 0x8A2E;\\n    readonly MAX_UNIFORM_BUFFER_BINDINGS: 0x8A2F;\\n    readonly MAX_UNIFORM_BLOCK_SIZE: 0x8A30;\\n    readonly MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 0x8A31;\\n    readonly MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 0x8A33;\\n    readonly UNIFORM_BUFFER_OFFSET_ALIGNMENT: 0x8A34;\\n    readonly ACTIVE_UNIFORM_BLOCKS: 0x8A36;\\n    readonly UNIFORM_TYPE: 0x8A37;\\n    readonly UNIFORM_SIZE: 0x8A38;\\n    readonly UNIFORM_BLOCK_INDEX: 0x8A3A;\\n    readonly UNIFORM_OFFSET: 0x8A3B;\\n    readonly UNIFORM_ARRAY_STRIDE: 0x8A3C;\\n    readonly UNIFORM_MATRIX_STRIDE: 0x8A3D;\\n    readonly UNIFORM_IS_ROW_MAJOR: 0x8A3E;\\n    readonly UNIFORM_BLOCK_BINDING: 0x8A3F;\\n    readonly UNIFORM_BLOCK_DATA_SIZE: 0x8A40;\\n    readonly UNIFORM_BLOCK_ACTIVE_UNIFORMS: 0x8A42;\\n    readonly UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 0x8A43;\\n    readonly UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 0x8A44;\\n    readonly UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 0x8A46;\\n    readonly INVALID_INDEX: 0xFFFFFFFF;\\n    readonly MAX_VERTEX_OUTPUT_COMPONENTS: 0x9122;\\n    readonly MAX_FRAGMENT_INPUT_COMPONENTS: 0x9125;\\n    readonly MAX_SERVER_WAIT_TIMEOUT: 0x9111;\\n    readonly OBJECT_TYPE: 0x9112;\\n    readonly SYNC_CONDITION: 0x9113;\\n    readonly SYNC_STATUS: 0x9114;\\n    readonly SYNC_FLAGS: 0x9115;\\n    readonly SYNC_FENCE: 0x9116;\\n    readonly SYNC_GPU_COMMANDS_COMPLETE: 0x9117;\\n    readonly UNSIGNALED: 0x9118;\\n    readonly SIGNALED: 0x9119;\\n    readonly ALREADY_SIGNALED: 0x911A;\\n    readonly TIMEOUT_EXPIRED: 0x911B;\\n    readonly CONDITION_SATISFIED: 0x911C;\\n    readonly WAIT_FAILED: 0x911D;\\n    readonly SYNC_FLUSH_COMMANDS_BIT: 0x00000001;\\n    readonly VERTEX_ATTRIB_ARRAY_DIVISOR: 0x88FE;\\n    readonly ANY_SAMPLES_PASSED: 0x8C2F;\\n    readonly ANY_SAMPLES_PASSED_CONSERVATIVE: 0x8D6A;\\n    readonly SAMPLER_BINDING: 0x8919;\\n    readonly RGB10_A2UI: 0x906F;\\n    readonly INT_2_10_10_10_REV: 0x8D9F;\\n    readonly TRANSFORM_FEEDBACK: 0x8E22;\\n    readonly TRANSFORM_FEEDBACK_PAUSED: 0x8E23;\\n    readonly TRANSFORM_FEEDBACK_ACTIVE: 0x8E24;\\n    readonly TRANSFORM_FEEDBACK_BINDING: 0x8E25;\\n    readonly TEXTURE_IMMUTABLE_FORMAT: 0x912F;\\n    readonly MAX_ELEMENT_INDEX: 0x8D6B;\\n    readonly TEXTURE_IMMUTABLE_LEVELS: 0x82DF;\\n    readonly TIMEOUT_IGNORED: -1;\\n    readonly MAX_CLIENT_WAIT_TIMEOUT_WEBGL: 0x9247;\\n    readonly DEPTH_BUFFER_BIT: 0x00000100;\\n    readonly STENCIL_BUFFER_BIT: 0x00000400;\\n    readonly COLOR_BUFFER_BIT: 0x00004000;\\n    readonly POINTS: 0x0000;\\n    readonly LINES: 0x0001;\\n    readonly LINE_LOOP: 0x0002;\\n    readonly LINE_STRIP: 0x0003;\\n    readonly TRIANGLES: 0x0004;\\n    readonly TRIANGLE_STRIP: 0x0005;\\n    readonly TRIANGLE_FAN: 0x0006;\\n    readonly ZERO: 0;\\n    readonly ONE: 1;\\n    readonly SRC_COLOR: 0x0300;\\n    readonly ONE_MINUS_SRC_COLOR: 0x0301;\\n    readonly SRC_ALPHA: 0x0302;\\n    readonly ONE_MINUS_SRC_ALPHA: 0x0303;\\n    readonly DST_ALPHA: 0x0304;\\n    readonly ONE_MINUS_DST_ALPHA: 0x0305;\\n    readonly DST_COLOR: 0x0306;\\n    readonly ONE_MINUS_DST_COLOR: 0x0307;\\n    readonly SRC_ALPHA_SATURATE: 0x0308;\\n    readonly FUNC_ADD: 0x8006;\\n    readonly BLEND_EQUATION: 0x8009;\\n    readonly BLEND_EQUATION_RGB: 0x8009;\\n    readonly BLEND_EQUATION_ALPHA: 0x883D;\\n    readonly FUNC_SUBTRACT: 0x800A;\\n    readonly FUNC_REVERSE_SUBTRACT: 0x800B;\\n    readonly BLEND_DST_RGB: 0x80C8;\\n    readonly BLEND_SRC_RGB: 0x80C9;\\n    readonly BLEND_DST_ALPHA: 0x80CA;\\n    readonly BLEND_SRC_ALPHA: 0x80CB;\\n    readonly CONSTANT_COLOR: 0x8001;\\n    readonly ONE_MINUS_CONSTANT_COLOR: 0x8002;\\n    readonly CONSTANT_ALPHA: 0x8003;\\n    readonly ONE_MINUS_CONSTANT_ALPHA: 0x8004;\\n    readonly BLEND_COLOR: 0x8005;\\n    readonly ARRAY_BUFFER: 0x8892;\\n    readonly ELEMENT_ARRAY_BUFFER: 0x8893;\\n    readonly ARRAY_BUFFER_BINDING: 0x8894;\\n    readonly ELEMENT_ARRAY_BUFFER_BINDING: 0x8895;\\n    readonly STREAM_DRAW: 0x88E0;\\n    readonly STATIC_DRAW: 0x88E4;\\n    readonly DYNAMIC_DRAW: 0x88E8;\\n    readonly BUFFER_SIZE: 0x8764;\\n    readonly BUFFER_USAGE: 0x8765;\\n    readonly CURRENT_VERTEX_ATTRIB: 0x8626;\\n    readonly FRONT: 0x0404;\\n    readonly BACK: 0x0405;\\n    readonly FRONT_AND_BACK: 0x0408;\\n    readonly CULL_FACE: 0x0B44;\\n    readonly BLEND: 0x0BE2;\\n    readonly DITHER: 0x0BD0;\\n    readonly STENCIL_TEST: 0x0B90;\\n    readonly DEPTH_TEST: 0x0B71;\\n    readonly SCISSOR_TEST: 0x0C11;\\n    readonly POLYGON_OFFSET_FILL: 0x8037;\\n    readonly SAMPLE_ALPHA_TO_COVERAGE: 0x809E;\\n    readonly SAMPLE_COVERAGE: 0x80A0;\\n    readonly NO_ERROR: 0;\\n    readonly INVALID_ENUM: 0x0500;\\n    readonly INVALID_VALUE: 0x0501;\\n    readonly INVALID_OPERATION: 0x0502;\\n    readonly OUT_OF_MEMORY: 0x0505;\\n    readonly CW: 0x0900;\\n    readonly CCW: 0x0901;\\n    readonly LINE_WIDTH: 0x0B21;\\n    readonly ALIASED_POINT_SIZE_RANGE: 0x846D;\\n    readonly ALIASED_LINE_WIDTH_RANGE: 0x846E;\\n    readonly CULL_FACE_MODE: 0x0B45;\\n    readonly FRONT_FACE: 0x0B46;\\n    readonly DEPTH_RANGE: 0x0B70;\\n    readonly DEPTH_WRITEMASK: 0x0B72;\\n    readonly DEPTH_CLEAR_VALUE: 0x0B73;\\n    readonly DEPTH_FUNC: 0x0B74;\\n    readonly STENCIL_CLEAR_VALUE: 0x0B91;\\n    readonly STENCIL_FUNC: 0x0B92;\\n    readonly STENCIL_FAIL: 0x0B94;\\n    readonly STENCIL_PASS_DEPTH_FAIL: 0x0B95;\\n    readonly STENCIL_PASS_DEPTH_PASS: 0x0B96;\\n    readonly STENCIL_REF: 0x0B97;\\n    readonly STENCIL_VALUE_MASK: 0x0B93;\\n    readonly STENCIL_WRITEMASK: 0x0B98;\\n    readonly STENCIL_BACK_FUNC: 0x8800;\\n    readonly STENCIL_BACK_FAIL: 0x8801;\\n    readonly STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802;\\n    readonly STENCIL_BACK_PASS_DEPTH_PASS: 0x8803;\\n    readonly STENCIL_BACK_REF: 0x8CA3;\\n    readonly STENCIL_BACK_VALUE_MASK: 0x8CA4;\\n    readonly STENCIL_BACK_WRITEMASK: 0x8CA5;\\n    readonly VIEWPORT: 0x0BA2;\\n    readonly SCISSOR_BOX: 0x0C10;\\n    readonly COLOR_CLEAR_VALUE: 0x0C22;\\n    readonly COLOR_WRITEMASK: 0x0C23;\\n    readonly UNPACK_ALIGNMENT: 0x0CF5;\\n    readonly PACK_ALIGNMENT: 0x0D05;\\n    readonly MAX_TEXTURE_SIZE: 0x0D33;\\n    readonly MAX_VIEWPORT_DIMS: 0x0D3A;\\n    readonly SUBPIXEL_BITS: 0x0D50;\\n    readonly RED_BITS: 0x0D52;\\n    readonly GREEN_BITS: 0x0D53;\\n    readonly BLUE_BITS: 0x0D54;\\n    readonly ALPHA_BITS: 0x0D55;\\n    readonly DEPTH_BITS: 0x0D56;\\n    readonly STENCIL_BITS: 0x0D57;\\n    readonly POLYGON_OFFSET_UNITS: 0x2A00;\\n    readonly POLYGON_OFFSET_FACTOR: 0x8038;\\n    readonly TEXTURE_BINDING_2D: 0x8069;\\n    readonly SAMPLE_BUFFERS: 0x80A8;\\n    readonly SAMPLES: 0x80A9;\\n    readonly SAMPLE_COVERAGE_VALUE: 0x80AA;\\n    readonly SAMPLE_COVERAGE_INVERT: 0x80AB;\\n    readonly COMPRESSED_TEXTURE_FORMATS: 0x86A3;\\n    readonly DONT_CARE: 0x1100;\\n    readonly FASTEST: 0x1101;\\n    readonly NICEST: 0x1102;\\n    readonly GENERATE_MIPMAP_HINT: 0x8192;\\n    readonly BYTE: 0x1400;\\n    readonly UNSIGNED_BYTE: 0x1401;\\n    readonly SHORT: 0x1402;\\n    readonly UNSIGNED_SHORT: 0x1403;\\n    readonly INT: 0x1404;\\n    readonly UNSIGNED_INT: 0x1405;\\n    readonly FLOAT: 0x1406;\\n    readonly DEPTH_COMPONENT: 0x1902;\\n    readonly ALPHA: 0x1906;\\n    readonly RGB: 0x1907;\\n    readonly RGBA: 0x1908;\\n    readonly LUMINANCE: 0x1909;\\n    readonly LUMINANCE_ALPHA: 0x190A;\\n    readonly UNSIGNED_SHORT_4_4_4_4: 0x8033;\\n    readonly UNSIGNED_SHORT_5_5_5_1: 0x8034;\\n    readonly UNSIGNED_SHORT_5_6_5: 0x8363;\\n    readonly FRAGMENT_SHADER: 0x8B30;\\n    readonly VERTEX_SHADER: 0x8B31;\\n    readonly MAX_VERTEX_ATTRIBS: 0x8869;\\n    readonly MAX_VERTEX_UNIFORM_VECTORS: 0x8DFB;\\n    readonly MAX_VARYING_VECTORS: 0x8DFC;\\n    readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8B4D;\\n    readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8B4C;\\n    readonly MAX_TEXTURE_IMAGE_UNITS: 0x8872;\\n    readonly MAX_FRAGMENT_UNIFORM_VECTORS: 0x8DFD;\\n    readonly SHADER_TYPE: 0x8B4F;\\n    readonly DELETE_STATUS: 0x8B80;\\n    readonly LINK_STATUS: 0x8B82;\\n    readonly VALIDATE_STATUS: 0x8B83;\\n    readonly ATTACHED_SHADERS: 0x8B85;\\n    readonly ACTIVE_UNIFORMS: 0x8B86;\\n    readonly ACTIVE_ATTRIBUTES: 0x8B89;\\n    readonly SHADING_LANGUAGE_VERSION: 0x8B8C;\\n    readonly CURRENT_PROGRAM: 0x8B8D;\\n    readonly NEVER: 0x0200;\\n    readonly LESS: 0x0201;\\n    readonly EQUAL: 0x0202;\\n    readonly LEQUAL: 0x0203;\\n    readonly GREATER: 0x0204;\\n    readonly NOTEQUAL: 0x0205;\\n    readonly GEQUAL: 0x0206;\\n    readonly ALWAYS: 0x0207;\\n    readonly KEEP: 0x1E00;\\n    readonly REPLACE: 0x1E01;\\n    readonly INCR: 0x1E02;\\n    readonly DECR: 0x1E03;\\n    readonly INVERT: 0x150A;\\n    readonly INCR_WRAP: 0x8507;\\n    readonly DECR_WRAP: 0x8508;\\n    readonly VENDOR: 0x1F00;\\n    readonly RENDERER: 0x1F01;\\n    readonly VERSION: 0x1F02;\\n    readonly NEAREST: 0x2600;\\n    readonly LINEAR: 0x2601;\\n    readonly NEAREST_MIPMAP_NEAREST: 0x2700;\\n    readonly LINEAR_MIPMAP_NEAREST: 0x2701;\\n    readonly NEAREST_MIPMAP_LINEAR: 0x2702;\\n    readonly LINEAR_MIPMAP_LINEAR: 0x2703;\\n    readonly TEXTURE_MAG_FILTER: 0x2800;\\n    readonly TEXTURE_MIN_FILTER: 0x2801;\\n    readonly TEXTURE_WRAP_S: 0x2802;\\n    readonly TEXTURE_WRAP_T: 0x2803;\\n    readonly TEXTURE_2D: 0x0DE1;\\n    readonly TEXTURE: 0x1702;\\n    readonly TEXTURE_CUBE_MAP: 0x8513;\\n    readonly TEXTURE_BINDING_CUBE_MAP: 0x8514;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851A;\\n    readonly MAX_CUBE_MAP_TEXTURE_SIZE: 0x851C;\\n    readonly TEXTURE0: 0x84C0;\\n    readonly TEXTURE1: 0x84C1;\\n    readonly TEXTURE2: 0x84C2;\\n    readonly TEXTURE3: 0x84C3;\\n    readonly TEXTURE4: 0x84C4;\\n    readonly TEXTURE5: 0x84C5;\\n    readonly TEXTURE6: 0x84C6;\\n    readonly TEXTURE7: 0x84C7;\\n    readonly TEXTURE8: 0x84C8;\\n    readonly TEXTURE9: 0x84C9;\\n    readonly TEXTURE10: 0x84CA;\\n    readonly TEXTURE11: 0x84CB;\\n    readonly TEXTURE12: 0x84CC;\\n    readonly TEXTURE13: 0x84CD;\\n    readonly TEXTURE14: 0x84CE;\\n    readonly TEXTURE15: 0x84CF;\\n    readonly TEXTURE16: 0x84D0;\\n    readonly TEXTURE17: 0x84D1;\\n    readonly TEXTURE18: 0x84D2;\\n    readonly TEXTURE19: 0x84D3;\\n    readonly TEXTURE20: 0x84D4;\\n    readonly TEXTURE21: 0x84D5;\\n    readonly TEXTURE22: 0x84D6;\\n    readonly TEXTURE23: 0x84D7;\\n    readonly TEXTURE24: 0x84D8;\\n    readonly TEXTURE25: 0x84D9;\\n    readonly TEXTURE26: 0x84DA;\\n    readonly TEXTURE27: 0x84DB;\\n    readonly TEXTURE28: 0x84DC;\\n    readonly TEXTURE29: 0x84DD;\\n    readonly TEXTURE30: 0x84DE;\\n    readonly TEXTURE31: 0x84DF;\\n    readonly ACTIVE_TEXTURE: 0x84E0;\\n    readonly REPEAT: 0x2901;\\n    readonly CLAMP_TO_EDGE: 0x812F;\\n    readonly MIRRORED_REPEAT: 0x8370;\\n    readonly FLOAT_VEC2: 0x8B50;\\n    readonly FLOAT_VEC3: 0x8B51;\\n    readonly FLOAT_VEC4: 0x8B52;\\n    readonly INT_VEC2: 0x8B53;\\n    readonly INT_VEC3: 0x8B54;\\n    readonly INT_VEC4: 0x8B55;\\n    readonly BOOL: 0x8B56;\\n    readonly BOOL_VEC2: 0x8B57;\\n    readonly BOOL_VEC3: 0x8B58;\\n    readonly BOOL_VEC4: 0x8B59;\\n    readonly FLOAT_MAT2: 0x8B5A;\\n    readonly FLOAT_MAT3: 0x8B5B;\\n    readonly FLOAT_MAT4: 0x8B5C;\\n    readonly SAMPLER_2D: 0x8B5E;\\n    readonly SAMPLER_CUBE: 0x8B60;\\n    readonly VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622;\\n    readonly VERTEX_ATTRIB_ARRAY_SIZE: 0x8623;\\n    readonly VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624;\\n    readonly VERTEX_ATTRIB_ARRAY_TYPE: 0x8625;\\n    readonly VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886A;\\n    readonly VERTEX_ATTRIB_ARRAY_POINTER: 0x8645;\\n    readonly VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889F;\\n    readonly IMPLEMENTATION_COLOR_READ_TYPE: 0x8B9A;\\n    readonly IMPLEMENTATION_COLOR_READ_FORMAT: 0x8B9B;\\n    readonly COMPILE_STATUS: 0x8B81;\\n    readonly LOW_FLOAT: 0x8DF0;\\n    readonly MEDIUM_FLOAT: 0x8DF1;\\n    readonly HIGH_FLOAT: 0x8DF2;\\n    readonly LOW_INT: 0x8DF3;\\n    readonly MEDIUM_INT: 0x8DF4;\\n    readonly HIGH_INT: 0x8DF5;\\n    readonly FRAMEBUFFER: 0x8D40;\\n    readonly RENDERBUFFER: 0x8D41;\\n    readonly RGBA4: 0x8056;\\n    readonly RGB5_A1: 0x8057;\\n    readonly RGB565: 0x8D62;\\n    readonly DEPTH_COMPONENT16: 0x81A5;\\n    readonly STENCIL_INDEX8: 0x8D48;\\n    readonly DEPTH_STENCIL: 0x84F9;\\n    readonly RENDERBUFFER_WIDTH: 0x8D42;\\n    readonly RENDERBUFFER_HEIGHT: 0x8D43;\\n    readonly RENDERBUFFER_INTERNAL_FORMAT: 0x8D44;\\n    readonly RENDERBUFFER_RED_SIZE: 0x8D50;\\n    readonly RENDERBUFFER_GREEN_SIZE: 0x8D51;\\n    readonly RENDERBUFFER_BLUE_SIZE: 0x8D52;\\n    readonly RENDERBUFFER_ALPHA_SIZE: 0x8D53;\\n    readonly RENDERBUFFER_DEPTH_SIZE: 0x8D54;\\n    readonly RENDERBUFFER_STENCIL_SIZE: 0x8D55;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8CD0;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8CD1;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8CD2;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8CD3;\\n    readonly COLOR_ATTACHMENT0: 0x8CE0;\\n    readonly DEPTH_ATTACHMENT: 0x8D00;\\n    readonly STENCIL_ATTACHMENT: 0x8D20;\\n    readonly DEPTH_STENCIL_ATTACHMENT: 0x821A;\\n    readonly NONE: 0;\\n    readonly FRAMEBUFFER_COMPLETE: 0x8CD5;\\n    readonly FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8CD6;\\n    readonly FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8CD7;\\n    readonly FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8CD9;\\n    readonly FRAMEBUFFER_UNSUPPORTED: 0x8CDD;\\n    readonly FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly RENDERBUFFER_BINDING: 0x8CA7;\\n    readonly MAX_RENDERBUFFER_SIZE: 0x84E8;\\n    readonly INVALID_FRAMEBUFFER_OPERATION: 0x0506;\\n    readonly UNPACK_FLIP_Y_WEBGL: 0x9240;\\n    readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241;\\n    readonly CONTEXT_LOST_WEBGL: 0x9242;\\n    readonly UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243;\\n    readonly BROWSER_DEFAULT_WEBGL: 0x9244;\\n};\\n\\ninterface WebGL2RenderingContextBase {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/beginQuery) */\\n    beginQuery(target: GLenum, query: WebGLQuery): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/beginTransformFeedback) */\\n    beginTransformFeedback(primitiveMode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindBufferBase) */\\n    bindBufferBase(target: GLenum, index: GLuint, buffer: WebGLBuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindBufferRange) */\\n    bindBufferRange(target: GLenum, index: GLuint, buffer: WebGLBuffer | null, offset: GLintptr, size: GLsizeiptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindSampler) */\\n    bindSampler(unit: GLuint, sampler: WebGLSampler | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindTransformFeedback) */\\n    bindTransformFeedback(target: GLenum, tf: WebGLTransformFeedback | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindVertexArray) */\\n    bindVertexArray(array: WebGLVertexArrayObject | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/blitFramebuffer) */\\n    blitFramebuffer(srcX0: GLint, srcY0: GLint, srcX1: GLint, srcY1: GLint, dstX0: GLint, dstY0: GLint, dstX1: GLint, dstY1: GLint, mask: GLbitfield, filter: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferfi(buffer: GLenum, drawbuffer: GLint, depth: GLfloat, stencil: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferfv(buffer: GLenum, drawbuffer: GLint, values: Float32List, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferiv(buffer: GLenum, drawbuffer: GLint, values: Int32List, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferuiv(buffer: GLenum, drawbuffer: GLint, values: Uint32List, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clientWaitSync) */\\n    clientWaitSync(sync: WebGLSync, flags: GLbitfield, timeout: GLuint64): GLenum;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/compressedTexImage3D) */\\n    compressedTexImage3D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, imageSize: GLsizei, offset: GLintptr): void;\\n    compressedTexImage3D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, srcData: ArrayBufferView, srcOffset?: GLuint, srcLengthOverride?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/compressedTexSubImage3D) */\\n    compressedTexSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, imageSize: GLsizei, offset: GLintptr): void;\\n    compressedTexSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, srcData: ArrayBufferView, srcOffset?: GLuint, srcLengthOverride?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/copyBufferSubData) */\\n    copyBufferSubData(readTarget: GLenum, writeTarget: GLenum, readOffset: GLintptr, writeOffset: GLintptr, size: GLsizeiptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/copyTexSubImage3D) */\\n    copyTexSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/createQuery) */\\n    createQuery(): WebGLQuery | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/createSampler) */\\n    createSampler(): WebGLSampler | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/createTransformFeedback) */\\n    createTransformFeedback(): WebGLTransformFeedback | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/createVertexArray) */\\n    createVertexArray(): WebGLVertexArrayObject | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteQuery) */\\n    deleteQuery(query: WebGLQuery | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteSampler) */\\n    deleteSampler(sampler: WebGLSampler | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteSync) */\\n    deleteSync(sync: WebGLSync | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteTransformFeedback) */\\n    deleteTransformFeedback(tf: WebGLTransformFeedback | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteVertexArray) */\\n    deleteVertexArray(vertexArray: WebGLVertexArrayObject | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawArraysInstanced) */\\n    drawArraysInstanced(mode: GLenum, first: GLint, count: GLsizei, instanceCount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawBuffers) */\\n    drawBuffers(buffers: GLenum[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawElementsInstanced) */\\n    drawElementsInstanced(mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr, instanceCount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawRangeElements) */\\n    drawRangeElements(mode: GLenum, start: GLuint, end: GLuint, count: GLsizei, type: GLenum, offset: GLintptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/endQuery) */\\n    endQuery(target: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/endTransformFeedback) */\\n    endTransformFeedback(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/fenceSync) */\\n    fenceSync(condition: GLenum, flags: GLbitfield): WebGLSync | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/framebufferTextureLayer) */\\n    framebufferTextureLayer(target: GLenum, attachment: GLenum, texture: WebGLTexture | null, level: GLint, layer: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getActiveUniformBlockName) */\\n    getActiveUniformBlockName(program: WebGLProgram, uniformBlockIndex: GLuint): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getActiveUniformBlockParameter) */\\n    getActiveUniformBlockParameter(program: WebGLProgram, uniformBlockIndex: GLuint, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getActiveUniforms) */\\n    getActiveUniforms(program: WebGLProgram, uniformIndices: GLuint[], pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getBufferSubData) */\\n    getBufferSubData(target: GLenum, srcByteOffset: GLintptr, dstBuffer: ArrayBufferView, dstOffset?: GLuint, length?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getFragDataLocation) */\\n    getFragDataLocation(program: WebGLProgram, name: string): GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getIndexedParameter) */\\n    getIndexedParameter(target: GLenum, index: GLuint): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getInternalformatParameter) */\\n    getInternalformatParameter(target: GLenum, internalformat: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getQuery) */\\n    getQuery(target: GLenum, pname: GLenum): WebGLQuery | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getQueryParameter) */\\n    getQueryParameter(query: WebGLQuery, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getSamplerParameter) */\\n    getSamplerParameter(sampler: WebGLSampler, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getSyncParameter) */\\n    getSyncParameter(sync: WebGLSync, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getTransformFeedbackVarying) */\\n    getTransformFeedbackVarying(program: WebGLProgram, index: GLuint): WebGLActiveInfo | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getUniformBlockIndex) */\\n    getUniformBlockIndex(program: WebGLProgram, uniformBlockName: string): GLuint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getUniformIndices) */\\n    getUniformIndices(program: WebGLProgram, uniformNames: string[]): GLuint[] | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/invalidateFramebuffer) */\\n    invalidateFramebuffer(target: GLenum, attachments: GLenum[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/invalidateSubFramebuffer) */\\n    invalidateSubFramebuffer(target: GLenum, attachments: GLenum[], x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isQuery) */\\n    isQuery(query: WebGLQuery | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isSampler) */\\n    isSampler(sampler: WebGLSampler | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isSync) */\\n    isSync(sync: WebGLSync | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isTransformFeedback) */\\n    isTransformFeedback(tf: WebGLTransformFeedback | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isVertexArray) */\\n    isVertexArray(vertexArray: WebGLVertexArrayObject | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/pauseTransformFeedback) */\\n    pauseTransformFeedback(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/readBuffer) */\\n    readBuffer(src: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/renderbufferStorageMultisample) */\\n    renderbufferStorageMultisample(target: GLenum, samples: GLsizei, internalformat: GLenum, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/resumeTransformFeedback) */\\n    resumeTransformFeedback(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/samplerParameter) */\\n    samplerParameterf(sampler: WebGLSampler, pname: GLenum, param: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/samplerParameter) */\\n    samplerParameteri(sampler: WebGLSampler, pname: GLenum, param: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/texImage3D) */\\n    texImage3D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, type: GLenum, pboOffset: GLintptr): void;\\n    texImage3D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texImage3D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, type: GLenum, srcData: ArrayBufferView | null): void;\\n    texImage3D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, type: GLenum, srcData: ArrayBufferView, srcOffset: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/texStorage2D) */\\n    texStorage2D(target: GLenum, levels: GLsizei, internalformat: GLenum, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/texStorage3D) */\\n    texStorage3D(target: GLenum, levels: GLsizei, internalformat: GLenum, width: GLsizei, height: GLsizei, depth: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/texSubImage3D) */\\n    texSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, type: GLenum, pboOffset: GLintptr): void;\\n    texSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, type: GLenum, srcData: ArrayBufferView | null, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/transformFeedbackVaryings) */\\n    transformFeedbackVaryings(program: WebGLProgram, varyings: string[], bufferMode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform1ui(location: WebGLUniformLocation | null, v0: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform1uiv(location: WebGLUniformLocation | null, data: Uint32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform2ui(location: WebGLUniformLocation | null, v0: GLuint, v1: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform2uiv(location: WebGLUniformLocation | null, data: Uint32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform3ui(location: WebGLUniformLocation | null, v0: GLuint, v1: GLuint, v2: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform3uiv(location: WebGLUniformLocation | null, data: Uint32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform4ui(location: WebGLUniformLocation | null, v0: GLuint, v1: GLuint, v2: GLuint, v3: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform4uiv(location: WebGLUniformLocation | null, data: Uint32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformBlockBinding) */\\n    uniformBlockBinding(program: WebGLProgram, uniformBlockIndex: GLuint, uniformBlockBinding: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix2x3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix2x4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix3x2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix3x4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix4x2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix4x3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribDivisor) */\\n    vertexAttribDivisor(index: GLuint, divisor: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4i(index: GLuint, x: GLint, y: GLint, z: GLint, w: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4iv(index: GLuint, values: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4ui(index: GLuint, x: GLuint, y: GLuint, z: GLuint, w: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4uiv(index: GLuint, values: Uint32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribIPointer) */\\n    vertexAttribIPointer(index: GLuint, size: GLint, type: GLenum, stride: GLsizei, offset: GLintptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/waitSync) */\\n    waitSync(sync: WebGLSync, flags: GLbitfield, timeout: GLint64): void;\\n    readonly READ_BUFFER: 0x0C02;\\n    readonly UNPACK_ROW_LENGTH: 0x0CF2;\\n    readonly UNPACK_SKIP_ROWS: 0x0CF3;\\n    readonly UNPACK_SKIP_PIXELS: 0x0CF4;\\n    readonly PACK_ROW_LENGTH: 0x0D02;\\n    readonly PACK_SKIP_ROWS: 0x0D03;\\n    readonly PACK_SKIP_PIXELS: 0x0D04;\\n    readonly COLOR: 0x1800;\\n    readonly DEPTH: 0x1801;\\n    readonly STENCIL: 0x1802;\\n    readonly RED: 0x1903;\\n    readonly RGB8: 0x8051;\\n    readonly RGBA8: 0x8058;\\n    readonly RGB10_A2: 0x8059;\\n    readonly TEXTURE_BINDING_3D: 0x806A;\\n    readonly UNPACK_SKIP_IMAGES: 0x806D;\\n    readonly UNPACK_IMAGE_HEIGHT: 0x806E;\\n    readonly TEXTURE_3D: 0x806F;\\n    readonly TEXTURE_WRAP_R: 0x8072;\\n    readonly MAX_3D_TEXTURE_SIZE: 0x8073;\\n    readonly UNSIGNED_INT_2_10_10_10_REV: 0x8368;\\n    readonly MAX_ELEMENTS_VERTICES: 0x80E8;\\n    readonly MAX_ELEMENTS_INDICES: 0x80E9;\\n    readonly TEXTURE_MIN_LOD: 0x813A;\\n    readonly TEXTURE_MAX_LOD: 0x813B;\\n    readonly TEXTURE_BASE_LEVEL: 0x813C;\\n    readonly TEXTURE_MAX_LEVEL: 0x813D;\\n    readonly MIN: 0x8007;\\n    readonly MAX: 0x8008;\\n    readonly DEPTH_COMPONENT24: 0x81A6;\\n    readonly MAX_TEXTURE_LOD_BIAS: 0x84FD;\\n    readonly TEXTURE_COMPARE_MODE: 0x884C;\\n    readonly TEXTURE_COMPARE_FUNC: 0x884D;\\n    readonly CURRENT_QUERY: 0x8865;\\n    readonly QUERY_RESULT: 0x8866;\\n    readonly QUERY_RESULT_AVAILABLE: 0x8867;\\n    readonly STREAM_READ: 0x88E1;\\n    readonly STREAM_COPY: 0x88E2;\\n    readonly STATIC_READ: 0x88E5;\\n    readonly STATIC_COPY: 0x88E6;\\n    readonly DYNAMIC_READ: 0x88E9;\\n    readonly DYNAMIC_COPY: 0x88EA;\\n    readonly MAX_DRAW_BUFFERS: 0x8824;\\n    readonly DRAW_BUFFER0: 0x8825;\\n    readonly DRAW_BUFFER1: 0x8826;\\n    readonly DRAW_BUFFER2: 0x8827;\\n    readonly DRAW_BUFFER3: 0x8828;\\n    readonly DRAW_BUFFER4: 0x8829;\\n    readonly DRAW_BUFFER5: 0x882A;\\n    readonly DRAW_BUFFER6: 0x882B;\\n    readonly DRAW_BUFFER7: 0x882C;\\n    readonly DRAW_BUFFER8: 0x882D;\\n    readonly DRAW_BUFFER9: 0x882E;\\n    readonly DRAW_BUFFER10: 0x882F;\\n    readonly DRAW_BUFFER11: 0x8830;\\n    readonly DRAW_BUFFER12: 0x8831;\\n    readonly DRAW_BUFFER13: 0x8832;\\n    readonly DRAW_BUFFER14: 0x8833;\\n    readonly DRAW_BUFFER15: 0x8834;\\n    readonly MAX_FRAGMENT_UNIFORM_COMPONENTS: 0x8B49;\\n    readonly MAX_VERTEX_UNIFORM_COMPONENTS: 0x8B4A;\\n    readonly SAMPLER_3D: 0x8B5F;\\n    readonly SAMPLER_2D_SHADOW: 0x8B62;\\n    readonly FRAGMENT_SHADER_DERIVATIVE_HINT: 0x8B8B;\\n    readonly PIXEL_PACK_BUFFER: 0x88EB;\\n    readonly PIXEL_UNPACK_BUFFER: 0x88EC;\\n    readonly PIXEL_PACK_BUFFER_BINDING: 0x88ED;\\n    readonly PIXEL_UNPACK_BUFFER_BINDING: 0x88EF;\\n    readonly FLOAT_MAT2x3: 0x8B65;\\n    readonly FLOAT_MAT2x4: 0x8B66;\\n    readonly FLOAT_MAT3x2: 0x8B67;\\n    readonly FLOAT_MAT3x4: 0x8B68;\\n    readonly FLOAT_MAT4x2: 0x8B69;\\n    readonly FLOAT_MAT4x3: 0x8B6A;\\n    readonly SRGB: 0x8C40;\\n    readonly SRGB8: 0x8C41;\\n    readonly SRGB8_ALPHA8: 0x8C43;\\n    readonly COMPARE_REF_TO_TEXTURE: 0x884E;\\n    readonly RGBA32F: 0x8814;\\n    readonly RGB32F: 0x8815;\\n    readonly RGBA16F: 0x881A;\\n    readonly RGB16F: 0x881B;\\n    readonly VERTEX_ATTRIB_ARRAY_INTEGER: 0x88FD;\\n    readonly MAX_ARRAY_TEXTURE_LAYERS: 0x88FF;\\n    readonly MIN_PROGRAM_TEXEL_OFFSET: 0x8904;\\n    readonly MAX_PROGRAM_TEXEL_OFFSET: 0x8905;\\n    readonly MAX_VARYING_COMPONENTS: 0x8B4B;\\n    readonly TEXTURE_2D_ARRAY: 0x8C1A;\\n    readonly TEXTURE_BINDING_2D_ARRAY: 0x8C1D;\\n    readonly R11F_G11F_B10F: 0x8C3A;\\n    readonly UNSIGNED_INT_10F_11F_11F_REV: 0x8C3B;\\n    readonly RGB9_E5: 0x8C3D;\\n    readonly UNSIGNED_INT_5_9_9_9_REV: 0x8C3E;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_MODE: 0x8C7F;\\n    readonly MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 0x8C80;\\n    readonly TRANSFORM_FEEDBACK_VARYINGS: 0x8C83;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_START: 0x8C84;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_SIZE: 0x8C85;\\n    readonly TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: 0x8C88;\\n    readonly RASTERIZER_DISCARD: 0x8C89;\\n    readonly MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 0x8C8A;\\n    readonly MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 0x8C8B;\\n    readonly INTERLEAVED_ATTRIBS: 0x8C8C;\\n    readonly SEPARATE_ATTRIBS: 0x8C8D;\\n    readonly TRANSFORM_FEEDBACK_BUFFER: 0x8C8E;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_BINDING: 0x8C8F;\\n    readonly RGBA32UI: 0x8D70;\\n    readonly RGB32UI: 0x8D71;\\n    readonly RGBA16UI: 0x8D76;\\n    readonly RGB16UI: 0x8D77;\\n    readonly RGBA8UI: 0x8D7C;\\n    readonly RGB8UI: 0x8D7D;\\n    readonly RGBA32I: 0x8D82;\\n    readonly RGB32I: 0x8D83;\\n    readonly RGBA16I: 0x8D88;\\n    readonly RGB16I: 0x8D89;\\n    readonly RGBA8I: 0x8D8E;\\n    readonly RGB8I: 0x8D8F;\\n    readonly RED_INTEGER: 0x8D94;\\n    readonly RGB_INTEGER: 0x8D98;\\n    readonly RGBA_INTEGER: 0x8D99;\\n    readonly SAMPLER_2D_ARRAY: 0x8DC1;\\n    readonly SAMPLER_2D_ARRAY_SHADOW: 0x8DC4;\\n    readonly SAMPLER_CUBE_SHADOW: 0x8DC5;\\n    readonly UNSIGNED_INT_VEC2: 0x8DC6;\\n    readonly UNSIGNED_INT_VEC3: 0x8DC7;\\n    readonly UNSIGNED_INT_VEC4: 0x8DC8;\\n    readonly INT_SAMPLER_2D: 0x8DCA;\\n    readonly INT_SAMPLER_3D: 0x8DCB;\\n    readonly INT_SAMPLER_CUBE: 0x8DCC;\\n    readonly INT_SAMPLER_2D_ARRAY: 0x8DCF;\\n    readonly UNSIGNED_INT_SAMPLER_2D: 0x8DD2;\\n    readonly UNSIGNED_INT_SAMPLER_3D: 0x8DD3;\\n    readonly UNSIGNED_INT_SAMPLER_CUBE: 0x8DD4;\\n    readonly UNSIGNED_INT_SAMPLER_2D_ARRAY: 0x8DD7;\\n    readonly DEPTH_COMPONENT32F: 0x8CAC;\\n    readonly DEPTH32F_STENCIL8: 0x8CAD;\\n    readonly FLOAT_32_UNSIGNED_INT_24_8_REV: 0x8DAD;\\n    readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: 0x8210;\\n    readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: 0x8211;\\n    readonly FRAMEBUFFER_ATTACHMENT_RED_SIZE: 0x8212;\\n    readonly FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 0x8213;\\n    readonly FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 0x8214;\\n    readonly FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 0x8215;\\n    readonly FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 0x8216;\\n    readonly FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 0x8217;\\n    readonly FRAMEBUFFER_DEFAULT: 0x8218;\\n    readonly UNSIGNED_INT_24_8: 0x84FA;\\n    readonly DEPTH24_STENCIL8: 0x88F0;\\n    readonly UNSIGNED_NORMALIZED: 0x8C17;\\n    readonly DRAW_FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly READ_FRAMEBUFFER: 0x8CA8;\\n    readonly DRAW_FRAMEBUFFER: 0x8CA9;\\n    readonly READ_FRAMEBUFFER_BINDING: 0x8CAA;\\n    readonly RENDERBUFFER_SAMPLES: 0x8CAB;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: 0x8CD4;\\n    readonly MAX_COLOR_ATTACHMENTS: 0x8CDF;\\n    readonly COLOR_ATTACHMENT1: 0x8CE1;\\n    readonly COLOR_ATTACHMENT2: 0x8CE2;\\n    readonly COLOR_ATTACHMENT3: 0x8CE3;\\n    readonly COLOR_ATTACHMENT4: 0x8CE4;\\n    readonly COLOR_ATTACHMENT5: 0x8CE5;\\n    readonly COLOR_ATTACHMENT6: 0x8CE6;\\n    readonly COLOR_ATTACHMENT7: 0x8CE7;\\n    readonly COLOR_ATTACHMENT8: 0x8CE8;\\n    readonly COLOR_ATTACHMENT9: 0x8CE9;\\n    readonly COLOR_ATTACHMENT10: 0x8CEA;\\n    readonly COLOR_ATTACHMENT11: 0x8CEB;\\n    readonly COLOR_ATTACHMENT12: 0x8CEC;\\n    readonly COLOR_ATTACHMENT13: 0x8CED;\\n    readonly COLOR_ATTACHMENT14: 0x8CEE;\\n    readonly COLOR_ATTACHMENT15: 0x8CEF;\\n    readonly FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: 0x8D56;\\n    readonly MAX_SAMPLES: 0x8D57;\\n    readonly HALF_FLOAT: 0x140B;\\n    readonly RG: 0x8227;\\n    readonly RG_INTEGER: 0x8228;\\n    readonly R8: 0x8229;\\n    readonly RG8: 0x822B;\\n    readonly R16F: 0x822D;\\n    readonly R32F: 0x822E;\\n    readonly RG16F: 0x822F;\\n    readonly RG32F: 0x8230;\\n    readonly R8I: 0x8231;\\n    readonly R8UI: 0x8232;\\n    readonly R16I: 0x8233;\\n    readonly R16UI: 0x8234;\\n    readonly R32I: 0x8235;\\n    readonly R32UI: 0x8236;\\n    readonly RG8I: 0x8237;\\n    readonly RG8UI: 0x8238;\\n    readonly RG16I: 0x8239;\\n    readonly RG16UI: 0x823A;\\n    readonly RG32I: 0x823B;\\n    readonly RG32UI: 0x823C;\\n    readonly VERTEX_ARRAY_BINDING: 0x85B5;\\n    readonly R8_SNORM: 0x8F94;\\n    readonly RG8_SNORM: 0x8F95;\\n    readonly RGB8_SNORM: 0x8F96;\\n    readonly RGBA8_SNORM: 0x8F97;\\n    readonly SIGNED_NORMALIZED: 0x8F9C;\\n    readonly COPY_READ_BUFFER: 0x8F36;\\n    readonly COPY_WRITE_BUFFER: 0x8F37;\\n    readonly COPY_READ_BUFFER_BINDING: 0x8F36;\\n    readonly COPY_WRITE_BUFFER_BINDING: 0x8F37;\\n    readonly UNIFORM_BUFFER: 0x8A11;\\n    readonly UNIFORM_BUFFER_BINDING: 0x8A28;\\n    readonly UNIFORM_BUFFER_START: 0x8A29;\\n    readonly UNIFORM_BUFFER_SIZE: 0x8A2A;\\n    readonly MAX_VERTEX_UNIFORM_BLOCKS: 0x8A2B;\\n    readonly MAX_FRAGMENT_UNIFORM_BLOCKS: 0x8A2D;\\n    readonly MAX_COMBINED_UNIFORM_BLOCKS: 0x8A2E;\\n    readonly MAX_UNIFORM_BUFFER_BINDINGS: 0x8A2F;\\n    readonly MAX_UNIFORM_BLOCK_SIZE: 0x8A30;\\n    readonly MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 0x8A31;\\n    readonly MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 0x8A33;\\n    readonly UNIFORM_BUFFER_OFFSET_ALIGNMENT: 0x8A34;\\n    readonly ACTIVE_UNIFORM_BLOCKS: 0x8A36;\\n    readonly UNIFORM_TYPE: 0x8A37;\\n    readonly UNIFORM_SIZE: 0x8A38;\\n    readonly UNIFORM_BLOCK_INDEX: 0x8A3A;\\n    readonly UNIFORM_OFFSET: 0x8A3B;\\n    readonly UNIFORM_ARRAY_STRIDE: 0x8A3C;\\n    readonly UNIFORM_MATRIX_STRIDE: 0x8A3D;\\n    readonly UNIFORM_IS_ROW_MAJOR: 0x8A3E;\\n    readonly UNIFORM_BLOCK_BINDING: 0x8A3F;\\n    readonly UNIFORM_BLOCK_DATA_SIZE: 0x8A40;\\n    readonly UNIFORM_BLOCK_ACTIVE_UNIFORMS: 0x8A42;\\n    readonly UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 0x8A43;\\n    readonly UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 0x8A44;\\n    readonly UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 0x8A46;\\n    readonly INVALID_INDEX: 0xFFFFFFFF;\\n    readonly MAX_VERTEX_OUTPUT_COMPONENTS: 0x9122;\\n    readonly MAX_FRAGMENT_INPUT_COMPONENTS: 0x9125;\\n    readonly MAX_SERVER_WAIT_TIMEOUT: 0x9111;\\n    readonly OBJECT_TYPE: 0x9112;\\n    readonly SYNC_CONDITION: 0x9113;\\n    readonly SYNC_STATUS: 0x9114;\\n    readonly SYNC_FLAGS: 0x9115;\\n    readonly SYNC_FENCE: 0x9116;\\n    readonly SYNC_GPU_COMMANDS_COMPLETE: 0x9117;\\n    readonly UNSIGNALED: 0x9118;\\n    readonly SIGNALED: 0x9119;\\n    readonly ALREADY_SIGNALED: 0x911A;\\n    readonly TIMEOUT_EXPIRED: 0x911B;\\n    readonly CONDITION_SATISFIED: 0x911C;\\n    readonly WAIT_FAILED: 0x911D;\\n    readonly SYNC_FLUSH_COMMANDS_BIT: 0x00000001;\\n    readonly VERTEX_ATTRIB_ARRAY_DIVISOR: 0x88FE;\\n    readonly ANY_SAMPLES_PASSED: 0x8C2F;\\n    readonly ANY_SAMPLES_PASSED_CONSERVATIVE: 0x8D6A;\\n    readonly SAMPLER_BINDING: 0x8919;\\n    readonly RGB10_A2UI: 0x906F;\\n    readonly INT_2_10_10_10_REV: 0x8D9F;\\n    readonly TRANSFORM_FEEDBACK: 0x8E22;\\n    readonly TRANSFORM_FEEDBACK_PAUSED: 0x8E23;\\n    readonly TRANSFORM_FEEDBACK_ACTIVE: 0x8E24;\\n    readonly TRANSFORM_FEEDBACK_BINDING: 0x8E25;\\n    readonly TEXTURE_IMMUTABLE_FORMAT: 0x912F;\\n    readonly MAX_ELEMENT_INDEX: 0x8D6B;\\n    readonly TEXTURE_IMMUTABLE_LEVELS: 0x82DF;\\n    readonly TIMEOUT_IGNORED: -1;\\n    readonly MAX_CLIENT_WAIT_TIMEOUT_WEBGL: 0x9247;\\n}\\n\\ninterface WebGL2RenderingContextOverloads {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bufferData) */\\n    bufferData(target: GLenum, size: GLsizeiptr, usage: GLenum): void;\\n    bufferData(target: GLenum, srcData: BufferSource | null, usage: GLenum): void;\\n    bufferData(target: GLenum, srcData: ArrayBufferView, usage: GLenum, srcOffset: GLuint, length?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bufferSubData) */\\n    bufferSubData(target: GLenum, dstByteOffset: GLintptr, srcData: BufferSource): void;\\n    bufferSubData(target: GLenum, dstByteOffset: GLintptr, srcData: ArrayBufferView, srcOffset: GLuint, length?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compressedTexImage2D) */\\n    compressedTexImage2D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, imageSize: GLsizei, offset: GLintptr): void;\\n    compressedTexImage2D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, srcData: ArrayBufferView, srcOffset?: GLuint, srcLengthOverride?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compressedTexSubImage2D) */\\n    compressedTexSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, imageSize: GLsizei, offset: GLintptr): void;\\n    compressedTexSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, srcData: ArrayBufferView, srcOffset?: GLuint, srcLengthOverride?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/readPixels) */\\n    readPixels(x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, dstData: ArrayBufferView | null): void;\\n    readPixels(x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, offset: GLintptr): void;\\n    readPixels(x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, dstData: ArrayBufferView, dstOffset: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texImage2D) */\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, pboOffset: GLintptr): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, srcData: ArrayBufferView, srcOffset: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texSubImage2D) */\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pboOffset: GLintptr): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, srcData: ArrayBufferView, srcOffset: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1fv(location: WebGLUniformLocation | null, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1iv(location: WebGLUniformLocation | null, data: Int32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2fv(location: WebGLUniformLocation | null, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2iv(location: WebGLUniformLocation | null, data: Int32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3fv(location: WebGLUniformLocation | null, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3iv(location: WebGLUniformLocation | null, data: Int32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4fv(location: WebGLUniformLocation | null, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4iv(location: WebGLUniformLocation | null, data: Int32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n}\\n\\n/**\\n * Part of the WebGL API and represents the information returned by calling the WebGLRenderingContext.getActiveAttrib() and WebGLRenderingContext.getActiveUniform() methods.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLActiveInfo)\\n */\\ninterface WebGLActiveInfo {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLActiveInfo/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLActiveInfo/size) */\\n    readonly size: GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLActiveInfo/type) */\\n    readonly type: GLenum;\\n}\\n\\ndeclare var WebGLActiveInfo: {\\n    prototype: WebGLActiveInfo;\\n    new(): WebGLActiveInfo;\\n};\\n\\n/**\\n * Part of the WebGL API and represents an opaque buffer object storing data such as vertices or colors.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLBuffer)\\n */\\ninterface WebGLBuffer {\\n}\\n\\ndeclare var WebGLBuffer: {\\n    prototype: WebGLBuffer;\\n    new(): WebGLBuffer;\\n};\\n\\n/**\\n * The WebContextEvent interface is part of the WebGL API and is an interface for an event that is generated in response to a status change to the WebGL rendering context.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLContextEvent)\\n */\\ninterface WebGLContextEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLContextEvent/statusMessage) */\\n    readonly statusMessage: string;\\n}\\n\\ndeclare var WebGLContextEvent: {\\n    prototype: WebGLContextEvent;\\n    new(type: string, eventInit?: WebGLContextEventInit): WebGLContextEvent;\\n};\\n\\n/**\\n * Part of the WebGL API and represents a collection of buffers that serve as a rendering destination.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLFramebuffer)\\n */\\ninterface WebGLFramebuffer {\\n}\\n\\ndeclare var WebGLFramebuffer: {\\n    prototype: WebGLFramebuffer;\\n    new(): WebGLFramebuffer;\\n};\\n\\n/**\\n * The WebGLProgram is part of the WebGL API and is a combination of two compiled WebGLShaders consisting of a vertex shader and a fragment shader (both written in GLSL).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLProgram)\\n */\\ninterface WebGLProgram {\\n}\\n\\ndeclare var WebGLProgram: {\\n    prototype: WebGLProgram;\\n    new(): WebGLProgram;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLQuery) */\\ninterface WebGLQuery {\\n}\\n\\ndeclare var WebGLQuery: {\\n    prototype: WebGLQuery;\\n    new(): WebGLQuery;\\n};\\n\\n/**\\n * Part of the WebGL API and represents a buffer that can contain an image, or can be source or target of an rendering operation.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderbuffer)\\n */\\ninterface WebGLRenderbuffer {\\n}\\n\\ndeclare var WebGLRenderbuffer: {\\n    prototype: WebGLRenderbuffer;\\n    new(): WebGLRenderbuffer;\\n};\\n\\n/**\\n * Provides an interface to the OpenGL ES 2.0 graphics rendering context for the drawing surface of an HTML <canvas> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext)\\n */\\ninterface WebGLRenderingContext extends WebGLRenderingContextBase, WebGLRenderingContextOverloads {\\n}\\n\\ndeclare var WebGLRenderingContext: {\\n    prototype: WebGLRenderingContext;\\n    new(): WebGLRenderingContext;\\n    readonly DEPTH_BUFFER_BIT: 0x00000100;\\n    readonly STENCIL_BUFFER_BIT: 0x00000400;\\n    readonly COLOR_BUFFER_BIT: 0x00004000;\\n    readonly POINTS: 0x0000;\\n    readonly LINES: 0x0001;\\n    readonly LINE_LOOP: 0x0002;\\n    readonly LINE_STRIP: 0x0003;\\n    readonly TRIANGLES: 0x0004;\\n    readonly TRIANGLE_STRIP: 0x0005;\\n    readonly TRIANGLE_FAN: 0x0006;\\n    readonly ZERO: 0;\\n    readonly ONE: 1;\\n    readonly SRC_COLOR: 0x0300;\\n    readonly ONE_MINUS_SRC_COLOR: 0x0301;\\n    readonly SRC_ALPHA: 0x0302;\\n    readonly ONE_MINUS_SRC_ALPHA: 0x0303;\\n    readonly DST_ALPHA: 0x0304;\\n    readonly ONE_MINUS_DST_ALPHA: 0x0305;\\n    readonly DST_COLOR: 0x0306;\\n    readonly ONE_MINUS_DST_COLOR: 0x0307;\\n    readonly SRC_ALPHA_SATURATE: 0x0308;\\n    readonly FUNC_ADD: 0x8006;\\n    readonly BLEND_EQUATION: 0x8009;\\n    readonly BLEND_EQUATION_RGB: 0x8009;\\n    readonly BLEND_EQUATION_ALPHA: 0x883D;\\n    readonly FUNC_SUBTRACT: 0x800A;\\n    readonly FUNC_REVERSE_SUBTRACT: 0x800B;\\n    readonly BLEND_DST_RGB: 0x80C8;\\n    readonly BLEND_SRC_RGB: 0x80C9;\\n    readonly BLEND_DST_ALPHA: 0x80CA;\\n    readonly BLEND_SRC_ALPHA: 0x80CB;\\n    readonly CONSTANT_COLOR: 0x8001;\\n    readonly ONE_MINUS_CONSTANT_COLOR: 0x8002;\\n    readonly CONSTANT_ALPHA: 0x8003;\\n    readonly ONE_MINUS_CONSTANT_ALPHA: 0x8004;\\n    readonly BLEND_COLOR: 0x8005;\\n    readonly ARRAY_BUFFER: 0x8892;\\n    readonly ELEMENT_ARRAY_BUFFER: 0x8893;\\n    readonly ARRAY_BUFFER_BINDING: 0x8894;\\n    readonly ELEMENT_ARRAY_BUFFER_BINDING: 0x8895;\\n    readonly STREAM_DRAW: 0x88E0;\\n    readonly STATIC_DRAW: 0x88E4;\\n    readonly DYNAMIC_DRAW: 0x88E8;\\n    readonly BUFFER_SIZE: 0x8764;\\n    readonly BUFFER_USAGE: 0x8765;\\n    readonly CURRENT_VERTEX_ATTRIB: 0x8626;\\n    readonly FRONT: 0x0404;\\n    readonly BACK: 0x0405;\\n    readonly FRONT_AND_BACK: 0x0408;\\n    readonly CULL_FACE: 0x0B44;\\n    readonly BLEND: 0x0BE2;\\n    readonly DITHER: 0x0BD0;\\n    readonly STENCIL_TEST: 0x0B90;\\n    readonly DEPTH_TEST: 0x0B71;\\n    readonly SCISSOR_TEST: 0x0C11;\\n    readonly POLYGON_OFFSET_FILL: 0x8037;\\n    readonly SAMPLE_ALPHA_TO_COVERAGE: 0x809E;\\n    readonly SAMPLE_COVERAGE: 0x80A0;\\n    readonly NO_ERROR: 0;\\n    readonly INVALID_ENUM: 0x0500;\\n    readonly INVALID_VALUE: 0x0501;\\n    readonly INVALID_OPERATION: 0x0502;\\n    readonly OUT_OF_MEMORY: 0x0505;\\n    readonly CW: 0x0900;\\n    readonly CCW: 0x0901;\\n    readonly LINE_WIDTH: 0x0B21;\\n    readonly ALIASED_POINT_SIZE_RANGE: 0x846D;\\n    readonly ALIASED_LINE_WIDTH_RANGE: 0x846E;\\n    readonly CULL_FACE_MODE: 0x0B45;\\n    readonly FRONT_FACE: 0x0B46;\\n    readonly DEPTH_RANGE: 0x0B70;\\n    readonly DEPTH_WRITEMASK: 0x0B72;\\n    readonly DEPTH_CLEAR_VALUE: 0x0B73;\\n    readonly DEPTH_FUNC: 0x0B74;\\n    readonly STENCIL_CLEAR_VALUE: 0x0B91;\\n    readonly STENCIL_FUNC: 0x0B92;\\n    readonly STENCIL_FAIL: 0x0B94;\\n    readonly STENCIL_PASS_DEPTH_FAIL: 0x0B95;\\n    readonly STENCIL_PASS_DEPTH_PASS: 0x0B96;\\n    readonly STENCIL_REF: 0x0B97;\\n    readonly STENCIL_VALUE_MASK: 0x0B93;\\n    readonly STENCIL_WRITEMASK: 0x0B98;\\n    readonly STENCIL_BACK_FUNC: 0x8800;\\n    readonly STENCIL_BACK_FAIL: 0x8801;\\n    readonly STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802;\\n    readonly STENCIL_BACK_PASS_DEPTH_PASS: 0x8803;\\n    readonly STENCIL_BACK_REF: 0x8CA3;\\n    readonly STENCIL_BACK_VALUE_MASK: 0x8CA4;\\n    readonly STENCIL_BACK_WRITEMASK: 0x8CA5;\\n    readonly VIEWPORT: 0x0BA2;\\n    readonly SCISSOR_BOX: 0x0C10;\\n    readonly COLOR_CLEAR_VALUE: 0x0C22;\\n    readonly COLOR_WRITEMASK: 0x0C23;\\n    readonly UNPACK_ALIGNMENT: 0x0CF5;\\n    readonly PACK_ALIGNMENT: 0x0D05;\\n    readonly MAX_TEXTURE_SIZE: 0x0D33;\\n    readonly MAX_VIEWPORT_DIMS: 0x0D3A;\\n    readonly SUBPIXEL_BITS: 0x0D50;\\n    readonly RED_BITS: 0x0D52;\\n    readonly GREEN_BITS: 0x0D53;\\n    readonly BLUE_BITS: 0x0D54;\\n    readonly ALPHA_BITS: 0x0D55;\\n    readonly DEPTH_BITS: 0x0D56;\\n    readonly STENCIL_BITS: 0x0D57;\\n    readonly POLYGON_OFFSET_UNITS: 0x2A00;\\n    readonly POLYGON_OFFSET_FACTOR: 0x8038;\\n    readonly TEXTURE_BINDING_2D: 0x8069;\\n    readonly SAMPLE_BUFFERS: 0x80A8;\\n    readonly SAMPLES: 0x80A9;\\n    readonly SAMPLE_COVERAGE_VALUE: 0x80AA;\\n    readonly SAMPLE_COVERAGE_INVERT: 0x80AB;\\n    readonly COMPRESSED_TEXTURE_FORMATS: 0x86A3;\\n    readonly DONT_CARE: 0x1100;\\n    readonly FASTEST: 0x1101;\\n    readonly NICEST: 0x1102;\\n    readonly GENERATE_MIPMAP_HINT: 0x8192;\\n    readonly BYTE: 0x1400;\\n    readonly UNSIGNED_BYTE: 0x1401;\\n    readonly SHORT: 0x1402;\\n    readonly UNSIGNED_SHORT: 0x1403;\\n    readonly INT: 0x1404;\\n    readonly UNSIGNED_INT: 0x1405;\\n    readonly FLOAT: 0x1406;\\n    readonly DEPTH_COMPONENT: 0x1902;\\n    readonly ALPHA: 0x1906;\\n    readonly RGB: 0x1907;\\n    readonly RGBA: 0x1908;\\n    readonly LUMINANCE: 0x1909;\\n    readonly LUMINANCE_ALPHA: 0x190A;\\n    readonly UNSIGNED_SHORT_4_4_4_4: 0x8033;\\n    readonly UNSIGNED_SHORT_5_5_5_1: 0x8034;\\n    readonly UNSIGNED_SHORT_5_6_5: 0x8363;\\n    readonly FRAGMENT_SHADER: 0x8B30;\\n    readonly VERTEX_SHADER: 0x8B31;\\n    readonly MAX_VERTEX_ATTRIBS: 0x8869;\\n    readonly MAX_VERTEX_UNIFORM_VECTORS: 0x8DFB;\\n    readonly MAX_VARYING_VECTORS: 0x8DFC;\\n    readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8B4D;\\n    readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8B4C;\\n    readonly MAX_TEXTURE_IMAGE_UNITS: 0x8872;\\n    readonly MAX_FRAGMENT_UNIFORM_VECTORS: 0x8DFD;\\n    readonly SHADER_TYPE: 0x8B4F;\\n    readonly DELETE_STATUS: 0x8B80;\\n    readonly LINK_STATUS: 0x8B82;\\n    readonly VALIDATE_STATUS: 0x8B83;\\n    readonly ATTACHED_SHADERS: 0x8B85;\\n    readonly ACTIVE_UNIFORMS: 0x8B86;\\n    readonly ACTIVE_ATTRIBUTES: 0x8B89;\\n    readonly SHADING_LANGUAGE_VERSION: 0x8B8C;\\n    readonly CURRENT_PROGRAM: 0x8B8D;\\n    readonly NEVER: 0x0200;\\n    readonly LESS: 0x0201;\\n    readonly EQUAL: 0x0202;\\n    readonly LEQUAL: 0x0203;\\n    readonly GREATER: 0x0204;\\n    readonly NOTEQUAL: 0x0205;\\n    readonly GEQUAL: 0x0206;\\n    readonly ALWAYS: 0x0207;\\n    readonly KEEP: 0x1E00;\\n    readonly REPLACE: 0x1E01;\\n    readonly INCR: 0x1E02;\\n    readonly DECR: 0x1E03;\\n    readonly INVERT: 0x150A;\\n    readonly INCR_WRAP: 0x8507;\\n    readonly DECR_WRAP: 0x8508;\\n    readonly VENDOR: 0x1F00;\\n    readonly RENDERER: 0x1F01;\\n    readonly VERSION: 0x1F02;\\n    readonly NEAREST: 0x2600;\\n    readonly LINEAR: 0x2601;\\n    readonly NEAREST_MIPMAP_NEAREST: 0x2700;\\n    readonly LINEAR_MIPMAP_NEAREST: 0x2701;\\n    readonly NEAREST_MIPMAP_LINEAR: 0x2702;\\n    readonly LINEAR_MIPMAP_LINEAR: 0x2703;\\n    readonly TEXTURE_MAG_FILTER: 0x2800;\\n    readonly TEXTURE_MIN_FILTER: 0x2801;\\n    readonly TEXTURE_WRAP_S: 0x2802;\\n    readonly TEXTURE_WRAP_T: 0x2803;\\n    readonly TEXTURE_2D: 0x0DE1;\\n    readonly TEXTURE: 0x1702;\\n    readonly TEXTURE_CUBE_MAP: 0x8513;\\n    readonly TEXTURE_BINDING_CUBE_MAP: 0x8514;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851A;\\n    readonly MAX_CUBE_MAP_TEXTURE_SIZE: 0x851C;\\n    readonly TEXTURE0: 0x84C0;\\n    readonly TEXTURE1: 0x84C1;\\n    readonly TEXTURE2: 0x84C2;\\n    readonly TEXTURE3: 0x84C3;\\n    readonly TEXTURE4: 0x84C4;\\n    readonly TEXTURE5: 0x84C5;\\n    readonly TEXTURE6: 0x84C6;\\n    readonly TEXTURE7: 0x84C7;\\n    readonly TEXTURE8: 0x84C8;\\n    readonly TEXTURE9: 0x84C9;\\n    readonly TEXTURE10: 0x84CA;\\n    readonly TEXTURE11: 0x84CB;\\n    readonly TEXTURE12: 0x84CC;\\n    readonly TEXTURE13: 0x84CD;\\n    readonly TEXTURE14: 0x84CE;\\n    readonly TEXTURE15: 0x84CF;\\n    readonly TEXTURE16: 0x84D0;\\n    readonly TEXTURE17: 0x84D1;\\n    readonly TEXTURE18: 0x84D2;\\n    readonly TEXTURE19: 0x84D3;\\n    readonly TEXTURE20: 0x84D4;\\n    readonly TEXTURE21: 0x84D5;\\n    readonly TEXTURE22: 0x84D6;\\n    readonly TEXTURE23: 0x84D7;\\n    readonly TEXTURE24: 0x84D8;\\n    readonly TEXTURE25: 0x84D9;\\n    readonly TEXTURE26: 0x84DA;\\n    readonly TEXTURE27: 0x84DB;\\n    readonly TEXTURE28: 0x84DC;\\n    readonly TEXTURE29: 0x84DD;\\n    readonly TEXTURE30: 0x84DE;\\n    readonly TEXTURE31: 0x84DF;\\n    readonly ACTIVE_TEXTURE: 0x84E0;\\n    readonly REPEAT: 0x2901;\\n    readonly CLAMP_TO_EDGE: 0x812F;\\n    readonly MIRRORED_REPEAT: 0x8370;\\n    readonly FLOAT_VEC2: 0x8B50;\\n    readonly FLOAT_VEC3: 0x8B51;\\n    readonly FLOAT_VEC4: 0x8B52;\\n    readonly INT_VEC2: 0x8B53;\\n    readonly INT_VEC3: 0x8B54;\\n    readonly INT_VEC4: 0x8B55;\\n    readonly BOOL: 0x8B56;\\n    readonly BOOL_VEC2: 0x8B57;\\n    readonly BOOL_VEC3: 0x8B58;\\n    readonly BOOL_VEC4: 0x8B59;\\n    readonly FLOAT_MAT2: 0x8B5A;\\n    readonly FLOAT_MAT3: 0x8B5B;\\n    readonly FLOAT_MAT4: 0x8B5C;\\n    readonly SAMPLER_2D: 0x8B5E;\\n    readonly SAMPLER_CUBE: 0x8B60;\\n    readonly VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622;\\n    readonly VERTEX_ATTRIB_ARRAY_SIZE: 0x8623;\\n    readonly VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624;\\n    readonly VERTEX_ATTRIB_ARRAY_TYPE: 0x8625;\\n    readonly VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886A;\\n    readonly VERTEX_ATTRIB_ARRAY_POINTER: 0x8645;\\n    readonly VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889F;\\n    readonly IMPLEMENTATION_COLOR_READ_TYPE: 0x8B9A;\\n    readonly IMPLEMENTATION_COLOR_READ_FORMAT: 0x8B9B;\\n    readonly COMPILE_STATUS: 0x8B81;\\n    readonly LOW_FLOAT: 0x8DF0;\\n    readonly MEDIUM_FLOAT: 0x8DF1;\\n    readonly HIGH_FLOAT: 0x8DF2;\\n    readonly LOW_INT: 0x8DF3;\\n    readonly MEDIUM_INT: 0x8DF4;\\n    readonly HIGH_INT: 0x8DF5;\\n    readonly FRAMEBUFFER: 0x8D40;\\n    readonly RENDERBUFFER: 0x8D41;\\n    readonly RGBA4: 0x8056;\\n    readonly RGB5_A1: 0x8057;\\n    readonly RGB565: 0x8D62;\\n    readonly DEPTH_COMPONENT16: 0x81A5;\\n    readonly STENCIL_INDEX8: 0x8D48;\\n    readonly DEPTH_STENCIL: 0x84F9;\\n    readonly RENDERBUFFER_WIDTH: 0x8D42;\\n    readonly RENDERBUFFER_HEIGHT: 0x8D43;\\n    readonly RENDERBUFFER_INTERNAL_FORMAT: 0x8D44;\\n    readonly RENDERBUFFER_RED_SIZE: 0x8D50;\\n    readonly RENDERBUFFER_GREEN_SIZE: 0x8D51;\\n    readonly RENDERBUFFER_BLUE_SIZE: 0x8D52;\\n    readonly RENDERBUFFER_ALPHA_SIZE: 0x8D53;\\n    readonly RENDERBUFFER_DEPTH_SIZE: 0x8D54;\\n    readonly RENDERBUFFER_STENCIL_SIZE: 0x8D55;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8CD0;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8CD1;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8CD2;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8CD3;\\n    readonly COLOR_ATTACHMENT0: 0x8CE0;\\n    readonly DEPTH_ATTACHMENT: 0x8D00;\\n    readonly STENCIL_ATTACHMENT: 0x8D20;\\n    readonly DEPTH_STENCIL_ATTACHMENT: 0x821A;\\n    readonly NONE: 0;\\n    readonly FRAMEBUFFER_COMPLETE: 0x8CD5;\\n    readonly FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8CD6;\\n    readonly FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8CD7;\\n    readonly FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8CD9;\\n    readonly FRAMEBUFFER_UNSUPPORTED: 0x8CDD;\\n    readonly FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly RENDERBUFFER_BINDING: 0x8CA7;\\n    readonly MAX_RENDERBUFFER_SIZE: 0x84E8;\\n    readonly INVALID_FRAMEBUFFER_OPERATION: 0x0506;\\n    readonly UNPACK_FLIP_Y_WEBGL: 0x9240;\\n    readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241;\\n    readonly CONTEXT_LOST_WEBGL: 0x9242;\\n    readonly UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243;\\n    readonly BROWSER_DEFAULT_WEBGL: 0x9244;\\n};\\n\\ninterface WebGLRenderingContextBase {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/canvas) */\\n    readonly canvas: HTMLCanvasElement | OffscreenCanvas;\\n    drawingBufferColorSpace: PredefinedColorSpace;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/drawingBufferHeight) */\\n    readonly drawingBufferHeight: GLsizei;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/drawingBufferWidth) */\\n    readonly drawingBufferWidth: GLsizei;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/activeTexture) */\\n    activeTexture(texture: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/attachShader) */\\n    attachShader(program: WebGLProgram, shader: WebGLShader): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindAttribLocation) */\\n    bindAttribLocation(program: WebGLProgram, index: GLuint, name: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindBuffer) */\\n    bindBuffer(target: GLenum, buffer: WebGLBuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindFramebuffer) */\\n    bindFramebuffer(target: GLenum, framebuffer: WebGLFramebuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindRenderbuffer) */\\n    bindRenderbuffer(target: GLenum, renderbuffer: WebGLRenderbuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindTexture) */\\n    bindTexture(target: GLenum, texture: WebGLTexture | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendColor) */\\n    blendColor(red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendEquation) */\\n    blendEquation(mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendEquationSeparate) */\\n    blendEquationSeparate(modeRGB: GLenum, modeAlpha: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendFunc) */\\n    blendFunc(sfactor: GLenum, dfactor: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendFuncSeparate) */\\n    blendFuncSeparate(srcRGB: GLenum, dstRGB: GLenum, srcAlpha: GLenum, dstAlpha: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/checkFramebufferStatus) */\\n    checkFramebufferStatus(target: GLenum): GLenum;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/clear) */\\n    clear(mask: GLbitfield): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/clearColor) */\\n    clearColor(red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/clearDepth) */\\n    clearDepth(depth: GLclampf): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/clearStencil) */\\n    clearStencil(s: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/colorMask) */\\n    colorMask(red: GLboolean, green: GLboolean, blue: GLboolean, alpha: GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compileShader) */\\n    compileShader(shader: WebGLShader): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/copyTexImage2D) */\\n    copyTexImage2D(target: GLenum, level: GLint, internalformat: GLenum, x: GLint, y: GLint, width: GLsizei, height: GLsizei, border: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/copyTexSubImage2D) */\\n    copyTexSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createBuffer) */\\n    createBuffer(): WebGLBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createFramebuffer) */\\n    createFramebuffer(): WebGLFramebuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createProgram) */\\n    createProgram(): WebGLProgram | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createRenderbuffer) */\\n    createRenderbuffer(): WebGLRenderbuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createShader) */\\n    createShader(type: GLenum): WebGLShader | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createTexture) */\\n    createTexture(): WebGLTexture | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/cullFace) */\\n    cullFace(mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteBuffer) */\\n    deleteBuffer(buffer: WebGLBuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteFramebuffer) */\\n    deleteFramebuffer(framebuffer: WebGLFramebuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteProgram) */\\n    deleteProgram(program: WebGLProgram | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteRenderbuffer) */\\n    deleteRenderbuffer(renderbuffer: WebGLRenderbuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteShader) */\\n    deleteShader(shader: WebGLShader | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteTexture) */\\n    deleteTexture(texture: WebGLTexture | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/depthFunc) */\\n    depthFunc(func: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/depthMask) */\\n    depthMask(flag: GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/depthRange) */\\n    depthRange(zNear: GLclampf, zFar: GLclampf): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/detachShader) */\\n    detachShader(program: WebGLProgram, shader: WebGLShader): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/disable) */\\n    disable(cap: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/disableVertexAttribArray) */\\n    disableVertexAttribArray(index: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/drawArrays) */\\n    drawArrays(mode: GLenum, first: GLint, count: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/drawElements) */\\n    drawElements(mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/enable) */\\n    enable(cap: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/enableVertexAttribArray) */\\n    enableVertexAttribArray(index: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/finish) */\\n    finish(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/flush) */\\n    flush(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/framebufferRenderbuffer) */\\n    framebufferRenderbuffer(target: GLenum, attachment: GLenum, renderbuffertarget: GLenum, renderbuffer: WebGLRenderbuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/framebufferTexture2D) */\\n    framebufferTexture2D(target: GLenum, attachment: GLenum, textarget: GLenum, texture: WebGLTexture | null, level: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/frontFace) */\\n    frontFace(mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/generateMipmap) */\\n    generateMipmap(target: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getActiveAttrib) */\\n    getActiveAttrib(program: WebGLProgram, index: GLuint): WebGLActiveInfo | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getActiveUniform) */\\n    getActiveUniform(program: WebGLProgram, index: GLuint): WebGLActiveInfo | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getAttachedShaders) */\\n    getAttachedShaders(program: WebGLProgram): WebGLShader[] | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getAttribLocation) */\\n    getAttribLocation(program: WebGLProgram, name: string): GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getBufferParameter) */\\n    getBufferParameter(target: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getContextAttributes) */\\n    getContextAttributes(): WebGLContextAttributes | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getError) */\\n    getError(): GLenum;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getExtension) */\\n    getExtension(extensionName: \\\"ANGLE_instanced_arrays\\\"): ANGLE_instanced_arrays | null;\\n    getExtension(extensionName: \\\"EXT_blend_minmax\\\"): EXT_blend_minmax | null;\\n    getExtension(extensionName: \\\"EXT_color_buffer_float\\\"): EXT_color_buffer_float | null;\\n    getExtension(extensionName: \\\"EXT_color_buffer_half_float\\\"): EXT_color_buffer_half_float | null;\\n    getExtension(extensionName: \\\"EXT_float_blend\\\"): EXT_float_blend | null;\\n    getExtension(extensionName: \\\"EXT_frag_depth\\\"): EXT_frag_depth | null;\\n    getExtension(extensionName: \\\"EXT_sRGB\\\"): EXT_sRGB | null;\\n    getExtension(extensionName: \\\"EXT_shader_texture_lod\\\"): EXT_shader_texture_lod | null;\\n    getExtension(extensionName: \\\"EXT_texture_compression_bptc\\\"): EXT_texture_compression_bptc | null;\\n    getExtension(extensionName: \\\"EXT_texture_compression_rgtc\\\"): EXT_texture_compression_rgtc | null;\\n    getExtension(extensionName: \\\"EXT_texture_filter_anisotropic\\\"): EXT_texture_filter_anisotropic | null;\\n    getExtension(extensionName: \\\"KHR_parallel_shader_compile\\\"): KHR_parallel_shader_compile | null;\\n    getExtension(extensionName: \\\"OES_element_index_uint\\\"): OES_element_index_uint | null;\\n    getExtension(extensionName: \\\"OES_fbo_render_mipmap\\\"): OES_fbo_render_mipmap | null;\\n    getExtension(extensionName: \\\"OES_standard_derivatives\\\"): OES_standard_derivatives | null;\\n    getExtension(extensionName: \\\"OES_texture_float\\\"): OES_texture_float | null;\\n    getExtension(extensionName: \\\"OES_texture_float_linear\\\"): OES_texture_float_linear | null;\\n    getExtension(extensionName: \\\"OES_texture_half_float\\\"): OES_texture_half_float | null;\\n    getExtension(extensionName: \\\"OES_texture_half_float_linear\\\"): OES_texture_half_float_linear | null;\\n    getExtension(extensionName: \\\"OES_vertex_array_object\\\"): OES_vertex_array_object | null;\\n    getExtension(extensionName: \\\"OVR_multiview2\\\"): OVR_multiview2 | null;\\n    getExtension(extensionName: \\\"WEBGL_color_buffer_float\\\"): WEBGL_color_buffer_float | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_astc\\\"): WEBGL_compressed_texture_astc | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_etc\\\"): WEBGL_compressed_texture_etc | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_etc1\\\"): WEBGL_compressed_texture_etc1 | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_pvrtc\\\"): WEBGL_compressed_texture_pvrtc | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_s3tc\\\"): WEBGL_compressed_texture_s3tc | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_s3tc_srgb\\\"): WEBGL_compressed_texture_s3tc_srgb | null;\\n    getExtension(extensionName: \\\"WEBGL_debug_renderer_info\\\"): WEBGL_debug_renderer_info | null;\\n    getExtension(extensionName: \\\"WEBGL_debug_shaders\\\"): WEBGL_debug_shaders | null;\\n    getExtension(extensionName: \\\"WEBGL_depth_texture\\\"): WEBGL_depth_texture | null;\\n    getExtension(extensionName: \\\"WEBGL_draw_buffers\\\"): WEBGL_draw_buffers | null;\\n    getExtension(extensionName: \\\"WEBGL_lose_context\\\"): WEBGL_lose_context | null;\\n    getExtension(extensionName: \\\"WEBGL_multi_draw\\\"): WEBGL_multi_draw | null;\\n    getExtension(name: string): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getFramebufferAttachmentParameter) */\\n    getFramebufferAttachmentParameter(target: GLenum, attachment: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getParameter) */\\n    getParameter(pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getProgramInfoLog) */\\n    getProgramInfoLog(program: WebGLProgram): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getProgramParameter) */\\n    getProgramParameter(program: WebGLProgram, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getRenderbufferParameter) */\\n    getRenderbufferParameter(target: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getShaderInfoLog) */\\n    getShaderInfoLog(shader: WebGLShader): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getShaderParameter) */\\n    getShaderParameter(shader: WebGLShader, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getShaderPrecisionFormat) */\\n    getShaderPrecisionFormat(shadertype: GLenum, precisiontype: GLenum): WebGLShaderPrecisionFormat | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getShaderSource) */\\n    getShaderSource(shader: WebGLShader): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getSupportedExtensions) */\\n    getSupportedExtensions(): string[] | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getTexParameter) */\\n    getTexParameter(target: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getUniform) */\\n    getUniform(program: WebGLProgram, location: WebGLUniformLocation): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getUniformLocation) */\\n    getUniformLocation(program: WebGLProgram, name: string): WebGLUniformLocation | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getVertexAttrib) */\\n    getVertexAttrib(index: GLuint, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getVertexAttribOffset) */\\n    getVertexAttribOffset(index: GLuint, pname: GLenum): GLintptr;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/hint) */\\n    hint(target: GLenum, mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isBuffer) */\\n    isBuffer(buffer: WebGLBuffer | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isContextLost) */\\n    isContextLost(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isEnabled) */\\n    isEnabled(cap: GLenum): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isFramebuffer) */\\n    isFramebuffer(framebuffer: WebGLFramebuffer | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isProgram) */\\n    isProgram(program: WebGLProgram | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isRenderbuffer) */\\n    isRenderbuffer(renderbuffer: WebGLRenderbuffer | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isShader) */\\n    isShader(shader: WebGLShader | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isTexture) */\\n    isTexture(texture: WebGLTexture | null): GLboolean;\\n    lineWidth(width: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/linkProgram) */\\n    linkProgram(program: WebGLProgram): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/pixelStorei) */\\n    pixelStorei(pname: GLenum, param: GLint | GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/polygonOffset) */\\n    polygonOffset(factor: GLfloat, units: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/renderbufferStorage) */\\n    renderbufferStorage(target: GLenum, internalformat: GLenum, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/sampleCoverage) */\\n    sampleCoverage(value: GLclampf, invert: GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/scissor) */\\n    scissor(x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/shaderSource) */\\n    shaderSource(shader: WebGLShader, source: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilFunc) */\\n    stencilFunc(func: GLenum, ref: GLint, mask: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilFuncSeparate) */\\n    stencilFuncSeparate(face: GLenum, func: GLenum, ref: GLint, mask: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilMask) */\\n    stencilMask(mask: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilMaskSeparate) */\\n    stencilMaskSeparate(face: GLenum, mask: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilOp) */\\n    stencilOp(fail: GLenum, zfail: GLenum, zpass: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilOpSeparate) */\\n    stencilOpSeparate(face: GLenum, fail: GLenum, zfail: GLenum, zpass: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texParameter) */\\n    texParameterf(target: GLenum, pname: GLenum, param: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texParameter) */\\n    texParameteri(target: GLenum, pname: GLenum, param: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1f(location: WebGLUniformLocation | null, x: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1i(location: WebGLUniformLocation | null, x: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2f(location: WebGLUniformLocation | null, x: GLfloat, y: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2i(location: WebGLUniformLocation | null, x: GLint, y: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3f(location: WebGLUniformLocation | null, x: GLfloat, y: GLfloat, z: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3i(location: WebGLUniformLocation | null, x: GLint, y: GLint, z: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4f(location: WebGLUniformLocation | null, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4i(location: WebGLUniformLocation | null, x: GLint, y: GLint, z: GLint, w: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/useProgram) */\\n    useProgram(program: WebGLProgram | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/validateProgram) */\\n    validateProgram(program: WebGLProgram): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib1f(index: GLuint, x: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib1fv(index: GLuint, values: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib2f(index: GLuint, x: GLfloat, y: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib2fv(index: GLuint, values: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib3f(index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib3fv(index: GLuint, values: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib4f(index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib4fv(index: GLuint, values: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttribPointer) */\\n    vertexAttribPointer(index: GLuint, size: GLint, type: GLenum, normalized: GLboolean, stride: GLsizei, offset: GLintptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/viewport) */\\n    viewport(x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    readonly DEPTH_BUFFER_BIT: 0x00000100;\\n    readonly STENCIL_BUFFER_BIT: 0x00000400;\\n    readonly COLOR_BUFFER_BIT: 0x00004000;\\n    readonly POINTS: 0x0000;\\n    readonly LINES: 0x0001;\\n    readonly LINE_LOOP: 0x0002;\\n    readonly LINE_STRIP: 0x0003;\\n    readonly TRIANGLES: 0x0004;\\n    readonly TRIANGLE_STRIP: 0x0005;\\n    readonly TRIANGLE_FAN: 0x0006;\\n    readonly ZERO: 0;\\n    readonly ONE: 1;\\n    readonly SRC_COLOR: 0x0300;\\n    readonly ONE_MINUS_SRC_COLOR: 0x0301;\\n    readonly SRC_ALPHA: 0x0302;\\n    readonly ONE_MINUS_SRC_ALPHA: 0x0303;\\n    readonly DST_ALPHA: 0x0304;\\n    readonly ONE_MINUS_DST_ALPHA: 0x0305;\\n    readonly DST_COLOR: 0x0306;\\n    readonly ONE_MINUS_DST_COLOR: 0x0307;\\n    readonly SRC_ALPHA_SATURATE: 0x0308;\\n    readonly FUNC_ADD: 0x8006;\\n    readonly BLEND_EQUATION: 0x8009;\\n    readonly BLEND_EQUATION_RGB: 0x8009;\\n    readonly BLEND_EQUATION_ALPHA: 0x883D;\\n    readonly FUNC_SUBTRACT: 0x800A;\\n    readonly FUNC_REVERSE_SUBTRACT: 0x800B;\\n    readonly BLEND_DST_RGB: 0x80C8;\\n    readonly BLEND_SRC_RGB: 0x80C9;\\n    readonly BLEND_DST_ALPHA: 0x80CA;\\n    readonly BLEND_SRC_ALPHA: 0x80CB;\\n    readonly CONSTANT_COLOR: 0x8001;\\n    readonly ONE_MINUS_CONSTANT_COLOR: 0x8002;\\n    readonly CONSTANT_ALPHA: 0x8003;\\n    readonly ONE_MINUS_CONSTANT_ALPHA: 0x8004;\\n    readonly BLEND_COLOR: 0x8005;\\n    readonly ARRAY_BUFFER: 0x8892;\\n    readonly ELEMENT_ARRAY_BUFFER: 0x8893;\\n    readonly ARRAY_BUFFER_BINDING: 0x8894;\\n    readonly ELEMENT_ARRAY_BUFFER_BINDING: 0x8895;\\n    readonly STREAM_DRAW: 0x88E0;\\n    readonly STATIC_DRAW: 0x88E4;\\n    readonly DYNAMIC_DRAW: 0x88E8;\\n    readonly BUFFER_SIZE: 0x8764;\\n    readonly BUFFER_USAGE: 0x8765;\\n    readonly CURRENT_VERTEX_ATTRIB: 0x8626;\\n    readonly FRONT: 0x0404;\\n    readonly BACK: 0x0405;\\n    readonly FRONT_AND_BACK: 0x0408;\\n    readonly CULL_FACE: 0x0B44;\\n    readonly BLEND: 0x0BE2;\\n    readonly DITHER: 0x0BD0;\\n    readonly STENCIL_TEST: 0x0B90;\\n    readonly DEPTH_TEST: 0x0B71;\\n    readonly SCISSOR_TEST: 0x0C11;\\n    readonly POLYGON_OFFSET_FILL: 0x8037;\\n    readonly SAMPLE_ALPHA_TO_COVERAGE: 0x809E;\\n    readonly SAMPLE_COVERAGE: 0x80A0;\\n    readonly NO_ERROR: 0;\\n    readonly INVALID_ENUM: 0x0500;\\n    readonly INVALID_VALUE: 0x0501;\\n    readonly INVALID_OPERATION: 0x0502;\\n    readonly OUT_OF_MEMORY: 0x0505;\\n    readonly CW: 0x0900;\\n    readonly CCW: 0x0901;\\n    readonly LINE_WIDTH: 0x0B21;\\n    readonly ALIASED_POINT_SIZE_RANGE: 0x846D;\\n    readonly ALIASED_LINE_WIDTH_RANGE: 0x846E;\\n    readonly CULL_FACE_MODE: 0x0B45;\\n    readonly FRONT_FACE: 0x0B46;\\n    readonly DEPTH_RANGE: 0x0B70;\\n    readonly DEPTH_WRITEMASK: 0x0B72;\\n    readonly DEPTH_CLEAR_VALUE: 0x0B73;\\n    readonly DEPTH_FUNC: 0x0B74;\\n    readonly STENCIL_CLEAR_VALUE: 0x0B91;\\n    readonly STENCIL_FUNC: 0x0B92;\\n    readonly STENCIL_FAIL: 0x0B94;\\n    readonly STENCIL_PASS_DEPTH_FAIL: 0x0B95;\\n    readonly STENCIL_PASS_DEPTH_PASS: 0x0B96;\\n    readonly STENCIL_REF: 0x0B97;\\n    readonly STENCIL_VALUE_MASK: 0x0B93;\\n    readonly STENCIL_WRITEMASK: 0x0B98;\\n    readonly STENCIL_BACK_FUNC: 0x8800;\\n    readonly STENCIL_BACK_FAIL: 0x8801;\\n    readonly STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802;\\n    readonly STENCIL_BACK_PASS_DEPTH_PASS: 0x8803;\\n    readonly STENCIL_BACK_REF: 0x8CA3;\\n    readonly STENCIL_BACK_VALUE_MASK: 0x8CA4;\\n    readonly STENCIL_BACK_WRITEMASK: 0x8CA5;\\n    readonly VIEWPORT: 0x0BA2;\\n    readonly SCISSOR_BOX: 0x0C10;\\n    readonly COLOR_CLEAR_VALUE: 0x0C22;\\n    readonly COLOR_WRITEMASK: 0x0C23;\\n    readonly UNPACK_ALIGNMENT: 0x0CF5;\\n    readonly PACK_ALIGNMENT: 0x0D05;\\n    readonly MAX_TEXTURE_SIZE: 0x0D33;\\n    readonly MAX_VIEWPORT_DIMS: 0x0D3A;\\n    readonly SUBPIXEL_BITS: 0x0D50;\\n    readonly RED_BITS: 0x0D52;\\n    readonly GREEN_BITS: 0x0D53;\\n    readonly BLUE_BITS: 0x0D54;\\n    readonly ALPHA_BITS: 0x0D55;\\n    readonly DEPTH_BITS: 0x0D56;\\n    readonly STENCIL_BITS: 0x0D57;\\n    readonly POLYGON_OFFSET_UNITS: 0x2A00;\\n    readonly POLYGON_OFFSET_FACTOR: 0x8038;\\n    readonly TEXTURE_BINDING_2D: 0x8069;\\n    readonly SAMPLE_BUFFERS: 0x80A8;\\n    readonly SAMPLES: 0x80A9;\\n    readonly SAMPLE_COVERAGE_VALUE: 0x80AA;\\n    readonly SAMPLE_COVERAGE_INVERT: 0x80AB;\\n    readonly COMPRESSED_TEXTURE_FORMATS: 0x86A3;\\n    readonly DONT_CARE: 0x1100;\\n    readonly FASTEST: 0x1101;\\n    readonly NICEST: 0x1102;\\n    readonly GENERATE_MIPMAP_HINT: 0x8192;\\n    readonly BYTE: 0x1400;\\n    readonly UNSIGNED_BYTE: 0x1401;\\n    readonly SHORT: 0x1402;\\n    readonly UNSIGNED_SHORT: 0x1403;\\n    readonly INT: 0x1404;\\n    readonly UNSIGNED_INT: 0x1405;\\n    readonly FLOAT: 0x1406;\\n    readonly DEPTH_COMPONENT: 0x1902;\\n    readonly ALPHA: 0x1906;\\n    readonly RGB: 0x1907;\\n    readonly RGBA: 0x1908;\\n    readonly LUMINANCE: 0x1909;\\n    readonly LUMINANCE_ALPHA: 0x190A;\\n    readonly UNSIGNED_SHORT_4_4_4_4: 0x8033;\\n    readonly UNSIGNED_SHORT_5_5_5_1: 0x8034;\\n    readonly UNSIGNED_SHORT_5_6_5: 0x8363;\\n    readonly FRAGMENT_SHADER: 0x8B30;\\n    readonly VERTEX_SHADER: 0x8B31;\\n    readonly MAX_VERTEX_ATTRIBS: 0x8869;\\n    readonly MAX_VERTEX_UNIFORM_VECTORS: 0x8DFB;\\n    readonly MAX_VARYING_VECTORS: 0x8DFC;\\n    readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8B4D;\\n    readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8B4C;\\n    readonly MAX_TEXTURE_IMAGE_UNITS: 0x8872;\\n    readonly MAX_FRAGMENT_UNIFORM_VECTORS: 0x8DFD;\\n    readonly SHADER_TYPE: 0x8B4F;\\n    readonly DELETE_STATUS: 0x8B80;\\n    readonly LINK_STATUS: 0x8B82;\\n    readonly VALIDATE_STATUS: 0x8B83;\\n    readonly ATTACHED_SHADERS: 0x8B85;\\n    readonly ACTIVE_UNIFORMS: 0x8B86;\\n    readonly ACTIVE_ATTRIBUTES: 0x8B89;\\n    readonly SHADING_LANGUAGE_VERSION: 0x8B8C;\\n    readonly CURRENT_PROGRAM: 0x8B8D;\\n    readonly NEVER: 0x0200;\\n    readonly LESS: 0x0201;\\n    readonly EQUAL: 0x0202;\\n    readonly LEQUAL: 0x0203;\\n    readonly GREATER: 0x0204;\\n    readonly NOTEQUAL: 0x0205;\\n    readonly GEQUAL: 0x0206;\\n    readonly ALWAYS: 0x0207;\\n    readonly KEEP: 0x1E00;\\n    readonly REPLACE: 0x1E01;\\n    readonly INCR: 0x1E02;\\n    readonly DECR: 0x1E03;\\n    readonly INVERT: 0x150A;\\n    readonly INCR_WRAP: 0x8507;\\n    readonly DECR_WRAP: 0x8508;\\n    readonly VENDOR: 0x1F00;\\n    readonly RENDERER: 0x1F01;\\n    readonly VERSION: 0x1F02;\\n    readonly NEAREST: 0x2600;\\n    readonly LINEAR: 0x2601;\\n    readonly NEAREST_MIPMAP_NEAREST: 0x2700;\\n    readonly LINEAR_MIPMAP_NEAREST: 0x2701;\\n    readonly NEAREST_MIPMAP_LINEAR: 0x2702;\\n    readonly LINEAR_MIPMAP_LINEAR: 0x2703;\\n    readonly TEXTURE_MAG_FILTER: 0x2800;\\n    readonly TEXTURE_MIN_FILTER: 0x2801;\\n    readonly TEXTURE_WRAP_S: 0x2802;\\n    readonly TEXTURE_WRAP_T: 0x2803;\\n    readonly TEXTURE_2D: 0x0DE1;\\n    readonly TEXTURE: 0x1702;\\n    readonly TEXTURE_CUBE_MAP: 0x8513;\\n    readonly TEXTURE_BINDING_CUBE_MAP: 0x8514;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851A;\\n    readonly MAX_CUBE_MAP_TEXTURE_SIZE: 0x851C;\\n    readonly TEXTURE0: 0x84C0;\\n    readonly TEXTURE1: 0x84C1;\\n    readonly TEXTURE2: 0x84C2;\\n    readonly TEXTURE3: 0x84C3;\\n    readonly TEXTURE4: 0x84C4;\\n    readonly TEXTURE5: 0x84C5;\\n    readonly TEXTURE6: 0x84C6;\\n    readonly TEXTURE7: 0x84C7;\\n    readonly TEXTURE8: 0x84C8;\\n    readonly TEXTURE9: 0x84C9;\\n    readonly TEXTURE10: 0x84CA;\\n    readonly TEXTURE11: 0x84CB;\\n    readonly TEXTURE12: 0x84CC;\\n    readonly TEXTURE13: 0x84CD;\\n    readonly TEXTURE14: 0x84CE;\\n    readonly TEXTURE15: 0x84CF;\\n    readonly TEXTURE16: 0x84D0;\\n    readonly TEXTURE17: 0x84D1;\\n    readonly TEXTURE18: 0x84D2;\\n    readonly TEXTURE19: 0x84D3;\\n    readonly TEXTURE20: 0x84D4;\\n    readonly TEXTURE21: 0x84D5;\\n    readonly TEXTURE22: 0x84D6;\\n    readonly TEXTURE23: 0x84D7;\\n    readonly TEXTURE24: 0x84D8;\\n    readonly TEXTURE25: 0x84D9;\\n    readonly TEXTURE26: 0x84DA;\\n    readonly TEXTURE27: 0x84DB;\\n    readonly TEXTURE28: 0x84DC;\\n    readonly TEXTURE29: 0x84DD;\\n    readonly TEXTURE30: 0x84DE;\\n    readonly TEXTURE31: 0x84DF;\\n    readonly ACTIVE_TEXTURE: 0x84E0;\\n    readonly REPEAT: 0x2901;\\n    readonly CLAMP_TO_EDGE: 0x812F;\\n    readonly MIRRORED_REPEAT: 0x8370;\\n    readonly FLOAT_VEC2: 0x8B50;\\n    readonly FLOAT_VEC3: 0x8B51;\\n    readonly FLOAT_VEC4: 0x8B52;\\n    readonly INT_VEC2: 0x8B53;\\n    readonly INT_VEC3: 0x8B54;\\n    readonly INT_VEC4: 0x8B55;\\n    readonly BOOL: 0x8B56;\\n    readonly BOOL_VEC2: 0x8B57;\\n    readonly BOOL_VEC3: 0x8B58;\\n    readonly BOOL_VEC4: 0x8B59;\\n    readonly FLOAT_MAT2: 0x8B5A;\\n    readonly FLOAT_MAT3: 0x8B5B;\\n    readonly FLOAT_MAT4: 0x8B5C;\\n    readonly SAMPLER_2D: 0x8B5E;\\n    readonly SAMPLER_CUBE: 0x8B60;\\n    readonly VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622;\\n    readonly VERTEX_ATTRIB_ARRAY_SIZE: 0x8623;\\n    readonly VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624;\\n    readonly VERTEX_ATTRIB_ARRAY_TYPE: 0x8625;\\n    readonly VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886A;\\n    readonly VERTEX_ATTRIB_ARRAY_POINTER: 0x8645;\\n    readonly VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889F;\\n    readonly IMPLEMENTATION_COLOR_READ_TYPE: 0x8B9A;\\n    readonly IMPLEMENTATION_COLOR_READ_FORMAT: 0x8B9B;\\n    readonly COMPILE_STATUS: 0x8B81;\\n    readonly LOW_FLOAT: 0x8DF0;\\n    readonly MEDIUM_FLOAT: 0x8DF1;\\n    readonly HIGH_FLOAT: 0x8DF2;\\n    readonly LOW_INT: 0x8DF3;\\n    readonly MEDIUM_INT: 0x8DF4;\\n    readonly HIGH_INT: 0x8DF5;\\n    readonly FRAMEBUFFER: 0x8D40;\\n    readonly RENDERBUFFER: 0x8D41;\\n    readonly RGBA4: 0x8056;\\n    readonly RGB5_A1: 0x8057;\\n    readonly RGB565: 0x8D62;\\n    readonly DEPTH_COMPONENT16: 0x81A5;\\n    readonly STENCIL_INDEX8: 0x8D48;\\n    readonly DEPTH_STENCIL: 0x84F9;\\n    readonly RENDERBUFFER_WIDTH: 0x8D42;\\n    readonly RENDERBUFFER_HEIGHT: 0x8D43;\\n    readonly RENDERBUFFER_INTERNAL_FORMAT: 0x8D44;\\n    readonly RENDERBUFFER_RED_SIZE: 0x8D50;\\n    readonly RENDERBUFFER_GREEN_SIZE: 0x8D51;\\n    readonly RENDERBUFFER_BLUE_SIZE: 0x8D52;\\n    readonly RENDERBUFFER_ALPHA_SIZE: 0x8D53;\\n    readonly RENDERBUFFER_DEPTH_SIZE: 0x8D54;\\n    readonly RENDERBUFFER_STENCIL_SIZE: 0x8D55;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8CD0;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8CD1;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8CD2;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8CD3;\\n    readonly COLOR_ATTACHMENT0: 0x8CE0;\\n    readonly DEPTH_ATTACHMENT: 0x8D00;\\n    readonly STENCIL_ATTACHMENT: 0x8D20;\\n    readonly DEPTH_STENCIL_ATTACHMENT: 0x821A;\\n    readonly NONE: 0;\\n    readonly FRAMEBUFFER_COMPLETE: 0x8CD5;\\n    readonly FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8CD6;\\n    readonly FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8CD7;\\n    readonly FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8CD9;\\n    readonly FRAMEBUFFER_UNSUPPORTED: 0x8CDD;\\n    readonly FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly RENDERBUFFER_BINDING: 0x8CA7;\\n    readonly MAX_RENDERBUFFER_SIZE: 0x84E8;\\n    readonly INVALID_FRAMEBUFFER_OPERATION: 0x0506;\\n    readonly UNPACK_FLIP_Y_WEBGL: 0x9240;\\n    readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241;\\n    readonly CONTEXT_LOST_WEBGL: 0x9242;\\n    readonly UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243;\\n    readonly BROWSER_DEFAULT_WEBGL: 0x9244;\\n}\\n\\ninterface WebGLRenderingContextOverloads {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bufferData) */\\n    bufferData(target: GLenum, size: GLsizeiptr, usage: GLenum): void;\\n    bufferData(target: GLenum, data: BufferSource | null, usage: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bufferSubData) */\\n    bufferSubData(target: GLenum, offset: GLintptr, data: BufferSource): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compressedTexImage2D) */\\n    compressedTexImage2D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, data: ArrayBufferView): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compressedTexSubImage2D) */\\n    compressedTexSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, data: ArrayBufferView): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/readPixels) */\\n    readPixels(x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texImage2D) */\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texSubImage2D) */\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1fv(location: WebGLUniformLocation | null, v: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1iv(location: WebGLUniformLocation | null, v: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2fv(location: WebGLUniformLocation | null, v: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2iv(location: WebGLUniformLocation | null, v: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3fv(location: WebGLUniformLocation | null, v: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3iv(location: WebGLUniformLocation | null, v: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4fv(location: WebGLUniformLocation | null, v: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4iv(location: WebGLUniformLocation | null, v: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Float32List): void;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLSampler) */\\ninterface WebGLSampler {\\n}\\n\\ndeclare var WebGLSampler: {\\n    prototype: WebGLSampler;\\n    new(): WebGLSampler;\\n};\\n\\n/**\\n * The WebGLShader is part of the WebGL API and can either be a vertex or a fragment shader. A WebGLProgram requires both types of shaders.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShader)\\n */\\ninterface WebGLShader {\\n}\\n\\ndeclare var WebGLShader: {\\n    prototype: WebGLShader;\\n    new(): WebGLShader;\\n};\\n\\n/**\\n * Part of the WebGL API and represents the information returned by calling the WebGLRenderingContext.getShaderPrecisionFormat() method.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShaderPrecisionFormat)\\n */\\ninterface WebGLShaderPrecisionFormat {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShaderPrecisionFormat/precision) */\\n    readonly precision: GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShaderPrecisionFormat/rangeMax) */\\n    readonly rangeMax: GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShaderPrecisionFormat/rangeMin) */\\n    readonly rangeMin: GLint;\\n}\\n\\ndeclare var WebGLShaderPrecisionFormat: {\\n    prototype: WebGLShaderPrecisionFormat;\\n    new(): WebGLShaderPrecisionFormat;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLSync) */\\ninterface WebGLSync {\\n}\\n\\ndeclare var WebGLSync: {\\n    prototype: WebGLSync;\\n    new(): WebGLSync;\\n};\\n\\n/**\\n * Part of the WebGL API and represents an opaque texture object providing storage and state for texturing operations.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLTexture)\\n */\\ninterface WebGLTexture {\\n}\\n\\ndeclare var WebGLTexture: {\\n    prototype: WebGLTexture;\\n    new(): WebGLTexture;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLTransformFeedback) */\\ninterface WebGLTransformFeedback {\\n}\\n\\ndeclare var WebGLTransformFeedback: {\\n    prototype: WebGLTransformFeedback;\\n    new(): WebGLTransformFeedback;\\n};\\n\\n/**\\n * Part of the WebGL API and represents the location of a uniform variable in a shader program.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLUniformLocation)\\n */\\ninterface WebGLUniformLocation {\\n}\\n\\ndeclare var WebGLUniformLocation: {\\n    prototype: WebGLUniformLocation;\\n    new(): WebGLUniformLocation;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLVertexArrayObject) */\\ninterface WebGLVertexArrayObject {\\n}\\n\\ndeclare var WebGLVertexArrayObject: {\\n    prototype: WebGLVertexArrayObject;\\n    new(): WebGLVertexArrayObject;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLVertexArrayObjectOES) */\\ninterface WebGLVertexArrayObjectOES {\\n}\\n\\ninterface WebSocketEventMap {\\n    \\\"close\\\": CloseEvent;\\n    \\\"error\\\": Event;\\n    \\\"message\\\": MessageEvent;\\n    \\\"open\\\": Event;\\n}\\n\\n/**\\n * Provides the API for creating and managing a WebSocket connection to a server, as well as for sending and receiving data on the connection.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket)\\n */\\ninterface WebSocket extends EventTarget {\\n    /**\\n     * Returns a string that indicates how binary data from the WebSocket object is exposed to scripts:\\n     *\\n     * Can be set, to change how binary data is returned. The default is \\\"blob\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/binaryType)\\n     */\\n    binaryType: BinaryType;\\n    /**\\n     * Returns the number of bytes of application data (UTF-8 text and binary data) that have been queued using send() but not yet been transmitted to the network.\\n     *\\n     * If the WebSocket connection is closed, this attribute's value will only increase with each call to the send() method. (The number does not reset to zero once the connection closes.)\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/bufferedAmount)\\n     */\\n    readonly bufferedAmount: number;\\n    /**\\n     * Returns the extensions selected by the server, if any.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/extensions)\\n     */\\n    readonly extensions: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/close_event) */\\n    onclose: ((this: WebSocket, ev: CloseEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/error_event) */\\n    onerror: ((this: WebSocket, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/message_event) */\\n    onmessage: ((this: WebSocket, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/open_event) */\\n    onopen: ((this: WebSocket, ev: Event) => any) | null;\\n    /**\\n     * Returns the subprotocol selected by the server, if any. It can be used in conjunction with the array form of the constructor's second argument to perform subprotocol negotiation.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/protocol)\\n     */\\n    readonly protocol: string;\\n    /**\\n     * Returns the state of the WebSocket object's connection. It can have the values described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/readyState)\\n     */\\n    readonly readyState: number;\\n    /**\\n     * Returns the URL that was used to establish the WebSocket connection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/url)\\n     */\\n    readonly url: string;\\n    /**\\n     * Closes the WebSocket connection, optionally using code as the the WebSocket connection close code and reason as the the WebSocket connection close reason.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/close)\\n     */\\n    close(code?: number, reason?: string): void;\\n    /**\\n     * Transmits data using the WebSocket connection. data can be a string, a Blob, an ArrayBuffer, or an ArrayBufferView.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/send)\\n     */\\n    send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;\\n    readonly CONNECTING: 0;\\n    readonly OPEN: 1;\\n    readonly CLOSING: 2;\\n    readonly CLOSED: 3;\\n    addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var WebSocket: {\\n    prototype: WebSocket;\\n    new(url: string | URL, protocols?: string | string[]): WebSocket;\\n    readonly CONNECTING: 0;\\n    readonly OPEN: 1;\\n    readonly CLOSING: 2;\\n    readonly CLOSED: 3;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport)\\n */\\ninterface WebTransport {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/closed) */\\n    readonly closed: Promise<WebTransportCloseInfo>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/datagrams) */\\n    readonly datagrams: WebTransportDatagramDuplexStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/incomingBidirectionalStreams) */\\n    readonly incomingBidirectionalStreams: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/incomingUnidirectionalStreams) */\\n    readonly incomingUnidirectionalStreams: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/ready) */\\n    readonly ready: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/close) */\\n    close(closeInfo?: WebTransportCloseInfo): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/createBidirectionalStream) */\\n    createBidirectionalStream(options?: WebTransportSendStreamOptions): Promise<WebTransportBidirectionalStream>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/createUnidirectionalStream) */\\n    createUnidirectionalStream(options?: WebTransportSendStreamOptions): Promise<WritableStream>;\\n}\\n\\ndeclare var WebTransport: {\\n    prototype: WebTransport;\\n    new(url: string | URL, options?: WebTransportOptions): WebTransport;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream)\\n */\\ninterface WebTransportBidirectionalStream {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream/readable) */\\n    readonly readable: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream/writable) */\\n    readonly writable: WritableStream;\\n}\\n\\ndeclare var WebTransportBidirectionalStream: {\\n    prototype: WebTransportBidirectionalStream;\\n    new(): WebTransportBidirectionalStream;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream)\\n */\\ninterface WebTransportDatagramDuplexStream {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/incomingHighWaterMark) */\\n    incomingHighWaterMark: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/incomingMaxAge) */\\n    incomingMaxAge: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/maxDatagramSize) */\\n    readonly maxDatagramSize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/outgoingHighWaterMark) */\\n    outgoingHighWaterMark: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/outgoingMaxAge) */\\n    outgoingMaxAge: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/readable) */\\n    readonly readable: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/writable) */\\n    readonly writable: WritableStream;\\n}\\n\\ndeclare var WebTransportDatagramDuplexStream: {\\n    prototype: WebTransportDatagramDuplexStream;\\n    new(): WebTransportDatagramDuplexStream;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError)\\n */\\ninterface WebTransportError extends DOMException {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError/source) */\\n    readonly source: WebTransportErrorSource;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError/streamErrorCode) */\\n    readonly streamErrorCode: number | null;\\n}\\n\\ndeclare var WebTransportError: {\\n    prototype: WebTransportError;\\n    new(message?: string, options?: WebTransportErrorOptions): WebTransportError;\\n};\\n\\n/**\\n * Events that occur due to the user moving a mouse wheel or similar input device.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WheelEvent)\\n */\\ninterface WheelEvent extends MouseEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WheelEvent/deltaMode) */\\n    readonly deltaMode: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WheelEvent/deltaX) */\\n    readonly deltaX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WheelEvent/deltaY) */\\n    readonly deltaY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WheelEvent/deltaZ) */\\n    readonly deltaZ: number;\\n    readonly DOM_DELTA_PIXEL: 0x00;\\n    readonly DOM_DELTA_LINE: 0x01;\\n    readonly DOM_DELTA_PAGE: 0x02;\\n}\\n\\ndeclare var WheelEvent: {\\n    prototype: WheelEvent;\\n    new(type: string, eventInitDict?: WheelEventInit): WheelEvent;\\n    readonly DOM_DELTA_PIXEL: 0x00;\\n    readonly DOM_DELTA_LINE: 0x01;\\n    readonly DOM_DELTA_PAGE: 0x02;\\n};\\n\\ninterface WindowEventMap extends GlobalEventHandlersEventMap, WindowEventHandlersEventMap {\\n    \\\"DOMContentLoaded\\\": Event;\\n    \\\"devicemotion\\\": DeviceMotionEvent;\\n    \\\"deviceorientation\\\": DeviceOrientationEvent;\\n    \\\"gamepadconnected\\\": GamepadEvent;\\n    \\\"gamepaddisconnected\\\": GamepadEvent;\\n    \\\"orientationchange\\\": Event;\\n}\\n\\n/**\\n * A window containing a DOM document; the document property points to the DOM document loaded in that window.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window)\\n */\\ninterface Window extends EventTarget, AnimationFrameProvider, GlobalEventHandlers, WindowEventHandlers, WindowLocalStorage, WindowOrWorkerGlobalScope, WindowSessionStorage {\\n    /**\\n     * @deprecated This is a legacy alias of `navigator`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/navigator)\\n     */\\n    readonly clientInformation: Navigator;\\n    /**\\n     * Returns true if the window has been closed, false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/closed)\\n     */\\n    readonly closed: boolean;\\n    /**\\n     * Defines a new custom element, mapping the given name to the given constructor as an autonomous custom element.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/customElements)\\n     */\\n    readonly customElements: CustomElementRegistry;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/devicePixelRatio) */\\n    readonly devicePixelRatio: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/document) */\\n    readonly document: Document;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/event)\\n     */\\n    readonly event: Event | undefined;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/external)\\n     */\\n    readonly external: External;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/frameElement) */\\n    readonly frameElement: Element | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/frames) */\\n    readonly frames: WindowProxy;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/history) */\\n    readonly history: History;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/innerHeight) */\\n    readonly innerHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/innerWidth) */\\n    readonly innerWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/location) */\\n    get location(): Location;\\n    set location(href: string | Location);\\n    /**\\n     * Returns true if the location bar is visible; otherwise, returns false.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/locationbar)\\n     */\\n    readonly locationbar: BarProp;\\n    /**\\n     * Returns true if the menu bar is visible; otherwise, returns false.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/menubar)\\n     */\\n    readonly menubar: BarProp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/name) */\\n    name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/navigator) */\\n    readonly navigator: Navigator;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/devicemotion_event)\\n     */\\n    ondevicemotion: ((this: Window, ev: DeviceMotionEvent) => any) | null;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/deviceorientation_event)\\n     */\\n    ondeviceorientation: ((this: Window, ev: DeviceOrientationEvent) => any) | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/orientationchange_event)\\n     */\\n    onorientationchange: ((this: Window, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/opener) */\\n    opener: any;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/orientation)\\n     */\\n    readonly orientation: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/outerHeight) */\\n    readonly outerHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/outerWidth) */\\n    readonly outerWidth: number;\\n    /**\\n     * @deprecated This is a legacy alias of `scrollX`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollX)\\n     */\\n    readonly pageXOffset: number;\\n    /**\\n     * @deprecated This is a legacy alias of `scrollY`.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollY)\\n     */\\n    readonly pageYOffset: number;\\n    /**\\n     * Refers to either the parent WindowProxy, or itself.\\n     *\\n     * It can rarely be null e.g. for contentWindow of an iframe that is already removed from the parent.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/parent)\\n     */\\n    readonly parent: WindowProxy;\\n    /**\\n     * Returns true if the personal bar is visible; otherwise, returns false.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/personalbar)\\n     */\\n    readonly personalbar: BarProp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screen) */\\n    readonly screen: Screen;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screenLeft) */\\n    readonly screenLeft: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screenTop) */\\n    readonly screenTop: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screenX) */\\n    readonly screenX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screenY) */\\n    readonly screenY: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollX) */\\n    readonly scrollX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollY) */\\n    readonly scrollY: number;\\n    /**\\n     * Returns true if the scrollbars are visible; otherwise, returns false.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollbars)\\n     */\\n    readonly scrollbars: BarProp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/self) */\\n    readonly self: Window & typeof globalThis;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/speechSynthesis) */\\n    readonly speechSynthesis: SpeechSynthesis;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/status)\\n     */\\n    status: string;\\n    /**\\n     * Returns true if the status bar is visible; otherwise, returns false.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/statusbar)\\n     */\\n    readonly statusbar: BarProp;\\n    /**\\n     * Returns true if the toolbar is visible; otherwise, returns false.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/toolbar)\\n     */\\n    readonly toolbar: BarProp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/top) */\\n    readonly top: WindowProxy | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/visualViewport) */\\n    readonly visualViewport: VisualViewport | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/window) */\\n    readonly window: Window & typeof globalThis;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/alert) */\\n    alert(message?: any): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/blur) */\\n    blur(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/cancelIdleCallback) */\\n    cancelIdleCallback(handle: number): void;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/captureEvents)\\n     */\\n    captureEvents(): void;\\n    /**\\n     * Closes the window.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/close)\\n     */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/confirm) */\\n    confirm(message?: string): boolean;\\n    /**\\n     * Moves the focus to the window's browsing context, if any.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/focus)\\n     */\\n    focus(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/getComputedStyle) */\\n    getComputedStyle(elt: Element, pseudoElt?: string | null): CSSStyleDeclaration;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/getSelection) */\\n    getSelection(): Selection | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/matchMedia) */\\n    matchMedia(query: string): MediaQueryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/moveBy) */\\n    moveBy(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/moveTo) */\\n    moveTo(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/open) */\\n    open(url?: string | URL, target?: string, features?: string): WindowProxy | null;\\n    /**\\n     * Posts a message to the given window. Messages can be structured objects, e.g. nested objects and arrays, can contain JavaScript values (strings, numbers, Date objects, etc), and can contain certain data objects such as File Blob, FileList, and ArrayBuffer objects.\\n     *\\n     * Objects listed in the transfer member of options are transferred, not just cloned, meaning that they are no longer usable on the sending side.\\n     *\\n     * A target origin can be specified using the targetOrigin member of options. If not provided, it defaults to \\\"/\\\". This default restricts the message to same-origin targets only.\\n     *\\n     * If the origin of the target window doesn't match the given target origin, the message is discarded, to avoid information leakage. To send the message to the target regardless of origin, set the target origin to \\\"*\\\".\\n     *\\n     * Throws a \\\"DataCloneError\\\" DOMException if transfer array contains duplicate objects or if message could not be cloned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/postMessage)\\n     */\\n    postMessage(message: any, targetOrigin: string, transfer?: Transferable[]): void;\\n    postMessage(message: any, options?: WindowPostMessageOptions): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/print) */\\n    print(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/prompt) */\\n    prompt(message?: string, _default?: string): string | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/releaseEvents)\\n     */\\n    releaseEvents(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/requestIdleCallback) */\\n    requestIdleCallback(callback: IdleRequestCallback, options?: IdleRequestOptions): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/resizeBy) */\\n    resizeBy(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/resizeTo) */\\n    resizeTo(width: number, height: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scroll) */\\n    scroll(options?: ScrollToOptions): void;\\n    scroll(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollBy) */\\n    scrollBy(options?: ScrollToOptions): void;\\n    scrollBy(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollTo) */\\n    scrollTo(options?: ScrollToOptions): void;\\n    scrollTo(x: number, y: number): void;\\n    /**\\n     * Cancels the document load.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/stop)\\n     */\\n    stop(): void;\\n    addEventListener<K extends keyof WindowEventMap>(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof WindowEventMap>(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n    [index: number]: Window;\\n}\\n\\ndeclare var Window: {\\n    prototype: Window;\\n    new(): Window;\\n};\\n\\ninterface WindowEventHandlersEventMap {\\n    \\\"afterprint\\\": Event;\\n    \\\"beforeprint\\\": Event;\\n    \\\"beforeunload\\\": BeforeUnloadEvent;\\n    \\\"gamepadconnected\\\": GamepadEvent;\\n    \\\"gamepaddisconnected\\\": GamepadEvent;\\n    \\\"hashchange\\\": HashChangeEvent;\\n    \\\"languagechange\\\": Event;\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n    \\\"offline\\\": Event;\\n    \\\"online\\\": Event;\\n    \\\"pagehide\\\": PageTransitionEvent;\\n    \\\"pageshow\\\": PageTransitionEvent;\\n    \\\"popstate\\\": PopStateEvent;\\n    \\\"rejectionhandled\\\": PromiseRejectionEvent;\\n    \\\"storage\\\": StorageEvent;\\n    \\\"unhandledrejection\\\": PromiseRejectionEvent;\\n    \\\"unload\\\": Event;\\n}\\n\\ninterface WindowEventHandlers {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/afterprint_event) */\\n    onafterprint: ((this: WindowEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/beforeprint_event) */\\n    onbeforeprint: ((this: WindowEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/beforeunload_event) */\\n    onbeforeunload: ((this: WindowEventHandlers, ev: BeforeUnloadEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/gamepadconnected_event) */\\n    ongamepadconnected: ((this: WindowEventHandlers, ev: GamepadEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/gamepaddisconnected_event) */\\n    ongamepaddisconnected: ((this: WindowEventHandlers, ev: GamepadEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/hashchange_event) */\\n    onhashchange: ((this: WindowEventHandlers, ev: HashChangeEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/languagechange_event) */\\n    onlanguagechange: ((this: WindowEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/message_event) */\\n    onmessage: ((this: WindowEventHandlers, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/messageerror_event) */\\n    onmessageerror: ((this: WindowEventHandlers, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/offline_event) */\\n    onoffline: ((this: WindowEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/online_event) */\\n    ononline: ((this: WindowEventHandlers, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/pagehide_event) */\\n    onpagehide: ((this: WindowEventHandlers, ev: PageTransitionEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/pageshow_event) */\\n    onpageshow: ((this: WindowEventHandlers, ev: PageTransitionEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) */\\n    onpopstate: ((this: WindowEventHandlers, ev: PopStateEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/rejectionhandled_event) */\\n    onrejectionhandled: ((this: WindowEventHandlers, ev: PromiseRejectionEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/storage_event) */\\n    onstorage: ((this: WindowEventHandlers, ev: StorageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/unhandledrejection_event) */\\n    onunhandledrejection: ((this: WindowEventHandlers, ev: PromiseRejectionEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/unload_event) */\\n    onunload: ((this: WindowEventHandlers, ev: Event) => any) | null;\\n    addEventListener<K extends keyof WindowEventHandlersEventMap>(type: K, listener: (this: WindowEventHandlers, ev: WindowEventHandlersEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof WindowEventHandlersEventMap>(type: K, listener: (this: WindowEventHandlers, ev: WindowEventHandlersEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ninterface WindowLocalStorage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/localStorage) */\\n    readonly localStorage: Storage;\\n}\\n\\ninterface WindowOrWorkerGlobalScope {\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/caches)\\n     */\\n    readonly caches: CacheStorage;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/crossOriginIsolated) */\\n    readonly crossOriginIsolated: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/crypto_property) */\\n    readonly crypto: Crypto;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/indexedDB) */\\n    readonly indexedDB: IDBFactory;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/isSecureContext) */\\n    readonly isSecureContext: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/origin) */\\n    readonly origin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/performance_property) */\\n    readonly performance: Performance;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/atob) */\\n    atob(data: string): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/btoa) */\\n    btoa(data: string): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/clearInterval) */\\n    clearInterval(id: number | undefined): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/clearTimeout) */\\n    clearTimeout(id: number | undefined): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/createImageBitmap) */\\n    createImageBitmap(image: ImageBitmapSource, options?: ImageBitmapOptions): Promise<ImageBitmap>;\\n    createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/fetch) */\\n    fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/queueMicrotask) */\\n    queueMicrotask(callback: VoidFunction): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/reportError) */\\n    reportError(e: any): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/setInterval) */\\n    setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/setTimeout) */\\n    setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/structuredClone) */\\n    structuredClone<T = any>(value: T, options?: StructuredSerializeOptions): T;\\n}\\n\\ninterface WindowSessionStorage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage) */\\n    readonly sessionStorage: Storage;\\n}\\n\\ninterface WorkerEventMap extends AbstractWorkerEventMap {\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/**\\n * This Web Workers API interface represents a background task that can be easily created and can send messages back to its creator. Creating a worker is as simple as calling the Worker() constructor and specifying a script to be run in the worker thread.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker)\\n */\\ninterface Worker extends EventTarget, AbstractWorker {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/message_event) */\\n    onmessage: ((this: Worker, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/messageerror_event) */\\n    onmessageerror: ((this: Worker, ev: MessageEvent) => any) | null;\\n    /**\\n     * Clones message and transmits it to worker's global environment. transfer can be passed as a list of objects that are to be transferred rather than cloned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/postMessage)\\n     */\\n    postMessage(message: any, transfer: Transferable[]): void;\\n    postMessage(message: any, options?: StructuredSerializeOptions): void;\\n    /**\\n     * Aborts worker's associated global environment.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/terminate)\\n     */\\n    terminate(): void;\\n    addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Worker: {\\n    prototype: Worker;\\n    new(scriptURL: string | URL, options?: WorkerOptions): Worker;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worklet)\\n */\\ninterface Worklet {\\n    /**\\n     * Loads and executes the module script given by moduleURL into all of worklet's global scopes. It can also create additional global scopes as part of this process, depending on the worklet type. The returned promise will fulfill once the script has been successfully loaded and run in all global scopes.\\n     *\\n     * The credentials option can be set to a credentials mode to modify the script-fetching process. It defaults to \\\"same-origin\\\".\\n     *\\n     * Any failures in fetching the script or its dependencies will cause the returned promise to be rejected with an \\\"AbortError\\\" DOMException. Any errors in parsing the script or its dependencies will cause the returned promise to be rejected with the exception generated during parsing.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worklet/addModule)\\n     */\\n    addModule(moduleURL: string | URL, options?: WorkletOptions): Promise<void>;\\n}\\n\\ndeclare var Worklet: {\\n    prototype: Worklet;\\n    new(): Worklet;\\n};\\n\\n/**\\n * This Streams API interface provides a standard abstraction for writing streaming data to a destination, known as a sink. This object comes with built-in backpressure and queuing.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream)\\n */\\ninterface WritableStream<W = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream/locked) */\\n    readonly locked: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream/abort) */\\n    abort(reason?: any): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream/close) */\\n    close(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream/getWriter) */\\n    getWriter(): WritableStreamDefaultWriter<W>;\\n}\\n\\ndeclare var WritableStream: {\\n    prototype: WritableStream;\\n    new<W = any>(underlyingSink?: UnderlyingSink<W>, strategy?: QueuingStrategy<W>): WritableStream<W>;\\n};\\n\\n/**\\n * This Streams API interface represents a controller allowing control of a WritableStream's state. When constructing a WritableStream, the underlying sink is given a corresponding WritableStreamDefaultController instance to manipulate.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultController)\\n */\\ninterface WritableStreamDefaultController {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultController/signal) */\\n    readonly signal: AbortSignal;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultController/error) */\\n    error(e?: any): void;\\n}\\n\\ndeclare var WritableStreamDefaultController: {\\n    prototype: WritableStreamDefaultController;\\n    new(): WritableStreamDefaultController;\\n};\\n\\n/**\\n * This Streams API interface is the object returned by WritableStream.getWriter() and once created locks the < writer to the WritableStream ensuring that no other streams can write to the underlying sink.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter)\\n */\\ninterface WritableStreamDefaultWriter<W = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/closed) */\\n    readonly closed: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/desiredSize) */\\n    readonly desiredSize: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/ready) */\\n    readonly ready: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/abort) */\\n    abort(reason?: any): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/close) */\\n    close(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/releaseLock) */\\n    releaseLock(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/write) */\\n    write(chunk?: W): Promise<void>;\\n}\\n\\ndeclare var WritableStreamDefaultWriter: {\\n    prototype: WritableStreamDefaultWriter;\\n    new<W = any>(stream: WritableStream<W>): WritableStreamDefaultWriter<W>;\\n};\\n\\n/**\\n * An XML document. It inherits from the generic Document and does not add any specific methods or properties to it: nevertheless, several algorithms behave differently with the two types of documents.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLDocument)\\n */\\ninterface XMLDocument extends Document {\\n    addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: XMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: XMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var XMLDocument: {\\n    prototype: XMLDocument;\\n    new(): XMLDocument;\\n};\\n\\ninterface XMLHttpRequestEventMap extends XMLHttpRequestEventTargetEventMap {\\n    \\\"readystatechange\\\": Event;\\n}\\n\\n/**\\n * Use XMLHttpRequest (XHR) objects to interact with servers. You can retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest)\\n */\\ninterface XMLHttpRequest extends XMLHttpRequestEventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/readystatechange_event) */\\n    onreadystatechange: ((this: XMLHttpRequest, ev: Event) => any) | null;\\n    /**\\n     * Returns client's state.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/readyState)\\n     */\\n    readonly readyState: number;\\n    /**\\n     * Returns the response body.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/response)\\n     */\\n    readonly response: any;\\n    /**\\n     * Returns response as text.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if responseType is not the empty string or \\\"text\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseText)\\n     */\\n    readonly responseText: string;\\n    /**\\n     * Returns the response type.\\n     *\\n     * Can be set to change the response type. Values are: the empty string (default), \\\"arraybuffer\\\", \\\"blob\\\", \\\"document\\\", \\\"json\\\", and \\\"text\\\".\\n     *\\n     * When set: setting to \\\"document\\\" is ignored if current global object is not a Window object.\\n     *\\n     * When set: throws an \\\"InvalidStateError\\\" DOMException if state is loading or done.\\n     *\\n     * When set: throws an \\\"InvalidAccessError\\\" DOMException if the synchronous flag is set and current global object is a Window object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseType)\\n     */\\n    responseType: XMLHttpRequestResponseType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseURL) */\\n    readonly responseURL: string;\\n    /**\\n     * Returns the response as document.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if responseType is not the empty string or \\\"document\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseXML)\\n     */\\n    readonly responseXML: Document | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/status) */\\n    readonly status: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/statusText) */\\n    readonly statusText: string;\\n    /**\\n     * Can be set to a time in milliseconds. When set to a non-zero value will cause fetching to terminate after the given time has passed. When the time has passed, the request has not yet completed, and this's synchronous flag is unset, a timeout event will then be dispatched, or a \\\"TimeoutError\\\" DOMException will be thrown otherwise (for the send() method).\\n     *\\n     * When set: throws an \\\"InvalidAccessError\\\" DOMException if the synchronous flag is set and current global object is a Window object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/timeout)\\n     */\\n    timeout: number;\\n    /**\\n     * Returns the associated XMLHttpRequestUpload object. It can be used to gather transmission information when data is transferred to a server.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/upload)\\n     */\\n    readonly upload: XMLHttpRequestUpload;\\n    /**\\n     * True when credentials are to be included in a cross-origin request. False when they are to be excluded in a cross-origin request and when cookies are to be ignored in its response. Initially false.\\n     *\\n     * When set: throws an \\\"InvalidStateError\\\" DOMException if state is not unsent or opened, or if the send() flag is set.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/withCredentials)\\n     */\\n    withCredentials: boolean;\\n    /**\\n     * Cancels any network activity.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/abort)\\n     */\\n    abort(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/getAllResponseHeaders) */\\n    getAllResponseHeaders(): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/getResponseHeader) */\\n    getResponseHeader(name: string): string | null;\\n    /**\\n     * Sets the request method, request URL, and synchronous flag.\\n     *\\n     * Throws a \\\"SyntaxError\\\" DOMException if either method is not a valid method or url cannot be parsed.\\n     *\\n     * Throws a \\\"SecurityError\\\" DOMException if method is a case-insensitive match for `CONNECT`, `TRACE`, or `TRACK`.\\n     *\\n     * Throws an \\\"InvalidAccessError\\\" DOMException if async is false, current global object is a Window object, and the timeout attribute is not zero or the responseType attribute is not the empty string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/open)\\n     */\\n    open(method: string, url: string | URL): void;\\n    open(method: string, url: string | URL, async: boolean, username?: string | null, password?: string | null): void;\\n    /**\\n     * Acts as if the `Content-Type` header value for a response is mime. (It does not change the header.)\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if state is loading or done.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/overrideMimeType)\\n     */\\n    overrideMimeType(mime: string): void;\\n    /**\\n     * Initiates the request. The body argument provides the request body, if any, and is ignored if the request method is GET or HEAD.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if either state is not opened or the send() flag is set.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/send)\\n     */\\n    send(body?: Document | XMLHttpRequestBodyInit | null): void;\\n    /**\\n     * Combines a header in author request headers.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if either state is not opened or the send() flag is set.\\n     *\\n     * Throws a \\\"SyntaxError\\\" DOMException if name is not a header name or if value is not a header value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/setRequestHeader)\\n     */\\n    setRequestHeader(name: string, value: string): void;\\n    readonly UNSENT: 0;\\n    readonly OPENED: 1;\\n    readonly HEADERS_RECEIVED: 2;\\n    readonly LOADING: 3;\\n    readonly DONE: 4;\\n    addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var XMLHttpRequest: {\\n    prototype: XMLHttpRequest;\\n    new(): XMLHttpRequest;\\n    readonly UNSENT: 0;\\n    readonly OPENED: 1;\\n    readonly HEADERS_RECEIVED: 2;\\n    readonly LOADING: 3;\\n    readonly DONE: 4;\\n};\\n\\ninterface XMLHttpRequestEventTargetEventMap {\\n    \\\"abort\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"error\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"load\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"loadend\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"loadstart\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"progress\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"timeout\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequestEventTarget) */\\ninterface XMLHttpRequestEventTarget extends EventTarget {\\n    onabort: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onerror: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onload: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onloadend: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onprogress: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var XMLHttpRequestEventTarget: {\\n    prototype: XMLHttpRequestEventTarget;\\n    new(): XMLHttpRequestEventTarget;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequestUpload) */\\ninterface XMLHttpRequestUpload extends XMLHttpRequestEventTarget {\\n    addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var XMLHttpRequestUpload: {\\n    prototype: XMLHttpRequestUpload;\\n    new(): XMLHttpRequestUpload;\\n};\\n\\n/**\\n * Provides the serializeToString() method to construct an XML string representing a DOM tree.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLSerializer)\\n */\\ninterface XMLSerializer {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLSerializer/serializeToString) */\\n    serializeToString(root: Node): string;\\n}\\n\\ndeclare var XMLSerializer: {\\n    prototype: XMLSerializer;\\n    new(): XMLSerializer;\\n};\\n\\n/**\\n * The XPathEvaluator interface allows to compile and evaluate XPath expressions.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathEvaluator)\\n */\\ninterface XPathEvaluator extends XPathEvaluatorBase {\\n}\\n\\ndeclare var XPathEvaluator: {\\n    prototype: XPathEvaluator;\\n    new(): XPathEvaluator;\\n};\\n\\ninterface XPathEvaluatorBase {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createExpression) */\\n    createExpression(expression: string, resolver?: XPathNSResolver | null): XPathExpression;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/createNSResolver) */\\n    createNSResolver(nodeResolver: Node): Node;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/evaluate) */\\n    evaluate(expression: string, contextNode: Node, resolver?: XPathNSResolver | null, type?: number, result?: XPathResult | null): XPathResult;\\n}\\n\\n/**\\n * This interface is a compiled XPath expression that can be evaluated on a document or specific node to return information its DOM tree.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathExpression)\\n */\\ninterface XPathExpression {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathExpression/evaluate) */\\n    evaluate(contextNode: Node, type?: number, result?: XPathResult | null): XPathResult;\\n}\\n\\ndeclare var XPathExpression: {\\n    prototype: XPathExpression;\\n    new(): XPathExpression;\\n};\\n\\n/**\\n * The results generated by evaluating an XPath expression within the context of a given node.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult)\\n */\\ninterface XPathResult {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/booleanValue) */\\n    readonly booleanValue: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/invalidIteratorState) */\\n    readonly invalidIteratorState: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/numberValue) */\\n    readonly numberValue: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/resultType) */\\n    readonly resultType: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/singleNodeValue) */\\n    readonly singleNodeValue: Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/snapshotLength) */\\n    readonly snapshotLength: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/stringValue) */\\n    readonly stringValue: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/iterateNext) */\\n    iterateNext(): Node | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XPathResult/snapshotItem) */\\n    snapshotItem(index: number): Node | null;\\n    readonly ANY_TYPE: 0;\\n    readonly NUMBER_TYPE: 1;\\n    readonly STRING_TYPE: 2;\\n    readonly BOOLEAN_TYPE: 3;\\n    readonly UNORDERED_NODE_ITERATOR_TYPE: 4;\\n    readonly ORDERED_NODE_ITERATOR_TYPE: 5;\\n    readonly UNORDERED_NODE_SNAPSHOT_TYPE: 6;\\n    readonly ORDERED_NODE_SNAPSHOT_TYPE: 7;\\n    readonly ANY_UNORDERED_NODE_TYPE: 8;\\n    readonly FIRST_ORDERED_NODE_TYPE: 9;\\n}\\n\\ndeclare var XPathResult: {\\n    prototype: XPathResult;\\n    new(): XPathResult;\\n    readonly ANY_TYPE: 0;\\n    readonly NUMBER_TYPE: 1;\\n    readonly STRING_TYPE: 2;\\n    readonly BOOLEAN_TYPE: 3;\\n    readonly UNORDERED_NODE_ITERATOR_TYPE: 4;\\n    readonly ORDERED_NODE_ITERATOR_TYPE: 5;\\n    readonly UNORDERED_NODE_SNAPSHOT_TYPE: 6;\\n    readonly ORDERED_NODE_SNAPSHOT_TYPE: 7;\\n    readonly ANY_UNORDERED_NODE_TYPE: 8;\\n    readonly FIRST_ORDERED_NODE_TYPE: 9;\\n};\\n\\n/**\\n * An XSLTProcessor applies an XSLT stylesheet transformation to an XML document to produce a new XML document as output. It has methods to load the XSLT stylesheet, to manipulate <xsl:param> parameter values, and to apply the transformation to documents.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor)\\n */\\ninterface XSLTProcessor {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/clearParameters) */\\n    clearParameters(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/getParameter) */\\n    getParameter(namespaceURI: string | null, localName: string): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/importStylesheet) */\\n    importStylesheet(style: Node): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/removeParameter) */\\n    removeParameter(namespaceURI: string | null, localName: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/reset) */\\n    reset(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/setParameter) */\\n    setParameter(namespaceURI: string | null, localName: string, value: any): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/transformToDocument) */\\n    transformToDocument(source: Node): Document;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XSLTProcessor/transformToFragment) */\\n    transformToFragment(source: Node, output: Document): DocumentFragment;\\n}\\n\\ndeclare var XSLTProcessor: {\\n    prototype: XSLTProcessor;\\n    new(): XSLTProcessor;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console) */\\ninterface Console {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/assert) */\\n    assert(condition?: boolean, ...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/clear) */\\n    clear(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/count) */\\n    count(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/countReset) */\\n    countReset(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/debug) */\\n    debug(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/dir) */\\n    dir(item?: any, options?: any): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/dirxml) */\\n    dirxml(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error) */\\n    error(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/group) */\\n    group(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/groupCollapsed) */\\n    groupCollapsed(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/groupEnd) */\\n    groupEnd(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/info) */\\n    info(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log) */\\n    log(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/table) */\\n    table(tabularData?: any, properties?: string[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/time) */\\n    time(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeEnd) */\\n    timeEnd(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeLog) */\\n    timeLog(label?: string, ...data: any[]): void;\\n    timeStamp(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/trace) */\\n    trace(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/warn) */\\n    warn(...data: any[]): void;\\n}\\n\\ndeclare var console: Console;\\n\\n/** Holds useful CSS-related methods. No object with this interface are implemented: it contains only static methods and therefore is a utilitarian interface. */\\ndeclare namespace CSS {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function Hz(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function Q(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function ch(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function cm(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function cqb(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function cqh(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function cqi(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function cqmax(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function cqmin(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function cqw(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function deg(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dpcm(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dpi(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dppx(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dvb(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dvh(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dvi(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dvmax(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dvmin(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function dvw(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function em(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/escape_static) */\\n    function escape(ident: string): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function ex(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function fr(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function grad(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function kHz(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function lvb(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function lvh(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function lvi(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function lvmax(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function lvmin(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function lvw(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function mm(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function ms(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function number(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function pc(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function percent(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function pt(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function px(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function rad(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/registerProperty_static) */\\n    function registerProperty(definition: PropertyDefinition): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function rem(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function s(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/supports_static) */\\n    function supports(property: string, value: string): boolean;\\n    function supports(conditionText: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function svb(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function svh(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function svi(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function svmax(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function svmin(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function svw(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function turn(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function vb(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function vh(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function vi(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function vmax(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function vmin(value: number): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSS/factory_functions_static) */\\n    function vw(value: number): CSSUnitValue;\\n}\\n\\ndeclare namespace WebAssembly {\\n    interface CompileError extends Error {\\n    }\\n\\n    var CompileError: {\\n        prototype: CompileError;\\n        new(message?: string): CompileError;\\n        (message?: string): CompileError;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Global) */\\n    interface Global<T extends ValueType = ValueType> {\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Global/value) */\\n        value: ValueTypeMap[T];\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Global/valueOf) */\\n        valueOf(): ValueTypeMap[T];\\n    }\\n\\n    var Global: {\\n        prototype: Global;\\n        new<T extends ValueType = ValueType>(descriptor: GlobalDescriptor<T>, v?: ValueTypeMap[T]): Global<T>;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance) */\\n    interface Instance {\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance/exports) */\\n        readonly exports: Exports;\\n    }\\n\\n    var Instance: {\\n        prototype: Instance;\\n        new(module: Module, importObject?: Imports): Instance;\\n    };\\n\\n    interface LinkError extends Error {\\n    }\\n\\n    var LinkError: {\\n        prototype: LinkError;\\n        new(message?: string): LinkError;\\n        (message?: string): LinkError;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory) */\\n    interface Memory {\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory/buffer) */\\n        readonly buffer: ArrayBuffer;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory/grow) */\\n        grow(delta: number): number;\\n    }\\n\\n    var Memory: {\\n        prototype: Memory;\\n        new(descriptor: MemoryDescriptor): Memory;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module) */\\n    interface Module {\\n    }\\n\\n    var Module: {\\n        prototype: Module;\\n        new(bytes: BufferSource): Module;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/customSections) */\\n        customSections(moduleObject: Module, sectionName: string): ArrayBuffer[];\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/exports) */\\n        exports(moduleObject: Module): ModuleExportDescriptor[];\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/imports) */\\n        imports(moduleObject: Module): ModuleImportDescriptor[];\\n    };\\n\\n    interface RuntimeError extends Error {\\n    }\\n\\n    var RuntimeError: {\\n        prototype: RuntimeError;\\n        new(message?: string): RuntimeError;\\n        (message?: string): RuntimeError;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table) */\\n    interface Table {\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/length) */\\n        readonly length: number;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/get) */\\n        get(index: number): any;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/grow) */\\n        grow(delta: number, value?: any): number;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/set) */\\n        set(index: number, value?: any): void;\\n    }\\n\\n    var Table: {\\n        prototype: Table;\\n        new(descriptor: TableDescriptor, value?: any): Table;\\n    };\\n\\n    interface GlobalDescriptor<T extends ValueType = ValueType> {\\n        mutable?: boolean;\\n        value: T;\\n    }\\n\\n    interface MemoryDescriptor {\\n        initial: number;\\n        maximum?: number;\\n        shared?: boolean;\\n    }\\n\\n    interface ModuleExportDescriptor {\\n        kind: ImportExportKind;\\n        name: string;\\n    }\\n\\n    interface ModuleImportDescriptor {\\n        kind: ImportExportKind;\\n        module: string;\\n        name: string;\\n    }\\n\\n    interface TableDescriptor {\\n        element: TableKind;\\n        initial: number;\\n        maximum?: number;\\n    }\\n\\n    interface ValueTypeMap {\\n        anyfunc: Function;\\n        externref: any;\\n        f32: number;\\n        f64: number;\\n        i32: number;\\n        i64: bigint;\\n        v128: never;\\n    }\\n\\n    interface WebAssemblyInstantiatedSource {\\n        instance: Instance;\\n        module: Module;\\n    }\\n\\n    type ImportExportKind = \\\"function\\\" | \\\"global\\\" | \\\"memory\\\" | \\\"table\\\";\\n    type TableKind = \\\"anyfunc\\\" | \\\"externref\\\";\\n    type ExportValue = Function | Global | Memory | Table;\\n    type Exports = Record<string, ExportValue>;\\n    type ImportValue = ExportValue | number;\\n    type Imports = Record<string, ModuleImports>;\\n    type ModuleImports = Record<string, ImportValue>;\\n    type ValueType = keyof ValueTypeMap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compile) */\\n    function compile(bytes: BufferSource): Promise<Module>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming) */\\n    function compileStreaming(source: Response | PromiseLike<Response>): Promise<Module>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate) */\\n    function instantiate(bytes: BufferSource, importObject?: Imports): Promise<WebAssemblyInstantiatedSource>;\\n    function instantiate(moduleObject: Module, importObject?: Imports): Promise<Instance>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming) */\\n    function instantiateStreaming(source: Response | PromiseLike<Response>, importObject?: Imports): Promise<WebAssemblyInstantiatedSource>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/validate) */\\n    function validate(bytes: BufferSource): boolean;\\n}\\n\\ninterface BlobCallback {\\n    (blob: Blob | null): void;\\n}\\n\\ninterface CustomElementConstructor {\\n    new (...params: any[]): HTMLElement;\\n}\\n\\ninterface DecodeErrorCallback {\\n    (error: DOMException): void;\\n}\\n\\ninterface DecodeSuccessCallback {\\n    (decodedData: AudioBuffer): void;\\n}\\n\\ninterface EncodedVideoChunkOutputCallback {\\n    (chunk: EncodedVideoChunk, metadata?: EncodedVideoChunkMetadata): void;\\n}\\n\\ninterface ErrorCallback {\\n    (err: DOMException): void;\\n}\\n\\ninterface FileCallback {\\n    (file: File): void;\\n}\\n\\ninterface FileSystemEntriesCallback {\\n    (entries: FileSystemEntry[]): void;\\n}\\n\\ninterface FileSystemEntryCallback {\\n    (entry: FileSystemEntry): void;\\n}\\n\\ninterface FrameRequestCallback {\\n    (time: DOMHighResTimeStamp): void;\\n}\\n\\ninterface FunctionStringCallback {\\n    (data: string): void;\\n}\\n\\ninterface IdleRequestCallback {\\n    (deadline: IdleDeadline): void;\\n}\\n\\ninterface IntersectionObserverCallback {\\n    (entries: IntersectionObserverEntry[], observer: IntersectionObserver): void;\\n}\\n\\ninterface LockGrantedCallback {\\n    (lock: Lock | null): any;\\n}\\n\\ninterface MediaSessionActionHandler {\\n    (details: MediaSessionActionDetails): void;\\n}\\n\\ninterface MutationCallback {\\n    (mutations: MutationRecord[], observer: MutationObserver): void;\\n}\\n\\ninterface NotificationPermissionCallback {\\n    (permission: NotificationPermission): void;\\n}\\n\\ninterface OnBeforeUnloadEventHandlerNonNull {\\n    (event: Event): string | null;\\n}\\n\\ninterface OnErrorEventHandlerNonNull {\\n    (event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error): any;\\n}\\n\\ninterface PerformanceObserverCallback {\\n    (entries: PerformanceObserverEntryList, observer: PerformanceObserver): void;\\n}\\n\\ninterface PositionCallback {\\n    (position: GeolocationPosition): void;\\n}\\n\\ninterface PositionErrorCallback {\\n    (positionError: GeolocationPositionError): void;\\n}\\n\\ninterface QueuingStrategySize<T = any> {\\n    (chunk: T): number;\\n}\\n\\ninterface RTCPeerConnectionErrorCallback {\\n    (error: DOMException): void;\\n}\\n\\ninterface RTCSessionDescriptionCallback {\\n    (description: RTCSessionDescriptionInit): void;\\n}\\n\\ninterface RemotePlaybackAvailabilityCallback {\\n    (available: boolean): void;\\n}\\n\\ninterface ReportingObserverCallback {\\n    (reports: Report[], observer: ReportingObserver): void;\\n}\\n\\ninterface ResizeObserverCallback {\\n    (entries: ResizeObserverEntry[], observer: ResizeObserver): void;\\n}\\n\\ninterface TransformerFlushCallback<O> {\\n    (controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;\\n}\\n\\ninterface TransformerStartCallback<O> {\\n    (controller: TransformStreamDefaultController<O>): any;\\n}\\n\\ninterface TransformerTransformCallback<I, O> {\\n    (chunk: I, controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSinkAbortCallback {\\n    (reason?: any): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSinkCloseCallback {\\n    (): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSinkStartCallback {\\n    (controller: WritableStreamDefaultController): any;\\n}\\n\\ninterface UnderlyingSinkWriteCallback<W> {\\n    (chunk: W, controller: WritableStreamDefaultController): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSourceCancelCallback {\\n    (reason?: any): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSourcePullCallback<R> {\\n    (controller: ReadableStreamController<R>): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSourceStartCallback<R> {\\n    (controller: ReadableStreamController<R>): any;\\n}\\n\\ninterface VideoFrameOutputCallback {\\n    (output: VideoFrame): void;\\n}\\n\\ninterface VideoFrameRequestCallback {\\n    (now: DOMHighResTimeStamp, metadata: VideoFrameCallbackMetadata): void;\\n}\\n\\ninterface VoidFunction {\\n    (): void;\\n}\\n\\ninterface WebCodecsErrorCallback {\\n    (error: DOMException): void;\\n}\\n\\ninterface HTMLElementTagNameMap {\\n    \\\"a\\\": HTMLAnchorElement;\\n    \\\"abbr\\\": HTMLElement;\\n    \\\"address\\\": HTMLElement;\\n    \\\"area\\\": HTMLAreaElement;\\n    \\\"article\\\": HTMLElement;\\n    \\\"aside\\\": HTMLElement;\\n    \\\"audio\\\": HTMLAudioElement;\\n    \\\"b\\\": HTMLElement;\\n    \\\"base\\\": HTMLBaseElement;\\n    \\\"bdi\\\": HTMLElement;\\n    \\\"bdo\\\": HTMLElement;\\n    \\\"blockquote\\\": HTMLQuoteElement;\\n    \\\"body\\\": HTMLBodyElement;\\n    \\\"br\\\": HTMLBRElement;\\n    \\\"button\\\": HTMLButtonElement;\\n    \\\"canvas\\\": HTMLCanvasElement;\\n    \\\"caption\\\": HTMLTableCaptionElement;\\n    \\\"cite\\\": HTMLElement;\\n    \\\"code\\\": HTMLElement;\\n    \\\"col\\\": HTMLTableColElement;\\n    \\\"colgroup\\\": HTMLTableColElement;\\n    \\\"data\\\": HTMLDataElement;\\n    \\\"datalist\\\": HTMLDataListElement;\\n    \\\"dd\\\": HTMLElement;\\n    \\\"del\\\": HTMLModElement;\\n    \\\"details\\\": HTMLDetailsElement;\\n    \\\"dfn\\\": HTMLElement;\\n    \\\"dialog\\\": HTMLDialogElement;\\n    \\\"div\\\": HTMLDivElement;\\n    \\\"dl\\\": HTMLDListElement;\\n    \\\"dt\\\": HTMLElement;\\n    \\\"em\\\": HTMLElement;\\n    \\\"embed\\\": HTMLEmbedElement;\\n    \\\"fieldset\\\": HTMLFieldSetElement;\\n    \\\"figcaption\\\": HTMLElement;\\n    \\\"figure\\\": HTMLElement;\\n    \\\"footer\\\": HTMLElement;\\n    \\\"form\\\": HTMLFormElement;\\n    \\\"h1\\\": HTMLHeadingElement;\\n    \\\"h2\\\": HTMLHeadingElement;\\n    \\\"h3\\\": HTMLHeadingElement;\\n    \\\"h4\\\": HTMLHeadingElement;\\n    \\\"h5\\\": HTMLHeadingElement;\\n    \\\"h6\\\": HTMLHeadingElement;\\n    \\\"head\\\": HTMLHeadElement;\\n    \\\"header\\\": HTMLElement;\\n    \\\"hgroup\\\": HTMLElement;\\n    \\\"hr\\\": HTMLHRElement;\\n    \\\"html\\\": HTMLHtmlElement;\\n    \\\"i\\\": HTMLElement;\\n    \\\"iframe\\\": HTMLIFrameElement;\\n    \\\"img\\\": HTMLImageElement;\\n    \\\"input\\\": HTMLInputElement;\\n    \\\"ins\\\": HTMLModElement;\\n    \\\"kbd\\\": HTMLElement;\\n    \\\"label\\\": HTMLLabelElement;\\n    \\\"legend\\\": HTMLLegendElement;\\n    \\\"li\\\": HTMLLIElement;\\n    \\\"link\\\": HTMLLinkElement;\\n    \\\"main\\\": HTMLElement;\\n    \\\"map\\\": HTMLMapElement;\\n    \\\"mark\\\": HTMLElement;\\n    \\\"menu\\\": HTMLMenuElement;\\n    \\\"meta\\\": HTMLMetaElement;\\n    \\\"meter\\\": HTMLMeterElement;\\n    \\\"nav\\\": HTMLElement;\\n    \\\"noscript\\\": HTMLElement;\\n    \\\"object\\\": HTMLObjectElement;\\n    \\\"ol\\\": HTMLOListElement;\\n    \\\"optgroup\\\": HTMLOptGroupElement;\\n    \\\"option\\\": HTMLOptionElement;\\n    \\\"output\\\": HTMLOutputElement;\\n    \\\"p\\\": HTMLParagraphElement;\\n    \\\"picture\\\": HTMLPictureElement;\\n    \\\"pre\\\": HTMLPreElement;\\n    \\\"progress\\\": HTMLProgressElement;\\n    \\\"q\\\": HTMLQuoteElement;\\n    \\\"rp\\\": HTMLElement;\\n    \\\"rt\\\": HTMLElement;\\n    \\\"ruby\\\": HTMLElement;\\n    \\\"s\\\": HTMLElement;\\n    \\\"samp\\\": HTMLElement;\\n    \\\"script\\\": HTMLScriptElement;\\n    \\\"search\\\": HTMLElement;\\n    \\\"section\\\": HTMLElement;\\n    \\\"select\\\": HTMLSelectElement;\\n    \\\"slot\\\": HTMLSlotElement;\\n    \\\"small\\\": HTMLElement;\\n    \\\"source\\\": HTMLSourceElement;\\n    \\\"span\\\": HTMLSpanElement;\\n    \\\"strong\\\": HTMLElement;\\n    \\\"style\\\": HTMLStyleElement;\\n    \\\"sub\\\": HTMLElement;\\n    \\\"summary\\\": HTMLElement;\\n    \\\"sup\\\": HTMLElement;\\n    \\\"table\\\": HTMLTableElement;\\n    \\\"tbody\\\": HTMLTableSectionElement;\\n    \\\"td\\\": HTMLTableCellElement;\\n    \\\"template\\\": HTMLTemplateElement;\\n    \\\"textarea\\\": HTMLTextAreaElement;\\n    \\\"tfoot\\\": HTMLTableSectionElement;\\n    \\\"th\\\": HTMLTableCellElement;\\n    \\\"thead\\\": HTMLTableSectionElement;\\n    \\\"time\\\": HTMLTimeElement;\\n    \\\"title\\\": HTMLTitleElement;\\n    \\\"tr\\\": HTMLTableRowElement;\\n    \\\"track\\\": HTMLTrackElement;\\n    \\\"u\\\": HTMLElement;\\n    \\\"ul\\\": HTMLUListElement;\\n    \\\"var\\\": HTMLElement;\\n    \\\"video\\\": HTMLVideoElement;\\n    \\\"wbr\\\": HTMLElement;\\n}\\n\\ninterface HTMLElementDeprecatedTagNameMap {\\n    \\\"acronym\\\": HTMLElement;\\n    \\\"applet\\\": HTMLUnknownElement;\\n    \\\"basefont\\\": HTMLElement;\\n    \\\"bgsound\\\": HTMLUnknownElement;\\n    \\\"big\\\": HTMLElement;\\n    \\\"blink\\\": HTMLUnknownElement;\\n    \\\"center\\\": HTMLElement;\\n    \\\"dir\\\": HTMLDirectoryElement;\\n    \\\"font\\\": HTMLFontElement;\\n    \\\"frame\\\": HTMLFrameElement;\\n    \\\"frameset\\\": HTMLFrameSetElement;\\n    \\\"isindex\\\": HTMLUnknownElement;\\n    \\\"keygen\\\": HTMLUnknownElement;\\n    \\\"listing\\\": HTMLPreElement;\\n    \\\"marquee\\\": HTMLMarqueeElement;\\n    \\\"menuitem\\\": HTMLElement;\\n    \\\"multicol\\\": HTMLUnknownElement;\\n    \\\"nextid\\\": HTMLUnknownElement;\\n    \\\"nobr\\\": HTMLElement;\\n    \\\"noembed\\\": HTMLElement;\\n    \\\"noframes\\\": HTMLElement;\\n    \\\"param\\\": HTMLParamElement;\\n    \\\"plaintext\\\": HTMLElement;\\n    \\\"rb\\\": HTMLElement;\\n    \\\"rtc\\\": HTMLElement;\\n    \\\"spacer\\\": HTMLUnknownElement;\\n    \\\"strike\\\": HTMLElement;\\n    \\\"tt\\\": HTMLElement;\\n    \\\"xmp\\\": HTMLPreElement;\\n}\\n\\ninterface SVGElementTagNameMap {\\n    \\\"a\\\": SVGAElement;\\n    \\\"animate\\\": SVGAnimateElement;\\n    \\\"animateMotion\\\": SVGAnimateMotionElement;\\n    \\\"animateTransform\\\": SVGAnimateTransformElement;\\n    \\\"circle\\\": SVGCircleElement;\\n    \\\"clipPath\\\": SVGClipPathElement;\\n    \\\"defs\\\": SVGDefsElement;\\n    \\\"desc\\\": SVGDescElement;\\n    \\\"ellipse\\\": SVGEllipseElement;\\n    \\\"feBlend\\\": SVGFEBlendElement;\\n    \\\"feColorMatrix\\\": SVGFEColorMatrixElement;\\n    \\\"feComponentTransfer\\\": SVGFEComponentTransferElement;\\n    \\\"feComposite\\\": SVGFECompositeElement;\\n    \\\"feConvolveMatrix\\\": SVGFEConvolveMatrixElement;\\n    \\\"feDiffuseLighting\\\": SVGFEDiffuseLightingElement;\\n    \\\"feDisplacementMap\\\": SVGFEDisplacementMapElement;\\n    \\\"feDistantLight\\\": SVGFEDistantLightElement;\\n    \\\"feDropShadow\\\": SVGFEDropShadowElement;\\n    \\\"feFlood\\\": SVGFEFloodElement;\\n    \\\"feFuncA\\\": SVGFEFuncAElement;\\n    \\\"feFuncB\\\": SVGFEFuncBElement;\\n    \\\"feFuncG\\\": SVGFEFuncGElement;\\n    \\\"feFuncR\\\": SVGFEFuncRElement;\\n    \\\"feGaussianBlur\\\": SVGFEGaussianBlurElement;\\n    \\\"feImage\\\": SVGFEImageElement;\\n    \\\"feMerge\\\": SVGFEMergeElement;\\n    \\\"feMergeNode\\\": SVGFEMergeNodeElement;\\n    \\\"feMorphology\\\": SVGFEMorphologyElement;\\n    \\\"feOffset\\\": SVGFEOffsetElement;\\n    \\\"fePointLight\\\": SVGFEPointLightElement;\\n    \\\"feSpecularLighting\\\": SVGFESpecularLightingElement;\\n    \\\"feSpotLight\\\": SVGFESpotLightElement;\\n    \\\"feTile\\\": SVGFETileElement;\\n    \\\"feTurbulence\\\": SVGFETurbulenceElement;\\n    \\\"filter\\\": SVGFilterElement;\\n    \\\"foreignObject\\\": SVGForeignObjectElement;\\n    \\\"g\\\": SVGGElement;\\n    \\\"image\\\": SVGImageElement;\\n    \\\"line\\\": SVGLineElement;\\n    \\\"linearGradient\\\": SVGLinearGradientElement;\\n    \\\"marker\\\": SVGMarkerElement;\\n    \\\"mask\\\": SVGMaskElement;\\n    \\\"metadata\\\": SVGMetadataElement;\\n    \\\"mpath\\\": SVGMPathElement;\\n    \\\"path\\\": SVGPathElement;\\n    \\\"pattern\\\": SVGPatternElement;\\n    \\\"polygon\\\": SVGPolygonElement;\\n    \\\"polyline\\\": SVGPolylineElement;\\n    \\\"radialGradient\\\": SVGRadialGradientElement;\\n    \\\"rect\\\": SVGRectElement;\\n    \\\"script\\\": SVGScriptElement;\\n    \\\"set\\\": SVGSetElement;\\n    \\\"stop\\\": SVGStopElement;\\n    \\\"style\\\": SVGStyleElement;\\n    \\\"svg\\\": SVGSVGElement;\\n    \\\"switch\\\": SVGSwitchElement;\\n    \\\"symbol\\\": SVGSymbolElement;\\n    \\\"text\\\": SVGTextElement;\\n    \\\"textPath\\\": SVGTextPathElement;\\n    \\\"title\\\": SVGTitleElement;\\n    \\\"tspan\\\": SVGTSpanElement;\\n    \\\"use\\\": SVGUseElement;\\n    \\\"view\\\": SVGViewElement;\\n}\\n\\ninterface MathMLElementTagNameMap {\\n    \\\"annotation\\\": MathMLElement;\\n    \\\"annotation-xml\\\": MathMLElement;\\n    \\\"maction\\\": MathMLElement;\\n    \\\"math\\\": MathMLElement;\\n    \\\"merror\\\": MathMLElement;\\n    \\\"mfrac\\\": MathMLElement;\\n    \\\"mi\\\": MathMLElement;\\n    \\\"mmultiscripts\\\": MathMLElement;\\n    \\\"mn\\\": MathMLElement;\\n    \\\"mo\\\": MathMLElement;\\n    \\\"mover\\\": MathMLElement;\\n    \\\"mpadded\\\": MathMLElement;\\n    \\\"mphantom\\\": MathMLElement;\\n    \\\"mprescripts\\\": MathMLElement;\\n    \\\"mroot\\\": MathMLElement;\\n    \\\"mrow\\\": MathMLElement;\\n    \\\"ms\\\": MathMLElement;\\n    \\\"mspace\\\": MathMLElement;\\n    \\\"msqrt\\\": MathMLElement;\\n    \\\"mstyle\\\": MathMLElement;\\n    \\\"msub\\\": MathMLElement;\\n    \\\"msubsup\\\": MathMLElement;\\n    \\\"msup\\\": MathMLElement;\\n    \\\"mtable\\\": MathMLElement;\\n    \\\"mtd\\\": MathMLElement;\\n    \\\"mtext\\\": MathMLElement;\\n    \\\"mtr\\\": MathMLElement;\\n    \\\"munder\\\": MathMLElement;\\n    \\\"munderover\\\": MathMLElement;\\n    \\\"semantics\\\": MathMLElement;\\n}\\n\\n/** @deprecated Directly use HTMLElementTagNameMap or SVGElementTagNameMap as appropriate, instead. */\\ntype ElementTagNameMap = HTMLElementTagNameMap & Pick<SVGElementTagNameMap, Exclude<keyof SVGElementTagNameMap, keyof HTMLElementTagNameMap>>;\\n\\ndeclare var Audio: {\\n    new(src?: string): HTMLAudioElement;\\n};\\ndeclare var Image: {\\n    new(width?: number, height?: number): HTMLImageElement;\\n};\\ndeclare var Option: {\\n    new(text?: string, value?: string, defaultSelected?: boolean, selected?: boolean): HTMLOptionElement;\\n};\\n/**\\n * @deprecated This is a legacy alias of `navigator`.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/navigator)\\n */\\ndeclare var clientInformation: Navigator;\\n/**\\n * Returns true if the window has been closed, false otherwise.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/closed)\\n */\\ndeclare var closed: boolean;\\n/**\\n * Defines a new custom element, mapping the given name to the given constructor as an autonomous custom element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/customElements)\\n */\\ndeclare var customElements: CustomElementRegistry;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/devicePixelRatio) */\\ndeclare var devicePixelRatio: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/document) */\\ndeclare var document: Document;\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/event)\\n */\\ndeclare var event: Event | undefined;\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/external)\\n */\\ndeclare var external: External;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/frameElement) */\\ndeclare var frameElement: Element | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/frames) */\\ndeclare var frames: WindowProxy;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/history) */\\ndeclare var history: History;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/innerHeight) */\\ndeclare var innerHeight: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/innerWidth) */\\ndeclare var innerWidth: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/length) */\\ndeclare var length: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/location) */\\ndeclare var location: Location;\\n/**\\n * Returns true if the location bar is visible; otherwise, returns false.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/locationbar)\\n */\\ndeclare var locationbar: BarProp;\\n/**\\n * Returns true if the menu bar is visible; otherwise, returns false.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/menubar)\\n */\\ndeclare var menubar: BarProp;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/name) */\\n/** @deprecated */\\ndeclare const name: void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/navigator) */\\ndeclare var navigator: Navigator;\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/devicemotion_event)\\n */\\ndeclare var ondevicemotion: ((this: Window, ev: DeviceMotionEvent) => any) | null;\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/deviceorientation_event)\\n */\\ndeclare var ondeviceorientation: ((this: Window, ev: DeviceOrientationEvent) => any) | null;\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/orientationchange_event)\\n */\\ndeclare var onorientationchange: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/opener) */\\ndeclare var opener: any;\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/orientation)\\n */\\ndeclare var orientation: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/outerHeight) */\\ndeclare var outerHeight: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/outerWidth) */\\ndeclare var outerWidth: number;\\n/**\\n * @deprecated This is a legacy alias of `scrollX`.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollX)\\n */\\ndeclare var pageXOffset: number;\\n/**\\n * @deprecated This is a legacy alias of `scrollY`.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollY)\\n */\\ndeclare var pageYOffset: number;\\n/**\\n * Refers to either the parent WindowProxy, or itself.\\n *\\n * It can rarely be null e.g. for contentWindow of an iframe that is already removed from the parent.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/parent)\\n */\\ndeclare var parent: WindowProxy;\\n/**\\n * Returns true if the personal bar is visible; otherwise, returns false.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/personalbar)\\n */\\ndeclare var personalbar: BarProp;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screen) */\\ndeclare var screen: Screen;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screenLeft) */\\ndeclare var screenLeft: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screenTop) */\\ndeclare var screenTop: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screenX) */\\ndeclare var screenX: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/screenY) */\\ndeclare var screenY: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollX) */\\ndeclare var scrollX: number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollY) */\\ndeclare var scrollY: number;\\n/**\\n * Returns true if the scrollbars are visible; otherwise, returns false.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollbars)\\n */\\ndeclare var scrollbars: BarProp;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/self) */\\ndeclare var self: Window & typeof globalThis;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/speechSynthesis) */\\ndeclare var speechSynthesis: SpeechSynthesis;\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/status)\\n */\\ndeclare var status: string;\\n/**\\n * Returns true if the status bar is visible; otherwise, returns false.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/statusbar)\\n */\\ndeclare var statusbar: BarProp;\\n/**\\n * Returns true if the toolbar is visible; otherwise, returns false.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/toolbar)\\n */\\ndeclare var toolbar: BarProp;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/top) */\\ndeclare var top: WindowProxy | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/visualViewport) */\\ndeclare var visualViewport: VisualViewport | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/window) */\\ndeclare var window: Window & typeof globalThis;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/alert) */\\ndeclare function alert(message?: any): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/blur) */\\ndeclare function blur(): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/cancelIdleCallback) */\\ndeclare function cancelIdleCallback(handle: number): void;\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/captureEvents)\\n */\\ndeclare function captureEvents(): void;\\n/**\\n * Closes the window.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/close)\\n */\\ndeclare function close(): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/confirm) */\\ndeclare function confirm(message?: string): boolean;\\n/**\\n * Moves the focus to the window's browsing context, if any.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/focus)\\n */\\ndeclare function focus(): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/getComputedStyle) */\\ndeclare function getComputedStyle(elt: Element, pseudoElt?: string | null): CSSStyleDeclaration;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/getSelection) */\\ndeclare function getSelection(): Selection | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/matchMedia) */\\ndeclare function matchMedia(query: string): MediaQueryList;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/moveBy) */\\ndeclare function moveBy(x: number, y: number): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/moveTo) */\\ndeclare function moveTo(x: number, y: number): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/open) */\\ndeclare function open(url?: string | URL, target?: string, features?: string): WindowProxy | null;\\n/**\\n * Posts a message to the given window. Messages can be structured objects, e.g. nested objects and arrays, can contain JavaScript values (strings, numbers, Date objects, etc), and can contain certain data objects such as File Blob, FileList, and ArrayBuffer objects.\\n *\\n * Objects listed in the transfer member of options are transferred, not just cloned, meaning that they are no longer usable on the sending side.\\n *\\n * A target origin can be specified using the targetOrigin member of options. If not provided, it defaults to \\\"/\\\". This default restricts the message to same-origin targets only.\\n *\\n * If the origin of the target window doesn't match the given target origin, the message is discarded, to avoid information leakage. To send the message to the target regardless of origin, set the target origin to \\\"*\\\".\\n *\\n * Throws a \\\"DataCloneError\\\" DOMException if transfer array contains duplicate objects or if message could not be cloned.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/postMessage)\\n */\\ndeclare function postMessage(message: any, targetOrigin: string, transfer?: Transferable[]): void;\\ndeclare function postMessage(message: any, options?: WindowPostMessageOptions): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/print) */\\ndeclare function print(): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/prompt) */\\ndeclare function prompt(message?: string, _default?: string): string | null;\\n/**\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/releaseEvents)\\n */\\ndeclare function releaseEvents(): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/requestIdleCallback) */\\ndeclare function requestIdleCallback(callback: IdleRequestCallback, options?: IdleRequestOptions): number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/resizeBy) */\\ndeclare function resizeBy(x: number, y: number): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/resizeTo) */\\ndeclare function resizeTo(width: number, height: number): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scroll) */\\ndeclare function scroll(options?: ScrollToOptions): void;\\ndeclare function scroll(x: number, y: number): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollBy) */\\ndeclare function scrollBy(options?: ScrollToOptions): void;\\ndeclare function scrollBy(x: number, y: number): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/scrollTo) */\\ndeclare function scrollTo(options?: ScrollToOptions): void;\\ndeclare function scrollTo(x: number, y: number): void;\\n/**\\n * Cancels the document load.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/stop)\\n */\\ndeclare function stop(): void;\\ndeclare function toString(): string;\\n/**\\n * Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/dispatchEvent)\\n */\\ndeclare function dispatchEvent(event: Event): boolean;\\ndeclare function cancelAnimationFrame(handle: number): void;\\ndeclare function requestAnimationFrame(callback: FrameRequestCallback): number;\\n/**\\n * Fires when the user aborts the download.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/abort_event)\\n */\\ndeclare var onabort: ((this: Window, ev: UIEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationcancel_event) */\\ndeclare var onanimationcancel: ((this: Window, ev: AnimationEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationend_event) */\\ndeclare var onanimationend: ((this: Window, ev: AnimationEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationiteration_event) */\\ndeclare var onanimationiteration: ((this: Window, ev: AnimationEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationstart_event) */\\ndeclare var onanimationstart: ((this: Window, ev: AnimationEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/auxclick_event) */\\ndeclare var onauxclick: ((this: Window, ev: MouseEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/beforeinput_event) */\\ndeclare var onbeforeinput: ((this: Window, ev: InputEvent) => any) | null;\\n/**\\n * Fires when the object loses the input focus.\\n * @param ev The focus event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/blur_event)\\n */\\ndeclare var onblur: ((this: Window, ev: FocusEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/cancel_event) */\\ndeclare var oncancel: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when playback is possible, but would require further buffering.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/canplay_event)\\n */\\ndeclare var oncanplay: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/canplaythrough_event) */\\ndeclare var oncanplaythrough: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Fires when the contents of the object or selection have changed.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/change_event)\\n */\\ndeclare var onchange: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Fires when the user clicks the left mouse button on the object\\n * @param ev The mouse event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/click_event)\\n */\\ndeclare var onclick: ((this: Window, ev: MouseEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDialogElement/close_event) */\\ndeclare var onclose: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Fires when the user clicks the right mouse button in the client area, opening the context menu.\\n * @param ev The mouse event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/contextmenu_event)\\n */\\ndeclare var oncontextmenu: ((this: Window, ev: MouseEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/copy_event) */\\ndeclare var oncopy: ((this: Window, ev: ClipboardEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTrackElement/cuechange_event) */\\ndeclare var oncuechange: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/cut_event) */\\ndeclare var oncut: ((this: Window, ev: ClipboardEvent) => any) | null;\\n/**\\n * Fires when the user double-clicks the object.\\n * @param ev The mouse event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/dblclick_event)\\n */\\ndeclare var ondblclick: ((this: Window, ev: MouseEvent) => any) | null;\\n/**\\n * Fires on the source object continuously during a drag operation.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/drag_event)\\n */\\ndeclare var ondrag: ((this: Window, ev: DragEvent) => any) | null;\\n/**\\n * Fires on the source object when the user releases the mouse at the close of a drag operation.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragend_event)\\n */\\ndeclare var ondragend: ((this: Window, ev: DragEvent) => any) | null;\\n/**\\n * Fires on the target element when the user drags the object to a valid drop target.\\n * @param ev The drag event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragenter_event)\\n */\\ndeclare var ondragenter: ((this: Window, ev: DragEvent) => any) | null;\\n/**\\n * Fires on the target object when the user moves the mouse out of a valid drop target during a drag operation.\\n * @param ev The drag event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragleave_event)\\n */\\ndeclare var ondragleave: ((this: Window, ev: DragEvent) => any) | null;\\n/**\\n * Fires on the target element continuously while the user drags the object over a valid drop target.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragover_event)\\n */\\ndeclare var ondragover: ((this: Window, ev: DragEvent) => any) | null;\\n/**\\n * Fires on the source object when the user starts to drag a text selection or selected object.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/dragstart_event)\\n */\\ndeclare var ondragstart: ((this: Window, ev: DragEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/drop_event) */\\ndeclare var ondrop: ((this: Window, ev: DragEvent) => any) | null;\\n/**\\n * Occurs when the duration attribute is updated.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/durationchange_event)\\n */\\ndeclare var ondurationchange: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when the media element is reset to its initial state.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/emptied_event)\\n */\\ndeclare var onemptied: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when the end of playback is reached.\\n * @param ev The event\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/ended_event)\\n */\\ndeclare var onended: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Fires when an error occurs during object loading.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/error_event)\\n */\\ndeclare var onerror: OnErrorEventHandler;\\n/**\\n * Fires when the object receives focus.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/focus_event)\\n */\\ndeclare var onfocus: ((this: Window, ev: FocusEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/formdata_event) */\\ndeclare var onformdata: ((this: Window, ev: FormDataEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/gotpointercapture_event) */\\ndeclare var ongotpointercapture: ((this: Window, ev: PointerEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/input_event) */\\ndeclare var oninput: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/invalid_event) */\\ndeclare var oninvalid: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Fires when the user presses a key.\\n * @param ev The keyboard event\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/keydown_event)\\n */\\ndeclare var onkeydown: ((this: Window, ev: KeyboardEvent) => any) | null;\\n/**\\n * Fires when the user presses an alphanumeric key.\\n * @param ev The event.\\n * @deprecated\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/keypress_event)\\n */\\ndeclare var onkeypress: ((this: Window, ev: KeyboardEvent) => any) | null;\\n/**\\n * Fires when the user releases a key.\\n * @param ev The keyboard event\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/keyup_event)\\n */\\ndeclare var onkeyup: ((this: Window, ev: KeyboardEvent) => any) | null;\\n/**\\n * Fires immediately after the browser loads the object.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SVGElement/load_event)\\n */\\ndeclare var onload: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when media data is loaded at the current playback position.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/loadeddata_event)\\n */\\ndeclare var onloadeddata: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when the duration and dimensions of the media have been determined.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/loadedmetadata_event)\\n */\\ndeclare var onloadedmetadata: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when Internet Explorer begins looking for media data.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/loadstart_event)\\n */\\ndeclare var onloadstart: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/lostpointercapture_event) */\\ndeclare var onlostpointercapture: ((this: Window, ev: PointerEvent) => any) | null;\\n/**\\n * Fires when the user clicks the object with either mouse button.\\n * @param ev The mouse event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mousedown_event)\\n */\\ndeclare var onmousedown: ((this: Window, ev: MouseEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseenter_event) */\\ndeclare var onmouseenter: ((this: Window, ev: MouseEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseleave_event) */\\ndeclare var onmouseleave: ((this: Window, ev: MouseEvent) => any) | null;\\n/**\\n * Fires when the user moves the mouse over the object.\\n * @param ev The mouse event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mousemove_event)\\n */\\ndeclare var onmousemove: ((this: Window, ev: MouseEvent) => any) | null;\\n/**\\n * Fires when the user moves the mouse pointer outside the boundaries of the object.\\n * @param ev The mouse event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseout_event)\\n */\\ndeclare var onmouseout: ((this: Window, ev: MouseEvent) => any) | null;\\n/**\\n * Fires when the user moves the mouse pointer into the object.\\n * @param ev The mouse event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseover_event)\\n */\\ndeclare var onmouseover: ((this: Window, ev: MouseEvent) => any) | null;\\n/**\\n * Fires when the user releases a mouse button while the mouse is over the object.\\n * @param ev The mouse event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/mouseup_event)\\n */\\ndeclare var onmouseup: ((this: Window, ev: MouseEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/paste_event) */\\ndeclare var onpaste: ((this: Window, ev: ClipboardEvent) => any) | null;\\n/**\\n * Occurs when playback is paused.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/pause_event)\\n */\\ndeclare var onpause: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when the play method is requested.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/play_event)\\n */\\ndeclare var onplay: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when the audio or video has started playing.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/playing_event)\\n */\\ndeclare var onplaying: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointercancel_event) */\\ndeclare var onpointercancel: ((this: Window, ev: PointerEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerdown_event) */\\ndeclare var onpointerdown: ((this: Window, ev: PointerEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerenter_event) */\\ndeclare var onpointerenter: ((this: Window, ev: PointerEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerleave_event) */\\ndeclare var onpointerleave: ((this: Window, ev: PointerEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointermove_event) */\\ndeclare var onpointermove: ((this: Window, ev: PointerEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerout_event) */\\ndeclare var onpointerout: ((this: Window, ev: PointerEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerover_event) */\\ndeclare var onpointerover: ((this: Window, ev: PointerEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/pointerup_event) */\\ndeclare var onpointerup: ((this: Window, ev: PointerEvent) => any) | null;\\n/**\\n * Occurs to indicate progress while downloading media data.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/progress_event)\\n */\\ndeclare var onprogress: ((this: Window, ev: ProgressEvent) => any) | null;\\n/**\\n * Occurs when the playback rate is increased or decreased.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/ratechange_event)\\n */\\ndeclare var onratechange: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Fires when the user resets a form.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/reset_event)\\n */\\ndeclare var onreset: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/resize_event) */\\ndeclare var onresize: ((this: Window, ev: UIEvent) => any) | null;\\n/**\\n * Fires when the user repositions the scroll box in the scroll bar on the object.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/scroll_event)\\n */\\ndeclare var onscroll: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/scrollend_event) */\\ndeclare var onscrollend: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/securitypolicyviolation_event) */\\ndeclare var onsecuritypolicyviolation: ((this: Window, ev: SecurityPolicyViolationEvent) => any) | null;\\n/**\\n * Occurs when the seek operation ends.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/seeked_event)\\n */\\ndeclare var onseeked: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when the current playback position is moved.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/seeking_event)\\n */\\ndeclare var onseeking: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Fires when the current selection changes.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/select_event)\\n */\\ndeclare var onselect: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/selectionchange_event) */\\ndeclare var onselectionchange: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Node/selectstart_event) */\\ndeclare var onselectstart: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSlotElement/slotchange_event) */\\ndeclare var onslotchange: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when the download has stopped.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/stalled_event)\\n */\\ndeclare var onstalled: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLFormElement/submit_event) */\\ndeclare var onsubmit: ((this: Window, ev: SubmitEvent) => any) | null;\\n/**\\n * Occurs if the load operation has been intentionally halted.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/suspend_event)\\n */\\ndeclare var onsuspend: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs to indicate the current playback position.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/timeupdate_event)\\n */\\ndeclare var ontimeupdate: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDetailsElement/toggle_event) */\\ndeclare var ontoggle: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/touchcancel_event) */\\ndeclare var ontouchcancel: ((this: Window, ev: TouchEvent) => any) | null | undefined;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/touchend_event) */\\ndeclare var ontouchend: ((this: Window, ev: TouchEvent) => any) | null | undefined;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/touchmove_event) */\\ndeclare var ontouchmove: ((this: Window, ev: TouchEvent) => any) | null | undefined;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/touchstart_event) */\\ndeclare var ontouchstart: ((this: Window, ev: TouchEvent) => any) | null | undefined;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitioncancel_event) */\\ndeclare var ontransitioncancel: ((this: Window, ev: TransitionEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitionend_event) */\\ndeclare var ontransitionend: ((this: Window, ev: TransitionEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitionrun_event) */\\ndeclare var ontransitionrun: ((this: Window, ev: TransitionEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitionstart_event) */\\ndeclare var ontransitionstart: ((this: Window, ev: TransitionEvent) => any) | null;\\n/**\\n * Occurs when the volume is changed, or playback is muted or unmuted.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/volumechange_event)\\n */\\ndeclare var onvolumechange: ((this: Window, ev: Event) => any) | null;\\n/**\\n * Occurs when playback stops because the next frame of a video resource is not available.\\n * @param ev The event.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMediaElement/waiting_event)\\n */\\ndeclare var onwaiting: ((this: Window, ev: Event) => any) | null;\\n/**\\n * @deprecated This is a legacy alias of `onanimationend`.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationend_event)\\n */\\ndeclare var onwebkitanimationend: ((this: Window, ev: Event) => any) | null;\\n/**\\n * @deprecated This is a legacy alias of `onanimationiteration`.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationiteration_event)\\n */\\ndeclare var onwebkitanimationiteration: ((this: Window, ev: Event) => any) | null;\\n/**\\n * @deprecated This is a legacy alias of `onanimationstart`.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/animationstart_event)\\n */\\ndeclare var onwebkitanimationstart: ((this: Window, ev: Event) => any) | null;\\n/**\\n * @deprecated This is a legacy alias of `ontransitionend`.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/transitionend_event)\\n */\\ndeclare var onwebkittransitionend: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/wheel_event) */\\ndeclare var onwheel: ((this: Window, ev: WheelEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/afterprint_event) */\\ndeclare var onafterprint: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/beforeprint_event) */\\ndeclare var onbeforeprint: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/beforeunload_event) */\\ndeclare var onbeforeunload: ((this: Window, ev: BeforeUnloadEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/gamepadconnected_event) */\\ndeclare var ongamepadconnected: ((this: Window, ev: GamepadEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/gamepaddisconnected_event) */\\ndeclare var ongamepaddisconnected: ((this: Window, ev: GamepadEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/hashchange_event) */\\ndeclare var onhashchange: ((this: Window, ev: HashChangeEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/languagechange_event) */\\ndeclare var onlanguagechange: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/message_event) */\\ndeclare var onmessage: ((this: Window, ev: MessageEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/messageerror_event) */\\ndeclare var onmessageerror: ((this: Window, ev: MessageEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/offline_event) */\\ndeclare var onoffline: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/online_event) */\\ndeclare var ononline: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/pagehide_event) */\\ndeclare var onpagehide: ((this: Window, ev: PageTransitionEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/pageshow_event) */\\ndeclare var onpageshow: ((this: Window, ev: PageTransitionEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) */\\ndeclare var onpopstate: ((this: Window, ev: PopStateEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/rejectionhandled_event) */\\ndeclare var onrejectionhandled: ((this: Window, ev: PromiseRejectionEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/storage_event) */\\ndeclare var onstorage: ((this: Window, ev: StorageEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/unhandledrejection_event) */\\ndeclare var onunhandledrejection: ((this: Window, ev: PromiseRejectionEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/unload_event) */\\ndeclare var onunload: ((this: Window, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/localStorage) */\\ndeclare var localStorage: Storage;\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/caches)\\n */\\ndeclare var caches: CacheStorage;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/crossOriginIsolated) */\\ndeclare var crossOriginIsolated: boolean;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/crypto_property) */\\ndeclare var crypto: Crypto;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/indexedDB) */\\ndeclare var indexedDB: IDBFactory;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/isSecureContext) */\\ndeclare var isSecureContext: boolean;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/origin) */\\ndeclare var origin: string;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/performance_property) */\\ndeclare var performance: Performance;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/atob) */\\ndeclare function atob(data: string): string;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/btoa) */\\ndeclare function btoa(data: string): string;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/clearInterval) */\\ndeclare function clearInterval(id: number | undefined): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/clearTimeout) */\\ndeclare function clearTimeout(id: number | undefined): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/createImageBitmap) */\\ndeclare function createImageBitmap(image: ImageBitmapSource, options?: ImageBitmapOptions): Promise<ImageBitmap>;\\ndeclare function createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/fetch) */\\ndeclare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/queueMicrotask) */\\ndeclare function queueMicrotask(callback: VoidFunction): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/reportError) */\\ndeclare function reportError(e: any): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/setInterval) */\\ndeclare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/setTimeout) */\\ndeclare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/structuredClone) */\\ndeclare function structuredClone<T = any>(value: T, options?: StructuredSerializeOptions): T;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage) */\\ndeclare var sessionStorage: Storage;\\ndeclare function addEventListener<K extends keyof WindowEventMap>(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\ndeclare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\ndeclare function removeEventListener<K extends keyof WindowEventMap>(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\ndeclare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\ntype AlgorithmIdentifier = Algorithm | string;\\ntype AllowSharedBufferSource = ArrayBuffer | ArrayBufferView;\\ntype AutoFill = AutoFillBase | `${OptionalPrefixToken<AutoFillSection>}${OptionalPrefixToken<AutoFillAddressKind>}${AutoFillField}${OptionalPostfixToken<AutoFillCredentialField>}`;\\ntype AutoFillField = AutoFillNormalField | `${OptionalPrefixToken<AutoFillContactKind>}${AutoFillContactField}`;\\ntype AutoFillSection = `section-${string}`;\\ntype BigInteger = Uint8Array;\\ntype BinaryData = ArrayBuffer | ArrayBufferView;\\ntype BlobPart = BufferSource | Blob | string;\\ntype BodyInit = ReadableStream | XMLHttpRequestBodyInit;\\ntype BufferSource = ArrayBufferView | ArrayBuffer;\\ntype COSEAlgorithmIdentifier = number;\\ntype CSSKeywordish = string | CSSKeywordValue;\\ntype CSSNumberish = number | CSSNumericValue;\\ntype CSSPerspectiveValue = CSSNumericValue | CSSKeywordish;\\ntype CSSUnparsedSegment = string | CSSVariableReferenceValue;\\ntype CanvasImageSource = HTMLOrSVGImageElement | HTMLVideoElement | HTMLCanvasElement | ImageBitmap | OffscreenCanvas | VideoFrame;\\ntype ClipboardItemData = Promise<string | Blob>;\\ntype ClipboardItems = ClipboardItem[];\\ntype ConstrainBoolean = boolean | ConstrainBooleanParameters;\\ntype ConstrainDOMString = string | string[] | ConstrainDOMStringParameters;\\ntype ConstrainDouble = number | ConstrainDoubleRange;\\ntype ConstrainULong = number | ConstrainULongRange;\\ntype DOMHighResTimeStamp = number;\\ntype EpochTimeStamp = number;\\ntype EventListenerOrEventListenerObject = EventListener | EventListenerObject;\\ntype FileSystemWriteChunkType = BufferSource | Blob | string | WriteParams;\\ntype Float32List = Float32Array | GLfloat[];\\ntype FormDataEntryValue = File | string;\\ntype GLbitfield = number;\\ntype GLboolean = boolean;\\ntype GLclampf = number;\\ntype GLenum = number;\\ntype GLfloat = number;\\ntype GLint = number;\\ntype GLint64 = number;\\ntype GLintptr = number;\\ntype GLsizei = number;\\ntype GLsizeiptr = number;\\ntype GLuint = number;\\ntype GLuint64 = number;\\ntype HTMLOrSVGImageElement = HTMLImageElement | SVGImageElement;\\ntype HTMLOrSVGScriptElement = HTMLScriptElement | SVGScriptElement;\\ntype HashAlgorithmIdentifier = AlgorithmIdentifier;\\ntype HeadersInit = [string, string][] | Record<string, string> | Headers;\\ntype IDBValidKey = number | string | Date | BufferSource | IDBValidKey[];\\ntype ImageBitmapSource = CanvasImageSource | Blob | ImageData;\\ntype Int32List = Int32Array | GLint[];\\ntype LineAndPositionSetting = number | AutoKeyword;\\ntype MediaProvider = MediaStream | MediaSource | Blob;\\ntype MessageEventSource = WindowProxy | MessagePort | ServiceWorker;\\ntype MutationRecordType = \\\"attributes\\\" | \\\"characterData\\\" | \\\"childList\\\";\\ntype NamedCurve = string;\\ntype OffscreenRenderingContext = OffscreenCanvasRenderingContext2D | ImageBitmapRenderingContext | WebGLRenderingContext | WebGL2RenderingContext;\\ntype OnBeforeUnloadEventHandler = OnBeforeUnloadEventHandlerNonNull | null;\\ntype OnErrorEventHandler = OnErrorEventHandlerNonNull | null;\\ntype OptionalPostfixToken<T extends string> = ` ${T}` | \\\"\\\";\\ntype OptionalPrefixToken<T extends string> = `${T} ` | \\\"\\\";\\ntype PerformanceEntryList = PerformanceEntry[];\\ntype ReadableStreamController<T> = ReadableStreamDefaultController<T> | ReadableByteStreamController;\\ntype ReadableStreamReadResult<T> = ReadableStreamReadValueResult<T> | ReadableStreamReadDoneResult<T>;\\ntype ReadableStreamReader<T> = ReadableStreamDefaultReader<T> | ReadableStreamBYOBReader;\\ntype RenderingContext = CanvasRenderingContext2D | ImageBitmapRenderingContext | WebGLRenderingContext | WebGL2RenderingContext;\\ntype ReportList = Report[];\\ntype RequestInfo = Request | string;\\ntype TexImageSource = ImageBitmap | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | OffscreenCanvas | VideoFrame;\\ntype TimerHandler = string | Function;\\ntype Transferable = OffscreenCanvas | ImageBitmap | MessagePort | ReadableStream | WritableStream | TransformStream | VideoFrame | ArrayBuffer;\\ntype Uint32List = Uint32Array | GLuint[];\\ntype VibratePattern = number | number[];\\ntype WindowProxy = Window;\\ntype XMLHttpRequestBodyInit = Blob | BufferSource | FormData | URLSearchParams | string;\\ntype AlignSetting = \\\"center\\\" | \\\"end\\\" | \\\"left\\\" | \\\"right\\\" | \\\"start\\\";\\ntype AlphaOption = \\\"discard\\\" | \\\"keep\\\";\\ntype AnimationPlayState = \\\"finished\\\" | \\\"idle\\\" | \\\"paused\\\" | \\\"running\\\";\\ntype AnimationReplaceState = \\\"active\\\" | \\\"persisted\\\" | \\\"removed\\\";\\ntype AppendMode = \\\"segments\\\" | \\\"sequence\\\";\\ntype AttestationConveyancePreference = \\\"direct\\\" | \\\"enterprise\\\" | \\\"indirect\\\" | \\\"none\\\";\\ntype AudioContextLatencyCategory = \\\"balanced\\\" | \\\"interactive\\\" | \\\"playback\\\";\\ntype AudioContextState = \\\"closed\\\" | \\\"running\\\" | \\\"suspended\\\";\\ntype AuthenticatorAttachment = \\\"cross-platform\\\" | \\\"platform\\\";\\ntype AuthenticatorTransport = \\\"ble\\\" | \\\"hybrid\\\" | \\\"internal\\\" | \\\"nfc\\\" | \\\"usb\\\";\\ntype AutoFillAddressKind = \\\"billing\\\" | \\\"shipping\\\";\\ntype AutoFillBase = \\\"\\\" | \\\"off\\\" | \\\"on\\\";\\ntype AutoFillContactField = \\\"email\\\" | \\\"tel\\\" | \\\"tel-area-code\\\" | \\\"tel-country-code\\\" | \\\"tel-extension\\\" | \\\"tel-local\\\" | \\\"tel-local-prefix\\\" | \\\"tel-local-suffix\\\" | \\\"tel-national\\\";\\ntype AutoFillContactKind = \\\"home\\\" | \\\"mobile\\\" | \\\"work\\\";\\ntype AutoFillCredentialField = \\\"webauthn\\\";\\ntype AutoFillNormalField = \\\"additional-name\\\" | \\\"address-level1\\\" | \\\"address-level2\\\" | \\\"address-level3\\\" | \\\"address-level4\\\" | \\\"address-line1\\\" | \\\"address-line2\\\" | \\\"address-line3\\\" | \\\"bday-day\\\" | \\\"bday-month\\\" | \\\"bday-year\\\" | \\\"cc-csc\\\" | \\\"cc-exp\\\" | \\\"cc-exp-month\\\" | \\\"cc-exp-year\\\" | \\\"cc-family-name\\\" | \\\"cc-given-name\\\" | \\\"cc-name\\\" | \\\"cc-number\\\" | \\\"cc-type\\\" | \\\"country\\\" | \\\"country-name\\\" | \\\"current-password\\\" | \\\"family-name\\\" | \\\"given-name\\\" | \\\"honorific-prefix\\\" | \\\"honorific-suffix\\\" | \\\"name\\\" | \\\"new-password\\\" | \\\"one-time-code\\\" | \\\"organization\\\" | \\\"postal-code\\\" | \\\"street-address\\\" | \\\"transaction-amount\\\" | \\\"transaction-currency\\\" | \\\"username\\\";\\ntype AutoKeyword = \\\"auto\\\";\\ntype AutomationRate = \\\"a-rate\\\" | \\\"k-rate\\\";\\ntype AvcBitstreamFormat = \\\"annexb\\\" | \\\"avc\\\";\\ntype BinaryType = \\\"arraybuffer\\\" | \\\"blob\\\";\\ntype BiquadFilterType = \\\"allpass\\\" | \\\"bandpass\\\" | \\\"highpass\\\" | \\\"highshelf\\\" | \\\"lowpass\\\" | \\\"lowshelf\\\" | \\\"notch\\\" | \\\"peaking\\\";\\ntype CSSMathOperator = \\\"clamp\\\" | \\\"invert\\\" | \\\"max\\\" | \\\"min\\\" | \\\"negate\\\" | \\\"product\\\" | \\\"sum\\\";\\ntype CSSNumericBaseType = \\\"angle\\\" | \\\"flex\\\" | \\\"frequency\\\" | \\\"length\\\" | \\\"percent\\\" | \\\"resolution\\\" | \\\"time\\\";\\ntype CanPlayTypeResult = \\\"\\\" | \\\"maybe\\\" | \\\"probably\\\";\\ntype CanvasDirection = \\\"inherit\\\" | \\\"ltr\\\" | \\\"rtl\\\";\\ntype CanvasFillRule = \\\"evenodd\\\" | \\\"nonzero\\\";\\ntype CanvasFontKerning = \\\"auto\\\" | \\\"none\\\" | \\\"normal\\\";\\ntype CanvasFontStretch = \\\"condensed\\\" | \\\"expanded\\\" | \\\"extra-condensed\\\" | \\\"extra-expanded\\\" | \\\"normal\\\" | \\\"semi-condensed\\\" | \\\"semi-expanded\\\" | \\\"ultra-condensed\\\" | \\\"ultra-expanded\\\";\\ntype CanvasFontVariantCaps = \\\"all-petite-caps\\\" | \\\"all-small-caps\\\" | \\\"normal\\\" | \\\"petite-caps\\\" | \\\"small-caps\\\" | \\\"titling-caps\\\" | \\\"unicase\\\";\\ntype CanvasLineCap = \\\"butt\\\" | \\\"round\\\" | \\\"square\\\";\\ntype CanvasLineJoin = \\\"bevel\\\" | \\\"miter\\\" | \\\"round\\\";\\ntype CanvasTextAlign = \\\"center\\\" | \\\"end\\\" | \\\"left\\\" | \\\"right\\\" | \\\"start\\\";\\ntype CanvasTextBaseline = \\\"alphabetic\\\" | \\\"bottom\\\" | \\\"hanging\\\" | \\\"ideographic\\\" | \\\"middle\\\" | \\\"top\\\";\\ntype CanvasTextRendering = \\\"auto\\\" | \\\"geometricPrecision\\\" | \\\"optimizeLegibility\\\" | \\\"optimizeSpeed\\\";\\ntype ChannelCountMode = \\\"clamped-max\\\" | \\\"explicit\\\" | \\\"max\\\";\\ntype ChannelInterpretation = \\\"discrete\\\" | \\\"speakers\\\";\\ntype ClientTypes = \\\"all\\\" | \\\"sharedworker\\\" | \\\"window\\\" | \\\"worker\\\";\\ntype CodecState = \\\"closed\\\" | \\\"configured\\\" | \\\"unconfigured\\\";\\ntype ColorGamut = \\\"p3\\\" | \\\"rec2020\\\" | \\\"srgb\\\";\\ntype ColorSpaceConversion = \\\"default\\\" | \\\"none\\\";\\ntype CompositeOperation = \\\"accumulate\\\" | \\\"add\\\" | \\\"replace\\\";\\ntype CompositeOperationOrAuto = \\\"accumulate\\\" | \\\"add\\\" | \\\"auto\\\" | \\\"replace\\\";\\ntype CompressionFormat = \\\"deflate\\\" | \\\"deflate-raw\\\" | \\\"gzip\\\";\\ntype CredentialMediationRequirement = \\\"conditional\\\" | \\\"optional\\\" | \\\"required\\\" | \\\"silent\\\";\\ntype DOMParserSupportedType = \\\"application/xhtml+xml\\\" | \\\"application/xml\\\" | \\\"image/svg+xml\\\" | \\\"text/html\\\" | \\\"text/xml\\\";\\ntype DirectionSetting = \\\"\\\" | \\\"lr\\\" | \\\"rl\\\";\\ntype DisplayCaptureSurfaceType = \\\"browser\\\" | \\\"monitor\\\" | \\\"window\\\";\\ntype DistanceModelType = \\\"exponential\\\" | \\\"inverse\\\" | \\\"linear\\\";\\ntype DocumentReadyState = \\\"complete\\\" | \\\"interactive\\\" | \\\"loading\\\";\\ntype DocumentVisibilityState = \\\"hidden\\\" | \\\"visible\\\";\\ntype EncodedVideoChunkType = \\\"delta\\\" | \\\"key\\\";\\ntype EndOfStreamError = \\\"decode\\\" | \\\"network\\\";\\ntype EndingType = \\\"native\\\" | \\\"transparent\\\";\\ntype FileSystemHandleKind = \\\"directory\\\" | \\\"file\\\";\\ntype FillMode = \\\"auto\\\" | \\\"backwards\\\" | \\\"both\\\" | \\\"forwards\\\" | \\\"none\\\";\\ntype FontDisplay = \\\"auto\\\" | \\\"block\\\" | \\\"fallback\\\" | \\\"optional\\\" | \\\"swap\\\";\\ntype FontFaceLoadStatus = \\\"error\\\" | \\\"loaded\\\" | \\\"loading\\\" | \\\"unloaded\\\";\\ntype FontFaceSetLoadStatus = \\\"loaded\\\" | \\\"loading\\\";\\ntype FullscreenNavigationUI = \\\"auto\\\" | \\\"hide\\\" | \\\"show\\\";\\ntype GamepadHapticActuatorType = \\\"vibration\\\";\\ntype GamepadHapticEffectType = \\\"dual-rumble\\\";\\ntype GamepadHapticsResult = \\\"complete\\\" | \\\"preempted\\\";\\ntype GamepadMappingType = \\\"\\\" | \\\"standard\\\" | \\\"xr-standard\\\";\\ntype GlobalCompositeOperation = \\\"color\\\" | \\\"color-burn\\\" | \\\"color-dodge\\\" | \\\"copy\\\" | \\\"darken\\\" | \\\"destination-atop\\\" | \\\"destination-in\\\" | \\\"destination-out\\\" | \\\"destination-over\\\" | \\\"difference\\\" | \\\"exclusion\\\" | \\\"hard-light\\\" | \\\"hue\\\" | \\\"lighten\\\" | \\\"lighter\\\" | \\\"luminosity\\\" | \\\"multiply\\\" | \\\"overlay\\\" | \\\"saturation\\\" | \\\"screen\\\" | \\\"soft-light\\\" | \\\"source-atop\\\" | \\\"source-in\\\" | \\\"source-out\\\" | \\\"source-over\\\" | \\\"xor\\\";\\ntype HardwareAcceleration = \\\"no-preference\\\" | \\\"prefer-hardware\\\" | \\\"prefer-software\\\";\\ntype HdrMetadataType = \\\"smpteSt2086\\\" | \\\"smpteSt2094-10\\\" | \\\"smpteSt2094-40\\\";\\ntype IDBCursorDirection = \\\"next\\\" | \\\"nextunique\\\" | \\\"prev\\\" | \\\"prevunique\\\";\\ntype IDBRequestReadyState = \\\"done\\\" | \\\"pending\\\";\\ntype IDBTransactionDurability = \\\"default\\\" | \\\"relaxed\\\" | \\\"strict\\\";\\ntype IDBTransactionMode = \\\"readonly\\\" | \\\"readwrite\\\" | \\\"versionchange\\\";\\ntype ImageOrientation = \\\"flipY\\\" | \\\"from-image\\\" | \\\"none\\\";\\ntype ImageSmoothingQuality = \\\"high\\\" | \\\"low\\\" | \\\"medium\\\";\\ntype InsertPosition = \\\"afterbegin\\\" | \\\"afterend\\\" | \\\"beforebegin\\\" | \\\"beforeend\\\";\\ntype IterationCompositeOperation = \\\"accumulate\\\" | \\\"replace\\\";\\ntype KeyFormat = \\\"jwk\\\" | \\\"pkcs8\\\" | \\\"raw\\\" | \\\"spki\\\";\\ntype KeyType = \\\"private\\\" | \\\"public\\\" | \\\"secret\\\";\\ntype KeyUsage = \\\"decrypt\\\" | \\\"deriveBits\\\" | \\\"deriveKey\\\" | \\\"encrypt\\\" | \\\"sign\\\" | \\\"unwrapKey\\\" | \\\"verify\\\" | \\\"wrapKey\\\";\\ntype LatencyMode = \\\"quality\\\" | \\\"realtime\\\";\\ntype LineAlignSetting = \\\"center\\\" | \\\"end\\\" | \\\"start\\\";\\ntype LockMode = \\\"exclusive\\\" | \\\"shared\\\";\\ntype MIDIPortConnectionState = \\\"closed\\\" | \\\"open\\\" | \\\"pending\\\";\\ntype MIDIPortDeviceState = \\\"connected\\\" | \\\"disconnected\\\";\\ntype MIDIPortType = \\\"input\\\" | \\\"output\\\";\\ntype MediaDecodingType = \\\"file\\\" | \\\"media-source\\\" | \\\"webrtc\\\";\\ntype MediaDeviceKind = \\\"audioinput\\\" | \\\"audiooutput\\\" | \\\"videoinput\\\";\\ntype MediaEncodingType = \\\"record\\\" | \\\"webrtc\\\";\\ntype MediaKeyMessageType = \\\"individualization-request\\\" | \\\"license-release\\\" | \\\"license-renewal\\\" | \\\"license-request\\\";\\ntype MediaKeySessionClosedReason = \\\"closed-by-application\\\" | \\\"hardware-context-reset\\\" | \\\"internal-error\\\" | \\\"release-acknowledged\\\" | \\\"resource-evicted\\\";\\ntype MediaKeySessionType = \\\"persistent-license\\\" | \\\"temporary\\\";\\ntype MediaKeyStatus = \\\"expired\\\" | \\\"internal-error\\\" | \\\"output-downscaled\\\" | \\\"output-restricted\\\" | \\\"released\\\" | \\\"status-pending\\\" | \\\"usable\\\" | \\\"usable-in-future\\\";\\ntype MediaKeysRequirement = \\\"not-allowed\\\" | \\\"optional\\\" | \\\"required\\\";\\ntype MediaSessionAction = \\\"nexttrack\\\" | \\\"pause\\\" | \\\"play\\\" | \\\"previoustrack\\\" | \\\"seekbackward\\\" | \\\"seekforward\\\" | \\\"seekto\\\" | \\\"skipad\\\" | \\\"stop\\\";\\ntype MediaSessionPlaybackState = \\\"none\\\" | \\\"paused\\\" | \\\"playing\\\";\\ntype MediaStreamTrackState = \\\"ended\\\" | \\\"live\\\";\\ntype NavigationTimingType = \\\"back_forward\\\" | \\\"navigate\\\" | \\\"prerender\\\" | \\\"reload\\\";\\ntype NotificationDirection = \\\"auto\\\" | \\\"ltr\\\" | \\\"rtl\\\";\\ntype NotificationPermission = \\\"default\\\" | \\\"denied\\\" | \\\"granted\\\";\\ntype OffscreenRenderingContextId = \\\"2d\\\" | \\\"bitmaprenderer\\\" | \\\"webgl\\\" | \\\"webgl2\\\" | \\\"webgpu\\\";\\ntype OrientationType = \\\"landscape-primary\\\" | \\\"landscape-secondary\\\" | \\\"portrait-primary\\\" | \\\"portrait-secondary\\\";\\ntype OscillatorType = \\\"custom\\\" | \\\"sawtooth\\\" | \\\"sine\\\" | \\\"square\\\" | \\\"triangle\\\";\\ntype OverSampleType = \\\"2x\\\" | \\\"4x\\\" | \\\"none\\\";\\ntype PanningModelType = \\\"HRTF\\\" | \\\"equalpower\\\";\\ntype PaymentComplete = \\\"fail\\\" | \\\"success\\\" | \\\"unknown\\\";\\ntype PermissionName = \\\"geolocation\\\" | \\\"notifications\\\" | \\\"persistent-storage\\\" | \\\"push\\\" | \\\"screen-wake-lock\\\" | \\\"xr-spatial-tracking\\\";\\ntype PermissionState = \\\"denied\\\" | \\\"granted\\\" | \\\"prompt\\\";\\ntype PlaybackDirection = \\\"alternate\\\" | \\\"alternate-reverse\\\" | \\\"normal\\\" | \\\"reverse\\\";\\ntype PositionAlignSetting = \\\"auto\\\" | \\\"center\\\" | \\\"line-left\\\" | \\\"line-right\\\";\\ntype PredefinedColorSpace = \\\"display-p3\\\" | \\\"srgb\\\";\\ntype PremultiplyAlpha = \\\"default\\\" | \\\"none\\\" | \\\"premultiply\\\";\\ntype PresentationStyle = \\\"attachment\\\" | \\\"inline\\\" | \\\"unspecified\\\";\\ntype PublicKeyCredentialType = \\\"public-key\\\";\\ntype PushEncryptionKeyName = \\\"auth\\\" | \\\"p256dh\\\";\\ntype RTCBundlePolicy = \\\"balanced\\\" | \\\"max-bundle\\\" | \\\"max-compat\\\";\\ntype RTCDataChannelState = \\\"closed\\\" | \\\"closing\\\" | \\\"connecting\\\" | \\\"open\\\";\\ntype RTCDegradationPreference = \\\"balanced\\\" | \\\"maintain-framerate\\\" | \\\"maintain-resolution\\\";\\ntype RTCDtlsTransportState = \\\"closed\\\" | \\\"connected\\\" | \\\"connecting\\\" | \\\"failed\\\" | \\\"new\\\";\\ntype RTCEncodedVideoFrameType = \\\"delta\\\" | \\\"empty\\\" | \\\"key\\\";\\ntype RTCErrorDetailType = \\\"data-channel-failure\\\" | \\\"dtls-failure\\\" | \\\"fingerprint-failure\\\" | \\\"hardware-encoder-error\\\" | \\\"hardware-encoder-not-available\\\" | \\\"sctp-failure\\\" | \\\"sdp-syntax-error\\\";\\ntype RTCIceCandidateType = \\\"host\\\" | \\\"prflx\\\" | \\\"relay\\\" | \\\"srflx\\\";\\ntype RTCIceComponent = \\\"rtcp\\\" | \\\"rtp\\\";\\ntype RTCIceConnectionState = \\\"checking\\\" | \\\"closed\\\" | \\\"completed\\\" | \\\"connected\\\" | \\\"disconnected\\\" | \\\"failed\\\" | \\\"new\\\";\\ntype RTCIceGathererState = \\\"complete\\\" | \\\"gathering\\\" | \\\"new\\\";\\ntype RTCIceGatheringState = \\\"complete\\\" | \\\"gathering\\\" | \\\"new\\\";\\ntype RTCIceProtocol = \\\"tcp\\\" | \\\"udp\\\";\\ntype RTCIceTcpCandidateType = \\\"active\\\" | \\\"passive\\\" | \\\"so\\\";\\ntype RTCIceTransportPolicy = \\\"all\\\" | \\\"relay\\\";\\ntype RTCIceTransportState = \\\"checking\\\" | \\\"closed\\\" | \\\"completed\\\" | \\\"connected\\\" | \\\"disconnected\\\" | \\\"failed\\\" | \\\"new\\\";\\ntype RTCPeerConnectionState = \\\"closed\\\" | \\\"connected\\\" | \\\"connecting\\\" | \\\"disconnected\\\" | \\\"failed\\\" | \\\"new\\\";\\ntype RTCPriorityType = \\\"high\\\" | \\\"low\\\" | \\\"medium\\\" | \\\"very-low\\\";\\ntype RTCRtcpMuxPolicy = \\\"require\\\";\\ntype RTCRtpTransceiverDirection = \\\"inactive\\\" | \\\"recvonly\\\" | \\\"sendonly\\\" | \\\"sendrecv\\\" | \\\"stopped\\\";\\ntype RTCSctpTransportState = \\\"closed\\\" | \\\"connected\\\" | \\\"connecting\\\";\\ntype RTCSdpType = \\\"answer\\\" | \\\"offer\\\" | \\\"pranswer\\\" | \\\"rollback\\\";\\ntype RTCSignalingState = \\\"closed\\\" | \\\"have-local-offer\\\" | \\\"have-local-pranswer\\\" | \\\"have-remote-offer\\\" | \\\"have-remote-pranswer\\\" | \\\"stable\\\";\\ntype RTCStatsIceCandidatePairState = \\\"failed\\\" | \\\"frozen\\\" | \\\"in-progress\\\" | \\\"inprogress\\\" | \\\"succeeded\\\" | \\\"waiting\\\";\\ntype RTCStatsType = \\\"candidate-pair\\\" | \\\"certificate\\\" | \\\"codec\\\" | \\\"data-channel\\\" | \\\"inbound-rtp\\\" | \\\"local-candidate\\\" | \\\"media-source\\\" | \\\"outbound-rtp\\\" | \\\"peer-connection\\\" | \\\"remote-candidate\\\" | \\\"remote-inbound-rtp\\\" | \\\"remote-outbound-rtp\\\" | \\\"transport\\\";\\ntype ReadableStreamReaderMode = \\\"byob\\\";\\ntype ReadableStreamType = \\\"bytes\\\";\\ntype ReadyState = \\\"closed\\\" | \\\"ended\\\" | \\\"open\\\";\\ntype RecordingState = \\\"inactive\\\" | \\\"paused\\\" | \\\"recording\\\";\\ntype ReferrerPolicy = \\\"\\\" | \\\"no-referrer\\\" | \\\"no-referrer-when-downgrade\\\" | \\\"origin\\\" | \\\"origin-when-cross-origin\\\" | \\\"same-origin\\\" | \\\"strict-origin\\\" | \\\"strict-origin-when-cross-origin\\\" | \\\"unsafe-url\\\";\\ntype RemotePlaybackState = \\\"connected\\\" | \\\"connecting\\\" | \\\"disconnected\\\";\\ntype RequestCache = \\\"default\\\" | \\\"force-cache\\\" | \\\"no-cache\\\" | \\\"no-store\\\" | \\\"only-if-cached\\\" | \\\"reload\\\";\\ntype RequestCredentials = \\\"include\\\" | \\\"omit\\\" | \\\"same-origin\\\";\\ntype RequestDestination = \\\"\\\" | \\\"audio\\\" | \\\"audioworklet\\\" | \\\"document\\\" | \\\"embed\\\" | \\\"font\\\" | \\\"frame\\\" | \\\"iframe\\\" | \\\"image\\\" | \\\"manifest\\\" | \\\"object\\\" | \\\"paintworklet\\\" | \\\"report\\\" | \\\"script\\\" | \\\"sharedworker\\\" | \\\"style\\\" | \\\"track\\\" | \\\"video\\\" | \\\"worker\\\" | \\\"xslt\\\";\\ntype RequestMode = \\\"cors\\\" | \\\"navigate\\\" | \\\"no-cors\\\" | \\\"same-origin\\\";\\ntype RequestRedirect = \\\"error\\\" | \\\"follow\\\" | \\\"manual\\\";\\ntype ResidentKeyRequirement = \\\"discouraged\\\" | \\\"preferred\\\" | \\\"required\\\";\\ntype ResizeObserverBoxOptions = \\\"border-box\\\" | \\\"content-box\\\" | \\\"device-pixel-content-box\\\";\\ntype ResizeQuality = \\\"high\\\" | \\\"low\\\" | \\\"medium\\\" | \\\"pixelated\\\";\\ntype ResponseType = \\\"basic\\\" | \\\"cors\\\" | \\\"default\\\" | \\\"error\\\" | \\\"opaque\\\" | \\\"opaqueredirect\\\";\\ntype ScrollBehavior = \\\"auto\\\" | \\\"instant\\\" | \\\"smooth\\\";\\ntype ScrollLogicalPosition = \\\"center\\\" | \\\"end\\\" | \\\"nearest\\\" | \\\"start\\\";\\ntype ScrollRestoration = \\\"auto\\\" | \\\"manual\\\";\\ntype ScrollSetting = \\\"\\\" | \\\"up\\\";\\ntype SecurityPolicyViolationEventDisposition = \\\"enforce\\\" | \\\"report\\\";\\ntype SelectionMode = \\\"end\\\" | \\\"preserve\\\" | \\\"select\\\" | \\\"start\\\";\\ntype ServiceWorkerState = \\\"activated\\\" | \\\"activating\\\" | \\\"installed\\\" | \\\"installing\\\" | \\\"parsed\\\" | \\\"redundant\\\";\\ntype ServiceWorkerUpdateViaCache = \\\"all\\\" | \\\"imports\\\" | \\\"none\\\";\\ntype ShadowRootMode = \\\"closed\\\" | \\\"open\\\";\\ntype SlotAssignmentMode = \\\"manual\\\" | \\\"named\\\";\\ntype SpeechSynthesisErrorCode = \\\"audio-busy\\\" | \\\"audio-hardware\\\" | \\\"canceled\\\" | \\\"interrupted\\\" | \\\"invalid-argument\\\" | \\\"language-unavailable\\\" | \\\"network\\\" | \\\"not-allowed\\\" | \\\"synthesis-failed\\\" | \\\"synthesis-unavailable\\\" | \\\"text-too-long\\\" | \\\"voice-unavailable\\\";\\ntype TextTrackKind = \\\"captions\\\" | \\\"chapters\\\" | \\\"descriptions\\\" | \\\"metadata\\\" | \\\"subtitles\\\";\\ntype TextTrackMode = \\\"disabled\\\" | \\\"hidden\\\" | \\\"showing\\\";\\ntype TouchType = \\\"direct\\\" | \\\"stylus\\\";\\ntype TransferFunction = \\\"hlg\\\" | \\\"pq\\\" | \\\"srgb\\\";\\ntype UserVerificationRequirement = \\\"discouraged\\\" | \\\"preferred\\\" | \\\"required\\\";\\ntype VideoColorPrimaries = \\\"bt470bg\\\" | \\\"bt709\\\" | \\\"smpte170m\\\";\\ntype VideoEncoderBitrateMode = \\\"constant\\\" | \\\"quantizer\\\" | \\\"variable\\\";\\ntype VideoFacingModeEnum = \\\"environment\\\" | \\\"left\\\" | \\\"right\\\" | \\\"user\\\";\\ntype VideoMatrixCoefficients = \\\"bt470bg\\\" | \\\"bt709\\\" | \\\"rgb\\\" | \\\"smpte170m\\\";\\ntype VideoPixelFormat = \\\"BGRA\\\" | \\\"BGRX\\\" | \\\"I420\\\" | \\\"I420A\\\" | \\\"I422\\\" | \\\"I444\\\" | \\\"NV12\\\" | \\\"RGBA\\\" | \\\"RGBX\\\";\\ntype VideoTransferCharacteristics = \\\"bt709\\\" | \\\"iec61966-2-1\\\" | \\\"smpte170m\\\";\\ntype WakeLockType = \\\"screen\\\";\\ntype WebGLPowerPreference = \\\"default\\\" | \\\"high-performance\\\" | \\\"low-power\\\";\\ntype WebTransportCongestionControl = \\\"default\\\" | \\\"low-latency\\\" | \\\"throughput\\\";\\ntype WebTransportErrorSource = \\\"session\\\" | \\\"stream\\\";\\ntype WorkerType = \\\"classic\\\" | \\\"module\\\";\\ntype WriteCommandType = \\\"seek\\\" | \\\"truncate\\\" | \\\"write\\\";\\ntype XMLHttpRequestResponseType = \\\"\\\" | \\\"arraybuffer\\\" | \\\"blob\\\" | \\\"document\\\" | \\\"json\\\" | \\\"text\\\";\\n\"\n  },\n  {\n    \"fileName\": \"lib.dom.iterable.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/////////////////////////////\\n/// Window Iterable APIs\\n/////////////////////////////\\n\\ninterface AudioParam {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/setValueCurveAtTime) */\\n    setValueCurveAtTime(values: Iterable<number>, startTime: number, duration: number): AudioParam;\\n}\\n\\ninterface AudioParamMap extends ReadonlyMap<string, AudioParam> {\\n}\\n\\ninterface BaseAudioContext {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createIIRFilter) */\\n    createIIRFilter(feedforward: Iterable<number>, feedback: Iterable<number>): IIRFilterNode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BaseAudioContext/createPeriodicWave) */\\n    createPeriodicWave(real: Iterable<number>, imag: Iterable<number>, constraints?: PeriodicWaveConstraints): PeriodicWave;\\n}\\n\\ninterface CSSKeyframesRule {\\n    [Symbol.iterator](): IterableIterator<CSSKeyframeRule>;\\n}\\n\\ninterface CSSNumericArray {\\n    [Symbol.iterator](): IterableIterator<CSSNumericValue>;\\n    entries(): IterableIterator<[number, CSSNumericValue]>;\\n    keys(): IterableIterator<number>;\\n    values(): IterableIterator<CSSNumericValue>;\\n}\\n\\ninterface CSSRuleList {\\n    [Symbol.iterator](): IterableIterator<CSSRule>;\\n}\\n\\ninterface CSSStyleDeclaration {\\n    [Symbol.iterator](): IterableIterator<string>;\\n}\\n\\ninterface CSSTransformValue {\\n    [Symbol.iterator](): IterableIterator<CSSTransformComponent>;\\n    entries(): IterableIterator<[number, CSSTransformComponent]>;\\n    keys(): IterableIterator<number>;\\n    values(): IterableIterator<CSSTransformComponent>;\\n}\\n\\ninterface CSSUnparsedValue {\\n    [Symbol.iterator](): IterableIterator<CSSUnparsedSegment>;\\n    entries(): IterableIterator<[number, CSSUnparsedSegment]>;\\n    keys(): IterableIterator<number>;\\n    values(): IterableIterator<CSSUnparsedSegment>;\\n}\\n\\ninterface Cache {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/addAll) */\\n    addAll(requests: Iterable<RequestInfo>): Promise<void>;\\n}\\n\\ninterface CanvasPath {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/roundRect) */\\n    roundRect(x: number, y: number, w: number, h: number, radii?: number | DOMPointInit | Iterable<number | DOMPointInit>): void;\\n}\\n\\ninterface CanvasPathDrawingStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash) */\\n    setLineDash(segments: Iterable<number>): void;\\n}\\n\\ninterface DOMRectList {\\n    [Symbol.iterator](): IterableIterator<DOMRect>;\\n}\\n\\ninterface DOMStringList {\\n    [Symbol.iterator](): IterableIterator<string>;\\n}\\n\\ninterface DOMTokenList {\\n    [Symbol.iterator](): IterableIterator<string>;\\n    entries(): IterableIterator<[number, string]>;\\n    keys(): IterableIterator<number>;\\n    values(): IterableIterator<string>;\\n}\\n\\ninterface DataTransferItemList {\\n    [Symbol.iterator](): IterableIterator<DataTransferItem>;\\n}\\n\\ninterface EventCounts extends ReadonlyMap<string, number> {\\n}\\n\\ninterface FileList {\\n    [Symbol.iterator](): IterableIterator<File>;\\n}\\n\\ninterface FontFaceSet extends Set<FontFace> {\\n}\\n\\ninterface FormData {\\n    [Symbol.iterator](): IterableIterator<[string, FormDataEntryValue]>;\\n    /** Returns an array of key, value pairs for every entry in the list. */\\n    entries(): IterableIterator<[string, FormDataEntryValue]>;\\n    /** Returns a list of keys in the list. */\\n    keys(): IterableIterator<string>;\\n    /** Returns a list of values in the list. */\\n    values(): IterableIterator<FormDataEntryValue>;\\n}\\n\\ninterface HTMLAllCollection {\\n    [Symbol.iterator](): IterableIterator<Element>;\\n}\\n\\ninterface HTMLCollectionBase {\\n    [Symbol.iterator](): IterableIterator<Element>;\\n}\\n\\ninterface HTMLCollectionOf<T extends Element> {\\n    [Symbol.iterator](): IterableIterator<T>;\\n}\\n\\ninterface HTMLFormElement {\\n    [Symbol.iterator](): IterableIterator<Element>;\\n}\\n\\ninterface HTMLSelectElement {\\n    [Symbol.iterator](): IterableIterator<HTMLOptionElement>;\\n}\\n\\ninterface Headers {\\n    [Symbol.iterator](): IterableIterator<[string, string]>;\\n    /** Returns an iterator allowing to go through all key/value pairs contained in this object. */\\n    entries(): IterableIterator<[string, string]>;\\n    /** Returns an iterator allowing to go through all keys of the key/value pairs contained in this object. */\\n    keys(): IterableIterator<string>;\\n    /** Returns an iterator allowing to go through all values of the key/value pairs contained in this object. */\\n    values(): IterableIterator<string>;\\n}\\n\\ninterface IDBDatabase {\\n    /**\\n     * Returns a new transaction with the given mode (\\\"readonly\\\" or \\\"readwrite\\\") and scope which can be a single object store name or an array of names.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/transaction)\\n     */\\n    transaction(storeNames: string | Iterable<string>, mode?: IDBTransactionMode, options?: IDBTransactionOptions): IDBTransaction;\\n}\\n\\ninterface IDBObjectStore {\\n    /**\\n     * Creates a new index in store with the given name, keyPath and options and returns a new IDBIndex. If the keyPath and options define constraints that cannot be satisfied with the data already in store the upgrade transaction will abort with a \\\"ConstraintError\\\" DOMException.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/createIndex)\\n     */\\n    createIndex(name: string, keyPath: string | Iterable<string>, options?: IDBIndexParameters): IDBIndex;\\n}\\n\\ninterface MIDIInputMap extends ReadonlyMap<string, MIDIInput> {\\n}\\n\\ninterface MIDIOutput {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MIDIOutput/send) */\\n    send(data: Iterable<number>, timestamp?: DOMHighResTimeStamp): void;\\n}\\n\\ninterface MIDIOutputMap extends ReadonlyMap<string, MIDIOutput> {\\n}\\n\\ninterface MediaKeyStatusMap {\\n    [Symbol.iterator](): IterableIterator<[BufferSource, MediaKeyStatus]>;\\n    entries(): IterableIterator<[BufferSource, MediaKeyStatus]>;\\n    keys(): IterableIterator<BufferSource>;\\n    values(): IterableIterator<MediaKeyStatus>;\\n}\\n\\ninterface MediaList {\\n    [Symbol.iterator](): IterableIterator<string>;\\n}\\n\\ninterface MessageEvent<T = any> {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/initMessageEvent)\\n     */\\n    initMessageEvent(type: string, bubbles?: boolean, cancelable?: boolean, data?: any, origin?: string, lastEventId?: string, source?: MessageEventSource | null, ports?: Iterable<MessagePort>): void;\\n}\\n\\ninterface MimeTypeArray {\\n    [Symbol.iterator](): IterableIterator<MimeType>;\\n}\\n\\ninterface NamedNodeMap {\\n    [Symbol.iterator](): IterableIterator<Attr>;\\n}\\n\\ninterface Navigator {\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/requestMediaKeySystemAccess)\\n     */\\n    requestMediaKeySystemAccess(keySystem: string, supportedConfigurations: Iterable<MediaKeySystemConfiguration>): Promise<MediaKeySystemAccess>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/vibrate) */\\n    vibrate(pattern: Iterable<number>): boolean;\\n}\\n\\ninterface NodeList {\\n    [Symbol.iterator](): IterableIterator<Node>;\\n    /** Returns an array of key, value pairs for every entry in the list. */\\n    entries(): IterableIterator<[number, Node]>;\\n    /** Returns an list of keys in the list. */\\n    keys(): IterableIterator<number>;\\n    /** Returns an list of values in the list. */\\n    values(): IterableIterator<Node>;\\n}\\n\\ninterface NodeListOf<TNode extends Node> {\\n    [Symbol.iterator](): IterableIterator<TNode>;\\n    /** Returns an array of key, value pairs for every entry in the list. */\\n    entries(): IterableIterator<[number, TNode]>;\\n    /** Returns an list of keys in the list. */\\n    keys(): IterableIterator<number>;\\n    /** Returns an list of values in the list. */\\n    values(): IterableIterator<TNode>;\\n}\\n\\ninterface Plugin {\\n    [Symbol.iterator](): IterableIterator<MimeType>;\\n}\\n\\ninterface PluginArray {\\n    [Symbol.iterator](): IterableIterator<Plugin>;\\n}\\n\\ninterface RTCRtpTransceiver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/RTCRtpTransceiver/setCodecPreferences) */\\n    setCodecPreferences(codecs: Iterable<RTCRtpCodecCapability>): void;\\n}\\n\\ninterface RTCStatsReport extends ReadonlyMap<string, any> {\\n}\\n\\ninterface SVGLengthList {\\n    [Symbol.iterator](): IterableIterator<SVGLength>;\\n}\\n\\ninterface SVGNumberList {\\n    [Symbol.iterator](): IterableIterator<SVGNumber>;\\n}\\n\\ninterface SVGPointList {\\n    [Symbol.iterator](): IterableIterator<DOMPoint>;\\n}\\n\\ninterface SVGStringList {\\n    [Symbol.iterator](): IterableIterator<string>;\\n}\\n\\ninterface SVGTransformList {\\n    [Symbol.iterator](): IterableIterator<SVGTransform>;\\n}\\n\\ninterface SourceBufferList {\\n    [Symbol.iterator](): IterableIterator<SourceBuffer>;\\n}\\n\\ninterface SpeechRecognitionResult {\\n    [Symbol.iterator](): IterableIterator<SpeechRecognitionAlternative>;\\n}\\n\\ninterface SpeechRecognitionResultList {\\n    [Symbol.iterator](): IterableIterator<SpeechRecognitionResult>;\\n}\\n\\ninterface StylePropertyMapReadOnly {\\n    [Symbol.iterator](): IterableIterator<[string, Iterable<CSSStyleValue>]>;\\n    entries(): IterableIterator<[string, Iterable<CSSStyleValue>]>;\\n    keys(): IterableIterator<string>;\\n    values(): IterableIterator<Iterable<CSSStyleValue>>;\\n}\\n\\ninterface StyleSheetList {\\n    [Symbol.iterator](): IterableIterator<CSSStyleSheet>;\\n}\\n\\ninterface SubtleCrypto {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveKey) */\\n    deriveKey(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | HkdfParams | Pbkdf2Params, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) */\\n    generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKeyPair>;\\n    generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;\\n    generateKey(algorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKeyPair | CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) */\\n    importKey(format: \\\"jwk\\\", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;\\n    importKey(format: Exclude<KeyFormat, \\\"jwk\\\">, keyData: BufferSource, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/unwrapKey) */\\n    unwrapKey(format: KeyFormat, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, unwrappedKeyAlgorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKey>;\\n}\\n\\ninterface TextTrackCueList {\\n    [Symbol.iterator](): IterableIterator<TextTrackCue>;\\n}\\n\\ninterface TextTrackList {\\n    [Symbol.iterator](): IterableIterator<TextTrack>;\\n}\\n\\ninterface TouchList {\\n    [Symbol.iterator](): IterableIterator<Touch>;\\n}\\n\\ninterface URLSearchParams {\\n    [Symbol.iterator](): IterableIterator<[string, string]>;\\n    /** Returns an array of key, value pairs for every entry in the search params. */\\n    entries(): IterableIterator<[string, string]>;\\n    /** Returns a list of keys in the search params. */\\n    keys(): IterableIterator<string>;\\n    /** Returns a list of values in the search params. */\\n    values(): IterableIterator<string>;\\n}\\n\\ninterface WEBGL_draw_buffers {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_draw_buffers/drawBuffersWEBGL) */\\n    drawBuffersWEBGL(buffers: Iterable<GLenum>): void;\\n}\\n\\ninterface WEBGL_multi_draw {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawArraysInstancedWEBGL) */\\n    multiDrawArraysInstancedWEBGL(mode: GLenum, firstsList: Int32Array | Iterable<GLint>, firstsOffset: GLuint, countsList: Int32Array | Iterable<GLsizei>, countsOffset: GLuint, instanceCountsList: Int32Array | Iterable<GLsizei>, instanceCountsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawArraysWEBGL) */\\n    multiDrawArraysWEBGL(mode: GLenum, firstsList: Int32Array | Iterable<GLint>, firstsOffset: GLuint, countsList: Int32Array | Iterable<GLsizei>, countsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawElementsInstancedWEBGL) */\\n    multiDrawElementsInstancedWEBGL(mode: GLenum, countsList: Int32Array | Iterable<GLsizei>, countsOffset: GLuint, type: GLenum, offsetsList: Int32Array | Iterable<GLsizei>, offsetsOffset: GLuint, instanceCountsList: Int32Array | Iterable<GLsizei>, instanceCountsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawElementsWEBGL) */\\n    multiDrawElementsWEBGL(mode: GLenum, countsList: Int32Array | Iterable<GLsizei>, countsOffset: GLuint, type: GLenum, offsetsList: Int32Array | Iterable<GLsizei>, offsetsOffset: GLuint, drawcount: GLsizei): void;\\n}\\n\\ninterface WebGL2RenderingContextBase {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferfv(buffer: GLenum, drawbuffer: GLint, values: Iterable<GLfloat>, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferiv(buffer: GLenum, drawbuffer: GLint, values: Iterable<GLint>, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferuiv(buffer: GLenum, drawbuffer: GLint, values: Iterable<GLuint>, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawBuffers) */\\n    drawBuffers(buffers: Iterable<GLenum>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getActiveUniforms) */\\n    getActiveUniforms(program: WebGLProgram, uniformIndices: Iterable<GLuint>, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getUniformIndices) */\\n    getUniformIndices(program: WebGLProgram, uniformNames: Iterable<string>): Iterable<GLuint> | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/invalidateFramebuffer) */\\n    invalidateFramebuffer(target: GLenum, attachments: Iterable<GLenum>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/invalidateSubFramebuffer) */\\n    invalidateSubFramebuffer(target: GLenum, attachments: Iterable<GLenum>, x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/transformFeedbackVaryings) */\\n    transformFeedbackVaryings(program: WebGLProgram, varyings: Iterable<string>, bufferMode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform1uiv(location: WebGLUniformLocation | null, data: Iterable<GLuint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform2uiv(location: WebGLUniformLocation | null, data: Iterable<GLuint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform3uiv(location: WebGLUniformLocation | null, data: Iterable<GLuint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform4uiv(location: WebGLUniformLocation | null, data: Iterable<GLuint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix2x3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix2x4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix3x2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix3x4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix4x2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix4x3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4iv(index: GLuint, values: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4uiv(index: GLuint, values: Iterable<GLuint>): void;\\n}\\n\\ninterface WebGL2RenderingContextOverloads {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1fv(location: WebGLUniformLocation | null, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1iv(location: WebGLUniformLocation | null, data: Iterable<GLint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2fv(location: WebGLUniformLocation | null, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2iv(location: WebGLUniformLocation | null, data: Iterable<GLint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3fv(location: WebGLUniformLocation | null, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3iv(location: WebGLUniformLocation | null, data: Iterable<GLint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4fv(location: WebGLUniformLocation | null, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4iv(location: WebGLUniformLocation | null, data: Iterable<GLint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n}\\n\\ninterface WebGLRenderingContextBase {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib1fv(index: GLuint, values: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib2fv(index: GLuint, values: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib3fv(index: GLuint, values: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib4fv(index: GLuint, values: Iterable<GLfloat>): void;\\n}\\n\\ninterface WebGLRenderingContextOverloads {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.collection.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Map<K, V> {\\n    clear(): void;\\n    /**\\n     * @returns true if an element in the Map existed and has been removed, or false if the element does not exist.\\n     */\\n    delete(key: K): boolean;\\n    /**\\n     * Executes a provided function once per each key/value pair in the Map, in insertion order.\\n     */\\n    forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;\\n    /**\\n     * Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.\\n     * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.\\n     */\\n    get(key: K): V | undefined;\\n    /**\\n     * @returns boolean indicating whether an element with the specified key exists or not.\\n     */\\n    has(key: K): boolean;\\n    /**\\n     * Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.\\n     */\\n    set(key: K, value: V): this;\\n    /**\\n     * @returns the number of elements in the Map.\\n     */\\n    readonly size: number;\\n}\\n\\ninterface MapConstructor {\\n    new (): Map<any, any>;\\n    new <K, V>(entries?: readonly (readonly [K, V])[] | null): Map<K, V>;\\n    readonly prototype: Map<any, any>;\\n}\\ndeclare var Map: MapConstructor;\\n\\ninterface ReadonlyMap<K, V> {\\n    forEach(callbackfn: (value: V, key: K, map: ReadonlyMap<K, V>) => void, thisArg?: any): void;\\n    get(key: K): V | undefined;\\n    has(key: K): boolean;\\n    readonly size: number;\\n}\\n\\ninterface WeakMap<K extends WeakKey, V> {\\n    /**\\n     * Removes the specified element from the WeakMap.\\n     * @returns true if the element was successfully removed, or false if it was not present.\\n     */\\n    delete(key: K): boolean;\\n    /**\\n     * @returns a specified element.\\n     */\\n    get(key: K): V | undefined;\\n    /**\\n     * @returns a boolean indicating whether an element with the specified key exists or not.\\n     */\\n    has(key: K): boolean;\\n    /**\\n     * Adds a new element with a specified key and value.\\n     * @param key Must be an object or symbol.\\n     */\\n    set(key: K, value: V): this;\\n}\\n\\ninterface WeakMapConstructor {\\n    new <K extends WeakKey = WeakKey, V = any>(entries?: readonly (readonly [K, V])[] | null): WeakMap<K, V>;\\n    readonly prototype: WeakMap<WeakKey, any>;\\n}\\ndeclare var WeakMap: WeakMapConstructor;\\n\\ninterface Set<T> {\\n    /**\\n     * Appends a new element with a specified value to the end of the Set.\\n     */\\n    add(value: T): this;\\n\\n    clear(): void;\\n    /**\\n     * Removes a specified value from the Set.\\n     * @returns Returns true if an element in the Set existed and has been removed, or false if the element does not exist.\\n     */\\n    delete(value: T): boolean;\\n    /**\\n     * Executes a provided function once per each value in the Set object, in insertion order.\\n     */\\n    forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: any): void;\\n    /**\\n     * @returns a boolean indicating whether an element with the specified value exists in the Set or not.\\n     */\\n    has(value: T): boolean;\\n    /**\\n     * @returns the number of (unique) elements in Set.\\n     */\\n    readonly size: number;\\n}\\n\\ninterface SetConstructor {\\n    new <T = any>(values?: readonly T[] | null): Set<T>;\\n    readonly prototype: Set<any>;\\n}\\ndeclare var Set: SetConstructor;\\n\\ninterface ReadonlySet<T> {\\n    forEach(callbackfn: (value: T, value2: T, set: ReadonlySet<T>) => void, thisArg?: any): void;\\n    has(value: T): boolean;\\n    readonly size: number;\\n}\\n\\ninterface WeakSet<T extends WeakKey> {\\n    /**\\n     * Appends a new value to the end of the WeakSet.\\n     */\\n    add(value: T): this;\\n    /**\\n     * Removes the specified element from the WeakSet.\\n     * @returns Returns true if the element existed and has been removed, or false if the element does not exist.\\n     */\\n    delete(value: T): boolean;\\n    /**\\n     * @returns a boolean indicating whether a value exists in the WeakSet or not.\\n     */\\n    has(value: T): boolean;\\n}\\n\\ninterface WeakSetConstructor {\\n    new <T extends WeakKey = WeakKey>(values?: readonly T[] | null): WeakSet<T>;\\n    readonly prototype: WeakSet<WeakKey>;\\n}\\ndeclare var WeakSet: WeakSetConstructor;\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.core.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Array<T> {\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find<S extends T>(predicate: (value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;\\n    find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: T, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n}\\n\\ninterface ArrayConstructor {\\n    /**\\n     * Creates an array from an array-like object.\\n     * @param arrayLike An array-like object to convert to an array.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>): T[];\\n\\n    /**\\n     * Creates an array from an iterable object.\\n     * @param arrayLike An array-like object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of<T>(...items: T[]): T[];\\n}\\n\\ninterface DateConstructor {\\n    new (value: number | string | Date): Date;\\n}\\n\\ninterface Function {\\n    /**\\n     * Returns the name of the function. Function names are read-only and can not be changed.\\n     */\\n    readonly name: string;\\n}\\n\\ninterface Math {\\n    /**\\n     * Returns the number of leading zero bits in the 32-bit binary representation of a number.\\n     * @param x A numeric expression.\\n     */\\n    clz32(x: number): number;\\n\\n    /**\\n     * Returns the result of 32-bit multiplication of two numbers.\\n     * @param x First number\\n     * @param y Second number\\n     */\\n    imul(x: number, y: number): number;\\n\\n    /**\\n     * Returns the sign of the x, indicating whether x is positive, negative or zero.\\n     * @param x The numeric expression to test\\n     */\\n    sign(x: number): number;\\n\\n    /**\\n     * Returns the base 10 logarithm of a number.\\n     * @param x A numeric expression.\\n     */\\n    log10(x: number): number;\\n\\n    /**\\n     * Returns the base 2 logarithm of a number.\\n     * @param x A numeric expression.\\n     */\\n    log2(x: number): number;\\n\\n    /**\\n     * Returns the natural logarithm of 1 + x.\\n     * @param x A numeric expression.\\n     */\\n    log1p(x: number): number;\\n\\n    /**\\n     * Returns the result of (e^x - 1), which is an implementation-dependent approximation to\\n     * subtracting 1 from the exponential function of x (e raised to the power of x, where e\\n     * is the base of the natural logarithms).\\n     * @param x A numeric expression.\\n     */\\n    expm1(x: number): number;\\n\\n    /**\\n     * Returns the hyperbolic cosine of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    cosh(x: number): number;\\n\\n    /**\\n     * Returns the hyperbolic sine of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    sinh(x: number): number;\\n\\n    /**\\n     * Returns the hyperbolic tangent of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    tanh(x: number): number;\\n\\n    /**\\n     * Returns the inverse hyperbolic cosine of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    acosh(x: number): number;\\n\\n    /**\\n     * Returns the inverse hyperbolic sine of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    asinh(x: number): number;\\n\\n    /**\\n     * Returns the inverse hyperbolic tangent of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    atanh(x: number): number;\\n\\n    /**\\n     * Returns the square root of the sum of squares of its arguments.\\n     * @param values Values to compute the square root for.\\n     *     If no arguments are passed, the result is +0.\\n     *     If there is only one argument, the result is the absolute value.\\n     *     If any argument is +Infinity or -Infinity, the result is +Infinity.\\n     *     If any argument is NaN, the result is NaN.\\n     *     If all arguments are either +0 or −0, the result is +0.\\n     */\\n    hypot(...values: number[]): number;\\n\\n    /**\\n     * Returns the integral part of the a numeric expression, x, removing any fractional digits.\\n     * If x is already an integer, the result is x.\\n     * @param x A numeric expression.\\n     */\\n    trunc(x: number): number;\\n\\n    /**\\n     * Returns the nearest single precision float representation of a number.\\n     * @param x A numeric expression.\\n     */\\n    fround(x: number): number;\\n\\n    /**\\n     * Returns an implementation-dependent approximation to the cube root of number.\\n     * @param x A numeric expression.\\n     */\\n    cbrt(x: number): number;\\n}\\n\\ninterface NumberConstructor {\\n    /**\\n     * The value of Number.EPSILON is the difference between 1 and the smallest value greater than 1\\n     * that is representable as a Number value, which is approximately:\\n     * 2.2204460492503130808472633361816 x 10‍−‍16.\\n     */\\n    readonly EPSILON: number;\\n\\n    /**\\n     * Returns true if passed value is finite.\\n     * Unlike the global isFinite, Number.isFinite doesn't forcibly convert the parameter to a\\n     * number. Only finite values of the type number, result in true.\\n     * @param number A numeric value.\\n     */\\n    isFinite(number: unknown): boolean;\\n\\n    /**\\n     * Returns true if the value passed is an integer, false otherwise.\\n     * @param number A numeric value.\\n     */\\n    isInteger(number: unknown): boolean;\\n\\n    /**\\n     * Returns a Boolean value that indicates whether a value is the reserved value NaN (not a\\n     * number). Unlike the global isNaN(), Number.isNaN() doesn't forcefully convert the parameter\\n     * to a number. Only values of the type number, that are also NaN, result in true.\\n     * @param number A numeric value.\\n     */\\n    isNaN(number: unknown): boolean;\\n\\n    /**\\n     * Returns true if the value passed is a safe integer.\\n     * @param number A numeric value.\\n     */\\n    isSafeInteger(number: unknown): boolean;\\n\\n    /**\\n     * The value of the largest integer n such that n and n + 1 are both exactly representable as\\n     * a Number value.\\n     * The value of Number.MAX_SAFE_INTEGER is 9007199254740991 2^53 − 1.\\n     */\\n    readonly MAX_SAFE_INTEGER: number;\\n\\n    /**\\n     * The value of the smallest integer n such that n and n − 1 are both exactly representable as\\n     * a Number value.\\n     * The value of Number.MIN_SAFE_INTEGER is −9007199254740991 (−(2^53 − 1)).\\n     */\\n    readonly MIN_SAFE_INTEGER: number;\\n\\n    /**\\n     * Converts a string to a floating-point number.\\n     * @param string A string that contains a floating-point number.\\n     */\\n    parseFloat(string: string): number;\\n\\n    /**\\n     * Converts A string to an integer.\\n     * @param string A string to convert into a number.\\n     * @param radix A value between 2 and 36 that specifies the base of the number in `string`.\\n     * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\\n     * All other strings are considered decimal.\\n     */\\n    parseInt(string: string, radix?: number): number;\\n}\\n\\ninterface ObjectConstructor {\\n    /**\\n     * Copy the values of all of the enumerable own properties from one or more source objects to a\\n     * target object. Returns the target object.\\n     * @param target The target object to copy to.\\n     * @param source The source object from which to copy properties.\\n     */\\n    assign<T extends {}, U>(target: T, source: U): T & U;\\n\\n    /**\\n     * Copy the values of all of the enumerable own properties from one or more source objects to a\\n     * target object. Returns the target object.\\n     * @param target The target object to copy to.\\n     * @param source1 The first source object from which to copy properties.\\n     * @param source2 The second source object from which to copy properties.\\n     */\\n    assign<T extends {}, U, V>(target: T, source1: U, source2: V): T & U & V;\\n\\n    /**\\n     * Copy the values of all of the enumerable own properties from one or more source objects to a\\n     * target object. Returns the target object.\\n     * @param target The target object to copy to.\\n     * @param source1 The first source object from which to copy properties.\\n     * @param source2 The second source object from which to copy properties.\\n     * @param source3 The third source object from which to copy properties.\\n     */\\n    assign<T extends {}, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W;\\n\\n    /**\\n     * Copy the values of all of the enumerable own properties from one or more source objects to a\\n     * target object. Returns the target object.\\n     * @param target The target object to copy to.\\n     * @param sources One or more source objects from which to copy properties\\n     */\\n    assign(target: object, ...sources: any[]): any;\\n\\n    /**\\n     * Returns an array of all symbol properties found directly on object o.\\n     * @param o Object to retrieve the symbols from.\\n     */\\n    getOwnPropertySymbols(o: any): symbol[];\\n\\n    /**\\n     * Returns the names of the enumerable string properties and methods of an object.\\n     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.\\n     */\\n    keys(o: {}): string[];\\n\\n    /**\\n     * Returns true if the values are the same value, false otherwise.\\n     * @param value1 The first value.\\n     * @param value2 The second value.\\n     */\\n    is(value1: any, value2: any): boolean;\\n\\n    /**\\n     * Sets the prototype of a specified object o to object proto or null. Returns the object o.\\n     * @param o The object to change its prototype.\\n     * @param proto The value of the new prototype or null.\\n     */\\n    setPrototypeOf(o: any, proto: object | null): any;\\n}\\n\\ninterface ReadonlyArray<T> {\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find<S extends T>(predicate: (value: T, index: number, obj: readonly T[]) => value is S, thisArg?: any): S | undefined;\\n    find(predicate: (value: T, index: number, obj: readonly T[]) => unknown, thisArg?: any): T | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: T, index: number, obj: readonly T[]) => unknown, thisArg?: any): number;\\n}\\n\\ninterface RegExp {\\n    /**\\n     * Returns a string indicating the flags of the regular expression in question. This field is read-only.\\n     * The characters in this string are sequenced and concatenated in the following order:\\n     *\\n     *    - \\\"g\\\" for global\\n     *    - \\\"i\\\" for ignoreCase\\n     *    - \\\"m\\\" for multiline\\n     *    - \\\"u\\\" for unicode\\n     *    - \\\"y\\\" for sticky\\n     *\\n     * If no flags are set, the value is the empty string.\\n     */\\n    readonly flags: string;\\n\\n    /**\\n     * Returns a Boolean value indicating the state of the sticky flag (y) used with a regular\\n     * expression. Default is false. Read-only.\\n     */\\n    readonly sticky: boolean;\\n\\n    /**\\n     * Returns a Boolean value indicating the state of the Unicode flag (u) used with a regular\\n     * expression. Default is false. Read-only.\\n     */\\n    readonly unicode: boolean;\\n}\\n\\ninterface RegExpConstructor {\\n    new (pattern: RegExp | string, flags?: string): RegExp;\\n    (pattern: RegExp | string, flags?: string): RegExp;\\n}\\n\\ninterface String {\\n    /**\\n     * Returns a nonnegative integer Number less than 1114112 (0x110000) that is the code point\\n     * value of the UTF-16 encoded code point starting at the string element at position pos in\\n     * the String resulting from converting this object to a String.\\n     * If there is no element at that position, the result is undefined.\\n     * If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos.\\n     */\\n    codePointAt(pos: number): number | undefined;\\n\\n    /**\\n     * Returns true if searchString appears as a substring of the result of converting this\\n     * object to a String, at one or more positions that are\\n     * greater than or equal to position; otherwise, returns false.\\n     * @param searchString search string\\n     * @param position If position is undefined, 0 is assumed, so as to search all of the String.\\n     */\\n    includes(searchString: string, position?: number): boolean;\\n\\n    /**\\n     * Returns true if the sequence of elements of searchString converted to a String is the\\n     * same as the corresponding elements of this object (converted to a String) starting at\\n     * endPosition – length(this). Otherwise returns false.\\n     */\\n    endsWith(searchString: string, endPosition?: number): boolean;\\n\\n    /**\\n     * Returns the String value result of normalizing the string into the normalization form\\n     * named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms.\\n     * @param form Applicable values: \\\"NFC\\\", \\\"NFD\\\", \\\"NFKC\\\", or \\\"NFKD\\\", If not specified default\\n     * is \\\"NFC\\\"\\n     */\\n    normalize(form: \\\"NFC\\\" | \\\"NFD\\\" | \\\"NFKC\\\" | \\\"NFKD\\\"): string;\\n\\n    /**\\n     * Returns the String value result of normalizing the string into the normalization form\\n     * named by form as specified in Unicode Standard Annex #15, Unicode Normalization Forms.\\n     * @param form Applicable values: \\\"NFC\\\", \\\"NFD\\\", \\\"NFKC\\\", or \\\"NFKD\\\", If not specified default\\n     * is \\\"NFC\\\"\\n     */\\n    normalize(form?: string): string;\\n\\n    /**\\n     * Returns a String value that is made from count copies appended together. If count is 0,\\n     * the empty string is returned.\\n     * @param count number of copies to append\\n     */\\n    repeat(count: number): string;\\n\\n    /**\\n     * Returns true if the sequence of elements of searchString converted to a String is the\\n     * same as the corresponding elements of this object (converted to a String) starting at\\n     * position. Otherwise returns false.\\n     */\\n    startsWith(searchString: string, position?: number): boolean;\\n\\n    /**\\n     * Returns an `<a>` HTML anchor element and sets the name attribute to the text value\\n     * @deprecated A legacy feature for browser compatibility\\n     * @param name\\n     */\\n    anchor(name: string): string;\\n\\n    /**\\n     * Returns a `<big>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    big(): string;\\n\\n    /**\\n     * Returns a `<blink>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    blink(): string;\\n\\n    /**\\n     * Returns a `<b>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    bold(): string;\\n\\n    /**\\n     * Returns a `<tt>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    fixed(): string;\\n\\n    /**\\n     * Returns a `<font>` HTML element and sets the color attribute value\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    fontcolor(color: string): string;\\n\\n    /**\\n     * Returns a `<font>` HTML element and sets the size attribute value\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    fontsize(size: number): string;\\n\\n    /**\\n     * Returns a `<font>` HTML element and sets the size attribute value\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    fontsize(size: string): string;\\n\\n    /**\\n     * Returns an `<i>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    italics(): string;\\n\\n    /**\\n     * Returns an `<a>` HTML element and sets the href attribute value\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    link(url: string): string;\\n\\n    /**\\n     * Returns a `<small>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    small(): string;\\n\\n    /**\\n     * Returns a `<strike>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    strike(): string;\\n\\n    /**\\n     * Returns a `<sub>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    sub(): string;\\n\\n    /**\\n     * Returns a `<sup>` HTML element\\n     * @deprecated A legacy feature for browser compatibility\\n     */\\n    sup(): string;\\n}\\n\\ninterface StringConstructor {\\n    /**\\n     * Return the String value whose elements are, in order, the elements in the List elements.\\n     * If length is 0, the empty string is returned.\\n     */\\n    fromCodePoint(...codePoints: number[]): string;\\n\\n    /**\\n     * String.raw is usually used as a tag function of a Tagged Template String. When called as\\n     * such, the first argument will be a well formed template call site object and the rest\\n     * parameter will contain the substitution values. It can also be called directly, for example,\\n     * to interleave strings and values from your own tag function, and in this case the only thing\\n     * it needs from the first argument is the raw property.\\n     * @param template A well-formed template string call site representation.\\n     * @param substitutions A set of substitution values.\\n     */\\n    raw(template: { raw: readonly string[] | ArrayLike<string>; }, ...substitutions: any[]): string;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es5\\\" />\\n/// <reference lib=\\\"es2015.core\\\" />\\n/// <reference lib=\\\"es2015.collection\\\" />\\n/// <reference lib=\\\"es2015.iterable\\\" />\\n/// <reference lib=\\\"es2015.generator\\\" />\\n/// <reference lib=\\\"es2015.promise\\\" />\\n/// <reference lib=\\\"es2015.proxy\\\" />\\n/// <reference lib=\\\"es2015.reflect\\\" />\\n/// <reference lib=\\\"es2015.symbol\\\" />\\n/// <reference lib=\\\"es2015.symbol.wellknown\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.generator.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.iterable\\\" />\\n\\ninterface Generator<T = unknown, TReturn = any, TNext = unknown> extends Iterator<T, TReturn, TNext> {\\n    // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.\\n    next(...args: [] | [TNext]): IteratorResult<T, TReturn>;\\n    return(value: TReturn): IteratorResult<T, TReturn>;\\n    throw(e: any): IteratorResult<T, TReturn>;\\n    [Symbol.iterator](): Generator<T, TReturn, TNext>;\\n}\\n\\ninterface GeneratorFunction {\\n    /**\\n     * Creates a new Generator object.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    new (...args: any[]): Generator;\\n    /**\\n     * Creates a new Generator object.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    (...args: any[]): Generator;\\n    /**\\n     * The length of the arguments.\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the name of the function.\\n     */\\n    readonly name: string;\\n    /**\\n     * A reference to the prototype.\\n     */\\n    readonly prototype: Generator;\\n}\\n\\ninterface GeneratorFunctionConstructor {\\n    /**\\n     * Creates a new Generator function.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    new (...args: string[]): GeneratorFunction;\\n    /**\\n     * Creates a new Generator function.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    (...args: string[]): GeneratorFunction;\\n    /**\\n     * The length of the arguments.\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the name of the function.\\n     */\\n    readonly name: string;\\n    /**\\n     * A reference to the prototype.\\n     */\\n    readonly prototype: GeneratorFunction;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.iterable.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.symbol\\\" />\\n\\ninterface SymbolConstructor {\\n    /**\\n     * A method that returns the default iterator for an object. Called by the semantics of the\\n     * for-of statement.\\n     */\\n    readonly iterator: unique symbol;\\n}\\n\\ninterface IteratorYieldResult<TYield> {\\n    done?: false;\\n    value: TYield;\\n}\\n\\ninterface IteratorReturnResult<TReturn> {\\n    done: true;\\n    value: TReturn;\\n}\\n\\ntype IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;\\n\\ninterface Iterator<T, TReturn = any, TNext = undefined> {\\n    // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.\\n    next(...args: [] | [TNext]): IteratorResult<T, TReturn>;\\n    return?(value?: TReturn): IteratorResult<T, TReturn>;\\n    throw?(e?: any): IteratorResult<T, TReturn>;\\n}\\n\\ninterface Iterable<T> {\\n    [Symbol.iterator](): Iterator<T>;\\n}\\n\\ninterface IterableIterator<T> extends Iterator<T> {\\n    [Symbol.iterator](): IterableIterator<T>;\\n}\\n\\ninterface Array<T> {\\n    /** Iterator */\\n    [Symbol.iterator](): IterableIterator<T>;\\n\\n    /**\\n     * Returns an iterable of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, T]>;\\n\\n    /**\\n     * Returns an iterable of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n\\n    /**\\n     * Returns an iterable of values in the array\\n     */\\n    values(): IterableIterator<T>;\\n}\\n\\ninterface ArrayConstructor {\\n    /**\\n     * Creates an array from an iterable object.\\n     * @param iterable An iterable object to convert to an array.\\n     */\\n    from<T>(iterable: Iterable<T> | ArrayLike<T>): T[];\\n\\n    /**\\n     * Creates an array from an iterable object.\\n     * @param iterable An iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];\\n}\\n\\ninterface ReadonlyArray<T> {\\n    /** Iterator of values in the array. */\\n    [Symbol.iterator](): IterableIterator<T>;\\n\\n    /**\\n     * Returns an iterable of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, T]>;\\n\\n    /**\\n     * Returns an iterable of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n\\n    /**\\n     * Returns an iterable of values in the array\\n     */\\n    values(): IterableIterator<T>;\\n}\\n\\ninterface IArguments {\\n    /** Iterator */\\n    [Symbol.iterator](): IterableIterator<any>;\\n}\\n\\ninterface Map<K, V> {\\n    /** Returns an iterable of entries in the map. */\\n    [Symbol.iterator](): IterableIterator<[K, V]>;\\n\\n    /**\\n     * Returns an iterable of key, value pairs for every entry in the map.\\n     */\\n    entries(): IterableIterator<[K, V]>;\\n\\n    /**\\n     * Returns an iterable of keys in the map\\n     */\\n    keys(): IterableIterator<K>;\\n\\n    /**\\n     * Returns an iterable of values in the map\\n     */\\n    values(): IterableIterator<V>;\\n}\\n\\ninterface ReadonlyMap<K, V> {\\n    /** Returns an iterable of entries in the map. */\\n    [Symbol.iterator](): IterableIterator<[K, V]>;\\n\\n    /**\\n     * Returns an iterable of key, value pairs for every entry in the map.\\n     */\\n    entries(): IterableIterator<[K, V]>;\\n\\n    /**\\n     * Returns an iterable of keys in the map\\n     */\\n    keys(): IterableIterator<K>;\\n\\n    /**\\n     * Returns an iterable of values in the map\\n     */\\n    values(): IterableIterator<V>;\\n}\\n\\ninterface MapConstructor {\\n    new (): Map<any, any>;\\n    new <K, V>(iterable?: Iterable<readonly [K, V]> | null): Map<K, V>;\\n}\\n\\ninterface WeakMap<K extends WeakKey, V> {}\\n\\ninterface WeakMapConstructor {\\n    new <K extends WeakKey, V>(iterable: Iterable<readonly [K, V]>): WeakMap<K, V>;\\n}\\n\\ninterface Set<T> {\\n    /** Iterates over values in the set. */\\n    [Symbol.iterator](): IterableIterator<T>;\\n    /**\\n     * Returns an iterable of [v,v] pairs for every value `v` in the set.\\n     */\\n    entries(): IterableIterator<[T, T]>;\\n    /**\\n     * Despite its name, returns an iterable of the values in the set.\\n     */\\n    keys(): IterableIterator<T>;\\n\\n    /**\\n     * Returns an iterable of values in the set.\\n     */\\n    values(): IterableIterator<T>;\\n}\\n\\ninterface ReadonlySet<T> {\\n    /** Iterates over values in the set. */\\n    [Symbol.iterator](): IterableIterator<T>;\\n\\n    /**\\n     * Returns an iterable of [v,v] pairs for every value `v` in the set.\\n     */\\n    entries(): IterableIterator<[T, T]>;\\n\\n    /**\\n     * Despite its name, returns an iterable of the values in the set.\\n     */\\n    keys(): IterableIterator<T>;\\n\\n    /**\\n     * Returns an iterable of values in the set.\\n     */\\n    values(): IterableIterator<T>;\\n}\\n\\ninterface SetConstructor {\\n    new <T>(iterable?: Iterable<T> | null): Set<T>;\\n}\\n\\ninterface WeakSet<T extends WeakKey> {}\\n\\ninterface WeakSetConstructor {\\n    new <T extends WeakKey = WeakKey>(iterable: Iterable<T>): WeakSet<T>;\\n}\\n\\ninterface Promise<T> {}\\n\\ninterface PromiseConstructor {\\n    /**\\n     * Creates a Promise that is resolved with an array of results when all of the provided Promises\\n     * resolve, or rejected when any Promise is rejected.\\n     * @param values An iterable of Promises.\\n     * @returns A new Promise.\\n     */\\n    all<T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>;\\n\\n    /**\\n     * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved\\n     * or rejected.\\n     * @param values An iterable of Promises.\\n     * @returns A new Promise.\\n     */\\n    race<T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>>;\\n}\\n\\ninterface String {\\n    /** Iterator */\\n    [Symbol.iterator](): IterableIterator<string>;\\n}\\n\\ninterface Int8Array {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Int8ArrayConstructor {\\n    new (elements: Iterable<number>): Int8Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int8Array;\\n}\\n\\ninterface Uint8Array {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Uint8ArrayConstructor {\\n    new (elements: Iterable<number>): Uint8Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Uint8Array;\\n}\\n\\ninterface Uint8ClampedArray {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Uint8ClampedArrayConstructor {\\n    new (elements: Iterable<number>): Uint8ClampedArray;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Uint8ClampedArray;\\n}\\n\\ninterface Int16Array {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Int16ArrayConstructor {\\n    new (elements: Iterable<number>): Int16Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int16Array;\\n}\\n\\ninterface Uint16Array {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Uint16ArrayConstructor {\\n    new (elements: Iterable<number>): Uint16Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Uint16Array;\\n}\\n\\ninterface Int32Array {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Int32ArrayConstructor {\\n    new (elements: Iterable<number>): Int32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Int32Array;\\n}\\n\\ninterface Uint32Array {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Uint32ArrayConstructor {\\n    new (elements: Iterable<number>): Uint32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Uint32Array;\\n}\\n\\ninterface Float32Array {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Float32ArrayConstructor {\\n    new (elements: Iterable<number>): Float32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Float32Array;\\n}\\n\\ninterface Float64Array {\\n    [Symbol.iterator](): IterableIterator<number>;\\n    /**\\n     * Returns an array of key, value pairs for every entry in the array\\n     */\\n    entries(): IterableIterator<[number, number]>;\\n    /**\\n     * Returns an list of keys in the array\\n     */\\n    keys(): IterableIterator<number>;\\n    /**\\n     * Returns an list of values in the array\\n     */\\n    values(): IterableIterator<number>;\\n}\\n\\ninterface Float64ArrayConstructor {\\n    new (elements: Iterable<number>): Float64Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Float64Array;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.promise.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface PromiseConstructor {\\n    /**\\n     * A reference to the prototype.\\n     */\\n    readonly prototype: Promise<any>;\\n\\n    /**\\n     * Creates a new Promise.\\n     * @param executor A callback used to initialize the promise. This callback is passed two arguments:\\n     * a resolve callback used to resolve the promise with a value or the result of another promise,\\n     * and a reject callback used to reject the promise with a provided reason or error.\\n     */\\n    new <T>(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;\\n\\n    /**\\n     * Creates a Promise that is resolved with an array of results when all of the provided Promises\\n     * resolve, or rejected when any Promise is rejected.\\n     * @param values An array of Promises.\\n     * @returns A new Promise.\\n     */\\n    all<T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]>; }>;\\n\\n    // see: lib.es2015.iterable.d.ts\\n    // all<T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>;\\n\\n    /**\\n     * Creates a Promise that is resolved or rejected when any of the provided Promises are resolved\\n     * or rejected.\\n     * @param values An array of Promises.\\n     * @returns A new Promise.\\n     */\\n    race<T extends readonly unknown[] | []>(values: T): Promise<Awaited<T[number]>>;\\n\\n    // see: lib.es2015.iterable.d.ts\\n    // race<T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>>;\\n\\n    /**\\n     * Creates a new rejected promise for the provided reason.\\n     * @param reason The reason the promise was rejected.\\n     * @returns A new rejected Promise.\\n     */\\n    reject<T = never>(reason?: any): Promise<T>;\\n\\n    /**\\n     * Creates a new resolved promise.\\n     * @returns A resolved promise.\\n     */\\n    resolve(): Promise<void>;\\n    /**\\n     * Creates a new resolved promise for the provided value.\\n     * @param value A promise.\\n     * @returns A promise whose internal state matches the provided promise.\\n     */\\n    resolve<T>(value: T): Promise<Awaited<T>>;\\n    /**\\n     * Creates a new resolved promise for the provided value.\\n     * @param value A promise.\\n     * @returns A promise whose internal state matches the provided promise.\\n     */\\n    resolve<T>(value: T | PromiseLike<T>): Promise<Awaited<T>>;\\n}\\n\\ndeclare var Promise: PromiseConstructor;\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.proxy.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface ProxyHandler<T extends object> {\\n    /**\\n     * A trap method for a function call.\\n     * @param target The original callable object which is being proxied.\\n     */\\n    apply?(target: T, thisArg: any, argArray: any[]): any;\\n\\n    /**\\n     * A trap for the `new` operator.\\n     * @param target The original object which is being proxied.\\n     * @param newTarget The constructor that was originally called.\\n     */\\n    construct?(target: T, argArray: any[], newTarget: Function): object;\\n\\n    /**\\n     * A trap for `Object.defineProperty()`.\\n     * @param target The original object which is being proxied.\\n     * @returns A `Boolean` indicating whether or not the property has been defined.\\n     */\\n    defineProperty?(target: T, property: string | symbol, attributes: PropertyDescriptor): boolean;\\n\\n    /**\\n     * A trap for the `delete` operator.\\n     * @param target The original object which is being proxied.\\n     * @param p The name or `Symbol` of the property to delete.\\n     * @returns A `Boolean` indicating whether or not the property was deleted.\\n     */\\n    deleteProperty?(target: T, p: string | symbol): boolean;\\n\\n    /**\\n     * A trap for getting a property value.\\n     * @param target The original object which is being proxied.\\n     * @param p The name or `Symbol` of the property to get.\\n     * @param receiver The proxy or an object that inherits from the proxy.\\n     */\\n    get?(target: T, p: string | symbol, receiver: any): any;\\n\\n    /**\\n     * A trap for `Object.getOwnPropertyDescriptor()`.\\n     * @param target The original object which is being proxied.\\n     * @param p The name of the property whose description should be retrieved.\\n     */\\n    getOwnPropertyDescriptor?(target: T, p: string | symbol): PropertyDescriptor | undefined;\\n\\n    /**\\n     * A trap for the `[[GetPrototypeOf]]` internal method.\\n     * @param target The original object which is being proxied.\\n     */\\n    getPrototypeOf?(target: T): object | null;\\n\\n    /**\\n     * A trap for the `in` operator.\\n     * @param target The original object which is being proxied.\\n     * @param p The name or `Symbol` of the property to check for existence.\\n     */\\n    has?(target: T, p: string | symbol): boolean;\\n\\n    /**\\n     * A trap for `Object.isExtensible()`.\\n     * @param target The original object which is being proxied.\\n     */\\n    isExtensible?(target: T): boolean;\\n\\n    /**\\n     * A trap for `Reflect.ownKeys()`.\\n     * @param target The original object which is being proxied.\\n     */\\n    ownKeys?(target: T): ArrayLike<string | symbol>;\\n\\n    /**\\n     * A trap for `Object.preventExtensions()`.\\n     * @param target The original object which is being proxied.\\n     */\\n    preventExtensions?(target: T): boolean;\\n\\n    /**\\n     * A trap for setting a property value.\\n     * @param target The original object which is being proxied.\\n     * @param p The name or `Symbol` of the property to set.\\n     * @param receiver The object to which the assignment was originally directed.\\n     * @returns A `Boolean` indicating whether or not the property was set.\\n     */\\n    set?(target: T, p: string | symbol, newValue: any, receiver: any): boolean;\\n\\n    /**\\n     * A trap for `Object.setPrototypeOf()`.\\n     * @param target The original object which is being proxied.\\n     * @param newPrototype The object's new prototype or `null`.\\n     */\\n    setPrototypeOf?(target: T, v: object | null): boolean;\\n}\\n\\ninterface ProxyConstructor {\\n    /**\\n     * Creates a revocable Proxy object.\\n     * @param target A target object to wrap with Proxy.\\n     * @param handler An object whose properties define the behavior of Proxy when an operation is attempted on it.\\n     */\\n    revocable<T extends object>(target: T, handler: ProxyHandler<T>): { proxy: T; revoke: () => void; };\\n\\n    /**\\n     * Creates a Proxy object. The Proxy object allows you to create an object that can be used in place of the\\n     * original object, but which may redefine fundamental Object operations like getting, setting, and defining\\n     * properties. Proxy objects are commonly used to log property accesses, validate, format, or sanitize inputs.\\n     * @param target A target object to wrap with Proxy.\\n     * @param handler An object whose properties define the behavior of Proxy when an operation is attempted on it.\\n     */\\n    new <T extends object>(target: T, handler: ProxyHandler<T>): T;\\n}\\ndeclare var Proxy: ProxyConstructor;\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.reflect.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ndeclare namespace Reflect {\\n    /**\\n     * Calls the function with the specified object as the this value\\n     * and the elements of specified array as the arguments.\\n     * @param target The function to call.\\n     * @param thisArgument The object to be used as the this object.\\n     * @param argumentsList An array of argument values to be passed to the function.\\n     */\\n    function apply<T, A extends readonly any[], R>(\\n        target: (this: T, ...args: A) => R,\\n        thisArgument: T,\\n        argumentsList: Readonly<A>,\\n    ): R;\\n    function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;\\n\\n    /**\\n     * Constructs the target with the elements of specified array as the arguments\\n     * and the specified constructor as the `new.target` value.\\n     * @param target The constructor to invoke.\\n     * @param argumentsList An array of argument values to be passed to the constructor.\\n     * @param newTarget The constructor to be used as the `new.target` object.\\n     */\\n    function construct<A extends readonly any[], R>(\\n        target: new (...args: A) => R,\\n        argumentsList: Readonly<A>,\\n        newTarget?: new (...args: any) => any,\\n    ): R;\\n    function construct(target: Function, argumentsList: ArrayLike<any>, newTarget?: Function): any;\\n\\n    /**\\n     * Adds a property to an object, or modifies attributes of an existing property.\\n     * @param target Object on which to add or modify the property. This can be a native JavaScript object\\n     *        (that is, a user-defined object or a built in object) or a DOM object.\\n     * @param propertyKey The property name.\\n     * @param attributes Descriptor for the property. It can be for a data property or an accessor property.\\n     */\\n    function defineProperty(target: object, propertyKey: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): boolean;\\n\\n    /**\\n     * Removes a property from an object, equivalent to `delete target[propertyKey]`,\\n     * except it won't throw if `target[propertyKey]` is non-configurable.\\n     * @param target Object from which to remove the own property.\\n     * @param propertyKey The property name.\\n     */\\n    function deleteProperty(target: object, propertyKey: PropertyKey): boolean;\\n\\n    /**\\n     * Gets the property of target, equivalent to `target[propertyKey]` when `receiver === target`.\\n     * @param target Object that contains the property on itself or in its prototype chain.\\n     * @param propertyKey The property name.\\n     * @param receiver The reference to use as the `this` value in the getter function,\\n     *        if `target[propertyKey]` is an accessor property.\\n     */\\n    function get<T extends object, P extends PropertyKey>(\\n        target: T,\\n        propertyKey: P,\\n        receiver?: unknown,\\n    ): P extends keyof T ? T[P] : any;\\n\\n    /**\\n     * Gets the own property descriptor of the specified object.\\n     * An own property descriptor is one that is defined directly on the object and is not inherited from the object's prototype.\\n     * @param target Object that contains the property.\\n     * @param propertyKey The property name.\\n     */\\n    function getOwnPropertyDescriptor<T extends object, P extends PropertyKey>(\\n        target: T,\\n        propertyKey: P,\\n    ): TypedPropertyDescriptor<P extends keyof T ? T[P] : any> | undefined;\\n\\n    /**\\n     * Returns the prototype of an object.\\n     * @param target The object that references the prototype.\\n     */\\n    function getPrototypeOf(target: object): object | null;\\n\\n    /**\\n     * Equivalent to `propertyKey in target`.\\n     * @param target Object that contains the property on itself or in its prototype chain.\\n     * @param propertyKey Name of the property.\\n     */\\n    function has(target: object, propertyKey: PropertyKey): boolean;\\n\\n    /**\\n     * Returns a value that indicates whether new properties can be added to an object.\\n     * @param target Object to test.\\n     */\\n    function isExtensible(target: object): boolean;\\n\\n    /**\\n     * Returns the string and symbol keys of the own properties of an object. The own properties of an object\\n     * are those that are defined directly on that object, and are not inherited from the object's prototype.\\n     * @param target Object that contains the own properties.\\n     */\\n    function ownKeys(target: object): (string | symbol)[];\\n\\n    /**\\n     * Prevents the addition of new properties to an object.\\n     * @param target Object to make non-extensible.\\n     * @return Whether the object has been made non-extensible.\\n     */\\n    function preventExtensions(target: object): boolean;\\n\\n    /**\\n     * Sets the property of target, equivalent to `target[propertyKey] = value` when `receiver === target`.\\n     * @param target Object that contains the property on itself or in its prototype chain.\\n     * @param propertyKey Name of the property.\\n     * @param receiver The reference to use as the `this` value in the setter function,\\n     *        if `target[propertyKey]` is an accessor property.\\n     */\\n    function set<T extends object, P extends PropertyKey>(\\n        target: T,\\n        propertyKey: P,\\n        value: P extends keyof T ? T[P] : any,\\n        receiver?: any,\\n    ): boolean;\\n    function set(target: object, propertyKey: PropertyKey, value: any, receiver?: any): boolean;\\n\\n    /**\\n     * Sets the prototype of a specified object o to object proto or null.\\n     * @param target The object to change its prototype.\\n     * @param proto The value of the new prototype or null.\\n     * @return Whether setting the prototype was successful.\\n     */\\n    function setPrototypeOf(target: object, proto: object | null): boolean;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.symbol.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface SymbolConstructor {\\n    /**\\n     * A reference to the prototype.\\n     */\\n    readonly prototype: Symbol;\\n\\n    /**\\n     * Returns a new unique Symbol value.\\n     * @param  description Description of the new Symbol object.\\n     */\\n    (description?: string | number): symbol;\\n\\n    /**\\n     * Returns a Symbol object from the global symbol registry matching the given key if found.\\n     * Otherwise, returns a new symbol with this key.\\n     * @param key key to search for.\\n     */\\n    for(key: string): symbol;\\n\\n    /**\\n     * Returns a key from the global symbol registry matching the given Symbol if found.\\n     * Otherwise, returns a undefined.\\n     * @param sym Symbol to find the key for.\\n     */\\n    keyFor(sym: symbol): string | undefined;\\n}\\n\\ndeclare var Symbol: SymbolConstructor;\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2015.symbol.wellknown.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.symbol\\\" />\\n\\ninterface SymbolConstructor {\\n    /**\\n     * A method that determines if a constructor object recognizes an object as one of the\\n     * constructor’s instances. Called by the semantics of the instanceof operator.\\n     */\\n    readonly hasInstance: unique symbol;\\n\\n    /**\\n     * A Boolean value that if true indicates that an object should flatten to its array elements\\n     * by Array.prototype.concat.\\n     */\\n    readonly isConcatSpreadable: unique symbol;\\n\\n    /**\\n     * A regular expression method that matches the regular expression against a string. Called\\n     * by the String.prototype.match method.\\n     */\\n    readonly match: unique symbol;\\n\\n    /**\\n     * A regular expression method that replaces matched substrings of a string. Called by the\\n     * String.prototype.replace method.\\n     */\\n    readonly replace: unique symbol;\\n\\n    /**\\n     * A regular expression method that returns the index within a string that matches the\\n     * regular expression. Called by the String.prototype.search method.\\n     */\\n    readonly search: unique symbol;\\n\\n    /**\\n     * A function valued property that is the constructor function that is used to create\\n     * derived objects.\\n     */\\n    readonly species: unique symbol;\\n\\n    /**\\n     * A regular expression method that splits a string at the indices that match the regular\\n     * expression. Called by the String.prototype.split method.\\n     */\\n    readonly split: unique symbol;\\n\\n    /**\\n     * A method that converts an object to a corresponding primitive value.\\n     * Called by the ToPrimitive abstract operation.\\n     */\\n    readonly toPrimitive: unique symbol;\\n\\n    /**\\n     * A String value that is used in the creation of the default string description of an object.\\n     * Called by the built-in method Object.prototype.toString.\\n     */\\n    readonly toStringTag: unique symbol;\\n\\n    /**\\n     * An Object whose truthy properties are properties that are excluded from the 'with'\\n     * environment bindings of the associated objects.\\n     */\\n    readonly unscopables: unique symbol;\\n}\\n\\ninterface Symbol {\\n    /**\\n     * Converts a Symbol object to a symbol.\\n     */\\n    [Symbol.toPrimitive](hint: string): symbol;\\n\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface Array<T> {\\n    /**\\n     * Is an object whose properties have the value 'true'\\n     * when they will be absent when used in a 'with' statement.\\n     */\\n    readonly [Symbol.unscopables]: {\\n        [K in keyof any[]]?: boolean;\\n    };\\n}\\n\\ninterface ReadonlyArray<T> {\\n    /**\\n     * Is an object whose properties have the value 'true'\\n     * when they will be absent when used in a 'with' statement.\\n     */\\n    readonly [Symbol.unscopables]: {\\n        [K in keyof readonly any[]]?: boolean;\\n    };\\n}\\n\\ninterface Date {\\n    /**\\n     * Converts a Date object to a string.\\n     */\\n    [Symbol.toPrimitive](hint: \\\"default\\\"): string;\\n    /**\\n     * Converts a Date object to a string.\\n     */\\n    [Symbol.toPrimitive](hint: \\\"string\\\"): string;\\n    /**\\n     * Converts a Date object to a number.\\n     */\\n    [Symbol.toPrimitive](hint: \\\"number\\\"): number;\\n    /**\\n     * Converts a Date object to a string or number.\\n     *\\n     * @param hint The strings \\\"number\\\", \\\"string\\\", or \\\"default\\\" to specify what primitive to return.\\n     *\\n     * @throws {TypeError} If 'hint' was given something other than \\\"number\\\", \\\"string\\\", or \\\"default\\\".\\n     * @returns A number if 'hint' was \\\"number\\\", a string if 'hint' was \\\"string\\\" or \\\"default\\\".\\n     */\\n    [Symbol.toPrimitive](hint: string): string | number;\\n}\\n\\ninterface Map<K, V> {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface WeakMap<K extends WeakKey, V> {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface Set<T> {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface WeakSet<T extends WeakKey> {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface JSON {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface Function {\\n    /**\\n     * Determines whether the given value inherits from this function if this function was used\\n     * as a constructor function.\\n     *\\n     * A constructor function can control which objects are recognized as its instances by\\n     * 'instanceof' by overriding this method.\\n     */\\n    [Symbol.hasInstance](value: any): boolean;\\n}\\n\\ninterface GeneratorFunction {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface Math {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface Promise<T> {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface PromiseConstructor {\\n    readonly [Symbol.species]: PromiseConstructor;\\n}\\n\\ninterface RegExp {\\n    /**\\n     * Matches a string with this regular expression, and returns an array containing the results of\\n     * that search.\\n     * @param string A string to search within.\\n     */\\n    [Symbol.match](string: string): RegExpMatchArray | null;\\n\\n    /**\\n     * Replaces text in a string, using this regular expression.\\n     * @param string A String object or string literal whose contents matching against\\n     *               this regular expression will be replaced\\n     * @param replaceValue A String object or string literal containing the text to replace for every\\n     *                     successful match of this regular expression.\\n     */\\n    [Symbol.replace](string: string, replaceValue: string): string;\\n\\n    /**\\n     * Replaces text in a string, using this regular expression.\\n     * @param string A String object or string literal whose contents matching against\\n     *               this regular expression will be replaced\\n     * @param replacer A function that returns the replacement text.\\n     */\\n    [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;\\n\\n    /**\\n     * Finds the position beginning first substring match in a regular expression search\\n     * using this regular expression.\\n     *\\n     * @param string The string to search within.\\n     */\\n    [Symbol.search](string: string): number;\\n\\n    /**\\n     * Returns an array of substrings that were delimited by strings in the original input that\\n     * match against this regular expression.\\n     *\\n     * If the regular expression contains capturing parentheses, then each time this\\n     * regular expression matches, the results (including any undefined results) of the\\n     * capturing parentheses are spliced.\\n     *\\n     * @param string string value to split\\n     * @param limit if not undefined, the output array is truncated so that it contains no more\\n     * than 'limit' elements.\\n     */\\n    [Symbol.split](string: string, limit?: number): string[];\\n}\\n\\ninterface RegExpConstructor {\\n    readonly [Symbol.species]: RegExpConstructor;\\n}\\n\\ninterface String {\\n    /**\\n     * Matches a string or an object that supports being matched against, and returns an array\\n     * containing the results of that search, or null if no matches are found.\\n     * @param matcher An object that supports being matched against.\\n     */\\n    match(matcher: { [Symbol.match](string: string): RegExpMatchArray | null; }): RegExpMatchArray | null;\\n\\n    /**\\n     * Passes a string and {@linkcode replaceValue} to the `[Symbol.replace]` method on {@linkcode searchValue}. This method is expected to implement its own replacement algorithm.\\n     * @param searchValue An object that supports searching for and replacing matches within a string.\\n     * @param replaceValue The replacement text.\\n     */\\n    replace(searchValue: { [Symbol.replace](string: string, replaceValue: string): string; }, replaceValue: string): string;\\n\\n    /**\\n     * Replaces text in a string, using an object that supports replacement within a string.\\n     * @param searchValue A object can search for and replace matches within a string.\\n     * @param replacer A function that returns the replacement text.\\n     */\\n    replace(searchValue: { [Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string; }, replacer: (substring: string, ...args: any[]) => string): string;\\n\\n    /**\\n     * Finds the first substring match in a regular expression search.\\n     * @param searcher An object which supports searching within a string.\\n     */\\n    search(searcher: { [Symbol.search](string: string): number; }): number;\\n\\n    /**\\n     * Split a string into substrings using the specified separator and return them as an array.\\n     * @param splitter An object that can split a string.\\n     * @param limit A value used to limit the number of elements returned in the array.\\n     */\\n    split(splitter: { [Symbol.split](string: string, limit?: number): string[]; }, limit?: number): string[];\\n}\\n\\ninterface ArrayBuffer {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface DataView {\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface Int8Array {\\n    readonly [Symbol.toStringTag]: \\\"Int8Array\\\";\\n}\\n\\ninterface Uint8Array {\\n    readonly [Symbol.toStringTag]: \\\"Uint8Array\\\";\\n}\\n\\ninterface Uint8ClampedArray {\\n    readonly [Symbol.toStringTag]: \\\"Uint8ClampedArray\\\";\\n}\\n\\ninterface Int16Array {\\n    readonly [Symbol.toStringTag]: \\\"Int16Array\\\";\\n}\\n\\ninterface Uint16Array {\\n    readonly [Symbol.toStringTag]: \\\"Uint16Array\\\";\\n}\\n\\ninterface Int32Array {\\n    readonly [Symbol.toStringTag]: \\\"Int32Array\\\";\\n}\\n\\ninterface Uint32Array {\\n    readonly [Symbol.toStringTag]: \\\"Uint32Array\\\";\\n}\\n\\ninterface Float32Array {\\n    readonly [Symbol.toStringTag]: \\\"Float32Array\\\";\\n}\\n\\ninterface Float64Array {\\n    readonly [Symbol.toStringTag]: \\\"Float64Array\\\";\\n}\\n\\ninterface ArrayConstructor {\\n    readonly [Symbol.species]: ArrayConstructor;\\n}\\ninterface MapConstructor {\\n    readonly [Symbol.species]: MapConstructor;\\n}\\ninterface SetConstructor {\\n    readonly [Symbol.species]: SetConstructor;\\n}\\ninterface ArrayBufferConstructor {\\n    readonly [Symbol.species]: ArrayBufferConstructor;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2016.array.include.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Array<T> {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: T, fromIndex?: number): boolean;\\n}\\n\\ninterface ReadonlyArray<T> {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: T, fromIndex?: number): boolean;\\n}\\n\\ninterface Int8Array {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\\ninterface Uint8Array {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\\ninterface Uint8ClampedArray {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\\ninterface Int16Array {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\\ninterface Uint16Array {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\\ninterface Int32Array {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\\ninterface Uint32Array {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\\ninterface Float32Array {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\\ninterface Float64Array {\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: number, fromIndex?: number): boolean;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2016.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015\\\" />\\n/// <reference lib=\\\"es2016.array.include\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2016.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2016\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2017.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2016\\\" />\\n/// <reference lib=\\\"es2017.object\\\" />\\n/// <reference lib=\\\"es2017.sharedmemory\\\" />\\n/// <reference lib=\\\"es2017.string\\\" />\\n/// <reference lib=\\\"es2017.intl\\\" />\\n/// <reference lib=\\\"es2017.typedarrays\\\" />\\n/// <reference lib=\\\"es2017.date\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2017.date.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface DateConstructor {\\n    /**\\n     * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date.\\n     * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.\\n     * @param monthIndex The month as a number between 0 and 11 (January to December).\\n     * @param date The date as a number between 1 and 31.\\n     * @param hours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour.\\n     * @param minutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes.\\n     * @param seconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds.\\n     * @param ms A number from 0 to 999 that specifies the milliseconds.\\n     */\\n    UTC(year: number, monthIndex?: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2017.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2017\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2017.intl.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ndeclare namespace Intl {\\n    interface DateTimeFormatPartTypesRegistry {\\n        day: any;\\n        dayPeriod: any;\\n        era: any;\\n        hour: any;\\n        literal: any;\\n        minute: any;\\n        month: any;\\n        second: any;\\n        timeZoneName: any;\\n        weekday: any;\\n        year: any;\\n    }\\n\\n    type DateTimeFormatPartTypes = keyof DateTimeFormatPartTypesRegistry;\\n\\n    interface DateTimeFormatPart {\\n        type: DateTimeFormatPartTypes;\\n        value: string;\\n    }\\n\\n    interface DateTimeFormat {\\n        formatToParts(date?: Date | number): DateTimeFormatPart[];\\n    }\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2017.object.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface ObjectConstructor {\\n    /**\\n     * Returns an array of values of the enumerable properties of an object\\n     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.\\n     */\\n    values<T>(o: { [s: string]: T; } | ArrayLike<T>): T[];\\n\\n    /**\\n     * Returns an array of values of the enumerable properties of an object\\n     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.\\n     */\\n    values(o: {}): any[];\\n\\n    /**\\n     * Returns an array of key/values of the enumerable properties of an object\\n     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.\\n     */\\n    entries<T>(o: { [s: string]: T; } | ArrayLike<T>): [string, T][];\\n\\n    /**\\n     * Returns an array of key/values of the enumerable properties of an object\\n     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.\\n     */\\n    entries(o: {}): [string, any][];\\n\\n    /**\\n     * Returns an object containing all own property descriptors of an object\\n     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.\\n     */\\n    getOwnPropertyDescriptors<T>(o: T): { [P in keyof T]: TypedPropertyDescriptor<T[P]>; } & { [x: string]: PropertyDescriptor; };\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2017.sharedmemory.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.symbol\\\" />\\n/// <reference lib=\\\"es2015.symbol.wellknown\\\" />\\n\\ninterface SharedArrayBuffer {\\n    /**\\n     * Read-only. The length of the ArrayBuffer (in bytes).\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * Returns a section of an SharedArrayBuffer.\\n     */\\n    slice(begin: number, end?: number): SharedArrayBuffer;\\n    readonly [Symbol.species]: SharedArrayBuffer;\\n    readonly [Symbol.toStringTag]: \\\"SharedArrayBuffer\\\";\\n}\\n\\ninterface SharedArrayBufferConstructor {\\n    readonly prototype: SharedArrayBuffer;\\n    new (byteLength: number): SharedArrayBuffer;\\n}\\ndeclare var SharedArrayBuffer: SharedArrayBufferConstructor;\\n\\ninterface ArrayBufferTypes {\\n    SharedArrayBuffer: SharedArrayBuffer;\\n}\\n\\ninterface Atomics {\\n    /**\\n     * Adds a value to the value at the given position in the array, returning the original value.\\n     * Until this atomic operation completes, any other read or write operation against the array\\n     * will block.\\n     */\\n    add(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;\\n\\n    /**\\n     * Stores the bitwise AND of a value with the value at the given position in the array,\\n     * returning the original value. Until this atomic operation completes, any other read or\\n     * write operation against the array will block.\\n     */\\n    and(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;\\n\\n    /**\\n     * Replaces the value at the given position in the array if the original value equals the given\\n     * expected value, returning the original value. Until this atomic operation completes, any\\n     * other read or write operation against the array will block.\\n     */\\n    compareExchange(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, expectedValue: number, replacementValue: number): number;\\n\\n    /**\\n     * Replaces the value at the given position in the array, returning the original value. Until\\n     * this atomic operation completes, any other read or write operation against the array will\\n     * block.\\n     */\\n    exchange(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;\\n\\n    /**\\n     * Returns a value indicating whether high-performance algorithms can use atomic operations\\n     * (`true`) or must use locks (`false`) for the given number of bytes-per-element of a typed\\n     * array.\\n     */\\n    isLockFree(size: number): boolean;\\n\\n    /**\\n     * Returns the value at the given position in the array. Until this atomic operation completes,\\n     * any other read or write operation against the array will block.\\n     */\\n    load(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number): number;\\n\\n    /**\\n     * Stores the bitwise OR of a value with the value at the given position in the array,\\n     * returning the original value. Until this atomic operation completes, any other read or write\\n     * operation against the array will block.\\n     */\\n    or(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;\\n\\n    /**\\n     * Stores a value at the given position in the array, returning the new value. Until this\\n     * atomic operation completes, any other read or write operation against the array will block.\\n     */\\n    store(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;\\n\\n    /**\\n     * Subtracts a value from the value at the given position in the array, returning the original\\n     * value. Until this atomic operation completes, any other read or write operation against the\\n     * array will block.\\n     */\\n    sub(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;\\n\\n    /**\\n     * If the value at the given position in the array is equal to the provided value, the current\\n     * agent is put to sleep causing execution to suspend until the timeout expires (returning\\n     * `\\\"timed-out\\\"`) or until the agent is awoken (returning `\\\"ok\\\"`); otherwise, returns\\n     * `\\\"not-equal\\\"`.\\n     */\\n    wait(typedArray: Int32Array, index: number, value: number, timeout?: number): \\\"ok\\\" | \\\"not-equal\\\" | \\\"timed-out\\\";\\n\\n    /**\\n     * Wakes up sleeping agents that are waiting on the given index of the array, returning the\\n     * number of agents that were awoken.\\n     * @param typedArray A shared Int32Array.\\n     * @param index The position in the typedArray to wake up on.\\n     * @param count The number of sleeping agents to notify. Defaults to +Infinity.\\n     */\\n    notify(typedArray: Int32Array, index: number, count?: number): number;\\n\\n    /**\\n     * Stores the bitwise XOR of a value with the value at the given position in the array,\\n     * returning the original value. Until this atomic operation completes, any other read or write\\n     * operation against the array will block.\\n     */\\n    xor(typedArray: Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array, index: number, value: number): number;\\n\\n    readonly [Symbol.toStringTag]: \\\"Atomics\\\";\\n}\\n\\ndeclare var Atomics: Atomics;\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2017.string.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface String {\\n    /**\\n     * Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length.\\n     * The padding is applied from the start (left) of the current string.\\n     *\\n     * @param maxLength The length of the resulting string once the current string has been padded.\\n     *        If this parameter is smaller than the current string's length, the current string will be returned as it is.\\n     *\\n     * @param fillString The string to pad the current string with.\\n     *        If this string is too long, it will be truncated and the left-most part will be applied.\\n     *        The default value for this parameter is \\\" \\\" (U+0020).\\n     */\\n    padStart(maxLength: number, fillString?: string): string;\\n\\n    /**\\n     * Pads the current string with a given string (possibly repeated) so that the resulting string reaches a given length.\\n     * The padding is applied from the end (right) of the current string.\\n     *\\n     * @param maxLength The length of the resulting string once the current string has been padded.\\n     *        If this parameter is smaller than the current string's length, the current string will be returned as it is.\\n     *\\n     * @param fillString The string to pad the current string with.\\n     *        If this string is too long, it will be truncated and the left-most part will be applied.\\n     *        The default value for this parameter is \\\" \\\" (U+0020).\\n     */\\n    padEnd(maxLength: number, fillString?: string): string;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2017.typedarrays.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Int8ArrayConstructor {\\n    new (): Int8Array;\\n}\\n\\ninterface Uint8ArrayConstructor {\\n    new (): Uint8Array;\\n}\\n\\ninterface Uint8ClampedArrayConstructor {\\n    new (): Uint8ClampedArray;\\n}\\n\\ninterface Int16ArrayConstructor {\\n    new (): Int16Array;\\n}\\n\\ninterface Uint16ArrayConstructor {\\n    new (): Uint16Array;\\n}\\n\\ninterface Int32ArrayConstructor {\\n    new (): Int32Array;\\n}\\n\\ninterface Uint32ArrayConstructor {\\n    new (): Uint32Array;\\n}\\n\\ninterface Float32ArrayConstructor {\\n    new (): Float32Array;\\n}\\n\\ninterface Float64ArrayConstructor {\\n    new (): Float64Array;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2018.asyncgenerator.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2018.asynciterable\\\" />\\n\\ninterface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> extends AsyncIterator<T, TReturn, TNext> {\\n    // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.\\n    next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;\\n    return(value: TReturn | PromiseLike<TReturn>): Promise<IteratorResult<T, TReturn>>;\\n    throw(e: any): Promise<IteratorResult<T, TReturn>>;\\n    [Symbol.asyncIterator](): AsyncGenerator<T, TReturn, TNext>;\\n}\\n\\ninterface AsyncGeneratorFunction {\\n    /**\\n     * Creates a new AsyncGenerator object.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    new (...args: any[]): AsyncGenerator;\\n    /**\\n     * Creates a new AsyncGenerator object.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    (...args: any[]): AsyncGenerator;\\n    /**\\n     * The length of the arguments.\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the name of the function.\\n     */\\n    readonly name: string;\\n    /**\\n     * A reference to the prototype.\\n     */\\n    readonly prototype: AsyncGenerator;\\n}\\n\\ninterface AsyncGeneratorFunctionConstructor {\\n    /**\\n     * Creates a new AsyncGenerator function.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    new (...args: string[]): AsyncGeneratorFunction;\\n    /**\\n     * Creates a new AsyncGenerator function.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    (...args: string[]): AsyncGeneratorFunction;\\n    /**\\n     * The length of the arguments.\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns the name of the function.\\n     */\\n    readonly name: string;\\n    /**\\n     * A reference to the prototype.\\n     */\\n    readonly prototype: AsyncGeneratorFunction;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2018.asynciterable.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.symbol\\\" />\\n/// <reference lib=\\\"es2015.iterable\\\" />\\n\\ninterface SymbolConstructor {\\n    /**\\n     * A method that returns the default async iterator for an object. Called by the semantics of\\n     * the for-await-of statement.\\n     */\\n    readonly asyncIterator: unique symbol;\\n}\\n\\ninterface AsyncIterator<T, TReturn = any, TNext = undefined> {\\n    // NOTE: 'next' is defined using a tuple to ensure we report the correct assignability errors in all places.\\n    next(...args: [] | [TNext]): Promise<IteratorResult<T, TReturn>>;\\n    return?(value?: TReturn | PromiseLike<TReturn>): Promise<IteratorResult<T, TReturn>>;\\n    throw?(e?: any): Promise<IteratorResult<T, TReturn>>;\\n}\\n\\ninterface AsyncIterable<T> {\\n    [Symbol.asyncIterator](): AsyncIterator<T>;\\n}\\n\\ninterface AsyncIterableIterator<T> extends AsyncIterator<T> {\\n    [Symbol.asyncIterator](): AsyncIterableIterator<T>;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2018.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2017\\\" />\\n/// <reference lib=\\\"es2018.asynciterable\\\" />\\n/// <reference lib=\\\"es2018.asyncgenerator\\\" />\\n/// <reference lib=\\\"es2018.promise\\\" />\\n/// <reference lib=\\\"es2018.regexp\\\" />\\n/// <reference lib=\\\"es2018.intl\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2018.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2018\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2018.intl.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ndeclare namespace Intl {\\n    // http://cldr.unicode.org/index/cldr-spec/plural-rules#TOC-Determining-Plural-Categories\\n    type LDMLPluralRule = \\\"zero\\\" | \\\"one\\\" | \\\"two\\\" | \\\"few\\\" | \\\"many\\\" | \\\"other\\\";\\n    type PluralRuleType = \\\"cardinal\\\" | \\\"ordinal\\\";\\n\\n    interface PluralRulesOptions {\\n        localeMatcher?: \\\"lookup\\\" | \\\"best fit\\\" | undefined;\\n        type?: PluralRuleType | undefined;\\n        minimumIntegerDigits?: number | undefined;\\n        minimumFractionDigits?: number | undefined;\\n        maximumFractionDigits?: number | undefined;\\n        minimumSignificantDigits?: number | undefined;\\n        maximumSignificantDigits?: number | undefined;\\n    }\\n\\n    interface ResolvedPluralRulesOptions {\\n        locale: string;\\n        pluralCategories: LDMLPluralRule[];\\n        type: PluralRuleType;\\n        minimumIntegerDigits: number;\\n        minimumFractionDigits: number;\\n        maximumFractionDigits: number;\\n        minimumSignificantDigits?: number;\\n        maximumSignificantDigits?: number;\\n    }\\n\\n    interface PluralRules {\\n        resolvedOptions(): ResolvedPluralRulesOptions;\\n        select(n: number): LDMLPluralRule;\\n    }\\n\\n    const PluralRules: {\\n        new (locales?: string | string[], options?: PluralRulesOptions): PluralRules;\\n        (locales?: string | string[], options?: PluralRulesOptions): PluralRules;\\n\\n        supportedLocalesOf(locales: string | string[], options?: { localeMatcher?: \\\"lookup\\\" | \\\"best fit\\\"; }): string[];\\n    };\\n\\n    // We can only have one definition for 'type' in TypeScript, and so you can learn where the keys come from here:\\n    type ES2018NumberFormatPartType = \\\"literal\\\" | \\\"nan\\\" | \\\"infinity\\\" | \\\"percent\\\" | \\\"integer\\\" | \\\"group\\\" | \\\"decimal\\\" | \\\"fraction\\\" | \\\"plusSign\\\" | \\\"minusSign\\\" | \\\"percentSign\\\" | \\\"currency\\\" | \\\"code\\\" | \\\"symbol\\\" | \\\"name\\\";\\n    type ES2020NumberFormatPartType = \\\"compact\\\" | \\\"exponentInteger\\\" | \\\"exponentMinusSign\\\" | \\\"exponentSeparator\\\" | \\\"unit\\\" | \\\"unknown\\\";\\n    type NumberFormatPartTypes = ES2018NumberFormatPartType | ES2020NumberFormatPartType;\\n\\n    interface NumberFormatPart {\\n        type: NumberFormatPartTypes;\\n        value: string;\\n    }\\n\\n    interface NumberFormat {\\n        formatToParts(number?: number | bigint): NumberFormatPart[];\\n    }\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2018.promise.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/**\\n * Represents the completion of an asynchronous operation\\n */\\ninterface Promise<T> {\\n    /**\\n     * Attaches a callback that is invoked when the Promise is settled (fulfilled or rejected). The\\n     * resolved value cannot be modified from the callback.\\n     * @param onfinally The callback to execute when the Promise is settled (fulfilled or rejected).\\n     * @returns A Promise for the completion of the callback.\\n     */\\n    finally(onfinally?: (() => void) | undefined | null): Promise<T>;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2018.regexp.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface RegExpMatchArray {\\n    groups?: {\\n        [key: string]: string;\\n    };\\n}\\n\\ninterface RegExpExecArray {\\n    groups?: {\\n        [key: string]: string;\\n    };\\n}\\n\\ninterface RegExp {\\n    /**\\n     * Returns a Boolean value indicating the state of the dotAll flag (s) used with a regular expression.\\n     * Default is false. Read-only.\\n     */\\n    readonly dotAll: boolean;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2019.array.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ntype FlatArray<Arr, Depth extends number> = {\\n    done: Arr;\\n    recur: Arr extends ReadonlyArray<infer InnerArr> ? FlatArray<InnerArr, [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][Depth]>\\n        : Arr;\\n}[Depth extends -1 ? \\\"done\\\" : \\\"recur\\\"];\\n\\ninterface ReadonlyArray<T> {\\n    /**\\n     * Calls a defined callback function on each element of an array. Then, flattens the result into\\n     * a new array.\\n     * This is identical to a map followed by flat with depth 1.\\n     *\\n     * @param callback A function that accepts up to three arguments. The flatMap method calls the\\n     * callback function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callback function. If\\n     * thisArg is omitted, undefined is used as the this value.\\n     */\\n    flatMap<U, This = undefined>(\\n        callback: (this: This, value: T, index: number, array: T[]) => U | ReadonlyArray<U>,\\n        thisArg?: This,\\n    ): U[];\\n\\n    /**\\n     * Returns a new array with all sub-array elements concatenated into it recursively up to the\\n     * specified depth.\\n     *\\n     * @param depth The maximum recursion depth\\n     */\\n    flat<A, D extends number = 1>(\\n        this: A,\\n        depth?: D,\\n    ): FlatArray<A, D>[];\\n}\\n\\ninterface Array<T> {\\n    /**\\n     * Calls a defined callback function on each element of an array. Then, flattens the result into\\n     * a new array.\\n     * This is identical to a map followed by flat with depth 1.\\n     *\\n     * @param callback A function that accepts up to three arguments. The flatMap method calls the\\n     * callback function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callback function. If\\n     * thisArg is omitted, undefined is used as the this value.\\n     */\\n    flatMap<U, This = undefined>(\\n        callback: (this: This, value: T, index: number, array: T[]) => U | ReadonlyArray<U>,\\n        thisArg?: This,\\n    ): U[];\\n\\n    /**\\n     * Returns a new array with all sub-array elements concatenated into it recursively up to the\\n     * specified depth.\\n     *\\n     * @param depth The maximum recursion depth\\n     */\\n    flat<A, D extends number = 1>(\\n        this: A,\\n        depth?: D,\\n    ): FlatArray<A, D>[];\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2019.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2018\\\" />\\n/// <reference lib=\\\"es2019.array\\\" />\\n/// <reference lib=\\\"es2019.object\\\" />\\n/// <reference lib=\\\"es2019.string\\\" />\\n/// <reference lib=\\\"es2019.symbol\\\" />\\n/// <reference lib=\\\"es2019.intl\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2019.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2019\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2019.intl.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ndeclare namespace Intl {\\n    interface DateTimeFormatPartTypesRegistry {\\n        unknown: any;\\n    }\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2019.object.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.iterable\\\" />\\n\\ninterface ObjectConstructor {\\n    /**\\n     * Returns an object created by key-value entries for properties and methods\\n     * @param entries An iterable object that contains key-value entries for properties and methods.\\n     */\\n    fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: string]: T; };\\n\\n    /**\\n     * Returns an object created by key-value entries for properties and methods\\n     * @param entries An iterable object that contains key-value entries for properties and methods.\\n     */\\n    fromEntries(entries: Iterable<readonly any[]>): any;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2019.string.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface String {\\n    /** Removes the trailing white space and line terminator characters from a string. */\\n    trimEnd(): string;\\n\\n    /** Removes the leading white space and line terminator characters from a string. */\\n    trimStart(): string;\\n\\n    /**\\n     * Removes the leading white space and line terminator characters from a string.\\n     * @deprecated A legacy feature for browser compatibility. Use `trimStart` instead\\n     */\\n    trimLeft(): string;\\n\\n    /**\\n     * Removes the trailing white space and line terminator characters from a string.\\n     * @deprecated A legacy feature for browser compatibility. Use `trimEnd` instead\\n     */\\n    trimRight(): string;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2019.symbol.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Symbol {\\n    /**\\n     * Expose the [[Description]] internal slot of a symbol directly.\\n     */\\n    readonly description: string | undefined;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.bigint.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2020.intl\\\" />\\n\\ninterface BigIntToLocaleStringOptions {\\n    /**\\n     * The locale matching algorithm to use.The default is \\\"best fit\\\". For information about this option, see the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_negotiation Intl page}.\\n     */\\n    localeMatcher?: string;\\n    /**\\n     * The formatting style to use , the default is \\\"decimal\\\".\\n     */\\n    style?: string;\\n\\n    numberingSystem?: string;\\n    /**\\n     * The unit to use in unit formatting, Possible values are core unit identifiers, defined in UTS #35, Part 2, Section 6. A subset of units from the full list was selected for use in ECMAScript. Pairs of simple units can be concatenated with \\\"-per-\\\" to make a compound unit. There is no default value; if the style is \\\"unit\\\", the unit property must be provided.\\n     */\\n    unit?: string;\\n\\n    /**\\n     * The unit formatting style to use in unit formatting, the defaults is \\\"short\\\".\\n     */\\n    unitDisplay?: string;\\n\\n    /**\\n     * The currency to use in currency formatting. Possible values are the ISO 4217 currency codes, such as \\\"USD\\\" for the US dollar, \\\"EUR\\\" for the euro, or \\\"CNY\\\" for the Chinese RMB — see the Current currency & funds code list. There is no default value; if the style is \\\"currency\\\", the currency property must be provided. It is only used when [[Style]] has the value \\\"currency\\\".\\n     */\\n    currency?: string;\\n\\n    /**\\n     * How to display the currency in currency formatting. It is only used when [[Style]] has the value \\\"currency\\\". The default is \\\"symbol\\\".\\n     *\\n     * \\\"symbol\\\" to use a localized currency symbol such as €,\\n     *\\n     * \\\"code\\\" to use the ISO currency code,\\n     *\\n     * \\\"name\\\" to use a localized currency name such as \\\"dollar\\\"\\n     */\\n    currencyDisplay?: string;\\n\\n    /**\\n     * Whether to use grouping separators, such as thousands separators or thousand/lakh/crore separators. The default is true.\\n     */\\n    useGrouping?: boolean;\\n\\n    /**\\n     * The minimum number of integer digits to use. Possible values are from 1 to 21; the default is 1.\\n     */\\n    minimumIntegerDigits?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21;\\n\\n    /**\\n     * The minimum number of fraction digits to use. Possible values are from 0 to 20; the default for plain number and percent formatting is 0; the default for currency formatting is the number of minor unit digits provided by the {@link http://www.currency-iso.org/en/home/tables/table-a1.html ISO 4217 currency codes list} (2 if the list doesn't provide that information).\\n     */\\n    minimumFractionDigits?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20;\\n\\n    /**\\n     * The maximum number of fraction digits to use. Possible values are from 0 to 20; the default for plain number formatting is the larger of minimumFractionDigits and 3; the default for currency formatting is the larger of minimumFractionDigits and the number of minor unit digits provided by the {@link http://www.currency-iso.org/en/home/tables/table-a1.html ISO 4217 currency codes list} (2 if the list doesn't provide that information); the default for percent formatting is the larger of minimumFractionDigits and 0.\\n     */\\n    maximumFractionDigits?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20;\\n\\n    /**\\n     * The minimum number of significant digits to use. Possible values are from 1 to 21; the default is 1.\\n     */\\n    minimumSignificantDigits?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21;\\n\\n    /**\\n     * The maximum number of significant digits to use. Possible values are from 1 to 21; the default is 21.\\n     */\\n    maximumSignificantDigits?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21;\\n\\n    /**\\n     * The formatting that should be displayed for the number, the defaults is \\\"standard\\\"\\n     *\\n     *     \\\"standard\\\" plain number formatting\\n     *\\n     *     \\\"scientific\\\" return the order-of-magnitude for formatted number.\\n     *\\n     *     \\\"engineering\\\" return the exponent of ten when divisible by three\\n     *\\n     *     \\\"compact\\\" string representing exponent, defaults is using the \\\"short\\\" form\\n     */\\n    notation?: string;\\n\\n    /**\\n     * used only when notation is \\\"compact\\\"\\n     */\\n    compactDisplay?: string;\\n}\\n\\ninterface BigInt {\\n    /**\\n     * Returns a string representation of an object.\\n     * @param radix Specifies a radix for converting numeric values to strings.\\n     */\\n    toString(radix?: number): string;\\n\\n    /** Returns a string representation appropriate to the host environment's current locale. */\\n    toLocaleString(locales?: Intl.LocalesArgument, options?: BigIntToLocaleStringOptions): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): bigint;\\n\\n    readonly [Symbol.toStringTag]: \\\"BigInt\\\";\\n}\\n\\ninterface BigIntConstructor {\\n    (value: bigint | boolean | number | string): bigint;\\n    readonly prototype: BigInt;\\n\\n    /**\\n     * Interprets the low bits of a BigInt as a 2's-complement signed integer.\\n     * All higher bits are discarded.\\n     * @param bits The number of low bits to use\\n     * @param int The BigInt whose bits to extract\\n     */\\n    asIntN(bits: number, int: bigint): bigint;\\n    /**\\n     * Interprets the low bits of a BigInt as an unsigned integer.\\n     * All higher bits are discarded.\\n     * @param bits The number of low bits to use\\n     * @param int The BigInt whose bits to extract\\n     */\\n    asUintN(bits: number, int: bigint): bigint;\\n}\\n\\ndeclare var BigInt: BigIntConstructor;\\n\\n/**\\n * A typed array of 64-bit signed integer values. The contents are initialized to 0. If the\\n * requested number of bytes could not be allocated, an exception is raised.\\n */\\ninterface BigInt64Array {\\n    /** The size in bytes of each element in the array. */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /** The ArrayBuffer instance referenced by the array. */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /** The length in bytes of the array. */\\n    readonly byteLength: number;\\n\\n    /** The offset in bytes of the array. */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /** Yields index, value pairs for every entry in the array. */\\n    entries(): IterableIterator<[number, bigint]>;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns false,\\n     * or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: bigint, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: bigint, index: number, array: BigInt64Array) => any, thisArg?: any): BigInt64Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): bigint | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: bigint, index: number, array: BigInt64Array) => void, thisArg?: any): void;\\n\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: bigint, fromIndex?: number): boolean;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    indexOf(searchElement: bigint, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /** Yields each index in the array. */\\n    keys(): IterableIterator<number>;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: bigint, fromIndex?: number): number;\\n\\n    /** The length of the array. */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: bigint, index: number, array: BigInt64Array) => bigint, thisArg?: any): BigInt64Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigInt64Array) => bigint): bigint;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigInt64Array) => U, initialValue: U): U;\\n\\n    /** Reverses the elements in the array. */\\n    reverse(): this;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<bigint>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array.\\n     */\\n    slice(start?: number, end?: number): BigInt64Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls the\\n     * predicate function for each element in the array until the predicate returns true, or until\\n     * the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: bigint, index: number, array: BigInt64Array) => boolean, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts the array.\\n     * @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order.\\n     */\\n    sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this;\\n\\n    /**\\n     * Gets a new BigInt64Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): BigInt64Array;\\n\\n    /** Converts the array to a string by using the current locale. */\\n    toLocaleString(): string;\\n\\n    /** Returns a string representation of the array. */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): BigInt64Array;\\n\\n    /** Yields each value in the array. */\\n    values(): IterableIterator<bigint>;\\n\\n    [Symbol.iterator](): IterableIterator<bigint>;\\n\\n    readonly [Symbol.toStringTag]: \\\"BigInt64Array\\\";\\n\\n    [index: number]: bigint;\\n}\\n\\ninterface BigInt64ArrayConstructor {\\n    readonly prototype: BigInt64Array;\\n    new (length?: number): BigInt64Array;\\n    new (array: Iterable<bigint>): BigInt64Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigInt64Array;\\n\\n    /** The size in bytes of each element in the array. */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: bigint[]): BigInt64Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: ArrayLike<bigint>): BigInt64Array;\\n    from<U>(arrayLike: ArrayLike<U>, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigInt64Array;\\n}\\n\\ndeclare var BigInt64Array: BigInt64ArrayConstructor;\\n\\n/**\\n * A typed array of 64-bit unsigned integer values. The contents are initialized to 0. If the\\n * requested number of bytes could not be allocated, an exception is raised.\\n */\\ninterface BigUint64Array {\\n    /** The size in bytes of each element in the array. */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /** The ArrayBuffer instance referenced by the array. */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /** The length in bytes of the array. */\\n    readonly byteLength: number;\\n\\n    /** The offset in bytes of the array. */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /** Yields index, value pairs for every entry in the array. */\\n    entries(): IterableIterator<[number, bigint]>;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns false,\\n     * or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: bigint, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: bigint, index: number, array: BigUint64Array) => any, thisArg?: any): BigUint64Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): bigint | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: bigint, index: number, array: BigUint64Array) => void, thisArg?: any): void;\\n\\n    /**\\n     * Determines whether an array includes a certain element, returning true or false as appropriate.\\n     * @param searchElement The element to search for.\\n     * @param fromIndex The position in this array at which to begin searching for searchElement.\\n     */\\n    includes(searchElement: bigint, fromIndex?: number): boolean;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    indexOf(searchElement: bigint, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /** Yields each index in the array. */\\n    keys(): IterableIterator<number>;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: bigint, fromIndex?: number): number;\\n\\n    /** The length of the array. */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: bigint, index: number, array: BigUint64Array) => bigint, thisArg?: any): BigUint64Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: bigint, currentValue: bigint, currentIndex: number, array: BigUint64Array) => bigint): bigint;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: bigint, currentIndex: number, array: BigUint64Array) => U, initialValue: U): U;\\n\\n    /** Reverses the elements in the array. */\\n    reverse(): this;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<bigint>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array.\\n     */\\n    slice(start?: number, end?: number): BigUint64Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls the\\n     * predicate function for each element in the array until the predicate returns true, or until\\n     * the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: bigint, index: number, array: BigUint64Array) => boolean, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts the array.\\n     * @param compareFn The function used to determine the order of the elements. If omitted, the elements are sorted in ascending order.\\n     */\\n    sort(compareFn?: (a: bigint, b: bigint) => number | bigint): this;\\n\\n    /**\\n     * Gets a new BigUint64Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): BigUint64Array;\\n\\n    /** Converts the array to a string by using the current locale. */\\n    toLocaleString(): string;\\n\\n    /** Returns a string representation of the array. */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): BigUint64Array;\\n\\n    /** Yields each value in the array. */\\n    values(): IterableIterator<bigint>;\\n\\n    [Symbol.iterator](): IterableIterator<bigint>;\\n\\n    readonly [Symbol.toStringTag]: \\\"BigUint64Array\\\";\\n\\n    [index: number]: bigint;\\n}\\n\\ninterface BigUint64ArrayConstructor {\\n    readonly prototype: BigUint64Array;\\n    new (length?: number): BigUint64Array;\\n    new (array: Iterable<bigint>): BigUint64Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigUint64Array;\\n\\n    /** The size in bytes of each element in the array. */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: bigint[]): BigUint64Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from(arrayLike: ArrayLike<bigint>): BigUint64Array;\\n    from<U>(arrayLike: ArrayLike<U>, mapfn: (v: U, k: number) => bigint, thisArg?: any): BigUint64Array;\\n}\\n\\ndeclare var BigUint64Array: BigUint64ArrayConstructor;\\n\\ninterface DataView {\\n    /**\\n     * Gets the BigInt64 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     * @param littleEndian If false or undefined, a big-endian value should be read.\\n     */\\n    getBigInt64(byteOffset: number, littleEndian?: boolean): bigint;\\n\\n    /**\\n     * Gets the BigUint64 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     * @param littleEndian If false or undefined, a big-endian value should be read.\\n     */\\n    getBigUint64(byteOffset: number, littleEndian?: boolean): bigint;\\n\\n    /**\\n     * Stores a BigInt64 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     * @param littleEndian If false or undefined, a big-endian value should be written.\\n     */\\n    setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void;\\n\\n    /**\\n     * Stores a BigUint64 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     * @param littleEndian If false or undefined, a big-endian value should be written.\\n     */\\n    setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void;\\n}\\n\\ndeclare namespace Intl {\\n    interface NumberFormat {\\n        format(value: number | bigint): string;\\n        resolvedOptions(): ResolvedNumberFormatOptions;\\n    }\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2019\\\" />\\n/// <reference lib=\\\"es2020.bigint\\\" />\\n/// <reference lib=\\\"es2020.date\\\" />\\n/// <reference lib=\\\"es2020.number\\\" />\\n/// <reference lib=\\\"es2020.promise\\\" />\\n/// <reference lib=\\\"es2020.sharedmemory\\\" />\\n/// <reference lib=\\\"es2020.string\\\" />\\n/// <reference lib=\\\"es2020.symbol.wellknown\\\" />\\n/// <reference lib=\\\"es2020.intl\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.date.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2020.intl\\\" />\\n\\ninterface Date {\\n    /**\\n     * Converts a date and time to a string by using the current or specified locale.\\n     * @param locales A locale string, array of locale strings, Intl.Locale object, or array of Intl.Locale objects that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\\n     * @param options An object that contains one or more properties that specify comparison options.\\n     */\\n    toLocaleString(locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string;\\n\\n    /**\\n     * Converts a date to a string by using the current or specified locale.\\n     * @param locales A locale string, array of locale strings, Intl.Locale object, or array of Intl.Locale objects that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\\n     * @param options An object that contains one or more properties that specify comparison options.\\n     */\\n    toLocaleDateString(locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string;\\n\\n    /**\\n     * Converts a time to a string by using the current or specified locale.\\n     * @param locales A locale string, array of locale strings, Intl.Locale object, or array of Intl.Locale objects that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\\n     * @param options An object that contains one or more properties that specify comparison options.\\n     */\\n    toLocaleTimeString(locales?: Intl.LocalesArgument, options?: Intl.DateTimeFormatOptions): string;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2020\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.intl.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2018.intl\\\" />\\ndeclare namespace Intl {\\n    /**\\n     * [Unicode BCP 47 Locale Identifiers](https://unicode.org/reports/tr35/#Unicode_Language_and_Locale_Identifiers) definition.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument).\\n     */\\n    type UnicodeBCP47LocaleIdentifier = string;\\n\\n    /**\\n     * Unit to use in the relative time internationalized message.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/format#Parameters).\\n     */\\n    type RelativeTimeFormatUnit =\\n        | \\\"year\\\"\\n        | \\\"years\\\"\\n        | \\\"quarter\\\"\\n        | \\\"quarters\\\"\\n        | \\\"month\\\"\\n        | \\\"months\\\"\\n        | \\\"week\\\"\\n        | \\\"weeks\\\"\\n        | \\\"day\\\"\\n        | \\\"days\\\"\\n        | \\\"hour\\\"\\n        | \\\"hours\\\"\\n        | \\\"minute\\\"\\n        | \\\"minutes\\\"\\n        | \\\"second\\\"\\n        | \\\"seconds\\\";\\n\\n    /**\\n     * Value of the `unit` property in objects returned by\\n     * `Intl.RelativeTimeFormat.prototype.formatToParts()`. `formatToParts` and\\n     * `format` methods accept either singular or plural unit names as input,\\n     * but `formatToParts` only outputs singular (e.g. \\\"day\\\") not plural (e.g.\\n     * \\\"days\\\").\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/formatToParts#Using_formatToParts).\\n     */\\n    type RelativeTimeFormatUnitSingular =\\n        | \\\"year\\\"\\n        | \\\"quarter\\\"\\n        | \\\"month\\\"\\n        | \\\"week\\\"\\n        | \\\"day\\\"\\n        | \\\"hour\\\"\\n        | \\\"minute\\\"\\n        | \\\"second\\\";\\n\\n    /**\\n     * The locale matching algorithm to use.\\n     *\\n     * [MDN](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_negotiation).\\n     */\\n    type RelativeTimeFormatLocaleMatcher = \\\"lookup\\\" | \\\"best fit\\\";\\n\\n    /**\\n     * The format of output message.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat#Parameters).\\n     */\\n    type RelativeTimeFormatNumeric = \\\"always\\\" | \\\"auto\\\";\\n\\n    /**\\n     * The length of the internationalized message.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat#Parameters).\\n     */\\n    type RelativeTimeFormatStyle = \\\"long\\\" | \\\"short\\\" | \\\"narrow\\\";\\n\\n    /**\\n     * [BCP 47 language tag](http://tools.ietf.org/html/rfc5646) definition.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument).\\n     */\\n    type BCP47LanguageTag = string;\\n\\n    /**\\n     * The locale(s) to use\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locales_argument).\\n     */\\n    type LocalesArgument = UnicodeBCP47LocaleIdentifier | Locale | readonly (UnicodeBCP47LocaleIdentifier | Locale)[] | undefined;\\n\\n    /**\\n     * An object with some or all of properties of `options` parameter\\n     * of `Intl.RelativeTimeFormat` constructor.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat#Parameters).\\n     */\\n    interface RelativeTimeFormatOptions {\\n        /** The locale matching algorithm to use. For information about this option, see [Intl page](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_negotiation). */\\n        localeMatcher?: RelativeTimeFormatLocaleMatcher;\\n        /** The format of output message. */\\n        numeric?: RelativeTimeFormatNumeric;\\n        /** The length of the internationalized message. */\\n        style?: RelativeTimeFormatStyle;\\n    }\\n\\n    /**\\n     * An object with properties reflecting the locale\\n     * and formatting options computed during initialization\\n     * of the `Intl.RelativeTimeFormat` object\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/resolvedOptions#Description).\\n     */\\n    interface ResolvedRelativeTimeFormatOptions {\\n        locale: UnicodeBCP47LocaleIdentifier;\\n        style: RelativeTimeFormatStyle;\\n        numeric: RelativeTimeFormatNumeric;\\n        numberingSystem: string;\\n    }\\n\\n    /**\\n     * An object representing the relative time format in parts\\n     * that can be used for custom locale-aware formatting.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/formatToParts#Using_formatToParts).\\n     */\\n    type RelativeTimeFormatPart =\\n        | {\\n            type: \\\"literal\\\";\\n            value: string;\\n        }\\n        | {\\n            type: Exclude<NumberFormatPartTypes, \\\"literal\\\">;\\n            value: string;\\n            unit: RelativeTimeFormatUnitSingular;\\n        };\\n\\n    interface RelativeTimeFormat {\\n        /**\\n         * Formats a value and a unit according to the locale\\n         * and formatting options of the given\\n         * [`Intl.RelativeTimeFormat`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat)\\n         * object.\\n         *\\n         * While this method automatically provides the correct plural forms,\\n         * the grammatical form is otherwise as neutral as possible.\\n         *\\n         * It is the caller's responsibility to handle cut-off logic\\n         * such as deciding between displaying \\\"in 7 days\\\" or \\\"in 1 week\\\".\\n         * This API does not support relative dates involving compound units.\\n         * e.g \\\"in 5 days and 4 hours\\\".\\n         *\\n         * @param value -  Numeric value to use in the internationalized relative time message\\n         *\\n         * @param unit - [Unit](https://tc39.es/ecma402/#sec-singularrelativetimeunit) to use in the relative time internationalized message.\\n         *\\n         * @throws `RangeError` if `unit` was given something other than `unit` possible values\\n         *\\n         * @returns {string} Internationalized relative time message as string\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/format).\\n         */\\n        format(value: number, unit: RelativeTimeFormatUnit): string;\\n\\n        /**\\n         *  Returns an array of objects representing the relative time format in parts that can be used for custom locale-aware formatting.\\n         *\\n         *  @param value - Numeric value to use in the internationalized relative time message\\n         *\\n         *  @param unit - [Unit](https://tc39.es/ecma402/#sec-singularrelativetimeunit) to use in the relative time internationalized message.\\n         *\\n         *  @throws `RangeError` if `unit` was given something other than `unit` possible values\\n         *\\n         *  [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/formatToParts).\\n         */\\n        formatToParts(value: number, unit: RelativeTimeFormatUnit): RelativeTimeFormatPart[];\\n\\n        /**\\n         * Provides access to the locale and options computed during initialization of this `Intl.RelativeTimeFormat` object.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/resolvedOptions).\\n         */\\n        resolvedOptions(): ResolvedRelativeTimeFormatOptions;\\n    }\\n\\n    /**\\n     * The [`Intl.RelativeTimeFormat`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat)\\n     * object is a constructor for objects that enable language-sensitive relative time formatting.\\n     *\\n     * [Compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat#Browser_compatibility).\\n     */\\n    const RelativeTimeFormat: {\\n        /**\\n         * Creates [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat) objects\\n         *\\n         * @param locales - A string with a [BCP 47 language tag](http://tools.ietf.org/html/rfc5646), or an array of such strings.\\n         *  For the general form and interpretation of the locales argument,\\n         *  see the [`Intl` page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation).\\n         *\\n         * @param options - An [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat#Parameters)\\n         *  with some or all of options of `RelativeTimeFormatOptions`.\\n         *\\n         * @returns [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat) object.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat).\\n         */\\n        new (\\n            locales?: UnicodeBCP47LocaleIdentifier | UnicodeBCP47LocaleIdentifier[],\\n            options?: RelativeTimeFormatOptions,\\n        ): RelativeTimeFormat;\\n\\n        /**\\n         * Returns an array containing those of the provided locales\\n         * that are supported in date and time formatting\\n         * without having to fall back to the runtime's default locale.\\n         *\\n         * @param locales - A string with a [BCP 47 language tag](http://tools.ietf.org/html/rfc5646), or an array of such strings.\\n         *  For the general form and interpretation of the locales argument,\\n         *  see the [`Intl` page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation).\\n         *\\n         * @param options - An [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/RelativeTimeFormat#Parameters)\\n         *  with some or all of options of the formatting.\\n         *\\n         * @returns An array containing those of the provided locales\\n         *  that are supported in date and time formatting\\n         *  without having to fall back to the runtime's default locale.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat/supportedLocalesOf).\\n         */\\n        supportedLocalesOf(\\n            locales?: UnicodeBCP47LocaleIdentifier | UnicodeBCP47LocaleIdentifier[],\\n            options?: RelativeTimeFormatOptions,\\n        ): UnicodeBCP47LocaleIdentifier[];\\n    };\\n\\n    interface NumberFormatOptions {\\n        compactDisplay?: \\\"short\\\" | \\\"long\\\" | undefined;\\n        notation?: \\\"standard\\\" | \\\"scientific\\\" | \\\"engineering\\\" | \\\"compact\\\" | undefined;\\n        signDisplay?: \\\"auto\\\" | \\\"never\\\" | \\\"always\\\" | \\\"exceptZero\\\" | undefined;\\n        unit?: string | undefined;\\n        unitDisplay?: \\\"short\\\" | \\\"long\\\" | \\\"narrow\\\" | undefined;\\n        currencyDisplay?: string | undefined;\\n        currencySign?: string | undefined;\\n    }\\n\\n    interface ResolvedNumberFormatOptions {\\n        compactDisplay?: \\\"short\\\" | \\\"long\\\";\\n        notation?: \\\"standard\\\" | \\\"scientific\\\" | \\\"engineering\\\" | \\\"compact\\\";\\n        signDisplay?: \\\"auto\\\" | \\\"never\\\" | \\\"always\\\" | \\\"exceptZero\\\";\\n        unit?: string;\\n        unitDisplay?: \\\"short\\\" | \\\"long\\\" | \\\"narrow\\\";\\n        currencyDisplay?: string;\\n        currencySign?: string;\\n    }\\n\\n    interface DateTimeFormatOptions {\\n        calendar?: string | undefined;\\n        dayPeriod?: \\\"narrow\\\" | \\\"short\\\" | \\\"long\\\" | undefined;\\n        numberingSystem?: string | undefined;\\n\\n        dateStyle?: \\\"full\\\" | \\\"long\\\" | \\\"medium\\\" | \\\"short\\\" | undefined;\\n        timeStyle?: \\\"full\\\" | \\\"long\\\" | \\\"medium\\\" | \\\"short\\\" | undefined;\\n        hourCycle?: \\\"h11\\\" | \\\"h12\\\" | \\\"h23\\\" | \\\"h24\\\" | undefined;\\n    }\\n\\n    type LocaleHourCycleKey = \\\"h12\\\" | \\\"h23\\\" | \\\"h11\\\" | \\\"h24\\\";\\n    type LocaleCollationCaseFirst = \\\"upper\\\" | \\\"lower\\\" | \\\"false\\\";\\n\\n    interface LocaleOptions {\\n        /** A string containing the language, and the script and region if available. */\\n        baseName?: string;\\n        /** The part of the Locale that indicates the locale's calendar era. */\\n        calendar?: string;\\n        /** Flag that defines whether case is taken into account for the locale's collation rules. */\\n        caseFirst?: LocaleCollationCaseFirst;\\n        /** The collation type used for sorting */\\n        collation?: string;\\n        /** The time keeping format convention used by the locale. */\\n        hourCycle?: LocaleHourCycleKey;\\n        /** The primary language subtag associated with the locale. */\\n        language?: string;\\n        /** The numeral system used by the locale. */\\n        numberingSystem?: string;\\n        /** Flag that defines whether the locale has special collation handling for numeric characters. */\\n        numeric?: boolean;\\n        /** The region of the world (usually a country) associated with the locale. Possible values are region codes as defined by ISO 3166-1. */\\n        region?: string;\\n        /** The script used for writing the particular language used in the locale. Possible values are script codes as defined by ISO 15924. */\\n        script?: string;\\n    }\\n\\n    interface Locale extends LocaleOptions {\\n        /** A string containing the language, and the script and region if available. */\\n        baseName: string;\\n        /** The primary language subtag associated with the locale. */\\n        language: string;\\n        /** Gets the most likely values for the language, script, and region of the locale based on existing values. */\\n        maximize(): Locale;\\n        /** Attempts to remove information about the locale that would be added by calling `Locale.maximize()`. */\\n        minimize(): Locale;\\n        /** Returns the locale's full locale identifier string. */\\n        toString(): BCP47LanguageTag;\\n    }\\n\\n    /**\\n     * Constructor creates [Intl.Locale](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale)\\n     * objects\\n     *\\n     * @param tag - A string with a [BCP 47 language tag](http://tools.ietf.org/html/rfc5646).\\n     *  For the general form and interpretation of the locales argument,\\n     *  see the [`Intl` page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation).\\n     *\\n     * @param options - An [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/Locale#Parameters) with some or all of options of the locale.\\n     *\\n     * @returns [Intl.Locale](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale) object.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale).\\n     */\\n    const Locale: {\\n        new (tag: BCP47LanguageTag | Locale, options?: LocaleOptions): Locale;\\n    };\\n\\n    type DisplayNamesFallback =\\n        | \\\"code\\\"\\n        | \\\"none\\\";\\n\\n    type DisplayNamesType =\\n        | \\\"language\\\"\\n        | \\\"region\\\"\\n        | \\\"script\\\"\\n        | \\\"calendar\\\"\\n        | \\\"dateTimeField\\\"\\n        | \\\"currency\\\";\\n\\n    type DisplayNamesLanguageDisplay =\\n        | \\\"dialect\\\"\\n        | \\\"standard\\\";\\n\\n    interface DisplayNamesOptions {\\n        localeMatcher?: RelativeTimeFormatLocaleMatcher;\\n        style?: RelativeTimeFormatStyle;\\n        type: DisplayNamesType;\\n        languageDisplay?: DisplayNamesLanguageDisplay;\\n        fallback?: DisplayNamesFallback;\\n    }\\n\\n    interface ResolvedDisplayNamesOptions {\\n        locale: UnicodeBCP47LocaleIdentifier;\\n        style: RelativeTimeFormatStyle;\\n        type: DisplayNamesType;\\n        fallback: DisplayNamesFallback;\\n        languageDisplay?: DisplayNamesLanguageDisplay;\\n    }\\n\\n    interface DisplayNames {\\n        /**\\n         * Receives a code and returns a string based on the locale and options provided when instantiating\\n         * [`Intl.DisplayNames()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames)\\n         *\\n         * @param code The `code` to provide depends on the `type` passed to display name during creation:\\n         *  - If the type is `\\\"region\\\"`, code should be either an [ISO-3166 two letters region code](https://www.iso.org/iso-3166-country-codes.html),\\n         *    or a [three digits UN M49 Geographic Regions](https://unstats.un.org/unsd/methodology/m49/).\\n         *  - If the type is `\\\"script\\\"`, code should be an [ISO-15924 four letters script code](https://unicode.org/iso15924/iso15924-codes.html).\\n         *  - If the type is `\\\"language\\\"`, code should be a `languageCode` [\\\"-\\\" `scriptCode`] [\\\"-\\\" `regionCode` ] *(\\\"-\\\" `variant` )\\n         *    subsequence of the unicode_language_id grammar in [UTS 35's Unicode Language and Locale Identifiers grammar](https://unicode.org/reports/tr35/#Unicode_language_identifier).\\n         *    `languageCode` is either a two letters ISO 639-1 language code or a three letters ISO 639-2 language code.\\n         *  - If the type is `\\\"currency\\\"`, code should be a [3-letter ISO 4217 currency code](https://www.iso.org/iso-4217-currency-codes.html).\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames/of).\\n         */\\n        of(code: string): string | undefined;\\n        /**\\n         * Returns a new object with properties reflecting the locale and style formatting options computed during the construction of the current\\n         * [`Intl/DisplayNames`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames) object.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames/resolvedOptions).\\n         */\\n        resolvedOptions(): ResolvedDisplayNamesOptions;\\n    }\\n\\n    /**\\n     * The [`Intl.DisplayNames()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames)\\n     * object enables the consistent translation of language, region and script display names.\\n     *\\n     * [Compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames#browser_compatibility).\\n     */\\n    const DisplayNames: {\\n        prototype: DisplayNames;\\n\\n        /**\\n         * @param locales A string with a BCP 47 language tag, or an array of such strings.\\n         *   For the general form and interpretation of the `locales` argument, see the [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locale_identification_and_negotiation)\\n         *   page.\\n         *\\n         * @param options An object for setting up a display name.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames/DisplayNames).\\n         */\\n        new (locales: LocalesArgument, options: DisplayNamesOptions): DisplayNames;\\n\\n        /**\\n         * Returns an array containing those of the provided locales that are supported in display names without having to fall back to the runtime's default locale.\\n         *\\n         * @param locales A string with a BCP 47 language tag, or an array of such strings.\\n         *   For the general form and interpretation of the `locales` argument, see the [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#locale_identification_and_negotiation)\\n         *   page.\\n         *\\n         * @param options An object with a locale matcher.\\n         *\\n         * @returns An array of strings representing a subset of the given locale tags that are supported in display names without having to fall back to the runtime's default locale.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames/supportedLocalesOf).\\n         */\\n        supportedLocalesOf(locales?: LocalesArgument, options?: { localeMatcher?: RelativeTimeFormatLocaleMatcher; }): BCP47LanguageTag[];\\n    };\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.number.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2020.intl\\\" />\\n\\ninterface Number {\\n    /**\\n     * Converts a number to a string by using the current or specified locale.\\n     * @param locales A locale string, array of locale strings, Intl.Locale object, or array of Intl.Locale objects that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\\n     * @param options An object that contains one or more properties that specify comparison options.\\n     */\\n    toLocaleString(locales?: Intl.LocalesArgument, options?: Intl.NumberFormatOptions): string;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.promise.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface PromiseFulfilledResult<T> {\\n    status: \\\"fulfilled\\\";\\n    value: T;\\n}\\n\\ninterface PromiseRejectedResult {\\n    status: \\\"rejected\\\";\\n    reason: any;\\n}\\n\\ntype PromiseSettledResult<T> = PromiseFulfilledResult<T> | PromiseRejectedResult;\\n\\ninterface PromiseConstructor {\\n    /**\\n     * Creates a Promise that is resolved with an array of results when all\\n     * of the provided Promises resolve or reject.\\n     * @param values An array of Promises.\\n     * @returns A new Promise.\\n     */\\n    allSettled<T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: PromiseSettledResult<Awaited<T[P]>>; }>;\\n\\n    /**\\n     * Creates a Promise that is resolved with an array of results when all\\n     * of the provided Promises resolve or reject.\\n     * @param values An array of Promises.\\n     * @returns A new Promise.\\n     */\\n    allSettled<T>(values: Iterable<T | PromiseLike<T>>): Promise<PromiseSettledResult<Awaited<T>>[]>;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.sharedmemory.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Atomics {\\n    /**\\n     * Adds a value to the value at the given position in the array, returning the original value.\\n     * Until this atomic operation completes, any other read or write operation against the array\\n     * will block.\\n     */\\n    add(typedArray: BigInt64Array | BigUint64Array, index: number, value: bigint): bigint;\\n\\n    /**\\n     * Stores the bitwise AND of a value with the value at the given position in the array,\\n     * returning the original value. Until this atomic operation completes, any other read or\\n     * write operation against the array will block.\\n     */\\n    and(typedArray: BigInt64Array | BigUint64Array, index: number, value: bigint): bigint;\\n\\n    /**\\n     * Replaces the value at the given position in the array if the original value equals the given\\n     * expected value, returning the original value. Until this atomic operation completes, any\\n     * other read or write operation against the array will block.\\n     */\\n    compareExchange(typedArray: BigInt64Array | BigUint64Array, index: number, expectedValue: bigint, replacementValue: bigint): bigint;\\n\\n    /**\\n     * Replaces the value at the given position in the array, returning the original value. Until\\n     * this atomic operation completes, any other read or write operation against the array will\\n     * block.\\n     */\\n    exchange(typedArray: BigInt64Array | BigUint64Array, index: number, value: bigint): bigint;\\n\\n    /**\\n     * Returns the value at the given position in the array. Until this atomic operation completes,\\n     * any other read or write operation against the array will block.\\n     */\\n    load(typedArray: BigInt64Array | BigUint64Array, index: number): bigint;\\n\\n    /**\\n     * Stores the bitwise OR of a value with the value at the given position in the array,\\n     * returning the original value. Until this atomic operation completes, any other read or write\\n     * operation against the array will block.\\n     */\\n    or(typedArray: BigInt64Array | BigUint64Array, index: number, value: bigint): bigint;\\n\\n    /**\\n     * Stores a value at the given position in the array, returning the new value. Until this\\n     * atomic operation completes, any other read or write operation against the array will block.\\n     */\\n    store(typedArray: BigInt64Array | BigUint64Array, index: number, value: bigint): bigint;\\n\\n    /**\\n     * Subtracts a value from the value at the given position in the array, returning the original\\n     * value. Until this atomic operation completes, any other read or write operation against the\\n     * array will block.\\n     */\\n    sub(typedArray: BigInt64Array | BigUint64Array, index: number, value: bigint): bigint;\\n\\n    /**\\n     * If the value at the given position in the array is equal to the provided value, the current\\n     * agent is put to sleep causing execution to suspend until the timeout expires (returning\\n     * `\\\"timed-out\\\"`) or until the agent is awoken (returning `\\\"ok\\\"`); otherwise, returns\\n     * `\\\"not-equal\\\"`.\\n     */\\n    wait(typedArray: BigInt64Array, index: number, value: bigint, timeout?: number): \\\"ok\\\" | \\\"not-equal\\\" | \\\"timed-out\\\";\\n\\n    /**\\n     * Wakes up sleeping agents that are waiting on the given index of the array, returning the\\n     * number of agents that were awoken.\\n     * @param typedArray A shared BigInt64Array.\\n     * @param index The position in the typedArray to wake up on.\\n     * @param count The number of sleeping agents to notify. Defaults to +Infinity.\\n     */\\n    notify(typedArray: BigInt64Array, index: number, count?: number): number;\\n\\n    /**\\n     * Stores the bitwise XOR of a value with the value at the given position in the array,\\n     * returning the original value. Until this atomic operation completes, any other read or write\\n     * operation against the array will block.\\n     */\\n    xor(typedArray: BigInt64Array | BigUint64Array, index: number, value: bigint): bigint;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.string.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.iterable\\\" />\\n\\ninterface String {\\n    /**\\n     * Matches a string with a regular expression, and returns an iterable of matches\\n     * containing the results of that search.\\n     * @param regexp A variable name or string literal containing the regular expression pattern and flags.\\n     */\\n    matchAll(regexp: RegExp): IterableIterator<RegExpMatchArray>;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2020.symbol.wellknown.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.iterable\\\" />\\n/// <reference lib=\\\"es2015.symbol\\\" />\\n\\ninterface SymbolConstructor {\\n    /**\\n     * A regular expression method that matches the regular expression against a string. Called\\n     * by the String.prototype.matchAll method.\\n     */\\n    readonly matchAll: unique symbol;\\n}\\n\\ninterface RegExp {\\n    /**\\n     * Matches a string with this regular expression, and returns an iterable of matches\\n     * containing the results of that search.\\n     * @param string A string to search within.\\n     */\\n    [Symbol.matchAll](str: string): IterableIterator<RegExpMatchArray>;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2021.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2020\\\" />\\n/// <reference lib=\\\"es2021.promise\\\" />\\n/// <reference lib=\\\"es2021.string\\\" />\\n/// <reference lib=\\\"es2021.weakref\\\" />\\n/// <reference lib=\\\"es2021.intl\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2021.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2021\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2021.intl.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ndeclare namespace Intl {\\n    interface DateTimeFormatPartTypesRegistry {\\n        fractionalSecond: any;\\n    }\\n\\n    interface DateTimeFormatOptions {\\n        formatMatcher?: \\\"basic\\\" | \\\"best fit\\\" | \\\"best fit\\\" | undefined;\\n        dateStyle?: \\\"full\\\" | \\\"long\\\" | \\\"medium\\\" | \\\"short\\\" | undefined;\\n        timeStyle?: \\\"full\\\" | \\\"long\\\" | \\\"medium\\\" | \\\"short\\\" | undefined;\\n        dayPeriod?: \\\"narrow\\\" | \\\"short\\\" | \\\"long\\\" | undefined;\\n        fractionalSecondDigits?: 1 | 2 | 3 | undefined;\\n    }\\n\\n    interface DateTimeRangeFormatPart extends DateTimeFormatPart {\\n        source: \\\"startRange\\\" | \\\"endRange\\\" | \\\"shared\\\";\\n    }\\n\\n    interface DateTimeFormat {\\n        formatRange(startDate: Date | number | bigint, endDate: Date | number | bigint): string;\\n        formatRangeToParts(startDate: Date | number | bigint, endDate: Date | number | bigint): DateTimeRangeFormatPart[];\\n    }\\n\\n    interface ResolvedDateTimeFormatOptions {\\n        formatMatcher?: \\\"basic\\\" | \\\"best fit\\\" | \\\"best fit\\\";\\n        dateStyle?: \\\"full\\\" | \\\"long\\\" | \\\"medium\\\" | \\\"short\\\";\\n        timeStyle?: \\\"full\\\" | \\\"long\\\" | \\\"medium\\\" | \\\"short\\\";\\n        hourCycle?: \\\"h11\\\" | \\\"h12\\\" | \\\"h23\\\" | \\\"h24\\\";\\n        dayPeriod?: \\\"narrow\\\" | \\\"short\\\" | \\\"long\\\";\\n        fractionalSecondDigits?: 1 | 2 | 3;\\n    }\\n\\n    /**\\n     * The locale matching algorithm to use.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/ListFormat#parameters).\\n     */\\n    type ListFormatLocaleMatcher = \\\"lookup\\\" | \\\"best fit\\\";\\n\\n    /**\\n     * The format of output message.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/ListFormat#parameters).\\n     */\\n    type ListFormatType = \\\"conjunction\\\" | \\\"disjunction\\\" | \\\"unit\\\";\\n\\n    /**\\n     * The length of the formatted message.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/ListFormat#parameters).\\n     */\\n    type ListFormatStyle = \\\"long\\\" | \\\"short\\\" | \\\"narrow\\\";\\n\\n    /**\\n     * An object with some or all properties of the `Intl.ListFormat` constructor `options` parameter.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/ListFormat#parameters).\\n     */\\n    interface ListFormatOptions {\\n        /** The locale matching algorithm to use. For information about this option, see [Intl page](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_negotiation). */\\n        localeMatcher?: ListFormatLocaleMatcher | undefined;\\n        /** The format of output message. */\\n        type?: ListFormatType | undefined;\\n        /** The length of the internationalized message. */\\n        style?: ListFormatStyle | undefined;\\n    }\\n\\n    interface ResolvedListFormatOptions {\\n        locale: string;\\n        style: ListFormatStyle;\\n        type: ListFormatType;\\n    }\\n\\n    interface ListFormat {\\n        /**\\n         * Returns a string with a language-specific representation of the list.\\n         *\\n         * @param list - An iterable object, such as an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array).\\n         *\\n         * @throws `TypeError` if `list` includes something other than the possible values.\\n         *\\n         * @returns {string} A language-specific formatted string representing the elements of the list.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/format).\\n         */\\n        format(list: Iterable<string>): string;\\n\\n        /**\\n         * Returns an Array of objects representing the different components that can be used to format a list of values in a locale-aware fashion.\\n         *\\n         * @param list - An iterable object, such as an [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array), to be formatted according to a locale.\\n         *\\n         * @throws `TypeError` if `list` includes something other than the possible values.\\n         *\\n         * @returns {{ type: \\\"element\\\" | \\\"literal\\\", value: string; }[]} An Array of components which contains the formatted parts from the list.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/formatToParts).\\n         */\\n        formatToParts(list: Iterable<string>): { type: \\\"element\\\" | \\\"literal\\\"; value: string; }[];\\n\\n        /**\\n         * Returns a new object with properties reflecting the locale and style\\n         * formatting options computed during the construction of the current\\n         * `Intl.ListFormat` object.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/resolvedOptions).\\n         */\\n        resolvedOptions(): ResolvedListFormatOptions;\\n    }\\n\\n    const ListFormat: {\\n        prototype: ListFormat;\\n\\n        /**\\n         * Creates [Intl.ListFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat) objects that\\n         * enable language-sensitive list formatting.\\n         *\\n         * @param locales - A string with a [BCP 47 language tag](http://tools.ietf.org/html/rfc5646), or an array of such strings.\\n         *  For the general form and interpretation of the `locales` argument,\\n         *  see the [`Intl` page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation).\\n         *\\n         * @param options - An [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/ListFormat#parameters)\\n         *  with some or all options of `ListFormatOptions`.\\n         *\\n         * @returns [Intl.ListFormatOptions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat) object.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat).\\n         */\\n        new (locales?: BCP47LanguageTag | BCP47LanguageTag[], options?: ListFormatOptions): ListFormat;\\n\\n        /**\\n         * Returns an array containing those of the provided locales that are\\n         * supported in list formatting without having to fall back to the runtime's default locale.\\n         *\\n         * @param locales - A string with a [BCP 47 language tag](http://tools.ietf.org/html/rfc5646), or an array of such strings.\\n         *  For the general form and interpretation of the `locales` argument,\\n         *  see the [`Intl` page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation).\\n         *\\n         * @param options - An [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/supportedLocalesOf#parameters).\\n         *  with some or all possible options.\\n         *\\n         * @returns An array of strings representing a subset of the given locale tags that are supported in list\\n         *  formatting without having to fall back to the runtime's default locale.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat/supportedLocalesOf).\\n         */\\n        supportedLocalesOf(locales: BCP47LanguageTag | BCP47LanguageTag[], options?: Pick<ListFormatOptions, \\\"localeMatcher\\\">): BCP47LanguageTag[];\\n    };\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2021.promise.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface AggregateError extends Error {\\n    errors: any[];\\n}\\n\\ninterface AggregateErrorConstructor {\\n    new (errors: Iterable<any>, message?: string): AggregateError;\\n    (errors: Iterable<any>, message?: string): AggregateError;\\n    readonly prototype: AggregateError;\\n}\\n\\ndeclare var AggregateError: AggregateErrorConstructor;\\n\\n/**\\n * Represents the completion of an asynchronous operation\\n */\\ninterface PromiseConstructor {\\n    /**\\n     * The any function returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an AggregateError containing an array of rejection reasons if all of the given promises are rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm.\\n     * @param values An array or iterable of Promises.\\n     * @returns A new Promise.\\n     */\\n    any<T extends readonly unknown[] | []>(values: T): Promise<Awaited<T[number]>>;\\n\\n    /**\\n     * The any function returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an AggregateError containing an array of rejection reasons if all of the given promises are rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm.\\n     * @param values An array or iterable of Promises.\\n     * @returns A new Promise.\\n     */\\n    any<T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>>;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2021.string.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface String {\\n    /**\\n     * Replace all instances of a substring in a string, using a regular expression or search string.\\n     * @param searchValue A string to search for.\\n     * @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.\\n     */\\n    replaceAll(searchValue: string | RegExp, replaceValue: string): string;\\n\\n    /**\\n     * Replace all instances of a substring in a string, using a regular expression or search string.\\n     * @param searchValue A string to search for.\\n     * @param replacer A function that returns the replacement text.\\n     */\\n    replaceAll(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2021.weakref.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface WeakRef<T extends WeakKey> {\\n    readonly [Symbol.toStringTag]: \\\"WeakRef\\\";\\n\\n    /**\\n     * Returns the WeakRef instance's target value, or undefined if the target value has been\\n     * reclaimed.\\n     * In es2023 the value can be either a symbol or an object, in previous versions only object is permissible.\\n     */\\n    deref(): T | undefined;\\n}\\n\\ninterface WeakRefConstructor {\\n    readonly prototype: WeakRef<any>;\\n\\n    /**\\n     * Creates a WeakRef instance for the given target value.\\n     * In es2023 the value can be either a symbol or an object, in previous versions only object is permissible.\\n     * @param target The target value for the WeakRef instance.\\n     */\\n    new <T extends WeakKey>(target: T): WeakRef<T>;\\n}\\n\\ndeclare var WeakRef: WeakRefConstructor;\\n\\ninterface FinalizationRegistry<T> {\\n    readonly [Symbol.toStringTag]: \\\"FinalizationRegistry\\\";\\n\\n    /**\\n     * Registers a value with the registry.\\n     * In es2023 the value can be either a symbol or an object, in previous versions only object is permissible.\\n     * @param target The target value to register.\\n     * @param heldValue The value to pass to the finalizer for this value. This cannot be the\\n     * target value.\\n     * @param unregisterToken The token to pass to the unregister method to unregister the target\\n     * value. If not provided, the target cannot be unregistered.\\n     */\\n    register(target: WeakKey, heldValue: T, unregisterToken?: WeakKey): void;\\n\\n    /**\\n     * Unregisters a value from the registry.\\n     * In es2023 the value can be either a symbol or an object, in previous versions only object is permissible.\\n     * @param unregisterToken The token that was used as the unregisterToken argument when calling\\n     * register to register the target value.\\n     */\\n    unregister(unregisterToken: WeakKey): void;\\n}\\n\\ninterface FinalizationRegistryConstructor {\\n    readonly prototype: FinalizationRegistry<any>;\\n\\n    /**\\n     * Creates a finalization registry with an associated cleanup callback\\n     * @param cleanupCallback The callback to call after a value in the registry has been reclaimed.\\n     */\\n    new <T>(cleanupCallback: (heldValue: T) => void): FinalizationRegistry<T>;\\n}\\n\\ndeclare var FinalizationRegistry: FinalizationRegistryConstructor;\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.array.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Array<T> {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): T | undefined;\\n}\\n\\ninterface ReadonlyArray<T> {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): T | undefined;\\n}\\n\\ninterface Int8Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface Uint8Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface Uint8ClampedArray {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface Int16Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface Uint16Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface Int32Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface Uint32Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface Float32Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface Float64Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): number | undefined;\\n}\\n\\ninterface BigInt64Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): bigint | undefined;\\n}\\n\\ninterface BigUint64Array {\\n    /**\\n     * Returns the item located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): bigint | undefined;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2021\\\" />\\n/// <reference lib=\\\"es2022.array\\\" />\\n/// <reference lib=\\\"es2022.error\\\" />\\n/// <reference lib=\\\"es2022.intl\\\" />\\n/// <reference lib=\\\"es2022.object\\\" />\\n/// <reference lib=\\\"es2022.sharedmemory\\\" />\\n/// <reference lib=\\\"es2022.string\\\" />\\n/// <reference lib=\\\"es2022.regexp\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.error.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface ErrorOptions {\\n    cause?: unknown;\\n}\\n\\ninterface Error {\\n    cause?: unknown;\\n}\\n\\ninterface ErrorConstructor {\\n    new (message?: string, options?: ErrorOptions): Error;\\n    (message?: string, options?: ErrorOptions): Error;\\n}\\n\\ninterface EvalErrorConstructor {\\n    new (message?: string, options?: ErrorOptions): EvalError;\\n    (message?: string, options?: ErrorOptions): EvalError;\\n}\\n\\ninterface RangeErrorConstructor {\\n    new (message?: string, options?: ErrorOptions): RangeError;\\n    (message?: string, options?: ErrorOptions): RangeError;\\n}\\n\\ninterface ReferenceErrorConstructor {\\n    new (message?: string, options?: ErrorOptions): ReferenceError;\\n    (message?: string, options?: ErrorOptions): ReferenceError;\\n}\\n\\ninterface SyntaxErrorConstructor {\\n    new (message?: string, options?: ErrorOptions): SyntaxError;\\n    (message?: string, options?: ErrorOptions): SyntaxError;\\n}\\n\\ninterface TypeErrorConstructor {\\n    new (message?: string, options?: ErrorOptions): TypeError;\\n    (message?: string, options?: ErrorOptions): TypeError;\\n}\\n\\ninterface URIErrorConstructor {\\n    new (message?: string, options?: ErrorOptions): URIError;\\n    (message?: string, options?: ErrorOptions): URIError;\\n}\\n\\ninterface AggregateErrorConstructor {\\n    new (\\n        errors: Iterable<any>,\\n        message?: string,\\n        options?: ErrorOptions,\\n    ): AggregateError;\\n    (\\n        errors: Iterable<any>,\\n        message?: string,\\n        options?: ErrorOptions,\\n    ): AggregateError;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2022\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.intl.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ndeclare namespace Intl {\\n    /**\\n     * An object with some or all properties of the `Intl.Segmenter` constructor `options` parameter.\\n     *\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter/Segmenter#parameters)\\n     */\\n    interface SegmenterOptions {\\n        /** The locale matching algorithm to use. For information about this option, see [Intl page](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_negotiation). */\\n        localeMatcher?: \\\"best fit\\\" | \\\"lookup\\\" | undefined;\\n        /** The type of input to be split */\\n        granularity?: \\\"grapheme\\\" | \\\"word\\\" | \\\"sentence\\\" | undefined;\\n    }\\n\\n    interface Segmenter {\\n        /**\\n         * Returns `Segments` object containing the segments of the input string, using the segmenter's locale and granularity.\\n         *\\n         * @param input - The text to be segmented as a `string`.\\n         *\\n         * @returns A new iterable Segments object containing the segments of the input string, using the segmenter's locale and granularity.\\n         */\\n        segment(input: string): Segments;\\n        resolvedOptions(): ResolvedSegmenterOptions;\\n    }\\n\\n    interface ResolvedSegmenterOptions {\\n        locale: string;\\n        granularity: \\\"grapheme\\\" | \\\"word\\\" | \\\"sentence\\\";\\n    }\\n\\n    interface Segments {\\n        /**\\n         * Returns an object describing the segment in the original string that includes the code unit at a specified index.\\n         *\\n         * @param codeUnitIndex - A number specifying the index of the code unit in the original input string. If the value is omitted, it defaults to `0`.\\n         */\\n        containing(codeUnitIndex?: number): SegmentData;\\n\\n        /** Returns an iterator to iterate over the segments. */\\n        [Symbol.iterator](): IterableIterator<SegmentData>;\\n    }\\n\\n    interface SegmentData {\\n        /** A string containing the segment extracted from the original input string. */\\n        segment: string;\\n        /** The code unit index in the original input string at which the segment begins. */\\n        index: number;\\n        /** The complete input string that was segmented. */\\n        input: string;\\n        /**\\n         * A boolean value only if granularity is \\\"word\\\"; otherwise, undefined.\\n         * If granularity is \\\"word\\\", then isWordLike is true when the segment is word-like (i.e., consists of letters/numbers/ideographs/etc.); otherwise, false.\\n         */\\n        isWordLike?: boolean;\\n    }\\n\\n    const Segmenter: {\\n        prototype: Segmenter;\\n\\n        /**\\n         * Creates a new `Intl.Segmenter` object.\\n         *\\n         * @param locales - A string with a [BCP 47 language tag](http://tools.ietf.org/html/rfc5646), or an array of such strings.\\n         *  For the general form and interpretation of the `locales` argument,\\n         *  see the [`Intl` page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation).\\n         *\\n         * @param options - An [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter/Segmenter#parameters)\\n         *  with some or all options of `SegmenterOptions`.\\n         *\\n         * @returns [Intl.Segmenter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segments) object.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter).\\n         */\\n        new (locales?: BCP47LanguageTag | BCP47LanguageTag[], options?: SegmenterOptions): Segmenter;\\n\\n        /**\\n         * Returns an array containing those of the provided locales that are supported without having to fall back to the runtime's default locale.\\n         *\\n         * @param locales - A string with a [BCP 47 language tag](http://tools.ietf.org/html/rfc5646), or an array of such strings.\\n         *  For the general form and interpretation of the `locales` argument,\\n         *  see the [`Intl` page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation).\\n         *\\n         * @param options An [object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter/supportedLocalesOf#parameters).\\n         *  with some or all possible options.\\n         *\\n         * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter/supportedLocalesOf)\\n         */\\n        supportedLocalesOf(locales: BCP47LanguageTag | BCP47LanguageTag[], options?: Pick<SegmenterOptions, \\\"localeMatcher\\\">): BCP47LanguageTag[];\\n    };\\n\\n    /**\\n     * Returns a sorted array of the supported collation, calendar, currency, numbering system, timezones, and units by the implementation.\\n     * [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf)\\n     *\\n     * @param key A string indicating the category of values to return.\\n     * @returns A sorted array of the supported values.\\n     */\\n    function supportedValuesOf(key: \\\"calendar\\\" | \\\"collation\\\" | \\\"currency\\\" | \\\"numberingSystem\\\" | \\\"timeZone\\\" | \\\"unit\\\"): string[];\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.object.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface ObjectConstructor {\\n    /**\\n     * Determines whether an object has a property with the specified name.\\n     * @param o An object.\\n     * @param v A property name.\\n     */\\n    hasOwn(o: object, v: PropertyKey): boolean;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.regexp.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface RegExpMatchArray {\\n    indices?: RegExpIndicesArray;\\n}\\n\\ninterface RegExpExecArray {\\n    indices?: RegExpIndicesArray;\\n}\\n\\ninterface RegExpIndicesArray extends Array<[number, number]> {\\n    groups?: {\\n        [key: string]: [number, number];\\n    };\\n}\\n\\ninterface RegExp {\\n    /**\\n     * Returns a Boolean value indicating the state of the hasIndices flag (d) used with with a regular expression.\\n     * Default is false. Read-only.\\n     */\\n    readonly hasIndices: boolean;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.sharedmemory.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Atomics {\\n    /**\\n     * A non-blocking, asynchronous version of wait which is usable on the main thread.\\n     * Waits asynchronously on a shared memory location and returns a Promise\\n     * @param typedArray A shared Int32Array or BigInt64Array.\\n     * @param index The position in the typedArray to wait on.\\n     * @param value The expected value to test.\\n     * @param [timeout] The expected value to test.\\n     */\\n    waitAsync(typedArray: Int32Array, index: number, value: number, timeout?: number): { async: false; value: \\\"not-equal\\\" | \\\"timed-out\\\"; } | { async: true; value: Promise<\\\"ok\\\" | \\\"timed-out\\\">; };\\n\\n    /**\\n     * A non-blocking, asynchronous version of wait which is usable on the main thread.\\n     * Waits asynchronously on a shared memory location and returns a Promise\\n     * @param typedArray A shared Int32Array or BigInt64Array.\\n     * @param index The position in the typedArray to wait on.\\n     * @param value The expected value to test.\\n     * @param [timeout] The expected value to test.\\n     */\\n    waitAsync(typedArray: BigInt64Array, index: number, value: bigint, timeout?: number): { async: false; value: \\\"not-equal\\\" | \\\"timed-out\\\"; } | { async: true; value: Promise<\\\"ok\\\" | \\\"timed-out\\\">; };\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2022.string.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface String {\\n    /**\\n     * Returns a new String consisting of the single UTF-16 code unit located at the specified index.\\n     * @param index The zero-based index of the desired code unit. A negative index will count back from the last item.\\n     */\\n    at(index: number): string | undefined;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2023.array.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface Array<T> {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S | undefined;\\n    findLast(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): number;\\n\\n    /**\\n     * Returns a copy of an array with its elements reversed.\\n     */\\n    toReversed(): T[];\\n\\n    /**\\n     * Returns a copy of an array with its elements sorted.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending, ASCII character order.\\n     * ```ts\\n     * [11, 2, 22, 1].toSorted((a, b) => a - b) // [1, 2, 11, 22]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: T, b: T) => number): T[];\\n\\n    /**\\n     * Copies an array and removes elements and, if necessary, inserts new elements in their place. Returns the copied array.\\n     * @param start The zero-based location in the array from which to start removing elements.\\n     * @param deleteCount The number of elements to remove.\\n     * @param items Elements to insert into the copied array in place of the deleted elements.\\n     * @returns The copied array.\\n     */\\n    toSpliced(start: number, deleteCount: number, ...items: T[]): T[];\\n\\n    /**\\n     * Copies an array and removes elements while returning the remaining elements.\\n     * @param start The zero-based location in the array from which to start removing elements.\\n     * @param deleteCount The number of elements to remove.\\n     * @returns A copy of the original array with the remaining elements.\\n     */\\n    toSpliced(start: number, deleteCount?: number): T[];\\n\\n    /**\\n     * Copies an array, then overwrites the value at the provided index with the\\n     * given value. If the index is negative, then it replaces from the end\\n     * of the array.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to write into the copied array.\\n     * @returns The copied array with the updated value.\\n     */\\n    with(index: number, value: T): T[];\\n}\\n\\ninterface ReadonlyArray<T> {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends T>(\\n        predicate: (value: T, index: number, array: readonly T[]) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (value: T, index: number, array: readonly T[]) => unknown,\\n        thisArg?: any,\\n    ): T | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (value: T, index: number, array: readonly T[]) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copied array with all of its elements reversed.\\n     */\\n    toReversed(): T[];\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending, ASCII character order.\\n     * ```ts\\n     * [11, 2, 22, 1].toSorted((a, b) => a - b) // [1, 2, 11, 22]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: T, b: T) => number): T[];\\n\\n    /**\\n     * Copies an array and removes elements while, if necessary, inserting new elements in their place, returning the remaining elements.\\n     * @param start The zero-based location in the array from which to start removing elements.\\n     * @param deleteCount The number of elements to remove.\\n     * @param items Elements to insert into the copied array in place of the deleted elements.\\n     * @returns A copy of the original array with the remaining elements.\\n     */\\n    toSpliced(start: number, deleteCount: number, ...items: T[]): T[];\\n\\n    /**\\n     * Copies an array and removes elements while returning the remaining elements.\\n     * @param start The zero-based location in the array from which to start removing elements.\\n     * @param deleteCount The number of elements to remove.\\n     * @returns A copy of the original array with the remaining elements.\\n     */\\n    toSpliced(start: number, deleteCount?: number): T[];\\n\\n    /**\\n     * Copies an array, then overwrites the value at the provided index with the\\n     * given value. If the index is negative, then it replaces from the end\\n     * of the array\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: T): T[];\\n}\\n\\ninterface Int8Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Int8Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (value: number, index: number, array: Int8Array) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (value: number, index: number, array: Int8Array) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Uint8Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Uint8Array.from([11, 2, 22, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Uint8Array(4) [1, 2, 11, 22]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Uint8Array;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Uint8Array;\\n}\\n\\ninterface Uint8Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint8Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (value: number, index: number, array: Uint8Array) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (value: number, index: number, array: Uint8Array) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Uint8Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Uint8Array.from([11, 2, 22, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Uint8Array(4) [1, 2, 11, 22]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Uint8Array;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Uint8Array;\\n}\\n\\ninterface Uint8ClampedArray {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint8ClampedArray,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint8ClampedArray,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint8ClampedArray,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Uint8ClampedArray;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Uint8ClampedArray.from([11, 2, 22, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Uint8ClampedArray(4) [1, 2, 11, 22]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Uint8ClampedArray;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Uint8ClampedArray;\\n}\\n\\ninterface Int16Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Int16Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (value: number, index: number, array: Int16Array) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (value: number, index: number, array: Int16Array) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Int16Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Int16Array.from([11, 2, -22, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Int16Array(4) [-22, 1, 2, 11]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Int16Array;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Int16Array;\\n}\\n\\ninterface Uint16Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint16Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint16Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint16Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Uint16Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Uint16Array.from([11, 2, 22, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Uint16Array(4) [1, 2, 11, 22]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Uint16Array;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Uint16Array;\\n}\\n\\ninterface Int32Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Int32Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (value: number, index: number, array: Int32Array) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (value: number, index: number, array: Int32Array) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Int32Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Int32Array.from([11, 2, -22, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Int32Array(4) [-22, 1, 2, 11]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Int32Array;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Int32Array;\\n}\\n\\ninterface Uint32Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint32Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint32Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Uint32Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Uint32Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Uint32Array.from([11, 2, 22, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Uint32Array(4) [1, 2, 11, 22]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Uint32Array;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Uint32Array;\\n}\\n\\ninterface Float32Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Float32Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Float32Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Float32Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Float32Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Float32Array.from([11.25, 2, -22.5, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Float32Array(4) [-22.5, 1, 2, 11.5]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Float32Array;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Float32Array;\\n}\\n\\ninterface Float64Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends number>(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Float64Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Float64Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (\\n            value: number,\\n            index: number,\\n            array: Float64Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): Float64Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = Float64Array.from([11.25, 2, -22.5, 1]);\\n     * myNums.toSorted((a, b) => a - b) // Float64Array(4) [-22.5, 1, 2, 11.5]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: number, b: number) => number): Float64Array;\\n\\n    /**\\n     * Copies the array and inserts the given number at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: number): Float64Array;\\n}\\n\\ninterface BigInt64Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends bigint>(\\n        predicate: (\\n            value: bigint,\\n            index: number,\\n            array: BigInt64Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (\\n            value: bigint,\\n            index: number,\\n            array: BigInt64Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): bigint | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (\\n            value: bigint,\\n            index: number,\\n            array: BigInt64Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): BigInt64Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = BigInt64Array.from([11n, 2n, -22n, 1n]);\\n     * myNums.toSorted((a, b) => Number(a - b)) // BigInt64Array(4) [-22n, 1n, 2n, 11n]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: bigint, b: bigint) => number): BigInt64Array;\\n\\n    /**\\n     * Copies the array and inserts the given bigint at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: bigint): BigInt64Array;\\n}\\n\\ninterface BigUint64Array {\\n    /**\\n     * Returns the value of the last element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate findLast calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found, findLast\\n     * immediately returns that element value. Otherwise, findLast returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLast<S extends bigint>(\\n        predicate: (\\n            value: bigint,\\n            index: number,\\n            array: BigUint64Array,\\n        ) => value is S,\\n        thisArg?: any,\\n    ): S | undefined;\\n    findLast(\\n        predicate: (\\n            value: bigint,\\n            index: number,\\n            array: BigUint64Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): bigint | undefined;\\n\\n    /**\\n     * Returns the index of the last element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate findLastIndex calls predicate once for each element of the array, in descending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findLastIndex immediately returns that element index. Otherwise, findLastIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findLastIndex(\\n        predicate: (\\n            value: bigint,\\n            index: number,\\n            array: BigUint64Array,\\n        ) => unknown,\\n        thisArg?: any,\\n    ): number;\\n\\n    /**\\n     * Copies the array and returns the copy with the elements in reverse order.\\n     */\\n    toReversed(): BigUint64Array;\\n\\n    /**\\n     * Copies and sorts the array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * const myNums = BigUint64Array.from([11n, 2n, 22n, 1n]);\\n     * myNums.toSorted((a, b) => Number(a - b)) // BigUint64Array(4) [1n, 2n, 11n, 22n]\\n     * ```\\n     */\\n    toSorted(compareFn?: (a: bigint, b: bigint) => number): BigUint64Array;\\n\\n    /**\\n     * Copies the array and inserts the given bigint at the provided index.\\n     * @param index The index of the value to overwrite. If the index is\\n     * negative, then it replaces from the end of the array.\\n     * @param value The value to insert into the copied array.\\n     * @returns A copy of the original array with the inserted value.\\n     */\\n    with(index: number, value: bigint): BigUint64Array;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2023.collection.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ninterface WeakKeyTypes {\\n    symbol: symbol;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2023.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2022\\\" />\\n/// <reference lib=\\\"es2023.array\\\" />\\n/// <reference lib=\\\"es2023.collection\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es2023.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2023\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.es5.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"decorators\\\" />\\n/// <reference lib=\\\"decorators.legacy\\\" />\\n\\n/////////////////////////////\\n/// ECMAScript APIs\\n/////////////////////////////\\n\\ndeclare var NaN: number;\\ndeclare var Infinity: number;\\n\\n/**\\n * Evaluates JavaScript code and executes it.\\n * @param x A String value that contains valid JavaScript code.\\n */\\ndeclare function eval(x: string): any;\\n\\n/**\\n * Converts a string to an integer.\\n * @param string A string to convert into a number.\\n * @param radix A value between 2 and 36 that specifies the base of the number in `string`.\\n * If this argument is not supplied, strings with a prefix of '0x' are considered hexadecimal.\\n * All other strings are considered decimal.\\n */\\ndeclare function parseInt(string: string, radix?: number): number;\\n\\n/**\\n * Converts a string to a floating-point number.\\n * @param string A string that contains a floating-point number.\\n */\\ndeclare function parseFloat(string: string): number;\\n\\n/**\\n * Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).\\n * @param number A numeric value.\\n */\\ndeclare function isNaN(number: number): boolean;\\n\\n/**\\n * Determines whether a supplied number is finite.\\n * @param number Any numeric value.\\n */\\ndeclare function isFinite(number: number): boolean;\\n\\n/**\\n * Gets the unencoded version of an encoded Uniform Resource Identifier (URI).\\n * @param encodedURI A value representing an encoded URI.\\n */\\ndeclare function decodeURI(encodedURI: string): string;\\n\\n/**\\n * Gets the unencoded version of an encoded component of a Uniform Resource Identifier (URI).\\n * @param encodedURIComponent A value representing an encoded URI component.\\n */\\ndeclare function decodeURIComponent(encodedURIComponent: string): string;\\n\\n/**\\n * Encodes a text string as a valid Uniform Resource Identifier (URI)\\n * @param uri A value representing an unencoded URI.\\n */\\ndeclare function encodeURI(uri: string): string;\\n\\n/**\\n * Encodes a text string as a valid component of a Uniform Resource Identifier (URI).\\n * @param uriComponent A value representing an unencoded URI component.\\n */\\ndeclare function encodeURIComponent(uriComponent: string | number | boolean): string;\\n\\n/**\\n * Computes a new string in which certain characters have been replaced by a hexadecimal escape sequence.\\n * @deprecated A legacy feature for browser compatibility\\n * @param string A string value\\n */\\ndeclare function escape(string: string): string;\\n\\n/**\\n * Computes a new string in which hexadecimal escape sequences are replaced with the character that it represents.\\n * @deprecated A legacy feature for browser compatibility\\n * @param string A string value\\n */\\ndeclare function unescape(string: string): string;\\n\\ninterface Symbol {\\n    /** Returns a string representation of an object. */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): symbol;\\n}\\n\\ndeclare type PropertyKey = string | number | symbol;\\n\\ninterface PropertyDescriptor {\\n    configurable?: boolean;\\n    enumerable?: boolean;\\n    value?: any;\\n    writable?: boolean;\\n    get?(): any;\\n    set?(v: any): void;\\n}\\n\\ninterface PropertyDescriptorMap {\\n    [key: PropertyKey]: PropertyDescriptor;\\n}\\n\\ninterface Object {\\n    /** The initial value of Object.prototype.constructor is the standard built-in Object constructor. */\\n    constructor: Function;\\n\\n    /** Returns a string representation of an object. */\\n    toString(): string;\\n\\n    /** Returns a date converted to a string using the current locale. */\\n    toLocaleString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Object;\\n\\n    /**\\n     * Determines whether an object has a property with the specified name.\\n     * @param v A property name.\\n     */\\n    hasOwnProperty(v: PropertyKey): boolean;\\n\\n    /**\\n     * Determines whether an object exists in another object's prototype chain.\\n     * @param v Another object whose prototype chain is to be checked.\\n     */\\n    isPrototypeOf(v: Object): boolean;\\n\\n    /**\\n     * Determines whether a specified property is enumerable.\\n     * @param v A property name.\\n     */\\n    propertyIsEnumerable(v: PropertyKey): boolean;\\n}\\n\\ninterface ObjectConstructor {\\n    new (value?: any): Object;\\n    (): any;\\n    (value: any): any;\\n\\n    /** A reference to the prototype for a class of objects. */\\n    readonly prototype: Object;\\n\\n    /**\\n     * Returns the prototype of an object.\\n     * @param o The object that references the prototype.\\n     */\\n    getPrototypeOf(o: any): any;\\n\\n    /**\\n     * Gets the own property descriptor of the specified object.\\n     * An own property descriptor is one that is defined directly on the object and is not inherited from the object's prototype.\\n     * @param o Object that contains the property.\\n     * @param p Name of the property.\\n     */\\n    getOwnPropertyDescriptor(o: any, p: PropertyKey): PropertyDescriptor | undefined;\\n\\n    /**\\n     * Returns the names of the own properties of an object. The own properties of an object are those that are defined directly\\n     * on that object, and are not inherited from the object's prototype. The properties of an object include both fields (objects) and functions.\\n     * @param o Object that contains the own properties.\\n     */\\n    getOwnPropertyNames(o: any): string[];\\n\\n    /**\\n     * Creates an object that has the specified prototype or that has null prototype.\\n     * @param o Object to use as a prototype. May be null.\\n     */\\n    create(o: object | null): any;\\n\\n    /**\\n     * Creates an object that has the specified prototype, and that optionally contains specified properties.\\n     * @param o Object to use as a prototype. May be null\\n     * @param properties JavaScript object that contains one or more property descriptors.\\n     */\\n    create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;\\n\\n    /**\\n     * Adds a property to an object, or modifies attributes of an existing property.\\n     * @param o Object on which to add or modify the property. This can be a native JavaScript object (that is, a user-defined object or a built in object) or a DOM object.\\n     * @param p The property name.\\n     * @param attributes Descriptor for the property. It can be for a data property or an accessor property.\\n     */\\n    defineProperty<T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): T;\\n\\n    /**\\n     * Adds one or more properties to an object, and/or modifies attributes of existing properties.\\n     * @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object.\\n     * @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property.\\n     */\\n    defineProperties<T>(o: T, properties: PropertyDescriptorMap & ThisType<any>): T;\\n\\n    /**\\n     * Prevents the modification of attributes of existing properties, and prevents the addition of new properties.\\n     * @param o Object on which to lock the attributes.\\n     */\\n    seal<T>(o: T): T;\\n\\n    /**\\n     * Prevents the modification of existing property attributes and values, and prevents the addition of new properties.\\n     * @param f Object on which to lock the attributes.\\n     */\\n    freeze<T extends Function>(f: T): T;\\n\\n    /**\\n     * Prevents the modification of existing property attributes and values, and prevents the addition of new properties.\\n     * @param o Object on which to lock the attributes.\\n     */\\n    freeze<T extends { [idx: string]: U | null | undefined | object; }, U extends string | bigint | number | boolean | symbol>(o: T): Readonly<T>;\\n\\n    /**\\n     * Prevents the modification of existing property attributes and values, and prevents the addition of new properties.\\n     * @param o Object on which to lock the attributes.\\n     */\\n    freeze<T>(o: T): Readonly<T>;\\n\\n    /**\\n     * Prevents the addition of new properties to an object.\\n     * @param o Object to make non-extensible.\\n     */\\n    preventExtensions<T>(o: T): T;\\n\\n    /**\\n     * Returns true if existing property attributes cannot be modified in an object and new properties cannot be added to the object.\\n     * @param o Object to test.\\n     */\\n    isSealed(o: any): boolean;\\n\\n    /**\\n     * Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object.\\n     * @param o Object to test.\\n     */\\n    isFrozen(o: any): boolean;\\n\\n    /**\\n     * Returns a value that indicates whether new properties can be added to an object.\\n     * @param o Object to test.\\n     */\\n    isExtensible(o: any): boolean;\\n\\n    /**\\n     * Returns the names of the enumerable string properties and methods of an object.\\n     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.\\n     */\\n    keys(o: object): string[];\\n}\\n\\n/**\\n * Provides functionality common to all JavaScript objects.\\n */\\ndeclare var Object: ObjectConstructor;\\n\\n/**\\n * Creates a new function.\\n */\\ninterface Function {\\n    /**\\n     * Calls the function, substituting the specified object for the this value of the function, and the specified array for the arguments of the function.\\n     * @param thisArg The object to be used as the this object.\\n     * @param argArray A set of arguments to be passed to the function.\\n     */\\n    apply(this: Function, thisArg: any, argArray?: any): any;\\n\\n    /**\\n     * Calls a method of an object, substituting another object for the current object.\\n     * @param thisArg The object to be used as the current object.\\n     * @param argArray A list of arguments to be passed to the method.\\n     */\\n    call(this: Function, thisArg: any, ...argArray: any[]): any;\\n\\n    /**\\n     * For a given function, creates a bound function that has the same body as the original function.\\n     * The this object of the bound function is associated with the specified object, and has the specified initial parameters.\\n     * @param thisArg An object to which the this keyword can refer inside the new function.\\n     * @param argArray A list of arguments to be passed to the new function.\\n     */\\n    bind(this: Function, thisArg: any, ...argArray: any[]): any;\\n\\n    /** Returns a string representation of a function. */\\n    toString(): string;\\n\\n    prototype: any;\\n    readonly length: number;\\n\\n    // Non-standard extensions\\n    arguments: any;\\n    caller: Function;\\n}\\n\\ninterface FunctionConstructor {\\n    /**\\n     * Creates a new function.\\n     * @param args A list of arguments the function accepts.\\n     */\\n    new (...args: string[]): Function;\\n    (...args: string[]): Function;\\n    readonly prototype: Function;\\n}\\n\\ndeclare var Function: FunctionConstructor;\\n\\n/**\\n * Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter.\\n */\\ntype ThisParameterType<T> = T extends (this: infer U, ...args: never) => any ? U : unknown;\\n\\n/**\\n * Removes the 'this' parameter from a function type.\\n */\\ntype OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: infer A) => infer R ? (...args: A) => R : T;\\n\\ninterface CallableFunction extends Function {\\n    /**\\n     * Calls the function with the specified object as the this value and the elements of specified array as the arguments.\\n     * @param thisArg The object to be used as the this object.\\n     */\\n    apply<T, R>(this: (this: T) => R, thisArg: T): R;\\n\\n    /**\\n     * Calls the function with the specified object as the this value and the elements of specified array as the arguments.\\n     * @param thisArg The object to be used as the this object.\\n     * @param args An array of argument values to be passed to the function.\\n     */\\n    apply<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, args: A): R;\\n\\n    /**\\n     * Calls the function with the specified object as the this value and the specified rest arguments as the arguments.\\n     * @param thisArg The object to be used as the this object.\\n     * @param args Argument values to be passed to the function.\\n     */\\n    call<T, A extends any[], R>(this: (this: T, ...args: A) => R, thisArg: T, ...args: A): R;\\n\\n    /**\\n     * For a given function, creates a bound function that has the same body as the original function.\\n     * The this object of the bound function is associated with the specified object, and has the specified initial parameters.\\n     * @param thisArg The object to be used as the this object.\\n     */\\n    bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;\\n\\n    /**\\n     * For a given function, creates a bound function that has the same body as the original function.\\n     * The this object of the bound function is associated with the specified object, and has the specified initial parameters.\\n     * @param thisArg The object to be used as the this object.\\n     * @param args Arguments to bind to the parameters of the function.\\n     */\\n    bind<T, A extends any[], B extends any[], R>(this: (this: T, ...args: [...A, ...B]) => R, thisArg: T, ...args: A): (...args: B) => R;\\n}\\n\\ninterface NewableFunction extends Function {\\n    /**\\n     * Calls the function with the specified object as the this value and the elements of specified array as the arguments.\\n     * @param thisArg The object to be used as the this object.\\n     */\\n    apply<T>(this: new () => T, thisArg: T): void;\\n    /**\\n     * Calls the function with the specified object as the this value and the elements of specified array as the arguments.\\n     * @param thisArg The object to be used as the this object.\\n     * @param args An array of argument values to be passed to the function.\\n     */\\n    apply<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, args: A): void;\\n\\n    /**\\n     * Calls the function with the specified object as the this value and the specified rest arguments as the arguments.\\n     * @param thisArg The object to be used as the this object.\\n     * @param args Argument values to be passed to the function.\\n     */\\n    call<T, A extends any[]>(this: new (...args: A) => T, thisArg: T, ...args: A): void;\\n\\n    /**\\n     * For a given function, creates a bound function that has the same body as the original function.\\n     * The this object of the bound function is associated with the specified object, and has the specified initial parameters.\\n     * @param thisArg The object to be used as the this object.\\n     */\\n    bind<T>(this: T, thisArg: any): T;\\n\\n    /**\\n     * For a given function, creates a bound function that has the same body as the original function.\\n     * The this object of the bound function is associated with the specified object, and has the specified initial parameters.\\n     * @param thisArg The object to be used as the this object.\\n     * @param args Arguments to bind to the parameters of the function.\\n     */\\n    bind<A extends any[], B extends any[], R>(this: new (...args: [...A, ...B]) => R, thisArg: any, ...args: A): new (...args: B) => R;\\n}\\n\\ninterface IArguments {\\n    [index: number]: any;\\n    length: number;\\n    callee: Function;\\n}\\n\\ninterface String {\\n    /** Returns a string representation of a string. */\\n    toString(): string;\\n\\n    /**\\n     * Returns the character at the specified index.\\n     * @param pos The zero-based index of the desired character.\\n     */\\n    charAt(pos: number): string;\\n\\n    /**\\n     * Returns the Unicode value of the character at the specified location.\\n     * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned.\\n     */\\n    charCodeAt(index: number): number;\\n\\n    /**\\n     * Returns a string that contains the concatenation of two or more strings.\\n     * @param strings The strings to append to the end of the string.\\n     */\\n    concat(...strings: string[]): string;\\n\\n    /**\\n     * Returns the position of the first occurrence of a substring.\\n     * @param searchString The substring to search for in the string\\n     * @param position The index at which to begin searching the String object. If omitted, search starts at the beginning of the string.\\n     */\\n    indexOf(searchString: string, position?: number): number;\\n\\n    /**\\n     * Returns the last occurrence of a substring in the string.\\n     * @param searchString The substring to search for.\\n     * @param position The index at which to begin searching. If omitted, the search begins at the end of the string.\\n     */\\n    lastIndexOf(searchString: string, position?: number): number;\\n\\n    /**\\n     * Determines whether two strings are equivalent in the current locale.\\n     * @param that String to compare to target string\\n     */\\n    localeCompare(that: string): number;\\n\\n    /**\\n     * Matches a string with a regular expression, and returns an array containing the results of that search.\\n     * @param regexp A variable name or string literal containing the regular expression pattern and flags.\\n     */\\n    match(regexp: string | RegExp): RegExpMatchArray | null;\\n\\n    /**\\n     * Replaces text in a string, using a regular expression or search string.\\n     * @param searchValue A string or regular expression to search for.\\n     * @param replaceValue A string containing the text to replace. When the {@linkcode searchValue} is a `RegExp`, all matches are replaced if the `g` flag is set (or only those matches at the beginning, if the `y` flag is also present). Otherwise, only the first match of {@linkcode searchValue} is replaced.\\n     */\\n    replace(searchValue: string | RegExp, replaceValue: string): string;\\n\\n    /**\\n     * Replaces text in a string, using a regular expression or search string.\\n     * @param searchValue A string to search for.\\n     * @param replacer A function that returns the replacement text.\\n     */\\n    replace(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string;\\n\\n    /**\\n     * Finds the first substring match in a regular expression search.\\n     * @param regexp The regular expression pattern and applicable flags.\\n     */\\n    search(regexp: string | RegExp): number;\\n\\n    /**\\n     * Returns a section of a string.\\n     * @param start The index to the beginning of the specified portion of stringObj.\\n     * @param end The index to the end of the specified portion of stringObj. The substring includes the characters up to, but not including, the character indicated by end.\\n     * If this value is not specified, the substring continues to the end of stringObj.\\n     */\\n    slice(start?: number, end?: number): string;\\n\\n    /**\\n     * Split a string into substrings using the specified separator and return them as an array.\\n     * @param separator A string that identifies character or characters to use in separating the string. If omitted, a single-element array containing the entire string is returned.\\n     * @param limit A value used to limit the number of elements returned in the array.\\n     */\\n    split(separator: string | RegExp, limit?: number): string[];\\n\\n    /**\\n     * Returns the substring at the specified location within a String object.\\n     * @param start The zero-based index number indicating the beginning of the substring.\\n     * @param end Zero-based index number indicating the end of the substring. The substring includes the characters up to, but not including, the character indicated by end.\\n     * If end is omitted, the characters from start through the end of the original string are returned.\\n     */\\n    substring(start: number, end?: number): string;\\n\\n    /** Converts all the alphabetic characters in a string to lowercase. */\\n    toLowerCase(): string;\\n\\n    /** Converts all alphabetic characters to lowercase, taking into account the host environment's current locale. */\\n    toLocaleLowerCase(locales?: string | string[]): string;\\n\\n    /** Converts all the alphabetic characters in a string to uppercase. */\\n    toUpperCase(): string;\\n\\n    /** Returns a string where all alphabetic characters have been converted to uppercase, taking into account the host environment's current locale. */\\n    toLocaleUpperCase(locales?: string | string[]): string;\\n\\n    /** Removes the leading and trailing white space and line terminator characters from a string. */\\n    trim(): string;\\n\\n    /** Returns the length of a String object. */\\n    readonly length: number;\\n\\n    // IE extensions\\n    /**\\n     * Gets a substring beginning at the specified location and having the specified length.\\n     * @deprecated A legacy feature for browser compatibility\\n     * @param from The starting position of the desired substring. The index of the first character in the string is zero.\\n     * @param length The number of characters to include in the returned substring.\\n     */\\n    substr(from: number, length?: number): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): string;\\n\\n    readonly [index: number]: string;\\n}\\n\\ninterface StringConstructor {\\n    new (value?: any): String;\\n    (value?: any): string;\\n    readonly prototype: String;\\n    fromCharCode(...codes: number[]): string;\\n}\\n\\n/**\\n * Allows manipulation and formatting of text strings and determination and location of substrings within strings.\\n */\\ndeclare var String: StringConstructor;\\n\\ninterface Boolean {\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): boolean;\\n}\\n\\ninterface BooleanConstructor {\\n    new (value?: any): Boolean;\\n    <T>(value?: T): boolean;\\n    readonly prototype: Boolean;\\n}\\n\\ndeclare var Boolean: BooleanConstructor;\\n\\ninterface Number {\\n    /**\\n     * Returns a string representation of an object.\\n     * @param radix Specifies a radix for converting numeric values to strings. This value is only used for numbers.\\n     */\\n    toString(radix?: number): string;\\n\\n    /**\\n     * Returns a string representing a number in fixed-point notation.\\n     * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.\\n     */\\n    toFixed(fractionDigits?: number): string;\\n\\n    /**\\n     * Returns a string containing a number represented in exponential notation.\\n     * @param fractionDigits Number of digits after the decimal point. Must be in the range 0 - 20, inclusive.\\n     */\\n    toExponential(fractionDigits?: number): string;\\n\\n    /**\\n     * Returns a string containing a number represented either in exponential or fixed-point notation with a specified number of digits.\\n     * @param precision Number of significant digits. Must be in the range 1 - 21, inclusive.\\n     */\\n    toPrecision(precision?: number): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): number;\\n}\\n\\ninterface NumberConstructor {\\n    new (value?: any): Number;\\n    (value?: any): number;\\n    readonly prototype: Number;\\n\\n    /** The largest number that can be represented in JavaScript. Equal to approximately 1.79E+308. */\\n    readonly MAX_VALUE: number;\\n\\n    /** The closest number to zero that can be represented in JavaScript. Equal to approximately 5.00E-324. */\\n    readonly MIN_VALUE: number;\\n\\n    /**\\n     * A value that is not a number.\\n     * In equality comparisons, NaN does not equal any value, including itself. To test whether a value is equivalent to NaN, use the isNaN function.\\n     */\\n    readonly NaN: number;\\n\\n    /**\\n     * A value that is less than the largest negative number that can be represented in JavaScript.\\n     * JavaScript displays NEGATIVE_INFINITY values as -infinity.\\n     */\\n    readonly NEGATIVE_INFINITY: number;\\n\\n    /**\\n     * A value greater than the largest number that can be represented in JavaScript.\\n     * JavaScript displays POSITIVE_INFINITY values as infinity.\\n     */\\n    readonly POSITIVE_INFINITY: number;\\n}\\n\\n/** An object that represents a number of any kind. All JavaScript numbers are 64-bit floating-point numbers. */\\ndeclare var Number: NumberConstructor;\\n\\ninterface TemplateStringsArray extends ReadonlyArray<string> {\\n    readonly raw: readonly string[];\\n}\\n\\n/**\\n * The type of `import.meta`.\\n *\\n * If you need to declare that a given property exists on `import.meta`,\\n * this type may be augmented via interface merging.\\n */\\ninterface ImportMeta {\\n}\\n\\n/**\\n * The type for the optional second argument to `import()`.\\n *\\n * If your host environment supports additional options, this type may be\\n * augmented via interface merging.\\n */\\ninterface ImportCallOptions {\\n    /** @deprecated*/ assert?: ImportAssertions;\\n    with?: ImportAttributes;\\n}\\n\\n/**\\n * The type for the `assert` property of the optional second argument to `import()`.\\n */\\ninterface ImportAssertions {\\n    [key: string]: string;\\n}\\n\\n/**\\n * The type for the `with` property of the optional second argument to `import()`.\\n */\\ninterface ImportAttributes {\\n    [key: string]: string;\\n}\\n\\ninterface Math {\\n    /** The mathematical constant e. This is Euler's number, the base of natural logarithms. */\\n    readonly E: number;\\n    /** The natural logarithm of 10. */\\n    readonly LN10: number;\\n    /** The natural logarithm of 2. */\\n    readonly LN2: number;\\n    /** The base-2 logarithm of e. */\\n    readonly LOG2E: number;\\n    /** The base-10 logarithm of e. */\\n    readonly LOG10E: number;\\n    /** Pi. This is the ratio of the circumference of a circle to its diameter. */\\n    readonly PI: number;\\n    /** The square root of 0.5, or, equivalently, one divided by the square root of 2. */\\n    readonly SQRT1_2: number;\\n    /** The square root of 2. */\\n    readonly SQRT2: number;\\n    /**\\n     * Returns the absolute value of a number (the value without regard to whether it is positive or negative).\\n     * For example, the absolute value of -5 is the same as the absolute value of 5.\\n     * @param x A numeric expression for which the absolute value is needed.\\n     */\\n    abs(x: number): number;\\n    /**\\n     * Returns the arc cosine (or inverse cosine) of a number.\\n     * @param x A numeric expression.\\n     */\\n    acos(x: number): number;\\n    /**\\n     * Returns the arcsine of a number.\\n     * @param x A numeric expression.\\n     */\\n    asin(x: number): number;\\n    /**\\n     * Returns the arctangent of a number.\\n     * @param x A numeric expression for which the arctangent is needed.\\n     */\\n    atan(x: number): number;\\n    /**\\n     * Returns the angle (in radians) from the X axis to a point.\\n     * @param y A numeric expression representing the cartesian y-coordinate.\\n     * @param x A numeric expression representing the cartesian x-coordinate.\\n     */\\n    atan2(y: number, x: number): number;\\n    /**\\n     * Returns the smallest integer greater than or equal to its numeric argument.\\n     * @param x A numeric expression.\\n     */\\n    ceil(x: number): number;\\n    /**\\n     * Returns the cosine of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    cos(x: number): number;\\n    /**\\n     * Returns e (the base of natural logarithms) raised to a power.\\n     * @param x A numeric expression representing the power of e.\\n     */\\n    exp(x: number): number;\\n    /**\\n     * Returns the greatest integer less than or equal to its numeric argument.\\n     * @param x A numeric expression.\\n     */\\n    floor(x: number): number;\\n    /**\\n     * Returns the natural logarithm (base e) of a number.\\n     * @param x A numeric expression.\\n     */\\n    log(x: number): number;\\n    /**\\n     * Returns the larger of a set of supplied numeric expressions.\\n     * @param values Numeric expressions to be evaluated.\\n     */\\n    max(...values: number[]): number;\\n    /**\\n     * Returns the smaller of a set of supplied numeric expressions.\\n     * @param values Numeric expressions to be evaluated.\\n     */\\n    min(...values: number[]): number;\\n    /**\\n     * Returns the value of a base expression taken to a specified power.\\n     * @param x The base value of the expression.\\n     * @param y The exponent value of the expression.\\n     */\\n    pow(x: number, y: number): number;\\n    /** Returns a pseudorandom number between 0 and 1. */\\n    random(): number;\\n    /**\\n     * Returns a supplied numeric expression rounded to the nearest integer.\\n     * @param x The value to be rounded to the nearest integer.\\n     */\\n    round(x: number): number;\\n    /**\\n     * Returns the sine of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    sin(x: number): number;\\n    /**\\n     * Returns the square root of a number.\\n     * @param x A numeric expression.\\n     */\\n    sqrt(x: number): number;\\n    /**\\n     * Returns the tangent of a number.\\n     * @param x A numeric expression that contains an angle measured in radians.\\n     */\\n    tan(x: number): number;\\n}\\n/** An intrinsic object that provides basic mathematics functionality and constants. */\\ndeclare var Math: Math;\\n\\n/** Enables basic storage and retrieval of dates and times. */\\ninterface Date {\\n    /** Returns a string representation of a date. The format of the string depends on the locale. */\\n    toString(): string;\\n    /** Returns a date as a string value. */\\n    toDateString(): string;\\n    /** Returns a time as a string value. */\\n    toTimeString(): string;\\n    /** Returns a value as a string value appropriate to the host environment's current locale. */\\n    toLocaleString(): string;\\n    /** Returns a date as a string value appropriate to the host environment's current locale. */\\n    toLocaleDateString(): string;\\n    /** Returns a time as a string value appropriate to the host environment's current locale. */\\n    toLocaleTimeString(): string;\\n    /** Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC. */\\n    valueOf(): number;\\n    /** Returns the stored time value in milliseconds since midnight, January 1, 1970 UTC. */\\n    getTime(): number;\\n    /** Gets the year, using local time. */\\n    getFullYear(): number;\\n    /** Gets the year using Universal Coordinated Time (UTC). */\\n    getUTCFullYear(): number;\\n    /** Gets the month, using local time. */\\n    getMonth(): number;\\n    /** Gets the month of a Date object using Universal Coordinated Time (UTC). */\\n    getUTCMonth(): number;\\n    /** Gets the day-of-the-month, using local time. */\\n    getDate(): number;\\n    /** Gets the day-of-the-month, using Universal Coordinated Time (UTC). */\\n    getUTCDate(): number;\\n    /** Gets the day of the week, using local time. */\\n    getDay(): number;\\n    /** Gets the day of the week using Universal Coordinated Time (UTC). */\\n    getUTCDay(): number;\\n    /** Gets the hours in a date, using local time. */\\n    getHours(): number;\\n    /** Gets the hours value in a Date object using Universal Coordinated Time (UTC). */\\n    getUTCHours(): number;\\n    /** Gets the minutes of a Date object, using local time. */\\n    getMinutes(): number;\\n    /** Gets the minutes of a Date object using Universal Coordinated Time (UTC). */\\n    getUTCMinutes(): number;\\n    /** Gets the seconds of a Date object, using local time. */\\n    getSeconds(): number;\\n    /** Gets the seconds of a Date object using Universal Coordinated Time (UTC). */\\n    getUTCSeconds(): number;\\n    /** Gets the milliseconds of a Date, using local time. */\\n    getMilliseconds(): number;\\n    /** Gets the milliseconds of a Date object using Universal Coordinated Time (UTC). */\\n    getUTCMilliseconds(): number;\\n    /** Gets the difference in minutes between the time on the local computer and Universal Coordinated Time (UTC). */\\n    getTimezoneOffset(): number;\\n    /**\\n     * Sets the date and time value in the Date object.\\n     * @param time A numeric value representing the number of elapsed milliseconds since midnight, January 1, 1970 GMT.\\n     */\\n    setTime(time: number): number;\\n    /**\\n     * Sets the milliseconds value in the Date object using local time.\\n     * @param ms A numeric value equal to the millisecond value.\\n     */\\n    setMilliseconds(ms: number): number;\\n    /**\\n     * Sets the milliseconds value in the Date object using Universal Coordinated Time (UTC).\\n     * @param ms A numeric value equal to the millisecond value.\\n     */\\n    setUTCMilliseconds(ms: number): number;\\n\\n    /**\\n     * Sets the seconds value in the Date object using local time.\\n     * @param sec A numeric value equal to the seconds value.\\n     * @param ms A numeric value equal to the milliseconds value.\\n     */\\n    setSeconds(sec: number, ms?: number): number;\\n    /**\\n     * Sets the seconds value in the Date object using Universal Coordinated Time (UTC).\\n     * @param sec A numeric value equal to the seconds value.\\n     * @param ms A numeric value equal to the milliseconds value.\\n     */\\n    setUTCSeconds(sec: number, ms?: number): number;\\n    /**\\n     * Sets the minutes value in the Date object using local time.\\n     * @param min A numeric value equal to the minutes value.\\n     * @param sec A numeric value equal to the seconds value.\\n     * @param ms A numeric value equal to the milliseconds value.\\n     */\\n    setMinutes(min: number, sec?: number, ms?: number): number;\\n    /**\\n     * Sets the minutes value in the Date object using Universal Coordinated Time (UTC).\\n     * @param min A numeric value equal to the minutes value.\\n     * @param sec A numeric value equal to the seconds value.\\n     * @param ms A numeric value equal to the milliseconds value.\\n     */\\n    setUTCMinutes(min: number, sec?: number, ms?: number): number;\\n    /**\\n     * Sets the hour value in the Date object using local time.\\n     * @param hours A numeric value equal to the hours value.\\n     * @param min A numeric value equal to the minutes value.\\n     * @param sec A numeric value equal to the seconds value.\\n     * @param ms A numeric value equal to the milliseconds value.\\n     */\\n    setHours(hours: number, min?: number, sec?: number, ms?: number): number;\\n    /**\\n     * Sets the hours value in the Date object using Universal Coordinated Time (UTC).\\n     * @param hours A numeric value equal to the hours value.\\n     * @param min A numeric value equal to the minutes value.\\n     * @param sec A numeric value equal to the seconds value.\\n     * @param ms A numeric value equal to the milliseconds value.\\n     */\\n    setUTCHours(hours: number, min?: number, sec?: number, ms?: number): number;\\n    /**\\n     * Sets the numeric day-of-the-month value of the Date object using local time.\\n     * @param date A numeric value equal to the day of the month.\\n     */\\n    setDate(date: number): number;\\n    /**\\n     * Sets the numeric day of the month in the Date object using Universal Coordinated Time (UTC).\\n     * @param date A numeric value equal to the day of the month.\\n     */\\n    setUTCDate(date: number): number;\\n    /**\\n     * Sets the month value in the Date object using local time.\\n     * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively.\\n     * @param date A numeric value representing the day of the month. If this value is not supplied, the value from a call to the getDate method is used.\\n     */\\n    setMonth(month: number, date?: number): number;\\n    /**\\n     * Sets the month value in the Date object using Universal Coordinated Time (UTC).\\n     * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively.\\n     * @param date A numeric value representing the day of the month. If it is not supplied, the value from a call to the getUTCDate method is used.\\n     */\\n    setUTCMonth(month: number, date?: number): number;\\n    /**\\n     * Sets the year of the Date object using local time.\\n     * @param year A numeric value for the year.\\n     * @param month A zero-based numeric value for the month (0 for January, 11 for December). Must be specified if numDate is specified.\\n     * @param date A numeric value equal for the day of the month.\\n     */\\n    setFullYear(year: number, month?: number, date?: number): number;\\n    /**\\n     * Sets the year value in the Date object using Universal Coordinated Time (UTC).\\n     * @param year A numeric value equal to the year.\\n     * @param month A numeric value equal to the month. The value for January is 0, and other month values follow consecutively. Must be supplied if numDate is supplied.\\n     * @param date A numeric value equal to the day of the month.\\n     */\\n    setUTCFullYear(year: number, month?: number, date?: number): number;\\n    /** Returns a date converted to a string using Universal Coordinated Time (UTC). */\\n    toUTCString(): string;\\n    /** Returns a date as a string value in ISO format. */\\n    toISOString(): string;\\n    /** Used by the JSON.stringify method to enable the transformation of an object's data for JavaScript Object Notation (JSON) serialization. */\\n    toJSON(key?: any): string;\\n}\\n\\ninterface DateConstructor {\\n    new (): Date;\\n    new (value: number | string): Date;\\n    /**\\n     * Creates a new Date.\\n     * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.\\n     * @param monthIndex The month as a number between 0 and 11 (January to December).\\n     * @param date The date as a number between 1 and 31.\\n     * @param hours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour.\\n     * @param minutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes.\\n     * @param seconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds.\\n     * @param ms A number from 0 to 999 that specifies the milliseconds.\\n     */\\n    new (year: number, monthIndex: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date;\\n    (): string;\\n    readonly prototype: Date;\\n    /**\\n     * Parses a string containing a date, and returns the number of milliseconds between that date and midnight, January 1, 1970.\\n     * @param s A date string\\n     */\\n    parse(s: string): number;\\n    /**\\n     * Returns the number of milliseconds between midnight, January 1, 1970 Universal Coordinated Time (UTC) (or GMT) and the specified date.\\n     * @param year The full year designation is required for cross-century date accuracy. If year is between 0 and 99 is used, then year is assumed to be 1900 + year.\\n     * @param monthIndex The month as a number between 0 and 11 (January to December).\\n     * @param date The date as a number between 1 and 31.\\n     * @param hours Must be supplied if minutes is supplied. A number from 0 to 23 (midnight to 11pm) that specifies the hour.\\n     * @param minutes Must be supplied if seconds is supplied. A number from 0 to 59 that specifies the minutes.\\n     * @param seconds Must be supplied if milliseconds is supplied. A number from 0 to 59 that specifies the seconds.\\n     * @param ms A number from 0 to 999 that specifies the milliseconds.\\n     */\\n    UTC(year: number, monthIndex: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number;\\n    /** Returns the number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC). */\\n    now(): number;\\n}\\n\\ndeclare var Date: DateConstructor;\\n\\ninterface RegExpMatchArray extends Array<string> {\\n    /**\\n     * The index of the search at which the result was found.\\n     */\\n    index?: number;\\n    /**\\n     * A copy of the search string.\\n     */\\n    input?: string;\\n    /**\\n     * The first match. This will always be present because `null` will be returned if there are no matches.\\n     */\\n    0: string;\\n}\\n\\ninterface RegExpExecArray extends Array<string> {\\n    /**\\n     * The index of the search at which the result was found.\\n     */\\n    index: number;\\n    /**\\n     * A copy of the search string.\\n     */\\n    input: string;\\n    /**\\n     * The first match. This will always be present because `null` will be returned if there are no matches.\\n     */\\n    0: string;\\n}\\n\\ninterface RegExp {\\n    /**\\n     * Executes a search on a string using a regular expression pattern, and returns an array containing the results of that search.\\n     * @param string The String object or string literal on which to perform the search.\\n     */\\n    exec(string: string): RegExpExecArray | null;\\n\\n    /**\\n     * Returns a Boolean value that indicates whether or not a pattern exists in a searched string.\\n     * @param string String on which to perform the search.\\n     */\\n    test(string: string): boolean;\\n\\n    /** Returns a copy of the text of the regular expression pattern. Read-only. The regExp argument is a Regular expression object. It can be a variable name or a literal. */\\n    readonly source: string;\\n\\n    /** Returns a Boolean value indicating the state of the global flag (g) used with a regular expression. Default is false. Read-only. */\\n    readonly global: boolean;\\n\\n    /** Returns a Boolean value indicating the state of the ignoreCase flag (i) used with a regular expression. Default is false. Read-only. */\\n    readonly ignoreCase: boolean;\\n\\n    /** Returns a Boolean value indicating the state of the multiline flag (m) used with a regular expression. Default is false. Read-only. */\\n    readonly multiline: boolean;\\n\\n    lastIndex: number;\\n\\n    // Non-standard extensions\\n    /** @deprecated A legacy feature for browser compatibility */\\n    compile(pattern: string, flags?: string): this;\\n}\\n\\ninterface RegExpConstructor {\\n    new (pattern: RegExp | string): RegExp;\\n    new (pattern: string, flags?: string): RegExp;\\n    (pattern: RegExp | string): RegExp;\\n    (pattern: string, flags?: string): RegExp;\\n    readonly \\\"prototype\\\": RegExp;\\n\\n    // Non-standard extensions\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$1\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$2\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$3\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$4\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$5\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$6\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$7\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$8\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$9\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"input\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$_\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"lastMatch\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$&\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"lastParen\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$+\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"leftContext\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$`\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"rightContext\\\": string;\\n    /** @deprecated A legacy feature for browser compatibility */\\n    \\\"$'\\\": string;\\n}\\n\\ndeclare var RegExp: RegExpConstructor;\\n\\ninterface Error {\\n    name: string;\\n    message: string;\\n    stack?: string;\\n}\\n\\ninterface ErrorConstructor {\\n    new (message?: string): Error;\\n    (message?: string): Error;\\n    readonly prototype: Error;\\n}\\n\\ndeclare var Error: ErrorConstructor;\\n\\ninterface EvalError extends Error {\\n}\\n\\ninterface EvalErrorConstructor extends ErrorConstructor {\\n    new (message?: string): EvalError;\\n    (message?: string): EvalError;\\n    readonly prototype: EvalError;\\n}\\n\\ndeclare var EvalError: EvalErrorConstructor;\\n\\ninterface RangeError extends Error {\\n}\\n\\ninterface RangeErrorConstructor extends ErrorConstructor {\\n    new (message?: string): RangeError;\\n    (message?: string): RangeError;\\n    readonly prototype: RangeError;\\n}\\n\\ndeclare var RangeError: RangeErrorConstructor;\\n\\ninterface ReferenceError extends Error {\\n}\\n\\ninterface ReferenceErrorConstructor extends ErrorConstructor {\\n    new (message?: string): ReferenceError;\\n    (message?: string): ReferenceError;\\n    readonly prototype: ReferenceError;\\n}\\n\\ndeclare var ReferenceError: ReferenceErrorConstructor;\\n\\ninterface SyntaxError extends Error {\\n}\\n\\ninterface SyntaxErrorConstructor extends ErrorConstructor {\\n    new (message?: string): SyntaxError;\\n    (message?: string): SyntaxError;\\n    readonly prototype: SyntaxError;\\n}\\n\\ndeclare var SyntaxError: SyntaxErrorConstructor;\\n\\ninterface TypeError extends Error {\\n}\\n\\ninterface TypeErrorConstructor extends ErrorConstructor {\\n    new (message?: string): TypeError;\\n    (message?: string): TypeError;\\n    readonly prototype: TypeError;\\n}\\n\\ndeclare var TypeError: TypeErrorConstructor;\\n\\ninterface URIError extends Error {\\n}\\n\\ninterface URIErrorConstructor extends ErrorConstructor {\\n    new (message?: string): URIError;\\n    (message?: string): URIError;\\n    readonly prototype: URIError;\\n}\\n\\ndeclare var URIError: URIErrorConstructor;\\n\\ninterface JSON {\\n    /**\\n     * Converts a JavaScript Object Notation (JSON) string into an object.\\n     * @param text A valid JSON string.\\n     * @param reviver A function that transforms the results. This function is called for each member of the object.\\n     * If a member contains nested objects, the nested objects are transformed before the parent object is.\\n     */\\n    parse(text: string, reviver?: (this: any, key: string, value: any) => any): any;\\n    /**\\n     * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.\\n     * @param value A JavaScript value, usually an object or array, to be converted.\\n     * @param replacer A function that transforms the results.\\n     * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.\\n     */\\n    stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;\\n    /**\\n     * Converts a JavaScript value to a JavaScript Object Notation (JSON) string.\\n     * @param value A JavaScript value, usually an object or array, to be converted.\\n     * @param replacer An array of strings and numbers that acts as an approved list for selecting the object properties that will be stringified.\\n     * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.\\n     */\\n    stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string;\\n}\\n\\n/**\\n * An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.\\n */\\ndeclare var JSON: JSON;\\n\\n/////////////////////////////\\n/// ECMAScript Array API (specially handled by compiler)\\n/////////////////////////////\\n\\ninterface ReadonlyArray<T> {\\n    /**\\n     * Gets the length of the array. This is a number one higher than the highest element defined in an array.\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n    /**\\n     * Returns a string representation of an array. The elements are converted to string using their toLocaleString methods.\\n     */\\n    toLocaleString(): string;\\n    /**\\n     * Combines two or more arrays.\\n     * @param items Additional items to add to the end of array1.\\n     */\\n    concat(...items: ConcatArray<T>[]): T[];\\n    /**\\n     * Combines two or more arrays.\\n     * @param items Additional items to add to the end of array1.\\n     */\\n    concat(...items: (T | ConcatArray<T>)[]): T[];\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): T[];\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.\\n     */\\n    indexOf(searchElement: T, fromIndex?: number): number;\\n    /**\\n     * Returns the index of the last occurrence of a specified value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.\\n     */\\n    lastIndexOf(searchElement: T, fromIndex?: number): number;\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every<S extends T>(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): this is readonly S[];\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): boolean;\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): boolean;\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: T, index: number, array: readonly T[]) => void, thisArg?: any): void;\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map<U>(callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any): U[];\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter<S extends T>(predicate: (value: T, index: number, array: readonly T[]) => value is S, thisArg?: any): S[];\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any): T[];\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T): T;\\n    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T, initialValue: T): T;\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: readonly T[]) => U, initialValue: U): U;\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T): T;\\n    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T, initialValue: T): T;\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: readonly T[]) => U, initialValue: U): U;\\n\\n    readonly [n: number]: T;\\n}\\n\\ninterface ConcatArray<T> {\\n    readonly length: number;\\n    readonly [n: number]: T;\\n    join(separator?: string): string;\\n    slice(start?: number, end?: number): T[];\\n}\\n\\ninterface Array<T> {\\n    /**\\n     * Gets or sets the length of the array. This is a number one higher than the highest index in the array.\\n     */\\n    length: number;\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n    /**\\n     * Returns a string representation of an array. The elements are converted to string using their toLocaleString methods.\\n     */\\n    toLocaleString(): string;\\n    /**\\n     * Removes the last element from an array and returns it.\\n     * If the array is empty, undefined is returned and the array is not modified.\\n     */\\n    pop(): T | undefined;\\n    /**\\n     * Appends new elements to the end of an array, and returns the new length of the array.\\n     * @param items New elements to add to the array.\\n     */\\n    push(...items: T[]): number;\\n    /**\\n     * Combines two or more arrays.\\n     * This method returns a new array without modifying any existing arrays.\\n     * @param items Additional arrays and/or items to add to the end of the array.\\n     */\\n    concat(...items: ConcatArray<T>[]): T[];\\n    /**\\n     * Combines two or more arrays.\\n     * This method returns a new array without modifying any existing arrays.\\n     * @param items Additional arrays and/or items to add to the end of the array.\\n     */\\n    concat(...items: (T | ConcatArray<T>)[]): T[];\\n    /**\\n     * Adds all the elements of an array into a string, separated by the specified separator string.\\n     * @param separator A string used to separate one element of the array from the next in the resulting string. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n    /**\\n     * Reverses the elements in an array in place.\\n     * This method mutates the array and returns a reference to the same array.\\n     */\\n    reverse(): T[];\\n    /**\\n     * Removes the first element from an array and returns it.\\n     * If the array is empty, undefined is returned and the array is not modified.\\n     */\\n    shift(): T | undefined;\\n    /**\\n     * Returns a copy of a section of an array.\\n     * For both start and end, a negative index can be used to indicate an offset from the end of the array.\\n     * For example, -2 refers to the second to last element of the array.\\n     * @param start The beginning index of the specified portion of the array.\\n     * If start is undefined, then the slice begins at index 0.\\n     * @param end The end index of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     * If end is undefined, then the slice extends to the end of the array.\\n     */\\n    slice(start?: number, end?: number): T[];\\n    /**\\n     * Sorts an array in place.\\n     * This method mutates the array and returns a reference to the same array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if the first argument is less than the second argument, zero if they're equal, and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending, ASCII character order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: T, b: T) => number): this;\\n    /**\\n     * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.\\n     * @param start The zero-based location in the array from which to start removing elements.\\n     * @param deleteCount The number of elements to remove.\\n     * @returns An array containing the elements that were deleted.\\n     */\\n    splice(start: number, deleteCount?: number): T[];\\n    /**\\n     * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.\\n     * @param start The zero-based location in the array from which to start removing elements.\\n     * @param deleteCount The number of elements to remove.\\n     * @param items Elements to insert into the array in place of the deleted elements.\\n     * @returns An array containing the elements that were deleted.\\n     */\\n    splice(start: number, deleteCount: number, ...items: T[]): T[];\\n    /**\\n     * Inserts new elements at the start of an array, and returns the new length of the array.\\n     * @param items Elements to insert at the start of the array.\\n     */\\n    unshift(...items: T[]): number;\\n    /**\\n     * Returns the index of the first occurrence of a value in an array, or -1 if it is not present.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.\\n     */\\n    indexOf(searchElement: T, fromIndex?: number): number;\\n    /**\\n     * Returns the index of the last occurrence of a specified value in an array, or -1 if it is not present.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin searching backward. If fromIndex is omitted, the search starts at the last index in the array.\\n     */\\n    lastIndexOf(searchElement: T, fromIndex?: number): number;\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): this is S[];\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter<S extends T>(predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;\\n    reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;\\n    reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;\\n\\n    [n: number]: T;\\n}\\n\\ninterface ArrayConstructor {\\n    new (arrayLength?: number): any[];\\n    new <T>(arrayLength: number): T[];\\n    new <T>(...items: T[]): T[];\\n    (arrayLength?: number): any[];\\n    <T>(arrayLength: number): T[];\\n    <T>(...items: T[]): T[];\\n    isArray(arg: any): arg is any[];\\n    readonly prototype: any[];\\n}\\n\\ndeclare var Array: ArrayConstructor;\\n\\ninterface TypedPropertyDescriptor<T> {\\n    enumerable?: boolean;\\n    configurable?: boolean;\\n    writable?: boolean;\\n    value?: T;\\n    get?: () => T;\\n    set?: (value: T) => void;\\n}\\n\\ndeclare type PromiseConstructorLike = new <T>(executor: (resolve: (value: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>;\\n\\ninterface PromiseLike<T> {\\n    /**\\n     * Attaches callbacks for the resolution and/or rejection of the Promise.\\n     * @param onfulfilled The callback to execute when the Promise is resolved.\\n     * @param onrejected The callback to execute when the Promise is rejected.\\n     * @returns A Promise for the completion of which ever callback is executed.\\n     */\\n    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;\\n}\\n\\n/**\\n * Represents the completion of an asynchronous operation\\n */\\ninterface Promise<T> {\\n    /**\\n     * Attaches callbacks for the resolution and/or rejection of the Promise.\\n     * @param onfulfilled The callback to execute when the Promise is resolved.\\n     * @param onrejected The callback to execute when the Promise is rejected.\\n     * @returns A Promise for the completion of which ever callback is executed.\\n     */\\n    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;\\n\\n    /**\\n     * Attaches a callback for only the rejection of the Promise.\\n     * @param onrejected The callback to execute when the Promise is rejected.\\n     * @returns A Promise for the completion of the callback.\\n     */\\n    catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;\\n}\\n\\n/**\\n * Recursively unwraps the \\\"awaited type\\\" of a type. Non-promise \\\"thenables\\\" should resolve to `never`. This emulates the behavior of `await`.\\n */\\ntype Awaited<T> = T extends null | undefined ? T : // special case for `null | undefined` when not in `--strictNullChecks` mode\\n    T extends object & { then(onfulfilled: infer F, ...args: infer _): any; } ? // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped\\n        F extends ((value: infer V, ...args: infer _) => any) ? // if the argument to `then` is callable, extracts the first argument\\n            Awaited<V> : // recursively unwrap the value\\n        never : // the argument to `then` was not callable\\n    T; // non-object or non-thenable\\n\\ninterface ArrayLike<T> {\\n    readonly length: number;\\n    readonly [n: number]: T;\\n}\\n\\n/**\\n * Make all properties in T optional\\n */\\ntype Partial<T> = {\\n    [P in keyof T]?: T[P];\\n};\\n\\n/**\\n * Make all properties in T required\\n */\\ntype Required<T> = {\\n    [P in keyof T]-?: T[P];\\n};\\n\\n/**\\n * Make all properties in T readonly\\n */\\ntype Readonly<T> = {\\n    readonly [P in keyof T]: T[P];\\n};\\n\\n/**\\n * From T, pick a set of properties whose keys are in the union K\\n */\\ntype Pick<T, K extends keyof T> = {\\n    [P in K]: T[P];\\n};\\n\\n/**\\n * Construct a type with a set of properties K of type T\\n */\\ntype Record<K extends keyof any, T> = {\\n    [P in K]: T;\\n};\\n\\n/**\\n * Exclude from T those types that are assignable to U\\n */\\ntype Exclude<T, U> = T extends U ? never : T;\\n\\n/**\\n * Extract from T those types that are assignable to U\\n */\\ntype Extract<T, U> = T extends U ? T : never;\\n\\n/**\\n * Construct a type with the properties of T except for those in type K.\\n */\\ntype Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;\\n\\n/**\\n * Exclude null and undefined from T\\n */\\ntype NonNullable<T> = T & {};\\n\\n/**\\n * Obtain the parameters of a function type in a tuple\\n */\\ntype Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;\\n\\n/**\\n * Obtain the parameters of a constructor function type in a tuple\\n */\\ntype ConstructorParameters<T extends abstract new (...args: any) => any> = T extends abstract new (...args: infer P) => any ? P : never;\\n\\n/**\\n * Obtain the return type of a function type\\n */\\ntype ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;\\n\\n/**\\n * Obtain the return type of a constructor function type\\n */\\ntype InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;\\n\\n/**\\n * Convert string literal type to uppercase\\n */\\ntype Uppercase<S extends string> = intrinsic;\\n\\n/**\\n * Convert string literal type to lowercase\\n */\\ntype Lowercase<S extends string> = intrinsic;\\n\\n/**\\n * Convert first character of string literal type to uppercase\\n */\\ntype Capitalize<S extends string> = intrinsic;\\n\\n/**\\n * Convert first character of string literal type to lowercase\\n */\\ntype Uncapitalize<S extends string> = intrinsic;\\n\\n/**\\n * Marker for contextual 'this' type\\n */\\ninterface ThisType<T> {}\\n\\n/**\\n * Stores types to be used with WeakSet, WeakMap, WeakRef, and FinalizationRegistry\\n */\\ninterface WeakKeyTypes {\\n    object: object;\\n}\\n\\ntype WeakKey = WeakKeyTypes[keyof WeakKeyTypes];\\n\\n/**\\n * Represents a raw buffer of binary data, which is used to store data for the\\n * different typed arrays. ArrayBuffers cannot be read from or written to directly,\\n * but can be passed to a typed array or DataView Object to interpret the raw\\n * buffer as needed.\\n */\\ninterface ArrayBuffer {\\n    /**\\n     * Read-only. The length of the ArrayBuffer (in bytes).\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * Returns a section of an ArrayBuffer.\\n     */\\n    slice(begin: number, end?: number): ArrayBuffer;\\n}\\n\\n/**\\n * Allowed ArrayBuffer types for the buffer of an ArrayBufferView and related Typed Arrays.\\n */\\ninterface ArrayBufferTypes {\\n    ArrayBuffer: ArrayBuffer;\\n}\\ntype ArrayBufferLike = ArrayBufferTypes[keyof ArrayBufferTypes];\\n\\ninterface ArrayBufferConstructor {\\n    readonly prototype: ArrayBuffer;\\n    new (byteLength: number): ArrayBuffer;\\n    isView(arg: any): arg is ArrayBufferView;\\n}\\ndeclare var ArrayBuffer: ArrayBufferConstructor;\\n\\ninterface ArrayBufferView {\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    byteOffset: number;\\n}\\n\\ninterface DataView {\\n    readonly buffer: ArrayBuffer;\\n    readonly byteLength: number;\\n    readonly byteOffset: number;\\n    /**\\n     * Gets the Float32 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     * @param littleEndian If false or undefined, a big-endian value should be read.\\n     */\\n    getFloat32(byteOffset: number, littleEndian?: boolean): number;\\n\\n    /**\\n     * Gets the Float64 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     * @param littleEndian If false or undefined, a big-endian value should be read.\\n     */\\n    getFloat64(byteOffset: number, littleEndian?: boolean): number;\\n\\n    /**\\n     * Gets the Int8 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     */\\n    getInt8(byteOffset: number): number;\\n\\n    /**\\n     * Gets the Int16 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     * @param littleEndian If false or undefined, a big-endian value should be read.\\n     */\\n    getInt16(byteOffset: number, littleEndian?: boolean): number;\\n    /**\\n     * Gets the Int32 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     * @param littleEndian If false or undefined, a big-endian value should be read.\\n     */\\n    getInt32(byteOffset: number, littleEndian?: boolean): number;\\n\\n    /**\\n     * Gets the Uint8 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     */\\n    getUint8(byteOffset: number): number;\\n\\n    /**\\n     * Gets the Uint16 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     * @param littleEndian If false or undefined, a big-endian value should be read.\\n     */\\n    getUint16(byteOffset: number, littleEndian?: boolean): number;\\n\\n    /**\\n     * Gets the Uint32 value at the specified byte offset from the start of the view. There is\\n     * no alignment constraint; multi-byte values may be fetched from any offset.\\n     * @param byteOffset The place in the buffer at which the value should be retrieved.\\n     * @param littleEndian If false or undefined, a big-endian value should be read.\\n     */\\n    getUint32(byteOffset: number, littleEndian?: boolean): number;\\n\\n    /**\\n     * Stores an Float32 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     * @param littleEndian If false or undefined, a big-endian value should be written.\\n     */\\n    setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void;\\n\\n    /**\\n     * Stores an Float64 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     * @param littleEndian If false or undefined, a big-endian value should be written.\\n     */\\n    setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void;\\n\\n    /**\\n     * Stores an Int8 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     */\\n    setInt8(byteOffset: number, value: number): void;\\n\\n    /**\\n     * Stores an Int16 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     * @param littleEndian If false or undefined, a big-endian value should be written.\\n     */\\n    setInt16(byteOffset: number, value: number, littleEndian?: boolean): void;\\n\\n    /**\\n     * Stores an Int32 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     * @param littleEndian If false or undefined, a big-endian value should be written.\\n     */\\n    setInt32(byteOffset: number, value: number, littleEndian?: boolean): void;\\n\\n    /**\\n     * Stores an Uint8 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     */\\n    setUint8(byteOffset: number, value: number): void;\\n\\n    /**\\n     * Stores an Uint16 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     * @param littleEndian If false or undefined, a big-endian value should be written.\\n     */\\n    setUint16(byteOffset: number, value: number, littleEndian?: boolean): void;\\n\\n    /**\\n     * Stores an Uint32 value at the specified byte offset from the start of the view.\\n     * @param byteOffset The place in the buffer at which the value should be set.\\n     * @param value The value to set.\\n     * @param littleEndian If false or undefined, a big-endian value should be written.\\n     */\\n    setUint32(byteOffset: number, value: number, littleEndian?: boolean): void;\\n}\\n\\ninterface DataViewConstructor {\\n    readonly prototype: DataView;\\n    new (buffer: ArrayBufferLike & { BYTES_PER_ELEMENT?: never; }, byteOffset?: number, byteLength?: number): DataView;\\n}\\ndeclare var DataView: DataViewConstructor;\\n\\n/**\\n * A typed array of 8-bit integer values. The contents are initialized to 0. If the requested\\n * number of bytes could not be allocated an exception is raised.\\n */\\ninterface Int8Array {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Int8Array) => any, thisArg?: any): Int8Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Int8Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Int8Array) => void, thisArg?: any): void;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Int8Array) => number, thisArg?: any): Int8Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int8Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int8Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Int8Array;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Int8Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Int8Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Int8Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Int8Array;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Int8Array;\\n\\n    [index: number]: number;\\n}\\ninterface Int8ArrayConstructor {\\n    readonly prototype: Int8Array;\\n    new (length: number): Int8Array;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Int8Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int8Array;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Int8Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Int8Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int8Array;\\n}\\ndeclare var Int8Array: Int8ArrayConstructor;\\n\\n/**\\n * A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the\\n * requested number of bytes could not be allocated an exception is raised.\\n */\\ninterface Uint8Array {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Uint8Array) => any, thisArg?: any): Uint8Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Uint8Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Uint8Array) => void, thisArg?: any): void;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Uint8Array) => number, thisArg?: any): Uint8Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Uint8Array;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Uint8Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Uint8Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Uint8Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Uint8Array;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Uint8Array;\\n\\n    [index: number]: number;\\n}\\n\\ninterface Uint8ArrayConstructor {\\n    readonly prototype: Uint8Array;\\n    new (length: number): Uint8Array;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Uint8Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint8Array;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Uint8Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Uint8Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Uint8Array;\\n}\\ndeclare var Uint8Array: Uint8ArrayConstructor;\\n\\n/**\\n * A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.\\n * If the requested number of bytes could not be allocated an exception is raised.\\n */\\ninterface Uint8ClampedArray {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Uint8ClampedArray) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Uint8ClampedArray) => any, thisArg?: any): Uint8ClampedArray;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Uint8ClampedArray) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Uint8ClampedArray) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => void, thisArg?: any): void;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Uint8ClampedArray) => number, thisArg?: any): Uint8ClampedArray;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint8ClampedArray) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Uint8ClampedArray;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Uint8ClampedArray;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Uint8ClampedArray) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Uint8ClampedArray view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Uint8ClampedArray;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Uint8ClampedArray;\\n\\n    [index: number]: number;\\n}\\n\\ninterface Uint8ClampedArrayConstructor {\\n    readonly prototype: Uint8ClampedArray;\\n    new (length: number): Uint8ClampedArray;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Uint8ClampedArray;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint8ClampedArray;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Uint8ClampedArray;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Uint8ClampedArray;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Uint8ClampedArray;\\n}\\ndeclare var Uint8ClampedArray: Uint8ClampedArrayConstructor;\\n\\n/**\\n * A typed array of 16-bit signed integer values. The contents are initialized to 0. If the\\n * requested number of bytes could not be allocated an exception is raised.\\n */\\ninterface Int16Array {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Int16Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Int16Array) => any, thisArg?: any): Int16Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Int16Array) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Int16Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Int16Array) => void, thisArg?: any): void;\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Int16Array) => number, thisArg?: any): Int16Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int16Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int16Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Int16Array;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Int16Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Int16Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Int16Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Int16Array;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Int16Array;\\n\\n    [index: number]: number;\\n}\\n\\ninterface Int16ArrayConstructor {\\n    readonly prototype: Int16Array;\\n    new (length: number): Int16Array;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Int16Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int16Array;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Int16Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Int16Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int16Array;\\n}\\ndeclare var Int16Array: Int16ArrayConstructor;\\n\\n/**\\n * A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the\\n * requested number of bytes could not be allocated an exception is raised.\\n */\\ninterface Uint16Array {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Uint16Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Uint16Array) => any, thisArg?: any): Uint16Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Uint16Array) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Uint16Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Uint16Array) => void, thisArg?: any): void;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Uint16Array) => number, thisArg?: any): Uint16Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint16Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint16Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint16Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Uint16Array;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Uint16Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Uint16Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Uint16Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Uint16Array;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Uint16Array;\\n\\n    [index: number]: number;\\n}\\n\\ninterface Uint16ArrayConstructor {\\n    readonly prototype: Uint16Array;\\n    new (length: number): Uint16Array;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Uint16Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint16Array;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Uint16Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Uint16Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Uint16Array;\\n}\\ndeclare var Uint16Array: Uint16ArrayConstructor;\\n/**\\n * A typed array of 32-bit signed integer values. The contents are initialized to 0. If the\\n * requested number of bytes could not be allocated an exception is raised.\\n */\\ninterface Int32Array {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Int32Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Int32Array) => any, thisArg?: any): Int32Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Int32Array) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Int32Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Int32Array) => void, thisArg?: any): void;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Int32Array) => number, thisArg?: any): Int32Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Int32Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Int32Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Int32Array;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Int32Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Int32Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Int32Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Int32Array;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Int32Array;\\n\\n    [index: number]: number;\\n}\\n\\ninterface Int32ArrayConstructor {\\n    readonly prototype: Int32Array;\\n    new (length: number): Int32Array;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Int32Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Int32Array;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Int32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Int32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Int32Array;\\n}\\ndeclare var Int32Array: Int32ArrayConstructor;\\n\\n/**\\n * A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the\\n * requested number of bytes could not be allocated an exception is raised.\\n */\\ninterface Uint32Array {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Uint32Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Uint32Array) => any, thisArg?: any): Uint32Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Uint32Array) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Uint32Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Uint32Array) => void, thisArg?: any): void;\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Uint32Array) => number, thisArg?: any): Uint32Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint32Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Uint32Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Uint32Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Uint32Array;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Uint32Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Uint32Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Uint32Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Uint32Array;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Uint32Array;\\n\\n    [index: number]: number;\\n}\\n\\ninterface Uint32ArrayConstructor {\\n    readonly prototype: Uint32Array;\\n    new (length: number): Uint32Array;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Uint32Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Uint32Array;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Uint32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Uint32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Uint32Array;\\n}\\ndeclare var Uint32Array: Uint32ArrayConstructor;\\n\\n/**\\n * A typed array of 32-bit float values. The contents are initialized to 0. If the requested number\\n * of bytes could not be allocated an exception is raised.\\n */\\ninterface Float32Array {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Float32Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Float32Array) => any, thisArg?: any): Float32Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Float32Array) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Float32Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Float32Array) => void, thisArg?: any): void;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Float32Array) => number, thisArg?: any): Float32Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float32Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float32Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Float32Array;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Float32Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Float32Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Float32Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Float32Array;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Float32Array;\\n\\n    [index: number]: number;\\n}\\n\\ninterface Float32ArrayConstructor {\\n    readonly prototype: Float32Array;\\n    new (length: number): Float32Array;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Float32Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Float32Array;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Float32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Float32Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Float32Array;\\n}\\ndeclare var Float32Array: Float32ArrayConstructor;\\n\\n/**\\n * A typed array of 64-bit float values. The contents are initialized to 0. If the requested\\n * number of bytes could not be allocated an exception is raised.\\n */\\ninterface Float64Array {\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * The ArrayBuffer instance referenced by the array.\\n     */\\n    readonly buffer: ArrayBufferLike;\\n\\n    /**\\n     * The length in bytes of the array.\\n     */\\n    readonly byteLength: number;\\n\\n    /**\\n     * The offset in bytes of the array.\\n     */\\n    readonly byteOffset: number;\\n\\n    /**\\n     * Returns the this object after copying a section of the array identified by start and end\\n     * to the same array starting at position target\\n     * @param target If target is negative, it is treated as length+target where length is the\\n     * length of the array.\\n     * @param start If start is negative, it is treated as length+start. If end is negative, it\\n     * is treated as length+end.\\n     * @param end If not specified, length of the this object is used as its default value.\\n     */\\n    copyWithin(target: number, start: number, end?: number): this;\\n\\n    /**\\n     * Determines whether all the members of an array satisfy the specified test.\\n     * @param predicate A function that accepts up to three arguments. The every method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value false, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    every(predicate: (value: number, index: number, array: Float64Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Changes all array elements from `start` to `end` index to a static `value` and returns the modified array\\n     * @param value value to fill array section with\\n     * @param start index to start filling the array at. If start is negative, it is treated as\\n     * length+start where length is the length of the array.\\n     * @param end index to stop filling the array at. If end is negative, it is treated as\\n     * length+end.\\n     */\\n    fill(value: number, start?: number, end?: number): this;\\n\\n    /**\\n     * Returns the elements of an array that meet the condition specified in a callback function.\\n     * @param predicate A function that accepts up to three arguments. The filter method calls\\n     * the predicate function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    filter(predicate: (value: number, index: number, array: Float64Array) => any, thisArg?: any): Float64Array;\\n\\n    /**\\n     * Returns the value of the first element in the array where predicate is true, and undefined\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found, find\\n     * immediately returns that element value. Otherwise, find returns undefined.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    find(predicate: (value: number, index: number, obj: Float64Array) => boolean, thisArg?: any): number | undefined;\\n\\n    /**\\n     * Returns the index of the first element in the array where predicate is true, and -1\\n     * otherwise.\\n     * @param predicate find calls predicate once for each element of the array, in ascending\\n     * order, until it finds one where predicate returns true. If such an element is found,\\n     * findIndex immediately returns that element index. Otherwise, findIndex returns -1.\\n     * @param thisArg If provided, it will be used as the this value for each invocation of\\n     * predicate. If it is not provided, undefined is used instead.\\n     */\\n    findIndex(predicate: (value: number, index: number, obj: Float64Array) => boolean, thisArg?: any): number;\\n\\n    /**\\n     * Performs the specified action for each element in an array.\\n     * @param callbackfn  A function that accepts up to three arguments. forEach calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg  An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    forEach(callbackfn: (value: number, index: number, array: Float64Array) => void, thisArg?: any): void;\\n\\n    /**\\n     * Returns the index of the first occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     *  search starts at index 0.\\n     */\\n    indexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * Adds all the elements of an array separated by the specified separator string.\\n     * @param separator A string used to separate one element of an array from the next in the\\n     * resulting String. If omitted, the array elements are separated with a comma.\\n     */\\n    join(separator?: string): string;\\n\\n    /**\\n     * Returns the index of the last occurrence of a value in an array.\\n     * @param searchElement The value to locate in the array.\\n     * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the\\n     * search starts at index 0.\\n     */\\n    lastIndexOf(searchElement: number, fromIndex?: number): number;\\n\\n    /**\\n     * The length of the array.\\n     */\\n    readonly length: number;\\n\\n    /**\\n     * Calls a defined callback function on each element of an array, and returns an array that\\n     * contains the results.\\n     * @param callbackfn A function that accepts up to three arguments. The map method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param thisArg An object to which the this keyword can refer in the callbackfn function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    map(callbackfn: (value: number, index: number, array: Float64Array) => number, thisArg?: any): Float64Array;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number;\\n    reduce(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array. The return value of\\n     * the callback function is the accumulated result, and is provided as an argument in the next\\n     * call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduce method calls the\\n     * callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduce<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an\\n     * argument instead of an array value.\\n     */\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number): number;\\n    reduceRight(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: Float64Array) => number, initialValue: number): number;\\n\\n    /**\\n     * Calls the specified callback function for all the elements in an array, in descending order.\\n     * The return value of the callback function is the accumulated result, and is provided as an\\n     * argument in the next call to the callback function.\\n     * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls\\n     * the callbackfn function one time for each element in the array.\\n     * @param initialValue If initialValue is specified, it is used as the initial value to start\\n     * the accumulation. The first call to the callbackfn function provides this value as an argument\\n     * instead of an array value.\\n     */\\n    reduceRight<U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: Float64Array) => U, initialValue: U): U;\\n\\n    /**\\n     * Reverses the elements in an Array.\\n     */\\n    reverse(): Float64Array;\\n\\n    /**\\n     * Sets a value or an array of values.\\n     * @param array A typed or untyped array of values to set.\\n     * @param offset The index in the current array at which the values are to be written.\\n     */\\n    set(array: ArrayLike<number>, offset?: number): void;\\n\\n    /**\\n     * Returns a section of an array.\\n     * @param start The beginning of the specified portion of the array.\\n     * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.\\n     */\\n    slice(start?: number, end?: number): Float64Array;\\n\\n    /**\\n     * Determines whether the specified callback function returns true for any element of an array.\\n     * @param predicate A function that accepts up to three arguments. The some method calls\\n     * the predicate function for each element in the array until the predicate returns a value\\n     * which is coercible to the Boolean value true, or until the end of the array.\\n     * @param thisArg An object to which the this keyword can refer in the predicate function.\\n     * If thisArg is omitted, undefined is used as the this value.\\n     */\\n    some(predicate: (value: number, index: number, array: Float64Array) => unknown, thisArg?: any): boolean;\\n\\n    /**\\n     * Sorts an array.\\n     * @param compareFn Function used to determine the order of the elements. It is expected to return\\n     * a negative value if first argument is less than second argument, zero if they're equal and a positive\\n     * value otherwise. If omitted, the elements are sorted in ascending order.\\n     * ```ts\\n     * [11,2,22,1].sort((a, b) => a - b)\\n     * ```\\n     */\\n    sort(compareFn?: (a: number, b: number) => number): this;\\n\\n    /**\\n     * Gets a new Float64Array view of the ArrayBuffer store for this array, referencing the elements\\n     * at begin, inclusive, up to end, exclusive.\\n     * @param begin The index of the beginning of the array.\\n     * @param end The index of the end of the array.\\n     */\\n    subarray(begin?: number, end?: number): Float64Array;\\n\\n    /**\\n     * Converts a number to a string by using the current locale.\\n     */\\n    toLocaleString(): string;\\n\\n    /**\\n     * Returns a string representation of an array.\\n     */\\n    toString(): string;\\n\\n    /** Returns the primitive value of the specified object. */\\n    valueOf(): Float64Array;\\n\\n    [index: number]: number;\\n}\\n\\ninterface Float64ArrayConstructor {\\n    readonly prototype: Float64Array;\\n    new (length: number): Float64Array;\\n    new (array: ArrayLike<number> | ArrayBufferLike): Float64Array;\\n    new (buffer: ArrayBufferLike, byteOffset?: number, length?: number): Float64Array;\\n\\n    /**\\n     * The size in bytes of each element in the array.\\n     */\\n    readonly BYTES_PER_ELEMENT: number;\\n\\n    /**\\n     * Returns a new array from a set of elements.\\n     * @param items A set of elements to include in the new array object.\\n     */\\n    of(...items: number[]): Float64Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     */\\n    from(arrayLike: ArrayLike<number>): Float64Array;\\n\\n    /**\\n     * Creates an array from an array-like or iterable object.\\n     * @param arrayLike An array-like or iterable object to convert to an array.\\n     * @param mapfn A mapping function to call on every element of the array.\\n     * @param thisArg Value of 'this' used to invoke the mapfn.\\n     */\\n    from<T>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => number, thisArg?: any): Float64Array;\\n}\\ndeclare var Float64Array: Float64ArrayConstructor;\\n\\n/////////////////////////////\\n/// ECMAScript Internationalization API\\n/////////////////////////////\\n\\ndeclare namespace Intl {\\n    interface CollatorOptions {\\n        usage?: \\\"sort\\\" | \\\"search\\\" | undefined;\\n        localeMatcher?: \\\"lookup\\\" | \\\"best fit\\\" | undefined;\\n        numeric?: boolean | undefined;\\n        caseFirst?: \\\"upper\\\" | \\\"lower\\\" | \\\"false\\\" | undefined;\\n        sensitivity?: \\\"base\\\" | \\\"accent\\\" | \\\"case\\\" | \\\"variant\\\" | undefined;\\n        collation?: \\\"big5han\\\" | \\\"compat\\\" | \\\"dict\\\" | \\\"direct\\\" | \\\"ducet\\\" | \\\"emoji\\\" | \\\"eor\\\" | \\\"gb2312\\\" | \\\"phonebk\\\" | \\\"phonetic\\\" | \\\"pinyin\\\" | \\\"reformed\\\" | \\\"searchjl\\\" | \\\"stroke\\\" | \\\"trad\\\" | \\\"unihan\\\" | \\\"zhuyin\\\" | undefined;\\n        ignorePunctuation?: boolean | undefined;\\n    }\\n\\n    interface ResolvedCollatorOptions {\\n        locale: string;\\n        usage: string;\\n        sensitivity: string;\\n        ignorePunctuation: boolean;\\n        collation: string;\\n        caseFirst: string;\\n        numeric: boolean;\\n    }\\n\\n    interface Collator {\\n        compare(x: string, y: string): number;\\n        resolvedOptions(): ResolvedCollatorOptions;\\n    }\\n    var Collator: {\\n        new (locales?: string | string[], options?: CollatorOptions): Collator;\\n        (locales?: string | string[], options?: CollatorOptions): Collator;\\n        supportedLocalesOf(locales: string | string[], options?: CollatorOptions): string[];\\n    };\\n\\n    interface NumberFormatOptions {\\n        localeMatcher?: string | undefined;\\n        style?: string | undefined;\\n        currency?: string | undefined;\\n        currencySign?: string | undefined;\\n        useGrouping?: boolean | undefined;\\n        minimumIntegerDigits?: number | undefined;\\n        minimumFractionDigits?: number | undefined;\\n        maximumFractionDigits?: number | undefined;\\n        minimumSignificantDigits?: number | undefined;\\n        maximumSignificantDigits?: number | undefined;\\n    }\\n\\n    interface ResolvedNumberFormatOptions {\\n        locale: string;\\n        numberingSystem: string;\\n        style: string;\\n        currency?: string;\\n        minimumIntegerDigits: number;\\n        minimumFractionDigits: number;\\n        maximumFractionDigits: number;\\n        minimumSignificantDigits?: number;\\n        maximumSignificantDigits?: number;\\n        useGrouping: boolean;\\n    }\\n\\n    interface NumberFormat {\\n        format(value: number): string;\\n        resolvedOptions(): ResolvedNumberFormatOptions;\\n    }\\n    var NumberFormat: {\\n        new (locales?: string | string[], options?: NumberFormatOptions): NumberFormat;\\n        (locales?: string | string[], options?: NumberFormatOptions): NumberFormat;\\n        supportedLocalesOf(locales: string | string[], options?: NumberFormatOptions): string[];\\n        readonly prototype: NumberFormat;\\n    };\\n\\n    interface DateTimeFormatOptions {\\n        localeMatcher?: \\\"best fit\\\" | \\\"lookup\\\" | undefined;\\n        weekday?: \\\"long\\\" | \\\"short\\\" | \\\"narrow\\\" | undefined;\\n        era?: \\\"long\\\" | \\\"short\\\" | \\\"narrow\\\" | undefined;\\n        year?: \\\"numeric\\\" | \\\"2-digit\\\" | undefined;\\n        month?: \\\"numeric\\\" | \\\"2-digit\\\" | \\\"long\\\" | \\\"short\\\" | \\\"narrow\\\" | undefined;\\n        day?: \\\"numeric\\\" | \\\"2-digit\\\" | undefined;\\n        hour?: \\\"numeric\\\" | \\\"2-digit\\\" | undefined;\\n        minute?: \\\"numeric\\\" | \\\"2-digit\\\" | undefined;\\n        second?: \\\"numeric\\\" | \\\"2-digit\\\" | undefined;\\n        timeZoneName?: \\\"short\\\" | \\\"long\\\" | \\\"shortOffset\\\" | \\\"longOffset\\\" | \\\"shortGeneric\\\" | \\\"longGeneric\\\" | undefined;\\n        formatMatcher?: \\\"best fit\\\" | \\\"basic\\\" | undefined;\\n        hour12?: boolean | undefined;\\n        timeZone?: string | undefined;\\n    }\\n\\n    interface ResolvedDateTimeFormatOptions {\\n        locale: string;\\n        calendar: string;\\n        numberingSystem: string;\\n        timeZone: string;\\n        hour12?: boolean;\\n        weekday?: string;\\n        era?: string;\\n        year?: string;\\n        month?: string;\\n        day?: string;\\n        hour?: string;\\n        minute?: string;\\n        second?: string;\\n        timeZoneName?: string;\\n    }\\n\\n    interface DateTimeFormat {\\n        format(date?: Date | number): string;\\n        resolvedOptions(): ResolvedDateTimeFormatOptions;\\n    }\\n    var DateTimeFormat: {\\n        new (locales?: string | string[], options?: DateTimeFormatOptions): DateTimeFormat;\\n        (locales?: string | string[], options?: DateTimeFormatOptions): DateTimeFormat;\\n        supportedLocalesOf(locales: string | string[], options?: DateTimeFormatOptions): string[];\\n        readonly prototype: DateTimeFormat;\\n    };\\n}\\n\\ninterface String {\\n    /**\\n     * Determines whether two strings are equivalent in the current or specified locale.\\n     * @param that String to compare to target string\\n     * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used. This parameter must conform to BCP 47 standards; see the Intl.Collator object for details.\\n     * @param options An object that contains one or more properties that specify comparison options. see the Intl.Collator object for details.\\n     */\\n    localeCompare(that: string, locales?: string | string[], options?: Intl.CollatorOptions): number;\\n}\\n\\ninterface Number {\\n    /**\\n     * Converts a number to a string by using the current or specified locale.\\n     * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\\n     * @param options An object that contains one or more properties that specify comparison options.\\n     */\\n    toLocaleString(locales?: string | string[], options?: Intl.NumberFormatOptions): string;\\n}\\n\\ninterface Date {\\n    /**\\n     * Converts a date and time to a string by using the current or specified locale.\\n     * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\\n     * @param options An object that contains one or more properties that specify comparison options.\\n     */\\n    toLocaleString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;\\n    /**\\n     * Converts a date to a string by using the current or specified locale.\\n     * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\\n     * @param options An object that contains one or more properties that specify comparison options.\\n     */\\n    toLocaleDateString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;\\n\\n    /**\\n     * Converts a time to a string by using the current or specified locale.\\n     * @param locales A locale string or array of locale strings that contain one or more language or locale tags. If you include more than one locale string, list them in descending order of priority so that the first entry is the preferred locale. If you omit this parameter, the default locale of the JavaScript runtime is used.\\n     * @param options An object that contains one or more properties that specify comparison options.\\n     */\\n    toLocaleTimeString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.es6.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.esnext.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2023\\\" />\\n/// <reference lib=\\\"esnext.intl\\\" />\\n/// <reference lib=\\\"esnext.decorators\\\" />\\n/// <reference lib=\\\"esnext.disposable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.esnext.decorators.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.symbol\\\" />\\n/// <reference lib=\\\"decorators\\\" />\\n\\ninterface SymbolConstructor {\\n    readonly metadata: unique symbol;\\n}\\n\\ninterface Function {\\n    [Symbol.metadata]: DecoratorMetadata | null;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.esnext.disposable.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"es2015.symbol\\\" />\\n\\ninterface SymbolConstructor {\\n    /**\\n     * A method that is used to release resources held by an object. Called by the semantics of the `using` statement.\\n     */\\n    readonly dispose: unique symbol;\\n\\n    /**\\n     * A method that is used to asynchronously release resources held by an object. Called by the semantics of the `await using` statement.\\n     */\\n    readonly asyncDispose: unique symbol;\\n}\\n\\ninterface Disposable {\\n    [Symbol.dispose](): void;\\n}\\n\\ninterface AsyncDisposable {\\n    [Symbol.asyncDispose](): PromiseLike<void>;\\n}\\n\\ninterface SuppressedError extends Error {\\n    error: any;\\n    suppressed: any;\\n}\\n\\ninterface SuppressedErrorConstructor extends ErrorConstructor {\\n    new (error: any, suppressed: any, message?: string): SuppressedError;\\n    (error: any, suppressed: any, message?: string): SuppressedError;\\n    readonly prototype: SuppressedError;\\n}\\ndeclare var SuppressedError: SuppressedErrorConstructor;\\n\\ninterface DisposableStack {\\n    /**\\n     * Returns a value indicating whether this stack has been disposed.\\n     */\\n    readonly disposed: boolean;\\n    /**\\n     * Disposes each resource in the stack in the reverse order that they were added.\\n     */\\n    dispose(): void;\\n    /**\\n     * Adds a disposable resource to the stack, returning the resource.\\n     * @param value The resource to add. `null` and `undefined` will not be added, but will be returned.\\n     * @returns The provided {@link value}.\\n     */\\n    use<T extends Disposable | null | undefined>(value: T): T;\\n    /**\\n     * Adds a value and associated disposal callback as a resource to the stack.\\n     * @param value The value to add.\\n     * @param onDispose The callback to use in place of a `[Symbol.dispose]()` method. Will be invoked with `value`\\n     * as the first parameter.\\n     * @returns The provided {@link value}.\\n     */\\n    adopt<T>(value: T, onDispose: (value: T) => void): T;\\n    /**\\n     * Adds a callback to be invoked when the stack is disposed.\\n     */\\n    defer(onDispose: () => void): void;\\n    /**\\n     * Move all resources out of this stack and into a new `DisposableStack`, and marks this stack as disposed.\\n     * @example\\n     * ```ts\\n     * class C {\\n     *   #res1: Disposable;\\n     *   #res2: Disposable;\\n     *   #disposables: DisposableStack;\\n     *   constructor() {\\n     *     // stack will be disposed when exiting constructor for any reason\\n     *     using stack = new DisposableStack();\\n     *\\n     *     // get first resource\\n     *     this.#res1 = stack.use(getResource1());\\n     *\\n     *     // get second resource. If this fails, both `stack` and `#res1` will be disposed.\\n     *     this.#res2 = stack.use(getResource2());\\n     *\\n     *     // all operations succeeded, move resources out of `stack` so that they aren't disposed\\n     *     // when constructor exits\\n     *     this.#disposables = stack.move();\\n     *   }\\n     *\\n     *   [Symbol.dispose]() {\\n     *     this.#disposables.dispose();\\n     *   }\\n     * }\\n     * ```\\n     */\\n    move(): DisposableStack;\\n    [Symbol.dispose](): void;\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface DisposableStackConstructor {\\n    new (): DisposableStack;\\n    readonly prototype: DisposableStack;\\n}\\ndeclare var DisposableStack: DisposableStackConstructor;\\n\\ninterface AsyncDisposableStack {\\n    /**\\n     * Returns a value indicating whether this stack has been disposed.\\n     */\\n    readonly disposed: boolean;\\n    /**\\n     * Disposes each resource in the stack in the reverse order that they were added.\\n     */\\n    disposeAsync(): Promise<void>;\\n    /**\\n     * Adds a disposable resource to the stack, returning the resource.\\n     * @param value The resource to add. `null` and `undefined` will not be added, but will be returned.\\n     * @returns The provided {@link value}.\\n     */\\n    use<T extends AsyncDisposable | Disposable | null | undefined>(value: T): T;\\n    /**\\n     * Adds a value and associated disposal callback as a resource to the stack.\\n     * @param value The value to add.\\n     * @param onDisposeAsync The callback to use in place of a `[Symbol.asyncDispose]()` method. Will be invoked with `value`\\n     * as the first parameter.\\n     * @returns The provided {@link value}.\\n     */\\n    adopt<T>(value: T, onDisposeAsync: (value: T) => PromiseLike<void> | void): T;\\n    /**\\n     * Adds a callback to be invoked when the stack is disposed.\\n     */\\n    defer(onDisposeAsync: () => PromiseLike<void> | void): void;\\n    /**\\n     * Move all resources out of this stack and into a new `DisposableStack`, and marks this stack as disposed.\\n     * @example\\n     * ```ts\\n     * class C {\\n     *   #res1: Disposable;\\n     *   #res2: Disposable;\\n     *   #disposables: DisposableStack;\\n     *   constructor() {\\n     *     // stack will be disposed when exiting constructor for any reason\\n     *     using stack = new DisposableStack();\\n     *\\n     *     // get first resource\\n     *     this.#res1 = stack.use(getResource1());\\n     *\\n     *     // get second resource. If this fails, both `stack` and `#res1` will be disposed.\\n     *     this.#res2 = stack.use(getResource2());\\n     *\\n     *     // all operations succeeded, move resources out of `stack` so that they aren't disposed\\n     *     // when constructor exits\\n     *     this.#disposables = stack.move();\\n     *   }\\n     *\\n     *   [Symbol.dispose]() {\\n     *     this.#disposables.dispose();\\n     *   }\\n     * }\\n     * ```\\n     */\\n    move(): AsyncDisposableStack;\\n    [Symbol.asyncDispose](): Promise<void>;\\n    readonly [Symbol.toStringTag]: string;\\n}\\n\\ninterface AsyncDisposableStackConstructor {\\n    new (): AsyncDisposableStack;\\n    readonly prototype: AsyncDisposableStack;\\n}\\ndeclare var AsyncDisposableStack: AsyncDisposableStackConstructor;\\n\"\n  },\n  {\n    \"fileName\": \"lib.esnext.full.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/// <reference lib=\\\"esnext\\\" />\\n/// <reference lib=\\\"dom\\\" />\\n/// <reference lib=\\\"webworker.importscripts\\\" />\\n/// <reference lib=\\\"scripthost\\\" />\\n/// <reference lib=\\\"dom.iterable\\\" />\\n\"\n  },\n  {\n    \"fileName\": \"lib.esnext.intl.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\ndeclare namespace Intl {\\n    interface NumberRangeFormatPart extends NumberFormatPart {\\n        source: \\\"startRange\\\" | \\\"endRange\\\" | \\\"shared\\\";\\n    }\\n\\n    interface NumberFormat {\\n        formatRange(start: number | bigint, end: number | bigint): string;\\n        formatRangeToParts(start: number | bigint, end: number | bigint): NumberRangeFormatPart[];\\n    }\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.scripthost.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/////////////////////////////\\n/// Windows Script Host APIS\\n/////////////////////////////\\n\\ninterface ActiveXObject {\\n    new (s: string): any;\\n}\\ndeclare var ActiveXObject: ActiveXObject;\\n\\ninterface ITextWriter {\\n    Write(s: string): void;\\n    WriteLine(s: string): void;\\n    Close(): void;\\n}\\n\\ninterface TextStreamBase {\\n    /**\\n     * The column number of the current character position in an input stream.\\n     */\\n    Column: number;\\n\\n    /**\\n     * The current line number in an input stream.\\n     */\\n    Line: number;\\n\\n    /**\\n     * Closes a text stream.\\n     * It is not necessary to close standard streams; they close automatically when the process ends. If\\n     * you close a standard stream, be aware that any other pointers to that standard stream become invalid.\\n     */\\n    Close(): void;\\n}\\n\\ninterface TextStreamWriter extends TextStreamBase {\\n    /**\\n     * Sends a string to an output stream.\\n     */\\n    Write(s: string): void;\\n\\n    /**\\n     * Sends a specified number of blank lines (newline characters) to an output stream.\\n     */\\n    WriteBlankLines(intLines: number): void;\\n\\n    /**\\n     * Sends a string followed by a newline character to an output stream.\\n     */\\n    WriteLine(s: string): void;\\n}\\n\\ninterface TextStreamReader extends TextStreamBase {\\n    /**\\n     * Returns a specified number of characters from an input stream, starting at the current pointer position.\\n     * Does not return until the ENTER key is pressed.\\n     * Can only be used on a stream in reading mode; causes an error in writing or appending mode.\\n     */\\n    Read(characters: number): string;\\n\\n    /**\\n     * Returns all characters from an input stream.\\n     * Can only be used on a stream in reading mode; causes an error in writing or appending mode.\\n     */\\n    ReadAll(): string;\\n\\n    /**\\n     * Returns an entire line from an input stream.\\n     * Although this method extracts the newline character, it does not add it to the returned string.\\n     * Can only be used on a stream in reading mode; causes an error in writing or appending mode.\\n     */\\n    ReadLine(): string;\\n\\n    /**\\n     * Skips a specified number of characters when reading from an input text stream.\\n     * Can only be used on a stream in reading mode; causes an error in writing or appending mode.\\n     * @param characters Positive number of characters to skip forward. (Backward skipping is not supported.)\\n     */\\n    Skip(characters: number): void;\\n\\n    /**\\n     * Skips the next line when reading from an input text stream.\\n     * Can only be used on a stream in reading mode, not writing or appending mode.\\n     */\\n    SkipLine(): void;\\n\\n    /**\\n     * Indicates whether the stream pointer position is at the end of a line.\\n     */\\n    AtEndOfLine: boolean;\\n\\n    /**\\n     * Indicates whether the stream pointer position is at the end of a stream.\\n     */\\n    AtEndOfStream: boolean;\\n}\\n\\ndeclare var WScript: {\\n    /**\\n     * Outputs text to either a message box (under WScript.exe) or the command console window followed by\\n     * a newline (under CScript.exe).\\n     */\\n    Echo(s: any): void;\\n\\n    /**\\n     * Exposes the write-only error output stream for the current script.\\n     * Can be accessed only while using CScript.exe.\\n     */\\n    StdErr: TextStreamWriter;\\n\\n    /**\\n     * Exposes the write-only output stream for the current script.\\n     * Can be accessed only while using CScript.exe.\\n     */\\n    StdOut: TextStreamWriter;\\n    Arguments: { length: number; Item(n: number): string; };\\n\\n    /**\\n     *  The full path of the currently running script.\\n     */\\n    ScriptFullName: string;\\n\\n    /**\\n     * Forces the script to stop immediately, with an optional exit code.\\n     */\\n    Quit(exitCode?: number): number;\\n\\n    /**\\n     * The Windows Script Host build version number.\\n     */\\n    BuildVersion: number;\\n\\n    /**\\n     * Fully qualified path of the host executable.\\n     */\\n    FullName: string;\\n\\n    /**\\n     * Gets/sets the script mode - interactive(true) or batch(false).\\n     */\\n    Interactive: boolean;\\n\\n    /**\\n     * The name of the host executable (WScript.exe or CScript.exe).\\n     */\\n    Name: string;\\n\\n    /**\\n     * Path of the directory containing the host executable.\\n     */\\n    Path: string;\\n\\n    /**\\n     * The filename of the currently running script.\\n     */\\n    ScriptName: string;\\n\\n    /**\\n     * Exposes the read-only input stream for the current script.\\n     * Can be accessed only while using CScript.exe.\\n     */\\n    StdIn: TextStreamReader;\\n\\n    /**\\n     * Windows Script Host version\\n     */\\n    Version: string;\\n\\n    /**\\n     * Connects a COM object's event sources to functions named with a given prefix, in the form prefix_event.\\n     */\\n    ConnectObject(objEventSource: any, strPrefix: string): void;\\n\\n    /**\\n     * Creates a COM object.\\n     * @param strProgiID\\n     * @param strPrefix Function names in the form prefix_event will be bound to this object's COM events.\\n     */\\n    CreateObject(strProgID: string, strPrefix?: string): any;\\n\\n    /**\\n     * Disconnects a COM object from its event sources.\\n     */\\n    DisconnectObject(obj: any): void;\\n\\n    /**\\n     * Retrieves an existing object with the specified ProgID from memory, or creates a new one from a file.\\n     * @param strPathname Fully qualified path to the file containing the object persisted to disk.\\n     *                       For objects in memory, pass a zero-length string.\\n     * @param strProgID\\n     * @param strPrefix Function names in the form prefix_event will be bound to this object's COM events.\\n     */\\n    GetObject(strPathname: string, strProgID?: string, strPrefix?: string): any;\\n\\n    /**\\n     * Suspends script execution for a specified length of time, then continues execution.\\n     * @param intTime Interval (in milliseconds) to suspend script execution.\\n     */\\n    Sleep(intTime: number): void;\\n};\\n\\n/**\\n * WSH is an alias for WScript under Windows Script Host\\n */\\ndeclare var WSH: typeof WScript;\\n\\n/**\\n * Represents an Automation SAFEARRAY\\n */\\ndeclare class SafeArray<T = any> {\\n    private constructor();\\n    private SafeArray_typekey: SafeArray<T>;\\n}\\n\\n/**\\n * Allows enumerating over a COM collection, which may not have indexed item access.\\n */\\ninterface Enumerator<T = any> {\\n    /**\\n     * Returns true if the current item is the last one in the collection, or the collection is empty,\\n     * or the current item is undefined.\\n     */\\n    atEnd(): boolean;\\n\\n    /**\\n     * Returns the current item in the collection\\n     */\\n    item(): T;\\n\\n    /**\\n     * Resets the current item in the collection to the first item. If there are no items in the collection,\\n     * the current item is set to undefined.\\n     */\\n    moveFirst(): void;\\n\\n    /**\\n     * Moves the current item to the next item in the collection. If the enumerator is at the end of\\n     * the collection or the collection is empty, the current item is set to undefined.\\n     */\\n    moveNext(): void;\\n}\\n\\ninterface EnumeratorConstructor {\\n    new <T = any>(safearray: SafeArray<T>): Enumerator<T>;\\n    new <T = any>(collection: { Item(index: any): T; }): Enumerator<T>;\\n    new <T = any>(collection: any): Enumerator<T>;\\n}\\n\\ndeclare var Enumerator: EnumeratorConstructor;\\n\\n/**\\n * Enables reading from a COM safe array, which might have an alternate lower bound, or multiple dimensions.\\n */\\ninterface VBArray<T = any> {\\n    /**\\n     * Returns the number of dimensions (1-based).\\n     */\\n    dimensions(): number;\\n\\n    /**\\n     * Takes an index for each dimension in the array, and returns the item at the corresponding location.\\n     */\\n    getItem(dimension1Index: number, ...dimensionNIndexes: number[]): T;\\n\\n    /**\\n     * Returns the smallest available index for a given dimension.\\n     * @param dimension 1-based dimension (defaults to 1)\\n     */\\n    lbound(dimension?: number): number;\\n\\n    /**\\n     * Returns the largest available index for a given dimension.\\n     * @param dimension 1-based dimension (defaults to 1)\\n     */\\n    ubound(dimension?: number): number;\\n\\n    /**\\n     * Returns a Javascript array with all the elements in the VBArray. If there are multiple dimensions,\\n     * each successive dimension is appended to the end of the array.\\n     * Example: [[1,2,3],[4,5,6]] becomes [1,2,3,4,5,6]\\n     */\\n    toArray(): T[];\\n}\\n\\ninterface VBArrayConstructor {\\n    new <T = any>(safeArray: SafeArray<T>): VBArray<T>;\\n}\\n\\ndeclare var VBArray: VBArrayConstructor;\\n\\n/**\\n * Automation date (VT_DATE)\\n */\\ndeclare class VarDate {\\n    private constructor();\\n    private VarDate_typekey: VarDate;\\n}\\n\\ninterface DateConstructor {\\n    new (vd: VarDate): Date;\\n}\\n\\ninterface Date {\\n    getVarDate: () => VarDate;\\n}\\n\"\n  },\n  {\n    \"fileName\": \"lib.webworker.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/////////////////////////////\\n/// Worker APIs\\n/////////////////////////////\\n\\ninterface AddEventListenerOptions extends EventListenerOptions {\\n    once?: boolean;\\n    passive?: boolean;\\n    signal?: AbortSignal;\\n}\\n\\ninterface AesCbcParams extends Algorithm {\\n    iv: BufferSource;\\n}\\n\\ninterface AesCtrParams extends Algorithm {\\n    counter: BufferSource;\\n    length: number;\\n}\\n\\ninterface AesDerivedKeyParams extends Algorithm {\\n    length: number;\\n}\\n\\ninterface AesGcmParams extends Algorithm {\\n    additionalData?: BufferSource;\\n    iv: BufferSource;\\n    tagLength?: number;\\n}\\n\\ninterface AesKeyAlgorithm extends KeyAlgorithm {\\n    length: number;\\n}\\n\\ninterface AesKeyGenParams extends Algorithm {\\n    length: number;\\n}\\n\\ninterface Algorithm {\\n    name: string;\\n}\\n\\ninterface AudioConfiguration {\\n    bitrate?: number;\\n    channels?: string;\\n    contentType: string;\\n    samplerate?: number;\\n    spatialRendering?: boolean;\\n}\\n\\ninterface AvcEncoderConfig {\\n    format?: AvcBitstreamFormat;\\n}\\n\\ninterface BlobPropertyBag {\\n    endings?: EndingType;\\n    type?: string;\\n}\\n\\ninterface CSSMatrixComponentOptions {\\n    is2D?: boolean;\\n}\\n\\ninterface CSSNumericType {\\n    angle?: number;\\n    flex?: number;\\n    frequency?: number;\\n    length?: number;\\n    percent?: number;\\n    percentHint?: CSSNumericBaseType;\\n    resolution?: number;\\n    time?: number;\\n}\\n\\ninterface CacheQueryOptions {\\n    ignoreMethod?: boolean;\\n    ignoreSearch?: boolean;\\n    ignoreVary?: boolean;\\n}\\n\\ninterface ClientQueryOptions {\\n    includeUncontrolled?: boolean;\\n    type?: ClientTypes;\\n}\\n\\ninterface CloseEventInit extends EventInit {\\n    code?: number;\\n    reason?: string;\\n    wasClean?: boolean;\\n}\\n\\ninterface CryptoKeyPair {\\n    privateKey: CryptoKey;\\n    publicKey: CryptoKey;\\n}\\n\\ninterface CustomEventInit<T = any> extends EventInit {\\n    detail?: T;\\n}\\n\\ninterface DOMMatrix2DInit {\\n    a?: number;\\n    b?: number;\\n    c?: number;\\n    d?: number;\\n    e?: number;\\n    f?: number;\\n    m11?: number;\\n    m12?: number;\\n    m21?: number;\\n    m22?: number;\\n    m41?: number;\\n    m42?: number;\\n}\\n\\ninterface DOMMatrixInit extends DOMMatrix2DInit {\\n    is2D?: boolean;\\n    m13?: number;\\n    m14?: number;\\n    m23?: number;\\n    m24?: number;\\n    m31?: number;\\n    m32?: number;\\n    m33?: number;\\n    m34?: number;\\n    m43?: number;\\n    m44?: number;\\n}\\n\\ninterface DOMPointInit {\\n    w?: number;\\n    x?: number;\\n    y?: number;\\n    z?: number;\\n}\\n\\ninterface DOMQuadInit {\\n    p1?: DOMPointInit;\\n    p2?: DOMPointInit;\\n    p3?: DOMPointInit;\\n    p4?: DOMPointInit;\\n}\\n\\ninterface DOMRectInit {\\n    height?: number;\\n    width?: number;\\n    x?: number;\\n    y?: number;\\n}\\n\\ninterface EcKeyGenParams extends Algorithm {\\n    namedCurve: NamedCurve;\\n}\\n\\ninterface EcKeyImportParams extends Algorithm {\\n    namedCurve: NamedCurve;\\n}\\n\\ninterface EcdhKeyDeriveParams extends Algorithm {\\n    public: CryptoKey;\\n}\\n\\ninterface EcdsaParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n}\\n\\ninterface EncodedVideoChunkInit {\\n    data: BufferSource;\\n    duration?: number;\\n    timestamp: number;\\n    type: EncodedVideoChunkType;\\n}\\n\\ninterface EncodedVideoChunkMetadata {\\n    decoderConfig?: VideoDecoderConfig;\\n}\\n\\ninterface ErrorEventInit extends EventInit {\\n    colno?: number;\\n    error?: any;\\n    filename?: string;\\n    lineno?: number;\\n    message?: string;\\n}\\n\\ninterface EventInit {\\n    bubbles?: boolean;\\n    cancelable?: boolean;\\n    composed?: boolean;\\n}\\n\\ninterface EventListenerOptions {\\n    capture?: boolean;\\n}\\n\\ninterface EventSourceInit {\\n    withCredentials?: boolean;\\n}\\n\\ninterface ExtendableEventInit extends EventInit {\\n}\\n\\ninterface ExtendableMessageEventInit extends ExtendableEventInit {\\n    data?: any;\\n    lastEventId?: string;\\n    origin?: string;\\n    ports?: MessagePort[];\\n    source?: Client | ServiceWorker | MessagePort | null;\\n}\\n\\ninterface FetchEventInit extends ExtendableEventInit {\\n    clientId?: string;\\n    handled?: Promise<undefined>;\\n    preloadResponse?: Promise<any>;\\n    replacesClientId?: string;\\n    request: Request;\\n    resultingClientId?: string;\\n}\\n\\ninterface FilePropertyBag extends BlobPropertyBag {\\n    lastModified?: number;\\n}\\n\\ninterface FileSystemCreateWritableOptions {\\n    keepExistingData?: boolean;\\n}\\n\\ninterface FileSystemGetDirectoryOptions {\\n    create?: boolean;\\n}\\n\\ninterface FileSystemGetFileOptions {\\n    create?: boolean;\\n}\\n\\ninterface FileSystemReadWriteOptions {\\n    at?: number;\\n}\\n\\ninterface FileSystemRemoveOptions {\\n    recursive?: boolean;\\n}\\n\\ninterface FontFaceDescriptors {\\n    ascentOverride?: string;\\n    descentOverride?: string;\\n    display?: FontDisplay;\\n    featureSettings?: string;\\n    lineGapOverride?: string;\\n    stretch?: string;\\n    style?: string;\\n    unicodeRange?: string;\\n    variant?: string;\\n    weight?: string;\\n}\\n\\ninterface FontFaceSetLoadEventInit extends EventInit {\\n    fontfaces?: FontFace[];\\n}\\n\\ninterface GetNotificationOptions {\\n    tag?: string;\\n}\\n\\ninterface HkdfParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n    info: BufferSource;\\n    salt: BufferSource;\\n}\\n\\ninterface HmacImportParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n    length?: number;\\n}\\n\\ninterface HmacKeyGenParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n    length?: number;\\n}\\n\\ninterface IDBDatabaseInfo {\\n    name?: string;\\n    version?: number;\\n}\\n\\ninterface IDBIndexParameters {\\n    multiEntry?: boolean;\\n    unique?: boolean;\\n}\\n\\ninterface IDBObjectStoreParameters {\\n    autoIncrement?: boolean;\\n    keyPath?: string | string[] | null;\\n}\\n\\ninterface IDBTransactionOptions {\\n    durability?: IDBTransactionDurability;\\n}\\n\\ninterface IDBVersionChangeEventInit extends EventInit {\\n    newVersion?: number | null;\\n    oldVersion?: number;\\n}\\n\\ninterface ImageBitmapOptions {\\n    colorSpaceConversion?: ColorSpaceConversion;\\n    imageOrientation?: ImageOrientation;\\n    premultiplyAlpha?: PremultiplyAlpha;\\n    resizeHeight?: number;\\n    resizeQuality?: ResizeQuality;\\n    resizeWidth?: number;\\n}\\n\\ninterface ImageBitmapRenderingContextSettings {\\n    alpha?: boolean;\\n}\\n\\ninterface ImageDataSettings {\\n    colorSpace?: PredefinedColorSpace;\\n}\\n\\ninterface ImageEncodeOptions {\\n    quality?: number;\\n    type?: string;\\n}\\n\\ninterface ImportMeta {\\n    url: string;\\n}\\n\\ninterface JsonWebKey {\\n    alg?: string;\\n    crv?: string;\\n    d?: string;\\n    dp?: string;\\n    dq?: string;\\n    e?: string;\\n    ext?: boolean;\\n    k?: string;\\n    key_ops?: string[];\\n    kty?: string;\\n    n?: string;\\n    oth?: RsaOtherPrimesInfo[];\\n    p?: string;\\n    q?: string;\\n    qi?: string;\\n    use?: string;\\n    x?: string;\\n    y?: string;\\n}\\n\\ninterface KeyAlgorithm {\\n    name: string;\\n}\\n\\ninterface LockInfo {\\n    clientId?: string;\\n    mode?: LockMode;\\n    name?: string;\\n}\\n\\ninterface LockManagerSnapshot {\\n    held?: LockInfo[];\\n    pending?: LockInfo[];\\n}\\n\\ninterface LockOptions {\\n    ifAvailable?: boolean;\\n    mode?: LockMode;\\n    signal?: AbortSignal;\\n    steal?: boolean;\\n}\\n\\ninterface MediaCapabilitiesDecodingInfo extends MediaCapabilitiesInfo {\\n    configuration?: MediaDecodingConfiguration;\\n}\\n\\ninterface MediaCapabilitiesEncodingInfo extends MediaCapabilitiesInfo {\\n    configuration?: MediaEncodingConfiguration;\\n}\\n\\ninterface MediaCapabilitiesInfo {\\n    powerEfficient: boolean;\\n    smooth: boolean;\\n    supported: boolean;\\n}\\n\\ninterface MediaConfiguration {\\n    audio?: AudioConfiguration;\\n    video?: VideoConfiguration;\\n}\\n\\ninterface MediaDecodingConfiguration extends MediaConfiguration {\\n    type: MediaDecodingType;\\n}\\n\\ninterface MediaEncodingConfiguration extends MediaConfiguration {\\n    type: MediaEncodingType;\\n}\\n\\ninterface MessageEventInit<T = any> extends EventInit {\\n    data?: T;\\n    lastEventId?: string;\\n    origin?: string;\\n    ports?: MessagePort[];\\n    source?: MessageEventSource | null;\\n}\\n\\ninterface MultiCacheQueryOptions extends CacheQueryOptions {\\n    cacheName?: string;\\n}\\n\\ninterface NavigationPreloadState {\\n    enabled?: boolean;\\n    headerValue?: string;\\n}\\n\\ninterface NotificationAction {\\n    action: string;\\n    icon?: string;\\n    title: string;\\n}\\n\\ninterface NotificationEventInit extends ExtendableEventInit {\\n    action?: string;\\n    notification: Notification;\\n}\\n\\ninterface NotificationOptions {\\n    actions?: NotificationAction[];\\n    badge?: string;\\n    body?: string;\\n    data?: any;\\n    dir?: NotificationDirection;\\n    icon?: string;\\n    image?: string;\\n    lang?: string;\\n    renotify?: boolean;\\n    requireInteraction?: boolean;\\n    silent?: boolean | null;\\n    tag?: string;\\n    timestamp?: EpochTimeStamp;\\n    vibrate?: VibratePattern;\\n}\\n\\ninterface Pbkdf2Params extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n    iterations: number;\\n    salt: BufferSource;\\n}\\n\\ninterface PerformanceMarkOptions {\\n    detail?: any;\\n    startTime?: DOMHighResTimeStamp;\\n}\\n\\ninterface PerformanceMeasureOptions {\\n    detail?: any;\\n    duration?: DOMHighResTimeStamp;\\n    end?: string | DOMHighResTimeStamp;\\n    start?: string | DOMHighResTimeStamp;\\n}\\n\\ninterface PerformanceObserverInit {\\n    buffered?: boolean;\\n    entryTypes?: string[];\\n    type?: string;\\n}\\n\\ninterface PermissionDescriptor {\\n    name: PermissionName;\\n}\\n\\ninterface PlaneLayout {\\n    offset: number;\\n    stride: number;\\n}\\n\\ninterface ProgressEventInit extends EventInit {\\n    lengthComputable?: boolean;\\n    loaded?: number;\\n    total?: number;\\n}\\n\\ninterface PromiseRejectionEventInit extends EventInit {\\n    promise: Promise<any>;\\n    reason?: any;\\n}\\n\\ninterface PushEventInit extends ExtendableEventInit {\\n    data?: PushMessageDataInit;\\n}\\n\\ninterface PushSubscriptionJSON {\\n    endpoint?: string;\\n    expirationTime?: EpochTimeStamp | null;\\n    keys?: Record<string, string>;\\n}\\n\\ninterface PushSubscriptionOptionsInit {\\n    applicationServerKey?: BufferSource | string | null;\\n    userVisibleOnly?: boolean;\\n}\\n\\ninterface QueuingStrategy<T = any> {\\n    highWaterMark?: number;\\n    size?: QueuingStrategySize<T>;\\n}\\n\\ninterface QueuingStrategyInit {\\n    /**\\n     * Creates a new ByteLengthQueuingStrategy with the provided high water mark.\\n     *\\n     * Note that the provided high water mark will not be validated ahead of time. Instead, if it is negative, NaN, or not a number, the resulting ByteLengthQueuingStrategy will cause the corresponding stream constructor to throw.\\n     */\\n    highWaterMark: number;\\n}\\n\\ninterface RTCEncodedAudioFrameMetadata {\\n    contributingSources?: number[];\\n    synchronizationSource?: number;\\n}\\n\\ninterface RTCEncodedVideoFrameMetadata {\\n    dependencies?: number[];\\n    frameId?: number;\\n    height?: number;\\n    spatialIndex?: number;\\n    synchronizationSource?: number;\\n    temporalIndex?: number;\\n    width?: number;\\n}\\n\\ninterface ReadableStreamGetReaderOptions {\\n    /**\\n     * Creates a ReadableStreamBYOBReader and locks the stream to the new reader.\\n     *\\n     * This call behaves the same way as the no-argument variant, except that it only works on readable byte streams, i.e. streams which were constructed specifically with the ability to handle \\\"bring your own buffer\\\" reading. The returned BYOB reader provides the ability to directly read individual chunks from the stream via its read() method, into developer-supplied buffers, allowing more precise control over allocation.\\n     */\\n    mode?: ReadableStreamReaderMode;\\n}\\n\\ninterface ReadableStreamReadDoneResult<T> {\\n    done: true;\\n    value?: T;\\n}\\n\\ninterface ReadableStreamReadValueResult<T> {\\n    done: false;\\n    value: T;\\n}\\n\\ninterface ReadableWritablePair<R = any, W = any> {\\n    readable: ReadableStream<R>;\\n    /**\\n     * Provides a convenient, chainable way of piping this readable stream through a transform stream (or any other { writable, readable } pair). It simply pipes the stream into the writable side of the supplied pair, and returns the readable side for further use.\\n     *\\n     * Piping a stream will lock it for the duration of the pipe, preventing any other consumer from acquiring a reader.\\n     */\\n    writable: WritableStream<W>;\\n}\\n\\ninterface RegistrationOptions {\\n    scope?: string;\\n    type?: WorkerType;\\n    updateViaCache?: ServiceWorkerUpdateViaCache;\\n}\\n\\ninterface ReportingObserverOptions {\\n    buffered?: boolean;\\n    types?: string[];\\n}\\n\\ninterface RequestInit {\\n    /** A BodyInit object or null to set request's body. */\\n    body?: BodyInit | null;\\n    /** A string indicating how the request will interact with the browser's cache to set request's cache. */\\n    cache?: RequestCache;\\n    /** A string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL. Sets request's credentials. */\\n    credentials?: RequestCredentials;\\n    /** A Headers object, an object literal, or an array of two-item arrays to set request's headers. */\\n    headers?: HeadersInit;\\n    /** A cryptographic hash of the resource to be fetched by request. Sets request's integrity. */\\n    integrity?: string;\\n    /** A boolean to set request's keepalive. */\\n    keepalive?: boolean;\\n    /** A string to set request's method. */\\n    method?: string;\\n    /** A string to indicate whether the request will use CORS, or will be restricted to same-origin URLs. Sets request's mode. */\\n    mode?: RequestMode;\\n    /** A string indicating whether request follows redirects, results in an error upon encountering a redirect, or returns the redirect (in an opaque fashion). Sets request's redirect. */\\n    redirect?: RequestRedirect;\\n    /** A string whose value is a same-origin URL, \\\"about:client\\\", or the empty string, to set request's referrer. */\\n    referrer?: string;\\n    /** A referrer policy to set request's referrerPolicy. */\\n    referrerPolicy?: ReferrerPolicy;\\n    /** An AbortSignal to set request's signal. */\\n    signal?: AbortSignal | null;\\n    /** Can only be null. Used to disassociate request from any Window. */\\n    window?: null;\\n}\\n\\ninterface ResponseInit {\\n    headers?: HeadersInit;\\n    status?: number;\\n    statusText?: string;\\n}\\n\\ninterface RsaHashedImportParams extends Algorithm {\\n    hash: HashAlgorithmIdentifier;\\n}\\n\\ninterface RsaHashedKeyGenParams extends RsaKeyGenParams {\\n    hash: HashAlgorithmIdentifier;\\n}\\n\\ninterface RsaKeyGenParams extends Algorithm {\\n    modulusLength: number;\\n    publicExponent: BigInteger;\\n}\\n\\ninterface RsaOaepParams extends Algorithm {\\n    label?: BufferSource;\\n}\\n\\ninterface RsaOtherPrimesInfo {\\n    d?: string;\\n    r?: string;\\n    t?: string;\\n}\\n\\ninterface RsaPssParams extends Algorithm {\\n    saltLength: number;\\n}\\n\\ninterface SecurityPolicyViolationEventInit extends EventInit {\\n    blockedURI?: string;\\n    columnNumber?: number;\\n    disposition: SecurityPolicyViolationEventDisposition;\\n    documentURI: string;\\n    effectiveDirective: string;\\n    lineNumber?: number;\\n    originalPolicy: string;\\n    referrer?: string;\\n    sample?: string;\\n    sourceFile?: string;\\n    statusCode: number;\\n    violatedDirective: string;\\n}\\n\\ninterface StorageEstimate {\\n    quota?: number;\\n    usage?: number;\\n}\\n\\ninterface StreamPipeOptions {\\n    preventAbort?: boolean;\\n    preventCancel?: boolean;\\n    /**\\n     * Pipes this readable stream to a given writable stream destination. The way in which the piping process behaves under various error conditions can be customized with a number of passed options. It returns a promise that fulfills when the piping process completes successfully, or rejects if any errors were encountered.\\n     *\\n     * Piping a stream will lock it for the duration of the pipe, preventing any other consumer from acquiring a reader.\\n     *\\n     * Errors and closures of the source and destination streams propagate as follows:\\n     *\\n     * An error in this source readable stream will abort destination, unless preventAbort is truthy. The returned promise will be rejected with the source's error, or with any error that occurs during aborting the destination.\\n     *\\n     * An error in destination will cancel this source readable stream, unless preventCancel is truthy. The returned promise will be rejected with the destination's error, or with any error that occurs during canceling the source.\\n     *\\n     * When this source readable stream closes, destination will be closed, unless preventClose is truthy. The returned promise will be fulfilled once this process completes, unless an error is encountered while closing the destination, in which case it will be rejected with that error.\\n     *\\n     * If destination starts out closed or closing, this source readable stream will be canceled, unless preventCancel is true. The returned promise will be rejected with an error indicating piping to a closed stream failed, or with any error that occurs during canceling the source.\\n     *\\n     * The signal option can be set to an AbortSignal to allow aborting an ongoing pipe operation via the corresponding AbortController. In this case, this source readable stream will be canceled, and destination aborted, unless the respective options preventCancel or preventAbort are set.\\n     */\\n    preventClose?: boolean;\\n    signal?: AbortSignal;\\n}\\n\\ninterface StructuredSerializeOptions {\\n    transfer?: Transferable[];\\n}\\n\\ninterface TextDecodeOptions {\\n    stream?: boolean;\\n}\\n\\ninterface TextDecoderOptions {\\n    fatal?: boolean;\\n    ignoreBOM?: boolean;\\n}\\n\\ninterface TextEncoderEncodeIntoResult {\\n    read: number;\\n    written: number;\\n}\\n\\ninterface Transformer<I = any, O = any> {\\n    flush?: TransformerFlushCallback<O>;\\n    readableType?: undefined;\\n    start?: TransformerStartCallback<O>;\\n    transform?: TransformerTransformCallback<I, O>;\\n    writableType?: undefined;\\n}\\n\\ninterface UnderlyingByteSource {\\n    autoAllocateChunkSize?: number;\\n    cancel?: UnderlyingSourceCancelCallback;\\n    pull?: (controller: ReadableByteStreamController) => void | PromiseLike<void>;\\n    start?: (controller: ReadableByteStreamController) => any;\\n    type: \\\"bytes\\\";\\n}\\n\\ninterface UnderlyingDefaultSource<R = any> {\\n    cancel?: UnderlyingSourceCancelCallback;\\n    pull?: (controller: ReadableStreamDefaultController<R>) => void | PromiseLike<void>;\\n    start?: (controller: ReadableStreamDefaultController<R>) => any;\\n    type?: undefined;\\n}\\n\\ninterface UnderlyingSink<W = any> {\\n    abort?: UnderlyingSinkAbortCallback;\\n    close?: UnderlyingSinkCloseCallback;\\n    start?: UnderlyingSinkStartCallback;\\n    type?: undefined;\\n    write?: UnderlyingSinkWriteCallback<W>;\\n}\\n\\ninterface UnderlyingSource<R = any> {\\n    autoAllocateChunkSize?: number;\\n    cancel?: UnderlyingSourceCancelCallback;\\n    pull?: UnderlyingSourcePullCallback<R>;\\n    start?: UnderlyingSourceStartCallback<R>;\\n    type?: ReadableStreamType;\\n}\\n\\ninterface VideoColorSpaceInit {\\n    fullRange?: boolean | null;\\n    matrix?: VideoMatrixCoefficients | null;\\n    primaries?: VideoColorPrimaries | null;\\n    transfer?: VideoTransferCharacteristics | null;\\n}\\n\\ninterface VideoConfiguration {\\n    bitrate: number;\\n    colorGamut?: ColorGamut;\\n    contentType: string;\\n    framerate: number;\\n    hdrMetadataType?: HdrMetadataType;\\n    height: number;\\n    scalabilityMode?: string;\\n    transferFunction?: TransferFunction;\\n    width: number;\\n}\\n\\ninterface VideoDecoderConfig {\\n    codec: string;\\n    codedHeight?: number;\\n    codedWidth?: number;\\n    colorSpace?: VideoColorSpaceInit;\\n    description?: BufferSource;\\n    displayAspectHeight?: number;\\n    displayAspectWidth?: number;\\n    hardwareAcceleration?: HardwareAcceleration;\\n    optimizeForLatency?: boolean;\\n}\\n\\ninterface VideoDecoderInit {\\n    error: WebCodecsErrorCallback;\\n    output: VideoFrameOutputCallback;\\n}\\n\\ninterface VideoDecoderSupport {\\n    config?: VideoDecoderConfig;\\n    supported?: boolean;\\n}\\n\\ninterface VideoEncoderConfig {\\n    alpha?: AlphaOption;\\n    avc?: AvcEncoderConfig;\\n    bitrate?: number;\\n    bitrateMode?: VideoEncoderBitrateMode;\\n    codec: string;\\n    displayHeight?: number;\\n    displayWidth?: number;\\n    framerate?: number;\\n    hardwareAcceleration?: HardwareAcceleration;\\n    height: number;\\n    latencyMode?: LatencyMode;\\n    scalabilityMode?: string;\\n    width: number;\\n}\\n\\ninterface VideoEncoderEncodeOptions {\\n    keyFrame?: boolean;\\n}\\n\\ninterface VideoEncoderInit {\\n    error: WebCodecsErrorCallback;\\n    output: EncodedVideoChunkOutputCallback;\\n}\\n\\ninterface VideoEncoderSupport {\\n    config?: VideoEncoderConfig;\\n    supported?: boolean;\\n}\\n\\ninterface VideoFrameBufferInit {\\n    codedHeight: number;\\n    codedWidth: number;\\n    colorSpace?: VideoColorSpaceInit;\\n    displayHeight?: number;\\n    displayWidth?: number;\\n    duration?: number;\\n    format: VideoPixelFormat;\\n    layout?: PlaneLayout[];\\n    timestamp: number;\\n    visibleRect?: DOMRectInit;\\n}\\n\\ninterface VideoFrameCopyToOptions {\\n    layout?: PlaneLayout[];\\n    rect?: DOMRectInit;\\n}\\n\\ninterface VideoFrameInit {\\n    alpha?: AlphaOption;\\n    displayHeight?: number;\\n    displayWidth?: number;\\n    duration?: number;\\n    timestamp?: number;\\n    visibleRect?: DOMRectInit;\\n}\\n\\ninterface WebGLContextAttributes {\\n    alpha?: boolean;\\n    antialias?: boolean;\\n    depth?: boolean;\\n    desynchronized?: boolean;\\n    failIfMajorPerformanceCaveat?: boolean;\\n    powerPreference?: WebGLPowerPreference;\\n    premultipliedAlpha?: boolean;\\n    preserveDrawingBuffer?: boolean;\\n    stencil?: boolean;\\n}\\n\\ninterface WebGLContextEventInit extends EventInit {\\n    statusMessage?: string;\\n}\\n\\ninterface WebTransportCloseInfo {\\n    closeCode?: number;\\n    reason?: string;\\n}\\n\\ninterface WebTransportErrorOptions {\\n    source?: WebTransportErrorSource;\\n    streamErrorCode?: number | null;\\n}\\n\\ninterface WebTransportHash {\\n    algorithm?: string;\\n    value?: BufferSource;\\n}\\n\\ninterface WebTransportOptions {\\n    allowPooling?: boolean;\\n    congestionControl?: WebTransportCongestionControl;\\n    requireUnreliable?: boolean;\\n    serverCertificateHashes?: WebTransportHash[];\\n}\\n\\ninterface WebTransportSendStreamOptions {\\n    sendOrder?: number | null;\\n}\\n\\ninterface WorkerOptions {\\n    credentials?: RequestCredentials;\\n    name?: string;\\n    type?: WorkerType;\\n}\\n\\ninterface WriteParams {\\n    data?: BufferSource | Blob | string | null;\\n    position?: number | null;\\n    size?: number | null;\\n    type: WriteCommandType;\\n}\\n\\n/**\\n * The ANGLE_instanced_arrays extension is part of the WebGL API and allows to draw the same object, or groups of similar objects multiple times, if they share the same vertex data, primitive count and type.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays)\\n */\\ninterface ANGLE_instanced_arrays {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/drawArraysInstancedANGLE) */\\n    drawArraysInstancedANGLE(mode: GLenum, first: GLint, count: GLsizei, primcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/drawElementsInstancedANGLE) */\\n    drawElementsInstancedANGLE(mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr, primcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ANGLE_instanced_arrays/vertexAttribDivisorANGLE) */\\n    vertexAttribDivisorANGLE(index: GLuint, divisor: GLuint): void;\\n    readonly VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 0x88FE;\\n}\\n\\n/**\\n * A controller object that allows you to abort one or more DOM requests as and when desired.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortController)\\n */\\ninterface AbortController {\\n    /**\\n     * Returns the AbortSignal object associated with this object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortController/signal)\\n     */\\n    readonly signal: AbortSignal;\\n    /**\\n     * Invoking this method will set this object's AbortSignal's aborted flag and signal to any observers that the associated activity is to be aborted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortController/abort)\\n     */\\n    abort(reason?: any): void;\\n}\\n\\ndeclare var AbortController: {\\n    prototype: AbortController;\\n    new(): AbortController;\\n};\\n\\ninterface AbortSignalEventMap {\\n    \\\"abort\\\": Event;\\n}\\n\\n/**\\n * A signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal)\\n */\\ninterface AbortSignal extends EventTarget {\\n    /**\\n     * Returns true if this AbortSignal's AbortController has signaled to abort, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/aborted)\\n     */\\n    readonly aborted: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/abort_event) */\\n    onabort: ((this: AbortSignal, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/reason) */\\n    readonly reason: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/throwIfAborted) */\\n    throwIfAborted(): void;\\n    addEventListener<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AbortSignalEventMap>(type: K, listener: (this: AbortSignal, ev: AbortSignalEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var AbortSignal: {\\n    prototype: AbortSignal;\\n    new(): AbortSignal;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/abort_static) */\\n    abort(reason?: any): AbortSignal;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/timeout_static) */\\n    timeout(milliseconds: number): AbortSignal;\\n};\\n\\ninterface AbstractWorkerEventMap {\\n    \\\"error\\\": ErrorEvent;\\n}\\n\\ninterface AbstractWorker {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/error_event) */\\n    onerror: ((this: AbstractWorker, ev: ErrorEvent) => any) | null;\\n    addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ninterface AnimationFrameProvider {\\n    cancelAnimationFrame(handle: number): void;\\n    requestAnimationFrame(callback: FrameRequestCallback): number;\\n}\\n\\n/**\\n * A file-like object of immutable, raw data. Blobs represent data that isn't necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob)\\n */\\ninterface Blob {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */\\n    readonly size: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */\\n    readonly type: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/arrayBuffer) */\\n    arrayBuffer(): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */\\n    slice(start?: number, end?: number, contentType?: string): Blob;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/stream) */\\n    stream(): ReadableStream<Uint8Array>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */\\n    text(): Promise<string>;\\n}\\n\\ndeclare var Blob: {\\n    prototype: Blob;\\n    new(blobParts?: BlobPart[], options?: BlobPropertyBag): Blob;\\n};\\n\\ninterface Body {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/body) */\\n    readonly body: ReadableStream<Uint8Array> | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bodyUsed) */\\n    readonly bodyUsed: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/arrayBuffer) */\\n    arrayBuffer(): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */\\n    blob(): Promise<Blob>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/formData) */\\n    formData(): Promise<FormData>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/json) */\\n    json(): Promise<any>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/text) */\\n    text(): Promise<string>;\\n}\\n\\ninterface BroadcastChannelEventMap {\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel) */\\ninterface BroadcastChannel extends EventTarget {\\n    /**\\n     * Returns the channel name (as passed to the constructor).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/name)\\n     */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/message_event) */\\n    onmessage: ((this: BroadcastChannel, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/messageerror_event) */\\n    onmessageerror: ((this: BroadcastChannel, ev: MessageEvent) => any) | null;\\n    /**\\n     * Closes the BroadcastChannel object, opening it up to garbage collection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/close)\\n     */\\n    close(): void;\\n    /**\\n     * Sends the given message to other BroadcastChannel objects set up for this channel. Messages can be structured objects, e.g. nested objects and arrays.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/BroadcastChannel/postMessage)\\n     */\\n    postMessage(message: any): void;\\n    addEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof BroadcastChannelEventMap>(type: K, listener: (this: BroadcastChannel, ev: BroadcastChannelEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var BroadcastChannel: {\\n    prototype: BroadcastChannel;\\n    new(name: string): BroadcastChannel;\\n};\\n\\n/**\\n * This Streams API interface provides a built-in byte length queuing strategy that can be used when constructing streams.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ByteLengthQueuingStrategy)\\n */\\ninterface ByteLengthQueuingStrategy extends QueuingStrategy<ArrayBufferView> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ByteLengthQueuingStrategy/highWaterMark) */\\n    readonly highWaterMark: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ByteLengthQueuingStrategy/size) */\\n    readonly size: QueuingStrategySize<ArrayBufferView>;\\n}\\n\\ndeclare var ByteLengthQueuingStrategy: {\\n    prototype: ByteLengthQueuingStrategy;\\n    new(init: QueuingStrategyInit): ByteLengthQueuingStrategy;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSImageValue) */\\ninterface CSSImageValue extends CSSStyleValue {\\n}\\n\\ndeclare var CSSImageValue: {\\n    prototype: CSSImageValue;\\n    new(): CSSImageValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeywordValue) */\\ninterface CSSKeywordValue extends CSSStyleValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSKeywordValue/value) */\\n    value: string;\\n}\\n\\ndeclare var CSSKeywordValue: {\\n    prototype: CSSKeywordValue;\\n    new(value: string): CSSKeywordValue;\\n};\\n\\ninterface CSSMathClamp extends CSSMathValue {\\n    readonly lower: CSSNumericValue;\\n    readonly upper: CSSNumericValue;\\n    readonly value: CSSNumericValue;\\n}\\n\\ndeclare var CSSMathClamp: {\\n    prototype: CSSMathClamp;\\n    new(lower: CSSNumberish, value: CSSNumberish, upper: CSSNumberish): CSSMathClamp;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathInvert) */\\ninterface CSSMathInvert extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathInvert/value) */\\n    readonly value: CSSNumericValue;\\n}\\n\\ndeclare var CSSMathInvert: {\\n    prototype: CSSMathInvert;\\n    new(arg: CSSNumberish): CSSMathInvert;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathMax) */\\ninterface CSSMathMax extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathMax/values) */\\n    readonly values: CSSNumericArray;\\n}\\n\\ndeclare var CSSMathMax: {\\n    prototype: CSSMathMax;\\n    new(...args: CSSNumberish[]): CSSMathMax;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathMin) */\\ninterface CSSMathMin extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathMin/values) */\\n    readonly values: CSSNumericArray;\\n}\\n\\ndeclare var CSSMathMin: {\\n    prototype: CSSMathMin;\\n    new(...args: CSSNumberish[]): CSSMathMin;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathNegate) */\\ninterface CSSMathNegate extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathNegate/value) */\\n    readonly value: CSSNumericValue;\\n}\\n\\ndeclare var CSSMathNegate: {\\n    prototype: CSSMathNegate;\\n    new(arg: CSSNumberish): CSSMathNegate;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathProduct) */\\ninterface CSSMathProduct extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathProduct/values) */\\n    readonly values: CSSNumericArray;\\n}\\n\\ndeclare var CSSMathProduct: {\\n    prototype: CSSMathProduct;\\n    new(...args: CSSNumberish[]): CSSMathProduct;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathSum) */\\ninterface CSSMathSum extends CSSMathValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathSum/values) */\\n    readonly values: CSSNumericArray;\\n}\\n\\ndeclare var CSSMathSum: {\\n    prototype: CSSMathSum;\\n    new(...args: CSSNumberish[]): CSSMathSum;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathValue) */\\ninterface CSSMathValue extends CSSNumericValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMathValue/operator) */\\n    readonly operator: CSSMathOperator;\\n}\\n\\ndeclare var CSSMathValue: {\\n    prototype: CSSMathValue;\\n    new(): CSSMathValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMatrixComponent) */\\ninterface CSSMatrixComponent extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSMatrixComponent/matrix) */\\n    matrix: DOMMatrix;\\n}\\n\\ndeclare var CSSMatrixComponent: {\\n    prototype: CSSMatrixComponent;\\n    new(matrix: DOMMatrixReadOnly, options?: CSSMatrixComponentOptions): CSSMatrixComponent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericArray) */\\ninterface CSSNumericArray {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericArray/length) */\\n    readonly length: number;\\n    forEach(callbackfn: (value: CSSNumericValue, key: number, parent: CSSNumericArray) => void, thisArg?: any): void;\\n    [index: number]: CSSNumericValue;\\n}\\n\\ndeclare var CSSNumericArray: {\\n    prototype: CSSNumericArray;\\n    new(): CSSNumericArray;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue) */\\ninterface CSSNumericValue extends CSSStyleValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/add) */\\n    add(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/div) */\\n    div(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/equals) */\\n    equals(...value: CSSNumberish[]): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/max) */\\n    max(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/min) */\\n    min(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/mul) */\\n    mul(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/sub) */\\n    sub(...values: CSSNumberish[]): CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/to) */\\n    to(unit: string): CSSUnitValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/toSum) */\\n    toSum(...units: string[]): CSSMathSum;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSNumericValue/type) */\\n    type(): CSSNumericType;\\n}\\n\\ndeclare var CSSNumericValue: {\\n    prototype: CSSNumericValue;\\n    new(): CSSNumericValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPerspective) */\\ninterface CSSPerspective extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSPerspective/length) */\\n    length: CSSPerspectiveValue;\\n}\\n\\ndeclare var CSSPerspective: {\\n    prototype: CSSPerspective;\\n    new(length: CSSPerspectiveValue): CSSPerspective;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate) */\\ninterface CSSRotate extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate/angle) */\\n    angle: CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate/x) */\\n    x: CSSNumberish;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate/y) */\\n    y: CSSNumberish;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSRotate/z) */\\n    z: CSSNumberish;\\n}\\n\\ndeclare var CSSRotate: {\\n    prototype: CSSRotate;\\n    new(angle: CSSNumericValue): CSSRotate;\\n    new(x: CSSNumberish, y: CSSNumberish, z: CSSNumberish, angle: CSSNumericValue): CSSRotate;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSScale) */\\ninterface CSSScale extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSScale/x) */\\n    x: CSSNumberish;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSScale/y) */\\n    y: CSSNumberish;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSScale/z) */\\n    z: CSSNumberish;\\n}\\n\\ndeclare var CSSScale: {\\n    prototype: CSSScale;\\n    new(x: CSSNumberish, y: CSSNumberish, z?: CSSNumberish): CSSScale;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkew) */\\ninterface CSSSkew extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkew/ax) */\\n    ax: CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkew/ay) */\\n    ay: CSSNumericValue;\\n}\\n\\ndeclare var CSSSkew: {\\n    prototype: CSSSkew;\\n    new(ax: CSSNumericValue, ay: CSSNumericValue): CSSSkew;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkewX) */\\ninterface CSSSkewX extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkewX/ax) */\\n    ax: CSSNumericValue;\\n}\\n\\ndeclare var CSSSkewX: {\\n    prototype: CSSSkewX;\\n    new(ax: CSSNumericValue): CSSSkewX;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkewY) */\\ninterface CSSSkewY extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkewY/ay) */\\n    ay: CSSNumericValue;\\n}\\n\\ndeclare var CSSSkewY: {\\n    prototype: CSSSkewY;\\n    new(ay: CSSNumericValue): CSSSkewY;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleValue) */\\ninterface CSSStyleValue {\\n    toString(): string;\\n}\\n\\ndeclare var CSSStyleValue: {\\n    prototype: CSSStyleValue;\\n    new(): CSSStyleValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformComponent) */\\ninterface CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformComponent/is2D) */\\n    is2D: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformComponent/toMatrix) */\\n    toMatrix(): DOMMatrix;\\n    toString(): string;\\n}\\n\\ndeclare var CSSTransformComponent: {\\n    prototype: CSSTransformComponent;\\n    new(): CSSTransformComponent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformValue) */\\ninterface CSSTransformValue extends CSSStyleValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformValue/is2D) */\\n    readonly is2D: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformValue/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTransformValue/toMatrix) */\\n    toMatrix(): DOMMatrix;\\n    forEach(callbackfn: (value: CSSTransformComponent, key: number, parent: CSSTransformValue) => void, thisArg?: any): void;\\n    [index: number]: CSSTransformComponent;\\n}\\n\\ndeclare var CSSTransformValue: {\\n    prototype: CSSTransformValue;\\n    new(transforms: CSSTransformComponent[]): CSSTransformValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTranslate) */\\ninterface CSSTranslate extends CSSTransformComponent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTranslate/x) */\\n    x: CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTranslate/y) */\\n    y: CSSNumericValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSTranslate/z) */\\n    z: CSSNumericValue;\\n}\\n\\ndeclare var CSSTranslate: {\\n    prototype: CSSTranslate;\\n    new(x: CSSNumericValue, y: CSSNumericValue, z?: CSSNumericValue): CSSTranslate;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnitValue) */\\ninterface CSSUnitValue extends CSSNumericValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnitValue/unit) */\\n    readonly unit: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnitValue/value) */\\n    value: number;\\n}\\n\\ndeclare var CSSUnitValue: {\\n    prototype: CSSUnitValue;\\n    new(value: number, unit: string): CSSUnitValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnparsedValue) */\\ninterface CSSUnparsedValue extends CSSStyleValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSUnparsedValue/length) */\\n    readonly length: number;\\n    forEach(callbackfn: (value: CSSUnparsedSegment, key: number, parent: CSSUnparsedValue) => void, thisArg?: any): void;\\n    [index: number]: CSSUnparsedSegment;\\n}\\n\\ndeclare var CSSUnparsedValue: {\\n    prototype: CSSUnparsedValue;\\n    new(members: CSSUnparsedSegment[]): CSSUnparsedValue;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSVariableReferenceValue) */\\ninterface CSSVariableReferenceValue {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSVariableReferenceValue/fallback) */\\n    readonly fallback: CSSUnparsedValue | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSVariableReferenceValue/variable) */\\n    variable: string;\\n}\\n\\ndeclare var CSSVariableReferenceValue: {\\n    prototype: CSSVariableReferenceValue;\\n    new(variable: string, fallback?: CSSUnparsedValue | null): CSSVariableReferenceValue;\\n};\\n\\n/**\\n * Provides a storage mechanism for Request / Response object pairs that are cached, for example as part of the ServiceWorker life cycle. Note that the Cache interface is exposed to windowed scopes as well as workers. You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache)\\n */\\ninterface Cache {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/add) */\\n    add(request: RequestInfo | URL): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/addAll) */\\n    addAll(requests: RequestInfo[]): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/delete) */\\n    delete(request: RequestInfo | URL, options?: CacheQueryOptions): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/keys) */\\n    keys(request?: RequestInfo | URL, options?: CacheQueryOptions): Promise<ReadonlyArray<Request>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/match) */\\n    match(request: RequestInfo | URL, options?: CacheQueryOptions): Promise<Response | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/matchAll) */\\n    matchAll(request?: RequestInfo | URL, options?: CacheQueryOptions): Promise<ReadonlyArray<Response>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/put) */\\n    put(request: RequestInfo | URL, response: Response): Promise<void>;\\n}\\n\\ndeclare var Cache: {\\n    prototype: Cache;\\n    new(): Cache;\\n};\\n\\n/**\\n * The storage for Cache objects.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage)\\n */\\ninterface CacheStorage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/delete) */\\n    delete(cacheName: string): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/has) */\\n    has(cacheName: string): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/keys) */\\n    keys(): Promise<string[]>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/match) */\\n    match(request: RequestInfo | URL, options?: MultiCacheQueryOptions): Promise<Response | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CacheStorage/open) */\\n    open(cacheName: string): Promise<Cache>;\\n}\\n\\ndeclare var CacheStorage: {\\n    prototype: CacheStorage;\\n    new(): CacheStorage;\\n};\\n\\ninterface CanvasCompositing {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/globalAlpha) */\\n    globalAlpha: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation) */\\n    globalCompositeOperation: GlobalCompositeOperation;\\n}\\n\\ninterface CanvasDrawImage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/drawImage) */\\n    drawImage(image: CanvasImageSource, dx: number, dy: number): void;\\n    drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;\\n    drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;\\n}\\n\\ninterface CanvasDrawPath {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/beginPath) */\\n    beginPath(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/clip) */\\n    clip(fillRule?: CanvasFillRule): void;\\n    clip(path: Path2D, fillRule?: CanvasFillRule): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fill) */\\n    fill(fillRule?: CanvasFillRule): void;\\n    fill(path: Path2D, fillRule?: CanvasFillRule): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/isPointInPath) */\\n    isPointInPath(x: number, y: number, fillRule?: CanvasFillRule): boolean;\\n    isPointInPath(path: Path2D, x: number, y: number, fillRule?: CanvasFillRule): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/isPointInStroke) */\\n    isPointInStroke(x: number, y: number): boolean;\\n    isPointInStroke(path: Path2D, x: number, y: number): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/stroke) */\\n    stroke(): void;\\n    stroke(path: Path2D): void;\\n}\\n\\ninterface CanvasFillStrokeStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fillStyle) */\\n    fillStyle: string | CanvasGradient | CanvasPattern;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/strokeStyle) */\\n    strokeStyle: string | CanvasGradient | CanvasPattern;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createConicGradient) */\\n    createConicGradient(startAngle: number, x: number, y: number): CanvasGradient;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createLinearGradient) */\\n    createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createPattern) */\\n    createPattern(image: CanvasImageSource, repetition: string | null): CanvasPattern | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createRadialGradient) */\\n    createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;\\n}\\n\\ninterface CanvasFilters {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/filter) */\\n    filter: string;\\n}\\n\\n/**\\n * An opaque object describing a gradient. It is returned by the methods CanvasRenderingContext2D.createLinearGradient() or CanvasRenderingContext2D.createRadialGradient().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasGradient)\\n */\\ninterface CanvasGradient {\\n    /**\\n     * Adds a color stop with the given color to the gradient at the given offset. 0.0 is the offset at one end of the gradient, 1.0 is the offset at the other end.\\n     *\\n     * Throws an \\\"IndexSizeError\\\" DOMException if the offset is out of range. Throws a \\\"SyntaxError\\\" DOMException if the color cannot be parsed.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasGradient/addColorStop)\\n     */\\n    addColorStop(offset: number, color: string): void;\\n}\\n\\ndeclare var CanvasGradient: {\\n    prototype: CanvasGradient;\\n    new(): CanvasGradient;\\n};\\n\\ninterface CanvasImageData {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createImageData) */\\n    createImageData(sw: number, sh: number, settings?: ImageDataSettings): ImageData;\\n    createImageData(imagedata: ImageData): ImageData;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/getImageData) */\\n    getImageData(sx: number, sy: number, sw: number, sh: number, settings?: ImageDataSettings): ImageData;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/putImageData) */\\n    putImageData(imagedata: ImageData, dx: number, dy: number): void;\\n    putImageData(imagedata: ImageData, dx: number, dy: number, dirtyX: number, dirtyY: number, dirtyWidth: number, dirtyHeight: number): void;\\n}\\n\\ninterface CanvasImageSmoothing {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/imageSmoothingEnabled) */\\n    imageSmoothingEnabled: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/imageSmoothingQuality) */\\n    imageSmoothingQuality: ImageSmoothingQuality;\\n}\\n\\ninterface CanvasPath {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/arc) */\\n    arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/arcTo) */\\n    arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo) */\\n    bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/closePath) */\\n    closePath(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/ellipse) */\\n    ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineTo) */\\n    lineTo(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/moveTo) */\\n    moveTo(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/quadraticCurveTo) */\\n    quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/rect) */\\n    rect(x: number, y: number, w: number, h: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/roundRect) */\\n    roundRect(x: number, y: number, w: number, h: number, radii?: number | DOMPointInit | (number | DOMPointInit)[]): void;\\n}\\n\\ninterface CanvasPathDrawingStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineCap) */\\n    lineCap: CanvasLineCap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineDashOffset) */\\n    lineDashOffset: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineJoin) */\\n    lineJoin: CanvasLineJoin;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/lineWidth) */\\n    lineWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/miterLimit) */\\n    miterLimit: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/getLineDash) */\\n    getLineDash(): number[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash) */\\n    setLineDash(segments: number[]): void;\\n}\\n\\n/**\\n * An opaque object describing a pattern, based on an image, a canvas, or a video, created by the CanvasRenderingContext2D.createPattern() method.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasPattern)\\n */\\ninterface CanvasPattern {\\n    /**\\n     * Sets the transformation matrix that will be used when rendering the pattern during a fill or stroke painting operation.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasPattern/setTransform)\\n     */\\n    setTransform(transform?: DOMMatrix2DInit): void;\\n}\\n\\ndeclare var CanvasPattern: {\\n    prototype: CanvasPattern;\\n    new(): CanvasPattern;\\n};\\n\\ninterface CanvasRect {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/clearRect) */\\n    clearRect(x: number, y: number, w: number, h: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fillRect) */\\n    fillRect(x: number, y: number, w: number, h: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/strokeRect) */\\n    strokeRect(x: number, y: number, w: number, h: number): void;\\n}\\n\\ninterface CanvasShadowStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/shadowBlur) */\\n    shadowBlur: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/shadowColor) */\\n    shadowColor: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/shadowOffsetX) */\\n    shadowOffsetX: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/shadowOffsetY) */\\n    shadowOffsetY: number;\\n}\\n\\ninterface CanvasState {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/reset) */\\n    reset(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/restore) */\\n    restore(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/save) */\\n    save(): void;\\n}\\n\\ninterface CanvasText {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fillText) */\\n    fillText(text: string, x: number, y: number, maxWidth?: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/measureText) */\\n    measureText(text: string): TextMetrics;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/strokeText) */\\n    strokeText(text: string, x: number, y: number, maxWidth?: number): void;\\n}\\n\\ninterface CanvasTextDrawingStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/direction) */\\n    direction: CanvasDirection;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/font) */\\n    font: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fontKerning) */\\n    fontKerning: CanvasFontKerning;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/textAlign) */\\n    textAlign: CanvasTextAlign;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/textBaseline) */\\n    textBaseline: CanvasTextBaseline;\\n}\\n\\ninterface CanvasTransform {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/getTransform) */\\n    getTransform(): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/resetTransform) */\\n    resetTransform(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/rotate) */\\n    rotate(angle: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/scale) */\\n    scale(x: number, y: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setTransform) */\\n    setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;\\n    setTransform(transform?: DOMMatrix2DInit): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/transform) */\\n    transform(a: number, b: number, c: number, d: number, e: number, f: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/translate) */\\n    translate(x: number, y: number): void;\\n}\\n\\n/**\\n * The Client interface represents an executable context such as a Worker, or a SharedWorker. Window clients are represented by the more-specific WindowClient. You can get Client/WindowClient objects from methods such as Clients.matchAll() and Clients.get().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Client)\\n */\\ninterface Client {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Client/frameType) */\\n    readonly frameType: FrameType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Client/id) */\\n    readonly id: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Client/type) */\\n    readonly type: ClientTypes;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Client/url) */\\n    readonly url: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Client/postMessage) */\\n    postMessage(message: any, transfer: Transferable[]): void;\\n    postMessage(message: any, options?: StructuredSerializeOptions): void;\\n}\\n\\ndeclare var Client: {\\n    prototype: Client;\\n    new(): Client;\\n};\\n\\n/**\\n * Provides access to Client objects. Access it via self.clients within a service worker.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clients)\\n */\\ninterface Clients {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clients/claim) */\\n    claim(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clients/get) */\\n    get(id: string): Promise<Client | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clients/matchAll) */\\n    matchAll<T extends ClientQueryOptions>(options?: T): Promise<ReadonlyArray<T[\\\"type\\\"] extends \\\"window\\\" ? WindowClient : Client>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clients/openWindow) */\\n    openWindow(url: string | URL): Promise<WindowClient | null>;\\n}\\n\\ndeclare var Clients: {\\n    prototype: Clients;\\n    new(): Clients;\\n};\\n\\n/**\\n * A CloseEvent is sent to clients using WebSockets when the connection is closed. This is delivered to the listener indicated by the WebSocket object's onclose attribute.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CloseEvent)\\n */\\ninterface CloseEvent extends Event {\\n    /**\\n     * Returns the WebSocket connection close code provided by the server.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CloseEvent/code)\\n     */\\n    readonly code: number;\\n    /**\\n     * Returns the WebSocket connection close reason provided by the server.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CloseEvent/reason)\\n     */\\n    readonly reason: string;\\n    /**\\n     * Returns true if the connection closed cleanly; false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CloseEvent/wasClean)\\n     */\\n    readonly wasClean: boolean;\\n}\\n\\ndeclare var CloseEvent: {\\n    prototype: CloseEvent;\\n    new(type: string, eventInitDict?: CloseEventInit): CloseEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompressionStream) */\\ninterface CompressionStream extends GenericTransformStream {\\n}\\n\\ndeclare var CompressionStream: {\\n    prototype: CompressionStream;\\n    new(format: CompressionFormat): CompressionStream;\\n};\\n\\n/**\\n * This Streams API interface provides a built-in byte length queuing strategy that can be used when constructing streams.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CountQueuingStrategy)\\n */\\ninterface CountQueuingStrategy extends QueuingStrategy {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CountQueuingStrategy/highWaterMark) */\\n    readonly highWaterMark: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CountQueuingStrategy/size) */\\n    readonly size: QueuingStrategySize;\\n}\\n\\ndeclare var CountQueuingStrategy: {\\n    prototype: CountQueuingStrategy;\\n    new(init: QueuingStrategyInit): CountQueuingStrategy;\\n};\\n\\n/**\\n * Basic cryptography features available in the current context. It allows access to a cryptographically strong random number generator and to cryptographic primitives.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto)\\n */\\ninterface Crypto {\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/subtle)\\n     */\\n    readonly subtle: SubtleCrypto;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */\\n    getRandomValues<T extends ArrayBufferView | null>(array: T): T;\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)\\n     */\\n    randomUUID(): `${string}-${string}-${string}-${string}-${string}`;\\n}\\n\\ndeclare var Crypto: {\\n    prototype: Crypto;\\n    new(): Crypto;\\n};\\n\\n/**\\n * The CryptoKey dictionary of the Web Crypto API represents a cryptographic key.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey)\\n */\\ninterface CryptoKey {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/algorithm) */\\n    readonly algorithm: KeyAlgorithm;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/extractable) */\\n    readonly extractable: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/type) */\\n    readonly type: KeyType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CryptoKey/usages) */\\n    readonly usages: KeyUsage[];\\n}\\n\\ndeclare var CryptoKey: {\\n    prototype: CryptoKey;\\n    new(): CryptoKey;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomEvent) */\\ninterface CustomEvent<T = any> extends Event {\\n    /**\\n     * Returns any custom data event was created with. Typically used for synthetic events.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomEvent/detail)\\n     */\\n    readonly detail: T;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomEvent/initCustomEvent)\\n     */\\n    initCustomEvent(type: string, bubbles?: boolean, cancelable?: boolean, detail?: T): void;\\n}\\n\\ndeclare var CustomEvent: {\\n    prototype: CustomEvent;\\n    new<T>(type: string, eventInitDict?: CustomEventInit<T>): CustomEvent<T>;\\n};\\n\\n/**\\n * An abnormal event (called an exception) which occurs as a result of calling a method or accessing a property of a web API.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException)\\n */\\ninterface DOMException extends Error {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/code)\\n     */\\n    readonly code: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/message) */\\n    readonly message: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMException/name) */\\n    readonly name: string;\\n    readonly INDEX_SIZE_ERR: 1;\\n    readonly DOMSTRING_SIZE_ERR: 2;\\n    readonly HIERARCHY_REQUEST_ERR: 3;\\n    readonly WRONG_DOCUMENT_ERR: 4;\\n    readonly INVALID_CHARACTER_ERR: 5;\\n    readonly NO_DATA_ALLOWED_ERR: 6;\\n    readonly NO_MODIFICATION_ALLOWED_ERR: 7;\\n    readonly NOT_FOUND_ERR: 8;\\n    readonly NOT_SUPPORTED_ERR: 9;\\n    readonly INUSE_ATTRIBUTE_ERR: 10;\\n    readonly INVALID_STATE_ERR: 11;\\n    readonly SYNTAX_ERR: 12;\\n    readonly INVALID_MODIFICATION_ERR: 13;\\n    readonly NAMESPACE_ERR: 14;\\n    readonly INVALID_ACCESS_ERR: 15;\\n    readonly VALIDATION_ERR: 16;\\n    readonly TYPE_MISMATCH_ERR: 17;\\n    readonly SECURITY_ERR: 18;\\n    readonly NETWORK_ERR: 19;\\n    readonly ABORT_ERR: 20;\\n    readonly URL_MISMATCH_ERR: 21;\\n    readonly QUOTA_EXCEEDED_ERR: 22;\\n    readonly TIMEOUT_ERR: 23;\\n    readonly INVALID_NODE_TYPE_ERR: 24;\\n    readonly DATA_CLONE_ERR: 25;\\n}\\n\\ndeclare var DOMException: {\\n    prototype: DOMException;\\n    new(message?: string, name?: string): DOMException;\\n    readonly INDEX_SIZE_ERR: 1;\\n    readonly DOMSTRING_SIZE_ERR: 2;\\n    readonly HIERARCHY_REQUEST_ERR: 3;\\n    readonly WRONG_DOCUMENT_ERR: 4;\\n    readonly INVALID_CHARACTER_ERR: 5;\\n    readonly NO_DATA_ALLOWED_ERR: 6;\\n    readonly NO_MODIFICATION_ALLOWED_ERR: 7;\\n    readonly NOT_FOUND_ERR: 8;\\n    readonly NOT_SUPPORTED_ERR: 9;\\n    readonly INUSE_ATTRIBUTE_ERR: 10;\\n    readonly INVALID_STATE_ERR: 11;\\n    readonly SYNTAX_ERR: 12;\\n    readonly INVALID_MODIFICATION_ERR: 13;\\n    readonly NAMESPACE_ERR: 14;\\n    readonly INVALID_ACCESS_ERR: 15;\\n    readonly VALIDATION_ERR: 16;\\n    readonly TYPE_MISMATCH_ERR: 17;\\n    readonly SECURITY_ERR: 18;\\n    readonly NETWORK_ERR: 19;\\n    readonly ABORT_ERR: 20;\\n    readonly URL_MISMATCH_ERR: 21;\\n    readonly QUOTA_EXCEEDED_ERR: 22;\\n    readonly TIMEOUT_ERR: 23;\\n    readonly INVALID_NODE_TYPE_ERR: 24;\\n    readonly DATA_CLONE_ERR: 25;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix) */\\ninterface DOMMatrix extends DOMMatrixReadOnly {\\n    a: number;\\n    b: number;\\n    c: number;\\n    d: number;\\n    e: number;\\n    f: number;\\n    m11: number;\\n    m12: number;\\n    m13: number;\\n    m14: number;\\n    m21: number;\\n    m22: number;\\n    m23: number;\\n    m24: number;\\n    m31: number;\\n    m32: number;\\n    m33: number;\\n    m34: number;\\n    m41: number;\\n    m42: number;\\n    m43: number;\\n    m44: number;\\n    invertSelf(): DOMMatrix;\\n    multiplySelf(other?: DOMMatrixInit): DOMMatrix;\\n    preMultiplySelf(other?: DOMMatrixInit): DOMMatrix;\\n    rotateAxisAngleSelf(x?: number, y?: number, z?: number, angle?: number): DOMMatrix;\\n    rotateFromVectorSelf(x?: number, y?: number): DOMMatrix;\\n    rotateSelf(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/scale3dSelf) */\\n    scale3dSelf(scale?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrix/scaleSelf) */\\n    scaleSelf(scaleX?: number, scaleY?: number, scaleZ?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;\\n    skewXSelf(sx?: number): DOMMatrix;\\n    skewYSelf(sy?: number): DOMMatrix;\\n    translateSelf(tx?: number, ty?: number, tz?: number): DOMMatrix;\\n}\\n\\ndeclare var DOMMatrix: {\\n    prototype: DOMMatrix;\\n    new(init?: string | number[]): DOMMatrix;\\n    fromFloat32Array(array32: Float32Array): DOMMatrix;\\n    fromFloat64Array(array64: Float64Array): DOMMatrix;\\n    fromMatrix(other?: DOMMatrixInit): DOMMatrix;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly) */\\ninterface DOMMatrixReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/a) */\\n    readonly a: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/b) */\\n    readonly b: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/c) */\\n    readonly c: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/d) */\\n    readonly d: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/e) */\\n    readonly e: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/f) */\\n    readonly f: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/is2D) */\\n    readonly is2D: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/isIdentity) */\\n    readonly isIdentity: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m11) */\\n    readonly m11: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m12) */\\n    readonly m12: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m13) */\\n    readonly m13: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m14) */\\n    readonly m14: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m21) */\\n    readonly m21: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m22) */\\n    readonly m22: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m23) */\\n    readonly m23: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m24) */\\n    readonly m24: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m31) */\\n    readonly m31: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m32) */\\n    readonly m32: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m33) */\\n    readonly m33: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m34) */\\n    readonly m34: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m41) */\\n    readonly m41: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m42) */\\n    readonly m42: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m43) */\\n    readonly m43: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/m44) */\\n    readonly m44: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/flipX) */\\n    flipX(): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/flipY) */\\n    flipY(): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/inverse) */\\n    inverse(): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/multiply) */\\n    multiply(other?: DOMMatrixInit): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotate) */\\n    rotate(rotX?: number, rotY?: number, rotZ?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotateAxisAngle) */\\n    rotateAxisAngle(x?: number, y?: number, z?: number, angle?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/rotateFromVector) */\\n    rotateFromVector(x?: number, y?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/scale) */\\n    scale(scaleX?: number, scaleY?: number, scaleZ?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/scale3d) */\\n    scale3d(scale?: number, originX?: number, originY?: number, originZ?: number): DOMMatrix;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/scaleNonUniform)\\n     */\\n    scaleNonUniform(scaleX?: number, scaleY?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/skewX) */\\n    skewX(sx?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/skewY) */\\n    skewY(sy?: number): DOMMatrix;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/toFloat32Array) */\\n    toFloat32Array(): Float32Array;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/toFloat64Array) */\\n    toFloat64Array(): Float64Array;\\n    toJSON(): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/transformPoint) */\\n    transformPoint(point?: DOMPointInit): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMMatrixReadOnly/translate) */\\n    translate(tx?: number, ty?: number, tz?: number): DOMMatrix;\\n}\\n\\ndeclare var DOMMatrixReadOnly: {\\n    prototype: DOMMatrixReadOnly;\\n    new(init?: string | number[]): DOMMatrixReadOnly;\\n    fromFloat32Array(array32: Float32Array): DOMMatrixReadOnly;\\n    fromFloat64Array(array64: Float64Array): DOMMatrixReadOnly;\\n    fromMatrix(other?: DOMMatrixInit): DOMMatrixReadOnly;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint) */\\ninterface DOMPoint extends DOMPointReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/w) */\\n    w: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/x) */\\n    x: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/y) */\\n    y: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/z) */\\n    z: number;\\n}\\n\\ndeclare var DOMPoint: {\\n    prototype: DOMPoint;\\n    new(x?: number, y?: number, z?: number, w?: number): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPoint/fromPoint_static) */\\n    fromPoint(other?: DOMPointInit): DOMPoint;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly) */\\ninterface DOMPointReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/w) */\\n    readonly w: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/x) */\\n    readonly x: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/y) */\\n    readonly y: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/z) */\\n    readonly z: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/matrixTransform) */\\n    matrixTransform(matrix?: DOMMatrixInit): DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var DOMPointReadOnly: {\\n    prototype: DOMPointReadOnly;\\n    new(x?: number, y?: number, z?: number, w?: number): DOMPointReadOnly;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMPointReadOnly/fromPoint_static) */\\n    fromPoint(other?: DOMPointInit): DOMPointReadOnly;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad) */\\ninterface DOMQuad {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p1) */\\n    readonly p1: DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p2) */\\n    readonly p2: DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p3) */\\n    readonly p3: DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/p4) */\\n    readonly p4: DOMPoint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMQuad/getBounds) */\\n    getBounds(): DOMRect;\\n    toJSON(): any;\\n}\\n\\ndeclare var DOMQuad: {\\n    prototype: DOMQuad;\\n    new(p1?: DOMPointInit, p2?: DOMPointInit, p3?: DOMPointInit, p4?: DOMPointInit): DOMQuad;\\n    fromQuad(other?: DOMQuadInit): DOMQuad;\\n    fromRect(other?: DOMRectInit): DOMQuad;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRect) */\\ninterface DOMRect extends DOMRectReadOnly {\\n    height: number;\\n    width: number;\\n    x: number;\\n    y: number;\\n}\\n\\ndeclare var DOMRect: {\\n    prototype: DOMRect;\\n    new(x?: number, y?: number, width?: number, height?: number): DOMRect;\\n    fromRect(other?: DOMRectInit): DOMRect;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly) */\\ninterface DOMRectReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/bottom) */\\n    readonly bottom: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/height) */\\n    readonly height: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/left) */\\n    readonly left: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/right) */\\n    readonly right: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/top) */\\n    readonly top: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/width) */\\n    readonly width: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/x) */\\n    readonly x: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/y) */\\n    readonly y: number;\\n    toJSON(): any;\\n}\\n\\ndeclare var DOMRectReadOnly: {\\n    prototype: DOMRectReadOnly;\\n    new(x?: number, y?: number, width?: number, height?: number): DOMRectReadOnly;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMRectReadOnly/fromRect_static) */\\n    fromRect(other?: DOMRectInit): DOMRectReadOnly;\\n};\\n\\n/**\\n * A type returned by some APIs which contains a list of DOMString (strings).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringList)\\n */\\ninterface DOMStringList {\\n    /**\\n     * Returns the number of strings in strings.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringList/length)\\n     */\\n    readonly length: number;\\n    /**\\n     * Returns true if strings contains string, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringList/contains)\\n     */\\n    contains(string: string): boolean;\\n    /**\\n     * Returns the string with index index from strings.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DOMStringList/item)\\n     */\\n    item(index: number): string | null;\\n    [index: number]: string;\\n}\\n\\ndeclare var DOMStringList: {\\n    prototype: DOMStringList;\\n    new(): DOMStringList;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DecompressionStream) */\\ninterface DecompressionStream extends GenericTransformStream {\\n}\\n\\ndeclare var DecompressionStream: {\\n    prototype: DecompressionStream;\\n    new(format: CompressionFormat): DecompressionStream;\\n};\\n\\ninterface DedicatedWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/**\\n * (the Worker global scope) is accessible through the self keyword. Some additional global functions, namespaces objects, and constructors, not typically associated with the worker global scope, but available on it, are listed in the JavaScript Reference. See also: Functions available to workers.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope)\\n */\\ninterface DedicatedWorkerGlobalScope extends WorkerGlobalScope, AnimationFrameProvider {\\n    /**\\n     * Returns dedicatedWorkerGlobal's name, i.e. the value given to the Worker constructor. Primarily useful for debugging.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/name)\\n     */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/message_event) */\\n    onmessage: ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/messageerror_event) */\\n    onmessageerror: ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null;\\n    /**\\n     * Aborts dedicatedWorkerGlobal.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/close)\\n     */\\n    close(): void;\\n    /**\\n     * Clones message and transmits it to the Worker object associated with dedicatedWorkerGlobal. transfer can be passed as a list of objects that are to be transferred rather than cloned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/postMessage)\\n     */\\n    postMessage(message: any, transfer: Transferable[]): void;\\n    postMessage(message: any, options?: StructuredSerializeOptions): void;\\n    addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var DedicatedWorkerGlobalScope: {\\n    prototype: DedicatedWorkerGlobalScope;\\n    new(): DedicatedWorkerGlobalScope;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_blend_minmax) */\\ninterface EXT_blend_minmax {\\n    readonly MIN_EXT: 0x8007;\\n    readonly MAX_EXT: 0x8008;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_color_buffer_float) */\\ninterface EXT_color_buffer_float {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_color_buffer_half_float) */\\ninterface EXT_color_buffer_half_float {\\n    readonly RGBA16F_EXT: 0x881A;\\n    readonly RGB16F_EXT: 0x881B;\\n    readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211;\\n    readonly UNSIGNED_NORMALIZED_EXT: 0x8C17;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_float_blend) */\\ninterface EXT_float_blend {\\n}\\n\\n/**\\n * The EXT_frag_depth extension is part of the WebGL API and enables to set a depth value of a fragment from within the fragment shader.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_frag_depth)\\n */\\ninterface EXT_frag_depth {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_sRGB) */\\ninterface EXT_sRGB {\\n    readonly SRGB_EXT: 0x8C40;\\n    readonly SRGB_ALPHA_EXT: 0x8C42;\\n    readonly SRGB8_ALPHA8_EXT: 0x8C43;\\n    readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: 0x8210;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_shader_texture_lod) */\\ninterface EXT_shader_texture_lod {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_texture_compression_bptc) */\\ninterface EXT_texture_compression_bptc {\\n    readonly COMPRESSED_RGBA_BPTC_UNORM_EXT: 0x8E8C;\\n    readonly COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: 0x8E8D;\\n    readonly COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: 0x8E8E;\\n    readonly COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: 0x8E8F;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_texture_compression_rgtc) */\\ninterface EXT_texture_compression_rgtc {\\n    readonly COMPRESSED_RED_RGTC1_EXT: 0x8DBB;\\n    readonly COMPRESSED_SIGNED_RED_RGTC1_EXT: 0x8DBC;\\n    readonly COMPRESSED_RED_GREEN_RGTC2_EXT: 0x8DBD;\\n    readonly COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: 0x8DBE;\\n}\\n\\n/**\\n * The EXT_texture_filter_anisotropic extension is part of the WebGL API and exposes two constants for anisotropic filtering (AF).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_texture_filter_anisotropic)\\n */\\ninterface EXT_texture_filter_anisotropic {\\n    readonly TEXTURE_MAX_ANISOTROPY_EXT: 0x84FE;\\n    readonly MAX_TEXTURE_MAX_ANISOTROPY_EXT: 0x84FF;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EXT_texture_norm16) */\\ninterface EXT_texture_norm16 {\\n    readonly R16_EXT: 0x822A;\\n    readonly RG16_EXT: 0x822C;\\n    readonly RGB16_EXT: 0x8054;\\n    readonly RGBA16_EXT: 0x805B;\\n    readonly R16_SNORM_EXT: 0x8F98;\\n    readonly RG16_SNORM_EXT: 0x8F99;\\n    readonly RGB16_SNORM_EXT: 0x8F9A;\\n    readonly RGBA16_SNORM_EXT: 0x8F9B;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk) */\\ninterface EncodedVideoChunk {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/byteLength) */\\n    readonly byteLength: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/duration) */\\n    readonly duration: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/timestamp) */\\n    readonly timestamp: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/type) */\\n    readonly type: EncodedVideoChunkType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EncodedVideoChunk/copyTo) */\\n    copyTo(destination: BufferSource): void;\\n}\\n\\ndeclare var EncodedVideoChunk: {\\n    prototype: EncodedVideoChunk;\\n    new(init: EncodedVideoChunkInit): EncodedVideoChunk;\\n};\\n\\n/**\\n * Events providing information related to errors in scripts or in files.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent)\\n */\\ninterface ErrorEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/colno) */\\n    readonly colno: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/error) */\\n    readonly error: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/filename) */\\n    readonly filename: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/lineno) */\\n    readonly lineno: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ErrorEvent/message) */\\n    readonly message: string;\\n}\\n\\ndeclare var ErrorEvent: {\\n    prototype: ErrorEvent;\\n    new(type: string, eventInitDict?: ErrorEventInit): ErrorEvent;\\n};\\n\\n/**\\n * An event which takes place in the DOM.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event)\\n */\\ninterface Event {\\n    /**\\n     * Returns true or false depending on how event was initialized. True if event goes through its target's ancestors in reverse tree order, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/bubbles)\\n     */\\n    readonly bubbles: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/cancelBubble)\\n     */\\n    cancelBubble: boolean;\\n    /**\\n     * Returns true or false depending on how event was initialized. Its return value does not always carry meaning, but true can indicate that part of the operation during which event was dispatched, can be canceled by invoking the preventDefault() method.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/cancelable)\\n     */\\n    readonly cancelable: boolean;\\n    /**\\n     * Returns true or false depending on how event was initialized. True if event invokes listeners past a ShadowRoot node that is the root of its target, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/composed)\\n     */\\n    readonly composed: boolean;\\n    /**\\n     * Returns the object whose event listener's callback is currently being invoked.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/currentTarget)\\n     */\\n    readonly currentTarget: EventTarget | null;\\n    /**\\n     * Returns true if preventDefault() was invoked successfully to indicate cancelation, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/defaultPrevented)\\n     */\\n    readonly defaultPrevented: boolean;\\n    /**\\n     * Returns the event's phase, which is one of NONE, CAPTURING_PHASE, AT_TARGET, and BUBBLING_PHASE.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/eventPhase)\\n     */\\n    readonly eventPhase: number;\\n    /**\\n     * Returns true if event was dispatched by the user agent, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/isTrusted)\\n     */\\n    readonly isTrusted: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/returnValue)\\n     */\\n    returnValue: boolean;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/srcElement)\\n     */\\n    readonly srcElement: EventTarget | null;\\n    /**\\n     * Returns the object to which event is dispatched (its target).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/target)\\n     */\\n    readonly target: EventTarget | null;\\n    /**\\n     * Returns the event's timestamp as the number of milliseconds measured relative to the time origin.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/timeStamp)\\n     */\\n    readonly timeStamp: DOMHighResTimeStamp;\\n    /**\\n     * Returns the type of event, e.g. \\\"click\\\", \\\"hashchange\\\", or \\\"submit\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/type)\\n     */\\n    readonly type: string;\\n    /**\\n     * Returns the invocation target objects of event's path (objects on which listeners will be invoked), except for any nodes in shadow trees of which the shadow root's mode is \\\"closed\\\" that are not reachable from event's currentTarget.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/composedPath)\\n     */\\n    composedPath(): EventTarget[];\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/initEvent)\\n     */\\n    initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void;\\n    /**\\n     * If invoked when the cancelable attribute value is true, and while executing a listener for the event with passive set to false, signals to the operation that caused event to be dispatched that it needs to be canceled.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/preventDefault)\\n     */\\n    preventDefault(): void;\\n    /**\\n     * Invoking this method prevents event from reaching any registered event listeners after the current one finishes running and, when dispatched in a tree, also prevents event from reaching any other objects.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/stopImmediatePropagation)\\n     */\\n    stopImmediatePropagation(): void;\\n    /**\\n     * When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Event/stopPropagation)\\n     */\\n    stopPropagation(): void;\\n    readonly NONE: 0;\\n    readonly CAPTURING_PHASE: 1;\\n    readonly AT_TARGET: 2;\\n    readonly BUBBLING_PHASE: 3;\\n}\\n\\ndeclare var Event: {\\n    prototype: Event;\\n    new(type: string, eventInitDict?: EventInit): Event;\\n    readonly NONE: 0;\\n    readonly CAPTURING_PHASE: 1;\\n    readonly AT_TARGET: 2;\\n    readonly BUBBLING_PHASE: 3;\\n};\\n\\ninterface EventListener {\\n    (evt: Event): void;\\n}\\n\\ninterface EventListenerObject {\\n    handleEvent(object: Event): void;\\n}\\n\\ninterface EventSourceEventMap {\\n    \\\"error\\\": Event;\\n    \\\"message\\\": MessageEvent;\\n    \\\"open\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource) */\\ninterface EventSource extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */\\n    onerror: ((this: EventSource, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */\\n    onmessage: ((this: EventSource, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */\\n    onopen: ((this: EventSource, ev: Event) => any) | null;\\n    /**\\n     * Returns the state of this EventSource object's connection. It can have the values described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)\\n     */\\n    readonly readyState: number;\\n    /**\\n     * Returns the URL providing the event stream.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)\\n     */\\n    readonly url: string;\\n    /**\\n     * Returns true if the credentials mode for connection requests to the URL providing the event stream is set to \\\"include\\\", and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)\\n     */\\n    readonly withCredentials: boolean;\\n    /**\\n     * Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)\\n     */\\n    close(): void;\\n    readonly CONNECTING: 0;\\n    readonly OPEN: 1;\\n    readonly CLOSED: 2;\\n    addEventListener<K extends keyof EventSourceEventMap>(type: K, listener: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: (this: EventSource, event: MessageEvent) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof EventSourceEventMap>(type: K, listener: (this: EventSource, ev: EventSourceEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: (this: EventSource, event: MessageEvent) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var EventSource: {\\n    prototype: EventSource;\\n    new(url: string | URL, eventSourceInitDict?: EventSourceInit): EventSource;\\n    readonly CONNECTING: 0;\\n    readonly OPEN: 1;\\n    readonly CLOSED: 2;\\n};\\n\\n/**\\n * EventTarget is a DOM interface implemented by objects that can receive events and may have listeners for them.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget)\\n */\\ninterface EventTarget {\\n    /**\\n     * Appends an event listener for events whose type attribute value is type. The callback argument sets the callback that will be invoked when the event is dispatched.\\n     *\\n     * The options argument sets listener-specific options. For compatibility this can be a boolean, in which case the method behaves exactly as if the value was specified as options's capture.\\n     *\\n     * When set to true, options's capture prevents callback from being invoked when the event's eventPhase attribute value is BUBBLING_PHASE. When false (or not present), callback will not be invoked when event's eventPhase attribute value is CAPTURING_PHASE. Either way, callback will be invoked if event's eventPhase attribute value is AT_TARGET.\\n     *\\n     * When set to true, options's passive indicates that the callback will not cancel the event by invoking preventDefault(). This is used to enable performance optimizations described in § 2.8 Observing event listeners.\\n     *\\n     * When set to true, options's once indicates that the callback will only be invoked once after which the event listener will be removed.\\n     *\\n     * If an AbortSignal is passed for options's signal, then the event listener will be removed when signal is aborted.\\n     *\\n     * The event listener is appended to target's event listener list and is not appended if it has the same type, callback, and capture.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener)\\n     */\\n    addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void;\\n    /**\\n     * Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/dispatchEvent)\\n     */\\n    dispatchEvent(event: Event): boolean;\\n    /**\\n     * Removes the event listener in target's event listener list with the same type, callback, and options.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/removeEventListener)\\n     */\\n    removeEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;\\n}\\n\\ndeclare var EventTarget: {\\n    prototype: EventTarget;\\n    new(): EventTarget;\\n};\\n\\n/**\\n * Extends the lifetime of the install and activate events dispatched on the global scope as part of the service worker lifecycle. This ensures that any functional events (like FetchEvent) are not dispatched until it upgrades database schemas and deletes the outdated cache entries.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ExtendableEvent)\\n */\\ninterface ExtendableEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ExtendableEvent/waitUntil) */\\n    waitUntil(f: Promise<any>): void;\\n}\\n\\ndeclare var ExtendableEvent: {\\n    prototype: ExtendableEvent;\\n    new(type: string, eventInitDict?: ExtendableEventInit): ExtendableEvent;\\n};\\n\\n/**\\n * This ServiceWorker API interface represents the event object of a message event fired on a service worker (when a channel message is received on the ServiceWorkerGlobalScope from another context) — extends the lifetime of such events.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ExtendableMessageEvent)\\n */\\ninterface ExtendableMessageEvent extends ExtendableEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ExtendableMessageEvent/data) */\\n    readonly data: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ExtendableMessageEvent/lastEventId) */\\n    readonly lastEventId: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ExtendableMessageEvent/origin) */\\n    readonly origin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ExtendableMessageEvent/ports) */\\n    readonly ports: ReadonlyArray<MessagePort>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ExtendableMessageEvent/source) */\\n    readonly source: Client | ServiceWorker | MessagePort | null;\\n}\\n\\ndeclare var ExtendableMessageEvent: {\\n    prototype: ExtendableMessageEvent;\\n    new(type: string, eventInitDict?: ExtendableMessageEventInit): ExtendableMessageEvent;\\n};\\n\\n/**\\n * This is the event type for fetch events dispatched on the service worker global scope. It contains information about the fetch, including the request and how the receiver will treat the response. It provides the event.respondWith() method, which allows us to provide a response to this fetch.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent)\\n */\\ninterface FetchEvent extends ExtendableEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent/clientId) */\\n    readonly clientId: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent/handled) */\\n    readonly handled: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent/preloadResponse) */\\n    readonly preloadResponse: Promise<any>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent/request) */\\n    readonly request: Request;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent/resultingClientId) */\\n    readonly resultingClientId: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FetchEvent/respondWith) */\\n    respondWith(r: Response | PromiseLike<Response>): void;\\n}\\n\\ndeclare var FetchEvent: {\\n    prototype: FetchEvent;\\n    new(type: string, eventInitDict: FetchEventInit): FetchEvent;\\n};\\n\\n/**\\n * Provides information about files and allows JavaScript in a web page to access their content.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/File)\\n */\\ninterface File extends Blob {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */\\n    readonly lastModified: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/webkitRelativePath) */\\n    readonly webkitRelativePath: string;\\n}\\n\\ndeclare var File: {\\n    prototype: File;\\n    new(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): File;\\n};\\n\\n/**\\n * An object of this type is returned by the files property of the HTML <input> element; this lets you access the list of files selected with the <input type=\\\"file\\\"> element. It's also used for a list of files dropped into web content when using the drag and drop API; see the DataTransfer object for details on this usage.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileList)\\n */\\ninterface FileList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileList/length) */\\n    readonly length: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileList/item) */\\n    item(index: number): File | null;\\n    [index: number]: File;\\n}\\n\\ndeclare var FileList: {\\n    prototype: FileList;\\n    new(): FileList;\\n};\\n\\ninterface FileReaderEventMap {\\n    \\\"abort\\\": ProgressEvent<FileReader>;\\n    \\\"error\\\": ProgressEvent<FileReader>;\\n    \\\"load\\\": ProgressEvent<FileReader>;\\n    \\\"loadend\\\": ProgressEvent<FileReader>;\\n    \\\"loadstart\\\": ProgressEvent<FileReader>;\\n    \\\"progress\\\": ProgressEvent<FileReader>;\\n}\\n\\n/**\\n * Lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer, using File or Blob objects to specify the file or data to read.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader)\\n */\\ninterface FileReader extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/error) */\\n    readonly error: DOMException | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/abort_event) */\\n    onabort: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/error_event) */\\n    onerror: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/load_event) */\\n    onload: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/loadend_event) */\\n    onloadend: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/loadstart_event) */\\n    onloadstart: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/progress_event) */\\n    onprogress: ((this: FileReader, ev: ProgressEvent<FileReader>) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readyState) */\\n    readonly readyState: typeof FileReader.EMPTY | typeof FileReader.LOADING | typeof FileReader.DONE;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/result) */\\n    readonly result: string | ArrayBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/abort) */\\n    abort(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readAsArrayBuffer) */\\n    readAsArrayBuffer(blob: Blob): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readAsBinaryString) */\\n    readAsBinaryString(blob: Blob): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readAsDataURL) */\\n    readAsDataURL(blob: Blob): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReader/readAsText) */\\n    readAsText(blob: Blob, encoding?: string): void;\\n    readonly EMPTY: 0;\\n    readonly LOADING: 1;\\n    readonly DONE: 2;\\n    addEventListener<K extends keyof FileReaderEventMap>(type: K, listener: (this: FileReader, ev: FileReaderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof FileReaderEventMap>(type: K, listener: (this: FileReader, ev: FileReaderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var FileReader: {\\n    prototype: FileReader;\\n    new(): FileReader;\\n    readonly EMPTY: 0;\\n    readonly LOADING: 1;\\n    readonly DONE: 2;\\n};\\n\\n/**\\n * Allows to read File or Blob objects in a synchronous way.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReaderSync)\\n */\\ninterface FileReaderSync {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReaderSync/readAsArrayBuffer) */\\n    readAsArrayBuffer(blob: Blob): ArrayBuffer;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReaderSync/readAsBinaryString)\\n     */\\n    readAsBinaryString(blob: Blob): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReaderSync/readAsDataURL) */\\n    readAsDataURL(blob: Blob): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileReaderSync/readAsText) */\\n    readAsText(blob: Blob, encoding?: string): string;\\n}\\n\\ndeclare var FileReaderSync: {\\n    prototype: FileReaderSync;\\n    new(): FileReaderSync;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle)\\n */\\ninterface FileSystemDirectoryHandle extends FileSystemHandle {\\n    readonly kind: \\\"directory\\\";\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle/getDirectoryHandle) */\\n    getDirectoryHandle(name: string, options?: FileSystemGetDirectoryOptions): Promise<FileSystemDirectoryHandle>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle/getFileHandle) */\\n    getFileHandle(name: string, options?: FileSystemGetFileOptions): Promise<FileSystemFileHandle>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle/removeEntry) */\\n    removeEntry(name: string, options?: FileSystemRemoveOptions): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemDirectoryHandle/resolve) */\\n    resolve(possibleDescendant: FileSystemHandle): Promise<string[] | null>;\\n}\\n\\ndeclare var FileSystemDirectoryHandle: {\\n    prototype: FileSystemDirectoryHandle;\\n    new(): FileSystemDirectoryHandle;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle)\\n */\\ninterface FileSystemFileHandle extends FileSystemHandle {\\n    readonly kind: \\\"file\\\";\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/createSyncAccessHandle) */\\n    createSyncAccessHandle(): Promise<FileSystemSyncAccessHandle>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/createWritable) */\\n    createWritable(options?: FileSystemCreateWritableOptions): Promise<FileSystemWritableFileStream>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemFileHandle/getFile) */\\n    getFile(): Promise<File>;\\n}\\n\\ndeclare var FileSystemFileHandle: {\\n    prototype: FileSystemFileHandle;\\n    new(): FileSystemFileHandle;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemHandle)\\n */\\ninterface FileSystemHandle {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/kind) */\\n    readonly kind: FileSystemHandleKind;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemHandle/isSameEntry) */\\n    isSameEntry(other: FileSystemHandle): Promise<boolean>;\\n}\\n\\ndeclare var FileSystemHandle: {\\n    prototype: FileSystemHandle;\\n    new(): FileSystemHandle;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemSyncAccessHandle)\\n */\\ninterface FileSystemSyncAccessHandle {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemSyncAccessHandle/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemSyncAccessHandle/flush) */\\n    flush(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemSyncAccessHandle/getSize) */\\n    getSize(): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemSyncAccessHandle/read) */\\n    read(buffer: AllowSharedBufferSource, options?: FileSystemReadWriteOptions): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemSyncAccessHandle/truncate) */\\n    truncate(newSize: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemSyncAccessHandle/write) */\\n    write(buffer: AllowSharedBufferSource, options?: FileSystemReadWriteOptions): number;\\n}\\n\\ndeclare var FileSystemSyncAccessHandle: {\\n    prototype: FileSystemSyncAccessHandle;\\n    new(): FileSystemSyncAccessHandle;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemWritableFileStream)\\n */\\ninterface FileSystemWritableFileStream extends WritableStream {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemWritableFileStream/seek) */\\n    seek(position: number): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemWritableFileStream/truncate) */\\n    truncate(size: number): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FileSystemWritableFileStream/write) */\\n    write(data: FileSystemWriteChunkType): Promise<void>;\\n}\\n\\ndeclare var FileSystemWritableFileStream: {\\n    prototype: FileSystemWritableFileStream;\\n    new(): FileSystemWritableFileStream;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace) */\\ninterface FontFace {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/ascentOverride) */\\n    ascentOverride: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/descentOverride) */\\n    descentOverride: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/display) */\\n    display: FontDisplay;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/family) */\\n    family: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/featureSettings) */\\n    featureSettings: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/lineGapOverride) */\\n    lineGapOverride: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/loaded) */\\n    readonly loaded: Promise<FontFace>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/status) */\\n    readonly status: FontFaceLoadStatus;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/stretch) */\\n    stretch: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/style) */\\n    style: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/unicodeRange) */\\n    unicodeRange: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/variant) */\\n    variant: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/weight) */\\n    weight: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFace/load) */\\n    load(): Promise<FontFace>;\\n}\\n\\ndeclare var FontFace: {\\n    prototype: FontFace;\\n    new(family: string, source: string | BinaryData, descriptors?: FontFaceDescriptors): FontFace;\\n};\\n\\ninterface FontFaceSetEventMap {\\n    \\\"loading\\\": Event;\\n    \\\"loadingdone\\\": Event;\\n    \\\"loadingerror\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet) */\\ninterface FontFaceSet extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/loading_event) */\\n    onloading: ((this: FontFaceSet, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/loadingdone_event) */\\n    onloadingdone: ((this: FontFaceSet, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/loadingerror_event) */\\n    onloadingerror: ((this: FontFaceSet, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/ready) */\\n    readonly ready: Promise<FontFaceSet>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/status) */\\n    readonly status: FontFaceSetLoadStatus;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/check) */\\n    check(font: string, text?: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSet/load) */\\n    load(font: string, text?: string): Promise<FontFace[]>;\\n    forEach(callbackfn: (value: FontFace, key: FontFace, parent: FontFaceSet) => void, thisArg?: any): void;\\n    addEventListener<K extends keyof FontFaceSetEventMap>(type: K, listener: (this: FontFaceSet, ev: FontFaceSetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof FontFaceSetEventMap>(type: K, listener: (this: FontFaceSet, ev: FontFaceSetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var FontFaceSet: {\\n    prototype: FontFaceSet;\\n    new(initialFaces: FontFace[]): FontFaceSet;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSetLoadEvent) */\\ninterface FontFaceSetLoadEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FontFaceSetLoadEvent/fontfaces) */\\n    readonly fontfaces: ReadonlyArray<FontFace>;\\n}\\n\\ndeclare var FontFaceSetLoadEvent: {\\n    prototype: FontFaceSetLoadEvent;\\n    new(type: string, eventInitDict?: FontFaceSetLoadEventInit): FontFaceSetLoadEvent;\\n};\\n\\ninterface FontFaceSource {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fonts) */\\n    readonly fonts: FontFaceSet;\\n}\\n\\n/**\\n * Provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to \\\"multipart/form-data\\\".\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData)\\n */\\ninterface FormData {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/append) */\\n    append(name: string, value: string | Blob): void;\\n    append(name: string, value: string): void;\\n    append(name: string, blobValue: Blob, filename?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/delete) */\\n    delete(name: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/get) */\\n    get(name: string): FormDataEntryValue | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/getAll) */\\n    getAll(name: string): FormDataEntryValue[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/has) */\\n    has(name: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/FormData/set) */\\n    set(name: string, value: string | Blob): void;\\n    set(name: string, value: string): void;\\n    set(name: string, blobValue: Blob, filename?: string): void;\\n    forEach(callbackfn: (value: FormDataEntryValue, key: string, parent: FormData) => void, thisArg?: any): void;\\n}\\n\\ndeclare var FormData: {\\n    prototype: FormData;\\n    new(): FormData;\\n};\\n\\ninterface GenericTransformStream {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompressionStream/readable) */\\n    readonly readable: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CompressionStream/writable) */\\n    readonly writable: WritableStream;\\n}\\n\\n/**\\n * This Fetch API interface allows you to perform various actions on HTTP request and response headers. These actions include retrieving, setting, adding to, and removing. A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs.  You can add to this using methods like append() (see Examples.) In all methods of this interface, header names are matched by case-insensitive byte sequence.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers)\\n */\\ninterface Headers {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/append) */\\n    append(name: string, value: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/delete) */\\n    delete(name: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/get) */\\n    get(name: string): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/getSetCookie) */\\n    getSetCookie(): string[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/has) */\\n    has(name: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Headers/set) */\\n    set(name: string, value: string): void;\\n    forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: any): void;\\n}\\n\\ndeclare var Headers: {\\n    prototype: Headers;\\n    new(init?: HeadersInit): Headers;\\n};\\n\\n/**\\n * This IndexedDB API interface represents a cursor for traversing or iterating over multiple records in a database.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor)\\n */\\ninterface IDBCursor {\\n    /**\\n     * Returns the direction (\\\"next\\\", \\\"nextunique\\\", \\\"prev\\\" or \\\"prevunique\\\") of the cursor.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/direction)\\n     */\\n    readonly direction: IDBCursorDirection;\\n    /**\\n     * Returns the key of the cursor. Throws a \\\"InvalidStateError\\\" DOMException if the cursor is advancing or is finished.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/key)\\n     */\\n    readonly key: IDBValidKey;\\n    /**\\n     * Returns the effective key of the cursor. Throws a \\\"InvalidStateError\\\" DOMException if the cursor is advancing or is finished.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/primaryKey)\\n     */\\n    readonly primaryKey: IDBValidKey;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/request) */\\n    readonly request: IDBRequest;\\n    /**\\n     * Returns the IDBObjectStore or IDBIndex the cursor was opened from.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/source)\\n     */\\n    readonly source: IDBObjectStore | IDBIndex;\\n    /**\\n     * Advances the cursor through the next count records in range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/advance)\\n     */\\n    advance(count: number): void;\\n    /**\\n     * Advances the cursor to the next record in range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/continue)\\n     */\\n    continue(key?: IDBValidKey): void;\\n    /**\\n     * Advances the cursor to the next record in range matching or after key and primaryKey. Throws an \\\"InvalidAccessError\\\" DOMException if the source is not an index.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/continuePrimaryKey)\\n     */\\n    continuePrimaryKey(key: IDBValidKey, primaryKey: IDBValidKey): void;\\n    /**\\n     * Delete the record pointed at by the cursor with a new value.\\n     *\\n     * If successful, request's result will be undefined.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/delete)\\n     */\\n    delete(): IDBRequest<undefined>;\\n    /**\\n     * Updated the record pointed at by the cursor with a new value.\\n     *\\n     * Throws a \\\"DataError\\\" DOMException if the effective object store uses in-line keys and the key would have changed.\\n     *\\n     * If successful, request's result will be the record's key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursor/update)\\n     */\\n    update(value: any): IDBRequest<IDBValidKey>;\\n}\\n\\ndeclare var IDBCursor: {\\n    prototype: IDBCursor;\\n    new(): IDBCursor;\\n};\\n\\n/**\\n * This IndexedDB API interface represents a cursor for traversing or iterating over multiple records in a database. It is the same as the IDBCursor, except that it includes the value property.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursorWithValue)\\n */\\ninterface IDBCursorWithValue extends IDBCursor {\\n    /**\\n     * Returns the cursor's current value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBCursorWithValue/value)\\n     */\\n    readonly value: any;\\n}\\n\\ndeclare var IDBCursorWithValue: {\\n    prototype: IDBCursorWithValue;\\n    new(): IDBCursorWithValue;\\n};\\n\\ninterface IDBDatabaseEventMap {\\n    \\\"abort\\\": Event;\\n    \\\"close\\\": Event;\\n    \\\"error\\\": Event;\\n    \\\"versionchange\\\": IDBVersionChangeEvent;\\n}\\n\\n/**\\n * This IndexedDB API interface provides a connection to a database; you can use an IDBDatabase object to open a transaction on your database then create, manipulate, and delete objects (data) in that database. The interface provides the only way to get and manage versions of the database.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase)\\n */\\ninterface IDBDatabase extends EventTarget {\\n    /**\\n     * Returns the name of the database.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/name)\\n     */\\n    readonly name: string;\\n    /**\\n     * Returns a list of the names of object stores in the database.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/objectStoreNames)\\n     */\\n    readonly objectStoreNames: DOMStringList;\\n    onabort: ((this: IDBDatabase, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/close_event) */\\n    onclose: ((this: IDBDatabase, ev: Event) => any) | null;\\n    onerror: ((this: IDBDatabase, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/versionchange_event) */\\n    onversionchange: ((this: IDBDatabase, ev: IDBVersionChangeEvent) => any) | null;\\n    /**\\n     * Returns the version of the database.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/version)\\n     */\\n    readonly version: number;\\n    /**\\n     * Closes the connection once all running transactions have finished.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/close)\\n     */\\n    close(): void;\\n    /**\\n     * Creates a new object store with the given name and options and returns a new IDBObjectStore.\\n     *\\n     * Throws a \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/createObjectStore)\\n     */\\n    createObjectStore(name: string, options?: IDBObjectStoreParameters): IDBObjectStore;\\n    /**\\n     * Deletes the object store with the given name.\\n     *\\n     * Throws a \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/deleteObjectStore)\\n     */\\n    deleteObjectStore(name: string): void;\\n    /**\\n     * Returns a new transaction with the given mode (\\\"readonly\\\" or \\\"readwrite\\\") and scope which can be a single object store name or an array of names.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/transaction)\\n     */\\n    transaction(storeNames: string | string[], mode?: IDBTransactionMode, options?: IDBTransactionOptions): IDBTransaction;\\n    addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var IDBDatabase: {\\n    prototype: IDBDatabase;\\n    new(): IDBDatabase;\\n};\\n\\n/**\\n * In the following code snippet, we make a request to open a database, and include handlers for the success and error cases. For a full working example, see our To-do Notifications app (view example live.)\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory)\\n */\\ninterface IDBFactory {\\n    /**\\n     * Compares two values as keys. Returns -1 if key1 precedes key2, 1 if key2 precedes key1, and 0 if the keys are equal.\\n     *\\n     * Throws a \\\"DataError\\\" DOMException if either input is not a valid key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory/cmp)\\n     */\\n    cmp(first: any, second: any): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory/databases) */\\n    databases(): Promise<IDBDatabaseInfo[]>;\\n    /**\\n     * Attempts to delete the named database. If the database already exists and there are open connections that don't close in response to a versionchange event, the request will be blocked until all they close. If the request is successful request's result will be null.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory/deleteDatabase)\\n     */\\n    deleteDatabase(name: string): IDBOpenDBRequest;\\n    /**\\n     * Attempts to open a connection to the named database with the current version, or 1 if it does not already exist. If the request is successful request's result will be the connection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBFactory/open)\\n     */\\n    open(name: string, version?: number): IDBOpenDBRequest;\\n}\\n\\ndeclare var IDBFactory: {\\n    prototype: IDBFactory;\\n    new(): IDBFactory;\\n};\\n\\n/**\\n * IDBIndex interface of the IndexedDB API provides asynchronous access to an index in a database. An index is a kind of object store for looking up records in another object store, called the referenced object store. You use this interface to retrieve data.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex)\\n */\\ninterface IDBIndex {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/keyPath) */\\n    readonly keyPath: string | string[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/multiEntry) */\\n    readonly multiEntry: boolean;\\n    /**\\n     * Returns the name of the index.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/name)\\n     */\\n    name: string;\\n    /**\\n     * Returns the IDBObjectStore the index belongs to.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/objectStore)\\n     */\\n    readonly objectStore: IDBObjectStore;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/unique) */\\n    readonly unique: boolean;\\n    /**\\n     * Retrieves the number of records matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the count.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/count)\\n     */\\n    count(query?: IDBValidKey | IDBKeyRange): IDBRequest<number>;\\n    /**\\n     * Retrieves the value of the first record matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the value, or undefined if there was no matching record.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/get)\\n     */\\n    get(query: IDBValidKey | IDBKeyRange): IDBRequest<any>;\\n    /**\\n     * Retrieves the values of the records matching the given key or key range in query (up to count if given).\\n     *\\n     * If successful, request's result will be an Array of the values.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/getAll)\\n     */\\n    getAll(query?: IDBValidKey | IDBKeyRange | null, count?: number): IDBRequest<any[]>;\\n    /**\\n     * Retrieves the keys of records matching the given key or key range in query (up to count if given).\\n     *\\n     * If successful, request's result will be an Array of the keys.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/getAllKeys)\\n     */\\n    getAllKeys(query?: IDBValidKey | IDBKeyRange | null, count?: number): IDBRequest<IDBValidKey[]>;\\n    /**\\n     * Retrieves the key of the first record matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the key, or undefined if there was no matching record.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/getKey)\\n     */\\n    getKey(query: IDBValidKey | IDBKeyRange): IDBRequest<IDBValidKey | undefined>;\\n    /**\\n     * Opens a cursor over the records matching query, ordered by direction. If query is null, all records in index are matched.\\n     *\\n     * If successful, request's result will be an IDBCursorWithValue, or null if there were no matching records.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/openCursor)\\n     */\\n    openCursor(query?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null>;\\n    /**\\n     * Opens a cursor with key only flag set over the records matching query, ordered by direction. If query is null, all records in index are matched.\\n     *\\n     * If successful, request's result will be an IDBCursor, or null if there were no matching records.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBIndex/openKeyCursor)\\n     */\\n    openKeyCursor(query?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection): IDBRequest<IDBCursor | null>;\\n}\\n\\ndeclare var IDBIndex: {\\n    prototype: IDBIndex;\\n    new(): IDBIndex;\\n};\\n\\n/**\\n * A key range can be a single value or a range with upper and lower bounds or endpoints. If the key range has both upper and lower bounds, then it is bounded; if it has no bounds, it is unbounded. A bounded key range can either be open (the endpoints are excluded) or closed (the endpoints are included). To retrieve all keys within a certain range, you can use the following code constructs:\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange)\\n */\\ninterface IDBKeyRange {\\n    /**\\n     * Returns lower bound, or undefined if none.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/lower)\\n     */\\n    readonly lower: any;\\n    /**\\n     * Returns true if the lower open flag is set, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/lowerOpen)\\n     */\\n    readonly lowerOpen: boolean;\\n    /**\\n     * Returns upper bound, or undefined if none.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/upper)\\n     */\\n    readonly upper: any;\\n    /**\\n     * Returns true if the upper open flag is set, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/upperOpen)\\n     */\\n    readonly upperOpen: boolean;\\n    /**\\n     * Returns true if key is included in the range, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/includes)\\n     */\\n    includes(key: any): boolean;\\n}\\n\\ndeclare var IDBKeyRange: {\\n    prototype: IDBKeyRange;\\n    new(): IDBKeyRange;\\n    /**\\n     * Returns a new IDBKeyRange spanning from lower to upper. If lowerOpen is true, lower is not included in the range. If upperOpen is true, upper is not included in the range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/bound_static)\\n     */\\n    bound(lower: any, upper: any, lowerOpen?: boolean, upperOpen?: boolean): IDBKeyRange;\\n    /**\\n     * Returns a new IDBKeyRange starting at key with no upper bound. If open is true, key is not included in the range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/lowerBound_static)\\n     */\\n    lowerBound(lower: any, open?: boolean): IDBKeyRange;\\n    /**\\n     * Returns a new IDBKeyRange spanning only key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/only_static)\\n     */\\n    only(value: any): IDBKeyRange;\\n    /**\\n     * Returns a new IDBKeyRange with no lower bound and ending at key. If open is true, key is not included in the range.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBKeyRange/upperBound_static)\\n     */\\n    upperBound(upper: any, open?: boolean): IDBKeyRange;\\n};\\n\\n/**\\n * This example shows a variety of different uses of object stores, from updating the data structure with IDBObjectStore.createIndex inside an onupgradeneeded function, to adding a new item to our object store with IDBObjectStore.add. For a full working example, see our To-do Notifications app (view example live.)\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore)\\n */\\ninterface IDBObjectStore {\\n    /**\\n     * Returns true if the store has a key generator, and false otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/autoIncrement)\\n     */\\n    readonly autoIncrement: boolean;\\n    /**\\n     * Returns a list of the names of indexes in the store.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/indexNames)\\n     */\\n    readonly indexNames: DOMStringList;\\n    /**\\n     * Returns the key path of the store, or null if none.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/keyPath)\\n     */\\n    readonly keyPath: string | string[];\\n    /**\\n     * Returns the name of the store.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/name)\\n     */\\n    name: string;\\n    /**\\n     * Returns the associated transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/transaction)\\n     */\\n    readonly transaction: IDBTransaction;\\n    /**\\n     * Adds or updates a record in store with the given value and key.\\n     *\\n     * If the store uses in-line keys and key is specified a \\\"DataError\\\" DOMException will be thrown.\\n     *\\n     * If put() is used, any existing record with the key will be replaced. If add() is used, and if a record with the key already exists the request will fail, with request's error set to a \\\"ConstraintError\\\" DOMException.\\n     *\\n     * If successful, request's result will be the record's key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/add)\\n     */\\n    add(value: any, key?: IDBValidKey): IDBRequest<IDBValidKey>;\\n    /**\\n     * Deletes all records in store.\\n     *\\n     * If successful, request's result will be undefined.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/clear)\\n     */\\n    clear(): IDBRequest<undefined>;\\n    /**\\n     * Retrieves the number of records matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the count.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/count)\\n     */\\n    count(query?: IDBValidKey | IDBKeyRange): IDBRequest<number>;\\n    /**\\n     * Creates a new index in store with the given name, keyPath and options and returns a new IDBIndex. If the keyPath and options define constraints that cannot be satisfied with the data already in store the upgrade transaction will abort with a \\\"ConstraintError\\\" DOMException.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/createIndex)\\n     */\\n    createIndex(name: string, keyPath: string | string[], options?: IDBIndexParameters): IDBIndex;\\n    /**\\n     * Deletes records in store with the given key or in the given key range in query.\\n     *\\n     * If successful, request's result will be undefined.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/delete)\\n     */\\n    delete(query: IDBValidKey | IDBKeyRange): IDBRequest<undefined>;\\n    /**\\n     * Deletes the index in store with the given name.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/deleteIndex)\\n     */\\n    deleteIndex(name: string): void;\\n    /**\\n     * Retrieves the value of the first record matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the value, or undefined if there was no matching record.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/get)\\n     */\\n    get(query: IDBValidKey | IDBKeyRange): IDBRequest<any>;\\n    /**\\n     * Retrieves the values of the records matching the given key or key range in query (up to count if given).\\n     *\\n     * If successful, request's result will be an Array of the values.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getAll)\\n     */\\n    getAll(query?: IDBValidKey | IDBKeyRange | null, count?: number): IDBRequest<any[]>;\\n    /**\\n     * Retrieves the keys of records matching the given key or key range in query (up to count if given).\\n     *\\n     * If successful, request's result will be an Array of the keys.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getAllKeys)\\n     */\\n    getAllKeys(query?: IDBValidKey | IDBKeyRange | null, count?: number): IDBRequest<IDBValidKey[]>;\\n    /**\\n     * Retrieves the key of the first record matching the given key or key range in query.\\n     *\\n     * If successful, request's result will be the key, or undefined if there was no matching record.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/getKey)\\n     */\\n    getKey(query: IDBValidKey | IDBKeyRange): IDBRequest<IDBValidKey | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/index) */\\n    index(name: string): IDBIndex;\\n    /**\\n     * Opens a cursor over the records matching query, ordered by direction. If query is null, all records in store are matched.\\n     *\\n     * If successful, request's result will be an IDBCursorWithValue pointing at the first matching record, or null if there were no matching records.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/openCursor)\\n     */\\n    openCursor(query?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection): IDBRequest<IDBCursorWithValue | null>;\\n    /**\\n     * Opens a cursor with key only flag set over the records matching query, ordered by direction. If query is null, all records in store are matched.\\n     *\\n     * If successful, request's result will be an IDBCursor pointing at the first matching record, or null if there were no matching records.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/openKeyCursor)\\n     */\\n    openKeyCursor(query?: IDBValidKey | IDBKeyRange | null, direction?: IDBCursorDirection): IDBRequest<IDBCursor | null>;\\n    /**\\n     * Adds or updates a record in store with the given value and key.\\n     *\\n     * If the store uses in-line keys and key is specified a \\\"DataError\\\" DOMException will be thrown.\\n     *\\n     * If put() is used, any existing record with the key will be replaced. If add() is used, and if a record with the key already exists the request will fail, with request's error set to a \\\"ConstraintError\\\" DOMException.\\n     *\\n     * If successful, request's result will be the record's key.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/put)\\n     */\\n    put(value: any, key?: IDBValidKey): IDBRequest<IDBValidKey>;\\n}\\n\\ndeclare var IDBObjectStore: {\\n    prototype: IDBObjectStore;\\n    new(): IDBObjectStore;\\n};\\n\\ninterface IDBOpenDBRequestEventMap extends IDBRequestEventMap {\\n    \\\"blocked\\\": IDBVersionChangeEvent;\\n    \\\"upgradeneeded\\\": IDBVersionChangeEvent;\\n}\\n\\n/**\\n * Also inherits methods from its parents IDBRequest and EventTarget.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBOpenDBRequest)\\n */\\ninterface IDBOpenDBRequest extends IDBRequest<IDBDatabase> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBOpenDBRequest/blocked_event) */\\n    onblocked: ((this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBOpenDBRequest/upgradeneeded_event) */\\n    onupgradeneeded: ((this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any) | null;\\n    addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var IDBOpenDBRequest: {\\n    prototype: IDBOpenDBRequest;\\n    new(): IDBOpenDBRequest;\\n};\\n\\ninterface IDBRequestEventMap {\\n    \\\"error\\\": Event;\\n    \\\"success\\\": Event;\\n}\\n\\n/**\\n * The request object does not initially contain any information about the result of the operation, but once information becomes available, an event is fired on the request, and the information becomes available through the properties of the IDBRequest instance.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest)\\n */\\ninterface IDBRequest<T = any> extends EventTarget {\\n    /**\\n     * When a request is completed, returns the error (a DOMException), or null if the request succeeded. Throws a \\\"InvalidStateError\\\" DOMException if the request is still pending.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/error)\\n     */\\n    readonly error: DOMException | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/error_event) */\\n    onerror: ((this: IDBRequest<T>, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/success_event) */\\n    onsuccess: ((this: IDBRequest<T>, ev: Event) => any) | null;\\n    /**\\n     * Returns \\\"pending\\\" until a request is complete, then returns \\\"done\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/readyState)\\n     */\\n    readonly readyState: IDBRequestReadyState;\\n    /**\\n     * When a request is completed, returns the result, or undefined if the request failed. Throws a \\\"InvalidStateError\\\" DOMException if the request is still pending.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/result)\\n     */\\n    readonly result: T;\\n    /**\\n     * Returns the IDBObjectStore, IDBIndex, or IDBCursor the request was made against, or null if is was an open request.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/source)\\n     */\\n    readonly source: IDBObjectStore | IDBIndex | IDBCursor;\\n    /**\\n     * Returns the IDBTransaction the request was made within. If this as an open request, then it returns an upgrade transaction while it is running, or null otherwise.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBRequest/transaction)\\n     */\\n    readonly transaction: IDBTransaction | null;\\n    addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest<T>, ev: IDBRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest<T>, ev: IDBRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var IDBRequest: {\\n    prototype: IDBRequest;\\n    new(): IDBRequest;\\n};\\n\\ninterface IDBTransactionEventMap {\\n    \\\"abort\\\": Event;\\n    \\\"complete\\\": Event;\\n    \\\"error\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction) */\\ninterface IDBTransaction extends EventTarget {\\n    /**\\n     * Returns the transaction's connection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/db)\\n     */\\n    readonly db: IDBDatabase;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/durability) */\\n    readonly durability: IDBTransactionDurability;\\n    /**\\n     * If the transaction was aborted, returns the error (a DOMException) providing the reason.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/error)\\n     */\\n    readonly error: DOMException | null;\\n    /**\\n     * Returns the mode the transaction was created with (\\\"readonly\\\" or \\\"readwrite\\\"), or \\\"versionchange\\\" for an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/mode)\\n     */\\n    readonly mode: IDBTransactionMode;\\n    /**\\n     * Returns a list of the names of object stores in the transaction's scope. For an upgrade transaction this is all object stores in the database.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/objectStoreNames)\\n     */\\n    readonly objectStoreNames: DOMStringList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/abort_event) */\\n    onabort: ((this: IDBTransaction, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/complete_event) */\\n    oncomplete: ((this: IDBTransaction, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/error_event) */\\n    onerror: ((this: IDBTransaction, ev: Event) => any) | null;\\n    /**\\n     * Aborts the transaction. All pending requests will fail with a \\\"AbortError\\\" DOMException and all changes made to the database will be reverted.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/abort)\\n     */\\n    abort(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/commit) */\\n    commit(): void;\\n    /**\\n     * Returns an IDBObjectStore in the transaction's scope.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBTransaction/objectStore)\\n     */\\n    objectStore(name: string): IDBObjectStore;\\n    addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var IDBTransaction: {\\n    prototype: IDBTransaction;\\n    new(): IDBTransaction;\\n};\\n\\n/**\\n * This IndexedDB API interface indicates that the version of the database has changed, as the result of an IDBOpenDBRequest.onupgradeneeded event handler function.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBVersionChangeEvent)\\n */\\ninterface IDBVersionChangeEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBVersionChangeEvent/newVersion) */\\n    readonly newVersion: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBVersionChangeEvent/oldVersion) */\\n    readonly oldVersion: number;\\n}\\n\\ndeclare var IDBVersionChangeEvent: {\\n    prototype: IDBVersionChangeEvent;\\n    new(type: string, eventInitDict?: IDBVersionChangeEventInit): IDBVersionChangeEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmap) */\\ninterface ImageBitmap {\\n    /**\\n     * Returns the intrinsic height of the image, in CSS pixels.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmap/height)\\n     */\\n    readonly height: number;\\n    /**\\n     * Returns the intrinsic width of the image, in CSS pixels.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmap/width)\\n     */\\n    readonly width: number;\\n    /**\\n     * Releases imageBitmap's underlying bitmap data.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmap/close)\\n     */\\n    close(): void;\\n}\\n\\ndeclare var ImageBitmap: {\\n    prototype: ImageBitmap;\\n    new(): ImageBitmap;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmapRenderingContext) */\\ninterface ImageBitmapRenderingContext {\\n    /**\\n     * Transfers the underlying bitmap data from imageBitmap to context, and the bitmap becomes the contents of the canvas element to which context is bound.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageBitmapRenderingContext/transferFromImageBitmap)\\n     */\\n    transferFromImageBitmap(bitmap: ImageBitmap | null): void;\\n}\\n\\ndeclare var ImageBitmapRenderingContext: {\\n    prototype: ImageBitmapRenderingContext;\\n    new(): ImageBitmapRenderingContext;\\n};\\n\\n/**\\n * The underlying pixel data of an area of a <canvas> element. It is created using the ImageData() constructor or creator methods on the CanvasRenderingContext2D object associated with a canvas: createImageData() and getImageData(). It can also be used to set a part of the canvas by using putImageData().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData)\\n */\\ninterface ImageData {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData/colorSpace) */\\n    readonly colorSpace: PredefinedColorSpace;\\n    /**\\n     * Returns the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData/data)\\n     */\\n    readonly data: Uint8ClampedArray;\\n    /**\\n     * Returns the actual dimensions of the data in the ImageData object, in pixels.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData/height)\\n     */\\n    readonly height: number;\\n    /**\\n     * Returns the actual dimensions of the data in the ImageData object, in pixels.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ImageData/width)\\n     */\\n    readonly width: number;\\n}\\n\\ndeclare var ImageData: {\\n    prototype: ImageData;\\n    new(sw: number, sh: number, settings?: ImageDataSettings): ImageData;\\n    new(data: Uint8ClampedArray, sw: number, sh?: number, settings?: ImageDataSettings): ImageData;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/KHR_parallel_shader_compile) */\\ninterface KHR_parallel_shader_compile {\\n    readonly COMPLETION_STATUS_KHR: 0x91B1;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Lock)\\n */\\ninterface Lock {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Lock/mode) */\\n    readonly mode: LockMode;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Lock/name) */\\n    readonly name: string;\\n}\\n\\ndeclare var Lock: {\\n    prototype: Lock;\\n    new(): Lock;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/LockManager)\\n */\\ninterface LockManager {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LockManager/query) */\\n    query(): Promise<LockManagerSnapshot>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LockManager/request) */\\n    request(name: string, callback: LockGrantedCallback): Promise<any>;\\n    request(name: string, options: LockOptions, callback: LockGrantedCallback): Promise<any>;\\n}\\n\\ndeclare var LockManager: {\\n    prototype: LockManager;\\n    new(): LockManager;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaCapabilities) */\\ninterface MediaCapabilities {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaCapabilities/decodingInfo) */\\n    decodingInfo(configuration: MediaDecodingConfiguration): Promise<MediaCapabilitiesDecodingInfo>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MediaCapabilities/encodingInfo) */\\n    encodingInfo(configuration: MediaEncodingConfiguration): Promise<MediaCapabilitiesEncodingInfo>;\\n}\\n\\ndeclare var MediaCapabilities: {\\n    prototype: MediaCapabilities;\\n    new(): MediaCapabilities;\\n};\\n\\n/**\\n * This Channel Messaging API interface allows us to create a new message channel and send data through it via its two MessagePort properties.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageChannel)\\n */\\ninterface MessageChannel {\\n    /**\\n     * Returns the first MessagePort object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageChannel/port1)\\n     */\\n    readonly port1: MessagePort;\\n    /**\\n     * Returns the second MessagePort object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageChannel/port2)\\n     */\\n    readonly port2: MessagePort;\\n}\\n\\ndeclare var MessageChannel: {\\n    prototype: MessageChannel;\\n    new(): MessageChannel;\\n};\\n\\n/**\\n * A message received by a target object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent)\\n */\\ninterface MessageEvent<T = any> extends Event {\\n    /**\\n     * Returns the data of the message.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/data)\\n     */\\n    readonly data: T;\\n    /**\\n     * Returns the last event ID string, for server-sent events.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/lastEventId)\\n     */\\n    readonly lastEventId: string;\\n    /**\\n     * Returns the origin of the message, for server-sent events and cross-document messaging.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/origin)\\n     */\\n    readonly origin: string;\\n    /**\\n     * Returns the MessagePort array sent with the message, for cross-document messaging and channel messaging.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/ports)\\n     */\\n    readonly ports: ReadonlyArray<MessagePort>;\\n    /**\\n     * Returns the WindowProxy of the source window, for cross-document messaging, and the MessagePort being attached, in the connect event fired at SharedWorkerGlobalScope objects.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/source)\\n     */\\n    readonly source: MessageEventSource | null;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/initMessageEvent)\\n     */\\n    initMessageEvent(type: string, bubbles?: boolean, cancelable?: boolean, data?: any, origin?: string, lastEventId?: string, source?: MessageEventSource | null, ports?: MessagePort[]): void;\\n}\\n\\ndeclare var MessageEvent: {\\n    prototype: MessageEvent;\\n    new<T>(type: string, eventInitDict?: MessageEventInit<T>): MessageEvent<T>;\\n};\\n\\ninterface MessagePortEventMap {\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/**\\n * This Channel Messaging API interface represents one of the two ports of a MessageChannel, allowing messages to be sent from one port and listening out for them arriving at the other.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort)\\n */\\ninterface MessagePort extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/message_event) */\\n    onmessage: ((this: MessagePort, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/messageerror_event) */\\n    onmessageerror: ((this: MessagePort, ev: MessageEvent) => any) | null;\\n    /**\\n     * Disconnects the port, so that it is no longer active.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/close)\\n     */\\n    close(): void;\\n    /**\\n     * Posts a message through the channel. Objects listed in transfer are transferred, not just cloned, meaning that they are no longer usable on the sending side.\\n     *\\n     * Throws a \\\"DataCloneError\\\" DOMException if transfer contains duplicate objects or port, or if message could not be cloned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/postMessage)\\n     */\\n    postMessage(message: any, transfer: Transferable[]): void;\\n    postMessage(message: any, options?: StructuredSerializeOptions): void;\\n    /**\\n     * Begins dispatching messages received on the port.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessagePort/start)\\n     */\\n    start(): void;\\n    addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var MessagePort: {\\n    prototype: MessagePort;\\n    new(): MessagePort;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager)\\n */\\ninterface NavigationPreloadManager {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager/disable) */\\n    disable(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager/enable) */\\n    enable(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager/getState) */\\n    getState(): Promise<NavigationPreloadState>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NavigationPreloadManager/setHeaderValue) */\\n    setHeaderValue(value: string): Promise<void>;\\n}\\n\\ndeclare var NavigationPreloadManager: {\\n    prototype: NavigationPreloadManager;\\n    new(): NavigationPreloadManager;\\n};\\n\\n/** Available only in secure contexts. */\\ninterface NavigatorBadge {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/clearAppBadge) */\\n    clearAppBadge(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/setAppBadge) */\\n    setAppBadge(contents?: number): Promise<void>;\\n}\\n\\ninterface NavigatorConcurrentHardware {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/hardwareConcurrency) */\\n    readonly hardwareConcurrency: number;\\n}\\n\\ninterface NavigatorID {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/appCodeName)\\n     */\\n    readonly appCodeName: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/appName)\\n     */\\n    readonly appName: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/appVersion)\\n     */\\n    readonly appVersion: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/platform)\\n     */\\n    readonly platform: string;\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/product)\\n     */\\n    readonly product: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/userAgent) */\\n    readonly userAgent: string;\\n}\\n\\ninterface NavigatorLanguage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/language) */\\n    readonly language: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/languages) */\\n    readonly languages: ReadonlyArray<string>;\\n}\\n\\n/** Available only in secure contexts. */\\ninterface NavigatorLocks {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/locks) */\\n    readonly locks: LockManager;\\n}\\n\\ninterface NavigatorOnLine {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/onLine) */\\n    readonly onLine: boolean;\\n}\\n\\n/** Available only in secure contexts. */\\ninterface NavigatorStorage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Navigator/storage) */\\n    readonly storage: StorageManager;\\n}\\n\\ninterface NotificationEventMap {\\n    \\\"click\\\": Event;\\n    \\\"close\\\": Event;\\n    \\\"error\\\": Event;\\n    \\\"show\\\": Event;\\n}\\n\\n/**\\n * This Notifications API interface is used to configure and display desktop notifications to the user.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification)\\n */\\ninterface Notification extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/body) */\\n    readonly body: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/data) */\\n    readonly data: any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/dir) */\\n    readonly dir: NotificationDirection;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/icon) */\\n    readonly icon: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/lang) */\\n    readonly lang: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/click_event) */\\n    onclick: ((this: Notification, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/close_event) */\\n    onclose: ((this: Notification, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/error_event) */\\n    onerror: ((this: Notification, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/show_event) */\\n    onshow: ((this: Notification, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/silent) */\\n    readonly silent: boolean | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/tag) */\\n    readonly tag: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/title) */\\n    readonly title: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/close) */\\n    close(): void;\\n    addEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Notification: {\\n    prototype: Notification;\\n    new(title: string, options?: NotificationOptions): Notification;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Notification/permission_static) */\\n    readonly permission: NotificationPermission;\\n};\\n\\n/**\\n * The parameter passed into the onnotificationclick handler, the NotificationEvent interface represents a notification click event that is dispatched on the ServiceWorkerGlobalScope of a ServiceWorker.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/NotificationEvent)\\n */\\ninterface NotificationEvent extends ExtendableEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NotificationEvent/action) */\\n    readonly action: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/NotificationEvent/notification) */\\n    readonly notification: Notification;\\n}\\n\\ndeclare var NotificationEvent: {\\n    prototype: NotificationEvent;\\n    new(type: string, eventInitDict: NotificationEventInit): NotificationEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed) */\\ninterface OES_draw_buffers_indexed {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/blendEquationSeparateiOES) */\\n    blendEquationSeparateiOES(buf: GLuint, modeRGB: GLenum, modeAlpha: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/blendEquationiOES) */\\n    blendEquationiOES(buf: GLuint, mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/blendFuncSeparateiOES) */\\n    blendFuncSeparateiOES(buf: GLuint, srcRGB: GLenum, dstRGB: GLenum, srcAlpha: GLenum, dstAlpha: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/blendFunciOES) */\\n    blendFunciOES(buf: GLuint, src: GLenum, dst: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/colorMaskiOES) */\\n    colorMaskiOES(buf: GLuint, r: GLboolean, g: GLboolean, b: GLboolean, a: GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/disableiOES) */\\n    disableiOES(target: GLenum, index: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_draw_buffers_indexed/enableiOES) */\\n    enableiOES(target: GLenum, index: GLuint): void;\\n}\\n\\n/**\\n * The OES_element_index_uint extension is part of the WebGL API and adds support for gl.UNSIGNED_INT types to WebGLRenderingContext.drawElements().\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_element_index_uint)\\n */\\ninterface OES_element_index_uint {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_fbo_render_mipmap) */\\ninterface OES_fbo_render_mipmap {\\n}\\n\\n/**\\n * The OES_standard_derivatives extension is part of the WebGL API and adds the GLSL derivative functions dFdx, dFdy, and fwidth.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_standard_derivatives)\\n */\\ninterface OES_standard_derivatives {\\n    readonly FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 0x8B8B;\\n}\\n\\n/**\\n * The OES_texture_float extension is part of the WebGL API and exposes floating-point pixel types for textures.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_texture_float)\\n */\\ninterface OES_texture_float {\\n}\\n\\n/**\\n * The OES_texture_float_linear extension is part of the WebGL API and allows linear filtering with floating-point pixel types for textures.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_texture_float_linear)\\n */\\ninterface OES_texture_float_linear {\\n}\\n\\n/**\\n * The OES_texture_half_float extension is part of the WebGL API and adds texture formats with 16- (aka half float) and 32-bit floating-point components.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_texture_half_float)\\n */\\ninterface OES_texture_half_float {\\n    readonly HALF_FLOAT_OES: 0x8D61;\\n}\\n\\n/**\\n * The OES_texture_half_float_linear extension is part of the WebGL API and allows linear filtering with half floating-point pixel types for textures.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_texture_half_float_linear)\\n */\\ninterface OES_texture_half_float_linear {\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object) */\\ninterface OES_vertex_array_object {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object/bindVertexArrayOES) */\\n    bindVertexArrayOES(arrayObject: WebGLVertexArrayObjectOES | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object/createVertexArrayOES) */\\n    createVertexArrayOES(): WebGLVertexArrayObjectOES | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object/deleteVertexArrayOES) */\\n    deleteVertexArrayOES(arrayObject: WebGLVertexArrayObjectOES | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object/isVertexArrayOES) */\\n    isVertexArrayOES(arrayObject: WebGLVertexArrayObjectOES | null): GLboolean;\\n    readonly VERTEX_ARRAY_BINDING_OES: 0x85B5;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OVR_multiview2) */\\ninterface OVR_multiview2 {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OVR_multiview2/framebufferTextureMultiviewOVR) */\\n    framebufferTextureMultiviewOVR(target: GLenum, attachment: GLenum, texture: WebGLTexture | null, level: GLint, baseViewIndex: GLint, numViews: GLsizei): void;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: 0x9630;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR: 0x9632;\\n    readonly MAX_VIEWS_OVR: 0x9631;\\n    readonly FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR: 0x9633;\\n}\\n\\ninterface OffscreenCanvasEventMap {\\n    \\\"contextlost\\\": Event;\\n    \\\"contextrestored\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas) */\\ninterface OffscreenCanvas extends EventTarget {\\n    /**\\n     * These attributes return the dimensions of the OffscreenCanvas object's bitmap.\\n     *\\n     * They can be set, to replace the bitmap with a new, transparent black bitmap of the specified dimensions (effectively resizing it).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/height)\\n     */\\n    height: number;\\n    oncontextlost: ((this: OffscreenCanvas, ev: Event) => any) | null;\\n    oncontextrestored: ((this: OffscreenCanvas, ev: Event) => any) | null;\\n    /**\\n     * These attributes return the dimensions of the OffscreenCanvas object's bitmap.\\n     *\\n     * They can be set, to replace the bitmap with a new, transparent black bitmap of the specified dimensions (effectively resizing it).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/width)\\n     */\\n    width: number;\\n    /**\\n     * Returns a promise that will fulfill with a new Blob object representing a file containing the image in the OffscreenCanvas object.\\n     *\\n     * The argument, if provided, is a dictionary that controls the encoding options of the image file to be created. The type field specifies the file format and has a default value of \\\"image/png\\\"; that type is also used if the requested type isn't supported. If the image format supports variable quality (such as \\\"image/jpeg\\\"), then the quality field is a number in the range 0.0 to 1.0 inclusive indicating the desired quality level for the resulting image.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/convertToBlob)\\n     */\\n    convertToBlob(options?: ImageEncodeOptions): Promise<Blob>;\\n    /**\\n     * Returns an object that exposes an API for drawing on the OffscreenCanvas object. contextId specifies the desired API: \\\"2d\\\", \\\"bitmaprenderer\\\", \\\"webgl\\\", or \\\"webgl2\\\". options is handled by that API.\\n     *\\n     * This specification defines the \\\"2d\\\" context below, which is similar but distinct from the \\\"2d\\\" context that is created from a canvas element. The WebGL specifications define the \\\"webgl\\\" and \\\"webgl2\\\" contexts. [WEBGL]\\n     *\\n     * Returns null if the canvas has already been initialized with another context type (e.g., trying to get a \\\"2d\\\" context after getting a \\\"webgl\\\" context).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/getContext)\\n     */\\n    getContext(contextId: \\\"2d\\\", options?: any): OffscreenCanvasRenderingContext2D | null;\\n    getContext(contextId: \\\"bitmaprenderer\\\", options?: any): ImageBitmapRenderingContext | null;\\n    getContext(contextId: \\\"webgl\\\", options?: any): WebGLRenderingContext | null;\\n    getContext(contextId: \\\"webgl2\\\", options?: any): WebGL2RenderingContext | null;\\n    getContext(contextId: OffscreenRenderingContextId, options?: any): OffscreenRenderingContext | null;\\n    /**\\n     * Returns a newly created ImageBitmap object with the image in the OffscreenCanvas object. The image in the OffscreenCanvas object is replaced with a new blank image.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvas/transferToImageBitmap)\\n     */\\n    transferToImageBitmap(): ImageBitmap;\\n    addEventListener<K extends keyof OffscreenCanvasEventMap>(type: K, listener: (this: OffscreenCanvas, ev: OffscreenCanvasEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof OffscreenCanvasEventMap>(type: K, listener: (this: OffscreenCanvas, ev: OffscreenCanvasEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var OffscreenCanvas: {\\n    prototype: OffscreenCanvas;\\n    new(width: number, height: number): OffscreenCanvas;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvasRenderingContext2D) */\\ninterface OffscreenCanvasRenderingContext2D extends CanvasCompositing, CanvasDrawImage, CanvasDrawPath, CanvasFillStrokeStyles, CanvasFilters, CanvasImageData, CanvasImageSmoothing, CanvasPath, CanvasPathDrawingStyles, CanvasRect, CanvasShadowStyles, CanvasState, CanvasText, CanvasTextDrawingStyles, CanvasTransform {\\n    readonly canvas: OffscreenCanvas;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/OffscreenCanvasRenderingContext2D/commit) */\\n    commit(): void;\\n}\\n\\ndeclare var OffscreenCanvasRenderingContext2D: {\\n    prototype: OffscreenCanvasRenderingContext2D;\\n    new(): OffscreenCanvasRenderingContext2D;\\n};\\n\\n/**\\n * This Canvas 2D API interface is used to declare a path that can then be used on a CanvasRenderingContext2D object. The path methods of the CanvasRenderingContext2D interface are also present on this interface, which gives you the convenience of being able to retain and replay your path whenever desired.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Path2D)\\n */\\ninterface Path2D extends CanvasPath {\\n    /**\\n     * Adds to the path the path given by the argument.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Path2D/addPath)\\n     */\\n    addPath(path: Path2D, transform?: DOMMatrix2DInit): void;\\n}\\n\\ndeclare var Path2D: {\\n    prototype: Path2D;\\n    new(path?: Path2D | string): Path2D;\\n};\\n\\ninterface PerformanceEventMap {\\n    \\\"resourcetimingbufferfull\\\": Event;\\n}\\n\\n/**\\n * Provides access to performance-related information for the current page. It's part of the High Resolution Time API, but is enhanced by the Performance Timeline API, the Navigation Timing API, the User Timing API, and the Resource Timing API.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance)\\n */\\ninterface Performance extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/resourcetimingbufferfull_event) */\\n    onresourcetimingbufferfull: ((this: Performance, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/timeOrigin) */\\n    readonly timeOrigin: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/clearMarks) */\\n    clearMarks(markName?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/clearMeasures) */\\n    clearMeasures(measureName?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/clearResourceTimings) */\\n    clearResourceTimings(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/getEntries) */\\n    getEntries(): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/getEntriesByName) */\\n    getEntriesByName(name: string, type?: string): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/getEntriesByType) */\\n    getEntriesByType(type: string): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/mark) */\\n    mark(markName: string, markOptions?: PerformanceMarkOptions): PerformanceMark;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/measure) */\\n    measure(measureName: string, startOrMeasureOptions?: string | PerformanceMeasureOptions, endMark?: string): PerformanceMeasure;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/now) */\\n    now(): DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/setResourceTimingBufferSize) */\\n    setResourceTimingBufferSize(maxSize: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Performance/toJSON) */\\n    toJSON(): any;\\n    addEventListener<K extends keyof PerformanceEventMap>(type: K, listener: (this: Performance, ev: PerformanceEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof PerformanceEventMap>(type: K, listener: (this: Performance, ev: PerformanceEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Performance: {\\n    prototype: Performance;\\n    new(): Performance;\\n};\\n\\n/**\\n * Encapsulates a single performance metric that is part of the performance timeline. A performance entry can be directly created by making a performance mark or measure (for example by calling the mark() method) at an explicit point in an application. Performance entries are also created in indirect ways such as loading a resource (such as an image).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry)\\n */\\ninterface PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/duration) */\\n    readonly duration: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/entryType) */\\n    readonly entryType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/startTime) */\\n    readonly startTime: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceEntry/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PerformanceEntry: {\\n    prototype: PerformanceEntry;\\n    new(): PerformanceEntry;\\n};\\n\\n/**\\n * PerformanceMark is an abstract interface for PerformanceEntry objects with an entryType of \\\"mark\\\". Entries of this type are created by calling performance.mark() to add a named DOMHighResTimeStamp (the mark) to the browser's performance timeline.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMark)\\n */\\ninterface PerformanceMark extends PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMark/detail) */\\n    readonly detail: any;\\n}\\n\\ndeclare var PerformanceMark: {\\n    prototype: PerformanceMark;\\n    new(markName: string, markOptions?: PerformanceMarkOptions): PerformanceMark;\\n};\\n\\n/**\\n * PerformanceMeasure is an abstract interface for PerformanceEntry objects with an entryType of \\\"measure\\\". Entries of this type are created by calling performance.measure() to add a named DOMHighResTimeStamp (the measure) between two marks to the browser's performance timeline.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMeasure)\\n */\\ninterface PerformanceMeasure extends PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceMeasure/detail) */\\n    readonly detail: any;\\n}\\n\\ndeclare var PerformanceMeasure: {\\n    prototype: PerformanceMeasure;\\n    new(): PerformanceMeasure;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver) */\\ninterface PerformanceObserver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver/disconnect) */\\n    disconnect(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver/observe) */\\n    observe(options?: PerformanceObserverInit): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver/takeRecords) */\\n    takeRecords(): PerformanceEntryList;\\n}\\n\\ndeclare var PerformanceObserver: {\\n    prototype: PerformanceObserver;\\n    new(callback: PerformanceObserverCallback): PerformanceObserver;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserver/supportedEntryTypes_static) */\\n    readonly supportedEntryTypes: ReadonlyArray<string>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserverEntryList) */\\ninterface PerformanceObserverEntryList {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserverEntryList/getEntries) */\\n    getEntries(): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserverEntryList/getEntriesByName) */\\n    getEntriesByName(name: string, type?: string): PerformanceEntryList;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceObserverEntryList/getEntriesByType) */\\n    getEntriesByType(type: string): PerformanceEntryList;\\n}\\n\\ndeclare var PerformanceObserverEntryList: {\\n    prototype: PerformanceObserverEntryList;\\n    new(): PerformanceObserverEntryList;\\n};\\n\\n/**\\n * Enables retrieval and analysis of detailed network timing data regarding the loading of an application's resources. An application can use the timing metrics to determine, for example, the length of time it takes to fetch a specific resource, such as an XMLHttpRequest, <SVG>, image, or script.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming)\\n */\\ninterface PerformanceResourceTiming extends PerformanceEntry {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/connectEnd) */\\n    readonly connectEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/connectStart) */\\n    readonly connectStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/decodedBodySize) */\\n    readonly decodedBodySize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/domainLookupEnd) */\\n    readonly domainLookupEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/domainLookupStart) */\\n    readonly domainLookupStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/encodedBodySize) */\\n    readonly encodedBodySize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/fetchStart) */\\n    readonly fetchStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/initiatorType) */\\n    readonly initiatorType: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/nextHopProtocol) */\\n    readonly nextHopProtocol: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/redirectEnd) */\\n    readonly redirectEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/redirectStart) */\\n    readonly redirectStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/requestStart) */\\n    readonly requestStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/responseEnd) */\\n    readonly responseEnd: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/responseStart) */\\n    readonly responseStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/secureConnectionStart) */\\n    readonly secureConnectionStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/serverTiming) */\\n    readonly serverTiming: ReadonlyArray<PerformanceServerTiming>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/transferSize) */\\n    readonly transferSize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/workerStart) */\\n    readonly workerStart: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceResourceTiming/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PerformanceResourceTiming: {\\n    prototype: PerformanceResourceTiming;\\n    new(): PerformanceResourceTiming;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming) */\\ninterface PerformanceServerTiming {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming/description) */\\n    readonly description: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming/duration) */\\n    readonly duration: DOMHighResTimeStamp;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PerformanceServerTiming/toJSON) */\\n    toJSON(): any;\\n}\\n\\ndeclare var PerformanceServerTiming: {\\n    prototype: PerformanceServerTiming;\\n    new(): PerformanceServerTiming;\\n};\\n\\ninterface PermissionStatusEventMap {\\n    \\\"change\\\": Event;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PermissionStatus) */\\ninterface PermissionStatus extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PermissionStatus/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PermissionStatus/change_event) */\\n    onchange: ((this: PermissionStatus, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PermissionStatus/state) */\\n    readonly state: PermissionState;\\n    addEventListener<K extends keyof PermissionStatusEventMap>(type: K, listener: (this: PermissionStatus, ev: PermissionStatusEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof PermissionStatusEventMap>(type: K, listener: (this: PermissionStatus, ev: PermissionStatusEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var PermissionStatus: {\\n    prototype: PermissionStatus;\\n    new(): PermissionStatus;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Permissions) */\\ninterface Permissions {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Permissions/query) */\\n    query(permissionDesc: PermissionDescriptor): Promise<PermissionStatus>;\\n}\\n\\ndeclare var Permissions: {\\n    prototype: Permissions;\\n    new(): Permissions;\\n};\\n\\n/**\\n * Events measuring progress of an underlying process, like an HTTP request (for an XMLHttpRequest, or the loading of the underlying resource of an <img>, <audio>, <video>, <style> or <link>).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent)\\n */\\ninterface ProgressEvent<T extends EventTarget = EventTarget> extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/lengthComputable) */\\n    readonly lengthComputable: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/loaded) */\\n    readonly loaded: number;\\n    readonly target: T | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ProgressEvent/total) */\\n    readonly total: number;\\n}\\n\\ndeclare var ProgressEvent: {\\n    prototype: ProgressEvent;\\n    new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent) */\\ninterface PromiseRejectionEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent/promise) */\\n    readonly promise: Promise<any>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PromiseRejectionEvent/reason) */\\n    readonly reason: any;\\n}\\n\\ndeclare var PromiseRejectionEvent: {\\n    prototype: PromiseRejectionEvent;\\n    new(type: string, eventInitDict: PromiseRejectionEventInit): PromiseRejectionEvent;\\n};\\n\\n/**\\n * This Push API interface represents a push message that has been received. This event is sent to the global scope of a ServiceWorker. It contains the information sent from an application server to a PushSubscription.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushEvent)\\n */\\ninterface PushEvent extends ExtendableEvent {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushEvent/data) */\\n    readonly data: PushMessageData | null;\\n}\\n\\ndeclare var PushEvent: {\\n    prototype: PushEvent;\\n    new(type: string, eventInitDict?: PushEventInit): PushEvent;\\n};\\n\\n/**\\n * This Push API interface provides a way to receive notifications from third-party servers as well as request URLs for push notifications.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager)\\n */\\ninterface PushManager {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager/getSubscription) */\\n    getSubscription(): Promise<PushSubscription | null>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager/permissionState) */\\n    permissionState(options?: PushSubscriptionOptionsInit): Promise<PermissionState>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager/subscribe) */\\n    subscribe(options?: PushSubscriptionOptionsInit): Promise<PushSubscription>;\\n}\\n\\ndeclare var PushManager: {\\n    prototype: PushManager;\\n    new(): PushManager;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushManager/supportedContentEncodings_static) */\\n    readonly supportedContentEncodings: ReadonlyArray<string>;\\n};\\n\\n/**\\n * This Push API interface provides methods which let you retrieve the push data sent by a server in various formats.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushMessageData)\\n */\\ninterface PushMessageData {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushMessageData/arrayBuffer) */\\n    arrayBuffer(): ArrayBuffer;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushMessageData/blob) */\\n    blob(): Blob;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushMessageData/json) */\\n    json(): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushMessageData/text) */\\n    text(): string;\\n}\\n\\ndeclare var PushMessageData: {\\n    prototype: PushMessageData;\\n    new(): PushMessageData;\\n};\\n\\n/**\\n * This Push API interface provides a subcription's URL endpoint and allows unsubscription from a push service.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription)\\n */\\ninterface PushSubscription {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/endpoint) */\\n    readonly endpoint: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/expirationTime) */\\n    readonly expirationTime: EpochTimeStamp | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/options) */\\n    readonly options: PushSubscriptionOptions;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/getKey) */\\n    getKey(name: PushEncryptionKeyName): ArrayBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/toJSON) */\\n    toJSON(): PushSubscriptionJSON;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscription/unsubscribe) */\\n    unsubscribe(): Promise<boolean>;\\n}\\n\\ndeclare var PushSubscription: {\\n    prototype: PushSubscription;\\n    new(): PushSubscription;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscriptionOptions)\\n */\\ninterface PushSubscriptionOptions {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscriptionOptions/applicationServerKey) */\\n    readonly applicationServerKey: ArrayBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/PushSubscriptionOptions/userVisibleOnly) */\\n    readonly userVisibleOnly: boolean;\\n}\\n\\ndeclare var PushSubscriptionOptions: {\\n    prototype: PushSubscriptionOptions;\\n    new(): PushSubscriptionOptions;\\n};\\n\\ninterface RTCEncodedAudioFrame {\\n    data: ArrayBuffer;\\n    readonly timestamp: number;\\n    getMetadata(): RTCEncodedAudioFrameMetadata;\\n}\\n\\ndeclare var RTCEncodedAudioFrame: {\\n    prototype: RTCEncodedAudioFrame;\\n    new(): RTCEncodedAudioFrame;\\n};\\n\\ninterface RTCEncodedVideoFrame {\\n    data: ArrayBuffer;\\n    readonly timestamp: number;\\n    readonly type: RTCEncodedVideoFrameType;\\n    getMetadata(): RTCEncodedVideoFrameMetadata;\\n}\\n\\ndeclare var RTCEncodedVideoFrame: {\\n    prototype: RTCEncodedVideoFrame;\\n    new(): RTCEncodedVideoFrame;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController) */\\ninterface ReadableByteStreamController {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/byobRequest) */\\n    readonly byobRequest: ReadableStreamBYOBRequest | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/desiredSize) */\\n    readonly desiredSize: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/enqueue) */\\n    enqueue(chunk: ArrayBufferView): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableByteStreamController/error) */\\n    error(e?: any): void;\\n}\\n\\ndeclare var ReadableByteStreamController: {\\n    prototype: ReadableByteStreamController;\\n    new(): ReadableByteStreamController;\\n};\\n\\n/**\\n * This Streams API interface represents a readable stream of byte data. The Fetch API offers a concrete instance of a ReadableStream through the body property of a Response object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream)\\n */\\ninterface ReadableStream<R = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/locked) */\\n    readonly locked: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/cancel) */\\n    cancel(reason?: any): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/getReader) */\\n    getReader(options: { mode: \\\"byob\\\" }): ReadableStreamBYOBReader;\\n    getReader(): ReadableStreamDefaultReader<R>;\\n    getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader<R>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/pipeThrough) */\\n    pipeThrough<T>(transform: ReadableWritablePair<T, R>, options?: StreamPipeOptions): ReadableStream<T>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/pipeTo) */\\n    pipeTo(destination: WritableStream<R>, options?: StreamPipeOptions): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStream/tee) */\\n    tee(): [ReadableStream<R>, ReadableStream<R>];\\n}\\n\\ndeclare var ReadableStream: {\\n    prototype: ReadableStream;\\n    new(underlyingSource: UnderlyingByteSource, strategy?: { highWaterMark?: number }): ReadableStream<Uint8Array>;\\n    new<R = any>(underlyingSource: UnderlyingDefaultSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;\\n    new<R = any>(underlyingSource?: UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader) */\\ninterface ReadableStreamBYOBReader extends ReadableStreamGenericReader {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/read) */\\n    read<T extends ArrayBufferView>(view: T): Promise<ReadableStreamReadResult<T>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/releaseLock) */\\n    releaseLock(): void;\\n}\\n\\ndeclare var ReadableStreamBYOBReader: {\\n    prototype: ReadableStreamBYOBReader;\\n    new(stream: ReadableStream): ReadableStreamBYOBReader;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest) */\\ninterface ReadableStreamBYOBRequest {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/view) */\\n    readonly view: ArrayBufferView | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/respond) */\\n    respond(bytesWritten: number): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/respondWithNewView) */\\n    respondWithNewView(view: ArrayBufferView): void;\\n}\\n\\ndeclare var ReadableStreamBYOBRequest: {\\n    prototype: ReadableStreamBYOBRequest;\\n    new(): ReadableStreamBYOBRequest;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController) */\\ninterface ReadableStreamDefaultController<R = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController/desiredSize) */\\n    readonly desiredSize: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController/enqueue) */\\n    enqueue(chunk?: R): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultController/error) */\\n    error(e?: any): void;\\n}\\n\\ndeclare var ReadableStreamDefaultController: {\\n    prototype: ReadableStreamDefaultController;\\n    new(): ReadableStreamDefaultController;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultReader) */\\ninterface ReadableStreamDefaultReader<R = any> extends ReadableStreamGenericReader {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultReader/read) */\\n    read(): Promise<ReadableStreamReadResult<R>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamDefaultReader/releaseLock) */\\n    releaseLock(): void;\\n}\\n\\ndeclare var ReadableStreamDefaultReader: {\\n    prototype: ReadableStreamDefaultReader;\\n    new<R = any>(stream: ReadableStream<R>): ReadableStreamDefaultReader<R>;\\n};\\n\\ninterface ReadableStreamGenericReader {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/closed) */\\n    readonly closed: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/cancel) */\\n    cancel(reason?: any): Promise<void>;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Report) */\\ninterface Report {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Report/body) */\\n    readonly body: ReportBody | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Report/type) */\\n    readonly type: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Report/url) */\\n    readonly url: string;\\n    toJSON(): any;\\n}\\n\\ndeclare var Report: {\\n    prototype: Report;\\n    new(): Report;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportBody) */\\ninterface ReportBody {\\n    toJSON(): any;\\n}\\n\\ndeclare var ReportBody: {\\n    prototype: ReportBody;\\n    new(): ReportBody;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportingObserver) */\\ninterface ReportingObserver {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportingObserver/disconnect) */\\n    disconnect(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportingObserver/observe) */\\n    observe(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReportingObserver/takeRecords) */\\n    takeRecords(): ReportList;\\n}\\n\\ndeclare var ReportingObserver: {\\n    prototype: ReportingObserver;\\n    new(callback: ReportingObserverCallback, options?: ReportingObserverOptions): ReportingObserver;\\n};\\n\\n/**\\n * This Fetch API interface represents a resource request.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request)\\n */\\ninterface Request extends Body {\\n    /**\\n     * Returns the cache mode associated with request, which is a string indicating how the request will interact with the browser's cache when fetching.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/cache)\\n     */\\n    readonly cache: RequestCache;\\n    /**\\n     * Returns the credentials mode associated with request, which is a string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/credentials)\\n     */\\n    readonly credentials: RequestCredentials;\\n    /**\\n     * Returns the kind of resource requested by request, e.g., \\\"document\\\" or \\\"script\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/destination)\\n     */\\n    readonly destination: RequestDestination;\\n    /**\\n     * Returns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the \\\"Host\\\" header.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/headers)\\n     */\\n    readonly headers: Headers;\\n    /**\\n     * Returns request's subresource integrity metadata, which is a cryptographic hash of the resource being fetched. Its value consists of multiple hashes separated by whitespace. [SRI]\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/integrity)\\n     */\\n    readonly integrity: string;\\n    /**\\n     * Returns a boolean indicating whether or not request can outlive the global in which it was created.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/keepalive)\\n     */\\n    readonly keepalive: boolean;\\n    /**\\n     * Returns request's HTTP method, which is \\\"GET\\\" by default.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/method)\\n     */\\n    readonly method: string;\\n    /**\\n     * Returns the mode associated with request, which is a string indicating whether the request will use CORS, or will be restricted to same-origin URLs.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/mode)\\n     */\\n    readonly mode: RequestMode;\\n    /**\\n     * Returns the redirect mode associated with request, which is a string indicating how redirects for the request will be handled during fetching. A request will follow redirects by default.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/redirect)\\n     */\\n    readonly redirect: RequestRedirect;\\n    /**\\n     * Returns the referrer of request. Its value can be a same-origin URL if explicitly set in init, the empty string to indicate no referrer, and \\\"about:client\\\" when defaulting to the global's default. This is used during fetching to determine the value of the `Referer` header of the request being made.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/referrer)\\n     */\\n    readonly referrer: string;\\n    /**\\n     * Returns the referrer policy associated with request. This is used during fetching to compute the value of the request's referrer.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/referrerPolicy)\\n     */\\n    readonly referrerPolicy: ReferrerPolicy;\\n    /**\\n     * Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort event handler.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/signal)\\n     */\\n    readonly signal: AbortSignal;\\n    /**\\n     * Returns the URL of request as a string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/url)\\n     */\\n    readonly url: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/clone) */\\n    clone(): Request;\\n}\\n\\ndeclare var Request: {\\n    prototype: Request;\\n    new(input: RequestInfo | URL, init?: RequestInit): Request;\\n};\\n\\n/**\\n * This Fetch API interface represents the response to a request.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response)\\n */\\ninterface Response extends Body {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/headers) */\\n    readonly headers: Headers;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/ok) */\\n    readonly ok: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/redirected) */\\n    readonly redirected: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/status) */\\n    readonly status: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/statusText) */\\n    readonly statusText: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/type) */\\n    readonly type: ResponseType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/url) */\\n    readonly url: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/clone) */\\n    clone(): Response;\\n}\\n\\ndeclare var Response: {\\n    prototype: Response;\\n    new(body?: BodyInit | null, init?: ResponseInit): Response;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/error_static) */\\n    error(): Response;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/json_static) */\\n    json(data: any, init?: ResponseInit): Response;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Response/redirect_static) */\\n    redirect(url: string | URL, status?: number): Response;\\n};\\n\\n/**\\n * Inherits from Event, and represents the event object of an event sent on a document or worker when its content security policy is violated.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent)\\n */\\ninterface SecurityPolicyViolationEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/blockedURI) */\\n    readonly blockedURI: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/columnNumber) */\\n    readonly columnNumber: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/disposition) */\\n    readonly disposition: SecurityPolicyViolationEventDisposition;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/documentURI) */\\n    readonly documentURI: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/effectiveDirective) */\\n    readonly effectiveDirective: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/lineNumber) */\\n    readonly lineNumber: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/originalPolicy) */\\n    readonly originalPolicy: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/referrer) */\\n    readonly referrer: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/sample) */\\n    readonly sample: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/sourceFile) */\\n    readonly sourceFile: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/statusCode) */\\n    readonly statusCode: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SecurityPolicyViolationEvent/violatedDirective) */\\n    readonly violatedDirective: string;\\n}\\n\\ndeclare var SecurityPolicyViolationEvent: {\\n    prototype: SecurityPolicyViolationEvent;\\n    new(type: string, eventInitDict?: SecurityPolicyViolationEventInit): SecurityPolicyViolationEvent;\\n};\\n\\ninterface ServiceWorkerEventMap extends AbstractWorkerEventMap {\\n    \\\"statechange\\\": Event;\\n}\\n\\n/**\\n * This ServiceWorker API interface provides a reference to a service worker. Multiple browsing contexts (e.g. pages, workers, etc.) can be associated with the same service worker, each through a unique ServiceWorker object.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker)\\n */\\ninterface ServiceWorker extends EventTarget, AbstractWorker {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/statechange_event) */\\n    onstatechange: ((this: ServiceWorker, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/scriptURL) */\\n    readonly scriptURL: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/state) */\\n    readonly state: ServiceWorkerState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorker/postMessage) */\\n    postMessage(message: any, transfer: Transferable[]): void;\\n    postMessage(message: any, options?: StructuredSerializeOptions): void;\\n    addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ServiceWorker: {\\n    prototype: ServiceWorker;\\n    new(): ServiceWorker;\\n};\\n\\ninterface ServiceWorkerContainerEventMap {\\n    \\\"controllerchange\\\": Event;\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/**\\n * The ServiceWorkerContainer interface of the ServiceWorker API provides an object representing the service worker as an overall unit in the network ecosystem, including facilities to register, unregister and update service workers, and access the state of service workers and their registrations.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer)\\n */\\ninterface ServiceWorkerContainer extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/controller) */\\n    readonly controller: ServiceWorker | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/controllerchange_event) */\\n    oncontrollerchange: ((this: ServiceWorkerContainer, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/message_event) */\\n    onmessage: ((this: ServiceWorkerContainer, ev: MessageEvent) => any) | null;\\n    onmessageerror: ((this: ServiceWorkerContainer, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/ready) */\\n    readonly ready: Promise<ServiceWorkerRegistration>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/getRegistration) */\\n    getRegistration(clientURL?: string | URL): Promise<ServiceWorkerRegistration | undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/getRegistrations) */\\n    getRegistrations(): Promise<ReadonlyArray<ServiceWorkerRegistration>>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/register) */\\n    register(scriptURL: string | URL, options?: RegistrationOptions): Promise<ServiceWorkerRegistration>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerContainer/startMessages) */\\n    startMessages(): void;\\n    addEventListener<K extends keyof ServiceWorkerContainerEventMap>(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ServiceWorkerContainerEventMap>(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ServiceWorkerContainer: {\\n    prototype: ServiceWorkerContainer;\\n    new(): ServiceWorkerContainer;\\n};\\n\\ninterface ServiceWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {\\n    \\\"activate\\\": ExtendableEvent;\\n    \\\"fetch\\\": FetchEvent;\\n    \\\"install\\\": ExtendableEvent;\\n    \\\"message\\\": ExtendableMessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n    \\\"notificationclick\\\": NotificationEvent;\\n    \\\"notificationclose\\\": NotificationEvent;\\n    \\\"push\\\": PushEvent;\\n    \\\"pushsubscriptionchange\\\": Event;\\n}\\n\\n/**\\n * This ServiceWorker API interface represents the global execution context of a service worker.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope)\\n */\\ninterface ServiceWorkerGlobalScope extends WorkerGlobalScope {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/clients) */\\n    readonly clients: Clients;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/activate_event) */\\n    onactivate: ((this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/fetch_event) */\\n    onfetch: ((this: ServiceWorkerGlobalScope, ev: FetchEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/install_event) */\\n    oninstall: ((this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/message_event) */\\n    onmessage: ((this: ServiceWorkerGlobalScope, ev: ExtendableMessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/messageerror_event) */\\n    onmessageerror: ((this: ServiceWorkerGlobalScope, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/notificationclick_event) */\\n    onnotificationclick: ((this: ServiceWorkerGlobalScope, ev: NotificationEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/notificationclose_event) */\\n    onnotificationclose: ((this: ServiceWorkerGlobalScope, ev: NotificationEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/push_event) */\\n    onpush: ((this: ServiceWorkerGlobalScope, ev: PushEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/pushsubscriptionchange_event) */\\n    onpushsubscriptionchange: ((this: ServiceWorkerGlobalScope, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/registration) */\\n    readonly registration: ServiceWorkerRegistration;\\n    readonly serviceWorker: ServiceWorker;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope/skipWaiting) */\\n    skipWaiting(): Promise<void>;\\n    addEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ServiceWorkerGlobalScope: {\\n    prototype: ServiceWorkerGlobalScope;\\n    new(): ServiceWorkerGlobalScope;\\n};\\n\\ninterface ServiceWorkerRegistrationEventMap {\\n    \\\"updatefound\\\": Event;\\n}\\n\\n/**\\n * This ServiceWorker API interface represents the service worker registration. You register a service worker to control one or more pages that share the same origin.\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration)\\n */\\ninterface ServiceWorkerRegistration extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/active) */\\n    readonly active: ServiceWorker | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/installing) */\\n    readonly installing: ServiceWorker | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/navigationPreload) */\\n    readonly navigationPreload: NavigationPreloadManager;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/updatefound_event) */\\n    onupdatefound: ((this: ServiceWorkerRegistration, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/pushManager) */\\n    readonly pushManager: PushManager;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/scope) */\\n    readonly scope: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/updateViaCache) */\\n    readonly updateViaCache: ServiceWorkerUpdateViaCache;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/waiting) */\\n    readonly waiting: ServiceWorker | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/getNotifications) */\\n    getNotifications(filter?: GetNotificationOptions): Promise<Notification[]>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/showNotification) */\\n    showNotification(title: string, options?: NotificationOptions): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/unregister) */\\n    unregister(): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerRegistration/update) */\\n    update(): Promise<void>;\\n    addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var ServiceWorkerRegistration: {\\n    prototype: ServiceWorkerRegistration;\\n    new(): ServiceWorkerRegistration;\\n};\\n\\ninterface SharedWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {\\n    \\\"connect\\\": MessageEvent;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SharedWorkerGlobalScope) */\\ninterface SharedWorkerGlobalScope extends WorkerGlobalScope {\\n    /**\\n     * Returns sharedWorkerGlobal's name, i.e. the value given to the SharedWorker constructor. Multiple SharedWorker objects can correspond to the same shared worker (and SharedWorkerGlobalScope), by reusing the same name.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SharedWorkerGlobalScope/name)\\n     */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SharedWorkerGlobalScope/connect_event) */\\n    onconnect: ((this: SharedWorkerGlobalScope, ev: MessageEvent) => any) | null;\\n    /**\\n     * Aborts sharedWorkerGlobal.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SharedWorkerGlobalScope/close)\\n     */\\n    close(): void;\\n    addEventListener<K extends keyof SharedWorkerGlobalScopeEventMap>(type: K, listener: (this: SharedWorkerGlobalScope, ev: SharedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof SharedWorkerGlobalScopeEventMap>(type: K, listener: (this: SharedWorkerGlobalScope, ev: SharedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var SharedWorkerGlobalScope: {\\n    prototype: SharedWorkerGlobalScope;\\n    new(): SharedWorkerGlobalScope;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager)\\n */\\ninterface StorageManager {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager/estimate) */\\n    estimate(): Promise<StorageEstimate>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager/getDirectory) */\\n    getDirectory(): Promise<FileSystemDirectoryHandle>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StorageManager/persisted) */\\n    persisted(): Promise<boolean>;\\n}\\n\\ndeclare var StorageManager: {\\n    prototype: StorageManager;\\n    new(): StorageManager;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly) */\\ninterface StylePropertyMapReadOnly {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly/size) */\\n    readonly size: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly/get) */\\n    get(property: string): undefined | CSSStyleValue;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly/getAll) */\\n    getAll(property: string): CSSStyleValue[];\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/StylePropertyMapReadOnly/has) */\\n    has(property: string): boolean;\\n    forEach(callbackfn: (value: CSSStyleValue[], key: string, parent: StylePropertyMapReadOnly) => void, thisArg?: any): void;\\n}\\n\\ndeclare var StylePropertyMapReadOnly: {\\n    prototype: StylePropertyMapReadOnly;\\n    new(): StylePropertyMapReadOnly;\\n};\\n\\n/**\\n * This Web Crypto API interface provides a number of low-level cryptographic functions. It is accessed via the Crypto.subtle properties available in a window context (via Window.crypto).\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto)\\n */\\ninterface SubtleCrypto {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/decrypt) */\\n    decrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveBits) */\\n    deriveBits(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, length: number): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveKey) */\\n    deriveKey(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | HkdfParams | Pbkdf2Params, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/digest) */\\n    digest(algorithm: AlgorithmIdentifier, data: BufferSource): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/encrypt) */\\n    encrypt(algorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/exportKey) */\\n    exportKey(format: \\\"jwk\\\", key: CryptoKey): Promise<JsonWebKey>;\\n    exportKey(format: Exclude<KeyFormat, \\\"jwk\\\">, key: CryptoKey): Promise<ArrayBuffer>;\\n    exportKey(format: KeyFormat, key: CryptoKey): Promise<ArrayBuffer | JsonWebKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) */\\n    generateKey(algorithm: \\\"Ed25519\\\", extractable: boolean, keyUsages: ReadonlyArray<\\\"sign\\\" | \\\"verify\\\">): Promise<CryptoKeyPair>;\\n    generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKeyPair>;\\n    generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;\\n    generateKey(algorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKeyPair | CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) */\\n    importKey(format: \\\"jwk\\\", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;\\n    importKey(format: Exclude<KeyFormat, \\\"jwk\\\">, keyData: BufferSource, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/sign) */\\n    sign(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/unwrapKey) */\\n    unwrapKey(format: KeyFormat, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, unwrappedKeyAlgorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/verify) */\\n    verify(algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, signature: BufferSource, data: BufferSource): Promise<boolean>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/wrapKey) */\\n    wrapKey(format: KeyFormat, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams): Promise<ArrayBuffer>;\\n}\\n\\ndeclare var SubtleCrypto: {\\n    prototype: SubtleCrypto;\\n    new(): SubtleCrypto;\\n};\\n\\n/**\\n * A decoder for a specific method, that is a specific character encoding, like utf-8, iso-8859-2, koi8, cp1261, gbk, etc. A decoder takes a stream of bytes as input and emits a stream of code points. For a more scalable, non-native library, see StringView – a C-like representation of strings based on typed arrays.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder)\\n */\\ninterface TextDecoder extends TextDecoderCommon {\\n    /**\\n     * Returns the result of running encoding's decoder. The method can be invoked zero or more times with options's stream set to true, and then once without options's stream (or set to false), to process a fragmented input. If the invocation without options's stream (or set to false) has no input, it's clearest to omit both arguments.\\n     *\\n     * ```\\n     * var string = \\\"\\\", decoder = new TextDecoder(encoding), buffer;\\n     * while(buffer = next_chunk()) {\\n     *   string += decoder.decode(buffer, {stream:true});\\n     * }\\n     * string += decoder.decode(); // end-of-queue\\n     * ```\\n     *\\n     * If the error mode is \\\"fatal\\\" and encoding's decoder returns error, throws a TypeError.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/decode)\\n     */\\n    decode(input?: AllowSharedBufferSource, options?: TextDecodeOptions): string;\\n}\\n\\ndeclare var TextDecoder: {\\n    prototype: TextDecoder;\\n    new(label?: string, options?: TextDecoderOptions): TextDecoder;\\n};\\n\\ninterface TextDecoderCommon {\\n    /**\\n     * Returns encoding's name, lowercased.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/encoding)\\n     */\\n    readonly encoding: string;\\n    /**\\n     * Returns true if error mode is \\\"fatal\\\", otherwise false.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/fatal)\\n     */\\n    readonly fatal: boolean;\\n    /**\\n     * Returns the value of ignore BOM.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoder/ignoreBOM)\\n     */\\n    readonly ignoreBOM: boolean;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextDecoderStream) */\\ninterface TextDecoderStream extends GenericTransformStream, TextDecoderCommon {\\n    readonly readable: ReadableStream<string>;\\n    readonly writable: WritableStream<BufferSource>;\\n}\\n\\ndeclare var TextDecoderStream: {\\n    prototype: TextDecoderStream;\\n    new(label?: string, options?: TextDecoderOptions): TextDecoderStream;\\n};\\n\\n/**\\n * TextEncoder takes a stream of code points as input and emits a stream of bytes. For a more scalable, non-native library, see StringView – a C-like representation of strings based on typed arrays.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder)\\n */\\ninterface TextEncoder extends TextEncoderCommon {\\n    /**\\n     * Returns the result of running UTF-8's encoder.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encode)\\n     */\\n    encode(input?: string): Uint8Array;\\n    /**\\n     * Runs the UTF-8 encoder on source, stores the result of that operation into destination, and returns the progress made as an object wherein read is the number of converted code units of source and written is the number of bytes modified in destination.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encodeInto)\\n     */\\n    encodeInto(source: string, destination: Uint8Array): TextEncoderEncodeIntoResult;\\n}\\n\\ndeclare var TextEncoder: {\\n    prototype: TextEncoder;\\n    new(): TextEncoder;\\n};\\n\\ninterface TextEncoderCommon {\\n    /**\\n     * Returns \\\"utf-8\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoder/encoding)\\n     */\\n    readonly encoding: string;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextEncoderStream) */\\ninterface TextEncoderStream extends GenericTransformStream, TextEncoderCommon {\\n    readonly readable: ReadableStream<Uint8Array>;\\n    readonly writable: WritableStream<string>;\\n}\\n\\ndeclare var TextEncoderStream: {\\n    prototype: TextEncoderStream;\\n    new(): TextEncoderStream;\\n};\\n\\n/**\\n * The dimensions of a piece of text in the canvas, as created by the CanvasRenderingContext2D.measureText() method.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics)\\n */\\ninterface TextMetrics {\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/actualBoundingBoxAscent)\\n     */\\n    readonly actualBoundingBoxAscent: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/actualBoundingBoxDescent)\\n     */\\n    readonly actualBoundingBoxDescent: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/actualBoundingBoxLeft)\\n     */\\n    readonly actualBoundingBoxLeft: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/actualBoundingBoxRight)\\n     */\\n    readonly actualBoundingBoxRight: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/fontBoundingBoxAscent)\\n     */\\n    readonly fontBoundingBoxAscent: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/fontBoundingBoxDescent)\\n     */\\n    readonly fontBoundingBoxDescent: number;\\n    /**\\n     * Returns the measurement described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/TextMetrics/width)\\n     */\\n    readonly width: number;\\n}\\n\\ndeclare var TextMetrics: {\\n    prototype: TextMetrics;\\n    new(): TextMetrics;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStream) */\\ninterface TransformStream<I = any, O = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStream/readable) */\\n    readonly readable: ReadableStream<O>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStream/writable) */\\n    readonly writable: WritableStream<I>;\\n}\\n\\ndeclare var TransformStream: {\\n    prototype: TransformStream;\\n    new<I = any, O = any>(transformer?: Transformer<I, O>, writableStrategy?: QueuingStrategy<I>, readableStrategy?: QueuingStrategy<O>): TransformStream<I, O>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController) */\\ninterface TransformStreamDefaultController<O = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController/desiredSize) */\\n    readonly desiredSize: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController/enqueue) */\\n    enqueue(chunk?: O): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController/error) */\\n    error(reason?: any): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/TransformStreamDefaultController/terminate) */\\n    terminate(): void;\\n}\\n\\ndeclare var TransformStreamDefaultController: {\\n    prototype: TransformStreamDefaultController;\\n    new(): TransformStreamDefaultController;\\n};\\n\\n/**\\n * The URL interface represents an object providing static methods used for creating object URLs.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL)\\n */\\ninterface URL {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/hash) */\\n    hash: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/host) */\\n    host: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/hostname) */\\n    hostname: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/href) */\\n    href: string;\\n    toString(): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/origin) */\\n    readonly origin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/password) */\\n    password: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/pathname) */\\n    pathname: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/port) */\\n    port: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/protocol) */\\n    protocol: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/search) */\\n    search: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/searchParams) */\\n    readonly searchParams: URLSearchParams;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/username) */\\n    username: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/toJSON) */\\n    toJSON(): string;\\n}\\n\\ndeclare var URL: {\\n    prototype: URL;\\n    new(url: string | URL, base?: string | URL): URL;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/canParse_static) */\\n    canParse(url: string | URL, base?: string): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/createObjectURL_static) */\\n    createObjectURL(obj: Blob): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URL/revokeObjectURL_static) */\\n    revokeObjectURL(url: string): void;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams) */\\ninterface URLSearchParams {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/size) */\\n    readonly size: number;\\n    /**\\n     * Appends a specified key/value pair as a new search parameter.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/append)\\n     */\\n    append(name: string, value: string): void;\\n    /**\\n     * Deletes the given search parameter, and its associated value, from the list of all search parameters.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/delete)\\n     */\\n    delete(name: string, value?: string): void;\\n    /**\\n     * Returns the first value associated to the given search parameter.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/get)\\n     */\\n    get(name: string): string | null;\\n    /**\\n     * Returns all the values association with a given search parameter.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/getAll)\\n     */\\n    getAll(name: string): string[];\\n    /**\\n     * Returns a Boolean indicating if such a search parameter exists.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/has)\\n     */\\n    has(name: string, value?: string): boolean;\\n    /**\\n     * Sets the value associated to a given search parameter to the given value. If there were several values, delete the others.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/set)\\n     */\\n    set(name: string, value: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/URLSearchParams/sort) */\\n    sort(): void;\\n    /** Returns a string containing a query string suitable for use in a URL. Does not include the question mark. */\\n    toString(): string;\\n    forEach(callbackfn: (value: string, key: string, parent: URLSearchParams) => void, thisArg?: any): void;\\n}\\n\\ndeclare var URLSearchParams: {\\n    prototype: URLSearchParams;\\n    new(init?: string[][] | Record<string, string> | string | URLSearchParams): URLSearchParams;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace) */\\ninterface VideoColorSpace {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/fullRange) */\\n    readonly fullRange: boolean | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/matrix) */\\n    readonly matrix: VideoMatrixCoefficients | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/primaries) */\\n    readonly primaries: VideoColorPrimaries | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/transfer) */\\n    readonly transfer: VideoTransferCharacteristics | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoColorSpace/toJSON) */\\n    toJSON(): VideoColorSpaceInit;\\n}\\n\\ndeclare var VideoColorSpace: {\\n    prototype: VideoColorSpace;\\n    new(init?: VideoColorSpaceInit): VideoColorSpace;\\n};\\n\\ninterface VideoDecoderEventMap {\\n    \\\"dequeue\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder)\\n */\\ninterface VideoDecoder extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/decodeQueueSize) */\\n    readonly decodeQueueSize: number;\\n    ondequeue: ((this: VideoDecoder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/state) */\\n    readonly state: CodecState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/configure) */\\n    configure(config: VideoDecoderConfig): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/decode) */\\n    decode(chunk: EncodedVideoChunk): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/flush) */\\n    flush(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoDecoder/reset) */\\n    reset(): void;\\n    addEventListener<K extends keyof VideoDecoderEventMap>(type: K, listener: (this: VideoDecoder, ev: VideoDecoderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof VideoDecoderEventMap>(type: K, listener: (this: VideoDecoder, ev: VideoDecoderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var VideoDecoder: {\\n    prototype: VideoDecoder;\\n    new(init: VideoDecoderInit): VideoDecoder;\\n    isConfigSupported(config: VideoDecoderConfig): Promise<VideoDecoderSupport>;\\n};\\n\\ninterface VideoEncoderEventMap {\\n    \\\"dequeue\\\": Event;\\n}\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder)\\n */\\ninterface VideoEncoder extends EventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/encodeQueueSize) */\\n    readonly encodeQueueSize: number;\\n    ondequeue: ((this: VideoEncoder, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/state) */\\n    readonly state: CodecState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/close) */\\n    close(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/configure) */\\n    configure(config: VideoEncoderConfig): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/encode) */\\n    encode(frame: VideoFrame, options?: VideoEncoderEncodeOptions): void;\\n    flush(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoEncoder/reset) */\\n    reset(): void;\\n    addEventListener<K extends keyof VideoEncoderEventMap>(type: K, listener: (this: VideoEncoder, ev: VideoEncoderEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof VideoEncoderEventMap>(type: K, listener: (this: VideoEncoder, ev: VideoEncoderEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var VideoEncoder: {\\n    prototype: VideoEncoder;\\n    new(init: VideoEncoderInit): VideoEncoder;\\n    isConfigSupported(config: VideoEncoderConfig): Promise<VideoEncoderSupport>;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame) */\\ninterface VideoFrame {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/codedHeight) */\\n    readonly codedHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/codedRect) */\\n    readonly codedRect: DOMRectReadOnly | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/codedWidth) */\\n    readonly codedWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/colorSpace) */\\n    readonly colorSpace: VideoColorSpace;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/displayHeight) */\\n    readonly displayHeight: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/displayWidth) */\\n    readonly displayWidth: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/duration) */\\n    readonly duration: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/format) */\\n    readonly format: VideoPixelFormat | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/timestamp) */\\n    readonly timestamp: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/visibleRect) */\\n    readonly visibleRect: DOMRectReadOnly | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/allocationSize) */\\n    allocationSize(options?: VideoFrameCopyToOptions): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/clone) */\\n    clone(): VideoFrame;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/VideoFrame/close) */\\n    close(): void;\\n    copyTo(destination: BufferSource, options?: VideoFrameCopyToOptions): Promise<PlaneLayout[]>;\\n}\\n\\ndeclare var VideoFrame: {\\n    prototype: VideoFrame;\\n    new(image: CanvasImageSource, init?: VideoFrameInit): VideoFrame;\\n    new(data: BufferSource, init: VideoFrameBufferInit): VideoFrame;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_color_buffer_float) */\\ninterface WEBGL_color_buffer_float {\\n    readonly RGBA32F_EXT: 0x8814;\\n    readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211;\\n    readonly UNSIGNED_NORMALIZED_EXT: 0x8C17;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_astc) */\\ninterface WEBGL_compressed_texture_astc {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_astc/getSupportedProfiles) */\\n    getSupportedProfiles(): string[];\\n    readonly COMPRESSED_RGBA_ASTC_4x4_KHR: 0x93B0;\\n    readonly COMPRESSED_RGBA_ASTC_5x4_KHR: 0x93B1;\\n    readonly COMPRESSED_RGBA_ASTC_5x5_KHR: 0x93B2;\\n    readonly COMPRESSED_RGBA_ASTC_6x5_KHR: 0x93B3;\\n    readonly COMPRESSED_RGBA_ASTC_6x6_KHR: 0x93B4;\\n    readonly COMPRESSED_RGBA_ASTC_8x5_KHR: 0x93B5;\\n    readonly COMPRESSED_RGBA_ASTC_8x6_KHR: 0x93B6;\\n    readonly COMPRESSED_RGBA_ASTC_8x8_KHR: 0x93B7;\\n    readonly COMPRESSED_RGBA_ASTC_10x5_KHR: 0x93B8;\\n    readonly COMPRESSED_RGBA_ASTC_10x6_KHR: 0x93B9;\\n    readonly COMPRESSED_RGBA_ASTC_10x8_KHR: 0x93BA;\\n    readonly COMPRESSED_RGBA_ASTC_10x10_KHR: 0x93BB;\\n    readonly COMPRESSED_RGBA_ASTC_12x10_KHR: 0x93BC;\\n    readonly COMPRESSED_RGBA_ASTC_12x12_KHR: 0x93BD;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: 0x93D0;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: 0x93D1;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: 0x93D2;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: 0x93D3;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: 0x93D4;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: 0x93D5;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: 0x93D6;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: 0x93D7;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: 0x93D8;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: 0x93D9;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: 0x93DA;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: 0x93DB;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: 0x93DC;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: 0x93DD;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_etc) */\\ninterface WEBGL_compressed_texture_etc {\\n    readonly COMPRESSED_R11_EAC: 0x9270;\\n    readonly COMPRESSED_SIGNED_R11_EAC: 0x9271;\\n    readonly COMPRESSED_RG11_EAC: 0x9272;\\n    readonly COMPRESSED_SIGNED_RG11_EAC: 0x9273;\\n    readonly COMPRESSED_RGB8_ETC2: 0x9274;\\n    readonly COMPRESSED_SRGB8_ETC2: 0x9275;\\n    readonly COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: 0x9276;\\n    readonly COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: 0x9277;\\n    readonly COMPRESSED_RGBA8_ETC2_EAC: 0x9278;\\n    readonly COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: 0x9279;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_etc1) */\\ninterface WEBGL_compressed_texture_etc1 {\\n    readonly COMPRESSED_RGB_ETC1_WEBGL: 0x8D64;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_pvrtc) */\\ninterface WEBGL_compressed_texture_pvrtc {\\n    readonly COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 0x8C00;\\n    readonly COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 0x8C01;\\n    readonly COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 0x8C02;\\n    readonly COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: 0x8C03;\\n}\\n\\n/**\\n * The WEBGL_compressed_texture_s3tc extension is part of the WebGL API and exposes four S3TC compressed texture formats.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_s3tc)\\n */\\ninterface WEBGL_compressed_texture_s3tc {\\n    readonly COMPRESSED_RGB_S3TC_DXT1_EXT: 0x83F0;\\n    readonly COMPRESSED_RGBA_S3TC_DXT1_EXT: 0x83F1;\\n    readonly COMPRESSED_RGBA_S3TC_DXT3_EXT: 0x83F2;\\n    readonly COMPRESSED_RGBA_S3TC_DXT5_EXT: 0x83F3;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_compressed_texture_s3tc_srgb) */\\ninterface WEBGL_compressed_texture_s3tc_srgb {\\n    readonly COMPRESSED_SRGB_S3TC_DXT1_EXT: 0x8C4C;\\n    readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: 0x8C4D;\\n    readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: 0x8C4E;\\n    readonly COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: 0x8C4F;\\n}\\n\\n/**\\n * The WEBGL_debug_renderer_info extension is part of the WebGL API and exposes two constants with information about the graphics driver for debugging purposes.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_debug_renderer_info)\\n */\\ninterface WEBGL_debug_renderer_info {\\n    readonly UNMASKED_VENDOR_WEBGL: 0x9245;\\n    readonly UNMASKED_RENDERER_WEBGL: 0x9246;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_debug_shaders) */\\ninterface WEBGL_debug_shaders {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_debug_shaders/getTranslatedShaderSource) */\\n    getTranslatedShaderSource(shader: WebGLShader): string;\\n}\\n\\n/**\\n * The WEBGL_depth_texture extension is part of the WebGL API and defines 2D depth and depth-stencil textures.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_depth_texture)\\n */\\ninterface WEBGL_depth_texture {\\n    readonly UNSIGNED_INT_24_8_WEBGL: 0x84FA;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_draw_buffers) */\\ninterface WEBGL_draw_buffers {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_draw_buffers/drawBuffersWEBGL) */\\n    drawBuffersWEBGL(buffers: GLenum[]): void;\\n    readonly COLOR_ATTACHMENT0_WEBGL: 0x8CE0;\\n    readonly COLOR_ATTACHMENT1_WEBGL: 0x8CE1;\\n    readonly COLOR_ATTACHMENT2_WEBGL: 0x8CE2;\\n    readonly COLOR_ATTACHMENT3_WEBGL: 0x8CE3;\\n    readonly COLOR_ATTACHMENT4_WEBGL: 0x8CE4;\\n    readonly COLOR_ATTACHMENT5_WEBGL: 0x8CE5;\\n    readonly COLOR_ATTACHMENT6_WEBGL: 0x8CE6;\\n    readonly COLOR_ATTACHMENT7_WEBGL: 0x8CE7;\\n    readonly COLOR_ATTACHMENT8_WEBGL: 0x8CE8;\\n    readonly COLOR_ATTACHMENT9_WEBGL: 0x8CE9;\\n    readonly COLOR_ATTACHMENT10_WEBGL: 0x8CEA;\\n    readonly COLOR_ATTACHMENT11_WEBGL: 0x8CEB;\\n    readonly COLOR_ATTACHMENT12_WEBGL: 0x8CEC;\\n    readonly COLOR_ATTACHMENT13_WEBGL: 0x8CED;\\n    readonly COLOR_ATTACHMENT14_WEBGL: 0x8CEE;\\n    readonly COLOR_ATTACHMENT15_WEBGL: 0x8CEF;\\n    readonly DRAW_BUFFER0_WEBGL: 0x8825;\\n    readonly DRAW_BUFFER1_WEBGL: 0x8826;\\n    readonly DRAW_BUFFER2_WEBGL: 0x8827;\\n    readonly DRAW_BUFFER3_WEBGL: 0x8828;\\n    readonly DRAW_BUFFER4_WEBGL: 0x8829;\\n    readonly DRAW_BUFFER5_WEBGL: 0x882A;\\n    readonly DRAW_BUFFER6_WEBGL: 0x882B;\\n    readonly DRAW_BUFFER7_WEBGL: 0x882C;\\n    readonly DRAW_BUFFER8_WEBGL: 0x882D;\\n    readonly DRAW_BUFFER9_WEBGL: 0x882E;\\n    readonly DRAW_BUFFER10_WEBGL: 0x882F;\\n    readonly DRAW_BUFFER11_WEBGL: 0x8830;\\n    readonly DRAW_BUFFER12_WEBGL: 0x8831;\\n    readonly DRAW_BUFFER13_WEBGL: 0x8832;\\n    readonly DRAW_BUFFER14_WEBGL: 0x8833;\\n    readonly DRAW_BUFFER15_WEBGL: 0x8834;\\n    readonly MAX_COLOR_ATTACHMENTS_WEBGL: 0x8CDF;\\n    readonly MAX_DRAW_BUFFERS_WEBGL: 0x8824;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_lose_context) */\\ninterface WEBGL_lose_context {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_lose_context/loseContext) */\\n    loseContext(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_lose_context/restoreContext) */\\n    restoreContext(): void;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw) */\\ninterface WEBGL_multi_draw {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawArraysInstancedWEBGL) */\\n    multiDrawArraysInstancedWEBGL(mode: GLenum, firstsList: Int32Array | GLint[], firstsOffset: GLuint, countsList: Int32Array | GLsizei[], countsOffset: GLuint, instanceCountsList: Int32Array | GLsizei[], instanceCountsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawArraysWEBGL) */\\n    multiDrawArraysWEBGL(mode: GLenum, firstsList: Int32Array | GLint[], firstsOffset: GLuint, countsList: Int32Array | GLsizei[], countsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawElementsInstancedWEBGL) */\\n    multiDrawElementsInstancedWEBGL(mode: GLenum, countsList: Int32Array | GLsizei[], countsOffset: GLuint, type: GLenum, offsetsList: Int32Array | GLsizei[], offsetsOffset: GLuint, instanceCountsList: Int32Array | GLsizei[], instanceCountsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawElementsWEBGL) */\\n    multiDrawElementsWEBGL(mode: GLenum, countsList: Int32Array | GLsizei[], countsOffset: GLuint, type: GLenum, offsetsList: Int32Array | GLsizei[], offsetsOffset: GLuint, drawcount: GLsizei): void;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext) */\\ninterface WebGL2RenderingContext extends WebGL2RenderingContextBase, WebGL2RenderingContextOverloads, WebGLRenderingContextBase {\\n}\\n\\ndeclare var WebGL2RenderingContext: {\\n    prototype: WebGL2RenderingContext;\\n    new(): WebGL2RenderingContext;\\n    readonly READ_BUFFER: 0x0C02;\\n    readonly UNPACK_ROW_LENGTH: 0x0CF2;\\n    readonly UNPACK_SKIP_ROWS: 0x0CF3;\\n    readonly UNPACK_SKIP_PIXELS: 0x0CF4;\\n    readonly PACK_ROW_LENGTH: 0x0D02;\\n    readonly PACK_SKIP_ROWS: 0x0D03;\\n    readonly PACK_SKIP_PIXELS: 0x0D04;\\n    readonly COLOR: 0x1800;\\n    readonly DEPTH: 0x1801;\\n    readonly STENCIL: 0x1802;\\n    readonly RED: 0x1903;\\n    readonly RGB8: 0x8051;\\n    readonly RGBA8: 0x8058;\\n    readonly RGB10_A2: 0x8059;\\n    readonly TEXTURE_BINDING_3D: 0x806A;\\n    readonly UNPACK_SKIP_IMAGES: 0x806D;\\n    readonly UNPACK_IMAGE_HEIGHT: 0x806E;\\n    readonly TEXTURE_3D: 0x806F;\\n    readonly TEXTURE_WRAP_R: 0x8072;\\n    readonly MAX_3D_TEXTURE_SIZE: 0x8073;\\n    readonly UNSIGNED_INT_2_10_10_10_REV: 0x8368;\\n    readonly MAX_ELEMENTS_VERTICES: 0x80E8;\\n    readonly MAX_ELEMENTS_INDICES: 0x80E9;\\n    readonly TEXTURE_MIN_LOD: 0x813A;\\n    readonly TEXTURE_MAX_LOD: 0x813B;\\n    readonly TEXTURE_BASE_LEVEL: 0x813C;\\n    readonly TEXTURE_MAX_LEVEL: 0x813D;\\n    readonly MIN: 0x8007;\\n    readonly MAX: 0x8008;\\n    readonly DEPTH_COMPONENT24: 0x81A6;\\n    readonly MAX_TEXTURE_LOD_BIAS: 0x84FD;\\n    readonly TEXTURE_COMPARE_MODE: 0x884C;\\n    readonly TEXTURE_COMPARE_FUNC: 0x884D;\\n    readonly CURRENT_QUERY: 0x8865;\\n    readonly QUERY_RESULT: 0x8866;\\n    readonly QUERY_RESULT_AVAILABLE: 0x8867;\\n    readonly STREAM_READ: 0x88E1;\\n    readonly STREAM_COPY: 0x88E2;\\n    readonly STATIC_READ: 0x88E5;\\n    readonly STATIC_COPY: 0x88E6;\\n    readonly DYNAMIC_READ: 0x88E9;\\n    readonly DYNAMIC_COPY: 0x88EA;\\n    readonly MAX_DRAW_BUFFERS: 0x8824;\\n    readonly DRAW_BUFFER0: 0x8825;\\n    readonly DRAW_BUFFER1: 0x8826;\\n    readonly DRAW_BUFFER2: 0x8827;\\n    readonly DRAW_BUFFER3: 0x8828;\\n    readonly DRAW_BUFFER4: 0x8829;\\n    readonly DRAW_BUFFER5: 0x882A;\\n    readonly DRAW_BUFFER6: 0x882B;\\n    readonly DRAW_BUFFER7: 0x882C;\\n    readonly DRAW_BUFFER8: 0x882D;\\n    readonly DRAW_BUFFER9: 0x882E;\\n    readonly DRAW_BUFFER10: 0x882F;\\n    readonly DRAW_BUFFER11: 0x8830;\\n    readonly DRAW_BUFFER12: 0x8831;\\n    readonly DRAW_BUFFER13: 0x8832;\\n    readonly DRAW_BUFFER14: 0x8833;\\n    readonly DRAW_BUFFER15: 0x8834;\\n    readonly MAX_FRAGMENT_UNIFORM_COMPONENTS: 0x8B49;\\n    readonly MAX_VERTEX_UNIFORM_COMPONENTS: 0x8B4A;\\n    readonly SAMPLER_3D: 0x8B5F;\\n    readonly SAMPLER_2D_SHADOW: 0x8B62;\\n    readonly FRAGMENT_SHADER_DERIVATIVE_HINT: 0x8B8B;\\n    readonly PIXEL_PACK_BUFFER: 0x88EB;\\n    readonly PIXEL_UNPACK_BUFFER: 0x88EC;\\n    readonly PIXEL_PACK_BUFFER_BINDING: 0x88ED;\\n    readonly PIXEL_UNPACK_BUFFER_BINDING: 0x88EF;\\n    readonly FLOAT_MAT2x3: 0x8B65;\\n    readonly FLOAT_MAT2x4: 0x8B66;\\n    readonly FLOAT_MAT3x2: 0x8B67;\\n    readonly FLOAT_MAT3x4: 0x8B68;\\n    readonly FLOAT_MAT4x2: 0x8B69;\\n    readonly FLOAT_MAT4x3: 0x8B6A;\\n    readonly SRGB: 0x8C40;\\n    readonly SRGB8: 0x8C41;\\n    readonly SRGB8_ALPHA8: 0x8C43;\\n    readonly COMPARE_REF_TO_TEXTURE: 0x884E;\\n    readonly RGBA32F: 0x8814;\\n    readonly RGB32F: 0x8815;\\n    readonly RGBA16F: 0x881A;\\n    readonly RGB16F: 0x881B;\\n    readonly VERTEX_ATTRIB_ARRAY_INTEGER: 0x88FD;\\n    readonly MAX_ARRAY_TEXTURE_LAYERS: 0x88FF;\\n    readonly MIN_PROGRAM_TEXEL_OFFSET: 0x8904;\\n    readonly MAX_PROGRAM_TEXEL_OFFSET: 0x8905;\\n    readonly MAX_VARYING_COMPONENTS: 0x8B4B;\\n    readonly TEXTURE_2D_ARRAY: 0x8C1A;\\n    readonly TEXTURE_BINDING_2D_ARRAY: 0x8C1D;\\n    readonly R11F_G11F_B10F: 0x8C3A;\\n    readonly UNSIGNED_INT_10F_11F_11F_REV: 0x8C3B;\\n    readonly RGB9_E5: 0x8C3D;\\n    readonly UNSIGNED_INT_5_9_9_9_REV: 0x8C3E;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_MODE: 0x8C7F;\\n    readonly MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 0x8C80;\\n    readonly TRANSFORM_FEEDBACK_VARYINGS: 0x8C83;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_START: 0x8C84;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_SIZE: 0x8C85;\\n    readonly TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: 0x8C88;\\n    readonly RASTERIZER_DISCARD: 0x8C89;\\n    readonly MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 0x8C8A;\\n    readonly MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 0x8C8B;\\n    readonly INTERLEAVED_ATTRIBS: 0x8C8C;\\n    readonly SEPARATE_ATTRIBS: 0x8C8D;\\n    readonly TRANSFORM_FEEDBACK_BUFFER: 0x8C8E;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_BINDING: 0x8C8F;\\n    readonly RGBA32UI: 0x8D70;\\n    readonly RGB32UI: 0x8D71;\\n    readonly RGBA16UI: 0x8D76;\\n    readonly RGB16UI: 0x8D77;\\n    readonly RGBA8UI: 0x8D7C;\\n    readonly RGB8UI: 0x8D7D;\\n    readonly RGBA32I: 0x8D82;\\n    readonly RGB32I: 0x8D83;\\n    readonly RGBA16I: 0x8D88;\\n    readonly RGB16I: 0x8D89;\\n    readonly RGBA8I: 0x8D8E;\\n    readonly RGB8I: 0x8D8F;\\n    readonly RED_INTEGER: 0x8D94;\\n    readonly RGB_INTEGER: 0x8D98;\\n    readonly RGBA_INTEGER: 0x8D99;\\n    readonly SAMPLER_2D_ARRAY: 0x8DC1;\\n    readonly SAMPLER_2D_ARRAY_SHADOW: 0x8DC4;\\n    readonly SAMPLER_CUBE_SHADOW: 0x8DC5;\\n    readonly UNSIGNED_INT_VEC2: 0x8DC6;\\n    readonly UNSIGNED_INT_VEC3: 0x8DC7;\\n    readonly UNSIGNED_INT_VEC4: 0x8DC8;\\n    readonly INT_SAMPLER_2D: 0x8DCA;\\n    readonly INT_SAMPLER_3D: 0x8DCB;\\n    readonly INT_SAMPLER_CUBE: 0x8DCC;\\n    readonly INT_SAMPLER_2D_ARRAY: 0x8DCF;\\n    readonly UNSIGNED_INT_SAMPLER_2D: 0x8DD2;\\n    readonly UNSIGNED_INT_SAMPLER_3D: 0x8DD3;\\n    readonly UNSIGNED_INT_SAMPLER_CUBE: 0x8DD4;\\n    readonly UNSIGNED_INT_SAMPLER_2D_ARRAY: 0x8DD7;\\n    readonly DEPTH_COMPONENT32F: 0x8CAC;\\n    readonly DEPTH32F_STENCIL8: 0x8CAD;\\n    readonly FLOAT_32_UNSIGNED_INT_24_8_REV: 0x8DAD;\\n    readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: 0x8210;\\n    readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: 0x8211;\\n    readonly FRAMEBUFFER_ATTACHMENT_RED_SIZE: 0x8212;\\n    readonly FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 0x8213;\\n    readonly FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 0x8214;\\n    readonly FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 0x8215;\\n    readonly FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 0x8216;\\n    readonly FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 0x8217;\\n    readonly FRAMEBUFFER_DEFAULT: 0x8218;\\n    readonly UNSIGNED_INT_24_8: 0x84FA;\\n    readonly DEPTH24_STENCIL8: 0x88F0;\\n    readonly UNSIGNED_NORMALIZED: 0x8C17;\\n    readonly DRAW_FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly READ_FRAMEBUFFER: 0x8CA8;\\n    readonly DRAW_FRAMEBUFFER: 0x8CA9;\\n    readonly READ_FRAMEBUFFER_BINDING: 0x8CAA;\\n    readonly RENDERBUFFER_SAMPLES: 0x8CAB;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: 0x8CD4;\\n    readonly MAX_COLOR_ATTACHMENTS: 0x8CDF;\\n    readonly COLOR_ATTACHMENT1: 0x8CE1;\\n    readonly COLOR_ATTACHMENT2: 0x8CE2;\\n    readonly COLOR_ATTACHMENT3: 0x8CE3;\\n    readonly COLOR_ATTACHMENT4: 0x8CE4;\\n    readonly COLOR_ATTACHMENT5: 0x8CE5;\\n    readonly COLOR_ATTACHMENT6: 0x8CE6;\\n    readonly COLOR_ATTACHMENT7: 0x8CE7;\\n    readonly COLOR_ATTACHMENT8: 0x8CE8;\\n    readonly COLOR_ATTACHMENT9: 0x8CE9;\\n    readonly COLOR_ATTACHMENT10: 0x8CEA;\\n    readonly COLOR_ATTACHMENT11: 0x8CEB;\\n    readonly COLOR_ATTACHMENT12: 0x8CEC;\\n    readonly COLOR_ATTACHMENT13: 0x8CED;\\n    readonly COLOR_ATTACHMENT14: 0x8CEE;\\n    readonly COLOR_ATTACHMENT15: 0x8CEF;\\n    readonly FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: 0x8D56;\\n    readonly MAX_SAMPLES: 0x8D57;\\n    readonly HALF_FLOAT: 0x140B;\\n    readonly RG: 0x8227;\\n    readonly RG_INTEGER: 0x8228;\\n    readonly R8: 0x8229;\\n    readonly RG8: 0x822B;\\n    readonly R16F: 0x822D;\\n    readonly R32F: 0x822E;\\n    readonly RG16F: 0x822F;\\n    readonly RG32F: 0x8230;\\n    readonly R8I: 0x8231;\\n    readonly R8UI: 0x8232;\\n    readonly R16I: 0x8233;\\n    readonly R16UI: 0x8234;\\n    readonly R32I: 0x8235;\\n    readonly R32UI: 0x8236;\\n    readonly RG8I: 0x8237;\\n    readonly RG8UI: 0x8238;\\n    readonly RG16I: 0x8239;\\n    readonly RG16UI: 0x823A;\\n    readonly RG32I: 0x823B;\\n    readonly RG32UI: 0x823C;\\n    readonly VERTEX_ARRAY_BINDING: 0x85B5;\\n    readonly R8_SNORM: 0x8F94;\\n    readonly RG8_SNORM: 0x8F95;\\n    readonly RGB8_SNORM: 0x8F96;\\n    readonly RGBA8_SNORM: 0x8F97;\\n    readonly SIGNED_NORMALIZED: 0x8F9C;\\n    readonly COPY_READ_BUFFER: 0x8F36;\\n    readonly COPY_WRITE_BUFFER: 0x8F37;\\n    readonly COPY_READ_BUFFER_BINDING: 0x8F36;\\n    readonly COPY_WRITE_BUFFER_BINDING: 0x8F37;\\n    readonly UNIFORM_BUFFER: 0x8A11;\\n    readonly UNIFORM_BUFFER_BINDING: 0x8A28;\\n    readonly UNIFORM_BUFFER_START: 0x8A29;\\n    readonly UNIFORM_BUFFER_SIZE: 0x8A2A;\\n    readonly MAX_VERTEX_UNIFORM_BLOCKS: 0x8A2B;\\n    readonly MAX_FRAGMENT_UNIFORM_BLOCKS: 0x8A2D;\\n    readonly MAX_COMBINED_UNIFORM_BLOCKS: 0x8A2E;\\n    readonly MAX_UNIFORM_BUFFER_BINDINGS: 0x8A2F;\\n    readonly MAX_UNIFORM_BLOCK_SIZE: 0x8A30;\\n    readonly MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 0x8A31;\\n    readonly MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 0x8A33;\\n    readonly UNIFORM_BUFFER_OFFSET_ALIGNMENT: 0x8A34;\\n    readonly ACTIVE_UNIFORM_BLOCKS: 0x8A36;\\n    readonly UNIFORM_TYPE: 0x8A37;\\n    readonly UNIFORM_SIZE: 0x8A38;\\n    readonly UNIFORM_BLOCK_INDEX: 0x8A3A;\\n    readonly UNIFORM_OFFSET: 0x8A3B;\\n    readonly UNIFORM_ARRAY_STRIDE: 0x8A3C;\\n    readonly UNIFORM_MATRIX_STRIDE: 0x8A3D;\\n    readonly UNIFORM_IS_ROW_MAJOR: 0x8A3E;\\n    readonly UNIFORM_BLOCK_BINDING: 0x8A3F;\\n    readonly UNIFORM_BLOCK_DATA_SIZE: 0x8A40;\\n    readonly UNIFORM_BLOCK_ACTIVE_UNIFORMS: 0x8A42;\\n    readonly UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 0x8A43;\\n    readonly UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 0x8A44;\\n    readonly UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 0x8A46;\\n    readonly INVALID_INDEX: 0xFFFFFFFF;\\n    readonly MAX_VERTEX_OUTPUT_COMPONENTS: 0x9122;\\n    readonly MAX_FRAGMENT_INPUT_COMPONENTS: 0x9125;\\n    readonly MAX_SERVER_WAIT_TIMEOUT: 0x9111;\\n    readonly OBJECT_TYPE: 0x9112;\\n    readonly SYNC_CONDITION: 0x9113;\\n    readonly SYNC_STATUS: 0x9114;\\n    readonly SYNC_FLAGS: 0x9115;\\n    readonly SYNC_FENCE: 0x9116;\\n    readonly SYNC_GPU_COMMANDS_COMPLETE: 0x9117;\\n    readonly UNSIGNALED: 0x9118;\\n    readonly SIGNALED: 0x9119;\\n    readonly ALREADY_SIGNALED: 0x911A;\\n    readonly TIMEOUT_EXPIRED: 0x911B;\\n    readonly CONDITION_SATISFIED: 0x911C;\\n    readonly WAIT_FAILED: 0x911D;\\n    readonly SYNC_FLUSH_COMMANDS_BIT: 0x00000001;\\n    readonly VERTEX_ATTRIB_ARRAY_DIVISOR: 0x88FE;\\n    readonly ANY_SAMPLES_PASSED: 0x8C2F;\\n    readonly ANY_SAMPLES_PASSED_CONSERVATIVE: 0x8D6A;\\n    readonly SAMPLER_BINDING: 0x8919;\\n    readonly RGB10_A2UI: 0x906F;\\n    readonly INT_2_10_10_10_REV: 0x8D9F;\\n    readonly TRANSFORM_FEEDBACK: 0x8E22;\\n    readonly TRANSFORM_FEEDBACK_PAUSED: 0x8E23;\\n    readonly TRANSFORM_FEEDBACK_ACTIVE: 0x8E24;\\n    readonly TRANSFORM_FEEDBACK_BINDING: 0x8E25;\\n    readonly TEXTURE_IMMUTABLE_FORMAT: 0x912F;\\n    readonly MAX_ELEMENT_INDEX: 0x8D6B;\\n    readonly TEXTURE_IMMUTABLE_LEVELS: 0x82DF;\\n    readonly TIMEOUT_IGNORED: -1;\\n    readonly MAX_CLIENT_WAIT_TIMEOUT_WEBGL: 0x9247;\\n    readonly DEPTH_BUFFER_BIT: 0x00000100;\\n    readonly STENCIL_BUFFER_BIT: 0x00000400;\\n    readonly COLOR_BUFFER_BIT: 0x00004000;\\n    readonly POINTS: 0x0000;\\n    readonly LINES: 0x0001;\\n    readonly LINE_LOOP: 0x0002;\\n    readonly LINE_STRIP: 0x0003;\\n    readonly TRIANGLES: 0x0004;\\n    readonly TRIANGLE_STRIP: 0x0005;\\n    readonly TRIANGLE_FAN: 0x0006;\\n    readonly ZERO: 0;\\n    readonly ONE: 1;\\n    readonly SRC_COLOR: 0x0300;\\n    readonly ONE_MINUS_SRC_COLOR: 0x0301;\\n    readonly SRC_ALPHA: 0x0302;\\n    readonly ONE_MINUS_SRC_ALPHA: 0x0303;\\n    readonly DST_ALPHA: 0x0304;\\n    readonly ONE_MINUS_DST_ALPHA: 0x0305;\\n    readonly DST_COLOR: 0x0306;\\n    readonly ONE_MINUS_DST_COLOR: 0x0307;\\n    readonly SRC_ALPHA_SATURATE: 0x0308;\\n    readonly FUNC_ADD: 0x8006;\\n    readonly BLEND_EQUATION: 0x8009;\\n    readonly BLEND_EQUATION_RGB: 0x8009;\\n    readonly BLEND_EQUATION_ALPHA: 0x883D;\\n    readonly FUNC_SUBTRACT: 0x800A;\\n    readonly FUNC_REVERSE_SUBTRACT: 0x800B;\\n    readonly BLEND_DST_RGB: 0x80C8;\\n    readonly BLEND_SRC_RGB: 0x80C9;\\n    readonly BLEND_DST_ALPHA: 0x80CA;\\n    readonly BLEND_SRC_ALPHA: 0x80CB;\\n    readonly CONSTANT_COLOR: 0x8001;\\n    readonly ONE_MINUS_CONSTANT_COLOR: 0x8002;\\n    readonly CONSTANT_ALPHA: 0x8003;\\n    readonly ONE_MINUS_CONSTANT_ALPHA: 0x8004;\\n    readonly BLEND_COLOR: 0x8005;\\n    readonly ARRAY_BUFFER: 0x8892;\\n    readonly ELEMENT_ARRAY_BUFFER: 0x8893;\\n    readonly ARRAY_BUFFER_BINDING: 0x8894;\\n    readonly ELEMENT_ARRAY_BUFFER_BINDING: 0x8895;\\n    readonly STREAM_DRAW: 0x88E0;\\n    readonly STATIC_DRAW: 0x88E4;\\n    readonly DYNAMIC_DRAW: 0x88E8;\\n    readonly BUFFER_SIZE: 0x8764;\\n    readonly BUFFER_USAGE: 0x8765;\\n    readonly CURRENT_VERTEX_ATTRIB: 0x8626;\\n    readonly FRONT: 0x0404;\\n    readonly BACK: 0x0405;\\n    readonly FRONT_AND_BACK: 0x0408;\\n    readonly CULL_FACE: 0x0B44;\\n    readonly BLEND: 0x0BE2;\\n    readonly DITHER: 0x0BD0;\\n    readonly STENCIL_TEST: 0x0B90;\\n    readonly DEPTH_TEST: 0x0B71;\\n    readonly SCISSOR_TEST: 0x0C11;\\n    readonly POLYGON_OFFSET_FILL: 0x8037;\\n    readonly SAMPLE_ALPHA_TO_COVERAGE: 0x809E;\\n    readonly SAMPLE_COVERAGE: 0x80A0;\\n    readonly NO_ERROR: 0;\\n    readonly INVALID_ENUM: 0x0500;\\n    readonly INVALID_VALUE: 0x0501;\\n    readonly INVALID_OPERATION: 0x0502;\\n    readonly OUT_OF_MEMORY: 0x0505;\\n    readonly CW: 0x0900;\\n    readonly CCW: 0x0901;\\n    readonly LINE_WIDTH: 0x0B21;\\n    readonly ALIASED_POINT_SIZE_RANGE: 0x846D;\\n    readonly ALIASED_LINE_WIDTH_RANGE: 0x846E;\\n    readonly CULL_FACE_MODE: 0x0B45;\\n    readonly FRONT_FACE: 0x0B46;\\n    readonly DEPTH_RANGE: 0x0B70;\\n    readonly DEPTH_WRITEMASK: 0x0B72;\\n    readonly DEPTH_CLEAR_VALUE: 0x0B73;\\n    readonly DEPTH_FUNC: 0x0B74;\\n    readonly STENCIL_CLEAR_VALUE: 0x0B91;\\n    readonly STENCIL_FUNC: 0x0B92;\\n    readonly STENCIL_FAIL: 0x0B94;\\n    readonly STENCIL_PASS_DEPTH_FAIL: 0x0B95;\\n    readonly STENCIL_PASS_DEPTH_PASS: 0x0B96;\\n    readonly STENCIL_REF: 0x0B97;\\n    readonly STENCIL_VALUE_MASK: 0x0B93;\\n    readonly STENCIL_WRITEMASK: 0x0B98;\\n    readonly STENCIL_BACK_FUNC: 0x8800;\\n    readonly STENCIL_BACK_FAIL: 0x8801;\\n    readonly STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802;\\n    readonly STENCIL_BACK_PASS_DEPTH_PASS: 0x8803;\\n    readonly STENCIL_BACK_REF: 0x8CA3;\\n    readonly STENCIL_BACK_VALUE_MASK: 0x8CA4;\\n    readonly STENCIL_BACK_WRITEMASK: 0x8CA5;\\n    readonly VIEWPORT: 0x0BA2;\\n    readonly SCISSOR_BOX: 0x0C10;\\n    readonly COLOR_CLEAR_VALUE: 0x0C22;\\n    readonly COLOR_WRITEMASK: 0x0C23;\\n    readonly UNPACK_ALIGNMENT: 0x0CF5;\\n    readonly PACK_ALIGNMENT: 0x0D05;\\n    readonly MAX_TEXTURE_SIZE: 0x0D33;\\n    readonly MAX_VIEWPORT_DIMS: 0x0D3A;\\n    readonly SUBPIXEL_BITS: 0x0D50;\\n    readonly RED_BITS: 0x0D52;\\n    readonly GREEN_BITS: 0x0D53;\\n    readonly BLUE_BITS: 0x0D54;\\n    readonly ALPHA_BITS: 0x0D55;\\n    readonly DEPTH_BITS: 0x0D56;\\n    readonly STENCIL_BITS: 0x0D57;\\n    readonly POLYGON_OFFSET_UNITS: 0x2A00;\\n    readonly POLYGON_OFFSET_FACTOR: 0x8038;\\n    readonly TEXTURE_BINDING_2D: 0x8069;\\n    readonly SAMPLE_BUFFERS: 0x80A8;\\n    readonly SAMPLES: 0x80A9;\\n    readonly SAMPLE_COVERAGE_VALUE: 0x80AA;\\n    readonly SAMPLE_COVERAGE_INVERT: 0x80AB;\\n    readonly COMPRESSED_TEXTURE_FORMATS: 0x86A3;\\n    readonly DONT_CARE: 0x1100;\\n    readonly FASTEST: 0x1101;\\n    readonly NICEST: 0x1102;\\n    readonly GENERATE_MIPMAP_HINT: 0x8192;\\n    readonly BYTE: 0x1400;\\n    readonly UNSIGNED_BYTE: 0x1401;\\n    readonly SHORT: 0x1402;\\n    readonly UNSIGNED_SHORT: 0x1403;\\n    readonly INT: 0x1404;\\n    readonly UNSIGNED_INT: 0x1405;\\n    readonly FLOAT: 0x1406;\\n    readonly DEPTH_COMPONENT: 0x1902;\\n    readonly ALPHA: 0x1906;\\n    readonly RGB: 0x1907;\\n    readonly RGBA: 0x1908;\\n    readonly LUMINANCE: 0x1909;\\n    readonly LUMINANCE_ALPHA: 0x190A;\\n    readonly UNSIGNED_SHORT_4_4_4_4: 0x8033;\\n    readonly UNSIGNED_SHORT_5_5_5_1: 0x8034;\\n    readonly UNSIGNED_SHORT_5_6_5: 0x8363;\\n    readonly FRAGMENT_SHADER: 0x8B30;\\n    readonly VERTEX_SHADER: 0x8B31;\\n    readonly MAX_VERTEX_ATTRIBS: 0x8869;\\n    readonly MAX_VERTEX_UNIFORM_VECTORS: 0x8DFB;\\n    readonly MAX_VARYING_VECTORS: 0x8DFC;\\n    readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8B4D;\\n    readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8B4C;\\n    readonly MAX_TEXTURE_IMAGE_UNITS: 0x8872;\\n    readonly MAX_FRAGMENT_UNIFORM_VECTORS: 0x8DFD;\\n    readonly SHADER_TYPE: 0x8B4F;\\n    readonly DELETE_STATUS: 0x8B80;\\n    readonly LINK_STATUS: 0x8B82;\\n    readonly VALIDATE_STATUS: 0x8B83;\\n    readonly ATTACHED_SHADERS: 0x8B85;\\n    readonly ACTIVE_UNIFORMS: 0x8B86;\\n    readonly ACTIVE_ATTRIBUTES: 0x8B89;\\n    readonly SHADING_LANGUAGE_VERSION: 0x8B8C;\\n    readonly CURRENT_PROGRAM: 0x8B8D;\\n    readonly NEVER: 0x0200;\\n    readonly LESS: 0x0201;\\n    readonly EQUAL: 0x0202;\\n    readonly LEQUAL: 0x0203;\\n    readonly GREATER: 0x0204;\\n    readonly NOTEQUAL: 0x0205;\\n    readonly GEQUAL: 0x0206;\\n    readonly ALWAYS: 0x0207;\\n    readonly KEEP: 0x1E00;\\n    readonly REPLACE: 0x1E01;\\n    readonly INCR: 0x1E02;\\n    readonly DECR: 0x1E03;\\n    readonly INVERT: 0x150A;\\n    readonly INCR_WRAP: 0x8507;\\n    readonly DECR_WRAP: 0x8508;\\n    readonly VENDOR: 0x1F00;\\n    readonly RENDERER: 0x1F01;\\n    readonly VERSION: 0x1F02;\\n    readonly NEAREST: 0x2600;\\n    readonly LINEAR: 0x2601;\\n    readonly NEAREST_MIPMAP_NEAREST: 0x2700;\\n    readonly LINEAR_MIPMAP_NEAREST: 0x2701;\\n    readonly NEAREST_MIPMAP_LINEAR: 0x2702;\\n    readonly LINEAR_MIPMAP_LINEAR: 0x2703;\\n    readonly TEXTURE_MAG_FILTER: 0x2800;\\n    readonly TEXTURE_MIN_FILTER: 0x2801;\\n    readonly TEXTURE_WRAP_S: 0x2802;\\n    readonly TEXTURE_WRAP_T: 0x2803;\\n    readonly TEXTURE_2D: 0x0DE1;\\n    readonly TEXTURE: 0x1702;\\n    readonly TEXTURE_CUBE_MAP: 0x8513;\\n    readonly TEXTURE_BINDING_CUBE_MAP: 0x8514;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851A;\\n    readonly MAX_CUBE_MAP_TEXTURE_SIZE: 0x851C;\\n    readonly TEXTURE0: 0x84C0;\\n    readonly TEXTURE1: 0x84C1;\\n    readonly TEXTURE2: 0x84C2;\\n    readonly TEXTURE3: 0x84C3;\\n    readonly TEXTURE4: 0x84C4;\\n    readonly TEXTURE5: 0x84C5;\\n    readonly TEXTURE6: 0x84C6;\\n    readonly TEXTURE7: 0x84C7;\\n    readonly TEXTURE8: 0x84C8;\\n    readonly TEXTURE9: 0x84C9;\\n    readonly TEXTURE10: 0x84CA;\\n    readonly TEXTURE11: 0x84CB;\\n    readonly TEXTURE12: 0x84CC;\\n    readonly TEXTURE13: 0x84CD;\\n    readonly TEXTURE14: 0x84CE;\\n    readonly TEXTURE15: 0x84CF;\\n    readonly TEXTURE16: 0x84D0;\\n    readonly TEXTURE17: 0x84D1;\\n    readonly TEXTURE18: 0x84D2;\\n    readonly TEXTURE19: 0x84D3;\\n    readonly TEXTURE20: 0x84D4;\\n    readonly TEXTURE21: 0x84D5;\\n    readonly TEXTURE22: 0x84D6;\\n    readonly TEXTURE23: 0x84D7;\\n    readonly TEXTURE24: 0x84D8;\\n    readonly TEXTURE25: 0x84D9;\\n    readonly TEXTURE26: 0x84DA;\\n    readonly TEXTURE27: 0x84DB;\\n    readonly TEXTURE28: 0x84DC;\\n    readonly TEXTURE29: 0x84DD;\\n    readonly TEXTURE30: 0x84DE;\\n    readonly TEXTURE31: 0x84DF;\\n    readonly ACTIVE_TEXTURE: 0x84E0;\\n    readonly REPEAT: 0x2901;\\n    readonly CLAMP_TO_EDGE: 0x812F;\\n    readonly MIRRORED_REPEAT: 0x8370;\\n    readonly FLOAT_VEC2: 0x8B50;\\n    readonly FLOAT_VEC3: 0x8B51;\\n    readonly FLOAT_VEC4: 0x8B52;\\n    readonly INT_VEC2: 0x8B53;\\n    readonly INT_VEC3: 0x8B54;\\n    readonly INT_VEC4: 0x8B55;\\n    readonly BOOL: 0x8B56;\\n    readonly BOOL_VEC2: 0x8B57;\\n    readonly BOOL_VEC3: 0x8B58;\\n    readonly BOOL_VEC4: 0x8B59;\\n    readonly FLOAT_MAT2: 0x8B5A;\\n    readonly FLOAT_MAT3: 0x8B5B;\\n    readonly FLOAT_MAT4: 0x8B5C;\\n    readonly SAMPLER_2D: 0x8B5E;\\n    readonly SAMPLER_CUBE: 0x8B60;\\n    readonly VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622;\\n    readonly VERTEX_ATTRIB_ARRAY_SIZE: 0x8623;\\n    readonly VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624;\\n    readonly VERTEX_ATTRIB_ARRAY_TYPE: 0x8625;\\n    readonly VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886A;\\n    readonly VERTEX_ATTRIB_ARRAY_POINTER: 0x8645;\\n    readonly VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889F;\\n    readonly IMPLEMENTATION_COLOR_READ_TYPE: 0x8B9A;\\n    readonly IMPLEMENTATION_COLOR_READ_FORMAT: 0x8B9B;\\n    readonly COMPILE_STATUS: 0x8B81;\\n    readonly LOW_FLOAT: 0x8DF0;\\n    readonly MEDIUM_FLOAT: 0x8DF1;\\n    readonly HIGH_FLOAT: 0x8DF2;\\n    readonly LOW_INT: 0x8DF3;\\n    readonly MEDIUM_INT: 0x8DF4;\\n    readonly HIGH_INT: 0x8DF5;\\n    readonly FRAMEBUFFER: 0x8D40;\\n    readonly RENDERBUFFER: 0x8D41;\\n    readonly RGBA4: 0x8056;\\n    readonly RGB5_A1: 0x8057;\\n    readonly RGB565: 0x8D62;\\n    readonly DEPTH_COMPONENT16: 0x81A5;\\n    readonly STENCIL_INDEX8: 0x8D48;\\n    readonly DEPTH_STENCIL: 0x84F9;\\n    readonly RENDERBUFFER_WIDTH: 0x8D42;\\n    readonly RENDERBUFFER_HEIGHT: 0x8D43;\\n    readonly RENDERBUFFER_INTERNAL_FORMAT: 0x8D44;\\n    readonly RENDERBUFFER_RED_SIZE: 0x8D50;\\n    readonly RENDERBUFFER_GREEN_SIZE: 0x8D51;\\n    readonly RENDERBUFFER_BLUE_SIZE: 0x8D52;\\n    readonly RENDERBUFFER_ALPHA_SIZE: 0x8D53;\\n    readonly RENDERBUFFER_DEPTH_SIZE: 0x8D54;\\n    readonly RENDERBUFFER_STENCIL_SIZE: 0x8D55;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8CD0;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8CD1;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8CD2;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8CD3;\\n    readonly COLOR_ATTACHMENT0: 0x8CE0;\\n    readonly DEPTH_ATTACHMENT: 0x8D00;\\n    readonly STENCIL_ATTACHMENT: 0x8D20;\\n    readonly DEPTH_STENCIL_ATTACHMENT: 0x821A;\\n    readonly NONE: 0;\\n    readonly FRAMEBUFFER_COMPLETE: 0x8CD5;\\n    readonly FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8CD6;\\n    readonly FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8CD7;\\n    readonly FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8CD9;\\n    readonly FRAMEBUFFER_UNSUPPORTED: 0x8CDD;\\n    readonly FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly RENDERBUFFER_BINDING: 0x8CA7;\\n    readonly MAX_RENDERBUFFER_SIZE: 0x84E8;\\n    readonly INVALID_FRAMEBUFFER_OPERATION: 0x0506;\\n    readonly UNPACK_FLIP_Y_WEBGL: 0x9240;\\n    readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241;\\n    readonly CONTEXT_LOST_WEBGL: 0x9242;\\n    readonly UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243;\\n    readonly BROWSER_DEFAULT_WEBGL: 0x9244;\\n};\\n\\ninterface WebGL2RenderingContextBase {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/beginQuery) */\\n    beginQuery(target: GLenum, query: WebGLQuery): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/beginTransformFeedback) */\\n    beginTransformFeedback(primitiveMode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindBufferBase) */\\n    bindBufferBase(target: GLenum, index: GLuint, buffer: WebGLBuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindBufferRange) */\\n    bindBufferRange(target: GLenum, index: GLuint, buffer: WebGLBuffer | null, offset: GLintptr, size: GLsizeiptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindSampler) */\\n    bindSampler(unit: GLuint, sampler: WebGLSampler | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindTransformFeedback) */\\n    bindTransformFeedback(target: GLenum, tf: WebGLTransformFeedback | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/bindVertexArray) */\\n    bindVertexArray(array: WebGLVertexArrayObject | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/blitFramebuffer) */\\n    blitFramebuffer(srcX0: GLint, srcY0: GLint, srcX1: GLint, srcY1: GLint, dstX0: GLint, dstY0: GLint, dstX1: GLint, dstY1: GLint, mask: GLbitfield, filter: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferfi(buffer: GLenum, drawbuffer: GLint, depth: GLfloat, stencil: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferfv(buffer: GLenum, drawbuffer: GLint, values: Float32List, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferiv(buffer: GLenum, drawbuffer: GLint, values: Int32List, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferuiv(buffer: GLenum, drawbuffer: GLint, values: Uint32List, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clientWaitSync) */\\n    clientWaitSync(sync: WebGLSync, flags: GLbitfield, timeout: GLuint64): GLenum;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/compressedTexImage3D) */\\n    compressedTexImage3D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, imageSize: GLsizei, offset: GLintptr): void;\\n    compressedTexImage3D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, srcData: ArrayBufferView, srcOffset?: GLuint, srcLengthOverride?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/compressedTexSubImage3D) */\\n    compressedTexSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, imageSize: GLsizei, offset: GLintptr): void;\\n    compressedTexSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, srcData: ArrayBufferView, srcOffset?: GLuint, srcLengthOverride?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/copyBufferSubData) */\\n    copyBufferSubData(readTarget: GLenum, writeTarget: GLenum, readOffset: GLintptr, writeOffset: GLintptr, size: GLsizeiptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/copyTexSubImage3D) */\\n    copyTexSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/createQuery) */\\n    createQuery(): WebGLQuery | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/createSampler) */\\n    createSampler(): WebGLSampler | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/createTransformFeedback) */\\n    createTransformFeedback(): WebGLTransformFeedback | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/createVertexArray) */\\n    createVertexArray(): WebGLVertexArrayObject | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteQuery) */\\n    deleteQuery(query: WebGLQuery | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteSampler) */\\n    deleteSampler(sampler: WebGLSampler | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteSync) */\\n    deleteSync(sync: WebGLSync | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteTransformFeedback) */\\n    deleteTransformFeedback(tf: WebGLTransformFeedback | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/deleteVertexArray) */\\n    deleteVertexArray(vertexArray: WebGLVertexArrayObject | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawArraysInstanced) */\\n    drawArraysInstanced(mode: GLenum, first: GLint, count: GLsizei, instanceCount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawBuffers) */\\n    drawBuffers(buffers: GLenum[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawElementsInstanced) */\\n    drawElementsInstanced(mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr, instanceCount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawRangeElements) */\\n    drawRangeElements(mode: GLenum, start: GLuint, end: GLuint, count: GLsizei, type: GLenum, offset: GLintptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/endQuery) */\\n    endQuery(target: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/endTransformFeedback) */\\n    endTransformFeedback(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/fenceSync) */\\n    fenceSync(condition: GLenum, flags: GLbitfield): WebGLSync | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/framebufferTextureLayer) */\\n    framebufferTextureLayer(target: GLenum, attachment: GLenum, texture: WebGLTexture | null, level: GLint, layer: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getActiveUniformBlockName) */\\n    getActiveUniformBlockName(program: WebGLProgram, uniformBlockIndex: GLuint): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getActiveUniformBlockParameter) */\\n    getActiveUniformBlockParameter(program: WebGLProgram, uniformBlockIndex: GLuint, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getActiveUniforms) */\\n    getActiveUniforms(program: WebGLProgram, uniformIndices: GLuint[], pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getBufferSubData) */\\n    getBufferSubData(target: GLenum, srcByteOffset: GLintptr, dstBuffer: ArrayBufferView, dstOffset?: GLuint, length?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getFragDataLocation) */\\n    getFragDataLocation(program: WebGLProgram, name: string): GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getIndexedParameter) */\\n    getIndexedParameter(target: GLenum, index: GLuint): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getInternalformatParameter) */\\n    getInternalformatParameter(target: GLenum, internalformat: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getQuery) */\\n    getQuery(target: GLenum, pname: GLenum): WebGLQuery | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getQueryParameter) */\\n    getQueryParameter(query: WebGLQuery, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getSamplerParameter) */\\n    getSamplerParameter(sampler: WebGLSampler, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getSyncParameter) */\\n    getSyncParameter(sync: WebGLSync, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getTransformFeedbackVarying) */\\n    getTransformFeedbackVarying(program: WebGLProgram, index: GLuint): WebGLActiveInfo | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getUniformBlockIndex) */\\n    getUniformBlockIndex(program: WebGLProgram, uniformBlockName: string): GLuint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getUniformIndices) */\\n    getUniformIndices(program: WebGLProgram, uniformNames: string[]): GLuint[] | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/invalidateFramebuffer) */\\n    invalidateFramebuffer(target: GLenum, attachments: GLenum[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/invalidateSubFramebuffer) */\\n    invalidateSubFramebuffer(target: GLenum, attachments: GLenum[], x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isQuery) */\\n    isQuery(query: WebGLQuery | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isSampler) */\\n    isSampler(sampler: WebGLSampler | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isSync) */\\n    isSync(sync: WebGLSync | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isTransformFeedback) */\\n    isTransformFeedback(tf: WebGLTransformFeedback | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/isVertexArray) */\\n    isVertexArray(vertexArray: WebGLVertexArrayObject | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/pauseTransformFeedback) */\\n    pauseTransformFeedback(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/readBuffer) */\\n    readBuffer(src: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/renderbufferStorageMultisample) */\\n    renderbufferStorageMultisample(target: GLenum, samples: GLsizei, internalformat: GLenum, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/resumeTransformFeedback) */\\n    resumeTransformFeedback(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/samplerParameter) */\\n    samplerParameterf(sampler: WebGLSampler, pname: GLenum, param: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/samplerParameter) */\\n    samplerParameteri(sampler: WebGLSampler, pname: GLenum, param: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/texImage3D) */\\n    texImage3D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, type: GLenum, pboOffset: GLintptr): void;\\n    texImage3D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texImage3D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, type: GLenum, srcData: ArrayBufferView | null): void;\\n    texImage3D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, border: GLint, format: GLenum, type: GLenum, srcData: ArrayBufferView, srcOffset: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/texStorage2D) */\\n    texStorage2D(target: GLenum, levels: GLsizei, internalformat: GLenum, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/texStorage3D) */\\n    texStorage3D(target: GLenum, levels: GLsizei, internalformat: GLenum, width: GLsizei, height: GLsizei, depth: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/texSubImage3D) */\\n    texSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, type: GLenum, pboOffset: GLintptr): void;\\n    texSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texSubImage3D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, zoffset: GLint, width: GLsizei, height: GLsizei, depth: GLsizei, format: GLenum, type: GLenum, srcData: ArrayBufferView | null, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/transformFeedbackVaryings) */\\n    transformFeedbackVaryings(program: WebGLProgram, varyings: string[], bufferMode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform1ui(location: WebGLUniformLocation | null, v0: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform1uiv(location: WebGLUniformLocation | null, data: Uint32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform2ui(location: WebGLUniformLocation | null, v0: GLuint, v1: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform2uiv(location: WebGLUniformLocation | null, data: Uint32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform3ui(location: WebGLUniformLocation | null, v0: GLuint, v1: GLuint, v2: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform3uiv(location: WebGLUniformLocation | null, data: Uint32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform4ui(location: WebGLUniformLocation | null, v0: GLuint, v1: GLuint, v2: GLuint, v3: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform4uiv(location: WebGLUniformLocation | null, data: Uint32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformBlockBinding) */\\n    uniformBlockBinding(program: WebGLProgram, uniformBlockIndex: GLuint, uniformBlockBinding: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix2x3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix2x4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix3x2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix3x4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix4x2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix4x3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribDivisor) */\\n    vertexAttribDivisor(index: GLuint, divisor: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4i(index: GLuint, x: GLint, y: GLint, z: GLint, w: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4iv(index: GLuint, values: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4ui(index: GLuint, x: GLuint, y: GLuint, z: GLuint, w: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4uiv(index: GLuint, values: Uint32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribIPointer) */\\n    vertexAttribIPointer(index: GLuint, size: GLint, type: GLenum, stride: GLsizei, offset: GLintptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/waitSync) */\\n    waitSync(sync: WebGLSync, flags: GLbitfield, timeout: GLint64): void;\\n    readonly READ_BUFFER: 0x0C02;\\n    readonly UNPACK_ROW_LENGTH: 0x0CF2;\\n    readonly UNPACK_SKIP_ROWS: 0x0CF3;\\n    readonly UNPACK_SKIP_PIXELS: 0x0CF4;\\n    readonly PACK_ROW_LENGTH: 0x0D02;\\n    readonly PACK_SKIP_ROWS: 0x0D03;\\n    readonly PACK_SKIP_PIXELS: 0x0D04;\\n    readonly COLOR: 0x1800;\\n    readonly DEPTH: 0x1801;\\n    readonly STENCIL: 0x1802;\\n    readonly RED: 0x1903;\\n    readonly RGB8: 0x8051;\\n    readonly RGBA8: 0x8058;\\n    readonly RGB10_A2: 0x8059;\\n    readonly TEXTURE_BINDING_3D: 0x806A;\\n    readonly UNPACK_SKIP_IMAGES: 0x806D;\\n    readonly UNPACK_IMAGE_HEIGHT: 0x806E;\\n    readonly TEXTURE_3D: 0x806F;\\n    readonly TEXTURE_WRAP_R: 0x8072;\\n    readonly MAX_3D_TEXTURE_SIZE: 0x8073;\\n    readonly UNSIGNED_INT_2_10_10_10_REV: 0x8368;\\n    readonly MAX_ELEMENTS_VERTICES: 0x80E8;\\n    readonly MAX_ELEMENTS_INDICES: 0x80E9;\\n    readonly TEXTURE_MIN_LOD: 0x813A;\\n    readonly TEXTURE_MAX_LOD: 0x813B;\\n    readonly TEXTURE_BASE_LEVEL: 0x813C;\\n    readonly TEXTURE_MAX_LEVEL: 0x813D;\\n    readonly MIN: 0x8007;\\n    readonly MAX: 0x8008;\\n    readonly DEPTH_COMPONENT24: 0x81A6;\\n    readonly MAX_TEXTURE_LOD_BIAS: 0x84FD;\\n    readonly TEXTURE_COMPARE_MODE: 0x884C;\\n    readonly TEXTURE_COMPARE_FUNC: 0x884D;\\n    readonly CURRENT_QUERY: 0x8865;\\n    readonly QUERY_RESULT: 0x8866;\\n    readonly QUERY_RESULT_AVAILABLE: 0x8867;\\n    readonly STREAM_READ: 0x88E1;\\n    readonly STREAM_COPY: 0x88E2;\\n    readonly STATIC_READ: 0x88E5;\\n    readonly STATIC_COPY: 0x88E6;\\n    readonly DYNAMIC_READ: 0x88E9;\\n    readonly DYNAMIC_COPY: 0x88EA;\\n    readonly MAX_DRAW_BUFFERS: 0x8824;\\n    readonly DRAW_BUFFER0: 0x8825;\\n    readonly DRAW_BUFFER1: 0x8826;\\n    readonly DRAW_BUFFER2: 0x8827;\\n    readonly DRAW_BUFFER3: 0x8828;\\n    readonly DRAW_BUFFER4: 0x8829;\\n    readonly DRAW_BUFFER5: 0x882A;\\n    readonly DRAW_BUFFER6: 0x882B;\\n    readonly DRAW_BUFFER7: 0x882C;\\n    readonly DRAW_BUFFER8: 0x882D;\\n    readonly DRAW_BUFFER9: 0x882E;\\n    readonly DRAW_BUFFER10: 0x882F;\\n    readonly DRAW_BUFFER11: 0x8830;\\n    readonly DRAW_BUFFER12: 0x8831;\\n    readonly DRAW_BUFFER13: 0x8832;\\n    readonly DRAW_BUFFER14: 0x8833;\\n    readonly DRAW_BUFFER15: 0x8834;\\n    readonly MAX_FRAGMENT_UNIFORM_COMPONENTS: 0x8B49;\\n    readonly MAX_VERTEX_UNIFORM_COMPONENTS: 0x8B4A;\\n    readonly SAMPLER_3D: 0x8B5F;\\n    readonly SAMPLER_2D_SHADOW: 0x8B62;\\n    readonly FRAGMENT_SHADER_DERIVATIVE_HINT: 0x8B8B;\\n    readonly PIXEL_PACK_BUFFER: 0x88EB;\\n    readonly PIXEL_UNPACK_BUFFER: 0x88EC;\\n    readonly PIXEL_PACK_BUFFER_BINDING: 0x88ED;\\n    readonly PIXEL_UNPACK_BUFFER_BINDING: 0x88EF;\\n    readonly FLOAT_MAT2x3: 0x8B65;\\n    readonly FLOAT_MAT2x4: 0x8B66;\\n    readonly FLOAT_MAT3x2: 0x8B67;\\n    readonly FLOAT_MAT3x4: 0x8B68;\\n    readonly FLOAT_MAT4x2: 0x8B69;\\n    readonly FLOAT_MAT4x3: 0x8B6A;\\n    readonly SRGB: 0x8C40;\\n    readonly SRGB8: 0x8C41;\\n    readonly SRGB8_ALPHA8: 0x8C43;\\n    readonly COMPARE_REF_TO_TEXTURE: 0x884E;\\n    readonly RGBA32F: 0x8814;\\n    readonly RGB32F: 0x8815;\\n    readonly RGBA16F: 0x881A;\\n    readonly RGB16F: 0x881B;\\n    readonly VERTEX_ATTRIB_ARRAY_INTEGER: 0x88FD;\\n    readonly MAX_ARRAY_TEXTURE_LAYERS: 0x88FF;\\n    readonly MIN_PROGRAM_TEXEL_OFFSET: 0x8904;\\n    readonly MAX_PROGRAM_TEXEL_OFFSET: 0x8905;\\n    readonly MAX_VARYING_COMPONENTS: 0x8B4B;\\n    readonly TEXTURE_2D_ARRAY: 0x8C1A;\\n    readonly TEXTURE_BINDING_2D_ARRAY: 0x8C1D;\\n    readonly R11F_G11F_B10F: 0x8C3A;\\n    readonly UNSIGNED_INT_10F_11F_11F_REV: 0x8C3B;\\n    readonly RGB9_E5: 0x8C3D;\\n    readonly UNSIGNED_INT_5_9_9_9_REV: 0x8C3E;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_MODE: 0x8C7F;\\n    readonly MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 0x8C80;\\n    readonly TRANSFORM_FEEDBACK_VARYINGS: 0x8C83;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_START: 0x8C84;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_SIZE: 0x8C85;\\n    readonly TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: 0x8C88;\\n    readonly RASTERIZER_DISCARD: 0x8C89;\\n    readonly MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 0x8C8A;\\n    readonly MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 0x8C8B;\\n    readonly INTERLEAVED_ATTRIBS: 0x8C8C;\\n    readonly SEPARATE_ATTRIBS: 0x8C8D;\\n    readonly TRANSFORM_FEEDBACK_BUFFER: 0x8C8E;\\n    readonly TRANSFORM_FEEDBACK_BUFFER_BINDING: 0x8C8F;\\n    readonly RGBA32UI: 0x8D70;\\n    readonly RGB32UI: 0x8D71;\\n    readonly RGBA16UI: 0x8D76;\\n    readonly RGB16UI: 0x8D77;\\n    readonly RGBA8UI: 0x8D7C;\\n    readonly RGB8UI: 0x8D7D;\\n    readonly RGBA32I: 0x8D82;\\n    readonly RGB32I: 0x8D83;\\n    readonly RGBA16I: 0x8D88;\\n    readonly RGB16I: 0x8D89;\\n    readonly RGBA8I: 0x8D8E;\\n    readonly RGB8I: 0x8D8F;\\n    readonly RED_INTEGER: 0x8D94;\\n    readonly RGB_INTEGER: 0x8D98;\\n    readonly RGBA_INTEGER: 0x8D99;\\n    readonly SAMPLER_2D_ARRAY: 0x8DC1;\\n    readonly SAMPLER_2D_ARRAY_SHADOW: 0x8DC4;\\n    readonly SAMPLER_CUBE_SHADOW: 0x8DC5;\\n    readonly UNSIGNED_INT_VEC2: 0x8DC6;\\n    readonly UNSIGNED_INT_VEC3: 0x8DC7;\\n    readonly UNSIGNED_INT_VEC4: 0x8DC8;\\n    readonly INT_SAMPLER_2D: 0x8DCA;\\n    readonly INT_SAMPLER_3D: 0x8DCB;\\n    readonly INT_SAMPLER_CUBE: 0x8DCC;\\n    readonly INT_SAMPLER_2D_ARRAY: 0x8DCF;\\n    readonly UNSIGNED_INT_SAMPLER_2D: 0x8DD2;\\n    readonly UNSIGNED_INT_SAMPLER_3D: 0x8DD3;\\n    readonly UNSIGNED_INT_SAMPLER_CUBE: 0x8DD4;\\n    readonly UNSIGNED_INT_SAMPLER_2D_ARRAY: 0x8DD7;\\n    readonly DEPTH_COMPONENT32F: 0x8CAC;\\n    readonly DEPTH32F_STENCIL8: 0x8CAD;\\n    readonly FLOAT_32_UNSIGNED_INT_24_8_REV: 0x8DAD;\\n    readonly FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: 0x8210;\\n    readonly FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: 0x8211;\\n    readonly FRAMEBUFFER_ATTACHMENT_RED_SIZE: 0x8212;\\n    readonly FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 0x8213;\\n    readonly FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 0x8214;\\n    readonly FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 0x8215;\\n    readonly FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 0x8216;\\n    readonly FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 0x8217;\\n    readonly FRAMEBUFFER_DEFAULT: 0x8218;\\n    readonly UNSIGNED_INT_24_8: 0x84FA;\\n    readonly DEPTH24_STENCIL8: 0x88F0;\\n    readonly UNSIGNED_NORMALIZED: 0x8C17;\\n    readonly DRAW_FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly READ_FRAMEBUFFER: 0x8CA8;\\n    readonly DRAW_FRAMEBUFFER: 0x8CA9;\\n    readonly READ_FRAMEBUFFER_BINDING: 0x8CAA;\\n    readonly RENDERBUFFER_SAMPLES: 0x8CAB;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: 0x8CD4;\\n    readonly MAX_COLOR_ATTACHMENTS: 0x8CDF;\\n    readonly COLOR_ATTACHMENT1: 0x8CE1;\\n    readonly COLOR_ATTACHMENT2: 0x8CE2;\\n    readonly COLOR_ATTACHMENT3: 0x8CE3;\\n    readonly COLOR_ATTACHMENT4: 0x8CE4;\\n    readonly COLOR_ATTACHMENT5: 0x8CE5;\\n    readonly COLOR_ATTACHMENT6: 0x8CE6;\\n    readonly COLOR_ATTACHMENT7: 0x8CE7;\\n    readonly COLOR_ATTACHMENT8: 0x8CE8;\\n    readonly COLOR_ATTACHMENT9: 0x8CE9;\\n    readonly COLOR_ATTACHMENT10: 0x8CEA;\\n    readonly COLOR_ATTACHMENT11: 0x8CEB;\\n    readonly COLOR_ATTACHMENT12: 0x8CEC;\\n    readonly COLOR_ATTACHMENT13: 0x8CED;\\n    readonly COLOR_ATTACHMENT14: 0x8CEE;\\n    readonly COLOR_ATTACHMENT15: 0x8CEF;\\n    readonly FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: 0x8D56;\\n    readonly MAX_SAMPLES: 0x8D57;\\n    readonly HALF_FLOAT: 0x140B;\\n    readonly RG: 0x8227;\\n    readonly RG_INTEGER: 0x8228;\\n    readonly R8: 0x8229;\\n    readonly RG8: 0x822B;\\n    readonly R16F: 0x822D;\\n    readonly R32F: 0x822E;\\n    readonly RG16F: 0x822F;\\n    readonly RG32F: 0x8230;\\n    readonly R8I: 0x8231;\\n    readonly R8UI: 0x8232;\\n    readonly R16I: 0x8233;\\n    readonly R16UI: 0x8234;\\n    readonly R32I: 0x8235;\\n    readonly R32UI: 0x8236;\\n    readonly RG8I: 0x8237;\\n    readonly RG8UI: 0x8238;\\n    readonly RG16I: 0x8239;\\n    readonly RG16UI: 0x823A;\\n    readonly RG32I: 0x823B;\\n    readonly RG32UI: 0x823C;\\n    readonly VERTEX_ARRAY_BINDING: 0x85B5;\\n    readonly R8_SNORM: 0x8F94;\\n    readonly RG8_SNORM: 0x8F95;\\n    readonly RGB8_SNORM: 0x8F96;\\n    readonly RGBA8_SNORM: 0x8F97;\\n    readonly SIGNED_NORMALIZED: 0x8F9C;\\n    readonly COPY_READ_BUFFER: 0x8F36;\\n    readonly COPY_WRITE_BUFFER: 0x8F37;\\n    readonly COPY_READ_BUFFER_BINDING: 0x8F36;\\n    readonly COPY_WRITE_BUFFER_BINDING: 0x8F37;\\n    readonly UNIFORM_BUFFER: 0x8A11;\\n    readonly UNIFORM_BUFFER_BINDING: 0x8A28;\\n    readonly UNIFORM_BUFFER_START: 0x8A29;\\n    readonly UNIFORM_BUFFER_SIZE: 0x8A2A;\\n    readonly MAX_VERTEX_UNIFORM_BLOCKS: 0x8A2B;\\n    readonly MAX_FRAGMENT_UNIFORM_BLOCKS: 0x8A2D;\\n    readonly MAX_COMBINED_UNIFORM_BLOCKS: 0x8A2E;\\n    readonly MAX_UNIFORM_BUFFER_BINDINGS: 0x8A2F;\\n    readonly MAX_UNIFORM_BLOCK_SIZE: 0x8A30;\\n    readonly MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 0x8A31;\\n    readonly MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 0x8A33;\\n    readonly UNIFORM_BUFFER_OFFSET_ALIGNMENT: 0x8A34;\\n    readonly ACTIVE_UNIFORM_BLOCKS: 0x8A36;\\n    readonly UNIFORM_TYPE: 0x8A37;\\n    readonly UNIFORM_SIZE: 0x8A38;\\n    readonly UNIFORM_BLOCK_INDEX: 0x8A3A;\\n    readonly UNIFORM_OFFSET: 0x8A3B;\\n    readonly UNIFORM_ARRAY_STRIDE: 0x8A3C;\\n    readonly UNIFORM_MATRIX_STRIDE: 0x8A3D;\\n    readonly UNIFORM_IS_ROW_MAJOR: 0x8A3E;\\n    readonly UNIFORM_BLOCK_BINDING: 0x8A3F;\\n    readonly UNIFORM_BLOCK_DATA_SIZE: 0x8A40;\\n    readonly UNIFORM_BLOCK_ACTIVE_UNIFORMS: 0x8A42;\\n    readonly UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 0x8A43;\\n    readonly UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 0x8A44;\\n    readonly UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 0x8A46;\\n    readonly INVALID_INDEX: 0xFFFFFFFF;\\n    readonly MAX_VERTEX_OUTPUT_COMPONENTS: 0x9122;\\n    readonly MAX_FRAGMENT_INPUT_COMPONENTS: 0x9125;\\n    readonly MAX_SERVER_WAIT_TIMEOUT: 0x9111;\\n    readonly OBJECT_TYPE: 0x9112;\\n    readonly SYNC_CONDITION: 0x9113;\\n    readonly SYNC_STATUS: 0x9114;\\n    readonly SYNC_FLAGS: 0x9115;\\n    readonly SYNC_FENCE: 0x9116;\\n    readonly SYNC_GPU_COMMANDS_COMPLETE: 0x9117;\\n    readonly UNSIGNALED: 0x9118;\\n    readonly SIGNALED: 0x9119;\\n    readonly ALREADY_SIGNALED: 0x911A;\\n    readonly TIMEOUT_EXPIRED: 0x911B;\\n    readonly CONDITION_SATISFIED: 0x911C;\\n    readonly WAIT_FAILED: 0x911D;\\n    readonly SYNC_FLUSH_COMMANDS_BIT: 0x00000001;\\n    readonly VERTEX_ATTRIB_ARRAY_DIVISOR: 0x88FE;\\n    readonly ANY_SAMPLES_PASSED: 0x8C2F;\\n    readonly ANY_SAMPLES_PASSED_CONSERVATIVE: 0x8D6A;\\n    readonly SAMPLER_BINDING: 0x8919;\\n    readonly RGB10_A2UI: 0x906F;\\n    readonly INT_2_10_10_10_REV: 0x8D9F;\\n    readonly TRANSFORM_FEEDBACK: 0x8E22;\\n    readonly TRANSFORM_FEEDBACK_PAUSED: 0x8E23;\\n    readonly TRANSFORM_FEEDBACK_ACTIVE: 0x8E24;\\n    readonly TRANSFORM_FEEDBACK_BINDING: 0x8E25;\\n    readonly TEXTURE_IMMUTABLE_FORMAT: 0x912F;\\n    readonly MAX_ELEMENT_INDEX: 0x8D6B;\\n    readonly TEXTURE_IMMUTABLE_LEVELS: 0x82DF;\\n    readonly TIMEOUT_IGNORED: -1;\\n    readonly MAX_CLIENT_WAIT_TIMEOUT_WEBGL: 0x9247;\\n}\\n\\ninterface WebGL2RenderingContextOverloads {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bufferData) */\\n    bufferData(target: GLenum, size: GLsizeiptr, usage: GLenum): void;\\n    bufferData(target: GLenum, srcData: BufferSource | null, usage: GLenum): void;\\n    bufferData(target: GLenum, srcData: ArrayBufferView, usage: GLenum, srcOffset: GLuint, length?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bufferSubData) */\\n    bufferSubData(target: GLenum, dstByteOffset: GLintptr, srcData: BufferSource): void;\\n    bufferSubData(target: GLenum, dstByteOffset: GLintptr, srcData: ArrayBufferView, srcOffset: GLuint, length?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compressedTexImage2D) */\\n    compressedTexImage2D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, imageSize: GLsizei, offset: GLintptr): void;\\n    compressedTexImage2D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, srcData: ArrayBufferView, srcOffset?: GLuint, srcLengthOverride?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compressedTexSubImage2D) */\\n    compressedTexSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, imageSize: GLsizei, offset: GLintptr): void;\\n    compressedTexSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, srcData: ArrayBufferView, srcOffset?: GLuint, srcLengthOverride?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/readPixels) */\\n    readPixels(x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, dstData: ArrayBufferView | null): void;\\n    readPixels(x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, offset: GLintptr): void;\\n    readPixels(x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, dstData: ArrayBufferView, dstOffset: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texImage2D) */\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, pboOffset: GLintptr): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, srcData: ArrayBufferView, srcOffset: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texSubImage2D) */\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pboOffset: GLintptr): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, srcData: ArrayBufferView, srcOffset: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1fv(location: WebGLUniformLocation | null, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1iv(location: WebGLUniformLocation | null, data: Int32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2fv(location: WebGLUniformLocation | null, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2iv(location: WebGLUniformLocation | null, data: Int32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3fv(location: WebGLUniformLocation | null, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3iv(location: WebGLUniformLocation | null, data: Int32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4fv(location: WebGLUniformLocation | null, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4iv(location: WebGLUniformLocation | null, data: Int32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Float32List, srcOffset?: GLuint, srcLength?: GLuint): void;\\n}\\n\\n/**\\n * Part of the WebGL API and represents the information returned by calling the WebGLRenderingContext.getActiveAttrib() and WebGLRenderingContext.getActiveUniform() methods.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLActiveInfo)\\n */\\ninterface WebGLActiveInfo {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLActiveInfo/name) */\\n    readonly name: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLActiveInfo/size) */\\n    readonly size: GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLActiveInfo/type) */\\n    readonly type: GLenum;\\n}\\n\\ndeclare var WebGLActiveInfo: {\\n    prototype: WebGLActiveInfo;\\n    new(): WebGLActiveInfo;\\n};\\n\\n/**\\n * Part of the WebGL API and represents an opaque buffer object storing data such as vertices or colors.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLBuffer)\\n */\\ninterface WebGLBuffer {\\n}\\n\\ndeclare var WebGLBuffer: {\\n    prototype: WebGLBuffer;\\n    new(): WebGLBuffer;\\n};\\n\\n/**\\n * The WebContextEvent interface is part of the WebGL API and is an interface for an event that is generated in response to a status change to the WebGL rendering context.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLContextEvent)\\n */\\ninterface WebGLContextEvent extends Event {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLContextEvent/statusMessage) */\\n    readonly statusMessage: string;\\n}\\n\\ndeclare var WebGLContextEvent: {\\n    prototype: WebGLContextEvent;\\n    new(type: string, eventInit?: WebGLContextEventInit): WebGLContextEvent;\\n};\\n\\n/**\\n * Part of the WebGL API and represents a collection of buffers that serve as a rendering destination.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLFramebuffer)\\n */\\ninterface WebGLFramebuffer {\\n}\\n\\ndeclare var WebGLFramebuffer: {\\n    prototype: WebGLFramebuffer;\\n    new(): WebGLFramebuffer;\\n};\\n\\n/**\\n * The WebGLProgram is part of the WebGL API and is a combination of two compiled WebGLShaders consisting of a vertex shader and a fragment shader (both written in GLSL).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLProgram)\\n */\\ninterface WebGLProgram {\\n}\\n\\ndeclare var WebGLProgram: {\\n    prototype: WebGLProgram;\\n    new(): WebGLProgram;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLQuery) */\\ninterface WebGLQuery {\\n}\\n\\ndeclare var WebGLQuery: {\\n    prototype: WebGLQuery;\\n    new(): WebGLQuery;\\n};\\n\\n/**\\n * Part of the WebGL API and represents a buffer that can contain an image, or can be source or target of an rendering operation.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderbuffer)\\n */\\ninterface WebGLRenderbuffer {\\n}\\n\\ndeclare var WebGLRenderbuffer: {\\n    prototype: WebGLRenderbuffer;\\n    new(): WebGLRenderbuffer;\\n};\\n\\n/**\\n * Provides an interface to the OpenGL ES 2.0 graphics rendering context for the drawing surface of an HTML <canvas> element.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext)\\n */\\ninterface WebGLRenderingContext extends WebGLRenderingContextBase, WebGLRenderingContextOverloads {\\n}\\n\\ndeclare var WebGLRenderingContext: {\\n    prototype: WebGLRenderingContext;\\n    new(): WebGLRenderingContext;\\n    readonly DEPTH_BUFFER_BIT: 0x00000100;\\n    readonly STENCIL_BUFFER_BIT: 0x00000400;\\n    readonly COLOR_BUFFER_BIT: 0x00004000;\\n    readonly POINTS: 0x0000;\\n    readonly LINES: 0x0001;\\n    readonly LINE_LOOP: 0x0002;\\n    readonly LINE_STRIP: 0x0003;\\n    readonly TRIANGLES: 0x0004;\\n    readonly TRIANGLE_STRIP: 0x0005;\\n    readonly TRIANGLE_FAN: 0x0006;\\n    readonly ZERO: 0;\\n    readonly ONE: 1;\\n    readonly SRC_COLOR: 0x0300;\\n    readonly ONE_MINUS_SRC_COLOR: 0x0301;\\n    readonly SRC_ALPHA: 0x0302;\\n    readonly ONE_MINUS_SRC_ALPHA: 0x0303;\\n    readonly DST_ALPHA: 0x0304;\\n    readonly ONE_MINUS_DST_ALPHA: 0x0305;\\n    readonly DST_COLOR: 0x0306;\\n    readonly ONE_MINUS_DST_COLOR: 0x0307;\\n    readonly SRC_ALPHA_SATURATE: 0x0308;\\n    readonly FUNC_ADD: 0x8006;\\n    readonly BLEND_EQUATION: 0x8009;\\n    readonly BLEND_EQUATION_RGB: 0x8009;\\n    readonly BLEND_EQUATION_ALPHA: 0x883D;\\n    readonly FUNC_SUBTRACT: 0x800A;\\n    readonly FUNC_REVERSE_SUBTRACT: 0x800B;\\n    readonly BLEND_DST_RGB: 0x80C8;\\n    readonly BLEND_SRC_RGB: 0x80C9;\\n    readonly BLEND_DST_ALPHA: 0x80CA;\\n    readonly BLEND_SRC_ALPHA: 0x80CB;\\n    readonly CONSTANT_COLOR: 0x8001;\\n    readonly ONE_MINUS_CONSTANT_COLOR: 0x8002;\\n    readonly CONSTANT_ALPHA: 0x8003;\\n    readonly ONE_MINUS_CONSTANT_ALPHA: 0x8004;\\n    readonly BLEND_COLOR: 0x8005;\\n    readonly ARRAY_BUFFER: 0x8892;\\n    readonly ELEMENT_ARRAY_BUFFER: 0x8893;\\n    readonly ARRAY_BUFFER_BINDING: 0x8894;\\n    readonly ELEMENT_ARRAY_BUFFER_BINDING: 0x8895;\\n    readonly STREAM_DRAW: 0x88E0;\\n    readonly STATIC_DRAW: 0x88E4;\\n    readonly DYNAMIC_DRAW: 0x88E8;\\n    readonly BUFFER_SIZE: 0x8764;\\n    readonly BUFFER_USAGE: 0x8765;\\n    readonly CURRENT_VERTEX_ATTRIB: 0x8626;\\n    readonly FRONT: 0x0404;\\n    readonly BACK: 0x0405;\\n    readonly FRONT_AND_BACK: 0x0408;\\n    readonly CULL_FACE: 0x0B44;\\n    readonly BLEND: 0x0BE2;\\n    readonly DITHER: 0x0BD0;\\n    readonly STENCIL_TEST: 0x0B90;\\n    readonly DEPTH_TEST: 0x0B71;\\n    readonly SCISSOR_TEST: 0x0C11;\\n    readonly POLYGON_OFFSET_FILL: 0x8037;\\n    readonly SAMPLE_ALPHA_TO_COVERAGE: 0x809E;\\n    readonly SAMPLE_COVERAGE: 0x80A0;\\n    readonly NO_ERROR: 0;\\n    readonly INVALID_ENUM: 0x0500;\\n    readonly INVALID_VALUE: 0x0501;\\n    readonly INVALID_OPERATION: 0x0502;\\n    readonly OUT_OF_MEMORY: 0x0505;\\n    readonly CW: 0x0900;\\n    readonly CCW: 0x0901;\\n    readonly LINE_WIDTH: 0x0B21;\\n    readonly ALIASED_POINT_SIZE_RANGE: 0x846D;\\n    readonly ALIASED_LINE_WIDTH_RANGE: 0x846E;\\n    readonly CULL_FACE_MODE: 0x0B45;\\n    readonly FRONT_FACE: 0x0B46;\\n    readonly DEPTH_RANGE: 0x0B70;\\n    readonly DEPTH_WRITEMASK: 0x0B72;\\n    readonly DEPTH_CLEAR_VALUE: 0x0B73;\\n    readonly DEPTH_FUNC: 0x0B74;\\n    readonly STENCIL_CLEAR_VALUE: 0x0B91;\\n    readonly STENCIL_FUNC: 0x0B92;\\n    readonly STENCIL_FAIL: 0x0B94;\\n    readonly STENCIL_PASS_DEPTH_FAIL: 0x0B95;\\n    readonly STENCIL_PASS_DEPTH_PASS: 0x0B96;\\n    readonly STENCIL_REF: 0x0B97;\\n    readonly STENCIL_VALUE_MASK: 0x0B93;\\n    readonly STENCIL_WRITEMASK: 0x0B98;\\n    readonly STENCIL_BACK_FUNC: 0x8800;\\n    readonly STENCIL_BACK_FAIL: 0x8801;\\n    readonly STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802;\\n    readonly STENCIL_BACK_PASS_DEPTH_PASS: 0x8803;\\n    readonly STENCIL_BACK_REF: 0x8CA3;\\n    readonly STENCIL_BACK_VALUE_MASK: 0x8CA4;\\n    readonly STENCIL_BACK_WRITEMASK: 0x8CA5;\\n    readonly VIEWPORT: 0x0BA2;\\n    readonly SCISSOR_BOX: 0x0C10;\\n    readonly COLOR_CLEAR_VALUE: 0x0C22;\\n    readonly COLOR_WRITEMASK: 0x0C23;\\n    readonly UNPACK_ALIGNMENT: 0x0CF5;\\n    readonly PACK_ALIGNMENT: 0x0D05;\\n    readonly MAX_TEXTURE_SIZE: 0x0D33;\\n    readonly MAX_VIEWPORT_DIMS: 0x0D3A;\\n    readonly SUBPIXEL_BITS: 0x0D50;\\n    readonly RED_BITS: 0x0D52;\\n    readonly GREEN_BITS: 0x0D53;\\n    readonly BLUE_BITS: 0x0D54;\\n    readonly ALPHA_BITS: 0x0D55;\\n    readonly DEPTH_BITS: 0x0D56;\\n    readonly STENCIL_BITS: 0x0D57;\\n    readonly POLYGON_OFFSET_UNITS: 0x2A00;\\n    readonly POLYGON_OFFSET_FACTOR: 0x8038;\\n    readonly TEXTURE_BINDING_2D: 0x8069;\\n    readonly SAMPLE_BUFFERS: 0x80A8;\\n    readonly SAMPLES: 0x80A9;\\n    readonly SAMPLE_COVERAGE_VALUE: 0x80AA;\\n    readonly SAMPLE_COVERAGE_INVERT: 0x80AB;\\n    readonly COMPRESSED_TEXTURE_FORMATS: 0x86A3;\\n    readonly DONT_CARE: 0x1100;\\n    readonly FASTEST: 0x1101;\\n    readonly NICEST: 0x1102;\\n    readonly GENERATE_MIPMAP_HINT: 0x8192;\\n    readonly BYTE: 0x1400;\\n    readonly UNSIGNED_BYTE: 0x1401;\\n    readonly SHORT: 0x1402;\\n    readonly UNSIGNED_SHORT: 0x1403;\\n    readonly INT: 0x1404;\\n    readonly UNSIGNED_INT: 0x1405;\\n    readonly FLOAT: 0x1406;\\n    readonly DEPTH_COMPONENT: 0x1902;\\n    readonly ALPHA: 0x1906;\\n    readonly RGB: 0x1907;\\n    readonly RGBA: 0x1908;\\n    readonly LUMINANCE: 0x1909;\\n    readonly LUMINANCE_ALPHA: 0x190A;\\n    readonly UNSIGNED_SHORT_4_4_4_4: 0x8033;\\n    readonly UNSIGNED_SHORT_5_5_5_1: 0x8034;\\n    readonly UNSIGNED_SHORT_5_6_5: 0x8363;\\n    readonly FRAGMENT_SHADER: 0x8B30;\\n    readonly VERTEX_SHADER: 0x8B31;\\n    readonly MAX_VERTEX_ATTRIBS: 0x8869;\\n    readonly MAX_VERTEX_UNIFORM_VECTORS: 0x8DFB;\\n    readonly MAX_VARYING_VECTORS: 0x8DFC;\\n    readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8B4D;\\n    readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8B4C;\\n    readonly MAX_TEXTURE_IMAGE_UNITS: 0x8872;\\n    readonly MAX_FRAGMENT_UNIFORM_VECTORS: 0x8DFD;\\n    readonly SHADER_TYPE: 0x8B4F;\\n    readonly DELETE_STATUS: 0x8B80;\\n    readonly LINK_STATUS: 0x8B82;\\n    readonly VALIDATE_STATUS: 0x8B83;\\n    readonly ATTACHED_SHADERS: 0x8B85;\\n    readonly ACTIVE_UNIFORMS: 0x8B86;\\n    readonly ACTIVE_ATTRIBUTES: 0x8B89;\\n    readonly SHADING_LANGUAGE_VERSION: 0x8B8C;\\n    readonly CURRENT_PROGRAM: 0x8B8D;\\n    readonly NEVER: 0x0200;\\n    readonly LESS: 0x0201;\\n    readonly EQUAL: 0x0202;\\n    readonly LEQUAL: 0x0203;\\n    readonly GREATER: 0x0204;\\n    readonly NOTEQUAL: 0x0205;\\n    readonly GEQUAL: 0x0206;\\n    readonly ALWAYS: 0x0207;\\n    readonly KEEP: 0x1E00;\\n    readonly REPLACE: 0x1E01;\\n    readonly INCR: 0x1E02;\\n    readonly DECR: 0x1E03;\\n    readonly INVERT: 0x150A;\\n    readonly INCR_WRAP: 0x8507;\\n    readonly DECR_WRAP: 0x8508;\\n    readonly VENDOR: 0x1F00;\\n    readonly RENDERER: 0x1F01;\\n    readonly VERSION: 0x1F02;\\n    readonly NEAREST: 0x2600;\\n    readonly LINEAR: 0x2601;\\n    readonly NEAREST_MIPMAP_NEAREST: 0x2700;\\n    readonly LINEAR_MIPMAP_NEAREST: 0x2701;\\n    readonly NEAREST_MIPMAP_LINEAR: 0x2702;\\n    readonly LINEAR_MIPMAP_LINEAR: 0x2703;\\n    readonly TEXTURE_MAG_FILTER: 0x2800;\\n    readonly TEXTURE_MIN_FILTER: 0x2801;\\n    readonly TEXTURE_WRAP_S: 0x2802;\\n    readonly TEXTURE_WRAP_T: 0x2803;\\n    readonly TEXTURE_2D: 0x0DE1;\\n    readonly TEXTURE: 0x1702;\\n    readonly TEXTURE_CUBE_MAP: 0x8513;\\n    readonly TEXTURE_BINDING_CUBE_MAP: 0x8514;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851A;\\n    readonly MAX_CUBE_MAP_TEXTURE_SIZE: 0x851C;\\n    readonly TEXTURE0: 0x84C0;\\n    readonly TEXTURE1: 0x84C1;\\n    readonly TEXTURE2: 0x84C2;\\n    readonly TEXTURE3: 0x84C3;\\n    readonly TEXTURE4: 0x84C4;\\n    readonly TEXTURE5: 0x84C5;\\n    readonly TEXTURE6: 0x84C6;\\n    readonly TEXTURE7: 0x84C7;\\n    readonly TEXTURE8: 0x84C8;\\n    readonly TEXTURE9: 0x84C9;\\n    readonly TEXTURE10: 0x84CA;\\n    readonly TEXTURE11: 0x84CB;\\n    readonly TEXTURE12: 0x84CC;\\n    readonly TEXTURE13: 0x84CD;\\n    readonly TEXTURE14: 0x84CE;\\n    readonly TEXTURE15: 0x84CF;\\n    readonly TEXTURE16: 0x84D0;\\n    readonly TEXTURE17: 0x84D1;\\n    readonly TEXTURE18: 0x84D2;\\n    readonly TEXTURE19: 0x84D3;\\n    readonly TEXTURE20: 0x84D4;\\n    readonly TEXTURE21: 0x84D5;\\n    readonly TEXTURE22: 0x84D6;\\n    readonly TEXTURE23: 0x84D7;\\n    readonly TEXTURE24: 0x84D8;\\n    readonly TEXTURE25: 0x84D9;\\n    readonly TEXTURE26: 0x84DA;\\n    readonly TEXTURE27: 0x84DB;\\n    readonly TEXTURE28: 0x84DC;\\n    readonly TEXTURE29: 0x84DD;\\n    readonly TEXTURE30: 0x84DE;\\n    readonly TEXTURE31: 0x84DF;\\n    readonly ACTIVE_TEXTURE: 0x84E0;\\n    readonly REPEAT: 0x2901;\\n    readonly CLAMP_TO_EDGE: 0x812F;\\n    readonly MIRRORED_REPEAT: 0x8370;\\n    readonly FLOAT_VEC2: 0x8B50;\\n    readonly FLOAT_VEC3: 0x8B51;\\n    readonly FLOAT_VEC4: 0x8B52;\\n    readonly INT_VEC2: 0x8B53;\\n    readonly INT_VEC3: 0x8B54;\\n    readonly INT_VEC4: 0x8B55;\\n    readonly BOOL: 0x8B56;\\n    readonly BOOL_VEC2: 0x8B57;\\n    readonly BOOL_VEC3: 0x8B58;\\n    readonly BOOL_VEC4: 0x8B59;\\n    readonly FLOAT_MAT2: 0x8B5A;\\n    readonly FLOAT_MAT3: 0x8B5B;\\n    readonly FLOAT_MAT4: 0x8B5C;\\n    readonly SAMPLER_2D: 0x8B5E;\\n    readonly SAMPLER_CUBE: 0x8B60;\\n    readonly VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622;\\n    readonly VERTEX_ATTRIB_ARRAY_SIZE: 0x8623;\\n    readonly VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624;\\n    readonly VERTEX_ATTRIB_ARRAY_TYPE: 0x8625;\\n    readonly VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886A;\\n    readonly VERTEX_ATTRIB_ARRAY_POINTER: 0x8645;\\n    readonly VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889F;\\n    readonly IMPLEMENTATION_COLOR_READ_TYPE: 0x8B9A;\\n    readonly IMPLEMENTATION_COLOR_READ_FORMAT: 0x8B9B;\\n    readonly COMPILE_STATUS: 0x8B81;\\n    readonly LOW_FLOAT: 0x8DF0;\\n    readonly MEDIUM_FLOAT: 0x8DF1;\\n    readonly HIGH_FLOAT: 0x8DF2;\\n    readonly LOW_INT: 0x8DF3;\\n    readonly MEDIUM_INT: 0x8DF4;\\n    readonly HIGH_INT: 0x8DF5;\\n    readonly FRAMEBUFFER: 0x8D40;\\n    readonly RENDERBUFFER: 0x8D41;\\n    readonly RGBA4: 0x8056;\\n    readonly RGB5_A1: 0x8057;\\n    readonly RGB565: 0x8D62;\\n    readonly DEPTH_COMPONENT16: 0x81A5;\\n    readonly STENCIL_INDEX8: 0x8D48;\\n    readonly DEPTH_STENCIL: 0x84F9;\\n    readonly RENDERBUFFER_WIDTH: 0x8D42;\\n    readonly RENDERBUFFER_HEIGHT: 0x8D43;\\n    readonly RENDERBUFFER_INTERNAL_FORMAT: 0x8D44;\\n    readonly RENDERBUFFER_RED_SIZE: 0x8D50;\\n    readonly RENDERBUFFER_GREEN_SIZE: 0x8D51;\\n    readonly RENDERBUFFER_BLUE_SIZE: 0x8D52;\\n    readonly RENDERBUFFER_ALPHA_SIZE: 0x8D53;\\n    readonly RENDERBUFFER_DEPTH_SIZE: 0x8D54;\\n    readonly RENDERBUFFER_STENCIL_SIZE: 0x8D55;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8CD0;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8CD1;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8CD2;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8CD3;\\n    readonly COLOR_ATTACHMENT0: 0x8CE0;\\n    readonly DEPTH_ATTACHMENT: 0x8D00;\\n    readonly STENCIL_ATTACHMENT: 0x8D20;\\n    readonly DEPTH_STENCIL_ATTACHMENT: 0x821A;\\n    readonly NONE: 0;\\n    readonly FRAMEBUFFER_COMPLETE: 0x8CD5;\\n    readonly FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8CD6;\\n    readonly FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8CD7;\\n    readonly FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8CD9;\\n    readonly FRAMEBUFFER_UNSUPPORTED: 0x8CDD;\\n    readonly FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly RENDERBUFFER_BINDING: 0x8CA7;\\n    readonly MAX_RENDERBUFFER_SIZE: 0x84E8;\\n    readonly INVALID_FRAMEBUFFER_OPERATION: 0x0506;\\n    readonly UNPACK_FLIP_Y_WEBGL: 0x9240;\\n    readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241;\\n    readonly CONTEXT_LOST_WEBGL: 0x9242;\\n    readonly UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243;\\n    readonly BROWSER_DEFAULT_WEBGL: 0x9244;\\n};\\n\\ninterface WebGLRenderingContextBase {\\n    drawingBufferColorSpace: PredefinedColorSpace;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/drawingBufferHeight) */\\n    readonly drawingBufferHeight: GLsizei;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/drawingBufferWidth) */\\n    readonly drawingBufferWidth: GLsizei;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/activeTexture) */\\n    activeTexture(texture: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/attachShader) */\\n    attachShader(program: WebGLProgram, shader: WebGLShader): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindAttribLocation) */\\n    bindAttribLocation(program: WebGLProgram, index: GLuint, name: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindBuffer) */\\n    bindBuffer(target: GLenum, buffer: WebGLBuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindFramebuffer) */\\n    bindFramebuffer(target: GLenum, framebuffer: WebGLFramebuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindRenderbuffer) */\\n    bindRenderbuffer(target: GLenum, renderbuffer: WebGLRenderbuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bindTexture) */\\n    bindTexture(target: GLenum, texture: WebGLTexture | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendColor) */\\n    blendColor(red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendEquation) */\\n    blendEquation(mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendEquationSeparate) */\\n    blendEquationSeparate(modeRGB: GLenum, modeAlpha: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendFunc) */\\n    blendFunc(sfactor: GLenum, dfactor: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/blendFuncSeparate) */\\n    blendFuncSeparate(srcRGB: GLenum, dstRGB: GLenum, srcAlpha: GLenum, dstAlpha: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/checkFramebufferStatus) */\\n    checkFramebufferStatus(target: GLenum): GLenum;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/clear) */\\n    clear(mask: GLbitfield): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/clearColor) */\\n    clearColor(red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/clearDepth) */\\n    clearDepth(depth: GLclampf): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/clearStencil) */\\n    clearStencil(s: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/colorMask) */\\n    colorMask(red: GLboolean, green: GLboolean, blue: GLboolean, alpha: GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compileShader) */\\n    compileShader(shader: WebGLShader): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/copyTexImage2D) */\\n    copyTexImage2D(target: GLenum, level: GLint, internalformat: GLenum, x: GLint, y: GLint, width: GLsizei, height: GLsizei, border: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/copyTexSubImage2D) */\\n    copyTexSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createBuffer) */\\n    createBuffer(): WebGLBuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createFramebuffer) */\\n    createFramebuffer(): WebGLFramebuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createProgram) */\\n    createProgram(): WebGLProgram | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createRenderbuffer) */\\n    createRenderbuffer(): WebGLRenderbuffer | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createShader) */\\n    createShader(type: GLenum): WebGLShader | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/createTexture) */\\n    createTexture(): WebGLTexture | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/cullFace) */\\n    cullFace(mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteBuffer) */\\n    deleteBuffer(buffer: WebGLBuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteFramebuffer) */\\n    deleteFramebuffer(framebuffer: WebGLFramebuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteProgram) */\\n    deleteProgram(program: WebGLProgram | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteRenderbuffer) */\\n    deleteRenderbuffer(renderbuffer: WebGLRenderbuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteShader) */\\n    deleteShader(shader: WebGLShader | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/deleteTexture) */\\n    deleteTexture(texture: WebGLTexture | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/depthFunc) */\\n    depthFunc(func: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/depthMask) */\\n    depthMask(flag: GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/depthRange) */\\n    depthRange(zNear: GLclampf, zFar: GLclampf): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/detachShader) */\\n    detachShader(program: WebGLProgram, shader: WebGLShader): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/disable) */\\n    disable(cap: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/disableVertexAttribArray) */\\n    disableVertexAttribArray(index: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/drawArrays) */\\n    drawArrays(mode: GLenum, first: GLint, count: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/drawElements) */\\n    drawElements(mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/enable) */\\n    enable(cap: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/enableVertexAttribArray) */\\n    enableVertexAttribArray(index: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/finish) */\\n    finish(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/flush) */\\n    flush(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/framebufferRenderbuffer) */\\n    framebufferRenderbuffer(target: GLenum, attachment: GLenum, renderbuffertarget: GLenum, renderbuffer: WebGLRenderbuffer | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/framebufferTexture2D) */\\n    framebufferTexture2D(target: GLenum, attachment: GLenum, textarget: GLenum, texture: WebGLTexture | null, level: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/frontFace) */\\n    frontFace(mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/generateMipmap) */\\n    generateMipmap(target: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getActiveAttrib) */\\n    getActiveAttrib(program: WebGLProgram, index: GLuint): WebGLActiveInfo | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getActiveUniform) */\\n    getActiveUniform(program: WebGLProgram, index: GLuint): WebGLActiveInfo | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getAttachedShaders) */\\n    getAttachedShaders(program: WebGLProgram): WebGLShader[] | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getAttribLocation) */\\n    getAttribLocation(program: WebGLProgram, name: string): GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getBufferParameter) */\\n    getBufferParameter(target: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getContextAttributes) */\\n    getContextAttributes(): WebGLContextAttributes | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getError) */\\n    getError(): GLenum;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getExtension) */\\n    getExtension(extensionName: \\\"ANGLE_instanced_arrays\\\"): ANGLE_instanced_arrays | null;\\n    getExtension(extensionName: \\\"EXT_blend_minmax\\\"): EXT_blend_minmax | null;\\n    getExtension(extensionName: \\\"EXT_color_buffer_float\\\"): EXT_color_buffer_float | null;\\n    getExtension(extensionName: \\\"EXT_color_buffer_half_float\\\"): EXT_color_buffer_half_float | null;\\n    getExtension(extensionName: \\\"EXT_float_blend\\\"): EXT_float_blend | null;\\n    getExtension(extensionName: \\\"EXT_frag_depth\\\"): EXT_frag_depth | null;\\n    getExtension(extensionName: \\\"EXT_sRGB\\\"): EXT_sRGB | null;\\n    getExtension(extensionName: \\\"EXT_shader_texture_lod\\\"): EXT_shader_texture_lod | null;\\n    getExtension(extensionName: \\\"EXT_texture_compression_bptc\\\"): EXT_texture_compression_bptc | null;\\n    getExtension(extensionName: \\\"EXT_texture_compression_rgtc\\\"): EXT_texture_compression_rgtc | null;\\n    getExtension(extensionName: \\\"EXT_texture_filter_anisotropic\\\"): EXT_texture_filter_anisotropic | null;\\n    getExtension(extensionName: \\\"KHR_parallel_shader_compile\\\"): KHR_parallel_shader_compile | null;\\n    getExtension(extensionName: \\\"OES_element_index_uint\\\"): OES_element_index_uint | null;\\n    getExtension(extensionName: \\\"OES_fbo_render_mipmap\\\"): OES_fbo_render_mipmap | null;\\n    getExtension(extensionName: \\\"OES_standard_derivatives\\\"): OES_standard_derivatives | null;\\n    getExtension(extensionName: \\\"OES_texture_float\\\"): OES_texture_float | null;\\n    getExtension(extensionName: \\\"OES_texture_float_linear\\\"): OES_texture_float_linear | null;\\n    getExtension(extensionName: \\\"OES_texture_half_float\\\"): OES_texture_half_float | null;\\n    getExtension(extensionName: \\\"OES_texture_half_float_linear\\\"): OES_texture_half_float_linear | null;\\n    getExtension(extensionName: \\\"OES_vertex_array_object\\\"): OES_vertex_array_object | null;\\n    getExtension(extensionName: \\\"OVR_multiview2\\\"): OVR_multiview2 | null;\\n    getExtension(extensionName: \\\"WEBGL_color_buffer_float\\\"): WEBGL_color_buffer_float | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_astc\\\"): WEBGL_compressed_texture_astc | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_etc\\\"): WEBGL_compressed_texture_etc | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_etc1\\\"): WEBGL_compressed_texture_etc1 | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_pvrtc\\\"): WEBGL_compressed_texture_pvrtc | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_s3tc\\\"): WEBGL_compressed_texture_s3tc | null;\\n    getExtension(extensionName: \\\"WEBGL_compressed_texture_s3tc_srgb\\\"): WEBGL_compressed_texture_s3tc_srgb | null;\\n    getExtension(extensionName: \\\"WEBGL_debug_renderer_info\\\"): WEBGL_debug_renderer_info | null;\\n    getExtension(extensionName: \\\"WEBGL_debug_shaders\\\"): WEBGL_debug_shaders | null;\\n    getExtension(extensionName: \\\"WEBGL_depth_texture\\\"): WEBGL_depth_texture | null;\\n    getExtension(extensionName: \\\"WEBGL_draw_buffers\\\"): WEBGL_draw_buffers | null;\\n    getExtension(extensionName: \\\"WEBGL_lose_context\\\"): WEBGL_lose_context | null;\\n    getExtension(extensionName: \\\"WEBGL_multi_draw\\\"): WEBGL_multi_draw | null;\\n    getExtension(name: string): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getFramebufferAttachmentParameter) */\\n    getFramebufferAttachmentParameter(target: GLenum, attachment: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getParameter) */\\n    getParameter(pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getProgramInfoLog) */\\n    getProgramInfoLog(program: WebGLProgram): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getProgramParameter) */\\n    getProgramParameter(program: WebGLProgram, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getRenderbufferParameter) */\\n    getRenderbufferParameter(target: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getShaderInfoLog) */\\n    getShaderInfoLog(shader: WebGLShader): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getShaderParameter) */\\n    getShaderParameter(shader: WebGLShader, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getShaderPrecisionFormat) */\\n    getShaderPrecisionFormat(shadertype: GLenum, precisiontype: GLenum): WebGLShaderPrecisionFormat | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getShaderSource) */\\n    getShaderSource(shader: WebGLShader): string | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getSupportedExtensions) */\\n    getSupportedExtensions(): string[] | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getTexParameter) */\\n    getTexParameter(target: GLenum, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getUniform) */\\n    getUniform(program: WebGLProgram, location: WebGLUniformLocation): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getUniformLocation) */\\n    getUniformLocation(program: WebGLProgram, name: string): WebGLUniformLocation | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getVertexAttrib) */\\n    getVertexAttrib(index: GLuint, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/getVertexAttribOffset) */\\n    getVertexAttribOffset(index: GLuint, pname: GLenum): GLintptr;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/hint) */\\n    hint(target: GLenum, mode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isBuffer) */\\n    isBuffer(buffer: WebGLBuffer | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isContextLost) */\\n    isContextLost(): boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isEnabled) */\\n    isEnabled(cap: GLenum): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isFramebuffer) */\\n    isFramebuffer(framebuffer: WebGLFramebuffer | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isProgram) */\\n    isProgram(program: WebGLProgram | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isRenderbuffer) */\\n    isRenderbuffer(renderbuffer: WebGLRenderbuffer | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isShader) */\\n    isShader(shader: WebGLShader | null): GLboolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/isTexture) */\\n    isTexture(texture: WebGLTexture | null): GLboolean;\\n    lineWidth(width: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/linkProgram) */\\n    linkProgram(program: WebGLProgram): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/pixelStorei) */\\n    pixelStorei(pname: GLenum, param: GLint | GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/polygonOffset) */\\n    polygonOffset(factor: GLfloat, units: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/renderbufferStorage) */\\n    renderbufferStorage(target: GLenum, internalformat: GLenum, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/sampleCoverage) */\\n    sampleCoverage(value: GLclampf, invert: GLboolean): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/scissor) */\\n    scissor(x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/shaderSource) */\\n    shaderSource(shader: WebGLShader, source: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilFunc) */\\n    stencilFunc(func: GLenum, ref: GLint, mask: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilFuncSeparate) */\\n    stencilFuncSeparate(face: GLenum, func: GLenum, ref: GLint, mask: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilMask) */\\n    stencilMask(mask: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilMaskSeparate) */\\n    stencilMaskSeparate(face: GLenum, mask: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilOp) */\\n    stencilOp(fail: GLenum, zfail: GLenum, zpass: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/stencilOpSeparate) */\\n    stencilOpSeparate(face: GLenum, fail: GLenum, zfail: GLenum, zpass: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texParameter) */\\n    texParameterf(target: GLenum, pname: GLenum, param: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texParameter) */\\n    texParameteri(target: GLenum, pname: GLenum, param: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1f(location: WebGLUniformLocation | null, x: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1i(location: WebGLUniformLocation | null, x: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2f(location: WebGLUniformLocation | null, x: GLfloat, y: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2i(location: WebGLUniformLocation | null, x: GLint, y: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3f(location: WebGLUniformLocation | null, x: GLfloat, y: GLfloat, z: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3i(location: WebGLUniformLocation | null, x: GLint, y: GLint, z: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4f(location: WebGLUniformLocation | null, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4i(location: WebGLUniformLocation | null, x: GLint, y: GLint, z: GLint, w: GLint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/useProgram) */\\n    useProgram(program: WebGLProgram | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/validateProgram) */\\n    validateProgram(program: WebGLProgram): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib1f(index: GLuint, x: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib1fv(index: GLuint, values: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib2f(index: GLuint, x: GLfloat, y: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib2fv(index: GLuint, values: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib3f(index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib3fv(index: GLuint, values: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib4f(index: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib4fv(index: GLuint, values: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttribPointer) */\\n    vertexAttribPointer(index: GLuint, size: GLint, type: GLenum, normalized: GLboolean, stride: GLsizei, offset: GLintptr): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/viewport) */\\n    viewport(x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    readonly DEPTH_BUFFER_BIT: 0x00000100;\\n    readonly STENCIL_BUFFER_BIT: 0x00000400;\\n    readonly COLOR_BUFFER_BIT: 0x00004000;\\n    readonly POINTS: 0x0000;\\n    readonly LINES: 0x0001;\\n    readonly LINE_LOOP: 0x0002;\\n    readonly LINE_STRIP: 0x0003;\\n    readonly TRIANGLES: 0x0004;\\n    readonly TRIANGLE_STRIP: 0x0005;\\n    readonly TRIANGLE_FAN: 0x0006;\\n    readonly ZERO: 0;\\n    readonly ONE: 1;\\n    readonly SRC_COLOR: 0x0300;\\n    readonly ONE_MINUS_SRC_COLOR: 0x0301;\\n    readonly SRC_ALPHA: 0x0302;\\n    readonly ONE_MINUS_SRC_ALPHA: 0x0303;\\n    readonly DST_ALPHA: 0x0304;\\n    readonly ONE_MINUS_DST_ALPHA: 0x0305;\\n    readonly DST_COLOR: 0x0306;\\n    readonly ONE_MINUS_DST_COLOR: 0x0307;\\n    readonly SRC_ALPHA_SATURATE: 0x0308;\\n    readonly FUNC_ADD: 0x8006;\\n    readonly BLEND_EQUATION: 0x8009;\\n    readonly BLEND_EQUATION_RGB: 0x8009;\\n    readonly BLEND_EQUATION_ALPHA: 0x883D;\\n    readonly FUNC_SUBTRACT: 0x800A;\\n    readonly FUNC_REVERSE_SUBTRACT: 0x800B;\\n    readonly BLEND_DST_RGB: 0x80C8;\\n    readonly BLEND_SRC_RGB: 0x80C9;\\n    readonly BLEND_DST_ALPHA: 0x80CA;\\n    readonly BLEND_SRC_ALPHA: 0x80CB;\\n    readonly CONSTANT_COLOR: 0x8001;\\n    readonly ONE_MINUS_CONSTANT_COLOR: 0x8002;\\n    readonly CONSTANT_ALPHA: 0x8003;\\n    readonly ONE_MINUS_CONSTANT_ALPHA: 0x8004;\\n    readonly BLEND_COLOR: 0x8005;\\n    readonly ARRAY_BUFFER: 0x8892;\\n    readonly ELEMENT_ARRAY_BUFFER: 0x8893;\\n    readonly ARRAY_BUFFER_BINDING: 0x8894;\\n    readonly ELEMENT_ARRAY_BUFFER_BINDING: 0x8895;\\n    readonly STREAM_DRAW: 0x88E0;\\n    readonly STATIC_DRAW: 0x88E4;\\n    readonly DYNAMIC_DRAW: 0x88E8;\\n    readonly BUFFER_SIZE: 0x8764;\\n    readonly BUFFER_USAGE: 0x8765;\\n    readonly CURRENT_VERTEX_ATTRIB: 0x8626;\\n    readonly FRONT: 0x0404;\\n    readonly BACK: 0x0405;\\n    readonly FRONT_AND_BACK: 0x0408;\\n    readonly CULL_FACE: 0x0B44;\\n    readonly BLEND: 0x0BE2;\\n    readonly DITHER: 0x0BD0;\\n    readonly STENCIL_TEST: 0x0B90;\\n    readonly DEPTH_TEST: 0x0B71;\\n    readonly SCISSOR_TEST: 0x0C11;\\n    readonly POLYGON_OFFSET_FILL: 0x8037;\\n    readonly SAMPLE_ALPHA_TO_COVERAGE: 0x809E;\\n    readonly SAMPLE_COVERAGE: 0x80A0;\\n    readonly NO_ERROR: 0;\\n    readonly INVALID_ENUM: 0x0500;\\n    readonly INVALID_VALUE: 0x0501;\\n    readonly INVALID_OPERATION: 0x0502;\\n    readonly OUT_OF_MEMORY: 0x0505;\\n    readonly CW: 0x0900;\\n    readonly CCW: 0x0901;\\n    readonly LINE_WIDTH: 0x0B21;\\n    readonly ALIASED_POINT_SIZE_RANGE: 0x846D;\\n    readonly ALIASED_LINE_WIDTH_RANGE: 0x846E;\\n    readonly CULL_FACE_MODE: 0x0B45;\\n    readonly FRONT_FACE: 0x0B46;\\n    readonly DEPTH_RANGE: 0x0B70;\\n    readonly DEPTH_WRITEMASK: 0x0B72;\\n    readonly DEPTH_CLEAR_VALUE: 0x0B73;\\n    readonly DEPTH_FUNC: 0x0B74;\\n    readonly STENCIL_CLEAR_VALUE: 0x0B91;\\n    readonly STENCIL_FUNC: 0x0B92;\\n    readonly STENCIL_FAIL: 0x0B94;\\n    readonly STENCIL_PASS_DEPTH_FAIL: 0x0B95;\\n    readonly STENCIL_PASS_DEPTH_PASS: 0x0B96;\\n    readonly STENCIL_REF: 0x0B97;\\n    readonly STENCIL_VALUE_MASK: 0x0B93;\\n    readonly STENCIL_WRITEMASK: 0x0B98;\\n    readonly STENCIL_BACK_FUNC: 0x8800;\\n    readonly STENCIL_BACK_FAIL: 0x8801;\\n    readonly STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802;\\n    readonly STENCIL_BACK_PASS_DEPTH_PASS: 0x8803;\\n    readonly STENCIL_BACK_REF: 0x8CA3;\\n    readonly STENCIL_BACK_VALUE_MASK: 0x8CA4;\\n    readonly STENCIL_BACK_WRITEMASK: 0x8CA5;\\n    readonly VIEWPORT: 0x0BA2;\\n    readonly SCISSOR_BOX: 0x0C10;\\n    readonly COLOR_CLEAR_VALUE: 0x0C22;\\n    readonly COLOR_WRITEMASK: 0x0C23;\\n    readonly UNPACK_ALIGNMENT: 0x0CF5;\\n    readonly PACK_ALIGNMENT: 0x0D05;\\n    readonly MAX_TEXTURE_SIZE: 0x0D33;\\n    readonly MAX_VIEWPORT_DIMS: 0x0D3A;\\n    readonly SUBPIXEL_BITS: 0x0D50;\\n    readonly RED_BITS: 0x0D52;\\n    readonly GREEN_BITS: 0x0D53;\\n    readonly BLUE_BITS: 0x0D54;\\n    readonly ALPHA_BITS: 0x0D55;\\n    readonly DEPTH_BITS: 0x0D56;\\n    readonly STENCIL_BITS: 0x0D57;\\n    readonly POLYGON_OFFSET_UNITS: 0x2A00;\\n    readonly POLYGON_OFFSET_FACTOR: 0x8038;\\n    readonly TEXTURE_BINDING_2D: 0x8069;\\n    readonly SAMPLE_BUFFERS: 0x80A8;\\n    readonly SAMPLES: 0x80A9;\\n    readonly SAMPLE_COVERAGE_VALUE: 0x80AA;\\n    readonly SAMPLE_COVERAGE_INVERT: 0x80AB;\\n    readonly COMPRESSED_TEXTURE_FORMATS: 0x86A3;\\n    readonly DONT_CARE: 0x1100;\\n    readonly FASTEST: 0x1101;\\n    readonly NICEST: 0x1102;\\n    readonly GENERATE_MIPMAP_HINT: 0x8192;\\n    readonly BYTE: 0x1400;\\n    readonly UNSIGNED_BYTE: 0x1401;\\n    readonly SHORT: 0x1402;\\n    readonly UNSIGNED_SHORT: 0x1403;\\n    readonly INT: 0x1404;\\n    readonly UNSIGNED_INT: 0x1405;\\n    readonly FLOAT: 0x1406;\\n    readonly DEPTH_COMPONENT: 0x1902;\\n    readonly ALPHA: 0x1906;\\n    readonly RGB: 0x1907;\\n    readonly RGBA: 0x1908;\\n    readonly LUMINANCE: 0x1909;\\n    readonly LUMINANCE_ALPHA: 0x190A;\\n    readonly UNSIGNED_SHORT_4_4_4_4: 0x8033;\\n    readonly UNSIGNED_SHORT_5_5_5_1: 0x8034;\\n    readonly UNSIGNED_SHORT_5_6_5: 0x8363;\\n    readonly FRAGMENT_SHADER: 0x8B30;\\n    readonly VERTEX_SHADER: 0x8B31;\\n    readonly MAX_VERTEX_ATTRIBS: 0x8869;\\n    readonly MAX_VERTEX_UNIFORM_VECTORS: 0x8DFB;\\n    readonly MAX_VARYING_VECTORS: 0x8DFC;\\n    readonly MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8B4D;\\n    readonly MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8B4C;\\n    readonly MAX_TEXTURE_IMAGE_UNITS: 0x8872;\\n    readonly MAX_FRAGMENT_UNIFORM_VECTORS: 0x8DFD;\\n    readonly SHADER_TYPE: 0x8B4F;\\n    readonly DELETE_STATUS: 0x8B80;\\n    readonly LINK_STATUS: 0x8B82;\\n    readonly VALIDATE_STATUS: 0x8B83;\\n    readonly ATTACHED_SHADERS: 0x8B85;\\n    readonly ACTIVE_UNIFORMS: 0x8B86;\\n    readonly ACTIVE_ATTRIBUTES: 0x8B89;\\n    readonly SHADING_LANGUAGE_VERSION: 0x8B8C;\\n    readonly CURRENT_PROGRAM: 0x8B8D;\\n    readonly NEVER: 0x0200;\\n    readonly LESS: 0x0201;\\n    readonly EQUAL: 0x0202;\\n    readonly LEQUAL: 0x0203;\\n    readonly GREATER: 0x0204;\\n    readonly NOTEQUAL: 0x0205;\\n    readonly GEQUAL: 0x0206;\\n    readonly ALWAYS: 0x0207;\\n    readonly KEEP: 0x1E00;\\n    readonly REPLACE: 0x1E01;\\n    readonly INCR: 0x1E02;\\n    readonly DECR: 0x1E03;\\n    readonly INVERT: 0x150A;\\n    readonly INCR_WRAP: 0x8507;\\n    readonly DECR_WRAP: 0x8508;\\n    readonly VENDOR: 0x1F00;\\n    readonly RENDERER: 0x1F01;\\n    readonly VERSION: 0x1F02;\\n    readonly NEAREST: 0x2600;\\n    readonly LINEAR: 0x2601;\\n    readonly NEAREST_MIPMAP_NEAREST: 0x2700;\\n    readonly LINEAR_MIPMAP_NEAREST: 0x2701;\\n    readonly NEAREST_MIPMAP_LINEAR: 0x2702;\\n    readonly LINEAR_MIPMAP_LINEAR: 0x2703;\\n    readonly TEXTURE_MAG_FILTER: 0x2800;\\n    readonly TEXTURE_MIN_FILTER: 0x2801;\\n    readonly TEXTURE_WRAP_S: 0x2802;\\n    readonly TEXTURE_WRAP_T: 0x2803;\\n    readonly TEXTURE_2D: 0x0DE1;\\n    readonly TEXTURE: 0x1702;\\n    readonly TEXTURE_CUBE_MAP: 0x8513;\\n    readonly TEXTURE_BINDING_CUBE_MAP: 0x8514;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518;\\n    readonly TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519;\\n    readonly TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851A;\\n    readonly MAX_CUBE_MAP_TEXTURE_SIZE: 0x851C;\\n    readonly TEXTURE0: 0x84C0;\\n    readonly TEXTURE1: 0x84C1;\\n    readonly TEXTURE2: 0x84C2;\\n    readonly TEXTURE3: 0x84C3;\\n    readonly TEXTURE4: 0x84C4;\\n    readonly TEXTURE5: 0x84C5;\\n    readonly TEXTURE6: 0x84C6;\\n    readonly TEXTURE7: 0x84C7;\\n    readonly TEXTURE8: 0x84C8;\\n    readonly TEXTURE9: 0x84C9;\\n    readonly TEXTURE10: 0x84CA;\\n    readonly TEXTURE11: 0x84CB;\\n    readonly TEXTURE12: 0x84CC;\\n    readonly TEXTURE13: 0x84CD;\\n    readonly TEXTURE14: 0x84CE;\\n    readonly TEXTURE15: 0x84CF;\\n    readonly TEXTURE16: 0x84D0;\\n    readonly TEXTURE17: 0x84D1;\\n    readonly TEXTURE18: 0x84D2;\\n    readonly TEXTURE19: 0x84D3;\\n    readonly TEXTURE20: 0x84D4;\\n    readonly TEXTURE21: 0x84D5;\\n    readonly TEXTURE22: 0x84D6;\\n    readonly TEXTURE23: 0x84D7;\\n    readonly TEXTURE24: 0x84D8;\\n    readonly TEXTURE25: 0x84D9;\\n    readonly TEXTURE26: 0x84DA;\\n    readonly TEXTURE27: 0x84DB;\\n    readonly TEXTURE28: 0x84DC;\\n    readonly TEXTURE29: 0x84DD;\\n    readonly TEXTURE30: 0x84DE;\\n    readonly TEXTURE31: 0x84DF;\\n    readonly ACTIVE_TEXTURE: 0x84E0;\\n    readonly REPEAT: 0x2901;\\n    readonly CLAMP_TO_EDGE: 0x812F;\\n    readonly MIRRORED_REPEAT: 0x8370;\\n    readonly FLOAT_VEC2: 0x8B50;\\n    readonly FLOAT_VEC3: 0x8B51;\\n    readonly FLOAT_VEC4: 0x8B52;\\n    readonly INT_VEC2: 0x8B53;\\n    readonly INT_VEC3: 0x8B54;\\n    readonly INT_VEC4: 0x8B55;\\n    readonly BOOL: 0x8B56;\\n    readonly BOOL_VEC2: 0x8B57;\\n    readonly BOOL_VEC3: 0x8B58;\\n    readonly BOOL_VEC4: 0x8B59;\\n    readonly FLOAT_MAT2: 0x8B5A;\\n    readonly FLOAT_MAT3: 0x8B5B;\\n    readonly FLOAT_MAT4: 0x8B5C;\\n    readonly SAMPLER_2D: 0x8B5E;\\n    readonly SAMPLER_CUBE: 0x8B60;\\n    readonly VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622;\\n    readonly VERTEX_ATTRIB_ARRAY_SIZE: 0x8623;\\n    readonly VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624;\\n    readonly VERTEX_ATTRIB_ARRAY_TYPE: 0x8625;\\n    readonly VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886A;\\n    readonly VERTEX_ATTRIB_ARRAY_POINTER: 0x8645;\\n    readonly VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889F;\\n    readonly IMPLEMENTATION_COLOR_READ_TYPE: 0x8B9A;\\n    readonly IMPLEMENTATION_COLOR_READ_FORMAT: 0x8B9B;\\n    readonly COMPILE_STATUS: 0x8B81;\\n    readonly LOW_FLOAT: 0x8DF0;\\n    readonly MEDIUM_FLOAT: 0x8DF1;\\n    readonly HIGH_FLOAT: 0x8DF2;\\n    readonly LOW_INT: 0x8DF3;\\n    readonly MEDIUM_INT: 0x8DF4;\\n    readonly HIGH_INT: 0x8DF5;\\n    readonly FRAMEBUFFER: 0x8D40;\\n    readonly RENDERBUFFER: 0x8D41;\\n    readonly RGBA4: 0x8056;\\n    readonly RGB5_A1: 0x8057;\\n    readonly RGB565: 0x8D62;\\n    readonly DEPTH_COMPONENT16: 0x81A5;\\n    readonly STENCIL_INDEX8: 0x8D48;\\n    readonly DEPTH_STENCIL: 0x84F9;\\n    readonly RENDERBUFFER_WIDTH: 0x8D42;\\n    readonly RENDERBUFFER_HEIGHT: 0x8D43;\\n    readonly RENDERBUFFER_INTERNAL_FORMAT: 0x8D44;\\n    readonly RENDERBUFFER_RED_SIZE: 0x8D50;\\n    readonly RENDERBUFFER_GREEN_SIZE: 0x8D51;\\n    readonly RENDERBUFFER_BLUE_SIZE: 0x8D52;\\n    readonly RENDERBUFFER_ALPHA_SIZE: 0x8D53;\\n    readonly RENDERBUFFER_DEPTH_SIZE: 0x8D54;\\n    readonly RENDERBUFFER_STENCIL_SIZE: 0x8D55;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8CD0;\\n    readonly FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8CD1;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8CD2;\\n    readonly FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8CD3;\\n    readonly COLOR_ATTACHMENT0: 0x8CE0;\\n    readonly DEPTH_ATTACHMENT: 0x8D00;\\n    readonly STENCIL_ATTACHMENT: 0x8D20;\\n    readonly DEPTH_STENCIL_ATTACHMENT: 0x821A;\\n    readonly NONE: 0;\\n    readonly FRAMEBUFFER_COMPLETE: 0x8CD5;\\n    readonly FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8CD6;\\n    readonly FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8CD7;\\n    readonly FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8CD9;\\n    readonly FRAMEBUFFER_UNSUPPORTED: 0x8CDD;\\n    readonly FRAMEBUFFER_BINDING: 0x8CA6;\\n    readonly RENDERBUFFER_BINDING: 0x8CA7;\\n    readonly MAX_RENDERBUFFER_SIZE: 0x84E8;\\n    readonly INVALID_FRAMEBUFFER_OPERATION: 0x0506;\\n    readonly UNPACK_FLIP_Y_WEBGL: 0x9240;\\n    readonly UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241;\\n    readonly CONTEXT_LOST_WEBGL: 0x9242;\\n    readonly UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243;\\n    readonly BROWSER_DEFAULT_WEBGL: 0x9244;\\n}\\n\\ninterface WebGLRenderingContextOverloads {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bufferData) */\\n    bufferData(target: GLenum, size: GLsizeiptr, usage: GLenum): void;\\n    bufferData(target: GLenum, data: BufferSource | null, usage: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/bufferSubData) */\\n    bufferSubData(target: GLenum, offset: GLintptr, data: BufferSource): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compressedTexImage2D) */\\n    compressedTexImage2D(target: GLenum, level: GLint, internalformat: GLenum, width: GLsizei, height: GLsizei, border: GLint, data: ArrayBufferView): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/compressedTexSubImage2D) */\\n    compressedTexSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, data: ArrayBufferView): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/readPixels) */\\n    readPixels(x: GLint, y: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texImage2D) */\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, width: GLsizei, height: GLsizei, border: GLint, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    texImage2D(target: GLenum, level: GLint, internalformat: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/texSubImage2D) */\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, width: GLsizei, height: GLsizei, format: GLenum, type: GLenum, pixels: ArrayBufferView | null): void;\\n    texSubImage2D(target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, format: GLenum, type: GLenum, source: TexImageSource): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1fv(location: WebGLUniformLocation | null, v: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1iv(location: WebGLUniformLocation | null, v: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2fv(location: WebGLUniformLocation | null, v: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2iv(location: WebGLUniformLocation | null, v: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3fv(location: WebGLUniformLocation | null, v: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3iv(location: WebGLUniformLocation | null, v: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4fv(location: WebGLUniformLocation | null, v: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4iv(location: WebGLUniformLocation | null, v: Int32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Float32List): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Float32List): void;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLSampler) */\\ninterface WebGLSampler {\\n}\\n\\ndeclare var WebGLSampler: {\\n    prototype: WebGLSampler;\\n    new(): WebGLSampler;\\n};\\n\\n/**\\n * The WebGLShader is part of the WebGL API and can either be a vertex or a fragment shader. A WebGLProgram requires both types of shaders.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShader)\\n */\\ninterface WebGLShader {\\n}\\n\\ndeclare var WebGLShader: {\\n    prototype: WebGLShader;\\n    new(): WebGLShader;\\n};\\n\\n/**\\n * Part of the WebGL API and represents the information returned by calling the WebGLRenderingContext.getShaderPrecisionFormat() method.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShaderPrecisionFormat)\\n */\\ninterface WebGLShaderPrecisionFormat {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShaderPrecisionFormat/precision) */\\n    readonly precision: GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShaderPrecisionFormat/rangeMax) */\\n    readonly rangeMax: GLint;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLShaderPrecisionFormat/rangeMin) */\\n    readonly rangeMin: GLint;\\n}\\n\\ndeclare var WebGLShaderPrecisionFormat: {\\n    prototype: WebGLShaderPrecisionFormat;\\n    new(): WebGLShaderPrecisionFormat;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLSync) */\\ninterface WebGLSync {\\n}\\n\\ndeclare var WebGLSync: {\\n    prototype: WebGLSync;\\n    new(): WebGLSync;\\n};\\n\\n/**\\n * Part of the WebGL API and represents an opaque texture object providing storage and state for texturing operations.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLTexture)\\n */\\ninterface WebGLTexture {\\n}\\n\\ndeclare var WebGLTexture: {\\n    prototype: WebGLTexture;\\n    new(): WebGLTexture;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLTransformFeedback) */\\ninterface WebGLTransformFeedback {\\n}\\n\\ndeclare var WebGLTransformFeedback: {\\n    prototype: WebGLTransformFeedback;\\n    new(): WebGLTransformFeedback;\\n};\\n\\n/**\\n * Part of the WebGL API and represents the location of a uniform variable in a shader program.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLUniformLocation)\\n */\\ninterface WebGLUniformLocation {\\n}\\n\\ndeclare var WebGLUniformLocation: {\\n    prototype: WebGLUniformLocation;\\n    new(): WebGLUniformLocation;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLVertexArrayObject) */\\ninterface WebGLVertexArrayObject {\\n}\\n\\ndeclare var WebGLVertexArrayObject: {\\n    prototype: WebGLVertexArrayObject;\\n    new(): WebGLVertexArrayObject;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLVertexArrayObjectOES) */\\ninterface WebGLVertexArrayObjectOES {\\n}\\n\\ninterface WebSocketEventMap {\\n    \\\"close\\\": CloseEvent;\\n    \\\"error\\\": Event;\\n    \\\"message\\\": MessageEvent;\\n    \\\"open\\\": Event;\\n}\\n\\n/**\\n * Provides the API for creating and managing a WebSocket connection to a server, as well as for sending and receiving data on the connection.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket)\\n */\\ninterface WebSocket extends EventTarget {\\n    /**\\n     * Returns a string that indicates how binary data from the WebSocket object is exposed to scripts:\\n     *\\n     * Can be set, to change how binary data is returned. The default is \\\"blob\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/binaryType)\\n     */\\n    binaryType: BinaryType;\\n    /**\\n     * Returns the number of bytes of application data (UTF-8 text and binary data) that have been queued using send() but not yet been transmitted to the network.\\n     *\\n     * If the WebSocket connection is closed, this attribute's value will only increase with each call to the send() method. (The number does not reset to zero once the connection closes.)\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/bufferedAmount)\\n     */\\n    readonly bufferedAmount: number;\\n    /**\\n     * Returns the extensions selected by the server, if any.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/extensions)\\n     */\\n    readonly extensions: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/close_event) */\\n    onclose: ((this: WebSocket, ev: CloseEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/error_event) */\\n    onerror: ((this: WebSocket, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/message_event) */\\n    onmessage: ((this: WebSocket, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/open_event) */\\n    onopen: ((this: WebSocket, ev: Event) => any) | null;\\n    /**\\n     * Returns the subprotocol selected by the server, if any. It can be used in conjunction with the array form of the constructor's second argument to perform subprotocol negotiation.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/protocol)\\n     */\\n    readonly protocol: string;\\n    /**\\n     * Returns the state of the WebSocket object's connection. It can have the values described below.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/readyState)\\n     */\\n    readonly readyState: number;\\n    /**\\n     * Returns the URL that was used to establish the WebSocket connection.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/url)\\n     */\\n    readonly url: string;\\n    /**\\n     * Closes the WebSocket connection, optionally using code as the the WebSocket connection close code and reason as the the WebSocket connection close reason.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/close)\\n     */\\n    close(code?: number, reason?: string): void;\\n    /**\\n     * Transmits data using the WebSocket connection. data can be a string, a Blob, an ArrayBuffer, or an ArrayBufferView.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebSocket/send)\\n     */\\n    send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;\\n    readonly CONNECTING: 0;\\n    readonly OPEN: 1;\\n    readonly CLOSING: 2;\\n    readonly CLOSED: 3;\\n    addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var WebSocket: {\\n    prototype: WebSocket;\\n    new(url: string | URL, protocols?: string | string[]): WebSocket;\\n    readonly CONNECTING: 0;\\n    readonly OPEN: 1;\\n    readonly CLOSING: 2;\\n    readonly CLOSED: 3;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport)\\n */\\ninterface WebTransport {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/closed) */\\n    readonly closed: Promise<WebTransportCloseInfo>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/datagrams) */\\n    readonly datagrams: WebTransportDatagramDuplexStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/incomingBidirectionalStreams) */\\n    readonly incomingBidirectionalStreams: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/incomingUnidirectionalStreams) */\\n    readonly incomingUnidirectionalStreams: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/ready) */\\n    readonly ready: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/close) */\\n    close(closeInfo?: WebTransportCloseInfo): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/createBidirectionalStream) */\\n    createBidirectionalStream(options?: WebTransportSendStreamOptions): Promise<WebTransportBidirectionalStream>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/createUnidirectionalStream) */\\n    createUnidirectionalStream(options?: WebTransportSendStreamOptions): Promise<WritableStream>;\\n}\\n\\ndeclare var WebTransport: {\\n    prototype: WebTransport;\\n    new(url: string | URL, options?: WebTransportOptions): WebTransport;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream)\\n */\\ninterface WebTransportBidirectionalStream {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream/readable) */\\n    readonly readable: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream/writable) */\\n    readonly writable: WritableStream;\\n}\\n\\ndeclare var WebTransportBidirectionalStream: {\\n    prototype: WebTransportBidirectionalStream;\\n    new(): WebTransportBidirectionalStream;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream)\\n */\\ninterface WebTransportDatagramDuplexStream {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/incomingHighWaterMark) */\\n    incomingHighWaterMark: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/incomingMaxAge) */\\n    incomingMaxAge: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/maxDatagramSize) */\\n    readonly maxDatagramSize: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/outgoingHighWaterMark) */\\n    outgoingHighWaterMark: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/outgoingMaxAge) */\\n    outgoingMaxAge: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/readable) */\\n    readonly readable: ReadableStream;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/writable) */\\n    readonly writable: WritableStream;\\n}\\n\\ndeclare var WebTransportDatagramDuplexStream: {\\n    prototype: WebTransportDatagramDuplexStream;\\n    new(): WebTransportDatagramDuplexStream;\\n};\\n\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError)\\n */\\ninterface WebTransportError extends DOMException {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError/source) */\\n    readonly source: WebTransportErrorSource;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError/streamErrorCode) */\\n    readonly streamErrorCode: number | null;\\n}\\n\\ndeclare var WebTransportError: {\\n    prototype: WebTransportError;\\n    new(message?: string, options?: WebTransportErrorOptions): WebTransportError;\\n};\\n\\n/**\\n * This ServiceWorker API interface represents the scope of a service worker client that is a document in a browser context, controlled by an active worker. The service worker client independently selects and uses a service worker for its own loading and sub-resources.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WindowClient)\\n */\\ninterface WindowClient extends Client {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WindowClient/focused) */\\n    readonly focused: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WindowClient/visibilityState) */\\n    readonly visibilityState: DocumentVisibilityState;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WindowClient/focus) */\\n    focus(): Promise<WindowClient>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WindowClient/navigate) */\\n    navigate(url: string | URL): Promise<WindowClient | null>;\\n}\\n\\ndeclare var WindowClient: {\\n    prototype: WindowClient;\\n    new(): WindowClient;\\n};\\n\\ninterface WindowOrWorkerGlobalScope {\\n    /**\\n     * Available only in secure contexts.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/caches)\\n     */\\n    readonly caches: CacheStorage;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/crossOriginIsolated) */\\n    readonly crossOriginIsolated: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/crypto_property) */\\n    readonly crypto: Crypto;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/indexedDB) */\\n    readonly indexedDB: IDBFactory;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/isSecureContext) */\\n    readonly isSecureContext: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/origin) */\\n    readonly origin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/performance_property) */\\n    readonly performance: Performance;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/atob) */\\n    atob(data: string): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/btoa) */\\n    btoa(data: string): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/clearInterval) */\\n    clearInterval(id: number | undefined): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/clearTimeout) */\\n    clearTimeout(id: number | undefined): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/createImageBitmap) */\\n    createImageBitmap(image: ImageBitmapSource, options?: ImageBitmapOptions): Promise<ImageBitmap>;\\n    createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/fetch) */\\n    fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/queueMicrotask) */\\n    queueMicrotask(callback: VoidFunction): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/reportError) */\\n    reportError(e: any): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/setInterval) */\\n    setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/setTimeout) */\\n    setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/structuredClone) */\\n    structuredClone<T = any>(value: T, options?: StructuredSerializeOptions): T;\\n}\\n\\ninterface WorkerEventMap extends AbstractWorkerEventMap {\\n    \\\"message\\\": MessageEvent;\\n    \\\"messageerror\\\": MessageEvent;\\n}\\n\\n/**\\n * This Web Workers API interface represents a background task that can be easily created and can send messages back to its creator. Creating a worker is as simple as calling the Worker() constructor and specifying a script to be run in the worker thread.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker)\\n */\\ninterface Worker extends EventTarget, AbstractWorker {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/message_event) */\\n    onmessage: ((this: Worker, ev: MessageEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/messageerror_event) */\\n    onmessageerror: ((this: Worker, ev: MessageEvent) => any) | null;\\n    /**\\n     * Clones message and transmits it to worker's global environment. transfer can be passed as a list of objects that are to be transferred rather than cloned.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/postMessage)\\n     */\\n    postMessage(message: any, transfer: Transferable[]): void;\\n    postMessage(message: any, options?: StructuredSerializeOptions): void;\\n    /**\\n     * Aborts worker's associated global environment.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Worker/terminate)\\n     */\\n    terminate(): void;\\n    addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var Worker: {\\n    prototype: Worker;\\n    new(scriptURL: string | URL, options?: WorkerOptions): Worker;\\n};\\n\\ninterface WorkerGlobalScopeEventMap {\\n    \\\"error\\\": ErrorEvent;\\n    \\\"languagechange\\\": Event;\\n    \\\"offline\\\": Event;\\n    \\\"online\\\": Event;\\n    \\\"rejectionhandled\\\": PromiseRejectionEvent;\\n    \\\"unhandledrejection\\\": PromiseRejectionEvent;\\n}\\n\\n/**\\n * This Web Workers API interface is an interface representing the scope of any worker. Workers have no browsing context; this scope contains the information usually conveyed by Window objects — in this case event handlers, the console or the associated WorkerNavigator object. Each WorkerGlobalScope has its own event loop.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope)\\n */\\ninterface WorkerGlobalScope extends EventTarget, FontFaceSource, WindowOrWorkerGlobalScope {\\n    /**\\n     * Returns workerGlobal's WorkerLocation object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/location)\\n     */\\n    readonly location: WorkerLocation;\\n    /**\\n     * Returns workerGlobal's WorkerNavigator object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/navigator)\\n     */\\n    readonly navigator: WorkerNavigator;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/error_event) */\\n    onerror: ((this: WorkerGlobalScope, ev: ErrorEvent) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/languagechange_event) */\\n    onlanguagechange: ((this: WorkerGlobalScope, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/offline_event) */\\n    onoffline: ((this: WorkerGlobalScope, ev: Event) => any) | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/online_event) */\\n    ononline: ((this: WorkerGlobalScope, ev: Event) => any) | null;\\n    onrejectionhandled: ((this: WorkerGlobalScope, ev: PromiseRejectionEvent) => any) | null;\\n    onunhandledrejection: ((this: WorkerGlobalScope, ev: PromiseRejectionEvent) => any) | null;\\n    /**\\n     * Returns workerGlobal.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/self)\\n     */\\n    readonly self: WorkerGlobalScope & typeof globalThis;\\n    /**\\n     * Fetches each URL in urls, executes them one-by-one in the order they are passed, and then returns (or throws if something went amiss).\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/importScripts)\\n     */\\n    importScripts(...urls: (string | URL)[]): void;\\n    addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var WorkerGlobalScope: {\\n    prototype: WorkerGlobalScope;\\n    new(): WorkerGlobalScope;\\n};\\n\\n/**\\n * The absolute location of the script executed by the Worker. Such an object is initialized for each worker and is available via the WorkerGlobalScope.location property obtained by calling self.location.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation)\\n */\\ninterface WorkerLocation {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/hash) */\\n    readonly hash: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/host) */\\n    readonly host: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/hostname) */\\n    readonly hostname: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/href) */\\n    readonly href: string;\\n    toString(): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/origin) */\\n    readonly origin: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/pathname) */\\n    readonly pathname: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/port) */\\n    readonly port: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/protocol) */\\n    readonly protocol: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerLocation/search) */\\n    readonly search: string;\\n}\\n\\ndeclare var WorkerLocation: {\\n    prototype: WorkerLocation;\\n    new(): WorkerLocation;\\n};\\n\\n/**\\n * A subset of the Navigator interface allowed to be accessed from a Worker. Such an object is initialized for each worker and is available via the WorkerGlobalScope.navigator property obtained by calling window.self.navigator.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerNavigator)\\n */\\ninterface WorkerNavigator extends NavigatorBadge, NavigatorConcurrentHardware, NavigatorID, NavigatorLanguage, NavigatorLocks, NavigatorOnLine, NavigatorStorage {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerNavigator/mediaCapabilities) */\\n    readonly mediaCapabilities: MediaCapabilities;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerNavigator/permissions) */\\n    readonly permissions: Permissions;\\n}\\n\\ndeclare var WorkerNavigator: {\\n    prototype: WorkerNavigator;\\n    new(): WorkerNavigator;\\n};\\n\\n/**\\n * This Streams API interface provides a standard abstraction for writing streaming data to a destination, known as a sink. This object comes with built-in backpressure and queuing.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream)\\n */\\ninterface WritableStream<W = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream/locked) */\\n    readonly locked: boolean;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream/abort) */\\n    abort(reason?: any): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream/close) */\\n    close(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStream/getWriter) */\\n    getWriter(): WritableStreamDefaultWriter<W>;\\n}\\n\\ndeclare var WritableStream: {\\n    prototype: WritableStream;\\n    new<W = any>(underlyingSink?: UnderlyingSink<W>, strategy?: QueuingStrategy<W>): WritableStream<W>;\\n};\\n\\n/**\\n * This Streams API interface represents a controller allowing control of a WritableStream's state. When constructing a WritableStream, the underlying sink is given a corresponding WritableStreamDefaultController instance to manipulate.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultController)\\n */\\ninterface WritableStreamDefaultController {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultController/signal) */\\n    readonly signal: AbortSignal;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultController/error) */\\n    error(e?: any): void;\\n}\\n\\ndeclare var WritableStreamDefaultController: {\\n    prototype: WritableStreamDefaultController;\\n    new(): WritableStreamDefaultController;\\n};\\n\\n/**\\n * This Streams API interface is the object returned by WritableStream.getWriter() and once created locks the < writer to the WritableStream ensuring that no other streams can write to the underlying sink.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter)\\n */\\ninterface WritableStreamDefaultWriter<W = any> {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/closed) */\\n    readonly closed: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/desiredSize) */\\n    readonly desiredSize: number | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/ready) */\\n    readonly ready: Promise<undefined>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/abort) */\\n    abort(reason?: any): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/close) */\\n    close(): Promise<void>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/releaseLock) */\\n    releaseLock(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WritableStreamDefaultWriter/write) */\\n    write(chunk?: W): Promise<void>;\\n}\\n\\ndeclare var WritableStreamDefaultWriter: {\\n    prototype: WritableStreamDefaultWriter;\\n    new<W = any>(stream: WritableStream<W>): WritableStreamDefaultWriter<W>;\\n};\\n\\ninterface XMLHttpRequestEventMap extends XMLHttpRequestEventTargetEventMap {\\n    \\\"readystatechange\\\": Event;\\n}\\n\\n/**\\n * Use XMLHttpRequest (XHR) objects to interact with servers. You can retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just part of a page without disrupting what the user is doing.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest)\\n */\\ninterface XMLHttpRequest extends XMLHttpRequestEventTarget {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/readystatechange_event) */\\n    onreadystatechange: ((this: XMLHttpRequest, ev: Event) => any) | null;\\n    /**\\n     * Returns client's state.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/readyState)\\n     */\\n    readonly readyState: number;\\n    /**\\n     * Returns the response body.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/response)\\n     */\\n    readonly response: any;\\n    /**\\n     * Returns response as text.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if responseType is not the empty string or \\\"text\\\".\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseText)\\n     */\\n    readonly responseText: string;\\n    /**\\n     * Returns the response type.\\n     *\\n     * Can be set to change the response type. Values are: the empty string (default), \\\"arraybuffer\\\", \\\"blob\\\", \\\"document\\\", \\\"json\\\", and \\\"text\\\".\\n     *\\n     * When set: setting to \\\"document\\\" is ignored if current global object is not a Window object.\\n     *\\n     * When set: throws an \\\"InvalidStateError\\\" DOMException if state is loading or done.\\n     *\\n     * When set: throws an \\\"InvalidAccessError\\\" DOMException if the synchronous flag is set and current global object is a Window object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseType)\\n     */\\n    responseType: XMLHttpRequestResponseType;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/responseURL) */\\n    readonly responseURL: string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/status) */\\n    readonly status: number;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/statusText) */\\n    readonly statusText: string;\\n    /**\\n     * Can be set to a time in milliseconds. When set to a non-zero value will cause fetching to terminate after the given time has passed. When the time has passed, the request has not yet completed, and this's synchronous flag is unset, a timeout event will then be dispatched, or a \\\"TimeoutError\\\" DOMException will be thrown otherwise (for the send() method).\\n     *\\n     * When set: throws an \\\"InvalidAccessError\\\" DOMException if the synchronous flag is set and current global object is a Window object.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/timeout)\\n     */\\n    timeout: number;\\n    /**\\n     * Returns the associated XMLHttpRequestUpload object. It can be used to gather transmission information when data is transferred to a server.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/upload)\\n     */\\n    readonly upload: XMLHttpRequestUpload;\\n    /**\\n     * True when credentials are to be included in a cross-origin request. False when they are to be excluded in a cross-origin request and when cookies are to be ignored in its response. Initially false.\\n     *\\n     * When set: throws an \\\"InvalidStateError\\\" DOMException if state is not unsent or opened, or if the send() flag is set.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/withCredentials)\\n     */\\n    withCredentials: boolean;\\n    /**\\n     * Cancels any network activity.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/abort)\\n     */\\n    abort(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/getAllResponseHeaders) */\\n    getAllResponseHeaders(): string;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/getResponseHeader) */\\n    getResponseHeader(name: string): string | null;\\n    /**\\n     * Sets the request method, request URL, and synchronous flag.\\n     *\\n     * Throws a \\\"SyntaxError\\\" DOMException if either method is not a valid method or url cannot be parsed.\\n     *\\n     * Throws a \\\"SecurityError\\\" DOMException if method is a case-insensitive match for `CONNECT`, `TRACE`, or `TRACK`.\\n     *\\n     * Throws an \\\"InvalidAccessError\\\" DOMException if async is false, current global object is a Window object, and the timeout attribute is not zero or the responseType attribute is not the empty string.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/open)\\n     */\\n    open(method: string, url: string | URL): void;\\n    open(method: string, url: string | URL, async: boolean, username?: string | null, password?: string | null): void;\\n    /**\\n     * Acts as if the `Content-Type` header value for a response is mime. (It does not change the header.)\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if state is loading or done.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/overrideMimeType)\\n     */\\n    overrideMimeType(mime: string): void;\\n    /**\\n     * Initiates the request. The body argument provides the request body, if any, and is ignored if the request method is GET or HEAD.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if either state is not opened or the send() flag is set.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/send)\\n     */\\n    send(body?: XMLHttpRequestBodyInit | null): void;\\n    /**\\n     * Combines a header in author request headers.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if either state is not opened or the send() flag is set.\\n     *\\n     * Throws a \\\"SyntaxError\\\" DOMException if name is not a header name or if value is not a header value.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/setRequestHeader)\\n     */\\n    setRequestHeader(name: string, value: string): void;\\n    readonly UNSENT: 0;\\n    readonly OPENED: 1;\\n    readonly HEADERS_RECEIVED: 2;\\n    readonly LOADING: 3;\\n    readonly DONE: 4;\\n    addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var XMLHttpRequest: {\\n    prototype: XMLHttpRequest;\\n    new(): XMLHttpRequest;\\n    readonly UNSENT: 0;\\n    readonly OPENED: 1;\\n    readonly HEADERS_RECEIVED: 2;\\n    readonly LOADING: 3;\\n    readonly DONE: 4;\\n};\\n\\ninterface XMLHttpRequestEventTargetEventMap {\\n    \\\"abort\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"error\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"load\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"loadend\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"loadstart\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"progress\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n    \\\"timeout\\\": ProgressEvent<XMLHttpRequestEventTarget>;\\n}\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequestEventTarget) */\\ninterface XMLHttpRequestEventTarget extends EventTarget {\\n    onabort: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onerror: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onload: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onloadend: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onloadstart: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    onprogress: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    ontimeout: ((this: XMLHttpRequest, ev: ProgressEvent) => any) | null;\\n    addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var XMLHttpRequestEventTarget: {\\n    prototype: XMLHttpRequestEventTarget;\\n    new(): XMLHttpRequestEventTarget;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/XMLHttpRequestUpload) */\\ninterface XMLHttpRequestUpload extends XMLHttpRequestEventTarget {\\n    addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\n    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\n    removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\n    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\n}\\n\\ndeclare var XMLHttpRequestUpload: {\\n    prototype: XMLHttpRequestUpload;\\n    new(): XMLHttpRequestUpload;\\n};\\n\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console) */\\ninterface Console {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/assert) */\\n    assert(condition?: boolean, ...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/clear) */\\n    clear(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/count) */\\n    count(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/countReset) */\\n    countReset(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/debug) */\\n    debug(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/dir) */\\n    dir(item?: any, options?: any): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/dirxml) */\\n    dirxml(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/error) */\\n    error(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/group) */\\n    group(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/groupCollapsed) */\\n    groupCollapsed(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/groupEnd) */\\n    groupEnd(): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/info) */\\n    info(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log) */\\n    log(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/table) */\\n    table(tabularData?: any, properties?: string[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/time) */\\n    time(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeEnd) */\\n    timeEnd(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/timeLog) */\\n    timeLog(label?: string, ...data: any[]): void;\\n    timeStamp(label?: string): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/trace) */\\n    trace(...data: any[]): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/warn) */\\n    warn(...data: any[]): void;\\n}\\n\\ndeclare var console: Console;\\n\\ndeclare namespace WebAssembly {\\n    interface CompileError extends Error {\\n    }\\n\\n    var CompileError: {\\n        prototype: CompileError;\\n        new(message?: string): CompileError;\\n        (message?: string): CompileError;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Global) */\\n    interface Global<T extends ValueType = ValueType> {\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Global/value) */\\n        value: ValueTypeMap[T];\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Global/valueOf) */\\n        valueOf(): ValueTypeMap[T];\\n    }\\n\\n    var Global: {\\n        prototype: Global;\\n        new<T extends ValueType = ValueType>(descriptor: GlobalDescriptor<T>, v?: ValueTypeMap[T]): Global<T>;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance) */\\n    interface Instance {\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance/exports) */\\n        readonly exports: Exports;\\n    }\\n\\n    var Instance: {\\n        prototype: Instance;\\n        new(module: Module, importObject?: Imports): Instance;\\n    };\\n\\n    interface LinkError extends Error {\\n    }\\n\\n    var LinkError: {\\n        prototype: LinkError;\\n        new(message?: string): LinkError;\\n        (message?: string): LinkError;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory) */\\n    interface Memory {\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory/buffer) */\\n        readonly buffer: ArrayBuffer;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory/grow) */\\n        grow(delta: number): number;\\n    }\\n\\n    var Memory: {\\n        prototype: Memory;\\n        new(descriptor: MemoryDescriptor): Memory;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module) */\\n    interface Module {\\n    }\\n\\n    var Module: {\\n        prototype: Module;\\n        new(bytes: BufferSource): Module;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/customSections) */\\n        customSections(moduleObject: Module, sectionName: string): ArrayBuffer[];\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/exports) */\\n        exports(moduleObject: Module): ModuleExportDescriptor[];\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/imports) */\\n        imports(moduleObject: Module): ModuleImportDescriptor[];\\n    };\\n\\n    interface RuntimeError extends Error {\\n    }\\n\\n    var RuntimeError: {\\n        prototype: RuntimeError;\\n        new(message?: string): RuntimeError;\\n        (message?: string): RuntimeError;\\n    };\\n\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table) */\\n    interface Table {\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/length) */\\n        readonly length: number;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/get) */\\n        get(index: number): any;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/grow) */\\n        grow(delta: number, value?: any): number;\\n        /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/set) */\\n        set(index: number, value?: any): void;\\n    }\\n\\n    var Table: {\\n        prototype: Table;\\n        new(descriptor: TableDescriptor, value?: any): Table;\\n    };\\n\\n    interface GlobalDescriptor<T extends ValueType = ValueType> {\\n        mutable?: boolean;\\n        value: T;\\n    }\\n\\n    interface MemoryDescriptor {\\n        initial: number;\\n        maximum?: number;\\n        shared?: boolean;\\n    }\\n\\n    interface ModuleExportDescriptor {\\n        kind: ImportExportKind;\\n        name: string;\\n    }\\n\\n    interface ModuleImportDescriptor {\\n        kind: ImportExportKind;\\n        module: string;\\n        name: string;\\n    }\\n\\n    interface TableDescriptor {\\n        element: TableKind;\\n        initial: number;\\n        maximum?: number;\\n    }\\n\\n    interface ValueTypeMap {\\n        anyfunc: Function;\\n        externref: any;\\n        f32: number;\\n        f64: number;\\n        i32: number;\\n        i64: bigint;\\n        v128: never;\\n    }\\n\\n    interface WebAssemblyInstantiatedSource {\\n        instance: Instance;\\n        module: Module;\\n    }\\n\\n    type ImportExportKind = \\\"function\\\" | \\\"global\\\" | \\\"memory\\\" | \\\"table\\\";\\n    type TableKind = \\\"anyfunc\\\" | \\\"externref\\\";\\n    type ExportValue = Function | Global | Memory | Table;\\n    type Exports = Record<string, ExportValue>;\\n    type ImportValue = ExportValue | number;\\n    type Imports = Record<string, ModuleImports>;\\n    type ModuleImports = Record<string, ImportValue>;\\n    type ValueType = keyof ValueTypeMap;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compile) */\\n    function compile(bytes: BufferSource): Promise<Module>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming) */\\n    function compileStreaming(source: Response | PromiseLike<Response>): Promise<Module>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate) */\\n    function instantiate(bytes: BufferSource, importObject?: Imports): Promise<WebAssemblyInstantiatedSource>;\\n    function instantiate(moduleObject: Module, importObject?: Imports): Promise<Instance>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming) */\\n    function instantiateStreaming(source: Response | PromiseLike<Response>, importObject?: Imports): Promise<WebAssemblyInstantiatedSource>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/validate) */\\n    function validate(bytes: BufferSource): boolean;\\n}\\n\\ninterface EncodedVideoChunkOutputCallback {\\n    (chunk: EncodedVideoChunk, metadata?: EncodedVideoChunkMetadata): void;\\n}\\n\\ninterface FrameRequestCallback {\\n    (time: DOMHighResTimeStamp): void;\\n}\\n\\ninterface LockGrantedCallback {\\n    (lock: Lock | null): any;\\n}\\n\\ninterface OnErrorEventHandlerNonNull {\\n    (event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error): any;\\n}\\n\\ninterface PerformanceObserverCallback {\\n    (entries: PerformanceObserverEntryList, observer: PerformanceObserver): void;\\n}\\n\\ninterface QueuingStrategySize<T = any> {\\n    (chunk: T): number;\\n}\\n\\ninterface ReportingObserverCallback {\\n    (reports: Report[], observer: ReportingObserver): void;\\n}\\n\\ninterface TransformerFlushCallback<O> {\\n    (controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;\\n}\\n\\ninterface TransformerStartCallback<O> {\\n    (controller: TransformStreamDefaultController<O>): any;\\n}\\n\\ninterface TransformerTransformCallback<I, O> {\\n    (chunk: I, controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSinkAbortCallback {\\n    (reason?: any): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSinkCloseCallback {\\n    (): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSinkStartCallback {\\n    (controller: WritableStreamDefaultController): any;\\n}\\n\\ninterface UnderlyingSinkWriteCallback<W> {\\n    (chunk: W, controller: WritableStreamDefaultController): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSourceCancelCallback {\\n    (reason?: any): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSourcePullCallback<R> {\\n    (controller: ReadableStreamController<R>): void | PromiseLike<void>;\\n}\\n\\ninterface UnderlyingSourceStartCallback<R> {\\n    (controller: ReadableStreamController<R>): any;\\n}\\n\\ninterface VideoFrameOutputCallback {\\n    (output: VideoFrame): void;\\n}\\n\\ninterface VoidFunction {\\n    (): void;\\n}\\n\\ninterface WebCodecsErrorCallback {\\n    (error: DOMException): void;\\n}\\n\\n/**\\n * Returns dedicatedWorkerGlobal's name, i.e. the value given to the Worker constructor. Primarily useful for debugging.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/name)\\n */\\ndeclare var name: string;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/message_event) */\\ndeclare var onmessage: ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/messageerror_event) */\\ndeclare var onmessageerror: ((this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any) | null;\\n/**\\n * Aborts dedicatedWorkerGlobal.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/close)\\n */\\ndeclare function close(): void;\\n/**\\n * Clones message and transmits it to the Worker object associated with dedicatedWorkerGlobal. transfer can be passed as a list of objects that are to be transferred rather than cloned.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/postMessage)\\n */\\ndeclare function postMessage(message: any, transfer: Transferable[]): void;\\ndeclare function postMessage(message: any, options?: StructuredSerializeOptions): void;\\n/**\\n * Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/dispatchEvent)\\n */\\ndeclare function dispatchEvent(event: Event): boolean;\\n/**\\n * Returns workerGlobal's WorkerLocation object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/location)\\n */\\ndeclare var location: WorkerLocation;\\n/**\\n * Returns workerGlobal's WorkerNavigator object.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/navigator)\\n */\\ndeclare var navigator: WorkerNavigator;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/error_event) */\\ndeclare var onerror: ((this: DedicatedWorkerGlobalScope, ev: ErrorEvent) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/languagechange_event) */\\ndeclare var onlanguagechange: ((this: DedicatedWorkerGlobalScope, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/offline_event) */\\ndeclare var onoffline: ((this: DedicatedWorkerGlobalScope, ev: Event) => any) | null;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/online_event) */\\ndeclare var ononline: ((this: DedicatedWorkerGlobalScope, ev: Event) => any) | null;\\ndeclare var onrejectionhandled: ((this: DedicatedWorkerGlobalScope, ev: PromiseRejectionEvent) => any) | null;\\ndeclare var onunhandledrejection: ((this: DedicatedWorkerGlobalScope, ev: PromiseRejectionEvent) => any) | null;\\n/**\\n * Returns workerGlobal.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/self)\\n */\\ndeclare var self: WorkerGlobalScope & typeof globalThis;\\n/**\\n * Fetches each URL in urls, executes them one-by-one in the order they are passed, and then returns (or throws if something went amiss).\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/WorkerGlobalScope/importScripts)\\n */\\ndeclare function importScripts(...urls: (string | URL)[]): void;\\n/**\\n * Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventTarget/dispatchEvent)\\n */\\ndeclare function dispatchEvent(event: Event): boolean;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/fonts) */\\ndeclare var fonts: FontFaceSet;\\n/**\\n * Available only in secure contexts.\\n *\\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/caches)\\n */\\ndeclare var caches: CacheStorage;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/crossOriginIsolated) */\\ndeclare var crossOriginIsolated: boolean;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/crypto_property) */\\ndeclare var crypto: Crypto;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/indexedDB) */\\ndeclare var indexedDB: IDBFactory;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/isSecureContext) */\\ndeclare var isSecureContext: boolean;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/origin) */\\ndeclare var origin: string;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/performance_property) */\\ndeclare var performance: Performance;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/atob) */\\ndeclare function atob(data: string): string;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/btoa) */\\ndeclare function btoa(data: string): string;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/clearInterval) */\\ndeclare function clearInterval(id: number | undefined): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/clearTimeout) */\\ndeclare function clearTimeout(id: number | undefined): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/createImageBitmap) */\\ndeclare function createImageBitmap(image: ImageBitmapSource, options?: ImageBitmapOptions): Promise<ImageBitmap>;\\ndeclare function createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/fetch) */\\ndeclare function fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/queueMicrotask) */\\ndeclare function queueMicrotask(callback: VoidFunction): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/reportError) */\\ndeclare function reportError(e: any): void;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/setInterval) */\\ndeclare function setInterval(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/setTimeout) */\\ndeclare function setTimeout(handler: TimerHandler, timeout?: number, ...arguments: any[]): number;\\n/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/structuredClone) */\\ndeclare function structuredClone<T = any>(value: T, options?: StructuredSerializeOptions): T;\\ndeclare function cancelAnimationFrame(handle: number): void;\\ndeclare function requestAnimationFrame(callback: FrameRequestCallback): number;\\ndeclare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;\\ndeclare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;\\ndeclare function removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, options?: boolean | EventListenerOptions): void;\\ndeclare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;\\ntype AlgorithmIdentifier = Algorithm | string;\\ntype AllowSharedBufferSource = ArrayBuffer | ArrayBufferView;\\ntype BigInteger = Uint8Array;\\ntype BinaryData = ArrayBuffer | ArrayBufferView;\\ntype BlobPart = BufferSource | Blob | string;\\ntype BodyInit = ReadableStream | XMLHttpRequestBodyInit;\\ntype BufferSource = ArrayBufferView | ArrayBuffer;\\ntype CSSKeywordish = string | CSSKeywordValue;\\ntype CSSNumberish = number | CSSNumericValue;\\ntype CSSPerspectiveValue = CSSNumericValue | CSSKeywordish;\\ntype CSSUnparsedSegment = string | CSSVariableReferenceValue;\\ntype CanvasImageSource = ImageBitmap | OffscreenCanvas | VideoFrame;\\ntype DOMHighResTimeStamp = number;\\ntype EpochTimeStamp = number;\\ntype EventListenerOrEventListenerObject = EventListener | EventListenerObject;\\ntype FileSystemWriteChunkType = BufferSource | Blob | string | WriteParams;\\ntype Float32List = Float32Array | GLfloat[];\\ntype FormDataEntryValue = File | string;\\ntype GLbitfield = number;\\ntype GLboolean = boolean;\\ntype GLclampf = number;\\ntype GLenum = number;\\ntype GLfloat = number;\\ntype GLint = number;\\ntype GLint64 = number;\\ntype GLintptr = number;\\ntype GLsizei = number;\\ntype GLsizeiptr = number;\\ntype GLuint = number;\\ntype GLuint64 = number;\\ntype HashAlgorithmIdentifier = AlgorithmIdentifier;\\ntype HeadersInit = [string, string][] | Record<string, string> | Headers;\\ntype IDBValidKey = number | string | Date | BufferSource | IDBValidKey[];\\ntype ImageBitmapSource = CanvasImageSource | Blob | ImageData;\\ntype Int32List = Int32Array | GLint[];\\ntype MessageEventSource = MessagePort | ServiceWorker;\\ntype NamedCurve = string;\\ntype OffscreenRenderingContext = OffscreenCanvasRenderingContext2D | ImageBitmapRenderingContext | WebGLRenderingContext | WebGL2RenderingContext;\\ntype OnErrorEventHandler = OnErrorEventHandlerNonNull | null;\\ntype PerformanceEntryList = PerformanceEntry[];\\ntype PushMessageDataInit = BufferSource | string;\\ntype ReadableStreamController<T> = ReadableStreamDefaultController<T> | ReadableByteStreamController;\\ntype ReadableStreamReadResult<T> = ReadableStreamReadValueResult<T> | ReadableStreamReadDoneResult<T>;\\ntype ReadableStreamReader<T> = ReadableStreamDefaultReader<T> | ReadableStreamBYOBReader;\\ntype ReportList = Report[];\\ntype RequestInfo = Request | string;\\ntype TexImageSource = ImageBitmap | ImageData | OffscreenCanvas | VideoFrame;\\ntype TimerHandler = string | Function;\\ntype Transferable = OffscreenCanvas | ImageBitmap | MessagePort | ReadableStream | WritableStream | TransformStream | VideoFrame | ArrayBuffer;\\ntype Uint32List = Uint32Array | GLuint[];\\ntype VibratePattern = number | number[];\\ntype XMLHttpRequestBodyInit = Blob | BufferSource | FormData | URLSearchParams | string;\\ntype AlphaOption = \\\"discard\\\" | \\\"keep\\\";\\ntype AvcBitstreamFormat = \\\"annexb\\\" | \\\"avc\\\";\\ntype BinaryType = \\\"arraybuffer\\\" | \\\"blob\\\";\\ntype CSSMathOperator = \\\"clamp\\\" | \\\"invert\\\" | \\\"max\\\" | \\\"min\\\" | \\\"negate\\\" | \\\"product\\\" | \\\"sum\\\";\\ntype CSSNumericBaseType = \\\"angle\\\" | \\\"flex\\\" | \\\"frequency\\\" | \\\"length\\\" | \\\"percent\\\" | \\\"resolution\\\" | \\\"time\\\";\\ntype CanvasDirection = \\\"inherit\\\" | \\\"ltr\\\" | \\\"rtl\\\";\\ntype CanvasFillRule = \\\"evenodd\\\" | \\\"nonzero\\\";\\ntype CanvasFontKerning = \\\"auto\\\" | \\\"none\\\" | \\\"normal\\\";\\ntype CanvasFontStretch = \\\"condensed\\\" | \\\"expanded\\\" | \\\"extra-condensed\\\" | \\\"extra-expanded\\\" | \\\"normal\\\" | \\\"semi-condensed\\\" | \\\"semi-expanded\\\" | \\\"ultra-condensed\\\" | \\\"ultra-expanded\\\";\\ntype CanvasFontVariantCaps = \\\"all-petite-caps\\\" | \\\"all-small-caps\\\" | \\\"normal\\\" | \\\"petite-caps\\\" | \\\"small-caps\\\" | \\\"titling-caps\\\" | \\\"unicase\\\";\\ntype CanvasLineCap = \\\"butt\\\" | \\\"round\\\" | \\\"square\\\";\\ntype CanvasLineJoin = \\\"bevel\\\" | \\\"miter\\\" | \\\"round\\\";\\ntype CanvasTextAlign = \\\"center\\\" | \\\"end\\\" | \\\"left\\\" | \\\"right\\\" | \\\"start\\\";\\ntype CanvasTextBaseline = \\\"alphabetic\\\" | \\\"bottom\\\" | \\\"hanging\\\" | \\\"ideographic\\\" | \\\"middle\\\" | \\\"top\\\";\\ntype CanvasTextRendering = \\\"auto\\\" | \\\"geometricPrecision\\\" | \\\"optimizeLegibility\\\" | \\\"optimizeSpeed\\\";\\ntype ClientTypes = \\\"all\\\" | \\\"sharedworker\\\" | \\\"window\\\" | \\\"worker\\\";\\ntype CodecState = \\\"closed\\\" | \\\"configured\\\" | \\\"unconfigured\\\";\\ntype ColorGamut = \\\"p3\\\" | \\\"rec2020\\\" | \\\"srgb\\\";\\ntype ColorSpaceConversion = \\\"default\\\" | \\\"none\\\";\\ntype CompressionFormat = \\\"deflate\\\" | \\\"deflate-raw\\\" | \\\"gzip\\\";\\ntype DocumentVisibilityState = \\\"hidden\\\" | \\\"visible\\\";\\ntype EncodedVideoChunkType = \\\"delta\\\" | \\\"key\\\";\\ntype EndingType = \\\"native\\\" | \\\"transparent\\\";\\ntype FileSystemHandleKind = \\\"directory\\\" | \\\"file\\\";\\ntype FontDisplay = \\\"auto\\\" | \\\"block\\\" | \\\"fallback\\\" | \\\"optional\\\" | \\\"swap\\\";\\ntype FontFaceLoadStatus = \\\"error\\\" | \\\"loaded\\\" | \\\"loading\\\" | \\\"unloaded\\\";\\ntype FontFaceSetLoadStatus = \\\"loaded\\\" | \\\"loading\\\";\\ntype FrameType = \\\"auxiliary\\\" | \\\"nested\\\" | \\\"none\\\" | \\\"top-level\\\";\\ntype GlobalCompositeOperation = \\\"color\\\" | \\\"color-burn\\\" | \\\"color-dodge\\\" | \\\"copy\\\" | \\\"darken\\\" | \\\"destination-atop\\\" | \\\"destination-in\\\" | \\\"destination-out\\\" | \\\"destination-over\\\" | \\\"difference\\\" | \\\"exclusion\\\" | \\\"hard-light\\\" | \\\"hue\\\" | \\\"lighten\\\" | \\\"lighter\\\" | \\\"luminosity\\\" | \\\"multiply\\\" | \\\"overlay\\\" | \\\"saturation\\\" | \\\"screen\\\" | \\\"soft-light\\\" | \\\"source-atop\\\" | \\\"source-in\\\" | \\\"source-out\\\" | \\\"source-over\\\" | \\\"xor\\\";\\ntype HardwareAcceleration = \\\"no-preference\\\" | \\\"prefer-hardware\\\" | \\\"prefer-software\\\";\\ntype HdrMetadataType = \\\"smpteSt2086\\\" | \\\"smpteSt2094-10\\\" | \\\"smpteSt2094-40\\\";\\ntype IDBCursorDirection = \\\"next\\\" | \\\"nextunique\\\" | \\\"prev\\\" | \\\"prevunique\\\";\\ntype IDBRequestReadyState = \\\"done\\\" | \\\"pending\\\";\\ntype IDBTransactionDurability = \\\"default\\\" | \\\"relaxed\\\" | \\\"strict\\\";\\ntype IDBTransactionMode = \\\"readonly\\\" | \\\"readwrite\\\" | \\\"versionchange\\\";\\ntype ImageOrientation = \\\"flipY\\\" | \\\"from-image\\\" | \\\"none\\\";\\ntype ImageSmoothingQuality = \\\"high\\\" | \\\"low\\\" | \\\"medium\\\";\\ntype KeyFormat = \\\"jwk\\\" | \\\"pkcs8\\\" | \\\"raw\\\" | \\\"spki\\\";\\ntype KeyType = \\\"private\\\" | \\\"public\\\" | \\\"secret\\\";\\ntype KeyUsage = \\\"decrypt\\\" | \\\"deriveBits\\\" | \\\"deriveKey\\\" | \\\"encrypt\\\" | \\\"sign\\\" | \\\"unwrapKey\\\" | \\\"verify\\\" | \\\"wrapKey\\\";\\ntype LatencyMode = \\\"quality\\\" | \\\"realtime\\\";\\ntype LockMode = \\\"exclusive\\\" | \\\"shared\\\";\\ntype MediaDecodingType = \\\"file\\\" | \\\"media-source\\\" | \\\"webrtc\\\";\\ntype MediaEncodingType = \\\"record\\\" | \\\"webrtc\\\";\\ntype NotificationDirection = \\\"auto\\\" | \\\"ltr\\\" | \\\"rtl\\\";\\ntype NotificationPermission = \\\"default\\\" | \\\"denied\\\" | \\\"granted\\\";\\ntype OffscreenRenderingContextId = \\\"2d\\\" | \\\"bitmaprenderer\\\" | \\\"webgl\\\" | \\\"webgl2\\\" | \\\"webgpu\\\";\\ntype PermissionName = \\\"geolocation\\\" | \\\"notifications\\\" | \\\"persistent-storage\\\" | \\\"push\\\" | \\\"screen-wake-lock\\\" | \\\"xr-spatial-tracking\\\";\\ntype PermissionState = \\\"denied\\\" | \\\"granted\\\" | \\\"prompt\\\";\\ntype PredefinedColorSpace = \\\"display-p3\\\" | \\\"srgb\\\";\\ntype PremultiplyAlpha = \\\"default\\\" | \\\"none\\\" | \\\"premultiply\\\";\\ntype PushEncryptionKeyName = \\\"auth\\\" | \\\"p256dh\\\";\\ntype RTCEncodedVideoFrameType = \\\"delta\\\" | \\\"empty\\\" | \\\"key\\\";\\ntype ReadableStreamReaderMode = \\\"byob\\\";\\ntype ReadableStreamType = \\\"bytes\\\";\\ntype ReferrerPolicy = \\\"\\\" | \\\"no-referrer\\\" | \\\"no-referrer-when-downgrade\\\" | \\\"origin\\\" | \\\"origin-when-cross-origin\\\" | \\\"same-origin\\\" | \\\"strict-origin\\\" | \\\"strict-origin-when-cross-origin\\\" | \\\"unsafe-url\\\";\\ntype RequestCache = \\\"default\\\" | \\\"force-cache\\\" | \\\"no-cache\\\" | \\\"no-store\\\" | \\\"only-if-cached\\\" | \\\"reload\\\";\\ntype RequestCredentials = \\\"include\\\" | \\\"omit\\\" | \\\"same-origin\\\";\\ntype RequestDestination = \\\"\\\" | \\\"audio\\\" | \\\"audioworklet\\\" | \\\"document\\\" | \\\"embed\\\" | \\\"font\\\" | \\\"frame\\\" | \\\"iframe\\\" | \\\"image\\\" | \\\"manifest\\\" | \\\"object\\\" | \\\"paintworklet\\\" | \\\"report\\\" | \\\"script\\\" | \\\"sharedworker\\\" | \\\"style\\\" | \\\"track\\\" | \\\"video\\\" | \\\"worker\\\" | \\\"xslt\\\";\\ntype RequestMode = \\\"cors\\\" | \\\"navigate\\\" | \\\"no-cors\\\" | \\\"same-origin\\\";\\ntype RequestRedirect = \\\"error\\\" | \\\"follow\\\" | \\\"manual\\\";\\ntype ResizeQuality = \\\"high\\\" | \\\"low\\\" | \\\"medium\\\" | \\\"pixelated\\\";\\ntype ResponseType = \\\"basic\\\" | \\\"cors\\\" | \\\"default\\\" | \\\"error\\\" | \\\"opaque\\\" | \\\"opaqueredirect\\\";\\ntype SecurityPolicyViolationEventDisposition = \\\"enforce\\\" | \\\"report\\\";\\ntype ServiceWorkerState = \\\"activated\\\" | \\\"activating\\\" | \\\"installed\\\" | \\\"installing\\\" | \\\"parsed\\\" | \\\"redundant\\\";\\ntype ServiceWorkerUpdateViaCache = \\\"all\\\" | \\\"imports\\\" | \\\"none\\\";\\ntype TransferFunction = \\\"hlg\\\" | \\\"pq\\\" | \\\"srgb\\\";\\ntype VideoColorPrimaries = \\\"bt470bg\\\" | \\\"bt709\\\" | \\\"smpte170m\\\";\\ntype VideoEncoderBitrateMode = \\\"constant\\\" | \\\"quantizer\\\" | \\\"variable\\\";\\ntype VideoMatrixCoefficients = \\\"bt470bg\\\" | \\\"bt709\\\" | \\\"rgb\\\" | \\\"smpte170m\\\";\\ntype VideoPixelFormat = \\\"BGRA\\\" | \\\"BGRX\\\" | \\\"I420\\\" | \\\"I420A\\\" | \\\"I422\\\" | \\\"I444\\\" | \\\"NV12\\\" | \\\"RGBA\\\" | \\\"RGBX\\\";\\ntype VideoTransferCharacteristics = \\\"bt709\\\" | \\\"iec61966-2-1\\\" | \\\"smpte170m\\\";\\ntype WebGLPowerPreference = \\\"default\\\" | \\\"high-performance\\\" | \\\"low-power\\\";\\ntype WebTransportCongestionControl = \\\"default\\\" | \\\"low-latency\\\" | \\\"throughput\\\";\\ntype WebTransportErrorSource = \\\"session\\\" | \\\"stream\\\";\\ntype WorkerType = \\\"classic\\\" | \\\"module\\\";\\ntype WriteCommandType = \\\"seek\\\" | \\\"truncate\\\" | \\\"write\\\";\\ntype XMLHttpRequestResponseType = \\\"\\\" | \\\"arraybuffer\\\" | \\\"blob\\\" | \\\"document\\\" | \\\"json\\\" | \\\"text\\\";\\n\"\n  },\n  {\n    \"fileName\": \"lib.webworker.importscripts.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/////////////////////////////\\n/// WorkerGlobalScope APIs\\n/////////////////////////////\\n// These are only available in a Web Worker\\ndeclare function importScripts(...urls: string[]): void;\\n\"\n  },\n  {\n    \"fileName\": \"lib.webworker.iterable.d.ts\",\n    \"content\": \"/*! *****************************************************************************\\nCopyright (c) Microsoft Corporation. All rights reserved.\\nLicensed under the Apache License, Version 2.0 (the \\\"License\\\"); you may not use\\nthis file except in compliance with the License. You may obtain a copy of the\\nLicense at http://www.apache.org/licenses/LICENSE-2.0\\n\\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\\nMERCHANTABLITY OR NON-INFRINGEMENT.\\n\\nSee the Apache Version 2.0 License for specific language governing permissions\\nand limitations under the License.\\n***************************************************************************** */\\n\\n\\n/// <reference no-default-lib=\\\"true\\\"/>\\n\\n/////////////////////////////\\n/// Worker Iterable APIs\\n/////////////////////////////\\n\\ninterface CSSNumericArray {\\n    [Symbol.iterator](): IterableIterator<CSSNumericValue>;\\n    entries(): IterableIterator<[number, CSSNumericValue]>;\\n    keys(): IterableIterator<number>;\\n    values(): IterableIterator<CSSNumericValue>;\\n}\\n\\ninterface CSSTransformValue {\\n    [Symbol.iterator](): IterableIterator<CSSTransformComponent>;\\n    entries(): IterableIterator<[number, CSSTransformComponent]>;\\n    keys(): IterableIterator<number>;\\n    values(): IterableIterator<CSSTransformComponent>;\\n}\\n\\ninterface CSSUnparsedValue {\\n    [Symbol.iterator](): IterableIterator<CSSUnparsedSegment>;\\n    entries(): IterableIterator<[number, CSSUnparsedSegment]>;\\n    keys(): IterableIterator<number>;\\n    values(): IterableIterator<CSSUnparsedSegment>;\\n}\\n\\ninterface Cache {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Cache/addAll) */\\n    addAll(requests: Iterable<RequestInfo>): Promise<void>;\\n}\\n\\ninterface CanvasPath {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/roundRect) */\\n    roundRect(x: number, y: number, w: number, h: number, radii?: number | DOMPointInit | Iterable<number | DOMPointInit>): void;\\n}\\n\\ninterface CanvasPathDrawingStyles {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash) */\\n    setLineDash(segments: Iterable<number>): void;\\n}\\n\\ninterface DOMStringList {\\n    [Symbol.iterator](): IterableIterator<string>;\\n}\\n\\ninterface FileList {\\n    [Symbol.iterator](): IterableIterator<File>;\\n}\\n\\ninterface FontFaceSet extends Set<FontFace> {\\n}\\n\\ninterface FormData {\\n    [Symbol.iterator](): IterableIterator<[string, FormDataEntryValue]>;\\n    /** Returns an array of key, value pairs for every entry in the list. */\\n    entries(): IterableIterator<[string, FormDataEntryValue]>;\\n    /** Returns a list of keys in the list. */\\n    keys(): IterableIterator<string>;\\n    /** Returns a list of values in the list. */\\n    values(): IterableIterator<FormDataEntryValue>;\\n}\\n\\ninterface Headers {\\n    [Symbol.iterator](): IterableIterator<[string, string]>;\\n    /** Returns an iterator allowing to go through all key/value pairs contained in this object. */\\n    entries(): IterableIterator<[string, string]>;\\n    /** Returns an iterator allowing to go through all keys of the key/value pairs contained in this object. */\\n    keys(): IterableIterator<string>;\\n    /** Returns an iterator allowing to go through all values of the key/value pairs contained in this object. */\\n    values(): IterableIterator<string>;\\n}\\n\\ninterface IDBDatabase {\\n    /**\\n     * Returns a new transaction with the given mode (\\\"readonly\\\" or \\\"readwrite\\\") and scope which can be a single object store name or an array of names.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBDatabase/transaction)\\n     */\\n    transaction(storeNames: string | Iterable<string>, mode?: IDBTransactionMode, options?: IDBTransactionOptions): IDBTransaction;\\n}\\n\\ninterface IDBObjectStore {\\n    /**\\n     * Creates a new index in store with the given name, keyPath and options and returns a new IDBIndex. If the keyPath and options define constraints that cannot be satisfied with the data already in store the upgrade transaction will abort with a \\\"ConstraintError\\\" DOMException.\\n     *\\n     * Throws an \\\"InvalidStateError\\\" DOMException if not called within an upgrade transaction.\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/IDBObjectStore/createIndex)\\n     */\\n    createIndex(name: string, keyPath: string | Iterable<string>, options?: IDBIndexParameters): IDBIndex;\\n}\\n\\ninterface MessageEvent<T = any> {\\n    /**\\n     * @deprecated\\n     *\\n     * [MDN Reference](https://developer.mozilla.org/docs/Web/API/MessageEvent/initMessageEvent)\\n     */\\n    initMessageEvent(type: string, bubbles?: boolean, cancelable?: boolean, data?: any, origin?: string, lastEventId?: string, source?: MessageEventSource | null, ports?: Iterable<MessagePort>): void;\\n}\\n\\ninterface StylePropertyMapReadOnly {\\n    [Symbol.iterator](): IterableIterator<[string, Iterable<CSSStyleValue>]>;\\n    entries(): IterableIterator<[string, Iterable<CSSStyleValue>]>;\\n    keys(): IterableIterator<string>;\\n    values(): IterableIterator<Iterable<CSSStyleValue>>;\\n}\\n\\ninterface SubtleCrypto {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/deriveKey) */\\n    deriveKey(algorithm: AlgorithmIdentifier | EcdhKeyDeriveParams | HkdfParams | Pbkdf2Params, baseKey: CryptoKey, derivedKeyType: AlgorithmIdentifier | AesDerivedKeyParams | HmacImportParams | HkdfParams | Pbkdf2Params, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/generateKey) */\\n    generateKey(algorithm: RsaHashedKeyGenParams | EcKeyGenParams, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKeyPair>;\\n    generateKey(algorithm: AesKeyGenParams | HmacKeyGenParams | Pbkdf2Params, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;\\n    generateKey(algorithm: AlgorithmIdentifier, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKeyPair | CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/importKey) */\\n    importKey(format: \\\"jwk\\\", keyData: JsonWebKey, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;\\n    importKey(format: Exclude<KeyFormat, \\\"jwk\\\">, keyData: BufferSource, algorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKey>;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/SubtleCrypto/unwrapKey) */\\n    unwrapKey(format: KeyFormat, wrappedKey: BufferSource, unwrappingKey: CryptoKey, unwrapAlgorithm: AlgorithmIdentifier | RsaOaepParams | AesCtrParams | AesCbcParams | AesGcmParams, unwrappedKeyAlgorithm: AlgorithmIdentifier | RsaHashedImportParams | EcKeyImportParams | HmacImportParams | AesKeyAlgorithm, extractable: boolean, keyUsages: Iterable<KeyUsage>): Promise<CryptoKey>;\\n}\\n\\ninterface URLSearchParams {\\n    [Symbol.iterator](): IterableIterator<[string, string]>;\\n    /** Returns an array of key, value pairs for every entry in the search params. */\\n    entries(): IterableIterator<[string, string]>;\\n    /** Returns a list of keys in the search params. */\\n    keys(): IterableIterator<string>;\\n    /** Returns a list of values in the search params. */\\n    values(): IterableIterator<string>;\\n}\\n\\ninterface WEBGL_draw_buffers {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_draw_buffers/drawBuffersWEBGL) */\\n    drawBuffersWEBGL(buffers: Iterable<GLenum>): void;\\n}\\n\\ninterface WEBGL_multi_draw {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawArraysInstancedWEBGL) */\\n    multiDrawArraysInstancedWEBGL(mode: GLenum, firstsList: Int32Array | Iterable<GLint>, firstsOffset: GLuint, countsList: Int32Array | Iterable<GLsizei>, countsOffset: GLuint, instanceCountsList: Int32Array | Iterable<GLsizei>, instanceCountsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawArraysWEBGL) */\\n    multiDrawArraysWEBGL(mode: GLenum, firstsList: Int32Array | Iterable<GLint>, firstsOffset: GLuint, countsList: Int32Array | Iterable<GLsizei>, countsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawElementsInstancedWEBGL) */\\n    multiDrawElementsInstancedWEBGL(mode: GLenum, countsList: Int32Array | Iterable<GLsizei>, countsOffset: GLuint, type: GLenum, offsetsList: Int32Array | Iterable<GLsizei>, offsetsOffset: GLuint, instanceCountsList: Int32Array | Iterable<GLsizei>, instanceCountsOffset: GLuint, drawcount: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WEBGL_multi_draw/multiDrawElementsWEBGL) */\\n    multiDrawElementsWEBGL(mode: GLenum, countsList: Int32Array | Iterable<GLsizei>, countsOffset: GLuint, type: GLenum, offsetsList: Int32Array | Iterable<GLsizei>, offsetsOffset: GLuint, drawcount: GLsizei): void;\\n}\\n\\ninterface WebGL2RenderingContextBase {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferfv(buffer: GLenum, drawbuffer: GLint, values: Iterable<GLfloat>, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferiv(buffer: GLenum, drawbuffer: GLint, values: Iterable<GLint>, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/clearBuffer) */\\n    clearBufferuiv(buffer: GLenum, drawbuffer: GLint, values: Iterable<GLuint>, srcOffset?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/drawBuffers) */\\n    drawBuffers(buffers: Iterable<GLenum>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getActiveUniforms) */\\n    getActiveUniforms(program: WebGLProgram, uniformIndices: Iterable<GLuint>, pname: GLenum): any;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/getUniformIndices) */\\n    getUniformIndices(program: WebGLProgram, uniformNames: Iterable<string>): Iterable<GLuint> | null;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/invalidateFramebuffer) */\\n    invalidateFramebuffer(target: GLenum, attachments: Iterable<GLenum>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/invalidateSubFramebuffer) */\\n    invalidateSubFramebuffer(target: GLenum, attachments: Iterable<GLenum>, x: GLint, y: GLint, width: GLsizei, height: GLsizei): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/transformFeedbackVaryings) */\\n    transformFeedbackVaryings(program: WebGLProgram, varyings: Iterable<string>, bufferMode: GLenum): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform1uiv(location: WebGLUniformLocation | null, data: Iterable<GLuint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform2uiv(location: WebGLUniformLocation | null, data: Iterable<GLuint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform3uiv(location: WebGLUniformLocation | null, data: Iterable<GLuint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniform) */\\n    uniform4uiv(location: WebGLUniformLocation | null, data: Iterable<GLuint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix2x3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix2x4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix3x2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix3x4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix4x2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/uniformMatrix) */\\n    uniformMatrix4x3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4iv(index: GLuint, values: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGL2RenderingContext/vertexAttribI) */\\n    vertexAttribI4uiv(index: GLuint, values: Iterable<GLuint>): void;\\n}\\n\\ninterface WebGL2RenderingContextOverloads {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1fv(location: WebGLUniformLocation | null, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1iv(location: WebGLUniformLocation | null, data: Iterable<GLint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2fv(location: WebGLUniformLocation | null, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2iv(location: WebGLUniformLocation | null, data: Iterable<GLint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3fv(location: WebGLUniformLocation | null, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3iv(location: WebGLUniformLocation | null, data: Iterable<GLint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4fv(location: WebGLUniformLocation | null, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4iv(location: WebGLUniformLocation | null, data: Iterable<GLint>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, data: Iterable<GLfloat>, srcOffset?: GLuint, srcLength?: GLuint): void;\\n}\\n\\ninterface WebGLRenderingContextBase {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib1fv(index: GLuint, values: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib2fv(index: GLuint, values: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib3fv(index: GLuint, values: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/vertexAttrib) */\\n    vertexAttrib4fv(index: GLuint, values: Iterable<GLfloat>): void;\\n}\\n\\ninterface WebGLRenderingContextOverloads {\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform1iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform2iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform3iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4fv(location: WebGLUniformLocation | null, v: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniform) */\\n    uniform4iv(location: WebGLUniformLocation | null, v: Iterable<GLint>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix2fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix3fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;\\n    /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebGLRenderingContext/uniformMatrix) */\\n    uniformMatrix4fv(location: WebGLUniformLocation | null, transpose: GLboolean, value: Iterable<GLfloat>): void;\\n}\\n\"\n  }\n]"
  },
  {
    "path": "compiler/companion/src/types/IstanbulLibInstrument.d.ts",
    "content": "// copied from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/istanbul-lib-instrument/index.d.ts\n// API docs for 4.0.3 version https://github.com/istanbuljs/istanbuljs/blob/istanbul-lib-instrument%404.0.3/packages/istanbul-lib-instrument/api.md\n\ndeclare module 'istanbul-lib-instrument' {\n  import { FileCoverage, FileCoverageData } from 'istanbul-lib-coverage';\n  import { RawSourceMap } from 'source-map';\n  import * as babelTypes from '@babel/types';\n  export interface InstrumenterOptions {\n    coverageVariable: string;\n    preserveComments: boolean;\n    compact: boolean;\n    esModules: boolean;\n    autoWrap: boolean;\n    produceSourceMap: boolean;\n    ignoreClassMethods: string[];\n    sourceMapUrlCallback(filename: string, url: string): void;\n    debug: boolean;\n    parserPlugins: string[];\n  }\n\n  export type InstrumenterCallback = (error: Error | null, code: string) => void;\n\n  export class Instrumenter {\n    fileCoverage: FileCoverage;\n    sourceMap: RawSourceMap | null;\n    opts: InstrumenterOptions;\n\n    constructor(options?: Partial<InstrumenterOptions>);\n\n    normalizeOpts(options?: Partial<InstrumenterOptions>): InstrumenterOptions;\n\n    instrumentSync(code: string, filename: string, inputSourceMap?: RawSourceMap): string;\n\n    instrument(\n      code: string,\n      filenameOrCallback: string | InstrumenterCallback,\n      callback?: InstrumenterCallback,\n      inputSourceMap?: RawSourceMap,\n    ): void;\n\n    lastFileCoverage(): FileCoverageData;\n    lastSourceMap(): RawSourceMap;\n  }\n\n  export function createInstrumenter(options?: Partial<InstrumenterOptions>): Instrumenter;\n\n  export interface InitialCoverage {\n    path: string;\n    hash: string;\n    gcv: any;\n    coverageData: any;\n  }\n\n  export function readInitialCoverage(code: string): InitialCoverage;\n\n  export interface Visitor {\n    enter(path: string): void;\n    exit(path: string): { fileCoverage: FileCoverage; sourceMappingURL: string };\n  }\n\n  export interface VisitorOptions {\n    coverageVariable: string;\n    inputSourceMap: RawSourceMap;\n  }\n\n  export function programVisitor(\n    types: typeof babelTypes,\n    sourceFilePath?: string,\n    opts?: Partial<VisitorOptions>,\n  ): Visitor;\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/EmitResolver.ts",
    "content": "import * as ts from 'typescript';\n\nexport interface SymbolTracker {}\n\nexport interface EmitResolver {\n  hasGlobalName(name: string): boolean;\n  getReferencedExportContainer(\n    node: ts.Identifier,\n    prefixLocals?: boolean,\n  ): ts.SourceFile | ts.ModuleDeclaration | ts.EnumDeclaration | undefined;\n  getReferencedImportDeclaration(node: ts.Identifier): ts.Declaration | undefined;\n  getReferencedDeclarationWithCollidingName(node: ts.Identifier): ts.Declaration | undefined;\n  isDeclarationWithCollidingName(node: ts.Declaration): boolean;\n  isValueAliasDeclaration(node: ts.Node): boolean;\n  isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean;\n  isTopLevelValueImportEqualsWithEntityName(node: ts.ImportEqualsDeclaration): boolean;\n  // getNodeCheckFlags(node: Node): NodeCheckFlags;\n  // isDeclarationVisible(node: ts.Declaration | AnyImportSyntax): boolean;\n  // isLateBound(node: ts.Declaration): node is ts.LateBoundDeclaration;\n  collectLinkedAliases(node: ts.Identifier, setVisibility?: boolean): Node[] | undefined;\n  isImplementationOfOverload(node: ts.SignatureDeclaration): boolean | undefined;\n  isRequiredInitializedParameter(node: ts.ParameterDeclaration): boolean;\n  isOptionalUninitializedParameterProperty(node: ts.ParameterDeclaration): boolean;\n  isExpandoFunctionDeclaration(node: ts.FunctionDeclaration): boolean;\n  getPropertiesOfContainerFunction(node: ts.Declaration): Symbol[];\n  createTypeOfDeclaration(\n    declaration: ts.AccessorDeclaration | ts.VariableLikeDeclaration | ts.PropertyAccessExpression,\n    enclosingDeclaration: Node,\n    flags: ts.NodeBuilderFlags,\n    tracker: SymbolTracker,\n    addUndefined?: boolean,\n  ): ts.TypeNode | undefined;\n  createReturnTypeOfSignatureDeclaration(\n    signatureDeclaration: ts.SignatureDeclaration,\n    enclosingDeclaration: Node,\n    flags: ts.NodeBuilderFlags,\n    tracker: SymbolTracker,\n  ): ts.TypeNode | undefined;\n  createTypeOfExpression(\n    expr: ts.Expression,\n    enclosingDeclaration: Node,\n    flags: ts.NodeBuilderFlags,\n    tracker: SymbolTracker,\n  ): ts.TypeNode | undefined;\n  createLiteralConstValue(\n    node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration,\n    tracker: SymbolTracker,\n  ): ts.Expression;\n  // isSymbolAccessible(\n  //   symbol: Symbol,\n  //   enclosingDeclaration: Node | undefined,\n  //   meaning: ts.SymbolFlags | undefined,\n  //   shouldComputeAliasToMarkVisible: boolean,\n  // ): ts.SymbolAccessibilityResult;\n  // isEntityNameVisible(\n  //   entityName: ts.EntityNameOrEntityNameExpression,\n  //   enclosingDeclaration: Node,\n  // ): ts.SymbolVisibilityResult;\n  // Returns the constant value this property access resolves to, or 'undefined' for a non-constant\n  getConstantValue(\n    node: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression,\n  ): string | number | undefined;\n  getReferencedValueDeclaration(reference: ts.Identifier): ts.Declaration | undefined;\n  // getTypeReferenceSerializationKind(typeName: ts.EntityName, location?: Node): ts.TypeReferenceSerializationKind;\n  isOptionalParameter(node: ts.ParameterDeclaration): boolean;\n  moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean;\n  isArgumentsLocalBinding(node: ts.Identifier): boolean;\n  getExternalModuleFileFromDeclaration(\n    declaration:\n      | ts.ImportEqualsDeclaration\n      | ts.ImportDeclaration\n      | ts.ExportDeclaration\n      | ts.ModuleDeclaration\n      | ts.ImportTypeNode\n      | ts.ImportCall,\n  ): ts.SourceFile | undefined;\n  getTypeReferenceDirectivesForEntityName(name: ts.EntityNameOrEntityNameExpression): string[] | undefined;\n  getTypeReferenceDirectivesForSymbol(symbol: Symbol, meaning?: ts.SymbolFlags): string[] | undefined;\n  isLiteralConstDeclaration(\n    node: ts.VariableDeclaration | ts.PropertyDeclaration | ts.PropertySignature | ts.ParameterDeclaration,\n  ): boolean;\n  getJsxFactoryEntity(location?: Node): ts.EntityName | undefined;\n  getJsxFragmentFactoryEntity(location?: Node): ts.EntityName | undefined;\n  // getAllAccessorDeclarations(declaration: ts.AccessorDeclaration): ts.AllAccessorDeclarations;\n  getSymbolOfExternalModuleSpecifier(node: ts.StringLiteralLike): Symbol | undefined;\n  // isBindingCapturedByNode(node: Node, decl: ts.VariableDeclaration | BindingElement): boolean;\n  getDeclarationStatementsForSourceFile(\n    node: ts.SourceFile,\n    flags: ts.NodeBuilderFlags,\n    tracker: SymbolTracker,\n    bundled?: boolean,\n  ): ts.Statement[] | undefined;\n  isImportRequiredByAugmentation(decl: ts.ImportDeclaration): boolean;\n}\n\ninterface EmitResolverProvider {\n  getEmitResolver(sourceFile: ts.SourceFile, cancellationToken: ts.CancellationToken): EmitResolver;\n}\n\nexport function getEmitResolver(\n  typeChecker: ts.TypeChecker,\n  sourceFile: ts.SourceFile,\n  cancellationToken: ts.CancellationToken | undefined,\n): EmitResolver {\n  const provider = typeChecker as unknown as EmitResolverProvider;\n  if (!provider.getEmitResolver) {\n    throw new Error('Could not resolve getEmitResolver() fn');\n  }\n\n  return provider.getEmitResolver(sourceFile, cancellationToken as any);\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/ImportPathResolver.ts",
    "content": "import * as ts from 'typescript';\nimport * as _path from 'path';\nimport { Lazy } from './Lazy';\nimport { FilePath } from '../project/FileManager';\n\nfunction toAbsoluteImportPath(dirname: string, toPath: string): string {\n  if (toPath.startsWith('.') || toPath.startsWith('/')) {\n    return _path.resolve(dirname, toPath);\n  } else {\n    // Absolute import path\n    return _path.join('/', toPath);\n  }\n}\n\nexport class ImportPathResolver {\n  private resolvedPaths = new Map<string, string>();\n  private resolvedFilePathByAlias = new Map<string, FilePath>();\n  private didResolvePathsFromCompilerOptions = false;\n  private getCompilerOptionsLazy: Lazy<ts.CompilerOptions>;\n\n  constructor(getCompilerOptions: () => ts.CompilerOptions) {\n    this.getCompilerOptionsLazy = new Lazy(getCompilerOptions);\n  }\n\n  resolveImportPath(fromPath: string, toPath: string): string {\n    if (!this.didResolvePathsFromCompilerOptions) {\n      this.didResolvePathsFromCompilerOptions = true;\n      this.resolvePathsFromCompilerOptions();\n    }\n\n    const dirname = _path.dirname(fromPath);\n    const resolvedPath = this.resolvedPaths.get(toPath) ?? toPath;\n    return toAbsoluteImportPath(dirname, resolvedPath);\n  }\n\n  registerAlias(filePath: FilePath): void {\n    const fileName = filePath.pathComponents[filePath.pathComponents.length - 1];\n\n    const indexOfDot = fileName.lastIndexOf('.');\n    if (indexOfDot < 0) {\n      return;\n    }\n\n    // Register an alias where the file is available without its extension\n    let resolvedAlias = filePath.absolutePath.substring(0, filePath.absolutePath.length - fileName.length + indexOfDot);\n\n    if (resolvedAlias.endsWith('.d')) {\n      resolvedAlias = resolvedAlias.substr(0, resolvedAlias.length - 2);\n    }\n\n    this.updateAliasIfNeeded(resolvedAlias, filePath);\n\n    if (resolvedAlias.endsWith('/index')) {\n      this.updateAliasIfNeeded(resolvedAlias.substring(0, resolvedAlias.length - 6), filePath);\n    }\n  }\n\n  getAlias(filePath: FilePath): FilePath | undefined {\n    return this.resolvedFilePathByAlias.get(filePath.absolutePath);\n  }\n\n  private updateAliasIfNeeded(resolvedAlias: string, filePath: FilePath): boolean {\n    const existingAlias = this.resolvedFilePathByAlias.get(resolvedAlias);\n    if (!existingAlias || (existingAlias.pathExtension === '.js' && filePath.pathExtension !== '.js')) {\n      this.resolvedFilePathByAlias.set(resolvedAlias, filePath);\n      return true;\n    }\n\n    return false;\n  }\n\n  private resolvePathsFromCompilerOptions(): void {\n    const compilerOptions = this.getCompilerOptionsLazy.target;\n    if (!compilerOptions.paths) {\n      return;\n    }\n\n    const baseUrl = compilerOptions.baseUrl ?? '/';\n\n    const keys = Object.keys(compilerOptions.paths);\n\n    for (const key of keys) {\n      const entries = compilerOptions.paths[key]!;\n      // TODO(simon): We don't support multiple search path here\n      const entry = entries[0];\n      const resolvedEntry = toAbsoluteImportPath(baseUrl, entry);\n\n      this.resolvedPaths.set(key, resolvedEntry);\n    }\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/Lazy.ts",
    "content": "export class Lazy<T> {\n  private value?: { value: T };\n  private work?: () => T;\n\n  constructor(work: () => T) {\n    this.work = work;\n  }\n\n  get target(): T {\n    if (!this.value) {\n      this.value = { value: this.work!() };\n      this.work = undefined;\n    }\n    return this.value.value;\n  }\n\n  loadIfNeeded(): boolean {\n    const previousValue = this.value;\n    const newValue = this.target;\n    return newValue !== previousValue;\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/SerialTaskQueue.ts",
    "content": "type PendingTask = (done: () => void) => void;\n\nexport class SerialTaskQueue {\n  private ready: boolean = true;\n  private pendingTasks: PendingTask[] = [];\n\n  enqueueTask<T>(operation: () => T): Promise<T> {\n    return new Promise((resolve, reject) => {\n      this.doEnqueueTask((done) => {\n        try {\n          const result = operation();\n          resolve(result);\n        } catch (err) {\n          reject(err);\n        } finally {\n          done();\n        }\n      });\n    });\n  }\n\n  enqueueAsyncTask<T>(operation: () => Promise<T>): Promise<T> {\n    return new Promise((resolve, reject) => {\n      this.doEnqueueTask((done) => {\n        operation()\n          .then((result) => {\n            resolve(result);\n          })\n          .catch((err) => {\n            reject(err);\n          })\n          .finally(done);\n      });\n    });\n  }\n\n  private doEnqueueTask(task: PendingTask) {\n    this.pendingTasks.push(task);\n    this.flushTasks();\n  }\n\n  private flushTasks() {\n    if (this.ready && this.pendingTasks.length) {\n      const operation = this.pendingTasks.shift()!;\n      this.ready = false;\n      operation(() => {\n        this.ready = true;\n        this.flushTasks();\n      });\n    }\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/Stopwatch.ts",
    "content": "export class Stopwatch {\n  private timeAtStart: number = 0;\n\n  get elapsedSeconds(): number {\n    return this.elapsedMilliseconds / 1000.0;\n  }\n\n  get elapsedMilliseconds(): number {\n    return performance.now() - this.timeAtStart;\n  }\n\n  get elapsedString(): string {\n    let current = this.elapsedMilliseconds;\n    let unit = 'ms';\n    let precision = 2;\n    if (current > 1000) {\n      current /= 1000;\n      unit = 's';\n      precision = 3;\n    }\n\n    return `${current.toFixed(precision)}${unit}`;\n  }\n\n  constructor() {\n    this.start();\n  }\n\n  start() {\n    this.timeAtStart = performance.now();\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/StringUtils.ts",
    "content": "export function trimAllLines(str: string): string {\n  const outLines: string[] = [];\n\n  for (const line of str.split('\\n')) {\n    const trimmed = line.trim();\n\n    if (trimmed) {\n      outLines.push(trimmed);\n    }\n  }\n\n  return outLines.join('\\n');\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/TextParser.ts",
    "content": "export const enum CharCode {\n  space = 32,\n  newline = 10,\n  doubleQuote = 34,\n  dollar = 36,\n  singleQuote = 39,\n  semiColon = 59,\n  underscore = 95,\n}\n\nexport class TextParser {\n  position = 0;\n  private currentLine = 0;\n  private currentLineGlobalPosition = 0;\n\n  constructor(readonly text: string) {}\n\n  debugPositionString(): string {\n    return `line ${this.currentLine + 1}, column: ${this.position - this.currentLineGlobalPosition + 1}`;\n  }\n\n  private onError(message: string): never {\n    throw new Error(`At ${this.debugPositionString()}: ${message}`);\n  }\n\n  isAtEnd(): boolean {\n    return this.position >= this.text.length;\n  }\n\n  parse(term: string): void {\n    if (!this.tryParse(term)) {\n      this.onError(`Expecting '${term}'`);\n    }\n  }\n\n  parseQuotedString(): string {\n    if (this.tryParse('\"')) {\n      return this.parseUntilCharCode(CharCode.doubleQuote);\n    } else {\n      this.parse(\"'\");\n      return this.parseUntilCharCode(CharCode.singleQuote);\n    }\n  }\n\n  parseUntilCharCode(charCode: number): string {\n    let startPosition = this.position;\n    let endPosition = startPosition;\n    let foundCharCode = false;\n\n    while (endPosition < this.text.length) {\n      const code = this.text.charCodeAt(endPosition);\n      endPosition++;\n      if (code === charCode) {\n        foundCharCode = true;\n        break;\n      }\n    }\n\n    this.position = endPosition;\n\n    return this.text.substring(startPosition, foundCharCode ? endPosition - 1 : endPosition);\n  }\n\n  peek(term: string): boolean {\n    this.consumeWhitespaces();\n\n    let position = this.position;\n    if (this.tryParse(term)) {\n      this.position = position;\n      return true;\n    }\n    return false;\n  }\n\n  tryParse(term: string): boolean {\n    this.consumeWhitespaces();\n\n    for (let i = 0; i < term.length; i++) {\n      if (term.charCodeAt(i) !== this.text.charCodeAt(this.position + i)) {\n        return false;\n      }\n    }\n\n    this.position += term.length;\n    return true;\n  }\n\n  private isIdentifier(position: number): boolean {\n    const code = this.text.charCodeAt(position);\n    return (\n      (code > 47 && code < 58) ||\n      (code > 64 && code < 91) ||\n      (code > 96 && code < 123) ||\n      code === CharCode.underscore ||\n      code === CharCode.dollar\n    );\n  }\n\n  isAtIdentifier(): boolean {\n    this.consumeWhitespaces();\n    return this.isIdentifier(this.position);\n  }\n\n  parseIdentifier(): string {\n    this.consumeWhitespaces();\n    let startPosition = this.position;\n    let endPosition = startPosition;\n\n    for (;;) {\n      if (this.isIdentifier(endPosition)) {\n        endPosition++;\n      } else {\n        break;\n      }\n    }\n\n    if (startPosition === endPosition) {\n      this.onError('Not an identifier');\n    }\n\n    this.position = endPosition;\n\n    return this.text.substring(startPosition, endPosition);\n  }\n\n  skipCurrentLine(): void {\n    while (!this.isAtEnd()) {\n      const code = this.text.charCodeAt(this.position);\n      if (code === CharCode.newline) {\n        this.position++;\n        this.currentLine++;\n        this.currentLineGlobalPosition = this.position;\n        return;\n      } else {\n        this.position++;\n      }\n    }\n  }\n\n  private consumeWhitespaces() {\n    for (;;) {\n      let code = this.text.charCodeAt(this.position);\n      if (code === CharCode.space) {\n        this.position++;\n      } else if (code === CharCode.newline) {\n        this.position++;\n        this.currentLine++;\n        this.currentLineGlobalPosition = this.position;\n      } else {\n        break;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/companionTransport.ts",
    "content": "import { ResponseBody, TransportPayload } from '../protocol';\n\nexport function send(payload: TransportPayload) {\n  const output = JSON.stringify(payload) + '\\n';\n  process.stdout.write(output);\n}\n\n/**\n * Send a successful response to a Compiler request with ID `id`\n */\n\nexport function sendResponse(id: string, body: ResponseBody) {\n  send({\n    id: id,\n    body,\n  });\n}\n\n/**\n * Send a failed response to a Compiler request with ID `id`\n */\nexport function sendError(id: string, err: Error) {\n  send({\n    id: id,\n    error: `CompilerCompanion error: (rid: ${id}) ${err.message}`,\n  });\n}\n\n/**\n * Notify the Compiler that an event has occurred.\n *\n * Events are sent without an `id`, since they can happen at any time,\n * without necessarily corresponding to processing a particular request\n */\nexport function sendEvent(type: string, message: string) {\n  send({ event: { type, message: message } });\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/fileUtils.ts",
    "content": "import { stat, readdir } from 'fs/promises';\nimport * as path from 'path';\n\n// Asynchronous utility function to check if a file/directory exists at the provided path.\nexport async function fileExists(path: string): Promise<boolean> {\n  try {\n    await stat(path);\n  } catch (error) {\n    const nodeError = error as NodeJS.ErrnoException;\n    if (nodeError.code && nodeError.code === 'ENOENT') {\n      // path doesn't exist\n      return false;\n    }\n\n    // some other error - rethrow\n    throw error;\n  }\n  return true;\n}\n\nexport async function forEachFile(dir: string, cb: (filePath: string) => void): Promise<void> {\n  const dirents = await readdir(dir, { withFileTypes: true });\n\n  for (const dirent of dirents) {\n    const filePath = path.join(dir, dirent.name);\n    if (dirent.isDirectory()) {\n      await forEachFile(filePath, cb);\n    } else {\n      cb(filePath);\n    }\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/getArgumentValue.ts",
    "content": "export function getArgumentValue(name: string) {\n  const index = process.argv.indexOf(name) + 1;\n  if (index >= process.argv.length) {\n    throw new Error(`Missing associated argument value for ${name}`);\n  }\n  return process.argv[index];\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/rethrow.ts",
    "content": "export function rethrow(messagePrefix: string, error: unknown): never {\n  if (error instanceof Error) {\n    const newError = new Error(messagePrefix + ': ' + error.message);\n    newError.stack = error.stack;\n    throw newError;\n  } else {\n    throw new Error(messagePrefix);\n  }\n}\n"
  },
  {
    "path": "compiler/companion/src/utils/sha256.ts",
    "content": "import { createHash } from 'crypto';\n\n/**\n * Generates the SHA256 hash of a file.\n * @param fileContent - The content of the file represented as a UInt8Array.\n * @returns the SHA256 hash of the file.\n */\nexport function generateSHA256Hash(fileContent: Uint8Array): string {\n  return createHash('sha256').update(fileContent).digest('hex');\n}\n\n/**\n * Generates the SHA256 hash of a string.\n * @param data - The content of the file represented as a string.\n * @returns the SHA256 hash of the file.\n */\nexport function generateSHA256HashFromString(data: string): string {\n  return generateSHA256HashFromStrings([data]);\n}\n\n/**\n * Generates the SHA256 hash of a set of strings\n * @param data - The content of the file represented as an array of string\n * @returns the SHA256 hash of the file.\n */\nexport function generateSHA256HashFromStrings(data: string[]): string {\n  const hash = createHash('sha256');\n  for (const entry of data) {\n    hash.update(entry, 'utf-8');\n  }\n\n  return hash.digest('hex');\n}\n"
  },
  {
    "path": "compiler/companion/supported-locales/.gitignore",
    "content": "node_modules/\n!.vscode\nout\n!dist/\n"
  },
  {
    "path": "compiler/companion/supported-locales/.npmrc",
    "content": "# Better compatibility between rules_js and pnpm\n# https://docs.aspect.build/guides/rules_js_migration/#translate-your-lockfile-to-pnpm-format-optional\nhoist=false"
  },
  {
    "path": "compiler/companion/supported-locales/package.json",
    "content": "{\n  \"name\": \"supported-locales\",\n  \"license\": \"UNLICENSED\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Supported locales\",\n  \"main\": \"./out/index.js\",\n  \"types\": \"./out/index.d.ts\",\n  \"scripts\": {\n    \"build\": \"tsc\"\n  },\n  \"dependencies\": {\n    \"typescript\": \"5.1.6\"\n  }\n}\n"
  },
  {
    "path": "compiler/companion/supported-locales/src/index.ts",
    "content": "// This file defines the list of supported input locales and the corresponding output locales for iOS and Android,\n// since some regional locale names are actually different between the two platforms. For example:\n// input locale (web-like): zh-Hant\n// ios: zh-Hant\n// android: zh-rTW\n//\n// If Localization Engineering ever supports new locales, we'll need to update these mappings.\n\nexport interface LocaleMapRecord {\n  ios: string;\n  android: string;\n}\n\nexport let fullLocaleMap = new Map<string, LocaleMapRecord>();\n\nconst inputLocales = [\n  'ar',\n  'bn-BD',\n  'bn-IN',\n  'da-DK',\n  'de-DE',\n  'el-GR',\n  'en-GB',\n  'en-US',\n  'es',\n  'es-AR',\n  'es-ES',\n  'es-MX',\n  'fi-FI',\n  'fil-PH',\n  'fr-FR',\n  'gu-IN',\n  'hi-IN',\n  'id-ID',\n  'it-IT',\n  'ja-JP',\n  'kn-IN',\n  'ko-KR',\n  'ml-IN',\n  'mr-IN',\n  'ms-MY',\n  'nb-NO',\n  'nl-NL',\n  'pa',\n  'pl-PL',\n  'pt-BR',\n  'pt-PT',\n  'ro-RO',\n  'ru-RU',\n  'sv-SE',\n  'ta-IN',\n  'te-IN',\n  'th-TH',\n  'tr-TR',\n  'ur-PK',\n  'vi-VN',\n  'zh-Hans',\n  'zh-Hant',\n];\n\nconst iosLocales = [\n  'ar',\n  'bn-BD',\n  'bn-IN',\n  'da',\n  'de',\n  'el',\n  'en-GB',\n  'en-US',\n  'es',\n  'es-AR',\n  'es-ES',\n  'es-MX',\n  'fi',\n  'fil-PH',\n  'fr',\n  'gu-IN',\n  'hi-IN',\n  'id',\n  'it',\n  'ja',\n  'kn-IN',\n  'ko',\n  'ml-IN',\n  'mr-IN',\n  'ms-MY',\n  'nb',\n  'nl',\n  'pa-IN',\n  'pl',\n  'pt',\n  'pt-PT',\n  'ro',\n  'ru',\n  'sv',\n  'ta-IN',\n  'te-IN',\n  'th-TH',\n  'tr',\n  'ur-PK',\n  'vi-VN',\n  'zh-Hans',\n  'zh-Hant',\n];\n\nconst androidLocales = [\n  'ar',\n  'bn-rBD',\n  'bn-rIN',\n  'da',\n  'de',\n  'el',\n  'en-rGB',\n  'en-rUS',\n  'es',\n  'es-rAR',\n  'es-rES',\n  'es-rMX',\n  'fi',\n  'fil-rPH',\n  'fr',\n  'gu-rIN',\n  'hi-rIN',\n  'in',\n  'it',\n  'ja',\n  'kn-rIN',\n  'ko',\n  'ml-rIN',\n  'mr-rIN',\n  'ms-rMY',\n  'nb',\n  'nl',\n  'pa-rIN',\n  'pl',\n  'pt',\n  'pt-rPT',\n  'ro',\n  'ru',\n  'sv',\n  'ta-rIN',\n  'te-rIN',\n  'th-rTH',\n  'tr',\n  'ur-rPK',\n  'vi-rVN',\n  'zh',\n  'zh-rTW',\n];\n\nfullLocaleMap.set('en', {\n  ios: 'en',\n  android: 'en',\n});\n\nfor (const [idx, inputLocale] of inputLocales.entries()) {\n  fullLocaleMap.set(inputLocale, {\n    ios: iosLocales[idx] as string,\n    android: androidLocales[idx] as string,\n  });\n}\n"
  },
  {
    "path": "compiler/companion/supported-locales/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    // Type Checking\n    \"exactOptionalPropertyTypes\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitOverride\": true,\n    \"noImplicitReturns\": true,\n    \"noPropertyAccessFromIndexSignature\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"strict\": true,\n\n    // Modules\n    \"module\": \"CommonJS\",\n    \"moduleResolution\": \"node\",\n    \"esModuleInterop\": true,\n    \"resolveJsonModule\": true,\n\n    // Emit\n    \"importHelpers\": true,\n    \"noEmitHelpers\": true,\n    \"noEmitOnError\": true,\n    \"removeComments\": true,\n\n    // Interop Constraints\n    \"allowSyntheticDefaultImports\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"isolatedModules\": true,\n\n    // Language and Environment\n    \"experimentalDecorators\": true,\n    \"lib\": [\"ESNext\"],\n    \"target\": \"ESNext\",\n    \"useDefineForClassFields\": true,\n\n    \"outDir\": \"./dist/\",\n    \"rootDir\": \"./src/\",\n    \"declaration\": true,\n    \"composite\": true,\n\n    // Needed to avoid error TS2430 when building\n    \"skipLibCheck\": true,\n  },\n  \"include\": [\"./src/**/*.ts\"]\n\n}\n"
  },
  {
    "path": "compiler/companion/tsconfig.base.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"commonjs\",\n    \"lib\": [\"es6\", \"dom\", \"es2022.intl\"],\n    \"declaration\": true,\n    \"noImplicitAny\": true,\n    \"noImplicitReturns\": true,\n    \"strict\": true,\n    \"moduleResolution\": \"node\",\n    \"typeRoots\": [\"@types\", \"node_modules/@types\", \"src/types\"],\n    \"sourceMap\": true,\n    \"composite\": true,\n    \"allowJs\": true,\n    \"outDir\": \"out\",\n    \"rootDir\": \"src\",\n    \"skipLibCheck\": true\n  },\n  \"include\": [\"src/**/*.ts\"],\n  \"exclude\": [\"node_modules\", \"src/**/*.spec.ts\"]\n}\n"
  },
  {
    "path": "compiler/companion/tsconfig.bazel.json",
    "content": "{\n  \"extends\": \"./tsconfig.base.json\",\n  \"references\": []\n}\n"
  },
  {
    "path": "compiler/companion/tsconfig.json",
    "content": "{\n  \"extends\": \"./tsconfig.base.json\",\n  \"references\": [{ \"path\": \"remotedebug-ios-webkit-adapter\" }, { \"path\": \"supported-locales\" }]\n}\n"
  },
  {
    "path": "compiler/companion/webpack.config.js",
    "content": "const path = require('path');\nconst webpack = require('webpack');\n\nconst DEFAULT_COMMIT_HASH=\"develop\"\n\nconst pickFirst = (...options) => {\n  for (option of options) {\n    try {\n      return option();\n    } catch (error) {\n      continue;\n    }\n  }\n  console.warn('No git hash provided, falling back to', DEFAULT_COMMIT_HASH);\n  return DEFAULT_COMMIT_HASH;\n}\n\n/**\n * Read in the current git hash. For bazel builds it is expected to read it from\n * the GIT_HASH file since the git state is not aviable to BUILD.bazel\n */\nlet commitHash = pickFirst(\n  // for bzl build expects a COMMIT_HASH file with the commit hash in it\n  () => require('child_process').execSync('git rev-parse HEAD').toString().trim(),\n  () => require('fs').readFileSync('./GIT_HASH').toString().trim(),\n);\n\nmodule.exports = {\n  mode: 'production',\n  target: 'node',\n  entry: './src/index.ts',\n  devtool: 'source-map',\n  plugins: [\n    new webpack.DefinePlugin({\n      __COMMIT_HASH__: JSON.stringify(commitHash),\n    }),\n  ],\n  module: {\n    rules: [\n      {\n        test: /\\.([cm]?ts|tsx)$/,\n        include: [\n          path.resolve(__dirname, './src'),\n          path.resolve(__dirname, './remotedebug-ios-webkit-adapter'),\n          path.resolve(__dirname, './supported-locales')\n        ],\n        exclude: /node_modules/,\n        loader: 'ts-loader',\n      },\n      {\n        test: /\\.node$/,\n        loader: 'node-loader',\n        options: {\n          name: '[name].[ext]',\n        },\n      },\n    ],\n  },\n  resolve: {\n    // Add `.ts` and `.tsx` as a resolvable extension.\n    extensions: ['.ts', '.tsx', '.js'],\n    // Add support for TypeScripts fully qualified ESM imports.\n    extensionAlias: {\n      '.js': ['.js', '.ts'],\n      '.cjs': ['.cjs', '.cts'],\n      '.mjs': ['.mjs', '.mts'],\n    },\n  },\n  output: {\n    filename: 'bundle.js',\n    path: path.resolve(__dirname, 'dist'),\n  },\n};\n"
  },
  {
    "path": "compiler/companion/webpack.dev.config.js",
    "content": "const path = require('path');\n\nmodule.exports = {\n  mode: 'development',\n  target: 'node',\n  entry: './src/index.ts',\n  devtool: 'source-map',\n  plugins: [],\n  module: {\n    rules: [\n      {\n        test: /\\.([cm]?ts|tsx)$/,\n        include: [\n          path.resolve(__dirname, './src'),\n          path.resolve(__dirname, './remotedebug-ios-webkit-adapter'),\n          path.resolve(__dirname, './supported-locales')\n        ],\n        exclude: /node_modules/,\n        loader: 'ts-loader',\n      },\n      {\n        test: /\\.node$/,\n        loader: 'node-loader',\n        options: {\n          name: '[name].[ext]',\n        },\n      },\n    ],\n  },\n  resolve: {\n    // Add `.ts` and `.tsx` as a resolvable extension.\n    extensions: ['.ts', '.tsx', '.js'],\n    // Add support for TypeScripts fully qualified ESM imports.\n    extensionAlias: {\n      '.js': ['.js', '.ts'],\n      '.cjs': ['.cjs', '.cts'],\n      '.mjs': ['.mjs', '.mts'],\n    },\n  },\n  output: {\n    filename: 'bundle.js',\n    path: path.resolve(__dirname, 'dist_dev'),\n  },\n};\n"
  },
  {
    "path": "compiler/compiler/.gitignore",
    "content": "# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## Build generated\nbuild/\nDerivedData/\n\n## Various settings\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\nxcuserdata/\n\nvendor/\n\n## Other\n*.moved-aside\n*.xcuserstate\n**/*.DS_Store\n\n## Obj-C/Swift specific\n*.hmap\n*.ipa\n*.dSYM.zip\n*.dSYM\n\n## Playgrounds\ntimeline.xctimeline\nplayground.xcworkspace\n\n# Swift Package Manager\n#\n# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.\n# Packages/\n.build/\n\n.swiftpm/\n\n# CocoaPods\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n#\n# Pods/\n\n# Carthage\n#\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\n# Carthage/Checkouts\n\nCarthage/Build\n\n# fastlane\n#\n# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the\n# screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md\n\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\n\nnode_modules\n.idea/\n\nwebsite/translated_docs\nwebsite/build/\nwebsite/yarn.lock\nwebsite/node_modules\nwebsite/i18n/*\n\n\n# dependencies\n/node_modules\n\n# production\n/build\n\n# generated files\n.docusaurus\n.cache-loader\n\n# Local Valdi compiler binary (from scripts/update_compiler.sh -o out)\nout/\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*"
  },
  {
    "path": "compiler/compiler/BUILD.bazel",
    "content": "load(\"@bazel_skylib//rules:native_binary.bzl\", \"native_binary\")\n\n# Local Valdi compiler binary for use with --//bzl/valdi:use_local_compiler=true.\n# Build the compiler with: scripts/update_compiler.sh -o out\n# That produces out/macos/valdi_compiler or out/linux/valdi_compiler; this\n# makes that binary usable as the toolchain compiler without the sh_binary\n# runfiles complexity.\nnative_binary(\n    name = \"local_valdi_compiler\",\n    src = select({\n        \"@bazel_tools//src/conditions:darwin\": \"out/macos/valdi_compiler\",\n        \"@bazel_tools//src/conditions:linux_x86_64\": \"out/linux/valdi_compiler\",\n    }),\n    out = \"local_valdi_compiler\",\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "compiler/compiler/Compiler/.gitignore",
    "content": ".DS_Store\n/.build\n/Packages\n/*.xcodeproj\n"
  },
  {
    "path": "compiler/compiler/Compiler/Package.resolved",
    "content": "{\n  \"pins\" : [\n    {\n      \"identity\" : \"chalk\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/mxcl/Chalk.git\",\n      \"state\" : {\n        \"revision\" : \"a7f58e47a08ca5a84f73acc4bcf6c2c19d990609\",\n        \"version\" : \"0.5.0\"\n      }\n    },\n    {\n      \"identity\" : \"legibleerror\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/mxcl/LegibleError.git\",\n      \"state\" : {\n        \"revision\" : \"bc596702d7ff618c3f90ba480eeb48b3e83a2fbe\",\n        \"version\" : \"1.0.6\"\n      }\n    },\n    {\n      \"identity\" : \"sentry-cocoa\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/getsentry/sentry-cocoa\",\n      \"state\" : {\n        \"revision\" : \"bf7bdd75e25556d0f97ad54fb804b4287863e106\",\n        \"version\" : \"8.22.4\"\n      }\n    },\n    {\n      \"identity\" : \"swift-argument-parser\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/apple/swift-argument-parser\",\n      \"state\" : {\n        \"revision\" : \"46989693916f56d1186bd59ac15124caef896560\",\n        \"version\" : \"1.3.1\"\n      }\n    },\n    {\n      \"identity\" : \"swift-backtrace\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/swift-server/swift-backtrace.git\",\n      \"state\" : {\n        \"revision\" : \"f25620d5d05e2f1ba27154b40cafea2b67566956\",\n        \"version\" : \"1.3.3\"\n      }\n    },\n    {\n      \"identity\" : \"swift-collections\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/apple/swift-collections.git\",\n      \"state\" : {\n        \"revision\" : \"94cf62b3ba8d4bed62680a282d4c25f9c63c2efb\",\n        \"version\" : \"1.1.0\"\n      }\n    },\n    {\n      \"identity\" : \"swift-crypto\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/apple/swift-crypto.git\",\n      \"state\" : {\n        \"revision\" : \"cc76b894169a3c86b71bac10c78a4db6beb7a9ad\",\n        \"version\" : \"3.2.0\"\n      }\n    },\n    {\n      \"identity\" : \"swift-protobuf\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/apple/swift-protobuf.git\",\n      \"state\" : {\n        \"revision\" : \"65e8f29b2d63c4e38e736b25c27b83e012159be8\",\n        \"version\" : \"1.25.2\"\n      }\n    },\n    {\n      \"identity\" : \"swiftsoup\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/scinfu/SwiftSoup.git\",\n      \"state\" : {\n        \"revision\" : \"f83c097597094a04124eb6e0d1e894d24129af87\",\n        \"version\" : \"2.7.0\"\n      }\n    },\n    {\n      \"identity\" : \"swxmlhash\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/drmohundro/SWXMLHash.git\",\n      \"state\" : {\n        \"revision\" : \"a853604c9e9a83ad9954c7e3d2a565273982471f\",\n        \"version\" : \"7.0.2\"\n      }\n    },\n    {\n      \"identity\" : \"yams\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/jpsim/Yams.git\",\n      \"state\" : {\n        \"revision\" : \"0d9ee7ea8c4ebd4a489ad7a73d5c6cad55d6fed3\",\n        \"version\" : \"5.0.6\"\n      }\n    },\n    {\n      \"identity\" : \"zip\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/marmelroy/Zip.git\",\n      \"state\" : {\n        \"revision\" : \"67fa55813b9e7b3b9acee9c0ae501def28746d76\",\n        \"version\" : \"2.1.2\"\n      }\n    }\n  ],\n  \"version\" : 2\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Package.swift",
    "content": "// swift-tools-version:5.6\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"Compiler\",\n    platforms: [\n        .macOS(.v11),\n    ],\n    dependencies: [\n        .package(path: \"Vendors/BlueSocket\"),\n        .package(path: \"Vendors/SwiftCSSParser\"),\n        .package(url: \"https://github.com/drmohundro/SWXMLHash.git\", from: \"7.0.0\"),\n        .package(url: \"https://github.com/apple/swift-protobuf.git\", from: \"1.25.2\"),\n        .package(path: \"Vendors/Zstd\"),\n        .package(path: \"Vendors/Clibsass\"),\n        .package(url: \"https://github.com/mxcl/LegibleError.git\", from: \"1.0.6\"),\n        .package(url: \"https://github.com/mxcl/Chalk.git\", from: \"0.5.0\"),\n        .package(url: \"https://github.com/jpsim/Yams.git\", from: \"5.0.6\"),\n        .package(url: \"https://github.com/swift-server/swift-backtrace.git\", from: \"1.3.3\"),\n        .package(url: \"https://github.com/getsentry/sentry-cocoa\", from: \"8.22.4\"),\n        .package(url: \"https://github.com/apple/swift-argument-parser\", from: \"1.3.1\"),\n        .package(url: \"https://github.com/scinfu/SwiftSoup.git\", from: \"2.6.0\"),\n        .package(url: \"https://github.com/apple/swift-crypto.git\", from: \"3.1.0\"),\n        .package(url: \"https://github.com/marmelroy/Zip.git\", .upToNextMinor(from: \"2.1.0\")),\n        .package(\n          url: \"https://github.com/apple/swift-collections.git\", .upToNextMinor(from: \"1.1.0\")  ),\n    ],\n    targets: [\n        // Targets are the basic building blocks of a package. A target can define a module or a test suite.\n        // Targets can depend on other targets in this package, and on products in packages which this package depends on.\n        .executableTarget(\n            name: \"Compiler\",\n            dependencies: [\n                .product(name: \"Backtrace\", package: \"swift-backtrace\"),\n                \"BlueSocket\",\n                \"SwiftCSSParser\",\n                \"SWXMLHash\",\n                .product(name: \"SwiftProtobuf\", package: \"swift-protobuf\"),\n                \"Clibsass\",\n                \"Zstd\",\n                \"LegibleError\",\n                \"Chalk\",\n                \"SwiftSoup\",\n                \"Yams\",\n                \"Zip\",\n                .product(name: \"Crypto\", package: \"swift-crypto\"),\n                .product(name: \"Sentry\", package: \"sentry-cocoa\", condition: .when(platforms: [.macOS])),\n                .product(name: \"ArgumentParser\", package: \"swift-argument-parser\"),\n                .product(name: \"Collections\", package: \"swift-collections\"),\n            ],\n            path: \"Sources\"\n        ),\n        .testTarget(\n            name: \"CompilerTests\",\n            dependencies: [\"Compiler\", \"SwiftSoup\"]\n        ),\n    ]\n)\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ADBClient/ADBClient.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by saniul on 10/10/2019.\n//\n\nimport Foundation\nimport BlueSocket\n\nstruct ADBDeviceId: Hashable, CustomStringConvertible {\n    let serial: String\n\n    var description: String { return serial }\n}\n\nstruct ADBTunnel: Hashable, CustomStringConvertible {\n    let deviceId: ADBDeviceId\n    let localPort: Int\n    let devicePort: Int\n\n    var key: String { return \"adb:\\(deviceId):\\(localPort)\" }\n\n    var description: String { return key }\n}\n\nenum ADBError: Error {\n    case couldNotOpenTunnel\n    case couldNotParseLocalPort\n}\n\nclass ADBClient {\n    private let logger: ILogger\n\n    init(logger: ILogger) {\n        self.logger = logger\n    }\n    \n    func getCurrentlyAttachedDevices() throws -> Set<ADBDeviceId> {\n        let result = try runADBCommand(command: [\"adb\", \"devices\", \"-l\"])\n        let lines = result.components(separatedBy: .newlines).filter { !$0.isEmpty }\n        let deviceLines = (lines.first?.contains(\"List of devices\") == true) ? Array(lines.dropFirst()) : lines\n        let serials = deviceLines\n            .compactMap { $0.components(separatedBy: .whitespaces).first }\n        let deviceIds = serials.map { ADBDeviceId(serial: $0) }\n\n        return Set(deviceIds)\n    }\n\n    func getCurrentlyOpenTunnels(matchingDevicePort: Int) throws -> Set<ADBTunnel> {\n        let result = try runADBCommand(command: [\"adb\", \"forward\", \"--list\"])\n        let lines = result.components(separatedBy: .newlines).filter { !$0.isEmpty }\n        let componentsByLine = lines.map { $0.components(separatedBy: .whitespaces).filter { !$0.isEmpty } }\n        let tunnels = componentsByLine.compactMap { components -> ADBTunnel? in\n            guard let serial = components[safe: 0],\n                let localPortString = components[safe: 1]?.components(separatedBy: \":\")[safe: 1],\n                let localPort = Int(localPortString),\n                let devicePortString = components[safe: 2]?.components(separatedBy: \":\")[safe: 1],\n                let devicePort = Int(devicePortString),\n                devicePort == matchingDevicePort\n                else { return nil }\n\n            let tunnel = ADBTunnel(deviceId: ADBDeviceId(serial: serial), localPort: localPort, devicePort: devicePort)\n            return tunnel\n        }\n\n        return Set(tunnels)\n    }\n\n    func openTunnelForDevice(_ deviceId: ADBDeviceId, devicePort: Int) throws -> ADBTunnel {\n        return try openTunnelForDevice(deviceId, devicePort: devicePort, localPort: 0)\n    }\n\n    func openTunnelForDevice(_ deviceId: ADBDeviceId, devicePort: Int, localPort: Int) throws -> ADBTunnel {\n        let result = try runADBCommand(command: [\"adb\", \"-s\", deviceId.serial, \"forward\", \"tcp:\\(localPort)\", \"tcp:\\(devicePort)\"])\n        let lines = result.components(separatedBy: .newlines).filter { !$0.isEmpty }\n        guard let localPortLine = lines.first else {\n            throw ADBError.couldNotOpenTunnel\n        }\n        guard let boundLocalPort = Int(localPortLine) else {\n            throw ADBError.couldNotParseLocalPort\n        }\n        let tunnel = ADBTunnel(deviceId: deviceId, localPort: boundLocalPort, devicePort: devicePort)\n        return tunnel\n    }\n\n    func closeTunnelForDevice(_ tunnel: ADBTunnel) throws {\n        _ = try runADBCommand(command: [\"adb\", \"forward\", \"--remove\", \"tcp:\\(tunnel.localPort)\"])\n    }\n\n    func runADBCommand(command: [String]) throws -> String {\n        let process = SyncProcessHandle.usingEnv(logger: logger, command: command)\n        try process.run()\n\n        if !process.stderr.content.isEmpty {\n            throw CompilerError(\"adb error: \\(process.stderr.contentAsString)\")\n        }\n\n        let outputData = process.stdout.content\n        guard let outputString = String(data: outputData, encoding: .utf8) else {\n            throw CompilerError(\"could not decode adb output: \\(outputData)\")\n        }\n        return outputString\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ADBClient/ADBDeviceConnection.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by saniul on 11/10/2019.\n//\n\nimport Foundation\nimport BlueSocket\n\nprotocol ADBDeviceDaemonConnectionDelegate: AnyObject {\n    func connection(_ adbConnection: ADBDeviceDaemonConnection, established connection: DaemonTCPConnection)\n    func connection(_ adbConnection: ADBDeviceDaemonConnection, stopped result: Result<Void, Error>)\n}\n\nclass ADBDeviceDaemonConnection {\n    weak var delegate: ADBDeviceDaemonConnectionDelegate?\n\n    private let logger: ILogger\n    let tunnel: ADBTunnel\n    let queue: DispatchQueue\n    private var connection: DaemonTCPConnection?\n\n    init(logger: ILogger, tunnel: ADBTunnel) {\n        self.logger = logger\n        self.tunnel = tunnel\n        queue = DispatchQueue(label: \"ADBDeviceDaemonConnection(\\(tunnel.key))\")\n    }\n\n    func start() {\n        queue.async { [weak self] in\n            self?.attemptConnecting()\n        }\n    }\n\n    func stop() {\n        queue.async { [weak self] in\n            self?.connection?.close()\n        }\n    }\n\n    private func attemptConnecting() {\n        assert(connection == nil)\n\n        do {\n            let socket = try Socket.create()\n            try socket.connect(to: \"localhost\", port: Int32(tunnel.localPort))\n\n            let channel = DispatchIO(type: .stream, fileDescriptor: socket.socketfd, queue: queue, cleanupHandler: { [socket] (_: Int32) in\n                // Intentional retain, need to clean up the channel before we clean up the socket\n                _ = socket\n            })\n\n            let connection = DaemonTCPConnection(logger: logger, key: tunnel.key, channel: channel)\n            self.connection = connection\n        } catch {\n            cleanUpAndScheduleNextAttempt()\n            return\n        }\n\n        guard let connection = self.connection else {\n            return\n        }\n\n        connection.addDisconnectHandler({ [weak self, weak connection] error in\n            guard let this = self, let connection = connection else { return }\n            let result: Result = error.map { .failure($0) } ?? .success(())\n            this.handleConnectionEnded(connection, result: result)\n        })\n        // TODO: change to logInfo when updated to not fail in a loop while app is not running on connected device\n        logger.verbose(\"Localhost reloader connection with ADB device \\(tunnel.deviceId) established\")\n        // TODO: only call established once we've confirmed that the connection can be read from\n\n        // Can do something like, manage the connection here first, keep attempting to read the initial bytes\n        // (without failing the connection if we read zero bytes) and once we do - buffer that data, and only _then_\n        // hand over the DaemonTCPConnection.\n        delegate?.connection(self, established: connection)\n    }\n\n    private func cleanUpAndScheduleNextAttempt() {\n        self.connection = nil\n        queue.asyncAfter(deadline: .now() + 1) { [weak self] in\n            self?.attemptConnecting()\n        }\n    }\n\n    private func handleConnectionEnded(_ connection: DaemonTCPConnection, result: Result<Void, Error>) {\n        guard self.connection === connection else {\n            // Irrelevant connection\n            return\n        }\n        // TODO: change to logInfo when updated to not fail in a loop while app is not running on connected device\n        logger.verbose(\"Localhost reloader connection with ADB device \\(tunnel.deviceId) ended\")\n        delegate?.connection(self, stopped: result)\n        cleanUpAndScheduleNextAttempt()\n    }\n}\n\nextension ADBDeviceDaemonConnection: CustomStringConvertible {\n    var description: String { return \"ADBDeviceDaemonConnection(\\(tunnel)) \"}\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ADBClient/DaemonServiceADBAutoConnector.swift",
    "content": "//\n//  File.swift\n//\n//\n//  Created by saniul on 11/10/2019.\n//\n\nimport Foundation\n\nclass DaemonServiceADBAutoConnector: ADBDeviceDaemonConnectionDelegate, DaemonServiceAutoConnector {\n    weak var delegate: DaemonServiceAutoConnectorDelegate?\n\n    private let logger: ILogger\n    private let companion: CompanionExecutable\n    private let client: ADBClient\n    private let queue = DispatchQueue(label: \"ADBClient\")\n\n    private var attachedDevices: Set<ADBDeviceId> = []\n    private var connections: [ADBTunnel: ADBDeviceDaemonConnection] = [:]\n    private var openTunnels: Set<ADBTunnel> = []\n    private var requestedTunnels: Set<ADBTunnel> = []\n\n    init(logger: ILogger, companion: CompanionExecutable) {\n        self.logger = logger\n        self.companion = companion\n        self.client = ADBClient(logger: logger)\n    }\n\n    func start() {\n        queue.async { [weak self] in\n            self?.doStart()\n        }\n    }\n\n    func createTunnel(logger: ILogger, fromLocalPort localPort: Int, toDeviceId: String, devicePort: Int) throws -> TCPTunnel? {\n        try? self.client.closeTunnelForDevice(ADBTunnel(deviceId: ADBDeviceId(serial: toDeviceId), localPort: localPort, devicePort: devicePort))\n\n        logger.info(\"Opening ADB Tunnel from localhost:\\(localPort) -> \\(toDeviceId):\\(devicePort)\")\n        let newTunnel = try client.openTunnelForDevice(ADBDeviceId(serial: toDeviceId), devicePort: devicePort, localPort: localPort)\n\n        queue.async { [weak self] in\n            self?.requestedTunnels.insert(newTunnel)\n        }\n        return nil\n    }\n\n    private func doStart() {\n        logger.info(\"Started listening for ADB devices\")\n\n        let openReloaderTunnels = (try? client.getCurrentlyOpenTunnels(matchingDevicePort: Ports.reloaderOverUSB)) ?? []\n        let openDebuggerTunnels = (try? client.getCurrentlyOpenTunnels(matchingDevicePort: Ports.valdiDebugger)) ?? []\n        let tunnels = Array(openReloaderTunnels) + Array(openDebuggerTunnels)\n        for tunnel in tunnels {\n            try? client.closeTunnelForDevice(tunnel)\n        }\n        update()\n    }\n\n    private func update() {\n        logAttachedDetachedDevices()\n\n        var openReloaderTunnels = (try? client.getCurrentlyOpenTunnels(matchingDevicePort: Ports.reloaderOverUSB)) ?? []\n        var openDebuggerTunnels = (try? client.getCurrentlyOpenTunnels(matchingDevicePort: Ports.valdiDebugger)) ?? []\n        let openTunnels = openReloaderTunnels.union(openDebuggerTunnels)\n        let tunnelsByDeviceId = openReloaderTunnels.groupBy { $0.deviceId }\n\n        let devicesWithoutTunnels = attachedDevices.filter { !tunnelsByDeviceId.keys.contains($0) }\n        for deviceId in devicesWithoutTunnels {\n            do {\n                let openedReloaderTunnel = try client.openTunnelForDevice(deviceId, devicePort: Ports.reloaderOverUSB)\n                openReloaderTunnels.insert(openedReloaderTunnel)\n                let openedDebuggerTunnel = try client.openTunnelForDevice(deviceId, devicePort: Ports.valdiDebugger)\n                openDebuggerTunnels.insert(openedDebuggerTunnel)\n            } catch {\n                logger.error(\"Could not open tunnel for ADB device \\(deviceId): \\(error.legibleLocalizedDescription)\")\n            }\n        }\n\n        let freshlyClosedTunnels = self.openTunnels.subtracting(openTunnels)\n        let newlyOpenTunnels = openTunnels.subtracting(self.openTunnels)\n        self.openTunnels = openTunnels\n\n        for closedTunnel in freshlyClosedTunnels {\n            let connection = connections.removeValue(forKey: closedTunnel)\n            connection?.stop()\n        }\n\n        for newTunnel in newlyOpenTunnels where newTunnel.devicePort == Ports.reloaderOverUSB {\n            let connection = ADBDeviceDaemonConnection(logger: logger, tunnel: newTunnel)\n            connections[newTunnel] = connection\n            connection.delegate = self\n            connection.start()\n        }\n\n        let debuggingTargets = openDebuggerTunnels.map { tunnel in\n            return AndroidDebuggingTarget(deviceId: tunnel.deviceId.serial,\n                                          target: \"localhost:\\(tunnel.localPort)\")\n        }\n\n        _ = companion.updatedAndroidTargets(targets: debuggingTargets)\n\n        queue.asyncAfter(deadline: .now() + 1) { [weak self] in\n            self?.update()\n        }\n    }\n\n    private func logAttachedDetachedDevices() {\n        let attachedDevices = (try? client.getCurrentlyAttachedDevices()) ?? []\n        let freshlyDetachedDevices = self.attachedDevices.subtracting(attachedDevices)\n        let newlyAttachedDevices = attachedDevices.subtracting(self.attachedDevices)\n        self.attachedDevices = attachedDevices\n\n        for detachedDevice in freshlyDetachedDevices {\n            logger.info(\"ADB device detached: \\(detachedDevice)\")\n        }\n\n        for attachedDevice in newlyAttachedDevices {\n            logger.info(\"ADB device attached: \\(attachedDevice)\")\n        }\n    }\n\n    // MARK: DaemonServiceAutoConnectorDelegate\n\n    func connection(_ adbConnection: ADBDeviceDaemonConnection, established connection: DaemonTCPConnection) {\n        logger.debug(\"ADBDeviceDaemonConnection connection \\(adbConnection) established\")\n        queue.async { [weak self] in\n            guard let this = self else { return }\n            this.delegate?.autoConnector(this, newConnectionEstablished: connection, deviceId: adbConnection.tunnel.deviceId.serial)\n        }\n    }\n\n    func connection(_ adbConnection: ADBDeviceDaemonConnection, stopped result: Result<Void, Error>) {\n        logger.debug(\"ADBDeviceDaemonConnection connection \\(adbConnection) stopped with result: \\(result)\")\n\n        queue.async { [weak self] in\n            guard let this = self else { return }\n\n            guard this.connections[adbConnection.tunnel] === adbConnection else {\n                return\n            }\n\n            for tunnel in this.openTunnels where tunnel.deviceId == adbConnection.tunnel.deviceId {\n                try? this.client.closeTunnelForDevice(tunnel)\n            }\n            for tunnel in this.requestedTunnels where tunnel.deviceId == adbConnection.tunnel.deviceId {\n                try? this.client.closeTunnelForDevice(tunnel)\n                this.requestedTunnels.remove(tunnel)\n            }\n            this.connections[adbConnection.tunnel] = nil\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Bazel/BazelPersistentWorker.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nfileprivate extension Data {\n    mutating func appendNewline() {\n        var newline: UInt8 = 10\n        Swift.withUnsafePointer(to: &newline) {\n            append($0, count: 1)\n        }\n    }\n}\n\nclass BazelPersistentWorker {\n\n    struct Request {\n        let arguments: [String]\n        let logger: ILogger\n        let cancelableToken: StateCancelable\n        let workingDirectory: String\n    }\n\n    struct Response {\n        let result: Promise<Void>\n    }\n\n    typealias StartHandler = (Request) -> Response\n\n    private struct CurrentRequest {\n        let cancelableToken: StateCancelable\n    }\n\n    private let stdin: FileHandleReader\n    private let stdout: FileHandle\n    private let workQueue = DispatchQueue(label: \"com.snap.valdi.compiler.BazelWorkQueue\", qos: .userInitiated)\n    private let logger: ILogger\n    private var requestById = [Int: CurrentRequest]()\n\n    init(stdin: FileHandle, stdout: FileHandle, logger: ILogger) {\n        self.stdin = FileHandleReader(fileHandle: stdin, dispatchQueue: DispatchQueue.main)\n        self.stdout = stdout\n        self.logger = logger\n    }\n\n    func run(startHandler: @escaping StartHandler) {\n        self.stdin.onDidReceiveData = { [weak self] reader in\n            guard let self else { return }\n            while self.consumeNextRequest(startHandler: startHandler) {}\n        }\n        RunLoop.main.run()\n    }\n\n    private func submitResponse(exitCode: Int, output: String, requestId: Int, wasCancelled: Bool) {\n        let workResponse = BazelWorkerProtocol.WorkResponse(exitCode: exitCode, output: output, requestId: requestId, wasCancelled: wasCancelled)\n\n        do {\n            var json = try workResponse.toJSON(keyEncodingStrategy: .useDefaultKeys)\n            json.appendNewline()\n\n            try self.stdout.write(contentsOf: json)\n        } catch let error {\n            logger.error(\"Failed to write Bazel response: \\(error.legibleLocalizedDescription)\")\n            logger.flush()\n            _exit(1)\n        }\n    }\n\n    private func onRequestCompleted(result: Result<Void, Error>, logOutput: BufferLoggerOutput, requestId: Int) {\n        guard requestById.removeValue(forKey: requestId) != nil else {\n            return\n        }\n\n        var logData = logOutput.data\n        var exitCode: Int32\n\n        switch result {\n        case .success:\n            exitCode = EXIT_SUCCESS\n        case .failure(let error):\n            exitCode = EXIT_FAILURE\n            if let errorData = try? error.legibleLocalizedDescription.utf8Data() {\n                logData.appendNewline()\n                logData.append(errorData)\n            }\n        }\n        submitResponse(exitCode: Int(exitCode), output: String(data: logData, encoding: .utf8) ?? \"\", requestId: requestId, wasCancelled: false)\n    }\n\n    private func process(data: Data, startHandler: @escaping StartHandler) {\n        do {\n            let workRequest = try BazelWorkerProtocol.WorkRequest.fromJSON(data, keyDecodingStrategy: .useDefaultKeys)\n            let requestId = workRequest.requestId ?? 0\n\n            if let cancel = workRequest.cancel, cancel {\n                if let cancelToken = self.requestById.removeValue(forKey: requestId) {\n                    cancelToken.cancelableToken.cancel()\n                    self.submitResponse(exitCode: 0, output: \"\", requestId: requestId, wasCancelled: true)\n                }\n\n                return\n            }\n\n            let cancelableToken = StateCancelable()\n\n            self.requestById[requestId] = CurrentRequest(cancelableToken: cancelableToken)\n\n            workQueue.async {\n                let logOutput = BufferLoggerOutput()\n                let logger = Logger(output: logOutput)\n                let response = startHandler(Request(\n                    arguments: workRequest.arguments,\n                    logger: logger,\n                    cancelableToken: cancelableToken,\n                    workingDirectory: workRequest.sandboxDir ?? FileManager.default.currentDirectoryPath))\n                response.result.onComplete { result in\n                    logger.flush()\n                    DispatchQueue.main.async {\n                        self.onRequestCompleted(result: result, logOutput: logOutput, requestId: requestId)\n                    }\n                }\n            }\n        } catch let error {\n            let inputData = String(data: data, encoding: .utf8) ?? \"\"\n            logger.error(\"Failed to process Bazel request: \\(error.legibleLocalizedDescription) (request content: \\(inputData)\")\n            logger.flush()\n            _exit(1)\n        }\n    }\n\n    private func consumeNextRequest(startHandler: @escaping StartHandler) -> Bool {\n        guard let newLineIndex = stdin.content.fastFirstIndex(of: /* newline separator */ 10) else {\n            return false\n        }\n\n        process(data: stdin.content[..<newLineIndex], startHandler: startHandler)\n        stdin.trimContent(by: newLineIndex + 1)\n\n        return true\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Bazel/BazelWorkerProtocol.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nstruct BazelWorkerProtocol {\n    // From https://github.com/bazelbuild/bazel/blob/54a547f30fd582933889b961df1d6e37a3e33d85/src/main/protobuf/worker_protocol.proto\n\n    // An input file.\n    struct Input: Codable {\n        // The path in the file system where to read this input artifact from. This is\n        // either a path relative to the execution root (the worker process is\n        // launched with the working directory set to the execution root), or an\n        // absolute path.\n        let path: String\n\n        // A hash-value of the contents. The format of the contents is unspecified and\n        // the digest should be treated as an opaque token. This can be empty in some\n        // cases.\n        let digest: String\n    }\n\n    struct WorkRequest: Codable {\n\n        let arguments: [String]\n\n        // The inputs that the worker is allowed to read during execution of this\n        // request.\n        let inputs: [Input]?\n\n        // Each WorkRequest must have either a unique\n        // request_id or request_id = 0. If request_id is 0, this WorkRequest must be\n        // processed alone (singleplex), otherwise the worker may process multiple\n        // WorkRequests in parallel (multiplexing). As an exception to the above, if\n        // the cancel field is true, the request_id must be the same as a previously\n        // sent WorkRequest. The request_id must be attached unchanged to the\n        // corresponding WorkResponse. Only one singleplex request may be sent to a\n        // worker at a time.\n        let requestId: Int?\n\n\n        // EXPERIMENTAL: When true, this is a cancel request, indicating that a\n        // previously sent WorkRequest with the same request_id should be cancelled.\n        // The arguments and inputs fields must be empty and should be ignored.\n        let cancel: Bool?\n\n        // Values greater than 0 indicate that the worker may output extra debug\n        // information to stderr (which will go into the worker log). Setting the\n        // --worker_verbose flag for Bazel makes this flag default to 10.\n        let verbosity: Int?\n\n        // The relative directory inside the workers working directory where the\n        // inputs and outputs are placed, for sandboxing purposes. For singleplex\n        // workers, this is unset, as they can use their working directory as sandbox.\n        // For multiplex workers, this will be set when the\n        // --experimental_worker_multiplex_sandbox flag is set _and_ the execution\n        // requirements for the worker includes 'supports-multiplex-sandbox'.\n        // The paths in `inputs` will not contain this prefix, but the actual files\n        // will be placed/must be written relative to this directory. The worker\n        // implementation is responsible for resolving the file paths.\n        let sandboxDir: String?\n    }\n\n    // The worker sends this message to Blaze when it finished its work on the\n    // WorkRequest message.\n    struct WorkResponse: Codable {\n        let exitCode: Int\n\n        // This is printed to the user after the WorkResponse has been received and is\n        // supposed to contain compiler warnings / errors etc. - thus we'll use a\n        // string type here, which gives us UTF-8 encoding.\n        let output: String\n\n        // This field must be set to the same request_id as the WorkRequest it is a\n        // response to. Since worker processes which support multiplex worker will\n        // handle multiple WorkRequests in parallel, this ID will be used to\n        // determined which WorkerProxy does this WorkResponse belong to.\n        let requestId: Int\n\n        // EXPERIMENTAL When true, indicates that this response was sent due to\n        // receiving a cancel request. The exit_code and output fields should be empty\n        // and will be ignored. Exactly one WorkResponse must be sent for each\n        // non-cancelling WorkRequest received by the worker, but if the worker\n        // received a cancel request, it doesn't matter if it replies with a regular\n        // WorkResponse or with one where was_cancelled = true.\n        let wasCancelled: Bool\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Bazel/BundleInfo+Bazel.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nextension CompilationItem.BundleInfo {\n\n    private static func makeBazelTarget(currentWorkspace: String?, workspace: String, target: String) -> String {\n        if currentWorkspace == workspace {\n            return \"\\(target)\"\n        } else {\n            return \"@\\(workspace)\\(target)\"\n        }\n    }\n\n    func toBazelTarget(projectConfig: ValdiProjectConfig, currentWorkspace: String?) throws -> String {\n        let bundleName = self.resolvedBundleName()\n        \n        let workspace: String\n        let target: String\n        \n        if let openSourceDir = projectConfig.openSourceDir, !openSourceDir.relativePath(to: self.baseDir).hasPrefix(\"../\") {\n            workspace = \"valdi\"\n            target = \"//src/valdi_modules/src/valdi/\\(bundleName)\"\n        } else if self.baseDir.path.contains(\"/node_modules/\"),\n                  let configWorkspace = projectConfig.nodeModulesWorkspace,\n                  let configTarget = projectConfig.nodeModulesTarget {\n            workspace = configWorkspace\n            target = \"\\(configTarget)/\\(bundleName)\"\n        } else if let configWorkspace = projectConfig.externalModulesWorkspace,\n                  let configTarget = projectConfig.externalModulesTarget {\n            workspace = configWorkspace\n            target = \"\\(configTarget)/\\(bundleName)\"\n        } else {\n            throw CompilerError(\"No bazel target configuration found for bundle '\\(bundleName)' at path: \\(self.baseDir.path)\")\n        }\n        \n        return CompilationItem.BundleInfo.makeBazelTarget(currentWorkspace: currentWorkspace, workspace: workspace, target: target)\n    }\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/BundleManager.swift",
    "content": "//\n//  BundleManager.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 3/1/19.\n//\n\nimport Foundation\nimport Yams\n\nprivate struct CircularDependencyError: LocalizedError {\n    let moduleChain: [String]\n\n    init(moduleChain: [String]) {\n        self.moduleChain = moduleChain\n    }\n\n    public var errorDescription: String? {\n        let dependencyChain = moduleChain.joined(separator: \" -> \")\n        return \"\"\"\n        Circular dependency detected while loading module '\\(moduleChain.first!)'\n        Dependency chain: \\(dependencyChain)\\n\n        \"\"\"\n    }\n}\n\nclass BundleManager {\n    struct RegisteredBundle {\n        let url: URL\n        let file: File\n    }\n\n    private var bundleURLByName = [String: RegisteredBundle]()\n    private var bundleByName = [String: CompilationItem.BundleInfo]()\n    private var bundleNameByDirURL = [URL: String]()\n    private let lock = DispatchSemaphore.newLock()\n\n    private let projectConfig: ValdiProjectConfig\n    private let compilerConfig: CompilerConfig\n    private var loadingBundleURLs = Set<URL>()\n    private let baseDirURLs: [URL]\n    // Used during module info resolving so that we can tell whether we\n    // are still within the allowed base dirs while going through ancestor\n    // directories.\n    private var baseDirsTrie = Trie<Bool>()\n    let rootBundle: CompilationItem.BundleInfo\n\n    init(projectConfig: ValdiProjectConfig,\n         compilerConfig: CompilerConfig,\n         baseDirURLs: [URL]) throws {\n        self.projectConfig = projectConfig\n        self.compilerConfig = compilerConfig\n        self.baseDirURLs = baseDirURLs.sorted(by: { left, right in\n            return left.pathComponents.count > right.pathComponents.count\n        })\n\n        for baseDirURL in baseDirURLs {\n            self.baseDirsTrie.insert(name: baseDirURL.pathComponents, value: true)\n        }\n\n        // Every module will have a dependency on the root\n        rootBundle = try CompilationItem.BundleInfo(name: CompilationItem.BundleInfo.rootModuleName,\n                                                    baseDir: projectConfig.baseDir,\n                                                    relativeProjectPathPrefix: \"\",\n                                                    disableHotReload: false,\n                                                    disableAnnotationProcessing: false,\n                                                    disableDependencyVerification: true,\n                                                    disableBazelBuildFileGeneration: true,\n                                                    asyncStrictMode: false,\n                                                    webNpmScope: \"\",\n                                                    webVersion: \"\",\n                                                    webPublishConfig: \"\",\n                                                    webMain: \"\",\n                                                    iosModuleName: \"\",\n                                                    iosLanguage: IOSLanguage.objc,\n                                                    iosClassPrefix: nil,\n                                                    androidClassPath: nil,\n                                                    cppClassPrefix: nil,\n                                                    iosCodegenEnabled: false,\n                                                    androidCodegenEnabled: false,\n                                                    cppCodegenEnabled: false,\n                                                    disableCodeCoverage: false,\n                                                    singleFileCodegen: false,\n                                                    compilationModeConfig: CompilationModeConfig(js: nil, jsBytecode: nil, native: nil),\n                                                    iosOutputTarget: .releaseReady,\n                                                    iosGeneratedContextFactories: [],\n                                                    androidOutputTarget: .releaseReady,\n                                                    webOutputTarget: .releaseReady,\n                                                    cppOutputTarget: .releaseReady,\n                                                    downloadableAssets: false,\n                                                    downloadableSources: false,\n                                                    inclusionConfig: InclusionConfig.alwaysIncluded,\n                                                    excludeGlobs: [],\n                                                    dependencies: [],\n                                                    stringsConfig: nil,\n                                                    projectConfig: projectConfig,\n                                                    outputTarget: compilerConfig.outputTarget\n        )\n        self.bundleByName[rootBundle.name] = rootBundle\n        self.bundleNameByDirURL[projectConfig.baseDir] = rootBundle.name\n        assert(rootBundle.isRoot)\n    }\n\n    func registerBundle(forName bundleName: String, bundleURL: URL, file: File) {\n        lock.lock {\n            self.bundleURLByName[bundleName] = RegisteredBundle(url: bundleURL, file: file)\n            self.bundleNameByDirURL[bundleURL.deletingLastPathComponent()] = bundleName\n        }\n    }\n\n    func getBundleInfo(forName name: String) throws -> CompilationItem.BundleInfo {\n        return try lock.lock {\n            try getBundleInfo(bundleName: name)\n        }\n    }\n\n    func getBundleInfo(fileURL: URL) throws -> CompilationItem.BundleInfo {\n        let directoryURL = fileURL.deletingLastPathComponent()\n\n        return try lock.lock {\n            return try resolveBundleInfo(itemURL: fileURL, dirURL: directoryURL)\n        }\n    }\n\n    static func parseOutputTarget(node: Yams.Node?) throws -> ModuleOutputTarget? {\n        return try parseOutputTarget(string: node?[\"output_target\"]?.string)\n    }\n\n    static func parseOutputTarget(mapping: Yams.Node.Mapping?) throws -> ModuleOutputTarget? {\n        return try parseOutputTarget(string: mapping?[\"output_target\"]?.string)\n    }\n\n    static func parseOutputTarget(string: String?) throws -> ModuleOutputTarget? {\n        guard let outputTargetString = string?.lowercased() else {\n            return nil\n        }\n\n        let outputTarget: ModuleOutputTarget\n        switch outputTargetString {\n        case \"debug\":\n            outputTarget = .debugOnly\n        case \"release\":\n            outputTarget = .releaseReady\n        default:\n            throw CompilerError(\"Unrecognized output target '\\(outputTargetString)', supported values are 'debug' and 'release'\")\n        }\n        return outputTarget\n    }\n\n    static func getBundleNameComponents(bundleName: String) -> (moduleName: String, scope: String) {\n        // Resolves scoped bundleName to its moduleName and scope components\n        // Assume scoped bundleName uses '@'\n        return bundleName.split(at: \"@\")\n    }\n\n    static func resolveBundleName(bundleName: String) -> String {\n        // Resolves concatenated intermediate module names in the form of <name><scope> to <scope>/<name> for path resolution purposes\n        // Ex: \"module@scope\" -> \"@scope/module\"\n        let (moduleName, scope) = getBundleNameComponents(bundleName: bundleName)\n        return scope.isEmpty ? moduleName : \"@\\(scope)/\\(moduleName)\"\n    }\n\n    private static func resolveCodegenEnabled(config: Yams.Node.Mapping?, outputConfig: ValdiOutputConfig?) -> Bool {\n        guard let outputConfig else { return false }\n\n        return config?[\"codegen_enabled\"]?.bool ?? outputConfig.codegenEnabled\n    }\n    \n    private static func resolveGeneratedContextFactories(config: Yams.Node.Mapping?) -> [String] {\n        guard let config = config else { return [] }\n        \n        return config[\"generated_context_factories\"]?.array().compactMap({ $0.string }) ?? []\n    }\n\n    private func loadBundle(bundleName: String, bundleURL: URL, bundleFile: File) throws -> CompilationItem.BundleInfo {\n        if loadingBundleURLs.contains(bundleURL) {\n            throw CircularDependencyError(moduleChain: [bundleName])\n        }\n\n        loadingBundleURLs.insert(bundleURL)\n        defer {\n            loadingBundleURLs.remove(bundleURL)\n        }\n\n        let resolvedBundleDir = try bundleURL.deletingLastPathComponent().resolvingSymlink()\n\n        let configData: String\n        do {\n            configData = try bundleFile.readString()\n        } catch let error {\n            throw CompilerError(\"Failed to read module file at \\(bundleURL.path): \\(error.legibleLocalizedDescription)\")\n        }\n\n        let config: Yams.Node\n        do {\n            guard let configMaybe = try Yams.compose(yaml: configData) else {\n                throw CompilerError(\"YAML parsing returned nil\")\n            }\n            config = configMaybe\n        } catch let error {\n            throw CompilerError(\"Failed to parse module file at \\(bundleURL.path): \\(error.legibleLocalizedDescription)\")\n        }\n\n        let iosConfig = config[\"ios\"]?.mapping\n        let androidConfig = config[\"android\"]?.mapping\n        let webConfig = config[\"web\"]?.mapping\n        let cppConfig = config[\"cpp\"]?.mapping\n\n        let webNpmScope = webConfig?[\"scope\"]?.string ?? \"\"\n        let webVersion = webConfig?[\"version\"]?.string ?? \"1.0.0\"\n        let webPublishConfig = webConfig?[\"publish_config\"]?.string ?? \"\"\n        let webMain = webConfig?[\"main\"]?.string ?? \"\"\n\n        let iosClassPrefix = iosConfig?[\"class_prefix\"]?.string\n        let cppClassPrefix = cppConfig?[\"class_prefix\"]?.string\n\n        let disableHotReload = config[\"disable_hotreload\"]?.bool ?? false\n        let disableAnnotationProcessing = config[\"disable_annotation_processing\"]?.bool ?? false\n        let disableDependencyVerification = config[\"disable_dependency_verification\"]?.bool ?? false\n        let disableCodeCoverage = config[\"disable_code_coverage\"]?.bool ?? false\n        let disableBazelBuildFileGeneration = config[\"bazel_build_file_generation_disabled\"]?.bool ?? false\n        let asyncStrictMode = config[\"async_strict_mode\"]?.bool ?? false\n\n        let compilationModeConfig = try config[\"compilation_mode\"].map { try CompilationModeConfig.parse(from: $0) } ?? CompilationModeConfig.forJsBytecode()\n\n        let iosModuleName: String\n        if let iosConfigName = iosConfig?[\"module_name\"]?.string?.trimmed {\n            iosModuleName = iosConfigName\n        } else {\n            let (moduleName, _) = BundleManager.getBundleNameComponents(bundleName: bundleName)\n            iosModuleName = String.concatenate(projectConfig.iosDefaultModuleNamePrefix, moduleName.pascalCased) ?? moduleName.pascalCased\n        }\n        \n        let iosLanguage: IOSLanguage\n        if let language = iosConfig?[\"language\"]?.string {\n            iosLanguage = try IOSLanguage.parse(input: language)\n        } else {\n            iosLanguage = projectConfig.iosDefaultLanguage\n        }\n\n        let parsedCommonOutputTarget = try Self.parseOutputTarget(node: config)\n        let parsedIosOutputTarget = try Self.parseOutputTarget(mapping: iosConfig)\n        let parsedAndroidOutputTarget = try Self.parseOutputTarget(mapping: androidConfig)\n        let parsedWebOutputTarget = try Self.parseOutputTarget(mapping: webConfig)\n\n        let iosOutputTarget: ModuleOutputTarget?\n        let androidOutputTarget: ModuleOutputTarget?\n        let webOutputTarget: ModuleOutputTarget?\n        switch (parsedCommonOutputTarget, parsedIosOutputTarget, parsedAndroidOutputTarget) {\n        case (.none, .none, .none):\n            throw CompilerError(\"No output_target in the \\(bundleName) module.yaml. Supported values are 'debug' and 'release'\")\n        case (.some, .some, _), (.some, _, .some):\n            throw CompilerError(\"If you specify a platform-specific output target, you need to specify it for both platforms.\")\n        case let (.some(commonOutputTarget), .none, .none):\n            iosOutputTarget = commonOutputTarget\n            androidOutputTarget = commonOutputTarget\n            webOutputTarget = commonOutputTarget\n        case (.none, .some, _), (.none, _, .some):\n            iosOutputTarget = parsedIosOutputTarget\n            androidOutputTarget = parsedAndroidOutputTarget\n            webOutputTarget = parsedWebOutputTarget\n        }\n\n        let inclusionConfig = try InclusionConfig.parse(from: config)\n\n        var excludeGlobs = [String]()\n\n        if let excludeGlobsArray = config[\"exclude_globs\"]?.array().compactMap({ $0.string }) {\n            for glob in excludeGlobsArray {\n                excludeGlobs.append(glob)\n            }\n        }\n\n        // Enable downloadable assets by default\n        var downloadableAssets = true\n        var downloadableSources = false\n\n        if let downloadable = config[\"downloadable\"] {\n            if let allDownloadable = downloadable.bool, allDownloadable {\n                downloadableAssets = true\n                downloadableSources = true\n            } else {\n                if let downloadableAssetsCfg = downloadable[\"assets\"]?.bool {\n                    downloadableAssets = downloadableAssetsCfg\n                }\n                downloadableSources = downloadable[\"sources\"]?.bool ?? false\n            }\n        }\n\n        if compilerConfig.disableDownloadableModules {\n            downloadableAssets = false\n            downloadableSources = false\n        }\n\n        if [iosOutputTarget, androidOutputTarget, webOutputTarget].contains(.debugOnly), downloadableSources {\n            throw CompilerError(\"Module '\\(bundleName)' is marked as downloadable, but the module's output target is set to 'debug'. A debug-only module cannot be downloadable to avoid easily leaking unreleased features.\")\n        }\n\n        let androidClassPath = androidConfig?[\"class_path\"]?.string\n\n        let dependencyStrings = config[\"dependencies\"]?.array().compactMap({ $0.string }) ?? [String]()\n        var dependencies = try resolveDependencies(ofModule: bundleName,\n                                                   moduleURL: bundleURL,\n                                                   dependencyStrings: dependencyStrings)\n        let debugOnlyDependencyStrings = config[\"allowed_debug_dependencies\"]?.array().compactMap({ $0.string }) ?? [String]()\n        let allowedDebugDependencies = try resolveDependencies(ofModule: bundleName,\n                                                               moduleURL: bundleURL,\n                                                               dependencyStrings: debugOnlyDependencyStrings)\n        dependencies.append(contentsOf: Set(allowedDebugDependencies).subtracting(Set(dependencies)))\n\n        dependencies.append(rootBundle)\n        dependencies.sort {\n            $0.name < $1.name\n        }\n\n        let stringsConfig: CompilationItem.BundleInfo.ModuleStringsConfig?\n        if let stringsDir = config[\"strings_dir\"]?.string {\n            stringsConfig = .jsonDir(bundleRelativePath: stringsDir)\n        } else {\n            stringsConfig = nil\n        }\n\n        let iosCodegenEnabled = Self.resolveCodegenEnabled(config: iosConfig, outputConfig: projectConfig.iosOutput)\n        let androidCodegenEnabled = Self.resolveCodegenEnabled(config: androidConfig, outputConfig: projectConfig.androidOutput)\n        let cppCodegenEnabled = Self.resolveCodegenEnabled(config: cppConfig, outputConfig: projectConfig.cppOutput)\n\n\n        let iosGeneratedContextFactories = Self.resolveGeneratedContextFactories(config: iosConfig)\n\n        let relativeProjectPathPrefix = config[\"path_prefix\"]?.string ?? \"\\(bundleName)/\"\n\n        let singleFileCodegen = config[\"single_file_codegen\"]?.bool ?? false\n\n        let bundleInfo = try CompilationItem.BundleInfo(name: bundleName,\n                                                        baseDir: resolvedBundleDir,\n                                                        relativeProjectPathPrefix: relativeProjectPathPrefix,\n                                                        disableHotReload: disableHotReload,\n                                                        disableAnnotationProcessing: disableAnnotationProcessing,\n                                                        disableDependencyVerification: disableDependencyVerification,\n                                                        disableBazelBuildFileGeneration: disableBazelBuildFileGeneration,\n                                                        asyncStrictMode: asyncStrictMode,\n                                                        webNpmScope: webNpmScope,\n                                                        webVersion: webVersion,\n                                                        webPublishConfig: webPublishConfig,\n                                                        webMain: webMain,\n                                                        iosModuleName: iosModuleName,\n                                                        iosLanguage: iosLanguage,\n                                                        iosClassPrefix: iosClassPrefix,\n                                                        androidClassPath: androidClassPath,\n                                                        cppClassPrefix: cppClassPrefix,\n                                                        iosCodegenEnabled: iosCodegenEnabled,\n                                                        androidCodegenEnabled: androidCodegenEnabled,\n                                                        cppCodegenEnabled: cppCodegenEnabled,\n                                                        disableCodeCoverage: disableCodeCoverage,\n                                                        singleFileCodegen: singleFileCodegen,\n                                                        compilationModeConfig: compilationModeConfig,\n                                                        iosOutputTarget: iosOutputTarget,\n                                                        iosGeneratedContextFactories: iosGeneratedContextFactories,\n                                                        androidOutputTarget: androidOutputTarget,\n                                                        webOutputTarget: webOutputTarget,\n                                                        cppOutputTarget: .releaseReady,\n                                                        downloadableAssets: downloadableAssets,\n                                                        downloadableSources: downloadableSources,\n                                                        inclusionConfig: inclusionConfig,\n                                                        excludeGlobs: excludeGlobs,\n                                                        dependencies: dependencies,\n                                                        stringsConfig: stringsConfig,\n                                                        projectConfig: projectConfig,\n                                                        outputTarget: compilerConfig.outputTarget)\n\n        try [Platform.ios, Platform.android, Platform.web].forEach { platform in\n            guard case .releaseReady = bundleInfo.outputTarget(platform: platform) else {\n                return\n            }\n\n            let unexpectedDebugDependencies = dependencies.filter { dep -> Bool in\n                return dep.outputTarget(platform: platform) != .releaseReady && !allowedDebugDependencies.contains(dep)\n            }\n            guard unexpectedDebugDependencies.isEmpty else {\n                throw CompilerError(\"Module '\\(bundleName)''s output_target is set to 'release' when building for \\(platform), but it depends on the following 'debug' targets: \\(unexpectedDebugDependencies.map { $0.name }). If this is intentional, please list them in your module's module.yaml under 'allowed_debug_dependencies'\")\n            }\n        }\n\n        if let conflictingBundle = self.bundleByName[bundleName] {\n            throw CompilerError(\"Found multiple module named '\\(bundleName)': at \\(bundleURL.path) and \\(conflictingBundle.baseDir.path)\")\n        }\n\n        self.bundleByName[bundleName] = bundleInfo\n        self.bundleNameByDirURL[resolvedBundleDir] = bundleName\n\n        return bundleInfo\n    }\n\n    private func resolveDependencies(ofModule moduleName: String, moduleURL: URL, dependencyStrings: [String]) throws -> [CompilationItem.BundleInfo] {\n        return try dependencyStrings.map {\n            do {\n                return try getBundleInfo(bundleName: getDependencyModuleName(dependencyString: $0))\n            } catch let error as CircularDependencyError {\n                throw CircularDependencyError(moduleChain: [moduleName] + error.moduleChain)\n            } catch let error {\n                throw CompilerError(\"Unable to resolve dependency '\\($0)' of module '\\(moduleName)' at \\(moduleURL.relativePath(from: projectConfig.baseDir)): \\(error.legibleLocalizedDescription)\")\n            }\n        }\n    }\n\n    private func getDependencyModuleName(dependencyString: String) -> String {\n        // Dependency strings read from the 'dependencies' section of the module.yaml from the corresponding module\n        let dependencyComponents = dependencyString.split(separator: \"/\")\n        if (dependencyComponents.count >= 2) {\n            let scope = dependencyComponents[dependencyComponents.count - 2]\n            let moduleName = dependencyComponents[dependencyComponents.count - 1]\n\n            return String(moduleName + scope)\n        }\n\n        return dependencyString\n    }\n\n    private func getBundleInfo(bundleName: String) throws -> CompilationItem.BundleInfo {\n        if let bundleInfo = bundleByName[bundleName] {\n            // Cached Bundle if bundleName was resolved previously\n            return bundleInfo\n        }\n\n        let bundleURL: URL\n        let bundleFile: File\n        if let registeredBundle = self.bundleURLByName[bundleName] {\n            // Bundle registered via explicit_input_list.json in [ValdiCompilerRunner.swift]\n            bundleURL = registeredBundle.url\n            bundleFile = registeredBundle.file\n        } else {\n            // Infer based on name from the base directory\n            let resolvedBundlePath = BundleManager.resolveBundleName(bundleName: bundleName)\n\n            // List of directories to look for modules in\n            var possibleBundleURL: URL? = nil\n\n            for urlPrefix in self.baseDirURLs.reversed() {\n                let maybeBundleURL = urlPrefix.appendingPathComponent(resolvedBundlePath).appendingPathComponent(Files.moduleYaml)\n\n                if FileManager.default.fileExists(atPath: maybeBundleURL.path) {\n                    possibleBundleURL = maybeBundleURL\n                    break\n                }\n            }\n\n            if let possibleBundleURL = possibleBundleURL {\n                bundleURL = possibleBundleURL\n            } else {\n                return rootBundle\n            }\n\n            bundleFile = .url(bundleURL)\n        }\n\n        return try loadBundle(bundleName: bundleName, bundleURL: bundleURL, bundleFile: bundleFile)\n    }\n\n    private func resolveBundleInfo(itemURL: URL, dirURL: URL) throws -> CompilationItem.BundleInfo {\n        if let bundleName = self.bundleNameByDirURL[try dirURL.resolvingSymlink()] {\n            return try getBundleInfo(bundleName: bundleName)\n        }\n\n        if baseDirsTrie.get(name: dirURL.pathComponents).nearestValue == nil {\n            if baseDirsTrie.get(name: itemURL.pathComponents).nearestValue != nil {\n                // If our file is containing within the provided baseDir but we couldn't resolve a module\n                // for it, we use the root module as fallback.\n                return rootBundle\n            }\n\n            throw CompilerError(\"File \\(itemURL.path) is not within any provided baseDirs at \\(self.baseDirURLs)\")\n        }\n\n        let possibleBundleURL = dirURL.appendingPathComponent(Files.moduleYaml)\n        if FileManager.default.fileExists(atPath: possibleBundleURL.path) {\n            return try loadBundle(bundleName: dirURL.lastPathComponent, bundleURL: possibleBundleURL, bundleFile: .url(possibleBundleURL))\n        }\n\n        let bundleInfoFromParentDir = try resolveBundleInfo(itemURL: itemURL, dirURL: dirURL.deletingLastPathComponent())\n\n        self.bundleNameByDirURL[dirURL] = bundleInfoFromParentDir.name\n\n        return bundleInfoFromParentDir\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/CSS/CSSModuleCompiler.swift",
    "content": "//\n//  CSSModuleGenerator.swift\n//  \n//\n//  Created by Simon Corsin on 10/29/19.\n//\n\nimport Foundation\n\nstruct CSSModuleCompilerOutputFile {\n    let file: File\n    let outputPath: String\n}\n\nstruct CSSModuleCompilerResult {\n    let compiledCSS: CSSModuleCompilerOutputFile\n    let jsModule: CSSModuleCompilerOutputFile\n    let typeDefinition: CSSModuleCompilerOutputFile\n    let allOpenedFiles: Set<URL>\n}\n\nclass CSSModuleCompiler {\n\n    private let logger: ILogger\n    private let fileContent: String\n    private let projectBaseDir: URL\n    private let relativeProjectPath: String\n\n    init(logger: ILogger, fileContent: String, projectBaseDir: URL, relativeProjectPath: String) {\n        self.logger = logger\n        self.fileContent = fileContent\n        self.projectBaseDir = projectBaseDir\n        self.relativeProjectPath = relativeProjectPath\n    }\n\n    private func generateModule(importPath: String, ruleIndex: Valdi_CSSRuleIndex) -> (typeDefinition: String, jsContent: String) {\n        let classRules = ruleIndex.classRules.sorted { (left, right) -> Bool in\n            return left.name < right.name\n        }\n\n        let tsOutput = CodeWriter()\n        tsOutput.appendBody(\"\"\"\n        /**\n         * CSS Module generated from \\(relativeProjectPath)\n         */\n        \\n\n        \"\"\")\n\n        var jsDeclarationLines = [String]()\n\n        for namedRule in classRules {\n            let className = namedRule.name\n            let tsName = className.camelCased\n\n            tsOutput.appendBody(\"\")\n            tsOutput.appendBody(\"export const \\(tsName): {\\n\")\n\n            for style in namedRule.node.styles {\n                let attributeValue: String\n                if !style.attribute.strValue.isEmpty {\n                    attributeValue = \"'\\(style.attribute.strValue)'\"\n                } else if style.attribute.intValue != 0 {\n                    attributeValue = \"\\(style.attribute.intValue)\"\n                } else {\n                    attributeValue = \"\\(style.attribute.doubleValue)\"\n                }\n                tsOutput.appendBody(\"  \\(style.attribute.name): \\(attributeValue);\\n\")\n            }\n\n            tsOutput.appendBody(\"}\\n\\n\")\n\n            jsDeclarationLines.append(\"'\\(tsName)': '\\(className)'\")\n        }\n\n        // TODO(3521): Update to valdi\n        let jsOutput = \"\"\"\n        module.exports = require('valdi_core/src/CSSModule').makeModule('\\(importPath)', {\\(jsDeclarationLines.joined(separator: \", \"))});\\n\n        \"\"\"\n\n        return (typeDefinition: tsOutput.content.indented(indentPattern: \"  \"), jsContent: jsOutput)\n    }\n\n    func compile() throws -> CSSModuleCompilerResult {\n        let baseURL = projectBaseDir.appendingPathComponent(relativeProjectPath).deletingLastPathComponent()\n        let compiler = StyleSheetCompiler(logger: logger, content: fileContent, baseURL: baseURL, relativeProjectPath: relativeProjectPath)\n        let result = try compiler.compile()\n\n        let data = try result.rootStyleNode.orderedSerializedData()\n\n        let importPath = \"\\(relativeProjectPath).\\(FileExtensions.valdiCss)\"\n\n        let compiledCSS = CSSModuleCompilerOutputFile(file: .data(data), outputPath: importPath)\n\n        let module = generateModule(importPath: importPath, ruleIndex: result.rootStyleNode.ruleIndex)\n\n        let jsModule = CSSModuleCompilerOutputFile(file: .data(try module.jsContent.utf8Data()), outputPath: \"\\(relativeProjectPath).js\")\n\n        let typeDefinitionPath = \"\\(relativeProjectPath).\\(FileExtensions.typescriptDeclaration)\"\n        let typeDefinition = CSSModuleCompilerOutputFile(file: .data(try module.typeDefinition.utf8Data()), outputPath: typeDefinitionPath)\n\n        return CSSModuleCompilerResult(compiledCSS: compiledCSS, jsModule: jsModule, typeDefinition: typeDefinition, allOpenedFiles: compiler.filesImported)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/CSS/Selector.swift",
    "content": "//\n//  Selector.swift\n//  Compiler\n//\n//  Created by Nathaniel Parrott on 5/14/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport SwiftCSSParser\n\nclass SelectorTerm {\n    init() { }\n    // represents a selector as a linked list.\n    // e.g. in .nav > Label:first-child, 'nav' and `Label:first-child` would be two terms,\n    // with the SelectorTerm for `Label:first-child` as the root, with a link to the term for `.nav`.\n    // A term without any values set would represent the universal selector\n    var idRule: String?\n    var classRules: [String] = []\n    var tagRule: String?\n    var attributeRules: [(attribute: String, value: String, type: Valdi_CSSRuleIndex.AttributeRule.TypeEnum)] = []\n    var firstChild = false\n    var lastChild = false\n    var nthChildRules: [(n: Int?, offset: Int?)] = []\n    var parent: (term: SelectorTerm, directChild: Bool)?\n\n    class func parseSelectorToTerms(selector: StyleSelector, termNode: SelectorTerm) throws {\n        // returns the last term in the selector, which holds a reference to the term before it, etc\n        guard let match = selector.match else { return /* done */ }\n        switch match {\n        case .className:\n            termNode.classRules.append(selector.value!)\n        case .id:\n            termNode.idRule = selector.value!\n        case .pseudoClass:\n            guard let psuedoType = selector.psuedoType else {\n                throw CompilerError(\"Unsupported CSS selector: \\(selector.value ?? \"\")\")\n            }\n            switch psuedoType {\n            case .firstChild:\n                termNode.firstChild = true\n            case .lastChild:\n                termNode.lastChild = true\n            case .nthChild:\n                guard let argument = selector.data?.argument else {\n                    throw CompilerError(\"No argument provided for nth-child selector\")\n                }\n                let nth = try parseNthChildArgument(argument)\n                termNode.nthChildRules.append(( n: nth.n, offset: nth.offset ))\n            default:\n                throw CompilerError(\"Unknown css psuedo-selector: \\(psuedoType)\")\n            }\n        case .attributeExact:\n            termNode.attributeRules.append((attribute: selector.data!.attribute!, value: selector.value!, type: Valdi_CSSRuleIndex.AttributeRule.TypeEnum.equals))\n        case .tag:\n            termNode.tagRule = selector.value!\n            // TODO: support non-exact attribute selectors, even though they aren't supported by the katana Swift wrapper (need to check the raw c structs)\n        }\n        if let related = selector.related, let relation = selector.relation, related.match != nil {\n            // there's another term before this one, or another part of the current term:\n            switch relation {\n            case .child, .descendant:\n                termNode.parent = (term: SelectorTerm(), directChild: relation == .child)\n                try parseSelectorToTerms(selector: related, termNode: termNode.parent!.term)\n            case .subselector:\n                // additional qualifier on the current term\n                try parseSelectorToTerms(selector: related, termNode: termNode)\n            default:\n                throw CompilerError(\"Unsupported css relation: \\(relation)\")\n            }\n        }\n    }\n\n    private class func parseNthChildArgument(_ argument: String) throws -> (n: Int, offset: Int) {\n        let argument = argument.trimmed\n        if argument == \"even\" {\n            return (n: 2, offset: 0)\n        }\n        if argument == \"odd\" {\n            return (n: 2, offset: 1)\n        }\n        if !argument.contains(\"n\") {\n            guard let offset = Int(argument) else {\n                throw CompilerError(\"Failed to parse nth-child offset value: '\\(argument)'\")\n            }\n            return (n: 0, offset: offset)\n        }\n\n        let components = argument.components(separatedBy: \"n\")\n        let nStr = !components.isEmpty ? components[0] : \"\"\n        let offsetStr = components.count > 1 ? components[1].replacingOccurrences(of: \" \", with: \"\") : \"\"\n\n        guard let n = nStr.isEmpty || nStr == \"+\" ? 1 : (nStr == \"-\" ? -1 : Int(nStr)) else {\n            throw CompilerError(\"Failed to parse nth-child n value: '\\(nStr)'\")\n        }\n        guard let offset = offsetStr.isEmpty ? 0 : Int(offsetStr) else {\n            throw CompilerError(\"Failed to parse nth-child offset value: '\\(offsetStr)'\")\n        }\n        return (n: n, offset: offset)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/CSS/StyleSheetCompiler.swift",
    "content": "//\n//  CSSCompiler.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass StyleSheetCompiler {\n\n    private let logger: ILogger\n    private let content: String\n    private let baseURL: URL\n    private let relativeProjectPath: String\n\n    private(set) var filesImported: Set<URL> = []\n    private var sassCompiler: SassCompiler = SassCompiler()\n\n    init(logger: ILogger, content: String, baseURL: URL, relativeProjectPath: String) {\n        self.logger = logger\n        self.content = content\n        self.baseURL = baseURL\n        self.relativeProjectPath = relativeProjectPath\n    }\n\n    private func importCssFile(url: URL, tree: StyleTree) throws {\n        guard !filesImported.contains(url) else {\n            throw CompilerError(\"Cyclic import detected\")\n        }\n\n        filesImported.insert(url)\n        let cssContent = try String(contentsOf: url)\n        return try processCss(cssContent: cssContent, baseURL: url, tree: tree)\n    }\n\n    private func processCss(cssContent: String, baseURL: URL, tree: StyleTree) throws {\n        logger.verbose(\"Processing CSS for \\(relativeProjectPath)\")\n        var importFilenames = [String]()\n        try tree.add(logger: logger, cssString: cssContent, filename: baseURL.path) { filename in\n            importFilenames.append(filename)\n        }\n\n        for filename in importFilenames {\n            let fileURL = baseURL.resolving(path: filename)\n            try importCssFile(url: fileURL, tree: tree)\n        }\n    }\n\n    private func compileSass(sassContent: String, baseURL: URL) throws -> String {\n        logger.verbose(\"Compiling SASS for \\(relativeProjectPath)\")\n        guard let data = sassContent.data(using: .utf8) else {\n            throw CompilerError(\"Error converting style content into data\")\n        }\n\n        // The sass compiler will automatically resolve .scss imports, but .css imports will still exist\n        let result = try sassCompiler.compile(file: .data(data), importBaseDirectoryURL: baseURL)\n        for includedFilePath in result.includedFilePaths {\n            filesImported.insert(baseURL.resolving(path: includedFilePath))\n        }\n\n        return result.output\n    }\n\n    func compile() throws -> StyleSheetCompilerResult {\n        let tree = StyleTree()\n\n        self.filesImported = []\n\n        // Always compile as sass first, then resolve css imports that still exist after compilation\n        let cssContent = try compileSass(sassContent: content, baseURL: baseURL)\n        try processCss(cssContent: cssContent, baseURL: baseURL, tree: tree)\n\n        return StyleSheetCompilerResult(rootStyleNode: tree.root.toProto(logger: logger))\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/CSS/StyleSheetCompilerResult.swift",
    "content": "//\n//  StyleSheetCompilerResult.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct StyleSheetCompilerResult {\n    let rootStyleNode: Valdi_StyleNode\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/CSS/StyleTree+Proto.swift",
    "content": "//\n//  StyleTree+Proto.swift\n//  Compiler\n//\n//  Created by Nathaniel Parrott on 5/14/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension StyleNode {\n\n    private func convert(logger: ILogger, rules: [String: StyleNode]) -> [Valdi_NamedStyleNode] {\n        var out: [Valdi_NamedStyleNode] = rules.map {\n            var node = Valdi_NamedStyleNode()\n            node.name = $0\n            node.node = $1.toProto(logger: logger)\n            return node\n        }\n\n        out.sort(by: { $0.name < $1.name })\n\n        return out\n    }\n\n    func toProto(logger: ILogger) -> Valdi_StyleNode {\n        var p = Valdi_StyleNode()\n\n        p.ruleIndex.idRules = convert(logger: logger, rules: idRules)\n        p.ruleIndex.classRules = convert(logger: logger, rules: classRules)\n        p.ruleIndex.tagRules = convert(logger: logger, rules: tagRules)\n        for attrRule in attribRules {\n            var ruleProto = Valdi_CSSRuleIndex.AttributeRule()\n            ruleProto.attribute = Valdi_NodeAttribute(logger: logger, name: attrRule.attrib, value: attrRule.value)\n            ruleProto.type = attrRule.type\n            ruleProto.node = attrRule.node.toProto(logger: logger)\n            p.ruleIndex.attributeRules.append(ruleProto)\n        }\n        if let firstChild = firstChildRule {\n            p.ruleIndex.firstChildRule = firstChild.toProto(logger: logger)\n        }\n        if let lastChild = lastChildRule {\n            p.ruleIndex.lastChildRule = lastChild.toProto(logger: logger)\n        }\n        for nthChildRule in nthChildRules {\n            var ruleProto = Valdi_CSSRuleIndex.NthChildRule()\n            if let n = nthChildRule.n {\n                ruleProto.n = Int32(n)\n            }\n            if let offset = nthChildRule.offset {\n                ruleProto.offset = Int32(offset)\n            }\n            ruleProto.node = nthChildRule.node.toProto(logger: logger)\n            p.ruleIndex.nthChildRules.append(ruleProto)\n        }\n        if let parent = directParentRule {\n            p.ruleIndex.directParentRules = parent.toProto(logger: logger).ruleIndex\n        }\n        if let parent = ancestorRule {\n            p.ruleIndex.ancestorRules = parent.toProto(logger: logger).ruleIndex\n        }\n        p.styles = declarations\n        return p\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/CSS/StyleTree.swift",
    "content": "//\n//  StyleTree.swift\n//  Compiler\n//\n//  Created by Nathaniel Parrott on 5/14/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport SwiftCSSParser\n\nclass StyleTree {\n\n    init() {\n\n    }\n\n    let root = StyleNode()\n\n    func add(logger: ILogger, cssString: String, filename: String, onImport: ((String) throws -> Void)?) throws {\n        if cssString.isEmpty {\n            return\n        }\n\n        guard let parsed = StyleSheet(string: cssString) else {\n            throw CompilerError(\"Failed to parse CSS from \\(filename)\")\n        }\n        if let cssErr = parsed.errors.first {\n            throw cssErr\n        }\n        for importFilename in parsed.importFilenames {\n            try onImport?(importFilename)\n        }\n        for rule in parsed.rules {\n            for selector in rule.selectors {\n                let rootSelectorTerm = SelectorTerm()\n                try SelectorTerm.parseSelectorToTerms(selector: selector, termNode: rootSelectorTerm)\n                root.add(logger: logger, declarations: rule.declarations, forSelectorTerm: rootSelectorTerm, specificity: selector.specificity!, totalRuleCount: totalRuleCount)\n            }\n        }\n    }\n\n    class TotalRuleCount {\n        init() { }\n        var count = 0\n    }\n    let totalRuleCount = TotalRuleCount()\n}\n\nclass StyleNode {\n    init() { }\n\n    var declarations: [Valdi_StyleDeclaration] = []\n    var idRules: [String: StyleNode] = [:]\n    var classRules: [String: StyleNode] = [:]\n    var tagRules: [String: StyleNode] = [:]\n    var attribRules: [AttribRule] = []\n    var firstChildRule: StyleNode?\n    var lastChildRule: StyleNode?\n    var nthChildRules: [NthChildRule] = []\n    var ancestorRule: StyleNode?\n    var directParentRule: StyleNode?\n\n    struct AttribRule {\n        let attrib: String\n        let value: String\n        let type: Valdi_CSSRuleIndex.AttributeRule.TypeEnum\n        let node: StyleNode\n    }\n\n    struct NthChildRule {\n        let n: Int?\n        let offset: Int?\n        let node: StyleNode\n    }\n\n    func add(logger: ILogger, declarations: [StyleDeclaration], forSelectorTerm term: SelectorTerm, specificity: Int, totalRuleCount: StyleTree.TotalRuleCount) {\n        // When building (and querying) the tree, it's important\n        // to be consistent in our ordering of selector rules.\n        // Label.classA.classB is semantically identical to .classB.classA.Label,\n        // so they need to be added to the tree in a consistent order.\n        // [.classA] -> [.classB] -> [Label]\n        // This means sorting classes and attribute selectors, and adding\n        // rules in the order they're specified in the proto -- id -> class -> tag -> attrib -> firstChild -> lastChild -> nthChild.\n        var curNode = self\n        if let idString = term.idRule {\n            if curNode.idRules[idString] == nil {\n                curNode.idRules[idString] = StyleNode()\n            }\n            curNode = curNode.idRules[idString]!\n        }\n        for classString in term.classRules.sorted() {\n            if curNode.classRules[classString] == nil {\n                curNode.classRules[classString] = StyleNode()\n            }\n            curNode = curNode.classRules[classString]!\n        }\n        if let tag = term.tagRule {\n            if curNode.tagRules[tag] == nil {\n                curNode.tagRules[tag] = StyleNode()\n            }\n            curNode = curNode.tagRules[tag]!\n        }\n        for (attribute, value, type) in term.attributeRules.sorted(by: { (attr1, attr2) -> Bool in\n            return attr1.attribute <= attr2.attribute\n        }) {\n            if let existingNode = curNode.attribRules.filter({ $0.attrib == attribute && $0.value == value && $0.type == type }).first?.node {\n                curNode = existingNode\n            } else {\n                let newNode = StyleNode()\n                curNode.attribRules.append(AttribRule(attrib: attribute.camelCased, value: value, type: type, node: newNode))\n                curNode = newNode\n            }\n        }\n        if term.firstChild {\n            if curNode.firstChildRule == nil {\n                curNode.firstChildRule = StyleNode()\n            }\n            curNode = curNode.firstChildRule!\n        }\n        if term.lastChild {\n            if curNode.lastChildRule == nil {\n                curNode.lastChildRule = StyleNode()\n            }\n            curNode = curNode.lastChildRule!\n        }\n        for (n, offset) in term.nthChildRules.sorted(by: { (item1, item2) -> Bool in\n            if item1.n ?? 0 < item2.n ?? 0 {\n                return true\n            }\n            return item1.offset ?? 0 <= item2.offset ?? 0\n        }) {\n            if let existingNode = curNode.nthChildRules.filter({ $0.n == n && $0.offset == offset }).first?.node {\n                curNode = existingNode\n            } else {\n                let newNode = StyleNode()\n                curNode.nthChildRules.append(NthChildRule(n: n, offset: offset, node: newNode))\n                curNode = newNode\n            }\n        }\n        if let (term, directChild) = term.parent {\n            if directChild {\n                if curNode.directParentRule == nil {\n                    curNode.directParentRule = StyleNode()\n                }\n                curNode.directParentRule!.add(logger: logger, declarations: declarations, forSelectorTerm: term, specificity: specificity, totalRuleCount: totalRuleCount)\n            } else {\n                if curNode.ancestorRule == nil {\n                    curNode.ancestorRule = StyleNode()\n                }\n                curNode.ancestorRule!.add(logger: logger, declarations: declarations, forSelectorTerm: term, specificity: specificity, totalRuleCount: totalRuleCount)\n            }\n        } else {\n            // add declarations:\n            for declaration in declarations {\n                var declarationProto = Valdi_StyleDeclaration()\n                declarationProto.priority = Int32(specificity)\n                declarationProto.order = Int32(totalRuleCount.count)\n                declarationProto.attribute = Valdi_NodeAttribute(logger: logger, name: declaration.name.camelCased, value: declaration.value)\n                declarationProto.id = declarationProto.order // order is unique to each compile, so we can use it as our ID\n                totalRuleCount.count += 1\n                curNode.declarations.append(declarationProto)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Config/CompilerConfig.swift",
    "content": "import Foundation\n\n// Structure for collecting configuration values for the current\n// invocation of the Compiler.\nstruct CompilerConfig {\n    let hotReloadingEnabled: Bool\n    let disableDiskCache: Bool\n\n    // Skip starting the debugging proxy when running in the hot reloader mode.\n    let disableDebuggingProxy: Bool\n\n    let skipCalculatingCompanionBinarySignature: Bool\n\n    let tsSkipVerifyingImports: Bool\n    let tsEmitDeclarationFiles: Bool\n\n    // Currently, emitted declaration (.d.ts) files from dependencies must have their comments kept intact\n    // because generating native Obj-C/Kotlin types requires parsing the @GenerateNativeXXX annotations on types\n    // imported from dependencies.\n    let tsKeepComments: Bool\n\n    // HACK: Until we figure out how to get a fresh LCA token when executing a Bazel rule, we can't\n    // use the artifact service to upload downloadable assets to Bolt.\n    let disableDownloadableModules: Bool\n\n    /// When specified, the compiler will serialize the result of the dumpAllSymbols command in the provided\n    /// directory.\n    let outputDumpedSymbolsDirectory: URL?\n\n    /// If set, only TypeScript files from these modules will be included when issuing TypeScript\n    /// open/check/compileAndSave commands to the companion.\n    ///\n    /// This allows us to minimize the amount of TypeScript operations that have to be performed when\n    /// compiling modules in isolation.\n    ///\n    /// (Note: successful compilation requires dumped symbols from dependencies\n    /// to be present. See `inputDumpedSymbolsDirectory`).\n    let onlyCompileTypeScriptForModules: Set<String>\n\n    /// When set, native types, functions, view classes will only be generated for the specified modules.\n    let onlyGenerateNativeCodeForModules: Set<String>\n\n    /// When set, image resources will only be processed for the specified modules\n    let onlyProcessResourcesForModules: Set<String>\n\n    /// When set, dependency data will only be processed for the specified modules\n    let onlyFocusProcessingForModules: Set<String>\n\n    /// Direct path to the companion app\n    let directCompanionPath: String?\n\n    /// List of input files to pass to the compiler instead of automatically discovering them\n    let explicitInputList: CompilerFileInputList?\n\n    /// When set, this will _rewrite_ the BUILD.bazel files within the sources of each Valdi module\n    let regenerateValdiModulesBuildFiles: Bool\n\n    /// When set, only the steps that generate TS code will run, which includes Strings.d.ts and res.d.ts files\n    let generateTSResFiles: Bool\n\n    /// When set, this wil validate artifacts against .downloadableArtifacts instead of uploading\n    let verifyDownloadableArtifacts: Bool\n\n    /// Whether we should process the outputs for iOS\n    let outputForIOS: Bool\n\n    /// Whether we should process the outputs for Android\n    let outputForAndroid: Bool\n\n    /// Whether we should process the outputs for Web\n    let outputForWeb: Bool\n\n    /// Whether we should process the outputs for C++\n    let outputForCpp: Bool\n\n    /// Whether to output for release, debug or both\n    let outputTarget: OutputTarget\n\n    static func from(args: ValdiCompilerArguments, baseURL: URL, environment: [String: String]) throws -> CompilerConfig {\n        let hotReloadingEnabled = args.monitor\n\n        let disableDiskCache = args.disableDiskCache\n        let skipCalculatingCompanionBinarySignature = args.disableDiskCache\n\n        let tsSkipVerifyingImports = hotReloadingEnabled || args.tsSkipVerifyingImports\n        let tsEmitDeclarationFiles = args.tsEmitDeclarationFiles\n        let tsKeepComments = args.tsKeepComments\n\n        let disableDownloadableModules = args.disableDownloadableModules\n\n        let outputDumpedSymbolsDirectory = args.outputDumpedSymbolsDir.map { baseURL.appendingPathComponent($0, isDirectory: true) }\n\n        let explicitInputList = try args.explicitInputListFile\n            .map {\n                let url = baseURL.appendingPathComponent($0)\n                let data = try File.url(url).readData()\n                let parsed = try CompilerFileInputList.fromJSON(data, keyDecodingStrategy: .convertFromSnakeCase)\n\n                return try parsed.resolvingVariables(environment)\n            }\n\n        return CompilerConfig(\n            hotReloadingEnabled: hotReloadingEnabled,\n            disableDiskCache: disableDiskCache,\n            disableDebuggingProxy: args.noDebuggingProxy,\n            skipCalculatingCompanionBinarySignature: skipCalculatingCompanionBinarySignature,\n            tsSkipVerifyingImports: tsSkipVerifyingImports,\n            tsEmitDeclarationFiles: tsEmitDeclarationFiles,\n            tsKeepComments: tsKeepComments,\n            disableDownloadableModules: disableDownloadableModules,\n            outputDumpedSymbolsDirectory: outputDumpedSymbolsDirectory,\n            onlyCompileTypeScriptForModules: Set(args.onlyCompileTsForModule),\n            onlyGenerateNativeCodeForModules: Set(args.onlyGenerateNativeCodeForModule),\n            onlyProcessResourcesForModules: Set(args.onlyProcessResourcesForModule),\n            onlyFocusProcessingForModules: Set(args.onlyFocusProcessingForModule),\n            directCompanionPath: args.directCompanionPath,\n            explicitInputList: explicitInputList,\n            regenerateValdiModulesBuildFiles: args.regenerateValdiModulesBuildFiles,\n            generateTSResFiles: args.generateTSResFiles,\n            verifyDownloadableArtifacts: args.verifyDownloadableArtifacts,\n            outputForIOS: args.ios,\n            outputForAndroid: args.android,\n            outputForWeb: args.web,\n            outputForCpp: args.cpp,\n            outputTarget: args.outputTarget ?? OutputTarget.all\n        )\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Config/CompilerFileInputList.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nstruct CompilerFileInputListEntryFile: Codable {\n    let file: String\n    let content: String?\n    let relativeProjectPath: String\n}\n\nstruct CompilerFileInputListEntry: Codable {\n    let moduleName: String\n    let modulePath: String\n    let moduleContent: String?\n    let monitor: Bool?\n    let autoDiscover: Bool?\n    let files: [CompilerFileInputListEntryFile]\n}\n\nstruct CompilerFileInputList: Codable {\n    let entries: [CompilerFileInputListEntry]\n}\n\nextension CompilerFileInputListEntryFile {\n    func resolvingVariables(_ variables: [String: String]) throws -> CompilerFileInputListEntryFile {\n        return CompilerFileInputListEntryFile(file: try file.resolvingVariables(variables),\n                                              content: content,\n                                              relativeProjectPath: try relativeProjectPath.resolvingVariables(variables))\n    }\n}\n\nextension CompilerFileInputListEntry {\n    func resolvingVariables(_ variables: [String: String]) throws -> CompilerFileInputListEntry {\n        return CompilerFileInputListEntry(moduleName: moduleName,\n                                          modulePath: try modulePath.resolvingVariables(variables),\n                                          moduleContent: moduleContent,\n                                          monitor: monitor,\n                                          autoDiscover: autoDiscover,\n                                          files: try files.map { try $0.resolvingVariables(variables) })\n    }\n}\n\nextension CompilerFileInputList {\n    func resolvingVariables(_ variables: [String: String]) throws -> CompilerFileInputList {\n        return CompilerFileInputList(entries: try self.entries.map {  try $0.resolvingVariables(variables)})\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Config/ResolvedConfigs.swift",
    "content": "import Foundation\n\nstruct ResolvedConfigs {\n    let compilerConfig: CompilerConfig\n    let projectConfig: ValdiProjectConfig\n    let userConfig: ValdiUserConfig\n\n    static func from(logger: ILogger, baseURL: URL, userConfigURL: URL, args: ValdiCompilerArguments) throws -> ResolvedConfigs {\n        var userConfig = ValdiUserConfig(usernames: [], deviceIds: [], ipAddresses: [], logsOutputDir: nil)\n        if FileManager.default.fileExists(atPath: userConfigURL.path) {\n            userConfig = try ValdiUserConfig.from(configUrl: userConfigURL, args: args)\n            logger.info(\"Parsed the user config at \\(userConfigURL.path)\")\n        }\n\n        guard let projectConfigPath = args.config else {\n            throw CompilerError(\"No project config provided\")\n        }\n\n        var environment = ProcessInfo.processInfo.environment\n        // Insert PWD magic env var if its not there\n        environment[\"PWD\"] = baseURL.path\n\n        let projectConfigURL = baseURL.resolving(path: projectConfigPath, isDirectory: false)\n        let projectConfig = try ValdiProjectConfig.from(logger: logger, configUrl: projectConfigURL, currentDirectoryUrl: baseURL, environment: environment, args: args)\n        logger.info(\"Parsed the project config at \\(projectConfigURL.path)\")\n\n        let compilerConfig = try CompilerConfig.from(args: args, baseURL: baseURL, environment: environment)\n        return ResolvedConfigs(compilerConfig: compilerConfig,\n                               projectConfig: projectConfig,\n                               userConfig: userConfig)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Config/ValdiProjectConfig.swift",
    "content": "//\n//  ValdiProjectConfig.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/15/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport Yams\n\nstruct ValdiOutputConfig {\n    let ignoredFiles: [NSRegularExpression]\n    let debugPath: UnresolvedPath?\n    let releasePath: UnresolvedPath?\n    let metadataPath: UnresolvedPath?\n    let globalMetadataPath: UnresolvedPath?\n    let codegenEnabled: Bool\n\n    static let noop = ValdiOutputConfig(ignoredFiles: [], debugPath: nil, releasePath: nil, metadataPath: nil, globalMetadataPath: nil, codegenEnabled: false)\n}\n\nstruct ValdiCodeCoverageConfig: Codable {\n    let reportFolder: URL\n    let reportResultFile: URL\n    let instrumentedFilesResult: URL\n}\n\nstruct GeneratedBuildFileConfig {\n    let buildFileName: String\n    let buildFileMacroPath: String\n    let buildFileMacroName: String\n}\n\nstruct ValdiProjectConfig {\n    let configDirectoryUrl: URL\n    let projectName: String\n    let baseDir: URL\n\n    var webEnabled: Bool\n\n    var iosOutput: ValdiOutputConfig?\n    var androidOutput: ValdiOutputConfig?\n    var webOutput: ValdiOutputConfig?\n    var cppOutput: ValdiOutputConfig?\n\n    var iosBuildFileConfig: GeneratedBuildFileConfig?\n    var androidBuildFileConfig: GeneratedBuildFileConfig?\n    var webBuildFileConfig: GeneratedBuildFileConfig?\n\n    var codeCoverageResultConfig: ValdiCodeCoverageConfig\n\n    let iosDefaultModuleNamePrefix: String?\n    let iosDefaultLanguage: IOSLanguage\n\n    let ignoredFiles: [NSRegularExpression]\n    let directoriesToKeepRegexes: [NSRegularExpression]\n\n    let moduleUploadBaseURL: URL?\n    let diagnosticsDir: URL\n    let compilerCompanionBinaryURL: URL?\n    var shouldDebugCompilerCompanion: Bool\n    var shouldEmitDiagnostics: Bool\n    var shouldSkipRemoveOrphanFiles: Bool\n\n    let compilerToolboxURL: URL\n\n    let minifyConfigURL: URL?\n\n    let pngquantURL: URL?\n\n    let clientSqlURL: URL?\n    \n    let sqlExportPathTemplate: String?\n\n    let androidDefaultClassPath: String?\n\n    let cppDefaultClassPrefix: String?\n\n    let cppImportPathPrefix: String?\n\n    /**\n     If set for the project, artifacts will not be uploaded, they\n     will be stored as this location instead.\n     */\n    var preparedUploadArtifactOutput: URL?\n\n    let buildDirectoryURL: URL\n    let generatedTsDirectoryURL: URL\n\n    let androidJsBytecodeFormat: String?\n\n    let nodeModulesDir: URL?\n\n    let openSourceDir: URL?\n\n    let nodeModulesTarget: String?\n    let nodeModulesWorkspace: String?\n    let externalModulesTarget: String?\n    let externalModulesWorkspace: String?\n\n    private static func parseOutputConfig(inputConfig: Yams.Node.Mapping?,\n                                          ignoredFiles: [NSRegularExpression]?,\n                                          baseDirUrl: URL,\n                                          environment: [String: String]\n    ) throws -> ValdiOutputConfig? {\n        guard let configDict = inputConfig?[\"output\"] else { return nil }\n        guard let basePath = configDict[\"base\"]?.string else {\n            return nil\n        }\n\n        func parseAndResolve(_ key: String) -> UnresolvedPath? {\n            return configDict[key]?.string.flatMap { UnresolvedPath(baseURL: baseDirUrl, components: [basePath, $0], variables: environment) }\n        }\n\n        let debugPath = parseAndResolve(\"debug_path\")\n        let releasePath = parseAndResolve(\"release_path\")\n        let metadataPath = parseAndResolve(\"metadata_path\")\n        let globalMetadataPath = parseAndResolve(\"global_metadata_path\")\n        let codegenEnabled = inputConfig?[\"codegen_enabled\"]?.bool ?? true\n\n        return ValdiOutputConfig(ignoredFiles: ignoredFiles ?? [],\n                                    debugPath: debugPath,\n                                    releasePath: releasePath,\n                                    metadataPath: metadataPath,\n                                    globalMetadataPath: globalMetadataPath,\n                                    codegenEnabled: codegenEnabled)\n    }\n\n    private static func parseCodeCoverageConfig(codeCoverageConfig: Yams.Node.Mapping?,\n                                                configDirectoryUrl: URL) -> ValdiCodeCoverageConfig {\n        func parseAndResolve(_ key: String, _ defaultValue: String) -> URL {\n            return configDirectoryUrl.resolving(path: (codeCoverageConfig?[key]?.string ?? defaultValue), isDirectory: true)\n        }\n\n        let reportFolder = parseAndResolve(\"report_folder\", \"./coverage\")\n        let reportResultFile = parseAndResolve(\"code_coverage_report_result\", \"./coverage/result.json\")\n        let instrumentedFilesResult = parseAndResolve(\"instrumented_files_result\", \"./coverage/files.json\")\n\n        return ValdiCodeCoverageConfig(reportFolder: reportFolder, reportResultFile: reportResultFile, instrumentedFilesResult: instrumentedFilesResult)\n    }\n\n    private static func getOSSpecificValue(config: Yams.Node, key: String) -> Yams.Node? {\n        if let dict = config[key]?.mapping {\n#if os(Linux)\n            return dict[\"linux\"]\n#else\n            return dict[\"macos\"]\n#endif\n        } else {\n            return config[key]\n        }\n    }\n\n    static func from(logger: ILogger, configUrl: URL, currentDirectoryUrl: URL, environment: [String: String], args: ValdiCompilerArguments) throws -> ValdiProjectConfig {\n        let configValueOverrides = args.configValue\n\n        let configContent = try String(contentsOf: configUrl)\n        guard var config = try Yams.compose(yaml: configContent) else {\n            throw CompilerError(\"Failed to parse project config at: \\(configUrl)\")\n        }\n\n        for configValue in configValueOverrides {\n            do {\n                let parsedValue = try ConfigValue.parse(text: configValue)\n                config = parsedValue.inject(into: config)\n            } catch let error {\n                throw CompilerError(\"Failed to parse config value '\\(configValue)': \\(error.legibleLocalizedDescription)\")\n            }\n        }\n\n        guard let baseDirPath = try config[\"base_dir\"]?.string?.resolvingVariables(environment) else {\n            throw CompilerError(\"Missing base_dir in config file\")\n        }\n\n        let configDirectoryUrl = configUrl.deletingLastPathComponent()\n\n        let baseDirUrl = configDirectoryUrl.resolving(path: baseDirPath, isDirectory: true)\n\n        let projectName = try config[\"project_name\"]?.string?.resolvingVariables(environment) ?? baseDirUrl.lastPathComponent\n\n        let iosConfig = config[\"ios\"]?.mapping\n\n        let ignoredPatternsIOS = try iosConfig?[\"exclude_patterns\"]?.array()\n            .compactMap { try $0.string?.resolvingVariables(environment) }\n            .map { try NSRegularExpression(pattern: $0, options: []) }\n\n        let iosOutputConfig = try parseOutputConfig(inputConfig: iosConfig, ignoredFiles: ignoredPatternsIOS, baseDirUrl: baseDirUrl, environment: environment)\n        let iosDefaultModuleNamePrefix = iosConfig?[\"default_module_name_prefix\"]?.string\n        let iosDefaultLanguage = try IOSLanguage.parse(input: iosConfig?[\"default_language\"]?.string ?? \"objc\")\n\n        let iosBuildFileEnabled = iosConfig?[\"build_file_enabled\"]?.bool ?? false\n        let iosBuildFileName = iosConfig?[\"build_file_name\"]?.string ?? \"BUILD.bazel\"\n        let iosBuildFileMacroPath = iosConfig?[\"build_file_macro_path\"]?.string ?? \"@macros//:DEFS.bzl\"\n        let iosBuildFileMacroName = iosConfig?[\"build_file_macro_name\"]?.string ?? \"modularised_valdi_module\"\n        let iosBuildFileConfig = iosBuildFileEnabled ? GeneratedBuildFileConfig(buildFileName: iosBuildFileName,\n                                                                                buildFileMacroPath: iosBuildFileMacroPath,\n                                                                                buildFileMacroName: iosBuildFileMacroName) : nil\n\n        let androidConfig = config[\"android\"]?.mapping\n\n        let ignoredPatternsAndroid = try androidConfig?[\"exclude_patterns\"]?.array()\n            .compactMap { try $0.string?.resolvingVariables(environment) }\n            .map { try NSRegularExpression(pattern: $0, options: []) }\n\n        let androidOutputConfig = try parseOutputConfig(inputConfig: androidConfig, ignoredFiles: ignoredPatternsAndroid, baseDirUrl: baseDirUrl, environment: environment)\n        let androidDefaultClassPath = androidConfig?[\"class_path\"]?.string\n        let androidJsBytecodeFormat = androidConfig?[\"js_bytecode_format\"]?.string\n\n        let androidBuildFileEnabled = androidConfig?[\"build_file_enabled\"]?.bool ?? config[\"build_file_generation_enabled\"]?.bool ?? false\n        let androidBuildFileName = androidConfig?[\"build_file_name\"]?.string ?? \"BUILD.bazel\"\n        let androidBuildFileMacroPath = androidConfig?[\"build_file_macro_path\"]?.string ?? \"//bzl/valdi:valdi_module.bzl\"\n        let androidBuildFileMacroName = androidConfig?[\"build_file_macro_name\"]?.string ?? \"valdi_module\"\n        let androidBuildFileConfig = androidBuildFileEnabled ? GeneratedBuildFileConfig(buildFileName: androidBuildFileName,\n                                                                                        buildFileMacroPath: androidBuildFileMacroPath,\n                                                                                        buildFileMacroName: androidBuildFileMacroName) : nil\n\n        let webConfig = config[\"web\"]?.mapping\n\n        let ignoredPatternsWeb = try webConfig?[\"exclude_patterns\"]?.array()\n            .compactMap { try $0.string?.resolvingVariables(environment) }\n            .map { try NSRegularExpression(pattern: $0, options: []) }\n\n        let webOutputConfig = try parseOutputConfig(inputConfig: webConfig, ignoredFiles: ignoredPatternsWeb, baseDirUrl: baseDirUrl, environment: environment)\n        let webBuildFileEnabled = webConfig?[\"build_file_enabled\"]?.bool ?? config[\"build_file_generation_enabled\"]?.bool ?? true\n        let webBuildFileName = webConfig?[\"build_file_name\"]?.string ?? \"package.json\"\n        let webBuildFileConfig = webBuildFileEnabled ? GeneratedBuildFileConfig(buildFileName: webBuildFileName,\n                                                                                    buildFileMacroPath: \"\",\n                                                                                    buildFileMacroName: \"\") : nil\n\n\n        let codeCoverageConfig = config[\"code_coverage\"]?.mapping\n\n        let codeCoverageResultConfig = parseCodeCoverageConfig(codeCoverageConfig: codeCoverageConfig, configDirectoryUrl: configDirectoryUrl)\n\n        let cppConfig = config[\"cpp\"]?.mapping\n\n        let ignoredPatternsCpp = try cppConfig?[\"exclude_patterns\"]?.array()\n            .compactMap { try $0.string?.resolvingVariables(environment) }\n            .map { try NSRegularExpression(pattern: $0, options: []) }\n\n        let cppOutputConfig = try parseOutputConfig(inputConfig: cppConfig, ignoredFiles: ignoredPatternsCpp, baseDirUrl: baseDirUrl, environment: environment)\n\n        let cppDefaultClassPrefix = cppConfig?[\"default_class_prefix\"]?.string\n        let cppImportPathPrefix = cppConfig?[\"import_path_prefix\"]?.string\n\n        let ignoredFiles = try config[\"ignored_files\"]?.array().compactMap { try $0.string?.resolvingVariables(environment) } ?? []\n\n        let directoriesToKeepRegexes = try config[\"directories_to_keep_regexes\"]?.array().compactMap { try $0.string?.resolvingVariables(environment) } ?? []\n\n        let moduleUploadBaseURL = config[\"module_upload_base_url\"]?.string.flatMap { URL(string: $0) }\n\n        let diagnosticsDir = configDirectoryUrl.resolving(path: (config[\"diagnostics_dir\"]?.string ?? \"./diagnostics\"), isDirectory: true)\n\n        if let path = args.directCompanionPath {\n            logger.info(\"Using direct companion toolbox: \\(path)\")\n        }\n        let compilerCompanionBinaryURL = try config[\"compiler_companion_binary\"]?.string\n            .map { try $0.resolvingVariables(environment) }\n            .flatMap { configDirectoryUrl.resolving(path: $0, isDirectory: false)}\n\n        var compilerToolboxURL: URL?\n        if let path = args.directCompilerToolboxPath {\n            logger.info(\"Using direct compiler toolbox: \\(path)\")\n            compilerToolboxURL = currentDirectoryUrl.resolving(path: path, isDirectory: false)\n        } else {\n            compilerToolboxURL = try getOSSpecificValue(config: config, key: \"compiler_toolbox_path\")?.string\n                .map { try $0.resolvingVariables(environment) }\n                .flatMap { configDirectoryUrl.resolving(path: $0, isDirectory: false) }\n        }\n\n        guard let compilerToolboxURL = compilerToolboxURL else {\n            throw CompilerError(\"compiler_toolbox_path not configured in the Valdi project config file\")\n        }\n\n        var pngquantURL: URL?\n        if let path = args.directPngquantPath {\n            logger.info(\"Using direct pngquant: \\(path)\")\n            pngquantURL = currentDirectoryUrl.resolving(path: path)\n        } else {\n            pngquantURL = try getOSSpecificValue(config: config, key: \"pngquant_bin_path\")?.string\n                .map { try $0.resolvingVariables(environment) }\n                .flatMap { configDirectoryUrl.resolving(path: $0, isDirectory: false) }\n        }\n\n        var minifyConfigURL:URL?\n        if let path = args.directMinifyConfigPath {\n            logger.info(\"Using direct minify config: \\(path)\")\n            minifyConfigURL = currentDirectoryUrl.resolving(path: path)\n        } else {\n            minifyConfigURL = try config[\"minify_config_path\"]?.string\n                .map { try $0.resolvingVariables(environment) }\n                .flatMap { configDirectoryUrl.resolving(path: $0, isDirectory: false) }\n        }\n\n        var clientSqlURL: URL?\n        if let path = args.directClientSqlPath {\n            logger.info(\"Using direct clientsql: \\(path)\")\n            clientSqlURL = currentDirectoryUrl.resolving(path: path)\n        } else {\n            clientSqlURL = try config[\"clientsql_binary_path\"]?.string\n                .map { try $0.resolvingVariables(environment) }\n                .flatMap { configDirectoryUrl.resolving(path: $0, isDirectory: false) }\n        }\n        \n        let sqlExportPathTemplate = config[\"sql_export_path_template\"]?.string\n        \n        let hotReloadingEnabled = args.monitor\n\n        let buildDirectoryURL: URL\n        if let buildDir = args.buildDir {\n            buildDirectoryURL = currentDirectoryUrl.resolving(path: try buildDir.resolvingVariables(environment))\n        } else {\n            let buildRootURL = configDirectoryUrl.appendingPathComponent(\".valdi_build\", isDirectory: true)\n            buildDirectoryURL = buildRootURL.appendingPathComponent(hotReloadingEnabled ? \"hotreload\" : \"compile\", isDirectory: true)\n        }\n\n        let generatedTsDirectoryURL = buildDirectoryURL.appendingPathComponent(\"generated_ts\", isDirectory: true)\n\n        let nodeModulesDirectoryURL: URL? = try config[\"node_modules_dir\"]?.string\n            .map { try $0.resolvingVariables(environment) }\n            .flatMap { configDirectoryUrl.resolving(path: $0, isDirectory: true)}\n\n        let openSourceDirectoryURL: URL? = try config[\"open_source_dir\"]?.string\n            .map { try $0.resolvingVariables(environment) }\n            .flatMap { configDirectoryUrl.resolving(path: $0, isDirectory: true)}\n\n        let nodeModulesTarget = config[\"node_modules_target\"]?.string\n        let nodeModulesWorkspace = config[\"node_modules_workspace\"]?.string\n        let externalModulesTarget = config[\"external_modules_target\"]?.string\n        let externalModulesWorkspace = config[\"external_modules_workspace\"]?.string\n\n        var projectConfig = ValdiProjectConfig(configDirectoryUrl: configDirectoryUrl,\n                                                  projectName: projectName,\n                                                  baseDir: baseDirUrl,\n                                                  webEnabled: args.web,\n                                                  iosOutput: iosOutputConfig,\n                                                  androidOutput: androidOutputConfig,\n                                                  webOutput:\n                                                    webOutputConfig,\n                                                  cppOutput: cppOutputConfig,\n                                                  iosBuildFileConfig: iosBuildFileConfig,\n                                                  androidBuildFileConfig: androidBuildFileConfig,\n                                                  webBuildFileConfig: webBuildFileConfig,\n                                                  codeCoverageResultConfig: codeCoverageResultConfig,\n                                                  iosDefaultModuleNamePrefix: iosDefaultModuleNamePrefix,\n                                                  iosDefaultLanguage: iosDefaultLanguage,\n                                                  ignoredFiles: try ignoredFiles.map { try NSRegularExpression(pattern: $0, options: [])},\n                                                  directoriesToKeepRegexes: try directoriesToKeepRegexes.map { try NSRegularExpression(pattern: $0, options: []) },\n                                                  moduleUploadBaseURL: moduleUploadBaseURL,\n                                                  diagnosticsDir: diagnosticsDir,\n                                                  compilerCompanionBinaryURL: compilerCompanionBinaryURL,\n                                                  shouldDebugCompilerCompanion: false,\n                                                  shouldEmitDiagnostics: false,\n                                                  shouldSkipRemoveOrphanFiles: false,\n                                                  compilerToolboxURL: compilerToolboxURL,\n                                                  minifyConfigURL: minifyConfigURL,\n                                                  pngquantURL: pngquantURL,\n                                                  clientSqlURL: clientSqlURL,\n                                                  sqlExportPathTemplate: sqlExportPathTemplate,\n                                                  androidDefaultClassPath: androidDefaultClassPath,\n                                                  cppDefaultClassPrefix: cppDefaultClassPrefix,\n                                                  cppImportPathPrefix: cppImportPathPrefix,\n                                                  preparedUploadArtifactOutput: nil,\n                                                  buildDirectoryURL: buildDirectoryURL,\n                                                  generatedTsDirectoryURL: generatedTsDirectoryURL,\n                                                  androidJsBytecodeFormat: androidJsBytecodeFormat,\n                                                  nodeModulesDir: nodeModulesDirectoryURL,\n                                                  openSourceDir: openSourceDirectoryURL,\n                                                  nodeModulesTarget: nodeModulesTarget,\n                                                  nodeModulesWorkspace: nodeModulesWorkspace,\n                                                  externalModulesTarget: externalModulesTarget,\n                                                  externalModulesWorkspace: externalModulesWorkspace)\n\n        projectConfig.shouldEmitDiagnostics = args.emitDiagnostics\n        projectConfig.shouldDebugCompilerCompanion = args.debugCompanion\n        projectConfig.shouldSkipRemoveOrphanFiles = args.skipRemoveOrphanFiles\n        if let preparedUploadArtifactOutput = args.preparedUploadArtifactOutput {\n            projectConfig.preparedUploadArtifactOutput = currentDirectoryUrl.resolving(path: preparedUploadArtifactOutput)\n        }\n\n        return projectConfig\n    }\n\n    func resolve(url: URL, outURL: URL) -> URL {\n        let relativePath = baseDir.relativePath(to: url)\n        return outURL.appendingPathComponent(relativePath)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Config/ValdiUserConfig.swift",
    "content": "//\n//  ValdiUserConfig.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 2/18/19.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport Yams\n\nstruct ValdiUserConfig {\n    var usernames: [String]\n    var deviceIds: [String]\n    var ipAddresses: [String]\n    var logsOutputDir: URL?\n    var deviceStorageDir: URL?\n\n    static func from(configUrl: URL, args: ValdiCompilerArguments) throws -> ValdiUserConfig {\n        let configContent = try String(contentsOf: configUrl)\n        guard let config = try Yams.compose(yaml: configContent) else {\n            throw CompilerError(\"Could not parse user config at: \\(configUrl)\")\n        }\n\n        var usernames = config[\"usernames\"]?.array().compactMap { $0.string } ?? []\n        var deviceIds = config[\"device_ids\"]?.array().compactMap { $0.string } ?? []\n        var ipAddresses = config[\"ip_addresses\"]?.array().compactMap { $0.string } ?? []\n        let logsOutputDir = config[\"logs_output_dir\"]?.string.map { configUrl.deletingLastPathComponent().resolving(path: $0, isDirectory: true) }\n        let deviceStorageDir = config[\"device_storage_dir\"]?.string.map { configUrl.deletingLastPathComponent().resolving(path: $0, isDirectory: true) }\n\n        // Temporary compatibility with usernames/deviceIds provided by --username --device-id\n        usernames.append(contentsOf: args.username)\n        deviceIds.append(contentsOf: args.deviceId)\n        ipAddresses.append(contentsOf: args.ip)\n\n        return ValdiUserConfig(usernames: usernames, deviceIds: deviceIds, ipAddresses: ipAddresses, logsOutputDir: logsOutputDir, deviceStorageDir: deviceStorageDir)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Constants.swift",
    "content": "//\n//  Constants.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n//\n\nimport Foundation\n\nlet ValdiVersion: Int32 = 3\n\nstruct Ports {\n    static let reloaderServiceDiscovery = 13253\n    static let reloaderStandalone: Int = 13591\n    static let reloaderOverUSB: Int = 13592\n    static let valdiDebugger: Int = 13594\n    static let hermesDebugger: Int = 13595\n}\n\nstruct FileExtensions {\n\n    static let valdiCss = \"valdicss\"\n    static let css = \"css\"\n    static let javascript = \"js\"\n    static let kotlin = \"kt\"\n    static let sass = \"scss\"\n    static let svg = \"svg\"\n    static let typescript = \"ts\"\n    static let typescriptXml = \"tsx\"\n    static let typescriptDeclaration = \"d.ts\"\n    static let json = \"json\"\n    static let bin = \"bin\"\n    static let vue = \"vue\"\n    static let zip = \"zip\"\n    static let map = \"map\"\n    static let protoDecl = \"protodecl\"\n    static let sql = [\"sq\", \"sqm\"]\n    static let valdiModule = \"valdimodule\"\n    static let sourceMapJson = \"map.json\"\n    static let assetCatalog = \"assetcatalog\"\n    static let assetPackage = \"assetpackage\"\n    static let downloadableArtifacts = \"downloadableArtifacts\"\n    static let objc = [\"h\", \"m\", \"mm\"]\n    static let swift = \"swift\"\n    static let exportedImages = [\"png\", \"webp\", svg]\n    static let images = FileExtensions.exportedImages + [\"jpg\", \"jpeg\"]\n    static let legacyStyles = [FileExtensions.css, FileExtensions.sass]\n    static let legacyModuleStyles = [FileExtensions.css, FileExtensions.sass].map { \".module.\\($0)\" }\n    static let fonts = [\"ttf\"]\n\n    static let typescriptFileExtensionsDotted = [FileExtensions.typescriptDeclaration, FileExtensions.typescript, FileExtensions.typescriptXml].map { \".\\($0)\" }\n\n}\n\nstruct Files {\n    static let classMapping = \"class-mapping.xml\"\n    static let compilationMetadata = \"compilation-metadata.json\"\n    static let downloadManifest = \"download_manifest\"\n    static let hash = \"hash\"\n    static let keepXML = \"valdi_keep.xml\"\n    static let stringsJSONPrefix = \"strings-\"\n    static let stringsJSONSuffix = \".json\"\n    static let stringsJSON = \"\\(stringsJSONPrefix)en\\(stringsJSONSuffix)\"\n    static let ids = \"ids.yaml\"\n    static let moduleYaml = \"module.yaml\"\n    static let buildFile = \"BUILD.bazel\"\n    static let sqlTypesYaml = \"sql_types.yaml\"\n    static let sqlManifestYaml = \"sql_manifest.yaml\"\n    static let sqlExportDir = \"sqldelight\"\n}\n\nstruct Magic {\n    static let valdiMagic: Data = {\n        var packetData = Data()\n        packetData.append(0x33)\n        packetData.append(0xC6)\n        packetData.append(0x00)\n        packetData.append(0x01)\n        return packetData\n    }()\n}\n\nstruct DeterministicDate {\n    // a fixed date for deterministic builds: January 1, 2020 00:00:00 UTC\n    static let fixedDate = Date(timeIntervalSince1970: 1577836800)\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Debugger/AndroidDebuggingTarget.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Saniul Ahmed on 19/06/2020.\n//\n\nimport Foundation\n\nstruct AndroidDebuggingTarget: Codable {\n    let deviceId: String\n    let target: String // host:port\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Files/ValdiFilesFinder.swift",
    "content": "//\n//  CompserFilesFinder.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprotocol ValdiFilesFinderDelegate: AnyObject {\n\n    func valdiFilesFinder(_ valdiFilesFinder: ValdiFilesFinder, filesDidChange files: [URL])\n\n}\n\nclass ValdiFilesFinder {\n\n    weak var delegate: ValdiFilesFinderDelegate?\n\n    private let queue = DispatchQueue(label: \"com.snap.valdi.filesfinder\")\n    private var foundFileURLs: Set<URL> = []\n    private var watchmanClient: WatchmanClient?\n\n    private let urls: [URL]\n\n    private var monitoringObserver: Cancelable?\n\n    init(urls: [URL]) {\n        self.urls = urls\n    }\n\n    convenience init(url: URL) {\n        self.init(urls: [url])\n    }\n\n    func startMonitoring(logger: ILogger) throws {\n        guard watchmanClient == nil else { return }\n\n        let watchmanClient = try WatchmanClient(logger: logger)\n        self.watchmanClient = watchmanClient\n\n        let watchmanRoot = URL.commonFileURL(in: self.urls)\n\n        let watchedPaths: [String] = self.urls.map { RelativePath(from: watchmanRoot, to: $0).description }\n\n        monitoringObserver = watchmanClient.subscribe(projectPath: watchmanRoot.path, paths: watchedPaths) { [weak self] changes in\n            self?.queue.async {\n                guard let strongSelf = self else { return }\n                strongSelf.process(notifications: changes)\n            }\n        }\n    }\n\n    func stopMonitoring() {\n        monitoringObserver?.cancel()\n        monitoringObserver = nil\n        watchmanClient = nil\n    }\n\n    private func process(notifications: [WatchmanFileNotification]) {\n        var updatedFileURLs = [URL]()\n        for notification in notifications {\n            let fileURL = notification.url\n\n            switch notification.kind {\n            case .removed:\n                self.foundFileURLs.remove(fileURL)\n            case .created:\n                fallthrough\n            case .changed:\n                if shouldUseFile(at: fileURL) {\n                    self.foundFileURLs.insert(fileURL)\n                    updatedFileURLs.append(fileURL)\n                }\n            }\n        }\n\n        if !updatedFileURLs.isEmpty {\n            delegate?.valdiFilesFinder(self, filesDidChange: updatedFileURLs)\n        }\n    }\n\n    func allFiles() throws -> [URL] {\n        // Dedupe since it's possible for a file to be counted twice if it meets multiple queries\n        var files = Set<URL>()\n        try forEachFile { (file) in\n            files.insert(file)\n        }\n        return Array(files)\n    }\n\n    private func forEachFile(_ closure: (URL) -> Void) throws {\n        for url in urls {\n            try forEachFile(url: url, closure: closure)\n        }\n    }\n\n    private func forEachFile(url: URL, closure: (URL) -> Void) throws {\n        guard let enumerator = FileManager.default.enumerator(at: url, includingPropertiesForKeys: nil, options: []) else {\n            throw CompilerError(\"Failed to get enumerator\")\n        }\n\n        while let url = (enumerator.nextObject() as? URL)?.standardizedFileURL {\n            let realUrl: URL\n            do {\n                realUrl = try url.resolvingSymlink()\n            } catch SymlinkErrors.resolvedSymlinkDoesNotExist {\n                continue\n            }\n\n            if realUrl.hasDirectoryPath {\n                if realUrl != url {\n                    try forEachFile(url: realUrl) { (innerUrl) in\n                        let relativePath = realUrl.relativePath(to: innerUrl)\n                        let relativeUrl = url.appendingPathComponent(relativePath)\n\n                        closure(relativeUrl)\n                    }\n                }\n                continue\n            }\n\n            closure(url)\n        }\n    }\n\n    private func shouldUseFile(at url: URL) -> Bool {\n        var isDirectory: ObjCBool = false\n        if !FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory) {\n            return false\n        }\n        if isDirectory.boolValue {\n            // We only care about the files, not the directories\n            return false\n        }\n\n        return true\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/CodeWriter.swift",
    "content": "//\n//  CodeWriter.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprotocol CodeWriterContent {\n\n    var content: String { get }\n\n}\n\nextension String: CodeWriterContent {\n\n    var content: String { return self }\n\n}\n\nclass TemplateContext {\n    fileprivate var replacements = [String: CodeWriterContent]()\n\n    func set(arg: String, value: CodeWriterContent) {\n        self.replacements[arg] = value\n    }\n\n    subscript(arg: String) -> CodeWriterContent? {\n        get {\n            return replacements[arg]\n        }\n        set(newValue) {\n            replacements[arg] = newValue\n        }\n    }\n}\n\nclass TemplateContent: CodeWriterContent {\n\n    let context: TemplateContext\n    let template: String\n\n    init(template: String) {\n        self.context = TemplateContext()\n        self.template = template\n    }\n\n    var content: String {\n        var out = template\n\n        for replacement in context.replacements {\n            let replacementContent = replacement.value.content\n\n            let key = \"$\\(replacement.key)\"\n            out = out.replacingOccurrences(of: key, with: replacementContent)\n        }\n        return out\n    }\n}\n\nclass JoinedContent: CodeWriterContent {\n\n    private var items: [CodeWriterContent]\n    private let separator: String\n\n    init(separator: String) {\n        self.items = []\n        self.separator = separator\n    }\n\n    init(items: [CodeWriterContent], separator: String) {\n        self.items = items\n        self.separator = separator\n    }\n\n    func append(content: CodeWriterContent) {\n        self.items.append(content)\n    }\n\n    var content: String {\n        return self.items.map { $0.content }.joined(separator: separator)\n    }\n}\n\nclass CodeWriter: CodeWriterContent {\n\n    var content: String {\n        var output = (headers + body).map { $0.content }.joined()\n        if !output.isEmpty {\n            output += nonEmptyTerminator\n        }\n\n        return output\n    }\n\n    /**\n     A terminator string to add if the content was not empty\n     */\n    var nonEmptyTerminator: String = \"\"\n\n    private var headers = [CodeWriterContent]()\n    private var body = [CodeWriterContent]()\n\n    func appendHeader(_ str: CodeWriterContent) {\n        headers.append(str)\n    }\n\n    func prependHeader(_ str: CodeWriterContent) {\n        headers.insert(str, at: 0)\n    }\n\n    func prependBody(_ str: CodeWriterContent) {\n        body.insert(str, at: 0)\n    }\n\n    func appendBody(_ str: CodeWriterContent) {\n        body.append(str)\n    }\n\n    func data() throws -> Data {\n        let content = self.content\n        guard let data = content.data(using: .utf8) else {\n            throw CompilerError(\"Failed to make data out of string\")\n        }\n        return data\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Cpp/CppCodeGenerator.swift",
    "content": "//\n//  CppCodeGenerator.swift\n//  \n//\n//  Created by Simon Corsin on 4/11/23.\n//\n\nimport Foundation\n\nstruct CppMethodParameter {\n    let name: String\n    let typeNameResolver: CPPTypeNameResolver\n}\n\nstruct CppMethod {\n    let returnTypeNameResolver: CPPTypeNameResolver\n    let parameters: [CppMethodParameter]\n}\n\nstruct CPPTypeNameResolver: CustomStringConvertible {\n    let resolve: (CPPNamespace) -> String\n\n    init(_ resolve: @escaping (CPPNamespace) -> String) {\n        self.resolve = resolve\n    }\n\n    var description: String {\n        return resolve(CPPNamespace.rootNamespace)\n    }\n\n    static func with(templateType: CPPTypeNameResolver, typeArguments: [CPPTypeNameResolver]) -> CPPTypeNameResolver {\n        return CPPTypeNameResolver { namespace in\n            let typeName = templateType.resolve(namespace)\n            let typeArgumentsStr = typeArguments.map { $0.resolve(namespace) }.joined(separator: \", \")\n            return \"\\(typeName)<\\(typeArgumentsStr)>\"\n        }\n    }\n\n    static func with(templateType: CPPTypeNameResolver, typeArgument: CPPTypeNameResolver) -> CPPTypeNameResolver {\n        return CPPTypeNameResolver { namespace in\n            let typeName = templateType.resolve(namespace)\n            let typeArgumentStr = typeArgument.resolve(namespace)\n            return \"\\(typeName)<\\(typeArgumentStr)>\"\n        }\n    }\n\n    static func with(typeName: String) -> CPPTypeNameResolver {\n        return CPPTypeNameResolver { _ in typeName }\n    }\n\n    static func with(typeDeclaration: CPPTypeDeclaration) -> CPPTypeNameResolver {\n        return CPPTypeNameResolver { namespace in typeDeclaration.resolveTypeName(inNamespace: namespace) }\n    }\n\n    struct Specifiers: OptionSet {\n        let rawValue: Int\n\n        static let const = Specifiers(rawValue: 1 << 0)\n        static let ref = Specifiers(rawValue: 1 << 1)\n        static let rValueRef = Specifiers(rawValue: 1 << 2)\n        static let ptr = Specifiers(rawValue: 1 << 3)\n\n        static let constRef: Specifiers = [.const, .ref]\n    }\n\n    static func with(specifiers: Specifiers, _ typeNameResolver: CPPTypeNameResolver) -> CPPTypeNameResolver {\n        return CPPTypeNameResolver { namespace in\n            var output = \"\"\n            if specifiers.contains(.const) {\n                output += \"const \"\n            }\n            output += typeNameResolver.resolve(namespace)\n\n            if specifiers.contains(.ref) {\n                output += \" &\"\n            } else if specifiers.contains(.ptr) {\n                output += \" *\"\n            } else if specifiers.contains(.rValueRef) {\n                output += \" &&\"\n            }\n\n            return output\n        }\n    }\n}\n\nstruct CppTypeParser {\n    let typeNameResolver: CPPTypeNameResolver\n    let method: CppMethod?\n    let isMovable: Bool\n    let isIntrinsicallyNullable: Bool\n    let defaultInitializationString: String?\n\n    init(typeNameResolver: CPPTypeNameResolver,\n         method: CppMethod?,\n         isMovable: Bool,\n         isIntrinsicallyNullable: Bool,\n         defaultInitializationString: String?) {\n        self.typeNameResolver = typeNameResolver\n        self.method = method\n        self.isMovable = isMovable\n        self.isIntrinsicallyNullable = isIntrinsicallyNullable\n        self.defaultInitializationString = defaultInitializationString\n    }\n}\n\nfinal class CppIncludeSection: CodeWriterContent {\n\n    private var includedFiles = Set<String>()\n\n    @discardableResult func addInclude(path: String) -> Bool {\n        return includedFiles.insert(\"\\\"\\(path)\\\"\").inserted\n    }\n\n    @discardableResult func addSystemInclude(path: String) -> Bool {\n        return includedFiles.insert(\"<\\(path)>\").inserted\n    }\n\n    var content: String {\n        return includedFiles.sorted().map { \"#include \\($0)\\n\" }.joined()\n    }\n}\n\nfinal class CppForwardDeclarationSection: CodeWriterContent {\n    private var includedTypes = Set<CPPTypeReference>()\n\n    func addForwardDeclaration(typeReference: CPPTypeReference) {\n        includedTypes.insert(typeReference)\n    }\n\n    var content: String {\n        if includedTypes.isEmpty {\n            return \"\"\n        }\n\n        let typeDeclarationsByNamespace = includedTypes.groupBy { $0.declaration.namespace }\n        let namespaces = typeDeclarationsByNamespace.keys.sorted()\n\n        let body = CodeWriter()\n\n        for namespace in namespaces {\n            body.appendBody(\"namespace \\(namespace.description) {\\n\")\n\n            let types = typeDeclarationsByNamespace[namespace]!.map {\n                if let typeArguments = $0.typeArguments {\n                    let typeArgumentsStr = typeArguments.map { \"typename \\($0)\" }.joined(separator: \", \")\n                    let prefix = \"template<\\(typeArgumentsStr)>\\n\"\n                    return \"\\(prefix)\\($0.declaration.symbolType.declarationString) \\($0.declaration.name);\\n\"\n                } else {\n                    return \"\\($0.declaration.symbolType.declarationString) \\($0.declaration.name);\\n\"\n                }\n            }.sorted()\n\n            for t in types {\n                body.appendBody(t)\n            }\n\n            body.appendBody(\"}\\n\\n\")\n        }\n\n        return body.content\n    }\n}\n\nclass CppCodeWriter: CodeWriter {\n\n}\n\nstruct CPPFunctionArgument {\n    let typeResolver: CPPTypeNameResolver\n    let name: String\n\n    func resolve(namespace: CPPNamespace) -> String {\n        var output = typeResolver.resolve(namespace)\n\n        if output.last == \"*\" || output.last == \"&\" {\n            output += name\n        } else {\n            output += \" \"\n            output += name\n        }\n\n        return output\n    }\n}\n\nenum CppMethodSpecifiers {\n    case none\n    case const\n    case static_\n}\n\nstruct CppClassWriter {\n    let namespace: CPPNamespace\n    let className: String\n    let header: CppCodeWriter\n    let impl: CppCodeWriter\n    let inlineImplementation: Bool\n\n    private let headerNamespace: CPPNamespace\n\n    init(namespace: CPPNamespace, className: String, header: CppCodeWriter, impl: CppCodeWriter, inlineImplementation: Bool) {\n        self.namespace = namespace\n        self.className = className\n        self.header = header\n        self.impl = impl\n        self.inlineImplementation = inlineImplementation\n        self.headerNamespace = namespace.appending(component: className)\n    }\n\n    private func resolveMethodReturnType(namespace: CPPNamespace, returnTypeResolver: CPPTypeNameResolver) -> String {\n        let returnType = returnTypeResolver.resolve(namespace)\n        if returnType.last == \"*\" || returnType.last == \"&\" {\n            return returnType\n        } else {\n            return \"\\(returnType) \"\n        }\n    }\n\n    private func resolveArguments(namespace: CPPNamespace, arguments: [CPPFunctionArgument]) -> String {\n        return arguments.map { $0.resolve(namespace: namespace) }.joined(separator: \", \")\n    }\n\n    func writeMethod(name: String, arguments: [CPPFunctionArgument], returnType: CPPTypeNameResolver, specifiers: CppMethodSpecifiers, writeBody: (CodeWriter) -> Void) {\n        if specifiers == .static_ {\n            header.appendBody(\"static \")\n        }\n\n        if inlineImplementation {\n            let methodPrefix = resolveMethodReturnType(namespace: headerNamespace, returnTypeResolver: returnType)\n            header.appendBody(\"\\(methodPrefix)\\(name)(\\(self.resolveArguments(namespace: headerNamespace, arguments: arguments)))\")\n            if specifiers == .const {\n                header.appendBody(\" const\")\n            }\n            writeMethodImpl(writer: header, writeBody: writeBody)\n        } else {\n            let methodPrefixHeader = resolveMethodReturnType(namespace: headerNamespace, returnTypeResolver: returnType)\n            let methodPrefixImpl = resolveMethodReturnType(namespace: namespace, returnTypeResolver: returnType)\n            header.appendBody(\"\\(methodPrefixHeader)\\(name)(\\(self.resolveArguments(namespace: headerNamespace, arguments: arguments)))\")\n            if specifiers == .const {\n                header.appendBody(\" const\")\n            }\n            header.appendBody(\";\\n\\n\")\n            impl.appendBody(\"\\(methodPrefixImpl)\\(className)::\\(name)(\\(self.resolveArguments(namespace: namespace, arguments: arguments)))\")\n            if specifiers == .const {\n                impl.appendBody(\" const\")\n            }\n            writeMethodImpl(writer: impl, writeBody: writeBody)\n        }\n    }\n\n    func writeConstructor(arguments: [CPPFunctionArgument], memberInitializerList: String, writeBody: (CodeWriter) -> Void) {\n        if inlineImplementation {\n            header.appendBody(\"\\(className)(\\(self.resolveArguments(namespace: headerNamespace, arguments: arguments)))\")\n            if !memberInitializerList.isEmpty {\n                header.appendBody(\": \\(memberInitializerList)\")\n            }\n            writeMethodImpl(writer: header, writeBody: writeBody)\n        } else {\n            header.appendBody(\"\\(className)(\\(self.resolveArguments(namespace: headerNamespace, arguments: arguments)));\\n\\n\")\n            impl.appendBody(\"\\(className)::\\(className)(\\(self.resolveArguments(namespace: namespace, arguments: arguments)))\")\n            if !memberInitializerList.isEmpty {\n                impl.appendBody(\": \\(memberInitializerList)\")\n            }\n            writeMethodImpl(writer: impl, writeBody: writeBody)\n        }\n    }\n\n    private func writeMethodImpl(writer: CodeWriter, writeBody: (CodeWriter) -> Void) {\n        writer.appendBody(\" {\\n\")\n        writeBody(writer)\n        writer.appendBody(\"}\\n\\n\")\n    }\n}\n\nfinal class CppFileGenerator: CodeWriterContent {\n\n    static let valdiNamespace = CPPNamespace(components: [\"Valdi\"])\n\n    var content: String {\n        return writer.content\n    }\n\n    let includeSection = CppIncludeSection()\n    let forwardDeclarations = CppForwardDeclarationSection()\n\n    let body = CppCodeWriter()\n\n    private let writer = CodeWriter()\n\n    init(namespace: CPPNamespace, isHeader: Bool) {\n        if isHeader {\n            writer.appendHeader(\"#pragma once\\n\")\n        }\n        writer.appendHeader(includeSection)\n        writer.appendHeader(\"\\n\")\n\n        if namespace.components.isEmpty {\n            writer.appendBody(forwardDeclarations)\n            writer.appendBody(body)\n        } else {\n            writer.appendBody(forwardDeclarations)\n            writer.appendBody(\"namespace \\(namespace.description) {\\n\\n\")\n            writer.appendBody(body)\n            writer.appendBody(\"\\n}\")\n        }\n    }\n\n    static func getValdiTypeDeclaration(typeName: String) -> CPPTypeDeclaration {\n        return CPPTypeDeclaration(namespace: CppFileGenerator.valdiNamespace, name: typeName, symbolType: .class)\n    }\n}\n\nstruct CppTypeAlias {\n    let statement: CPPTypeNameResolver\n    let isOnMethod: Bool\n}\n\nprotocol CppCodeGeneratorNamespaceResolver: AnyObject {\n    func getNamespace(forTypeAlias typeAlias: CppTypeAlias) -> CPPNamespace\n}\n\n\nfinal class CppCodeGeneratorSingleNamespaceResolver: CppCodeGeneratorNamespaceResolver {\n    private let classNamespace: CPPNamespace\n\n    init(classNamespace: CPPNamespace) {\n        self.classNamespace = classNamespace\n    }\n\n    func getNamespace(forTypeAlias typeAlias: CppTypeAlias) -> CPPNamespace {\n        return classNamespace\n    }\n}\n\nfinal class CppCodeGenerator {\n\n    let header: CppFileGenerator\n    let impl: CppFileGenerator\n\n    private var referencedTypesIndex = Set<CPPTypeReference>()\n    private(set) var referencedTypes: [CPPTypeReference] = []\n    private(set) var referenceTypeKeys: [String] = []\n    private(set) var typealiases: [CppTypeAlias] = []\n    private(set) var dependenciesInSameHeaderFile: [String] = []\n\n    private let selfIncludePath: String\n    private let namespaceResolver: CppCodeGeneratorNamespaceResolver\n\n    init(namespace: CPPNamespace,\n         selfIncludePath: String,\n         namespaceResolver: CppCodeGeneratorNamespaceResolver) {\n        self.header = CppFileGenerator(namespace: namespace, isHeader: true)\n        self.impl = CppFileGenerator(namespace: namespace, isHeader: false)\n        self.selfIncludePath = selfIncludePath\n        self.namespaceResolver = namespaceResolver\n    }\n\n    static func getValdiTypeName(typeName: String) -> CPPTypeNameResolver {\n        let typeDeclaration = CppFileGenerator.getValdiTypeDeclaration(typeName: typeName)\n\n        return CPPTypeNameResolver.with(typeDeclaration: typeDeclaration)\n    }\n\n    static func makeRefType(typeName: CPPTypeNameResolver) -> CPPTypeNameResolver {\n        let refTypeName = getValdiTypeName(typeName: \"Ref\")\n\n        return CPPTypeNameResolver.with(templateType: refTypeName, typeArgument: typeName)\n    }\n\n    private static func resolveGetRegisteredClassExpression(namespace: CPPNamespace, typeReference: CPPTypeReference) -> String {\n        let resolvedTypeName = typeReference.resolveTypeName(inNamespace: namespace)\n        switch typeReference.declaration.symbolType {\n        case .class:\n            return \"\\(resolvedTypeName)::getRegisteredClass()\"\n        case .enum:\n            return \"::\\(typeReference.declaration.namespace.description)::getRegisteredEnumClass(static_cast<const \\(resolvedTypeName) *>(nullptr))\"\n        }\n    }\n\n    func getTypeReferencesVecExpression(inNamespace namespace: CPPNamespace) -> String {\n        let typeReferencesVecString = referencedTypes.map { CppCodeGenerator.resolveGetRegisteredClassExpression(namespace: namespace, typeReference: $0) }.joined(separator: \", \")\n\n        return \"\"\"\n        []() -> Valdi::TypeReferencesVec {\n            return {\\(typeReferencesVecString)};\n         }\n        \"\"\"\n    }\n\n    private func getPrimitiveTypeParser(primitiveType: String,\n                                        isMovable: Bool,\n                                        isIntrinsicallyNullable: Bool,\n                                        defaultInitializationString: String?) -> CppTypeParser {\n        return CppTypeParser(\n            typeNameResolver: CPPTypeNameResolver.with(typeName: primitiveType),\n            method: nil,\n            isMovable: isMovable,\n            isIntrinsicallyNullable: isIntrinsicallyNullable,\n            defaultInitializationString: defaultInitializationString\n        )\n    }\n\n    private static func elementTypeIsObject(_ elementType: ValdiModelPropertyType) -> Bool {\n        switch elementType {\n        case .object:\n            return true\n        case .genericObject:\n            return true\n        default:\n            return false\n        }\n    }\n\n    private func toOptionalTypeParser(elementType: ValdiModelPropertyType, typeParser: CppTypeParser) -> CppTypeParser {\n        if typeParser.isIntrinsicallyNullable {\n            return typeParser\n        }\n\n        if CppCodeGenerator.elementTypeIsObject(elementType) {\n            // For optional of object references, we turn them into Ref<> so that we can support\n            // circular type references.\n            let refType = CppCodeGenerator.makeRefType(typeName: typeParser.typeNameResolver)\n            return CppTypeParser(\n                typeNameResolver: refType,\n                method: typeParser.method,\n                isMovable: true,\n                isIntrinsicallyNullable: true,\n                defaultInitializationString: nil)\n        } else {\n            let parentTypeNameResolver = typeParser.typeNameResolver\n            return CppTypeParser(\n                typeNameResolver: CPPTypeNameResolver.with(templateType: .with(typeName: \"std::optional\"), typeArgument: parentTypeNameResolver),\n                method: typeParser.method,\n                isMovable: typeParser.isMovable,\n                isIntrinsicallyNullable: true,\n                defaultInitializationString: nil)\n        }\n    }\n\n    private func getArrayTypeParser(elementType: ValdiModelPropertyType, namePaths: [String], nameAllocator: PropertyNameAllocator) throws -> CppTypeParser {\n        let elementTypeParser = try getTypeParser(type: elementType, namePaths: namePaths + [\"Element\"], nameAllocator: nameAllocator)\n\n        return CppTypeParser(typeNameResolver: CPPTypeNameResolver.with(templateType: .with(typeName: \"std::vector\"), typeArgument: elementTypeParser.typeNameResolver),\n                             method: nil,\n                             isMovable: true,\n                             isIntrinsicallyNullable: false,\n                             defaultInitializationString: nil)\n    }\n\n    private func appendReferencedType(_ referencedType: CPPTypeReference, propertyType: ValdiModelPropertyType, includePath: String, isRefType: Bool) {\n        let fromSameIncludePath = includePath == self.selfIncludePath\n        if !fromSameIncludePath {\n            header.includeSection.addInclude(path: includePath)\n        }\n\n        if let typeArguments = referencedType.typeArguments {\n            let forwardDeclaredTypeArguments = typeArguments.enumerated().map { \"T\\($0.offset)\" }\n            header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration: referencedType.declaration, typeArguments: forwardDeclaredTypeArguments))\n        } else {\n            header.forwardDeclarations.addForwardDeclaration(typeReference: referencedType)\n        }\n\n        let inserted = referencedTypesIndex.insert(referencedType).inserted\n        if inserted {\n            if fromSameIncludePath && !isRefType {\n                // If we are depending on a file in the same header and that the type is not boxed in a Ref, then we have\n                // a hard dependency on that type and the referenced type definition needs to appear before our type when\n                // using single file codegen.\n                dependenciesInSameHeaderFile.append(\"\\(referencedType.declaration.name).hpp\")\n            }\n            referencedTypes.append(referencedType)\n            referenceTypeKeys.append(CppCodeGenerator.makeCanonicalTypeKey(type: propertyType))\n        }\n    }\n\n    private func getTypeReferenceTypeParser(referencedType: CPPType,\n                                            referencedPropertyType: ValdiModelPropertyType,\n                                            isObject: Bool,\n                                            isRefType: Bool,\n                                            nameAllocator: PropertyNameAllocator) -> CppTypeParser {\n        appendReferencedType(CPPTypeReference(declaration: referencedType.declaration, typeArguments: nil),\n                             propertyType: referencedPropertyType,\n                             includePath: referencedType.includePath,\n                             isRefType: isRefType)\n\n        return CppTypeParser(\n            typeNameResolver: isRefType ? CppCodeGenerator.makeRefType(typeName: .with(typeDeclaration: referencedType.declaration)) : .with(typeDeclaration: referencedType.declaration),\n            method: nil,\n            isMovable: isObject,\n            isIntrinsicallyNullable: isRefType,\n            defaultInitializationString: nil\n        )\n    }\n\n    private func getGenericTypeReferenceTypeParser(referencedType: CPPType,\n                                                   referencedPropertyType: ValdiModelPropertyType,\n                                                   referenceTypeIsInterface: Bool,\n                                                   typeParsers: [CppTypeParser],\n                                                   nameAllocator: PropertyNameAllocator) -> CppTypeParser {\n        let typeReference = CPPTypeReference(declaration: referencedType.declaration, typeArguments: typeParsers.map { $0.typeNameResolver.resolve(.rootNamespace) })\n        appendReferencedType(typeReference, propertyType: referencedPropertyType, includePath: referencedType.includePath, isRefType: false)\n\n        let resolveTypeArguments = typeParsers.map { $0.typeNameResolver }\n\n        let typeNameResolver = CPPTypeNameResolver.with(templateType: .with(typeDeclaration: referencedType.declaration), typeArguments: resolveTypeArguments)\n\n        return CppTypeParser(\n            typeNameResolver: referenceTypeIsInterface ? CppCodeGenerator.makeRefType(typeName: typeNameResolver) : typeNameResolver,\n            method: nil,\n            isMovable: true,\n            isIntrinsicallyNullable: referenceTypeIsInterface,\n            defaultInitializationString: nil\n        )\n    }\n\n    private func getUntypedTypeParser() -> CppTypeParser {\n        header.includeSection.addInclude(path: \"valdi_core/cpp/Utils/Value.hpp\")\n\n        return CppTypeParser(\n            typeNameResolver: CppCodeGenerator.getValdiTypeName(typeName: \"Value\"),\n            method: nil,\n            isMovable: true,\n            isIntrinsicallyNullable: true,\n            defaultInitializationString: nil\n        )\n    }\n\n    private func getPromiseTypeParser(valueTypeParser: CppTypeParser) -> CppTypeParser {\n        header.includeSection.addInclude(path: \"valdi_core/cpp/Utils/Future.hpp\")\n\n        return CppTypeParser(\n            typeNameResolver: CPPTypeNameResolver.with(templateType: CppCodeGenerator.getValdiTypeName(typeName: \"Future\"), typeArgument: valueTypeParser.typeNameResolver),\n            method: nil,\n            isMovable: true,\n            isIntrinsicallyNullable: false,\n            defaultInitializationString: nil\n        )\n    }\n\n    private func getFunctionTypeParser(parameters: [ValdiModelProperty], returnType: ValdiModelPropertyType, namePaths: [String], nameAllocator: PropertyNameAllocator) throws -> CppTypeParser {\n        header.includeSection.addInclude(path: \"valdi_core/cpp/Utils/Function.hpp\")\n\n        let returnTypeParser = try getTypeParser(type: returnType, namePaths: namePaths + [\"Return\"], nameAllocator: nameAllocator)\n\n        let parameterTypeParsers = try parameters.map { ($0.name, try getTypeParser(type: $0.type, namePaths: namePaths + [$0.name], nameAllocator: nameAllocator)) }\n\n        let parameterTypeNameResolvers = parameterTypeParsers.map { $1.typeNameResolver }\n\n        let typealiasFunctionName = nameAllocator.allocate(property: (namePaths + [\"Fn\"]).map { $0.pascalCased }.joined()).name\n\n        let functionType = CppCodeGenerator.getValdiTypeName(typeName: \"Function\")\n        let returnTypeNameResolver = returnTypeParser.typeNameResolver\n\n        let realTypeNameResolver = CPPTypeNameResolver.with(templateType: functionType, typeArgument: CPPTypeNameResolver { namespace in\n            let returnTypeName = returnTypeNameResolver.resolve(namespace)\n            let parameterTypeNames = parameterTypeNameResolvers.map { $0.resolve(namespace) }.joined(separator: \", \")\n            return \"\\(returnTypeName)(\\(parameterTypeNames))\"\n        })\n\n        var cppMethod: CppMethod?\n        if namePaths.count == 1 {\n            cppMethod = CppMethod(returnTypeNameResolver: returnTypeNameResolver, parameters: parameterTypeParsers.map { CppMethodParameter(name: $0, typeNameResolver: $1.typeNameResolver) })\n        }\n\n        let typealiasStatement = CPPTypeNameResolver { namespace in\n            return \"using \\(typealiasFunctionName) = \\(realTypeNameResolver.resolve(namespace));\\n\"\n        }\n\n        let typeAlias = CppTypeAlias(statement: typealiasStatement, isOnMethod: cppMethod != nil)\n        typealiases.append(typeAlias)\n\n        let namespace = self.namespaceResolver.getNamespace(forTypeAlias: typeAlias)\n        return CppTypeParser(typeNameResolver: .with(typeDeclaration: CPPTypeDeclaration(namespace: namespace, name: typealiasFunctionName, symbolType: .class)),\n                             method: cppMethod,\n                             isMovable: true,\n                             isIntrinsicallyNullable: false,\n                             defaultInitializationString: nil)\n    }\n\n    static func makeCanonicalTypeKey(type: ValdiModelPropertyType) -> String {\n        switch type {\n        case .string:\n            return \"string\"\n        case .double:\n            return \"double\"\n        case .bool:\n            return \"bool\"\n        case .long:\n            return \"long\"\n        case .array(elementType: let elementType):\n            return \"[\\(makeCanonicalTypeKey(type: elementType))]\"\n        case .bytes:\n            return \"bytes\"\n        case .map:\n            return \"map\"\n        case .any:\n            return \"any\"\n        case .void:\n            return \"void\"\n        case .function(parameters: let parameters, returnType: let returnType, _, _):\n            let parameterStrings = parameters.map { makeCanonicalTypeKey(type: $0.type) }.joined(separator: \", \")\n            return \"(\\(parameterStrings)): \\(makeCanonicalTypeKey(type: returnType))\"\n        case .object(let type):\n            if !type.isGenerated {\n                return \"any\"\n            }\n\n            return type.cppType?.declaration.fullTypeName ?? \"any\"\n        case .genericTypeParameter(let name):\n            return name\n        case .genericObject(let type, let typeArguments):\n            if !type.isGenerated {\n                return \"any\"\n            }\n\n            let objectType = type.cppType?.declaration.fullTypeName ?? \"any\"\n\n            let str = typeArguments.map { makeCanonicalTypeKey(type: $0) }.joined(separator: \", \")\n\n            return \"\\(objectType)<\\(str)>\"\n        case .promise(let type):\n            let element = makeCanonicalTypeKey(type: type)\n            return \"promise<\\(element)>\"\n        case .enum(let type):\n            if !type.isGenerated {\n                return \"any\"\n            }\n\n            return type.cppType?.declaration.fullTypeName ?? \"any\"\n        case .nullable(let elementType):\n            return \"\\(makeCanonicalTypeKey(type: elementType))?\"\n        }\n    }\n\n    func getTypeParser(type: ValdiModelPropertyType, namePaths: [String], nameAllocator: PropertyNameAllocator) throws -> CppTypeParser {\n        switch type {\n        case .string:\n            header.includeSection.addInclude(path: \"valdi_core/cpp/Utils/StringBox.hpp\")\n            return CppTypeParser(\n                typeNameResolver: CppCodeGenerator.getValdiTypeName(typeName: \"StringBox\"),\n                method: nil,\n                isMovable: true,\n                isIntrinsicallyNullable: false,\n                defaultInitializationString: nil\n            )\n        case .double:\n            return getPrimitiveTypeParser(primitiveType: \"double\", isMovable: false, isIntrinsicallyNullable: false, defaultInitializationString: \"0.0\")\n        case .bool:\n            return getPrimitiveTypeParser(primitiveType: \"bool\", isMovable: false, isIntrinsicallyNullable: false, defaultInitializationString: \"false\")\n        case .long:\n            return getPrimitiveTypeParser(primitiveType: \"int64_t\", isMovable: false, isIntrinsicallyNullable: false, defaultInitializationString: \"0\")\n        case .array(elementType: let elementType):\n            return try getArrayTypeParser(elementType: elementType, namePaths: namePaths, nameAllocator: nameAllocator)\n        case .bytes:\n            header.includeSection.addInclude(path: \"valdi_core/cpp/Utils/Bytes.hpp\")\n            return CppTypeParser(\n                typeNameResolver: CppCodeGenerator.getValdiTypeName(typeName: \"BytesView\"),\n                method: nil,\n                isMovable: true,\n                isIntrinsicallyNullable: false,\n                defaultInitializationString: nil\n            )\n        case .map:\n            header.includeSection.addInclude(path: \"valdi_core/cpp/Utils/ValueMap.hpp\")\n            return CppTypeParser(\n                typeNameResolver: CppCodeGenerator.makeRefType(typeName: CppCodeGenerator.getValdiTypeName(typeName: \"ValueMap\")),\n                method: nil,\n                isMovable: true,\n                isIntrinsicallyNullable: true,\n                defaultInitializationString: nil\n            )\n        case .any:\n            return getUntypedTypeParser()\n        case .void:\n            return CppTypeParser(\n                typeNameResolver: .with(typeName: \"void\"),\n                method: nil,\n                isMovable: false,\n                isIntrinsicallyNullable: false,\n                defaultInitializationString: nil\n            )\n        case .function(parameters: let parameters, returnType: let returnType, _, _):\n            return try getFunctionTypeParser(parameters: parameters, returnType: returnType, namePaths: namePaths, nameAllocator: nameAllocator)\n        case .object(let objectType):\n            if !objectType.isGenerated {\n                // No support for @NativeClass and @NativeInterface for now.\n                // We just export them as untyped\n                return getUntypedTypeParser()\n            }\n\n            guard let cppType = objectType.cppType else {\n                throw CompilerError(\"No C++ type declared for referenced type \\(objectType.tsType)\")\n            }\n\n            let isInterface = objectType.kind == .interface\n\n            return getTypeReferenceTypeParser(referencedType: cppType,\n                                              referencedPropertyType: type,\n                                              isObject: true,\n                                              isRefType: isInterface,\n                                              nameAllocator: nameAllocator)\n        case .genericTypeParameter(let name):\n            return CppTypeParser(\n                typeNameResolver: .with(typeName: name),\n                method: nil,\n                isMovable: true,\n                isIntrinsicallyNullable: false,\n                defaultInitializationString: \"{}\"\n            )\n        case .genericObject(let objectType, let typeArguments):\n            if !objectType.isGenerated {\n                // No support for @NativeClass and @NativeInterface for now.\n                // We just export them as untyped\n                return getUntypedTypeParser()\n            }\n\n            guard let cppType = objectType.cppType else {\n                throw CompilerError(\"No C++ type declared for referenced type \\(objectType.tsType)\")\n            }\n\n\n            let typeParsers = try typeArguments.map { try getTypeParser(type: $0, namePaths: namePaths, nameAllocator: nameAllocator) }\n            let isInterface = objectType.kind == .interface\n\n            return getGenericTypeReferenceTypeParser(referencedType: cppType,\n                                                     referencedPropertyType: type,\n                                                     referenceTypeIsInterface: isInterface,\n                                                     typeParsers: typeParsers,\n                                                     nameAllocator: nameAllocator)\n        case .promise(let type):\n            let innerType = try getTypeParser(type: type, namePaths: namePaths, nameAllocator: nameAllocator)\n\n            return getPromiseTypeParser(valueTypeParser: innerType)\n        case .enum(let enumType):\n            if !enumType.isGenerated {\n                // No support for @NativeClass and @NativeInterface for now.\n                // We just export them as untyped\n                return getUntypedTypeParser()\n            }\n\n            guard let cppType = enumType.cppType else {\n                throw CompilerError(\"No C++ type declared for referenced enum \\(enumType.tsType)\")\n            }\n\n            return getTypeReferenceTypeParser(referencedType: cppType,\n                                              referencedPropertyType: type,\n                                              isObject: false,\n                                              isRefType: false,\n                                              nameAllocator: nameAllocator)\n        case .nullable(let elementType):\n            // For nullable object types, we need to handle them specially because they get wrapped\n            // in Ref<> (which only requires a forward declaration), but the recursive getTypeParser\n            // call would register a hard dependency before we have a chance to wrap it.\n            switch elementType {\n            case .object(let objectType):\n                if !objectType.isGenerated {\n                    return getUntypedTypeParser()\n                }\n                guard let cppType = objectType.cppType else {\n                    throw CompilerError(\"No C++ type declared for referenced type \\(objectType.tsType)\")\n                }\n                // Pass isRefType: true since nullable objects become Ref<T> which only needs forward declaration\n                // Use elementType as referencedPropertyType to maintain consistent canonical type keys\n                return getTypeReferenceTypeParser(referencedType: cppType,\n                                                  referencedPropertyType: elementType,\n                                                  isObject: true,\n                                                  isRefType: true,\n                                                  nameAllocator: nameAllocator)\n            case .genericObject(let objectType, let typeArguments):\n                if !objectType.isGenerated {\n                    return getUntypedTypeParser()\n                }\n                guard let cppType = objectType.cppType else {\n                    throw CompilerError(\"No C++ type declared for referenced type \\(objectType.tsType)\")\n                }\n                let typeParsers = try typeArguments.map { try getTypeParser(type: $0, namePaths: namePaths, nameAllocator: nameAllocator) }\n                // Pass referenceTypeIsInterface: true since nullable generic objects become Ref<T<...>> which only needs forward declaration\n                // Use elementType as referencedPropertyType to maintain consistent canonical type keys\n                return getGenericTypeReferenceTypeParser(referencedType: cppType,\n                                                         referencedPropertyType: elementType,\n                                                         referenceTypeIsInterface: true,\n                                                         typeParsers: typeParsers,\n                                                         nameAllocator: nameAllocator)\n            default:\n                let elementTypeParser = try getTypeParser(type: elementType, namePaths: namePaths, nameAllocator: nameAllocator)\n                return toOptionalTypeParser(elementType: elementType, typeParser: elementTypeParser)\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Cpp/CppFunctionGenerator.swift",
    "content": "//\n//  CppFunctionGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/1/25.\n//\n\nfinal class CppFunctionGenerator {\n    private let cppType: CPPType\n    private let exportedFunction: ExportedFunction\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n    private let modulePath: String\n    private let bundleInfo: CompilationItem.BundleInfo\n\n    init(cppType: CPPType,\n         exportedFunction: ExportedFunction,\n         classMapping: ResolvedClassMapping,\n         sourceFileName: GeneratedSourceFilename,\n         modulePath: String,\n         bundleInfo: CompilationItem.BundleInfo) {\n        self.cppType = cppType\n        self.exportedFunction = exportedFunction\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.modulePath = modulePath\n        self.bundleInfo = bundleInfo\n    }\n\n    func write() throws -> [NativeSource] {\n        let typealiasNamespace = cppType.declaration.namespace.appending(component: \"\\(cppType.declaration.name)TypeAliases\")\n\n        let generator = CppCodeGenerator(namespace: self.cppType.declaration.namespace,\n                                         selfIncludePath: cppType.includePath,\n                                         namespaceResolver: CppCodeGeneratorSingleNamespaceResolver(classNamespace: typealiasNamespace))\n\n        generator.header.includeSection.addInclude(path: \"valdi_core/cpp/Marshalling/CppGeneratedExportedFunction.hpp\")\n        generator.header.includeSection.addInclude(path: \"valdi_core/cpp/Utils/Result.hpp\")\n        generator.impl.includeSection.addInclude(path: \"valdi_core/cpp/Marshalling/CppGeneratedExportedFunctionUtils.hpp\")\n        generator.impl.includeSection.addInclude(path: cppType.includePath)\n\n\n        generator.header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration:\n                                                                                                    CPPTypeDeclaration(namespace: CPPNamespace(components: [\"snap\", \"valdi_core\"]), name: \"JSRuntime\", symbolType: .class),\n                                                                                                   typeArguments: nil))\n        generator.header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration:\n                                                                                                    CPPTypeDeclaration(namespace: CPPNamespace(components: [\"snap\", \"valdi_core\"]), name: \"JSRuntimeNativeObjectsManager\", symbolType: .class),\n                                                                                                   typeArguments: nil))\n\n        let property = ValdiModelProperty(name: exportedFunction.functionName,\n                                          type: .function(parameters: exportedFunction.parameters, returnType: exportedFunction.returnType, isSingleCall: false, shouldCallOnWorkerThread: false),\n                                          comments: exportedFunction.comments,\n                                          omitConstructor: nil,\n                                          injectableParams: .empty)\n\n        let nameAllocator = PropertyNameAllocator.forCpp()\n\n        let returnTypeParser = try generator.getTypeParser(type: exportedFunction.returnType, namePaths: [], nameAllocator: nameAllocator)\n        let parameterTypeParsers = try exportedFunction.parameters.map { try generator.getTypeParser(type: $0.type, namePaths: [], nameAllocator: nameAllocator) }\n\n        let schemaWriter = CppSchemaWriter(typeParameters: nil, generator: generator)\n\n        try schemaWriter.appendClass(cppType.declaration.name, properties: [property])\n\n        let allTypeArguments = ([returnTypeParser] + parameterTypeParsers).map { $0.typeNameResolver.resolve(self.cppType.declaration.namespace) }.joined(separator: \", \")\n\n        var registerSchemaParameters: [String]\n        if generator.referencedTypes.isEmpty {\n            registerSchemaParameters = [\"\\\"\\(schemaWriter.str)\\\"\"]\n        } else {\n            registerSchemaParameters = [\"\\\"\\(schemaWriter.str)\\\"\", generator.getTypeReferencesVecExpression(inNamespace: self.cppType.declaration.namespace)]\n        }\n\n        if !generator.typealiases.isEmpty {\n            generator.header.body.appendBody(\"namespace \\(typealiasNamespace.components.last!) {\\n\")\n            for cppTypealias in generator.typealiases {\n                generator.header.body.appendBody(cppTypealias.statement.resolve(typealiasNamespace))\n            }\n            generator.header.body.appendBody(\"}\\n\\n\")\n        }\n\n        generator.header.body.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: exportedFunction.comments))\n\n        let className = cppType.declaration.name\n        generator.header.body.appendBody(\"\"\"\n\n            class \\(className): public Valdi::CppGeneratedExportedFunction<\\(allTypeArguments)> {\n            public:\n                using CppGeneratedExportedFunction<\\(allTypeArguments)>::CppGeneratedExportedFunction;\n            \n                /**\n                * Resolve the function from the given JS runtime. If the native objects manager is provided,\n                * emitted native objects will be associated with the given manager, otherwise they will be \n                * associated with the global native objects manager and only be cleaned up on JS GC.\n                */\n                static Valdi::Result<\\(className)> resolve(snap::valdi_core::JSRuntime &jsRuntime, const std::shared_ptr<snap::valdi_core::JSRuntimeNativeObjectsManager>& nativeObjectsManager);\n            };\n\n            \"\"\")\n\n        generator.impl.body.appendBody(\"\"\"\n            \n            Valdi::Result<\\(className)> \\(className)::resolve(snap::valdi_core::JSRuntime &jsRuntime, const std::shared_ptr<snap::valdi_core::JSRuntimeNativeObjectsManager>& nativeObjectsManager) {\n                static auto *kSchema = Valdi::CppGeneratedExportedFunctionUtils::registerFunctionSchema(\\(registerSchemaParameters.joined(separator: \", \")));\n                return Valdi::CppGeneratedExportedFunctionUtils::resolve<\\(className)>(jsRuntime, nativeObjectsManager, \"\\(bundleInfo.name)/\\(modulePath)\", *kSchema);\n            }\n            \"\"\")\n\n        return [\n            NativeSource(relativePath: cppType.includeDir,\n                         filename: \"\\(cppType.declaration.name).hpp\",\n                         file: .data(try generator.header.content.indented.utf8Data()),\n                         groupingIdentifier: \"\\(bundleInfo.name).hpp\", groupingPriority: 0, localFilenameDependencies: generator.dependenciesInSameHeaderFile),\n            NativeSource(relativePath: cppType.includeDir,\n                         filename: \"\\(cppType.declaration.name).cpp\",\n                         file: .data(try generator.impl.content.indented.utf8Data()),\n                         groupingIdentifier: \"\\(bundleInfo.name).cpp\", groupingPriority: 0)\n\n        ]\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Cpp/CppModuleGenerator.swift",
    "content": "//\n//  CppModuleGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 11/26/25.\n//\n\n\nfinal class CppModuleGenerator {\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let cppType: CPPType\n    private let exportedModule: ExportedModule\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         cppType: CPPType,\n         exportedModule: ExportedModule,\n         classMapping: ResolvedClassMapping,\n         sourceFileName: GeneratedSourceFilename) {\n        self.bundleInfo = bundleInfo\n        self.cppType = cppType\n        self.exportedModule = exportedModule\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n    }\n\n    func write() throws -> [NativeSource] {\n        let moduleFactoryClassName = \"\\(cppType.declaration.name)Factory\"\n        let moduleFactoryCppType = CPPType(declaration: CPPTypeDeclaration(namespace: self.cppType.declaration.namespace,\n                                                                         name: moduleFactoryClassName,\n                                                                         symbolType: .class),\n                                         module: bundleInfo,\n                                         includePrefix: self.cppType.includePrefix)\n\n        let classNamespace = cppType.declaration.namespace.appending(component: moduleFactoryCppType.declaration.name)\n\n        var output: [NativeSource] = []\n\n        let modelGenerator = CppModelGenerator(cppType: cppType,\n                                               bundleInfo: bundleInfo,\n                                               typeParameters: nil,\n                                               properties: exportedModule.model.properties,\n                                               classMapping: classMapping,\n                                               sourceFileName: sourceFileName,\n                                               isInterface: true,\n                                               comments: exportedModule.model.comments)\n\n        output += try modelGenerator.write()\n\n        let generator = CppCodeGenerator(namespace: self.cppType.declaration.namespace,\n                                         selfIncludePath: moduleFactoryCppType.includePath,\n                                         namespaceResolver: CppCodeGeneratorSingleNamespaceResolver(classNamespace: classNamespace))\n\n        generator.impl.includeSection.addInclude(path: moduleFactoryCppType.includePath)\n\n        generator.header.includeSection.addInclude(path: \"valdi_core/cpp/Marshalling/CppGeneratedModuleFactory.hpp\")\n        generator.header.includeSection.addInclude(path: \"valdi_core/cpp/JavaScript/ModuleFactoryRegistry.hpp\")\n        if cppType.includePath != moduleFactoryCppType.includePath {\n            generator.header.includeSection.addInclude(path: cppType.includePath)\n        }\n\n        let additionalComments = \"\"\"\n        This type should be inherited from, and the onLoadModule() should be overriden to return\n        an instance of type \\(cppType.declaration.fullTypeName).\n        The module should then be registered by creating a Valdi::RegisterModuleFactory static instance.\n            \n        \"\"\"\n\n        generator.header.body.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: additionalComments))\n        generator.header.body.appendBody(\"\"\"\n            \n            class \\(moduleFactoryClassName): public Valdi::CppGeneratedModuleFactory<\\(cppType.declaration.name)> {\n            public:\n                \\(moduleFactoryClassName)();\n                ~\\(moduleFactoryClassName)() override;\n            \n                Valdi::StringBox getModulePath() final;            \n            };\n\n            \"\"\")\n\n        generator.impl.body.appendBody(\"\"\"\n            \\(moduleFactoryClassName)::\\(moduleFactoryClassName)() = default;\n            \\(moduleFactoryClassName)::~\\(moduleFactoryClassName)() = default;\n            \n            Valdi::StringBox \\(moduleFactoryClassName)::getModulePath() {\n                return Valdi::StringBox::fromCString(\"\\(self.exportedModule.modulePath)\");\n            }\n            \"\"\")\n\n        output.append(NativeSource(relativePath: moduleFactoryCppType.includeDir,\n                                   filename: \"\\(moduleFactoryCppType.declaration.name).hpp\",\n                                   file: .data(try generator.header.content.indented.utf8Data()),\n                                   groupingIdentifier: \"\\(bundleInfo.name).hpp\", groupingPriority: 0))\n\n        output.append(NativeSource(relativePath: moduleFactoryCppType.includeDir,\n                                   filename: \"\\(moduleFactoryCppType.declaration.name).cpp\",\n                                   file: .data(try generator.impl.content.indented.utf8Data()),\n                                   groupingIdentifier: \"\\(bundleInfo.name).cpp\", groupingPriority: 0))\n\n        return output\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Cpp/CppSchemaWriter.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 4/12/23.\n//\n\nimport Foundation\n\nclass CppSchemaWriterListener: SchemaWriterListener {\n    private let generator: CppCodeGenerator?\n    private let referencedTypes: [String]\n    private let indexByTypeName: [String: Int]\n\n    init(generator: CppCodeGenerator?) {\n        self.generator = generator\n        self.referencedTypes = generator?.referenceTypeKeys ?? []\n\n        self.indexByTypeName = referencedTypes.enumerated().associate {\n            ($0.element, $0.offset)\n        }\n    }\n\n    func getClassName(nodeMapping: ValdiNodeClassMapping, typeArguments: [ValdiModelPropertyType]?) throws -> String? {\n        if !nodeMapping.isGenerated {\n            return nil\n        }\n\n        let fullTypeName: String\n        if let typeArguments {\n            fullTypeName = CppCodeGenerator.makeCanonicalTypeKey(type: .genericObject(nodeMapping, typeArguments: typeArguments))\n        } else {\n            fullTypeName = CppCodeGenerator.makeCanonicalTypeKey(type: .object(nodeMapping))\n        }\n\n        guard let index = self.indexByTypeName[fullTypeName] else {\n            throw CompilerError(\"Could not resolve dependent declaration for type \\(fullTypeName)\")\n        }\n\n        return \"[\\(index)]\"\n    }\n}\n\nclass CppSchemaWriter: SchemaWriter {\n    private let cppWriterListener: CppSchemaWriterListener\n\n    init(typeParameters: [ValdiTypeParameter]?, generator: CppCodeGenerator?) {\n        self.cppWriterListener = CppSchemaWriterListener(generator: generator)\n        super.init(typeParameters: typeParameters,\n                   listener: cppWriterListener,\n                   alwaysBoxFunctionParametersAndReturnValue: false,\n                   boxIntEnums: false)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Cpp/CppValidation.swift",
    "content": "//\n//  CppValidation.swift\n//  \n//\n//  Created by Simon Corsin on 4/11/23.\n//\n\nimport Foundation\n\nenum CppValidation {\n\n    /// These keywords must be avoided when using identifiers for generated code (e.g. type names, properties)\n    static let cppKeywords = [\n        \"alignas\",\n        \"alignof\",\n        \"and\",\n        \"and_eq\",\n        \"asm\",\n        \"atomic_cancel\",\n        \"atomic_commit\",\n        \"atomic_noexcept\",\n        \"auto\",\n        \"bitand\",\n        \"bitor\",\n        \"bool\",\n        \"break\",\n        \"case\",\n        \"catch\",\n        \"char\",\n        \"char8_t\",\n        \"char16_t\",\n        \"char32_t\",\n        \"class\",\n        \"compl\",\n        \"concept\",\n        \"const\",\n        \"consteval\",\n        \"constexpr\",\n        \"constinit\",\n        \"const_cast\",\n        \"continue\",\n        \"co_await\",\n        \"co_return\",\n        \"co_yield\",\n        \"decltype\",\n        \"default\",\n        \"delete\",\n        \"do\",\n        \"double\",\n        \"dynamic_cast\",\n        \"else\",\n        \"enum\",\n        \"explicit\",\n        \"export\",\n        \"extern\",\n        \"false\",\n        \"float\",\n        \"for\",\n        \"friend\",\n        \"goto\",\n        \"if\",\n        \"inline\",\n        \"int\",\n        \"long\",\n        \"mutable\",\n        \"namespace\",\n        \"new\",\n        \"noexcept\",\n        \"not\",\n        \"not_eq\",\n        \"nullptr\",\n        \"operator\",\n        \"or\",\n        \"or_eq\",\n        \"private\",\n        \"protected\",\n        \"public\",\n        \"reflexpr\",\n        \"register\",\n        \"reinterpret_cast\",\n        \"requires\",\n        \"return\",\n        \"short\",\n        \"signed\",\n        \"sizeof\",\n        \"static\",\n        \"static_assert\",\n        \"static_cast\",\n        \"struct\",\n        \"switch\",\n        \"synchronized\",\n        \"template\",\n        \"this\",\n        \"thread_local\",\n        \"throw\",\n        \"true\",\n        \"try\",\n        \"typedef\",\n        \"typeid\",\n        \"typename\",\n        \"union\",\n        \"unsigned\",\n        \"using\",\n        \"virtual\",\n        \"void\",\n        \"volatile\",\n        \"wchar_t\",\n        \"while\",\n        \"xor\",\n        \"xor_eq\",\n        \"null\",\n        \"NULL\",\n        \"DEBUG\",\n        \"NDEBUG\"\n    ]\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Cpp/PropertyNameAllocator+CPP.swift",
    "content": "//\n//  PropertyNameAllocator+CPP.swift\n//  \n//\n//  Created by Simon Corsin on 4/11/23.\n//\n\nimport Foundation\n\nextension PropertyNameAllocator {\n\n    class func forCpp() -> PropertyNameAllocator {\n        let allocator = PropertyNameAllocator()\n\n        // Reserve the C++ keywords\n        CppValidation.cppKeywords.forEach { _ = allocator.allocate(property: $0) }\n\n        return allocator\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/EmittedIdentifiers.swift",
    "content": "//\n//  EmittedIdentifiers.swift\n//  \n//\n//  Created by Simon Corsin on 2/17/23.\n//\n\nimport Foundation\n\nclass EmittedIdentifiers {\n\n    var isEmpty: Bool {\n        return indexByIdentifier.isEmpty\n    }\n\n    private(set) var identifiers: [String] = []\n    private var indexByIdentifier: [String: Int] = [:]\n\n    func getIdentifierIndex(_ identifier: String) -> Int {\n        if let index = self.indexByIdentifier[identifier] {\n            return index\n        }\n\n        let index = identifiers.count\n        indexByIdentifier[identifier] = index\n        identifiers.append(identifier)\n        return index\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ExportedFunctionGenerator.swift",
    "content": "//\n//  ExportedFunctionGenerator.swift\n//  BlueSocket\n//\n//  Created by saniul on 25/03/2019.\n//\n\nimport Foundation\n\nstruct ExportedFunction {\n    let containingIosType: IOSType?\n    let containingAndroidTypeName: String?\n    let containingCppType: CPPType?\n\n    let functionName: String\n    let parameters: [ValdiModelProperty]\n    let returnType: ValdiModelPropertyType\n    let comments: String?\n}\n\nfinal class ExportedFunctionGenerator: NativeSourceGenerator {\n\n    private let exportedFunction: ExportedFunction\n    private let modulePath: String\n\n    init(exportedFunction: ExportedFunction, modulePath: String) {\n        self.exportedFunction = exportedFunction\n        self.modulePath = modulePath\n    }\n\n    func generateSwiftSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource] {\n        let iosGenerator = SwiftFunctionGenerator(iosType: type,\n                                                  exportedFunction: exportedFunction,\n                                                  classMapping: parameters.classMapping,\n                                                  sourceFileName: parameters.sourceFileName,\n                                                  bundleName: parameters.bundleInfo.name,\n                                                  modulePath: modulePath,\n                                                  bundleInfo: parameters.bundleInfo)\n\n        return try iosGenerator.write()\n    }\n\n    func generateObjCSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource] {\n        let iosGenerator = ObjCFunctionGenerator(iosType: type,\n                                                 exportedFunction: exportedFunction,\n                                                 classMapping: parameters.classMapping,\n                                                 sourceFileName: parameters.sourceFileName,\n                                                 bundleName: parameters.bundleInfo.name,\n                                                 modulePath: modulePath,\n                                                 bundleInfo: parameters.bundleInfo)\n\n        return try iosGenerator.write()\n    }\n\n    func generateKotlinSources(parameters: NativeSourceParameters, fullTypeName: String) throws -> [NativeSource] {\n        let androidGenerator = KotlinFunctionGenerator(bundleInfo: parameters.bundleInfo,\n                                                       fullTypeName: fullTypeName,\n                                                       exportedFunction: exportedFunction,\n                                                       classMapping: parameters.classMapping,\n                                                       sourceFileName: parameters.sourceFileName,\n                                                       modulePath: modulePath)\n\n        return try androidGenerator.write()\n    }\n\n    func generateCppSources(parameters: NativeSourceParameters, cppType: CPPType) throws -> [NativeSource] {\n        let cppGenerator = CppFunctionGenerator(cppType: cppType,\n                                                exportedFunction: exportedFunction,\n                                                classMapping: parameters.classMapping,\n                                                sourceFileName: parameters.sourceFileName,\n                                                modulePath: modulePath,\n                                                bundleInfo: parameters.bundleInfo)\n        return try cppGenerator.write()\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ExportedModuleGenerator.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nfinal class ExportedModuleGenerator: NativeSourceGenerator {\n\n    private let exportedModule: ExportedModule\n\n    init(bundleInfo: CompilationItem.BundleInfo, exportedModule: ExportedModule) {\n        self.exportedModule = exportedModule\n    }\n\n    func generateSwiftSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource] {\n        return []\n    }\n\n    func generateObjCSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource] {\n        let iosGenerator = ObjCModuleGenerator(iosType: type,\n                                               exportedModule: exportedModule,\n                                               bundleInfo: parameters.bundleInfo,\n                                               classMapping: parameters.classMapping,\n                                               sourceFileName: parameters.sourceFileName)\n        return try iosGenerator.write()\n    }\n\n    func generateKotlinSources(parameters: NativeSourceParameters, fullTypeName: String) throws -> [NativeSource] {\n        let androidGenerator = KotlinModuleGenerator(bundleInfo: parameters.bundleInfo,\n                                                     fullTypeName: fullTypeName,\n                                                     exportedModule: exportedModule,\n                                                     classMapping: parameters.classMapping,\n                                                     sourceFileName: parameters.sourceFileName)\n\n        return try androidGenerator.write()\n    }\n\n    func generateCppSources(parameters: NativeSourceParameters, cppType: CPPType) throws -> [NativeSource] {\n        let cppGenerator = CppModuleGenerator(bundleInfo: parameters.bundleInfo,\n                                              cppType: cppType,\n                                              exportedModule: exportedModule,\n                                              classMapping: parameters.classMapping,\n                                              sourceFileName: parameters.sourceFileName)\n        return try cppGenerator.write()\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/GeneratedTypesDiagnostics.swift",
    "content": "//\n//  GeneratedTypesDiagnostics.swift\n//  Compiler\n//\n//  Created by saniul on 17/07/2019.\n//\n\nimport Foundation\n\n//////////\n// This file defines set of easily-encodable structs describing the classes,\n// interfaces, enums etc. generated by the compiler.\n// These are then used to emit diagnostics JSON files\n//////////\n\nstruct GeneratedTypesSummary: Encodable {\n    let sourceFilePath: String\n    let generatedTypes: [GeneratedTypeDescription]\n\n    func toFile() -> File {\n        let data = (try? toJSON(outputFormatting: [.prettyPrinted, .sortedKeys])) ?? Data()\n        let file = File.data(data)\n        return file\n    }\n}\n\nenum GeneratedTypeDescription: Encodable {\n    case `class`(GeneratedNativeClassDescription)\n    case interface(GeneratedNativeInterfaceDescription)\n    case `enum`(GeneratedEnumDescription)\n    case function(GeneratedFunctionDescription)\n    case viewClass(GeneratedViewClassDescription)\n\n    enum CodingKeys: CodingKey {\n        case `class`\n        case interface\n        case `enum`\n        case function\n        case viewClass\n    }\n\n    func encode(to encoder: Encoder) throws {\n        var container = encoder.container(keyedBy: CodingKeys.self)\n        switch self {\n        case let .class(value):\n            try container.encode(value, forKey: .class)\n        case let .interface(value):\n            try container.encode(value, forKey: .interface)\n        case let .enum(value):\n            try container.encode(value, forKey: .enum)\n        case let .function(value):\n            try container.encode(value, forKey: .function)\n        case let .viewClass(value):\n            try container.encode(value, forKey: .viewClass)\n        }\n    }\n\n    func typeName(for platform: Platform) -> String? {\n        switch platform {\n        case .ios:\n            return iosTypeName\n        case .android:\n            return androidTypeName\n        case .web:\n            return webTypeName\n        case .cpp:\n            return cppTypeName\n        }\n    }\n\n    var iosTypeName: String? {\n        switch self {\n        case let .class(this):\n            return this.iosTypeName\n        case let .interface(this):\n            return this.iosTypeName\n        case let .enum(this):\n            return this.iosTypeName\n        case let .function(this):\n            return this.containingIosTypeName\n        case let .viewClass(this):\n            return this.iosTypeName\n        }\n    }\n\n    var androidTypeName: String? {\n        switch self {\n        case let .class(this):\n            return this.androidTypeName\n        case let .interface(this):\n            return this.androidTypeName\n        case let .enum(this):\n            return this.androidTypeName\n        case let .function(this):\n            return this.containingAndroidTypeName\n        case let .viewClass(this):\n            return this.androidClassName\n        }\n    }\n\n    var cppTypeName: String? {\n        switch self {\n        case let .class(this):\n            return this.cppTypeName\n        case let .interface(this):\n            return this.cppTypeName\n        case let .enum(this):\n            return this.cppTypeName\n        case .function:\n            // TODO: not supported yet\n            return nil\n        case .viewClass:\n            return nil\n        }\n    }\n\n    var webTypeName: String? {\n        // TODO: Implement this\n        return nil\n    }\n\n    var valueToSortBy: String {\n        switch self {\n        case let .class(this):\n            return this.iosTypeName ?? this.androidTypeName ?? \"\"\n        case let .interface(this):\n            return this.iosTypeName ?? this.androidTypeName ?? \"\"\n        case let .enum(this):\n            return this.iosTypeName ?? this.androidTypeName ?? \"\"\n        case let .function(this):\n            return this.functionName\n        case let .viewClass(this):\n            return this.iosTypeName ?? this.androidClassName ?? \"\"\n        }\n    }\n}\n\nstruct GeneratedNativeClassDescription: Encodable {\n    let iosTypeName: String?\n    let androidTypeName: String?\n    let cppTypeName: String?\n    let properties: [PropertyDescription]\n\n    init(model: ValdiModel) {\n        iosTypeName = model.iosType?.name\n        androidTypeName = model.androidClassName\n        cppTypeName = model.cppType?.declaration.fullTypeName\n        properties = model.properties.map(PropertyDescription.init)\n    }\n}\n\nstruct GeneratedNativeInterfaceDescription: Encodable {\n    let iosTypeName: String?\n    let androidTypeName: String?\n    let cppTypeName: String?\n    let properties: [PropertyDescription]\n\n    init(model: ValdiModel) {\n        iosTypeName = model.iosType?.name\n        androidTypeName = model.androidClassName\n        cppTypeName = model.cppType?.declaration.fullTypeName\n        properties = model.properties.map(PropertyDescription.init)\n    }\n}\n\nstruct GeneratedEnumDescription: Encodable {\n    let iosTypeName: String?\n    let androidTypeName: String?\n    let cppTypeName: String?\n\n    let intCases: [EnumCase<Int>]?\n    let stringCases: [EnumCase<String>]?\n\n    static func from(exportedEnum: ExportedEnum) -> GeneratedEnumDescription {\n        let intCases: [EnumCase<Int>]?\n        let stringCases: [EnumCase<String>]?\n        switch exportedEnum.cases {\n        case let .enum(cases):\n            intCases = cases\n            stringCases = nil\n        case let .stringEnum(cases):\n            intCases = nil\n            stringCases = cases\n        }\n        return GeneratedEnumDescription(iosTypeName: exportedEnum.iosType?.name,\n                                        androidTypeName: exportedEnum.androidTypeName,\n                                        cppTypeName: exportedEnum.cppType?.declaration.fullTypeName,\n                                        intCases: intCases,\n                                        stringCases: stringCases)\n    }\n}\n\nstruct GeneratedFunctionDescription: Encodable {\n    let containingIosTypeName: String?\n    let containingAndroidTypeName: String?\n    let functionName: String\n    let parameters: [PropertyDescription]\n    let returnType: PropertyTypeDescription\n\n    static func from(exportedFunction: ExportedFunction) -> GeneratedFunctionDescription {\n        return GeneratedFunctionDescription(containingIosTypeName: exportedFunction.containingIosType?.name,\n                                            containingAndroidTypeName: exportedFunction.containingAndroidTypeName,\n                                            functionName: exportedFunction.functionName,\n                                            parameters: exportedFunction.parameters.map(PropertyDescription.init),\n                                            returnType: PropertyTypeDescription(propType: exportedFunction.returnType))\n    }\n}\n\nstruct GeneratedViewClassDescription: Encodable {\n    let iosTypeName: String?\n    let androidClassName: String?\n\n    let iosViewModelClassName: String?\n    let androidViewModelClassName: String?\n\n    let iosComponentContextClassName: String?\n    let androidComponentContextClassName: String?\n\n    var accessors: [AccessorDescription]?\n    var nativeActions: [String]?\n    var emitActions: [String]?\n\n    struct AccessorDescription: Encodable {\n        let iosTypeName: String?\n        let androidClassName: String?\n        let name: String\n    }\n}\n\n// class for indirection\nclass PropertyTypeDescription: Encodable {\n    let typeStr: String\n\n    private(set) var functionTypeMetadata: FunctionTypeMetadata?\n    struct FunctionTypeMetadata: Encodable {\n        let parameters: [PropertyDescription]\n        let returnType: PropertyTypeDescription\n    }\n\n    private(set) var genericTypeMetadata: GenericTypeMetadata?\n    struct GenericTypeMetadata: Encodable {\n        let types: [PropertyTypeDescription]\n    }\n\n    private(set) var customTypeMetadata: CustomTypeMetadata?\n    struct CustomTypeMetadata: Encodable {\n        let iosTypeName: String?\n        let androidClassName: String?\n    }\n\n    private(set) var typeParameterMetadata: TypeParameterMetadata?\n    struct TypeParameterMetadata: Encodable {\n        let typeParameterName: String\n    }\n\n    init(propType: ValdiModelPropertyType) {\n        switch propType {\n        case .string:\n            typeStr = \"string\"\n        case .double:\n            typeStr = \"double\"\n        case .bool:\n            typeStr = \"bool\"\n        case .long:\n            typeStr = \"long\"\n        case let .array(elementType):\n            typeStr = \"array\"\n            let description = PropertyTypeDescription(propType: elementType)\n            genericTypeMetadata = GenericTypeMetadata(types: [description])\n        case .bytes:\n            typeStr = \"bytes\"\n        case .map:\n            typeStr = \"map\"\n        case .any:\n            typeStr = \"any\"\n        case .void:\n            typeStr = \"void\"\n        case let .function(parameters, returnType, _, _):\n            typeStr = \"function\"\n            let parameters = parameters.map(PropertyDescription.init)\n            let returnType = PropertyTypeDescription(propType: returnType)\n            functionTypeMetadata = FunctionTypeMetadata(parameters: parameters, returnType: returnType)\n        case let .object(nodeClassMapping):\n            typeStr = \"object\"\n            customTypeMetadata = CustomTypeMetadata(iosTypeName: nodeClassMapping.iosType?.name, androidClassName: nodeClassMapping.androidClassName)\n        case let .genericTypeParameter(name):\n            typeStr = \"genericTypeParameter\"\n            typeParameterMetadata = .init(typeParameterName: name)\n        case let .genericObject(nodeClassMapping, _):\n            typeStr = \"genericObject\"\n            customTypeMetadata = CustomTypeMetadata(iosTypeName: nodeClassMapping.iosType?.name, androidClassName: nodeClassMapping.androidClassName)\n        case let .enum(nodeClassMapping):\n            typeStr = \"enum\"\n            customTypeMetadata = CustomTypeMetadata(iosTypeName: nodeClassMapping.iosType?.name, androidClassName: nodeClassMapping.androidClassName)\n        case .promise(let typeArgument):\n            typeStr = \"promise\"\n            genericTypeMetadata = GenericTypeMetadata(types: [PropertyTypeDescription(propType: typeArgument)])\n        case let .nullable(innerType):\n            let innerDescription = PropertyTypeDescription(propType: innerType)\n            typeStr = \"\\(innerDescription.typeStr)?\"\n        }\n    }\n}\n\nstruct PropertyDescription: Encodable {\n    let name: String\n    let isOptional: Bool\n\n    let type: PropertyTypeDescription\n\n    // not for interfaces\n    let omitConstructor: OmitConstructorParams?\n\n    init(prop: ValdiModelProperty) {\n        name = prop.name\n        isOptional = prop.type.isOptional\n        type = PropertyTypeDescription(propType: prop.type.unwrappingOptional)\n        omitConstructor = prop.omitConstructor\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Kotlin/JVMClass.swift",
    "content": "//\n//  JVMClass.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 8/13/19.\n//\n\nimport Foundation\n\nstruct JVMClass {\n\n    let fullClassName: String\n    let name: String\n    let package: String?\n\n    var filePath: String {\n        var components = fullClassName.split(separator: \".\")\n        if components.count > 0 {\n            components.removeLast()\n        }\n\n        return components.joined(separator: \"/\")\n    }\n\n    init(fullClassName: String) {\n        self.fullClassName = fullClassName\n\n        let components = fullClassName.split(separator: \".\")\n        if components.count > 1 {\n            name = String(components.last!)\n            package = components[0..<components.count - 1].joined(separator: \".\")\n        } else {\n            name = fullClassName\n            package = nil\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Kotlin/KotlinCodeGenerator.swift",
    "content": "//\n//  KotlinCodeGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct KotlinTypeParser {\n    let typeName: String\n    let functionTypeParser: KotlinFunctionTypeParser?\n    let typeArguments: [KotlinTypeParser]?\n    let fullTypeName: String\n\n    init(\n        typeName: String,\n        functionTypeParser: KotlinFunctionTypeParser? = nil,\n        typeArguments: [KotlinTypeParser]? = nil\n    ) {\n        self.typeName = typeName\n        self.functionTypeParser = functionTypeParser\n        self.typeArguments = typeArguments\n        self.fullTypeName = KotlinTypeParser.getFullTypeName(typeName: typeName, typeArguments: typeArguments)\n    }\n\n    private static func getFullTypeName(typeName: String, typeArguments: [KotlinTypeParser]?) -> String {\n        if let typeArguments = typeArguments {\n            let typeNameWithoutOptionalMark = typeName.hasSuffix(\"?\") ? String(typeName.dropLast()) : typeName\n            let optionalMarkIfNeeded = typeName.hasSuffix(\"?\") ? \"?\" : \"\"\n            return \"\\(typeNameWithoutOptionalMark)<\\(typeArguments.map { $0.fullTypeName }.joined(separator: \", \"))>\\(optionalMarkIfNeeded)\"\n        } else {\n            return typeName\n        }\n    }\n}\n\nprivate final class KotlinImportSection: CodeWriterContent {\n\n    private(set) var importedClasses = Set<String>()\n\n    func addImport(fullClassName: String) {\n        importedClasses.insert(fullClassName)\n    }\n\n    var content: String {\n        if importedClasses.isEmpty {\n            return \"\"\n        }\n        return importedClasses.sorted().map { \"import \\($0)\\n\" }.joined() + \"\\n\"\n    }\n\n}\n\nstruct KotlinSchemaAnnotationResult {\n    let typeReferences: CodeWriterContent\n    let schema: CodeWriterContent\n}\n\nclass KotlinFunctionTypeParser {\n    let parameterNames: [PropertyName]\n    let parameterTypes: [KotlinTypeParser]\n    let returnType: KotlinTypeParser\n\n    init(parameterNames: [PropertyName], parameterTypes: [KotlinTypeParser], returnType: KotlinTypeParser) {\n        self.parameterNames = parameterNames\n        self.parameterTypes = parameterTypes\n        self.returnType = returnType\n    }\n\n    var parametersString: String {\n        return parameterNames.enumerated().map { index, name in\n            return \"\\(name): \\(parameterTypes[index].fullTypeName)\"\n        }.joined(separator: \", \")\n    }\n\n    var lambdaTypeName: String {\n        return \"(\\(parametersString)) -> \\(returnType.fullTypeName)\"\n    }\n\n    var methodTypeName: String {\n        return \"(\\(parametersString)): \\(returnType.fullTypeName)\"\n    }\n}\n\nprivate class KotlinSchemaWriterListener: SchemaWriterListener {\n    private unowned let codeGenerator: KotlinCodeGenerator\n    private let emittedTypeReferences: KotlinEmittedTypeReferences\n\n    init(codeGenerator: KotlinCodeGenerator, emittedTypeReferences: KotlinEmittedTypeReferences) {\n        self.codeGenerator = codeGenerator\n        self.emittedTypeReferences = emittedTypeReferences\n    }\n\n    func getClassName(nodeMapping: ValdiNodeClassMapping, typeArguments: [ValdiModelPropertyType]?) throws -> String? {\n        guard let androidClassName = nodeMapping.androidClassName else {\n            throw CompilerError(\"No Android type declared\")\n        }\n\n        let jvmClass = try codeGenerator.importClass(androidClassName)\n\n        let identifierIndex = emittedTypeReferences.getIdentifierIndex(jvmClass.name)\n\n        return \"[\\(identifierIndex)]\"\n    }\n\n}\n\nclass KotlinPropertyReplacements: CodeWriterContent {\n\n    var replacements = [(Int, String)]()\n\n    var content: String {\n        let stringContent = replacements.map { \"\\($0):'\\($1)'\" }.joined(separator: \",\")\n        return \"\\\"\\(stringContent)\\\"\"\n    }\n\n}\n\nclass KotlinSchema: CodeWriterContent {\n\n    let schemaWriter: KotlinSchemaWriter\n\n    init(typeParameters: [ValdiTypeParameter]?, listener: SchemaWriterListener) {\n        self.schemaWriter = KotlinSchemaWriter(typeParameters: typeParameters, listener: listener)\n    }\n\n    var content: String {\n        return \"\\\"\\(self.schemaWriter.str)\\\"\"\n    }\n\n}\n\nclass KotlinMarshallableObjectDescriptorAnnotation: CodeWriter {\n\n    enum ObjectType {\n        case valdiClass\n        case valdiInterface\n        case stringEnum\n        case intEnum\n        case valdiFunction\n    }\n\n    let type: ObjectType\n    private unowned let generator: KotlinCodeGenerator\n    private let schema: KotlinSchema\n    private let emittedTypeReferences = KotlinEmittedTypeReferences()\n    private let propertyReplacements = KotlinPropertyReplacements()\n\n    init(type: ObjectType, generator: KotlinCodeGenerator, typeParameters: [ValdiTypeParameter]?, additionalParameters: [(String, CodeWriterContent)]) throws {\n        self.type = type\n        self.generator = generator\n        self.schema = KotlinSchema(typeParameters: typeParameters, listener: KotlinSchemaWriterListener(codeGenerator: generator, emittedTypeReferences: self.emittedTypeReferences))\n\n        super.init()\n\n        var allParameters = [(String, CodeWriterContent)]()\n        allParameters.append((\"schema\", schema))\n\n        let annotationName: String\n        switch type {\n        case .valdiClass:\n            annotationName = \"ValdiClass\"\n            allParameters.append((\"typeReferences\", emittedTypeReferences))\n            allParameters.append((\"propertyReplacements\", propertyReplacements))\n        case .valdiInterface:\n            annotationName = \"ValdiInterface\"\n            allParameters.append((\"typeReferences\", emittedTypeReferences))\n            allParameters.append((\"propertyReplacements\", propertyReplacements))\n        case .stringEnum:\n            annotationName = \"ValdiEnum\"\n            allParameters.append((\"propertyReplacements\", propertyReplacements))\n        case .intEnum:\n            annotationName = \"ValdiEnum\"\n            allParameters.append((\"propertyReplacements\", propertyReplacements))\n        case .valdiFunction:\n            annotationName = \"ValdiFunctionClass\"\n            allParameters.append((\"typeReferences\", emittedTypeReferences))\n            allParameters.append((\"propertyReplacements\", propertyReplacements))\n        }\n        allParameters.append(contentsOf: additionalParameters)\n\n        appendBody(try generator.getJavaAnnotationContent(annotationType: \"com.snap.valdi.schema.\\(annotationName)\", parameters: allParameters))\n    }\n\n    func appendField(propertyIndex: Int,\n                     propertyName: String,\n                     kotlinFieldName: String,\n                     expectedKotlinFieldName: String,\n                     schemaBuilder: (SchemaWriter) throws -> Void) throws -> CodeWriterContent {\n        if propertyIndex > 0 {\n            self.schema.schemaWriter.appendComma()\n        }\n\n        if kotlinFieldName != expectedKotlinFieldName {\n            // Kotlin field name cannot be infered, add an entry in the mapping array\n            let tuple = (propertyIndex, kotlinFieldName)\n            propertyReplacements.replacements.append(tuple)\n        }\n\n        self.schema.schemaWriter.appendPropertyName(propertyName)\n        try schemaBuilder(self.schema.schemaWriter)\n\n        return try generator.getJavaAnnotationContent(annotationType: \"com.snap.valdi.schema.ValdiField\")\n    }\n}\n\nfinal class KotlinCodeGenerator: CodeWriter {\n\n    static let maxFunctionParametersCount = 16\n\n    private let package: String?\n    private let classMapping: ResolvedClassMapping?\n    private let importSection = KotlinImportSection()\n\n    init(package: String? = nil, classMapping: ResolvedClassMapping? = nil) {\n        self.package = package\n        self.classMapping = classMapping\n        super.init()\n\n        if let package = package {\n            appendHeader(\"package \\(package)\\n\\n\")\n        }\n\n        appendHeader(importSection)\n    }\n\n    private func importClassIfNeeded(_ jvmClass: JVMClass) {\n        if let package = package, jvmClass.package == package {\n            return\n        }\n\n        importSection.addImport(fullClassName: jvmClass.fullClassName)\n    }\n\n    @discardableResult func importClass(_ className: String) throws -> JVMClass {\n        if className.isEmpty {\n            throw CompilerError(\"No class defined\")\n        }\n        let jvmClass = JVMClass(fullClassName: className)\n\n        importClassIfNeeded(jvmClass)\n\n        return jvmClass\n    }\n\n    private func resolveTypeName(typeName: String, isOptional: Bool) -> String {\n        return isOptional ? \"\\(typeName)?\" : typeName\n    }\n\n    private func getPrimitiveTypeParser(primitiveType: String, propertyName: String?, isOptional: Bool) -> KotlinTypeParser {\n        let resolvedType = resolveTypeName(typeName: primitiveType, isOptional: isOptional)\n        return KotlinTypeParser(typeName: resolvedType)\n    }\n\n    private func getGenericTypeParameterTypeParser(name: String, propertyName: String?, isOptional: Bool, nameAllocator: PropertyNameAllocator) throws -> KotlinTypeParser {\n        // properties with generic parameter types have to always accept optional values\n        let isOptional = propertyName != nil || isOptional\n        let resolvedTypeName = resolveTypeName(typeName: name, isOptional: isOptional)\n        return KotlinTypeParser(typeName: resolvedTypeName)\n    }\n\n    private func getObjectTypeParser(typeName: String, mapping: ValdiNodeClassMapping, propertyName: String?, isOptional: Bool, nameAllocator: PropertyNameAllocator) -> KotlinTypeParser {\n        let resolvedTypeName = resolveTypeName(typeName: typeName, isOptional: isOptional)\n        return KotlinTypeParser(typeName: resolvedTypeName)\n    }\n\n    private func getGenericObjectTypeParser(typeName: String, mapping: ValdiNodeClassMapping, propertyName: String?, isOptional: Bool, nameAllocator: PropertyNameAllocator, typeArgumentsTypeParsers: [KotlinTypeParser]) throws -> KotlinTypeParser {\n        let resolvedTypeName = resolveTypeName(typeName: typeName, isOptional: isOptional)\n        let typeParser = KotlinTypeParser(\n            typeName: resolvedTypeName,\n            typeArguments: typeArgumentsTypeParsers\n        )\n        return typeParser\n    }\n\n    func getJavaAnnotationContent(annotationType: String) throws -> CodeWriterContent {\n        return try getJavaAnnotationContent(annotationType: annotationType, parameters: [])\n    }\n\n    func getJavaAnnotationContent(annotationType: String, parameters: [(String, CodeWriterContent)]) throws -> CodeWriterContent {\n        let annotationClassType = try importClass(annotationType)\n\n        let output = CodeWriter()\n        output.appendBody(\"@\\(annotationClassType.name)\")\n\n        if !parameters.isEmpty {\n            output.appendBody(\"(\")\n            if parameters.count  == 1 {\n                output.appendBody(\"\\(parameters[0].0) = \")\n                output.appendBody(parameters[0].1)\n            } else {\n                var first = true\n                for parameter in parameters {\n                    if !first {\n                        output.appendBody(\",\")\n                    }\n                    first = false\n                    output.appendBody(\"\\n    \\(parameter.0) = \")\n                    output.appendBody(parameter.1)\n                }\n                output.appendBody(\"\\n\" )\n            }\n            output.appendBody(\")\")\n        }\n\n        output.appendBody(\"\\n\")\n\n        return output\n    }\n\n    func getDescriptorAnnotation(type: KotlinMarshallableObjectDescriptorAnnotation.ObjectType, typeParameters: [ValdiTypeParameter]?, additionalParameters: [(String, CodeWriterContent)]) throws -> KotlinMarshallableObjectDescriptorAnnotation {\n        return try KotlinMarshallableObjectDescriptorAnnotation(type: type, generator: self, typeParameters: typeParameters, additionalParameters: additionalParameters)\n    }\n\n    private func getFunctionTypeParser(returnType: ValdiModelPropertyType,\n                               parameters: [ValdiModelProperty],\n                               nameAllocator: PropertyNameAllocator) throws -> KotlinFunctionTypeParser {\n        guard parameters.count <= KotlinCodeGenerator.maxFunctionParametersCount else {\n            throw CompilerError(\"Exported functions to Kotlin can only support up to \\(KotlinCodeGenerator.maxFunctionParametersCount) parameters.\")\n        }\n\n        let parameterNames = parameters.map { nameAllocator.allocate(property: $0.name) }\n        let parameterParsers = try parameters.map { try getTypeParser(type: $0.type.unwrappingOptional, isOptional: $0.type.isOptional, propertyName: nil, nameAllocator: nameAllocator) }\n        let returnParser = try getTypeParser(type: returnType.unwrappingOptional, isOptional: returnType.isOptional, propertyName: nil, nameAllocator: nameAllocator)\n\n        return KotlinFunctionTypeParser(parameterNames: parameterNames, parameterTypes: parameterParsers, returnType: returnParser)\n    }\n\n    func getTypeParser(type: ValdiModelPropertyType, isOptional: Bool, propertyName: String?, nameAllocator: PropertyNameAllocator) throws -> KotlinTypeParser {\n        switch type {\n        case .string:\n            return getPrimitiveTypeParser(primitiveType: \"String\", propertyName: propertyName, isOptional: isOptional)\n        case .double:\n            return getPrimitiveTypeParser(primitiveType: \"Double\", propertyName: propertyName, isOptional: isOptional)\n        case .bool:\n            return getPrimitiveTypeParser(primitiveType: \"Boolean\", propertyName: propertyName, isOptional: isOptional)\n        case .long:\n            return getPrimitiveTypeParser(primitiveType: \"Long\", propertyName: propertyName, isOptional: isOptional)\n        case .array(let elementType):\n            let childParser = try getTypeParser(type: elementType.unwrappingOptional, isOptional: elementType.isOptional, propertyName: nil, nameAllocator: nameAllocator)\n            let typeName = \"List<\\(childParser.fullTypeName)>\"\n\n            return KotlinTypeParser(typeName: resolveTypeName(typeName: typeName, isOptional: isOptional))\n        case .bytes:\n            return getPrimitiveTypeParser(primitiveType: \"ByteArray\", propertyName: propertyName, isOptional: isOptional)\n        case .map:\n            let typeName = resolveTypeName(typeName: \"Map<String, Any?>\", isOptional: isOptional)\n            return KotlinTypeParser(typeName: typeName)\n        case .any:\n            let isOptional = true\n            let typeName = resolveTypeName(typeName: \"Any\", isOptional: isOptional)\n            return KotlinTypeParser(typeName: typeName)\n        case .void:\n            let typeName = \"Unit\"\n            return KotlinTypeParser(typeName: typeName)\n        case .function(let parameters, let returnType, _, _):\n            let functionTypeParser = try getFunctionTypeParser(returnType: returnType, parameters: parameters, nameAllocator: nameAllocator)\n\n            let typeName = functionTypeParser.lambdaTypeName\n\n            let resolvedTypeName: String\n            if isOptional {\n                resolvedTypeName = \"(\\(typeName))?\"\n            } else {\n                resolvedTypeName = typeName\n            }\n\n            return KotlinTypeParser(typeName: resolvedTypeName, functionTypeParser: functionTypeParser)\n        case .enum(let mapping):\n            guard let resolvedType = mapping.androidClassName else {\n                throw CompilerError(\"No android type declared\")\n            }\n\n            let typeName = try importClass(resolvedType).name\n            return getObjectTypeParser(typeName: typeName, mapping: mapping, propertyName: propertyName, isOptional: isOptional, nameAllocator: nameAllocator)\n        case .object(let mapping):\n            guard let resolvedType = mapping.androidClassName else {\n                throw CompilerError(\"No android class declared\")\n            }\n\n            let typeName = try importClass(resolvedType).name\n            return getObjectTypeParser(typeName: typeName, mapping: mapping, propertyName: propertyName, isOptional: isOptional, nameAllocator: nameAllocator)\n        case .genericTypeParameter(let name):\n            return try getGenericTypeParameterTypeParser(name: name, propertyName: propertyName, isOptional: isOptional, nameAllocator: nameAllocator)\n        case .genericObject(let mapping, let typeArguments):\n            guard let resolvedType = mapping.androidClassName else {\n                throw CompilerError(\"No android class declared\")\n            }\n\n            let typeArgumentsTypeParsers = try typeArguments.map {\n                try getTypeParser(type: $0, isOptional: false, propertyName: nil, nameAllocator: nameAllocator)\n            }\n\n            let typeName = try importClass(resolvedType).name\n            return try getGenericObjectTypeParser(typeName: typeName, mapping: mapping, propertyName: propertyName, isOptional: isOptional, nameAllocator: nameAllocator, typeArgumentsTypeParsers: typeArgumentsTypeParsers)\n        case .promise(let typeArgument):\n            let promiseTypeName = try importClass(\"com.snap.valdi.promise.Promise\").name\n            let childParser = try getTypeParser(type: typeArgument.unwrappingOptional, isOptional: typeArgument.isOptional, propertyName: nil, nameAllocator: nameAllocator)\n            let typeName = \"\\(promiseTypeName)<\\(childParser.fullTypeName)>\"\n\n            return getPrimitiveTypeParser(primitiveType: typeName, propertyName: nil, isOptional: isOptional)\n        case .nullable(let type):\n            return try getTypeParser(type: type, isOptional: true, propertyName: propertyName, nameAllocator: nameAllocator)\n        }\n    }\n\n    static func makeNativeSource(bundleInfo: CompilationItem.BundleInfo, jvmClass: JVMClass, file: File, fileNameOverride: String? = nil) -> NativeSource {\n        let filename = fileNameOverride ?? \"\\(jvmClass.name).\\(FileExtensions.kotlin)\"\n\n        return NativeSource(relativePath: jvmClass.filePath,\n                            filename: filename,\n                            file: file,\n                            groupingIdentifier: \"\\(bundleInfo.name).\\(FileExtensions.kotlin)\",\n                            groupingPriority: 0)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Kotlin/KotlinEmittedTypeReferences.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 2/17/23.\n//\n\nimport Foundation\n\nclass KotlinEmittedTypeReferences: EmittedIdentifiers, CodeWriterContent {\n\n    var initializationString: CodeWriter {\n        let body = identifiers.map {\n             \"\\($0)::class\"\n        }.joined(separator: \", \")\n        let out = CodeWriter()\n        out.appendBody(\"[\")\n        out.appendBody(body)\n        out.appendBody(\"]\")\n        return out\n    }\n\n    var content: String {\n        return initializationString.content\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Kotlin/KotlinFunctionGenerator.swift",
    "content": "//\n//  KotlinFunctionGenerator.swift\n//  Compiler\n//\n//  Created by saniul on 12/04/2019.\n//\n\nimport Foundation\n\nfinal class KotlinFunctionGenerator {\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let fullTypeName: String\n    private let exportedFunction: ExportedFunction\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n    private let modulePath: String\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         fullTypeName: String,\n         exportedFunction: ExportedFunction,\n         classMapping: ResolvedClassMapping,\n         sourceFileName: GeneratedSourceFilename,\n         modulePath: String) {\n        self.bundleInfo = bundleInfo\n        self.fullTypeName = fullTypeName\n        self.exportedFunction = exportedFunction\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.modulePath = modulePath\n    }\n\n    func write() throws -> [NativeSource] {\n        let jvmClass = JVMClass(fullClassName: fullTypeName)\n        let containingTypeName = jvmClass.name\n\n        let generator = KotlinCodeGenerator(package: jvmClass.package, classMapping: classMapping)\n        let jsRuntimeClass = try generator.importClass(\"com.snap.valdi.jsmodules.ValdiJSRuntime\")\n        let bridgeFunctionClass = try generator.importClass(\"com.snap.valdi.callable.ValdiBridgeFunction\")\n\n        generator.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: exportedFunction.comments))\n        generator.appendBody(\"\\n\")\n\n        let nameAllocator = PropertyNameAllocator.forKotlin()\n\n        let fieldName = nameAllocator.allocate(property: \"_invoker\").name\n\n        let typeParser = try generator.getTypeParser(type: .function(parameters: exportedFunction.parameters, returnType: exportedFunction.returnType, isSingleCall: false, shouldCallOnWorkerThread: false), isOptional: false, propertyName: nil, nameAllocator: nameAllocator)\n\n        guard let functionTypeParser = typeParser.functionTypeParser else {\n            throw CompilerError(\"Expecting functionTypePArser\")\n        }\n\n        let descriptorAnnotation = try generator.getDescriptorAnnotation(type: KotlinMarshallableObjectDescriptorAnnotation.ObjectType.valdiFunction, typeParameters: nil, additionalParameters: [])\n\n        let constructorAnnotationContent = try generator.getJavaAnnotationContent(annotationType: \"com.snap.valdi.schema.ValdiClassConstructor\")\n\n        let invokeParameters = functionTypeParser.parameterNames.map { $0.name }.joined(separator: \", \")\n\n        generator.appendBody(\"\\n\")\n        generator.appendBody(descriptorAnnotation)\n        generator.appendBody(\"class \\(containingTypeName): \\(bridgeFunctionClass.name) {\\n\\n\")\n\n        let fieldAnnotation = try descriptorAnnotation.appendField(propertyIndex: 0, propertyName: exportedFunction.functionName, kotlinFieldName: fieldName, expectedKotlinFieldName: \"_invoker\") { schemaWriter in\n            try schemaWriter.appendFunction(returnType: exportedFunction.returnType, parameters: exportedFunction.parameters, isOptional: false, isMethod: false, isSingleCall: false, shouldCallOnWorkerThread: false)\n        }\n\n        generator.appendBody(fieldAnnotation)\n        generator.appendBody(\"private var \\(fieldName): \\(typeParser.fullTypeName)\\n\\n\")\n\n        generator.appendBody(constructorAnnotationContent)\n        generator.appendBody(\"\"\"\n        constructor(invoker: \\(typeParser.fullTypeName)) {\n            \\(fieldName) = invoker\n        }\n\n        fun invoke\\(functionTypeParser.methodTypeName) {\n            return \\(fieldName)(\\(invokeParameters))\n        }\n\n        companion object {\n            const val MODULE_PATH = \"\\(bundleInfo.name)/\\(modulePath)\"\n            const val ASYNC_STRICT_MODE: Boolean = \\(bundleInfo.asyncStrictMode ? \"true\" : \"false\")\n\n            @JvmStatic\n            fun create(runtime: \\(jsRuntimeClass.name)): \\(containingTypeName) {\n              \\(bridgeFunctionClass.name).assertResolutionNotOnMainThreadIfNeeded(ASYNC_STRICT_MODE)\n              return \\(bridgeFunctionClass.name).createFromRuntime(runtime, \\(containingTypeName)::class.java, MODULE_PATH)\n            }\n\n            @JvmStatic\n            fun invokeWithJSRuntime(jsRuntimeProvider: () -> \\(jsRuntimeClass.name)\\(functionTypeParser.parameterNames.isEmpty ? \"\" : \", \")\\(functionTypeParser.parameterNames.enumerated().map { \"\\($0.element.name): \\(functionTypeParser.parameterTypes[$0.offset].fullTypeName)\" }.joined(separator: \", \")), completionHandler: \\(functionTypeParser.returnType.fullTypeName == \"Unit\" ? \"() -> Unit\" : \"(\\(functionTypeParser.returnType.fullTypeName)) -> Unit\")) {\n                val runtime = jsRuntimeProvider()\n                runtime.runOnJsThread {\n                    val function = create(runtime)\n                    \\(functionTypeParser.returnType.fullTypeName == \"Unit\" ? \"function.\\(fieldName)(\\(invokeParameters))\\n                    completionHandler()\" : \"val result = function.\\(fieldName)(\\(invokeParameters))\\n                    completionHandler(result)\")\n                }\n            }\n        }\n        }\n\n        \"\"\")\n\n        let data = try generator.content.indented(indentPattern: \"    \").utf8Data()\n        return [KotlinCodeGenerator.makeNativeSource(bundleInfo: bundleInfo, jvmClass: jvmClass, file: .data(data))]\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Kotlin/KotlinModuleGenerator.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nfinal class KotlinModuleGenerator {\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let fullTypeName: String\n    private let exportedModule: ExportedModule\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         fullTypeName: String,\n         exportedModule: ExportedModule,\n         classMapping: ResolvedClassMapping,\n         sourceFileName: GeneratedSourceFilename) {\n        self.bundleInfo = bundleInfo\n        self.fullTypeName = fullTypeName\n        self.exportedModule = exportedModule\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n    }\n\n    func write() throws -> [NativeSource] {\n        var output: [NativeSource] = []\n        let androidGenerator = KotlinModelGenerator(bundleInfo: bundleInfo,\n                                                    className: fullTypeName,\n                                                    typeParameters: exportedModule.model.typeParameters,\n                                                    properties: exportedModule.model.properties,\n                                                    classMapping: classMapping,\n                                                    sourceFileName: sourceFileName,\n                                                    isInterface: exportedModule.model.exportAsInterface,\n                                                    emitLegacyConstructors: exportedModule.model.legacyConstructors,\n                                                    comments: exportedModule.model.comments)\n        output += try androidGenerator.write()\n\n        let jvmClass = JVMClass(fullClassName: \"\\(fullTypeName)Factory\")\n\n        let generator = KotlinCodeGenerator(package: jvmClass.package, classMapping: classMapping)\n        let baseClass = try generator.importClass(\"com.snap.valdi.modules.ValdiGeneratedModuleFactory\")\n        let implementingClass = try generator.importClass(fullTypeName)\n\n        generator.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: exportedModule.model.comments))\n        generator.appendBody(\"\\n\")\n        generator.appendBody(\"\"\"\n        abstract class \\(jvmClass.name): \\(baseClass.name)<\\(implementingClass.name)>() {\n            override fun getModulePath(): String {\n               return \"\\(exportedModule.modulePath)\"\n            }\n        }\n        \"\"\")\n\n        let data = try generator.content.indented(indentPattern: \"    \").utf8Data()\n\n        output.append(KotlinCodeGenerator.makeNativeSource(bundleInfo: bundleInfo, jvmClass: jvmClass, file: .data(data)))\n\n        return output\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Kotlin/KotlinSchemaWriter.swift",
    "content": "//\n//  KotlinSchemaWriter.swift\n//\n//\n//  Created by Simon Corsin on 1/26/23.\n//\n\nimport Foundation\n\nclass KotlinSchemaWriter: SchemaWriter {\n    init(typeParameters: [ValdiTypeParameter]?, listener: SchemaWriterListener) {\n        super.init(typeParameters: typeParameters,\n                   listener: listener,\n                   alwaysBoxFunctionParametersAndReturnValue: true,\n                   boxIntEnums: false)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Kotlin/KotlinValidation.swift",
    "content": "import Foundation\n\n// Swift doesn't have namespaces, it's customary to use an enum without cases instead\nenum KotlinValidation {\n\n    /// These keywords must be avoided when using identifiers for generated code (e.g. for type names, properties, package name components)\n    static let kotlinKeywords = [\n        \"as\",\n        \"break\",\n        \"class\",\n        \"continue\",\n        \"do\",\n        \"else\",\n        \"false\",\n        \"for\",\n        \"fun\",\n        \"if\",\n        \"in\",\n        \"interface\",\n        \"is\",\n        \"null\",\n        \"object\",\n        \"package\",\n        \"return\",\n        \"super\",\n        \"this\",\n        \"throw\",\n        \"true\",\n        \"try\",\n        \"typealias\",\n        \"typeof\",\n        \"val\",\n        \"var\",\n        \"when\",\n        \"while\"\n    ]\n\n    private static let kotlinKeywordsSet = Set(kotlinKeywords)\n\n    static private let androidRegex = try! NSRegularExpression(pattern: \"^[a-z]+(\\\\.[a-zA-Z_]\\\\w*)*$\")\n    static func isValidAndroidTypeName(androidTypeName: String) -> Bool {\n        guard androidTypeName.matches(regex: androidRegex) else {\n            return false\n        }\n\n        let components = androidTypeName.components(separatedBy: \".\")\n        let noReservedKeywords = components.allSatisfy({ !kotlinKeywordsSet.contains($0.trimmed) })\n        return noReservedKeywords\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/NativeSourceGenerator.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nstruct NativeSourceParameters {\n    let bundleInfo: CompilationItem.BundleInfo\n    let sourceFileName: GeneratedSourceFilename\n    let classMapping: ResolvedClassMapping\n    let iosType: IOSType?\n    let androidTypeName: String?\n    let cppType: CPPType?\n}\n\nprotocol NativeSourceGenerator {\n    func generateSwiftSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource]\n    func generateObjCSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource]\n    func generateKotlinSources(parameters: NativeSourceParameters, fullTypeName: String) throws -> [NativeSource]\n    func generateCppSources(parameters: NativeSourceParameters, cppType: CPPType) throws -> [NativeSource]\n}\n\nextension NativeSourceGenerator {\n    func generate(parameters: NativeSourceParameters) throws -> [NativeSourceAndPlatform] {\n        var sources = [NativeSourceAndPlatform]()\n\n        if let iosType = parameters.iosType {\n            switch parameters.bundleInfo.iosLanguage {\n            case IOSLanguage.swift:\n                sources += try generateSwiftSources(parameters: parameters, type: iosType).map {\n                    NativeSourceAndPlatform(source: $0, platform: .ios)\n                }\n            case IOSLanguage.objc:\n                sources += try generateObjCSources(parameters: parameters, type: iosType).map {\n                    NativeSourceAndPlatform(source: $0, platform: .ios)\n                }\n            case IOSLanguage.both:\n                sources += try generateSwiftSources(parameters: parameters, type: iosType).map {\n                    NativeSourceAndPlatform(source: $0, platform: .ios)\n                }\n                sources += try generateObjCSources(parameters: parameters, type: iosType).map {\n                    NativeSourceAndPlatform(source: $0, platform: .ios)\n                }\n            }\n        }\n\n        if let androidName = parameters.androidTypeName {\n            sources += try generateKotlinSources(parameters: parameters, fullTypeName: androidName).map {\n                NativeSourceAndPlatform(source: $0, platform: .android)\n            }\n        }\n        if let cppType = parameters.cppType {\n            sources += try generateCppSources(parameters: parameters, cppType: cppType).map {\n                NativeSourceAndPlatform(source: $0, platform: .cpp)\n            }\n        }\n\n        return sources\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ObjC/ObjCCodeGenerator.swift",
    "content": "//\n//  ObjCCodeGenerator.swift\n//  Compiler\n//\n//  Created by saniul on 25/03/2019.\n//\n\nimport Foundation\n\nstruct GeneratedCode {\n    let apiHeader: CodeWriter\n    let apiImpl: CodeWriter\n    let header: CodeWriter\n    let impl: CodeWriter\n}\n\nstruct ObjCTypeParser {\n    let typeName: String\n    let propertyAttribute: String\n    let objcSelector: ObjCSelector?\n    let cType: CType\n    // Type name safe to use in the global header scope\n    let headerDeclarationSafeTypeName: String\n    let propertyAdditionalHeaderDeclaration: String?\n}\n\nstruct ObjCProperty {\n    let propertyName: String\n    let modelProperty: ValdiModelProperty\n}\n\nprivate final class ObjCImportSection: CodeWriterContent {\n\n    private(set) var importedClasses = Set<String>()\n\n    func addImport(path: String) {\n        importedClasses.insert(path)\n    }\n\n    var content: String {\n        return importedClasses.sorted().map { \"#import \\($0)\\n\" }.joined()\n    }\n}\n\nprivate final class ObjCForwardDeclarationSection: CodeWriterContent {\n\n    private(set) var forwardsSet = Set<String>()\n\n    func addForwardDeclaration(value: String) {\n        forwardsSet.insert(value)\n    }\n\n    var content: String {\n        return forwardsSet.sorted().map { \"\\($0)\\n\" }.joined()\n    }\n\n}\n\nclass ObjCCodeGenerator: CodeWriter {}\n\nfinal class ObjCFileGenerator: ObjCCodeGenerator {\n\n    private let importSection = ObjCImportSection()\n    private let forwardDeclarationSection = ObjCForwardDeclarationSection()\n    private let declarationSection = JoinedContent(separator: \"\\n\")\n\n    override init() {\n        super.init()\n\n        appendHeader(importSection)\n        appendHeader(\"\\n\")\n        appendHeader(forwardDeclarationSection)\n        appendHeader(\"\\n\")\n        appendHeader(declarationSection)\n        appendHeader(\"\\n\")\n    }\n\n    func addImport(path: String) {\n        importSection.addImport(path: path)\n    }\n\n    func addForwardDeclaration(type: String) {\n        forwardDeclarationSection.addForwardDeclaration(value: type)\n    }\n\n    func addDeclaration(type: String) {\n        declarationSection.append(content: type)\n    }\n\n    func appendSwiftName(_ swiftName: String) {\n        appendBody(\"NS_SWIFT_NAME(\\(swiftName))\")\n    }\n}\n\nstruct ObjCFunctionParameterParser {\n    let name: PropertyName\n    let parser: ObjCTypeParser\n}\n\nstruct ObjCFunctionParser {\n    let parameters: [ObjCFunctionParameterParser]\n    let returnParser: ObjCTypeParser\n    let objcSelector: ObjCSelector?\n    let typeName: String\n    let propertyAdditionalHeaderDeclaration: String?\n\n    init(parameters: [ObjCFunctionParameterParser],\n         returnParser: ObjCTypeParser,\n         objcSelectr: ObjCSelector?,\n         typeName: String,\n         propertyAdditionalHeaderDeclaration: String?) {\n        self.parameters = parameters\n        self.returnParser = returnParser\n        self.objcSelector = objcSelectr\n        self.typeName = typeName\n        self.propertyAdditionalHeaderDeclaration = propertyAdditionalHeaderDeclaration\n    }\n}\n\nfinal class ObjCClassGenerator {\n\n    let nameAllocator = PropertyNameAllocator.forObjC()\n\n    let apiHeader = ObjCFileGenerator()\n    let apiImpl = ObjCFileGenerator()\n\n    let header = ObjCFileGenerator()\n    let impl = ObjCFileGenerator()\n\n    let emittedIdentifiers = ObjCEmittedIdentifiers()\n    let typeArgumentIdentifiers = ObjCEmittedIdentifiers()\n    let emittedFunctions = ObjCEmittedTrampolineFunctions()\n\n    private let className: String\n\n    init(className: String) {\n        self.className = className\n\n        //TODO(3521): Update to valid_core\n        apiHeader.addImport(path: \"<Foundation/Foundation.h>\")\n        apiImpl.addImport(path: \"<valdi_core/SCValdiBuiltinTrampolines.h>\")\n\n        header.addImport(path: \"<valdi_core/SCValdiMarshaller.h>\")\n        impl.addImport(path: \"<valdi_core/SCValdiJSConversionUtils.h>\")\n\n        // We reserve marshaller as a keyword to simplify code gen\n        _ = nameAllocator.allocate(property: \"marshaller\")\n    }\n\n    private func newUniqueType(namePaths: [String], suffix: String) -> PropertyName {\n        let innerIdentifier = namePaths.map { $0.pascalCased }.joined()\n        let identifier = \"\\(className)\\(innerIdentifier)\\(suffix)\"\n\n        // We use the root name allocator since the type will be declared in both the header and impl\n        return nameAllocator.allocate(property: identifier)\n    }\n\n    func writeFunctionTypeParser(returnType: ValdiModelPropertyType,\n                                 parameters: [ValdiModelProperty],\n                                 namePaths: [String],\n                                 isInterface: Bool,\n                                 includesGenericType: Bool,\n                                 nameAllocator: PropertyNameAllocator) throws -> ObjCFunctionParser {\n        let parsers: [ObjCTypeParser] = try parameters.map {\n            // emitMarshall/unmarshall values passed to the arguments parsers is reversed here\n            // If we are marshalling a function, we need unmarshall of the parameters, and we need marshall of return value\n            try writeTypeParser(type: $0.type.unwrappingOptional,\n                                isOptional: $0.type.isOptional,\n                                namePaths: namePaths + [$0.name],\n                                allowValueType: true,\n                                isInterface: false,\n                                nameAllocator: nameAllocator.scoped())\n        }\n\n        let returnParser = try writeTypeParser(type: returnType.unwrappingOptional,\n                                               isOptional: returnType.isOptional,\n                                               namePaths: namePaths + [\"Return\"],\n                                               allowValueType: true,\n                                               isInterface: false,\n                                               nameAllocator: nameAllocator.scoped())\n\n        let parametersAndParsers: [ObjCFunctionParameterParser] = parsers.enumerated().map { index, parser in\n            let name = nameAllocator.allocate(property: parameters[index].name)\n            return ObjCFunctionParameterParser(name: name, parser: parser)\n        }\n\n        let objcSelector: ObjCSelector?\n        let typeName: String\n        var propertyAdditionalHeaderDeclaration: String?\n\n        if isInterface {\n            let methodName = namePaths[0]\n            objcSelector = ObjCSelector(returnType: returnParser.typeName, methodName: methodName, parameters: parametersAndParsers.map { ObjcMessageParameter(name: $0.name.name, type: $0.parser.typeName) })\n            typeName = objcSelector!.messageDeclaration\n        } else {\n            objcSelector = nil\n            let blockName = newUniqueType(namePaths: namePaths, suffix: \"Block\")\n            let headerSafeParameterString = parametersAndParsers.map { propertyAndParser -> String in\n                \"\\(propertyAndParser.parser.headerDeclarationSafeTypeName) \\(propertyAndParser.name)\"\n                }.joined(separator: \", \")\n\n            let headerDeclarationSafeTypeDef = \"typedef \\(returnParser.headerDeclarationSafeTypeName)(^\\(blockName))(\\(headerSafeParameterString));\"\n            typeName = blockName.name\n\n            // we can't use typedefs for any function types that include generic types, since the types are declared _outside_ of a context that declares the type parameters\n            if includesGenericType {\n                let actualParameterString = parametersAndParsers.map { propertyAndParser -> String in\n                    \"\\(propertyAndParser.parser.typeName) \\(propertyAndParser.name)\"\n                    }.joined(separator: \", \")\n                let actualTypeDef = \"typedef \\(returnParser.typeName)(^\\(blockName))(\\(actualParameterString));\"\n                var declarations = parametersAndParsers.compactMap { propertyAndParser -> String? in\n                    propertyAndParser.parser.propertyAdditionalHeaderDeclaration\n                }\n                if let returnAdditionalHeaderDeclaration = returnParser.propertyAdditionalHeaderDeclaration {\n                    declarations.append(returnAdditionalHeaderDeclaration)\n                }\n                declarations.append(actualTypeDef)\n                propertyAdditionalHeaderDeclaration = declarations.joined(separator: \"\\n\")\n            } else {\n                apiHeader.addDeclaration(type: headerDeclarationSafeTypeDef)\n            }\n        }\n\n        emittedFunctions.appendBlockSupportIfNeeded(parameters: parametersAndParsers.map { $0.parser.cType }, returnType: returnParser.cType, functionType: isInterface ? .objcMethod : .block)\n\n        return ObjCFunctionParser(parameters: parametersAndParsers,\n                                  returnParser: returnParser,\n                                  objcSelectr: objcSelector,\n                                  typeName: typeName,\n                                  propertyAdditionalHeaderDeclaration: propertyAdditionalHeaderDeclaration)\n    }\n\n    func ensureTypeAvailability(type: IOSType) {\n        apiHeader.addImport(path: type.importHeaderStatement(kind: .apiOnly))\n        header.addImport(path: type.importHeaderStatement(kind: .withUtilities))\n        if type.kind == .interface {\n            apiHeader.addForwardDeclaration(type: \"@protocol \\(type.name);\")\n        } else if type.kind == .class {\n            apiHeader.addForwardDeclaration(type: \"@class \\(type.name);\")\n        }\n    }\n\n    func writeObjectDescriptorGetter(resolvedProperties: [ObjCProperty],\n                                     objcSelectors: [ObjCSelector?],\n                                     typeParameters: [ValdiTypeParameter]?,\n                                     objectDescriptorType: String) throws -> CodeWriter {\n        let output = ObjCCodeGenerator()\n\n        output.appendBody(\"\"\"\n        + (SCValdiMarshallableObjectDescriptor)valdiMarshallableObjectDescriptor\n        {\n\n        \"\"\")\n\n        let blocksParam: String\n\n        if emittedFunctions.needBlockSupport {\n            blocksParam = \"kBlocks\"\n            output.appendBody(\"static const SCValdiMarshallableObjectBlockSupport \\(blocksParam)[] = {\\n\")\n            output.appendBody(emittedFunctions.blocksSection)\n            output.appendBody(\"{ .typeEncoding = nil },\\n\")\n            output.appendBody(\"};\\n\")\n        } else {\n            blocksParam = \"nil\"\n        }\n\n        output.appendBody(\"static const SCValdiMarshallableObjectFieldDescriptor kFields[] = {\\n\")\n\n        for (index, objcProperty) in resolvedProperties.enumerated() {\n            let selName: String\n            let objcSelector = objcSelectors[index]\n            if let objcSelector = objcSelector {\n                selName = \"\\\"\\(objcSelector.selectorName)\\\"\"\n            } else if objcProperty.propertyName != objcProperty.modelProperty.name {\n                selName = \"\\\"\\(objcProperty.propertyName)\\\"\"\n            } else {\n                selName = \"nil\"\n            }\n\n            let schemaWriter = ObjCSchemaWriter(typeParameters: typeParameters, emittedIdentifiers: emittedIdentifiers)\n            try schemaWriter.appendType(objcProperty.modelProperty.type, asBoxed: false, isMethod: objcSelector != nil)\n\n            output.appendBody(\"{.name = \\\"\\(objcProperty.modelProperty.name)\\\", .selName = \\(selName), .type = \\\"\\(schemaWriter.str)\\\"},\\n\")\n        }\n\n        output.appendBody(\"{.name = nil},\\n\")\n        output.appendBody(\"};\\n\")\n\n        let identifiersParam: String\n\n        if !emittedIdentifiers.isEmpty {\n            identifiersParam = \"kIdentifiers\"\n\n            output.appendBody(\"static const char *const \\(identifiersParam)[] = \")\n            output.appendBody(emittedIdentifiers.initializationString)\n            output.appendBody(\";\\n\")\n        } else {\n            identifiersParam = \"nil\"\n        }\n\n        output.appendBody(\"return SCValdiMarshallableObjectDescriptorMake(kFields, \\(identifiersParam), \\(blocksParam), \\(objectDescriptorType));\\n\")\n\n        output.appendBody(\"}\\n\\n\")\n\n        return output\n    }\n\n    func writeTypeParser(type: ValdiModelPropertyType,\n                         isOptional: Bool,\n                         namePaths: [String],\n                         allowValueType: Bool,\n                         isInterface: Bool,\n                         nameAllocator: PropertyNameAllocator,\n                         typeParameterSafe: Bool = false) throws -> ObjCTypeParser {\n        let typeName: String\n        let cElementType: CType\n\n        var isVoid = false\n        var objcSelector: ObjCSelector?\n        var propertyAttribute: String\n        var propertyAdditionalHeaderDeclaration: String?\n        var headerDeclarationSafeTypeNameOverride: String?\n\n        switch type {\n        case .string:\n            typeName = \"NSString *\"\n            propertyAttribute = \"copy\"\n            cElementType = .pointer\n        case .double:\n            if isOptional || !allowValueType {\n                typeName = \"NSNumber *\"\n                propertyAttribute = \"strong\"\n                cElementType = .pointer\n            } else {\n                typeName = \"double\"\n                propertyAttribute = \"assign\"\n                cElementType = .double\n            }\n        case .bool:\n            if isOptional || !allowValueType {\n                typeName = \"NSNumber *\"\n                propertyAttribute = \"strong\"\n                cElementType = .pointer\n            } else {\n                typeName = \"BOOL\"\n                propertyAttribute = \"assign\"\n                cElementType = .bool\n            }\n        case .long:\n            if isOptional || !allowValueType {\n                typeName = \"NSNumber *\"\n                propertyAttribute = \"strong\"\n                cElementType = .pointer\n            } else {\n                typeName = \"int64_t\"\n                propertyAttribute = \"assign\"\n                cElementType = .long\n            }\n        case .array(let elementType):\n            let childParser = try writeTypeParser(type: elementType.unwrappingOptional,\n                                                  isOptional: elementType.isOptional,\n                                                  namePaths: namePaths + [\"element\"],\n                                                  allowValueType: false,\n                                                  isInterface: false,\n                                                  nameAllocator: nameAllocator.scoped(),\n                                                  typeParameterSafe: true)\n\n            propertyAdditionalHeaderDeclaration = childParser.propertyAdditionalHeaderDeclaration\n            typeName = \"NSArray<\\(childParser.typeName)> *\"\n            headerDeclarationSafeTypeNameOverride = \"NSArray<\\(childParser.headerDeclarationSafeTypeName)> *\"\n            propertyAttribute = \"copy\"\n            cElementType = .pointer\n        case .bytes:\n            typeName = \"NSData *\"\n            propertyAttribute = \"copy\"\n            cElementType = .pointer\n        case .map:\n            typeName = \"NSDictionary <NSString *, id> *\"\n            propertyAttribute = \"copy\"\n            cElementType = .pointer\n        case .any:\n            typeName = \"NSObject *\"\n            propertyAttribute = \"strong\"\n            cElementType = .pointer\n        case .void:\n            if typeParameterSafe {\n                let undefinedImportPath = \"<valdi_core/SCValdiUndefinedValue.h>\"\n                apiHeader.addImport(path: undefinedImportPath)\n                header.addImport(path: undefinedImportPath)\n\n                typeName = \"SCValdiUndefinedValue *\"\n                propertyAttribute = \"strong\"\n                cElementType = .pointer\n            } else {\n                typeName = \"void\"\n                propertyAttribute = \"\"\n                isVoid = true\n                cElementType = .void\n            }\n        case .function(let parameters, let returnType, _, _):\n            let functionParser = try writeFunctionTypeParser(returnType: returnType,\n                                                             parameters: parameters,\n                                                             namePaths: namePaths,\n                                                             isInterface: isInterface,\n                                                             includesGenericType: type.includesGenericType,\n                                                             nameAllocator: nameAllocator)\n\n            typeName = functionParser.typeName\n            objcSelector = functionParser.objcSelector\n            propertyAdditionalHeaderDeclaration = functionParser.propertyAdditionalHeaderDeclaration\n            propertyAttribute = \"copy\"\n            cElementType = .pointer\n        case .enum(let mapping):\n            guard let resolvedType = mapping.iosType else {\n                throw CompilerError(\"No iOS type declared\")\n            }\n\n            ensureTypeAvailability(type: resolvedType)\n\n            if mapping.kind == .enum && (isOptional || !allowValueType) {\n                typeName = \"NSNumber *\"\n                propertyAttribute = \"strong\"\n                cElementType = .pointer\n            } else {\n                if isOptional {\n                    typeName = ObjCEnumGenerator.nullableTypeName(typename: resolvedType.name)\n                } else {\n                    typeName = resolvedType.name\n                }\n\n                if mapping.kind == .stringEnum {\n                    propertyAttribute = \"copy\"\n                    cElementType = .pointer\n                } else {\n                    propertyAttribute = \"assign\"\n                    cElementType = .int\n                }\n            }\n        case .genericTypeParameter(let name):\n            typeName = name\n            headerDeclarationSafeTypeNameOverride = \"id\"\n            propertyAttribute = \"strong\"\n            cElementType = .pointer\n        case .genericObject(let mapping, let typeArguments):\n            guard let resolvedType = mapping.iosType else {\n                throw CompilerError(\"No iOS type declared\")\n            }\n\n            ensureTypeAvailability(type: resolvedType)\n\n            guard case .class = mapping.kind else {\n                throw CompilerError(\"Generic object must be a class, not a protocol\")\n            }\n\n            let typeArgumentsParsers: [ObjCTypeParser] = try typeArguments.map {\n                let typeArgumentTypeParser = try writeTypeParser(type: $0,\n                                                             isOptional: $0.isOptional,\n                                                             namePaths: namePaths,\n                                                             allowValueType: false,\n                                                             isInterface: false,\n                                                             nameAllocator: nameAllocator)\n                return typeArgumentTypeParser\n            }\n            let typeArgumentsList = typeArgumentsParsers.map(\\.headerDeclarationSafeTypeName).joined(separator: \", \")\n            let resolvedTypeName = \"\\(resolvedType.name)<\\(typeArgumentsList)> *\"\n            propertyAdditionalHeaderDeclaration = typeArgumentsParsers.compactMap(\\.propertyAdditionalHeaderDeclaration).joined(separator: \"\\n\")\n\n            typeName = resolvedTypeName\n\n            guard mapping.isGenerated else {\n                throw CompilerError(\"Generic objects must be generated\")\n            }\n            propertyAttribute = \"strong\"\n            cElementType = .pointer\n        case .object(let mapping):\n            guard let resolvedType = mapping.iosType else {\n                throw CompilerError(\"No iOS type declared\")\n            }\n\n            ensureTypeAvailability(type: resolvedType)\n\n            let resolvedTypeName: String\n            switch mapping.kind {\n            case .interface:\n                resolvedTypeName = \"id<\\(resolvedType.name)>\"\n            case .class:\n                resolvedTypeName = \"\\(resolvedType.name) *\"\n            case .enum, .stringEnum:\n                resolvedTypeName = resolvedType.name\n            }\n\n            typeName = resolvedTypeName\n            propertyAttribute = \"strong\"\n            cElementType = .pointer\n        case .promise(let typeArgument):\n            let promiseImportPath = \"<valdi_core/SCValdiPromise.h>\"\n            apiHeader.addImport(path: promiseImportPath)\n            header.addImport(path: promiseImportPath)\n\n            let childParser = try writeTypeParser(type: typeArgument.unwrappingOptional,\n                                                  isOptional: typeArgument.isOptional,\n                                                  namePaths: namePaths + [\"element\"],\n                                                  allowValueType: false,\n                                                  isInterface: false,\n                                                  nameAllocator: nameAllocator.scoped(),\n                                                  typeParameterSafe: true)\n\n            propertyAdditionalHeaderDeclaration = childParser.propertyAdditionalHeaderDeclaration\n            typeName = \"SCValdiPromise<\\(childParser.typeName)> *\"\n            headerDeclarationSafeTypeNameOverride = \"SCValdiPromise<\\(childParser.headerDeclarationSafeTypeName)> *\"\n            propertyAttribute = \"strong\"\n            cElementType = .pointer\n        case .nullable(let type):\n            return try writeTypeParser(type: type, isOptional: true, namePaths: namePaths, allowValueType: false, isInterface: isInterface, nameAllocator: nameAllocator)\n        }\n\n        let isObjCMessage = objcSelector != nil\n\n        func resolveTypeName(_ typeName: String) -> String {\n            if isOptional && !isObjCMessage {\n                if !isVoid && !isObjCMessage && allowValueType && !typeParameterSafe {\n                    return \"\\(typeName) _Nullable\"\n                }\n            } else {\n                if !propertyAttribute.contains(\"assign\") && !isVoid && !isObjCMessage && allowValueType && !typeParameterSafe {\n                    return \"\\(typeName) _Nonnull\"\n                }\n            }\n            return typeName\n        }\n\n        let resolvedTypeName = resolveTypeName(typeName)\n        let headerDeclarationSafeTypeName = headerDeclarationSafeTypeNameOverride.map(resolveTypeName) ?? resolvedTypeName\n\n        return ObjCTypeParser(typeName: resolvedTypeName,\n                              propertyAttribute: propertyAttribute,\n                              objcSelector: objcSelector,\n                              cType: cElementType,\n                              headerDeclarationSafeTypeName: headerDeclarationSafeTypeName,\n                              propertyAdditionalHeaderDeclaration: propertyAdditionalHeaderDeclaration)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ObjC/ObjCDependencyRepresentationGenerator.swift",
    "content": "//\n//  ObjCDependencyRepresentationGenerator.swift\n//\n//\n//  Created by John Corbett on 5/16/23.\n//\n\nimport Foundation\n\nfinal class ObjCDependencyRepresentationGenerator {\n    private struct ContextFactoryProperty: Encodable {\n        let qualifiedType: String\n        let name: String\n        let propertyAttribute: String\n        let injectable: Bool\n    }\n\n    private let items: [IntermediateDependencyMetadata]\n\n    init(items: [IntermediateDependencyMetadata]) {\n        self.items = items\n    }\n\n    func generate() throws -> File {\n        let out = try items.reduce(into: [String: [ContextFactoryProperty]]()) { initialItems, dependencyMetadata in\n            let model = dependencyMetadata.model\n\n            guard let iosType = model.iosType else {\n                return\n            }\n\n            let className = iosType.name\n            let objcGenerator = ObjCClassGenerator(className: className)\n\n            let nameAllocator = PropertyNameAllocator.forObjC()\n\n            let properties = try model.properties.map { property in\n                let typeParser = try objcGenerator.writeTypeParser(type: property.type.unwrappingOptional,\n                                                                   isOptional: property.type.isOptional,\n                                                                   namePaths: [property.name],\n                                                                   allowValueType: true,\n                                                                   isInterface: model.exportAsInterface,\n                                                                   nameAllocator: nameAllocator.scoped())\n\n                return ContextFactoryProperty(qualifiedType: typeParser.typeName,\n                                              name: property.name,\n                                              propertyAttribute: typeParser.propertyAttribute,\n                                              injectable: property.injectableParams.compatibility.contains(.ios))\n            }\n\n            initialItems[className] = properties\n        }\n\n        let encoder = JSONEncoder()\n        encoder.outputFormatting = .sortedKeys\n\n        let data: Data\n        do {\n            data = try encoder.encode(out)\n        } catch {\n            throw CompilerError(\"Failed to encode dependency metadata\")\n        }\n\n        return File.data(data)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ObjC/ObjCEmittedIdentifiers.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 6/9/20.\n//\n\nimport Foundation\n\nclass ObjCEmittedIdentifiers: EmittedIdentifiers {\n\n    var initializationString: CodeWriter {\n        let out = CodeWriter()\n        out.appendBody(\"{\\n\")\n\n        for identifier in identifiers {\n            out.appendBody(\"\\\"\\(identifier)\\\"\")\n            out.appendBody(\",\\n\")\n        }\n        out.appendBody(\"nil\\n\")\n\n        out.appendBody(\"}\")\n        return out\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ObjC/ObjCEmittedTrampolineFunctions.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 6/5/20.\n//\n\nimport Foundation\n\nenum CType {\n    case void\n    case pointer\n    case double\n    case bool\n    case int\n    case long\n    case nsobject\n\n    var typeEncoding: String {\n        switch self {\n        case .void:\n            return \"v\"\n        case .pointer:\n            return \"o\"\n        case .double:\n            return \"d\"\n        case .bool:\n            return \"b\"\n        case .int:\n            return \"i\"\n        case .long:\n            return \"l\"\n        case .nsobject:\n            return \"o\"\n        }\n    }\n\n    var cName: String {\n        switch self {\n        case .void:\n            return \"void\"\n        case .pointer:\n            return \"const void *\"\n        case .double:\n            return \"double\"\n        case .bool:\n            return \"BOOL\"\n        case .int:\n            return \"int32_t\"\n        case .long:\n            return \"int64_t\"\n        case .nsobject:\n            return \"id\"\n        }\n    }\n\n    var makeFieldValueFunctionName: String {\n        switch self {\n        case .void:\n            return \"SCValdiFieldValueMakeNull\"\n        case .pointer:\n            return \"SCValdiFieldValueMakePtr\"\n        case .double:\n            return \"SCValdiFieldValueMakeDouble\"\n        case .bool:\n            return \"SCValdiFieldValueMakeBool\"\n        case .int:\n            return \"SCValdiFieldValueMakeInt\"\n        case .long:\n            return \"SCValdiFieldValueMakeLong\"\n        case .nsobject:\n            return \"SCValdiFieldValueMakeUnretainedObject\"\n        }\n    }\n\n    var getFieldValueFunctionName: String {\n        switch self {\n        case .void:\n            return \"void\"\n        case .pointer:\n            return \"SCValdiFieldValueGetPtr\"\n        case .double:\n            return \"SCValdiFieldValueGetDouble\"\n        case .bool:\n            return \"SCValdiFieldValueGetBool\"\n        case .int:\n            return \"SCValdiFieldValueGetInt\"\n        case .long:\n            return \"SCValdiFieldValueGetLong\"\n        case .nsobject:\n            return \"SCValdiFieldValueGetObject\"\n        }\n    }\n\n    var defaultValue: String {\n        switch self {\n            case .void:\n                return \"void\"\n            case .pointer:\n                return \"nil\"\n            case .double:\n                return \"0.0\"\n            case .bool:\n                return \"FALSE\"\n            case .int:\n                return \"0\"\n            case .long:\n                return \"0\"\n            case .nsobject:\n                return \"nil\"\n        }\n    }\n\n    var convertingPointerToNSObject: CType {\n        if case .pointer = self {\n            return .nsobject\n        }\n        return self\n    }\n}\n\nenum CFunctionType {\n    case block\n    case objcMethod\n}\n\nstruct ObjCTrampolineCallArgument {\n    let name: String\n    let type: CType\n}\n\nclass ObjCEmittedTrampolineFunctions {\n\n    /**\n     Type signature that the runtime already supports.\n     For those we don't need to emit trampoline funcitons\n     */\n    static let builtinTypeSignatures: Set<String> = [\n        \"o:v\", \"oo:v\", \"ooo:v\", \"oooo:v\", \"ooooo:v\", \"oooooo:v\",\n        \"o:o\", \"oo:o\", \"ooo:o\", \"oooo:o\",\n        \"o:b\", \"oo:b\", \"ooo:b\",\n        \"o:d\", \"oo:d\", \"ooo:d\"\n    ]\n\n    let emittedFunctionsSection = ObjCCodeGenerator()\n    let blocksSection = ObjCCodeGenerator()\n\n    var needBlockSupport: Bool {\n        return !emittedBlockSupportSignatures.isEmpty\n    }\n\n    private var emittedBlockSupportSignatures: Set<String> = []\n\n    func appendBlockSupportIfNeeded(parameters: [CType], returnType: CType, functionType: CFunctionType) {\n        let resolvedParameters: [CType]\n        switch functionType {\n        case .block:\n            // The first parameter of the block in the Objective-C block ABI is always the block itself\n            resolvedParameters = [CType.pointer] + parameters\n        case .objcMethod:\n            // Objective-C methods take the receiver and the selector as the first two parameters\n            resolvedParameters = [CType.pointer, CType.pointer] + parameters\n        }\n\n        let parametersTypeEncoding = resolvedParameters.map { $0.typeEncoding }.joined()\n\n        let functionTypeSignature = \"\\(parametersTypeEncoding):\\(returnType.typeEncoding)\"\n\n        if ObjCEmittedTrampolineFunctions.builtinTypeSignatures.contains(functionTypeSignature) {\n            // The runtime already supports this type signature\n            return\n        }\n\n        if emittedBlockSupportSignatures.contains(functionTypeSignature) {\n            // We already emitted a trampoline function for this type signature\n            return\n        }\n        emittedBlockSupportSignatures.insert(functionTypeSignature)\n\n        appendTrampoline(typeEncoding: functionTypeSignature, parametersTypeEncoding: parametersTypeEncoding, parameters: resolvedParameters, returnType: returnType)\n    }\n\n    private func appendTrampoline(typeEncoding: String, parametersTypeEncoding: String, parameters: [CType], returnType: CType) {\n        let functionNameSuffix = \"\\(parametersTypeEncoding.uppercased())_\\(returnType.typeEncoding)\"\n        // If additional function names are added, make sure to update the logic in CombineNativeSourcesProcessor.swift\n        // that looks for trampoline function definitions in order to deduplicate them (see trampolineFunctionName)\n        let invokeFunctionName = \"SCValdiFunctionInvoke\\(functionNameSuffix)\"\n        let createBlockFunctionName = \"SCValdiBlockCreate\\(functionNameSuffix)\"\n\n        appendInvokeFunction(functionName: invokeFunctionName, parameters: parameters, returnType: returnType)\n        appendCreateBlockFunction(functionName: createBlockFunctionName, parameters: parameters, returnType: returnType)\n        appendBlockSupportDeclaration(typeEncoding: typeEncoding, invokeFunctionName: invokeFunctionName, createBlockFunctionName: createBlockFunctionName)\n    }\n\n    private func appendBlockSupportDeclaration(typeEncoding: String, invokeFunctionName: String, createBlockFunctionName: String) {\n        blocksSection.appendBody(\"{ .typeEncoding = \\\"\\(typeEncoding)\\\", .invoker = &\\(invokeFunctionName), .factory = &\\(createBlockFunctionName) },\\n\")\n    }\n\n    private func appendInvokeFunction(functionName: String, parameters: [CType], returnType: CType) {\n        let functionBody = CodeWriter()\n\n        emittedFunctionsSection.appendBody(\"static SCValdiFieldValue \\(functionName)(const void *function, SCValdiFieldValue* fields) {\\n\")\n        emittedFunctionsSection.appendBody(functionBody)\n        emittedFunctionsSection.appendBody(\"}\\n\\n\")\n\n        let callArguments = parameters.enumerated().map { \"\\($0.element.getFieldValueFunctionName)(fields[\\($0.offset)])\" }.joined(separator: \", \")\n\n        let cFunctionPointerType = \"(\\(returnType.cName) (*) (\\(parameters.map { $0.cName }.joined(separator: \", \")) ))\"\n\n        let callExpression = \"(\\(cFunctionPointerType)function)(\\(callArguments))\"\n\n        if case .void = returnType {\n            functionBody.appendBody(\"\\(callExpression);\\n\")\n            functionBody.appendBody(\"return \\(returnType.makeFieldValueFunctionName)();\\n\")\n        } else {\n            functionBody.appendBody(\"\\(returnType.cName) result = \\(callExpression);\\n\")\n            functionBody.appendBody(\"return \\(returnType.makeFieldValueFunctionName)(result);\\n\")\n        }\n    }\n\n    private func appendCreateBlockFunction(functionName: String, parameters: [CType], returnType: CType) {\n        let functionBody = CodeWriter()\n\n        emittedFunctionsSection.appendBody(\"static id \\(functionName)(SCValdiBlockTrampoline trampoline) {\\n\")\n        emittedFunctionsSection.appendBody(functionBody)\n        emittedFunctionsSection.appendBody(\"}\\n\\n\")\n\n        // The first parameter is already present in the block\n        let resolvedParameters = parameters[1...]\n\n        let callArguments = resolvedParameters.enumerated().map { ObjCTrampolineCallArgument(name: \"p\\($0.offset)\", type: $0.element) }\n\n        let blockArguments = callArguments.map { \"\\($0.type.cName) \\($0.name)\" }.joined(separator: \", \")\n\n        functionBody.appendBody(\"return ^\\(returnType.cName)(\\(blockArguments)) {\\n\")\n\n        ObjCEmittedTrampolineFunctions.appendTrampolineCall(output: functionBody, trampolineVar: \"trampoline\", receiver: \"nil\", arguments: callArguments, returnType: returnType)\n        functionBody.appendBody(\"};\\n\")\n    }\n\n    static func appendTrampolineCall(output: CodeWriter, trampolineVar: String, receiver: String, arguments: [ObjCTrampolineCallArgument], returnType: CType) {\n        if case .void = returnType {\n            appendTrampolineCallBody(output: output, trampolineVar: trampolineVar, receiver: receiver, arguments: arguments)\n            output.appendBody(\";\\n\")\n        } else {\n            output.appendBody(\"return \\(returnType.getFieldValueFunctionName)(\")\n            appendTrampolineCallBody(output: output, trampolineVar: trampolineVar, receiver: receiver, arguments: arguments)\n            output.appendBody(\");\\n\")\n        }\n    }\n\n    private static func appendTrampolineCallBody(output: CodeWriter, trampolineVar: String, receiver: String, arguments: [ObjCTrampolineCallArgument]) {\n        output.appendBody(\"\\(trampolineVar)(\\(receiver)\")\n\n        if !arguments.isEmpty {\n            output.appendBody(\", \")\n            let argumentsString = arguments.map { \"\\($0.type.makeFieldValueFunctionName)(\\($0.name))\" }.joined(separator: \", \")\n            output.appendBody(argumentsString)\n        }\n\n        output.appendBody(\")\")\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ObjC/ObjCFunctionGenerator.swift",
    "content": "//\n//  ObjCFunctionGenerator.swift\n//  Compiler\n//\n//  Created by saniul on 12/04/2019.\n//\n\nimport Foundation\n\nfinal class ObjCFunctionGenerator {\n    private let iosType: IOSType\n    private let typeName: String\n    private let exportedFunction: ExportedFunction\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n    private let bundleName: String\n    private let modulePath: String\n    private let bundleInfo: CompilationItem.BundleInfo\n\n    init(iosType: IOSType, exportedFunction: ExportedFunction, classMapping: ResolvedClassMapping, sourceFileName: GeneratedSourceFilename, bundleName: String, modulePath: String, bundleInfo: CompilationItem.BundleInfo) {\n        self.iosType = iosType\n        self.typeName = iosType.name\n        self.exportedFunction = exportedFunction\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.bundleName = bundleName\n        self.modulePath = modulePath\n        self.bundleInfo = bundleInfo\n    }\n\n    private func generateCode() throws -> GeneratedCode {\n        let classGenerator = ObjCClassGenerator(className: typeName)\n\n        // TODO(3521): Update to valdi_core\n        classGenerator.header.addImport(path: \"<valdi_core/SCValdiBridgeFunction.h>\")\n        classGenerator.impl.addImport(path: \"<valdi_core/SCValdiMarshallableObjectRegistry.h>\")\n\n        let callBlockVariable = classGenerator.nameAllocator.allocate(property: \"callBlock\")\n\n        let functionParser = try classGenerator.writeFunctionTypeParser(returnType: exportedFunction.returnType, parameters: exportedFunction.parameters, namePaths: [], isInterface: false, includesGenericType: false, nameAllocator: classGenerator.nameAllocator)\n\n        let objcSelector = ObjCSelector(returnType: functionParser.returnParser.typeName,\n                                        methodName: exportedFunction.functionName,\n                                        parameters: functionParser.parameters.map { ObjcMessageParameter(name: $0.name.name, type: $0.parser.typeName) })\n\n        let comments = FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: exportedFunction.comments)\n\n        var messageDeclaration = \"\"\n        if let comments = exportedFunction.comments, !comments.isEmpty {\n            messageDeclaration = FileHeaderCommentGenerator.generateMultilineComment(comment: comments)\n            messageDeclaration.append(\"\\n\")\n        }\n        messageDeclaration.append(objcSelector.messageDeclaration)\n        messageDeclaration.append(\";\")\n\n        // Generate invokeWithJSRuntime static method signature\n        let jsRuntimeProviderType = \"id<SCValdiJSRuntime> _Nonnull (^ _Nonnull)(void)\"\n        var invokeWithJSRuntimeSelectorParts: [String] = []\n        \n        // First part with jsRuntimeProvider\n        invokeWithJSRuntimeSelectorParts.append(\"invokeWithJSRuntimeProvider:(\\(jsRuntimeProviderType))jsRuntimeProvider\")\n        \n        // Add original function parameters\n        for param in functionParser.parameters {\n            invokeWithJSRuntimeSelectorParts.append(\"\\(param.name.name):(\\(param.parser.typeName))\\(param.name.name)\")\n        }\n        \n        // Add completionHandler parameter (using completionHandler to avoid naming conflicts)\n        let completionBlockType: String\n        if functionParser.returnParser.cType == .void {\n            completionBlockType = \"void (^ _Nonnull)(void)\"\n        } else {\n            completionBlockType = \"void (^ _Nonnull)(\\(functionParser.returnParser.typeName))\"\n        }\n        invokeWithJSRuntimeSelectorParts.append(\"completionHandler:(\\(completionBlockType))completionHandler\")\n        \n        let invokeWithJSRuntimeDeclaration = \"+ (void)\\(invokeWithJSRuntimeSelectorParts.joined(separator: \" \"))\"\n\n        classGenerator.header.appendBody(\"\"\"\n            \\(comments)\n            @interface \\(typeName): SCValdiBridgeFunction\n\n            \\(messageDeclaration);\n\n            \\(invokeWithJSRuntimeDeclaration);\n\n            @end\n\n        \"\"\")\n\n        let objcProperty = ObjCProperty(propertyName: exportedFunction.functionName, modelProperty:\n                                            ValdiModelProperty(name: exportedFunction.functionName,\n                                                                  type: .function(parameters: exportedFunction.parameters, returnType: exportedFunction.returnType, isSingleCall: false, shouldCallOnWorkerThread: false),\n                                                                  comments: nil,\n                                                                  omitConstructor: nil,\n                                                                  injectableParams: .empty))\n        let objectDescriptor = try classGenerator.writeObjectDescriptorGetter(resolvedProperties: [objcProperty],\n                                                                              objcSelectors: [nil],\n                                                                              typeParameters: nil,\n                                                                              objectDescriptorType: \"SCValdiMarshallableObjectTypeFunction\")\n\n        let messageForwarder = ObjCCodeGenerator()\n        messageForwarder.appendBody(objcSelector.messageDeclaration)\n        messageForwarder.appendBody(\"{\\n\")\n        messageForwarder.appendBody(\"\\(functionParser.typeName) \\(callBlockVariable.name) = (\\(functionParser.typeName))self.\\(callBlockVariable);\\n\")\n\n        let callBody = \"\\(callBlockVariable)(\\(objcSelector.parameters.map { $0.name }.joined(separator: \", \") ))\"\n        if functionParser.returnParser.cType == .void {\n            messageForwarder.appendBody(callBody)\n        } else {\n            messageForwarder.appendBody(\"return \")\n            messageForwarder.appendBody(callBody)\n        }\n        messageForwarder.appendBody(\";\\n\")\n        messageForwarder.appendBody(\"}\\n\")\n\n        classGenerator.impl.appendBody(classGenerator.emittedFunctions.emittedFunctionsSection)\n        classGenerator.impl.appendBody(\"\"\"\n        @implementation \\(typeName)\n\n        + (NSString *)modulePath\n        {\n          return @\"\\(bundleName)/\\(modulePath)\";\n        }\n\n        + (BOOL)asyncStrictMode\n        {\n          return \\(bundleInfo.asyncStrictMode ? \"YES\" : \"NO\");\n        }\n\n        \"\"\")\n\n        classGenerator.impl.appendBody(messageForwarder)\n        classGenerator.impl.appendBody(\"\\n\")\n        \n        // Generate invokeWithJSRuntime implementation\n        let invokeWithJSRuntimeImpl = ObjCCodeGenerator()\n        invokeWithJSRuntimeImpl.appendBody(\"\\(invokeWithJSRuntimeDeclaration)\\n\")\n        invokeWithJSRuntimeImpl.appendBody(\"{\\n\")\n        invokeWithJSRuntimeImpl.appendBody(\"  id<SCValdiJSRuntime> runtime = jsRuntimeProvider();\\n\")\n        invokeWithJSRuntimeImpl.appendBody(\"  [runtime dispatchInJsThread:^{\\n\")\n        invokeWithJSRuntimeImpl.appendBody(\"    \\(typeName) *function = [\\(typeName) functionWithJSRuntime:runtime];\\n\")\n        invokeWithJSRuntimeImpl.appendBody(\"    \\(functionParser.typeName) \\(callBlockVariable.name) = (\\(functionParser.typeName))function.\\(callBlockVariable);\\n\")\n        let directCallBody = \"\\(callBlockVariable)(\\(objcSelector.parameters.map { $0.name }.joined(separator: \", \")))\"\n        \n        if functionParser.returnParser.cType == .void {\n            invokeWithJSRuntimeImpl.appendBody(\"    \\(directCallBody);\\n\")\n            invokeWithJSRuntimeImpl.appendBody(\"    completionHandler();\\n\")\n        } else {\n            invokeWithJSRuntimeImpl.appendBody(\"    \\(functionParser.returnParser.typeName) result = \\(directCallBody);\\n\")\n            invokeWithJSRuntimeImpl.appendBody(\"    completionHandler(result);\\n\")\n        }\n        \n        invokeWithJSRuntimeImpl.appendBody(\"  }];\\n\")\n        invokeWithJSRuntimeImpl.appendBody(\"}\\n\")\n        invokeWithJSRuntimeImpl.appendBody(\"\\n\")\n        \n        classGenerator.impl.appendBody(invokeWithJSRuntimeImpl)\n        classGenerator.impl.appendBody(objectDescriptor)\n        classGenerator.impl.appendBody(\"\\n\")\n        classGenerator.impl.appendBody(\"@end\\n\")\n\n        return GeneratedCode(apiHeader: classGenerator.apiHeader, apiImpl: classGenerator.apiImpl, header: classGenerator.header, impl: classGenerator.impl)\n    }\n\n    func write() throws -> [NativeSource] {\n        let generatedCode = try generateCode()\n        let nativeSources = try NativeSource.iosNativeSourcesFromGeneratedCode(generatedCode,\n                                                                               iosType: iosType,\n                                                                               bundleInfo: bundleInfo)\n\n        return nativeSources\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ObjC/ObjCModuleGenerator.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nfinal class ObjCModuleGenerator {\n    private let iosType: IOSType\n    private let exportedModule: ExportedModule\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n\n    init(iosType: IOSType,\n         exportedModule: ExportedModule,\n         bundleInfo: CompilationItem.BundleInfo,\n         classMapping: ResolvedClassMapping,\n         sourceFileName: GeneratedSourceFilename) {\n        self.iosType = iosType\n        self.exportedModule = exportedModule\n        self.bundleInfo = bundleInfo\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n    }\n\n    private func generateCode(iosType: IOSType) throws -> GeneratedCode {\n        let implementingType = self.iosType\n        let header = ObjCFileGenerator()\n        let impl = ObjCFileGenerator()\n\n        header.addImport(path: \"<valdi_core/SCValdiGeneratedModuleFactory.h>\")\n        header.addImport(path: \"\\\"\\(implementingType.importHeaderFilename(kind: .apiOnly))\\\"\")\n\n        let comments = \"\"\"\n        Subclasses of this class must implement the onLoadModule method\n        and return an object implementing \\(implementingType.name).\n        \"\"\".trimmed\n\n        header.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: comments))\n        header.appendBody(\"\"\"\n        \n        @interface \\(iosType.name): SCValdiGeneratedModuleFactory\n        \n        - (id<\\(implementingType.name)> _Nonnull)onLoadModule;\n        \n        @end\n        \"\"\")\n\n        impl.appendBody(\"\"\"\n        @implementation \\(iosType.name)\n\n        - (id<\\(implementingType.name)>)onLoadModule\n        {\n          return [self onLoadModule];\n        }\n                \n        - (NSString *)getModulePath\n        {\n          return @\"\\(exportedModule.modulePath)\";\n        }\n        \n        - (Protocol *)moduleProtocol\n        {\n          return @protocol(\\(implementingType.name));\n        }\n        \n        @end\n        \"\"\")\n\n        return GeneratedCode(apiHeader: header, apiImpl: impl, header: CodeWriter(), impl: CodeWriter())\n    }\n\n    func write() throws -> [NativeSource] {\n        var output: [NativeSource] = []\n\n        let iosGenerator = ObjCModelGenerator(iosType: iosType,\n                                              bundleInfo: bundleInfo,\n                                              typeParameters: nil,\n                                              properties: exportedModule.model.properties,\n                                              classMapping: classMapping,\n                                              sourceFileName: sourceFileName,\n                                              isInterface: true,\n                                              emitLegacyConstructors: exportedModule.model.legacyConstructors,\n                                              comments: exportedModule.model.comments)\n\n        output += try iosGenerator.write()\n\n        let resolvedIOSType = IOSType(name: \"\\(self.iosType.name)Factory\", bundleInfo: bundleInfo, kind: self.iosType.kind, iosLanguage: self.iosType.iosLanguage)\n\n        let code = try generateCode(iosType: resolvedIOSType)\n\n        output += try NativeSource.iosNativeSourcesFromGeneratedCode(code, iosType: resolvedIOSType, bundleInfo: bundleInfo)\n\n        return output\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ObjC/ObjCSchemaWriter.swift",
    "content": "//\n//  ObjCSchemaWriter.swift\n//  \n//\n//  Created by Simon Corsin on 1/26/23.\n//\n\nimport Foundation\n\nclass ObjCSchemaWriterListener: SchemaWriterListener {\n\n    private let emittedIdentifiers: ObjCEmittedIdentifiers\n\n    init(emittedIdentifiers: ObjCEmittedIdentifiers) {\n        self.emittedIdentifiers = emittedIdentifiers\n    }\n\n    func getClassName(nodeMapping: ValdiNodeClassMapping, typeArguments: [ValdiModelPropertyType]?) throws -> String? {\n        guard let iosType = nodeMapping.iosType else {\n            throw CompilerError(\"No iOS type in given mapping\")\n        }\n\n        let identifierIndex = emittedIdentifiers.getIdentifierIndex(iosType.name)\n\n        return \"[\\(identifierIndex)]\"\n    }\n}\n\nclass ObjCSchemaWriter: SchemaWriter {\n    init(typeParameters: [ValdiTypeParameter]?, emittedIdentifiers: ObjCEmittedIdentifiers) {\n        super.init(typeParameters: typeParameters,\n                   listener: ObjCSchemaWriterListener(emittedIdentifiers: emittedIdentifiers),\n                   alwaysBoxFunctionParametersAndReturnValue: false,\n                   boxIntEnums: true)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/ObjC/ObjCValidation.swift",
    "content": "import Foundation\n\n// Swift doesn't have namespaces, it's customary to use an enum without cases instead\nenum ObjCValidation {\n\n    /// These keywords must be avoided when using identifiers for generated code (e.g. type names, properties)\n    ///\n    /// https://www.oreilly.com/library/view/learning-objective-c-20/9780133047462/app01.html\n    /// https://www.binpress.com/objective-c-reserved-keywords/\n    static let objcKeywords = [\n\n        // additional\n        \"description\",\n\n        // hard\n        \"asm\",\n        \"auto\",\n        \"break\",\n        \"case\",\n        \"char\",\n        \"const\",\n        \"continue\",\n        \"default\",\n        \"do\",\n        \"double\",\n        \"else\",\n        \"enum\",\n        \"extern\",\n        \"float\",\n        \"for\",\n        \"goto\",\n        \"if\",\n        \"inline\",\n        \"int\",\n        \"long\",\n        \"register\",\n        \"restrict\",\n        \"return\",\n        \"short\",\n        \"signed\",\n        \"sizeof\",\n        \"static\",\n        \"struct\",\n        \"switch\",\n        \"typedef\",\n        \"union\",\n        \"unsigned\",\n        \"void\",\n        \"volatile\",\n        \"_Bool\",\n        \"_Complex\",\n        \"_Imaginary\",\n        \"__block\",\n\n        // soft\n        \"BOOL\",\n        \"Class\",\n        \"bycopy\",\n        \"byref\",\n        \"id\",\n        \"IMP\",\n        \"in\",\n        \"In\",\n        \"inout\",\n        \"nil\",\n        \"Nil\",\n        \"NO\",\n        \"NULL\",\n        \"oneway\",\n        \"out\",\n        \"Protocol\",\n        \"SEL\",\n        \"self\",\n        \"super\",\n        \"YES\",\n        \"@interface\",\n        \"@end\",\n        \"@implementation\",\n        \"@protocol\",\n        \"@class\",\n        \"@public\",\n        \"@protected\",\n        \"@private\",\n        \"@property\",\n        \"@try\",\n        \"@throw\",\n        \"@catch\",\n        \"@finally\",\n        \"@synthesize\",\n        \"@dynamic\",\n        \"@selector\",\n        \"atomic\",\n        \"nonatomic\",\n        \"retain\",\n        \"_cmd\",\n        \"__autoreleasing\",\n        \"__strong\",\n        \"__weak\",\n        \"__unsafe_unretained\"\n    ]\n\n    static private let objcIdentifierRegex = try! NSRegularExpression(pattern: \"^[a-zA-Z_]+([a-zA-Z_0-9])*$\")\n\n    static func isValidIOSTypeName(iosTypeName: String) -> Bool {\n        return iosTypeName.matches(regex: objcIdentifierRegex)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/SchemaWriter.swift",
    "content": "//\n//  File.swift\n//\n//\n//  Created by Simon Corsin on 1/23/23.\n//\n\nimport Foundation\n\nprotocol SchemaWriterListener: AnyObject {\n    func getClassName(nodeMapping: ValdiNodeClassMapping, typeArguments: [ValdiModelPropertyType]?) throws -> String?\n}\n\nclass SchemaWriter {\n\n    private(set) var str = \"\"\n    private let listener: SchemaWriterListener\n    private let typeParameters: [ValdiTypeParameter]?\n    private let alwaysBoxFunctionParametersAndReturnValue: Bool\n    private let boxIntEnums: Bool\n\n    init(typeParameters: [ValdiTypeParameter]?,\n         listener: SchemaWriterListener,\n         alwaysBoxFunctionParametersAndReturnValue: Bool,\n         boxIntEnums: Bool) {\n        self.typeParameters = typeParameters\n        self.listener = listener\n        self.alwaysBoxFunctionParametersAndReturnValue = alwaysBoxFunctionParametersAndReturnValue\n        self.boxIntEnums = boxIntEnums\n    }\n\n    func appendComma() {\n        str.append(\",\")\n    }\n\n    func appendClass(_ clsName: String, properties: [ValdiModelProperty]) throws {\n        str.append(\"c '\\(clsName)'\")\n        try appendProperties(properties: properties, isMethod: false)\n    }\n\n    func appendInterface(_ clsName: String, properties: [ValdiModelProperty]) throws {\n        str.append(\"c+ '\\(clsName)'\")\n        try appendProperties(properties: properties, isMethod: true)\n    }\n\n    func appendStringEnum(_ enumName: String, enumCases: [EnumCase<String>]) throws {\n        try appendEnum(enumName, enumTypename: \"s\", enumCases: enumCases) { value in\n            return \"'\\(value)'\"\n        }\n    }\n\n    func appendIntEnum(_ enumName: String, enumCases: [EnumCase<Int>]) throws {\n        try appendEnum(enumName, enumTypename: \"i\", enumCases: enumCases) { value in\n            return \"\\(value)\"\n        }\n    }\n\n    private func appendEnum<T>(_ enumName: String, enumTypename: String, enumCases: [EnumCase<T>], caseToString: (T) -> String) throws {\n        str.append(\"e<\\(enumTypename)> '\\(enumName)'\")\n        try appendList(list: enumCases, startDelimiter: \"{\", endDelimiter: \"}\", handle: { enumCase in\n            appendPropertyName(enumCase.name)\n            str.append(caseToString(enumCase.value))\n        })\n    }\n\n    func appendFunction(returnType: ValdiModelPropertyType, parameters: [ValdiModelProperty], isOptional: Bool, isMethod: Bool, isSingleCall: Bool, shouldCallOnWorkerThread: Bool) throws {\n        doAppendTypeName(\"f\", boxed: false, isOptional: isOptional)\n\n        if isMethod || isSingleCall || shouldCallOnWorkerThread {\n            var modifiers = [String]()\n            if isMethod {\n                modifiers.append(\"m\")\n            }\n            if isSingleCall {\n                modifiers.append(\"s\")\n            }\n            if shouldCallOnWorkerThread {\n                modifiers.append(\"w\")\n            }\n\n            try appendList(list: modifiers, startDelimiter: \"|\", endDelimiter: \"|\", handle: { modifier in\n                str.append(modifier)\n            })\n        }\n\n        let shouldBoxParametersAndReturnValue = !isMethod && self.alwaysBoxFunctionParametersAndReturnValue\n        try appendList(list: parameters, startDelimiter: \"(\", endDelimiter: \")\") { parameter in\n            try appendType(parameter.type, asBoxed: shouldBoxParametersAndReturnValue, isMethod: false)\n        }\n\n        if !returnType.isVoid {\n            str.append(\": \")\n            try appendType(returnType, asBoxed: shouldBoxParametersAndReturnValue, isMethod: false)\n        }\n    }\n\n    func appendTypeRef(nodeMapping: ValdiNodeClassMapping, boxed: Bool, isOptional: Bool, hasConverter: Bool) throws {\n        guard let className = try listener.getClassName(nodeMapping: nodeMapping, typeArguments: nil) else {\n            doAppendTypeName(\"u\", boxed: false, isOptional: isOptional)\n            return\n        }\n\n        doAppendTypeName(\"r\", boxed: boxed, isOptional: isOptional)\n        if nodeMapping.kind == .enum {\n            str.append(\"<e>\")\n        } else if hasConverter {\n            str.append(\"<c>\")\n        }\n\n        str.append(\":'\")\n        str.append(className)\n        str.append(\"'\")\n    }\n\n    func appendGenTypeRef(nodeMapping: ValdiNodeClassMapping,\n                          isOptional: Bool,\n                          hasConverter: Bool,\n                          typeArguments: [ValdiModelPropertyType]) throws {\n        guard let className = try listener.getClassName(nodeMapping: nodeMapping, typeArguments: typeArguments) else {\n            doAppendTypeName(\"u\", boxed: false, isOptional: isOptional)\n            return\n        }\n\n        doAppendTypeName(\"g\", boxed: false, isOptional: isOptional)\n        if hasConverter {\n            str.append(\"<c>\")\n        }\n        str.append(\":'\")\n        str.append(className)\n        str.append(\"'\")\n        try appendList(list: typeArguments, startDelimiter: \"<\", endDelimiter: \">\") { item in\n            try appendType(item, asBoxed: true, isMethod: false)\n        }\n    }\n\n    func appendPromise(isOptional: Bool, typeArgument: ValdiModelPropertyType) throws {\n        doAppendTypeName(\"p\", boxed: false, isOptional: isOptional)\n        str.append(\"<\")\n        try appendType(typeArgument, asBoxed: true, isMethod: false)\n        str.append(\">\")\n    }\n\n    private func doAppendTypeName(_ name: String, boxed: Bool, isOptional: Bool) {\n        str.append(name)\n        if boxed {\n            str.append(\"@\")\n        }\n        if isOptional {\n            str.append(\"?\")\n        }\n    }\n\n    func appendType(_ type: ValdiModelPropertyType, asBoxed: Bool, isMethod: Bool) throws {\n        let innerType = type.unwrappingOptional\n        let isOptional = type.isOptional\n\n        switch innerType {\n        case .string:\n            doAppendTypeName(\"s\", boxed: false, isOptional: isOptional)\n        case .double:\n            doAppendTypeName(\"d\", boxed: asBoxed || isOptional, isOptional: isOptional)\n        case .bool:\n            doAppendTypeName(\"b\", boxed: asBoxed || isOptional, isOptional: isOptional)\n        case .long:\n            doAppendTypeName(\"l\", boxed: asBoxed || isOptional, isOptional: isOptional)\n        case .array(elementType: let elementType):\n            doAppendTypeName(\"a\", boxed: false, isOptional: isOptional)\n            str.append(\"<\")\n            try appendType(elementType, asBoxed: true, isMethod: false)\n            str.append(\">\")\n        case .bytes:\n            doAppendTypeName(\"t\", boxed: false, isOptional: isOptional)\n        case .map(keyType: let keyType, valueType: let valueType):\n            doAppendTypeName(\"m\", boxed: false, isOptional: isOptional)\n            str.append(\"<\")\n            try appendType(keyType, asBoxed: true, isMethod: false)\n            str.append(\",\")\n            try appendType(valueType, asBoxed: true, isMethod: false)\n            str.append(\">\")\n        case .any:\n            doAppendTypeName(\"u\", boxed: false, isOptional: isOptional)\n        case .void:\n            doAppendTypeName(\"v\", boxed: false, isOptional: isOptional)\n        case .function(parameters: let parameters, returnType: let returnType, isSingleCall: let isSingleCall, shouldCallOnWorkerThread: let shouldCallOnWorkerThread):\n            try appendFunction(returnType: returnType, parameters: parameters, isOptional: isOptional, isMethod: isMethod, isSingleCall: isSingleCall, shouldCallOnWorkerThread: shouldCallOnWorkerThread)\n        case .object(let nodeMapping):\n            try appendTypeRef(nodeMapping: nodeMapping, boxed: false, isOptional: isOptional, hasConverter: nodeMapping.converter != nil)\n        case .genericTypeParameter(name: let name):\n            guard let index = typeParameters?.firstIndex(where: { item in\n                item.name == name\n            }) else {\n                throw CompilerError(\"Could not match generic type parameter \\(name) to given type parameters \\(self.typeParameters ?? [])\")\n            }\n\n            doAppendTypeName(\"r\", boxed: false, isOptional: isOptional)\n            str.append(\":\\(index)\")\n        case .genericObject(let nodeMapping, let typeArguments):\n            try appendGenTypeRef(nodeMapping: nodeMapping, isOptional: isOptional, hasConverter: nodeMapping.converter != nil, typeArguments: typeArguments)\n        case .promise(typeArgument: let typeArgument):\n            try appendPromise(isOptional: isOptional, typeArgument: typeArgument)\n        case .enum(let e):\n            let shouldBoxEnum = e.kind == .enum && self.boxIntEnums && (asBoxed || isOptional)\n            try appendTypeRef(nodeMapping: e, boxed: shouldBoxEnum, isOptional: isOptional, hasConverter: false)\n        case .nullable:\n            fatalError()\n        }\n    }\n\n    func appendProperties(properties: [ValdiModelProperty], isMethod: Bool) throws {\n        try appendList(list: properties, startDelimiter: \"{\", endDelimiter: \"}\") { property in\n            try appendProperty(property: property, isMethod: isMethod)\n        }\n    }\n\n    func appendPropertyName(_ propertyName: String) {\n        str.append(\"'\\(propertyName)':\")\n    }\n\n    func appendProperty(property: ValdiModelProperty, isMethod: Bool) throws {\n        appendPropertyName(property.name)\n        try appendType(property.type, asBoxed: false, isMethod: isMethod)\n    }\n\n    func appendEnumValue(_ value: String) {\n        str.append(value)\n    }\n\n    private func appendList<T>(list: [T],\n                               startDelimiter: String,\n                               endDelimiter: String,\n                               handle: (T) throws -> Void) throws {\n        str.append(startDelimiter)\n        var first = true\n        for item in list {\n            if !first {\n                str.append(\", \")\n            }\n            first = false\n            try handle(item)\n        }\n        str.append(endDelimiter)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Swift/SwiftCodeGenerator.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nfunc indent(spaces count: Int) -> String {\n    return \"\\n\" + String(repeating: \" \", count: count)\n}\n\nprivate final class SwiftImportSection: CodeWriterContent {\n\n    private(set) var importedClasses = Set<String>()\n\n    func addImport(path: String) {\n        importedClasses.insert(path)\n    }\n\n    var content: String {\n        return importedClasses.sorted().map { \"import \\($0)\\n\" }.joined()\n    }\n}\n\nstruct SwiftTypeParser {\n    let typeName: String\n    let isOptional: Bool\n    let isInterface: Bool\n    let functionTypeParser: SwiftFunctionTypeParser?\n    let innerTypeParser: [SwiftTypeParser]?\n    let typeArguments: [SwiftTypeParser]?\n    let marshallerName: String?\n    var needsEscaping: Bool {\n        return functionTypeParser != nil && !isOptional\n    }\n    var isFunction: Bool {\n        return functionTypeParser != nil\n    }\n\n    /// - Parameters:\n    ///   - typeName: The actual name of that type in Swift (without optional mark)\n    ///   - isOptional: Whether the type is optional or not.\n    ///   - marshallerName: The name of the marshaller function to use for this type. it. getBool, getFunction, etc...\n    ///   - innerTypeParser: The type parser for the inner type of the array, map, or promise.\n    ///   - functionTypeParser: The type parser if this is a function type.\n    ///   - typeArguments: The type parsers for the type arguments of the generic type.\n    init(\n        typeName: String,\n        isOptional: Bool,\n        marshallerName: String?,\n        innerTypeParser: SwiftTypeParser? = nil,\n        functionTypeParser: SwiftFunctionTypeParser? = nil,\n        typeArguments: [SwiftTypeParser]? = nil\n    ) {\n        self.typeName = SwiftTypeParser.getFullTypeName(typeName: typeName, isOptional: isOptional, isFunction: (functionTypeParser != nil),  typeArguments: typeArguments)\n        self.isOptional = isOptional\n        self.isInterface = false\n        self.functionTypeParser = functionTypeParser\n        self.typeArguments = typeArguments\n        self.innerTypeParser = innerTypeParser.map { [$0] }\n        self.marshallerName = marshallerName.map { (isOptional ? \"Optional\" : \"\") + $0 }\n    }\n    init(\n      typeName: String,\n      isOptional: Bool,\n      marshallerName: String?,\n      isInterface: Bool\n    ) {\n        self.typeName = SwiftTypeParser.getFullTypeName(typeName: typeName, isOptional: isOptional, isFunction: false,  typeArguments: nil)\n        self.isOptional = isOptional\n        self.isInterface = isInterface\n        self.functionTypeParser = nil\n        self.typeArguments = nil\n        self.innerTypeParser = nil\n        self.marshallerName = marshallerName.map { (isOptional ? \"Optional\" : \"\") + $0 }\n    }\n\n    private static func getFullTypeName(typeName: String, isOptional: Bool, isFunction: Bool, typeArguments: [SwiftTypeParser]?) -> String {\n        let optionalMarkIfNeeded = isOptional ? \"?\" : \"\"\n        if let typeArguments = typeArguments {\n            return \"\\(typeName)<\\(typeArguments.map { $0.typeName }.joined(separator: \", \"))>\\(optionalMarkIfNeeded)\"\n        } else {\n            return \"\\(typeName)\\(optionalMarkIfNeeded)\"\n        }\n    }\n    public func typeNameRemoveOptional() -> String {\n        if self.typeName.hasSuffix(\"?\") {\n            return String(self.typeName.dropLast())\n        } else {\n            return self.typeName\n        }\n    }\n}\n\nstruct SwiftProperty {\n    let name: String\n    let typeParser: SwiftTypeParser\n    let comments: String?\n}\n\nstruct SwiftSchemaAnnotationResult {\n    let typeReferences: CodeWriterContent\n    let schema: CodeWriterContent\n}\n\nclass SwiftFunctionTypeParser {\n    let parameterNames: [PropertyName]\n    let parameterTypes: [SwiftTypeParser]\n    let returnType: SwiftTypeParser\n    let functionThrows : Bool = true\n    let functionHelperName : String\n\n    init(parameterNames: [PropertyName], parameterTypes: [SwiftTypeParser], returnType: SwiftTypeParser, functionHelperName: String) {\n        self.parameterNames = parameterNames\n        self.parameterTypes = parameterTypes\n        self.returnType = returnType\n        self.functionHelperName = functionHelperName\n    }\n\n    private var parametersStringWithNames: String {\n        return parameterNames.enumerated().map { index, name in\n            let maybeEscaping = parameterTypes[index].needsEscaping ? \"@escaping \" : \"\"\n            return \"\\(name): \\(maybeEscaping)\\(parameterTypes[index].typeName)\"\n        }.joined(separator: \", \")\n    }\n\n    private var parametersStringWithoutName: String {\n        return parameterNames.enumerated().map { index, name in\n            let maybeEscaping = parameterTypes[index].needsEscaping ? \"@escaping \" : \"\"\n            return \"\\(maybeEscaping)\\(parameterTypes[index].typeName)\"\n        }.joined(separator: \", \")\n    }\n\n    var callableParametersString: String {\n        return parameterNames.enumerated().map { index, name in\n            return \"\\(name)\"\n        }.joined(separator: \", \")\n    }\n\n    var callableParametersStringWithNames: String {\n        return parameterNames.enumerated().map { index, name in\n            return \"\\(name): \\(name)\"\n        }.joined(separator: \", \")\n    }\n\n    var methodTypeWithNames: String {\n        return \"(\\(parametersStringWithNames))\\(functionThrows ? \" throws \" : \" \")-> \\(returnType.typeName)\"\n    }\n\n    var methodTypeWithoutNames: String {\n        return \"(\\(parametersStringWithoutName))\\(functionThrows ? \" throws \" : \" \")-> \\(returnType.typeName)\"\n    }\n}\n\nfinal class SwiftCodeGenerator: CodeWriter {\n    static let maxFunctionParametersCount = 16\n}\n\nfinal class SwiftSourceFileGenerator : CodeWriter {\n    let nameAllocator = PropertyNameAllocator.forSwift()\n    let moduleName: String\n    let className: String\n    var functionParsers: [SwiftTypeParser] = []\n    private let importSection = SwiftImportSection()\n\n    func addImport(path: String) {\n        if path == moduleName {\n            return\n        }\n        self.importSection.addImport(path: path)\n    }\n\n    init(className: String, moduleName: String = \"\") {\n        self.moduleName = moduleName\n        self.className = className\n        super.init()\n        self.appendHeader(importSection)\n        self.appendBody(\"\\n\")\n    }\n\n    private func getFunctionTypeParser(returnType: ValdiModelPropertyType,\n                               parameters: [ValdiModelProperty],\n                               nameAllocator: PropertyNameAllocator,\n                               functionHelperName: String) throws -> SwiftFunctionTypeParser {\n        guard parameters.count <= SwiftCodeGenerator.maxFunctionParametersCount else {\n            throw CompilerError(\"Exported functions to Swift can only support up to \\(SwiftCodeGenerator.maxFunctionParametersCount) parameters.\")\n        }\n\n        let parameterNames = parameters.map { nameAllocator.allocate(property: $0.name) }\n        let parameterParsers = try parameters.map { try getTypeParser(type: $0.type.unwrappingOptional, isOptional: $0.type.isOptional, functionHelperName: functionHelperName + $0.name, nameAllocator: nameAllocator) }\n        let returnParser = try getTypeParser(type: returnType.unwrappingOptional, isOptional: returnType.isOptional, functionHelperName: functionHelperName + \"Return\", nameAllocator: nameAllocator)\n\n        return SwiftFunctionTypeParser(parameterNames: parameterNames, parameterTypes: parameterParsers, returnType: returnParser, functionHelperName: functionHelperName)\n    }\n\n    private func getGenericTypeParameterTypeParser(name: String, isOptional: Bool, nameAllocator: PropertyNameAllocator) throws -> SwiftTypeParser {\n        return SwiftTypeParser(typeName: name, isOptional: isOptional, marshallerName: \"GenericTypeParameter\")\n    }\n\n    private func getGenericObjectTypeParser(typeName: String, mapping: ValdiNodeClassMapping, isOptional: Bool, nameAllocator: PropertyNameAllocator, typeArgumentsTypeParsers: [SwiftTypeParser]) throws -> SwiftTypeParser {\n        let typeParser = SwiftTypeParser(\n            typeName: typeName,\n            isOptional: isOptional,\n            marshallerName: \"GenericObject\",\n            typeArguments: typeArgumentsTypeParsers\n        )\n        return typeParser\n    }\n\n    /// Returns the type parser for the given type.\n    /// - Parameters:\n    ///   - type: The type to parse.\n    ///   - isOptional: Whether the type is optional or not.\n    ///   - functionHelperName: Name for the helper function to generate for the function type.\n    ///   - nameAllocator: The name allocator to use for naming the function type.\n    func getTypeParser(type: ValdiModelPropertyType, isOptional: Bool, functionHelperName: String?, nameAllocator: PropertyNameAllocator) throws -> SwiftTypeParser {\n        switch type {\n        case .string:\n            return SwiftTypeParser(typeName: \"String\", isOptional: isOptional, marshallerName: \"String\")\n        case .double:\n            return SwiftTypeParser(typeName: \"Double\", isOptional: isOptional, marshallerName: \"Double\")\n        case .bool:\n            return SwiftTypeParser(typeName: \"Bool\", isOptional: isOptional, marshallerName: \"Bool\")\n        case .long:\n            return SwiftTypeParser(typeName: \"Int64\", isOptional: isOptional, marshallerName: \"Long\")\n        case .array(let elementType):\n            let childParser = try getTypeParser(type: elementType.unwrappingOptional, isOptional: elementType.isOptional, functionHelperName: functionHelperName, nameAllocator: nameAllocator)\n            return SwiftTypeParser(typeName: \"[\\(childParser.typeName)]\", isOptional: isOptional, marshallerName: \"Array\", innerTypeParser: childParser)\n        case .bytes:\n            self.addImport(path: \"Foundation\")\n            return SwiftTypeParser(typeName: \"Data\", isOptional: isOptional, marshallerName: \"Data\")\n        case .map(let keyType, let valueType):\n            let valueTypeParser = try getTypeParser(type: valueType.unwrappingOptional, isOptional: valueType.isOptional, functionHelperName: functionHelperName, nameAllocator: nameAllocator)\n            let keyTypeParser = try getTypeParser(type: keyType.unwrappingOptional, isOptional: keyType.isOptional, functionHelperName: functionHelperName, nameAllocator: nameAllocator)\n            guard keyTypeParser.typeName == \"String\" else {\n                throw CompilerError(\"Maps with non-string keys are not supported in Swift\")\n            }\n            return SwiftTypeParser(typeName: \"[\\(keyTypeParser.typeName): \\(valueTypeParser.typeName)]\", isOptional: isOptional, marshallerName: \"Map\", innerTypeParser: valueTypeParser)\n        case .any:\n            return SwiftTypeParser(typeName: \"Any\", isOptional: true, marshallerName: \"Untyped\")\n        case .void:\n            return SwiftTypeParser(typeName: \"Void\", isOptional: false, marshallerName: nil)\n        case .function(let parameters, let returnType, _, _):\n            guard let functionHelperName = functionHelperName else {\n                throw CompilerError(\"Function type must have a name\")\n            }\n            let functionTypeParser = try getFunctionTypeParser(returnType: returnType, parameters: parameters, nameAllocator: nameAllocator, functionHelperName: functionHelperName)\n            let swiftTypeParser = SwiftTypeParser(typeName: \"(\\(functionTypeParser.methodTypeWithoutNames))\", isOptional: isOptional, marshallerName: \"Function\", functionTypeParser: functionTypeParser)\n            self.functionParsers.append(swiftTypeParser)\n            return swiftTypeParser\n        case .enum(let mapping):\n            guard let resolvedType = mapping.iosType?.swiftName,\n                  let moduleImport = mapping.iosType?.importPrefix else {\n                throw CompilerError(\"No swift type declared\")\n            }\n            _ = importModule(moduleImport, mapping)\n            return SwiftTypeParser(typeName: resolvedType, isOptional: isOptional, marshallerName: \"Enum\")\n        case .object(let mapping):\n            guard let resolvedType = mapping.iosType?.swiftName,\n                  let moduleImport = mapping.iosType?.importPrefix else {\n                throw CompilerError(\"No swift class declared\")\n            }\n            _ = importModule(moduleImport, mapping)\n\n            let marshallerName: String\n            switch mapping.iosType?.iosLanguage {\n            case .swift, .both:\n                marshallerName = \"Object\"\n            case .objc:\n                marshallerName = \"ObjCObject\"\n            default:\n                let language = mapping.iosType?.iosLanguage.rawValue ?? \"Unknown\"\n                throw CompilerError(\"Unknown language for object \\(resolvedType): \\(language)\")\n            }\n            switch mapping.kind {\n            case .interface:\n                return SwiftTypeParser(typeName: resolvedType, isOptional: isOptional, marshallerName: marshallerName, isInterface: marshallerName == \"Object\")\n            default:\n                return SwiftTypeParser(typeName: resolvedType, isOptional: isOptional, marshallerName: marshallerName)\n            }\n        case .genericTypeParameter(let name):\n            return try getGenericTypeParameterTypeParser(name: name, isOptional: isOptional, nameAllocator: nameAllocator)\n        case .genericObject(let mapping, let typeArguments):\n            guard let resolvedType = mapping.iosType?.swiftName,\n                  let moduleImport = mapping.iosType?.importPrefix else {\n                throw CompilerError(\"No swift class declared\")\n            }\n\n            let typeArgumentsTypeParsers = try typeArguments.map {\n                try getTypeParser(type: $0, isOptional: false, functionHelperName: functionHelperName, nameAllocator: nameAllocator)\n            }\n\n            _ = importModule(moduleImport, mapping)\n            return try getGenericObjectTypeParser(typeName: resolvedType, mapping: mapping, isOptional: isOptional, nameAllocator: nameAllocator, typeArgumentsTypeParsers: typeArgumentsTypeParsers)\n        case .promise(let typeArgument):\n            let promiseTypeName = \"ValdiPromise\"\n            let childParser = try getTypeParser(type: typeArgument.unwrappingOptional, isOptional: typeArgument.isOptional, functionHelperName: functionHelperName, nameAllocator: nameAllocator)\n            let typeName = \"\\(promiseTypeName)<\\(childParser.typeName)>\"\n\n            return SwiftTypeParser(typeName: typeName, isOptional: isOptional, marshallerName: \"Promise\")\n        case .nullable(let type):\n            return try getTypeParser(type: type, isOptional: true, functionHelperName: functionHelperName, nameAllocator: nameAllocator)\n        }\n    }\n\n    private func importModule(_ moduleName: String, _ mapping: ValdiNodeClassMapping) -> String {\n        if moduleName == self.moduleName {\n            return moduleName\n        }\n        let languageSuffix = (mapping.iosType?.iosLanguage == .both) ? \"_Swift\" : \"\"\n        let importName = moduleName + languageSuffix\n        self.addImport(path: importName)\n        return importName\n    }\n\n    private static func marshallerCanThrow(type: SwiftTypeParser) -> Bool {\n        let baseMarshallerNames = [\"Array\", \"Map\", \"Object\", \"GenericObject\", \"Untyped\", \"Promise\", \"ObjCObject\", \"GenericTypeParameter\"\n        ]\n        let marshallerNames = baseMarshallerNames.flatMap { [$0, \"Optional\\($0)\"] }\n        return marshallerNames.contains(type.marshallerName ?? \"\")\n    }\n\n    /// Returns the marshaller function for a given typeParser\n    /// Parameters:\n    ///   - typeParser: The typeParser for the type\n    ///   - parameter: The parameter to pass to the marshaller function\n    private static func getMarshallerFunction(for typeParser: SwiftTypeParser, withParameter parameter: String) -> String {\n        guard let marshallingName = typeParser.marshallerName else {\n            return \"\"\n        }\n\n        let maybeTry = marshallerCanThrow(type: typeParser) ? \"try \" : \"\"\n        let innerMarshaller = typeParser.innerTypeParser.map { innerTypeParser in\n            \" { \\(getMarshallerFunction(for: innerTypeParser[0], withParameter: \"$0\")) }\"\n        } ?? \"\"\n\n        var parameter = parameter\n        if let functionHelperName = typeParser.functionTypeParser?.functionHelperName {\n            parameter = \"Self.create_\\(functionHelperName)_bridgeFunction(using: \\(parameter))\"\n        }\n        return \"\\(maybeTry)marshaller.push\" + marshallingName + \"(\\(parameter))\" + innerMarshaller\n    }\n\n\n    /// Returns the unmarshaller function for a given typeParser\n    /// Parameters:\n    ///   - typeParser: The typeParser for the type\n    ///   - parameter: The parameter to pass to the unmarshaller function\n    private static func getUnmarshallerFunction(for typeParser: SwiftTypeParser, withParameter parameter: String) -> String {\n        guard let marshallingName = typeParser.marshallerName else {\n            return \"\"\n        }\n\n        if typeParser.isInterface {\n            if typeParser.isOptional {\n                let proxyUnmarshaller = \"try \\(typeParser.typeNameRemoveOptional())_Proxy(from:marshaller, at:$0)\"\n                return \"try marshaller.getOptional(\\(parameter)) { \\(proxyUnmarshaller) }\"\n            } else {\n                return \"try \\(typeParser.typeNameRemoveOptional())_Proxy(from:marshaller, at:\\(parameter))\"\n            }\n        }\n\n        let innerMarshaller = typeParser.innerTypeParser.map { innerTypeParser in\n            \" { \\(getUnmarshallerFunction(for: innerTypeParser[0], withParameter: \"$0\")) }\"\n        } ?? \"\"\n        let unmarshaller = \"try marshaller.get\" + marshallingName + \"(\\(parameter))\" + innerMarshaller\n        if let functionHelperName = typeParser.functionTypeParser?.functionHelperName {\n            return \"Self.create_\\(functionHelperName)_from_bridgeFunction(using: \\(unmarshaller))\"\n        }\n        return unmarshaller\n    }\n\n    // Creates a function that writes calls bridgeFunction with a ValdiMarshaller using the given parameterTypes and returnTypes\n    // bridgeFunction is a ValdiFunction that will be called with a marshaller\n    // isLambda is true will generate a lambda function, false will generate a regular function\n    public static func writeFunctionMarshaller(functionParser: SwiftFunctionTypeParser, isOptional: Bool) -> String  {\n        let optionalMark = isOptional ? \"?\" : \"\"\n        let optionalPredicate = isOptional ? \"guard let functionImpl = functionImpl else { return nil }\" : \"\"\n\n        // Body of the function that places each parameter onto the marshaller stack\n        let parameterMarshallers = functionParser.parameterTypes.enumerated().map { index, parameterType in\n            let paramName = functionParser.parameterNames[index].name\n            return \"_ = \\(getMarshallerFunction(for: parameterType, withParameter: paramName))\"\n        }.joined(separator: indent(spaces: 12))\n\n        let returnValue = getUnmarshallerFunction(for: functionParser.returnType, withParameter: \"-1\")\n        let shouldSync = returnValue.isEmpty ? \"false\" : \"true\"\n        return  \"\"\"\n                    static func create_\\(functionParser.functionHelperName)_from_bridgeFunction(using functionImpl: ValdiFunction\\(optionalMark)) -> (\\(functionParser.methodTypeWithoutNames))\\(optionalMark) {\n                        \\(optionalPredicate)\n                        return { \\(functionParser.methodTypeWithNames) in\n                            let marshaller = ValdiMarshaller()\n                            \\(parameterMarshallers)\n                            if !functionImpl.perform(with: marshaller, sync: \\(shouldSync)) {\n                                try marshaller.checkError()\n                                throw ValdiError.functionCallFailed(\\\"\\(functionParser.functionHelperName)\\\")\n                            }\n                            return \\(returnValue)\n                        }\n                    }\\n\n                \"\"\"\n    }\n\n    // Writes the unmarshalling code for an object that initializes the object with the values from a marshaller\n    // Calls getTypedObjectProperty for each property of the object which calls the unmarshaller specific for the type of the property\n    public static func writeObjectUnmarshaller(properties: [SwiftProperty], isInterface: Bool) -> CodeWriter {\n        let propertyUnmarshallers = properties.enumerated().map { index, property in\n            var propertyNameOrFunctionImpl = property.name\n            let unmarshallPropertyType = getUnmarshallerFunction(for: property.typeParser, withParameter: \"$0\")\n            if isInterface && property.typeParser.isFunction {\n                propertyNameOrFunctionImpl += \"_implementation\"\n            }\n\n            // shortcut for common types\n            switch property.typeParser.typeName {\n            case \"Bool\": fallthrough\n            case \"Int\": fallthrough\n            case \"Long\": fallthrough\n            case \"Double\": fallthrough\n            case \"String\": fallthrough\n            case \"Data\": \n                return \"self.\\(propertyNameOrFunctionImpl) = try marshaller.getTypedObjectProperty\\(property.typeParser.typeName)(objectIndex, \\(index))\"\n            case \"Bool?\": fallthrough\n            case \"Int?\": fallthrough\n            case \"Long?\": fallthrough\n            case \"Double?\": fallthrough\n            case \"String?\": fallthrough\n            case \"Data?\": \n                return \"self.\\(propertyNameOrFunctionImpl) = try marshaller.getTypedObjectPropertyOptional\\(property.typeParser.typeName.dropLast())(objectIndex, \\(index))\"\n            default:\n                let enumsAndObjectMarshallers = [\"Enum\", \"OptionalEnum\", \"Object\", \"OptionalObject\"]\n                let functionMarshallers = [\"Function\", \"OptionalFunction\"]\n                if !property.typeParser.isInterface,\n                   let marshallerName = property.typeParser.marshallerName, enumsAndObjectMarshallers.contains(marshallerName) {\n                    return \"self.\\(propertyNameOrFunctionImpl) = try marshaller.getTypedObjectProperty\\(marshallerName)(objectIndex, \\(index))\"\n                } else if let marshallerName = property.typeParser.marshallerName,\n                          let functionHelperName = property.typeParser.functionTypeParser?.functionHelperName,\n                          functionMarshallers.contains(marshallerName) {\n                    return \"self.\\(propertyNameOrFunctionImpl) = Self.create_\\(functionHelperName)_from_bridgeFunction(using: try marshaller.getTypedObjectProperty\\(marshallerName)(objectIndex, \\(index)))\"\n                } else {\n                    return \"self.\\(propertyNameOrFunctionImpl) = try marshaller.getTypedObjectProperty(objectIndex, \\(index)) { \\(unmarshallPropertyType) }\"\n                }\n            }\n        }.joined(separator: indent(spaces: 8))\n\n\n        // If we're initializing an interface, we need to unwrap given proxy object to place the ValueTyped object on the marshaller stack\n        // and then pop the proxy object from the stack\n        let maybeUnwrapProxy = isInterface ? \"let objectIndex = try marshaller.unwrapProxy(objectIndex)\" : \"\"\n        let maybePop = isInterface ? \"marshaller.pop()\" : \"\"\n\n        let unmarshaller = CodeWriter()\n        unmarshaller.appendBody(\n        \"\"\"\n            public required init(from marshaller: ValdiMarshaller, at objectIndex: Int) throws {\n                \\(maybeUnwrapProxy)\n                \\(propertyUnmarshallers)\n                \\(maybePop)\n            }\\n\n        \"\"\")\n        return unmarshaller\n    }\n\n    /// Write marshalling code that pushes an object onto the marshaller stack\n    /// Then assigns each property of the object in the marshaller\n    /// Parameters:\n    ///   - properties: The properties of the object\n    ///   - className: The name of the class\n    ///   - isInterface: True we are generating an interface. Pushes a proxy object onto the marshaller stack.\n    public static func writeObjectMarshaller(properties: [SwiftProperty], className: String, isInterface: Bool) -> CodeWriter {\n        let propertyMarshallers = properties.enumerated().map() { index, property in\n\n            switch property.typeParser.typeName {\n            case \"Bool\": fallthrough\n            case \"Int\": fallthrough\n            case \"Long\": fallthrough\n            case \"Double\": fallthrough\n            case \"String\": fallthrough\n            case \"Data\": \n                return \"try marshaller.setTypedObjectProperty\\(property.typeParser.typeName)(objectIndex, \\(index), self.\\(property.name))\"\n            case \"Bool?\": fallthrough\n            case \"Int?\": fallthrough\n            case \"Long?\": fallthrough\n            case \"Double?\": fallthrough\n            case \"String?\": fallthrough\n            case \"Data?\": \n                return \"try marshaller.setTypedObjectPropertyOptional\\(property.typeParser.typeName.dropLast())(objectIndex, \\(index), self.\\(property.name))\"\n            default:\n                let enumsAndObjectMarshallers = [\"Enum\", \"OptionalEnum\", \"Object\", \"OptionalObject\"]\n                let functionMarshallers = [\"Function\", \"OptionalFunction\"]\n                if let marshallerName = property.typeParser.marshallerName, enumsAndObjectMarshallers.contains(marshallerName) {\n                    return \"try marshaller.setTypedObjectProperty\\(marshallerName)(objectIndex, \\(index), self.\\(property.name))\"\n                } else if let marshallerName = property.typeParser.marshallerName,\n                          let functionHelperName = property.typeParser.functionTypeParser?.functionHelperName,\n                          functionMarshallers.contains(marshallerName) {\n                    let parameter = \"Self.create_\\(functionHelperName)_bridgeFunction(using: self.\\(property.name))\"\n                    return \"try marshaller.setTypedObjectProperty\\(marshallerName)(objectIndex, \\(index), \\(parameter))\"\n                }\n                else {\n                    let marshallerFunction = getMarshallerFunction(for: property.typeParser, withParameter: \"self.\\(property.name)\")\n                    return \"try marshaller.setTypedObjectProperty(objectIndex, \\(index)) { _ = \\(marshallerFunction) }\"\n                }\n            }\n        }.joined(separator: indent(spaces: 8))\n\n        // Push a proxy object onto the marshaller stack if we're generating an interface. The return value\n        let maybePushProxyStart = isInterface ? \"let objectIndex = try marshaller.pushProxy(object: self) {\" : \"\"\n        let maybePushProxyEnd = isInterface ? \"}\" : \"\"\n\n        let marshaller = CodeWriter()\n        marshaller.appendBody(\n        \"\"\"\n            public func push(to marshaller: ValdiMarshaller) throws -> Int {\n                \\(maybePushProxyStart)\n                register_\\(className)()\n                let objectIndex = try marshaller.pushObject(className: \"\\(className)\")\n                \\(propertyMarshallers)\n                \\(maybePushProxyEnd)\n                return objectIndex\n            }\\n\n        \"\"\")\n        return marshaller\n    }\n\n    // Write the constructor that initializes the object with all the non-optional properties\n    /// Parameters:\n    ///   - properties: The properties of the object\n    public static func writeConstructor(properties: [SwiftProperty]) -> CodeWriter {\n        var propertyAssignments = [String]()\n        var callParameters = [String]()\n\n        // Iterate over all properties non-optional properties and build the function signature and body\n        for property in properties {\n            if !property.typeParser.isOptional {\n                let escaping = property.typeParser.needsEscaping ? \"@escaping \" : \"\"\n                callParameters.append(\"\\(property.name):\\(escaping)\\(property.typeParser.typeName)\")\n                propertyAssignments.append(\"self.\\(property.name) = \\(property.name)\")\n            }\n        }\n\n        let callParameterString = callParameters.joined(separator: \", \")\n        let constructorBody = propertyAssignments.joined(separator: indent(spaces: 8))\n        let constructor = CodeWriter()\n        constructor.appendBody(\n        \"\"\"\n            public init(\\(callParameterString)) {\n                \\(constructorBody)\n            }\\n\n        \"\"\")\n        return constructor\n    }\n\n    /// Writes out a function that returns a ValdiMarshallableObjectDescriptor for the object. This contains the schema of the object.\n    /// Parameters:\n    ///   - properties: The properties of the object\n    ///   - typeParameters: The type parameters of the object\n    ///   - objectDescriptorType: The type of the object descriptor\n    public static func writeObjectDescriptorGetter(properties: [SwiftProperty],\n                                                   propertyTypes: [ValdiModelPropertyType],\n                                                   typeParameters: [ValdiTypeParameter]?,\n                                                   objectDescriptorType: String) throws -> CodeWriter {\n        let emittedIdentifiers = SwiftEmittedIdentifiers()\n        // Write a ValdiMarshallableObjectFieldDescriptor for each property of the object. This contains its name and schema.\n        let fieldDescriptors = try properties.enumerated().map { index, property throws in\n            let schemaWriter = SwiftSchemaWriter(typeParameters: typeParameters, emittedIdentifiers: emittedIdentifiers)\n            try schemaWriter.appendType(propertyTypes[index], asBoxed: false, isMethod: false)\n            return \"ValdiMarshallableObjectFieldDescriptor(name: \\\"\\(property.name)\\\", type: \\\"\\(schemaWriter.str)\\\"),\"\n        }.joined(separator: indent(spaces: 12))\n\n        // Create identifiers list for other referenced objects\n        let identifiersParam = !emittedIdentifiers.isEmpty ? \"identifiers\" : \"nil\"\n        let identifiersDefinition = !emittedIdentifiers.isEmpty ?\n            \"let \\(identifiersParam): [ValdiMarshallableIdentifier] =\\n\\(emittedIdentifiers.initializationString.content)\" :\n            \"// No identifiers needed for this object\"\n\n        let descGetter = CodeWriter()\n        descGetter.appendBody(\n            \"\"\"\n                static func getDescriptor() -> ValdiMarshallableObjectDescriptor {\n                    let fields: [ValdiMarshallableObjectFieldDescriptor] =\n                    [\n                        \\(fieldDescriptors)\n                    ]\n                    \\(identifiersDefinition)\n                    return ValdiMarshallableObjectDescriptor(fields, identifiers: \\(identifiersParam), type: \\(objectDescriptorType))\n                }\\n\n            \"\"\")\n        return descGetter\n    }\n\n    public static func writeProxyFunctionImplementation(propertyName: String, functionParser: SwiftFunctionTypeParser, isOptional: Bool) -> String {\n        let functionImpl = \"\\(propertyName)_implementation\"\n        let optionalMark = isOptional ? \"?\" : \"\"\n        let optionalPredicate =  isOptional ? \"guard let functionImpl = self.\\(functionImpl) else { throw ValdiError.functionCallFailed(\\\"\\(propertyName)\\\") }\" : \"\"\n        let callStatement = isOptional ?\n            \"return try functionImpl(\\(functionParser.callableParametersString))\" :\n            \"return try self.\\(functionImpl)(\\(functionParser.callableParametersString))\"\n        return\n            \"\"\"\n                public func \\(propertyName) \\(functionParser.methodTypeWithNames) {\n                    \\(optionalPredicate)\n                    \\(callStatement)\n                }\n                private var \\(functionImpl): (\\(functionParser.methodTypeWithoutNames))\\(optionalMark)\\n\n            \"\"\"\n    }\n\n    /// Writes the variable declarations for the object\n    /// Function properties in Proxy objects (interfaces) are implemented as a call to a bridge function\n    /// Parameters:\n    ///   - properties: The properties of the object\n    ///   - isInterface: True we are generating an interface. Affects how function properties are generated.\n    public static func writeVariableDeclaration(properties: [SwiftProperty], isInterface: Bool) -> CodeWriter {\n        let variableDeclarations = CodeWriter()\n        for property in properties {\n            if let functionParser = property.typeParser.functionTypeParser, isInterface {\n                let functionImplementation = writeProxyFunctionImplementation(propertyName: property.name, functionParser: functionParser, isOptional: property.typeParser.isOptional)\n                variableDeclarations.appendBody(functionImplementation)\n                continue\n            }\n\n            if !isInterface {\n                if let comments = property.comments {\n                    variableDeclarations.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: comments))\n                    variableDeclarations.appendBody(\"\\n\")\n                }\n            }\n            variableDeclarations.appendBody(\"    public var \\(property.name): \\(property.typeParser.typeName)\\n\")\n        }\n        return variableDeclarations\n    }\n\n    // Writes the function that unmarshalls the parameters of a function from a marshaller and calls the function\n    // The return value is then pushed onto the marshaller stack\n    public static func writeFunctionUnmarshaller(functionParser: SwiftFunctionTypeParser, isOptional: Bool) -> CodeWriter {\n        let escaping = isOptional ? \"\" : \"@escaping \"\n        let optionalMark = isOptional ? \"?\" : \"\"\n        let optionalPredicate = isOptional ? \"guard let functionImpl = functionImpl else { return nil }\" : \"\"\n\n        // Unmarshall each parameter and build the call arguments for the function\n        let parameterUnmarshallers = functionParser.parameterTypes.enumerated().map { index, parameterType in\n            let paramName = functionParser.parameterNames[index].name\n            return \"let \\(paramName) : \\(parameterType.typeName) = \\(getUnmarshallerFunction(for:parameterType, withParameter: String(index)))\"\n        }.joined(separator: indent(spaces: 16))\n\n        let returnMarshaller = getMarshallerFunction(for: functionParser.returnType, withParameter: \"result\")\n        let callStatement = \"\\(returnMarshaller.isEmpty ? \"\" : \"let result = \")try functionImpl(\\(functionParser.callableParametersString))\"\n        let marshallReturnValue = returnMarshaller.isEmpty ? \"// No return value for this call\" : \"_ = \\(returnMarshaller)\"\n\n        let functionHelpers = CodeWriter()\n        functionHelpers.appendBody(\n        \"\"\"\n            static func create_\\(functionParser.functionHelperName)_bridgeFunction(using functionImpl: \\(escaping)(\\(functionParser.methodTypeWithoutNames))\\(optionalMark)) -> ((ValdiMarshaller) -> Bool)\\(optionalMark) {\n                \\(optionalPredicate)\n                return createBridgeFunctionWrapper({ marshaller in\n                    \\(parameterUnmarshallers)\n                    \\(callStatement)\n                    \\(marshallReturnValue)\n                    })\n            }\\n\n        \"\"\")\n        return functionHelpers\n    }\n\n    public static func writeFunctionHelpers(sourceGenerator: SwiftSourceFileGenerator) throws -> CodeWriter {\n        let funcionHelpers = CodeWriter()\n        for typeParser in sourceGenerator.functionParsers {\n            if let functionTypeParser = typeParser.functionTypeParser {\n                funcionHelpers.appendBody(writeFunctionUnmarshaller(functionParser: functionTypeParser, isOptional: typeParser.isOptional))\n                funcionHelpers.appendBody(writeFunctionMarshaller(functionParser: functionTypeParser, isOptional: typeParser.isOptional))\n            }\n        }\n        return funcionHelpers\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Swift/SwiftEmittedIdentifiers.swift",
    "content": "import Foundation\n\nclass SwiftEmittedIdentifiers: EmittedIdentifiers {\n    var registerFunctions: [String: String] = [:]\n    var initializationString: CodeWriter {\n        let out = CodeWriter()\n        out.appendBody(\"        [\\n\")\n        for identifier in identifiers {\n            let registerFunc = registerFunctions[identifier] ?? \"nil\"\n            out.appendBody(\"            ValdiMarshallableIdentifier(name:\\\"\\(identifier)\\\", registerFunc: \\(registerFunc)),\\n\")\n        }\n        out.appendBody(\"        ]\\n\")\n        return out\n    }\n\n    public func setRegisterFunction(forIdentifier identifier: String, registerFunction: String) {\n        registerFunctions[identifier] = registerFunction\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Swift/SwiftFunctionGenerator.swift",
    "content": "//\n//  SwiftFunctionGenerator.swift\n//  Compiler\n//\n\nimport Foundation\n\nfinal class SwiftFunctionGenerator {\n    private let iosType: IOSType\n    private let typeName: String\n    private let exportedFunction: ExportedFunction\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n    private let bundleName: String\n    private let modulePath: String\n    private let bundleInfo: CompilationItem.BundleInfo\n\n    init(iosType: IOSType, exportedFunction: ExportedFunction, classMapping: ResolvedClassMapping, sourceFileName: GeneratedSourceFilename, bundleName: String, modulePath: String, bundleInfo: CompilationItem.BundleInfo) {\n        self.iosType = iosType\n        self.typeName = iosType.swiftName\n        self.exportedFunction = exportedFunction\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.bundleName = bundleName\n        self.modulePath = modulePath\n        self.bundleInfo = bundleInfo\n    }\n\n    func write() throws -> [NativeSource] {\n        let containingTypeName = iosType.swiftName\n\n        let generator = SwiftSourceFileGenerator(className: containingTypeName, moduleName: iosType.importPrefix ?? \"\")\n        // TODO(3521): Update to valdi_core\n        generator.addImport(path: \"valdi_core\")\n        generator.addImport(path: \"ValdiCoreSwift\")\n\n        generator.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: exportedFunction.comments))\n        generator.appendBody(\"\\n\")\n\n        let nameAllocator = PropertyNameAllocator.forSwift()\n\n        let functionType : ValdiModelPropertyType = .function(parameters: exportedFunction.parameters, returnType: exportedFunction.returnType, isSingleCall: false, shouldCallOnWorkerThread: false)\n        let typeParser = try generator.getTypeParser(type: functionType, isOptional: false, functionHelperName: \"callBlock\", nameAllocator: nameAllocator)\n        // let swiftProperties = \n\n        let objectDescriptorGetter = try SwiftSourceFileGenerator.writeObjectDescriptorGetter(\n            properties: [SwiftProperty(name: exportedFunction.functionName, typeParser: typeParser, comments: nil)],\n            propertyTypes: [functionType],\n            typeParameters: nil,\n            objectDescriptorType: \"ValdiMarshallableObjectType.Function\")\n\n        guard let functionTypeParser = typeParser.functionTypeParser else {\n            throw CompilerError(\"Expecting functionTypePArser\")\n        }\n\n        let functionHelpers = try SwiftSourceFileGenerator.writeFunctionHelpers(sourceGenerator: generator)\n\n        // Generate invokeWithJSRuntime method signature\n        var invokeWithJSRuntimeParams = [\"jsRuntimeProvider: @escaping () -> SCValdiJSRuntime\"]\n        var invokeWithJSRuntimeCallParams: [String] = []\n        \n        // Add original function parameters\n        for (index, paramName) in functionTypeParser.parameterNames.enumerated() {\n            let paramType = functionTypeParser.parameterTypes[index].typeName\n            invokeWithJSRuntimeParams.append(\"\\(paramName): \\(paramType)\")\n            invokeWithJSRuntimeCallParams.append(\"\\(paramName): \\(paramName)\")\n        }\n        \n        // Add completionHandler parameter (using completionHandler to avoid naming conflicts)\n        let isVoidReturn = functionTypeParser.returnType.typeName == \"Void\"\n        let completionType = isVoidReturn ? \"() -> Void\" : \"(\\(functionTypeParser.returnType.typeName)) -> Void\"\n        invokeWithJSRuntimeParams.append(\"completionHandler: @escaping \\(completionType)\")\n        \n        let invokeWithJSRuntimeSignature = \"invokeWithJSRuntime(\\(invokeWithJSRuntimeParams.joined(separator: \", \")))\"\n        let functionCallParams = invokeWithJSRuntimeCallParams.joined(separator: \", \")\n        \n        // Generate the completion call based on return type\n        let completionCallCode: String\n        if isVoidReturn {\n            completionCallCode = \"\"\"\n                        try function.callBlock(\\(functionTypeParser.callableParametersString))\n                                completionHandler()\n            \"\"\"\n        } else {\n            completionCallCode = \"\"\"\n                        let result = try function.callBlock(\\(functionTypeParser.callableParametersString))\n                                completionHandler(result)\n            \"\"\"\n        }\n\n        generator.appendBody(\"\"\"\n        public class \\(containingTypeName): ValdiBridgeFunction {\n            private let callBlock : \\(functionTypeParser.methodTypeWithoutNames)\n            public static var className = \"\\(containingTypeName)\"\n            public static let asyncStrictMode: Bool = \\(bundleInfo.asyncStrictMode ? \"true\" : \"false\")\n\n            public init(jsRuntime: Any) throws {\n                guard let jsRuntime = jsRuntime as? SCValdiJSRuntime else {\n                    throw ValdiError.runtimeError(\"jsRuntime is not of type SCValdiJSRuntime\")\n                }\n                Self.assertResolutionNotOnMainThreadIfNeeded(asyncStrictMode: Self.asyncStrictMode)\n                register_\\(containingTypeName)()\n                self.callBlock = try Self.create_callBlock_from_bridgeFunction(using: Self.createBridgeFunction(jsRuntime: jsRuntime))\n            }\n\n            public static func modulePath() -> String {\n                return \"\\(bundleName)/\\(modulePath)\";\n            }\n            public func \\(exportedFunction.functionName)\\(functionTypeParser.methodTypeWithNames) {\n                return try self.callBlock(\\(functionTypeParser.callableParametersString))\n            }\n\n            public static func \\(invokeWithJSRuntimeSignature) {\n                let runtime = jsRuntimeProvider()\n                runtime.dispatch(inJsThread: {\n                    do {\n                        let function = try \\(containingTypeName)(jsRuntime: runtime)\n        \\(completionCallCode)\n                    } catch {\n                        // Handle error - for now we'll just print it\n                        print(\"Error in invokeWithJSRuntime: \\\\(error)\")\n                    }\n                })\n            }\n\n            \\(functionHelpers.content)\n            \\(objectDescriptorGetter.content)\n        }\n        public func register_\\(containingTypeName)() {\n            ValdiMarshallableObjectRegistry.shared.register(className: \\(containingTypeName).className, objectDescriptor: \\(containingTypeName).getDescriptor())\n        }\n        \"\"\")\n\n        let data = try generator.content.indented(indentPattern: \"    \").utf8Data()\n        return [NativeSource(relativePath: nil,\n                             filename: \"\\(containingTypeName).\\(FileExtensions.swift)\",\n                             file: .data(data),\n                             groupingIdentifier: \"\\(bundleInfo.iosModuleName).\\(FileExtensions.swift)\", groupingPriority: IOSType.functionTypeGroupingPriority)]\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Swift/SwiftSchemaWriter.swift",
    "content": "//\n//  SwiftSchemaWriter.swift\n//\n//\n//  Created by Ben Dodson on 2/2/24.\n//\n\nimport Foundation\n\nclass SwiftSchemaWriterListener: SchemaWriterListener {\n\n    private let emittedIdentifiers: SwiftEmittedIdentifiers\n\n    init(emittedIdentifiers: SwiftEmittedIdentifiers) {\n        self.emittedIdentifiers = emittedIdentifiers\n    }\n\n    func getClassName(nodeMapping: ValdiNodeClassMapping, typeArguments: [ValdiModelPropertyType]?) throws -> String? {\n        guard let iosType = nodeMapping.iosType else {\n            throw CompilerError(\"No iOS type in given mapping\")\n        }\n\n        let identifierIndex = emittedIdentifiers.getIdentifierIndex(iosType.swiftName)\n        if (nodeMapping.iosType?.iosLanguage == .swift || nodeMapping.iosType?.iosLanguage == .both) {\n            emittedIdentifiers.setRegisterFunction(forIdentifier: iosType.swiftName, registerFunction: \"register_\\(iosType.swiftName)\")\n        } else if nodeMapping.iosType?.iosLanguage == .objc {\n\n            if nodeMapping.marshallAsUntyped {\n                emittedIdentifiers.setRegisterFunction(forIdentifier: iosType.swiftName, registerFunction: \"{ ValdiMarshallableObjectRegistry.shared.registerUntypedObjCClass(className: \\\"\\(iosType.swiftName)\\\") }\")\n            } else {\n                emittedIdentifiers.setRegisterFunction(forIdentifier: iosType.swiftName, registerFunction: \"{ ValdiMarshallableObjectRegistry.shared.registerObjCClass(className: \\\"\\(iosType.swiftName)\\\") }\")\n            }\n        } else {\n            let language = nodeMapping.iosType?.iosLanguage.rawValue ?? \"Unknown\"\n            throw CompilerError(\"Unsupported language for type \\(iosType.swiftName): \\(language)\")\n        }\n        return \"[\\(identifierIndex)]\"\n    }\n}\n\nclass SwiftSchemaWriter: SchemaWriter {\n    init(typeParameters: [ValdiTypeParameter]?, emittedIdentifiers: SwiftEmittedIdentifiers) {\n        super.init(typeParameters: typeParameters,\n                   listener: SwiftSchemaWriterListener(emittedIdentifiers: emittedIdentifiers),\n                   alwaysBoxFunctionParametersAndReturnValue: false,\n                   boxIntEnums: true)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Generation/Swift/SwiftValidation.swift",
    "content": "import Foundation\n\n// Swift doesn't have namespaces, it's customary to use an enum without cases instead\nenum SwiftValidation {\n\n    /// These keywords must be avoided when using identifiers for generated code (e.g. type names, properties)\n    ///\n    /// https://www.geeksforgeeks.org/swift-keywords/\n    ///\n    \n    // Keywords used in the declaration\n    static let swiftKeywords = [\n        \"associatedtype\",\n        \"class\",\n        \"deinit\",\n        \"enum\",\n        \"extension\",\n        \"fileprivate\",\n        \"func\",\n        \"import\",\n        \"init\",\n        \"inout\",\n        \"internal\",\n        \"let\",\n        \"open\",\n        \"operator\",\n        \"private\",\n        \"precedencegroup\",\n        \"protocol\",\n        \"public\",\n        \"rethrows\",\n        \"static\",\n        \"struct\",\n        \"subscript\",\n        \"typealias\",\n        \"var\",\n        \n        // Keywords used in statements\n        \"break\",\n        \"case\",\n        \"catch\",\n        \"continue\",\n        \"default\",\n        \"defer\",\n        \"do\",\n        \"else\",\n        \"fallthrough\",\n        \"for\",\n        \"guard\",\n        \"if\",\n        \"in\",\n        \"repeat\",\n        \"return\",\n        \"throw\",\n        \"switch\",\n        \"where\",\n        \"while\",\n        \n        // Keywords used in expression and type\n        \"Any\",\n        \"as\",\n        \"catch\",\n        \"false\",\n        \"is\",\n        \"nil\",\n        \"rethrows\",\n        \"self\",\n        \"Self\",\n        \"super\",\n        \"throw\",\n        \"throws\",\n        \"true\",\n        \"try\",\n        \n        // Keywords used in the specific context\n        \"associativity\",\n        \"convenience\",\n        \"didSet\",\n        \"dynamic\",\n        \"final\",\n        \"get\",\n        \"indirect\",\n        \"infix\",\n        \"lazy\",\n        \"left\",\n        \"mutating\",\n        \"none\",\n        \"nonmutating\",\n        \"optional\",\n        \"override\",\n        \"postfix\",\n        \"precedence\",\n        \"prefix\",\n        \"Protocol\",\n        \"required\",\n        \"right\",\n        \"set\",\n        \"some\",\n        \"Type\",\n        \"unowned\",\n        \"weak\",\n        \"willSet\",\n    ]\n\n    static private let objcIdentifierRegex = try! NSRegularExpression(pattern: \"^[a-zA-Z_]+([a-zA-Z_0-9])*$\")\n\n    static func isValidIOSTypeName(iosTypeName: String) -> Bool {\n        return iosTypeName.matches(regex: objcIdentifierRegex)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Images/ImageConverter.swift",
    "content": "//\n//  ImageConverter.swift\n//  Compiler\n//\n//  Created by David Byttow on 10/23/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class ImageConverter {\n\n    let logger: ILogger\n    let fileManager: ValdiFileManager\n    let projectConfig: ValdiProjectConfig\n    let imageToolbox: ImageToolbox\n\n    init(logger: ILogger, fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, imageToolbox: ImageToolbox) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.imageToolbox = imageToolbox\n    }\n\n    struct ImageConversionInfo {\n        let renderSize: ImageSize\n        let outputSize: ImageSize\n        let density: String\n    }\n\n    private func computeExtent(desiredExtent: Int, scale: Double) -> Int {\n        let divider = Int(scale)\n        let remainder = desiredExtent % divider\n\n        return desiredExtent + remainder\n    }\n\n    public func getConversionInfo(sourceImage: ImageAssetVariant, targetVariantSpecs: ImageVariantSpecs) -> ImageConversionInfo {\n        let resolvedScale = 1.0 / sourceImage.variantSpecs.scale * targetVariantSpecs.scale\n        let targetSize = sourceImage.imageInfo.size.scaled(resolvedScale)\n\n        let density = String(Int(resolvedScale * 100)) + \"%\"\n\n        let extentWidth = computeExtent(desiredExtent: targetSize.width, scale: targetVariantSpecs.scale)\n        let extentHeight = computeExtent(desiredExtent: targetSize.height, scale: targetVariantSpecs.scale)\n\n        return ImageConversionInfo(renderSize: targetSize, outputSize: ImageSize(width: extentWidth, height: extentHeight), density: density)\n    }\n\n    func dependenciesVersions() throws -> [String: String] {\n        return [\n            \"pnquant\": try pngquantVersionString(),\n            \"image_toolbox\": try imageToolbox.getVersion()\n        ]\n    }\n\n    func pngquantCommand() -> String {\n        return projectConfig.pngquantURL?.path ?? \"pngquant\"\n    }\n\n    private func pngquantVersionString() throws -> String {\n        logger.debug(\"Resolving pngquant version\")\n        return try run(logger: logger, command: [\n            pngquantCommand(),\n            \"--version\"\n        ]).trimmed\n    }\n\n    private func optimizePNG(outputFileURL: URL) throws {\n        guard outputFileURL.pathExtension == \"png\" else {\n            return\n        }\n        \n        _ = try run(logger: logger,\n                    command: [\n                        pngquantCommand(),\n                        \"--skip-if-larger\",\n                        \"--ext=.png\",\n                        \"--force\",\n                        \"--speed=1\",\n                        \"--quality=70-90\",\n                        outputFileURL.path\n                    ])\n    }\n\n    public func convert(imageInfo: ImageInfo, filePath: String, outputFileURL: URL, conversionInfo: ImageConversionInfo) throws -> ImageInfo {\n        if conversionInfo.outputSize != conversionInfo.renderSize {\n            logger.warn(\"Image conversion outputSize doesn't match renderSize: \\(filePath) -> \\(outputFileURL.path)\\nThis usually means that the original image is not divisible by its display scale (e.g. @3x image with the size of 62x47).\")\n        }\n\n        try fileManager.createDirectory(at: outputFileURL.deletingLastPathComponent())\n\n        var qualityRatio: Double?\n        if outputFileURL.pathExtension == \"webp\" {\n            // matching the default quality value previously used by cwebp\n            qualityRatio = 0.75\n        }\n        try imageToolbox.convert(inputPath: filePath,\n                                 outputPath: outputFileURL.path,\n                                 outputWidth: conversionInfo.outputSize.width,\n                                 outputHeight: conversionInfo.outputSize.height,\n                                 qualityRatio: qualityRatio)\n\n        if outputFileURL.pathExtension == \"png\" {\n            try optimizePNG(outputFileURL: outputFileURL)\n        }\n\n        return ImageInfo(size: conversionInfo.outputSize)\n    }\n\n    private func run(logger: ILogger, command: [String]) throws -> String {\n        let handle = SyncProcessHandle.usingEnv(logger: logger, command: command)\n        try handle.run()\n        if !handle.stderr.content.isEmpty {\n            throw CompilerError(\"ImageConverter error: \" + handle.stderr.contentAsString)\n        }\n        return handle.stdout.contentAsString\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Images/ImageToolbox.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 8/2/22.\n//\n\nimport Foundation\n\nclass ImageToolbox {\n\n    private let toolboxExecutable: ToolboxExecutable\n\n    init(toolboxExecutable: ToolboxExecutable) {\n        self.toolboxExecutable = toolboxExecutable\n    }\n\n    func convert(inputPath: String, outputPath: String, outputWidth: Int, outputHeight: Int, qualityRatio: Double?) throws {\n        try toolboxExecutable.convertImage(inputFilePath: inputPath,\n                                           outputFilePath: outputPath,\n                                           outputWidth: outputWidth,\n                                           outputHeight: outputHeight,\n                                           qualityRatio: qualityRatio)\n    }\n\n    func getInfo(inputPath: String) throws -> ToolboxExecutable.ImageInfoOutput {\n        return try toolboxExecutable.getImageInfo(inputFilePath: inputPath)\n    }\n\n    func getVersion() throws -> String {\n        return try toolboxExecutable.getVersionString()\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Images/ImageVariantResolver.swift",
    "content": "//\n//  ImageVariantResolver.swift\n//  \n//\n//  Created by Simon Corsin on 2/12/20.\n//\n\nimport Foundation\n\nstruct ResolvedImageVariant {\n    let variant: ImageVariantSpecs\n    let assetIdentifier: ImageAssetIdentifier\n}\n\nclass ImageVariantResolver {\n\n    private static let iosVariantSpecs = [\n        ImageVariantSpecs(filenamePattern: \"$file@2x.png\", scale: 2.0, platform: .ios),\n        ImageVariantSpecs(filenamePattern: \"$file@3x.png\", scale: 3.0, platform: .ios)\n    ]\n\n    private static let androidVariantSpecs = [\n        ImageVariantSpecs(filenamePattern: \"drawable-mdpi/$file.webp\", scale: 1.0, platform: .android),\n        ImageVariantSpecs(filenamePattern: \"drawable-hdpi/$file.webp\", scale: 1.5, platform: .android),\n        ImageVariantSpecs(filenamePattern: \"drawable-xhdpi/$file.webp\", scale: 2.0, platform: .android),\n        ImageVariantSpecs(filenamePattern: \"drawable-xxhdpi/$file.webp\", scale: 3.0, platform: .android),\n        ImageVariantSpecs(filenamePattern: \"drawable-xxxhdpi/$file.webp\", scale: 4.0, platform: .android)\n    ]\n\n    private static let webVariantSpecs = [\n        ImageVariantSpecs(filenamePattern: \"$file.png\", scale: 3.0, platform: .web)\n    ]\n\n    private static let svgVariantSpecs = ImageVariantSpecs(filenamePattern: \"$file.svg\", scale: 1.0, platform: nil)\n\n    static let allExportedVariantSpecs = iosVariantSpecs + androidVariantSpecs + webVariantSpecs\n    static let allSupportedVariantSpecs = allExportedVariantSpecs + [svgVariantSpecs]\n\n    static func resolveVariant(imageURL: URL, relativeProjectPath: String) throws -> ResolvedImageVariant {\n        for variant in allSupportedVariantSpecs {\n            if let assetIdentifier = variant.matches(fileURL: imageURL, relativeProjectPath: relativeProjectPath) {\n                return ResolvedImageVariant(variant: variant, assetIdentifier: assetIdentifier)\n            }\n        }\n        \n        let supportedPatterns = allSupportedVariantSpecs.map { $0.filenamePattern }\n\n        throw CompilerError(\"Could not resolve image variant at file path: \\(imageURL.path).\\nIn order to use an image it must match one of the filename patterns:\\n\\(supportedPatterns.joined(separator: \"\\n\"))\")\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Images/ImageVariantSpecs.swift",
    "content": "//\n//  ImageVariantSpecs.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 2/12/20.\n//\n\nimport Foundation\n\nclass ImageVariantSpecs {\n    let identifier: String\n\n    let scale: Double\n    let platform: Platform?\n\n    let fileExtension: String\n\n    let filenamePattern: String\n    private let matchRegex: NSRegularExpression\n    private let componentsCount: Int\n\n    init(filenamePattern: String, scale: Double, platform: Platform?) {\n        self.filenamePattern = filenamePattern\n        self.scale = scale\n        self.platform = platform\n\n        if let platform = platform {\n            self.identifier = \"\\(platform)-\\(scale)\"\n        } else {\n            self.identifier = \"all-\\(scale)\"\n        }\n\n        self.fileExtension = String(filenamePattern.split(separator: \".\").last!)\n\n        self.componentsCount = filenamePattern.count { $0 == \"/\" } + 1\n\n        let filePattern = filenamePattern.replacingOccurrences(of: \".\", with: \"\\\\.\").replacingOccurrences(of: \"$file\", with: \"(.*)\")\n        let regexStr = \".*/\\(filePattern)$\"\n\n        self.matchRegex = try! NSRegularExpression(pattern: regexStr.replacingOccurrences(of: \"/\", with: \"\\\\/\"))\n    }\n\n    func matches(fileURL: URL, relativeProjectPath: String) -> ImageAssetIdentifier? {\n        let filePath = fileURL.path\n\n        guard let textResult = fileURL.path.getMatch(regex: matchRegex) else {\n            return nil\n        }\n\n        let fileRange = textResult.range(at: 1)\n\n        guard let fileName = filePath.substring(with: fileRange) else {\n            return nil\n        }\n\n        let assetName = fileName.replacingOccurrences(of: \"-\", with: \"_\")\n        let relativeProjectAssetDirectoryPath = (0..<self.componentsCount).reduce(relativeProjectPath, { path, _ in path.deletingLastPathComponent() })\n\n        return ImageAssetIdentifier(assetName: assetName, relativeProjectAssetDirectoryPath: relativeProjectAssetDirectoryPath)\n    }\n\n    func resolveFilename(assetName: String) -> String {\n        return \"\\(filenamePattern.replacingOccurrences(of: \"$file\", with: assetName))\"\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Kotlin/KotlinCompiler.swift",
    "content": "//\n//  KotlinCompiler.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass KotlinCompiler {\n\n    struct KotlinJsFile {\n        let url: URL\n        let relativePath: String\n    }\n\n    private var sentKotlinJsFile = false\n\n    private static let kotlinStdLibJsPath = \"node_modules/kotlin/kotlin.js\"\n    private static let expectedOutputPath = \"build/classes/kotlin/js/main/ValdiKotlin.js\"\n\n    func getKotlinJs(logger: ILogger, gradleDirURL: URL) throws -> KotlinJsFile {\n        let currentPath = FileManager.default.currentDirectoryPath\n        defer {\n            FileManager.default.changeCurrentDirectoryPath(currentPath)\n        }\n        FileManager.default.changeCurrentDirectoryPath(gradleDirURL.path)\n\n        let processHandle = SyncProcessHandle.usingEnv(logger: logger, command: [\"npm\", \"install\", \"kotlin\"])\n        try processHandle.run()\n\n        if !processHandle.exitedSuccesfully {\n            throw CompilerError(\"\\(processHandle.stderr.contentAsString)\")\n        }\n        let expectedOutputPathURL = gradleDirURL.appendingPathComponent(KotlinCompiler.kotlinStdLibJsPath)\n\n        if !FileManager.default.fileExists(atPath: expectedOutputPathURL.path) {\n            throw CompilerError(\"Did not find output file at expected location \\(expectedOutputPathURL.path)\")\n        }\n\n        return KotlinJsFile(url: expectedOutputPathURL, relativePath: KotlinCompiler.kotlinStdLibJsPath)\n    }\n\n    func compile(logger: ILogger, gradleDirURL: URL) throws -> KotlinJsFile {\n        let currentPath = FileManager.default.currentDirectoryPath\n        defer {\n            FileManager.default.changeCurrentDirectoryPath(currentPath)\n        }\n        FileManager.default.changeCurrentDirectoryPath(gradleDirURL.path)\n\n        let processHandle = SyncProcessHandle.usingEnv(logger: logger, command: [\"gradle\", \"jsMainClasses\"])\n        try processHandle.run()\n\n        if !processHandle.exitedSuccesfully {\n            throw CompilerError(\"\\(processHandle.stderr.contentAsString)\")\n        }\n\n        let expectedOutputPathURL = gradleDirURL.appendingPathComponent(KotlinCompiler.expectedOutputPath)\n\n        if !FileManager.default.fileExists(atPath: expectedOutputPathURL.path) {\n            throw CompilerError(\"Did not find output file at expected location \\(expectedOutputPathURL.path)\")\n        }\n\n        return KotlinJsFile(url: expectedOutputPathURL, relativePath: KotlinCompiler.expectedOutputPath)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Logs/LogsCleaner.swift",
    "content": "//\n//  LogsCleaner.swift\n//  \n//\n//  Created by saniul on 03/12/2021.\n//\n\nimport Foundation\n\n/// Cleans up outdated logs files\nfinal class LogsCleaner {\n    private let logger: ILogger\n    private let logsDirectoryURL: URL\n\n    init(logger: ILogger, logsDirectoryURL: URL) {\n        self.logger = logger\n        self.logsDirectoryURL = logsDirectoryURL\n    }\n\n    public func cleanLogsFilesIfNeeded() {\n        do {\n            try _cleanLogsFilesIfNeeded()\n        } catch {\n            logger.error(\"Failed to clean logs files from \\(logsDirectoryURL): \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    private func _listAllLogsFiles() throws -> [LogsFileProtocol] {\n        let fileURLs = try FileManager.default.contentsOfDirectory(at: logsDirectoryURL,\n                                                includingPropertiesForKeys: [.contentModificationDateKey,\n                                                     .fileSizeKey],\n                                                options: [])\n        let logsFiles = fileURLs\n            .filter({ $0.pathExtension == \"log\" })\n            .map(LogsFileHandle.init)\n        return logsFiles\n    }\n\n    private func _shouldDeleteLogsFile(_ file: LogsFileProtocol) -> Bool {\n        guard let modificationDate = file.modificationDate else {\n            return false\n        }\n\n        // delete logs that have not been modified in over 30 days\n        let isTooOld = abs(modificationDate.timeIntervalSinceNow) > 60 * 60 * 24 * 30\n        return isTooOld\n    }\n\n    private func _cleanLogsFilesIfNeeded() throws {\n        let logsFiles = try _listAllLogsFiles()\n        for logsFile in logsFiles {\n            if _shouldDeleteLogsFile(logsFile) {\n                logger.info(\"Deleting outdated log file at \\(logsFile.fileURL) (\\(logsFile.fileSizeString))...\")\n                do {\n                    try FileManager.default.removeItem(at: logsFile.fileURL)\n                } catch {\n                    logger.error(\"Failed to delete logs file at \\(logsFile.fileURL): \\(error.legibleLocalizedDescription)\")\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Logs/LogsFileHandle.swift",
    "content": "//\n//  LogsFileHandle.swift\n//  \n//\n//  Created by saniul on 03/12/2021.\n//\n\nimport Foundation\n\npublic protocol LogsFileProtocol {\n    var fileURL: URL { get }\n    var modificationDate: Date? { get }\n    var fileSize: Int { get }\n    var fileSizeString: String { get }\n}\n\nfinal class LogsFileHandle: LogsFileProtocol {\n    let fileURL: URL\n\n    init(fileURL: URL) {\n        self.fileURL = fileURL\n    }\n\n    var resourceValues: URLResourceValues? {\n        do {\n            return try fileURL.resourceValues(forKeys: [.contentModificationDateKey,\n                                             .fileSizeKey])\n        } catch let error as NSError {\n            print(\"URLResourceValues error: \\(error)\")\n        }\n        return nil\n    }\n\n    var modificationDate: Date? {\n        return resourceValues?.contentModificationDate\n    }\n\n    var fileSize: Int {\n        return resourceValues?.fileSize ?? 0\n    }\n\n    var fileSizeString: String {\n        return ByteCountFormatter.string(fromByteCount: Int64(fileSize),\n                                         countStyle: .file)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Logs/LogsRotator.swift",
    "content": "import Foundation\n\n/// Rotates logs files when they get too large.\n///\n/// Rotated logs files stop being regularly modified, so they will get cleaned up by LogsCleaner eventually.\npublic final class LogsRotator {\n    private let logger: ILogger\n    let logsDirectoryURL: URL\n\n    init(logger: ILogger, logsDirectoryURL: URL) {\n        self.logger = logger\n        self.logsDirectoryURL = logsDirectoryURL\n    }\n\n    public func rotateLogsFileIfNeeded(_ file: LogsFileProtocol) {\n        guard _shouldRotateLogsFile(file) else {\n            return\n        }\n\n        _rotateLogsFile(file)\n    }\n\n    private func _shouldRotateLogsFile(_ file: LogsFileProtocol) -> Bool {\n        guard file.fileSize > 0 else {\n            return false\n        }\n\n        // rotate logs after they grow larger than 100 MB\n        let isTooLarge = file.fileSize > 100_000_000\n        return isTooLarge\n    }\n\n    private func _rotateLogsFile(_ file: LogsFileProtocol) {\n        let fileName = file.fileURL.deletingPathExtension().lastPathComponent\n        // insert current timestamp between the existing filename and file extension\n        let newFileName = \"\\(fileName)-\\(Int(Date().timeIntervalSince1970)).\\(file.fileURL.pathExtension)\"\n        let newFileURL = logsDirectoryURL.appendingPathComponent(newFileName)\n\n        logger.info(\"Rotating log file from \\(file.fileURL) to \\(newFileURL)...\")\n        // we just don't care about conflicts, unlikely that we'd end up rotating a log file with the same name (same client id) again.\n        // It'd have to grow to be over the shouldRotateLogsFile instantly and the daemon service would have to disconnect and reconnect\n        // in the same second.\n        do {\n            let attributes = try FileManager.default.attributesOfItem(atPath: file.fileURL.path)\n            try FileManager.default.moveItem(at: file.fileURL, to: newFileURL)\n            FileManager.default.createFile(atPath: file.fileURL.path, contents: nil, attributes: attributes)\n        } catch {\n            logger.warn(\"Failed to rotate logs file from \\(file.fileURL) to \\(newFileURL): \\(error.legibleLocalizedDescription)\")\n        }\n\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Logs/LogsWriter.swift",
    "content": "//\n//  LogsWriter.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 2/19/19.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprivate let startEndSessionDelimiter = \"---------------\"\n\nfinal class LogsWriter {\n\n    let outputURL: URL\n\n    private let logger: ILogger\n    private let outputStream: OutputStream\n    private let queue = DispatchQueue(label: \"com.snap.valdi.LogsWriter\")\n\n    init(logger: ILogger, fileManager: ValdiFileManager, outputURL: URL) throws {\n        self.logger = logger\n        self.outputURL = outputURL\n\n        let directoryURL = outputURL.deletingLastPathComponent()\n        try fileManager.createDirectory(at: directoryURL)\n\n        if !FileManager.default.fileExists(atPath: outputURL.path) {\n            FileManager.default.createFile(atPath: outputURL.path, contents: nil, attributes: nil)\n        }\n\n        let logsRotator = LogsRotator(logger: logger, logsDirectoryURL: directoryURL)\n        logsRotator.rotateLogsFileIfNeeded(LogsFileHandle(fileURL: outputURL))\n\n        guard let outputStream = OutputStream(toFileAtPath: outputURL.path, append: true) else {\n            throw CompilerError(\"Unable to open output stream to write logs at \\(outputURL.path)\")\n        }\n        outputStream.open()\n\n        self.outputStream = outputStream\n\n        queue.async {\n            self.doWrite(formattedLog: \"\\n\\(startEndSessionDelimiter) Session started at \\(Date().description) \\(startEndSessionDelimiter)\\n\")\n        }\n    }\n\n    func close() {\n\n        queue.async {\n            self.doWrite(formattedLog: \"\\n\\(startEndSessionDelimiter) Session ended at \\(Date().description) \\(startEndSessionDelimiter)\\n\")\n            self.outputStream.close()\n        }\n    }\n\n    private func doWrite(formattedLog: String) {\n        do {\n            let data = try formattedLog.utf8Data()\n            data.withUnsafePointer { bufferStart in\n                _ = self.outputStream.write(bufferStart, maxLength: data.count)\n            }\n        } catch let error {\n            logger.error(\"Unable to convert log to utf8: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    func write(log: String) {\n        let date = Date()\n        queue.async {\n            let formattedLog = \"\\(date.description) \\(log)\\n\"\n            self.doWrite(formattedLog: formattedLog)\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/CompilationResult.swift",
    "content": "//\n//  CompilationResult.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct CompilationResult {\n\n    var componentPath: ComponentPath\n\n    var originalDocument: ValdiRawDocument\n\n    var templateResult: TemplateCompilerResult\n\n    let classMapping: ResolvedClassMapping\n\n    let userScriptSourceURL: URL?\n\n    let scriptLang: String\n\n    var symbolsToImportsInGeneratedCode = [TypeScriptSymbol]()\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/DependencyMetadata.swift",
    "content": "//\n//  DependencyMetadata.swift\n//  \n//\n//  Created by John Corbett on 5/15/23.\n//\n\nimport Foundation\n\nstruct DependencyMetadata {\n    let file: File\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/DownloadableArtifactSignatures.swift",
    "content": "//\n//  DownloadableArtifactSignatures.swift\n//\n//\n//  Created by Vasily Fomin on 9/22/23.\n//\n\n\nimport Foundation\n\nstruct DownloadableArtifactSignatures {\n    let key: String\n    let file: File\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/File.swift",
    "content": "//\n//  File.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nenum File {\n    case url(URL)\n    case data(Data)\n    case string(String)\n    case lazyData(block: () throws -> Data)\n}\n\nextension File {\n\n    func readData() throws -> Data {\n        switch self {\n        case .lazyData(let block):\n            let data = try block()\n            return data\n        case .data(let data):\n            return data\n        case .string(let str):\n            return try str.utf8Data()\n        case .url(let url):\n            do {\n                return try Data(contentsOf: url)\n            } catch {\n                throw CompilerError(\"Failed to read Data from \\(url): \\(error.legibleLocalizedDescription)\")\n            }\n        }\n    }\n\n    func readString() throws -> String {\n        if case let .string(str) = self {\n            return str\n        }\n\n        let data = try readData()\n        guard let str = String(data: data, encoding: .utf8) else {\n            throw CompilerError(\"Failed to read String from UTF8 Data\")\n        }\n        return str\n    }\n\n    func withURL<T>(_ urlClosure: (URL) throws -> T) throws -> T {\n        let urlHandle = try getURLHandle()\n        return try withExtendedLifetime(urlHandle) {\n            return try urlClosure(urlHandle.url)\n        }\n    }\n\n    func getURLHandle() throws -> URLHandle {\n        switch self {\n        case .url(let url):\n            return DefaultURLHandle(url: url)\n        case .data(let data):\n            return try disposableURLHandleForData(data: data)\n        case .string(let str):\n            return try disposableURLHandleForData(data: try str.utf8Data())\n        case .lazyData(let block):\n            let data = try block()\n            return try disposableURLHandleForData(data: data)\n        }\n    }\n\n    private func disposableURLHandleForData(data: Data) throws -> DisposableURLHandle {\n        let fileURL = URL.randomFileURL()\n        try data.write(to: fileURL)\n        return DisposableURLHandle(url: fileURL)\n    }\n}\n\n// File is only guaranteed to exist at the URL as long as the handle exists\nprotocol URLHandle: AnyObject {\n    var url: URL { get }\n}\n\nprivate class DefaultURLHandle: URLHandle {\n    let url: URL\n\n    init(url: URL) {\n        self.url = url\n    }\n}\n\nprivate class DisposableURLHandle: URLHandle {\n    let url: URL\n\n    init(url: URL) {\n        self.url = url\n    }\n\n    deinit {\n        _ = try? FileManager.default.removeItem(at: url)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/FinalFile.swift",
    "content": "//\n//  FinalFile.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct FinalFile {\n\n    let outputURL: URL\n    let file: File\n    let platform: Platform?\n    let kind: Kind\n\n    enum Kind {\n        case image(scale: Double?, isRemote: Bool)\n        case compiledSource\n        case nativeSource\n        case unknown\n        case assetsPackage\n        case dependencyInjectionData\n    }\n\n    var shouldBundle: Bool {\n        return platform != nil\n    }\n\n    func outputPath(relativeBundleURL: URL) -> String {\n        var path = relativeBundleURL\n            .deletingLastPathComponent()\n            .appendingPathComponent(outputURL.lastPathComponent)\n            .standardized.path\n\n        // On Linux URL.standardized doesn't remove \"./\"\n        while path.hasPrefix(\"./\") {\n            path = String(path[path.index(path.startIndex, offsetBy: 2)...])\n        }\n\n        return path\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/FontAsset.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nstruct FontAsset {\n    let name: String\n    let data: File\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/IgnoredFile.swift",
    "content": "//\n//  IgnoredFile.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/21/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct IgnoredFile {\n\n    let inputURL: URL\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/ImageAsset.swift",
    "content": "//\n//  ImageAsset.swift\n//  \n//\n//  Created by Simon Corsin on 2/12/20.\n//\n\nimport Foundation\n\nstruct ImageInfo: Equatable, Codable {\n    let size: ImageSize\n}\n\nstruct ImageSize: Equatable, Codable, CustomStringConvertible {\n    let width: Int\n    let height: Int\n\n    var cgSize: CGSize {\n        return CGSize(width: Double(width), height: Double(height))\n    }\n\n    var description: String {\n        return \"\\(width)x\\(height)\"\n    }\n\n    func scaled(_ scale: Double) -> ImageSize {\n        let scaledWidth = Int((Double(width) * scale).rounded())\n        let scaledheight = Int((Double(height) * scale).rounded())\n\n        return ImageSize(width: scaledWidth, height: scaledheight)\n    }\n}\n\nstruct ImageAssetVariant {\n    let imageInfo: ImageInfo\n    let file: File\n    let variantSpecs: ImageVariantSpecs\n}\n\nstruct ImageAssetIdentifier {\n    /**\n     A name identifying an asset accross all variants\n     */\n    let assetName: String\n\n    /**\n     Root directory which this asset lives, relative to the project path\n     */\n    let relativeProjectAssetDirectoryPath: String\n\n    /**\n     A virtual path which uniquely identifies an asset on the system\n     across all variants.\n     */\n    var virtualPath: String {\n        return \"\\(relativeProjectAssetDirectoryPath)/\\(assetName)\"\n    }\n}\n\nstruct ImageAsset {\n    let identifier: ImageAssetIdentifier\n    let size: ImageSize\n    let variants: [ImageAssetVariant]\n}\n\nextension ImageAsset {\n\n    var bestVariant: ImageAssetVariant? {\n        return ImageAsset.findHighestVariant(variants: variants)\n    }\n\n    static func findHighestVariant(variants: [ImageAssetVariant]) -> ImageAssetVariant? {\n        // Find if we have an SVG available, if we do, we use it for generating images\n        if let svgVariant = variants.first(where: { $0.variantSpecs.fileExtension == FileExtensions.svg }) {\n            return svgVariant\n        }\n\n        // Otherwise, find the variant with the highest scale\n        return variants.max { (lhs, rhs) -> Bool in\n            let left = lhs.variantSpecs\n            let right = rhs.variantSpecs\n            if left.scale > right.scale {\n                return false\n            } else if left.platform == .ios && right.platform == .android {\n                // If scales are equal, prefer the iOS png to stabilize the sort\n                return false\n            } else {\n                return true\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/ImageVariantsFilter.swift",
    "content": "// Copyright © 2025 Snap, Inc. All rights reserved.\n\nstruct ImageVariantsFilter: Decodable {\n\n    let scalesByPlatform: [Platform: [Double]]\n\n    init(scalesByPlatform: [Platform: [Double]]) {\n        self.scalesByPlatform = scalesByPlatform\n    }\n\n    func shouldInclude(platform: Platform, scale: Double) -> Bool {\n        guard let scales = scalesByPlatform[platform] else {\n            return true\n        }\n\n        return scales.contains(where: { $0 == scale })\n    }\n\n    static func parse(str: String) throws -> ImageVariantsFilter {\n        // example: android=2.0,3.0;ios=2.0\n        var scalesByPlatform = [Platform: [Double]]()\n        let components = str.split(separator: \";\")\n\n        for component in components {\n            let nested = component.split(separator: \"=\")\n\n            if nested.count != 2 {\n                throw CompilerError(\"Invalid image variants filter\")\n            }\n\n            guard let platform = Platform(rawValue: String(nested[0])) else {\n                throw CompilerError(\"Invalid platform '\\(nested[0])'\")\n            }\n\n            let unparsedScales = nested[1].split(separator: \",\")\n\n            let scales = try unparsedScales.map {\n                guard let scale = Double($0) else {\n                    throw CompilerError(\"Invalid scale '\\($0)'\")\n                }\n                return scale\n            }\n\n            scalesByPlatform[platform] = scales\n        }\n\n        return ImageVariantsFilter(scalesByPlatform: scalesByPlatform)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/JavaScriptFile.swift",
    "content": "//\n//  JavaScriptFile.swift\n//\n//\n//  Created by Simon Corsin on 1/24/20.\n//\n\nimport Foundation\n\nstruct JavaScriptFile {\n    let file: File\n    let relativePath: String\n\n    init(file: File, relativePath: String) {\n        self.file = file\n        self.relativePath = relativePath\n    }\n\n    func with(file: File) -> JavaScriptFile {\n        return JavaScriptFile(file: file, relativePath: self.relativePath)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/NativeSource.swift",
    "content": "//\n//  NativeSource.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct NativeSource {\n\n    let relativePath: String?\n    let filename: String\n    let file: File\n    /**\n     An identifier which helps with grouping NativeSource instances together when using singleFileCodegen.\n     */\n    let groupingIdentifier: String\n    /**\n     An integer that helps with sorting NativeSource instances when using singleFileCodegen.\n     */\n    let groupingPriority: Int\n\n    /**\n     The list of local dependencies that this NativeSource has, where each entry is the filename that should match another NativeSource.\n     This is used for single file codegen to help with dependency ordering. We write the sources that have no dependencies first.\n     */\n    let localFilenameDependencies: [String]\n\n    init(relativePath: String?, filename: String, file: File, groupingIdentifier: String, groupingPriority: Int, localFilenameDependencies: [String] = []) {\n        self.relativePath = relativePath\n        self.filename = filename\n        self.file = file\n        self.groupingIdentifier = groupingIdentifier\n        self.groupingPriority = groupingPriority\n        self.localFilenameDependencies = localFilenameDependencies\n    }\n\n    static func iosNativeSourcesFromGeneratedCode(_ generatedCode: GeneratedCode,\n                                                  iosType: IOSType,\n                                                  bundleInfo: CompilationItem.BundleInfo) throws -> [NativeSource] {\n        let typeName = iosType.name\n        let headerFilename = \"\\(typeName).h\"\n        let implFilename = \"\\(typeName).m\"\n\n        // import the api header in api implementation\n        generatedCode.apiImpl.appendHeader(\"#import \\\"\\(iosType.importHeaderFilename(kind: .apiOnly))\\\"\\n\\n\")\n        // import the api header in utility header\n        generatedCode.header.appendHeader(\"#import \\(iosType.importHeaderStatement)\\n\\n\")\n        // import the utility header in utility implementation\n        generatedCode.impl.appendHeader(\"#import \\\"\\(iosType.importHeaderFilename(kind: .withUtilities))\\\"\\n\\n\")\n\n        let groupingPriority: Int\n        switch iosType.kind {\n        case .enum:\n            groupingPriority = IOSType.enumTypeGroupingPriority\n        case .stringEnum:\n            groupingPriority = IOSType.enumStringTypeGroupingPriority\n        case .class:\n            groupingPriority = IOSType.classTypeGroupingPriority\n        case .interface:\n            groupingPriority = IOSType.interfaceTypeGroupingPriority\n        }\n\n        let headerData = try generatedCode.header.content.indented(indentPattern: \"    \").utf8Data()\n        let headerSource = NativeSource(relativePath: nil, filename: headerFilename, file: .data(headerData), groupingIdentifier: \"\\(bundleInfo.iosModuleName).h\", groupingPriority: groupingPriority)\n\n        let implData = try generatedCode.impl.content.indented(indentPattern: \"    \").utf8Data()\n        let implSource = NativeSource(relativePath: nil, filename: implFilename, file: .data(implData), groupingIdentifier: \"\\(bundleInfo.iosModuleName).m\", groupingPriority: groupingPriority)\n\n        var results = [headerSource, implSource]\n\n        let apiSourcesDirectoryRelativePath = \"../\\(bundleInfo.iosModuleName)\\(IOSType.HeaderImportKind.apiOnlyModuleNameSuffix)\"\n        let apiImplData = try generatedCode.apiImpl.content.indented(indentPattern: \"    \").utf8Data()\n        let apiImplFilename = \"\\(typeName).m\"\n        let apiImplSource = NativeSource(relativePath: apiSourcesDirectoryRelativePath,\n                                         filename: apiImplFilename,\n                                         file: .data(apiImplData),\n                                         groupingIdentifier: \"\\(bundleInfo.iosModuleName)\\(IOSType.HeaderImportKind.apiOnlyModuleNameSuffix).m\", groupingPriority: groupingPriority)\n        results.insert(apiImplSource, at: 0)\n\n        let apiHeaderData = try generatedCode.apiHeader.content.indented(indentPattern: \"    \").utf8Data()\n        let apiHeaderFilename = \"\\(typeName).h\"\n        let apiHeaderSource = NativeSource(relativePath: apiSourcesDirectoryRelativePath,\n                                           filename: apiHeaderFilename,\n                                           file: .data(apiHeaderData),\n                                           groupingIdentifier: \"\\(bundleInfo.iosModuleName)\\(IOSType.HeaderImportKind.apiOnlyModuleNameSuffix).h\", groupingPriority: groupingPriority)\n        results.insert(apiHeaderSource, at: 0)\n\n        return results\n    }\n}\n\nstruct NativeSourceAndPlatform {\n    let source: NativeSource\n    let platform: Platform\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/ResourceResult.swift",
    "content": "//\n//  ResourceResult.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/15/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ResourceResult {\n\n    let inputURL: URL\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/TransformedResource.swift",
    "content": "//\n//  TransformedResource.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 6/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ImageResource {\n    let outputFilename: String\n    let file: File\n    let imageScale: Double\n    let isRemote: Bool\n}\n\nstruct DocumentResource {\n    let outputFilename: String\n    let file: File\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/Valdi.pb.swift",
    "content": "// DO NOT EDIT.\n// swift-format-ignore-file\n//\n// Generated by the Swift generator plugin for the protocol buffer compiler.\n// Source: valdi.proto\n//\n// For information on using the generated types, please see the documentation:\n//   https://github.com/apple/swift-protobuf/\n\nimport Foundation\nimport SwiftProtobuf\n\n// If the compiler emits an error on this type, it is because this file\n// was generated by a version of the `protoc` Swift plug-in that is\n// incompatible with the version of SwiftProtobuf to which you are linking.\n// Please ensure that you are building against the same version of the API\n// that was used to generate this file.\nprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {\n  struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}\n  typealias Version = _2\n}\n\n/// Defines a static attribute name\n/// and its value.\nstruct Valdi_NodeAttribute {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var type: Valdi_NodeAttribute.TypeEnum = .nodeAttributeTypeString\n\n  var name: String = String()\n\n  /// Set if the type is STRING\n  var strValue: String = String()\n\n  /// Set if type is INT\n  var intValue: Int64 = 0\n\n  /// Set if double is INT\n  var doubleValue: Double = 0\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  enum TypeEnum: SwiftProtobuf.Enum {\n    typealias RawValue = Int\n    case nodeAttributeTypeString // = 0\n    case nodeAttributeTypeInt // = 1\n    case nodeAttributeTypeDouble // = 2\n    case UNRECOGNIZED(Int)\n\n    init() {\n      self = .nodeAttributeTypeString\n    }\n\n    init?(rawValue: Int) {\n      switch rawValue {\n      case 0: self = .nodeAttributeTypeString\n      case 1: self = .nodeAttributeTypeInt\n      case 2: self = .nodeAttributeTypeDouble\n      default: self = .UNRECOGNIZED(rawValue)\n      }\n    }\n\n    var rawValue: Int {\n      switch self {\n      case .nodeAttributeTypeString: return 0\n      case .nodeAttributeTypeInt: return 1\n      case .nodeAttributeTypeDouble: return 2\n      case .UNRECOGNIZED(let i): return i\n      }\n    }\n\n  }\n}\n\n#if swift(>=4.2)\n\nextension Valdi_NodeAttribute.TypeEnum: CaseIterable {\n  // The compiler won't synthesize support with the UNRECOGNIZED case.\n  static var allCases: [Valdi_NodeAttribute.TypeEnum] = [\n    .nodeAttributeTypeString,\n    .nodeAttributeTypeInt,\n    .nodeAttributeTypeDouble\n  ]\n}\n\n#endif  // swift(>=4.2)\n\nstruct Valdi_DownloadableModuleArtifact {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  /// The url on which the artifact can be downloaded.\n  var url: String = String()\n\n  /// The sha256 digest of the artifact data that can be used for verification.\n  var sha256Digest: Data = Data()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\nstruct Valdi_DownloadableModuleArtifactSignatures {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  // An array of artifacts sorted by url, generated by BundleResourcesProcessor.swift\n  var artifacts: [Valdi_DownloadableModuleArtifact] = []\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n}\n\n\nstruct Valdi_DownloadableModuleAssets {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var artifact: Valdi_DownloadableModuleArtifact {\n    get {return _artifact ?? Valdi_DownloadableModuleArtifact()}\n    set {_artifact = newValue}\n  }\n  /// Returns true if `artifact` has been explicitly set.\n  var hasArtifact: Bool {return self._artifact != nil}\n  /// Clears the value of `artifact`. Subsequent reads from it will return its default value.\n  mutating func clearArtifact() {self._artifact = nil}\n\n  /// The device density for which the assets contained\n  /// in this artifact are optimized for.\n  /// List of known density:\n  /// iPhone @2x: 2\n  /// iPhone @3x: 3\n  /// Android mdpi: 1\n  /// Android hdpi: 1.5\n  /// Android xhdpi: 2\n  /// Android xxhdpi: 3\n  /// Android xxxhdpi: 4\n  var deviceDensity: Double = 0\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n\n  fileprivate var _artifact: Valdi_DownloadableModuleArtifact?\n}\n\n/// Manifest stored in a .valdimodule when the module\n/// is downloadable. Contains all the dependencies and all\n/// the urls in which the artifact can be downloaded from.\nstruct Valdi_DownloadableModuleManifest {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  /// The name which uniquely identifies the module\n  var name: String = String()\n\n  /// Where to download the .valdimodule containing the compiled sources\n  /// Can be unset if this module only contains assets\n  var artifact: Valdi_DownloadableModuleArtifact {\n    get {return _artifact ?? Valdi_DownloadableModuleArtifact()}\n    set {_artifact = newValue}\n  }\n  /// Returns true if `artifact` has been explicitly set.\n  var hasArtifact: Bool {return self._artifact != nil}\n  /// Clears the value of `artifact`. Subsequent reads from it will return its default value.\n  mutating func clearArtifact() {self._artifact = nil}\n\n  /// The list of available artifacts containing the assets.\n  var assets: [Valdi_DownloadableModuleAssets] = []\n\n  /// The list of module dependencies on this module.\n  /// This can be used to ensure that they are available before\n  /// attempting to use the module.\n  var dependencies: [String] = []\n\n  /// Whether the downloadable assets are also available locally\n  var hasLocalAssets_p: Bool = false\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n\n  fileprivate var _artifact: Valdi_DownloadableModuleArtifact?\n}\n\nstruct Valdi_DaemonAwakeMessage {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  /// The list of device ids that should connect to the announced service\n  var deviceIds: [String] = []\n\n  /// The list of usernames that should connect to the announced service\n  var usernames: [String] = []\n\n  /// addresses at which the daemon service is listening\n  var serviceAddresses: [String] = []\n\n  /// port at which the daemon service is listening\n  var servicePort: Int32 = 0\n\n  /// The id of the daemon process\n  var processID: String = String()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\nstruct Valdi_ClientAwakeMessage {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var deviceID: String = String()\n\n  var username: String = String()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\nstruct Valdi_DaemonServiceDiscoveryPayload {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var message: Valdi_DaemonServiceDiscoveryPayload.OneOf_Message?\n\n  var daemonAwakeMessage: Valdi_DaemonAwakeMessage {\n    get {\n      if case .daemonAwakeMessage(let v)? = message {return v}\n      return Valdi_DaemonAwakeMessage()\n    }\n    set {message = .daemonAwakeMessage(newValue)}\n  }\n\n  var clientAwakeMessage: Valdi_ClientAwakeMessage {\n    get {\n      if case .clientAwakeMessage(let v)? = message {return v}\n      return Valdi_ClientAwakeMessage()\n    }\n    set {message = .clientAwakeMessage(newValue)}\n  }\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  enum OneOf_Message: Equatable {\n    case daemonAwakeMessage(Valdi_DaemonAwakeMessage)\n    case clientAwakeMessage(Valdi_ClientAwakeMessage)\n\n  #if !swift(>=4.1)\n    static func ==(lhs: Valdi_DaemonServiceDiscoveryPayload.OneOf_Message, rhs: Valdi_DaemonServiceDiscoveryPayload.OneOf_Message) -> Bool {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch (lhs, rhs) {\n      case (.daemonAwakeMessage, .daemonAwakeMessage): return {\n        guard case .daemonAwakeMessage(let l) = lhs, case .daemonAwakeMessage(let r) = rhs else { preconditionFailure() }\n        return l == r\n      }()\n      case (.clientAwakeMessage, .clientAwakeMessage): return {\n        guard case .clientAwakeMessage(let l) = lhs, case .clientAwakeMessage(let r) = rhs else { preconditionFailure() }\n        return l == r\n      }()\n      default: return false\n      }\n    }\n  #endif\n  }\n\n  init() {}\n}\n\nstruct Valdi_StyleNode {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var styles: [Valdi_StyleDeclaration] {\n    get {return _storage._styles}\n    set {_uniqueStorage()._styles = newValue}\n  }\n\n  var ruleIndex: Valdi_CSSRuleIndex {\n    get {return _storage._ruleIndex ?? Valdi_CSSRuleIndex()}\n    set {_uniqueStorage()._ruleIndex = newValue}\n  }\n  /// Returns true if `ruleIndex` has been explicitly set.\n  var hasRuleIndex: Bool {return _storage._ruleIndex != nil}\n  /// Clears the value of `ruleIndex`. Subsequent reads from it will return its default value.\n  mutating func clearRuleIndex() {_uniqueStorage()._ruleIndex = nil}\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n\n  fileprivate var _storage = _StorageClass.defaultInstance\n}\n\nstruct Valdi_StyleDeclaration {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var attribute: Valdi_NodeAttribute {\n    get {return _attribute ?? Valdi_NodeAttribute()}\n    set {_attribute = newValue}\n  }\n  /// Returns true if `attribute` has been explicitly set.\n  var hasAttribute: Bool {return self._attribute != nil}\n  /// Clears the value of `attribute`. Subsequent reads from it will return its default value.\n  mutating func clearAttribute() {self._attribute = nil}\n\n  /// value corresponding to CSS specificity\n  var priority: Int32 = 0\n\n  var order: Int32 = 0\n\n  var id: Int32 = 0\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n\n  fileprivate var _attribute: Valdi_NodeAttribute?\n}\n\nstruct Valdi_NamedStyleNode {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var name: String = String()\n\n  var node: Valdi_StyleNode {\n    get {return _node ?? Valdi_StyleNode()}\n    set {_node = newValue}\n  }\n  /// Returns true if `node` has been explicitly set.\n  var hasNode: Bool {return self._node != nil}\n  /// Clears the value of `node`. Subsequent reads from it will return its default value.\n  mutating func clearNode() {self._node = nil}\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n\n  fileprivate var _node: Valdi_StyleNode?\n}\n\nstruct Valdi_CSSRuleIndex {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  /// To determine the rules that match an element, elements should start with\n  /// the current element and the document's root CSSRuleIndex, and recur up\n  /// through matching ruleIndexes and the element's ancestry. For a particular\n  /// element and ruleIndex, the ruleIndex's properties should be checked in the\n  /// order they appear in this proto, and the current ruleIndex should be\n  /// reassigned if a match is found.\n  var idRules: [Valdi_NamedStyleNode] {\n    get {return _storage._idRules}\n    set {_uniqueStorage()._idRules = newValue}\n  }\n\n  var classRules: [Valdi_NamedStyleNode] {\n    get {return _storage._classRules}\n    set {_uniqueStorage()._classRules = newValue}\n  }\n\n  /// the universal selector is implemented as a tagRule with tag '*'\n  var tagRules: [Valdi_NamedStyleNode] {\n    get {return _storage._tagRules}\n    set {_uniqueStorage()._tagRules = newValue}\n  }\n\n  var attributeRules: [Valdi_CSSRuleIndex.AttributeRule] {\n    get {return _storage._attributeRules}\n    set {_uniqueStorage()._attributeRules = newValue}\n  }\n\n  var firstChildRule: Valdi_StyleNode {\n    get {return _storage._firstChildRule ?? Valdi_StyleNode()}\n    set {_uniqueStorage()._firstChildRule = newValue}\n  }\n  /// Returns true if `firstChildRule` has been explicitly set.\n  var hasFirstChildRule: Bool {return _storage._firstChildRule != nil}\n  /// Clears the value of `firstChildRule`. Subsequent reads from it will return its default value.\n  mutating func clearFirstChildRule() {_uniqueStorage()._firstChildRule = nil}\n\n  var lastChildRule: Valdi_StyleNode {\n    get {return _storage._lastChildRule ?? Valdi_StyleNode()}\n    set {_uniqueStorage()._lastChildRule = newValue}\n  }\n  /// Returns true if `lastChildRule` has been explicitly set.\n  var hasLastChildRule: Bool {return _storage._lastChildRule != nil}\n  /// Clears the value of `lastChildRule`. Subsequent reads from it will return its default value.\n  mutating func clearLastChildRule() {_uniqueStorage()._lastChildRule = nil}\n\n  var nthChildRules: [Valdi_CSSRuleIndex.NthChildRule] {\n    get {return _storage._nthChildRules}\n    set {_uniqueStorage()._nthChildRules = newValue}\n  }\n\n  var ancestorRules: Valdi_CSSRuleIndex {\n    get {return _storage._ancestorRules ?? Valdi_CSSRuleIndex()}\n    set {_uniqueStorage()._ancestorRules = newValue}\n  }\n  /// Returns true if `ancestorRules` has been explicitly set.\n  var hasAncestorRules: Bool {return _storage._ancestorRules != nil}\n  /// Clears the value of `ancestorRules`. Subsequent reads from it will return its default value.\n  mutating func clearAncestorRules() {_uniqueStorage()._ancestorRules = nil}\n\n  var directParentRules: Valdi_CSSRuleIndex {\n    get {return _storage._directParentRules ?? Valdi_CSSRuleIndex()}\n    set {_uniqueStorage()._directParentRules = newValue}\n  }\n  /// Returns true if `directParentRules` has been explicitly set.\n  var hasDirectParentRules: Bool {return _storage._directParentRules != nil}\n  /// Clears the value of `directParentRules`. Subsequent reads from it will return its default value.\n  mutating func clearDirectParentRules() {_uniqueStorage()._directParentRules = nil}\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  struct AttributeRule {\n    // SwiftProtobuf.Message conformance is added in an extension below. See the\n    // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n    // methods supported on all messages.\n\n    var type: Valdi_CSSRuleIndex.AttributeRule.TypeEnum = .equals\n\n    var attribute: Valdi_NodeAttribute {\n      get {return _attribute ?? Valdi_NodeAttribute()}\n      set {_attribute = newValue}\n    }\n    /// Returns true if `attribute` has been explicitly set.\n    var hasAttribute: Bool {return self._attribute != nil}\n    /// Clears the value of `attribute`. Subsequent reads from it will return its default value.\n    mutating func clearAttribute() {self._attribute = nil}\n\n    var node: Valdi_StyleNode {\n      get {return _node ?? Valdi_StyleNode()}\n      set {_node = newValue}\n    }\n    /// Returns true if `node` has been explicitly set.\n    var hasNode: Bool {return self._node != nil}\n    /// Clears the value of `node`. Subsequent reads from it will return its default value.\n    mutating func clearNode() {self._node = nil}\n\n    var unknownFields = SwiftProtobuf.UnknownStorage()\n\n    enum TypeEnum: SwiftProtobuf.Enum {\n      typealias RawValue = Int\n\n      /// [title=\"flower\"]\n      case equals // = 0\n\n      /// [title~=\"flower\"]\n      case containsWord // = 1\n\n      /// [title|=\"flower\"]\n      case startsWithWord // = 2\n\n      /// [title^=\"flower\"]\n      case startsWithSubstring // = 3\n\n      /// [title$=\"flower\"]\n      case endsWithSubstring // = 4\n\n      /// [title*=\"flower\"]\n      case containsSubstring // = 5\n\n      /// [title]\n      case hasAttribute // = 6\n      case UNRECOGNIZED(Int)\n\n      init() {\n        self = .equals\n      }\n\n      init?(rawValue: Int) {\n        switch rawValue {\n        case 0: self = .equals\n        case 1: self = .containsWord\n        case 2: self = .startsWithWord\n        case 3: self = .startsWithSubstring\n        case 4: self = .endsWithSubstring\n        case 5: self = .containsSubstring\n        case 6: self = .hasAttribute\n        default: self = .UNRECOGNIZED(rawValue)\n        }\n      }\n\n      var rawValue: Int {\n        switch self {\n        case .equals: return 0\n        case .containsWord: return 1\n        case .startsWithWord: return 2\n        case .startsWithSubstring: return 3\n        case .endsWithSubstring: return 4\n        case .containsSubstring: return 5\n        case .hasAttribute: return 6\n        case .UNRECOGNIZED(let i): return i\n        }\n      }\n\n    }\n\n    init() {}\n\n    fileprivate var _attribute: Valdi_NodeAttribute?\n    fileprivate var _node: Valdi_StyleNode?\n  }\n\n  struct NthChildRule {\n    // SwiftProtobuf.Message conformance is added in an extension below. See the\n    // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n    // methods supported on all messages.\n\n    var n: Int32 = 0\n\n    var offset: Int32 = 0\n\n    var node: Valdi_StyleNode {\n      get {return _node ?? Valdi_StyleNode()}\n      set {_node = newValue}\n    }\n    /// Returns true if `node` has been explicitly set.\n    var hasNode: Bool {return self._node != nil}\n    /// Clears the value of `node`. Subsequent reads from it will return its default value.\n    mutating func clearNode() {self._node = nil}\n\n    var unknownFields = SwiftProtobuf.UnknownStorage()\n\n    init() {}\n\n    fileprivate var _node: Valdi_StyleNode?\n  }\n\n  init() {}\n\n  fileprivate var _storage = _StorageClass.defaultInstance\n}\n\n#if swift(>=4.2)\n\nextension Valdi_CSSRuleIndex.AttributeRule.TypeEnum: CaseIterable {\n  // The compiler won't synthesize support with the UNRECOGNIZED case.\n  static var allCases: [Valdi_CSSRuleIndex.AttributeRule.TypeEnum] = [\n    .equals,\n    .containsWord,\n    .startsWithWord,\n    .startsWithSubstring,\n    .endsWithSubstring,\n    .containsSubstring,\n    .hasAttribute\n  ]\n}\n\n#endif  // swift(>=4.2)\n\n#if swift(>=5.5) && canImport(_Concurrency)\nextension Valdi_NodeAttribute: @unchecked Sendable {}\nextension Valdi_NodeAttribute.TypeEnum: @unchecked Sendable {}\nextension Valdi_DownloadableModuleArtifact: @unchecked Sendable {}\nextension Valdi_DownloadableModuleArtifactSignatures: @unchecked Sendable {}\nextension Valdi_DownloadableModuleAssets: @unchecked Sendable {}\nextension Valdi_DownloadableModuleManifest: @unchecked Sendable {}\nextension Valdi_DaemonAwakeMessage: @unchecked Sendable {}\nextension Valdi_ClientAwakeMessage: @unchecked Sendable {}\nextension Valdi_DaemonServiceDiscoveryPayload: @unchecked Sendable {}\nextension Valdi_DaemonServiceDiscoveryPayload.OneOf_Message: @unchecked Sendable {}\nextension Valdi_StyleNode: @unchecked Sendable {}\nextension Valdi_StyleDeclaration: @unchecked Sendable {}\nextension Valdi_NamedStyleNode: @unchecked Sendable {}\nextension Valdi_CSSRuleIndex: @unchecked Sendable {}\nextension Valdi_CSSRuleIndex.AttributeRule: @unchecked Sendable {}\nextension Valdi_CSSRuleIndex.AttributeRule.TypeEnum: @unchecked Sendable {}\nextension Valdi_CSSRuleIndex.NthChildRule: @unchecked Sendable {}\n#endif  // swift(>=5.5) && canImport(_Concurrency)\n\n// MARK: - Code below here is support for the SwiftProtobuf runtime.\n\nprivate let _protobuf_package = \"Valdi\"\n\nextension Valdi_NodeAttribute: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".NodeAttribute\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"type\"),\n    2: .same(proto: \"name\"),\n    3: .standard(proto: \"str_value\"),\n    4: .standard(proto: \"int_value\"),\n    5: .standard(proto: \"double_value\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularEnumField(value: &self.type) }()\n      case 2: try { try decoder.decodeSingularStringField(value: &self.name) }()\n      case 3: try { try decoder.decodeSingularStringField(value: &self.strValue) }()\n      case 4: try { try decoder.decodeSingularInt64Field(value: &self.intValue) }()\n      case 5: try { try decoder.decodeSingularDoubleField(value: &self.doubleValue) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if self.type != .nodeAttributeTypeString {\n      try visitor.visitSingularEnumField(value: self.type, fieldNumber: 1)\n    }\n    if !self.name.isEmpty {\n      try visitor.visitSingularStringField(value: self.name, fieldNumber: 2)\n    }\n    if !self.strValue.isEmpty {\n      try visitor.visitSingularStringField(value: self.strValue, fieldNumber: 3)\n    }\n    if self.intValue != 0 {\n      try visitor.visitSingularInt64Field(value: self.intValue, fieldNumber: 4)\n    }\n    if self.doubleValue != 0 {\n      try visitor.visitSingularDoubleField(value: self.doubleValue, fieldNumber: 5)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_NodeAttribute, rhs: Valdi_NodeAttribute) -> Bool {\n    if lhs.type != rhs.type {return false}\n    if lhs.name != rhs.name {return false}\n    if lhs.strValue != rhs.strValue {return false}\n    if lhs.intValue != rhs.intValue {return false}\n    if lhs.doubleValue != rhs.doubleValue {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_NodeAttribute.TypeEnum: SwiftProtobuf._ProtoNameProviding {\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    0: .same(proto: \"NODE_ATTRIBUTE_TYPE_STRING\"),\n    1: .same(proto: \"NODE_ATTRIBUTE_TYPE_INT\"),\n    2: .same(proto: \"NODE_ATTRIBUTE_TYPE_DOUBLE\")\n  ]\n}\n\nextension Valdi_DownloadableModuleArtifact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".DownloadableModuleArtifact\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"url\"),\n    2: .same(proto: \"sha256Digest\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.url) }()\n      case 2: try { try decoder.decodeSingularBytesField(value: &self.sha256Digest) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.url.isEmpty {\n      try visitor.visitSingularStringField(value: self.url, fieldNumber: 1)\n    }\n    if !self.sha256Digest.isEmpty {\n      try visitor.visitSingularBytesField(value: self.sha256Digest, fieldNumber: 2)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_DownloadableModuleArtifact, rhs: Valdi_DownloadableModuleArtifact) -> Bool {\n    if lhs.url != rhs.url {return false}\n    if lhs.sha256Digest != rhs.sha256Digest {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_DownloadableModuleArtifactSignatures: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".DownloadableModuleArtifact\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"artifacts\"),\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeRepeatedMessageField(value: &self.artifacts) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.artifacts.isEmpty {\n        try visitor.visitRepeatedMessageField(value: self.artifacts, fieldNumber: 1)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_DownloadableModuleArtifactSignatures, rhs: Valdi_DownloadableModuleArtifactSignatures) -> Bool {\n    if lhs.artifacts != rhs.artifacts {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\n\nextension Valdi_DownloadableModuleAssets: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".DownloadableModuleAssets\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"artifact\"),\n    3: .standard(proto: \"device_density\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularMessageField(value: &self._artifact) }()\n      case 3: try { try decoder.decodeSingularDoubleField(value: &self.deviceDensity) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    try { if let v = self._artifact {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 1)\n    } }()\n    if self.deviceDensity != 0 {\n      try visitor.visitSingularDoubleField(value: self.deviceDensity, fieldNumber: 3)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_DownloadableModuleAssets, rhs: Valdi_DownloadableModuleAssets) -> Bool {\n    if lhs._artifact != rhs._artifact {return false}\n    if lhs.deviceDensity != rhs.deviceDensity {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_DownloadableModuleManifest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".DownloadableModuleManifest\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"name\"),\n    2: .same(proto: \"artifact\"),\n    3: .same(proto: \"assets\"),\n    4: .same(proto: \"dependencies\"),\n    5: .standard(proto: \"has_local_assets\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()\n      case 2: try { try decoder.decodeSingularMessageField(value: &self._artifact) }()\n      case 3: try { try decoder.decodeRepeatedMessageField(value: &self.assets) }()\n      case 4: try { try decoder.decodeRepeatedStringField(value: &self.dependencies) }()\n      case 5: try { try decoder.decodeSingularBoolField(value: &self.hasLocalAssets_p) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    if !self.name.isEmpty {\n      try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)\n    }\n    try { if let v = self._artifact {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 2)\n    } }()\n    if !self.assets.isEmpty {\n      try visitor.visitRepeatedMessageField(value: self.assets, fieldNumber: 3)\n    }\n    if !self.dependencies.isEmpty {\n      try visitor.visitRepeatedStringField(value: self.dependencies, fieldNumber: 4)\n    }\n    if self.hasLocalAssets_p != false {\n      try visitor.visitSingularBoolField(value: self.hasLocalAssets_p, fieldNumber: 5)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_DownloadableModuleManifest, rhs: Valdi_DownloadableModuleManifest) -> Bool {\n    if lhs.name != rhs.name {return false}\n    if lhs._artifact != rhs._artifact {return false}\n    if lhs.assets != rhs.assets {return false}\n    if lhs.dependencies != rhs.dependencies {return false}\n    if lhs.hasLocalAssets_p != rhs.hasLocalAssets_p {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_DaemonAwakeMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".DaemonAwakeMessage\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    16: .standard(proto: \"device_ids\"),\n    17: .same(proto: \"usernames\"),\n    1: .standard(proto: \"service_addresses\"),\n    2: .standard(proto: \"service_port\"),\n    3: .standard(proto: \"process_id\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeRepeatedStringField(value: &self.serviceAddresses) }()\n      case 2: try { try decoder.decodeSingularInt32Field(value: &self.servicePort) }()\n      case 3: try { try decoder.decodeSingularStringField(value: &self.processID) }()\n      case 16: try { try decoder.decodeRepeatedStringField(value: &self.deviceIds) }()\n      case 17: try { try decoder.decodeRepeatedStringField(value: &self.usernames) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.serviceAddresses.isEmpty {\n      try visitor.visitRepeatedStringField(value: self.serviceAddresses, fieldNumber: 1)\n    }\n    if self.servicePort != 0 {\n      try visitor.visitSingularInt32Field(value: self.servicePort, fieldNumber: 2)\n    }\n    if !self.processID.isEmpty {\n      try visitor.visitSingularStringField(value: self.processID, fieldNumber: 3)\n    }\n    if !self.deviceIds.isEmpty {\n      try visitor.visitRepeatedStringField(value: self.deviceIds, fieldNumber: 16)\n    }\n    if !self.usernames.isEmpty {\n      try visitor.visitRepeatedStringField(value: self.usernames, fieldNumber: 17)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_DaemonAwakeMessage, rhs: Valdi_DaemonAwakeMessage) -> Bool {\n    if lhs.deviceIds != rhs.deviceIds {return false}\n    if lhs.usernames != rhs.usernames {return false}\n    if lhs.serviceAddresses != rhs.serviceAddresses {return false}\n    if lhs.servicePort != rhs.servicePort {return false}\n    if lhs.processID != rhs.processID {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_ClientAwakeMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".ClientAwakeMessage\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .standard(proto: \"device_id\"),\n    2: .same(proto: \"username\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.deviceID) }()\n      case 2: try { try decoder.decodeSingularStringField(value: &self.username) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.deviceID.isEmpty {\n      try visitor.visitSingularStringField(value: self.deviceID, fieldNumber: 1)\n    }\n    if !self.username.isEmpty {\n      try visitor.visitSingularStringField(value: self.username, fieldNumber: 2)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_ClientAwakeMessage, rhs: Valdi_ClientAwakeMessage) -> Bool {\n    if lhs.deviceID != rhs.deviceID {return false}\n    if lhs.username != rhs.username {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_DaemonServiceDiscoveryPayload: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".DaemonServiceDiscoveryPayload\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .standard(proto: \"daemon_awake_message\"),\n    2: .standard(proto: \"client_awake_message\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try {\n        var v: Valdi_DaemonAwakeMessage?\n        var hadOneofValue = false\n        if let current = self.message {\n          hadOneofValue = true\n          if case .daemonAwakeMessage(let m) = current {v = m}\n        }\n        try decoder.decodeSingularMessageField(value: &v)\n        if let v = v {\n          if hadOneofValue {try decoder.handleConflictingOneOf()}\n          self.message = .daemonAwakeMessage(v)\n        }\n      }()\n      case 2: try {\n        var v: Valdi_ClientAwakeMessage?\n        var hadOneofValue = false\n        if let current = self.message {\n          hadOneofValue = true\n          if case .clientAwakeMessage(let m) = current {v = m}\n        }\n        try decoder.decodeSingularMessageField(value: &v)\n        if let v = v {\n          if hadOneofValue {try decoder.handleConflictingOneOf()}\n          self.message = .clientAwakeMessage(v)\n        }\n      }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    switch self.message {\n    case .daemonAwakeMessage?: try {\n      guard case .daemonAwakeMessage(let v)? = self.message else { preconditionFailure() }\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 1)\n    }()\n    case .clientAwakeMessage?: try {\n      guard case .clientAwakeMessage(let v)? = self.message else { preconditionFailure() }\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 2)\n    }()\n    case nil: break\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_DaemonServiceDiscoveryPayload, rhs: Valdi_DaemonServiceDiscoveryPayload) -> Bool {\n    if lhs.message != rhs.message {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_StyleNode: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".StyleNode\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"styles\"),\n    2: .same(proto: \"ruleIndex\")\n  ]\n\n  fileprivate class _StorageClass {\n    var _styles: [Valdi_StyleDeclaration] = []\n    var _ruleIndex: Valdi_CSSRuleIndex?\n\n    static let defaultInstance = _StorageClass()\n\n    private init() {}\n\n    init(copying source: _StorageClass) {\n      _styles = source._styles\n      _ruleIndex = source._ruleIndex\n    }\n  }\n\n  fileprivate mutating func _uniqueStorage() -> _StorageClass {\n    if !isKnownUniquelyReferenced(&_storage) {\n      _storage = _StorageClass(copying: _storage)\n    }\n    return _storage\n  }\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    _ = _uniqueStorage()\n    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in\n      while let fieldNumber = try decoder.nextFieldNumber() {\n        // The use of inline closures is to circumvent an issue where the compiler\n        // allocates stack space for every case branch when no optimizations are\n        // enabled. https://github.com/apple/swift-protobuf/issues/1034\n        switch fieldNumber {\n        case 1: try { try decoder.decodeRepeatedMessageField(value: &_storage._styles) }()\n        case 2: try { try decoder.decodeSingularMessageField(value: &_storage._ruleIndex) }()\n        default: break\n        }\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every if/case branch local when no optimizations\n      // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n      // https://github.com/apple/swift-protobuf/issues/1182\n      if !_storage._styles.isEmpty {\n        try visitor.visitRepeatedMessageField(value: _storage._styles, fieldNumber: 1)\n      }\n      try { if let v = _storage._ruleIndex {\n        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)\n      } }()\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_StyleNode, rhs: Valdi_StyleNode) -> Bool {\n    if lhs._storage !== rhs._storage {\n      let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in\n        let _storage = _args.0\n        let rhs_storage = _args.1\n        if _storage._styles != rhs_storage._styles {return false}\n        if _storage._ruleIndex != rhs_storage._ruleIndex {return false}\n        return true\n      }\n      if !storagesAreEqual {return false}\n    }\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_StyleDeclaration: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".StyleDeclaration\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"attribute\"),\n    2: .same(proto: \"priority\"),\n    3: .same(proto: \"order\"),\n    4: .same(proto: \"id\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularMessageField(value: &self._attribute) }()\n      case 2: try { try decoder.decodeSingularInt32Field(value: &self.priority) }()\n      case 3: try { try decoder.decodeSingularInt32Field(value: &self.order) }()\n      case 4: try { try decoder.decodeSingularInt32Field(value: &self.id) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    try { if let v = self._attribute {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 1)\n    } }()\n    if self.priority != 0 {\n      try visitor.visitSingularInt32Field(value: self.priority, fieldNumber: 2)\n    }\n    if self.order != 0 {\n      try visitor.visitSingularInt32Field(value: self.order, fieldNumber: 3)\n    }\n    if self.id != 0 {\n      try visitor.visitSingularInt32Field(value: self.id, fieldNumber: 4)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_StyleDeclaration, rhs: Valdi_StyleDeclaration) -> Bool {\n    if lhs._attribute != rhs._attribute {return false}\n    if lhs.priority != rhs.priority {return false}\n    if lhs.order != rhs.order {return false}\n    if lhs.id != rhs.id {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_NamedStyleNode: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".NamedStyleNode\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"name\"),\n    2: .same(proto: \"node\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()\n      case 2: try { try decoder.decodeSingularMessageField(value: &self._node) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    if !self.name.isEmpty {\n      try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)\n    }\n    try { if let v = self._node {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 2)\n    } }()\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_NamedStyleNode, rhs: Valdi_NamedStyleNode) -> Bool {\n    if lhs.name != rhs.name {return false}\n    if lhs._node != rhs._node {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_CSSRuleIndex: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".CSSRuleIndex\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .standard(proto: \"id_rules\"),\n    2: .standard(proto: \"class_rules\"),\n    3: .standard(proto: \"tag_rules\"),\n    4: .standard(proto: \"attribute_rules\"),\n    5: .standard(proto: \"first_child_rule\"),\n    6: .standard(proto: \"last_child_rule\"),\n    7: .standard(proto: \"nth_child_rules\"),\n    8: .standard(proto: \"ancestor_rules\"),\n    9: .standard(proto: \"direct_parent_rules\")\n  ]\n\n  fileprivate class _StorageClass {\n    var _idRules: [Valdi_NamedStyleNode] = []\n    var _classRules: [Valdi_NamedStyleNode] = []\n    var _tagRules: [Valdi_NamedStyleNode] = []\n    var _attributeRules: [Valdi_CSSRuleIndex.AttributeRule] = []\n    var _firstChildRule: Valdi_StyleNode?\n    var _lastChildRule: Valdi_StyleNode?\n    var _nthChildRules: [Valdi_CSSRuleIndex.NthChildRule] = []\n    var _ancestorRules: Valdi_CSSRuleIndex?\n    var _directParentRules: Valdi_CSSRuleIndex?\n\n    static let defaultInstance = _StorageClass()\n\n    private init() {}\n\n    init(copying source: _StorageClass) {\n      _idRules = source._idRules\n      _classRules = source._classRules\n      _tagRules = source._tagRules\n      _attributeRules = source._attributeRules\n      _firstChildRule = source._firstChildRule\n      _lastChildRule = source._lastChildRule\n      _nthChildRules = source._nthChildRules\n      _ancestorRules = source._ancestorRules\n      _directParentRules = source._directParentRules\n    }\n  }\n\n  fileprivate mutating func _uniqueStorage() -> _StorageClass {\n    if !isKnownUniquelyReferenced(&_storage) {\n      _storage = _StorageClass(copying: _storage)\n    }\n    return _storage\n  }\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    _ = _uniqueStorage()\n    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in\n      while let fieldNumber = try decoder.nextFieldNumber() {\n        // The use of inline closures is to circumvent an issue where the compiler\n        // allocates stack space for every case branch when no optimizations are\n        // enabled. https://github.com/apple/swift-protobuf/issues/1034\n        switch fieldNumber {\n        case 1: try { try decoder.decodeRepeatedMessageField(value: &_storage._idRules) }()\n        case 2: try { try decoder.decodeRepeatedMessageField(value: &_storage._classRules) }()\n        case 3: try { try decoder.decodeRepeatedMessageField(value: &_storage._tagRules) }()\n        case 4: try { try decoder.decodeRepeatedMessageField(value: &_storage._attributeRules) }()\n        case 5: try { try decoder.decodeSingularMessageField(value: &_storage._firstChildRule) }()\n        case 6: try { try decoder.decodeSingularMessageField(value: &_storage._lastChildRule) }()\n        case 7: try { try decoder.decodeRepeatedMessageField(value: &_storage._nthChildRules) }()\n        case 8: try { try decoder.decodeSingularMessageField(value: &_storage._ancestorRules) }()\n        case 9: try { try decoder.decodeSingularMessageField(value: &_storage._directParentRules) }()\n        default: break\n        }\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every if/case branch local when no optimizations\n      // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n      // https://github.com/apple/swift-protobuf/issues/1182\n      if !_storage._idRules.isEmpty {\n        try visitor.visitRepeatedMessageField(value: _storage._idRules, fieldNumber: 1)\n      }\n      if !_storage._classRules.isEmpty {\n        try visitor.visitRepeatedMessageField(value: _storage._classRules, fieldNumber: 2)\n      }\n      if !_storage._tagRules.isEmpty {\n        try visitor.visitRepeatedMessageField(value: _storage._tagRules, fieldNumber: 3)\n      }\n      if !_storage._attributeRules.isEmpty {\n        try visitor.visitRepeatedMessageField(value: _storage._attributeRules, fieldNumber: 4)\n      }\n      try { if let v = _storage._firstChildRule {\n        try visitor.visitSingularMessageField(value: v, fieldNumber: 5)\n      } }()\n      try { if let v = _storage._lastChildRule {\n        try visitor.visitSingularMessageField(value: v, fieldNumber: 6)\n      } }()\n      if !_storage._nthChildRules.isEmpty {\n        try visitor.visitRepeatedMessageField(value: _storage._nthChildRules, fieldNumber: 7)\n      }\n      try { if let v = _storage._ancestorRules {\n        try visitor.visitSingularMessageField(value: v, fieldNumber: 8)\n      } }()\n      try { if let v = _storage._directParentRules {\n        try visitor.visitSingularMessageField(value: v, fieldNumber: 9)\n      } }()\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_CSSRuleIndex, rhs: Valdi_CSSRuleIndex) -> Bool {\n    if lhs._storage !== rhs._storage {\n      let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in\n        let _storage = _args.0\n        let rhs_storage = _args.1\n        if _storage._idRules != rhs_storage._idRules {return false}\n        if _storage._classRules != rhs_storage._classRules {return false}\n        if _storage._tagRules != rhs_storage._tagRules {return false}\n        if _storage._attributeRules != rhs_storage._attributeRules {return false}\n        if _storage._firstChildRule != rhs_storage._firstChildRule {return false}\n        if _storage._lastChildRule != rhs_storage._lastChildRule {return false}\n        if _storage._nthChildRules != rhs_storage._nthChildRules {return false}\n        if _storage._ancestorRules != rhs_storage._ancestorRules {return false}\n        if _storage._directParentRules != rhs_storage._directParentRules {return false}\n        return true\n      }\n      if !storagesAreEqual {return false}\n    }\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_CSSRuleIndex.AttributeRule: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = Valdi_CSSRuleIndex.protoMessageName + \".AttributeRule\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"type\"),\n    2: .same(proto: \"attribute\"),\n    3: .same(proto: \"node\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularEnumField(value: &self.type) }()\n      case 2: try { try decoder.decodeSingularMessageField(value: &self._attribute) }()\n      case 3: try { try decoder.decodeSingularMessageField(value: &self._node) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    if self.type != .equals {\n      try visitor.visitSingularEnumField(value: self.type, fieldNumber: 1)\n    }\n    try { if let v = self._attribute {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 2)\n    } }()\n    try { if let v = self._node {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 3)\n    } }()\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_CSSRuleIndex.AttributeRule, rhs: Valdi_CSSRuleIndex.AttributeRule) -> Bool {\n    if lhs.type != rhs.type {return false}\n    if lhs._attribute != rhs._attribute {return false}\n    if lhs._node != rhs._node {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension Valdi_CSSRuleIndex.AttributeRule.TypeEnum: SwiftProtobuf._ProtoNameProviding {\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    0: .same(proto: \"EQUALS\"),\n    1: .same(proto: \"CONTAINS_WORD\"),\n    2: .same(proto: \"STARTS_WITH_WORD\"),\n    3: .same(proto: \"STARTS_WITH_SUBSTRING\"),\n    4: .same(proto: \"ENDS_WITH_SUBSTRING\"),\n    5: .same(proto: \"CONTAINS_SUBSTRING\"),\n    6: .same(proto: \"HAS_ATTRIBUTE\")\n  ]\n}\n\nextension Valdi_CSSRuleIndex.NthChildRule: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = Valdi_CSSRuleIndex.protoMessageName + \".NthChildRule\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"n\"),\n    2: .same(proto: \"offset\"),\n    3: .same(proto: \"node\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularInt32Field(value: &self.n) }()\n      case 2: try { try decoder.decodeSingularInt32Field(value: &self.offset) }()\n      case 3: try { try decoder.decodeSingularMessageField(value: &self._node) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    if self.n != 0 {\n      try visitor.visitSingularInt32Field(value: self.n, fieldNumber: 1)\n    }\n    if self.offset != 0 {\n      try visitor.visitSingularInt32Field(value: self.offset, fieldNumber: 2)\n    }\n    try { if let v = self._node {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 3)\n    } }()\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: Valdi_CSSRuleIndex.NthChildRule, rhs: Valdi_CSSRuleIndex.NthChildRule) -> Bool {\n    if lhs.n != rhs.n {return false}\n    if lhs.offset != rhs.offset {return false}\n    if lhs._node != rhs._node {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/ZippableItem.swift",
    "content": "//\n//  ZippableItem.swift\n//  \n//\n//  Created by saniul on 21/10/2019.\n//\n\nimport Foundation\n\nstruct ZippableItem {\n    let file: File\n    let path: String\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/valdi-artifact-management.pb.swift",
    "content": "// DO NOT EDIT.\n// swift-format-ignore-file\n// swiftlint:disable all\n//\n// Generated by the Swift generator plugin for the protocol buffer compiler.\n// Source: valdi-artifact-management.proto\n//\n// For information on using the generated types, please see the documentation:\n//   https://github.com/apple/swift-protobuf/\n\nimport Foundation\nimport SwiftProtobuf\n\n// If the compiler emits an error on this type, it is because this file\n// was generated by a version of the `protoc` Swift plug-in that is\n// incompatible with the version of SwiftProtobuf to which you are linking.\n// Please ensure that you are building against the same version of the API\n// that was used to generate this file.\nfileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {\n  struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}\n  typealias Version = _2\n}\n\n/// Endpoint suffix: /uploadArtifact\nstruct ValdiArtifactManagement_UploadArtifactRequest: @unchecked Sendable {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  /// A unique key generated by the client.\n  /// If an item already exists at this key, it should\n  /// be replaced\n  var key: String = String()\n\n  /// The human-readable name of the artifact. It doesn't need to be unique\n  var name: String = String()\n\n  /// The bytes contents of the artifact\n  var data: Data = Data()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n}\n\nstruct ValdiArtifactManagement_UploadArtifactResponse: Sendable {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var success: Bool = false\n\n  var errorMessage: String = String()\n\n  var url: String = String()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n}\n\n/// Endpoint suffix: /getArtifact\nstruct ValdiArtifactManagement_GetArtifactRequest: Sendable {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var key: String = String()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n}\n\nstruct ValdiArtifactManagement_GetArtifactResponse: Sendable {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var success: Bool = false\n\n  var errorMessage: String = String()\n\n  var url: String = String()\n\n  var name: String = String()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n}\n\nstruct ValdiArtifactManagement_ManagedArtifact: Sendable {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var key: String = String()\n\n  var url: String = String()\n\n  var name: String = String()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n}\n\n// MARK: - Code below here is support for the SwiftProtobuf runtime.\n\nfileprivate let _protobuf_package = \"ValdiArtifactManagement\"\n\nextension ValdiArtifactManagement_UploadArtifactRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".UploadArtifactRequest\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"key\"),\n    2: .same(proto: \"name\"),\n    3: .same(proto: \"data\"),\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.key) }()\n      case 2: try { try decoder.decodeSingularStringField(value: &self.name) }()\n      case 3: try { try decoder.decodeSingularBytesField(value: &self.data) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.key.isEmpty {\n      try visitor.visitSingularStringField(value: self.key, fieldNumber: 1)\n    }\n    if !self.name.isEmpty {\n      try visitor.visitSingularStringField(value: self.name, fieldNumber: 2)\n    }\n    if !self.data.isEmpty {\n      try visitor.visitSingularBytesField(value: self.data, fieldNumber: 3)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiArtifactManagement_UploadArtifactRequest, rhs: ValdiArtifactManagement_UploadArtifactRequest) -> Bool {\n    if lhs.key != rhs.key {return false}\n    if lhs.name != rhs.name {return false}\n    if lhs.data != rhs.data {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiArtifactManagement_UploadArtifactResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".UploadArtifactResponse\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"success\"),\n    2: .standard(proto: \"error_message\"),\n    3: .same(proto: \"url\"),\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularBoolField(value: &self.success) }()\n      case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }()\n      case 3: try { try decoder.decodeSingularStringField(value: &self.url) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if self.success != false {\n      try visitor.visitSingularBoolField(value: self.success, fieldNumber: 1)\n    }\n    if !self.errorMessage.isEmpty {\n      try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2)\n    }\n    if !self.url.isEmpty {\n      try visitor.visitSingularStringField(value: self.url, fieldNumber: 3)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiArtifactManagement_UploadArtifactResponse, rhs: ValdiArtifactManagement_UploadArtifactResponse) -> Bool {\n    if lhs.success != rhs.success {return false}\n    if lhs.errorMessage != rhs.errorMessage {return false}\n    if lhs.url != rhs.url {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiArtifactManagement_GetArtifactRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".GetArtifactRequest\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"key\"),\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.key) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.key.isEmpty {\n      try visitor.visitSingularStringField(value: self.key, fieldNumber: 1)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiArtifactManagement_GetArtifactRequest, rhs: ValdiArtifactManagement_GetArtifactRequest) -> Bool {\n    if lhs.key != rhs.key {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiArtifactManagement_GetArtifactResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".GetArtifactResponse\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"success\"),\n    2: .standard(proto: \"error_message\"),\n    3: .same(proto: \"url\"),\n    4: .same(proto: \"name\"),\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularBoolField(value: &self.success) }()\n      case 2: try { try decoder.decodeSingularStringField(value: &self.errorMessage) }()\n      case 3: try { try decoder.decodeSingularStringField(value: &self.url) }()\n      case 4: try { try decoder.decodeSingularStringField(value: &self.name) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if self.success != false {\n      try visitor.visitSingularBoolField(value: self.success, fieldNumber: 1)\n    }\n    if !self.errorMessage.isEmpty {\n      try visitor.visitSingularStringField(value: self.errorMessage, fieldNumber: 2)\n    }\n    if !self.url.isEmpty {\n      try visitor.visitSingularStringField(value: self.url, fieldNumber: 3)\n    }\n    if !self.name.isEmpty {\n      try visitor.visitSingularStringField(value: self.name, fieldNumber: 4)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiArtifactManagement_GetArtifactResponse, rhs: ValdiArtifactManagement_GetArtifactResponse) -> Bool {\n    if lhs.success != rhs.success {return false}\n    if lhs.errorMessage != rhs.errorMessage {return false}\n    if lhs.url != rhs.url {return false}\n    if lhs.name != rhs.name {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiArtifactManagement_ManagedArtifact: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".ManagedArtifact\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"key\"),\n    2: .same(proto: \"url\"),\n    3: .same(proto: \"name\"),\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.key) }()\n      case 2: try { try decoder.decodeSingularStringField(value: &self.url) }()\n      case 3: try { try decoder.decodeSingularStringField(value: &self.name) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.key.isEmpty {\n      try visitor.visitSingularStringField(value: self.key, fieldNumber: 1)\n    }\n    if !self.url.isEmpty {\n      try visitor.visitSingularStringField(value: self.url, fieldNumber: 2)\n    }\n    if !self.name.isEmpty {\n      try visitor.visitSingularStringField(value: self.name, fieldNumber: 3)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiArtifactManagement_ManagedArtifact, rhs: ValdiArtifactManagement_ManagedArtifact) -> Bool {\n    if lhs.key != rhs.key {return false}\n    if lhs.url != rhs.url {return false}\n    if lhs.name != rhs.name {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Models/valdi-daemon-registry.pb.swift",
    "content": "// DO NOT EDIT.\n// swift-format-ignore-file\n//\n// Generated by the Swift generator plugin for the protocol buffer compiler.\n// Source: valdi-daemon-registry.proto\n//\n// For information on using the generated types, please see the documentation:\n//   https://github.com/apple/swift-protobuf/\n\nimport Foundation\nimport SwiftProtobuf\n\n// If the compiler emits an error on this type, it is because this file\n// was generated by a version of the `protoc` Swift plug-in that is\n// incompatible with the version of SwiftProtobuf to which you are linking.\n// Please ensure that you are building against the same version of the API\n// that was used to generate this file.\nprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {\n  struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}\n  typealias Version = _2\n}\n\n/// Describes a Valdi daemon service and the devices it's targeting\nstruct ValdiDaemonRegistry_DaemonService {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var key: String = String()\n\n  var serviceAddresses: [String] = []\n\n  var servicePort: Int32 = 0\n\n  var processID: String = String()\n\n  var deviceIds: [String] = []\n\n  var usernames: [String] = []\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\nstruct ValdiDaemonRegistry_ListServicesRequest {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var filters: ValdiDaemonRegistry_ListServicesFilters {\n    get {return _filters ?? ValdiDaemonRegistry_ListServicesFilters()}\n    set {_filters = newValue}\n  }\n  /// Returns true if `filters` has been explicitly set.\n  var hasFilters: Bool {return self._filters != nil}\n  /// Clears the value of `filters`. Subsequent reads from it will return its default value.\n  mutating func clearFilters() {self._filters = nil}\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n\n  fileprivate var _filters: ValdiDaemonRegistry_ListServicesFilters?\n}\n\nstruct ValdiDaemonRegistry_ListServicesFilters {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var deviceID: String = String()\n\n  var username: String = String()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\nstruct ValdiDaemonRegistry_ListServicesResponse {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var services: [ValdiDaemonRegistry_DaemonService] = []\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\nstruct ValdiDaemonRegistry_RegisterServiceRequest {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var service: ValdiDaemonRegistry_DaemonService {\n    get {return _service ?? ValdiDaemonRegistry_DaemonService()}\n    set {_service = newValue}\n  }\n  /// Returns true if `service` has been explicitly set.\n  var hasService: Bool {return self._service != nil}\n  /// Clears the value of `service`. Subsequent reads from it will return its default value.\n  mutating func clearService() {self._service = nil}\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n\n  init() {}\n\n  fileprivate var _service: ValdiDaemonRegistry_DaemonService?\n}\n\nstruct ValdiDaemonRegistry_RegisterServiceResponse {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var success: Bool = false\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\nstruct ValdiDaemonRegistry_UnregisterServiceRequest {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var serviceKey: String = String()\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\nstruct ValdiDaemonRegistry_UnregisterServiceResponse {\n  // SwiftProtobuf.Message conformance is added in an extension below. See the\n  // `Message` and `Message+*Additions` files in the SwiftProtobuf library for\n  // methods supported on all messages.\n\n  var success: Bool = false\n\n  var unknownFields = SwiftProtobuf.UnknownStorage()\n}\n\n#if swift(>=5.5) && canImport(_Concurrency)\nextension ValdiDaemonRegistry_DaemonService: @unchecked Sendable {}\nextension ValdiDaemonRegistry_ListServicesRequest: @unchecked Sendable {}\nextension ValdiDaemonRegistry_ListServicesFilters: @unchecked Sendable {}\nextension ValdiDaemonRegistry_ListServicesResponse: @unchecked Sendable {}\nextension ValdiDaemonRegistry_RegisterServiceRequest: @unchecked Sendable {}\nextension ValdiDaemonRegistry_RegisterServiceResponse: @unchecked Sendable {}\nextension ValdiDaemonRegistry_UnregisterServiceRequest: @unchecked Sendable {}\nextension ValdiDaemonRegistry_UnregisterServiceResponse: @unchecked Sendable {}\n#endif  // swift(>=5.5) && canImport(_Concurrency)\n\n// MARK: - Code below here is support for the SwiftProtobuf runtime.\n\nprivate let _protobuf_package = \"ValdiDaemonRegistry\"\n\nextension ValdiDaemonRegistry_DaemonService: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".DaemonService\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"key\"),\n    2: .standard(proto: \"service_addresses\"),\n    3: .standard(proto: \"service_port\"),\n    4: .standard(proto: \"process_id\"),\n    5: .standard(proto: \"device_ids\"),\n    6: .same(proto: \"usernames\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.key) }()\n      case 2: try { try decoder.decodeRepeatedStringField(value: &self.serviceAddresses) }()\n      case 3: try { try decoder.decodeSingularInt32Field(value: &self.servicePort) }()\n      case 4: try { try decoder.decodeSingularStringField(value: &self.processID) }()\n      case 5: try { try decoder.decodeRepeatedStringField(value: &self.deviceIds) }()\n      case 6: try { try decoder.decodeRepeatedStringField(value: &self.usernames) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.key.isEmpty {\n      try visitor.visitSingularStringField(value: self.key, fieldNumber: 1)\n    }\n    if !self.serviceAddresses.isEmpty {\n      try visitor.visitRepeatedStringField(value: self.serviceAddresses, fieldNumber: 2)\n    }\n    if self.servicePort != 0 {\n      try visitor.visitSingularInt32Field(value: self.servicePort, fieldNumber: 3)\n    }\n    if !self.processID.isEmpty {\n      try visitor.visitSingularStringField(value: self.processID, fieldNumber: 4)\n    }\n    if !self.deviceIds.isEmpty {\n      try visitor.visitRepeatedStringField(value: self.deviceIds, fieldNumber: 5)\n    }\n    if !self.usernames.isEmpty {\n      try visitor.visitRepeatedStringField(value: self.usernames, fieldNumber: 6)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiDaemonRegistry_DaemonService, rhs: ValdiDaemonRegistry_DaemonService) -> Bool {\n    if lhs.key != rhs.key {return false}\n    if lhs.serviceAddresses != rhs.serviceAddresses {return false}\n    if lhs.servicePort != rhs.servicePort {return false}\n    if lhs.processID != rhs.processID {return false}\n    if lhs.deviceIds != rhs.deviceIds {return false}\n    if lhs.usernames != rhs.usernames {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiDaemonRegistry_ListServicesRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".ListServicesRequest\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"filters\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularMessageField(value: &self._filters) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    try { if let v = self._filters {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 1)\n    } }()\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiDaemonRegistry_ListServicesRequest, rhs: ValdiDaemonRegistry_ListServicesRequest) -> Bool {\n    if lhs._filters != rhs._filters {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiDaemonRegistry_ListServicesFilters: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".ListServicesFilters\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .standard(proto: \"device_id\"),\n    2: .same(proto: \"username\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.deviceID) }()\n      case 2: try { try decoder.decodeSingularStringField(value: &self.username) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.deviceID.isEmpty {\n      try visitor.visitSingularStringField(value: self.deviceID, fieldNumber: 1)\n    }\n    if !self.username.isEmpty {\n      try visitor.visitSingularStringField(value: self.username, fieldNumber: 2)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiDaemonRegistry_ListServicesFilters, rhs: ValdiDaemonRegistry_ListServicesFilters) -> Bool {\n    if lhs.deviceID != rhs.deviceID {return false}\n    if lhs.username != rhs.username {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiDaemonRegistry_ListServicesResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".ListServicesResponse\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"services\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeRepeatedMessageField(value: &self.services) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.services.isEmpty {\n      try visitor.visitRepeatedMessageField(value: self.services, fieldNumber: 1)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiDaemonRegistry_ListServicesResponse, rhs: ValdiDaemonRegistry_ListServicesResponse) -> Bool {\n    if lhs.services != rhs.services {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiDaemonRegistry_RegisterServiceRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".RegisterServiceRequest\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"service\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularMessageField(value: &self._service) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    // The use of inline closures is to circumvent an issue where the compiler\n    // allocates stack space for every if/case branch local when no optimizations\n    // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and\n    // https://github.com/apple/swift-protobuf/issues/1182\n    try { if let v = self._service {\n      try visitor.visitSingularMessageField(value: v, fieldNumber: 1)\n    } }()\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiDaemonRegistry_RegisterServiceRequest, rhs: ValdiDaemonRegistry_RegisterServiceRequest) -> Bool {\n    if lhs._service != rhs._service {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiDaemonRegistry_RegisterServiceResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".RegisterServiceResponse\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"success\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularBoolField(value: &self.success) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if self.success != false {\n      try visitor.visitSingularBoolField(value: self.success, fieldNumber: 1)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiDaemonRegistry_RegisterServiceResponse, rhs: ValdiDaemonRegistry_RegisterServiceResponse) -> Bool {\n    if lhs.success != rhs.success {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiDaemonRegistry_UnregisterServiceRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".UnregisterServiceRequest\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .standard(proto: \"service_key\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularStringField(value: &self.serviceKey) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if !self.serviceKey.isEmpty {\n      try visitor.visitSingularStringField(value: self.serviceKey, fieldNumber: 1)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiDaemonRegistry_UnregisterServiceRequest, rhs: ValdiDaemonRegistry_UnregisterServiceRequest) -> Bool {\n    if lhs.serviceKey != rhs.serviceKey {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n\nextension ValdiDaemonRegistry_UnregisterServiceResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {\n  static let protoMessageName: String = _protobuf_package + \".UnregisterServiceResponse\"\n  static let _protobuf_nameMap: SwiftProtobuf._NameMap = [\n    1: .same(proto: \"success\")\n  ]\n\n  mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {\n    while let fieldNumber = try decoder.nextFieldNumber() {\n      // The use of inline closures is to circumvent an issue where the compiler\n      // allocates stack space for every case branch when no optimizations are\n      // enabled. https://github.com/apple/swift-protobuf/issues/1034\n      switch fieldNumber {\n      case 1: try { try decoder.decodeSingularBoolField(value: &self.success) }()\n      default: break\n      }\n    }\n  }\n\n  func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {\n    if self.success != false {\n      try visitor.visitSingularBoolField(value: self.success, fieldNumber: 1)\n    }\n    try unknownFields.traverse(visitor: &visitor)\n  }\n\n  static func ==(lhs: ValdiDaemonRegistry_UnregisterServiceResponse, rhs: ValdiDaemonRegistry_UnregisterServiceResponse) -> Bool {\n    if lhs.success != rhs.success {return false}\n    if lhs.unknownFields != rhs.unknownFields {return false}\n    return true\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/OutputDirectories.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 10/17/19.\n//\n\nimport Foundation\n\nstruct OutDirectories {\n    let baseURL: URL\n    let assetsURL: URL\n    /**\n     Directory that will hold the platform specific generated sources, like Objective-C, Swift or Kotlin\n     */\n    let srcURL: URL\n\n    /**\n     Directory that will hold the C or C++ generated sources\n     */\n    let nativeSrcURL: URL\n\n    let resourcesURL: URL // .bundle for iOS, res/ directory for Android\n    let metadataURL: URL? // where to place module metadata (e.g. DI information)\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Parser/Models/ValdiRawDocument.swift",
    "content": "//\n//  ValdiRawDocument.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/6/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ValdiRawDocument {\n\n    var content = \"\"\n\n    var scripts = [ValdiScript]()\n    var styles = [ValdiStyleSheet]()\n    var actions = [ValdiAction]()\n    var template: ValdiRawTemplate?\n    var viewModel: ValdiModel?\n    var componentContext: ValdiNodeClassMapping?\n    var additionalModels = [ValdiModel]()\n    var classMapping: ValdiClassMapping?\n}\n\nstruct ValdiStyleSheet {\n    var source: String?\n    var content: String?\n}\n\nstruct ValdiScript {\n    var source: String?\n    var content: String?\n    var lang: String?\n    var lineOffset: Int?\n}\n\nstruct ValdiRawNodeAttribute {\n    var name = \"\"\n    var value = \"\"\n    var valueIsExpr = false\n    var evaluateOnce = false\n    var isViewModelField = false\n}\n\nenum ValdiActionType {\n    case native\n    case javaScript\n}\n\nstruct ValdiAction: Equatable {\n    let name: String\n    let type: ValdiActionType\n}\n\nstruct ValdiRawNode {\n    enum Child {\n        case expression(String)\n        case node(ValdiRawNode)\n\n        var node: ValdiRawNode? {\n            guard case let .node(node) = self else {\n                return nil\n            }\n            return node\n        }\n    }\n\n    var nodeType = \"\"\n    var id = \"\"\n    var destSlotName: String?\n\n    var forEachExpr: ValdiRawNodeAttribute?\n    var ifExpr: ValdiRawNodeAttribute?\n    var elseIfExpr: ValdiRawNodeAttribute?\n    var elseExpr: ValdiRawNodeAttribute?\n    var unlessExpr: ValdiRawNodeAttribute?\n    var customAttributes = [ValdiRawNodeAttribute]()\n    var isLayout: Bool?\n\n    var children = [Child]()\n\n    var lineNumber = -1\n    var columnNumber = -1\n}\n\nstruct ValdiRawTemplate {\n    var rootNode: ValdiRawNode?\n    var jsComponentClass: String?\n}\n\nindirect enum ValdiModelPropertyType {\n    case string\n    case double\n    case bool\n    case long\n    case array(elementType: ValdiModelPropertyType)\n    case bytes\n    case map(keyType: ValdiModelPropertyType, valueType: ValdiModelPropertyType)\n    case any\n    case void\n    case function(parameters: [ValdiModelProperty], returnType: ValdiModelPropertyType, isSingleCall: Bool, shouldCallOnWorkerThread: Bool)\n    case object(ValdiNodeClassMapping)\n    case genericTypeParameter(name: String)\n    case genericObject(ValdiNodeClassMapping, typeArguments: [ValdiModelPropertyType])\n    case promise(typeArgument: ValdiModelPropertyType)\n    case `enum`(ValdiNodeClassMapping)\n    case nullable(ValdiModelPropertyType)\n\n    var isFunction: Bool {\n        switch self {\n        case .function:\n            return true\n        case .nullable(let innerType):\n            return innerType.isFunction\n        default:\n            return false\n        }\n    }\n\n    var isOptional: Bool {\n        switch self {\n        case .nullable:\n            return true\n        default:\n            return false\n        }\n    }\n\n    var isVoid: Bool {\n        switch self {\n        case .void:\n            return true\n        default:\n            return false\n        }\n    }\n\n    var unwrappingOptional: ValdiModelPropertyType {\n        switch self {\n        case .nullable(let innerType):\n            return innerType.unwrappingOptional\n        default:\n            return self\n        }\n    }\n\n    var includesGenericType: Bool {\n        switch self {\n        case .string, .double, .bool, .bytes, .map, .void, .object, .enum, .long, .any:\n            return false\n        case .array(let elementType):\n            return elementType.includesGenericType\n        case .function(let parameters, let returnType, _, _):\n            return parameters.contains(where: { $0.type.includesGenericType }) || returnType.includesGenericType\n        case .genericTypeParameter:\n            return true\n        case .genericObject:\n            return true\n        case .promise:\n            return true\n        case .nullable(let type):\n            return type.includesGenericType\n        }\n    }\n}\n\nstruct OmitConstructorParams: Encodable {\n    let ios: Bool?\n    let android: Bool?\n}\n\nstruct InjectableParams {\n    struct Compatibility: OptionSet {\n        let rawValue: UInt\n        \n        static let ios: Compatibility = Compatibility(rawValue: 1 << 0)\n        static let android: Compatibility = Compatibility(rawValue: 1 << 1)\n        static let all: Compatibility = [.ios, .android]\n    }\n    \n    static let empty: InjectableParams = InjectableParams(compatibility: [])\n    \n    let compatibility: Compatibility\n}\n\nstruct ValdiModelProperty {\n    var name: String\n    var type: ValdiModelPropertyType\n    let comments: String?\n    let omitConstructor: OmitConstructorParams?\n    let injectableParams: InjectableParams\n}\n\nstruct ValdiTypeParameter {\n    var name: String\n}\n\nstruct ValdiModel {\n    var tsType: String = \"\"\n    var iosType: IOSType?\n    var androidClassName: String?\n    var cppType: CPPType?\n    var typeParameters: [ValdiTypeParameter]?\n    var exportAsInterface = false\n    var legacyConstructors = false\n    var usePublicFields = false\n    var comments: String?\n    var properties = [ValdiModelProperty]()\n}\n\nstruct ExportedModule {\n    var model: ValdiModel\n    var modulePath: String\n}\n\nprotocol EnumCaseValueType { }\nextension String: EnumCaseValueType { }\nextension Int: EnumCaseValueType { }\n\nstruct EnumCase<T: EnumCaseValueType> {\n    let name: String\n    let value: T\n    let comments: String?\n}\n\nextension EnumCase: Encodable where T: Encodable {\n\n}\n\nenum NativeTypeKind: Codable {\n    case interface\n    case `class`\n    case `enum`\n    case stringEnum\n}\n\nenum IOSLanguage: String, Codable {\n    case swift = \"swift\"\n    case objc = \"objc\"\n    case both = \"both\"\n\n    static func split(_ input: String) -> [String] {\n        let components = input.components(separatedBy: \",\")\n        let trimmed = components.map { $0.trimmingCharacters(in: .whitespaces) }\n        return trimmed.sorted()\n    }\n    \n    static func parse(input: String) throws -> IOSLanguage {\n        switch input {\n        case \"objc\": return objc\n        case \"swift\": return swift\n        case let components where split(components) == [\"objc\", \"swift\"]:\n            return both\n        default:\n            throw CompilerError(\"Unsupported ios language '\\(input)'\")\n        }\n    }\n}\n\nstruct IOSType: Codable {\n    static let enumTypeGroupingPriority = 0\n    static let enumStringTypeGroupingPriority = 1\n    static let classTypeGroupingPriority = 2\n    static let interfaceTypeGroupingPriority = 3\n    static let functionTypeGroupingPriority = 4\n    static let idsTypeGroupingPriority = 5\n    static let viewTypeGroupingPriority = 6\n\n    let name: String\n    let swiftName: String\n    var importPrefix: String?\n    let importSuffix: String\n    var isImportPrefixOverridden = false\n    var fromSingleFileCodegen = false\n    var kind: NativeTypeKind\n    var iosLanguage: IOSLanguage\n\n    init(name: String, swiftName: String? = nil, bundleInfo: CompilationItem.BundleInfo?, kind: NativeTypeKind, iosLanguage: IOSLanguage) {\n        self.name = name\n        self.swiftName = swiftName ?? name\n        if let bundleInfo {\n            self.fromSingleFileCodegen = bundleInfo.singleFileCodegen\n            self.importSuffix = bundleInfo.singleFileCodegen ? bundleInfo.iosModuleName : name\n        } else {\n            self.importSuffix = name\n        }\n        self.kind = kind\n        self.iosLanguage = iosLanguage\n    }\n\n    var importHeaderStatement: String {\n        return self.importHeaderStatement(kind: .apiOnly)\n    }\n\n    enum HeaderImportKind {\n        case apiOnly\n        case withUtilities\n\n        static let apiOnlyModuleNameSuffix = \"Types\"\n    }\n\n    func importHeaderFilename(kind: HeaderImportKind) -> String {\n        switch kind {\n        case .apiOnly:\n            if fromSingleFileCodegen {\n                return \"\\(importSuffix)\\(HeaderImportKind.apiOnlyModuleNameSuffix).h\"\n            } else {\n                return \"\\(importSuffix).h\"\n            }\n        case .withUtilities:\n            return \"\\(importSuffix).h\"\n        }\n    }\n\n    func importHeaderStatement(kind: HeaderImportKind) -> String {\n        let filename = importHeaderFilename(kind: kind)\n        if let importPrefix = importPrefix {\n            if isImportPrefixOverridden {\n                if fromSingleFileCodegen {\n                    // If the import prefix is explicitly overridden (eg. with iosImportPrefix)\n                    // AND the type comes from a single_file_codegen module, then the final \n                    // output type should map to an external native header.\n                    // For example, if iosImportPrefix is \"valdi_core\" and the type is \"INavigator\",\n                    // then output should be <valdi_core/INavigator.h>, not <valdi_core/SCCNavigationTypes.h>\n                    // Return the header with the type's name, instead of using the consolidated module header.\n                    return \"<\\(importPrefix)/\\(name).h>\"\n                }\n                return \"<\\(importPrefix)/\\(filename)>\"\n            } else {\n                let suffix: String\n                switch kind {\n                case .apiOnly: suffix = HeaderImportKind.apiOnlyModuleNameSuffix\n                case .withUtilities: suffix = \"\"\n                }\n\n                return \"<\\(importPrefix)\\(suffix)/\\(filename)>\"\n            }\n        }\n        return \"\\\"\\(filename)\\\"\"\n    }\n\n    var typeDeclaration: String {\n        switch kind {\n        case .class:\n            return \"\\(name) *\"\n        case .interface:\n            return \"id<\\(name)>\"\n        case .enum:\n            return name\n        case .stringEnum:\n            return name\n        }\n    }\n\n    mutating func applyImportPrefix(iosImportPrefix: String, isOverridden: Bool) {\n        self.importPrefix = String.sanitizePathComponents(iosImportPrefix)\n\n        self.isImportPrefixOverridden = isOverridden\n    }\n}\n\nstruct CPPNamespace: Codable, Hashable, Comparable {\n    static let rootNamespace = CPPNamespace(components: [])\n    \n    let components: [String]\n\n    func resolve(other: CPPNamespace) -> CPPNamespace {\n        var outComponents = components\n\n        for component in other.components {\n            if outComponents.first == component {\n                outComponents.removeFirst()\n            } else {\n                break\n            }\n        }\n\n        return CPPNamespace(components: outComponents)\n    }\n\n    var description: String {\n        return components.joined(separator: \"::\")\n    }\n\n    func appending(component: String) -> CPPNamespace {\n        var components = self.components\n        components.append(component)\n        return CPPNamespace(components: components)\n    }\n\n    static func < (lhs: CPPNamespace, rhs: CPPNamespace) -> Bool {\n        return lhs.description < rhs.description\n    }\n}\n\nstruct CPPTypeDeclaration: Codable, Hashable {\n    enum SymbolType: Codable, Hashable, Comparable {\n        case `class`\n        case `enum`\n\n        var declarationString: String {\n            switch self {\n            case .class:\n                return \"class\"\n            case .enum:\n                return \"enum class\"\n            }\n        }\n    }\n\n    let namespace: CPPNamespace\n    let name: String\n    let symbolType: SymbolType\n\n    init(namespace: CPPNamespace,\n         name: String,\n         symbolType: SymbolType) {\n        self.namespace = namespace\n        self.name = name\n        self.symbolType = symbolType\n    }\n\n    init(namespace: String,\n         name: String,\n         symbolType: SymbolType) {\n        self.namespace = CPPNamespace(components: namespace.components(separatedBy: \"::\"))\n        self.name = name\n        self.symbolType = symbolType\n    }\n\n    init(name: String,\n         symbolType: SymbolType) {\n        let components = name.components(separatedBy: \"::\")\n        if components.count == 1 {\n            self.namespace = CPPNamespace(components: [])\n            self.name = name\n        } else {\n            self.namespace = CPPNamespace(components: components[0..<(components.count - 1)].map { String($0) })\n            self.name = String(components.last!)\n        }\n        self.symbolType = symbolType\n    }\n\n    var fullTypeName: String {\n        return resolveTypeName(inNamespace: CPPNamespace(components: []))\n    }\n\n    func resolveTypeName(inNamespace: CPPNamespace) -> String {\n        let resolved = namespace.resolve(other: inNamespace)\n\n        if resolved.components.isEmpty {\n            return name\n        } else {\n            return \"\\(resolved.components.joined(separator: \"::\"))::\\(name)\"\n        }\n    }\n}\n\nstruct CPPTypeReference: Hashable {\n    let declaration: CPPTypeDeclaration\n    let typeArguments: [String]?\n\n    var fullTypeName: String {\n        if let typeArguments {\n            return \"\\(declaration.fullTypeName)<\\(typeArguments.joined(separator: \", \"))>\"\n        } else {\n            return declaration.fullTypeName\n        }\n    }\n\n    func resolveTypeName(inNamespace: CPPNamespace) -> String {\n        if let typeArguments {\n            return \"\\(declaration.resolveTypeName(inNamespace: inNamespace))<\\(typeArguments.joined(separator: \",\"))>\"\n        } else {\n            return declaration.resolveTypeName(inNamespace: inNamespace)\n        }\n    }\n}\n\nstruct CPPType: Codable {\n    let declaration: CPPTypeDeclaration\n    let includePath: String\n    let includePrefix: String?\n\n    var includeDir: String? {\n        guard let index = self.includePath.lastIndex(of: \"/\") else {\n            return \"\"\n        }\n\n        return String(self.includePath[self.includePath.startIndex..<index])\n    }\n\n    init(declaration: CPPTypeDeclaration,\n         module: CompilationItem.BundleInfo,\n         includePrefix: String?) {\n        self.declaration = declaration\n        self.includePath = CPPType.resolveIncludePath(moduleName: module.name,\n                                                      prefix: includePrefix,\n                                                      typeName: declaration.name,\n                                                      singleFileCodegen: module.singleFileCodegen)\n        self.includePrefix = includePrefix\n    }\n\n    private static func resolveIncludePath(moduleName: String,\n                                           prefix: String?,\n                                           typeName: String,\n                                           singleFileCodegen: Bool) -> String {\n        let resolvedIncludePrefix: String\n        if let prefix = prefix {\n            resolvedIncludePrefix = \"\\(prefix)\\(moduleName)\"\n        } else {\n            resolvedIncludePrefix = moduleName\n        }\n\n        if singleFileCodegen {\n            return \"\\(resolvedIncludePrefix)/\\(moduleName).hpp\"\n        } else {\n            return \"\\(resolvedIncludePrefix)/\\(typeName).hpp\"\n        }\n    }\n}\n\n// TODO: rename to ValdiNodeTypeMapping?\nstruct ValdiNodeClassMapping {\n    let tsType: String\n    var iosType: IOSType?\n    // TODO: use JVMClass/JVMType, for consistency\n    var androidClassName: String?\n    var cppType: CPPType?\n    var kind: NativeTypeKind\n\n    var isGenerated = false\n    var marshallAsUntyped = false\n    var converter: String? = nil\n\n    init(tsType: String,\n         iosType: IOSType?,\n         androidClassName: String?,\n         cppType: CPPType?,\n         kind: NativeTypeKind) {\n        self.tsType = tsType\n        self.iosType = iosType\n        self.androidClassName = androidClassName\n        self.cppType = cppType\n        self.kind = kind\n    }\n}\n\n// TODO: rename to ValdiTypeMapping?\nstruct ValdiClassMapping {\n    var nodeMappingByClass = [String: ValdiNodeClassMapping]()\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Parser/ValdiDocumentParser.swift",
    "content": "//\n//  ValdiDocumentParser.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/5/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport SwiftSoup\n\nprivate extension Substring {\n\n    var lineCount: Int {\n        let newlines = CharacterSet.newlines\n        var count = 0\n        var range = startIndex..<endIndex\n        while range.lowerBound != endIndex {\n            if let foundRange = rangeOfCharacter(from: newlines, options: [], range: range) {\n                count += 1\n                range = foundRange.upperBound..<endIndex\n            } else {\n                break\n            }\n        }\n\n        return count\n    }\n\n}\n\nprivate extension Substring {\n\n    var escapingQuotes: String {\n        return replacingOccurrences(of: \"'\", with: \"\\\\'\").replacingOccurrences(of: \"\\\"\", with: \"\\\\\\\"\")\n    }\n\n}\n\nprivate extension String {\n\n    var extractingExpression: String? {\n        if isEmpty {\n            return nil\n        }\n\n        var currentIndex = startIndex\n        let endIndex = self.endIndex\n\n        var expressions = [String]()\n\n        while currentIndex != endIndex {\n            if let from = range(of: \"{{\", options: [], range: currentIndex..<endIndex, locale: nil),\n                let to = range(of: \"}}\", options: [], range: from.upperBound..<endIndex, locale: nil) {\n\n                if from.lowerBound > currentIndex {\n                    expressions.append(\"'\\(self[currentIndex..<from.lowerBound].escapingQuotes)'\")\n                }\n                var extractedExpr = String(self[from.upperBound..<to.lowerBound]).trimmed\n                if extractedExpr.last == \";\" {\n                    // Backward compat for attributes that had ; at the end\n                    extractedExpr = extractedExpr.removingLastCharacter\n                }\n                expressions.append(extractedExpr)\n\n                currentIndex = to.upperBound\n            } else {\n                if currentIndex == startIndex {\n                    // We didn't find any expressions\n                    return nil\n                }\n\n                expressions.append(\"'\\(self[currentIndex..<endIndex].escapingQuotes)'\")\n\n                currentIndex = endIndex\n            }\n        }\n\n        if expressions.count > 1 {\n            return expressions.map { \"( \\($0) )\" }.joined(separator: \" + \")\n        } else {\n            return expressions[0]\n        }\n    }\n\n}\n\nclass ValdiDocumentParser {\n    private static let xmlAttributeValuePattern = \"([a-zA-Z0-9-_:]+)=\\\"((?:.|\\\\s)*?)\\\"\"\n\n    // Workaround to fix a crash in SwiftSoup. This library uses a static mutable variable\n    // that is not behind a lock and gets lazily populated when the escape mode fields are created.\n    // This ensures that the initialization of those fields is done ahead of time, inside a lock.\n    private static let ensureSwiftSoupIsInitialized: Bool = {\n        _ = [\n            SwiftSoup.Entities.EscapeMode.xhtml,\n            SwiftSoup.Entities.EscapeMode.base,\n            SwiftSoup.Entities.EscapeMode.extended\n        ]\n\n        return true\n    }()\n\n    static let openTagRegex = try! NSRegularExpression(pattern: \"<\\\\s*([a-zA-Z0-9-_]+)[^>]*>\")\n    static let viewModelRegex = try! NSRegularExpression(pattern: \"\\\\s:\\(ValdiDocumentParser.xmlAttributeValuePattern)\")\n    static let onViewModelRegex = try! NSRegularExpression(pattern: \"\\\\s:@\\(ValdiDocumentParser.xmlAttributeValuePattern)\")\n    static let viewModelOnceRegex = try! NSRegularExpression(pattern: \"\\\\s:once:\\(ValdiDocumentParser.xmlAttributeValuePattern)\")\n    static let onRegex = try! NSRegularExpression(pattern: \"\\\\s@\\(ValdiDocumentParser.xmlAttributeValuePattern)\")\n\n    var document = ValdiRawDocument()\n\n    private let logger: ILogger\n    private let content: String\n    private let parser: SwiftSoup.Parser\n    private let iosImportPrefix: String\n\n    private init(logger: ILogger, content: String, iosImportPrefix: String) {\n        self.logger = logger\n        self.content = content\n        self.document.content = content\n        self.iosImportPrefix = iosImportPrefix\n\n        _ = ValdiDocumentParser.ensureSwiftSoupIsInitialized\n        let parser = SwiftSoup.Parser.xmlParser()\n        parser.settings(.preserveCase)\n        parser.setTrackErrors(16)\n        self.parser = parser\n    }\n\n    func parse() throws {\n        var deferredProcesses = [() throws -> Void]()\n\n        // Extract tags from content\n        var searchIndex = self.content.startIndex\n        while searchIndex < self.content.endIndex {\n            var matches = ValdiDocumentParser.openTagRegex.matches(in: self.content, options: [], range: NSRange(searchIndex..., in: self.content))\n            guard !matches.isEmpty else {\n                break\n            }\n\n            guard let startTagRange = Range(matches[0].range, in: self.content) else {\n                break\n            }\n            let sectionStart = startTagRange.lowerBound\n            let contentStart = startTagRange.upperBound\n            let startTag = self.content[startTagRange]\n            let lineOffset = self.content[..<sectionStart].lineCount\n\n            let tagName = self.content[Range(matches[0].range(at: 1), in: self.content)!]\n\n            let closeTagPattern = \"</\\\\s*\\(tagName)\\\\s*\\\\s*>\"\n            let closeTagRegex = try NSRegularExpression(pattern: closeTagPattern)\n            matches = closeTagRegex.matches(in: self.content, options: [], range: NSRange(contentStart..., in: self.content))\n            if matches.count == 0 {\n                throw CompilerError(type: \"Parse error\",\n                                    message: \"Missing close tag for \\(tagName).\",\n                                    atZeroIndexedLine: lineOffset,\n                                    column: nil,\n                                    inDocument: self.content)\n            }\n\n            guard let endTagRange = Range(matches[0].range, in: self.content) else {\n                break\n            }\n            let contentEnd = endTagRange.lowerBound\n            let sectionEnd = endTagRange.upperBound\n            let endTag = self.content[endTagRange]\n\n            let outerContent = self.content[sectionStart..<sectionEnd]\n            let innerContent = self.content[contentStart..<contentEnd]\n\n            switch tagName {\n            case \"actions\":\n                try process(actionsElement: parseSection(content: outerContent, tagName: tagName, lineOffset: lineOffset))\n            case \"class-mapping\":\n                try process(classMappingElement: parseSection(content: outerContent, tagName: tagName, lineOffset: lineOffset))\n            case \"script\":\n                try process(scriptElementStartTag: startTag, content: innerContent, scriptElementEndTag: endTag, lineOffset: lineOffset)\n            case \"style\":\n                // Sass styles can use special characters such as \"&\" and \">\" that need to be escaped\n                let xmlEscapedOuterContent = String(outerContent[sectionStart..<contentStart]) +\n                    String(outerContent[contentStart..<contentEnd]).xmlEscaped +\n                    String(outerContent[contentEnd..<sectionEnd])\n                let styleElement = try parseSection(content: Substring(xmlEscapedOuterContent), tagName: tagName, lineOffset: lineOffset)\n                try process(styleElement: styleElement)\n            case \"template\":\n                deferredProcesses.append {\n                    let lang = self.document.scripts.compactMap { $0.lang }.first\n                    var expandedContent = self.expandOnAttributes(content: String(innerContent), lang: lang)\n                    expandedContent = self.expandViewModelAttributes(content: expandedContent)\n\n                    try self.process(templateElementStartTag: startTag, content: Substring(expandedContent), templateElementEndTag: endTag, lineOffset: lineOffset)\n                }\n            default:\n                throw CompilerError(type: \"Parse error\",\n                                    message: \"Unsupported valdi section '\\(tagName)'. Supported sections are style, template, script, view-model, class-mapping, and actions.\",\n                                    atZeroIndexedLine: lineOffset,\n                                    column: nil,\n                                    inDocument: self.content)\n            }\n            searchIndex = sectionEnd\n        }\n\n        try deferredProcesses.forEach { try $0() }\n    }\n\n    private func parseSection(content: Substring, tagName: Substring, lineOffset: Int) throws -> SwiftSoup.Element {\n        do {\n            let xmlDoc = try self.parser.parseInput(String(content), \"\")\n            guard xmlDoc.children().count == 1 else {\n                throw CompilerError(\"There should be exactly one root element in section '\\(tagName)'\")\n            }\n            let element = xmlDoc.child(0)\n            return element\n        } catch {\n            throw CompilerError(type: \"XML parse error for section '\\(tagName)'\",\n            message: error.legibleLocalizedDescription,\n            atZeroIndexedLine: 0 + lineOffset, // FIXME: error.line - 1 + lineOffset,\n            column: nil,\n            inDocument: self.content)\n        }\n    }\n\n    private func process(styleElement: SwiftSoup.Element) throws {\n        if styleElement.children().count > 0 {\n            throw CompilerError(\"Style section cannot have children\")\n        }\n\n        var style = ValdiStyleSheet()\n\n        let allAttributes = styleElement.getAttributes()?.asList() ?? []\n        for attribute in allAttributes {\n            switch attribute.getKey() {\n            case \"src\":\n                style.source = attribute.getValue()\n            case \"lang\":\n                // Ignore\n                continue\n            default:\n                throw CompilerError(\"Unsupported attribute '\\(attribute.getKey())' in style. Only 'src' is supported.\")\n            }\n        }\n\n        style.content = styleElement.textNodes().first?.getWholeText().trimmed ?? \"\"\n        document.styles.append(style)\n    }\n\n    private func xmlEscape(s: Substring) -> String {\n        return String(s).xmlEscaped\n    }\n\n    private func process(scriptElementStartTag: Substring, content: Substring, scriptElementEndTag: Substring, lineOffset: Int) throws {\n        // Escape the contents first\n        let escapedContents = \"\\(scriptElementStartTag)\\(xmlEscape(s: content))\\(scriptElementEndTag)\"\n\n        let parsedScriptSection = try self.parser.parseInput(escapedContents, \"\")\n        guard parsedScriptSection.children().count == 1 else {\n            throw CompilerError(\"The 'script' section should have exactly one element\")\n        }\n        let scriptElement = parsedScriptSection.child(0)\n\n        var script = ValdiScript()\n\n        let allAttributes = scriptElement.getAttributes()?.asList() ?? []\n        for attribute in allAttributes {\n            switch attribute.getKey() {\n            case \"src\":\n                script.source = attribute.getValue().trimmed\n            case \"lang\":\n                script.lang = attribute.getValue().trimmed\n            default:\n                throw CompilerError(\"Unsupported attribute '\\(attribute.getKey())' in script. Only 'src' is supported.\")\n            }\n        }\n\n        let scriptContent = scriptElement.textNodes().first?.getWholeText().trimmed ?? \"\"\n\n        if !scriptContent.isEmpty {\n            script.content = scriptContent\n        }\n        script.lineOffset = lineOffset\n        document.scripts.append(script)\n    }\n\n    private func expandOnAttributes(content: String, lang: String?) -> String {\n        let replacement: String\n\n        if lang == \"kt\" {\n            replacement = \"{ params: dynamic -> this.$2(params) }\"\n        } else {\n            replacement = \"this.$2.bind(this)\"\n        }\n\n        // TODO: should be able to avoid requiring the namespace/prefix with SwiftSoup\n        let result = ValdiDocumentParser.onViewModelRegex.stringByReplacingMatches(in: content, options: [], range: content.nsrange, withTemplate: \" view-model-once:on-$1=\\\"{{ \\(replacement) }}\\\"\")\n\n        return ValdiDocumentParser.onRegex.stringByReplacingMatches(in: result, options: [], range: result.nsrange, withTemplate: \" once:on-$1=\\\"{{ \\(replacement) }}\\\"\")\n    }\n\n    // TODO: should be able to avoid requiring the namespace/prefix with SwiftSoup\n    private func expandViewModelAttributes(content: String) -> String {\n        let result = ValdiDocumentParser.viewModelOnceRegex.stringByReplacingMatches(in: content, options: [], range: content.nsrange, withTemplate: \" view-model-once:$1=\\\"{{ $2 }}\\\"\")\n\n        return ValdiDocumentParser.viewModelRegex.stringByReplacingMatches(in: result, options: [], range: result.nsrange, withTemplate: \" view-model:$1=\\\"{{ $2 }}\\\"\")\n    }\n\n    private func process(templateElementStartTag: Substring, content: Substring, templateElementEndTag: Substring, lineOffset: Int) throws {\n        // Escape the contents of the mustached template sections first\n        var escaped = \"\"\n        var startIndex = content.startIndex\n        while startIndex < content.endIndex {\n            guard let start = content.range(of: \"{{\", range: startIndex..<content.endIndex) else {\n                escaped += content[startIndex...]\n                break\n            }\n\n            guard let end = content.range(of: \"}}\", range: start.upperBound..<content.endIndex) else {\n                throw CompilerError(type: \"XML parse error for section 'template'\",\n                    message: \"Unmatched template {{\",\n                    atZeroIndexedLine: content[..<start.lowerBound].lineCount + lineOffset,\n                    column: nil,\n                    inDocument: self.content)\n            }\n\n            let templateEscaped = xmlEscape(s: content[start.upperBound..<end.lowerBound])\n            escaped += \"\\(content[startIndex..<start.lowerBound]){{ \\(templateEscaped) }}\"\n\n            startIndex = end.upperBound\n        }\n\n        let adjustedXML = \"\\(templateElementStartTag)\\(escaped)\\(templateElementEndTag)\"\n        let parsedDoc = try self.parser.parseInput(adjustedXML, \"\")\n        guard parsedDoc.children().count == 1 else {\n            throw CompilerError(\"The 'template' section should have exactly one root element\")\n        }\n        let rootElement = parsedDoc.child(0)\n\n        let parserDelegate = TemplateParserDelegate()\n\n        func visit(_ element: SwiftSoup.Element) throws {\n            let tagName = element.tagName()\n            let attributes = element.getAttributes()?.associate { ($0.getKey(), $0.getValue() ) } ?? [:]\n            parserDelegate.parser(self.parser, didStartElement: tagName, attributes: attributes)\n            if parserDelegate.error != nil {\n                return\n            }\n\n            for node in element.getChildNodes() {\n                if let textNode = node as? TextNode {\n                    if let text = textNode.getWholeText().trimmed.nonEmpty {\n                        parserDelegate.parser(parser, didEncounterTextNode: text)\n                    }\n                } else if let elementNode = node as? Element {\n                    try visit(elementNode)\n                    if parserDelegate.error != nil {\n                        return\n                    }\n                } else if node is Comment {\n                    // we don't currently do anything for comments\n                } else {\n                    throw CompilerError(\"Unknown node type: \\(node)\")\n                }\n            }\n\n            parserDelegate.parser(self.parser, didEndElement: tagName)\n            if parserDelegate.error != nil {\n                return\n            }\n        }\n\n        try visit(rootElement)\n\n        if let parserError = parserDelegate.error {\n            // FIXME: line/col\n            let parserErrorMessage: String? = nil\n            throw CompilerError(type: \"XML parse error for section 'template'\",\n                                message: parserErrorMessage ?? parserError.legibleLocalizedDescription,\n                                atZeroIndexedLine: lineOffset, // (parserErrorLineNumber ?? parser.lineNumber) - 1 + lineOffset,\n                                column: nil, // parserErrorColumnNumber ?? parser.columnNumber,\n                                inDocument: self.content)\n        }\n\n        var template = ValdiRawTemplate()\n\n        guard let templateRoot = parserDelegate.finish() else {\n            throw CompilerError(type: \"XML parse error for section 'template'\",\n                                message: \"No template root element\",\n                atZeroIndexedLine: lineOffset - 1,\n                column: nil,\n                inDocument: self.content)\n        }\n\n        for attr in templateRoot.customAttributes {\n            switch attr.name {\n            case \"jsViewClass\":\n                logger.warn(\"js-view-class is deprecated, use js-component-class instead\")\n                template.jsComponentClass = attr.value\n            case \"jsComponentClass\":\n                template.jsComponentClass = attr.value\n            default:\n                if attr.name.hasPrefix(\"xmlns:\") {\n                    continue\n                }\n                throw CompilerError(type: \"XML parse error for section 'template'\",\n                                    message: \"Unrecognized attribute '\\(attr.name)' in 'template'\",\n                                    atZeroIndexedLine: lineOffset,\n                                    column: nil,\n                                    inDocument: self.content)\n            }\n        }\n\n        guard !templateRoot.children.isEmpty else {\n            throw CompilerError(type: \"XML parse error for section 'template'\",\n                                message: \"Template is empty\",\n                                atZeroIndexedLine: lineOffset,\n                                column: nil,\n                                inDocument: self.content)\n        }\n\n        template.rootNode = templateRoot.children.first?.node\n\n        document.template = template\n    }\n\n    private func process(actionsElement: SwiftSoup.Element) throws {\n        for actionElement in actionsElement.children() {\n            let type: ValdiActionType\n\n            switch actionElement.tagName().lowercased() {\n            case \"native\":\n                type = .native\n            case \"js\", \"javascript\":\n                type = .javaScript\n            default:\n                throw CompilerError(\"Unrecognized action type '\\(actionElement.tagName())'. Only 'native' and 'javascript' are supported\")\n            }\n\n            let attributes = actionElement.getAttributes()?.asList() ?? []\n            for attribute in attributes {\n                let attributeName = attribute.getKey().camelCased\n                switch attributeName {\n                case \"name\":\n                    document.actions.append(ValdiAction(name: attribute.getValue().trimmed, type: type))\n                default:\n                    throw CompilerError(\"Unrecognized property '\\(attribute.getKey())' in actions section. Only 'name' is supported.\")\n                }\n            }\n        }\n    }\n\n    private func process(classMappingElement: SwiftSoup.Element) throws {\n        let classMapping = try ValdiDocumentParser.parseClassMapping(classMappingElement: classMappingElement, iosImportPrefix: iosImportPrefix)\n        document.classMapping = classMapping\n    }\n\n    class func parseClassMapping(classMappingElement: SwiftSoup.Element, iosImportPrefix: String) throws -> ValdiClassMapping {\n        var classMapping = ValdiClassMapping()\n\n        for child in classMappingElement.children() {\n            var nodeMapping = ValdiNodeClassMapping(\n                tsType: \"\",\n                iosType: nil,\n                androidClassName: nil,\n                cppType: nil,\n                kind: .class)\n\n            var localIosImportPrefix: String?\n\n            let attributes = child.getAttributes()?.asList() ?? []\n            for attribute in attributes {\n                switch attribute.getKey() {\n                case \"android\":\n                    nodeMapping.androidClassName = attribute.getValue().trimmed\n                case \"ios\":\n                    nodeMapping.iosType = IOSType(name: attribute.getValue().trimmed, bundleInfo: nil, kind: .class, iosLanguage: .objc)\n                case \"iosImportPrefix\":\n                    localIosImportPrefix = attribute.getValue().trimmed\n                default:\n                    throw CompilerError(\"Unrecognized attribute '\\(attribute.getKey())' in class mapping\")\n                }\n            }\n            nodeMapping.iosType?.applyImportPrefix(iosImportPrefix: localIosImportPrefix ?? iosImportPrefix, isOverridden: false)\n\n            classMapping.nodeMappingByClass[child.tagName()] = nodeMapping\n        }\n\n        return classMapping\n    }\n\n    class func parse(logger: ILogger, content: String, iosImportPrefix: String) throws -> ValdiRawDocument {\n        let parser = ValdiDocumentParser(logger: logger, content: content, iosImportPrefix: iosImportPrefix)\n        try parser.parse()\n        return parser.document\n    }\n\n    class TemplateParserDelegate {\n        static let rootNodeType = \"__ROOT__\"\n\n        class ParseNode {\n            enum Child {\n                case expression(String)\n                case node(ParseNode)\n\n                var node: ParseNode? {\n                    guard case let .node(node) = self else {\n                        return nil\n                    }\n                    return node\n                }\n            }\n            var rawNode: ValdiRawNode\n            var children: [Child] = []\n\n            var childrenNodes: [ParseNode] {\n                return children.compactMap(\\.node)\n            }\n\n            init(rawNode: ValdiRawNode) {\n                self.rawNode = rawNode\n            }\n        }\n\n        private var stack: [ParseNode] = []\n        private var finished = false\n\n        var error: Error?\n\n        init() {\n            var rootRawNode = ValdiRawNode()\n            rootRawNode.nodeType = TemplateParserDelegate.rootNodeType\n\n            let root = ParseNode(rawNode: rootRawNode)\n            stack.append(root)\n        }\n\n        func finish() -> ValdiRawNode? {\n            guard !finished else {\n                fatalError(\"finish() called twice\")\n            }\n\n            guard error == nil else {\n                return nil\n            }\n\n            guard let root = stack.last else {\n                return nil\n            }\n\n            // Walk the parse tree to fill the raw nodes\n            fillRawNodeChildren(parseNode: root)\n\n            self.finished = true\n\n            return root.rawNode.children.first?.node\n        }\n\n        private static let viewModelNamespace = \"viewModel:\"\n        private static let viewModelOnceNamespace = \"viewModelOnce:\"\n        private static let evaluateOnceNamespace = \"once:\"\n\n        private func parsePrefix(name: inout String, prefix: String) -> Bool {\n            if name.hasPrefix(prefix) {\n                name = String(name[prefix.endIndex...])\n                return true\n            }\n            return false\n        }\n\n        private func makeNodeAttribute(attributeName: String, trimmedText: String) -> ValdiRawNodeAttribute {\n            var attr = ValdiRawNodeAttribute()\n            attr.name = attributeName\n            attr.value = trimmedText\n\n            if parsePrefix(name: &attr.name, prefix: TemplateParserDelegate.viewModelNamespace) {\n                attr.isViewModelField = true\n                attr.valueIsExpr = true\n            } else if parsePrefix(name: &attr.name, prefix: TemplateParserDelegate.viewModelOnceNamespace) {\n                attr.isViewModelField = true\n                attr.evaluateOnce = true\n            } else if parsePrefix(name: &attr.name, prefix: TemplateParserDelegate.evaluateOnceNamespace) {\n                attr.evaluateOnce = true\n            }\n\n            if let expression = attr.value.extractingExpression {\n                attr.value = expression\n                attr.valueIsExpr = true\n            }\n\n            return attr\n        }\n\n        private func fillRawNodeChildren(parseNode: ParseNode) {\n            for parseChild in parseNode.children {\n                let rawChild: ValdiRawNode.Child\n\n                switch parseChild {\n                case let .expression(expression):\n                    rawChild = .expression(expression)\n                case let .node(parseChildNode):\n                    fillRawNodeChildren(parseNode: parseChildNode)\n                    rawChild = .node(parseChildNode.rawNode)\n                }\n\n                parseNode.rawNode.children.append(rawChild)\n            }\n        }\n\n        private func error(parser: SwiftSoup.Parser, message: String) {\n            error = CompilerError(message)\n//            parser.abortParsing()\n        }\n\n        func parser(_ parser: SwiftSoup.Parser, didStartElement elementName: String, attributes attributeDict: [String: String] = [:]) {\n            guard error == nil else {\n                return\n            }\n\n            var node = ValdiRawNode()\n            // FIXME: line/col numbers\n//            node.lineNumber = parser.lineNumber - 1\n//            if attributeDict.isEmpty {\n//                node.columnNumber = max(parser.columnNumber - elementName.count, 0)\n//            } else {\n//                // TODO(simon): The columnNumber won't be correct if have attributes.\n//                // We need to have some kind of way to get the line and column of\n//                // when the element started as opposed to when the > has been found.\n//                node.columnNumber = parser.columnNumber\n//            }\n            node.nodeType = elementName\n\n            guard let parent = stack.last else {\n                error(parser: parser, message: \"Invalid parser state: no parent element\")\n                return\n            }\n\n            for (rawAttributeName, attributeText) in attributeDict {\n                let nodeAttribute = makeNodeAttribute(attributeName: rawAttributeName.camelCased, trimmedText: attributeText.trimmed)\n\n                switch nodeAttribute.name {\n                case \"forEach\":\n                    if !nodeAttribute.valueIsExpr {\n                        error(parser: parser, message: \"'for-each' must be an expression using {{ }}\")\n                        return\n                    }\n                    if nodeAttribute.evaluateOnce {\n                        // We can't do eval once on for-each because we need the emitted local variable\n                        // name\n                        error(parser: parser, message: \"'for-each' does not support `once` tag.\")\n                        return\n                    }\n\n                    node.forEachExpr = nodeAttribute\n                case \"id\":\n                    if nodeAttribute.valueIsExpr {\n                        error(parser: parser, message: \"Attribute 'id' cannot have a dynamic expression yet\")\n                        return\n                    }\n                    node.id = nodeAttribute.value\n                    node.customAttributes.append(nodeAttribute)\n                case \"renderIf\":\n                    if !nodeAttribute.valueIsExpr {\n                        error(parser: parser, message: \"render-if must be an expression using {{ }}\")\n                        return\n                    }\n                    node.ifExpr = nodeAttribute\n                case \"renderElseIf\":\n                    if !nodeAttribute.valueIsExpr {\n                        error(parser: parser, message: \"render-else-if must be an expression using {{ }}\")\n                        return\n                    }\n                    let prevSibling = parent.childrenNodes.last\n                    if prevSibling == nil || (prevSibling!.rawNode.ifExpr == nil && prevSibling!.rawNode.elseIfExpr == nil) {\n                        error(parser: parser, message: \"render-else-if must be sibling to a render-if or render-else-if\")\n                        return\n                    }\n                    node.elseIfExpr = nodeAttribute\n                case \"renderElse\":\n                    if nodeAttribute.value != \"\" {\n                        error(parser: parser, message: \"render-else must not have an expression\")\n                        return\n                    }\n                    let prevSibling = parent.childrenNodes.last\n                    if prevSibling == nil || (prevSibling!.rawNode.ifExpr == nil && prevSibling!.rawNode.elseIfExpr == nil) {\n                        error(parser: parser, message: \"render-else must be sibling to a render-if or render-else-if\")\n                        return\n                    }\n                    node.elseExpr = nodeAttribute\n                case \"renderUnless\":\n                    if !nodeAttribute.valueIsExpr {\n                        error(parser: parser, message: \"render-unless must be an expression using {{ }}\")\n                        return\n                    }\n                    node.unlessExpr = nodeAttribute\n                case \"slot\":\n                    if nodeAttribute.valueIsExpr {\n                        error(parser: parser, message: \"'slot' cannot support dynamic expressions\")\n                        return\n                    }\n                    node.destSlotName = nodeAttribute.value\n                case \"isLayout\":\n                    if nodeAttribute.valueIsExpr {\n                        error(parser: parser, message: \"'is-layout' cannot support dynamic expressions\")\n                        return\n                    }\n                    guard let bool = Bool(nodeAttribute.value) else {\n                        error(parser: parser, message: \"'is-layout' should be a bool\")\n                        return\n                    }\n                    node.isLayout = bool\n                default:\n                    node.customAttributes.append(nodeAttribute)\n                }\n            }\n\n            node.customAttributes.sort { (left, right) -> Bool in\n                return left.name < right.name\n            }\n\n            let parseNode = ParseNode(rawNode: node)\n            parent.children.append(.node(parseNode))\n            stack.append(parseNode)\n        }\n\n        func parser(_ parser: SwiftSoup.Parser, didEncounterTextNode value: String) {\n            guard error == nil else {\n                return\n            }\n\n            guard let node = stack.last else {\n                error(parser: parser, message: \"Encountered text node without a currently-open tag. Shouldn't be possible\")\n                return\n            }\n\n            guard let value = value.trimmed.nonEmpty else {\n                return\n            }\n\n            guard node.rawNode.customAttributes.filter({ $0.name == \"value\" }).isEmpty else {\n                error(parser: parser, message: \"Cannot have both an XML text and a 'value' attribute. Text values are automatically converted to a 'value' attribute\")\n                return\n            }\n\n            if [\"Label\", \"Button\", \"TextField\"].contains(node.rawNode.nodeType) {\n                let attribute = makeNodeAttribute(attributeName: \"value\", trimmedText: value)\n                node.rawNode.customAttributes.append(attribute)\n            } else if let expression = value.extractingExpression {\n                node.children.append(.expression(expression))\n            }\n        }\n\n        func parser(_ parser: SwiftSoup.Parser, didEndElement elementName: String) {\n            guard error == nil else {\n                return\n            }\n\n            guard let node = stack.popLast() else {\n                error(parser: parser, message: \"Unmatched tag '\\(elementName)'\")\n                return\n            }\n\n            if node.rawNode.nodeType != elementName {\n                error(parser: parser, message: \"Invalid end element '\\(elementName)'\")\n                return\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/CompilationItem.swift",
    "content": "//\n//  CompilationItem.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport Yams\n\nenum Platform: String, CaseIterable, Codable {\n    case ios\n    case android\n    case web\n    case cpp\n}\n\nenum ModuleOutputTarget: Int {\n    case debugOnly\n    case releaseReady\n}\n\nstruct OutputTarget: OptionSet, Hashable {\n    let rawValue: Int\n\n    static let debug = OutputTarget(rawValue: 1 << 0)\n    static let release = OutputTarget(rawValue: 1 << 1)\n    static let all: OutputTarget = [.debug, .release]\n\n    var description: String {\n        if self == .debug {\n            return \"debug\"\n        } else if self == .release {\n            return \"release\"\n        } else {\n            return \"all\"\n        }\n    }\n}\n\nstruct CompilationItem {\n\n    indirect enum Kind {\n        /**\n         A file that is not known yet by Valdi\n         */\n        case unknown(File)\n\n        /**\n         A Valdi document that isn't processed yet\n         */\n        case rawDocument(File)\n\n        /**\n         A parsed Valdi document\n         */\n        case parsedDocument(ValdiRawDocument)\n\n        /**\n         A Valdi document that was compiled, before\n         it was fully assembled with its JavaScript\n         */\n        case document(CompilationResult)\n\n        /**\n         An exported type that needs to be converted to a native source.\n         */\n        case exportedType(ExportedType, ResolvedClassMapping, GeneratedSourceFilename)\n\n        /**\n         Dependency metadata that should be exported from the valdi module.\n         */\n        case exportedDependencyMetadata(ValdiModel, ResolvedClassMapping, GeneratedSourceFilename)\n\n        /**\n         A Native code source file (Objective-C or Kotlin)\n         */\n        case nativeSource(NativeSource)\n\n        /**\n         Diagnostics structure describing an exported type (class, interface, enum, function, view class).\n         */\n        case generatedTypeDescription(GeneratedTypeDescription)\n\n        /**\n         A diagnostics file to be emitted when we finish processing\n         */\n        case diagnosticsFile(File)\n\n        /**\n         A file containing the declared strings for a module\n         */\n        case stringsJSON(File)\n\n        /**\n         A file containing the ids declared for a module\n         */\n        case ids(File)\n\n        /**\n         A Kotlin file that needs to be compiled\n         */\n        case kotlin(File, URL)\n\n        /**\n         A raw resource file that was not transformed by Valdi\n         */\n        case rawResource(File)\n\n        /**\n         An Android resource file, meant to be added in the res directory\n         */\n        case androidResource(String, File)\n\n        /**\n         The raw module.yaml file from the module directory\n         */\n        case moduleYaml(File)\n\n        /**\n         The raw BUILD.bazel from the module directory\n         */\n        case buildFile(File)\n\n        /**\n         An image asset with all its available variants\n         */\n        case imageAsset(ImageAsset)\n\n        /**\n         An image resource which was processed from an image asset\n         */\n        case processedResourceImage(ImageResource)\n\n        /**\n         Dependency injection metadata.\n         */\n        case dependencyMetadata(DependencyMetadata)\n\n        /**\n         A Valdi document resource file\n         */\n        case resourceDocument(DocumentResource)\n\n        /**\n         A class mapping XML file\n         */\n        case classMapping(File)\n\n        /**\n         A JavaScript file\n         */\n        case javaScript(JavaScriptFile)\n\n        /**\n         A TypeScript declaration file\n         */\n        case declaration(JavaScriptFile)\n\n        /**\n         A TypeScript file\n         */\n        case typeScript(File, URL)\n\n        /**\n         Result of requesting dumped symbols from a given TypeScript file.\n         */\n        case dumpedTypeScriptSymbols(DumpedTypeScriptSymbolsResult)\n\n        /**\n         a CSS file\n         */\n        case css(File)\n\n        /**\n         A file that finished processing.\n         */\n        case finalFile(FinalFile)\n\n        /**\n         An item that failed to be processed\n         */\n        case error(Error, originalItemKind: Kind)\n\n        /**\n         A ClientSQL source file\n         */\n        case sql(File)\n        case sqlManifest(File)\n\n        /**\n         Metadata file from a previous compilation run.\n         These files are needed to allow the Compiler to resolve Components defined in .vue files from\n         other Valdi modules that have been compiled separately (i.e. when the Compiler\n         is driven by Bazel and some .vue file refers to a Component from a .vue file from another module).\n         */\n        case compilationMetadata(File)\n\n        /**\n         When a new downloadable artifact is generated we save this signature file into the module's directory.\n         If an existing signature matches the newly generated downloadable artifact, we know we don't need to\n         upload it to Bolt again.\n\n         BundleResourcesProcessor can run in a special mode that will fail compilation if a produced downloadable artifact\n         doesn't match an existing signature (see BundleResourcesProcessor.DownloadableArtifactsProcessingMode\n         */\n        case downloadableArtifactSignatures(DownloadableArtifactSignatures)\n\n        /**\n         Single iOS Strings resource file\n         */\n        case iosStringResource(String, File)\n    }\n\n    /**\n     Info about the bundle that a compilation item belongs to\n     */\n    class BundleInfo: Hashable {\n        /**\n         The name of the bundle\n         */\n        let name: String\n\n        /**\n         Absolute url to the bundle's base directory\n         */\n        let baseDir: URL\n\n        /**\n         The prefix to add to all items found within this bundle\n         */\n        let relativeProjectPathPrefix: String\n\n        let disableHotReload: Bool\n        let disableAnnotationProcessing: Bool\n        let disableDependencyVerification: Bool\n        let disableBazelBuildFileGeneration: Bool\n        let asyncStrictMode: Bool\n\n        let webNpmScope: String\n        let webVersion: String\n        let webPublishConfig: String\n        let webMain: String\n\n        let iosModuleName: String\n        let iosLanguage: IOSLanguage\n        let iosGeneratedContextFactories: [String]\n\n        let isRoot: Bool\n\n        let downloadableAssets: Bool\n        let downloadableSources: Bool\n\n        let inclusionConfig: InclusionConfig\n        let excludeGlobs: [String]\n        let dependencies: [BundleInfo]\n\n        let compilationModeConfig: CompilationModeConfig\n\n        let projectConfig: ValdiProjectConfig\n\n        let iosReleaseOutputDirectories: OutDirectories?\n        let androidReleaseOutputDirectories: OutDirectories?\n        let webReleaseOutputDirectories: OutDirectories?\n        let cppReleaseOutputDirectories: OutDirectories?\n        let iosDebugOutputDirectories: OutDirectories?\n        let androidDebugOutputDirectories: OutDirectories?\n        let webDebugOutputDirectories: OutDirectories?\n        let cppDebugOutputDirectories: OutDirectories?\n\n        // for cleaning up if a Valdi module goes from releaseReady to debugOnly\n        let iosExpectedReleaseOutputDirectories: OutDirectories?\n        let androidExpectedReleaseOutputDirectories: OutDirectories?\n        let webExpectedReleaseOutputDirectories: OutDirectories?\n        let cppExpectedReleaseOutputDirectories: OutDirectories?\n\n        let androidClassPath: String?\n        let iosClassPrefix: String?\n        let cppClassPrefix: String?\n\n        let iosCodegenEnabled: Bool\n        let androidCodegenEnabled: Bool\n        let cppCodegenEnabled: Bool\n        let disableCodeCoverage: Bool\n        let singleFileCodegen: Bool\n\n        private let iosOutputTarget: ModuleOutputTarget?\n        private let androidOutputTarget: ModuleOutputTarget?\n        private let webOutputTarget: ModuleOutputTarget?\n        private let cppOutputTarget: ModuleOutputTarget?\n\n        enum ModuleStringsConfig {\n            case jsonDir(bundleRelativePath: String)\n\n            var bundleRelativePath: String {\n                switch self {\n                case let .jsonDir(bundleRelativePath):\n                    return bundleRelativePath\n                }\n            }\n        }\n\n        let stringsConfig: ModuleStringsConfig?\n\n        init(name: String,\n             baseDir: URL,\n             relativeProjectPathPrefix: String,\n             disableHotReload: Bool,\n             disableAnnotationProcessing: Bool,\n             disableDependencyVerification: Bool,\n             disableBazelBuildFileGeneration: Bool,\n             asyncStrictMode: Bool,\n             webNpmScope: String,\n             webVersion: String,\n             webPublishConfig: String,\n             webMain: String,\n             iosModuleName: String,\n             iosLanguage: IOSLanguage,\n             iosClassPrefix: String?,\n             androidClassPath: String?,\n             cppClassPrefix: String?,\n             iosCodegenEnabled: Bool,\n             androidCodegenEnabled: Bool,\n             cppCodegenEnabled: Bool,\n             disableCodeCoverage: Bool,\n             singleFileCodegen: Bool,\n             compilationModeConfig: CompilationModeConfig,\n             iosOutputTarget: ModuleOutputTarget?,\n             iosGeneratedContextFactories: [String],\n             androidOutputTarget: ModuleOutputTarget?,\n             webOutputTarget: ModuleOutputTarget?,\n             cppOutputTarget: ModuleOutputTarget?,\n             downloadableAssets: Bool,\n             downloadableSources: Bool,\n             inclusionConfig: InclusionConfig,\n             excludeGlobs: [String],\n             dependencies: [BundleInfo],\n             stringsConfig: ModuleStringsConfig?,\n             projectConfig: ValdiProjectConfig,\n             outputTarget: OutputTarget) throws {\n            self.name = name\n            self.baseDir = baseDir\n            self.relativeProjectPathPrefix = relativeProjectPathPrefix\n            self.disableHotReload = disableHotReload\n            self.disableAnnotationProcessing = disableAnnotationProcessing\n            self.disableDependencyVerification = disableDependencyVerification\n            self.disableBazelBuildFileGeneration = disableBazelBuildFileGeneration\n            self.asyncStrictMode = asyncStrictMode\n            self.webNpmScope = webNpmScope\n            self.webVersion = webVersion\n            self.webPublishConfig = webPublishConfig\n            self.webMain = webMain\n            self.iosModuleName = iosModuleName\n            self.iosLanguage = iosLanguage\n            self.iosOutputTarget = iosOutputTarget\n            self.iosGeneratedContextFactories = iosGeneratedContextFactories\n            self.androidOutputTarget = androidOutputTarget\n            self.webOutputTarget = webOutputTarget\n            self.cppOutputTarget = cppOutputTarget\n            self.disableCodeCoverage = disableCodeCoverage\n            self.downloadableAssets = downloadableAssets\n            self.downloadableSources = downloadableSources\n            self.isRoot = name == BundleInfo.rootModuleName\n            self.inclusionConfig = inclusionConfig\n            self.excludeGlobs = excludeGlobs\n            self.dependencies = dependencies\n            self.allDependencies = Self.collectAllDependencies(dependencies)\n            self.allDependenciesNames = Set(allDependencies.map { $0.name })\n\n            self.compilationModeConfig = compilationModeConfig\n            self.projectConfig = projectConfig\n\n            if !isRoot {\n                let iosExpectedDebugOutputDirectories = try projectConfig.iosOutput?.debugPath.flatMap { try Self.iosOutputDirectories(iosOutputPath: $0,\n                                                                                                                                   moduleName: name,\n                                                                                                                                   iosModuleName: iosModuleName,\n                                                                                                                                   projectConfig: projectConfig) }\n                self.iosExpectedReleaseOutputDirectories = try Self.iosOutputDirectories(iosOutputPath: projectConfig.iosOutput?.releasePath,\n                                                                                         moduleName: name,\n                                                                                         iosModuleName: iosModuleName,\n                                                                                         projectConfig: projectConfig)\n\n                (self.iosDebugOutputDirectories, self.iosReleaseOutputDirectories) = BundleInfo.getOutputDirectories(\n                    moduleOutputTarget: iosOutputTarget,\n                    compileOutputTarget: outputTarget,\n                    expectedDebugOutputDirectories: iosExpectedDebugOutputDirectories,\n                    expectedReleaseOutputDirectories: iosExpectedReleaseOutputDirectories)\n\n                let androidExpectedDebugOutputDirectories = try projectConfig.androidOutput?.debugPath.flatMap {  try Self.androidOutputDirectories(androidOutputPath: $0,\n                                                                                                                                                moduleName: name,\n                                                                                                                                                projectConfig: projectConfig)  }\n                self.androidExpectedReleaseOutputDirectories = try Self.androidOutputDirectories(androidOutputPath: projectConfig.androidOutput?.releasePath,\n                                                                                                 moduleName: name,\n                                                                                                 projectConfig: projectConfig)\n\n                (self.androidDebugOutputDirectories, self.androidReleaseOutputDirectories) = BundleInfo.getOutputDirectories(\n                    moduleOutputTarget: androidOutputTarget,\n                    compileOutputTarget: outputTarget,\n                    expectedDebugOutputDirectories: androidExpectedDebugOutputDirectories,\n                    expectedReleaseOutputDirectories: androidExpectedReleaseOutputDirectories)\n\n                let webExpectedDebugOutputDirectories = try projectConfig.webOutput?.debugPath.flatMap {\n                    return try Self.webOutputDirectories(webOutputPath: $0,\n                                                         moduleName: name,\n                                                         projectConfig: projectConfig)\n                }\n                self.webExpectedReleaseOutputDirectories = try Self.webOutputDirectories(webOutputPath: projectConfig.webOutput?.releasePath,\n                                                                                         moduleName: name,\n                                                                                         projectConfig: projectConfig)\n\n                (self.webDebugOutputDirectories, self.webReleaseOutputDirectories) = BundleInfo.getOutputDirectories(\n                    moduleOutputTarget: webOutputTarget,\n                    compileOutputTarget: outputTarget,\n                    expectedDebugOutputDirectories: webExpectedDebugOutputDirectories,\n                    expectedReleaseOutputDirectories: webExpectedReleaseOutputDirectories)\n\n                let cppExpectedDebugOutputDirectories = try projectConfig.cppOutput?.debugPath.flatMap {\n                    return try Self.cppOutputDirectories(cppOutputPath: $0,\n                                                         moduleName: name,\n                                                         projectConfig: projectConfig)\n                }\n                self.cppExpectedReleaseOutputDirectories = try Self.cppOutputDirectories(cppOutputPath: projectConfig.cppOutput?.releasePath,\n                                                                                         moduleName: name,\n                                                                                         projectConfig: projectConfig)\n\n                (self.cppDebugOutputDirectories, self.cppReleaseOutputDirectories) = BundleInfo.getOutputDirectories(\n                    moduleOutputTarget: cppOutputTarget,\n                    compileOutputTarget: outputTarget,\n                    expectedDebugOutputDirectories: cppExpectedDebugOutputDirectories,\n                    expectedReleaseOutputDirectories: cppExpectedReleaseOutputDirectories)\n            } else {\n                self.iosReleaseOutputDirectories = nil\n                self.iosDebugOutputDirectories = nil\n                self.iosExpectedReleaseOutputDirectories = nil\n                self.androidReleaseOutputDirectories = nil\n                self.androidDebugOutputDirectories = nil\n                self.androidExpectedReleaseOutputDirectories = nil\n                self.webReleaseOutputDirectories = nil\n                self.webDebugOutputDirectories = nil\n                self.webExpectedReleaseOutputDirectories = nil\n                self.cppReleaseOutputDirectories = nil\n                self.cppDebugOutputDirectories = nil\n                self.cppExpectedReleaseOutputDirectories = nil\n            }\n\n            self.iosClassPrefix = iosClassPrefix\n            self.androidClassPath = androidClassPath\n            self.cppClassPrefix = cppClassPrefix\n\n            self.iosCodegenEnabled = iosCodegenEnabled\n            self.androidCodegenEnabled = androidCodegenEnabled\n            self.cppCodegenEnabled = cppCodegenEnabled\n            self.singleFileCodegen = singleFileCodegen\n\n            self.stringsConfig = stringsConfig\n        }\n\n        private static func getOutputDirectories(moduleOutputTarget: ModuleOutputTarget?,\n                                                 compileOutputTarget: OutputTarget, \n                                                 expectedDebugOutputDirectories: OutDirectories?,\n                                                 expectedReleaseOutputDirectories: OutDirectories?) -> (debug: OutDirectories?, release: OutDirectories?) {\n            let debugCompilationEnabled = compileOutputTarget.contains(.debug)\n            let releaseCompilationEnabled = compileOutputTarget.contains(.release)\n\n            switch moduleOutputTarget {\n            case .none, .debugOnly:\n                return (debug: debugCompilationEnabled ? expectedDebugOutputDirectories : nil, release: nil)\n            case .releaseReady:\n                return (debug: debugCompilationEnabled ? expectedDebugOutputDirectories : nil, release: releaseCompilationEnabled ? expectedReleaseOutputDirectories: nil)\n            }\n        }\n\n        func relativeProjectPath(forItemPath itemPath: String) -> String {\n            return self.relativeProjectPathPrefix + itemPath\n        }\n\n        func relativeProjectPath(forItemURL itemURL: URL) -> String {\n            let itemPath = self.itemPath(forItemURL: itemURL)\n            return relativeProjectPath(forItemPath: itemPath)\n        }\n\n        func itemPath(forItemURL itemURL: URL) -> String {\n            let resolvedItemURL = (try? itemURL.resolvingSymlink(resolveParentDirs: true)) ?? itemURL\n            return baseDir.relativePath(to: resolvedItemURL)\n        }\n\n        func itemPath(forRelativeProjectPath relativeProjectPath: String) throws -> String {\n            guard relativeProjectPath.hasPrefix(self.relativeProjectPathPrefix) else {\n                throw CompilerError(\"Expecting relative project path to start with '\\(self.relativeProjectPathPrefix)'\")\n            }\n\n            return String(relativeProjectPath[self.relativeProjectPathPrefix.endIndex...])\n        }\n\n        func relativeBundleURL(forRelativeProjectPath relativeProjectPath: String, sourceURL: URL) -> URL {\n            if isRoot {\n                // We're getting paths with <root> in them here\n                guard let url = URL(string: relativeProjectPath) else {\n                    return URL(string: relativeProjectPath.replacingOccurrences(of: BundleInfo.rootModuleName, with: \"\"))!\n                }\n                return url\n            } else {\n                guard relativeProjectPath.hasPrefix(name) else {\n                    return URL(string: baseDir.relativePath(to: sourceURL))!\n                }\n\n                let bundlePath = String(relativeProjectPath[relativeProjectPath.index(name.endIndex, offsetBy: 1)..<relativeProjectPath.endIndex])\n\n                return URL(string: bundlePath)!\n            }\n        }\n\n        func absoluteURL(forRelativeProjectPath relativeProjectPath: String) -> URL {\n            return baseDir.deletingLastPathComponent().appendingPathComponent(relativeProjectPath)\n        }\n\n        func resolvedBundleName() -> String {\n            return BundleManager.resolveBundleName(bundleName: name)\n        }\n\n        private static func iosOutputDirectories(iosOutputPath: UnresolvedPath?, moduleName: String, iosModuleName: String, projectConfig: ValdiProjectConfig) throws -> OutDirectories? {\n            let outDirectories = try BundleInfo.resolveIOSOutputDirectories(outputPath: iosOutputPath,\n                                                                            metadataPath: projectConfig.iosOutput?.metadataPath,\n                                                                            moduleName: moduleName,\n                                                                            iosModuleName: iosModuleName,\n                                                                            projectConfig: projectConfig)\n            return outDirectories\n        }\n\n        private static func androidOutputDirectories(androidOutputPath: UnresolvedPath?, moduleName: String, projectConfig: ValdiProjectConfig) throws -> OutDirectories? {\n            let outDirectories = try BundleInfo.resolveOutputDirectories(outputPath: androidOutputPath,\n                                                                         metadataPath: projectConfig.androidOutput?.metadataPath,\n                                                                         moduleName: moduleName,\n                                                                         projectConfig: projectConfig,\n                                                                         assetDir: \"assets\")\n            return outDirectories\n        }\n\n        private static func webOutputDirectories(webOutputPath: UnresolvedPath?, moduleName: String, projectConfig: ValdiProjectConfig) throws -> OutDirectories? {\n            let outDirectories = try BundleInfo.resolveWebOutputDirectories(outputPath: webOutputPath,\n                                                                         metadataPath: projectConfig.webOutput?.metadataPath,\n                                                                         moduleName: moduleName,\n                                                                         projectConfig: projectConfig,\n                                                                         assetDir: \"assets\")\n            return outDirectories\n        }\n\n        private static func cppOutputDirectories(cppOutputPath: UnresolvedPath?, moduleName: String, projectConfig: ValdiProjectConfig) throws -> OutDirectories? {\n            let outDirectories = try BundleInfo.resolveCppOutputDirectories(outputPath: cppOutputPath,\n                                                                            metadataPath: projectConfig.webOutput?.metadataPath,\n                                                                            moduleName: moduleName,\n                                                                            projectConfig: projectConfig)\n            return outDirectories\n        }\n\n        private static func resolveModulePath(_ path: UnresolvedPath, moduleName: String) throws -> URL {\n            return try path.appendingVariable(key: \"MODULE_NAME\", value: moduleName).resolve()\n        }\n\n        private static func resolveOutputAndMetadataURL(outputPath: UnresolvedPath?, metadataPath: UnresolvedPath?, moduleName: String) throws -> (outputURL: URL, metadataURL: URL?)? {\n            guard let outputPath = outputPath else {\n                return nil\n            }\n\n            let outputURL = try resolveModulePath(outputPath, moduleName: moduleName)\n\n            let moduleMetadataURL: URL?\n            if let metadataPath = metadataPath {\n                moduleMetadataURL = try resolveModulePath(metadataPath, moduleName: moduleName)\n            } else {\n                moduleMetadataURL = nil\n            }\n\n            return (outputURL, moduleMetadataURL)\n        }\n\n        private static func resolveOutputDirectories(outputPath: UnresolvedPath?, metadataPath: UnresolvedPath?, moduleName: String, projectConfig: ValdiProjectConfig, assetDir: String) throws -> OutDirectories? {\n            guard let (outputURL, metadataURL) = try resolveOutputAndMetadataURL(outputPath: outputPath, metadataPath: metadataPath, moduleName: moduleName) else {\n                return nil\n            }\n\n            let assetsURL: URL = outputURL.appendingPathComponent(assetDir, isDirectory: true)\n\n            let srcURL = outputURL.appendingPathComponent(\"src\", isDirectory: true)\n            let nativeSrcURL = outputURL.appendingPathComponent(\"native\", isDirectory: true)\n            let resourcesURL = outputURL.appendingPathComponent(\"res\", isDirectory: true)\n\n            return OutDirectories(\n                baseURL: outputURL,\n                assetsURL: assetsURL,\n                srcURL: srcURL,\n                nativeSrcURL: nativeSrcURL,\n                resourcesURL: resourcesURL,\n                metadataURL: metadataURL)\n        }\n\n        private static func resolveWebOutputDirectories(outputPath: UnresolvedPath?, metadataPath: UnresolvedPath?, moduleName: String, projectConfig: ValdiProjectConfig, assetDir: String) throws -> OutDirectories? {\n            if !projectConfig.webEnabled {\n                return nil\n            }\n            \n            guard let (outputURL, metadataURL) = try resolveOutputAndMetadataURL(outputPath: outputPath, metadataPath: metadataPath, moduleName: moduleName) else {\n                return nil\n            }\n\n            // All compiled typescript files are being saved as assets,\n            // file naming overlap between modules is causing problems so let's shove them\n            // into their own named directories\n            // Including resources in this extra path thing\n            // TODO(cholgate): fix this\n            let assetsURL: URL = outputURL.appendingPathComponent(assetDir, isDirectory: true).appendingPathComponent(moduleName, isDirectory: true)\n            let resourcesURL = outputURL.appendingPathComponent(\"res\", isDirectory: true).appendingPathComponent(moduleName, isDirectory: true)\n\n\n            let srcURL = outputURL.appendingPathComponent(\"src\", isDirectory: true).appendingPathComponent(moduleName, isDirectory: true)\n            let nativeSrcURL = outputURL.appendingPathComponent(\"native\", isDirectory: true)\n\n            return OutDirectories(\n                baseURL: outputURL,\n                assetsURL: assetsURL,\n                srcURL: srcURL,\n                nativeSrcURL: nativeSrcURL,\n                resourcesURL: resourcesURL,\n                metadataURL: metadataURL)\n        }\n\n        private static func resolveCppOutputDirectories(outputPath: UnresolvedPath?, metadataPath: UnresolvedPath?, moduleName: String, projectConfig: ValdiProjectConfig) throws -> OutDirectories? {\n            guard let (outputURL, metadataURL) = try resolveOutputAndMetadataURL(outputPath: outputPath, metadataPath: metadataPath, moduleName: moduleName) else {\n                return nil\n            }\n\n            let assetsURL: URL = outputURL.appendingPathComponent(\"assets\", isDirectory: true)\n\n            let srcURL = outputURL.appendingPathComponent(\"src\", isDirectory: true)\n            let resourcesURL = outputURL.appendingPathComponent(\"res\", isDirectory: true)\n\n            return OutDirectories(\n                baseURL: outputURL,\n                assetsURL: assetsURL,\n                srcURL: srcURL,\n                nativeSrcURL: srcURL,\n                resourcesURL: resourcesURL,\n                metadataURL: metadataURL)\n        }\n\n        private static func resolveIOSOutputDirectories(outputPath: UnresolvedPath?, metadataPath: UnresolvedPath?, moduleName: String, iosModuleName: String, projectConfig: ValdiProjectConfig) throws -> OutDirectories? {\n            guard let (outputURL, metadataURL) = try resolveOutputAndMetadataURL(outputPath: outputPath, metadataPath: metadataPath, moduleName: iosModuleName) else {\n                return nil\n            }\n\n            let moduleAssetsURL = outputURL.appendingPathComponent(\"assets\", isDirectory: true)\n\n            let srcURL = outputURL.appendingPathComponent(\"src\", isDirectory: true).appendingPathComponent(iosModuleName, isDirectory: true)\n            let nativeSrcURL = outputURL.appendingPathComponent(\"native\", isDirectory: true).appendingPathComponent(iosModuleName, isDirectory: true)\n            let resourcesURL = moduleAssetsURL.appendingPathComponent(\"\\(moduleName).bundle\", isDirectory: true)\n\n            return OutDirectories(\n                baseURL: outputURL,\n                assetsURL: moduleAssetsURL,\n                srcURL: srcURL,\n                nativeSrcURL: nativeSrcURL,\n                resourcesURL: resourcesURL,\n                metadataURL: metadataURL)\n        }\n\n        static func==(lhs: BundleInfo, rhs: BundleInfo) -> Bool {\n            return lhs === rhs\n        }\n\n        func hash(into hasher: inout Hasher) {\n            hasher.combine(baseDir)\n        }\n\n        func outputTarget(platform: Platform) -> ModuleOutputTarget? {\n            switch platform {\n            case .ios:\n                return iosOutputTarget\n            case .android:\n                return androidOutputTarget\n            case .web:\n                return webOutputTarget\n            case .cpp:\n                return cppOutputTarget\n            }\n        }\n\n        let allDependencies: Set<BundleInfo>\n\n        let allDependenciesNames: Set<String>\n\n        /**\n         Placeholder used for the root module\n         */\n        static let rootModuleName = \"<root>\"\n\n        private static func collectAllDependencies(_ dependencies: [BundleInfo]) -> Set<BundleInfo> {\n            var modules = Set<BundleInfo>()\n\n            var queue = dependencies\n            while !queue.isEmpty {\n                let current = queue.removeLast()\n                if !modules.contains(current) {\n                    modules.insert(current)\n                    queue.append(contentsOf: current.dependencies)\n                }\n            }\n\n            return modules\n        }\n    }\n\n    let sourceURL: URL\n    let kind: Kind\n    let bundleInfo: BundleInfo\n    let platform: Platform?\n    let outputTarget: OutputTarget\n\n    /// URL relative to the bundle's base directory\n    let relativeBundleURL: URL\n\n    /**\n     The path identifying this item within the compilation unit.\n     From within the compiler, the file will be available to be imported with\n     this given path.\n     */\n    let relativeProjectPath: String\n\n    /**\n     Returns the relative path from the bundle base's directory\n     */\n    var relativeBundlePath: RelativePath {\n        return RelativePath(url: self.relativeBundleURL)\n    }\n\n    init(relativeProjectPath: String, kind: Kind, bundleInfo: BundleInfo, platform: Platform?, outputTarget: OutputTarget) {\n        self.init(sourceURL: bundleInfo.absoluteURL(forRelativeProjectPath: relativeProjectPath),\n                  relativeProjectPath: relativeProjectPath,\n                  kind: kind,\n                  bundleInfo: bundleInfo,\n                  platform: platform,\n                  outputTarget: outputTarget)\n    }\n\n    init(sourceURL: URL, relativeProjectPath: String?, kind: Kind, bundleInfo: BundleInfo, platform: Platform?, outputTarget: OutputTarget) {\n        self.sourceURL = sourceURL\n\n        if let relativeProjectPath {\n            self.relativeBundleURL = bundleInfo.relativeBundleURL(forRelativeProjectPath: relativeProjectPath, sourceURL: sourceURL)\n            self.relativeProjectPath = relativeProjectPath\n        } else {\n            let itemPath = bundleInfo.itemPath(forItemURL: sourceURL)\n            let relativeProjectPath = bundleInfo.relativeProjectPath(forItemPath: itemPath)\n            guard let relativeBundleURL = URL(string: itemPath) else {\n                fatalError(\"Could not resolve URL from \\(sourceURL)\")\n            }\n\n            self.relativeBundleURL = relativeBundleURL\n            self.relativeProjectPath = relativeProjectPath\n        }\n\n        self.kind = kind\n        self.bundleInfo = bundleInfo\n        self.platform = platform\n        self.outputTarget = outputTarget\n    }\n\n    init(generatedFromBundleInfo bundleInfo: BundleInfo, kind: Kind, platform: Platform?, outputTarget: OutputTarget) {\n        self.sourceURL = bundleInfo.baseDir\n        self.relativeBundleURL = URL(string: \".\")!\n        self.relativeProjectPath = bundleInfo.relativeProjectPath(forItemPath: \".\")\n\n        self.kind = kind\n        self.bundleInfo = bundleInfo\n        self.platform = platform\n        self.outputTarget = outputTarget\n    }\n\n    func with(newKind: Kind, newPlatform: Platform?) -> CompilationItem {\n        return with(newKind: newKind, newPlatform: newPlatform, newOutputTarget: self.outputTarget)\n    }\n\n    func with(newKind: Kind, newPlatform: Platform?, newOutputTarget: OutputTarget) -> CompilationItem {\n        return CompilationItem(sourceURL: sourceURL, relativeProjectPath: self.relativeProjectPath, kind: newKind, bundleInfo: bundleInfo, platform: newPlatform, outputTarget: newOutputTarget)\n    }\n\n    func with(newPlatform: Platform) -> CompilationItem {\n        return with(newKind: self.kind, newPlatform: newPlatform)\n    }\n\n    func with(newKind: Kind) -> CompilationItem {\n        return with(newKind: newKind, newPlatform: self.platform)\n    }\n\n    func with(error: Error) -> CompilationItem {\n        return with(newKind: .error(error, originalItemKind: self.kind))\n    }\n\n    func with(newOutputTarget: OutputTarget) -> CompilationItem {\n        return with(newKind: kind, newPlatform: self.platform, newOutputTarget: newOutputTarget)\n    }\n\n    func toString() -> String {\n        // For debugging purposes\n        return \"url: \\(sourceURL) platform: \\(platform.debugDescription) kind: \\(kind)\"\n    }\n}\n\nextension CompilationItem {\n\n    func shouldOutput(to outputPlatform: Platform) -> Bool {\n        return platform.map { $0 == outputPlatform } ?? true\n    }\n\n    var shouldOutputToAndroid: Bool {\n        return shouldOutput(to: .android)\n    }\n\n    var shouldOutputToIOS: Bool {\n        return shouldOutput(to: .ios)\n    }\n\n    var shouldOutputToWeb: Bool {\n        return shouldOutput(to: .web)\n    }\n\n    var shouldOutputToCpp: Bool {\n        return shouldOutput(to: .cpp)\n    }\n\n    /// Indicate whether the item is a test compilation item.\n    /// Test items are located under \"test\" subdirectory.\n    var isTestItem: Bool {\n        // test sources will be in module/test directory\n        return relativeBundleURL.pathComponents.first == \"test\"\n    }\n\n    var error: Error? {\n        if case .error(let error, _) = self.kind {\n            return error\n        } else {\n            return nil\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/CompilationItems.swift",
    "content": "//\n//  PipelineItems.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct SelectedItem<T> {\n    let item: CompilationItem\n    let data: T\n}\n\nstruct GroupedItems<Key, T> {\n    let key: Key\n    let items: [T]\n}\n\nstruct SelectedCompilationItems<T> {\n    let compileSequence: CompilationSequence\n    let unselectedItems: [CompilationItem]\n    let selectedItems: [T]\n\n    func discardSelected() -> CompilationItems {\n        return CompilationItems(compileSequence: compileSequence, items: unselectedItems)\n    }\n\n    func discardNonSelected() -> SelectedCompilationItems<T> {\n        return SelectedCompilationItems(compileSequence: compileSequence, unselectedItems: [], selectedItems: self.selectedItems)\n    }\n\n    func transformEach(_ eachClosure: (T) throws -> Void) rethrows -> CompilationItems {\n        return try transformEach { (item) -> [CompilationItem] in\n            try eachClosure(item)\n            return []\n        }\n    }\n\n    func transformEach(_ eachClosure: (T) throws -> CompilationItem) rethrows -> CompilationItems {\n        return try transformEach {\n            [try eachClosure($0)]\n        }\n    }\n\n    func transformEachConcurrently(_ eachClosure: (T) throws -> CompilationItem) rethrows -> CompilationItems {\n        return try transformAll { (items) -> [CompilationItem] in\n            return try items.parallelMap { (item) in\n                try eachClosure(item)\n            }\n        }\n    }\n\n    func transformEachConcurrently(_ eachClosure: (T) throws -> [CompilationItem]) rethrows -> CompilationItems {\n        return try transformAll { (items) -> [CompilationItem] in\n            return try items.parallelMap { (item) in\n                try eachClosure(item)\n                }.flatMap { $0 }\n        }\n    }\n\n    @discardableResult func processEachConcurrently(_ eachClosure: (T) throws -> Void) rethrows -> SelectedCompilationItems<T> {\n        try selectedItems.parallelProcess { (item) in\n            try eachClosure(item)\n        }\n\n        return self\n    }\n\n    @discardableResult func processAll(_ allClosure: ([T]) throws -> Void) rethrows -> SelectedCompilationItems<T> {\n        try allClosure(selectedItems)\n        return self\n    }\n\n    func transformEach(_ eachClosure: (T) throws -> [CompilationItem]) rethrows -> CompilationItems {\n        var newItems = [CompilationItem]()\n        newItems.reserveCapacity(unselectedItems.count + selectedItems.count)\n        newItems.append(contentsOf: unselectedItems)\n\n        for selectedItem in selectedItems {\n            let updatedItems = try eachClosure(selectedItem)\n            newItems += updatedItems\n        }\n\n        return CompilationItems(compileSequence: compileSequence, items: newItems)\n    }\n\n    func transformAll(_ allClosure: ([T]) throws -> [CompilationItem]) rethrows -> CompilationItems {\n        let updatedItems = try allClosure(selectedItems)\n\n        return CompilationItems(compileSequence: compileSequence, items: unselectedItems + updatedItems)\n    }\n\n    func transformInBatches(_  batchClosure: (_ items: [T]) throws -> [CompilationItem]) rethrows -> CompilationItems {\n        return try transformInBatches(ProcessInfo.processInfo.activeProcessorCount, batchClosure)\n    }\n\n    func transformInBatches(_ numberOfBatches: Int, _ batchClosure: (_ items: [T]) throws -> [CompilationItem]) rethrows -> CompilationItems {\n        let distance = Int(ceil(Float(selectedItems.count) / Float(numberOfBatches)))\n        let batchSequence = BatchSequence(array: selectedItems, distance: distance)\n        let batches = Array(batchSequence)\n        let processedBatches = try batches.parallelMap(batchClosure)\n        let updatedItems = processedBatches.flatMap { $0 }\n\n        return CompilationItems(compileSequence: compileSequence, items: unselectedItems + updatedItems)\n    }\n\n    func groupBy<Key: Hashable>(_ getKeyClosure: (T) -> Key) -> SelectedCompilationItems<GroupedItems<Key, T>> {\n        var itemsByKey = [Key: [T]]()\n        for item in selectedItems {\n            let key = getKeyClosure(item)\n            itemsByKey[key, default: []].append(item)\n        }\n\n        let newSelectedItems = itemsByKey.map { GroupedItems(key: $0.key, items: $0.value) }\n\n        return SelectedCompilationItems<GroupedItems<Key, T>>(compileSequence: compileSequence, unselectedItems: unselectedItems, selectedItems: newSelectedItems)\n    }\n}\n\nstruct CompilationItems {\n\n    let compileSequence: CompilationSequence\n    var allItems: [CompilationItem]\n\n    init(compileSequence: CompilationSequence, items: [CompilationItem]) {\n        self.compileSequence = compileSequence\n        self.allItems = items\n    }\n\n    mutating func append(item: CompilationItem) {\n        self.allItems.append(item)\n    }\n\n    func select<T>(_ selectClosure: (CompilationItem) -> T?) -> SelectedCompilationItems<SelectedItem<T>> {\n        var unselectedItems = [CompilationItem]()\n        unselectedItems.reserveCapacity(allItems.count)\n\n        var selectedItems = [SelectedItem<T>]()\n\n        for item in allItems {\n            if let data = selectClosure(item) {\n                selectedItems.append(SelectedItem(item: item, data: data))\n            } else {\n                unselectedItems.append(item)\n            }\n        }\n\n        return SelectedCompilationItems(compileSequence: compileSequence, unselectedItems: unselectedItems, selectedItems: selectedItems)\n    }\n\n    func selectAll() -> SelectedCompilationItems<CompilationItem> {\n        return SelectedCompilationItems(compileSequence: compileSequence, unselectedItems: [], selectedItems: allItems)\n    }\n\n    func debugLog(logger: ILogger) {\n        for item in allItems {\n            logger.error(item.toString())\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/CompilationMode.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\nimport Yams\n\nenum CompilationMode {\n    case jsBytecode\n    case js\n    case native\n\n    static func from(str: String) throws -> CompilationMode {\n        switch str.trimmed {\n        case \"js\":\n            return .js\n        case \"js_bytecode\":\n            return .jsBytecode\n        case \"native\":\n            return .native\n        default:\n            throw CompilerError(\"Invalid compilation mode '\\(str)'. Expecting 'js', 'js_bytecode' or 'native'\")\n        }\n    }\n}\n\n/**\n Holds the set of inclusion rules that helps resolving the compilation mode to use of each item within a module.\n */\nstruct CompilationModeConfig {\n    let js: InclusionConfig?\n    let jsBytecode: InclusionConfig?\n    let native: InclusionConfig?\n\n    /**\n     Compilation mode config that will use JS output  for every item in the module\n     */\n    static func forJs() -> CompilationModeConfig {\n        return CompilationModeConfig(js: InclusionConfig.alwaysIncluded, jsBytecode: nil, native: nil)\n    }\n\n    /**\n     Compilation mode config that will use JS bytecode output  for every item in the module\n     */\n    static func forJsBytecode() -> CompilationModeConfig {\n        return CompilationModeConfig(js: nil, jsBytecode: InclusionConfig.alwaysIncluded, native: nil)\n    }\n\n    /**\n     Compilation mode config that will use native output  for every item in the module\n     */\n    static func forNative() -> CompilationModeConfig {\n        return CompilationModeConfig(js: nil, jsBytecode: nil, native: InclusionConfig.alwaysIncluded)\n    }\n\n    static func parse(from node: Yams.Node) throws -> CompilationModeConfig {\n        if let str = node.string {\n            switch try CompilationMode.from(str: str) {\n            case .js:\n                return CompilationModeConfig.forJs()\n            case .jsBytecode:\n                return CompilationModeConfig.forJsBytecode()\n            case .native:\n                return CompilationModeConfig.forNative()\n            }\n        }\n\n        guard let mapping = node.mapping else {\n            throw CompilerError(\"Expected string or mapping for 'compilation_mode' config\")\n        }\n\n        var jsInclusionConfig: InclusionConfig?\n        var jsBytecodeInclusionConfig: InclusionConfig?\n        var nativeInclusionConfig: InclusionConfig?\n\n        for (key, value) in mapping {\n            guard let compilationModeStr = key.string else {\n                throw CompilerError(\"Each entry in the 'compilation_mode' mapping should have a string key\")\n            }\n\n            switch try CompilationMode.from(str: compilationModeStr) {\n            case .js:\n                jsInclusionConfig = try InclusionConfig.parse(from: value)\n            case .jsBytecode:\n                jsBytecodeInclusionConfig = try InclusionConfig.parse(from: value)\n            case .native:\n                nativeInclusionConfig = try InclusionConfig.parse(from: value)\n            }\n        }\n\n        return CompilationModeConfig(js: jsInclusionConfig, jsBytecode: jsBytecodeInclusionConfig, native: nativeInclusionConfig)\n    }\n\n    /**\n     Resolves the compilation mode to use for the item at the given path.\n     Will use native if one of the include patterns matches the item path.\n     Will use js if one of the include patterns matches the item path, or if the js bytecode exclude patterns matches\n     Will use js bytecode in all other scenarios.\n     */\n    func resolveCompilationMode(forItemPath itemPath: String) -> CompilationMode {\n        if let native {\n            if native.resolve(itemPath) == .included {\n                return .native\n            }\n        }\n\n        if let js {\n            if js.resolve(itemPath) == .included {\n                return .js\n            }\n        }\n\n        if let jsBytecode {\n            switch jsBytecode.resolve(itemPath) {\n            case .included:\n                return .jsBytecode\n            case .excluded:\n                // If jsBytecode is specifically excluded, we use js\n                return .js\n            case .unknown:\n                break\n            }\n        }\n\n        // Use jsBytecode by default\n\n        return .jsBytecode\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/CompilationPipeline.swift",
    "content": "//\n//  CompilationPipeline.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class CompilationPipelineErrorDumper {\n    private let deferredWarningCollector: DeferredWarningCollector\n    \n    init(deferredWarningCollector: DeferredWarningCollector) {\n        self.deferredWarningCollector = deferredWarningCollector\n    }\n    \n    func dump(logger: ILogger, error: Error) {\n        // NOTE:\n        // We are parsing these error messages in our pybuild scripts.\n        // If you change how these error messages are formatted, that might\n        // require a change in client/snapci/...\n        logger.error(\"=== Start error output ===\")\n        \n        deferredWarningCollector.collectAndPrintAllWarnings()\n        \n        logger.error(\"🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑\")\n        logger.error(\"🛑                                     🛑\")\n        logger.error(\"🛑            Printing errors:         🛑\")\n        logger.error(\"🛑                                     🛑\")\n        logger.error(\"🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑\")\n        \n        if let compilationPipelineError = error as? CompilationPipelineError {\n            let processor = compilationPipelineError.processor\n            \n            switch compilationPipelineError.kind {\n            case .unitemizedError(let error):\n                logger.error(\"Got an error during phase '\\(processor.description)': \\(error.legibleLocalizedDescription)\")\n            case .itemizedErrors(let errorItems):\n                logger.error(\"Got \\(errorItems.count) \\(errorItems.count == 1 ? \"error\" : \"errors\") during phase '\\(processor.description)':\")\n                for (item, error) in errorItems {\n                    let location = item.relativeProjectPath\n                    logger.error(\"-- \\(location): \\(error.legibleLocalizedDescription)\")\n                }\n            }\n        } else {\n            logger.error(\"Caught global error: \\(error.legibleLocalizedDescription)\")\n        }\n        \n        logger.error(\"========================\")\n        logger.error(\"=== End error output ===\")\n        \n    }\n}\n\nstruct CompilationPipelineError: Error {\n    enum Kind {\n        case unitemizedError(Error)\n        case itemizedErrors([(item: CompilationItem, error: Error)])\n    }\n    \n    let processor: CompilationProcessor\n    let kind: Kind\n    \n    init(processor: CompilationProcessor, unitemizedError: Error) {\n        self.processor = processor\n        self.kind = .unitemizedError(unitemizedError)\n    }\n    \n    init(processor: CompilationProcessor, itemizedErrors: [(item: CompilationItem, error: Error)]) {\n        self.processor = processor\n        self.kind = .itemizedErrors(itemizedErrors)\n    }\n}\n\nclass CompilationPipeline {\n    \n    struct Result {\n        let warnings: [DeferredWarning]\n        let failedItems: [URL: CompilationItem]\n    }\n    \n    private let logger: ILogger\n    private let processors: [CompilationProcessor]\n    private let deferredWarningCollector: DeferredWarningCollector\n    private let failImmediatelyOnError: Bool\n    private var onTeardownCallbacks = [() -> Void]()\n\n    init(logger: ILogger, processors: [CompilationProcessor], deferredWarningCollector: DeferredWarningCollector, failImmediatelyOnError: Bool) {\n        self.logger = logger\n        self.processors = processors\n        self.deferredWarningCollector = deferredWarningCollector\n        self.failImmediatelyOnError = failImmediatelyOnError\n    }\n\n    deinit {\n        self.onTeardownCallbacks.forEach { cb in\n            cb()\n        }\n    }\n\n    func onTeardown(_ onTeardownCallback: @escaping () -> Void) {\n        self.onTeardownCallbacks.append(onTeardownCallback)\n    }\n\n    func process(items: CompilationItems) throws -> Result {\n        let mainTransaction = SentryClient.startTransaction(name: \"Process\", operation: \"Running all configured processors\")\n        \n        do {\n            deferredWarningCollector.compilationPassStarted()\n            defer {\n                deferredWarningCollector.compilationPassFinished()\n            }\n            \n            var currentItems = items\n            \n            var failedItems = [URL: CompilationItem]()\n            var deferredWarnings = [DeferredWarning]()\n            \n            var timerResults = [String]()\n            \n            let startTime = AbsoluteTime.current\n                    \n            for processor in processors {\n                let time = AbsoluteTime.current\n                logger.info(\"\\(processor.description)\")\n                \n                let childTransaction = SentryClient.startChild(parent: mainTransaction, operation: String(describing: type(of: processor)), description: processor.description)\n                \n                do {\n                    currentItems = try processor.process(items: currentItems)\n                } catch {\n                    SentryClient.finish(transaction: childTransaction)\n                    throw CompilationPipelineError(processor: processor, unitemizedError: error)\n                }\n                \n                let errorItems = currentItems.allItems.compactMap { item -> (item: CompilationItem, error: Error)? in\n                    if case .error(let error, _) = item.kind {\n                        return (item, error)\n                    } else {\n                        return nil\n                    }\n                }.sorted { (lhs, rhs) -> Bool in\n                    return lhs.item.relativeProjectPath < rhs.item.relativeProjectPath\n                }\n                \n                if errorItems.count > 0 {\n                    if failImmediatelyOnError {\n                        throw CompilationPipelineError(processor: processor, itemizedErrors: errorItems)\n                    } else {\n                        for (item, _) in errorItems {\n                            failedItems[item.sourceURL] = item\n                        }\n                    }\n                }\n                \n                deferredWarnings.append(contentsOf: deferredWarningCollector.collectWarnings())\n                \n                SentryClient.finish(transaction: childTransaction)\n                timerResults.append(\"-- \\(processor.description): \\(time.timeElapsed.milliseconds)ms\")\n            }\n            \n            SentryClient.finish(transaction: mainTransaction)\n            logger.info(\"\"\"\n                Compilation took \\(startTime.timeElapsed.milliseconds)ms\n                \\(timerResults.joined(separator: \"\\n\"))\n                \"\"\")\n            \n            return Result(warnings: deferredWarnings, failedItems: failedItems)\n        } catch {\n            SentryClient.finish(transaction: mainTransaction)\n            throw error\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/CompilationProcessor.swift",
    "content": "//\n//  CompilationProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprotocol CompilationProcessor: CustomStringConvertible {\n\n    func process(items: CompilationItems) throws -> CompilationItems\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/CompilationSequence.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 9/28/20.\n//\n\nimport Foundation\n\nstruct CompilationSequence: Equatable {\n    let id: Int\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/DeferredWarningCollector.swift",
    "content": "import Foundation\n\nstruct DeferredWarning {\n    let tag: String\n    let message: String\n}\n\nfinal class DeferredWarningCollector {\n    private let reportedWarnings = Synchronized<[DeferredWarning]>(data: [])\n\n    private var shouldDefer = false\n    private let logger: ILogger\n\n    init(logger: ILogger) {\n        self.logger = logger\n    }\n\n    func compilationPassStarted() {\n        shouldDefer = true\n    }\n\n    func compilationPassFinished() {\n        shouldDefer = false\n    }\n\n    func reportWarning(_ warning: DeferredWarning) {\n        if shouldDefer {\n            self.reportedWarnings.data { $0.append(warning) }\n        } else {\n            logger.error(\"⚠️  Warning: \\(warning.tag): \\(warning.message)\")\n        }\n    }\n\n    func collectWarnings() -> [DeferredWarning] {\n        let events: [DeferredWarning] = self.reportedWarnings.data { data in\n            let copy = data\n            data.removeAll()\n            return copy\n        }\n        return events\n    }\n\n    func collectAndPrintAllWarnings() {\n        let deferredWarnings = collectWarnings()\n        guard deferredWarnings.count > 0 else { return }\n\n        logger.error(\"⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️\")\n        logger.error(\"⚠️                                     ⚠️\")\n        logger.error(\"⚠️           Printing warnings:        ⚠️\")\n        logger.error(\"⚠️                                     ⚠️\")\n        logger.error(\"⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️\")\n        deferredWarnings.forEach {\n            logger.error(\"-- \\($0.tag): \\($0.message)\")\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/JSConstants.swift",
    "content": "//\n//  JSConstants.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/29/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct JSConstants {\n    static let outVariable = \"elementById\"\n    static let shouldRenderSuffix = \"shouldRender\"\n    static let contexts = \"contexts\"\n\n    static let valdiViewClassName = \"View\"\n\n    static let autoImportedComponentIdentifier = \"LegacyVueComponent\"\n    static let autoImportedRuntimeIdentifier = \"Runtime\"\n    static let autoImportedActionsIdentifier = \"Actions\"\n    static let autoImportedElementsIdentifier = \"Elements\"\n    static let autoImportedAttributesIdentifier = \"Attributes\"\n    static let autoImportedElementIdentifier = \"Element\"\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Pipeline/ModulesFilter.swift",
    "content": "//\n//  ModulesFilter.swift\n//  \n//\n//  Created by Simon Corsin on 6/26/20.\n//\n\nimport Foundation\n\nstruct ModulesFilter {\n\n    private let modulesAndDeps: [CompilationItem.BundleInfo]\n    private let modulesFilter: [String]\n    private let ignoreModuleDeps: Bool\n\n    init(bundleManager: BundleManager, modulesFilter: [String], ignoreModuleDeps: Bool) throws {\n        var modules = [CompilationItem.BundleInfo]()\n        modules.append(bundleManager.rootBundle)\n\n        for modulePath in modulesFilter {\n            let module = try bundleManager.getBundleInfo(forName: modulePath)\n\n            let dependencies = module.allDependencies.filter { !modules.contains($0) }\n\n            modules.append(module)\n            modules += dependencies\n        }\n\n        self.modulesAndDeps = modules\n        self.modulesFilter = modulesFilter\n        self.ignoreModuleDeps = ignoreModuleDeps\n    }\n\n    func shouldIncludeInInput(bundleInfo: CompilationItem.BundleInfo) -> Bool {\n        return modulesAndDeps.contains(bundleInfo)\n    }\n\n    func shouldIncludeInOutput(bundleInfo: CompilationItem.BundleInfo) -> Bool {\n        if ignoreModuleDeps {\n            return modulesFilter.contains(bundleInfo.name)\n        } else {\n            return true\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/ApplyTypeScriptAnnotationsProcessor.swift",
    "content": "//\n//  ApplyTypeScriptAnnotationsProcessor.swift\n//  Compiler\n//\n//  Created by saniul on 13/06/2019.\n//\n\nimport Foundation\n\nfinal class ApplyTypeScriptAnnotationsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Processing TypeScript Annotations\"\n    }\n\n    private let logger: ILogger\n    private let typeScriptCompilerManager: TypeScriptCompilerManager\n    private let typeScriptAnnotationsManager: TypeScriptAnnotationsManager\n    private let nativeCodeGenerationManager: NativeCodeGenerationManager\n\n    init(logger: ILogger, typeScriptCompilerManager: TypeScriptCompilerManager, typeScriptAnnotationsManager: TypeScriptAnnotationsManager, nativeCodeGenerationManager: NativeCodeGenerationManager) {\n        self.logger = logger\n        self.typeScriptCompilerManager = typeScriptCompilerManager\n        self.typeScriptAnnotationsManager = typeScriptAnnotationsManager\n        self.nativeCodeGenerationManager = nativeCodeGenerationManager\n    }\n\n    func extractErrors(items: [CompilationItem]) -> [URL: Error] {\n        return items.compactMap { (item) -> (CompilationItem, Error)? in\n            if case .error(let error, _) = item.kind {\n                return (item, error)\n            }\n            return nil\n            }.associate { (item, error) -> (URL, Error) in\n                return (item.sourceURL, error)\n        }\n    }\n\n    private func hasComponentAnnotation(parsedAnnotation: ParsedAnnotation) -> Bool {\n        for annotation in parsedAnnotation.symbol.annotations {\n            if let annotationType = ValdiAnnotationType(rawValue: annotation.name), annotationType == .component {\n                return true\n            }\n        }\n        return false\n    }\n\n    private func processAnnotations(items: [CompilationItem]) -> [CompilationItem] {\n        let out = DocumentsIndexer(items: items)\n\n        nativeCodeGenerationManager.clear()\n\n        let allAnnotations = typeScriptAnnotationsManager.listAllAnnotations()\n        for (sourceURL, parsedAnnotation) in allAnnotations {\n            let commentedFile = parsedAnnotation.file\n            let linesIndexer = commentedFile.linesIndexer\n            let annotatedSymbol = parsedAnnotation.symbol\n            let symbol = annotatedSymbol.symbol\n            let annotation = parsedAnnotation.annotation\n            let compilationItem = parsedAnnotation.compilationItem\n\n            var documentAndIndex = out.findDocument(fromSourceURL: sourceURL)\n\n            let isTSorTSX = !sourceURL.path.hasSuffix(\".vue.ts\")\n                && !sourceURL.path.hasSuffix(\".vue.tsx\")\n                && (sourceURL.path.hasSuffix(\".ts\") || sourceURL.path.hasSuffix(\".tsx\"))\n\n            do {\n                switch parsedAnnotation.type {\n                case .exportModule:\n                    try nativeCodeGenerationManager.addNativeModuleToGenerate(commentedFile: commentedFile, annotation: annotation, sourceURL: sourceURL, annotatedSymbol: annotatedSymbol, compilationItem: compilationItem, linesIndexer: linesIndexer)\n                case .exportModel, .generateNativeClass:\n                    let isComponent = hasComponentAnnotation(parsedAnnotation: parsedAnnotation)\n                    try nativeCodeGenerationManager.addNativeTypeToGenerate(commentedFile: commentedFile, annotation: annotation, sourceURL: sourceURL, annotatedSymbol: annotatedSymbol, compilationItem: compilationItem, linesIndexer: linesIndexer, kind: .class, isComponent: isComponent)\n                case .exportProxy, .generateNativeInterface:\n                    try nativeCodeGenerationManager.addNativeTypeToGenerate(commentedFile: commentedFile, annotation: annotation, sourceURL: sourceURL, annotatedSymbol: annotatedSymbol, compilationItem: compilationItem, linesIndexer: linesIndexer, kind: .interface, isComponent: false)\n                case .exportEnum, .generativeNativeEnum:\n                    guard let dumpedEnum = symbol.enum else {\n                        try throwAnnotationError(annotation, commentedFile, message: \"[Shouldn't happen] Processing a @GenerateNativeEnum annotation, but there is no enum information\")\n                    }\n\n                    let members = dumpedEnum.members\n                    let stringMembers = members.filter { $0.stringValue != nil }\n\n                    let anyContainQuotes = !stringMembers.isEmpty\n                    let allContainQuotes = stringMembers.count == members.count\n\n                    if anyContainQuotes != allContainQuotes {\n                        try throwAnnotationError(annotation, commentedFile, message: \"Invalid enum '\\(symbol.text)' - Can't mix String and Int cases\")\n                    }\n\n                    let kind: NativeTypeKind = anyContainQuotes ? .stringEnum : .enum\n\n                    // TODO: Support non-generated enums\n                    try nativeCodeGenerationManager.addNativeTypeToGenerate(commentedFile: commentedFile, annotation: annotation, sourceURL: sourceURL, annotatedSymbol: annotatedSymbol, compilationItem: compilationItem, linesIndexer: linesIndexer, kind: kind, isComponent: false)\n                case .exportFunction, .generativeNativeFunction:\n                    try nativeCodeGenerationManager.addNativeFuncToGenerate(commentedFile: commentedFile, annotation: annotation, sourceURL: sourceURL, annotatedSymbol: annotatedSymbol, compilationItem: compilationItem, linesIndexer: linesIndexer)\n                case .nativeTypeConverter:\n                    try nativeCodeGenerationManager.addNativeTypeConverter(commentedFile: commentedFile, annotation: annotation, sourceURL: sourceURL, annotatedSymbol: annotatedSymbol, compilationItem: compilationItem, linesIndexer: linesIndexer)\n                case .nativeClass:\n                    try nativeCodeGenerationManager.registerNativeClass(commentedFile: commentedFile, annotation: annotation, symbol: symbol, shouldGenerateIOS: compilationItem.shouldOutputToIOS, shouldGenerateAndroid: compilationItem.shouldOutputToAndroid, kind: .class, bundleInfo: compilationItem.bundleInfo, isGenerated: false)\n                case .nativeInterface:\n                    try nativeCodeGenerationManager.registerNativeClass(commentedFile: commentedFile, annotation: annotation, symbol: symbol, shouldGenerateIOS: compilationItem.shouldOutputToIOS, shouldGenerateAndroid: compilationItem.shouldOutputToAndroid, kind: .interface, bundleInfo: compilationItem.bundleInfo, isGenerated: false)\n                case .component:\n                    if isTSorTSX {\n                        guard let symbolName = symbol.text.nonEmpty else {\n                            try throwAnnotationError(annotation, commentedFile, message: \"Couldn't get the JS symbol name for @Component\")\n                        }\n                        // Hacking support for @Component in .tsx files\n                        var docAndIndex = out.findOrCreateDocument(fromSourceURL: sourceURL, compilationItem: compilationItem)\n                        let fileName = (compilationItem.relativeProjectPath as NSString).deletingPathExtension\n                        docAndIndex.compilationResult.componentPath = ComponentPath(fileName: fileName, exportedMember: symbolName)\n                        documentAndIndex = docAndIndex\n                    } else {\n                        guard documentAndIndex != nil else {\n                            try throwAnnotationError(annotation, commentedFile, message: \"@Component must be set in a .vue, .ts, or .tsx file\")\n                        }\n                    }\n                    try processComponent(sourceURL: sourceURL, commentedFile: commentedFile, annotation: annotation, symbol: symbol, document: &documentAndIndex!.compilationResult.originalDocument)\n                case .action:\n                    if isTSorTSX {\n                        documentAndIndex = out.findOrCreateDocument(fromSourceURL: sourceURL, compilationItem: compilationItem)\n                    } else {\n                        guard documentAndIndex != nil else {\n                            try throwAnnotationError(annotation, commentedFile, message: \"@Action must be set in a .vue, .ts, or .tsx file\")\n                        }\n                    }\n                    guard let interface = symbol.interface else {\n                        try throwAnnotationError(annotation, commentedFile, message: \"@Action must be set on a class member function\")\n                    }\n                    guard let memberIndex = parsedAnnotation.memberIndex, let actionProperty = interface.members[safe: memberIndex] else {\n                        try throwAnnotationError(annotation, commentedFile, message: \"Couldn't find the method member for the @Action annotation\")\n                    }\n\n                    try processAction(commentedFile: commentedFile, annotation: annotation, actionDeclaration: actionProperty, actions: &documentAndIndex!.compilationResult.templateResult.actions)\n                case .viewModel:\n                    guard isTSorTSX || documentAndIndex != nil else {\n                        try throwAnnotationError(annotation, commentedFile, message: \"@ViewModel must be set in a .vue, .ts, or .tsx file\")\n                    }\n                    guard symbol.kind == TS.SyntaxKind.interfaceDeclaration else {\n                        try throwAnnotationError(annotation, commentedFile, message: \"@ViewModel must be on a TypeScript interface\")\n                    }\n                    if nativeCodeGenerationManager.hasViewModelSymbol(for: sourceURL) {\n                        try throwAnnotationError(annotation, commentedFile, message: \"@ViewModel can only be placed once per file\")\n                    }\n\n                    nativeCodeGenerationManager.addViewModelSymbol(sourceURL: sourceURL, symbol: symbol.text)\n                case .context:\n                    guard isTSorTSX || documentAndIndex != nil else {\n                        try throwAnnotationError(annotation, commentedFile, message: \"@Context must be set in a .vue, .ts, or .tsx file\")\n                    }\n                    guard symbol.kind == TS.SyntaxKind.interfaceDeclaration else {\n                        try throwAnnotationError(annotation, commentedFile, message: \"@Context must be on a TypeScript interface\")\n                    }\n                    if nativeCodeGenerationManager.hasContextSymbol(for: sourceURL) {\n                        try throwAnnotationError(annotation, commentedFile, message: \"@Context can only be placed once per vue file\")\n                    }\n\n                    nativeCodeGenerationManager.addContextSymbol(sourceURL: sourceURL, symbol: symbol.text)\n                case .constructorOmitted:\n                    // ConstructorOmitted annotations get processed as part of @GenerateNativeClass\n                    break\n                case .nativeTemplateElement:\n                    // @NativeTemplateElement is handled when parsing annotations\n                    break\n                case .injectable:\n                    // Injectable annotations get processed as part of @GenerateNativeClass\n                    break\n                case .singleCall:\n                    // SingleCall annotations get processed inside TypeScriptNativeTypeExporter\n                    break\n                case .workerThread:\n                    // WorkerThread annotations get processed inside TypeScriptNativeTypeExporter\n                    break\n                case .untyped:\n                    // Untyped annotations get processed inside TypeScriptNativeTypeExporter\n                    break\n                case .untypedMap:\n                    // UntypedMap annotations get processed inside TypeScriptNativeTypeExporter\n                    break\n                }\n\n                // Replace the CompilationItem with possibly-updated document\n                if let documentAndIndexUnwrapped = documentAndIndex {\n                    out.replace(atIndex: documentAndIndexUnwrapped.itemIndex) { item in\n                        return item.with(newKind: .document(documentAndIndexUnwrapped.compilationResult))\n                    }\n                }\n            } catch let error {\n                logger.info(\"Error processing annotations: \\(error.legibleLocalizedDescription)\")\n                out.injectError(logger: logger, error, relatedItem: compilationItem)\n            }\n        }\n\n        let allDumped: [(TypeScriptItem, TS.DumpSymbolsWithCommentsResponseBody)] = out.allItems.compactMap { item in\n            if case let .dumpedTypeScriptSymbols(result) = item.kind {\n                return (result.typeScriptItemAndSymbols.typeScriptItem, result.typeScriptItemAndSymbols.dumpedSymbols)\n            } else {\n                return nil\n            }\n        }\n        let dumpedSymbolsGroupedBySourceURL = Dictionary(grouping: allDumped, by: { record in record.0.src.sourceURL })\n\n        for (sourceURL, group) in dumpedSymbolsGroupedBySourceURL {\n            let documentAndIndexMaybe = out.findDocument(fromSourceURL: sourceURL)\n\n            guard var documentAndIndex = documentAndIndexMaybe else {\n                continue\n            }\n\n            let allSymbolsInGroup = group.flatMap { $0.1.dumpedSymbols }\n\n            for dumpedSymbol in allSymbolsInGroup {\n                if dumpedSymbol.modifiers?.contains(\"export\") == true {\n                    let isDefault = dumpedSymbol.modifiers?.contains(\"default\") == true\n                    let symbol = TypeScriptSymbol(symbol: dumpedSymbol.text, isDefault: isDefault)\n                    documentAndIndex.compilationResult.symbolsToImportsInGeneratedCode.append(symbol)\n                }\n            }\n\n            if let tsClassName = documentAndIndex.compilationResult.originalDocument.template?.jsComponentClass,\n                !documentAndIndex.compilationResult.symbolsToImportsInGeneratedCode.contains(where: { $0.symbol == tsClassName }) {\n                out.injectError(logger: logger, CompilerError(\"Custom component class '\\(tsClassName)' should be exported using the 'export' keyword\"), relatedItem: group.first!.0.item)\n            } else {\n                out.replace(atIndex: documentAndIndex.itemIndex) { item in\n                    return item.with(newKind: .document(documentAndIndex.compilationResult))\n                }\n            }\n        }\n\n        nativeCodeGenerationManager.createCompilationItems(existingItems: out)\n\n        return out.allItems\n    }\n\n    private func processComponent(sourceURL: URL, commentedFile: TypeScriptCommentedFile, annotation: ValdiTypeScriptAnnotation, symbol: TS.DumpedSymbolWithComments, document: inout ValdiRawDocument) throws {\n        guard symbol.kind == TS.SyntaxKind.classDeclaration else {\n            try throwAnnotationError(annotation, commentedFile, message: \"@Component must be set on a class\")\n        }\n        let kindModifiers = (symbol.kindModifiers ?? \"\").split(separator: \" \")\n\n        guard kindModifiers.contains(\"export\") else {\n            try throwAnnotationError(annotation, commentedFile, message: \"@Component must be set on a class that is exported\")\n        }\n\n        document.template?.jsComponentClass = symbol.text\n    }\n\n    private func processAction(commentedFile: TypeScriptCommentedFile, annotation: ValdiTypeScriptAnnotation, actionDeclaration: TS.AST.PropertyLikeDeclaration, actions: inout [ValdiAction]) throws {\n        let action = ValdiAction(name: actionDeclaration.name, type: .javaScript)\n        if !actions.contains(action) {\n            actions.append(action)\n        }\n    }\n\n    private func generateTs(_ selectedItem: SelectedItem<CompilationResult>, typeScriptErrorBySourceURL: [URL: Error]) -> [CompilationItem] {\n        if let userScriptSourceURL = selectedItem.data.userScriptSourceURL, let error = typeScriptErrorBySourceURL[userScriptSourceURL] {\n            return [selectedItem.item.with(error: error)]\n        }\n\n        let result = selectedItem.data\n        let cssModulePath = \"\\(selectedItem.item.relativeProjectPath).\\(FileExtensions.valdiCss)\"\n\n        let tsGenerator = TypeScriptGenerator(logger: logger,\n                                              customComponentClass: result.originalDocument.template?.jsComponentClass,\n                                              elements: result.templateResult.rootElement,\n                                              actions: result.templateResult.actions,\n                                              useLegacyActions: false,\n                                              hasUserScript: selectedItem.data.userScriptSourceURL != nil,\n                                              sourceURL: selectedItem.item.sourceURL,\n                                              symbolsToImport: result.symbolsToImportsInGeneratedCode,\n                                              emitDebug: typeScriptCompilerManager.emitDebug,\n                                              cssModulePath: cssModulePath)\n\n        do {\n            var out = [CompilationItem]()\n\n            if let tsResult = try tsGenerator.generate() {\n                guard let tsData = tsResult.typeScript.data(using: .utf8) else {\n                    throw CompilerError(\"Failed to convert TS to data\")\n                }\n\n                let sourceURL = TypeScriptCompilerManager.generatedUrl(url: selectedItem.item.sourceURL.appendingPathExtension(FileExtensions.typescript))\n                logger.debug(\"Creating generated TypeScript file \\(sourceURL.path)\")\n                out.append(CompilationItem(sourceURL: sourceURL, relativeProjectPath: nil, kind: .typeScript(.data(tsData), sourceURL), bundleInfo: selectedItem.item.bundleInfo, platform: selectedItem.item.platform, outputTarget: selectedItem.item.outputTarget))\n            }\n\n            out.append(selectedItem.item.with(newKind: .document(result)))\n\n            return out\n        } catch let error {\n            return [selectedItem.item.with(error: error)]\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        // process the previously-parsed file annotations\n        let outItems = processAnnotations(items: items.allItems)\n        let failedFiles = extractErrors(items: outItems)\n\n        // generate the TS files from the CompilationResult's\n        let selectedItems = CompilationItems(compileSequence: items.compileSequence, items: outItems)\n            .select { (item) -> CompilationResult? in\n                if case .document(let result) = item.kind, result.scriptLang == FileExtensions.typescript {\n                    return result\n                }\n                return nil\n        }\n        let newItems = selectedItems.transformEachConcurrently { (selectedItem: SelectedItem<CompilationResult>) -> [CompilationItem] in\n            return generateTs(selectedItem, typeScriptErrorBySourceURL: failedFiles)\n        }\n\n        return CompilationItems(compileSequence: items.compileSequence, items: newItems.allItems)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/BundleResourcesProcessor.swift",
    "content": "//\n//  BundleAssetsProcessor.swift\n//  Compiler\n//\n//  Created by Brandon Francis on 7/25/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.finalFile] -> [.finalFile]\nclass BundleResourcesProcessor: CompilationProcessor {\n\n    enum OutputMode {\n        /**\n         Package sources and assets and upload them to the\n         moduleUploadBaseURL endpoint set in the config\n         */\n        case uploadedArtifacts\n        /**\n         Package assets in an assetpackage format, sources\n         are left untouched.\n         */\n        case assetPackage\n\n        /**\n         Package sources and assets into .valdimodule\n         */\n        case bundledAssetPackage\n    }\n\n    enum DownloadableArtifactsProcessingMode {\n        /**\n         Build modules and verify that the signatures found on-disk match.\n         Will fail compilations if a matching signature can't be found, since this\n         means that the developer has made a change that hasn't been uploaded to\n         the Bolt proxy.\n         Normally used when the Valdi compiler is driven with Bazel.\n         */\n        case verifySignatures\n        /**\n         Build modules, ensure they have already been uploaded to Bolt,\n         generate signature files and write them to disk.\n         */\n        case uploadIfNeeded\n    }\n\n    private struct ModuleAndPlatform: Hashable {\n        let moduleInfo: CompilationItem.BundleInfo\n        let platform: Platform\n    }\n\n    private struct DownloadableAssetsArtifact {\n        let deviceDensity: Double\n        let files: [SelectedItem<FinalFile>]\n    }\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n    private let compilerConfig: CompilerConfig\n    private let outputMode: BundleResourcesProcessor.OutputMode\n    private let downloadableArtifactsProcessingMode: DownloadableArtifactsProcessingMode\n    private let artifactUploader: ArtifactUploader?\n    private let diskCache: DiskCache?\n    private let downloadableArtifactCache: DiskCache?\n    private let rootBundle: CompilationItem.BundleInfo\n    private let companionExecutable: CompanionExecutable\n    private let writeDownloadableArtifactsManifest: Bool\n    private var pendingPreparedArtifact = Synchronized(data: [String: File]())\n\n    init(logger: ILogger, \n         fileManager: ValdiFileManager,\n         diskCacheProvider: DiskCacheProvider,\n         projectConfig: ValdiProjectConfig,\n         compilerConfig: CompilerConfig,\n         maxUploadConcurrentRequests: Int,\n         outputMode: OutputMode,\n         downloadableArtifactsProcessingMode: DownloadableArtifactsProcessingMode,\n         writeDownloadableArtifactsManifest: Bool,\n         rootBundle: CompilationItem.BundleInfo,\n         companionExecutable: CompanionExecutable) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.compilerConfig = compilerConfig\n        self.outputMode = outputMode\n        self.downloadableArtifactsProcessingMode = downloadableArtifactsProcessingMode\n        self.writeDownloadableArtifactsManifest = writeDownloadableArtifactsManifest\n        self.rootBundle = rootBundle\n        self.companionExecutable = companionExecutable\n\n        if let moduleUploadBaseURL = projectConfig.moduleUploadBaseURL {\n            artifactUploader = ArtifactUploader(moduleBaseUploadURL: moduleUploadBaseURL,\n                                                companionExecutable: companionExecutable)\n        } else {\n            artifactUploader = nil\n        }\n\n        self.diskCache = diskCacheProvider.newCache(cacheName: \"modules_build\",\n                                   outputExtension: FileExtensions.valdiModule,\n                                   metadata: [:])\n\n        self.downloadableArtifactCache = diskCacheProvider.newCache(cacheName: \"downloadable_artifacts\", outputExtension: \"bin\", metadata: [:])\n    }\n\n    var description: String {\n        return \"Bundling resources\"\n    }\n\n    private func getZipItem(forItem item: CompilationItem, finalFile: FinalFile) -> ZippableItem {\n        let itemPath: String\n        if item.relativeBundleURL.pathComponents.count > 1 {\n            // Use the filename from the output url, appended to the relative source url\n            itemPath = item.relativeBundleURL.deletingLastPathComponent().appendingPathComponent(finalFile.outputURL.lastPathComponent).path\n        } else {\n            itemPath = finalFile.outputURL.lastPathComponent\n        }\n\n        return ZippableItem(file: finalFile.file, path: itemPath)\n    }\n\n    /**\n     * Bundles the files in the .valdimodule format.\n     *\n     * Parameters:\n     * - moduleName: Only used for caching/logging. The name of the module.\n     * - zippableItems/finalFiles: The items (file + path) to be bundled.\n     * - platform: Only used for caching. Platform (android/ios).\n     * - target: Only used for caching. Build target (debug/release).\n     *\n     * Returns:\n     * - The .valdimodule file contents as Data().\n     */\n    private func buildModule(moduleName: String, finalFiles: [SelectedItem<FinalFile>], platform: Platform, target: OutputTarget) throws -> Data {\n        let zippableItems = finalFiles.map { getZipItem(forItem: $0.item, finalFile: $0.data) }\n        return try buildModule(moduleName: moduleName, zippableItems: zippableItems, platform: platform, target: target)\n    }\n\n    private func buildModule(moduleName: String, zippableItems: [ZippableItem], platform: Platform, target: OutputTarget) throws -> Data {\n        do {\n            let moduleBuilder = ValdiModuleBuilder(items: zippableItems)\n            moduleBuilder.compress = false\n\n            let data = try moduleBuilder.build()\n\n            let cacheKey = getCacheKey(moduleName)\n\n            if let cachedCompressed = diskCache?.getOutput(item: cacheKey, platform: platform, target: target, inputData: data) {\n                return cachedCompressed\n            }\n\n            let compressedData = try ValdiModuleBuilder.compress(data: data)\n            try diskCache?.setOutput(item: cacheKey, platform: platform, target: target, inputData: data, outputData: compressedData)\n\n            return compressedData\n        } catch let error {\n            let errorMessage = \"Failed to create valdi module '\\(moduleName)': \\(error.legibleLocalizedDescription)\"\n            logger.error(errorMessage)\n            throw CompilerError(errorMessage)\n        }\n    }\n\n    private func makeItem(forValdiModuleData moduleData: Data, moduleInfo: CompilationItem.BundleInfo, platform: Platform, target: OutputTarget, outputDirectories: OutDirectories) -> CompilationItem {\n        let fileName = moduleInfo.name\n\n        let outputDirectoryURL: URL = outputDirectories.assetsURL\n\n        let outputURL = outputDirectoryURL.appendingPathComponent(\"\\(fileName).\\(FileExtensions.valdiModule)\", isDirectory: false)\n        let finalFile = FinalFile(outputURL: outputURL, file: .data(moduleData), platform: platform, kind: .unknown)\n\n        // Source url doesn't matter here, just give it something\n        return CompilationItem(sourceURL: moduleInfo.baseDir, relativeProjectPath: nil, kind: .finalFile(finalFile), bundleInfo: moduleInfo, platform: platform, outputTarget: target)\n    }\n\n    struct ResolveFilesResult {\n        let sources: [SelectedItem<FinalFile>]\n        let assets: [SelectedItem<FinalFile>]\n        // Items that should not be explicitly handled, they should be just saved\n        // on disk.\n        let passthroughItems: [SelectedItem<FinalFile>]\n    }\n\n    private func resolveFiles(items: [SelectedItem<FinalFile>]) -> ResolveFilesResult {\n        var sources = [SelectedItem<FinalFile>]()\n        var assets = [SelectedItem<FinalFile>]()\n        var passthroughItems = [SelectedItem<FinalFile>]()\n\n        for item in items {\n            if item.data.platform == .web {\n                passthroughItems.append(item)\n            }\n            switch item.data.kind {\n            case .image:\n                assets.append(item)\n            case .compiledSource:\n                sources.append(item)\n            case .unknown, .nativeSource, .assetsPackage, .dependencyInjectionData:\n                // Append if it wasn't already added\n                if item.data.platform != .web {\n                    passthroughItems.append(item)\n                }\n            }\n        }\n\n        return ResolveFilesResult(sources: sources, assets: assets, passthroughItems: passthroughItems)\n    }\n\n    private func getCacheKey(_ artifactName: String) -> String {\n        return artifactName + \".valdiarchive\"\n    }\n\n    private func getDownloadableModuleArtifactFromCache(artifactName: String, moduleData: Data) -> Valdi_DownloadableModuleArtifact? {\n        guard let outputData = downloadableArtifactCache?.getOutput(item: getCacheKey(artifactName), inputData: moduleData) else {\n            return nil\n        }\n        return try? Valdi_DownloadableModuleArtifact(serializedData: outputData)\n    }\n\n    private func expectedSignatureFileURL(moduleInfo: CompilationItem.BundleInfo, platform: Platform) -> URL {\n        let expectedSignatureFileURL = moduleInfo.baseDir.appendingPathComponent(platform.rawValue)\n            .appendingPathExtension(FileExtensions.downloadableArtifacts)\n\n        return expectedSignatureFileURL\n    }\n    \n    private func buildAndUpload(moduleInfo: CompilationItem.BundleInfo, artifactUploader: ArtifactUploader, artifactName: String, moduleData: Data, sha256Digest: String, downloadableArtifactSignatures: Valdi_DownloadableModuleArtifactSignatures) -> Promise<Valdi_DownloadableModuleArtifact> {\n        do {\n            guard let foundSignature = downloadableArtifactSignatures.artifacts.first(where: { $0.sha256Digest == Data(hexString: sha256Digest) }) else {\n                throw CompilerError(\"Downloadable artifact signature for '\\(artifactName)' not found.\")\n            }\n            return Promise(data: foundSignature)\n        } catch {\n            let errorMessage = \"Failed to verify that downloadable module \\(artifactName) has already been uploaded (sha256: \\(sha256Digest)). Underlying error: \\(error.legibleLocalizedDescription)\"\n            switch downloadableArtifactsProcessingMode {\n            case .verifySignatures:\n                logger.error(errorMessage)\n                return Promise(error: CompilerError(errorMessage))\n            case .uploadIfNeeded:\n                // continue execution to create the artifact and upload it\n                break\n            }\n        }\n        let logger = self.logger\n        let maxAttempts = 3\n        var attempt = 0\n        var retryDelay = 500.0\n        let startTime = Date()\n        let requestId = String(UUID().uuidString.prefix(8))\n        while (true) {\n            let promise = uploadArtifact(artifactUploader: artifactUploader, artifactName: artifactName, moduleData: moduleData, sha256Digest: sha256Digest)\n            let result = promise.waitForResult()\n            \n            switch result {\n            case .success(let artifact):\n                return Promise(data: artifact)\n            case .failure(let error):\n                let elapsedTime = Date().timeIntervalSince(startTime)\n                \n                logger.warn(\"[\\(requestId)] buildAndUpload attempt \\(attempt + 1)/\\(maxAttempts) failed for '\\(artifactName)'\")\n                logger.warn(\"[\\(requestId)]   Module: \\(moduleInfo.name)\")\n                logger.warn(\"[\\(requestId)]   Artifact size: \\(moduleData.count) bytes\")\n                logger.warn(\"[\\(requestId)]   SHA256: \\(sha256Digest)\")\n                logger.warn(\"[\\(requestId)]   Error: \\(error.legibleLocalizedDescription)\")\n                logger.warn(\"[\\(requestId)]   Error type: \\(type(of: error))\")\n                logger.warn(\"[\\(requestId)]   Time since start: \\(String(format: \"%.2f\", elapsedTime))s\")\n                \n                if ((attempt + 1) >= maxAttempts) {\n                    logger.error(\"[\\(requestId)] buildAndUpload exhausted all \\(maxAttempts) attempts for '\\(artifactName)' after \\(String(format: \"%.2f\", elapsedTime))s\")\n                    return Promise(error: error)\n                }\n\n                logger.info(\"[\\(requestId)] buildAndUpload waiting \\(retryDelay)ms before retry \\(attempt + 2)\")\n                Thread.sleep(forTimeInterval: (retryDelay / 1000.0))\n                retryDelay *= 2\n                attempt += 1\n            }\n        }\n    }\n\n    private func uploadArtifact(artifactUploader: ArtifactUploader, artifactName: String, moduleData: Data, sha256Digest: String) -> Promise<Valdi_DownloadableModuleArtifact> {\n        let artifactInfoPromise: Promise<ArtifactInfo>\n        if let _ = self.projectConfig.preparedUploadArtifactOutput {\n            artifactInfoPromise = artifactUploader.appendToPreparedArtifact(artifactName: artifactName, artifactData: moduleData, sha256: sha256Digest)\n        } else {\n            artifactInfoPromise = artifactUploader.upload(artifactName: artifactName, artifactData: moduleData, sha256: sha256Digest)\n        }\n        let promise: Promise<Valdi_DownloadableModuleArtifact> = artifactInfoPromise.then { (artifactInfo) -> Valdi_DownloadableModuleArtifact in\n            var artifact = Valdi_DownloadableModuleArtifact()\n            artifact.url = artifactInfo.url.absoluteString\n            guard let sha256Digest = Data(hexString: artifactInfo.sha256Digest) else {\n                throw CompilerError(\"Couldn't parse SHA256 digest: \\(artifactInfo.sha256Digest)\")\n            }\n            artifact.sha256Digest = sha256Digest\n\n            return artifact\n        }\n        return promise\n    }\n\n    private func makeDownloadableAssetsArtifacts(assets: [SelectedItem<FinalFile>]) -> [DownloadableAssetsArtifact] {\n        // files without density will be added to every artifact\n        var filesWithoutDensity = [SelectedItem<FinalFile>]()\n        var filesByDensity = [Double: [SelectedItem<FinalFile>]]()\n\n        for asset in assets {\n            switch asset.data.kind {\n            case .image(let scale, _):\n                if let imageScale = scale, imageScale != 0.0 {\n                    filesByDensity[imageScale, default: []].append(asset)\n                } else {\n                    filesWithoutDensity.append(asset)\n                }\n            default:\n                fatalError(\"finalFile assets should only be of kind image\")\n            }\n        }\n\n        // We create one artifact with imageScale 0, which will end up containing all the files without density specified only.\n        filesByDensity[0] = []\n\n        for key in filesByDensity.keys {\n            filesByDensity[key, default: []].append(contentsOf: filesWithoutDensity)\n        }\n\n        return filesByDensity\n            .map { DownloadableAssetsArtifact(deviceDensity: $0.key, files: $0.value) }\n            .filter { !$0.files.isEmpty }\n    }\n\n    /**\n     Process a local module, which will be stored locally on disk.\n\n     - A .valdimodule is created which contains all sources.\n     - All assets are stored locally in the assets or res folder.\n     */\n    private func processLocalModule(moduleInfo: CompilationItem.BundleInfo,\n                                    platform: Platform,\n                                    target: OutputTarget,\n                                    sources: [ZippableItem],\n                                    assets: [SelectedItem<FinalFile>],\n                                    outputDirectories: OutDirectories) throws -> [CompilationItem] {\n        var out = [CompilationItem]()\n\n        if !sources.isEmpty {\n            let valdiModule = try buildModule(moduleName: moduleInfo.name, zippableItems: sources, platform: platform, target: target)\n            out.append(makeItem(forValdiModuleData: valdiModule, moduleInfo: moduleInfo, platform: platform, target: target, outputDirectories: outputDirectories))\n        }\n\n        for asset in assets {\n            if case let .image(_, isRemote) = asset.data.kind, isRemote {\n                // Ignore emitted images meant to be remote\n                continue\n            }\n\n            out.append(asset.item)\n        }\n\n        return out\n    }\n\n    private func makeModuleName(moduleInfo: CompilationItem.BundleInfo, platform: Platform, isDebug: Bool) -> String {\n        return \"\\(moduleInfo.name)-\\(platform)-\\(isDebug ? \"debug\" : \"release\")\"\n    }\n\n    /**\n     Process a downloadable module, which will be hosted remotely on a server.\n\n     - A .valdimodule is created with all sources and will be hosted remotely\n     - .valdiassets files are created with all assets, for each image density and will be hosted remotely.\n     - An additional .valdimodule is created and will contain a single file, the downloadable manifest,\n     and will be stored locally. The manifest is used by the app to know how to fetch the remote module/assets.\n     */\n    private func processDownloadableModule(moduleInfo: CompilationItem.BundleInfo, platform: Platform, target: OutputTarget, sources: [SelectedItem<FinalFile>], assets: [SelectedItem<FinalFile>], previousDownloadableArtifactSignatures:  [DownloadableArtifactSignatures]) throws -> ZippableItem {\n        guard let artifactUploader = artifactUploader else {\n            throw CompilerError(\"Cannot process downloadable module '\\(moduleInfo.name)': The 'module_upload_base_url' setting was not configured in the project yaml file. Please set it to a valid endpoint that can be used to retrieve and upload artifacts, or make this module non downloadable by removing the 'downloadable: true' in its module.yaml\")\n        }\n\n        let dependencies = moduleInfo.dependencies.filter { !$0.isRoot }.map { $0.name }\n\n        let hasDownloadableSources = !sources.isEmpty && moduleInfo.downloadableSources\n        let hasDownloadableAssets = !assets.isEmpty && moduleInfo.downloadableAssets\n\n        let manifest = Synchronized(data: Valdi_DownloadableModuleManifest())\n        manifest.data { (manifest) in\n            manifest.name = moduleInfo.name\n            manifest.dependencies = dependencies\n        }\n\n        var pendingPromises = [Promise<Void>]()\n        let newArtifacts: Synchronized<[Valdi_DownloadableModuleArtifact]> = Synchronized(data: [])\n        let platformDownloadableArtifactSignatures = previousDownloadableArtifactSignatures.first(where: { $0.key == platform.rawValue })\n        var downloadableArtifactSignatures = Valdi_DownloadableModuleArtifactSignatures()\n\n        if (hasDownloadableSources || hasDownloadableAssets) {\n            switch (downloadableArtifactsProcessingMode) {\n            case .uploadIfNeeded:\n                break\n            case .verifySignatures:\n                do {\n                    if (platformDownloadableArtifactSignatures == nil) {\n                        throw CompilerError(\"Cannot verify downloadable module '\\(moduleInfo.name)': No downloadable artifact signatures were found\")\n                    }\n                    let fileData = try platformDownloadableArtifactSignatures!.file.readData()\n                    downloadableArtifactSignatures = try Valdi_DownloadableModuleArtifactSignatures(serializedData: fileData)\n                } catch {\n                    throw CompilerError(\"Failed to verify that downloadable module \\(moduleInfo.name) has already been uploaded\")\n                }\n            }\n        }\n\n        if hasDownloadableSources {\n            let artifactName = \"\\(moduleInfo.name)-\\(platform)-sources\"\n            do {\n                let moduleData = try buildModule(moduleName: artifactName, finalFiles: sources, platform: platform, target: target)\n                let sha256Digest = try moduleData.generateSHA256Digest()\n\n                let promise = buildAndUpload(moduleInfo: moduleInfo,\n                                             artifactUploader: artifactUploader,\n                                             artifactName: artifactName,\n                                             moduleData: moduleData,\n                                             sha256Digest: sha256Digest,\n                                             downloadableArtifactSignatures: downloadableArtifactSignatures).then { (artifact) -> Void in\n                    manifest.data { (manifest) in\n                        manifest.artifact = artifact\n                    }\n                    newArtifacts.data { newArtifacts in\n                        newArtifacts.append(artifact)\n                    }\n                }\n\n                pendingPromises.append(promise)\n            } catch let error {\n                let errorMessage = \"Failed to build artifact '\\(artifactName)': \\(error.legibleLocalizedDescription)\"\n                logger.error(errorMessage)\n                throw CompilerError(errorMessage)\n            }\n        }\n        \n        if hasDownloadableAssets {\n            let assetsArtifacts = makeDownloadableAssetsArtifacts(assets: assets)\n            for assetsArtifact in assetsArtifacts {\n                let artifactName = \"\\(moduleInfo.name)-\\(platform)-assets-\\(assetsArtifact.deviceDensity)dp\"\n                do {\n                    let moduleData = try buildModule(moduleName: artifactName, finalFiles: assetsArtifact.files, platform: platform, target: target)\n                    let sha256Digest = try moduleData.generateSHA256Digest()\n\n                    let promise = buildAndUpload(moduleInfo: moduleInfo,\n                                                 artifactUploader: artifactUploader,\n                                                 artifactName: artifactName,\n                                                 moduleData: moduleData,\n                                                 sha256Digest: sha256Digest,\n                                                 downloadableArtifactSignatures: downloadableArtifactSignatures\n                                                 ).then { (artifact) -> Void in\n                        var assets = Valdi_DownloadableModuleAssets()\n                        assets.artifact = artifact\n                        assets.deviceDensity = assetsArtifact.deviceDensity\n\n                        manifest.data { (manifest) in\n                            manifest.assets.append(assets)\n                        }\n\n                        newArtifacts.data { newArtifacts in\n                            newArtifacts.append(artifact)\n                        }\n                    }\n\n                    pendingPromises.append(promise)\n                } catch let error {\n                    let errorMessage = \"Failed to build artifact '\\(artifactName)': \\(error.legibleLocalizedDescription)\"\n                    logger.error(errorMessage)\n                    throw CompilerError(errorMessage)\n                }\n            }\n        }\n\n        for promise in pendingPromises {\n            try promise.waitForData()\n        }\n\n        if (hasDownloadableSources || hasDownloadableAssets) {\n            switch downloadableArtifactsProcessingMode {\n            case .verifySignatures:\n                break\n            case .uploadIfNeeded:\n                if writeDownloadableArtifactsManifest {\n                    var artifactsSignatures = Valdi_DownloadableModuleArtifactSignatures()\n                    artifactsSignatures.artifacts = newArtifacts.unsafeData.sorted(by: { (obj1: Valdi_DownloadableModuleArtifact, obj2: Valdi_DownloadableModuleArtifact) -> Bool in\n                        return obj1.url < obj2.url\n                    })\n                    let serializedData = try artifactsSignatures.serializedData()\n                    let expectedSignatureFileURL = expectedSignatureFileURL(moduleInfo: moduleInfo, platform: platform)\n\n                    if (!artifactsSignatures.artifacts.isEmpty) {\n                        try self.fileManager.save(data: serializedData, to: expectedSignatureFileURL)\n                    }\n                }\n                break\n            }\n        }\n\n        var completedManifest = manifest.unsafeData\n        completedManifest.assets.sort(by: { left, right in left.deviceDensity < right.deviceDensity })\n\n        let data = try completedManifest.orderedSerializedData()\n        return ZippableItem(file: .data(data), path: Files.downloadManifest)\n    }\n\n    private func doBuildAssetPackage(fileName: String,\n                                     platform: Platform,\n                                     target: OutputTarget,\n                                     assets: [SelectedItem<FinalFile>]) throws -> Data {\n        let assetsArtifacts = makeDownloadableAssetsArtifacts(assets: assets)\n\n        var items = [ZippableItem]()\n        for assetsArtifact in assetsArtifacts {\n            var assetItems = [ZippableItem]()\n            for file in assetsArtifact.files {\n                assetItems.append(getZipItem(forItem: file.item, finalFile: file.data))\n            }\n\n            let assetsBuilder = ValdiModuleBuilder(items: assetItems)\n            assetsBuilder.compress = false\n\n            let assetsData = try assetsBuilder.build()\n\n            items.append(ZippableItem(file: .data(assetsData), path: \"\\(assetsArtifact.deviceDensity)\"))\n        }\n\n        return try buildModule(moduleName: fileName, zippableItems: items, platform: platform, target: target)\n    }\n\n    private func buildAssetPackage(moduleInfo: CompilationItem.BundleInfo,\n                                   platform: Platform,\n                                   target: OutputTarget,\n                                   sources: [SelectedItem<FinalFile>],\n                                   assets: [SelectedItem<FinalFile>],\n                                   outputDirectories: OutDirectories) -> [CompilationItem] {\n        var out = sources.map { $0.item }\n\n        guard !assets.isEmpty else { return out }\n\n        do {\n            let fileName = \"\\(moduleInfo.name).\\(FileExtensions.assetPackage)\"\n\n            let packageData = try doBuildAssetPackage(fileName: fileName, platform: platform, target: target, assets: assets)\n\n            let outputDirectoryURL: URL = outputDirectories.assetsURL\n            let outputURL = outputDirectoryURL.appendingPathComponent(fileName, isDirectory: false)\n\n            let finalFile = FinalFile(outputURL: outputURL, file: .data(packageData), platform: platform, kind: .assetsPackage)\n\n            out += [CompilationItem(sourceURL: moduleInfo.baseDir, relativeProjectPath: nil, kind: .finalFile(finalFile), bundleInfo: moduleInfo, platform: platform, outputTarget: target)]\n        } catch let error {\n            out += assets.map { $0.item.with(error: error) }\n        }\n\n        return out\n    }\n\n    private func buildModuleAndUpload(moduleInfo: CompilationItem.BundleInfo,\n                                      platform: Platform,\n                                      target: OutputTarget,\n                                      sources: [SelectedItem<FinalFile>],\n                                      assets: [SelectedItem<FinalFile>],\n                                      appendAssetsToValdiModule: Bool,\n                                      outputDirectories: OutDirectories,\n                                      downloadableArtifactSignatures: [DownloadableArtifactSignatures]) -> [CompilationItem] {\n        do {\n            if sources.isEmpty && assets.isEmpty {\n                return []\n            }\n\n            var moduleItems = [ZippableItem]()\n\n            if moduleInfo.downloadableSources || moduleInfo.downloadableAssets {\n                let manifest = try processDownloadableModule(moduleInfo: moduleInfo, platform: platform, target: target, sources: sources, assets: assets, previousDownloadableArtifactSignatures: downloadableArtifactSignatures)\n                moduleItems.append(manifest)\n            }\n\n            if !moduleInfo.downloadableSources {\n                moduleItems += sources.map { getZipItem(forItem: $0.item, finalFile: $0.data) }\n\n                if appendAssetsToValdiModule && !assets.isEmpty && !moduleInfo.downloadableAssets {\n                    let fileName = \"\\(moduleInfo.name).\\(FileExtensions.assetPackage)\"\n\n                    let assetPackage = try doBuildAssetPackage(fileName: fileName, platform: platform, target: target, assets: assets)\n                    moduleItems.append(ZippableItem(file: .data(assetPackage), path: \"res.\\(FileExtensions.assetPackage)\"))\n                    return try processLocalModule(moduleInfo: moduleInfo,\n                                                  platform: platform,\n                                                  target: target,\n                                                  sources: moduleItems,\n                                                  assets: [],\n                                                  outputDirectories: outputDirectories)\n                } else {\n                    return try processLocalModule(moduleInfo: moduleInfo,\n                                                  platform: platform,\n                                                  target: target,\n                                                  sources: moduleItems,\n                                                  assets: assets,\n                                                  outputDirectories: outputDirectories)\n                }\n            } else {\n                // Sources are remote, we just store the manifest in the .valdimodule\n                let moduleData = try buildModule(moduleName: \"\\(moduleInfo.name)-manifest\", zippableItems: moduleItems, platform: platform, target: target)\n\n                return [makeItem(forValdiModuleData: moduleData, moduleInfo: moduleInfo, platform: platform, target: target, outputDirectories: outputDirectories)]\n            }\n        } catch let error {\n            return (sources + assets).map { $0.item.with(error: error) }\n        }\n    }\n    \n    private func processModule(moduleInfo: CompilationItem.BundleInfo, platform: Platform, target: OutputTarget, sources: [SelectedItem<FinalFile>], assets: [SelectedItem<FinalFile>], outputDirectories: OutDirectories, downloadableArtifactSignatures: [DownloadableArtifactSignatures]) -> [CompilationItem] {\n        switch outputMode {\n        case .uploadedArtifacts:\n            return buildModuleAndUpload(moduleInfo: moduleInfo, platform: platform, target: target, sources: sources, assets: assets, appendAssetsToValdiModule: false, outputDirectories: outputDirectories, downloadableArtifactSignatures: downloadableArtifactSignatures)\n        case .assetPackage:\n            return buildAssetPackage(moduleInfo: moduleInfo, platform: platform, target: target, sources: sources, assets: assets, outputDirectories: outputDirectories)\n        case .bundledAssetPackage:\n            return buildModuleAndUpload(moduleInfo: moduleInfo, platform: platform, target: target, sources: sources, assets: assets, appendAssetsToValdiModule: true, outputDirectories: outputDirectories, downloadableArtifactSignatures: downloadableArtifactSignatures)\n        }\n    }\n    \n    private func generateModules(selectedItems: GroupedItems<ModuleAndPlatform, SelectedItem<FinalFile>>, downloadableArtifactSignatures: [DownloadableArtifactSignatures]) -> [CompilationItem] {\n        let moduleInfo = selectedItems.key.moduleInfo\n        let platform = selectedItems.key.platform\n\n        logger.verbose(\"Processing module \\(moduleInfo.name) for platform \\(platform)\")\n\n        let resolvedFiles = resolveFiles(items: selectedItems.items)\n\n        var out = [CompilationItem]()\n        out += resolvedFiles.passthroughItems.map { $0.item }\n\n        // Web and CPP doesn't need any packaging\n        if platform == .web  || platform == .cpp {\n            return out\n        }\n\n        let debugSources = resolvedFiles.sources.filter { $0.item.outputTarget.contains(.debug) }\n        let releaseSources = resolvedFiles.sources.filter { $0.item.outputTarget.contains(.release) }\n        let debugAssets = resolvedFiles.assets.filter { $0.item.outputTarget.contains(.debug) }\n        let releaseAssets = resolvedFiles.assets.filter { $0.item.outputTarget.contains(.release) }\n\n        let debugDirectories: OutDirectories? = {\n            switch platform {\n            case .android:\n                return moduleInfo.androidDebugOutputDirectories\n            case .ios:\n                return moduleInfo.iosDebugOutputDirectories\n            case .web:\n                return moduleInfo.webDebugOutputDirectories\n            default:\n                return nil\n            }\n        }()\n\n        let releaseDirectories: OutDirectories? = {\n            switch platform {\n            case .android:\n                return moduleInfo.androidReleaseOutputDirectories\n            case .ios:\n                return moduleInfo.iosReleaseOutputDirectories\n            case .web:\n                return moduleInfo.webReleaseOutputDirectories\n            default:\n                return nil\n            }\n        }()\n\n        if let debugDirectories = debugDirectories {\n            out += processModule(moduleInfo: moduleInfo, platform: platform, target: .debug, sources: debugSources, assets: debugAssets, outputDirectories: debugDirectories, downloadableArtifactSignatures: downloadableArtifactSignatures)\n        }\n\n        if let releaseDirectories = releaseDirectories {\n            out += processModule(moduleInfo: moduleInfo, platform: platform, target: .release, sources: releaseSources, assets: releaseAssets, outputDirectories: releaseDirectories, downloadableArtifactSignatures: downloadableArtifactSignatures)\n        }\n\n        return out\n    }\n\n    private func generatePreparedUploadArtifact(to url: URL, artifactUploader: ArtifactUploader) -> CompilationItem {\n        do {\n            let preparedUploadArtifact = try artifactUploader.makePreparedUploadArtifact()\n            return CompilationItem(relativeProjectPath: url.lastPathComponent,\n                                   kind: .finalFile(FinalFile(outputURL: url, file: preparedUploadArtifact, platform: nil, kind: .assetsPackage)),\n                                   bundleInfo: self.rootBundle,\n                                   platform: nil,\n                                   outputTarget: .all)\n        } catch let error {\n            return CompilationItem(relativeProjectPath: url.lastPathComponent, kind: .error(error, originalItemKind: .unknown(.url(url))), bundleInfo: self.rootBundle, platform: nil, outputTarget: .all)\n        }\n\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let downloadableArtifactSignatureItems = items.select { item in\n            if case let .downloadableArtifactSignatures(sig) = item.kind {\n                return sig\n            }\n            return nil\n        }\n\n        let downloadableArtifactSignaturesByModule = downloadableArtifactSignatureItems.selectedItems.groupBy { selectedItem in\n            return selectedItem.item.bundleInfo\n        }.mapValues { selectedItems in\n            return selectedItems.map { $0.data }\n        }\n\n        let filteredItems = downloadableArtifactSignatureItems.transformAll { _ in return [] }\n\n        if compilerConfig.regenerateValdiModulesBuildFiles {\n            return filteredItems\n        }\n\n        var items = filteredItems.select { (item) -> FinalFile? in\n            if !compilerConfig.onlyProcessResourcesForModules.isEmpty && !compilerConfig.onlyProcessResourcesForModules.contains(item.bundleInfo.name) /* The following expr breaks module filtering: && !item.shouldOutputToWeb */ {\n                return nil\n            }\n\n            guard case let .finalFile(finalFile) = item.kind, finalFile.shouldBundle else {\n                return nil\n            }\n\n            return finalFile\n        }.groupBy { (item: SelectedItem<FinalFile>) -> ModuleAndPlatform in\n            return ModuleAndPlatform(moduleInfo: item.item.bundleInfo, platform: item.data.platform!)\n        }.transformEachConcurrently { groupedItems -> [CompilationItem] in\n            return generateModules(selectedItems: groupedItems, downloadableArtifactSignatures: downloadableArtifactSignaturesByModule[groupedItems.key.moduleInfo] ?? [] )\n        }\n\n        if let preparedUploadArtifactOutput = self.projectConfig.preparedUploadArtifactOutput, let artifactUploader = artifactUploader {\n            items.append(item: generatePreparedUploadArtifact(to: preparedUploadArtifactOutput, artifactUploader: artifactUploader))\n        }\n\n        return items\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/CSSModulesProcessor.swift",
    "content": "//\n//  CSSModulesProcessor.swift\n//  \n//\n//  Created by Simon Corsin on 10/29/19.\n//\n\nimport Foundation\n\nclass CSSModulesProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Compiling CSS modules\"\n    }\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n    private let fileDependenciesManager: FileDependenciesManager\n    private let stagingDirectoryURL: URL = URL.randomFileURL()\n\n    init(logger: ILogger, fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, fileDependenciesManager: FileDependenciesManager) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.fileDependenciesManager = fileDependenciesManager\n    }\n\n    private func transform(item: SelectedItem<File>) -> [CompilationItem] {\n        do {\n            logger.debug(\"-- Compiling CSS module \\(item.item.relativeProjectPath)\")\n\n            let shouldEmitJsModule = item.item.sourceURL.pathExtension != \"vue\"\n\n            let fileContent = try item.data.readString()\n\n            let compiler = CSSModuleCompiler(logger: logger, fileContent: fileContent, projectBaseDir: stagingDirectoryURL, relativeProjectPath: item.item.relativeProjectPath)\n            let result = try compiler.compile()\n\n            fileDependenciesManager.register(file: item.item.sourceURL, dependencies: result.allOpenedFiles, forKey: \"CSSModuleProcessor\")\n\n            let moduleRelativePath = try item.item.bundleInfo.itemPath(forRelativeProjectPath: result.compiledCSS.outputPath)\n            let compiledCSS = item.item.with(newKind: .resourceDocument(DocumentResource(outputFilename: moduleRelativePath, file: result.compiledCSS.file)))\n\n            var out = [compiledCSS]\n\n            if shouldEmitJsModule {\n                out += try TypeScriptIntermediateUtils.emitGeneratedJs(fileManager: fileManager, projectConfig: projectConfig, sourceItem: item.item, jsOutputPath: result.jsModule.outputPath, jsContent: result.jsModule.file, tsDefinitionOutputPath: result.typeDefinition.outputPath, tsDefinitionContent: result.typeDefinition.file)\n            }\n\n            return out\n        } catch let error {\n            logger.error(\"Failed to compile CSS module: \\(error.legibleLocalizedDescription)\")\n            return [item.item.with(error: error)]\n        }\n    }\n\n    private func updateStagingDirectory(items: [SelectedItem<File>]) throws {\n        guard !items.isEmpty else { return }\n\n        for item in items {\n            let itemExtension = item.item.sourceURL.pathExtension\n            guard itemExtension == FileExtensions.css || itemExtension == FileExtensions.sass else {\n                continue\n            }\n\n            try fileManager.save(file: item.data, to: stagingDirectoryURL.appendingPathComponent(item.item.relativeProjectPath))\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        // Ignore the existing .module.css since we generate them\n        let itemsWithoutCompiledCSSModules = items.select { (item) -> File? in\n            switch item.kind {\n            case .typeScript(let file, let url):\n                let fileName = url.lastPathComponent\n                guard fileName.hasSuffix(\".module.css.d.ts\") else {\n                    return nil\n                }\n                return file\n            default:\n                return nil\n            }\n        }.discardSelected()\n\n        try itemsWithoutCompiledCSSModules.select { item -> File? in\n            switch item.kind {\n            case .css(let file):\n                return file\n            default:\n                return nil\n            }\n        }.processAll(updateStagingDirectory(items:))\n\n        let selectedItems = itemsWithoutCompiledCSSModules.select { (item) -> File? in\n            switch item.kind {\n            case .css(let file):\n                guard item.sourceURL.lastPathComponent.contains(\".module.\") || item.sourceURL.pathExtension == \"vue\" else {\n                    return nil\n                }\n                return file\n            default:\n                return nil\n            }\n        }\n\n#if os(Linux)\n        // Running this processor concurrently on Linux occasionally causes a segmentation fault without a backtrace,\n        // that we haven't been able to trace.\n        return selectedItems.transformEach(transform)\n#else\n        return selectedItems.transformEachConcurrently(transform)\n#endif\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/ClientSqlExportProcessor.swift",
    "content": "//\n//  ClientSqlExportProcessor.swift\n//\n//\n//  Created by Alex Pawlowski on 10/02/23.\n//\n\nimport Foundation\nimport Yams\n\nfinal class ClientSqlExportProcessor: CompilationProcessor {\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n    private let rootBundle: CompilationItem.BundleInfo\n\n    var description: String {\n        return \"Exporting SQL files\"\n    }\n\n    init(logger: ILogger,\n         fileManager: ValdiFileManager,\n         projectConfig: ValdiProjectConfig,\n         rootBundle: CompilationItem.BundleInfo\n    ) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.rootBundle = rootBundle\n    }\n\n    private func getSqlMigrations(sqlBaseUrl: URL) throws -> [URL] {\n        let filesFinder = ValdiFilesFinder(url: sqlBaseUrl)\n        let allFiles = try filesFinder.allFiles()\n        let steps = allFiles.filter { $0.pathExtension == \"sqm\" }\n        return steps\n    }\n\n    private func exportSqlFilesAndroid(\n        bundle: CompilationItem.BundleInfo,\n        manifestUrl: URL\n    ) throws -> [CompilationItem] {\n        let platform: Platform = .android\n\n        guard let globalMetadataURL = try projectConfig.globalMetadataURL(for: platform) else {\n            return []\n        }\n\n        let manifestContent = try String(contentsOf: manifestUrl)\n\n        guard let manifest = try Yams.compose(yaml: manifestContent) else {\n            throw CompilerError(\"Failed to parse sql manifest at: \\(manifestUrl)\")\n        }\n\n        // create the output dir\n        let sqldelightUrl = globalMetadataURL.appendingPathComponent(Files.sqlExportDir, isDirectory: true)\n        let outputUrl = URL(fileURLWithPath: bundle.name, isDirectory: true, relativeTo: sqldelightUrl)\n\n        let sqlBaseUrl = manifestUrl.deletingLastPathComponent()\n\n        logger.verbose(\"-- CLIENTSQL exporting sql source files in \\(manifestUrl.relativePath(from: projectConfig.baseDir))\")\n\n        // for each file under manifest.files\n        var exportedFiles: [CompilationItem] = (manifest[\"files\"]?.sequence ?? [])\n            .compactMap { $0.string }\n            .compactMap { filename in\n                let sqlSrc = URL(fileURLWithPath: filename, isDirectory: false, relativeTo: sqlBaseUrl)\n                let sqlDst = URL(fileURLWithPath: filename, isDirectory: false, relativeTo: outputUrl)\n                if sqlSrc.pathExtension == \"sqm\" {\n                    logger.verbose(\"-- CLIENTSQL skipping migration file: \\(filename)\")\n                    return nil\n                }\n\n                logger.verbose(\"-- CLIENTSQL - \\(filename)\")\n\n                let file = File.url(sqlSrc)\n                let finalFile = FinalFile(outputURL: sqlDst, file: file, platform: platform, kind: .unknown)\n\n                return CompilationItem(sourceURL: sqlDst,\n                                       relativeProjectPath: nil,\n                                       kind: .finalFile(finalFile),\n                                       bundleInfo: rootBundle,\n                                       platform: platform,\n                                       outputTarget: .all)\n            }\n\n        let migrationFiles = try getSqlMigrations(sqlBaseUrl: sqlBaseUrl)\n        try migrationFiles.forEach { sqm in\n            let sqmFile = File.data(try Data(contentsOf: sqm))\n            let outputUrl = URL(fileURLWithPath: sqm.lastPathComponent, isDirectory: false, relativeTo: outputUrl)\n            let finalFile = FinalFile(outputURL: outputUrl, file: sqmFile, platform: platform, kind: .unknown)\n            exportedFiles += [CompilationItem(sourceURL: manifestUrl,\n                                              relativeProjectPath: nil,\n                                              kind: .finalFile(finalFile),\n                                              bundleInfo: rootBundle,\n                                              platform: platform,\n                                              outputTarget: .all)]\n        }\n\n        if !exportedFiles.isEmpty {\n            // generate BUILD.bazel for Android\n            let bazelUrl = URL(fileURLWithPath: \"BUILD.bazel\", isDirectory: false, relativeTo: outputUrl)\n            let bazelContent = \"\"\"\n            load(\"@rules_pkg//:mappings.bzl\", \"pkg_files\", \"strip_prefix\")\n            load(\"@rules_pkg//:pkg.bzl\", \"pkg_zip\")\n\n            pkg_files(\n                name = \"srcs\",\n                srcs = glob([\"**/*.sq\", \"**/*.sqm\", \"**/*.yaml\"]),\n                strip_prefix = strip_prefix.from_pkg(),\n            )\n\n            pkg_zip(\n                name = \"\\(bundle.name)_sql\",\n                srcs = [\":srcs\"],\n                visibility = [\"//visibility:public\"],\n                package_dir = \"com/snap\",\n            )\n            \"\"\"\n            let bazelFile = File.data(try bazelContent.utf8Data())\n            let finalFile = FinalFile(outputURL: bazelUrl, file: bazelFile, platform: platform, kind: .unknown)\n            exportedFiles += [CompilationItem(sourceURL: manifestUrl,\n                                              relativeProjectPath: nil,\n                                              kind: .finalFile(finalFile),\n                                              bundleInfo: rootBundle,\n                                              platform: platform,\n                                              outputTarget: .all)]\n        }\n\n        return exportedFiles\n    }\n\n    private func generateExportIndexAndroid(manifestYamlFileItems: [SelectedItem<File>]) throws -> [CompilationItem] {\n        guard let globalMetadataURL = try projectConfig.globalMetadataURL(for: .android) else {\n            return []\n        }\n        \n        guard let pathTemplate = projectConfig.sqlExportPathTemplate else {\n            logger.error(\"Missing required config 'sql_export_path_template' in valdi_config.yaml. Skipping SQL export index generation.\")\n            return []\n        }\n        \n        let bundlesWithExports = manifestYamlFileItems.map({\n            $0.item.bundleInfo.name\n        })\n        // TODO(3521): Update to valid_modules\n        let labels = Array(bundlesWithExports.map({bundleName in\n            pathTemplate.replacingOccurrences(of: \"{bundle_name}\", with: bundleName)\n        }))\n        let labelsJson = try labels.toJSON(outputFormatting: [.sortedKeys, .prettyPrinted, .withoutEscapingSlashes])\n        let labelsString = String(data: labelsJson, encoding: .utf8) ?? \"[]\"\n        let exportIndexUrl = URL(fileURLWithPath: \"sqldelight/BUILD.bazel\", isDirectory: false, relativeTo: globalMetadataURL)\n        let exportIndexContent = \"\"\"\n        load(\"@rules_pkg//:pkg.bzl\", \"pkg_zip\")\n\n        pkg_zip(\n            name = \"all_sql_exports\",\n            srcs = \\(labelsString),\n            visibility = [\"//visibility:public\"],\n        )\n        \"\"\"\n        let exportIndexFile = File.data(try exportIndexContent.utf8Data())\n        let finalFile = FinalFile(outputURL: exportIndexUrl, file: exportIndexFile, platform: .android, kind: .unknown)\n        let projectURL = projectConfig.baseDir.appendingPathComponent(projectConfig.projectName)\n\n        return [CompilationItem(sourceURL: projectURL,\n                                relativeProjectPath: nil,\n                                kind: .finalFile(finalFile),\n                                bundleInfo: rootBundle,\n                                platform: .android,\n                                outputTarget: .all)]\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return try items.select { item -> File? in\n            switch item.kind {\n            case .sqlManifest(let file):\n                return file\n            default:\n                return nil\n            }\n        }\n        .transformAll { selectedItems in\n            let exportAndroid = (projectConfig.androidOutput?.codegenEnabled ?? false) ? try selectedItems.flatMap {\n                try exportSqlFilesAndroid(\n                    bundle: $0.item.bundleInfo,\n                    manifestUrl: $0.data.getURLHandle().url\n                )\n            } : []\n            let androidIndex = try generateExportIndexAndroid(manifestYamlFileItems: selectedItems)\n\n            return exportAndroid + androidIndex\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/ClientSqlProcessor.swift",
    "content": "//\n//  ClientSqlProcessor.swift\n//\n//\n//  Created by Li Feng on 2/20/23.\n//\n\nimport Foundation\nimport Yams\n\nfinal class ClientSqlProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Generating code for SQL\"\n    }\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n    private let rootBundle: CompilationItem.BundleInfo\n\n    // bundle=>file=>content\n    private var bundleToSourceMap: Synchronized<[String: [RelativePath: String]]> = Synchronized(data: [:])\n    private let diskCache: DiskCache?\n\n    init(logger: ILogger, \n         fileManager: ValdiFileManager,\n         diskCacheProvider: DiskCacheProvider,\n         projectConfig: ValdiProjectConfig,\n         rootBundle: CompilationItem.BundleInfo\n    ) throws {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.rootBundle = rootBundle\n\n        if let clientSqlCompilerPath = projectConfig.clientSqlURL?.path, diskCacheProvider.isEnabled() {\n            logger.debug(\"Resolving SQL version\")\n            let output = try SyncProcessHandle.run(logger: logger, command: clientSqlCompilerPath, arguments: [\"-version\"]).trimmed\n            diskCache = diskCacheProvider.newCache(cacheName: \"clientsql\", outputExtension: \"ts\", metadata: [\"version\": output])\n        } else {\n            diskCache = nil\n        }\n    }\n\n    private func runSqlDelight(items: GroupedItems<CompilationItem.BundleInfo, SelectedItem<File>>) throws -> [CompilationItem] {\n        let bundleInfo = items.key\n        let sqlUrl = bundleInfo.baseDir.appendingPathComponent(\"sql\")\n        let sqlDir = sqlUrl.path\n\n        // Update source map with incoming files (may happen concurrently from different bundles)\n        let sourceMap = try bundleToSourceMap.data {bundleToSourceMap in\n            var sourceMap = bundleToSourceMap[bundleInfo.name, default: Dictionary()]\n            for item in items.items {\n                let relativePath = item.item.relativeBundlePath\n                if relativePath.components.first == \"sql\" {\n                    sourceMap[relativePath] = try item.data.readString()\n                }\n            }\n            bundleToSourceMap[bundleInfo.name] = sourceMap\n            return sourceMap\n        }\n\n        if sourceMap.isEmpty {\n            logger.verbose(\"No valid SQL sources found for module \\(items.key.name)\")\n            return []\n        }\n\n        // Expected SQL source tree layout:\n        // proj_root\n        //   src  (TS source code)\n        //   test (TS test code)\n        //   sql  (SQL source code)\n        //     my_db_class_name (schema and query definitions)\n        //       my_db_stuff.sq\n        //     migration (optional migration file directory)\n        //       1.sqm\n        //       2.sqm\n        //     sql_types.yaml (optional type mapping file)\n        let migrationDirName = \"migration\"\n        let pkg = sourceMap.keys.reduce(\"\", {\n            // package/class/module = first dir under sqldir that's not \"migration\" or type mapping\n            guard $1.components.count > 2 else { return $0 }\n            let dir = $1.components[1]\n            return ($0 == \"\" && dir != migrationDirName && dir != Files.sqlTypesYaml && dir != Files.sqlManifestYaml) ? dir : $0\n        })\n        if pkg == \"\" {\n            return []\n        }\n        logger.verbose(\"-- CLIENTSQL generating code for package \\(bundleInfo.name)/\\(pkg)\")\n        let clazz = pkg\n        let outdir = \"src/sqlgen\"\n        let tmfile = \"\\(sqlDir)/\\(Files.sqlTypesYaml)\"\n        let typemapping = FileManager.default.isReadableFile(atPath: tmfile) ?\n        [\"-tm\", Files.sqlTypesYaml] : []\n\n        // Locate the input files and expected output file path\n        let outputDirectory = projectConfig.generatedTsDirectoryURL\n            .appendingPathComponent(\"\\(bundleInfo.name)\")\n            .appendingPathComponent(outdir)\n            .resolvingSymlinksInPath()\n        try fileManager.createDirectory(at: outputDirectory)\n\n        // All input files sorted by path and put together as the key to locate the DiskCache entry\n        let sortedSourcePaths = sourceMap.keys.sorted()\n        let inputData = try sortedSourcePaths\n            .reduce(\"\", {$0 + \"[\\($1)]\" + sourceMap[$1]!})\n            .utf8Data()\n\n        if let cachedData = diskCache?.getOutput(item: outputDirectory.path, inputData: inputData) {\n            logger.verbose(\"-- CLIENTSQL use cached output: \\(outputDirectory.path)\")\n            if let outputFiles:[String: Data] = try (NSKeyedUnarchiver.unarchivedObject(ofClass:NSDictionary.self, from:cachedData)) as? [String : Data] {\n                var emittedItems: [CompilationItem] = []\n                for (relativePath, tsContents) in outputFiles {\n                    let relativeProjectPath = \"\\(bundleInfo.name)/\\(outdir)/\\(relativePath)\"\n                    let emittedTsSourceURL = bundleInfo.absoluteURL(forRelativeProjectPath: relativeProjectPath)\n                    let item = CompilationItem(sourceURL: emittedTsSourceURL,\n                                               relativeProjectPath: relativeProjectPath,\n                                               kind: .typeScript(.data(tsContents), emittedTsSourceURL),\n                                               bundleInfo: bundleInfo,\n                                               platform: nil,\n                                               outputTarget: .all)\n                    emittedItems.append(item)\n                }\n                return emittedItems\n            }\n        }\n\n        // Run the external compiler\n        let compilerPath = try projectConfig.ensureClientSqlCompiler()\n\n        let args = [\"-s\", sqlDir,\n                    \"-p\", pkg,\n                    \"-c\", clazz,\n                    \"-m\", clazz,\n                    \"-o\", outputDirectory.path,\n                    \"-l\", \"typescript\"] + typemapping\n        let output = try SyncProcessHandle.run(logger: logger, command: compilerPath, arguments: args)\n\n        logger.verbose(\"-- CLIENTSQL compiler:\")\n        logger.info(output)\n\n        var outputFiles: [String: Data] = [:]\n        var emittedItems: [CompilationItem] = []\n        if let enumerator = FileManager.default.enumerator(at: outputDirectory, includingPropertiesForKeys: [.isRegularFileKey], options: [.skipsHiddenFiles, .skipsPackageDescendants]) {\n            for case let fileURL as URL in enumerator {\n                do {\n                    let fileAttributes = try fileURL.resourceValues(forKeys:[.isRegularFileKey])\n                    if fileAttributes.isRegularFile! {\n                        let relativePath = fileURL.relativePath(from: outputDirectory)\n                        logger.verbose(\"-- CLIENTSQL file: \\(relativePath)\")\n                        let relativeProjectPath = \"\\(bundleInfo.name)/\\(outdir)/\\(relativePath)\"\n                        let emittedTsSourceURL = bundleInfo.absoluteURL(forRelativeProjectPath: relativeProjectPath)\n                        let tsContents = try String(contentsOfFile: fileURL.path).utf8Data()\n                        outputFiles[relativePath] = tsContents\n                        let item = CompilationItem(sourceURL: emittedTsSourceURL,\n                                                   relativeProjectPath: relativeProjectPath,\n                                                   kind: .typeScript(.data(tsContents), emittedTsSourceURL),\n                                                   bundleInfo: bundleInfo,\n                                                   platform: nil,\n                                                   outputTarget: .all)\n                        emittedItems.append(item)\n                    }\n                } catch { logger.error(\"-- CLIENTSQL error: \\(error) at \\(fileURL)\") }\n            }\n        }\n\n        if let cachedData = try? NSKeyedArchiver.archivedData(withRootObject: outputFiles, requiringSecureCoding: false) {\n            try diskCache?.setOutput(item: outputDirectory.path, inputData: inputData, outputData: cachedData)\n        }\n        return emittedItems\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        // Select *.sq files, we will re-run the codegen if any of them has changed\n        return try items.select { (item) -> File? in\n            switch item.kind {\n            case .sql(let file):\n                return file\n            default:\n                return nil\n            }\n        }.groupBy { (item) -> CompilationItem.BundleInfo in\n            return item.item.bundleInfo\n        }.transformEachConcurrently(runSqlDelight)\n    }\n}\n\nextension ValdiProjectConfig {\n    func ensureClientSqlCompiler() throws -> String {\n        guard let path = clientSqlURL?.path else {\n            throw CompilerError(\"ClientSQL binary path is not defined\")\n        }\n\n        return path\n    }\n\n    func globalMetadataURL(for platform: Platform) throws -> URL? {\n        let output: ValdiOutputConfig?\n        switch platform {\n        case .ios:\n            output = iosOutput\n        case .android:\n            output = androidOutput\n        case .web:\n            output = webOutput\n        case .cpp:\n            output = cppOutput\n        }\n        return try output?.globalMetadataPath?.resolve()\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/CodeCoverageProcessor.swift",
    "content": "import Foundation\n\nclass CodeCoverageProcessor: CompilationProcessor {\n    private let logger: ILogger\n    private let projectConfig: ValdiProjectConfig\n    private let jsCodeInstrumentation: JSCodeInstrumentation\n    private var typeScriptCompilerManager: TypeScriptCompilerManager\n    private let ignoredTestName = try! NSRegularExpression(pattern: \"^.*test.*\")\n    private let includedFileExtensions = try! NSRegularExpression(pattern: \"^.*(tsx|ts)$\")\n    private let ignoredFilesPattern = try! NSRegularExpression(pattern: \"^.*\\\\.(spec.(tsx|ts)|d.ts|vue.ts)\")\n    private let codeCoverageByPath: Synchronized<[String: Any]> = Synchronized(data: [:])\n    private let fileManager: ValdiFileManager\n\n    var description: String {\n        return \"Code Coverage Processor\"\n    }\n\n    init(logger: ILogger,\n         jsCodeInstrumentation: JSCodeInstrumentation, diskCacheProvider: DiskCacheProvider, projectConfig: ValdiProjectConfig, typeScriptCompilerManager: TypeScriptCompilerManager, fileManager: ValdiFileManager) {\n        self.logger = logger\n        self.projectConfig = projectConfig\n        self.jsCodeInstrumentation = jsCodeInstrumentation\n        self.typeScriptCompilerManager = typeScriptCompilerManager\n        self.fileManager = fileManager\n    }\n\n    private func filterFileForCodeInstrumentation(_ item: SelectedItem<JavaScriptFile>) -> Bool {\n        let filePath = item.item.sourceURL.path\n        return !item.item.bundleInfo.disableCodeCoverage &&\n        !filePath.contains(\"/res.ts\") &&\n        !filePath.matches(regex: self.ignoredFilesPattern) &&\n        !filePath.matches(regex: self.ignoredTestName) &&\n        filePath.matches(regex: self.includedFileExtensions)\n    }\n\n    private func addCodeInstrumentation(items: [SelectedItem<JavaScriptFile>]) throws -> [CompilationItem] {\n        let inputFiles = try items\n            .filter { (item) in filterFileForCodeInstrumentation(item) }\n            .parallelMap { (item) in\n                logger.info(\"-- Adding Code Instrumentation to \\(item.data.relativePath)\")\n                return InstrumentationFileConfig(sourceFilePath: item.item.sourceURL.path, fileContent: try item.data.file.readString())\n            }\n\n        let codeInstrumentationResults = try self.jsCodeInstrumentation.instrumentFiles(files: inputFiles).waitForData()\n\n        let codeInstrumentationResultsByFileURL = try codeInstrumentationResults.associateUnique { ($0.sourceFilePath, $0) }\n\n        return items.parallelMap { item in\n            let compilationItem = item.item\n\n            guard let codeInstrumentationResult = codeInstrumentationResultsByFileURL[item.item.sourceURL.path] else {\n                return compilationItem\n            }\n\n            logger.info(\"-- Added Code Instrumentation to \\(item.data.relativePath)\")\n\n            do {\n                let codeCoverage = try JSONSerialization.jsonObject(with: try codeInstrumentationResult.fileCoverage.utf8Data())\n                let sourceURLPath = item.item.sourceURL.path\n                codeCoverageByPath.data { dict -> Void in\n                    dict[sourceURLPath] = codeCoverage\n                }\n\n                let outputJs = item.data.with(file: .string(codeInstrumentationResult.instrumentedFileContent))\n                return compilationItem.with(newKind: .javaScript(outputJs))\n            } catch let error {\n                logger.error(\"Failed to add code coverage to \\(item.data.relativePath): \\(error.legibleLocalizedDescription)\")\n                return compilationItem.with(error: error)\n            }\n        }\n    }\n\n    private func addCodeInstrumentationInBatch(items: [SelectedItem<JavaScriptFile>]) -> [CompilationItem] {\n        do {\n            var outItems: [CompilationItem] = []\n            let codeInstrumentedItems = try addCodeInstrumentation(items: items)\n\n            for item in codeInstrumentedItems {\n                switch item.kind {\n                case .javaScript:\n                    outItems.append(item.with(newOutputTarget: .debug))\n                default:\n                    outItems.append(item)\n                }\n            }\n\n            return outItems\n        } catch {\n            return items.map { $0.item.with(error: error) }\n        }\n    }\n\n    private func generateCodeCoverageIndexFile() throws {\n        let allCodeCoverageByPath = codeCoverageByPath.data { data in\n            return data\n        }\n\n        let entries = allCodeCoverageByPath.sorted { left, right in\n            return left.key < right.key\n        }\n\n        let json: [String: Any] = [\"files\": entries.map { [$0.key, $0.value] }]\n\n        let outputURL = self.projectConfig.codeCoverageResultConfig.instrumentedFilesResult\n\n        do {\n            let data = try JSONSerialization.data(withJSONObject: json)\n            try fileManager.save(data: data, to: outputURL)\n        } catch let error {\n            throw CompilerError(\"Failed to generate code coverage index file: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let outItems = items.select { (item) -> JavaScriptFile? in\n            switch item.kind {\n            case .javaScript(let jsFile):\n                return jsFile\n            default:\n                return nil\n            }\n        }.transformInBatches(addCodeInstrumentationInBatch)\n\n        try generateCodeCoverageIndexFile()\n\n        return outItems\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/CombineNativeSourcesProcessor.swift",
    "content": "// Copyright © 2025 Snap, Inc. All rights reserved.\n\nimport Foundation\n\n// [.nativeSource] -> [.nativeSource]\nfinal class CombineNativeSourcesProcessor: CompilationProcessor {\n\n    fileprivate struct GroupingKey: Equatable, Hashable {\n        let platform: Platform?\n        let groupingIdentifier: String\n    }\n\n    fileprivate struct FileAndContent {\n        let filename: String\n        let content: String\n    }\n\n    private let logger: ILogger\n    private let compilerConfig: CompilerConfig\n    private let projectConfig: ValdiProjectConfig\n    private let bundleManager: BundleManager\n    private var cachedNativeSourceByModule = Synchronized(data: [CompilationItem.BundleInfo: [SelectedItem<NativeSource>]]())\n\n    init(logger: ILogger, compilerConfig: CompilerConfig, projectConfig: ValdiProjectConfig, bundleManager: BundleManager) {\n        self.logger = logger\n        self.compilerConfig = compilerConfig\n        self.projectConfig = projectConfig\n        self.bundleManager = bundleManager\n    }\n\n    var description: String {\n        return \"Combining Native Sources\"\n    }\n\n    private func collectNativeSources(bundleInfo: CompilationItem.BundleInfo, selectedItems: [SelectedItem<NativeSource>]) -> [SelectedItem<NativeSource>] {\n        let existingItems = self.cachedNativeSourceByModule.data { map in\n            return map[bundleInfo] ?? []\n        }\n\n        var allItems = selectedItems\n        let allItemsByPath = allItems.groupBy { item in\n            return GroupingKey(platform: item.item.platform, groupingIdentifier: item.data.groupingIdentifier)\n        }\n\n        for existingItem in existingItems {\n            let groupingKey = GroupingKey(platform: existingItem.item.platform, groupingIdentifier: existingItem.data.groupingIdentifier)\n            guard allItemsByPath[groupingKey] == nil else { continue }\n\n            allItems.append(existingItem)\n        }\n\n        self.cachedNativeSourceByModule.data { map in\n            map[bundleInfo] = allItems\n        }\n\n        return allItems\n    }\n\n    private func mergeAnySources(files: [FileAndContent]) -> File {\n        var data = \"\"\n\n        for file in files {\n            data +=  \"//\\n// \\(file.filename)\\n//\\n\\n\"\n            data += file.content\n            data += \"\\n\"\n        }\n\n        return .string(data)\n    }\n\n    // Merges .m files and deduplicates static trampoline functions\n    // eg. (`SCValdiFunctionInvoke*`, `SCValdiBlockCreate*`) that are emitted per-type\n    // but end up redefined when multiple types share the same combined file.\n    //\n    // This function works by checking content by line and looking for trampoline function \n    // definitions. The first occurrence of a trampoline function is kept, and subsequent\n    // occurrences are dropped.\n    private func mergeObjcSources(files: [FileAndContent]) -> File {\n        var emittedTrampolineNames = Set<String>()\n        var data = \"\"\n\n        for file in files {\n            data += \"//\\n// \\(file.filename)\\n//\\n\\n\"\n            data += Self.deduplicateTrampolines(in: file.content, emitted: &emittedTrampolineNames)\n            data += \"\\n\"\n        }\n\n        return .string(data)\n    }\n\n    private static func deduplicateTrampolines(in content: String, emitted: inout Set<String>) -> String {\n        let lines = content.components(separatedBy: \"\\n\")\n        var result = [String]()\n        var lineIndex = 0\n\n        while lineIndex < lines.count {\n            let line = lines[lineIndex]\n\n            if let name = trampolineFunctionName(in: line) {\n                // Collect the full function block (including nested braces).\n                var blockLines = [String]()\n                var depth = 0\n                var j = lineIndex\n                while j < lines.count {\n                    let current = lines[j]\n                    blockLines.append(current)\n                    for ch in current {\n                        if ch == Character(\"{\") { depth += 1 }\n                        else if ch == Character(\"}\") { depth -= 1 }\n                    }\n                    j += 1\n                    if depth == 0 && !blockLines.isEmpty { break }\n                }\n\n                if !emitted.contains(name) {\n                    emitted.insert(name)\n                    result.append(contentsOf: blockLines)\n                }\n                // Either way, skip past the block.\n                lineIndex = j\n            } else {\n                result.append(line)\n                lineIndex += 1\n            }\n        }\n\n        return result.joined(separator: \"\\n\")\n    }\n\n    // If the line is the opening of a trampoline function definition, returns\n    // the function name (e.g. `SCValdiFunctionInvokeODDB_v`); otherwise `nil`.\n    private static func trampolineFunctionName(in line: String) -> String? {\n        let prefixes = [\n            \"static SCValdiFieldValue \",\n            \"static id \",\n        ]\n        let markers = [\n            \"SCValdiFunctionInvoke\",\n            \"SCValdiBlockCreate\",\n        ]\n\n        for prefix in prefixes {\n            guard line.hasPrefix(prefix) else { continue }\n            let afterPrefix = line.dropFirst(prefix.count)\n            for marker in markers {\n                guard afterPrefix.hasPrefix(marker) else { continue }\n                // Read the full identifier (letters, digits, underscore) starting at the marker.\n                let identifier = afterPrefix.prefix(while: { $0.isLetter || $0.isNumber || $0 == \"_\" })\n                if !identifier.isEmpty {\n                    return String(identifier)\n                }\n            }\n        }\n        return nil\n    }\n\n    private func mergeCppHeaders(files: [FileAndContent]) -> File {\n        let pragmaOnce = \"#pragma once\"\n        var data = \"\\(pragmaOnce)\\n\"\n\n        for file in files {\n            data +=  \"//\\n// \\(file.filename)\\n//\\n\\n\"\n\n            for line in file.content.split(separator: \"\\n\", omittingEmptySubsequences: false) where line != pragmaOnce {\n                data += line\n                data += \"\\n\"\n            }\n            data += \"\\n\"\n        }\n\n        return .string(data)\n    }\n\n    private func mergeKotlinSources(files: [FileAndContent]) -> File {\n        let writer = CodeWriter()\n        var headerStatements = Set<String>()\n        writer.appendBody(\"\\n\")\n\n        // The following reconstructs a .kt file where package and import statements are de-duplicated\n        // and place at the top of the file.\n        /**\n         The following reconstructs a .kt file where package and import statements are de-duplicated and placed at the top of the file.\n         For example:\n         packge my_package\n         import B\n         import C\n\n         class ClassA {\n         }\n\n         package my_package\n         import B\n\n         class Class B {\n         }\n\n         Would become:\n\n         package my_package\n         import B\n         import C\n\n         class ClassA {\n         }\n\n         class ClassB {\n         }\n         */\n\n        for fileAndContent in files {\n            var inBody = false\n            for line in fileAndContent.content.components(separatedBy: CharacterSet.newlines) {\n                if !inBody {\n                    if line.hasPrefix(\"package \") || line.hasPrefix(\"import \") || line.isEmpty {\n                        if !headerStatements.contains(line) {\n                            headerStatements.insert(line)\n                            writer.appendHeader(line)\n                            writer.appendHeader(\"\\n\")\n                        }\n                    } else {\n                        inBody = true\n                        writer.appendBody(\"//\\n// \\(fileAndContent.filename)\\n//\\n\\n\")\n                    }\n                }\n\n                if inBody {\n                    writer.appendBody(line)\n                    writer.appendBody(\"\\n\")\n                }\n            }\n        }\n\n        return .string(writer.content)\n    }\n\n    private func resolveNativeSourcesOrdering(nativeSources: [SelectedItem<NativeSource>]) -> [SelectedItem<NativeSource>] {\n        guard !nativeSources.isEmpty else { return [] }\n\n        // Build a map from filename to native source index\n        var sourceIndexByFilename = [String: Int]()\n        for (index, source) in nativeSources.enumerated() {\n            sourceIndexByFilename[source.data.filename] = index\n        }\n\n        // Calculate in-degree for each source (count of local dependencies that exist in our set)\n        var inDegree = Array(repeating: 0, count: nativeSources.count)\n        for (index, source) in nativeSources.enumerated() {\n            for dependency in source.data.localFilenameDependencies {\n                if sourceIndexByFilename[dependency] != nil {\n                    inDegree[index] += 1\n                }\n            }\n        }\n\n        // Build reverse dependency map: for each filename, track which indices depend on it\n        var dependentIndices = [String: [Int]]()\n        for (index, source) in nativeSources.enumerated() {\n            for dependency in source.data.localFilenameDependencies {\n                dependentIndices[dependency, default: []].append(index)\n            }\n        }\n\n        // Helper to compare source indices by groupingPriority then filename\n        func isOrderedBefore(_ leftIdx: Int, _ rightIdx: Int) -> Bool {\n            let left = nativeSources[leftIdx]\n            let right = nativeSources[rightIdx]\n            if left.data.groupingPriority != right.data.groupingPriority {\n                return left.data.groupingPriority < right.data.groupingPriority\n            }\n            return left.data.filename < right.data.filename\n        }\n\n        // Initialize available list with all items that have in-degree 0, sorted by priority/filename\n        var available = nativeSources.indices.filter { inDegree[$0] == 0 }.sorted(by: isOrderedBefore)\n\n        var result = [SelectedItem<NativeSource>]()\n        result.reserveCapacity(nativeSources.count)\n\n        // Topological sort: pop best available item, update dependents\n        while let selectedIndex = available.first {\n            available.removeFirst()\n            inDegree[selectedIndex] = -1  // Mark as processed\n            result.append(nativeSources[selectedIndex])\n\n            // Decrement in-degree for all sources that depend on the selected one\n            let filename = nativeSources[selectedIndex].data.filename\n            if let indices = dependentIndices[filename] {\n                for depIdx in indices where inDegree[depIdx] > 0 {\n                    inDegree[depIdx] -= 1\n                    if inDegree[depIdx] == 0 {\n                        // Binary search to find insertion point in sorted available list\n                        var low = 0\n                        var high = available.count\n                        while low < high {\n                            let mid = (low + high) / 2\n                            if isOrderedBefore(available[mid], depIdx) {\n                                low = mid + 1\n                            } else {\n                                high = mid\n                            }\n                        }\n                        available.insert(depIdx, at: low)\n                    }\n                }\n            }\n        }\n\n        // Handle cycles: add remaining items sorted by priority/filename\n        if result.count < nativeSources.count {\n            let remainingIndices = nativeSources.indices.filter { inDegree[$0] >= 0 }\n            let sortedRemaining = remainingIndices.sorted(by: isOrderedBefore)\n            for idx in sortedRemaining {\n                result.append(nativeSources[idx])\n            }\n        }\n\n        return result\n    }\n\n    private func doCombineNativeSources(filename: String,\n                                        bundleInfo: CompilationItem.BundleInfo,\n                                        platform: Platform?,\n                                        nativeSources: [SelectedItem<NativeSource>]) -> CompilationItem {\n        let sortedNativeSources = resolveNativeSourcesOrdering(nativeSources: nativeSources)\n\n        var relativePath: String?\n        var firstItemSettingRelativePath: CompilationItem?\n\n        var isKotlin = false\n        var isCppHeader = false\n        var fileAndContentArray = [FileAndContent]()\n\n        for nativeSource in sortedNativeSources {\n            do {\n                if relativePath != nativeSource.data.relativePath {\n                    if let relativePath {\n                        return nativeSource.item.with(error: CompilerError(\"Modules with single_file_codegen enabled must have generated files output to the same directory or package. Found '\\(relativePath)' from emitting file '\\(firstItemSettingRelativePath?.relativeProjectPath ?? \"<null>\")' vs '\\(nativeSource.data.relativePath ?? \"<null>\")' from emitting file '\\(nativeSource.item.relativeProjectPath)'\"))\n                    }\n                    relativePath = nativeSource.data.relativePath\n                    firstItemSettingRelativePath = nativeSource.item\n                }\n                if nativeSource.data.filename.hasSuffix(\".kt\") {\n                    isKotlin = true\n                } else if nativeSource.data.filename.hasSuffix(\".hpp\") {\n                    isCppHeader = true\n                }\n                let nativeSourceContent = try nativeSource.data.file.readString()\n                fileAndContentArray.append(FileAndContent(filename: nativeSource.data.filename, content: nativeSourceContent))\n            } catch let error {\n                return nativeSource.item.with(error: error)\n            }\n        }\n\n        let generatedNativeSource: NativeSource\n        if isKotlin {\n            let file = mergeKotlinSources(files: fileAndContentArray)\n            generatedNativeSource = NativeSource(relativePath: nil, filename: filename, file: file, groupingIdentifier: filename, groupingPriority: 0)\n        } else if isCppHeader {\n            let file = mergeCppHeaders(files: fileAndContentArray)\n            generatedNativeSource = NativeSource(relativePath: relativePath, filename: filename, file: file, groupingIdentifier: filename, groupingPriority: 0)\n        } else if filename.hasSuffix(\".m\") {\n            let file = mergeObjcSources(files: fileAndContentArray)\n            generatedNativeSource = NativeSource(relativePath: relativePath, filename: filename, file: file, groupingIdentifier: filename, groupingPriority: 0)\n        } else {\n            let file = mergeAnySources(files: fileAndContentArray)\n            generatedNativeSource = NativeSource(relativePath: relativePath, filename: filename, file: file, groupingIdentifier: filename, groupingPriority: 0)\n        }\n\n        return CompilationItem(sourceURL: bundleInfo.baseDir,\n                               relativeProjectPath: nil,\n                               kind: .nativeSource(generatedNativeSource),\n                               bundleInfo: bundleInfo,\n                               platform: platform,\n                               outputTarget: .all)\n    }\n\n    private func makeEmptySource(bundle: CompilationItem.BundleInfo, filename: String, platform: Platform, relativePath: String? = nil) -> CompilationItem {\n        let nativeSource = NativeSource(relativePath: relativePath, filename: filename, file: .string(\"\"), groupingIdentifier: filename, groupingPriority: 0)\n        return CompilationItem(generatedFromBundleInfo: bundle, kind: .nativeSource(nativeSource), platform: platform, outputTarget: .all)\n    }\n\n    private func generateEmptySourcesIfNeeded(bundle: CompilationItem.BundleInfo,\n                                              matchedItems: [SelectedItem<NativeSource>]) -> [CompilationItem] {\n        var output = [CompilationItem]()\n        let hasKotlin = matchedItems.contains(where: { $0.data.filename.hasSuffix(\".kt\") })\n        let hasSwift = matchedItems.contains(where: { $0.data.filename.hasSuffix(\".swift\") })\n        let hasObjectiveC = matchedItems.contains(where: { $0.data.filename.hasSuffix(\".m\") })\n        let hasCpp = matchedItems.contains(where: { $0.data.filename.hasSuffix(\".cpp\") })\n\n        if bundle.androidCodegenEnabled && !hasKotlin {\n            output.append(makeEmptySource(bundle: bundle, filename: \"\\(bundle.name).kt\", platform: .android))\n        }\n\n        if bundle.iosCodegenEnabled && bundle.iosLanguage == .objc && !hasObjectiveC {\n            do {\n                let iosType = IOSType(name: \"Empty\", bundleInfo: bundle, kind: .class, iosLanguage: .objc)\n                let nativeSources = try NativeSource.iosNativeSourcesFromGeneratedCode(GeneratedCode(apiHeader: CodeWriter(),\n                                                                                                     apiImpl: CodeWriter(),\n                                                                                                     header: CodeWriter(),\n                                                                                                     impl: CodeWriter()),\n                                                                                       iosType: iosType, bundleInfo: bundle)\n\n                output += nativeSources.map {\n                    NativeSource(relativePath: $0.relativePath, filename: $0.groupingIdentifier, file: $0.file, groupingIdentifier: $0.groupingIdentifier, groupingPriority: $0.groupingPriority)\n                }\n                .map {\n                    CompilationItem(generatedFromBundleInfo: bundle, kind: .nativeSource($0), platform: .ios, outputTarget: .all)\n                }\n            } catch let error {\n                output.append(CompilationItem(generatedFromBundleInfo: bundle, kind: .error(error, originalItemKind: .moduleYaml(.url(bundle.baseDir))), platform: .android, outputTarget: .all))\n            }\n        }\n\n        if bundle.iosCodegenEnabled && bundle.iosLanguage == .swift && !hasSwift {\n            output.append(makeEmptySource(bundle: bundle, filename: \"\\(bundle.iosModuleName).swift\", platform: .ios))\n        }\n\n        if bundle.cppCodegenEnabled && !hasCpp {\n            let relativePath: String\n            if let cppImportPathPrefix = projectConfig.cppImportPathPrefix {\n                relativePath = \"\\(cppImportPathPrefix)\\(bundle.name)\"\n            } else {\n                relativePath = bundle.name\n            }\n            output.append(makeEmptySource(bundle: bundle, filename: \"\\(bundle.name).cpp\", platform: .cpp, relativePath: relativePath))\n            output.append(makeEmptySource(bundle: bundle, filename: \"\\(bundle.name).hpp\", platform: .cpp, relativePath: relativePath))\n        }\n\n        return output\n    }\n\n\n    private func combineNativeSources(selectedItems: [SelectedItem<NativeSource>]) -> [CompilationItem] {\n        let selectedItemsByBundleInfo = selectedItems.groupBy { item in\n            return item.item.bundleInfo\n        }\n\n        var output = [CompilationItem]()\n\n        for (bundleInfo, selectedItems) in selectedItemsByBundleInfo {\n            let nativeSources = self.collectNativeSources(bundleInfo: bundleInfo, selectedItems: selectedItems)\n\n            let nativeSourcesByRelativePath = nativeSources.groupBy { nativeSource in\n                return GroupingKey(platform: nativeSource.item.platform, groupingIdentifier: nativeSource.data.groupingIdentifier)\n            }\n\n            for (groupingKey, nativeSources) in nativeSourcesByRelativePath {\n                output.append(doCombineNativeSources(filename: groupingKey.groupingIdentifier,\n                                                     bundleInfo: bundleInfo,\n                                                     platform: groupingKey.platform,\n                                                     nativeSources: nativeSources))\n            }\n        }\n\n        // Generate dummy empty sources if --only-generate-native-code-for-modules is specified\n        // and nothing was generated.\n        for moduleName in compilerConfig.onlyGenerateNativeCodeForModules {\n            guard let bundle = try? bundleManager.getBundleInfo(forName: moduleName), bundle.singleFileCodegen else { continue }\n\n            let existingItems = selectedItemsByBundleInfo[bundle, default: []]\n\n            output += generateEmptySourcesIfNeeded(bundle: bundle, matchedItems: existingItems)\n        }\n\n        return output\n    }\n\n    private func shouldProcessItem(item: CompilationItem) -> Bool {\n        return shouldProcessBundle(bundle: item.bundleInfo)\n    }\n\n    private func shouldProcessBundle(bundle: CompilationItem.BundleInfo) -> Bool {\n        guard bundle.singleFileCodegen else { return false }\n        guard !compilerConfig.onlyGenerateNativeCodeForModules.isEmpty else {\n            return true\n        }\n        return compilerConfig.onlyGenerateNativeCodeForModules.contains(bundle.name)\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { item -> NativeSource? in\n            guard case .nativeSource(let nativeSource) = item.kind, shouldProcessItem(item: item) else {\n                return nil\n            }\n\n            return nativeSource\n        }.transformAll(self.combineNativeSources(selectedItems:))\n    }\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/CompileDocumentsProcessor.swift",
    "content": "//\n//  CompileDocumentsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport SWXMLHash\nimport SwiftSoup\n\nprivate extension CompilationItem {\n    var documentNameFromSourceURL: String {\n        return sourceURL.deletingPathExtension().lastPathComponent\n    }\n}\n\n// [.parsedDocument, .css] -> [.document, .invalidDocument, .typeScript]\nfinal class CompileDocumentsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Compiling Documents\"\n    }\n\n    private let logger: ILogger\n    private var projectClassMappingManager: ProjectClassMappingManager\n    private let userScriptManager: UserScriptManager\n    private let fileDependenciesManager: FileDependenciesManager\n\n    init(logger: ILogger, projectClassMappingManager: ProjectClassMappingManager, userScriptManager: UserScriptManager, fileDependenciesManager: FileDependenciesManager) {\n        self.logger = logger\n        self.projectClassMappingManager = projectClassMappingManager\n        self.userScriptManager = userScriptManager\n        self.fileDependenciesManager = fileDependenciesManager\n    }\n\n    private func compile(item: CompilationItem, template: ValdiRawTemplate, actions: [ValdiAction], viewModel: ValdiModel?, classMapping: ResolvedClassMapping, documentContent: String) throws -> TemplateCompilerResult {\n        let templateCompiler = ValdiTemplateCompiler(template: template, viewModel: viewModel, classMapping: classMapping, actions: actions, compileIOS: true, compileAndroid: true, documentContent: documentContent)\n        return try templateCompiler.compile()\n    }\n\n    private func getComponentPath(item: CompilationItem) -> ComponentPath {\n        // TODO(simon): Remove this hack\n        return ComponentPath(fileName: \"\\(item.relativeProjectPath).generated\", exportedMember: \"ComponentClass\")\n    }\n\n    private func resolveClassMapping(item: CompilationItem, rawDocument: ValdiRawDocument) throws {\n        if let rootNode = rawDocument.template?.rootNode {\n            let rootNodeType = rootNode.nodeType\n            let isLayout = rootNode.isLayout ?? true\n\n            let rootClassMapping = rawDocument.classMapping?.nodeMappingByClass[rootNodeType]\n\n            let viewPath = getComponentPath(item: item)\n\n            do {\n                try projectClassMappingManager.mutate { (classMapping) in\n                    // TODO(simon): Remove this hack\n                    let rootClass: ValdiClass\n                    if isLayout {\n                        rootClass = try classMapping.resolveClass(nodeType: \"Layout\", currentBundle: item.bundleInfo, localMapping: nil)\n                    } else {\n                        rootClass = try classMapping.resolveClass(nodeType: \"View\", currentBundle: item.bundleInfo, localMapping: nil)\n                    }\n\n                    try classMapping.register(bundle: item.bundleInfo,\n                                              nodeType: rootNodeType,\n                                              valdiViewPath: viewPath,\n                                              iosType: rootClassMapping?.iosType,\n                                              androidClassName: rootClassMapping?.androidClassName,\n                                              jsxName: rootClass.jsxName,\n                                              isLayout: isLayout,\n                                              sourceFilePath: item.relativeBundleURL.path)\n                }\n            } catch let error {\n                throw CompilerError(type: \"ClassMapping Error\", message: error.legibleLocalizedDescription, atZeroIndexedLine: rootNode.lineNumber, column: rootNode.columnNumber, inDocument: rawDocument.content)\n            }\n        }\n    }\n\n    private func resolveClassMapping(selectedItem: SelectedItem<File>) throws {\n        try resolveClassMapping(item: selectedItem.item, classMappingXMLFile: selectedItem.data)\n    }\n\n    private func resolveClassMapping(item: CompilationItem, classMappingXMLFile: File) throws {\n        let parser = SwiftSoup.Parser.xmlParser()\n        parser.settings(.preserveCase)\n        parser.setTrackErrors(16)\n\n        let xml = try parser.parseInput(try classMappingXMLFile.readString(), \"\")\n\n        guard let rootElement = xml.children().first(), rootElement.tagName() == \"class-mapping\" else {\n            throw CompilerError(\"Root element of a class mapping file should be 'class-mapping'\")\n        }\n\n        let localClassMapping = try ValdiDocumentParser.parseClassMapping(classMappingElement: rootElement, iosImportPrefix: item.bundleInfo.iosModuleName)\n        try projectClassMappingManager.mutate { (classMapping) in\n            for (nodeType, mapping) in localClassMapping.nodeMappingByClass {\n                try classMapping.register(bundle: item.bundleInfo, nodeType: nodeType, valdiViewPath: nil, iosType: mapping.iosType, androidClassName: mapping.androidClassName, jsxName: nil, isLayout: false, isSlot: false, sourceFilePath: item.relativeBundleURL.path)\n            }\n        }\n    }\n\n    private func compile(item: CompilationItem, rawDocument: ValdiRawDocument) -> [CompilationItem] {\n        let inputURL = item.sourceURL\n        logger.debug(\"-- Compiling Document \\(inputURL.lastPathComponent)\")\n        do {\n            guard let template = rawDocument.template else {\n                throw CompilerError(\"No template found in this document\")\n            }\n\n            let projectClassMapping = projectClassMappingManager.copyProjectClassMapping()\n            let resolvedMapping = ResolvedClassMapping(localClassMapping: rawDocument.classMapping,\n                                                       projectClassMapping: projectClassMapping,\n                                                       currentBundle: item.bundleInfo)\n\n            let compiledTemplate = try compile(item: item,\n                                               template: template,\n                                               actions: rawDocument.actions,\n                                               viewModel: rawDocument.viewModel,\n                                               classMapping: resolvedMapping,\n                                               documentContent: rawDocument.content)\n\n            var out = [CompilationItem]()\n\n            let scriptLang = FileExtensions.typescript\n\n            let userScriptURL = userScriptManager.findUserScriptURL(documentSourceURL: inputURL)\n\n            let componentPath = getComponentPath(item: item)\n\n            let compilationResult = CompilationResult(\n                componentPath: componentPath,\n                originalDocument: rawDocument,\n                templateResult: compiledTemplate,\n                classMapping: resolvedMapping,\n                userScriptSourceURL: userScriptURL,\n                scriptLang: scriptLang,\n                symbolsToImportsInGeneratedCode: [])\n\n            out.append(item.with(newKind: .document(compilationResult)))\n\n            return out\n        } catch let error {\n            logger.error(\"Failed to compile document \\(inputURL): \\(error.legibleLocalizedDescription)\")\n            return [item.with(error: error)]\n        }\n    }\n\n    private func compile(selectedItem: SelectedItem<ValdiRawDocument>) throws -> [CompilationItem] {\n        return compile(item: selectedItem.item, rawDocument: selectedItem.data)\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        // First resolve the class mappings\n\n       try items.select { (item) in\n            switch item.kind {\n            case .classMapping(let file):\n                return file\n            default:\n                return nil\n            }\n        }.processEachConcurrently(resolveClassMapping)\n\n        var filteredItems = [CompilationItem]()\n\n        for item in items.allItems {\n            switch item.kind {\n            case .classMapping:\n                break\n            case .css:\n                // css files get injected into the parsed documents directly.\n                break\n            case .parsedDocument(let parsedDocument):\n                do {\n                    try resolveClassMapping(item: item, rawDocument: parsedDocument)\n                    filteredItems.append(item)\n                } catch let error {\n                    filteredItems.append(item.with(error: error))\n                }\n            default:\n                filteredItems.append(item)\n            }\n        }\n\n        return try CompilationItems(compileSequence: items.compileSequence, items: filteredItems).select {\n            if case .parsedDocument(let parsedDocument) = $0.kind {\n                return parsedDocument\n            } else {\n                return nil\n            }\n        }.transformEachConcurrently(compile)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/CompileTypeScriptProcessor.swift",
    "content": "//\n//  CompileTypeScriptProcessor.swift\n//  Compiler\n//\n//  Created by saniul on 13/06/2019.\n//\n\nimport Foundation\n\nfinal class CompileTypeScriptProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Compiling TypeScript\"\n    }\n\n    private let typeScriptCompilerManager: TypeScriptCompilerManager\n    private let compilerConfig: CompilerConfig\n\n    init(typeScriptCompilerManager: TypeScriptCompilerManager, compilerConfig: CompilerConfig) {\n        self.typeScriptCompilerManager = typeScriptCompilerManager\n        self.compilerConfig = compilerConfig\n    }\n\n    struct ComponentPathData {\n        let componentClass: String\n        let componentPath: ComponentPath\n    }\n\n    private func injectComponentPaths(selectedItem: SelectedItem<(JavaScriptFile, ComponentPathData)>) throws -> CompilationItem {\n        var jsContent = try selectedItem.data.0.file.readString()\n\n        let stringToInsert =  \"\\n\\(selectedItem.data.1.componentClass).componentPath = \\\"\\(selectedItem.data.1.componentPath.stringRepresentation)\\\";\\n\"\n\n        let insertionIndex = jsContent.range(of: SourceMapProcessor.sourceMapPrefix)?.lowerBound ?? jsContent.endIndex\n        jsContent.insert(contentsOf: stringToInsert, at: insertionIndex)\n\n        let modifiedJsContent = try jsContent.utf8Data()\n\n        return selectedItem.item.with(newKind: .javaScript(selectedItem.data.0.with(file: .data(modifiedJsContent))))\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        // We add a Valdi.ignore.ts file to the root of valdi_modules, so that we can get the TypeScript compiler\n        // to open and parse any .d.ts files we specify. Unfortunately, the TypeScript compiler does not pick up\n        // projects that only specify .d.ts files.\n        //\n        // ignore files ending in .ignore.ts\n        let selectedItems = items.allItems.filter { !$0.sourceURL.lastPathComponent.hasSuffix(\".ignore.ts\") }\n\n        // compile the TS files\n        let generatedResult = try typeScriptCompilerManager.compileItems(compileSequence: items.compileSequence,\n                                                                         items: selectedItems,\n                                                                         onlyCompileTypeScriptForModules: compilerConfig.onlyCompileTypeScriptForModules)\n\n        var out = CompilationItems(compileSequence: items.compileSequence, items: generatedResult.outItems)\n\n        // inject the componentPath into all components, so that we can retrieve them within JS\n\n        // Associate component name by which files they live in\n        let componentNameByScriptURL =  out.allItems.compactMap { (item) -> (URL, ComponentPathData)? in\n            if case .document(let result) = item.kind {\n                if let userScriptSourceURL = result.userScriptSourceURL, let componentClass = result.originalDocument.template?.jsComponentClass {\n                    return (userScriptSourceURL, ComponentPathData(componentClass: componentClass, componentPath: result.componentPath))\n                }\n            }\n            return nil\n        }.associate { keyVal -> (URL, ComponentPathData) in\n            return keyVal\n        }\n\n        out = try out.select { (item) -> (JavaScriptFile, ComponentPathData)? in\n            guard let componentName = componentNameByScriptURL[item.sourceURL] else { return nil }\n\n            if case .javaScript(let file) = item.kind {\n                return (file, componentName)\n            }\n\n            return nil\n        }.transformEachConcurrently(injectComponentPaths)\n\n        return out\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/DiagnosticsProcessor.swift",
    "content": "//\n//  DiagnosticsProcessor.swift\n//  Compiler\n//\n//  Created by saniul on 19/07/2019.\n//\n\nimport Foundation\n\n// Collates all the diagnostics generated for a given source file together.\n// Outputs a File that can then be emitted in the final output.\n//\n// At the moment we only have GeneratedTypeDescription diagnostics,\n// but if we had more, this Processor is where we would collate all the diagnostics that are\n// relevant to a given source file, and put them in a common structure.\nclass DiagnosticsProcessor: CompilationProcessor {\n\n    let projectConfig: ValdiProjectConfig\n\n    var description: String {\n        return \"Summarizing Diagnostics by Source File\"\n    }\n\n    init(projectConfig: ValdiProjectConfig) {\n        self.projectConfig = projectConfig\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        guard projectConfig.shouldEmitDiagnostics else {\n            return items\n        }\n\n        return items.select { (item) -> GeneratedTypeDescription? in\n            if case let .generatedTypeDescription(generatedTypeDescription) = item.kind {\n                return generatedTypeDescription\n            }\n            return nil\n            }.groupBy { selectedItem -> String in\n                selectedItem.item.relativeProjectPath\n            }.transformEachConcurrently { groupedItems -> CompilationItem in\n                let relativeSourceFilePath = groupedItems.key\n                let descriptions = groupedItems.items.map { $0.data }.sorted { $0.valueToSortBy < $1.valueToSortBy }\n                let summary = GeneratedTypesSummary(sourceFilePath: relativeSourceFilePath,\n                                                    generatedTypes: descriptions)\n                let anyItem = groupedItems.items[0]\n\n                let file = summary.toFile()\n\n                return anyItem.item.with(newKind: .diagnosticsFile(file),\n                                         newPlatform: .none)\n            }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/DocumentUserScriptExtractionProcessor.swift",
    "content": "//\n//  DocumentUserScriptExtraction.swift\n//  Compiler\n//\n//  Created by saniul on 16/06/2019.\n//\n\nimport Foundation\n\nfinal class DocumentUserScriptExtractionProcessor: CompilationProcessor {\n    let userScriptManager: UserScriptManager\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n\n    init(logger: ILogger, fileManager: ValdiFileManager, userScriptManager: UserScriptManager, projectConfig: ValdiProjectConfig) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.userScriptManager = userScriptManager\n        self.projectConfig = projectConfig\n    }\n\n    var description: String {\n        return \"Extracting user scripts from Documents\"\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return try items.select {\n            if case .parsedDocument(let parsedDocument) = $0.kind {\n                return parsedDocument\n            } else {\n                return nil\n            }\n            }.transformEachConcurrently(compile)\n    }\n\n    private func compile(selectedItem: SelectedItem<ValdiRawDocument>) throws -> [CompilationItem] {\n        return compile(item: selectedItem.item, rawDocument: selectedItem.data)\n    }\n\n    private func compile(item: CompilationItem, rawDocument: ValdiRawDocument) -> [CompilationItem] {\n        let inputURL = item.sourceURL\n        logger.debug(\"-- Extracting user scripts from Document \\(inputURL.lastPathComponent)\")\n        do {\n            var out: [CompilationItem] = [item]\n\n            if let result = try userScriptManager.processUserScript(documentItem: item, rawDocument: rawDocument),\n                let emitUserScriptItem = result.emitScriptCompilationItem {\n                // Store the extracted file in the generatedTsDirectory so that we get autocompletion in VSCode\n                let definitionURL = projectConfig.generatedTsDirectoryURL.appendingPathComponent(emitUserScriptItem.relativeProjectPath)\n                try fileManager.save(file: result.userScript.content, to: definitionURL)\n\n                out.append(emitUserScriptItem)\n            }\n\n            return out\n        } catch let error {\n            logger.error(\"Failed to extract user scripts from Document \\(inputURL): \\(error.legibleLocalizedDescription)\")\n            return [item.with(error: error)]\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/DumpCompilationMetadataProcessor.swift",
    "content": "import Foundation\n\nclass DumpCompilationMetadataProcessor: CompilationProcessor {\n\n    let projectConfig: ValdiProjectConfig\n    let compilerConfig: CompilerConfig\n    let projectClassMappingManager: ProjectClassMappingManager\n\n    var description: String {\n        return \"Dumping compilation metadata\"\n    }\n\n    private let typeScriptCompilationManager: TypeScriptCompilerManager\n    private let typeScriptNativeTypeResolver: TypeScriptNativeTypeResolver\n\n    init(projectConfig: ValdiProjectConfig, compilerConfig: CompilerConfig, projectClassMappingManager: ProjectClassMappingManager, typeScriptCompilationManager: TypeScriptCompilerManager, typeScriptNativeTypeResolver: TypeScriptNativeTypeResolver) {\n        self.projectConfig = projectConfig\n        self.compilerConfig = compilerConfig\n        self.projectClassMappingManager = projectClassMappingManager\n        self.typeScriptCompilationManager = typeScriptCompilationManager\n        self.typeScriptNativeTypeResolver = typeScriptNativeTypeResolver\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let resolvedMappings = projectClassMappingManager.copyProjectClassMapping().copyMappings()\n        let nativeTypes =  typeScriptNativeTypeResolver.serialize()\n\n        let encoder = JSONEncoder()\n        encoder.outputFormatting = .sortedKeys\n\n        let selectedItems = items.select { item -> ([String: ValdiClass], SerializedTypeScriptNativeTypeResolver)? in\n            guard case .moduleYaml = item.kind, !compilerConfig.onlyFocusProcessingForModules.isEmpty && compilerConfig.onlyFocusProcessingForModules.contains(item.bundleInfo.name) else {\n                return nil\n            }\n            let resolvedMappingsForModule = resolvedMappings.filter { (_, v) in\n                v.sourceModuleName == item.bundleInfo.name\n            }\n\n            let filteredEntries = nativeTypes.entries.filter { entry in\n                entry.emittingBundleName == item.bundleInfo.name\n            }\n\n            let resolvedTypeResolverForModule = SerializedTypeScriptNativeTypeResolver(entries: filteredEntries)\n\n            return (resolvedMappingsForModule, resolvedTypeResolverForModule)\n        }\n\n        let transformed = try selectedItems.transformEach { selectedItem in\n            let item = selectedItem.item\n            let (resolvedMappingsFromModule, resolvedTypeResolverForModule) = selectedItem.data\n            let compilationMetadata = CompilationMetadata(classMappings: resolvedMappingsFromModule, nativeTypes: resolvedTypeResolverForModule)\n\n            let encoded = try encoder.encode(compilationMetadata)\n            let file = File.data(encoded)\n\n            return [item, item.with(newKind: .compilationMetadata(file))]\n        }\n\n        return transformed\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/DumpComponentsProcessor.swift",
    "content": "//\n//  DumpComponentsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 1/14/19.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// passthrough\nclass DumpComponentsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Dumping Components\"\n    }\n\n    private let outFileURLs: [URL]\n\n    init(outFileURLs: [URL]) {\n        self.outFileURLs = outFileURLs\n    }\n\n    private func dumpIOSType(iosType: IOSType) -> [String: Any] {\n        return [\n            \"class\": iosType.name,\n            \"import_statement\": \"#import \\(iosType.importHeaderStatement)\"\n        ]\n    }\n\n    private func dumpAndroidClass(androidClassName: String) -> [String: Any] {\n        let jvmClass = JVMClass(fullClassName: androidClassName)\n\n        var out: [String: Any] = [\n            \"class\": jvmClass.name,\n            \"full_class\": androidClassName\n        ]\n\n        if let package = jvmClass.package {\n            out[\"import_statement\"] = \"import \\(package).\\(jvmClass.name)\"\n        }\n\n        return out\n    }\n\n    private func dumpComponent(result: CompilationResult, item: CompilationItem) -> [String: Any] {\n        let rootNodeType = result.originalDocument.template?.rootNode?.nodeType ?? \"\"\n\n        let iosView = IOSType(name: result.templateResult.rootElement.iosViewClass ?? \"\",\n                              bundleInfo: item.bundleInfo,\n                              kind: .class,\n                              iosLanguage: item.bundleInfo.iosLanguage)\n\n        var out: [String: Any] = [\n            \"relative_path\": item.relativeBundleURL.path,\n            \"ios_view\": dumpIOSType(iosType: iosView),\n            \"android_view\": dumpAndroidClass(androidClassName: result.templateResult.rootElement.androidViewClass ?? \"\")\n        ]\n        if let rootViewNodeMapping = result.originalDocument.classMapping?.nodeMappingByClass[rootNodeType] {\n            if let iosType = rootViewNodeMapping.iosType {\n                out[\"ios_view\"] = dumpIOSType(iosType: iosType)\n            }\n            if let androidClass = rootViewNodeMapping.androidClassName {\n                out[\"android_view\"] = dumpAndroidClass(androidClassName: androidClass)\n            }\n        }\n\n        if let componentContextIOSType = result.originalDocument.componentContext?.iosType {\n            out[\"ios_context\"] = dumpIOSType(iosType: componentContextIOSType)\n        }\n        if let componentContextAndroidClass = result.originalDocument.componentContext?.androidClassName {\n            out[\"android_context\"] = dumpAndroidClass(androidClassName: componentContextAndroidClass)\n        }\n\n        if let viewModel = result.originalDocument.viewModel {\n            if let viewModelIOSType = viewModel.iosType {\n                out[\"ios_view_model\"] = dumpIOSType(iosType: viewModelIOSType)\n            }\n            if let androidViewModelClass = viewModel.androidClassName {\n                out[\"android_view_model\"] = dumpAndroidClass(androidClassName: androidViewModelClass)\n            }\n        }\n\n        return out\n    }\n\n    private func processDocuments(selectedItems: [SelectedItem<CompilationResult>]) throws -> [CompilationItem] {\n        var out = [[String: Any]]()\n\n        let itemsByBundleName = selectedItems.groupBy { (item) -> String in\n            return item.item.bundleInfo.name\n        }\n\n        for (bundle, items) in itemsByBundleName {\n            let outItems = items.map {\n                dumpComponent(result: $0.data, item: $0.item)\n            }\n\n            out.append([\n                \"bundle\": bundle,\n                \"path\": items[0].item.bundleInfo.baseDir.path,\n                \"components\": outItems])\n        }\n\n        let jsonData = try JSONSerialization.data(withJSONObject: out, options: .prettyPrinted)\n\n        for url in outFileURLs {\n            try jsonData.write(to: url)\n        }\n\n        return selectedItems.map { $0.item }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return try items.select { (item) -> CompilationResult? in\n            switch item.kind {\n            case .document(let result):\n                return result\n            default:\n                return nil\n            }\n        }.transformAll(processDocuments)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/DumpTypeScriptSymbolsProcessor.swift",
    "content": "//\n//  ParseTypeScriptAnnotationsProcessor.swift\n//  Compiler\n//\n//  Created by saniul on 13/06/2019.\n//\n\nimport Foundation\n\nstruct DumpedTypeScriptSymbolsResult {\n    let typeScriptItemAndSymbols: TypedScriptItemAndSymbols\n}\n\nfinal class DumpTypeScriptSymbolsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Checking TypeScript and Dumping Symbols\"\n    }\n\n    private let logger: ILogger\n    private let typeScriptCompilerManager: TypeScriptCompilerManager\n    private let compilerConfig: CompilerConfig\n    private let skipTypeChecking: Bool\n\n    init(logger: ILogger, typeScriptCompilerManager: TypeScriptCompilerManager, compilerConfig: CompilerConfig, skipTypeChecking: Bool = false) {\n        self.logger = logger\n        self.typeScriptCompilerManager = typeScriptCompilerManager\n        self.compilerConfig = compilerConfig\n        self.skipTypeChecking = skipTypeChecking\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let userResult: TypeScriptCompilationResult\n        \n        if skipTypeChecking {\n            // In regenerate mode, skip type checking since generated files may not exist\n            // Just prepare items and open files without checking\n            userResult = try typeScriptCompilerManager.prepareItemsForSymbolDumping(compileSequence: items.compileSequence,\n                                                                                     items: items.allItems,\n                                                                                     onlyCompileTypeScriptForModules: compilerConfig.onlyCompileTypeScriptForModules)\n        } else {\n            // Full type checking in normal compilation mode\n            userResult = try typeScriptCompilerManager.checkItems(compileSequence: items.compileSequence,\n                                                                   items: items.allItems,\n                                                                   onlyCompileTypeScriptForModules: compilerConfig.onlyCompileTypeScriptForModules)\n        }\n\n        // parse the TS file annotations\n        let typeScriptItems = userResult.typeScriptItems\n        let filteredTypeScriptItems = typeScriptItems.filter { !$0.item.bundleInfo.disableAnnotationProcessing }\n        let outItems = try dumpSymbols(typescriptItems: filteredTypeScriptItems, items: userResult.outItems)\n\n        return CompilationItems(compileSequence: items.compileSequence, items: outItems)\n    }\n\n    private func dumpSymbols(typescriptItems: [TypeScriptItem], items: [CompilationItem]) throws -> [CompilationItem] {\n        logger.info(\"Getting TypeScript comments...\")\n        let dumpAllSymbolsResult = try typeScriptCompilerManager.dumpAllSymbols(typescriptItems: typescriptItems)\n\n        let dumpedSymbolsItems = dumpAllSymbolsResult.typeScriptItemsAndSymbols.map { typeScriptItemAndSymbols in\n            return typeScriptItemAndSymbols.typeScriptItem.item.with(newKind: .dumpedTypeScriptSymbols(DumpedTypeScriptSymbolsResult(typeScriptItemAndSymbols: typeScriptItemAndSymbols)))\n        }\n        return items + dumpedSymbolsItems\n    }\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/FilterItemsProcessor.swift",
    "content": "//\n//  FilterItemsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/26/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.unknown] -> [.unknown]\nclass FilterItemsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Filtering items\"\n    }\n\n    private let modulesFilter: ModulesFilter?\n    private let hotreloadingEnabled: Bool\n\n    init(modulesFilter: ModulesFilter?, hotreloadingEnabled: Bool = false) {\n        self.modulesFilter = modulesFilter\n        self.hotreloadingEnabled = hotreloadingEnabled\n    }\n\n    private func resolveInclusion(item: CompilationItem) -> Bool {\n        if let modulesFilter = modulesFilter {\n            if !modulesFilter.shouldIncludeInInput(bundleInfo: item.bundleInfo) {\n                return false\n            }\n        }\n\n        if (self.hotreloadingEnabled) {\n            // Verify that compilationItem path relative to its bundle does not begin by exiting the bundle\n            // when hotreloading\n            let sourceURLToResolve = (try? item.sourceURL.resolvingSymlink()) ?? item.sourceURL\n            let itemBundleRelativePath = RelativePath(from: item.bundleInfo.baseDir, to: sourceURLToResolve)\n            if let firstPathComponent = itemBundleRelativePath.components.first, firstPathComponent == \"..\" {\n                return false\n            }\n        }\n\n        if item.sourceURL.lastPathComponent.starts(with: \".\") {\n            return false\n        }\n\n        let path = item.sourceURL.path\n        switch item.bundleInfo.inclusionConfig.resolve(path) {\n            case .included:\n                return true\n            case .excluded:\n                return false\n            case .unknown:\n                return true\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.selectAll().transformEachConcurrently { (item) -> [CompilationItem] in\n            if resolveInclusion(item: item) {\n                return [item]\n            }\n            return []\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/FinalFilesVerificationProcessor.swift",
    "content": "//\n//  FinalFilesVerificationProcessor.swift\n//  Compiler\n//\n//  Created by saniul on 25/07/2019.\n//\n\nimport Foundation\n\nclass FinalFilesVerificationProcessor: CompilationProcessor {\n\n    private let logger: ILogger\n    let projectConfig: ValdiProjectConfig\n\n    init(logger: ILogger, projectConfig: ValdiProjectConfig) {\n        self.logger = logger\n        self.projectConfig = projectConfig\n    }\n\n    var description: String {\n        return \"Verifying final files before saving\"\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        var alreadyEncountered: [URL: [CompilationItem]] = [:]\n        var urlsWithMultipleFinalFiles: Set<URL> = []\n\n        for item in items.allItems {\n            guard case let .finalFile(finalFile) = item.kind else {\n                throw CompilerError(\"Final verification failed: Only .finalFiles are expected\")\n            }\n\n            if alreadyEncountered.keys.contains(finalFile.outputURL) {\n                urlsWithMultipleFinalFiles.insert(finalFile.outputURL)\n            }\n            alreadyEncountered[finalFile.outputURL] = alreadyEncountered[finalFile.outputURL, default: []] + [item]\n        }\n\n        guard !urlsWithMultipleFinalFiles.isEmpty else {\n            // All good\n\n            return items\n        }\n\n        logger.error(\"🚨 Multiple .finalFile items writing to the same output URL 🚨\")\n        logger.error(\"(This may mean that you have multiple annotated TypeScript types generating the same native type)\")\n        for (urlIndex, urlWithDupes) in urlsWithMultipleFinalFiles.enumerated() {\n            logger.error(\"\\(urlIndex+1). Output URL: \\(urlWithDupes.relativePath(from: projectConfig.baseDir)):\")\n            let items = alreadyEncountered[urlWithDupes, default: []]\n\n            for item in items {\n                logger.error(\"-- Source URL: \\(item.sourceURL.relativePath(from: projectConfig.baseDir)), Output platform: \\(item.platform?.rawValue ?? \"<none>\"), Output target: \\(item.outputTarget.description)\")\n            }\n        }\n        throw CompilerError(\"Multiple final files writing to the same output URL\")\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GenerateAssetCatalogProcessor.swift",
    "content": "//\n//  GenerateAssetCatalogProcessor.swift\n//  \n//\n//  Created by Simon Corsin on 2/13/20.\n//\n\nimport Foundation\n\nstruct AssetCatalogEntry {\n    let projectRelativeDirectoryPath: String\n    let virtualPath: String\n    let image: ImageAsset?\n    let font: FontAsset?\n}\n\nstruct AssetCatalogTypes {\n    static let image: UInt32 = 1\n    static let font: UInt32 = 2\n}\n\nclass GenerateAssetCatalogProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Generating Asset Catalogs\"\n    }\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n    private let targetSizeForPreview = 30\n    private let previousAssets = Synchronized<[String: [AssetCatalogEntry]]>(data: [:])\n    private let enablePreviewInGeneratedTSFile: Bool\n\n    init(logger: ILogger, fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, enablePreviewInGeneratedTSFile: Bool) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.enablePreviewInGeneratedTSFile = enablePreviewInGeneratedTSFile\n    }\n\n    private func findOptimalVariantForPreview(variants: [ImageAssetVariant]) -> ImageAssetVariant? {\n        var best: ImageAssetVariant?\n        var bestTargetOffset = Int.max\n\n        for variant in variants {\n            let variantSize = max(variant.imageInfo.size.width, variant.imageInfo.size.height)\n            let targetOffset = abs(targetSizeForPreview - variantSize)\n\n            if best == nil || targetOffset < bestTargetOffset {\n                best = variant\n                bestTargetOffset = targetOffset\n            }\n        }\n\n        return best\n    }\n\n    private func generateTypeScriptModule(relativeAssetDirectoryPath: String, assets: [AssetCatalogEntry]) -> String {\n        let body = CodeWriter()\n\n        for (index, asset) in assets.enumerated() {\n            if index > 0 {\n                body.appendBody(\"\\n\\n\")\n            }\n\n            if let image = asset.image {\n                let propertyName = image.identifier.assetName.camelCased\n\n                if enablePreviewInGeneratedTSFile {\n                    let bestVariant = findOptimalVariantForPreview(variants: image.variants)\n\n                    let absolutePath: String\n                    switch bestVariant?.file {\n                    case .url(let url):\n                        absolutePath = url.path\n                    default:\n                        absolutePath = \"<null>\"\n                    }\n\n                    // Adding additinal empty lines in the comment to workaround an issue with VSCode preview\n                    // where it doesn't make the preview window big enough to show the image.\n\n                    body.appendBody(\"\"\"\n                    /**\n                    * ![Preview](\\(absolutePath))\n                    *\n                    *\n                    *\n                    *\n                    * .\n                    */\n\n                    \"\"\")\n                }\n\n                body.appendBody(\"readonly \\(propertyName): Asset;\")\n            } else if let font = asset.font {\n                if enablePreviewInGeneratedTSFile {\n                    body.appendBody(\"\"\"\n                    /**\n                    * Font reference for \\(asset.virtualPath)\n                    */\n                    \"\"\")\n                }\n                let propertyName = font.name.camelCased\n                body.appendBody(\"\\n\\(propertyName)(size: number): string;\")\n            }\n        }\n\n        let tsOutput = CodeWriter()\n        tsOutput.appendBody(\"\"\"\n            import { loadCatalog } from 'valdi_core/src/AssetCatalog';\n            import { Asset } from 'valdi_core/src/Asset';\n\n            /**\n            * Assets Catalog Module generated from files in \\(relativeAssetDirectoryPath)\n            */\n            interface AssetCatalog {\n                \\(body.content)\n            }\n\n            const catalog = loadCatalog('\\(relativeAssetDirectoryPath)') as AssetCatalog;\n            export default catalog;\n            \"\"\")\n\n        return tsOutput.content.indented(indentPattern: \"  \")\n    }\n\n    private func generateCatalogBin(assets: [AssetCatalogEntry]) throws -> Data {\n        var items = [ZippableItem]()\n\n        for asset in assets {\n            var data = Data()\n\n            let path: String\n            if let image = asset.image {\n                data.append(integer: UInt32(image.size.width))\n                data.append(integer: UInt32(image.size.height))\n                data.append(integer: AssetCatalogTypes.image)\n\n                path = image.identifier.assetName\n            } else if let font = asset.font {\n                data.append(integer: UInt32(0))\n                data.append(integer: UInt32(0))\n                data.append(integer: AssetCatalogTypes.font)\n\n                path = font.name\n            } else {\n                fatalError()\n            }\n\n            let item = ZippableItem(file: .data(data), path: path)\n            items.append(item)\n        }\n\n        let module = ValdiModuleBuilder(items: items)\n        module.compress = false\n\n        return try module.build()\n    }\n\n    private func resolveAssets(key: String, inputAssets: [AssetCatalogEntry]) -> [AssetCatalogEntry] {\n        var allAssets: [AssetCatalogEntry]\n\n        if let previousAssets = self.previousAssets.data({ (previousAssets) -> [AssetCatalogEntry]? in\n            return previousAssets[key]\n        }) {\n            allAssets = inputAssets\n\n            var seenIdentifiers: Set<String> = []\n            inputAssets.forEach { seenIdentifiers.insert($0.virtualPath) }\n\n            allAssets += previousAssets.filter { !seenIdentifiers.contains($0.virtualPath) }\n        } else {\n            allAssets = inputAssets\n        }\n\n        self.previousAssets.data { (previousAssets) -> Void in\n            previousAssets[key] = allAssets\n        }\n\n        return allAssets.sorted(by: { (left, right) in left.virtualPath < right.virtualPath })\n    }\n\n    private func generateAssetCatalog(assetsInBundle: GroupedItems<String, SelectedItem<AssetCatalogEntry>>) -> [CompilationItem] {\n        let assetDirectoryPath = assetsInBundle.key\n        let assets = resolveAssets(key: assetDirectoryPath, inputAssets: assetsInBundle.items.map { $0.data })\n\n        var outItems = assetsInBundle.items.map { $0.item }\n        let anyItem = outItems[0]\n\n        do {\n            let tsModule = generateTypeScriptModule(relativeAssetDirectoryPath: assetDirectoryPath, assets: assets)\n            let tsModuleData = try tsModule.utf8Data()\n\n            let catalogData = try generateCatalogBin(assets: assets)\n\n            let catalogURL = anyItem.bundleInfo.absoluteURL(forRelativeProjectPath: \"\\(assetDirectoryPath).\\(FileExtensions.assetCatalog)\")\n\n            let assetFilename = \"\\(assetDirectoryPath).\\(FileExtensions.typescript)\"\n\n            // Save the file into the generated_ts directory to get autocompletion in VSCode\n            let outputTsURL = projectConfig.generatedTsDirectoryURL.appendingPathComponent(assetFilename)\n            try fileManager.save(data: tsModuleData, to: outputTsURL)\n\n            // Also generate an item so we can actually compile it\n            let emittedTsSourceURL = anyItem.bundleInfo.absoluteURL(forRelativeProjectPath: assetFilename)\n            let emittedTsItem = CompilationItem(sourceURL: emittedTsSourceURL, relativeProjectPath: assetFilename, kind: .typeScript(.data(tsModuleData), emittedTsSourceURL), bundleInfo: anyItem.bundleInfo, platform: nil, outputTarget: .all)\n            let emittedCatalogItemIOS = CompilationItem(sourceURL: catalogURL, relativeProjectPath: nil, kind: .finalFile(FinalFile(outputURL: catalogURL, file: .data(catalogData), platform: .ios, kind: .compiledSource)), bundleInfo: anyItem.bundleInfo, platform: .ios, outputTarget: .all)\n            let emittedCatalogItemAndroid = CompilationItem(sourceURL: catalogURL, relativeProjectPath: nil, kind: .finalFile(FinalFile(outputURL: catalogURL, file: .data(catalogData), platform: .android, kind: .compiledSource)), bundleInfo: anyItem.bundleInfo, platform: .android, outputTarget: .all)\n\n            outItems.append(emittedTsItem)\n            outItems.append(emittedCatalogItemIOS)\n            outItems.append(emittedCatalogItemAndroid)\n\n            logger.debug(\"-- Generated Asset Catalog from assets in \\(assetDirectoryPath)\")\n        } catch let error {\n            let errorMessage = \"Failed to generate Asset Catalog: \\(error.legibleLocalizedDescription)\"\n            logger.error(errorMessage)\n            let newError = CompilerError(errorMessage)\n\n            return outItems.map { $0.with(error: newError) }\n        }\n\n        return outItems\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> AssetCatalogEntry? in\n            if case .imageAsset(let asset) = item.kind {\n                return AssetCatalogEntry(projectRelativeDirectoryPath: asset.identifier.relativeProjectAssetDirectoryPath, virtualPath: asset.identifier.virtualPath, image: asset, font: nil)\n            }\n            if case .resourceDocument(let document) = item.kind, document.outputFilename.hasAnyExtension(FileExtensions.fonts) {\n                return AssetCatalogEntry(projectRelativeDirectoryPath: item.relativeProjectPath.deletingLastPathComponent(), virtualPath: item.relativeProjectPath, image: nil, font: FontAsset(name: document.outputFilename.deletingPathExtension(), data: document.file))\n            }\n            return nil\n        }.groupBy { (item) -> String in\n            return item.data.projectRelativeDirectoryPath\n        }.transformEachConcurrently(generateAssetCatalog)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GenerateBuildFileProcessor.swift",
    "content": "import Foundation\n\nprivate struct AndroidBazelFile {\n    let macroPath: String\n    let macroName: String\n\n    let snakeCaseName: String\n    let snakeCaseDeps: [String]\n\n    func generateContents() -> String {\n        return \"\"\"\n        ### THIS IS A GENERATED FILE, DO NOT EDIT MANUALLY\n        ###\n        ### This file was generated by the Valdi compiler from the \\(snakeCaseName) module.\n\n        load(\"\\(macroPath)\", \"\\(macroName)\")\n\n        snake_case_name = \"\\(snakeCaseName)\"\n\n        snake_case_deps = [\n            \\(snakeCaseDeps.map { \"\\\"\\($0)\\\"\" }.joined(separator: \",\\n    \"))\\(snakeCaseDeps.count > 0 ? \",\" : \"\")\n        ]\n\n        \\(macroName)(\n            snake_case_name,\n            snake_case_deps,\n        )\n\n        \"\"\"\n    }\n}\n\nprivate struct WebPackageFile {\n    let npmName: String\n    let version: String\n    let publishConfig: String\n    let main: String\n    let dependencies: String\n\n    func generateContents() -> String {\n        // For realz, the only way to add comments to a JSON file is to make them\n        // part of the object. This is a garbage format. <- LOL\n        return \"\"\"\n        {\n            \"_warning\": \"THIS IS A GENERATED FILE, DO NOT EDIT MANUALLY\",\n            \"_source\": \"This file was generated by the Valdi compiler from the \\(npmName) module.\",\n            \"name\": \"\\(npmName)\",\n            \"version\": \"\\(version)\",\n            \"description\": \"\",\n            \"main\": \"\\(main)\",\n            \"scripts\":\n                { \"test\": \"echo \\\\\\\"Error: no test specified\\\\\\\" && exit 1\" },\n            \"author\": \"\",\n            \"license\": \"ISC\",\n            \"publishConfig\": \\(publishConfig),\n            \"dependencies\": {\n        \\(dependencies)\n            }\n        }\n        \"\"\"\n    }\n}\n\nfinal class GenerateBuildFileProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Generating modularized BUILD files\"\n    }\n\n    private let projectConfig: ValdiProjectConfig\n\n    init(projectConfig: ValdiProjectConfig) {\n        self.projectConfig = projectConfig\n    }\n\n    private func generateAndroidBuildFile(item: CompilationItem) -> CompilationItem? {\n        guard let androidBuildConfig = projectConfig.androidBuildFileConfig else {\n            return nil\n        }\n        let bundleInfo = item.bundleInfo\n        guard let metadataURL = bundleInfo.androidDebugOutputDirectories?.metadataURL else {\n            return nil\n        }\n\n        do {\n            // we can improve the dependency graph of the resulting targets if we keep track of\n            // internal deps separately from dependencies that have to be public\n            // TODO: separate internal_deps from public_deps\n            let allDependencies = bundleInfo.allDependencies\n            let snakeCaseDeps = Set(allDependencies)\n                .filter { !$0.isRoot }\n                .map { $0.name }\n                .sorted()\n\n            let bazelFile = AndroidBazelFile(\n                macroPath: androidBuildConfig.buildFileMacroPath,\n                macroName: androidBuildConfig.buildFileMacroName,\n                snakeCaseName: bundleInfo.name,\n                snakeCaseDeps: snakeCaseDeps\n            )\n            let bazelFileContents = bazelFile.generateContents()\n            let file = File.data(try bazelFileContents.utf8Data())\n            let outputURL = metadataURL.appendingPathComponent(androidBuildConfig.buildFileName, isDirectory: false)\n            let finalFile = FinalFile(outputURL: outputURL, file: file, platform: .android, kind: .unknown)\n            return item.with(newKind: .finalFile(finalFile))\n        } catch let error {\n            return item.with(error: error)\n        }\n    }\n\n    private func generateWebPackageFile(item: CompilationItem) -> CompilationItem? {\n            guard let webBuildConfig = projectConfig.webBuildFileConfig else {\n                return nil\n            }\n            let bundleInfo = item.bundleInfo\n            guard let metadataURL = bundleInfo.webDebugOutputDirectories?.metadataURL else {\n                return nil\n            }\n\n            var npmName = bundleInfo.name\n            if !bundleInfo.webNpmScope.isEmpty {\n                npmName = \"@\\(bundleInfo.webNpmScope)/\\(npmName)\"\n            }\n            let version = bundleInfo.webVersion\n            let publishConfig = bundleInfo.webPublishConfig\n            let main = bundleInfo.webMain\n\n            let allDependencies = bundleInfo.allDependencies\n            let rawDeps = Set(allDependencies)\n                .filter { !$0.isRoot }\n                .map { \n                    let scope = !$0.webNpmScope.isEmpty ? \"@\\($0.webNpmScope)/\" : \"\"\n                    return \"\\t\\t\\\"\\(scope)\\($0.name)\\\" : \\\"\\($0.webVersion)\\\"\"\n                }\n            \n            let dependencies = rawDeps.joined(separator: \",\\n\")\n\n            do {\n                let packageFile = WebPackageFile(\n                    npmName: npmName,\n                    version: version,\n                    publishConfig: publishConfig,\n                    main: main,\n                    dependencies: dependencies\n                )\n                let packageFileContents = packageFile.generateContents()\n                let file = File.data(try packageFileContents.utf8Data())\n                let outputURL = metadataURL.appendingPathComponent(webBuildConfig.buildFileName, isDirectory: false)\n                let finalFile = FinalFile(outputURL: outputURL, file: file, platform: .ios, kind: .unknown)\n                return item.with(newKind: .finalFile(finalFile))\n            } catch let error {\n                return item.with(error: error)\n            }\n        }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> File? in\n            guard case .moduleYaml(let file) = item.kind else { return nil }\n            return file\n        }.transformEachConcurrently { selectedItem -> [CompilationItem] in\n            let android = generateAndroidBuildFile(item: selectedItem.item)\n            let web = generateWebPackageFile(item: selectedItem.item)\n            return [android, web].compactMap { $0 }\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GenerateDependencyInjectionDataProcessor.swift",
    "content": "//\n//  GenerateDependencyInjectionDataProcessor.swift\n//\n//\n//  Created by John Corbett on 5/10/23.\n//\n\nimport Foundation\n\nstruct IntermediateDependencyMetadata {\n    let model: ValdiModel\n    let classMapping: ResolvedClassMapping\n    let sourceFilename: GeneratedSourceFilename\n}\n\nfinal class GenerateDependencyInjectionDataProcessor: CompilationProcessor {\n    let onlyFocusProcessingForModules: Set<String>\n    private let logger: ILogger\n\n    init(logger: ILogger, onlyFocusProcessingForModules: Set<String>) {\n        self.logger = logger\n        self.onlyFocusProcessingForModules = onlyFocusProcessingForModules\n    }\n\n    var description: String {\n        \"Generating Dependency Injection Data\"\n    }\n\n    private func processDependencyInjectionData(groupedItems: GroupedItems<CompilationItem.BundleInfo, SelectedItem<IntermediateDependencyMetadata>>) throws -> [CompilationItem] {\n        var out: [CompilationItem] = []\n        let bundleInfo = groupedItems.key\n        let items = groupedItems.items\n\n        let outputTarget = items[0].item.outputTarget\n\n        assert(items.allSatisfy { selectedItem in selectedItem.item.outputTarget == outputTarget })\n\n        // Process iOS dependency data.\n        let intermediateMetadata = items.map { item in item.data }\n        let generator = ObjCDependencyRepresentationGenerator(items: intermediateMetadata)\n        let metadataModel = try DependencyMetadata(file: generator.generate())\n\n        out.append(CompilationItem(sourceURL: bundleInfo.baseDir,\n                                   relativeProjectPath: nil,\n                                   kind: .dependencyMetadata(metadataModel),\n                                   bundleInfo: bundleInfo,\n                                   platform: .ios,\n                                   outputTarget: outputTarget))\n\n        // on Android, each item is processed individually as we generate the factory in the Valdi compiler.\n        for item in items {\n            let model = item.data.model\n            let resolvedClassMapping = item.data.classMapping\n            let sourceFileName = item.data.sourceFilename\n            guard let androidClassName = model.androidClassName else {\n                continue\n            }\n\n            do {\n                let jvmClass = JVMClass(fullClassName: androidClassName)\n                let modelGenerator = KotlinFactoryGenerator(jvmClass: jvmClass,\n                                                            typeParameters: model.typeParameters,\n                                                            properties: model.properties,\n                                                            classMapping: resolvedClassMapping,\n                                                            sourceFileName: sourceFileName)\n                let file = try modelGenerator.write()\n                let nativeSource = KotlinCodeGenerator.makeNativeSource(bundleInfo: item.item.bundleInfo,\n                                                                        jvmClass: jvmClass,\n                                                                        file: file,\n                                                                        fileNameOverride: \"\\(jvmClass.name)_ContextFactory.\\(FileExtensions.kotlin)\")\n                out.append(CompilationItem(sourceURL: bundleInfo.baseDir,\n                                           relativeProjectPath: nil,\n                                           kind: .nativeSource(nativeSource),\n                                           bundleInfo: bundleInfo,\n                                           platform: .android,\n                                           outputTarget: outputTarget))\n            } catch {\n                logger.error(\"Failed to generate factory for \\(item.item.sourceURL.path): \\(error.legibleLocalizedDescription)\")\n                out.append(item.item.with(error: error))\n            }\n        }\n\n        return out\n    }\n\n    private func shouldProcessItem(item: CompilationItem) -> Bool {\n        guard !onlyFocusProcessingForModules.isEmpty else {\n            return true\n        }\n        return onlyFocusProcessingForModules.contains(item.bundleInfo.name)\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let bundlesToContexts = items.allItems.compactMap { dependencyItem -> (CompilationItem.BundleInfo, String)? in\n            guard case let .exportedDependencyMetadata(model, _, _) = dependencyItem.kind,\n                  let iosType = model.iosType,\n                  model.properties.contains(where: { param in param.injectableParams.compatibility.contains(.ios) })\n            else {\n                return nil\n            }\n\n            return (dependencyItem.bundleInfo, iosType.name)\n        }.reduce(into: [String: [String]]()) { partialResult, bundleTypePair in\n            let bundleName = bundleTypePair.0.iosModuleName\n            let iosTypeName = bundleTypePair.1\n            partialResult[bundleName, default: []].append(iosTypeName)\n        }\n\n        return try items\n            .select { item -> IntermediateDependencyMetadata? in\n                guard case let .exportedDependencyMetadata(model, classMapping, filename) = item.kind,\n                      shouldProcessItem(item: item)\n                else {\n                    return nil\n                }\n\n                return IntermediateDependencyMetadata(\n                    model: model,\n                    classMapping: classMapping,\n                    sourceFilename: filename\n                )\n            }\n            .groupBy { item -> CompilationItem.BundleInfo in\n                item.item.bundleInfo\n            }\n            .transformEachConcurrently(processDependencyInjectionData)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GenerateGlobalMetadataProcessor.swift",
    "content": "import Foundation\nimport Yams\n\nfinal class GenerateGlobalMetadataProcessor: CompilationProcessor {\n\n    private struct AllModulesAndDepsRecord: Encodable, Decodable {\n        let iosModuleName: String\n        let deps: [String]\n        let ios_context_factories: [String]\n    }\n\n    var description: String {\n        return \"Generating global metadata\"\n    }\n\n    private let logger: ILogger\n    private let projectConfig: ValdiProjectConfig\n    private let rootBundle: CompilationItem.BundleInfo\n    private let shouldMergeWithExistingFile: Bool\n\n    init(logger: ILogger, projectConfig: ValdiProjectConfig, rootBundle: CompilationItem.BundleInfo, shouldMergeWithExistingFile: Bool) {\n        self.logger = logger\n        self.projectConfig = projectConfig\n        self.rootBundle = rootBundle\n        self.shouldMergeWithExistingFile = shouldMergeWithExistingFile\n    }\n\n    private func generateAllDepsFile(platform: Platform, moduleYamlFileItems: [SelectedItem<File>]) throws -> [CompilationItem] {\n        let output: ValdiOutputConfig?\n        switch platform {\n        case .ios:\n            output = projectConfig.iosOutput\n        case .android:\n            output = projectConfig.androidOutput\n        case .web:\n            output = projectConfig.webOutput\n        case .cpp:\n            output = projectConfig.cppOutput\n        }\n\n        guard let globalMetadataURL = try output?.globalMetadataPath?.resolve() else {\n            return []\n        }\n\n        let outputURL = globalMetadataURL.appendingPathComponent(\"ALL_MODULES_AND_DEPS.bzl\", isDirectory: false)\n\n        // If --module is specified, we want to avoid overwriting the existing ALL_MODULES_AND_DEPS with just the information\n        // from the dependency subtree that is currently being compiled. So, in those cases, we take extra steps to parse the\n        // existing contents.\n        let existingAllModulesAndDeps: [String: AllModulesAndDepsRecord]\n        if shouldMergeWithExistingFile && FileManager.default.fileExists(atPath: outputURL.path) {\n            do {\n                let existingContents = String(data: try Data(contentsOf: outputURL), encoding: .utf8) ?? \"\"\n                // Find the _GENERATED_MODULES_AND_DEPS dict in the file\n                let marker = \"_GENERATED_MODULES_AND_DEPS = \"\n                guard let markerRange = existingContents.range(of: marker) else {\n                    throw CompilerError(\"Unexpected contents in existing ALL_MODULES_AND_DEPS.bzl - missing _GENERATED_MODULES_AND_DEPS\")\n                }\n                let afterMarker = existingContents[markerRange.upperBound...]\n                // Find the closing brace that ends the dict (before the merge line)\n                guard let endRange = afterMarker.range(of: \"\\n\\nALL_MODULES_AND_DEPS = \") else {\n                    throw CompilerError(\"Unexpected contents in existing ALL_MODULES_AND_DEPS.bzl - missing merge statement\")\n                }\n                let jsonString = String(afterMarker[..<endRange.lowerBound])\n                guard let existingJson = jsonString.data(using: .utf8) else {\n                    throw CompilerError(\"Failed to convert existing ALL_MODULES_AND_DEPS.bzl content to data\")\n                }\n                existingAllModulesAndDeps = try .fromJSON(existingJson, keyDecodingStrategy: .convertFromSnakeCase)\n            } catch {\n                logger.error(\"Failed to read existing ALL_MODULES_AND_DEPS.bzl: \\(error)\")\n                existingAllModulesAndDeps = [:]\n            }\n        } else {\n            existingAllModulesAndDeps = [:]\n        }\n\n        let tuples = try moduleYamlFileItems.map { item -> (String, AllModulesAndDepsRecord) in\n            let bundleInfo = item.item.bundleInfo\n            let name = try bundleInfo.toBazelTarget(projectConfig: self.projectConfig, currentWorkspace: nil)\n            let deps = try bundleInfo.dependencies\n                .filter { !$0.isRoot }\n                .map { try $0.toBazelTarget(projectConfig: self.projectConfig, currentWorkspace: nil) }\n                .uniqueElements()\n                .sorted()\n\n            let record = AllModulesAndDepsRecord(iosModuleName: bundleInfo.iosModuleName,\n                                                 deps: deps,\n                                                 ios_context_factories: bundleInfo.iosGeneratedContextFactories)\n            return (name, record)\n        }\n        let updatedAllModulesAndDeps = try tuples.associateUnique { tuple in\n            return tuple\n        }\n        let allModulesAndDeps = existingAllModulesAndDeps.merging(updatedAllModulesAndDeps, uniquingKeysWith: { _, updated in updated })\n        let allModulesAndDepsData = try allModulesAndDeps.toJSON(outputFormatting: [.prettyPrinted, .sortedKeys, .withoutEscapingSlashes], keyEncodingStrategy: .convertToSnakeCase)\n        let allModulesAndDepsString = String(data: allModulesAndDepsData, encoding: .utf8) ?? \"{}\"\n\n        let fileContents = \"\"\"\nload(\":MANUAL_MODULES_AND_DEPS.bzl\", \"MANUAL_MODULES_AND_DEPS\")\n\n_GENERATED_MODULES_AND_DEPS = \\(allModulesAndDepsString)\n\nALL_MODULES_AND_DEPS = _GENERATED_MODULES_AND_DEPS | MANUAL_MODULES_AND_DEPS\n\"\"\"\n\n        let file = File.data(try fileContents.utf8Data())\n        let finalFile = FinalFile(outputURL: outputURL, file: file, platform: platform, kind: .unknown)\n\n        let projectURL = projectConfig.baseDir.appendingPathComponent(projectConfig.projectName)\n        let errorItem = CompilationItem(sourceURL: projectURL,\n                                        relativeProjectPath: nil,\n                                        kind: .finalFile(finalFile),\n                                        bundleInfo: rootBundle,\n                                        platform: .android,\n                                        outputTarget: .release)\n        return [errorItem]\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return try items.select { (item) -> File? in\n            guard case .moduleYaml(let file) = item.kind\n            else { return nil }\n            return file\n        }.transformAll({ selectedItems in\n            let android = try generateAllDepsFile(platform: .android, moduleYamlFileItems: selectedItems)\n            let ios = try generateAllDepsFile(platform: .ios, moduleYamlFileItems: selectedItems)\n            return android + ios + selectedItems.map(\\.item)\n        })\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GenerateIdsFilesProcessor.swift",
    "content": "//\n//  GenerateIdsFilesProcessor.swift\n//  \n//\n//  Created by Simon Corsin on 5/10/22.\n//\n\nimport Foundation\n\nstruct GenerateIdsFilesResult {\n    let android: String\n    let iosHeader: String\n    let iosImplementation: String\n    let typescriptDefinition: String\n    let typescriptImplementation: String\n}\n\nclass GenerateIdsFilesProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Generating Ids Files\"\n    }\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n    private let companion: CompanionExecutable\n    private let nativeCodeGenerationManager: NativeCodeGenerationManager\n\n    init(logger: ILogger, fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, companion: CompanionExecutable, nativeCodeGenerationManager: NativeCodeGenerationManager) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.companion = companion\n        self.nativeCodeGenerationManager = nativeCodeGenerationManager\n    }\n\n    private func generateIdFiles(selectedItem: SelectedItem<File>) -> [CompilationItem] {\n        do {\n            logger.debug(\"-- Generating Ids files from \\(selectedItem.item.relativeProjectPath)\")\n\n            let iosFileNamePrefix = \"Ids\"\n\n            var iosType = IOSType(name: iosFileNamePrefix, bundleInfo: selectedItem.item.bundleInfo, kind: .enum, iosLanguage: selectedItem.item.bundleInfo.iosLanguage)\n            iosType.applyImportPrefix(iosImportPrefix: selectedItem.item.bundleInfo.iosModuleName, isOverridden: false)\n            let iosHeaderStatement = iosType.importHeaderStatement(kind: .withUtilities)\n\n            let result = try selectedItem.data.withURL { url in\n                return try companion.generateIdsFiles(moduleName: selectedItem.item.bundleInfo.name, iosHeaderImportPath: iosHeaderStatement, idFilePath: url.path).waitForData()\n            }\n\n            let relativeProjectPathWithoutExtension = selectedItem.item.relativeProjectPath.deletingPathExtension()\n\n            var generatedFiles = try TypeScriptIntermediateUtils.emitGeneratedJs(fileManager: fileManager,\n                                                                                 projectConfig: projectConfig,\n                                                                                 sourceItem: selectedItem.item,\n                                                                                 jsOutputPath: \"\\(relativeProjectPathWithoutExtension).\\(FileExtensions.javascript)\",\n                                                                                 jsContent: .data(try result.typescriptImplementation.utf8Data()),\n                                                                                 tsDefinitionOutputPath: \"\\(relativeProjectPathWithoutExtension).\\(FileExtensions.typescriptDeclaration)\",\n                                                                                 tsDefinitionContent: .data(try result.typescriptDefinition.utf8Data()))\n\n            generatedFiles.append(selectedItem.item.with(newKind: .nativeSource(NativeSource(relativePath: nil,\n                                                                                             filename: \"\\(iosFileNamePrefix).h\",\n                                                                                             file: .data(try result.iosHeader.utf8Data()),\n                                                                                             groupingIdentifier: \"\\(selectedItem.item.bundleInfo.iosModuleName).h\",\n                                                                                             groupingPriority: IOSType.idsTypeGroupingPriority\n                                                                                            )\n            ), newPlatform: .ios))\n            generatedFiles.append(selectedItem.item.with(newKind: .nativeSource(NativeSource(relativePath: nil,\n                                                                                             filename: \"\\(iosFileNamePrefix).m\",\n                                                                                             file: .data(try result.iosImplementation.utf8Data()),\n                                                                                             groupingIdentifier: \"\\(selectedItem.item.bundleInfo.iosModuleName).m\",\n                                                                                             groupingPriority: IOSType.idsTypeGroupingPriority)), newPlatform: .ios))\n\n            let androidXmlPath = \"values/\\(selectedItem.item.bundleInfo.name)_ids.xml\"\n\n            generatedFiles.append(selectedItem.item.with(newKind:\n                    .androidResource(androidXmlPath, .data(try result.android.utf8Data())), newPlatform: .android))\n\n            return generatedFiles\n        } catch let error {\n            return [selectedItem.item.with(error: CompilerError(\"Failed to generate ids files from \\(selectedItem.item.relativeProjectPath): \\(error.legibleLocalizedDescription)\"))]\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> File? in\n            if case .ids(let file) = item.kind {\n                return file\n            }\n            return nil\n        }.transformEachConcurrently(generateIdFiles)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GenerateModelsProcessor.swift",
    "content": "//\n//  GenerateViewModelsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.document, .model] -> [.document, .nativeSource]\nfinal class GenerateModelsProcessor: CompilationProcessor {\n\n    fileprivate struct GroupingKey: Equatable, Hashable {\n        let platform: Platform?\n        let groupingIdentifier: String\n    }\n\n    private let logger: ILogger\n    private let compilerConfig: CompilerConfig\n\n    init(logger: ILogger, compilerConfig: CompilerConfig) {\n        self.logger = logger\n        self.compilerConfig = compilerConfig\n    }\n\n    var description: String {\n        return \"Generating Native Models\"\n    }\n\n    private func doGenerate<T: NativeSourceGenerator>(item: CompilationItem,\n                                                      intermediateItem: IntermediateItem,\n                                                      iosType: IOSType?,\n                                                      androidClassName: String?,\n                                                      cppType: CPPType?,\n                                                      generationType: String,\n                                                      generator: T) -> [CompilationItem] {\n        do {\n            let nativeSourceParameters = NativeSourceParameters(bundleInfo: item.bundleInfo,\n                                                                sourceFileName: intermediateItem.sourceFilename,\n                                                                classMapping: intermediateItem.classMapping,\n                                                                iosType: iosType,\n                                                                androidTypeName: androidClassName,\n                                                                cppType: cppType)\n\n            let codes = try generator.generate(parameters: nativeSourceParameters)\n            for code in codes {\n                logger.debug(\"-- Generated \\(code.source.filename)\")\n            }\n\n            return codes.map { item.with(newKind: .nativeSource($0.source), newPlatform: $0.platform) }\n        } catch let error {\n            logger.error(\"Failed to generate \\(generationType) of \\(item.sourceURL.path): \\(error.legibleLocalizedDescription)\")\n            return [item.with(error: error)]\n        }\n    }\n\n    private struct IntermediateItem {\n        let sourceFilename: GeneratedSourceFilename\n        let exportedType: ExportedType\n        let classMapping: ResolvedClassMapping\n    }\n\n    private func typeDescription(for exportedType: ExportedType) -> GeneratedTypeDescription? {\n        switch exportedType {\n        case let .valdiModel(model):\n            if model.exportAsInterface {\n                return .interface(GeneratedNativeInterfaceDescription(model: model))\n            } else {\n                return .class(GeneratedNativeClassDescription(model: model))\n            }\n        case let .enum(exportedEnum):\n            return .enum(GeneratedEnumDescription.from(exportedEnum: exportedEnum))\n        case let .function(exportedFunction):\n            return .function(GeneratedFunctionDescription.from(exportedFunction: exportedFunction))\n        case .module:\n            return nil\n        }\n    }\n\n    private func generate(selectedItem: SelectedItem<[IntermediateItem]>) -> [CompilationItem] {\n        var out = [CompilationItem]()\n        for item in selectedItem.data {\n            switch item.exportedType {\n            case .valdiModel(let valdiModel):\n                out += doGenerate(item: selectedItem.item,\n                                  intermediateItem: item,\n                                  iosType: valdiModel.iosType,\n                                  androidClassName: valdiModel.androidClassName,\n                                  cppType: valdiModel.cppType,\n                                  generationType: \"model\",\n                                  generator: ValdiModelGenerator(model: valdiModel))\n            case .enum(let exportedEnum):\n                out += doGenerate(item: selectedItem.item,\n                                  intermediateItem: item,\n                                   iosType: exportedEnum.iosType,\n                                   androidClassName: exportedEnum.androidTypeName,\n                                   cppType: exportedEnum.cppType,\n                                   generationType: \"enum\",\n                                   generator: ExportedEnumGenerator(exportedEnum: exportedEnum))\n            case .function(let exportedFunc):\n                out += doGenerate(item: selectedItem.item,\n                                  intermediateItem: item,\n                                  iosType: exportedFunc.containingIosType,\n                                  androidClassName: exportedFunc.containingAndroidTypeName,\n                                  cppType: exportedFunc.containingCppType,\n                                  generationType: \"function\",\n                                  generator: ExportedFunctionGenerator(exportedFunction: exportedFunc, modulePath: selectedItem.item.relativeBundleURL.deletingPathExtension().absoluteString))\n            case .module(let exportedModule):\n                out += doGenerate(item: selectedItem.item,\n                                  intermediateItem: item,\n                                  iosType: exportedModule.model.iosType,\n                                  androidClassName: exportedModule.model.androidClassName,\n                                  cppType: exportedModule.model.cppType,\n                                  generationType: \"module\",\n                                  generator: ExportedModuleGenerator(bundleInfo: selectedItem.item.bundleInfo, exportedModule: exportedModule))\n            }\n\n            if let description = typeDescription(for: item.exportedType) {\n                let newItem = selectedItem.item.with(newKind: .generatedTypeDescription(description), newPlatform: .none)\n                out.append(newItem)\n            }\n        }\n\n        if case .document = selectedItem.item.kind {\n            // For documents, we want to keep the original file.\n            out.append(selectedItem.item)\n        }\n\n        return out\n    }\n\n    private func shouldProcessItem(item: CompilationItem) -> Bool {\n        return shouldProcessBundle(bundle: item.bundleInfo)\n    }\n\n    private func shouldProcessBundle(bundle: CompilationItem.BundleInfo) -> Bool {\n        guard !compilerConfig.onlyGenerateNativeCodeForModules.isEmpty else {\n            return true\n        }\n        return compilerConfig.onlyGenerateNativeCodeForModules.contains(bundle.name)\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let intermediateItems = items.select { (item) -> [IntermediateItem]? in\n            guard shouldProcessItem(item: item) else {\n                return nil\n            }\n\n            if case .document(let result) = item.kind, let viewModel = result.originalDocument.viewModel {\n                let generatedSourceFilename = GeneratedSourceFilename(filename: result.componentPath.fileName, symbolName: result.componentPath.exportedMember)\n                var out = [IntermediateItem]()\n                out.append(IntermediateItem(sourceFilename: generatedSourceFilename,\n                                            exportedType: .valdiModel(viewModel),\n                                            classMapping: result.classMapping))\n\n                for childModel in result.originalDocument.additionalModels {\n                    out.append(IntermediateItem(sourceFilename: generatedSourceFilename,\n                                                exportedType: .valdiModel(childModel),\n                                                classMapping: result.classMapping))\n                }\n                return out\n            } else if case .exportedType(let exportedType, let classMapping, let generatedSourceFilename) = item.kind {\n                return [IntermediateItem(sourceFilename: generatedSourceFilename,\n                                         exportedType: exportedType,\n                                         classMapping: classMapping)]\n            } else {\n                return nil\n            }\n        }\n\n        return intermediateItems.transformEachConcurrently(generate)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GenerateModuleBuildFileProcessor.swift",
    "content": "import Foundation\n\nextension Sequence where Element: Hashable {\n    func uniqueElements() -> [Element] {\n        var set = Set<Element>()\n        return filter { set.insert($0).inserted }\n    }\n}\n\nprivate struct ModuleBuildTargetConfig {\n    let projectConfig: ValdiProjectConfig\n    let name: String\n    let iosModuleName: String\n    let iosLanguage: IOSLanguage\n    let iosGeneratedContextFactories: [String]\n\n    let iosOutputTarget: ModuleOutputTarget?\n    let androidOutputTarget: ModuleOutputTarget?\n\n    let declarationTSSourceDirs: SourceDirTracking\n    let nonDeclarationTSSourceDirs: SourceDirTracking\n    let jsonSourceDirs: SourceDirTracking\n    let jsSourceDirs: SourceDirTracking\n    let legacyVueSourceDirs: SourceDirTracking\n    let legacyStyleSourceDirs: SourceDirTracking\n    let legacyModuleStyleSourceDirs: SourceDirTracking\n    let resourceSourceDirs: SourceDirTracking\n    let sqlSourceDirs: SourceDirTracking\n    let sqlDatabaseNames: [String]?\n    let protoDeclSourceDirs: SourceDirTracking\n\n    let disableAnnotationProcessing: Bool\n    let asyncStrictMode: Bool\n    let stringsDir: String?\n    let idsYaml: String?\n    let noCompiledValdiModuleOutput: Bool\n    let downloadableAssets: Bool\n    let downloadableSources: Bool\n    let singleFileCodegen: Bool\n    let hasIOSExports: Bool\n    let hasAndroidExports: Bool\n\n    let iosDeps: [String]\n\n    let excludePatterns: [NSRegularExpression]\n    let excludeGlobs: [String]\n\n    // Dependencies array\n    let deps: [CompilationItem.BundleInfo]\n}\n\nprivate struct GlobPatterns {\n    struct GlobContent {\n        let srcs: [String]\n        let exclude: [String]\n        let files: [String]\n\n        func toGlobCallString() -> String {\n            return \"\"\n        }\n    }\n\n    private var fileExtensions: Set<String> = []\n    private var filenames: [String] = []\n\n    init(fileExtensions: [String] = [], filenames: [String] = []) {\n        self.fileExtensions = Set<String>(fileExtensions)\n        self.filenames = filenames\n    }\n\n    mutating func append(_ fileExtension: String) {\n        self.fileExtensions.insert(fileExtension)\n    }\n\n    mutating func append(fileExtensions newFileExtensions: [String]) {\n        self.fileExtensions = self.fileExtensions.union(newFileExtensions)\n    }\n\n    mutating func append(filename: String) {\n        self.filenames.append(filename)\n    }\n\n    func getGlobCallString(sourceDirectories: Set<String>, files: Set<String>, exclude: [String], separator: String = \", \") -> String {\n        var sortedExtensions = Array(self.fileExtensions)\n        sortedExtensions.sort()\n\n        let globSrcs = sourceDirectories\n            .sorted()\n            .map { sourceDir in\n                sortedExtensions.map { \"\\\"\\(sourceDir)/**/*.\\($0)\\\"\" } + filenames.map { \"\\\"\\(sourceDir)/**/\\($0)\\\"\" }\n            }\n            .flatMap { $0 }\n            .joined(separator: separator)\n\n        var globCall = \"glob([\\n\\(globSrcs)]\"\n\n        if !exclude.isEmpty {\n            let excludeString = exclude.joined(separator: separator)\n            globCall += \"\\n,    exclude = [\\(excludeString)]\"\n        }\n\n        globCall += \")\"\n\n        if !files.isEmpty {\n            let filesString = files\n                .sorted()\n                .map { file in \"\\\"\\(file)\\\"\" }\n                .joined(separator: separator)\n\n            globCall += \" + [\\n\\(filesString)\\n]\"\n        }\n\n        return globCall\n    }\n}\n\nprivate struct ModuleBuildFile {\n    let config: ModuleBuildTargetConfig\n\n    func isExcludePatternsAndGlobsValid() -> Bool {\n        // Validates that the number of entries in exclude_patterns and exclude_globs match\n        return !config.excludeGlobs.isEmpty ? config.excludePatterns.count == config.excludeGlobs.count : true\n    }\n\n    func generateContents() throws -> String {\n        var srcsPatterns = GlobPatterns(fileExtensions: [])\n\n        if !config.nonDeclarationTSSourceDirs.sourceDirs.isEmpty || !config.declarationTSSourceDirs.sourceDirs.isEmpty {\n            srcsPatterns.append(fileExtensions: [\n                FileExtensions.typescript,\n                FileExtensions.typescriptXml\n            ])\n        }\n        if !config.jsSourceDirs.sourceDirs.isEmpty {\n            srcsPatterns.append(FileExtensions.javascript)\n        }\n        if !config.jsonSourceDirs.sourceDirs.isEmpty {\n            srcsPatterns.append(FileExtensions.json)\n        }\n        let allSourceDirsToCheck = [config.nonDeclarationTSSourceDirs, config.declarationTSSourceDirs, config.jsSourceDirs, config.jsonSourceDirs]\n        var srcsSourceDirectories = Set<String>()\n        allSourceDirsToCheck.forEach { srcsSourceDirectories.formUnion($0.sourceDirs) }\n        var files = Set<String>()\n        allSourceDirsToCheck.forEach { files.formUnion($0.files) }\n\n        let excludePaths = config.excludeGlobs.uniqueElements().map{#\"\"\\#($0)\"\"#}\n\n        let srcGlobCallString = srcsPatterns.getGlobCallString(sourceDirectories: srcsSourceDirectories,\n                                                               files: files,\n                                                               exclude: excludePaths,\n                                                               separator: \",\\n        \")\n\n        func outputTargetString(_ outputTarget: ModuleOutputTarget?) -> String {\n            switch outputTarget {\n            case .debugOnly?:\n                return \"\\\"debug\\\"\"\n            case .releaseReady?:\n                return \"\\\"release\\\"\"\n            case nil:\n                return \"None\"\n            }\n        }\n\n        let iosOutputTargetString = outputTargetString(config.iosOutputTarget)\n        let androidOutputTargetString = outputTargetString(config.androidOutputTarget)\n\n        var contents = \"load(\\\"@valdi//bzl/valdi:valdi_module.bzl\\\", \\\"valdi_module\\\")\\n\"\n        if !config.sqlSourceDirs.isEmpty {\n            contents.append(\n            \"\"\"\n            load(\"@rules_pkg//:mappings.bzl\", \"pkg_files\", \"strip_prefix\")\\n\n            load(\"@rules_pkg//:pkg.bzl\", \"pkg_zip\")\\n\n            \"\"\")\n        }\n\n        if (!isExcludePatternsAndGlobsValid()) {\n            throw CompilerError(\"Module \\'\\(config.name)\\' has mismatched number of entries for exclude_patterns (\\(config.excludePatterns.count)) and exclude_globs (\\(config.excludeGlobs.count)) in 'module.yaml'.\")\n        }\n\n        contents.append(\n        \"\"\"\n\n        ####################\n        ## THIS IS AN AUTOGENERATED FILE\n        ##\n        ## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n        ####################\n\n        valdi_module(\n            name = \"\\(config.name)\",\n            ios_module_name = \"\\(config.iosModuleName)\",\n            ios_output_target = \\(iosOutputTargetString),\n            android_output_target = \\(androidOutputTargetString),\n            srcs = \\(srcGlobCallString),\n            module_yaml = \"module.yaml\",\n            single_file_codegen = \\(config.singleFileCodegen ? \"True\" : \"False\"),\n        \"\"\")\n\n        if !config.hasIOSExports || !config.hasAndroidExports {\n            contents.append(\"\"\"\n            has_ios_exports = \\(config.hasIOSExports ? \"True\" : \"False\"),\n            has_android_exports = \\(config.hasAndroidExports ? \"True\" : \"False\"),\n        \"\"\")\n        }\n\n        func maybeAppendDepsSequence(_ sequence: [String], attributeName: String) {\n            if !sequence.isEmpty {\n                let sequenceString = sequence.joined(separator: \",\\n        \")\n                contents.append(\"\"\"\n                \\n    \\(attributeName) = [\\n        \\(sequenceString)\\n    ],\n                \"\"\")\n            }\n        }\n\n        var combinedDeps: [String] = []\n\n        for dep in config.deps {\n            let bazelTarget = try dep.toBazelTarget(projectConfig: self.config.projectConfig, currentWorkspace: \"snap_client\")\n            combinedDeps.append(\"\\\"\\(bazelTarget)\\\"\")\n        }\n\n        maybeAppendDepsSequence(combinedDeps.sorted(), attributeName: \"deps\")\n\n        func maybeAppendAttributeGlobPatternsSequence(fileExtensions: [String], filenames: [String] = [], sourceDirs: SourceDirTracking, attributeName: String) {\n            guard !sourceDirs.isEmpty else {\n                return\n            }\n            let globCall = GlobPatterns(fileExtensions: fileExtensions, filenames: filenames)\n                .getGlobCallString(sourceDirectories: sourceDirs.sourceDirs, files: [], exclude: [], separator: \",\\n        \")\n            contents.append(\"\"\"\n            \\n    \\(attributeName) = \\(globCall),\n            \"\"\")\n        }\n\n        maybeAppendAttributeGlobPatternsSequence(fileExtensions: FileExtensions.images + FileExtensions.exportedImages + FileExtensions.fonts,\n                                                 sourceDirs: config.resourceSourceDirs,\n                                                 attributeName: \"res\")\n\n        maybeAppendAttributeGlobPatternsSequence(fileExtensions: FileExtensions.legacyStyles,\n                                                 sourceDirs: config.legacyStyleSourceDirs,\n                                                 attributeName: \"legacy_style_srcs\")\n\n        maybeAppendAttributeGlobPatternsSequence(fileExtensions: FileExtensions.legacyModuleStyles,\n                                                 sourceDirs: config.legacyModuleStyleSourceDirs,\n                                                 attributeName: \"legacy_module_style_srcs\")\n\n        maybeAppendAttributeGlobPatternsSequence(fileExtensions: [FileExtensions.vue],\n                                                 sourceDirs: config.legacyVueSourceDirs,\n                                                 attributeName: \"legacy_vue_srcs\")\n\n        maybeAppendAttributeGlobPatternsSequence(fileExtensions: FileExtensions.sql,\n                                                 filenames: [Files.sqlTypesYaml, Files.sqlManifestYaml],\n                                                 sourceDirs: config.sqlSourceDirs,\n                                                 attributeName: \"sql_srcs\")\n\n        maybeAppendAttributeGlobPatternsSequence(fileExtensions: [FileExtensions.protoDecl],\n                                                 sourceDirs: config.protoDeclSourceDirs,\n                                                 attributeName: \"protodecl_srcs\")\n\n        if let sqlDatabaseNames = config.sqlDatabaseNames {\n            let outputSqlDatabaseNames = sqlDatabaseNames.map { \"\\\"\\($0)\\\"\" }.joined(separator: \", \")\n            contents.append(\"\"\"\n            \\n    sql_db_names = [\\(outputSqlDatabaseNames)],\n            \"\"\")\n        }\n\n        if !config.iosGeneratedContextFactories.isEmpty {\n            let iosGeneratedContextFactories = config.iosGeneratedContextFactories\n\n            let outputGeneratedContextFactoryNames = iosGeneratedContextFactories.map { \"\\\"\\($0)\\\"\" }.joined(separator: \", \")\n            contents.append(\"\"\"\n            \\n    ios_generated_context_factories = [\\(outputGeneratedContextFactoryNames)],\n            \"\"\")\n        }\n\n        func maybeAppendStringAttribute(_ attributeName: String, value: String?) {\n            guard let value = value else {\n                return\n            }\n\n            contents.append(\"\"\"\n            \\n    \\(attributeName) = \\\"\\(value)\\\",\n            \"\"\")\n        }\n\n        func maybeAppendStringListAttribute(_ attributeName: String, values: [String]?) {\n            guard let values = values else {\n                return\n            }\n            let quoted = values.map { \"\\\"\\($0)\\\"\" }.joined(separator: \", \")\n            contents.append(\"\"\"\n            \\n    \\(attributeName) = [\\(quoted)],\n            \"\"\")\n        }\n\n        enum AppendOnlyIf {\n            case valueTrue\n            case valueFalse\n            case always\n        }\n\n        func maybeAppendBoolAttribute(_ attributeName: String, value: Bool, appendOnlyIf: AppendOnlyIf) {\n            switch appendOnlyIf {\n            case .valueTrue:\n                if !value {\n                    return\n                }\n            case .valueFalse:\n                if value {\n                    return\n                }\n            case .always:\n                break\n            }\n\n            contents.append(\"\"\"\n            \\n    \\(attributeName) = \\(value ? \"True\" : \"False\"),\n            \"\"\")\n        }\n\n        maybeAppendStringAttribute(\"strings_dir\", value: config.stringsDir)\n        maybeAppendStringAttribute(\"ids_yaml\", value: config.idsYaml)\n\n        switch config.iosLanguage {\n        case .objc: break // default is \"objc\", no need to add anything\n        case .swift: maybeAppendStringAttribute(\"ios_language\", value: \"swift\")\n        case .both: maybeAppendStringListAttribute(\"ios_language\", values: [\"objc\", \"swift\"])\n        }\n\n        maybeAppendBoolAttribute(\"disable_annotation_processing\", value: config.disableAnnotationProcessing, appendOnlyIf: .valueTrue)\n\n        maybeAppendBoolAttribute(\"async_strict_mode\", value: config.asyncStrictMode, appendOnlyIf: .valueTrue)\n\n        maybeAppendBoolAttribute(\"downloadable_assets\", value: config.downloadableAssets, appendOnlyIf: .valueFalse)\n\n        maybeAppendBoolAttribute(\"no_compiled_valdimodule_output\", value: config.noCompiledValdiModuleOutput, appendOnlyIf: .valueTrue)\n\n        contents.append(\"\"\"\n        \\n    visibility = [\"//visibility:public\"],\n        )\\n\n        \"\"\")\n        if !config.sqlSourceDirs.isEmpty {\n            contents.append(\n            \"\"\"\n            pkg_files(\n                name = \"\\(config.name)_sql_srcs\",\n                srcs = glob([\"**/*.sq\", \"**/*.sqm\", \"**/*.yaml\"]),\n                strip_prefix = strip_prefix.from_pkg(),\n                visibility = [\"//visibility:public\"],\n            )\n\n            pkg_zip(\n                name = \"\\(config.name)_sql\",\n                srcs = [\":\\(config.name)_sql_srcs\"],\n                visibility = [\"//visibility:public\"],\n                package_dir = \"com/snap\",\n            )\n            \"\"\")\n        }\n        return contents\n    }\n}\n\nprivate struct SourceDirTracking {\n    private let supportedSourceDirectories: Set<String>\n\n    private let logger: ILogger\n    private(set) var items: [CompilationItem] = []\n    private(set) var sourceDirs: Set<String> = []\n    private(set) var files: Set<String> = []\n\n    init(logger: ILogger, _ supportedSourceDirectories: [String]) {\n        self.logger = logger\n        self.supportedSourceDirectories = Set(supportedSourceDirectories)\n    }\n\n    mutating func append(_ item: CompilationItem) {\n        items.append(item)\n\n        let pathComponents = item.relativeBundleURL.pathComponents\n        let isTsConfig = item.sourceURL.lastPathComponent == \"tsconfig.json\"\n        let isParentReference = pathComponents.first == \"..\"\n        \n        // Special handling for tsconfig.json:\n        // - If it's in a parent directory (starts with \"..\"), treat as a file\n        // - If it's at the root level (single component), treat as a file\n        // - If it's nested in a source directory (e.g., src/lib/tsconfig.json), treat as part of that source dir\n        if pathComponents.count > 1 && !(isTsConfig && isParentReference) {\n            let sourceDir = pathComponents[0]\n            if !supportedSourceDirectories.contains(sourceDir) {\n                logger.warn(\"!!! Unusual source directory '\\(sourceDir)' for item \\(item.relativeProjectPath)\")\n            }\n            sourceDirs.insert(sourceDir)\n        } else {\n            // must be root .d.ts files:\n            //    StringMap.d.ts\n            //    NativeTemplateElements.d.ts\n            //    MapStrings.d.ts\n            //    Drawing.d.ts\n            //    StringSet.d.ts\n            //    Strings.d.ts\n            //    Valdi.ignore.ts\n            //    Networking.d.ts\n            // OR tsconfig.json that's either at root level or in parent directory (../tsconfig.json)\n            if item.bundleInfo.isRoot {\n                logger.warn(\"Unusual source directory '<root>' for item \\(item.relativeProjectPath)\")\n            } else {\n                files.insert(item.relativeBundleURL.path)\n            }\n        }\n    }\n\n    var isEmpty: Bool {\n        return sourceDirs.isEmpty && files.isEmpty\n    }\n}\n\nfinal class GenerateModuleBuildFileProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Re-generating valdi_modules BUILD files\"\n    }\n\n    private let logger: ILogger\n    private let projectConfig: ValdiProjectConfig\n    private let compilerConfig: CompilerConfig\n    private let nativeCodeGenerationManager: NativeCodeGenerationManager?\n\n    init(logger: ILogger, projectConfig: ValdiProjectConfig, compilerConfig: CompilerConfig, nativeCodeGenerationManager: NativeCodeGenerationManager? = nil) {\n        self.logger = logger\n        self.projectConfig = projectConfig\n        self.compilerConfig = compilerConfig\n        self.nativeCodeGenerationManager = nativeCodeGenerationManager\n    }\n\n    private func hasNonTSConfigJsonFile(jsonSourceDirs: SourceDirTracking) -> Bool {\n        for file in jsonSourceDirs.items {\n            if file.sourceURL.lastPathComponent != \"tsconfig.json\" {\n                return true\n            }\n        }\n\n        return false\n    }\n\n    private func generateModuleBuildFile(moduleName: String, bundleInfo: CompilationItem.BundleInfo, items: [CompilationItem]) throws -> ModuleBuildFile {\n        let supportedSrcDirectories = [\"src\", \"test\"]\n        var declarationTSSourceDirs = SourceDirTracking(logger: logger, supportedSrcDirectories)\n        var nonDeclarationTSSourceDirs = SourceDirTracking(logger: logger, supportedSrcDirectories)\n        var jsonSourceDirs = SourceDirTracking(logger: logger, supportedSrcDirectories)\n        var jsSourceDirs = SourceDirTracking(logger: logger, supportedSrcDirectories)\n        var legacyVueSourceDirs = SourceDirTracking(logger: logger, supportedSrcDirectories)\n        var legacyStyleSourceDirs = SourceDirTracking(logger: logger, supportedSrcDirectories)\n        var legacyModuleStyleSourceDirs = SourceDirTracking(logger: logger, supportedSrcDirectories)\n        let supportedImageResourceDirectories = [\"res\"]\n        var resourceSourceDirs = SourceDirTracking(logger: logger, supportedImageResourceDirectories)\n        let supportedSqlDirectories = [\"sql\", \"sqlite\"]\n        var sqlSourceDirs = SourceDirTracking(logger: logger, supportedSqlDirectories)\n        var sqlItems: [CompilationItem] = []\n        var protoDeclSourceDirs = SourceDirTracking(logger: logger, [\"src\", \"test\"])\n        var idsYaml: String? = nil\n\n        for item in items {\n            let isTypescriptDeclarationSource = item.sourceURL.lastPathComponent.hasSuffix(FileExtensions.typescriptDeclaration)\n\n            if isTypescriptDeclarationSource {\n                declarationTSSourceDirs.append(item)\n            } else if [FileExtensions.typescriptDeclaration, FileExtensions.typescript, FileExtensions.typescriptXml].contains(item.sourceURL.pathExtension) {\n                nonDeclarationTSSourceDirs.append(item)\n            }\n            if item.sourceURL.pathExtension == FileExtensions.vue {\n                legacyVueSourceDirs.append(item)\n            }\n            if FileExtensions.fonts.contains(item.sourceURL.pathExtension) {\n                resourceSourceDirs.append(item)\n            }\n            if FileExtensions.legacyStyles.contains(item.sourceURL.pathExtension) {\n                legacyStyleSourceDirs.append(item)\n            }\n\n            let isLegacyModuleStyleSource = FileExtensions.legacyModuleStyles.contains { item.sourceURL.lastPathComponent.hasSuffix($0) }\n            if isLegacyModuleStyleSource {\n                legacyModuleStyleSourceDirs.append(item)\n            }\n            if item.sourceURL.pathExtension == FileExtensions.javascript {\n                jsSourceDirs.append(item)\n            }\n            if FileExtensions.images.contains(item.sourceURL.pathExtension) {\n                resourceSourceDirs.append(item)\n            }\n            if Files.stringsJSON == item.sourceURL.lastPathComponent {\n                // FIXME: implement strings.json detection here to validate a situation where it's present, but strings_dir is not configured?\n            }\n            if FileExtensions.sql.contains(item.sourceURL.pathExtension) || Files.sqlTypesYaml == item.sourceURL.lastPathComponent {\n                if item.relativeBundleURL.path.hasPrefix(\"sql\") {\n                    sqlSourceDirs.append(item)\n                    sqlItems.append(item)\n                } else {\n                    // We have cases with .sql/.sq files that are under src/ instead of sql/\n                    // Those should _not_ be processed\n                }\n            }\n            if item.sourceURL.pathExtension == FileExtensions.protoDecl {\n                protoDeclSourceDirs.append(item)\n            }\n\n            if case .ids(_) = item.kind {\n                // We currently only support one ids.yaml file within a valdi module\n                idsYaml = item.relativeBundleURL.path\n            } else if case .resourceDocument = item.kind {\n                if item.sourceURL.pathExtension == FileExtensions.json {\n                    jsonSourceDirs.append(item)\n               }\n            }\n        }\n\n        let noCompiledValdiModuleOutput = [\n            // intentionally excluding declarationTSSourceDirs, since those do not produce output\n            nonDeclarationTSSourceDirs,\n            jsSourceDirs,\n            legacyVueSourceDirs,\n            legacyStyleSourceDirs,\n            legacyModuleStyleSourceDirs,\n            resourceSourceDirs,\n            sqlSourceDirs,\n            protoDeclSourceDirs\n        ].allSatisfy(\\.isEmpty) && !hasNonTSConfigJsonFile(jsonSourceDirs: jsonSourceDirs)\n\n        let sqlDatabaseNames: [String]?\n        if !sqlItems.isEmpty {\n            // See database naming logic from ClientSqlProcessor.runSqlDelight...\n            // This seems very fragile\n            let sqlItemPathComponents: [[String]] = sqlItems\n                .compactMap { item in\n                    let components = item.relativeBundleURL.path.components(separatedBy: \"/\")\n                    return components\n                }\n                .filter { $0.last != \"sql_types.yaml\" }\n                .filter { $0[safe: $0.count-2] != \"migration\" }\n            let dbPathComponents = sqlItemPathComponents\n                .map { $0.dropFirst().first! }\n\n            let uniquedDbPathComponents = Set(dbPathComponents).sorted()\n\n            if uniquedDbPathComponents.isEmpty {\n                throw CompilerError(\"Could not detect the sql database name for module '\\(moduleName)' items: \\(sqlItems.map(\\.relativeProjectPath))\")\n            }\n            sqlDatabaseNames = uniquedDbPathComponents\n        } else {\n            sqlDatabaseNames = nil\n        }\n\n        let sortedDeps = Set(bundleInfo.dependencies)\n            .filter { !$0.isRoot }\n            .sorted(by: { $0.resolvedBundleName() < $1.resolvedBundleName() })\n\n        let iosDeps = sortedDeps.map { $0.iosModuleName }\n\n        let iosOutputTarget = bundleInfo.outputTarget(platform: .ios)\n        let androidOutputTarget = bundleInfo.outputTarget(platform: .android)\n\n        // Determine if the module has native exports\n        // Default to true for safety if annotation processing hasn't run or failed\n        var hasIOSExports: Bool\n        var hasAndroidExports: Bool\n        if let manager = nativeCodeGenerationManager {\n            hasIOSExports = manager.hasIOSExports(for: bundleInfo)\n            hasAndroidExports = manager.hasAndroidExports(for: bundleInfo)\n        } else {\n            // No manager available (shouldn't happen in normal flow, but default to safe value)\n            hasIOSExports = true\n            hasAndroidExports = true\n        }\n        \n        // Also check Vue files for native exports\n        let vueExports = checkVueFilesForNativeExports(legacyVueSourceDirs)\n        hasIOSExports = hasIOSExports || vueExports.hasIOSExports\n        hasAndroidExports = hasAndroidExports || vueExports.hasAndroidExports\n\n        let config = ModuleBuildTargetConfig(projectConfig: self.projectConfig,\n                                             name: moduleName,\n                                             iosModuleName: bundleInfo.iosModuleName,\n                                             iosLanguage: bundleInfo.iosLanguage,\n                                             iosGeneratedContextFactories: bundleInfo.iosGeneratedContextFactories,\n                                             iosOutputTarget: iosOutputTarget,\n                                             androidOutputTarget: androidOutputTarget,\n                                             declarationTSSourceDirs: declarationTSSourceDirs,\n                                             nonDeclarationTSSourceDirs: nonDeclarationTSSourceDirs,\n                                             jsonSourceDirs: jsonSourceDirs,\n                                             jsSourceDirs: jsSourceDirs,\n                                             legacyVueSourceDirs: legacyVueSourceDirs,\n                                             legacyStyleSourceDirs: legacyStyleSourceDirs,\n                                             legacyModuleStyleSourceDirs: legacyModuleStyleSourceDirs,\n                                             resourceSourceDirs: resourceSourceDirs,\n                                             sqlSourceDirs: sqlSourceDirs,\n                                             sqlDatabaseNames: sqlDatabaseNames,\n                                             protoDeclSourceDirs: protoDeclSourceDirs,\n                                             disableAnnotationProcessing: bundleInfo.disableAnnotationProcessing,\n                                             asyncStrictMode: bundleInfo.asyncStrictMode,\n                                             stringsDir: bundleInfo.stringsConfig?.bundleRelativePath,\n                                             idsYaml: idsYaml,\n                                             noCompiledValdiModuleOutput: noCompiledValdiModuleOutput,\n                                             downloadableAssets: bundleInfo.downloadableAssets,\n                                             downloadableSources: bundleInfo.downloadableSources,\n                                             singleFileCodegen: bundleInfo.singleFileCodegen,\n                                             hasIOSExports: hasIOSExports,\n                                             hasAndroidExports: hasAndroidExports,\n                                             iosDeps: iosDeps,\n                                             excludePatterns: bundleInfo.inclusionConfig.excludePatterns,\n                                             excludeGlobs: bundleInfo.excludeGlobs,\n                                             deps: sortedDeps)\n        let moduleBuildFile = ModuleBuildFile(config: config)\n        return moduleBuildFile\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let itemsByModuleName = items.allItems.groupBy { item in\n            return item.bundleInfo.name\n        }\n\n        var generatedModuleBuildFiles: [String: ModuleBuildFile] = [:]\n        let baseDir = projectConfig.baseDir\n\n        for (moduleName, items) in itemsByModuleName {\n            guard let bundleInfo = items.first?.bundleInfo else {\n                // technically unreachable\n                throw CompilerError(\"Each module must have at least one item\")\n            }\n\n            if !bundleInfo.disableBazelBuildFileGeneration && !baseDir.relativePath(to: bundleInfo.baseDir).hasPrefix(\"../\") {\n                let generatedModuleBuildFile = try generateModuleBuildFile(moduleName: moduleName, bundleInfo: bundleInfo, items: items)\n                generatedModuleBuildFiles[moduleName] = generatedModuleBuildFile\n            }\n        }\n\n\n        return try items.select { (item) -> ModuleBuildFile? in\n            guard case .moduleYaml = item.kind, let moduleBuildFile = generatedModuleBuildFiles[item.bundleInfo.name] else { return nil }\n            return moduleBuildFile\n        }.transformEach { (selectedItem: SelectedItem<ModuleBuildFile>) -> [CompilationItem] in\n            let generatedFile = selectedItem.data\n            let moduleName = selectedItem.item.bundleInfo.name\n\n            let contents = try generatedFile.generateContents()\n            let file = File.data(try contents.utf8Data())\n\n            let finalFile = FinalFile(outputURL: baseDir.appendingPathComponent(moduleName).appendingPathComponent(\"BUILD.bazel\"),\n                                      file: file,\n                                      platform: nil,\n                                      kind: .unknown)\n            let buildFileItem = selectedItem.item.with(newKind: .finalFile(finalFile))\n            return [selectedItem.item, buildFileItem]\n        }\n    }\n    \n    /// Scans Vue files for native exports that can be defined via:\n    /// 1. <class-mapping> sections with ios= or android= attributes\n    /// 2. Standard Typescript export annotations (from ValdiAnnotationType.nativeExportAnnotationNames)\n    private func checkVueFilesForNativeExports(_ vueSourceDirs: SourceDirTracking) -> (hasIOSExports: Bool, hasAndroidExports: Bool) {\n        var hasIOSExports = false\n        var hasAndroidExports = false\n        \n        // Regex patterns to detect iOS and Android exports in Vue files\n        // Pattern 1: <class-mapping> sections with ios= or android= attributes\n        // Matches: <SomeView ios=\"SCClassName\" android=\"com.package.ClassName\"/>\n        let classMappingIosPattern = try? NSRegularExpression(pattern: #\"\\bios\\s*=\\s*[\"\\'][^\"\\']+[\"\\']\"#, options: [])\n        let classMappingAndroidPattern = try? NSRegularExpression(pattern: #\"\\bandroid\\s*=\\s*[\"\\'][^\"\\']+[\"\\']\"#, options: [])\n        \n        // Pattern 2: TypeScript annotations with ios/android parameters\n        // Build regex pattern dynamically from ValdiAnnotationType.nativeExportAnnotationNames\n        // This ensures that if new annotation types are added, they will be automatically included\n        let annotationNames = ValdiAnnotationType.nativeExportAnnotationNames.joined(separator: \"|\")\n        let annotationIosPattern = try? NSRegularExpression(pattern: \"@(?:\\(annotationNames))\\\\s*\\\\([^)]*\\\\bios\\\\s*:\\\\s*['\\\"][^'\\\"]+['\\\"]\", options: [])\n        let annotationAndroidPattern = try? NSRegularExpression(pattern: \"@(?:\\(annotationNames))\\\\s*\\\\([^)]*\\\\bandroid\\\\s*:\\\\s*['\\\"][^'\\\"]+['\\\"]\", options: [])\n        \n        for item in vueSourceDirs.items {\n            guard item.sourceURL.pathExtension == FileExtensions.vue else { continue }\n            \n            // Read the Vue file content\n            guard let content = try? String(contentsOf: item.sourceURL, encoding: .utf8) else { continue }\n            \n            let range = NSRange(content.startIndex..<content.endIndex, in: content)\n            \n            // Check for iOS exports (class-mapping or annotations)\n            if !hasIOSExports {\n                if let pattern = classMappingIosPattern, pattern.firstMatch(in: content, options: [], range: range) != nil {\n                    hasIOSExports = true\n                } else if let pattern = annotationIosPattern, pattern.firstMatch(in: content, options: [], range: range) != nil {\n                    hasIOSExports = true\n                }\n            }\n            \n            // Check for Android exports (class-mapping or annotations)\n            if !hasAndroidExports {\n                if let pattern = classMappingAndroidPattern, pattern.firstMatch(in: content, options: [], range: range) != nil {\n                    hasAndroidExports = true\n                } else if let pattern = annotationAndroidPattern, pattern.firstMatch(in: content, options: [], range: range) != nil {\n                    hasAndroidExports = true\n                }\n            }\n            \n            // Early exit if both exports are found\n            if hasIOSExports && hasAndroidExports {\n                break\n            }\n        }\n        \n        return (hasIOSExports, hasAndroidExports)\n    }\n\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GenerateViewClassesProcessor.swift",
    "content": "//\n//  GenerateViewClassesProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.document] -> [.document, .nativeSource]\nclass GenerateViewClassesProcessor: CompilationProcessor {\n\n    private let logger: ILogger\n    private let compilerConfig: CompilerConfig\n\n    init(logger: ILogger, compilerConfig: CompilerConfig) {\n        self.logger = logger\n        self.compilerConfig = compilerConfig\n    }\n\n    var description: String {\n        return \"Generating View Classes\"\n    }\n\n    private func generateViewClass(item: CompilationItem, compilationResult: CompilationResult) -> [CompilationItem] {\n        let rawDocument = compilationResult.originalDocument\n        let compiledDocument = compilationResult.templateResult\n\n        let rootNodeType = rawDocument.template?.rootNode?.nodeType ?? \"\"\n        guard let classMapping = rawDocument.classMapping?.nodeMappingByClass[rootNodeType] else {\n                logger.debug(\"Not generating view class for \\(item.sourceURL.path) because the root node doesn't have a custom class.\")\n                return []\n        }\n        let generatedSourceFilename = GeneratedSourceFilename(filename: item.relativeProjectPath, symbolName: compilationResult.componentPath.exportedMember)\n        let iosType = classMapping.iosType\n        let androidClassName = classMapping.androidClassName\n\n        let generator = ViewClassGenerator(bundleInfo: item.bundleInfo,\n                                           logger: logger,\n                                           compiledDocument: compiledDocument,\n                                           rawDocument: rawDocument,\n                                           componentPath: compilationResult.componentPath,\n                                           sourceFilename: generatedSourceFilename,\n                                           iosType: iosType,\n                                           iosLanguage: item.bundleInfo.iosLanguage,\n                                           androidClassName: androidClassName)\n        do {\n            guard let result = try generator.generate() else {\n                return []\n            }\n\n            for nativeSource in result.nativeSources {\n                logger.debug(\"-- Generated \\(nativeSource.source.filename)\")\n            }\n            let nativeSourceItems = result.nativeSources.map { item.with(newKind: .nativeSource($0.source), newPlatform: $0.platform) }\n            let typeDescription = GeneratedTypeDescription.viewClass(result.description)\n            let descriptionItem = item.with(newKind: .generatedTypeDescription(typeDescription), newPlatform: .none)\n            return nativeSourceItems + [descriptionItem]\n        } catch let error {\n            logger.error(\"Failed to generate View class for \\(item.sourceURL.path): \\(error.legibleLocalizedDescription)\")\n            return []\n        }\n    }\n\n    func generateViewClass(selectedItem: SelectedItem<CompilationResult>) -> [CompilationItem] {\n        var out = generateViewClass(item: selectedItem.item,\n                                    compilationResult: selectedItem.data)\n        out.append(selectedItem.item)\n        return out\n    }\n\n    private func shouldProcessItem(item: CompilationItem) -> Bool {\n        guard !compilerConfig.onlyGenerateNativeCodeForModules.isEmpty else {\n            return true\n        }\n        return compilerConfig.onlyGenerateNativeCodeForModules.contains(item.bundleInfo.name)\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> CompilationResult? in\n            guard shouldProcessItem(item: item), case .document(let result) = item.kind else {\n                return nil\n            }\n\n            return result\n        }.transformEachConcurrently(generateViewClass)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/GeneratedTypesVerificationProcessor.swift",
    "content": "//\n//  GeneratedTypesVerificationProcessor.swift\n//  Compiler\n//\n//  Created by saniul on 25/07/2019.\n//\n\nimport Foundation\n\nclass GeneratedTypesVerificationProcessor: CompilationProcessor {\n    let projectConfig: ValdiProjectConfig\n\n    var description: String {\n        return \"Verifying generated types\"\n    }\n\n    private let logger: ILogger\n\n    init(logger: ILogger, projectConfig: ValdiProjectConfig) {\n        self.logger = logger\n        self.projectConfig = projectConfig\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        try items.select { item -> GeneratedTypeDescription? in\n            guard case let .generatedTypeDescription(generatedTypeDescription) = item.kind else {\n                return nil\n            }\n            return generatedTypeDescription\n            }.processAll { selectedItems in\n                let duplicatesByPlatform = Platform.allCases.associate { (platform: Platform) -> (Platform, [String: [CompilationItem]]) in\n                    let grouped = selectedItems.compactMap { selectedItem -> (String, CompilationItem)? in\n                        guard let typename = selectedItem.data.typeName(for: platform) else { return nil }\n                        return (typename, selectedItem.item)\n                        }\n                        .group { typeName, item in\n                            (typeName, item)\n                        }\n                        .filter { _, items in\n                            items.count > 1\n                    }\n                    return (platform, grouped)\n                    }\n                    .filter { _, itemsByType in\n                        itemsByType.count > 0\n                }\n                // duplicatesByPlatform should be a [Platform: [String: [CompilationItem]]] which only contains duplicated types\n\n                guard !duplicatesByPlatform.isEmpty else {\n                    return\n                }\n\n                for (platform, dupedTypes) in duplicatesByPlatform {\n                    logger.error(\"🚨 Conflicting generated type names for platform: \\(platform.rawValue, color: .red)🚨\")\n\n                    for (index, tuple) in dupedTypes.enumerated() {\n                        let (dupedType, items) = tuple\n                        logger.error(\"\\(index+1). Type: \\(dupedType):\")\n\n                        for item in items {\n                            logger.error(\"-- Source URL: \\(item.sourceURL.relativePath(from: projectConfig.baseDir))\")\n                        }\n                    }\n\n                    logger.error(\"\")\n                }\n\n                throw CompilerError(\"Conflicting generated type names\")\n        }\n\n        return items\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/HotReloadingProcessor.swift",
    "content": "//\n//  HotReloadingProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.finalFile] -> [.finalFile]\nclass HotReloadingProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Notifying Document changes over the network\"\n    }\n\n    private struct FinalImage {\n        let scale: Double\n        let data: Data\n\n    }\n\n    private let logger: ILogger\n    private let daemonService: DaemonService\n\n    init(logger: ILogger, daemonService: DaemonService) {\n        self.logger = logger\n        self.daemonService = daemonService\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        var allAddedResource = [Resource]()\n\n        for item in items.allItems {\n            guard case .finalFile(let finalFile) = item.kind, item.outputTarget.contains(.debug) else {\n                continue\n            }\n\n            switch finalFile.kind {\n            case .compiledSource, .assetsPackage:\n                do {\n                    let data = try finalFile.file.readData()\n                    let resource = Resource(item: item, finalFile: finalFile, data: data)\n                    allAddedResource.append(resource)\n                } catch let error {\n                    logger.error(\"Failed to hot reload file \\(item.bundleInfo.name)/\\(item.relativeBundleURL.path) : \\(error.legibleLocalizedDescription)\")\n                }\n            case .nativeSource, .unknown, .image, .dependencyInjectionData:\n                // Only compiled sources and assets packages can be handled\n                break\n            }\n        }\n\n        if !allAddedResource.isEmpty {\n            daemonService.resourcesDidChange(resources: allAddedResource)\n        }\n\n        return items\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/IdentifyFontAssetsProcessor.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nclass IdentifyFontAssetsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Identifying Font assets\"\n    }\n\n    private func identifyFont(selectedItem: SelectedItem<File>) -> CompilationItem {\n        let relativeBundleURL = selectedItem.item.relativeBundleURL\n\n        let outputFilename = \"\\(relativeBundleURL.deletingPathExtension().lastPathComponent.snakeCased).\\(relativeBundleURL.pathExtension)\"\n\n        return selectedItem.item.with(newKind: .resourceDocument(DocumentResource(outputFilename: outputFilename, file: selectedItem.data)))\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { item -> File? in\n            if case .rawResource(let file) = item.kind, FileExtensions.fonts.contains(item.sourceURL.pathExtension) {\n                return file\n            }\n            return nil\n        }.transformEach(identifyFont)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/IdentifyImageAssetsProcessor.swift",
    "content": "//\n//  IdentifyImageAssetsProcessor.swift\n//  \n//\n//  Created by Simon Corsin on 2/12/20.\n//\n\nimport Foundation\n\nprivate struct IdentifiedImage {\n    let resolvedVariant: ResolvedImageVariant\n    let imageInfo: ImageInfo\n    let url: URL\n\n    var densityIndependentSize: ImageSize {\n        return imageInfo.size.scaled(1.0 / resolvedVariant.variant.scale)\n    }\n}\n\nprivate struct IdentifiedImageItem {\n    let item: SelectedItem<URL>\n    let image: IdentifiedImage\n}\n\n// [.rawResource] -> [.imageAsset]\nclass IdentifyImageAssetsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Identifying Image assets\"\n    }\n\n    private let logger: ILogger\n    private let compilerConfig: CompilerConfig\n\n    private let imageToolbox: ImageToolbox\n    private let lock = DispatchSemaphore.newLock()\n    private var previousIdentifiedItemsByPath: [String: [IdentifiedImageItem]] = [:]\n    private static let maxImageSizeDeviation = 2\n    private let cache: DiskCache?\n\n    init(logger: ILogger, imageToolbox: ImageToolbox, compilerConfig: CompilerConfig, diskCacheProvider: DiskCacheProvider) throws {\n        self.logger = logger\n        self.imageToolbox = imageToolbox\n        self.compilerConfig = compilerConfig\n        if diskCacheProvider.isEnabled() {\n            let version = try imageToolbox.getVersion()\n            self.cache = diskCacheProvider.newCache(cacheName: \"identify_images\", outputExtension: \"json\", metadata: [\"image_toolbox_version\": version])\n        } else {\n            self.cache = nil\n        }\n    }\n\n    private func getImageInfo(item: CompilationItem, inputURL: URL) throws -> ToolboxExecutable.ImageInfoOutput {\n        guard let cache else {\n            return try imageToolbox.getInfo(inputPath: inputURL.path)\n        }\n\n        let inputData = try File.url(inputURL).readData()\n\n        let output = cache.getOutput(compilationItem: item, inputData: inputData)\n\n        if let output, let imageInfoOutput = try? ToolboxExecutable.ImageInfoOutput.fromJSON(output) {\n            return imageInfoOutput\n        }\n\n        let imageInfoOutput = try imageToolbox.getInfo(inputPath: inputURL.path)\n\n        try cache.setOutput(compilationItem: item, inputData: inputData, outputData: try imageInfoOutput.toJSON())\n\n        return imageInfoOutput\n    }\n\n    private func identifyImage(item: CompilationItem, imageURL: URL) -> Promise<IdentifiedImage> {\n        do {\n            let variant = try ImageVariantResolver.resolveVariant(imageURL: imageURL, relativeProjectPath: item.relativeProjectPath)\n\n            let assetName = variant.assetIdentifier.assetName\n\n            if assetName.lowercased() != assetName {\n                throw CompilerError(\"Invalid filename '\\(assetName)', image filenames need to be lowercased\")\n            }\n\n            let imageInfo: ImageInfo\n            if compilerConfig.generateTSResFiles {\n                // Image size is not needed when just generating TS res files\n                imageInfo = ImageInfo(size: ImageSize(width: 0, height: 0))\n            } else {\n                let info = try getImageInfo(item: item, inputURL: imageURL)\n                imageInfo = ImageInfo(size: ImageSize(width: info.width, height: info.height))\n            }\n\n            return Promise(data: IdentifiedImage(resolvedVariant: variant, imageInfo: imageInfo, url: imageURL))\n        } catch let error {\n            return Promise(error: error)\n        }\n    }\n\n    private func getIdentifiedItemsByPath(items: [SelectedItem<URL>], resolvedImagePromises: [Promise<IdentifiedImage>], out: inout [CompilationItem]) -> [String: [IdentifiedImageItem]] {\n        var identifiedItemsByPath: [String: [IdentifiedImageItem]] = [:]\n        let previousIdentifiedItemsByPath = lock.lock { self.previousIdentifiedItemsByPath }\n\n        for (index, item) in items.enumerated() {\n            let imagePromise = resolvedImagePromises[index]\n\n            do {\n                let resolvedImage = try imagePromise.waitForData()\n\n                let virtualPath = resolvedImage.resolvedVariant.assetIdentifier.virtualPath\n\n                var identifiedItems = identifiedItemsByPath[virtualPath, default: []]\n\n                if identifiedItems.isEmpty {\n                    // Re-add previously identified items, so that we can support hot reload on images\n                    if let previousItems = previousIdentifiedItemsByPath[virtualPath] {\n                        // Only re-add the items that have a different url than the one we're processing\n                        for previousItem in previousItems where previousItem.item.data != item.data {\n                            identifiedItems.append(previousItem)\n                        }\n                    }\n                }\n\n                identifiedItems.append(IdentifiedImageItem(item: item, image: resolvedImage))\n\n                identifiedItemsByPath[virtualPath] = identifiedItems\n            } catch let error {\n                out.append(item.item.with(error: error))\n            }\n        }\n\n        return identifiedItemsByPath\n    }\n\n    private func validateImageVariantsSizes(items: [IdentifiedImageItem], densityIndependentSize: ImageSize) throws {\n        var failed = false\n\n        for item in items {\n            let currentDPSize = item.image.densityIndependentSize\n\n            let widthDeviation = abs(densityIndependentSize.width - currentDPSize.width)\n            let heightDeviation = abs(densityIndependentSize.height - currentDPSize.height)\n            if widthDeviation > IdentifyImageAssetsProcessor.maxImageSizeDeviation || heightDeviation > IdentifyImageAssetsProcessor.maxImageSizeDeviation {\n                failed = true\n                break\n            }\n        }\n\n        if failed {\n            let detailMessage: String = items.map {\n                let dp = $0.image.densityIndependentSize\n                let pixels = $0.image.imageInfo.size\n                return \"\\($0.item.item.sourceURL.path): \\(dp.width)x\\(dp.height)dp (\\(pixels.width)x\\(pixels.height)px)\"\n            }.joined(separator: \"\\n\")\n            let errorMessage = \"Incorrect image sizes, the density independent size of those images varies by more than \\(IdentifyImageAssetsProcessor.maxImageSizeDeviation)dp:\\n\\(detailMessage)\\n\\nPlease find and remove the incorrect images.\"\n            throw CompilerError(errorMessage)\n        }\n    }\n\n    private func createImageAssetItems(identifiedItemsByPath: [String: [IdentifiedImageItem]]) -> [CompilationItem] {\n        var out = [CompilationItem]()\n\n        for (virtualPath, items) in identifiedItemsByPath {\n            lock.lock {\n                 self.previousIdentifiedItemsByPath[virtualPath] = items\n             }\n\n            // Take the highest available scale our base\n            let sortedItems = items.sorted(by: { (left, right) in\n                if left.image.resolvedVariant.variant.scale == right.image.resolvedVariant.variant.scale {\n                    // Use the file path on disk to sort in case of equality (e.g. iOS @3x with Android xxhdpi)\n                    return left.item.data.absoluteString > right.item.data.absoluteString\n                } else {\n                    return left.image.resolvedVariant.variant.scale > right.image.resolvedVariant.variant.scale\n                }\n            })\n            let highestItem = sortedItems.last!\n            let imageSize = highestItem.image.densityIndependentSize\n\n            do {\n                if !compilerConfig.generateTSResFiles {\n                    try validateImageVariantsSizes(items: sortedItems, densityIndependentSize: imageSize)\n                }\n\n                var allVariants = items.map { ImageAssetVariant(imageInfo: $0.image.imageInfo, file: .url($0.image.url), variantSpecs: $0.image.resolvedVariant.variant) }\n                allVariants.sort { left, right in\n                    return left.variantSpecs.scale < right.variantSpecs.scale\n                }\n\n                let imageAsset = ImageAsset(identifier: highestItem.image.resolvedVariant.assetIdentifier, size: imageSize, variants: allVariants)\n                out.append(highestItem.item.item.with(newKind: .imageAsset(imageAsset)))\n            } catch let error {\n                logger.error(error.legibleLocalizedDescription)\n                out.append(highestItem.item.item.with(error: error))\n            }\n        }\n\n        return out\n    }\n\n    private func identifyAssets(items: [SelectedItem<URL>]) -> [CompilationItem] {\n        let filteredItems = items.filter { selectedItem in\n            if !compilerConfig.onlyProcessResourcesForModules.isEmpty && !compilerConfig.onlyProcessResourcesForModules.contains(selectedItem.item.bundleInfo.name) {\n                return false\n            }\n            return true\n        }\n\n        // Step 1: identify all images and find their size\n        let resolvedImagePromises = filteredItems.parallelMap { self.identifyImage(item: $0.item, imageURL: $0.data) }\n\n        var out = [CompilationItem]()\n\n        // Step 2: Group the images by their asset identifier\n\n        let identifiedItemsByPath = getIdentifiedItemsByPath(items: filteredItems, resolvedImagePromises: resolvedImagePromises, out: &out)\n\n        // Step 3: Generate Compilation items backed by ImageAsset's\n\n        out += createImageAssetItems(identifiedItemsByPath: identifiedItemsByPath)\n\n        return out\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> URL? in\n            if case .rawResource(let file) = item.kind, case .url(let url) = file, FileExtensions.exportedImages.contains(url.pathExtension) {\n                return url\n            }\n            return nil\n        }\n        .transformAll(identifyAssets)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/IdentifyItemsProcessor.swift",
    "content": "//\n//  IdentifyItemsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.unknown] -> [.rawDocument, .typeScript, .javaScript, .css, .rawResource, .unknown]\nclass IdentifyItemsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Identifying items\"\n    }\n\n    private let logger: ILogger\n    private let ignoredFiles: [NSRegularExpression]\n\n    init(logger: ILogger, ignoredFiles: [NSRegularExpression]) {\n        self.logger = logger\n        self.ignoredFiles = ignoredFiles\n    }\n\n    private func shouldIgnore(inputURL: URL) -> Bool {\n        let filename = inputURL.lastPathComponent\n        return filename.matches(anyRegex: ignoredFiles)\n    }    \n\n    private func findKind(inputURL: URL, bundle: CompilationItem.BundleInfo, relativeProjectPath: String) -> CompilationItem.Kind {\n        let filename = inputURL.lastPathComponent\n\n        if filename == Files.classMapping {\n            return .classMapping(.url(inputURL))\n        } else if filename == Files.compilationMetadata {\n            return .compilationMetadata(.url(inputURL))\n        } else if filename.hasPrefix(Files.stringsJSONPrefix) && filename.hasSuffix(Files.stringsJSONSuffix) {\n            return .stringsJSON(.url(inputURL))\n        } else if filename == Files.moduleYaml {\n            return .moduleYaml(.url(inputURL))\n        } else if filename == Files.buildFile {\n            return .buildFile(.url(inputURL))\n        } else if filename == Files.ids {\n            return .ids(.url(inputURL))\n        } else if filename == Files.sqlTypesYaml {\n            return .sql(.url(inputURL))\n        } else if filename == Files.sqlManifestYaml {\n            return .sqlManifest(.url(inputURL))\n        }\n\n        switch inputURL.pathExtension {\n        case FileExtensions.vue:\n            return .rawDocument(.url(inputURL))\n        case FileExtensions.typescript, FileExtensions.typescriptXml:\n            return .typeScript(.url(inputURL), inputURL)\n        case FileExtensions.javascript:\n            return .javaScript(JavaScriptFile(file: .url(inputURL), relativePath: relativeProjectPath))\n        case FileExtensions.sass, FileExtensions.css:\n            return .css(.url(inputURL))\n        case FileExtensions.kotlin:\n            return .kotlin(.url(inputURL), inputURL)\n        case FileExtensions.protoDecl:\n            return .resourceDocument(DocumentResource(outputFilename: inputURL.lastPathComponent, file: .url(inputURL)))\n        case FileExtensions.json:\n            return .resourceDocument(DocumentResource(outputFilename: bundle.itemPath(forItemURL: inputURL), file: .url(inputURL)))\n        case FileExtensions.bin:\n            return .resourceDocument(DocumentResource(outputFilename: bundle.itemPath(forItemURL: inputURL), file: .url(inputURL)))\n        case FileExtensions.downloadableArtifacts:\n            return .downloadableArtifactSignatures(DownloadableArtifactSignatures(key: inputURL.deletingPathExtension().lastPathComponent, file: .url(inputURL)))\n        case let ext where FileExtensions.sql.contains(ext):\n            return .sql(.url(inputURL))\n        case let ext where FileExtensions.images.contains(ext) || FileExtensions.fonts.contains(ext):\n            return .rawResource(.url(inputURL))\n        default:\n            return .unknown(.url(inputURL))\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.selectAll().transformEachConcurrently { (item) -> [CompilationItem] in\n            if case .unknown(let file) = item.kind, case .url(let url) = file {\n                if shouldIgnore(inputURL: url) {\n                    logger.debug(\"-- Ignoring file: \\(url.lastPathComponent)\")\n                    return []\n                }\n\n                let newKind = findKind(inputURL: url, bundle: item.bundleInfo, relativeProjectPath: item.relativeProjectPath)\n                return [item.with(newKind: newKind)]\n            }\n            return [item]\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/ImageResourcesProcessor.swift",
    "content": "//\n//  ImageResourcesProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.imageAsset] -> [.imageResource]\nclass ImageResourcesProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Processing Resources\"\n    }\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let alwaysUseVariantAgnosticFilenames: Bool\n    private let diskCacheProvider: DiskCacheProvider\n    private let projectConfig: ValdiProjectConfig\n    private let compilerConfig: CompilerConfig\n    private let imageConverter: ImageConverter\n    private var cacheByExtension: [String: DiskCache] = [:]\n    private let lock = DispatchSemaphore.newLock()\n    private var imageConverterDependencies: [String: String]?\n    private let imageVariantsFilter: ImageVariantsFilter?\n\n    init(logger: ILogger, \n         fileManager: ValdiFileManager,\n         diskCacheProvider: DiskCacheProvider,\n         projectConfig: ValdiProjectConfig,\n         compilerConfig: CompilerConfig,\n         imageToolbox: ImageToolbox,\n         imageVariantsFilter: ImageVariantsFilter?,\n         alwaysUseVariantAgnosticFilenames: Bool) throws {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.diskCacheProvider = diskCacheProvider\n        self.projectConfig = projectConfig\n        self.compilerConfig = compilerConfig\n        self.imageVariantsFilter = imageVariantsFilter\n        self.alwaysUseVariantAgnosticFilenames = alwaysUseVariantAgnosticFilenames\n        self.imageConverter = ImageConverter(logger: logger, fileManager: fileManager, projectConfig: projectConfig, imageToolbox: imageToolbox)\n\n        // Warm up the disk caches we know we will use\n        FileExtensions.exportedImages.forEach { imageExt in\n            DispatchQueue.global().async {\n                _ = try? self.getDiskCache(forExtension: imageExt)\n            }\n        }\n    }\n\n    private func lockFreeGetOrCreateImageConverterDependenciesVersions() throws -> [String: String] {\n        if let imageConverterDependencies {\n            return imageConverterDependencies\n        }\n\n        let imageConverterDependencies = try imageConverter.dependenciesVersions()\n        self.imageConverterDependencies = imageConverterDependencies\n        return imageConverterDependencies\n    }\n\n    private func getDiskCache(forExtension ext: String) throws -> DiskCache? {\n        return try lock.lock {\n            if let diskCache = cacheByExtension[ext] {\n                return diskCache\n            }\n\n            guard diskCacheProvider.isEnabled() else { return nil }\n\n            guard let diskCache = diskCacheProvider.newCache(cacheName: \"image_processing/\\(ext)\", outputExtension: ext, metadata: try lockFreeGetOrCreateImageConverterDependenciesVersions()) else {\n                return nil\n            }\n\n            self.cacheByExtension[ext] = diskCache\n\n            return diskCache\n        }\n    }\n\n    private func getGeneratedImageFromCache(cacheKey: String, inputImageData: Data, cache: DiskCache) -> Data? {\n        guard let outputData = cache.getOutput(item: cacheKey, inputData: inputImageData) else {\n            return nil\n        }\n\n        return outputData\n    }\n\n    private func generateImage(fromImageAssetVariant: ImageAssetVariant, sourceItemProjectPath: String, inputImageURL: URL, inputImageData: Data, variantSpecs: ImageVariantSpecs) throws -> ImageAssetVariant {\n        let diskCache = try getDiskCache(forExtension: variantSpecs.fileExtension)\n\n        let cacheKey = \"\\(variantSpecs.identifier)/\\(sourceItemProjectPath)\"\n\n        let conversionInfo = imageConverter.getConversionInfo(sourceImage: fromImageAssetVariant, targetVariantSpecs: variantSpecs)\n        let outputImageInfo = ImageInfo(size: conversionInfo.outputSize)\n\n        if let diskCache = diskCache {\n            if let cachedImage = getGeneratedImageFromCache(cacheKey: cacheKey, inputImageData: inputImageData, cache: diskCache) {\n                logger.verbose(\"-- Using cached generated image from \\(sourceItemProjectPath) with variant \\(variantSpecs.identifier)\")\n\n                return ImageAssetVariant(imageInfo: outputImageInfo, file: .data(cachedImage), variantSpecs: variantSpecs)\n            }\n        }\n\n        logger.debug(\"-- Generating image from \\(sourceItemProjectPath) into variant \\(variantSpecs.identifier)\")\n\n        let outputFileURL = URL.randomFileURL(extension: variantSpecs.fileExtension)\n        defer {\n            _ = try? FileManager.default.removeItem(at: outputFileURL)\n        }\n\n        let resultImageInfo = try imageConverter.convert(imageInfo: fromImageAssetVariant.imageInfo, filePath: inputImageURL.path, outputFileURL: outputFileURL, conversionInfo: conversionInfo)\n\n        let outputData = try File.url(outputFileURL).readData()\n\n        try diskCache?.setOutput(item: cacheKey, inputData: inputImageData, outputData: outputData)\n\n        return ImageAssetVariant(imageInfo: resultImageInfo, file: .data(outputData), variantSpecs: variantSpecs)\n    }\n\n    private func shouldInclude(variantSpecs: ImageVariantSpecs) -> Bool {\n        guard let platform = variantSpecs.platform, let imageVariantsFilter else {\n            return true\n        }\n\n        return imageVariantsFilter.shouldInclude(platform: platform, scale: variantSpecs.scale)\n    }\n\n    private func findMissingVariants(currentVariants: [ImageAssetVariant]) -> [ImageVariantSpecs] {\n        let existingVariants = Set(currentVariants.map { $0.variantSpecs.identifier })\n        return ImageVariantResolver.allExportedVariantSpecs.filter { shouldInclude(variantSpecs: $0) && !existingVariants.contains($0.identifier) }\n    }\n\n    private func makeImageResourceItem(fromCompilationItem: CompilationItem, imageAsset: ImageAsset) -> [CompilationItem] {\n        let variants = imageAsset.variants.filter { $0.variantSpecs.platform != nil }\n\n        var items = [CompilationItem]()\n        if fromCompilationItem.bundleInfo.downloadableAssets || alwaysUseVariantAgnosticFilenames {\n            for variant in variants {\n                let outputFilename = \"\\(imageAsset.identifier.assetName).\\(variant.variantSpecs.fileExtension)\"\n                let imageResource = ImageResource(outputFilename: outputFilename, file: variant.file, imageScale: variant.variantSpecs.scale, isRemote: true)\n\n                items.append(fromCompilationItem.with(newKind: .processedResourceImage(imageResource), newPlatform: variant.variantSpecs.platform))\n            }\n        } else {\n            for variant in variants {\n                let resolvedFilename: String\n                if variant.variantSpecs.platform == .android {\n                    // On Android, we prefix by the module_name for uniqueness, since the asset won't be\n                    // stored in a unique .bundle\n                    resolvedFilename = \"\\(fromCompilationItem.bundleInfo.name)_\\(imageAsset.identifier.assetName)\"\n                } else {\n                    resolvedFilename = imageAsset.identifier.assetName\n                }\n\n                let outputFilename = variant.variantSpecs.resolveFilename(assetName: resolvedFilename)\n                let imageResource = ImageResource(outputFilename: outputFilename, file: variant.file, imageScale: variant.variantSpecs.scale, isRemote: false)\n\n                items.append(fromCompilationItem.with(newKind: .processedResourceImage(imageResource), newPlatform: variant.variantSpecs.platform))\n            }\n        }\n\n        return items\n    }\n\n    private func processImageAsset(item: SelectedItem<ImageAsset>) -> [CompilationItem] {\n        do {\n            guard !item.data.variants.isEmpty else {\n                throw CompilerError(\"No variants available!\")\n            }\n\n            // Step 1: We find the image variants which we don't currently have\n            let missingVariants = findMissingVariants(currentVariants: item.data.variants)\n\n            // Step 2: Find the variant we can use for resizing the images\n            let bestVariant = item.data.bestVariant!\n\n            let inputImage = bestVariant.file\n\n            return try inputImage.withURL { url in\n                // Step 3: Generate all the missing variants\n\n                let generatedImages = try missingVariants.map { try generateImage(fromImageAssetVariant: bestVariant, sourceItemProjectPath: item.item.relativeProjectPath, inputImageURL: url, inputImageData: try inputImage.readData(), variantSpecs: $0) }\n\n                let allVariants = (item.data.variants + generatedImages).filter { variant in\n                    return shouldInclude(variantSpecs: variant.variantSpecs)\n                }\n\n                let newImageAsset = ImageAsset(identifier: item.data.identifier, size: item.data.size, variants: allVariants)\n                return makeImageResourceItem(fromCompilationItem: item.item, imageAsset: newImageAsset)\n            }\n        } catch let error {\n            let errorMessage = \"Failed to process image asset from \\(item.item.relativeProjectPath): \\(error.legibleLocalizedDescription)\"\n            logger.error(errorMessage)\n            return [item.item.with(error: CompilerError(errorMessage))]\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { item in\n            if !compilerConfig.onlyProcessResourcesForModules.isEmpty && !compilerConfig.onlyProcessResourcesForModules.contains(item.bundleInfo.name) {\n                return nil\n            }\n\n            if case .imageAsset(let asset) = item.kind {\n                return asset\n            }\n            return nil\n        }.transformEachConcurrently(processImageAsset)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/InvalidDocumentsProcessor.swift",
    "content": "//\n//  InvalidDocumentsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.invalidDocument] -> [.resourceDocument]\nclass InvalidDocumentsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Handling document errors\"\n    }\n\n    private let logger: ILogger\n    private let generateErrorDocuments: Bool\n    private let compilationPipeline: [CompilationProcessor]\n    private let projectConfig: ValdiProjectConfig\n\n    init(logger: ILogger, generateErrorDocuments: Bool, compilationPipeline: [CompilationProcessor], projectConfig: ValdiProjectConfig) {\n        self.logger = logger\n        self.generateErrorDocuments = generateErrorDocuments\n        self.compilationPipeline = compilationPipeline\n        self.projectConfig = projectConfig\n    }\n\n    private func makeItems(forKotlinError error: Error, item: CompilationItem) -> [CompilationItem] {\n        // TODO(simon): Implements\n        // Need some kind of way to know which components have failed\n        return []\n    }\n\n    private func makeItems(forError error: Error, message: String, item: CompilationItem) -> [CompilationItem] {\n        let relativeURL = URL(string: item.relativeProjectPath)!\n\n        guard relativeURL.pathExtension != FileExtensions.vue else {\n            let relativeURLWithExtension = relativeURL.appendingPathExtension(FileExtensions.typescript)\n            // Case for vue template which failed compilation before we emitted the item.\n            // We generate a new item as if the template compiled succesfully with the error\n            // script.\n            let generatedSourceURL = TypeScriptCompilerManager.generatedUrl(url: relativeURLWithExtension)\n            let generatedItem = CompilationItem(sourceURL: generatedSourceURL,\n                                                relativeProjectPath: relativeURLWithExtension.path,\n                                                kind: .error(error, originalItemKind: item.kind),\n                                                bundleInfo: item.bundleInfo,\n                                                platform: item.platform,\n                                                outputTarget: item.outputTarget)\n            return makeItems(forError: error, message: message, item: generatedItem)\n        }\n\n        //TODO(3521): update to valdi_core\n        let errorDocument = \"\"\"\n        let errorClass;\n        try {\n          errorClass = require('valdi_core/src/utils/CompilerError').CompilerError;\n        } catch (err) {\n          errorClass = Error;\n        }\n        throw new errorClass('\\(message.jsonEscaped)');\n        \"\"\"\n\n        do {\n            let data = try errorDocument.utf8Data()\n            let relativePath = relativeURL.deletingPathExtension().appendingPathExtension(FileExtensions.javascript).path\n            return [item.with(newKind: .javaScript(JavaScriptFile(file: .data(data), relativePath: relativePath)))]\n        } catch let error {\n            logger.error(\"Failed to generate Error document: \\(error.legibleLocalizedDescription)\")\n            return []\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        var out = [CompilationItem]()\n        var failuresCount = 0\n\n        func handle(error: Error, messagePrefix: String, item: CompilationItem) {\n            let message = \"\\(messagePrefix): \\(error.legibleLocalizedDescription)\"\n\n            if generateErrorDocuments {\n                out += makeItems(forError: error, message: message, item: item)\n            } else {\n                failuresCount += 1\n            }\n        }\n\n        for item in items.allItems {\n            if case .error(let error, let sourceItem) = item.kind {\n                switch sourceItem {\n                case .rawDocument, .document, .parsedDocument:\n                    handle(error: error, messagePrefix: \"Failed to process document from \\(item.relativeProjectPath)\", item: item)\n                case .typeScript:\n                    handle(error: error, messagePrefix: \"Failed to compile TypeScript from \\(item.relativeProjectPath)\", item: item)\n                case .stringsJSON:\n                    let messagePrefix = \"Failed to compile strings from \\(item.relativeProjectPath): \\(error.legibleLocalizedDescription)\"\n                    let jsOutputPath = TypeScriptStringsModuleGenerator.outputPath(bundleName: item.bundleInfo.name, ext: FileExtensions.javascript)\n                    let jsOutputURL = item.bundleInfo.absoluteURL(forRelativeProjectPath: jsOutputPath)\n                    let item = CompilationItem(sourceURL: jsOutputURL, relativeProjectPath: nil, kind: .error(error, originalItemKind: sourceItem), bundleInfo: item.bundleInfo, platform: item.platform, outputTarget: item.outputTarget)\n                    handle(error: error, messagePrefix: messagePrefix, item: item)\n                case .kotlin:\n                    handle(error: error, messagePrefix: \"Failed to compile Kotlin from \\(item.relativeProjectPath)\", item: item)\n                default:\n                    break\n                }\n            } else {\n                out.append(item)\n            }\n        }\n\n        if failuresCount > 0 {\n            throw CompilerError(\"Got \\(failuresCount) errors.\")\n        }\n\n        return CompilationItems(compileSequence: items.compileSequence, items: out)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/JavaScriptPreCompiler.swift",
    "content": "//\n//  File.swift\n//\n//\n//  Created by Simon Corsin on 1/24/20.\n//\n\nimport Foundation\n\nclass JavaScriptPreCompilerProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Pre-compiling JavaScript files\"\n    }\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let toolboxExecutable: ToolboxExecutable\n    private let diskCache: DiskCache?\n    private let androidJsBytecodeFormat: String?\n\n    init(logger: ILogger,\n         fileManager: ValdiFileManager,\n         diskCacheProvider: DiskCacheProvider,\n         toolboxExecutable: ToolboxExecutable,\n         androidJsBytecodeFormat: String?) throws {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.toolboxExecutable = toolboxExecutable\n        self.androidJsBytecodeFormat = androidJsBytecodeFormat\n\n        if diskCacheProvider.isEnabled() {\n            let versionString = try toolboxExecutable.getVersionString()\n            self.diskCache = diskCacheProvider.newCache(cacheName: \"js_precompiler\", outputExtension: \"jsbin\", metadata: [\n                \"toolbox_version\": versionString,\n                \"android_js_bytecode_format\": androidJsBytecodeFormat ?? \"\"\n            ])\n        } else {\n            self.diskCache = nil\n        }\n\n    }\n\n    private func compile(item: SelectedItem<JavaScriptFile>) -> [CompilationItem] {\n        var output = [CompilationItem]()\n        if item.item.shouldOutputToIOS {\n            output.append(item.item.with(newPlatform: .ios))\n        }\n        if item.item.shouldOutputToWeb {\n            output.append(item.item.with(newPlatform: .web))\n        }\n\n        // Early out if we're not looking at Android\n        if !item.item.shouldOutputToAndroid {\n            return output\n        }\n\n        if item.item.outputTarget.contains(.debug) {\n            output.append(item.item.with(newKind: item.item.kind, newPlatform: .android, newOutputTarget: .debug))\n        }\n\n        guard let androidJsBytecodeFormat = self.androidJsBytecodeFormat else {\n            output.append(item.item.with(newKind: item.item.kind, newPlatform: .android, newOutputTarget: .release))\n            return output\n        }\n\n        do {\n            let jsPath = item.data.relativePath\n            logger.debug(\"-- Pre-compiling JavaScript file \\(jsPath)\")\n\n            let data = try item.data.file.readData()\n\n            if let cachedData = diskCache?.getOutput(item: jsPath, platform: .android, target: .release, inputData: data) {\n                let outputJsFile = item.data.with(file: .data(cachedData))\n                output.append(item.item.with(newKind: .javaScript(outputJsFile), newPlatform: .android))\n                return output\n            }\n\n            let inputFile = URL.randomFileURL(extension: \"js\")\n            let outputFile = URL.randomFileURL(extension: \"js\")\n            try fileManager.save(data: data, to: inputFile)\n            defer {\n                _ = try? fileManager.delete(url: inputFile)\n                _ = try? fileManager.delete(url: outputFile)\n            }\n\n            // Remove .js suffix, JS files are referred without their extension\n            // in the consumer code\n            var filename = jsPath\n            if filename.hasSuffix(\".js\") {\n                filename.removeLast(3)\n            }\n\n            try toolboxExecutable.precompile(inputFilePath: inputFile.path, outputFilePath: outputFile.path, filename: filename, engine: androidJsBytecodeFormat)\n\n            let outputData = try File.url(outputFile).readData()\n\n            let outputJsFile = item.data.with(file: .data(outputData))\n            try diskCache?.setOutput(item: jsPath, platform: .android, target: .release, inputData: data, outputData: outputData)\n\n            output.append(item.item.with(newKind: .javaScript(outputJsFile), newPlatform: .android))\n\n            return output\n        } catch let error {\n            logger.error(error.legibleLocalizedDescription)\n            return [item.item.with(error: error)]\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> JavaScriptFile? in\n            if !item.shouldOutputToAndroid || item.bundleInfo.compilationModeConfig.resolveCompilationMode(forItemPath: item.relativeProjectPath) == .js || !item.outputTarget.contains(.release) {\n                return nil\n            }\n\n            switch item.kind {\n            case .javaScript(let file):\n                return file\n            default:\n                return nil\n            }\n        }.transformEachConcurrently(compile)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/LoadDumpedClassMappingProcessor.swift",
    "content": "import Foundation\n\nclass LoadCompilationMetadataProcessor: CompilationProcessor {\n\n    let projectClassMappingManager: ProjectClassMappingManager\n\n    var description: String {\n        return \"Load serialized compilation metadata\"\n    }\n\n    private let typeScriptCompilationManager: TypeScriptCompilerManager\n    private let typeScriptNativeTypeResolver: TypeScriptNativeTypeResolver\n\n    init(projectClassMappingManager: ProjectClassMappingManager, typeScriptCompilationManager: TypeScriptCompilerManager, typeScriptNativeTypeResolver: TypeScriptNativeTypeResolver) {\n        self.projectClassMappingManager = projectClassMappingManager\n        self.typeScriptCompilationManager = typeScriptCompilationManager\n        self.typeScriptNativeTypeResolver = typeScriptNativeTypeResolver\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let decoder = JSONDecoder()\n\n        let selectedItems = items.select { item -> File? in\n            guard case let .compilationMetadata(file) = item.kind else {\n                return nil\n            }\n\n            return file\n        }\n\n        return try selectedItems.transformAll { selectedItems in\n            for selectedItem in selectedItems {\n                let file = selectedItem.data\n\n                let decoded = try decoder.decode(CompilationMetadata.self, from: try file.readData())\n                try projectClassMappingManager.mutate { mapping in\n                    for (k, v) in decoded.classMappings {\n                        mapping.registerResolved(fullyQualifiedName: k, klass: v)\n                    }\n                }\n\n\n                try typeScriptNativeTypeResolver.restore(fromSerialized: decoded.nativeTypes)\n            }\n            return []\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/MinifyJsProcessor.swift",
    "content": "//\n//  MinifyJsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 9/19/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nenum Minifier: String {\n    case uglifyJS = \"uglify-js\"\n    case terser = \"terser\"\n}\n\nlet minifierToUse = Minifier.terser\n\nstruct BatchMinifyResult: Codable {\n    let fileURL: String\n    let uglified: String?\n    let error: String?\n}\n\n// [.javaScript] -> [.javaScript]\nclass MinifyJsProcessor: CompilationProcessor {\n    let companion: CompanionExecutable\n\n    var description: String {\n        return \"Minify JavaScript\"\n    }\n\n    private let logger: ILogger\n    private var diskCache: DiskCache?\n    private let minifyOptions: String?\n    private let disableMinifyWeb: Bool\n\n    // These minify options are the same as minifyOptions, but will keep preserve line numbers\n    private let beautifyMinifyOptions: String?\n\n    // QuickJS stack traces don't include line numbers, so we need to beautify the output for proper tracing.\n    private let androidIsQuickJS: Bool\n\n    init(logger: ILogger, diskCacheProvider: DiskCacheProvider, projectConfig: ValdiProjectConfig, companion: CompanionExecutable, disableMinifyWeb: Bool) {\n        self.logger = logger\n        self.companion = companion\n        self.disableMinifyWeb = disableMinifyWeb\n        self.minifyOptions = projectConfig.minifyConfigURL.flatMap { try? String(contentsOf: $0, encoding: .utf8 )}\n        self.androidIsQuickJS = projectConfig.androidJsBytecodeFormat == \"quickjs\"\n\n        do {\n            let minifyOptionsData = minifyOptions?.data(using: .utf8) ?? Data()\n            var minifyOptionsJson = try JSONSerialization.jsonObject(with: minifyOptionsData, options: []) as? [String: Any] ?? [:]\n            minifyOptionsJson[\"output\"] = [\"beautify\": true, \"indent_level\": 0]\n            let beautifyMinifyOptionsData = try JSONSerialization.data(withJSONObject: minifyOptionsJson, options: [.prettyPrinted])\n            self.beautifyMinifyOptions = String(data: beautifyMinifyOptionsData, encoding: .utf8)\n        } catch {\n            self.beautifyMinifyOptions = nil\n        }\n\n        self.diskCache = diskCacheProvider.newCache(cacheName: \"uglify_build\",\n                                                    outputExtension: FileExtensions.javascript,\n                                                    metadata: [\"minifier\": minifierToUse.rawValue,\n                                                                \"options\": self.minifyOptions ?? \"\"\n                                                                ])\n    }\n\n    private func doMinifyBatch(items: [SelectedItem<JavaScriptFile>], minifyOptions: String?) throws -> [CompilationItem] {\n        items.forEach {\n            logger.debug(\"-- Minifying JavaScript file \\($0.data.relativePath)\")\n        }\n\n        let itemsAndURLHandles = try items.parallelMap { (item: $0, urlHandle: try $0.data.file.getURLHandle()) }\n\n        return try withExtendedLifetime(itemsAndURLHandles) { _ -> [CompilationItem] in\n            let urls = itemsAndURLHandles.map { $0.urlHandle.url }\n\n            let uglifyResults = try companion.batchMinifyJS(inputURLs: urls,\n                                                            minifier: minifierToUse,\n                                                            options: minifyOptions).waitForData()\n\n            let uglifyResultsByFileURL = try uglifyResults.associateUnique { ($0.fileURL, $0) }\n\n            return try itemsAndURLHandles.map {\n                let compilationItem = $0.item.item\n\n                guard let uglifyResult = uglifyResultsByFileURL[$0.urlHandle.url.absoluteString] else {\n                    return compilationItem.with(error: CompilerError(\"Couldn't get uglify result\"))\n                }\n\n                if let errorMessage = uglifyResult.error {\n                    return compilationItem.with(error: CompilerError(\"Minify error: \\(errorMessage)\"))\n                } else {\n                    let data = (try uglifyResult.uglified?.utf8Data()) ?? Data()\n                    let outputJs = $0.item.data.with(file: .data(data))\n                    return compilationItem.with(newKind: .javaScript(outputJs))\n                }\n            }\n        }\n    }\n\n    private func uglifyBatch(items: [SelectedItem<JavaScriptFile>], minifyOptions: String?, platforms: [Platform?]) -> [CompilationItem] {\n        do {\n            var itemsToMinify: [(Data, SelectedItem<JavaScriptFile>)] = []\n            var outItems: [CompilationItem] = []\n\n            for selectedItem in items {\n                let inputData = try selectedItem.data.file.readData() + (minifyOptions?.data(using: .utf8) ?? Data())\n\n                if let cachedData = diskCache?.getOutput(compilationItem: selectedItem.item, inputData: inputData) {\n                    let outputJsFile = selectedItem.data.with(file: .data(cachedData))\n                    outItems.append(selectedItem.item.with(newKind: .javaScript(outputJsFile), newPlatform: selectedItem.item.platform, newOutputTarget: .debug))\n                    if selectedItem.item.outputTarget.contains(.release) {\n                        outItems.append(selectedItem.item.with(newKind: .javaScript(outputJsFile), newPlatform: selectedItem.item.platform, newOutputTarget: .release))\n                    }\n                } else {\n                    itemsToMinify.append((inputData, selectedItem))\n                }\n            }\n\n            if !itemsToMinify.isEmpty {\n                let uglifiedItems = try doMinifyBatch(items: itemsToMinify.map { $0.1 }, minifyOptions: minifyOptions)\n\n                for (index, item) in uglifiedItems.enumerated() {\n                    switch item.kind {\n                    case .javaScript(let jsFile):\n                        for platform in platforms {\n                            outItems.append(item.with(newKind: item.kind, newPlatform: platform, newOutputTarget: .debug))\n                            if item.outputTarget.contains(.release) {\n                                outItems.append(item.with(newKind: item.kind, newPlatform: platform, newOutputTarget: .release))\n                            }\n                        }\n                        let inputData = itemsToMinify[index].0\n                        try diskCache?.setOutput(compilationItem: item, inputData: inputData, outputData: try jsFile.file.readData())\n                    default:\n                        outItems.append(item)\n                    }\n                }\n            }\n\n            return outItems\n        } catch {\n            return items.map { $0.item.with(error: error) }\n        }\n    }\n\n    private func passThrough(items: [SelectedItem<JavaScriptFile>], platforms: [Platform?]) -> [CompilationItem] {\n        do {\n            var passThroughItems: [(Data, SelectedItem<JavaScriptFile>)] = []\n            var outItems: [CompilationItem] = []\n\n            for selectedItem in items {\n                let inputData = try selectedItem.data.file.readData()\n\n                if let cachedData = diskCache?.getOutput(compilationItem: selectedItem.item, inputData: inputData) {\n                    let outputJsFile = selectedItem.data.with(file: .data(cachedData))\n                    outItems.append(selectedItem.item.with(newKind: .javaScript(outputJsFile), newPlatform: selectedItem.item.platform, newOutputTarget: .debug))\n                    if selectedItem.item.outputTarget.contains(.release) {\n                        outItems.append(selectedItem.item.with(newKind: .javaScript(outputJsFile), newPlatform: selectedItem.item.platform, newOutputTarget: .release))\n                    }\n                } else {\n                    passThroughItems.append((inputData, selectedItem))\n                }\n            }\n\n            for (index, rawItem) in passThroughItems.enumerated() {\n                let item = rawItem.1.item\n                switch item.kind {\n                case .javaScript(let jsFile):\n                    for platform in platforms {\n                        outItems.append(item.with(newKind: item.kind, newPlatform: platform, newOutputTarget: .debug))\n                        if item.outputTarget.contains(.release) {\n                            outItems.append(item.with(newKind: item.kind, newPlatform: platform, newOutputTarget: .release))\n                        }\n                    }\n                    let inputData = passThroughItems[index].0\n                    try diskCache?.setOutput(compilationItem: item, inputData: inputData, outputData: try jsFile.file.readData())\n                default:\n                    outItems.append(item)\n                }\n            }\n            return outItems\n        } catch {\n            return items.map { $0.item.with(error: error) }\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let selectedItems = items.select { item -> JavaScriptFile? in\n            switch item.kind {\n            case .javaScript(let file):\n                return file\n            default:\n                return nil\n            }\n        }\n        return selectedItems.transformInBatches { items -> [CompilationItem] in\n            if androidIsQuickJS && self.beautifyMinifyOptions != nil {\n                var batches = uglifyBatch(items: items, minifyOptions: self.minifyOptions, platforms: [.ios]) +\n                    uglifyBatch(items: items, minifyOptions: self.beautifyMinifyOptions, platforms: [.android]) \n                if disableMinifyWeb {\n                    batches += passThrough(items: items, platforms: [.web])\n                } else {\n                    batches += uglifyBatch(items: items, minifyOptions: self.minifyOptions, platforms: [.web])\n                }\n                return batches\n            } else {\n                // Use the same minify options for all platforms\n                return uglifyBatch(items: items, minifyOptions: self.minifyOptions, platforms: [nil])\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/NativeCodeGenerationManager.swift",
    "content": "//\n//  NativeCodeGenerationManager.swift\n//  Compiler\n//\n//  Created by saniul on 13/06/2019.\n//\n\nimport Foundation\n\n// TODO: Most mentions of \"NativeClassXXX\" should probably say \"NativeTypeXXX\"\nstruct NativeClassToGenerate {\n    let annotation: ValdiTypeScriptAnnotation\n    let commentedFile: TypeScriptCommentedFile\n    let annotatedSymbol: TypeScriptAnnotatedSymbol\n    let dumpedSymbol: TS.DumpedSymbolWithComments\n    let sourceURL: URL\n    let nativeClass: TypeScriptNativeClass\n    let compilationItem: CompilationItem\n    let linesIndexer: LinesIndexer\n    let kind: NativeTypeKind\n}\n\nenum NativeClassPurpose {\n    case unspecified\n    case viewModel\n    case context\n}\n\nstruct NativeTypesToGenerate {\n    let iosType: IOSType?\n    let androidClass: String?\n    let cppType: CPPType?\n}\n\nstruct NativeFunctionToGenerate {\n    let annotation: ValdiTypeScriptAnnotation\n    let commentedFile: TypeScriptCommentedFile\n    let annotatedSymbol: TypeScriptAnnotatedSymbol\n    let dumpedSymbol: TS.DumpedSymbolWithComments\n    let sourceURL: URL\n\n    let src: TypeScriptItemSrc\n    let tsTypeName: String\n    let nativeTypes: NativeTypesToGenerate\n\n    let compilationItem: CompilationItem\n    let linesIndexer: LinesIndexer\n}\n\nstruct NativeModuleToGenerate {\n    let annotation: ValdiTypeScriptAnnotation\n    let commentedFile: TypeScriptCommentedFile\n    let annotatedSymbol: TypeScriptAnnotatedSymbol\n    let dumpedSymbol: TS.DumpedSymbolWithComments\n\n    let tsTypeName: String\n    let nativeTypes: NativeTypesToGenerate\n\n    let compilationItem: CompilationItem\n}\n\nclass NativeCodeGenerationManager {\n    private let logger: ILogger\n\n    let globalIosImport: String?\n\n    let nativeTypeResolver: TypeScriptNativeTypeResolver\n\n    private var nativeClassesToGenerate = Synchronized<[NativeClassToGenerate]>(data: [])\n    private var viewClassesToGenerate = Synchronized<[NativeClassToGenerate]>(data: [])\n    private var nativeFunctionsToGenerate = Synchronized<[NativeFunctionToGenerate]>(data: [])\n    private var nativeModulesToGenerate = Synchronized<[NativeModuleToGenerate]>(data: [])\n    private var viewModelSymbolNameBySourceURL = Synchronized<[URL: String]>(data: [:])\n    private var contextSymbolNameBySourceURL = Synchronized<[URL: String]>(data: [:])\n\n    init(logger: ILogger, globalIosImport: String?, rootURL: URL) {\n        self.logger = logger\n        self.globalIosImport = globalIosImport\n        self.nativeTypeResolver = TypeScriptNativeTypeResolver(rootURL: rootURL)\n    }\n\n    func addNativeTypeToGenerate(commentedFile: TypeScriptCommentedFile, annotation: ValdiTypeScriptAnnotation, sourceURL: URL, annotatedSymbol: TypeScriptAnnotatedSymbol, compilationItem: CompilationItem, linesIndexer: LinesIndexer, kind: NativeTypeKind, isComponent: Bool) throws {\n        let nativeTypeToGenerate = try makeNativeClassToGenerate(\n            commentedFile: commentedFile,\n            annotation: annotation,\n            sourceURL: sourceURL,\n            annotatedSymbol: annotatedSymbol,\n            compilationItem: compilationItem,\n            linesIndexer: linesIndexer,\n            kind: kind,\n            isComponent: isComponent)\n\n        if isComponent {\n            viewClassesToGenerate.data { $0.append(nativeTypeToGenerate) }\n        } else {\n            nativeClassesToGenerate.data { $0.append(nativeTypeToGenerate) }\n        }\n    }\n\n    private func makeNativeTypesToGenerate(symbolName: String,\n                                           commentedFile: TypeScriptCommentedFile,\n                                           annotation: ValdiTypeScriptAnnotation,\n                                           compilationItem: CompilationItem) throws  -> NativeTypesToGenerate {\n        var iosContainingTypeName = annotation.parameters?[\"ios\"]\n        let swiftContainingTypeName = annotation.parameters?[\"swift\"] ?? annotation.parameters?[\"ios\"] ?? symbolName\n        var androidContainingClassName = annotation.parameters?[\"android\"]\n\n        if compilationItem.shouldOutputToIOS && iosContainingTypeName == nil {\n            iosContainingTypeName = inferIOSClassName(symbolName: symbolName, bundleInfo: compilationItem.bundleInfo)\n        }\n\n        if compilationItem.shouldOutputToAndroid && androidContainingClassName == nil {\n            androidContainingClassName = inferAndroidClassName(symbolName: symbolName, bundleInfo: compilationItem.bundleInfo)\n        }\n\n        var iosContainingType = iosContainingTypeName.map { IOSType(name: $0, swiftName: swiftContainingTypeName, bundleInfo: compilationItem.bundleInfo, kind: .class, iosLanguage: compilationItem.bundleInfo.iosLanguage) }\n\n        if let overridenIosImport = annotation.parameters?[\"iosImportPrefix\"] {\n            iosContainingType?.applyImportPrefix(iosImportPrefix: overridenIosImport, isOverridden: true)\n        } else {\n            iosContainingType?.applyImportPrefix(iosImportPrefix: compilationItem.bundleInfo.iosModuleName, isOverridden: false)\n        }\n\n        let cppType = try resolveGeneratedCppType(commentedFile: commentedFile, annotation: annotation, symbolName: symbolName, symbolType: .class, bundleInfo: compilationItem.bundleInfo)\n\n        return NativeTypesToGenerate(\n            iosType: compilationItem.bundleInfo.iosCodegenEnabled ? iosContainingType : nil,\n            androidClass: compilationItem.bundleInfo.androidCodegenEnabled ? androidContainingClassName : nil,\n            cppType: cppType)\n    }\n\n    func addNativeModuleToGenerate(commentedFile: TypeScriptCommentedFile, annotation: ValdiTypeScriptAnnotation, sourceURL: URL, annotatedSymbol: TypeScriptAnnotatedSymbol, compilationItem: CompilationItem, linesIndexer: LinesIndexer) throws {\n\n\n\n        let fileNameWithoutExtension = commentedFile.src.compilationPath\n            .removing(suffixes: FileExtensions.typescriptFileExtensionsDotted)\n            .lastPathComponent()\n            .replacingOccurrences(of: \".\", with: \"_\")\n        let symbolName = \"\\(fileNameWithoutExtension)_Module\".pascalCased\n\n        let nativeTypes = try makeNativeTypesToGenerate(symbolName: symbolName, commentedFile: commentedFile, annotation: annotation, compilationItem: compilationItem)\n\n        let nativeModuleToGenerate = NativeModuleToGenerate(\n            annotation: annotation,\n            commentedFile: commentedFile,\n            annotatedSymbol: annotatedSymbol,\n            dumpedSymbol: annotatedSymbol.symbol,\n            tsTypeName: symbolName,\n            nativeTypes: nativeTypes,\n            compilationItem: compilationItem)\n        nativeModulesToGenerate.data {\n            $0.append(nativeModuleToGenerate)\n        }\n    }\n\n    func addNativeFuncToGenerate(commentedFile: TypeScriptCommentedFile, annotation: ValdiTypeScriptAnnotation, sourceURL: URL, annotatedSymbol: TypeScriptAnnotatedSymbol, compilationItem: CompilationItem, linesIndexer: LinesIndexer) throws {\n        let nativeFuncToGenerate = try makeNativeFuncToGenerate(commentedFile: commentedFile, annotation: annotation, sourceURL: sourceURL, annotatedSymbol: annotatedSymbol, compilationItem: compilationItem, linesIndexer: linesIndexer)\n        nativeFunctionsToGenerate.data { $0.append(nativeFuncToGenerate) }\n    }\n\n    func hasIOSExports(for bundleInfo: CompilationItem.BundleInfo) -> Bool {\n        let hasIOSClasses = nativeClassesToGenerate.data { classes in\n            classes.contains { $0.compilationItem.bundleInfo.name == bundleInfo.name && $0.nativeClass.iosType != nil }\n        }\n        let hasIOSViewClasses = viewClassesToGenerate.data { classes in\n            classes.contains { $0.compilationItem.bundleInfo.name == bundleInfo.name && $0.nativeClass.iosType != nil }\n        }\n        let hasIOSFunctions = nativeFunctionsToGenerate.data { functions in\n            functions.contains { $0.compilationItem.bundleInfo.name == bundleInfo.name && $0.nativeTypes.iosType != nil }\n        }\n        let hasIOSModules = nativeModulesToGenerate.data { modules in\n            modules.contains { $0.compilationItem.bundleInfo.name == bundleInfo.name && $0.nativeTypes.iosType != nil }\n        }\n        return hasIOSClasses || hasIOSViewClasses || hasIOSFunctions || hasIOSModules\n    }\n\n    func hasAndroidExports(for bundleInfo: CompilationItem.BundleInfo) -> Bool {\n        let hasAndroidClasses = nativeClassesToGenerate.data { classes in\n            classes.contains { $0.compilationItem.bundleInfo.name == bundleInfo.name && $0.nativeClass.androidClass != nil }\n        }\n        let hasAndroidViewClasses = viewClassesToGenerate.data { classes in\n            classes.contains { $0.compilationItem.bundleInfo.name == bundleInfo.name && $0.nativeClass.androidClass != nil }\n        }\n        let hasAndroidFunctions = nativeFunctionsToGenerate.data { functions in\n            functions.contains { $0.compilationItem.bundleInfo.name == bundleInfo.name && $0.nativeTypes.androidClass != nil }\n        }\n        let hasAndroidModules = nativeModulesToGenerate.data { modules in\n            modules.contains { $0.compilationItem.bundleInfo.name == bundleInfo.name && $0.nativeTypes.androidClass != nil }\n        }\n        return hasAndroidClasses || hasAndroidViewClasses || hasAndroidFunctions || hasAndroidModules\n    }\n\n    func addNativeTypeConverter(commentedFile: TypeScriptCommentedFile, annotation: ValdiTypeScriptAnnotation, sourceURL: URL, annotatedSymbol: TypeScriptAnnotatedSymbol, compilationItem: CompilationItem, linesIndexer: LinesIndexer) throws {\n        let symbol = annotatedSymbol.symbol\n        guard let function = symbol.function else {\n            try throwAnnotationError(annotation, commentedFile, message: \"@NativeTypeConverter must be set on a function\")\n        }\n\n        let kindModifiers = (symbol.kindModifiers ?? \"\").split(separator: \" \")\n\n        guard kindModifiers.contains(\"export\") else {\n            try throwAnnotationError(annotation, commentedFile, message: \"@NativeTypeConverter must be set on a function that is exported (please add export keyword)\")\n        }\n\n        guard let typeArguments = function.type.returnValue.typeArguments, typeArguments.count == 2 else {\n            try throwAnnotationError(annotation, commentedFile, message: \"@NativeTypeConverter must be set on a function that returns a generic type with two parameters\")\n        }\n\n        let fromType = typeArguments[0].type\n        let toType = typeArguments[1].type\n\n        guard let typeReferenceIndexFromType = fromType.typeReferenceIndex, let typeReferenceIndexToType = toType.typeReferenceIndex else {\n            try throwAnnotationError(annotation, commentedFile, message: \"Expecting type references on the return value generic type\")\n        }\n\n        guard typeReferenceIndexFromType >= 0 && typeReferenceIndexFromType < commentedFile.references.count else {\n            throw CompilerError(\"Out of bounds type reference \\(typeReferenceIndexFromType)\")\n        }\n        guard typeReferenceIndexToType >= 0 && typeReferenceIndexToType < commentedFile.references.count else {\n            throw CompilerError(\"Out of bounds type reference \\(typeReferenceIndexFromType)\")\n        }\n\n\n        let typeReferenceFromType = commentedFile.references[typeReferenceIndexFromType]\n        let typeReferenceToType = commentedFile.references[typeReferenceIndexToType]        \n\n        nativeTypeResolver.registerTypeConverter(src: commentedFile.src, emittingBundleName: compilationItem.bundleInfo.name, tsTypeName: symbol.text, fromTypePath: typeReferenceFromType.fileName, tsFromTypeName: typeReferenceFromType.name, toTypePath: typeReferenceToType.fileName, tsToTypeName: typeReferenceToType.name)\n    }\n\n    func addViewModelSymbol(sourceURL: URL, symbol: String) {\n        viewModelSymbolNameBySourceURL.data { $0[sourceURL] = symbol }\n    }\n\n    func hasViewModelSymbol(for sourceURL: URL) -> Bool {\n        return viewModelSymbolNameBySourceURL.data { $0[sourceURL] != nil }\n    }\n\n    func addContextSymbol(sourceURL: URL, symbol: String) {\n        contextSymbolNameBySourceURL.data { $0[sourceURL] = symbol }\n    }\n\n    func hasContextSymbol(for sourceURL: URL) -> Bool {\n        return contextSymbolNameBySourceURL.data { $0[sourceURL] != nil }\n    }\n\n    func clear() {\n        nativeClassesToGenerate.data { $0.removeAll() }\n        nativeFunctionsToGenerate.data { $0.removeAll() }\n        nativeModulesToGenerate.data { $0.removeAll() }\n        viewModelSymbolNameBySourceURL.data { $0.removeAll() }\n        contextSymbolNameBySourceURL.data { $0.removeAll() }\n        viewClassesToGenerate.data { $0.removeAll() }\n    }\n\n    private func inferIOSClassName(symbolName: String, bundleInfo: CompilationItem.BundleInfo) -> String? {\n        if let iosClassPrefix = bundleInfo.iosClassPrefix {\n            return \"\\(iosClassPrefix)\\(symbolName)\"\n        }\n\n        return \"\\(bundleInfo.iosModuleName)\\(symbolName)\"\n    }\n\n    private func resolveGeneratedIOSClassName(commentedFile: TypeScriptCommentedFile,\n                                              annotation: ValdiTypeScriptAnnotation,\n                                              symbolName: String,\n                                              bundleInfo: CompilationItem.BundleInfo) throws -> String? {\n        guard bundleInfo.iosCodegenEnabled else { return nil }\n\n        let generatedClassName = inferIOSClassName(symbolName: symbolName, bundleInfo: bundleInfo)\n        if let typeName = annotation.parameters?[\"ios\"] {\n            return typeName\n        }\n\n        guard let generatedClassName = generatedClassName else {\n            try throwAnnotationError(annotation, commentedFile, message: \"Cannot infer a generated iOS class name for \\(symbolName) as the 'ios.class_prefix' value was not set in the valdi_config.yaml or module.yaml.\")\n        }\n        return generatedClassName\n    }\n\n    private func resolveGeneratedSwiftClassName(commentedFile: TypeScriptCommentedFile,\n                                                annotation: ValdiTypeScriptAnnotation,\n                                                symbolName: String,\n                                                bundleInfo: CompilationItem.BundleInfo) throws -> String? {\n        guard bundleInfo.iosCodegenEnabled else { return nil }\n        // Swift names are already in namespaces, so no need to add class_prefix\n        return annotation.parameters?[\"swift\"] ?? annotation.parameters?[\"ios\"] ?? symbolName\n    }\n\n    private func inferAndroidClassName(symbolName: String, bundleInfo: CompilationItem.BundleInfo) -> String? {\n        if let androidClassPath = bundleInfo.androidClassPath {\n            return \"\\(androidClassPath).\\(symbolName)\"\n        }\n\n        if let defaultClassPath = bundleInfo.projectConfig.androidDefaultClassPath {\n            return \"\\(defaultClassPath).\\(bundleInfo.name).\\(symbolName)\"\n        }\n\n        return nil\n    }\n\n    private func resolveGeneratedAndroidClassName(commentedFile: TypeScriptCommentedFile,\n                                                  annotation: ValdiTypeScriptAnnotation,\n                                                  symbolName: String,\n                                                  bundleInfo: CompilationItem.BundleInfo) throws -> String? {\n        guard bundleInfo.androidCodegenEnabled else { return nil }\n\n        let generatedClassName = inferAndroidClassName(symbolName: symbolName, bundleInfo: bundleInfo)\n\n        if let typeName = annotation.parameters?[\"android\"] {\n\n            return typeName\n        }\n\n        guard let generatedClassName = generatedClassName else {\n            try throwAnnotationError(annotation, commentedFile, message: \"Cannot infer the generated Android class path for \\(symbolName) as the 'android.class_path' value was not set in the valdi_config.yaml or module.yaml.\")\n        }\n\n        return generatedClassName\n    }\n\n    private func inferCppType(symbolName: String, bundleInfo: CompilationItem.BundleInfo) -> String? {\n        if let cppClassPrefix = bundleInfo.cppClassPrefix {\n            return \"\\(cppClassPrefix)\\(symbolName.pascalCased)\"\n        }\n\n        if let defaultClassPrefix = bundleInfo.projectConfig.cppDefaultClassPrefix {\n            return \"\\(defaultClassPrefix)\\(bundleInfo.name)::\\(symbolName.pascalCased)\"\n        }\n\n        return nil\n    }\n\n    private func resolveGeneratedCppType(commentedFile: TypeScriptCommentedFile,\n                                         annotation: ValdiTypeScriptAnnotation,\n                                         symbolName: String,\n                                         symbolType: CPPTypeDeclaration.SymbolType,\n                                         bundleInfo: CompilationItem.BundleInfo) throws -> CPPType? {\n        guard bundleInfo.cppCodegenEnabled else { return nil }\n        let generatedClassName = inferCppType(symbolName: symbolName, bundleInfo: bundleInfo)\n\n        if let typeName = annotation.parameters?[\"cpp\"] {\n            return CPPType(declaration: CPPTypeDeclaration(name: typeName, symbolType: symbolType), module: bundleInfo, includePrefix: bundleInfo.projectConfig.cppImportPathPrefix)\n        }\n\n        guard let generatedClassName = generatedClassName else {\n            try throwAnnotationError(annotation, commentedFile, message: \"Cannot infer the generated C++ class type for \\(symbolName) as the 'cpp.default_class_prefrix' value was not set in the valdi_config.yaml or module.yaml.\")\n        }\n\n        return CPPType(declaration: CPPTypeDeclaration(name: generatedClassName, symbolType: symbolType), module: bundleInfo, includePrefix: bundleInfo.projectConfig.cppImportPathPrefix)\n    }\n\n    @discardableResult func registerNativeClass(commentedFile: TypeScriptCommentedFile,\n                                                annotation: ValdiTypeScriptAnnotation,\n                                                symbol: TS.DumpedSymbolWithComments,\n                                                shouldGenerateIOS: Bool,\n                                                shouldGenerateAndroid: Bool,\n                                                kind: NativeTypeKind,\n                                                bundleInfo: CompilationItem.BundleInfo,\n                                                isGenerated: Bool) throws -> TypeScriptNativeClass {\n        let iosTypeName = try resolveGeneratedIOSClassName(commentedFile: commentedFile, annotation: annotation, symbolName: symbol.text, bundleInfo: bundleInfo)\n        let swiftTypeName = try resolveGeneratedSwiftClassName(commentedFile: commentedFile, annotation: annotation, symbolName: symbol.text, bundleInfo: bundleInfo)\n        let androidClassName = try resolveGeneratedAndroidClassName(commentedFile: commentedFile, annotation: annotation, symbolName: symbol.text, bundleInfo: bundleInfo)\n\n        let cppSymbolType: CPPTypeDeclaration.SymbolType\n        switch kind {\n        case .interface:\n            cppSymbolType = .class\n        case .class:\n            cppSymbolType = .class\n        case .enum:\n            cppSymbolType = .enum\n        case .stringEnum:\n            cppSymbolType = .enum\n        }\n        let cppType = try resolveGeneratedCppType(commentedFile: commentedFile, annotation: annotation, symbolName: symbol.text, symbolType: cppSymbolType, bundleInfo: bundleInfo)\n\n        let iosType = iosTypeName.flatMap { iosTypeName in\n            var iosType = IOSType(name: iosTypeName, swiftName: swiftTypeName, bundleInfo: bundleInfo, kind: kind, iosLanguage: bundleInfo.iosLanguage)\n            if let overridenIosImport = annotation.parameters?[\"iosImportPrefix\"] {\n                iosType.applyImportPrefix(iosImportPrefix: overridenIosImport, isOverridden: true)\n            } else {\n                iosType.applyImportPrefix(iosImportPrefix: bundleInfo.iosModuleName, isOverridden: false)\n            }\n\n            return iosType\n        }\n\n        let marshallAsUntyped = annotation.parameters?[\"marshallAsUntyped\"] == \"true\"\n        let marshallAsUntypedMap = annotation.parameters?[\"marshallAsUntypedMap\"] == \"true\"\n\n        if isGenerated && marshallAsUntyped == true {\n            try throwAnnotationError(annotation, commentedFile, message: \"Generated types are never marshalled as untyped\")\n        }\n\n        return nativeTypeResolver.register(src: commentedFile.src,\n                                           emittingBundleName: bundleInfo.name,\n                                           tsTypeName: symbol.text,\n                                           iosType: iosType,\n                                           androidClass: androidClassName,\n                                           cppType: cppType,\n                                           kind: kind,\n                                           isGenerated: isGenerated,\n                                           marshallAsUntyped: marshallAsUntyped,\n                                           marshallAsUntypedMap: marshallAsUntypedMap)\n    }\n\n    func createCompilationItems(existingItems: DocumentsIndexer) {\n        var nativeClassesPromises = [Promise<Void>]()\n        let nativeClassesToGenerate = self.nativeClassesToGenerate.data { $0 }\n\n        for nativeClass in nativeClassesToGenerate {\n            var isViewModel = false\n            if let viewModelSymbolName = viewModelSymbolNameBySourceURL.data({ $0[nativeClass.sourceURL] }), viewModelSymbolName == nativeClass.dumpedSymbol.text {\n                isViewModel = true\n            }\n            var isContext = false\n            if let contextSymbolName = contextSymbolNameBySourceURL.data({ $0[nativeClass.sourceURL] }), contextSymbolName == nativeClass.dumpedSymbol.text {\n                isContext = true\n            }\n\n            if isContext && isViewModel {\n                existingItems.injectError(logger: logger, CompilerError(\"Cannot put @ViewModel and @Context on the same symbol\"), relatedItem: nativeClass.compilationItem)\n                continue\n            }\n\n            var nativeClassPurpose = NativeClassPurpose.unspecified\n            if isViewModel {\n                nativeClassPurpose = .viewModel\n            } else if isContext {\n                nativeClassPurpose = .context\n            }\n\n            let promise = generateNativeClass(nativeClass, nativeClassPurpose: nativeClassPurpose, items: existingItems).catch { (error) in\n                existingItems.injectError(logger: self.logger, error, relatedItem: nativeClass.compilationItem)\n            }\n\n            nativeClassesPromises.append(promise)\n        }\n\n        var nativeFunctionsPromises = [Promise<Void>]()\n        let nativeFunctionsToGenerate = self.nativeFunctionsToGenerate.data { $0 }\n        for nativeFunction in nativeFunctionsToGenerate {\n            let logger = self.logger\n            let promise = generateNativeFunction(nativeFunction, items: existingItems).catch { (error) in\n                existingItems.injectError(logger: logger, error, relatedItem: nativeFunction.compilationItem)\n            }\n            nativeFunctionsPromises.append(promise)\n        }\n\n        var nativeModulesPromises = [Promise<Void>]()\n        let nativeModulesToGenerate = self.nativeModulesToGenerate.data { $0 }\n        for nativeModuleToGenerate in nativeModulesToGenerate {\n            let logger = self.logger\n            let promise = generateNativeModule(nativeModuleToGenerate, items: existingItems).catch { (error) in\n                existingItems.injectError(logger: logger, error, relatedItem: nativeModuleToGenerate.compilationItem)\n            }\n            nativeModulesPromises.append(promise)\n        }\n\n        let allPromises = nativeClassesPromises + nativeFunctionsPromises + nativeModulesPromises\n        _ = try? Promise.of(promises: allPromises).waitForData()\n\n        // This needs to happen at the end after we proccessed all the generated types, since some of\n        // the types might inject type informations into the documents\n        viewClassesToGenerate.data { (nativeClasses) in\n            for nativeClass in nativeClasses {\n                updateCompilationItemsForGeneratedViewClass(nativeClassToGenerate: nativeClass, items: existingItems)\n            }\n        }\n    }\n\n    private func updateCompilationItemsForGeneratedViewClass(nativeClassToGenerate: NativeClassToGenerate, items: DocumentsIndexer) {\n        guard var documentAndIndex = items.findDocument(fromSourceURL: nativeClassToGenerate.sourceURL) else {\n            return\n        }\n\n        if documentAndIndex.compilationResult.originalDocument.classMapping == nil {\n            documentAndIndex.compilationResult.originalDocument.classMapping = ValdiClassMapping()\n        }\n\n        let rootNodeType = documentAndIndex.compilationResult.originalDocument.template?.rootNode?.nodeType ?? \"\"\n\n        // We replace the node mapping as if we specified a class for the root node in the class mapping section.\n        documentAndIndex.compilationResult.originalDocument.classMapping?.nodeMappingByClass[rootNodeType] = ValdiNodeClassMapping(\n            tsType: nativeClassToGenerate.dumpedSymbol.text,\n            iosType: nativeClassToGenerate.nativeClass.iosType,\n            androidClassName: nativeClassToGenerate.nativeClass.androidClass,\n            cppType: nativeClassToGenerate.nativeClass.cppType,\n            kind: .class)\n\n        items.replace(atIndex: documentAndIndex.itemIndex) { item in\n            return item.with(newKind: .document(documentAndIndex.compilationResult))\n        }\n    }\n\n    private func generateNativeModule(_ nativeModuleToGenerate: NativeModuleToGenerate, items: DocumentsIndexer) -> Promise<Void> {\n        let nativeTypeExporter = TypeScriptNativeTypeExporter(iosType: nativeModuleToGenerate.nativeTypes.iosType,\n                                                              androidClass: nativeModuleToGenerate.nativeTypes.androidClass,\n                                                              cppType: nativeModuleToGenerate.nativeTypes.cppType,\n                                                              commentedFile: nativeModuleToGenerate.commentedFile,\n                                                              annotatedSymbol: nativeModuleToGenerate.annotatedSymbol,\n                                                              dumpedSymbol: nativeModuleToGenerate.dumpedSymbol,\n                                                              nativeTypeResolver: nativeTypeResolver)\n\n        return nativeTypeExporter.exportModule().then { (exportedModule, classMapping) in\n            let resolvedClassMapping = ResolvedClassMapping(localClassMapping: classMapping, projectClassMapping: ProjectClassMapping(allowMappingOverride: false), currentBundle: nativeModuleToGenerate.compilationItem.bundleInfo)\n\n            let item = nativeModuleToGenerate.compilationItem.with(\n                newKind: .exportedType(.module(exportedModule), resolvedClassMapping, GeneratedSourceFilename(filename: nativeModuleToGenerate.compilationItem.relativeProjectPath, symbolName: nativeModuleToGenerate.tsTypeName))\n            )\n\n            items.append(item: item)\n\n            return\n        }\n    }\n\n    private func generateNativeClass(_ nativeClassToGenerate: NativeClassToGenerate, nativeClassPurpose: NativeClassPurpose, items: DocumentsIndexer) -> Promise<Void> {\n        let nativeTypeExported = TypeScriptNativeTypeExporter(iosType: nativeClassToGenerate.nativeClass.iosType,\n                                                              androidClass: nativeClassToGenerate.nativeClass.androidClass,\n                                                              cppType: nativeClassToGenerate.nativeClass.cppType,\n                                                              commentedFile: nativeClassToGenerate.commentedFile,\n                                                              annotatedSymbol: nativeClassToGenerate.annotatedSymbol,\n                                                              dumpedSymbol: nativeClassToGenerate.dumpedSymbol,\n                                                              nativeTypeResolver: nativeTypeResolver)\n\n        return nativeTypeExported.export().then { (nativeTypeToExport, classMapping) -> Void in\n            let resolvedClassMapping = ResolvedClassMapping(localClassMapping: classMapping, projectClassMapping: ProjectClassMapping(allowMappingOverride: false), currentBundle: nativeClassToGenerate.compilationItem.bundleInfo)\n            let generatedSourceFilename = GeneratedSourceFilename(filename: nativeClassToGenerate.compilationItem.relativeProjectPath, symbolName: nativeClassToGenerate.nativeClass.tsTypeName)\n\n            switch nativeTypeToExport {\n            case .valdiModel(let model):\n                var modelToUse = model\n\n                if nativeClassToGenerate.annotation.parameters?[\"emitConstructors\"] == \"legacy\" {\n                    modelToUse.legacyConstructors = true\n                } else {\n                    for property in modelToUse.properties where property.omitConstructor != nil {\n                        throw CompilerError(\"\\(nativeClassToGenerate.nativeClass.tsTypeName).\\(property.name) - Using @ConstructorOmitted is deprecated when not using legacy constructors.\")\n                    }\n                }\n\n                if nativeClassToGenerate.kind == .interface {\n                    modelToUse.exportAsInterface = true\n                    for property in modelToUse.properties where property.omitConstructor != nil {\n                        let hint = property.type.isOptional ? \"\" : \" Did you mean to make the property optional with a '?' in the TypeScript interface?\"\n                        throw CompilerError(\"\\(nativeClassToGenerate.nativeClass.tsTypeName).\\(property.name) - Using @ConstructorOmitted on a @GenerateProxy does not do anything.\\(hint)\")\n                    }\n                }\n\n                switch nativeClassPurpose {\n                case .unspecified:\n                    items.append(item: nativeClassToGenerate.compilationItem.with(newKind: .exportedType(.valdiModel(modelToUse), resolvedClassMapping, generatedSourceFilename)))\n                case .viewModel:\n                    if var foundDocumentAndIndexes = items.findDocument(fromSourceURL: nativeClassToGenerate.sourceURL) {\n                        foundDocumentAndIndexes.compilationResult.originalDocument.viewModel = modelToUse\n                        items.replace(atIndex: foundDocumentAndIndexes.itemIndex) { item in\n                            return item.with(newKind: .document(foundDocumentAndIndexes.compilationResult))\n                        }\n                    } else {\n                        items.append(item: nativeClassToGenerate.compilationItem.with(newKind: .exportedType(.valdiModel(modelToUse), resolvedClassMapping, generatedSourceFilename)))\n                    }\n                case .context:\n                    if var foundDocumentAndIndexes = items.findDocument(fromSourceURL: nativeClassToGenerate.sourceURL) {\n                        foundDocumentAndIndexes.compilationResult.originalDocument.componentContext = ValdiNodeClassMapping(\n                            tsType: modelToUse.tsType,\n                            iosType: modelToUse.iosType,\n                            androidClassName: modelToUse.androidClassName,\n                            cppType: modelToUse.cppType,\n                            kind: .class)\n\n                        items.replace(atIndex: foundDocumentAndIndexes.itemIndex) { item in\n                            return item.with(newKind: .document(foundDocumentAndIndexes.compilationResult))\n                        }\n                    }\n\n                    items.append(item: nativeClassToGenerate.compilationItem.with(newKind: .exportedType(.valdiModel(modelToUse), resolvedClassMapping, generatedSourceFilename)))\n\n                    if !modelToUse.exportAsInterface {\n                        items.append(item: nativeClassToGenerate.compilationItem.with(newKind: .exportedDependencyMetadata(modelToUse, resolvedClassMapping, generatedSourceFilename)))\n                    }\n                }\n            case .enum(let exportedEnum):\n                let item = nativeClassToGenerate.compilationItem.with(\n                    newKind: .exportedType(.enum(exportedEnum), resolvedClassMapping, generatedSourceFilename)\n                )\n\n                items.append(item: item)\n            case .function, .module:\n                return\n            }\n        }.catch { (error) -> Promise<Void> in\n            let exporterError = CompilerError(type: \"NativeClassExporter error\", message: \"Failed to export native class '\\(nativeClassToGenerate.dumpedSymbol.text)': \\(error.legibleLocalizedDescription)\", range: NSRange(location: nativeClassToGenerate.dumpedSymbol.start, length: nativeClassToGenerate.dumpedSymbol.text.count), inDocument: nativeClassToGenerate.commentedFile.fileContent)\n            return Promise(error: exporterError)\n        }\n    }\n\n    private func generateNativeFunction(_ nativeFuncToGenerate: NativeFunctionToGenerate, items: DocumentsIndexer) -> Promise<Void> {\n        let nativeTypeExported = TypeScriptNativeTypeExporter(iosType: nativeFuncToGenerate.nativeTypes.iosType,\n                                                              androidClass: nativeFuncToGenerate.nativeTypes.androidClass,\n                                                              cppType: nativeFuncToGenerate.nativeTypes.cppType,\n                                                              commentedFile: nativeFuncToGenerate.commentedFile,\n                                                              annotatedSymbol: nativeFuncToGenerate.annotatedSymbol,\n                                                              dumpedSymbol: nativeFuncToGenerate.dumpedSymbol,\n                                                              nativeTypeResolver: nativeTypeResolver)\n\n        return nativeTypeExported.exportFunction().then { (exportedFunction, classMapping) -> Void in\n            let resolvedClassMapping = ResolvedClassMapping(localClassMapping: classMapping, projectClassMapping: ProjectClassMapping(allowMappingOverride: false), currentBundle: nativeFuncToGenerate.compilationItem.bundleInfo)\n\n            let item = nativeFuncToGenerate.compilationItem.with(\n                newKind: .exportedType(.function(exportedFunction), resolvedClassMapping, GeneratedSourceFilename(filename: nativeFuncToGenerate.compilationItem.relativeProjectPath, symbolName: nativeFuncToGenerate.tsTypeName))\n            )\n\n            items.append(item: item)\n            }.catch { (error) -> Promise<Void> in\n                let exporterError = CompilerError(type: \"NativeFuncExporter error\", message: \"Failed to export native function '\\(nativeFuncToGenerate.dumpedSymbol.text)': \\(error.legibleLocalizedDescription)\", range: nativeFuncToGenerate.annotation.range, inDocument: nativeFuncToGenerate.commentedFile.fileContent)\n                return Promise(error: exporterError)\n        }\n    }    \n\n    private func makeNativeClassToGenerate(commentedFile: TypeScriptCommentedFile,\n                                           annotation: ValdiTypeScriptAnnotation,\n                                           sourceURL: URL,\n                                           annotatedSymbol: TypeScriptAnnotatedSymbol,\n                                           compilationItem: CompilationItem,\n                                           linesIndexer: LinesIndexer,\n                                           kind: NativeTypeKind,\n                                           isComponent: Bool) throws -> NativeClassToGenerate {\n\n        let symbol = annotatedSymbol.symbol\n        // TODO: extract validation from this function?\n        switch kind {\n        case .class, .interface:\n            guard symbol.kind == TS.SyntaxKind.interfaceDeclaration || symbol.kind == TS.SyntaxKind.classDeclaration\n            else {\n                try throwAnnotationError(annotation, commentedFile, message: \"@ExportModel or @ExportProxy must be set on an interface or class\")\n            }\n\n            let ignoreInheritance = annotation.parameters?[\"ignoreInheritance\"] == \"true\"\n\n            guard ignoreInheritance || isComponent || (symbol.interface?.supertypes?.count ?? 0) == 0 else {\n                try throwAnnotationError(annotation, commentedFile, message: \"@ExportModel or @ExportProxy can only be used on types without inheritance\")\n            }\n\n        case .enum, .stringEnum:\n            guard symbol.kind == TS.SyntaxKind.enumDeclaration else {\n                try throwAnnotationError(annotation, commentedFile, message: \"@ExportEnum must be set on an enum\")\n            }\n        }\n\n        let nativeClass = try registerNativeClass(commentedFile: commentedFile, annotation: annotation, symbol: symbol, shouldGenerateIOS: compilationItem.shouldOutputToIOS, shouldGenerateAndroid: compilationItem.shouldOutputToAndroid, kind: kind, bundleInfo: compilationItem.bundleInfo, isGenerated: true)\n\n        return NativeClassToGenerate(annotation: annotation,\n                                     commentedFile: commentedFile,\n                                     annotatedSymbol: annotatedSymbol,\n                                     dumpedSymbol: symbol,\n                                     sourceURL: sourceURL,\n                                     nativeClass: nativeClass,\n                                     compilationItem: compilationItem,\n                                     linesIndexer: linesIndexer,\n                                     kind: kind)\n    }\n\n    private func makeNativeFuncToGenerate(commentedFile: TypeScriptCommentedFile, annotation: ValdiTypeScriptAnnotation, sourceURL: URL, annotatedSymbol: TypeScriptAnnotatedSymbol, compilationItem: CompilationItem, linesIndexer: LinesIndexer) throws -> NativeFunctionToGenerate {\n\n        let symbol = annotatedSymbol.symbol\n        guard symbol.function != nil else {\n            try throwAnnotationError(annotation, commentedFile, message: \"@ExportFunction must be set on a function\")\n        }\n\n        let kindModifiers = (symbol.kindModifiers ?? \"\").split(separator: \" \")\n\n        guard kindModifiers.contains(\"export\") else {\n            try throwAnnotationError(annotation, commentedFile, message: \"@ExportFunction must be set on a function that is exported (please add export keyword)\")\n        }\n\n        let functionName = symbol.text\n\n        let nativeTypes = try makeNativeTypesToGenerate(symbolName: functionName.pascalCased,\n                                                        commentedFile: commentedFile,\n                                                        annotation: annotation,\n                                                        compilationItem: compilationItem)\n\n        let nativeFunc = NativeFunctionToGenerate(annotation: annotation,\n                                                  commentedFile: commentedFile,\n                                                  annotatedSymbol: annotatedSymbol,\n                                                  dumpedSymbol: symbol,\n                                                  sourceURL: sourceURL,\n                                                  src: commentedFile.src,\n                                                  tsTypeName: functionName,\n                                                  nativeTypes: nativeTypes,\n                                                  compilationItem: compilationItem,\n                                                  linesIndexer: linesIndexer)\n        return nativeFunc\n    }\n\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/ParseDocumentsProcessor.swift",
    "content": "//\n//  ParseDocumentsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.document] -> [.parsedDocument, .invalidDocument]\nclass ParseDocumentsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Parsing Documents\"\n    }\n\n    private let logger: ILogger\n    private let globalIosImportPrefix: String?\n\n    init(logger: ILogger, globalIosImportPrefix: String?) {\n        self.logger = logger\n        self.globalIosImportPrefix = globalIosImportPrefix\n    }\n\n    private func mergeStyles(styles: [ValdiStyleSheet]) throws -> String {\n        var out = \"\"\n\n        for style in styles {\n            if let content = style.content {\n                out += content\n            }\n            if let _ = style.source {\n                throw CompilerError(\"src= is not implemented, please use @import instead\")\n            }\n        }\n\n        return out.trimmed\n    }\n\n    private func parse(selectedItem: SelectedItem<File>) -> [CompilationItem] {\n        let sourceURL = selectedItem.item.sourceURL\n        do {\n            logger.debug(\"-- Parsing \\(sourceURL.lastPathComponent)\")\n            let fileContent = try selectedItem.data.readString()\n            let parsedDocument = try ValdiDocumentParser.parse(logger: logger,\n                                                                  content: fileContent,\n                                                                  iosImportPrefix: selectedItem.item.bundleInfo.iosModuleName)\n\n            let cssContent = try mergeStyles(styles: parsedDocument.styles)\n\n            return [\n                selectedItem.item.with(newKind: .parsedDocument(parsedDocument)),\n                selectedItem.item.with(newKind: .css(.data(try cssContent.utf8Data())))\n            ]\n        } catch let error {\n            logger.error(\"Failed to parse \\(sourceURL.path): \\(error.legibleLocalizedDescription)\")\n            return [selectedItem.item.with(error: error)]\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> File? in\n            if case .rawDocument(let file) = item.kind {\n                return file\n            }\n            return nil\n        }.transformEachConcurrently(parse)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/ParseTypeScriptAnnotationsProcessor.swift",
    "content": "//\n//  ParseTypeScriptAnnotationsProcessor.swift\n//  Compiler\n//\n//  Created by saniul on 13/06/2019.\n//\n\nimport Foundation\n\nfinal class ParseTypeScriptAnnotationsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Parsing TypeScript Annotations\"\n    }\n\n    private let logger: ILogger\n    private let projectClassMappingManager: ProjectClassMappingManager\n    private let annotationsManager: TypeScriptAnnotationsManager\n    private let typeScriptCompilerManager: TypeScriptCompilerManager\n\n    init(logger: ILogger, projectClassMappingManager: ProjectClassMappingManager, typeScriptCompilerManager: TypeScriptCompilerManager, annotationsManager: TypeScriptAnnotationsManager) {\n        self.logger = logger\n        self.projectClassMappingManager = projectClassMappingManager\n        self.typeScriptCompilerManager = typeScriptCompilerManager\n        self.annotationsManager = annotationsManager\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let selectedItems: SelectedCompilationItems<SelectedItem<DumpedTypeScriptSymbolsResult>> = items.select { item in\n            guard !item.bundleInfo.disableAnnotationProcessing else {\n                return nil\n            }\n\n            switch item.kind {\n            case let .dumpedTypeScriptSymbols(result):\n                return result\n            default:\n                return nil\n            }\n        }\n\n        annotationsManager.clear()\n        let transformed = try selectedItems.transformEachConcurrently(parseAnnotations(selectedItem:))\n\n        return transformed\n    }\n\n    // get comments from all TypeScript files, update the annotations manager with parsed annotations and return list of the input compilation items\n    // with possible injected errors\n    private func parseAnnotations(selectedItem: SelectedItem<DumpedTypeScriptSymbolsResult>) throws -> [CompilationItem] {\n        let typeScriptItem = selectedItem.data.typeScriptItemAndSymbols.typeScriptItem\n        let result = selectedItem.data.typeScriptItemAndSymbols.dumpedSymbols\n        let compilationItem = typeScriptItem.item\n\n        let sourceURL = compilationItem.sourceURL\n\n        do {\n            let commentedFile = try TypeScriptCommentedFile(src: typeScriptItem.src,\n                                                            file: typeScriptItem.file,\n                                                            dumpedSymbolsResult: result,\n                                                            typeScriptCompiler: typeScriptCompilerManager.typeScriptCompiler)\n            for (symbolIndex, annotatedSymbol) in commentedFile.annotatedSymbols.enumerated() {\n\n                for annotation in annotatedSymbol.annotations {\n                    guard let annotationType = ValdiAnnotationType(rawValue: annotation.name) else {\n                        try throwAnnotationError(annotation, commentedFile, message: \"Unrecognized annotation '\\(annotation.name)'\")\n                    }\n\n                    let parsedAnnotation = ParsedAnnotation(type: annotationType,\n                                                            annotation: annotation,\n                                                            symbol: annotatedSymbol,\n                                                            file: commentedFile,\n                                                            compilationItem: compilationItem,\n                                                            memberIndex: nil)\n\n                    try annotationsManager.registerAnnotation(parsedAnnotation, symbolIndex: symbolIndex, sourceURL: sourceURL)\n\n                    if case .nativeTemplateElement = annotationType {\n                        guard let name = annotatedSymbol.symbol.text.nonEmpty else {\n                            throw CompilerError(\"@NativeTemplateElement needs a name\")\n                        }\n\n                        let isSlot = annotation.parameters?[\"slot\"] == \"true\"\n                        let isLayout = annotation.parameters?[\"layout\"] == \"true\"\n\n                        let iosTypeName = annotation.parameters?[\"ios\"]?.nonEmpty\n                        let androidClassName = annotation.parameters?[\"android\"]?.nonEmpty\n                        let webViewClassName = annotation.parameters?[\"web\"]?.nonEmpty\n                        let macosViewClassName = annotation.parameters?[\"macos\"]?.nonEmpty\n                        let jsxName = annotation.parameters?[\"jsx\"]?.nonEmpty\n\n                        guard isSlot || isLayout || (iosTypeName != nil && androidClassName != nil) else {\n                            throw CompilerError(\"@NativeTemplateElement needs 'ios' and 'android' typenames\")\n                        }\n\n                        let iosType = iosTypeName.map { IOSType(name: $0, bundleInfo: selectedItem.item.bundleInfo, kind: .class, iosLanguage: compilationItem.bundleInfo.iosLanguage) }\n                        try projectClassMappingManager.mutate { (classMapping) in\n                            try classMapping.register(bundle: compilationItem.bundleInfo,\n                                                      nodeType: name,\n                                                      valdiViewPath: nil,\n                                                      iosType: iosType,\n                                                      androidClassName: androidClassName,\n                                                      webViewClassName: webViewClassName,\n                                                      macosViewClassName: macosViewClassName,\n                                                      jsxName: jsxName,\n                                                      isLayout: isLayout,\n                                                      isSlot: isSlot,\n                                                      sourceFilePath: compilationItem.relativeBundleURL.path)\n                        }\n                    }\n                }\n\n                for (memberIndex, annotations) in annotatedSymbol.memberAnnotations.sorted(by: { $0.key < $1.key  }) {\n                    for annotation in annotations {\n                        guard let annotationType = ValdiAnnotationType(rawValue: annotation.name) else {\n                            try throwAnnotationError(annotation, commentedFile, message: \"Unrecognized member annotation '\\(annotation.name)'\")\n                        }\n\n                        let parsedAnnotation = ParsedAnnotation(type: annotationType,\n                                                                annotation: annotation,\n                                                                symbol: annotatedSymbol,\n                                                                file: commentedFile,\n                                                                compilationItem: compilationItem,\n                                                                memberIndex: memberIndex)\n\n                        try annotationsManager.registerAnnotation(parsedAnnotation, symbolIndex: symbolIndex, sourceURL: sourceURL)\n                    }\n                }\n            }\n            return [selectedItem.item]\n        } catch let error {\n            logger.error(\"Error parsing annotations in file \\(typeScriptItem.src.compilationPath): \\(error.legibleLocalizedDescription)\")\n            return [selectedItem.item.with(error: error)]\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/PrependWebJsProcessor.swift",
    "content": "import Foundation\n\nclass PrependWebJSProcessor: CompilationProcessor {\n    let logger: ILogger\n\n    // Files are excluded because they run before module resolution is setup\n    let excluded_files = [\n        \"web_renderer/src/ValdiWebRenderer.js\", \n        \"web_renderer/src/ValdiWebRuntime.js\",\n        \"valdi_core/src/Init.js\", \n        \"valdi_core/src/ModuleLoader.js\"\n    ]\n\n    init(logger: ILogger) {\n        self.logger = logger\n    }\n\n    var description: String {\n        return \"Modify js files for web\"\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> FinalFile? in\n            switch item.kind {\n            case let .finalFile(finalFile):\n                if let platform = finalFile.platform, platform == .web, finalFile.outputURL.lastPathComponent.hasSuffix(\".js\") {\n                    return finalFile\n                }\n                return nil\n            default:\n                return nil\n            }\n        }.transformEach { selected -> CompilationItem in\n            let item = selected.item\n            guard case let .finalFile(finalFile) = item.kind else {\n                return item\n            }\n\n            let finalFileOutput = finalFile.outputURL.relativeString\n\n            for name in excluded_files {\n                if finalFileOutput.contains(name) {\n                    return item\n                }\n            }\n\n            var relativePath = item.relativeProjectPath\n            // Strip TypeScript extensions (.tsx, .ts) from the path since compiled files are .js\n            // This ensures module.path matches what the module loader expects\n            if relativePath.hasSuffix(\".tsx\") {\n                relativePath = String(relativePath.dropLast(4))\n            } else if relativePath.hasSuffix(\".ts\") {\n                relativePath = String(relativePath.dropLast(3))\n            }\n            \n            var newFile = finalFile.file\n            var contents: String? = try? newFile.readString()\n            // Transform require( to customRequire( - this must happen for all web JS files\n            // Note: TypeScript with module: \"commonjs\" already transforms import() to Promise.resolve().then(() => require(...)),\n            // so we only need to transform require( to customRequire( and the import() transformation is handled automatically.\n            contents = contents?.replacingOccurrences(of: \"require(\", with: \"customRequire(\")\n            \n            // Set up module.path for code that uses NavigationPage decorator\n            // The module variable is provided by webpack as a function parameter, so we just set the path property\n            // The module variable is declared in source code as: declare const module: { path: string; exports: unknown };\n            // Note: We use the adjusted relativePath (without .tsx/.ts extension) so module resolution works correctly\n            let moduleSetup = \"module.path = \\\"\\(relativePath)\\\";\\n\"\n            let prefix = \"\\(moduleSetup)var customRequire = globalThis.moduleLoader.resolveRequire(\\\"\\(relativePath)\\\");\\n\"\n            if let data = (prefix + (contents ?? \"\" )).data(using: .utf8) {\n                newFile = .data(data)\n            }\n            return item.with(newKind: .finalFile(FinalFile(outputURL: finalFile.outputURL, file: newFile, platform: .web, kind: finalFile.kind)))\n        }\n    }\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/ProjectClassMappingManager.swift",
    "content": "//\n//  ProjectClassMappingManager.swift\n//  Compiler\n//\n//  Created by saniul on 14/06/2019.\n//\n\nimport Foundation\n\nfinal class ProjectClassMappingManager {\n    private var projectClassMapping: ProjectClassMapping\n    private let lock = DispatchSemaphore.newLock()\n\n    init(allowMappingOverride: Bool) {\n        projectClassMapping = ProjectClassMapping(allowMappingOverride: allowMappingOverride)\n    }\n\n    func mutate(_ closure: (inout ProjectClassMapping) throws -> Void) throws {\n        try lock.lock {\n            try closure(&projectClassMapping)\n        }\n    }\n\n    func copyProjectClassMapping() -> ProjectClassMapping {\n        return lock.lock { return projectClassMapping }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/ResolveOutputPathsProcessor.swift",
    "content": "//\n//  ResolveOutputPathsProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ResolvedOutDirectories {\n    let iosRelease: OutDirectories?\n    let iosDebug: OutDirectories?\n    let androidRelease: OutDirectories?\n    let androidDebug: OutDirectories?\n    let webRelease: OutDirectories?\n    let webDebug: OutDirectories?\n    let cppRelease: OutDirectories?\n    let cppDebug: OutDirectories?\n\n    func forEach(platform: Platform, item: CompilationItem, closure: (CompilationItem, OutDirectories) -> Void) {\n        switch platform {\n        case .ios:\n            forEachIOSDirectories(item: item, closure: closure)\n        case .android:\n            forEachAndroidDirectories(item: item, closure: closure)\n        case .web:\n            forEachWebDirectories(item: item, closure: closure)\n        case .cpp:\n            forEachCppDirectories(item: item, closure: closure)\n        }\n    }\n\n    private func forEachDirectories(item: CompilationItem,\n                                    platform: Platform,\n                                    releaseDirectories: OutDirectories?,\n                                    debugDirectories: OutDirectories?,\n                                    closure: (CompilationItem, OutDirectories) -> Void) {\n        guard item.shouldOutput(to: platform) else { return }\n\n        if let releaseDirectories = releaseDirectories, item.outputTarget.contains(.release), !item.isTestItem {\n            closure(item.with(newOutputTarget: .release), releaseDirectories)\n        }\n        if let debugDirectories = debugDirectories, item.outputTarget.contains(.debug) {\n            closure(item.with(newOutputTarget: .debug), debugDirectories)\n        }\n    }\n\n    func forEachIOSDirectories(item: CompilationItem, closure: (CompilationItem, OutDirectories) -> Void) {\n        forEachDirectories(item: item, platform: .ios, releaseDirectories: iosRelease, debugDirectories: iosDebug, closure: closure)\n    }\n\n    func forEachAndroidDirectories(item: CompilationItem, closure: (CompilationItem, OutDirectories) -> Void) {\n        forEachDirectories(item: item, platform: .android, releaseDirectories: androidRelease, debugDirectories: androidDebug, closure: closure)\n    }\n\n    func forEachWebDirectories(item: CompilationItem, closure: (CompilationItem, OutDirectories) -> Void) {\n        forEachDirectories(item: item, platform: .web, releaseDirectories: webRelease, debugDirectories: webDebug, closure: closure)\n    }\n\n    func forEachCppDirectories(item: CompilationItem, closure: (CompilationItem, OutDirectories) -> Void) {\n        forEachDirectories(item: item, platform: .cpp, releaseDirectories: cppRelease, debugDirectories: cppDebug, closure: closure)\n    }\n}\n\nclass ExportedAndroidResources {\n\n    let bundleInfo: CompilationItem.BundleInfo\n    var files = Set<String>()\n\n    init(bundleInfo: CompilationItem.BundleInfo) {\n        self.bundleInfo = bundleInfo\n    }\n}\n\nstruct AndroidOutputDirectory: Hashable {\n    let url: URL\n    let outputTarget: OutputTarget\n}\n\n// [.resourceDocument, .processedResourceImage, .nativeSource, .javaScript, .rawResource] -> [.finalFile]\nclass ResolveOutputPathsProcessor: CompilationProcessor {\n\n    var description: String {\n        return \"Resolving output paths\"\n    }\n\n    private let logger: ILogger\n    private let projectConfig: ValdiProjectConfig\n    private let compilerConfig: CompilerConfig\n    private var allAndroidResByFolder = [AndroidOutputDirectory: ExportedAndroidResources]()\n    private let allAndroidResByFolderLock = DispatchSemaphore.newLock()\n    private let drawableCapturePattern = try! NSRegularExpression(pattern: \"^drawable(-[mhx]+dpi)?/(.*$)\", options: [])\n    private let shouldGenerateKeepXML: Bool\n\n    init(logger: ILogger, projectConfig: ValdiProjectConfig, compilerConfig: CompilerConfig, shouldGenerateKeepXML: Bool) {\n        self.logger = logger\n        self.projectConfig = projectConfig\n        self.compilerConfig = compilerConfig\n        self.shouldGenerateKeepXML = shouldGenerateKeepXML\n    }\n\n    private func processImage(item: CompilationItem, file: File, imageScale: Double?, newFilename: String?, isRemote: Bool, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        let filename = newFilename ?? item.sourceURL.lastPathComponent\n\n        var out = [CompilationItem]()\n\n        directories.forEachIOSDirectories(item: item) { (item, ios) -> Void in\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: ios.resourcesURL.appendingPathComponent(filename), file: file, platform: .ios, kind: .image(scale: imageScale, isRemote: isRemote)))))\n        }\n\n        directories.forEachAndroidDirectories(item: item) { (item, android) -> Void in\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: android.resourcesURL.appendingPathComponent(filename), file: file, platform: .android, kind: .image(scale: imageScale, isRemote: isRemote)))))\n\n            let outputDirectory = AndroidOutputDirectory(url: android.resourcesURL, outputTarget: item.outputTarget)\n\n            allAndroidResByFolderLock.lock {\n                if let androidResources = allAndroidResByFolder[outputDirectory] {\n                    androidResources.files.insert(filename)\n                } else {\n                    let androidResources = ExportedAndroidResources(bundleInfo: item.bundleInfo)\n                    androidResources.files.insert(filename)\n                    allAndroidResByFolder[outputDirectory] = androidResources\n                }\n            }\n        }\n\n        directories.forEachWebDirectories(item: item) { (item, web) -> Void in\n            let webFilePath = item.relativeBundleURL.absoluteString.deletingLastPathComponent()\n            let outputURL =  web.resourcesURL.appendingPathComponent(webFilePath).appendingPathComponent(filename)\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: outputURL, file: file, platform: .web, kind: .image(scale: imageScale, isRemote: isRemote)))))\n        }\n        \n        return out\n    }\n\n    private func processAndroidResource(item: CompilationItem, file: File, filePath: String, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        var out = [CompilationItem]()\n\n        directories.forEachAndroidDirectories(item: item) { (item, android) -> Void in\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: android.resourcesURL.appendingPathComponent(filePath), file: file, platform: .android, kind: .unknown))))\n        }\n\n        return out\n    }\n    \n    private func processIosStringResource(item: CompilationItem, file: File, filePath: String, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        var out = [CompilationItem]()\n\n        directories.forEachIOSDirectories(item: item) { (item, ios) -> Void in\n            let outputURL = ios.baseURL.appendingPathComponent(\"strings\").appendingPathComponent(filePath)\n\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: outputURL, file: file, platform: .ios, kind: .unknown))))\n        }\n\n        return out\n    }\n\n    private func processRegularResource(item: CompilationItem, file: File, kind: FinalFile.Kind, newFilename: String?, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        let filename = newFilename ?? item.sourceURL.lastPathComponent\n        var out = [CompilationItem]()\n\n        directories.forEachIOSDirectories(item: item) { (item, ios) -> Void in\n            let outputURL = ios.assetsURL.appendingPathComponent(filename)\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: outputURL, file: file, platform: .ios, kind: kind))))\n        }\n\n        directories.forEachAndroidDirectories(item: item) { (item, android) -> Void in\n            let directoryURL = android.assetsURL\n            let outputURL: URL\n            if !filename.hasPrefix(\"src/\") {\n                // Backward compatibility\n                outputURL = directoryURL.appendingPathComponent(item.relativeBundleURL.path).deletingLastPathComponent().appendingPathComponent(filename)\n            } else {\n                outputURL = directoryURL.appendingPathComponent(filename)\n            }\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: outputURL, file: file, platform: .android, kind: kind))))\n        } \n\n        directories.forEachWebDirectories(item: item) { (item, web) -> Void in\n            let directoryURL = web.assetsURL\n            let outputURL = directoryURL.appendingPathComponent(filename)\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: outputURL, file: file, platform: .web, kind: kind))))\n        }\n\n        return out\n    }\n\n    private func processRawResource(item: CompilationItem, file: File, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        let filename = item.sourceURL.lastPathComponent\n\n        if filename.hasAnyExtension(FileExtensions.images) {\n            return processImage(item: item, file: file, imageScale: nil, newFilename: filename, isRemote: false, directories: directories)\n        } else if filename.hasAnyExtension([FileExtensions.javascript, FileExtensions.valdiCss]) {\n            return processRegularResource(item: item, file: file, kind: .compiledSource, newFilename: filename, directories: directories)\n        } else {\n            return processRegularResource(item: item, file: file, kind: .unknown, newFilename: filename, directories: directories)\n        }\n    }\n\n    private func processNativeSource(item: CompilationItem, nativeSource: NativeSource, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        let relativePath = nativeSource.relativePath ?? \".\"\n        let shouldUseNativeSrcURL = nativeSource.filename.hasSuffix(\".c\") || nativeSource.filename.hasSuffix(\".cpp\")\n\n        var out = [CompilationItem]()\n\n        directories.forEachAndroidDirectories(item: item) { (item, android) in\n            let targetDirectoryURL = shouldUseNativeSrcURL ? android.nativeSrcURL : android.srcURL\n            let url = targetDirectoryURL.appendingPathComponent(relativePath).appendingPathComponent(nativeSource.filename)\n            logger.verbose(\"-- Emitting generated Android native source \\(relativePath)/\\(nativeSource.filename) to \\(url)\")\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: url, file: nativeSource.file, platform: .android, kind: .nativeSource))))\n        }\n\n        directories.forEachIOSDirectories(item: item) { (item, ios) in\n            let targetDirectoryURL = shouldUseNativeSrcURL ? ios.nativeSrcURL : ios.srcURL\n            let url = targetDirectoryURL.appendingPathComponent(relativePath).appendingPathComponent(nativeSource.filename)\n            logger.verbose(\"-- Emitting generated iOS native source \\(relativePath)/\\(nativeSource.filename) to \\(url)\")\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: url, file: nativeSource.file, platform: .ios, kind: .nativeSource))))\n        }\n\n        directories.forEachCppDirectories(item: item) { item, cpp in\n            let targetDirectoryURL = shouldUseNativeSrcURL ? cpp.nativeSrcURL : cpp.srcURL\n            let url = targetDirectoryURL.appendingPathComponent(relativePath).appendingPathComponent(nativeSource.filename)\n            logger.verbose(\"-- Emitting generated C++ native source \\(relativePath)/\\(nativeSource.filename) to \\(url)\")\n            out.append(item.with(newKind: .finalFile(FinalFile(outputURL: url, file: nativeSource.file, platform: .cpp, kind: .nativeSource))))\n        }\n\n        return out\n    }\n\n    // Dependency Metadata only exists for iOS.\n    private func processDependencyMetadata(item: CompilationItem, metadata: DependencyMetadata, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        var out = [CompilationItem]()\n\n        let fixedItem = computeFixedItem(item: item, platform: Platform.ios, directories: directories)\n\n        directories.forEach(platform: Platform.ios, item: fixedItem) { (item, outDirectories) -> Void in\n            let outputURL = outDirectories.metadataURL?.appendingPathComponent(\"dependencyData\").appendingPathExtension(FileExtensions.json)\n\n            if let outputURL = outputURL {\n                out.append(item.with(newKind: .finalFile(\n                    FinalFile(outputURL: outputURL,\n                              file: metadata.file,\n                              platform: Platform.ios,\n                              kind: .dependencyInjectionData))))\n            }\n        }\n\n        return out\n    }\n\n    private func processDiagnosticsFile(item: CompilationItem, file: File, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        let relativeSourceFilePath = item.bundleInfo.baseDir\n            .appendingPathComponent(item.relativeBundleURL.path)\n            .relativePath(from: projectConfig.baseDir)\n        let outputURL = projectConfig.diagnosticsDir.appendingPathComponent(relativeSourceFilePath).appendingPathExtension(FileExtensions.json)\n        let finalFile = FinalFile(outputURL: outputURL, file: file, platform: nil, kind: .unknown)\n        return [item.with(newKind: .finalFile(finalFile))]\n    }\n\n    private func processCompilationMetadata(item: CompilationItem, file: File, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        guard let outputDumpedSymbolsDirectory = compilerConfig.outputDumpedSymbolsDirectory else {\n            return []\n        }\n\n        let outputURL = outputDumpedSymbolsDirectory\n            .appendingPathComponent(item.bundleInfo.name)\n            .appendingPathComponent(Files.compilationMetadata)\n\n        let finalFile = FinalFile(outputURL: outputURL, file: file, platform: nil, kind: .unknown)\n        return [item.with(newKind: .finalFile(finalFile))]\n    }\n\n    private func processJs(item: CompilationItem, jsFile: JavaScriptFile, directories: ResolvedOutDirectories) -> [CompilationItem ] {\n        let filename: String\n\n        // Make sure the resouces have a javascript file extension\n        if item.sourceURL.pathExtension != FileExtensions.javascript {\n            filename = item.relativeBundleURL.deletingPathExtension()\n                .appendingPathExtension(FileExtensions.javascript).absoluteString\n        } else {\n            filename = item.relativeBundleURL.absoluteString\n        }\n\n        return processRegularResource(item: item, file: jsFile.file, kind: .compiledSource, newFilename: filename, directories: directories)\n    }\n\n    private func processDeclaration(item: CompilationItem, file: JavaScriptFile, directories: ResolvedOutDirectories) -> [CompilationItem ] {\n        let filename: String\n\n        // Make sure the resouces have a d.ts file extension\n        if !item.sourceURL.absoluteString.hasSuffix(\".d.ts\") {\n            filename = item.relativeBundleURL.deletingPathExtension()\n                .appendingPathExtension(FileExtensions.typescriptDeclaration).absoluteString\n        } else {\n            filename = item.relativeBundleURL.absoluteString\n        }\n\n        return processRegularResource(item: item, file: file.file, kind: .compiledSource, newFilename: filename, directories: directories)\n    }\n\n    private func processWebOnlyFile(item: CompilationItem, file: File, directories: ResolvedOutDirectories) -> [CompilationItem] {\n        // We only need the original build file for web\n        let webDirectories = ResolvedOutDirectories(\n                iosRelease: nil,\n                iosDebug: nil,\n                androidRelease: nil,\n                androidDebug: nil,\n                webRelease: directories.webRelease,\n                webDebug: directories.webDebug,\n                cppRelease: nil,\n                cppDebug: nil\n            )\n\n        return processRegularResource(item: item, file: file, kind: .unknown, newFilename: item.relativeBundleURL.absoluteString, directories: webDirectories)\n    }\n\n    private func computeFixedItem(item: CompilationItem, platform: Platform, directories: ResolvedOutDirectories) -> CompilationItem {\n        let wouldTrample: Bool\n        switch platform {\n        case .ios:\n            wouldTrample = directories.iosDebug?.metadataURL == directories.iosRelease?.metadataURL\n        case .android:\n            wouldTrample = directories.androidDebug?.metadataURL == directories.androidRelease?.metadataURL\n        case .web:\n            wouldTrample = directories.webDebug?.metadataURL == directories.webRelease?.metadataURL\n        case .cpp:\n            wouldTrample = directories.cppDebug?.metadataURL == directories.cppRelease?.metadataURL\n        }\n\n        if wouldTrample {\n            return item.with(newOutputTarget: .debug)\n        }\n\n        return item\n    }\n\n    private func generateKeepXML() -> [CompilationItem] {\n        guard shouldGenerateKeepXML else {\n            return []\n        }\n\n        var out = [CompilationItem]()\n\n        allAndroidResByFolderLock.lock {\n            for (outputDirectory, androidResources) in allAndroidResByFolder {\n                var allFilenames = Set<String>()\n                for file in androidResources.files {\n                    if let match = drawableCapturePattern.firstMatch(in: file, options: [], range: file.nsrange) {\n                        let range = match.range(at: 2)\n                        let filename = file.substring(with: range)!\n                        let filenameWithoutExtension = String(filename.split(separator: \".\").first!)\n                        allFilenames.insert(filenameWithoutExtension)\n                    }\n                }\n\n                guard !allFilenames.isEmpty else {\n                    continue\n                }\n\n                let keepFileStr = allFilenames.sorted().map { \"@drawable/\\($0)\" }.joined(separator: \",\")\n\n                let xmlFile = try! \"\"\"\n                <?xml version=\"1.0\" encoding=\"utf-8\"?>\n                <!-- These resources are fetched using reflection from valdi -->\n                <resources xmlns:tools=\"http://schemas.android.com/tools\" tools:keep=\"\\(keepFileStr)\" tools:shrinkMode=\"strict\" />\n                \"\"\".utf8Data()\n                let outputURL = outputDirectory.url.appendingPathComponent(\"raw/valdi_\\(androidResources.bundleInfo.name)_keep.xml\", isDirectory: false)\n\n                out.append(CompilationItem(sourceURL: androidResources.bundleInfo.baseDir, relativeProjectPath: nil, kind: .finalFile(FinalFile(outputURL: outputURL, file: .data(xmlFile), platform: .android, kind: .unknown)), bundleInfo: androidResources.bundleInfo, platform: .android, outputTarget: outputDirectory.outputTarget))\n            }\n        }\n\n        return out\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        let items = items.selectAll().transformEachConcurrently { (item) -> [CompilationItem] in\n            let directories = ResolvedOutDirectories(\n                iosRelease: item.bundleInfo.iosReleaseOutputDirectories,\n                iosDebug: item.bundleInfo.iosDebugOutputDirectories,\n                androidRelease: item.bundleInfo.androidReleaseOutputDirectories,\n                androidDebug: item.bundleInfo.androidDebugOutputDirectories,\n                webRelease: item.bundleInfo.webReleaseOutputDirectories,\n                webDebug: item.bundleInfo.webDebugOutputDirectories,\n                cppRelease: item.bundleInfo.cppReleaseOutputDirectories,\n                cppDebug: item.bundleInfo.cppDebugOutputDirectories\n            )\n\n            switch item.kind {\n            case .rawResource(let file):\n                return processRawResource(item: item, file: file, directories: directories)\n            case .resourceDocument(let documentResource):\n                return processRegularResource(item: item, file: documentResource.file, kind: .compiledSource, newFilename: documentResource.outputFilename, directories: directories)\n            case .processedResourceImage(let imageResource):\n                return processImage(item: item, file: imageResource.file, imageScale: imageResource.imageScale, newFilename: imageResource.outputFilename, isRemote: imageResource.isRemote, directories: directories)\n            case .androidResource(let filePath, let file):\n                return processAndroidResource(item: item, file: file, filePath: filePath, directories: directories)\n            case .unknown:\n                logger.warn(\"Ignoring unknown file \\(item.sourceURL.path)\")\n                return []\n            case .nativeSource(let nativeSource):\n                return processNativeSource(item: item, nativeSource: nativeSource, directories: directories)\n            case .finalFile:\n                return [item]\n            case .javaScript(let file):\n                return processJs(item: item, jsFile: file, directories: directories)\n            case .declaration(let file):\n                return processDeclaration(item: item, file: file, directories: directories)\n            case .dependencyMetadata(let metadata):\n                return processDependencyMetadata(item: item, metadata: metadata, directories: directories)\n            case .diagnosticsFile(let file):\n                return processDiagnosticsFile(item: item, file: file, directories: directories)\n            case .compilationMetadata(let file):\n                return processCompilationMetadata(item: item, file: file, directories: directories)\n            case .downloadableArtifactSignatures:\n                return [item]\n            case .iosStringResource(let filePath, let file):\n                return processIosStringResource(item: item, file: file, filePath: filePath, directories: directories)\n            case .buildFile(let file), .stringsJSON(let file):\n                return processWebOnlyFile(item: item, file: file, directories: directories)\n            case .document(let result):\n                if (result.componentPath.fileName.contains(\".vue\")) {\n                    \n                    return processWebOnlyFile(item: item, file: .string(result.originalDocument.content), directories: directories)\n                } else {\n                    return []\n                }\n            case .rawDocument,\n            .parsedDocument,\n            .document,\n            .exportedType,\n            .kotlin,\n            .generatedTypeDescription,\n            .moduleYaml,\n            .imageAsset,\n            .classMapping,\n            .typeScript,\n            .css,\n            .ids,\n            .sql,\n            .sqlManifest,\n            .error,\n            .exportedDependencyMetadata,\n            .dumpedTypeScriptSymbols:\n                return []\n            }\n        }\n\n        let keepXMLItems = generateKeepXML()\n\n        return CompilationItems(compileSequence: items.compileSequence, items: items.allItems + keepXMLItems)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/SaveFilesProcessor.swift",
    "content": "//\n//  SaveFilesProcessor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// [.finalFile] -> []\nclass SaveFilesProcessor: CompilationProcessor {\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n\n    private var processedFiles = Set<URL>()\n    private let modulesFilter: ModulesFilter?\n    private let removeOrphanFiles: Bool\n    private let hotReloadingEnabled: Bool\n\n    var description: String {\n        return \"Saving files\"\n    }\n\n    init(logger: ILogger, fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, modulesFilter: ModulesFilter?,\n        removeOrphanFiles: Bool, hotReloadingEnabled: Bool) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.modulesFilter = modulesFilter\n        self.removeOrphanFiles = removeOrphanFiles\n        self.hotReloadingEnabled = hotReloadingEnabled\n    }\n\n    private func saveFile(file: File, to outUrl: URL) throws {\n        try fileManager.save(file: file, to: outUrl, options: [.overwriteOnlyIfDifferent])\n    }\n\n    private func doSave(item: SelectedItem<FinalFile>) -> [CompilationItem] {\n        do {\n            try saveFile(file: item.data.file, to: item.data.outputURL)\n            logger.verbose(\"Saving final file to \\(item.data.outputURL.path)\")\n            return []\n        } catch let error {\n            let errorMessage = \"Failed to save file to \\(item.data.outputURL.path): \\(error.legibleLocalizedDescription)\"\n            logger.error(errorMessage)\n            return [item.item.with(error: error)]\n        }\n    }\n\n    private func saveProcessedFiles(processedFiles: [SelectedItem<FinalFile>]) {\n        for processedFile in processedFiles {\n            self.processedFiles.insert(processedFile.data.outputURL.standardized)\n        }\n    }\n\n    private func doRemoveOrphanFiles(rootDirectoryURL: URL) {\n        let allFiles: [URL]\n        do {\n            let filesFinder = ValdiFilesFinder(url: rootDirectoryURL)\n            allFiles = try filesFinder.allFiles()\n        } catch let error {\n            logger.error(\"Failed to remove : \\(error.legibleLocalizedDescription)\")\n            return\n        }\n\n        for file in allFiles {\n            guard !processedFiles.contains(file) else {\n                continue\n            }\n\n            // orphaned strings files will get removed in the next localization service pass\n            guard file.lastPathComponent.starts(with: \"valdi-strings-\") == false else {\n                continue\n            }\n\n            do {\n                try FileManager.default.removeItem(at: file)\n                logger.info(\"Removed orphan file at \\(file.path)\")\n            } catch let error {\n                logger.error(\"Failed to remove orphan file at \\(file.path): \\(error.legibleLocalizedDescription)\")\n            }\n        }\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n\n        let finalFiles = items.select { item -> FinalFile? in\n            switch item.kind {\n            case let .finalFile(finalFile):\n                if (hotReloadingEnabled && finalFile.platform != Platform.web) {\n                    // Only web files get written to disk when hotreloading\n                    return nil\n                }\n\n                if let modulesFilter = modulesFilter, !modulesFilter.shouldIncludeInOutput(bundleInfo: item.bundleInfo) {\n                    return nil\n                }\n                \n                if let platform = finalFile.platform {\n                    if let androidIgnoredFiles = projectConfig.androidOutput?.ignoredFiles, platform == .android, finalFile.outputURL.lastPathComponent.matches(anyRegex: androidIgnoredFiles) {\n                        return nil\n                    }\n                    if let iosIgnoredFiles = projectConfig.iosOutput?.ignoredFiles, platform == .ios, finalFile.outputURL.lastPathComponent.matches(anyRegex: iosIgnoredFiles) {\n                        return nil\n                    }\n                }\n\n                return finalFile\n            default:\n                return nil\n            }\n        }\n\n        let items = finalFiles.transformEachConcurrently(doSave)\n        try removeOrphanFilesIfNeeded(finalFiles: finalFiles)\n        return items\n    }\n\n    private func getResolvedBaseURL(unresolvedPath: UnresolvedPath?) throws -> URL? {\n        guard let unresolvedPath = unresolvedPath else {\n            return nil\n        }\n        guard unresolvedPath.components.count == 2 else {\n            throw CompilerError(\"debugPath or releasePath should have 2 components, found \\(unresolvedPath.components.count) \")\n        }\n\n        return try UnresolvedPath(baseURL: unresolvedPath.baseURL, components: [unresolvedPath.components[0]], variables: unresolvedPath.variables).resolve()\n    }\n\n    private func removeOrphanFilesIfNeeded(finalFiles: SelectedCompilationItems<SelectedItem<FinalFile>>) throws {\n        guard removeOrphanFiles else {\n            return\n        }\n\n        logger.info(\"Removing orphan files\")\n        finalFiles.processAll(saveProcessedFiles)\n\n        var uniqueModuleRootDirectoryURLs = Set<URL>()\n\n        finalFiles.groupBy { $0.item.bundleInfo }.processAll { allBundles in\n            allBundles.forEach { byBundle in\n                let bundleInfo = byBundle.key\n\n                let urlsForThisModule = [\n                    bundleInfo.androidDebugOutputDirectories?.baseURL,\n                    bundleInfo.androidExpectedReleaseOutputDirectories?.baseURL,\n                    bundleInfo.iosDebugOutputDirectories?.baseURL,\n                    bundleInfo.iosExpectedReleaseOutputDirectories?.baseURL,\n                    bundleInfo.webDebugOutputDirectories?.baseURL,\n                    bundleInfo.webExpectedReleaseOutputDirectories?.baseURL,\n                ].compactMap { $0 }\n                uniqueModuleRootDirectoryURLs.formUnion(urlsForThisModule)\n            }\n        }\n        let moduleRootDirectoryURLs = Array(uniqueModuleRootDirectoryURLs)\n        moduleRootDirectoryURLs.parallelProcess(doRemoveOrphanFiles)\n\n        let rootDirectoryURLs: [URL] = [\n            try getResolvedBaseURL(unresolvedPath: projectConfig.iosOutput?.debugPath),\n            try getResolvedBaseURL(unresolvedPath: projectConfig.iosOutput?.releasePath),\n            try getResolvedBaseURL(unresolvedPath: projectConfig.androidOutput?.debugPath),\n            try getResolvedBaseURL(unresolvedPath: projectConfig.androidOutput?.releasePath),\n            try getResolvedBaseURL(unresolvedPath: projectConfig.webOutput?.debugPath),\n            try getResolvedBaseURL(unresolvedPath: projectConfig.webOutput?.releasePath),\n        ].compactMap { $0 }\n\n        deleteUnknownDirectories(rootDirectoryURLs: rootDirectoryURLs,\n                                 moduleRootDirectoryURLs: moduleRootDirectoryURLs)\n    }\n\n    // directories that don't match any processed module\n    private func deleteUnknownDirectories(rootDirectoryURLs: [URL], moduleRootDirectoryURLs: [URL]) {\n        for rootDir in rootDirectoryURLs {\n            let results = (try? FileManager.default.contentsOfDirectory(at: rootDir, includingPropertiesForKeys: [.isDirectoryKey], options: [])) ?? []\n            let directoriesOnly = results.filter { (url) -> Bool in\n                do {\n                    let resourceValues = try url.resourceValues(forKeys: [.isDirectoryKey])\n                    return resourceValues.isDirectory ?? false\n                } catch { return false }\n            }\n\n            let unknownDirectories = Set(directoriesOnly)\n                .map { $0.standardizedFileURL }\n                .filter { possiblyUnknownDirectory in\n                return possiblyUnknownDirectory.pathExtension.isEmpty // ignore the .xcodeproj, we just want to clean up actual directories\n                    && !moduleRootDirectoryURLs.contains(where: { $0.absoluteString.hasPrefix(possiblyUnknownDirectory.absoluteString) })\n                    && projectConfig.directoriesToKeepRegexes.allSatisfy({ !possiblyUnknownDirectory.relativeString.matches(regex: $0) })\n            }\n\n            Array(unknownDirectories).parallelProcess { unknownDirectory in\n                do {\n                    try FileManager.default.removeItem(at: unknownDirectory)\n                    logger.warn(\"Removed unknown directory at \\(unknownDirectory.path)\")\n                } catch let error {\n                    logger.error(\"Failed to unknown directory at \\(unknownDirectory.path): \\(error.legibleLocalizedDescription)\")\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/SourceMapProcessor.swift",
    "content": "//\n//  SourceMapProcessor.swift\n//\n//\n//  Created by Simon Corsin on 12/15/20.\n//\n\nimport Foundation\nimport Zip\n\nprivate struct CompilatiomItemWithSourceMap {\n    let item: CompilationItem\n    let sourceMap: String?\n}\n\nclass SourceMapProcessor: CompilationProcessor {\n\n    static let sourceMapPrefix = \"//# sourceMappingURL=\"\n\n    var description: String {\n        return \"Generating Source Maps\"\n    }\n\n    private let outputTarget: OutputTarget\n    private let disableMinifyWeb: Bool\n\n    private struct ModuleAndPlatform: Hashable {\n        let moduleInfo: CompilationItem.BundleInfo\n        let platform: Platform?\n    }\n\n    init(compilerConfig: CompilerConfig, disableMinifyWeb: Bool) {\n        self.outputTarget = compilerConfig.outputTarget\n        self.disableMinifyWeb = disableMinifyWeb\n    }\n\n    private func stringFromSourceMappingURL(_ sourceMappingURL: Substring) -> String? {\n        guard sourceMappingURL.hasPrefix(\"data:application/json\") else {\n            return nil\n        }\n\n        guard let base64StartIndex = sourceMappingURL.range(of: \"base64,\") else {\n            return nil\n        }\n\n        guard let base64Data = Data(base64Encoded: String(sourceMappingURL[base64StartIndex.upperBound...])) else {\n            return nil\n        }\n\n        return String(data: base64Data, encoding: .utf8)\n    }\n\n    /**\n     * Generates a SHA-256 digest based on the items concatenated together.\n     * The path of each item is concatenated with the file data.\n     * The items are sorted alphabetically (A to Z) by path before being concatenated.\n     *\n     * Parameters:\n     * - items: The items (file + path) to be zipped.\n     *\n     * Returns:\n     * - A String representing the SHA-256 of the provided items.\n     */\n    private func createHash(items: [CompilationItem]) throws -> String {\n        // Only include JavaScript files in the hash\n        let javaScriptFileItems = items.compactMap { item -> JavaScriptFile? in\n            guard case .javaScript(let jsFile) = item.kind else { return nil }\n            return jsFile\n        }\n\n        // Sort items alphabethically\n        let sortedItems = javaScriptFileItems.sorted { $0.relativePath < $1.relativePath }\n\n        // Join data together and generate SHA-256 digest\n        let data = try sortedItems.map { jsFile -> Data in\n            let pathData = jsFile.relativePath.data(using: .utf8) ?? Data()\n            let fileData = try jsFile.file.readData()\n            return pathData + fileData\n        }.reduce(Data()) {$0 + $1}\n        return try data.generateSHA256Digest()\n    }\n\n    private func extractSourceMap(item: SelectedItem<JavaScriptFile>) -> CompilatiomItemWithSourceMap {\n        let outItem: CompilationItem\n        var sourceMap: String?\n\n        do {\n            let jsFileContent = try item.data.file.readString()\n\n            guard let index = jsFileContent.range(of: SourceMapProcessor.sourceMapPrefix) else {\n                // Allow an empty sourcemap for web for now\n                if disableMinifyWeb && item.item.platform == Platform.web {\n                    let jsFileContentWithoutSourceMap = jsFileContent\n                    outItem = item.item.with(newKind: .javaScript(JavaScriptFile(file: .data(try jsFileContentWithoutSourceMap.utf8Data()), relativePath: item.data.relativePath)))\n                    return CompilatiomItemWithSourceMap(item: outItem, sourceMap: nil)\n                }\n\n                throw CompilerError(\"Could not resolve source map in '\\(item.data.relativePath)'\")\n            }\n\n            let jsFileContentWithoutSourceMap = jsFileContent[jsFileContent.startIndex..<index.lowerBound]\n\n            sourceMap = stringFromSourceMappingURL(jsFileContent[index.upperBound..<jsFileContent.endIndex].trimmed)\n\n            outItem = item.item.with(newKind: .javaScript(JavaScriptFile(file: .data(try jsFileContentWithoutSourceMap.utf8Data()), relativePath: item.data.relativePath)))\n\n        } catch let error {\n            outItem = item.item.with(error: error)\n        }\n\n        return CompilatiomItemWithSourceMap(item: outItem, sourceMap: sourceMap)\n    }\n\n    /**\n     * Writes the provided data to the specified URL.\n     * Will create the directory if it does not exist.\n     * Parameters:\n     * - url: The URL to write the data to\n     * - data: The data to write\n     */\n    private func writeFile(to url: URL, data: Data) throws {\n        let directoryURL = url.deletingLastPathComponent()\n        try FileManager.default.createDirectory(at: directoryURL, withIntermediateDirectories: true, attributes: nil)\n        try data.write(to: url)\n    }\n\n    /**\n     * Sets the last modified date of the file to the provided date.\n     * Parameters:\n     * - url: The URL of the file\n     * - date: The date to set\n     */\n    private func setLastModifiedDate(for url: URL, date: Date) throws {\n        let attributes = [FileAttributeKey.modificationDate: date]\n        try FileManager.default.setAttributes(attributes, ofItemAtPath: url.path)\n    }\n\n    /**\n     * Creates a CompilationItem that will be added to the specified bundle\n     * Parameters:\n     * - file: The data of the file\n     * - path: The path of the file within the bundle\n     * - module: The bundle to add the file to\n     * - platform: The platform of the file\n     * - outputTarget: The output target of the file (debug or release)\n     */\n    private func createBundleItem(file: File, path: String, module: CompilationItem.BundleInfo, platform: Platform?, outputTarget: OutputTarget) -> CompilationItem {\n        let kind : CompilationItem.Kind = .resourceDocument(DocumentResource(outputFilename: path, file: file))\n        let sourceURL = module.baseDir.appendingPathComponent(path)\n        return CompilationItem(sourceURL: sourceURL, relativeProjectPath: path, kind: kind, bundleInfo: module, platform: platform, outputTarget: outputTarget)\n    }\n\n    /**\n     * Creates a CompilationItem that will be written out to disk\n     * Parameters:\n     * - file: The data of the file\n     * - path: The URL to write the file to\n     * - module: The bundle to add the file to\n     * - platform: The platform of the file\n     * - outputTarget: The output target of the file (debug or release)\n     */\n    private func createDiskItem(file: File, path: URL, module: CompilationItem.BundleInfo, platform: Platform?, outputTarget: OutputTarget) -> CompilationItem {\n        let kind : CompilationItem.Kind = .finalFile(FinalFile(outputURL: path, file: file, platform: nil, kind: .compiledSource))\n        let sourceURL = module.baseDir.appendingPathComponent(path.lastPathComponent)\n        return CompilationItem(sourceURL:sourceURL, relativeProjectPath: nil, kind: kind, bundleInfo: module, platform: platform, outputTarget: outputTarget)\n    }\n\n    /**\n     * Zips the provided sources and source maps\n     *\n     * Parameters:\n     * - sources: The sources to be zipped.\n     * - sourceMaps: The source maps to be zipped.\n     *\n     * Returns:\n     * - The zipped data.\n     */\n    private func zipSourceAndMaps(sources: [CompilationItem], sourceMaps: [String: String]) throws -> Data {\n        // Create a temporary directory to store the sources and source maps at the correct patahs\n        let dir = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString)\n        let zipFile = dir.appendingPathComponent(\"maps.zip\")\n\n        for source in sources {\n            guard case .javaScript(let jsFile) = source.kind else { continue }\n            guard let sourceMap = sourceMaps[jsFile.relativePath] else { continue }\n            guard let mapFile = try? File.data(sourceMap.utf8Data()) else { continue }\n\n            let sourceURL = dir.appendingPathComponent(jsFile.relativePath)\n            let mapURL = sourceURL.appendingPathExtension(FileExtensions.map)\n\n            try writeFile(to: sourceURL, data: try jsFile.file.readData())\n            try writeFile(to: mapURL, data: try mapFile.readData())\n\n            // set the last modified date to the fixed date to produce deterministic .zip files\n            try setLastModifiedDate(for: sourceURL, date: DeterministicDate.fixedDate)\n            try setLastModifiedDate(for: mapURL, date: DeterministicDate.fixedDate)\n        }\n        // Add all contents of dir to the zip file\n        let filesToZip = try FileManager.default.contentsOfDirectory(at: dir, includingPropertiesForKeys: nil, options: [])\n        _ = try Zip.zipFiles(paths: filesToZip, zipFilePath: zipFile, password: nil, progress: nil)\n        let zipData = try Data(contentsOf: zipFile)\n\n        try FileManager.default.removeItem(at: zipFile)\n        try FileManager.default.removeItem(at: dir)\n\n        return zipData\n    }\n\n    private func generateSourceMap(moduleAndPlatform: ModuleAndPlatform, outputTarget: OutputTarget, items: [SelectedItem<JavaScriptFile>]) -> [CompilationItem] {\n        var outItems: [CompilationItem] = []\n\n        let kind: CompilationItem.Kind\n\n        let module = moduleAndPlatform.moduleInfo\n        let platform = moduleAndPlatform.platform\n\n        let outputFilename = \"\\(module.name).\\(FileExtensions.sourceMapJson)\"\n\n        do {\n            var sourceMaps: [String: String] = [:]\n\n            for item in items where item.item.outputTarget.contains(outputTarget) {\n                let itemAndSourceMap = extractSourceMap(item: item)\n\n                if let sourceMap = itemAndSourceMap.sourceMap {\n                    sourceMaps[item.data.relativePath] = sourceMap\n                }\n\n                outItems.append(itemAndSourceMap.item)\n            }\n\n            let jsonData: Data\n            if #available(OSX 10.13, *) {\n                jsonData = try JSONSerialization.data(withJSONObject: sourceMaps, options: .sortedKeys)\n            } else {\n                jsonData = try JSONSerialization.data(withJSONObject: sourceMaps, options: [])\n            }\n\n            if let saveDir = getSaveDir(platform: platform, module: module, outputTarget: outputTarget)?.appendingPathComponent(\"source-maps\") {\n                try FileManager.default.createDirectory(at: saveDir, withIntermediateDirectories: true, attributes: nil)\n                let itemsWithoutTestFiles = outItems.filter { !$0.isTestItem }\n                if !itemsWithoutTestFiles.isEmpty {\n                    let hash = try createHash(items: itemsWithoutTestFiles)\n                    let zippedMaps = try zipSourceAndMaps(sources: itemsWithoutTestFiles, sourceMaps: sourceMaps)\n                    let zippedMapsURL = saveDir.appendingPathComponent(\"\\(hash).\\(FileExtensions.zip)\")\n                    outItems.append(createDiskItem(file: .data(zippedMaps), path: zippedMapsURL, module: module, platform: platform, outputTarget: outputTarget))\n                    outItems.append(createBundleItem(file: .string(hash), path: Files.hash, module: module, platform: platform, outputTarget: outputTarget))\n                }\n            }\n\n            kind = .rawResource(.data(jsonData))\n        } catch let error {\n            kind = .error(error, originalItemKind: .rawResource(.data(Data())))\n        }\n\n        outItems.append(CompilationItem(sourceURL: module.baseDir.appendingPathComponent(outputFilename), relativeProjectPath: nil, kind: kind, bundleInfo: module, platform: platform, outputTarget: outputTarget))\n\n        return outItems\n    }\n\n    private func getSaveDir(platform: Platform?, module: CompilationItem.BundleInfo, outputTarget: OutputTarget) -> URL? {\n        switch platform {\n        case .ios:\n            if outputTarget.contains(.debug) {\n                return module.iosDebugOutputDirectories?.baseURL\n            } else if outputTarget.contains(.release) {\n                return module.iosReleaseOutputDirectories?.baseURL\n            }\n        case .android:\n            if outputTarget.contains(.debug) {\n                return module.androidDebugOutputDirectories?.baseURL\n            } else if outputTarget.contains(.release) {\n                return module.androidReleaseOutputDirectories?.baseURL\n            }\n        default:\n            return nil\n        }\n        return nil\n    }\n\n    private func generateSourceMaps(items: GroupedItems<ModuleAndPlatform, SelectedItem<JavaScriptFile>>) -> [CompilationItem] {\n        var out = [CompilationItem]()\n\n        if outputTarget.contains(.debug) {\n            out += generateSourceMap(moduleAndPlatform: items.key, outputTarget: .debug, items: items.items)\n        }\n        if outputTarget.contains(.release) {\n            out += generateSourceMap(moduleAndPlatform: items.key, outputTarget: .release, items: items.items)\n        }\n\n        return out\n    }\n\n    func process(items: CompilationItems) throws -> CompilationItems {\n        return items.select { (item) -> JavaScriptFile? in\n            switch item.kind {\n            case .javaScript(let jsFile):\n                return jsFile\n            default:\n                return nil\n            }\n        }.groupBy { (item) -> ModuleAndPlatform in\n            return ModuleAndPlatform(moduleInfo: item.item.bundleInfo, platform: item.item.platform)\n        }.transformEach(generateSourceMaps)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/TranslationStringsProcessor.swift",
    "content": "//\n//  TranslationStringsProcessor.swift\n//\n//\n//  Created by Simon Corsin on 3/23/20.\n//\n\nimport Foundation\n\nfinal class TranslationStringsProcessor: CompilationProcessor {\n    \n    var description: String {\n        return \"Processing translation strings\"\n    }\n    \n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let compilerConfig: CompilerConfig\n    private let projectConfig: ValdiProjectConfig\n    private let emitInlineTranslations: Bool\n    private let companion: CompanionExecutable\n\n    private var cache: Synchronized<[CompilationItem.BundleInfo:[LocalizableStringsContent]]> = Synchronized(data: [:])\n\n    init(logger: ILogger, fileManager: ValdiFileManager, compilerConfig: CompilerConfig, projectConfig: ValdiProjectConfig, emitInlineTranslations: Bool, companion: CompanionExecutable) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.compilerConfig = compilerConfig\n        self.projectConfig = projectConfig\n        self.emitInlineTranslations = emitInlineTranslations\n        self.companion = companion\n    }\n    \n    private func generateStringsDts(bundleInfo: CompilationItem.BundleInfo, localizableStringContents: [LocalizableStringsContent], defaultLocalizableStringContentsIndex: Int) throws -> [CompilationItem] {\n        logger.debug(\"-- Creating Strings.d.ts for \\(bundleInfo.name)\")\n\n        do {\n            let generator = TypeScriptStringsModuleGenerator(stringFiles: localizableStringContents,\n                                                             defaultStringFileIndex: defaultLocalizableStringContentsIndex,\n                                                             moduleName: bundleInfo.name,\n                                                             emitInlineTranslations: emitInlineTranslations)\n\n            let result = try generator.generate()\n            \n            let jsOutputPath = TypeScriptStringsModuleGenerator.outputPath(bundleName: bundleInfo.name, ext: FileExtensions.javascript)\n            let tsOutputPath = TypeScriptStringsModuleGenerator.outputPath(bundleName: bundleInfo.name, ext: FileExtensions.typescriptDeclaration)\n\n            return try TypeScriptIntermediateUtils.emitGeneratedJs(fileManager: fileManager, projectConfig: projectConfig, bundleInfo: bundleInfo, outputTarget: OutputTarget.all, jsOutputPath: jsOutputPath, jsContent: result.jsFile, tsDefinitionOutputPath: tsOutputPath, tsDefinitionContent: result.tsDefinitionFile)\n        } catch let error {\n            let errorMessage = \"Failed to generate Strings.d.ts for \\(bundleInfo.name): \\(error.legibleLocalizedDescription)\"\n            logger.error(errorMessage)\n            throw CompilerError(errorMessage)\n        }\n    }\n    \n    private func extractAndroidStringsXML(moduleName: String, selectedItem: SelectedItem<File>, response: ExportTranslationStrings.Response) throws -> CompilationItem {\n        logger.debug(\"-- Created Android Strings resource: \\(response.outputFileName)\")\n        \n        return selectedItem.item.with(newKind: .androidResource(response.outputFileName, .data(try response.content.utf8Data())), newPlatform: .android)\n    }\n    \n    private func extractIosStrings(moduleName: String, selectedItem: SelectedItem<File>, response: ExportTranslationStrings.Response) throws -> CompilationItem {\n        logger.debug(\"-- Created iOS Strings resource: \\(response.outputFileName)\")\n        \n        return selectedItem.item.with(newKind: .iosStringResource(response.outputFileName, .data(try response.content.utf8Data())), newPlatform: .ios)\n    }\n\n    private func resolveLocalizableStringsContent(module: CompilationItem.BundleInfo, moduleStrings: [SelectedItem<File>]) -> [LocalizableStringsContent] {\n        var localizableStringContents = moduleStrings.map { LocalizableStringsContent(relativePath: $0.item.relativeBundlePath, file: $0.data) }\n\n        if let existingLocalizableStringContents = (self.cache.data { $0[module] }) {\n            let asDict = localizableStringContents.associateBy { $0.relativePath }\n\n            for existingLocalizableStringContent in existingLocalizableStringContents {\n                if asDict[existingLocalizableStringContent.relativePath] == nil {\n                    localizableStringContents.append(existingLocalizableStringContent)\n                }\n            }\n        }\n\n        self.cache.data { $0[module] = localizableStringContents }\n\n        return localizableStringContents\n    }\n\n    private func processModuleStrings(moduleStrings: GroupedItems<CompilationItem.BundleInfo, SelectedItem<File>>) throws -> [CompilationItem] {\n        let localizableStringsContents = resolveLocalizableStringsContent(module: moduleStrings.key, moduleStrings: moduleStrings.items)\n        let moduleName = moduleStrings.key.name\n        guard let baseLocaleJSONItemIndex = localizableStringsContents.firstIndex(where: { $0.relativePath.components.last == \"strings-en.json\" }) else {\n            throw CompilerError(\"Missing strings-en.json for module \\(moduleName)\")\n        }\n\n        var result: [CompilationItem] = []\n        let baseLocaleJSONURLHandle: URLHandle\n\n        do {\n            baseLocaleJSONURLHandle = try localizableStringsContents[baseLocaleJSONItemIndex].file.getURLHandle()\n            result.append(contentsOf: try generateStringsDts(bundleInfo: moduleStrings.key,\n                                                             localizableStringContents: localizableStringsContents,\n                                                             defaultLocalizableStringContentsIndex: baseLocaleJSONItemIndex))\n        } catch let error {\n            return moduleStrings.items.map { $0.item.with(error: error) }\n        }\n\n        if emitInlineTranslations {\n            // string files will be bundled within the .valdimodule\n            result.append(contentsOf: moduleStrings.items.map { $0.item.with(newKind: .resourceDocument(DocumentResource(outputFilename: $0.item.relativeBundlePath.description, file: $0.data))) })\n        } else {\n            let outputForAndroid = compilerConfig.outputForAndroid && self.projectConfig.androidOutput != nil\n            let outputForIOS = compilerConfig.outputForIOS && self.projectConfig.iosOutput != nil\n            let outputForWeb = compilerConfig.outputForWeb && self.projectConfig.webOutput != nil\n\n            if outputForAndroid || outputForIOS || outputForWeb {\n                logger.debug(\"-- Exporting translation strings for \\(moduleName)\")\n\n                result.append(contentsOf: try moduleStrings.items\n                    .flatMap { selectedItem in\n                        var result: [(SelectedItem<File>, Promise<ExportTranslationStrings.Response>, Platform)] = []\n                        if outputForAndroid {\n                            logger.debug(\"-- Creating android output for: \\(selectedItem.item.sourceURL)\")                            \n                            result.append((\n                                selectedItem,\n                                self.companion.exportAndroidStringsTranslations(moduleName: moduleName, baseLocalePath: baseLocaleJSONURLHandle.url.path, inputLocalePath: selectedItem.item.sourceURL.path),\n                                Platform.android))\n\n                        }\n                        if outputForIOS {\n                            logger.debug(\"-- Creating iOS output for: \\(selectedItem.item.sourceURL)\")\n                            result.append((\n                                selectedItem,\n                                self.companion.exportIosStringsTranslations(moduleName: moduleName, baseLocalePath: baseLocaleJSONURLHandle.url.path, inputLocalePath: selectedItem.item.sourceURL.path),\n                                Platform.ios))\n                        }\n                        if outputForWeb {\n                            logger.debug(\"-- Creating web output for: \\(selectedItem.item.sourceURL)\")\n                            result.append((selectedItem, Promise(), Platform.web))\n                        }\n\n                        return result\n                    }\n                    .map { (selectedItem: SelectedItem<File>, promise: Promise<ExportTranslationStrings.Response>, platform: Platform) in\n                        if platform == Platform.android || platform == Platform.ios || platform == Platform.web {\n                            return (selectedItem, try promise.waitForData(), platform)\n                        }\n                        return (selectedItem, nil, platform)\n                    }\n                    .map { (selectedItem: SelectedItem<File>, response: ExportTranslationStrings.Response!, platform: Platform) in\n\n                        switch platform {\n                            case .android:\n                                return try extractAndroidStringsXML(moduleName: moduleName, selectedItem: selectedItem, response: response)\n                            case .ios:\n                                return try extractIosStrings(moduleName: moduleName, selectedItem: selectedItem, response: response)\n                            case .web:\n                                // Pass the raw items through for Web\n                                return selectedItem.item.with(newPlatform: .web)\n                            case .cpp:\n                                // Doesn't actually happen yet.\n                                return selectedItem.item.with(newPlatform: .cpp)\n                        }\n                    })\n            }\n        }\n        \n        return result\n    }\n    \n    \n    func process(items: CompilationItems) throws -> CompilationItems {\n        return try items.select { (item) -> File? in\n            switch item.kind {\n            case .stringsJSON(let file):\n                return file\n            default:\n                return nil\n            }\n        }.groupBy { selectedItem -> CompilationItem.BundleInfo in\n            selectedItem.item.bundleInfo\n        }.transformEachConcurrently(processModuleStrings)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/TypeScriptAnnotationsManager.swift",
    "content": "//\n//  TypeScriptAnnotationsManager.swift\n//  Compiler\n//\n//  Created by saniul on 13/06/2019.\n//\n\nimport Foundation\n\nstruct ParsedAnnotation {\n    let type: ValdiAnnotationType\n    let annotation: ValdiTypeScriptAnnotation\n    let symbol: TypeScriptAnnotatedSymbol\n    let file: TypeScriptCommentedFile\n    let compilationItem: CompilationItem\n    let memberIndex: Int?\n}\n\n// TODO: could parse annotation parameters into the enum as associated values\nenum ValdiAnnotationType: String, CaseIterable {\n    case generateNativeClass = \"GenerateNativeClass\" // Deprecated, use ExportModel\n    case generateNativeInterface = \"GenerateNativeInterface\" // Deprecated, use ExportProxy\n    case generativeNativeEnum = \"GenerateNativeEnum\" // Deprecated, use ExportEnum\n    case generativeNativeFunction = \"GenerateNativeFunction\" // Deprecated, use ExportFunction\n    case exportModule = \"ExportModule\"\n    case exportModel = \"ExportModel\"\n    case exportProxy = \"ExportProxy\"\n    case exportEnum = \"ExportEnum\"\n    case exportFunction = \"ExportFunction\"\n    case nativeTypeConverter = \"NativeTypeConverter\"\n    case nativeClass = \"NativeClass\"\n    case nativeInterface = \"NativeInterface\"\n    case component = \"Component\"\n    case action = \"Action\"\n    case viewModel = \"ViewModel\"\n    case context = \"Context\"\n    case constructorOmitted = \"ConstructorOmitted\"\n    case nativeTemplateElement = \"NativeTemplateElement\"\n    case injectable = \"Injectable\"\n    case singleCall = \"SingleCall\"\n    case workerThread = \"WorkerThread\"\n    case untypedMap = \"UntypedMap\"\n    case untyped = \"Untyped\"\n    \n    /// Returns true if this annotation type can have ios/android parameters that indicate native exports.\n    /// Used for detecting native exports in Vue files and validating annotation parameters.\n    var canHaveNativeExportParameters: Bool {\n        switch self {\n        case .exportModule,\n             .generateNativeClass,\n             .generateNativeInterface,\n             .generativeNativeEnum,\n             .generativeNativeFunction,\n             .exportModel,\n             .exportProxy,\n             .exportEnum,\n             .exportFunction,\n             .nativeClass,\n             .nativeTemplateElement,\n             .nativeInterface:\n            return true\n        case .nativeTypeConverter,\n             .component,\n             .action,\n             .viewModel,\n             .context,\n             .constructorOmitted,\n             .injectable,\n             .singleCall,\n             .workerThread,\n             .untypedMap,\n             .untyped:\n            return false\n        }\n    }\n    \n    /// Returns the annotation names that can have native export parameters (ios/android).\n    /// This is used for scanning Vue files for native exports.\n    static var nativeExportAnnotationNames: [String] {\n        return allCases.filter { $0.canHaveNativeExportParameters }.map { $0.rawValue }\n    }\n}\n\nfinal class TypeScriptAnnotationsManager {\n    private var records = Synchronized<[URL: [ParsedAnnotation]]>(data: [:])\n\n    func registerAnnotation(_ parsedAnnotation: ParsedAnnotation, symbolIndex: Int, sourceURL: URL) throws {\n        try TypeScriptAnnotationsManager.validateAnnotation(parsedAnnotation, symbolIndex: symbolIndex)\n\n        records.data { data in\n            data[sourceURL, default: []].append(parsedAnnotation)\n        }\n    }\n\n    func listAllAnnotations() -> [(URL, ParsedAnnotation)] {\n        return records.data { data in\n            return data.flatMap { keyValue in\n                keyValue.value.map { (keyValue.key, $0) }\n            }\n        }\n    }\n\n    func clear() {\n        records.data { $0.removeAll() }\n    }\n\n    /// Throws if the parsed annotation's parameters are not considered valid, e.g. when the iOS/Android type names\n    /// contain disallowed characters\n    static func validateAnnotation(_ parsedAnnotation: ParsedAnnotation, symbolIndex: Int) throws {\n        // Special validation for @ExportModule which must be at the top of the file\n        if parsedAnnotation.type == .exportModule && symbolIndex != 0 {\n            throw CompilerError(\"@ExportModule must be placed at the top of the file\")\n        }\n        \n        // Validate ios/android type names for annotations that can have native export parameters\n        if parsedAnnotation.type.canHaveNativeExportParameters {\n            if let iosTypeName = parsedAnnotation.annotation.parameters?[\"ios\"] {\n                guard ObjCValidation.isValidIOSTypeName(iosTypeName: iosTypeName) else {\n                    throw CompilerError(\"Invalid iOS type name: \\(iosTypeName)\")\n                }\n            }\n            if let androidTypeName = parsedAnnotation.annotation.parameters?[\"android\"] {\n                guard KotlinValidation.isValidAndroidTypeName(androidTypeName: androidTypeName) else {\n                    throw CompilerError(\"Invalid Android type name: \\(androidTypeName)\")\n                }\n            }\n        }\n    }\n}\n\nfunc throwAnnotationError(_ annotation: ValdiTypeScriptAnnotation, _ commentedFile: TypeScriptCommentedFile, message: String) throws -> Never {\n    throw CompilerError(type: \"Annotation error\", message: message, range: annotation.range, inDocument: commentedFile.fileContent)\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/TypeScriptCompilerManager.swift",
    "content": "//\n//  TypeScriptCompilerManager.swift\n//  Compiler\n//\n//  Created by saniul on 13/06/2019.\n//\n\nimport Foundation\n\nstruct TypeScriptItemSrc {\n    let compilationPath: String\n    let sourceURL: URL\n}\n\nprivate struct IntermediateTypeScriptItem {\n    let compilationItem: CompilationItem\n    let src: TypeScriptItemSrc\n    let tsFile: File\n}\n\nprivate struct OpenedIntermediateTypeScriptItem {\n    let intermediateItem: IntermediateTypeScriptItem\n    let needCompilation: Bool\n}\n\nstruct TypeScriptItem {\n    let src: TypeScriptItemSrc\n    let file: File\n    let item: CompilationItem\n}\n\nstruct TypeScriptCompilationResult {\n    let outItems: [CompilationItem]\n    let typeScriptItems: [TypeScriptItem]\n}\n\nstruct TypedScriptItemAndSymbols {\n    let typeScriptItem: TypeScriptItem\n    let dumpedSymbols: TS.DumpSymbolsWithCommentsResponseBody\n    let restoredFromDisk: Bool\n}\n\nstruct DumpAllSymbolsResult {\n    let typeScriptItemsAndSymbols: [TypedScriptItemAndSymbols]\n}\n\nprivate struct PrepareTypeScriptItemResult {\n    let item: CompilationItem\n    let promise: Promise<Void>?\n    let intermediateTypeScriptItem: IntermediateTypeScriptItem?\n    let shouldPassThroughItem: Bool\n}\n\nfinal class TypeScriptCompilerManager {\n    private let fileManager: ValdiFileManager\n\n    let typeScriptCompiler: TypeScriptCompiler\n\n    private let logger: ILogger\n    private let bundleManager: BundleManager\n\n    private let projectName: String\n    private let rootURL: URL\n    private let onlyCompileTypeScriptForModules: Set<String>\n    private let hotReloadingEnabled: Bool\n\n    public let outputRootURL: URL\n\n    var emitDebug: Bool {\n        return hotReloadingEnabled\n    }\n\n    private let shouldVerifyImports: Bool\n    private let shouldRemoveComments: Bool\n    private let tsEmitDeclarationFiles: Bool\n\n    private var everInitializedWorkspace = false\n    private let writerCache = CompilationCache<Bool>()\n\n    init(logger: ILogger,\n         fileManager: ValdiFileManager,\n         typeScriptCompiler: TypeScriptCompiler,\n         projectName: String,\n         rootURL: URL,\n         hotReloadingEnabled: Bool,\n         bundleManager: BundleManager,\n         projectConfig: ValdiProjectConfig,\n         compilerConfig: CompilerConfig) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.shouldVerifyImports = !compilerConfig.tsSkipVerifyingImports\n        self.shouldRemoveComments = !compilerConfig.tsKeepComments\n        self.tsEmitDeclarationFiles = compilerConfig.tsEmitDeclarationFiles\n        self.typeScriptCompiler = typeScriptCompiler\n        self.bundleManager = bundleManager\n\n        self.projectName = projectName\n        self.rootURL = rootURL\n        self.hotReloadingEnabled = hotReloadingEnabled\n\n        self.outputRootURL = projectConfig.buildDirectoryURL.appendingPathComponent(\"typescript/output\", isDirectory: true)\n        self.onlyCompileTypeScriptForModules = compilerConfig.onlyCompileTypeScriptForModules\n\n        if FileManager.default.fileExists(atPath: self.outputRootURL.path) {\n            try? FileManager.default.removeItem(at: outputRootURL)\n        }\n    }\n\n    private class func getRelativeProjectPathWithoutTSExtension(compilationItem: CompilationItem) -> String {\n        return compilationItem.relativeProjectPath.removing(suffixes: FileExtensions.typescriptFileExtensionsDotted)\n    }\n\n    private func filterIntermediateTypeScriptItems(_ intermediateTypeScriptItems: [IntermediateTypeScriptItem], filter: Set<String>) -> [IntermediateTypeScriptItem] {\n        guard !filter.isEmpty else {\n            return intermediateTypeScriptItems\n        }\n\n        return intermediateTypeScriptItems.filter {\n            return $0.compilationItem.bundleInfo.isRoot || filter.contains($0.compilationItem.bundleInfo.name)\n        }\n    }\n\n    static private func isBundleInfoIncluded(_ bundleInfo: CompilationItem.BundleInfo, filter: Set<String>) -> Bool {\n        return !bundleInfo.isRoot && (filter.isEmpty || filter.contains(bundleInfo.name))\n    }\n\n    func checkItems(compileSequence: CompilationSequence, items: [CompilationItem], onlyCompileTypeScriptForModules: Set<String>) throws -> TypeScriptCompilationResult {\n        // Intermediates directory prepared with _all_ TypeScript files\n        var (allTypeScriptItems, intermediateTypeScriptItems, _, outItems) = try prepareIntermediateItems(for: items, compilationSequence: compileSequence, dotTsOnly: false)\n\n        // We only open and typecheck files for the requested modules, if filter is present\n        let filteredIntermediateTypeScriptItems = filterIntermediateTypeScriptItems(intermediateTypeScriptItems, filter: onlyCompileTypeScriptForModules)\n\n        let checkResult = openFiles(items: filteredIntermediateTypeScriptItems, compileSequence: compileSequence).then { (items) -> Promise<[CompilationItem]> in\n            return Promise.of(promises: items.map { self.check(item: $0, compileSequence: compileSequence) })\n        }\n\n        outItems += try checkResult.waitForData()\n\n        return TypeScriptCompilationResult(outItems: outItems, typeScriptItems: allTypeScriptItems)\n    }\n\n    func prepareItemsForSymbolDumping(compileSequence: CompilationSequence, items: [CompilationItem], onlyCompileTypeScriptForModules: Set<String>) throws -> TypeScriptCompilationResult {\n        // Similar to checkItems but skips the actual type checking\n        // This is used in regenerate mode where generated files may not exist\n        var (allTypeScriptItems, intermediateTypeScriptItems, _, outItems) = try prepareIntermediateItems(for: items, compilationSequence: compileSequence, dotTsOnly: false)\n\n        // We only open files for the requested modules, if filter is present\n        let filteredIntermediateTypeScriptItems = filterIntermediateTypeScriptItems(intermediateTypeScriptItems, filter: onlyCompileTypeScriptForModules)\n\n        // Just open the files without type checking\n        let openResult = openFiles(items: filteredIntermediateTypeScriptItems, compileSequence: compileSequence).then { (items) -> [CompilationItem] in\n            return items.map { $0.compilationItem }\n        }\n\n        outItems += try openResult.waitForData()\n\n        return TypeScriptCompilationResult(outItems: outItems, typeScriptItems: allTypeScriptItems)\n    }\n\n    func compileItems(compileSequence: CompilationSequence, items: [CompilationItem], onlyCompileTypeScriptForModules: Set<String>) throws -> TypeScriptCompilationResult {\n        var (allTypeScriptItems, intermediateTypeScriptItems, jsItems, outItems) = try prepareIntermediateItems(for: items, compilationSequence: compileSequence, dotTsOnly: true)\n\n        // Only compile and emit files for the requested modules, if filter is present\n        let filteredIntermediateTypeScriptItems = filterIntermediateTypeScriptItems(intermediateTypeScriptItems, filter: onlyCompileTypeScriptForModules)\n\n        let compilationResults = openFiles(items: filteredIntermediateTypeScriptItems, compileSequence: compileSequence).then { (items) -> [Promise<[CompilationItem]>] in\n            return items.map { self.compile(item: $0, compileSequence: compileSequence) }\n        }\n\n        for promise in try compilationResults.waitForData() {\n            outItems += try promise.waitForData()\n        }\n\n        var compilationPathsByBundleInfo: [CompilationItem.BundleInfo: [String]] = [:]\n\n        for jsItem in jsItems where TypeScriptCompilerManager.isBundleInfoIncluded(jsItem.item.bundleInfo, filter: onlyCompileTypeScriptForModules) {\n            compilationPathsByBundleInfo[jsItem.item.bundleInfo, default: []].append(jsItem.src.compilationPath)\n        }\n\n        for tsItem in filteredIntermediateTypeScriptItems {\n            compilationPathsByBundleInfo[tsItem.compilationItem.bundleInfo, default: []].append(tsItem.src.compilationPath)\n        }\n\n        // We generate native c files even for modules that have no .ts / .js files\n        for item in outItems where TypeScriptCompilerManager.isBundleInfoIncluded(item.bundleInfo, filter: onlyCompileTypeScriptForModules) {\n            if compilationPathsByBundleInfo[item.bundleInfo] == nil {\n                compilationPathsByBundleInfo[item.bundleInfo] = []\n            }\n        }\n\n        var compileNativePromises: [Promise<[CompilationItem]>] = []\n        for (bundleInfo, compilationPaths) in compilationPathsByBundleInfo {\n            let compilationPathsWithNativeCompilation = compilationPaths.filter {  bundleInfo.compilationModeConfig.resolveCompilationMode(forItemPath: $0) == .native }\n            if !compilationPathsWithNativeCompilation.isEmpty {\n                compileNativePromises.append(self.compileNative(bundleInfo: bundleInfo, compilationPaths: compilationPathsWithNativeCompilation, compileSequence: compileSequence))\n            } else {\n                // Add empty sources as it will be used by the Bazel rule\n                compileNativePromises.append(Promise(data: TypeScriptCompilerManager.generateTSNativeSource(bundleInfo: bundleInfo, inputNativeSources: [])))\n            }\n        }\n\n        for compileNativePromise in compileNativePromises {\n            outItems += try compileNativePromise.waitForData()\n        }\n\n        return TypeScriptCompilationResult(outItems: outItems, typeScriptItems: allTypeScriptItems)\n    }\n\n    static func generatedUrl(url: URL) -> URL {\n        return url.deletingPathExtension().appendingPathExtension(\"generated.\\(url.pathExtension)\")\n    }\n\n    private func prepareIntermediateItems(for items: [CompilationItem], compilationSequence: CompilationSequence, dotTsOnly: Bool) throws -> (allTypeScriptItems: [TypeScriptItem], intermediateItems: [IntermediateTypeScriptItem], jsItems: [TypeScriptItem], outItems: [CompilationItem]) {\n        var outItems = [CompilationItem]()\n\n        var prepareResults = [PrepareTypeScriptItemResult]()\n        var jsItems = [TypeScriptItem]()\n\n        for item in items {\n            if case .typeScript(let file, _) = item.kind {\n                let src = getTypeScriptItemSrc(forItem: item)\n                let promise = register(src: src, file: file, compilationSequence: compilationSequence)\n\n                prepareResults.append(PrepareTypeScriptItemResult(item: item, promise: promise, intermediateTypeScriptItem: IntermediateTypeScriptItem(compilationItem: item, src: src, tsFile: file), shouldPassThroughItem: false))\n            } else if case .javaScript(let jsFile) = item.kind {\n                let src = getTypeScriptItemSrc(forItem: item)\n\n                jsItems.append(TypeScriptItem(src: src, file: jsFile.file, item: item))\n\n                if !dotTsOnly {\n                    // We just write the file, no need to pass it through TypeScript, but we still\n                    // put it to the intermediate directory so that TypeScript can import it\n                    let promise = register(src: src, file: jsFile.file, compilationSequence: compilationSequence)\n\n\n                    prepareResults.append(PrepareTypeScriptItemResult(item: item, promise: promise, intermediateTypeScriptItem: nil, shouldPassThroughItem: true))\n                } else {\n                    outItems.append(item)\n                }\n            } else if case .resourceDocument(let resource) = item.kind, !dotTsOnly && item.sourceURL.lastPathComponent.hasSuffix(\"tsconfig.json\") {\n                let src = getTypeScriptItemSrc(forItem: item)\n                let promise: Promise<Void>?\n                if item.sourceURL.lastPathComponent == \"base.tsconfig.json\" {\n                    logger.debug(\"-- Write our own base config based on \\(item.sourceURL.path)\")\n                    promise = registerBaseProjectConfigIfNeeded(src: src, file: resource.file, outputDirURL: outputRootURL, compilationSequence: compilationSequence)\n                } else {\n                    logger.debug(\"-- Copying TS project file to \\(src.compilationPath)\")\n                    promise = registerTSConfig(src: src, tsConfigFile: resource.file, bundleInfo: item.bundleInfo, compilationSequence: compilationSequence)\n                }\n\n                // Pass through tsconfig.json items so they appear in BUILD file generation\n                prepareResults.append(PrepareTypeScriptItemResult(item: item, promise: promise, intermediateTypeScriptItem: nil, shouldPassThroughItem: true))\n            } else {\n                outItems.append(item)\n            }\n        }\n\n        var allTypeScriptItems = [TypeScriptItem]()\n        var intermediateTypeScriptItems = [IntermediateTypeScriptItem]()\n\n        for prepareResult in prepareResults {\n            do {\n                if let promise = prepareResult.promise {\n                    try promise.waitForData()\n                }\n\n                if let intermediateTypeScriptItem = prepareResult.intermediateTypeScriptItem {\n                    allTypeScriptItems.append(TypeScriptItem(src: intermediateTypeScriptItem.src, file: intermediateTypeScriptItem.tsFile, item: prepareResult.item))\n                    intermediateTypeScriptItems.append(intermediateTypeScriptItem)\n                }\n\n                if prepareResult.shouldPassThroughItem {\n                    outItems.append(prepareResult.item)\n                }\n\n                // Output declaration files but only for Web\n                // url.pathExtension is just the last chunk after the last . we need the last two chunks for .d.ts\n                // Can't use FileExtensions.typescriptDeclaration because it'll also match fileNamed.ts\n                let url = prepareResult.item.sourceURL.absoluteString\n                if url.hasSuffix(\".d.ts\") {\n                    if case let .typeScript(file, _) = prepareResult.item.kind {\n                        outItems.append(prepareResult.item.with(\n                            newKind: .declaration(JavaScriptFile(file: file, relativePath: prepareResult.item.relativeProjectPath)),\n                            newPlatform: Platform.web))\n                    }\n                }\n\n            } catch let error {\n                outItems.append(prepareResult.item.with(error: error))\n            }\n        }\n\n        // Sort by natural path ordering, to get a consistent compile order\n        intermediateTypeScriptItems.sort { (left, right) -> Bool in\n            return left.src.compilationPath < right.src.compilationPath\n        }\n\n        if !everInitializedWorkspace {\n            do {\n                everInitializedWorkspace = true\n                logger.debug(\"Initializing workspace...\")\n                _ = try typeScriptCompiler.initializeWorkspace().waitForData()\n                logger.debug(\"Workspace initialized!\")\n            } catch {\n                throw CompilerError(\"Failed to initialize workspace with error: \\(error.legibleLocalizedDescription).\")\n            }\n        }\n\n        return (allTypeScriptItems, intermediateTypeScriptItems, jsItems, outItems)\n    }\n\n    private func registerBaseProjectConfigIfNeeded(src: TypeScriptItemSrc, file: File, outputDirURL: URL, compilationSequence: CompilationSequence) -> Promise<Void>? {\n        guard shouldRegister(filePath: src.compilationPath, compilationSequence: compilationSequence) else { return nil }\n\n        do {\n            let tsConfig = try baseProjectConfig(rootURL: rootURL, outputDirURL: outputDirURL, originalConfigFile: file)\n\n            let encoder = Foundation.JSONEncoder()\n            encoder.outputFormatting = [.sortedKeys, .prettyPrinted]\n            let encoded = try encoder.encode(tsConfig)\n            let promise = typeScriptCompiler.register(file: .data(encoded), filePath: src.compilationPath)\n            logger.debug(\"-- Wrote out base config at \\(src.compilationPath)\")\n            return promise\n        } catch {\n            return Promise(error: CompilerError(\"Could not write base project config: \\(error.legibleLocalizedDescription)\"))\n        }\n    }\n\n    private func baseProjectConfig(rootURL: URL, outputDirURL: URL, originalConfigFile: File) throws -> TS.Config {\n        let rootPath = TypeScriptCompiler.workspaceRoot.path\n\n        let originalConfigData = try originalConfigFile.readData()\n        var baseProjectConfig = try JSONDecoder().decode(TS.Config.self, from: originalConfigData)\n\n        var compilerOptions = baseProjectConfig.compilerOptions ?? TS.CompilerOptions()\n        compilerOptions.baseUrl = rootPath\n        compilerOptions.rootDir = rootPath\n        compilerOptions.outDir = outputDirURL.path\n        compilerOptions.removeComments = self.shouldRemoveComments\n        compilerOptions.declaration = self.tsEmitDeclarationFiles\n        // Using this option to have a .js output extension, since\n        // we are processing the JSX inline with the TSX compilation\n        compilerOptions.jsx = \"react-native\"\n\n        compilerOptions.sourceMap = true\n        compilerOptions.inlineSourceMap = true\n        // Uncomment to enable show sources in safari debugger\n        // compilerOptions.inlineSources = true\n        compilerOptions.sourceRoot = \"/\"\n\n        baseProjectConfig.compilerOptions = compilerOptions\n        return baseProjectConfig\n    }\n\n    private func openFiles(items: [IntermediateTypeScriptItem], compileSequence: CompilationSequence) -> Promise<[IntermediateTypeScriptItem]> {\n        let promises = items.map { (item) -> Promise<OpenedIntermediateTypeScriptItem> in\n            return typeScriptCompiler.ensureOpenFile(filePath: item.src.compilationPath, outputDirURL: outputRootURL, compileSequence: compileSequence)\n            .then { (result: EnsureOpenResult) -> Void in\n                if case let .opened(importPaths: importPaths) = result {\n                    try self.verifyImportPaths(item: item, filePath: item.src.compilationPath, rootURL: self.rootURL, importPaths: importPaths)\n                }\n            }\n            .then { _ -> OpenedIntermediateTypeScriptItem in\n                let isTsDeclaration = item.src.compilationPath.hasSuffix(\".\\(FileExtensions.typescriptDeclaration)\")\n                let isTS = item.src.compilationPath.hasSuffix(\".\\(FileExtensions.typescript)\")\n                let isTSX = item.src.compilationPath.hasSuffix(\".\\(FileExtensions.typescriptXml)\")\n                let needCompilation = !isTsDeclaration && (isTS || isTSX)\n                return OpenedIntermediateTypeScriptItem(intermediateItem: item, needCompilation: needCompilation)\n            }\n        }\n\n        return Promise.of(promises: promises).then { (items) -> [IntermediateTypeScriptItem] in\n            return items.filter { $0.needCompilation }.map { $0.intermediateItem }\n        }\n    }\n\n    private func verifyImportPaths(item: IntermediateTypeScriptItem, filePath: String, rootURL: URL, importPaths: [ImportPath]) throws {\n        let thisModule = item.compilationItem.bundleInfo\n        guard shouldVerifyImports, !importPaths.isEmpty, !thisModule.disableDependencyVerification else {\n            return\n        }\n\n        let resolvedImports = importPaths.map { importPath in\n            return ResolvedModuleImport(compilationPath: filePath, importPath: importPath.absolute)\n        }\n\n        if !item.compilationItem.isTestItem {\n            let testImportPaths = resolvedImports.filter { $0.isTestImport }\n            if !testImportPaths.isEmpty {\n                // TODO(vfomin): replace log with error once sqlite testdata module is fixed\n//                throw CompilerError(\"Files under 'src/...' should not import files under 'test/...'. File \\(item.compilationItem.relativeBundleURL) from module '\\(item.compilationItem.bundleInfo.name)' imports test paths: \\(testImportPaths)\")\n                logger.warn(\"Files under 'src/...' should not import files under 'test/...'. File \\(item.compilationItem.relativeBundleURL) from module '\\(item.compilationItem.bundleInfo.name)' imports test paths: \\(testImportPaths)\")\n            }\n        }\n\n        let importedModuleNames = resolvedImports.compactMap { $0.moduleName }\n        let uniquedActualDependencies = Set(importedModuleNames).subtracting([thisModule.name])\n\n        let declaredDependencies = item.compilationItem.bundleInfo.allDependenciesNames\n        let undeclaredDependencies = uniquedActualDependencies.subtracting(declaredDependencies)\n        if !undeclaredDependencies.isEmpty {\n            let sourcePath = item.compilationItem.relativeProjectPath\n\n            let message = \"Found imports from undeclared dependencies in \\(sourcePath): [\\(undeclaredDependencies.joined(separator: \",\"))]. Please update the '\\(thisModule.name)' module.yaml and specify the missing dependencies.\"\n            throw CompilerError(message)\n        }\n    }\n\n    private func check(item: IntermediateTypeScriptItem, compileSequence: CompilationSequence) -> Promise<CompilationItem> {\n        let logger = self.logger\n        logger.debug(\">> Checking TypeScript file \\(item.src.compilationPath)\")\n\n        return typeScriptCompiler.checkErrors(filePath: item.src.compilationPath, compileSequence: compileSequence)\n            .then { result in\n                logger.debug(\"<< Checked TypeScript file \\(item.src.compilationPath) in \\(Int(result.timeTakenMs))ms\")\n            return Promise(data: item.compilationItem)\n        }\n        .catch { (error) -> Promise<CompilationItem> in\n            logger.error(\"<< TypeScript file \\(item.src.compilationPath) failed to check: \\(error.legibleLocalizedDescription)\")\n            return Promise(data: item.compilationItem.with(error: error))\n        }\n    }\n\n    private static func isTestFile(item: IntermediateTypeScriptItem) -> Bool {\n        let filename = item.src.compilationPath.lastPathComponent()\n        return filename.contains(\".spec.\")\n    }\n\n    private func compile(item: IntermediateTypeScriptItem, compileSequence: CompilationSequence) -> Promise<[CompilationItem]> {\n        let logger = self.logger\n        logger.debug(\">> Compiling TypeScript file \\(item.src.compilationPath)\")\n        return typeScriptCompiler.compile(filePath: item.src.compilationPath, outputDirURL: outputRootURL, compileSequence: compileSequence)\n        .then { (file) -> [CompilationItem] in\n            logger.debug(\"<< Compiled TypeScript file \\(item.src.compilationPath)\")\n\n            let outputTarget: OutputTarget = TypeScriptCompilerManager.isTestFile(item: item) ? .debug : item.compilationItem.outputTarget\n            var output = [item.compilationItem.with(newKind: .javaScript(file.jsFile), newPlatform: nil, newOutputTarget: outputTarget)]\n\n            if let declarationFile = file.declarationFile {\n                output.append(item.compilationItem.with(newKind: .finalFile(declarationFile)))\n\n                // Output declaration files to an additional location\n                // (but only for Web)\n                let fileName = declarationFile.outputURL.lastPathComponent\n                let outputURL = URL(fileURLWithPath: file.jsFile.relativePath)\n                    .deletingLastPathComponent()\n                    .appendingPathComponent(fileName)\n                let webDeclaration = JavaScriptFile(file: declarationFile.file, relativePath: outputURL.relativePath)\n                output.append(item.compilationItem.with(newKind: .declaration(webDeclaration), newPlatform: .web, newOutputTarget: outputTarget))\n\n            }\n\n            return output\n        }.catch { (error) -> Promise<[CompilationItem]> in\n            logger.error(\"<< TypeScript file \\(item.src.compilationPath) failed to compile: \\(error.legibleLocalizedDescription)\")\n            return Promise(data: [item.compilationItem.with(error: error)])\n        }\n    }\n\n    private static func generateTSNativeSource(bundleInfo: CompilationItem.BundleInfo, inputNativeSources: [NativeSource]) -> [CompilationItem] {\n        let outputNativeSourceFile: File\n        if inputNativeSources.isEmpty {\n            outputNativeSourceFile = .string(\"\")\n        } else if inputNativeSources.count == 1 {\n            outputNativeSourceFile = inputNativeSources[0].file\n        } else {\n            outputNativeSourceFile = .lazyData(block: {\n                var data = Data()\n\n                for inputNativeSource in inputNativeSources {\n                    data.append(contentsOf: try inputNativeSource.file.readData())\n                }\n\n                return data\n            })\n        }\n\n        let filename = \"\\(bundleInfo.name)_native.c\"\n\n        let sourceURL = bundleInfo.baseDir\n        let item = CompilationItem(sourceURL: sourceURL,\n                               relativeProjectPath: bundleInfo.relativeProjectPath(forItemPath: filename),\n                               kind: .nativeSource(NativeSource(relativePath: nil,\n                                                                filename: filename,\n                                                                file: outputNativeSourceFile,\n                                                                groupingIdentifier: filename,\n                                                                groupingPriority: 0)),\n                               bundleInfo: bundleInfo,\n                               platform: nil,\n                               outputTarget: .all)\n\n        return [item.with(newPlatform: .android), item.with(newPlatform: .ios)]\n    }\n\n    private func compileNative(bundleInfo: CompilationItem.BundleInfo, compilationPaths: [String], compileSequence: CompilationSequence) -> Promise<[CompilationItem]> {\n        logger.debug(\">> Compiling TypeScript files into native for module \\(bundleInfo.name)\")\n        return typeScriptCompiler.compileNative(filePaths: compilationPaths.sorted(), compileSequence: compileSequence).then { nativeSources in\n            return TypeScriptCompilerManager.generateTSNativeSource(bundleInfo: bundleInfo, inputNativeSources: nativeSources)\n        }\n    }\n\n    private func getTypeScriptItemSrc(forItem item: CompilationItem) -> TypeScriptItemSrc {\n        var sourceURLToUse = item.sourceURL\n        if case let .typeScript(_, sourceURL) = item.kind {\n            sourceURLToUse = sourceURL\n        }\n\n        let compilationPath = item.relativeProjectPath\n\n        return TypeScriptItemSrc(compilationPath: compilationPath, sourceURL: sourceURLToUse)\n    }\n\n    private func shouldRegister(filePath: String, compilationSequence: CompilationSequence) -> Bool {\n        var shouldRegister = false\n\n        _ = writerCache.getOrUpdate(key: filePath, compileSequence: compilationSequence, onUpdate: { _, _ in\n            shouldRegister = true\n            return true\n        })\n\n        return shouldRegister\n    }\n\n    private func register(src: TypeScriptItemSrc, file: File, compilationSequence: CompilationSequence) -> Promise<Void>? {\n        guard shouldRegister(filePath: src.compilationPath, compilationSequence: compilationSequence) else {\n            return nil\n        }\n\n        return self.typeScriptCompiler.register(file: file, filePath: src.compilationPath)\n    }\n\n    private func makeTsConfigFileDataWithSkipLibCheck(tsConfigFileContent: String) throws -> File {\n        let tsConfigFileData = tsConfigFileContent.strippingSingleLineComments\n\n        var json = try JSONSerialization.jsonObject(with: try tsConfigFileData.utf8Data()) as? [String: Any]\n        if json == nil {\n            json = [:]\n        }\n\n        var compilerOptions = json![\"compilerOptions\"] as? [String: Any] ?? [:]\n        compilerOptions[\"skipLibCheck\"] = true\n\n        json![\"compilerOptions\"] = compilerOptions\n\n        let updatedTsConfigFileData = try JSONSerialization.data(withJSONObject: json as Any)\n\n        return .data(updatedTsConfigFileData)\n    }\n\n    private func registerTSConfig(src: TypeScriptItemSrc, tsConfigFile: File, bundleInfo: CompilationItem.BundleInfo, compilationSequence: CompilationSequence) -> Promise<Void>? {\n        if onlyCompileTypeScriptForModules.isEmpty || onlyCompileTypeScriptForModules.contains(bundleInfo.name) {\n            return register(src: src, file: tsConfigFile, compilationSequence: compilationSequence)\n        } else {\n            guard shouldRegister(filePath: src.compilationPath, compilationSequence: compilationSequence) else {\n                return nil\n            }\n\n            do {\n                // Insert skipLibCheck for tsconfig files of modules we are not compiling\n                let tsConfigFileContent = try tsConfigFile.readString()\n                let updatedTsConfigFile = try makeTsConfigFileDataWithSkipLibCheck(tsConfigFileContent: tsConfigFileContent)\n                return typeScriptCompiler.register(file: updatedTsConfigFile, filePath: src.compilationPath)\n            } catch {\n                return Promise(error: error)\n            }\n        }\n    }\n\n    private func canonicalizeDumpSymbolsResponse(_ response: TS.DumpSymbolsWithCommentsResponseBody) throws -> TS.DumpSymbolsWithCommentsResponseBody {\n        let prefix = \"/\"\n        let updatedReferences: [TS.AST.TypeReference] = response.references.map {\n            guard $0.fileName.hasPrefix(prefix) else {\n                return $0\n            }\n\n            let canonicalizedFileName = String($0.fileName.dropFirst(prefix.count))\n            return TS.AST.TypeReference(name: $0.name, fileName: canonicalizedFileName)\n        }\n\n        var responseCopy = response\n        responseCopy.references = updatedReferences\n        return responseCopy\n    }\n\n    func dumpAllSymbols(typescriptItems: [TypeScriptItem]) throws -> DumpAllSymbolsResult {\n        let promises: [Promise<TypedScriptItemAndSymbols?>] = typescriptItems.map { typeScriptItem in\n            if !onlyCompileTypeScriptForModules.isEmpty && !typeScriptItem.item.bundleInfo.isRoot && !onlyCompileTypeScriptForModules.contains(typeScriptItem.item.bundleInfo.name) {\n                return Promise(data: nil)\n            } else {\n                logger.verbose(\"Dumping symbols for \\(typeScriptItem.src.compilationPath)\")\n                return self.typeScriptCompiler.dumpSymbolsWithComments(filePath: typeScriptItem.src.compilationPath).then { dumpSymbolsWithCommentsResult in\n                    return TypedScriptItemAndSymbols(typeScriptItem: typeScriptItem, dumpedSymbols: try self.canonicalizeDumpSymbolsResponse(dumpSymbolsWithCommentsResult), restoredFromDisk: false)\n                }\n            }\n        }\n\n        // Collect successful results, log failures but don't fail the entire operation\n        let typeScriptItemsAndSymbols = promises.compactMap { promise -> TypedScriptItemAndSymbols? in\n            do {\n                return try promise.waitForData()\n            } catch {\n                // Log the error but continue processing other modules\n                logger.warn(\"Failed to dump symbols: \\(error.legibleLocalizedDescription)\")\n                return nil\n            }\n        }\n\n        let result = DumpAllSymbolsResult(typeScriptItemsAndSymbols: typeScriptItemsAndSymbols)\n        return result\n    }\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/TypeScriptProcessingUtils.swift",
    "content": "//\n//  TypeScriptProcessingUtils.swift\n//  Compiler\n//\n//  Created by saniul on 17/06/2019.\n//\n\nimport Foundation\n\nstruct CompilationResultAndItemIndex {\n    var compilationResult: CompilationResult\n    let itemIndex: Int\n}\n\nclass DocumentsIndexer {\n    private var items: [CompilationItem] = []\n    private let lock = DispatchSemaphore.newLock()\n    private var itemIndexByUserScriptSourceURL = [URL: Int]()\n\n    var allItems: [CompilationItem] {\n        get { return lock.lock { items } }\n    }\n\n    init(items: [CompilationItem]) {\n        for item in items {\n            doAppend(item: item)\n        }\n    }\n\n    func append(item: CompilationItem) {\n        let _ = lock.lock {\n            doAppend(item: item)\n        }\n    }\n\n    func replace(atIndex index: Int, block: (CompilationItem) -> CompilationItem) {\n        lock.lock {\n            let oldItem = self.items[index]\n            let newItem = block(oldItem)\n\n            self.items[index] = newItem\n\n            onReplace(oldItem: oldItem, newItem: newItem)\n        }\n    }\n\n    private func onReplace(oldItem: CompilationItem, newItem: CompilationItem) {\n        if case .document(let document) = oldItem.kind {\n            if case .document = newItem.kind {\n                // Nothing to do\n                return\n            }\n            // We had a document and we dont anymore, remove the userScriptSourceURL\n\n            if let userScriptSourceURL = document.userScriptSourceURL {\n                self.itemIndexByUserScriptSourceURL.removeValue(forKey: userScriptSourceURL)\n            }\n        }\n    }\n\n    func injectError(logger: ILogger, _ error: Error, relatedItem: CompilationItem) {\n        let sourceURL = relatedItem.sourceURL\n\n        lock.lock {\n            var found = false\n            items.transform { (item) in\n                if case .javaScript = item.kind, item.sourceURL == sourceURL {\n                    let newItem = item.with(error: error)\n                    onReplace(oldItem: item, newItem: newItem)\n                    item = newItem\n                    found = true\n                } else if case .document(let result) = item.kind, result.userScriptSourceURL == sourceURL {\n                    let newItem = item.with(error: error)\n                    onReplace(oldItem: item, newItem: newItem)\n                    item = newItem\n                    logger.error(\"TypeScript from Document \\(item.sourceURL.path) had an error: \\(error.legibleLocalizedDescription)\")\n                    found = true\n                }\n            }\n            if !found {\n                items.append(relatedItem.with(error: error))\n            }\n        }\n    }\n\n    @discardableResult private func doAppend(item: CompilationItem) -> Int {\n        let itemsIndex = items.count\n\n        switch item.kind {\n        case .document(let result):\n            if let userScriptSourceURL = result.userScriptSourceURL {\n                self.itemIndexByUserScriptSourceURL[userScriptSourceURL] = itemsIndex\n            }\n        default:\n            break\n        }\n\n        self.items.append(item)\n\n        return itemsIndex\n    }\n\n    func findDocument(fromSourceURL sourceURL: URL) -> CompilationResultAndItemIndex? {\n        return lock.lock {\n            return doFindDocument(fromSourceURL: sourceURL)\n        }\n    }\n\n    func findOrCreateDocument(fromSourceURL sourceURL: URL, compilationItem: CompilationItem) -> CompilationResultAndItemIndex {\n        return lock.lock {\n            if let found = doFindDocument(fromSourceURL: sourceURL) {\n                return found\n            }\n\n            let componentPath = ComponentPath(fileName: \"__TMP__(\\(compilationItem.relativeProjectPath))\", exportedMember: \"__EXPORTED_MEMBER__\")\n            let fakeCompilationResult = CompilationResult(componentPath: componentPath,\n                                                          originalDocument: ValdiRawDocument(),\n                                                          templateResult: TemplateCompilerResult(rootElement: ValdiJSElement(id: \"\", componentPath: nil, nodeType: \"__ROOT__\", jsxName: nil), actions: []),\n                                                          classMapping: ResolvedClassMapping(localClassMapping: nil, projectClassMapping: ProjectClassMapping(allowMappingOverride: false), currentBundle: compilationItem.bundleInfo),\n                                                          userScriptSourceURL: sourceURL,\n                                                          scriptLang: \"tsx\")\n            let itemIndex = doAppend(item: compilationItem.with(newKind: .document(fakeCompilationResult)))\n\n            return CompilationResultAndItemIndex(compilationResult: fakeCompilationResult, itemIndex: itemIndex)\n        }\n    }\n\n    private func doFindDocument(fromSourceURL sourceURL: URL) -> CompilationResultAndItemIndex? {\n        guard let itemIndex = itemIndexByUserScriptSourceURL[sourceURL] else {\n            return nil\n        }\n\n        guard case .document(let result) = items[itemIndex].kind else {\n            fatalError(\"this should not happen\")\n        }\n\n        return CompilationResultAndItemIndex(compilationResult: result, itemIndex: itemIndex)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Processors/UserScriptManager.swift",
    "content": "//\n//  UserScriptManager.swift\n//  Compiler\n//\n//  Created by saniul on 16/06/2019.\n//\n\nimport Foundation\n\nstruct UserScript {\n    let content: File\n    let lang: String\n    let lineOffset: Int\n}\n\nstruct UserScriptResult {\n    let userScript: UserScript\n    let emitScriptCompilationItem: CompilationItem?\n}\n\nfinal class UserScriptManager {\n\n    private var registeredUserScripts = Synchronized<[URL: UserScript]>(data: [:])\n\n    func findUserScript(documentSourceURL: URL) -> UserScript? {\n        return registeredUserScripts.data { $0[documentSourceURL] }\n    }\n\n    func findUserScriptURL(documentSourceURL: URL) -> URL? {\n        guard let userScript = findUserScript(documentSourceURL: documentSourceURL) else {\n            return nil\n        }\n\n        switch userScript.content {\n        case .url(let url):\n            return url\n        case .data, .lazyData, .string:\n            return documentSourceURL.appendingPathExtension(userScript.lang)\n        }\n    }\n\n    func processUserScript(documentItem: CompilationItem, rawDocument: ValdiRawDocument) throws -> UserScriptResult? {\n        let inputURL = documentItem.sourceURL\n        let baseURL = inputURL.deletingLastPathComponent()\n\n        var emitScriptCompilationItem: CompilationItem?\n\n        guard let userScript = try makeUserScript(baseURL: baseURL, rawDocument: rawDocument) else {\n            return nil\n        }\n\n        let relativeProjectPath: String\n        var shouldEmitItem = false\n        let url: URL\n        switch userScript.content {\n        case .url(let urlScript):\n            url = urlScript\n            relativeProjectPath = documentItem.bundleInfo.relativeProjectPath(forItemURL: urlScript)\n        case .data, .lazyData, .string:\n            url = inputURL.appendingPathExtension(userScript.lang)\n            relativeProjectPath = documentItem.relativeProjectPath + \".\\(userScript.lang)\"\n            shouldEmitItem = true\n        }\n\n        let kind: CompilationItem.Kind\n\n        switch userScript.lang {\n        case FileExtensions.typescriptXml:\n            fallthrough\n        case FileExtensions.typescript:\n            kind = .typeScript(userScript.content, url)\n        case FileExtensions.javascript:\n            kind = .javaScript(JavaScriptFile(file: userScript.content, relativePath: relativeProjectPath))\n        case FileExtensions.kotlin:\n            kind = .kotlin(userScript.content, url)\n        default:\n            throw CompilerError(type: \"Script error\", message: \"Unsupported script lang '\\(userScript.lang)'\", atZeroIndexedLine: userScript.lineOffset, column: nil, inDocument: rawDocument.content)\n        }\n\n        if shouldEmitItem {\n            // We emit a new compilation item for the user generated code.\n            emitScriptCompilationItem = CompilationItem(sourceURL: url, relativeProjectPath: relativeProjectPath, kind: kind, bundleInfo: documentItem.bundleInfo, platform: documentItem.platform, outputTarget: .all)\n        }\n\n        registeredUserScripts.data { $0[inputURL] = userScript }\n\n        return UserScriptResult(userScript: userScript,\n                                  emitScriptCompilationItem: emitScriptCompilationItem)\n    }\n\n    private func makeUserScript(baseURL: URL, rawDocument: ValdiRawDocument) throws -> UserScript? {\n        var resolvedLang: String?\n        var scriptFiles = [File]()\n        var lineOffset = 0\n        for script in rawDocument.scripts {\n            lineOffset = script.lineOffset ?? 0\n            if let content = script.content {\n                scriptFiles.append(.data(try content.utf8Data()))\n            }\n            if let source = script.source {\n                let url = baseURL.resolving(path: source)\n                if resolvedLang == nil {\n                    resolvedLang = url.pathExtension\n                }\n                scriptFiles.append(.url(url))\n            }\n            if let lang = script.lang {\n                if resolvedLang != nil && resolvedLang != lang {\n                    throw CompilerError(type: \"Script error\", message: \"Conflicting lang '\\(resolvedLang!)' and '\\(lang)'\", atZeroIndexedLine: script.lineOffset ?? 0, column: nil, inDocument: rawDocument.content)\n                }\n                resolvedLang = lang\n            }\n        }\n\n        if scriptFiles.isEmpty {\n            return nil\n        }\n\n        let resolvedContent: File\n\n        if scriptFiles.count == 1 {\n            resolvedContent = scriptFiles[0]\n        } else {\n            var newData = Data()\n            try scriptFiles.forEach { newData.append(try $0.readData()) }\n            resolvedContent = .data(newData)\n        }\n\n        return UserScript(content: resolvedContent, lang: resolvedLang ?? FileExtensions.typescript, lineOffset: lineOffset)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/AddressPort.swift",
    "content": "//\n//  AddressPort.swift\n//  BlueSocket\n//\n//  Created by Simon Corsin on 6/5/19.\n//\n\nimport Foundation\n\nstruct AddressPort: Hashable, CustomStringConvertible {\n    enum Family: Hashable {\n        case IPv4\n        case IPv6\n    }\n\n    let family: Family\n    let address: String\n    let port: Int32\n\n    var description: String {\n        return \"\\(address):\\(port)\"\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/AutoRecompiler.swift",
    "content": "//\n//  AutoRecompiler.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class AutoRecompiler {\n\n    private let logger: ILogger\n    private let compiler: ValdiCompiler\n    private let filesFinder: ValdiFilesFinder\n    private let bundleManager: BundleManager\n    private let fileDependenciesManager: FileDependenciesManager\n    private let errorDumper: CompilationPipelineErrorDumper\n\n    private let queue = DispatchQueue(label: \"com.snap.valdi.reloader\")\n\n    init(logger: ILogger, compiler: ValdiCompiler, filesFinder: ValdiFilesFinder, bundleManager: BundleManager, fileDependenciesManager: FileDependenciesManager, errorDumper: CompilationPipelineErrorDumper) {\n        self.logger = logger\n        self.compiler = compiler\n        self.filesFinder = filesFinder\n        self.bundleManager = bundleManager\n        self.fileDependenciesManager = fileDependenciesManager\n        self.errorDumper = errorDumper\n    }\n\n    private func filesDidChange(urls: [URL]) {\n        DispatchQueue.main.async { [weak self] in\n            guard let self else { return }\n            for url in urls {\n                self.compiler.addFile(file: url)\n\n                let getDependents = self.fileDependenciesManager.getDependents(file: url)\n                for dependent in getDependents {\n                    self.compiler.addFile(file: dependent)\n                }\n            }\n\n            do {\n                self.logger.info(\"--- Files changed - starting recompilation pass\")\n                try self.compiler.compile()\n                self.logger.info(\"Recompilation pass finished, waiting for file changes...\")\n                self.logger.info(\"--------------------------------------------------------\")\n            } catch let error {\n                self.errorDumper.dump(logger: self.logger, error: error)\n            }\n        }\n    }\n\n    func start() throws {\n        filesFinder.delegate = self\n        try filesFinder.startMonitoring(logger: logger)\n    }\n\n    func stop() {\n        if filesFinder.delegate === self {\n            filesFinder.delegate = nil\n        }\n        filesFinder.stopMonitoring()\n    }\n\n}\n\nextension AutoRecompiler: ValdiFilesFinderDelegate {\n\n    func valdiFilesFinder(_ valdiFilesFinder: ValdiFilesFinder, filesDidChange files: [URL]) {\n        queue.async {\n            self.filesDidChange(urls: files)\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/DaemonService.swift",
    "content": "//\n//  DaemonService.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 2/15/19.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport Chalk\n\nprotocol DaemonServiceAutoConnectorDelegate: AnyObject {\n    func autoConnector(_ autoConnector: DaemonServiceAutoConnector, newConnectionEstablished connection: DaemonTCPConnection, deviceId : String)\n}\n\nprotocol DaemonServiceAutoConnector {\n    var delegate: DaemonServiceAutoConnectorDelegate? { get set }\n    // Throws if the tunnel can't be created. Returns nil if the tunnel is internally managed and doesn't need to be exposed.\n    func createTunnel(logger: ILogger, fromLocalPort: Int, toDeviceId: String, devicePort: Int) throws -> TCPTunnel?\n}\n\nfinal class DaemonService {\n\n    private let logger: ILogger\n    private let queue = DispatchQueue(label: \"com.snap.valdi.DaemonService.connections\")\n    private var connectedClients = [DaemonServiceConnectedClient]()\n\n    private let fileManager: ValdiFileManager\n\n    private let resourceStore: ResourceStore\n    private let deviceWhitelist: ReloaderDeviceWhitelist\n    private let logsOutputDirURL: URL\n    private let deviceStorageURL: URL\n\n    private let serviceAnnouncer: ReloaderServiceAnnouncer?\n    private let connectionAcceptor: DaemonTCPConnectionAcceptor?\n\n    private let usbMuxAutoConnector: DaemonServiceUSBMuxAutoConnector?\n    private let simulatorAutoConnectors: [DaemonServiceSimulatorAutoConnector]\n    private let adbAutoConnector: DaemonServiceADBAutoConnector?\n    private var idSequence = 0\n    private let companion: CompanionExecutable\n\n    init(logger: ILogger,\n         fileManager: ValdiFileManager,\n         userConfig: ValdiUserConfig,\n         projectConfig: ValdiProjectConfig,\n         compilerConfig: CompilerConfig,\n         companion: CompanionExecutable,\n         reloadOverUSB: Bool) throws {\n        self.logger = logger\n        self.fileManager = fileManager\n        let deviceWhitelist = ReloaderDeviceWhitelist(deviceIds: Set(userConfig.deviceIds.map({ $0.uppercased() })),\n                                                      usernames: Set(userConfig.usernames.map({ $0.uppercased() })),\n                                                      ipAddresses: Set(userConfig.ipAddresses))\n        self.deviceWhitelist = deviceWhitelist\n        self.logsOutputDirURL = userConfig.logsOutputDir ?? URL.logsDirectoryURL\n        self.deviceStorageURL = userConfig.deviceStorageDir ?? URL.deviceStorageDirectoryURL\n\n        self.companion = companion\n        self.resourceStore = ResourceStore()\n\n        let logsCleaner = LogsCleaner(logger: logger, logsDirectoryURL: logsOutputDirURL)\n        logsCleaner.cleanLogsFilesIfNeeded()\n\n        if !compilerConfig.disableDebuggingProxy {\n            // It's fine to wait here, since DaemonService is only initialized when we're in hot reload mode and this is something\n            // we're going to want to hear back about.\n            do {\n                let startDebuggingProxyResponse = try companion.startDebuggingProxy().waitForData()\n                logger.info(\"Valdi debugging proxy is listening on port \\(startDebuggingProxyResponse.actualPort)\")\n            } catch {\n                logger.error(\"Failed to start debugging proxy\")\n            }\n        }\n\n        if reloadOverUSB {\n            let usbMuxAutoConnector = DaemonServiceUSBMuxAutoConnector(logger: logger)\n            self.usbMuxAutoConnector = usbMuxAutoConnector\n\n            self.simulatorAutoConnectors = [\n                DaemonServiceSimulatorAutoConnector(logger: logger, port: Ports.reloaderOverUSB),\n                DaemonServiceSimulatorAutoConnector(logger: logger, port: Ports.reloaderStandalone)\n            ]\n            let adbAutoConnector = DaemonServiceADBAutoConnector(logger: logger, companion: companion)\n            self.adbAutoConnector = adbAutoConnector\n\n            self.connectionAcceptor = nil\n            self.serviceAnnouncer = nil\n\n            usbMuxAutoConnector.delegate = self\n            usbMuxAutoConnector.start()\n\n            for simulatorAutoConnector in simulatorAutoConnectors {\n                simulatorAutoConnector.delegate = self\n                simulatorAutoConnector.start()\n            }\n\n            adbAutoConnector.delegate = self\n            adbAutoConnector.start()\n        } else {\n            self.usbMuxAutoConnector = nil\n            self.simulatorAutoConnectors = []\n            adbAutoConnector = nil\n\n            let connectionAcceptor = try DaemonTCPConnectionAcceptor(logger: logger)\n            self.connectionAcceptor = connectionAcceptor\n            let serviceAnnouncer = try ReloaderServiceAnnouncer(logger: logger, deviceWhitelist: deviceWhitelist, projectConfig: projectConfig, servicePort: connectionAcceptor.listeningPort)\n            self.serviceAnnouncer = serviceAnnouncer\n\n            connectionAcceptor.delegate = self\n            connectionAcceptor.startAccepting()\n        }\n    }\n\n    func resourcesDidChange(resources: [Resource]) {\n        for resource in resources {\n            self.resourceStore.addResource(resource)\n        }\n\n        queue.async {\n            let readyClients = self.connectedClients.filter(\\.clientIsReady)\n            guard !readyClients.isEmpty else {\n                self.logger.info(\"[Hot reloader] \\(resources.count) updated resources, but no connected clients.\")\n                return\n            }\n            self.logger.info(\"[Hot reloader] sending \\(resources.count) updated resources to \\(readyClients.count) connected client(s)...\")\n            for client in readyClients {\n                self.send(resources: resources, to: client)\n            }\n        }\n    }\n\n    private func sendAllResourcesToNewlyConnected(client: DaemonServiceConnectedClient) {\n        guard !client.hotReloadDisabled else { return }\n        logger.info(\"[Hot reloader] Sending all resources to newly connected client \\(client)\")\n        self.send(resources: resourceStore.allResources, to: client)\n    }\n\n    private func shouldClientReceiveResource(client: DaemonServiceConnectedClient, resource: Resource) -> Bool {\n        guard let platform = client.platform else {\n            return true\n        }\n\n        return platform == resource.finalFile.platform\n    }\n\n    private func send(resources: [Resource], to client: DaemonServiceConnectedClient) {\n        guard !resources.isEmpty && !client.hotReloadDisabled else {\n            return\n        }\n\n        if client.wasConfigured {\n            var event = DaemonServerEvent()\n            event.updated_resources = DaemonUpdatedResourcesEvent(resources: [])\n            for resource in resources where shouldClientReceiveResource(client: client, resource: resource) {\n\n                var dataString: String?\n                var data: Data?\n                if let asString = String(data: resource.data, encoding: .utf8) {\n                    dataString = asString\n                    data = nil\n                } else {\n                    dataString = nil\n                    data = resource.data\n                }\n\n                event.updated_resources?.resources.append(DaemonResource(bundle_name: resource.item.bundleInfo.name,\n                                                                         file_path_within_bundle: resource.filePathInBundle,\n                                                                         data_base64: data,\n                                                                         data_string: dataString))\n            }\n\n            let updatedResources = event.updated_resources?.resources.map { \"\\($0.bundle_name):\\($0.file_path_within_bundle)\" }\n            logger.verbose(\"Sending updated resources event with \\(String(describing: updatedResources)) to client \\(client)\")\n\n            client.protocolConnection.send(event: event)\n\n        } else {\n            logger.error(\"Client \\(client) was never configured, can't send the updated resources event!\")\n        }\n    }\n\n    private func addClient(_ client: DaemonServiceConnectedClient) {\n        self.connectedClients.append(client)\n    }\n\n    private func removeClient(_ client: DaemonServiceConnectedClient) {\n        if let index = self.connectedClients.firstIndex(where: { $0 === client }) {\n            client.logsWriter?.close()\n            self.connectedClients.remove(at: index)\n        }\n    }\n\n    private func retrieveClient(connection: ValdiDaemonProtocolConnection, completion: @escaping (DaemonServiceConnectedClient) -> Void) {\n        queue.async {\n            if let index = self.connectedClients.firstIndex(where: { $0.protocolConnection === connection }) {\n                completion(self.connectedClients[index])\n            }\n        }\n    }\n\n    private func getPathFromJSONRequest(_ request: DaemonFileManagerRequestBody) throws -> URL {\n        let path = request.path\n        return deviceStorageURL.resolving(path: path)\n    }\n\n    private func writeFile(_ request: DaemonFileManagerRequestBody) throws -> DaemonFileManagerPayloadResponse {\n        let filePath = try getPathFromJSONRequest(request)\n        if let dataBase64 = request.data_base64 {\n            try fileManager.save(data: dataBase64, to: filePath)\n        } else if let dataString = request.data_string {\n            try fileManager.save(data: try dataString.utf8Data(), to: filePath)\n        }\n\n        return DaemonFileManagerPayloadResponse()\n    }\n\n    private func deleteFile(_ request: DaemonFileManagerRequestBody) throws -> DaemonFileManagerPayloadResponse {\n        let filePath = try getPathFromJSONRequest(request)\n        try FileManager.default.removeItem(at: filePath)\n        return DaemonFileManagerPayloadResponse()\n    }\n\n    private func readFile(_ request: DaemonFileManagerRequestBody) throws -> DaemonFileManagerPayloadResponse {\n        let filePath = try getPathFromJSONRequest(request)\n        let file = File.url(filePath)\n        var filePayload = DaemonFileManagerPayloadResponse()\n\n        switch request.output_format {\n        case .base64:\n            let data = try file.readData()\n            let base64 = data.base64EncodedString()\n            filePayload.data_base64 = base64\n            break\n        case .string:\n            let dataString = try file.readString()\n            filePayload.data_string = dataString\n        case .none:\n            logger.error(\"Unknown readFile request output format\")\n        }\n        return filePayload\n    }\n\n    private func readDirectory(_ request: DaemonFileManagerRequestBody) throws -> DaemonFileManagerPayloadResponse {\n\n        let filePath = try getPathFromJSONRequest(request)\n\n        let keys = [URLResourceKey.creationDateKey, URLResourceKey.contentModificationDateKey, URLResourceKey.isDirectoryKey]\n        let keysSet = Set(keys)\n\n        let items = try FileManager.default.contentsOfDirectory(at: filePath, includingPropertiesForKeys: keys, options: [])\n\n        let outputItems = try items.map { item throws -> DaemonFileManagerFileEntry in\n            let filename = item.lastPathComponent\n            let absolutePath = item.path\n            let resourceValues = try item.resourceValues(forKeys: keysSet)\n\n            let contentModificationDate = resourceValues.contentModificationDate?.timeIntervalSince1970\n            let creationDate = resourceValues.creationDate?.timeIntervalSince1970\n            let isDirectory = resourceValues.isDirectory ?? false\n\n            return DaemonFileManagerFileEntry(filename: filename, absolute_path: absolutePath, type: isDirectory ? 2  : 1, modification_date: contentModificationDate?.milliseconds, creation_date: creationDate?.milliseconds)\n        }\n        var filePayload = DaemonFileManagerPayloadResponse()\n        filePayload.entries = outputItems\n        return filePayload\n    }\n\n    private func processRequest(request: DaemonClientRequest, response: Promise<DaemonServerResponse>, client: DaemonServiceConnectedClient) {\n        if let req = request.configure {\n            let wasConfigured = client.wasConfigured\n            client.applicationId = req.application_id\n            client.wasConfigured = true\n            client.clientIsReady = true\n\n            if let disableHotReload = req.disable_hot_reload {\n                client.hotReloadDisabled = disableHotReload\n            }\n\n            let platform = req.platform\n            switch platform {\n            case \"ios\":\n                client.platform = .ios\n            case \"android\":\n                client.platform = .android\n            default:\n                client.platform = nil\n            }\n\n            if let applicationId = client.applicationId {\n                let logsURL = logsOutputDirURL.appendingPathComponent(\"\\(platform)-\\(applicationId).log\", isDirectory: false)\n                if logsURL != client.logsWriter?.outputURL {\n                    client.logsWriter?.close()\n                    do {\n                        client.logsWriter = try LogsWriter(logger: logger, fileManager: fileManager, outputURL: logsURL)\n                    } catch let error {\n                        logger.error(\"Unable to start log writer: \\(error.legibleLocalizedDescription)\")\n                    }\n                }\n            }\n            var serverResponse = DaemonServerResponse()\n            serverResponse.configure = DaemonClientConfigureResponse()\n\n            response.resolve(data: serverResponse)\n\n            if !wasConfigured {\n                self.sendAllResourcesToNewlyConnected(client: client)\n            }\n        }\n\n        if request.list_connected_clients != nil {\n            var clients: [DaemonConnectedClient] = []\n\n            for existingClient in self.connectedClients where existingClient !== client {\n                let connectedClient = DaemonConnectedClient(client_id: Int32(existingClient.id), platform: existingClient.platform?.rawValue ?? \"\", application_id: existingClient.applicationId)\n\n                clients.append(connectedClient)\n            }\n            var serverResponse = DaemonServerResponse()\n            serverResponse.list_connected_clients = DaemonClientListConnectedClientsResponse(clients: clients)\n            response.resolve(data: serverResponse)\n        }\n\n        if let req = request.forward_client_payload {\n            var serverResponse = DaemonServerResponse()\n            guard let recipientClient = self.connectedClients.first(where: { $0.id == (req.client_id) }) else {\n                serverResponse.error = DaemonErrorResponse(error_message: \"No client with id \\(req.client_id)\")\n                response.resolve(data: serverResponse)\n                return\n            }\n            var event = DaemonServerEvent()\n            event.payload_from_client = DaemonPayloadFromClientEvent(sender_client_id: Int32(client.id), payload_base64: req.payload_base64, payload_string: req.payload_string)\n\n            recipientClient.protocolConnection.send(event: event)\n\n            serverResponse.forward_client_payload = DaemonClientForwardPayloadResponse()\n\n            response.resolve(data: serverResponse)\n        }\n\n        if let requestEnvelope = request.file_manager {\n            var serverResponse = DaemonServerResponse()\n            do {\n                let output: DaemonFileManagerPayloadResponse\n                switch requestEnvelope.type {\n                case .write_file:\n                    output = try writeFile(requestEnvelope.body)\n                case .read_file:\n                    output = try readFile(requestEnvelope.body)\n                case .read_directory:\n                    output = try readDirectory(requestEnvelope.body)\n                case .delete_file:\n                    output = try deleteFile(requestEnvelope.body)\n                }\n\n                serverResponse.file_manager = output\n                response.resolve(data: serverResponse)\n            } catch let err {\n                serverResponse.error = DaemonErrorResponse(error_message: err.legibleLocalizedDescription)\n                response.resolve(data: serverResponse)\n            }\n\n        }\n\n    }\n\n    private func processEvent(event: DaemonClientEvent, client: DaemonServiceConnectedClient) {\n        if let new_logs = event.new_logs {\n            for log in new_logs {\n                let logMessage = \"[\\(log.severity)] \\(log.log)\"\n                client.logsWriter?.write(log: logMessage)\n            }\n        }\n\n        if let debuggerInfo = event.js_debugger_info {\n            processJsDebuggerInfoEvent(debuggerInfo: debuggerInfo, client: client)\n        }\n    }\n\n    private func processJsDebuggerInfoEvent(debuggerInfo: DaemonJsDebuggerInfo, client: DaemonServiceConnectedClient) {\n        guard debuggerInfo.port != 0 else {\n            return\n        }\n        let devicePort = debuggerInfo.port\n        let localPort = Ports.hermesDebugger\n        do {\n            if let tunnel = try client.autoConnector.createTunnel(logger: logger, fromLocalPort: localPort, toDeviceId: client.deviceId, devicePort: devicePort) {\n                tunnel.delegate = self\n                tunnel.start()\n                client.tunnels.append(tunnel)\n            }\n        } catch let error {\n            logger.error(\"Error creating tunnel for port \\(devicePort) on \\(client): \\(error.legibleLocalizedDescription)\")\n            return\n        }\n\n        client.debuggerConnected = true\n        logger.info(\"\\(\"Debugger connected to client at:\", color: .green, style: .bold)\")\n        for target in debuggerInfo.websocket_targets {\n            if target == debuggerInfo.websocket_targets.first {\n                logger.info(\"\\(\"    ws://localhost:\\(localPort)/\\(target) (default)\", color: .green, style: .bold)\")\n            } else {\n                logger.info(\"\\(\"    ws://localhost:\\(localPort)/\\(target)\", color: .green, style: .bold)\")\n            }\n        }\n    }\n\n    fileprivate func daemonServiceOnNewConnection(connection: ValdiDaemonProtocolConnection, autoConnector: DaemonServiceAutoConnector, deviceId: String) {\n        queue.async {\n            self.idSequence += 1\n            let clientId = self.idSequence\n\n            let client = DaemonServiceConnectedClient(\n                id: clientId,\n                deviceId: deviceId,\n                protocolConnection: connection,\n                autoConnector: autoConnector)\n            self.connectedClients.append(client)\n        }\n    }\n\n}\n\nextension DaemonService: DaemonServiceAutoConnectorDelegate {\n    func autoConnector(_ autoConnector: DaemonServiceAutoConnector, newConnectionEstablished connection: DaemonTCPConnection, deviceId: String) {\n        let protocolConnection = ValdiDaemonProtocolConnection(logger: logger, connection: connection, delegate: self)\n        daemonServiceOnNewConnection(connection: protocolConnection, autoConnector: autoConnector, deviceId: deviceId)\n    }\n\n}\n\nextension DaemonService: ValdiDaemonProtocolConnectionDelegate {\n\n    func connection(_ connection: ValdiDaemonProtocolConnection, didDisconnectWithError error: Error?) {\n        retrieveClient(connection: connection) { (client) in\n            // Sometimes (i.e. when using ADB) we may have an established connection, but it will fail as soon as we read from\n            // it, since the stream is actually empty.\n            // This condition prevents over\n            if connection.isConfirmed {\n                self.logger.info(\"Client \\(client) disconnected with error: \\(error?.legibleLocalizedDescription ?? \"<none>\") \")\n            } else {\n                self.logger.verbose(\"Client \\(client) disconnected with error: \\(error?.legibleLocalizedDescription ?? \"<none>\") \")\n            }\n            if client.debuggerConnected {\n                client.debuggerConnected = false\n                self.logger.info(\"\\(\"Debugger disconnected from client\", color: .red, style: .bold)\")\n                for tunnel in client.tunnels {\n                    tunnel.stop()\n                }\n            }\n            client.tunnels.removeAll()\n            self.removeClient(client)\n        }\n    }\n\n    func connection(_ connection: ValdiDaemonProtocolConnection, didReceiveRequest request: DaemonClientRequest, responsePromise: Promise<DaemonServerResponse>) {\n        retrieveClient(connection: connection) { (client) in\n            self.processRequest(request: request, response: responsePromise, client: client)\n        }\n    }\n\n    func connection(_ connection: ValdiDaemonProtocolConnection, didReceiveEvent event: DaemonClientEvent) {\n        retrieveClient(connection: connection) { (client) in\n            self.processEvent(event: event, client: client)\n        }\n    }\n\n}\n\nextension DaemonService: TCPTunnelManagerDelegate {\n    func tunnelConnectionCreated(_ tunnel: TCPTunnel, connection: TCPTunnelConnection, from: TCPConnection, to: TCPConnection) {\n    }\n\n    func tunnelConnectionDisconnected(_ tunnel: TCPTunnel, connection: TCPTunnelConnection) {\n    }\n\n    func tunnelConnectionError(_ tunnel: TCPTunnel, error: Error) {\n        logger.error(\"Unexpected error with debugger tunnel: \\(error). Reconnect device to renabled debugging\")\n        tunnel.stop()\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/DaemonServiceConnectedClient.swift",
    "content": "//\n//  DaemonServiceConnectedClient.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 2/15/19.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class DaemonServiceConnectedClient: CustomStringConvertible {\n\n    let protocolConnection: ValdiDaemonProtocolConnection\n\n    let id: Int\n    var applicationId: String?\n    var platform: Platform?\n    var wasConfigured = false\n    var clientIsReady = false\n    var hotReloadDisabled = false\n    var logsWriter: LogsWriter?\n    var autoConnector: DaemonServiceAutoConnector\n    var deviceId: String\n    var tunnels: [TCPTunnel] = []\n    var debuggerConnected = false\n\n    init(id: Int, deviceId: String, protocolConnection: ValdiDaemonProtocolConnection, autoConnector: DaemonServiceAutoConnector) {\n        self.id = id\n        self.protocolConnection = protocolConnection\n        self.deviceId = deviceId\n        self.autoConnector = autoConnector\n    }\n\n    var description: String {\n        if wasConfigured {\n            return \"{ platform: \\(platform?.rawValue ?? \"\"), applicationId: \\(applicationId ?? \"\"), connectionKey: \\(protocolConnection.connectionKey) }\"\n        } else {\n            return \"{ UNCONFIGURED CLIENT \\(protocolConnection.connectionKey) }\"\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/DaemonServiceDefinitions.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Carson Holgate on 4/26/22.\n//\n\nimport Foundation\n\nstruct DaemonClientLog: Codable {\n    var severity: String\n    var log: String\n}\n\nstruct DaemonSendLogsServerResponse: Codable {\n    var logs: [DaemonClientLog]\n}\n\nstruct DaemonErrorResponse: Codable {\n    var error_message: String\n}\n\nstruct DaemonClientConfigureResponse: Codable {}\n\nstruct DaemonConnectedClient: Codable {\n    var client_id: Int32\n    var platform: String\n    var application_id: String?\n}\n\nstruct DaemonClientListConnectedClientsResponse: Codable {\n    var clients: [DaemonConnectedClient]\n}\n\nstruct DaemonClientForwardPayloadResponse: Codable {}\n\nstruct DaemonFileManagerFileEntry: Codable {\n    var filename: String\n    var absolute_path: String\n    var type: Int\n    var modification_date: Int?\n    var creation_date: Int?\n}\n\nstruct DaemonFileManagerPayloadResponse: Codable {\n    var data_base64: String?\n    var data_string: String?\n    var entries: [DaemonFileManagerFileEntry]?\n}\n\nstruct DaemonServerResponse: Codable {\n    var request_id: String?\n    var error: DaemonErrorResponse?\n    var configure: DaemonClientConfigureResponse?\n    var list_connected_clients: DaemonClientListConnectedClientsResponse?\n    var forward_client_payload: DaemonClientForwardPayloadResponse?\n    var file_manager: DaemonFileManagerPayloadResponse?\n}\n\nstruct DaemonSendLogsServerRequest: Codable {}\n\nstruct DaemonServerRequest: Codable {\n    var request_id: String?\n    var send_logs: DaemonSendLogsServerRequest?\n}\n\nstruct DaemonResource: Codable {\n    var bundle_name: String\n    var file_path_within_bundle: String\n    var data_base64: Data?\n    var data_string: String?\n}\n\nstruct DaemonUpdatedResourcesEvent: Codable {\n    var resources: [DaemonResource]\n}\n\nstruct DaemonPayloadFromClientEvent: Codable {\n    var sender_client_id: Int32\n    var payload_base64: Data?\n    var payload_string: String?\n}\n\nstruct DaemonServerEvent: Codable {\n    var updated_resources: DaemonUpdatedResourcesEvent?\n    var payload_from_client: DaemonPayloadFromClientEvent?\n}\n\nstruct DaemonServerPayload: Codable {\n    var request: DaemonServerRequest?\n    var response: DaemonServerResponse?\n    var event: DaemonServerEvent?\n}\n\nstruct DaemonClientResponse: Codable {\n    var request_id: String\n    var error: DaemonErrorResponse?\n    var send_logs: DaemonSendLogsServerResponse?\n}\n\nstruct DaemonClientConfigureRequest: Codable {\n    var application_id: String\n    var platform: String\n    var disable_hot_reload: Bool?\n}\n\nstruct DaemonListConnectedClientsRequest: Codable {}\n\nstruct DaemonClientForwardPayloadRequest: Codable {\n    var client_id: Int\n    var payload_base64: Data?\n    var payload_string: String?\n}\n\nstruct DaemonClientRequest: Decodable {\n    var request_id: String\n    var configure: DaemonClientConfigureRequest?\n    var list_connected_clients: DaemonListConnectedClientsRequest?\n    var forward_client_payload: DaemonClientForwardPayloadRequest?\n    var file_manager: DaemonFileManagerRequest?\n}\n\nstruct DaemonJsDebuggerInfo: Codable {\n    var port : Int\n    var websocket_targets: [String]\n}\n\nstruct DaemonClientEvent: Codable {\n    var new_logs: [DaemonClientLog]?\n    var js_debugger_info: DaemonJsDebuggerInfo?\n}\n\nstruct DaemonFileManagerRequestBody: Decodable {\n    var path: String\n    var data_string: String?\n    var data_base64: Data?\n    var output_format: OutputFormat?\n\n    enum OutputFormat: String, Decodable {\n        case base64\n        case string\n    }\n}\n\nstruct DaemonFileManagerRequest: Decodable {\n    let type: RequestType\n    let body: DaemonFileManagerRequestBody\n\n    enum RequestType: String, Decodable {\n        case write_file\n        case read_file\n        case read_directory\n        case delete_file\n    }\n\n}\n\nstruct DaemonClientPayload: Decodable {\n    var request: DaemonClientRequest?\n    var response: DaemonClientResponse?\n    var event: DaemonClientEvent?\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/DaemonServiceSimulatorAutoConnector.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by saniul on 10/10/2019.\n//\n\nimport Foundation\nimport BlueSocket\n\nfinal class DaemonServiceSimulatorAutoConnector: DaemonServiceAutoConnector {\n    weak var delegate: DaemonServiceAutoConnectorDelegate?\n\n    let port: Int\n    var key: String { return \"localhost:\\(port)\" }\n\n    private let logger: ILogger\n    private let queue = DispatchQueue(label: \"DaemonServiceSimulatorAutoConnector\")\n    private var socket: Socket?\n\n    init(logger: ILogger, port: Int) {\n        self.logger = logger\n        self.port = port\n    }\n\n    func start() {\n        queue.async { [weak self] in\n            self?.attemptConnecting()\n        }\n    }\n\n    private func cleanUpAndScheduleNextAttempt() {\n        self.socket = nil\n        queue.asyncAfter(deadline: .now() + 1) { [weak self] in\n            self?.attemptConnecting()\n        }\n    }\n\n    private func attemptConnecting() {\n        assert(socket == nil)\n\n        do {\n            let socket = try Socket.create()\n            try socket.connect(to: \"localhost\", port: Int32(port))\n            self.socket = socket\n\n            let connection = DaemonTCPConnection(logger: logger, socket: socket)\n            connection.addDisconnectHandler({ [weak self] _ in\n                guard let self else { return }\n                self.logger.info(\"Localhost reloader connection with iOS Simulator ended\")\n                self.cleanUpAndScheduleNextAttempt()\n            })\n            logger.info(\"Localhost reloader connection with iOS Simulator established\")\n            delegate?.autoConnector(self, newConnectionEstablished: connection, deviceId: \"localhost\")\n        } catch {\n            cleanUpAndScheduleNextAttempt()\n            return\n        }\n    }\n\n    func createTunnel(logger: ILogger, fromLocalPort localPort: Int, toDeviceId: String, devicePort: Int) throws -> TCPTunnel? {\n        return try LocalTCPTunnel(logger: logger, listenPort: localPort, destinationPort: devicePort)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/DaemonServiceUSBMuxAutoConnector.swift",
    "content": "//\n//  DaemonServiceUSBMuxAutoConnector.swift\n//  Compiler\n//\n//  Created by saniul on 09/10/2019.\n//\n\nimport Foundation\n\nfinal class DaemonServiceUSBMuxAutoConnector: DaemonServiceAutoConnector, USBMuxClientDelegate {\n    weak var delegate: DaemonServiceAutoConnectorDelegate?\n\n    private let logger: ILogger\n    private let queue = DispatchQueue(label: \"USBMuxAutoConnector\", attributes: .concurrent)\n    private let usbMuxClient: USBMuxClient\n\n    init(logger: ILogger) {\n        self.logger = logger\n        let usbMuxClient = USBMuxClient(logger: logger, devicePortNumber: Ports.reloaderOverUSB)\n        self.usbMuxClient = usbMuxClient\n        usbMuxClient.delegate = self\n    }\n\n    func start() {\n        usbMuxClient.start()\n    }\n\n    func usbMuxClientDeviceConnected(_ client: USBMuxClient, deviceId: USBMuxDeviceId, connection: USBMuxDeviceConnection) {\n        logger.info(\"USB reloader connection with iOS device established: \\(deviceId)\")\n\n        guard let channel = connection.channel else {\n            fatalError(\"usbMuxDeviceConnected, but no channel\")\n        }\n\n        let connectionKey = \"usb:\\(deviceId):\\(connection.port)\"\n        let connection = DaemonTCPConnection(logger: logger, key: connectionKey, channel: channel)\n        delegate?.autoConnector(self, newConnectionEstablished: connection, deviceId: deviceId.description)\n    }\n\n    func usbMuxClientDeviceDisconnected(_ client: USBMuxClient, deviceId: USBMuxDeviceId) {\n        queue.async(flags: .barrier) {\n            self.logger.info(\"USB reloader connection with iOS device ended: \\(deviceId)\")\n        }\n    }\n\n    func createTunnel(logger: ILogger, fromLocalPort localPort: Int, toDeviceId: String, devicePort: Int) throws -> TCPTunnel? {\n        let usbMuxDeviceId = USBMuxDeviceId(Int(toDeviceId)!)\n        logger.info(\"Opening USBMux Tunnel from localhost:\\(localPort) -> DeviceId:\\(usbMuxDeviceId):\\(devicePort)\")\n        return try USBMuxTunnel(logger: logger, listenPort: localPort, deviceId: usbMuxDeviceId, devicePort: devicePort)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/DaemonTCPConnection.swift",
    "content": "//\n//  DaemonTCPConnection.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 2/15/19.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport BlueSocket\n\nprotocol DaemonTCPConnectionDelegate: AnyObject {\n    func connection(_ connection: DaemonTCPConnection, didReceiveData data: Data)\n    func connection(_ connection: DaemonTCPConnection, didDisconnectWithError error: Error?)\n}\n\nprivate struct ValdiProtocol: TCPConnectionDataProcessor {\n    func process(data: Data) -> TCPConnectionProcessDataResult {\n        if data.count < 8 {\n            return .notEnoughData(lengthNeeded: 8 - data.count)\n        }\n\n        if !data.starts(with: Magic.valdiMagic) {\n            return .invalid(dataToDiscard: 1)\n        }\n\n        let dataLength: UInt32 = data.withUnsafePointer { bufferStart in\n            return bufferStart.advanced(by: 1).pointee\n        }\n\n        if dataLength > data.count - 8 {\n            // Not enough data yet\n            return .notEnoughData(lengthNeeded: Int(dataLength) - (data.count - 8))\n        }\n\n        return .valid(dataLength: Int(dataLength) + 8)\n    }\n}\n\nfinal class DaemonTCPConnection: TCPConnectionDelegate {\n    weak var delegate: DaemonTCPConnectionDelegate?\n\n    var key: String {\n        return connection.key\n    }\n\n    var everReadPacket: Bool = false\n\n    private let connection: TCPConnection\n    private var disconnectHandlers: [((Error?) -> Void)] = []\n\n    private var additionalDisconnectHandlers: [((Error?) -> Void)] = []\n\n    convenience init(logger: ILogger, socket: Socket) {\n        let connection = BlueSocketTCPConnection(logger: logger, socket: socket, queueNamePrefix: \"DaemonTCPConnection\")\n        self.init(connection: connection)\n    }\n\n    convenience init(logger: ILogger, key: String, channel: DispatchIO) {\n        let connection = DispatchChannelTCPConnection(logger: logger, key: key, ioChannel: channel, queueNamePrefix: \"DaemonTCPConnection\")\n        self.init(connection: connection)\n    }\n\n    init(connection: TCPConnection) {\n        self.connection = connection\n        self.connection.dataProcessor = ValdiProtocol()\n        self.connection.delegate = self\n    }\n\n    func startListening() {\n        connection.startListening()\n    }\n\n    func close() {\n        connection.close()\n    }\n\n    func send(data: Data) {\n        var packetData = Data(capacity: 8 + data.count)\n        packetData.append(Magic.valdiMagic)\n\n        var dataLength = UInt32(data.count)\n        Swift.withUnsafePointer(to: &dataLength) {\n            packetData.append(UnsafeBufferPointer(start: $0, count: 1))\n        }\n        packetData.append(data)\n\n        connection.send(data: packetData)\n    }\n\n    func addDisconnectHandler(_ handler: @escaping (Error?) -> Void) {\n        self.disconnectHandlers.append(handler)\n    }\n\n    func connection(_ connection: TCPConnection, didReceiveData data: Data) {\n        let packet = data[8...]\n        everReadPacket = true\n        delegate?.connection(self, didReceiveData: packet)\n    }\n\n    func connection(_ connection: TCPConnection, didDisconnectWithError error: Error?) {\n        delegate?.connection(self, didDisconnectWithError: error)\n        for handler in disconnectHandlers {\n            handler(error)\n        }\n        disconnectHandlers = []\n    }\n}\n\nextension DaemonTCPConnection: CustomStringConvertible {\n\n    var description: String {\n        return key\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/DaemonTCPConnectionAcceptor.swift",
    "content": "//\n//  DaemonTCPConnectionAcceptor.swift\n//  Compiler\n//\n//  Created by saniul on 03/02/2019.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport BlueSocket\n\nfinal class DaemonTCPConnectionAcceptor: DaemonServiceAutoConnector {\n    weak var delegate: DaemonServiceAutoConnectorDelegate?\n    let listeningPort: Int\n\n    private let logger: ILogger\n    private let listenSocket: Socket\n    private let acceptQueue = DispatchQueue(label: \"com.snap.valdi.DaemonTCPConnectionAcceptor.accept\")\n    private var startedAccepting: Bool = false\n\n    init(logger: ILogger, port: Int = 0) throws {\n        self.logger = logger\n        let socket = try Socket.create(family: .inet, type: .stream, proto: .tcp)\n        self.listenSocket = socket\n        try socket.listen(on: port)\n        self.listeningPort = Int(socket.listeningPort)\n        logger.info(\"Reloader listening on port: \\(socket.listeningPort)\")\n    }\n\n    deinit {\n        self.listenSocket.close()\n    }\n\n    func startAccepting() {\n        guard !startedAccepting else {\n            return\n        }\n\n        startedAccepting = true\n        runAcceptLoop()\n    }\n\n    private func runAcceptLoop() {\n        acceptQueue.async {\n            repeat {\n                do {\n                    let newSocket = try self.listenSocket.acceptClientConnection()\n\n                    self.logger.info(\"Accepted reloader connection from {\\(newSocket.remoteHostname):\\(newSocket.remotePort)}\")\n\n                    self.addNewConnection(socket: newSocket)\n                } catch {\n                    guard let socketError = error as? Socket.Error else {\n                        self.logger.error(\"Unexpected error...\")\n                        return\n                    }\n\n                    self.logger.error(\"Error while accepting: \\(socketError.description)\")\n                }\n\n            } while self.listenSocket.isActive == true\n        }\n    }\n\n    private func addNewConnection(socket: Socket) {\n        let connection = DaemonTCPConnection(logger: logger, socket: socket)\n        delegate?.autoConnector(self, newConnectionEstablished: connection, deviceId: \"localhost\")\n    }\n\n    func createTunnel(logger: ILogger, fromLocalPort localPort: Int, toDeviceId: String, devicePort: Int) throws -> TCPTunnel? {\n        return try LocalTCPTunnel(logger: logger, listenPort: localPort, destinationPort: devicePort)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/DocumentChangeNotifier.swift",
    "content": "//\n//  DocumentChangeNotifier.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprotocol DocumentChangeNotifier {\n\n    func propagateEventData(_ eventData: Data)\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/FileDependenciesManager.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 10/29/19.\n//\n\nimport Foundation\n\nstruct DeclaredFileDependencies {\n    let key: String\n    let dependencies: Set<URL>\n}\n\nclass FileDependenciesManager {\n\n    private let lock = DispatchSemaphore.newLock()\n\n    private var dependenciesByFile = [URL: [DeclaredFileDependencies]]()\n    private var dependentsByFile = [URL: Set<URL>]()\n    private var dependentsDirty = false\n\n    func register(file: URL, dependencies: Set<URL>, forKey key: String, append: Bool = false) {\n        lock.lock {\n            var declaredDependencies = dependenciesByFile[file, default: []]\n\n            if let existingIndex = declaredDependencies.firstIndex(where: { $0.key == key }) {\n                let existingDeps = declaredDependencies[existingIndex].dependencies\n\n                let newDependencies: Set<URL>\n                if append {\n                    newDependencies = existingDeps.union(dependencies)\n                } else {\n                    newDependencies = dependencies\n                }\n\n                if existingDeps == newDependencies {\n                    // Dependencies are the same\n                    return\n                }\n\n                declaredDependencies[existingIndex] = DeclaredFileDependencies(key: key, dependencies: newDependencies)\n            } else {\n                declaredDependencies.append(DeclaredFileDependencies(key: key, dependencies: dependencies))\n            }\n\n            dependenciesByFile[file] = declaredDependencies\n            dependentsDirty = true\n        }\n    }\n\n    private func computeDependents() {\n        // TODO(simon): Can be made incremental if necessary\n        dependentsByFile.removeAll()\n\n        for (file, declaredDependencies) in dependenciesByFile {\n            for dependencies in declaredDependencies {\n                for dependency in dependencies.dependencies {\n                    dependentsByFile[dependency, default: []].insert(file)\n                }\n            }\n        }\n    }\n\n    func getDependents(file: URL) -> [URL] {\n        return lock.lock {\n            if dependentsDirty {\n                dependentsDirty = false\n                computeDependents()\n            }\n            guard let dependents = dependentsByFile[file] else {\n                return []\n            }\n            return dependents.map { $0 }\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/NonSpammyLog.swift",
    "content": "//\n//  NonSpammyLog.swift\n//  Compiler\n//\n//  Created by saniul on 10/05/2019.\n//\n\nimport Foundation\n\nclass NonSpammyLogger<Key: Hashable> {\n    private var countsByKey: Synchronized<[Key: Int]> = Synchronized(data: [:])\n\n    private let logger: ILogger\n\n    init(logger: ILogger) {\n        self.logger = logger\n    }\n\n    func log(level: LogLevel, maxCount: Int, key: Key, _ message: @autoclosure () -> String, _ functionStr: StaticString = #function) {\n        countsByKey.data { countsByKey in\n            var currentCount = countsByKey[key] ?? 0\n\n            currentCount += 1\n            guard currentCount <= maxCount else {\n                return\n            }\n\n            logger.log(level: level, message, functionStr: functionStr)\n\n            if currentCount == maxCount {\n                logger.log(level: level, { \"...won't log further messages like ^that to avoid spamming the logs\" }, functionStr: functionStr)\n            }\n\n            countsByKey[key] = currentCount\n        }\n    }\n\n    func reset(key: Key) {\n        countsByKey.data { countsByKey in\n            countsByKey[key] = 0\n        }\n    }\n\n    func reset(matching predicate: (Key) -> Bool) {\n        countsByKey.data { countsByKey in\n            let keysToRemove = countsByKey.filter { key, _ in predicate(key) }.keys\n            keysToRemove.forEach { countsByKey[$0] = nil }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/ReloaderDeviceWhitelist.swift",
    "content": "//\n//  ReloaderContext.swift\n//  Compiler\n//\n//  Created by saniul on 28/12/2018.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ReloaderDeviceWhitelist {\n    init(deviceIds: Set<String>, usernames: Set<String>, ipAddresses: Set<String>) {\n        self.deviceIds = deviceIds\n        self.usernames = usernames\n\n        var foundAddressPorts = Set<AddressPort>()\n        var foundIpAddresses = Set<String>()\n        for addressStr in ipAddresses {\n            let components = addressStr.components(separatedBy: \":\")\n            if components.count == 2, let port = Int32(components[1]) {\n                let address = components[0]\n                let addressPort = AddressPort(family: .IPv4, address: address, port: port)\n                foundAddressPorts.insert(addressPort)\n                foundIpAddresses.insert(address)\n            } else {\n                foundIpAddresses.insert(addressStr)\n            }\n        }\n        self.ipAddresses = foundIpAddresses\n        addressPorts = foundAddressPorts\n    }\n\n    let deviceIds: Set<String>\n    let usernames: Set<String>\n    let ipAddresses: Set<String>\n    let addressPorts: Set<AddressPort>\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/ReloaderServiceAnnouncer.swift",
    "content": "//\n//  ReloaderServiceAnnouncer.swift\n//  Compiler\n//\n//  Created by saniul on 01/05/2019.\n//\n\nimport Foundation\n\nprotocol ReloaderServiceAnnouncerType {\n}\n\nfinal class ReloaderServiceAnnouncer {\n    private let logger: ILogger\n    private let processID = UUID().uuidString\n    private let subannouncers: [ReloaderServiceAnnouncerType]\n\n    init(logger: ILogger, deviceWhitelist: ReloaderDeviceWhitelist, projectConfig: ValdiProjectConfig, servicePort: Int) throws {\n        self.logger = logger\n        var subannouncers: [ReloaderServiceAnnouncerType] = []\n        do {\n            subannouncers.append(try ReloaderServiceUDPAnnouncer(logger: logger, processID: processID, deviceWhitelist: deviceWhitelist, servicePort: servicePort))\n        } catch {\n            logger.error(\"Failed to setup UDP reloader: \\(error.legibleLocalizedDescription)\")\n        }\n\n        self.subannouncers = subannouncers\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/ReloaderServiceUDPAnnouncer.swift",
    "content": "//\n//  ReloaderServiceAnnouncer.swift\n//  Compiler\n//\n//  Created by saniul on 03/02/2019.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport BlueSocket\nimport LegibleError\n\nprivate let valdiMulticastGroup: String = \"226.1.1.1\"\nprivate let announcerTimeInterval: TimeInterval = 5.0\n\n/// Uses UDP broadcast to announce the addresses and ports where the reloader service is listening\nfinal class ReloaderServiceUDPAnnouncer: ReloaderServiceAnnouncerType {\n    private let logger: ILogger\n    private let processID: String\n    private let deviceWhitelist: ReloaderDeviceWhitelist\n    private let servicePort: Int\n\n    private let sendToAddresses: [Socket.Address]\n    private let sendQueue: DispatchQueue\n    private let recvQueue: DispatchQueue\n    private var recvSocket: Socket\n    private var announcerTimer: Timer?\n\n    private var socketsByInterface: [in_addr: Socket] = [:]\n    private var announceFailureLogger: NonSpammyLogger<AnnounceFailureKey>\n\n    init(logger: ILogger, processID: String, deviceWhitelist: ReloaderDeviceWhitelist, servicePort: Int) throws {\n        self.logger = logger\n        self.processID = processID\n        self.deviceWhitelist = deviceWhitelist\n        self.servicePort = servicePort\n        self.announceFailureLogger = NonSpammyLogger<AnnounceFailureKey>(logger: logger)\n\n        let whitelistedAddresses = deviceWhitelist.ipAddresses.compactMap { try? $0.toIpAddress() }\n        let ipAddresses = whitelistedAddresses + [try \"127.0.0.1\".toIpAddress()] + [try valdiMulticastGroup.toIpAddress(), UInt32.max]\n        self.sendToAddresses = ipAddresses.map { Socket.Address(address: $0, port: UInt16(Ports.reloaderServiceDiscovery)) }\n\n        self.sendQueue = DispatchQueue(label: \"com.snap.valdi.ReloaderServiceAnnouncer.send\")\n        self.recvQueue = DispatchQueue(label: \"com.snap.valdi.ReloaderServiceAnnouncer.recv\")\n        self.recvSocket = try Socket.create(family: .inet, type: .datagram, proto: .udp)\n\n        try configureRecvSocket()\n\n        if #available(OSX 10.12, *) {\n            announcerTimer = Timer.scheduledTimer(withTimeInterval: announcerTimeInterval, repeats: true) { [weak self] (_) in\n                logger.verbose(\"Reloader: Announcing 'Daemon awake' on a timer\")\n                try? self?.announceDaemonAwake(additionalAddress: nil)\n            }\n        }\n        try announceDaemonAwake(additionalAddress: nil)\n\n        startListeningForClientAwakes()\n    }\n\n    deinit {\n        announcerTimer?.invalidate()\n        recvSocket.close()\n    }\n\n    private func configureSendSocket(_ socket: Socket, networkInterfaceAddress: in_addr) throws {\n        var addr = networkInterfaceAddress\n        let result = setsockopt(socket.socketfd, Int32(IPPROTO_IP), IP_MULTICAST_IF, &addr, socklen_t(MemoryLayout<in_addr>.size))\n\n        try socket.udpBroadcast(enable: true)\n\n        if result < 0 {\n            throw CompilerError(\"Failed to configure specific multicast interface for send socket\")\n        }\n    }\n\n    private func configureRecvSocket() throws {\n        let groupIpAddr = try valdiMulticastGroup.toIpAddress()\n\n        var mreq: ip_mreq = ip_mreq(imr_multiaddr: in_addr(s_addr: groupIpAddr), imr_interface: in_addr(s_addr: INADDR_ANY))\n        let result = setsockopt(recvSocket.socketfd, Int32(IPPROTO_IP), IP_ADD_MEMBERSHIP, &mreq, socklen_t(MemoryLayout<ip_mreq>.size))\n\n        if result < 0 {\n            throw CompilerError(\"Failed to add multicast group membership for recv socket\")\n        }\n    }\n\n    private func startListeningForClientAwakes() {\n        recvQueue.async { [weak self, recvSocket] in\n            repeat {\n                guard let this = self else {\n                    break\n                }\n\n                do {\n                    var data = Data()\n                    let (bytesRead, address) = try this.recvSocket.listen(forMessage: &data, on: Ports.reloaderServiceDiscovery)\n                    guard bytesRead > 0 else {\n                        continue\n                    }\n\n                    let payload = try Valdi_DaemonServiceDiscoveryPayload(serializedData: data)\n                    this.logger.verbose(\"Received discovery payload\")\n\n                    guard let payloadMessage = payload.message else {\n                        this.logger.verbose(\"Couldn't decode payload message, ignoring\")\n                        continue\n                    }\n\n                    guard case .clientAwakeMessage(let message) = payloadMessage else {\n                        this.logger.verbose(\"Not a 'Client awake' message, ignoring\")\n                        continue\n                    }\n\n                    this.logger.verbose(\"Client awake payload username: \\(message.username) deviceId: \\(message.deviceID)\")\n                    guard this.deviceWhitelist.usernames.contains(message.username) || this.deviceWhitelist.deviceIds.contains(message.deviceID) else {\n                        this.logger.verbose(\"'Client awake' message does not contain whitelisted username or deviceID, ignoring\")\n                        continue\n                    }\n\n                    this.logger.verbose(\"Announcing 'Daemon awake' in response to a 'Client awake' message\")\n                    try this.announceDaemonAwake(additionalAddress: address)\n                } catch {\n                    this.logger.error(\"Listening loop error: \\(error.legibleLocalizedDescription)\")\n                }\n            } while recvSocket.isActive\n        }\n    }\n\n    private func announceDaemonAwake(additionalAddress: Socket.Address?) throws {\n        let sendToAddresses = self.sendToAddresses + [additionalAddress].compactMap({ $0 })\n\n        let interfaceAddresses = NetworkInterfaceAddresses.getAll()\n\n        var message = Valdi_DaemonAwakeMessage()\n        message.deviceIds = Array(deviceWhitelist.deviceIds)\n        message.usernames = Array(deviceWhitelist.usernames)\n        message.processID = processID\n        message.serviceAddresses = interfaceAddresses.cInAddrs.map { String(cString: inet_ntoa($0)) }\n        message.servicePort = Int32(servicePort)\n        var payload = Valdi_DaemonServiceDiscoveryPayload()\n        payload.daemonAwakeMessage = message\n        let payloadData = try payload.serializedData()\n\n        sendQueue.async { [weak self] in\n            guard let this = self else { return }\n\n            this.updateInterfaces(interfaceAddresses.cInAddrs)\n            for (interface, socket) in this.socketsByInterface {\n                for addressToSendTo in sendToAddresses {\n                    guard case let .ipv4(addr) = addressToSendTo else {\n                        continue\n                    }\n\n                    let targetAddressString = String(cString: inet_ntoa(addr.sin_addr))\n                    let interfaceAddressString = String(cString: inet_ntoa(interface))\n\n                    this.logger.verbose(\"Sending daemon awake packet addressed to \\(targetAddressString) via interface \\(interfaceAddressString)\")\n\n                    do {\n                        try socket.write(from: payloadData, to: addressToSendTo)\n                    } catch let error {\n                        let key = AnnounceFailureKey(networkInterfaceAddress: interfaceAddressString, error: error)\n                        this.announceFailureLogger.log(level: .verbose, maxCount: 1, key: key, \"Failed to announce daemon awake addressed to \\(targetAddressString) via interface \\(interfaceAddressString): \\(error.legibleLocalizedDescription)\")\n                    }\n                }\n            }\n        }\n    }\n\n    private func updateInterfaces(_ interfaces: [in_addr]) {\n        let next = Set(interfaces)\n        let current = Set(socketsByInterface.keys)\n\n        let removedInterfaces = current.subtracting(next)\n        for removedInterface in removedInterfaces {\n            let interfaceAddress = String(cString: inet_ntoa(removedInterface))\n            logger.verbose(\"Removed interface, closing socket and cleaning up: \\(interfaceAddress)\")\n\n            let socket = socketsByInterface[removedInterface]\n            socket?.close()\n            socketsByInterface[removedInterface] = nil\n\n            announceFailureLogger.reset(matching: { $0.networkInterfaceAddress == interfaceAddress })\n        }\n\n        let addedInterfaces = next.subtracting(current)\n        for addedInterface in addedInterfaces {\n            do {\n                let interfaceAddress = String(cString: inet_ntoa(addedInterface))\n                logger.verbose(\"Added interface, configuring socket for it: \\(interfaceAddress)\")\n                let socket = try Socket.create(family: .inet, type: .datagram, proto: .udp)\n                try self.configureSendSocket(socket, networkInterfaceAddress: addedInterface)\n                socketsByInterface[addedInterface] = socket\n            } catch {\n                logger.error(\"Failed to configure send socket: \\(error.legibleLocalizedDescription)\")\n            }\n        }\n    }\n}\n\nstruct AnnounceFailureKey: Hashable {\n    let networkInterfaceAddress: String\n    let error: Error\n\n    static func == (lhs: AnnounceFailureKey, rhs: AnnounceFailureKey) -> Bool {\n        return (lhs.networkInterfaceAddress == rhs.networkInterfaceAddress)\n            && (lhs.error.legibleDescription == rhs.error.legibleLocalizedDescription)\n    }\n\n    func hash(into hasher: inout Hasher) {\n        hasher.combine(networkInterfaceAddress)\n        hasher.combine(error.legibleLocalizedDescription)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/ResourceStore.swift",
    "content": "//\n//  ResourceStore.swift\n//  Compiler\n//\n//  Created by saniul on 27/12/2018.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct Resource {\n    let item: CompilationItem\n    let finalFile: FinalFile\n    let data: Data\n\n    let filePathInBundle: String\n\n    init(item: CompilationItem, finalFile: FinalFile, data: Data) {\n        self.item = item\n        self.finalFile = finalFile\n        self.data = data\n\n        filePathInBundle = Resource.getFilePathInBudle(item: item, finalFile: finalFile)\n    }\n\n    static func getFilePathInBudle(item: CompilationItem, finalFile: FinalFile) -> String {\n        return finalFile.outputPath(relativeBundleURL: item.relativeBundleURL)\n    }\n}\n\n/**\n Store all compiled resources by file path\n */\nfinal class ResourceStore {\n\n    private let resourcesLock = DispatchSemaphore.newLock()\n\n    private var resources = [String: Resource]()\n\n    var allResources: [Resource] {\n        return resourcesLock.lock { Array(resources.values) }\n    }\n\n    func addResource(_ resource: Resource) {\n        let platformPrefix = resource.finalFile.platform.map { \"\\($0)\" } ?? \"unknown\"\n        let filePath = resource.item.relativeBundleURL\n            .deletingLastPathComponent()\n            .appendingPathComponent(resource.finalFile.outputURL.lastPathComponent)\n            .standardized.path\n        let bundleName = resource.item.bundleInfo.name\n        let fullPath = \"\\(platformPrefix)/\\(bundleName)/\\(filePath)\"\n\n        resourcesLock.lock {\n            resources[fullPath] = resource\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/String+Network.swift",
    "content": "//\n//  Utils.swift\n//  Compiler\n//\n//  Created by saniul on 04/02/2019.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension String {\n    func toIpAddress() throws -> UInt32 {\n        let components = self.components(separatedBy: \".\").compactMap { UInt32($0) }\n        guard components.count == 4 else {\n            throw CompilerError(\"Invalid ip address: \" + self)\n        }\n\n        var out: UInt32 = 0\n        for (index, component) in components.enumerated() {\n            guard component < 255 else {\n                throw CompilerError(\"Invalid ip address: \" + self)\n            }\n            out |= component << (8 * (3 - index))\n        }\n        return out.bigEndian\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/ValdiDaemonProtocolClient.swift",
    "content": "//\n//  ValdiDaemonProtocolConnection.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 2/15/19.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport SwiftProtobuf\n\nprotocol ValdiDaemonProtocolConnectionDelegate: AnyObject {\n\n    func connection(_ connection: ValdiDaemonProtocolConnection, didDisconnectWithError error: Error?)\n\n    func connection(_ connection: ValdiDaemonProtocolConnection, didReceiveRequest request: DaemonClientRequest, responsePromise: Promise<DaemonServerResponse>)\n\n    func connection(_ connection: ValdiDaemonProtocolConnection, didReceiveEvent event: DaemonClientEvent)\n\n}\n\nfinal class ValdiDaemonProtocolConnection {\n    var connectionKey: String { return connection.key }\n\n    // Sometimes (i.e. when using ADB) we may have an established connection, but it will fail as soon as we read from\n    // it, since the stream is actually empty. isConfirmed will be true if we've read at least a single packet.\n    var isConfirmed: Bool { return connection.everReadPacket }\n\n    private let logger: ILogger\n    private weak var delegate: ValdiDaemonProtocolConnectionDelegate?\n\n    private let connection: DaemonTCPConnection\n    private let queue = DispatchQueue(label: \"com.snap.valdi.DaemonService.client\")\n\n    private var promiseByRequestId = [String: Promise<DaemonClientResponse>]()\n\n    init(logger: ILogger, connection: DaemonTCPConnection, delegate: ValdiDaemonProtocolConnectionDelegate) {\n        self.logger = logger\n        self.delegate = delegate\n        self.connection = connection\n        connection.delegate = self\n        connection.startListening()\n    }\n\n    func close() {\n        queue.async {\n            self.connection.close()\n        }\n    }\n\n    func send(event: DaemonServerEvent) {\n        queue.async {\n            var payload = DaemonServerPayload()\n            payload.event = event\n            self.doSend(payload: payload)\n        }\n    }\n\n    func send(request: DaemonServerRequest) -> Promise<DaemonClientResponse> {\n        let requestId = UUID().uuidString\n\n        let promise = Promise<DaemonClientResponse>()\n\n        queue.async {\n            self.promiseByRequestId[requestId] = promise\n\n            var payload = DaemonServerPayload()\n            payload.request = request\n            payload.request?.request_id = requestId\n\n            self.doSend(payload: payload)\n        }\n\n        return promise\n    }\n\n    private func doSend(payload: DaemonServerPayload) {\n        do {\n            let encoder = JSONEncoder()\n            encoder.outputFormatting = .sortedKeys\n            let data = try encoder.encode(payload)\n            connection.send(data: data)\n        } catch let error {\n            logger.error(\"Failed to send data to client: \\(error)\")\n        }\n    }\n\n    private func processRequestResponse(_ response: Result<DaemonServerResponse, Error>, requestId: String) {\n        queue.async {\n            var payload = DaemonServerPayload()\n\n            do {\n                payload.response = try response.get()\n            } catch let error {\n                payload.response = DaemonServerResponse()\n                payload.response?.error = DaemonErrorResponse(error_message: error.legibleLocalizedDescription)\n            }\n            payload.response?.request_id = requestId\n\n            self.doSend(payload: payload)\n        }\n    }\n\n    private func processPacket(data: Data) {\n        do {\n            let decoder = JSONDecoder()\n            let payload = try decoder.decode(DaemonClientPayload.self, from: data)\n\n            if let request = payload.request {\n\n                let promise = Promise<DaemonServerResponse>()\n                let requestId = request.request_id\n                promise.onComplete { [weak self] (result) in\n                    self?.processRequestResponse(result, requestId: requestId)\n                }\n\n                delegate?.connection(self, didReceiveRequest: request, responsePromise: promise)\n                return\n            }\n\n            if let response = payload.response {\n\n                guard let pendingPromise = promiseByRequestId[response.request_id] else {\n                    logger.error(\"Received a response without an associated request, ignoring (request id: \\(response.request_id))\")\n                    return\n                }\n\n                if let error = response.error {\n                    pendingPromise.reject(error: CompilerError(error.error_message))\n                } else {\n                    pendingPromise.resolve(data: response)\n                }\n                return\n            }\n\n            if let event = payload.event {\n                delegate?.connection(self, didReceiveEvent: event)\n                return\n            }\n\n            // If we make it this far, something is wrong\n            throw CompilerError(\"Unknown data format: \\(payload)\")\n        } catch let error {\n            logger.error(\"Failed to deserialize packet: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n}\n\nextension ValdiDaemonProtocolConnection: DaemonTCPConnectionDelegate {\n\n    func connection(_ connection: DaemonTCPConnection, didReceiveData data: Data) {\n        queue.async {\n            self.processPacket(data: data)\n        }\n    }\n\n    func connection(_ connection: DaemonTCPConnection, didDisconnectWithError error: Error?) {\n        queue.async {\n            self.delegate?.connection(self, didDisconnectWithError: error)\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/Watchman/WatchmanClient.swift",
    "content": "//\n//  WatchmanClient.swift\n//  BlueSocket\n//\n//  Created by Simon Corsin on 6/5/19.\n//\n\nimport Foundation\n\nstruct WatchmanFileNotification {\n    enum Kind {\n        case changed\n        case created\n        case removed\n    }\n\n    let url: URL\n    let kind: Kind\n}\n\nprivate struct WatchmanObserver {\n    let callback: ([WatchmanFileNotification]) -> Void\n    var rootURL: URL?\n}\n\nclass WatchmanClient: WatchmanConnectionDelegate {\n\n    private let logger: ILogger\n    private let subscriptionToken = try! \"\\\"subscription\\\":\".utf8Data()\n\n    private let connection: WatchmanConnection\n    private let lock = DispatchSemaphore.newLock()\n\n    private var observerById: [String: WatchmanObserver] = [:]\n\n    init(logger: ILogger) throws {\n        self.logger = logger\n        do {\n            let response = try SyncProcessHandle.run(logger: logger, command: \"watchman\", arguments: [\"get-sockname\"])\n            let parsedResponse = try WatchmanGetSocknameResponse.fromJSON(try response.utf8Data())\n            self.connection = try WatchmanConnection(logger: logger, sockname: parsedResponse.sockname)\n            self.connection.delegate = self\n        } catch let error {\n            throw CompilerError(\"Failed to start watchman: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    private func unsubscribe(path: String, id: String) {\n        let logger = self.logger\n        _ = self.connection.send(data: try! \"[\\\"unsubscribe\\\", \\\"\\(path)\\\", \\\"\\(id)\\\"]\".utf8Data())\n            .catch { (error) -> Void in\n                logger.error(\"Failed to unsubscribe path '\\(path)': \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    private func watchProject(path: String) -> Promise<WatchmanWatchProjectResponse> {\n        logger.debug(\"Watchman watching project at path: \\(path)\")\n        let json = try! \"[\\\"watch-project\\\", \\\"\\(path)\\\"]\".utf8Data()\n        return self.connection.send(data: json).then { data -> WatchmanWatchProjectResponse in\n            return try WatchmanWatchProjectResponse.fromJSON(data)\n        }\n    }\n\n    func subscribe(projectPath: String, path: String, onChange: @escaping ([WatchmanFileNotification]) -> Void) -> Cancelable {\n        return subscribe(projectPath: projectPath, paths: [path], onChange: onChange)\n    }\n\n    func subscribe(projectPath: String, paths: [String], onChange: @escaping ([WatchmanFileNotification]) -> Void) -> Cancelable {\n        let id = UUID().uuidString\n\n        lock.lock {\n            observerById[id] = WatchmanObserver(callback: onChange, rootURL: nil)\n        }\n\n        let cancelObservering = CallbackCancelable {\n            self.lock.lock {\n                self.observerById.removeValue(forKey: id)\n            }\n        }\n\n        _ = self.watchProject(path: projectPath).then { response -> Promise<Data> in\n            do {\n                self.lock.lock {\n                    self.observerById[id]?.rootURL = URL(fileURLWithPath: response.watch)\n                }\n\n                let dirnameExpressions: [String]\n\n                // response.relativePath returns path relative to the watchRoot\n                // null if relativePath is the same as watchRoot\n                if let relativePath = response.relativePath {\n                    dirnameExpressions = paths.map{watchPath in\n                        let concatPath = \"\\(relativePath)/\\(watchPath)\"\n                        let normalizedPath = (concatPath as NSString).standardizingPath\n\n                        return normalizedPath\n                    }\n                } else {\n                    dirnameExpressions = paths\n                }\n\n                let dirNameString = dirnameExpressions.map { #\"[\"dirname\", \"\\#($0)\"]\"# }.joined(separator: \", \")\n                let expressionJson = #\"{\"expression\": [\"anyof\", \\#(dirNameString)]}\"#\n\n                let command = \"[\\\"subscribe\\\", \\\"\\(response.watch)\\\", \\\"\\(id)\\\", \\(expressionJson)]\"\n\n                self.logger.debug(\"Watchman subscribe: \\(command)\")\n\n                return self.connection.send(data: try command.utf8Data())\n            } catch let error {\n                return Promise(error: error)\n            }\n        }.catch { error -> Void in\n            self.logger.error(\"Failed to observe path '\\(projectPath)': \\(error.legibleLocalizedDescription)\")\n            cancelObservering.cancel()\n        }\n\n        return CallbackCancelable {\n            cancelObservering.cancel()\n            self.unsubscribe(path: projectPath, id: id)\n        }\n    }\n\n    func watchmanConnection(_ watchmanConnection: WatchmanConnection, didReceiveUnilateralPacket packet: Data) {\n        do {\n            guard packet.range(of: subscriptionToken) != nil else {\n                logger.error(\"Received unrecognized unilateral Watchman packet of size \\(packet.count)\")\n                return\n            }\n            let response = try WatchmanSubscribeEvent.fromJSON(packet)\n\n            let wrappedObserver = lock.lock {\n                observerById[response.subscription]\n            }\n\n            guard let observer = wrappedObserver, let rootURL = observer.rootURL else {\n                logger.error(\"Resolved Watchman Universal Packet on an unresolved observer\")\n                return\n            }\n\n            let notifications: [WatchmanFileNotification] = response.files.map {\n                let kind: WatchmanFileNotification.Kind\n                if !$0.exists {\n                    kind = .removed\n                } else if $0.new {\n                    kind = .created\n                } else {\n                    kind = .changed\n                }\n                return WatchmanFileNotification(url: rootURL.resolving(path: $0.name), kind: kind)\n            }\n\n            observer.callback(notifications)\n        } catch let error {\n            logger.error(\"Unable to parse Watchman subscribe event: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/Watchman/WatchmanConnection.swift",
    "content": "//\n//  WatchmanConnection.swift\n//  BlueSocket\n//\n//  Created by Simon Corsin on 6/5/19.\n//\n\nimport Foundation\nimport BlueSocket\n\nstruct WatchmanProtocol: TCPConnectionDataProcessor {\n\n    func process(data: Data) -> TCPConnectionProcessDataResult {\n        guard let newLineIndex = data.fastFirstIndex(of: 10) else {\n            return .notEnoughData(lengthNeeded: 1)\n        }\n        return .valid(dataLength: newLineIndex + 1)\n    }\n}\n\nprotocol WatchmanConnectionDelegate: AnyObject {\n    func watchmanConnection(_ watchmanConnection: WatchmanConnection, didReceiveUnilateralPacket packet: Data)\n}\n\nclass WatchmanConnection: TCPConnectionDelegate {\n\n    weak var delegate: WatchmanConnectionDelegate?\n\n    private static let unilateralToken = try! \"\\\"unilateral\\\":true\".utf8Data()\n    private static let errorToken = try! \"\\\"error\\\":\".utf8Data()\n\n    private let logger: ILogger\n    private let socket: Socket\n    private let queue = DispatchQueue(label: \"com.snap.valdi.WatchmanClient\")\n    private let tcpConnection: TCPConnection\n    private var sequence = 0\n    private var packetObservers = [Promise<Data>]()\n\n    init(logger: ILogger, sockname: String) throws {\n        self.logger = logger\n        guard let signature = try Socket.Signature(socketType: .stream, proto: .unix, path: sockname) else {\n            throw CompilerError(\"Could not create signature from socket at \\(sockname)\")\n        }\n        self.socket = try Socket.create(connectedUsing: signature)\n\n        self.tcpConnection = BlueSocketTCPConnection(logger: logger, socket: socket, queueNamePrefix: \"com.snap.valdi.WatchmanClient\")\n        self.tcpConnection.dataProcessor = WatchmanProtocol()\n        self.tcpConnection.delegate = self\n\n        self.tcpConnection.startListening()\n    }\n\n    func send(data: Data) -> Promise<Data> {\n        let promise = Promise<Data>()\n        queue.async {\n            self.packetObservers.append(promise)\n            var outData = data\n            outData.append(10)\n            self.tcpConnection.send(data: outData)\n        }\n\n        return promise\n    }\n\n    func connection(_ connection: TCPConnection, didReceiveData data: Data) {\n        queue.async {\n            let packet = data[..<(data.count - 1)]\n            if packet.range(of: WatchmanConnection.unilateralToken) != nil {\n                self.delegate?.watchmanConnection(self, didReceiveUnilateralPacket: packet)\n            } else {\n                if self.packetObservers.isEmpty {\n                    self.logger.error(\"Received unhandled packet of size \\(data.count)\")\n                    return\n                }\n                let promise = self.packetObservers.removeFirst()\n\n                if packet.range(of: WatchmanConnection.errorToken) != nil {\n                    let errorMessage: String\n                    do {\n                        let errorPacket = try WatchmanErrorResponse.fromJSON(packet)\n                        errorMessage = errorPacket.error\n                    } catch let error {\n                        errorMessage = \"Failed to deserialize error \\(error.legibleLocalizedDescription)\"\n                    }\n                    promise.reject(error: CompilerError(errorMessage))\n                } else {\n                    promise.resolve(data: packet)\n                }\n            }\n        }\n    }\n\n    func connection(_ connection: TCPConnection, didDisconnectWithError error: Error?) {\n\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Reloader/Watchman/WatchmanResponse.swift",
    "content": "//\n//  WatchmanResponse.swift\n//  BlueSocket\n//\n//  Created by Simon Corsin on 6/5/19.\n//\n\nimport Foundation\n\nextension Decodable {\n    static func fromJSON(_ jsonData: Data, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .convertFromSnakeCase) throws -> Self {\n        let decoder = JSONDecoder()\n        decoder.keyDecodingStrategy = keyDecodingStrategy\n        return try decoder.decode(self, from: jsonData)\n    }\n}\n\nextension Encodable {\n    func toJSON(outputFormatting: JSONEncoder.OutputFormatting = [], keyEncodingStrategy: JSONEncoder.KeyEncodingStrategy = .convertToSnakeCase) throws -> Data {\n        let encoder = JSONEncoder()\n        encoder.outputFormatting = outputFormatting\n        encoder.keyEncodingStrategy = keyEncodingStrategy\n        return try encoder.encode(self)\n    }\n}\n\nstruct WatchmanGetSocknameResponse: Codable {\n    let version: String\n    let sockname: String\n}\n\nstruct WatchmanErrorResponse: Codable {\n    let version: String\n    let error: String\n}\n\nstruct WatchmanSubscribeEventFile: Codable {\n    let exists: Bool\n    let new: Bool\n    let name: String\n}\n\nstruct WatchmanSubscribeEvent: Codable {\n    let root: String\n    let files: [WatchmanSubscribeEventFile]\n    let subscription: String\n}\n\nstruct WatchmanWatchProjectResponse: Decodable {\n    let watcher: String\n    let watch: String\n    let relativePath: String?\n    let version: String\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Sass/LibSassCompiler.swift",
    "content": "import Foundation\nimport Clibsass\n\npublic struct SassResult {\n    let output: String\n    let includedFilePaths: [String]\n}\n\npublic final class LibSassCompiler {\n    // Right now this is a dumb simple API so no initialization, just a single compile input -> output function\n    private init() { }\n\n    public static func compile(inputString: String, includePath: String) throws -> SassResult {\n        typealias DataContext = OpaquePointer\n\n        var inputCString = inputString.utf8CString\n\n        return try inputCString.withUnsafeMutableBytes { input -> SassResult in\n            let strlen = input.count\n            let inputCopy = malloc(strlen)!\n            memcpy(inputCopy, input.baseAddress!.bindMemory(to: Int8.self, capacity: strlen), strlen)\n            let context: DataContext = sass_make_data_context(inputCopy.bindMemory(to: Int8.self, capacity: strlen))\n            defer { sass_delete_data_context(context) }\n\n            let options = sass_data_context_get_options(context)\n            // TODO: set desired options\n            sass_option_set_precision(options, 5)\n            sass_option_set_source_comments(options, false)\n            sass_option_set_output_style(options, SASS_STYLE_COMPACT)\n            sass_option_set_include_path(options, includePath)\n            sass_data_context_set_options(context, options)\n\n            let compiler = sass_make_data_compiler(context)\n            defer { sass_delete_compiler(compiler) }\n            sass_compiler_parse(compiler)\n            sass_compiler_execute(compiler)\n\n            let errorStatus = sass_context_get_error_status(context)\n            guard errorStatus == 0 else {\n                let errorFile = sass_context_get_error_file(context).map(String.init(cString:))\n                // The error might've occurred in an _included_ file, instead of the original document\n                let errorFileURL = errorFile?.nonEmpty.flatMap(URL.init(fileURLWithPath:))\n                let failedDependenciesURLs: Set<URL> = errorFileURL.map { [$0] } ?? []\n\n                // LibSass 3.6.2 has a heap-use-after-free bug that causes sass_context_get_error_src to sometimes\n                // return an invalid pointer see: https://github.com/sass/libsass/issues/3019\n                // FIXME: Reenable this code path after LibSass 3.6.3 is released\n                #if LIB_SASS_ERROR_SRC_SAFE_TO_USE\n                let message = sass_context_get_error_text(context).map(String.init(cString:)) ?? \"<invalid error message>\"\n                let errorSource = sass_context_get_error_src(context).map(String.init(cString:)) ?? \"<invalid source>\"\n\n                let errorLine = sass_context_get_error_line(context)\n                let errorColumn = sass_context_get_error_column(context)\n\n                let errorFileRelativePath = errorFileURL?.map { $0.relativePath(from: URL(fileURLWithPath: includePath)) }\n                let inFileSuffix = errorFileRelativePath.map { \" in \\($0)\" } ?? \"\"\n\n                throw CompilerError(type: \"Sass error\" + inFileSuffix,\n                                         message: message,\n                                         atZeroIndexedLine: errorLine - 1,\n                                         column: errorColumn,\n                                         inDocument: sourceWithError,\n                                         failedDependenciesURLs: failedDependenciesURLs)\n                #else\n                let message = sass_context_get_error_message(context).map(String.init(cString:)) ?? \"<invalid error message>\"\n                throw CompilerError(\"Sass error: \\(message)\", failedDependenciesURLs: failedDependenciesURLs)\n                #endif\n            }\n\n            let output = sass_context_get_output_string(context)\n            let outputString = output.map(String.init(cString:)) ?? \"\"\n\n            var includedFilePaths = [String]()\n\n            if var includedFiles = sass_context_get_included_files(context) {\n                var index = 0\n                while index < sass_context_get_included_files_size(context) {\n                    if let filePath = includedFiles.pointee {\n                        includedFilePaths.append(String(cString: filePath))\n                    }\n                    index += 1\n                    includedFiles = includedFiles.advanced(by: 1)\n                }\n            }\n\n            return SassResult(output: outputString, includedFilePaths: includedFilePaths)\n        }\n    }\n\n    public struct Error: LocalizedError {\n        public let code: Code\n        public let message: String\n\n        public init(code: Int32, message: String) {\n            self.code = Error.Code(rawValue: code) ?? .unknown\n            self.message = message\n        }\n\n        public enum Code: Int32 {\n            case normal = 1\n            case memoryError\n            case untranslatedException\n            case legacyStringException\n            case unknown\n        }\n\n        public var errorDescription: String? {\n            return \"libsass error code \\(code.rawValue): \\(message)\"\n        }\n\n        public var failureReason: String? {\n            return message\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Sass/SassCompiler.swift",
    "content": "//\n//  Sass.swift\n//  Compiler\n//\n//  Created by Brandon Francis on 8/20/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n/**\n Compiles sass into css.\n https://sass-lang.com/\n */\nclass SassCompiler {\n\n    public func compile(file: File, importBaseDirectoryURL: URL) throws -> SassResult {\n        let input = try file.readString()\n        if input.isEmpty {\n            return SassResult(output: \"\", includedFilePaths: [])\n        }\n\n        return try LibSassCompiler.compile(inputString: input, includePath: importBaseDirectoryURL.path)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/StaticRes/StaticResGenerator.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nclass StaticResGenerator {\n\n    static func generate(baseUrl: URL, inputFiles: [String], to path: String) throws {\n        let url = baseUrl.resolving(path: path)\n\n        if FileManager.default.fileExists(atPath: url.path) {\n            try? FileManager.default.removeItem(atPath: url.path)\n        }\n\n        let writer = CppFileGenerator(namespace: CPPNamespace(components: [\"snap\", \"valdi\", \"static_resources\"]), isHeader: false)\n\n        writer.includeSection.addInclude(path: \"valdi_core/cpp/Resources/StaticResourceRegistry.hpp\")\n\n        let staticArraysSection = CppCodeWriter()\n\n        writer.body.appendBody(staticArraysSection)\n\n        writer.body.appendBody(\"__attribute__((constructor)) static void register_static_valdi_resources() {\\n\")\n\n        let registerSection = CppCodeWriter()\n        writer.body.appendBody(registerSection)\n\n        writer.body.appendBody(\"}\")\n\n        let propertyNameAllocator = PropertyNameAllocator()\n\n        for inputFile in inputFiles {\n            let fileURL = baseUrl.resolving(path: inputFile)\n\n            let fileData = try File.url(fileURL).readData()\n\n            let filePath = fileURL.lastPathComponent\n\n            let resolvedFileData: Data\n            let requiresDecompression: Bool\n\n            if filePath.hasSuffix(\".\\(FileExtensions.json)\") {\n                // Automatically compress json files\n                resolvedFileData = try ZstdCompressor.compress(data: fileData)\n                requiresDecompression = true\n            } else {\n                resolvedFileData = fileData\n                requiresDecompression = false\n            }\n\n            let fileContentStr = resolvedFileData.lazy.map { String(format: \"0x%02x\", $0) }.joined(separator: \", \")\n\n            let variableName = propertyNameAllocator.allocate(property: filePath.snakeCased).name\n\n            staticArraysSection.appendBody(\"static uint8_t \\(variableName)[] = {\\n\\(fileContentStr)\\n};\\n\\n\")\n            registerSection.appendBody(\"VALDI_REGISTER_STATIC_RESOURCE(\\\"\\(filePath)\\\", &\\(variableName)[0], \\(resolvedFileData.count), \\(requiresDecompression ? \"true\" : \"false\"));\\n\")\n        }\n\n        let data = try writer.content.indented.utf8Data()\n\n        try data.write(to: url, options: .atomic)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/CompilationMetadata.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nstruct CompilationMetadata: Codable {\n\n    let classMappings: [String: ValdiClass]\n    let nativeTypes: SerializedTypeScriptNativeTypeResolver\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/KotlinViewClassGenerator.swift",
    "content": "//\n//  KotlinViewClassGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass KotlinViewClassGenerator: LanguageSpecificViewClassGenerator {\n    static let platform: Platform = .android\n\n    private let bundleInfo: CompilationItem.BundleInfo\n\n    private let className: JVMClass\n    private let componentPath: String\n\n    private let sourceFilename: GeneratedSourceFilename\n\n    private let viewModelClassName: String?\n    private let componentContextClassName: String?\n\n    private let writer: KotlinCodeGenerator\n\n    private let staticMethods = KotlinCodeGenerator()\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         className: String,\n         componentPath: String,\n         sourceFilename: GeneratedSourceFilename,\n         viewModelClassName: String?,\n         componentContextClassName: String?) {\n        self.bundleInfo = bundleInfo\n        self.className = JVMClass(fullClassName: className)\n        self.componentPath = componentPath\n        self.sourceFilename = sourceFilename\n        self.viewModelClassName = viewModelClassName\n        self.componentContextClassName = componentContextClassName\n        self.writer = KotlinCodeGenerator(package: self.className.package)\n    }\n\n    func start() throws {\n        writer.appendHeader(\"\")\n\n        try [\n            \"com.snap.valdi.IValdiRuntime\",\n            \"com.snap.valdi.context.ValdiViewOwner\",\n            \"com.snap.valdi.views.ValdiGeneratedRootView\"\n            ].forEach { try self.writer.importClass($0) }\n\n        writer.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFilename))\n\n        let viewModelType = try getViewModelType()\n        let componentContextType = try getComponentContextType()\n\n        writer.appendBody(\"\\nclass \\(className.name)(context: android.content.Context): ValdiGeneratedRootView<\\(viewModelType), \\(componentContextType)>(context) {\\n\\n\")\n\n        staticMethods.appendBody(\"companion object {\\n\")\n    }\n\n    func finish() {\n        staticMethods.appendBody(\"}\\n\")\n\n        writer.appendBody(staticMethods)\n\n        writer.appendBody(\"}\\n\")\n    }\n\n    func write() throws -> [NativeSource] {\n        let data = try writer.content.indented(indentPattern: \"    \").utf8Data()\n        return [KotlinCodeGenerator.makeNativeSource(bundleInfo: bundleInfo, jvmClass: className, file: .data(data))]\n    }\n\n    func appendAccessor(className: String, nodeId: String) throws {\n        let jvmClass = try writer.importClass(className)\n\n        let staticPropertyName = \"\\(nodeId.camelCased)Id\"\n\n        staticMethods.appendBody(\"val \\(staticPropertyName) = \\\"\\(nodeId)\\\"\\n\")\n\n        writer.appendBody(\"val \\(nodeId.camelCased): \\(jvmClass.name)?\\n\")\n        writer.appendBody(\"get() = valdiContext?.getView(\\(staticPropertyName)) as? \\(jvmClass.name)\\n\")\n        writer.appendBody(\"\\n\\n\")\n    }\n\n    private func getViewModelType() throws -> String {\n        guard let viewModelClassName = viewModelClassName else {\n            return \"Any?\"\n        }\n        return try writer.importClass(viewModelClassName).name\n    }\n\n    private func getComponentContextType() throws -> String {\n        guard let componentContextClassName = componentContextClassName else {\n            return \"Any\"\n        }\n        return try writer.importClass(componentContextClassName).name\n    }\n\n    func appendConstructor() throws {\n        let viewModelType = try getViewModelType()\n        let componentContextType = try getComponentContextType()\n\n        let inflationCompletion = try writer.importClass(\"com.snap.valdi.InflationCompletion\")\n\n        staticMethods.appendBody(\"val componentPath = \\\"\\(componentPath)\\\"\\n\")\n        staticMethods.appendBody(\"\\n\")\n\n        staticMethods.appendBody(\"@JvmStatic fun create(runtime: IValdiRuntime, owner: ValdiViewOwner? = null): \\(className.name) = create(runtime, null, null, owner)\\n\\n\")\n        staticMethods.appendBody(\"\"\"\n        @JvmStatic fun create(runtime: IValdiRuntime, viewModel: \\(viewModelType)?, componentContext: \\(componentContextType)?, owner: ValdiViewOwner? = null, inflationCompletion: \\(inflationCompletion.name)? = null): \\(className.name) {\n            val view = \\(className.name)(runtime.context)\n            runtime.inflateViewAsync(view, componentPath, viewModel, componentContext, owner, inflationCompletion)\n            return view\n        }\n        \\n\n        \"\"\")\n    }\n\n    func appendNativeActions(nativeFunctionNames: [String]) {\n        guard !nativeFunctionNames.isEmpty else {\n            return\n        }\n\n        let keepName = try! writer.importClass(\"androidx.annotation.Keep\").name\n        writer.appendBody(\"@\\(keepName)\\n\")\n        writer.appendBody(\"interface ActionHandler {\\n\")\n        for functionName in nativeFunctionNames {\n            writer.appendBody(\"fun \\(functionName)(parameters: Array<Any?>)\\n\")\n        }\n        writer.appendBody(\"}\\n\\n\")\n\n        writer.appendBody(\"\"\"\n        var actionHandler: ActionHandler?\n            get() = valdiContext?.actionHandler as? ActionHandler\n            set(value) { setActionHandlerUntyped(value) }\n        \\n\n        \"\"\")\n    }\n\n    func appendEmitActions(actions: [String]) {\n        for action in actions {\n            let functionName = String(action.split(separator: \"_\").last!).pascalCased\n\n            writer.appendBody(\"\"\"\n                fun emit\\(functionName)(parameters: Array<Any?> = arrayOf()) {\n                    getValdiContext {\n                        it.performJsAction(\\\"\\(action)\\\", parameters)\n                    }\n                }\n                \\n\n            \"\"\")\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/LanguageSpecificViewClassGenerator.swift",
    "content": "//\n//  LanguageSpecificViewClassGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprotocol LanguageSpecificViewClassGenerator {\n    static var platform: Platform { get }\n\n    func start() throws\n    func finish()\n    func write() throws -> [NativeSource]\n\n    func appendAccessor(className: String, nodeId: String) throws\n    func appendConstructor() throws\n//    func appendViewModelAccessor(viewModelClassName: String) throws\n    func appendNativeActions(nativeFunctionNames: [String])\n    func appendEmitActions(actions: [String])\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/ObjCViewClassGenerator.swift",
    "content": "//\n//  ObjCViewClassGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass ObjCViewClassGenerator: LanguageSpecificViewClassGenerator {\n    static let platform: Platform = .ios\n\n    let className: String\n    let componentPath: String\n\n    private let iosType: IOSType\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let header = CodeWriter()\n    private let impl = CodeWriter()\n    private let viewModelClass: IOSType?\n    private let componentContextClass: IOSType?\n    private let sourceFilename: GeneratedSourceFilename\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         iosType: IOSType,\n         componentPath: String,\n         sourceFilename: GeneratedSourceFilename,\n         viewModelClass: IOSType?,\n         componentContextClass: IOSType?) {\n        self.bundleInfo = bundleInfo\n        self.iosType = iosType\n        self.className = iosType.name\n        self.componentPath = componentPath\n        self.sourceFilename = sourceFilename\n        self.viewModelClass = viewModelClass\n        self.componentContextClass = componentContextClass\n    }\n\n    func start() throws {\n        // TODO(3521): update to valdi_core\n        header.appendHeader(\"#import <UIKit/UIKit.h>\\n\")\n        header.appendHeader(\"#import <valdi_core/SCValdiRootView.h>\\n\")\n        let superclassName = \"SCValdiRootView\"\n\n        impl.appendHeader(\"#import \\(iosType.importHeaderStatement(kind: .withUtilities))\\n\")\n        impl.appendHeader(\"#import <valdi_core/SCValdiRuntimeProtocol.h>\\n\")\n\n        header.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFilename))\n        header.appendBody(\"\\n\")\n        header.appendBody(\"@interface \\(className): \\(superclassName)\\n\\n\")\n        impl.appendBody(\"@implementation \\(className)\\n\\n\")\n\n        impl.appendBody(\"\"\"\n            + (NSString *)componentPath\n            {\n            return @\"\\(componentPath)\";\n            }\n            \\n\n            \"\"\")\n    }\n\n    func finish() {\n        header.appendBody(\"\\n@end\\n\")\n        impl.appendBody(\"@end\\n\")\n\n        impl.appendHeader(\"#import <valdi_core/SCValdiContextProtocol.h>\\n\")\n    }\n\n    func appendAccessor(className: String, nodeId: String) {\n        header.appendBody(\"@property (readonly, nonatomic) \\(className) * _Nullable \\(nodeId.camelCased);\\n\")\n        // TODO(3521): Update to SCValdiView\n        if !className.hasPrefix(\"UI\") && className != \"SCValdiView\" {\n            header.appendHeader(\"@class \\(className);\\n\")\n        }\n\n        impl.appendBody(\"\"\"\n            - (\\(className) *)\\(nodeId.camelCased)\n            {\n            return (\\(className) *)[self.valdiContext viewForNodeId:@\"\\(nodeId)\"];\n            }\n            \\n\n            \"\"\")\n    }\n\n    func appendConstructor() throws {\n        var viewModelType = \"NSDictionary<NSString *, id> *\"\n        if let viewModelClass = viewModelClass {\n            header.appendHeader(\"#import \\(viewModelClass.importHeaderStatement(kind: .withUtilities))\\n\")\n            viewModelType = viewModelClass.typeDeclaration\n        }\n\n        var contextType = \"NSDictionary<NSString *, id> *\"\n        if let contextClass = componentContextClass {\n            header.appendHeader(\"#import \\(contextClass.importHeaderStatement(kind: .withUtilities))\\n\")\n            contextType = contextClass.typeDeclaration\n        }\n\n        header.appendBody(\"- (instancetype _Nonnull)initWithViewModel:(\\(viewModelType) _Nullable)viewModel componentContext:(\\(contextType) _Nullable)componentContext runtime:(id<SCValdiRuntimeProtocol> _Nonnull)runtime;\\n\\n\")\n        header.appendBody(\"@property (strong, nonatomic) \\(viewModelType) _Nullable viewModel;\\n\")\n\n        impl.appendBody(\"\"\"\n            - (instancetype)initWithViewModel:(\\(viewModelType))viewModel componentContext:(\\(contextType))componentContext runtime:(id<SCValdiRuntimeProtocol>)runtime\n            {\n                return [super initWithViewModelUntyped:viewModel componentContextUntyped:componentContext runtime:runtime];\n            }\n            \\n\n            \"\"\")\n\n        impl.appendBody(\"\"\"\n            - (void)setViewModel:(\\(viewModelType))viewModel\n            {\n                self.valdiContext.viewModel = viewModel;\n            }\n\n            - (\\(viewModelType))viewModel\n            {\n                return self.valdiContext.viewModel;\n            }\n            \\n\n            \"\"\")\n    }\n\n    func appendNativeActions(nativeFunctionNames: [String]) {\n        guard !nativeFunctionNames.isEmpty else {\n            return\n        }\n\n        let protocolName = className + \"ActionHandler\"\n\n        let methods: [String] = nativeFunctionNames.map {\n            \"-(void)\\($0):(NSArray<id> * _Nonnull)parameters;\"\n        }\n\n        let protocolDecl = \"\"\"\n        @protocol \\(protocolName)\n\n        \\(methods.joined(separator: \"\\n\"))\n\n        @end\n        \\n\n        \"\"\"\n\n        header.prependBody(protocolDecl)\n        header.appendBody(\"\\n@property (weak, nonatomic) id<\\(protocolName)> _Nullable actionHandler;\\n\\n\")\n\n        impl.appendBody(\"\"\"\n            -(void)setActionHandler:(id<\\(protocolName)>)actionHandler\n            {\n            self.valdiContext.actionHandler = actionHandler;\n            }\n            \\n\n            \"\"\")\n        impl.appendBody(\"\"\"\n            - (id<\\(protocolName)>)actionHandler\n            {\n            return self.valdiContext.actionHandler;\n            }\n            \\n\n            \"\"\")\n    }\n\n    func appendEmitActions(actions: [String]) {\n        guard !actions.isEmpty else {\n            return\n        }\n\n        header.appendHeader(\"#import <valdi_core/SCValdiActions.h>\\n\")\n\n        for action in actions {\n            let functionName = String(action.split(separator: \"_\").last!).pascalCased\n\n            header.appendBody(\"-(void)emit\\(functionName):(nonnull NSArray<id> *)parameters;\\n\")\n            impl.appendBody(\"\"\"\n                -(void)emit\\(functionName):(NSArray<id> *)parameters\n                {\n                [self.valdiContext performJsAction:@\"\\(action)\" parameters:parameters];\n                }\n                \\n\n                \"\"\")\n        }\n\n        // Append empty line\n        header.appendBody(\"\\n\")\n    }\n\n    func write() throws -> [NativeSource] {\n        let headerData = try header.content.indented(indentPattern: \"    \").utf8Data()\n        let implData = try impl.content.indented(indentPattern: \"    \").utf8Data()\n\n        return [NativeSource(relativePath: nil,\n                             filename: \"\\(className).h\",\n                             file: .data(headerData),\n                             groupingIdentifier: \"\\(bundleInfo.iosModuleName).h\",\n                             groupingPriority: IOSType.viewTypeGroupingPriority\n                            ),\n                NativeSource(relativePath: nil,\n                             filename: \"\\(className).m\",\n                             file: .data(implData),\n                             groupingIdentifier: \"\\(bundleInfo.iosModuleName).m\",\n                             groupingPriority: IOSType.viewTypeGroupingPriority\n                            )]\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/ProjectClassMapping.swift",
    "content": "//\n//  ProjectClassMapping.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 8/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ValdiClass: Equatable, Codable {\n    var androidClassName: String?\n    var iosType: IOSType?\n    var webViewClassName: String?\n    var macosViewClassName: String?\n    let jsxName: String?\n    var valdiViewPath: ComponentPath?\n    var isLayout: Bool\n    var isSlot: Bool\n    let sourceFilePath: String\n    let sourceModuleName: String\n}\n\nfunc==(lhs: ValdiClass, rhs: ValdiClass) -> Bool {\n    return lhs.androidClassName == rhs.androidClassName && lhs.iosType?.name == rhs.iosType?.name && lhs.iosType?.importPrefix == rhs.iosType?.importPrefix && lhs.webViewClassName == rhs.webViewClassName && lhs.macosViewClassName == rhs.macosViewClassName && lhs.valdiViewPath == rhs.valdiViewPath && lhs.sourceModuleName == rhs.sourceModuleName\n}\n\nclass ValdiClassResolveError: CompilerError {\n\n    init(nodeType: String, error: String) {\n        super.init(\"Could not resolve Valdi class '\\(nodeType)': \\(error)\")\n    }\n}\n\nstruct RegisteredValdiClass {\n    var valdiClass: ValdiClass\n    var allowOverride: Bool\n}\n\nstruct ProjectClassMapping {\n\n    private var classByFullyQualifiedName = [String: RegisteredValdiClass]()\n\n    private let allowMappingOverride: Bool\n\n    init(allowMappingOverride: Bool) {\n        self.allowMappingOverride = allowMappingOverride\n    }\n\n    mutating func register(bundle: CompilationItem.BundleInfo, nodeType: String, valdiViewPath: ComponentPath?, iosType: IOSType?, androidClassName: String?, webViewClassName: String? = nil, macosViewClassName: String? = nil, jsxName: String?, isLayout: Bool, sourceFilePath: String) throws {\n        try register(bundle: bundle, nodeType: nodeType, valdiViewPath: valdiViewPath, iosType: iosType, androidClassName: androidClassName, webViewClassName: webViewClassName, macosViewClassName: macosViewClassName, jsxName: jsxName, isLayout: isLayout, isSlot: false, sourceFilePath: sourceFilePath)\n    }\n\n    mutating func register(bundle: CompilationItem.BundleInfo, nodeType: String, valdiViewPath: ComponentPath?, iosType: IOSType?, androidClassName: String?, webViewClassName: String? = nil, macosViewClassName: String? = nil, jsxName: String?, isLayout: Bool, isSlot: Bool, sourceFilePath: String) throws {\n        let classDescription = ValdiClass(androidClassName: androidClassName, iosType: iosType, webViewClassName: webViewClassName, macosViewClassName: macosViewClassName, jsxName: jsxName, valdiViewPath: valdiViewPath, isLayout: isLayout, isSlot: isSlot, sourceFilePath: sourceFilePath, sourceModuleName: bundle.name)\n\n        let className =  \"\\(bundle.name).\\(nodeType)\"\n\n        if !allowMappingOverride {\n            if let existingMapping = classByFullyQualifiedName[className], !existingMapping.allowOverride {\n                throw CompilerError(\"Root node class conflict for \\(className), was previously registered by \\(existingMapping.valdiClass.sourceFilePath), attempting to register by \\(sourceFilePath)\")\n            }\n        }\n\n        classByFullyQualifiedName[className] = RegisteredValdiClass(valdiClass: classDescription, allowOverride: false)\n    }\n\n    mutating func registerResolved(fullyQualifiedName: String, klass: ValdiClass) {\n        classByFullyQualifiedName[fullyQualifiedName] = RegisteredValdiClass(valdiClass: klass, allowOverride: true)\n    }\n\n    func resolveClass(nodeType: String, currentBundle: CompilationItem.BundleInfo, localMapping: ValdiClassMapping?) throws -> ValdiClass {\n        // First local at local mapping (declared inside the .vue file)\n        if let resolvedLocalMapping = localMapping?.nodeMappingByClass[nodeType] {\n            return ValdiClass(androidClassName: resolvedLocalMapping.androidClassName, iosType: resolvedLocalMapping.iosType, webViewClassName: nil, macosViewClassName: nil, jsxName: nil, valdiViewPath: nil, isLayout: false, isSlot: false, sourceFilePath: \"\", sourceModuleName: currentBundle.name)\n        }\n\n        let components = nodeType.split(separator: \".\")\n        guard components.count <= 2 else {\n            throw CompilerError(\"Invalid nodeType '\\(nodeType)', can only have one dot to specify the bundle\")\n        }\n\n        if components.count == 2 {\n            // Absolute import\n            guard let valdiClass = classByFullyQualifiedName[nodeType]?.valdiClass else {\n                throw ValdiClassResolveError(nodeType: nodeType, error: \"The class was not found in the class path\")\n            }\n            let currentModuleDeps = currentBundle.dependencies.map { $0.name }\n            if !currentModuleDeps.contains(valdiClass.sourceModuleName) {\n                throw ValdiClassResolveError(nodeType: nodeType, error: \"The class was found but the module \\(currentBundle.name) does not have a dependency on \\(valdiClass.sourceModuleName)\")\n            }\n\n            return valdiClass\n        } else {\n            // Implicit import\n\n            // First look inside the current module\n            if let valdiClass = classByFullyQualifiedName[\"\\(currentBundle.name).\\(nodeType)\"]?.valdiClass {\n                return valdiClass\n            }\n\n            // Then look if it exists in another module\n            let modulesToSearch = currentBundle.dependencies\n            let foundClasses = modulesToSearch.map { \"\\($0.name).\\(nodeType)\" }.compactMap { classByFullyQualifiedName[$0]?.valdiClass }\n            if foundClasses.isEmpty {\n                let modulesList = modulesToSearch.map { $0.name }.joined(separator: \", \")\n                throw ValdiClassResolveError(nodeType: nodeType, error: \"The class was not found in the modules \\(modulesList)\")\n            }\n            if foundClasses.count > 1 {\n                let modulesList = foundClasses.map { $0.sourceModuleName }.joined(separator: \", \")\n                throw ValdiClassResolveError(nodeType: nodeType, error: \"\"\"\n                    The class was found in \\(foundClasses.count) modules: \\(modulesList).\n                    You can fix this issue by explicitly specifying which class to use using\n                    <\\(foundClasses[0].sourceModuleName).\\(nodeType)/> in your vue XML for instance, or by removing a dependency in your module.yaml.\n                    \"\"\")\n            }\n            return foundClasses[0]\n        }\n    }\n\n    func copyMappings() -> [String: ValdiClass] {\n        var out: [String: ValdiClass] = [:]\n        for (key, registeredClass) in classByFullyQualifiedName {\n            out[key] = registeredClass.valdiClass\n        }\n        return out\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/ResolvedClassMapping.swift",
    "content": "//\n//  CurrentClassMapping.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 8/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// TODO: rename, something like CapturedClassMapping or CompoundClassMapping\nstruct ResolvedClassMapping {\n\n    let localClassMapping: ValdiClassMapping?\n    let projectClassMapping: ProjectClassMapping\n    let currentBundle: CompilationItem.BundleInfo\n\n    func resolve(nodeType: String) throws -> ValdiClass {\n        return try projectClassMapping.resolveClass(nodeType: nodeType,\n                                                    currentBundle: currentBundle,\n                                                    localMapping: localClassMapping)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/SwiftViewClassGenerator.swift",
    "content": "//\n//  KotlinViewClassGenerator.swift\n//  Compiler\n//\n//  Copyright © 2024 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass SwiftViewClassGenerator: LanguageSpecificViewClassGenerator {\n    static let platform: Platform = .ios\n\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let iosType: IOSType\n    private let componentPath: String\n\n    private let sourceFilename: GeneratedSourceFilename\n\n    private let viewModelClass: IOSType?\n    private let componentContextClass: IOSType?\n\n    private let writer: SwiftSourceFileGenerator\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         iosType: IOSType,\n         componentPath: String,\n         sourceFilename: GeneratedSourceFilename,\n         viewModelClass: IOSType?,\n         componentContextClass: IOSType?) {\n        self.bundleInfo = bundleInfo\n        self.iosType = iosType\n        self.componentPath = componentPath\n        self.sourceFilename = sourceFilename\n        self.viewModelClass = viewModelClass\n        self.componentContextClass = componentContextClass\n        self.writer = SwiftSourceFileGenerator(className: iosType.swiftName)\n    }\n\n    func start() throws {\n        // TODO(3521): update to valdi_core\n        self.writer.addImport(path: \"valdi_core\")\n        self.writer.addImport(path: \"ValdiCoreSwift\")\n        writer.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFilename))\n        writer.appendBody(\"\\npublic class \\(iosType.swiftName): SwiftComponentBase {\\n\\n\")\n    }\n\n    func finish() {\n        writer.appendBody(\"}\\n\")\n    }\n\n    func write() throws -> [NativeSource] {\n        let data = try writer.content.indented(indentPattern: \"    \").utf8Data()\n        return [NativeSource(relativePath: nil,\n                             filename: \"\\(iosType.swiftName).\\(FileExtensions.swift)\",\n                             file: .data(data),\n                             groupingIdentifier: \"\\(bundleInfo.iosModuleName).\\(FileExtensions.swift)\",\n                             groupingPriority: IOSType.viewTypeGroupingPriority\n                            )]\n    }\n\n    func appendAccessor(className: String, nodeId: String) throws {\n        let staticPropertyName = \"\\(nodeId.camelCased)Id\"\n\n        writer.appendBody(\"let \\(nodeId.camelCased): \\(className)? {\\n\")\n        writer.appendBody(\"get { return valdiContext?.getView(\\(staticPropertyName)) as? \\(className) }\\n\")\n        writer.appendBody(\"\\n\\n\")\n    }\n\n    private func getViewModelType() -> String? {\n        guard let viewModelClassName = viewModelClass?.swiftName else {\n            return nil\n        }\n        return viewModelClassName\n    }\n\n    private func getComponentContextType() -> String? {\n        guard let componentContextClassName = componentContextClass?.swiftName else {\n            return nil\n        }\n        return componentContextClassName\n    }\n    \n    func appendNativeActions(nativeFunctionNames: [String]) {\n        // Not supported\n    }\n    \n    func appendEmitActions(actions: [String]) {\n        // Not supported\n    }\n\n    func appendConstructor() throws {\n        writer.appendBody(\n        \"\"\"\n        static public override func componentPath() -> String {\n            return \"\\(componentPath)\"\n        }\n        \\n\n        \"\"\")\n\n        \n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/TemplateCompilerResult.swift",
    "content": "//\n//  TemplateCompilerResult.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ObservedElement {\n    let elementId: String\n    let attributeValue: ValdiRawNodeAttribute\n}\n\nstruct TemplateCompilerResult {\n\n    let rootElement: ValdiJSElement\n    var actions: [ValdiAction]\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/ValdiTemplateCompiler.swift",
    "content": "//\n//  ValdiTemplateCompiler.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/6/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprivate extension String {\n\n    var isImplicitAction: Bool {\n        // checking if string is `onSomething`\n        guard hasPrefix(\"on\") && count >= 3 else { return false }\n\n        return self[2].isUppercase\n    }\n\n}\n\nclass ValdiTemplateCompiler {\n\n    private let template: ValdiRawTemplate\n    private var viewModel: ValdiModel?\n    private let actions: [ValdiAction]\n\n    private var idSequence = 0\n    private var assignedIds: Set<String> = []\n    private var slotNames: Set<String> = []\n\n    private let classMapping: ResolvedClassMapping\n\n    private let compileIOS: Bool\n    private let compileAndroid: Bool\n    private let documentContent: String\n\n    init(template: ValdiRawTemplate,\n         viewModel: ValdiModel?,\n         classMapping: ResolvedClassMapping,\n         actions: [ValdiAction],\n         compileIOS: Bool,\n         compileAndroid: Bool,\n         documentContent: String) {\n        self.template = template\n        self.actions = actions\n        self.viewModel = viewModel\n        self.classMapping = classMapping\n        self.compileIOS = compileIOS\n        self.compileAndroid = compileAndroid\n        self.documentContent = documentContent\n    }\n\n    private func generateId() -> String {\n        idSequence += 1\n\n        return \"!\\(idSequence)\"\n    }\n\n    private func makeAttributeKey(variable: String, nodeId: String, attributeName: String) -> String {\n        return \"\\(variable)['\\(nodeId)']['\\(attributeName)']\"\n    }\n\n    private func throwError(node: ValdiRawNode, message: String) throws -> Never {\n        throw CompilerError(type: \"Compilation error\", message: message, atZeroIndexedLine: node.lineNumber, column: node.columnNumber, inDocument: documentContent)\n    }\n\n    private func doResolve(node: ValdiRawNode) throws -> ValdiClass {\n        do {\n            return try classMapping.resolve(nodeType: node.nodeType)\n        } catch let error {\n            try throwError(node: node, message: error.legibleLocalizedDescription)\n        }\n    }\n\n    private func makeDebugInfo(node: ValdiRawNode, attribute: ValdiRawNodeAttribute) -> ValdiJSAttributeDebugInfo {\n        // TODO(simon): Move to a custom parser instead of NSXMLParser so that we can get the exact line and column number from\n        // the vue file.\n        return ValdiJSAttributeDebugInfo(originalExpression: \"\\(attribute.name)=\\\"{{ \\(attribute.value) }}\\\"\", line: node.lineNumber, column: node.columnNumber)\n    }\n\n    private func compile(node: ValdiRawNode, parentJSElement: ValdiJSElement?, actions: inout [ValdiAction], parentMapping: ValdiClass?, parentIsRoot: Bool, rootClass: ValdiClass?) throws -> ValdiJSElement {\n        let mapping = try doResolve(node: node)\n\n        if let rootClass = rootClass, rootClass == mapping {\n            try throwError(node: node, message: \"Component is trying to recursively inflate itself\")\n        }\n\n        let componentPath = mapping.valdiViewPath\n\n        let id = node.id.isEmpty ? generateId() : node.id\n\n        let jsElement = ValdiJSElement(id: id, componentPath: componentPath, nodeType: node.nodeType, jsxName: mapping.jsxName)\n\n        if let forEachExpr = node.forEachExpr {\n            jsElement.forEachExpr = ValdiJSAttribute(attribute: \"forEach\", value: forEachExpr.value, valueIsExpr: true, evaluateOnce: false, isViewModelField: false, debugInfo: makeDebugInfo(node: node, attribute: forEachExpr))\n        }\n\n        guard !assignedIds.contains(id) else {\n            try throwError(node: node, message: \"Node id \\(id) was already assigned.\")\n        }\n        assignedIds.insert(id)\n\n        let nonNilCount = [node.ifExpr, node.elseIfExpr, node.elseExpr, node.unlessExpr].count { $0 != nil }\n        if nonNilCount > 1 {\n            try throwError(node: node, message: \"Attributes 'render-if', 'render-else-if', 'render-else', and 'render-unless' are mutually exclusive\")\n        }\n\n        if let ifExpr = node.ifExpr {\n            // Truthty evaluation converted to bool\n            jsElement.renderIfExpr = ValdiJSAttribute(attribute: \"shouldRender\", value: ifExpr.value, valueIsExpr: true, evaluateOnce: ifExpr.evaluateOnce, isViewModelField: false, debugInfo: makeDebugInfo(node: node, attribute: ifExpr))\n        } else if let elseIfExpr = node.elseIfExpr {\n            jsElement.renderElseIfExpr = ValdiJSAttribute(attribute: \"shouldRender\", value: elseIfExpr.value, valueIsExpr: true, evaluateOnce: elseIfExpr.evaluateOnce, isViewModelField: false, debugInfo: makeDebugInfo(node: node, attribute: elseIfExpr))\n        } else if let elseExpr = node.elseExpr {\n            jsElement.renderElseIfExpr = ValdiJSAttribute(attribute: \"shouldRender\", value: \"true\", valueIsExpr: true, evaluateOnce: elseExpr.evaluateOnce, isViewModelField: false, debugInfo: makeDebugInfo(node: node, attribute: elseExpr))\n        } else if let unlessExpr = node.unlessExpr {\n            // renderUnless is not conditional render, as it inflates the view immediately before going to JS\n            jsElement.renderIfExpr = ValdiJSAttribute(attribute: \"shouldRender\", value: \"!(\\(unlessExpr.value))\", valueIsExpr: true, evaluateOnce: unlessExpr.evaluateOnce, isViewModelField: false, debugInfo: makeDebugInfo(node: node, attribute: unlessExpr))\n        }\n\n        for attribute in node.customAttributes {\n            let attributeValue = attribute.value\n\n            if attribute.name == \"key\" && !attribute.isViewModelField {\n                if attribute.evaluateOnce || !attribute.valueIsExpr {\n                    try throwError(node: node, message: \"'key' need to be a regular JS expression\")\n                }\n                jsElement.forEachKey = ValdiJSAttribute(attribute: \"key\", value: attribute.value, valueIsExpr: true, evaluateOnce: attribute.evaluateOnce, isViewModelField: attribute.isViewModelField, debugInfo: makeDebugInfo(node: node, attribute: attribute))\n                continue\n            }\n\n            if mapping.isSlot {\n                if attribute.name == \"name\" {\n                    jsElement.slotName = attributeValue\n                    continue\n                }\n                if attribute.name == \"ref\" {\n                    if !attribute.valueIsExpr {\n                        try throwError(node: node, message: \"ref must be an expression\")\n                    }\n                    jsElement.slotRefExpr = attributeValue\n                    continue\n                }\n\n                try throwError(node: node, message: \"Attributes are not supported on Slots.\")\n            }\n\n            jsElement.attributes.append(ValdiJSAttribute(attribute: attribute.name, value: attributeValue, valueIsExpr: attribute.valueIsExpr, evaluateOnce: attribute.evaluateOnce, isViewModelField: attribute.isViewModelField, debugInfo: makeDebugInfo(node: node, attribute: attribute)))\n        }\n\n        // If parent is a component we process the elements slot name\n        if let parentJSElement = parentJSElement, !parentIsRoot, parentMapping?.valdiViewPath != nil || parentJSElement.attributes.contains(where: { $0.attribute == \"componentClass\" }) {\n            let destSlotName = node.destSlotName ?? \"default\"\n            jsElement.insertInSlotName = destSlotName\n        }\n\n        // We use the default view if we can't resolve the class\n        if let androidClassName = mapping.androidClassName {\n            jsElement.androidViewClass = androidClassName\n        } else if !mapping.isSlot {\n            if mapping.isLayout {\n                jsElement.androidViewClass = \"Layout\"\n            } else if parentJSElement == nil || componentPath != nil {\n                jsElement.androidViewClass = try classMapping.resolve(nodeType: \"View\").androidClassName!\n            } else if compileAndroid && mapping.valdiViewPath == nil {\n                try throwError(node: node, message: \"Could not resolve Android class for node type \\(node.nodeType)\")\n            }\n        }\n        if let iosTypeName = mapping.iosType?.name {\n            jsElement.iosViewClass = iosTypeName\n        } else if !mapping.isSlot {\n            if mapping.isLayout {\n                jsElement.iosViewClass = \"Layout\"\n            } else if parentJSElement == nil || componentPath != nil {\n                jsElement.iosViewClass = try classMapping.resolve(nodeType: \"View\").iosType!.name\n            } else if compileIOS && mapping.valdiViewPath == nil {\n                try throwError(node: node, message: \"Could not resolve Android class for node type \\(node.nodeType)\")\n            }\n        }\n        if let webViewClassName = mapping.webViewClassName {\n            jsElement.webViewClass = webViewClassName\n        }\n        if let macosViewClassName = mapping.macosViewClassName {\n            jsElement.macosViewClass = macosViewClassName\n        }\n\n        if mapping.isSlot {\n            let slotName = jsElement.slotName ?? \"default\"\n            jsElement.slotName = slotName\n\n            if slotNames.contains(slotName) {\n                try throwError(node: node, message: \"slot '\\(slotName)' was already assigned\")\n            }\n\n            slotNames.insert(slotName)\n        }\n\n        jsElement.children += try node.children.map {\n            switch $0 {\n            case let .expression(expression):\n                return .expression(ValdiJSExpression(expression: expression))\n            case let .node(node):\n                return .element(try compile(node: node,\n                                     parentJSElement: jsElement,\n                                     actions: &actions,\n                                     parentMapping: mapping,\n                                     parentIsRoot: parentJSElement == nil,\n                                     rootClass: rootClass))\n            }\n        }\n\n        return jsElement\n    }\n\n    func compile() throws -> TemplateCompilerResult {\n        idSequence = 0\n        assignedIds.removeAll()\n        slotNames.removeAll()\n\n        guard let rootNode = self.template.rootNode else {\n            throw CompilerError(\"This template has no root node\")\n        }\n\n        var actions = self.actions\n        let rootElement = try compile(node: rootNode, parentJSElement: nil, actions: &actions, parentMapping: nil, parentIsRoot: false, rootClass: nil)\n\n        return TemplateCompilerResult(rootElement: rootElement, actions: actions)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Template/ViewClassGenerator.swift",
    "content": "//\n//  ViewClassGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ViewClassGenerationResult {\n    let nativeSources: [NativeSourceAndPlatform]\n    let description: GeneratedViewClassDescription\n}\n\nfinal class ViewClassGenerator {\n\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let logger: ILogger\n    private let compiledDocument: TemplateCompilerResult\n    private let rawDocument: ValdiRawDocument\n    private let componentPath: ComponentPath?\n    private let sourceFilename: GeneratedSourceFilename\n    private let iosType: IOSType?\n    private let iosLanguage: IOSLanguage\n    private let androidClassName: String?\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         logger: ILogger,\n         compiledDocument: TemplateCompilerResult,\n         rawDocument: ValdiRawDocument,\n         componentPath: ComponentPath?,\n         sourceFilename: GeneratedSourceFilename,\n         iosType: IOSType?,\n         iosLanguage: IOSLanguage,\n         androidClassName: String?) {\n        self.bundleInfo = bundleInfo\n        self.logger = logger\n        self.compiledDocument = compiledDocument\n        self.rawDocument = rawDocument\n        self.componentPath = componentPath\n        self.sourceFilename = sourceFilename\n        self.iosType = iosType\n        self.iosLanguage = iosLanguage\n        self.androidClassName = androidClassName\n    }\n\n    private func generateAccessors(nodes: [(raw: ValdiRawNode, compiled: ValdiJSElement)], generator: LanguageSpecificViewClassGenerator) {\n        for (rawNode, compiledNode) in nodes {\n            let className: String?\n            switch type(of: generator).platform {\n            case .ios: className = compiledNode.iosViewClass\n            case .android: className = compiledNode.androidViewClass\n            // This won't happen yet\n            case .web: className = nil\n            case .cpp: className = nil\n            }\n\n            if let className = className {\n                do {\n                    try generator.appendAccessor(className: className, nodeId: rawNode.id)\n                } catch let error {\n                    let platform = type(of: generator).platform\n                    logger.error(\"Failed to add \\(platform) accessor for node \\(rawNode.id): \\(error.legibleLocalizedDescription)\")\n                }\n            }\n        }\n    }\n\n    private func listAccessorEligibleNodes(rawNode: ValdiRawNode?, compiledNode: ValdiJSElement) -> [(raw: ValdiRawNode, compiled: ValdiJSElement)] {\n        guard let rawNode = rawNode else {\n            return []\n        }\n\n        var nodes: [(raw: ValdiRawNode, compiled: ValdiJSElement)] = []\n\n        if !rawNode.id.isEmpty && compiledNode.jsxName != \"layout\" {\n            nodes.append((rawNode, compiledNode))\n        }\n\n        let childNodes = rawNode.children.enumerated().flatMap { (index, child) -> [(raw: ValdiRawNode, compiled: ValdiJSElement)] in\n            guard let childNode = child.node, let childCompiledNode = compiledNode.children[index].element else {\n                return []\n            }\n            return listAccessorEligibleNodes(rawNode: childNode, compiledNode: childCompiledNode)\n        }\n\n        nodes += childNodes\n\n        return nodes\n    }\n\n    func generate() throws -> ViewClassGenerationResult? {\n        var generators: [LanguageSpecificViewClassGenerator] = []\n\n        guard let componentPath = self.componentPath else {\n            throw CompilerError(\"Could not resolve componentPath\")\n        }\n\n        if let iosType = iosType {\n            let iosSwiftGenerator = SwiftViewClassGenerator(bundleInfo: self.bundleInfo,\n                                                            iosType: iosType,\n                                                            componentPath: componentPath.stringRepresentation,\n                                                            sourceFilename: sourceFilename,\n                                                            viewModelClass: rawDocument.viewModel?.iosType,\n                                                            componentContextClass: rawDocument.componentContext?.iosType)\n            let iosObjCGenerator = ObjCViewClassGenerator(bundleInfo: self.bundleInfo,\n                                                          iosType: iosType,\n                                                          componentPath: componentPath.stringRepresentation,\n                                                          sourceFilename: sourceFilename,\n                                                          viewModelClass: rawDocument.viewModel?.iosType,\n                                                          componentContextClass: rawDocument.componentContext?.iosType)\n            switch self.iosLanguage {\n            case IOSLanguage.swift:\n                generators.append(iosSwiftGenerator)\n            case IOSLanguage.objc:\n                generators.append(iosObjCGenerator)\n            case IOSLanguage.both:\n                generators.append(iosSwiftGenerator)\n                generators.append(iosObjCGenerator)\n            }\n            logger.debug(\"Generating iOS type \\(iosType.name)\")\n        } else {\n            logger.debug(\"Not generating iOS type\")\n        }\n\n        if let androidClassName = androidClassName {\n            let androidCodeGenerator = KotlinViewClassGenerator(bundleInfo: self.bundleInfo,\n                                                                className: androidClassName,\n                                                                componentPath: componentPath.stringRepresentation,\n                                                                sourceFilename: sourceFilename,\n                                                                viewModelClassName: rawDocument.viewModel?.androidClassName,\n                                                                componentContextClassName: rawDocument.componentContext?.androidClassName)\n            generators.append(androidCodeGenerator)\n            logger.debug(\"Generating Android class \\(androidClassName)\")\n        } else {\n            logger.debug(\"Not generating Android class\")\n        }\n\n        guard !generators.isEmpty else {\n            return nil\n        }\n\n        let accessorEligibleNodes = listAccessorEligibleNodes(rawNode: rawDocument.template?.rootNode,\n                                                              compiledNode: compiledDocument.rootElement)\n\n        let viewModel = rawDocument.viewModel\n        let componentContext = rawDocument.componentContext\n        let accessors = accessorEligibleNodes.map { (rawNode, compiledNode) in\n            GeneratedViewClassDescription.AccessorDescription(iosTypeName: compiledNode.iosViewClass,\n                                                              androidClassName: compiledNode.androidViewClass,\n                                                              name: rawNode.id.camelCased)\n        }\n        let nativeActions = compiledDocument.actions.filter { $0.type == .native }.map { $0.name }\n        let emitActions = compiledDocument.actions.filter { $0.type == .javaScript }.map { $0.name }\n\n        var nativeSources: [NativeSourceAndPlatform] = []\n\n        for generator in generators {\n            try generator.start()\n\n            try generator.appendConstructor()\n\n            generateAccessors(nodes: accessorEligibleNodes,\n                              generator: generator)\n\n            generator.appendNativeActions(nativeFunctionNames: nativeActions)\n            generator.appendEmitActions(actions: emitActions)\n\n            generator.finish()\n\n            nativeSources += try generator.write().map {\n                NativeSourceAndPlatform(source: $0, platform: type(of: generator).platform)\n            }\n        }\n\n        let description = GeneratedViewClassDescription(iosTypeName: iosType?.name,\n                                                        androidClassName: androidClassName,\n                                                        iosViewModelClassName: viewModel?.iosType?.name,\n                                                        androidViewModelClassName: viewModel?.androidClassName,\n                                                        iosComponentContextClassName: componentContext?.iosType?.name,\n                                                        androidComponentContextClassName: componentContext?.androidClassName,\n                                                        accessors: accessors.nonEmpty,\n                                                        nativeActions: nativeActions.nonEmpty,\n                                                        emitActions: emitActions.nonEmpty)\n\n        let result = ViewClassGenerationResult(nativeSources: nativeSources,\n                                               description: description)\n        return result\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Tests/Tests.swift",
    "content": "//\n//  Tests.swift\n//  Compiler\n//\n//  Created by Nathaniel Parrott on 5/14/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport SwiftCSSParser\n//\n// func test() {\n//    testCSSParsing()\n//    testCSSImportParsing()\n//    testCommaSelectorParsing()\n//    testHierarchicalSelectorParsing()\n//    testCSSErrors()\n//    testSelectorTermParsing()\n//    testSelectorTermParsing2()\n//    testStyleTree()\n//    testStyleTreeSpecificity()\n//    testUniversalSelector()\n//    testMultiSelector()\n//    testStyleTreeProto()\n//    testAttributeEqualitySelector()\n//    testQuoting()\n//    testCamelCase()\n//    testNumericalValues()\n//    testCamelCaseAttributeSelectors()\n//    print(\"🎉 Tests passed!\")\n// }\n\n// func testCSSParsing() {\n//    let basicDeclaration = StyleSheet(string: \"#element {color: red;}\")!\n//    assert(basicDeclaration.rules.count == 1)\n//    assert(basicDeclaration.rules[0].declarations.count == 1)\n//    assert(basicDeclaration.rules[0].declarations[0].name == \"color\");\n//    assert(basicDeclaration.rules[0].declarations[0].value == \"red\");\n//    assert(basicDeclaration.rules[0].selectors.count == 1)\n//    let sel = basicDeclaration.rules[0].selectors[0]\n//    assert(sel.match! == .id)\n//    assert(sel.value! == \"element\")\n// }\n//\n// func testCSSImportParsing() {\n//    let sheet = StyleSheet(string: \"@import 'test.css';\")!\n//    assert(sheet.importFilenames.count == 1)\n//    assert(sheet.importFilenames[0] == \"test.css\")\n// }\n//\n// func testCommaSelectorParsing() {\n//    let sheet = StyleSheet(string: \"h1, h2 { x: 1; }\")!\n//    assert(sheet.rules.count == 1)\n//    assert(sheet.rules[0].selectors.count == 2)\n// }\n//\n// func testHierarchicalSelectorParsing() {\n//    let sheet = StyleSheet(string: \"abc def > ghi:first-child {x: y}\")!\n//    assert(sheet.rules[0].selectors.count == 1)\n//\n//    let ghi = sheet.rules[0].selectors[0]\n//    assert(ghi.value! == \"ghi\")\n//    assert(ghi.relation! == .subselector)\n//\n//    let firstChild = ghi.related!\n//    assert(firstChild.match! == .pseudoClass)\n//    assert(firstChild.psuedoType! == .firstChild)\n//    assert(firstChild.relation! == .child)\n//\n//    let def = firstChild.related!\n//    assert(def.relation! == .descendant)\n//\n//    let abc = def.related!\n//    assert(abc.value! == \"abc\")\n//    assert(abc.related!.match == nil)\n// }\n//\n// func testCSSErrors() {\n//    let sheet = StyleSheet(string: \"{}\")!\n//    assert(sheet.errors.count == 1)\n// }\n//\n// func testSelectorTermParsing() {\n//    let sheet = StyleSheet(string: \"*:first-child > myTag.myClass.myClass2[attr=\\\"xyz\\\"] {x: y}\")!\n//    let termNode = SelectorTerm()\n//    try! SelectorTerm.parseSelectorToTerms(selector: sheet.rules[0].selectors[0], termNode: termNode)\n//    assert(termNode.tagRule == \"myTag\")\n//    assert(termNode.classRules.contains(\"myClass\"))\n//    assert(termNode.classRules.contains(\"myClass2\"))\n//    assert(termNode.attributeRules[0].attribute == \"attr\")\n//    assert(termNode.attributeRules[0].value == \"xyz\")\n//    assert(termNode.parent!.directChild)\n//    let parent = termNode.parent!.term\n//    assert(parent.classRules.count == 0)\n//    assert(parent.firstChild)\n//    assert(!parent.lastChild)\n//    assert(parent.parent == nil)\n// }\n//\n// func testSelectorTermParsing2() {\n//    let sheet = StyleSheet(string: \"#waka:nth-child(3) #flocka.FLAME {x: y}\")!\n//    let termNode = SelectorTerm()\n//    try! SelectorTerm.parseSelectorToTerms(selector: sheet.rules[0].selectors[0], termNode: termNode)\n//    assert(termNode.classRules.contains(\"FLAME\"))\n//    assert(termNode.idRule! == \"flocka\")\n//    assert(termNode.parent!.directChild == false)\n//    assert(termNode.parent!.term.idRule! == \"waka\")\n//    // TODO: (nate) fix nth-child parsing\n//    // assert(termNode.parent!.term.nthChildRules.first!.n == 3)\n// }\n//\n// func testStyleTree() {\n//    let t = StyleTree()\n//    var imports: [String] = []\n//    try! t.add(cssString: \"@import 'abc.css'; @import 'xyz.css'; #id > .xyz.abc { rule1: val1; rule2: val2; }\", filename: \"test.css\") { (name) in\n//        imports.append(name)\n//    }\n//    assert(imports == [\"abc.css\", \"xyz.css\"])\n//    let node = t.root.classRules[\"abc\"]!.classRules[\"xyz\"]!.directParentRule!.idRules[\"id\"]!\n//    assert(node.declarations.count == 2)\n//    assert(node.declarations[0].order == 0)\n//    assert(node.declarations[1].order == 1)\n//    assert(node.declarations[0].attribute.name == \"rule1\")\n//    assert(node.declarations[0].attribute.strValue == \"val1\")\n// }\n//\n// func testStyleTreeSpecificity() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \"#xyz #def {rule: abc;} Label:first-child {rule: def;}\", filename: \"test.css\", onImport: nil)\n//    let abc = t.root.idRules[\"def\"]!.ancestorRule!.idRules[\"xyz\"]!.declarations.first!\n//    let def = t.root.tagRules[\"Label\"]!.firstChildRule!.declarations.first!\n//    assert(abc.priority > def.priority)\n//\n//    try! t.add(cssString: \"Label:first-child {rule2: one;} Label.cls {rule2: two;}\", filename: \"test.css\", onImport: nil)\n//    let one = t.root.tagRules[\"Label\"]!.firstChildRule!.declarations.first!\n//    let two = t.root.classRules[\"cls\"]!.tagRules[\"Label\"]!.declarations.first!\n//    assert(one.priority == two.priority)\n// }\n//\n// func testUniversalSelector() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \"* > * {abc: def;}\", filename: \"test.css\", onImport: nil)\n//    assert(t.root.tagRules[\"*\"]!.directParentRule!.tagRules[\"*\"]!.declarations.first!.attribute.name == \"abc\")\n// }\n//\n// func testMultiSelector() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \"h1, h2 { color: red; }\", filename: \"test.css\", onImport: nil)\n//    assert(t.root.tagRules[\"h1\"]!.declarations.count == 1)\n//    assert(t.root.tagRules[\"h2\"]!.declarations.count == 1)\n// }\n//\n// func testNumericalValues() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \"h1 {width: 100%; height: 50px; left: 20; color: #ffffff; }\", filename: \"test.css\", onImport: nil)\n//    let h1 = t.root.tagRules[\"h1\"]!.declarations\n//    assert(h1[0].attribute.strValue == \"100%\")\n//    assert(h1[1].attribute.strValue == \"50px\")\n//    assert(h1[2].attribute.strValue == \"20\")\n//    assert(h1[3].attribute.strValue == \"#ffffff\")\n// }\n//\n// func testStyleTreeProto() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \".class #id > Tag:first-child {test: value;}\", filename: \"test.css\", onImport: nil)\n//    let p = t.root.proto\n//    assert(p.ruleIndex.tagRules[\"Tag\"]!.ruleIndex.firstChildRule.ruleIndex.directParentRules.idRules[\"id\"]!.ruleIndex.ancestorRules.classRules[\"class\"]!.styles.first!.attribute.strValue == \"value\")\n//    // ensure that unused fields are unset:\n//    assert(!p.ruleIndex.hasDirectParentRules)\n// }\n//\n// func testAttributeEqualitySelector() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \"[def=\\\"456\\\"][abc=\\\"123\\\"] {test: value;}\", filename: \"test.css\", onImport: nil)\n//    let p = t.root.proto\n//    // ensure the attributes are sorted properly\n//    assert(p.ruleIndex.attributeRules[0].attribute.name == \"abc\")\n//    assert(p.ruleIndex.attributeRules[0].attribute.strValue == \"123\")\n//    assert(p.ruleIndex.attributeRules[0].node.ruleIndex.attributeRules[0].attribute.name == \"def\")\n// }\n//\n// func testQuoting() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \"Label {x: abc; y: 'def'; z: \\\"ghi\\\";}\", filename: \"test.css\", onImport: nil)\n//    let p = t.root.proto\n//    let styles = p.ruleIndex.tagRules[\"Label\"]!.styles\n//    assert(styles[0].attribute.strValue == \"abc\")\n//    assert(styles[1].attribute.strValue == \"def\")\n//    assert(styles[2].attribute.strValue == \"ghi\")\n// }\n//\n// func testCamelCase() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \"Test { abc-def: abc-def ;}\", filename: \"test.css\", onImport: nil)\n//    let p = t.root.proto\n//    let rule = p.ruleIndex.tagRules[\"Test\"]!.styles.first!\n//    assert(rule.attribute.name == \"abcDef\")\n//    assert(rule.attribute.strValue == \"abc-def\")\n// }\n//\n// func testCamelCaseAttributeSelectors() {\n//    let t = StyleTree()\n//    try! t.add(cssString: \"[my-attr=\\\"value\\\"] { abc: def; }\", filename: \"test.css\", onImport: nil)\n//    let p = t.root.proto\n//    assert(p.ruleIndex.attributeRules.first!.attribute.name == \"myAttr\")\n// }\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ToolboxExecutable/ToolboxExecutable.swift",
    "content": "//\n//  ToolboxExecutable.swift\n//  \n//\n//  Created by Simon Corsin on 9/2/22.\n//\n\nimport Foundation\n\nclass ToolboxExecutable {\n\n    struct ImageInfoOutput: Codable {\n        var width: Int\n        var height: Int\n    }\n\n    private let logger: ILogger\n    private let compilerToolboxURL: URL\n    private var version: String?\n    private let lock = DispatchSemaphore.newLock()\n\n    init(logger: ILogger, compilerToolboxURL: URL) {\n        self.logger = logger\n        self.compilerToolboxURL = compilerToolboxURL\n    }\n\n    private func run(arguments: [String]) throws -> String {\n        let handle = SyncProcessHandle.usingEnv(logger: logger, command: [compilerToolboxURL.path] + arguments)\n        try handle.run()\n        if !handle.stderr.content.isEmpty {\n            throw CompilerError(\"Compiler Toolbox error: \" + handle.stderr.contentAsString)\n        }\n        return handle.stdout.contentAsString.trimmed\n    }\n\n    private func logIfNeeded(runOutput: String) {\n        if !runOutput.isEmpty {\n            logger.info(\"CompilerToolbox: \\(runOutput)\")\n        }\n    }\n\n    func precompile(inputFilePath: String, outputFilePath: String, filename: String, engine: String) throws {\n        let output = try run(arguments: [\"precompile\", \"-i\", inputFilePath, \"-o\", outputFilePath, \"-f\", filename, \"-e\", engine])\n        logIfNeeded(runOutput: output)\n    }\n\n    func getImageInfo(inputFilePath: String) throws -> ImageInfoOutput {\n        let output = try run(arguments: [\"image_info\", \"-i\", inputFilePath])\n\n        return try ImageInfoOutput.fromJSON(try output.utf8Data(), keyDecodingStrategy: .convertFromSnakeCase)\n    }\n\n    func convertImage(inputFilePath: String, outputFilePath: String, outputWidth: Int?, outputHeight: Int?, qualityRatio: Double?) throws {\n        var arguments = [\"image_convert\", \"-i\", inputFilePath, \"-o\", outputFilePath]\n\n        if let outputWidth = outputWidth {\n            arguments += [\"-w\", String(outputWidth)]\n        }\n\n        if let outputHeight = outputHeight {\n            arguments += [\"-h\", String(outputHeight)]\n        }\n\n        if let qualityRatio = qualityRatio {\n            arguments += [\"-q\", String(qualityRatio)]\n        }\n\n        let output = try run(arguments: arguments)\n        logIfNeeded(runOutput: output)\n    }\n\n    func getVersionString() throws -> String {\n        return try lock.lock {\n            if let version {\n                return version\n            }\n            logger.debug(\"Resolving Image Toolbox version\")\n            let version = try run(arguments: [\"version\"])\n            self.version = version\n\n            return version\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/CompanionExecutable.swift",
    "content": "//\n//  File.swift\n//\n//\n//  Created by Simon Corsin on 10/11/19.\n//\n\nimport Foundation\n\nenum CommandType: String {\n    case processJSX\n    case batchMinifyJS\n\n    case createWorkspace\n    case destroyWorkspace\n    case initializeWorkspace\n    case registerFile\n    case openFile\n    case emitFile\n    case uploadArtifact\n    case addCodeInstrumentation\n    case getDiagnostics\n    case dumpInterface\n    case dumpSymbolsWithComments\n    case dumpEnum\n    case dumpFunction\n    case generateIdsFiles\n    case exportTranslationStrings\n    case getLcaToken\n    case compileNative\n\n    case startDebuggingProxy\n    case updatedAndroidTargets\n    case updatedDebuggerPorts\n}\n\nprivate struct BatchMinifyJS: Command {\n    static let type: CommandType = .batchMinifyJS\n\n    struct Request: RequestBody {\n        let inputFiles: [String]\n        let minifier: String\n        let options: String?\n    }\n\n    struct Response: ResponseBody {\n        let results: [BatchMinifyResult]\n    }\n}\n\nprivate struct CreateWorkspace: Command {\n    static let type: CommandType = .createWorkspace\n\n    struct Request: RequestBody {\n    }\n\n    struct Response: ResponseBody {\n        let workspaceId: Int\n    }\n}\n\nprivate struct DestroyWorkspace: Command {\n    static let type: CommandType = .destroyWorkspace\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n    }\n\n    struct Response: ResponseBody {\n    }\n}\n\nprivate struct InitializeWorkspace: Command {\n    static let type: CommandType = .initializeWorkspace\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n    }\n\n    struct Response: ResponseBody {\n\n    }\n}\n\nprivate struct OpenFile: Command {\n    static let type: CommandType = .openFile\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let fileName: String\n    }\n\n    struct Response: ResponseBody {\n        let openResult: TS.OpenResponseBody\n    }\n}\n\nprivate struct RegisterFile: Command {\n    static let type: CommandType = .registerFile\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let fileName: String\n        let absoluteDiskPath: String?\n        let fileContent: String?\n    }\n\n    struct Response: ResponseBody {\n    }\n}\n\nprivate struct EmitFile: Command {\n    static let type: CommandType = .emitFile\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let fileName: String\n    }\n\n    struct Response: ResponseBody {\n        let emitted: Bool\n        let files: [TS.EmittedFile]\n    }\n}\n\nprivate struct CompileNative: Command {\n    static let type: CommandType = .compileNative\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let stripIncludePrefix: String\n        let inputFiles: [String]\n        let outputFile: String?\n    }\n\n    struct Response: ResponseBody {\n        let files: [TS.EmittedFile]\n    }\n}\n\nprivate struct UploadArtifact: Command {\n    static let type: CommandType = .uploadArtifact\n\n    struct Request: RequestBody {\n        let artifactName: String\n        let artifactData: Data\n        let sha256: String\n    }\n\n    struct Response: ResponseBody {\n        let sha256: String\n        let url: URL\n    }\n}\n\nprivate struct AddCodeInstrumentation: Command {\n    static let type: CommandType = .addCodeInstrumentation\n\n    struct Request: RequestBody {\n        let files: [InstrumentationFileConfig]\n    }\n\n    struct Response: ResponseBody {\n        let results: [CodeInstrumentationResult]\n    }\n}\n\nprivate struct GetSyntacticDiagnostics: Command {\n    static let type: CommandType = .getDiagnostics\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let fileName: String\n    }\n\n    struct Response: ResponseBody {\n        // Will be provided if an error was found\n        let fileContent: String?\n        let diagnostics: [TS.Diagnostic]\n        let hasError: Bool\n        let timeTakenMs: Double\n    }\n}\n\nstruct GetErrorsResult {\n    let error: CompilerError?\n    let timeTakenMs: Double\n}\n\nstruct StartDebuggingProxy: Command {\n    static let type: CommandType = .startDebuggingProxy\n\n    struct Request: RequestBody {\n    }\n\n    struct Response: ResponseBody {\n        let actualPort: Int\n    }\n}\n\nprivate struct UpdatedAndroidTargets: Command {\n    static let type: CommandType = .updatedAndroidTargets\n\n    struct Request: RequestBody {\n        let targets: [AndroidDebuggingTarget]\n    }\n\n    struct Response: ResponseBody {\n\n    }\n}\n\nprivate struct UpdatedDebuggerPorts: Command {\n    static let type: CommandType = .updatedDebuggerPorts\n\n    struct Request: RequestBody {\n        let ports: [Int]\n    }\n\n    struct Response: ResponseBody {\n    }\n}\n\nprivate struct DumpSymbolsWithComments: Command {\n    static let type: CommandType = .dumpSymbolsWithComments\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let fileName: String\n    }\n\n    struct Response: ResponseBody {\n        let dumpedSymbols: TS.DumpSymbolsWithCommentsResponseBody\n    }\n}\n\nprivate struct DumpInterface: Command {\n    static let type: CommandType = .dumpInterface\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let fileName: String\n        let position: Int\n    }\n\n    struct Response: ResponseBody {\n        let interface: TS.DumpInterfaceResponseBody\n    }\n}\n\nprivate struct DumpEnum: Command {\n    static let type: CommandType = .dumpEnum\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let fileName: String\n        let position: Int\n    }\n\n    struct Response: ResponseBody {\n        let `enum`: TS.DumpEnumResponseBody\n    }\n}\n\nprivate struct DumpFunction: Command {\n    static let type: CommandType = .dumpFunction\n\n    struct Request: RequestBody {\n        let workspaceId: Int\n        let fileName: String\n        let position: Int\n    }\n\n    struct Response: ResponseBody {\n        let function: TS.DumpFunctionResponseBody\n    }\n}\n\nprivate struct GenerateIds: Command {\n    static let type: CommandType = .generateIdsFiles\n\n    struct Request: RequestBody {\n        let moduleName: String\n        let filePath: String\n        let iosHeaderImportPath: String\n    }\n\n    struct Response: ResponseBody {\n        let android: String\n        let iosHeader: String\n        let iosImplementation: String\n        let typescriptDefinition: String\n        let typescriptImplementation: String\n    }\n}\n\n/// Command to generate platform specific translation strings representation\nstruct ExportTranslationStrings: Command {\n    static let type: CommandType = .exportTranslationStrings\n\n    struct Request: RequestBody {\n        /// Module name to generate the translation file for\n        let moduleName: String\n        /// Path to the strings-en.json aka base locale file\n        let baseLocaleStringsPath: String\n        /// Path to the strings-.json to generate the translation file for\n        let inputLocaleStringsPath: String\n        /// One of: 'android', 'ios'\n        let platform: String\n    }\n\n    struct Response: ResponseBody {\n        /// Input locale extracted from the passed `inputLocaleStringsPaths`\n        let inputLocale: String\n        /// Platform specific input locale name. Android and iOS call the same locale using different names\n        let platformLocale: String\n        /// The exported translation content\n        let content: String\n        /// The platform specific translation string name, including the folder, if necessary.\n        let outputFileName: String\n    }\n}\n\nprivate protocol Command {\n    static var type: CommandType { get }\n    associatedtype Request: RequestBody\n    associatedtype Response: ResponseBody\n}\n\nprivate protocol RequestBody: Encodable {}\nprivate protocol ResponseBody: Decodable {}\n\nprivate struct RequestEnvelope<C: Command>: Encodable {\n    let id: Int\n    let command: String\n    let body: C.Request\n\n    init(id: Int, body: C.Request) {\n        self.id = id\n        self.command = C.type.rawValue\n        self.body = body\n    }\n}\n\nprivate struct EventPayload: Decodable {\n    let type: String\n    let message: String\n}\n\nprivate struct ResponseHeader: Decodable {\n    let id: Int?\n    let error: String?\n\n    // Events don't have an id and can occur outside of the normal request/response back-and-forth\n    let event: EventPayload?\n}\n\nprivate struct ResponseEnvelope<C: Command>: Decodable {\n    let id: Int\n    let body: C.Response\n}\n\nclass CompanionExecutable {\n    private let logger: ILogger\n\n    let compilerCompanionBinaryPath: String\n    let nodeOptions: [String]\n    let logsOutputPath: String?\n    let compilerCacheURL: URL?\n    let isBazelBuild: Bool\n\n    private(set) var processExited = false\n\n    private let queue = DispatchQueue(label: \"CompanionExecutable\")\n    private var processHandle: AsyncProcessHandle?\n    private var requestSequence = 0\n    private var pendingResponses: [Int: Promise<Data>] = [:]\n    private var exitError: CompilerError? = nil\n    private static let newlineSeparator: UInt8 = 10\n\n    init(logger: ILogger,\n         compilerCompanionBinaryPath: String,\n         nodeOptions: [String],\n         logsOutputPath: String?,\n         compilerCacheURL: URL?,\n         isBazelBuild: Bool) {\n        self.logger = logger\n        self.compilerCompanionBinaryPath = compilerCompanionBinaryPath\n        self.nodeOptions = nodeOptions\n        self.logsOutputPath = logsOutputPath\n        self.compilerCacheURL = compilerCacheURL\n        self.isBazelBuild = isBazelBuild\n\n        // Warm up process immediately\n        self.prepareProcess()\n    }\n\n    private func startProcessIfNeeded() throws {\n        guard self.processHandle == nil else {\n            return\n        }\n\n        if let exitError {\n            throw exitError\n        }\n\n        logger.info(\"Will start companion executable\")\n\n        var command: [String] = [compilerCompanionBinaryPath]\n        let cwd: String? = nil\n        let nodeOptions = self.nodeOptions\n\n        if let compilerCacheURL = self.compilerCacheURL {\n            command.append(\"--cache-dir\")\n            command.append(compilerCacheURL.absoluteURL.path)\n        }\n\n        if let logsOutputPath {\n            command.append(\"--log-output\")\n            command.append(logsOutputPath)\n        }\n\n        logger.info(\"Starting companion executable with command: \\(command)\")\n        var envOverrides: [String: String] = [\n            \"NODE_OPTIONS\": nodeOptions.joined(separator: \" \"),\n            // Set this flag to track Bazel build adoption during the migration\n            \"IS_BAZEL_BUILD\": String(self.isBazelBuild)\n        ]\n        // Configure the service account\n        if let serviceAccount = ProcessInfo.processInfo.environment[\"VALDI_COMPILER_GCP_SERVICE_ACCOUNT\"] {\n            envOverrides[\"VALDI_COMPILER_GCP_SERVICE_ACCOUNT\"] = serviceAccount\n        }\n\n        let processHandle = AsyncProcessHandle.usingEnv(logger: logger,\n                                                        command: command,\n                                                        dispatchQueue: queue,\n                                                        cwd: cwd,\n                                                        envOverrides: envOverrides)\n\n        let logger = self.logger\n        processHandle.stderr.onDidReceiveData = { (pipeHandle) in\n            let content = pipeHandle.contentAsString\n            pipeHandle.content = Data()\n            logger.warn(\"CompilerCompanion: \\(content)\")\n        }\n        processHandle.stdout.onDidReceiveData = { [weak self] (pipeHandle) in\n            self?.didReceiveData(pipeHandle: pipeHandle)\n        }\n        try processHandle.runAsync { [weak self] _ in\n            guard let strongSelf = self else { return }\n\n            strongSelf.queue.async {\n                let processHandle = strongSelf.processHandle\n                strongSelf.processExited = true\n                strongSelf.processHandle = nil\n                let errorMessage = processHandle?.stderr.contentAsString ?? \"\"\n                let error = CompilerError(\"CompilerCompanion exited: \\(errorMessage)\")\n                strongSelf.exitError = error\n\n                for value in Array(strongSelf.pendingResponses.values) {\n                    value.reject(error: error)\n                }\n                strongSelf.pendingResponses.removeAll()\n            }\n        }\n\n        self.processHandle = processHandle\n    }\n\n    private func didReceiveData(pipeHandle: FileHandleReader) {\n        while processData(pipeHandle: pipeHandle) {\n\n        }\n    }\n\n    private func process(data: Data) {\n        do {\n            let decoder = JSONDecoder()\n            let responseEnvelope = try decoder.decode(ResponseHeader.self, from: data)\n            if let event = responseEnvelope.event {\n                if event.type == \"info\" {\n                    logger.info(event.message)\n                } else if event.type == \"debug\" {\n                    logger.debug(event.message)\n                } else if event.type == \"warn\" {\n                    logger.warn(event.message)\n                } else if event.type == \"error\" {\n                    logger.error(event.message)\n                } else {\n                    throw CompilerError(\"Could not resolve event type '\\(event.type)'\")\n                }\n\n                return\n            }\n            guard let id = responseEnvelope.id else {\n                throw CompilerError(\"Received a response envelope with no event and no id\")\n            }\n            if let pendingResponse = pendingResponses.removeValue(forKey: id) {\n                if let errorMessage = responseEnvelope.error {\n                    pendingResponse.reject(error: CompilerError(errorMessage))\n                } else {\n                    pendingResponse.resolve(data: data)\n                }\n            } else {\n                logger.error(\"Could not resolve response for compiler companion request id \\(id)\")\n            }\n        } catch let error {\n            logger.error(\"Failed to parse compiler companion response: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    private func processData(pipeHandle: FileHandleReader) -> Bool {\n        guard let newLineIndex = pipeHandle.content.fastFirstIndex(of: CompanionExecutable.newlineSeparator) else {\n            return false\n        }\n\n        process(data: pipeHandle.content[..<newLineIndex])\n        pipeHandle.trimContent(by: newLineIndex + 1)\n\n        return true\n    }\n\n    private func submit<C: Command>(_ commandType: C.Type, _ body: C.Request) -> Promise<C.Response> {\n        self.requestSequence += 1\n        let sequence = self.requestSequence\n\n        let envelope = RequestEnvelope<C>(id: sequence, body: body)\n\n        do {\n            let data = try encodeEnvelope(envelope)\n            let innerPromise = Promise<Data>()\n            self.pendingResponses[sequence] = innerPromise\n\n            // Swift 5.3 and macOS 10.15 provides FileHandle methods that catch and translate Obj-C exceptions into Swift errors\n            if #available(OSX 10.15.4, *) {\n                try processHandle?.stdinFileHandle.write(contentsOf: data)\n                try processHandle?.stdinFileHandle.write(contentsOf: \"\\n\".data(using: .utf8)!)\n            } else {\n                processHandle?.stdinFileHandle.write(data)\n                processHandle?.stdinFileHandle.write(\"\\n\".data(using: .utf8)!)\n            }\n\n            logger.trace(\"Sending companion request >>> \\(String(data: data, encoding: .utf8) ?? \"<none>\")\")\n\n            return innerPromise.then { (data) -> Promise<C.Response> in\n                self.pendingResponses.removeValue(forKey: sequence)\n\n                self.logger.trace(\"Received companion response <<< \\(String(data: data, encoding: .utf8) ?? \"<none>\")\")\n\n                return DispatchQueue.global(qos: .userInitiated).asyncPromise { () throws -> C.Response in\n                    return try decodeData(data, commandType)\n                }\n            }\n        } catch let error {\n            return Promise(error: error)\n        }\n    }\n\n    private func processRequest<C: Command>(_ commandType: C.Type, _ request: C.Request) -> Promise<C.Response> {\n        let promise = Promise<C.Response>()\n        queue.async {\n            do {\n                try self.startProcessIfNeeded()\n\n                let logger = self.logger\n                self.submit(C.self, request)\n                    .catch { (error) -> Void in\n                        logger.error(\"Compiler companion command '\\(commandType)' failed: \\(error.legibleLocalizedDescription)\")\n                    }\n                    .onComplete { (result) in\n                        switch result {\n                        case .success(let data):\n                            promise.resolve(data: data)\n                        case .failure(let error):\n                            promise.reject(error: error)\n                        }\n                    }\n            } catch let error {\n                promise.reject(error: error)\n            }\n        }\n\n        return promise\n    }\n\n    func prepareProcess() {\n        queue.async {\n            try? self.startProcessIfNeeded()\n        }\n    }\n\n    func batchMinifyJS(inputURLs: [URL], minifier: Minifier, options: String?) -> Promise<[BatchMinifyResult]> {\n        let request = BatchMinifyJS.Request(inputFiles: inputURLs.map { $0.absoluteString }, minifier: minifier.rawValue, options: options)\n        return processRequest(BatchMinifyJS.self, request).then { return $0.results }\n    }\n\n    func createWorkspace() -> Promise<Int> {\n        let request = CreateWorkspace.Request()\n        return processRequest(CreateWorkspace.self, request).then { response in response.workspaceId }\n    }\n\n    func destroyWorkspace(workspaceId: Int) -> Promise<Void> {\n        let request = DestroyWorkspace.Request(workspaceId: workspaceId)\n        return processRequest(DestroyWorkspace.self, request).then { response in () }\n    }\n\n    func initializeWorkspace(workspaceId: Int) -> Promise<Void> {\n        let request = InitializeWorkspace.Request(workspaceId: workspaceId)\n        return processRequest(InitializeWorkspace.self, request).then { _ in () }\n    }\n\n    func registerInMemoryFile(workspaceId: Int, filePath: String, fileContent: String) -> Promise<Void> {\n        let request = RegisterFile.Request(workspaceId: workspaceId, fileName: filePath, absoluteDiskPath: nil, fileContent: fileContent)\n        return processRequest(RegisterFile.self, request).then { _ in return () }\n    }\n\n    func registerDiskFile(workspaceId: Int, filePath: String, absoluteFileURL: URL) -> Promise<Void> {\n        let request = RegisterFile.Request(workspaceId: workspaceId, fileName: filePath, absoluteDiskPath: absoluteFileURL.path, fileContent: nil)\n        return processRequest(RegisterFile.self, request).then { _ in return () }\n    }\n\n    func openFile(workspaceId: Int, filePath: String) -> Promise<TS.OpenResponseBody> {\n        let request = OpenFile.Request(workspaceId: workspaceId, fileName: filePath)\n        return processRequest(OpenFile.self, request).then { $0.openResult }\n    }\n\n    func saveFile(workspaceId: Int, filePath: String) -> Promise<[TS.EmittedFile]> {\n        let request = EmitFile.Request(workspaceId: workspaceId, fileName: filePath)\n        return processRequest(EmitFile.self, request).then { $0.files }\n    }\n\n    func compileNative(workspaceId: Int, stripIncludePrefix: String, inputFiles: [String]) -> Promise<[TS.EmittedFile]> {\n        let request = CompileNative.Request(workspaceId: workspaceId, stripIncludePrefix: stripIncludePrefix, inputFiles: inputFiles, outputFile: nil)\n        return processRequest(CompileNative.self, request).then { $0.files }\n    }\n\n    func uploadArtifact(artifactName: String, artifactData: Data, sha256: String) -> Promise<ArtifactInfo> {\n        let request = UploadArtifact.Request(artifactName: artifactName, artifactData: artifactData, sha256: sha256)\n        return processRequest(UploadArtifact.self, request).then { ArtifactInfo (url: $0.url, sha256Digest: $0.sha256 )}\n    }\n\n    func instrumentJSFiles(files: [InstrumentationFileConfig]) -> Promise<[CodeInstrumentationResult]> {\n        let request = AddCodeInstrumentation.Request(files: files)\n        return processRequest(AddCodeInstrumentation.self, request).then { $0.results }\n    }\n\n    func getErrors(workspaceId: Int, filePath: String) -> Promise<GetErrorsResult> {\n        let request = GetSyntacticDiagnostics.Request(workspaceId: workspaceId, fileName: filePath)\n\n        return processRequest(GetSyntacticDiagnostics.self, request).then { response -> GetErrorsResult in\n            if response.hasError {\n                for diagnostic in response.diagnostics {\n                    if diagnostic.category == \"error\" {\n                        if let documentContent = response.fileContent {\n                            return GetErrorsResult(error: CompilerError(type: \"TypeScript error\", message: diagnostic.text,\n                                                                       atZeroIndexedLine: diagnostic.start.line - 1,\n                                                                        column: diagnostic.start.offset, inDocument: documentContent), timeTakenMs: response.timeTakenMs)\n                        } else {\n                            return GetErrorsResult(error: CompilerError(\"TypeScript error: \\(diagnostic.text)\"), timeTakenMs: response.timeTakenMs)\n                        }\n                    }\n                }\n            }\n\n            return GetErrorsResult(error: nil, timeTakenMs: response.timeTakenMs)\n        }\n    }\n\n    func startDebuggingProxy() -> Promise<StartDebuggingProxy.Response> {\n        let request = StartDebuggingProxy.Request()\n        return processRequest(StartDebuggingProxy.self, request)\n    }\n\n    func updatedAndroidTargets(targets: [AndroidDebuggingTarget]) -> Promise<Void> {\n        let request = UpdatedAndroidTargets.Request(targets: targets)\n        return processRequest(UpdatedAndroidTargets.self, request).then { _ in }\n    }\n\n    func updatedDebuggerPorts(ports: [Int]) -> Promise<Void> {\n        let request = UpdatedDebuggerPorts.Request(ports: ports)\n        return processRequest(UpdatedDebuggerPorts.self, request).then { _ in }\n    }\n\n    func dumpSymbolsWithComments(workspaceId: Int, filePath: String) -> Promise<TS.DumpSymbolsWithCommentsResponseBody> {\n        let request = DumpSymbolsWithComments.Request(workspaceId: workspaceId, fileName: filePath)\n        return processRequest(DumpSymbolsWithComments.self, request).then { $0.dumpedSymbols }\n    }\n\n    func dumpInterface(workspaceId: Int, filePath: String, position: Int) -> Promise<TS.DumpInterfaceResponseBody> {\n        let request = DumpInterface.Request(workspaceId: workspaceId, fileName: filePath, position: position)\n        return processRequest(DumpInterface.self, request).then { $0.interface }\n    }\n\n    func dumpEnum(workspaceId: Int, filePath: String, position: Int) -> Promise<TS.DumpEnumResponseBody> {\n        let request = DumpEnum.Request(workspaceId: workspaceId, fileName: filePath, position: position)\n        return processRequest(DumpEnum.self, request).then { $0.enum }\n    }\n\n    func dumpFunction(workspaceId: Int, filePath: String, position: Int) -> Promise<TS.DumpFunctionResponseBody> {\n        let request = DumpFunction.Request(workspaceId: workspaceId, fileName: filePath, position: position)\n        return processRequest(DumpFunction.self, request).then { $0.function }\n    }\n\n    func generateIdsFiles(moduleName: String, iosHeaderImportPath: String, idFilePath: String) -> Promise<GenerateIdsFilesResult> {\n        let request = GenerateIds.Request(moduleName: moduleName, filePath: idFilePath, iosHeaderImportPath: iosHeaderImportPath)\n        return processRequest(GenerateIds.self, request).then { GenerateIdsFilesResult(android: $0.android,\n                                                                                       iosHeader: $0.iosHeader,\n                                                                                       iosImplementation: $0.iosImplementation,\n                                                                                       typescriptDefinition: $0.typescriptDefinition,\n                                                                                       typescriptImplementation: $0.typescriptImplementation) }\n    }\n\n    func exportAndroidStringsTranslations(moduleName: String, baseLocalePath: String, inputLocalePath: String) -> Promise<ExportTranslationStrings.Response> {\n        let request = ExportTranslationStrings.Request(moduleName: moduleName, baseLocaleStringsPath: baseLocalePath, inputLocaleStringsPath: inputLocalePath, platform: \"android\")\n        return processRequest(ExportTranslationStrings.self, request)\n    }\n\n    func exportIosStringsTranslations(moduleName: String, baseLocalePath: String, inputLocalePath: String) -> Promise<ExportTranslationStrings.Response> {\n        let request = ExportTranslationStrings.Request(moduleName: moduleName, baseLocaleStringsPath: baseLocalePath, inputLocaleStringsPath: inputLocalePath, platform: \"ios\")\n        return processRequest(ExportTranslationStrings.self, request)\n    }\n}\n\nprivate func encodeEnvelope<C: Command>(_ envelope: RequestEnvelope<C>) throws -> Data {\n    do {\n        let encoder = JSONEncoder()\n        encoder.outputFormatting = .sortedKeys\n        let data = try encoder.encode(envelope)\n        return data\n    } catch EncodingError.invalidValue(let value, let context) {\n        try throwEncodeError(\"Invalid value '\\(value)'\", context)\n    } catch {\n        throw error\n    }\n}\n\nprivate func throwEncodeError(_ message: String, _ context: EncodingError.Context) throws -> Never {\n    throw CompilerError(\"Failed to encode companion payload: \\(message) - \\(context.debugDescription)\")\n}\n\nprivate func decodeData<C: Command>(_ data: Data, _ commandType: C.Type) throws -> C.Response {\n    do {\n        let decoder = JSONDecoder()\n        let decoded = try decoder.decode(ResponseEnvelope<C>.self, from: data)\n        return decoded.body\n    } catch DecodingError.dataCorrupted(let context) {\n        try throwDecodeError(\"Data corrupted\", context)\n    } catch DecodingError.keyNotFound(let key, let context) {\n        try throwDecodeError(\"Key '\\(key)' not found:\", context)\n    } catch DecodingError.valueNotFound(let value, let context) {\n        try throwDecodeError(\"Value '\\(value)' not found:\", context)\n    } catch DecodingError.typeMismatch(let type, let context) {\n        try throwDecodeError(\"Type '\\(type)' mismatch:\", context)\n    } catch {\n        throw error\n    }\n}\n\nprivate func throwDecodeError(_ message: String, _ context: DecodingError.Context) throws -> Never {\n    throw CompilerError(\"Failed to decode companion payload: \\(message) - \\(context.debugDescription)\")\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/CompanionExecutableProvider.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nclass CompanionExecutableProvider {\n\n    private let logger: ILogger\n    private var lastCompanionExecutable: CompanionExecutable? = nil\n    private let lock = DispatchSemaphore.newLock()\n\n    init(logger: ILogger) {\n        self.logger = logger\n    }\n\n    func getCompanionExecutable(compilerCompanionBinaryPath: String,\n                                nodeOptions: [String],\n                                logsOutputPath: String?,\n                                compilerCacheURL: URL?,\n                                isBazelBuild: Bool) -> CompanionExecutable {\n        lock.lock {\n            if let lastCompanionExecutable,\n                lastCompanionExecutable.compilerCompanionBinaryPath == compilerCompanionBinaryPath,\n               lastCompanionExecutable.nodeOptions == nodeOptions,\n               lastCompanionExecutable.logsOutputPath == logsOutputPath,\n               lastCompanionExecutable.compilerCacheURL == compilerCacheURL,\n               lastCompanionExecutable.isBazelBuild == isBazelBuild,\n               !lastCompanionExecutable.processExited {\n                return lastCompanionExecutable\n            }\n\n            let companionExecutable = CompanionExecutable(logger: self.logger,\n                                                          compilerCompanionBinaryPath: compilerCompanionBinaryPath,\n                                                          nodeOptions: nodeOptions,\n                                                          logsOutputPath: logsOutputPath,\n                                                          compilerCacheURL: compilerCacheURL,\n                                                          isBazelBuild: isBazelBuild)\n            self.lastCompanionExecutable = companionExecutable\n\n            return companionExecutable\n        }\n    }\n\n    func getCompanionExecutable(compilerConfig: CompilerConfig,\n                                projectConfig: ValdiProjectConfig,\n                                logsOutputPath: String?,\n                                disableTsCompilerCache: Bool,\n                                diskCacheProvider: DiskCacheProvider,\n                                isBazelBuild: Bool) throws -> CompanionExecutable {\n        let compilerCompanionBinaryPath: String\n        var nodeOptions = [String]()\n        let compilerCacheURL: URL?\n        if let directCompanionPath = compilerConfig.directCompanionPath {\n            compilerCompanionBinaryPath = directCompanionPath\n        } else {\n            guard let companionBinaryURL = projectConfig.compilerCompanionBinaryURL else {\n                throw CompilerError(\"Need compiler_companion_bin set in the config.yaml\")\n            }\n            compilerCompanionBinaryPath = companionBinaryURL.path\n            nodeOptions.append(\"--max-old-space-size=4096\")\n            if projectConfig.shouldDebugCompilerCompanion {\n                nodeOptions.append(\"--inspect\")\n            }\n        }\n\n        if !disableTsCompilerCache, let diskCache = diskCacheProvider.newCache(cacheName: \"companion\", outputExtension: \"\", metadata: [:]) {\n            compilerCacheURL = diskCache.getURL().absoluteURL\n        } else {\n            compilerCacheURL = nil\n        }\n\n        return getCompanionExecutable(\n            compilerCompanionBinaryPath: compilerCompanionBinaryPath,\n            nodeOptions: nodeOptions,\n            logsOutputPath: logsOutputPath,\n            compilerCacheURL: compilerCacheURL,\n            isBazelBuild: isBazelBuild)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/JSCodeInstrumentation.swift",
    "content": "import Foundation\n\nstruct InstrumentationFileConfig: Codable {\n    let sourceFilePath: String\n    let fileContent: String\n}\n\nstruct CodeInstrumentationResult: Codable {\n    let sourceFilePath: String\n    let instrumentedFileContent: String\n    let fileCoverage: String\n}\n\nclass JSCodeInstrumentation {\n    private let companion: CompanionExecutable\n\n    init(companion: CompanionExecutable) {\n        self.companion = companion\n    }\n\n    func instrumentFiles(files: [InstrumentationFileConfig]) -> Promise<[CodeInstrumentationResult]> {\n        return companion.instrumentJSFiles(files: files)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/JSDocs.swift",
    "content": "//\n//  JSDocs.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/15/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass JSDocs {\n\n    static let allSymbols: Set<String> = [\n        \"abstract\",\n        \"access\",\n        \"alias\",\n        \"async\",\n        \"augments\",\n        \"author\",\n        \"borrows\",\n        \"callback\",\n        \"class\",\n        \"classdesc\",\n        \"constant\",\n        \"constructs\",\n        \"copyright\",\n        \"default\",\n        \"deprecated\",\n        \"description\",\n        \"enum\",\n        \"event\",\n        \"example\",\n        \"exports\",\n        \"external\",\n        \"file\",\n        \"fires\",\n        \"function\",\n        \"generator\",\n        \"global\",\n        \"hideconstructor\",\n        \"ignore\",\n        \"implements\",\n        \"inheritdoc\",\n        \"inner\",\n        \"instance\",\n        \"interface\",\n        \"kind\",\n        \"lends\",\n        \"license\",\n        \"listens\",\n        \"member\",\n        \"memberof\",\n        \"mixes\",\n        \"mixin\",\n        \"module\",\n        \"name\",\n        \"namespace\",\n        \"override\",\n        \"package\",\n        \"param\",\n        \"private\",\n        \"property\",\n        \"protected\",\n        \"public\",\n        \"readonly\",\n        \"requires\",\n        \"returns\",\n        \"see\",\n        \"since\",\n        \"static\",\n        \"summary\",\n        \"this\",\n        \"throws\",\n        \"todo\",\n        \"tutorial\",\n        \"type\",\n        \"typedef\",\n        \"variation\",\n        \"version\",\n        \"yields\",\n        \"ts-ignore\",\n        \"link\",\n        \"extends\",\n        \"nocollapse\",\n        \"constructor\",\n        \"return\",\n        \"internal\",\n        \"owner\",\n        \"method\"\n    ]\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptAnnotation.swift",
    "content": "//\n//  TypeScriptAnnotation.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/5/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// CharacterSet to use when trimming contents of code comments (e.g. leading \\* treated like whitespace)\nprivate let trimCharSet = CharacterSet.whitespacesAndNewlines.union(CharacterSet(charactersIn: \"*\"))\n\n// Special user-friendly handling for quotes, including unicode quote characters, because\n// we actually had a case where someone used a unicode quotation mark, Ticket: 223\nprivate let asciiQuoteCharSet = CharacterSet(charactersIn: \"\\'\\\"\")\nprivate let unicodeQuoteCharSet = CharacterSet(charactersIn: \"«»‘’‚‛”„‟〝〞＂\")\nprivate let quoteCharSet = asciiQuoteCharSet.union(unicodeQuoteCharSet)\n\n// TODO: rename to `TypeScriptAnnotation`\nstruct ValdiTypeScriptAnnotation {\n\n    let name: String\n    let range: NSRange\n    let parameters: [String: String]?\n    let content: String\n\n    init(name: String, parameters: [String: String]?, range: NSRange, content: String) {\n        self.name = name\n        self.parameters = parameters\n        self.range = range\n        self.content = content\n    }\n\n    private static let annotationRegex = try! NSRegularExpression(pattern: \"@([A-z-]+) *(?:\\\\((?:\\\\{(.*?)\\\\})\\\\))?\", options: [.dotMatchesLineSeparators])\n\n    static func extractAnnotations(comments: TS.AST.Comments, fileContent: String) throws -> [ValdiTypeScriptAnnotation] {\n        let joinedComments = comments.text\n        let matches = Self.annotationRegex.matches(in: joinedComments, options: [], range: joinedComments.nsrange)\n\n        if matches.isEmpty {\n             return []\n        }\n\n        let commentsRange = NSRange(location: comments.start, length: comments.end - comments.start)\n\n        let nsString = comments.text as NSString\n        var annotations = [ValdiTypeScriptAnnotation]()\n\n        for match in matches {\n            let annotationNameRange = match.range(at: 1)\n            let annotationName = nsString.substring(with: annotationNameRange)\n            // Make sure we aren't parsing jsDocs tags as annotations.\n            if JSDocs.allSymbols.contains(annotationName) {\n                continue\n            }\n\n            let annotationRange = match.range(at: 0)\n            let annotationContent = nsString.substring(with: annotationRange)\n\n            let totalRange = NSRange(location: annotationNameRange.lowerBound + commentsRange.lowerBound, length: annotationNameRange.length)\n\n            var parameters: [String: String]?\n\n            let parametersRange = match.range(at: 2)\n            if parametersRange.location != NSNotFound {\n                let rangeInFile = NSRange(location: commentsRange.location + parametersRange.location, length: parametersRange.length)\n                let parametersString = nsString.substring(with: parametersRange)\n                var foundParameters = [String: String]()\n                for property in parametersString.split(separator: \",\") {\n                    let (key, value) = try parseAnnotationKeyValue(property: property,\n                                                                   rangeInFile: rangeInFile,\n                                                                   fileContent: fileContent)\n                    foundParameters[key] = value\n                }\n                parameters = foundParameters\n            }\n\n            annotations.append(ValdiTypeScriptAnnotation(name: annotationName, parameters: parameters, range: totalRange, content: annotationContent))\n        }\n\n        return annotations\n    }\n\n    private static func parseAnnotationKeyValue(property: Substring, rangeInFile: NSRange, fileContent: String) throws -> (key: String, value: String) {\n        guard let separatorIndex = property.firstIndex(of: \":\") else {\n            try throwAnnotationError(message: \"Cannot parse annotation - missing column separator\",\n                                     range: rangeInFile,\n                                     inDocument: fileContent)\n        }\n\n        let key = String(property[..<separatorIndex].trimmingCharacters(in: trimCharSet).unquote)\n        let value = String(property[property.index(separatorIndex, offsetBy: 1)...].trimmingCharacters(in: trimCharSet).unquote)\n\n        let keyOrValueHasQuotes = [key, value].contains(where: { $0.unicodeScalars.contains(where: quoteCharSet.contains) })\n        if keyOrValueHasQuotes {\n            try throwAnnotationError(message: \"Cannot parse annotation - maybe missing/extra/invalid quote character (\\' or \\\")?\",\n                                     range: rangeInFile,\n                                     inDocument: fileContent)\n        }\n\n        return (key, value)\n    }\n\n    private static func throwAnnotationError(message: String, range: NSRange, inDocument: String) throws -> Never {\n        throw CompilerError(type: \"Annotation error\", message: message, range: range, inDocument: inDocument)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptCommands.swift",
    "content": "//\n//  TypeScriptCommands.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/19/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct TS {\n\n    struct AST {\n        struct Comments: Codable {\n            var text: String\n            var start: Int\n            var end: Int\n        }\n\n        struct EnumMember: Codable {\n            var start: Int\n            var end: Int\n            var name: String\n            var numberValue: String?\n            var stringValue: String?\n            var leadingComments: Comments?\n        }\n\n        struct Enum: Codable {\n            var start: Int\n            var end: Int\n            var name: String\n            var members: [EnumMember]\n        }\n\n        struct FunctionType: Codable {\n            var parameters: [PropertyLikeDeclaration]\n            var returnValue: TSType\n        }\n\n        struct TypeArgument: Codable {\n            var type: TSType\n        }\n\n        class TSType: Codable {\n            var name: String\n            var leadingComments: Comments?\n            var function: FunctionType?\n            var unions: [TSType]?\n            var typeReferenceIndex: Int?\n            var array: TSType?\n            var typeArguments: [TypeArgument]?\n            var isTypeParameter: Bool?\n\n            init(name: String, leadingComments: Comments? = nil, function: FunctionType? = nil, unions: [TSType]? = nil, typeReferenceIndex: Int? = nil, array: TSType? = nil, typeArguments: [TypeArgument]? = nil, isTypeParameter: Bool? = nil) {\n                self.name = name\n                self.leadingComments = leadingComments\n                self.function = function\n                self.unions = unions\n                self.typeReferenceIndex = typeReferenceIndex\n                self.array = array\n                self.typeArguments = typeArguments\n                self.isTypeParameter = isTypeParameter\n            }\n        }\n\n        struct PropertyLikeDeclaration: Codable {\n            var start: Int\n            var end: Int\n            var name: String\n            var isOptional: Bool\n            var type: TSType\n            var leadingComments: Comments?\n        }\n\n        struct TypeParameterLikeDeclaration: Codable {\n            var start: Int\n            var end: Int\n            var name: String\n        }\n\n        struct SuperTypeClause: Codable {\n            var start: Int\n            var end: Int\n            var isImplements: Bool\n            var type: TSType\n        }\n\n        struct Interface: Codable {\n            var start: Int\n            var end: Int\n            var name: String\n            var members: [PropertyLikeDeclaration]\n            var typeParameters: [TypeParameterLikeDeclaration]?\n            var supertypes: [SuperTypeClause]?\n        }\n\n        struct Variable: Codable {\n            var start: Int\n            var end: Int\n            var name: String\n            var type: TSType\n            var leadingComments: Comments?\n        }\n\n        struct Function: Codable {\n            var start: Int\n            var end: Int\n            var name: String\n            var type: FunctionType\n            var leadingComments: Comments?\n        }\n\n        struct TypeReference: Codable {\n            var name: String\n            var fileName: String\n        }\n    }\n\n    enum MessageType: String {\n        case request = \"request\"\n        case response = \"response\"\n        case event = \"event\"\n    }\n\n    struct Request<T: Codable>: Codable {\n\n        var type = \"request\"\n\n        var seq: Int = 0\n        var command: String?\n\n        var arguments: T?\n\n        init(command: String, arguments: T?) {\n            self.command = command\n            self.arguments = arguments\n        }\n    }\n\n    struct Response<T: Codable>: Codable {\n\n        var type: String\n        var requestSeq: Int\n        var success: Bool\n        var command: String\n        var message: String?\n\n        var body: T\n    }\n\n    /**\n     * Server-initiated event message\n     */\n    struct Event<T: Codable>: Codable {\n\n        /**\n         * Name of event\n         */\n        var event: String\n\n        /**\n         * Event-specific information\n         */\n        var body: T\n    }\n\n    // Specific requests and responses\n\n    struct StatusResponseBody: Codable {\n\n        var version: String\n\n    }\n\n    struct OpenRequestBody: Codable {\n\n        /**\n         * The file for the request (absolute pathname required).\n         */\n        var file: String\n\n        var fileContent: String?\n        var scriptKindName: String\n        var projectRootPath: String\n        var projectFileName: String?\n\n    }\n\n    struct TextSpan: Codable {\n        /**\n         * First character of the definition.\n         */\n        var start: Location?\n\n        /**\n         * One character past last character of the definition.\n         */\n        var end: Location?\n    }\n\n    struct SimpleTextSpan: Codable {\n        var start: Int?\n        var length: Int?\n    }\n\n    struct CompileOnSaveEmitFileRequestArgs: Codable {\n        /**\n         * The file for the request (absolute pathname required).\n         */\n        var file: String\n\n        /**\n         * if true - then file should be recompiled even if it does not have any changes.\n         */\n        var forced: Bool\n    }\n\n    /**\n     * Arguments for geterr messages.\n     */\n    struct GeterrRequestArgs: Codable {\n        /**\n         * List of file names for which to compute compiler errors.\n         * The files will be checked in list order.\n         */\n        var files: [String]\n\n        /**\n         * Delay in milliseconds to wait before starting to compute\n         * errors for the files in the file list\n         */\n        var delay: Int\n    }\n\n    struct DiagnosticEventBody: Codable {\n        /**\n         * The file for which diagnostic information is reported.\n         */\n        var file: String\n        /**\n         * An array of diagnostic information items.\n         */\n        var diagnostics: [Diagnostic]\n    }\n\n    /**\n     * Item of diagnostic information found in a DiagnosticEvent message.\n     */\n    struct Diagnostic: Codable {\n        /**\n         * Starting file location at which text applies.\n         */\n        var start: Location\n        /**\n         * The last file location at which the text applies.\n         */\n        var end: Location\n        /**\n         * Text of diagnostic message.\n         */\n        var text: String\n        /**\n         * The category of the diagnostic message, e.g. \"error\", \"warning\", or \"suggestion\".\n         */\n        var category: String\n\n        /**\n         * Any related spans the diagnostic may have, such as other locations relevant to an error, such as declarartion sites\n         */\n        var relatedInformation: [DiagnosticRelatedInformation]?\n        /**\n         * The error code of the diagnostic message.\n         */\n        var code: Int?\n        /**\n         * The name of the plugin reporting the message.\n         */\n        var source: String?\n    }\n\n    /**\n     * Location in source code expressed as (one-based) line and (one-based) column offset.\n     */\n    struct Location: Codable {\n        var line: Int\n        var offset: Int\n    }\n\n//    /**\n//     * Object found in response messages defining a span of text in source code.\n//     */\n//    struct TextSpan: Codable {\n//        /**\n//         * First character of the definition.\n//         */\n//        var start: Location\n//        /**\n//         * One character past last character of the definition.\n//         */\n//        var end: Location\n//    }\n\n    struct FileRequestArgs: Codable {\n        var file: String?\n        var projectFileName: String?\n    }\n\n    struct DiagnosticsSyncRequestArgs: Codable {\n        var file: String?\n        var projectFileName: String?\n        var includeLinePosition: Bool?\n    }\n\n    struct FileLocationRequestArgs: Codable {\n\n        var file: String?\n        var projectFileName: String?\n\n        /**\n         * The line number for the request (1-based).\n         */\n        var line: Int?\n        /**\n         * The character offset (on the line) for the request (1-based).\n         */\n        var offset: Int?\n\n        /**\n         The character position\n         */\n        var position: Int?\n    }\n\n    /**\n     * Object found in response messages defining a span of text in source code.\n     */\n    struct FileSpan: Codable {\n\n        /**\n         * First character of the definition.\n         */\n        var start: Location?\n\n        /**\n         * One character past last character of the definition.\n         */\n        var end: Location?\n\n        /**\n         * File containing text span.\n         */\n        var file: String?\n    }\n\n    struct SimpleFileSpan: Codable {\n\n        /**\n         * First character of the definition.\n         */\n        var start: Int?\n\n        /**\n         * One character past last character of the definition.\n         */\n        var end: Int?\n\n        /**\n         * File containing text span.\n         */\n        var file: String?\n    }\n\n    struct TypeDefinition: Codable {\n        var fileName: String\n        var textSpan: SimpleTextSpan\n        var kind: ScriptElementKind\n        var name: String\n    }\n\n    enum OutliningSpanKind: String, Codable {\n        /** Single or multi-line comments */\n        case comment = \"comment\"\n        /** Sections marked by '// #region' and '// #endregion' comments */\n        case region = \"region\"\n        /** Declarations and expressions */\n        case code = \"code\"\n        /** Contiguous blocks of import declarations */\n        case imports = \"imports\"\n    }\n\n    struct OutliningSpan: Codable {\n        /** The span of the document to actually collapse. */\n        var textSpan: TextSpan?\n        /** The span of the document to display when the user hovers over the collapsed span. */\n        var hintSpan: TextSpan?\n        /** The text to display in the editor for the collapsed region. */\n        var bannerText: String?\n        /**\n         * Whether or not this region should be automatically collapsed when\n         * the 'Collapse to Definitions' command is invoked.\n         */\n        var autoCollapse: Bool?\n        /**\n         * Classification of the contents of the span\n         */\n        var kind: OutliningSpanKind?\n    }\n\n    struct DefinitionInfo: Codable {\n\n        /**\n         * First character of the definition.\n         */\n        var start: Int?\n\n        /**\n         * One character past last character of the definition.\n         */\n        var end: Int?\n\n        /**\n         * File containing text span.\n         */\n        var file: String?\n\n        var kind: ScriptElementKind\n        var name: String\n        var containerKind: ScriptElementKind?\n        var containerName: String?\n    }\n\n    struct DefinitionInfoAndBoundSpan: Codable {\n        var definitions: [DefinitionInfo]?\n        var textSpan: SimpleTextSpan?\n    }    \n\n    struct OpenFileImportPath: Codable {\n        var relative: String\n        var absolute: String\n    }\n\n    struct OpenResponseBody: Codable {\n        var importPaths: [OpenFileImportPath]\n    }\n\n    struct RegisterFileResponseBody: Codable {        \n    }\n\n    struct EmittedFile: Codable {\n        var fileName: String\n        var content: String\n    }\n\n    /**\n     * Body of QuickInfoResponse.\n     */\n    struct QuickInfoResponseBody: Codable {\n        /**\n         * The symbol's kind (such as 'className' or 'parameterName' or plain 'text').\n         */\n        var kind: ScriptElementKind?\n\n        var textSpan: SimpleTextSpan?\n\n        /**\n         * Optional modifiers for the kind (such as 'public').\n         */\n        var kindModifiers: String?\n\n        var displayParts: [SymbolDisplayPart]?\n        var documentation: [SymbolDisplayPart]?\n\n        /**\n         * JSDoc tags associated with symbol.\n         */\n        var tags: [JSDocTagInfo]?\n    }\n\n    enum DumpedSymbolNodeType: String, Codable {\n        case `enum`\n        case function\n        case interface\n        case exportedVariable\n    }\n\n    struct DumpedSymbolWithComments: Codable {\n        var nodeType: String\n        var start: Int\n\n        var leadingComments: AST.Comments?\n        var text: String\n        var kind: SyntaxKind\n        var modifiers: [String]?\n\n        var function: AST.Function?\n        var `enum`: AST.Enum?\n        var interface: AST.Interface?\n        var variable: AST.Variable?\n        var exportedTypeAlias: String?\n\n        var kindModifiers: String? {\n            return modifiers?.joined(separator: \" \") // FIXME: just leave it as an array\n        }\n    }\n\n    struct DumpSymbolsWithCommentsResponseBody: Codable {\n        var dumpedSymbols: [DumpedSymbolWithComments]\n        var references: [AST.TypeReference]\n    }\n\n    struct DumpInterfaceResponseBody: Codable {\n        var interface: AST.Interface\n        var references: [AST.TypeReference]\n    }\n\n    struct DumpEnumResponseBody: Codable {\n        var `enum`: AST.Enum\n    }\n\n    struct DumpFunctionResponseBody: Codable {\n        var function: AST.Function\n        var references: [AST.TypeReference]\n    }\n\n    struct NavigationBarItem: Codable {\n\n        /**\n         * The item's display text.\n         */\n        var text: String?\n\n        /**\n         * The symbol's kind (such as 'className' or 'parameterName').\n         */\n        var kind: ScriptElementKind?\n\n        /**\n         * Optional modifiers for the kind (such as 'public').\n         */\n        var kindModifiers: String?\n\n        /**\n         * The definition locations of the item.\n         */\n        var spans: [TextSpan]?\n\n        /**\n         * Optional children.\n         */\n        var childItems: [NavigationBarItem]?\n\n        /**\n         * Number of levels deep this item should appear.\n         */\n        var indent: Int?\n    }\n\n    /** protocol.NavigationTree is identical to ts.NavigationTree, except using protocol.TextSpan instead of ts.TextSpan */\n    struct NavigationTree: Codable {\n        var text: String?\n        var kind: ScriptElementKind?\n        var kindModifiers: String?\n        var spans: [SimpleTextSpan]?\n        var nameSpan: SimpleTextSpan?\n        var childItems: [NavigationTree]?\n    }\n\n    /**\n     * Part of a symbol description.\n     */\n    struct SymbolDisplayPart: Codable {\n        /**\n         * Text of an item describing the symbol.\n         */\n        var text: String?\n        /**\n         * The symbol's kind (such as 'className' or 'parameterName' or plain 'text').\n         */\n        var kind: String?\n    }\n\n    /**\n     * Signature help information for a single parameter\n     */\n    struct SignatureHelpParameter: Codable {\n\n        /**\n         * The parameter's name\n         */\n        var name: String?\n        /**\n         * Documentation of the parameter.\n         */\n        var documentation: [SymbolDisplayPart]?\n        /**\n         * Display parts of the parameter.\n         */\n        var displayParts: [SymbolDisplayPart]?\n        /**\n         * Whether the parameter is optional or not.\n         */\n        var isOptional: Bool?\n    }\n\n    /**\n     * Represents a single signature to show in signature help.\n     */\n    struct SignatureHelpItem: Codable {\n        /**\n         * Whether the signature accepts a variable number of arguments.\n         */\n        var isVariadic: Bool?\n        /**\n         * The prefix display parts.\n         */\n        var prefixDisplayParts: [SymbolDisplayPart]?\n        /**\n         * The suffix display parts.\n         */\n        var suffixDisplayParts: [SymbolDisplayPart]?\n        /**\n         * The separator display parts.\n         */\n        var separatorDisplayParts: [SymbolDisplayPart]?\n        /**\n         * The signature helps items for the parameters.\n         */\n        var parameters: [SignatureHelpParameter]?\n        /**\n         * The signature's documentation\n         */\n        var documentation: [SymbolDisplayPart]?\n\n    }\n\n    /**\n     * Signature help items found in the response of a signature help request.\n     */\n    struct SignatureHelpItems: Codable {\n        /**\n         * The signature help items.\n         */\n        var items: [SignatureHelpItem]?\n        /**\n         * The span for which signature help should appear on a signature\n         */\n        var applicableSpan: TextSpan?\n        /**\n         * The item selected in the set of available help items.\n         */\n        var selectedItemIndex: Int?\n        /**\n         * The argument selected in the set of parameters.\n         */\n        var argumentIndex: Int?\n        /**\n         * The argument count\n         */\n        var argumentCount: Int?\n    }\n\n    /**\n     * Arguments of a signature help request.\n     */\n    struct SignatureHelpRequestArgs: Codable {\n\n        var file: String?\n        var projectFileName: String?\n\n        /**\n         * The line number for the request (1-based).\n         */\n        var line: Int?\n        /**\n         * The character offset (on the line) for the request (1-based).\n         */\n        var offset: Int?\n\n        /**\n         The character position\n         */\n        var position: Int?\n\n        /**\n         * Reason why signature help was invoked.\n         * See each individual possible\n         */\n        var triggerReason: [String: String]?\n    }\n\n    struct ImplementationLocation: Codable {\n        var kind: ScriptElementKind\n        var displayParts: [SymbolDisplayPart]\n    }\n\n    enum SyntaxKind: Int, Codable {\n        case unknown = 0\n        case variableStatement = 243\n        case functionDeclaration = 262\n        case classDeclaration = 263\n        case interfaceDeclaration = 264\n        case typeAliasDeclaration = 265\n        case enumDeclaration = 266\n    }\n\n    enum ScriptElementKind: String, Codable {\n        case unknown = \"\"\n        case warning = \"warning\"\n        /** predefined type (void) or keyword (class) */\n        case keyword = \"keyword\"\n        /** top level script node */\n        case scriptElement = \"script\"\n        /** module foo {} */\n        case moduleElement = \"module\"\n        /** class X {} */\n        case classElement = \"class\"\n        /** var x = class X {} */\n        case localClassElement = \"local class\"\n        /** interface Y {} */\n        case interfaceElement = \"interface\"\n        /** type T = ... */\n        case typeElement = \"type\"\n        /** enum E */\n        case enumElement = \"enum\"\n        case enumMemberElement = \"enum member\"\n        /**\n         * Inside module and script only\n         * const v = ..\n         */\n        case variableElement = \"var\"\n        /** Inside function */\n        case localVariableElement = \"local var\"\n        /**\n         * Inside module and script only\n         * function f() { }\n         */\n        case functionElement = \"function\"\n        /** Inside function */\n        case localFunctionElement = \"local function\"\n        /** class X { [public|private]* foo() {} } */\n        case memberFunctionElement = \"method\"\n        /** class X { [public|private]* [get|set] foo:number; } */\n        case memberGetAccessorElement = \"getter\"\n        case memberSetAccessorElement = \"setter\"\n        /**\n         * class X { [public|private]* foo:number; }\n         * interface Y { foo:number; }\n         */\n        case memberVariableElement = \"property\"\n        /** class X { constructor() { } } */\n        case constructorImplementationElement = \"constructor\"\n        /** interface Y { ():number; } */\n        case callSignatureElement = \"call\"\n        /** interface Y { []:number; } */\n        case indexSignatureElement = \"index\"\n        /** interface Y { new():Y; } */\n        case constructSignatureElement = \"construct\"\n        /** function foo(*Y*: string) */\n        case parameterElement = \"parameter\"\n        case typeParameterElement = \"type parameter\"\n        case primitiveType = \"primitive type\"\n        case label = \"label\"\n        case alias = \"alias\"\n        case constElement = \"const\"\n        case letElement = \"let\"\n        case directory = \"directory\"\n        case externalModuleName = \"external module name\"\n        /**\n         * <JsxTagName attribute1 attribute2={0} />\n         */\n        case jsxAttribute = \"JSX attribute\"\n        /** String literal */\n        case string = \"string\"\n    }\n\n    /**\n     * Represents additional spans returned with a diagnostic which are relevant to it\n     */\n    struct DiagnosticRelatedInformation: Codable {\n        /**\n         * The category of the related information message, e.g. \"error\", \"warning\", or \"suggestion\".\n         */\n        var category: String\n        /**\n         * The code used ot identify the related information\n         */\n        var code: Int\n        /**\n         * Text of related or additional information.\n         */\n        var message: String\n        /**\n         * Associated location\n         */\n        var span: FileSpan?\n    }\n\n    /**\n     * Arguments for reload request.\n     */\n    struct ReloadRequestArgs: Codable {\n        /**\n         * The file for the request (absolute pathname required).\n         */\n        var file: String\n\n        var projectFileName: String?\n\n        /**\n         * Name of temporary file from which to reload file\n         * contents. May be same as file.\n         */\n        var tmpfile: String\n    }\n\n    /**\n     * An item found in a completion response.\n     */\n    struct CompletionEntry: Codable {\n        /**\n         * The symbol's name.\n         */\n        var name: String?\n        /**\n         * The symbol's kind (such as 'className' or 'parameterName').\n         */\n        var kind: ScriptElementKind?\n        /**\n         * Optional modifiers for the kind (such as 'public').\n         */\n        var kindModifiers: String?\n        /**\n         * A string that is used for comparing completion items so that they can be ordered.  This\n         * is often the same as the name but may be different in certain circumstances.\n         */\n        var sortText: String\n        /**\n         * Text to insert instead of `name`.\n         * This is used to support bracketed completions; If `name` might be \"a-b\" but `insertText` would be `[\"a-b\"]`,\n         * coupled with `replacementSpan` to replace a dotted access with a bracket access.\n         */\n        var insertText: String?\n        /**\n         * An optional span that indicates the text to be replaced by this completion item.\n         * If present, this span should be used instead of the default one.\n         * It will be set if the required span differs from the one generated by the default replacement behavior.\n         */\n        var replacementSpan: TextSpan?\n        /**\n         * Indicates whether commiting this completion entry will require additional code actions to be\n         * made to avoid errors. The CompletionEntryDetails will have these actions.\n         */\n        var hasAction: Bool?\n        /**\n         * Identifier (not necessarily human-readable) identifying where this completion came from.\n         */\n        var source: String?\n        /**\n         * If true, this completion should be highlighted as recommended. There will only be one of these.\n         * This will be set when we know the user should write an expression with a certain type and that type is an enum or constructable class.\n         * Then either that enum/class or a namespace containing it will be the recommended symbol.\n         */\n        var isRecommended: Bool?\n    }\n\n    struct JSDocTagInfo: Codable {\n        var name: String\n        var text: String?\n    }\n\n    struct CodeAction: Codable {\n//    /** Description of the code action to display in the UI of the editor */\n//    var description: string;\n//    /** Text changes to apply to each file as part of the code action */\n//    var changes: FileCodeEdit\n//    /** A command is an opaque object that should be passed to `ApplyCodeActionCommandRequestArgs` without modification.  */\n//    commands?: {}[];\n    }\n\n    /**\n     * Additional completion entry details, available on demand\n     */\n    struct CompletionEntryDetails: Codable {\n        /**\n         * The symbol's name.\n         */\n        var name: String\n        /**\n         * The symbol's kind (such as 'className' or 'parameterName').\n         */\n        var kind: ScriptElementKind\n        /**\n         * Optional modifiers for the kind (such as 'public').\n         */\n        var kindModifiers: String\n        /**\n         * Display parts of the symbol (similar to quick info).\n         */\n        var displayParts: [SymbolDisplayPart]\n        /**\n         * Documentation strings for the symbol.\n         */\n        var documentation: [SymbolDisplayPart]?\n        /**\n         * JSDoc tags for the symbol.\n         */\n        var tags: [JSDocTagInfo]?\n        /**\n         * The associated code actions for this entry\n         */\n        var codeActions: [CodeAction]?\n        /**\n         * Human-readable description of the `source` from the CompletionEntry.\n         */\n        var source: [SymbolDisplayPart]?\n    }\n\n    struct CompletionInfo: Codable {\n        var isGlobalCompletion: Bool\n        var isMemberCompletion: Bool\n        var isNewIdentifierLocation: Bool\n        var entries: [CompletionEntry]\n    }\n\n    /**\n     * Represents a file in external project.\n     * External project is project whose set of files, compilation options and open\\close state\n     * is maintained by the client (i.e. if all this data come from .csproj file in Visual Studio).\n     * External project will exist even if all files in it are closed and should be closed explicitly.\n     * If external project includes one or more tsconfig.json/jsconfig.json files then tsserver will\n     * create configured project for every config file but will maintain a link that these projects were created\n     * as a result of opening external project so they should be removed once external project is closed.\n     */\n    struct ExternalFile: Codable {\n        /**\n         * Name of file file\n         */\n        var fileName: String\n        /**\n         * Script kind of the file\n         */\n        var scriptKind: String?\n        /**\n         * Whether file has mixed content (i.e. .cshtml file that combines html markup with C#/JavaScript)\n         */\n        var hasMixedContent: Bool?\n        /**\n         * Content of the file\n         */\n        var content: String?\n    }\n\n    struct ExternalProject: Codable {\n        /**\n         * Project name\n         */\n        var projectFileName: String\n        /**\n         * List of root files in project\n         */\n        var rootFiles: [ExternalFile]\n        /**\n         * Compiler options for the project\n         */\n        var options: CompilerOptions\n\n        /**\n         * Explicitly specified type acquisition for the project\n         */\n        var typeAcquisition: TypeAcquisition?\n    }\n\n    struct TypeAcquisition: Codable {\n        var enableAutoDiscovery: Bool\n        var enable: Bool?\n        var include: [String]?\n        var exclude: [String]?\n    }\n\n    struct PluginImport: Codable {\n        var name: String\n    }\n\n    struct ProjectReference: Codable {\n        /** A normalized path on disk */\n        var path: String\n        /** The path as the user originally wrote it */\n        var originalPath: String?\n        /** True if the output of this reference should be prepended to the output of this project. Only valid for --outFile compilations */\n        var prepend: Bool?\n        /** True if it is intended that this reference form a circularity */\n        var circular: Bool?\n    }\n\n    struct CompilerOptions: Codable {\n        var allowJs: Bool?\n        var allowSyntheticDefaultImports: Bool?\n        var allowUnreachableCode: Bool?\n        var allowUnusedLabels: Bool?\n        var alwaysStrict: Bool?\n        var baseUrl: String?\n        var charset: String?\n        var checkJs: Bool?\n        var declaration: Bool?\n        var declarationDir: String?\n        var disableSizeLimit: Bool?\n        var downlevelIteration: Bool?\n        var emitBOM: Bool?\n        var emitDecoratorMetadata: Bool?\n        var experimentalDecorators: Bool?\n        var forceConsistentCasingInFileNames: Bool?\n        var importHelpers: Bool?\n        var inlineSourceMap: Bool?\n        var inlineSources: Bool?\n        var isolatedModules: Bool?\n        var jsx: String?\n        var lib: [String]?\n        var locale: String?\n        var mapRoot: String?\n        var maxNodeModuleJsDepth: Int?\n        var module: String?\n        var moduleResolution: String?\n        var newLine: String?\n        var noEmit: Bool?\n        var noEmitHelpers: Bool?\n        var noEmitOnError: Bool?\n        var noErrorTruncation: Bool?\n        var noFallthroughCasesInSwitch: Bool?\n        var noImplicitAny: Bool?\n        var noImplicitReturns: Bool?\n        var noImplicitThis: Bool?\n        var noUnusedLocals: Bool?\n        var noUnusedParameters: Bool?\n        var noImplicitUseStrict: Bool?\n        var noLib: Bool?\n        var noResolve: Bool?\n        var out: String?\n        var outDir: String?\n        var outFile: String?\n        var paths: [String: [String]]?\n        var plugins: [PluginImport]?\n        var preserveConstEnums: Bool?\n        var preserveSymlinks: Bool?\n        var project: String?\n        var reactNamespace: String?\n        var removeComments: Bool?\n        var references: [ProjectReference]?\n        var rootDir: String?\n        var rootDirs: [String]?\n        var skipLibCheck: Bool?\n        var skipDefaultLibCheck: Bool?\n        var sourceMap: Bool?\n        var sourceRoot: String?\n        var strict: Bool?\n        var strictNullChecks: Bool?\n        var suppressExcessPropertyErrors: Bool?\n        var suppressImplicitAnyIndexErrors: Bool?\n        var target: String?\n        var traceResolution: Bool?\n        var resolveJsonModule: Bool?\n        var types: [String]?\n        /** Paths used to used to compute primary types search locations */\n        var typeRoots: [String]?\n\n        init() {\n\n        }\n    }\n\n    struct Empty: Codable {\n\n    }\n\n    /**\n     * Arguments for ProjectInfoRequest request.\n     */\n    struct ProjectInfoRequestArgs: Codable {\n        /**\n         * The file for the request (absolute pathname required).\n         */\n        var file: String?\n        var projectFileName: String?\n        /**\n         * Indicate if the file name list of the project is needed\n         */\n        var needFileNameList: Bool\n    }\n\n    /**\n     * Response message body for \"projectInfo\" request\n     */\n    struct ProjectInfo: Codable {\n        /**\n         * For configured project, this is the normalized path of the 'tsconfig.json' file\n         * For inferred project, this is undefined\n         */\n        var configFileName: String\n        /**\n         * The list of normalized file name in the project, including 'lib.d.ts'\n         */\n        var fileNames: [String]?\n        /**\n         * Indicates if the project has a active language service instance\n         */\n        var languageServiceDisabled: Bool?\n    }\n\n    struct TextInsertion: Codable {\n        var newText: String?\n        /** The position in newText the caret should point to after the insertion. */\n        var caretOffset: Int?\n    }\n\n    struct Config: Codable {\n\n        var extends: String?\n        var compilerOptions: CompilerOptions?\n        var files: [String]?\n        var include: [String]?\n        var exclude: [String]?\n\n    }\n\n}\n\nprivate func doParse<T: Codable>(type: T.Type, data: Data) throws -> T {\n    let decoder = Foundation.JSONDecoder()\n    decoder.keyDecodingStrategy = .convertFromSnakeCase\n    return try decoder.decode(type, from: data)\n}\n\nextension TS.Response {\n\n    static func parse(from data: Data) throws -> TS.Response<T> {\n        return try doParse(type: self, data: data)\n    }\n\n}\n\nextension TS.Event {\n\n    static func parse(from data: Data) throws -> TS.Event<T> {\n        return try doParse(type: self, data: data)\n    }\n\n}\n\nextension TS.Config {\n    static func parse(from data: Data) throws -> TS.Config {\n        return try doParse(type: self, data: data)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptCommentedFile.swift",
    "content": "//\n//  TypeScriptAnnotatedSymbol.swift\n//  BlueSocket\n//\n//  Created by Simon Corsin on 5/15/19.\n//\n\nimport Foundation\n\nclass TypeScriptCommentedFile {\n\n    let src: TypeScriptItemSrc\n    let fileContent: String\n    let linesIndexer: LinesIndexer\n\n    let annotatedSymbols: [TypeScriptAnnotatedSymbol]\n    private(set) var references: [TS.AST.TypeReference] = []\n\n    init(src: TypeScriptItemSrc, file: File, dumpedSymbolsResult: TS.DumpSymbolsWithCommentsResponseBody, typeScriptCompiler: TypeScriptCompiler) throws {\n        self.src = src\n        self.fileContent = try file.readString()\n        self.linesIndexer = LinesIndexer(str: fileContent)\n\n        let dumpedSymbolsWithComments = dumpedSymbolsResult.dumpedSymbols\n        self.references = dumpedSymbolsResult.references\n        self.annotatedSymbols = try TypeScriptCommentedFile.resolveSymbolsAndAnnotations(dumpedSymbolsWithComments,\n                                                                                         typeScriptCompiler: typeScriptCompiler,\n                                                                                         fileContent: fileContent)\n    }\n\n    private static func resolveSymbolsAndAnnotations(_ dumpedSymbolWithCommentsResult: [TS.DumpedSymbolWithComments], typeScriptCompiler: TypeScriptCompiler, fileContent: String) throws -> [TypeScriptAnnotatedSymbol] {\n        return try dumpedSymbolWithCommentsResult.map { dumpedSymbol in\n            let annotatedSymbol = TypeScriptAnnotatedSymbol(symbol: dumpedSymbol)\n            if let leadingComments = dumpedSymbol.leadingComments {\n                let annotations = try ValdiTypeScriptAnnotation.extractAnnotations(comments: leadingComments,\n                                                                                      fileContent: fileContent)\n                annotatedSymbol.addAnnotations(annotations)\n\n                if let interface = annotatedSymbol.symbol.interface {\n                    for (idx, member) in interface.members.enumerated() {\n                        guard let memberComments = member.leadingComments else {\n                            continue\n                        }\n                        let memberAnnotations = try ValdiTypeScriptAnnotation.extractAnnotations(comments: memberComments,\n                                                                                                    fileContent: fileContent)\n                        guard !memberAnnotations.isEmpty else {\n                            continue\n                        }\n                        annotatedSymbol.addMemberAnnotations(memberAnnotations, atIndex: idx)\n                    }\n                }\n            }\n\n            return annotatedSymbol\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptCommentedSymbol.swift",
    "content": "import Foundation\n\nclass TypeScriptAnnotatedSymbol {\n    let symbol: TS.DumpedSymbolWithComments\n\n    // All the annotations found in the leading comments\n    private(set) var annotations: [ValdiTypeScriptAnnotation] = []\n\n    // All the annotations found on members, by member index\n    private(set) var memberAnnotations: [Int: [ValdiTypeScriptAnnotation]] = [:]\n\n    init(symbol: TS.DumpedSymbolWithComments) {\n        self.symbol = symbol\n    }\n\n    func addAnnotations(_ annotations: [ValdiTypeScriptAnnotation]) {\n        self.annotations.append(contentsOf: annotations)\n    }\n\n    func addMemberAnnotations(_ memberAnnotations: [ValdiTypeScriptAnnotation], atIndex idx: Int) {\n        self.memberAnnotations[idx, default: []] += memberAnnotations\n    }\n\n    func getAnnotation(_ annotation: String) -> ValdiTypeScriptAnnotation? {\n        return annotations.first(where: { $0.name == annotation })\n    }\n\n    func mergedCommentsWithoutAnnotations() -> String {\n        TypeScriptAnnotatedSymbol.mergedCommentsWithoutAnnotations(fullComments: symbol.leadingComments?.text ?? \"\", annotations: self.annotations)\n    }\n\n    static func mergedCommentsWithoutAnnotations(fullComments: String, annotations: [ValdiTypeScriptAnnotation]) -> String {\n        var commentsString = fullComments\n        for annotation in annotations {\n            commentsString = commentsString.replacingOccurrences(of: annotation.content, with: \"\")\n        }\n\n        let clean = cleanCommentString(commentsString)\n        return clean\n    }\n\n    static private let cleanCommentsCharacterSet = CharacterSet.whitespacesAndNewlines.union(CharacterSet(charactersIn: \"*/\"))\n    static func cleanCommentString(_ comment: String) -> String {\n        let lines = comment\n            .components(separatedBy: CharacterSet.newlines)\n\n        let clean = lines.map { $0.trimmingCharacters(in: cleanCommentsCharacterSet) }\n          .joined(separator: \"\\n\")\n          .trimmed\n\n        return clean\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptCompiler.swift",
    "content": "//\n//  TypeScriptCompiler.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/19/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprivate struct TypeScriptProject {\n\n    let path: String\n    let name: String\n\n}\n\nprivate enum TypeScriptFileStatus {\n    case upToDate\n    case needOpen\n    case needReload\n}\n\nstruct ImportPath {\n    let relative: String\n    let absolute: String\n}\n\nenum EnsureOpenResult {\n    case upToDate\n    case opened(importPaths: [ImportPath])\n}\n\nstruct CompiledTypeScriptFile {\n    let jsFile: JavaScriptFile\n    let declarationFile: FinalFile?\n}\n\nprivate struct TypeScriptFileDiagnostic {\n    let error: CompilerError?\n}\n\nfinal class TypeScriptCompiler {\n    static let configsDirectoryName = \"_configs\"\n    static let baseConfigFileName = \"base.tsconfig.json\"\n    static let workspaceRoot = URL(fileURLWithPath: \"/\")\n\n    private let logger: ILogger\n    private let companion: CompanionExecutable\n    private let driver: TypeScriptCompilerCompanionDriver\n    private let queue = DispatchQueue(label: \"com.snap.valdi.TypeScriptCompiler\")\n\n    private let emitDebug: Bool\n    private let projectConfig: ValdiProjectConfig\n    private let openedFileCache = CompilationCache<Bool>()\n    private let getErrorsCache = CompilationCache<Bool>()\n    private let fileManager: ValdiFileManager\n\n    init(logger: ILogger, \n         companion: CompanionExecutable,\n         projectConfig: ValdiProjectConfig,\n         fileManager: ValdiFileManager,\n         emitDebug: Bool) {\n        self.logger = logger\n        self.companion = companion\n        self.driver = TypeScriptCompilerCompanionDriver(logger: logger, companion: companion)\n        self.projectConfig = projectConfig\n        self.fileManager = fileManager\n        self.emitDebug = emitDebug\n    }\n\n    func initializeWorkspace() -> Promise<Void> {\n        return driver.initializeWorkspace().dispatch(on: queue)\n    }\n\n    func destroyWorkspace() -> Promise<Void> {\n        return driver.destroyWorkspace()\n    }\n\n    private func getFileStatus(filePath: String, compileSequence: CompilationSequence) -> TypeScriptFileStatus {\n        var status = TypeScriptFileStatus.upToDate\n        _ = openedFileCache.getOrUpdate(key: filePath, compileSequence: compileSequence) { (_, previousValue) -> Bool in\n            status = previousValue == nil ? .needOpen : .needReload\n            return true\n        }\n\n        return status\n    }\n\n    private func openFile(filePath: String) -> Promise<TS.OpenResponseBody> {\n        return driver.openFile(filePath: filePath)\n    }\n\n    private func getErrors(filePath: String, compileSequence: CompilationSequence) -> Promise<GetErrorsResult> {\n        var shouldUpdate = false\n        _ = getErrorsCache.getOrUpdate(key: filePath, compileSequence: compileSequence) { _, diagnostics in\n            shouldUpdate = true\n            return true\n        }\n\n        if shouldUpdate {\n            return driver.getErrors(filePath: filePath).then { result -> Promise<GetErrorsResult> in\n                if let error = result.error {\n                    return Promise(error: error)\n                } else {\n                    return Promise(data: result)\n                }\n            }\n        } else {\n            return Promise(data: GetErrorsResult(error: nil, timeTakenMs: 0))\n        }\n    }\n\n    private func saveFile(filePath: String, outputDirURL: URL) -> Promise<CompiledTypeScriptFile> {\n        let logger = self.logger\n        return driver.saveFile(filePath: filePath)\n            .then { (files) throws -> CompiledTypeScriptFile in\n\n                var emittedJsFile: TS.EmittedFile? = nil\n                var emittedDeclarationFile: TS.EmittedFile? = nil\n\n                for file in files {\n                    if file.fileName.hasSuffix(\".js\") {\n                        emittedJsFile = file\n                    } else if file.fileName.hasSuffix(\".d.ts\") {\n                        emittedDeclarationFile = file\n                    }\n                }\n\n                guard let entry = emittedJsFile else {\n                    throw CompilerError(\"Did not receive JS file output\")\n                }\n\n                let relativePath = outputDirURL.relativePath(to: URL(fileURLWithPath: entry.fileName))\n                logger.verbose(\"Compiled and save file \\(relativePath)\")\n                let jsFile = JavaScriptFile(file: .string(entry.content), relativePath: relativePath)\n                let declarationFile = emittedDeclarationFile.map { emittedFile -> FinalFile in\n                    return FinalFile(outputURL: URL(fileURLWithPath: emittedFile.fileName), file: .string(emittedFile.content), platform: nil, kind: .compiledSource)\n                } \n\n                return CompiledTypeScriptFile(jsFile: jsFile, declarationFile: declarationFile)\n\n            }\n            .catch { (error) -> Error in\n                return CompilerError(\"Failed to save file: \\(error.legibleLocalizedDescription)\")\n            }\n    }\n\n    private func stringFromTextSpan(_ textSpan: TS.TextSpan?, in lines: [Substring]) throws -> String {\n        guard let startSpan = textSpan?.start, let endSpan = textSpan?.end else {\n            throw CompilerError(\"Unable to deserialize TextSpan\")\n        }\n\n        guard startSpan.line <= endSpan.line, startSpan.line - 1 < lines.count, endSpan.line - 1 < lines.count else {\n            throw CompilerError(\"TextSpan is out of bounds\")\n        }\n\n        var out = \"\"\n\n        for line in startSpan.line...endSpan.line {\n\n            let adjustedLine = line - 1\n\n            let currentLine = lines[adjustedLine]\n\n            if line == startSpan.line {\n                out += currentLine[currentLine.index(currentLine.startIndex, offsetBy: startSpan.offset - 1)...]\n            } else if line == endSpan.line {\n                out += currentLine[..<currentLine.index(currentLine.startIndex, offsetBy: endSpan.offset - 1)]\n            } else {\n                out += currentLine\n            }\n        }\n\n        return out\n    }\n\n    func dumpSymbolsWithComments(filePath: String) -> Promise<TS.DumpSymbolsWithCommentsResponseBody> {\n        return driver.dumpSymbolsWithComments(filePath: filePath)\n    }\n\n    func dumpInterface(filePath: String, position: Int) -> Promise<TS.DumpInterfaceResponseBody> {\n        return driver.dumpInterface(filePath: filePath, position: position)\n    }\n\n    func dumpEnum(filePath: String, position: Int) -> Promise<TS.DumpEnumResponseBody> {\n        return driver.dumpEnum(filePath: filePath, position: position)\n    }\n\n    func dumpFunction(filePath: String, position: Int) -> Promise<TS.DumpFunctionResponseBody> {\n        return driver.dumpFunction(filePath: filePath, position: position)\n    }\n\n    func register(file: File, filePath: String) -> Promise<Void> {\n        logger.verbose(\"Registering file \\(filePath)\")\n\n        switch file {\n        case .data(let data):\n            let str = String(data: data, encoding: .utf8)!\n            return driver.registerInMemoryFile(filePath: filePath, fileContent: str)\n        case .string(let str):\n            return driver.registerInMemoryFile(filePath: filePath, fileContent: str)\n        case .lazyData(let block):\n            do {\n                let data = try block()\n                let str = String(data: data, encoding: .utf8)!\n                return driver.registerInMemoryFile(filePath: filePath, fileContent: str)\n            } catch let error {\n                return Promise(error: error)\n            }\n        case .url(let url):\n            return driver.registerDiskFile(filePath: filePath, absoluteFileURL: url)\n        }\n    }\n\n    func ensureOpenFile(filePath: String, outputDirURL: URL, compileSequence: CompilationSequence) -> Promise<EnsureOpenResult> {\n        let fileStatus = getFileStatus(filePath: filePath, compileSequence: compileSequence)\n        switch fileStatus {\n        case .needOpen:\n            logger.verbose(\"-- Opening TypeScript File \\(filePath)\")\n            return self.openFile(filePath: filePath).then {\n                return .opened(importPaths: $0.importPaths.map { ImportPath(relative: $0.relative, absolute: $0.absolute) })\n            }\n        case .needReload:\n            logger.verbose(\"-- Reloading TypeScript File \\(filePath)\")\n            return self.openFile(filePath: filePath).then {\n                return .opened(importPaths: $0.importPaths.map { ImportPath(relative: $0.relative, absolute: $0.absolute) })\n            }\n        case .upToDate:\n            return Promise(data: .upToDate)\n        }\n    }\n\n    func checkErrors(filePath: String, compileSequence: CompilationSequence) -> Promise<GetErrorsResult> {\n        return self.getErrors(filePath: filePath, compileSequence: compileSequence)\n    }\n\n    func compile(filePath: String, outputDirURL: URL, compileSequence: CompilationSequence) -> Promise<CompiledTypeScriptFile> {\n        return self.getErrors(filePath: filePath, compileSequence: compileSequence)\n            .then { (_) -> Promise<CompiledTypeScriptFile> in\n                return self.saveFile(filePath: filePath, outputDirURL: outputDirURL)\n            }\n    }\n\n    func compileNative(filePaths: [String], compileSequence: CompilationSequence) -> Promise<[NativeSource]> {\n        return self.driver.compileNative(filePaths: filePaths).then { emittedFile in\n            return emittedFile.map {\n                return NativeSource(relativePath: nil, filename: $0.fileName, file: .string($0.content), groupingIdentifier: $0.fileName, groupingPriority: 0)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptCompilerCompanionDriver.swift",
    "content": "//\n//  TypeScriptCompilerTSServerDriver.swift\n//\n//\n//  Created by saniul on 31/12/2019.\n//\n\nimport Foundation\n\nclass TypeScriptCompilerCompanionDriver: TypeScriptCompilerDriver {\n\n    private let logger: ILogger\n    private let companion: CompanionExecutable\n    private var workspaceId: Int?\n    private var lock = DispatchSemaphore.newLock()\n    private var currentCreateWorkspacePromise: Promise<Int>?\n\n    init(logger: ILogger, companion: CompanionExecutable) {\n        self.logger = logger\n        self.companion = companion\n    }\n\n    func destroyWorkspace() -> Promise<Void> {\n        var workspaceId: Int?\n        lock.lock {\n            workspaceId = self.workspaceId\n            self.workspaceId = nil\n            self.currentCreateWorkspacePromise = nil\n        }\n\n        if let workspaceId {\n            return companion.destroyWorkspace(workspaceId: workspaceId)\n        } else {\n            return Promise(data: Void())\n        }\n    }\n\n    private func onWorkspaceCreated(workspaceId: Int) {\n        logger.trace(\"Created new TypeScript Workspace project with id \\(workspaceId)\")\n        lock.lock {\n            self.workspaceId = workspaceId\n            self.currentCreateWorkspacePromise = nil\n        }\n    }\n\n    @discardableResult func getOrCreateWorkspace<T>(_ completion: @escaping (Int) -> Promise<T>) -> Promise<T> {\n        var workspaceId: Int?\n        var currentCreateWorkspacePromise: Promise<Int>?\n        var needsOnWorkspaceCreatedCallback = false\n\n        lock.lock {\n            if self.workspaceId == nil && self.currentCreateWorkspacePromise == nil {\n                logger.trace(\"Creating TypeScript Workspace project\")\n                self.currentCreateWorkspacePromise = companion.createWorkspace()\n                needsOnWorkspaceCreatedCallback = true\n            }\n\n            workspaceId = self.workspaceId\n            currentCreateWorkspacePromise = self.currentCreateWorkspacePromise\n        }\n\n        if let workspaceId {\n            return completion(workspaceId)\n        }\n\n        if let currentCreateWorkspacePromise {\n            if needsOnWorkspaceCreatedCallback {\n                // We register the then() outside of the lock(), to prevent deadlocks where the createWorkspace() promise\n                // resolves almost immediately while we have the lock() acquired\n                currentCreateWorkspacePromise.then { [weak self] workspaceId in\n                    self?.onWorkspaceCreated(workspaceId: workspaceId)\n                    return workspaceId\n                }\n            }\n\n            return currentCreateWorkspacePromise.then(completion)\n        }\n\n        fatalError(\"Should have either a workspaceId or a pending create workspace promise\")\n    }\n\n    func initializeWorkspace() -> Promise<Void> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.initializeWorkspace(workspaceId: workspaceId)\n        }\n    }\n\n    func registerInMemoryFile(filePath: String, fileContent: String) -> Promise<Void> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.registerInMemoryFile(workspaceId: workspaceId, filePath: filePath, fileContent: fileContent)\n        }\n    }\n\n    func registerDiskFile(filePath: String, absoluteFileURL: URL) -> Promise<Void> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.registerDiskFile(workspaceId: workspaceId, filePath: filePath, absoluteFileURL: absoluteFileURL)\n        }\n    }\n\n    func openFile(filePath: String) -> Promise<TS.OpenResponseBody> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.openFile(workspaceId: workspaceId, filePath: filePath)\n        }\n    }\n\n    func saveFile(filePath: String) -> Promise<[TS.EmittedFile]> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.saveFile(workspaceId: workspaceId, filePath: filePath)\n        }\n    }\n\n    func compileNative(filePaths: [String]) -> Promise<[TS.EmittedFile]> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.compileNative(workspaceId: workspaceId, stripIncludePrefix: \"\", inputFiles: filePaths)\n        }\n    }\n\n    func getErrors(filePath: String) -> Promise<GetErrorsResult> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.getErrors(workspaceId: workspaceId, filePath: filePath)\n        }\n    }\n\n    func dumpSymbolsWithComments(filePath: String) -> Promise<TS.DumpSymbolsWithCommentsResponseBody> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.dumpSymbolsWithComments(workspaceId: workspaceId, filePath: filePath)\n        }\n    }\n\n    func dumpInterface(filePath: String, position: Int) -> Promise<TS.DumpInterfaceResponseBody> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.dumpInterface(workspaceId: workspaceId, filePath: filePath, position: position)\n        }\n    }\n\n    func dumpFunction(filePath: String, position: Int) -> Promise<TS.DumpFunctionResponseBody> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.dumpFunction(workspaceId: workspaceId, filePath: filePath, position: position)\n        }\n    }\n\n    func dumpEnum(filePath: String, position: Int) -> Promise<TS.DumpEnumResponseBody> {\n        return getOrCreateWorkspace { workspaceId in\n            return self.companion.dumpEnum(workspaceId: workspaceId, filePath: filePath, position: position)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptCompilerDriver.swift",
    "content": "//\n//  TypeScriptCompilerTSServerDriver.swift\n//  \n//\n//  Created by saniul on 31/12/2019.\n//\n\nimport Foundation\n\nprotocol TypeScriptCompilerDriver {\n    func initializeWorkspace() -> Promise<Void>\n\n    func registerInMemoryFile(filePath: String, fileContent: String) -> Promise<Void>\n\n    func registerDiskFile(filePath: String, absoluteFileURL: URL) -> Promise<Void>\n\n    func openFile(filePath: String) -> Promise<TS.OpenResponseBody>\n\n    func getErrors(filePath: String) -> Promise<GetErrorsResult>\n\n    func saveFile(filePath: String) -> Promise<[TS.EmittedFile]>\n\n    func compileNative(filePaths: [String]) -> Promise<[TS.EmittedFile]>\n\n    func dumpSymbolsWithComments(filePath: String) -> Promise<TS.DumpSymbolsWithCommentsResponseBody>\n\n    func dumpInterface(filePath: String, position: Int) -> Promise<TS.DumpInterfaceResponseBody>\n\n    func dumpEnum(filePath: String, position: Int) -> Promise<TS.DumpEnumResponseBody>\n\n    func dumpFunction(filePath: String, position: Int) -> Promise<TS.DumpFunctionResponseBody>\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptFile.swift",
    "content": "//\n//  TypeScriptFile.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/23/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct TypeScriptFile {\n\n    let url: URL\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptGenerator.swift",
    "content": "//\n//  TypeScriptGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/29/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct TypeScriptResult {\n\n    var typeScript: String\n}\n\nfileprivate extension String {\n\n    var escapingQuotesAndNewlines: String {\n        return replacingOccurrences(of: \"'\", with: \"\\\\'\").replacingOccurrences(of: \"\\n\", with: \"\\\\n\")\n    }\n\n}\n\nfinal class TypeScriptGenerator {\n\n    private let logger: ILogger\n    private let elements: ValdiJSElement\n    private let customComponentClass: String?\n    private let actions: [ValdiAction]\n    private let useLegacyActions: Bool\n    private let hasUserScript: Bool\n    private let sourceURL: URL\n    private let symbolsToImport: [TypeScriptSymbol]\n    private let emitDebug: Bool\n    private let cssModulePath: String?\n\n    private let nameAllocator = PropertyNameAllocator()\n    private let nodePrototypesSection = CodeWriter()\n    private let importSection = CodeWriter()\n    private var importedComponents: [ComponentPath: String] = [:]\n\n    init(logger: ILogger, customComponentClass: String?, elements: ValdiJSElement, actions: [ValdiAction], useLegacyActions: Bool, hasUserScript: Bool, sourceURL: URL, symbolsToImport: [TypeScriptSymbol], emitDebug: Bool, cssModulePath: String?) {\n        self.logger = logger\n        self.customComponentClass = customComponentClass\n        self.elements = elements\n        self.actions = actions\n        self.useLegacyActions = useLegacyActions\n        self.hasUserScript = hasUserScript\n        self.sourceURL = sourceURL\n        self.symbolsToImport = symbolsToImport\n        self.emitDebug = emitDebug\n        self.cssModulePath = cssModulePath\n    }\n\n    private func resolvePreviousSiblingRenderIfResults(element: ValdiJSElement, parent: ValdiJSElement?) -> [String] {\n        guard let parent = parent,\n              let onlyElementChildren = parent.children.compactMap({ $0.element }).nonEmpty,\n              let index = onlyElementChildren.firstIndex(where: { $0 === element }), index > 0 else {\n             return []\n         }\n\n        let previousElement = onlyElementChildren[index - 1]\n\n        var resultVars = [String]()\n        if previousElement.renderElseIfExpr != nil {\n            // This previous element also depends on previous siblings, we need to resolve them as well\n            resultVars += resolvePreviousSiblingRenderIfResults(element: previousElement, parent: parent)\n        }\n\n        resultVars.append(TypeScriptGenerator.makePrivateVar(named: TypeScriptGenerator.renderIfResultName, forId: previousElement.id))\n\n        return resultVars\n    }\n\n    private func appendDebugLine(context: String, attribute: ValdiJSAttribute, lines: inout [String]) {\n        // TODO(simon): Not supported currently in new renderer, see whether we should re-introduce it\n\n//        guard let debugInfo = attribute.debugInfo, emitDebug else {\n//            return\n//        }\n//\n//        lines.append(\"renderer.willEvaluate('\\(context.escapingQuotesAndNewlines)', '\\(attribute.value.escapingQuotesAndNewlines)', \\(debugInfo.line + 1), \\(debugInfo.column));\")\n    }\n\n    private func toPropertyList(dict: [String: String]) -> String {\n        if dict.isEmpty {\n            return \"[]\"\n        }\n\n        let keyValues = dict.sorted(by: { $0 < $1 })\n\n        let body = keyValues.map { \"\\n  '\\($0)', \\($1)\" }.joined(separator: \",\")\n        return \"[\\(body)\\n]\"\n    }\n\n    private func makeClassName(fileName: String, suffix: String) -> String {\n        let name = fileName.split(separator: \"/\").last!.split(separator: \".\").first!.pascalCased\n        return nameAllocator.allocate(property: name + suffix).description\n    }\n\n    private func importComponent(componentPath: ComponentPath) throws -> String {\n        if let variableName = importedComponents[componentPath] {\n            return variableName\n        }\n\n        let moduleVariableName = makeClassName(fileName: componentPath.fileName, suffix: \"\")\n\n        importSection.appendBody(\"import * as \\(moduleVariableName) from '\\(componentPath.fileName)';\\n\")\n\n        let resolvedVariableName = \"\\(moduleVariableName).\\(componentPath.exportedMember)\"\n        importedComponents[componentPath] = resolvedVariableName\n        return resolvedVariableName\n    }\n\n    private func makeSetAttributeStatement(evalOnceCheck: String, setAttributeStatement: String, evaluateOnce: Bool) -> String {\n        if evaluateOnce {\n            return \"\"\"\n                if (!renderer.\\(evalOnceCheck)) {\n                renderer.\\(setAttributeStatement);\n                }\n                \"\"\"\n        } else {\n            return \"renderer.\\(setAttributeStatement);\"\n        }\n    }\n\n    private func generateRenderTemplateInnerBody(element: ValdiJSElement, parent: ValdiJSElement?, key: String?) throws -> [String] {\n        var resolvedAttributes = element.attributes\n\n        var staticProperties: [String: String] = [:]\n        staticProperties[\"tag\"] = \"'\\(element.nodeType)'\"\n        if !element.id.hasPrefix(\"!\") {\n            staticProperties[\"id\"] = \"'\\(element.id)'\"\n\n            if resolvedAttributes.contains(where: { $0.attribute == \"ref\" }) {\n                throw CompilerError(\"Cannot use both id and ref attribute on the same element\")\n            }\n\n            resolvedAttributes.append(ValdiJSAttribute(attribute: \"ref\", value: \"this.elementRefs['\\(element.id)']\", valueIsExpr: true, evaluateOnce: false, isViewModelField: false, debugInfo: nil))\n        }\n\n        if cssModulePath != nil {\n            staticProperties[\"cssDocument\"] = \"__cssDocument\"\n        }\n\n        var componentClassToSet: String?\n        var componentRefToSet: String?\n        var componentPathToSet: String?\n        var onCreateCallback: String?\n        var onDestroyCallback: String?\n\n        var lines = [String]()\n        var elementLines = [String]()\n\n        for attribute in resolvedAttributes {\n            if attribute.attribute == \"componentHandler\" {\n                throw CompilerError(\"componentHandler was removed, please use the componentClass attribute instead and provide the constructor for the component directly\")\n            }\n\n            if attribute.isViewModelField {\n                let setAttributeStatement = \"setViewModelProperty('\\(attribute.attribute)', \\(attribute.value))\"\n                let evalOnceCheck = \"hasViewModelProperty('\\(attribute.attribute)')\"\n\n                elementLines.append(makeSetAttributeStatement(evalOnceCheck: evalOnceCheck, setAttributeStatement: setAttributeStatement, evaluateOnce: attribute.evaluateOnce))\n            } else if !attribute.valueIsExpr {\n                if attribute.attribute == \"onCreate\" {\n                    onCreateCallback = attribute.value\n                    continue\n                }\n                if attribute.attribute == \"onDestroy\" {\n                    onDestroyCallback = attribute.value\n                    continue\n                }\n\n                let node = Valdi_NodeAttribute(logger: logger, name: attribute.attribute, value: attribute.value)\n\n                let exprRepresentation: String\n                switch node.type {\n                case .nodeAttributeTypeDouble:\n                    exprRepresentation = \"\\(node.doubleValue)\"\n                case .nodeAttributeTypeInt:\n                    exprRepresentation = \"\\(node.intValue)\"\n                case .nodeAttributeTypeString:\n                    exprRepresentation = \"'\\(attribute.value.escapingQuotesAndNewlines)'\"\n                case .UNRECOGNIZED:\n                    continue\n                }\n\n                if attribute.attribute == \"context\" {\n                    elementLines.append(\"\"\"\n                                          if (!renderer.hasContext()) {\n                                              renderer.setContext(\\(exprRepresentation));\n                                          }\n                                          \"\"\")\n                } else {\n                    staticProperties[attribute.attribute] = exprRepresentation\n                }\n            } else if element.slotName != nil {\n                staticProperties[attribute.attribute] = attribute.value\n            } else {\n                if attribute.attribute == \"componentClass\" {\n                    componentClassToSet = attribute.value\n                } else if attribute.attribute == \"componentRef\" {\n                    componentRefToSet = attribute.value\n                } else if attribute.attribute == \"componentPath\" {\n                    componentPathToSet = attribute.value\n                } else if attribute.attribute == \"onCreate\" {\n                    onCreateCallback = attribute.value\n                } else if attribute.attribute == \"onDestroy\" {\n                    onDestroyCallback = attribute.value\n                } else {\n                    appendDebugLine(context: \"attribute '\\(attribute.attribute)'\", attribute: attribute, lines: &elementLines)\n\n                    if attribute.attribute == \"viewModel\" {\n                        if attribute.evaluateOnce {\n                            throw CompilerError(\"once: is not supported on viewModel attribute\")\n                        }\n                        elementLines.append(\"renderer.setViewModelProperties(\\(attribute.value));\")\n                    } else if attribute.attribute == \"context\" {\n                        elementLines.append(\"\"\"\n                        if (!renderer.hasContext()) {\n                            renderer.setContext(\\(attribute.value));\n                        }\n                        \"\"\")\n                    } else {\n                        let evalOnceCheck: String\n                        let setAttributeStatement: String\n\n                        if element.componentPath != nil && parent != nil {\n                            evalOnceCheck = \"hasInjectedAttribute('$\\(attribute.attribute)')\"\n                            setAttributeStatement = \"setInjectedAttribute('$\\(attribute.attribute)', \\(attribute.value))\"\n                        } else {\n                            evalOnceCheck = \"hasAttribute('\\(attribute.attribute)')\"\n                            setAttributeStatement = \"setAttribute('\\(attribute.attribute)', \\(attribute.value))\"\n                        }\n\n                        elementLines.append(makeSetAttributeStatement(evalOnceCheck: evalOnceCheck, setAttributeStatement: setAttributeStatement, evaluateOnce: attribute.evaluateOnce))\n                    }\n                }\n            }\n        }\n\n        let isComponent = element.componentPath != nil || componentClassToSet != nil || componentPathToSet != nil\n\n        let startRenderLine: String\n        let endRenderLine: String\n\n        if let slotName = element.slotName {\n            if let refExpr = element.slotRefExpr {\n                startRenderLine = \"renderer.renderNamedSlot('\\(slotName)', this, \\(refExpr));\"\n            } else {\n                startRenderLine = \"renderer.renderNamedSlot('\\(slotName)', this);\"\n            }\n            endRenderLine = \"\"\n        } else if isComponent, parent != nil {\n            let variableName: String\n            if let componentPath = element.componentPath {\n                variableName = try importComponent(componentPath: componentPath)\n            } else if let componentPathToSet = componentPathToSet {\n                variableName = componentPathToSet\n            } else {\n                variableName = componentClassToSet!\n            }\n\n            for (attributeName, attributeValue) in staticProperties.sorted(by: { $0 < $1 }) {\n                elementLines.append(\"renderer.setInjectedAttribute('$\\(attributeName)', \\(attributeValue));\")\n            }\n            staticProperties.removeAll()\n\n            var beginComponentParameters = [variableName, key, componentRefToSet]\n            let beginComponentFunction: String\n            if componentPathToSet != nil {\n                beginComponentParameters = [\"require\"] + beginComponentParameters\n                beginComponentFunction = \"beginComponentFromPath\"\n            } else {\n                beginComponentFunction = \"beginComponentWithoutPrototype\"\n            }\n            let beginComponentParametersStr = beginComponentParameters.map { $0 ?? \"undefined\" }.joined(separator: \", \")\n            startRenderLine = \"renderer.\\(beginComponentFunction)(\\(beginComponentParametersStr));\"\n\n            if let onCreateCallback = onCreateCallback {\n                elementLines.append(\"renderer.setComponentOnCreateObserver(\\(onCreateCallback));\")\n            }\n            if let onDestroyCallback = onDestroyCallback {\n                elementLines.append(\"renderer.setComponentOnDestroyObserver(\\(onDestroyCallback));\")\n            }\n\n            endRenderLine = \"renderer.endComponent();\"\n        } else {\n            let nodePrototypeVariableName = \"__node\\(nameAllocator.allocate(property: element.nodeType))\"\n\n             if let key = key {\n                 startRenderLine = \"renderer.beginRender(\\(nodePrototypeVariableName), \\(key));\"\n             } else {\n                 startRenderLine = \"renderer.beginRender(\\(nodePrototypeVariableName));\"\n             }\n             endRenderLine = \"renderer.endRender();\"\n\n            let nodeType: String\n            if let jsxName = element.jsxName {\n                nodeType = jsxName\n            } else {\n                nodeType = \"custom-view\"\n                if let androidViewClass = element.androidViewClass {\n                    staticProperties[\"androidClass\"] = \"'\\(androidViewClass)'\"\n                }\n                if let iosViewClass = element.iosViewClass {\n                    staticProperties[\"iosClass\"] = \"'\\(iosViewClass)'\"\n                }\n                if let webViewClass = element.webViewClass {\n                    staticProperties[\"webClass\"] = \"'\\(webViewClass)'\"\n                }\n                if let macosViewClass = element.macosViewClass {\n                    staticProperties[\"macosClass\"] = \"'\\(macosViewClass)'\"\n                }\n            }\n\n            let staticPropertiesContent = toPropertyList(dict: staticProperties)\n\n            nodePrototypesSection.appendBody(\"const \\(nodePrototypeVariableName) = renderer.makeNodePrototype('\\(nodeType)', \\(staticPropertiesContent));\\n\")\n        }\n\n        var shouldRenderExprs = [String]()\n\n        // Get the previous expression in the if-else chain of elements, if there is one.\n        var renderConditional = element.renderIfExpr\n        if let renderElseIfExpr = element.renderElseIfExpr {\n            let dependentRenderIfResults = resolvePreviousSiblingRenderIfResults(element: element, parent: parent)\n            for dependentRenderIfResult in dependentRenderIfResults {\n                shouldRenderExprs.append(\"!\\(dependentRenderIfResult)\")\n            }\n\n            renderConditional = renderElseIfExpr\n        }\n\n        // Construct the custom render-if expression for this element if applicable.\n        if let renderIf = renderConditional {\n            let renderIfExpr = \"!(!(\\(renderIf.value)))\"\n            let shouldRenderExpr = renderIfExpr\n\n            appendDebugLine(context: \"renderIf\", attribute: renderIf, lines: &lines)\n\n            shouldRenderExprs.append(shouldRenderExpr)\n        }\n\n        let childrenElementLines = try element.children.flatMap { try generateRenderTemplateBody(node: $0, parent: element) }\n        let hasRenderIf = !shouldRenderExprs.isEmpty\n\n        if hasRenderIf {\n            let renderIfResultVar = TypeScriptGenerator.makePrivateVar(named: TypeScriptGenerator.renderIfResultName, forId: element.id)\n            lines.append(\"const \\(renderIfResultVar) = \\(shouldRenderExprs.joined(separator: \" && \"));\")\n\n            lines.append(\"if (\\(renderIfResultVar)) {\")\n            lines.append(startRenderLine)\n            lines += elementLines\n            lines += childrenElementLines\n            lines.append(endRenderLine)\n            lines.append(\"}\")\n        } else {\n            lines.append(startRenderLine)\n            lines += elementLines\n            lines += childrenElementLines\n            lines.append(endRenderLine)\n        }\n\n        return lines\n    }\n\n    private func resolveForEachExpr(forEachExpr: String) -> String {\n        if forEachExpr.hasPrefix(\"const \") || forEachExpr.hasPrefix(\"let \") {\n            return forEachExpr\n        }\n        return \"const \\(forEachExpr)\"\n    }\n\n    private func generateRenderTemplateBody(node: ValdiJSNode, parent: ValdiJSElement?) throws -> [String] {\n        switch node {\n        case let .expression(expression):\n            return try generateRenderTemplateBody(expression: expression, parent: parent)\n        case let .element(element):\n            return try generateRenderTemplateBody(element: element, parent: parent)\n        }\n    }\n\n    private func generateRenderTemplateBody(expression: ValdiJSExpression, parent: ValdiJSElement?) throws -> [String] {\n        return [ expression.expression ]\n    }\n\n    private func generateRenderTemplateBody(element: ValdiJSElement, parent: ValdiJSElement?) throws -> [String] {\n        var lines = [String]()\n\n        if let forEachExpr = element.forEachExpr {\n            let indexVar = TypeScriptGenerator.makePrivateVar(named: \"index\", forId: element.id)\n\n            lines.append(\"\"\"\n                let \\(indexVar) = 0;\n                \"\"\")\n\n            appendDebugLine(context: \"forEach\", attribute: forEachExpr, lines: &lines)\n\n            var keyLines = [String]()\n            let forEachKeyExpr: String\n            if let forEachKey = element.forEachKey {\n                forEachKeyExpr = forEachKey.value\n                appendDebugLine(context: \"forEach key\", attribute: forEachKey, lines: &keyLines)\n            } else {\n                forEachKeyExpr = indexVar\n            }\n\n            let keyName = nameAllocator.allocate(property: \"__key\")\n\n            let keySelector = \"const \\(keyName) = (\\(forEachKeyExpr)).toString();\"\n\n            let elementLines = try generateRenderTemplateInnerBody(element: element, parent: parent, key: keyName.name)\n\n            keyLines.append(keySelector)\n\n            let resolvedForEachExpr = resolveForEachExpr(forEachExpr: forEachExpr.value)\n            lines.append(\"\"\"\n                for (\\(resolvedForEachExpr)) {\n                    \\(keyLines.joined(separator: \"\\n\"))\n                    \\(elementLines.joined(separator: \"\\n\"))\n                    \\(indexVar) += 1;\n                }\n                \"\"\")\n        } else {\n            if let key = element.forEachKey {\n                lines += try generateRenderTemplateInnerBody(element: element, parent: parent, key: key.value)\n            } else {\n                lines += try generateRenderTemplateInnerBody(element: element, parent: parent, key: nil)\n            }\n        }\n\n        if let slotName = element.insertInSlotName {\n            lines.insert(\"renderer.setNamedSlot('\\(slotName)', () => {\", at: 0)\n            lines.append(\"});\")\n        }\n\n        return lines\n    }\n\n    private func generateRenderTemplate(functionName: String, className: String) throws -> String {\n        let renderTemplateBody = try generateRenderTemplateBody(element: elements, parent: nil).joined(separator: \"\\n\")\n\n        return \"\"\"\n        function \\(functionName)(this: \\(className)) {\n        const viewModel = this.viewModel;\n        const state = this.state;\n\n        \\(renderTemplateBody)\n        }\n        \"\"\"\n    }\n\n    private func extractAllUserProvidedIds(element: ValdiJSElement, out: inout Set<String>) {\n        if !element.id.hasPrefix(\"!\") {\n            out.insert(element.id)\n        }\n        element.children.compactMap { $0.element }.forEach { extractAllUserProvidedIds(element: $0, out: &out) }\n    }\n\n    private func generateElementInitializer(element: ValdiJSElement) -> String {\n        var allIds: Set<String> = []\n\n        extractAllUserProvidedIds(element: element, out: &allIds)\n\n        let ids = allIds.map { \"'\\($0)'\" }.sorted()\n        return \"[\\(ids.joined(separator: \", \"))]\"\n    }\n\n    private func generateComponentSetup(className: String, renderTemplateArgument: String) throws -> String {\n        let out = CodeWriter()\n\n        let resolvedClassName: String\n        if className == JSConstants.autoImportedComponentIdentifier {\n            resolvedClassName = makeClassName(fileName: self.elements.componentPath?.fileName ?? \"Function\", suffix: \"Component\")\n            out.appendBody(\"class \\(resolvedClassName) extends \\(JSConstants.autoImportedComponentIdentifier) {}\\n\")\n        } else {\n            resolvedClassName = className\n        }\n\n        guard let rootPath = self.elements.componentPath else {\n            throw CompilerError(\"Missing componentPath on root element\")\n        }\n\n        let elementByIdBody = generateElementInitializer(element: elements)\n\n        out.appendBody(\"\"\"\n        export const \\(rootPath.exportedMember) = \\(resolvedClassName);\n\n        const elements: ElementsSpecs = \\(elementByIdBody);\n        LegacyVueComponent.setup(\\(rootPath.exportedMember), elements, \\(renderTemplateArgument));\n        \"\"\")\n\n        return out.content\n    }\n\n    private func generateRequires() -> String {\n        // TODO(3521): Update to valdi_core\n        var baseRequires = \"\"\"\n        import { LegacyVueComponent, ElementsSpecs } from 'valdi_core/src/Valdi';\n        import * as JSX from 'valdi_core/src/JSX';\n        import { PropertyList } from 'valdi_core/src/utils/PropertyList';\n        import { ValdiRuntime } from 'valdi_core/src/ValdiRuntime';\n        declare const runtime: ValdiRuntime;\n\n        const renderer = JSX.jsx;\n        \"\"\"\n\n        if !symbolsToImport.isEmpty {\n            let symbolsByDefault = self.symbolsToImport.groupBy { (symbol) -> Bool in\n                return symbol.isDefault\n            }\n\n            let defaultImport = symbolsByDefault[true]?.map { $0.symbol }.joined(separator: \", \")\n            let regularImport = symbolsByDefault[false]?.map { $0.symbol }.joined(separator: \", \")\n\n            let allImports = [defaultImport, regularImport.map { \"{ \\($0) }\" }].compactMap { $0 }.joined(separator: \", \")\n\n            baseRequires += \"\\nimport \\(allImports) from './\\(sourceURL.lastPathComponent)';\"\n        }\n\n        return baseRequires\n    }\n\n    func generate() throws -> TypeScriptResult? {\n        let viewClassName = self.customComponentClass ?? JSConstants.autoImportedComponentIdentifier\n\n        if let cssModulePath = self.cssModulePath {\n            importSection.appendBody(\"import { getNativeModule as __getNativeModule } from 'valdi_core/src/CSSModule';\\n\")\n            nodePrototypesSection.appendBody(\"const __cssDocument = __getNativeModule('\\(cssModulePath)');\\n\")\n        }\n        importSection.appendBody(\"import { RequireFunc } from 'valdi_core/src/ModuleLoader';\\n\")\n        importSection.appendBody(\"declare const require: RequireFunc;\\n\")\n\n        let renderTemplateFunctionName = \"renderTemplate\"\n        let renderTemplateFunction = try generateRenderTemplate(functionName: renderTemplateFunctionName, className: viewClassName)\n\n        if renderTemplateFunction.isEmpty && !hasUserScript {\n            return nil\n        }\n\n        let requires = generateRequires()\n\n        let setupBody = try generateComponentSetup(className: viewClassName, renderTemplateArgument: renderTemplateFunctionName)\n\n        let generatedScript = ([requires, importSection.content, nodePrototypesSection.content, renderTemplateFunction, setupBody] ).joined(separator: \"\\n\").indented\n\n        return TypeScriptResult(typeScript: generatedScript)\n    }\n\n    class func objectFunctionName(fromActionFunctionName actionFunctionName: String) -> String {\n        return String(actionFunctionName.split(separator: \"_\").last!)\n    }\n\n    static let renderIfResultName = \"renderIfResult\"\n\n    class func makePrivateVar(named name: String, forId id: String) -> String {\n        return \"__\\(name)\\(id.pascalCased)\"\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptIntermediateUtils.swift",
    "content": "//\n//  TypeScriptIntermediateUtils.swift\n//  \n//\n//  Created by Simon Corsin on 3/23/20.\n//\n\nimport Foundation\n\nclass TypeScriptIntermediateUtils {\n\n    /**\n     Emits a generated JS file along with its type definition.\n     It will also ensure the type definition is available in the generated ts directory\n     so that the IDE can pick it up.\n     */\n    static func emitGeneratedJs(fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, bundleInfo: CompilationItem.BundleInfo, outputTarget: OutputTarget, jsOutputPath: String, jsContent: File, tsDefinitionOutputPath: String, tsDefinitionContent: File) throws -> [CompilationItem] {\n        let emittedJsSourceURL = bundleInfo.absoluteURL(forRelativeProjectPath: jsOutputPath)\n\n        // Emit an item for our generated JS module\n        let jsFile = JavaScriptFile(file: jsContent, relativePath: jsOutputPath)\n        let emittedJsItem = CompilationItem(sourceURL: emittedJsSourceURL, relativeProjectPath: jsOutputPath, kind: .javaScript(jsFile), bundleInfo: bundleInfo, platform: nil, outputTarget: outputTarget)\n\n        // Emit an item for the type definition\n\n        let emittedTsSourceURL = bundleInfo.absoluteURL(forRelativeProjectPath: tsDefinitionOutputPath)\n        let emittedTsItem = CompilationItem(sourceURL: emittedTsSourceURL, relativeProjectPath: tsDefinitionOutputPath, kind: .typeScript(tsDefinitionContent, emittedTsSourceURL), bundleInfo: bundleInfo, platform: nil, outputTarget: outputTarget)\n\n        // Save the type declaration file to have autocompletion in VSCode\n        let tsData = try tsDefinitionContent.readData()\n\n        let definitionURL = projectConfig.generatedTsDirectoryURL.appendingPathComponent(tsDefinitionOutputPath)\n        try fileManager.save(data: tsData, to: definitionURL)\n\n        return [\n            emittedJsItem,\n            emittedTsItem\n        ]\n    }\n\n    static func emitGeneratedJs(fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, sourceItem: CompilationItem, jsOutputPath: String, jsContent: File, tsDefinitionOutputPath: String, tsDefinitionContent: File) throws -> [CompilationItem] {\n        return try emitGeneratedJs(fileManager: fileManager,\n                                   projectConfig: projectConfig,\n                                   bundleInfo: sourceItem.bundleInfo,\n                                   outputTarget: sourceItem.outputTarget,\n                                   jsOutputPath: jsOutputPath,\n                                   jsContent: jsContent,\n                                   tsDefinitionOutputPath: tsDefinitionOutputPath,\n                                   tsDefinitionContent: tsDefinitionContent)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptNativeTypeExporter.swift",
    "content": "//\n//  TypeScriptNativeTypeExporter.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/10/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprivate let propertyCharactersToTrim = CharacterSet.whitespacesAndNewlines.union(CharacterSet(charactersIn: \"?:;\"))\n\nenum ExportedType {\n    case valdiModel(ValdiModel)\n    case `enum`(ExportedEnum)\n    case function(ExportedFunction)\n    case module(ExportedModule)\n}\n\nprivate struct EnumMember {\n    let name: String\n\n    enum Value {\n        case string(String)\n        case number(Int)\n    }\n\n    let value: Value\n    let comments: String?\n}\n\nprivate class DocumentIndexMatcher {\n\n    private let indexOffset: Int\n    private let str: NSString\n    private var currentIndex = 0\n\n    var location: Int {\n        return currentIndex + indexOffset\n    }\n\n    init(str: String, indexOffset: Int) {\n        self.indexOffset = indexOffset\n        self.str = str as NSString\n    }\n\n    // NOTE: Will look for a match in the full remainder of the contents, unless `limitTokens` is provided\n    @discardableResult func match(str: String, limitToNextToken limitTokens: [String] = []) throws -> Int {\n        let rangeLimit: Int = limitTokens.map { (limitToken: String) -> Int in\n            let limitTokenRange = self.str.range(of: limitToken, options: [], range: NSRange(location: currentIndex, length: self.str.length - currentIndex))\n            let rangeLimit = limitTokenRange.location == NSNotFound ? self.str.length : limitTokenRange.location\n            return rangeLimit\n        }.min() ?? self.str.length\n\n        let range = self.str.range(of: str, options: [], range: NSRange(location: currentIndex, length: rangeLimit - currentIndex))\n        guard range.location != NSNotFound else {\n            throw CompilerError(\"Could not match index for string '\\(str)' in '\\(self.str)' after location \\(currentIndex)\")\n        }\n\n        currentIndex = range.upperBound\n        return range.location + indexOffset\n    }\n\n    func debugDump() -> String {\n        let lhs = self.str.substring(with: NSRange(location: 0, length: currentIndex))\n        let rhs = self.str.substring(with: NSRange(location: currentIndex, length: self.str.length - currentIndex))\n        return \"\\(lhs)^\\(rhs)\"\n    }\n}\n\nprivate class EnumMemberSequence {\n    private var sequence = 0\n\n    func setNext(_ next: Int) {\n        sequence = next\n    }\n\n    func assign() -> Int {\n        let value = sequence\n        sequence += 1\n        return value\n    }\n}\n\nfinal class TypeScriptNativeTypeExporter {\n\n    private let iosType: IOSType?\n    private let androidClass: String?\n    private let cppType: CPPType?\n    private let commentedFile: TypeScriptCommentedFile\n    private let annotatedSymbol: TypeScriptAnnotatedSymbol\n    private let dumpedSymbol: TS.DumpedSymbolWithComments\n    private let linesIndexer: LinesIndexer\n    private let nativeTypeResolver: TypeScriptNativeTypeResolver\n\n    init(iosType: IOSType?,\n         androidClass: String?,\n         cppType: CPPType?,\n         commentedFile: TypeScriptCommentedFile,\n         annotatedSymbol: TypeScriptAnnotatedSymbol,\n         dumpedSymbol: TS.DumpedSymbolWithComments,\n         nativeTypeResolver: TypeScriptNativeTypeResolver) {\n        self.iosType = iosType\n        self.androidClass = androidClass\n        self.cppType = cppType\n        self.commentedFile = commentedFile\n        self.annotatedSymbol = annotatedSymbol\n        self.dumpedSymbol = dumpedSymbol\n        self.linesIndexer = commentedFile.linesIndexer\n        self.nativeTypeResolver = nativeTypeResolver\n    }\n\n    private func throwAnnotationError(comments: TS.AST.Comments, message: String) throws -> Never {\n        throw CompilerError(type: \"Annotation error\", message: message, range: NSRange(location: comments.start, length: comments.end - comments.start), inDocument: self.commentedFile.fileContent)\n    }\n\n    private func validateWorkerThreadAnnotation(functionReturnType: ValdiModelPropertyType, leadingComments: TS.AST.Comments) throws {\n        switch functionReturnType {\n        case .void:\n            fallthrough\n        case .promise:\n            // All good\n            break\n        default:\n            try self.throwAnnotationError(comments: leadingComments, message: \"@WorkerThread can only be set on functions returning a Promise or void\")\n        }\n    }\n\n    private func makeUnrecognizedType(type: TS.AST.TSType, annotations: [ValdiTypeScriptAnnotation]?, name: String) throws -> ValdiModelPropertyType {\n        if let annotations = annotations {\n            for annotation in annotations {\n                guard let annotation = ValdiAnnotationType(rawValue: annotation.name) else {\n                    try self.throwAnnotationError(comments: type.leadingComments!, message: \"Invalid annotation\")\n                }\n\n                if annotation == .untypedMap {\n                    return .map(keyType: .string, valueType: .any)\n                } else if annotation == .untyped {\n                    return .any\n                }\n            }\n        }\n\n        throw CompilerError(\"Unrecognized type '\\(name)'. Only annotated types can be exported.\")\n    }\n\n    private func resolveType(type: TS.AST.TSType, references: [TS.AST.TypeReference]) throws -> ValdiModelPropertyType {\n        var annotations: [ValdiTypeScriptAnnotation]? = nil\n        if let leadingComments = type.leadingComments {\n            annotations = try ValdiTypeScriptAnnotation.extractAnnotations(comments: leadingComments, fileContent: self.commentedFile.fileContent)\n        }\n\n        if let function = type.function {\n            let functionParameters = try function.parameters.map { try parsePropertyOrParameter(propertyLikeDeclaration: $0, references: references) }\n            let returnValue = try resolveType(type: function.returnValue, references: references)\n\n            var isSingleCall = false\n            var shouldCallOnWorkerThread = false\n            if let annotations = annotations {\n                for annotation in annotations {\n                    guard let annotation = ValdiAnnotationType(rawValue: annotation.name) else {\n                        try self.throwAnnotationError(comments: type.leadingComments!, message: \"Invalid annotation\")\n                    }\n\n                    if annotation == .singleCall {\n                        isSingleCall = true\n                    } else if annotation == .workerThread {\n                        try validateWorkerThreadAnnotation(functionReturnType: returnValue, leadingComments: type.leadingComments!)\n\n                        shouldCallOnWorkerThread = true\n                    } else {\n                        try self.throwAnnotationError(comments: type.leadingComments!, message: \"Function only support the @SingleCall and @WorkerThread annotations\")\n                    }\n                }\n            }\n\n            return .function(parameters: functionParameters, returnType: returnValue, isSingleCall: isSingleCall, shouldCallOnWorkerThread: shouldCallOnWorkerThread)\n        }\n\n        if let typeReferenceIndex = type.typeReferenceIndex {\n            guard typeReferenceIndex >= 0 && typeReferenceIndex < references.count else {\n                throw CompilerError(\"Out of bounds type reference \\(typeReferenceIndex)\")\n            }\n\n            let typeReference = references[typeReferenceIndex]\n\n            if typeReference.name == \"Uint8Array\" {\n                return .bytes\n            } else if typeReference.name == \"Long\" {\n                return .long\n            } else if typeReference.name == \"Number\" {\n                return .double\n            } else if typeReference.name == \"Promise\" || typeReference.name == \"CancelablePromise\" {\n                guard let typeArgument = type.typeArguments?.first else {\n                    throw CompilerError(\"Promise types should have a single type argument\")\n                }\n                let resolvedTypeArgument = try self.resolveType(type: typeArgument.type, references: references)\n                return .promise(typeArgument: resolvedTypeArgument)\n            } else if typeReference.name == \"Map\" {\n                // TODO(simon): Real implementation\n                return .map(keyType: .string, valueType: .any)\n            }\n\n            if type.isTypeParameter == true {\n                return .genericTypeParameter(name: typeReference.name)\n            } else if let resolvedClass = self.nativeTypeResolver.resolve(filePath: typeReference.fileName, tsTypeName: typeReference.name) {\n                if resolvedClass.marshallAsUntypedMap {\n                    return .map(keyType: .string, valueType: .any)\n                }\n\n                var classMapping = ValdiNodeClassMapping(tsType: typeReference.name,\n                                                            iosType: resolvedClass.iosType,\n                                                            androidClassName: resolvedClass.androidClass,\n                                                            cppType: resolvedClass.cppType,\n                                                            kind: resolvedClass.kind)\n                classMapping.isGenerated = resolvedClass.isGenerated\n                classMapping.marshallAsUntyped = resolvedClass.marshallAsUntyped\n                classMapping.converter = resolvedClass.convertedFromFunctionPath\n\n                if let typeArguments = type.typeArguments {\n                    guard case .class = resolvedClass.kind else {\n                        throw CompilerError(\"Generics are only supported on generated types annotated with @GenerateNativeClass\")\n                    }\n                    let resolvedTypeArguments = try typeArguments.map { try self.resolveType(type: $0.type, references: references) }\n                    return .genericObject(classMapping, typeArguments: resolvedTypeArguments)\n                } else {\n                    switch resolvedClass.kind {\n                    case .class, .interface:\n                        return .object(classMapping)\n                    case .enum, .stringEnum:\n                        return .enum(classMapping)\n                    }\n                }\n            } else {\n                return try makeUnrecognizedType(type: type, annotations: annotations, name: typeReference.name)\n            }\n        }\n\n        if let array = type.array {\n            let elementType = try resolveType(type: array, references: references)\n\n            return .array(elementType: elementType)\n        }\n\n        if let unions = type.unions {\n            var resolvedType: ValdiModelPropertyType?\n            var isOptional = false\n\n            for union in unions {\n                if union.name == \"null\" || union.name == \"undefined\" {\n                    isOptional = true\n                } else {\n                    guard resolvedType == nil else {\n                        let desc = unions.map { $0.name }.joined(separator: \" | \")\n                        throw CompilerError(\"Union types are only supported with null or undefined (got \\(desc)\")\n                    }\n\n                    resolvedType = try resolveType(type: union, references: references)\n                }\n            }\n\n            guard let type = resolvedType else {\n                let desc = unions.map { $0.name }.joined(separator: \" | \")\n                throw CompilerError(\"Could not resolve type in union '\\(desc)'\")\n            }\n            if isOptional {\n                return .nullable(type)\n            }\n\n            return type\n        }\n\n        let typeName = type.name\n        if typeName == \"string\" {\n            return .string\n        } else if typeName == \"number\" {\n            return .double\n        } else if typeName == \"boolean\" {\n            return .bool\n        } else if typeName == \"void\" {\n            return .void\n        } else if typeName == \"any\" {\n            // TODO: should actually be .any, but introduces lots of breaking changes\n            return .map(keyType: .string, valueType: .any)\n        } else if typeName == \"object\" {\n            return .any\n        } else {\n            return try makeUnrecognizedType(type: type, annotations: annotations, name: typeName)\n        }\n    }\n\n    private struct PropertyMetadata {\n        let comments: String?\n        let omitConstructor: OmitConstructorParams?\n        let injectableParams: InjectableParams\n        let shouldCallOnWorkerThread: Bool\n    }\n\n    private func getPropertyMetadata(leadingComments: TS.AST.Comments) throws -> PropertyMetadata {\n        let annotations = try ValdiTypeScriptAnnotation.extractAnnotations(comments: leadingComments,\n                                                                              fileContent: commentedFile.fileContent)\n\n        var omitConstructor: OmitConstructorParams?\n        if let annotation = annotations.first(where: { $0.name == \"ConstructorOmitted\" }) {\n            let ios = annotation.parameters?[\"ios\"].map { $0 == \"true\" }\n            let android = annotation.parameters?[\"android\"].map { $0 == \"true\" }\n\n            omitConstructor = OmitConstructorParams(ios: ios, android: android)\n        }\n\n        var injectableParams: InjectableParams = .empty\n        if let injectableAnnotation = annotations.first(where: { $0.name == ValdiAnnotationType.injectable.rawValue }) {\n            var injectableParamsCompatibility: InjectableParams.Compatibility = []\n            \n            // no parameters mean its injectable on both\n            if injectableAnnotation.parameters?.isEmpty != false {\n                injectableParamsCompatibility = InjectableParams.Compatibility.all\n            } else {\n                let iosOnly = injectableAnnotation.parameters?[\"iosOnly\"].map { $0 == \"true\" } ?? false\n                let androidOnly = injectableAnnotation.parameters?[\"androidOnly\"].map { $0 == \"true\" } ?? false\n                if iosOnly && androidOnly {\n                    throw CompilerError(\"The @Injectable annotation should either be iosOnly or androidOnly. If you want it injectable on both platforms, remove any parameters.\")\n                }\n\n                if iosOnly {\n                    injectableParamsCompatibility.insert(.ios)\n                }\n\n                if androidOnly {\n                    injectableParamsCompatibility.insert(.android)\n                }\n            }\n            \n            injectableParams = InjectableParams(compatibility: injectableParamsCompatibility)\n        }\n\n        let shouldCallOnWorkerThread = annotations.contains(where: { $0.name == ValdiAnnotationType.workerThread.rawValue })\n\n        let commentsWithoutAnnotations = TypeScriptAnnotatedSymbol.mergedCommentsWithoutAnnotations(fullComments: leadingComments.text, annotations: annotations)\n        return PropertyMetadata(comments: commentsWithoutAnnotations.nonEmpty, omitConstructor: omitConstructor, injectableParams: injectableParams, shouldCallOnWorkerThread: shouldCallOnWorkerThread)\n    }\n\n    private func parsePropertyLike(name: String,\n                                   type: TS.AST.TSType,\n                                   isOptional: Bool,\n                                   leadingComments: TS.AST.Comments?,\n                                   references: [TS.AST.TypeReference]) throws -> ValdiModelProperty {\n        var parsedType = try resolveType(type: type, references: references)\n        if isOptional {\n            parsedType = .nullable(parsedType)\n        }\n\n        var resolvedPropertyMetadata: PropertyMetadata? = nil\n        if let leadingComments {\n            let propertyMetadata = try getPropertyMetadata(leadingComments: leadingComments)\n            resolvedPropertyMetadata = propertyMetadata\n\n            if propertyMetadata.omitConstructor != nil && !parsedType.isOptional {\n                throw CompilerError(\"@ConstructorOmitted can only be set on an optional property or function\")\n            }\n\n            if propertyMetadata.injectableParams.compatibility.contains(.android) && propertyMetadata.injectableParams.compatibility.contains(.ios) && parsedType.isOptional {\n                throw CompilerError(\"@Injectable can only be set on non-optional properties\")\n            }\n\n            if propertyMetadata.shouldCallOnWorkerThread {\n                guard case let .function(parameters, returnType, isSingleCall, _) = parsedType.unwrappingOptional else {\n                    try throwAnnotationError(comments: leadingComments, message: \"@WorkerThread can only be set on functions or methods\")\n                }\n                try validateWorkerThreadAnnotation(functionReturnType: returnType, leadingComments: leadingComments)\n\n                let newType = ValdiModelPropertyType.function(parameters: parameters, returnType: returnType, isSingleCall: isSingleCall, shouldCallOnWorkerThread: true)\n                if parsedType.isOptional {\n                    parsedType = ValdiModelPropertyType.nullable(newType)\n                } else {\n                    parsedType = newType\n                }\n            }\n        }\n\n        return ValdiModelProperty(name: name,\n                                  type: parsedType,\n                                  comments: resolvedPropertyMetadata?.comments,\n                                  omitConstructor: resolvedPropertyMetadata?.omitConstructor,\n                                  injectableParams: resolvedPropertyMetadata?.injectableParams ?? .empty)\n    }\n\n    private func parsePropertyOrParameter(propertyLikeDeclaration: TS.AST.PropertyLikeDeclaration, references: [TS.AST.TypeReference]) throws -> ValdiModelProperty {\n        return try parsePropertyLike(name: propertyLikeDeclaration.name,\n                                 type: propertyLikeDeclaration.type,\n                                 isOptional: propertyLikeDeclaration.isOptional,\n                                 leadingComments: propertyLikeDeclaration.leadingComments,\n                                 references: references)\n    }\n\n    func export() -> Promise<(ExportedType, ValdiClassMapping)> {\n        if dumpedSymbol.enum != nil {\n            return exportEnum()\n        } else {\n            return exportValdiModel()\n        }\n    }\n\n    private func parseEnumMember(enumMember: TS.AST.EnumMember, sequence: EnumMemberSequence) throws -> EnumMember {\n        if let numberValue = enumMember.numberValue {\n            guard let enumValue = Int(numberValue) else {\n                throw CompilerError(\"Could not parse number '\\(numberValue)' in enum member \\(enumMember.name) \")\n            }\n            sequence.setNext(enumValue + 1)\n            return EnumMember(name: enumMember.name, value: .number(enumValue), comments: enumMember.leadingComments?.text)\n        }\n\n        if let stringValue = enumMember.stringValue {\n            return EnumMember(name: enumMember.name, value: .string(stringValue), comments: enumMember.leadingComments?.text)\n        }\n\n        return EnumMember(name: enumMember.name, value: .number(sequence.assign()), comments: enumMember.leadingComments?.text)\n    }\n\n    func exportFunction() -> Promise<(ExportedFunction, ValdiClassMapping)> {\n        guard let dumpedFunction = dumpedSymbol.function else {\n            return Promise(error: CompilerError(\"Missing function data for '\\(dumpedSymbol.text)'\"))\n        }\n\n        let comments = annotatedSymbol.mergedCommentsWithoutAnnotations()\n\n        do {\n            let parameters = try dumpedFunction.type.parameters.map { try self.parsePropertyOrParameter(propertyLikeDeclaration: $0, references: self.commentedFile.references) }\n            let returnType = try self.resolveType(type: dumpedFunction.type.returnValue, references: self.commentedFile.references)\n            let exportedFunction = ExportedFunction(containingIosType: self.iosType,\n                                                    containingAndroidTypeName: self.androidClass,\n                                                    containingCppType: self.cppType,\n                                                    functionName: dumpedFunction.name,\n                                                    parameters: parameters,\n                                                    returnType: returnType,\n                                                    comments: comments)\n            let classMapping = ValdiClassMapping()\n            return Promise(data: (exportedFunction, classMapping))\n        } catch {\n            return Promise(error: error)\n        }\n    }\n\n    func exportModule() -> Promise<(ExportedModule, ValdiClassMapping)>  {\n        do {\n            var model = ValdiModel()\n            model.exportAsInterface = true\n            model.cppType = cppType\n            model.iosType = iosType\n            model.androidClassName = androidClass\n\n            for annotatedSymbol in commentedFile.annotatedSymbols where annotatedSymbol.symbol.modifiers?.contains(\"export\") == true {\n                if let function = annotatedSymbol.symbol.function {\n                    let wrappedType = TS.AST.TSType(name: function.name,\n                                                    leadingComments: nil,\n                                                    function: function.type,\n                                                    unions: nil,\n                                                    typeReferenceIndex: nil,\n                                                    array: nil,\n                                                    typeArguments: nil,\n                                                    isTypeParameter: nil)\n                    model.properties.append(try parsePropertyLike(name: function.name,\n                                                                  type: wrappedType,\n                                                                  isOptional: false,\n                                                                  leadingComments: dumpedSymbol.leadingComments,\n                                                                  references: self.commentedFile.references))\n                }\n\n                if let variable = annotatedSymbol.symbol.variable {\n                    model.properties.append(try parsePropertyLike(name: variable.name, type: variable.type, isOptional: false, leadingComments: variable.leadingComments, references: self.commentedFile.references))\n                }\n            }\n\n            let modulePath = commentedFile.src.compilationPath.removing(suffixes: FileExtensions.typescriptFileExtensionsDotted)\n\n            let classMapping = ValdiClassMapping()\n            return Promise(data: (ExportedModule(model: model, modulePath: modulePath), classMapping))\n        } catch let error {\n            return Promise(error: error)\n        }\n    }\n\n    private func exportEnum() -> Promise<(ExportedType, ValdiClassMapping)> {\n        guard let dumpedEnum = dumpedSymbol.enum else {\n            return Promise(error: CompilerError(\"Missing enum data for '\\(dumpedSymbol.text)'\"))\n        }\n\n        let comments = annotatedSymbol.mergedCommentsWithoutAnnotations()\n\n        do {\n            let enumSequence = EnumMemberSequence()\n            let enumMembers = try dumpedEnum.members.map { try self.parseEnumMember(enumMember: $0, sequence: enumSequence) }\n\n            let classMapping = ValdiClassMapping()\n\n            let stringCases: [EnumCase<String>] = enumMembers.compactMap { member in\n                guard case let .string(value) = member.value else { return nil }\n                let comments = member.comments.map {\n                    TypeScriptAnnotatedSymbol.cleanCommentString($0)\n                }\n\n                return EnumCase(name: member.name, value: value, comments: comments)\n            }\n            let numberCases: [EnumCase<Int>] = enumMembers.compactMap { member in\n                guard case let .number(value) = member.value else { return nil }\n                let comments = member.comments.map {\n                    TypeScriptAnnotatedSymbol.cleanCommentString($0)\n                }\n\n                return EnumCase(name: member.name, value: value, comments: comments)\n            }\n\n            let valid = stringCases.isEmpty != numberCases.isEmpty\n            guard valid else {\n                return Promise(error: CompilerError(\"Invalid enum members: \\(enumMembers)\") )\n            }\n\n            let enumCases: ExportedEnum.Cases\n            if !stringCases.isEmpty {\n                enumCases = .stringEnum(stringCases)\n            } else {\n                enumCases = .enum(numberCases)\n            }\n\n            let exportedEnum = ExportedEnum(iosType: self.iosType,\n                                            androidTypeName: self.androidClass,\n                                            cppType: self.cppType,\n                                            cases: enumCases,\n                                            comments: comments)\n\n            return Promise(data: (.enum(exportedEnum), classMapping))\n        } catch {\n            return Promise(error: error)\n        }\n    }\n\n    private func exportValdiModel() -> Promise<(ExportedType, ValdiClassMapping)> {\n        guard let dumpedInterface = dumpedSymbol.interface else {\n            return Promise(error: CompilerError(\"Missing interface data for '\\(dumpedSymbol.text)'\"))\n        }\n\n        let comments = annotatedSymbol.mergedCommentsWithoutAnnotations()\n\n        do {\n            var properties: [ValdiModelProperty] = []\n            for member in dumpedInterface.members {\n                do {\n                    let property = try self.parsePropertyOrParameter(propertyLikeDeclaration: member, references: self.commentedFile.references)\n                    properties.append(property)\n                } catch let error {\n                    throw CompilerError(\"Failed to parse property \\(member.name): \\(error.legibleLocalizedDescription)\")\n                }\n            }\n\n            var model = ValdiModel()\n            model.tsType = self.dumpedSymbol.text\n            model.iosType = self.iosType\n            model.androidClassName = self.androidClass\n            model.cppType = self.cppType\n            model.properties = properties\n            model.comments = comments\n            model.typeParameters = dumpedInterface.typeParameters?.map { ValdiTypeParameter(name: $0.name) }\n            \n            // Check for usePublicFields parameter in ExportModel annotation\n            if let exportModelAnnotation = self.annotatedSymbol.annotations.first(where: { $0.name == \"ExportModel\" }) {\n                model.usePublicFields = exportModelAnnotation.parameters?[\"usePublicFields\"] == \"true\"\n            }\n\n            let classMapping = ValdiClassMapping()\n\n            return Promise(data: (.valdiModel(model), classMapping))\n        } catch {\n            return Promise(error: error)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptNativeTypeResolver.swift",
    "content": "//\n//  TypeScriptNativeTypeResolver.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/10/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct TypeScriptNativeClass: Codable {\n    let tsTypeName: String\n    let iosType: IOSType?\n    let androidClass: String?\n    let cppType: CPPType?\n    let kind: NativeTypeKind\n    let isGenerated: Bool\n    let marshallAsUntyped: Bool\n    let marshallAsUntypedMap: Bool\n    let convertedFromFunctionPath: String?\n}\n\nstruct TypeScriptNativeConvertedClass: Codable {\n    let convertFunctionPath: String\n    let toCompilationPath: String\n    let toTypeName: String\n}\n\nenum TypeScriptNativeTypeKind {\n    case cls(TypeScriptNativeClass)\n    case convertedClass(TypeScriptNativeConvertedClass)\n}\n\nstruct TypeScriptNativeType {\n    let emittingBundleName: String\n    let kind: TypeScriptNativeTypeKind\n}\n\nstruct SerializedTypeScriptNativeType: Codable {\n    let compilationPath: String\n    let tsTypeName: String\n    let emittingBundleName: String\n    let cls: TypeScriptNativeClass?\n    let convertedClass: TypeScriptNativeConvertedClass?\n}\n\nstruct SerializedTypeScriptNativeTypeResolver: Codable {\n    let entries: [SerializedTypeScriptNativeType]\n}\n\nfinal class TypeScriptNativeTypeResolver {\n    private let rootURL: URL\n\n    private let lock = DispatchSemaphore.newLock()\n\n    private var typesByPath = [String: [String: TypeScriptNativeType]]()\n\n    init(rootURL: URL) {\n        self.rootURL = rootURL\n    }\n\n    func restore(fromSerialized serialized: SerializedTypeScriptNativeTypeResolver) throws {\n        try lock.lock {\n            for entry in serialized.entries {\n                if let cls = entry.cls {\n                    typesByPath[entry.compilationPath, default: [:]][entry.tsTypeName] = TypeScriptNativeType(emittingBundleName: entry.emittingBundleName, kind: .cls(cls))\n                } else if let convertedClass = entry.convertedClass {\n                    typesByPath[entry.compilationPath, default: [:]][entry.tsTypeName] = TypeScriptNativeType(emittingBundleName: entry.emittingBundleName, kind: .convertedClass(convertedClass))\n                } else {\n                    throw CompilerError(\"Could not resolve entry type\")\n                }\n            }\n        }\n    }\n\n    func serialize() -> SerializedTypeScriptNativeTypeResolver {\n        var entries = [SerializedTypeScriptNativeType]()\n        lock.lock {\n            for (compilationPath, values) in typesByPath {\n                for (tsTypeName, type) in values {\n                    switch type .kind{\n                    case .cls(let cls):\n                        entries.append(SerializedTypeScriptNativeType(compilationPath: compilationPath, tsTypeName: tsTypeName, emittingBundleName: type.emittingBundleName, cls: cls, convertedClass: nil))\n                    case .convertedClass(let convertedClass):\n                        entries.append(SerializedTypeScriptNativeType(compilationPath: compilationPath, tsTypeName: tsTypeName, emittingBundleName: type.emittingBundleName, cls: nil, convertedClass: convertedClass))\n                    }\n                }\n            }\n        }\n\n        entries.sort { left, right in\n            if left.compilationPath < right.compilationPath {\n                return true\n            } else if left.compilationPath > right.compilationPath {\n                return false\n            }\n\n            return left.tsTypeName < right.tsTypeName\n        }\n\n        return SerializedTypeScriptNativeTypeResolver(entries: entries)\n    }\n\n    private func makeSrcWithoutExtension(src: TypeScriptItemSrc) -> TypeScriptItemSrc {\n        let compilationPath = src.compilationPath.removing(suffixes: FileExtensions.typescriptFileExtensionsDotted)\n        return TypeScriptItemSrc(compilationPath: compilationPath, sourceURL: src.sourceURL)\n    }\n\n    func register(src: TypeScriptItemSrc,\n                  emittingBundleName: String,\n                  tsTypeName: String,\n                  iosType: IOSType?,\n                  androidClass: String?,\n                  cppType: CPPType?,\n                  kind: NativeTypeKind,\n                  isGenerated: Bool,\n                  marshallAsUntyped: Bool,\n                  marshallAsUntypedMap: Bool) -> TypeScriptNativeClass {\n        let standardizedSrc = makeSrcWithoutExtension(src: src)\n        let nativeClass = TypeScriptNativeClass(tsTypeName: tsTypeName,\n                                                iosType: iosType,\n                                                androidClass: androidClass,\n                                                cppType: cppType,\n                                                kind: kind,\n                                                isGenerated: isGenerated,\n                                                marshallAsUntyped: marshallAsUntyped,\n                                                marshallAsUntypedMap: marshallAsUntypedMap,\n                                                convertedFromFunctionPath: nil)\n\n        lock.lock {\n            typesByPath[standardizedSrc.compilationPath, default: [:]][tsTypeName] = TypeScriptNativeType(emittingBundleName: emittingBundleName, kind: .cls(nativeClass))\n        }\n\n        return nativeClass\n    }\n\n    func registerTypeConverter(src: TypeScriptItemSrc,\n                               emittingBundleName: String,\n                               tsTypeName: String,\n                               fromTypePath: String,\n                               tsFromTypeName: String,\n                               toTypePath: String,\n                               tsToTypeName: String) {\n        let standardizedSrc = makeSrcWithoutExtension(src: src)\n        let functionPath = \"\\(tsTypeName)@\\(standardizedSrc.compilationPath)\"\n\n        let standardizedFromType = makeSrcWithoutExtension(src: TypeScriptItemSrc(compilationPath: fromTypePath, sourceURL: src.sourceURL))\n        let standardizedToType = makeSrcWithoutExtension(src: TypeScriptItemSrc(compilationPath: toTypePath, sourceURL: src.sourceURL))\n\n        lock.lock {\n            typesByPath[standardizedFromType.compilationPath, default: [:]][tsFromTypeName] = TypeScriptNativeType(emittingBundleName: emittingBundleName, kind: .convertedClass(TypeScriptNativeConvertedClass(convertFunctionPath: functionPath, toCompilationPath: standardizedToType.compilationPath, toTypeName: tsToTypeName)))\n        }\n    }\n\n    private func lockFreeResolve(compilationPath: String, tsTypeName: String) -> TypeScriptNativeClass? {\n        guard let types = typesByPath[compilationPath], let type = types[tsTypeName] else {\n            return nil\n        }\n\n        switch type.kind {\n        case .cls(let nativeClass):\n            return nativeClass\n        case .convertedClass(let convertedClass):\n            guard let nativeClass = lockFreeResolve(compilationPath: convertedClass.toCompilationPath, tsTypeName: convertedClass.toTypeName) else {\n                return nil\n            }\n\n            return TypeScriptNativeClass(tsTypeName: nativeClass.tsTypeName,\n                                         iosType: nativeClass.iosType,\n                                         androidClass: nativeClass.androidClass,\n                                         cppType: nativeClass.cppType,\n                                         kind: nativeClass.kind,\n                                         isGenerated: nativeClass.isGenerated,\n                                         marshallAsUntyped: nativeClass.marshallAsUntyped,\n                                         marshallAsUntypedMap: nativeClass.marshallAsUntypedMap,\n                                         convertedFromFunctionPath: convertedClass.convertFunctionPath)\n        }\n    }\n\n    func resolve(src: TypeScriptItemSrc, tsTypeName: String) -> TypeScriptNativeClass? {\n        let standardizedSrc = makeSrcWithoutExtension(src: src)\n        return lock.lock {\n            return lockFreeResolve(compilationPath: standardizedSrc.compilationPath, tsTypeName: tsTypeName)\n        }\n    }\n\n    func resolve(filePath: String, tsTypeName: String) -> TypeScriptNativeClass? {\n        let fileURL = URL(fileURLWithPath: filePath, relativeTo: rootURL)\n        return resolve(src: TypeScriptItemSrc(compilationPath: filePath, sourceURL: fileURL), tsTypeName: tsTypeName)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptStringsModuleGenerator.swift",
    "content": "//\n//  TypeScriptStringsModuleGenerator.swift\n//  \n//\n//  Created by Simon Corsin on 3/23/20.\n//\n\nimport Foundation\nimport Yams\n\nstruct TypeScriptStringsModuleResult {\n    let jsFile: File\n    let tsDefinitionFile: File\n}\n\nprivate struct LocalizableStringParam {\n    enum Specifier {\n        case string\n        case int\n    }\n\n    let name: String\n    let specifier: Specifier\n}\n\nprivate struct LocalizableString {\n    let key: String\n    let params: [LocalizableStringParam]\n    let message: String\n    let example: String?\n}\n\nprivate class ParsedLocalizableStrings {\n    var strings: [LocalizableString]\n\n    init(strings: [LocalizableString]) {\n        self.strings = strings\n    }\n}\n\nstruct LocalizableStringsContent {\n    let relativePath: RelativePath\n    let file: File\n}\n\nclass TypeScriptStringsModuleGenerator {\n\n    private let moduleName: String\n\n    private let paramRegex = try! NSRegularExpression(pattern: \"(\\\\{([\\\\w_]+)(%.*?)?\\\\})\")\n    private let stringFiles: [LocalizableStringsContent]\n    private let defaultStringFileIndex: Int\n    private let emitInlineTranslations: Bool\n\n    init(stringFiles: [LocalizableStringsContent], defaultStringFileIndex: Int, moduleName: String, emitInlineTranslations: Bool) {\n        self.stringFiles = stringFiles\n        self.defaultStringFileIndex = defaultStringFileIndex\n        self.moduleName = moduleName\n        self.emitInlineTranslations = emitInlineTranslations\n    }\n\n    static func outputPath(bundleName: String, ext: String) -> String {\n        return \"\\(bundleName)/src/Strings.\\(ext)\"\n    }\n\n    private func parseLocalizableString(key: String, message: String, example: String?, comment: String?) throws -> LocalizableString {\n        let matches = paramRegex.matches(in: message, options: [], range: message.nsrange)\n\n        let nsMessage = message as NSString\n\n        var params = [LocalizableStringParam]()\n        for match in matches {\n            let paramName: String\n\n            let paramNameRange = match.range(at: 2)\n            if paramNameRange.location != NSNotFound {\n                paramName = nsMessage.substring(with: paramNameRange)\n            } else {\n                paramName = \"unnamed\\(params.count + 1)\"\n            }\n\n            let specifier: LocalizableStringParam.Specifier\n\n            let specifierRange = match.range(at: 3)\n            if specifierRange.location != NSNotFound {\n                let specifierString = nsMessage.substring(with: specifierRange)\n                switch specifierString {\n                case \"%d\":\n                    specifier = .int\n                case \"%s\":\n                    specifier = .string\n                default:\n                    throw CompilerError(\"Unrecognized specifier '\\(specifierString)' in message '\\(message)' at key '\\(key)'\")\n                }\n            } else {\n                specifier = .string\n            }\n\n            params.append(LocalizableStringParam(name: paramName, specifier: specifier))\n        }\n\n        return LocalizableString(key: key, params: params, message: message, example: example)\n    }\n\n    private func extractStringsFromJSON(json: Any) throws -> ParsedLocalizableStrings {\n        guard let rootDict = json as? [String: Any] else {\n            throw CompilerError(\"Invalid strings JSON format\")\n        }\n\n        let localizableStrings = try rootDict.compactMap { keyAndValue -> LocalizableString? in\n            let key = keyAndValue.key\n            let untypedRecord = keyAndValue.value\n\n            // Snap-specific: a \"l10nsvc\": \"sourcefile\" key/value pair is used as an annotation required by the Snap Localization Service\n            // We ignore it when processing the strings.json file\n            guard key != \"l10nsvc\" else {\n                return nil\n            }\n\n            guard let record = untypedRecord as? [String: Any] else {\n                throw CompilerError(\"Invalid record for key \\(key). Expected a dictionary.\")\n            }\n\n            guard let message = record[\"defaultMessage\"] as? String else {\n                throw CompilerError(\"Invalid 'message' for key \\(key)\")\n            }\n            let example = record[\"example\"] as? String\n            let comment = record[\"comment\"] as? String\n            return try parseLocalizableString(key: key, message: message, example: example, comment: comment)\n        }\n        return ParsedLocalizableStrings(strings: localizableStrings)\n    }\n\n    private func parseStrings(file: File) throws -> ParsedLocalizableStrings {\n        let fileContent = try file.readData()\n        let json = try JSONSerialization.jsonObject(with: fileContent)\n        return try extractStringsFromJSON(json: json)\n    }\n\n    private func resolveLanguage(fromPath: RelativePath) throws -> String {\n        let filename = fromPath.components.last ?? \"\"\n\n        guard filename.hasPrefix(Files.stringsJSONPrefix) && filename.hasSuffix(Files.stringsJSONSuffix) else {\n            throw CompilerError(\"File '\\(filename)' is not a string JSON file\")\n        }\n\n        let startIndex = Files.stringsJSONPrefix.endIndex\n        let endIndex = filename.index(filename.endIndex, offsetBy: -Files.stringsJSONSuffix.count)\n\n        return String(filename[startIndex..<endIndex])\n    }\n\n    private func resolveAvailableLanguagesAndFilePaths() throws -> [(String, String)] {\n        let defaultFile = self.stringFiles[self.defaultStringFileIndex]\n\n        for file in self.stringFiles where file.relativePath != defaultFile.relativePath {\n            // We don't do any fancy processing with the file here, but we parse it\n            // to validate that it is at least correct\n            let _ = try parseStrings(file: file.file)\n        }\n\n        return try self.stringFiles.map {\n            let language = try resolveLanguage(fromPath: $0.relativePath)\n            return (language, $0.relativePath.description)\n        }.sorted(by: { $0.0 < $1.0 })\n    }\n\n    func generate() throws -> TypeScriptStringsModuleResult {\n        let localizableStrings = try parseStrings(file: self.stringFiles[self.defaultStringFileIndex].file)\n        localizableStrings.strings.sort { (left, right) -> Bool in\n            return left.key < right.key\n        }\n\n        let jsFile = CodeWriter()\n        let tsDefFile = CodeWriter()\n\n        let stringKeys = CodeWriter()\n        let parameterTypes = CodeWriter()\n\n        jsFile.appendBody(\"exports.default = require('valdi_core/src/LocalizableStrings').\")\n        if emitInlineTranslations {\n            jsFile.appendBody(\"buildInlineModule('\\(moduleName)', [\")\n            jsFile.appendBody(stringKeys)\n            jsFile.appendBody(\"], [\")\n            jsFile.appendBody(parameterTypes)\n            jsFile.appendBody(\"], [\")\n\n            let availableLanguagesAndFilePaths = try resolveAvailableLanguagesAndFilePaths()\n\n            jsFile.appendBody(availableLanguagesAndFilePaths.map { \"\\\"\\($0.0)\\\"\" }.joined(separator: \", \"))\n            jsFile.appendBody(\"], [\")\n            jsFile.appendBody(availableLanguagesAndFilePaths.map { \"\\\"\\($0.1)\\\"\" }.joined(separator: \", \"))\n            jsFile.appendBody(\"]);\\n\")\n        } else {\n            jsFile.appendBody(\"buildExternalModule('\\(moduleName)', [\")\n            jsFile.appendBody(stringKeys)\n            jsFile.appendBody(\"], [\")\n            jsFile.appendBody(parameterTypes)\n            jsFile.appendBody(\"]);\\n\")\n        }\n\n        tsDefFile.appendBody(\"export interface Strings {\\n\")\n\n        var isFirst = true\n\n        for localizableString in localizableStrings.strings {\n            if !isFirst {\n                stringKeys.appendBody(\", \")\n                parameterTypes.appendBody(\", \")\n                tsDefFile.appendBody(\"\\n\")\n            }\n            isFirst = false\n\n            stringKeys.appendBody(\"'\\(localizableString.key)'\")\n\n            var functionComment = \"Returns the localizable string for the key '\\(localizableString.key)'\"\n            if let example = localizableString.example {\n                functionComment += \"\\nExample: \"\n                functionComment += example\n            }\n\n            var resolvedFunctionComment = FileHeaderCommentGenerator.generateMultilineComment(comment: functionComment)\n            // Indent comment by 2 spaces\n            resolvedFunctionComment = resolvedFunctionComment.split(separator: \"\\n\").map { \"  \\($0)\" }.joined(separator: \"\\n\")\n\n            tsDefFile.appendBody(resolvedFunctionComment)\n            tsDefFile.appendBody(\"\\n  \\(localizableString.key.camelCased)(\")\n\n            var tsParamDecls: [String] = []\n            var jsParamTypes: [String] = []\n\n            for param in localizableString.params {\n                let tsParamType: String\n                let jsParamType: String\n\n                switch param.specifier {\n                case .string:\n                    tsParamType = \"string\"\n                    jsParamType = \"0\"\n                case .int:\n                    tsParamType = \"number\"\n                    jsParamType = \"1\"\n                }\n\n                tsParamDecls.append(\"\\(param.name.camelCased): \\(tsParamType)\")\n                jsParamTypes.append(jsParamType)\n            }\n\n            tsDefFile.appendBody(tsParamDecls.joined(separator: \", \"))\n            tsDefFile.appendBody(\"): string,\\n\")\n\n            if jsParamTypes.isEmpty {\n                parameterTypes.appendBody(\"undefined\")\n            } else {\n                parameterTypes.appendBody(\"[\")\n                parameterTypes.appendBody(jsParamTypes.joined(separator: \", \"))\n                parameterTypes.appendBody(\"]\")\n            }\n        }\n\n        tsDefFile.appendBody(\"}\\n\")\n        tsDefFile.appendBody(\"\\ndeclare const strings: Strings;\\n\")\n        tsDefFile.appendBody(\"export default strings;\\n\")\n\n        return TypeScriptStringsModuleResult(jsFile: .data(try jsFile.data()), tsDefinitionFile: .data(try tsDefFile.data()))\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptSymbol.swift",
    "content": "//\n//  TypeScriptSymbol.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/15/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct TypeScriptSymbol {\n    let symbol: String\n    let isDefault: Bool\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/TypeScriptSymbolParser.swift",
    "content": "//\n//  TypeScriptSymbolParser.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/18/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class TypeScriptSymbolParser {\n\n    private(set) var currentLocation: Int = 0\n\n    private let symbols: [TS.SymbolDisplayPart]\n\n    init(symbols: [TS.SymbolDisplayPart]) {\n        self.symbols = symbols\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/TypeScript/ValdiJSElement.swift",
    "content": "//\n//  ValdiJSElement.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ValdiJSAttributeDebugInfo {\n    let originalExpression: String\n    let line: Int\n    let column: Int\n}\n\nstruct ValdiJSAttribute {\n    let attribute: String\n    let value: String\n    let valueIsExpr: Bool\n    let evaluateOnce: Bool\n    let isViewModelField: Bool\n    let debugInfo: ValdiJSAttributeDebugInfo?\n}\n\nenum ValdiJSNode {\n    case expression(ValdiJSExpression)\n    case element(ValdiJSElement)\n\n    var element: ValdiJSElement? {\n        if case let .element(element) = self {\n            return element\n        }\n        return nil\n    }\n\n    var expression: ValdiJSExpression? {\n        if case let .expression(expression) = self {\n            return expression\n        }\n        return nil\n    }\n}\n\nstruct ValdiJSExpression {\n    let expression: String\n}\n\nclass ValdiJSElement {\n\n    let id: String\n    let componentPath: ComponentPath?\n    let nodeType: String\n    let jsxName: String?\n\n    var androidViewClass: String?\n    var iosViewClass: String?\n    var webViewClass: String?\n    var macosViewClass: String?\n\n    var forEachExpr: ValdiJSAttribute?\n    var renderIfExpr: ValdiJSAttribute?\n    var renderElseIfExpr: ValdiJSAttribute?\n    var insertInSlotName: String?\n    var slotName: String?\n    var slotRefExpr: String?\n\n    var children: [ValdiJSNode] = []\n    var attributes: [ValdiJSAttribute] = []\n    var forEachKey: ValdiJSAttribute?\n\n    init(id: String, componentPath: ComponentPath?, nodeType: String, jsxName: String?) {\n        self.id = id\n        self.componentPath = componentPath\n        self.nodeType = nodeType\n        self.jsxName = jsxName\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/USBMuxClient/USBMuxBroadcastConnection.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by saniul on 10/10/2019.\n//\n\nimport Foundation\n\nprotocol USBMuxBroadcastConnectionDelegate: AnyObject {\n    func broadcastConnection(_ connection: USBMuxBroadcastConnection, started result: Result<Void, Error>)\n    func broadcastConnection(_ connection: USBMuxBroadcastConnection, stopped result: Result<Void, Error>)\n\n    func broadcastConnection(_ connection: USBMuxBroadcastConnection, deviceAttached deviceId: USBMuxDeviceId)\n    func broadcastConnection(_ connection: USBMuxBroadcastConnection, deviceDetached deviceId: USBMuxDeviceId)\n}\n\nprivate enum USBMuxBroadcastResponseType: String {\n    case deviceAttached = \"Attached\"\n    case deviceDetached = \"Detached\"\n}\n\nclass USBMuxBroadcastConnection {\n    weak var delegate: USBMuxBroadcastConnectionDelegate?\n\n    private let logger: ILogger\n    private let connection: USBMuxConnection\n    private let queue: DispatchQueue\n\n    init(logger: ILogger) {\n        self.logger = logger\n        let queue = DispatchQueue(label: \"USBMuxBroadcastConnection\")\n        self.queue = queue\n        let connection = USBMuxConnection(logger: logger, queue: queue)\n        self.connection = connection\n    }\n\n    func start() {\n        do {\n            try connection.open(onEnd: { [weak self] result in\n                guard let this = self else { return }\n                this.delegate?.broadcastConnection(this, stopped: result)\n            })\n            connection.broadcastHandler = { [weak self] packet in\n                self?.handleBroadcastPacket(packet)\n            }\n\n            let packet = USBMuxPacket.packetPayloadWithRequestType(.listen, contents: [:])\n            connection.sendRequest(packet, callback: { [weak self] result in\n                guard let this = self else { return }\n                this.delegate?.broadcastConnection(this, started: result)\n            })\n        } catch {\n            delegate?.broadcastConnection(self, started: .failure(error))\n            return\n        }\n    }\n\n    func handleBroadcastPacket(_ packet: USBMuxPlistPayload) {\n        guard let messageType = packet[\"MessageType\"] as? String else {\n            logger.warn(\"Warning: Broadcast message with missing MessageType: \\(packet)\")\n            return\n        }\n\n        guard let broadcastResponseType = USBMuxBroadcastResponseType(rawValue: messageType) else {\n            logger.warn(\"Warning: Unknown broadcast message: \\(packet)\")\n            return\n        }\n\n        switch broadcastResponseType {\n        case .deviceAttached:\n            guard let deviceIdInt = packet[\"DeviceID\"] as? Int else {\n                logger.warn(\"Warning: Received 'Attached' message, but couldn't parse: \\(packet)\")\n                return\n            }\n            let deviceId = USBMuxDeviceId(deviceIdInt)\n            delegate?.broadcastConnection(self, deviceAttached: deviceId)\n        case .deviceDetached:\n            guard let deviceIdInt = packet[\"DeviceID\"] as? Int else {\n                logger.warn(\"Warning: Received 'Detached' message, but couldn't parse: \\(packet)\")\n                return\n            }\n            let deviceId = USBMuxDeviceId(deviceIdInt)\n            delegate?.broadcastConnection(self, deviceDetached: deviceId)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/USBMuxClient/USBMuxClient.swift",
    "content": "//\n//  USBDeviceHub.swift\n//  Compiler\n//\n//  Created by saniul on 02/10/2019.\n//\n\nimport Foundation\nimport BlueSocket\n\nprotocol USBMuxClientDelegate: AnyObject {\n    func usbMuxClientDeviceConnected(_ client: USBMuxClient, deviceId: USBMuxDeviceId, connection: USBMuxDeviceConnection)\n    func usbMuxClientDeviceDisconnected(_ client: USBMuxClient, deviceId: USBMuxDeviceId)\n}\n\nclass USBMuxClient: USBMuxBroadcastConnectionDelegate, USBMuxDeviceConnectionDelegate {\n    weak var delegate: USBMuxClientDelegate?\n\n    let devicePortNumber: Int\n\n    private let logger: ILogger\n    private var queue =  DispatchQueue(label: \"USBMuxClient\")\n\n    private var broadcastConnection: USBMuxBroadcastConnection?\n    private var deviceConnections: [USBMuxDeviceId: USBMuxDeviceConnection] = [:]\n    private var started = false\n\n    init(logger: ILogger, devicePortNumber: Int) {\n        self.logger = logger\n        self.devicePortNumber = devicePortNumber\n    }\n\n    func start() {\n        logger.debug(\"USBMuxClient starting\")\n\n        guard !started else {\n            logger.warn(\"USBMuxClient already started\")\n            return\n        }\n        started = true\n\n        let broadcastConnection = USBMuxBroadcastConnection(logger: logger)\n        self.broadcastConnection = broadcastConnection\n        broadcastConnection.delegate = self\n        broadcastConnection.start()\n    }\n\n    // MARK: USBMuxBroadcastConnectionDelegate\n\n    func broadcastConnection(_ connection: USBMuxBroadcastConnection, started result: Result<Void, Error>) {\n        switch result {\n        case .success:\n            logger.info(\"USBMuxClient started listening for USB iOS devices\")\n        case let .failure(error):\n            logger.error(\"USBMuxClient failed to start: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    func broadcastConnection(_ connection: USBMuxBroadcastConnection, stopped result: Result<Void, Error>) {\n        switch result {\n        case .success:\n            logger.info(\"USBMuxClient stopped listening for USB iOS devices\")\n        case let .failure(error):\n            logger.error(\"USBMuxClient stopped with error: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    func broadcastConnection(_ connection: USBMuxBroadcastConnection, deviceAttached deviceId: USBMuxDeviceId) {\n        // TODO: print device properties too?\n        logger.info(\"USB iOS device attached: \\(deviceId)\")\n\n        queue.async { [weak self, port = devicePortNumber] in\n            guard let self else { return }\n            let deviceConnection = USBMuxDeviceConnection(logger: self.logger, deviceId: deviceId, port: port)\n            self.deviceConnections[deviceId] = deviceConnection\n            deviceConnection.delegate = self\n            deviceConnection.start()\n        }\n    }\n\n    func broadcastConnection(_ connection: USBMuxBroadcastConnection, deviceDetached deviceId: USBMuxDeviceId) {\n        logger.info(\"USB iOS device detached: \\(deviceId)\")\n\n        queue.async { [weak self] in\n            guard let deviceConnection = self?.deviceConnections.removeValue(forKey: deviceId) else {\n                return\n            }\n            self?.delegate?.usbMuxClientDeviceDisconnected(self!, deviceId: deviceId)\n            deviceConnection.stop()\n        }\n    }\n\n    // MARK: USBMuxDeviceConnectionDelegate\n\n    func deviceConnection(_ connection: USBMuxDeviceConnection, established channel: DispatchIO) {\n        logger.debug(\"USBMuxClient connection \\(connection) established\")\n        let deviceId = connection.deviceId\n\n        queue.async { [weak self] in\n            guard let this = self else { return }\n\n            guard this.deviceConnections[deviceId] === connection else {\n                return\n            }\n            this.delegate?.usbMuxClientDeviceConnected(this, deviceId: deviceId, connection: connection)\n        }\n    }\n\n    func deviceConnection(_ connection: USBMuxDeviceConnection, stopped result: Result<Void, Error>) {\n        logger.debug(\"USBMuxClient connection \\(connection) stopped with result: \\(result)\")\n        let deviceId = connection.deviceId\n\n        queue.async { [weak self] in\n            guard let this = self else { return }\n\n            guard this.deviceConnections[deviceId] === connection else {\n                return\n            }\n\n            this.delegate?.usbMuxClientDeviceDisconnected(this, deviceId: deviceId)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/USBMuxClient/USBMuxConnection.swift",
    "content": "//\n//  USBMuxConnection.swift\n//  Compiler\n//\n//  Created by saniul on 09/10/2019.\n//\n\nimport Foundation\nimport BlueSocket\n\nenum USBMuxResponseCode: UInt32 {\n    case ok = 0\n    case badCommand = 1\n    case badDevice = 2\n    case connectionRefused = 3\n    // ??? = 4\n    // ??? = 5\n    case badVersion = 6\n}\n\nenum USBMuxRequestType: String {\n    case listen = \"Listen\"\n    case connect = \"Connect\"\n}\n\nstruct USBMuxDeviceId: Hashable, CustomStringConvertible {\n    let deviceId: Int\n\n    init(_ deviceId: Int) {\n        self.deviceId = deviceId\n    }\n\n    var description: String {\n        return deviceId.description\n    }\n}\n\nstruct USBMuxDeviceInfo {\n    let deviceId: USBMuxDeviceId\n    let properties: [String: Any]\n}\n\nclass USBMuxConnection {\n    var channel: DispatchIO?\n    var broadcastHandler: ((_ packet: USBMuxPlistPayload) -> Void)?\n\n    private let logger: ILogger\n    private let queue: DispatchQueue\n    var socket: Socket?\n    private var nextPacketTag: USBMuxPacketTag = 0\n    private var waitingCallbacks: [USBMuxPacketTag: ((Result<USBMuxPlistPayload, Error>) -> Void)] = [:]\n    private var isReadingPackets: Bool = false\n    private var shouldAutoReadPackets: Bool { broadcastHandler != nil }\n\n    init(logger: ILogger, queue: DispatchQueue) {\n        self.logger = logger\n        self.queue = queue\n    }\n\n    deinit {\n        channel?.close()\n    }\n\n    func open(onEnd: @escaping (Result<Void, Error>) -> Void) throws {\n        guard channel == nil else {\n            fatalError(\"Channel should not be open when calling open()\")\n        }\n\n        guard let socketSig = try Socket.Signature(socketType: .stream, proto: .unix, path: \"/var/run/usbmuxd\") else {\n            throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)\n        }\n\n        let socket = try Socket.create(connectedUsing: socketSig)\n        self.socket = socket\n        guard socket.isConnected else {\n            throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)\n        }\n\n        channel = DispatchIO(type: .stream, fileDescriptor: socket.socketfd, queue: queue, cleanupHandler: { [socket] (errno: Int32) in\n            // Intentional retain, need to clean up the channel before we clean up the socket\n            _ = socket\n\n            if errno == 0 {\n                onEnd(.success(()))\n            } else {\n                let error = NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)\n                onEnd(.failure(USBMuxError.ioFailure(error)))\n            }\n        })\n    }\n\n    func sendRequest(_ payload: USBMuxPlistPayload, callback: @escaping (Result<Void, Error>) -> Void) {\n        nextPacketTag += 1\n        let tag = nextPacketTag\n\n        sendPacketWithPayload(payload, tag: tag, callback: { [weak self] result in\n            self?.logger.verbose(\"[USBMuxConnection] Sent: error=\\(String(describing: result.failure)) payload=\\(payload) packetTag=\\(tag)\")\n\n            switch result {\n            case let .failure(error):\n                callback(.failure(error))\n            case .success:\n                self?.waitingCallbacks[tag] = { result in\n                    guard let this = self else { return }\n                    let transformedResult = result.flatMap(this.checkResponsePayload)\n                    callback(transformedResult)\n                }\n            }\n        })\n\n        if !isReadingPackets {\n            scheduleReadPacket()\n        }\n    }\n\n    func scheduleReadPacket() {\n        assert(!isReadingPackets)\n\n        scheduleReadPacketWithCallback { [weak self] (packetTag, result) in\n            guard let this = self else { return }\n\n            this.logger.verbose(\"[USBMuxConnection] Received: error=\\(String(describing: result.failure)) packet=\\(String(describing: result.success)) packetTag=\\(packetTag)\")\n            if packetTag == 0 {\n                // Broadcast message\n                switch result {\n                case let .success(packet):\n                    this.broadcastHandler?(packet)\n                case let .failure(error):\n                    this.logger.error(\"Packet read failure: \\(error.legibleLocalizedDescription)\")\n                }\n            } else {\n                // Response\n                if let requestCallback = this.waitingCallbacks[packetTag] {\n                    this.waitingCallbacks[packetTag] = nil\n                    requestCallback(result)\n                } else {\n                    this.logger.warn(\"[USBMuxConnection] Warning: Ignoring response packet for which there is no registered callback. error=\\(String(describing: result.failure)) packet=\\(String(describing: result.success))\")\n                }\n            }\n\n            if this.shouldAutoReadPackets {\n                this.scheduleReadPacket()\n            }\n        }\n    }\n\n    // MARK: Private\n\n    private func sendDispatchData(data: DispatchData, callback: @escaping (Result<Void, Error>) -> Void) {\n        guard let channel = channel else {\n            fatalError(\"Channel should exist by now\")\n        }\n\n        channel.write(offset: 0, data: data, queue: queue, ioHandler: { (done: Bool, _: DispatchData?, errno: Int32) in\n            guard done else {\n                return\n            }\n\n            if errno == 0 {\n                callback(.success(()))\n            } else {\n                callback(.failure(NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)))\n            }\n        })\n    }\n\n    private func sendData(data: Data, callback: @escaping (Result<Void, Error>) -> Void) {\n        // retaining the passed-in data using a block capture to avoid having DispatchData\n        // copy the bytes\n        var tmp: Data? = data\n        let dispatchData: DispatchData = data.withUnsafeBytes { bytes in\n            return DispatchData(bytesNoCopy: bytes, deallocator: .custom(queue, {\n                _ = tmp\n                tmp = nil\n            }))\n        }\n        sendDispatchData(data: dispatchData, callback: callback)\n    }\n\n    private func readFromOffset(offset: off_t, length: size_t, callback: @escaping (Result<DispatchData, Error>) -> Void) {\n        guard let channel = channel else {\n            fatalError(\"Channel should exist by now\")\n        }\n\n        channel.read(offset: offset, length: length, queue: queue) { (done: Bool, data: DispatchData?, errno: Int32) in\n            guard done else {\n                return\n            }\n\n            guard let data = data else {\n                callback(.failure(USBMuxError.readEmptyData))\n                return\n            }\n\n            if errno == 0 {\n                callback(.success(data))\n            } else {\n                let error = NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)\n                callback(.failure(USBMuxError.ioFailure(error)))\n            }\n        }\n    }\n\n    private func checkResponsePayload(_ payload: USBMuxPlistPayload) -> Result<Void, Error> {\n        guard let responseNumber = payload[\"Number\"] as? Int else {\n            return .failure(USBMuxError.unknown)\n        }\n\n        guard responseNumber != 0 else {\n            return .success(())\n        }\n\n        guard let responseCode = USBMuxResponseCode(rawValue: UInt32(responseNumber)) else {\n            return .failure(USBMuxError.unknownResponse(responseCode: UInt32(responseNumber)))\n        }\n\n        return .failure(USBMuxError.failedResponse(responseCode))\n    }\n\n    private func sendPacketOfType(_ type: USBMuxPacketType, overProtocol protocol: USBMuxPacketProtocol, tag: UInt32, payload: Data, callback: @escaping (Result<Void, Error>) -> Void) {\n        let upacket = USBMuxPacket(protocol: `protocol`, type: type, tag: tag, payload: payload)\n        let data = upacket.fullPacketData.withUnsafeBytes { bytes in\n            DispatchData(bytes: bytes)\n        }\n        sendDispatchData(data: data, callback: callback)\n    }\n\n    private func sendPacketWithPayload(_ payload: USBMuxPlistPayload, tag: UInt32, callback: @escaping (Result<Void, Error>) -> Void) {\n        do {\n            let payloadData = try PropertyListSerialization.data(fromPropertyList: payload, format: .xml, options: .zero)\n            sendPacketOfType(.plistPayload, overProtocol: .plist, tag: tag, payload: payloadData, callback: callback)\n        } catch {\n            callback(.failure(error))\n        }\n    }\n\n    private func scheduleReadPacketWithCallback(callback: @escaping (_ packetTag: UInt32, Result<USBMuxPlistPayload, Error>) -> Void) {\n        isReadingPackets = true\n\n        scheduleReadPacketSize(callback: callback)\n    }\n\n    private func scheduleReadPacketSize(callback: @escaping (_ packetTag: UInt32, Result<USBMuxPlistPayload, Error>) -> Void) {\n        guard let channel = channel else {\n            fatalError(\"Channel should exist by now\")\n        }\n\n        channel.read(offset: 0,\n                     length: Int(USBMuxPacket.fullSizeLayoutSize),\n                     queue: queue,\n                     ioHandler: { [weak self] (done: Bool, dispatchData: DispatchData?, errno: Int32) in\n                        self?.handleReadPacketSize(done: done, dispatchData: dispatchData, errno: errno, callback: callback)\n        })\n    }\n\n    private func handleReadPacketSize(done: Bool, dispatchData: DispatchData?, errno: Int32, callback: @escaping (_ packetTag: UInt32, Result<USBMuxPlistPayload, Error>) -> Void) {\n        guard done else { return }\n\n        guard errno == 0 else {\n            isReadingPackets = false\n            let error = NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)\n            callback(0, .failure(USBMuxError.ioFailure(error)))\n            return\n        }\n\n        guard let dispatchData = dispatchData else {\n            callback(0, .failure(USBMuxError.readEmptyData))\n            return\n        }\n\n        let fullPacketSize: UInt32 = dispatchData.withUnsafeBytes(body: { (pointer: UnsafePointer<UInt32>) in\n            return pointer.pointee\n        })\n        let metaAndPayloadSize = fullPacketSize - USBMuxPacket.fullSizeLayoutSize\n        let offset = USBMuxPacket.fullSizeLayoutSize\n\n        scheduleReadPacketBody(offset: off_t(offset),\n                                    metaAndPayloadSize: Int(metaAndPayloadSize),\n                                    callback: callback)\n    }\n\n    private func scheduleReadPacketBody(offset: off_t, metaAndPayloadSize: Int, callback: @escaping (_ packetTag: UInt32, Result<USBMuxPlistPayload, Error>) -> Void) {\n        guard let channel = channel else {\n            fatalError(\"Channel should exist by now\")\n        }\n\n        channel.read(offset: off_t(offset),\n                     length: Int(metaAndPayloadSize),\n                     queue: queue,\n                     ioHandler: { [weak self] (done: Bool, dispatchData: DispatchData?, errno: Int32) in\n                        self?.handleReadPacketBody(done: done, dispatchData: dispatchData, errno: errno, callback: callback)\n        })\n    }\n\n    private func handleReadPacketBody(done: Bool, dispatchData: DispatchData?, errno: Int32, callback: @escaping (_ packetTag: UInt32, Result<USBMuxPlistPayload, Error>) -> Void) {\n        guard done else { return }\n\n        isReadingPackets = false\n\n         guard errno == 0 else {\n             let error = NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)\n             callback(0, .failure(USBMuxError.ioFailure(error)))\n             return\n         }\n\n         guard let dispatchData = dispatchData else {\n             callback(0, .failure(USBMuxError.readEmptyData))\n             return\n         }\n\n         let data = Data(dispatchData)\n         guard let packet = USBMuxPacket(metaAndPayloadData: data) else {\n             callback(0, .failure(USBMuxError.couldntParsePacket))\n             return\n         }\n\n         guard case .plist = packet.protocol else {\n             callback(packet.tag, .failure(USBMuxError.unexpectedPacketProtocol))\n             return\n         }\n\n         guard case .plistPayload = packet.type else {\n             callback(packet.tag, .failure(USBMuxError.unexpectedPacketType))\n             return\n         }\n\n         do {\n             let plistResult = try PropertyListSerialization.propertyList(from: packet.payload, options: [], format: nil)\n             guard let dict = plistResult as? USBMuxPlistPayload else {\n                 callback(packet.tag, .failure(USBMuxError.invalidPlistPayload))\n                 return\n             }\n             callback(packet.tag, .success(dict))\n         } catch {\n             callback(packet.tag, .failure(error))\n             return\n         }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/USBMuxClient/USBMuxDeviceConnection.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by saniul on 10/10/2019.\n//\n\nimport Foundation\nimport BlueSocket\n\nprotocol USBMuxDeviceConnectionDelegate: AnyObject {\n    func deviceConnection(_ connection: USBMuxDeviceConnection, established channel: DispatchIO)\n    func deviceConnection(_ connection: USBMuxDeviceConnection, stopped result: Result<Void, Error>)\n}\n\nclass USBMuxDeviceConnection {\n    let deviceId: USBMuxDeviceId\n    let port: Int\n    weak var delegate: USBMuxDeviceConnectionDelegate?\n\n    var channel: DispatchIO? { return connection?.channel }\n    var key: String { return \"usb:\\(deviceId):\\(port)\" }\n    var socket: Socket? { return connection?.socket }\n\n    private let logger: ILogger\n    private let queue: DispatchQueue\n    private var connection: USBMuxConnection?\n\n    init(logger: ILogger, deviceId: USBMuxDeviceId, port: Int) {\n        self.logger = logger\n        self.deviceId = deviceId\n        self.port = ((port << 8) & 0xFF00) | (port >> 8)\n        let queue = DispatchQueue(label: \"USBMuxDeviceConnection(\\(deviceId):\\(port))\")\n        self.queue = queue\n    }\n\n    func start() {\n        queue.async { [weak self] in\n            self?.attemptConnecting()\n        }\n    }\n\n    func stop() {\n        channel?.close()\n    }\n\n    private func cleanUpAndScheduleNextAttempt() {\n        self.connection = nil\n        queue.asyncAfter(deadline: .now() + 1) { [weak self] in\n            self?.attemptConnecting()\n        }\n    }\n\n    private func attemptConnecting() {\n        assert(connection == nil)\n\n        let connection = USBMuxConnection(logger: logger, queue: queue)\n        self.connection = connection\n\n        do {\n            try connection.open(onEnd: { [weak self, weak connection] result in\n                guard let this = self, let connection = connection else { return }\n                this.handleConnectionEnded(connection, result: result)\n            })\n        } catch {\n            cleanUpAndScheduleNextAttempt()\n            return\n        }\n\n        let packet = USBMuxPacket.packetPayloadWithRequestType(.connect, contents: [\n            \"DeviceID\": deviceId.deviceId,\n            \"PortNumber\": port\n        ])\n\n        connection.sendRequest(packet, callback: { [weak self, weak connection] result in\n            guard let this = self else { return }\n\n            guard case .success = result else {\n                this.cleanUpAndScheduleNextAttempt()\n                return\n            }\n\n            guard let channel = connection?.channel else {\n                fatalError(\"Channel should exist by now\")\n            }\n\n            this.delegate?.deviceConnection(this, established: channel)\n        })\n    }\n\n    private func handleConnectionEnded(_ connection: USBMuxConnection, result: Result<Void, Error>) {\n        guard self.connection === connection else {\n            // Irrelevant connection\n            return\n        }\n        delegate?.deviceConnection(self, stopped: result)\n        cleanUpAndScheduleNextAttempt()\n    }\n}\n\nextension USBMuxDeviceConnection: CustomStringConvertible {\n    var description: String { return key }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/USBMuxClient/USBMuxError.swift",
    "content": "//\n//  USBMuxError.swift\n//  Compiler\n//\n//  Created by saniul on 09/10/2019.\n//\n\nimport Foundation\n\nenum USBMuxError: Error {\n    case unknown\n\n    case failedResponse(USBMuxResponseCode)\n    case unknownResponse(responseCode: UInt32)\n\n    case ioFailure(NSError)\n    case readEmptyData\n\n    case couldntParsePacket\n    case unexpectedPacketProtocol\n    case unexpectedPacketType\n    case invalidPlistPayload\n    case timeout \n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/USBMuxClient/USBMuxPacket.swift",
    "content": "//\n//  USBMuxPacket.swift\n//  Compiler\n//\n//  Created by saniul on 09/10/2019.\n//\n\nimport Foundation\n\nenum USBMuxPacketProtocol: UInt32 {\n    case binary = 0\n    case plist = 1\n}\n\nenum USBMuxPacketType: UInt32 {\n    case result = 1\n    case connect = 2\n    case listen = 3\n    case add = 4\n    case remove = 5\n    // ??? = 6\n    // ??? = 7\n    case plistPayload = 8\n\n    var stringValue: String {\n        return \"\\(self)\"\n    }\n}\n\ntypealias USBMuxPacketSize = UInt32\ntypealias USBMuxPacketTag = UInt32\ntypealias USBMuxPlistPayload = [String: Any]\n\nstruct USBMuxPacket {\n    let `protocol`: USBMuxPacketProtocol\n    let type: USBMuxPacketType\n    let tag: USBMuxPacketTag\n    let payload: Data\n\n    static var fullSizeLayoutSize: UInt32 {\n        return UInt32(MemoryLayout<USBMuxPacketSize>.stride)\n    }\n\n    static var metaLayoutSize: UInt32 {\n        let metaSize: Int =\n            MemoryLayout<USBMuxPacketProtocol.RawValue>.stride +\n                MemoryLayout<USBMuxPacketType.RawValue>.stride +\n                MemoryLayout<USBMuxPacketTag>.stride\n        return UInt32(metaSize)\n    }\n\n    var fullPacketSize: USBMuxPacketSize {\n        return Self.fullSizeLayoutSize + Self.metaLayoutSize + UInt32(payload.count)\n    }\n\n    var fullPacketData: Data {\n        var data = Data()\n        // packet size\n        data.append(integer: fullPacketSize)\n\n        // meta\n        data.append(integer: `protocol`.rawValue)\n        data.append(integer: type.rawValue)\n        data.append(integer: tag)\n\n        // payload\n        data.append(payload)\n        return data\n    }\n\n    init(protocol: USBMuxPacketProtocol, type: USBMuxPacketType, tag: USBMuxPacketTag, payload: Data) {\n        self.protocol = `protocol`\n        self.type = type\n        self.tag = tag\n        self.payload = payload\n    }\n\n    init?(metaAndPayloadData: Data) {\n        // NOTE: data does not include packet size by this point\n        let protoRange = (0..<MemoryLayout<USBMuxPacketProtocol.RawValue>.stride)\n        let protoRaw: USBMuxPacketProtocol.RawValue = metaAndPayloadData[protoRange]\n            .withUnsafePointer { pointer in return pointer.pointee }\n\n        let typeRange = (protoRange.endIndex..<protoRange.endIndex + MemoryLayout<USBMuxPacketType.RawValue>.stride)\n        let typeRaw: USBMuxPacketType.RawValue = metaAndPayloadData[typeRange]\n            .withUnsafePointer { pointer in return pointer.pointee }\n\n        let tagRange = (typeRange.endIndex..<typeRange.endIndex + MemoryLayout<USBMuxPacketTag>.stride)\n        let tag: USBMuxPacketTag = metaAndPayloadData[tagRange]\n            .withUnsafePointer { pointer in return pointer.pointee }\n\n        let payload = metaAndPayloadData[tagRange.endIndex...]\n\n        guard let `protocol` = USBMuxPacketProtocol(rawValue: protoRaw),\n            let type = USBMuxPacketType(rawValue: typeRaw) else {\n                return nil\n        }\n\n        self = USBMuxPacket(protocol: `protocol`, type: type, tag: tag, payload: payload)\n    }\n\n    private static let bundleName = Bundle.main.infoDictionary?[\"CFBundleName\"]\n    private static let bundleVersion = Bundle.main.infoDictionary?[\"CFBundleVersion\"] ?? \"1\"\n\n    static func packetPayloadWithRequestType(_ requestType: USBMuxRequestType, contents: USBMuxPlistPayload) -> USBMuxPlistPayload {\n        let payload: USBMuxPlistPayload\n\n        if let bundleName = bundleName {\n            payload = [\n                \"MessageType\": requestType.rawValue,\n                \"ProgName\": bundleName,\n                \"ClientVersionString\": bundleVersion\n            ]\n        } else {\n            payload = [\n                \"MessageType\": requestType.rawValue\n            ]\n        }\n\n        let finalPayload = payload.merging(contents, uniquingKeysWith: { $1 })\n        return finalPayload as USBMuxPlistPayload\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/USBMuxClient/USBMuxTunnel.swift",
    "content": "//\n//  USBMuxTunnel.swift\n//  Compiler\n//\n//  Created by elee2 on 02/13/2024.\n//\n\nimport Foundation\n\nstruct USBMuxTunnelPendingTCPConnection {\n    let deviceConnection: USBMuxDeviceConnection\n    let promise: Promise<TCPConnection>\n}\n\nclass USBMuxTunnel : TCPTunnel {\n    private var deviceId: USBMuxDeviceId\n    private var devicePort: Int\n    private var pendingTCPConnections: [USBMuxTunnelPendingTCPConnection] = []\n    private let queue = DispatchQueue(label: \"USBMuxTunnel\")\n\n    init(logger: ILogger, listenPort: Int, deviceId: USBMuxDeviceId, devicePort: Int) throws {        \n        self.deviceId = deviceId\n        self.devicePort = devicePort\n        try super.init(logger: logger, port: listenPort)\n    }\n\n    override func destinationConnectionProvider() throws -> Promise<TCPConnection> {\n        let promise = Promise<TCPConnection>()\n        self.queue.async { [self, promise] in\n            let deviceConnection = USBMuxDeviceConnection(logger: self.logger, deviceId: self.deviceId, port: self.devicePort)\n            deviceConnection.delegate = self\n            deviceConnection.start()\n            let pendingTCPConnection = USBMuxTunnelPendingTCPConnection(deviceConnection: deviceConnection, promise: promise)\n            self.pendingTCPConnections.append(pendingTCPConnection)\n\n            self.queue.asyncAfter(deadline: .now() + 3) { [self] in\n                self.pendingTCPConnections.first(where: { $0.deviceConnection === deviceConnection })?.promise.reject(error: USBMuxError.timeout)\n                self.pendingTCPConnections.removeAll { $0.deviceConnection === deviceConnection }\n            }\n        }\n        return promise\n    }\n}\n\nextension USBMuxTunnel : USBMuxDeviceConnectionDelegate {\n    func deviceConnection(_ deviceConnection: USBMuxDeviceConnection, established channel: DispatchIO) {\n        self.queue.async { [weak self] in\n            guard let self = self else { return }\n            let tcpConnection = BlueSocketTCPConnection(logger: self.logger, socket: deviceConnection.socket!, queueNamePrefix: \"USBMuxTunnelDeviceConnection\")\n            self.pendingTCPConnections.first(where: { $0.deviceConnection === deviceConnection })?.promise.resolve(data: tcpConnection)\n            self.pendingTCPConnections.removeAll { $0.deviceConnection === deviceConnection }\n        }\n    }\n\n    func deviceConnection(_ deviceConnection: USBMuxDeviceConnection, stopped result: Result<Void, Error>) {\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ArtifactUploader.swift",
    "content": "//\n//  ArtifactUploader.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 8/8/19.\n//\n\nimport Foundation\n#if canImport(FoundationNetworking)\nimport FoundationNetworking\n#endif\nimport SwiftProtobuf\nimport Chalk\n\nstruct ArtifactInfo: Codable {\n    let url: URL\n    let sha256Digest: String\n}\n\n/// Upload artifacts to a remote endpoint\nclass ArtifactUploader {\n    private let moduleBaseUploadURL: URL\n    private let companionExecutable: CompanionExecutable\n\n    private var pendingPreparedArtifact = Synchronized(data: [String: File]())\n\n    init(moduleBaseUploadURL: URL, companionExecutable: CompanionExecutable) {\n        self.moduleBaseUploadURL = moduleBaseUploadURL\n        self.companionExecutable = companionExecutable\n    }\n\n    func makePreparedUploadArtifact() throws -> File {\n        let allItems = pendingPreparedArtifact.data { data in\n            return data\n        }\n\n        let builder = ValdiModuleBuilder(items: allItems.map { ZippableItem(file: $0.value, path: $0.key) })\n        builder.compress = false\n        return .data(try builder.build())\n    }\n\n    func appendToPreparedArtifact(artifactName: String, artifactData: Data, sha256: String) -> Promise<ArtifactInfo> {\n        let outputFilename = \"\\(artifactName)-\\(sha256)\"\n\n        pendingPreparedArtifact.data { dict in\n            dict[outputFilename] = .data(artifactData)\n        }\n\n        let resultURL = moduleBaseUploadURL.appendingPathComponent(outputFilename)\n        let artifactInfo = ArtifactInfo(url: resultURL, sha256Digest: sha256)\n        return Promise(data: artifactInfo)\n    }\n\n    func upload(artifactName: String, artifactData: Data, sha256: String) -> Promise<ArtifactInfo> {\n        let key = sha256\n        return companionExecutable.uploadArtifact(artifactName: artifactName, artifactData: artifactData, sha256: sha256)\n    }\n\n    static func uploadFiles(fileManager: ValdiFileManager, paths: [String], baseURL: URL, out: String?, moduleBaseUploadURL: URL?, companionExectuable: CompanionExecutable) throws {\n        guard let moduleBaseUploadURL = moduleBaseUploadURL else {\n            throw CompilerError(\"--upload-base-url must be provided when using the --upload-module utility command\")\n        }\n\n        let outputURL = try CLIUtils.getOutputURLs(commandName: \"--upload-module\", baseUrl: baseURL, out: out)\n\n        for inputPath in paths {\n            let inputURL = baseURL.resolving(path: inputPath)\n\n            let fileData = try File.url(inputURL).readData()\n\n            let artifactUploader = ArtifactUploader(moduleBaseUploadURL: moduleBaseUploadURL, companionExecutable: companionExectuable)\n\n            let artifactName = inputURL.lastPathComponent\n            let sha256Digest = try fileData.generateSHA256Digest()\n            let artifactInfo = try artifactUploader.upload(artifactName: artifactName, artifactData: fileData, sha256: sha256Digest).waitForData()\n\n            let outputFileContent = [artifactInfo.url.absoluteString, artifactInfo.sha256Digest].joined(separator: \"\\n\")\n            try fileManager.save(data: outputFileContent.utf8Data(), to: outputURL)\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/AsyncTaskQueue.swift",
    "content": "//\n//  Throttler.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/11/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass AsyncTaskQueue {\n\n    private let maxOperationsCount: Int\n\n    private let lock = DispatchSemaphore.newLock()\n    private var pendingOperations = [(@escaping () -> Void) -> Void]()\n    private var currentOperationsCount = 0\n\n    init(maxOperationsCount: Int) {\n        self.maxOperationsCount = maxOperationsCount\n    }\n\n    func enqueue<T>(_ work: @escaping  () -> Promise<T>) -> Promise<T> {\n        let promise = Promise<T>()\n\n        onReady { completion in\n            _ = work().then { (data) -> Void in\n                promise.resolve(data: data)\n                completion()\n                }.catch { (error) -> Void in\n                    promise.reject(error: error)\n                    completion()\n            }\n        }\n\n        return promise\n    }\n\n    private func dequeueIfNeeded() -> ((@escaping () -> Void) -> Void)? {\n        return lock.lock {\n            // should have the lock\n            guard currentOperationsCount < maxOperationsCount, !pendingOperations.isEmpty else {\n                return nil\n            }\n\n            currentOperationsCount += 1\n            return pendingOperations.removeFirst()\n        }\n    }\n\n    private func runOperations() {\n        while true {\n            guard let work = dequeueIfNeeded() else {\n                return\n            }\n\n            work {\n                self.lock.lock {\n                    self.currentOperationsCount -= 1\n                }\n                self.runOperations()\n            }\n        }\n    }\n\n    private func onReady(_ work: @escaping (@escaping () -> Void) -> Void) {\n        lock.lock {\n            pendingOperations.append(work)\n        }\n        runOperations()\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/BackoffTimer.swift",
    "content": "//\n//  BackoffTimer.swift\n//  Compiler\n//\n//  Created by saniul on 27/12/2018.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class BackoffTimer {\n    private let label: String\n    private let block: () -> Void\n\n    var minTimeInterval: TimeInterval = 0\n    var maxTimeInterval: TimeInterval = 60\n    var bumpModifier: (TimeInterval) -> TimeInterval = { max(1, $0) * 2 }\n\n    lazy var currentTimeInterval: TimeInterval = { return minTimeInterval }()\n\n    private var timer: Timer? {\n        didSet {\n            oldValue?.invalidate()\n        }\n    }\n\n    init(label: String = \"\", block: @escaping () -> Void) {\n        self.label = label\n        self.block = block\n    }\n\n    deinit {\n        timer = nil\n    }\n\n    func bump() {\n        let bumpedTimeInterval = bumpModifier(currentTimeInterval)\n        currentTimeInterval = min(maxTimeInterval, bumpedTimeInterval)\n        if #available(OSX 10.12, *) {\n            timer = Timer.scheduledTimer(withTimeInterval: currentTimeInterval, repeats: false, block: { [weak self] _ in\n                self?.block()\n            })\n        }\n    }\n\n    func reset() {\n        timer = nil\n        currentTimeInterval = minTimeInterval\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/BatchSequence.swift",
    "content": "//\n//  BatchSequence.swift\n//  Compiler\n//\n//  Created by saniul on 26/06/2019.\n//\n\nimport Foundation\n\nstruct BatchSequence<T>: Sequence, IteratorProtocol {\n\n    private let array: [T]\n    private let distance: Int\n    private var index = 0\n\n    init(array: [T], distance: Int) {\n        precondition(distance > 0 || (distance == 0 && array.isEmpty), \"distance must be greater than 0\") // prevents infinite loop\n        self.array = array\n        self.distance = distance\n    }\n\n    mutating func next() -> [T]? {\n        guard index < array.endIndex else { return nil }\n        let newIndex = index.advanced(by: distance) > array.endIndex ? array.endIndex : index.advanced(by: distance)\n        defer { index = newIndex }\n        return Array(array[index ..< newIndex])\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/BatchWorkerQueue.swift",
    "content": "//\n//  BatchWorkerQueue.swift\n//  \n//\n//  Created by Simon Corsin on 2/12/20.\n//\n\nimport Foundation\n\n/**\n A generic worker queue which can process items\n in batch as they are added.\n */\nclass BatchWorkerQueue<In, Out> {\n\n    private struct WorkItem {\n        let item: In\n        let promise: Promise<Out>\n    }\n\n    private let queue: DispatchQueue\n    private let processor: ([In]) throws -> [Result<Out, Error>]\n    private let lock = DispatchSemaphore.newLock()\n    private var workItems: [WorkItem] = []\n\n    init(queue: DispatchQueue, processor: @escaping ([In]) throws -> [Result<Out, Error>]) {\n        self.queue = queue\n        self.processor = processor\n    }\n\n    func enqueue(item: In) -> Promise<Out> {\n        let promise = Promise<Out>()\n\n        lock.lock {\n            self.workItems.append(WorkItem(item: item, promise: promise))\n        }\n\n        queue.async {\n            self.process()\n        }\n\n        return promise\n    }\n\n    private func dequeueAllItems() -> [WorkItem] {\n        return lock.lock {\n            let items = self.workItems\n            self.workItems = []\n            return items\n        }\n    }\n\n    private func process() {\n        let itemsToProcess = self.dequeueAllItems()\n\n        guard !itemsToProcess.isEmpty else { return }\n\n        let items = itemsToProcess.map { $0.item }\n\n        do {\n            let results = try processor(items)\n            guard results.count == items.count else {\n                throw CompilerError(\"Processor should have returned \\(items.count) results instead of \\(results.count)\")\n            }\n\n            for (index, result) in results.enumerated() {\n                itemsToProcess[index].promise.fulfill(result: result)\n            }\n        } catch let error {\n            itemsToProcess.forEach { (workItem) in\n                workItem.promise.reject(error: error)\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/BlueSocketTCPConnection.swift",
    "content": "//\n//  BlueSocketTCPConnection.swift\n//  Compiler\n//\n//  Created by saniul on 07/10/2019.\n//\n\nimport Foundation\nimport BlueSocket\n\nclass BlueSocketTCPConnection: TCPConnection {\n    weak var delegate: TCPConnectionDelegate?\n    var dataProcessor: TCPConnectionDataProcessor?\n\n    let key: String\n    let socket: Socket\n\n    private let logger: ILogger\n    private let sendQueue: DispatchQueue\n    private let recvQueue: DispatchQueue\n    private var startedListening: Bool = false\n    private var buffer = Data()\n\n    init(logger: ILogger, socket: Socket, queueNamePrefix: String) {\n        self.logger = logger\n        key = \"tcp:\\(socket.remoteHostname):\\(socket.remotePort)\"\n        sendQueue = DispatchQueue(label: \"\\(queueNamePrefix).\\(key).send\")\n        recvQueue = DispatchQueue(label: \"\\(queueNamePrefix).\\(key).recv\")\n        self.socket = socket\n    }\n\n    deinit {\n        socket.close()\n    }\n\n    func startListening() {\n        guard !startedListening else {\n            return\n        }\n\n        startedListening = true\n        recvQueue.async {\n            self.receiveLoop()\n        }\n    }\n\n    func close() {\n        closeConnection(error: nil)\n    }\n\n    func send(data: Data) {\n        sendQueue.async {\n            do {\n                self.logger.verbose(\"Writing \\(data.count) bytes to socket \\(self.key)\")\n                try self.socket.write(from: data)\n            } catch let error {\n                self.logger.error(\"Error while writing to {\\(self.key)}: \\(error.legibleLocalizedDescription)\")\n                self.closeConnection(error: error)\n            }\n        }\n    }\n\n    private func receiveLoop() {\n        repeat {\n            do {\n                let bytesRead = try socket.read(into: &buffer)\n                if bytesRead == 0 && socket.remoteConnectionClosed {\n                    closeConnection(error: nil)\n                    return\n                } else if bytesRead > 0 {\n                    _ = processBuffer(&buffer)\n                }\n            } catch let error {\n                logger.debug(\"Error while reading from {\\(key)}: \\(error.legibleLocalizedDescription)\")\n                closeConnection(error: error)\n            }\n        } while socket.isActive\n    }\n\n    private func closeConnection(error: Error?) {\n        logger.debug(\"Closing reloader connection \\(key) with error \\(error?.legibleLocalizedDescription ?? \"\")\")\n        socket.close()\n        delegate?.connection(self, didDisconnectWithError: error)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/CLIUtils.swift",
    "content": "//\n//  CLIUtils.swift\n//  \n//\n//  Created by Simon Corsin on 7/29/20.\n//\n\nimport Foundation\n\nclass CLIUtils {\n\n    static func getOutputURLs(commandName: String, baseUrl: URL, out: String?) throws -> URL {\n        guard let out = out else {\n            throw CompilerError(\"--out must be provided when using \\(commandName) to specify the output file\")\n        }\n\n        return baseUrl.resolving(path: out)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Caching/DiskCache.swift",
    "content": "import Foundation\n\nprotocol DiskCache: AnyObject {\n\n    func getOutput(compilationItem: CompilationItem, inputData: Data) -> Data?\n\n    func getOutput(item: String, platform: Platform?, target: OutputTarget, inputData: Data) -> Data?\n\n    func getOutput(item: String, inputData: Data) -> Data?\n\n    func getExpectedOutputURL(item: String) -> URL\n\n    func getURL() -> URL\n\n    func setOutput(compilationItem: CompilationItem, inputData: Data, outputData: Data) throws\n\n    func setOutput(item: String, platform: Platform?, target: OutputTarget, inputData: Data, outputData: Data) throws\n\n    func setOutput(item: String, inputData: Data, outputData: Data) throws\n\n    func removeOutput(item: String)\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Caching/DiskCacheImpl.swift",
    "content": "//\n//  DiskCache.swift\n//  \n//\n//  Created by Simon Corsin on 10/22/19.\n//\n\nimport Foundation\n\nstruct DiskCacheOutputWithURL {\n    let url: URL\n    let data: Data\n}\n\nclass DiskCacheImpl: DiskCache {\n\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let baseDirectoryURL: URL\n    private let inputDirectoryURL: URL\n    private let outputDirectoryURL: URL\n    private let outputExtension: String\n\n    init(logger: ILogger, fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, cacheName: String, outputExtension: String, metadata: [String: String]) {\n        self.logger = logger\n        self.fileManager = fileManager\n        let cachesRootURL = projectConfig.buildDirectoryURL.appendingPathComponent(\"caches\", isDirectory: true)\n        self.baseDirectoryURL = cachesRootURL.appendingPathComponent(cacheName, isDirectory: true)\n        self.inputDirectoryURL = baseDirectoryURL.appendingPathComponent(\"input\", isDirectory: true)\n        self.outputDirectoryURL = baseDirectoryURL.appendingPathComponent(\"output\", isDirectory: true)\n        self.outputExtension = outputExtension\n\n        try? fileManager.createDirectory(at: baseDirectoryURL)\n\n        let cacheMetadataURL = inputDirectoryURL.appendingPathComponent(\"cache.json\", isDirectory: false)\n\n        if let cacheMedata = getCachedMetadata(url: cacheMetadataURL), cacheMedata == metadata {\n            // All good\n        } else {\n            // Cache is invalid\n\n            do {\n                try fileManager.delete(url: inputDirectoryURL)\n                try fileManager.delete(url: outputDirectoryURL)\n\n                let data = try JSONSerialization.data(withJSONObject: metadata, options: [])\n                try fileManager.save(data: data, to: cacheMetadataURL)\n            } catch let error {\n                logger.error(\"Failed to write cache metadata: \\(error.legibleLocalizedDescription)\")\n            }\n        }\n    }\n\n    private func getCachedMetadata(url: URL) -> [String: String]? {\n        guard let data = try? Data(contentsOf: url) else {\n            return nil\n        }\n\n        guard let object = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: String] else {\n            return nil\n        }\n\n        return object\n    }\n\n    private func getCacheURLs(item: String) -> (inputURL: URL, outputURL: URL) {\n        var outputURL = outputDirectoryURL.appendingPathComponent(item, isDirectory: false)\n        outputURL.deletePathExtension()\n        outputURL.appendPathExtension(outputExtension)\n\n        return (\n            inputDirectoryURL.appendingPathComponent(item, isDirectory: false),\n            outputURL\n        )\n    }\n\n    private func getItemName(item: String, platform: Platform?, target: OutputTarget) -> String {\n        if let platform = platform {\n            return \"\\(target.description)/platform_\\(platform)/\\(item)\"\n        } else {\n            return \"\\(target.description)/platform_all/\\(item)\"\n        }\n    }\n\n    func getOutput(compilationItem: CompilationItem, inputData: Data) -> Data? {\n        return getOutput(item: compilationItem.relativeProjectPath, platform: compilationItem.platform, target: compilationItem.outputTarget, inputData: inputData)\n    }\n\n    func getOutput(item: String, platform: Platform?, target: OutputTarget, inputData: Data) -> Data? {\n        return getOutput(item: getItemName(item: item, platform: platform, target: target), inputData: inputData)\n    }\n\n    func getOutput(item: String, inputData: Data) -> Data? {\n        let urls = getCacheURLs(item: item)\n\n        guard let cacheData = try? Data(contentsOf: urls.inputURL), cacheData == inputData else {\n            return nil\n        }\n\n        guard let outputData = try? Data(contentsOf: urls.outputURL) else {\n            return nil\n        }\n\n        return outputData\n    }\n\n    func getExpectedOutputURL(item: String) -> URL {\n        return getCacheURLs(item: item).outputURL\n    }\n\n    func getURL() -> URL {\n        return baseDirectoryURL\n    }\n\n    func setOutput(compilationItem: CompilationItem, inputData: Data, outputData: Data) throws {\n        try setOutput(item: compilationItem.relativeProjectPath, platform: compilationItem.platform, target: compilationItem.outputTarget, inputData: inputData, outputData: outputData)\n    }\n\n    func setOutput(item: String, platform: Platform?, target: OutputTarget, inputData: Data, outputData: Data) throws {\n        try setOutput(item: getItemName(item: item, platform: platform, target: target), inputData: inputData, outputData: outputData)\n    }\n\n    func setOutput(item: String, inputData: Data, outputData: Data) throws {\n        let urls = getCacheURLs(item: item)\n\n        try fileManager.save(data: inputData, to: urls.inputURL)\n        try fileManager.save(data: outputData, to: urls.outputURL)\n    }\n\n    func removeOutput(item: String) {\n        let urls = getCacheURLs(item: item)\n\n        _ = try? fileManager.delete(url: urls.inputURL)\n        _ = try? fileManager.delete(url: urls.outputURL)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Caching/DiskCacheProvider.swift",
    "content": "import Foundation\n\nclass DiskCacheProvider {\n    private let logger: ILogger\n    private let fileManager: ValdiFileManager\n    private let projectConfig: ValdiProjectConfig\n    private let disableDiskCache: Bool\n\n    init(logger: ILogger, fileManager: ValdiFileManager, projectConfig: ValdiProjectConfig, disableDiskCache: Bool) {\n        self.logger = logger\n        self.fileManager = fileManager\n        self.projectConfig = projectConfig\n        self.disableDiskCache = disableDiskCache\n    }\n\n    func isEnabled() -> Bool {\n        return !disableDiskCache\n    }\n\n    func newCache(cacheName: String, outputExtension: String, metadata: [String: String]) -> DiskCache? {\n        if disableDiskCache {\n            return nil\n        } else {\n            return DiskCacheImpl(logger: logger,\n                                 fileManager: fileManager,\n                                 projectConfig: projectConfig,\n                                 cacheName: cacheName,\n                                 outputExtension: outputExtension,\n                                 metadata: metadata)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Cancelable.swift",
    "content": "//\n//  Cancelable.swift\n//  SwiftUtils-MacOS\n//\n//  Created by Simon Corsin on 11/8/17.\n//  Copyright © 2017 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n/**\n Encapsulate an operation that can be canceled\n */\npublic protocol Cancelable {\n\n    func cancel()\n\n}\n\n/**\n Encapsulate a block that can be run only once and can be canceled.\n */\npublic class CancelableBlock: Cancelable {\n\n    private var block: (() -> Void)?\n\n    public init(block: @escaping () -> Void) {\n        self.block = block\n    }\n\n    public func run() {\n        if let block = block {\n            self.block = nil\n            block()\n        }\n    }\n\n    public func cancel() {\n        block = nil\n    }\n\n}\n\n/**\n Encapsulate a callback that will be called only once when cancel() is called.\n */\npublic class CallbackCancelable: Cancelable {\n\n    private var onCancel: (() -> Void)?\n\n    public init(onCancel: @escaping () -> Void) {\n        self.onCancel = onCancel\n    }\n\n    public func cancel() {\n        if let onCancel = onCancel {\n            self.onCancel = nil\n            onCancel()\n        }\n    }\n}\n\n/**\n Cancelable object that does nothing on cancel()\n */\npublic class NoOpCancelable: Cancelable {\n\n    public func cancel() {\n        // no-op\n    }\n\n    public init() {\n\n    }\n\n}\n\n/**\n Cancelable that just holds a boolean state to know whether cancel() has been called or not.\n */\npublic class StateCancelable: Cancelable {\n\n    private(set) public var isCanceled = false\n\n    public func cancel() {\n        isCanceled = true\n    }\n\n    public init() {\n\n    }\n\n}\n\n/**\n Thread-safe Cancelable that can contains a list of Cancelable objects.\n */\npublic class CancelableGroup: Cancelable {\n\n    private(set) public var isCanceled = false\n    private let queue = DispatchQueue(label: \"com.snapchat.cancelable_group\")\n    private var children = [Cancelable]()\n\n    public init() {\n\n    }\n\n    public func cancel() {\n        var childrenToCall = [Cancelable]()\n        queue.sync {\n            guard !self.isCanceled else { return }\n            self.isCanceled = true\n            childrenToCall = self.children\n        }\n        childrenToCall.forEach { $0.cancel() }\n    }\n\n    public func add(_ cancelable: Cancelable) {\n        var alreadyCanceled = false\n        queue.sync {\n            if self.isCanceled {\n                alreadyCanceled = true\n            } else {\n                self.children.append(cancelable)\n            }\n        }\n\n        if alreadyCanceled {\n            cancelable.cancel()\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/CompilationCache.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 9/28/20.\n//\n\nimport Foundation\n\nstruct CompilationCacheEntry<T> {\n    let lastSequence: CompilationSequence\n    let value: T\n}\n\nclass CompilationCache<T> {\n\n    private var entries = Synchronized(data: [String: CompilationCacheEntry<T>]())\n\n    func getOrUpdate(key: String, compileSequence: CompilationSequence, onUpdate: (String, T?) throws -> T) rethrows -> T {\n        return try entries.data { (entries) -> T in\n            var previousValue: T?\n            if let entry = entries[key] {\n                previousValue = entry.value\n                if entry.lastSequence == compileSequence {\n                    return entry.value\n                }\n            }\n\n            let value = try onUpdate(key, previousValue)\n            entries[key] = CompilationCacheEntry(lastSequence: compileSequence, value: value)\n            return value\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/CompilerError.swift",
    "content": "//\n//  CompilerError.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/6/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass CompilerError: LocalizedError, CustomStringConvertible {\n    let name: String\n    let failedDependenciesURLs: Set<URL>\n\n    init(_ name: String, failedDependenciesURLs: Set<URL> = []) {\n        self.name = name\n        self.failedDependenciesURLs = failedDependenciesURLs\n    }\n\n    convenience init(type: String, message: String, range: NSRange, inDocument document: String, failedDependenciesURLs: Set<URL> = []) {\n        let lines = LinesIndexer(str: document)\n        let line = lines.lineIndex(atCharacterIndex: range.lowerBound)\n\n        self.init(type: type, message: message, atZeroIndexedLine: line.lineOffset, column: line.characterOffset, inDocument: document, failedDependenciesURLs: failedDependenciesURLs)\n    }\n\n    convenience init(type: String, message: String, atZeroIndexedLine lineIndex: Int, column: Int?, inDocument document: String, failedDependenciesURLs: Set<URL> = []) {\n        let lines = document.split(separator: \"\\n\", omittingEmptySubsequences: false)\n        let minLineToPrint = max(0, lineIndex - 3)\n        let maxLineToPrint = min(lines.count - 1, lineIndex + 3)\n        let linesToPrint: [String]\n\n        if maxLineToPrint < minLineToPrint {\n            linesToPrint = lines.map(String.init)\n        } else {\n            linesToPrint = (minLineToPrint..<maxLineToPrint+1).flatMap { i -> [String] in\n                let indent = \"   \"\n                let emoji = i == lineIndex ? \"👉\" : \" \"\n                var printLines = [indent + emoji + String(lines[i])]\n                if i == lineIndex, let col = column {\n                    printLines.append(indent + \" \" + String(repeating: \" \", count: col) + \"👆\")\n                }\n                return printLines\n            }\n        }\n        self.init(\"🚨 \\(type): \\(message) at line \\(lineIndex + 1)\\n\\n\" + linesToPrint.joined(separator: \"\\n\") + \"\\n\", failedDependenciesURLs: failedDependenciesURLs)\n    }\n\n    public var errorDescription: String? {\n        return name\n    }\n\n    var description: String {\n        return \"<CompilerError: \\(name)>\"\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ComponentPath.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 12/17/19.\n//\n\nimport Foundation\n\nstruct ComponentPath: Hashable, Codable {\n    let fileName: String\n    let exportedMember: String\n\n    var stringRepresentation: String {\n        return \"\\(exportedMember)@\\(fileName)\"\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ConfigValue.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 10/18/21.\n//\n\nimport Foundation\nimport Yams\n\nstruct ConfigValue {\n\n    let keyPath: [String]\n    let value: String\n\n    static func parse(text: String) throws -> ConfigValue {\n        guard let index = text.firstIndex(of: \"=\") else {\n            throw CompilerError(\"Missing =\")\n        }\n\n        let keyPathStr = text[text.startIndex..<index].trimmed.split(separator: \".\")\n        let value = text[text.index(after: index)...].trimmed\n\n        return ConfigValue(keyPath: keyPathStr.map { String($0) }, value: String(value))\n    }\n\n    func inject(into node: Yams.Node) -> Yams.Node {\n        return onInject(index: 0, node: node)\n    }\n\n    private func onInject(index: Int, node: Yams.Node?) -> Yams.Node {\n        if index == keyPath.count {\n            return Yams.Node(value)\n        } else {\n            let key = keyPath[index]\n\n            let updatedNode = onInject(index: index + 1, node: node?[key])\n\n            var out = node ?? Yams.Node.mapping(Yams.Node.Mapping([]))\n            out[key] = updatedNode\n\n            return out\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/DataConvertible.swift",
    "content": "import Foundation\n\n// Protocol and extensions for easily converting Data to numeric types and back\nprotocol DataConvertible {\n    init?(data: Data)\n    var data: Data { get }\n}\n\nextension DataConvertible where Self: ExpressibleByIntegerLiteral {\n\n    init?(data: Data) {\n        var value: Self = 0\n        guard data.count == MemoryLayout.size(ofValue: value) else { return nil }\n        _ = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0)})\n        self = value\n    }\n\n    var data: Data {\n        return withUnsafeBytes(of: self) { Data($0) }\n    }\n}\n\nextension Int: DataConvertible { }\nextension UInt32: DataConvertible { }\nextension Float: DataConvertible { }\nextension Double: DataConvertible { }\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/DispatchChannelTCPConnection.swift",
    "content": "//\n//  DispatchChannelTCPConnection.swift\n//  Compiler\n//\n//  Created by saniul on 07/10/2019.\n//\n\nimport Foundation\n\nclass DispatchChannelTCPConnection: TCPConnection {\n    weak var delegate: TCPConnectionDelegate?\n    var dataProcessor: TCPConnectionDataProcessor?\n\n    let key: String\n    let ioChannel: DispatchIO\n\n    private let logger: ILogger\n    private let sendQueue: DispatchQueue\n    private let recvQueue: DispatchQueue\n    private var startedListening: Bool = false\n    private var buffer = Data()\n\n    private enum Error: Swift.Error {\n        case readEmptyData\n    }\n\n    init(logger: ILogger, key: String, ioChannel: DispatchIO, queueNamePrefix: String) {\n        self.logger = logger\n        self.key = key\n        self.ioChannel = ioChannel\n        sendQueue = DispatchQueue(label: \"\\(queueNamePrefix).\\(key).send\")\n        recvQueue = DispatchQueue(label: \"\\(queueNamePrefix).\\(key).recv\")\n    }\n\n    deinit {\n        ioChannel.close()\n    }\n\n    func startListening() {\n        guard !startedListening else {\n            return\n        }\n\n        startedListening = true\n        recvQueue.async {\n            self.receiveLoop()\n        }\n    }\n\n    func close() {\n        closeConnection(error: nil)\n    }\n\n    func send(data: Data) {\n        sendQueue.async {\n            self.logger.verbose(\"Writing \\(data.count) bytes to channel \\(self.key)\")\n\n            var retainedData: Data? = data\n            let dispatchData: DispatchData = retainedData!.withUnsafeBytes { pointer in\n                return DispatchData(bytes: pointer)\n            }\n\n            self.ioChannel.write(offset: 0, data: dispatchData, queue: self.sendQueue) { (done, _, errno) in\n                defer { retainedData = nil }\n                guard done else { return }\n\n                if errno != 0 {\n                    let error = NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)\n                    self.logger.error(\"Error while writing to {\\(self.key)}: \\(error.legibleLocalizedDescription)\")\n                    self.closeConnection(error: error)\n                }\n            }\n        }\n    }\n\n    private func receiveLoop(lengthNeeded: Int? = nil) {\n        ioChannel.read(offset: 0, length: lengthNeeded ?? 1, queue: self.recvQueue) { [weak self] (done, dispatchData, errno) in\n            guard let this = self else { return }\n\n            guard errno == 0 else {\n                let error = NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)\n                this.closeConnection(error: error)\n                return\n            }\n\n            guard let dispatchData = dispatchData, dispatchData.count > 0 else {\n                this.closeConnection(error: Error.readEmptyData)\n                return\n            }\n\n            this.buffer.append(Data(dispatchData))\n\n            if done {\n                let nextLengthNeeded = this.processBuffer(&this.buffer)\n\n                this.receiveLoop(lengthNeeded: nextLengthNeeded)\n            }\n        }\n    }\n\n    private func closeConnection(error: Swift.Error?) {\n        logger.debug(\"Closing reloader connection \\(key) with error \\(error?.legibleLocalizedDescription ?? \"\")\")\n        ioChannel.close()\n        delegate?.connection(self, didDisconnectWithError: error)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/DumpModuleInfos.swift",
    "content": "// Copyright © 2023 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nstruct DumpedModuleInfo: Codable {\n    let path: String\n    let name: String\n    let dependencies: [String]\n}\n\nstruct DumpModulesInfoOutput: Codable {\n    var modules: [DumpedModuleInfo]\n}\n\nstruct DumpModulesInfo {\n\n    static func dump(fileManager: ValdiFileManager, configs: ResolvedConfigs, to path: String) throws {\n        let url = URL(fileURLWithPath: path)\n        let filesFinder = ValdiFilesFinder(url: configs.projectConfig.baseDir)\n        let fileUrls = try filesFinder.allFiles()\n        let bundleManager = try BundleManager(projectConfig: configs.projectConfig, compilerConfig: configs.compilerConfig, baseDirURLs: [configs.projectConfig.baseDir])\n\n        var allBundleInfos: Set<CompilationItem.BundleInfo> = []\n        for fileUrl in fileUrls {\n            let bundleInfo = try bundleManager.getBundleInfo(fileURL: fileUrl)\n            allBundleInfos.insert(bundleInfo)\n        }\n\n        let sortedBundleInfos = allBundleInfos.map { $0 }.sorted(by: { $0.baseDir.path < $1.baseDir.path })\n\n        var output = DumpModulesInfoOutput(modules: [])\n\n        for bundleInfo in sortedBundleInfos where !bundleInfo.isRoot {\n            output.modules.append(DumpedModuleInfo(path: bundleInfo.baseDir.path, name: bundleInfo.name, dependencies: bundleInfo.allDependenciesNames.map { $0 }))\n        }\n\n        let json = try output.toJSON(outputFormatting: [.prettyPrinted, .sortedKeys])\n\n        try fileManager.save(data: json, to: url)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Array+ParallelMap.swift",
    "content": "//\n//  Array+ParrallelMap.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 9/19/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// Allows to quickly enable/disable concurrent processing\n// This can help to make compilation consistent and make\n// debugging easier.\nstruct Concurrency {\n    static var enableConcurrency = true\n}\n\nextension Array {\n\n    func parallelProcess(_ process: (Element) throws -> Void) rethrows {\n        _ = try parallelMap(process)\n    }\n\n    private func doProcess<T>(index: Int, lock: DispatchSemaphore, outArray: UnsafeMutableBufferPointer<Result<T, Error>>, process: (Element) throws -> T) {\n        safeAutorelease {\n            let item = self[index]\n            do {\n                let outItem = try process(item)\n\n                lock.lock {\n                    outArray[index] = .success(outItem)\n                }\n            } catch let caughtError {\n                lock.lock {\n                    outArray[index] = .failure(caughtError)\n                }\n            }\n        }\n    }\n\n    func parallelMap<T>(_ process: (Element) throws -> T) rethrows -> [T] {\n        if isEmpty {\n            return []\n        }\n\n        var outArray = [Result<T, Error>]()\n        outArray.reserveCapacity(count)\n        for _ in 0..<count {\n            outArray.append(.failure(CompilerError(\"Item not processed\")))\n        }\n\n        let lock = DispatchSemaphore(value: 1)\n\n        outArray.withUnsafeMutableBufferPointer { bufferPointer in\n            if Concurrency.enableConcurrency {\n                DispatchQueue.concurrentPerform(iterations: bufferPointer.count) { (index) in\n                    self.doProcess(index: index, lock: lock, outArray: bufferPointer, process: process)\n                }\n            } else {\n                for index in 0..<count {\n                    doProcess(index: index, lock: lock, outArray: bufferPointer, process: process)\n                }\n            }\n        }\n\n        return try outArray.map { try $0.get() }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Array+Search.swift",
    "content": "//\n//  Array+Search.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/5/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\npublic extension Array {\n\n    /**\n     Index of using a binary search. The array MUST already be sorted.\n     If the sorting is ascending, you should return orderedDescending in the\n     comparator if the given element is before your researched element,\n     orderedAscending should be returned if the element is after your\n     researched element, orderedSame if the element has been found.\n     If the sorting is descending, just reverse the logic.\n     */\n    func index(where comparator: (Element) -> ComparisonResult) -> Index? {\n        var lowerBound = 0\n        var upperBound = count\n        while lowerBound < upperBound {\n            let midIndex = lowerBound + (upperBound - lowerBound) / 2\n            let result = comparator(self[midIndex])\n\n            switch result {\n            case .orderedSame:\n                return midIndex\n            case .orderedDescending:\n                lowerBound = midIndex + 1\n            case .orderedAscending:\n                upperBound = midIndex\n            }\n        }\n        return nil\n    }\n\n}\n\npublic extension Array where Element: Equatable {\n\n    func contains(_ other: Element) -> Bool {\n        return firstIndex(where: { $0 == other }) != nil\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/BlueSocket+Extensions.swift",
    "content": "//\n//  ReloaderServiceAnnouncer.swift\n//  Compiler\n//\n//  Created by saniul on 2019-03-07.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport BlueSocket\n\nextension Socket.Address {\n\n    init(address: UInt32, port: UInt16) {\n        let inaddr = in_addr(s_addr: address)\n        var socketaddr = sockaddr_in()\n        socketaddr.sin_family = sa_family_t(AF_INET)\n        socketaddr.sin_port = in_port_t(port.bigEndian)\n        socketaddr.sin_addr = inaddr\n        self = Socket.Address.ipv4(socketaddr)\n    }\n\n}\n\nextension in_addr: Equatable, Hashable {\n    public static func ==(lhs: in_addr, rhs: in_addr) -> Bool {\n        return lhs.s_addr == rhs.s_addr\n    }\n\n    public func hash(into hasher: inout Hasher) {\n        hasher.combine(s_addr)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Collection+Utils.swift",
    "content": "//\n//  Collection+Utils.swift\n//  Compiler\n//\n//  Created by David Byttow on 10/19/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\npublic extension Sequence {\n    func count(_ closure: (Element) -> Bool) -> Int {\n        return reduce(into: 0) { (acc: inout Int, item) in\n            if closure(item) {\n                acc += 1\n            }\n        }\n    }\n\n    func associate<Key: Hashable, Value>(_ closure: (Element) -> (Key, Value)) -> [Key: Value] {\n        var out = [Key: Value]()\n\n        for element in self {\n            let (key, value) = closure(element)\n            out[key] = value\n        }\n\n        return out\n    }\n\n    /**\n     Similar to Dictionary(uniqueKeysWithValues:), but will throw on duplicate key instead of asserting and crashing the\n     program unsafely.\n     */\n    func associateUnique<Key: Hashable, Value>(_ closure: (Element) -> (Key, Value)) throws -> [Key: Value] {\n        var out = [Key: Value]()\n\n        for element in self {\n            let (key, value) = closure(element)\n            guard out[key] == nil else {\n                throw CompilerError(\"Conflicting key '\\(key)'\")\n            }\n            out[key] = value\n        }\n\n        return out\n    }\n\n    func associateBy<Key: Hashable>(_ closure: (Element) -> Key) -> [Key: Element] {\n        return associate { (element) -> (Key, Element) in\n            return (closure(element), element)\n        }\n    }\n\n    func group<T: Hashable, Value>(_ closure: (Element) -> (T, Value)) -> [T: [Value]] {\n        var out = [T: [Value]]()\n\n        for element in self {\n            let (key, value) = closure(element)\n            out[key, default: []].append(value)\n        }\n\n        return out\n    }\n\n    func groupBy<T: Hashable>(_ closure: (Element) -> T) -> [T: [Element]] {\n        var out = [T: [Element]]()\n\n        for element in self {\n            let key = closure(element)\n            out[key, default: []].append(element)\n        }\n\n        return out\n    }\n\n}\n\nextension Array where Element: Comparable {\n    func replacingPrefix(_ prefix: [Element], replacement: [Element]) -> [Element] {\n        guard self.starts(with: prefix) else {\n            return self\n        }\n\n        return replacement + Array(dropFirst(prefix.count))\n    }\n}\n\npublic extension MutableCollection {\n\n    mutating func transform(_ closure: (inout Element) -> Void) {\n        var currentIndex = startIndex\n        let endIndex = self.endIndex\n        while currentIndex != endIndex {\n            closure(&self[currentIndex])\n\n            currentIndex = self.index(currentIndex, offsetBy: 1)\n        }\n    }\n\n}\n\nextension Collection {\n    var nonEmpty: Self? {\n        return isEmpty ? nil : self\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Data+HexString.swift",
    "content": "//\n//  Data+HexString.swift\n//  \n//\n//  Created by saniul on 04/11/2019.\n//\n\nimport Foundation\n\nextension Data {\n    init?(hexString: String) {\n        guard hexString.count % 2 == 0 else { return nil }\n\n        var result = Data(capacity: hexString.count/2)\n\n        for i in hexString.utf8.strideIndices(by: 2) {\n            let byteRange = i...hexString.index(after: i)\n            guard let byte = UInt8(hexString[byteRange], radix: 16) else { return nil }\n            result.append(byte)\n        }\n\n        self = result\n    }\n\n    var hexString: String {\n        self.map { String(format: \"%02x\", $0) }.joined()\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Data+SHA256.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by saniul on 15/11/2019.\n//\n\nimport Foundation\nimport Crypto\n\nextension Data {\n    func generateSHA256Digest() throws -> String {\n        let digest = Crypto.SHA256.hash(data: self)\n        var out = \"\"\n        out.reserveCapacity(64)\n        for element in digest {\n            out += String(format: \"%02x\", element)\n        }\n        return out\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Data+Serialization.swift",
    "content": "//\n//  Data+Serialization.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 3/11/19.\n//\n\nimport Foundation\n\nextension Data {\n\n    mutating func append(integer: UInt32) {\n        var value = integer\n        Swift.withUnsafePointer(to: &value) {\n            append(UnsafeBufferPointer(start: $0, count: 1))\n        }\n    }\n\n    private static func alignUp(size: UInt32, alignment: UInt32) -> UInt32 {\n        // See details here:\n        // https://github.com/KabukiStarship/KabukiToolkit/wiki/Fastest-Method-to-Align-Pointers#observations\n        return (size + alignment - 1) & ~(alignment - 1)\n    }\n\n    static func computePadding(size: UInt32) -> UInt32 {\n        return alignUp(size: size, alignment: 4) - size\n    }\n\n    static let valdiLengthFieldPaddingBit: UInt32 = 0x80000000\n\n    mutating func append(valdiData: Data, padding: Bool) {\n        var length = UInt32(valdiData.count)\n        let dataPadding = padding ? Data.computePadding(size: length) : 0\n\n        if dataPadding > 0 {\n            length |= Data.valdiLengthFieldPaddingBit\n        }\n\n        append(integer: length)\n        append(valdiData)\n\n        for _ in 0..<dataPadding {\n            append(0)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Data+UnsafePointers.swift",
    "content": "//\n//  Data+UnsafePointers.swift\n//  Compiler\n//\n//  Created by saniul on 09/09/2019.\n//\n\nimport Foundation\n\nextension Data {\n\n    // Shorthand for using `withUnsafeBytes` and accessing the `baseAddress` pointer of the buffer safely\n    @inlinable public func withUnsafePointer<ResultType, IntegerBufferType: ExpressibleByIntegerLiteral>(_ body: (UnsafePointer<IntegerBufferType>) throws -> ResultType) rethrows -> ResultType {\n        return try withUnsafeBytes { (rawBufferPointer: UnsafeRawBufferPointer) -> ResultType in\n            let unsafeBufferPointer = rawBufferPointer.bindMemory(to: IntegerBufferType.self)\n            guard let unsafePointer = unsafeBufferPointer.baseAddress else {\n                var int: IntegerBufferType = 0\n                return try body(&int)\n            }\n            return try body(unsafePointer)\n        }\n    }\n\n    // Shorthand for using `withUnsafeMutableBytes` and accessing the `baseAddress` pointer of the buffer safely\n    @inlinable public mutating func withUnsafeMutablePointer<ResultType, IntegerBufferType: ExpressibleByIntegerLiteral>(_ body: (UnsafeMutablePointer<IntegerBufferType>) throws -> ResultType) rethrows -> ResultType {\n        return try withUnsafeMutableBytes { (rawBufferPointer: UnsafeMutableRawBufferPointer) -> ResultType in\n            let unsafeBufferPointer = rawBufferPointer.bindMemory(to: IntegerBufferType.self)\n            guard let unsafePointer = unsafeBufferPointer.baseAddress else {\n                var int: IntegerBufferType = 0\n                return try body(&int)\n            }\n            return try body(unsafePointer)\n        }\n    }\n\n    public func fastFirstIndex(of value: UInt8) -> Int? {\n        // For some reason firstIndex(of: ) ends up being quite slow\n        // This hand-written implementation is 6 times faster in my testing\n        return withUnsafeBytes { buffer in\n            let count = self.count\n            let start = buffer.bindMemory(to: UInt8.self).baseAddress!\n            let end = start.advanced(by: count)\n            var current = start\n\n            while current < end {\n                if current.pointee == value {\n                    return start.distance(to: current)\n                }\n\n                current = current.advanced(by: 1)\n            }\n\n            return nil\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/DispatchQueue+Promise.swift",
    "content": "//\n//  DispatchQueue+Promise.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/11/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension DispatchQueue {\n\n    func asyncPromise<T>(_ closure: @escaping () -> Promise<T>) -> Promise<T> {\n        let promise = Promise<T>()\n\n        async {\n            _ = closure().then { (data) -> Void in\n                promise.resolve(data: data)\n                }.catch { (error) in\n                    promise.reject(error: error)\n                }\n        }\n\n        return promise\n    }\n\n    func asyncPromise<T>(_ closure: @escaping () throws -> T) -> Promise<T> {\n        let promise = Promise<T>()\n\n        async {\n            do {\n                let result = try closure()\n                promise.resolve(data: result)\n            } catch let error {\n                promise.reject(error: error)\n            }\n        }\n\n        return promise\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/DispatchSemaphore+Lock.swift",
    "content": "//\n//  DispatchSemaphore+Lock.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/26/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct LockConfig {\n    // Promises will end in failed state if they fail to resolve after 10 minutes.\n    static var waitTimeoutSeconds: TimeInterval = 10 * 60\n}\n\nextension DispatchSemaphore {\n\n    private func waitOrCrashAfterTimeout() {\n        let result = self.wait(timeout: DispatchTime.now() + LockConfig.waitTimeoutSeconds)\n        if result == .timedOut {\n            KillOnTimeout.notifyTimeout()\n        }\n    }\n\n    func lock(_ block: () throws -> Void) rethrows {\n        self.waitOrCrashAfterTimeout()\n        defer {\n            self.signal()\n        }\n        try block()\n    }\n\n    func lock<T>(_ block: () throws -> T) rethrows -> T {\n        self.waitOrCrashAfterTimeout()\n        defer {\n            self.signal()\n        }\n        return try block()\n    }\n\n    class func newLock() -> DispatchSemaphore {\n        return DispatchSemaphore(value: 1)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Message+orderedSerializedData.swift",
    "content": "//\n//  Message+orderedSerializedData.swift\n//\n//  Created by Vasily Fomin on 01/17/24.\n//  Copyright © 2024 Snap Inc. All rights reserved.\n//\nimport Foundation\nimport SwiftProtobuf\n\npublic extension Message {\n\n    // A version of serializedData with deterministic order.\n    func orderedSerializedData() throws -> Data {\n        var options = BinaryEncodingOptions()\n        options.useDeterministicOrdering = true\n        return try serializedData(options: options)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/NodeAttribute+Utils.swift",
    "content": "//\n//  NodeAttribute+Utils.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/27/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprivate let decimalDigits = CharacterSet.decimalDigits\n\nextension Valdi_NodeAttribute {\n\n    init(logger: ILogger, name: String, value: String) {\n        self.name = name\n\n        var isString = true\n\n        let trimmed = value.removingCharacters(in: decimalDigits)\n        if trimmed.isEmpty || trimmed == \"px\" || trimmed == \"pt\" {\n            var int: Int64 = 0\n\n            if Scanner(string: value).scanInt64(&int) {\n                intValue = int\n                type = .nodeAttributeTypeInt\n                isString = false\n            } else {\n                logger.warn(\"Was not able to convert auto-detected int with value '\\(value)' to Int\")\n            }\n        } else if trimmed == \".\" || trimmed == \".px\" || trimmed == \".pt\" {\n            if let double = Scanner(string: value).scanDouble() {\n                let behavior = NSDecimalNumberHandler(roundingMode: .plain,\n                                                      scale: 4,\n                                                      raiseOnExactness: false,\n                                                      raiseOnOverflow: false,\n                                                      raiseOnUnderflow: false,\n                                                      raiseOnDivideByZero: true)\n                // Rounding the parsed Double here because we noticed we get different behavior on macOS and Linux, e.g.\n                // \".95\" would parse to 0.95 on macOS, but 0.0.950000001 on Linux\n                let decimal = NSDecimalNumber(value: double).rounding(accordingToBehavior: behavior)\n                doubleValue = decimal.doubleValue\n                type = .nodeAttributeTypeDouble\n                isString = false\n            } else {\n                logger.warn(\"Was not able to convert auto-detected double with value '\\(value)' to Double\")\n            }\n        }\n\n        if isString {\n            self.strValue = value\n            type = .nodeAttributeTypeString\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Result+FromTuple.swift",
    "content": "//\n//  Result+FromTuple.swift\n//  Compiler\n//\n//  Created by saniul on 26/06/2019.\n//\n\nimport Foundation\n\n// Sometimes we have to deal with situations where the success or failure is expressed\n// as a pair of optional objects.\n// This utility extension exists to convert that easily into a Swift.Result instance.\nextension Result where Failure == Error {\n    init(fromTuple tuple: (Success?, Failure?)) {\n        switch tuple {\n        case (.none, .none), (.some, .some):\n            self = .failure(CompilerError(\"Invalid result \\(tuple)\"))\n        case let (.none, .some(failure)):\n            self = .failure(failure)\n        case let (.some(success), .none):\n            self = .success(success)\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Result+GetError.swift",
    "content": "//\n//  Result+GetError.swift\n//  Compiler\n//\n//  Created by saniul on 07/10/2019.\n//\n\nimport Foundation\n\nextension Swift.Result {\n    var success: Success? {\n        switch self {\n        case let .success(success): return success\n        case .failure: return nil\n        }\n    }\n\n    var failure: Failure? {\n        switch self {\n        case .success: return nil\n        case let .failure(failure): return failure\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/String+Concatenate.swift",
    "content": "//\n//  String+Concatenate.swift\n//  Compiler\n//\n//  Created by Ivan Golub on 6/7/22.\n//  Copyright © 2022 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension String {\n    static func concatenate(_ components: String?...,\n                               separator: String = \"\",\n                               transform: (String?) -> String? = { $0 }) -> String? {\n        return components\n            .compactMap { transform($0) }\n            .joined(separator: separator)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/String+EnvVariables.swift",
    "content": "//\n//  String+EnvVariables.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 2/2/19.\n//  Copyright © 2019 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprivate let envVarRegex = try! NSRegularExpression(pattern: \"\\\\$([a-zA-Z0-9]+[a-zA-Z0-9_]*)\")\n\nextension String {\n\n    private func replacingVariables(regex: NSRegularExpression, onReplace: (String) throws -> String) rethrows -> String {\n        var current = self\n\n        while true {\n            let utf16 = current.utf16\n            guard let match = regex.firstMatch(in: current, options: [], range: NSRange(location: 0, length: utf16.count)) else {\n                return current\n            }\n\n            let range = match.range(at: 1)\n            let envVariable = current.substring(with: range)!\n            let replacement = try onReplace(envVariable)\n            current = current.replacing(range: match.range, with: replacement) ?? \"\"\n        }\n    }\n\n    func resolvingVariables(_ variables: [String: String]) throws -> String {\n        return try replacingVariables(regex: envVarRegex) { key in\n            guard let value = variables[key] else {\n                throw CompilerError(\"Could not resolve variable \\\"\\(key)\\\"\")\n            }\n            return value\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/String+FileExtensions.swift",
    "content": "//\n//  String+FileExtensions.swift\n//  Compiler\n//\n//  Created by Brandon Francis on 8/6/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension String {\n\n    func hasExtension(_ ext: String) -> Bool {\n        return self.hasSuffix(\".\\(ext)\")\n    }\n\n    func hasAnyExtension(_ extensions: [String]) -> Bool {\n        return extensions.contains(where: { hasExtension($0) })\n    }\n\n    func deletingPathExtension() -> String {\n        return (self as NSString).deletingPathExtension\n    }\n\n    func deletingLastPathComponent() -> String {\n        return (self as NSString).deletingLastPathComponent\n    }\n\n    func lastPathComponent() -> String {\n        return (self as NSString).lastPathComponent\n    }\n\n    static func sanitizePathComponents(_ components: String?...) -> String? {\n        let sanitizedComponents =\n            components\n                .compactMap { $0 }\n                .map { $0.split(separator: \"/\", maxSplits: Int.max, omittingEmptySubsequences: true) }\n                .flatMap { $0 }\n\n        if !sanitizedComponents.isEmpty {\n            return sanitizedComponents.joined(separator: \"/\")\n        } else {\n            return nil\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/String+JS.swift",
    "content": "//\n//  String+JS.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/3/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension String {\n\n    var indented: String {\n        return indented(indentPattern: \"  \")\n    }\n\n    func indented(indentPattern: String) -> String {\n        // not completely correct but helps debugging\n        let lines = self.split(separator: \"\\n\", maxSplits: Int.max, omittingEmptySubsequences: false)\n\n        var indentCount = 0\n\n        var outLines = [String]()\n        var previousWasEmptyLine = true\n        for line in lines {\n            let trimmedLine = line.trimmed\n\n            if trimmedLine.isEmpty {\n                if previousWasEmptyLine {\n                    continue\n                }\n                outLines.append(\"\\n\")\n                previousWasEmptyLine = true\n                continue\n            }\n            previousWasEmptyLine = false\n\n            var newIndent = indentCount\n\n            for (index, c) in trimmedLine.enumerated() {\n                if c == \"{\" {\n                    newIndent += 1\n                } else if c == \"}\" {\n                    newIndent -= 1\n                    if index == 0 {\n                        indentCount -= 1\n                    }\n                }\n            }\n\n            // indentCount may be < 0 if the syntax is invalid -- we still shouldn't crash:\n            indentCount = max(0, indentCount)\n\n            let indent = String(repeating: indentPattern, count: indentCount)\n\n            indentCount = newIndent\n\n            outLines.append(indent + trimmedLine + \"\\n\")\n        }\n\n        return outLines.joined()\n    }\n\n    var strippingSingleLineComments: String {\n        return self.split(separator: \"\\n\")\n            .filter { !$0.trimmed.starts(with: \"//\") }\n            .joined(separator: \"\\n\")\n    }\n\n    var asJsExpression: String {\n        if isBool || isNumber {\n            return self\n        }\n        return \"'\" + self + \"'\"\n    }\n\n    var isBool: Bool {\n        return self == \"true\" || self == \"false\"\n    }\n\n    private static var nonDecimalSet: CharacterSet = CharacterSet.decimalDigits.inverted\n\n    var isNumber: Bool {\n        return self.rangeOfCharacter(from: String.nonDecimalSet) == nil\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/String+NSRange.swift",
    "content": "//\n//  String+NSRange.swift\n//  Compiler\n//\n//  Created by Nathaniel Parrott on 7/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\n// From https://nshipster.com/nsregularexpression/\n\nextension String {\n\n    /// An `NSRange` that represents the full range of the string.\n    var nsrange: NSRange {\n        return NSRange(location: 0, length: utf16.count)\n    }\n\n    /// Returns a substring with the given `NSRange`,\n    /// or `nil` if the range can't be converted.\n    func substring(with nsrange: NSRange) -> String? {\n        guard let range = Range(nsrange)\n            else { return nil }\n\n        let start = String.Index(utf16Offset: range.lowerBound, in: self)\n        let end = String.Index(utf16Offset: range.upperBound, in: self)\n        return String(utf16[start..<end])\n    }\n\n    func replacing(range nsrange: NSRange, with str: String) -> String? {\n        guard let range = Range(nsrange)\n            else { return nil }\n\n        let start = String.Index(utf16Offset: range.lowerBound, in: self)\n        let end = String.Index(utf16Offset: range.upperBound, in: self)\n\n        return (String(utf16[utf16.startIndex..<start]) ?? \"\") + str + (String(utf16[end..<utf16.endIndex]) ?? \"\")\n    }\n\n    /// Returns a range equivalent to the given `NSRange`,\n    /// or `nil` if the range can't be converted.\n    func range(from nsrange: NSRange) -> Range<Index>? {\n        guard let range = Range(nsrange) else { return nil }\n        let utf16Start = String.Index(utf16Offset: range.lowerBound, in: self)\n        let utf16End = String.Index(utf16Offset: range.upperBound, in: self)\n\n        guard let start = Index(utf16Start, within: self),\n            let end = Index(utf16End, within: self)\n            else { return nil }\n\n        return start..<end\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/String+Regex.swift",
    "content": "//\n//  String+Regex.swift\n//  Compiler\n//\n//  Created by Brandon Francis on 8/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension String {\n\n    func matches(regex: NSRegularExpression) -> Bool {\n        return getMatch(regex: regex) != nil\n    }\n\n    func getMatch(regex: NSRegularExpression) -> NSTextCheckingResult? {\n        return getMatch(regex: regex, range: NSRange(location: 0, length: self.utf16.count))\n    }\n\n    func getMatch(regex: NSRegularExpression, range: NSRange) -> NSTextCheckingResult? {\n        let matches = regex.matches(in: self, options: [], range: range)\n\n        return matches.first(where: { $0.range == range })\n    }\n\n    func matches(anyRegex regexes: [NSRegularExpression]) -> Bool {\n        let range = NSRange(location: 0, length: self.utf16.count)\n\n        return regexes.contains(where: { self.getMatch(regex: $0, range: range) != nil })\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/String+Stride.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by saniul on 04/11/2019.\n//\n\nimport Foundation\n\n// Swift's String.UTF8View.Index is not Strideable, see discussion:\n// https://stackoverflow.com/questions/36205309/conforming-string-characterview-index-to-strideable-fatal-error-when-using-stri\n//\n// This extension is loosely based on https://stackoverflow.com/a/36206979\nextension String.UTF8View {\n    typealias Index = String.UTF8View.Index\n\n    func strideIndices(by stride: Int) -> AnySequence<Index> {\n        strideIndices(from: startIndex, to: endIndex, by: stride)\n    }\n\n    func strideIndices(from start: Index, to end: Index, by stride: Int) -> AnySequence<Index> {\n        precondition(stride != 0, \"stride size must not be zero\")\n\n        return AnySequence { () -> AnyIterator<Index> in\n            var current = start\n            return AnyIterator {\n                guard let next = self.index(current, offsetBy: stride, limitedBy: end) else {\n                    return nil\n                }\n\n                let result = current\n                current = next\n                return result\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/String+Trim.swift",
    "content": "//\n//  StringUtils.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprivate let trimCharacterSet = CharacterSet.whitespacesAndNewlines\n\nextension Substring {\n\n    var trimmed: Substring {\n        let scalars = self.unicodeScalars\n\n        var newStartIndex = scalars.startIndex\n        var newEndIndex = scalars.endIndex\n\n        while newStartIndex < newEndIndex && trimCharacterSet.contains(scalars[newStartIndex]) {\n            newStartIndex = scalars.index(newStartIndex, offsetBy: 1)\n        }\n        while newEndIndex > newStartIndex {\n            let maybeNewEndIndex = scalars.index(newEndIndex, offsetBy: -1)\n            if trimCharacterSet.contains(scalars[maybeNewEndIndex]) {\n                newEndIndex = maybeNewEndIndex\n            } else {\n                break\n            }\n        }\n\n        return Substring(scalars[newStartIndex..<newEndIndex])\n    }\n\n    var unquote: Substring {\n        if (hasPrefix(\"'\") && hasSuffix(\"'\")) || (hasPrefix(\"\\\"\") && hasSuffix(\"\\\"\")) {\n            return self[index(startIndex, offsetBy: 1)..<index(endIndex, offsetBy: -1)]\n        }\n        return self\n    }\n\n    var pascalCased: String {\n        return String(self).pascalCased\n    }\n\n    var camelCased: String {\n        return String(self).camelCased\n    }\n\n}\n\nextension String {\n\n    var trimmed: String {\n        return self.trimmingCharacters(in: trimCharacterSet)\n    }\n\n    var xmlEscaped: String {\n        return self\n            .replacingOccurrences(of: \"&\", with: \"&amp;\")\n            .replacingOccurrences(of: \">\", with: \"&gt;\")\n            .replacingOccurrences(of: \"<\", with: \"&lt;\")\n    }\n\n    var jsonEscaped: String {\n        return self\n            .replacingOccurrences(of: \"\\\\\", with: \"\\\\\\\\\")\n            .replacingOccurrences(of: \"\\n\", with: \"\\\\n\")\n            .replacingOccurrences(of: \"\\t\", with: \"\\\\t\")\n            .replacingOccurrences(of: \"'\", with: \"\\\\'\")\n            .replacingOccurrences(of: \"\\\"\", with: \"\\\\\\\"\")\n    }\n\n    var removingLastCharacter: String {\n        let lastIndex = self.index(endIndex, offsetBy: -1)\n\n        return String(self[startIndex..<lastIndex])\n    }\n\n    var asValdiAttributeKey: String {\n        var out = String.UnicodeScalarView()\n        var shouldUpper = false\n\n        for currentCharacter in self.unicodeScalars {\n            if currentCharacter == \"-\" || currentCharacter == \"_\" {\n                if !out.isEmpty {\n                    shouldUpper = true\n                }\n                continue\n            }\n\n            var c = currentCharacter\n\n            if shouldUpper {\n                shouldUpper = false\n                if c >= \"a\" && c <= \"z\" {\n                    c = Unicode.Scalar(c.value - 32)!\n                }\n            }\n\n            if (c >= \"a\" && c <= \"z\") || (c >= \"A\" && c <= \"Z\") || (c >= \"0\" && c <= \"9\") || (c == \":\") {\n                out.append(c)\n            }\n        }\n\n        return String(out)\n    }\n\n    var unquote: Substring {\n        if (hasPrefix(\"'\") && hasSuffix(\"'\")) || (hasPrefix(\"\\\"\") && hasSuffix(\"\\\"\")) {\n            return self[index(startIndex, offsetBy: 1)..<index(endIndex, offsetBy: -1)]\n        }\n        return self[startIndex..<endIndex]\n    }\n\n    var camelCased: String {\n        var str = self.asValdiAttributeKey\n        if !str.isEmpty {\n            str = str[0..<1].lowercased() + str[1..<str.count]\n        }\n        return str\n    }\n\n    var pascalCased: String {\n        var str = self.asValdiAttributeKey\n        if !str.isEmpty {\n            str = str[0..<1].uppercased() + str[1..<str.count]\n        }\n        return str\n    }\n\n    var snakeCased: String {\n        let converted = self.asValdiAttributeKey\n        if converted.isEmpty {\n            return self\n        }\n\n        var allowSnakeInsertion = false\n\n        var snakeCased = \"\"\n        for char in converted {\n            if char.isUppercase {\n                if allowSnakeInsertion {\n                    allowSnakeInsertion = false\n                    snakeCased.append(\"_\")\n                }\n                snakeCased.append(String(char).lowercased())\n            } else {\n                allowSnakeInsertion = true\n                snakeCased.append(char)\n            }\n        }\n        return snakeCased\n    }\n\n    subscript(range: Range<Int>) -> Substring {\n        let fromIndex = index(startIndex, offsetBy: range.lowerBound)\n        let toIndex = index(fromIndex, offsetBy: range.count)\n\n        return self[fromIndex..<toIndex]\n    }\n\n    subscript(index: Int) -> Character {\n        return self[self.index(startIndex, offsetBy: index)]\n    }\n\n    func removingCharacters(in set: CharacterSet) -> String {\n        let filtered = unicodeScalars.lazy.filter { !set.contains($0) }\n        return String(String.UnicodeScalarView(filtered))\n    }\n\n    var removingFirstCharacter: String {\n        return String(self[self.index(self.startIndex, offsetBy: 1)...])\n    }\n\n    func split(at: Character) -> (String, String) {\n        let kv = self.split(separator: at, maxSplits: 1, omittingEmptySubsequences: true)\n        if kv.count != 2 {\n            return (String(kv[0]), \"\")\n        }\n        return (String(kv[0]), String(kv[1]))\n    }\n\n    func trim(after: Character) -> String {\n        let (trimmed, _) = self.split(at: after)\n        return trimmed\n    }\n\n    func removing(suffix: String) -> String {\n        if hasSuffix(suffix) {\n            return String(self[self.startIndex..<self.index(self.startIndex, offsetBy: self.count - suffix.count)])\n        } else {\n            return self\n        }\n    }\n\n    func removing(suffixes: [String]) -> String {\n        var current = self\n\n        for suffix in suffixes {\n            current = current.removing(suffix: suffix)\n        }\n\n        return current\n    }\n}\n\nprivate let lowercaseLettersSet = CharacterSet.lowercaseLetters\n\nextension Character {\n\n    var isUppercase: Bool {\n        return !String(self).trimmingCharacters(in: lowercaseLettersSet).isEmpty\n    }\n\n}\n\nextension StringProtocol {\n\n    var escapingSpaces: String {\n        return self.replacingOccurrences(of: \" \", with: \"\\\\ \")\n    }\n\n    func utf8Data() throws -> Data {\n        guard let data = self.data(using: .utf8) else {\n            throw CompilerError(\"Could not get UTF8 Data from string\")\n        }\n        return data\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/Swift+Utils.swift",
    "content": "//\n//  Swift+Utils.swift\n//  BlueSocket\n//\n//  Created by saniul on 25/03/2019.\n//\n\nimport Foundation\n\nfunc FIXME(_ message: String = \"\") -> Never {\n    fatalError(message)\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/TimeInterval+Utils.swift",
    "content": "//\n//  TimeInterval+Utils.swift\n//  Compiler\n//\n//  Created by David Byttow on 10/27/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\npublic extension TimeInterval {\n    var milliseconds: Int {\n        return Int(self * 1_000.0)\n    }\n\n    var microseconds: Int {\n        return Int(self * 1_000_000.0)\n    }\n\n    fileprivate static let since1970: TimeInterval = 978307200\n}\n\npublic typealias AbsoluteTime = Double\npublic extension AbsoluteTime {\n    static var current: AbsoluteTime {\n        #if os(macOS)\n        return CFAbsoluteTimeGetCurrent()\n        #else\n        var tv = timeval()\n        gettimeofday(&tv, nil)\n        return TimeInterval(tv.tv_sec) - TimeInterval.since1970 + (1.0E-6 * TimeInterval(tv.tv_usec))\n        #endif\n    }\n\n    var timeElapsed: TimeInterval {\n        return AbsoluteTime.current - self\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/URL+FileExtensions.swift",
    "content": "//\n//  URL+FileExtensions.swift\n//  Compiler\n//\n//  Created by David Byttow on 10/24/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension URL {\n    static var valdiDirectoryURL: URL {\n        return URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent(\".valdi\", isDirectory: true)\n    }\n\n    static var logsDirectoryURL: URL {\n        return valdiDirectoryURL.appendingPathComponent(\"logs\", isDirectory: true)\n    }\n\n    static var deviceStorageDirectoryURL: URL {\n        return valdiDirectoryURL.appendingPathComponent(\"device_storage\", isDirectory: true)\n    }\n\n    static var valdiUserConfigURL: URL {\n        return valdiDirectoryURL.appendingPathComponent(\"config.yaml\", isDirectory: false)\n    }\n\n    func deletingPathExtensions(_ set: [String]) -> URL {\n        let url = self.deletingLastPathComponent()\n        let newLastPathComponent = self.lastPathComponent.removing(suffixes: set)\n        return url.appendingPathComponent(newLastPathComponent)\n    }\n\n    var deletingTypeScriptFileExtensions: URL {\n        return deletingPathExtensions(FileExtensions.typescriptFileExtensionsDotted)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/URL+Navigation.swift",
    "content": "//\n//  URL+Navigation.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/29/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct RelativePath: CustomStringConvertible, CustomDebugStringConvertible, Hashable, Equatable, Comparable {\n    let components: [String]\n\n    init(from: URL, to: URL) {\n        let components = from.pathComponents.replacingPrefix([\"/\", \"private\"], replacement: [\"/\"])\n        let otherComponents = to.pathComponents.replacingPrefix([\"/\", \"private\"], replacement: [\"/\"])\n\n        var matchingIndex = 0\n        var index = 0\n        while index < components.count && index < otherComponents.count {\n            if components[index] == otherComponents[index] {\n                matchingIndex = index\n            } else {\n                break\n            }\n            index += 1\n        }\n\n        let dotDots = Array(repeating: \"..\", count: components.count - matchingIndex - 1)\n        let componentsRest = otherComponents[(matchingIndex + 1)...]\n        self.components = dotDots + componentsRest\n    }\n\n    init(url: URL) {\n        self.components = url.pathComponents\n    }\n\n    init(components: [String]) {\n        self.components = components\n    }\n\n    var description: String {\n        if components.isEmpty {\n            return \".\"\n        } else {\n            return components.joined(separator: \"/\")\n        }\n    }\n\n    var debugDescription: String {\n        return description\n    }\n\n    static func <(lhs: RelativePath, rhs: RelativePath) -> Bool {\n        if lhs.components.count < rhs.components.count {\n            return true\n        } else if lhs.components.count > rhs.components.count {\n            return false\n        }\n\n        for i in 0..<lhs.components.count {\n            if lhs.components[i] < rhs.components[i] {\n                return true\n            } else if lhs.components[i] > rhs.components[i] {\n                return false\n            }\n        }\n\n        return false\n    }\n}\n\nextension URL {\n\n    // NOTE: Only resolves symlinks if the file at `path` exists.\n    // See: https://developer.apple.com/documentation/foundation/nsurl/1415965-resolvingsymlinksinpath\n    func resolving(path: String, isDirectory: Bool = false) -> URL {\n        var newPath = path\n\n        if newPath.first == \"~\" {\n            newPath = \"\\(NSHomeDirectory())\\(newPath[1..<newPath.count])\"\n        }\n\n        return URL(fileURLWithPath: newPath, isDirectory: isDirectory, relativeTo: self).standardizedFileURL.absoluteURL\n    }\n\n    func relativePath(from url: URL) -> String {\n        return url.relativePath(to: self)\n    }\n\n    func relativePath(to url: URL) -> String {\n        return RelativePath(from: self, to: url).description\n    }\n\n    private static func getCommonPathComponent(index: Int, allPathComponents: [[String]]) -> String? {\n        var commonPathComponent: String? = nil\n\n        for pathComponents in allPathComponents {\n            let pathComponent = pathComponents[index]\n            if let commonPathComponent {\n                if commonPathComponent != pathComponent {\n                    return nil\n                }\n            } else {\n                commonPathComponent = pathComponent\n            }\n        }\n        return commonPathComponent\n    }\n\n    static func commonFileURL(in urls: [URL]) -> URL {\n        var commonComponents = [String]()\n        let allPathComponents = urls.map { $0.pathComponents }\n\n        let lowestNumberOfPathComponents = allPathComponents.reduce(Int.max) { partialResult, components in\n            return min(partialResult, components.count)\n        }\n\n        for i in 0..<lowestNumberOfPathComponents {\n            if let commonPathComponent = getCommonPathComponent(index: i, allPathComponents: allPathComponents) {\n                commonComponents.append(commonPathComponent)\n            } else {\n                break\n            }\n        }\n\n        return URL(fileURLWithPath: commonComponents.joined(separator: \"/\"))\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/URL+RandomFile.swift",
    "content": "//\n//  URL+RandomFile.swift\n//  Spectre\n//\n//  Created by Simon Corsin on 3/13/17.\n//  Copyright © 2017 Snapchat, Inc. All rights reserved.\n//\n\nimport Foundation\n\nextension URL {\n\n    static func randomFileURL(extension ext: String? = nil) -> URL {\n        let filenameWithoutExtension = UUID().uuidString\n        let filename = ext.map { \"\\(filenameWithoutExtension).\\($0)\" } ?? filenameWithoutExtension\n        return URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(filename)\n    }\n\n}\n\nextension NSURL {\n\n    // Obj-C version\n    class func randomFileURL(extension ext: String? = nil) -> NSURL {\n        return URL.randomFileURL(extension: ext) as NSURL\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Extensions/URL+Symlink.swift",
    "content": "//\n//  URL+Symlink.swift\n//  Compiler\n//\n//  Created by John Corbett on 9/25/24.\n//  Copyright © 2024 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nenum SymlinkErrors: Error {\n    case resolvedSymlinkDoesNotExist(String)\n}\n\nextension URL {\n    func resolvingSymlink() throws -> URL {\n        //  This code handles the resolution of symbolic links differently based on the operating system.\n        //  On Linux, the native `resolvingSymlinksInPath` method is known to have bugs. Therefore, we leverages C APIs directly.\n        //  https://github.com/swiftlang/swift-corelibs-foundation/issues/3685\n        // \n        //  On non-Linux systems, the standard `resolvingSymlinksInPath` method is used to resolve the symbolic links.\n\n        #if os(Linux)\n\n        var buffer = [CChar](repeating: 0, count: Int(PATH_MAX))\n        self.withUnsafeFileSystemRepresentation { fileSystemPath in\n            if let fileSystemPath = fileSystemPath {\n                _ = realpath(fileSystemPath, &buffer)\n            }\n        }\n        var isDirectory: ObjCBool = false\n        let resolvedPath = String(cString: buffer)\n        if !FileManager.default.fileExists(atPath: resolvedPath, isDirectory: &isDirectory) {\n            throw SymlinkErrors.resolvedSymlinkDoesNotExist(resolvedPath)\n        }\n        \n        return URL(fileURLWithFileSystemRepresentation: buffer, isDirectory: isDirectory.boolValue, relativeTo: nil)\n\n        #else  // os(MacOS)\n\n        return self.resolvingSymlinksInPath()\n\n        #endif  // end os(Linux)\n    }\n\n    func resolvingSymlink(resolveParentDirs: Bool) throws -> URL {\n        if resolveParentDirs && !FileManager.default.fileExists(atPath: self.path) {\n            var components = [String]()\n            var current = self.standardized.deletingLastPathComponent()\n            components.append(self.lastPathComponent)\n\n            while true {\n                if FileManager.default.fileExists(atPath: current.path) {\n                    break\n                }\n\n                let component = current.lastPathComponent\n                if component.isEmpty {\n                    throw SymlinkErrors.resolvedSymlinkDoesNotExist(self.path)\n                }\n\n                components.append(component)\n                current = current.deletingLastPathComponent()\n            }\n\n            let resolvedDir = try current.resolvingSymlink()\n\n            return resolvedDir.appendingPathComponent(components.reversed().joined(separator: \"/\"))\n        } else {\n            return try resolvingSymlink()\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/FileHandleReader.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\nopen class FileHandleReader {\n    var onDidReceiveData: ((_ reader: FileHandleReader) -> Void)?\n\n    var content: Data {\n        get {\n            if dispatchQueue == nil {\n                readToEnd()\n            }\n            return buffer\n        }\n        set(newValue) {\n            buffer = newValue\n        }\n    }\n    \n    var contentAsString: String {\n        get {\n            return String(data: content, encoding: .utf8) ?? \"\"\n        }\n        set {\n            content = newValue.data(using: .utf8) ?? Data()\n        }\n    }\n\n    private var buffer = Data()\n\n    private let dispatchQueue: DispatchQueue?\n    private let fileHandle: FileHandle\n    private var channel: DispatchIO?\n    private var onDonePromises: [Promise<Void>]?\n\n    init(fileHandle: FileHandle, dispatchQueue: DispatchQueue?) {\n        self.dispatchQueue = dispatchQueue\n        self.fileHandle = fileHandle\n\n        if let dispatchQueue = dispatchQueue {\n            self.channel = DispatchIO(type: .stream, fileDescriptor: fileHandle.fileDescriptor, queue: dispatchQueue) { (_) in\n\n            }\n            channel?.setLimit(lowWater: 1)\n            scheduleRead(queue: dispatchQueue)\n        }\n    }\n\n    deinit {\n        close()\n    }\n\n    func trimContent(by offset: Int) {\n        buffer.removeSubrange(0..<offset)\n    }\n\n    func readToEnd() {\n        let data = fileHandle.readDataToEndOfFile()\n        if !data.isEmpty {\n            if buffer.isEmpty {\n                buffer = data\n            } else {\n                buffer.append(data)\n            }\n        }\n    }\n\n    func waitUntilDone() throws {\n        if let dispatchQueue {\n            let promise = Promise<Void>()\n            dispatchQueue.sync {\n                if channel == nil {\n                    promise.resolve(data: ())\n                } else {\n                    if self.onDonePromises == nil {\n                        self.onDonePromises = []\n                    }\n                    self.onDonePromises?.append(promise)\n                }\n            }\n\n            try promise.waitForData()\n        } else {\n            readToEnd()\n        }\n    }\n\n    private func close() {\n        if let channel = self.channel {\n            self.channel = nil\n            channel.close()\n        }\n    }\n\n    private func onDone() {\n        close()\n        if let onDonePromises = self.onDonePromises {\n            self.onDonePromises = nil\n            onDonePromises.forEach { $0.resolve(data: ()) }\n        }\n    }\n\n    private func scheduleRead(queue: DispatchQueue) {\n        channel?.read(offset: 0, length: Int.max, queue: queue, ioHandler: { [weak self] (done, data, _) in\n            guard let self else { return }\n            if let data = data {\n                self.didReceive(data: data)\n            }\n\n            if done {\n                self.onDone()\n            } else {\n                self.scheduleRead(queue: queue)\n            }\n        })\n    }\n\n    private func didReceive(data: DispatchData) {\n        if !data.isEmpty {\n            for region in data.regions {\n                region.withUnsafeBytes { buffer in\n                    self.buffer.append(buffer.bindMemory(to: UInt8.self).baseAddress!, count: region.count)\n                }\n            }\n            self.onDidReceiveData?(self)\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/FileHeaderCommentGenerator.swift",
    "content": "//\n//  FileHeaderCommentGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/21/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct FileHeaderCommentGenerator {\n\n    static func generateMultilineComment(comment: String) -> String {\n        let commentLines = comment\n            .split(separator: \"\\n\", maxSplits: Int.max, omittingEmptySubsequences: false)\n            .map { \"* \\($0)\" }\n            .joined(separator: \"\\n\")\n\n        return \"\"\"\n        /**\n        \\(commentLines)\n        */\n        \"\"\"\n    }\n\n    private static func generateHeaderMessage(sourceFilename: GeneratedSourceFilename) -> String {\n        return \"\"\"\n        Generated from type '\\(sourceFilename.symbolName)' at '\\(sourceFilename.filename)' by the Valdi compiler.\n        Please do not edit this file directly.\n        \"\"\"\n    }\n\n    static func generateFactoryHeaderMessage(className: String, sourceFilename: GeneratedSourceFilename) -> String {\n        let commentMessage = \"\"\"\n        Generated factory for '\\(className)' at '\\(sourceFilename.filename)' by the Valdi compiler.\n        Needed for native dependency injection.\n        Please do not edit this file directly.\n        \"\"\"\n\n        return generateMultilineComment(comment: commentMessage)\n    }\n\n    static func generateComment(sourceFilename: GeneratedSourceFilename, additionalComments: String? = nil) -> String {\n        var commentMessage = generateHeaderMessage(sourceFilename: sourceFilename)\n\n        if let additionalComments = additionalComments, !additionalComments.isEmpty {\n            commentMessage = \"\\(additionalComments)\\n\\n\\(commentMessage)\"\n        }\n\n        return generateMultilineComment(comment: commentMessage)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/GeneratedSourceFilename.swift",
    "content": "//\n//  GeneratedSourceFilename.swift\n//  \n//\n//  Created by Simon Corsin on 11/23/21.\n//\n\nimport Foundation\n\nstruct GeneratedSourceFilename {\n    let filename: String\n    let symbolName: String\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/InclusionConfig.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\nimport Yams\n\n/**\n Holds a set of include or exclude patterns that helps resolving the inclusion or exclusion of an item for a rule.\n */\nstruct InclusionConfig {\n    enum InclusionResult {\n        /**\n         The item matches one of the include patterns\n         */\n        case included\n        /**\n         The item matches one of the exclude patterns\n         */\n        case excluded\n        /**\n         The item did match any of the patterns.\n         */\n        case unknown\n    }\n\n    let includePatterns: [NSRegularExpression]\n    let excludePatterns: [NSRegularExpression]\n\n    static let alwaysIncluded = InclusionConfig(includePatterns: [try! NSRegularExpression(pattern: \".*\")], excludePatterns: [])\n\n    private static func parsePatterns(from nodes: [Yams.Node]) throws -> [NSRegularExpression] {\n        return try nodes.compactMap { $0.string }.map { try NSRegularExpression(pattern: $0, options: []) }\n    }\n\n    static func parse(from mapping: Yams.Node) throws -> InclusionConfig {\n        let includePatterns = try parsePatterns(from: mapping[\"include_patterns\"]?.array() ?? [])\n        let excludePatterns = try parsePatterns(from: mapping[\"exclude_patterns\"]?.array() ?? [])\n\n        return InclusionConfig(includePatterns: includePatterns, excludePatterns: excludePatterns)\n    }\n\n    /**\n     Resolves whether the given item matches one of the include or exclude patterns.\n     */\n    func resolve(_ str: String) -> InclusionResult {\n        if isExcluded(str) {\n            return .excluded\n        }\n\n        if isIncluded(str) {\n            return .included\n        }\n\n        return .unknown\n    }\n\n    private func isIncluded(_ str: String) -> Bool {\n        for pattern in includePatterns {\n            if str.matches(regex: pattern) {\n                return true\n            }\n        }\n\n        return false\n    }\n\n    private func isExcluded(_ str: String) -> Bool {\n        for pattern in excludePatterns {\n            if str.matches(regex: pattern) {\n                return true\n            }\n        }\n\n        return false\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/KillOnTimeout.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\nimport Collections\nimport Backtrace\n\nclass LoggerInterceptorImpl: LoggerInterceptor {\n\n    private var logs = Deque<Log>()\n    private let lock = DispatchSemaphore.newLock()\n\n    private static let maxLogSize = 1000\n\n    struct Log {\n        let message: String\n    }\n\n    func onInterceptLog(message: String, functionStr: StaticString) {\n        lock.lock {\n            logs.append(Log(message: message))\n            while logs.count > LoggerInterceptorImpl.maxLogSize {\n                logs.removeFirst()\n            }\n        }\n    }\n\n    func collectLogs() -> [Log] {\n        return lock.lock {\n            logs.map { $0 }\n        }\n    }\n}\n\nclass KillOnTimeout {\n\n    private static var allInstances = Synchronized<[KillOnTimeout]>(data: [])\n\n    private let logger: ILogger\n    private let timeoutSeconds: TimeInterval\n    private var task: Cancelable?\n    private let queue = DispatchQueue(label: \"com.valdi.compiler.KillOnTimeout\", qos: .default)\n    private let logs = LoggerInterceptorImpl()\n\n    init(logger: ILogger, timeoutSeconds: TimeInterval) {\n        self.logger = logger\n        self.timeoutSeconds = timeoutSeconds\n    }\n\n    func start() {\n        logger.interceptor = logs\n\n        let task = CancelableBlock { [weak self] in\n            self?.timeoutDetected()\n        }\n        self.queue.asyncAfter(deadline: .now() + timeoutSeconds, execute: task.run)\n\n        KillOnTimeout.allInstances.data { array in\n            array.append(self)\n        }\n    }\n\n    func stop() {\n        task?.cancel()\n        task = nil\n\n        KillOnTimeout.allInstances.data { array in\n            array.removeAll { instance in\n                return instance === self\n            }\n        }\n    }\n\n    private func notifyTimeoutDetectedNow() {\n        queue.sync {\n            self.timeoutDetected()\n        }\n    }\n\n    private func logToStdError(message: String) {\n        let messageData = try! \"\\(message)\\n\".utf8Data()\n        let _ = try? FileHandle.standardError.write(contentsOf: messageData)\n    }\n\n    private func timeoutDetected() {\n        let allLogs = logs.collectLogs()\n        logToStdError(message: \"\\n\\n\\nSHOWING LAST \\(allLogs.count) LOGS...\\n\\n\\n\")\n        for l in allLogs {\n            logToStdError(message: l.message)\n        }\n\n        logToStdError(message: \"\\n\\n\\nPROCESS DID TIMEOUT AFTER \\(timeoutSeconds) seconds!\")\n        let _ = try? FileHandle.standardError.synchronize()\n        raise(SIGQUIT)\n\n        // Force kill process if it didn't kill itself already\n        queue.asyncAfter(deadline: .now() + TimeInterval(2)) {\n            Backtrace.print()\n            fflush(stderr)\n\n            _exit(1)\n        }\n    }\n\n    static func notifyTimeout() {\n        for instance in KillOnTimeout.allInstances.unsafeData {\n            instance.timeoutDetected()\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/LinesIndexer.swift",
    "content": "//\n//  LinesIndexer.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/5/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct LineOffset {\n    let lineOffset: Int\n    let characterOffset: Int\n}\n\nstruct LinesIndexer {\n\n    private var ranges = [NSRange]()\n    private let str: NSString\n\n    init(str: String) {\n        self.init(str: str as NSString)\n    }\n\n    init(str: NSString) {\n        var currentRange = NSRange(location: 0, length: str.length)\n        let newLines = CharacterSet.newlines\n\n        while true {\n            let foundRange = str.rangeOfCharacter(from: newLines, options: [], range: currentRange)\n            if foundRange.lowerBound == NSNotFound {\n                break\n            }\n\n            ranges.append(NSRange(location: currentRange.lowerBound, length: foundRange.upperBound - currentRange.lowerBound))\n            currentRange = NSRange(location: foundRange.upperBound, length: str.length - foundRange.upperBound)\n        }\n\n        if currentRange.length > 0 {\n            ranges.append(currentRange)\n        }\n        self.str = str\n    }\n\n    func substring(start: Int, end: Int) -> String {\n        return str.substring(with: NSRange(location: start, length: end - start))\n    }\n\n    func characterIndex(forLineIndex lineIndex: Int, column: Int) -> Int {\n        return ranges[lineIndex].lowerBound + column\n    }\n\n    func lineIndex(atCharacterIndex index: Int) -> LineOffset {\n        let rangeIndex = ranges.index { (range) -> ComparisonResult in\n            if range.lowerBound > index {\n                return .orderedAscending\n            } else if range.upperBound < index {\n                return .orderedDescending\n            }\n            return .orderedSame\n        }!\n\n        let range = ranges[rangeIndex]\n\n        return LineOffset(lineOffset: rangeIndex, characterOffset: index - range.lowerBound)\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Logger.swift",
    "content": "//\n//  Logger.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/6/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport Chalk\n\nenum LogLevel: Int, CaseIterable, Codable {\n    case trace = -2\n    case verbose = -1\n    case debug = 0\n    case info = 1\n    case warn = 2\n    case error = 3\n}\n\nextension LogLevel {\n\n    var description: String {\n        switch self {\n        case .trace:\n            return \"TRACE\"\n        case .verbose:\n            return \"VERBOSE\"\n        case .debug:\n            return \"DEBUG\"\n        case .info:\n            return \"INFO\"\n        case .warn:\n            return \"WARN\"\n        case .error:\n            return \"ERROR\"\n        }\n    }\n\n    var color: Chalk.Color {\n        switch self {\n        case .trace:\n            return .white\n        case .verbose:\n            return .white\n        case .debug:\n            return .white\n        case .info:\n            return .blue\n        case .warn:\n            return .yellow\n        case .error:\n            return .red\n        }\n    }\n\n    var style: Chalk.Style {\n        switch self {\n        case .trace:\n            return .dim\n        case .verbose:\n            return .dim\n        case .debug:\n            return .normal\n        case .info:\n            return .bold\n        case .warn:\n            return .bold\n        case .error:\n            return .bold\n        }\n    }\n\n    init?(description: String) {\n        switch description {\n        case \"TRACE\":\n            self = .trace\n        case \"VERBOSE\":\n            self = .verbose\n        case \"DEBUG\":\n            self = .debug\n        case \"INFO\":\n            self = .info\n        case \"WARN\":\n            self = .warn\n        case \"ERROR\":\n            self = .error\n        default:\n            return nil\n        }\n    }\n\n}\n\nextension Chalk.Style {\n    public static let normal = Style([])\n}\n\nprotocol LoggerInterceptor: AnyObject {\n    func onInterceptLog(message: String, functionStr: StaticString)\n}\n\nprotocol ILogger: AnyObject {\n    var minLevel: LogLevel { get set }\n    var duplicateStderrToStdout: Bool { get set }\n    var interceptor: LoggerInterceptor? { get set }\n    var emittedLogsCount: Int { get }\n\n    func log(level: LogLevel, _ message: () -> String, functionStr: StaticString)\n    func flush()\n}\n\nprotocol ILoggerOutput: AnyObject {\n    func write(data: Data, isError: Bool)\n}\n\nclass FileHandleLoggerOutput: ILoggerOutput {\n\n    private let stdout: FileHandle\n    private let stderr: FileHandle\n\n    init(stdout: FileHandle, stderr: FileHandle) {\n        self.stdout = stdout\n        self.stderr = stderr\n    }\n\n    private func doWrite(data: Data, fileHandle: FileHandle) throws {\n        if #available(OSX 10.15.4, *) {\n            try fileHandle.write(contentsOf: data)\n        } else {\n            fileHandle.write(data)\n        }\n    }\n\n    func write(data: Data, isError: Bool) {\n        do {\n            if isError {\n                // Flush stdout, to make sure the errors are displayed in the right order\n                try? self.stdout.synchronize()\n\n                try doWrite(data: data, fileHandle: self.stderr)\n            } else {\n                try doWrite(data: data, fileHandle: self.stdout)\n            }\n        } catch let error {\n            print(\"[FATAL] FAILED TO WRITE MESSAGE TO stream! Source location: Error: \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n}\n\nclass BufferLoggerOutput: ILoggerOutput {    \n    var data: Data {\n        return lock.lock {\n            self.buffer\n        }\n    }\n\n    private let lock = DispatchSemaphore.newLock()\n    private var buffer = Data()\n\n    func write(data: Data, isError: Bool) {\n        lock.lock {\n            self.buffer.append(data)\n        }\n    }\n}\n\nfinal class Logger: ILogger {\n    var minLevel = LogLevel.info\n    var duplicateStderrToStdout = false\n    var interceptor: LoggerInterceptor?\n    var asyncLogs = true\n\n    var emittedLogsCount: Int {\n        return queue.sync { _emittedLogsCount }\n    }\n\n    private var _emittedLogsCount = 0\n    private let startTime = Date.timeIntervalSinceReferenceDate\n    private let queue = DispatchQueue(label: \"com.snap.valdi.Logger\")\n    private let output: ILoggerOutput\n\n    init(output: ILoggerOutput) {\n        self.output = output\n    }\n\n    func flush() {\n        queue.sync {}\n    }\n\n    private func makeMessage(level: LogLevel, timeOffset: TimeInterval, _ message: () -> String) -> String {\n        let tag = \"[\\(level.description)]\"\n        return \"[\\(String(format: \"%.3f\", timeOffset))] \\(tag, color: level.color, style: level.style) \\(message())\"\n    }\n\n    func log(level: LogLevel, _ message: () -> String, functionStr: StaticString) {\n        let timeOffset = Date.timeIntervalSinceReferenceDate - startTime\n\n        guard isEnabled(forLevel: level) else {\n            if let interceptor {\n                let message =  makeMessage(level: level, timeOffset: timeOffset, message)\n                interceptor.onInterceptLog(message: message, functionStr: functionStr)\n            }\n\n            return\n        }\n\n        let message =  makeMessage(level: level, timeOffset: timeOffset, message)\n        if let interceptor {\n            interceptor.onInterceptLog(message: message, functionStr: functionStr)\n        }\n\n        if asyncLogs {\n            queue.async { self.doLog(level: level, message: message, functionStr: functionStr) }\n        } else {\n            queue.sync { self.doLog(level: level, message: message, functionStr: functionStr) }\n        }\n    }\n\n    private func doLog(level: LogLevel, message: String, functionStr: StaticString) {\n        let messageData = try! \"\\(message)\\n\".utf8Data()\n\n        if level.rawValue >= LogLevel.error.rawValue {\n            if duplicateStderrToStdout {\n                output.write(data: messageData, isError: false)\n            }\n\n            output.write(data: messageData, isError: true)\n        } else {\n            output.write(data: messageData, isError: false)\n        }\n\n        _emittedLogsCount += 1\n    }\n\n    func isEnabled(forLevel level: LogLevel) -> Bool {\n        return minLevel.rawValue <= level.rawValue\n    }\n}\n\nextension ILogger {\n\n    func trace(_ message: @autoclosure () -> String, functionStr: StaticString = #function) {\n        log(level: .trace, message, functionStr: functionStr)\n    }\n\n    func verbose(_ message: @autoclosure () -> String, functionStr: StaticString = #function) {\n        log(level: .verbose, message, functionStr: functionStr)\n    }\n\n    func debug(_ message: @autoclosure () -> String, functionStr: StaticString = #function) {\n        log(level: .debug, message, functionStr: functionStr)\n    }\n\n    func info(_ message: @autoclosure () -> String, functionStr: StaticString = #function) {\n        log(level: .info, message, functionStr: functionStr)\n    }\n\n    func warn(_ message: @autoclosure () -> String, functionStr: StaticString = #function) {\n        log(level: .warn, message, functionStr: functionStr)\n    }\n\n    func error(_ message: @autoclosure () -> String, functionStr: StaticString = #function) {\n        log(level: .error, message, functionStr: functionStr)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/MeasureExecution.swift",
    "content": "//\n//  MeasureExecution.swift\n//  \n//\n//  Created by saniul on 21/10/2019.\n//\n\nimport Foundation\n\nfunc measureExecution(logger: ILogger, name: String, block: () throws -> Void) rethrows {\n    logger.debug(\"\\(name)...\")\n    let start = AbsoluteTime.current\n    try block()\n    let timeInterval = start.timeElapsed\n    logger.debug(\"\\(name) took: \\(timeInterval)s\")\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/NetworkInterfaceAddresses.swift",
    "content": "//\n//  NetworkInterfaceAddresses.swift\n//  Compiler\n//\n//  Created by saniul on 15/05/2019.\n//\n\nimport Foundation\n\n// Use InterfaceAddresses.getAllInterfaceAddresses() to access the in_addr structures for all network interface addresses\n// that will clean itself up when the InterfaceAddresses deinitializes.\nfinal class NetworkInterfaceAddresses {\n    var cInAddrs: [in_addr]\n    private var pointerToFree: UnsafeMutablePointer<ifaddrs>?\n\n    static func getAll() -> NetworkInterfaceAddresses {\n        var firstInterface: UnsafeMutablePointer<ifaddrs>?\n        var interfaceAddresses: [in_addr] = []\n\n        let success = getifaddrs(&firstInterface)\n\n        if success == 0 {\n            var nextInterface: UnsafeMutablePointer<ifaddrs>? = firstInterface\n            while let interface = nextInterface?.pointee {\n                if interface.ifa_addr.pointee.sa_family == UInt8(AF_INET) {\n                    let addressPointer = interface.ifa_addr.withMemoryRebound(to: sockaddr_in.self, capacity: 1) { $0 }\n                    interfaceAddresses.append(addressPointer.pointee.sin_addr)\n                }\n                nextInterface = interface.ifa_next\n            }\n        }\n\n        return NetworkInterfaceAddresses(pointerToFree: firstInterface, cInAddrs: interfaceAddresses)\n    }\n\n    private init(pointerToFree: UnsafeMutablePointer<ifaddrs>?, cInAddrs: [in_addr]) {\n        self.pointerToFree = pointerToFree\n        self.cInAddrs = cInAddrs\n    }\n\n    deinit {\n        freeifaddrs(pointerToFree)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Parser.swift",
    "content": "//\n//  Parser.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/18/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass Parser<T: Collection> {\n\n    private let sequence: T\n    private var currentIndex: T.Index\n    private var endIndex: T.Index\n\n    var isAtEnd: Bool {\n        return currentIndex == endIndex\n    }\n\n    convenience init(sequence: T) {\n        self.init(sequence: sequence, startIndex: sequence.startIndex)\n    }\n\n    init(sequence: T, startIndex: T.Index) {\n        self.sequence = sequence\n        self.currentIndex = startIndex\n        self.endIndex = sequence.endIndex\n    }\n\n    private func ensureNotAtEnd() throws {\n        guard !isAtEnd else {\n            throw CompilerError(\"Unexpectedly reached end of stream\")\n        }\n    }\n\n    private func uncheckedAdvance(distance: Int = 1) {\n        currentIndex = sequence.index(currentIndex, offsetBy: distance)\n    }\n\n    func peek() throws -> T.Element {\n        try ensureNotAtEnd()\n        return sequence[currentIndex]\n    }\n\n    func advance(distance: Int = 1) throws {\n        try ensureNotAtEnd()\n        uncheckedAdvance(distance: distance)\n    }\n\n    @discardableResult func peekAndAdvance() throws -> T.Element {\n        let topValue = try peek()\n        uncheckedAdvance()\n        return topValue\n    }\n\n    func subsequence(length: Int) throws -> T.SubSequence {\n        let startIndex = currentIndex\n\n        for _ in 0..<length {\n            try advance()\n        }\n\n        return sequence[startIndex..<currentIndex]\n    }\n\n    func parse(when: (T.Element) -> Bool) throws -> Bool {\n        if when(try peek()) {\n            uncheckedAdvance()\n            return true\n        }\n        return false\n    }\n\n    func mustParse(when: (T.Element) -> Bool) throws {\n        guard try parse(when: when) else {\n            throw CompilerError(\"Top element did not match predicate\")\n        }\n    }\n\n}\n\nextension Parser where T.Element: Equatable {\n\n    func parse(element: T.Element) throws -> Bool {\n        return try parse { $0 == element }\n    }\n\n    func parse<T2: Collection>(subsequence: T2) throws -> Bool where T2.Element == T.Element {\n        let indexAtStart = currentIndex\n        do {\n            for element in subsequence {\n                if try !parse(element: element) {\n                    currentIndex = indexAtStart\n                    return false\n                }\n            }\n            return true\n        } catch let error {\n            currentIndex = indexAtStart\n            throw error\n        }\n    }\n\n}\n\n// Debugging extension (needs to be in the same file to access `private sequence`)\n\nprotocol TextSequenceElement {\n    var text: String? { get }\n}\n\nextension Parser where T.Element: TextSequenceElement {\n    func debugDump() -> String {\n        var sequenceStrings: [String] = sequence.indices.map { idx in\n            let prefix = idx == currentIndex ? \"^\" : \"\"\n            let text = sequence[idx].text ?? \"\"\n            return \"\\(prefix)\\(text)\"\n        }\n        if currentIndex == sequence.indices.endIndex {\n            sequenceStrings.append(\"^\")\n        }\n        return sequenceStrings.joined()\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/PipeHandle.swift",
    "content": "//\n//  PipeHandle.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\npublic class PipeHandle: FileHandleReader {\n\n    public let pipe = Pipe()\n\n    private var buffer = Data()\n\n    public init(dispatchQueue: DispatchQueue?) {\n        super.init(fileHandle: pipe.fileHandleForReading, dispatchQueue: dispatchQueue)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ProcessHandle.swift",
    "content": "//\n//  ProcessHandle.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/12/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport Dispatch\n\nclass ProcessHandle: NSObject {\n    private let logger: ILogger\n\n    var exitedSuccesfully: Bool {\n        // process.terminationStatus \"raises an NSInvalidArgumentException if the receiver is still running.\n        // Verify that the receiver isn’t running before you use it.\"\n        guard !process.isRunning else {\n            logger.error(\"Checking exitedSuccessfully for process \\(process.processIdentifier), but it's still running\")\n            return false\n        }\n\n        return terminationStatus == 0\n    }\n\n    fileprivate var terminationStatus: Int32 {\n        if let cachedTerminationStatus = self.cachedTerminationStatus.data({ $0 }) {\n            return cachedTerminationStatus\n        }\n\n        // We've seen cases where accessing process.terminationStatus causes signal 4 (SIGILL).\n        // This seemed to occur on the second time we're accessing process.terminationStatus of a SyncProcessHandle\n        // after its waitUntilExit() has completed.\n        //\n        // So, let's try to counteract that by caching the termination status and only reading it out of the Process once.\n        let cachedTerminationStatus = process.terminationStatus\n        self.cachedTerminationStatus.data { $0 = cachedTerminationStatus }\n        return cachedTerminationStatus\n    }\n\n    var arguments: [String]? {\n        get { return process.arguments }\n        set { process.arguments = newValue }\n    }\n\n    var isRunning: Bool {\n        return process.isRunning\n    }\n    var stdinFileHandle: FileHandle {\n        return stdin.fileHandleForWriting\n    }\n\n    var environment: [String: String]? {\n        get { return process.environment }\n        set { process.environment = newValue }\n    }\n\n    let stdout: PipeHandle\n    let stderr: PipeHandle\n    let url: URL\n    let dispatchQueue: DispatchQueue?\n\n    private let stdin = Pipe()\n\n    fileprivate let process: Process\n\n    private var cachedTerminationStatus = Synchronized<Int32?>(data: nil)\n\n    fileprivate init(logger: ILogger, url: URL, dispatchQueue: DispatchQueue?) {\n        self.logger = logger\n        self.url = url\n        self.dispatchQueue = dispatchQueue\n\n        stdout = PipeHandle(dispatchQueue: dispatchQueue)\n        stderr = PipeHandle(dispatchQueue: dispatchQueue)\n\n        process = Process()\n        process.executableURL = url\n        process.environment = ProcessInfo.processInfo.environment\n        process.standardOutput = stdout.pipe\n        process.standardError = stderr.pipe\n        process.standardInput = stdin\n\n        super.init()\n    }\n\n    private func cancel() {\n        cleanUp()\n        process.terminate()\n    }\n\n    fileprivate func runUnderlyingProcess() throws {\n        if #available(OSX 10.13, *) {\n            try process.run()\n        } else {\n            process.launch()\n        }\n    }\n\n    private func ensureFileIsExecutable() {\n        do {\n            let attributes = try FileManager.default.attributesOfItem(atPath: url.path)\n            if let permissions = attributes[FileAttributeKey.posixPermissions] as? Int {\n                let executableMask = 0b001001001\n                if permissions & executableMask != executableMask {\n                    try FileManager.default.setAttributes([FileAttributeKey.posixPermissions: permissions | executableMask], ofItemAtPath: url.path)\n                }\n            }\n        } catch let error {\n            logger.error(\"Unable to get attribute of executable at \\(url.path): \\(error)\")\n        }\n    }\n\n    fileprivate func prepareForRun() {\n        ensureFileIsExecutable()\n    }\n\n    fileprivate func cleanUp() {\n        process.terminationHandler = nil\n    }\n\n    class Error: CompilerError {\n        init(commandName: String, arguments: [String]?, output: String) {\n            self.output = output\n            super.init(\"Command \\(commandName) with arguments \\(arguments ?? []) failed: \\(output)\")\n        }\n        let output: String\n    }\n}\n\nclass AsyncProcessHandle: ProcessHandle {\n\n    init(logger: ILogger, url: URL, dispatchQueue: DispatchQueue, cwd: String?, envOverrides: [String: String]? = nil) {\n        super.init(logger: logger, url: url, dispatchQueue: dispatchQueue)\n        if let cwd = cwd {\n            process.currentDirectoryURL = URL(fileURLWithPath: cwd)\n            process.environment = envOverrides\n        }\n    }\n\n    func runAsync(completion: @escaping (ProcessHandle) -> Void) throws {\n        prepareForRun()\n\n        process.terminationHandler = { _ in\n            // Keep retain cycle while the process is running\n            self.cleanUp()\n            completion(self)\n        }\n        try super.runUnderlyingProcess()\n    }\n\n    func run() -> Promise<Void> {\n        let promise = Promise<Void>()\n\n        do {\n            try runAsync { _ in\n                promise.resolve(data: Void())\n            }\n        } catch let error {\n            promise.reject(error: error)\n        }\n\n        return promise\n    }\n\n    class func usingEnv(logger: ILogger, command: [String], dispatchQueue: DispatchQueue, cwd: String? = nil, envOverrides: [String: String]? = nil) -> AsyncProcessHandle {\n        let processHandle = AsyncProcessHandle(logger: logger,\n                                               url: URL(fileURLWithPath: \"/usr/bin/env\"),\n                                               dispatchQueue: dispatchQueue,\n                                               cwd: cwd,\n                                               envOverrides: envOverrides)\n        processHandle.arguments = command\n\n        return processHandle\n    }\n}\n\nclass SyncProcessHandle: ProcessHandle {\n\n    init(logger: ILogger, url: URL) {\n        super.init(logger: logger, url: url, dispatchQueue: nil)\n    }\n\n    class func run(logger: ILogger, command: String, arguments: [String]) throws -> String {\n        return try run(logger: logger, url: URL(fileURLWithPath: \"/usr/bin/env\"), arguments: [command] + arguments)\n    }\n\n    class func run(logger: ILogger, url: URL, arguments: [String]?) throws -> String {\n        let syncHandle = SyncProcessHandle(logger: logger, url: url)\n        syncHandle.arguments = arguments\n\n        try syncHandle.run()\n\n        if syncHandle.terminationStatus != 0 {\n            let stderr = syncHandle.stderr.contentAsString\n            let stdout = syncHandle.stdout.contentAsString\n            let out = stderr.isEmpty ? stdout : stderr\n            throw Error(commandName: url.lastPathComponent, arguments: arguments, output: out)\n        }\n        return syncHandle.stdout.contentAsString\n    }\n\n    // readyBlock gets called after the Process was asked to start running \n    func run(readyBlock: (() -> Void)? = nil) throws {\n        prepareForRun()\n\n        process.terminationHandler = nil\n\n        try super.runUnderlyingProcess()\n        readyBlock?()\n        waitUntilExit()\n\n        if process.isRunning {\n            // We've seen process.isRunning to return true on Linux, even after process.waitUntilExit() has completed\n            //\n            // We try to work around this with sleep.\n            var i = 0\n            while process.isRunning {\n                if i > 9 {\n                    throw CompilerError(\"Called syncHandle.waitUntilExit() multiple times with sleeps in-between, but process \\(process.processIdentifier) still reports that it's running\")\n                }\n                usleep(100000)\n                waitUntilExit()\n                i += 1\n            }\n        }\n    }\n\n    private func waitUntilExit() {\n        // Ensure the pipes are fully read before waiting. This works because the dispatch queue is nil.\n        stdout.readToEnd()\n        stderr.readToEnd()\n        process.waitUntilExit()\n    }\n\n    class func usingEnv(logger: ILogger, command: [String]) -> SyncProcessHandle {\n        let processHandle = SyncProcessHandle(logger: logger, url: URL(fileURLWithPath: \"/usr/bin/env\"))\n        processHandle.arguments = command\n        return processHandle\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Promise.swift",
    "content": "//\n//  Promise.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/26/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport CoreFoundation\n\nprotocol Rejectable {\n    func reject(error: Error)\n}\n\nclass TimeoutError: LocalizedError, CustomStringConvertible {\n    let name: String\n\n    init(_ name: String) {\n        self.name = name\n    }\n\n    public var errorDescription: String? {\n        return name\n    }\n\n    var description: String {\n        return \"<TimeoutError: \\(name)>\"\n    }\n}\n\nclass Promise<T>: Rejectable {\n\n    var result: Result<T, Error>? {\n        return semaphore.lock {\n            return innerResult\n        }\n    }\n\n    private var innerResult: Result<T, Error>?\n\n    private let semaphore = DispatchSemaphore(value: 1)\n    private let condition = DispatchSemaphore(value: 0)\n\n    private var callbacks = [(Result<T, Error>) -> Void]()\n\n    init() {\n\n    }\n\n    init(result: Result<T, Error>) {\n        fulfill(result: result)\n    }\n\n    init(data: T) {\n        resolve(data: data)\n    }\n\n    init(error: Error) {\n        reject(error: error)\n    }\n\n    func fulfill(result: Result<T, Error>) {\n        var callbacks = [(Result<T, Error>) -> Void]()\n        semaphore.lock {\n            guard self.innerResult == nil else {\n                fatalError(\"Promise is already resolved\")\n            }\n            self.innerResult = result\n            callbacks = self.callbacks\n            self.callbacks = []\n            condition.signal()\n        }\n        for callback in callbacks {\n            callback(result)\n        }\n    }\n\n    func resolve(data: T) {\n        fulfill(result: .success(data))\n    }\n\n    func reject(error: Error) {\n        fulfill(result: .failure(error))\n    }\n\n    @discardableResult func then<T2>(_ completion: @escaping (T) -> T2) -> Promise<T2> {\n        return then { (result) -> Promise<T2> in\n            let newResult = completion(result)\n            return Promise<T2>(data: newResult)\n        }\n    }\n\n    @discardableResult func then<T2>(_ completion: @escaping (T) throws -> T2) -> Promise<T2> {\n        return then { (result) -> Promise<T2> in\n            do {\n                let newResult = try completion(result)\n                return Promise<T2>(data: newResult)\n            } catch {\n                return Promise<T2>(error: error)\n            }\n        }\n    }\n\n    @discardableResult func then<T2>(_ completion: @escaping (T) -> Promise<T2>) -> Promise<T2> {\n        let newPromise = Promise<T2>()\n\n        onComplete { (result) in\n            switch result {\n            case .success(let data):\n                let returnedPromise = completion(data)\n                returnedPromise.onComplete { (result) in\n                    newPromise.fulfill(result: result)\n                }\n            case .failure(let error):\n                newPromise.reject(error: error)\n            }\n        }\n\n        return newPromise\n    }\n\n    func dispatch(on queue: DispatchQueue) -> Promise<T> {\n        let newPromise = Promise<T>()\n\n        onComplete { (result) in\n            queue.async {\n                newPromise.fulfill(result: result)\n            }\n        }\n\n        return newPromise\n    }\n\n    func `catch`(_ completion: @escaping (Error) -> Void) -> Promise<T> {\n        return self.catch { (error) -> Error in\n            completion(error)\n            return error\n        }\n    }\n\n    func `catch`(_ completion: @escaping (Error) -> Error) -> Promise<T> {\n        return self.catch { (error) -> Promise<T> in\n            let newError = completion(error)\n            return Promise(error: newError)\n        }\n    }\n\n    func `catch`(_ completion: @escaping (Error) -> Promise<T>) -> Promise<T> {\n        let newPromise = Promise<T>()\n\n        onComplete { (result) in\n            switch result {\n            case .success(let data):\n                newPromise.resolve(data: data)\n            case .failure(let error):\n                let returnedPromise = completion(error)\n                returnedPromise.onComplete { (result) in\n                    newPromise.fulfill(result: result)\n                }\n            }\n        }\n\n        return newPromise\n    }\n\n    func onComplete(_ completion: @escaping (Result<T, Error>) -> Void) {\n        var result: Result<T, Error>?\n        semaphore.lock {\n            if self.innerResult == nil {\n                callbacks.append(completion)\n            } else {\n                result = innerResult\n            }\n        }\n\n        if let result {\n            completion(result)\n        }\n    }\n\n    private func waitForResultDidTimeOut(timeoutSeconds: TimeInterval) -> Result<T, Error> {\n        return .failure(TimeoutError(\"Promise failed to resolve in \\(timeoutSeconds) seconds\"))\n    }\n\n    func waitForResult(maxWaitTimeSeconds: TimeInterval = LockConfig.waitTimeoutSeconds) -> Result<T, Error> {\n        if Thread.isMainThread {\n            let expirationTimeSeconds = CFAbsoluteTimeGetCurrent() + maxWaitTimeSeconds\n            var result = self.result\n            while result == nil {\n                if CFAbsoluteTimeGetCurrent() > expirationTimeSeconds {\n                    return waitForResultDidTimeOut(timeoutSeconds: maxWaitTimeSeconds)\n                }\n\n                // To avoid locking the main thread, we just run it until\n                // we get a result. This is because some completion logic may\n                // rely on enqueing into the main thread to complete\n                let _ = RunLoop.main.run(mode: .default, before: Date().addingTimeInterval(0.05))\n                result = self.result\n            }\n            return result!\n        } else {\n            switch condition.wait(timeout: DispatchTime.now() + maxWaitTimeSeconds) {\n            case .timedOut:\n                return waitForResultDidTimeOut(timeoutSeconds: maxWaitTimeSeconds)\n            case .success:\n                condition.signal()\n                return result!\n            }\n        }\n    }\n\n    func waitForData(maxWaitTimeSeconds: TimeInterval = LockConfig.waitTimeoutSeconds) throws -> T {\n        let result = waitForResult(maxWaitTimeSeconds: maxWaitTimeSeconds)\n        switch result {\n        case .success(let data):\n            return data\n        case .failure(let error):\n            throw error\n        }\n    }\n\n    class func of<C: Collection>(promises: C) -> Promise<[T]> where C.Element == Promise<T> {\n        if promises.isEmpty {\n            return Promise<[T]>(data: [])\n        }\n\n        let outPromise = Promise<[T]>()\n        let syncResults = Synchronized(data: [Result<T, Error>?](repeating: nil, count: promises.count))\n        var completedPromises = 0\n\n        for (index, promise) in promises.enumerated() {\n            promise.onComplete { (result) in\n                syncResults.data { (results) in\n                    results[index] = result\n                    completedPromises += 1\n\n                    if completedPromises == results.count {\n                        var allResults = [T]()\n                        allResults.reserveCapacity(results.count)\n                        for existingResult in results {\n                            do {\n                                let data = try existingResult!.get()\n                                allResults.append(data)\n                            } catch let error {\n                                outPromise.reject(error: error)\n                                return\n                            }\n                        }\n\n                        outPromise.resolve(data: allResults)\n                    }\n                }\n\n            }\n        }\n\n        return outPromise\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/RandomAccessCollection+SafeGet.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by saniul on 10/10/2019.\n//\n\nimport Foundation\n\npublic extension RandomAccessCollection {\n    subscript(safe idx: Index) -> Element? {\n        get {\n            if indices.contains(idx) {\n                return self[idx]\n            } else {\n                return nil\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Ref.swift",
    "content": "//\n//  Ref.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/7/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass Ref<T> {\n    var value: T\n\n    init(value: T) {\n        self.value = value\n    }\n}\n\nstruct WeakRef<T: AnyObject> {\n    weak var value: T?\n\n    init(value: T) {\n        self.value = value\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ResolvedModuleImport.swift",
    "content": "import Foundation\n\nstruct ResolvedModuleImport: CustomStringConvertible {\n    /// Module name. nil for global modules\n    let moduleName: String?\n\n    /// Import path relative to the module root\n    let moduleRelativeImportPath: String\n\n    /// Import path relative to the root folder\n    let rootRelativeImportPath: String\n\n    /// Return `true` if the import is from the `test` subfolder, `false` otherwise\n    var isTestImport: Bool {\n        return self.moduleRelativeImportPath.starts(with: \"test/\")\n    }\n\n    init(compilationPath: String, importPath: String) {\n        if importPath.hasPrefix(\"/\") {\n            self.rootRelativeImportPath = String(importPath[importPath.index(importPath.startIndex, offsetBy: 1)...])\n        } else {\n            self.rootRelativeImportPath = importPath\n        }\n\n        if self.rootRelativeImportPath.contains(\"/\") {\n            let rootRelativecomponents = self.rootRelativeImportPath.components(separatedBy: \"/\")\n            let firstComponent = rootRelativecomponents.first!\n\n            // NPM scoped import\n            if (rootRelativecomponents.count >= 2 && firstComponent.starts(with: \"@\")) {\n                self.moduleName = rootRelativecomponents[1] + rootRelativecomponents[0]\n            } else {\n                self.moduleName = firstComponent\n            }\n\n            self.moduleRelativeImportPath =  rootRelativecomponents[1...].joined(separator: \"/\")\n        } else {\n            self.moduleName = nil\n            self.moduleRelativeImportPath = self.rootRelativeImportPath\n        }\n    }\n\n    var description: String {\n        return self.rootRelativeImportPath\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/SafeAutorelease.swift",
    "content": "//\n//  SafeAutorelease.swift\n//  \n//\n//  Created by Simon Corsin on 3/5/21.\n//\n\nimport Foundation\n\n@_transparent\nfunc safeAutorelease<T>(_ block: () throws -> T) rethrows -> T {\n  #if canImport(Darwin)\n    return try autoreleasepool {\n      try block()\n    }\n  #else\n    return try block()\n  #endif\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/SentryClient.swift",
    "content": "//\n//  SentryClient.swift\n//\n// Created by Vasily Fomin on 03/26/24.\n// Copyright © 2024 Snap, Inc. All rights reserved.\n\nimport Foundation\n\n#if os(macOS) && !DEBUG\nimport Sentry\n\n// Upstream Sentry doesn't support Linux and we don't want to send events for DEBUG builds.\n// This wrapper is to avoid spreading #ifdefs all over the place\nclass SentryClient {\n    private static func getObjCClass(name: String) -> NSObject {\n        return name.withCString( { ptr in\n            return objc_getClass(ptr)\n        }) as! NSObject\n    }\n\n    private static func sendObjCMessage(obj: NSObject, message: String) -> NSObject? {\n        let selector = NSSelectorFromString(message)\n        guard let result = obj.perform(selector) else {\n            return nil\n        }\n\n        return result.takeUnretainedValue() as? NSObject\n    }\n\n    private static func sendObjCMessage(obj: NSObject, message: String, argument: Any?) -> NSObject? {\n        let selector = NSSelectorFromString(message)\n        guard let result = obj.perform(selector, with: argument) else {\n            return nil\n        }\n\n        return result.takeUnretainedValue() as? NSObject\n    }\n\n    private static func hackSentrySoThatItDoesntCrash(options: Options) {\n        autoreleasepool {\n            // Inject options into Sentry, so that SentryCrashWrapper.sharedInstance().systemInfo\n            // resolves the right options\n            let sentryCls = getObjCClass(name: \"SentrySDK\")\n            let _ = sendObjCMessage(obj: sentryCls, message: \"setStartOptions:\", argument: options)\n\n            // Executes: SentryCrashWrapper.sharedInstance().systemInfo\n            // The goal is to workaround a deadlock within Sentry by eagerly initializing\n            // SentryCrashWrapper's sharedInstance and its systemInfo property, which\n            // uses a global lock\n            let cls = getObjCClass(name: \"SentryCrashWrapper\")\n            let sharedInstance = sendObjCMessage(obj: cls, message: \"sharedInstance\")!\n            let _ = sendObjCMessage(obj: sharedInstance, message: \"systemInfo\")\n        }\n    }\n\n    static func start(dsn: String, tracesSampleRate: NSNumber, username: String) {\n        let options = Options()\n        options.dsn = dsn\n        options.tracesSampleRate = tracesSampleRate\n        options.enableAppHangTracking = false\n\n        hackSentrySoThatItDoesntCrash(options: options)\n\n        SentrySDK.start(options: options)\n        \n        let user = User()\n        user.username = username\n        SentrySDK.setUser(user)\n    }\n    \n    static func startTransaction(name: String, operation: String) -> Span {\n        return SentrySDK.startTransaction(\n            name: name,\n            operation: operation\n        )\n    }\n    \n    static func startChild(parent: Span, operation: String, description: String) -> Span {\n        return parent.startChild(operation: operation, description: description)\n        \n    }\n    \n    static func finish(transaction: Span, error: Error? = nil) {\n        if let error {\n            SentrySDK.capture(error: error)\n            transaction.finish(status: .internalError)\n        } else {\n            transaction.finish()\n        }\n    }\n    \n    static func setTag(value: String, key: String) {\n        SentrySDK.configureScope { scope in\n            scope.setTag(value: value, key: key)\n        }\n    }\n}\n#else\n// Linux/Debug client - all operations are no-op\nclass SentryClient {\n    static func start(dsn: String, tracesSampleRate: NSNumber, username: String) { }\n    static func startTransaction(name: String, operation: String) -> Any? { return nil }\n    static func startChild(parent: Any?, operation: String, description: String) -> Any? { return nil }\n    static func finish(transaction: Any?, error: Error? = nil) { }\n    static func setTag(value: String, key: String) { }\n}\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Synchronized.swift",
    "content": "//\n//  Synchronized.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/10/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass Synchronized<T> {\n\n    var unsafeData: T {\n        return lock.lock {\n            innerData\n        }\n    }\n\n    private var innerData: T\n    private let lock = DispatchSemaphore.newLock()\n\n    init(data: T) {\n        self.innerData = data\n    }\n\n    func data(_ closure: (inout T) throws -> Void) rethrows {\n        try lock.lock {\n            try closure(&innerData)\n        }\n    }\n\n    func data<Out>(_ closure: (inout T) throws -> Out) rethrows -> Out {\n        return try lock.lock {\n            return try closure(&innerData)\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/TCPConnection.swift",
    "content": "//\n//  SocketConnection.swift\n//  BlueSocket\n//\n//  Created by Simon Corsin on 6/5/19.\n//\n\nimport Foundation\nimport BlueSocket\n\nenum TCPConnectionProcessDataResult {\n    case valid(dataLength: Int)\n    case invalid(dataToDiscard: Int)\n    case notEnoughData(lengthNeeded: Int)\n}\n\nprotocol TCPConnectionDataProcessor {\n    func process(data: Data) -> TCPConnectionProcessDataResult\n}\n\nprotocol TCPConnectionDelegate: AnyObject {\n    func connection(_ connection: TCPConnection, didReceiveData data: Data)\n    func connection(_ connection: TCPConnection, didDisconnectWithError error: Error?)\n}\n\nprotocol TCPConnection: AnyObject {\n    var delegate: TCPConnectionDelegate? { get set }\n    var dataProcessor: TCPConnectionDataProcessor? { get set }\n    var key: String { get }\n\n    func startListening()\n    func send(data: Data)\n    func close()\n}\n\nextension TCPConnection {\n    func processBuffer(_ buffer: inout Data) -> Int? {\n        guard let dataProcessor = self.dataProcessor else {\n            let data = buffer\n            buffer = Data()\n            delegate?.connection(self, didReceiveData: data)\n            return nil\n        }\n\n        while !buffer.isEmpty {\n            let result = dataProcessor.process(data: buffer)\n            switch result {\n            case .valid(let dataLength):\n                let outData: Data\n                if dataLength == buffer.count {\n                    outData = buffer\n                    buffer = Data()\n                } else {\n                    outData = buffer[0..<dataLength]\n                    buffer = Data(buffer.advanced(by: dataLength))\n                }\n\n                delegate?.connection(self, didReceiveData: outData)\n            case .invalid(let dataToDiscard):\n                buffer = buffer.advanced(by: dataToDiscard)\n            case let .notEnoughData(lengthNeeded):\n                return lengthNeeded\n            }\n        }\n        return nil\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/TCPTunnel.swift",
    "content": "//\n//  TCPTunnel.swift\n//  Compiler\n//\n//  Created by elee2 on 02/22/2024.\n//\n\nimport Foundation\nimport BlueSocket\n\nenum TCPTunnelError: Error {\n    case unimplemented\n}\n\nprotocol TCPTunnelManagerDelegate: AnyObject {\n    func tunnelConnectionCreated(_ tunnel: TCPTunnel, connection: TCPTunnelConnection, from: TCPConnection, to: TCPConnection)\n    func tunnelConnectionDisconnected(_ tunnel: TCPTunnel, connection: TCPTunnelConnection)\n    func tunnelConnectionError(_ tunnel: TCPTunnel, error: Error)\n}\n\nclass TCPTunnel {\n    let listeningPort: Int\n    weak var delegate: TCPTunnelManagerDelegate?\n\n    let logger: ILogger\n    private let listenSocket: Socket\n    private var startedAccepting: Bool = false\n    private var connections: [TCPTunnelConnection] = []\n\n    private let acceptQueue = DispatchQueue(label: \"TCPTunnel.acceptQueue\")\n    private let queue = DispatchQueue(label: \"TCPTunnel\")\n\n    init(logger: ILogger, port: Int) throws {\n        self.logger = logger\n        self.listenSocket = try Socket.create(family: .inet, type: .stream, proto: .tcp)\n        try self.listenSocket.listen(on: port)\n        self.listeningPort = Int(self.listenSocket.listeningPort)\n    }\n\n    func destinationConnectionProvider() throws -> Promise<TCPConnection> {\n        throw TCPTunnelError.unimplemented\n    }\n\n    func start () {\n        guard !startedAccepting else {\n            return\n        }\n        startedAccepting = true\n        runAcceptLoop()\n    }\n\n    func stop () {\n        queue.async { [weak self] in\n            guard let self = self else { return }\n            self.listenSocket.close()\n            for connection in self.connections {\n                connection.stop()\n            }\n            self.connections.removeAll()\n        }\n    }\n\n    private func runAcceptLoop() {\n        acceptQueue.async {\n            repeat {\n                do {\n                    let newSocket = try self.listenSocket.acceptClientConnection()\n                    let connectionA = BlueSocketTCPConnection(logger: self.logger, socket: newSocket, queueNamePrefix: \"TunnelServer\")\n                    try self.destinationConnectionProvider().onComplete { [weak self, connectionA] (result) in\n                        switch result {\n                        case .success(let connectionB):\n                            self?.connectTunnel(from: connectionA, to: connectionB)\n                        case .failure(let error):\n                            self?.logger.error(\"[TCPTunnel] Error completing tunnel connection: \\(error)\")\n                            connectionA.close()\n                            self?.delegate?.tunnelConnectionError(self!, error: error)\n                        }\n                    }\n                } catch {\n                    if let socketError = error as? Socket.Error {\n                        self.logger.debug(\"[TCPTunnel] Error while accepting: \\(socketError.description)\")\n                    } else {\n                        self.logger.error(\"[TCPTunnel] Unexpected error... \\(error)\")\n                        self.delegate?.tunnelConnectionError(self, error: error)\n                    }\n                }\n\n            } while self.listenSocket.isActive == true\n        }\n    }\n\n    private func connectTunnel (from: TCPConnection, to: TCPConnection) {\n        queue.async { [weak self] in\n            guard let self = self else { return }\n            let connection = TCPTunnelConnection(a: from, b: to)\n            connection.delegate = self\n            connection.start()\n            self.connections.append(connection)\n            self.delegate?.tunnelConnectionCreated(self, connection: connection, from: from, to: to)\n        }\n    }\n}\n\nextension TCPTunnel: TCPTunnelConnectionDelegate {\n    func disconnected(_ connection: TCPTunnelConnection) {\n        queue.async { [weak self] in\n            guard let self = self else { return }\n            self.connections.removeAll { $0 === connection }\n            self.delegate?.tunnelConnectionDisconnected(self, connection: connection)\n        }\n    }\n}\n\nclass LocalTCPTunnel : TCPTunnel {\n    let destinationPort: Int\n    init(logger: ILogger, listenPort: Int, destinationPort: Int) throws {\n        logger.info(\"Opening tunnel from localhost:\\(listenPort) -> localhost:\\(destinationPort)\")\n        self.destinationPort = destinationPort\n        try super.init(logger: logger, port: listenPort)\n    }\n\n    override func destinationConnectionProvider() throws -> Promise<TCPConnection> {\n        let socket = try Socket.create()\n        try socket.connect(to: \"localhost\", port: Int32(destinationPort))\n        let tcpConnection = BlueSocketTCPConnection(logger: logger, socket: socket, queueNamePrefix: \"LocalTCPTunnelDestinationConnection\")\n        return Promise(data: tcpConnection)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/TCPTunnelConnection.swift",
    "content": "//\n//  TCPTunnelConnection.swift\n//  Compiler\n//\n//  Created by elee2 on 02/22/2024.\n//\n\nimport Foundation\n\nstruct TCPTunnelEndpoint {\n    let tcpConnection: TCPConnection\n    var started: Bool = false\n}\nprotocol TCPTunnelConnectionDelegate: AnyObject {\n    func disconnected(_ tunnel: TCPTunnelConnection)\n}\n\nclass TCPTunnelConnection {\n    let key: String\n    private var endpoints: [TCPTunnelEndpoint] = []\n    private let queue = DispatchQueue(label: \"TCPTunnelConnection\")\n\n    weak var delegate: TCPTunnelConnectionDelegate?\n\n    init(a: TCPConnection, b: TCPConnection) {\n        self.key = a.key + \"<->\" + b.key\n        self.endpoints = [TCPTunnelEndpoint(tcpConnection: a), TCPTunnelEndpoint(tcpConnection: b)]\n    }\n\n    deinit {\n        for endpoint in self.endpoints{\n            endpoint.tcpConnection.close()\n        }\n    }\n\n    func start () {\n        for index in self.endpoints.indices {\n            self.endpoints[index].started = true\n            self.endpoints[index].tcpConnection.delegate = self\n            self.endpoints[index].tcpConnection.startListening()\n        }\n    }\n\n    func stop () {\n        queue.async { [weak self] in\n            guard let self = self else { return }\n            for endpoint in self.endpoints{\n                endpoint.tcpConnection.close()\n            }\n        }\n    }\n}\n\nextension TCPTunnelConnection: TCPConnectionDelegate {\n    func connection(_ connection: TCPConnection, didReceiveData data: Data) {\n        queue.async { [weak self] in\n            guard let self = self else { return }\n            let otherEndpoint = self.endpoints.first { $0.tcpConnection !== connection }\n            otherEndpoint?.tcpConnection.send(data: data)\n        }\n    }\n\n    func connection(_ connection: TCPConnection, didDisconnectWithError error: Error?) {\n        queue.async { [weak self] in\n            guard let self = self else { return }\n\n            guard let thisEndpointIndex = self.endpoints.firstIndex(where: { $0.tcpConnection === connection }),\n                let otherEndpointIndex = self.endpoints.firstIndex(where: { $0.tcpConnection !== connection}) else {\n                return\n            }\n\n            if self.endpoints[thisEndpointIndex].started {\n                self.endpoints[thisEndpointIndex].started = false\n                if self.endpoints[otherEndpointIndex].started {\n                    self.endpoints[otherEndpointIndex].tcpConnection.close()\n                    self.delegate?.disconnected(self)\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/Trie.swift",
    "content": "// Copyright © 2024 Snap, Inc. All rights reserved.\n\nstruct Trie<T> {\n    class Entry {\n        typealias Name = [String]\n        let name: Name\n        var value: T?\n        var children = [String: Entry]()\n\n        init(name: Name, value: T?) {\n            self.name = name\n            self.value = value\n        }\n    }\n\n    struct Result {\n        let nearestName: Entry.Name?\n        let nearestValue: T?\n        let found: Bool\n    }\n\n    private var root = Entry(name: [], value: nil)\n\n    func insert(name: Entry.Name, value: T) {\n        upsertEntry(entry: root, name: name, index: 0).value = value\n    }\n\n    func get(name: Entry.Name) -> Result {\n        return doGetEntry(name: name)\n    }\n\n    private func upsertEntry(entry: Entry, name: Entry.Name, index: Int) -> Entry {\n        guard index < name.count else {\n            return entry\n        }\n\n        let component = name[index]\n        var resolvedEntry = entry.children[component]\n        if resolvedEntry == nil {\n            resolvedEntry = Entry(name: Entry.Name(name[0...index]), value: nil)\n            entry.children[component] = resolvedEntry\n        }\n\n        return upsertEntry(entry: resolvedEntry!, name: name, index: index + 1)\n    }\n\n    private func doGetEntry(name: Entry.Name) -> Result {\n        var currentEntry = self.root\n        var bestEntry: Entry?\n\n        if currentEntry.value != nil {\n            bestEntry = currentEntry\n        }\n\n        for i in 0..<name.count {\n            let component = name[i]\n            guard let child = currentEntry.children[component] else {\n                return Result(nearestName: bestEntry?.name, nearestValue: bestEntry?.value, found: false)\n            }\n\n            currentEntry = child\n            if child.value != nil {\n                bestEntry = child\n            }\n        }\n\n        return Result(nearestName: bestEntry?.name, nearestValue: bestEntry?.value, found: bestEntry != nil)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/TypeScriptCommands+ParserDebug.swift",
    "content": "//\n//  TypeScriptCommands+Debug.swift\n//  Compiler\n//\n//  Created by saniul on 05/08/2019.\n//\n\nimport Foundation\n\nextension TS.SymbolDisplayPart: TextSequenceElement {}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/UnresolvedPath.swift",
    "content": "//\n//  File.swift\n//  \n//\n//  Created by Simon Corsin on 10/18/21.\n//\n\nimport Foundation\n\nstruct UnresolvedPath {\n    let baseURL: URL\n    let components: [String]\n    let variables: [String: String]\n\n    func appendingVariable(key: String, value: String) -> UnresolvedPath {\n        var outVariables = self.variables\n        outVariables[key] = value\n\n        return UnresolvedPath(baseURL: baseURL, components: components, variables: outVariables)\n    }\n\n    func resolve() throws -> URL {\n        var current = baseURL\n        for component in components {\n            let resolvedComponent = try component.resolvingVariables(variables)\n            current = current.resolving(path: resolvedComponent, isDirectory: true)\n        }\n\n        return current\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ValdiFileManager.swift",
    "content": "//\n//  ValdiFileManager.swift\n//\n//\n//  Created by Simon Corsin on 4/2/21.\n//\n\nimport Foundation\n\nclass ValdiFileManager {\n\n    struct SaveOptions: OptionSet {\n        let rawValue: Int\n\n        static let overwriteOnlyIfDifferent = SaveOptions(rawValue: 1 << 0)\n\n        static let defaultOptions: SaveOptions = []\n    }\n\n    private let lock = DispatchSemaphore.newLock()\n\n    private let bazel: Bool\n\n    private let trashDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory())\n        .appendingPathComponent(\"valdi-trash\", isDirectory: true)\n        .appendingPathComponent(UUID().uuidString, isDirectory: true)\n    private var directoryCheckCache = Set<String>()\n\n    init(bazel: Bool) throws {\n        self.bazel = bazel\n        if FileManager.default.fileExists(atPath: trashDirectoryURL.path) {\n            try FileManager.default.removeItem(at: trashDirectoryURL)\n        }\n        try doCreateDirectory(atAbsoluteURL: trashDirectoryURL)\n    }\n\n    func save(file: File, to url: URL, options: SaveOptions = .defaultOptions) throws {\n        switch file {\n        case .data(let data):\n            try save(data: data, to: url, options: options)\n        case .string(let str):\n            try save(data: try str.utf8Data(), to: url, options: options)\n        case .url(let fileUrl):\n            try save(fileUrl: fileUrl, to: url, options: options)\n        case .lazyData(let block):\n            let data = try block()\n            try save(data: data, to: url, options: options)\n        }\n    }\n\n    func createDirectory(at url: URL) throws {\n        try lock.lock {\n            try doCreateDirectory(atAbsoluteURL: resolve(url: url))\n        }\n    }\n\n    @discardableResult func delete(url: URL) throws -> Bool {\n        let absolutePath = resolve(url: url).path\n\n        do {\n            guard let urlToDelete = try moveItemToTrash(absolutePath: absolutePath) else {\n                return false\n            }\n            try FileManager.default.removeItem(at: urlToDelete)\n            return true\n        } catch let error {\n            throw CompilerError(\"Failed to delete item at \\(absolutePath): \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n    func save(data: Data, to url: URL, options: SaveOptions = .defaultOptions) throws {\n        try doSave(to: url, options: options, data: data)\n    }\n\n    func save(fileUrl: URL, to url: URL, options: SaveOptions = .defaultOptions) throws {\n        // This is less efficient than using FileManager.default.copyItem, but\n        // the copyItem method somehow triggers a change notification from watchman\n        // on the file that we want to copy. Reading the input file manually and copying\n        // it fixes it.\n        let data = try Data(contentsOf: fileUrl)\n        try doSave(to: url, options: options, data: data)\n    }\n\n    func makeTrashItemURL() -> URL {\n        return trashDirectoryURL.appendingPathComponent(UUID().uuidString)\n    }\n\n    private func moveItemToTrash(absolutePath: String) throws -> URL? {\n        return try lock.lock {\n            if !FileManager.default.fileExists(atPath: absolutePath) {\n                return nil\n            }\n\n            let temporaryFileURL = makeTrashItemURL()\n\n            do {\n                try FileManager.default.moveItem(atPath: absolutePath, toPath: temporaryFileURL.path)\n            } catch let error {\n                throw CompilerError(\"Failed to move item to trash directory: \\(error.legibleLocalizedDescription)\")\n            }\n\n            return temporaryFileURL\n        }\n    }\n\n    private func doCreateDirectory(atAbsoluteURL absoluteURL: URL) throws {\n        let directoryPath = absoluteURL.path\n\n        if !FileManager.default.fileExists(atPath: directoryPath) {\n            do {\n                if bazel {\n                    directoryCheckCache.insert(directoryPath)\n                }\n                try FileManager.default.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)\n            } catch let error {\n                throw CompilerError(\"Failed to create directory at \\(directoryPath): \\(error.legibleLocalizedDescription)\")\n            }\n        } else if bazel && !directoryCheckCache.contains(directoryPath) {\n            directoryCheckCache.insert(directoryPath)\n\n            if !FileManager.default.isWritableFile(atPath: directoryPath) {\n                let attributes = try FileManager.default.attributesOfItem(atPath: directoryPath)\n\n                let mode = (attributes[.posixPermissions] as? NSNumber)?.uint16Value ?? 0\n                let newMode = mode | 0o200\n                try FileManager.default.setAttributes([.posixPermissions: NSNumber(value: newMode)], ofItemAtPath: directoryPath)\n            }\n        }\n    }\n\n    private func resolve(url: URL) -> URL {\n        return url.absoluteURL.standardized\n    }\n\n    private func doSave(to url: URL, options: SaveOptions, data: Data) throws {\n        guard url.isFileURL else {\n            throw CompilerError(\"Only fileURL's are supported within the ValdiFileManager\")\n        }\n        let absoluteURL = resolve(url: url)\n        let absolutePath = absoluteURL.path\n\n        do {\n            let directoryURL = absoluteURL.deletingLastPathComponent()\n            try createDirectory(at: directoryURL)\n            \n            if options.contains(.overwriteOnlyIfDifferent) && FileManager.default.fileExists(atPath: absolutePath) {\n                \n                do {\n                    let existingData = try Data(contentsOf: absoluteURL)\n                    if existingData == data {\n                        return\n                    }\n                } catch {\n                    throw CompilerError(\"Failed to read existing file: \\(error.legibleLocalizedDescription)\")\n                }\n\n                do {\n                    try FileManager.default.removeItem(atPath: absolutePath)\n                } catch {\n                    throw CompilerError(\"Failed to remove existing file: \\(error.legibleLocalizedDescription)\")\n                }\n            }\n            \n            try data.write(to: absoluteURL, options: [Data.WritingOptions.atomic])\n        } catch {\n            throw CompilerError(\"Failed to save file at '\\(absoluteURL.path)': \\(error.legibleLocalizedDescription)\")\n        }\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ValdiModuleBuilder.swift",
    "content": "//\n//  ValdiModuleBuilder.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 3/8/19.\n//\n\nimport Foundation\n\nprivate struct LengthField {\n    let raw: UInt32\n    \n    func size() -> Int {\n        return Int(raw & (Data.valdiLengthFieldPaddingBit - 1))\n    }\n    \n    func hasPadding() -> Bool {\n        return (raw & Data.valdiLengthFieldPaddingBit) != 0\n    }\n}\n\nextension Parser where T == Data {\n\n    func parseInt() throws -> UInt32 {\n        let data = try subsequence(length: 4)\n\n        return data.withUnsafePointer { bufferStart in\n            return bufferStart.pointee\n        }\n    }\n\n    func parseValdiData() throws -> Data {\n        let length = LengthField(raw: try parseInt())\n        let data = try subsequence(length: length.size())\n        if length.hasPadding() {\n            let padding = Int(Data.computePadding(size: UInt32(length.size())))\n            try advance(distance: padding)\n        }\n        \n        return data\n    }\n}\n\nclass ValdiModuleBuilder {\n\n    private let items: [ZippableItem]\n    var compress = true\n\n    init(items: [ZippableItem]) {\n        self.items = items\n    }\n\n    private func pack() throws -> Data {\n        var out = Data()\n\n        let sortedItems = items.sorted { (left, right) -> Bool in\n            return left.path > right.path\n        }\n\n        for item in sortedItems {\n            guard !item.path.hasPrefix(\"../\") else {\n                throw CompilerError(\"Invalid path for entry '\\(item.path)'\")\n            }\n\n            let filename = try item.path.utf8Data()\n            let fileData = try item.file.readData()\n\n            out.append(valdiData: filename, padding: true)\n            out.append(valdiData: fileData, padding: true)\n        }\n\n        return out\n    }\n\n    func build() throws -> Data {\n        let packetData = try pack()\n\n        var packed = Data()\n        packed.append(Magic.valdiMagic)\n        packed.append(valdiData: packetData, padding: false)\n\n        if self.compress {\n            return try ValdiModuleBuilder.compress(data: packed)\n        } else {\n            return packed\n        }\n    }\n\n    static func compress(data: Data) throws -> Data {\n        return try ZstdCompressor.compress(data: data)\n    }\n\n    static func unpack(module: Data) throws -> [ZippableItem] {\n        let moduleData = ZstdCompressor.isZstdCompressed(data: module) ? try ZstdCompressor.decompress(data: module) : module\n\n        let parser = Parser(sequence: moduleData)\n\n        guard try parser.parse(subsequence: Magic.valdiMagic) else {\n            throw CompilerError(\"Did not find valdi magic in module\")\n        }\n\n        let dataLength = try parser.parseInt()\n        if moduleData.count != dataLength + 8 {\n            throw CompilerError(\"Unexpected module length \\(moduleData.count - 4), expected \\(dataLength)\")\n        }\n\n        var out = [ZippableItem]()\n\n        while !parser.isAtEnd {\n            let filenameData = try parser.parseValdiData()\n            let fileData = try parser.parseValdiData()\n\n            guard let filename = String(data: filenameData, encoding: .utf8) else {\n                throw CompilerError(\"Could not extract file name\")\n            }\n            out.append(ZippableItem(file: .data(fileData), path: filename))\n        }\n\n        return out\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ValdiModuleUtils.swift",
    "content": "//\n//  ValdiModuleUtils.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 8/12/19.\n//\n\nimport Foundation\nimport SwiftProtobuf\n\nclass ValdiModuleUtils {\n\n    static func buildModule(logger: ILogger, fileManager: ValdiFileManager, paths: [String], baseUrl: URL, out: String?) throws {\n        let outputURL = try CLIUtils.getOutputURLs(commandName: \"--build-module\", baseUrl: baseUrl, out: out)\n\n        let zippableItems: [ZippableItem] = paths.map {\n            ZippableItem(file: .url(baseUrl.resolving(path: $0)), path: $0)\n        }\n\n        logger.info(\"Saving Valdi module...\")\n\n        let moduleData = try ValdiModuleBuilder(items: zippableItems).build()\n\n        logger.info(\"Writing Valdi module to \\(outputURL.path)\")\n        try fileManager.save(data: moduleData, to: outputURL)\n    }\n\n    static func unpackModule(logger: ILogger, fileManager: ValdiFileManager, paths: [String], baseUrl: URL, out: String?) throws {\n        let outputURL = try CLIUtils.getOutputURLs(commandName: \"--unpack-module\", baseUrl: baseUrl, out: out)\n\n        logger.info(\"Unpacking Valdi module...\")\n\n        for path in paths {\n            let url = baseUrl.resolving(path: path)\n            try unpackModule(logger: logger, fileManager: fileManager, url: url, outputURL: outputURL)\n        }\n    }\n\n    static func textconvModule(logger: ILogger, fileManager: ValdiFileManager, paths: [String], baseUrl: URL, out: String?) throws {\n        let outputURL = try CLIUtils.getOutputURLs(commandName: \"--textconv-module\", baseUrl: baseUrl, out: out)\n\n        logger.info(\"Textconverting Valdi module...\")\n\n        for path in paths {\n            let url = baseUrl.resolving(path: path)\n            try unpackModule(logger: logger, fileManager: fileManager, url: url, outputURL: outputURL, transform: textconvItem)\n        }\n    }\n\n    private static func unpackModule(logger: ILogger, fileManager: ValdiFileManager, url: URL, outputURL: URL, transform: ((ZippableItem) throws -> ZippableItem) = { $0 }) throws {\n        let moduleData = try Data(contentsOf: url)\n        let items = try ValdiModuleBuilder.unpack(module: moduleData)\n        let transformedItems = try items.map(transform)\n        for item in transformedItems {\n            let outputFileURL = outputURL.appendingPathComponent(item.path)\n            logger.info(\"Saving \\(outputFileURL.path)\")\n            try fileManager.save(file: item.file, to: outputFileURL)\n        }\n    }\n\n    private static func textconvItem(item: ZippableItem) throws -> ZippableItem {\n        let filename = item.path\n        let fileData = try item.file.readData()\n\n        let protobufMessage: Message?\n        if filename.hasSuffix(Files.downloadManifest) {\n            protobufMessage = try Valdi_DownloadableModuleManifest(serializedData: fileData)\n        } else if filename.hasSuffix(FileExtensions.valdiCss) {\n            protobufMessage = try Valdi_StyleNode(serializedData: fileData)\n        } else {\n            protobufMessage = nil\n        }\n\n        let dataToUse: Data\n        if let foundMessage = protobufMessage {\n            var options = TextFormatEncodingOptions()\n            options.printUnknownFields = true\n            let stringToUse = foundMessage.textFormatString(options: options)\n            dataToUse = stringToUse.data(using: .utf8) ?? Data()\n        } else if filename.hasSuffix(FileExtensions.assetCatalog) {\n            let records = try parseBinaryAssetCatalog(fileData: fileData)\n            let lines = records.map { \"- \\($0.fileName): \\($0.width)x\\($0.height)\" }\n            dataToUse = lines.joined(separator: \"\\n\").data(using: .utf8) ?? Data()\n        } else {\n            dataToUse = fileData\n        }\n\n        return ZippableItem(file: .data(dataToUse), path: filename)\n    }\n\n    private struct BinaryAssetCatalogRecord {\n        let width: UInt32\n        let height: UInt32\n        let fileName: String\n    }\n\n    private static func parseBinaryAssetCatalog(fileData: Data) throws -> [BinaryAssetCatalogRecord] {\n        let assetCatalogParser = Parser(sequence: fileData)\n        guard try assetCatalogParser.parse(subsequence: Magic.valdiMagic) else {\n            throw CompilerError(\"Did not find valdi magic in asset catalog data\")\n        }\n\n        let assetCatalogDataLength = try assetCatalogParser.parseInt()\n        if fileData.count != assetCatalogDataLength + 8 {\n            throw CompilerError(\"Unexpected asset catalog data length \\(fileData.count), expected \\(assetCatalogDataLength)\")\n        }\n        var records: [BinaryAssetCatalogRecord] = []\n        while !assetCatalogParser.isAtEnd {\n            let assetFileName = String(data: try assetCatalogParser.parseValdiData(), encoding: .utf8) ?? \"<invalid>\"\n\n            let widthHeightData = try assetCatalogParser.parseValdiData()\n\n            let widthData = widthHeightData[widthHeightData.startIndex..<widthHeightData.startIndex+4]\n            let heightData = widthHeightData[widthHeightData.startIndex+4..<widthHeightData.startIndex+8]\n            let width = UInt32(data: widthData) ?? 0\n            let height = UInt32(data: heightData) ?? 0\n            let record = BinaryAssetCatalogRecord(width: width,\n                                                  height: height,\n                                                  fileName: assetFileName)\n            records.append(record)\n        }\n        return records\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/Utils/ZstdCompressor.swift",
    "content": "//\n//  ZstdCompressor.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 3/8/19.\n//\n\nimport Foundation\nimport Zstd\n\nclass ZstdCompressor {\n\n    private static let compressionLevel: Int32 = 19\n\n    class func compress(data: Data) throws -> Data {\n        guard let stream = ZSTD_createCStream() else {\n            throw CompilerError(\"Failed to create compression stream\")\n        }\n        defer {\n            ZSTD_freeCStream(stream)\n        }\n\n        let initResult = ZSTD_initCStream(stream, ZstdCompressor.compressionLevel)\n        guard ZSTD_isError(initResult) == 0 else {\n            throw CompilerError(\"zstd: \\(String(cString: ZSTD_getErrorName(initResult)))\")\n        }\n\n        var output = Data()\n\n        try data.withUnsafePointer { (inputBytes: UnsafePointer<UInt8>) in\n            var buffer = Data()\n            let bufferLength = ZSTD_CStreamOutSize()\n            buffer.reserveCapacity(bufferLength)\n            for _ in 0..<bufferLength {\n                buffer.append(0)\n            }\n\n            var inBuffer = ZSTD_inBuffer()\n            inBuffer.pos = 0\n            inBuffer.src = UnsafeRawPointer(inputBytes)\n            inBuffer.size = data.count\n\n            while inBuffer.pos < inBuffer.size {\n                let written: Int = try buffer.withUnsafeMutablePointer { (bufferBytes: UnsafeMutablePointer<UInt8>) in\n                    var outBuffer = ZSTD_outBuffer()\n                    outBuffer.pos = 0\n                    outBuffer.dst = UnsafeMutableRawPointer(bufferBytes)\n                    outBuffer.size = bufferLength\n\n                    let result = ZSTD_compressStream(stream, &outBuffer, &inBuffer)\n                    guard ZSTD_isError(result) == 0 else {\n                        throw CompilerError(\"zstd: \\(String(cString: ZSTD_getErrorName(result)))\")\n                    }\n\n                    return outBuffer.pos\n                }\n\n                output.append(buffer[0..<written])\n            }\n\n            let written: Int = try buffer.withUnsafeMutablePointer { (bufferBytes: UnsafeMutablePointer<UInt8>) in\n                var outBuffer = ZSTD_outBuffer()\n                outBuffer.pos = 0\n                outBuffer.dst = UnsafeMutableRawPointer(bufferBytes)\n                outBuffer.size = bufferLength\n\n                let remainingToFlush = ZSTD_endStream(stream, &outBuffer)\n                guard remainingToFlush == 0 else {\n                    throw CompilerError(\"zstd did return data to flush\")\n                }\n\n                return outBuffer.pos\n            }\n\n            output.append(buffer[0..<written])\n        }\n\n        return output\n    }\n\n    class func decompress(data: Data) throws -> Data {\n        guard let dstream = ZSTD_createDStream() else {\n            throw CompilerError(\"Failed to create decompression stream\")\n        }\n        defer {\n            ZSTD_freeDStream(dstream)\n        }\n\n        let bufferSize = ZSTD_DStreamOutSize()\n\n        var buffer = Data()\n        buffer.reserveCapacity(bufferSize)\n\n        /* In more complex scenarios, a file may consist of multiple appended frames (ex : pzstd).\n         *  The following example decompresses only the first frame.\n         *  It is compatible with other provided streaming examples */\n        let initResult = ZSTD_initDStream(dstream)\n        guard ZSTD_isError(initResult)  == 0 else {\n            throw CompilerError(\"zstd: \\(String(cString: ZSTD_getErrorName(initResult)))\")\n        }\n\n        var output = Data()\n        output.reserveCapacity(data.count * 4)\n\n        try buffer.withUnsafeMutablePointer { (bufferBytes: UnsafeMutablePointer<UInt8>) in\n            try data.withUnsafePointer { (inputBytes: UnsafePointer<UInt8>) in\n                var inBuffer = ZSTD_inBuffer()\n                inBuffer.src = UnsafeRawPointer(inputBytes)\n                inBuffer.size = data.count\n                inBuffer.pos = 0\n\n                var outBuffer = ZSTD_outBuffer()\n                outBuffer.dst = UnsafeMutableRawPointer(bufferBytes)\n                outBuffer.pos = 0\n                outBuffer.size = bufferSize\n\n                while inBuffer.pos < data.count {\n                    let result = ZSTD_decompressStream(dstream, &outBuffer, &inBuffer)\n                    guard ZSTD_isError(result) == 0 else {\n                        throw CompilerError(\"zstd: \\(String(cString: ZSTD_getErrorName(result)))\")\n                    }\n\n                    let written = outBuffer.pos\n\n                    output.append(bufferBytes, count: written)\n                    outBuffer.pos = 0\n                }\n            }\n        }\n\n        return output\n    }\n    \n    class func isZstdCompressed(data: Data) -> Bool {\n        guard data.count >= MemoryLayout<UInt32>.size else {\n            return false\n        }\n\n        let magic = data.withUnsafeBytes { rawBytes in\n            rawBytes.load(as: UInt32.self)\n        }\n        \n        return magic == ZSTD_MAGICNUMBER\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ValdiCompiler.swift",
    "content": "//\n//  ValdiCompiler.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/6/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport Yams\n\nfinal class ValdiCompiler {\n\n    private struct NewFileData {\n        let bundleInfo: CompilationItem.BundleInfo?\n        let relativeProjectPath: String?\n        let content: String?\n    }\n\n    private let logger: ILogger\n    private let pipeline: CompilationPipeline\n    private let projectConfig: ValdiProjectConfig\n\n    private var newFiles = [URL: NewFileData]()\n\n    private let bundleManager: BundleManager\n    private var currentSequence = 0\n\n    init(logger: ILogger, pipeline: CompilationPipeline, projectConfig: ValdiProjectConfig, bundleManager: BundleManager) {\n        self.logger = logger\n        self.pipeline = pipeline\n        self.projectConfig = projectConfig\n        self.bundleManager = bundleManager\n    }\n\n    func addFiles(fromInputList inputList: CompilerFileInputList, baseUrl: URL) throws {\n        for entry in inputList.entries {\n            let bundleInfo = try bundleManager.getBundleInfo(forName: entry.moduleName)\n            for file in entry.files {\n                let fileURL = baseUrl.resolving(path: file.file).standardizedFileURL.absoluteURL\n                addFile(file: fileURL, bundleInfo: bundleInfo, relativeProjectPath: file.relativeProjectPath, content: file.content)\n            }\n\n            if let autoDiscover = entry.autoDiscover, autoDiscover {\n                let finder = ValdiFilesFinder(url: baseUrl.resolving(path: entry.modulePath))\n\n                for fileURL in try finder.allFiles() {\n                    addFile(file: try fileURL.resolvingSymlink(), bundleInfo: bundleInfo)\n                }\n            }\n        }\n    }\n\n    func addFile(file: URL, bundleInfo: CompilationItem.BundleInfo? = nil, relativeProjectPath: String? = nil, content: String? = nil) {\n        addFile(file: file, newFileData: NewFileData(bundleInfo: bundleInfo, relativeProjectPath: relativeProjectPath, content: content))\n    }\n\n    private func addFile(file: URL, newFileData: NewFileData) {\n        newFiles[file] = newFileData\n    }\n\n    func compile() throws {\n        self.currentSequence += 1\n        let compileSequence = CompilationSequence(id: currentSequence)\n\n        var newFileDataBySourceURL = [URL: NewFileData]()\n        let allFiles = try newFiles.map { (sourceURL: URL, newFileData: NewFileData) -> CompilationItem in\n            let resolvedBundleInfo = try (newFileData.bundleInfo ?? bundleManager.getBundleInfo(fileURL: sourceURL))\n            let file: File\n            if let content = newFileData.content {\n                file = .string(content)\n            } else {\n                file = .url(sourceURL)\n            }\n            newFileDataBySourceURL[sourceURL] = newFileData\n\n            return CompilationItem(sourceURL: sourceURL, relativeProjectPath: newFileData.relativeProjectPath, kind: .unknown(file), bundleInfo: resolvedBundleInfo, platform: nil, outputTarget: .all)\n        }\n        newFiles.removeAll()\n\n        let result = try pipeline.process(items: CompilationItems(compileSequence: compileSequence, items: allFiles))\n\n        if !result.warnings.isEmpty {\n            logger.error(\"Warnings reported:\")\n            result.warnings.forEach {\n                logger.error(\"-- \\($0.tag): \\($0.message)\")\n            }\n        }\n\n        if !result.failedItems.isEmpty {\n            logger.error(\"Errors reported:\")\n\n            // Re-add the failed files into the newFiles\n            for (sourceURL, failedItem) in result.failedItems {\n                // Don't include the emitted files from the process\n                guard let newFileData = newFileDataBySourceURL[sourceURL] else { continue }\n\n                addFile(file: sourceURL, newFileData: newFileData)\n\n                if let errorDescription = failedItem.error?.legibleLocalizedDescription {\n                    logger.error(\"-- \\(failedItem.relativeProjectPath): \\(errorDescription)\")\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ValdiCompilerArguments.swift",
    "content": "//\n//  ValdiCompilerArguments.swift\n//\n//  Created by Simon Corsin on 4/16/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport ArgumentParser\n\nstruct ValdiCompilerArguments: ParsableCommand {\n    @Option(help: \"provide Valdi configuration file\")\n    var config: String?\n\n    @Flag(help: \"enter watch mode with active hot reloader\")\n    var monitor = false\n\n    @Flag(help: \"Generate static resources file from a list of input files\")\n    var genStaticRes = false\n\n    @Option(help: \"list of input files to use for the requested command\")\n    var input: [String] = []\n\n    @Option(help: \"list of devices that should be auto-reloaded\")\n    var deviceId: [String] = []\n\n    @Option(help: \"list of usernames that should be auto-reloaded\")\n    var username: [String] = []\n\n    @Option(help: \"list of IP address that should be auto-reloaded\")\n    var ip: [String] = []\n\n    @Flag(help: \"connect to the device over usb/localhost instead of the local network\")\n    var usb = false\n\n    @Option(help: \"output directory\")\n    var out: String?\n\n    // TODO(vfomin): replace with enumerable to limit options to the actual log level\n    @Option(help: \"set the log level\")\n    var logLevel: String?\n\n    // TODO(vfomin): right now it dumps info about all components, even if the list below is limited\n    @Option(help: \"dump components information in the JSON format\")\n    var dumpComponents: [String] = []\n\n    @Option(help: \"pack selected files into .valdimodule archive\")\n    var buildModule: [String] = []\n\n    @Option(help: \"unpack selected modules\")\n    var unpackModule: [String] = []\n\n    @Option(help: \"textconv selected modules\")\n    var textconvModule: [String] = []\n\n    @Option(help: \"upload selected modules\")\n    var uploadModule: [String] = []\n\n    @Option(help: \"the base URL to upload downloadable artifacts\")\n    var uploadBaseUrl: String?\n\n    @Option(help: \"module name\")\n    var module: [String] = []\n\n    @Option(help: \"The path to the build directory. Will be inferred from the config directory if not set\")\n    var buildDir: String?\n\n    @Option(help: \"The path where to store the prepared artifact meant to be uploaded\")\n    var preparedUploadArtifactOutput: String?\n\n    @Option(help: \"override a config value\")\n    var configValue: [String] = []\n\n    @Option(help: \"the maximum number of concurrent requests to process module uploads\")\n    var maxUploadConcurrentRequests: Int = 4\n\n    @Option(help: \"Whether to compile for debug, release, or both\", transform: {\n        if $0 == \"debug\" {\n            return OutputTarget.debug\n        } else if $0 == \"release\" {\n            return OutputTarget.release\n        } else if $0 == \"all\" {\n            return OutputTarget.all\n        } else {\n            throw ValidationError(\"Unsupported output target '\\($0)', must be one of 'debug', 'release' or 'all'\")\n        }\n    })\n    var outputTarget: OutputTarget?\n\n    @Option\n    var outputDumpedSymbolsDir: String?\n\n    @Option\n    var onlyCompileTsForModule: [String] = []\n\n    @Option\n    var onlyGenerateNativeCodeForModule: [String] = []\n\n    @Option\n    var onlyProcessResourcesForModule: [String] = []\n\n    @Option\n    var onlyFocusProcessingForModule: [String] = []\n\n    @Flag(help: \"Dump modules information in JSON format to use for the Valdi module attribution in C++. See generate_attribution.py for more details\")\n    var dumpModulesInfo = false\n\n    @Flag(help: \"start compilation\")\n    var compile = false\n\n    @Flag(help: \"generate iOS output\")\n    var ios = false\n\n    @Flag(help: \"generate android output\")\n    var android = false\n\n    @Flag(help: \"Experimental: generate web output\")\n    var web = false\n\n    @Flag(help: \"generate C++ output\")\n    var cpp = false\n\n    @Flag\n    var disableDiskCache = false\n\n    @Flag\n    var emitDiagnostics = false\n\n    @Flag(help: \"run the code generator only\")\n    var codegenOnly = false\n\n    @Flag(help: \"generate module's code coverage\")\n    var codeCoverage = false\n\n    @Flag\n    var forceMinify = false\n\n    @Flag(help: \"disable minification + obfuscation for web\")\n    var disableMinifyWeb = false\n\n    @Flag(help: \"disable compiler's concurrency. useful for debugging\")\n    var disableConcurrency = false\n\n    @Flag\n    var ignoreModuleDeps = false\n\n    @Flag(help: \"start companion app with --inspect option to be able to debug\")\n    var debugCompanion = false\n\n    @Flag(help: \"disable debugging proxy\")\n    var noDebuggingProxy = false\n\n    @Flag(help: \"disable TS compiler cache\")\n    var disableTsCompilerCache = false\n\n    @Flag\n    var skipRemoveOrphanFiles = false\n\n    @Flag(help: \"set 'declaration: true' in the tconfig.json\")\n    var tsEmitDeclarationFiles = false\n\n    @Flag(help: \"set 'removeComments: false' in the tconfig.json\")\n    var tsKeepComments = false\n\n    @Flag\n    var tsSkipVerifyingImports = false\n\n    @Flag\n    var disableDownloadableModules = false\n\n    @Flag\n    var inlineTranslations = false\n\n    @Flag(help: \"Whether assets should be packed inline within the .valdimodule\")\n    var inlineAssets = false\n\n    @Flag\n    var duplicateStderrToStdout = false\n\n    @Option(help: \"path to the companion app\")\n    var directCompanionPath: String?\n\n    @Option(help: \"path to the compiler toolbox app\")\n    var directCompilerToolboxPath: String?\n\n    @Option(help: \"path to the pngquant app\")\n    var directPngquantPath: String?\n\n    @Option(help: \"path to the minify config\")\n    var directMinifyConfigPath: String?\n\n    @Option(help: \"path to the clientsql app\")\n    var directClientSqlPath: String?\n\n    @Option(help: \"path to the file with the list of input files\")\n    var explicitInputListFile: String?\n\n    @Option(help: \"Path to where to store the compiler companion logs\")\n    var companionLogOutput: String?\n\n    @Option(help: \"The list of image variants to include for each platform\")\n    var imageVariantsFilter: String?\n\n    @Option(help: \"Sentry DSN for error tracking\")\n    var sentryDsn: String?\n\n    @Flag(help: \"regenerate per module BUILD.bazel build files\")\n    var regenerateValdiModulesBuildFiles = false\n\n    @Flag(help: \"verify artifact files with uploaded signatures\")\n    var verifyDownloadableArtifacts = false\n\n    @Flag(help: \"generate TS files from strings and resources\")\n    var generateTSResFiles = false\n\n    @Flag(help: \"indicates whether the compiler was invoked from Bazel. Used while we're migrated to Bazel based builds to track usage\")\n    var bazel = false\n\n    @Option(help: \"specifies in seconds, how long each compiler task is allowed to wait until completion. Defaults to \\(LockConfig.waitTimeoutSeconds) seconds\")\n    var taskTimeout: Int?\n\n    @Option(help: \"specifies in seconds, how long the compiler can run before being automatically killed\")\n    var timeout: Int?\n\n    var parsedLogLevel: LogLevel? = nil\n\n    var parsedImageVariantsFilter: ImageVariantsFilter? = nil\n\n    mutating func validate() throws {\n        let selectedCount = [self.compile, self.monitor, !self.buildModule.isEmpty, !self.unpackModule.isEmpty, !self.textconvModule.isEmpty, !self.uploadModule.isEmpty, self.dumpModulesInfo, self.genStaticRes].filter{$0}.count\n        guard selectedCount == 1 else {\n            throw ValidationError(\"Must provide only one of: --compile OR --monitor OR --build-module OR --unpack-module OR --textconv-module OR --upload-module OR --dump-modules-info\")\n        }\n        \n        let requiresOutput = [!self.buildModule.isEmpty, !self.unpackModule.isEmpty, !self.textconvModule.isEmpty, !self.uploadModule.isEmpty, self.dumpModulesInfo, self.genStaticRes].filter{$0}.count > 0\n        if requiresOutput && self.out == nil {\n            throw ValidationError(\"Must provide --out\")\n        }\n        \n        if !self.uploadModule.isEmpty && self.uploadBaseUrl == nil {\n            throw ValidationError(\"Must provide --upload-base-url for --upload-module\")\n        }\n                \n        if let logLevel = self.logLevel {\n            guard let parsedLevel = LogLevel(description: logLevel.uppercased()) else {\n                throw ValidationError(\"Unrecognized log level. Supported values are: \\(LogLevel.allCases.map { $0.description })\")\n            }\n            self.parsedLogLevel = parsedLevel\n        }\n\n        if let imageVariantsFilter {\n            do {\n                self.parsedImageVariantsFilter = try ImageVariantsFilter.parse(str: imageVariantsFilter)\n            } catch let error {\n                throw ValidationError(\"Failed to parse --image-variants-filter: \\(error.legibleLocalizedDescription)\")\n            }\n        }\n    }\n\n    private func doRun() -> Bool {\n        let logger = Logger(output: FileHandleLoggerOutput(stdout: FileHandle.standardOutput, stderr: FileHandle.standardError))\n        let companionExecutableProvider = CompanionExecutableProvider(logger: logger)\n        defer {\n            // Ensure logs are flushed even when logs are displayed asynchronously\n            logger.flush()\n        }\n\n        return ValdiCompilerRunner(logger: logger,\n                                      arguments: self,\n                                      companionExecutableProvider: companionExecutableProvider,\n                                      workingDirectoryPath: FileManager.default.currentDirectoryPath,\n                                      runningAsWorker: false).run()\n    }\n\n    mutating func run() throws {\n        let success = doRun()\n\n#if os(Linux)\n        // HACK(simon): Exit process immediately on linux after finishing compiling.\n        // This is a workaround of a Swift runtime bug on Linux where the process was\n        // segfaulting during cleanup.\n        _exit(success ? 0 : 1)\n#else\n        guard success else {\n            throw ExitCode.failure\n        }\n#endif\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ValdiCompilerRunner.swift",
    "content": "//\n//  ValdiCompilerRunner.swift\n//\n//\n//  Created by Simon Corsin on 12/16/20.\n//\n\nimport Foundation\n\nstruct ValdiPipelineBuilder {\n\n    var preprocessors: [CompilationProcessor] = []\n    var processors: [CompilationProcessor] = []\n    var postprocessors: [CompilationProcessor] = []\n\n    private let logger: ILogger\n\n    init(logger: ILogger) {\n        self.logger = logger\n    }\n\n    mutating func append(preprocessor: CompilationProcessor) {\n        preprocessors.append(preprocessor)\n        onAppend(preprocessor)\n    }\n\n    mutating func append(processor: CompilationProcessor) {\n        processors.append(processor)\n        onAppend(processor)\n    }\n\n    mutating func append(postprocessor: CompilationProcessor) {\n        postprocessors.append(postprocessor)\n        onAppend(postprocessor)\n    }\n\n    func build() -> [CompilationProcessor] {\n        return preprocessors + processors + postprocessors\n    }\n\n    private func onAppend(_ processor: CompilationProcessor) {\n        logger.trace(\"Appending pipeline processor '\\(processor.description)'\")\n    }\n\n}\n\nclass ValdiCompilerRunner {\n\n    private let logger: ILogger\n    private let arguments: ValdiCompilerArguments\n    private let deferredWarningCollector: DeferredWarningCollector\n    private let errorDumper: CompilationPipelineErrorDumper\n    private let companionExecutableProvider: CompanionExecutableProvider\n    private let workingDirectoryPath: String\n    private let runningAsWorker: Bool\n\n    init(logger: ILogger, \n         arguments: ValdiCompilerArguments,\n         companionExecutableProvider: CompanionExecutableProvider,\n         workingDirectoryPath: String,\n         runningAsWorker: Bool) {\n        self.logger = logger\n        self.arguments = arguments\n        self.deferredWarningCollector = DeferredWarningCollector(logger: logger)\n        self.errorDumper = CompilationPipelineErrorDumper(deferredWarningCollector: self.deferredWarningCollector)\n        self.companionExecutableProvider = companionExecutableProvider\n        self.workingDirectoryPath = workingDirectoryPath\n        self.runningAsWorker = runningAsWorker\n    }\n\n    func run() -> Bool {\n        if let parsedLogLevel = arguments.parsedLogLevel {\n            logger.minLevel = parsedLogLevel\n        }\n\n        var killOnTimeout: KillOnTimeout?\n\n        if !runningAsWorker {\n            Concurrency.enableConcurrency = !self.arguments.disableConcurrency\n\n            if let taskTimeout = self.arguments.taskTimeout {\n                LockConfig.waitTimeoutSeconds = TimeInterval(taskTimeout)\n            }\n            if let timeout = arguments.timeout {\n                killOnTimeout = KillOnTimeout(logger: logger, timeoutSeconds: TimeInterval(timeout))\n                killOnTimeout?.start()\n            }\n        }\n\n        defer {\n            killOnTimeout?.stop()\n        }\n\n        do {\n            logger.duplicateStderrToStdout = self.arguments.duplicateStderrToStdout\n\n            let baseUrl = URL(fileURLWithPath: self.workingDirectoryPath).standardizedFileURL\n            let fileManager = try ValdiFileManager(bazel: self.arguments.bazel)\n\n            if !self.arguments.buildModule.isEmpty {\n                try ValdiModuleUtils.buildModule(logger: logger, fileManager: fileManager, paths: self.arguments.buildModule, baseUrl: baseUrl, out: self.arguments.out)\n                return true\n            } else if !self.arguments.unpackModule.isEmpty {\n                try ValdiModuleUtils.unpackModule(logger: logger, fileManager: fileManager, paths: self.arguments.unpackModule, baseUrl: baseUrl, out: self.arguments.out)\n                return true\n            } else if !self.arguments.textconvModule.isEmpty {\n                try ValdiModuleUtils.textconvModule(logger: logger, fileManager: fileManager, paths: self.arguments.textconvModule, baseUrl: baseUrl, out: self.arguments.out)\n                return true\n            } else if !self.arguments.uploadModule.isEmpty {\n                let configs = try ResolvedConfigs.from(logger: logger, baseURL: baseUrl, userConfigURL: URL.valdiUserConfigURL, args: self.arguments)\n                let diskCacheProvider = DiskCacheProvider(logger: logger, fileManager: fileManager, projectConfig: configs.projectConfig, disableDiskCache: configs.compilerConfig.disableDiskCache)\n                let compilerCompanion = try getCompanionExecutable(configs: configs, diskCacheProvider: diskCacheProvider)\n\n                try ArtifactUploader.uploadFiles(fileManager: fileManager,\n                                                 paths: self.arguments.uploadModule,\n                                                 baseURL: baseUrl,\n                                                 out: self.arguments.out,\n                                                 moduleBaseUploadURL: self.arguments.uploadBaseUrl.flatMap(URL.init(string:)),\n                                                 companionExectuable: compilerCompanion)\n                return true\n            } else if self.arguments.dumpModulesInfo {\n                let configs = try ResolvedConfigs.from(logger: logger, baseURL: baseUrl, userConfigURL: URL.valdiUserConfigURL, args: self.arguments)\n                try DumpModulesInfo.dump(fileManager: fileManager, configs: configs, to: self.arguments.out!)\n                return true\n            } else if self.arguments.genStaticRes {\n                try StaticResGenerator.generate(baseUrl: baseUrl, inputFiles: self.arguments.input, to: self.arguments.out!)\n                return true\n            } else if self.arguments.out != nil {\n                throw CompilerError(\"Specifying --out only makes sense if you're using one of the utility commands: --build OR --build-module OR --unpack-module OR --upload-module\")\n            }\n\n            let configs = try ResolvedConfigs.from(logger: logger, baseURL: baseUrl, userConfigURL: URL.valdiUserConfigURL, args: self.arguments)\n            let diskCacheProvider = DiskCacheProvider(logger: logger, fileManager: fileManager, projectConfig: configs.projectConfig, disableDiskCache: configs.compilerConfig.disableDiskCache)\n            let compilerCompanion = try getCompanionExecutable(configs: configs, diskCacheProvider: diskCacheProvider)\n\n            let hotReloadingEnabled = configs.compilerConfig.hotReloadingEnabled\n            let baseDirURLs: [URL]\n            if hotReloadingEnabled {\n                if let explicitInputList = configs.compilerConfig.explicitInputList {\n                    var resolvedBaseDirs: [URL] = []\n                    var uniqueModuleDirPaths = Set<URL>()\n                    logger.debug(\"Registering unique module directory paths for watchman\")\n                    for entry in explicitInputList.entries {\n                        guard let monitor = entry.monitor, monitor else { continue }\n\n                        let moduleDirURL = baseUrl.resolving(path: entry.modulePath, isDirectory: true).standardizedFileURL.absoluteURL\n                        if !uniqueModuleDirPaths.contains(moduleDirURL) {\n                            uniqueModuleDirPaths.insert(moduleDirURL)\n                            resolvedBaseDirs.append(moduleDirURL)\n                        }\n                    }\n                    baseDirURLs = resolvedBaseDirs\n                } else {\n                    baseDirURLs = [configs.projectConfig.baseDir, configs.projectConfig.nodeModulesDir, configs.projectConfig.openSourceDir].compactMap { $0 }\n                }\n            } else {\n                baseDirURLs = [configs.projectConfig.baseDir, configs.projectConfig.openSourceDir].compactMap { $0 }\n            }\n\n            let bundleManager = try BundleManager(projectConfig: configs.projectConfig, compilerConfig: configs.compilerConfig, baseDirURLs: baseDirURLs)\n\n            // Register known modules if they are provided by the explicit input list\n            if let explicitInputList = configs.compilerConfig.explicitInputList {\n                logger.debug(\"Registering known bundle from explicit input list\")\n                for entry in explicitInputList.entries {\n                    let moduleURL = baseUrl.resolving(path: entry.modulePath).appendingPathComponent(Files.moduleYaml).standardizedFileURL.absoluteURL\n                    let moduleFile: File\n                    if let moduleContent = entry.moduleContent {\n                        moduleFile = .string(moduleContent)\n                    } else if let moduleFileEntry = entry.files.first(where: { $0.file.lastPathComponent() == Files.moduleYaml }) {\n                        let fileURL = baseUrl.resolving(path: moduleFileEntry.file).standardizedFileURL.absoluteURL\n                        moduleFile = .url(fileURL)\n                    } else {\n                        moduleFile = .url(moduleURL)\n                    }\n                    bundleManager.registerBundle(forName: entry.moduleName, bundleURL: moduleURL, file: moduleFile)\n                }\n            }\n\n            var resolvedModulesFilter: ModulesFilter?\n            if !self.arguments.module.isEmpty {\n                resolvedModulesFilter = try ModulesFilter(bundleManager: bundleManager, modulesFilter: self.arguments.module, ignoreModuleDeps: self.arguments.ignoreModuleDeps)\n            }\n\n            var daemonService: DaemonService?\n            if hotReloadingEnabled {\n                daemonService = try DaemonService(logger: logger,\n                                                  fileManager: fileManager,\n                                                  userConfig: configs.userConfig,\n                                                  projectConfig: configs.projectConfig,\n                                                  compilerConfig: configs.compilerConfig,\n                                                  companion: compilerCompanion,\n                                                  reloadOverUSB: self.arguments.usb)\n            }\n\n            let dumpComponentURLs = self.arguments.dumpComponents.map { baseUrl.resolving(path: $0) }\n\n            let fileDependenciesManager = FileDependenciesManager()\n            logger.debug(\"Configuring compilation pipeline\")\n\n            let pipeline = try buildPipeline(\n                configs: configs,\n                fileManager: fileManager,\n                diskCacheProvider: diskCacheProvider,\n                deferredWarningCollector: self.deferredWarningCollector,\n                compilerCompanion: compilerCompanion,\n                daemonService: daemonService,\n                fileDependenciesManager: fileDependenciesManager,\n                maxUploadConcurrentRequests: self.arguments.maxUploadConcurrentRequests,\n                codeGenOnly: self.arguments.codegenOnly,\n                forceMinify: self.arguments.forceMinify,\n                disableMinifyWeb: self.arguments.disableMinifyWeb,\n                emitInlineTranslations: self.arguments.inlineTranslations,\n                emitInlineAssets: self.arguments.inlineAssets,\n                modulesFilter: resolvedModulesFilter,\n                imageVariantsFilter: self.arguments.parsedImageVariantsFilter,\n                bundleManager: bundleManager,\n                rootBundle: bundleManager.rootBundle,\n                dumpComponentURLs: dumpComponentURLs,\n                codeCoverage: self.arguments.codeCoverage,\n                bazel: self.arguments.bazel\n            )\n            logger.info(\"Configured the compilation pipeline\")\n\n            let compiler = ValdiCompiler(logger: logger, pipeline: pipeline, projectConfig: configs.projectConfig, bundleManager: bundleManager)\n\n            if hotReloadingEnabled {\n                logger.info(\"Hot reloading enabled - starting the AutoRecompiler\")\n                let filesFinder = ValdiFilesFinder(urls: baseDirURLs)\n                let autoRecompiler = AutoRecompiler(logger: logger,\n                                                    compiler: compiler,\n                                                    filesFinder: filesFinder,\n                                                    bundleManager: bundleManager,\n                                                    fileDependenciesManager: fileDependenciesManager,\n                                                    errorDumper: self.errorDumper)\n\n                if let explicitInputList = configs.compilerConfig.explicitInputList {\n                    try compiler.addFiles(fromInputList: explicitInputList, baseUrl: baseUrl)\n                }\n\n                try autoRecompiler.start()\n                RunLoop.main.run()\n                autoRecompiler.stop()\n            } else {\n                logger.info(\"Hot reloading disabled - finding all files\")\n                // Read all the files from the given list\n                if let explicitInputList = configs.compilerConfig.explicitInputList {\n                    try compiler.addFiles(fromInputList: explicitInputList, baseUrl: baseUrl)\n                } else {\n                    // Finding all the files from the given directories\n                    let filesFinder = ValdiFilesFinder(urls: baseDirURLs)\n                    let fileUrls = try filesFinder.allFiles()\n                    // Adding them to the compiler\n                    fileUrls.forEach { compiler.addFile(file: $0) }\n                }\n                logger.info(\"Hot reloading disabled - starting compilation\")\n                try compiler.compile()\n            }\n\n            if arguments.bazel && logger.emittedLogsCount > 0 {\n                // With bazel, we don't want to make the process succeeds if we emitted logs\n                // as it will thrown off the cache\n                logger.error(\"Failing process as logs were emitted under a Bazel build\")\n                logger.error(\"Logs in Bazel will thrash the cache and must be avoided except for fatal errors\")\n                return true\n                //return false\n            }\n\n            return true\n        } catch let error {\n            self.errorDumper.dump(logger: logger, error: error)\n            return false\n        }\n    }\n\n    private func buildPipeline(configs: ResolvedConfigs,\n                               fileManager: ValdiFileManager,\n                               diskCacheProvider: DiskCacheProvider,\n                               deferredWarningCollector: DeferredWarningCollector,\n                               compilerCompanion: CompanionExecutable,\n                               daemonService: DaemonService?,\n                               fileDependenciesManager: FileDependenciesManager,\n                               maxUploadConcurrentRequests: Int,\n                               codeGenOnly: Bool,\n                               forceMinify: Bool,\n                               disableMinifyWeb: Bool,\n                               emitInlineTranslations: Bool,\n                               emitInlineAssets: Bool,\n                               modulesFilter: ModulesFilter?,\n                               imageVariantsFilter: ImageVariantsFilter?,\n                               bundleManager: BundleManager,\n                               rootBundle: CompilationItem.BundleInfo,\n                               dumpComponentURLs: [URL],\n                               codeCoverage: Bool,\n                               bazel: Bool) throws -> CompilationPipeline {\n        var teardownCallbacks = [() -> Void]()\n        let hotReloadingEnabled = configs.compilerConfig.hotReloadingEnabled\n        let enablePreviewInGeneratedTSFile = configs.compilerConfig.onlyProcessResourcesForModules.isEmpty\n\n        let toolboxExecutable = ToolboxExecutable(logger: logger, compilerToolboxURL: configs.projectConfig.compilerToolboxURL)\n        let userScriptManager = UserScriptManager()\n        let hasSQL = configs.projectConfig.clientSqlURL != nil\n\n        let projectClassMappingManager = ProjectClassMappingManager(allowMappingOverride: hotReloadingEnabled)\n\n        let typeScriptCompiler = TypeScriptCompiler(logger: logger,\n                                                    companion: compilerCompanion,\n                                                    projectConfig: configs.projectConfig,\n                                                    fileManager: fileManager,\n                                                    emitDebug: hotReloadingEnabled)\n        teardownCallbacks.append {\n            let _ = try? typeScriptCompiler.destroyWorkspace().waitForData()\n        }\n        let jsCodeInstrumentation = JSCodeInstrumentation(companion: compilerCompanion)\n        let typeScriptCompilerManager = TypeScriptCompilerManager(logger: logger,\n                                                                  fileManager: fileManager,\n                                                                  typeScriptCompiler: typeScriptCompiler,\n                                                                  projectName: configs.projectConfig.projectName,\n                                                                  rootURL: configs.projectConfig.baseDir,\n                                                                  hotReloadingEnabled: hotReloadingEnabled,\n                                                                  bundleManager: bundleManager,\n                                                                  projectConfig: configs.projectConfig,\n                                                                  compilerConfig: configs.compilerConfig)\n\n        let typeScriptAnnotationsManager = TypeScriptAnnotationsManager()\n\n        let nativeCodeGenerationManager = NativeCodeGenerationManager(logger: logger,\n                                                                      globalIosImport: configs.projectConfig.iosDefaultModuleNamePrefix,\n                                                                      rootURL: configs.projectConfig.baseDir)\n\n        let imageToolbox = ImageToolbox(toolboxExecutable: toolboxExecutable)\n\n        var builder = ValdiPipelineBuilder(logger: logger)\n\n        builder.append(preprocessor: FilterItemsProcessor(modulesFilter: modulesFilter, hotreloadingEnabled: hotReloadingEnabled))\n        builder.append(preprocessor: IdentifyItemsProcessor(logger: logger, ignoredFiles: configs.projectConfig.ignoredFiles))\n\n        let regenerateValdiModulesBuildFilesOnly = configs.compilerConfig.regenerateValdiModulesBuildFiles\n\n        if regenerateValdiModulesBuildFilesOnly {\n            // Even in regenerate mode, we need annotation processing to detect native exports for correct output file generation\n            // However, we skip type checking since generated files (res, Strings, etc.) may not exist\n\n            // .vue files must be parsed and their scripts extracted so that TypeScript files\n            // importing from .vue modules can resolve those imports during symbol dumping.\n            builder.append(processor: ParseDocumentsProcessor(logger: logger, globalIosImportPrefix: configs.projectConfig.iosDefaultModuleNamePrefix))\n            builder.append(processor: DocumentUserScriptExtractionProcessor(logger: logger, fileManager: fileManager, userScriptManager: userScriptManager, projectConfig: configs.projectConfig))\n            builder.append(processor: DumpTypeScriptSymbolsProcessor(logger: logger, typeScriptCompilerManager: typeScriptCompilerManager, compilerConfig: configs.compilerConfig, skipTypeChecking: true))\n            builder.append(processor: ParseTypeScriptAnnotationsProcessor(logger: logger,\n                                                                          projectClassMappingManager: projectClassMappingManager,\n                                                                          typeScriptCompilerManager: typeScriptCompilerManager,\n                                                                          annotationsManager: typeScriptAnnotationsManager))\n            builder.append(processor: ApplyTypeScriptAnnotationsProcessor(logger: logger,\n                                                                          typeScriptCompilerManager: typeScriptCompilerManager,\n                                                                          typeScriptAnnotationsManager: typeScriptAnnotationsManager,\n                                                                          nativeCodeGenerationManager: nativeCodeGenerationManager))\n            builder.append(processor: GenerateModuleBuildFileProcessor(logger: logger, \n                                                                       projectConfig: configs.projectConfig,\n                                                                       compilerConfig: configs.compilerConfig,\n                                                                       nativeCodeGenerationManager: nativeCodeGenerationManager))\n            builder.append(preprocessor: GenerateGlobalMetadataProcessor(logger: logger,\n                                                                         projectConfig: configs.projectConfig,\n                                                                         rootBundle: rootBundle,\n                                                                         shouldMergeWithExistingFile: false))\n        } else {\n            builder.append(preprocessor: try IdentifyImageAssetsProcessor(logger: logger,  imageToolbox: imageToolbox, compilerConfig: configs.compilerConfig, diskCacheProvider: diskCacheProvider))\n            builder.append(preprocessor: IdentifyFontAssetsProcessor())\n            builder.append(preprocessor: GenerateAssetCatalogProcessor(logger: logger, fileManager: fileManager, projectConfig: configs.projectConfig, enablePreviewInGeneratedTSFile: enablePreviewInGeneratedTSFile))\n            builder.append(preprocessor: TranslationStringsProcessor(logger: logger, fileManager: fileManager, compilerConfig: configs.compilerConfig, projectConfig: configs.projectConfig, emitInlineTranslations: emitInlineTranslations, companion: compilerCompanion))\n            builder.append(preprocessor: GenerateIdsFilesProcessor(logger: logger, fileManager: fileManager, projectConfig: configs.projectConfig, companion: compilerCompanion, nativeCodeGenerationManager: nativeCodeGenerationManager))\n            if hasSQL {\n                builder.append(preprocessor: try ClientSqlProcessor(\n                    logger: logger,\n                    fileManager: fileManager,\n                    diskCacheProvider: diskCacheProvider,\n                    projectConfig: configs.projectConfig,\n                    rootBundle: rootBundle\n                ))\n                builder.append(preprocessor: ClientSqlExportProcessor(\n                    logger: logger,\n                    fileManager: fileManager,\n                    projectConfig: configs.projectConfig,\n                    rootBundle: rootBundle\n                ))\n            }\n\n            if !configs.compilerConfig.generateTSResFiles {\n                if configs.projectConfig.iosBuildFileConfig != nil || configs.projectConfig.androidBuildFileConfig != nil\n                    || configs.projectConfig.webBuildFileConfig != nil{\n                    let shouldMergeWithExistingFile = modulesFilter != nil\n                    builder.append(preprocessor: GenerateGlobalMetadataProcessor(logger: logger,\n                                                                                 projectConfig: configs.projectConfig,\n                                                                                 rootBundle: rootBundle,\n                                                                                 shouldMergeWithExistingFile: shouldMergeWithExistingFile))\n                    builder.append(preprocessor: GenerateBuildFileProcessor(projectConfig: configs.projectConfig))\n                }\n                \n                builder.append(processor: ParseDocumentsProcessor(logger: logger, globalIosImportPrefix: configs.projectConfig.iosDefaultModuleNamePrefix))\n                builder.append(processor: CSSModulesProcessor(logger: logger, fileManager: fileManager, projectConfig: configs.projectConfig, fileDependenciesManager: fileDependenciesManager))\n                builder.append(processor: DocumentUserScriptExtractionProcessor(logger: logger, fileManager: fileManager, userScriptManager: userScriptManager, projectConfig: configs.projectConfig))\n                builder.append(processor: LoadCompilationMetadataProcessor(projectClassMappingManager: projectClassMappingManager, typeScriptCompilationManager: typeScriptCompilerManager, typeScriptNativeTypeResolver: nativeCodeGenerationManager.nativeTypeResolver))\n                builder.append(processor: DumpTypeScriptSymbolsProcessor(logger: logger, typeScriptCompilerManager: typeScriptCompilerManager, compilerConfig: configs.compilerConfig))\n                builder.append(processor: ParseTypeScriptAnnotationsProcessor(logger: logger,\n                                                                              projectClassMappingManager: projectClassMappingManager,\n                                                                              typeScriptCompilerManager: typeScriptCompilerManager,\n                                                                              annotationsManager: typeScriptAnnotationsManager))\n                builder.append(processor: CompileDocumentsProcessor(logger: logger,\n                                                                    projectClassMappingManager: projectClassMappingManager,\n                                                                    userScriptManager: userScriptManager,\n                                                                    fileDependenciesManager: fileDependenciesManager))\n                builder.append(processor: ApplyTypeScriptAnnotationsProcessor(logger: logger,\n                                                                              typeScriptCompilerManager: typeScriptCompilerManager,\n                                                                              typeScriptAnnotationsManager: typeScriptAnnotationsManager,\n                                                                              nativeCodeGenerationManager: nativeCodeGenerationManager))\n                builder.append(processor: DumpCompilationMetadataProcessor(projectConfig: configs.projectConfig,\n                                                                           compilerConfig: configs.compilerConfig,\n                                                                           projectClassMappingManager: projectClassMappingManager,\n                                                                           typeScriptCompilationManager: typeScriptCompilerManager,\n                                                                           typeScriptNativeTypeResolver: nativeCodeGenerationManager.nativeTypeResolver))\n\n                if !codeGenOnly {\n                    builder.append(processor: CompileTypeScriptProcessor(typeScriptCompilerManager: typeScriptCompilerManager, compilerConfig: configs.compilerConfig))\n                }\n\n                if codeCoverage {\n                    builder.append(processor: CodeCoverageProcessor(logger: logger, jsCodeInstrumentation: jsCodeInstrumentation, diskCacheProvider: diskCacheProvider, projectConfig: configs.projectConfig, typeScriptCompilerManager: typeScriptCompilerManager, fileManager: fileManager))\n                }\n\n                if !dumpComponentURLs.isEmpty {\n                    builder.append(processor: DumpComponentsProcessor(outFileURLs: dumpComponentURLs))\n                }\n\n                if !codeCoverage && !codeGenOnly && (!hotReloadingEnabled || forceMinify) {\n                    builder.append(processor: MinifyJsProcessor(logger: logger, diskCacheProvider: diskCacheProvider, projectConfig: configs.projectConfig, companion: compilerCompanion, disableMinifyWeb: disableMinifyWeb))\n                }\n\n                if !hotReloadingEnabled && !codeGenOnly {\n                    if !codeCoverage {\n                        builder.append(processor: SourceMapProcessor(compilerConfig: configs.compilerConfig, disableMinifyWeb: disableMinifyWeb))\n                    }\n\n                    if configs.compilerConfig.outputTarget.contains(.release) {\n                        builder.append(processor: try JavaScriptPreCompilerProcessor(\n                            logger: logger,\n                            fileManager: fileManager,\n                            diskCacheProvider: diskCacheProvider,\n                            toolboxExecutable: toolboxExecutable,\n                            androidJsBytecodeFormat: configs.projectConfig.androidJsBytecodeFormat))\n                    }\n                }\n            }\n        }\n\n        if !configs.compilerConfig.generateTSResFiles {\n            if !hotReloadingEnabled && !regenerateValdiModulesBuildFilesOnly {\n                builder.append(postprocessor: GenerateViewClassesProcessor(logger: logger, compilerConfig: configs.compilerConfig))\n                builder.append(postprocessor: GenerateModelsProcessor(logger: logger, compilerConfig: configs.compilerConfig))\n                // GenerateDependencyInjectionDataProcessor must run BEFORE CombineNativeSourcesProcessor\n                // so that Factory classes are included in the combined output for single_file_codegen modules\n                builder.append(postprocessor: GenerateDependencyInjectionDataProcessor(logger: logger, onlyFocusProcessingForModules: configs.compilerConfig.onlyFocusProcessingForModules))\n                builder.append(postprocessor: CombineNativeSourcesProcessor(logger: logger, compilerConfig: configs.compilerConfig, projectConfig: configs.projectConfig, bundleManager: bundleManager))\n                builder.append(postprocessor: GeneratedTypesVerificationProcessor(logger: logger, projectConfig: configs.projectConfig))\n            }\n\n            if !codeGenOnly && !regenerateValdiModulesBuildFilesOnly {\n                builder.append(postprocessor: InvalidDocumentsProcessor(logger: logger, generateErrorDocuments: hotReloadingEnabled, compilationPipeline: builder.processors, projectConfig: configs.projectConfig))\n                builder.append(postprocessor: try ImageResourcesProcessor(logger: logger, fileManager: fileManager,\n                                                                          diskCacheProvider: diskCacheProvider,\n                                                                          projectConfig: configs.projectConfig,\n                                                                          compilerConfig: configs.compilerConfig,\n                                                                          imageToolbox: imageToolbox,\n                                                                          imageVariantsFilter: imageVariantsFilter,\n                                                                          alwaysUseVariantAgnosticFilenames: hotReloadingEnabled || emitInlineAssets))\n            }\n\n            let isCompilingEntireProject = modulesFilter == nil\n\n            builder.append(postprocessor: DiagnosticsProcessor(projectConfig: configs.projectConfig))\n            builder.append(postprocessor: ResolveOutputPathsProcessor(logger: logger,\n                                                                      projectConfig: configs.projectConfig,\n                                                                      compilerConfig: configs.compilerConfig,\n                                                                      shouldGenerateKeepXML: isCompilingEntireProject || bazel))\n            \n            if (configs.projectConfig.webEnabled) {\n                builder.append(postprocessor: PrependWebJSProcessor(logger: logger))\n            }\n\n            let bundleResourceOutputMode: BundleResourcesProcessor.OutputMode\n            if hotReloadingEnabled {\n                bundleResourceOutputMode = .assetPackage\n            } else if emitInlineAssets {\n                bundleResourceOutputMode = .bundledAssetPackage\n            } else {\n                bundleResourceOutputMode = .uploadedArtifacts\n            }\n            let downloadableArtifactsProcessingMode: BundleResourcesProcessor.DownloadableArtifactsProcessingMode = configs.compilerConfig.verifyDownloadableArtifacts ? .verifySignatures : .uploadIfNeeded\n\n            builder.append(postprocessor: BundleResourcesProcessor(logger: logger,\n                                                                   fileManager: fileManager,\n                                                                   diskCacheProvider: diskCacheProvider,\n                                                                   projectConfig: configs.projectConfig,\n                                                                   compilerConfig: configs.compilerConfig,\n                                                                   maxUploadConcurrentRequests: maxUploadConcurrentRequests,\n                                                                   outputMode: bundleResourceOutputMode,\n                                                                   downloadableArtifactsProcessingMode: downloadableArtifactsProcessingMode,\n                                                                   writeDownloadableArtifactsManifest: !bazel,\n                                                                   rootBundle: bundleManager.rootBundle,\n                                                                   companionExecutable: compilerCompanion\n                                                                  ))\n\n            if let daemonService = daemonService, hotReloadingEnabled {\n                let hotReloadingProcessor = HotReloadingProcessor(logger: logger, daemonService: daemonService)\n                builder.append(postprocessor: hotReloadingProcessor)\n            }\n\n            if !hotReloadingEnabled {\n                builder.append(postprocessor: FinalFilesVerificationProcessor(logger: logger, projectConfig: configs.projectConfig))\n            }\n            // we don't do clean up of orphaned files during hot reloading - we keep the compiler generated files\n            let removeOrphanFiles = modulesFilter == nil && !configs.projectConfig.shouldSkipRemoveOrphanFiles && !configs.compilerConfig.regenerateValdiModulesBuildFiles && !hotReloadingEnabled\n            builder.append(postprocessor: SaveFilesProcessor(logger: logger,\n                                                             fileManager: fileManager,\n                                                             projectConfig: configs.projectConfig,\n                                                             modulesFilter: modulesFilter,\n                                                             removeOrphanFiles: removeOrphanFiles,\n                                                             hotReloadingEnabled: hotReloadingEnabled))\n        }\n\n        // In regenerate mode, don't fail immediately on annotation processing errors\n        // These errors are often due to missing type information (generated files don't exist yet)\n        // Modules with errors will default to has_ios_exports=True, has_android_exports=True\n        let failImmediatelyOnError = !hotReloadingEnabled && !configs.compilerConfig.regenerateValdiModulesBuildFiles\n        \n        let pipeline = CompilationPipeline(logger: logger,\n                                   processors: builder.build(),\n                                   deferredWarningCollector: self.deferredWarningCollector,\n                                   failImmediatelyOnError: failImmediatelyOnError)\n\n        teardownCallbacks.forEach(pipeline.onTeardown)\n\n        return pipeline\n    }\n\n    private func getCompanionExecutable(configs: ResolvedConfigs, diskCacheProvider: DiskCacheProvider) throws -> CompanionExecutable {\n        return try self.companionExecutableProvider.getCompanionExecutable(\n            compilerConfig: configs.compilerConfig,\n            projectConfig: configs.projectConfig,\n            logsOutputPath: self.arguments.companionLogOutput, \n            disableTsCompilerCache: self.arguments.disableTsCompilerCache,\n            diskCacheProvider: diskCacheProvider,\n            isBazelBuild: self.arguments.bazel)\n    }\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/CppEnumGenerator.swift",
    "content": "// Copyright © 2025 Snap, Inc. All rights reserved.\n\nclass CppEnumGenerator {\n    private let exportedEnum: ExportedEnum\n    private let cppType: CPPType\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let sourceFileName: GeneratedSourceFilename\n\n    init(exportedEnum: ExportedEnum,\n         cppType: CPPType,\n         bundleInfo: CompilationItem.BundleInfo,\n         sourceFileName: GeneratedSourceFilename) {\n        self.exportedEnum = exportedEnum\n        self.cppType = cppType\n        self.bundleInfo = bundleInfo\n        self.sourceFileName = sourceFileName\n    }\n\n    func write() throws -> [NativeSource] {\n        let header = CppFileGenerator(namespace: cppType.declaration.namespace, isHeader: true)\n        let impl = CppFileGenerator(namespace: cppType.declaration.namespace, isHeader: false)\n        \n        impl.includeSection.addInclude(path: cppType.includePath)\n\n        let exceptionTrackerTypeDecl = CppFileGenerator.getValdiTypeDeclaration(typeName: \"ExceptionTracker\")\n        let valueTypeDecl = CppFileGenerator.getValdiTypeDeclaration(typeName: \"Value\")\n        let registeredClassType = CppFileGenerator.getValdiTypeDeclaration(typeName: \"RegisteredCppGeneratedClass\")\n        let generatedEnumClass = CppFileGenerator.getValdiTypeDeclaration(typeName: \"CppGeneratedEnum\")\n\n        header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration: exceptionTrackerTypeDecl, typeArguments: nil))\n        header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration: valueTypeDecl, typeArguments: nil))\n        header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration: registeredClassType, typeArguments: nil))\n\n        header.body.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: self.sourceFileName, additionalComments: exportedEnum.comments))\n        header.body.appendBody(\"\\n\")\n\n        let enumBody = CppCodeWriter()\n\n        header.body.appendBody(\"enum class \\(cppType.declaration.name) {\\n\")\n        header.body.appendBody(enumBody)\n        header.body.appendBody(\"};\\n\\n\")\n\n        header.body.appendBody(\"void unmarshallEnum(\\(exceptionTrackerTypeDecl.fullTypeName) &exceptionTracker, const \\(valueTypeDecl.fullTypeName) &value, \\(cppType.declaration.name) &out);\\n\\n\")\n        header.body.appendBody(\"void marshallEnum(\\(exceptionTrackerTypeDecl.fullTypeName) &exceptionTracker, \\(cppType.declaration.name) value, \\(valueTypeDecl.fullTypeName) &out);\\n\\n\")\n\n        header.body.appendBody(\"\\(registeredClassType.fullTypeName) *getRegisteredEnumClass(const \\(cppType.declaration.name) *);\\n\")\n\n        impl.includeSection.addInclude(path: \"valdi_core/cpp/Marshalling/CppGeneratedEnum.hpp\")\n\n        let fqMarshallerTypeName: String\n        let allEnumValuesLiteral: String\n        let schemaWriter = CppSchemaWriter(typeParameters: nil, generator: nil)\n        let nameAllocator = PropertyNameAllocator.forCpp()\n\n        let allCases: [(String, String?)]\n        switch exportedEnum.cases {\n        case .enum(let intCases):\n            try schemaWriter.appendIntEnum(cppType.declaration.fullTypeName, enumCases: intCases)\n            let intEnumMarshaller = CppFileGenerator.getValdiTypeDeclaration(typeName: \"CppIntEnumMarshaller\")\n            fqMarshallerTypeName = \"\\(intEnumMarshaller.fullTypeName)<\\(cppType.declaration.name), \\(intCases.count)>\"\n            allEnumValuesLiteral = intCases.map { \"\\($0.value)\" }.joined(separator: \", \")\n\n            allCases = intCases.map { (nameAllocator.allocate(property: $0.name).name, $0.comments) }\n            break\n        case .stringEnum(let stringCases):\n            try schemaWriter.appendStringEnum(cppType.declaration.fullTypeName, enumCases: stringCases)\n\n            let stringEnumMarshaller = CppFileGenerator.getValdiTypeDeclaration(typeName: \"CppStringEnumMarshaller\")\n            fqMarshallerTypeName = \"\\(stringEnumMarshaller.fullTypeName)<\\(cppType.declaration.name), \\(stringCases.count)>\"\n            allEnumValuesLiteral = stringCases.map { \"\\\"\\($0.value)\\\"\" }.joined(separator: \", \")\n\n            allCases = stringCases.map { (nameAllocator.allocate(property: $0.name).name, $0.comments) }\n            break\n        }\n\n        let lastIndex = allCases.count - 1\n        for (idx, (caseName, comments)) in allCases.enumerated() {\n            if let comments {\n                enumBody.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: comments))\n                enumBody.appendBody(\"\\n\")\n            }\n\n            enumBody.appendBody(\"\\(caseName) = \\(idx)\")\n            if idx != lastIndex {\n                enumBody.appendBody(\",\\n\")\n            } else {\n                enumBody.appendBody(\"\\n\")\n            }\n        }\n\n        let getEnumMarshallerName = \"get\\(cppType.declaration.name.pascalCased)EnumMarshaller\"\n\n        impl.body.appendBody(\"\"\"\n            namespace {\n              const \\(fqMarshallerTypeName) &\\(getEnumMarshallerName)() {\n                static auto kEnumMarshaller = \\(fqMarshallerTypeName)({\\(allEnumValuesLiteral)});\n                return kEnumMarshaller;\n              }\n            }\n            \n            void unmarshallEnum(\\(exceptionTrackerTypeDecl.fullTypeName) &exceptionTracker, const \\(valueTypeDecl.fullTypeName) &value, \\(cppType.declaration.name) &out) {\n              \\(getEnumMarshallerName)().unmarshall(exceptionTracker, value, out);\n            }\n            \n            void marshallEnum(\\(exceptionTrackerTypeDecl.fullTypeName) &exceptionTracker, \\(cppType.declaration.name) value, \\(valueTypeDecl.fullTypeName) &out) {\n              \\(getEnumMarshallerName)().marshall(exceptionTracker, value, out);\n            }\n            \n            \\(registeredClassType.fullTypeName) *getRegisteredEnumClass(const \\(cppType.declaration.name) *) {\n              static auto kEnumClass = \\(generatedEnumClass.fullTypeName)::registerEnumSchema(\"\\(schemaWriter.str)\");\n              return kEnumClass;\n            }\n            \"\"\")\n\n        return [\n            NativeSource(relativePath: cppType.includeDir,\n                         filename: \"\\(cppType.declaration.name).hpp\",\n                         file: .string(header.content.indented),\n                         groupingIdentifier: \"\\(bundleInfo.name).hpp\", groupingPriority: 0),\n            NativeSource(relativePath: cppType.includeDir,\n                         filename: \"\\(cppType.declaration.name).cpp\",\n                         file: .string(impl.content.indented),\n                         groupingIdentifier: \"\\(bundleInfo.name).cpp\", groupingPriority: 0)\n        ]\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/CppModelGenerator.swift",
    "content": "//\n//  CppModelGenerator.swift\n//\n//\n//  Created by Simon Corsin on 4/11/23.\n//\n\nimport Foundation\n\nprivate struct CppPropertyName {\n    let fieldName: String\n    let getterName: String\n    let setterName: String\n    let constructorParameterName: String\n}\n\nprivate struct CppProperty {\n    let name: CppPropertyName\n    let property: ValdiModelProperty\n    let typeParser: CppTypeParser\n}\n\nprivate final class CppCodeGeneratorModelNamespaceResolver: CppCodeGeneratorNamespaceResolver {\n    private let classNamespace: CPPNamespace\n    private let proxyNamespace: CPPNamespace\n    private let isInterface: Bool\n\n    init(classNamespace: CPPNamespace, proxyNamespace: CPPNamespace, isInterface: Bool) {\n        self.classNamespace = classNamespace\n        self.proxyNamespace = proxyNamespace\n        self.isInterface = isInterface\n    }\n\n    func getNamespace(forTypeAlias typeAlias: CppTypeAlias) -> CPPNamespace {\n        if isInterface && typeAlias.isOnMethod {\n            return proxyNamespace\n        } else {\n            return classNamespace\n        }\n    }\n}\n\nfinal class CppModelGenerator {\n    private let cppType: CPPType\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let typeParameters: [ValdiTypeParameter]?\n    private let properties: [ValdiModelProperty]\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n    private let isInterface: Bool\n    private let comments: String?\n\n    init(cppType: CPPType,\n         bundleInfo: CompilationItem.BundleInfo,\n         typeParameters: [ValdiTypeParameter]?,\n         properties: [ValdiModelProperty],\n         classMapping: ResolvedClassMapping,\n         sourceFileName: GeneratedSourceFilename,\n         isInterface: Bool,\n         comments: String?) {\n        self.cppType = cppType\n        self.bundleInfo = bundleInfo\n        self.typeParameters = typeParameters\n        self.properties = properties\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.isInterface = isInterface\n        self.comments = comments\n    }\n\n    private func resolveProperties(codeGenerator: CppCodeGenerator, nameAllocator: PropertyNameAllocator) throws -> [CppProperty] {\n        return try properties.map { property in\n            let typeParser = try codeGenerator.getTypeParser(type: property.type, namePaths: [property.name], nameAllocator: nameAllocator)\n            let fieldName = nameAllocator.allocate(property: \"_\\(property.name)\").name\n            let getterName = nameAllocator.allocate(property: \"get\\(property.name.pascalCased)\").name\n            let setterName = nameAllocator.allocate(property: \"set\\(property.name.pascalCased)\").name\n            let constructorParameterName = nameAllocator.allocate(property: property.name).name\n\n            return CppProperty(name:\n                                CppPropertyName(fieldName: fieldName, getterName: getterName, setterName: setterName, constructorParameterName: constructorParameterName),\n                               property: property,\n                               typeParser: typeParser)\n        }\n    }\n\n    private func generateClassFields(classNamespace: CPPNamespace, cppProperties: [CppProperty]) -> CppCodeWriter {\n        let decl = CppCodeWriter()\n        for cppProperty in cppProperties {\n            let typeName = cppProperty.typeParser.typeNameResolver.resolve(classNamespace)\n            if let fieldInitializationString = cppProperty.typeParser.defaultInitializationString {\n                decl.appendBody(\"\\(typeName) \\(cppProperty.name.fieldName) = \\(fieldInitializationString);\\n\")\n            } else {\n                decl.appendBody(\"\\(typeName) \\(cppProperty.name.fieldName);\\n\")\n            }\n        }\n\n        return decl\n    }\n\n    private func makeClassWriter() -> CppClassWriter {\n        let header = CppCodeWriter()\n        let impl = CppCodeWriter()\n        let inlineImplementation = typeParameters != nil\n\n        return CppClassWriter(namespace: cppType.declaration.namespace, className: cppType.declaration.name, header: header, impl: impl, inlineImplementation: inlineImplementation)\n    }\n\n    private func generateClassConstructors(classNamespace: CPPNamespace, cppProperties: [CppProperty], parentClassName: String) -> (decl: CppCodeWriter, impl: CppCodeWriter) {\n        let classWriter = makeClassWriter()\n\n        classWriter.writeConstructor(arguments: [], memberInitializerList: \"\\(parentClassName)(getRegisteredClass())\") { writer in\n\n        }\n\n        if !cppProperties.isEmpty {\n            let ctorParameters = cppProperties.map {\n                if $0.typeParser.isMovable {\n                    return CPPFunctionArgument(typeResolver: .with(specifiers:.constRef, $0.typeParser.typeNameResolver), name: $0.name.constructorParameterName)\n                } else {\n                    return CPPFunctionArgument(typeResolver: $0.typeParser.typeNameResolver, name: $0.name.constructorParameterName)\n                }\n            }\n            let ctorFieldInitializers = cppProperties.map {\n                let initializer = $0.typeParser.isMovable ? \"std::move(\\($0.name.constructorParameterName))\" : $0.name.constructorParameterName\n                return \"\\($0.name.fieldName)(\\(initializer))\"\n            }.joined(separator: \",\\n\")\n\n            classWriter.writeConstructor(arguments: ctorParameters, memberInitializerList: \"\\(parentClassName)(getRegisteredClass()),\\n\\(ctorFieldInitializers)\") { writer in\n\n            }\n        }\n\n        return (classWriter.header, classWriter.impl)\n    }\n\n    private func generateClassMethods(classNamespace: CPPNamespace, cppProperties: [CppProperty]) -> (decl: CppCodeWriter, impl: CppCodeWriter) {\n        let classWriter = makeClassWriter()\n        for cppProperty in cppProperties {\n            if cppProperty.typeParser.isMovable {\n                classWriter.writeMethod(name: cppProperty.name.getterName,\n                                        arguments: [],\n                                        returnType: .with(specifiers:.constRef, cppProperty.typeParser.typeNameResolver),\n                                        specifiers: .const) { writer in\n                    writer.appendBody(\"return \\(cppProperty.name.fieldName);\\n\")\n                }\n\n                classWriter.writeMethod(name: cppProperty.name.setterName,\n                                        arguments: [CPPFunctionArgument(typeResolver: .with(specifiers: .constRef, cppProperty.typeParser.typeNameResolver), name: \"value\")],\n                                        returnType: .with(typeName: \"void\"),\n                                        specifiers: .none) { writer in\n                    writer.appendBody(\"\\(cppProperty.name.fieldName) = value;\\n\")\n                }\n\n                classWriter.writeMethod(name: cppProperty.name.setterName,\n                                        arguments: [CPPFunctionArgument(typeResolver: .with(specifiers: .rValueRef, cppProperty.typeParser.typeNameResolver), name: \"value\")],\n                                        returnType: .with(typeName: \"void\"),\n                                        specifiers: .none) { writer in\n                    writer.appendBody(\"\\(cppProperty.name.fieldName) = std::move(value);\\n\")\n                }\n            } else {\n                classWriter.writeMethod(name: cppProperty.name.getterName,\n                                        arguments: [],\n                                        returnType: cppProperty.typeParser.typeNameResolver,\n                                        specifiers: .const) { writer in\n                    writer.appendBody(\"return \\(cppProperty.name.fieldName);\\n\")\n                }\n\n                classWriter.writeMethod(name: cppProperty.name.setterName,\n                                        arguments: [CPPFunctionArgument(typeResolver: cppProperty.typeParser.typeNameResolver, name: \"value\")],\n                                        returnType: .with(typeName: \"void\"),\n                                        specifiers: .none) { writer in\n                    writer.appendBody(\"\\(cppProperty.name.fieldName) = value;\\n\")\n                }\n            }\n        }\n\n        return (classWriter.header, classWriter.impl)\n    }\n\n    private func generateRegisterClass(generator: CppCodeGenerator) throws -> (decl: CppCodeWriter, impl: CppCodeWriter) {\n        let cppGeneratedClass = CppCodeGenerator.getValdiTypeName(typeName: \"CppGeneratedClass\").resolve(cppType.declaration.namespace)\n        let registeredClassType = CPPTypeNameResolver.with(specifiers: .ptr, CppCodeGenerator.getValdiTypeName(typeName: \"RegisteredCppGeneratedClass\"))\n\n        let schemaWriter = CppSchemaWriter(typeParameters: typeParameters, generator: generator)\n        if isInterface {\n            try schemaWriter.appendInterface(cppType.declaration.fullTypeName, properties: self.properties)\n        } else {\n            try schemaWriter.appendClass(cppType.declaration.fullTypeName, properties: self.properties)\n        }\n\n        let classWriter = makeClassWriter()\n\n        var registerSchemaParameters: [String]\n        if generator.referencedTypes.isEmpty {\n            registerSchemaParameters = [\"\\\"\\(schemaWriter.str)\\\"\"]\n        } else {\n            registerSchemaParameters = [\"\\\"\\(schemaWriter.str)\\\"\", generator.getTypeReferencesVecExpression(inNamespace: self.cppType.declaration.namespace)]\n        }\n\n        if let typeParameters {\n            registerSchemaParameters.append(\"Valdi::CppGeneratedGenericClass::makeTypeArgumentsCallback<\\(typeParameters.map { $0.name }.joined(separator: \", \"))>()\")\n            generator.header.includeSection.addInclude(path: \"valdi_core/cpp/Marshalling/CppGeneratedGenericClass.hpp\")\n\n            classWriter.writeMethod(name: \"getRegisteredClass\",\n                                    arguments: [],\n                                    returnType: registeredClassType,\n                                    specifiers: .static_) { writer in\n                writer.appendBody(\"static auto *kRegisteredClass = \\(cppGeneratedClass)::registerGenericSchema(\\(registerSchemaParameters.joined(separator: \", \")));\\n\\n\")\n                writer.appendBody(\"return kRegisteredClass;\\n\");\n            }\n        } else {\n            classWriter.writeMethod(name: \"getRegisteredClass\",\n                                    arguments: [],\n                                    returnType: registeredClassType,\n                                    specifiers: .static_) { writer in\n                writer.appendBody(\"static auto *kRegisteredClass = \\(cppGeneratedClass)::registerSchema(\\(registerSchemaParameters.joined(separator: \", \")));\\n\\n\")\n                writer.appendBody(\"return kRegisteredClass;\\n\");\n            }\n        }\n\n        return (classWriter.header, classWriter.impl)\n    }\n\n    private func generateFieldsReferenceArgument(cppProperties: [CppProperty]) -> String {\n        if cppProperties.isEmpty {\n            return \"\"\n        } else {\n            let fieldsReferenceString = cppProperties.map { \"self.\\($0.name.fieldName)\" }.joined(separator: \", \")\n            return \", \\(fieldsReferenceString)\"\n        }\n    }\n\n    private func generateMethodsReferenceArgument(receiverArgument: String, cppProperties: [CppProperty]) -> String {\n        if cppProperties.isEmpty {\n            return \"\"\n        } else {\n            let methodsReferenceString = cppProperties.map { cppProperty in\n                if cppProperty.typeParser.method != nil {\n                    return \"Valdi::CppMarshaller::methodToFunction<\\(cppType.declaration.name), &\\(cppType.declaration.name)::\\(cppProperty.name.constructorParameterName)>(\\(receiverArgument))\"\n                } else {\n                    return \"\\(receiverArgument)->\\(cppProperty.name.constructorParameterName)()\"\n                }\n            }.joined(separator: \", \")\n            return \", \\(methodsReferenceString)\"\n        }\n    }\n\n    private func writeClassPrologue(parentClassName: String, header: CodeWriter) {\n        header.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: self.sourceFileName, additionalComments: self.comments))\n        header.appendBody(\"\\n\")\n\n        if let typeParameters {\n            let typeNames = typeParameters.map { \"typename \\($0.name)\" }.joined(separator: \", \")\n            header.appendBody(\"template<\\(typeNames)>\\n\")\n        }\n        header.appendBody(\"class \\(cppType.declaration.name): public \\(parentClassName) {\\n\")\n    }\n\n    private func getSelfTypename() -> String {\n        if let typeParameters {\n            let typeNames = typeParameters.map { $0.name }.joined(separator: \", \")\n            return \"\\(cppType.declaration.name)<\\(typeNames)>\"\n        } else {\n            return cppType.declaration.name\n        }\n    }\n\n    private func writeClass(classNamespace: CPPNamespace, generator: CppCodeGenerator, cppProperties: [CppProperty]) throws {\n        let parentClassName = CppFileGenerator.getValdiTypeDeclaration(typeName: \"CppGeneratedModel\").resolveTypeName(inNamespace: classNamespace)\n        let exceptionTrackerTypeDeclaration = CppFileGenerator.getValdiTypeDeclaration(typeName: \"ExceptionTracker\")\n        let valueTypeDeclaration = CppFileGenerator.getValdiTypeDeclaration(typeName: \"Value\")\n\n        generator.header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration: exceptionTrackerTypeDeclaration, typeArguments: nil))\n        generator.header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration: valueTypeDeclaration, typeArguments: nil))\n\n        let exceptionTrackerType = CPPTypeNameResolver.with(specifiers: .ref, .with(typeDeclaration: exceptionTrackerTypeDeclaration))\n        let valueType = CPPTypeNameResolver.with(typeDeclaration: valueTypeDeclaration)\n\n        let (constructorsDecl, constructorsImpl) = generateClassConstructors(classNamespace: classNamespace, cppProperties: cppProperties, parentClassName: parentClassName)\n        let (methodsDecl, methodsImpl) = generateClassMethods(classNamespace: classNamespace, cppProperties: cppProperties)\n        let fieldsDeclaration = generateClassFields(classNamespace: classNamespace, cppProperties: cppProperties)\n        let (registerClassHeader, registerClassBody) = try generateRegisterClass(generator: generator)\n\n        let selfTypeName = getSelfTypename()\n\n        /* Header generation */\n        writeClassPrologue(parentClassName: parentClassName, header: generator.header.body)\n        generator.header.body.appendBody(\"public:\\n\")\n        if !generator.typealiases.isEmpty {\n            for cppTypealias in generator.typealiases {\n                generator.header.body.appendBody(cppTypealias.statement.resolve(classNamespace))\n            }\n            generator.header.body.appendBody(\"\\n\")\n        }\n\n        generator.header.body.appendBody(constructorsDecl)\n        generator.header.body.appendBody(\"\\n\")\n        generator.header.body.appendBody(methodsDecl)\n        generator.header.body.appendBody(registerClassHeader)\n\n        let marshallWriter = makeClassWriter()\n        let fieldsReferenceArguments = generateFieldsReferenceArgument(cppProperties: cppProperties)\n\n        marshallWriter.writeMethod(name: \"unmarshall\",\n                                   arguments: [\n                                        CPPFunctionArgument(typeResolver: exceptionTrackerType, name: \"exceptionTracker\"),\n                                        CPPFunctionArgument(typeResolver: .with(specifiers: .constRef, valueType), name: \"value\"),\n                                        CPPFunctionArgument(typeResolver: .with(specifiers: .ref, .with(typeName: selfTypeName)), name: \"out\")\n                                   ],\n                                   returnType: .with(typeName: \"void\"),\n                                   specifiers: .static_) { writer in\n            if !cppProperties.isEmpty {\n                writer.appendBody(\"auto &self = out;\\n\")\n            }\n\n            writer.appendBody(\"Valdi::CppMarshaller::unmarshallTypedObject(exceptionTracker, *getRegisteredClass(), value\\(fieldsReferenceArguments));\\n\")\n        }\n\n        marshallWriter.writeMethod(name: \"marshall\",\n                                   arguments: [\n                                        CPPFunctionArgument(typeResolver: exceptionTrackerType, name: \"exceptionTracker\"),\n                                        CPPFunctionArgument(typeResolver: .with(specifiers: .constRef, .with(typeName: selfTypeName)), name: \"value\"),\n                                        CPPFunctionArgument(typeResolver: .with(specifiers: .ref, valueType), name: \"out\")\n                                   ],\n                                   returnType: .with(typeName: \"void\"),\n                                   specifiers: .static_) { writer in\n            if !cppProperties.isEmpty {\n                writer.appendBody(\"const auto &self = value;\\n\")\n            }\n            writer.appendBody(\"Valdi::CppMarshaller::marshallTypedObject(exceptionTracker, *getRegisteredClass(), out\\(fieldsReferenceArguments));\\n\")\n        }\n\n        generator.header.body.appendBody(marshallWriter.header)\n\n        generator.header.body.appendBody(\"\\nprivate:\\n\")\n        generator.header.body.appendBody(fieldsDeclaration)\n        generator.header.body.appendBody(\"};\\n\")\n\n        /* Impl generation */\n\n        generator.impl.body.appendBody(constructorsImpl)\n        generator.impl.body.appendBody(methodsImpl)\n        generator.impl.body.appendBody(marshallWriter.impl)\n        generator.impl.body.appendBody(registerClassBody)\n    }\n\n    private func generateInterfaceMethods(classNamespace: CPPNamespace,\n                                          proxyNamespace: CPPNamespace,\n                                          generator: CppCodeGenerator,\n                                          nameAllocator: PropertyNameAllocator,\n                                          cppProperties: [CppProperty]) -> (decl: CppCodeWriter, impl: CppCodeWriter) {\n        let decl = CppCodeWriter()\n        let impl = CppCodeWriter()\n\n        for cppProperty in cppProperties {\n            let scopedNameAllocator = nameAllocator.scoped()\n\n            if let cppMethod = cppProperty.typeParser.method {\n                let returnTypeName = cppMethod.returnTypeNameResolver.resolve(classNamespace)\n                let returnPrefix = returnTypeName == \"void\" ? \"\" : \"return \"\n\n                let parameterNames = cppMethod.parameters.map { scopedNameAllocator.allocate(property: $0.name).name }\n                let parameterWithTypes = cppMethod.parameters.indices.map {\n                    let parameterName = parameterNames[$0]\n                    let parameterType = cppMethod.parameters[$0].typeNameResolver.resolve(classNamespace)\n                    return \"\\(parameterType) \\(parameterName)\"\n                }.joined(separator: \", \")\n\n                decl.appendBody(\"virtual \\(returnTypeName) \\(cppProperty.name.constructorParameterName)(\\(parameterWithTypes)) = 0;\\n\\n\")\n\n                if cppProperty.property.type.isOptional {\n                    impl.appendBody(\"\"\"\n                    \\(returnTypeName) \\(cppProperty.name.constructorParameterName)(\\(parameterWithTypes)) final {\n                      if (!\\(cppProperty.name.fieldName)) {\n                        Valdi::CppMarshaller::throwUnimplementedMethod();\n                      }\n                      \\(returnPrefix)\\(cppProperty.name.fieldName).value()(\\(parameterNames.joined(separator: \", \") ));\n                    }\n\n\n                    \"\"\")\n                } else {\n                    impl.appendBody(\"\"\"\n                    \\(returnTypeName) \\(cppProperty.name.constructorParameterName)(\\(parameterWithTypes)) final {\n                      \\(returnPrefix)\\(cppProperty.name.fieldName)(\\(parameterNames.joined(separator: \", \") ));\n                    }\n\n\n                    \"\"\")\n                }\n            } else {\n                decl.appendBody(\"virtual \\(cppProperty.typeParser.typeNameResolver.resolve(classNamespace)) \\(cppProperty.name.constructorParameterName)() = 0;\\n\\n\")\n\n                impl.appendBody(\"\"\"\n                \\(cppProperty.typeParser.typeNameResolver.resolve(proxyNamespace)) \\(cppProperty.name.constructorParameterName)() final {\n                  return \\(cppProperty.name.fieldName);\n                }\n\n\n                \"\"\")\n            }\n        }\n\n        return (decl, impl)\n    }\n\n    private func writeInterface(classNamespace: CPPNamespace,\n                                generator: CppCodeGenerator,\n                                proxyClassName: String,\n                                proxyNamespace: CPPNamespace,\n                                nameAllocator: PropertyNameAllocator,\n                                cppProperties: [CppProperty]) throws {\n        let parentClassName = CppFileGenerator.getValdiTypeDeclaration(typeName: \"CppGeneratedInterface\").resolveTypeName(inNamespace: classNamespace)\n        let exceptionTrackerTypeDeclaration = CppFileGenerator.getValdiTypeDeclaration(typeName: \"ExceptionTracker\")\n        let valueTypeDeclaration = CppFileGenerator.getValdiTypeDeclaration(typeName: \"Value\")\n\n        generator.header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration: exceptionTrackerTypeDeclaration, typeArguments: nil))\n        generator.header.forwardDeclarations.addForwardDeclaration(typeReference: CPPTypeReference(declaration: valueTypeDeclaration, typeArguments: nil))\n\n        let exceptionTrackerType = CPPTypeNameResolver.with(specifiers: .ref, .with(typeDeclaration: exceptionTrackerTypeDeclaration))\n        let valueType = CPPTypeNameResolver.with(typeDeclaration: valueTypeDeclaration)\n\n        let cppTypeRefType = CppCodeGenerator.makeRefType(typeName: .with(typeName: getSelfTypename()))\n        let (registerClassHeader, registerClassBody) = try generateRegisterClass(generator: generator)\n\n        let (methodsDecl, methodsImpl) = generateInterfaceMethods(classNamespace: classNamespace,\n                                                                  proxyNamespace: proxyNamespace,\n                                                                  generator: generator,\n                                                                  nameAllocator: nameAllocator,\n                                                                  cppProperties: cppProperties)\n        let fieldsDeclaration = generateClassFields(classNamespace: proxyNamespace, cppProperties: cppProperties)\n\n        /* Header generation */\n        writeClassPrologue(parentClassName: parentClassName, header: generator.header.body)\n        generator.header.body.appendBody(\"public:\\n\")\n        let nonMethodsTypealiases = generator.typealiases.filter { !$0.isOnMethod }\n        if !nonMethodsTypealiases.isEmpty {\n            for cppTypealias in nonMethodsTypealiases {\n                generator.header.body.appendBody(cppTypealias.statement.resolve(classNamespace))\n            }\n            generator.header.body.appendBody(\"\\n\")\n        }\n\n        let ctor = makeClassWriter()\n\n        generator.header.body.appendBody(ctor.header)\n        generator.header.body.appendBody(methodsDecl)\n        generator.header.body.appendBody(registerClassHeader)\n\n        let marshallWriter = makeClassWriter()\n\n        generator.header.body.appendBody(marshallWriter.header)\n        generator.header.body.appendBody(\"};\\n\")\n\n        ctor.writeConstructor(arguments: [], memberInitializerList: \"\\(parentClassName)(getRegisteredClass())\") { writer in\n        }\n\n        /* Impl generation */\n\n        generator.impl.body.appendBody(\"class \\(proxyClassName): public \\(cppType.declaration.name) {\\n\")\n        generator.impl.body.appendBody(\"public:\\n\")\n\n        let methodsTypealiases = generator.typealiases.filter { $0.isOnMethod }\n        if !methodsTypealiases.isEmpty {\n            for cppTypealias in methodsTypealiases {\n                generator.impl.body.appendBody(cppTypealias.statement.resolve(classNamespace))\n            }\n            generator.impl.body.appendBody(\"\\n\")\n        }\n\n        generator.impl.body.appendBody(\"\\(proxyClassName)() = default;\\n\")\n        generator.impl.body.appendBody(\"~\\(proxyClassName)() override = default;\\n\\n\")\n        generator.impl.body.appendBody(methodsImpl)\n\n        let proxyUnmarshallWriter = CppClassWriter(namespace: cppType.declaration.namespace, className: proxyClassName, header: generator.impl.body, impl: generator.impl.body, inlineImplementation: true)\n        proxyUnmarshallWriter.writeMethod(name: \"unmarshall\",\n                                          arguments: [\n                                            CPPFunctionArgument(typeResolver: exceptionTrackerType, name: \"exceptionTracker\"),\n                                            CPPFunctionArgument(typeResolver: .with(specifiers: .constRef, valueType), name: \"value\"),\n                                            CPPFunctionArgument(typeResolver: .with(specifiers: .ref, CppCodeGenerator.makeRefType(typeName: .with(typeName: proxyClassName))), name: \"out\")\n                                          ],\n                                          returnType: .with(typeName: \"void\"),\n                                          specifiers: .static_) { writer in\n            let fieldsReferenceArguments = generateFieldsReferenceArgument(cppProperties: cppProperties)\n            writer.appendBody(\"out = Valdi::makeShared<\\(proxyClassName)>();\\n\")\n            if !cppProperties.isEmpty {\n                writer.appendBody(\"auto &self = *out;\\n\")\n            }\n            writer.appendBody(\"Valdi::CppMarshaller::unmarshallTypedObject(exceptionTracker, *getRegisteredClass(), value\\(fieldsReferenceArguments));\\n\")\n        }\n\n        marshallWriter.writeMethod(name: \"unmarshall\",\n                                   arguments: [\n                                        CPPFunctionArgument(typeResolver: exceptionTrackerType, name: \"exceptionTracker\"),\n                                        CPPFunctionArgument(typeResolver: .with(specifiers: .constRef, valueType), name: \"value\"),\n                                        CPPFunctionArgument(typeResolver: .with(specifiers: .ref, cppTypeRefType), name: \"out\")\n                                   ],\n                                   returnType: .with(typeName: \"void\"),\n                                   specifiers: .static_) { writer in\n            writer.appendBody(\"Valdi::CppMarshaller::unmarshallProxyObject<\\(proxyClassName)>(exceptionTracker, *getRegisteredClass(), value, out);\\n\")\n        }\n\n        marshallWriter.writeMethod(name: \"marshall\",\n                                   arguments: [\n                                        CPPFunctionArgument(typeResolver: exceptionTrackerType, name: \"exceptionTracker\"),\n                                        CPPFunctionArgument(typeResolver: .with(specifiers: .constRef, cppTypeRefType), name: \"value\"),\n                                        CPPFunctionArgument(typeResolver: .with(specifiers: .ref, valueType), name: \"out\")\n                                   ],\n                                   returnType: .with(typeName: \"void\"),\n                                   specifiers: .static_) { writer in\n            let methodsReferenceArguments = generateMethodsReferenceArgument(receiverArgument: \"value\", cppProperties: cppProperties)\n            writer.appendBody(\"\"\"\n                Valdi::CppMarshaller::marshallProxyObject(exceptionTracker, *getRegisteredClass(), *value, out, [&]() {\n                   Valdi::CppMarshaller::marshallTypedObject(exceptionTracker, *getRegisteredClass(), out\\(methodsReferenceArguments));\n                });\n\n                \"\"\")\n        }\n\n        generator.impl.body.appendBody(\"private:\\n\")\n        generator.impl.body.appendBody(fieldsDeclaration)\n        generator.impl.body.appendBody(\"};\\n\\n\")\n\n        generator.impl.body.appendBody(ctor.impl)\n\n        generator.impl.body.appendBody(marshallWriter.impl)\n\n        generator.impl.body.appendBody(registerClassBody)\n    }\n\n    func write() throws -> [NativeSource] {\n        let namespace = cppType.declaration.namespace\n        let classNamespace = namespace.appending(component: self.cppType.declaration.name)\n\n        let nameAllocator = PropertyNameAllocator.forCpp()\n        let proxyClassName = nameAllocator.allocate(property: \"\\(cppType.declaration.name)Proxy\")\n\n        let proxyNamespace = namespace.appending(component: proxyClassName.name)\n\n        let generator = CppCodeGenerator(namespace: namespace,\n                                         selfIncludePath: cppType.includePath,\n                                         namespaceResolver: CppCodeGeneratorModelNamespaceResolver(classNamespace: classNamespace,\n                                                                                                   proxyNamespace: proxyNamespace,\n                                                                                                   isInterface: isInterface))\n        [\"getRegisteredClass\", \"registeredClass\"].forEach {\n            _ = nameAllocator.allocate(property: $0)\n        }\n\n        generator.header.includeSection.addInclude(path: \"valdi_core/cpp/Marshalling/CppGeneratedClass.hpp\")\n\n        generator.impl.includeSection.addInclude(path: cppType.includePath)\n        if typeParameters != nil {\n            generator.header.includeSection.addInclude(path: \"valdi_core/cpp/Marshalling/CppMarshaller.hpp\")\n        } else {\n            generator.impl.includeSection.addInclude(path: \"valdi_core/cpp/Marshalling/CppMarshaller.hpp\")\n        }\n\n        let cppProperties = try resolveProperties(codeGenerator: generator, nameAllocator: nameAllocator)\n\n        if isInterface {\n            try writeInterface(classNamespace: classNamespace,\n                               generator: generator,\n                               proxyClassName: proxyClassName.name,\n                               proxyNamespace: proxyNamespace,\n                               nameAllocator: nameAllocator,\n                               cppProperties: cppProperties)\n        } else {\n            try writeClass(classNamespace: classNamespace,\n                           generator: generator,\n                           cppProperties: cppProperties)\n        }\n\n        return [\n            NativeSource(relativePath: cppType.includeDir,\n                         filename: \"\\(cppType.declaration.name).hpp\",\n                         file: .data(try generator.header.content.indented.utf8Data()),\n                         groupingIdentifier: \"\\(bundleInfo.name).hpp\", groupingPriority: 0, localFilenameDependencies: generator.dependenciesInSameHeaderFile),\n            NativeSource(relativePath: cppType.includeDir,\n                         filename: \"\\(cppType.declaration.name).cpp\",\n                         file: .data(try generator.impl.content.indented.utf8Data()),\n                         groupingIdentifier: \"\\(bundleInfo.name).cpp\", groupingPriority: 0)\n        ]\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/ExportedEnumGenerator.swift",
    "content": "//\n//  ExportedEnumGenerator.swift\n//  BlueSocket\n//\n//  Created by saniul on 25/03/2019.\n//\n\nimport Foundation\n\nstruct ExportedEnum {\n    let iosType: IOSType?\n    let androidTypeName: String?\n    let cppType: CPPType?\n\n    enum Cases {\n        case `enum`([EnumCase<Int>])\n        case stringEnum([EnumCase<String>])\n    }\n    let cases: Cases\n    let comments: String?\n}\n\nfinal class ExportedEnumGenerator: NativeSourceGenerator {\n\n    private let exportedEnum: ExportedEnum\n\n    init(exportedEnum: ExportedEnum) {\n        self.exportedEnum = exportedEnum\n    }\n\n    func generateSwiftSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource] {\n        let iosGenerator = SwiftEnumGenerator(iosType: type,\n                                             exportedEnum: exportedEnum,\n                                              classMapping: parameters.classMapping,\n                                              sourceFileName: parameters.sourceFileName,\n                                              bundleInfo: parameters.bundleInfo)\n\n        return try iosGenerator.write()\n    }\n\n    func generateObjCSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource] {\n        let iosGenerator = ObjCEnumGenerator(iosType: type,\n                                             exportedEnum: exportedEnum,\n                                             classMapping: parameters.classMapping,\n                                             sourceFileName: parameters.sourceFileName,\n                                             bundleInfo: parameters.bundleInfo)\n\n        return try iosGenerator.write()\n    }\n\n    func generateKotlinSources(parameters: NativeSourceParameters, fullTypeName: String) throws -> [NativeSource] {\n        let androidGenerator = KotlinEnumGenerator(bundleInfo: parameters.bundleInfo,\n                                                   fullTypeName: fullTypeName,\n                                                   exportedEnum: exportedEnum,\n                                                   classMapping: parameters.classMapping,\n                                                   sourceFileName: parameters.sourceFileName)\n\n        return try androidGenerator.write()\n    }\n\n    func generateCppSources(parameters: NativeSourceParameters, cppType: CPPType) throws -> [NativeSource] {\n        let cppGenerator = CppEnumGenerator(exportedEnum: exportedEnum,\n                                            cppType: cppType,\n                                            bundleInfo: parameters.bundleInfo,\n                                            sourceFileName: parameters.sourceFileName)\n        return try cppGenerator.write()\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/KotlinEnumGenerator.swift",
    "content": "//\n//  KotlinViewModelGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class KotlinEnumGenerator {\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let exportedEnum: ExportedEnum\n    private let classMapping: ResolvedClassMapping\n\n    private let writer: KotlinCodeGenerator\n    private let jvmClass: JVMClass\n    private let sourceFileName: GeneratedSourceFilename\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         fullTypeName: String,\n         exportedEnum: ExportedEnum,\n         classMapping: ResolvedClassMapping, \n         sourceFileName: GeneratedSourceFilename) {\n        self.bundleInfo = bundleInfo\n        self.exportedEnum = exportedEnum\n        self.classMapping = classMapping\n\n        jvmClass = JVMClass(fullClassName: fullTypeName)\n        self.writer = KotlinCodeGenerator(package: jvmClass.package, classMapping: classMapping)\n        self.sourceFileName = sourceFileName\n    }\n\n    func write() throws -> [NativeSource] {\n        try write(className: jvmClass.name, writer: writer)\n\n        let data = try writer.content.indented(indentPattern: \"    \").utf8Data()\n\n        return [KotlinCodeGenerator.makeNativeSource(bundleInfo: bundleInfo, jvmClass: jvmClass, file: .data(data))]\n    }\n\n    private func write<T>(className: String,\n                          writer: KotlinCodeGenerator,\n                          enumType: String,\n                          objectType: KotlinMarshallableObjectDescriptorAnnotation.ObjectType,\n                          cases: [EnumCase<T>],\n                          getCaseStringValue: (Int, EnumCase<T>) -> String) throws {\n        writer.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: exportedEnum.comments))\n        writer.appendBody(\"\\n\")\n\n        let importedEnumType = try writer.importClass(\"com.snap.valdi.schema.ValdiEnumType\")\n        let valdiEnumUtils = try writer.importClass(\"com.snap.valdi.utils.ValdiEnumUtils\")\n\n        let descriptorAnnotation = try writer.getDescriptorAnnotation(type: objectType, typeParameters: nil, additionalParameters: [\n            (\"type\", \"\\(importedEnumType.name).\\(enumType.uppercased())\")\n        ])\n\n        writer.appendBody(descriptorAnnotation)\n        writer.appendBody(\"enum class \\(className) {\\n\")\n        for (idx, c) in cases.enumerated() {\n            let isLastCase = idx == cases.count - 1\n            let commaOrSemicolon = isLastCase ? \";\" : \",\"\n            // NOTE: c.value already contains quotes\n            if let comments = c.comments {\n                writer.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: comments))\n                writer.appendBody(\"\\n\")\n            }\n            let fieldAnnotationContent = try descriptorAnnotation.appendField(propertyIndex: idx, propertyName: c.name, kotlinFieldName: c.name, expectedKotlinFieldName: c.name, schemaBuilder: { schemaWriter in\n                let enumValue = getCaseStringValue(idx, c)\n                schemaWriter.appendEnumValue(enumValue)\n            })\n            writer.appendBody(fieldAnnotationContent)\n            writer.appendBody(\"\\(c.name)\\(commaOrSemicolon)\\n\")\n        }\n\n        writer.appendBody(\"\\nval value: \\(enumType)\\n\")\n        writer.appendBody(\"get() = \\(valdiEnumUtils.name).getEnum\\(enumType)Value(this)\\n\\n\")\n\n        writer.appendBody(\"}\\n\")\n    }\n\n    private func write(className: String, writer: KotlinCodeGenerator) throws {\n        switch exportedEnum.cases {\n        case .enum(let cases):\n            try write(className: className, writer: writer, enumType: \"Int\", objectType: KotlinMarshallableObjectDescriptorAnnotation.ObjectType.intEnum, cases: cases, getCaseStringValue: { _, c in\n                return \"\\(c.value)\"\n            })\n        case .stringEnum(let cases):\n            try write(className: className, writer: writer, enumType: \"String\", objectType: KotlinMarshallableObjectDescriptorAnnotation.ObjectType.stringEnum, cases: cases, getCaseStringValue: { _, c in\n                return \"'\\(c.value)'\"\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/KotlinFactoryGenerator.swift",
    "content": "//\n//  KotlinFactoryGenerator.swift\n//\n//\n//  Created by Dorit Rein on 5/18/23.\n//\nimport Foundation\n\nprivate struct KotlinProperty {\n    let propertyName: String\n    let fieldName: String\n    let modelProperty: ValdiModelProperty\n}\n\nfinal class KotlinFactoryGenerator {\n    private let typeParameters: [ValdiTypeParameter]?\n    private let properties: [ValdiModelProperty]\n    private let writer: KotlinCodeGenerator\n    private let jvmClass: JVMClass\n    private let sourceFileName: GeneratedSourceFilename\n    private let nameAllocator = PropertyNameAllocator.forKotlin()\n\n    init(jvmClass: JVMClass, typeParameters: [ValdiTypeParameter]?, properties: [ValdiModelProperty], classMapping: ResolvedClassMapping, sourceFileName: GeneratedSourceFilename) {\n        self.typeParameters = typeParameters\n        self.properties = properties\n        self.sourceFileName = sourceFileName\n\n        self.jvmClass = jvmClass\n        self.writer = KotlinCodeGenerator(package: jvmClass.package, classMapping: classMapping)\n    }\n\n    private struct ConstructorParameter {\n        let typeParser: KotlinTypeParser\n        let name: String\n        let typeName: String\n        let fieldName: String\n        let parameterToField: String\n    }\n\n    private struct CreateMethodParameter {\n        let typeParser: KotlinTypeParser\n        let name: String\n        let typeName: String\n        let fieldName: String\n        let injectable: Bool\n        let isOptional: Bool\n    }\n\n    private func generateConstructor(parameters: [ConstructorParameter]) throws -> CodeWriter {\n        let constructorBody = KotlinCodeGenerator()\n\n        var constructorParameters = [String]()\n\n        for parameter in parameters {\n            let constructorParameter = \"\\(parameter.name): \\(parameter.typeName)\"\n            constructorParameters.append(constructorParameter)\n            constructorBody.appendBody(parameter.fieldName)\n            constructorBody.appendBody(\" = \")\n            constructorBody.appendBody(parameter.parameterToField)\n            constructorBody.appendBody(\"\\n\")\n        }\n\n        let constructor = KotlinCodeGenerator()\n        let injectClass = try writer.importClass(\"javax.inject.Inject\")\n\n        constructor.appendBody(\"@\\(injectClass.name) constructor(\\(constructorParameters.joined(separator: \", \"))) {\\n\")\n        constructor.appendBody(constructorBody)\n        constructor.appendBody(\"}\\n\\n\")\n\n        return constructor\n    }\n\n    private func generateCreateMethod(name: String,\n                                      createMethodName: String,\n                                      parameters: [CreateMethodParameter],\n                                      indicesToOmit: Set<Int>) throws -> CodeWriter {\n        var createMethodParameters = [String]()\n        let createMethodBody = KotlinCodeGenerator()\n        createMethodBody.appendBody(\"return \\(name)(\\n\")\n\n        for (index, parameter) in parameters.enumerated() {\n            let isOmitted = indicesToOmit.contains(index)\n\n            if !isOmitted && !parameter.injectable {\n                createMethodParameters.append(\"\\(parameter.name): \\(parameter.typeName)\")\n            }\n\n            createMethodBody.appendBody(parameter.name)\n\n            if !isOmitted {\n                createMethodBody.appendBody(\" = \\(parameter.name),\\n\")\n            } else {\n                createMethodBody.appendBody(\" = null,\\n\")\n            }\n        }\n\n        createMethodBody.appendBody(\")\\n\")\n\n        let createMethod = KotlinCodeGenerator()\n\n        createMethod.appendBody(\"fun \\(createMethodName)(\\(createMethodParameters.joined(separator: \", \"))): \\(name) {\\n\")\n        createMethod.appendBody(createMethodBody)\n        createMethod.appendBody(\"}\\n\\n\")\n\n        return createMethod\n    }\n\n    private func resolveProperties(valdiProperties: [ValdiModelProperty]) -> [KotlinProperty] {\n        return valdiProperties.map { valdiProperty in\n            let propertyName = nameAllocator.allocate(property: valdiProperty.name).name\n            let fieldName = nameAllocator.allocate(property: \"_\\(valdiProperty.name)\").name\n\n            return KotlinProperty(propertyName: propertyName,\n                                  fieldName: fieldName,\n                                  modelProperty: valdiProperty)\n        }\n    }\n\n    private func writeConstructors(writer: KotlinCodeGenerator,\n                                   constructors: CodeWriter,\n                                   constructorParameters: [ConstructorParameter]) throws {\n        let constructorAnnotation = try writer.getJavaAnnotationContent(annotationType: \"com.snap.valdi.schema.ValdiClassConstructor\")\n        constructors.appendBody(constructorAnnotation)\n        try constructors.appendBody(generateConstructor(parameters: constructorParameters))\n    }\n\n    private func writeCreateMethod(fieldsBody: CodeWriter,\n                                   name: String,\n                                   parameters: [CreateMethodParameter]) throws {\n        try fieldsBody.appendBody(generateCreateMethod(name: name, createMethodName: \"create\", parameters: parameters, indicesToOmit: []))\n\n        // Generate alternate create method parameters\n        let alternateParameters = parameters.map { CreateMethodParameter(typeParser: $0.typeParser,\n                                                                         name: $0.name,\n                                                                         typeName: $0.typeName,\n                                                                         fieldName: $0.fieldName,\n                                                                         injectable: $0.injectable,\n                                                                         isOptional: $0.isOptional) }\n\n        var indicesToOmit: Set<Int> = []\n        for index in 0..<alternateParameters.count {\n            let resolvedNameAndType = alternateParameters[index]\n            if resolvedNameAndType.isOptional && !resolvedNameAndType.injectable {\n                indicesToOmit.insert(index)\n            }\n        }\n        if !alternateParameters.isEmpty && indicesToOmit.count > 0 {\n            let createMethod = try generateCreateMethod(name: name,\n                                                        createMethodName: \"createWithNullDefaults\",\n                                                        parameters: alternateParameters,\n                                                        indicesToOmit: indicesToOmit)\n            fieldsBody.appendBody(\"\\n\")\n            fieldsBody.appendBody(createMethod)\n        }\n    }\n\n    private func write(className: String, properties: [ValdiModelProperty], writer: KotlinCodeGenerator) throws {\n        let marshallableObjectClass = try writer.importClass(\"com.snap.valdi.utils.ValdiMarshallableObject\")\n\n        let constructors = CodeWriter()\n        let propertiesBody = CodeWriter()\n        let fieldsBody = CodeWriter()\n\n        writer.appendBody(\"\\n\")\n        writer.appendBody(FileHeaderCommentGenerator.generateFactoryHeaderMessage(className: className,\n                                                                                  sourceFilename: sourceFileName))\n        writer.appendBody(\"\\n\")\n\n        let descriptorAnnotation = try writer.getDescriptorAnnotation(type: KotlinMarshallableObjectDescriptorAnnotation.ObjectType.valdiClass, typeParameters: typeParameters, additionalParameters: [])\n\n        writer.appendBody(descriptorAnnotation)\n        writer.appendBody(\"class \\(className)Factory: \\(marshallableObjectClass.name) {\\n\\n\")\n        writer.appendBody(propertiesBody)\n        writer.appendBody(\"\\n\\n\")\n        writer.appendBody(fieldsBody)\n        writer.appendBody(\"\\n\\n\")\n        writer.appendBody(constructors)\n        writer.appendBody(\"}\")\n\n        // add all properties to constructor\n        let kotlinProperties = resolveProperties(valdiProperties: properties)\n\n        var resolvedNamesAndTypesForConstructor = [ConstructorParameter]()\n        var resolvedNamesAndTypesForProperties = [CreateMethodParameter]()\n\n        for (propertyIndex, kotlinProperty) in kotlinProperties.enumerated() {\n            let property = kotlinProperty.modelProperty\n            let isOptional = property.type.isOptional\n            let propertyName = kotlinProperty.propertyName\n            let typeParser = try writer.getTypeParser(type: property.type.unwrappingOptional,\n                                                      isOptional: isOptional,\n                                                      propertyName: kotlinProperty.modelProperty.name,\n                                                      nameAllocator: nameAllocator.scoped())\n\n            // only add injected properties to constructor\n            if property.injectableParams.compatibility.contains(.android) {\n                propertiesBody.appendBody(\"var \\(propertyName): \\(typeParser.fullTypeName)\\n\")\n                propertiesBody.appendBody(\"    get() = \\(kotlinProperty.fieldName)\\n\")\n                propertiesBody.appendBody(\"    set(value) { \\(kotlinProperty.fieldName) = value }\\n\\n\")\n\n                resolvedNamesAndTypesForConstructor.append(ConstructorParameter(\n                    typeParser: typeParser,\n                    name: property.name,\n                    typeName: typeParser.fullTypeName,\n                    fieldName: kotlinProperty.fieldName,\n                    parameterToField: property.name))\n            }\n\n            let fieldAnnotation = try descriptorAnnotation.appendField(propertyIndex: propertyIndex, propertyName: property.name, kotlinFieldName: kotlinProperty.fieldName, expectedKotlinFieldName: \"_\\(property.name)\", schemaBuilder: { schemaWriter in\n                try schemaWriter.appendType(property.type, asBoxed: false, isMethod: false)\n            })\n\n            if property.injectableParams.compatibility.contains(.android) {\n                fieldsBody.appendBody(fieldAnnotation)\n                fieldsBody.appendBody(\"private var \\(kotlinProperty.fieldName ): \\(typeParser.fullTypeName)\\n\\n\")\n            }\n\n            resolvedNamesAndTypesForProperties.append(CreateMethodParameter(\n                typeParser: typeParser,\n                name: property.name,\n                typeName: typeParser.fullTypeName,\n                fieldName: kotlinProperty.fieldName,\n                injectable: property.injectableParams.compatibility.contains(.android),\n                isOptional: property.type.isOptional))\n        }\n\n        try writeConstructors(writer: writer,\n                              constructors: constructors,\n                              constructorParameters: resolvedNamesAndTypesForConstructor)\n        try writeCreateMethod(fieldsBody: fieldsBody,\n                              name: className,\n                              parameters: resolvedNamesAndTypesForProperties)\n    }\n\n    func write() throws -> File {\n        try write(className: jvmClass.name, properties: properties, writer: writer)\n\n        let data = try writer.content.indented(indentPattern: \"    \").utf8Data()\n        return .data(data)\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/KotlinModelGenerator.swift",
    "content": "//\n//  KotlinViewModelGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nprivate struct KotlinProperty {\n    let propertyName: String\n    let fieldName: String\n    let getterName: String?\n    let modelProperty: ValdiModelProperty\n}\n\nprivate struct KotlinGenericTypeInfo {\n    let typeName: String\n}\n\nprivate struct KotlinTypeParameter {\n    let typeParameterName: String\n    let valdiTypeParameter: ValdiTypeParameter\n}\n\nfinal class KotlinModelGenerator {\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let typeParameters: [ValdiTypeParameter]?\n    private let properties: [ValdiModelProperty]\n    private let classMapping: ResolvedClassMapping\n    private let writer: KotlinCodeGenerator\n    private let jvmClass: JVMClass\n    private let sourceFileName: GeneratedSourceFilename\n    private let isInterface: Bool\n    private let emitLegacyConstructors: Bool\n    private let comments: String?\n    private let usePublicFields: Bool\n    private let nameAllocator = PropertyNameAllocator.forKotlin()\n\n    init(bundleInfo: CompilationItem.BundleInfo,\n         className: String,\n         typeParameters: [ValdiTypeParameter]?,\n         properties: [ValdiModelProperty],\n         classMapping: ResolvedClassMapping,\n         sourceFileName: GeneratedSourceFilename,\n         isInterface: Bool,\n         emitLegacyConstructors: Bool,\n         comments: String?,\n         usePublicFields: Bool = false) {\n        \n        self.bundleInfo = bundleInfo\n        self.typeParameters = typeParameters\n        self.properties = properties\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.isInterface = isInterface\n        self.emitLegacyConstructors = emitLegacyConstructors\n        self.comments = comments\n        self.usePublicFields = usePublicFields\n\n        jvmClass = JVMClass(fullClassName: className)\n        self.writer = KotlinCodeGenerator(package: jvmClass.package, classMapping: classMapping)\n    }\n\n    private struct ConstructorParameter {\n        let typeParser: KotlinTypeParser\n        let name: String\n        let typeName: String\n        let fieldName: String\n        let parameterToField: String\n        let isFunction: Bool\n        let isOptional: Bool\n        let constructorOmitted: Bool\n    }\n\n    private func generateConstructor(parameters: [ConstructorParameter],\n                                     indexesToOmit: Set<Int>) -> CodeWriter {\n                                        \n        let constructorBody = KotlinCodeGenerator()\n\n        var constructorParameters = [String]()\n\n        for (index, parameter) in parameters.enumerated() {\n            let isOmitted = indexesToOmit.contains(index)\n\n            if !isOmitted {\n                let constructorParameter = \"\\(parameter.name): \\(parameter.typeName)\\(parameter.isOptional ? \" = null\" : \"\")\"\n                constructorParameters.append(constructorParameter)\n                constructorBody.appendBody(\"this.\" + parameter.fieldName)\n                constructorBody.appendBody(\" = \")\n                constructorBody.appendBody(parameter.parameterToField)\n                constructorBody.appendBody(\"\\n\")\n            } else {\n                constructorBody.appendBody(\"this.\" + parameter.fieldName)\n                constructorBody.appendBody(\" = null\\n\")\n            }\n        }\n\n        let constructor = KotlinCodeGenerator()\n        constructor.appendBody(\"constructor(\\(constructorParameters.joined(separator: \", \"))) {\\n\")\n        constructor.appendBody(constructorBody)\n        constructor.appendBody(\"}\\n\\n\")\n\n        return constructor\n    }\n\n    private func resolveTypeParameters(typeParameters: [ValdiTypeParameter]?) -> [KotlinTypeParameter]? {\n        guard let typeParameters = typeParameters else { return nil }\n\n        return typeParameters.map {\n            let allocatedName = nameAllocator.allocate(property: $0.name).name\n            return KotlinTypeParameter(typeParameterName: allocatedName, valdiTypeParameter: $0)\n        }\n    }\n\n    private func resolvePropertyGetterName(propertyName: String) -> String {\n        if propertyName.hasPrefix(\"is\") && propertyName[propertyName.index(propertyName.startIndex, offsetBy: 2)].isUppercase {\n            return propertyName\n        } else {\n            return\"get\\(propertyName.pascalCased)\"\n        }\n    }\n\n    private func resolveProperties(valdiProperties: [ValdiModelProperty]) -> [KotlinProperty] {\n        return valdiProperties.map {\n            let propertyName = nameAllocator.allocate(property: $0.name).name\n            let fieldName = nameAllocator.allocate(property: \"_\\($0.name)\").name\n            let getterFieldName: String?\n\n            if isInterface && !$0.type.unwrappingOptional.isFunction {\n                let resolvedGetterFieldName = resolvePropertyGetterName(propertyName: $0.name)\n                if resolvedGetterFieldName != $0.name {\n                    getterFieldName = nameAllocator.allocate(property: resolvedGetterFieldName).name\n                } else {\n                    getterFieldName = resolvedGetterFieldName\n                }\n            } else {\n                getterFieldName = nil\n            }\n\n            return KotlinProperty(propertyName: propertyName,\n                                  fieldName: fieldName,\n                                  getterName: getterFieldName,\n                                  modelProperty: $0)\n        }\n    }\n\n    private func appendNextOmittedParameter(constructors: [ConstructorParameter], indexesToOmit: inout Set<Int>) -> Bool {\n        for index in (0..<constructors.count).reversed() {\n            let constructor = constructors[index]\n            guard constructor.constructorOmitted else { continue }\n\n            if !indexesToOmit.contains(index) {\n                indexesToOmit.insert(index)\n                return true\n            }\n        }\n\n        return false\n    }\n\n    private func shouldGenerateAlternateMainConstructor(constructorParameters: [ConstructorParameter], alternateConstructorParameters: [ConstructorParameter]) -> Bool {\n        for index in 0..<constructorParameters.count {\n            if constructorParameters[index].typeName != alternateConstructorParameters[index].typeName {\n                return true\n            }\n        }\n\n        return false\n    }\n\n    private func writeConstructors(writer: KotlinCodeGenerator,\n                                   constructors: CodeWriter,\n                                   constructorParameters: [ConstructorParameter]) throws {\n        // Check if number of parameters exceeds Java's 255 parameter limit\n        if constructorParameters.count > 250 {\n            throw CompilerError(\"Too many constructor parameters: \\(constructorParameters.count). Maximum allowed is 250 parameters to avoid Java bytecode limitations.\")\n        }\n        \n        // Generate main constructor\n        let constructorAnnotation = try writer.getJavaAnnotationContent(annotationType: \"com.snap.valdi.schema.ValdiClassConstructor\")\n        constructors.appendBody(constructorAnnotation)\n        constructors.appendBody(generateConstructor(parameters: constructorParameters, indexesToOmit: []))\n\n        // Generate alternate constructor parameters\n        let alternateConstructorParameters = constructorParameters.map { ConstructorParameter(typeParser: $0.typeParser,\n                                                                                              name: $0.name,\n                                                                                              typeName: $0.typeParser.fullTypeName,\n                                                                                              fieldName: $0.fieldName,\n                                                                                              parameterToField: $0.name,\n                                                                                              isFunction: $0.isFunction,\n                                                                                              isOptional: $0.isOptional,\n                                                                                              constructorOmitted: $0.constructorOmitted) }\n\n        if emitLegacyConstructors {\n            // Generate constructors using the legacy technique\n            var indexesToOmit: Set<Int> = []\n\n            if !constructorParameters.isEmpty {\n                if shouldGenerateAlternateMainConstructor(constructorParameters: constructorParameters, alternateConstructorParameters: alternateConstructorParameters) {\n                    let mainConstructor = generateConstructor(parameters: alternateConstructorParameters, indexesToOmit: indexesToOmit)\n                    constructors.appendBody(\"\\n\")\n                    constructors.appendBody(mainConstructor)\n                }\n\n                while appendNextOmittedParameter(constructors: alternateConstructorParameters, indexesToOmit: &indexesToOmit) {\n                    let alternateConstructor = generateConstructor(parameters: alternateConstructorParameters, indexesToOmit: indexesToOmit)\n                    constructors.appendBody(\"\\n\\n\")\n                    constructors.appendBody(alternateConstructor)\n                }\n            }\n        } else {\n            // Generate constructors using the new recommended minimal constructors technique\n            var indexesToOmit: Set<Int> = []\n            for index in 0..<alternateConstructorParameters.count {\n                let resolvedNameAndType = alternateConstructorParameters[index]\n                if resolvedNameAndType.isOptional {\n                    indexesToOmit.insert(index)\n                }\n            }\n            if !alternateConstructorParameters.isEmpty {\n                if indexesToOmit.count > 0 || shouldGenerateAlternateMainConstructor(constructorParameters: constructorParameters, alternateConstructorParameters: alternateConstructorParameters) {\n                    let mainConstructor = generateConstructor(parameters: alternateConstructorParameters, indexesToOmit: indexesToOmit)\n                    constructors.appendBody(\"\\n\")\n                    constructors.appendBody(mainConstructor)\n                }\n            }\n        }\n    }\n\n    private func write(className: String, properties: [ValdiModelProperty], writer: KotlinCodeGenerator, usePublicFields: Bool) throws {\n        let marshallableObjectClass = try writer.importClass(\"com.snap.valdi.utils.ValdiMarshallableObject\")\n\n        let fullTypeName: String\n        if let typeParameters = self.typeParameters, !typeParameters.isEmpty {\n            let typeParamList = \"<\\(typeParameters.map(\\.name).joined(separator: \", \"))>\"\n            fullTypeName = \"\\(className)\\(typeParamList)\"\n        } else {\n            fullTypeName = className\n        }\n\n        let constructors = CodeWriter()\n        let propertiesBody = CodeWriter()\n        let fieldsBody = CodeWriter()\n\n        writer.appendBody(\"\\n\")\n        writer.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: comments))\n        writer.appendBody(\"\\n\")\n\n        let descriptorAnnotation: KotlinMarshallableObjectDescriptorAnnotation\n\n        // ValdiMarshallableObject implements DisposablePrivate so we need to reserve the __dispose__() method\n        _ = nameAllocator.allocate(property: \"__dispose__\")\n\n        if isInterface {\n            let proxyClassName = nameAllocator.allocate(property: \"\\(fullTypeName)_Proxy\").name\n            let marshallableInterface = try writer.importClass(\"com.snap.valdi.utils.ValdiMarshallable\").name\n\n            descriptorAnnotation = try writer.getDescriptorAnnotation(type: KotlinMarshallableObjectDescriptorAnnotation.ObjectType.valdiInterface, typeParameters: typeParameters, additionalParameters: [(\"proxyClass\", \"\\(proxyClassName)::class\")])\n\n            writer.appendBody(descriptorAnnotation)\n            writer.appendBody(\"interface \\(fullTypeName): \\(marshallableInterface) {\\n\\n\")\n            writer.appendBody(propertiesBody)\n\n            let marshallerClass = try writer.importClass(\"com.snap.valdi.utils.ValdiMarshaller\").name\n            writer.appendBody(\"\"\"\n\n            override fun pushToMarshaller(marshaller: \\(marshallerClass)) = \\(marshallableObjectClass.name).marshall(\\(fullTypeName)::class.java, marshaller, this)\n            \\n\n            \"\"\")\n\n            writer.appendBody(\"}\\n\\n\")\n\n            writer.appendBody(\"class \\(proxyClassName): \\(fullTypeName) {\\n\\n\")\n            writer.appendBody(fieldsBody)\n            writer.appendBody(\"\\n\\n\")\n            writer.appendBody(constructors)\n            writer.appendBody(\"}\")\n        } else {\n            descriptorAnnotation = try writer.getDescriptorAnnotation(type: KotlinMarshallableObjectDescriptorAnnotation.ObjectType.valdiClass, typeParameters: typeParameters, additionalParameters: [])\n\n            writer.appendBody(descriptorAnnotation)\n            writer.appendBody(\"class \\(fullTypeName): \\(marshallableObjectClass.name) {\\n\\n\")\n            writer.appendBody(propertiesBody)\n            writer.appendBody(\"\\n\\n\")\n            writer.appendBody(fieldsBody)\n            writer.appendBody(\"\\n\\n\")\n            writer.appendBody(constructors)\n            writer.appendBody(\"}\")\n        }\n\n        let kotlinProperties = resolveProperties(valdiProperties: properties)\n\n        var resolvedNamesAndTypes = [ConstructorParameter]()\n        for (propertyIndex, kotlinProperty) in kotlinProperties.enumerated() {\n            let propertyName = kotlinProperty.propertyName\n            let property = kotlinProperty.modelProperty\n            let isOptional = property.type.isOptional\n\n            let typeParser = try writer.getTypeParser(type: property.type.unwrappingOptional,\n                                                      isOptional: isOptional,\n                                                      propertyName: kotlinProperty.modelProperty.name,\n                                                      nameAllocator: nameAllocator.scoped())\n\n            let isFunction = property.type.unwrappingOptional.isFunction\n\n            if let comments = property.comments {\n                if usePublicFields {\n                    // For public fields, place comments directly above the field declaration\n                    fieldsBody.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: comments))\n                    fieldsBody.appendBody(\"\\n\")\n                } else {\n                    // For traditional approach, place comments in properties body\n                    propertiesBody.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: comments))\n                    propertiesBody.appendBody(\"\\n\")\n                }\n            }\n\n            let fieldVisibility = usePublicFields ? \"var\" : \"private var\"\n            let fieldName = usePublicFields ? kotlinProperty.propertyName : kotlinProperty.fieldName\n            let publicFieldName = isInterface ? (kotlinProperty.getterName ?? kotlinProperty.propertyName) : fieldName\n            let expectedKotlinFieldName = isInterface ? (isFunction ? property.name : resolvePropertyGetterName(propertyName: property.name)) : \"_\\(property.name)\"\n\n            let fieldAnnotation = try descriptorAnnotation.appendField(propertyIndex: propertyIndex, propertyName: property.name, kotlinFieldName: publicFieldName, expectedKotlinFieldName: expectedKotlinFieldName, schemaBuilder: { schemaWriter in\n                try schemaWriter.appendType(property.type, asBoxed: false, isMethod: isInterface)\n            })\n\n            if !isInterface {\n                fieldsBody.appendBody(fieldAnnotation)\n            }\n            fieldsBody.appendBody(\"\\(fieldVisibility) \\(fieldName): \\(typeParser.fullTypeName)\\n\\n\")\n\n            if isInterface {\n                if isFunction {\n                    guard let functionTypeParser = typeParser.functionTypeParser else {\n                        throw CompilerError(\"Expected functionTypeParser for function property\")\n                    }\n                    let parameterNamesString = functionTypeParser.parameterNames.map { $0.name }.joined(separator: \", \")\n\n                    if isOptional {\n                        let optionalMethodAnnotation = try writer.getJavaAnnotationContent(annotationType: \"com.snap.valdi.schema.ValdiOptionalMethod\")\n\n                        propertiesBody.appendBody(optionalMethodAnnotation)\n                        propertiesBody.appendBody(\"\"\"\n                            fun \\(propertyName)\\(functionTypeParser.methodTypeName) {\n                              \\(marshallableObjectClass.name).unimplementedMethod()\n                            }\n                            \\n\n                            \"\"\")\n                    } else {\n                        propertiesBody.appendBody(\"fun \\(propertyName)\\(functionTypeParser.methodTypeName)\\n\\n\")\n                    }\n\n                    constructors.appendBody(fieldAnnotation)\n                    constructors.appendBody(\"override fun \\(propertyName)\\(functionTypeParser.methodTypeName) {\\n\")\n                    if isOptional {\n                        if functionTypeParser.returnType.fullTypeName == \"Unit\" {\n                            constructors.appendBody(\"    return \\(fieldName)?.invoke(\\(parameterNamesString)) ?: Unit\")\n                        } else {\n                            constructors.appendBody(\"    return \\(fieldName)!!(\\(parameterNamesString))\")\n                        }\n                    } else {\n                        constructors.appendBody(\"    return \\(fieldName)(\\(parameterNamesString))\")\n                    }\n                    constructors.appendBody(\"\\n}\\n\\n\")\n                } else {\n                    constructors.appendBody(\"override val \\(propertyName): \\(typeParser.fullTypeName)\\n\")\n                    constructors.appendBody(fieldAnnotation)\n                    constructors.appendBody(\"    get() = \\(fieldName)\\n\\n\")\n\n                    propertiesBody.appendBody(\"val \\(propertyName): \\(typeParser.fullTypeName)\\n\")\n                    if isOptional {\n                        propertiesBody.appendBody(\"    get() = null\\n\\n\")\n                    } else {\n                        propertiesBody.appendBody(\"\\n\")\n                    }\n                }\n            } else {\n                if !usePublicFields {\n                    propertiesBody.appendBody(\"var \\(propertyName): \\(typeParser.fullTypeName)\\n\")\n                    propertiesBody.appendBody(\"    get() = \\(kotlinProperty.fieldName)\\n\")\n                    propertiesBody.appendBody(\"    set(value) { \\(kotlinProperty.fieldName) = value }\\n\\n\")\n                }\n            }\n\n            let constructorOmitted = property.omitConstructor?.android == true\n\n            resolvedNamesAndTypes.append(ConstructorParameter(\n                typeParser: typeParser,\n                name: property.name,\n                typeName: typeParser.fullTypeName,\n                fieldName: fieldName,\n                parameterToField: property.name,\n                isFunction: isFunction,\n                isOptional: property.type.isOptional,\n                constructorOmitted: constructorOmitted))\n        }\n\n        try writeConstructors(writer: writer,\n                              constructors: constructors,\n                              constructorParameters: resolvedNamesAndTypes)\n    }\n\n    func write() throws -> [NativeSource] {\n        try write(className: jvmClass.name, properties: properties, writer: writer, usePublicFields: usePublicFields)\n\n        let data = try writer.content.indented(indentPattern: \"    \").utf8Data()\n        return [KotlinCodeGenerator.makeNativeSource(bundleInfo: bundleInfo, jvmClass: jvmClass, file: .data(data))]\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/ObjCEnumGenerator.swift",
    "content": "//\n//  ObjCViewModelGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class ObjCEnumGenerator {\n    private let iosType: IOSType\n    private let typeName: String\n    private let exportedEnum: ExportedEnum\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n    private let bundleInfo: CompilationItem.BundleInfo\n\n    init(iosType: IOSType, exportedEnum: ExportedEnum, classMapping: ResolvedClassMapping, sourceFileName: GeneratedSourceFilename, bundleInfo: CompilationItem.BundleInfo) {\n        self.iosType = iosType\n        self.typeName = iosType.name\n        self.exportedEnum = exportedEnum\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.bundleInfo = bundleInfo\n    }\n\n    private func containsOnlyIncreasingValues(enumCases: [EnumCase<Int>]) -> Bool {\n        let set = Set(enumCases.map { $0.value })\n\n        if set.count != enumCases.count {\n            return false\n        }\n\n        for index in 0..<enumCases.count {\n            if !set.contains(index) {\n                return false\n            }\n        }\n\n        return true\n    }\n\n    static func nullableTypeName(typename: String) -> String {\n        return \"\\(typename)_Nullable\"\n    }\n\n    private static func generateEnumCaseString(declarationString: String, comments: String?) -> String {\n        if let comments = comments {\n            let multilineComments = FileHeaderCommentGenerator.generateMultilineComment(comment: comments)\n            return \"\\(multilineComments)\\n\\(declarationString)\"\n        } else {\n            return declarationString\n        }\n    }\n\n    private func generateCode() throws -> GeneratedCode {\n        let classGenerator = ObjCClassGenerator(className: typeName)\n\n        classGenerator.header.addImport(path: \"<Foundation/Foundation.h>\")\n        // TODO(3521): Update to valdi_core\n        classGenerator.header.addImport(path: \"<valdi_core/SCValdiMarshaller.h>\")\n        classGenerator.apiImpl.addImport(path: \"<valdi_core/SCValdiMarshallableObjectRegistry.h>\")\n        classGenerator.impl.addImport(path: \"<valdi_core/SCValdiMarshallableObjectRegistry.h>\")\n        classGenerator.impl.addImport(path: \"<valdi_core/SCValdiMarshallableObject.h>\")\n\n        classGenerator.impl.addImport(path: iosType.importHeaderStatement(kind: .withUtilities))\n        classGenerator.impl.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName))\n        classGenerator.impl.appendBody(\"\\n\\n\")\n\n        classGenerator.header.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName))\n        classGenerator.header.appendBody(\"\\n\")\n\n        let comments = FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: exportedEnum.comments)\n        classGenerator.apiHeader.appendBody(comments)\n        classGenerator.apiHeader.appendBody(\"\\n\")\n\n        switch exportedEnum.cases {\n        case .enum(let cases):\n            let objcEnumCases = cases.map {\n                let caseName = typeName + $0.name\n                let declaration = \"\\(caseName) = \\($0.value)\"\n                return ObjCEnumGenerator.generateEnumCaseString(declarationString: declaration, comments: $0.comments)\n            }.joined(separator: \",\\n\")\n\n            classGenerator.apiHeader.appendBody(\"\"\"\n                typedef NS_CLOSED_ENUM(int32_t, \\(typeName)) {\n                    \\(objcEnumCases)\n                }\n                \"\"\")\n\n            classGenerator.apiHeader.appendBody(\";\\n\")\n            classGenerator.apiHeader.appendBody(\"\"\"\n                NSArray<NSNumber *> * _Nonnull \\(typeName)GetAllCases();\\n\n            \"\"\")\n\n\n            if containsOnlyIncreasingValues(enumCases: cases) {\n                classGenerator.apiImpl.appendBody(\"\"\"\n\n                VALDI_TRIVIAL_INT_ENUM(\\(typeName), \\(cases.count))\n\n                \"\"\")\n            } else {\n                let allEnumCasesBody = cases.map { typeName + $0.name }.joined(separator: \", \")\n                classGenerator.apiImpl.appendBody(\"\"\"\n\n                VALDI_INT_ENUM(\\(typeName), \\(allEnumCasesBody))\n\n                \"\"\")\n            }\n\n            classGenerator.apiImpl.appendBody(\"\\n\")\n            classGenerator.apiImpl.appendBody(\"\"\"\n            NSArray<NSNumber *> * _Nonnull \\(typeName)GetAllCases() {\n                static dispatch_once_t onceToken;\n                static NSArray<NSNumber *> *kAllCases;\n                dispatch_once(&onceToken, ^{\n                    kAllCases = @[\\(cases.map { \"@\\($0.value)\" }.joined(separator: \", \"))];\n                });\n                return kAllCases;\n            }\n            \"\"\")\n        case .stringEnum(let cases):\n            let objcEnumCases = cases.map {\n                let caseName = typeName + $0.name\n                let declaration = \"FOUNDATION_EXPORT \\(typeName) \\(caseName);\\n\"\n                return ObjCEnumGenerator.generateEnumCaseString(declarationString: declaration, comments: $0.comments)\n            }.joined()\n\n            classGenerator.apiHeader.appendBody(\"typedef NSString * _Nonnull \\(typeName) NS_STRING_ENUM\")\n            classGenerator.apiHeader.appendBody(\";\\n\")\n\n            classGenerator.apiHeader.appendBody(\"typedef NSString * _Nullable \\(ObjCEnumGenerator.nullableTypeName(typename: typeName)) NS_STRING_ENUM\")\n            classGenerator.apiHeader.appendBody(\";\\n\")\n\n            classGenerator.apiHeader.appendBody(\"\"\"\n\n                \\(objcEnumCases)\n            \"\"\")\n            classGenerator.apiHeader.appendBody(\"\\n\")\n            classGenerator.apiHeader.appendBody(\"\"\"\n                NSArray<NSString *> * _Nonnull \\(typeName)GetAllCases();\n            \"\"\")\n\n            let objcEnumCaseNames = cases.map {\n                typeName + $0.name\n            }\n\n            let objcEnumCasesImpl = cases.map {\n                let caseName = typeName + $0.name\n                return \"\\(typeName) \\(caseName) = @\\\"\\($0.value)\\\";\\n\"\n                }.joined()\n\n            classGenerator.apiImpl.appendBody(\"\"\"\n            \\(objcEnumCasesImpl)\n            \"\"\")\n\n            let allEnumCasesBody = objcEnumCaseNames.joined(separator: \", \")\n            classGenerator.apiImpl.appendBody(\"\"\"\n            VALDI_STRING_ENUM(\\(typeName), \\(allEnumCasesBody))\n            \"\"\")\n\n            classGenerator.apiImpl.appendBody(\"\\n\")\n            classGenerator.apiImpl.appendBody(\"\"\"\n            NSArray<NSString *> * _Nonnull \\(typeName)GetAllCases() {\n                static dispatch_once_t onceToken;\n                static NSArray<NSString *> *kAllCases;\n                dispatch_once(&onceToken, ^{\n                    kAllCases = @[\\(allEnumCasesBody)];\n                });\n                return kAllCases;\n            }\n            \"\"\")\n        }\n\n        return GeneratedCode(apiHeader: classGenerator.apiHeader, apiImpl: classGenerator.apiImpl, header: classGenerator.header, impl: classGenerator.impl)\n    }\n\n    func write() throws -> [NativeSource] {\n        let generatedCode = try generateCode()\n        let nativeSources = try NativeSource.iosNativeSourcesFromGeneratedCode(generatedCode,\n                                                                               iosType: iosType,\n                                                                               bundleInfo: bundleInfo)\n        return nativeSources\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/ObjCModelGenerator.swift",
    "content": "//\n//  ObjCViewModelGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 5/17/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class ObjCModelGenerator {\n    private let iosType: IOSType\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let className: String\n    private let typeParameters: [ValdiTypeParameter]?\n    private let properties: [ValdiModelProperty]\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n    private let isInterface: Bool\n    private let emitLegacyConstructors: Bool\n    private let comments: String?\n\n    init(iosType: IOSType, bundleInfo: CompilationItem.BundleInfo, typeParameters: [ValdiTypeParameter]?, properties: [ValdiModelProperty], classMapping: ResolvedClassMapping, sourceFileName: GeneratedSourceFilename, isInterface: Bool, emitLegacyConstructors: Bool, comments: String?) {\n        self.iosType = iosType\n        self.bundleInfo = bundleInfo\n        self.className = iosType.name\n        self.typeParameters = typeParameters\n        self.properties = properties\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.isInterface = isInterface\n        self.emitLegacyConstructors = emitLegacyConstructors\n        self.comments = comments\n    }\n\n    private struct ConstructorParameter {\n        let param: ObjcMessageParameter\n        let isOptional: Bool\n        let isOmitted: Bool\n    }\n\n    private func sanitizePropertyName(_ name: String) -> String {\n        if name.hasPrefix(\"new\") {\n            return \"_\\(name)\"\n        }\n        return name\n    }\n\n    private func resolveProperties(valdiProperties: [ValdiModelProperty], nameAllocator: PropertyNameAllocator) -> [ObjCProperty] {\n        return valdiProperties.map {\n            let sanitizedName = sanitizePropertyName($0.name)\n            let propertyName = nameAllocator.allocate(property: sanitizedName).name\n\n            return ObjCProperty(propertyName: propertyName, modelProperty: $0)\n        }\n    }\n\n    private func generateCode(for properties: [ValdiModelProperty], className: String) throws -> GeneratedCode {\n        let classGenerator = ObjCClassGenerator(className: className)\n\n        let nameAllocator = classGenerator.nameAllocator\n\n        _ = nameAllocator.allocate(property: className)\n\n        // TODO(3521): Update to valdi_core\n        classGenerator.apiHeader.addImport(path: \"<valdi_core/SCValdiMarshallable.h>\")\n        classGenerator.apiHeader.addImport(path: \"<valdi_core/SCValdiMarshallableObject.h>\")\n\n        // FIXME: import apiHeader into header\n        classGenerator.apiImpl.addImport(path: \"<valdi_core/SCValdiMarshallableObjectDescriptor.h>\")\n\n        classGenerator.apiHeader.appendBody(\"\\n\")\n        classGenerator.apiHeader.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: self.comments))\n        classGenerator.apiHeader.appendBody(\"\\n\")\n\n        classGenerator.impl.appendBody(\"\\n\")\n\n        let resolvedProperties = resolveProperties(valdiProperties: properties, nameAllocator: nameAllocator)\n\n        let classHeaderBody = ObjCCodeGenerator()\n        let classImplBody = ObjCCodeGenerator()\n\n        let isGenericType = self.typeParameters != nil\n\n        let instanceType: String\n\n        if isInterface {\n            classGenerator.impl.appendBody(classGenerator.emittedFunctions.emittedFunctionsSection)\n            classGenerator.apiHeader.appendBody(\"@protocol \\(className) <NSObject, SCValdiMarshallable>\\n\\n\")\n            classGenerator.apiHeader.appendBody(classHeaderBody)\n            classGenerator.apiHeader.appendBody(\"@end\\n\\n\")\n\n            classGenerator.impl.appendBody(\"@interface \\(className): SCValdiProxyMarshallableObject\\n\\n\")\n            classGenerator.impl.appendBody(\"@end\\n\\n\")\n\n            instanceType =  \"id<\\(className)> _Nonnull \"\n\n            // We also forward declare the protocol or class here in case if the typedef uses the class/protocol itself\n            classGenerator.apiHeader.addForwardDeclaration(type: \"@protocol \\(className);\")\n        } else {\n            instanceType = \"\\(className) * _Nonnull \"\n\n            classGenerator.apiImpl.appendBody(classGenerator.emittedFunctions.emittedFunctionsSection)\n\n            let typeParametersSuffix: String\n            if let typeParameters = self.typeParameters {\n                let typeParametersList = typeParameters.map { \"__covariant \\($0.name)\" }.joined(separator: \", \")\n                typeParametersSuffix = \"<\\(typeParametersList)>\"\n            } else {\n                typeParametersSuffix = \"\"\n            }\n            classGenerator.apiHeader.addForwardDeclaration(type: \"@class \\(className)\\(typeParametersSuffix);\")\n\n            for property in resolvedProperties {\n                classImplBody.appendBody(\"@dynamic \\(property.propertyName);\\n\")\n            }\n            classImplBody.appendBody(\"\\n\")\n\n            let supertype = isGenericType ? \"SCValdiMarshallableGenericObject\" : \"SCValdiMarshallableObject\"\n            classGenerator.apiHeader.appendBody(\"@interface \\(className)\\(typeParametersSuffix): \\(supertype)\\n\\n\")\n            classGenerator.apiHeader.appendBody(classHeaderBody)\n            classGenerator.apiHeader.appendBody(\"@end\\n\\n\")\n        }\n\n        if let typeParameters = self.typeParameters {\n            classGenerator.apiImpl.appendBody(\"// Obj-C lightweight generics do not exist in class implementations\\n\")\n            for typeParam in typeParameters {\n                classGenerator.apiImpl.appendBody(\"typedef id \\(typeParam.name);\\n\")\n            }\n        }\n\n        if isInterface {\n            classGenerator.impl.appendBody(\"@implementation \\(className)\\n\\n\")\n            classGenerator.impl.appendBody(classImplBody)\n            classGenerator.impl.appendBody(\"@end\\n\\n\")\n        } else {\n            classGenerator.apiImpl.appendBody(\"@implementation \\(className)\\n\\n\")\n            classGenerator.apiImpl.appendBody(classImplBody)\n            classGenerator.apiImpl.appendBody(\"@end\\n\\n\")\n        }\n\n        let marshallFunctionName = \"\\(className)Marshall\"\n        let unmarshallFunctionName = \"\\(className)Unmarshall\"\n\n        _ = nameAllocator.allocate(property: unmarshallFunctionName)\n        _ = nameAllocator.allocate(property: marshallFunctionName)\n\n        var resolvedParameters = [ConstructorParameter]()\n        var initMethods: [ObjCSelector] = []\n\n        var allTypeParsers = [ObjCTypeParser]()\n\n        for objcProperty in resolvedProperties {\n            let property = objcProperty.modelProperty\n            do {\n                let typeParser = try classGenerator.writeTypeParser(type: property.type.unwrappingOptional,\n                                                                    isOptional: property.type.isOptional,\n                                                                    namePaths: [property.name],\n                                                                    allowValueType: true,\n                                                                    isInterface: isInterface,\n                                                                    nameAllocator: nameAllocator.scoped())\n\n                allTypeParsers.append(typeParser)\n\n                let constructorOmitted = property.omitConstructor?.ios == true\n                resolvedParameters.append(ConstructorParameter(\n                    param: ObjcMessageParameter(name: objcProperty.propertyName, type: typeParser.typeName),\n                    isOptional: property.type.isOptional,\n                    isOmitted: constructorOmitted\n                ))\n\n                if typeParser.objcSelector != nil {\n                    let disclaimerComment = \"NOTE: This method can be called from any thread.\"\n                    if let comments = property.comments {\n                        classHeaderBody.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: \"\\(comments)\\n\\(disclaimerComment)\"))\n                    } else {\n                        classHeaderBody.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: disclaimerComment))\n                    }\n                    classHeaderBody.appendBody(\"\\n\")\n                    if property.type.isOptional {\n                        classHeaderBody.appendBody(\"@optional\\n\")\n                    } else {\n                        classHeaderBody.appendBody(\"@required\\n\")\n                    }\n                    classHeaderBody.appendBody(\"\\(typeParser.typeName);\\n\\n\")\n                } else {\n                    if let comments = property.comments {\n                        classHeaderBody.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: comments))\n                        classHeaderBody.appendBody(\"\\n\")\n                    }\n                    if let propertyAdditionalHeaderDeclaration = typeParser.propertyAdditionalHeaderDeclaration {\n                        classHeaderBody.appendBody(\"\\(propertyAdditionalHeaderDeclaration)\\n\")\n                    }\n                    if isInterface {\n                        if property.type.isOptional {\n                            classHeaderBody.appendBody(\"@optional\\n\")\n                        } else {\n                            classHeaderBody.appendBody(\"@required\\n\")\n                        }\n                    }\n                    classHeaderBody.appendBody(\"@property (\\(typeParser.propertyAttribute), nonatomic) \\(typeParser.typeName) \\(objcProperty.propertyName);\\n\\n\")\n                }\n            } catch let error {\n                throw CompilerError(\"Failed to process property '\\(property.name)': \\(error.legibleLocalizedDescription)\")\n            }\n        }\n\n        if isInterface {\n\n        } else {\n\n            if emitLegacyConstructors {\n                // Generate constructors using the legacy technique\n                let allParameters = resolvedParameters.map { $0.param }\n                let initSelector = ObjCSelector(returnType: \"instancetype _Nonnull\", methodName: \"init\", parameters: allParameters)\n                initMethods.append(initSelector)\n                // Add an initializer for every @ConstructorOmitted, by going backward and removing them one by one\n                var parametersWithoutOmitted = resolvedParameters\n                while let lastOmittedIndex = parametersWithoutOmitted.lastIndex(where: { $0.isOmitted }) {\n                    parametersWithoutOmitted.remove(at: lastOmittedIndex)\n                    initMethods.append(ObjCSelector(returnType: \"instancetype _Nonnull\", methodName: \"init\", parameters: parametersWithoutOmitted.map { $0.param }))\n                }\n            } else {\n                // Generate constructors using the new recommended minimal constructors technique\n                var parametersWithoutOptionals = resolvedParameters\n                while let lastOptionalIndex = parametersWithoutOptionals.lastIndex(where: { $0.isOptional }) {\n                    parametersWithoutOptionals.remove(at: lastOptionalIndex)\n                }\n                initMethods.append(ObjCSelector(returnType: \"instancetype _Nonnull\", methodName: \"init\", parameters: parametersWithoutOptionals.map { $0.param }))\n            }\n\n            for initMethod in initMethods {\n                if !initMethod.parameters.isEmpty {\n                    let parametersSet = Set(initMethod.parameters.map { $0.name })\n\n                    var passParameters = [String]()\n\n                    for (index, property) in resolvedProperties.enumerated() {\n                        if parametersSet.contains(property.propertyName) {\n                            passParameters.append(property.propertyName)\n                        } else {\n                            passParameters.append(allTypeParsers[index].cType.defaultValue)\n                        }\n                    }\n\n                    let initMethodContents: String = \"return [super initWithFieldValues:nil, \\(passParameters.joined(separator: \", \"))];\"\n\n                    classImplBody.appendBody(\"\"\"\n                    \\(initMethod.messageDeclaration)\n                    {\n                        \\(initMethodContents)\n                    }\n                    \\n\n                    \"\"\")\n                } else {\n                    classImplBody.appendBody(\"\"\"\n                        \\(initMethod.messageDeclaration)\n                        {\n                        return [super init];\n                        }\n                        \\n\n                        \"\"\")\n                }\n\n                classHeaderBody.appendBody(\"\\(initMethod.messageDeclaration);\\n\\n\")\n            }\n        }\n\n        let objectDescriptor = try classGenerator.writeObjectDescriptorGetter(resolvedProperties: resolvedProperties,\n                                                                              objcSelectors: allTypeParsers.map { $0.objcSelector },\n                                                                              typeParameters: self.typeParameters,\n                                                                              objectDescriptorType: isInterface ? \"SCValdiMarshallableObjectTypeProtocol\" : \"SCValdiMarshallableObjectTypeClass\")\n\n        classImplBody.appendBody(\"\\n\")\n        classImplBody.appendBody(objectDescriptor)\n\n        if !isGenericType && isInterface {\n            let marshallFunctionSignature = \"NSInteger \\(marshallFunctionName)(SCValdiMarshallerRef  _Nonnull marshaller, \\(instanceType)instance)\"\n\n            classGenerator.header.appendBody(\"\"\"\n            /**\n            * Marshall the instance into the given SCValdiMarshaller.\n            */\n            FOUNDATION_EXPORT \\(marshallFunctionSignature);\n            \\n\n            \"\"\")\n\n            classGenerator.impl.appendBody(\"\"\"\n                \\(marshallFunctionSignature) {\n                    return SCValdiMarshallableObjectMarshallInterface(marshaller, instance, [\\(className) class]);\n                }\n                \\n\n                \"\"\")\n        }\n\n        return GeneratedCode(\n            apiHeader: classGenerator.apiHeader,\n            apiImpl: classGenerator.apiImpl,\n            header: classGenerator.header,\n            impl: classGenerator.impl\n        )\n    }\n\n    func write() throws -> [NativeSource] {\n        let generatedCode = try generateCode(for: properties, className: className)\n        let nativeSources = try NativeSource.iosNativeSourcesFromGeneratedCode(generatedCode,\n                                                                               iosType: iosType,\n                                                                               bundleInfo: bundleInfo)\n        return nativeSources\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/ObjCSelector.swift",
    "content": "//\n//  ObjCSelector.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/20/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct ObjcMessageParameter {\n    let name: String\n    let type: String\n}\n\nstruct ObjCSelector {\n    let messageParts: [String]\n    let returnType: String\n    let parameters: [ObjcMessageParameter]\n    let messageDeclaration: String\n    let selectorName: String\n\n    init(returnType: String, methodName: String, parameters: [ObjcMessageParameter]) {\n        self.returnType = returnType\n        self.parameters = parameters\n\n        if parameters.isEmpty {\n            self.messageParts = [methodName]\n            self.messageDeclaration = \"- (\\(returnType))\\(methodName)\"\n            self.selectorName = methodName\n        } else {\n            var messageParts = [String]()\n            var messageDeclaration = \"- (\\(returnType))\"\n\n            for (index, parameter) in parameters.enumerated() {\n                let messagePart: String\n\n                if index == 0 {\n                    messagePart = \"\\(methodName)With\\(parameter.name.pascalCased)\"\n                } else {\n                    messagePart = parameter.name\n                    messageDeclaration += \" \"\n                }\n                messageDeclaration += messagePart\n                messageDeclaration += \":(\\(parameter.type))\\(parameter.name)\"\n\n                messageParts.append(messagePart)\n            }\n\n            self.messageParts = messageParts\n            self.messageDeclaration = messageDeclaration\n            self.selectorName = messageParts.map { \"\\($0):\" }.joined()\n        }\n    }\n\n    func makeCallString(parameterValues: [String]) throws -> String {\n        if parameterValues.count != parameters.count {\n            throw CompilerError(\"Invalid number of parameters, expected \\(parameters.count), got \\(parameterValues.count)\")\n        }\n\n        if parameters.isEmpty {\n            return messageParts[0]\n        }\n\n        return messageParts.enumerated().map {\n                \"\\($0.element):\\(parameterValues[$0.offset])\"\n        }.joined(separator: \" \")\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/PropertyNameAllocator+Kotlin.swift",
    "content": "//\n//  PropertyNameAllocator+Kotlin.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/26/19.\n//\n\nimport Foundation\n\nextension PropertyNameAllocator {\n\n    class func forKotlin() -> PropertyNameAllocator {\n        let allocator = PropertyNameAllocator()\n\n        // Reserve the Kotlin keywords\n        KotlinValidation.kotlinKeywords.forEach { _ = allocator.allocate(property: $0) }\n\n        // Reserve builtin functions\n        _ = allocator.allocate(property: \"toString\")\n        _ = allocator.allocate(property: \"copy\")\n\n        return allocator\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/PropertyNameAllocator+ObjC.swift",
    "content": "//\n//  PropertyNameAllocator+ObjC.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/30/19.\n//\n\nimport Foundation\n\nextension PropertyNameAllocator {\n\n    class func forObjC() -> PropertyNameAllocator {\n        let allocator = PropertyNameAllocator()\n\n        // Reserve the Kotlin keywords\n        ObjCValidation.objcKeywords.forEach { _ = allocator.allocate(property: $0) }\n\n        return allocator\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/PropertyNameAllocator+Swift.swift",
    "content": "//\n//  PropertyNameAllocator+Kotlin.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 7/26/19.\n//\n\nimport Foundation\n\nextension PropertyNameAllocator {\n\n    class func forSwift() -> PropertyNameAllocator {\n        let allocator = PropertyNameAllocator()\n\n        // Reserve the Swift keywords\n        SwiftValidation.swiftKeywords.forEach { _ = allocator.allocate(property: $0) }\n\n        return allocator\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/PropertyNameAllocator.swift",
    "content": "//\n//  PropertyNameAllocator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 12/19/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nstruct PropertyName: CustomStringConvertible {\n\n    var name: String {\n        if id == 0 {\n            return originalName\n        }\n\n        return \"\\(originalName)\\(id + 1)\"\n    }\n\n    let originalName: String\n    let id: Int\n\n    init(originalName: String, id: Int) {\n        self.originalName = originalName\n        self.id = id\n    }\n\n    init(name: String) {\n        self.originalName = name\n        self.id = 0\n    }\n\n    var description: String {\n        return name\n    }\n\n}\n\n/**\n PropertyNameAllocator can generate identifiers and\n ensure they don't conflict. It can be scoped so that\n identifiers can be allocated without impacting the\n parent scope.\n */\nclass PropertyNameAllocator {\n\n    private(set) weak var parent: PropertyNameAllocator?\n\n    private var propertyNames = [String: Set<Int>]()\n\n    func allocate(property: String) -> PropertyName {\n        let propertyName = resolve(property: property)\n\n        propertyNames[propertyName.originalName, default: []].insert(propertyName.id)\n\n        return propertyName\n    }\n\n    private func resolve(property: String) -> PropertyName {\n        var firstId = 0\n        if let parent = parent {\n            // If we have a parent, the property should not conflict with anything it has\n            firstId = parent.resolve(property: property).id\n        }\n\n        let existingIds = propertyNames[property, default: []]\n\n        while existingIds.contains(firstId) {\n            firstId += 1\n        }\n\n        return PropertyName(originalName: property, id: firstId)\n    }\n\n    /**\n     Returns a new NameAllocator which will have its own scope\n     for the allocated properties, while ensuring the scoped properties\n     don't conflict with this name allocator as well.\n     */\n    func scoped() -> PropertyNameAllocator {\n        let nameAllocator = PropertyNameAllocator()\n        nameAllocator.parent = self\n        return nameAllocator\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/SwiftEnumGenerator.swift",
    "content": "//\n//  SwiftEnumGenerator.swift\n//  Compiler\n//\n//  Created by Ben Dodson on 2/8/2024\n//  Copyright © 2024 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nfinal class SwiftEnumGenerator {\n    private let exportedEnum: ExportedEnum\n    private let classMapping: ResolvedClassMapping\n\n    private let writer: SwiftCodeGenerator\n    private let sourceFileName: GeneratedSourceFilename\n\n    private let iosType: IOSType\n    private let typeName: String\n    private let bundleInfo: CompilationItem.BundleInfo\n\n    init(iosType: IOSType, exportedEnum: ExportedEnum, classMapping: ResolvedClassMapping, sourceFileName: GeneratedSourceFilename, bundleInfo: CompilationItem.BundleInfo) {\n        self.iosType = iosType\n        self.typeName = iosType.swiftName\n        self.exportedEnum = exportedEnum\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.bundleInfo = bundleInfo\n        self.writer = SwiftCodeGenerator()\n    }\n\n\n    func write() throws -> [NativeSource] {\n        try write(className: typeName, writer: writer)\n\n        let data = try writer.content.indented(indentPattern: \"    \").utf8Data()\n        let sourcesDirectoryRelativePath = \"../\\(bundleInfo.iosModuleName)\\(IOSType.HeaderImportKind.apiOnlyModuleNameSuffix)\"\n        return [NativeSource(relativePath: sourcesDirectoryRelativePath,\n                             filename: \"\\(typeName).\\(FileExtensions.swift)\",\n                             file: .data(data),\n                             groupingIdentifier: \"\\(bundleInfo.iosModuleName)\\(IOSType.HeaderImportKind.apiOnlyModuleNameSuffix).\\(FileExtensions.swift)\",\n                             groupingPriority: IOSType.enumTypeGroupingPriority)]\n    }\n\n    private func write<T>(className: String,\n                          writer: SwiftCodeGenerator,\n                          enumType: String,\n                          objectType: KotlinMarshallableObjectDescriptorAnnotation.ObjectType,\n                          cases: [EnumCase<T>],\n                          getCaseStringValue: (Int, EnumCase<T>) -> String) throws {\n        guard enumType == \"Int\" || enumType == \"String\" else {\n            throw CompilerError(\"Enum type \\(enumType) is not supported in Swift. Only Int and String are supported.\")\n        }\n\n        writer.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: exportedEnum.comments))\n        writer.appendBody(\"\\n\")\n        // TODO(3521): Update to ValdiCoreSwift\n        writer.appendBody(\"import ValdiCoreSwift\\n\")\n\n        let enumCasesBody = CodeWriter()\n        let nameAllocator = PropertyNameAllocator.forSwift()\n        for (idx, c) in cases.enumerated() {\n            // NOTE: c.value already contains quotes\n            if let comments = c.comments {\n                enumCasesBody.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: comments))\n                enumCasesBody.appendBody(\"\\n\")\n            }\n            let actualName = nameAllocator.allocate(property: camelCase(c.name)).name\n            let caseValue = getCaseStringValue(idx, c)\n            enumCasesBody.appendBody(\"    case \\(actualName) = \\(caseValue)\\n\")\n        }\n\n        let nativeType = (enumType == \"Int\") ? \"Int32\" : enumType\n        // TODO(3521): Update to ValdiMarshall*\n        let valdiType = \"ValdiMarshallable\\(enumType)Enum\"\n        writer.appendBody(\n        \"\"\"\n        public enum \\(className): \\(nativeType), \\(valdiType) {\n            \\(enumCasesBody.content)\n            public init(from marshaller: ValdiMarshaller, at objectIndex: Int) throws {\n                self = try create\\(enumType)Enum(from:marshaller, at:objectIndex)\n            }\n        }\n        public func register_\\(className)() {\n            let enumCases: [\\(nativeType)] = allEnumCases(of: \\(className).self)\n            ValdiMarshallableObjectRegistry.shared.register\\(enumType)Enum(enumName: \"\\(className)\", enumCases: enumCases)\n        }\\n\n        \"\"\")\n    }\n    \n    private func camelCase(_ string: String) -> String {\n        let words = string.components(separatedBy: CharacterSet.alphanumerics.inverted)\n        let camelCasedWords = words.enumerated().map { index, word -> String in\n            if index == 0 {\n                return word.lowercased()\n            }\n            return word.capitalized\n        }\n        \n        return camelCasedWords.joined()\n    }\n\n    private func write(className: String, writer: SwiftCodeGenerator) throws {\n        switch exportedEnum.cases {\n        case .enum(let cases):\n            try write(className: className, writer: writer, enumType: \"Int\", objectType: KotlinMarshallableObjectDescriptorAnnotation.ObjectType.intEnum, cases: cases, getCaseStringValue: { _, c in\n                return \"\\(c.value)\"\n            })\n        case .stringEnum(let cases):\n            try write(className: className, writer: writer, enumType: \"String\", objectType: KotlinMarshallableObjectDescriptorAnnotation.ObjectType.stringEnum, cases: cases, getCaseStringValue: { _, c in\n                return \"\\\"\\(c.value)\\\"\"\n            })\n        }\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/SwiftModelGenerator.swift",
    "content": "//  Copyright © 2024 Snap Inc. All rights reserved.\n\nimport Foundation\n\nfinal class SwiftModelGenerator {\n    private let iosType: IOSType\n    private let bundleInfo: CompilationItem.BundleInfo\n    private let className: String\n    private let typeParameters: [ValdiTypeParameter]?\n    private let properties: [ValdiModelProperty]\n    private let classMapping: ResolvedClassMapping\n    private let sourceFileName: GeneratedSourceFilename\n    private let isInterface: Bool\n    private let comments: String?\n    private let nameAllocator = PropertyNameAllocator.forSwift()\n\n    init(iosType: IOSType, bundleInfo: CompilationItem.BundleInfo, typeParameters: [ValdiTypeParameter]?, properties: [ValdiModelProperty], classMapping: ResolvedClassMapping, sourceFileName: GeneratedSourceFilename, isInterface: Bool, comments: String?) {\n        self.iosType = iosType\n        self.bundleInfo = bundleInfo\n        self.className = iosType.swiftName\n        self.typeParameters = typeParameters\n        self.properties = properties\n        self.classMapping = classMapping\n        self.sourceFileName = sourceFileName\n        self.isInterface = isInterface\n        self.comments = comments\n    }\n\n    private struct SwiftGeneratedCode {\n        let filename: String\n        let source: SwiftSourceFileGenerator\n    }\n\n    private func resolveProperties(valdiProperties: [ValdiModelProperty], _ classGenerator: SwiftSourceFileGenerator) throws -> [SwiftProperty] {\n        return try valdiProperties.enumerated().map { (index, property) throws in\n            // let propertyName = nameAllocator.allocate(property: property.name).name\n            let propertyName = nameAllocator.allocate(property: property.name).name\n            let typeParser = try classGenerator.getTypeParser(type: property.type.unwrappingOptional,\n                                                              isOptional: property.type.isOptional,\n                                                              functionHelperName: propertyName,\n                                                              nameAllocator: classGenerator.nameAllocator.scoped())\n            return SwiftProperty(name: propertyName,\n                                 typeParser: typeParser,\n                                 comments: property.comments)\n        }\n    }\n\n    private func generateInterface(properties: [SwiftProperty], classGenerator: SwiftSourceFileGenerator) throws -> CodeWriter {\n        let interface = CodeWriter()\n        let interfaceBody = try properties.map() { property in\n            let commentWriter = CodeWriter()\n            if let comments = property.comments {\n                commentWriter.appendBody(FileHeaderCommentGenerator.generateMultilineComment(comment: comments))\n                commentWriter.appendBody(\"\\n\")\n            }\n\n            if (!property.typeParser.isFunction) {\n                return \"\\(commentWriter.content)var \\(property.name): \\(property.typeParser.typeName) { get }\"\n            } else {\n                guard let functionType = property.typeParser.functionTypeParser?.methodTypeWithNames else {\n                    throw CompilerError(\"Cannot get function signature for property \\(property.name)\")\n                }\n                return \"\\(commentWriter.content)func \\(property.name)\\(functionType)\"\n            }\n        }.joined(separator: indent(spaces: 8))\n        \n        // TODO(3521): Update to VladiMarshall*\n        interface.appendBody(\n        \"\"\"\n        public protocol \\(className) : ValdiMarshallableInterface {\n            \\(interfaceBody)\n        }\\n\\n\n        \"\"\")\n        return interface\n    }\n\n    private func generateCode(for valdiModelProperties: [ValdiModelProperty], className: String) throws -> SwiftGeneratedCode {\n        let thisModule = self.iosType.importPrefix ?? \"\"\n        let classGenerator = SwiftSourceFileGenerator(className: className, moduleName: thisModule)\n        // TODO(3521): Update to ValdiCoreSwift\n        classGenerator.addImport(path: \"ValdiCoreSwift\")\n        classGenerator.appendBody(FileHeaderCommentGenerator.generateComment(sourceFilename: sourceFileName, additionalComments: self.comments))\n        classGenerator.appendBody(\"\\n\")\n\n        let nameAllocator = classGenerator.nameAllocator\n        _ = nameAllocator.allocate(property: className)\n\n        let properties = try resolveProperties(valdiProperties: valdiModelProperties, classGenerator)\n\n        let variableDeclarations = SwiftSourceFileGenerator.writeVariableDeclaration(properties: properties, isInterface: isInterface)\n        let classConstructor = SwiftSourceFileGenerator.writeConstructor(properties: properties)\n        let objectMarshaller = SwiftSourceFileGenerator.writeObjectMarshaller(properties: properties, className: className, isInterface: isInterface)\n        let objectUnmarshaller = SwiftSourceFileGenerator.writeObjectUnmarshaller(properties: properties, isInterface: isInterface)\n        let objectDescriptorGetter = try SwiftSourceFileGenerator.writeObjectDescriptorGetter(\n            properties: properties,\n            propertyTypes: valdiModelProperties.map { $0.type },\n            typeParameters: self.typeParameters,\n            objectDescriptorType: isInterface ? \"ValdiMarshallableObjectType.Interface\" : \"ValdiMarshallableObjectType.Class\")\n        let functionHelpers = try SwiftSourceFileGenerator.writeFunctionHelpers(sourceGenerator: classGenerator)\n        let typeParameterList = self.typeParameters?.map { $0.name }.joined(separator: \", \") ?? \"\"\n        let typeParameterString =  self.typeParameters?.isEmpty == false ? \"<\\(typeParameterList)>\" : \"\"\n\n        if (!isInterface) {\n            let classDefinition =\n            \"\"\"\n            public class \\(className)\\(typeParameterString) : ValdiMarshallableObject {\n            \\(variableDeclarations.content)\n            \\(classConstructor.content)\n            \\(objectMarshaller.content)\n            \\(objectUnmarshaller.content)\n            \\(functionHelpers.content)\n            \\(objectDescriptorGetter.content)\n            }\\n\n            \"\"\"\n            classGenerator.appendBody(classDefinition)\n        } else {\n            let interface = try generateInterface(properties: properties, classGenerator: classGenerator)\n            let interfaceDefinition =\n            \"\"\"\n            \\(interface.content)\n            extension \\(className) {\n            \\(objectMarshaller.content)\n            \\(functionHelpers.content)\n            }\n            public class \\(className)_Proxy : \\(className), ValdiMarshallableObject {\n            \\(variableDeclarations.content)\n            \\(objectUnmarshaller.content)\n            \\(objectDescriptorGetter.content)\n            }\\n\n            \"\"\"\n            classGenerator.appendBody(interfaceDefinition)\n        }\n\n        let dummyParameterList = self.typeParameters?.map { p in \"Void\" }.joined(separator: \", \") ?? \"\"\n        let dummyParameterString = self.typeParameters?.isEmpty == false ? \"<\\(dummyParameterList)>\" : \"\"\n        let descriptorNamespace = (isInterface ? \"\\(className)_Proxy\" : className) + dummyParameterString\n        let registrationFunction = \n        \"\"\"\n        public func register_\\(className)() {\n            ValdiMarshallableObjectRegistry.shared.register(className: \"\\(className)\", objectDescriptor: \\(descriptorNamespace).getDescriptor())\n        }\\n\n        \"\"\"\n        classGenerator.appendBody(registrationFunction)\n\n        return SwiftGeneratedCode(filename: className, source: classGenerator)\n    }\n\n    func write() throws -> [NativeSource] {\n        let generatedCode = try generateCode(for: properties, className: className)\n        let source = try generatedCode.source.content.utf8Data()\n        let sourcesDirectoryRelativePath = \"../\\(bundleInfo.iosModuleName)\\(IOSType.HeaderImportKind.apiOnlyModuleNameSuffix)\"\n        return [NativeSource(relativePath: sourcesDirectoryRelativePath,\n                             filename: \"\\(generatedCode.filename).\\(FileExtensions.swift)\",\n                             file: .data(source),\n                             groupingIdentifier: \"\\(bundleInfo.iosModuleName)\\(IOSType.HeaderImportKind.apiOnlyModuleNameSuffix).\\(FileExtensions.swift)\",\n                             groupingPriority: isInterface ? IOSType.interfaceTypeGroupingPriority : IOSType.classTypeGroupingPriority)]\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/ViewModels/ValdiModelGenerator.swift",
    "content": "//\n//  ValdiModelGenerator.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/6/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\n\nclass ValdiModelGenerator: NativeSourceGenerator {\n\n    private let model: ValdiModel\n\n    init(model: ValdiModel) {\n        self.model = model\n    }\n\n    func generateSwiftSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource] {\n        let iosGenerator = SwiftModelGenerator(iosType: type,\n                                               bundleInfo: parameters.bundleInfo,\n                                               typeParameters: model.typeParameters,\n                                               properties: model.properties,\n                                               classMapping: parameters.classMapping,\n                                               sourceFileName: parameters.sourceFileName,\n                                               isInterface: model.exportAsInterface,\n                                               comments: model.comments)\n        return try iosGenerator.write()\n    }\n\n    func generateObjCSources(parameters: NativeSourceParameters, type: IOSType) throws -> [NativeSource] {\n        let iosGenerator = ObjCModelGenerator(iosType: type,\n                                              bundleInfo: parameters.bundleInfo,\n                                              typeParameters: model.typeParameters,\n                                              properties: model.properties,\n                                              classMapping: parameters.classMapping,\n                                              sourceFileName: parameters.sourceFileName,\n                                              isInterface: model.exportAsInterface,\n                                              emitLegacyConstructors: model.legacyConstructors,\n                                              comments: model.comments)\n\n        return try iosGenerator.write()\n    }\n\n    func generateKotlinSources(parameters: NativeSourceParameters, fullTypeName: String) throws -> [NativeSource] {\n        let androidGenerator = KotlinModelGenerator(bundleInfo: parameters.bundleInfo,\n                                                    className: fullTypeName,\n                                                    typeParameters: model.typeParameters,\n                                                    properties: model.properties,\n                                                    classMapping: parameters.classMapping,\n                                                    sourceFileName: parameters.sourceFileName,\n                                                    isInterface: model.exportAsInterface,\n                                                    emitLegacyConstructors: model.legacyConstructors,\n                                                    comments: model.comments,\n                                                    usePublicFields: model.usePublicFields)\n\n        return try androidGenerator.write()\n    }\n\n    func generateCppSources(parameters: NativeSourceParameters, cppType: CPPType) throws -> [NativeSource] {\n        let cppGenerator = CppModelGenerator(cppType: cppType,\n                                             bundleInfo: parameters.bundleInfo,\n                                             typeParameters: model.typeParameters,\n                                             properties: model.properties,\n                                             classMapping: parameters.classMapping,\n                                             sourceFileName: parameters.sourceFileName,\n                                             isInterface: model.exportAsInterface,\n                                             comments: model.comments)\n\n        return try cppGenerator.write()\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Sources/main.swift",
    "content": "//\n//  main.swift\n//  Compiler\n//\n//  Created by Simon Corsin on 4/5/18.\n//  Copyright © 2018 Snap Inc. All rights reserved.\n//\n\nimport Foundation\nimport Backtrace\n\nfunc isCompilingUnderBazel() -> Bool {\n    return CommandLine.arguments.contains { $0 == \"--bazel\" }\n}\n\nfunc shouldRunAsPersistentWorker() -> Bool {\n    return CommandLine.arguments.contains { $0 == \"--persistent_worker\" }\n}\n\nfunc getArgFilePath() -> String? {\n    let arguments = CommandLine.arguments\n    guard arguments.count == 2 else { return nil }\n    let arg = arguments[1]\n    let prefixToCheck = \"@\"\n    guard arg.hasPrefix(prefixToCheck) else { return nil }\n\n    return String(arg[prefixToCheck.endIndex..<arg.endIndex])\n}\n\nfunc main() {\n    // Installing Backtrace's signal handlers for sane-ish stack traces when crashing on Linux\n    // (this is a no-op on macOS)\n    Backtrace.install(signals: [SIGILL, SIGSEGV, SIGBUS, SIGFPE, SIGQUIT])\n\n    // Ignore SIGPIPE signals, they are very difficult to handle properly with the Foundation APIs\n    signal(SIGPIPE, SIG_IGN)\n\n    SentryClient.setTag(value: String(isCompilingUnderBazel()), key: \"bazel_build\")\n\n    if shouldRunAsPersistentWorker() {\n        let logger = Logger(output: FileHandleLoggerOutput(stdout: FileHandle.standardError, stderr: FileHandle.standardError))\n        let bazelPersistentWorker = BazelPersistentWorker(stdin: FileHandle.standardInput, stdout: FileHandle.standardOutput, logger: logger)\n        let companionExecutableProvider = CompanionExecutableProvider(logger: logger)\n        bazelPersistentWorker.run { request in\n            let arguments: ValdiCompilerArguments\n            do {\n                arguments = try ValdiCompilerArguments.parse(request.arguments)\n            } catch let error {\n                return BazelPersistentWorker.Response(result: Promise(error: error))\n            }\n\n            let runner = ValdiCompilerRunner(logger: request.logger, \n                                                arguments: arguments,\n                                                companionExecutableProvider: companionExecutableProvider,\n                                                workingDirectoryPath: request.workingDirectory,\n                                                runningAsWorker: true)\n            if runner.run() {\n                return BazelPersistentWorker.Response(result: Promise(data: ()))\n            } else {\n                return BazelPersistentWorker.Response(result: Promise(error: CompilerError(\"Compilation failed\")))\n            }\n        }\n    } else {\n        if let argFilePath = getArgFilePath() {\n            let argFile: String\n            do {\n                argFile = try String(contentsOfFile: argFilePath)\n            } catch let error {\n                print(\"Failed to read arg file: \\(error.legibleLocalizedDescription)\")\n                _exit(1)\n            }\n\n            let resolvedArguments = argFile.components(separatedBy: \"\\n\").filter { !$0.isEmpty }\n            ValdiCompilerArguments.main(resolvedArguments)\n        } else {\n            // Sentry doesn't really support running on multiple instances of a program at once.\n            // It reads and writes crash data into the same file\n            if !isCompilingUnderBazel() {\n                let arguments = Array(CommandLine.arguments.dropFirst())\n                if let parsedArgs = try? ValdiCompilerArguments.parseAsRoot(arguments) as? ValdiCompilerArguments,\n                   let sentryDsn = parsedArgs.sentryDsn {\n                    SentryClient.start(dsn: sentryDsn,\n                                    tracesSampleRate: 0.25,\n                                    username: NSUserName())\n                }\n            }\n\n            ValdiCompilerArguments.main()\n        }\n\n    }\n}\nmain()\n"
  },
  {
    "path": "compiler/compiler/Compiler/Tests/CompilerTests/CompilerTests.swift",
    "content": "import XCTest\nimport class Foundation.Bundle\n\nfinal class CompilerTests: XCTestCase {\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Tests/CompilerTests/ValdiAnnotationTests.swift",
    "content": "import XCTest\nimport Foundation\n@testable import Compiler\n\nfunc extractAnnotations(_ content: String) throws -> [ValdiTypeScriptAnnotation] {\n    let comments = TS.AST.Comments(text: content, start: 0, end: content.nsrange.length)\n    let extracted = try ValdiTypeScriptAnnotation.extractAnnotations(comments: comments,\n                                                                        fileContent: content)\n    return extracted\n}\n\nfinal class ValdiAnnotationTests: XCTestCase {\n    func testPlainAnnotation() throws {\n        var content: String = \"\"\n        var result: [ValdiTypeScriptAnnotation] = []\n\n        content = \"\"\"\n// @PlainAnnotation\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.name, \"PlainAnnotation\")\n\n        content = \"\"\"\n// @AnnotationWithParen()\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.name, \"AnnotationWithParen\")\n\n        content = \"\"\"\n/*\n * @MultilineCommentAnnotation()\n */\n\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.name, \"MultilineCommentAnnotation\")\n    }\n\n    func testAnnotationWithPayload() throws {\n        var content: String = \"\"\n        var result: [ValdiTypeScriptAnnotation] = []\n\n        content = \"\"\"\n// @EmptyPayloadAnnotation({})\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.parameters, [:])\n\n        content = \"\"\"\n// @SimplePayloadAnnotation({ \"ios\": \"blah\" })\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.parameters, [\"ios\": \"blah\"])\n\n        content = \"\"\"\n// @MultipleParamPayloadAnnotation({ \"ios\": \"blah\", \"foo\": \"bar\" })\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.parameters, [\"ios\": \"blah\", \"foo\": \"bar\"])\n\n        content = \"\"\"\n/*\n * @MultilineParamPayloadAnnotation({\n *  \"ios\": \"blah\",\n *  \"foo\": \"bar\"\n * })\n */\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.parameters, [\"ios\": \"blah\", \"foo\": \"bar\"])\n\n        content = \"\"\"\n// @SingleQuotePayload({ 'ios': 'blah' })\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.parameters, [\"ios\": \"blah\"])\n\n        content = \"\"\"\n// @UnquotedPayload({ ios: blah })\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.parameters, [\"ios\": \"blah\"])\n\n        content = \"\"\"\n// @PartiallyQuotedPayloadR({ ios: 'blah' })\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.parameters, [\"ios\": \"blah\"])\n\n        content = \"\"\"\n// @PartiallyQuotedPayloadL({ 'ios': blah })\n\"\"\"\n        result = try extractAnnotations(content)\n        XCTAssertEqual(result.first?.parameters, [\"ios\": \"blah\"])\n    }\n\n    func testBadCases() throws {\n        var content: String = \"\"\n\n        try XCTExpectFailure {\n            content = \"\"\"\n    // @BadOne({ ios: 'blah, android: 'bleugh' })\n    \"\"\"\n            _ = try extractAnnotations(content)\n        }\n\n        try XCTExpectFailure {\n            content = \"\"\"\n    // @BadTwo({ 'ios: 'blah', android: 'bleugh' })\n    \"\"\"\n            _ = try extractAnnotations(content)\n        }\n\n        try XCTExpectFailure {\n            content = \"\"\"\n// @BadThree({ ios: blah', android: 'bleugh' })\n\"\"\"\n            _ = try extractAnnotations(content)\n        }\n\n        try XCTExpectFailure {\n            content = \"\"\"\n// @BadFour({ ios: 'blah, android: bleugh' })\n\"\"\"\n            _ = try extractAnnotations(content)\n        }\n    }\n\n    func testiOSTypeNameValidation() throws {\n        XCTAssertTrue(ObjCValidation.isValidIOSTypeName(iosTypeName: \"SCCSomeType\"))\n        XCTAssertTrue(ObjCValidation.isValidIOSTypeName(iosTypeName: \"SCCSomeOtherType1234\"))\n        XCTAssertTrue(ObjCValidation.isValidIOSTypeName(iosTypeName: \"_SCCMyType\"))\n\n        XCTAssertFalse(ObjCValidation.isValidIOSTypeName(iosTypeName: \"\"))\n        XCTAssertFalse(ObjCValidation.isValidIOSTypeName(iosTypeName: \"123Invalid\"))\n        XCTAssertFalse(ObjCValidation.isValidIOSTypeName(iosTypeName: \"SCCObjCCantHaveDollars$\"))\n        XCTAssertFalse(ObjCValidation.isValidIOSTypeName(iosTypeName: \"'SCCAlsoInvalid\"))\n        XCTAssertFalse(ObjCValidation.isValidIOSTypeName(iosTypeName: \"SCCThisToo'\"))\n        XCTAssertFalse(ObjCValidation.isValidIOSTypeName(iosTypeName: \"com.snap.valdi.accidental.AndroidInsteadOfIOS\"))\n    }\n\n    func testAndroidTypeNameValidation() throws {\n        XCTAssertTrue(KotlinValidation.isValidAndroidTypeName(androidTypeName: \"com.snap.valdi.Blah\"))\n        XCTAssertTrue(KotlinValidation.isValidAndroidTypeName(androidTypeName: \"com.snap.contextcards.lib.valdi.ContextValdiActionHandler\"))\n\n        XCTAssertFalse(KotlinValidation.isValidAndroidTypeName(androidTypeName: \"\"))\n        XCTAssertFalse(KotlinValidation.isValidAndroidTypeName(androidTypeName: \"com.snap.packagepath.cant.have/slashes\"))\n        XCTAssertFalse(KotlinValidation.isValidAndroidTypeName(androidTypeName: \"com.snap.package.Cool\"))\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Tests/LinuxMain.swift",
    "content": "fatalError(\"Run the tests with `swift test --enable-test-discovery`.\")\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/BlueSocket/Package.swift",
    "content": "// swift-tools-version:5.0\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"BlueSocket\",\n    products: [\n        .library(name: \"BlueSocket\", targets: [\"BlueSocket\"])\n    ],\n    targets: [\n        // Targets are the basic building blocks of a package. A target can define a module or a test suite.\n        // Targets can depend on other targets in this package, and on products in packages which this package depends on.\n        .target(\n            name: \"BlueSocket\",\n            dependencies: [],\n            path: \"Sources\")\n    ]\n)\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/BlueSocket/Sources/Socket.swift",
    "content": "//\n//  Socket.swift\n//  BlueSocket\n//\n//  Created by Bill Abt on 11/9/15.\n//  Copyright © 2016 IBM. All rights reserved.\n//\n// \tLicensed under the Apache License, Version 2.0 (the \"License\");\n// \tyou may not use this file except in compliance with the License.\n// \tYou may obtain a copy of the License at\n//\n// \thttp://www.apache.org/licenses/LICENSE-2.0\n//\n// \tUnless required by applicable law or agreed to in writing, software\n// \tdistributed under the License is distributed on an \"AS IS\" BASIS,\n// \tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// \tSee the License for the specific language governing permissions and\n// \tlimitations under the License.\n//\n\n#if os(macOS) || os(iOS) || os(tvOS)\n\timport Darwin\n#elseif os(Linux)\n\timport Glibc\n#endif\n\nimport Foundation\n\n// MARK: Socket\n\n///\n/// **Socket:** Low level BSD sockets wrapper.\n///\npublic class Socket: SocketReader, SocketWriter {\n\n\t// MARK: Constants\n\n\t// MARK: -- Generic\n\n\tpublic static let SOCKET_MINIMUM_READ_BUFFER_SIZE\t\t= 1024\n\tpublic static let SOCKET_DEFAULT_READ_BUFFER_SIZE\t\t= 4096\n\tpublic static let SOCKET_DEFAULT_SSL_READ_BUFFER_SIZE\t= 32768\n\tpublic static let SOCKET_MAXIMUM_SSL_READ_BUFFER_SIZE\t= 8000000\n\tpublic static let SOCKET_DEFAULT_MAX_BACKLOG\t\t\t= 50\n\t#if os(macOS) || os(iOS) || os(tvOS)\n\tpublic static let SOCKET_MAX_DARWIN_BACKLOG\t\t\t\t= 128\n\t#endif\n\n\tpublic static let SOCKET_INVALID_PORT\t\t\t\t\t= Int32(0)\n\tpublic static let SOCKET_INVALID_DESCRIPTOR \t\t\t= Int32(-1)\n\n\tpublic static let INADDR_ANY\t\t\t\t\t\t\t= in_addr_t(0)\n\n\tpublic static let NO_HOSTNAME\t\t\t\t\t\t\t= \"No hostname\"\n\n\t// MARK: -- Errors: Domain and Codes\n\n\tpublic static let SOCKET_ERR_DOMAIN\t\t\t\t\t\t= \"com.ibm.oss.Socket.ErrorDomain\"\n\n\tpublic static let SOCKET_ERR_UNABLE_TO_CREATE_SOCKET    = -9999\n\tpublic static let SOCKET_ERR_BAD_DESCRIPTOR\t\t\t\t= -9998\n\tpublic static let SOCKET_ERR_ALREADY_CONNECTED\t\t\t= -9997\n\tpublic static let SOCKET_ERR_NOT_CONNECTED\t\t\t\t= -9996\n\tpublic static let SOCKET_ERR_NOT_LISTENING\t\t\t\t= -9995\n\tpublic static let SOCKET_ERR_ACCEPT_FAILED\t\t\t\t= -9994\n\tpublic static let SOCKET_ERR_SETSOCKOPT_FAILED\t\t\t= -9993\n\tpublic static let SOCKET_ERR_BIND_FAILED\t\t\t\t= -9992\n\tpublic static let SOCKET_ERR_INVALID_HOSTNAME\t\t\t= -9991\n\tpublic static let SOCKET_ERR_INVALID_PORT\t\t\t\t= -9990\n\tpublic static let SOCKET_ERR_GETADDRINFO_FAILED\t\t\t= -9989\n\tpublic static let SOCKET_ERR_CONNECT_FAILED\t\t\t\t= -9988\n\tpublic static let SOCKET_ERR_MISSING_CONNECTION_DATA\t= -9987\n\tpublic static let SOCKET_ERR_SELECT_FAILED\t\t\t\t= -9986\n\tpublic static let SOCKET_ERR_LISTEN_FAILED\t\t\t\t= -9985\n\tpublic static let SOCKET_ERR_INVALID_BUFFER\t\t\t\t= -9984\n\tpublic static let SOCKET_ERR_INVALID_BUFFER_SIZE\t\t= -9983\n\tpublic static let SOCKET_ERR_RECV_FAILED\t\t\t\t= -9982\n\tpublic static let SOCKET_ERR_RECV_BUFFER_TOO_SMALL\t\t= -9981\n\tpublic static let SOCKET_ERR_WRITE_FAILED\t\t\t\t= -9980\n\tpublic static let SOCKET_ERR_GET_FCNTL_FAILED\t\t\t= -9979\n\tpublic static let SOCKET_ERR_SET_FCNTL_FAILED\t\t\t= -9978\n\tpublic static let SOCKET_ERR_NOT_IMPLEMENTED\t\t\t= -9977\n\tpublic static let SOCKET_ERR_NOT_SUPPORTED_YET\t\t\t= -9976\n\tpublic static let SOCKET_ERR_BAD_SIGNATURE_PARAMETERS\t= -9975\n\tpublic static let SOCKET_ERR_INTERNAL\t\t\t\t\t= -9974\n\tpublic static let SOCKET_ERR_WRONG_PROTOCOL\t\t\t\t= -9973\n\tpublic static let SOCKET_ERR_NOT_ACTIVE\t\t\t\t\t= -9972\n\tpublic static let SOCKET_ERR_CONNECTION_RESET\t\t\t= -9971\n\tpublic static let SOCKET_ERR_SET_RECV_TIMEOUT_FAILED\t= -9970\n\tpublic static let SOCKET_ERR_SET_WRITE_TIMEOUT_FAILED\t= -9969\n\tpublic static let SOCKET_ERR_CONNECT_TIMEOUT\t\t\t= -9968\n\tpublic static let SOCKET_ERR_GETSOCKOPT_FAILED\t\t\t= -9967\n\tpublic static let SOCKET_ERR_INVALID_DELEGATE_CALL\t\t= -9966\n\tpublic static let SOCKET_ERR_MISSING_SIGNATURE\t\t\t= -9965\n\tpublic static let SOCKET_ERR_PARAMETER_ERROR\t\t\t= -9964\n\t\n\t///\n\t/// Specialized Operation Exception\n\t///\n\tenum OperationInterrupted: Swift.Error {\n\t\n\t\t/// Low level socket accept was interrupted.\n\t\t/// - **Note:** This is typically _NOT_ an error.\n\t\tcase accept\n\t\t\n\t\t/// Low level datagram read was interrupted.\n\t\t/// - **Note:** This is typically _NOT_ an error.\n\t\tcase readDatagram(length: Int)\n\t}\n\t\n\t///\n\t/// Flag to indicate the endian-ness of the host. (Readonly)\n\t///\n\tpublic static let isLittleEndian: Bool = Int(littleEndian: 42) == 42\n\n\t// MARK: Enums\n\n\t// MARK: -- ProtocolFamily\n\n\t///\n\t/// Socket Protocol Family Values\n\t///\n\t/// **Note:** Only the following are supported at this time:\n\t///\t\t\tinet = AF_INET (IPV4)\n\t///\t\t\tinet6 = AF_INET6 (IPV6)\n\t///\t\t\tunix = AF_UNIX\n\t///\n\tpublic enum ProtocolFamily {\n\n\t\t/// AF_INET (IPV4)\n\t\tcase inet\n\n\t\t/// AF_INET6 (IPV6)\n\t\tcase inet6\n\n\t\t/// AF_UNIX\n\t\tcase unix\n\n\t\t///\n\t\t/// Return the value for a particular case. (Readonly)\n\t\t///\n\t\tvar value: Int32 {\n\n\t\t\tswitch self {\n\n\t\t\tcase .inet:\n\t\t\t\treturn Int32(AF_INET)\n\n\t\t\tcase .inet6:\n\t\t\t\treturn Int32(AF_INET6)\n\n\t\t\tcase .unix:\n\t\t\t\treturn Int32(AF_UNIX)\n\t\t\t}\n\t\t}\n\t\t///\n\t\t/// Return enum equivalent of a raw value\n\t\t///\n\t\t/// - Parameter forValue: Value for which enum value is desired\n\t\t///\n\t\t/// - Returns: Optional contain enum value or nil\n\t\t///\n\t\tstatic func getFamily(forValue: Int32) -> ProtocolFamily? {\n\n\t\t\tswitch forValue {\n\n\t\t\tcase Int32(AF_INET):\n\t\t\t\treturn .inet\n\t\t\tcase Int32(AF_INET6):\n\t\t\t\treturn .inet6\n\t\t\tcase Int32(AF_UNIX):\n\t\t\t\treturn .unix\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\n\t}\n\n\t// MARK: -- SocketType\n\n\t///\n\t/// Socket Type Values\n\t///\n\t/// **Note:** Only the following are supported at this time:\n\t///\t\t\tstream = SOCK_STREAM (Provides sequenced, reliable, two-way, connection-based byte streams.)\n\t///\t\t\tdatagram = SOCK_DGRAM (Supports datagrams (connectionless, unreliable messages of a fixed maximum length).)\n\t///\n\tpublic enum SocketType {\n\n\t\t/// SOCK_STREAM (Provides sequenced, reliable, two-way, connection-based byte streams.)\n\t\tcase stream\n\n\t\t/// SOCK_DGRAM (Supports datagrams (connectionless, unreliable messages of a fixed maximum length).)\n\t\tcase datagram\n\n\t\t///\n\t\t/// Return the value for a particular case. (Readonly)\n\t\t///\n\t\tvar value: Int32 {\n\n\t\t\tswitch self {\n\n\t\t\tcase .stream:\n\t\t\t\t#if os(Linux)\n\t\t\t\t\treturn Int32(SOCK_STREAM.rawValue)\n\t\t\t\t#else\n\t\t\t\t\treturn SOCK_STREAM\n\t\t\t\t#endif\n\t\t\tcase .datagram:\n\t\t\t\t#if os(Linux)\n\t\t\t\t\treturn Int32(SOCK_DGRAM.rawValue)\n\t\t\t\t#else\n\t\t\t\t\treturn SOCK_DGRAM\n\t\t\t\t#endif\n\t\t\t}\n\t\t}\n\n\t\t///\n\t\t/// Return enum equivalent of a raw value\n\t\t///\n\t\t/// - Parameter forValue: Value for which enum value is desired\n\t\t///\n\t\t/// - Returns: Optional contain enum value or nil\n\t\t///\n\t\tstatic func getType(forValue: Int32) -> SocketType? {\n\n\t\t\t#if os(Linux)\n\t\t\t\tswitch forValue {\n\n\t\t\t\tcase Int32(SOCK_STREAM.rawValue):\n\t\t\t\t\treturn .stream\n\t\t\t\tcase Int32(SOCK_DGRAM.rawValue):\n\t\t\t\t\treturn .datagram\n\t\t\t\tdefault:\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t#else\n\t\t\t\tswitch forValue {\n\n\t\t\t\tcase SOCK_STREAM:\n\t\t\t\t\treturn .stream\n\t\t\t\tcase SOCK_DGRAM:\n\t\t\t\t\treturn .datagram\n\t\t\t\tdefault:\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t#endif\n\t\t}\n\t}\n\n\t// MARK: -- SocketProtocol\n\n\t///\n\t/// Socket Protocol Values\n\t///\n\t/// **Note:** Only the following are supported at this time:\n\t///\t\t\ttcp = IPPROTO_TCP\n\t///\t\t\tudp = IPPROTO_UDP\n\t///\t\t\tunix = Unix Domain Socket (raw value = 0)\n\t///\n\tpublic enum SocketProtocol: Int32 {\n\n\t\t/// IPPROTO_TCP\n\t\tcase tcp\n\n\t\t/// IPPROTO_UDP\n\t\tcase udp\n\n\t\t/// Unix Domain\n\t\tcase unix\n\n\t\t///\n\t\t/// Return the value for a particular case. (Readonly)\n\t\t///\n\t\tvar value: Int32 {\n\n\t\t\tswitch self {\n\n\t\t\tcase .tcp:\n\t\t\t\treturn Int32(IPPROTO_TCP)\n\t\t\tcase .udp:\n\t\t\t\treturn Int32(IPPROTO_UDP)\n\t\t\tcase .unix:\n\t\t\t\treturn Int32(0)\n\t\t\t}\n\t\t}\n\n\t\t///\n\t\t/// Return enum equivalent of a raw value\n\t\t///\n\t\t/// - Parameter forValue: Value for which enum value is desired\n\t\t///\n\t\t/// - Returns: Optional contain enum value or nil\n\t\t///\n\t\tstatic func getProtocol(forValue: Int32) -> SocketProtocol? {\n\n\t\t\tswitch forValue {\n\n\t\t\tcase Int32(IPPROTO_TCP):\n\t\t\t\treturn .tcp\n\t\t\tcase Int32(IPPROTO_UDP):\n\t\t\t\treturn .udp\n\t\t\tcase Int32(0):\n\t\t\t\treturn .unix\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\t// MARK: -- Socket Address\n\n\t///\n\t/// Socket Address\n\t///\n\tpublic enum Address {\n\n\t\t/// sockaddr_in\n\t\tcase ipv4(sockaddr_in)\n\n\t\t/// sockaddr_in6\n\t\tcase ipv6(sockaddr_in6)\n\n\t\t/// sockaddr_un\n\t\tcase unix(sockaddr_un)\n\n\t\t///\n\t\t/// Size of address. (Readonly)\n\t\t///\n\t\tpublic var size: Int {\n\n\t\t\tswitch self {\n\n\t\t\tcase .ipv4( _):\n\t\t\t\treturn MemoryLayout<(sockaddr_in)>.size\n\t\t\tcase .ipv6( _):\n\t\t\t\treturn MemoryLayout<(sockaddr_in6)>.size\n\t\t\tcase .unix( _):\n\t\t\t\treturn MemoryLayout<(sockaddr_un)>.size\n\t\t\t}\n\t\t}\n\t\t\n\t\t///\n\t\t/// The protocol family of the address. (Readonly)\n\t\t///\n\t\tpublic var family: ProtocolFamily {\n\t\t\tswitch self {\n\t\t\tcase .ipv4(_):\n\t\t\t\treturn ProtocolFamily.inet\n\t\t\tcase .ipv6(_):\n\t\t\t\treturn ProtocolFamily.inet6\n\t\t\tcase .unix(_):\n\t\t\t\treturn ProtocolFamily.unix\n\t\t\t}\n\t\t}\n\t}\n\n\t// MARK: Structs\n\n\t// MARK: -- Signature\n\n\t///\n\t/// Socket signature: contains the characteristics of the socket.\n\t///\n\tpublic struct Signature: CustomStringConvertible {\n\n\t\t// MARK: -- Public Properties\n\n\t\t///\n\t\t/// Protocol Family\n\t\t///\n\t\tpublic internal(set) var protocolFamily: ProtocolFamily\n\n\t\t///\n\t\t/// Socket Type. (Readonly)\n\t\t///\n\t\tpublic internal(set) var socketType: SocketType\n\n\t\t///\n\t\t/// Socket Protocol. (Readonly)\n\t\t///\n\t\tpublic internal(set) var proto: SocketProtocol\n\n\t\t///\n\t\t/// Host name for connection. (Readonly)\n\t\t///\n\t\tpublic internal(set) var hostname: String? = Socket.NO_HOSTNAME\n\n\t\t///\n\t\t/// Port for connection. (Readonly)\n\t\t///\n\t\tpublic internal(set) var port: Int32 = Socket.SOCKET_INVALID_PORT\n\n\t\t///\n\t\t/// Path for .unix type sockets. (Readonly)\n\t\t///\n\t\tpublic internal(set) var path: String? = nil\n\n\t\t///\n\t\t/// Address info for socket. (Readonly)\n\t\t///\n\t\tpublic internal(set) var address: Address? = nil\n\n\t\t///\n\t\t/// Flag to indicate whether `Socket` is secure or not. (Readonly)\n\t\t///\n\t\tpublic internal(set) var isSecure: Bool = false\n\n\t\t///\n\t\t/// `True` is socket bound, `false` otherwise.\n\t\t///\n\t\tpublic internal(set) var isBound: Bool = false\n\n\t\t///\n\t\t/// Returns a string description of the error.\n\t\t///\n\t\tpublic var description: String {\n\n\t\t\treturn \"Signature: family: \\(protocolFamily), type: \\(socketType), protocol: \\(proto), address: \\(address as Socket.Address?), hostname: \\(hostname as String?), port: \\(port), path: \\(String(describing: path)), bound: \\(isBound), secure: \\(isSecure)\"\n\t\t}\n\n\t\t// MARK: -- Public Functions\n\n\t\t///\n\t\t/// Create a socket signature\n\t\t///\n\t\t/// - Parameters:\n\t\t///\t\t- protocolFamily:\tThe family of the socket to create.\n\t\t///\t\t- socketType:\t\tThe type of socket to create.\n\t\t///\t\t- proto:\t\t\tThe protocool to use for the socket.\n\t\t/// \t- address:\t\t\tAddress info for the socket.\n\t\t///\n\t\t/// - Returns: New Signature instance\n\t\t///\n\t\tpublic init?(protocolFamily: Int32, socketType: Int32, proto: Int32, address: Address?) throws {\n\n\t\t\tguard let family = ProtocolFamily.getFamily(forValue: protocolFamily),\n\t\t\t\tlet type = SocketType.getType(forValue: socketType),\n\t\t\t\tlet pro = SocketProtocol.getProtocol(forValue: proto) else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Bad family, type or protocol passed.\")\n\t\t\t}\n\n\t\t\t// Validate the parameters...\n\t\t\tif type == .stream {\n\t\t\t\tguard pro == .tcp || pro == .unix else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Stream socket must use either .tcp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tif type == .datagram {\n\t\t\t\tguard pro == .udp || pro == .unix else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Datagram socket must use .udp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tself.protocolFamily = family\n\t\t\tself.socketType = type\n\t\t\tself.proto = pro\n\n\t\t\tself.address = address\n\n\t\t}\n\t\t\n\t\t///\n\t\t/// Create a socket signature\n\t\t///\n\t\t///\t- Parameters:\n\t\t///\t\t- socketType:\t\tThe type of socket to create.\n\t\t///\t\t- proto:\t\t\tThe protocool to use for the socket.\n\t\t/// \t- address:\t\t\tAddress info for the socket.\n\t\t/// \t- hostname:\t\t\tHostname for this signature.\n\t\t/// \t- port:\t\t\t\tPort for this signature.\n\t\t///\n\t\t/// - Returns: New Signature instance\n\t\t///\n\t\tpublic init?(socketType: SocketType, proto: SocketProtocol, address: Address, hostname: String?, port: Int32?) throws {\n\t\t\t\n\t\t\t// Validate the parameters...\n\t\t\tif socketType == .stream {\n\t\t\t\tguard proto == .tcp || proto == .unix else {\n\t\t\t\t\t\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Stream socket must use either .tcp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tif socketType == .datagram {\n\t\t\t\tguard proto == .udp || proto == .unix else {\n\t\t\t\t\t\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Datagram socket must use .udp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tself.protocolFamily = address.family\n\t\t\tself.socketType = socketType\n\t\t\tself.proto = proto\n\t\t\t\n\t\t\tself.address = address\n\t\t\tself.hostname = hostname\n\t\t\tif let port = port {\n\t\t\t\tself.port = port\n\t\t\t}\n\t\t}\n\n\t\t///\n\t\t/// Create a socket signature\n\t\t///\n\t\t///\t- Parameters:\n\t\t///\t\t- protocolFamily:\tThe protocol family to use (only `.inet` and `.inet6` supported by this `init` function).\n\t\t///\t\t- socketType:\t\tThe type of socket to create.\n\t\t///\t\t- proto:\t\t\tThe protocool to use for the socket.\n\t\t/// \t- hostname:\t\t\tHostname for this signature.\n\t\t/// \t- port:\t\t\t\tPort for this signature.\n\t\t///\n\t\t/// - Returns: New Signature instance\n\t\t///\n\t\tpublic init?(protocolFamily: ProtocolFamily, socketType: SocketType, proto: SocketProtocol, hostname: String?, port: Int32?) throws {\n\n\t\t\t// Make sure we have what we need...\n\t\t\tguard let _ = hostname,\n\t\t\t\tlet port = port, protocolFamily == .inet || protocolFamily == .inet6 else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Missing hostname, port or both or invalid protocol family.\")\n\t\t\t}\n\n\t\t\tself.protocolFamily = protocolFamily\n\n\t\t\t// Validate the parameters...\n\t\t\tif socketType == .stream {\n\t\t\t\tguard proto == .tcp || proto == .unix else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Stream socket must use either .tcp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tif socketType == .datagram {\n\t\t\t\tguard proto == .udp || proto == .unix else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Datagram socket must use .udp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tself.socketType = socketType\n\t\t\tself.proto = proto\n\n\t\t\tself.hostname = hostname\n\t\t\tself.port = port\n\t\t}\n\n\t\t///\n\t\t/// Create a socket signature\n\t\t///\n\t\t///\t- Parameters:\n\t\t///\t\t- socketType:\t\tThe type of socket to create.\n\t\t///\t\t- proto:\t\t\tThe protocool to use for the socket.\n\t\t/// \t- path:\t\t\t\tPathname for this signature.\n\t\t///\n\t\t/// - Returns: New Signature instance\n\t\t///\n\t\tpublic init?(socketType: SocketType, proto: SocketProtocol, path: String?) throws {\n\n\t\t\t// Make sure we have what we need...\n\t\t\tguard let path = path, !path.isEmpty else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Missing pathname.\")\n\t\t\t}\n\n\t\t\t// Default to Unix socket protocol family...\n\t\t\tself.protocolFamily = .unix\n\n\t\t\tself.socketType = socketType\n\t\t\tself.proto = proto\n\n\t\t\t// Validate the parameters...\n\t\t\tif socketType == .stream {\n\t\t\t\tguard proto == .tcp || proto == .unix else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Stream socket must use either .tcp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tif socketType == .datagram {\n\t\t\t\tguard proto == .udp || proto == .unix else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Datagram socket must use .udp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tself.path = path\n\n\t\t\t// Create the address...\n\t\t\tvar remoteAddr = sockaddr_un()\n\t\t\tremoteAddr.sun_family = sa_family_t(AF_UNIX)\n\n\t\t\tlet lengthOfPath = path.utf8.count\n\n\t\t\t// Validate the length...\n\t\t\tguard lengthOfPath < MemoryLayout.size(ofValue: remoteAddr.sun_path) else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Pathname supplied is too long.\")\n\t\t\t}\n\n\t\t\t// Copy the path to the remote address...\n\t\t\t_ = withUnsafeMutablePointer(to: &remoteAddr.sun_path.0) { ptr in\n\n\t\t\t\tpath.withCString {\n\t\t\t\t\tstrncpy(ptr, $0, lengthOfPath)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t#if !os(Linux)\n\t\t\t    remoteAddr.sun_len = UInt8(MemoryLayout<UInt8>.size + MemoryLayout<sa_family_t>.size + path.utf8.count + 1)\n\t\t\t#endif\n\n\t\t\tself.address = .unix(remoteAddr)\n\t\t}\n\n\t\t///\n\t\t/// Create a socket signature\n\t\t///\n\t\t/// - Parameters:\n\t\t///\t\t- protocolFamily:\tThe family of the socket to create.\n\t\t///\t\t- socketType:\t\tThe type of socket to create.\n\t\t///\t\t- proto:\t\t\tThe protocool to use for the socket.\n\t\t/// \t- address:\t\t\tAddress info for the socket.\n\t\t/// \t- hostname:\t\t\tHostname for this signature.\n\t\t/// \t- port:\t\t\t\tPort for this signature.\n\t\t///\n\t\t/// - Returns: New Signature instance\n\t\t///\n\t\tinternal init?(protocolFamily: Int32, socketType: Int32, proto: Int32, address: Address?, hostname: String?, port: Int32?) throws {\n\n\t\t\t// This constructor requires all items be present...\n\t\t\tguard let family = ProtocolFamily.getFamily(forValue: protocolFamily),\n\t\t\t\tlet type = SocketType.getType(forValue: socketType),\n\t\t\t\tlet pro = SocketProtocol.getProtocol(forValue: proto),\n\t\t\t\tlet _ = hostname,\n\t\t\t\tlet port = port else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Incomplete parameters.\")\n\t\t\t}\n\n\t\t\tself.protocolFamily = family\n\t\t\tself.socketType = type\n\t\t\tself.proto = pro\n\n\t\t\t// Validate the parameters...\n\t\t\tif type == .stream {\n\t\t\t\tguard pro == .tcp || pro == .unix else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Stream socket must use either .tcp or .unix for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tif type == .datagram {\n\t\t\t\tguard pro == .udp else {\n\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Datagram socket must use .udp for the protocol.\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tself.address = address\n\n\t\t\tself.hostname = hostname\n\t\t\tself.port = port\n\t\t}\n\n\t\t///\n\t\t///\tRetrieve the UNIX address as an UnsafeMutablePointer\n\t\t///\n\t\t///\t- Returns: \tTuple containing the pointer plus the size.\n\t\t///\t\t\t\t**IMPORTANT: The pointer returned needs to be deallocated after use.**\n\t\t///\n\t\tinternal func unixAddress() throws -> (UnsafeMutablePointer<UInt8>, Int) {\n\n\t\t\t// Throw an exception if the path is not set...\n\t\t\tif path == nil {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Specified path contains zero (0) bytes.\")\n\t\t\t}\n\n\t\t\tlet utf8 = path!.utf8\n\n\t\t\t// macOS has a size identifier in front, Linux does not...\n\t\t\t#if os(Linux)\n\t\t\t\tlet addrLen = MemoryLayout<sockaddr_un>.size\n\t\t\t#else\n\t\t\t\tlet addrLen = MemoryLayout<UInt8>.size + MemoryLayout<sa_family_t>.size + utf8.count + 1\n\t\t\t#endif\n\t\t\tlet addrPtr = UnsafeMutablePointer<UInt8>.allocate(capacity: addrLen)\n\n\t\t\tvar memLoc = 0\n\n\t\t\t// macOS uses one byte for sa_family_t, Linux uses two...\n\t\t\t//\tNote: on Linux, account for endianess...\n\t\t\t#if os(Linux)\n\t\t\t\tlet afUnixShort = UInt16(AF_UNIX)\n\t\t        if isLittleEndian {\n\t\t\t\t  addrPtr[memLoc] = UInt8(afUnixShort & 0xFF)\n\t\t\t\t  memLoc += 1\n\t\t\t\t  addrPtr[memLoc] = UInt8((afUnixShort >> 8) & 0xFF)\n\t\t\t\t  memLoc += 1\n\t\t\t\t} else {\n\t\t\t\t  addrPtr[memLoc] = UInt8((afUnixShort >> 8) & 0xFF)\n\t\t\t\t  memLoc += 1\n\t\t\t\t  addrPtr[memLoc] = UInt8(afUnixShort & 0xFF)\n\t\t\t\t  memLoc += 1\n\t\t\t\t}\n\t\t\t#else\n\t\t\t\taddrPtr[memLoc] = UInt8(addrLen)\n\t\t\t\tmemLoc += 1\n\t\t\t\taddrPtr[memLoc] = UInt8(AF_UNIX)\n\t\t\t\tmemLoc += 1\n\t\t\t#endif\n\n\t\t\t// Copy the pathname...\n\t\t\tfor char in utf8 {\n\t\t\t\taddrPtr[memLoc] = char\n\t\t\t\tmemLoc += 1\n\t\t\t}\n\n\t\t\taddrPtr[memLoc] = 0\n\n\t\t\treturn (addrPtr, addrLen)\n\t\t}\n\n\t}\n\n\t// MARK: -- Error\n\n\t///\n\t/// `Socket` specific error structure.\n\t///\n\tpublic struct Error: Swift.Error, CustomStringConvertible {\n\n\t\t// MARK: -- Public Properties\n\n\t\t///\n\t\t/// The error domain.\n\t\t///\n\t\tpublic let domain: String = SOCKET_ERR_DOMAIN\n\n\t\t///\n\t\t/// The error code: **see constants above for possible errors** (Readonly)\n\t\t///\n\t\tpublic internal(set) var errorCode: Int32\n\n\t\t///\n\t\t/// The reason for the error **(if available)** (Readonly)\n\t\t///\n\t\tpublic internal(set) var errorReason: String?\n\n\t\t///\n\t\t/// Returns a string description of the error. (Readonly)\n\t\t///\n\t\tpublic var description: String {\n\n\t\t\tlet reason: String = self.errorReason ?? \"Reason: Unavailable\"\n\t\t\treturn \"Error code: \\(self.errorCode)(0x\\(String(self.errorCode, radix: 16, uppercase: true))), \\(reason)\"\n\t\t}\n\n\t\t///\n\t\t/// The buffer size needed to complete the read. (Readonly)\n\t\t///\n\t\tpublic internal(set) var bufferSizeNeeded: Int32\n\n\t\t// MARK: -- Public Functions\n\n\t\t///\n\t\t/// Initializes an Error Instance\n\t\t///\n\t\t/// - Parameters:\n\t\t///\t\t- code:\t\tError code\n\t\t/// \t- reason:\tOptional Error Reason\n\t\t///\n\t\t/// - Returns: Error instance\n\t\t///\n\t\tinit(code: Int, reason: String?) {\n\n\t\t\tself.errorCode = Int32(code)\n\t\t\tself.errorReason = reason\n\t\t\tself.bufferSizeNeeded = 0\n\t\t}\n\n\t\t///\n\t\t/// Initializes an Error Instance for a too small receive buffer error.\n\t\t///\n\t\t///\t- Parameter bufferSize:\tRequired buffer size\n\t\t///\n\t\t///\t- Returns: Error Instance\n\t\t///\n\t\tinit(bufferSize: Int) {\n\n\t\t\tself.init(code: Socket.SOCKET_ERR_RECV_BUFFER_TOO_SMALL, reason: \"Socket has an invalid buffer, the size is too small\")\n\t\t\tself.bufferSizeNeeded = Int32(bufferSize)\n\t\t}\n\n\t\t///\n\t\t/// Initializes an Error instance using SSLError\n\t\t///\n\t\t/// - Parameter error: SSLError instance to be transformed\n\t\t///\n\t\t/// - Returns: Error Instance\n\t\t///\n\t\tinit(with error: SSLError) {\n\n\t\t\tself.init(code: error.errCode, reason: error.description)\n\t\t}\n\t}\n\n\t// MARK: Properties\n\n\t// MARK: -- Private\n\n\t///\n\t/// Internal read buffer.\n\t/// \t**Note:** The readBuffer is actually allocating unmanaged memory that'll\n\t///\t\t\tbe deallocated when we're done with it.\n\t///\n\tvar readBuffer: UnsafeMutablePointer<CChar> = UnsafeMutablePointer<CChar>.allocate(capacity: Socket.SOCKET_DEFAULT_READ_BUFFER_SIZE)\n\n\t///\n\t/// Internal Storage Buffer initially created with `Socket.SOCKET_DEFAULT_READ_BUFFER_SIZE`.\n\t///\n\tvar readStorage: NSMutableData = NSMutableData(capacity: Socket.SOCKET_DEFAULT_READ_BUFFER_SIZE)!\n\t\n\t///\n\t/// `True` if a delegate accept is pending.\n\t///\n\tvar needsAcceptDelegateCall: Bool = false\n\n\n\t// MARK: -- Public\n\n\t///\n\t/// The file descriptor representing this socket. (Readonly)\n\t///\n\tpublic internal(set) var socketfd: Int32 = SOCKET_INVALID_DESCRIPTOR\n\n\t///\n\t/// The signature for the socket. (Readonly)\n\t/// \t**Note:** See Signature above.\n\t///\n\tpublic internal(set) var signature: Signature? = nil\n\n\t///\n\t/// The delegate that provides the SSL implementation.\n\t///\n\tpublic var delegate: SSLServiceDelegate? = nil {\n\n\t\tdidSet {\n\n\t\t\t// If setting an SSL delegate, bump up the read buffer size...\n\t\t\tif delegate != nil {\n\t\t\t\treadBufferSize = Socket.SOCKET_DEFAULT_SSL_READ_BUFFER_SIZE\n\t\t\t}\n\t\t}\n\t}\n\n\t///\n\t/// Internal Read buffer size for all open sockets.\n\t///\t\t**Note:** Changing this value will cause the internal read buffer to\n\t///\t\t\tbe discarded and reallocated with the new size. The value must be\n\t///\t\t\tset to at least `Socket.SOCKET_MINIMUM_READ_BUFFER_SIZE`. If set\n\t///\t\t\tto something smaller, it will be automatically set to the minimum\n\t///\t\t\tsize as defined by `Socket.SOCKET_MINIMUM_READ_BUFFER_SIZE`.\n\t///\n\tpublic var readBufferSize: Int = Socket.SOCKET_DEFAULT_READ_BUFFER_SIZE {\n\n\t\t// If the buffer size changes we need to reallocate the buffer...\n\t\tdidSet {\n\n\t\t\t// Ensure minimum buffer size...\n\t\t\tif readBufferSize < Socket.SOCKET_MINIMUM_READ_BUFFER_SIZE {\n\n\t\t\t\treadBufferSize = Socket.SOCKET_MINIMUM_READ_BUFFER_SIZE\n\t\t\t}\n\n\t\t\tif readBufferSize != oldValue {\n\n\t\t\t\t#if swift(>=4.1)\n\t\t\t\t\treadBuffer.deinitialize(count: readBufferSize)\n\t\t\t\t\treadBuffer.deallocate()\n\t\t\t\t\treadBuffer = UnsafeMutablePointer<CChar>.allocate(capacity: readBufferSize)\n\t\t\t\t\treadBuffer.initialize(to: 0)\n\t\t\t\t#else\n\t\t\t\t\treadBuffer.deinitialize()\n\t\t\t\t\treadBuffer.deallocate(capacity: oldValue)\n\t\t\t\t\treadBuffer = UnsafeMutablePointer<CChar>.allocate(capacity: readBufferSize)\n\t\t\t\t\treadBuffer.initialize(to: 0, count: readBufferSize)\n\t\t\t\t#endif\n\t\t\t}\n\t\t}\n\t}\n\n\t///\n\t/// Maximum size of the queue containing pending connections.\n\t///\t\t**Note:** Default value is `Socket.SOCKET_DEFAULT_MAX_BACKLOG`\n\t///\n\tpublic var maxBacklogSize: Int = Socket.SOCKET_DEFAULT_MAX_BACKLOG\n\n\t///\n\t/// `True` if this socket is connected. `False` otherwise. (Readonly)\n\t///\n\tpublic internal(set) var isConnected: Bool = false\n\n\t///\n\t/// `True` if this socket is blocking. `False` otherwise. (Readonly)\n\t///\n\tpublic internal(set) var isBlocking: Bool = true\n\n\t///\n\t/// `True` if this socket is listening. `False` otherwise. (Readonly)\n\t///\n\tpublic internal(set) var isListening: Bool = false\n\n\t///\n\t/// `True` if this socket's remote connection has closed. (Readonly)\n\t///\t\t**Note:** This is only valid after a Socket is connected.\n\t///\n\tpublic internal(set) var remoteConnectionClosed: Bool = false\n\n\t///\n\t/// `True` if the socket is listening or connected. (Readonly)\n\t///\n\tpublic var isActive: Bool {\n\n\t\treturn isListening || isConnected\n\t}\n\n\t///\n\t/// `True` if this a server, `false` otherwise. (Readonly)\n\t///\n\tpublic var isServer: Bool {\n\n\t\treturn isListening\n\t}\n\n\t///\n\t/// `True` if this socket is secure, `false` otherwise. (Readonly)\n\t///\n\tpublic var isSecure: Bool {\n\n\t\tguard let sig = signature else {\n\t\t\treturn false\n\t\t}\n\t\treturn sig.isSecure\n\t}\n\n\t///\n\t/// Listening port (-1 if not listening). (Readonly)\n\t///\n\tpublic var listeningPort: Int32 {\n\n\t\tguard let sig = signature, isListening else {\n\t\t\treturn Int32(-1)\n\t\t}\n\t\treturn sig.port\n\t}\n\n\t///\n\t/// The remote host name this socket is connected to. (Readonly)\n\t///\n\tpublic var remoteHostname: String {\n\n\t\tguard let sig = signature,\n\t\t\tlet host = sig.hostname else {\n\t\t\t\treturn Socket.NO_HOSTNAME\n\t\t}\n\n\t\treturn host\n\t}\n\n\t///\n\t/// The remote port this socket is connected to. (Readonly)\n\t///\n\tpublic var remotePort: Int32 {\n\n\t\tguard let sig = signature, sig.port != Socket.SOCKET_INVALID_PORT else {\n\t\t\treturn Socket.SOCKET_INVALID_PORT\n\t\t}\n\n\t\treturn sig.port\n\t}\n\n\t///\n\t/// The path this socket is connected to or listening on. (Readonly)\n\t///\n\tpublic var remotePath: String? {\n\n\t\tguard let sig = signature,\n\t\t\tlet path = sig.path else {\n\t\t\treturn nil\n\t\t}\n\n\t\treturn path\n\t}\n\n\n\t// MARK: Class Functions\n\n\t///\n\t/// Create a configured Socket instance.\n\t/// \t**Note:** Calling with no parameters will create a default socket: IPV4, stream, TCP.\n\t///\n\t/// - Parameters:\n\t///\t\t- family:\tThe family of the socket to create.\n\t///\t\t- type:\t\tThe type of socket to create.\n\t///\t\t- proto:\tThe protocool to use for the socket.\n\t///\n\t/// - Returns: New Socket instance\n\t///\n\tpublic class func create(family: ProtocolFamily = .inet, type: SocketType = .stream, proto: SocketProtocol = .tcp) throws -> Socket {\n\n\t\t// Validate the parameters...\n\t\tif type == .stream {\n\t\t\tguard proto == .tcp || proto == .unix else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Stream socket must use either .tcp or .unix for the protocol.\")\n\t\t\t}\n\t\t}\n\t\tif type == .datagram {\n\t\t\tguard proto == .udp || proto == .unix else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Datagram socket must use .udp or .unix for the protocol.\")\n\t\t\t}\n\t\t}\n\n\t\treturn try Socket(family: family, type: type, proto: proto)\n\t}\n\n\t///\n\t/// Create a configured and connected Socket instance.\n\t///\n\t/// - Parameter signature:\tThe socket signature containing the connection information.\n\t///\n\t/// - Returns: New Socket instance. **Note:** Connection status should be checked via the *isConnected* property on the returned socket.\n\t///\n\tpublic class func create(connectedUsing signature: Signature) throws -> Socket {\n\n\t\tlet socket = try Socket(family: signature.protocolFamily, type: signature.socketType, proto: signature.proto)\n\n\t\ttry socket.connect(using: signature)\n\n\t\treturn socket\n\t}\n\n\t///\n\t/// Create an instance for existing open socket fd.\n\t///\n\t/// - Parameters:\n\t///\t\t- nativeHandle: Open file descriptor.\n\t///\t\t- address: \t\tThe Address associated with the open fd.\n\t///\n\t/// - Returns: New Socket instance\n\t///\n\tpublic class func create(fromNativeHandle nativeHandle: Int32, address: Address?) throws -> Socket {\n\n\t\tguard let addr = address else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_MISSING_CONNECTION_DATA, reason: \"Unable to access socket connection data.\")\n\t\t}\n\n\t\treturn try Socket(fd: nativeHandle, remoteAddress: addr)\n\t}\n\n\t///\n\t/// Extract the string form of IP address and the port.\n\t///\n\t/// - Parameter fromAddress: The Address struct.\n\t///\n\t/// - Returns: Optional Tuple containing the hostname and port.\n\t///\n\tpublic class func hostnameAndPort(from address: Address) -> (hostname: String, port: Int32)? {\n\n\t\tvar port: Int32 = 0\n\t\tvar bufLen: Int = 0\n\t\tvar buf: [CChar]\n\n\t\tswitch address {\n\n\t\tcase .ipv4(let address_in):\n\t\t\tvar addr_in = address_in\n\t\t\tbufLen = Int(INET_ADDRSTRLEN)\n\t\t\tbuf = [CChar](repeating: 0, count: bufLen)\n\t\t\tinet_ntop(Int32(addr_in.sin_family), &addr_in.sin_addr, &buf, socklen_t(bufLen))\n\t\t\tif isLittleEndian {\n\t\t\t\tport = Int32(UInt16(addr_in.sin_port).byteSwapped)\n\t\t\t} else {\n\t\t\t\tport = Int32(UInt16(addr_in.sin_port))\n\t\t\t}\n\n\t\tcase .ipv6(let address_in):\n\t\t\tvar addr_in = address_in\n\t\t\tbufLen = Int(INET6_ADDRSTRLEN)\n\t\t\tbuf = [CChar](repeating: 0, count: bufLen)\n\t\t\tinet_ntop(Int32(addr_in.sin6_family), &addr_in.sin6_addr, &buf, socklen_t(bufLen))\n\t\t\tif isLittleEndian {\n\t\t\t\tport = Int32(UInt16(addr_in.sin6_port).byteSwapped)\n\t\t\t} else {\n\t\t\t\tport = Int32(UInt16(addr_in.sin6_port))\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\n\t\tif let s = String(validatingUTF8: buf) {\n\t\t\treturn (s, port)\n\n\t\t}\n\n\t\treturn nil\n\t}\n\n\t///\n\t/// Check whether one or more sockets are available for reading and/or writing\n\t///\n\t/// - Parameter sockets: Array of Sockets to be tested.\n\t///\n\t/// - Returns: Tuple containing two arrays of Sockets, one each representing readable and writable sockets.\n\t///\n\tpublic class func checkStatus(for sockets: [Socket]) throws -> (readables: [Socket], writables: [Socket]) {\n\n\t\tvar readables: [Socket] = []\n\t\tvar writables: [Socket] = []\n\n\t\tfor socket in sockets {\n\n\t\t\tlet result = try socket.isReadableOrWritable()\n\t\t\tif result.readable {\n\t\t\t\treadables.append(socket)\n\t\t\t}\n\t\t\tif result.writable {\n\t\t\t\twritables.append(socket)\n\t\t\t}\n\t\t}\n\n\t\treturn (readables, writables)\n\t}\n\n\t///\n\t/// Monitor an array of sockets, returning when data is available or timeout occurs.\n\t///\n\t/// - Parameters:\n\t///\t\t- sockets:\t\tAn array of sockets to be monitored.\n\t///\t\t- timeout:\t\tTimeout (in msec) before returning.  A timeout value of 0 will return immediately.\n\t///\t\t- waitForever:\tIf `true`, this function will wait indefinitely regardless of timeout value. Defaults to `false`.\n\t///\n\t/// - Returns: An optional array of sockets which have data available or nil if a timeout expires.\n\t///\n\tpublic class func wait(for sockets: [Socket], timeout: UInt, waitForever: Bool = false) throws -> [Socket]? {\n\n\t\t// Validate we have sockets to look for and they are valid...\n\t\tfor socket in sockets {\n\n\t\t\tif socket.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"The socket has an invalid descriptor\")\n\t\t\t}\n\t\t\tif socket.signature == nil {\n\t\t\t\t\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_MISSING_SIGNATURE, reason: \"The socket is missing a signature\")\n\t\t\t}\n\t\t\tif !socket.isActive && !socket.signature!.isBound {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_NOT_ACTIVE, reason: \"The socket is not active\")\n\t\t\t}\n\t\t}\n\n\t\t// Setup the timeout...\n\t\tvar timer = timeval()\n\t\tif timeout > 0  && !waitForever {\n\n\t\t\t// First get seconds...\n\t\t\tlet secs = Int(Double(timeout / 1000))\n\t\t\ttimer.tv_sec = secs\n\n\t\t\t// Now get the leftover millisecs...\n\t\t\tlet msecs = Int32(Double(timeout % 1000))\n\n\t\t\t// Note: timeval expects microseconds, convert now...\n\t\t\tlet uSecs = msecs * 1000\n\n\t\t\t// Now the leftover microseconds...\n\t\t\t#if os(Linux)\n\t\t\t\ttimer.tv_usec = Int(uSecs)\n\t\t\t#else\n\t\t\t\ttimer.tv_usec = Int32(uSecs)\n\t\t\t#endif\n\t\t}\n\n\t\t// Setup the array of readfds...\n\t\tvar readfds = fd_set()\n\t\treadfds.zero()\n\n\t\tvar highSocketfd: Int32 = 0\n\t\tfor socket in sockets {\n\n\t\t\tif socket.socketfd > highSocketfd {\n\t\t\t\thighSocketfd = socket.socketfd\n\t\t\t}\n\t\t\treadfds.set(socket.socketfd)\n\t\t}\n\n\t\t// Issue the select...\n\t\tvar count: Int32 = 0\n\t\tif waitForever {\n\t\t\tcount = select(highSocketfd + Int32(1), &readfds, nil, nil, nil)\n\t\t} else {\n\t\t\tcount = select(highSocketfd + Int32(1), &readfds, nil, nil, &timer)\n\t\t}\n\n\t\t// A count of less than zero indicates select failed...\n\t\tif count < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_SELECT_FAILED, reason: String(validatingUTF8: strerror(errno)) ?? \"Error: \\(errno)\")\n\t\t}\n\n\t\t// A count equal zero, indicates we timed out...\n\t\tif count == 0 {\n\t\t\treturn nil\n\t\t}\n\n\t\t// Build the array of returned sockets...\n\t\treturn sockets.filter { readfds.isSet($0.socketfd) }\n\t}\n\n\t///\n\t/// Creates an Address for a given host and port.\n\t///\n\t///\t- Parameters:\n\t/// \t- hostname:\t\t\tHostname for this signature.\n\t/// \t- port:\t\t\t\tPort for this signature.\n\t///\n\t/// - Returns: An Address instance, or `nil` if the hostname and port are not valid.\n\t///\n\tpublic class func createAddress(for host: String, on port: Int32) -> Address? {\n\n\t\tvar info: UnsafeMutablePointer<addrinfo>?\n\n\t\t// Retrieve the info on our target...\n\t\tvar status: Int32 = getaddrinfo(host, String(port), nil, &info)\n\t\tif status != 0 {\n\n\t\t\treturn nil\n\t\t}\n\n\t\t// Defer cleanup of our target info...\n\t\tdefer {\n\n\t\t\tif info != nil {\n\t\t\t\tfreeaddrinfo(info)\n\t\t\t}\n\t\t}\n\n\t\tvar address: Address\n\t\tif info!.pointee.ai_family == Int32(AF_INET) {\n\n\t\t\tvar addr = sockaddr_in()\n\t\t\tmemcpy(&addr, info!.pointee.ai_addr, Int(MemoryLayout<sockaddr_in>.size))\n\t\t\taddress = .ipv4(addr)\n\n\t\t} else if info!.pointee.ai_family == Int32(AF_INET6) {\n\n\t\t\tvar addr = sockaddr_in6()\n\t\t\tmemcpy(&addr, info!.pointee.ai_addr, Int(MemoryLayout<sockaddr_in6>.size))\n\t\t\taddress = .ipv6(addr)\n\n\t\t} else {\n\n\t\t\treturn nil\n\t\t}\n\n\t\treturn address\n\t}\n\n\t// MARK: Lifecycle Functions\n\n\t// MARK: -- Private\n\n\t///\n\t/// Internal initializer to create a configured Socket instance.\n\t///\n\t/// - Parameters:\n\t///\t\t- family:\tThe family of the socket to create.\n\t///\t\t- type:\t\tThe type of socket to create.\n\t///\t\t- proto:\tThe protocol to use for the socket.\n\t///\n\t/// - Returns: New Socket instance\n\t///\n\tprivate init(family: ProtocolFamily, type: SocketType, proto: SocketProtocol) throws {\n\n\t\t// Initialize the read buffer...\n\t\t#if swift(>=4.1)\n\t\t\tself.readBuffer.initialize(to: 0)\n\t\t#else\n\t\t\tself.readBuffer.initialize(to: 0, count: readBufferSize)\n\t\t#endif\n\n\t\t// If the family is .unix, set the protocol to .unix as well...\n\t\tvar sockProto = proto\n\t\tif family == .unix {\n\t\t\tsockProto = .unix\n\t\t}\n\n\t\t// Create the socket...\n\t\t#if os(Linux)\n\t\t\tself.socketfd = Glibc.socket(family.value, type.value, sockProto.value)\n\t\t#else\n\t\t\tself.socketfd = Darwin.socket(family.value, type.value, sockProto.value)\n\t\t#endif\n\n\t\t// If error, throw an appropriate exception...\n\t\tif self.socketfd < 0 {\n\n\t\t\tself.socketfd = Socket.SOCKET_INVALID_DESCRIPTOR\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_UNABLE_TO_CREATE_SOCKET, reason: self.lastError())\n\t\t}\n\n\t\ttry self.ignoreSIGPIPE(on: self.socketfd)\n\n\t\t// Create the signature...\n\t\ttry self.signature = Signature(\n\t\t\tprotocolFamily: family.value,\n\t\t\tsocketType: type.value,\n\t\t\tproto: sockProto.value,\n\t\t\taddress: nil)\n\t}\n\n\t///\n\t/// Private constructor to create an instance for existing open socket fd.\n\t///\n\t/// - Parameters:\n\t///\t\t- fd: \t\t\t\tOpen file descriptor.\n\t///\t\t- remoteAddress: \tThe Address associated with the open fd.\n\t///\n\t/// - Returns: New Socket instance\n\t///\n\tprivate init(fd: Int32, remoteAddress: Address, path: String? = nil) throws {\n\n\t\tself.isConnected = true\n\t\tself.isListening = false\n\t\t#if swift(>=4.1)\n\t\t\tself.readBuffer.initialize(to: 0)\n\t\t#else\n\t\t\tself.readBuffer.initialize(to: 0, count: readBufferSize)\n\t\t#endif\n\n\t\tself.socketfd = fd\n\n\t\t// Create the signature...\n\t\t#if os(Linux)\n\t\t\tlet type = Int32(SOCK_STREAM.rawValue)\n\t\t#else\n\t\t\tlet type = SOCK_STREAM\n\t\t#endif\n\t\t\n\t\ttry self.ignoreSIGPIPE(on: self.socketfd)\n\n\t\tif path != nil {\n\n\t\t\ttry self.signature = Signature(socketType: .stream, proto: .unix, path: path)\n\n\t\t} else {\n\t\t\tif let (hostname, port) = Socket.hostnameAndPort(from: remoteAddress) {\n\t\t\t\ttry self.signature = Signature(\n\t\t\t\t\tprotocolFamily: remoteAddress.family.value,\n\t\t\t\t\tsocketType: type,\n\t\t\t\t\tproto: Int32(IPPROTO_TCP),\n\t\t\t\t\taddress: remoteAddress,\n\t\t\t\t\thostname: hostname,\n\t\t\t\t\tport: port)\n\t\t\t} else {\n\t\t\t\ttry self.signature = Signature(\n\t\t\t\t\tprotocolFamily: remoteAddress.family.value,\n\t\t\t\t\tsocketType: type,\n\t\t\t\t\tproto: Int32(IPPROTO_TCP),\n\t\t\t\t\taddress: remoteAddress)\n\t\t\t}\n\t\t}\n\t}\n\n    ///\n    /// Cleanup: close the socket, free memory buffers.\n    ///\n    deinit {\n\n        if self.socketfd > 0 {\n\n            self.close()\n        }\n\n        // Destroy and free the readBuffer...\n\t\t#if swift(>=4.1)\n\t\t\tself.readBuffer.deinitialize(count: readBufferSize)\n\t\t\tself.readBuffer.deallocate()\n\t\t#else\n\t\t\tself.readBuffer.deinitialize()\n\t\t\tself.readBuffer.deallocate(capacity: self.readBufferSize)\n\t\t#endif\n    }\n\n\t// MARK: Public Functions\n\n\t// MARK: -- Accept\n\n\t///\n\t/// Accepts an incoming client connection request on the current instance, leaving the current instance still listening.\n    ///\n    /// - Parameters:\n    ///\t\t- invokeDelegate: \t\tWhether to invoke the delegate's `onAccept()` function after accepting\n    ///                             a new connection. Defaults to `true`\n\t///\n\t/// - Returns: New Socket instance representing the newly accepted socket.\n\t///\n    public func acceptClientConnection(invokeDelegate: Bool = true) throws -> Socket {\n\n\t\t// The socket must've been created, not connected and listening...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"The socket has an invalid descriptor\")\n\t\t}\n\n\t\tif self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_ALREADY_CONNECTED, reason: \"The socket is not connected\")\n\t\t}\n\n\t\tif !self.isListening {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_NOT_LISTENING, reason: \"The socket is not listening\")\n\t\t}\n\n\t\t// Accept the remote connection...\n\t\tvar socketfd2: Int32 = Socket.SOCKET_INVALID_DESCRIPTOR\n\t\tvar address: Address? = nil\n\n\t\tvar keepRunning: Bool = true\n\t\trepeat {\n\t\t\tdo {\n\t\t\t\tguard let acceptAddress = try Address(addressProvider: { (addressPointer, addressLengthPointer) in\n\t\t\t\t\t#if os(Linux)\n\t\t\t\t\t\tlet fd = Glibc.accept(self.socketfd, addressPointer, addressLengthPointer)\n\t\t\t\t\t#else\n\t\t\t\t\t\tlet fd = Darwin.accept(self.socketfd, addressPointer, addressLengthPointer)\n\t\t\t\t\t#endif\n\t\t\t\t\t\n\t\t\t\t\tif fd < 0 {\n\t\t\t\t\t\t\n\t\t\t\t\t\t// The operation was interrupted, continue the loop...\n\t\t\t\t\t\tif errno == EINTR {\n\t\t\t\t\t\t\tthrow OperationInterrupted.accept\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\t// Note: if you're running tests inside Xcode and the tests stop on this line\n\t\t\t\t\t\t//  and the tests fail, but they work if you run `swift test` on the\n\t\t\t\t\t\t//  command line, Hit `Deactivate Breakpoints` in Xcode and try again\n\t\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_ACCEPT_FAILED, reason: self.lastError())\n\t\t\t\t\t}\n\t\t\t\t\tsocketfd2 = fd\n\t\t\t\t}) else {\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"Unable to determine incoming socket protocol family.\")\n\t\t\t\t}\n\t\t\t\taddress = acceptAddress\n\t\t\t\t\n\t\t\t} catch OperationInterrupted.accept {\n\t\t\t\t\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tkeepRunning = false\n\n\t\t} while keepRunning\n\n\t\t// Create the new socket...\n\t\t//\tNote: The current socket continues to listen.\n\t\tlet newSocket = try Socket(fd: socketfd2, remoteAddress: address!, path: self.signature?.path)\n\t\t\n\t\t// If there's a delegate, turn on the needs accept flag...\n\t\tif self.delegate != nil {\n\t\t\tnewSocket.needsAcceptDelegateCall = true\n\t\t}\n\n        // Let the delegate do post accept handling and verification...\n        if invokeDelegate, self.delegate != nil {\n            try invokeDelegateOnAccept(for: newSocket)\n        }\n\t\t\n        // Return the new socket...\n        return newSocket\n    }\n\t\n\t///\n    /// Invokes the delegate's `onAccept()` function for a client socket. This should be performed\n    /// only with a Socket obtained by calling `acceptClientConnection(invokeDelegate: false)`.\n    ///\n    /// - Parameters:\n    ///\t\t- newSocket: \t\tThe newly accepted Socket that requires further processing by our delegate\n    ///\n    public func invokeDelegateOnAccept(for newSocket: Socket) throws {\n\t\t\n\t\t// Only allow this if the socket needs it, otherwise it's a error...\n\t\tif !newSocket.needsAcceptDelegateCall {\n\t\t\t\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INVALID_DELEGATE_CALL, reason: \"Socket does not need a delegate accept call\")\n\t\t}\n\t\t\n\t\tdo {\n\t\t\t\n\t\t\tif self.delegate != nil {\n\t\t\t\ttry self.delegate?.onAccept(socket: newSocket)\n\t\t\t\tnewSocket.signature?.isSecure = true\n\t\t\t\tself.needsAcceptDelegateCall = false\n            }\n\t\t\t\n        } catch let error {\n\t\t\t\n\t\t\tguard let sslError = error as? SSLError else {\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\t\n\t\t\tthrow Error(with: sslError)\n\t\t}\n\t}\n\n\t///\n\t/// Accepts an incoming connection request replacing the existing socket with the newly accepted one.\n\t///\n\tpublic func acceptConnection() throws {\n\n\t\t// The socket must've been created, not connected and listening...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\tif self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_ALREADY_CONNECTED, reason: \"Socket is not connected\")\n\t\t}\n\n\t\tif !self.isListening {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_NOT_LISTENING, reason: \"Socket is not listening\")\n\t\t}\n\n\t\t// Accept the remote connection...\n\t\tvar socketfd2: Int32 = Socket.SOCKET_INVALID_DESCRIPTOR\n\t\tvar address: Address? = nil\n\n\t\tvar keepRunning: Bool = true\n\t\trepeat {\n\t\t\tdo {\n\t\t\t\tguard let acceptAddress = try Address(addressProvider: { (addressPointer, addressLengthPointer) in\n\t\t\t\t\t#if os(Linux)\n\t\t\t\t\t\tlet fd = Glibc.accept(self.socketfd, addressPointer, addressLengthPointer)\n\t\t\t\t\t#else\n\t\t\t\t\t\tlet fd = Darwin.accept(self.socketfd, addressPointer, addressLengthPointer)\n\t\t\t\t\t#endif\n\t\t\t\t\t\n\t\t\t\t\tif fd < 0 {\n\t\t\t\t\t\t\n\t\t\t\t\t\t// The operation was interrupted, continue the loop...\n\t\t\t\t\t\tif errno == EINTR {\n\t\t\t\t\t\t\tthrow OperationInterrupted.accept\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\t// Note: if you're running tests inside Xcode and the tests stop on this line\n\t\t\t\t\t\t//  and the tests fail, but they work if you run `swift test` on the\n\t\t\t\t\t\t//  command line, Hit `Deactivate Breakpoints` in Xcode and try again\n\t\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_ACCEPT_FAILED, reason: self.lastError())\n\t\t\t\t\t}\n\t\t\t\t\tsocketfd2 = fd\n\t\t\t\t}) else {\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"Unable to determine incoming socket protocol family.\")\n\t\t\t\t}\n\t\t\t\taddress = acceptAddress\n\t\t\t\t\n\t\t\t} catch OperationInterrupted.accept {\n\t\t\t\t\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t\n\t\t\tkeepRunning = false\n\n\t\t} while keepRunning\n\n\t\t// Close the old socket...\n\t\tself.close()\n\n\t\t// Save the address...\n\t\tself.signature!.address = address\n\n\t\t// Replace the existing socketfd with the new one...\n\t\tself.socketfd = socketfd2\n\n\t\tif let (hostname, port) = Socket.hostnameAndPort(from: address!) {\n\t\t\tself.signature!.hostname = hostname\n\t\t\tself.signature!.port = port\n\t\t}\n\n\t\t// We're connected but no longer listening...\n\t\tself.isConnected = true\n\t\tself.isListening = false\n\n\t\t// Let the delegate do post accept handling and verification...\n\t\tdo {\n\n\t\t\tif self.delegate != nil {\n\t\t\t\ttry self.delegate?.onAccept(socket: self)\n\t\t\t\tself.signature?.isSecure = true\n\t\t\t}\n\n\t\t} catch let error {\n\n\t\t\tguard let sslError = error as? SSLError else {\n\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\tthrow Error(with: sslError)\n\t\t}\n\t}\n\n\t// MARK: -- Close\n\n\t///\n\t/// Closes the current socket.\n\t///\n\tpublic func close() {\n\n\t\tself.close(withSSLCleanup: true)\n\t}\n\n\t// MARK: -- Connect\n\n\t///\n\t/// Connects to the named host on the specified port.\n\t///\n\t/// - Parameters:\n\t///\t\t- host:\t\t\tThe host name to connect to.\n\t///\t\t- port:\t\t\tThe port to be used.\n\t///\t\t- timeout:\t\tTimeout to use (in msec). *Note: If the socket is in blocking mode it\n\t///\t\t\t\t\t\twill be changed to non-blocking mode temporarily if a timeout greater\n\t///\t\t\t\t\t\tthan zero (0) is provided. The returned socket will be set back to its\n\t///\t\t\t\t\t\toriginal setting (blocking or non-blocking).*\n\t///\t\t- familyOnly:\tSetting this to `true` will only connect to a socket of the family of the\n\t///\t\t\t\t\t\tcurrent instance of *Socket*.  Setting it to `false`, will allow connection\n\t///\t\t\t\t\t\tto foreign sockets of a different family.  Default is *false*.\n\t///\n\tpublic func connect(to host: String, port: Int32, timeout: UInt = 0, familyOnly: Bool = false) throws {\n\n\t\t// The socket must've been created and must not be connected...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\tif self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_ALREADY_CONNECTED, reason: \"Socket is already connected\")\n\t\t}\n\n\t\tif host.utf8.count == 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INVALID_HOSTNAME, reason: \"Socket has an invalid hostname\")\n\t\t}\n\t\t\n\t\tif !self.isBlocking && timeout == 0 {\n\t\t\t\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_PARAMETER_ERROR, reason: \"No timeout set on call for non-blocking socket.\")\n\t\t}\n\n\t\tif port == 0 || port > 65535 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INVALID_PORT, reason: \"The port specified is invalid. Must be in the range of 1-65535.\")\n\t\t}\n\t\t\n\t\t// Tell the delegate to initialize as a client...\n\t\tdo {\n\n\t\t\ttry self.delegate?.initialize(asServer: false)\n\n\t\t} catch let error {\n\n\t\t\tguard let sslError = error as? SSLError else {\n\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\tthrow Error(with: sslError)\n\t\t}\n\n\t\t// Create the hints for our search...\n\t\tlet socketType: SocketType = signature?.socketType ?? .stream\n\t\t#if os(Linux)\n\t\t\tvar hints = addrinfo(\n\t\t\t\tai_flags: AI_PASSIVE,\n\t\t\t\tai_family: familyOnly ? signature?.protocolFamily.value ?? AF_UNSPEC : AF_UNSPEC,\n\t\t\t\tai_socktype: socketType.value,\n\t\t\t\tai_protocol: 0,\n\t\t\t\tai_addrlen: 0,\n\t\t\t\tai_addr: nil,\n\t\t\t\tai_canonname: nil,\n\t\t\t\tai_next: nil)\n\t\t#else\n\t\t\tvar hints = addrinfo(\n\t\t\t\tai_flags: AI_PASSIVE,\n\t\t\t\tai_family: familyOnly ? signature?.protocolFamily.value ?? AF_UNSPEC : AF_UNSPEC,\n\t\t\t\tai_socktype: socketType.value,\n\t\t\t\tai_protocol: 0,\n\t\t\t\tai_addrlen: 0,\n\t\t\t\tai_canonname: nil,\n\t\t\t\tai_addr: nil,\n\t\t\t\tai_next: nil)\n\t\t#endif\n\n\t\tvar targetInfo: UnsafeMutablePointer<addrinfo>?\n\n\t\t// Retrieve the info on our target...\n\t\tvar status: Int32 = getaddrinfo(host, String(port), &hints, &targetInfo)\n\t\tif status != 0 {\n\n\t\t\tvar errorString: String\n\t\t\tif status == EAI_SYSTEM {\n\t\t\t\terrorString = String(validatingUTF8: strerror(errno)) ?? \"Unknown error code.\"\n\t\t\t} else {\n\t\t\t\terrorString = String(validatingUTF8: gai_strerror(status)) ?? \"Unknown error code.\"\n\t\t\t}\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_GETADDRINFO_FAILED, reason: errorString)\n\t\t}\n\n\t\t// Defer cleanup of our target info...\n\t\tdefer {\n\n\t\t\tif targetInfo != nil {\n\t\t\t\tfreeaddrinfo(targetInfo)\n\t\t\t}\n\t\t}\n\n\t\tvar socketDescriptor: Int32?\n\t\tdefer {\n\t\t\t// if we throw an error, be sure we clean up any dangling socket properly.\n\t\t\t// note that we set this variable to nil when we assign the socket to `self.socketfd`.\n\t\t\tif let sock = socketDescriptor, sock != Socket.SOCKET_INVALID_DESCRIPTOR {\n\t\t\t\t#if os(Linux)\n\t\t\t\t\t_ = Glibc.close(socketDescriptor!)\n\t\t\t\t#else\n\t\t\t\t\t_ = Darwin.close(socketDescriptor!)\n\t\t\t\t#endif\n\t\t\t}\n\t\t}\n\n\t\tvar info = targetInfo\n\t\twhile info != nil {\n\n\t\t\t#if os(Linux)\n\t\t\t\tsocketDescriptor = Glibc.socket(info!.pointee.ai_family, info!.pointee.ai_socktype, info!.pointee.ai_protocol)\n\t\t\t#else\n\t\t\t\tsocketDescriptor = Darwin.socket(info!.pointee.ai_family, info!.pointee.ai_socktype, info!.pointee.ai_protocol)\n\t\t\t#endif\n\t\t\tif socketDescriptor == -1 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t\n\t\t\t// Check to see if the socket is in non-blocking mode or if a timeout is provided\n\t\t\t// \tIf either is the case, set our trial socket to be non-blocking as well...\n\t\t\tif !self.isBlocking || timeout > 0 {\n\t\t\t\t\n\t\t\t\tlet flags = fcntl(socketDescriptor!, F_GETFL)\n\t\t\t\tif flags < 0 {\n\t\t\t\t\t\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_GET_FCNTL_FAILED, reason: self.lastError())\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tlet result = fcntl(socketDescriptor!, F_SETFL, flags | O_NONBLOCK)\n\t\t\t\tif result < 0 {\n\t\t\t\t\t\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_SET_FCNTL_FAILED, reason: self.lastError())\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Connect to the server...\n\t\t\t#if os(Linux)\n\t\t\t\tstatus = Glibc.connect(socketDescriptor!, info!.pointee.ai_addr, info!.pointee.ai_addrlen)\n\t\t\t#else\n\t\t\t\tstatus = Darwin.connect(socketDescriptor!, info!.pointee.ai_addr, info!.pointee.ai_addrlen)\n\t\t\t#endif\n\n\t\t\t// Break if successful...\n\t\t\tif status == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t\n\t\t\t// If this is a non-blocking socket, check errno for EINPROGRESS and if set we've got a timeout, wait the appropriate time...\n\t\t\tif errno == EINPROGRESS {\n\t\t\t\t\n\t\t\t\tif timeout > 0 {\n\t\t\t\t\t\n\t\t\t\t\t// Set up for the select call...\n\t\t\t\t\tvar writefds = fd_set()\n\t\t\t\t\twritefds.zero()\n\t\t\t\t\twritefds.set(socketDescriptor!)\n\t\t\t\t\t\n\t\t\t\t\tvar timer = timeval()\n\t\t\t\t\t\n\t\t\t\t\t// First get seconds...\n\t\t\t\t\tlet secs = Int(Double(timeout / 1000))\n\t\t\t\t\ttimer.tv_sec = secs\n\t\t\t\t\t\n\t\t\t\t\t// Now get the leftover millisecs...\n\t\t\t\t\tlet msecs = Int32(Double(timeout % 1000))\n\t\t\t\t\t\n\t\t\t\t\t// Note: timeval expects microseconds, convert now...\n\t\t\t\t\tlet uSecs = msecs * 1000\n\t\t\t\t\t\n\t\t\t\t\t// Now the leftover microseconds...\n\t\t\t\t\t#if os(Linux)\n\t\t\t\t\t\ttimer.tv_usec = Int(uSecs)\n\t\t\t\t\t#else\n\t\t\t\t\t\ttimer.tv_usec = Int32(uSecs)\n\t\t\t\t\t#endif\n\t\t\t\t\t\n\t\t\t\t\tlet count = select(socketDescriptor! + Int32(1), nil, &writefds, nil, &timer)\n\t\t\t\t\tif count < 0 {\n\t\t\t\t\t\t\n\t\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_SELECT_FAILED, reason: self.lastError())\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// If the socket is writable, we're probably connected, but check anyway to be sure...\n\t\t\t\t\t//\t  Otherwise, we've timed out waiting to connect.\n\t\t\t\t\tif writefds.isSet(socketDescriptor!) {\n\t\t\t\t\t\t\n\t\t\t\t\t\t// Check the socket...\n\t\t\t\t\t\tvar result: Int = 0\n\t\t\t\t\t\tvar resultLength = socklen_t(MemoryLayout<Int>.size)\n\t\t\t\t\t\tif getsockopt(socketDescriptor!, SOL_SOCKET, SO_ERROR, &result, &resultLength) < 0 {\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_GETSOCKOPT_FAILED, reason: self.lastError())\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\t// Check the result of the socket connect...\n\t\t\t\t\t\tif result == 0 {\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// Success, we're connected, clear status and break out of the loop...\n\t\t\t\t\t\t\tstatus = 0\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t} else {\n\t\t\t\t\t\t\n\t\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_CONNECT_TIMEOUT, reason: self.lastError())\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Close the socket that was opened... Protocol family may have changed...\n\t\t\t#if os(Linux)\n\t\t\t\t_ = Glibc.close(socketDescriptor!)\n\t\t\t#else\n\t\t\t\t_ = Darwin.close(socketDescriptor!)\n\t\t\t#endif\n\t\t\tsocketDescriptor = nil\n\t\t\tinfo = info?.pointee.ai_next\n\t\t}\n\n\t\t// Throw if there is a status error...\n\t\tif status != 0 || socketDescriptor == nil {\n\n\t\t\tif socketDescriptor != nil {\n\t\t\t\t#if os(Linux)\n\t\t\t\t\t_ = Glibc.close(socketDescriptor!)\n\t\t\t\t#else\n\t\t\t\t\t_ = Darwin.close(socketDescriptor!)\n\t\t\t\t#endif\n\t\t\t}\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_GETADDRINFO_FAILED, reason: self.lastError())\n\t\t}\n\n\t\t// Close the existing socket (if open) before replacing it...\n\t\tif self.socketfd != Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tself.close(withSSLCleanup: false)\n\t\t}\n\n\t\tself.socketfd = socketDescriptor!\n\t\tsocketDescriptor = nil\t\t// clear out the temporary value -- our defer() can check for that alone\n\t\t\n\t\tself.isConnected = true\n\t\tvar address: Address\n\t\tif info!.pointee.ai_family == Int32(AF_INET6) {\n\n\t\t\tvar addr = sockaddr_in6()\n\t\t\tmemcpy(&addr, info!.pointee.ai_addr, Int(MemoryLayout<sockaddr_in6>.size))\n\t\t\taddress = .ipv6(addr)\n\n\t\t} else if info!.pointee.ai_family == Int32(AF_INET) {\n\n\t\t\tvar addr = sockaddr_in()\n\t\t\tmemcpy(&addr, info!.pointee.ai_addr, Int(MemoryLayout<sockaddr_in>.size))\n\t\t\taddress = .ipv4(addr)\n\n\t\t} else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"Unable to determine connected socket protocol family.\")\n\t\t}\n\n\t\ttry self.ignoreSIGPIPE(on: self.socketfd)\n\n\t\ttry self.signature = Signature(\n\t\t\tprotocolFamily: Int32(info!.pointee.ai_family),\n\t\t\tsocketType: info!.pointee.ai_socktype,\n\t\t\tproto: info!.pointee.ai_protocol,\n\t\t\taddress: address,\n\t\t\thostname: host,\n\t\t\tport: port)\n\t\t\n\t\t// Check to see if the socket is supposed to be blocking or non-blocking and adjust the new socket...\n\t\tif self.isBlocking && timeout > 0 {\n\t\t\t\n\t\t\t// Socket supposed to be blocking but we've changed it to non-blocking because\n\t\t\t//\ta timeout was requested...  Got to change it back before proceeding...\n\t\t\tlet flags = fcntl(self.socketfd, F_GETFL)\n\t\t\tif flags < 0 {\n\t\t\t\t\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_GET_FCNTL_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t\t\n\t\t\tlet result = fcntl(self.socketfd, F_SETFL, flags & ~O_NONBLOCK)\n\t\t\tif result < 0 {\n\t\t\t\t\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_SET_FCNTL_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t}\n\n\t\t// Let the delegate do post connect handling and verification...\n\t\tdo {\n\n\t\t\tif self.delegate != nil {\n\t\t\t\ttry self.delegate?.onConnect(socket: self)\n\t\t\t\tself.signature?.isSecure = true\n\t\t\t}\n\n\t\t} catch let error {\n\n\t\t\tguard let sslError = error as? SSLError else {\n\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\tthrow Error(with: sslError)\n\t\t}\n\t}\n\n\t///\n\t/// Connects to the named host on the specified port.\n\t///\n\t/// - Parameters path:\tPath to connect to.\n\t///\n\tpublic func connect(to path: String) throws {\n\n\t\t// Make sure this is a UNIX socket...\n\t\tguard let sig = self.signature, sig.protocolFamily == .unix else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"Socket has the wrong protocol, it must be UNIX socket\")\n\t\t}\n\n\t\t// The socket must've been created and must not be connected...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\tif self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_ALREADY_CONNECTED, reason: \"Socket is already connected\")\n\t\t}\n\n\t\t// Create the signature...\n\t\tself.signature = try Signature(socketType: .stream, proto: .unix, path: path)\n\t\tguard let signature = self.signature else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_MISSING_CONNECTION_DATA, reason: \"Unable to access connection data.\")\n\t\t}\n\n\t\t// Now, do the connection using the supplied address...\n\t\tlet (addrPtr, addrLen) = try signature.unixAddress()\n\t\tdefer {\n\t\t\t#if swift(>=4.1)\n\t\t\t\taddrPtr.deallocate()\n\t\t\t#else\n\t\t\t\taddrPtr.deallocate(capacity: addrLen)\n\t\t\t#endif\n\t\t}\n\n\t\tlet rc = addrPtr.withMemoryRebound(to: sockaddr.self, capacity: 1) {\n\t\t\t\n\t\t\t(p: UnsafeMutablePointer<sockaddr>) -> Int32 in\n\n\t\t\t#if os(Linux)\n\t\t\t\treturn Glibc.connect(self.socketfd, p, socklen_t(addrLen))\n\t\t\t#else\n\t\t\t\treturn Darwin.connect(self.socketfd, p, socklen_t(addrLen))\n\t\t\t#endif\n\t\t}\n\t\tif rc < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_CONNECT_FAILED, reason: self.lastError())\n\t\t}\n\n\t\tself.isConnected = true\n\t}\n\n\t///\n\t/// Connect to the address or hostname/port or path pointed to by the signature passed.\n\t///\n\t/// - Parameter signature:\tSignature containing the address hostname/port to connect to.\n\t///\n\tpublic func connect(using signature: Signature) throws {\n\n\t\t// Make sure we've got a valid socket...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// Ensure we've got a proper address...\n\t\t//\tHandle the Unix style socket first...\n\t\tif let path = signature.path {\n\n\t\t\ttry self.connect(to: path)\n\t\t\treturn\n\t\t}\n\t\t\n\t\tif let address = signature.address {\n\t\t\t\n\t\t\t// Tell the delegate to initialize as a client...\n\t\t\tdo {\n\t\t\t\t\n\t\t\t\ttry self.delegate?.initialize(asServer: false)\n\t\t\t\t\n\t\t\t} catch let error {\n\t\t\t\t\n\t\t\t\tguard let sslError = error as? SSLError else {\n\t\t\t\t\t\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthrow Error(with: sslError)\n\t\t\t}\n\t\t\t\n\t\t\t// Now, do the connection using the supplied address...\n\t\t\tlet rc = address.withSockAddrPointer { sockaddr, length -> Int32 in\n\t\t\t\t#if os(Linux)\n\t\t\t\t\treturn Glibc.connect(self.socketfd, sockaddr, length)\n\t\t\t\t#else\n\t\t\t\t\treturn Darwin.connect(self.socketfd, sockaddr, length)\n\t\t\t\t#endif\n\t\t\t}\n\t\t\t\n\t\t\tif rc < 0 {\n\t\t\t\t\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_CONNECT_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t\t\n\t\t\t// Complete the signature...\n\t\t\tif signature.hostname != nil, signature.port != Socket.SOCKET_INVALID_PORT {\n\t\t\t\t\n\t\t\t\tself.signature = signature\n\t\t\t\tself.isConnected = true\n\t\t\t\t\n\t\t\t} else if let (hostname, port) = Socket.hostnameAndPort(from: signature.address!) {\n\n\t\t\t\tvar sig = signature\n\t\t\t\tsig.hostname = hostname\n\t\t\t\tsig.port = Int32(port)\n\t\t\t\tself.signature = sig\n\t\t\t\tself.isConnected = true\n\t\t\t}\n\t\t\t\n\t\t\t// Let the delegate do post connect handling and verification...\n\t\t\tdo {\n\t\t\t\t\n\t\t\t\tif self.delegate != nil {\n\t\t\t\t\ttry self.delegate?.onConnect(socket: self)\n\t\t\t\t\tself.signature?.isSecure = true\n\t\t\t\t}\n\t\t\t\t\n\t\t\t} catch let error {\n\t\t\t\t\n\t\t\t\tguard let sslError = error as? SSLError else {\n\t\t\t\t\t\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthrow Error(with: sslError)\n\t\t\t}\n\t\t\t\n\t\t\treturn\n\t\t}\n\t\t\n\t\t// If here, we'll check to see if we've got a hostname and port and if so, try to connect using it...\n\t\tif let hostname = signature.hostname, signature.port != Socket.SOCKET_INVALID_PORT {\n\t\t\t// Connect using hostname and port....\n\t\t\ttry self.connect(to: hostname, port: signature.port)\n\t\t\treturn\n\t\t}\n\t\t\n\t\t// No such luck, don't have enough info to initiate a connection...\n\t\tthrow Error(code: Socket.SOCKET_ERR_MISSING_CONNECTION_DATA, reason: \"Unable to access connection data.\")\n\t}\n\n\t// MARK: -- Listen\n\n\t// MARK: --- TCP\n\n\t///\n\t/// Listen on a port, limiting the maximum number of pending connections.\n\t///\n\t/// - Parameters:\n\t///\t\t- port: \t\t\t\tThe port to listen on.\n\t/// \t- maxBacklogSize: \t\tThe maximum size of the queue containing pending connections. Default is *Socket.SOCKET_DEFAULT_MAX_BACKLOG*.\n\t///\t\t- allowPortReuse:\t\tSet to `true` to allow the port to be reused. `false` otherwise. Default is `true`.\n\t///\t\t- node:\t\t\t\t\tCan be set to listen on a *specific address*. The value passed is an *optional String* containing the numerical\n\t///\t\t\t\t\t\t\t\tnetwork address (for IPv4, numbers and dots notation, for iPv6, hexidecimal strting). If `nil`, a suitable address\n\t///\t\t\t\t\t\t\t\twill be used.\n\t///\n\tpublic func listen(on port: Int, maxBacklogSize: Int = Socket.SOCKET_DEFAULT_MAX_BACKLOG, allowPortReuse: Bool = true, node: String? = nil) throws {\n\n\t\t// Make sure we've got a valid socket...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// Set a flag so that this address can be re-used immediately after the connection\n\t\t// closes.  (TCP normally imposes a delay before an address can be re-used.)\n\t\tvar on: Int32 = 1\n\t\tif setsockopt(self.socketfd, SOL_SOCKET, SO_REUSEADDR, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())\n\t\t}\n\n\t\t// Allow port reuse if the caller desires...\n\t\tif allowPortReuse {\n\t\t\t\n\t\t\t// SO_REUSEPORT allows completely duplicate bindings by multiple processes if they\n\t\t\t// all set SO_REUSEPORT before binding the port.  This option permits multiple\n\t\t\t// instances of a program to each receive UDP/IP multicast or broadcast datagrams\n\t\t\t// destined for the bound port.\n\t\t\tif setsockopt(self.socketfd, SOL_SOCKET, SO_REUSEPORT, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {\n\t\t\t\t\n\t\t\t\t// Setting of this option on WSL (Windows Subsytem for Linux) is not supported.  Check for\n\t\t\t\t// the appropriate errno value and if set, ignore the error...\n\t\t\t\tif errno != ENOPROTOOPT {\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Get the signature for the socket...\n\t\tguard let sig = self.signature else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INTERNAL, reason: \"Socket signature not found.\")\n\t\t}\n\n        // Configure ipv6 socket so that it can share ports with ipv4 on the same port.\n        if sig.protocolFamily == .inet6 && sig.proto == .tcp {\n            if setsockopt(self.socketfd, Int32(IPPROTO_IPV6), IPV6_V6ONLY, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {\n\n                throw Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())\n            }\n        }\n\n\t\t// No SSL over UDP...\n\t\tif sig.socketType != .datagram && sig.proto != .udp {\n\n\t\t\t// Tell the delegate to initialize as a server...\n\t\t\tdo {\n\n\t\t\t\ttry self.delegate?.initialize(asServer: true)\n\n\t\t\t} catch let error {\n\n\t\t\t\tguard let sslError = error as? SSLError else {\n\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\n\t\t\t\tthrow Error(with: sslError)\n\t\t\t}\n\t\t}\n\n\t\t// Create the hints for our search...\n\t\t#if os(Linux)\n\t\t\tvar hints = addrinfo(\n\t\t\t\tai_flags: AI_PASSIVE,\n\t\t\t\tai_family: sig.protocolFamily.value,\n\t\t\t\tai_socktype: sig.socketType.value,\n\t\t\t\tai_protocol: 0,\n\t\t\t\tai_addrlen: 0,\n\t\t\t\tai_addr: nil,\n\t\t\t\tai_canonname: nil,\n\t\t\t\tai_next: nil)\n\t\t#else\n\t\t\tvar hints = addrinfo(\n\t\t\t\tai_flags: AI_PASSIVE,\n\t\t\t\tai_family: sig.protocolFamily.value,\n\t\t\t\tai_socktype: sig.socketType.value,\n\t\t\t\tai_protocol: 0,\n\t\t\t\tai_addrlen: 0,\n\t\t\t\tai_canonname: nil,\n\t\t\t\tai_addr: nil,\n\t\t\t\tai_next: nil)\n\t\t#endif\n\n\t\tvar targetInfo: UnsafeMutablePointer<addrinfo>?\n\t\t\n\t\t// Retrieve the info on our target...\n\t\tlet status: Int32 = getaddrinfo(node ?? nil, String(port), &hints, &targetInfo)\n\t\tif status != 0 {\n\n\t\t\tvar errorString: String\n\t\t\tif status == EAI_SYSTEM {\n\t\t\t\terrorString = String(validatingUTF8: strerror(errno)) ?? \"Unknown error code.\"\n\t\t\t} else {\n\t\t\t\terrorString = String(validatingUTF8: gai_strerror(errno)) ?? \"Unknown error code.\"\n\t\t\t}\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_GETADDRINFO_FAILED, reason: errorString)\n\t\t}\n\n\t\t// Defer cleanup of our target info...\n\t\tdefer {\n\n\t\t\tif targetInfo != nil {\n\t\t\t\tfreeaddrinfo(targetInfo)\n\t\t\t}\n\t\t}\n\n\t\tvar info = targetInfo\n\t\tvar bound = false\n\t\t\n\t\twhile info != nil {\n\n\t\t\t// Try to bind the socket to the address...\n\t\t\t#if os(Linux)\n\t\t\t\tif Glibc.bind(self.socketfd, info!.pointee.ai_addr, info!.pointee.ai_addrlen) == 0 {\n\n\t\t\t\t\t// Success... We've found our address...\n\t\t\t\t\tbound = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t#else\n\t\t\t\tif Darwin.bind(self.socketfd, info!.pointee.ai_addr, info!.pointee.ai_addrlen) == 0 {\n\n\t\t\t\t\t// Success... We've found our address...\n\t\t\t\t\tbound = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t#endif\n\n\t\t\t// Try the next one...\n\t\t\tinfo = info?.pointee.ai_next\n\t\t}\n\n\t\t// Throw an error if we weren't able to bind to an address...\n\t\tif !bound {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BIND_FAILED, reason: self.lastError())\n\t\t}\n\n\t\t// Save the address info...\n\t\tvar address: Address\n\n\t\t// If the port was set to zero, we need to retrieve the port that assigned by the OS...\n\t\tif port == 0 {\n\t\t\tguard let addressFromSockName = try Address(addressProvider: { (sockaddr, length) in\n\t\t\t\tif getsockname(self.socketfd, sockaddr, length) != 0 {\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_BIND_FAILED, reason: \"Unable to determine listening socket address after bind.\")\n\t\t\t\t}\n\t\t\t}) else {\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"Unable to determine listening socket protocol family.\")\n\t\t\t}\n\t\t\taddress = addressFromSockName\n\t\t} else {\n\n\t\t\tif info!.pointee.ai_family == Int32(AF_INET6) {\n\n\t\t\t\tvar addr = sockaddr_in6()\n\t\t\t\tmemcpy(&addr, info!.pointee.ai_addr, Int(MemoryLayout<sockaddr_in6>.size))\n\t\t\t\taddress = .ipv6(addr)\n\n\t\t\t} else if info!.pointee.ai_family == Int32(AF_INET) {\n\n\t\t\t\tvar addr = sockaddr_in()\n\t\t\t\tmemcpy(&addr, info!.pointee.ai_addr, Int(MemoryLayout<sockaddr_in>.size))\n\t\t\t\taddress = .ipv4(addr)\n\n\t\t\t} else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"Unable to determine listening socket protocol family.\")\n\t\t\t}\n\n\t\t}\n\n\t\t// Update our hostname and port...\n\t\tif let (hostname, port) = Socket.hostnameAndPort(from: address) {\n\t\t\tself.signature?.hostname = hostname\n\t\t\tself.signature?.port = Int32(port)\n\t\t}\n\n\t\tself.signature?.isBound = true\n\t\tself.signature?.address = address\n\n\t\t// We don't actually listen for connections with a UDP socket, so we skip the next steps...\n\t\tif sig.socketType == .datagram && sig.proto == .udp {\n\t\t\treturn\n\t\t}\n\n\t\t// Now listen for connections...\n\t\t#if os(Linux)\n\t\t\tif Glibc.listen(self.socketfd, Int32(maxBacklogSize)) < 0 {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_LISTEN_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t#else\n\t\t\tif Darwin.listen(self.socketfd, Int32(maxBacklogSize)) < 0 {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_LISTEN_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t#endif\n\n\t\tself.isListening = true\n\t\tself.signature?.isSecure = self.delegate != nil ? true : false\n\t}\n\n\t// MARK: --- UNIX\n\n\t///\n\t/// Listen on a path, limiting the maximum number of pending connections.\n\t///\n\t/// - Parameters:\n\t///\t\t- path: \t\t\t\tThe path to listen on.\n\t/// \t- maxBacklogSize: \t\tThe maximum size of the queue containing pending connections. Default is *Socket.SOCKET_DEFAULT_MAX_BACKLOG*.\n\t///\n\tpublic func listen(on path: String, maxBacklogSize: Int = Socket.SOCKET_DEFAULT_MAX_BACKLOG) throws {\n\n\t\t// Make sure we've got a valid socket...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// Make sure this is a UNIX socket...\n\t\tguard let sockSig = self.signature, sockSig.protocolFamily == .unix else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"Socket has the wrong protocol, it must be a UNIX socket\")\n\t\t}\n\n\t\t// Set a flag so that this address can be re-used immediately after the connection\n\t\t// closes.  (TCP normally imposes a delay before an address can be re-used.)\n\t\tvar on: Int32 = 1\n\t\tif setsockopt(self.socketfd, SOL_SOCKET, SO_REUSEADDR, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())\n\t\t}\n\n\t\t// Create the signature...\n\t\tlet sig = try Signature(socketType: .stream, proto: .unix, path: path)\n\t\tguard let signature = sig else {\n\n\t\t\tthrow Error(code:Socket.SOCKET_ERR_BAD_SIGNATURE_PARAMETERS, reason: \"Socket contains invalid signature parameters\")\n\t\t}\n\n\t\t// Ensure the path doesn't exist...\n\t\t#if os(Linux)\n\t\t\t_ = Glibc.unlink(path)\n\t\t#else\n\t\t\t_ = Darwin.unlink(path)\n\t\t#endif\n\n\t\t// Try to bind the socket to the address...\n\t\t// Now, do the connection using the supplied address from the signature...\n\t\tlet (addrPtr, addrLen) = try signature.unixAddress()\n\t\tdefer {\n\t\t\t#if swift(>=4.1)\n\t\t\t\taddrPtr.deallocate()\n\t\t\t#else\n\t\t\t\taddrPtr.deallocate(capacity: addrLen)\n\t\t\t#endif\n\t\t}\n\n\t\tlet rc = addrPtr.withMemoryRebound(to: sockaddr.self, capacity: 1) {\n\t\t\t\n\t\t\t(p: UnsafeMutablePointer<sockaddr>) -> Int32 in\n\n\t\t\t#if os(Linux)\n\t\t\t\treturn Glibc.bind(self.socketfd, p, socklen_t(addrLen))\n\t\t\t#else\n\t\t\t\treturn Darwin.bind(self.socketfd, p, socklen_t(addrLen))\n\t\t\t#endif\n\t\t}\n\n\t\tif rc < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_LISTEN_FAILED, reason: self.lastError())\n\t\t}\n\n\t\t// Now listen for connections...\n\t\t#if os(Linux)\n\t\t\tif Glibc.listen(self.socketfd, Int32(maxBacklogSize)) < 0 {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_LISTEN_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t#else\n\t\t\tif Darwin.listen(self.socketfd, Int32(maxBacklogSize)) < 0 {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_LISTEN_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t#endif\n\n\t\tself.isListening = true\n\t\tself.signature?.path = path\n\t\tself.signature?.isBound = true\n\t\tself.signature?.isSecure = false\n\t\tself.signature?.address = signature.address\n\t}\n\n\t// MARK: --- UDP\n\n\t///\n\t/// Listen for a message on a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- buffer: \t\t\tThe buffer to return the data in.\n\t/// \t- bufSize: \t\t\tThe size of the buffer.\n\t///\t\t- port:\t\t\t\tPort to listen on.\n\t/// \t- maxBacklogSize: \tThe maximum size of the queue containing pending connections. Default is *Socket.SOCKET_DEFAULT_MAX_BACKLOG*.\n\t///\n\t///\t- Returns:\t\t\t\tTuple containing the number of bytes read and the `Address` of the client who sent the data.\n\t///\n\tpublic func listen(forMessage buffer: UnsafeMutablePointer<CChar>, bufSize: Int, on port: Int, maxBacklogSize: Int = Socket.SOCKET_DEFAULT_MAX_BACKLOG) throws -> (bytesRead: Int, address: Address?) {\n\n\t\t// Make sure the buffer is valid...\n\t\tif bufSize == 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INVALID_BUFFER, reason: \"Socket has an invalid buffer, the size is zero\")\n\t\t}\n\n\t\t// The socket must've been created...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// The socket must've been created for UDP...\n\t\tguard let sig = self.signature,\n\t\t\tsig.socketType == .datagram else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"This is not a UDP socket.\")\n\t\t}\n\n\t\t// Set up the socket for listening for a message unless we're already set up...\n\t\tif !sig.isBound {\n\t\t\ttry self.listen(on: port, maxBacklogSize: maxBacklogSize)\n\t\t}\n\n\t\t// If we're not bound, something went wrong...\n\t\tguard self.signature?.isBound == true else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_LISTEN_FAILED, reason: \"\")\n\t\t}\n\n\t\tself.isListening = true\n\n\t\treturn try self.readDatagram(into: buffer, bufSize: bufSize)\n\t}\n\n\t///\n\t/// Listen for a message on a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- data:\t\t\t\tData buffer to receive the data read.\n\t///\t\t- port:\t\t\t\tPort to listen on.\n\t/// \t- maxBacklogSize: \tThe maximum size of the queue containing pending connections. Default is *Socket.SOCKET_DEFAULT_MAX_BACKLOG*.\n\t///\n\t///\t- Returns:\t\t\t\tTuple containing the number of bytes read and the `Address` of the client who sent the data.\n\t///\n\tpublic func listen(forMessage data: NSMutableData, on port: Int, maxBacklogSize: Int = Socket.SOCKET_DEFAULT_MAX_BACKLOG) throws -> (bytesRead: Int, address: Address?) {\n\n\t\t// The socket must've been created...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// The socket must've been created for UDP...\n\t\tguard let sig = self.signature,\n\t\t\tsig.socketType == .datagram && sig.proto == .udp else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"This is not a UDP socket.\")\n\t\t}\n\n\t\t// Set up the socket for listening for a message unless we're already set up...\n\t\tif !sig.isBound {\n\t\t\ttry self.listen(on: port, maxBacklogSize: maxBacklogSize)\n\t\t}\n\n\t\t// If we're not bound, something went wrong...\n\t\tguard self.signature?.isBound == true else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_LISTEN_FAILED, reason: \"\")\n\t\t}\n\n\t\tself.isListening = true\n\n\t\treturn try self.readDatagram(into: data)\n\t}\n\n\t///\n\t/// Listen for a message on a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- data:\t\t\t\tData buffer to receive the data read.\n\t///\t\t- port:\t\t\t\tPort to listen on.\n\t/// \t- maxBacklogSize: \tThe maximum size of the queue containing pending connections. Default is *Socket.SOCKET_DEFAULT_MAX_BACKLOG*.\n\t///\n\t///\t- Returns:\t\t\t\tTuple containing the number of bytes read and the `Address` of the client who sent the data.\n\t///\n\tpublic func listen(forMessage data: inout Data, on port: Int, maxBacklogSize: Int = Socket.SOCKET_DEFAULT_MAX_BACKLOG) throws -> (bytesRead: Int, address: Address?) {\n\n\t\t// The socket must've been created...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// The socket must've been created for UDP...\n\t\tguard let sig = self.signature,\n\t\t\tsig.socketType == .datagram else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"This is not a UDP socket.\")\n\t\t}\n\n\t\t// Set up the socket for listening for a message unless we're already set up...\n\t\tif !sig.isBound {\n\t\t\ttry self.listen(on: port, maxBacklogSize: maxBacklogSize)\n\t\t}\n\n\t\t// If we're not bound, something went wrong...\n\t\tguard self.signature?.isBound == true else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_LISTEN_FAILED, reason: \"\")\n\t\t}\n\n\t\tself.isListening = true\n\n\t\treturn try self.readDatagram(into: &data)\n\t}\n\n\t// MARK: -- Read\n\n\t// MARK: --- TCP/UNIX\n\n\t///\n\t/// Read data from the socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- buffer: The buffer to return the data in.\n\t/// \t- bufSize: The size of the buffer.\n\t///\t\t- truncate: Whether the data should be truncated if there is more available data than could fit in `buffer`.\n\t///\t\t\t**Note:** If called with `truncate = true` unretrieved data will be returned on next `read` call.\n\t///\n\t/// - Throws: `Socket.SOCKET_ERR_RECV_BUFFER_TOO_SMALL` if the buffer provided is too small and `truncate = false`.\n\t///\t\tCall again with proper buffer size (see `Error.bufferSizeNeeded`) or\n\t///\t\tuse `readData(data: NSMutableData)`.\n\t///\n\t/// - Returns: The number of bytes returned in the buffer.\n\t///\n\tpublic func read(into buffer: UnsafeMutablePointer<CChar>, bufSize: Int, truncate: Bool = false) throws -> Int {\n\n\t\t// Make sure the buffer is valid...\n\t\tif bufSize == 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INVALID_BUFFER, reason: \"Socket has an invalid buffer, the size is zero\")\n\t\t}\n\n\t\t// The socket must've been created and must be connected...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\tif !self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_NOT_CONNECTED, reason: \"Socket is not connected\")\n\t\t}\n\n\t\t// See if we have cached data to send back...\n\t\tif self.readStorage.length > 0 {\n\n\t\t\tif bufSize < self.readStorage.length {\n\n\t\t\t\tif truncate {\n\n\t\t\t\t\tmemcpy(buffer, self.readStorage.bytes, bufSize)\n\n\t\t\t\t\t#if os(Linux)\n\t\t\t\t\t\t// Workaround for apparent bug in NSMutableData\n\t\t\t\t\t\tself.readStorage = NSMutableData(bytes: self.readStorage.bytes.advanced(by: bufSize), length:self.readStorage.length - bufSize)\n\t\t\t\t\t#else\n\t\t\t\t\t\tself.readStorage.replaceBytes(in: NSRange(location:0, length:bufSize), withBytes: nil, length: 0)\n\t\t\t\t\t#endif\n\t\t\t\t\treturn bufSize\n\n\t\t\t\t} else {\n\n\t\t\t\t\tthrow Error(bufferSize: self.readStorage.length)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet returnCount = self.readStorage.length\n\n\t\t\t// - We've got data we've already read, copy to the caller's buffer...\n\t\t\tmemcpy(buffer, self.readStorage.bytes, self.readStorage.length)\n\n\t\t\t// - Reset the storage buffer...\n\t\t\tself.readStorage.length = 0\n\n\t\t\treturn returnCount\n\t\t}\n\n\t\t// Read all available bytes...\n\t\tlet count = try self.readDataIntoStorage()\n\n\t\t// Check for disconnect...\n\t\tif count == 0 {\n\n\t\t\treturn count\n\t\t}\n\n\t\t// Did we get data?\n\t\tvar returnCount: Int = 0\n\t\tif self.readStorage.length > 0 {\n\n\t\t\t// Is the caller's buffer big enough?\n\t\t\tif bufSize < self.readStorage.length {\n\n\t\t\t\t// It isn't should we just use the available space?\n\t\t\t\tif truncate {\n\n\t\t\t\t\t// Yep, copy what storage we can and remove the bytes from the internal buffer.\n\t\t\t\t\tmemcpy(buffer, self.readStorage.bytes, bufSize)\n\n\t\t\t\t\t#if os(Linux)\n\t\t\t\t\t\t// Workaround for apparent bug in NSMutableData\n\t\t\t\t\t\tself.readStorage = NSMutableData(bytes: self.readStorage.bytes.advanced(by: bufSize), length:self.readStorage.length - bufSize)\n\t\t\t\t\t#else\n\t\t\t\t\t\tself.readStorage.replaceBytes(in: NSRange(location:0, length:bufSize), withBytes: nil, length: 0)\n\t\t\t\t\t#endif\n\n\t\t\t\t\treturn bufSize\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Nope, throw an exception telling the caller how big the buffer must be...\n\t\t\t\t\tthrow Error(bufferSize: self.readStorage.length)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// - We've read data, copy to the callers buffer...\n\t\t\tmemcpy(buffer, self.readStorage.bytes, self.readStorage.length)\n\n\t\t\treturnCount = self.readStorage.length\n\n\t\t\t// - Reset the storage buffer...\n\t\t\tself.readStorage.length = 0\n\t\t}\n\n\t\treturn returnCount\n\t}\n\n\t///\n\t/// Read a string from the socket\n\t///\n\t/// - Returns: String containing the data read from the socket.\n\t///\n\tpublic func readString() throws -> String? {\n\n\t\tguard let data = NSMutableData(capacity: 2000) else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INTERNAL, reason: \"Unable to create temporary NSMutableData...\")\n\t\t}\n\n\t\tlet rc = try self.read(into: data)\n\n\t\tguard let str = NSString(bytes: data.bytes, length: data.length, encoding: String.Encoding.utf8.rawValue),\n\t\t\trc > 0 else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_INTERNAL, reason: \"Unable to convert data to NSString.\")\n\t\t}\n\n\t\treturn String(describing: str)\n\t}\n\n\n\t///\n\t/// Read data from the socket.\n\t///\n\t/// - Parameter data: The buffer to return the data in.\n\t///\n\t/// - Returns: The number of bytes returned in the buffer.\n\t///\n\tpublic func read(into data: NSMutableData) throws -> Int {\n\n\t\t// The socket must've been created and must be connected...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\tif !self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_NOT_CONNECTED, reason: \"Socket is not connected\")\n\t\t}\n\n\t\t// Read all available bytes...\n\t\tlet count = try self.readDataIntoStorage()\n\n\t\t// Did we get data?\n\t\tvar returnCount: Int = 0\n\t\tif count > 0 {\n\n\t\t\tdata.append(self.readStorage.bytes, length: self.readStorage.length)\n\n\t\t\treturnCount = self.readStorage.length\n\n\t\t\t// - Reset the storage buffer...\n\t\t\tself.readStorage.length = 0\n\t\t}\n\n\t\treturn returnCount\n\t}\n\n\t///\n\t/// Read data from the socket.\n\t///\n\t/// - Parameter data: The buffer to return the data in.\n\t///\n\t/// - Returns: The number of bytes returned in the buffer.\n\t///\n\tpublic func read(into data: inout Data) throws -> Int {\n\n\t\t// The socket must've been created and must be connected...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\tif !self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_NOT_CONNECTED, reason: \"Socket is not connected\")\n\t\t}\n\n\t\t// Read all available bytes...\n\t\tlet count = try self.readDataIntoStorage()\n\n\t\t// Did we get data?\n\t\tvar returnCount: Int = 0\n\t\tif count > 0 {\n\n\t\t\t// - Yes, move to caller's buffer...\n\t\t\tdata.append(self.readStorage.bytes.assumingMemoryBound(to: UInt8.self), count: self.readStorage.length)\n\n\t\t\treturnCount = self.readStorage.length\n\n\t\t\t// - Reset the storage buffer...\n\t\t\tself.readStorage.length = 0\n\t\t}\n\n\t\treturn returnCount\n\t}\n\n\t// MARK: --- UDP\n\n\t///\n\t/// Read data from a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- buffer: \tThe buffer to return the data in.\n\t/// \t- bufSize: \tThe size of the buffer.\n\t///\t\t- address: \tAddress to write data to.\n\t///\n\t/// - Returns: Tuple with the number of bytes returned in the buffer and the address they were received from.\n\t///\n\tpublic func readDatagram(into buffer: UnsafeMutablePointer<CChar>, bufSize: Int) throws -> (bytesRead: Int, address: Address?) {\n\n\t\t// Make sure the buffer is valid...\n\t\tif bufSize == 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INVALID_BUFFER, reason: \"Socket has an invalid buffer, size is zero\")\n\t\t}\n\n\t\t// The socket must've been created...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// The socket must've been created for UDP...\n\t\tguard let sig = self.signature,\n\t\t\tsig.socketType == .datagram else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"This is not a UDP socket.\")\n\t\t}\n\n\t\t// Read all available bytes...\n\t\tlet (count, address) = try self.readDatagramIntoStorage()\n\n\t\t// Check for disconnect...\n\t\tif count == 0 {\n\n\t\t\treturn (count, nil)\n\t\t}\n\n\t\t// Did we get data?\n\t\tvar returnCount: Int = 0\n\t\tif self.readStorage.length > 0 {\n\n\t\t\t// Is the caller's buffer big enough?\n\t\t\tif bufSize < self.readStorage.length {\n\n\t\t\t\t// No, discard the excess data...\n\t\t\t\tself.readStorage.length = bufSize\n\t\t\t}\n\n\t\t\t// - We've read data, copy to the callers buffer...\n\t\t\tmemcpy(buffer, self.readStorage.bytes, self.readStorage.length)\n\n\t\t\treturnCount = self.readStorage.length\n\n\t\t\t// - Reset the storage buffer...\n\t\t\tself.readStorage.length = 0\n\t\t}\n\n\t\treturn (returnCount, address)\n\t}\n\n\t///\n\t/// Read data from a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- data: \tThe buffer to return the data in.\n\t///\t\t- address: \tAddress to write data to.\n\t///\n\t/// - Returns: Tuple with the number of bytes returned in the buffer and the address they were received from.\n\t///\n\tpublic func readDatagram(into data: NSMutableData) throws -> (bytesRead: Int, address: Address?) {\n\n\t\t// The socket must've been created...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// The socket must've been created for UDP...\n\t\tguard let sig = self.signature,\n\t\t\tsig.socketType == .datagram else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"This is not a UDP socket.\")\n\t\t}\n\n\t\t// Read all available bytes...\n\t\tlet (count, address) = try self.readDatagramIntoStorage()\n\n\t\t// Did we get data?\n\t\tvar returnCount: Int = 0\n\t\tif count > 0 {\n\n\t\t\tdata.append(self.readStorage.bytes, length: self.readStorage.length)\n\n\t\t\treturnCount = self.readStorage.length\n\n\t\t\t// - Reset the storage buffer...\n\t\t\tself.readStorage.length = 0\n\t\t}\n\n\t\treturn (returnCount, address)\n\t}\n\n\t///\n\t/// Read data from a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- data: \tThe buffer to return the data in.\n\t///\t\t- address: \tAddress to write data to.\n\t///\n\t/// - Returns: Tuple with the number of bytes returned in the buffer and the address they were received from.\n\t///\n\tpublic func readDatagram(into data: inout Data) throws -> (bytesRead: Int, address: Address?) {\n\n\t\t// The socket must've been created...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"Socket has an invalid descriptor\")\n\t\t}\n\n\t\t// The socket must've been created for UDP...\n\t\tguard let sig = self.signature,\n\t\t\tsig.socketType == .datagram else {\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"This is not a UDP socket.\")\n\t\t}\n\n\t\t// Read all available bytes...\n\t\tlet (count, address) = try self.readDatagramIntoStorage()\n\n\t\t// Did we get data?\n\t\tvar returnCount: Int = 0\n\t\tif count > 0 {\n\n\t\t\t// - Yes, move to caller's buffer...\n\t\t\tdata.append(self.readStorage.bytes.assumingMemoryBound(to: UInt8.self), count: self.readStorage.length)\n\n\t\t\treturnCount = self.readStorage.length\n\n\t\t\t// - Reset the storage buffer...\n\t\t\tself.readStorage.length = 0\n\t\t}\n\n\t\treturn (returnCount, address)\n\t}\n\n\t// MARK: -- Write\n\n\t// MARK: --- TCP/UNIX\n\n\t///\n\t/// Write data to the socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- buffer: \tThe buffer containing the data to write.\n\t/// \t- bufSize: \tThe size of the buffer.\n\t///\n\t/// - Returns: Integer representing the number of bytes written.\n\t///\n\t@discardableResult public func write(from buffer: UnsafeRawPointer, bufSize: Int) throws -> Int {\n\n\t\t// Make sure the buffer is valid...\n\t\tif bufSize == 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INVALID_BUFFER, reason: \"The buffer is not valid, its size is zero\")\n\t\t}\n\n\t\t// The socket must've been created and must be connected...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"The socket is not valid, it must be created and connected\")\n\t\t}\n\n\t\tif !self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_NOT_CONNECTED, reason: \"The socket is not connected\")\n\t\t}\n\n\t\tvar sent = 0\n\t\tvar sendFlags: Int32 = 0\n\t\t#if os(Linux)\n\t\t\t// Ignore SIGPIPE to avoid process termination if the reader has closed the connection.\n\t\t\t// On Linux, we set the MSG_NOSIGNAL send flag. On OSX, we set SO_NOSIGPIPE during init().\n\t\t\tsendFlags = Int32(MSG_NOSIGNAL)\n\t\t#endif\n\t\twhile sent < bufSize {\n\n\t\t\tvar s = 0\n\t\t\tif self.delegate != nil {\n\n\t\t\t\trepeat {\n\n\t\t\t\t\tdo {\n\n\t\t\t\t\t\ts = try self.delegate!.send(buffer: buffer.advanced(by: sent), bufSize: Int(bufSize - sent))\n\n\t\t\t\t\t\tbreak\n\n\t\t\t\t\t} catch let error {\n\n\t\t\t\t\t\tguard let err = error as? SSLError else {\n\n\t\t\t\t\t\t\tthrow error\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tswitch err {\n\n\t\t\t\t\t\tcase .success:\n\t\t\t\t\t\t\tbreak\n\n\t\t\t\t\t\tcase .retryNeeded:\n\t\t\t\t\t\t\tdo {\n\n\t\t\t\t\t\t\t\ttry wait(forRead: false)\n\n\t\t\t\t\t\t\t} catch let waitError {\n\n\t\t\t\t\t\t\t\tthrow waitError\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow Error(with: err)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} while true\n\n\t\t\t} else {\n\t\t\t\t#if os(Linux)\n\t\t\t\t\ts = Glibc.send(self.socketfd, buffer.advanced(by: sent), Int(bufSize - sent), sendFlags)\n\t\t\t\t#else\n\t\t\t\t\ts = Darwin.send(self.socketfd, buffer.advanced(by: sent), Int(bufSize - sent), sendFlags)\n\t\t\t\t#endif\n\t\t\t}\n\t\t\tif s <= 0 {\n\n\t\t\t\tif errno == EAGAIN && !isBlocking {\n\n\t\t\t\t\t// We have written out as much as we can...\n\t\t\t\t\treturn sent\n\t\t\t\t}\n\n\t\t\t\t// - Handle a connection reset by peer (ECONNRESET) and throw a different exception...\n\t\t\t\tif errno == ECONNRESET {\n\t\t\t\t\tself.remoteConnectionClosed = true\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_CONNECTION_RESET, reason: self.lastError())\n\t\t\t\t}\n\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRITE_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t\tsent += s\n\t\t}\n\n\t\treturn sent\n\t}\n\n\t///\n\t/// Write data to the socket.\n\t///\n\t/// - Parameter data: The NSData object containing the data to write.\n\t///\n\t/// - Returns: Integer representing the number of bytes written.\n\t///\n\t@discardableResult public func write(from data: NSData) throws -> Int {\n\n\t\t// If there's no data in the NSData object, why bother? Fail silently...\n\t\tif data.length == 0 {\n\t\t\treturn 0\n\t\t}\n\n\t\treturn try write(from: data.bytes.assumingMemoryBound(to: UInt8.self), bufSize: data.length)\n\t}\n\n\t///\n\t/// Write data to the socket.\n\t///\n\t/// - Parameter data: The Data object containing the data to write.\n\t///\n\t/// - Returns: Integer representing the number of bytes written.\n\t///\n\t@discardableResult public func write(from data: Data) throws -> Int {\n\n\t\t// If there's no data in the Data object, why bother? Fail silently...\n\t\tif data.count == 0 {\n\t\t\treturn 0\n\t\t}\n#if swift(>=5.0)\n\t\treturn try data.withUnsafeBytes() { [unowned self] (buffer: UnsafeRawBufferPointer) throws -> Int in\n\t\t\treturn try self.write(from: buffer.baseAddress!, bufSize: data.count)\n\t\t}\n#else\n\t\treturn try data.withUnsafeBytes() { [unowned self] (buffer: UnsafePointer<UInt8>) throws -> Int in\n\n\t\t\treturn try self.write(from: buffer, bufSize: data.count)\n\t\t}\n#endif\n\n\t}\n\n\t///\n\t/// Write a string to the socket.\n\t///\n\t/// - Parameter string: The string to write.\n\t///\n\t/// - Returns: Integer representing the number of bytes written.\n\t///\n\t@discardableResult public func write(from string: String) throws -> Int {\n\n\t\treturn try string.utf8CString.withUnsafeBufferPointer() {\n\n\t\t\t// The count returned by nullTerminatedUTF8 includes the null terminator...\n\t\t\treturn try self.write(from: $0.baseAddress!, bufSize: $0.count-1)\n\t\t}\n\t}\n\n\t// MARK: --- UDP\n\n\t///\n\t/// Write data to a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- buffer: \tThe buffer containing the data to write.\n\t/// \t- bufSize: \tThe size of the buffer.\n\t///\t\t- address: \tAddress to write data to.\n\t///\n\t/// - Returns: Integer representing the number of bytes written.\n\t///\n\t@discardableResult public func write(from buffer: UnsafeRawPointer, bufSize: Int, to address: Address) throws -> Int {\n\n\t\t// If the remote connection has closed, disallow the operation...\n\t\tif self.remoteConnectionClosed {\n\t\t\treturn 0\n\t\t}\n\n\t\t// Make sure the buffer is valid...\n\t\tif bufSize == 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_INVALID_BUFFER, reason: \"The buffer is not valid, its size is zero\")\n\t\t}\n\n\t\t// The socket must've been created and must be connected...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"The socket is not valid, it must be created and connected\")\n\t\t}\n\n\t\t// The socket must've been created for UDP...\n\t\tguard let sig = self.signature,\n\t\t\tsig.socketType == .datagram else {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"This is not a UDP socket.\")\n\t\t}\n\n\t\treturn try address.withSockAddrPointer { addressPointer, addressLength -> Int in\n\t\t\tvar sent = 0\n\t\t\tvar sendFlags: Int32 = 0\n\t\t\t#if os(Linux)\n\t\t\t\t// Ignore SIGPIPE to avoid process termination if the reader has closed the connection.\n\t\t\t\t// On Linux, we set the MSG_NOSIGNAL send flag. On OSX, we set SO_NOSIGPIPE during init().\n\t\t\t\tsendFlags = Int32(MSG_NOSIGNAL)\n\t\t\t#endif\n\t\t\t\n\t\t\twhile sent < bufSize {\n\t\t\t\t\n\t\t\t\tvar s = 0\n\t\t\t\t#if os(Linux)\n\t\t\t\t\ts = Glibc.sendto(self.socketfd, buffer.advanced(by: sent), Int(bufSize - sent), sendFlags, addressPointer, addressLength)\n\t\t\t\t#else\n\t\t\t\t\ts = Darwin.sendto(self.socketfd, buffer.advanced(by: sent), Int(bufSize - sent), sendFlags, addressPointer, addressLength)\n\t\t\t\t#endif\n\t\t\t\t\n\t\t\t\tif s <= 0 {\n\t\t\t\t\t\n\t\t\t\t\tif errno == EAGAIN && !isBlocking {\n\t\t\t\t\t\t\n\t\t\t\t\t\t// We have written out as much as we can...\n\t\t\t\t\t\treturn sent\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// - Handle a connection reset by peer (ECONNRESET) and throw a different exception...\n\t\t\t\t\tif errno == ECONNRESET {\n\t\t\t\t\t\tself.remoteConnectionClosed = true\n\t\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_CONNECTION_RESET, reason: self.lastError())\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRITE_FAILED, reason: self.lastError())\n\t\t\t\t}\n\t\t\t\tsent += s\n\t\t\t}\n\t\t\t\n\t\t\treturn sent\n\t\t}\n\t}\n\n\t///\n\t/// Write data to a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- data: \tThe NSData object containing the data to write.\n\t///\t\t- address: \tAddress to write data to.\n\t///\n\t/// - Returns: Integer representing the number of bytes written.\n\t///\n\t@discardableResult public func write(from data: NSData, to address: Address) throws -> Int {\n\n\t\t// Send the bytes...\n\t\treturn try write(from: data.bytes.assumingMemoryBound(to: UInt8.self), bufSize: data.length)\n\t}\n\n\t///\n\t/// Write data to a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- data: \tThe Data object containing the data to write.\n\t///\t\t- address: \tAddress to write data to.\n\t///\n\t/// - Returns: Integer representing the number of bytes written.\n\t///\n\t@discardableResult public func write(from data: Data, to address: Address) throws -> Int {\n\n\t\t// Send the bytes...\n#if swift(>=5.0)\n\t\treturn try data.withUnsafeBytes() { [unowned self] (buffer: UnsafeRawBufferPointer) throws -> Int in\n\t\t\treturn try self.write(from: buffer.baseAddress!, bufSize: data.count, to: address)\n\t\t}\n#else\n\t\treturn try data.withUnsafeBytes() { [unowned self] (buffer: UnsafePointer<UInt8>) throws -> Int in\n\n\t\t\treturn try self.write(from: buffer, bufSize: data.count, to: address)\n\t\t}\n#endif\n\t}\n\n\t///\n\t/// Write a string to the UDP socket.\n\t///\n\t/// - Parameters:\n \t///\t\t- string: \tThe string to write.\n\t///\t\t- address: \tAddress to write data to.\n\t///\n\t/// - Returns: Integer representing the number of bytes written.\n\t///\n\t@discardableResult public func write(from string: String, to address: Address) throws -> Int {\n\n\t\treturn try string.utf8CString.withUnsafeBufferPointer() {\n\n\t\t\t// The count returned by nullTerminatedUTF8 includes the null terminator...\n\t\t\treturn try self.write(from: $0.baseAddress!, bufSize: $0.count-1, to: address)\n\t\t}\n\t}\n\n\t// MARK: -- Utility\n\n\t///\n\t/// Determines if this socket can be read from or written to.\n\t///\n\t/// - Parameters:\n \t///\t\t- waitForever:\tTrue to wait forever, false to check and return.  Default: false.\n\t///\t\t- timeout:\t\tTimeout (in msec) before returning.  A timeout value of 0 will return immediately.\n\t///\n\t/// - Returns: Tuple containing two boolean values, one for readable and one for writable.\n\t///\n\tpublic func isReadableOrWritable(waitForever: Bool = false, timeout: UInt = 0) throws -> (readable: Bool, writable: Bool) {\n\n\t\t// The socket must've been created and must be connected...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"The socket is not valid, it must be created and connected\")\n\t\t}\n\n\t\tif !self.isConnected {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_NOT_CONNECTED, reason: \"The socket is not connected\")\n\t\t}\n\n\t\t// Create a read and write file descriptor set for this socket...\n\t\tvar readfds = fd_set()\n\t\treadfds.zero()\n\t\treadfds.set(self.socketfd)\n\n\t\tvar writefds = fd_set()\n\t\twritefds.zero()\n\t\twritefds.set(self.socketfd)\n\n\t\t// Do the wait...\n\t\tvar count: Int32 = 0\n\t\tif waitForever {\n\n\t\t\t// Wait forever for data...\n\t\t\tcount = select(self.socketfd + Int32(1), &readfds, &writefds, nil, nil)\n\n\t\t} else {\n\n\t\t\t// Default timeout of zero (i.e. don't wait)...\n\t\t\tvar timer = timeval()\n\n\t\t\t// But honor callers desires...\n\t\t\tif timeout > 0 {\n\n\t\t\t\t// First get seconds...\n\t\t\t\tlet secs = Int(Double(timeout / 1000))\n\t\t\t\ttimer.tv_sec = secs\n\n\t\t\t\t// Now get the leftover millisecs...\n\t\t\t\tlet msecs = Int32(Double(timeout % 1000))\n\n\t\t\t\t// Note: timeval expects microseconds, convert now...\n\t\t\t\tlet uSecs = msecs * 1000\n\n\t\t\t\t// Now the leftover microseconds...\n\t\t\t\t#if os(Linux)\n\t\t\t\t\ttimer.tv_usec = Int(uSecs)\n\t\t\t\t#else\n\t\t\t\t\ttimer.tv_usec = Int32(uSecs)\n\t\t\t\t#endif\n\t\t\t}\n\n\t\t\t// See if there's data on the socket...\n\t\t\tcount = select(self.socketfd + Int32(1), &readfds, &writefds, nil, &timer)\n\t\t}\n\n\t\t// A count of less than zero indicates select failed...\n\t\tif count < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_SELECT_FAILED, reason: self.lastError())\n\t\t}\n\n\t\t// Return a tuple containing whether or not this socket is readable and/or writable...\n\t\treturn (readfds.isSet(self.socketfd), writefds.isSet(self.socketfd))\n\t}\n\n\t///\n\t/// Set blocking mode for socket.\n\t///\n\t/// - Parameter shouldBlock: `True` to block, `false` to not.\n\t///\n\tpublic func setBlocking(mode shouldBlock: Bool) throws {\n\n\t\tlet flags = fcntl(self.socketfd, F_GETFL)\n\t\tif flags < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_GET_FCNTL_FAILED, reason: self.lastError())\n\t\t}\n\n\t\tvar result: Int32 = 0\n\t\tif shouldBlock {\n\n\t\t\tresult = fcntl(self.socketfd, F_SETFL, flags & ~O_NONBLOCK)\n\n\t\t} else {\n\n\t\t\tresult = fcntl(self.socketfd, F_SETFL, flags | O_NONBLOCK)\n\t\t}\n\n\t\tif result < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_SET_FCNTL_FAILED, reason: self.lastError())\n\t\t}\n\n\t\tself.isBlocking = shouldBlock\n\t}\n\n\t///\n\t/// Set read timeout.\n\t///\n\t/// - Parameters:\n\t///\t\t- timeout:\t\tTimeout (in msec) before returning.  A timeout value of 0 will return immediately.\n\t///\n\tpublic func setReadTimeout(value: UInt = 0) throws {\n\n\t\t// Default timeout of zero (i.e. don't wait)...\n\t\tvar timer = timeval()\n\n\t\t// But honor callers desires...\n\t\tif value > 0 {\n\n\t\t\t// First get seconds...\n\t\t\tlet secs = Int(Double(value / 1000))\n\t\t\ttimer.tv_sec = secs\n\n\t\t\t// Now get the leftover millisecs...\n\t\t\tlet msecs = Int32(Double(value % 1000))\n\n\t\t\t// Note: timeval expects microseconds, convert now...\n\t\t\tlet uSecs = msecs * 1000\n\n\t\t\t// Now the leftover microseconds...\n\t\t\t#if os(Linux)\n\t\t\t\ttimer.tv_usec = Int(uSecs)\n\t\t\t#else\n\t\t\t\ttimer.tv_usec = Int32(uSecs)\n\t\t\t#endif\n\t\t}\n\n\t\tlet result = setsockopt(self.socketfd, SOL_SOCKET, SO_RCVTIMEO, &timer, socklen_t(MemoryLayout<timeval>.stride))\n\n\t\tif result < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_SET_RECV_TIMEOUT_FAILED, reason: self.lastError())\n\t\t}\n\t}\n\n\t///\n\t/// Set write timeout.\n\t///\n\t/// - Parameters:\n\t///\t\t- timeout:\t\tTimeout (in msec) before returning.  A timeout value of 0 will return immediately.\n\t///\n\tpublic func setWriteTimeout(value: UInt = 0) throws {\n\n\t\t// Default timeout of zero (i.e. don't wait)...\n\t\tvar timer = timeval()\n\n\t\t// But honor callers desires...\n\t\tif value > 0 {\n\n\t\t\t// First get seconds...\n\t\t\tlet secs = Int(Double(value / 1000))\n\t\t\ttimer.tv_sec = secs\n\n\t\t\t// Now get the leftover millisecs...\n\t\t\tlet msecs = Int32(Double(value % 1000))\n\n\t\t\t// Note: timeval expects microseconds, convert now...\n\t\t\tlet uSecs = msecs * 1000\n\n\t\t\t// Now the leftover microseconds...\n\t\t\t#if os(Linux)\n\t\t\t\ttimer.tv_usec = Int(uSecs)\n\t\t\t#else\n\t\t\t\ttimer.tv_usec = Int32(uSecs)\n\t\t\t#endif\n\t\t}\n\n\t\tlet result = setsockopt(self.socketfd, SOL_SOCKET, SO_SNDTIMEO, &timer, socklen_t(MemoryLayout<timeval>.stride))\n\n\t\tif result < 0 {\n\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_SET_WRITE_TIMEOUT_FAILED, reason: self.lastError())\n\t\t}\n\t}\n\t\n\t///\n\t/// Enable/disable broadcast on a UDP socket.\n\t///\n\t/// - Parameters:\n\t///\t\t- enable:\t\t`true` to enable broadcast, `false` otherwise.\n\t///\n\tpublic func udpBroadcast(enable: Bool) throws {\n\t\t\n\t\t// The socket must've been created and valid...\n\t\tif self.socketfd == Socket.SOCKET_INVALID_DESCRIPTOR {\n\t\t\t\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_BAD_DESCRIPTOR, reason: \"The socket is not valid, it must be created and connected\")\n\t\t}\n\t\t\n\t\t// The socket must've been created for UDP...\n\t\tguard let sig = self.signature,\n\t\t\tsig.socketType == .datagram else {\n\t\t\t\t\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"This is not a UDP socket.\")\n\t\t}\n\t\t\n\t\t// Turn on or off UDP broadcasting...\n\t\tvar on: Int32 = enable ? 1 : 0\n\t\tif setsockopt(self.socketfd, SOL_SOCKET, SO_BROADCAST, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {\n\t\t\tthrow Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())\n\t\t}\n\t}\n\n\t// MARK: Private Functions\n\n\t///\n\t/// Closes the current socket.\n\t///\n\t///\t- Parameters:\n\t///\t\t- withSSLCleanup:\t`True` to deinitialize the *SSLService* if present.\n\t///\n\tprivate func close(withSSLCleanup: Bool) {\n\n\t\tif self.socketfd != Socket.SOCKET_INVALID_DESCRIPTOR {\n\n\t\t\t// If we have a delegate, tell it to cleanup too...\n\t\t\tif withSSLCleanup {\n\t\t\t\tself.delegate?.deinitialize()\n\t\t\t}\n\n\t\t\t// Note: if the socket is listening, we need to shut it down prior to closing\n\t\t\t//\t\tor the socket will be left hanging until it times out.\n\t\t\t#if os(Linux)\n\t\t\t\tif self.isListening {\n\t\t\t\t\t_ = Glibc.shutdown(self.socketfd, Int32(SHUT_RDWR))\n\t\t\t\t\tself.isListening = false\n\t\t\t\t}\n\t\t\t\tself.isConnected = false\n\t\t\t\t_ = Glibc.close(self.socketfd)\n\t\t\t#else\n\t\t\t\tif self.isListening {\n\t\t\t\t\t_ = Darwin.shutdown(self.socketfd, Int32(SHUT_RDWR))\n\t\t\t\t\tself.isListening = false\n\t\t\t\t}\n\t\t\t\tself.isConnected = false\n\t\t\t\t_ = Darwin.close(self.socketfd)\n\t\t\t#endif\n\n\t\t\tself.socketfd = Socket.SOCKET_INVALID_DESCRIPTOR\n\t\t}\n\n\t\tif let _ = self.signature {\n\t\t\tself.signature!.hostname = Socket.NO_HOSTNAME\n\t\t\tself.signature!.port = Socket.SOCKET_INVALID_PORT\n\n\t\t\t// If we've got a path to a UNIX socket and we're listening...\n\t\t\t//\t\tDelete the file represented by the path as this listener\n\t\t\t//\t\tis no longer available.\n\t\t\tif self.signature!.path != nil && self.isListening {\n\t\t\t\t#if os(Linux)\n\t\t\t\t\t_ = Glibc.unlink(self.signature!.path!)\n\t\t\t\t#else\n\t\t\t\t\t_ = Darwin.unlink(self.signature!.path!)\n\t\t\t\t#endif\n\t\t\t}\n\t\t\tself.signature!.path = nil\n\t\t\tself.signature!.isSecure = false\n\t\t}\n\t}\n\n\t///\n\t/// Private function that reads all available data on an open socket into storage.\n\t///\n\t/// - Returns: number of bytes read.\n\t///\n\tprivate func readDataIntoStorage() throws -> Int {\n\n\t\t// Initialize the buffer...\n\t\t#if swift(>=4.1)\n\t\t\tself.readBuffer.initialize(to: 0x0)\n\t\t#else\n\t\t\tself.readBuffer.initialize(to: 0x0, count: readBufferSize)\n\t\t#endif\n\n\t\tvar recvFlags: Int32 = 0\n\t\tif self.readStorage.length > 0 {\n\t\t\trecvFlags |= Int32(MSG_DONTWAIT)\n\t\t}\n\n\t\t// Read all the available data...\n\t\tvar count: Int = 0\n\t\trepeat {\n\n\t\t\tif self.delegate == nil {\n\n\t\t\t\t#if os(Linux)\n\t\t\t\t\tcount = Glibc.recv(self.socketfd, self.readBuffer, self.readBufferSize, recvFlags)\n\t\t\t\t#else\n\t\t\t\t\tcount = Darwin.recv(self.socketfd, self.readBuffer, self.readBufferSize, recvFlags)\n\t\t\t\t#endif\n\n\t\t\t} else {\n\n\t\t\t\trepeat {\n\n\t\t\t\t\tdo {\n\n\t\t\t\t\t\tcount = try self.delegate!.recv(buffer: self.readBuffer, bufSize: self.readBufferSize)\n\n\t\t\t\t\t\tbreak\n\n\t\t\t\t\t} catch let error {\n\n\t\t\t\t\t\tguard let err = error as? SSLError else {\n\n\t\t\t\t\t\t\tthrow error\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tswitch err {\n\n\t\t\t\t\t\tcase .success:\n\t\t\t\t\t\t\tbreak\n\n\t\t\t\t\t\tcase .retryNeeded:\n\t\t\t\t\t\t\tdo {\n\n\t\t\t\t\t\t\t\ttry wait(forRead: true)\n\n\t\t\t\t\t\t\t} catch let waitError {\n\n\t\t\t\t\t\t\t\tthrow waitError\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tthrow Error(with: err)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t} while true\n\n\t\t\t}\n\t\t\t// Check for error...\n\t\t\tif count < 0 {\n\n\t\t\t\tswitch errno {\n\n\t\t\t\t// - Could be an error, but if errno is EAGAIN or EWOULDBLOCK (if a non-blocking socket),\n\t\t\t\t//\tit means there was NO data to read...\n\t\t\t\tcase EWOULDBLOCK, EAGAIN:\n\t\t\t\t\treturn self.readStorage.length\n\n\t\t\t\tcase ECONNRESET:\n\t\t\t\t\t// - Handle a connection reset by peer (ECONNRESET) and throw a different exception...\n\t\t\t\t\tself.remoteConnectionClosed = true\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_CONNECTION_RESET, reason: self.lastError())\n\n\t\t\t\tdefault:\n\t\t\t\t\t// - Something went wrong...\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_RECV_FAILED, reason: self.lastError())\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif count == 0 {\n\n\t\t\t\tself.remoteConnectionClosed = true\n\t\t\t\treturn 0\n\t\t\t}\n\n\t\t\t// Save the data in the buffer...\n\t\t\tself.readStorage.append(self.readBuffer, length: count)\n\n\t\t\t// Didn't fill the buffer so we've got everything available...\n\t\t\tif count < self.readBufferSize {\n\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t} while count > 0\n\n\t\treturn self.readStorage.length\n\t}\n\n\t///\n\t/// Private function that reads all available data on an open socket into storage.\n\t///\n\t/// - Returns: number of bytes read.\n\t///\n\tprivate func readDatagramIntoStorage() throws -> (bytesRead: Int, fromAddress: Address?) {\n\n\t\t// Initialize the buffer...\n\t\t#if swift(>=4.1)\n\t\t\tself.readBuffer.initialize(to: 0x0)\n\t\t#else\n\t\t\tself.readBuffer.initialize(to: 0x0, count: readBufferSize)\n\t\t#endif\n\t\tvar recvFlags: Int32 = 0\n\t\tif self.readStorage.length > 0 {\n\t\t\trecvFlags |= Int32(MSG_DONTWAIT)\n\t\t}\n\t\t\n\t\tdo {\n\t\t\tguard let address = try Address(addressProvider: { (addresssPointer, addressLengthPointer) in\n\t\t\t\t\n\t\t\t\t// Read all the available data...\n\t\t\t\t#if os(Linux)\n\t\t\t\t\tlet count = Glibc.recvfrom(self.socketfd, self.readBuffer, self.readBufferSize, recvFlags, addresssPointer, addressLengthPointer)\n\t\t\t\t#else\n\t\t\t\t\tlet count = Darwin.recvfrom(self.socketfd, self.readBuffer, self.readBufferSize, recvFlags, addresssPointer, addressLengthPointer)\n\t\t\t\t#endif\n\t\t\t\t\n\t\t\t\t// Check for error...\n\t\t\t\tif count < 0 {\n\t\t\t\t\t\n\t\t\t\t\t// - Could be an error, but if errno is EAGAIN or EWOULDBLOCK (if a non-blocking socket),\n\t\t\t\t\t//\t\tit means there was NO data to read...\n\t\t\t\t\tif errno == EAGAIN || errno == EWOULDBLOCK {\n\n\t\t\t\t\t\tthrow OperationInterrupted.readDatagram(length: self.readStorage.length)\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// - Handle a connection reset by peer (ECONNRESET) and throw a different exception...\n\t\t\t\t\tif errno == ECONNRESET {\n\t\t\t\t\t\tself.remoteConnectionClosed = true\n\t\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_CONNECTION_RESET, reason: self.lastError())\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// - Something went wrong...\n\t\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_RECV_FAILED, reason: self.lastError())\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif count == 0 {\n\t\t\t\t\tself.remoteConnectionClosed = true\n\t\t\t\t\tthrow OperationInterrupted.readDatagram(length: 0)\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Save the data in the buffer...\n\t\t\t\tself.readStorage.append(self.readBuffer, length: count)\n\t\t\t}) else {\n\t\t\t\t\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_WRONG_PROTOCOL, reason: \"Unable to determine receiving socket protocol family.\")\n\t\t\t}\n\t\t\t\n\t\t\treturn (self.readStorage.length, address)\n\t\t\t\n\t\t} catch OperationInterrupted.readDatagram(let length) {\n\t\t\t\n\t\t\treturn (length, nil)\n\t\t}\n\t}\n\n\t///\n\t/// Private function to wait for this instance to be either readable or writable.\n\t///\n\t///\t- Parameter forRead:\t`True` to wait for socket to be readable, `false` waits for it to be writable.\n\t///\n\tprivate func wait(forRead: Bool) throws {\n\n\t\trepeat {\n\n\t\t\tlet result = try self.isReadableOrWritable(waitForever: true)\n\n\t\t\tif forRead {\n\n\t\t\t\tif result.readable {\n\t\t\t\t\treturn\n\t\t\t\t} else {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif result.writable {\n\t\t\t\t\treturn\n\t\t\t\t} else {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t} while true\n\t}\n\n\t///\n\t/// Private function to return the last error based on the value of errno.\n\t///\n\t/// - Returns: String containing relevant text about the error.\n\t///\n\tprivate func lastError() -> String {\n\n\t\treturn String(validatingUTF8: strerror(errno)) ?? \"Error: \\(errno)\"\n\t}\n\t\n\t///\n\t/// Private function to set **NOSIGPIPE** on a socket. **No-op on Linux.**\n\t///\n\t/// - Parameter fd: The socket file descriptor upon which to act.\n\t///\n\tprivate func ignoreSIGPIPE(on fd: Int32) throws {\n\t\t\n\t\t#if !os(Linux)\n\t\t\n\t\t\t// Set the new socket to ignore SIGPIPE to avoid dying on interrupted connections...\n\t\t\t// Note: Linux does not support the SO_NOSIGPIPE option. Instead, we use the\n\t\t\t// MSG_NOSIGNAL flags passed to send.  See the write() functions below.\n\t\t\tvar on: Int32 = 1\n\t\t\tif setsockopt(self.socketfd, SOL_SOCKET, SO_NOSIGPIPE, &on, socklen_t(MemoryLayout<Int32>.size)) < 0 {\n\t\t\t\tthrow Error(code: Socket.SOCKET_ERR_SETSOCKOPT_FAILED, reason: self.lastError())\n\t\t\t}\n\t\t\n\t\t#endif\n\t}\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/BlueSocket/Sources/SocketProtocols.swift",
    "content": "//\n//  SocketProtocols.swift\n//  BlueSocket\n//\n//  Created by Bill Abt on 1/7/16.\n//  Copyright © 2016 IBM. All rights reserved.\n//\n// \tLicensed under the Apache License, Version 2.0 (the \"License\");\n// \tyou may not use this file except in compliance with the License.\n// \tYou may obtain a copy of the License at\n//\n// \thttp://www.apache.org/licenses/LICENSE-2.0\n//\n// \tUnless required by applicable law or agreed to in writing, software\n// \tdistributed under the License is distributed on an \"AS IS\" BASIS,\n// \tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// \tSee the License for the specific language governing permissions and\n// \tlimitations under the License.\n//\n\nimport Foundation\n\n// MARK: Reader\n\n///\n/// Socket reader protocol\n///\npublic protocol SocketReader {\n\t\n\t///\n\t/// Reads a string.\n\t///\n\t/// - Returns: Optional **String**\n\t///\n\tfunc readString() throws -> String?\n\t\n\t///\n\t/// Reads all available data into an Data object.\n\t///\n\t/// - Parameter data: **Data** object to contain read data.\n\t///\n\t/// - Returns: Integer representing the number of bytes read.\n\t///\n\tfunc read(into data: inout Data) throws -> Int\n\t\n\t///\n\t/// Reads all available data into an **NSMutableData** object.\n\t///\n\t/// - Parameter data: **NSMutableData** object to contain read data.\n\t///\n\t/// - Returns: Integer representing the number of bytes read.\n\t///\n\tfunc read(into data: NSMutableData) throws -> Int\n}\n\n// MARK: Writer\n\n///\n/// Socket writer protocol\n///\npublic protocol SocketWriter {\n\t\n\t///\n\t/// Writes data from **Data** object.\n\t///\n\t/// - Parameter data: **Data** object containing the data to be written.\n\t///\n\t@discardableResult func write(from data: Data) throws -> Int\n\t\n\t///\n\t/// Writes data from **NSData** object.\n\t///\n\t/// - Parameter data: **NSData** object containing the data to be written.\n\t///\n\t@discardableResult func write(from data: NSData) throws -> Int\n\t\n\t///\n\t/// Writes a string\n\t///\n\t/// - Parameter string: **String** data to be written.\n\t///\n\t@discardableResult func write(from string: String) throws -> Int\n}\n\n// MARK: SSLServiceDelegate\n\n///\n/// SSL Service Delegate Protocol\n///\npublic protocol SSLServiceDelegate {\n\t\n\t///\n\t/// Initialize SSL Service\n\t///\n\t/// - Parameter asServer:\t`True` for initializing a server, otherwise a client.\n\t///\n\tfunc initialize(asServer: Bool) throws\n\t\n\t///\n\t/// Deinitialize SSL Service\n\t///\n\tfunc deinitialize()\n\t\n\t///\n\t/// Processing on acceptance from a listening socket\n\t///\n\t/// - Parameter socket:\tThe connected Socket instance.\n\t///\n\tfunc onAccept(socket: Socket) throws\n\t\n\t///\n\t/// Processing on connection to a listening socket\n\t///\n\t/// - Parameter socket:\tThe connected Socket instance.\n\t///\n\tfunc onConnect(socket: Socket) throws\n\t\n\t///\n\t/// Low level writer\n\t///\n\t/// - Parameters:\n\t///\t\t- buffer:\t\tBuffer pointer.\n\t///\t\t- bufSize:\t\tSize of the buffer.\n\t///\n\t///\t- Returns the number of bytes written. Zero indicates SSL shutdown, less than zero indicates error.\n\t///\n\tfunc send(buffer: UnsafeRawPointer, bufSize: Int) throws -> Int\n\t\n\t///\n\t/// Low level reader\n\t///\n\t/// - Parameters:\n\t///\t\t- buffer:\t\tBuffer pointer.\n\t///\t\t- bufSize:\t\tSize of the buffer.\n\t///\n\t///\t- Returns the number of bytes read. Zero indicates SSL shutdown, less than zero indicates error.\n\t///\n\tfunc recv(buffer: UnsafeMutableRawPointer, bufSize: Int) throws -> Int\n\t\n\t#if os(Linux)\n\n\t\t// MARK: ALPN\n\t\t\n\t\t///\n\t\t/// Add a protocol to the list of supported ALPN protocol names. E.g. 'http/1.1' and 'h2'.\n\t\t///\n\t\t/// - Parameters:\n\t\t///\t\t- proto:\t\tThe protocol name to be added (e.g. 'h2').\n\t\t///\n\t\tfunc addSupportedAlpnProtocol(proto: String)\n\t\t\n\t\t///\n\t\t/// The negotiated ALPN protocol that has been agreed upon during the handshaking phase.\n\t\t/// Will be `nil` if ALPN hasn't been used or requestsed protocol is not available.\n\t\t///\n\t\tvar negotiatedAlpnProtocol: String? { get }\n\t\t\n\t#endif\n\t\n}\n\n// MARK: SSLError\n\n///\n/// SSL Service Error\n///\npublic enum SSLError: Swift.Error, CustomStringConvertible {\n\t\n\t/// Success\n\tcase success\n\t\n\t/// Retry needed\n\tcase retryNeeded\n\t\n\t/// Failure with error code and reason\n\tcase fail(Int, String)\n\t\n\t/// The error code itself\n\tpublic var errCode: Int {\n\t\t\n\t\tswitch self {\n\t\t\t\n\t\tcase .success:\n\t\t\treturn 0\n\t\t\t\n\t\tcase .retryNeeded:\n\t\t\treturn -1\n\t\t\t\n\t\tcase .fail(let (errCode, _)):\n\t\t\treturn Int(errCode)\n\t\t}\n\t}\n\t\n\t/// Error description\n\tpublic var description: String {\n\t\t\n\t\tswitch self {\n\t\t\t\n\t\tcase .success:\n\t\t\treturn \"Success\"\n\t\t\t\n\t\tcase .retryNeeded:\n\t\t\treturn \"Retry operation\"\n\t\t\t\n\t\tcase .fail(let (_, reason)):\n\t\t\treturn reason\n\t\t}\n\t}\n}\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/BlueSocket/Sources/SocketUtils.swift",
    "content": "//\n//  SocketUtils.swift\n//  BlueSocket\n//\n//  Created by Bill Abt on 11/19/15.\n//  Copyright © 2016 IBM. All rights reserved.\n//\n// \tLicensed under the Apache License, Version 2.0 (the \"License\");\n// \tyou may not use this file except in compliance with the License.\n// \tYou may obtain a copy of the License at\n//\n// \thttp://www.apache.org/licenses/LICENSE-2.0\n//\n// \tUnless required by applicable law or agreed to in writing, software\n// \tdistributed under the License is distributed on an \"AS IS\" BASIS,\n// \tWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// \tSee the License for the specific language governing permissions and\n// \tlimitations under the License.\n//\n\n#if os(macOS) || os(iOS) || os(tvOS)\nimport Darwin\n#elseif os(Linux)\nimport Glibc\n#endif\n\nimport Foundation\n\n//\n// Great help with this from\n// https://blog.obdev.at/representing-socket-addresses-in-swift-using-enums/\n//\nextension Socket.Address {\n\t\n\t///\n\t/// Call a low level socket function using the specified socket address pointer.\n\t///\n\t/// - Parameters:\n\t///\t\t- body:\t\tThe closure containing the call to the low level function.\n\t///\n\t///\t- Returns:\t\tThe result of executing the closure.\n\t///\n\tfunc withSockAddrPointer<Result>(body: (UnsafePointer<sockaddr>, socklen_t) throws -> Result) rethrows -> Result {\n\t\t\n\t\t///\n\t\t/// Internal function to call do the cast and call to the closure.\n\t\t///\n\t\t/// - Parameter:\tClosure body.\n\t\t///\n\t\t///\t- Returns:\t\tResult of executing the closure.\n\t\t///\n\t\tfunc castAndCall<T>(_ address: T, _ body: (UnsafePointer<sockaddr>, socklen_t) throws -> Result) rethrows -> Result {\n\t\t\tvar localAddress = address // We need a `var` here for the `&`.\n\t\t\treturn try withUnsafePointer(to: &localAddress) {\n\t\t\t\treturn try $0.withMemoryRebound(to: sockaddr.self, capacity: 1, {\n\t\t\t\t\treturn try body($0, socklen_t(MemoryLayout<T>.size))\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\t\n\t\tswitch self {\n\t\t\t\n\t\tcase .ipv4(let address):\n\t\t\treturn try castAndCall(address, body)\n\t\t\t\n\t\tcase .ipv6(let address):\n\t\t\treturn try castAndCall(address, body)\n\t\t\t\n\t\tcase .unix(let address):\n\t\t\treturn try castAndCall(address, body)\n\t\t\t\n\t\t}\n\t}\n}\n\nextension Socket.Address {\n\t\n\t///\n\t/// Creates a Socket.Address\n\t///\n\t/// - Parameters:\n\t///\t\t- addressProvider:    Tuple containing pointers to the sockaddr and its length.\n\t///\n\t///\t- Returns:                Newly initialized Socket.Address.\n\t///\n\tinit?(addressProvider: (UnsafeMutablePointer<sockaddr>, UnsafeMutablePointer<socklen_t>) throws -> Void) rethrows {\n\t\t\n\t\tvar addressStorage = sockaddr_storage()\n\t\tvar addressStorageLength = socklen_t(MemoryLayout.size(ofValue: addressStorage))\n\t\ttry withUnsafeMutablePointer(to: &addressStorage) {\n\t\t\ttry $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { addressPointer in\n\t\t\t\ttry withUnsafeMutablePointer(to: &addressStorageLength) { addressLengthPointer in\n\t\t\t\t\ttry addressProvider(addressPointer, addressLengthPointer)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tswitch Int32(addressStorage.ss_family) {\n\t\tcase AF_INET:\n\t\t\tself = withUnsafePointer(to: &addressStorage) {\n\t\t\t\treturn $0.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {\n\t\t\t\t\treturn Socket.Address.ipv4($0.pointee)\n\t\t\t\t}\n\t\t\t}\n\t\tcase AF_INET6:\n\t\t\tself = withUnsafePointer(to: &addressStorage) {\n\t\t\t\treturn $0.withMemoryRebound(to: sockaddr_in6.self, capacity: 1) {\n\t\t\t\t\treturn Socket.Address.ipv6($0.pointee)\n\t\t\t\t}\n\t\t\t}\n\t\tcase AF_UNIX:\n\t\t\tself = withUnsafePointer(to: &addressStorage) {\n\t\t\t\treturn $0.withMemoryRebound(to: sockaddr_un.self, capacity: 1) {\n\t\t\t\t\treturn Socket.Address.unix($0.pointee)\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\n#if os(Linux)\n\n\t/// Arm archictecture only allows for 16 fds.\n\t#if arch(arm)\n\t\tlet __fd_set_count = 16\n\t#else\n\t\tlet __fd_set_count = 32\n\t#endif\n\n\textension fd_set {\n\t\n\t\t@inline(__always)\n\t\tmutating func withCArrayAccess<T>(block: (UnsafeMutablePointer<Int32>) throws -> T) rethrows -> T {\n\t\t\treturn try withUnsafeMutablePointer(to: &__fds_bits) {\n\t\t\t\ttry block(UnsafeMutableRawPointer($0).assumingMemoryBound(to: Int32.self))\n\t\t\t}\n\t\t}\n\t}\n\n#else   // not Linux on ARM\n\n\t// __DARWIN_FD_SETSIZE is number of *bits*, so divide by number bits in each element to get element count\n\t// at present this is 1024 / 32 == 32\n\tlet __fd_set_count = Int(__DARWIN_FD_SETSIZE) / 32\n\n\textension fd_set {\n\t\n\t\t@inline(__always)\n\t\tmutating func withCArrayAccess<T>(block: (UnsafeMutablePointer<Int32>) throws -> T) rethrows -> T {\n\t\t\treturn try withUnsafeMutablePointer(to: &fds_bits) {\n\t\t\t\ttry block(UnsafeMutableRawPointer($0).assumingMemoryBound(to: Int32.self))\n\t\t\t}\n\t\t}\n\t}\n\n#endif\n\nextension fd_set {\n\t\n\t@inline(__always)\n\tprivate static func address(for fd: Int32) -> (Int, Int32) {\n\t\tvar intOffset = Int(fd) / __fd_set_count\n\t\t#if _endian(big)\n\t\tif intOffset % 2 == 0 {\n\t\t\tintOffset += 1\n\t\t} else {\n\t\t\tintOffset -= 1\n\t\t}\n\t\t#endif\n\t\tlet bitOffset = Int(fd) % __fd_set_count\n\t\tlet mask = Int32(bitPattern: UInt32(1 << bitOffset))\n\t\treturn (intOffset, mask)\n\t}\n\t\n\t///\n\t/// Zero the fd_set\n\t///\n\tpublic mutating func zero() {\n\t\t#if swift(>=4.1)\n\t\twithCArrayAccess { $0.initialize(repeating: 0, count: __fd_set_count) }\n\t\t#else\n\t\twithCArrayAccess { $0.initialize(to: 0, count: __fd_set_count) }\n\t\t#endif\n\t}\n\t\n\t///\n\t/// Set an fd in an fd_set\n\t///\n\t/// - Parameter fd:\tThe fd to add to the fd_set\n\t///\n\tpublic mutating func set(_ fd: Int32) {\n\t\tlet (index, mask) = fd_set.address(for: fd)\n\t\twithCArrayAccess { $0[index] |= mask }\n\t}\n\t\n\t///\n\t/// Clear an fd from an fd_set\n\t///\n\t/// - Parameter fd:\tThe fd to clear from the fd_set\n\t///\n\tpublic mutating func clear(_ fd: Int32) {\n\t\tlet (index, mask) = fd_set.address(for: fd)\n\t\twithCArrayAccess { $0[index] &= ~mask }\n\t}\n\t\n\t///\n\t/// Check if an fd is present in an fd_set\n\t///\n\t/// - Parameter fd:\tThe fd to check\n\t///\n\t///\t- Returns:\t`True` if present, `false` otherwise.\n\t///\n\tpublic mutating func isSet(_ fd: Int32) -> Bool {\n\t\tlet (index, mask) = fd_set.address(for: fd)\n\t\treturn withCArrayAccess { $0[index] & mask != 0 }\n\t}\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Package.swift",
    "content": "// swift-tools-version:5.0\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"Clibsass\",\n    products: [\n        .library(name: \"Clibsass\", targets: [\"Clibsass\"])\n    ],\n    dependencies: [\n    ],\n    targets: [\n        // Targets are the basic building blocks of a package. A target can define a module or a test suite.\n        // Targets can depend on other targets in this package, and on products in packages which this package depends on.\n        .target(\n            name: \"Clibsass\",\n            dependencies: [],\n            path: \"Sources\"\n        )\n    ],\n    cxxLanguageStandard: .cxx14\n)\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/README.snap",
    "content": "Forked from https://github.com/sass/libsass/releases/tag/3.6.5"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/GNUmakefile.am",
    "content": "ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} -I m4 -I script\n\nAM_COPT = -Wall -O2\nAM_COVLDFLAGS =\n\nif ENABLE_COVERAGE\n\tAM_COPT = -O0 --coverage\n\tAM_COVLDFLAGS += -lgcov\nendif\n\nAM_CPPFLAGS = -I$(top_srcdir)/include\nAM_CFLAGS   = $(AM_COPT)\nAM_CXXFLAGS = $(AM_COPT)\nAM_LDFLAGS  = $(AM_COPT) $(AM_COVLDFLAGS)\n\nAM_CXXFLAGS += -std=c++11\n\nEXTRA_DIST = \\\n\tCOPYING \\\n\tINSTALL \\\n\tLICENSE \\\n\tReadme.md\n\npkgconfigdir = $(libdir)/pkgconfig\npkgconfig_DATA = support/libsass.pc\n\nlib_LTLIBRARIES = libsass.la\n\ninclude $(top_srcdir)/Makefile.conf\n\nlibsass_la_SOURCES = ${CSOURCES} ${SOURCES}\n\nlibsass_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined -version-info 1:0:0\n\nif ENABLE_TESTS\nif ENABLE_COVERAGE\nnodist_EXTRA_libsass_la_SOURCES = non-existent-file-to-force-CXX-linking.cxx\nendif\nendif\n\ninclude_HEADERS = $(top_srcdir)/include/sass.h \\\n                  $(top_srcdir)/include/sass2scss.h\n\nsass_includedir = $(includedir)/sass\n\nsass_include_HEADERS = $(top_srcdir)/include/sass/base.h \\\n                       $(top_srcdir)/include/sass/values.h \\\n                       $(top_srcdir)/include/sass/version.h \\\n                       $(top_srcdir)/include/sass/context.h \\\n                       $(top_srcdir)/include/sass/functions.h\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/MurmurHash2.hpp",
    "content": "//-----------------------------------------------------------------------------\n// MurmurHash2 was written by Austin Appleby, and is placed in the public\n// domain. The author hereby disclaims copyright to this source code.\n//-----------------------------------------------------------------------------\n// LibSass only needs MurmurHash2, so we made this header only\n//-----------------------------------------------------------------------------\n\n#ifndef _MURMURHASH2_H_\n#define _MURMURHASH2_H_\n\n//-----------------------------------------------------------------------------\n// Platform-specific functions and macros\n\n// Microsoft Visual Studio\n\n#if defined(_MSC_VER) && (_MSC_VER < 1600)\n\ntypedef unsigned char uint8_t;\ntypedef unsigned int uint32_t;\ntypedef unsigned __int64 uint64_t;\n\n// Other compilers\n\n#else\t// defined(_MSC_VER)\n\n#include <stdint.h>\n\n#endif // !defined(_MSC_VER)\n\n//-----------------------------------------------------------------------------\n\ninline uint32_t MurmurHash2 ( const void * key, int len, uint32_t seed )\n{\n  // 'm' and 'r' are mixing constants generated offline.\n  // They're not really 'magic', they just happen to work well.\n\n  const uint32_t m = 0x5bd1e995;\n  const int r = 24;\n\n  // Initialize the hash to a 'random' value\n\n  uint32_t h = seed ^ len;\n\n  // Mix 4 bytes at a time into the hash\n\n  const unsigned char * data = (const unsigned char *)key;\n\n  while(len >= 4)\n  {\n    uint32_t k = *(uint32_t*)data;\n\n    k *= m;\n    k ^= k >> r;\n    k *= m;\n\n    h *= m;\n    h ^= k;\n\n    data += 4;\n    len -= 4;\n  }\n\n  // Handle the last few bytes of the input array\n\n  switch(len)\n  {\n  case 3:\n    h ^= data[2] << 16;\n    /* fall through */\n  case 2:\n    h ^= data[1] << 8;\n    /* fall through */\n  case 1:\n    h ^= data[0];\n    h *= m;\n  };\n\n  // Do a few final mixes of the hash to ensure the last few\n  // bytes are well-incorporated.\n\n  h ^= h >> 13;\n  h *= m;\n  h ^= h >> 15;\n\n  return h;\n} \n\n//-----------------------------------------------------------------------------\n\n#endif // _MURMURHASH2_H_\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  static Null sass_null(SourceSpan(\"null\"));\n\n  const char* sass_op_to_name(enum Sass_OP op) {\n    switch (op) {\n      case AND: return \"and\";\n      case OR: return \"or\";\n      case EQ: return \"eq\";\n      case NEQ: return \"neq\";\n      case GT: return \"gt\";\n      case GTE: return \"gte\";\n      case LT: return \"lt\";\n      case LTE: return \"lte\";\n      case ADD: return \"plus\";\n      case SUB: return \"minus\";\n      case MUL: return \"times\";\n      case DIV: return \"div\";\n      case MOD: return \"mod\";\n      // this is only used internally!\n      case NUM_OPS: return \"[OPS]\";\n      default: return \"invalid\";\n    }\n  }\n\n  const char* sass_op_separator(enum Sass_OP op) {\n    switch (op) {\n      case AND: return \"&&\";\n      case OR: return \"||\";\n      case EQ: return \"==\";\n      case NEQ: return \"!=\";\n      case GT: return \">\";\n      case GTE: return \">=\";\n      case LT: return \"<\";\n      case LTE: return \"<=\";\n      case ADD: return \"+\";\n      case SUB: return \"-\";\n      case MUL: return \"*\";\n      case DIV: return \"/\";\n      case MOD: return \"%\";\n      // this is only used internally!\n      case NUM_OPS: return \"[OPS]\";\n      default: return \"invalid\";\n    }\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  void AST_Node::update_pstate(const SourceSpan& pstate)\n  {\n    pstate_.offset += pstate.position - pstate_.position + pstate.offset;\n  }\n\n  sass::string AST_Node::to_string(Sass_Inspect_Options opt) const\n  {\n    Sass_Output_Options out(opt);\n    Emitter emitter(out);\n    Inspect i(emitter);\n    i.in_declaration = true;\n    // ToDo: inspect should be const\n    const_cast<AST_Node*>(this)->perform(&i);\n    return i.get_buffer();\n  }\n\n  sass::string AST_Node::to_css(Sass_Inspect_Options opt) const\n  {\n    opt.output_style = TO_CSS;\n    Sass_Output_Options out(opt);\n    Emitter emitter(out);\n    Inspect i(emitter);\n    i.in_declaration = true;\n    // ToDo: inspect should be const\n    const_cast<AST_Node*>(this)->perform(&i);\n    return i.get_buffer();\n  }\n\n  sass::string AST_Node::to_string() const\n  {\n    return to_string({ NESTED, 5 });\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Statement::Statement(SourceSpan pstate, Type st, size_t t)\n  : AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)\n  { }\n  Statement::Statement(const Statement* ptr)\n  : AST_Node(ptr),\n    statement_type_(ptr->statement_type_),\n    tabs_(ptr->tabs_),\n    group_end_(ptr->group_end_)\n  { }\n\n  bool Statement::bubbles()\n  {\n    return false;\n  }\n\n  bool Statement::has_content()\n  {\n    return statement_type_ == CONTENT;\n  }\n\n  bool Statement::is_invisible() const\n  {\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Block::Block(SourceSpan pstate, size_t s, bool r)\n  : Statement(pstate),\n    Vectorized<Statement_Obj>(s),\n    is_root_(r)\n  { }\n  Block::Block(const Block* ptr)\n  : Statement(ptr),\n    Vectorized<Statement_Obj>(*ptr),\n    is_root_(ptr->is_root_)\n  { }\n\n  bool Block::isInvisible() const\n  {\n    for (auto& item : elements()) {\n      if (!item->is_invisible()) return false;\n    }\n    return true;\n  }\n\n  bool Block::has_content()\n  {\n    for (size_t i = 0, L = elements().size(); i < L; ++i) {\n      if (elements()[i]->has_content()) return true;\n    }\n    return Statement::has_content();\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  ParentStatement::ParentStatement(SourceSpan pstate, Block_Obj b)\n  : Statement(pstate), block_(b)\n  { }\n  ParentStatement::ParentStatement(const ParentStatement* ptr)\n  : Statement(ptr), block_(ptr->block_)\n  { }\n\n  bool ParentStatement::has_content()\n  {\n    return (block_ && block_->has_content()) || Statement::has_content();\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  StyleRule::StyleRule(SourceSpan pstate, SelectorListObj s, Block_Obj b)\n  : ParentStatement(pstate, b), selector_(s), schema_(), is_root_(false)\n  { statement_type(RULESET); }\n  StyleRule::StyleRule(const StyleRule* ptr)\n  : ParentStatement(ptr),\n    selector_(ptr->selector_),\n    schema_(ptr->schema_),\n    is_root_(ptr->is_root_)\n  { statement_type(RULESET); }\n\n  bool StyleRule::is_invisible() const {\n    if (const SelectorList * sl = Cast<SelectorList>(selector())) {\n      for (size_t i = 0, L = sl->length(); i < L; i += 1)\n        if (!(*sl)[i]->isInvisible()) return false;\n    }\n    return true;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Bubble::Bubble(SourceSpan pstate, Statement_Obj n, Statement_Obj g, size_t t)\n  : Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == nullptr)\n  { }\n  Bubble::Bubble(const Bubble* ptr)\n  : Statement(ptr),\n    node_(ptr->node_),\n    group_end_(ptr->group_end_)\n  { }\n\n  bool Bubble::bubbles()\n  {\n    return true;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Trace::Trace(SourceSpan pstate, sass::string n, Block_Obj b, char type)\n  : ParentStatement(pstate, b), type_(type), name_(n)\n  { }\n  Trace::Trace(const Trace* ptr)\n  : ParentStatement(ptr),\n    type_(ptr->type_),\n    name_(ptr->name_)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  AtRule::AtRule(SourceSpan pstate, sass::string kwd, SelectorListObj sel, Block_Obj b, ExpressionObj val)\n  : ParentStatement(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed\n  { statement_type(DIRECTIVE); }\n  AtRule::AtRule(const AtRule* ptr)\n  : ParentStatement(ptr),\n    keyword_(ptr->keyword_),\n    selector_(ptr->selector_),\n    value_(ptr->value_) // set value manually if needed\n  { statement_type(DIRECTIVE); }\n\n  bool AtRule::bubbles() { return is_keyframes() || is_media(); }\n\n  bool AtRule::is_media() {\n    return keyword_.compare(\"@-webkit-media\") == 0 ||\n            keyword_.compare(\"@-moz-media\") == 0 ||\n            keyword_.compare(\"@-o-media\") == 0 ||\n            keyword_.compare(\"@media\") == 0;\n  }\n  bool AtRule::is_keyframes() {\n    return keyword_.compare(\"@-webkit-keyframes\") == 0 ||\n            keyword_.compare(\"@-moz-keyframes\") == 0 ||\n            keyword_.compare(\"@-o-keyframes\") == 0 ||\n            keyword_.compare(\"@keyframes\") == 0;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Keyframe_Rule::Keyframe_Rule(SourceSpan pstate, Block_Obj b)\n  : ParentStatement(pstate, b), name_()\n  { statement_type(KEYFRAMERULE); }\n  Keyframe_Rule::Keyframe_Rule(const Keyframe_Rule* ptr)\n  : ParentStatement(ptr), name_(ptr->name_)\n  { statement_type(KEYFRAMERULE); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Declaration::Declaration(SourceSpan pstate, String_Obj prop, ExpressionObj val, bool i, bool c, Block_Obj b)\n  : ParentStatement(pstate, b), property_(prop), value_(val), is_important_(i), is_custom_property_(c), is_indented_(false)\n  { statement_type(DECLARATION); }\n  Declaration::Declaration(const Declaration* ptr)\n  : ParentStatement(ptr),\n    property_(ptr->property_),\n    value_(ptr->value_),\n    is_important_(ptr->is_important_),\n    is_custom_property_(ptr->is_custom_property_),\n    is_indented_(ptr->is_indented_)\n  { statement_type(DECLARATION); }\n\n  bool Declaration::is_invisible() const\n  {\n    if (is_custom_property()) return false;\n    return !(value_ && !Cast<Null>(value_));\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Assignment::Assignment(SourceSpan pstate, sass::string var, ExpressionObj val, bool is_default, bool is_global)\n  : Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)\n  { statement_type(ASSIGNMENT); }\n  Assignment::Assignment(const Assignment* ptr)\n  : Statement(ptr),\n    variable_(ptr->variable_),\n    value_(ptr->value_),\n    is_default_(ptr->is_default_),\n    is_global_(ptr->is_global_)\n  { statement_type(ASSIGNMENT); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Import::Import(SourceSpan pstate)\n  : Statement(pstate),\n    urls_(sass::vector<ExpressionObj>()),\n    incs_(sass::vector<Include>()),\n    import_queries_()\n  { statement_type(IMPORT); }\n  Import::Import(const Import* ptr)\n  : Statement(ptr),\n    urls_(ptr->urls_),\n    incs_(ptr->incs_),\n    import_queries_(ptr->import_queries_)\n  { statement_type(IMPORT); }\n\n  sass::vector<Include>& Import::incs() { return incs_; }\n  sass::vector<ExpressionObj>& Import::urls() { return urls_; }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Import_Stub::Import_Stub(SourceSpan pstate, Include res)\n  : Statement(pstate), resource_(res)\n  { statement_type(IMPORT_STUB); }\n  Import_Stub::Import_Stub(const Import_Stub* ptr)\n  : Statement(ptr), resource_(ptr->resource_)\n  { statement_type(IMPORT_STUB); }\n  Include Import_Stub::resource() { return resource_; };\n  sass::string Import_Stub::imp_path() { return resource_.imp_path; };\n  sass::string Import_Stub::abs_path() { return resource_.abs_path; };\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  WarningRule::WarningRule(SourceSpan pstate, ExpressionObj msg)\n  : Statement(pstate), message_(msg)\n  { statement_type(WARNING); }\n  WarningRule::WarningRule(const WarningRule* ptr)\n  : Statement(ptr), message_(ptr->message_)\n  { statement_type(WARNING); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  ErrorRule::ErrorRule(SourceSpan pstate, ExpressionObj msg)\n  : Statement(pstate), message_(msg)\n  { statement_type(ERROR); }\n  ErrorRule::ErrorRule(const ErrorRule* ptr)\n  : Statement(ptr), message_(ptr->message_)\n  { statement_type(ERROR); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  DebugRule::DebugRule(SourceSpan pstate, ExpressionObj val)\n  : Statement(pstate), value_(val)\n  { statement_type(DEBUGSTMT); }\n  DebugRule::DebugRule(const DebugRule* ptr)\n  : Statement(ptr), value_(ptr->value_)\n  { statement_type(DEBUGSTMT); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Comment::Comment(SourceSpan pstate, String_Obj txt, bool is_important)\n  : Statement(pstate), text_(txt), is_important_(is_important)\n  { statement_type(COMMENT); }\n  Comment::Comment(const Comment* ptr)\n  : Statement(ptr),\n    text_(ptr->text_),\n    is_important_(ptr->is_important_)\n  { statement_type(COMMENT); }\n\n  bool Comment::is_invisible() const\n  {\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  If::If(SourceSpan pstate, ExpressionObj pred, Block_Obj con, Block_Obj alt)\n  : ParentStatement(pstate, con), predicate_(pred), alternative_(alt)\n  { statement_type(IF); }\n  If::If(const If* ptr)\n  : ParentStatement(ptr),\n    predicate_(ptr->predicate_),\n    alternative_(ptr->alternative_)\n  { statement_type(IF); }\n\n  bool If::has_content()\n  {\n    return ParentStatement::has_content() || (alternative_ && alternative_->has_content());\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  ForRule::ForRule(SourceSpan pstate,\n      sass::string var, ExpressionObj lo, ExpressionObj hi, Block_Obj b, bool inc)\n  : ParentStatement(pstate, b),\n    variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc)\n  { statement_type(FOR); }\n  ForRule::ForRule(const ForRule* ptr)\n  : ParentStatement(ptr),\n    variable_(ptr->variable_),\n    lower_bound_(ptr->lower_bound_),\n    upper_bound_(ptr->upper_bound_),\n    is_inclusive_(ptr->is_inclusive_)\n  { statement_type(FOR); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  EachRule::EachRule(SourceSpan pstate, sass::vector<sass::string> vars, ExpressionObj lst, Block_Obj b)\n  : ParentStatement(pstate, b), variables_(vars), list_(lst)\n  { statement_type(EACH); }\n  EachRule::EachRule(const EachRule* ptr)\n  : ParentStatement(ptr), variables_(ptr->variables_), list_(ptr->list_)\n  { statement_type(EACH); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  WhileRule::WhileRule(SourceSpan pstate, ExpressionObj pred, Block_Obj b)\n  : ParentStatement(pstate, b), predicate_(pred)\n  { statement_type(WHILE); }\n  WhileRule::WhileRule(const WhileRule* ptr)\n  : ParentStatement(ptr), predicate_(ptr->predicate_)\n  { statement_type(WHILE); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Return::Return(SourceSpan pstate, ExpressionObj val)\n  : Statement(pstate), value_(val)\n  { statement_type(RETURN); }\n  Return::Return(const Return* ptr)\n  : Statement(ptr), value_(ptr->value_)\n  { statement_type(RETURN); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n    ExtendRule::ExtendRule(SourceSpan pstate, SelectorListObj s)\n  : Statement(pstate), isOptional_(false), selector_(s), schema_()\n  { statement_type(EXTEND); }\n  ExtendRule::ExtendRule(SourceSpan pstate, Selector_Schema_Obj s)\n    : Statement(pstate), isOptional_(false), selector_(), schema_(s)\n  {\n    statement_type(EXTEND);\n  }\n  ExtendRule::ExtendRule(const ExtendRule* ptr)\n  : Statement(ptr),\n    isOptional_(ptr->isOptional_),\n    selector_(ptr->selector_),\n    schema_(ptr->schema_)\n  { statement_type(EXTEND); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Definition::Definition(const Definition* ptr)\n  : ParentStatement(ptr),\n    name_(ptr->name_),\n    parameters_(ptr->parameters_),\n    environment_(ptr->environment_),\n    type_(ptr->type_),\n    native_function_(ptr->native_function_),\n    c_function_(ptr->c_function_),\n    cookie_(ptr->cookie_),\n    is_overload_stub_(ptr->is_overload_stub_),\n    signature_(ptr->signature_)\n  { }\n\n  Definition::Definition(SourceSpan pstate,\n              sass::string n,\n              Parameters_Obj params,\n              Block_Obj b,\n              Type t)\n  : ParentStatement(pstate, b),\n    name_(n),\n    parameters_(params),\n    environment_(0),\n    type_(t),\n    native_function_(0),\n    c_function_(0),\n    cookie_(0),\n    is_overload_stub_(false),\n    signature_(0)\n  { }\n\n  Definition::Definition(SourceSpan pstate,\n              Signature sig,\n              sass::string n,\n              Parameters_Obj params,\n              Native_Function func_ptr,\n              bool overload_stub)\n  : ParentStatement(pstate, {}),\n    name_(n),\n    parameters_(params),\n    environment_(0),\n    type_(FUNCTION),\n    native_function_(func_ptr),\n    c_function_(0),\n    cookie_(0),\n    is_overload_stub_(overload_stub),\n    signature_(sig)\n  { }\n\n  Definition::Definition(SourceSpan pstate,\n              Signature sig,\n              sass::string n,\n              Parameters_Obj params,\n              Sass_Function_Entry c_func)\n  : ParentStatement(pstate, {}),\n    name_(n),\n    parameters_(params),\n    environment_(0),\n    type_(FUNCTION),\n    native_function_(0),\n    c_function_(c_func),\n    cookie_(sass_function_get_cookie(c_func)),\n    is_overload_stub_(false),\n    signature_(sig)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Mixin_Call::Mixin_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Parameters_Obj b_params, Block_Obj b)\n  : ParentStatement(pstate, b), name_(n), arguments_(args), block_parameters_(b_params)\n  { }\n  Mixin_Call::Mixin_Call(const Mixin_Call* ptr)\n  : ParentStatement(ptr),\n    name_(ptr->name_),\n    arguments_(ptr->arguments_),\n    block_parameters_(ptr->block_parameters_)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Content::Content(SourceSpan pstate, Arguments_Obj args)\n  : Statement(pstate),\n    arguments_(args)\n  { statement_type(CONTENT); }\n  Content::Content(const Content* ptr)\n  : Statement(ptr),\n    arguments_(ptr->arguments_)\n  { statement_type(CONTENT); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Expression::Expression(SourceSpan pstate, bool d, bool e, bool i, Type ct)\n  : AST_Node(pstate),\n    is_delayed_(d),\n    is_expanded_(e),\n    is_interpolant_(i),\n    concrete_type_(ct)\n  { }\n\n  Expression::Expression(const Expression* ptr)\n  : AST_Node(ptr),\n    is_delayed_(ptr->is_delayed_),\n    is_expanded_(ptr->is_expanded_),\n    is_interpolant_(ptr->is_interpolant_),\n    concrete_type_(ptr->concrete_type_)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Unary_Expression::Unary_Expression(SourceSpan pstate, Type t, ExpressionObj o)\n  : Expression(pstate), optype_(t), operand_(o), hash_(0)\n  { }\n  Unary_Expression::Unary_Expression(const Unary_Expression* ptr)\n  : Expression(ptr),\n    optype_(ptr->optype_),\n    operand_(ptr->operand_),\n    hash_(ptr->hash_)\n  { }\n  const sass::string Unary_Expression::type_name() {\n    switch (optype_) {\n      case PLUS: return \"plus\";\n      case MINUS: return \"minus\";\n      case SLASH: return \"slash\";\n      case NOT: return \"not\";\n      default: return \"invalid\";\n    }\n  }\n  bool Unary_Expression::operator==(const Expression& rhs) const\n  {\n    try\n    {\n      const Unary_Expression* m = Cast<Unary_Expression>(&rhs);\n      if (m == 0) return false;\n      return type() == m->type() &&\n              *operand() == *m->operand();\n    }\n    catch (std::bad_cast&)\n    {\n      return false;\n    }\n    catch (...) { throw; }\n  }\n  size_t Unary_Expression::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<size_t>()(optype_);\n      hash_combine(hash_, operand()->hash());\n    };\n    return hash_;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Argument::Argument(SourceSpan pstate, ExpressionObj val, sass::string n, bool rest, bool keyword)\n  : Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)\n  {\n    if (!name_.empty() && is_rest_argument_) {\n      coreError(\"variable-length argument may not be passed by name\", pstate_);\n    }\n  }\n  Argument::Argument(const Argument* ptr)\n  : Expression(ptr),\n    value_(ptr->value_),\n    name_(ptr->name_),\n    is_rest_argument_(ptr->is_rest_argument_),\n    is_keyword_argument_(ptr->is_keyword_argument_),\n    hash_(ptr->hash_)\n  {\n    if (!name_.empty() && is_rest_argument_) {\n      coreError(\"variable-length argument may not be passed by name\", pstate_);\n    }\n  }\n\n  void Argument::set_delayed(bool delayed)\n  {\n    if (value_) value_->set_delayed(delayed);\n    is_delayed(delayed);\n  }\n\n  bool Argument::operator==(const Expression& rhs) const\n  {\n    try\n    {\n      const Argument* m = Cast<Argument>(&rhs);\n      if (!(m && name() == m->name())) return false;\n      return *value() == *m->value();\n    }\n    catch (std::bad_cast&)\n    {\n      return false;\n    }\n    catch (...) { throw; }\n  }\n\n  size_t Argument::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<sass::string>()(name());\n      hash_combine(hash_, value()->hash());\n    }\n    return hash_;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Arguments::Arguments(SourceSpan pstate)\n  : Expression(pstate),\n    Vectorized<Argument_Obj>(),\n    has_named_arguments_(false),\n    has_rest_argument_(false),\n    has_keyword_argument_(false)\n  { }\n  Arguments::Arguments(const Arguments* ptr)\n  : Expression(ptr),\n    Vectorized<Argument_Obj>(*ptr),\n    has_named_arguments_(ptr->has_named_arguments_),\n    has_rest_argument_(ptr->has_rest_argument_),\n    has_keyword_argument_(ptr->has_keyword_argument_)\n  { }\n\n  void Arguments::set_delayed(bool delayed)\n  {\n    for (Argument_Obj arg : elements()) {\n      if (arg) arg->set_delayed(delayed);\n    }\n    is_delayed(delayed);\n  }\n\n  Argument_Obj Arguments::get_rest_argument()\n  {\n    if (this->has_rest_argument()) {\n      for (Argument_Obj arg : this->elements()) {\n        if (arg->is_rest_argument()) {\n          return arg;\n        }\n      }\n    }\n    return {};\n  }\n\n  Argument_Obj Arguments::get_keyword_argument()\n  {\n    if (this->has_keyword_argument()) {\n      for (Argument_Obj arg : this->elements()) {\n        if (arg->is_keyword_argument()) {\n          return arg;\n        }\n      }\n    }\n    return {};\n  }\n\n  void Arguments::adjust_after_pushing(Argument_Obj a)\n  {\n    if (!a->name().empty()) {\n      if (has_keyword_argument()) {\n        coreError(\"named arguments must precede variable-length argument\", a->pstate());\n      }\n      has_named_arguments(true);\n    }\n    else if (a->is_rest_argument()) {\n      if (has_rest_argument()) {\n        coreError(\"functions and mixins may only be called with one variable-length argument\", a->pstate());\n      }\n      if (has_keyword_argument_) {\n        coreError(\"only keyword arguments may follow variable arguments\", a->pstate());\n      }\n      has_rest_argument(true);\n    }\n    else if (a->is_keyword_argument()) {\n      if (has_keyword_argument()) {\n        coreError(\"functions and mixins may only be called with one keyword argument\", a->pstate());\n      }\n      has_keyword_argument(true);\n    }\n    else {\n      if (has_rest_argument()) {\n        coreError(\"ordinal arguments must precede variable-length arguments\", a->pstate());\n      }\n      if (has_named_arguments()) {\n        coreError(\"ordinal arguments must precede named arguments\", a->pstate());\n      }\n    }\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Media_Query::Media_Query(SourceSpan pstate, String_Obj t, size_t s, bool n, bool r)\n  : Expression(pstate), Vectorized<Media_Query_ExpressionObj>(s),\n    media_type_(t), is_negated_(n), is_restricted_(r)\n  { }\n  Media_Query::Media_Query(const Media_Query* ptr)\n  : Expression(ptr),\n    Vectorized<Media_Query_ExpressionObj>(*ptr),\n    media_type_(ptr->media_type_),\n    is_negated_(ptr->is_negated_),\n    is_restricted_(ptr->is_restricted_)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Media_Query_Expression::Media_Query_Expression(SourceSpan pstate,\n                          ExpressionObj f, ExpressionObj v, bool i)\n  : Expression(pstate), feature_(f), value_(v), is_interpolated_(i)\n  { }\n  Media_Query_Expression::Media_Query_Expression(const Media_Query_Expression* ptr)\n  : Expression(ptr),\n    feature_(ptr->feature_),\n    value_(ptr->value_),\n    is_interpolated_(ptr->is_interpolated_)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  At_Root_Query::At_Root_Query(SourceSpan pstate, ExpressionObj f, ExpressionObj v, bool i)\n  : Expression(pstate), feature_(f), value_(v)\n  { }\n  At_Root_Query::At_Root_Query(const At_Root_Query* ptr)\n  : Expression(ptr),\n    feature_(ptr->feature_),\n    value_(ptr->value_)\n  { }\n\n  bool At_Root_Query::exclude(sass::string str)\n  {\n    bool with = feature() && unquote(feature()->to_string()).compare(\"with\") == 0;\n    List* l = static_cast<List*>(value().ptr());\n    sass::string v;\n\n    if (with)\n    {\n      if (!l || l->length() == 0) return str.compare(\"rule\") != 0;\n      for (size_t i = 0, L = l->length(); i < L; ++i)\n      {\n        v = unquote((*l)[i]->to_string());\n        if (v.compare(\"all\") == 0 || v == str) return false;\n      }\n      return true;\n    }\n    else\n    {\n      if (!l || !l->length()) return str.compare(\"rule\") == 0;\n      for (size_t i = 0, L = l->length(); i < L; ++i)\n      {\n        v = unquote((*l)[i]->to_string());\n        if (v.compare(\"all\") == 0 || v == str) return true;\n      }\n      return false;\n    }\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  AtRootRule::AtRootRule(SourceSpan pstate, Block_Obj b, At_Root_Query_Obj e)\n  : ParentStatement(pstate, b), expression_(e)\n  { statement_type(ATROOT); }\n  AtRootRule::AtRootRule(const AtRootRule* ptr)\n  : ParentStatement(ptr), expression_(ptr->expression_)\n  { statement_type(ATROOT); }\n\n  bool AtRootRule::bubbles() {\n    return true;\n  }\n\n  bool AtRootRule::exclude_node(Statement_Obj s) {\n    if (expression() == nullptr)\n    {\n      return s->statement_type() == Statement::RULESET;\n    }\n\n    if (s->statement_type() == Statement::DIRECTIVE)\n    {\n      if (AtRuleObj dir = Cast<AtRule>(s))\n      {\n        sass::string keyword(dir->keyword());\n        if (keyword.length() > 0) keyword.erase(0, 1);\n        return expression()->exclude(keyword);\n      }\n    }\n    if (s->statement_type() == Statement::MEDIA)\n    {\n      return expression()->exclude(\"media\");\n    }\n    if (s->statement_type() == Statement::RULESET)\n    {\n      return expression()->exclude(\"rule\");\n    }\n    if (s->statement_type() == Statement::SUPPORTS)\n    {\n      return expression()->exclude(\"supports\");\n    }\n    if (AtRuleObj dir = Cast<AtRule>(s))\n    {\n      if (dir->is_keyframes()) return expression()->exclude(\"keyframes\");\n    }\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Parameter::Parameter(SourceSpan pstate, sass::string n, ExpressionObj def, bool rest)\n  : AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)\n  { }\n  Parameter::Parameter(const Parameter* ptr)\n  : AST_Node(ptr),\n    name_(ptr->name_),\n    default_value_(ptr->default_value_),\n    is_rest_parameter_(ptr->is_rest_parameter_)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Parameters::Parameters(SourceSpan pstate)\n  : AST_Node(pstate),\n    Vectorized<Parameter_Obj>(),\n    has_optional_parameters_(false),\n    has_rest_parameter_(false)\n  { }\n  Parameters::Parameters(const Parameters* ptr)\n  : AST_Node(ptr),\n    Vectorized<Parameter_Obj>(*ptr),\n    has_optional_parameters_(ptr->has_optional_parameters_),\n    has_rest_parameter_(ptr->has_rest_parameter_)\n  { }\n\n  void Parameters::adjust_after_pushing(Parameter_Obj p)\n  {\n    if (p->default_value()) {\n      if (has_rest_parameter()) {\n        coreError(\"optional parameters may not be combined with variable-length parameters\", p->pstate());\n      }\n      has_optional_parameters(true);\n    }\n    else if (p->is_rest_parameter()) {\n      if (has_rest_parameter()) {\n        coreError(\"functions and mixins cannot have more than one variable-length parameter\", p->pstate());\n      }\n      has_rest_parameter(true);\n    }\n    else {\n      if (has_rest_parameter()) {\n        coreError(\"required parameters must precede variable-length parameters\", p->pstate());\n      }\n      if (has_optional_parameters()) {\n        coreError(\"required parameters must precede optional parameters\", p->pstate());\n      }\n    }\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  // If you forget to add a class here you will get\n  // undefined reference to `vtable for Sass::Class'\n\n  IMPLEMENT_AST_OPERATORS(StyleRule);\n  IMPLEMENT_AST_OPERATORS(MediaRule);\n  IMPLEMENT_AST_OPERATORS(CssMediaRule);\n  IMPLEMENT_AST_OPERATORS(CssMediaQuery);\n  IMPLEMENT_AST_OPERATORS(Import);\n  IMPLEMENT_AST_OPERATORS(Import_Stub);\n  IMPLEMENT_AST_OPERATORS(AtRule);\n  IMPLEMENT_AST_OPERATORS(AtRootRule);\n  IMPLEMENT_AST_OPERATORS(WhileRule);\n  IMPLEMENT_AST_OPERATORS(EachRule);\n  IMPLEMENT_AST_OPERATORS(ForRule);\n  IMPLEMENT_AST_OPERATORS(If);\n  IMPLEMENT_AST_OPERATORS(Mixin_Call);\n  IMPLEMENT_AST_OPERATORS(ExtendRule);\n  IMPLEMENT_AST_OPERATORS(Media_Query);\n  IMPLEMENT_AST_OPERATORS(Media_Query_Expression);\n  IMPLEMENT_AST_OPERATORS(DebugRule);\n  IMPLEMENT_AST_OPERATORS(ErrorRule);\n  IMPLEMENT_AST_OPERATORS(WarningRule);\n  IMPLEMENT_AST_OPERATORS(Assignment);\n  IMPLEMENT_AST_OPERATORS(Return);\n  IMPLEMENT_AST_OPERATORS(At_Root_Query);\n  IMPLEMENT_AST_OPERATORS(Comment);\n  IMPLEMENT_AST_OPERATORS(Parameters);\n  IMPLEMENT_AST_OPERATORS(Parameter);\n  IMPLEMENT_AST_OPERATORS(Arguments);\n  IMPLEMENT_AST_OPERATORS(Argument);\n  IMPLEMENT_AST_OPERATORS(Unary_Expression);\n  IMPLEMENT_AST_OPERATORS(Block);\n  IMPLEMENT_AST_OPERATORS(Content);\n  IMPLEMENT_AST_OPERATORS(Trace);\n  IMPLEMENT_AST_OPERATORS(Keyframe_Rule);\n  IMPLEMENT_AST_OPERATORS(Bubble);\n  IMPLEMENT_AST_OPERATORS(Definition);\n  IMPLEMENT_AST_OPERATORS(Declaration);\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast.hpp",
    "content": "#ifndef SASS_AST_H\n#define SASS_AST_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <typeinfo>\n#include <unordered_map>\n\n#include \"sass/base.h\"\n#include \"ast_helpers.hpp\"\n#include \"ast_fwd_decl.hpp\"\n#include \"ast_def_macros.hpp\"\n\n#include \"file.hpp\"\n#include \"position.hpp\"\n#include \"operation.hpp\"\n#include \"environment.hpp\"\n#include \"fn_utils.hpp\"\n\nnamespace Sass {\n\n  // ToDo: where does this fit best?\n  // We don't share this with C-API?\n  class Operand {\n    public:\n      Operand(Sass_OP operand, bool ws_before = false, bool ws_after = false)\n      : operand(operand), ws_before(ws_before), ws_after(ws_after)\n      { }\n    public:\n      enum Sass_OP operand;\n      bool ws_before;\n      bool ws_after;\n  };\n\n  //////////////////////////////////////////////////////////\n  // `hash_combine` comes from boost (functional/hash):\n  // http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html\n  // Boost Software License - Version 1.0\n  // http://www.boost.org/users/license.html\n  template <typename T>\n  void hash_combine (std::size_t& seed, const T& val)\n  {\n    seed ^= std::hash<T>()(val) + 0x9e3779b9\n             + (seed<<6) + (seed>>2);\n  }\n  //////////////////////////////////////////////////////////\n\n  const char* sass_op_to_name(enum Sass_OP op);\n\n  const char* sass_op_separator(enum Sass_OP op);\n\n  //////////////////////////////////////////////////////////\n  // Abstract base class for all abstract syntax tree nodes.\n  //////////////////////////////////////////////////////////\n  class AST_Node : public SharedObj {\n    ADD_PROPERTY(SourceSpan, pstate)\n  public:\n    AST_Node(SourceSpan pstate)\n    : pstate_(pstate)\n    { }\n    AST_Node(const AST_Node* ptr)\n    : pstate_(ptr->pstate_)\n    { }\n\n    // allow implicit conversion to string\n    // needed for by SharedPtr implementation\n    operator sass::string() {\n      return to_string();\n    }\n\n    // AST_Node(AST_Node& ptr) = delete;\n\n    virtual ~AST_Node() = 0;\n    virtual size_t hash() const { return 0; }\n    virtual sass::string inspect() const { return to_string({ INSPECT, 5 }); }\n    virtual sass::string to_sass() const { return to_string({ TO_SASS, 5 }); }\n    virtual sass::string to_string(Sass_Inspect_Options opt) const;\n    virtual sass::string to_css(Sass_Inspect_Options opt) const;\n    virtual sass::string to_string() const;\n    virtual void cloneChildren() {};\n    // generic find function (not fully implemented yet)\n    // ToDo: add specific implementations to all children\n    virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };\n    void update_pstate(const SourceSpan& pstate);\n\n    // Some objects are not meant to be compared\n    // ToDo: maybe fall-back to pointer comparison?\n    virtual bool operator== (const AST_Node& rhs) const {\n      throw std::runtime_error(\"operator== not implemented\");\n    }\n\n    // We can give some reasonable implementations by using\n    // invert operators on the specialized implementations\n    virtual bool operator!= (const AST_Node& rhs) const {\n      // Unequal if not equal\n      return !(*this == rhs);\n    }\n\n    ATTACH_ABSTRACT_AST_OPERATIONS(AST_Node);\n    ATTACH_ABSTRACT_CRTP_PERFORM_METHODS()\n  };\n  inline AST_Node::~AST_Node() { }\n\n  //////////////////////////////////////////////////////////////////////\n  // define cast template now (need complete type)\n  //////////////////////////////////////////////////////////////////////\n\n  template<class T>\n  T* Cast(AST_Node* ptr) {\n    return ptr && typeid(T) == typeid(*ptr) ?\n           static_cast<T*>(ptr) : NULL;\n  };\n\n  template<class T>\n  const T* Cast(const AST_Node* ptr) {\n    return ptr && typeid(T) == typeid(*ptr) ?\n           static_cast<const T*>(ptr) : NULL;\n  };\n\n  //////////////////////////////////////////////////////////////////////\n  // Abstract base class for expressions. This side of the AST hierarchy\n  // represents elements in value contexts, which exist primarily to be\n  // evaluated and returned.\n  //////////////////////////////////////////////////////////////////////\n  class Expression : public AST_Node {\n  public:\n    enum Type {\n      NONE,\n      BOOLEAN,\n      NUMBER,\n      COLOR,\n      STRING,\n      LIST,\n      MAP,\n      SELECTOR,\n      NULL_VAL,\n      FUNCTION_VAL,\n      C_WARNING,\n      C_ERROR,\n      FUNCTION,\n      VARIABLE,\n      PARENT,\n      NUM_TYPES\n    };\n  private:\n    // expressions in some contexts shouldn't be evaluated\n    ADD_PROPERTY(bool, is_delayed)\n    ADD_PROPERTY(bool, is_expanded)\n    ADD_PROPERTY(bool, is_interpolant)\n    ADD_PROPERTY(Type, concrete_type)\n  public:\n    Expression(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);\n    virtual operator bool() { return true; }\n    virtual ~Expression() { }\n    virtual bool is_invisible() const { return false; }\n\n    virtual sass::string type() const { return \"\"; }\n    static sass::string type_name() { return \"\"; }\n\n    virtual bool is_false() { return false; }\n    // virtual bool is_true() { return !is_false(); }\n    virtual bool operator< (const Expression& rhs) const { return false; }\n    virtual bool operator== (const Expression& rhs) const { return false; }\n    inline bool operator>(const Expression& rhs) const { return rhs < *this; }\n    inline bool operator!=(const Expression& rhs) const { return !(rhs == *this); }\n    virtual bool eq(const Expression& rhs) const { return *this == rhs; };\n    virtual void set_delayed(bool delayed) { is_delayed(delayed); }\n    virtual bool has_interpolant() const { return is_interpolant(); }\n    virtual bool is_left_interpolant() const { return is_interpolant(); }\n    virtual bool is_right_interpolant() const { return is_interpolant(); }\n    ATTACH_VIRTUAL_AST_OPERATIONS(Expression);\n    size_t hash() const override { return 0; }\n  };\n\n}\n\n/////////////////////////////////////////////////////////////////////////////////////\n// Hash method specializations for std::unordered_map to work with Sass::Expression\n/////////////////////////////////////////////////////////////////////////////////////\n\nnamespace std {\n  template<>\n  struct hash<Sass::ExpressionObj>\n  {\n    size_t operator()(Sass::ExpressionObj s) const\n    {\n      return s->hash();\n    }\n  };\n  template<>\n  struct equal_to<Sass::ExpressionObj>\n  {\n    bool operator()( Sass::ExpressionObj lhs,  Sass::ExpressionObj rhs) const\n    {\n      return lhs->hash() == rhs->hash();\n    }\n  };\n}\n\nnamespace Sass {\n\n  /////////////////////////////////////////////////////////////////////////////\n  // Mixin class for AST nodes that should behave like vectors. Uses the\n  // \"Template Method\" design pattern to allow subclasses to adjust their flags\n  // when certain objects are pushed.\n  /////////////////////////////////////////////////////////////////////////////\n  template <typename T>\n  class Vectorized {\n    sass::vector<T> elements_;\n  protected:\n    mutable size_t hash_;\n    void reset_hash() { hash_ = 0; }\n    virtual void adjust_after_pushing(T element) { }\n  public:\n    Vectorized(size_t s = 0) : hash_(0)\n    { elements_.reserve(s); }\n    Vectorized(sass::vector<T> vec) :\n      elements_(std::move(vec)),\n      hash_(0)\n    {}\n    virtual ~Vectorized() = 0;\n    size_t length() const   { return elements_.size(); }\n    bool empty() const      { return elements_.empty(); }\n    void clear()            { return elements_.clear(); }\n    T& last()               { return elements_.back(); }\n    T& first()              { return elements_.front(); }\n    const T& last() const   { return elements_.back(); }\n    const T& first() const  { return elements_.front(); }\n\n    bool operator== (const Vectorized<T>& rhs) const {\n      // Abort early if sizes do not match\n      if (length() != rhs.length()) return false;\n      // Otherwise test each node for object equalicy in order\n      return std::equal(begin(), end(), rhs.begin(), ObjEqualityFn<T>);\n    }\n\n    bool operator!= (const Vectorized<T>& rhs) const {\n      return !(*this == rhs);\n    }\n\n    T& operator[](size_t i) { return elements_[i]; }\n    virtual const T& at(size_t i) const { return elements_.at(i); }\n    virtual T& at(size_t i) { return elements_.at(i); }\n    const T& get(size_t i) const { return elements_[i]; }\n    const T& operator[](size_t i) const { return elements_[i]; }\n\n    // Implicitly get the sass::vector from our object\n    // Makes the Vector directly assignable to sass::vector\n    // You are responsible to make a copy if needed\n    // Note: since this returns the real object, we can't\n    // Note: guarantee that the hash will not get out of sync\n    operator sass::vector<T>&() { return elements_; }\n    operator const sass::vector<T>&() const { return elements_; }\n\n    // Explicitly request all elements as a real sass::vector\n    // You are responsible to make a copy if needed\n    // Note: since this returns the real object, we can't\n    // Note: guarantee that the hash will not get out of sync\n    sass::vector<T>& elements() { return elements_; }\n    const sass::vector<T>& elements() const { return elements_; }\n\n    // Insert all items from compatible vector\n    void concat(const sass::vector<T>& v)\n    {\n      if (!v.empty()) reset_hash();\n      elements().insert(end(), v.begin(), v.end());\n    }\n\n    // Syntatic sugar for pointers\n    void concat(const Vectorized<T>* v)\n    {\n      if (v != nullptr) {\n        return concat(*v);\n      }\n    }\n\n    // Insert one item on the front\n    void unshift(T element)\n    {\n      reset_hash();\n      elements_.insert(begin(), element);\n    }\n\n    // Remove and return item on the front\n    // ToDo: handle empty vectors\n    T shift() {\n      reset_hash();\n      T first = get(0);\n      elements_.erase(begin());\n      return first;\n    }\n\n    // Insert one item on the back\n    // ToDo: rename this to push\n    void append(T element)\n    {\n      reset_hash();\n      elements_.insert(end(), element);\n      // ToDo: Mostly used by parameters and arguments\n      // ToDo: Find a more elegant way to support this\n      adjust_after_pushing(element);\n    }\n\n    // Check if an item already exists\n    // Uses underlying object `operator==`\n    // E.g. compares the actual objects\n    bool contains(const T& el) const {\n      for (const T& rhs : elements_) {\n        // Test the underlying objects for equality\n        // A std::find checks for pointer equality\n        if (ObjEqualityFn(el, rhs)) {\n          return true;\n        }\n      }\n      return false;\n    }\n\n    // This might be better implemented as `operator=`?\n    void elements(sass::vector<T> e) {\n      reset_hash();\n      elements_ = std::move(e);\n    }\n\n    virtual size_t hash() const\n    {\n      if (hash_ == 0) {\n        for (const T& el : elements_) {\n          hash_combine(hash_, el->hash());\n        }\n      }\n      return hash_;\n    }\n\n    template <typename P, typename V>\n    typename sass::vector<T>::iterator insert(P position, const V& val) {\n      reset_hash();\n      return elements_.insert(position, val);\n    }\n\n    typename sass::vector<T>::iterator end() { return elements_.end(); }\n    typename sass::vector<T>::iterator begin() { return elements_.begin(); }\n    typename sass::vector<T>::const_iterator end() const { return elements_.end(); }\n    typename sass::vector<T>::const_iterator begin() const { return elements_.begin(); }\n    typename sass::vector<T>::iterator erase(typename sass::vector<T>::iterator el) { reset_hash(); return elements_.erase(el); }\n    typename sass::vector<T>::const_iterator erase(typename sass::vector<T>::const_iterator el) { reset_hash(); return elements_.erase(el); }\n\n  };\n  template <typename T>\n  inline Vectorized<T>::~Vectorized() { }\n\n  /////////////////////////////////////////////////////////////////////////////\n  // Mixin class for AST nodes that should behave like a hash table. Uses an\n  // extra <sass::vector> internally to maintain insertion order for interation.\n  /////////////////////////////////////////////////////////////////////////////\n  template <typename K, typename T, typename U>\n  class Hashed {\n  private:\n    std::unordered_map<\n      K, T, ObjHash, ObjHashEquality\n    > elements_;\n\n    sass::vector<K> _keys;\n    sass::vector<T> _values;\n  protected:\n    mutable size_t hash_;\n    K duplicate_key_;\n    void reset_hash() { hash_ = 0; }\n    void reset_duplicate_key() { duplicate_key_ = {}; }\n    virtual void adjust_after_pushing(std::pair<K, T> p) { }\n  public:\n    Hashed(size_t s = 0)\n    : elements_(),\n      _keys(),\n      _values(),\n      hash_(0), duplicate_key_({})\n    {\n      _keys.reserve(s);\n      _values.reserve(s);\n      elements_.reserve(s);\n    }\n    virtual ~Hashed();\n    size_t length() const                  { return _keys.size(); }\n    bool empty() const                     { return _keys.empty(); }\n    bool has(K k) const          {\n      return elements_.find(k) != elements_.end();\n    }\n    T at(K k) const {\n      if (elements_.count(k))\n      {\n        return elements_.at(k);\n      }\n      else { return {}; }\n    }\n    bool has_duplicate_key() const         { return duplicate_key_ != nullptr; }\n    K get_duplicate_key() const  { return duplicate_key_; }\n    const std::unordered_map<\n      K, T, ObjHash, ObjHashEquality\n    >& elements() { return elements_; }\n    Hashed& operator<<(std::pair<K, T> p)\n    {\n      reset_hash();\n\n      if (!has(p.first)) {\n        _keys.push_back(p.first);\n        _values.push_back(p.second);\n      }\n      else if (!duplicate_key_) {\n        duplicate_key_ = p.first;\n      }\n\n      elements_[p.first] = p.second;\n\n      adjust_after_pushing(p);\n      return *this;\n    }\n    Hashed& operator+=(Hashed* h)\n    {\n      if (length() == 0) {\n        this->elements_ = h->elements_;\n        this->_values = h->_values;\n        this->_keys = h->_keys;\n        return *this;\n      }\n\n      for (auto key : h->keys()) {\n        *this << std::make_pair(key, h->at(key));\n      }\n\n      reset_duplicate_key();\n      return *this;\n    }\n    const std::unordered_map<\n      K, T, ObjHash, ObjHashEquality\n    >& pairs() const { return elements_; }\n\n    const sass::vector<K>& keys() const { return _keys; }\n    const sass::vector<T>& values() const { return _values; }\n\n//    std::unordered_map<ExpressionObj, ExpressionObj>::iterator end() { return elements_.end(); }\n//    std::unordered_map<ExpressionObj, ExpressionObj>::iterator begin() { return elements_.begin(); }\n//    std::unordered_map<ExpressionObj, ExpressionObj>::const_iterator end() const { return elements_.end(); }\n//    std::unordered_map<ExpressionObj, ExpressionObj>::const_iterator begin() const { return elements_.begin(); }\n\n  };\n  template <typename K, typename T, typename U>\n  inline Hashed<K, T, U>::~Hashed() { }\n\n  /////////////////////////////////////////////////////////////////////////\n  // Abstract base class for statements. This side of the AST hierarchy\n  // represents elements in expansion contexts, which exist primarily to be\n  // rewritten and macro-expanded.\n  /////////////////////////////////////////////////////////////////////////\n  class Statement : public AST_Node {\n  public:\n    enum Type {\n      NONE,\n      RULESET,\n      MEDIA,\n      DIRECTIVE,\n      SUPPORTS,\n      ATROOT,\n      BUBBLE,\n      CONTENT,\n      KEYFRAMERULE,\n      DECLARATION,\n      ASSIGNMENT,\n      IMPORT_STUB,\n      IMPORT,\n      COMMENT,\n      WARNING,\n      RETURN,\n      EXTEND,\n      ERROR,\n      DEBUGSTMT,\n      WHILE,\n      EACH,\n      FOR,\n      IF\n    };\n  private:\n    ADD_PROPERTY(Type, statement_type)\n    ADD_PROPERTY(size_t, tabs)\n    ADD_PROPERTY(bool, group_end)\n  public:\n    Statement(SourceSpan pstate, Type st = NONE, size_t t = 0);\n    virtual ~Statement() = 0; // virtual destructor\n    // needed for rearranging nested rulesets during CSS emission\n    virtual bool bubbles();\n    virtual bool has_content();\n    virtual bool is_invisible() const;\n    ATTACH_VIRTUAL_AST_OPERATIONS(Statement)\n  };\n  inline Statement::~Statement() { }\n\n  ////////////////////////\n  // Blocks of statements.\n  ////////////////////////\n  class Block final : public Statement, public Vectorized<Statement_Obj> {\n    ADD_PROPERTY(bool, is_root)\n    // needed for properly formatted CSS emission\n  protected:\n    void adjust_after_pushing(Statement_Obj s) override {}\n  public:\n    Block(SourceSpan pstate, size_t s = 0, bool r = false);\n    bool isInvisible() const;\n    bool has_content() override;\n    ATTACH_AST_OPERATIONS(Block)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////////////////\n  // Abstract base class for statements that contain blocks of statements.\n  ////////////////////////////////////////////////////////////////////////\n  class ParentStatement : public Statement {\n    ADD_PROPERTY(Block_Obj, block)\n  public:\n    ParentStatement(SourceSpan pstate, Block_Obj b);\n    ParentStatement(const ParentStatement* ptr); // copy constructor\n    virtual ~ParentStatement() = 0; // virtual destructor\n    virtual bool has_content() override;\n  };\n  inline ParentStatement::~ParentStatement() { }\n\n  /////////////////////////////////////////////////////////////////////////////\n  // Rulesets (i.e., sets of styles headed by a selector and containing a block\n  // of style declarations.\n  /////////////////////////////////////////////////////////////////////////////\n  class StyleRule final : public ParentStatement {\n    ADD_PROPERTY(SelectorListObj, selector)\n    ADD_PROPERTY(Selector_Schema_Obj, schema)\n    ADD_PROPERTY(bool, is_root);\n  public:\n    StyleRule(SourceSpan pstate, SelectorListObj s = {}, Block_Obj b = {});\n    bool is_invisible() const override;\n    ATTACH_AST_OPERATIONS(StyleRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////\n  // Bubble.\n  /////////////////\n  class Bubble final : public Statement {\n    ADD_PROPERTY(Statement_Obj, node)\n    ADD_PROPERTY(bool, group_end)\n  public:\n    Bubble(SourceSpan pstate, Statement_Obj n, Statement_Obj g = {}, size_t t = 0);\n    bool bubbles() override;\n    ATTACH_AST_OPERATIONS(Bubble)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////\n  // Trace.\n  /////////////////\n  class Trace final : public ParentStatement {\n    ADD_CONSTREF(char, type)\n    ADD_CONSTREF(sass::string, name)\n  public:\n    Trace(SourceSpan pstate, sass::string n, Block_Obj b = {}, char type = 'm');\n    ATTACH_AST_OPERATIONS(Trace)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////////////////////////////////////////\n  // At-rules -- arbitrary directives beginning with \"@\" that may have an\n  // optional statement block.\n  ///////////////////////////////////////////////////////////////////////\n  class AtRule final : public ParentStatement {\n    ADD_CONSTREF(sass::string, keyword)\n    ADD_PROPERTY(SelectorListObj, selector)\n    ADD_PROPERTY(ExpressionObj, value)\n  public:\n    AtRule(SourceSpan pstate, sass::string kwd, SelectorListObj sel = {}, Block_Obj b = {}, ExpressionObj val = {});\n    bool bubbles() override;\n    bool is_media();\n    bool is_keyframes();\n    ATTACH_AST_OPERATIONS(AtRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////////////////////////////////////////\n  // Keyframe-rules -- the child blocks of \"@keyframes\" nodes.\n  ///////////////////////////////////////////////////////////////////////\n  class Keyframe_Rule final : public ParentStatement {\n    // according to css spec, this should be <keyframes-name>\n    // <keyframes-name> = <custom-ident> | <string>\n    ADD_PROPERTY(SelectorListObj, name)\n  public:\n    Keyframe_Rule(SourceSpan pstate, Block_Obj b);\n    ATTACH_AST_OPERATIONS(Keyframe_Rule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////////////////\n  // Declarations -- style rules consisting of a property name and values.\n  ////////////////////////////////////////////////////////////////////////\n  class Declaration final : public ParentStatement {\n    ADD_PROPERTY(String_Obj, property)\n    ADD_PROPERTY(ExpressionObj, value)\n    ADD_PROPERTY(bool, is_important)\n    ADD_PROPERTY(bool, is_custom_property)\n    ADD_PROPERTY(bool, is_indented)\n  public:\n    Declaration(SourceSpan pstate, String_Obj prop, ExpressionObj val, bool i = false, bool c = false, Block_Obj b = {});\n    bool is_invisible() const override;\n    ATTACH_AST_OPERATIONS(Declaration)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////\n  // Assignments -- variable and value.\n  /////////////////////////////////////\n  class Assignment final : public Statement {\n    ADD_CONSTREF(sass::string, variable)\n    ADD_PROPERTY(ExpressionObj, value)\n    ADD_PROPERTY(bool, is_default)\n    ADD_PROPERTY(bool, is_global)\n  public:\n    Assignment(SourceSpan pstate, sass::string var, ExpressionObj val, bool is_default = false, bool is_global = false);\n    ATTACH_AST_OPERATIONS(Assignment)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////////////////////\n  // Import directives. CSS and Sass import lists can be intermingled, so it's\n  // necessary to store a list of each in an Import node.\n  ////////////////////////////////////////////////////////////////////////////\n  class Import final : public Statement {\n    sass::vector<ExpressionObj> urls_;\n    sass::vector<Include>        incs_;\n    ADD_PROPERTY(List_Obj,      import_queries);\n  public:\n    Import(SourceSpan pstate);\n    sass::vector<Include>& incs();\n    sass::vector<ExpressionObj>& urls();\n    ATTACH_AST_OPERATIONS(Import)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  // not yet resolved single import\n  // so far we only know requested name\n  class Import_Stub final : public Statement {\n    Include resource_;\n  public:\n    Import_Stub(SourceSpan pstate, Include res);\n    Include resource();\n    sass::string imp_path();\n    sass::string abs_path();\n    ATTACH_AST_OPERATIONS(Import_Stub)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////\n  // The Sass `@warn` directive.\n  //////////////////////////////\n  class WarningRule final : public Statement {\n    ADD_PROPERTY(ExpressionObj, message)\n  public:\n    WarningRule(SourceSpan pstate, ExpressionObj msg);\n    ATTACH_AST_OPERATIONS(WarningRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////\n  // The Sass `@error` directive.\n  ///////////////////////////////\n  class ErrorRule final : public Statement {\n    ADD_PROPERTY(ExpressionObj, message)\n  public:\n    ErrorRule(SourceSpan pstate, ExpressionObj msg);\n    ATTACH_AST_OPERATIONS(ErrorRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////\n  // The Sass `@debug` directive.\n  ///////////////////////////////\n  class DebugRule final : public Statement {\n    ADD_PROPERTY(ExpressionObj, value)\n  public:\n    DebugRule(SourceSpan pstate, ExpressionObj val);\n    ATTACH_AST_OPERATIONS(DebugRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////////////\n  // CSS comments. These may be interpolated.\n  ///////////////////////////////////////////\n  class Comment final : public Statement {\n    ADD_PROPERTY(String_Obj, text)\n    ADD_PROPERTY(bool, is_important)\n  public:\n    Comment(SourceSpan pstate, String_Obj txt, bool is_important);\n    virtual bool is_invisible() const override;\n    ATTACH_AST_OPERATIONS(Comment)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////\n  // The Sass `@if` control directive.\n  ////////////////////////////////////\n  class If final : public ParentStatement {\n    ADD_PROPERTY(ExpressionObj, predicate)\n    ADD_PROPERTY(Block_Obj, alternative)\n  public:\n    If(SourceSpan pstate, ExpressionObj pred, Block_Obj con, Block_Obj alt = {});\n    virtual bool has_content() override;\n    ATTACH_AST_OPERATIONS(If)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////\n  // The Sass `@for` control directive.\n  /////////////////////////////////////\n  class ForRule final : public ParentStatement {\n    ADD_CONSTREF(sass::string, variable)\n    ADD_PROPERTY(ExpressionObj, lower_bound)\n    ADD_PROPERTY(ExpressionObj, upper_bound)\n    ADD_PROPERTY(bool, is_inclusive)\n  public:\n    ForRule(SourceSpan pstate, sass::string var, ExpressionObj lo, ExpressionObj hi, Block_Obj b, bool inc);\n    ATTACH_AST_OPERATIONS(ForRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////////////\n  // The Sass `@each` control directive.\n  //////////////////////////////////////\n  class EachRule final : public ParentStatement {\n    ADD_PROPERTY(sass::vector<sass::string>, variables)\n    ADD_PROPERTY(ExpressionObj, list)\n  public:\n    EachRule(SourceSpan pstate, sass::vector<sass::string> vars, ExpressionObj lst, Block_Obj b);\n    ATTACH_AST_OPERATIONS(EachRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////////\n  // The Sass `@while` control directive.\n  ///////////////////////////////////////\n  class WhileRule final : public ParentStatement {\n    ADD_PROPERTY(ExpressionObj, predicate)\n  public:\n    WhileRule(SourceSpan pstate, ExpressionObj pred, Block_Obj b);\n    ATTACH_AST_OPERATIONS(WhileRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////////////////////////////\n  // The @return directive for use inside SassScript functions.\n  /////////////////////////////////////////////////////////////\n  class Return final : public Statement {\n    ADD_PROPERTY(ExpressionObj, value)\n  public:\n    Return(SourceSpan pstate, ExpressionObj val);\n    ATTACH_AST_OPERATIONS(Return)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////////////////////////////////////////////\n  // Definitions for both mixins and functions. The two cases are distinguished\n  // by a type tag.\n  /////////////////////////////////////////////////////////////////////////////\n  class Definition final : public ParentStatement {\n  public:\n    enum Type { MIXIN, FUNCTION };\n    ADD_CONSTREF(sass::string, name)\n    ADD_PROPERTY(Parameters_Obj, parameters)\n    ADD_PROPERTY(Env*, environment)\n    ADD_PROPERTY(Type, type)\n    ADD_PROPERTY(Native_Function, native_function)\n    ADD_PROPERTY(Sass_Function_Entry, c_function)\n    ADD_PROPERTY(void*, cookie)\n    ADD_PROPERTY(bool, is_overload_stub)\n    ADD_PROPERTY(Signature, signature)\n  public:\n    Definition(SourceSpan pstate,\n               sass::string n,\n               Parameters_Obj params,\n               Block_Obj b,\n               Type t);\n    Definition(SourceSpan pstate,\n               Signature sig,\n               sass::string n,\n               Parameters_Obj params,\n               Native_Function func_ptr,\n               bool overload_stub = false);\n    Definition(SourceSpan pstate,\n               Signature sig,\n               sass::string n,\n               Parameters_Obj params,\n               Sass_Function_Entry c_func);\n    ATTACH_AST_OPERATIONS(Definition)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////////////\n  // Mixin calls (i.e., `@include ...`).\n  //////////////////////////////////////\n  class Mixin_Call final : public ParentStatement {\n    ADD_CONSTREF(sass::string, name)\n    ADD_PROPERTY(Arguments_Obj, arguments)\n    ADD_PROPERTY(Parameters_Obj, block_parameters)\n  public:\n    Mixin_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Parameters_Obj b_params = {}, Block_Obj b = {});\n    ATTACH_AST_OPERATIONS(Mixin_Call)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////////////////////\n  // The @content directive for mixin content blocks.\n  ///////////////////////////////////////////////////\n  class Content final : public Statement {\n    ADD_PROPERTY(Arguments_Obj, arguments)\n  public:\n    Content(SourceSpan pstate, Arguments_Obj args);\n    ATTACH_AST_OPERATIONS(Content)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////////////////////\n  // Arithmetic negation (logical negation is just an ordinary function call).\n  ////////////////////////////////////////////////////////////////////////////\n  class Unary_Expression final : public Expression {\n  public:\n    enum Type { PLUS, MINUS, NOT, SLASH };\n  private:\n    HASH_PROPERTY(Type, optype)\n    HASH_PROPERTY(ExpressionObj, operand)\n    mutable size_t hash_;\n  public:\n    Unary_Expression(SourceSpan pstate, Type t, ExpressionObj o);\n    const sass::string type_name();\n    virtual bool operator==(const Expression& rhs) const override;\n    size_t hash() const override;\n    ATTACH_AST_OPERATIONS(Unary_Expression)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////\n  // Individual argument objects for mixin and function calls.\n  ////////////////////////////////////////////////////////////\n  class Argument final : public Expression {\n    HASH_PROPERTY(ExpressionObj, value)\n    HASH_CONSTREF(sass::string, name)\n    ADD_PROPERTY(bool, is_rest_argument)\n    ADD_PROPERTY(bool, is_keyword_argument)\n    mutable size_t hash_;\n  public:\n    Argument(SourceSpan pstate, ExpressionObj val, sass::string n = \"\", bool rest = false, bool keyword = false);\n    void set_delayed(bool delayed) override;\n    bool operator==(const Expression& rhs) const override;\n    size_t hash() const override;\n    ATTACH_AST_OPERATIONS(Argument)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////////////////\n  // Argument lists -- in their own class to facilitate context-sensitive\n  // error checking (e.g., ensuring that all ordinal arguments precede all\n  // named arguments).\n  ////////////////////////////////////////////////////////////////////////\n  class Arguments final : public Expression, public Vectorized<Argument_Obj> {\n    ADD_PROPERTY(bool, has_named_arguments)\n    ADD_PROPERTY(bool, has_rest_argument)\n    ADD_PROPERTY(bool, has_keyword_argument)\n  protected:\n    void adjust_after_pushing(Argument_Obj a) override;\n  public:\n    Arguments(SourceSpan pstate);\n    void set_delayed(bool delayed) override;\n    Argument_Obj get_rest_argument();\n    Argument_Obj get_keyword_argument();\n    ATTACH_AST_OPERATIONS(Arguments)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n\n  // A Media StyleRule before it has been evaluated\n  // Could be already final or an interpolation\n  class MediaRule final : public ParentStatement {\n    ADD_PROPERTY(List_Obj, schema)\n  public:\n    MediaRule(SourceSpan pstate, Block_Obj block = {});\n\n    bool bubbles() override { return true; };\n    bool is_invisible() const override { return false; };\n    ATTACH_AST_OPERATIONS(MediaRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  // A Media StyleRule after it has been evaluated\n  // Representing the static or resulting css\n  class CssMediaRule final : public ParentStatement,\n    public Vectorized<CssMediaQuery_Obj> {\n  public:\n    CssMediaRule(SourceSpan pstate, Block_Obj b);\n    bool bubbles() override { return true; };\n    bool isInvisible() const { return empty(); }\n    bool is_invisible() const override { return false; };\n\n  public:\n    // Hash and equality implemtation from vector\n    size_t hash() const override { return Vectorized::hash(); }\n    // Check if two instances are considered equal\n    bool operator== (const CssMediaRule& rhs) const {\n      return Vectorized::operator== (rhs);\n    }\n    bool operator!=(const CssMediaRule& rhs) const {\n      // Invert from equality\n      return !(*this == rhs);\n    }\n\n    ATTACH_AST_OPERATIONS(CssMediaRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  // Media Queries after they have been evaluated\n  // Representing the static or resulting css\n  class CssMediaQuery final : public AST_Node {\n\n    // The modifier, probably either \"not\" or \"only\".\n    // This may be `null` if no modifier is in use.\n    ADD_PROPERTY(sass::string, modifier);\n\n    // The media type, for example \"screen\" or \"print\".\n    // This may be `null`. If so, [features] will not be empty.\n    ADD_PROPERTY(sass::string, type);\n\n    // Feature queries, including parentheses.\n    ADD_PROPERTY(sass::vector<sass::string>, features);\n\n  public:\n    CssMediaQuery(SourceSpan pstate);\n\n    // Check if two instances are considered equal\n    bool operator== (const CssMediaQuery& rhs) const;\n    bool operator!=(const CssMediaQuery& rhs) const {\n      // Invert from equality\n      return !(*this == rhs);\n    }\n\n    // Returns true if this query is empty\n    // Meaning it has no type and features\n    bool empty() const {\n      return type_.empty()\n        && modifier_.empty()\n        && features_.empty();\n    }\n\n    // Whether this media query matches all media types.\n    bool matchesAllTypes() const {\n      return type_.empty() || Util::equalsLiteral(\"all\", type_);\n    }\n\n    // Merges this with [other] and adds a query that matches the intersection\n    // of both inputs to [result]. Returns false if the result is unrepresentable\n    CssMediaQuery_Obj merge(CssMediaQuery_Obj& other);\n\n    ATTACH_AST_OPERATIONS(CssMediaQuery)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////\n  // Media queries (replaced by MediaRule at al).\n  // ToDo: only used for interpolation case\n  ////////////////////////////////////////////////////\n  class Media_Query final : public Expression,\n                            public Vectorized<Media_Query_ExpressionObj> {\n    ADD_PROPERTY(String_Obj, media_type)\n    ADD_PROPERTY(bool, is_negated)\n    ADD_PROPERTY(bool, is_restricted)\n  public:\n    Media_Query(SourceSpan pstate, String_Obj t = {}, size_t s = 0, bool n = false, bool r = false);\n    ATTACH_AST_OPERATIONS(Media_Query)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////\n  // Media expressions (for use inside media queries).\n  // ToDo: only used for interpolation case\n  ////////////////////////////////////////////////////\n  class Media_Query_Expression final : public Expression {\n    ADD_PROPERTY(ExpressionObj, feature)\n    ADD_PROPERTY(ExpressionObj, value)\n    ADD_PROPERTY(bool, is_interpolated)\n  public:\n    Media_Query_Expression(SourceSpan pstate, ExpressionObj f, ExpressionObj v, bool i = false);\n    ATTACH_AST_OPERATIONS(Media_Query_Expression)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////////////////\n  // At root expressions (for use inside @at-root).\n  /////////////////////////////////////////////////\n  class At_Root_Query final : public Expression {\n  private:\n    ADD_PROPERTY(ExpressionObj, feature)\n    ADD_PROPERTY(ExpressionObj, value)\n  public:\n    At_Root_Query(SourceSpan pstate, ExpressionObj f = {}, ExpressionObj v = {}, bool i = false);\n    bool exclude(sass::string str);\n    ATTACH_AST_OPERATIONS(At_Root_Query)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////\n  // At-root.\n  ///////////\n  class AtRootRule final : public ParentStatement {\n    ADD_PROPERTY(At_Root_Query_Obj, expression)\n  public:\n    AtRootRule(SourceSpan pstate, Block_Obj b = {}, At_Root_Query_Obj e = {});\n    bool bubbles() override;\n    bool exclude_node(Statement_Obj s);\n    ATTACH_AST_OPERATIONS(AtRootRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////////////////////////\n  // Individual parameter objects for mixins and functions.\n  /////////////////////////////////////////////////////////\n  class Parameter final : public AST_Node {\n    ADD_CONSTREF(sass::string, name)\n    ADD_PROPERTY(ExpressionObj, default_value)\n    ADD_PROPERTY(bool, is_rest_parameter)\n  public:\n    Parameter(SourceSpan pstate, sass::string n, ExpressionObj def = {}, bool rest = false);\n    ATTACH_AST_OPERATIONS(Parameter)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////////////////////////////////////////\n  // Parameter lists -- in their own class to facilitate context-sensitive\n  // error checking (e.g., ensuring that all optional parameters follow all\n  // required parameters).\n  /////////////////////////////////////////////////////////////////////////\n  class Parameters final : public AST_Node, public Vectorized<Parameter_Obj> {\n    ADD_PROPERTY(bool, has_optional_parameters)\n    ADD_PROPERTY(bool, has_rest_parameter)\n  protected:\n    void adjust_after_pushing(Parameter_Obj p) override;\n  public:\n    Parameters(SourceSpan pstate);\n    ATTACH_AST_OPERATIONS(Parameters)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n}\n\n#include \"ast_values.hpp\"\n#include \"ast_supports.hpp\"\n#include \"ast_selectors.hpp\"\n\n#ifdef __clang__\n\n// #pragma clang diagnostic pop\n// #pragma clang diagnostic push\n\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast2c.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast2c.hpp\"\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  union Sass_Value* AST2C::operator()(Boolean* b)\n  { return sass_make_boolean(b->value()); }\n\n  union Sass_Value* AST2C::operator()(Number* n)\n  { return sass_make_number(n->value(), n->unit().c_str()); }\n\n  union Sass_Value* AST2C::operator()(Custom_Warning* w)\n  { return sass_make_warning(w->message().c_str()); }\n\n  union Sass_Value* AST2C::operator()(Custom_Error* e)\n  { return sass_make_error(e->message().c_str()); }\n\n  union Sass_Value* AST2C::operator()(Color_RGBA* c)\n  { return sass_make_color(c->r(), c->g(), c->b(), c->a()); }\n\n  union Sass_Value* AST2C::operator()(Color_HSLA* c)\n  {\n    Color_RGBA_Obj rgba = c->copyAsRGBA();\n    return operator()(rgba.ptr());\n  }\n\n  union Sass_Value* AST2C::operator()(String_Constant* s)\n  {\n    if (s->quote_mark()) {\n      return sass_make_qstring(s->value().c_str());\n    } else {\n      return sass_make_string(s->value().c_str());\n    }\n  }\n\n  union Sass_Value* AST2C::operator()(String_Quoted* s)\n  { return sass_make_qstring(s->value().c_str()); }\n\n  union Sass_Value* AST2C::operator()(List* l)\n  {\n    union Sass_Value* v = sass_make_list(l->length(), l->separator(), l->is_bracketed());\n    for (size_t i = 0, L = l->length(); i < L; ++i) {\n      sass_list_set_value(v, i, (*l)[i]->perform(this));\n    }\n    return v;\n  }\n\n  union Sass_Value* AST2C::operator()(Map* m)\n  {\n    union Sass_Value* v = sass_make_map(m->length());\n    int i = 0;\n    for (auto key : m->keys()) {\n      sass_map_set_key(v, i, key->perform(this));\n      sass_map_set_value(v, i, m->at(key)->perform(this));\n      i++;\n    }\n    return v;\n  }\n\n  union Sass_Value* AST2C::operator()(Arguments* a)\n  {\n    union Sass_Value* v = sass_make_list(a->length(), SASS_COMMA, false);\n    for (size_t i = 0, L = a->length(); i < L; ++i) {\n      sass_list_set_value(v, i, (*a)[i]->perform(this));\n    }\n    return v;\n  }\n\n  union Sass_Value* AST2C::operator()(Argument* a)\n  { return a->value()->perform(this); }\n\n  // not strictly necessary because of the fallback\n  union Sass_Value* AST2C::operator()(Null* n)\n  { return sass_make_null(); }\n\n};\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast2c.hpp",
    "content": "#ifndef SASS_AST2C_H\n#define SASS_AST2C_H\n\n#include \"ast_fwd_decl.hpp\"\n#include \"operation.hpp\"\n#include \"sass/values.h\"\n\nnamespace Sass {\n\n  class AST2C : public Operation_CRTP<union Sass_Value*, AST2C> {\n\n  public:\n\n    AST2C() { }\n    ~AST2C() { }\n\n    union Sass_Value* operator()(Boolean*);\n    union Sass_Value* operator()(Number*);\n    union Sass_Value* operator()(Color_RGBA*);\n    union Sass_Value* operator()(Color_HSLA*);\n    union Sass_Value* operator()(String_Constant*);\n    union Sass_Value* operator()(String_Quoted*);\n    union Sass_Value* operator()(Custom_Warning*);\n    union Sass_Value* operator()(Custom_Error*);\n    union Sass_Value* operator()(List*);\n    union Sass_Value* operator()(Map*);\n    union Sass_Value* operator()(Null*);\n    union Sass_Value* operator()(Arguments*);\n    union Sass_Value* operator()(Argument*);\n\n    // return sass error if type is not supported\n    union Sass_Value* fallback(AST_Node* x)\n    { return sass_make_error(\"unknown type for C-API\"); }\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_def_macros.hpp",
    "content": "#ifndef SASS_AST_DEF_MACROS_H\n#define SASS_AST_DEF_MACROS_H\n\n// Helper class to switch a flag and revert once we go out of scope\ntemplate <class T>\nclass LocalOption {\n  private:\n    T* var; // pointer to original variable\n    T orig; // copy of the original option\n  public:\n    LocalOption(T& var)\n    {\n      this->var = &var;\n      this->orig = var;\n    }\n    LocalOption(T& var, T orig)\n    {\n      this->var = &var;\n      this->orig = var;\n      *(this->var) = orig;\n    }\n    void reset()\n    {\n      *(this->var) = this->orig;\n    }\n    ~LocalOption() {\n      *(this->var) = this->orig;\n    }\n};\n\n#define LOCAL_FLAG(name,opt) LocalOption<bool> flag_##name(name, opt)\n#define LOCAL_COUNT(name,opt) LocalOption<size_t> cnt_##name(name, opt)\n\n#define NESTING_GUARD(name) \\\n  LocalOption<size_t> cnt_##name(name, name + 1); \\\n  if (name > MAX_NESTING) throw Exception::NestingLimitError(pstate, traces); \\\n\n#define ADD_PROPERTY(type, name)\\\nprotected:\\\n  type name##_;\\\npublic:\\\n  type name() const        { return name##_; }\\\n  type name(type name##__) { return name##_ = name##__; }\\\nprivate:\n\n#define HASH_PROPERTY(type, name)\\\nprotected:\\\n  type name##_;\\\npublic:\\\n  type name() const        { return name##_; }\\\n  type name(type name##__) { hash_ = 0; return name##_ = name##__; }\\\nprivate:\n\n#define ADD_CONSTREF(type, name) \\\nprotected: \\\n  type name##_; \\\npublic: \\\n  const type& name() const { return name##_; } \\\n  void name(type name##__) { name##_ = name##__; } \\\nprivate:\n\n#define HASH_CONSTREF(type, name) \\\nprotected: \\\n  type name##_; \\\npublic: \\\n  const type& name() const { return name##_; } \\\n  void name(type name##__) { hash_ = 0; name##_ = name##__; } \\\nprivate:\n\n#ifdef DEBUG_SHARED_PTR\n\n#define ATTACH_ABSTRACT_AST_OPERATIONS(klass) \\\n  virtual klass* copy(sass::string, size_t) const = 0; \\\n  virtual klass* clone(sass::string, size_t) const = 0; \\\n\n#define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \\\n  klass(const klass* ptr); \\\n  virtual klass* copy(sass::string, size_t) const override = 0; \\\n  virtual klass* clone(sass::string, size_t) const override = 0; \\\n\n#define ATTACH_AST_OPERATIONS(klass) \\\n  klass(const klass* ptr); \\\n  virtual klass* copy(sass::string, size_t) const override; \\\n  virtual klass* clone(sass::string, size_t) const override; \\\n\n#else\n\n#define ATTACH_ABSTRACT_AST_OPERATIONS(klass) \\\n  virtual klass* copy() const = 0; \\\n  virtual klass* clone() const = 0; \\\n\n#define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \\\n  klass(const klass* ptr); \\\n  virtual klass* copy() const override = 0; \\\n  virtual klass* clone() const override = 0; \\\n\n#define ATTACH_AST_OPERATIONS(klass) \\\n  klass(const klass* ptr); \\\n  virtual klass* copy() const override; \\\n  virtual klass* clone() const override; \\\n\n#endif\n\n#define ATTACH_VIRTUAL_CMP_OPERATIONS(klass) \\\n  virtual bool operator==(const klass& rhs) const = 0; \\\n  virtual bool operator!=(const klass& rhs) const { return !(*this == rhs); }; \\\n\n#define ATTACH_CMP_OPERATIONS(klass) \\\n  virtual bool operator==(const klass& rhs) const; \\\n  virtual bool operator!=(const klass& rhs) const { return !(*this == rhs); }; \\\n\n#ifdef DEBUG_SHARED_PTR\n\n  #define IMPLEMENT_AST_OPERATORS(klass) \\\n    klass* klass::copy(sass::string file, size_t line) const { \\\n      klass* cpy = SASS_MEMORY_NEW(klass, this); \\\n      cpy->trace(file, line); \\\n      return cpy; \\\n    } \\\n    klass* klass::clone(sass::string file, size_t line) const { \\\n      klass* cpy = copy(file, line); \\\n      cpy->cloneChildren(); \\\n      return cpy; \\\n    } \\\n\n#else\n\n  #define IMPLEMENT_AST_OPERATORS(klass) \\\n    klass* klass::copy() const { \\\n      return SASS_MEMORY_NEW(klass, this); \\\n    } \\\n    klass* klass::clone() const { \\\n      klass* cpy = copy(); \\\n      cpy->cloneChildren(); \\\n      return cpy; \\\n    } \\\n\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_fwd_decl.cpp",
    "content": "#include \"ast.hpp\"\n\nnamespace Sass {\n\n  #define IMPLEMENT_BASE_CAST(T) \\\n  template<> \\\n  T* Cast(AST_Node* ptr) { \\\n    return dynamic_cast<T*>(ptr); \\\n  }; \\\n  \\\n  template<> \\\n  const T* Cast(const AST_Node* ptr) { \\\n    return dynamic_cast<const T*>(ptr); \\\n  }; \\\n\n  IMPLEMENT_BASE_CAST(AST_Node)\n  IMPLEMENT_BASE_CAST(Expression)\n  IMPLEMENT_BASE_CAST(Statement)\n  IMPLEMENT_BASE_CAST(ParentStatement)\n  IMPLEMENT_BASE_CAST(PreValue)\n  IMPLEMENT_BASE_CAST(Value)\n  IMPLEMENT_BASE_CAST(Color)\n  IMPLEMENT_BASE_CAST(List)\n  IMPLEMENT_BASE_CAST(String)\n  IMPLEMENT_BASE_CAST(String_Constant)\n  IMPLEMENT_BASE_CAST(SupportsCondition)\n  IMPLEMENT_BASE_CAST(Selector)\n  IMPLEMENT_BASE_CAST(SelectorComponent)\n  IMPLEMENT_BASE_CAST(SimpleSelector)\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_fwd_decl.hpp",
    "content": "#ifndef SASS_AST_FWD_DECL_H\n#define SASS_AST_FWD_DECL_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"memory.hpp\"\n#include \"sass/functions.h\"\n\n/////////////////////////////////////////////\n// Forward declarations for the AST visitors.\n/////////////////////////////////////////////\nnamespace Sass {\n\n  class SourceData;\n  class SourceFile;\n  class SynthFile;\n  class ItplFile;\n\n  class AST_Node;\n\n  class ParentStatement;\n\n  class SimpleSelector;\n\n  class Parent_Reference;\n\n  class PreValue;\n  class Block;\n  class Expression;\n  class Statement;\n  class Value;\n  class Declaration;\n  class StyleRule;\n  class Bubble;\n  class Trace;\n\n  class MediaRule;\n  class CssMediaRule;\n  class CssMediaQuery;\n\n  class SupportsRule;\n  class AtRule;\n\n  class Keyframe_Rule;\n  class AtRootRule;\n  class Assignment;\n\n  class Import;\n  class Import_Stub;\n  class WarningRule;\n\n  class ErrorRule;\n  class DebugRule;\n  class Comment;\n\n  class If;\n  class ForRule;\n  class EachRule;\n  class WhileRule;\n  class Return;\n  class Content;\n  class ExtendRule;\n  class Definition;\n\n  class List;\n  class Map;\n  class Function;\n\n  class Mixin_Call;\n  class Binary_Expression;\n  class Unary_Expression;\n  class Function_Call;\n  class Custom_Warning;\n  class Custom_Error;\n\n  class Variable;\n  class Number;\n  class Color;\n  class Color_RGBA;\n  class Color_HSLA;\n  class Boolean;\n  class String;\n  class Null;\n\n  class String_Schema;\n  class String_Constant;\n  class String_Quoted;\n\n  class Media_Query;\n  class Media_Query_Expression;\n  class SupportsCondition;\n  class SupportsOperation;\n  class SupportsNegation;\n  class SupportsDeclaration;\n  class Supports_Interpolation;\n  \n  class At_Root_Query;\n  class Parameter;\n  class Parameters;\n  class Argument;\n  class Arguments;\n  class Selector;\n\n\n  class Selector_Schema;\n  class PlaceholderSelector;\n  class TypeSelector;\n  class ClassSelector;\n  class IDSelector;\n  class AttributeSelector;\n\n  class PseudoSelector;\n  \n  class SelectorComponent;\n  class SelectorCombinator;\n  class CompoundSelector;\n  class ComplexSelector;\n  class SelectorList;\n\n  // common classes\n  class Context;\n  class Expand;\n  class Eval;\n\n  class Extension;\n\n  // declare classes that are instances of memory nodes\n  // Note: also add a mapping without underscore\n  // ToDo: move to camelCase vars in the future\n  #define IMPL_MEM_OBJ(type) \\\n    typedef SharedImpl<type> type##Obj; \\\n    typedef SharedImpl<type> type##_Obj; \\\n\n  IMPL_MEM_OBJ(SourceData);\n  IMPL_MEM_OBJ(SourceFile);\n  IMPL_MEM_OBJ(SynthFile);\n  IMPL_MEM_OBJ(ItplFile);\n\n  IMPL_MEM_OBJ(AST_Node);\n  IMPL_MEM_OBJ(Statement);\n  IMPL_MEM_OBJ(Block);\n  IMPL_MEM_OBJ(StyleRule);\n  IMPL_MEM_OBJ(Bubble);\n  IMPL_MEM_OBJ(Trace);\n  IMPL_MEM_OBJ(MediaRule);\n  IMPL_MEM_OBJ(CssMediaRule);\n  IMPL_MEM_OBJ(CssMediaQuery);\n  IMPL_MEM_OBJ(SupportsRule);\n  IMPL_MEM_OBJ(AtRule);\n  IMPL_MEM_OBJ(Keyframe_Rule);\n  IMPL_MEM_OBJ(AtRootRule);\n  IMPL_MEM_OBJ(Declaration);\n  IMPL_MEM_OBJ(Assignment);\n  IMPL_MEM_OBJ(Import);\n  IMPL_MEM_OBJ(Import_Stub);\n  IMPL_MEM_OBJ(WarningRule);\n  IMPL_MEM_OBJ(ErrorRule);\n  IMPL_MEM_OBJ(DebugRule);\n  IMPL_MEM_OBJ(Comment);\n  IMPL_MEM_OBJ(PreValue);\n  IMPL_MEM_OBJ(ParentStatement);\n  IMPL_MEM_OBJ(If);\n  IMPL_MEM_OBJ(ForRule);\n  IMPL_MEM_OBJ(EachRule);\n  IMPL_MEM_OBJ(WhileRule);\n  IMPL_MEM_OBJ(Return);\n  IMPL_MEM_OBJ(Content);\n  IMPL_MEM_OBJ(ExtendRule);\n  IMPL_MEM_OBJ(Definition);\n  IMPL_MEM_OBJ(Mixin_Call);\n  IMPL_MEM_OBJ(Value);\n  IMPL_MEM_OBJ(Expression);\n  IMPL_MEM_OBJ(List);\n  IMPL_MEM_OBJ(Map);\n  IMPL_MEM_OBJ(Function);\n  IMPL_MEM_OBJ(Binary_Expression);\n  IMPL_MEM_OBJ(Unary_Expression);\n  IMPL_MEM_OBJ(Function_Call);\n  IMPL_MEM_OBJ(Custom_Warning);\n  IMPL_MEM_OBJ(Custom_Error);\n  IMPL_MEM_OBJ(Variable);\n  IMPL_MEM_OBJ(Number);\n  IMPL_MEM_OBJ(Color);\n  IMPL_MEM_OBJ(Color_RGBA);\n  IMPL_MEM_OBJ(Color_HSLA);\n  IMPL_MEM_OBJ(Boolean);\n  IMPL_MEM_OBJ(String_Schema);\n  IMPL_MEM_OBJ(String);\n  IMPL_MEM_OBJ(String_Constant);\n  IMPL_MEM_OBJ(String_Quoted);\n  IMPL_MEM_OBJ(Media_Query);\n  IMPL_MEM_OBJ(Media_Query_Expression);\n  IMPL_MEM_OBJ(SupportsCondition);\n  IMPL_MEM_OBJ(SupportsOperation);\n  IMPL_MEM_OBJ(SupportsNegation);\n  IMPL_MEM_OBJ(SupportsDeclaration);\n  IMPL_MEM_OBJ(Supports_Interpolation);\n  IMPL_MEM_OBJ(At_Root_Query);\n  IMPL_MEM_OBJ(Null);\n  IMPL_MEM_OBJ(Parent_Reference);\n  IMPL_MEM_OBJ(Parameter);\n  IMPL_MEM_OBJ(Parameters);\n  IMPL_MEM_OBJ(Argument);\n  IMPL_MEM_OBJ(Arguments);\n  IMPL_MEM_OBJ(Selector);\n  IMPL_MEM_OBJ(Selector_Schema);\n  IMPL_MEM_OBJ(SimpleSelector);\n  IMPL_MEM_OBJ(PlaceholderSelector);\n  IMPL_MEM_OBJ(TypeSelector);\n  IMPL_MEM_OBJ(ClassSelector);\n  IMPL_MEM_OBJ(IDSelector);\n  IMPL_MEM_OBJ(AttributeSelector);\n  IMPL_MEM_OBJ(PseudoSelector);\n\n  IMPL_MEM_OBJ(SelectorComponent);\n  IMPL_MEM_OBJ(SelectorCombinator);\n  IMPL_MEM_OBJ(CompoundSelector);\n  IMPL_MEM_OBJ(ComplexSelector);\n  IMPL_MEM_OBJ(SelectorList);\n\n  // ###########################################################################\n  // some often used typedefs\n  // ###########################################################################\n\n  typedef sass::vector<Block*> BlockStack;\n  typedef sass::vector<Sass_Callee> CalleeStack;\n  typedef sass::vector<AST_Node_Obj> CallStack;\n  typedef sass::vector<CssMediaRuleObj> MediaStack;\n  typedef sass::vector<SelectorListObj> SelectorStack;\n  typedef sass::vector<Sass_Import_Entry> ImporterStack;\n\n  // only to switch implementations for testing\n  #define environment_map std::map\n\n  // ###########################################################################\n  // explicit type conversion functions\n  // ###########################################################################\n\n  template<class T>\n  T* Cast(AST_Node* ptr);\n\n  template<class T>\n  const T* Cast(const AST_Node* ptr);\n\n  // sometimes you know the class you want to cast to is final\n  // in this case a simple typeid check is faster and safe to use\n\n  #define DECLARE_BASE_CAST(T) \\\n  template<> T* Cast(AST_Node* ptr); \\\n  template<> const T* Cast(const AST_Node* ptr); \\\n\n  // ###########################################################################\n  // implement specialization for final classes\n  // ###########################################################################\n\n  DECLARE_BASE_CAST(AST_Node)\n  DECLARE_BASE_CAST(Expression)\n  DECLARE_BASE_CAST(Statement)\n  DECLARE_BASE_CAST(ParentStatement)\n  DECLARE_BASE_CAST(PreValue)\n  DECLARE_BASE_CAST(Value)\n  DECLARE_BASE_CAST(List)\n  DECLARE_BASE_CAST(Color)\n  DECLARE_BASE_CAST(String)\n  DECLARE_BASE_CAST(String_Constant)\n  DECLARE_BASE_CAST(SupportsCondition)\n  DECLARE_BASE_CAST(Selector)\n  DECLARE_BASE_CAST(SimpleSelector)\n  DECLARE_BASE_CAST(SelectorComponent)\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_helpers.hpp",
    "content": "#ifndef SASS_AST_HELPERS_H\n#define SASS_AST_HELPERS_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include <algorithm>\n#include <functional>\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  // ###########################################################################\n  // ###########################################################################\n\n  // easier to search with name\n  const bool DELAYED = true;\n\n  // ToDo: should this really be hardcoded\n  // Note: most methods follow precision option\n  const double NUMBER_EPSILON = 1e-12;\n\n  // macro to test if numbers are equal within a small error margin\n  #define NEAR_EQUAL(lhs, rhs) std::fabs(lhs - rhs) < NUMBER_EPSILON\n\n  // ###########################################################################\n  // We define various functions and functors here.\n  // Functions satisfy the BinaryPredicate requirement\n  // Functors are structs used for e.g. unordered_map\n  // ###########################################################################\n\n  // ###########################################################################\n  // Implement compare and hashing operations for raw pointers\n  // ###########################################################################\n\n  template <class T>\n  size_t PtrHashFn(const T* ptr) {\n    return std::hash<std::size_t>()((size_t)ptr);\n  }\n\n  struct PtrHash {\n    template <class T>\n    size_t operator() (const T* ptr) const {\n      return PtrHashFn(ptr);\n    }\n  };\n\n  template <class T>\n  bool PtrEqualityFn(const T* lhs, const T* rhs) {\n    return lhs == rhs; // compare raw pointers\n  }\n\n  struct PtrEquality {\n    template <class T>\n    bool operator() (const T* lhs, const T* rhs) const {\n      return PtrEqualityFn<T>(lhs, rhs);\n    }\n  };\n\n  // ###########################################################################\n  // Implement compare and hashing operations for AST Nodes\n  // ###########################################################################\n\n  // TODO: get rid of functions and use ObjEquality<T>\n\n  template <class T>\n  // Hash the raw pointer instead of object\n  size_t ObjPtrHashFn(const T& obj) {\n    return PtrHashFn(obj.ptr());\n  }\n\n  struct ObjPtrHash {\n    template <class T>\n    // Hash the raw pointer instead of object\n    size_t operator() (const T& obj) const {\n      return ObjPtrHashFn(obj);\n    }\n  };\n\n  template <class T>\n  // Hash the object and its content\n  size_t ObjHashFn(const T& obj) {\n    return obj ? obj->hash() : 0;\n  }\n\n  struct ObjHash {\n    template <class T>\n    // Hash the object and its content\n    size_t operator() (const T& obj) const {\n      return ObjHashFn(obj);\n    }\n  };\n\n  template <class T>\n  // Hash the object behind pointer\n  size_t PtrObjHashFn(const T* obj) {\n    return obj ? obj->hash() : 0;\n  }\n\n  struct PtrObjHash {\n    template <class T>\n    // Hash the object behind pointer\n    size_t operator() (const T* obj) const {\n      return PtrObjHashFn(obj);\n    }\n  };\n\n  template <class T>\n  // Compare raw pointers to the object\n  bool ObjPtrEqualityFn(const T& lhs, const T& rhs) {\n    return PtrEqualityFn(lhs.ptr(), rhs.ptr());\n  }\n\n  struct ObjPtrEquality {\n    template <class T>\n    // Compare raw pointers to the object\n    bool operator() (const T& lhs, const T& rhs) const {\n      return ObjPtrEqualityFn<T>(lhs, rhs);\n    }\n  };\n\n  template <class T>\n  // Compare the objects behind the pointers\n  bool PtrObjEqualityFn(const T* lhs, const T* rhs) {\n    if (lhs == nullptr) return rhs == nullptr;\n    else if (rhs == nullptr) return false;\n    else return *lhs == *rhs;\n  }\n\n  struct PtrObjEquality {\n    template <class T>\n    // Compare the objects behind the pointers\n    bool operator() (const T* lhs, const T* rhs) const {\n      return PtrObjEqualityFn<T>(lhs, rhs);\n    }\n  };\n\n  template <class T>\n  // Compare the objects and its contents\n  bool ObjEqualityFn(const T& lhs, const T& rhs) {\n    return PtrObjEqualityFn(lhs.ptr(), rhs.ptr());\n  }\n\n  struct ObjEquality {\n    template <class T>\n    // Compare the objects and its contents\n    bool operator() (const T& lhs, const T& rhs) const {\n      return ObjEqualityFn<T>(lhs, rhs);\n    }\n  };\n\n  // ###########################################################################\n  // Special compare function only for hashes.\n  // We need to make sure to not have objects equal that \n  // have different hashes. This is currently an issue,\n  // since `1px` is equal to `1` but have different hashes.\n  // This goes away once we remove unitless equality.\n  // ###########################################################################\n\n  template <class T>\n  // Compare the objects and its hashes\n  bool ObjHashEqualityFn(const T& lhs, const T& rhs) {\n    if (lhs == nullptr) return rhs == nullptr;\n    else if (rhs == nullptr) return false;\n    else return lhs->hash() == rhs->hash();\n  }\n  struct ObjHashEquality {\n    template <class T>\n    // Compare the objects and its contents and hashes\n    bool operator() (const T& lhs, const T& rhs) const {\n      return ObjEqualityFn<T>(lhs, rhs) &&\n        ObjHashEqualityFn(lhs, rhs);\n    }\n  };\n\n  // ###########################################################################\n  // Implement ordering operations for AST Nodes\n  // ###########################################################################\n\n  template <class T>\n  // Compare the objects behind pointers\n  bool PtrObjLessThanFn(const T* lhs, const T* rhs) {\n    if (lhs == nullptr) return rhs != nullptr;\n    else if (rhs == nullptr) return false;\n    else return *lhs < *rhs;\n  }\n\n  struct PtrObjLessThan {\n    template <class T>\n    // Compare the objects behind pointers\n    bool operator() (const T* lhs, const T* rhs) const {\n      return PtrObjLessThanFn<T>(lhs, rhs);\n    }\n  };\n\n  template <class T>\n  // Compare the objects and its content\n  bool ObjLessThanFn(const T& lhs, const T& rhs) {\n    return PtrObjLessThanFn(lhs.ptr(), rhs.ptr());\n  };\n\n  struct ObjLessThan {\n    template <class T>\n    // Compare the objects and its content\n    bool operator() (const T& lhs, const T& rhs) const {\n      return ObjLessThanFn<T>(lhs, rhs);\n    }\n  };\n\n  // ###########################################################################\n  // Some STL helper functions\n  // ###########################################################################\n\n  // Check if all elements are equal\n  template <class X, class Y,\n    typename XT = typename X::value_type,\n    typename YT = typename Y::value_type>\n  bool ListEquality(const X& lhs, const Y& rhs,\n    bool(*cmp)(const XT*, const YT*))\n  {\n    return lhs.size() == rhs.size() &&\n      std::equal(lhs.begin(), lhs.end(),\n        rhs.begin(), cmp);\n  }\n\n  // Return if Vector is empty\n  template <class T>\n  bool listIsEmpty(T* cnt) {\n    return cnt && cnt->empty();\n  }\n\n  // Erase items from vector that match predicate\n  template<class T, class UnaryPredicate>\n  void listEraseItemIf(T& vec, UnaryPredicate* predicate)\n  {\n    vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end());\n  }\n\n  // Check that every item in `lhs` is also in `rhs`\n  // Note: this works by comparing the raw pointers\n  template <typename T>\n  bool listIsSubsetOrEqual(const T& lhs, const T& rhs) {\n    for (const auto& item : lhs) {\n      if (std::find(rhs.begin(), rhs.end(), item) == rhs.end())\n        return false;\n    }\n    return true;\n  }\n\n  // ##########################################################################\n  // Returns whether [name] is the name of a pseudo-element\n  // that can be written with pseudo-class syntax (CSS2 vs CSS3):\n  // `:before`, `:after`, `:first-line`, or `:first-letter`\n  // ##########################################################################\n  inline bool isFakePseudoElement(const sass::string& name)\n  {\n    return Util::equalsLiteral(\"after\", name)\n      || Util::equalsLiteral(\"before\", name)\n      || Util::equalsLiteral(\"first-line\", name)\n      || Util::equalsLiteral(\"first-letter\", name);\n  }\n\n  // ##########################################################################\n  // Names of pseudo selectors that take selectors as arguments,\n  // and that are subselectors of their arguments.\n  // For example, `.foo` is a superselector of `:matches(.foo)`.\n  // ##########################################################################\n  inline bool isSubselectorPseudo(const sass::string& norm)\n  {\n    return Util::equalsLiteral(\"any\", norm)\n      || Util::equalsLiteral(\"matches\", norm)\n      || Util::equalsLiteral(\"nth-child\", norm)\n      || Util::equalsLiteral(\"nth-last-child\", norm);\n  }\n  // EO isSubselectorPseudo\n\n  // ###########################################################################\n  // Pseudo-class selectors that take unadorned selectors as arguments.\n  // ###########################################################################\n  inline bool isSelectorPseudoClass(const sass::string& test)\n  {\n    return Util::equalsLiteral(\"not\", test)\n      || Util::equalsLiteral(\"matches\", test)\n      || Util::equalsLiteral(\"current\", test)\n      || Util::equalsLiteral(\"any\", test)\n      || Util::equalsLiteral(\"has\", test)\n      || Util::equalsLiteral(\"host\", test)\n      || Util::equalsLiteral(\"host-context\", test);\n  }\n  // EO isSelectorPseudoClass\n\n  // ###########################################################################\n  // Pseudo-element selectors that take unadorned selectors as arguments.\n  // ###########################################################################\n  inline bool isSelectorPseudoElement(const sass::string& test)\n  {\n    return Util::equalsLiteral(\"slotted\", test);\n  }\n  // EO isSelectorPseudoElement\n\n  // ###########################################################################\n  // Pseudo-element selectors that has binominals\n  // ###########################################################################\n  inline bool isSelectorPseudoBinominal(const sass::string& test)\n  {\n    return Util::equalsLiteral(\"nth-child\", test)\n      || Util::equalsLiteral(\"nth-last-child\", test);\n  }\n  // isSelectorPseudoBinominal\n\n  // ###########################################################################\n  // ###########################################################################\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_sel_cmp.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast_selectors.hpp\"\n\nnamespace Sass {\n\n  /*#########################################################################*/\n  // Compare against base class on right hand side\n  // try to find the most specialized implementation\n  /*#########################################################################*/\n\n  // Selector lists can be compared to comma lists\n  bool SelectorList::operator== (const Expression& rhs) const\n  {\n    if (auto l = Cast<List>(&rhs)) { return *this == *l; }\n    if (auto s = Cast<Selector>(&rhs)) { return *this == *s; }\n    if (Cast<String>(&rhs) || Cast<Null>(&rhs)) { return false; }\n    throw std::runtime_error(\"invalid selector base classes to compare\");\n  }\n\n  // Selector lists can be compared to comma lists\n  bool SelectorList::operator== (const Selector& rhs) const\n  {\n    if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }\n    if (auto list = Cast<List>(&rhs)) { return *this == *list; }\n    throw std::runtime_error(\"invalid selector base classes to compare\");\n  }\n\n  bool ComplexSelector::operator== (const Selector& rhs) const\n  {\n    if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<ComplexSelector>(&rhs)) { return *sel == *this; }\n    if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }\n    throw std::runtime_error(\"invalid selector base classes to compare\");\n  }\n\n  bool SelectorCombinator::operator== (const Selector& rhs) const\n  {\n    if (auto cpx = Cast<SelectorCombinator>(&rhs)) { return *this == *cpx; }\n    return false;\n  }\n\n  bool CompoundSelector::operator== (const Selector& rhs) const\n  {\n    if (auto sel = Cast<SimpleSelector>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }\n    throw std::runtime_error(\"invalid selector base classes to compare\");\n  }\n\n  bool SimpleSelector::operator== (const Selector& rhs) const\n  {\n    if (auto sel = Cast<SelectorList>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<ComplexSelector>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<CompoundSelector>(&rhs)) { return *this == *sel; }\n    if (auto sel = Cast<SimpleSelector>(&rhs)) return *this == *sel;\n    throw std::runtime_error(\"invalid selector base classes to compare\");\n  }\n\n  /*#########################################################################*/\n  /*#########################################################################*/\n\n  bool SelectorList::operator== (const SelectorList& rhs) const\n  {\n    if (&rhs == this) return true;\n    if (rhs.length() != length()) return false;\n    std::unordered_set<const ComplexSelector*, PtrObjHash, PtrObjEquality> lhs_set;\n    lhs_set.reserve(length());\n    for (const ComplexSelectorObj& element : elements()) {\n      lhs_set.insert(element.ptr());\n    }\n    for (const ComplexSelectorObj& element : rhs.elements()) {\n      if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;\n    }\n    return true;\n  }\n\n\n\n  /*#########################################################################*/\n  // Compare SelectorList against all other selector types\n  /*#########################################################################*/\n\n  bool SelectorList::operator== (const ComplexSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (length() != 1) return false;\n    // Compare simple selectors\n    return *get(0) == rhs;\n  }\n\n  bool SelectorList::operator== (const CompoundSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (length() != 1) return false;\n    // Compare simple selectors\n    return *get(0) == rhs;\n  }\n\n  bool SelectorList::operator== (const SimpleSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (length() != 1) return false;\n    // Compare simple selectors\n    return *get(0) == rhs;\n  }\n\n  /*#########################################################################*/\n  // Compare ComplexSelector against itself\n  /*#########################################################################*/\n\n  bool ComplexSelector::operator== (const ComplexSelector& rhs) const\n  {\n    size_t len = length();\n    size_t rlen = rhs.length();\n    if (len != rlen) return false;\n    for (size_t i = 0; i < len; i += 1) {\n      if (*get(i) != *rhs.get(i)) return false;\n    }\n    return true;\n  }\n\n  /*#########################################################################*/\n  // Compare ComplexSelector against all other selector types\n  /*#########################################################################*/\n\n  bool ComplexSelector::operator== (const SelectorList& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (rhs.length() != 1) return false;\n    // Compare complex selector\n    return *this == *rhs.get(0);\n  }\n\n  bool ComplexSelector::operator== (const CompoundSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (length() != 1) return false;\n    // Compare compound selector\n    return *get(0) == rhs;\n  }\n\n  bool ComplexSelector::operator== (const SimpleSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (length() != 1) return false;\n    // Compare simple selectors\n    return *get(0) == rhs;\n  }\n\n  /*#########################################################################*/\n  // Compare SelectorCombinator against itself\n  /*#########################################################################*/\n\n  bool SelectorCombinator::operator==(const SelectorCombinator& rhs) const\n  {\n    return combinator() == rhs.combinator();\n  }\n\n  /*#########################################################################*/\n  // Compare SelectorCombinator against SelectorComponent\n  /*#########################################################################*/\n\n  bool SelectorCombinator::operator==(const SelectorComponent& rhs) const\n  {\n    if (const SelectorCombinator * sel = rhs.getCombinator()) {\n      return *this == *sel;\n    }\n    return false;\n  }\n\n  bool CompoundSelector::operator==(const SelectorComponent& rhs) const\n  {\n    if (const CompoundSelector * sel = rhs.getCompound()) {\n      return *this == *sel;\n    }\n    return false;\n  }\n\n  /*#########################################################################*/\n  // Compare CompoundSelector against itself\n  /*#########################################################################*/\n  // ToDo: Verifiy implementation\n  /*#########################################################################*/\n\n  bool CompoundSelector::operator== (const CompoundSelector& rhs) const\n  {\n    // std::cerr << \"comp vs comp\\n\";\n    if (&rhs == this) return true;\n    if (rhs.length() != length()) return false;\n    std::unordered_set<const SimpleSelector*, PtrObjHash, PtrObjEquality> lhs_set;\n    lhs_set.reserve(length());\n    for (const SimpleSelectorObj& element : elements()) {\n      lhs_set.insert(element.ptr());\n    }\n    // there is no break?!\n    for (const SimpleSelectorObj& element : rhs.elements()) {\n      if (lhs_set.find(element.ptr()) == lhs_set.end()) return false;\n    }\n    return true;\n  }\n\n\n  /*#########################################################################*/\n  // Compare CompoundSelector against all other selector types\n  /*#########################################################################*/\n\n  bool CompoundSelector::operator== (const SelectorList& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (rhs.length() != 1) return false;\n    // Compare complex selector\n    return *this == *rhs.get(0);\n  }\n\n  bool CompoundSelector::operator== (const ComplexSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (rhs.length() != 1) return false;\n    // Compare compound selector\n    return *this == *rhs.get(0);\n  }\n\n  bool CompoundSelector::operator== (const SimpleSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return false;\n    // Must have exactly one item\n    size_t rlen = length();\n    if (rlen > 1) return false;\n    if (rlen == 0) return true;\n    // Compare simple selectors\n    return *get(0) < rhs;\n  }\n\n  /*#########################################################################*/\n  // Compare SimpleSelector against itself (upcast from abstract base)\n  /*#########################################################################*/\n\n  // DOES NOT EXIST FOR ABSTRACT BASE CLASS\n\n  /*#########################################################################*/\n  // Compare SimpleSelector against all other selector types\n  /*#########################################################################*/\n\n  bool SimpleSelector::operator== (const SelectorList& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (rhs.length() != 1) return false;\n    // Compare complex selector\n    return *this == *rhs.get(0);\n  }\n\n  bool SimpleSelector::operator== (const ComplexSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return true;\n    // Must have exactly one item\n    if (rhs.length() != 1) return false;\n    // Compare compound selector\n    return *this == *rhs.get(0);\n  }\n\n  bool SimpleSelector::operator== (const CompoundSelector& rhs) const\n  {\n    // If both are empty they are equal\n    if (empty() && rhs.empty()) return false;\n    // Must have exactly one item\n    if (rhs.length() != 1) return false;\n    // Compare simple selector\n    return *this == *rhs.get(0);\n  }\n\n  /*#########################################################################*/\n  /*#########################################################################*/\n\n  bool IDSelector::operator== (const SimpleSelector& rhs) const\n  {\n    auto sel = Cast<IDSelector>(&rhs);\n    return sel ? *this == *sel : false;\n  }\n\n  bool TypeSelector::operator== (const SimpleSelector& rhs) const\n  {\n    auto sel = Cast<TypeSelector>(&rhs);\n    return sel ? *this == *sel : false;\n  }\n\n  bool ClassSelector::operator== (const SimpleSelector& rhs) const\n  {\n    auto sel = Cast<ClassSelector>(&rhs);\n    return sel ? *this == *sel : false;\n  }\n\n  bool PseudoSelector::operator== (const SimpleSelector& rhs) const\n  {\n    auto sel = Cast<PseudoSelector>(&rhs);\n    return sel ? *this == *sel : false;\n  }\n\n  bool AttributeSelector::operator== (const SimpleSelector& rhs) const\n  {\n    auto sel = Cast<AttributeSelector>(&rhs);\n    return sel ? *this == *sel : false;\n  }\n\n  bool PlaceholderSelector::operator== (const SimpleSelector& rhs) const\n  {\n    auto sel = Cast<PlaceholderSelector>(&rhs);\n    return sel ? *this == *sel : false;\n  }\n\n  /*#########################################################################*/\n  /*#########################################################################*/\n\n  bool IDSelector::operator== (const IDSelector& rhs) const\n  {\n    // ID has no namespacing\n    return name() == rhs.name();\n  }\n\n  bool TypeSelector::operator== (const TypeSelector& rhs) const\n  {\n    return is_ns_eq(rhs) && name() == rhs.name();\n  }\n\n  bool ClassSelector::operator== (const ClassSelector& rhs) const\n  {\n    // Class has no namespacing\n    return name() == rhs.name();\n  }\n\n  bool PlaceholderSelector::operator== (const PlaceholderSelector& rhs) const\n  {\n    // Placeholder has no namespacing\n    return name() == rhs.name();\n  }\n\n  bool AttributeSelector::operator== (const AttributeSelector& rhs) const\n  {\n    // smaller return, equal go on, bigger abort\n    if (is_ns_eq(rhs)) {\n      if (name() != rhs.name()) return false;\n      if (matcher() != rhs.matcher()) return false;\n      if (modifier() != rhs.modifier()) return false;\n      const String* lhs_val = value();\n      const String* rhs_val = rhs.value();\n      return PtrObjEquality()(lhs_val, rhs_val);\n    }\n    else { return false; }\n  }\n\n  bool PseudoSelector::operator== (const PseudoSelector& rhs) const\n  {\n    if (is_ns_eq(rhs)) {\n      if (name() != rhs.name()) return false;\n      if (isElement() != rhs.isElement()) return false;\n      const String* lhs_arg = argument();\n      const String* rhs_arg = rhs.argument();\n      if (!PtrObjEquality()(lhs_arg, rhs_arg)) return false;\n      const SelectorList* lhs_sel = selector();\n      const SelectorList* rhs_sel = rhs.selector();\n      return PtrObjEquality()(lhs_sel, rhs_sel);\n    }\n    else { return false; }\n  }\n\n  /*#########################################################################*/\n  /*#########################################################################*/\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_sel_super.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  // ##########################################################################\n  // To compare/debug against libsass you can use debugger.hpp:\n  // c++: std::cerr << \"result \" << debug_vec(compound) << \"\\n\";\n  // dart: stderr.writeln(\"result \" + compound.toString());\n  // ##########################################################################\n\n  // ##########################################################################\n  // Returns whether [list1] is a superselector of [list2].\n  // That is, whether [list1] matches every element that\n  // [list2] matches, as well as possibly additional elements.\n  // ##########################################################################\n  bool listIsSuperslector(\n    const sass::vector<ComplexSelectorObj>& list1,\n    const sass::vector<ComplexSelectorObj>& list2);\n\n  // ##########################################################################\n  // Returns whether [complex1] is a superselector of [complex2].\n  // That is, whether [complex1] matches every element that\n  // [complex2] matches, as well as possibly additional elements.\n  // ##########################################################################\n  bool complexIsSuperselector(\n    const sass::vector<SelectorComponentObj>& complex1,\n    const sass::vector<SelectorComponentObj>& complex2);\n\n  // ##########################################################################\n  // Returns all pseudo selectors in [compound] that have\n  // a selector argument, and that have the given [name].\n  // ##########################################################################\n  sass::vector<PseudoSelectorObj> selectorPseudoNamed(\n    CompoundSelectorObj compound, sass::string name)\n  {\n    sass::vector<PseudoSelectorObj> rv;\n    for (SimpleSelectorObj sel : compound->elements()) {\n      if (PseudoSelectorObj pseudo = Cast<PseudoSelector>(sel)) {\n        if (pseudo->isClass() && pseudo->selector()) {\n          if (sel->name() == name) {\n            rv.push_back(sel);\n          }\n        }\n      }\n    }\n    return rv;\n  }\n  // EO selectorPseudoNamed\n\n  // ##########################################################################\n  // Returns whether [simple1] is a superselector of [simple2].\n  // That is, whether [simple1] matches every element that\n  // [simple2] matches, as well as possibly additional elements.\n  // ##########################################################################\n  bool simpleIsSuperselector(\n    const SimpleSelectorObj& simple1,\n    const SimpleSelectorObj& simple2)\n  {\n    // If they are equal they are superselectors\n    if (ObjEqualityFn(simple1, simple2)) {\n      return true;\n    }\n    // Some selector pseudoclasses can match normal selectors.\n    if (const PseudoSelector* pseudo = Cast<PseudoSelector>(simple2)) {\n      if (pseudo->selector() && isSubselectorPseudo(pseudo->normalized())) {\n        for (auto complex : pseudo->selector()->elements()) {\n          // Make sure we have exacly one items\n          if (complex->length() != 1) {\n            return false;\n          }\n          // That items must be a compound selector\n          if (auto compound = Cast<CompoundSelector>(complex->at(0))) {\n            // It must contain the lhs simple selector\n            if (!compound->contains(simple1)) { \n              return false;\n            }\n          }\n        }\n        return true;\n      }\n    }\n    return false;\n  }\n  // EO simpleIsSuperselector\n\n  // ##########################################################################\n  // Returns whether [simple] is a superselector of [compound].\n  // That is, whether [simple] matches every element that\n  // [compound] matches, as well as possibly additional elements.\n  // ##########################################################################\n  bool simpleIsSuperselectorOfCompound(\n    const SimpleSelectorObj& simple,\n    const CompoundSelectorObj& compound)\n  {\n    for (SimpleSelectorObj simple2 : compound->elements()) {\n      if (simpleIsSuperselector(simple, simple2)) {\n        return true;\n      }\n    }\n    return false;\n  }\n  // EO simpleIsSuperselectorOfCompound\n\n  // ##########################################################################\n  // ##########################################################################\n  bool typeIsSuperselectorOfCompound(\n    const TypeSelectorObj& type,\n    const CompoundSelectorObj& compound)\n  {\n    for (const SimpleSelectorObj& simple : compound->elements()) {\n      if (const TypeSelectorObj& rhs = Cast<TypeSelector>(simple)) {\n        if (*type != *rhs) return true;\n      }\n    }\n    return false;\n  }\n  // EO typeIsSuperselectorOfCompound\n\n  // ##########################################################################\n  // ##########################################################################\n  bool idIsSuperselectorOfCompound(\n    const IDSelectorObj& id,\n    const CompoundSelectorObj& compound)\n  {\n    for (const SimpleSelectorObj& simple : compound->elements()) {\n      if (const IDSelectorObj& rhs = Cast<IDSelector>(simple)) {\n        if (*id != *rhs) return true;\n      }\n    }\n    return false;\n  }\n  // EO idIsSuperselectorOfCompound\n\n  // ##########################################################################\n  // ##########################################################################\n  bool pseudoIsSuperselectorOfPseudo(\n    const PseudoSelectorObj& pseudo1,\n    const PseudoSelectorObj& pseudo2,\n    const ComplexSelectorObj& parent\n  )\n  {\n    if (!pseudo2->selector()) return false;\n    if (pseudo1->name() == pseudo2->name()) {\n      SelectorListObj list = pseudo2->selector();\n      return listIsSuperslector(list->elements(), { parent });\n    }\n    return false;\n  }\n  // EO pseudoIsSuperselectorOfPseudo\n\n  // ##########################################################################\n  // ##########################################################################\n  bool pseudoNotIsSuperselectorOfCompound(\n    const PseudoSelectorObj& pseudo1,\n    const CompoundSelectorObj& compound2,\n    const ComplexSelectorObj& parent)\n  {\n    for (const SimpleSelectorObj& simple2 : compound2->elements()) {\n      if (const TypeSelectorObj& type2 = Cast<TypeSelector>(simple2)) {\n        if (const CompoundSelectorObj& compound1 = Cast<CompoundSelector>(parent->last())) {\n          if (typeIsSuperselectorOfCompound(type2, compound1)) return true;\n        }\n      }\n      else if (const IDSelectorObj& id2 = Cast<IDSelector>(simple2)) {\n        if (const CompoundSelectorObj& compound1 = Cast<CompoundSelector>(parent->last())) {\n          if (idIsSuperselectorOfCompound(id2, compound1)) return true;\n        }\n      }\n      else if (const PseudoSelectorObj& pseudo2 = Cast<PseudoSelector>(simple2)) {\n        if (pseudoIsSuperselectorOfPseudo(pseudo1, pseudo2, parent)) return true;\n      }\n    }\n    return false;\n  }\n  // pseudoNotIsSuperselectorOfCompound\n\n  // ##########################################################################\n  // Returns whether [pseudo1] is a superselector of [compound2].\n  // That is, whether [pseudo1] matches every element that [compound2]\n  // matches, as well as possibly additional elements. This assumes that\n  // [pseudo1]'s `selector` argument is not `null`. If [parents] is passed,\n  // it represents the parents of [compound2]. This is relevant for pseudo\n  // selectors with selector arguments, where we may need to know if the\n  // parent selectors in the selector argument match [parents].\n  // ##########################################################################\n  bool selectorPseudoIsSuperselector(\n    const PseudoSelectorObj& pseudo1,\n    const CompoundSelectorObj& compound2,\n    // ToDo: is this really the most convenient way to do this?\n    sass::vector<SelectorComponentObj>::const_iterator parents_from,\n    sass::vector<SelectorComponentObj>::const_iterator parents_to)\n  {\n\n    // ToDo: move normalization function\n    sass::string name(Util::unvendor(pseudo1->name()));\n\n    if (name == \"matches\" || name == \"any\") {\n      sass::vector<PseudoSelectorObj> pseudos =\n        selectorPseudoNamed(compound2, pseudo1->name());\n      SelectorListObj selector1 = pseudo1->selector();\n      for (PseudoSelectorObj pseudo2 : pseudos) {\n        SelectorListObj selector = pseudo2->selector();\n        if (selector1->isSuperselectorOf(selector)) {\n          return true;\n        }\n      }\n\n      for (ComplexSelectorObj complex1 : selector1->elements()) {\n        sass::vector<SelectorComponentObj> parents;\n        for (auto cur = parents_from; cur != parents_to; cur++) {\n          parents.push_back(*cur);\n        }\n        parents.push_back(compound2);\n        if (complexIsSuperselector(complex1->elements(), parents)) {\n          return true;\n        }\n      }\n\n    }\n    else if (name == \"has\" || name == \"host\" || name == \"host-context\" || name == \"slotted\") {\n      sass::vector<PseudoSelectorObj> pseudos =\n        selectorPseudoNamed(compound2, pseudo1->name());\n      SelectorListObj selector1 = pseudo1->selector();\n      for (PseudoSelectorObj pseudo2 : pseudos) {\n        SelectorListObj selector = pseudo2->selector();\n        if (selector1->isSuperselectorOf(selector)) {\n          return true;\n        }\n      }\n\n    }\n    else if (name == \"not\") {\n      for (ComplexSelectorObj complex : pseudo1->selector()->elements()) {\n        if (!pseudoNotIsSuperselectorOfCompound(pseudo1, compound2, complex)) return false;\n      }\n      return true;\n    }\n    else if (name == \"current\") {\n      sass::vector<PseudoSelectorObj> pseudos =\n        selectorPseudoNamed(compound2, \"current\");\n      for (PseudoSelectorObj pseudo2 : pseudos) {\n        if (ObjEqualityFn(pseudo1, pseudo2)) return true;\n      }\n\n    }\n    else if (name == \"nth-child\" || name == \"nth-last-child\") {\n      for (auto simple2 : compound2->elements()) {\n        if (PseudoSelectorObj pseudo2 = simple2->getPseudoSelector()) {\n          if (pseudo1->name() != pseudo2->name()) continue;\n          if (!ObjEqualityFn(pseudo1->argument(), pseudo2->argument())) continue;\n          if (pseudo1->selector()->isSuperselectorOf(pseudo2->selector())) return true;\n        }\n      }\n      return false;\n    }\n\n    return false;\n\n  }\n  // EO selectorPseudoIsSuperselector\n\n  // ##########################################################################\n  // Returns whether [compound1] is a superselector of [compound2].\n  // That is, whether [compound1] matches every element that [compound2]\n  // matches, as well as possibly additional elements. If [parents] is\n  // passed, it represents the parents of [compound2]. This is relevant\n  // for pseudo selectors with selector arguments, where we may need to\n  // know if the parent selectors in the selector argument match [parents].\n  // ##########################################################################\n  bool compoundIsSuperselector(\n    const CompoundSelectorObj& compound1,\n    const CompoundSelectorObj& compound2,\n    // ToDo: is this really the most convenient way to do this?\n    const sass::vector<SelectorComponentObj>::const_iterator parents_from,\n    const sass::vector<SelectorComponentObj>::const_iterator parents_to)\n  {\n    // Every selector in [compound1.components] must have\n    // a matching selector in [compound2.components].\n    for (SimpleSelectorObj simple1 : compound1->elements()) {\n      PseudoSelectorObj pseudo1 = Cast<PseudoSelector>(simple1);\n      if (pseudo1 && pseudo1->selector()) {\n        if (!selectorPseudoIsSuperselector(pseudo1, compound2, parents_from, parents_to)) {\n          return false;\n        }\n      }\n      else if (!simpleIsSuperselectorOfCompound(simple1, compound2)) {\n        return false;\n      }\n    }\n    // [compound1] can't be a superselector of a selector\n    // with pseudo-elements that [compound2] doesn't share.\n    for (SimpleSelectorObj simple2 : compound2->elements()) {\n      PseudoSelectorObj pseudo2 = Cast<PseudoSelector>(simple2);\n      if (pseudo2 && pseudo2->isElement()) {\n        if (!simpleIsSuperselectorOfCompound(pseudo2, compound1)) {\n          return false;\n        }\n      }\n    }\n    return true;\n  }\n  // EO compoundIsSuperselector\n\n  // ##########################################################################\n  // Returns whether [compound1] is a superselector of [compound2].\n  // That is, whether [compound1] matches every element that [compound2]\n  // matches, as well as possibly additional elements. If [parents] is\n  // passed, it represents the parents of [compound2]. This is relevant\n  // for pseudo selectors with selector arguments, where we may need to\n  // know if the parent selectors in the selector argument match [parents].\n  // ##########################################################################\n  bool compoundIsSuperselector(\n    const CompoundSelectorObj& compound1,\n    const CompoundSelectorObj& compound2,\n    const sass::vector<SelectorComponentObj>& parents)\n  {\n    return compoundIsSuperselector(\n      compound1, compound2,\n      parents.begin(), parents.end()\n    );\n  }\n  // EO compoundIsSuperselector\n\n  // ##########################################################################\n  // Returns whether [complex1] is a superselector of [complex2].\n  // That is, whether [complex1] matches every element that\n  // [complex2] matches, as well as possibly additional elements.\n  // ##########################################################################\n  bool complexIsSuperselector(\n    const sass::vector<SelectorComponentObj>& complex1,\n    const sass::vector<SelectorComponentObj>& complex2)\n  {\n\n    // Selectors with trailing operators are neither superselectors nor subselectors.\n    if (!complex1.empty() && Cast<SelectorCombinator>(complex1.back())) return false;\n    if (!complex2.empty() && Cast<SelectorCombinator>(complex2.back())) return false;\n\n    size_t i1 = 0, i2 = 0;\n    while (true) {\n\n      size_t remaining1 = complex1.size() - i1;\n      size_t remaining2 = complex2.size() - i2;\n\n      if (remaining1 == 0 || remaining2 == 0) {\n        return false;\n      }\n      // More complex selectors are never\n      // superselectors of less complex ones.\n      if (remaining1 > remaining2) {\n        return false;\n      }\n\n      // Selectors with leading operators are\n      // neither superselectors nor subselectors.\n      if (Cast<SelectorCombinator>(complex1[i1])) {\n        return false;\n      }\n      if (Cast<SelectorCombinator>(complex2[i2])) {\n        return false;\n      }\n\n      CompoundSelectorObj compound1 = Cast<CompoundSelector>(complex1[i1]);\n      CompoundSelectorObj compound2 = Cast<CompoundSelector>(complex2.back());\n\n      if (remaining1 == 1) {\n        sass::vector<SelectorComponentObj>::const_iterator parents_to = complex2.end();\n        sass::vector<SelectorComponentObj>::const_iterator parents_from = complex2.begin();\n        std::advance(parents_from, i2 + 1); // equivalent to dart `.skip(i2 + 1)`\n        bool rv = compoundIsSuperselector(compound1, compound2, parents_from, parents_to);\n        sass::vector<SelectorComponentObj> pp;\n\n        sass::vector<SelectorComponentObj>::const_iterator end = parents_to;\n        sass::vector<SelectorComponentObj>::const_iterator beg = parents_from;\n        while (beg != end) {\n          pp.push_back(*beg);\n          beg++;\n        }\n\n        return rv;\n      }\n\n      // Find the first index where `complex2.sublist(i2, afterSuperselector)`\n      // is a subselector of [compound1]. We stop before the superselector\n      // would encompass all of [complex2] because we know [complex1] has \n      // more than one element, and consuming all of [complex2] wouldn't \n      // leave anything for the rest of [complex1] to match.\n      size_t afterSuperselector = i2 + 1;\n      for (; afterSuperselector < complex2.size(); afterSuperselector++) {\n        SelectorComponentObj component2 = complex2[afterSuperselector - 1];\n        if (CompoundSelectorObj compound2 = Cast<CompoundSelector>(component2)) {\n          sass::vector<SelectorComponentObj>::const_iterator parents_to = complex2.begin();\n          sass::vector<SelectorComponentObj>::const_iterator parents_from = complex2.begin();\n          // complex2.take(afterSuperselector - 1).skip(i2 + 1)\n          std::advance(parents_from, i2 + 1); // equivalent to dart `.skip`\n          std::advance(parents_to, afterSuperselector); // equivalent to dart `.take`\n          if (compoundIsSuperselector(compound1, compound2, parents_from, parents_to)) {\n            break;\n          }\n        }\n      }\n      if (afterSuperselector == complex2.size()) {\n        return false;\n      }\n\n      SelectorComponentObj component1 = complex1[i1 + 1],\n        component2 = complex2[afterSuperselector];\n\n      SelectorCombinatorObj combinator1 = Cast<SelectorCombinator>(component1);\n      SelectorCombinatorObj combinator2 = Cast<SelectorCombinator>(component2);\n\n      if (!combinator1.isNull()) {\n\n        if (combinator2.isNull()) {\n          return false;\n        }\n        // `.a ~ .b` is a superselector of `.a + .b`,\n        // but otherwise the combinators must match.\n        if (combinator1->isGeneralCombinator()) {\n          if (combinator2->isChildCombinator()) {\n            return false;\n          }\n        }\n        else if (*combinator1 != *combinator2) {\n          return false;\n        }\n\n        // `.foo > .baz` is not a superselector of `.foo > .bar > .baz` or\n        // `.foo > .bar .baz`, despite the fact that `.baz` is a superselector of\n        // `.bar > .baz` and `.bar .baz`. Same goes for `+` and `~`.\n        if (remaining1 == 3 && remaining2 > 3) {\n          return false;\n        }\n\n        i1 += 2; i2 = afterSuperselector + 1;\n\n      }\n      else if (!combinator2.isNull()) {\n        if (!combinator2->isChildCombinator()) {\n          return false;\n        }\n        i1 += 1; i2 = afterSuperselector + 1;\n      }\n      else {\n        i1 += 1; i2 = afterSuperselector;\n      }\n    }\n\n    return false;\n\n  }\n  // EO complexIsSuperselector\n\n  // ##########################################################################\n  // Like [complexIsSuperselector], but compares [complex1]\n  // and [complex2] as though they shared an implicit base\n  // [SimpleSelector]. For example, `B` is not normally a\n  // superselector of `B A`, since it doesn't match elements\n  // that match `A`. However, it *is* a parent superselector,\n  // since `B X` is a superselector of `B A X`.\n  // ##########################################################################\n  bool complexIsParentSuperselector(\n    const sass::vector<SelectorComponentObj>& complex1,\n    const sass::vector<SelectorComponentObj>& complex2)\n  {\n    // Try some simple heuristics to see if we can avoid allocations.\n    if (complex1.empty() && complex2.empty()) return false;\n    if (Cast<SelectorCombinator>(complex1.front())) return false;\n    if (Cast<SelectorCombinator>(complex2.front())) return false;\n    if (complex1.size() > complex2.size()) return false;\n    // TODO(nweiz): There's got to be a way to do this without a bunch of extra allocations...\n    sass::vector<SelectorComponentObj> cplx1(complex1);\n    sass::vector<SelectorComponentObj> cplx2(complex2);\n    CompoundSelectorObj base = SASS_MEMORY_NEW(CompoundSelector, \"[tmp]\");\n    cplx1.push_back(base); cplx2.push_back(base);\n    return complexIsSuperselector(cplx1, cplx2);\n  }\n  // EO complexIsParentSuperselector\n\n  // ##########################################################################\n  // Returns whether [list] has a superselector for [complex].\n  // That is, whether an item in [list] matches every element that\n  // [complex] matches, as well as possibly additional elements.\n  // ##########################################################################\n  bool listHasSuperslectorForComplex(\n    sass::vector<ComplexSelectorObj> list,\n    ComplexSelectorObj complex)\n  {\n    // Return true if every [complex] selector on [list2]\n    // is a super selector of the full selector [list1].\n    for (ComplexSelectorObj lhs : list) {\n      if (complexIsSuperselector(lhs->elements(), complex->elements())) {\n        return true;\n      }\n    }\n    return false;\n  }\n  // listIsSuperslectorOfComplex\n\n  // ##########################################################################\n  // Returns whether [list1] is a superselector of [list2].\n  // That is, whether [list1] matches every element that\n  // [list2] matches, as well as possibly additional elements.\n  // ##########################################################################\n  bool listIsSuperslector(\n    const sass::vector<ComplexSelectorObj>& list1,\n    const sass::vector<ComplexSelectorObj>& list2)\n  {\n    // Return true if every [complex] selector on [list2]\n    // is a super selector of the full selector [list1].\n    for (ComplexSelectorObj complex : list2) {\n      if (!listHasSuperslectorForComplex(list1, complex)) {\n        return false;\n      }\n    }\n    return true;\n  }\n  // EO listIsSuperslector\n\n  // ##########################################################################\n  // Implement selector methods (dispatch to functions)\n  // ##########################################################################\n  bool SelectorList::isSuperselectorOf(const SelectorList* sub) const\n  {\n    return listIsSuperslector(elements(), sub->elements());\n  }\n  bool ComplexSelector::isSuperselectorOf(const ComplexSelector* sub) const\n  {\n    return complexIsSuperselector(elements(), sub->elements());\n  }\n\n  // ##########################################################################\n  // ##########################################################################\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_sel_unify.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  // ##########################################################################\n  // Returns the contents of a [SelectorList] that matches only \n  // elements that are matched by both [complex1] and [complex2].\n  // If no such list can be produced, returns `null`.\n  // ##########################################################################\n  // ToDo: fine-tune API to avoid unnecessary wrapper allocations\n  // ##########################################################################\n  sass::vector<sass::vector<SelectorComponentObj>> unifyComplex(\n    const sass::vector<sass::vector<SelectorComponentObj>>& complexes)\n  {\n\n    SASS_ASSERT(!complexes.empty(), \"Can't unify empty list\");\n    if (complexes.size() == 1) return complexes;\n\n    CompoundSelectorObj unifiedBase = SASS_MEMORY_NEW(CompoundSelector, SourceSpan(\"[unify]\"));\n    for (auto complex : complexes) {\n      SelectorComponentObj base = complex.back();\n      if (CompoundSelector * comp = base->getCompound()) {\n        if (unifiedBase->empty()) {\n          unifiedBase->concat(comp);\n        }\n        else {\n          for (SimpleSelectorObj simple : comp->elements()) {\n            unifiedBase = simple->unifyWith(unifiedBase);\n            if (unifiedBase.isNull()) return {};\n          }\n        }\n      }\n      else {\n        return {};\n      }\n    }\n\n    sass::vector<sass::vector<SelectorComponentObj>> complexesWithoutBases;\n    for (size_t i = 0; i < complexes.size(); i += 1) {\n      sass::vector<SelectorComponentObj> sel = complexes[i];\n      sel.pop_back(); // remove last item (base) from the list\n      complexesWithoutBases.push_back(std::move(sel));\n    }\n\n    complexesWithoutBases.back().push_back(unifiedBase);\n\n    return weave(complexesWithoutBases);\n\n  }\n  // EO unifyComplex\n\n  // ##########################################################################\n  // Returns a [CompoundSelector] that matches only elements\n  // that are matched by both [compound1] and [compound2].\n  // If no such selector can be produced, returns `null`.\n  // ##########################################################################\n  CompoundSelector* CompoundSelector::unifyWith(CompoundSelector* rhs)\n  {\n    if (empty()) return rhs;\n    CompoundSelectorObj unified = SASS_MEMORY_COPY(rhs);\n    for (const SimpleSelectorObj& sel : elements()) {\n      unified = sel->unifyWith(unified);\n      if (unified.isNull()) break;\n    }\n    return unified.detach();\n  }\n  // EO CompoundSelector::unifyWith(CompoundSelector*)\n\n  // ##########################################################################\n  // Returns the compoments of a [CompoundSelector] that matches only elements\n  // matched by both this and [compound]. By default, this just returns a copy\n  // of [compound] with this selector added to the end, or returns the original\n  // array if this selector already exists in it. Returns `null` if unification\n  // is impossible—for example, if there are multiple ID selectors.\n  // ##########################################################################\n  // This is implemented in `selector/simple.dart` as `SimpleSelector::unify`\n  // ##########################################################################\n  CompoundSelector* SimpleSelector::unifyWith(CompoundSelector* rhs)\n  {\n\n    if (rhs->length() == 1) {\n      if (rhs->get(0)->is_universal()) {\n        CompoundSelector* this_compound = SASS_MEMORY_NEW(CompoundSelector, pstate());\n        this_compound->append(SASS_MEMORY_COPY(this));\n        CompoundSelector* unified = rhs->get(0)->unifyWith(this_compound);\n        if (unified == nullptr || unified != this_compound) delete this_compound;\n        return unified;\n      }\n    }\n    for (const SimpleSelectorObj& sel : rhs->elements()) {\n      if (*this == *sel) {\n        return rhs;\n      }\n    }\n\n    CompoundSelectorObj result = SASS_MEMORY_NEW(CompoundSelector, rhs->pstate());\n\n    bool addedThis = false;\n    for (auto simple : rhs->elements()) {\n      // Make sure pseudo selectors always come last.\n      if (!addedThis && simple->getPseudoSelector()) {\n        result->append(this);\n        addedThis = true;\n      }\n      result->append(simple);\n    }\n\n    if (!addedThis) {\n      result->append(this);\n    }\n    return result.detach();\n\n  }\n  // EO SimpleSelector::unifyWith(CompoundSelector*)\n\n  // ##########################################################################\n  // This is implemented in `selector/type.dart` as `PseudoSelector::unify`\n  // ##########################################################################\n  CompoundSelector* TypeSelector::unifyWith(CompoundSelector* rhs)\n  {\n    if (rhs->empty()) {\n      rhs->append(this);\n      return rhs;\n    }\n    TypeSelector* type = Cast<TypeSelector>(rhs->at(0));\n    if (type != nullptr) {\n      SimpleSelector* unified = unifyWith(type);\n      if (unified == nullptr) {\n        return nullptr;\n      }\n      rhs->elements()[0] = unified;\n    }\n    else if (!is_universal() || (has_ns_ && ns_ != \"*\")) {\n      rhs->insert(rhs->begin(), this);\n    }\n    return rhs;\n  }\n\n  // ##########################################################################\n  // This is implemented in `selector/id.dart` as `PseudoSelector::unify`\n  // ##########################################################################\n  CompoundSelector* IDSelector::unifyWith(CompoundSelector* rhs)\n  {\n    for (const SimpleSelector* sel : rhs->elements()) {\n      if (const IDSelector* id_sel = Cast<IDSelector>(sel)) {\n        if (id_sel->name() != name()) return nullptr;\n      }\n    }\n    return SimpleSelector::unifyWith(rhs);\n  }\n\n  // ##########################################################################\n  // This is implemented in `selector/pseudo.dart` as `PseudoSelector::unify`\n  // ##########################################################################\n  CompoundSelector* PseudoSelector::unifyWith(CompoundSelector* compound)\n  {\n\n    if (compound->length() == 1 && compound->first()->is_universal()) {\n      // std::cerr << \"implement universal pseudo\\n\";\n    }\n\n    for (const SimpleSelectorObj& sel : compound->elements()) {\n      if (*this == *sel) {\n        return compound;\n      }\n    }\n\n    CompoundSelectorObj result = SASS_MEMORY_NEW(CompoundSelector, compound->pstate());\n\n    bool addedThis = false;\n    for (auto simple : compound->elements()) {\n      // Make sure pseudo selectors always come last.\n      if (PseudoSelectorObj pseudo = simple->getPseudoSelector()) {\n        if (pseudo->isElement()) {\n          // A given compound selector may only contain one pseudo element. If\n          // [compound] has a different one than [this], unification fails.\n          if (isElement()) {\n            return {};\n          }\n          // Otherwise, this is a pseudo selector and\n          // should come before pseduo elements.\n          result->append(this);\n          addedThis = true;\n        }\n      }\n      result->append(simple);\n    }\n\n    if (!addedThis) {\n      result->append(this);\n    }\n\n    return result.detach();\n\n  }\n  // EO PseudoSelector::unifyWith(CompoundSelector*\n\n  // ##########################################################################\n  // This is implemented in `extend/functions.dart` as `unifyUniversalAndElement`\n  // Returns a [SimpleSelector] that matches only elements that are matched by\n  // both [selector1] and [selector2], which must both be either [UniversalSelector]s\n  // or [TypeSelector]s. If no such selector can be produced, returns `null`.\n  // Note: libsass handles universal selector directly within the type selector\n  // ##########################################################################\n  SimpleSelector* TypeSelector::unifyWith(const SimpleSelector* rhs)\n  {\n    bool rhs_ns = false;\n    if (!(is_ns_eq(*rhs) || rhs->is_universal_ns())) {\n      if (!is_universal_ns()) {\n        return nullptr;\n      }\n      rhs_ns = true;\n    }\n    bool rhs_name = false;\n    if (!(name_ == rhs->name() || rhs->is_universal())) {\n      if (!(is_universal())) {\n        return nullptr;\n      }\n      rhs_name = true;\n    }\n    if (rhs_ns) {\n      ns(rhs->ns());\n      has_ns(rhs->has_ns());\n    }\n    if (rhs_name) name(rhs->name());\n    return this;\n  }\n  // EO TypeSelector::unifyWith(const SimpleSelector*)\n\n  // ##########################################################################\n  // Unify two complex selectors. Internally calls `unifyComplex`\n  // and then wraps the result in newly create ComplexSelectors.\n  // ##########################################################################\n  SelectorList* ComplexSelector::unifyWith(ComplexSelector* rhs)\n  {\n    SelectorListObj list = SASS_MEMORY_NEW(SelectorList, pstate());\n    sass::vector<sass::vector<SelectorComponentObj>> rv =\n       unifyComplex({ elements(), rhs->elements() });\n    for (sass::vector<SelectorComponentObj> items : rv) {\n      ComplexSelectorObj sel = SASS_MEMORY_NEW(ComplexSelector, pstate());\n      sel->elements() = std::move(items);\n      list->append(sel);\n    }\n    return list.detach();\n  }\n  // EO ComplexSelector::unifyWith(ComplexSelector*)\n\n  // ##########################################################################\n  // only called from the sass function `selector-unify`\n  // ##########################################################################\n  SelectorList* SelectorList::unifyWith(SelectorList* rhs)\n  {\n    SelectorList* slist = SASS_MEMORY_NEW(SelectorList, pstate());\n    // Unify all of children with RHS's children,\n    // storing the results in `unified_complex_selectors`\n    for (ComplexSelectorObj& seq1 : elements()) {\n      for (ComplexSelectorObj& seq2 : rhs->elements()) {\n        if (SelectorListObj unified = seq1->unifyWith(seq2)) {\n          std::move(unified->begin(), unified->end(),\n            std::inserter(slist->elements(), slist->end()));\n        }\n      }\n    }\n    return slist;\n  }\n  // EO SelectorList::unifyWith(SelectorList*)\n\n  // ##########################################################################\n  // ##########################################################################\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_sel_weave.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast.hpp\"\n#include \"permutate.hpp\"\n#include \"dart_helpers.hpp\"\n\nnamespace Sass {\n\n  // ##########################################################################\n  // Returns whether or not [compound] contains a `::root` selector.\n  // ##########################################################################\n  bool hasRoot(const CompoundSelector* compound)\n  {\n    // Libsass does not yet know the root selector\n    return false;\n  }\n  // EO hasRoot\n\n  // ##########################################################################\n  // Returns whether a [CompoundSelector] may contain only\n  // one simple selector of the same type as [simple].\n  // ##########################################################################\n  bool isUnique(const SimpleSelector* simple)\n  {\n    if (Cast<IDSelector>(simple)) return true;\n    if (const PseudoSelector * pseudo = Cast<PseudoSelector>(simple)) {\n      if (pseudo->is_pseudo_element()) return true;\n    }\n    return false;\n  }\n  // EO isUnique\n\n  // ##########################################################################\n  // Returns whether [complex1] and [complex2] need to be unified to\n  // produce a valid combined selector. This is necessary when both\n  // selectors contain the same unique simple selector, such as an ID.\n  // ##########################################################################\n  bool mustUnify(\n    const sass::vector<SelectorComponentObj>& complex1,\n    const sass::vector<SelectorComponentObj>& complex2)\n  {\n\n    sass::vector<const SimpleSelector*> uniqueSelectors1;\n    for (const SelectorComponent* component : complex1) {\n      if (const CompoundSelector * compound = component->getCompound()) {\n        for (const SimpleSelector* sel : compound->elements()) {\n          if (isUnique(sel)) {\n            uniqueSelectors1.push_back(sel);\n          }\n        }\n      }\n    }\n    if (uniqueSelectors1.empty()) return false;\n\n    // ToDo: unsure if this is correct\n    for (const SelectorComponent* component : complex2) {\n      if (const CompoundSelector * compound = component->getCompound()) {\n        for (const SimpleSelector* sel : compound->elements()) {\n          if (isUnique(sel)) {\n            for (auto check : uniqueSelectors1) {\n              if (*check == *sel) return true;\n            }\n          }\n        }\n      }\n    }\n\n    return false;\n\n  }\n  // EO isUnique\n\n  // ##########################################################################\n  // Helper function used by `weaveParents`\n  // ##########################################################################\n  bool cmpGroups(\n    const sass::vector<SelectorComponentObj>& group1,\n    const sass::vector<SelectorComponentObj>& group2,\n    sass::vector<SelectorComponentObj>& select)\n  {\n\n    if (group1.size() == group2.size() && std::equal(group1.begin(), group1.end(), group2.begin(), PtrObjEqualityFn<SelectorComponent>)) {\n      select = group1;\n      return true;\n    }\n\n    if (!Cast<CompoundSelector>(group1.front())) {\n      select = {};\n      return false;\n    }\n    if (!Cast<CompoundSelector>(group2.front())) {\n      select = {};\n      return false;\n    }\n\n    if (complexIsParentSuperselector(group1, group2)) {\n      select = group2;\n      return true;\n    }\n    if (complexIsParentSuperselector(group2, group1)) {\n      select = group1;\n      return true;\n    }\n\n    if (!mustUnify(group1, group2)) {\n      select = {};\n      return false;\n    }\n\n    sass::vector<sass::vector<SelectorComponentObj>> unified\n      = unifyComplex({ group1, group2 });\n    if (unified.empty()) return false;\n    if (unified.size() > 1) return false;\n    select = unified.front();\n    return true;\n  }\n  // EO cmpGroups\n\n  // ##########################################################################\n  // Helper function used by `weaveParents`\n  // ##########################################################################\n  template <class T>\n  bool checkForEmptyChild(const T& item) {\n    return item.empty();\n  }\n  // EO checkForEmptyChild\n\n  // ##########################################################################\n  // Helper function used by `weaveParents`\n  // ##########################################################################\n  bool cmpChunkForEmptySequence(\n    const sass::vector<sass::vector<SelectorComponentObj>>& seq,\n    const sass::vector<SelectorComponentObj>& group)\n  {\n    return seq.empty();\n  }\n  // EO cmpChunkForEmptySequence\n\n  // ##########################################################################\n  // Helper function used by `weaveParents`\n  // ##########################################################################\n  bool cmpChunkForParentSuperselector(\n    const sass::vector<sass::vector<SelectorComponentObj>>& seq,\n    const sass::vector<SelectorComponentObj>& group)\n  {\n    return seq.empty() || complexIsParentSuperselector(seq.front(), group);\n  }\n   // EO cmpChunkForParentSuperselector\n\n  // ##########################################################################\n  // Returns all orderings of initial subseqeuences of [queue1] and [queue2].\n  // The [done] callback is used to determine the extent of the initial\n  // subsequences. It's called with each queue until it returns `true`.\n  // Destructively removes the initial subsequences of [queue1] and [queue2].\n  // For example, given `(A B C | D E)` and `(1 2 | 3 4 5)` (with `|` denoting\n  // the boundary of the initial subsequence), this would return `[(A B C 1 2),\n  // (1 2 A B C)]`. The queues would then contain `(D E)` and `(3 4 5)`.\n  // ##########################################################################\n  template <class T>\n  sass::vector<sass::vector<T>> getChunks(\n    sass::vector<T>& queue1, sass::vector<T>& queue2,\n    const T& group, bool(*done)(const sass::vector<T>&, const T&)\n  ) {\n\n    sass::vector<T> chunk1;\n    while (!done(queue1, group)) {\n      chunk1.push_back(queue1.front());\n      queue1.erase(queue1.begin());\n    }\n\n    sass::vector<T> chunk2;\n    while (!done(queue2, group)) {\n      chunk2.push_back(queue2.front());\n      queue2.erase(queue2.begin());\n    }\n\n    if (chunk1.empty() && chunk2.empty()) return {};\n    else if (chunk1.empty()) return { chunk2 };\n    else if (chunk2.empty()) return { chunk1 };\n\n    sass::vector<T> choice1(chunk1), choice2(chunk2);\n    std::move(std::begin(chunk2), std::end(chunk2),\n      std::inserter(choice1, std::end(choice1)));\n    std::move(std::begin(chunk1), std::end(chunk1),\n      std::inserter(choice2, std::end(choice2)));\n    return { choice1, choice2 };\n  }\n  // EO getChunks\n\n  // ##########################################################################\n  // If the first element of [queue] has a `::root` \n  // selector, removes and returns that element.\n  // ##########################################################################\n  CompoundSelectorObj getFirstIfRoot(sass::vector<SelectorComponentObj>& queue) {\n    if (queue.empty()) return {};\n    SelectorComponent* first = queue.front();\n    if (CompoundSelector* sel = Cast<CompoundSelector>(first)) {\n      if (!hasRoot(sel)) return {};\n      queue.erase(queue.begin());\n      return sel;\n    }\n    return {};\n  }\n  // EO getFirstIfRoot\n\n  // ##########################################################################\n  // Returns [complex], grouped into sub-lists such that no sub-list\n  // contains two adjacent [ComplexSelector]s. For example,\n  // `(A B > C D + E ~ > G)` is grouped into `[(A) (B > C) (D + E ~ > G)]`.\n  // ##########################################################################\n  sass::vector<sass::vector<SelectorComponentObj>> groupSelectors(\n    const sass::vector<SelectorComponentObj>& components)\n  {\n    bool lastWasCompound = false;\n    sass::vector<SelectorComponentObj> group;\n    sass::vector<sass::vector<SelectorComponentObj>> groups;\n    for (size_t i = 0; i < components.size(); i += 1) {\n      if (CompoundSelector* compound = components[i]->getCompound()) {\n        if (lastWasCompound) {\n          groups.push_back(group);\n          group.clear();\n        }\n        group.push_back(compound);\n        lastWasCompound = true;\n      }\n      else if (SelectorCombinator* combinator = components[i]->getCombinator()) {\n        group.push_back(combinator);\n        lastWasCompound = false;\n      }\n    }\n    if (!group.empty()) {\n      groups.push_back(group);\n    }\n    return groups;\n  }\n  // EO groupSelectors\n\n  // ##########################################################################\n  // Extracts leading [Combinator]s from [components1] and [components2]\n  // and merges them together into a single list of combinators.\n  // If there are no combinators to be merged, returns an empty list.\n  // If the combinators can't be merged, returns `null`.\n  // ##########################################################################\n  bool mergeInitialCombinators(\n    sass::vector<SelectorComponentObj>& components1,\n    sass::vector<SelectorComponentObj>& components2,\n    sass::vector<SelectorComponentObj>& result)\n  {\n\n    sass::vector<SelectorComponentObj> combinators1;\n    while (!components1.empty() && Cast<SelectorCombinator>(components1.front())) {\n      SelectorCombinatorObj front = Cast<SelectorCombinator>(components1.front());\n      components1.erase(components1.begin());\n      combinators1.push_back(front);\n    }\n\n    sass::vector<SelectorComponentObj> combinators2;\n    while (!components2.empty() && Cast<SelectorCombinator>(components2.front())) {\n      SelectorCombinatorObj front = Cast<SelectorCombinator>(components2.front());\n      components2.erase(components2.begin());\n      combinators2.push_back(front);\n    }\n\n    // If neither sequence of combinators is a subsequence\n    // of the other, they cannot be merged successfully.\n    sass::vector<SelectorComponentObj> LCS = lcs<SelectorComponentObj>(combinators1, combinators2);\n\n    if (ListEquality(LCS, combinators1, PtrObjEqualityFn<SelectorComponent>)) {\n      result = combinators2;\n      return true;\n    }\n    if (ListEquality(LCS, combinators2, PtrObjEqualityFn<SelectorComponent>)) {\n      result = combinators1;\n      return true;\n    }\n\n    return false;\n\n  }\n  // EO mergeInitialCombinators\n\n  // ##########################################################################\n  // Extracts trailing [Combinator]s, and the selectors to which they apply,\n  // from [components1] and [components2] and merges them together into a\n  // single list. If there are no combinators to be merged, returns an\n  // empty list. If the sequences can't be merged, returns `null`.\n  // ##########################################################################\n  bool mergeFinalCombinators(\n    sass::vector<SelectorComponentObj>& components1,\n    sass::vector<SelectorComponentObj>& components2,\n    sass::vector<sass::vector<sass::vector<SelectorComponentObj>>>& result)\n  {\n\n    if (components1.empty() || !Cast<SelectorCombinator>(components1.back())) {\n      if (components2.empty() || !Cast<SelectorCombinator>(components2.back())) {\n        return true;\n      }\n    }\n    \n    sass::vector<SelectorComponentObj> combinators1;\n    while (!components1.empty() && Cast<SelectorCombinator>(components1.back())) {\n      SelectorCombinatorObj back = Cast<SelectorCombinator>(components1.back());\n      components1.erase(components1.end() - 1);\n      combinators1.push_back(back);\n    }\n\n    sass::vector<SelectorComponentObj> combinators2;\n    while (!components2.empty() && Cast<SelectorCombinator>(components2.back())) {\n      SelectorCombinatorObj back = Cast<SelectorCombinator>(components2.back());\n      components2.erase(components2.end() - 1);\n      combinators2.push_back(back);\n    }\n\n    // reverse now as we used push_back (faster than new alloc)\n    std::reverse(combinators1.begin(), combinators1.end());\n    std::reverse(combinators2.begin(), combinators2.end());\n\n    if (combinators1.size() > 1 || combinators2.size() > 1) {\n      // If there are multiple combinators, something hacky's going on. If one\n      // is a supersequence of the other, use that, otherwise give up.\n      auto LCS = lcs<SelectorComponentObj>(combinators1, combinators2);\n      if (ListEquality(LCS, combinators1, PtrObjEqualityFn<SelectorComponent>)) {\n        result.push_back({ combinators2 });\n      }\n      else if (ListEquality(LCS, combinators2, PtrObjEqualityFn<SelectorComponent>)) {\n        result.push_back({ combinators1 });\n      }\n      else {\n        return false;\n      }\n      return true;\n    }\n\n    // This code looks complicated, but it's actually just a bunch of special\n    // cases for interactions between different combinators.\n    SelectorCombinatorObj combinator1, combinator2;\n    if (!combinators1.empty()) combinator1 = combinators1.back();\n    if (!combinators2.empty()) combinator2 = combinators2.back();\n\n    if (!combinator1.isNull() && !combinator2.isNull()) {\n\n      CompoundSelector* compound1 = Cast<CompoundSelector>(components1.back());\n      CompoundSelector* compound2 = Cast<CompoundSelector>(components2.back());\n\n      components1.pop_back();\n      components2.pop_back();\n\n      if (combinator1->isGeneralCombinator() && combinator2->isGeneralCombinator()) {\n\n        if (compound1->isSuperselectorOf(compound2)) {\n          result.push_back({ { compound2, combinator2 } });\n        }\n        else if (compound2->isSuperselectorOf(compound1)) {\n          result.push_back({ { compound1, combinator1 } });\n        }\n        else {\n          sass::vector<sass::vector<SelectorComponentObj>> choices;\n          choices.push_back({ compound1, combinator1, compound2, combinator2 });\n          choices.push_back({ compound2, combinator2, compound1, combinator1 });\n          if (CompoundSelector* unified = compound1->unifyWith(compound2)) {\n            choices.push_back({ unified, combinator1 });\n          }\n          result.push_back(choices);\n        }\n      }\n      else if ((combinator1->isGeneralCombinator() && combinator2->isAdjacentCombinator()) ||\n        (combinator1->isAdjacentCombinator() && combinator2->isGeneralCombinator())) {\n\n        CompoundSelector* followingSiblingSelector = combinator1->isGeneralCombinator() ? compound1 : compound2;\n        CompoundSelector* nextSiblingSelector = combinator1->isGeneralCombinator() ? compound2 : compound1;\n        SelectorCombinator* followingSiblingCombinator = combinator1->isGeneralCombinator() ? combinator1 : combinator2;\n        SelectorCombinator* nextSiblingCombinator = combinator1->isGeneralCombinator() ? combinator2 : combinator1;\n\n        if (followingSiblingSelector->isSuperselectorOf(nextSiblingSelector)) {\n          result.push_back({ { nextSiblingSelector, nextSiblingCombinator } });\n        }\n        else {\n          CompoundSelectorObj unified = compound1->unifyWith(compound2);\n          sass::vector<sass::vector<SelectorComponentObj>> items;\n          \n          if (!unified.isNull()) {\n            items.push_back({\n              unified, nextSiblingCombinator\n            });\n          }\n\n          items.insert(items.begin(), {\n            followingSiblingSelector,\n            followingSiblingCombinator,\n            nextSiblingSelector,\n            nextSiblingCombinator,\n          });\n\n          result.push_back(items);\n        }\n\n      }\n      else if (combinator1->isChildCombinator() && (combinator2->isAdjacentCombinator() || combinator2->isGeneralCombinator())) {\n        result.push_back({ { compound2, combinator2 } });\n        components1.push_back(compound1);\n        components1.push_back(combinator1);\n      }\n      else if (combinator2->isChildCombinator() && (combinator1->isAdjacentCombinator() || combinator1->isGeneralCombinator())) {\n        result.push_back({ { compound1, combinator1 } });\n        components2.push_back(compound2);\n        components2.push_back(combinator2);\n      }\n      else if (*combinator1 == *combinator2) {\n        CompoundSelectorObj unified = compound1->unifyWith(compound2);\n        if (unified.isNull()) return false;\n        result.push_back({ { unified, combinator1 } });\n      }\n      else {\n        return false;\n      }\n\n      return mergeFinalCombinators(components1, components2, result);\n\n    }\n    else if (!combinator1.isNull()) {\n\n      if (combinator1->isChildCombinator() && !components2.empty()) {\n        const CompoundSelector* back1 = Cast<CompoundSelector>(components1.back());\n        const CompoundSelector* back2 = Cast<CompoundSelector>(components2.back());\n        if (back1 && back2 && back2->isSuperselectorOf(back1)) {\n          components2.pop_back();\n        }\n      }\n\n      result.push_back({ { components1.back(), combinator1 } });\n\n      components1.pop_back();\n\n      return mergeFinalCombinators(components1, components2, result);\n\n    }\n\n    if (combinator2->isChildCombinator() && !components1.empty()) {\n      const CompoundSelector* back1 = Cast<CompoundSelector>(components1.back());\n      const CompoundSelector* back2 = Cast<CompoundSelector>(components2.back());\n      if (back1 && back2 && back1->isSuperselectorOf(back2)) {\n        components1.pop_back();\n      }\n    }\n\n    result.push_back({ { components2.back(), combinator2 } });\n\n    components2.pop_back();\n\n    return mergeFinalCombinators(components1, components2, result);\n\n  }\n  // EO mergeFinalCombinators\n\n  // ##########################################################################\n  // Expands \"parenthesized selectors\" in [complexes]. That is, if\n  // we have `.A .B {@extend .C}` and `.D .C {...}`, this conceptually\n  // expands into `.D .C, .D (.A .B)`, and this function translates\n  // `.D (.A .B)` into `.D .A .B, .A .D .B`. For thoroughness, `.A.D .B`\n  // would also be required, but including merged selectors results in\n  // exponential output for very little gain. The selector `.D (.A .B)`\n  // is represented as the list `[[.D], [.A, .B]]`.\n  // ##########################################################################\n  sass::vector<sass::vector<SelectorComponentObj>> weave(\n    const sass::vector<sass::vector<SelectorComponentObj>>& complexes) {\n\n    sass::vector<sass::vector<SelectorComponentObj>> prefixes;\n\n    prefixes.push_back(complexes.at(0));\n\n    for (size_t i = 1; i < complexes.size(); i += 1) {\n\n      if (complexes[i].empty()) {\n        continue;\n      }\n      const sass::vector<SelectorComponentObj>& complex = complexes[i];\n      SelectorComponent* target = complex.back();\n      if (complex.size() == 1) {\n        for (auto& prefix : prefixes) {\n          prefix.push_back(target);\n        }\n        continue;\n      }\n\n      sass::vector<SelectorComponentObj> parents(complex);\n\n      parents.pop_back();\n\n      sass::vector<sass::vector<SelectorComponentObj>> newPrefixes;\n      for (sass::vector<SelectorComponentObj> prefix : prefixes) {\n        sass::vector<sass::vector<SelectorComponentObj>>\n          parentPrefixes = weaveParents(prefix, parents);\n        if (parentPrefixes.empty()) continue;\n        for (auto& parentPrefix : parentPrefixes) {\n          parentPrefix.push_back(target);\n          newPrefixes.push_back(parentPrefix);\n        }\n      }\n      prefixes = newPrefixes;\n\n    }\n    return prefixes;\n\n  }\n  // EO weave\n\n  // ##########################################################################\n  // Interweaves [parents1] and [parents2] as parents of the same target\n  // selector. Returns all possible orderings of the selectors in the\n  // inputs (including using unification) that maintain the relative\n  // ordering of the input. For example, given `.foo .bar` and `.baz .bang`,\n  // this would return `.foo .bar .baz .bang`, `.foo .bar.baz .bang`,\n  // `.foo .baz .bar .bang`, `.foo .baz .bar.bang`, `.foo .baz .bang .bar`,\n  // and so on until `.baz .bang .foo .bar`. Semantically, for selectors A\n  // and B, this returns all selectors `AB_i` such that the union over all i\n  // of elements matched by `AB_i X` is identical to the intersection of all\n  // elements matched by `A X` and all elements matched by `B X`. Some `AB_i`\n  // are elided to reduce the size of the output.\n  // ##########################################################################\n  sass::vector<sass::vector<SelectorComponentObj>> weaveParents(\n    sass::vector<SelectorComponentObj> queue1,\n    sass::vector<SelectorComponentObj> queue2)\n  {\n\n    sass::vector<SelectorComponentObj> leads;\n    sass::vector<sass::vector<sass::vector<SelectorComponentObj>>> trails;\n    if (!mergeInitialCombinators(queue1, queue2, leads)) return {};\n    if (!mergeFinalCombinators(queue1, queue2, trails)) return {};\n    // list comes out in reverse order for performance\n    std::reverse(trails.begin(), trails.end());\n\n    // Make sure there's at most one `:root` in the output.\n    // Note: does not yet do anything in libsass (no root selector)\n    CompoundSelectorObj root1 = getFirstIfRoot(queue1);\n    CompoundSelectorObj root2 = getFirstIfRoot(queue2);\n\n    if (!root1.isNull() && !root2.isNull()) {\n      CompoundSelectorObj root = root1->unifyWith(root2);\n      if (root.isNull()) return {}; // null\n      queue1.insert(queue1.begin(), root);\n      queue2.insert(queue2.begin(), root);\n    }\n    else if (!root1.isNull()) {\n      queue2.insert(queue2.begin(), root1);\n    }\n    else if (!root2.isNull()) {\n      queue1.insert(queue1.begin(), root2);\n    }\n\n    // group into sub-lists so no sub-list contains two adjacent ComplexSelectors.\n    sass::vector<sass::vector<SelectorComponentObj>> groups1 = groupSelectors(queue1);\n    sass::vector<sass::vector<SelectorComponentObj>> groups2 = groupSelectors(queue2);\n\n    // The main array to store our choices that will be permutated\n    sass::vector<sass::vector<sass::vector<SelectorComponentObj>>> choices;\n\n    // append initial combinators\n    choices.push_back({ leads });\n\n    sass::vector<sass::vector<SelectorComponentObj>> LCS =\n      lcs<sass::vector<SelectorComponentObj>>(groups1, groups2, cmpGroups);\n\n    for (auto group : LCS) {\n\n      // Create junks from groups1 and groups2\n      sass::vector<sass::vector<sass::vector<SelectorComponentObj>>>\n        chunks = getChunks<sass::vector<SelectorComponentObj>>(\n          groups1, groups2, group, cmpChunkForParentSuperselector);\n\n      // Create expanded array by flattening chunks2 inner\n      sass::vector<sass::vector<SelectorComponentObj>>\n        expanded = flattenInner(chunks);\n\n      // Prepare data structures\n      choices.push_back(expanded);\n      choices.push_back({ group });\n      if (!groups1.empty()) {\n        groups1.erase(groups1.begin());\n      }\n      if (!groups2.empty()) {\n        groups2.erase(groups2.begin());\n      }\n\n    }\n\n    // Create junks from groups1 and groups2\n    sass::vector<sass::vector<sass::vector<SelectorComponentObj>>>\n      chunks = getChunks<sass::vector<SelectorComponentObj>>(\n        groups1, groups2, {}, cmpChunkForEmptySequence);\n\n    // Append chunks with inner arrays flattened\n    choices.emplace_back(flattenInner(chunks));\n\n    // append all trailing selectors to choices\n    std::move(std::begin(trails), std::end(trails),\n      std::inserter(choices, std::end(choices)));\n\n    // move all non empty items to the front, then erase the trailing ones\n    choices.erase(std::remove_if(choices.begin(), choices.end(), checkForEmptyChild\n      <sass::vector<sass::vector<SelectorComponentObj>>>), choices.end());\n\n    // permutate all possible paths through selectors\n    sass::vector<sass::vector<SelectorComponentObj>>\n      results = flattenInner(permutate(choices));\n\n    return results;\n\n  }\n  // EO weaveParents\n\n  // ##########################################################################\n  // ##########################################################################\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_selectors.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast.hpp\"\n#include \"permutate.hpp\"\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Selector::Selector(SourceSpan pstate)\n  : Expression(pstate),\n    hash_(0)\n  { concrete_type(SELECTOR); }\n\n  Selector::Selector(const Selector* ptr)\n  : Expression(ptr),\n    hash_(ptr->hash_)\n  { concrete_type(SELECTOR); }\n\n\n  bool Selector::has_real_parent_ref() const\n  {\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Selector_Schema::Selector_Schema(SourceSpan pstate, String_Obj c)\n  : AST_Node(pstate),\n    contents_(c),\n    connect_parent_(true),\n    hash_(0)\n  { }\n  Selector_Schema::Selector_Schema(const Selector_Schema* ptr)\n  : AST_Node(ptr),\n    contents_(ptr->contents_),\n    connect_parent_(ptr->connect_parent_),\n    hash_(ptr->hash_)\n  { }\n\n  unsigned long Selector_Schema::specificity() const\n  {\n    return 0;\n  }\n\n  size_t Selector_Schema::hash() const {\n    if (hash_ == 0) {\n      hash_combine(hash_, contents_->hash());\n    }\n    return hash_;\n  }\n\n  bool Selector_Schema::has_real_parent_ref() const\n  {\n    // Note: disabled since it does not seem to do anything?\n    // if (String_Schema_Obj schema = Cast<String_Schema>(contents())) {\n    // if (schema->empty()) return false;\n    // const auto first = schema->first();\n    // return Cast<Parent_Reference>(first);\n    // }\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SimpleSelector::SimpleSelector(SourceSpan pstate, sass::string n)\n  : Selector(pstate), ns_(\"\"), name_(n), has_ns_(false)\n  {\n    size_t pos = n.find('|');\n    // found some namespace\n    if (pos != sass::string::npos) {\n      has_ns_ = true;\n      ns_ = n.substr(0, pos);\n      name_ = n.substr(pos + 1);\n    }\n  }\n  SimpleSelector::SimpleSelector(const SimpleSelector* ptr)\n  : Selector(ptr),\n    ns_(ptr->ns_),\n    name_(ptr->name_),\n    has_ns_(ptr->has_ns_)\n  { }\n\n  sass::string SimpleSelector::ns_name() const\n  {\n    if (!has_ns_) return name_;\n    else return ns_ + \"|\" + name_;\n  }\n\n  size_t SimpleSelector::hash() const\n  {\n    if (hash_ == 0) {\n      hash_combine(hash_, name());\n      hash_combine(hash_, (int)SELECTOR);\n      hash_combine(hash_, (int)simple_type());\n      if (has_ns_) hash_combine(hash_, ns());\n    }\n    return hash_;\n  }\n\n  bool SimpleSelector::empty() const {\n    return ns().empty() && name().empty();\n  }\n\n  // namespace compare functions\n  bool SimpleSelector::is_ns_eq(const SimpleSelector& r) const\n  {\n    return has_ns_ == r.has_ns_ && ns_ == r.ns_;\n  }\n\n  // namespace query functions\n  bool SimpleSelector::is_universal_ns() const\n  {\n    return has_ns_ && ns_ == \"*\";\n  }\n\n  bool SimpleSelector::is_empty_ns() const\n  {\n    return !has_ns_ || ns_ == \"\";\n  }\n\n  bool SimpleSelector::has_empty_ns() const\n  {\n    return has_ns_ && ns_ == \"\";\n  }\n\n  bool SimpleSelector::has_qualified_ns() const\n  {\n    return has_ns_ && ns_ != \"\" && ns_ != \"*\";\n  }\n\n  // name query functions\n  bool SimpleSelector::is_universal() const\n  {\n    return name_ == \"*\";\n  }\n\n  bool SimpleSelector::has_placeholder()\n  {\n    return false;\n  }\n\n  bool SimpleSelector::has_real_parent_ref() const\n  {\n    return false;\n  };\n\n  bool SimpleSelector::is_pseudo_element() const\n  {\n    return false;\n  }\n\n  CompoundSelectorObj SimpleSelector::wrapInCompound()\n  {\n    CompoundSelectorObj selector =\n      SASS_MEMORY_NEW(CompoundSelector, pstate());\n    selector->append(this);\n    return selector;\n  }\n  ComplexSelectorObj SimpleSelector::wrapInComplex()\n  {\n    ComplexSelectorObj selector =\n      SASS_MEMORY_NEW(ComplexSelector, pstate());\n    selector->append(wrapInCompound());\n    return selector;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  PlaceholderSelector::PlaceholderSelector(SourceSpan pstate, sass::string n)\n  : SimpleSelector(pstate, n)\n  { simple_type(PLACEHOLDER_SEL); }\n  PlaceholderSelector::PlaceholderSelector(const PlaceholderSelector* ptr)\n  : SimpleSelector(ptr)\n  { simple_type(PLACEHOLDER_SEL); }\n  unsigned long PlaceholderSelector::specificity() const\n  {\n    return Constants::Specificity_Base;\n  }\n  bool PlaceholderSelector::has_placeholder() {\n    return true;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  TypeSelector::TypeSelector(SourceSpan pstate, sass::string n)\n  : SimpleSelector(pstate, n)\n  { simple_type(TYPE_SEL); }\n  TypeSelector::TypeSelector(const TypeSelector* ptr)\n  : SimpleSelector(ptr)\n  { simple_type(TYPE_SEL); }\n\n  unsigned long TypeSelector::specificity() const\n  {\n    if (name() == \"*\") return 0;\n    else return Constants::Specificity_Element;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  ClassSelector::ClassSelector(SourceSpan pstate, sass::string n)\n  : SimpleSelector(pstate, n)\n  { simple_type(CLASS_SEL); }\n  ClassSelector::ClassSelector(const ClassSelector* ptr)\n  : SimpleSelector(ptr)\n  { simple_type(CLASS_SEL); }\n\n  unsigned long ClassSelector::specificity() const\n  {\n    return Constants::Specificity_Class;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  IDSelector::IDSelector(SourceSpan pstate, sass::string n)\n  : SimpleSelector(pstate, n)\n  { simple_type(ID_SEL); }\n  IDSelector::IDSelector(const IDSelector* ptr)\n  : SimpleSelector(ptr)\n  { simple_type(ID_SEL); }\n\n  unsigned long IDSelector::specificity() const\n  {\n    return Constants::Specificity_ID;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  AttributeSelector::AttributeSelector(SourceSpan pstate, sass::string n, sass::string m, String_Obj v, char o)\n  : SimpleSelector(pstate, n), matcher_(m), value_(v), modifier_(o)\n  { simple_type(ATTRIBUTE_SEL); }\n  AttributeSelector::AttributeSelector(const AttributeSelector* ptr)\n  : SimpleSelector(ptr),\n    matcher_(ptr->matcher_),\n    value_(ptr->value_),\n    modifier_(ptr->modifier_)\n  { simple_type(ATTRIBUTE_SEL); }\n\n  size_t AttributeSelector::hash() const\n  {\n    if (hash_ == 0) {\n      hash_combine(hash_, SimpleSelector::hash());\n      hash_combine(hash_, std::hash<sass::string>()(matcher()));\n      if (value_) hash_combine(hash_, value_->hash());\n    }\n    return hash_;\n  }\n\n  unsigned long AttributeSelector::specificity() const\n  {\n    return Constants::Specificity_Attr;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  PseudoSelector::PseudoSelector(SourceSpan pstate, sass::string name, bool element)\n  : SimpleSelector(pstate, name),\n    normalized_(Util::unvendor(name)),\n    argument_({}),\n    selector_({}),\n    isSyntacticClass_(!element),\n    isClass_(!element && !isFakePseudoElement(normalized_))\n  { simple_type(PSEUDO_SEL); }\n  PseudoSelector::PseudoSelector(const PseudoSelector* ptr)\n  : SimpleSelector(ptr),\n    normalized_(ptr->normalized()),\n    argument_(ptr->argument()),\n    selector_(ptr->selector()),\n    isSyntacticClass_(ptr->isSyntacticClass()),\n    isClass_(ptr->isClass())\n  { simple_type(PSEUDO_SEL); }\n\n  // A pseudo-element is made of two colons (::) followed by the name.\n  // The `::` notation is introduced by the current document in order to\n  // establish a discrimination between pseudo-classes and pseudo-elements.\n  // For compatibility with existing style sheets, user agents must also\n  // accept the previous one-colon notation for pseudo-elements introduced\n  // in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and\n  // :after). This compatibility is not allowed for the new pseudo-elements\n  // introduced in this specification.\n  bool PseudoSelector::is_pseudo_element() const\n  {\n    return isElement();\n  }\n\n  size_t PseudoSelector::hash() const\n  {\n    if (hash_ == 0) {\n      hash_combine(hash_, SimpleSelector::hash());\n      if (selector_) hash_combine(hash_, selector_->hash());\n      if (argument_) hash_combine(hash_, argument_->hash());\n    }\n    return hash_;\n  }\n\n  unsigned long PseudoSelector::specificity() const\n  {\n    if (is_pseudo_element())\n      return Constants::Specificity_Element;\n    return Constants::Specificity_Pseudo;\n  }\n\n  PseudoSelectorObj PseudoSelector::withSelector(SelectorListObj selector)\n  {\n    PseudoSelectorObj pseudo = SASS_MEMORY_COPY(this);\n    pseudo->selector(selector);\n    return pseudo;\n  }\n\n  bool PseudoSelector::empty() const\n  {\n    // Only considered empty if selector is\n    // available but has no items in it.\n    return selector() && selector()->empty();\n  }\n\n  void PseudoSelector::cloneChildren()\n  {\n    if (selector().isNull()) selector({});\n    else selector(SASS_MEMORY_CLONE(selector()));\n  }\n\n  bool PseudoSelector::has_real_parent_ref() const {\n    if (!selector()) return false;\n    return selector()->has_real_parent_ref();\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SelectorList::SelectorList(SourceSpan pstate, size_t s)\n  : Selector(pstate),\n    Vectorized<ComplexSelectorObj>(s),\n    is_optional_(false)\n  { }\n  SelectorList::SelectorList(const SelectorList* ptr)\n    : Selector(ptr),\n    Vectorized<ComplexSelectorObj>(*ptr),\n    is_optional_(ptr->is_optional_)\n  { }\n\n  size_t SelectorList::hash() const\n  {\n    if (Selector::hash_ == 0) {\n      hash_combine(Selector::hash_, Vectorized::hash());\n    }\n    return Selector::hash_;\n  }\n\n  bool SelectorList::has_real_parent_ref() const\n  {\n    for (ComplexSelectorObj s : elements()) {\n      if (s && s->has_real_parent_ref()) return true;\n    }\n    return false;\n  }\n\n  void SelectorList::cloneChildren()\n  {\n    for (size_t i = 0, l = length(); i < l; i++) {\n      at(i) = SASS_MEMORY_CLONE(at(i));\n    }\n  }\n\n  unsigned long SelectorList::specificity() const\n  {\n    return 0;\n  }\n\n  bool SelectorList::isInvisible() const\n  {\n    if (length() == 0) return true;\n    for (size_t i = 0; i < length(); i += 1) {\n      if (get(i)->isInvisible()) return true;\n    }\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  ComplexSelector::ComplexSelector(SourceSpan pstate)\n  : Selector(pstate),\n    Vectorized<SelectorComponentObj>(),\n    chroots_(false),\n    hasPreLineFeed_(false)\n  {\n  }\n  ComplexSelector::ComplexSelector(const ComplexSelector* ptr)\n  : Selector(ptr),\n    Vectorized<SelectorComponentObj>(ptr->elements()),\n    chroots_(ptr->chroots()),\n    hasPreLineFeed_(ptr->hasPreLineFeed())\n  {\n  }\n\n  void ComplexSelector::cloneChildren()\n  {\n    for (size_t i = 0, l = length(); i < l; i++) {\n      at(i) = SASS_MEMORY_CLONE(at(i));\n    }\n  }\n\n  unsigned long ComplexSelector::specificity() const\n  {\n    int sum = 0;\n    for (auto component : elements()) {\n      sum += component->specificity();\n    }\n    return sum;\n  }\n\n  bool ComplexSelector::isInvisible() const\n  {\n    if (length() == 0) return true;\n    for (size_t i = 0; i < length(); i += 1) {\n      if (CompoundSelectorObj compound = get(i)->getCompound()) {\n        if (compound->isInvisible()) return true;\n      }\n    }\n    return false;\n  }\n\n  bool ComplexSelector::isInvalidCss() const\n  {\n    for (size_t i = 0; i < length(); i += 1) {\n      if (CompoundSelectorObj compound = get(i)->getCompound()) {\n        if (compound->isInvalidCss()) return true;\n      }\n    }\n    return false;\n  }\n\n  SelectorListObj ComplexSelector::wrapInList()\n  {\n    SelectorListObj selector =\n      SASS_MEMORY_NEW(SelectorList, pstate());\n    selector->append(this);\n    return selector;\n  }\n\n  size_t ComplexSelector::hash() const\n  {\n    if (Selector::hash_ == 0) {\n      hash_combine(Selector::hash_, Vectorized::hash());\n      // ToDo: this breaks some extend lookup\n      // hash_combine(Selector::hash_, chroots_);\n    }\n    return Selector::hash_;\n  }\n\n  bool ComplexSelector::has_placeholder() const {\n    for (size_t i = 0, L = length(); i < L; ++i) {\n      if (get(i)->has_placeholder()) return true;\n    }\n    return false;\n  }\n\n  bool ComplexSelector::has_real_parent_ref() const\n  {\n    for (auto item : elements()) {\n      if (item->has_real_parent_ref()) return true;\n    }\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SelectorComponent::SelectorComponent(SourceSpan pstate, bool postLineBreak)\n  : Selector(pstate),\n    hasPostLineBreak_(postLineBreak)\n  {\n  }\n\n  SelectorComponent::SelectorComponent(const SelectorComponent* ptr)\n  : Selector(ptr),\n    hasPostLineBreak_(ptr->hasPostLineBreak())\n  { }\n\n  void SelectorComponent::cloneChildren()\n  {\n  }\n\n  unsigned long SelectorComponent::specificity() const\n  {\n    return 0;\n  }\n\n  // Wrap the compound selector with a complex selector\n  ComplexSelector* SelectorComponent::wrapInComplex()\n  {\n    auto complex = SASS_MEMORY_NEW(ComplexSelector, pstate());\n    complex->append(this);\n    return complex;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SelectorCombinator::SelectorCombinator(SourceSpan pstate, SelectorCombinator::Combinator combinator, bool postLineBreak)\n    : SelectorComponent(pstate, postLineBreak),\n    combinator_(combinator)\n  {\n  }\n  SelectorCombinator::SelectorCombinator(const SelectorCombinator* ptr)\n    : SelectorComponent(ptr->pstate(), false),\n      combinator_(ptr->combinator())\n  { }\n\n  void SelectorCombinator::cloneChildren()\n  {\n  }\n\n  unsigned long SelectorCombinator::specificity() const\n  {\n    return 0;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  CompoundSelector::CompoundSelector(SourceSpan pstate, bool postLineBreak)\n    : SelectorComponent(pstate, postLineBreak),\n      Vectorized<SimpleSelectorObj>(),\n      hasRealParent_(false)\n  {\n  }\n  CompoundSelector::CompoundSelector(const CompoundSelector* ptr)\n    : SelectorComponent(ptr),\n      Vectorized<SimpleSelectorObj>(*ptr),\n      hasRealParent_(ptr->hasRealParent())\n  { }\n\n  size_t CompoundSelector::hash() const\n  {\n    if (Selector::hash_ == 0) {\n      hash_combine(Selector::hash_, Vectorized::hash());\n      hash_combine(Selector::hash_, hasRealParent_);\n    }\n    return Selector::hash_;\n  }\n\n  bool CompoundSelector::has_real_parent_ref() const\n  {\n    if (hasRealParent()) return true;\n    // ToDo: dart sass has another check?\n    // if (Cast<TypeSelector>(front)) {\n    //  if (front->ns() != \"\") return false;\n    // }\n    for (const SimpleSelector* s : elements()) {\n      if (s && s->has_real_parent_ref()) return true;\n    }\n    return false;\n  }\n\n  bool CompoundSelector::has_placeholder() const\n  {\n    if (length() == 0) return false;\n    for (SimpleSelectorObj ss : elements()) {\n      if (ss->has_placeholder()) return true;\n    }\n    return false;\n  }\n\n  void CompoundSelector::cloneChildren()\n  {\n    for (size_t i = 0, l = length(); i < l; i++) {\n      at(i) = SASS_MEMORY_CLONE(at(i));\n    }\n  }\n\n  unsigned long CompoundSelector::specificity() const\n  {\n    int sum = 0;\n    for (size_t i = 0, L = length(); i < L; ++i)\n    { sum += get(i)->specificity(); }\n    return sum;\n  }\n\n  bool CompoundSelector::isInvisible() const\n  {\n    for (size_t i = 0; i < length(); i += 1) {\n      if (!get(i)->isInvisible()) return false;\n    }\n    return true;\n  }\n\n  bool CompoundSelector::isSuperselectorOf(const CompoundSelector* sub, sass::string wrapped) const\n  {\n    CompoundSelector* rhs2 = const_cast<CompoundSelector*>(sub);\n    CompoundSelector* lhs2 = const_cast<CompoundSelector*>(this);\n    return compoundIsSuperselector(lhs2, rhs2, {});\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  MediaRule::MediaRule(SourceSpan pstate, Block_Obj block) :\n    ParentStatement(pstate, block),\n    schema_({})\n  {\n    statement_type(MEDIA);\n  }\n\n  MediaRule::MediaRule(const MediaRule* ptr) :\n    ParentStatement(ptr),\n    schema_(ptr->schema_)\n  {\n    statement_type(MEDIA);\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  CssMediaRule::CssMediaRule(SourceSpan pstate, Block_Obj block) :\n    ParentStatement(pstate, block),\n    Vectorized()\n  {\n    statement_type(MEDIA);\n  }\n\n  CssMediaRule::CssMediaRule(const CssMediaRule* ptr) :\n    ParentStatement(ptr),\n    Vectorized(*ptr)\n  {\n    statement_type(MEDIA);\n  }\n\n  CssMediaQuery::CssMediaQuery(SourceSpan pstate) :\n    AST_Node(pstate),\n    modifier_(\"\"),\n    type_(\"\"),\n    features_()\n  {\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  bool CssMediaQuery::operator==(const CssMediaQuery& rhs) const\n  {\n    return type_ == rhs.type_\n      && modifier_ == rhs.modifier_\n      && features_ == rhs.features_;\n  }\n\n  // Implemented after dart-sass (maybe move to other class?)\n  CssMediaQuery_Obj CssMediaQuery::merge(CssMediaQuery_Obj& other)\n  {\n\n    sass::string ourType = this->type();\n    Util::ascii_str_tolower(&ourType);\n\n    sass::string theirType = other->type();\n    Util::ascii_str_tolower(&theirType);\n\n    sass::string ourModifier = this->modifier();\n    Util::ascii_str_tolower(&ourModifier);\n\n    sass::string theirModifier = other->modifier();\n    Util::ascii_str_tolower(&theirModifier);\n\n    sass::string type;\n    sass::string modifier;\n    sass::vector<sass::string> features;\n\n    if (ourType.empty() && theirType.empty()) {\n      CssMediaQuery_Obj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());\n      sass::vector<sass::string> f1(this->features());\n      sass::vector<sass::string> f2(other->features());\n      features.insert(features.end(), f1.begin(), f1.end());\n      features.insert(features.end(), f2.begin(), f2.end());\n      query->features(features);\n      return query;\n    }\n\n    if ((ourModifier == \"not\") != (theirModifier == \"not\")) {\n      if (ourType == theirType) {\n        sass::vector<sass::string> negativeFeatures =\n          ourModifier == \"not\" ? this->features() : other->features();\n        sass::vector<sass::string> positiveFeatures =\n          ourModifier == \"not\" ? other->features() : this->features();\n\n        // If the negative features are a subset of the positive features, the\n        // query is empty. For example, `not screen and (color)` has no\n        // intersection with `screen and (color) and (grid)`.\n        // However, `not screen and (color)` *does* intersect with `screen and\n        // (grid)`, because it means `not (screen and (color))` and so it allows\n        // a screen with no color but with a grid.\n        if (listIsSubsetOrEqual(negativeFeatures, positiveFeatures)) {\n          return SASS_MEMORY_NEW(CssMediaQuery, pstate());\n        }\n        else {\n          return {};\n        }\n      }\n      else if (this->matchesAllTypes() || other->matchesAllTypes()) {\n        return {};\n      }\n\n      if (ourModifier == \"not\") {\n        modifier = theirModifier;\n        type = theirType;\n        features = other->features();\n      }\n      else {\n        modifier = ourModifier;\n        type = ourType;\n        features = this->features();\n      }\n    }\n    else if (ourModifier == \"not\") {\n      SASS_ASSERT(theirModifier == \"not\", \"modifiers not is sync\");\n\n      // CSS has no way of representing \"neither screen nor print\".\n      if (ourType != theirType) return {};\n\n      auto moreFeatures = this->features().size() > other->features().size()\n        ? this->features()\n        : other->features();\n      auto fewerFeatures = this->features().size() > other->features().size()\n        ? other->features()\n        : this->features();\n\n      // If one set of features is a superset of the other,\n      // use those features because they're strictly narrower.\n      if (listIsSubsetOrEqual(fewerFeatures, moreFeatures)) {\n        modifier = ourModifier; // \"not\"\n        type = ourType;\n        features = moreFeatures;\n      }\n      else {\n        // Otherwise, there's no way to\n        // represent the intersection.\n        return {};\n      }\n\n    }\n    else {\n      if (this->matchesAllTypes()) {\n        modifier = theirModifier;\n        // Omit the type if either input query did, since that indicates that they\n        // aren't targeting a browser that requires \"all and\".\n        type = (other->matchesAllTypes() && ourType.empty()) ? \"\" : theirType;\n        sass::vector<sass::string> f1(this->features());\n        sass::vector<sass::string> f2(other->features());\n        features.insert(features.end(), f1.begin(), f1.end());\n        features.insert(features.end(), f2.begin(), f2.end());\n      }\n      else if (other->matchesAllTypes()) {\n        modifier = ourModifier;\n        type = ourType;\n        sass::vector<sass::string> f1(this->features());\n        sass::vector<sass::string> f2(other->features());\n        features.insert(features.end(), f1.begin(), f1.end());\n        features.insert(features.end(), f2.begin(), f2.end());\n      }\n      else if (ourType != theirType) {\n        return SASS_MEMORY_NEW(CssMediaQuery, pstate());\n      }\n      else {\n        modifier = ourModifier.empty() ? theirModifier : ourModifier;\n        type = ourType;\n        sass::vector<sass::string> f1(this->features());\n        sass::vector<sass::string> f2(other->features());\n        features.insert(features.end(), f1.begin(), f1.end());\n        features.insert(features.end(), f2.begin(), f2.end());\n      }\n    }\n\n    CssMediaQuery_Obj query = SASS_MEMORY_NEW(CssMediaQuery, pstate());\n    query->modifier(modifier == ourModifier ? this->modifier() : other->modifier());\n    query->type(ourType.empty() ? other->type() : this->type());\n    query->features(features);\n    return query;\n  }\n\n  CssMediaQuery::CssMediaQuery(const CssMediaQuery* ptr) :\n    AST_Node(*ptr),\n    modifier_(ptr->modifier_),\n    type_(ptr->type_),\n    features_(ptr->features_)\n  {\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  // ToDo: finalize specificity implementation\n  /////////////////////////////////////////////////////////////////////////\n\n  size_t SelectorList::maxSpecificity() const\n  {\n    size_t specificity = 0;\n    for (auto complex : elements()) {\n      specificity = std::max(specificity, complex->maxSpecificity());\n    }\n    return specificity;\n  }\n\n  size_t SelectorList::minSpecificity() const\n  {\n    size_t specificity = 0;\n    for (auto complex : elements()) {\n      specificity = std::min(specificity, complex->minSpecificity());\n    }\n    return specificity;\n  }\n\n  size_t CompoundSelector::maxSpecificity() const\n  {\n    size_t specificity = 0;\n    for (auto simple : elements()) {\n      specificity += simple->maxSpecificity();\n    }\n    return specificity;\n  }\n\n  size_t CompoundSelector::minSpecificity() const\n  {\n    size_t specificity = 0;\n    for (auto simple : elements()) {\n      specificity += simple->minSpecificity();\n    }\n    return specificity;\n  }\n\n  size_t ComplexSelector::maxSpecificity() const\n  {\n    size_t specificity = 0;\n    for (auto component : elements()) {\n      specificity += component->maxSpecificity();\n    }\n    return specificity;\n  }\n\n  size_t ComplexSelector::minSpecificity() const\n  {\n    size_t specificity = 0;\n    for (auto component : elements()) {\n      specificity += component->minSpecificity();\n    }\n    return specificity;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  // ToDo: this might be done easier with new selector format\n  /////////////////////////////////////////////////////////////////////////\n\n  sass::vector<ComplexSelectorObj>\n    CompoundSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)\n  {\n\n    auto parent = pstack.back();\n    sass::vector<ComplexSelectorObj> rv;\n\n    for (SimpleSelectorObj simple : elements()) {\n      if (PseudoSelector * pseudo = Cast<PseudoSelector>(simple)) {\n        if (SelectorList* sel = Cast<SelectorList>(pseudo->selector())) {\n          if (parent) {\n            pseudo->selector(sel->resolve_parent_refs(\n              pstack, traces, implicit_parent));\n          }\n        }\n      }\n    }\n\n    // Mix with parents from stack\n    if (hasRealParent()) {\n\n      if (parent.isNull()) {\n        return { wrapInComplex() };\n      }\n      else {\n        for (auto complex : parent->elements()) {\n          // The parent complex selector has a compound selector\n          if (CompoundSelectorObj tail = Cast<CompoundSelector>(complex->last())) {\n            // Create a copy to alter it\n            complex = SASS_MEMORY_COPY(complex);\n            tail = SASS_MEMORY_COPY(tail);\n\n            // Check if we can merge front with back\n            if (length() > 0 && tail->length() > 0) {\n              SimpleSelectorObj back = tail->last();\n              SimpleSelectorObj front = first();\n              auto simple_back = Cast<SimpleSelector>(back);\n              auto simple_front = Cast<TypeSelector>(front);\n              if (simple_front && simple_back) {\n                simple_back = SASS_MEMORY_COPY(simple_back);\n                auto name = simple_back->name();\n                name += simple_front->name();\n                simple_back->name(name);\n                tail->elements().back() = simple_back;\n                tail->elements().insert(tail->end(),\n                  begin() + 1, end());\n              }\n              else {\n                tail->concat(this);\n              }\n            }\n            else {\n              tail->concat(this);\n            }\n\n            complex->elements().back() = tail;\n            // Append to results\n            rv.push_back(complex);\n          }\n          else {\n            // Can't insert parent that ends with a combinator\n            // where the parent selector is followed by something\n            if (parent && length() > 0) {\n              throw Exception::InvalidParent(parent, traces, this);\n            }\n            // Create a copy to alter it\n            complex = SASS_MEMORY_COPY(complex);\n            // Just append ourself\n            complex->append(this);\n            // Append to results\n            rv.push_back(complex);\n          }\n        }\n      }\n    }\n\n    // No parents\n    else {\n      // Create a new wrapper to wrap ourself\n      auto complex = SASS_MEMORY_NEW(ComplexSelector, pstate());\n      // Just append ourself\n      complex->append(this);\n      // Append to results\n      rv.push_back(complex);\n    }\n\n    return rv;\n\n  }\n\n  bool cmpSimpleSelectors(SimpleSelector* a, SimpleSelector* b)\n  {\n    return (a->getSortOrder() < b->getSortOrder());\n  }\n\n  void CompoundSelector::sortChildren()\n  {\n    std::sort(begin(), end(), cmpSimpleSelectors);\n  }\n\n  bool CompoundSelector::isInvalidCss() const\n  {\n    size_t current = 0, next = 0;\n    for (const SimpleSelector* sel : elements()) {\n      next = sel->getSortOrder();\n      // Must only have one type selector\n      if (current == 1 && next == 1) {\n        return true;\n      }\n      if (next < current) {\n        return true;\n      }\n      current = next;\n    }\n    return false;\n  }\n\n  /* better return sass::vector? only - is empty container anyway? */\n  SelectorList* ComplexSelector::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)\n  {\n\n    sass::vector<sass::vector<ComplexSelectorObj>> vars;\n\n    auto parent = pstack.back();\n\n    if (has_real_parent_ref() && !parent) {\n      throw Exception::TopLevelParent(traces, pstate());\n    }\n\n    if (!chroots() && parent) {\n\n      if (!has_real_parent_ref() && !implicit_parent) {\n        SelectorList* retval = SASS_MEMORY_NEW(SelectorList, pstate(), 1);\n        retval->append(this);\n        return retval;\n      }\n\n      vars.push_back(parent->elements());\n    }\n\n    for (auto sel : elements()) {\n      if (CompoundSelectorObj comp = Cast<CompoundSelector>(sel)) {\n        auto asd = comp->resolve_parent_refs(pstack, traces, implicit_parent);\n        if (asd.size() > 0) vars.push_back(asd);\n      }\n      else {\n        // ToDo: merge together sequences whenever possible\n        auto cont = SASS_MEMORY_NEW(ComplexSelector, pstate());\n        cont->append(sel);\n        vars.push_back({ cont });\n      }\n    }\n\n    // Need complex selectors to preserve linefeeds\n    sass::vector<sass::vector<ComplexSelectorObj>> res = permutateAlt(vars);\n\n    // std::reverse(std::begin(res), std::end(res));\n\n    auto lst = SASS_MEMORY_NEW(SelectorList, pstate());\n    for (auto items : res) {\n      if (items.size() > 0) {\n        ComplexSelectorObj first = SASS_MEMORY_COPY(items[0]);\n        first->hasPreLineFeed(first->hasPreLineFeed() || (!has_real_parent_ref() && hasPreLineFeed()));\n        // ToDo: remove once we know how to handle line feeds\n        // ToDo: currently a mashup between ruby and dart sass\n        // if (has_real_parent_ref()) first->has_line_feed(false);\n        // first->has_line_break(first->has_line_break() || has_line_break());\n        first->chroots(true); // has been resolved by now\n        for (size_t i = 1; i < items.size(); i += 1) {\n          first->concat(items[i]);\n        }\n        lst->append(first);\n      }\n    }\n\n    return lst;\n\n  }\n\n  SelectorList* SelectorList::resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent)\n  {\n    SelectorList* rv = SASS_MEMORY_NEW(SelectorList, pstate());\n    for (auto sel : elements()) {\n      // Note: this one is tricky as we get back a pointer from resolve parents ...\n      SelectorListObj res = sel->resolve_parent_refs(pstack, traces, implicit_parent);\n      // Note: ... and concat will only append the items in elements\n      // Therefore by passing it directly, the container will leak!\n      rv->concat(res);\n    }\n    return rv;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  IMPLEMENT_AST_OPERATORS(Selector_Schema);\n  IMPLEMENT_AST_OPERATORS(PlaceholderSelector);\n  IMPLEMENT_AST_OPERATORS(AttributeSelector);\n  IMPLEMENT_AST_OPERATORS(TypeSelector);\n  IMPLEMENT_AST_OPERATORS(ClassSelector);\n  IMPLEMENT_AST_OPERATORS(IDSelector);\n  IMPLEMENT_AST_OPERATORS(PseudoSelector);\n  IMPLEMENT_AST_OPERATORS(SelectorCombinator);\n  IMPLEMENT_AST_OPERATORS(CompoundSelector);\n  IMPLEMENT_AST_OPERATORS(ComplexSelector);\n  IMPLEMENT_AST_OPERATORS(SelectorList);\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_selectors.hpp",
    "content": "#ifndef SASS_AST_SEL_H\n#define SASS_AST_SEL_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  /////////////////////////////////////////////////////////////////////////\n  // Some helper functions\n  /////////////////////////////////////////////////////////////////////////\n\n  bool compoundIsSuperselector(\n    const CompoundSelectorObj& compound1,\n    const CompoundSelectorObj& compound2,\n    const sass::vector<SelectorComponentObj>& parents);\n\n  bool complexIsParentSuperselector(\n    const sass::vector<SelectorComponentObj>& complex1,\n    const sass::vector<SelectorComponentObj>& complex2);\n\n    sass::vector<sass::vector<SelectorComponentObj>> weave(\n    const sass::vector<sass::vector<SelectorComponentObj>>& complexes);\n\n  sass::vector<sass::vector<SelectorComponentObj>> weaveParents(\n    sass::vector<SelectorComponentObj> parents1,\n    sass::vector<SelectorComponentObj> parents2);\n\n  sass::vector<SimpleSelectorObj> unifyCompound(\n    const sass::vector<SimpleSelectorObj>& compound1,\n    const sass::vector<SimpleSelectorObj>& compound2);\n\n  sass::vector<sass::vector<SelectorComponentObj>> unifyComplex(\n    const sass::vector<sass::vector<SelectorComponentObj>>& complexes);\n\n  /////////////////////////////////////////\n  // Abstract base class for CSS selectors.\n  /////////////////////////////////////////\n  class Selector : public Expression {\n  protected:\n    mutable size_t hash_;\n  public:\n    Selector(SourceSpan pstate);\n    virtual ~Selector() = 0;\n    size_t hash() const override = 0;\n    virtual bool has_real_parent_ref() const;\n    // you should reset this to null on containers\n    virtual unsigned long specificity() const = 0;\n    // by default we return the regular specificity\n    // you must override this for all containers\n    virtual size_t maxSpecificity() const { return specificity(); }\n    virtual size_t minSpecificity() const { return specificity(); }\n    // dispatch to correct handlers\n    ATTACH_VIRTUAL_CMP_OPERATIONS(Selector)\n    ATTACH_VIRTUAL_AST_OPERATIONS(Selector)\n  };\n  inline Selector::~Selector() { }\n\n  /////////////////////////////////////////////////////////////////////////\n  // Interpolated selectors -- the interpolated String will be expanded and\n  // re-parsed into a normal selector class.\n  /////////////////////////////////////////////////////////////////////////\n  class Selector_Schema final : public AST_Node {\n    ADD_PROPERTY(String_Schema_Obj, contents)\n    ADD_PROPERTY(bool, connect_parent);\n    // store computed hash\n    mutable size_t hash_;\n  public:\n    Selector_Schema(SourceSpan pstate, String_Obj c);\n\n    bool has_real_parent_ref() const;\n    // selector schema is not yet a final selector, so we do not\n    // have a specificity for it yet. We need to\n    virtual unsigned long specificity() const;\n    size_t hash() const override;\n    ATTACH_AST_OPERATIONS(Selector_Schema)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////\n  // Abstract base class for simple selectors.\n  ////////////////////////////////////////////\n  class SimpleSelector : public Selector {\n  public:\n    enum Simple_Type {\n      ID_SEL,\n      TYPE_SEL,\n      CLASS_SEL,\n      PSEUDO_SEL,\n      ATTRIBUTE_SEL,\n      PLACEHOLDER_SEL,\n    };\n  public:\n    HASH_CONSTREF(sass::string, ns)\n    HASH_CONSTREF(sass::string, name)\n    ADD_PROPERTY(Simple_Type, simple_type)\n    HASH_PROPERTY(bool, has_ns)\n  public:\n    SimpleSelector(SourceSpan pstate, sass::string n = \"\");\n    // ordering within parent (peudos go last)\n    virtual int getSortOrder() const = 0;\n    virtual sass::string ns_name() const;\n    size_t hash() const override;\n    virtual bool empty() const;\n    // namespace compare functions\n    bool is_ns_eq(const SimpleSelector& r) const;\n    // namespace query functions\n    bool is_universal_ns() const;\n    bool is_empty_ns() const;\n    bool has_empty_ns() const;\n    bool has_qualified_ns() const;\n    // name query functions\n    bool is_universal() const;\n    virtual bool has_placeholder();\n\n    virtual ~SimpleSelector() = 0;\n    virtual CompoundSelector* unifyWith(CompoundSelector*);\n\n    /* helper function for syntax sugar */\n    virtual IDSelector* getIdSelector() { return NULL; }\n    virtual TypeSelector* getTypeSelector() { return NULL; }\n    virtual PseudoSelector* getPseudoSelector() { return NULL; }\n\n    ComplexSelectorObj wrapInComplex();\n    CompoundSelectorObj wrapInCompound();\n\n    virtual bool isInvisible() const { return false; }\n    virtual bool is_pseudo_element() const;\n    virtual bool has_real_parent_ref() const override;\n\n    bool operator==(const Selector& rhs) const final override;\n\n    virtual bool operator==(const SelectorList& rhs) const;\n    virtual bool operator==(const ComplexSelector& rhs) const;\n    virtual bool operator==(const CompoundSelector& rhs) const;\n\n    ATTACH_VIRTUAL_CMP_OPERATIONS(SimpleSelector);\n    ATTACH_VIRTUAL_AST_OPERATIONS(SimpleSelector);\n    ATTACH_CRTP_PERFORM_METHODS();\n\n  };\n  inline SimpleSelector::~SimpleSelector() { }\n\n  /////////////////////////////////////////////////////////////////////////\n  // Placeholder selectors (e.g., \"%foo\") for use in extend-only selectors.\n  /////////////////////////////////////////////////////////////////////////\n  class PlaceholderSelector final : public SimpleSelector {\n  public:\n    PlaceholderSelector(SourceSpan pstate, sass::string n);\n    int getSortOrder() const override final { return 0; }\n    bool isInvisible() const override { return true; }\n    virtual unsigned long specificity() const override;\n    virtual bool has_placeholder() override;\n    bool operator==(const SimpleSelector& rhs) const override;\n    ATTACH_CMP_OPERATIONS(PlaceholderSelector)\n    ATTACH_AST_OPERATIONS(PlaceholderSelector)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////////////////////////////////////\n  // Type selectors (and the universal selector) -- e.g., div, span, *.\n  /////////////////////////////////////////////////////////////////////\n  class TypeSelector final : public SimpleSelector {\n  public:\n    TypeSelector(SourceSpan pstate, sass::string n);\n    int getSortOrder() const override final { return 1; }\n    virtual unsigned long specificity() const override;\n    SimpleSelector* unifyWith(const SimpleSelector*);\n    CompoundSelector* unifyWith(CompoundSelector*) override;\n    TypeSelector* getTypeSelector() override { return this; }\n    bool operator==(const SimpleSelector& rhs) const final override;\n    ATTACH_CMP_OPERATIONS(TypeSelector)\n    ATTACH_AST_OPERATIONS(TypeSelector)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////\n  // Class selectors  -- i.e., .foo.\n  ////////////////////////////////////////////////\n  class ClassSelector final : public SimpleSelector {\n  public:\n    ClassSelector(SourceSpan pstate, sass::string n);\n    int getSortOrder() const override final { return 2; }\n    virtual unsigned long specificity() const override;\n    bool operator==(const SimpleSelector& rhs) const final override;\n    ATTACH_CMP_OPERATIONS(ClassSelector)\n    ATTACH_AST_OPERATIONS(ClassSelector)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////\n  // ID selectors -- i.e., #foo.\n  ////////////////////////////////////////////////\n  class IDSelector final : public SimpleSelector {\n  public:\n    IDSelector(SourceSpan pstate, sass::string n);\n    int getSortOrder() const override final { return 2; }\n    virtual unsigned long specificity() const override;\n    CompoundSelector* unifyWith(CompoundSelector*) override;\n    IDSelector* getIdSelector() final override { return this; }\n    bool operator==(const SimpleSelector& rhs) const final override;\n    ATTACH_CMP_OPERATIONS(IDSelector)\n    ATTACH_AST_OPERATIONS(IDSelector)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////////////////////\n  // Attribute selectors -- e.g., [src*=\".jpg\"], etc.\n  ///////////////////////////////////////////////////\n  class AttributeSelector final : public SimpleSelector {\n    ADD_CONSTREF(sass::string, matcher)\n    // this cannot be changed to obj atm!!!!!!????!!!!!!!\n    ADD_PROPERTY(String_Obj, value) // might be interpolated\n    ADD_PROPERTY(char, modifier);\n  public:\n    AttributeSelector(SourceSpan pstate, sass::string n, sass::string m, String_Obj v, char o = 0);\n    int getSortOrder() const override final { return 2; }\n    size_t hash() const override;\n    virtual unsigned long specificity() const override;\n    bool operator==(const SimpleSelector& rhs) const final override;\n    ATTACH_CMP_OPERATIONS(AttributeSelector)\n    ATTACH_AST_OPERATIONS(AttributeSelector)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////////////////////////////////////////\n  // Pseudo selectors -- e.g., :first-child, :nth-of-type(...), etc.\n  //////////////////////////////////////////////////////////////////\n  // Pseudo Selector cannot have any namespace?\n  class PseudoSelector final : public SimpleSelector {\n    ADD_PROPERTY(sass::string, normalized)\n    ADD_PROPERTY(String_Obj, argument)\n    ADD_PROPERTY(SelectorListObj, selector)\n    ADD_PROPERTY(bool, isSyntacticClass)\n    ADD_PROPERTY(bool, isClass)\n  public:\n    PseudoSelector(SourceSpan pstate, sass::string n, bool element = false);\n    int getSortOrder() const override final { return 3; }\n    virtual bool is_pseudo_element() const override;\n    size_t hash() const override;\n\n    bool empty() const override;\n\n    bool has_real_parent_ref() const override;\n\n    // Whether this is a pseudo-element selector.\n    // This is `true` if and only if [isClass] is `false`.\n    bool isElement() const { return !isClass(); }\n\n    // Whether this is syntactically a pseudo-element selector.\n    // This is `true` if and only if [isSyntacticClass] is `false`.\n    bool isSyntacticElement() const { return !isSyntacticClass(); }\n\n    virtual unsigned long specificity() const override;\n    PseudoSelectorObj withSelector(SelectorListObj selector);\n\n    CompoundSelector* unifyWith(CompoundSelector*) override;\n    PseudoSelector* getPseudoSelector() final override { return this; }\n    bool operator==(const SimpleSelector& rhs) const final override;\n    ATTACH_CMP_OPERATIONS(PseudoSelector)\n    ATTACH_AST_OPERATIONS(PseudoSelector)\n    void cloneChildren() override;\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n\n  ////////////////////////////////////////////////////////////////////////////\n  // Complex Selectors are the most important class of selectors.\n  // A Selector List consists of Complex Selectors (separated by comma)\n  // Complex Selectors are itself a list of Compounds and Combinators\n  // Between each item there is an implicit ancestor of combinator\n  ////////////////////////////////////////////////////////////////////////////\n  class ComplexSelector final : public Selector, public Vectorized<SelectorComponentObj> {\n    ADD_PROPERTY(bool, chroots);\n    // line break before list separator\n    ADD_PROPERTY(bool, hasPreLineFeed);\n  public:\n    ComplexSelector(SourceSpan pstate);\n\n    // Returns true if the first components\n    // is a compound selector and fulfills\n    // a few other criteria.\n    bool isInvisible() const;\n    bool isInvalidCss() const;\n\n    size_t hash() const override;\n    void cloneChildren() override;\n    bool has_placeholder() const;\n    bool has_real_parent_ref() const override;\n\n    SelectorList* resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent = true);\n    virtual unsigned long specificity() const override;\n\n    SelectorList* unifyWith(ComplexSelector* rhs);\n\n    bool isSuperselectorOf(const ComplexSelector* sub) const;\n\n    SelectorListObj wrapInList();\n\n    size_t maxSpecificity() const override;\n    size_t minSpecificity() const override;\n\n    bool operator==(const Selector& rhs) const override;\n    bool operator==(const SelectorList& rhs) const;\n    bool operator==(const CompoundSelector& rhs) const;\n    bool operator==(const SimpleSelector& rhs) const;\n\n    ATTACH_CMP_OPERATIONS(ComplexSelector)\n    ATTACH_AST_OPERATIONS(ComplexSelector)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////////////////////\n  // Base class for complex selector components\n  ////////////////////////////////////////////////////////////////////////////\n  class SelectorComponent : public Selector {\n    // line break after list separator\n    ADD_PROPERTY(bool, hasPostLineBreak)\n  public:\n    SelectorComponent(SourceSpan pstate, bool postLineBreak = false);\n    size_t hash() const override = 0;\n    void cloneChildren() override;\n\n\n    // By default we consider instances not empty\n    virtual bool empty() const { return false; }\n\n    virtual bool has_placeholder() const = 0;\n    bool has_real_parent_ref() const override = 0;\n\n    ComplexSelector* wrapInComplex();\n\n    size_t maxSpecificity() const override { return 0; }\n    size_t minSpecificity() const override { return 0; }\n\n    virtual bool isCompound() const { return false; };\n    virtual bool isCombinator() const { return false; };\n\n    /* helper function for syntax sugar */\n    virtual CompoundSelector* getCompound() { return NULL; }\n    virtual SelectorCombinator* getCombinator() { return NULL; }\n    virtual const CompoundSelector* getCompound() const { return NULL; }\n    virtual const SelectorCombinator* getCombinator() const { return NULL; }\n\n    virtual unsigned long specificity() const override;\n    bool operator==(const Selector& rhs) const override = 0;\n    ATTACH_VIRTUAL_CMP_OPERATIONS(SelectorComponent);\n    ATTACH_VIRTUAL_AST_OPERATIONS(SelectorComponent);\n  };\n\n  ////////////////////////////////////////////////////////////////////////////\n  // A specific combinator between compound selectors\n  ////////////////////////////////////////////////////////////////////////////\n  class SelectorCombinator final : public SelectorComponent {\n  public:\n\n    // Enumerate all possible selector combinators. There is some\n    // discrepancy with dart-sass. Opted to name them as in CSS33\n    enum Combinator { CHILD /* > */, GENERAL /* ~ */, ADJACENT /* + */};\n\n  private:\n\n    // Store the type of this combinator\n    HASH_CONSTREF(Combinator, combinator)\n\n  public:\n    SelectorCombinator(SourceSpan pstate, Combinator combinator, bool postLineBreak = false);\n\n    bool has_real_parent_ref() const override { return false; }\n    bool has_placeholder() const override { return false; }\n\n    /* helper function for syntax sugar */\n    SelectorCombinator* getCombinator() final override { return this; }\n    const SelectorCombinator* getCombinator() const final override { return this; }\n\n    // Query type of combinator\n    bool isCombinator() const override { return true; };\n\n    // Matches the right-hand selector if it's a direct child of the left-\n    // hand selector in the DOM tree. Dart-sass also calls this `child`\n    // https://developer.mozilla.org/en-US/docs/Web/CSS/Child_combinator\n    bool isChildCombinator() const { return combinator_ == CHILD; } // >\n\n    // Matches the right-hand selector if it comes after the left-hand\n    // selector in the DOM tree. Dart-sass class this `followingSibling`\n    // https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator\n    bool isGeneralCombinator() const { return combinator_ == GENERAL; } // ~\n\n    // Matches the right-hand selector if it's immediately adjacent to the\n    // left-hand selector in the DOM tree. Dart-sass calls this `nextSibling`\n    // https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator\n    bool isAdjacentCombinator() const { return combinator_ == ADJACENT; } // +\n\n    size_t maxSpecificity() const override { return 0; }\n    size_t minSpecificity() const override { return 0; }\n\n    size_t hash() const override {\n      return std::hash<int>()(combinator_);\n    }\n    void cloneChildren() override;\n    virtual unsigned long specificity() const override;\n    bool operator==(const Selector& rhs) const override;\n    bool operator==(const SelectorComponent& rhs) const override;\n\n    ATTACH_CMP_OPERATIONS(SelectorCombinator)\n    ATTACH_AST_OPERATIONS(SelectorCombinator)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////////////////////\n  // A compound selector consists of multiple simple selectors\n  ////////////////////////////////////////////////////////////////////////////\n  class CompoundSelector final : public SelectorComponent, public Vectorized<SimpleSelectorObj> {\n    ADD_PROPERTY(bool, hasRealParent)\n  public:\n    CompoundSelector(SourceSpan pstate, bool postLineBreak = false);\n\n    // Returns true if this compound selector\n    // fulfills various criteria.\n    bool isInvisible() const;\n\n    bool empty() const override {\n      return Vectorized::empty();\n    }\n\n    size_t hash() const override;\n    CompoundSelector* unifyWith(CompoundSelector* rhs);\n\n    /* helper function for syntax sugar */\n    CompoundSelector* getCompound() final override { return this; }\n    const CompoundSelector* getCompound() const final override { return this; }\n\n    bool isSuperselectorOf(const CompoundSelector* sub, sass::string wrapped = \"\") const;\n\n    void cloneChildren() override;\n    bool has_real_parent_ref() const override;\n    bool has_placeholder() const override;\n    sass::vector<ComplexSelectorObj> resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent = true);\n\n    virtual bool isCompound() const override { return true; };\n    virtual unsigned long specificity() const override;\n\n    size_t maxSpecificity() const override;\n    size_t minSpecificity() const override;\n\n    bool operator==(const Selector& rhs) const override;\n\n    bool operator==(const SelectorComponent& rhs) const override;\n\n    bool operator==(const SelectorList& rhs) const;\n    bool operator==(const ComplexSelector& rhs) const;\n    bool operator==(const SimpleSelector& rhs) const;\n\n    void sortChildren();\n    bool isInvalidCss() const;\n\n    ATTACH_CMP_OPERATIONS(CompoundSelector)\n    ATTACH_AST_OPERATIONS(CompoundSelector)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////\n  // Comma-separated selector groups.\n  ///////////////////////////////////\n  class SelectorList final : public Selector, public Vectorized<ComplexSelectorObj> {\n  private:\n    // maybe we have optional flag\n    // ToDo: should be at ExtendRule?\n    ADD_PROPERTY(bool, is_optional)\n  public:\n    SelectorList(SourceSpan pstate, size_t s = 0);\n    sass::string type() const override { return \"list\"; }\n    size_t hash() const override;\n\n    SelectorList* unifyWith(SelectorList*);\n\n    // Returns true if all complex selectors\n    // can have real parents, meaning every\n    // first component does allow for it\n    bool isInvisible() const;\n\n    void cloneChildren() override;\n    bool has_real_parent_ref() const override;\n    SelectorList* resolve_parent_refs(SelectorStack pstack, Backtraces& traces, bool implicit_parent = true);\n    virtual unsigned long specificity() const override;\n\n    bool isSuperselectorOf(const SelectorList* sub) const;\n\n    size_t maxSpecificity() const override;\n    size_t minSpecificity() const override;\n\n    bool operator==(const Selector& rhs) const override;\n    bool operator==(const ComplexSelector& rhs) const;\n    bool operator==(const CompoundSelector& rhs) const;\n    bool operator==(const SimpleSelector& rhs) const;\n    // Selector Lists can be compared to comma lists\n    bool operator==(const Expression& rhs) const override;\n\n    ATTACH_CMP_OPERATIONS(SelectorList)\n    ATTACH_AST_OPERATIONS(SelectorList)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////\n  // The Sass `@extend` directive.\n  ////////////////////////////////\n  class ExtendRule final : public Statement {\n    ADD_PROPERTY(bool, isOptional)\n    // This should be a simple selector only!\n    ADD_PROPERTY(SelectorListObj, selector)\n    ADD_PROPERTY(Selector_Schema_Obj, schema)\n  public:\n    ExtendRule(SourceSpan pstate, SelectorListObj s);\n    ExtendRule(SourceSpan pstate, Selector_Schema_Obj s);\n    ATTACH_AST_OPERATIONS(ExtendRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_supports.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\n\nnamespace Sass {\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SupportsRule::SupportsRule(SourceSpan pstate, SupportsConditionObj condition, Block_Obj block)\n  : ParentStatement(pstate, block), condition_(condition)\n  { statement_type(SUPPORTS); }\n  SupportsRule::SupportsRule(const SupportsRule* ptr)\n  : ParentStatement(ptr), condition_(ptr->condition_)\n  { statement_type(SUPPORTS); }\n  bool SupportsRule::bubbles() { return true; }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SupportsCondition::SupportsCondition(SourceSpan pstate)\n  : Expression(pstate)\n  { }\n\n  SupportsCondition::SupportsCondition(const SupportsCondition* ptr)\n  : Expression(ptr)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SupportsOperation::SupportsOperation(SourceSpan pstate, SupportsConditionObj l, SupportsConditionObj r, Operand o)\n  : SupportsCondition(pstate), left_(l), right_(r), operand_(o)\n  { }\n  SupportsOperation::SupportsOperation(const SupportsOperation* ptr)\n  : SupportsCondition(ptr),\n    left_(ptr->left_),\n    right_(ptr->right_),\n    operand_(ptr->operand_)\n  { }\n\n  bool SupportsOperation::needs_parens(SupportsConditionObj cond) const\n  {\n    if (SupportsOperationObj op = Cast<SupportsOperation>(cond)) {\n      return op->operand() != operand();\n    }\n    return Cast<SupportsNegation>(cond) != NULL;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SupportsNegation::SupportsNegation(SourceSpan pstate, SupportsConditionObj c)\n  : SupportsCondition(pstate), condition_(c)\n  { }\n  SupportsNegation::SupportsNegation(const SupportsNegation* ptr)\n  : SupportsCondition(ptr), condition_(ptr->condition_)\n  { }\n\n  bool SupportsNegation::needs_parens(SupportsConditionObj cond) const\n  {\n    return Cast<SupportsNegation>(cond) ||\n           Cast<SupportsOperation>(cond);\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  SupportsDeclaration::SupportsDeclaration(SourceSpan pstate, ExpressionObj f, ExpressionObj v)\n  : SupportsCondition(pstate), feature_(f), value_(v)\n  { }\n  SupportsDeclaration::SupportsDeclaration(const SupportsDeclaration* ptr)\n  : SupportsCondition(ptr),\n    feature_(ptr->feature_),\n    value_(ptr->value_)\n  { }\n\n  bool SupportsDeclaration::needs_parens(SupportsConditionObj cond) const\n  {\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Supports_Interpolation::Supports_Interpolation(SourceSpan pstate, ExpressionObj v)\n  : SupportsCondition(pstate), value_(v)\n  { }\n  Supports_Interpolation::Supports_Interpolation(const Supports_Interpolation* ptr)\n  : SupportsCondition(ptr),\n    value_(ptr->value_)\n  { }\n\n  bool Supports_Interpolation::needs_parens(SupportsConditionObj cond) const\n  {\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  IMPLEMENT_AST_OPERATORS(SupportsRule);\n  IMPLEMENT_AST_OPERATORS(SupportsCondition);\n  IMPLEMENT_AST_OPERATORS(SupportsOperation);\n  IMPLEMENT_AST_OPERATORS(SupportsNegation);\n  IMPLEMENT_AST_OPERATORS(SupportsDeclaration);\n  IMPLEMENT_AST_OPERATORS(Supports_Interpolation);\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_supports.hpp",
    "content": "#ifndef SASS_AST_SUPPORTS_H\n#define SASS_AST_SUPPORTS_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <set>\n#include <deque>\n#include <vector>\n#include <string>\n#include <sstream>\n#include <iostream>\n#include <typeinfo>\n#include <algorithm>\n#include \"sass/base.h\"\n#include \"ast_fwd_decl.hpp\"\n\n#include \"util.hpp\"\n#include \"units.hpp\"\n#include \"context.hpp\"\n#include \"position.hpp\"\n#include \"constants.hpp\"\n#include \"operation.hpp\"\n#include \"position.hpp\"\n#include \"inspect.hpp\"\n#include \"source_map.hpp\"\n#include \"environment.hpp\"\n#include \"error_handling.hpp\"\n#include \"ast_def_macros.hpp\"\n#include \"ast_fwd_decl.hpp\"\n#include \"source_map.hpp\"\n#include \"fn_utils.hpp\"\n\n#include \"sass.h\"\n\nnamespace Sass {\n\n  ////////////////////\n  // `@supports` rule.\n  ////////////////////\n  class SupportsRule : public ParentStatement {\n    ADD_PROPERTY(SupportsConditionObj, condition)\n  public:\n    SupportsRule(SourceSpan pstate, SupportsConditionObj condition, Block_Obj block = {});\n    bool bubbles() override;\n    ATTACH_AST_OPERATIONS(SupportsRule)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////////////////////////////\n  // The abstract superclass of all Supports conditions.\n  //////////////////////////////////////////////////////\n  class SupportsCondition : public Expression {\n  public:\n    SupportsCondition(SourceSpan pstate);\n    virtual bool needs_parens(SupportsConditionObj cond) const { return false; }\n    ATTACH_AST_OPERATIONS(SupportsCondition)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////\n  // An operator condition (e.g. `CONDITION1 and CONDITION2`).\n  ////////////////////////////////////////////////////////////\n  class SupportsOperation : public SupportsCondition {\n  public:\n    enum Operand { AND, OR };\n  private:\n    ADD_PROPERTY(SupportsConditionObj, left);\n    ADD_PROPERTY(SupportsConditionObj, right);\n    ADD_PROPERTY(Operand, operand);\n  public:\n    SupportsOperation(SourceSpan pstate, SupportsConditionObj l, SupportsConditionObj r, Operand o);\n    virtual bool needs_parens(SupportsConditionObj cond) const override;\n    ATTACH_AST_OPERATIONS(SupportsOperation)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////////////////\n  // A negation condition (`not CONDITION`).\n  //////////////////////////////////////////\n  class SupportsNegation : public SupportsCondition {\n  private:\n    ADD_PROPERTY(SupportsConditionObj, condition);\n  public:\n    SupportsNegation(SourceSpan pstate, SupportsConditionObj c);\n    virtual bool needs_parens(SupportsConditionObj cond) const override;\n    ATTACH_AST_OPERATIONS(SupportsNegation)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  /////////////////////////////////////////////////////\n  // A declaration condition (e.g. `(feature: value)`).\n  /////////////////////////////////////////////////////\n  class SupportsDeclaration : public SupportsCondition {\n  private:\n    ADD_PROPERTY(ExpressionObj, feature);\n    ADD_PROPERTY(ExpressionObj, value);\n  public:\n    SupportsDeclaration(SourceSpan pstate, ExpressionObj f, ExpressionObj v);\n    virtual bool needs_parens(SupportsConditionObj cond) const override;\n    ATTACH_AST_OPERATIONS(SupportsDeclaration)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////////////////\n  // An interpolation condition (e.g. `#{$var}`).\n  ///////////////////////////////////////////////\n  class Supports_Interpolation : public SupportsCondition {\n  private:\n    ADD_PROPERTY(ExpressionObj, value);\n  public:\n    Supports_Interpolation(SourceSpan pstate, ExpressionObj v);\n    virtual bool needs_parens(SupportsConditionObj cond) const override;\n    ATTACH_AST_OPERATIONS(Supports_Interpolation)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_values.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  void str_rtrim(sass::string& str, const sass::string& delimiters = \" \\f\\n\\r\\t\\v\")\n  {\n    str.erase( str.find_last_not_of( delimiters ) + 1 );\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  PreValue::PreValue(SourceSpan pstate, bool d, bool e, bool i, Type ct)\n  : Expression(pstate, d, e, i, ct)\n  { }\n  PreValue::PreValue(const PreValue* ptr)\n  : Expression(ptr)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Value::Value(SourceSpan pstate, bool d, bool e, bool i, Type ct)\n  : PreValue(pstate, d, e, i, ct)\n  { }\n  Value::Value(const Value* ptr)\n  : PreValue(ptr)\n  { }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  List::List(SourceSpan pstate, size_t size, enum Sass_Separator sep, bool argl, bool bracket)\n  : Value(pstate),\n    Vectorized<ExpressionObj>(size),\n    separator_(sep),\n    is_arglist_(argl),\n    is_bracketed_(bracket),\n    from_selector_(false)\n  { concrete_type(LIST); }\n\n  List::List(const List* ptr)\n  : Value(ptr),\n    Vectorized<ExpressionObj>(*ptr),\n    separator_(ptr->separator_),\n    is_arglist_(ptr->is_arglist_),\n    is_bracketed_(ptr->is_bracketed_),\n    from_selector_(ptr->from_selector_)\n  { concrete_type(LIST); }\n\n  size_t List::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<sass::string>()(sep_string());\n      hash_combine(hash_, std::hash<bool>()(is_bracketed()));\n      for (size_t i = 0, L = length(); i < L; ++i)\n        hash_combine(hash_, (elements()[i])->hash());\n    }\n    return hash_;\n  }\n\n  void List::set_delayed(bool delayed)\n  {\n    is_delayed(delayed);\n    // don't set children\n  }\n\n  bool List::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<List>(&rhs)) {\n      if (length() < r->length()) return true;\n      if (length() > r->length()) return false;\n      const auto& left = elements();\n      const auto& right = r->elements();\n      for (size_t i = 0; i < left.size(); i += 1) {\n        if (*left[i] < *right[i]) return true;\n        if (*left[i] == *right[i]) continue;\n        return false;\n      }\n      return false;\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool List::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<List>(&rhs)) {\n      if (length() != r->length()) return false;\n      if (separator() != r->separator()) return false;\n      if (is_bracketed() != r->is_bracketed()) return false;\n      for (size_t i = 0, L = length(); i < L; ++i) {\n        auto rv = r->at(i);\n        auto lv = this->at(i);\n        if (!lv && rv) return false;\n        else if (!rv && lv) return false;\n        else if (*lv != *rv) return false;\n      }\n      return true;\n    }\n    return false;\n  }\n\n  size_t List::size() const {\n    if (!is_arglist_) return length();\n    // arglist expects a list of arguments\n    // so we need to break before keywords\n    for (size_t i = 0, L = length(); i < L; ++i) {\n      ExpressionObj obj = this->at(i);\n      if (Argument* arg = Cast<Argument>(obj)) {\n        if (!arg->name().empty()) return i;\n      }\n    }\n    return length();\n  }\n\n\n  ExpressionObj List::value_at_index(size_t i) {\n    ExpressionObj obj = this->at(i);\n    if (is_arglist_) {\n      if (Argument* arg = Cast<Argument>(obj)) {\n        return arg->value();\n      } else {\n        return obj;\n      }\n    } else {\n      return obj;\n    }\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Map::Map(SourceSpan pstate, size_t size)\n  : Value(pstate),\n    Hashed(size)\n  { concrete_type(MAP); }\n\n  Map::Map(const Map* ptr)\n  : Value(ptr),\n    Hashed(*ptr)\n  { concrete_type(MAP); }\n\n  bool Map::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<Map>(&rhs)) {\n      if (length() < r->length()) return true;\n      if (length() > r->length()) return false;\n      const auto& lkeys = keys();\n      const auto& rkeys = r->keys();\n      for (size_t i = 0; i < lkeys.size(); i += 1) {\n        if (*lkeys[i] < *rkeys[i]) return true;\n        if (*lkeys[i] == *rkeys[i]) continue;\n        return false;\n      }\n      const auto& lvals = values();\n      const auto& rvals = r->values();\n      for (size_t i = 0; i < lvals.size(); i += 1) {\n        if (*lvals[i] < *rvals[i]) return true;\n        if (*lvals[i] == *rvals[i]) continue;\n        return false;\n      }\n      return false;\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Map::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<Map>(&rhs)) {\n      if (length() != r->length()) return false;\n      for (auto key : keys()) {\n        auto rv = r->at(key);\n        auto lv = this->at(key);\n        if (!lv && rv) return false;\n        else if (!rv && lv) return false;\n        else if (*lv != *rv) return false;\n      }\n      return true;\n    }\n    return false;\n  }\n\n  List_Obj Map::to_list(SourceSpan& pstate) {\n    List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);\n\n    for (auto key : keys()) {\n      List_Obj l = SASS_MEMORY_NEW(List, pstate, 2);\n      l->append(key);\n      l->append(at(key));\n      ret->append(l);\n    }\n\n    return ret;\n  }\n\n  size_t Map::hash() const\n  {\n    if (hash_ == 0) {\n      for (auto key : keys()) {\n        hash_combine(hash_, key->hash());\n        hash_combine(hash_, at(key)->hash());\n      }\n    }\n\n    return hash_;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Binary_Expression::Binary_Expression(SourceSpan pstate,\n                    Operand op, ExpressionObj lhs, ExpressionObj rhs)\n  : PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)\n  { }\n\n  Binary_Expression::Binary_Expression(const Binary_Expression* ptr)\n  : PreValue(ptr),\n    op_(ptr->op_),\n    left_(ptr->left_),\n    right_(ptr->right_),\n    hash_(ptr->hash_)\n  { }\n\n  bool Binary_Expression::is_left_interpolant(void) const\n  {\n    return is_interpolant() || (left() && left()->is_left_interpolant());\n  }\n  bool Binary_Expression::is_right_interpolant(void) const\n  {\n    return is_interpolant() || (right() && right()->is_right_interpolant());\n  }\n\n  const sass::string Binary_Expression::type_name()\n  {\n    return sass_op_to_name(optype());\n  }\n\n  const sass::string Binary_Expression::separator()\n  {\n    return sass_op_separator(optype());\n  }\n\n  bool Binary_Expression::has_interpolant() const\n  {\n    return is_left_interpolant() ||\n            is_right_interpolant();\n  }\n\n  void Binary_Expression::set_delayed(bool delayed)\n  {\n    right()->set_delayed(delayed);\n    left()->set_delayed(delayed);\n    is_delayed(delayed);\n  }\n\n  bool Binary_Expression::operator<(const Expression& rhs) const\n  {\n    if (auto m = Cast<Binary_Expression>(&rhs)) {\n      return type() < m->type() ||\n        *left() < *m->left() ||\n        *right() < *m->right();\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Binary_Expression::operator==(const Expression& rhs) const\n  {\n    if (auto m = Cast<Binary_Expression>(&rhs)) {\n      return type() == m->type() &&\n             *left() == *m->left() &&\n             *right() == *m->right();\n    }\n    return false;\n  }\n\n  size_t Binary_Expression::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<size_t>()(optype());\n      hash_combine(hash_, left()->hash());\n      hash_combine(hash_, right()->hash());\n    }\n    return hash_;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Function::Function(SourceSpan pstate, Definition_Obj def, bool css)\n  : Value(pstate), definition_(def), is_css_(css)\n  { concrete_type(FUNCTION_VAL); }\n\n  Function::Function(const Function* ptr)\n  : Value(ptr), definition_(ptr->definition_), is_css_(ptr->is_css_)\n  { concrete_type(FUNCTION_VAL); }\n\n  bool Function::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<Function>(&rhs)) {\n      auto d1 = Cast<Definition>(definition());\n      auto d2 = Cast<Definition>(r->definition());\n      if (d1 == nullptr) return d2 != nullptr;\n      else if (d2 == nullptr) return false;\n      if (is_css() == r->is_css()) {\n        return d1 < d2;\n      }\n      return r->is_css();\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Function::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<Function>(&rhs)) {\n      auto d1 = Cast<Definition>(definition());\n      auto d2 = Cast<Definition>(r->definition());\n      return d1 && d2 && d1 == d2 && is_css() == r->is_css();\n    }\n    return false;\n  }\n\n  sass::string Function::name() {\n    if (definition_) {\n      return definition_->name();\n    }\n    return \"\";\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, void* cookie)\n  : PreValue(pstate), sname_(n), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)\n  { concrete_type(FUNCTION); }\n  Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, Function_Obj func)\n  : PreValue(pstate), sname_(n), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)\n  { concrete_type(FUNCTION); }\n  Function_Call::Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args)\n  : PreValue(pstate), sname_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)\n  { concrete_type(FUNCTION); }\n\n  Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, void* cookie)\n  : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)\n  { concrete_type(FUNCTION); }\n  Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Function_Obj func)\n  : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)\n  { concrete_type(FUNCTION); }\n  Function_Call::Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args)\n  : PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), via_call_(false), cookie_(0), hash_(0)\n  { concrete_type(FUNCTION); }\n\n  Function_Call::Function_Call(const Function_Call* ptr)\n  : PreValue(ptr),\n    sname_(ptr->sname_),\n    arguments_(ptr->arguments_),\n    func_(ptr->func_),\n    via_call_(ptr->via_call_),\n    cookie_(ptr->cookie_),\n    hash_(ptr->hash_)\n  { concrete_type(FUNCTION); }\n\n  bool Function_Call::operator==(const Expression& rhs) const\n  {\n    if (auto m = Cast<Function_Call>(&rhs)) {\n      if (*sname() != *m->sname()) return false;\n      if (arguments()->length() != m->arguments()->length()) return false;\n      for (size_t i = 0, L = arguments()->length(); i < L; ++i)\n        if (*arguments()->get(i) != *m->arguments()->get(i)) return false;\n      return true;\n    }\n    return false;\n  }\n\n  size_t Function_Call::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<sass::string>()(name());\n      for (auto argument : arguments()->elements())\n        hash_combine(hash_, argument->hash());\n    }\n    return hash_;\n  }\n\n  sass::string Function_Call::name() const\n  {\n    return sname();\n  }\n\n  bool Function_Call::is_css() {\n    if (func_) return func_->is_css();\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Variable::Variable(SourceSpan pstate, sass::string n)\n  : PreValue(pstate), name_(n)\n  { concrete_type(VARIABLE); }\n\n  Variable::Variable(const Variable* ptr)\n  : PreValue(ptr), name_(ptr->name_)\n  { concrete_type(VARIABLE); }\n\n  bool Variable::operator==(const Expression& rhs) const\n  {\n    if (auto e = Cast<Variable>(&rhs)) {\n      return name() == e->name();\n    }\n    return false;\n  }\n\n  size_t Variable::hash() const\n  {\n    return std::hash<sass::string>()(name());\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Number::Number(SourceSpan pstate, double val, sass::string u, bool zero)\n  : Value(pstate),\n    Units(),\n    value_(val),\n    zero_(zero),\n    hash_(0)\n  {\n    size_t l = 0;\n    size_t r;\n    if (!u.empty()) {\n      bool nominator = true;\n      while (true) {\n        r = u.find_first_of(\"*/\", l);\n        sass::string unit(u.substr(l, r == sass::string::npos ? r : r - l));\n        if (!unit.empty()) {\n          if (nominator) numerators.push_back(unit);\n          else denominators.push_back(unit);\n        }\n        if (r == sass::string::npos) break;\n        // ToDo: should error for multiple slashes\n        // if (!nominator && u[r] == '/') error(...)\n        if (u[r] == '/')\n          nominator = false;\n        // strange math parsing?\n        // else if (u[r] == '*')\n        //  nominator = true;\n        l = r + 1;\n      }\n    }\n    concrete_type(NUMBER);\n  }\n\n  Number::Number(const Number* ptr)\n  : Value(ptr),\n    Units(ptr),\n    value_(ptr->value_), zero_(ptr->zero_),\n    hash_(ptr->hash_)\n  { concrete_type(NUMBER); }\n\n  // cancel out unnecessary units\n  void Number::reduce()\n  {\n    // apply conversion factor\n    value_ *= this->Units::reduce();\n  }\n\n  void Number::normalize()\n  {\n    // apply conversion factor\n    value_ *= this->Units::normalize();\n  }\n\n  size_t Number::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<double>()(value_);\n      for (const auto& numerator : numerators)\n        hash_combine(hash_, std::hash<sass::string>()(numerator));\n      for (const auto& denominator : denominators)\n        hash_combine(hash_, std::hash<sass::string>()(denominator));\n    }\n    return hash_;\n  }\n\n  bool Number::operator< (const Expression& rhs) const\n  {\n    if (auto n = Cast<Number>(&rhs)) {\n      return *this < *n;\n    }\n    return false;\n  }\n\n  bool Number::operator== (const Expression& rhs) const\n  {\n    if (auto n = Cast<Number>(&rhs)) {\n      return *this == *n;\n    }\n    return false;\n  }\n\n  bool Number::operator== (const Number& rhs) const\n  {\n    // unitless or only having one unit are equivalent (3.4)\n    // therefore we need to reduce the units beforehand\n    Number l(*this), r(rhs); l.reduce(); r.reduce();\n    size_t lhs_units = l.numerators.size() + l.denominators.size();\n    size_t rhs_units = r.numerators.size() + r.denominators.size();\n    if (!lhs_units || !rhs_units) {\n      return NEAR_EQUAL(l.value(), r.value());\n    }\n    // ensure both have same units\n    l.normalize(); r.normalize();\n    Units &lhs_unit = l, &rhs_unit = r;\n    return lhs_unit == rhs_unit &&\n      NEAR_EQUAL(l.value(), r.value());\n  }\n\n  bool Number::operator< (const Number& rhs) const\n  {\n    // unitless or only having one unit are equivalent (3.4)\n    // therefore we need to reduce the units beforehand\n    Number l(*this), r(rhs); l.reduce(); r.reduce();\n    size_t lhs_units = l.numerators.size() + l.denominators.size();\n    size_t rhs_units = r.numerators.size() + r.denominators.size();\n    if (!lhs_units || !rhs_units) {\n      return l.value() < r.value();\n    }\n    // ensure both have same units\n    l.normalize(); r.normalize();\n    Units &lhs_unit = l, &rhs_unit = r;\n    if (!(lhs_unit == rhs_unit)) {\n      /* ToDo: do we always get useful backtraces? */\n      throw Exception::IncompatibleUnits(rhs, *this);\n    }\n    if (lhs_unit == rhs_unit) {\n      return l.value() < r.value();\n    } else {\n      return lhs_unit < rhs_unit;\n    }\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Color::Color(SourceSpan pstate, double a, const sass::string disp)\n  : Value(pstate),\n    disp_(disp), a_(a),\n    hash_(0)\n  { concrete_type(COLOR); }\n\n  Color::Color(const Color* ptr)\n  : Value(ptr->pstate()),\n    // reset on copy\n    disp_(\"\"),\n    a_(ptr->a_),\n    hash_(ptr->hash_)\n  { concrete_type(COLOR); }\n\n  bool Color::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<Color_RGBA>(&rhs)) {\n      return *this < *r;\n    }\n    else if (auto r = Cast<Color_HSLA>(&rhs)) {\n      return *this < *r;\n    }\n    else if (auto r = Cast<Color>(&rhs)) {\n      return a_ < r->a();\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Color::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<Color_RGBA>(&rhs)) {\n      return *this == *r;\n    }\n    else if (auto r = Cast<Color_HSLA>(&rhs)) {\n      return *this == *r;\n    }\n    else if (auto r = Cast<Color>(&rhs)) {\n      return a_ == r->a();\n    }\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Color_RGBA::Color_RGBA(SourceSpan pstate, double r, double g, double b, double a, const sass::string disp)\n  : Color(pstate, a, disp),\n    r_(r), g_(g), b_(b)\n  { concrete_type(COLOR); }\n\n  Color_RGBA::Color_RGBA(const Color_RGBA* ptr)\n  : Color(ptr),\n    r_(ptr->r_),\n    g_(ptr->g_),\n    b_(ptr->b_)\n  { concrete_type(COLOR); }\n\n  bool Color_RGBA::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<Color_RGBA>(&rhs)) {\n      if (r_ < r->r()) return true;\n      if (r_ > r->r()) return false;\n      if (g_ < r->g()) return true;\n      if (g_ > r->g()) return false;\n      if (b_ < r->b()) return true;\n      if (b_ > r->b()) return false;\n      if (a_ < r->a()) return true;\n      if (a_ > r->a()) return false;\n      return false; // is equal\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Color_RGBA::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<Color_RGBA>(&rhs)) {\n      return r_ == r->r() &&\n             g_ == r->g() &&\n             b_ == r->b() &&\n             a_ == r->a();\n    }\n    return false;\n  }\n\n  size_t Color_RGBA::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<sass::string>()(\"RGBA\");\n      hash_combine(hash_, std::hash<double>()(a_));\n      hash_combine(hash_, std::hash<double>()(r_));\n      hash_combine(hash_, std::hash<double>()(g_));\n      hash_combine(hash_, std::hash<double>()(b_));\n    }\n    return hash_;\n  }\n\n  Color_HSLA* Color_RGBA::copyAsHSLA() const\n  {\n\n    // Algorithm from http://en.wikipedia.org/wiki/wHSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV\n    double r = r_ / 255.0;\n    double g = g_ / 255.0;\n    double b = b_ / 255.0;\n\n    double max = std::max(r, std::max(g, b));\n    double min = std::min(r, std::min(g, b));\n    double delta = max - min;\n\n    double h = 0;\n    double s;\n    double l = (max + min) / 2.0;\n\n    if (NEAR_EQUAL(max, min)) {\n      h = s = 0; // achromatic\n    }\n    else {\n      if (l < 0.5) s = delta / (max + min);\n      else         s = delta / (2.0 - max - min);\n\n      if      (r == max) h = (g - b) / delta + (g < b ? 6 : 0);\n      else if (g == max) h = (b - r) / delta + 2;\n      else if (b == max) h = (r - g) / delta + 4;\n    }\n\n    // HSL hsl_struct;\n    h = h * 60;\n    s = s * 100;\n    l = l * 100;\n\n    return SASS_MEMORY_NEW(Color_HSLA,\n      pstate(), h, s, l, a(), \"\"\n    );\n  }\n\n  Color_RGBA* Color_RGBA::copyAsRGBA() const\n  {\n    return SASS_MEMORY_COPY(this);\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Color_HSLA::Color_HSLA(SourceSpan pstate, double h, double s, double l, double a, const sass::string disp)\n  : Color(pstate, a, disp),\n    h_(absmod(h, 360.0)),\n    s_(clip(s, 0.0, 100.0)),\n    l_(clip(l, 0.0, 100.0))\n    // hash_(0)\n  { concrete_type(COLOR); }\n\n  Color_HSLA::Color_HSLA(const Color_HSLA* ptr)\n  : Color(ptr),\n    h_(ptr->h_),\n    s_(ptr->s_),\n    l_(ptr->l_)\n    // hash_(ptr->hash_)\n  { concrete_type(COLOR); }\n\n  bool Color_HSLA::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<Color_HSLA>(&rhs)) {\n      if (h_ < r->h()) return true;\n      if (h_ > r->h()) return false;\n      if (s_ < r->s()) return true;\n      if (s_ > r->s()) return false;\n      if (l_ < r->l()) return true;\n      if (l_ > r->l()) return false;\n      if (a_ < r->a()) return true;\n      if (a_ > r->a()) return false;\n      return false; // is equal\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Color_HSLA::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<Color_HSLA>(&rhs)) {\n      return h_ == r->h() &&\n             s_ == r->s() &&\n             l_ == r->l() &&\n             a_ == r->a();\n    }\n    return false;\n  }\n\n  size_t Color_HSLA::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<sass::string>()(\"HSLA\");\n      hash_combine(hash_, std::hash<double>()(a_));\n      hash_combine(hash_, std::hash<double>()(h_));\n      hash_combine(hash_, std::hash<double>()(s_));\n      hash_combine(hash_, std::hash<double>()(l_));\n    }\n    return hash_;\n  }\n\n  // hue to RGB helper function\n  double h_to_rgb(double m1, double m2, double h)\n  {\n    h = absmod(h, 1.0);\n    if (h*6.0 < 1) return m1 + (m2 - m1)*h*6;\n    if (h*2.0 < 1) return m2;\n    if (h*3.0 < 2) return m1 + (m2 - m1) * (2.0/3.0 - h)*6;\n    return m1;\n  }\n\n  Color_RGBA* Color_HSLA::copyAsRGBA() const\n  {\n\n    double h = absmod(h_ / 360.0, 1.0);\n    double s = clip(s_ / 100.0, 0.0, 1.0);\n    double l = clip(l_ / 100.0, 0.0, 1.0);\n\n    // Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color.\n    double m2;\n    if (l <= 0.5) m2 = l*(s+1.0);\n    else m2 = (l+s)-(l*s);\n    double m1 = (l*2.0)-m2;\n    // round the results -- consider moving this into the Color constructor\n    double r = (h_to_rgb(m1, m2, h + 1.0/3.0) * 255.0);\n    double g = (h_to_rgb(m1, m2, h) * 255.0);\n    double b = (h_to_rgb(m1, m2, h - 1.0/3.0) * 255.0);\n\n    return SASS_MEMORY_NEW(Color_RGBA,\n      pstate(), r, g, b, a(), \"\"\n    );\n  }\n\n  Color_HSLA* Color_HSLA::copyAsHSLA() const\n  {\n    return SASS_MEMORY_COPY(this);\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Custom_Error::Custom_Error(SourceSpan pstate, sass::string msg)\n  : Value(pstate), message_(msg)\n  { concrete_type(C_ERROR); }\n\n  Custom_Error::Custom_Error(const Custom_Error* ptr)\n  : Value(ptr), message_(ptr->message_)\n  { concrete_type(C_ERROR); }\n\n  bool Custom_Error::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<Custom_Error>(&rhs)) {\n      return message() < r->message();\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Custom_Error::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<Custom_Error>(&rhs)) {\n      return message() == r->message();\n    }\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Custom_Warning::Custom_Warning(SourceSpan pstate, sass::string msg)\n  : Value(pstate), message_(msg)\n  { concrete_type(C_WARNING); }\n\n  Custom_Warning::Custom_Warning(const Custom_Warning* ptr)\n  : Value(ptr), message_(ptr->message_)\n  { concrete_type(C_WARNING); }\n\n  bool Custom_Warning::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<Custom_Warning>(&rhs)) {\n      return message() < r->message();\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Custom_Warning::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<Custom_Warning>(&rhs)) {\n      return message() == r->message();\n    }\n    return false;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Boolean::Boolean(SourceSpan pstate, bool val)\n  : Value(pstate), value_(val),\n    hash_(0)\n  { concrete_type(BOOLEAN); }\n\n  Boolean::Boolean(const Boolean* ptr)\n  : Value(ptr),\n    value_(ptr->value_),\n    hash_(ptr->hash_)\n  { concrete_type(BOOLEAN); }\n\n bool Boolean::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<Boolean>(&rhs)) {\n      return (value() < r->value());\n    }\n    return false;\n  }\n\n bool Boolean::operator== (const Expression& rhs) const\n {\n   if (auto r = Cast<Boolean>(&rhs)) {\n     return (value() == r->value());\n   }\n   return false;\n }\n\n size_t Boolean::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<bool>()(value_);\n    }\n    return hash_;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  String::String(SourceSpan pstate, bool delayed)\n  : Value(pstate, delayed)\n  { concrete_type(STRING); }\n  String::String(const String* ptr)\n  : Value(ptr)\n  { concrete_type(STRING); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  String_Schema::String_Schema(SourceSpan pstate, size_t size, bool css)\n  : String(pstate), Vectorized<PreValueObj>(size), css_(css), hash_(0)\n  { concrete_type(STRING); }\n\n  String_Schema::String_Schema(const String_Schema* ptr)\n  : String(ptr),\n    Vectorized<PreValueObj>(*ptr),\n    css_(ptr->css_),\n    hash_(ptr->hash_)\n  { concrete_type(STRING); }\n\n  void String_Schema::rtrim()\n  {\n    if (!empty()) {\n      if (String* str = Cast<String>(last())) str->rtrim();\n    }\n  }\n\n  bool String_Schema::is_left_interpolant(void) const\n  {\n    return length() && first()->is_left_interpolant();\n  }\n  bool String_Schema::is_right_interpolant(void) const\n  {\n    return length() && last()->is_right_interpolant();\n  }\n\n  bool String_Schema::operator< (const Expression& rhs) const\n  {\n    if (auto r = Cast<String_Schema>(&rhs)) {\n      if (length() < r->length()) return true;\n      if (length() > r->length()) return false;\n      for (size_t i = 0, L = length(); i < L; ++i) {\n        if (*get(i) < *r->get(i)) return true;\n        if (*get(i) == *r->get(i)) continue;\n        return false;\n      }\n      // Is equal\n      return false;\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool String_Schema::operator== (const Expression& rhs) const\n  {\n    if (auto r = Cast<String_Schema>(&rhs)) {\n      if (length() != r->length()) return false;\n      for (size_t i = 0, L = length(); i < L; ++i) {\n        auto rv = (*r)[i];\n        auto lv = (*this)[i];\n        if (*lv != *rv) return false;\n      }\n      return true;\n    }\n    return false;\n  }\n\n  bool String_Schema::has_interpolants()\n  {\n    for (auto el : elements()) {\n      if (el->is_interpolant()) return true;\n    }\n    return false;\n  }\n\n  size_t String_Schema::hash() const\n  {\n    if (hash_ == 0) {\n      for (auto string : elements())\n        hash_combine(hash_, string->hash());\n    }\n    return hash_;\n  }\n\n  void String_Schema::set_delayed(bool delayed)\n  {\n    is_delayed(delayed);\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  String_Constant::String_Constant(SourceSpan pstate, sass::string val, bool css)\n  : String(pstate), quote_mark_(0), value_(read_css_string(val, css)), hash_(0)\n  { }\n  String_Constant::String_Constant(SourceSpan pstate, const char* beg, bool css)\n  : String(pstate), quote_mark_(0), value_(read_css_string(sass::string(beg), css)), hash_(0)\n  { }\n  String_Constant::String_Constant(SourceSpan pstate, const char* beg, const char* end, bool css)\n  : String(pstate), quote_mark_(0), value_(read_css_string(sass::string(beg, end-beg), css)), hash_(0)\n  { }\n  String_Constant::String_Constant(SourceSpan pstate, const Token& tok, bool css)\n  : String(pstate), quote_mark_(0), value_(read_css_string(sass::string(tok.begin, tok.end), css)), hash_(0)\n  { }\n\n  String_Constant::String_Constant(const String_Constant* ptr)\n  : String(ptr),\n    quote_mark_(ptr->quote_mark_),\n    value_(ptr->value_),\n    hash_(ptr->hash_)\n  { }\n\n  bool String_Constant::is_invisible() const {\n    return value_.empty() && quote_mark_ == 0;\n  }\n\n  bool String_Constant::operator< (const Expression& rhs) const\n  {\n    if (auto qstr = Cast<String_Quoted>(&rhs)) {\n      return value() < qstr->value();\n    }\n    else if (auto cstr = Cast<String_Constant>(&rhs)) {\n      return value() < cstr->value();\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool String_Constant::operator== (const Expression& rhs) const\n  {\n    if (auto qstr = Cast<String_Quoted>(&rhs)) {\n      return value() == qstr->value();\n    }\n    else if (auto cstr = Cast<String_Constant>(&rhs)) {\n      return value() == cstr->value();\n    }\n    return false;\n  }\n\n  sass::string String_Constant::inspect() const\n  {\n    return quote(value_, '*');\n  }\n\n  void String_Constant::rtrim()\n  {\n    str_rtrim(value_);\n  }\n\n  size_t String_Constant::hash() const\n  {\n    if (hash_ == 0) {\n      hash_ = std::hash<sass::string>()(value_);\n    }\n    return hash_;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  String_Quoted::String_Quoted(SourceSpan pstate, sass::string val, char q,\n    bool keep_utf8_escapes, bool skip_unquoting,\n    bool strict_unquoting, bool css)\n  : String_Constant(pstate, val, css)\n  {\n    if (skip_unquoting == false) {\n      value_ = unquote(value_, &quote_mark_, keep_utf8_escapes, strict_unquoting);\n    }\n    if (q && quote_mark_) quote_mark_ = q;\n  }\n\n  String_Quoted::String_Quoted(const String_Quoted* ptr)\n  : String_Constant(ptr)\n  { }\n\n  bool String_Quoted::operator< (const Expression& rhs) const\n  {\n    if (auto qstr = Cast<String_Quoted>(&rhs)) {\n      return value() < qstr->value();\n    }\n    else if (auto cstr = Cast<String_Constant>(&rhs)) {\n      return value() < cstr->value();\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool String_Quoted::operator== (const Expression& rhs) const\n  {\n    if (auto qstr = Cast<String_Quoted>(&rhs)) {\n      return value() == qstr->value();\n    }\n    else if (auto cstr = Cast<String_Constant>(&rhs)) {\n      return value() == cstr->value();\n    }\n    return false;\n  }\n\n  sass::string String_Quoted::inspect() const\n  {\n    return quote(value_, '*');\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Null::Null(SourceSpan pstate)\n  : Value(pstate)\n  { concrete_type(NULL_VAL); }\n\n  Null::Null(const Null* ptr) : Value(ptr)\n  { concrete_type(NULL_VAL); }\n\n  bool Null::operator< (const Expression& rhs) const\n  {\n    if (Cast<Null>(&rhs)) {\n      return false;\n    }\n    // compare/sort by type\n    return type() < rhs.type();\n  }\n\n  bool Null::operator== (const Expression& rhs) const\n  {\n    return Cast<Null>(&rhs) != nullptr;\n  }\n\n  size_t Null::hash() const\n  {\n    return -1;\n  }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  Parent_Reference::Parent_Reference(SourceSpan pstate)\n  : Value(pstate)\n  { concrete_type(PARENT); }\n\n  Parent_Reference::Parent_Reference(const Parent_Reference* ptr)\n  : Value(ptr)\n  { concrete_type(PARENT); }\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n  IMPLEMENT_AST_OPERATORS(List);\n  IMPLEMENT_AST_OPERATORS(Map);\n  IMPLEMENT_AST_OPERATORS(Binary_Expression);\n  IMPLEMENT_AST_OPERATORS(Function);\n  IMPLEMENT_AST_OPERATORS(Function_Call);\n  IMPLEMENT_AST_OPERATORS(Variable);\n  IMPLEMENT_AST_OPERATORS(Number);\n  IMPLEMENT_AST_OPERATORS(Color_RGBA);\n  IMPLEMENT_AST_OPERATORS(Color_HSLA);\n  IMPLEMENT_AST_OPERATORS(Custom_Error);\n  IMPLEMENT_AST_OPERATORS(Custom_Warning);\n  IMPLEMENT_AST_OPERATORS(Boolean);\n  IMPLEMENT_AST_OPERATORS(String_Schema);\n  IMPLEMENT_AST_OPERATORS(String_Constant);\n  IMPLEMENT_AST_OPERATORS(String_Quoted);\n  IMPLEMENT_AST_OPERATORS(Null);\n  IMPLEMENT_AST_OPERATORS(Parent_Reference);\n\n  /////////////////////////////////////////////////////////////////////////\n  /////////////////////////////////////////////////////////////////////////\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ast_values.hpp",
    "content": "#ifndef SASS_AST_VALUES_H\n#define SASS_AST_VALUES_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  //////////////////////////////////////////////////////////////////////\n  // Still just an expression, but with a to_string method\n  //////////////////////////////////////////////////////////////////////\n  class PreValue : public Expression {\n  public:\n    PreValue(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);\n    ATTACH_VIRTUAL_AST_OPERATIONS(PreValue);\n    virtual ~PreValue() { }\n  };\n\n  //////////////////////////////////////////////////////////////////////\n  // base class for values that support operations\n  //////////////////////////////////////////////////////////////////////\n  class Value : public PreValue {\n  public:\n    Value(SourceSpan pstate, bool d = false, bool e = false, bool i = false, Type ct = NONE);\n\n    // Some obects are not meant to be compared\n    // ToDo: maybe fallback to pointer comparison?\n    virtual bool operator< (const Expression& rhs) const override = 0;\n    virtual bool operator== (const Expression& rhs) const override = 0;\n\n    // We can give some reasonable implementations by using\n    // inverst operators on the specialized implementations\n    virtual bool operator> (const Expression& rhs) const {\n      return rhs < *this;\n    }\n    virtual bool operator!= (const Expression& rhs) const {\n      return !(*this == rhs);\n    }\n\n    ATTACH_VIRTUAL_AST_OPERATIONS(Value);\n\n  };\n\n  ///////////////////////////////////////////////////////////////////////\n  // Lists of values, both comma- and space-separated (distinguished by a\n  // type-tag.) Also used to represent variable-length argument lists.\n  ///////////////////////////////////////////////////////////////////////\n  class List : public Value, public Vectorized<ExpressionObj> {\n    void adjust_after_pushing(ExpressionObj e) override { is_expanded(false); }\n  private:\n    ADD_PROPERTY(enum Sass_Separator, separator)\n    ADD_PROPERTY(bool, is_arglist)\n    ADD_PROPERTY(bool, is_bracketed)\n    ADD_PROPERTY(bool, from_selector)\n  public:\n    List(SourceSpan pstate, size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false, bool bracket = false);\n    sass::string type() const override { return is_arglist_ ? \"arglist\" : \"list\"; }\n    static sass::string type_name() { return \"list\"; }\n    const char* sep_string(bool compressed = false) const {\n      return separator() == SASS_SPACE ?\n        \" \" : (compressed ? \",\" : \", \");\n    }\n    bool is_invisible() const override { return empty() && !is_bracketed(); }\n    ExpressionObj value_at_index(size_t i);\n\n    virtual size_t hash() const override;\n    virtual size_t size() const;\n    virtual void set_delayed(bool delayed) override;\n\n    virtual bool operator< (const Expression& rhs) const override;\n    virtual bool operator== (const Expression& rhs) const override;\n\n    ATTACH_AST_OPERATIONS(List)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////////////////////////////////////////////////////\n  // Key value paris.\n  ///////////////////////////////////////////////////////////////////////\n  class Map : public Value, public Hashed<ExpressionObj, ExpressionObj, Map_Obj> {\n    void adjust_after_pushing(std::pair<ExpressionObj, ExpressionObj> p) override { is_expanded(false); }\n  public:\n    Map(SourceSpan pstate, size_t size = 0);\n    sass::string type() const override { return \"map\"; }\n    static sass::string type_name() { return \"map\"; }\n    bool is_invisible() const override { return empty(); }\n    List_Obj to_list(SourceSpan& pstate);\n\n    virtual size_t hash() const override;\n\n    virtual bool operator< (const Expression& rhs) const override;\n    virtual bool operator== (const Expression& rhs) const override;\n\n    ATTACH_AST_OPERATIONS(Map)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n\n  //////////////////////////////////////////////////////////////////////////\n  // Binary expressions. Represents logical, relational, and arithmetic\n  // operations. Templatized to avoid large switch statements and repetitive\n  // subclassing.\n  //////////////////////////////////////////////////////////////////////////\n  class Binary_Expression : public PreValue {\n  private:\n    HASH_PROPERTY(Operand, op)\n    HASH_PROPERTY(ExpressionObj, left)\n    HASH_PROPERTY(ExpressionObj, right)\n    mutable size_t hash_;\n  public:\n    Binary_Expression(SourceSpan pstate,\n                      Operand op, ExpressionObj lhs, ExpressionObj rhs);\n\n    const sass::string type_name();\n    const sass::string separator();\n    bool is_left_interpolant(void) const override;\n    bool is_right_interpolant(void) const override;\n    bool has_interpolant() const override;\n\n    virtual void set_delayed(bool delayed) override;\n\n    virtual bool operator< (const Expression& rhs) const override;\n    virtual bool operator==(const Expression& rhs) const override;\n\n    virtual size_t hash() const override;\n    enum Sass_OP optype() const { return op_.operand; }\n    ATTACH_AST_OPERATIONS(Binary_Expression)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////\n  // Function reference.\n  ////////////////////////////////////////////////////\n  class Function final : public Value {\n  public:\n    ADD_PROPERTY(Definition_Obj, definition)\n    ADD_PROPERTY(bool, is_css)\n  public:\n    Function(SourceSpan pstate, Definition_Obj def, bool css);\n\n    sass::string type() const override { return \"function\"; }\n    static sass::string type_name() { return \"function\"; }\n    bool is_invisible() const override { return true; }\n\n    sass::string name();\n\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n\n    ATTACH_AST_OPERATIONS(Function)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////\n  // Function calls.\n  //////////////////\n  class Function_Call final : public PreValue {\n    HASH_CONSTREF(String_Obj, sname)\n    HASH_PROPERTY(Arguments_Obj, arguments)\n    HASH_PROPERTY(Function_Obj, func)\n    ADD_PROPERTY(bool, via_call)\n    ADD_PROPERTY(void*, cookie)\n    mutable size_t hash_;\n  public:\n    Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, void* cookie);\n    Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args, Function_Obj func);\n    Function_Call(SourceSpan pstate, sass::string n, Arguments_Obj args);\n\n    Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, void* cookie);\n    Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args, Function_Obj func);\n    Function_Call(SourceSpan pstate, String_Obj n, Arguments_Obj args);\n\n    sass::string name() const;\n    bool is_css();\n\n    bool operator==(const Expression& rhs) const override;\n\n    size_t hash() const override;\n\n    ATTACH_AST_OPERATIONS(Function_Call)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ///////////////////////\n  // Variable references.\n  ///////////////////////\n  class Variable final : public PreValue {\n    ADD_CONSTREF(sass::string, name)\n  public:\n    Variable(SourceSpan pstate, sass::string n);\n    virtual bool operator==(const Expression& rhs) const override;\n    virtual size_t hash() const override;\n    ATTACH_AST_OPERATIONS(Variable)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////\n  // Numbers, percentages, dimensions, and colors.\n  ////////////////////////////////////////////////\n  class Number final : public Value, public Units {\n    HASH_PROPERTY(double, value)\n    ADD_PROPERTY(bool, zero)\n    mutable size_t hash_;\n  public:\n    Number(SourceSpan pstate, double val, sass::string u = \"\", bool zero = true);\n\n    bool zero() { return zero_; }\n\n    sass::string type() const override { return \"number\"; }\n    static sass::string type_name() { return \"number\"; }\n\n    // cancel out unnecessary units\n    // result will be in input units\n    void reduce();\n\n    // normalize units to defaults\n    // needed to compare two numbers\n    void normalize();\n\n    size_t hash() const override;\n\n    bool operator< (const Number& rhs) const;\n    bool operator== (const Number& rhs) const;\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n    ATTACH_AST_OPERATIONS(Number)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////\n  // Colors.\n  //////////\n  class Color : public Value {\n    ADD_CONSTREF(sass::string, disp)\n    HASH_PROPERTY(double, a)\n  protected:\n    mutable size_t hash_;\n  public:\n    Color(SourceSpan pstate, double a = 1, const sass::string disp = \"\");\n\n    sass::string type() const override { return \"color\"; }\n    static sass::string type_name() { return \"color\"; }\n\n    virtual size_t hash() const override = 0;\n\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n\n    virtual Color_RGBA* copyAsRGBA() const = 0;\n    virtual Color_RGBA* toRGBA() = 0;\n\n    virtual Color_HSLA* copyAsHSLA() const = 0;\n    virtual Color_HSLA* toHSLA() = 0;\n\n    ATTACH_VIRTUAL_AST_OPERATIONS(Color)\n  };\n\n  //////////\n  // Colors.\n  //////////\n  class Color_RGBA final : public Color {\n    HASH_PROPERTY(double, r)\n    HASH_PROPERTY(double, g)\n    HASH_PROPERTY(double, b)\n  public:\n    Color_RGBA(SourceSpan pstate, double r, double g, double b, double a = 1, const sass::string disp = \"\");\n\n    sass::string type() const override { return \"color\"; }\n    static sass::string type_name() { return \"color\"; }\n\n    size_t hash() const override;\n\n    Color_RGBA* copyAsRGBA() const override;\n    Color_RGBA* toRGBA() override { return this; }\n\n    Color_HSLA* copyAsHSLA() const override;\n    Color_HSLA* toHSLA() override { return copyAsHSLA(); }\n\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n\n    ATTACH_AST_OPERATIONS(Color_RGBA)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n\n  //////////\n  // Colors.\n  //////////\n  class Color_HSLA final : public Color {\n    HASH_PROPERTY(double, h)\n    HASH_PROPERTY(double, s)\n    HASH_PROPERTY(double, l)\n  public:\n    Color_HSLA(SourceSpan pstate, double h, double s, double l, double a = 1, const sass::string disp = \"\");\n\n    sass::string type() const override { return \"color\"; }\n    static sass::string type_name() { return \"color\"; }\n\n    size_t hash() const override;\n\n    Color_RGBA* copyAsRGBA() const override;\n    Color_RGBA* toRGBA() override { return copyAsRGBA(); }\n\n    Color_HSLA* copyAsHSLA() const override;\n    Color_HSLA* toHSLA() override { return this; }\n\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n\n    ATTACH_AST_OPERATIONS(Color_HSLA)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////\n  // Errors from Sass_Values.\n  //////////////////////////////\n  class Custom_Error final : public Value {\n    ADD_CONSTREF(sass::string, message)\n  public:\n    Custom_Error(SourceSpan pstate, sass::string msg);\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n    ATTACH_AST_OPERATIONS(Custom_Error)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////\n  // Warnings from Sass_Values.\n  //////////////////////////////\n  class Custom_Warning final : public Value {\n    ADD_CONSTREF(sass::string, message)\n  public:\n    Custom_Warning(SourceSpan pstate, sass::string msg);\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n    ATTACH_AST_OPERATIONS(Custom_Warning)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////\n  // Booleans.\n  ////////////\n  class Boolean final : public Value {\n    HASH_PROPERTY(bool, value)\n    mutable size_t hash_;\n  public:\n    Boolean(SourceSpan pstate, bool val);\n    operator bool() override { return value_; }\n\n    sass::string type() const override { return \"bool\"; }\n    static sass::string type_name() { return \"bool\"; }\n\n    size_t hash() const override;\n\n    bool is_false() override { return !value_; }\n\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n\n    ATTACH_AST_OPERATIONS(Boolean)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////////////////////\n  // Abstract base class for Sass string values. Includes interpolated and\n  // \"flat\" strings.\n  ////////////////////////////////////////////////////////////////////////\n  class String : public Value {\n  public:\n    String(SourceSpan pstate, bool delayed = false);\n    static sass::string type_name() { return \"string\"; }\n    virtual ~String() = 0;\n    virtual void rtrim() = 0;\n    virtual bool operator<(const Expression& rhs) const override {\n      return this->to_string() < rhs.to_string();\n    };\n    virtual bool operator==(const Expression& rhs) const override {\n      return this->to_string() == rhs.to_string();\n    };\n    ATTACH_VIRTUAL_AST_OPERATIONS(String);\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n  inline String::~String() { };\n\n  ///////////////////////////////////////////////////////////////////////\n  // Interpolated strings. Meant to be reduced to flat strings during the\n  // evaluation phase.\n  ///////////////////////////////////////////////////////////////////////\n  class String_Schema final : public String, public Vectorized<PreValueObj> {\n    ADD_PROPERTY(bool, css)\n    mutable size_t hash_;\n  public:\n    String_Schema(SourceSpan pstate, size_t size = 0, bool css = true);\n\n    sass::string type() const override { return \"string\"; }\n    static sass::string type_name() { return \"string\"; }\n\n    bool is_left_interpolant(void) const override;\n    bool is_right_interpolant(void) const override;\n\n    bool has_interpolants();\n    void rtrim() override;\n    size_t hash() const override;\n    virtual void set_delayed(bool delayed) override;\n\n    bool operator< (const Expression& rhs) const override;\n    bool operator==(const Expression& rhs) const override;\n    ATTACH_AST_OPERATIONS(String_Schema)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////\n  // Flat strings -- the lowest level of raw textual data.\n  ////////////////////////////////////////////////////////\n  class String_Constant : public String {\n    ADD_PROPERTY(char, quote_mark)\n    HASH_CONSTREF(sass::string, value)\n  protected:\n    mutable size_t hash_;\n  public:\n    String_Constant(SourceSpan pstate, sass::string val, bool css = true);\n    String_Constant(SourceSpan pstate, const char* beg, bool css = true);\n    String_Constant(SourceSpan pstate, const char* beg, const char* end, bool css = true);\n    String_Constant(SourceSpan pstate, const Token& tok, bool css = true);\n    sass::string type() const override { return \"string\"; }\n    static sass::string type_name() { return \"string\"; }\n    bool is_invisible() const override;\n    virtual void rtrim() override;\n    size_t hash() const override;\n    bool operator< (const Expression& rhs) const override;\n    bool operator==(const Expression& rhs) const override;\n    // quotes are forced on inspection\n    virtual sass::string inspect() const override;\n    ATTACH_AST_OPERATIONS(String_Constant)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  ////////////////////////////////////////////////////////\n  // Possibly quoted string (unquote on instantiation)\n  ////////////////////////////////////////////////////////\n  class String_Quoted final : public String_Constant {\n  public:\n    String_Quoted(SourceSpan pstate, sass::string val, char q = 0,\n      bool keep_utf8_escapes = false, bool skip_unquoting = false,\n      bool strict_unquoting = true, bool css = true);\n    bool operator< (const Expression& rhs) const override;\n    bool operator==(const Expression& rhs) const override;\n    // quotes are forced on inspection\n    sass::string inspect() const override;\n    ATTACH_AST_OPERATIONS(String_Quoted)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////\n  // The null value.\n  //////////////////\n  class Null final : public Value {\n  public:\n    Null(SourceSpan pstate);\n    sass::string type() const override { return \"null\"; }\n    static sass::string type_name() { return \"null\"; }\n    bool is_invisible() const override { return true; }\n    operator bool() override { return false; }\n    bool is_false() override { return true; }\n\n    size_t hash() const override;\n\n    bool operator< (const Expression& rhs) const override;\n    bool operator== (const Expression& rhs) const override;\n\n    ATTACH_AST_OPERATIONS(Null)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n  //////////////////////////////////\n  // The Parent Reference Expression.\n  //////////////////////////////////\n  class Parent_Reference final : public Value {\n  public:\n    Parent_Reference(SourceSpan pstate);\n    sass::string type() const override { return \"parent\"; }\n    static sass::string type_name() { return \"parent\"; }\n    bool operator< (const Expression& rhs) const override {\n      return false; // they are always equal\n    }\n    bool operator==(const Expression& rhs) const override {\n      return true; // they are always equal\n    };\n    ATTACH_AST_OPERATIONS(Parent_Reference)\n    ATTACH_CRTP_PERFORM_METHODS()\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/b64/cencode.h",
    "content": "/*\ncencode.h - c header for a base64 encoding algorithm\n\nThis is part of the libb64 project, and has been placed in the public domain.\nFor details, see http://sourceforge.net/projects/libb64\n*/\n\n#ifndef BASE64_CENCODE_H\n#define BASE64_CENCODE_H\n\ntypedef enum\n{\n  step_A, step_B, step_C\n} base64_encodestep;\n\ntypedef struct\n{\n\tbase64_encodestep step;\n\tchar result;\n\tint stepcount;\n} base64_encodestate;\n\nvoid base64_init_encodestate(base64_encodestate* state_in);\n\nchar base64_encode_value(char value_in);\n\nint base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);\n\nint base64_encode_blockend(char* code_out, base64_encodestate* state_in);\n\n#endif /* BASE64_CENCODE_H */\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/b64/encode.h",
    "content": "// :mode=c++:\n/*\nencode.h - c++ wrapper for a base64 encoding algorithm\n\nThis is part of the libb64 project, and has been placed in the public domain.\nFor details, see http://sourceforge.net/projects/libb64\n*/\n#ifndef BASE64_ENCODE_H\n#define BASE64_ENCODE_H\n\n#include <iostream>\n\nnamespace base64\n{\n\textern \"C\"\n\t{\n\t\t#include \"cencode.h\"\n\t}\n\n\tstruct encoder\n\t{\n\t\tbase64_encodestate _state;\n\t\tint _buffersize;\n\n\t\tencoder(int buffersize_in = BUFFERSIZE)\n\t\t: _buffersize(buffersize_in)\n\t\t{\n\t\t\tbase64_init_encodestate(&_state);\n\t\t}\n\n\t\tint encode(char value_in)\n\t\t{\n\t\t\treturn base64_encode_value(value_in);\n\t\t}\n\n\t\tint encode(const char* code_in, const int length_in, char* plaintext_out)\n\t\t{\n\t\t\treturn base64_encode_block(code_in, length_in, plaintext_out, &_state);\n\t\t}\n\n\t\tint encode_end(char* plaintext_out)\n\t\t{\n\t\t\treturn base64_encode_blockend(plaintext_out, &_state);\n\t\t}\n\n\t\tvoid encode(std::istream& istream_in, std::ostream& ostream_in)\n\t\t{\n\t\t\tbase64_init_encodestate(&_state);\n\t\t\t//\n\t\t\tconst int N = _buffersize;\n\t\t\tchar* plaintext = new char[N];\n\t\t\tchar* code = new char[2*N];\n\t\t\tint plainlength;\n\t\t\tint codelength;\n\n\t\t\tdo\n\t\t\t{\n\t\t\t\tistream_in.read(plaintext, N);\n\t\t\t\tplainlength = static_cast<int>(istream_in.gcount());\n\t\t\t\t//\n\t\t\t\tcodelength = encode(plaintext, plainlength, code);\n\t\t\t\tostream_in.write(code, codelength);\n\t\t\t}\n\t\t\twhile (istream_in.good() && plainlength > 0);\n\n\t\t\tcodelength = encode_end(code);\n\t\t\tostream_in.write(code, codelength);\n\t\t\t//\n\t\t\tbase64_init_encodestate(&_state);\n\n\t\t\tdelete [] code;\n\t\t\tdelete [] plaintext;\n\t\t}\n\t};\n\n} // namespace base64\n\n#endif // BASE64_ENCODE_H\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/backtrace.cpp",
    "content": "#include \"backtrace.hpp\"\n\nnamespace Sass {\n\n  const sass::string traces_to_string(Backtraces traces, sass::string indent) {\n\n    sass::ostream ss;\n    sass::string cwd(File::get_cwd());\n\n    bool first = true;\n    size_t i_beg = traces.size() - 1;\n    size_t i_end = sass::string::npos;\n    for (size_t i = i_beg; i != i_end; i --) {\n\n      const Backtrace& trace = traces[i];\n\n      // make path relative to the current directory\n      sass::string rel_path(File::abs2rel(trace.pstate.getPath(), cwd, cwd));\n\n      // skip functions on error cases (unsure why ruby sass does this)\n      // if (trace.caller.substr(0, 6) == \", in f\") continue;\n\n      if (first) {\n        ss << indent;\n        ss << \"on line \";\n        ss << trace.pstate.getLine();\n        ss << \":\";\n        ss << trace.pstate.getColumn();\n        ss << \" of \" << rel_path;\n        // ss << trace.caller;\n        first = false;\n      } else {\n        ss << trace.caller;\n        ss << std::endl;\n        ss << indent;\n        ss << \"from line \";\n        ss << trace.pstate.getLine();\n        ss << \":\";\n        ss << trace.pstate.getColumn();\n        ss << \" of \" << rel_path;\n      }\n\n    }\n\n    ss << std::endl;\n    return ss.str();\n\n  }\n\n};\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/backtrace.hpp",
    "content": "#ifndef SASS_BACKTRACE_H\n#define SASS_BACKTRACE_H\n\n#include <vector>\n#include <sstream>\n#include \"file.hpp\"\n#include \"position.hpp\"\n\nnamespace Sass {\n\n  struct Backtrace {\n\n    SourceSpan pstate;\n    sass::string caller;\n\n    Backtrace(SourceSpan pstate, sass::string c = \"\")\n    : pstate(pstate),\n      caller(c)\n    { }\n\n  };\n\n  typedef sass::vector<Backtrace> Backtraces;\n\n  const sass::string traces_to_string(Backtraces traces, sass::string indent = \"\\t\");\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/base64vlq.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"base64vlq.hpp\"\n\nnamespace Sass {\n\n  sass::string Base64VLQ::encode(const int number) const\n  {\n    sass::string encoded = \"\";\n\n    int vlq = to_vlq_signed(number);\n\n    do {\n      int digit = vlq & VLQ_BASE_MASK;\n      vlq >>= VLQ_BASE_SHIFT;\n      if (vlq > 0) {\n        digit |= VLQ_CONTINUATION_BIT;\n      }\n      encoded += base64_encode(digit);\n    } while (vlq > 0);\n\n    return encoded;\n  }\n\n  char Base64VLQ::base64_encode(const int number) const\n  {\n    int index = number;\n    if (index < 0) index = 0;\n    if (index > 63) index = 63;\n    return CHARACTERS[index];\n  }\n\n  int Base64VLQ::to_vlq_signed(const int number) const\n  {\n    return (number < 0) ? ((-number) << 1) + 1 : (number << 1) + 0;\n  }\n\n  const char* Base64VLQ::CHARACTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n  const int Base64VLQ::VLQ_BASE_SHIFT = 5;\n  const int Base64VLQ::VLQ_BASE = 1 << VLQ_BASE_SHIFT;\n  const int Base64VLQ::VLQ_BASE_MASK = VLQ_BASE - 1;\n  const int Base64VLQ::VLQ_CONTINUATION_BIT = VLQ_BASE;\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/base64vlq.hpp",
    "content": "#ifndef SASS_BASE64VLQ_H\n#define SASS_BASE64VLQ_H\n\n#include <string>\n\nnamespace Sass {\n\n  class Base64VLQ {\n\n  public:\n\n    sass::string encode(const int number) const;\n\n  private:\n\n    char base64_encode(const int number) const;\n\n    int to_vlq_signed(const int number) const;\n\n    static const char* CHARACTERS;\n\n    static const int VLQ_BASE_SHIFT;\n    static const int VLQ_BASE;\n    static const int VLQ_BASE_MASK;\n    static const int VLQ_CONTINUATION_BIT;\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/bind.cpp",
    "content": "#include \"sass.hpp\"\n#include \"bind.hpp\"\n#include \"ast.hpp\"\n#include \"backtrace.hpp\"\n#include \"context.hpp\"\n#include \"expand.hpp\"\n#include \"eval.hpp\"\n#include <map>\n#include <iostream>\n#include <sstream>\n\nnamespace Sass {\n\n  void bind(sass::string type, sass::string name, Parameters_Obj ps, Arguments_Obj as, Env* env, Eval* eval, Backtraces& traces)\n  {\n    sass::string callee(type + \" \" + name);\n\n    std::map<sass::string, Parameter_Obj> param_map;\n    List_Obj varargs = SASS_MEMORY_NEW(List, as->pstate());\n    varargs->is_arglist(true); // enable keyword size handling\n\n    for (size_t i = 0, L = as->length(); i < L; ++i) {\n      if (auto str = Cast<String_Quoted>((*as)[i]->value())) {\n        // force optional quotes (only if needed)\n        if (str->quote_mark()) {\n          str->quote_mark('*');\n        }\n      }\n    }\n\n    // Set up a map to ensure named arguments refer to actual parameters. Also\n    // eval each default value left-to-right, wrt env, populating env as we go.\n    for (size_t i = 0, L = ps->length(); i < L; ++i) {\n      Parameter_Obj  p = ps->at(i);\n      param_map[p->name()] = p;\n      // if (p->default_value()) {\n      //   env->local_frame()[p->name()] = p->default_value()->perform(eval->with(env));\n      // }\n    }\n\n    // plug in all args; if we have leftover params, deal with it later\n    size_t ip = 0, LP = ps->length();\n    size_t ia = 0, LA = as->length();\n    while (ia < LA) {\n      Argument_Obj a = as->at(ia);\n      if (ip >= LP) {\n        // skip empty rest arguments\n        if (a->is_rest_argument()) {\n          if (List_Obj l = Cast<List>(a->value())) {\n            if (l->length() == 0) {\n              ++ ia; continue;\n            }\n          }\n        }\n        sass::ostream msg;\n        msg << \"wrong number of arguments (\" << LA << \" for \" << LP << \")\";\n        msg << \" for `\" << name << \"'\";\n        return error(msg.str(), as->pstate(), traces);\n      }\n      Parameter_Obj p = ps->at(ip);\n\n      // If the current parameter is the rest parameter, process and break the loop\n      if (p->is_rest_parameter()) {\n        // The next argument by coincidence provides a rest argument\n        if (a->is_rest_argument()) {\n\n          // We should always get a list for rest arguments\n          if (List_Obj rest = Cast<List>(a->value())) {\n              // create a new list object for wrapped items\n              List* arglist = SASS_MEMORY_NEW(List,\n                                              p->pstate(),\n                                              0,\n                                              rest->separator(),\n                                              true);\n              // wrap each item from list as an argument\n              for (ExpressionObj item : rest->elements()) {\n                if (Argument_Obj arg = Cast<Argument>(item)) {\n                  arglist->append(SASS_MEMORY_COPY(arg)); // copy\n                } else {\n                  arglist->append(SASS_MEMORY_NEW(Argument,\n                                                  item->pstate(),\n                                                  item,\n                                                  \"\",\n                                                  false,\n                                                  false));\n                }\n              }\n              // assign new arglist to environment\n              env->local_frame()[p->name()] = arglist;\n            }\n          // invalid state\n          else {\n            throw std::runtime_error(\"invalid state\");\n          }\n        } else if (a->is_keyword_argument()) {\n\n          // expand keyword arguments into their parameters\n          List* arglist = SASS_MEMORY_NEW(List, p->pstate(), 0, SASS_COMMA, true);\n          env->local_frame()[p->name()] = arglist;\n          Map_Obj argmap = Cast<Map>(a->value());\n          for (auto key : argmap->keys()) {\n            if (String_Constant_Obj str = Cast<String_Constant>(key)) {\n              sass::string param = unquote(str->value());\n              arglist->append(SASS_MEMORY_NEW(Argument,\n                                              key->pstate(),\n                                              argmap->at(key),\n                                              \"$\" + param,\n                                              false,\n                                              false));\n            } else {\n              traces.push_back(Backtrace(key->pstate()));\n              throw Exception::InvalidVarKwdType(key->pstate(), traces, key->inspect(), a);\n            }\n          }\n\n        } else {\n\n          // create a new list object for wrapped items\n          List_Obj arglist = SASS_MEMORY_NEW(List,\n                                          p->pstate(),\n                                          0,\n                                          SASS_COMMA,\n                                          true);\n          // consume the next args\n          while (ia < LA) {\n            // get and post inc\n            a = (*as)[ia++];\n            // maybe we have another list as argument\n            List_Obj ls = Cast<List>(a->value());\n            // skip any list completely if empty\n            if (ls && ls->empty() && a->is_rest_argument()) continue;\n\n            ExpressionObj value = a->value();\n            if (Argument_Obj arg = Cast<Argument>(value)) {\n              arglist->append(arg);\n            }\n            // check if we have rest argument\n            else if (a->is_rest_argument()) {\n              // preserve the list separator from rest args\n              if (List_Obj rest = Cast<List>(a->value())) {\n                arglist->separator(rest->separator());\n\n                for (size_t i = 0, L = rest->length(); i < L; ++i) {\n                  ExpressionObj obj = rest->value_at_index(i);\n                  arglist->append(SASS_MEMORY_NEW(Argument,\n                                                obj->pstate(),\n                                                obj,\n                                                \"\",\n                                                false,\n                                                false));\n                }\n              }\n              // no more arguments\n              break;\n            }\n            // wrap all other value types into Argument\n            else {\n              arglist->append(SASS_MEMORY_NEW(Argument,\n                                            a->pstate(),\n                                            a->value(),\n                                            a->name(),\n                                            false,\n                                            false));\n            }\n          }\n          // assign new arglist to environment\n          env->local_frame()[p->name()] = arglist;\n        }\n        // consumed parameter\n        ++ip;\n        // no more parameters\n        break;\n      }\n\n      // If the current argument is the rest argument, extract a value for processing\n      else if (a->is_rest_argument()) {\n        // normal param and rest arg\n        List_Obj arglist = Cast<List>(a->value());\n        if (!arglist) {\n          if (ExpressionObj arg = Cast<Expression>(a->value())) {\n            arglist = SASS_MEMORY_NEW(List, a->pstate(), 1);\n            arglist->append(arg);\n          }\n        }\n\n        // empty rest arg - treat all args as default values\n        if (!arglist || !arglist->length()) {\n          break;\n        } else {\n          if (arglist->length() > LP - ip && !ps->has_rest_parameter()) {\n            size_t arg_count = (arglist->length() + LA - 1);\n            sass::ostream msg;\n            msg << callee << \" takes \" << LP;\n            msg << (LP == 1 ? \" argument\" : \" arguments\");\n            msg << \" but \" << arg_count;\n            msg << (arg_count == 1 ? \" was passed\" : \" were passed.\");\n            deprecated_bind(msg.str(), as->pstate());\n\n            while (arglist->length() > LP - ip) {\n              arglist->elements().erase(arglist->elements().end() - 1);\n            }\n          }\n        }\n        // otherwise move one of the rest args into the param, converting to argument if necessary\n        ExpressionObj obj = arglist->at(0);\n        if (!(a = Cast<Argument>(obj))) {\n          Expression* a_to_convert = obj;\n          a = SASS_MEMORY_NEW(Argument,\n                              a_to_convert->pstate(),\n                              a_to_convert,\n                              \"\",\n                              false,\n                              false);\n        }\n        arglist->elements().erase(arglist->elements().begin());\n        if (!arglist->length() || (!arglist->is_arglist() && ip + 1 == LP)) {\n          ++ia;\n        }\n\n      } else if (a->is_keyword_argument()) {\n        Map_Obj argmap = Cast<Map>(a->value());\n\n        for (auto key : argmap->keys()) {\n          String_Constant* val = Cast<String_Constant>(key);\n          if (val == NULL) {\n            traces.push_back(Backtrace(key->pstate()));\n            throw Exception::InvalidVarKwdType(key->pstate(), traces, key->inspect(), a);\n          }\n          sass::string param = \"$\" + unquote(val->value());\n\n          if (!param_map.count(param)) {\n            sass::ostream msg;\n            msg << callee << \" has no parameter named \" << param;\n            error(msg.str(), a->pstate(), traces);\n          }\n          env->local_frame()[param] = argmap->at(key);\n        }\n        ++ia;\n        continue;\n      } else {\n        ++ia;\n      }\n\n      if (a->name().empty()) {\n        if (env->has_local(p->name())) {\n          sass::ostream msg;\n          msg << \"parameter \" << p->name()\n          << \" provided more than once in call to \" << callee;\n          error(msg.str(), a->pstate(), traces);\n        }\n        // ordinal arg -- bind it to the next param\n        env->local_frame()[p->name()] = a->value();\n        ++ip;\n      }\n      else {\n        // named arg -- bind it to the appropriately named param\n        if (!param_map.count(a->name())) {\n          if (ps->has_rest_parameter()) {\n            varargs->append(a);\n          } else {\n            sass::ostream msg;\n            msg << callee << \" has no parameter named \" << a->name();\n            error(msg.str(), a->pstate(), traces);\n          }\n        }\n        if (param_map[a->name()]) {\n          if (param_map[a->name()]->is_rest_parameter()) {\n            sass::ostream msg;\n            msg << \"argument \" << a->name() << \" of \" << callee\n                << \"cannot be used as named argument\";\n            error(msg.str(), a->pstate(), traces);\n          }\n        }\n        if (env->has_local(a->name())) {\n          sass::ostream msg;\n          msg << \"parameter \" << p->name()\n              << \"provided more than once in call to \" << callee;\n          error(msg.str(), a->pstate(), traces);\n        }\n        env->local_frame()[a->name()] = a->value();\n      }\n    }\n    // EO while ia\n\n    // If we make it here, we're out of args but may have leftover params.\n    // That's only okay if they have default values, or were already bound by\n    // named arguments, or if it's a single rest-param.\n    for (size_t i = ip; i < LP; ++i) {\n      Parameter_Obj leftover = ps->at(i);\n      // cerr << \"env for default params:\" << endl;\n      // env->print();\n      // cerr << \"********\" << endl;\n      if (!env->has_local(leftover->name())) {\n        if (leftover->is_rest_parameter()) {\n          env->local_frame()[leftover->name()] = varargs;\n        }\n        else if (leftover->default_value()) {\n          Expression* dv = leftover->default_value()->perform(eval);\n          env->local_frame()[leftover->name()] = dv;\n        }\n        else {\n          // param is unbound and has no default value -- error\n          throw Exception::MissingArgument(as->pstate(), traces, name, leftover->name(), type);\n        }\n      }\n    }\n\n    return;\n  }\n\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/bind.hpp",
    "content": "#ifndef SASS_BIND_H\n#define SASS_BIND_H\n\n#include <string>\n#include \"backtrace.hpp\"\n#include \"environment.hpp\"\n#include \"ast_fwd_decl.hpp\"\n\nnamespace Sass {\n\n  void bind(sass::string type, sass::string name, Parameters_Obj, Arguments_Obj, Env*, Eval*, Backtraces& traces);\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/c2ast.cpp",
    "content": "#include \"ast.hpp\"\n#include \"units.hpp\"\n#include \"position.hpp\"\n#include \"backtrace.hpp\"\n#include \"sass/values.h\"\n#include \"ast_fwd_decl.hpp\"\n#include \"error_handling.hpp\"\n\nnamespace Sass {\n\n  Value* c2ast(union Sass_Value* v, Backtraces traces, SourceSpan pstate)\n  {\n    using std::strlen;\n    using std::strcpy;\n    Value* e = NULL;\n    switch (sass_value_get_tag(v)) {\n      case SASS_BOOLEAN: {\n        e = SASS_MEMORY_NEW(Boolean, pstate, !!sass_boolean_get_value(v));\n      } break;\n      case SASS_NUMBER: {\n        e = SASS_MEMORY_NEW(Number, pstate, sass_number_get_value(v), sass_number_get_unit(v));\n      } break;\n      case SASS_COLOR: {\n        e = SASS_MEMORY_NEW(Color_RGBA, pstate, sass_color_get_r(v), sass_color_get_g(v), sass_color_get_b(v), sass_color_get_a(v));\n      } break;\n      case SASS_STRING: {\n        if (sass_string_is_quoted(v))\n          e = SASS_MEMORY_NEW(String_Quoted, pstate, sass_string_get_value(v));\n        else {\n          e = SASS_MEMORY_NEW(String_Constant, pstate, sass_string_get_value(v));\n        }\n      } break;\n      case SASS_LIST: {\n        List* l = SASS_MEMORY_NEW(List, pstate, sass_list_get_length(v), sass_list_get_separator(v));\n        for (size_t i = 0, L = sass_list_get_length(v); i < L; ++i) {\n          l->append(c2ast(sass_list_get_value(v, i), traces, pstate));\n        }\n        l->is_bracketed(sass_list_get_is_bracketed(v));\n        e = l;\n      } break;\n      case SASS_MAP: {\n        Map* m = SASS_MEMORY_NEW(Map, pstate);\n        for (size_t i = 0, L = sass_map_get_length(v); i < L; ++i) {\n          *m << std::make_pair(\n            c2ast(sass_map_get_key(v, i), traces, pstate),\n            c2ast(sass_map_get_value(v, i), traces, pstate));\n        }\n        e = m;\n      } break;\n      case SASS_NULL: {\n        e = SASS_MEMORY_NEW(Null, pstate);\n      } break;\n      case SASS_ERROR: {\n        error(\"Error in C function: \" + sass::string(sass_error_get_message(v)), pstate, traces);\n      } break;\n      case SASS_WARNING: {\n        error(\"Warning in C function: \" + sass::string(sass_warning_get_message(v)), pstate, traces);\n      } break;\n      default: break;\n    }\n    return e;\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/c2ast.hpp",
    "content": "#ifndef SASS_C2AST_H\n#define SASS_C2AST_H\n\n#include \"position.hpp\"\n#include \"backtrace.hpp\"\n#include \"ast_fwd_decl.hpp\"\n\nnamespace Sass {\n\n  Value* c2ast(union Sass_Value* v, Backtraces traces, SourceSpan pstate);\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/c99func.c",
    "content": "/*\n  Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com)\n  All rights reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n*/\n\n#if defined(_MSC_VER) && _MSC_VER < 1900\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n\nstatic int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)\n{\n    int count = -1;\n\n    if (size != 0)\n        count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);\n    if (count == -1)\n        count = _vscprintf(format, ap);\n\n    return count;\n}\n\nint snprintf(char* str, size_t size, const char* format, ...)\n{\n    int count;\n    va_list ap;\n\n    va_start(ap, format);\n    count = c99_vsnprintf(str, size, format, ap);\n    va_end(ap);\n\n    return count;\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/cencode.c",
    "content": "/*\ncencoder.c - c source to a base64 encoding algorithm implementation\n\nThis is part of the libb64 project, and has been placed in the public domain.\nFor details, see http://sourceforge.net/projects/libb64\n*/\n\n#include \"b64/cencode.h\"\n\nvoid base64_init_encodestate(base64_encodestate* state_in)\n{\n\tstate_in->step = step_A;\n\tstate_in->result = 0;\n\tstate_in->stepcount = 0;\n}\n\nchar base64_encode_value(char value_in)\n{\n\tstatic const char* encoding = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\tif (value_in > 63) return '=';\n\treturn encoding[(int)value_in];\n}\n\nint base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)\n{\n\tconst char* plainchar = plaintext_in;\n\tconst char* const plaintextend = plaintext_in + length_in;\n\tchar* codechar = code_out;\n\tchar result;\n\tchar fragment;\n\n\tresult = state_in->result;\n\n\tswitch (state_in->step)\n\t{\n\t\twhile (1)\n\t\t{\n\tcase step_A:\n\t\t\tif (plainchar == plaintextend)\n\t\t\t{\n\t\t\t\tstate_in->result = result;\n\t\t\t\tstate_in->step = step_A;\n\t\t\t\treturn (int)(codechar - code_out);\n\t\t\t}\n\t\t\tfragment = *plainchar++;\n\t\t\tresult = (fragment & 0x0fc) >> 2;\n\t\t\t*codechar++ = base64_encode_value(result);\n\t\t\tresult = (fragment & 0x003) << 4;\n\t\t\t/* fall through */\n\n\tcase step_B:\n\t\t\tif (plainchar == plaintextend)\n\t\t\t{\n\t\t\t\tstate_in->result = result;\n\t\t\t\tstate_in->step = step_B;\n\t\t\t\treturn (int)(codechar - code_out);\n\t\t\t}\n\t\t\tfragment = *plainchar++;\n\t\t\tresult |= (fragment & 0x0f0) >> 4;\n\t\t\t*codechar++ = base64_encode_value(result);\n\t\t\tresult = (fragment & 0x00f) << 2;\n\t\t\t/* fall through */\n\n\tcase step_C:\n\t\t\tif (plainchar == plaintextend)\n\t\t\t{\n\t\t\t\tstate_in->result = result;\n\t\t\t\tstate_in->step = step_C;\n\t\t\t\treturn (int)(codechar - code_out);\n\t\t\t}\n\t\t\tfragment = *plainchar++;\n\t\t\tresult |= (fragment & 0x0c0) >> 6;\n\t\t\t*codechar++ = base64_encode_value(result);\n\t\t\tresult  = (fragment & 0x03f) >> 0;\n\t\t\t*codechar++ = base64_encode_value(result);\n\n\t\t\t++(state_in->stepcount);\n\t\t}\n\t}\n\t/* control should not reach here */\n\treturn (int)(codechar - code_out);\n}\n\nint base64_encode_blockend(char* code_out, base64_encodestate* state_in)\n{\n\tchar* codechar = code_out;\n\n\tswitch (state_in->step)\n\t{\n\tcase step_B:\n\t\t*codechar++ = base64_encode_value(state_in->result);\n\t\t*codechar++ = '=';\n\t\t*codechar++ = '=';\n\t\tbreak;\n\tcase step_C:\n\t\t*codechar++ = base64_encode_value(state_in->result);\n\t\t*codechar++ = '=';\n\t\tbreak;\n\tcase step_A:\n\t\tbreak;\n\t}\n\t*codechar++ = '\\n';\n\n\treturn (int)(codechar - code_out);\n}\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/check_nesting.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n#include \"check_nesting.hpp\"\n\nnamespace Sass {\n\n  CheckNesting::CheckNesting()\n  : parents(sass::vector<Statement*>()),\n    traces(sass::vector<Backtrace>()),\n    parent(0), current_mixin_definition(0)\n  { }\n\n  void error(AST_Node* node, Backtraces traces, sass::string msg) {\n    traces.push_back(Backtrace(node->pstate()));\n    throw Exception::InvalidSass(node->pstate(), traces, msg);\n  }\n\n  Statement* CheckNesting::visit_children(Statement* parent)\n  {\n    Statement* old_parent = this->parent;\n\n    if (AtRootRule* root = Cast<AtRootRule>(parent)) {\n      sass::vector<Statement*> old_parents = this->parents;\n      sass::vector<Statement*> new_parents;\n\n      for (size_t i = 0, L = this->parents.size(); i < L; i++) {\n        Statement* p = this->parents.at(i);\n        if (!root->exclude_node(p)) {\n          new_parents.push_back(p);\n        }\n      }\n      this->parents = new_parents;\n\n      for (size_t i = this->parents.size(); i > 0; i--) {\n        Statement* p = 0;\n        Statement* gp = 0;\n        if (i > 0) p = this->parents.at(i - 1);\n        if (i > 1) gp = this->parents.at(i - 2);\n\n        if (!this->is_transparent_parent(p, gp)) {\n          this->parent = p;\n          break;\n        }\n      }\n\n      AtRootRule* ar = Cast<AtRootRule>(parent);\n      Block* ret = ar->block();\n\n      if (ret != NULL) {\n        for (auto n : ret->elements()) {\n          n->perform(this);\n        }\n      }\n\n      this->parent = old_parent;\n      this->parents = old_parents;\n\n      return ret;\n    }\n\n    if (!this->is_transparent_parent(parent, old_parent)) {\n      this->parent = parent;\n    }\n\n    this->parents.push_back(parent);\n\n    Block* b = Cast<Block>(parent);\n\n    if (Trace* trace = Cast<Trace>(parent)) {\n      if (trace->type() == 'i') {\n        this->traces.push_back(Backtrace(trace->pstate()));\n      }\n    }\n\n    if (!b) {\n      if (ParentStatement* bb = Cast<ParentStatement>(parent)) {\n        b = bb->block();\n      }\n    }\n\n    if (b) {\n      for (auto n : b->elements()) {\n        n->perform(this);\n      }\n    }\n\n    this->parent = old_parent;\n    this->parents.pop_back();\n\n    if (Trace* trace = Cast<Trace>(parent)) {\n      if (trace->type() == 'i') {\n        this->traces.pop_back();\n      }\n    }\n\n    return b;\n  }\n\n\n  Statement* CheckNesting::operator()(Block* b)\n  {\n    return this->visit_children(b);\n  }\n\n  Statement* CheckNesting::operator()(Definition* n)\n  {\n    if (!this->should_visit(n)) return NULL;\n    if (!is_mixin(n)) {\n      visit_children(n);\n      return n;\n    }\n\n    Definition* old_mixin_definition = this->current_mixin_definition;\n    this->current_mixin_definition = n;\n\n    visit_children(n);\n\n    this->current_mixin_definition = old_mixin_definition;\n\n    return n;\n  }\n\n  Statement* CheckNesting::operator()(If* i)\n  {\n    this->visit_children(i);\n\n    if (Block* b = Cast<Block>(i->alternative())) {\n      for (auto n : b->elements()) n->perform(this);\n    }\n\n    return i;\n  }\n\n  bool CheckNesting::should_visit(Statement* node)\n  {\n    if (!this->parent) return true;\n\n    if (Cast<Content>(node))\n    { this->invalid_content_parent(this->parent, node); }\n\n    if (is_charset(node))\n    { this->invalid_charset_parent(this->parent, node); }\n\n    if (Cast<ExtendRule>(node))\n    { this->invalid_extend_parent(this->parent, node); }\n\n    // if (Cast<Import>(node))\n    // { this->invalid_import_parent(this->parent); }\n\n    if (this->is_mixin(node))\n    { this->invalid_mixin_definition_parent(this->parent, node); }\n\n    if (this->is_function(node))\n    { this->invalid_function_parent(this->parent, node); }\n\n    if (this->is_function(this->parent))\n    { this->invalid_function_child(node); }\n\n    if (Declaration* d = Cast<Declaration>(node))\n    {\n      this->invalid_prop_parent(this->parent, node);\n      this->invalid_value_child(d->value());\n    }\n\n    if (Cast<Declaration>(this->parent))\n    { this->invalid_prop_child(node); }\n\n    if (Cast<Return>(node))\n    { this->invalid_return_parent(this->parent, node); }\n\n    return true;\n  }\n\n  void CheckNesting::invalid_content_parent(Statement* parent, AST_Node* node)\n  {\n    if (!this->current_mixin_definition) {\n      error(node, traces, \"@content may only be used within a mixin.\");\n    }\n  }\n\n  void CheckNesting::invalid_charset_parent(Statement* parent, AST_Node* node)\n  {\n    if (!(\n        is_root_node(parent)\n    )) {\n      error(node, traces, \"@charset may only be used at the root of a document.\");\n    }\n  }\n\n  void CheckNesting::invalid_extend_parent(Statement* parent, AST_Node* node)\n  {\n    if (!(\n        Cast<StyleRule>(parent) ||\n        Cast<Mixin_Call>(parent) ||\n        is_mixin(parent)\n    )) {\n      error(node, traces, \"Extend directives may only be used within rules.\");\n    }\n  }\n\n  // void CheckNesting::invalid_import_parent(Statement* parent, AST_Node* node)\n  // {\n  //   for (auto pp : this->parents) {\n  //     if (\n  //         Cast<EachRule>(pp) ||\n  //         Cast<ForRule>(pp) ||\n  //         Cast<If>(pp) ||\n  //         Cast<WhileRule>(pp) ||\n  //         Cast<Trace>(pp) ||\n  //         Cast<Mixin_Call>(pp) ||\n  //         is_mixin(pp)\n  //     ) {\n  //       error(node, traces, \"Import directives may not be defined within control directives or other mixins.\");\n  //     }\n  //   }\n\n  //   if (this->is_root_node(parent)) {\n  //     return;\n  //   }\n\n  //   if (false/*n.css_import?*/) {\n  //     error(node, traces, \"CSS import directives may only be used at the root of a document.\");\n  //   }\n  // }\n\n  void CheckNesting::invalid_mixin_definition_parent(Statement* parent, AST_Node* node)\n  {\n    for (Statement* pp : this->parents) {\n      if (\n          Cast<EachRule>(pp) ||\n          Cast<ForRule>(pp) ||\n          Cast<If>(pp) ||\n          Cast<WhileRule>(pp) ||\n          Cast<Trace>(pp) ||\n          Cast<Mixin_Call>(pp) ||\n          is_mixin(pp)\n      ) {\n        error(node, traces, \"Mixins may not be defined within control directives or other mixins.\");\n      }\n    }\n  }\n\n  void CheckNesting::invalid_function_parent(Statement* parent, AST_Node* node)\n  {\n    for (Statement* pp : this->parents) {\n      if (\n          Cast<EachRule>(pp) ||\n          Cast<ForRule>(pp) ||\n          Cast<If>(pp) ||\n          Cast<WhileRule>(pp) ||\n          Cast<Trace>(pp) ||\n          Cast<Mixin_Call>(pp) ||\n          is_mixin(pp)\n      ) {\n        error(node, traces, \"Functions may not be defined within control directives or other mixins.\");\n      }\n    }\n  }\n\n  void CheckNesting::invalid_function_child(Statement* child)\n  {\n    if (!(\n        Cast<EachRule>(child) ||\n        Cast<ForRule>(child) ||\n        Cast<If>(child) ||\n        Cast<WhileRule>(child) ||\n        Cast<Trace>(child) ||\n        Cast<Comment>(child) ||\n        Cast<DebugRule>(child) ||\n        Cast<Return>(child) ||\n        Cast<Variable>(child) ||\n        // Ruby Sass doesn't distinguish variables and assignments\n        Cast<Assignment>(child) ||\n        Cast<WarningRule>(child) ||\n        Cast<ErrorRule>(child)\n    )) {\n      error(child, traces, \"Functions can only contain variable declarations and control directives.\");\n    }\n  }\n\n  void CheckNesting::invalid_prop_child(Statement* child)\n  {\n    if (!(\n        Cast<EachRule>(child) ||\n        Cast<ForRule>(child) ||\n        Cast<If>(child) ||\n        Cast<WhileRule>(child) ||\n        Cast<Trace>(child) ||\n        Cast<Comment>(child) ||\n        Cast<Declaration>(child) ||\n        Cast<Mixin_Call>(child)\n    )) {\n      error(child, traces, \"Illegal nesting: Only properties may be nested beneath properties.\");\n    }\n  }\n\n  void CheckNesting::invalid_prop_parent(Statement* parent, AST_Node* node)\n  {\n    if (!(\n        is_mixin(parent) ||\n        is_directive_node(parent) ||\n        Cast<StyleRule>(parent) ||\n        Cast<Keyframe_Rule>(parent) ||\n        Cast<Declaration>(parent) ||\n        Cast<Mixin_Call>(parent)\n    )) {\n      error(node, traces, \"Properties are only allowed within rules, directives, mixin includes, or other properties.\");\n    }\n  }\n\n  void CheckNesting::invalid_value_child(AST_Node* d)\n  {\n    if (Map* m = Cast<Map>(d)) {\n      traces.push_back(Backtrace(m->pstate()));\n      throw Exception::InvalidValue(traces, *m);\n    }\n    if (Number* n = Cast<Number>(d)) {\n      if (!n->is_valid_css_unit()) {\n        traces.push_back(Backtrace(n->pstate()));\n        throw Exception::InvalidValue(traces, *n);\n      }\n    }\n\n    // error(dbg + \" isn't a valid CSS value.\", m->pstate(),);\n\n  }\n\n  void CheckNesting::invalid_return_parent(Statement* parent, AST_Node* node)\n  {\n    if (!this->is_function(parent)) {\n      error(node, traces, \"@return may only be used within a function.\");\n    }\n  }\n\n  bool CheckNesting::is_transparent_parent(Statement* parent, Statement* grandparent)\n  {\n    bool parent_bubbles = parent && parent->bubbles();\n\n    bool valid_bubble_node = parent_bubbles &&\n                             !is_root_node(grandparent) &&\n                             !is_at_root_node(grandparent);\n\n    return Cast<Import>(parent) ||\n           Cast<EachRule>(parent) ||\n           Cast<ForRule>(parent) ||\n           Cast<If>(parent) ||\n           Cast<WhileRule>(parent) ||\n           Cast<Trace>(parent) ||\n           valid_bubble_node;\n  }\n\n  bool CheckNesting::is_charset(Statement* n)\n  {\n    AtRule* d = Cast<AtRule>(n);\n    return d && d->keyword() == \"charset\";\n  }\n\n  bool CheckNesting::is_mixin(Statement* n)\n  {\n    Definition* def = Cast<Definition>(n);\n    return def && def->type() == Definition::MIXIN;\n  }\n\n  bool CheckNesting::is_function(Statement* n)\n  {\n    Definition* def = Cast<Definition>(n);\n    return def && def->type() == Definition::FUNCTION;\n  }\n\n  bool CheckNesting::is_root_node(Statement* n)\n  {\n    if (Cast<StyleRule>(n)) return false;\n\n    Block* b = Cast<Block>(n);\n    return b && b->is_root();\n  }\n\n  bool CheckNesting::is_at_root_node(Statement* n)\n  {\n    return Cast<AtRootRule>(n) != NULL;\n  }\n\n  bool CheckNesting::is_directive_node(Statement* n)\n  {\n    return Cast<AtRule>(n) ||\n           Cast<Import>(n) ||\n      Cast<MediaRule>(n) ||\n      Cast<CssMediaRule>(n) ||\n      Cast<SupportsRule>(n);\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/check_nesting.hpp",
    "content": "#ifndef SASS_CHECK_NESTING_H\n#define SASS_CHECK_NESTING_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n#include \"operation.hpp\"\n#include <vector>\n\nnamespace Sass {\n\n  class CheckNesting : public Operation_CRTP<Statement*, CheckNesting> {\n\n    sass::vector<Statement*>  parents;\n    Backtraces                  traces;\n    Statement*               parent;\n    Definition*              current_mixin_definition;\n\n    Statement* before(Statement*);\n    Statement* visit_children(Statement*);\n\n  public:\n    CheckNesting();\n    ~CheckNesting() { }\n\n    Statement* operator()(Block*);\n    Statement* operator()(Definition*);\n    Statement* operator()(If*);\n\n    template <typename U>\n    Statement* fallback(U x) {\n      Statement* s = Cast<Statement>(x);\n      if (s && this->should_visit(s)) {\n        Block* b1 = Cast<Block>(s);\n        ParentStatement* b2 = Cast<ParentStatement>(s);\n        if (b1 || b2) return visit_children(s);\n      }\n      return s;\n    }\n\n  private:\n    void invalid_content_parent(Statement*, AST_Node*);\n    void invalid_charset_parent(Statement*, AST_Node*);\n    void invalid_extend_parent(Statement*, AST_Node*);\n    // void invalid_import_parent(Statement*);\n    void invalid_mixin_definition_parent(Statement*, AST_Node*);\n    void invalid_function_parent(Statement*, AST_Node*);\n\n    void invalid_function_child(Statement*);\n    void invalid_prop_child(Statement*);\n    void invalid_prop_parent(Statement*, AST_Node*);\n    void invalid_return_parent(Statement*, AST_Node*);\n    void invalid_value_child(AST_Node*);\n\n    bool is_transparent_parent(Statement*, Statement*);\n\n    bool should_visit(Statement*);\n\n    bool is_charset(Statement*);\n    bool is_mixin(Statement*);\n    bool is_function(Statement*);\n    bool is_root_node(Statement*);\n    bool is_at_root_node(Statement*);\n    bool is_directive_node(Statement*);\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/color_maps.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast.hpp\"\n#include \"color_maps.hpp\"\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  namespace ColorNames\n  {\n    const char aliceblue [] = \"aliceblue\";\n    const char antiquewhite [] = \"antiquewhite\";\n    const char cyan [] = \"cyan\";\n    const char aqua [] = \"aqua\";\n    const char aquamarine [] = \"aquamarine\";\n    const char azure [] = \"azure\";\n    const char beige [] = \"beige\";\n    const char bisque [] = \"bisque\";\n    const char black [] = \"black\";\n    const char blanchedalmond [] = \"blanchedalmond\";\n    const char blue [] = \"blue\";\n    const char blueviolet [] = \"blueviolet\";\n    const char brown [] = \"brown\";\n    const char burlywood [] = \"burlywood\";\n    const char cadetblue [] = \"cadetblue\";\n    const char chartreuse [] = \"chartreuse\";\n    const char chocolate [] = \"chocolate\";\n    const char coral [] = \"coral\";\n    const char cornflowerblue [] = \"cornflowerblue\";\n    const char cornsilk [] = \"cornsilk\";\n    const char crimson [] = \"crimson\";\n    const char darkblue [] = \"darkblue\";\n    const char darkcyan [] = \"darkcyan\";\n    const char darkgoldenrod [] = \"darkgoldenrod\";\n    const char darkgray [] = \"darkgray\";\n    const char darkgrey [] = \"darkgrey\";\n    const char darkgreen [] = \"darkgreen\";\n    const char darkkhaki [] = \"darkkhaki\";\n    const char darkmagenta [] = \"darkmagenta\";\n    const char darkolivegreen [] = \"darkolivegreen\";\n    const char darkorange [] = \"darkorange\";\n    const char darkorchid [] = \"darkorchid\";\n    const char darkred [] = \"darkred\";\n    const char darksalmon [] = \"darksalmon\";\n    const char darkseagreen [] = \"darkseagreen\";\n    const char darkslateblue [] = \"darkslateblue\";\n    const char darkslategray [] = \"darkslategray\";\n    const char darkslategrey [] = \"darkslategrey\";\n    const char darkturquoise [] = \"darkturquoise\";\n    const char darkviolet [] = \"darkviolet\";\n    const char deeppink [] = \"deeppink\";\n    const char deepskyblue [] = \"deepskyblue\";\n    const char dimgray [] = \"dimgray\";\n    const char dimgrey [] = \"dimgrey\";\n    const char dodgerblue [] = \"dodgerblue\";\n    const char firebrick [] = \"firebrick\";\n    const char floralwhite [] = \"floralwhite\";\n    const char forestgreen [] = \"forestgreen\";\n    const char magenta [] = \"magenta\";\n    const char fuchsia [] = \"fuchsia\";\n    const char gainsboro [] = \"gainsboro\";\n    const char ghostwhite [] = \"ghostwhite\";\n    const char gold [] = \"gold\";\n    const char goldenrod [] = \"goldenrod\";\n    const char gray [] = \"gray\";\n    const char grey [] = \"grey\";\n    const char green [] = \"green\";\n    const char greenyellow [] = \"greenyellow\";\n    const char honeydew [] = \"honeydew\";\n    const char hotpink [] = \"hotpink\";\n    const char indianred [] = \"indianred\";\n    const char indigo [] = \"indigo\";\n    const char ivory [] = \"ivory\";\n    const char khaki [] = \"khaki\";\n    const char lavender [] = \"lavender\";\n    const char lavenderblush [] = \"lavenderblush\";\n    const char lawngreen [] = \"lawngreen\";\n    const char lemonchiffon [] = \"lemonchiffon\";\n    const char lightblue [] = \"lightblue\";\n    const char lightcoral [] = \"lightcoral\";\n    const char lightcyan [] = \"lightcyan\";\n    const char lightgoldenrodyellow [] = \"lightgoldenrodyellow\";\n    const char lightgray [] = \"lightgray\";\n    const char lightgrey [] = \"lightgrey\";\n    const char lightgreen [] = \"lightgreen\";\n    const char lightpink [] = \"lightpink\";\n    const char lightsalmon [] = \"lightsalmon\";\n    const char lightseagreen [] = \"lightseagreen\";\n    const char lightskyblue [] = \"lightskyblue\";\n    const char lightslategray [] = \"lightslategray\";\n    const char lightslategrey [] = \"lightslategrey\";\n    const char lightsteelblue [] = \"lightsteelblue\";\n    const char lightyellow [] = \"lightyellow\";\n    const char lime [] = \"lime\";\n    const char limegreen [] = \"limegreen\";\n    const char linen [] = \"linen\";\n    const char maroon [] = \"maroon\";\n    const char mediumaquamarine [] = \"mediumaquamarine\";\n    const char mediumblue [] = \"mediumblue\";\n    const char mediumorchid [] = \"mediumorchid\";\n    const char mediumpurple [] = \"mediumpurple\";\n    const char mediumseagreen [] = \"mediumseagreen\";\n    const char mediumslateblue [] = \"mediumslateblue\";\n    const char mediumspringgreen [] = \"mediumspringgreen\";\n    const char mediumturquoise [] = \"mediumturquoise\";\n    const char mediumvioletred [] = \"mediumvioletred\";\n    const char midnightblue [] = \"midnightblue\";\n    const char mintcream [] = \"mintcream\";\n    const char mistyrose [] = \"mistyrose\";\n    const char moccasin [] = \"moccasin\";\n    const char navajowhite [] = \"navajowhite\";\n    const char navy [] = \"navy\";\n    const char oldlace [] = \"oldlace\";\n    const char olive [] = \"olive\";\n    const char olivedrab [] = \"olivedrab\";\n    const char orange [] = \"orange\";\n    const char orangered [] = \"orangered\";\n    const char orchid [] = \"orchid\";\n    const char palegoldenrod [] = \"palegoldenrod\";\n    const char palegreen [] = \"palegreen\";\n    const char paleturquoise [] = \"paleturquoise\";\n    const char palevioletred [] = \"palevioletred\";\n    const char papayawhip [] = \"papayawhip\";\n    const char peachpuff [] = \"peachpuff\";\n    const char peru [] = \"peru\";\n    const char pink [] = \"pink\";\n    const char plum [] = \"plum\";\n    const char powderblue [] = \"powderblue\";\n    const char purple [] = \"purple\";\n    const char red [] = \"red\";\n    const char rosybrown [] = \"rosybrown\";\n    const char royalblue [] = \"royalblue\";\n    const char saddlebrown [] = \"saddlebrown\";\n    const char salmon [] = \"salmon\";\n    const char sandybrown [] = \"sandybrown\";\n    const char seagreen [] = \"seagreen\";\n    const char seashell [] = \"seashell\";\n    const char sienna [] = \"sienna\";\n    const char silver [] = \"silver\";\n    const char skyblue [] = \"skyblue\";\n    const char slateblue [] = \"slateblue\";\n    const char slategray [] = \"slategray\";\n    const char slategrey [] = \"slategrey\";\n    const char snow [] = \"snow\";\n    const char springgreen [] = \"springgreen\";\n    const char steelblue [] = \"steelblue\";\n    const char tan [] = \"tan\";\n    const char teal [] = \"teal\";\n    const char thistle [] = \"thistle\";\n    const char tomato [] = \"tomato\";\n    const char turquoise [] = \"turquoise\";\n    const char violet [] = \"violet\";\n    const char wheat [] = \"wheat\";\n    const char white [] = \"white\";\n    const char whitesmoke [] = \"whitesmoke\";\n    const char yellow [] = \"yellow\";\n    const char yellowgreen [] = \"yellowgreen\";\n    const char rebeccapurple [] = \"rebeccapurple\";\n    const char transparent [] = \"transparent\";\n  }\n\n  namespace Colors {\n    const SourceSpan color_table(\"[COLOR TABLE]\");\n    const Color_RGBA aliceblue(color_table, 240, 248, 255, 1);\n    const Color_RGBA antiquewhite(color_table, 250, 235, 215, 1);\n    const Color_RGBA cyan(color_table, 0, 255, 255, 1);\n    const Color_RGBA aqua(color_table, 0, 255, 255, 1);\n    const Color_RGBA aquamarine(color_table, 127, 255, 212, 1);\n    const Color_RGBA azure(color_table, 240, 255, 255, 1);\n    const Color_RGBA beige(color_table, 245, 245, 220, 1);\n    const Color_RGBA bisque(color_table, 255, 228, 196, 1);\n    const Color_RGBA black(color_table, 0, 0, 0, 1);\n    const Color_RGBA blanchedalmond(color_table, 255, 235, 205, 1);\n    const Color_RGBA blue(color_table, 0, 0, 255, 1);\n    const Color_RGBA blueviolet(color_table, 138, 43, 226, 1);\n    const Color_RGBA brown(color_table, 165, 42, 42, 1);\n    const Color_RGBA burlywood(color_table, 222, 184, 135, 1);\n    const Color_RGBA cadetblue(color_table, 95, 158, 160, 1);\n    const Color_RGBA chartreuse(color_table, 127, 255, 0, 1);\n    const Color_RGBA chocolate(color_table, 210, 105, 30, 1);\n    const Color_RGBA coral(color_table, 255, 127, 80, 1);\n    const Color_RGBA cornflowerblue(color_table, 100, 149, 237, 1);\n    const Color_RGBA cornsilk(color_table, 255, 248, 220, 1);\n    const Color_RGBA crimson(color_table, 220, 20, 60, 1);\n    const Color_RGBA darkblue(color_table, 0, 0, 139, 1);\n    const Color_RGBA darkcyan(color_table, 0, 139, 139, 1);\n    const Color_RGBA darkgoldenrod(color_table, 184, 134, 11, 1);\n    const Color_RGBA darkgray(color_table, 169, 169, 169, 1);\n    const Color_RGBA darkgrey(color_table, 169, 169, 169, 1);\n    const Color_RGBA darkgreen(color_table, 0, 100, 0, 1);\n    const Color_RGBA darkkhaki(color_table, 189, 183, 107, 1);\n    const Color_RGBA darkmagenta(color_table, 139, 0, 139, 1);\n    const Color_RGBA darkolivegreen(color_table, 85, 107, 47, 1);\n    const Color_RGBA darkorange(color_table, 255, 140, 0, 1);\n    const Color_RGBA darkorchid(color_table, 153, 50, 204, 1);\n    const Color_RGBA darkred(color_table, 139, 0, 0, 1);\n    const Color_RGBA darksalmon(color_table, 233, 150, 122, 1);\n    const Color_RGBA darkseagreen(color_table, 143, 188, 143, 1);\n    const Color_RGBA darkslateblue(color_table, 72, 61, 139, 1);\n    const Color_RGBA darkslategray(color_table, 47, 79, 79, 1);\n    const Color_RGBA darkslategrey(color_table, 47, 79, 79, 1);\n    const Color_RGBA darkturquoise(color_table, 0, 206, 209, 1);\n    const Color_RGBA darkviolet(color_table, 148, 0, 211, 1);\n    const Color_RGBA deeppink(color_table, 255, 20, 147, 1);\n    const Color_RGBA deepskyblue(color_table, 0, 191, 255, 1);\n    const Color_RGBA dimgray(color_table, 105, 105, 105, 1);\n    const Color_RGBA dimgrey(color_table, 105, 105, 105, 1);\n    const Color_RGBA dodgerblue(color_table, 30, 144, 255, 1);\n    const Color_RGBA firebrick(color_table, 178, 34, 34, 1);\n    const Color_RGBA floralwhite(color_table, 255, 250, 240, 1);\n    const Color_RGBA forestgreen(color_table, 34, 139, 34, 1);\n    const Color_RGBA magenta(color_table, 255, 0, 255, 1);\n    const Color_RGBA fuchsia(color_table, 255, 0, 255, 1);\n    const Color_RGBA gainsboro(color_table, 220, 220, 220, 1);\n    const Color_RGBA ghostwhite(color_table, 248, 248, 255, 1);\n    const Color_RGBA gold(color_table, 255, 215, 0, 1);\n    const Color_RGBA goldenrod(color_table, 218, 165, 32, 1);\n    const Color_RGBA gray(color_table, 128, 128, 128, 1);\n    const Color_RGBA grey(color_table, 128, 128, 128, 1);\n    const Color_RGBA green(color_table, 0, 128, 0, 1);\n    const Color_RGBA greenyellow(color_table, 173, 255, 47, 1);\n    const Color_RGBA honeydew(color_table, 240, 255, 240, 1);\n    const Color_RGBA hotpink(color_table, 255, 105, 180, 1);\n    const Color_RGBA indianred(color_table, 205, 92, 92, 1);\n    const Color_RGBA indigo(color_table, 75, 0, 130, 1);\n    const Color_RGBA ivory(color_table, 255, 255, 240, 1);\n    const Color_RGBA khaki(color_table, 240, 230, 140, 1);\n    const Color_RGBA lavender(color_table, 230, 230, 250, 1);\n    const Color_RGBA lavenderblush(color_table, 255, 240, 245, 1);\n    const Color_RGBA lawngreen(color_table, 124, 252, 0, 1);\n    const Color_RGBA lemonchiffon(color_table, 255, 250, 205, 1);\n    const Color_RGBA lightblue(color_table, 173, 216, 230, 1);\n    const Color_RGBA lightcoral(color_table, 240, 128, 128, 1);\n    const Color_RGBA lightcyan(color_table, 224, 255, 255, 1);\n    const Color_RGBA lightgoldenrodyellow(color_table, 250, 250, 210, 1);\n    const Color_RGBA lightgray(color_table, 211, 211, 211, 1);\n    const Color_RGBA lightgrey(color_table, 211, 211, 211, 1);\n    const Color_RGBA lightgreen(color_table, 144, 238, 144, 1);\n    const Color_RGBA lightpink(color_table, 255, 182, 193, 1);\n    const Color_RGBA lightsalmon(color_table, 255, 160, 122, 1);\n    const Color_RGBA lightseagreen(color_table, 32, 178, 170, 1);\n    const Color_RGBA lightskyblue(color_table, 135, 206, 250, 1);\n    const Color_RGBA lightslategray(color_table, 119, 136, 153, 1);\n    const Color_RGBA lightslategrey(color_table, 119, 136, 153, 1);\n    const Color_RGBA lightsteelblue(color_table, 176, 196, 222, 1);\n    const Color_RGBA lightyellow(color_table, 255, 255, 224, 1);\n    const Color_RGBA lime(color_table, 0, 255, 0, 1);\n    const Color_RGBA limegreen(color_table, 50, 205, 50, 1);\n    const Color_RGBA linen(color_table, 250, 240, 230, 1);\n    const Color_RGBA maroon(color_table, 128, 0, 0, 1);\n    const Color_RGBA mediumaquamarine(color_table, 102, 205, 170, 1);\n    const Color_RGBA mediumblue(color_table, 0, 0, 205, 1);\n    const Color_RGBA mediumorchid(color_table, 186, 85, 211, 1);\n    const Color_RGBA mediumpurple(color_table, 147, 112, 219, 1);\n    const Color_RGBA mediumseagreen(color_table, 60, 179, 113, 1);\n    const Color_RGBA mediumslateblue(color_table, 123, 104, 238, 1);\n    const Color_RGBA mediumspringgreen(color_table, 0, 250, 154, 1);\n    const Color_RGBA mediumturquoise(color_table, 72, 209, 204, 1);\n    const Color_RGBA mediumvioletred(color_table, 199, 21, 133, 1);\n    const Color_RGBA midnightblue(color_table, 25, 25, 112, 1);\n    const Color_RGBA mintcream(color_table, 245, 255, 250, 1);\n    const Color_RGBA mistyrose(color_table, 255, 228, 225, 1);\n    const Color_RGBA moccasin(color_table, 255, 228, 181, 1);\n    const Color_RGBA navajowhite(color_table, 255, 222, 173, 1);\n    const Color_RGBA navy(color_table, 0, 0, 128, 1);\n    const Color_RGBA oldlace(color_table, 253, 245, 230, 1);\n    const Color_RGBA olive(color_table, 128, 128, 0, 1);\n    const Color_RGBA olivedrab(color_table, 107, 142, 35, 1);\n    const Color_RGBA orange(color_table, 255, 165, 0, 1);\n    const Color_RGBA orangered(color_table, 255, 69, 0, 1);\n    const Color_RGBA orchid(color_table, 218, 112, 214, 1);\n    const Color_RGBA palegoldenrod(color_table, 238, 232, 170, 1);\n    const Color_RGBA palegreen(color_table, 152, 251, 152, 1);\n    const Color_RGBA paleturquoise(color_table, 175, 238, 238, 1);\n    const Color_RGBA palevioletred(color_table, 219, 112, 147, 1);\n    const Color_RGBA papayawhip(color_table, 255, 239, 213, 1);\n    const Color_RGBA peachpuff(color_table, 255, 218, 185, 1);\n    const Color_RGBA peru(color_table, 205, 133, 63, 1);\n    const Color_RGBA pink(color_table, 255, 192, 203, 1);\n    const Color_RGBA plum(color_table, 221, 160, 221, 1);\n    const Color_RGBA powderblue(color_table, 176, 224, 230, 1);\n    const Color_RGBA purple(color_table, 128, 0, 128, 1);\n    const Color_RGBA red(color_table, 255, 0, 0, 1);\n    const Color_RGBA rosybrown(color_table, 188, 143, 143, 1);\n    const Color_RGBA royalblue(color_table, 65, 105, 225, 1);\n    const Color_RGBA saddlebrown(color_table, 139, 69, 19, 1);\n    const Color_RGBA salmon(color_table, 250, 128, 114, 1);\n    const Color_RGBA sandybrown(color_table, 244, 164, 96, 1);\n    const Color_RGBA seagreen(color_table, 46, 139, 87, 1);\n    const Color_RGBA seashell(color_table, 255, 245, 238, 1);\n    const Color_RGBA sienna(color_table, 160, 82, 45, 1);\n    const Color_RGBA silver(color_table, 192, 192, 192, 1);\n    const Color_RGBA skyblue(color_table, 135, 206, 235, 1);\n    const Color_RGBA slateblue(color_table, 106, 90, 205, 1);\n    const Color_RGBA slategray(color_table, 112, 128, 144, 1);\n    const Color_RGBA slategrey(color_table, 112, 128, 144, 1);\n    const Color_RGBA snow(color_table, 255, 250, 250, 1);\n    const Color_RGBA springgreen(color_table, 0, 255, 127, 1);\n    const Color_RGBA steelblue(color_table, 70, 130, 180, 1);\n    const Color_RGBA tan(color_table, 210, 180, 140, 1);\n    const Color_RGBA teal(color_table, 0, 128, 128, 1);\n    const Color_RGBA thistle(color_table, 216, 191, 216, 1);\n    const Color_RGBA tomato(color_table, 255, 99, 71, 1);\n    const Color_RGBA turquoise(color_table, 64, 224, 208, 1);\n    const Color_RGBA violet(color_table, 238, 130, 238, 1);\n    const Color_RGBA wheat(color_table, 245, 222, 179, 1);\n    const Color_RGBA white(color_table, 255, 255, 255, 1);\n    const Color_RGBA whitesmoke(color_table, 245, 245, 245, 1);\n    const Color_RGBA yellow(color_table, 255, 255, 0, 1);\n    const Color_RGBA yellowgreen(color_table, 154, 205, 50, 1);\n    const Color_RGBA rebeccapurple(color_table, 102, 51, 153, 1);\n    const Color_RGBA transparent(color_table, 0, 0, 0, 0);\n  }\n\n  static const auto* const colors_to_names = new std::unordered_map<int, const char*> {\n    { 240 * 0x10000 + 248 * 0x100 + 255, ColorNames::aliceblue },\n    { 250 * 0x10000 + 235 * 0x100 + 215, ColorNames::antiquewhite },\n    {   0 * 0x10000 + 255 * 0x100 + 255, ColorNames::cyan },\n    { 127 * 0x10000 + 255 * 0x100 + 212, ColorNames::aquamarine },\n    { 240 * 0x10000 + 255 * 0x100 + 255, ColorNames::azure },\n    { 245 * 0x10000 + 245 * 0x100 + 220, ColorNames::beige },\n    { 255 * 0x10000 + 228 * 0x100 + 196, ColorNames::bisque },\n    {   0 * 0x10000 +   0 * 0x100 +   0, ColorNames::black },\n    { 255 * 0x10000 + 235 * 0x100 + 205, ColorNames::blanchedalmond },\n    {   0 * 0x10000 +   0 * 0x100 + 255, ColorNames::blue },\n    { 138 * 0x10000 +  43 * 0x100 + 226, ColorNames::blueviolet },\n    { 165 * 0x10000 +  42 * 0x100 +  42, ColorNames::brown },\n    { 222 * 0x10000 + 184 * 0x100 + 135, ColorNames::burlywood },\n    {  95 * 0x10000 + 158 * 0x100 + 160, ColorNames::cadetblue },\n    { 127 * 0x10000 + 255 * 0x100 +   0, ColorNames::chartreuse },\n    { 210 * 0x10000 + 105 * 0x100 +  30, ColorNames::chocolate },\n    { 255 * 0x10000 + 127 * 0x100 +  80, ColorNames::coral },\n    { 100 * 0x10000 + 149 * 0x100 + 237, ColorNames::cornflowerblue },\n    { 255 * 0x10000 + 248 * 0x100 + 220, ColorNames::cornsilk },\n    { 220 * 0x10000 +  20 * 0x100 +  60, ColorNames::crimson },\n    {   0 * 0x10000 +   0 * 0x100 + 139, ColorNames::darkblue },\n    {   0 * 0x10000 + 139 * 0x100 + 139, ColorNames::darkcyan },\n    { 184 * 0x10000 + 134 * 0x100 +  11, ColorNames::darkgoldenrod },\n    { 169 * 0x10000 + 169 * 0x100 + 169, ColorNames::darkgray },\n    {   0 * 0x10000 + 100 * 0x100 +   0, ColorNames::darkgreen },\n    { 189 * 0x10000 + 183 * 0x100 + 107, ColorNames::darkkhaki },\n    { 139 * 0x10000 +   0 * 0x100 + 139, ColorNames::darkmagenta },\n    {  85 * 0x10000 + 107 * 0x100 +  47, ColorNames::darkolivegreen },\n    { 255 * 0x10000 + 140 * 0x100 +   0, ColorNames::darkorange },\n    { 153 * 0x10000 +  50 * 0x100 + 204, ColorNames::darkorchid },\n    { 139 * 0x10000 +   0 * 0x100 +   0, ColorNames::darkred },\n    { 233 * 0x10000 + 150 * 0x100 + 122, ColorNames::darksalmon },\n    { 143 * 0x10000 + 188 * 0x100 + 143, ColorNames::darkseagreen },\n    {  72 * 0x10000 +  61 * 0x100 + 139, ColorNames::darkslateblue },\n    {  47 * 0x10000 +  79 * 0x100 +  79, ColorNames::darkslategray },\n    {   0 * 0x10000 + 206 * 0x100 + 209, ColorNames::darkturquoise },\n    { 148 * 0x10000 +   0 * 0x100 + 211, ColorNames::darkviolet },\n    { 255 * 0x10000 +  20 * 0x100 + 147, ColorNames::deeppink },\n    {   0 * 0x10000 + 191 * 0x100 + 255, ColorNames::deepskyblue },\n    { 105 * 0x10000 + 105 * 0x100 + 105, ColorNames::dimgray },\n    {  30 * 0x10000 + 144 * 0x100 + 255, ColorNames::dodgerblue },\n    { 178 * 0x10000 +  34 * 0x100 +  34, ColorNames::firebrick },\n    { 255 * 0x10000 + 250 * 0x100 + 240, ColorNames::floralwhite },\n    {  34 * 0x10000 + 139 * 0x100 +  34, ColorNames::forestgreen },\n    { 255 * 0x10000 +   0 * 0x100 + 255, ColorNames::magenta },\n    { 220 * 0x10000 + 220 * 0x100 + 220, ColorNames::gainsboro },\n    { 248 * 0x10000 + 248 * 0x100 + 255, ColorNames::ghostwhite },\n    { 255 * 0x10000 + 215 * 0x100 +   0, ColorNames::gold },\n    { 218 * 0x10000 + 165 * 0x100 +  32, ColorNames::goldenrod },\n    { 128 * 0x10000 + 128 * 0x100 + 128, ColorNames::gray },\n    {   0 * 0x10000 + 128 * 0x100 +   0, ColorNames::green },\n    { 173 * 0x10000 + 255 * 0x100 +  47, ColorNames::greenyellow },\n    { 240 * 0x10000 + 255 * 0x100 + 240, ColorNames::honeydew },\n    { 255 * 0x10000 + 105 * 0x100 + 180, ColorNames::hotpink },\n    { 205 * 0x10000 +  92 * 0x100 +  92, ColorNames::indianred },\n    {  75 * 0x10000 +   0 * 0x100 + 130, ColorNames::indigo },\n    { 255 * 0x10000 + 255 * 0x100 + 240, ColorNames::ivory },\n    { 240 * 0x10000 + 230 * 0x100 + 140, ColorNames::khaki },\n    { 230 * 0x10000 + 230 * 0x100 + 250, ColorNames::lavender },\n    { 255 * 0x10000 + 240 * 0x100 + 245, ColorNames::lavenderblush },\n    { 124 * 0x10000 + 252 * 0x100 +   0, ColorNames::lawngreen },\n    { 255 * 0x10000 + 250 * 0x100 + 205, ColorNames::lemonchiffon },\n    { 173 * 0x10000 + 216 * 0x100 + 230, ColorNames::lightblue },\n    { 240 * 0x10000 + 128 * 0x100 + 128, ColorNames::lightcoral },\n    { 224 * 0x10000 + 255 * 0x100 + 255, ColorNames::lightcyan },\n    { 250 * 0x10000 + 250 * 0x100 + 210, ColorNames::lightgoldenrodyellow },\n    { 211 * 0x10000 + 211 * 0x100 + 211, ColorNames::lightgray },\n    { 144 * 0x10000 + 238 * 0x100 + 144, ColorNames::lightgreen },\n    { 255 * 0x10000 + 182 * 0x100 + 193, ColorNames::lightpink },\n    { 255 * 0x10000 + 160 * 0x100 + 122, ColorNames::lightsalmon },\n    {  32 * 0x10000 + 178 * 0x100 + 170, ColorNames::lightseagreen },\n    { 135 * 0x10000 + 206 * 0x100 + 250, ColorNames::lightskyblue },\n    { 119 * 0x10000 + 136 * 0x100 + 153, ColorNames::lightslategray },\n    { 176 * 0x10000 + 196 * 0x100 + 222, ColorNames::lightsteelblue },\n    { 255 * 0x10000 + 255 * 0x100 + 224, ColorNames::lightyellow },\n    {   0 * 0x10000 + 255 * 0x100 +   0, ColorNames::lime },\n    {  50 * 0x10000 + 205 * 0x100 +  50, ColorNames::limegreen },\n    { 250 * 0x10000 + 240 * 0x100 + 230, ColorNames::linen },\n    { 128 * 0x10000 +   0 * 0x100 +   0, ColorNames::maroon },\n    { 102 * 0x10000 + 205 * 0x100 + 170, ColorNames::mediumaquamarine },\n    {   0 * 0x10000 +   0 * 0x100 + 205, ColorNames::mediumblue },\n    { 186 * 0x10000 +  85 * 0x100 + 211, ColorNames::mediumorchid },\n    { 147 * 0x10000 + 112 * 0x100 + 219, ColorNames::mediumpurple },\n    {  60 * 0x10000 + 179 * 0x100 + 113, ColorNames::mediumseagreen },\n    { 123 * 0x10000 + 104 * 0x100 + 238, ColorNames::mediumslateblue },\n    {   0 * 0x10000 + 250 * 0x100 + 154, ColorNames::mediumspringgreen },\n    {  72 * 0x10000 + 209 * 0x100 + 204, ColorNames::mediumturquoise },\n    { 199 * 0x10000 +  21 * 0x100 + 133, ColorNames::mediumvioletred },\n    {  25 * 0x10000 +  25 * 0x100 + 112, ColorNames::midnightblue },\n    { 245 * 0x10000 + 255 * 0x100 + 250, ColorNames::mintcream },\n    { 255 * 0x10000 + 228 * 0x100 + 225, ColorNames::mistyrose },\n    { 255 * 0x10000 + 228 * 0x100 + 181, ColorNames::moccasin },\n    { 255 * 0x10000 + 222 * 0x100 + 173, ColorNames::navajowhite },\n    {   0 * 0x10000 +   0 * 0x100 + 128, ColorNames::navy },\n    { 253 * 0x10000 + 245 * 0x100 + 230, ColorNames::oldlace },\n    { 128 * 0x10000 + 128 * 0x100 +   0, ColorNames::olive },\n    { 107 * 0x10000 + 142 * 0x100 +  35, ColorNames::olivedrab },\n    { 255 * 0x10000 + 165 * 0x100 +   0, ColorNames::orange },\n    { 255 * 0x10000 +  69 * 0x100 +   0, ColorNames::orangered },\n    { 218 * 0x10000 + 112 * 0x100 + 214, ColorNames::orchid },\n    { 238 * 0x10000 + 232 * 0x100 + 170, ColorNames::palegoldenrod },\n    { 152 * 0x10000 + 251 * 0x100 + 152, ColorNames::palegreen },\n    { 175 * 0x10000 + 238 * 0x100 + 238, ColorNames::paleturquoise },\n    { 219 * 0x10000 + 112 * 0x100 + 147, ColorNames::palevioletred },\n    { 255 * 0x10000 + 239 * 0x100 + 213, ColorNames::papayawhip },\n    { 255 * 0x10000 + 218 * 0x100 + 185, ColorNames::peachpuff },\n    { 205 * 0x10000 + 133 * 0x100 +  63, ColorNames::peru },\n    { 255 * 0x10000 + 192 * 0x100 + 203, ColorNames::pink },\n    { 221 * 0x10000 + 160 * 0x100 + 221, ColorNames::plum },\n    { 176 * 0x10000 + 224 * 0x100 + 230, ColorNames::powderblue },\n    { 128 * 0x10000 +   0 * 0x100 + 128, ColorNames::purple },\n    { 255 * 0x10000 +   0 * 0x100 +   0, ColorNames::red },\n    { 188 * 0x10000 + 143 * 0x100 + 143, ColorNames::rosybrown },\n    {  65 * 0x10000 + 105 * 0x100 + 225, ColorNames::royalblue },\n    { 139 * 0x10000 +  69 * 0x100 +  19, ColorNames::saddlebrown },\n    { 250 * 0x10000 + 128 * 0x100 + 114, ColorNames::salmon },\n    { 244 * 0x10000 + 164 * 0x100 +  96, ColorNames::sandybrown },\n    {  46 * 0x10000 + 139 * 0x100 +  87, ColorNames::seagreen },\n    { 255 * 0x10000 + 245 * 0x100 + 238, ColorNames::seashell },\n    { 160 * 0x10000 +  82 * 0x100 +  45, ColorNames::sienna },\n    { 192 * 0x10000 + 192 * 0x100 + 192, ColorNames::silver },\n    { 135 * 0x10000 + 206 * 0x100 + 235, ColorNames::skyblue },\n    { 106 * 0x10000 +  90 * 0x100 + 205, ColorNames::slateblue },\n    { 112 * 0x10000 + 128 * 0x100 + 144, ColorNames::slategray },\n    { 255 * 0x10000 + 250 * 0x100 + 250, ColorNames::snow },\n    {   0 * 0x10000 + 255 * 0x100 + 127, ColorNames::springgreen },\n    {  70 * 0x10000 + 130 * 0x100 + 180, ColorNames::steelblue },\n    { 210 * 0x10000 + 180 * 0x100 + 140, ColorNames::tan },\n    {   0 * 0x10000 + 128 * 0x100 + 128, ColorNames::teal },\n    { 216 * 0x10000 + 191 * 0x100 + 216, ColorNames::thistle },\n    { 255 * 0x10000 +  99 * 0x100 +  71, ColorNames::tomato },\n    {  64 * 0x10000 + 224 * 0x100 + 208, ColorNames::turquoise },\n    { 238 * 0x10000 + 130 * 0x100 + 238, ColorNames::violet },\n    { 245 * 0x10000 + 222 * 0x100 + 179, ColorNames::wheat },\n    { 255 * 0x10000 + 255 * 0x100 + 255, ColorNames::white },\n    { 245 * 0x10000 + 245 * 0x100 + 245, ColorNames::whitesmoke },\n    { 255 * 0x10000 + 255 * 0x100 +   0, ColorNames::yellow },\n    { 154 * 0x10000 + 205 * 0x100 +  50, ColorNames::yellowgreen },\n    { 102 * 0x10000 +  51 * 0x100 + 153, ColorNames::rebeccapurple }\n  };\n\n  static const auto *const names_to_colors = new std::unordered_map<sass::string, const Color_RGBA*>\n  {\n    { ColorNames::aliceblue, &Colors::aliceblue },\n    { ColorNames::antiquewhite, &Colors::antiquewhite },\n    { ColorNames::cyan, &Colors::cyan },\n    { ColorNames::aqua, &Colors::aqua },\n    { ColorNames::aquamarine, &Colors::aquamarine },\n    { ColorNames::azure, &Colors::azure },\n    { ColorNames::beige, &Colors::beige },\n    { ColorNames::bisque, &Colors::bisque },\n    { ColorNames::black, &Colors::black },\n    { ColorNames::blanchedalmond, &Colors::blanchedalmond },\n    { ColorNames::blue, &Colors::blue },\n    { ColorNames::blueviolet, &Colors::blueviolet },\n    { ColorNames::brown, &Colors::brown },\n    { ColorNames::burlywood, &Colors::burlywood },\n    { ColorNames::cadetblue, &Colors::cadetblue },\n    { ColorNames::chartreuse, &Colors::chartreuse },\n    { ColorNames::chocolate, &Colors::chocolate },\n    { ColorNames::coral, &Colors::coral },\n    { ColorNames::cornflowerblue, &Colors::cornflowerblue },\n    { ColorNames::cornsilk, &Colors::cornsilk },\n    { ColorNames::crimson, &Colors::crimson },\n    { ColorNames::darkblue, &Colors::darkblue },\n    { ColorNames::darkcyan, &Colors::darkcyan },\n    { ColorNames::darkgoldenrod, &Colors::darkgoldenrod },\n    { ColorNames::darkgray, &Colors::darkgray },\n    { ColorNames::darkgrey, &Colors::darkgrey },\n    { ColorNames::darkgreen, &Colors::darkgreen },\n    { ColorNames::darkkhaki, &Colors::darkkhaki },\n    { ColorNames::darkmagenta, &Colors::darkmagenta },\n    { ColorNames::darkolivegreen, &Colors::darkolivegreen },\n    { ColorNames::darkorange, &Colors::darkorange },\n    { ColorNames::darkorchid, &Colors::darkorchid },\n    { ColorNames::darkred, &Colors::darkred },\n    { ColorNames::darksalmon, &Colors::darksalmon },\n    { ColorNames::darkseagreen, &Colors::darkseagreen },\n    { ColorNames::darkslateblue, &Colors::darkslateblue },\n    { ColorNames::darkslategray, &Colors::darkslategray },\n    { ColorNames::darkslategrey, &Colors::darkslategrey },\n    { ColorNames::darkturquoise, &Colors::darkturquoise },\n    { ColorNames::darkviolet, &Colors::darkviolet },\n    { ColorNames::deeppink, &Colors::deeppink },\n    { ColorNames::deepskyblue, &Colors::deepskyblue },\n    { ColorNames::dimgray, &Colors::dimgray },\n    { ColorNames::dimgrey, &Colors::dimgrey },\n    { ColorNames::dodgerblue, &Colors::dodgerblue },\n    { ColorNames::firebrick, &Colors::firebrick },\n    { ColorNames::floralwhite, &Colors::floralwhite },\n    { ColorNames::forestgreen, &Colors::forestgreen },\n    { ColorNames::magenta, &Colors::magenta },\n    { ColorNames::fuchsia, &Colors::fuchsia },\n    { ColorNames::gainsboro, &Colors::gainsboro },\n    { ColorNames::ghostwhite, &Colors::ghostwhite },\n    { ColorNames::gold, &Colors::gold },\n    { ColorNames::goldenrod, &Colors::goldenrod },\n    { ColorNames::gray, &Colors::gray },\n    { ColorNames::grey, &Colors::grey },\n    { ColorNames::green, &Colors::green },\n    { ColorNames::greenyellow, &Colors::greenyellow },\n    { ColorNames::honeydew, &Colors::honeydew },\n    { ColorNames::hotpink, &Colors::hotpink },\n    { ColorNames::indianred, &Colors::indianred },\n    { ColorNames::indigo, &Colors::indigo },\n    { ColorNames::ivory, &Colors::ivory },\n    { ColorNames::khaki, &Colors::khaki },\n    { ColorNames::lavender, &Colors::lavender },\n    { ColorNames::lavenderblush, &Colors::lavenderblush },\n    { ColorNames::lawngreen, &Colors::lawngreen },\n    { ColorNames::lemonchiffon, &Colors::lemonchiffon },\n    { ColorNames::lightblue, &Colors::lightblue },\n    { ColorNames::lightcoral, &Colors::lightcoral },\n    { ColorNames::lightcyan, &Colors::lightcyan },\n    { ColorNames::lightgoldenrodyellow, &Colors::lightgoldenrodyellow },\n    { ColorNames::lightgray, &Colors::lightgray },\n    { ColorNames::lightgrey, &Colors::lightgrey },\n    { ColorNames::lightgreen, &Colors::lightgreen },\n    { ColorNames::lightpink, &Colors::lightpink },\n    { ColorNames::lightsalmon, &Colors::lightsalmon },\n    { ColorNames::lightseagreen, &Colors::lightseagreen },\n    { ColorNames::lightskyblue, &Colors::lightskyblue },\n    { ColorNames::lightslategray, &Colors::lightslategray },\n    { ColorNames::lightslategrey, &Colors::lightslategrey },\n    { ColorNames::lightsteelblue, &Colors::lightsteelblue },\n    { ColorNames::lightyellow, &Colors::lightyellow },\n    { ColorNames::lime, &Colors::lime },\n    { ColorNames::limegreen, &Colors::limegreen },\n    { ColorNames::linen, &Colors::linen },\n    { ColorNames::maroon, &Colors::maroon },\n    { ColorNames::mediumaquamarine, &Colors::mediumaquamarine },\n    { ColorNames::mediumblue, &Colors::mediumblue },\n    { ColorNames::mediumorchid, &Colors::mediumorchid },\n    { ColorNames::mediumpurple, &Colors::mediumpurple },\n    { ColorNames::mediumseagreen, &Colors::mediumseagreen },\n    { ColorNames::mediumslateblue, &Colors::mediumslateblue },\n    { ColorNames::mediumspringgreen, &Colors::mediumspringgreen },\n    { ColorNames::mediumturquoise, &Colors::mediumturquoise },\n    { ColorNames::mediumvioletred, &Colors::mediumvioletred },\n    { ColorNames::midnightblue, &Colors::midnightblue },\n    { ColorNames::mintcream, &Colors::mintcream },\n    { ColorNames::mistyrose, &Colors::mistyrose },\n    { ColorNames::moccasin, &Colors::moccasin },\n    { ColorNames::navajowhite, &Colors::navajowhite },\n    { ColorNames::navy, &Colors::navy },\n    { ColorNames::oldlace, &Colors::oldlace },\n    { ColorNames::olive, &Colors::olive },\n    { ColorNames::olivedrab, &Colors::olivedrab },\n    { ColorNames::orange, &Colors::orange },\n    { ColorNames::orangered, &Colors::orangered },\n    { ColorNames::orchid, &Colors::orchid },\n    { ColorNames::palegoldenrod, &Colors::palegoldenrod },\n    { ColorNames::palegreen, &Colors::palegreen },\n    { ColorNames::paleturquoise, &Colors::paleturquoise },\n    { ColorNames::palevioletred, &Colors::palevioletred },\n    { ColorNames::papayawhip, &Colors::papayawhip },\n    { ColorNames::peachpuff, &Colors::peachpuff },\n    { ColorNames::peru, &Colors::peru },\n    { ColorNames::pink, &Colors::pink },\n    { ColorNames::plum, &Colors::plum },\n    { ColorNames::powderblue, &Colors::powderblue },\n    { ColorNames::purple, &Colors::purple },\n    { ColorNames::red, &Colors::red },\n    { ColorNames::rosybrown, &Colors::rosybrown },\n    { ColorNames::royalblue, &Colors::royalblue },\n    { ColorNames::saddlebrown, &Colors::saddlebrown },\n    { ColorNames::salmon, &Colors::salmon },\n    { ColorNames::sandybrown, &Colors::sandybrown },\n    { ColorNames::seagreen, &Colors::seagreen },\n    { ColorNames::seashell, &Colors::seashell },\n    { ColorNames::sienna, &Colors::sienna },\n    { ColorNames::silver, &Colors::silver },\n    { ColorNames::skyblue, &Colors::skyblue },\n    { ColorNames::slateblue, &Colors::slateblue },\n    { ColorNames::slategray, &Colors::slategray },\n    { ColorNames::slategrey, &Colors::slategrey },\n    { ColorNames::snow, &Colors::snow },\n    { ColorNames::springgreen, &Colors::springgreen },\n    { ColorNames::steelblue, &Colors::steelblue },\n    { ColorNames::tan, &Colors::tan },\n    { ColorNames::teal, &Colors::teal },\n    { ColorNames::thistle, &Colors::thistle },\n    { ColorNames::tomato, &Colors::tomato },\n    { ColorNames::turquoise, &Colors::turquoise },\n    { ColorNames::violet, &Colors::violet },\n    { ColorNames::wheat, &Colors::wheat },\n    { ColorNames::white, &Colors::white },\n    { ColorNames::whitesmoke, &Colors::whitesmoke },\n    { ColorNames::yellow, &Colors::yellow },\n    { ColorNames::yellowgreen, &Colors::yellowgreen },\n    { ColorNames::rebeccapurple, &Colors::rebeccapurple },\n    { ColorNames::transparent, &Colors::transparent }\n  };\n\n  const Color_RGBA* name_to_color(const char* key)\n  {\n    return name_to_color(sass::string(key));\n  }\n\n  const Color_RGBA* name_to_color(const sass::string& key)\n  {\n    // case insensitive lookup.  See #2462\n    sass::string lower = key;\n    Util::ascii_str_tolower(&lower);\n\n    auto p = names_to_colors->find(lower);\n    if (p != names_to_colors->end()) {\n      return p->second;\n    }\n    return nullptr;\n  }\n\n  const char* color_to_name(const int key)\n  {\n    auto p = colors_to_names->find(key);\n    if (p != colors_to_names->end()) {\n      return p->second;\n    }\n    return nullptr;\n  }\n\n  const char* color_to_name(const double key)\n  {\n    return color_to_name((int)key);\n  }\n\n  const char* color_to_name(const Color_RGBA& c)\n  {\n    double key = c.r() * 0x10000\n               + c.g() * 0x100\n               + c.b();\n    return color_to_name(key);\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/color_maps.hpp",
    "content": "\n#ifndef SASS_COLOR_MAPS_H\n#define SASS_COLOR_MAPS_H\n\n#include <map>\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  namespace ColorNames\n  {\n    extern const char aliceblue[];\n    extern const char antiquewhite[];\n    extern const char cyan[];\n    extern const char aqua[];\n    extern const char aquamarine[];\n    extern const char azure[];\n    extern const char beige[];\n    extern const char bisque[];\n    extern const char black[];\n    extern const char blanchedalmond[];\n    extern const char blue[];\n    extern const char blueviolet[];\n    extern const char brown[];\n    extern const char burlywood[];\n    extern const char cadetblue[];\n    extern const char chartreuse[];\n    extern const char chocolate[];\n    extern const char coral[];\n    extern const char cornflowerblue[];\n    extern const char cornsilk[];\n    extern const char crimson[];\n    extern const char darkblue[];\n    extern const char darkcyan[];\n    extern const char darkgoldenrod[];\n    extern const char darkgray[];\n    extern const char darkgrey[];\n    extern const char darkgreen[];\n    extern const char darkkhaki[];\n    extern const char darkmagenta[];\n    extern const char darkolivegreen[];\n    extern const char darkorange[];\n    extern const char darkorchid[];\n    extern const char darkred[];\n    extern const char darksalmon[];\n    extern const char darkseagreen[];\n    extern const char darkslateblue[];\n    extern const char darkslategray[];\n    extern const char darkslategrey[];\n    extern const char darkturquoise[];\n    extern const char darkviolet[];\n    extern const char deeppink[];\n    extern const char deepskyblue[];\n    extern const char dimgray[];\n    extern const char dimgrey[];\n    extern const char dodgerblue[];\n    extern const char firebrick[];\n    extern const char floralwhite[];\n    extern const char forestgreen[];\n    extern const char magenta[];\n    extern const char fuchsia[];\n    extern const char gainsboro[];\n    extern const char ghostwhite[];\n    extern const char gold[];\n    extern const char goldenrod[];\n    extern const char gray[];\n    extern const char grey[];\n    extern const char green[];\n    extern const char greenyellow[];\n    extern const char honeydew[];\n    extern const char hotpink[];\n    extern const char indianred[];\n    extern const char indigo[];\n    extern const char ivory[];\n    extern const char khaki[];\n    extern const char lavender[];\n    extern const char lavenderblush[];\n    extern const char lawngreen[];\n    extern const char lemonchiffon[];\n    extern const char lightblue[];\n    extern const char lightcoral[];\n    extern const char lightcyan[];\n    extern const char lightgoldenrodyellow[];\n    extern const char lightgray[];\n    extern const char lightgrey[];\n    extern const char lightgreen[];\n    extern const char lightpink[];\n    extern const char lightsalmon[];\n    extern const char lightseagreen[];\n    extern const char lightskyblue[];\n    extern const char lightslategray[];\n    extern const char lightslategrey[];\n    extern const char lightsteelblue[];\n    extern const char lightyellow[];\n    extern const char lime[];\n    extern const char limegreen[];\n    extern const char linen[];\n    extern const char maroon[];\n    extern const char mediumaquamarine[];\n    extern const char mediumblue[];\n    extern const char mediumorchid[];\n    extern const char mediumpurple[];\n    extern const char mediumseagreen[];\n    extern const char mediumslateblue[];\n    extern const char mediumspringgreen[];\n    extern const char mediumturquoise[];\n    extern const char mediumvioletred[];\n    extern const char midnightblue[];\n    extern const char mintcream[];\n    extern const char mistyrose[];\n    extern const char moccasin[];\n    extern const char navajowhite[];\n    extern const char navy[];\n    extern const char oldlace[];\n    extern const char olive[];\n    extern const char olivedrab[];\n    extern const char orange[];\n    extern const char orangered[];\n    extern const char orchid[];\n    extern const char palegoldenrod[];\n    extern const char palegreen[];\n    extern const char paleturquoise[];\n    extern const char palevioletred[];\n    extern const char papayawhip[];\n    extern const char peachpuff[];\n    extern const char peru[];\n    extern const char pink[];\n    extern const char plum[];\n    extern const char powderblue[];\n    extern const char purple[];\n    extern const char red[];\n    extern const char rosybrown[];\n    extern const char royalblue[];\n    extern const char saddlebrown[];\n    extern const char salmon[];\n    extern const char sandybrown[];\n    extern const char seagreen[];\n    extern const char seashell[];\n    extern const char sienna[];\n    extern const char silver[];\n    extern const char skyblue[];\n    extern const char slateblue[];\n    extern const char slategray[];\n    extern const char slategrey[];\n    extern const char snow[];\n    extern const char springgreen[];\n    extern const char steelblue[];\n    extern const char tan[];\n    extern const char teal[];\n    extern const char thistle[];\n    extern const char tomato[];\n    extern const char turquoise[];\n    extern const char violet[];\n    extern const char wheat[];\n    extern const char white[];\n    extern const char whitesmoke[];\n    extern const char yellow[];\n    extern const char yellowgreen[];\n    extern const char rebeccapurple[];\n    extern const char transparent[];\n  }\n\n  namespace Colors {\n    extern const Color_RGBA aliceblue;\n    extern const Color_RGBA antiquewhite;\n    extern const Color_RGBA cyan;\n    extern const Color_RGBA aqua;\n    extern const Color_RGBA aquamarine;\n    extern const Color_RGBA azure;\n    extern const Color_RGBA beige;\n    extern const Color_RGBA bisque;\n    extern const Color_RGBA black;\n    extern const Color_RGBA blanchedalmond;\n    extern const Color_RGBA blue;\n    extern const Color_RGBA blueviolet;\n    extern const Color_RGBA brown;\n    extern const Color_RGBA burlywood;\n    extern const Color_RGBA cadetblue;\n    extern const Color_RGBA chartreuse;\n    extern const Color_RGBA chocolate;\n    extern const Color_RGBA coral;\n    extern const Color_RGBA cornflowerblue;\n    extern const Color_RGBA cornsilk;\n    extern const Color_RGBA crimson;\n    extern const Color_RGBA darkblue;\n    extern const Color_RGBA darkcyan;\n    extern const Color_RGBA darkgoldenrod;\n    extern const Color_RGBA darkgray;\n    extern const Color_RGBA darkgrey;\n    extern const Color_RGBA darkgreen;\n    extern const Color_RGBA darkkhaki;\n    extern const Color_RGBA darkmagenta;\n    extern const Color_RGBA darkolivegreen;\n    extern const Color_RGBA darkorange;\n    extern const Color_RGBA darkorchid;\n    extern const Color_RGBA darkred;\n    extern const Color_RGBA darksalmon;\n    extern const Color_RGBA darkseagreen;\n    extern const Color_RGBA darkslateblue;\n    extern const Color_RGBA darkslategray;\n    extern const Color_RGBA darkslategrey;\n    extern const Color_RGBA darkturquoise;\n    extern const Color_RGBA darkviolet;\n    extern const Color_RGBA deeppink;\n    extern const Color_RGBA deepskyblue;\n    extern const Color_RGBA dimgray;\n    extern const Color_RGBA dimgrey;\n    extern const Color_RGBA dodgerblue;\n    extern const Color_RGBA firebrick;\n    extern const Color_RGBA floralwhite;\n    extern const Color_RGBA forestgreen;\n    extern const Color_RGBA magenta;\n    extern const Color_RGBA fuchsia;\n    extern const Color_RGBA gainsboro;\n    extern const Color_RGBA ghostwhite;\n    extern const Color_RGBA gold;\n    extern const Color_RGBA goldenrod;\n    extern const Color_RGBA gray;\n    extern const Color_RGBA grey;\n    extern const Color_RGBA green;\n    extern const Color_RGBA greenyellow;\n    extern const Color_RGBA honeydew;\n    extern const Color_RGBA hotpink;\n    extern const Color_RGBA indianred;\n    extern const Color_RGBA indigo;\n    extern const Color_RGBA ivory;\n    extern const Color_RGBA khaki;\n    extern const Color_RGBA lavender;\n    extern const Color_RGBA lavenderblush;\n    extern const Color_RGBA lawngreen;\n    extern const Color_RGBA lemonchiffon;\n    extern const Color_RGBA lightblue;\n    extern const Color_RGBA lightcoral;\n    extern const Color_RGBA lightcyan;\n    extern const Color_RGBA lightgoldenrodyellow;\n    extern const Color_RGBA lightgray;\n    extern const Color_RGBA lightgrey;\n    extern const Color_RGBA lightgreen;\n    extern const Color_RGBA lightpink;\n    extern const Color_RGBA lightsalmon;\n    extern const Color_RGBA lightseagreen;\n    extern const Color_RGBA lightskyblue;\n    extern const Color_RGBA lightslategray;\n    extern const Color_RGBA lightslategrey;\n    extern const Color_RGBA lightsteelblue;\n    extern const Color_RGBA lightyellow;\n    extern const Color_RGBA lime;\n    extern const Color_RGBA limegreen;\n    extern const Color_RGBA linen;\n    extern const Color_RGBA maroon;\n    extern const Color_RGBA mediumaquamarine;\n    extern const Color_RGBA mediumblue;\n    extern const Color_RGBA mediumorchid;\n    extern const Color_RGBA mediumpurple;\n    extern const Color_RGBA mediumseagreen;\n    extern const Color_RGBA mediumslateblue;\n    extern const Color_RGBA mediumspringgreen;\n    extern const Color_RGBA mediumturquoise;\n    extern const Color_RGBA mediumvioletred;\n    extern const Color_RGBA midnightblue;\n    extern const Color_RGBA mintcream;\n    extern const Color_RGBA mistyrose;\n    extern const Color_RGBA moccasin;\n    extern const Color_RGBA navajowhite;\n    extern const Color_RGBA navy;\n    extern const Color_RGBA oldlace;\n    extern const Color_RGBA olive;\n    extern const Color_RGBA olivedrab;\n    extern const Color_RGBA orange;\n    extern const Color_RGBA orangered;\n    extern const Color_RGBA orchid;\n    extern const Color_RGBA palegoldenrod;\n    extern const Color_RGBA palegreen;\n    extern const Color_RGBA paleturquoise;\n    extern const Color_RGBA palevioletred;\n    extern const Color_RGBA papayawhip;\n    extern const Color_RGBA peachpuff;\n    extern const Color_RGBA peru;\n    extern const Color_RGBA pink;\n    extern const Color_RGBA plum;\n    extern const Color_RGBA powderblue;\n    extern const Color_RGBA purple;\n    extern const Color_RGBA red;\n    extern const Color_RGBA rosybrown;\n    extern const Color_RGBA royalblue;\n    extern const Color_RGBA saddlebrown;\n    extern const Color_RGBA salmon;\n    extern const Color_RGBA sandybrown;\n    extern const Color_RGBA seagreen;\n    extern const Color_RGBA seashell;\n    extern const Color_RGBA sienna;\n    extern const Color_RGBA silver;\n    extern const Color_RGBA skyblue;\n    extern const Color_RGBA slateblue;\n    extern const Color_RGBA slategray;\n    extern const Color_RGBA slategrey;\n    extern const Color_RGBA snow;\n    extern const Color_RGBA springgreen;\n    extern const Color_RGBA steelblue;\n    extern const Color_RGBA tan;\n    extern const Color_RGBA teal;\n    extern const Color_RGBA thistle;\n    extern const Color_RGBA tomato;\n    extern const Color_RGBA turquoise;\n    extern const Color_RGBA violet;\n    extern const Color_RGBA wheat;\n    extern const Color_RGBA white;\n    extern const Color_RGBA whitesmoke;\n    extern const Color_RGBA yellow;\n    extern const Color_RGBA yellowgreen;\n    extern const Color_RGBA rebeccapurple;\n    extern const Color_RGBA transparent;\n  }\n\n  const Color_RGBA* name_to_color(const char*);\n  const Color_RGBA* name_to_color(const sass::string&);\n  const char* color_to_name(const int);\n  const char* color_to_name(const Color_RGBA&);\n  const char* color_to_name(const double);\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/constants.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"constants.hpp\"\n\nnamespace Sass {\n  namespace Constants {\n\n    extern const unsigned long MaxCallStack = 1024;\n\n    // https://github.com/sass/libsass/issues/592\n    // https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity\n    // https://github.com/sass/sass/issues/1495#issuecomment-61189114\n    extern const unsigned long Specificity_Star = 0;\n    extern const unsigned long Specificity_Universal = 0;\n    extern const unsigned long Specificity_Element = 1;\n    extern const unsigned long Specificity_Base = 1000;\n    extern const unsigned long Specificity_Class = 1000;\n    extern const unsigned long Specificity_Attr = 1000;\n    extern const unsigned long Specificity_Pseudo = 1000;\n    extern const unsigned long Specificity_ID = 1000000;\n\n    extern const int UnificationOrder_Element = 1;\n    extern const int UnificationOrder_Id = 2;\n    extern const int UnificationOrder_Class = 2;\n    extern const int UnificationOrder_Attribute = 3;\n    extern const int UnificationOrder_PseudoClass = 4;\n    extern const int UnificationOrder_Wrapped = 5;\n    extern const int UnificationOrder_PseudoElement = 6;\n    extern const int UnificationOrder_Placeholder = 7;\n\n    // sass keywords\n    extern const char at_root_kwd[]       = \"@at-root\";\n    extern const char import_kwd[]        = \"@import\";\n    extern const char mixin_kwd[]         = \"@mixin\";\n    extern const char function_kwd[]      = \"@function\";\n    extern const char return_kwd[]        = \"@return\";\n    extern const char include_kwd[]       = \"@include\";\n    extern const char content_kwd[]       = \"@content\";\n    extern const char extend_kwd[]        = \"@extend\";\n    extern const char if_kwd[]            = \"@if\";\n    extern const char else_kwd[]          = \"@else\";\n    extern const char if_after_else_kwd[] = \"if\";\n    extern const char for_kwd[]           = \"@for\";\n    extern const char from_kwd[]          = \"from\";\n    extern const char to_kwd[]            = \"to\";\n    extern const char of_kwd[]            = \"of\";\n    extern const char through_kwd[]       = \"through\";\n    extern const char each_kwd[]          = \"@each\";\n    extern const char in_kwd[]            = \"in\";\n    extern const char while_kwd[]         = \"@while\";\n    extern const char warn_kwd[]          = \"@warn\";\n    extern const char error_kwd[]         = \"@error\";\n    extern const char debug_kwd[]         = \"@debug\";\n    extern const char default_kwd[]       = \"default\";\n    extern const char global_kwd[]        = \"global\";\n    extern const char null_kwd[]          = \"null\";\n    extern const char optional_kwd[]      = \"optional\";\n    extern const char with_kwd[]          = \"with\";\n    extern const char without_kwd[]       = \"without\";\n    extern const char all_kwd[]           = \"all\";\n    extern const char rule_kwd[]          = \"rule\";\n\n    // css standard units\n    extern const char em_kwd[]   = \"em\";\n    extern const char ex_kwd[]   = \"ex\";\n    extern const char px_kwd[]   = \"px\";\n    extern const char cm_kwd[]   = \"cm\";\n    extern const char mm_kwd[]   = \"mm\";\n    extern const char pt_kwd[]   = \"pt\";\n    extern const char pc_kwd[]   = \"pc\";\n    extern const char deg_kwd[]  = \"deg\";\n    extern const char rad_kwd[]  = \"rad\";\n    extern const char grad_kwd[] = \"grad\";\n    extern const char turn_kwd[] = \"turn\";\n    extern const char ms_kwd[]   = \"ms\";\n    extern const char s_kwd[]    = \"s\";\n    extern const char Hz_kwd[]   = \"Hz\";\n    extern const char kHz_kwd[]  = \"kHz\";\n\n    // vendor prefixes\n    extern const char vendor_opera_kwd[]    = \"-o-\";\n    extern const char vendor_webkit_kwd[]   = \"-webkit-\";\n    extern const char vendor_mozilla_kwd[]  = \"-moz-\";\n    extern const char vendor_ms_kwd[]       = \"-ms-\";\n    extern const char vendor_khtml_kwd[]    = \"-khtml-\";\n\n    // css functions and keywords\n    extern const char charset_kwd[]      = \"@charset\";\n    extern const char media_kwd[]        = \"@media\";\n    extern const char supports_kwd[]     = \"@supports\";\n    extern const char keyframes_kwd[]    = \"keyframes\";\n    extern const char only_kwd[]         = \"only\";\n    extern const char rgb_fn_kwd[]       = \"rgb(\";\n    extern const char url_fn_kwd[]       = \"url(\";\n    extern const char url_kwd[]          = \"url\";\n    // extern const char url_prefix_fn_kwd[] = \"url-prefix(\";\n    extern const char important_kwd[]    = \"important\";\n    extern const char pseudo_not_fn_kwd[] = \":not(\";\n    extern const char even_kwd[]         = \"even\";\n    extern const char odd_kwd[]          = \"odd\";\n    extern const char progid_kwd[]       = \"progid\";\n    extern const char expression_kwd[]   = \"expression\";\n    extern const char calc_fn_kwd[]      = \"calc\";\n\n    extern const char almost_any_value_class[] = \"\\\"'#!;{}\";\n\n    // css selector keywords\n    extern const char sel_deep_kwd[] = \"/deep/\";\n\n    // css attribute-matching operators\n    extern const char tilde_equal[]  = \"~=\";\n    extern const char pipe_equal[]   = \"|=\";\n    extern const char caret_equal[]  = \"^=\";\n    extern const char dollar_equal[] = \"$=\";\n    extern const char star_equal[]   = \"*=\";\n\n    // relational & logical operators and constants\n    extern const char and_kwd[]   = \"and\";\n    extern const char or_kwd[]    = \"or\";\n    extern const char not_kwd[]   = \"not\";\n    extern const char gt[]        = \">\";\n    extern const char gte[]       = \">=\";\n    extern const char lt[]        = \"<\";\n    extern const char lte[]       = \"<=\";\n    extern const char eq[]        = \"==\";\n    extern const char neq[]       = \"!=\";\n    extern const char true_kwd[]  = \"true\";\n    extern const char false_kwd[] = \"false\";\n\n    // definition keywords\n    extern const char using_kwd[]   = \"using\";\n\n    // miscellaneous punctuation and delimiters\n    extern const char percent_str[]     = \"%\";\n    extern const char empty_str[]       = \"\";\n    extern const char slash_slash[]     = \"//\";\n    extern const char slash_star[]      = \"/*\";\n    extern const char star_slash[]      = \"*/\";\n    extern const char hash_lbrace[]     = \"#{\";\n    extern const char rbrace[]          = \"}\";\n    extern const char rparen[]          = \")\";\n    extern const char sign_chars[]      = \"-+\";\n    extern const char op_chars[]        = \"-+\";\n    extern const char hyphen[]          = \"-\";\n    extern const char ellipsis[]        = \"...\";\n    // extern const char url_space_chars[] = \" \\t\\r\\n\\f\";\n    // type names\n    extern const char numeric_name[]    = \"numeric value\";\n    extern const char number_name[]     = \"number\";\n    extern const char percentage_name[] = \"percentage\";\n    extern const char dimension_name[]  = \"numeric dimension\";\n    extern const char string_name[]     = \"string\";\n    extern const char bool_name[]       = \"bool\";\n    extern const char color_name[]      = \"color\";\n    extern const char list_name[]       = \"list\";\n    extern const char map_name[]        = \"map\";\n    extern const char arglist_name[]    = \"arglist\";\n\n    // constants for uri parsing (RFC 3986 Appendix A.)\n    extern const char uri_chars[]  = \":;/?!%&#@|[]{}'`^\\\"*+-.,_=~\";\n    extern const char real_uri_chars[]  = \"#%&\";\n\n    extern const char selector_combinator_child[] = \">\";\n    extern const char selector_combinator_general[] = \"~\";\n    extern const char selector_combinator_adjacent[] = \"+\";\n\n    // some specific constant character classes\n    // they must be static to be useable by lexer\n    extern const char static_ops[]      = \"*/%\";\n    // some character classes for the parser\n    extern const char selector_list_delims[] = \"){};!\";\n    extern const char complex_selector_delims[] = \",){};!\";\n    extern const char selector_combinator_ops[] = \"+~>\";\n    // optional modifiers for alternative compare context\n    extern const char attribute_compare_modifiers[] = \"~|^$*\";\n    extern const char selector_lookahead_ops[] = \"*&%,()[]\";\n\n    // byte order marks\n    // (taken from http://en.wikipedia.org/wiki/Byte_order_mark)\n    extern const unsigned char utf_8_bom[]      = { 0xEF, 0xBB, 0xBF };\n    extern const unsigned char utf_16_bom_be[]  = { 0xFE, 0xFF };\n    extern const unsigned char utf_16_bom_le[]  = { 0xFF, 0xFE };\n    extern const unsigned char utf_32_bom_be[]  = { 0x00, 0x00, 0xFE, 0xFF };\n    extern const unsigned char utf_32_bom_le[]  = { 0xFF, 0xFE, 0x00, 0x00 };\n    extern const unsigned char utf_7_bom_1[]    = { 0x2B, 0x2F, 0x76, 0x38 };\n    extern const unsigned char utf_7_bom_2[]    = { 0x2B, 0x2F, 0x76, 0x39 };\n    extern const unsigned char utf_7_bom_3[]    = { 0x2B, 0x2F, 0x76, 0x2B };\n    extern const unsigned char utf_7_bom_4[]    = { 0x2B, 0x2F, 0x76, 0x2F };\n    extern const unsigned char utf_7_bom_5[]    = { 0x2B, 0x2F, 0x76, 0x38, 0x2D };\n    extern const unsigned char utf_1_bom[]      = { 0xF7, 0x64, 0x4C };\n    extern const unsigned char utf_ebcdic_bom[] = { 0xDD, 0x73, 0x66, 0x73 };\n    extern const unsigned char scsu_bom[]       = { 0x0E, 0xFE, 0xFF };\n    extern const unsigned char bocu_1_bom[]     = { 0xFB, 0xEE, 0x28 };\n    extern const unsigned char gb_18030_bom[]   = { 0x84, 0x31, 0x95, 0x33 };\n\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/constants.hpp",
    "content": "#ifndef SASS_CONSTANTS_H\n#define SASS_CONSTANTS_H\n\nnamespace Sass {\n  namespace Constants {\n\n    // The maximum call stack that can be created\n    extern const unsigned long MaxCallStack;\n\n    // https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity\n    // The following list of selectors is by increasing specificity:\n    extern const unsigned long Specificity_Star;\n    extern const unsigned long Specificity_Universal;\n    extern const unsigned long Specificity_Element;\n    extern const unsigned long Specificity_Base;\n    extern const unsigned long Specificity_Class;\n    extern const unsigned long Specificity_Attr;\n    extern const unsigned long Specificity_Pseudo;\n    extern const unsigned long Specificity_ID;\n\n    // Selector unification order;\n    extern const int UnificationOrder_Element;\n    extern const int UnificationOrder_Id;\n    extern const int UnificationOrder_Class;\n    extern const int UnificationOrder_Attribute;\n    extern const int UnificationOrder_PseudoClass;\n    extern const int UnificationOrder_Wrapped;\n    extern const int UnificationOrder_PseudoElement;\n    extern const int UnificationOrder_Placeholder;\n\n    // sass keywords\n    extern const char at_root_kwd[];\n    extern const char import_kwd[];\n    extern const char mixin_kwd[];\n    extern const char function_kwd[];\n    extern const char return_kwd[];\n    extern const char include_kwd[];\n    extern const char content_kwd[];\n    extern const char extend_kwd[];\n    extern const char if_kwd[];\n    extern const char else_kwd[];\n    extern const char if_after_else_kwd[];\n    extern const char for_kwd[];\n    extern const char from_kwd[];\n    extern const char to_kwd[];\n    extern const char of_kwd[];\n    extern const char through_kwd[];\n    extern const char each_kwd[];\n    extern const char in_kwd[];\n    extern const char while_kwd[];\n    extern const char warn_kwd[];\n    extern const char error_kwd[];\n    extern const char debug_kwd[];\n    extern const char default_kwd[];\n    extern const char global_kwd[];\n    extern const char null_kwd[];\n    extern const char optional_kwd[];\n    extern const char with_kwd[];\n    extern const char without_kwd[];\n    extern const char all_kwd[];\n    extern const char rule_kwd[];\n\n    // css standard units\n    extern const char em_kwd[];\n    extern const char ex_kwd[];\n    extern const char px_kwd[];\n    extern const char cm_kwd[];\n    extern const char mm_kwd[];\n    extern const char pt_kwd[];\n    extern const char pc_kwd[];\n    extern const char deg_kwd[];\n    extern const char rad_kwd[];\n    extern const char grad_kwd[];\n    extern const char turn_kwd[];\n    extern const char ms_kwd[];\n    extern const char s_kwd[];\n    extern const char Hz_kwd[];\n    extern const char kHz_kwd[];\n\n    // vendor prefixes\n    extern const char vendor_opera_kwd[];\n    extern const char vendor_webkit_kwd[];\n    extern const char vendor_mozilla_kwd[];\n    extern const char vendor_ms_kwd[];\n    extern const char vendor_khtml_kwd[];\n\n    // css functions and keywords\n    extern const char charset_kwd[];\n    extern const char media_kwd[];\n    extern const char supports_kwd[];\n    extern const char keyframes_kwd[];\n    extern const char only_kwd[];\n    extern const char rgb_fn_kwd[];\n    extern const char url_fn_kwd[];\n    extern const char url_kwd[];\n    // extern const char url_prefix_fn_kwd[];\n    extern const char important_kwd[];\n    extern const char pseudo_not_fn_kwd[];\n    extern const char even_kwd[];\n    extern const char odd_kwd[];\n    extern const char progid_kwd[];\n    extern const char expression_kwd[];\n    extern const char calc_fn_kwd[];\n\n    // char classes for \"regular expressions\"\n    extern const char almost_any_value_class[];\n\n    // css selector keywords\n    extern const char sel_deep_kwd[];\n\n    // css attribute-matching operators\n    extern const char tilde_equal[];\n    extern const char pipe_equal[];\n    extern const char caret_equal[];\n    extern const char dollar_equal[];\n    extern const char star_equal[];\n\n    // relational & logical operators and constants\n    extern const char and_kwd[];\n    extern const char or_kwd[];\n    extern const char not_kwd[];\n    extern const char gt[];\n    extern const char gte[];\n    extern const char lt[];\n    extern const char lte[];\n    extern const char eq[];\n    extern const char neq[];\n    extern const char true_kwd[];\n    extern const char false_kwd[];\n\n    // definition keywords\n    extern const char using_kwd[];\n\n    // miscellaneous punctuation and delimiters\n    extern const char percent_str[];\n    extern const char empty_str[];\n    extern const char slash_slash[];\n    extern const char slash_star[];\n    extern const char star_slash[];\n    extern const char hash_lbrace[];\n    extern const char rbrace[];\n    extern const char rparen[];\n    extern const char sign_chars[];\n    extern const char op_chars[];\n    extern const char hyphen[];\n    extern const char ellipsis[];\n    // extern const char url_space_chars[];\n\n    // type names\n    extern const char numeric_name[];\n    extern const char number_name[];\n    extern const char percentage_name[];\n    extern const char dimension_name[];\n    extern const char string_name[];\n    extern const char bool_name[];\n    extern const char color_name[];\n    extern const char list_name[];\n    extern const char map_name[];\n    extern const char arglist_name[];\n\n    // constants for uri parsing (RFC 3986 Appendix A.)\n    extern const char uri_chars[];\n    extern const char real_uri_chars[];\n\n    // constants for selector combinators\n    extern const char selector_combinator_child[];\n    extern const char selector_combinator_general[];\n    extern const char selector_combinator_adjacent[];\n\n    // some specific constant character classes\n    // they must be static to be useable by lexer\n    extern const char static_ops[];\n    extern const char selector_list_delims[];\n    extern const char complex_selector_delims[];\n    extern const char selector_combinator_ops[];\n    extern const char attribute_compare_modifiers[];\n    extern const char selector_lookahead_ops[];\n\n    // byte order marks\n    // (taken from http://en.wikipedia.org/wiki/Byte_order_mark)\n    extern const unsigned char utf_8_bom[];\n    extern const unsigned char utf_16_bom_be[];\n    extern const unsigned char utf_16_bom_le[];\n    extern const unsigned char utf_32_bom_be[];\n    extern const unsigned char utf_32_bom_le[];\n    extern const unsigned char utf_7_bom_1[];\n    extern const unsigned char utf_7_bom_2[];\n    extern const unsigned char utf_7_bom_3[];\n    extern const unsigned char utf_7_bom_4[];\n    extern const unsigned char utf_7_bom_5[];\n    extern const unsigned char utf_1_bom[];\n    extern const unsigned char utf_ebcdic_bom[];\n    extern const unsigned char scsu_bom[];\n    extern const unsigned char bocu_1_bom[];\n    extern const unsigned char gb_18030_bom[];\n\n  }\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/context.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\n#include \"remove_placeholders.hpp\"\n#include \"sass_functions.hpp\"\n#include \"check_nesting.hpp\"\n#include \"fn_selectors.hpp\"\n#include \"fn_strings.hpp\"\n#include \"fn_numbers.hpp\"\n#include \"fn_colors.hpp\"\n#include \"fn_miscs.hpp\"\n#include \"fn_lists.hpp\"\n#include \"fn_maps.hpp\"\n#include \"context.hpp\"\n#include \"expand.hpp\"\n#include \"parser.hpp\"\n#include \"cssize.hpp\"\n#include \"source.hpp\"\n\nnamespace Sass {\n  using namespace Constants;\n  using namespace File;\n  using namespace Sass;\n\n  inline bool sort_importers (const Sass_Importer_Entry& i, const Sass_Importer_Entry& j)\n  { return sass_importer_get_priority(i) > sass_importer_get_priority(j); }\n\n  static sass::string safe_input(const char* in_path)\n  {\n    if (in_path == nullptr || in_path[0] == '\\0') return \"stdin\";\n    return in_path;\n  }\n\n  static sass::string safe_output(const char* out_path, sass::string input_path)\n  {\n    if (out_path == nullptr || out_path[0] == '\\0') {\n      if (input_path.empty()) return \"stdout\";\n      return input_path.substr(0, input_path.find_last_of(\".\")) + \".css\";\n    }\n    return out_path;\n  }\n\n  Context::Context(struct Sass_Context& c_ctx)\n  : CWD(File::get_cwd()),\n    c_options(c_ctx),\n    entry_path(\"\"),\n    head_imports(0),\n    plugins(),\n    emitter(c_options),\n\n    ast_gc(),\n    strings(),\n    resources(),\n    sheets(),\n    import_stack(),\n    callee_stack(),\n    traces(),\n    extender(Extender::NORMAL, traces),\n    c_compiler(NULL),\n\n    c_headers               (sass::vector<Sass_Importer_Entry>()),\n    c_importers             (sass::vector<Sass_Importer_Entry>()),\n    c_functions             (sass::vector<Sass_Function_Entry>()),\n\n    indent                  (safe_str(c_options.indent, \"  \")),\n    linefeed                (safe_str(c_options.linefeed, \"\\n\")),\n\n    input_path              (make_canonical_path(safe_input(c_options.input_path))),\n    output_path             (make_canonical_path(safe_output(c_options.output_path, input_path))),\n    source_map_file         (make_canonical_path(safe_str(c_options.source_map_file, \"\"))),\n    source_map_root         (make_canonical_path(safe_str(c_options.source_map_root, \"\")))\n\n  {\n\n    // Sass 3.4: The current working directory will no longer be placed onto the Sass load path by default.\n    // If you need the current working directory to be available, set SASS_PATH=. in your shell's environment.\n    // include_paths.push_back(CWD);\n\n    // collect more paths from different options\n    collect_include_paths(c_options.include_path);\n    collect_include_paths(c_options.include_paths);\n    collect_plugin_paths(c_options.plugin_path);\n    collect_plugin_paths(c_options.plugin_paths);\n\n    // load plugins and register custom behaviors\n    for(auto plug : plugin_paths) plugins.load_plugins(plug);\n    for(auto fn : plugins.get_headers()) c_headers.push_back(fn);\n    for(auto fn : plugins.get_importers()) c_importers.push_back(fn);\n    for(auto fn : plugins.get_functions()) c_functions.push_back(fn);\n\n    // sort the items by priority (lowest first)\n    sort (c_headers.begin(), c_headers.end(), sort_importers);\n    sort (c_importers.begin(), c_importers.end(), sort_importers);\n\n    emitter.set_filename(abs2rel(output_path, source_map_file, CWD));\n\n  }\n\n  void Context::add_c_function(Sass_Function_Entry function)\n  {\n    c_functions.push_back(function);\n  }\n  void Context::add_c_header(Sass_Importer_Entry header)\n  {\n    c_headers.push_back(header);\n    // need to sort the array afterwards (no big deal)\n    sort (c_headers.begin(), c_headers.end(), sort_importers);\n  }\n  void Context::add_c_importer(Sass_Importer_Entry importer)\n  {\n    c_importers.push_back(importer);\n    // need to sort the array afterwards (no big deal)\n    sort (c_importers.begin(), c_importers.end(), sort_importers);\n  }\n\n  Context::~Context()\n  {\n    // resources were allocated by malloc\n    for (size_t i = 0; i < resources.size(); ++i) {\n      free(resources[i].contents);\n      free(resources[i].srcmap);\n    }\n    // free all strings we kept alive during compiler execution\n    for (size_t n = 0; n < strings.size(); ++n) free(strings[n]);\n    // everything that gets put into sources will be freed by us\n    // this shouldn't have anything in it anyway!?\n    for (size_t m = 0; m < import_stack.size(); ++m) {\n      sass_import_take_source(import_stack[m]);\n      sass_import_take_srcmap(import_stack[m]);\n      sass_delete_import(import_stack[m]);\n    }\n    // clear inner structures (vectors) and input source\n    resources.clear(); import_stack.clear();\n    sheets.clear();\n  }\n\n  Data_Context::~Data_Context()\n  {\n    // --> this will be freed by resources\n    // make sure we free the source even if not processed!\n    // if (resources.size() == 0 && source_c_str) free(source_c_str);\n    // if (resources.size() == 0 && srcmap_c_str) free(srcmap_c_str);\n    // source_c_str = 0; srcmap_c_str = 0;\n  }\n\n  File_Context::~File_Context()\n  {\n  }\n\n  void Context::collect_include_paths(const char* paths_str)\n  {\n    if (paths_str) {\n      const char* beg = paths_str;\n      const char* end = Prelexer::find_first<PATH_SEP>(beg);\n\n      while (end) {\n        sass::string path(beg, end - beg);\n        if (!path.empty()) {\n          if (*path.rbegin() != '/') path += '/';\n          include_paths.push_back(path);\n        }\n        beg = end + 1;\n        end = Prelexer::find_first<PATH_SEP>(beg);\n      }\n\n      sass::string path(beg);\n      if (!path.empty()) {\n        if (*path.rbegin() != '/') path += '/';\n        include_paths.push_back(path);\n      }\n    }\n  }\n\n  void Context::collect_include_paths(string_list* paths_array)\n  {\n    while (paths_array)\n    {\n      collect_include_paths(paths_array->string);\n      paths_array = paths_array->next;\n    }\n  }\n\n  void Context::collect_plugin_paths(const char* paths_str)\n  {\n    if (paths_str) {\n      const char* beg = paths_str;\n      const char* end = Prelexer::find_first<PATH_SEP>(beg);\n\n      while (end) {\n        sass::string path(beg, end - beg);\n        if (!path.empty()) {\n          if (*path.rbegin() != '/') path += '/';\n          plugin_paths.push_back(path);\n        }\n        beg = end + 1;\n        end = Prelexer::find_first<PATH_SEP>(beg);\n      }\n\n      sass::string path(beg);\n      if (!path.empty()) {\n        if (*path.rbegin() != '/') path += '/';\n        plugin_paths.push_back(path);\n      }\n    }\n  }\n\n  void Context::collect_plugin_paths(string_list* paths_array)\n  {\n    while (paths_array)\n    {\n      collect_plugin_paths(paths_array->string);\n      paths_array = paths_array->next;\n    }\n  }\n\n  // resolve the imp_path in base_path or include_paths\n  // looks for alternatives and returns a list from one directory\n  sass::vector<Include> Context::find_includes(const Importer& import)\n  {\n    // make sure we resolve against an absolute path\n    sass::string base_path(rel2abs(import.base_path));\n    // first try to resolve the load path relative to the base path\n    sass::vector<Include> vec(resolve_includes(base_path, import.imp_path));\n    // then search in every include path (but only if nothing found yet)\n    for (size_t i = 0, S = include_paths.size(); vec.size() == 0 && i < S; ++i)\n    {\n      // call resolve_includes and individual base path and append all results\n      sass::vector<Include> resolved(resolve_includes(include_paths[i], import.imp_path));\n      if (resolved.size()) vec.insert(vec.end(), resolved.begin(), resolved.end());\n    }\n    // return vector\n    return vec;\n  }\n\n  // register include with resolved path and its content\n  // memory of the resources will be freed by us on exit\n  void Context::register_resource(const Include& inc, const Resource& res)\n  {\n\n    // do not parse same resource twice\n    // maybe raise an error in this case\n    // if (sheets.count(inc.abs_path)) {\n    //   free(res.contents); free(res.srcmap);\n    //   throw std::runtime_error(\"duplicate resource registered\");\n    //   return;\n    // }\n\n    // get index for this resource\n    size_t idx = resources.size();\n\n    // tell emitter about new resource\n    emitter.add_source_index(idx);\n\n    // put resources under our control\n    // the memory will be freed later\n    resources.push_back(res);\n\n    // add a relative link to the working directory\n    included_files.push_back(inc.abs_path);\n    // add a relative link  to the source map output file\n    srcmap_links.push_back(abs2rel(inc.abs_path, source_map_file, CWD));\n\n    // get pointer to the loaded content\n    Sass_Import_Entry import = sass_make_import(\n      inc.imp_path.c_str(),\n      inc.abs_path.c_str(),\n      res.contents,\n      res.srcmap\n    );\n    // add the entry to the stack\n    import_stack.push_back(import);\n\n    // get pointer to the loaded content\n    const char* contents = resources[idx].contents;\n    SourceFileObj source = SASS_MEMORY_NEW(SourceFile,\n      inc.abs_path.c_str(), contents, idx);\n\n    // create the initial parser state from resource\n    SourceSpan pstate(source);\n\n    // check existing import stack for possible recursion\n    for (size_t i = 0; i < import_stack.size() - 2; ++i) {\n      auto parent = import_stack[i];\n      if (std::strcmp(parent->abs_path, import->abs_path) == 0) {\n        sass::string cwd(File::get_cwd());\n        // make path relative to the current directory\n        sass::string stack(\"An @import loop has been found:\");\n        for (size_t n = 1; n < i + 2; ++n) {\n          stack += \"\\n    \" + sass::string(File::abs2rel(import_stack[n]->abs_path, cwd, cwd)) +\n            \" imports \" + sass::string(File::abs2rel(import_stack[n+1]->abs_path, cwd, cwd));\n        }\n        // implement error throw directly until we\n        // decided how to handle full stack traces\n        throw Exception::InvalidSyntax(pstate, traces, stack);\n        // error(stack, prstate ? *prstate : pstate, import_stack);\n      }\n    }\n\n    // create a parser instance from the given c_str buffer\n    Parser p(source, *this, traces);\n    // do not yet dispose these buffers\n    sass_import_take_source(import);\n    sass_import_take_srcmap(import);\n    // then parse the root block\n    Block_Obj root = p.parse();\n    // delete memory of current stack frame\n    sass_delete_import(import_stack.back());\n    // remove current stack frame\n    import_stack.pop_back();\n    // create key/value pair for ast node\n    std::pair<const sass::string, StyleSheet>\n      ast_pair(inc.abs_path, { res, root });\n    // register resulting resource\n    sheets.insert(ast_pair);\n  }\n\n  // register include with resolved path and its content\n  // memory of the resources will be freed by us on exit\n  void Context::register_resource(const Include& inc, const Resource& res, SourceSpan& prstate)\n  {\n    traces.push_back(Backtrace(prstate));\n    register_resource(inc, res);\n    traces.pop_back();\n  }\n\n  // Add a new import to the context (called from `import_url`)\n  Include Context::load_import(const Importer& imp, SourceSpan pstate)\n  {\n\n    // search for valid imports (ie. partials) on the filesystem\n    // this may return more than one valid result (ambiguous imp_path)\n    const sass::vector<Include> resolved(find_includes(imp));\n\n    // error nicely on ambiguous imp_path\n    if (resolved.size() > 1) {\n      sass::ostream msg_stream;\n      msg_stream << \"It's not clear which file to import for \";\n      msg_stream << \"'@import \\\"\" << imp.imp_path << \"\\\"'.\" << \"\\n\";\n      msg_stream << \"Candidates:\" << \"\\n\";\n      for (size_t i = 0, L = resolved.size(); i < L; ++i)\n      { msg_stream << \"  \" << resolved[i].imp_path << \"\\n\"; }\n      msg_stream << \"Please delete or rename all but one of these files.\" << \"\\n\";\n      error(msg_stream.str(), pstate, traces);\n    }\n\n    // process the resolved entry\n    else if (resolved.size() == 1) {\n      bool use_cache = c_importers.size() == 0;\n      // use cache for the resource loading\n      if (use_cache && sheets.count(resolved[0].abs_path)) return resolved[0];\n      // try to read the content of the resolved file entry\n      // the memory buffer returned must be freed by us!\n      if (char* contents = read_file(resolved[0].abs_path)) {\n        // register the newly resolved file resource\n        register_resource(resolved[0], { contents, 0 }, pstate);\n        // return resolved entry\n        return resolved[0];\n      }\n    }\n\n    // nothing found\n    return { imp, \"\" };\n\n  }\n\n  void Context::import_url (Import* imp, sass::string load_path, const sass::string& ctx_path) {\n\n    SourceSpan pstate(imp->pstate());\n    sass::string imp_path(unquote(load_path));\n    sass::string protocol(\"file\");\n\n    using namespace Prelexer;\n    if (const char* proto = sequence< identifier, exactly<':'>, exactly<'/'>, exactly<'/'> >(imp_path.c_str())) {\n\n      protocol = sass::string(imp_path.c_str(), proto - 3);\n      // if (protocol.compare(\"file\") && true) { }\n    }\n\n    // add urls (protocol other than file) and urls without protocol to `urls` member\n    // ToDo: if ctx_path is already a file resource, we should not add it here?\n    if (imp->import_queries() || protocol != \"file\" || imp_path.substr(0, 2) == \"//\") {\n      imp->urls().push_back(SASS_MEMORY_NEW(String_Quoted, imp->pstate(), load_path));\n    }\n    else if (imp_path.length() > 4 && imp_path.substr(imp_path.length() - 4, 4) == \".css\") {\n      String_Constant* loc = SASS_MEMORY_NEW(String_Constant, pstate, unquote(load_path));\n      Argument_Obj loc_arg = SASS_MEMORY_NEW(Argument, pstate, loc);\n      Arguments_Obj loc_args = SASS_MEMORY_NEW(Arguments, pstate);\n      loc_args->append(loc_arg);\n      Function_Call* new_url = SASS_MEMORY_NEW(Function_Call, pstate, sass::string(\"url\"), loc_args);\n      imp->urls().push_back(new_url);\n    }\n    else {\n      const Importer importer(imp_path, ctx_path);\n      Include include(load_import(importer, pstate));\n      if (include.abs_path.empty()) {\n        error(\"File to import not found or unreadable: \" + imp_path + \".\", pstate, traces);\n      }\n      imp->incs().push_back(include);\n    }\n\n  }\n\n\n  // call custom importers on the given (unquoted) load_path and eventually parse the resulting style_sheet\n  bool Context::call_loader(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp, sass::vector<Sass_Importer_Entry> importers, bool only_one)\n  {\n    // unique counter\n    size_t count = 0;\n    // need one correct import\n    bool has_import = false;\n    // process all custom importers (or custom headers)\n    for (Sass_Importer_Entry& importer_ent : importers) {\n      // int priority = sass_importer_get_priority(importer);\n      Sass_Importer_Fn fn = sass_importer_get_function(importer_ent);\n      // skip importer if it returns NULL\n      if (Sass_Import_List includes =\n          fn(load_path.c_str(), importer_ent, c_compiler)\n      ) {\n        // get c pointer copy to iterate over\n        Sass_Import_List it_includes = includes;\n        while (*it_includes) { ++count;\n          // create unique path to use as key\n          sass::string uniq_path = load_path;\n          if (!only_one && count) {\n            sass::ostream path_strm;\n            path_strm << uniq_path << \":\" << count;\n            uniq_path = path_strm.str();\n          }\n          // create the importer struct\n          Importer importer(uniq_path, ctx_path);\n          // query data from the current include\n          Sass_Import_Entry include_ent = *it_includes;\n          char* source = sass_import_take_source(include_ent);\n          char* srcmap = sass_import_take_srcmap(include_ent);\n          size_t line = sass_import_get_error_line(include_ent);\n          size_t column = sass_import_get_error_column(include_ent);\n          const char *abs_path = sass_import_get_abs_path(include_ent);\n          // handle error message passed back from custom importer\n          // it may (or may not) override the line and column info\n          if (const char* err_message = sass_import_get_error_message(include_ent)) {\n            if (source || srcmap) register_resource({ importer, uniq_path }, { source, srcmap }, pstate);\n            if (line == sass::string::npos && column == sass::string::npos) error(err_message, pstate, traces);\n            else { error(err_message, { pstate.source, { line, column } }, traces); }\n          }\n          // content for import was set\n          else if (source) {\n            // resolved abs_path should be set by custom importer\n            // use the created uniq_path as fallback (maybe enforce)\n            sass::string path_key(abs_path ? abs_path : uniq_path);\n            // create the importer struct\n            Include include(importer, path_key);\n            // attach information to AST node\n            imp->incs().push_back(include);\n            // register the resource buffers\n            register_resource(include, { source, srcmap }, pstate);\n          }\n          // only a path was retuned\n          // try to load it like normal\n          else if(abs_path) {\n            // checks some urls to preserve\n            // `http://`, `https://` and `//`\n            // or dispatchs to `import_file`\n            // which will check for a `.css` extension\n            // or resolves the file on the filesystem\n            // added and resolved via `add_file`\n            // finally stores everything on `imp`\n            import_url(imp, abs_path, ctx_path);\n          }\n          // move to next\n          ++it_includes;\n        }\n        // deallocate the returned memory\n        sass_delete_import_list(includes);\n        // set success flag\n        has_import = true;\n        // break out of loop\n        if (only_one) break;\n      }\n    }\n    // return result\n    return has_import;\n  }\n\n  void register_function(Context&, Signature sig, Native_Function f, Env* env);\n  void register_function(Context&, Signature sig, Native_Function f, size_t arity, Env* env);\n  void register_overload_stub(Context&, sass::string name, Env* env);\n  void register_built_in_functions(Context&, Env* env);\n  void register_c_functions(Context&, Env* env, Sass_Function_List);\n  void register_c_function(Context&, Env* env, Sass_Function_Entry);\n\n  char* Context::render(Block_Obj root)\n  {\n    // check for valid block\n    if (!root) return 0;\n    // start the render process\n    root->perform(&emitter);\n    // finish emitter stream\n    emitter.finalize();\n    // get the resulting buffer from stream\n    OutputBuffer emitted = emitter.get_buffer();\n    // should we append a source map url?\n    if (!c_options.omit_source_map_url) {\n      // generate an embedded source map\n      if (c_options.source_map_embed) {\n        emitted.buffer += linefeed;\n        emitted.buffer += format_embedded_source_map();\n      }\n      // or just link the generated one\n      else if (source_map_file != \"\") {\n        emitted.buffer += linefeed;\n        emitted.buffer += format_source_mapping_url(source_map_file);\n      }\n    }\n    // create a copy of the resulting buffer string\n    // this must be freed or taken over by implementor\n    return sass_copy_c_string(emitted.buffer.c_str());\n  }\n\n  void Context::apply_custom_headers(Block_Obj root, const char* ctx_path, SourceSpan pstate)\n  {\n    // create a custom import to resolve headers\n    Import_Obj imp = SASS_MEMORY_NEW(Import, pstate);\n    // dispatch headers which will add custom functions\n    // custom headers are added to the import instance\n    call_headers(entry_path, ctx_path, pstate, imp);\n    // increase head count to skip later\n    head_imports += resources.size() - 1;\n    // add the statement if we have urls\n    if (!imp->urls().empty()) root->append(imp);\n    // process all other resources (add Import_Stub nodes)\n    for (size_t i = 0, S = imp->incs().size(); i < S; ++i) {\n      root->append(SASS_MEMORY_NEW(Import_Stub, pstate, imp->incs()[i]));\n    }\n  }\n\n  Block_Obj File_Context::parse()\n  {\n\n    // check if entry file is given\n    if (input_path.empty()) return {};\n\n    // create absolute path from input filename\n    // ToDo: this should be resolved via custom importers\n    sass::string abs_path(rel2abs(input_path, CWD));\n\n    // try to load the entry file\n    char* contents = read_file(abs_path);\n\n    // alternatively also look inside each include path folder\n    // I think this differs from ruby sass (IMO too late to remove)\n    for (size_t i = 0, S = include_paths.size(); contents == 0 && i < S; ++i) {\n      // build absolute path for this include path entry\n      abs_path = rel2abs(input_path, include_paths[i]);\n      // try to load the resulting path\n      contents = read_file(abs_path);\n    }\n\n    // abort early if no content could be loaded (various reasons)\n    if (!contents) throw std::runtime_error(\n      \"File to read not found or unreadable: \"\n      + std::string(input_path.c_str()));\n\n    // store entry path\n    entry_path = abs_path;\n\n    // create entry only for import stack\n    Sass_Import_Entry import = sass_make_import(\n      input_path.c_str(),\n      entry_path.c_str(),\n      contents,\n      0\n    );\n    // add the entry to the stack\n    import_stack.push_back(import);\n\n    // create the source entry for file entry\n    register_resource({{ input_path, \".\" }, abs_path }, { contents, 0 });\n\n    // create root ast tree node\n    return compile();\n\n  }\n\n  Block_Obj Data_Context::parse()\n  {\n\n    // check if source string is given\n    if (!source_c_str) return {};\n\n    // convert indented sass syntax\n    if(c_options.is_indented_syntax_src) {\n      // call sass2scss to convert the string\n      char * converted = sass2scss(source_c_str,\n        // preserve the structure as much as possible\n        SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT);\n      // replace old source_c_str with converted\n      free(source_c_str); source_c_str = converted;\n    }\n\n    // remember entry path (defaults to stdin for string)\n    entry_path = input_path.empty() ? \"stdin\" : input_path;\n\n    // ToDo: this may be resolved via custom importers\n    sass::string abs_path(rel2abs(entry_path));\n    char* abs_path_c_str = sass_copy_c_string(abs_path.c_str());\n    strings.push_back(abs_path_c_str);\n\n    // create entry only for the import stack\n    Sass_Import_Entry import = sass_make_import(\n      entry_path.c_str(),\n      abs_path_c_str,\n      source_c_str,\n      srcmap_c_str\n    );\n    // add the entry to the stack\n    import_stack.push_back(import);\n\n    // register a synthetic resource (path does not really exist, skip in includes)\n    register_resource({{ input_path, \".\" }, input_path }, { source_c_str, srcmap_c_str });\n\n    // create root ast tree node\n    return compile();\n  }\n\n  // parse root block from includes\n  Block_Obj Context::compile()\n  {\n    // abort if there is no data\n    if (resources.size() == 0) return {};\n    // get root block from the first style sheet\n    Block_Obj root = sheets.at(entry_path).root;\n    // abort on invalid root\n    if (root.isNull()) return {};\n    Env global; // create root environment\n    // register built-in functions on env\n    register_built_in_functions(*this, &global);\n    // register custom functions (defined via C-API)\n    for (size_t i = 0, S = c_functions.size(); i < S; ++i)\n    { register_c_function(*this, &global, c_functions[i]); }\n    // create initial backtrace entry\n    // create crtp visitor objects\n    Expand expand(*this, &global);\n    Cssize cssize(*this);\n    CheckNesting check_nesting;\n    // check nesting in all files\n    for (auto sheet : sheets) {\n      auto styles = sheet.second;\n      check_nesting(styles.root);\n    }\n    // expand and eval the tree\n    root = expand(root);\n\n    Extension unsatisfied;\n    // check that all extends were used\n    if (extender.checkForUnsatisfiedExtends(unsatisfied)) {\n      throw Exception::UnsatisfiedExtend(traces, unsatisfied);\n    }\n\n    // check nesting\n    check_nesting(root);\n    // merge and bubble certain rules\n    root = cssize(root);\n\n    // clean up by removing empty placeholders\n    // ToDo: maybe we can do this somewhere else?\n    Remove_Placeholders remove_placeholders;\n    root->perform(&remove_placeholders);\n\n    // return processed tree\n    return root;\n  }\n  // EO compile\n\n  sass::string Context::format_embedded_source_map()\n  {\n    sass::string map = emitter.render_srcmap(*this);\n    sass::istream is( map.c_str() );\n    sass::ostream buffer;\n    base64::encoder E;\n    E.encode(is, buffer);\n    sass::string url = \"data:application/json;base64,\" + buffer.str();\n    url.erase(url.size() - 1);\n    return \"/*# sourceMappingURL=\" + url + \" */\";\n  }\n\n  sass::string Context::format_source_mapping_url(const sass::string& file)\n  {\n    sass::string url = abs2rel(file, output_path, CWD);\n    return \"/*# sourceMappingURL=\" + url + \" */\";\n  }\n\n  char* Context::render_srcmap()\n  {\n    if (source_map_file == \"\") return 0;\n    sass::string map = emitter.render_srcmap(*this);\n    return sass_copy_c_string(map.c_str());\n  }\n\n\n  // for data context we want to start after \"stdin\"\n  // we probably always want to skip the header includes?\n  sass::vector<sass::string> Context::get_included_files(bool skip, size_t headers)\n  {\n      // create a copy of the vector for manipulations\n      sass::vector<sass::string> includes = included_files;\n      if (includes.size() == 0) return includes;\n      if (skip) { includes.erase( includes.begin(), includes.begin() + 1 + headers); }\n      else { includes.erase( includes.begin() + 1, includes.begin() + 1 + headers); }\n      includes.erase( std::unique( includes.begin(), includes.end() ), includes.end() );\n      std::sort( includes.begin() + (skip ? 0 : 1), includes.end() );\n      return includes;\n  }\n\n  void register_function(Context& ctx, Signature sig, Native_Function f, Env* env)\n  {\n    Definition* def = make_native_function(sig, f, ctx);\n    def->environment(env);\n    (*env)[def->name() + \"[f]\"] = def;\n  }\n\n  void register_function(Context& ctx, Signature sig, Native_Function f, size_t arity, Env* env)\n  {\n    Definition* def = make_native_function(sig, f, ctx);\n    sass::ostream ss;\n    ss << def->name() << \"[f]\" << arity;\n    def->environment(env);\n    (*env)[ss.str()] = def;\n  }\n\n  void register_overload_stub(Context& ctx, sass::string name, Env* env)\n  {\n    Definition* stub = SASS_MEMORY_NEW(Definition,\n                                       SourceSpan{ \"[built-in function]\" },\n                                       nullptr,\n                                       name,\n                                       Parameters_Obj{},\n                                       nullptr,\n                                       true);\n    (*env)[name + \"[f]\"] = stub;\n  }\n\n\n  void register_built_in_functions(Context& ctx, Env* env)\n  {\n    using namespace Functions;\n    // RGB Functions\n    register_function(ctx, rgb_sig, rgb, env);\n    register_overload_stub(ctx, \"rgba\", env);\n    register_function(ctx, rgba_4_sig, rgba_4, 4, env);\n    register_function(ctx, rgba_2_sig, rgba_2, 2, env);\n    register_function(ctx, red_sig, red, env);\n    register_function(ctx, green_sig, green, env);\n    register_function(ctx, blue_sig, blue, env);\n    register_function(ctx, mix_sig, mix, env);\n    // HSL Functions\n    register_function(ctx, hsl_sig, hsl, env);\n    register_function(ctx, hsla_sig, hsla, env);\n    register_function(ctx, hue_sig, hue, env);\n    register_function(ctx, saturation_sig, saturation, env);\n    register_function(ctx, lightness_sig, lightness, env);\n    register_function(ctx, adjust_hue_sig, adjust_hue, env);\n    register_function(ctx, lighten_sig, lighten, env);\n    register_function(ctx, darken_sig, darken, env);\n    register_function(ctx, saturate_sig, saturate, env);\n    register_function(ctx, desaturate_sig, desaturate, env);\n    register_function(ctx, grayscale_sig, grayscale, env);\n    register_function(ctx, complement_sig, complement, env);\n    register_function(ctx, invert_sig, invert, env);\n    // Opacity Functions\n    register_function(ctx, alpha_sig, alpha, env);\n    register_function(ctx, opacity_sig, alpha, env);\n    register_function(ctx, opacify_sig, opacify, env);\n    register_function(ctx, fade_in_sig, opacify, env);\n    register_function(ctx, transparentize_sig, transparentize, env);\n    register_function(ctx, fade_out_sig, transparentize, env);\n    // Other Color Functions\n    register_function(ctx, adjust_color_sig, adjust_color, env);\n    register_function(ctx, scale_color_sig, scale_color, env);\n    register_function(ctx, change_color_sig, change_color, env);\n    register_function(ctx, ie_hex_str_sig, ie_hex_str, env);\n    // String Functions\n    register_function(ctx, unquote_sig, sass_unquote, env);\n    register_function(ctx, quote_sig, sass_quote, env);\n    register_function(ctx, str_length_sig, str_length, env);\n    register_function(ctx, str_insert_sig, str_insert, env);\n    register_function(ctx, str_index_sig, str_index, env);\n    register_function(ctx, str_slice_sig, str_slice, env);\n    register_function(ctx, to_upper_case_sig, to_upper_case, env);\n    register_function(ctx, to_lower_case_sig, to_lower_case, env);\n    // Number Functions\n    register_function(ctx, percentage_sig, percentage, env);\n    register_function(ctx, round_sig, round, env);\n    register_function(ctx, ceil_sig, ceil, env);\n    register_function(ctx, floor_sig, floor, env);\n    register_function(ctx, abs_sig, abs, env);\n    register_function(ctx, min_sig, min, env);\n    register_function(ctx, max_sig, max, env);\n    register_function(ctx, random_sig, random, env);\n    // List Functions\n    register_function(ctx, length_sig, length, env);\n    register_function(ctx, nth_sig, nth, env);\n    register_function(ctx, set_nth_sig, set_nth, env);\n    register_function(ctx, index_sig, index, env);\n    register_function(ctx, join_sig, join, env);\n    register_function(ctx, append_sig, append, env);\n    register_function(ctx, zip_sig, zip, env);\n    register_function(ctx, list_separator_sig, list_separator, env);\n    register_function(ctx, is_bracketed_sig, is_bracketed, env);\n    // Map Functions\n    register_function(ctx, map_get_sig, map_get, env);\n    register_function(ctx, map_merge_sig, map_merge, env);\n    register_function(ctx, map_remove_sig, map_remove, env);\n    register_function(ctx, map_keys_sig, map_keys, env);\n    register_function(ctx, map_values_sig, map_values, env);\n    register_function(ctx, map_has_key_sig, map_has_key, env);\n    register_function(ctx, keywords_sig, keywords, env);\n    // Introspection Functions\n    register_function(ctx, type_of_sig, type_of, env);\n    register_function(ctx, unit_sig, unit, env);\n    register_function(ctx, unitless_sig, unitless, env);\n    register_function(ctx, comparable_sig, comparable, env);\n    register_function(ctx, variable_exists_sig, variable_exists, env);\n    register_function(ctx, global_variable_exists_sig, global_variable_exists, env);\n    register_function(ctx, function_exists_sig, function_exists, env);\n    register_function(ctx, mixin_exists_sig, mixin_exists, env);\n    register_function(ctx, feature_exists_sig, feature_exists, env);\n    register_function(ctx, call_sig, call, env);\n    register_function(ctx, content_exists_sig, content_exists, env);\n    register_function(ctx, get_function_sig, get_function, env);\n    // Boolean Functions\n    register_function(ctx, not_sig, sass_not, env);\n    register_function(ctx, if_sig, sass_if, env);\n    // Misc Functions\n    register_function(ctx, inspect_sig, inspect, env);\n    register_function(ctx, unique_id_sig, unique_id, env);\n    // Selector functions\n    register_function(ctx, selector_nest_sig, selector_nest, env);\n    register_function(ctx, selector_append_sig, selector_append, env);\n    register_function(ctx, selector_extend_sig, selector_extend, env);\n    register_function(ctx, selector_replace_sig, selector_replace, env);\n    register_function(ctx, selector_unify_sig, selector_unify, env);\n    register_function(ctx, is_superselector_sig, is_superselector, env);\n    register_function(ctx, simple_selectors_sig, simple_selectors, env);\n    register_function(ctx, selector_parse_sig, selector_parse, env);\n  }\n\n  void register_c_functions(Context& ctx, Env* env, Sass_Function_List descrs)\n  {\n    while (descrs && *descrs) {\n      register_c_function(ctx, env, *descrs);\n      ++descrs;\n    }\n  }\n  void register_c_function(Context& ctx, Env* env, Sass_Function_Entry descr)\n  {\n    Definition* def = make_c_function(descr, ctx);\n    def->environment(env);\n    (*env)[def->name() + \"[f]\"] = def;\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/context.hpp",
    "content": "#ifndef SASS_CONTEXT_H\n#define SASS_CONTEXT_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\n\n#define BUFFERSIZE 255\n#include \"b64/encode.h\"\n\n#include \"sass_context.hpp\"\n#include \"stylesheet.hpp\"\n#include \"plugins.hpp\"\n#include \"output.hpp\"\n\nnamespace Sass {\n\n  class Context {\n  public:\n    void import_url (Import* imp, sass::string load_path, const sass::string& ctx_path);\n    bool call_headers(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp)\n    { return call_loader(load_path, ctx_path, pstate, imp, c_headers, false); };\n    bool call_importers(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp)\n    { return call_loader(load_path, ctx_path, pstate, imp, c_importers, true); };\n\n  private:\n    bool call_loader(const sass::string& load_path, const char* ctx_path, SourceSpan& pstate, Import* imp, sass::vector<Sass_Importer_Entry> importers, bool only_one = true);\n\n  public:\n    const sass::string CWD;\n    struct Sass_Options& c_options;\n    sass::string entry_path;\n    size_t head_imports;\n    Plugins plugins;\n    Output emitter;\n\n    // generic ast node garbage container\n    // used to avoid possible circular refs\n    CallStack ast_gc;\n    // resources add under our control\n    // these are guaranteed to be freed\n    sass::vector<char*> strings;\n    sass::vector<Resource> resources;\n    std::map<const sass::string, StyleSheet> sheets;\n    ImporterStack import_stack;\n    sass::vector<Sass_Callee> callee_stack;\n    sass::vector<Backtrace> traces;\n    Extender extender;\n\n    struct Sass_Compiler* c_compiler;\n\n    // absolute paths to includes\n    sass::vector<sass::string> included_files;\n    // relative includes for sourcemap\n    sass::vector<sass::string> srcmap_links;\n    // vectors above have same size\n\n    sass::vector<sass::string> plugin_paths; // relative paths to load plugins\n    sass::vector<sass::string> include_paths; // lookup paths for includes\n\n    void apply_custom_headers(Block_Obj root, const char* path, SourceSpan pstate);\n\n    sass::vector<Sass_Importer_Entry> c_headers;\n    sass::vector<Sass_Importer_Entry> c_importers;\n    sass::vector<Sass_Function_Entry> c_functions;\n\n    void add_c_header(Sass_Importer_Entry header);\n    void add_c_importer(Sass_Importer_Entry importer);\n    void add_c_function(Sass_Function_Entry function);\n\n    const sass::string indent; // String to be used for indentation\n    const sass::string linefeed; // String to be used for line feeds\n    const sass::string input_path; // for relative paths in src-map\n    const sass::string output_path; // for relative paths to the output\n    const sass::string source_map_file; // path to source map file (enables feature)\n    const sass::string source_map_root; // path for sourceRoot property (pass-through)\n\n    virtual ~Context();\n    Context(struct Sass_Context&);\n    virtual Block_Obj parse() = 0;\n    virtual Block_Obj compile();\n    virtual char* render(Block_Obj root);\n    virtual char* render_srcmap();\n\n    void register_resource(const Include&, const Resource&);\n    void register_resource(const Include&, const Resource&, SourceSpan&);\n    sass::vector<Include> find_includes(const Importer& import);\n    Include load_import(const Importer&, SourceSpan pstate);\n\n    Sass_Output_Style output_style() { return c_options.output_style; };\n    sass::vector<sass::string> get_included_files(bool skip = false, size_t headers = 0);\n\n  private:\n    void collect_plugin_paths(const char* paths_str);\n    void collect_plugin_paths(string_list* paths_array);\n    void collect_include_paths(const char* paths_str);\n    void collect_include_paths(string_list* paths_array);\n    sass::string format_embedded_source_map();\n    sass::string format_source_mapping_url(const sass::string& out_path);\n\n\n    // void register_built_in_functions(Env* env);\n    // void register_function(Signature sig, Native_Function f, Env* env);\n    // void register_function(Signature sig, Native_Function f, size_t arity, Env* env);\n    // void register_overload_stub(sass::string name, Env* env);\n\n  public:\n    const sass::string& cwd() { return CWD; };\n  };\n\n  class File_Context : public Context {\n  public:\n    File_Context(struct Sass_File_Context& ctx)\n    : Context(ctx)\n    { }\n    virtual ~File_Context();\n    virtual Block_Obj parse();\n  };\n\n  class Data_Context : public Context {\n  public:\n    char* source_c_str;\n    char* srcmap_c_str;\n    Data_Context(struct Sass_Data_Context& ctx)\n    : Context(ctx)\n    {\n      source_c_str       = ctx.source_string;\n      srcmap_c_str       = ctx.srcmap_string;\n      ctx.source_string = 0; // passed away\n      ctx.srcmap_string = 0; // passed away\n    }\n    virtual ~Data_Context();\n    virtual Block_Obj parse();\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/cssize.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <iostream>\n#include <typeinfo>\n#include <vector>\n\n#include \"cssize.hpp\"\n#include \"context.hpp\"\n\nnamespace Sass {\n\n  Cssize::Cssize(Context& ctx)\n  : traces(ctx.traces),\n    block_stack(BlockStack()),\n    p_stack(sass::vector<Statement*>())\n  { }\n\n  Statement* Cssize::parent()\n  {\n    return p_stack.size() ? p_stack.back() : block_stack.front();\n  }\n\n  Block* Cssize::operator()(Block* b)\n  {\n    Block_Obj bb = SASS_MEMORY_NEW(Block, b->pstate(), b->length(), b->is_root());\n    // bb->tabs(b->tabs());\n    block_stack.push_back(bb);\n    append_block(b, bb);\n    block_stack.pop_back();\n    return bb.detach();\n  }\n\n  Statement* Cssize::operator()(Trace* t)\n  {\n    traces.push_back(Backtrace(t->pstate()));\n    auto result = t->block()->perform(this);\n    traces.pop_back();\n    return result;\n  }\n\n  Statement* Cssize::operator()(Declaration* d)\n  {\n    String_Obj property = Cast<String>(d->property());\n\n    if (Declaration* dd = Cast<Declaration>(parent())) {\n      String_Obj parent_property = Cast<String>(dd->property());\n      property = SASS_MEMORY_NEW(String_Constant,\n                                 d->property()->pstate(),\n                                 parent_property->to_string() + \"-\" + property->to_string());\n      if (!dd->value()) {\n        d->tabs(dd->tabs() + 1);\n      }\n    }\n\n    Declaration_Obj dd = SASS_MEMORY_NEW(Declaration,\n                                      d->pstate(),\n                                      property,\n                                      d->value(),\n                                      d->is_important(),\n                                      d->is_custom_property());\n    dd->is_indented(d->is_indented());\n    dd->tabs(d->tabs());\n\n    p_stack.push_back(dd);\n    Block_Obj bb = d->block() ? operator()(d->block()) : NULL;\n    p_stack.pop_back();\n\n    if (bb && bb->length()) {\n      if (dd->value() && !dd->value()->is_invisible()) {\n        bb->unshift(dd);\n      }\n      return bb.detach();\n    }\n    else if (dd->value() && !dd->value()->is_invisible()) {\n      return dd.detach();\n    }\n\n    return 0;\n  }\n\n  Statement* Cssize::operator()(AtRule* r)\n  {\n    if (!r->block() || !r->block()->length()) return r;\n\n    if (parent()->statement_type() == Statement::RULESET)\n    {\n      return r->is_keyframes() ? SASS_MEMORY_NEW(Bubble, r->pstate(), r) : bubble(r);\n    }\n\n    p_stack.push_back(r);\n    AtRuleObj rr = SASS_MEMORY_NEW(AtRule,\n                                  r->pstate(),\n                                  r->keyword(),\n                                  r->selector(),\n                                  r->block() ? operator()(r->block()) : 0);\n    if (r->value()) rr->value(r->value());\n    p_stack.pop_back();\n\n    bool directive_exists = false;\n    size_t L = rr->block() ? rr->block()->length() : 0;\n    for (size_t i = 0; i < L && !directive_exists; ++i) {\n      Statement_Obj s = r->block()->at(i);\n      if (s->statement_type() != Statement::BUBBLE) directive_exists = true;\n      else {\n        Bubble_Obj s_obj = Cast<Bubble>(s);\n        s = s_obj->node();\n        if (s->statement_type() != Statement::DIRECTIVE) directive_exists = false;\n        else directive_exists = (Cast<AtRule>(s)->keyword() == rr->keyword());\n      }\n\n    }\n\n    Block* result = SASS_MEMORY_NEW(Block, rr->pstate());\n    if (!(directive_exists || rr->is_keyframes()))\n    {\n      AtRule* empty_node = Cast<AtRule>(rr);\n      empty_node->block(SASS_MEMORY_NEW(Block, rr->block() ? rr->block()->pstate() : rr->pstate()));\n      result->append(empty_node);\n    }\n\n    Block_Obj db = rr->block();\n    if (db.isNull()) db = SASS_MEMORY_NEW(Block, rr->pstate());\n    Block_Obj ss = debubble(db, rr);\n    for (size_t i = 0, L = ss->length(); i < L; ++i) {\n      result->append(ss->at(i));\n    }\n\n    return result;\n  }\n\n  Statement* Cssize::operator()(Keyframe_Rule* r)\n  {\n    if (!r->block() || !r->block()->length()) return r;\n\n    Keyframe_Rule_Obj rr = SASS_MEMORY_NEW(Keyframe_Rule,\n                                        r->pstate(),\n                                        operator()(r->block()));\n    if (!r->name().isNull()) rr->name(r->name());\n\n    return debubble(rr->block(), rr);\n  }\n\n  Statement* Cssize::operator()(StyleRule* r)\n  {\n    p_stack.push_back(r);\n    // this can return a string schema\n    // string schema is not a statement!\n    // r->block() is already a string schema\n    // and that is coming from propset expand\n    Block* bb = operator()(r->block());\n    // this should protect us (at least a bit) from our mess\n    // fixing this properly is harder that it should be ...\n    if (Cast<Statement>(bb) == NULL) {\n      error(\"Illegal nesting: Only properties may be nested beneath properties.\", r->block()->pstate(), traces);\n    }\n    StyleRuleObj rr = SASS_MEMORY_NEW(StyleRule,\n                                  r->pstate(),\n                                  r->selector(),\n                                  bb);\n\n    rr->is_root(r->is_root());\n    // rr->tabs(r->block()->tabs());\n    p_stack.pop_back();\n\n    if (!rr->block()) {\n      error(\"Illegal nesting: Only properties may be nested beneath properties.\", r->block()->pstate(), traces);\n    }\n\n    Block_Obj props = SASS_MEMORY_NEW(Block, rr->block()->pstate());\n    Block* rules = SASS_MEMORY_NEW(Block, rr->block()->pstate());\n    for (size_t i = 0, L = rr->block()->length(); i < L; i++)\n    {\n      Statement* s = rr->block()->at(i);\n      if (bubblable(s)) rules->append(s);\n      if (!bubblable(s)) props->append(s);\n    }\n\n    if (props->length())\n    {\n      Block_Obj pb = SASS_MEMORY_NEW(Block, rr->block()->pstate());\n      pb->concat(props);\n      rr->block(pb);\n\n      for (size_t i = 0, L = rules->length(); i < L; i++)\n      {\n        Statement* stm = rules->at(i);\n        stm->tabs(stm->tabs() + 1);\n      }\n\n      rules->unshift(rr);\n    }\n\n    Block* ptr = rules;\n    rules = debubble(rules);\n    void* lp = ptr;\n    void* rp = rules;\n    if (lp != rp) {\n      Block_Obj obj = ptr;\n    }\n\n    if (!(!rules->length() ||\n          !bubblable(rules->last()) ||\n          parent()->statement_type() == Statement::RULESET))\n    {\n      rules->last()->group_end(true);\n    }\n    return rules;\n  }\n\n  Statement* Cssize::operator()(Null* m)\n  {\n    return 0;\n  }\n\n  Statement* Cssize::operator()(CssMediaRule* m)\n  {\n    if (parent()->statement_type() == Statement::RULESET)\n    {\n      return bubble(m);\n    }\n\n    if (parent()->statement_type() == Statement::MEDIA)\n    {\n      return SASS_MEMORY_NEW(Bubble, m->pstate(), m);\n    }\n\n    p_stack.push_back(m);\n\n    CssMediaRuleObj mm = SASS_MEMORY_NEW(CssMediaRule, m->pstate(), m->block());\n    mm->concat(m->elements());\n    mm->block(operator()(m->block()));\n    mm->tabs(m->tabs());\n\n    p_stack.pop_back();\n\n    return debubble(mm->block(), mm);\n  }\n\n  Statement* Cssize::operator()(SupportsRule* m)\n  {\n    if (!m->block()->length())\n    { return m; }\n\n    if (parent()->statement_type() == Statement::RULESET)\n    { return bubble(m); }\n\n    p_stack.push_back(m);\n\n    SupportsRuleObj mm = SASS_MEMORY_NEW(SupportsRule,\n                                       m->pstate(),\n                                       m->condition(),\n                                       operator()(m->block()));\n    mm->tabs(m->tabs());\n\n    p_stack.pop_back();\n\n    return debubble(mm->block(), mm);\n  }\n\n  Statement* Cssize::operator()(AtRootRule* m)\n  {\n    bool tmp = false;\n    for (size_t i = 0, L = p_stack.size(); i < L; ++i) {\n      Statement* s = p_stack[i];\n      tmp |= m->exclude_node(s);\n    }\n\n    if (!tmp && m->block())\n    {\n      Block* bb = operator()(m->block());\n      for (size_t i = 0, L = bb->length(); i < L; ++i) {\n        // (bb->elements())[i]->tabs(m->tabs());\n        Statement_Obj stm = bb->at(i);\n        if (bubblable(stm)) stm->tabs(stm->tabs() + m->tabs());\n      }\n      if (bb->length() && bubblable(bb->last())) bb->last()->group_end(m->group_end());\n      return bb;\n    }\n\n    if (m->exclude_node(parent()))\n    {\n      return SASS_MEMORY_NEW(Bubble, m->pstate(), m);\n    }\n\n    return bubble(m);\n  }\n\n  Statement* Cssize::bubble(AtRule* m)\n  {\n    Block* bb = SASS_MEMORY_NEW(Block, this->parent()->pstate());\n    ParentStatementObj new_rule = Cast<ParentStatement>(SASS_MEMORY_COPY(this->parent()));\n    new_rule->block(bb);\n    new_rule->tabs(this->parent()->tabs());\n    new_rule->block()->concat(m->block());\n\n    Block_Obj wrapper_block = SASS_MEMORY_NEW(Block, m->block() ? m->block()->pstate() : m->pstate());\n    wrapper_block->append(new_rule);\n    AtRuleObj mm = SASS_MEMORY_NEW(AtRule,\n                                  m->pstate(),\n                                  m->keyword(),\n                                  m->selector(),\n                                  wrapper_block);\n    if (m->value()) mm->value(m->value());\n\n    Bubble* bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm);\n    return bubble;\n  }\n\n  Statement* Cssize::bubble(AtRootRule* m)\n  {\n    if (!m || !m->block()) return NULL;\n    Block* bb = SASS_MEMORY_NEW(Block, this->parent()->pstate());\n    ParentStatementObj new_rule = Cast<ParentStatement>(SASS_MEMORY_COPY(this->parent()));\n    Block* wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate());\n    if (new_rule) {\n      new_rule->block(bb);\n      new_rule->tabs(this->parent()->tabs());\n      new_rule->block()->concat(m->block());\n      wrapper_block->append(new_rule);\n    }\n\n    AtRootRule* mm = SASS_MEMORY_NEW(AtRootRule,\n                                        m->pstate(),\n                                        wrapper_block,\n                                        m->expression());\n    Bubble* bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm);\n    return bubble;\n  }\n\n  Statement* Cssize::bubble(SupportsRule* m)\n  {\n    StyleRuleObj parent = Cast<StyleRule>(SASS_MEMORY_COPY(this->parent()));\n\n    Block* bb = SASS_MEMORY_NEW(Block, parent->block()->pstate());\n    StyleRule* new_rule = SASS_MEMORY_NEW(StyleRule,\n                                        parent->pstate(),\n                                        parent->selector(),\n                                        bb);\n    new_rule->tabs(parent->tabs());\n    new_rule->block()->concat(m->block());\n\n    Block* wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate());\n    wrapper_block->append(new_rule);\n    SupportsRule* mm = SASS_MEMORY_NEW(SupportsRule,\n                                       m->pstate(),\n                                       m->condition(),\n                                       wrapper_block);\n\n    mm->tabs(m->tabs());\n\n    Bubble* bubble = SASS_MEMORY_NEW(Bubble, mm->pstate(), mm);\n    return bubble;\n  }\n\n  Statement* Cssize::bubble(CssMediaRule* m)\n  {\n    StyleRuleObj parent = Cast<StyleRule>(SASS_MEMORY_COPY(this->parent()));\n\n    Block* bb = SASS_MEMORY_NEW(Block, parent->block()->pstate());\n    StyleRule* new_rule = SASS_MEMORY_NEW(StyleRule,\n      parent->pstate(),\n      parent->selector(),\n      bb);\n    new_rule->tabs(parent->tabs());\n    new_rule->block()->concat(m->block());\n\n    Block* wrapper_block = SASS_MEMORY_NEW(Block, m->block()->pstate());\n    wrapper_block->append(new_rule);\n    CssMediaRuleObj mm = SASS_MEMORY_NEW(CssMediaRule,\n      m->pstate(),\n      wrapper_block);\n    mm->concat(m->elements());\n\n    mm->tabs(m->tabs());\n\n    return SASS_MEMORY_NEW(Bubble, mm->pstate(), mm);\n  }\n\n  bool Cssize::bubblable(Statement* s)\n  {\n    return Cast<StyleRule>(s) || (s && s->bubbles());\n  }\n\n  Block* Cssize::flatten(const Block* b)\n  {\n    Block* result = SASS_MEMORY_NEW(Block, b->pstate(), 0, b->is_root());\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      Statement* ss = b->at(i);\n      if (const Block* bb = Cast<Block>(ss)) {\n        Block_Obj bs = flatten(bb);\n        for (size_t j = 0, K = bs->length(); j < K; ++j) {\n          result->append(bs->at(j));\n        }\n      }\n      else {\n        result->append(ss);\n      }\n    }\n    return result;\n  }\n\n  sass::vector<std::pair<bool, Block_Obj>> Cssize::slice_by_bubble(Block* b)\n  {\n    sass::vector<std::pair<bool, Block_Obj>> results;\n\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      Statement_Obj value = b->at(i);\n      bool key = Cast<Bubble>(value) != NULL;\n\n      if (!results.empty() && results.back().first == key)\n      {\n        Block_Obj wrapper_block = results.back().second;\n        wrapper_block->append(value);\n      }\n      else\n      {\n        Block* wrapper_block = SASS_MEMORY_NEW(Block, value->pstate());\n        wrapper_block->append(value);\n        results.push_back(std::make_pair(key, wrapper_block));\n      }\n    }\n    return results;\n  }\n\n  Block* Cssize::debubble(Block* children, Statement* parent)\n  {\n    ParentStatementObj previous_parent;\n    sass::vector<std::pair<bool, Block_Obj>> baz = slice_by_bubble(children);\n    Block_Obj result = SASS_MEMORY_NEW(Block, children->pstate());\n\n    for (size_t i = 0, L = baz.size(); i < L; ++i) {\n      bool is_bubble = baz[i].first;\n      Block_Obj slice = baz[i].second;\n\n      if (!is_bubble) {\n        if (!parent) {\n          result->append(slice);\n        }\n        else if (previous_parent) {\n          previous_parent->block()->concat(slice);\n        }\n        else {\n          previous_parent = SASS_MEMORY_COPY(parent);\n          previous_parent->block(slice);\n          previous_parent->tabs(parent->tabs());\n\n          result->append(previous_parent);\n        }\n        continue;\n      }\n\n      for (size_t j = 0, K = slice->length(); j < K; ++j)\n      {\n        Statement_Obj ss;\n        Statement_Obj stm = slice->at(j);\n        // this has to go now here (too bad)\n        Bubble_Obj node = Cast<Bubble>(stm);\n\n        CssMediaRule* rule1 = NULL;\n        CssMediaRule* rule2 = NULL;\n        if (parent) rule1 = Cast<CssMediaRule>(parent);\n        if (node) rule2 = Cast<CssMediaRule>(node->node());\n        if (rule1 || rule2) {\n          ss = node->node();\n        }\n\n        ss = node->node();\n\n        if (!ss) {\n          continue;\n        }\n\n        ss->tabs(ss->tabs() + node->tabs());\n        ss->group_end(node->group_end());\n\n        Block_Obj bb = SASS_MEMORY_NEW(Block,\n                                    children->pstate(),\n                                    children->length(),\n                                    children->is_root());\n        auto evaled = ss->perform(this);\n        if (evaled) bb->append(evaled);\n\n        Block_Obj wrapper_block = SASS_MEMORY_NEW(Block,\n                                              children->pstate(),\n                                              children->length(),\n                                              children->is_root());\n\n        Block* wrapper = flatten(bb);\n        wrapper_block->append(wrapper);\n\n        if (wrapper->length()) {\n          previous_parent = {};\n        }\n\n        if (wrapper_block) {\n          result->append(wrapper_block);\n        }\n      }\n    }\n\n    return flatten(result);\n  }\n\n  void Cssize::append_block(Block* b, Block* cur)\n  {\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      Statement_Obj ith = b->at(i)->perform(this);\n      if (Block_Obj bb = Cast<Block>(ith)) {\n        for (size_t j = 0, K = bb->length(); j < K; ++j) {\n          cur->append(bb->at(j));\n        }\n      }\n      else if (ith) {\n        cur->append(ith);\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/cssize.hpp",
    "content": "#ifndef SASS_CSSIZE_H\n#define SASS_CSSIZE_H\n\n#include \"ast.hpp\"\n#include \"context.hpp\"\n#include \"operation.hpp\"\n#include \"environment.hpp\"\n\nnamespace Sass {\n\n  struct Backtrace;\n\n  class Cssize : public Operation_CRTP<Statement*, Cssize> {\n\n    Backtraces&                 traces;\n    BlockStack      block_stack;\n    sass::vector<Statement*>  p_stack;\n\n  public:\n    Cssize(Context&);\n    ~Cssize() { }\n\n    Block* operator()(Block*);\n    Statement* operator()(StyleRule*);\n    // Statement* operator()(Bubble*);\n    Statement* operator()(CssMediaRule*);\n    Statement* operator()(SupportsRule*);\n    Statement* operator()(AtRootRule*);\n    Statement* operator()(AtRule*);\n    Statement* operator()(Keyframe_Rule*);\n    Statement* operator()(Trace*);\n    Statement* operator()(Declaration*);\n    // Statement* operator()(Assignment*);\n    // Statement* operator()(Import*);\n    // Statement* operator()(Import_Stub*);\n    // Statement* operator()(WarningRule*);\n    // Statement* operator()(Error*);\n    // Statement* operator()(Comment*);\n    // Statement* operator()(If*);\n    // Statement* operator()(ForRule*);\n    // Statement* operator()(EachRule*);\n    // Statement* operator()(WhileRule*);\n    // Statement* operator()(Return*);\n    // Statement* operator()(ExtendRule*);\n    // Statement* operator()(Definition*);\n    // Statement* operator()(Mixin_Call*);\n    // Statement* operator()(Content*);\n    Statement* operator()(Null*);\n\n    Statement* parent();\n    sass::vector<std::pair<bool, Block_Obj>> slice_by_bubble(Block*);\n    Statement* bubble(AtRule*);\n    Statement* bubble(AtRootRule*);\n    Statement* bubble(CssMediaRule*);\n    Statement* bubble(SupportsRule*);\n\n    Block* debubble(Block* children, Statement* parent = 0);\n    Block* flatten(const Block*);\n    bool bubblable(Statement*);\n\n    // generic fallback\n    template <typename U>\n    Statement* fallback(U x)\n    { return Cast<Statement>(x); }\n\n    void append_block(Block*, Block*);\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/dart_helpers.hpp",
    "content": "#ifndef SASS_DART_HELPERS_H\n#define SASS_DART_HELPERS_H\n\n#include <vector>\n#include <utility>\n#include <iterator>\n#include <functional>\n\nnamespace Sass {\n\n  // ##########################################################################\n  // Flatten `vector<vector<T>>` to `vector<T>`\n  // ##########################################################################\n  template <class T>\n  T flatten(const sass::vector<T>& all)\n  {\n    T flattened;\n    for (const auto& sub : all) {\n      std::copy(std::begin(sub), std::end(sub),\n        std::back_inserter(flattened));\n    }\n    return flattened;\n  }\n\n  // ##########################################################################\n  // Expands each element of this Iterable into zero or more elements.\n  // Calls a function on every element and ads all results to flat array\n  // ##########################################################################\n  // Equivalent to dart `cnt.any`\n  // Pass additional closure variables to `fn`\n  template <class T, class U, typename ...Args>\n  T expand(const T& cnt, U fn, Args... args) {\n    T flattened;\n    for (const auto& sub : cnt) {\n      auto rv = fn(sub, args...);\n      flattened.insert(flattened.end(),\n        rv.begin(), rv.end());\n    }\n    return flattened;\n  }\n\n  // ##########################################################################\n  // ##########################################################################\n  template <class T>\n  T flattenInner(const sass::vector<T>& vec)\n  {\n    T outer;\n    for (const auto& sub : vec) {\n      outer.emplace_back(std::move(flatten(sub)));\n    }\n    return outer;\n  }\n  // EO flattenInner\n\n  // ##########################################################################\n  // Equivalent to dart `cnt.any`\n  // Pass additional closure variables to `fn`\n  // ##########################################################################\n  template <class T, class U, typename ...Args>\n  bool hasAny(const T& cnt, U fn, Args... args) {\n    for (const auto& sub : cnt) {\n      if (fn(sub, args...)) {\n        return true;\n      }\n    }\n    return false;\n  }\n  // EO hasAny\n\n  // ##########################################################################\n  // Equivalent to dart `cnt.take(len).any`\n  // Pass additional closure variables to `fn`\n  // ##########################################################################\n  template <class T, class U, typename ...Args>\n  bool hasSubAny(const T& cnt, size_t len, U fn, Args... args) {\n    for (size_t i = 0; i < len; i++) {\n      if (fn(cnt[i], args...)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  // ##########################################################################\n  // Default predicate for lcs algorithm\n  // ##########################################################################\n  template <class T>\n  inline bool lcsIdentityCmp(const T& X, const T& Y, T& result)\n  {\n    // Assert equality\n    if (!ObjEqualityFn(X, Y)) {\n      return false;\n    }\n    // Store in reference\n    result = X;\n    // Return success\n    return true;\n  }\n  // EO lcsIdentityCmp\n\n  // ##########################################################################\n  // Longest common subsequence with predicate\n  // ##########################################################################\n  template <class T>\n  sass::vector<T> lcs(\n    const sass::vector<T>& X, const sass::vector<T>& Y,\n    bool(*select)(const T&, const T&, T&) = lcsIdentityCmp<T>)\n  {\n\n    std::size_t m = X.size(), mm = X.size() + 1;\n    std::size_t n = Y.size(), nn = Y.size() + 1;\n\n    if (m == 0) return {};\n    if (n == 0) return {};\n\n    // MSVC does not support variable-length arrays\n    // To circumvent, allocate one array on the heap\n    // Then use a macro to access via double index\n    // e.g. `size_t L[m][n]` is supported by gcc\n    size_t* len = new size_t[mm * nn + 1];\n    bool* acc = new bool[mm * nn + 1];\n    T* res = new T[mm * nn + 1];\n\n    #define LEN(x, y) len[(x) * nn + (y)]\n    #define ACC(x, y) acc[(x) * nn + (y)]\n    #define RES(x, y) res[(x) * nn + (y)]\n\n    /* Following steps build L[m+1][n+1] in bottom up fashion. Note\n      that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */\n    for (size_t i = 0; i <= m; i++) {\n      for (size_t j = 0; j <= n; j++) {\n        if (i == 0 || j == 0)\n          LEN(i, j) = 0;\n        else {\n          ACC(i - 1, j - 1) = select(X[i - 1], Y[j - 1], RES(i - 1, j - 1));\n          if (ACC(i - 1, j - 1))\n            LEN(i, j) = LEN(i - 1, j - 1) + 1;\n          else\n            LEN(i, j) = std::max(LEN(i - 1, j), LEN(i, j - 1));\n        }\n      }\n    }\n\n    // Following code is used to print LCS\n    sass::vector<T> lcs;\n    std::size_t index = LEN(m, n);\n    lcs.reserve(index);\n\n    // Start from the right-most-bottom-most corner\n    // and one by one store objects in lcs[]\n    std::size_t i = m, j = n;\n    while (i > 0 && j > 0) {\n\n      // If current objects in X[] and Y are same,\n      // then current object is part of LCS\n      if (ACC(i - 1, j - 1))\n      {\n        // Put the stored object in result\n        // Note: we push instead of unshift\n        // Note: reverse the vector later\n        // ToDo: is deque more performant?\n        lcs.push_back(RES(i - 1, j - 1));\n        // reduce values of i, j and index\n        i -= 1; j -= 1; index -= 1;\n      }\n\n      // If not same, then find the larger of two and\n      // go in the direction of larger value\n      else if (LEN(i - 1, j) > LEN(i, j - 1)) {\n        i--;\n      }\n      else {\n        j--;\n      }\n\n    }\n\n    // reverse now as we used push_back\n    std::reverse(lcs.begin(), lcs.end());\n\n    // Delete temp memory on heap\n    delete[] len;\n    delete[] acc;\n    delete[] res;\n\n    #undef LEN\n    #undef ACC\n    #undef RES\n\n    return lcs;\n  }\n  // EO lcs\n\n  // ##########################################################################\n  // ##########################################################################\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/debug.hpp",
    "content": "#ifndef SASS_DEBUG_H\n#define SASS_DEBUG_H\n\n#include <stdint.h>\n\n#ifndef UINT32_MAX\n  #define UINT32_MAX 0xffffffffU\n#endif\n\nenum dbg_lvl_t : uint32_t {\n  NONE = 0,\n  TRIM = 1,\n  CHUNKS = 2,\n  SUBWEAVE = 4,\n  WEAVE = 8,\n  EXTEND_COMPOUND = 16,\n  EXTEND_COMPLEX = 32,\n  LCS = 64,\n  EXTEND_OBJECT = 128,\n  ALL = UINT32_MAX\n};\n\n#ifdef DEBUG\n\n#ifndef DEBUG_LVL\nconst uint32_t debug_lvl = UINT32_MAX;\n#else\nconst uint32_t debug_lvl = (DEBUG_LVL);\n#endif // DEBUG_LVL\n\n#define DEBUG_PRINT(lvl, x) if((lvl) & debug_lvl) { std::cerr << x; }\n#define DEBUG_PRINTLN(lvl, x) if((lvl) & debug_lvl) { std::cerr << x << std::endl; }\n#define DEBUG_EXEC(lvl, x) if((lvl) & debug_lvl) { x; }\n\n#else // DEBUG\n\n#define DEBUG_PRINT(lvl, x)\n#define DEBUG_PRINTLN(lvl, x)\n#define DEBUG_EXEC(lvl, x)\n\n#endif // DEBUG\n\n#endif // SASS_DEBUG\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/debugger.hpp",
    "content": "#ifndef SASS_DEBUGGER_H\n#define SASS_DEBUGGER_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <queue>\n#include <vector>\n#include <string>\n#include <sstream>\n#include \"ast.hpp\"\n#include \"ast_fwd_decl.hpp\"\n#include \"extension.hpp\"\n\n#include \"ordered_map.hpp\"\n\nusing namespace Sass;\n\ninline void debug_ast(AST_Node* node, sass::string ind = \"\", Env* env = 0);\n\ninline sass::string debug_vec(const AST_Node* node) {\n  if (node == NULL) return \"null\";\n  else return node->to_string();\n}\n\ninline sass::string debug_dude(sass::vector<sass::vector<int>> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinOut = false;\n  for (auto ct : vec) {\n    if (joinOut) out << \", \";\n    joinOut = true;\n    out << \"{\";\n    bool joinIn = false;\n    for (auto nr : ct) {\n      if (joinIn) out << \", \";\n      joinIn = true;\n      out << nr;\n    }\n    out << \"}\";\n  }\n  out << \"}\";\n  return out.str();\n}\n\ninline sass::string debug_vec(sass::string& str) {\n  return str;\n}\n\ninline sass::string debug_vec(Extension& ext) {\n  sass::sstream out;\n  out << debug_vec(ext.extender);\n  out << \" {@extend \";\n  out << debug_vec(ext.target);\n  if (ext.isOptional) {\n    out << \" !optional\";\n  }\n  out << \"}\";\n  return out.str();\n}\n\ntemplate <class T>\ninline sass::string debug_vec(sass::vector<T> vec) {\n  sass::sstream out;\n  out << \"[\";\n  for (size_t i = 0; i < vec.size(); i += 1) {\n    if (i > 0) out << \", \";\n    out << debug_vec(vec[i]);\n  }\n  out << \"]\";\n  return out.str();\n}\n\ntemplate <class T>\ninline sass::string debug_vec(std::queue<T> vec) {\n  sass::sstream out;\n  out << \"{\";\n  for (size_t i = 0; i < vec.size(); i += 1) {\n    if (i > 0) out << \", \";\n    out << debug_vec(vec[i]);\n  }\n  out << \"}\";\n  return out.str();\n}\n\ntemplate <class T, class U, class O>\ninline sass::string debug_vec(std::map<T, U, O> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(it->first) // string (key)\n      << \": \"\n      << debug_vec(it->second); // string's value\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\ntemplate <class T, class U, class O, class V>\ninline sass::string debug_vec(const ordered_map<T, U, O, V>& vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(*it); // string (key)\n    // << debug_vec(it->second); // string's value\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\ntemplate <class T, class U, class O, class V>\ninline sass::string debug_vec(std::unordered_map<T, U, O, V> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(it->first) // string (key)\n      << \": \"\n      << debug_vec(it->second); // string's value\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\ntemplate <class T, class U, class O, class V>\ninline sass::string debug_keys(std::unordered_map<T, U, O, V> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(it->first); // string (key)\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\ninline sass::string debug_vec(ExtListSelSet& vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(*it); // string (key)\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\n/*\ntemplate <class T, class U, class O, class V>\ninline sass::string debug_values(tsl::ordered_map<T, U, O, V> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(const_cast<U&>(it->second)); // string's value\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n \ntemplate <class T, class U, class O, class V>\ninline sass::string debug_vec(tsl::ordered_map<T, U, O, V> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(it->first) // string (key)\n      << \": \"\n      << debug_vec(const_cast<U&>(it->second)); // string's value\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\ntemplate <class T, class U, class O, class V>\ninline sass::string debug_vals(tsl::ordered_map<T, U, O, V> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(const_cast<U&>(it->second)); // string's value\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\ntemplate <class T, class U, class O, class V>\ninline sass::string debug_keys(tsl::ordered_map<T, U, O, V> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto it = vec.begin(); it != vec.end(); it++)\n  {\n    if (joinit) out << \", \";\n    out << debug_vec(it->first);\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n*/\n\ntemplate <class T, class U>\ninline sass::string debug_vec(std::set<T, U> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto item : vec) {\n    if (joinit) out << \", \";\n    out << debug_vec(item);\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\n/*\ntemplate <class T, class U, class O, class V>\ninline sass::string debug_vec(tsl::ordered_set<T, U, O, V> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto item : vec) {\n    if (joinit) out << \", \";\n    out << debug_vec(item);\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n*/\n\ntemplate <class T, class U, class O, class V>\ninline sass::string debug_vec(std::unordered_set<T, U, O, V> vec) {\n  sass::sstream out;\n  out << \"{\";\n  bool joinit = false;\n  for (auto item : vec) {\n    if (joinit) out << \", \";\n    out << debug_vec(item);\n    joinit = true;\n  }\n  out << \"}\";\n  return out.str();\n}\n\ninline sass::string debug_bool(bool val) {\n  return val ? \"true\" : \"false\";\n}\ninline sass::string debug_vec(ExtSmplSelSet* node) {\n  if (node == NULL) return \"null\";\n  else return debug_vec(*node);\n}\n\ninline void debug_ast(const AST_Node* node, sass::string ind = \"\", Env* env = 0) {\n  debug_ast(const_cast<AST_Node*>(node), ind, env);\n}\n\ninline sass::string str_replace(sass::string str, const sass::string& oldStr, const sass::string& newStr)\n{\n  size_t pos = 0;\n  while((pos = str.find(oldStr, pos)) != sass::string::npos)\n  {\n     str.replace(pos, oldStr.length(), newStr);\n     pos += newStr.length();\n  }\n  return str;\n}\n\ninline sass::string prettyprint(const sass::string& str) {\n  sass::string clean = str_replace(str, \"\\n\", \"\\\\n\");\n  clean = str_replace(clean, \"\t\", \"\\\\t\");\n  clean = str_replace(clean, \"\\r\", \"\\\\r\");\n  return clean;\n}\n\ninline sass::string longToHex(long long t) {\n  sass::sstream is;\n  is << std::hex << t;\n  return is.str();\n}\n\ninline sass::string pstate_source_position(AST_Node* node)\n{\n  sass::sstream str;\n  Offset start(node->pstate().position);\n  Offset end(start + node->pstate().offset);\n  size_t file = node->pstate().getSrcId();\n  str << (file == sass::string::npos ? 99999999 : file)\n    << \"@[\" << start.line << \":\" << start.column << \"]\"\n    << \"-[\" << end.line << \":\" << end.column << \"]\";\n#ifdef DEBUG_SHARED_PTR\n      str << \"x\" << node->getRefCount() << \"\"\n      << \" \" << node->getDbgFile()\n      << \"@\" << node->getDbgLine();\n#endif\n  return str.str();\n}\n\ninline void debug_ast(AST_Node* node, sass::string ind, Env* env)\n{\n  if (node == 0) return;\n  if (ind == \"\") std::cerr << \"####################################################################\\n\";\n  if (Cast<Bubble>(node)) {\n    Bubble* bubble = Cast<Bubble>(node);\n    std::cerr << ind << \"Bubble \" << bubble;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << bubble->tabs();\n    std::cerr << std::endl;\n    debug_ast(bubble->node(), ind + \" \", env);\n  } else if (Cast<Trace>(node)) {\n    Trace* trace = Cast<Trace>(node);\n    std::cerr << ind << \"Trace \" << trace;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\"\n    << \" [name:\" << trace->name() << \", type: \" << trace->type() << \"]\"\n    << std::endl;\n    debug_ast(trace->block(), ind + \" \", env);\n  } else if (Cast<AtRootRule>(node)) {\n    AtRootRule* root_block = Cast<AtRootRule>(node);\n    std::cerr << ind << \"AtRootRule \" << root_block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << root_block->tabs();\n    std::cerr << std::endl;\n    debug_ast(root_block->expression(), ind + \":\", env);\n    debug_ast(root_block->block(), ind + \" \", env);\n  } else if (Cast<SelectorList>(node)) {\n    SelectorList* selector = Cast<SelectorList>(node);\n    std::cerr << ind << \"SelectorList \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <\" << selector->hash() << \">\";\n    std::cerr << (selector->is_invisible() ? \" [is_invisible]\" : \" -\");\n    std::cerr << (selector->isInvisible() ? \" [isInvisible]\" : \" -\");\n    std::cerr << (selector->has_real_parent_ref() ? \" [real-parent]\": \" -\");\n    std::cerr << std::endl;\n\n    for(const ComplexSelector_Obj& i : selector->elements()) { debug_ast(i, ind + \" \", env); }\n\n  } else if (Cast<ComplexSelector>(node)) {\n    ComplexSelector* selector = Cast<ComplexSelector>(node);\n    std::cerr << ind << \"ComplexSelector \" << selector\n      << \" (\" << pstate_source_position(node) << \")\"\n      << \" <\" << selector->hash() << \">\"\n      << \" [\" << (selector->chroots() ? \"CHROOT\" : \"CONNECT\") << \"]\"\n      << \" [length:\" << longToHex(selector->length()) << \"]\"\n      << \" [weight:\" << longToHex(selector->specificity()) << \"]\"\n      << (selector->is_invisible() ? \" [is_invisible]\" : \" -\")\n      << (selector->isInvisible() ? \" [isInvisible]\" : \" -\")\n      << (selector->hasPreLineFeed() ? \" [hasPreLineFeed]\" : \" -\")\n\n      // << (selector->is_invisible() ? \" [INVISIBLE]\": \" -\")\n      // << (selector->has_placeholder() ? \" [PLACEHOLDER]\": \" -\")\n      // << (selector->is_optional() ? \" [is_optional]\": \" -\")\n      << (selector->has_real_parent_ref() ? \" [real parent]\": \" -\")\n      // << (selector->has_line_feed() ? \" [line-feed]\": \" -\")\n      // << (selector->has_line_break() ? \" [line-break]\": \" -\")\n      << \" -- \\n\";\n\n    for(const SelectorComponentObj& i : selector->elements()) { debug_ast(i, ind + \" \", env); }\n\n  } else if (Cast<SelectorCombinator>(node)) {\n    SelectorCombinator* selector = Cast<SelectorCombinator>(node);\n    std::cerr << ind << \"SelectorCombinator \" << selector\n      << \" (\" << pstate_source_position(node) << \")\"\n      << \" <\" << selector->hash() << \">\"\n      << \" [weight:\" << longToHex(selector->specificity()) << \"]\"\n      << (selector->has_real_parent_ref() ? \" [real parent]\": \" -\")\n      << \" -- \";\n\n      sass::string del;\n      switch (selector->combinator()) {\n        case SelectorCombinator::CHILD:    del = \">\"; break;\n        case SelectorCombinator::GENERAL:  del = \"~\"; break;\n        case SelectorCombinator::ADJACENT: del = \"+\"; break;\n      }\n\n      std::cerr << \"[\" << del << \"]\" << \"\\n\";\n\n  } else if (Cast<CompoundSelector>(node)) {\n    CompoundSelector* selector = Cast<CompoundSelector>(node);\n    std::cerr << ind << \"CompoundSelector \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <\" << selector->hash() << \">\";\n    std::cerr << (selector->hasRealParent() ? \" [REAL PARENT]\" : \"\") << \">\";\n    std::cerr << \" [weight:\" << longToHex(selector->specificity()) << \"]\";\n    std::cerr << (selector->hasPostLineBreak() ? \" [hasPostLineBreak]\" : \" -\");\n    std::cerr << (selector->is_invisible() ? \" [is_invisible]\" : \" -\");\n    std::cerr << (selector->isInvisible() ? \" [isInvisible]\" : \" -\");\n    std::cerr << \"\\n\";\n    for(const SimpleSelector_Obj& i : selector->elements()) { debug_ast(i, ind + \" \", env); }\n\n  } else if (Cast<Parent_Reference>(node)) {\n    Parent_Reference* selector = Cast<Parent_Reference>(node);\n    std::cerr << ind << \"Parent_Reference \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <\" << selector->hash() << \">\";\n    std::cerr << std::endl;\n\n  } else if (Cast<PseudoSelector>(node)) {\n    PseudoSelector* selector = Cast<PseudoSelector>(node);\n    std::cerr << ind << \"PseudoSelector \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <\" << selector->hash() << \">\";\n    std::cerr << \" <<\" << selector->ns_name() << \">>\";\n    std::cerr << (selector->isClass() ? \" [isClass]\": \" -\");\n    std::cerr << (selector->isSyntacticClass() ? \" [isSyntacticClass]\": \" -\");\n    std::cerr << std::endl;\n    debug_ast(selector->argument(), ind + \" <= \", env);\n    debug_ast(selector->selector(), ind + \" || \", env);\n  } else if (Cast<AttributeSelector>(node)) {\n    AttributeSelector* selector = Cast<AttributeSelector>(node);\n    std::cerr << ind << \"AttributeSelector \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <\" << selector->hash() << \">\";\n    std::cerr << \" <<\" << selector->ns_name() << \">>\";\n    std::cerr << std::endl;\n    debug_ast(selector->value(), ind + \"[\" + selector->matcher() + \"] \", env);\n  } else if (Cast<ClassSelector>(node)) {\n    ClassSelector* selector = Cast<ClassSelector>(node);\n    std::cerr << ind << \"ClassSelector \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <\" << selector->hash() << \">\";\n    std::cerr << \" <<\" << selector->ns_name() << \">>\";\n    std::cerr << std::endl;\n  } else if (Cast<IDSelector>(node)) {\n    IDSelector* selector = Cast<IDSelector>(node);\n    std::cerr << ind << \"IDSelector \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <\" << selector->hash() << \">\";\n    std::cerr << \" <<\" << selector->ns_name() << \">>\";\n    std::cerr << std::endl;\n  } else if (Cast<TypeSelector>(node)) {\n    TypeSelector* selector = Cast<TypeSelector>(node);\n    std::cerr << ind << \"TypeSelector \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <\" << selector->hash() << \">\";\n    std::cerr << \" <<\" << selector->ns_name() << \">>\";\n    std::cerr << std::endl;\n  } else if (Cast<PlaceholderSelector>(node)) {\n\n    PlaceholderSelector* selector = Cast<PlaceholderSelector>(node);\n    std::cerr << ind << \"PlaceholderSelector [\" << selector->ns_name() << \"] \" << selector;\n    std::cerr << \" (\" << pstate_source_position(selector) << \")\"\n      << \" <\" << selector->hash() << \">\"\n      << (selector->isInvisible() ? \" [isInvisible]\" : \" -\")\n    << std::endl;\n\n  } else if (Cast<SimpleSelector>(node)) {\n    SimpleSelector* selector = Cast<SimpleSelector>(node);\n    std::cerr << ind << \"SimpleSelector \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n\n  } else if (Cast<Selector_Schema>(node)) {\n    Selector_Schema* selector = Cast<Selector_Schema>(node);\n    std::cerr << ind << \"Selector_Schema \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\"\n      << (selector->connect_parent() ? \" [connect-parent]\": \" -\")\n    << std::endl;\n\n    debug_ast(selector->contents(), ind + \" \");\n    // for(auto i : selector->elements()) { debug_ast(i, ind + \" \", env); }\n\n  } else if (Cast<Selector>(node)) {\n    Selector* selector = Cast<Selector>(node);\n    std::cerr << ind << \"Selector \" << selector;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\"\n    << std::endl;\n\n  } else if (Cast<Media_Query_Expression>(node)) {\n    Media_Query_Expression* block = Cast<Media_Query_Expression>(node);\n    std::cerr << ind << \"Media_Query_Expression \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << (block->is_interpolated() ? \" [is_interpolated]\": \" -\")\n    << std::endl;\n    debug_ast(block->feature(), ind + \" feature) \");\n    debug_ast(block->value(), ind + \" value) \");\n\n  } else if (Cast<Media_Query>(node)) {\n    Media_Query* block = Cast<Media_Query>(node);\n    std::cerr << ind << \"Media_Query \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << (block->is_negated() ? \" [is_negated]\": \" -\")\n      << (block->is_restricted() ? \" [is_restricted]\": \" -\")\n    << std::endl;\n    debug_ast(block->media_type(), ind + \" \");\n    for(const auto& i : block->elements()) { debug_ast(i, ind + \" \", env); }\n  }\n  else if (Cast<MediaRule>(node)) {\n    MediaRule* rule = Cast<MediaRule>(node);\n    std::cerr << ind << \"MediaRule \" << rule;\n    std::cerr << \" (\" << pstate_source_position(rule) << \")\";\n    std::cerr << \" \" << rule->tabs() << std::endl;\n    debug_ast(rule->schema(), ind + \" =@ \");\n    debug_ast(rule->block(), ind + \" \");\n  }\n  else if (Cast<CssMediaRule>(node)) {\n    CssMediaRule* rule = Cast<CssMediaRule>(node);\n    std::cerr << ind << \"CssMediaRule \" << rule;\n    std::cerr << \" (\" << pstate_source_position(rule) << \")\";\n    std::cerr << \" \" << rule->tabs() << std::endl;\n    for (auto item : rule->elements()) {\n      debug_ast(item, ind + \" == \");\n    }\n    debug_ast(rule->block(), ind + \" \");\n  }\n  else if (Cast<CssMediaQuery>(node)) {\n    CssMediaQuery* query = Cast<CssMediaQuery>(node);\n    std::cerr << ind << \"CssMediaQuery \" << query;\n    std::cerr << \" (\" << pstate_source_position(query) << \")\";\n    std::cerr << \" [\" << (query->modifier()) << \"] \";\n    std::cerr << \" [\" << (query->type()) << \"] \";\n    std::cerr << \" \" << debug_vec(query->features());\n    std::cerr << std::endl;\n  } else if (Cast<SupportsRule>(node)) {\n    SupportsRule* block = Cast<SupportsRule>(node);\n    std::cerr << ind << \"SupportsRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->condition(), ind + \" =@ \");\n    debug_ast(block->block(), ind + \" <>\");\n  } else if (Cast<SupportsOperation>(node)) {\n    SupportsOperation* block = Cast<SupportsOperation>(node);\n    std::cerr << ind << \"SupportsOperation \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\"\n    << std::endl;\n    debug_ast(block->left(), ind + \" left) \");\n    debug_ast(block->right(), ind + \" right) \");\n  } else if (Cast<SupportsNegation>(node)) {\n    SupportsNegation* block = Cast<SupportsNegation>(node);\n    std::cerr << ind << \"SupportsNegation \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\"\n    << std::endl;\n    debug_ast(block->condition(), ind + \" condition) \");\n  } else if (Cast<At_Root_Query>(node)) {\n    At_Root_Query* block = Cast<At_Root_Query>(node);\n    std::cerr << ind << \"At_Root_Query \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\"\n    << std::endl;\n    debug_ast(block->feature(), ind + \" feature) \");\n    debug_ast(block->value(), ind + \" value) \");\n  } else if (Cast<SupportsDeclaration>(node)) {\n    SupportsDeclaration* block = Cast<SupportsDeclaration>(node);\n    std::cerr << ind << \"SupportsDeclaration \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\"\n    << std::endl;\n    debug_ast(block->feature(), ind + \" feature) \");\n    debug_ast(block->value(), ind + \" value) \");\n  } else if (Cast<Block>(node)) {\n    Block* root_block = Cast<Block>(node);\n    std::cerr << ind << \"Block \" << root_block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    if (root_block->is_root()) std::cerr << \" [root]\";\n    if (root_block->isInvisible()) std::cerr << \" [isInvisible]\";\n    std::cerr << \" \" << root_block->tabs() << std::endl;\n    for(const Statement_Obj& i : root_block->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<WarningRule>(node)) {\n    WarningRule* block = Cast<WarningRule>(node);\n    std::cerr << ind << \"WarningRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->message(), ind + \" : \");\n  } else if (Cast<ErrorRule>(node)) {\n    ErrorRule* block = Cast<ErrorRule>(node);\n    std::cerr << ind << \"ErrorRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n  } else if (Cast<DebugRule>(node)) {\n    DebugRule* block = Cast<DebugRule>(node);\n    std::cerr << ind << \"DebugRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->value(), ind + \" \");\n  } else if (Cast<Comment>(node)) {\n    Comment* block = Cast<Comment>(node);\n    std::cerr << ind << \"Comment \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->text(), ind + \"// \", env);\n  } else if (Cast<If>(node)) {\n    If* block = Cast<If>(node);\n    std::cerr << ind << \"If \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->predicate(), ind + \" = \");\n    debug_ast(block->block(), ind + \" <>\");\n    debug_ast(block->alternative(), ind + \" ><\");\n  } else if (Cast<Return>(node)) {\n    Return* block = Cast<Return>(node);\n    std::cerr << ind << \"Return \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs();\n    std::cerr << \" [\" << block->value()->to_string() << \"]\" << std::endl;\n  } else if (Cast<ExtendRule>(node)) {\n    ExtendRule* block = Cast<ExtendRule>(node);\n    std::cerr << ind << \"ExtendRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->selector(), ind + \"-> \", env);\n  } else if (Cast<Content>(node)) {\n    Content* block = Cast<Content>(node);\n    std::cerr << ind << \"Content \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->arguments(), ind + \" args: \", env);\n  } else if (Cast<Import_Stub>(node)) {\n    Import_Stub* block = Cast<Import_Stub>(node);\n    std::cerr << ind << \"Import_Stub \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << block->imp_path() << \"] \";\n    std::cerr << \" \" << block->tabs() << std::endl;\n  } else if (Cast<Import>(node)) {\n    Import* block = Cast<Import>(node);\n    std::cerr << ind << \"Import \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    // sass::vector<sass::string>         files_;\n    for (auto imp : block->urls()) debug_ast(imp, ind + \"@: \", env);\n    debug_ast(block->import_queries(), ind + \"@@ \");\n  } else if (Cast<Assignment>(node)) {\n    Assignment* block = Cast<Assignment>(node);\n    std::cerr << ind << \"Assignment \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" <<\" << block->variable() << \">> \" << block->tabs() << std::endl;\n    debug_ast(block->value(), ind + \"=\", env);\n  } else if (Cast<Declaration>(node)) {\n    Declaration* block = Cast<Declaration>(node);\n    std::cerr << ind << \"Declaration \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [is_custom_property: \" << block->is_custom_property() << \"] \";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->property(), ind + \" prop: \", env);\n    debug_ast(block->value(), ind + \" value: \", env);\n    debug_ast(block->block(), ind + \" \", env);\n  } else if (Cast<Keyframe_Rule>(node)) {\n    Keyframe_Rule* ParentStatement = Cast<Keyframe_Rule>(node);\n    std::cerr << ind << \"Keyframe_Rule \" << ParentStatement;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << ParentStatement->tabs() << std::endl;\n    if (ParentStatement->name()) debug_ast(ParentStatement->name(), ind + \"@\");\n    if (ParentStatement->block()) for(const Statement_Obj& i : ParentStatement->block()->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<AtRule>(node)) {\n    AtRule* block = Cast<AtRule>(node);\n    std::cerr << ind << \"AtRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << block->keyword() << \"] \" << block->tabs() << std::endl;\n    debug_ast(block->selector(), ind + \"~\", env);\n    debug_ast(block->value(), ind + \"+\", env);\n    if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<EachRule>(node)) {\n    EachRule* block = Cast<EachRule>(node);\n    std::cerr << ind << \"EachRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<ForRule>(node)) {\n    ForRule* block = Cast<ForRule>(node);\n    std::cerr << ind << \"ForRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<WhileRule>(node)) {\n    WhileRule* block = Cast<WhileRule>(node);\n    std::cerr << ind << \"WhileRule \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    if (block->block()) for(const Statement_Obj& i : block->block()->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<Definition>(node)) {\n    Definition* block = Cast<Definition>(node);\n    std::cerr << ind << \"Definition \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [name: \" << block->name() << \"] \";\n    std::cerr << \" [type: \" << (block->type() == Sass::Definition::Type::MIXIN ? \"Mixin \" : \"Function \") << \"] \";\n    // this seems to lead to segfaults some times?\n    // std::cerr << \" [signature: \" << block->signature() << \"] \";\n    std::cerr << \" [native: \" << block->native_function() << \"] \";\n    std::cerr << \" \" << block->tabs() << std::endl;\n    debug_ast(block->parameters(), ind + \" params: \", env);\n    if (block->block()) debug_ast(block->block(), ind + \" \", env);\n  } else if (Cast<Mixin_Call>(node)) {\n    Mixin_Call* block = Cast<Mixin_Call>(node);\n    std::cerr << ind << \"Mixin_Call \" << block << \" \" << block->tabs();\n    std::cerr << \" (\" << pstate_source_position(block) << \")\";\n    std::cerr << \" [\" <<  block->name() << \"]\";\n    std::cerr << \" [has_content: \" << block->has_content() << \"] \" << std::endl;\n    debug_ast(block->arguments(), ind + \" args: \", env);\n    debug_ast(block->block_parameters(), ind + \" block_params: \", env);\n    if (block->block()) debug_ast(block->block(), ind + \" \", env);\n  } else if (StyleRule* ruleset = Cast<StyleRule>(node)) {\n    std::cerr << ind << \"StyleRule \" << ruleset;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [indent: \" << ruleset->tabs() << \"]\";\n    std::cerr << (ruleset->is_invisible() ? \" [INVISIBLE]\" : \"\");\n    std::cerr << (ruleset->is_root() ? \" [root]\" : \"\");\n    std::cerr << std::endl;\n    debug_ast(ruleset->selector(), ind + \">\");\n    debug_ast(ruleset->block(), ind + \" \");\n  } else if (Cast<Block>(node)) {\n    Block* block = Cast<Block>(node);\n    std::cerr << ind << \"Block \" << block;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << (block->is_invisible() ? \" [INVISIBLE]\" : \"\");\n    std::cerr << \" [indent: \" << block->tabs() << \"]\" << std::endl;\n    for(const Statement_Obj& i : block->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<Variable>(node)) {\n    Variable* expression = Cast<Variable>(node);\n    std::cerr << ind << \"Variable \" << expression;\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \";\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << expression->name() << \"]\" << std::endl;\n    sass::string name(expression->name());\n    if (env && env->has(name)) debug_ast(Cast<Expression>((*env)[name]), ind + \" -> \", env);\n  } else if (Cast<Function_Call>(node)) {\n    Function_Call* expression = Cast<Function_Call>(node);\n    std::cerr << ind << \"Function_Call \" << expression;\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \";\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << expression->name() << \"]\";\n    if (expression->is_delayed()) std::cerr << \" [delayed]\";\n    if (expression->is_interpolant()) std::cerr << \" [interpolant]\";\n    if (expression->is_css()) std::cerr << \" [css]\";\n    std::cerr << std::endl;\n    debug_ast(expression->arguments(), ind + \" args: \", env);\n    debug_ast(expression->func(), ind + \" func: \", env);\n  } else if (Cast<Function>(node)) {\n    Function* expression = Cast<Function>(node);\n    std::cerr << ind << \"Function \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    if (expression->is_css()) std::cerr << \" [css]\";\n    std::cerr << std::endl;\n    debug_ast(expression->definition(), ind + \" definition: \", env);\n  } else if (Cast<Arguments>(node)) {\n    Arguments* expression = Cast<Arguments>(node);\n    std::cerr << ind << \"Arguments \" << expression;\n    if (expression->is_delayed()) std::cerr << \" [delayed]\";\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    if (expression->has_named_arguments()) std::cerr << \" [has_named_arguments]\";\n    if (expression->has_rest_argument()) std::cerr << \" [has_rest_argument]\";\n    if (expression->has_keyword_argument()) std::cerr << \" [has_keyword_argument]\";\n    std::cerr << std::endl;\n    for(const Argument_Obj& i : expression->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<Argument>(node)) {\n    Argument* expression = Cast<Argument>(node);\n    std::cerr << ind << \"Argument \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << expression->value().ptr() << \"]\";\n    std::cerr << \" [name: \" << expression->name() << \"] \";\n    std::cerr << \" [rest: \" << expression->is_rest_argument() << \"] \";\n    std::cerr << \" [keyword: \" << expression->is_keyword_argument() << \"] \" << std::endl;\n    debug_ast(expression->value(), ind + \" value: \", env);\n  } else if (Cast<Parameters>(node)) {\n    Parameters* expression = Cast<Parameters>(node);\n    std::cerr << ind << \"Parameters \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [has_optional: \" << expression->has_optional_parameters() << \"] \";\n    std::cerr << \" [has_rest: \" << expression->has_rest_parameter() << \"] \";\n    std::cerr << std::endl;\n    for(const Parameter_Obj& i : expression->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<Parameter>(node)) {\n    Parameter* expression = Cast<Parameter>(node);\n    std::cerr << ind << \"Parameter \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [name: \" << expression->name() << \"] \";\n    std::cerr << \" [default: \" << expression->default_value().ptr() << \"] \";\n    std::cerr << \" [rest: \" << expression->is_rest_parameter() << \"] \" << std::endl;\n  } else if (Cast<Unary_Expression>(node)) {\n    Unary_Expression* expression = Cast<Unary_Expression>(node);\n    std::cerr << ind << \"Unary_Expression \" << expression;\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \";\n    std::cerr << \" [delayed: \" << expression->is_delayed() << \"] \";\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << expression->type() << \"]\" << std::endl;\n    debug_ast(expression->operand(), ind + \" operand: \", env);\n  } else if (Cast<Binary_Expression>(node)) {\n    Binary_Expression* expression = Cast<Binary_Expression>(node);\n    std::cerr << ind << \"Binary_Expression \" << expression;\n    if (expression->is_interpolant()) std::cerr << \" [is interpolant] \";\n    if (expression->is_left_interpolant()) std::cerr << \" [left interpolant] \";\n    if (expression->is_right_interpolant()) std::cerr << \" [right interpolant] \";\n    std::cerr << \" [delayed: \" << expression->is_delayed() << \"] \";\n    std::cerr << \" [ws_before: \" << expression->op().ws_before << \"] \";\n    std::cerr << \" [ws_after: \" << expression->op().ws_after << \"] \";\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << expression->type_name() << \"]\" << std::endl;\n    debug_ast(expression->left(), ind + \" left:  \", env);\n    debug_ast(expression->right(), ind + \" right: \", env);\n  } else if (Cast<Map>(node)) {\n    Map* expression = Cast<Map>(node);\n    std::cerr << ind << \"Map \" << expression;\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \";\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [Hashed]\" << std::endl;\n    for (const auto& i : expression->elements()) {\n      debug_ast(i.first, ind + \" key: \");\n      debug_ast(i.second, ind + \" val: \");\n    }\n  } else if (Cast<List>(node)) {\n    List* expression = Cast<List>(node);\n    std::cerr << ind << \"List \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" (\" << expression->length() << \") \" <<\n      (expression->separator() == SASS_COMMA ? \"Comma \" : expression->separator() == SASS_HASH ? \"Map \" : \"Space \") <<\n      \" [delayed: \" << expression->is_delayed() << \"] \" <<\n      \" [interpolant: \" << expression->is_interpolant() << \"] \" <<\n      \" [listized: \" << expression->from_selector() << \"] \" <<\n      \" [arglist: \" << expression->is_arglist() << \"] \" <<\n      \" [bracketed: \" << expression->is_bracketed() << \"] \" <<\n      \" [expanded: \" << expression->is_expanded() << \"] \" <<\n      \" [hash: \" << expression->hash() << \"] \" <<\n      std::endl;\n    for(const auto& i : expression->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<Boolean>(node)) {\n    Boolean* expression = Cast<Boolean>(node);\n    std::cerr << ind << \"Boolean \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \";\n    std::cerr << \" [\" << expression->value() << \"]\" << std::endl;\n  } else if (Cast<Color_RGBA>(node)) {\n    Color_RGBA* expression = Cast<Color_RGBA>(node);\n    std::cerr << ind << \"Color \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [name: \" << expression->disp() << \"] \";\n    std::cerr << \" [delayed: \" << expression->is_delayed() << \"] \";\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \";\n    std::cerr << \" rgba[\" << expression->r() << \":\"  << expression->g() << \":\" << expression->b() << \"@\" << expression->a() << \"]\" << std::endl;\n  } else if (Cast<Color_HSLA>(node)) {\n    Color_HSLA* expression = Cast<Color_HSLA>(node);\n    std::cerr << ind << \"Color \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [name: \" << expression->disp() << \"] \";\n    std::cerr << \" [delayed: \" << expression->is_delayed() << \"] \";\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \";\n    std::cerr << \" hsla[\" << expression->h() << \":\"  << expression->s() << \":\" << expression->l() << \"@\" << expression->a() << \"]\" << std::endl;\n  } else if (Cast<Number>(node)) {\n    Number* expression = Cast<Number>(node);\n    std::cerr << ind << \"Number \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [delayed: \" << expression->is_delayed() << \"] \";\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \";\n    std::cerr << \" [\" << expression->value() << expression->unit() << \"]\" <<\n      \" [hash: \" << expression->hash() << \"] \" <<\n      std::endl;\n  } else if (Cast<Null>(node)) {\n    Null* expression = Cast<Null>(node);\n    std::cerr << ind << \"Null \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [interpolant: \" << expression->is_interpolant() << \"] \"\n      // \" [hash: \" << expression->hash() << \"] \"\n      << std::endl;\n  } else if (Cast<String_Quoted>(node)) {\n    String_Quoted* expression = Cast<String_Quoted>(node);\n    std::cerr << ind << \"String_Quoted \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << prettyprint(expression->value()) << \"]\";\n    if (expression->is_delayed()) std::cerr << \" [delayed]\";\n    if (expression->is_interpolant()) std::cerr << \" [interpolant]\";\n    if (expression->quote_mark()) std::cerr << \" [quote_mark: \" << expression->quote_mark() << \"]\";\n    std::cerr << std::endl;\n  } else if (Cast<String_Constant>(node)) {\n    String_Constant* expression = Cast<String_Constant>(node);\n    std::cerr << ind << \"String_Constant \" << expression;\n    if (expression->concrete_type()) {\n      std::cerr << \" \" << expression->concrete_type();\n    }\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" [\" << prettyprint(expression->value()) << \"]\";\n    if (expression->is_delayed()) std::cerr << \" [delayed]\";\n    if (expression->is_interpolant()) std::cerr << \" [interpolant]\";\n    std::cerr << std::endl;\n  } else if (Cast<String_Schema>(node)) {\n    String_Schema* expression = Cast<String_Schema>(node);\n    std::cerr << ind << \"String_Schema \" << expression;\n    std::cerr << \" (\" << pstate_source_position(expression) << \")\";\n    std::cerr << \" \" << expression->concrete_type();\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    if (expression->css()) std::cerr << \" [css]\";\n    if (expression->is_delayed()) std::cerr << \" [delayed]\";\n    if (expression->is_interpolant()) std::cerr << \" [is interpolant]\";\n    if (expression->has_interpolant()) std::cerr << \" [has interpolant]\";\n    if (expression->is_left_interpolant()) std::cerr << \" [left interpolant] \";\n    if (expression->is_right_interpolant()) std::cerr << \" [right interpolant] \";\n    std::cerr << std::endl;\n    for(const auto& i : expression->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<String>(node)) {\n    String* expression = Cast<String>(node);\n    std::cerr << ind << \"String \" << expression;\n    std::cerr << \" \" << expression->concrete_type();\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    if (expression->is_interpolant()) std::cerr << \" [interpolant]\";\n    std::cerr << std::endl;\n  } else if (Cast<Expression>(node)) {\n    Expression* expression = Cast<Expression>(node);\n    std::cerr << ind << \"Expression \" << expression;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    switch (expression->concrete_type()) {\n      case Expression::Type::NONE: std::cerr << \" [NONE]\"; break;\n      case Expression::Type::BOOLEAN: std::cerr << \" [BOOLEAN]\"; break;\n      case Expression::Type::NUMBER: std::cerr << \" [NUMBER]\"; break;\n      case Expression::Type::COLOR: std::cerr << \" [COLOR]\"; break;\n      case Expression::Type::STRING: std::cerr << \" [STRING]\"; break;\n      case Expression::Type::LIST: std::cerr << \" [LIST]\"; break;\n      case Expression::Type::MAP: std::cerr << \" [MAP]\"; break;\n      case Expression::Type::SELECTOR: std::cerr << \" [SELECTOR]\"; break;\n      case Expression::Type::NULL_VAL: std::cerr << \" [NULL_VAL]\"; break;\n      case Expression::Type::C_WARNING: std::cerr << \" [C_WARNING]\"; break;\n      case Expression::Type::C_ERROR: std::cerr << \" [C_ERROR]\"; break;\n      case Expression::Type::FUNCTION: std::cerr << \" [FUNCTION]\"; break;\n      case Expression::Type::NUM_TYPES: std::cerr << \" [NUM_TYPES]\"; break;\n      case Expression::Type::VARIABLE: std::cerr << \" [VARIABLE]\"; break;\n      case Expression::Type::FUNCTION_VAL: std::cerr << \" [FUNCTION_VAL]\"; break;\n      case Expression::Type::PARENT: std::cerr << \" [PARENT]\"; break;\n    }\n    std::cerr << std::endl;\n  } else if (Cast<ParentStatement>(node)) {\n    ParentStatement* parent = Cast<ParentStatement>(node);\n    std::cerr << ind << \"ParentStatement \" << parent;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << parent->tabs() << std::endl;\n    if (parent->block()) for(const Statement_Obj& i : parent->block()->elements()) { debug_ast(i, ind + \" \", env); }\n  } else if (Cast<Statement>(node)) {\n    Statement* statement = Cast<Statement>(node);\n    std::cerr << ind << \"Statement \" << statement;\n    std::cerr << \" (\" << pstate_source_position(node) << \")\";\n    std::cerr << \" \" << statement->tabs() << std::endl;\n  }\n\n  if (ind == \"\") std::cerr << \"####################################################################\\n\";\n}\n\n\n/*\ninline void debug_ast(const AST_Node* node, sass::string ind = \"\", Env* env = 0)\n{\n  debug_ast(const_cast<AST_Node*>(node), ind, env);\n}\n*/\n\n#endif // SASS_DEBUGGER\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/emitter.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"emitter.hpp\"\n#include \"util_string.hpp\"\n#include \"util.hpp\"\n\nnamespace Sass {\n\n  Emitter::Emitter(struct Sass_Output_Options& opt)\n  : wbuf(),\n    opt(opt),\n    indentation(0),\n    scheduled_space(0),\n    scheduled_linefeed(0),\n    scheduled_delimiter(false),\n    scheduled_crutch(0),\n    scheduled_mapping(0),\n    in_custom_property(false),\n    in_comment(false),\n    in_wrapped(false),\n    in_media_block(false),\n    in_declaration(false),\n    in_space_array(false),\n    in_comma_array(false)\n  { }\n\n  // return buffer as string\n  sass::string Emitter::get_buffer(void)\n  {\n    return wbuf.buffer;\n  }\n\n  Sass_Output_Style Emitter::output_style(void) const\n  {\n    return opt.output_style;\n  }\n\n  // PROXY METHODS FOR SOURCE MAPS\n\n  void Emitter::add_source_index(size_t idx)\n  { wbuf.smap.source_index.push_back(idx); }\n\n  sass::string Emitter::render_srcmap(Context &ctx)\n  { return wbuf.smap.render_srcmap(ctx); }\n\n  void Emitter::set_filename(const sass::string& str)\n  { wbuf.smap.file = str; }\n\n  void Emitter::schedule_mapping(const AST_Node* node)\n  { scheduled_mapping = node; }\n  void Emitter::add_open_mapping(const AST_Node* node)\n  { wbuf.smap.add_open_mapping(node); }\n  void Emitter::add_close_mapping(const AST_Node* node)\n  { wbuf.smap.add_close_mapping(node); }\n  SourceSpan Emitter::remap(const SourceSpan& pstate)\n  { return wbuf.smap.remap(pstate); }\n\n  // MAIN BUFFER MANIPULATION\n\n  // add outstanding delimiter\n  void Emitter::finalize(bool final)\n  {\n    scheduled_space = 0;\n    if (output_style() == SASS_STYLE_COMPRESSED)\n      if (final) scheduled_delimiter = false;\n    if (scheduled_linefeed)\n      scheduled_linefeed = 1;\n    flush_schedules();\n  }\n\n  // flush scheduled space/linefeed\n  void Emitter::flush_schedules(void)\n  {\n    // check the schedule\n    if (scheduled_linefeed) {\n      sass::string linefeeds = \"\";\n\n      for (size_t i = 0; i < scheduled_linefeed; i++)\n        linefeeds += opt.linefeed;\n      scheduled_space = 0;\n      scheduled_linefeed = 0;\n      append_string(linefeeds);\n\n    } else if (scheduled_space) {\n      sass::string spaces(scheduled_space, ' ');\n      scheduled_space = 0;\n      append_string(spaces);\n    }\n    if (scheduled_delimiter) {\n      scheduled_delimiter = false;\n      append_string(\";\");\n    }\n  }\n\n  // prepend some text or token to the buffer\n  void Emitter::prepend_output(const OutputBuffer& output)\n  {\n    wbuf.smap.prepend(output);\n    wbuf.buffer = output.buffer + wbuf.buffer;\n  }\n\n  // prepend some text or token to the buffer\n  void Emitter::prepend_string(const sass::string& text)\n  {\n    // do not adjust mappings for utf8 bom\n    // seems they are not counted in any UA\n    if (text.compare(\"\\xEF\\xBB\\xBF\") != 0) {\n      wbuf.smap.prepend(Offset(text));\n    }\n    wbuf.buffer = text + wbuf.buffer;\n  }\n\n  char Emitter::last_char()\n  {\n    return wbuf.buffer.back();\n  }\n\n  // append a single char to the buffer\n  void Emitter::append_char(const char chr)\n  {\n    // write space/lf\n    flush_schedules();\n    // add to buffer\n    wbuf.buffer += chr;\n    // account for data in source-maps\n    wbuf.smap.append(Offset(chr));\n  }\n\n  // append some text or token to the buffer\n  void Emitter::append_string(const sass::string& text)\n  {\n\n    // write space/lf\n    flush_schedules();\n\n    if (in_comment) {\n      sass::string out = Util::normalize_newlines(text);\n      if (output_style() == COMPACT) {\n        out = comment_to_compact_string(out);\n      }\n      wbuf.smap.append(Offset(out));\n      wbuf.buffer += std::move(out);\n    } else {\n      // add to buffer\n      wbuf.buffer += text;\n      // account for data in source-maps\n      wbuf.smap.append(Offset(text));\n    }\n  }\n\n  // append some white-space only text\n  void Emitter::append_wspace(const sass::string& text)\n  {\n    if (text.empty()) return;\n    if (peek_linefeed(text.c_str())) {\n      scheduled_space = 0;\n      append_mandatory_linefeed();\n    }\n  }\n\n  // append some text or token to the buffer\n  // this adds source-mappings for node start and end\n  void Emitter::append_token(const sass::string& text, const AST_Node* node)\n  {\n    flush_schedules();\n    add_open_mapping(node);\n    // hotfix for browser issues\n    // this is pretty ugly indeed\n    if (scheduled_crutch) {\n      add_open_mapping(scheduled_crutch);\n      scheduled_crutch = 0;\n    }\n    append_string(text);\n    add_close_mapping(node);\n  }\n\n  // HELPER METHODS\n\n  void Emitter::append_indentation()\n  {\n    if (output_style() == COMPRESSED) return;\n    if (output_style() == COMPACT) return;\n    if (in_declaration && in_comma_array) return;\n    if (scheduled_linefeed && indentation)\n      scheduled_linefeed = 1;\n    sass::string indent = \"\";\n    for (size_t i = 0; i < indentation; i++)\n      indent += opt.indent;\n    append_string(indent);\n  }\n\n  void Emitter::append_delimiter()\n  {\n    scheduled_delimiter = true;\n    if (output_style() == COMPACT) {\n      if (indentation == 0) {\n        append_mandatory_linefeed();\n      } else {\n        append_mandatory_space();\n      }\n    } else if (output_style() != COMPRESSED) {\n      append_optional_linefeed();\n    }\n  }\n\n  void Emitter::append_comma_separator()\n  {\n    // scheduled_space = 0;\n    append_string(\",\");\n    append_optional_space();\n  }\n\n  void Emitter::append_colon_separator()\n  {\n    scheduled_space = 0;\n    append_string(\":\");\n    if (!in_custom_property) append_optional_space();\n  }\n\n  void Emitter::append_mandatory_space()\n  {\n    scheduled_space = 1;\n  }\n\n  void Emitter::append_optional_space()\n  {\n    if ((output_style() != COMPRESSED) && buffer().size()) {\n      unsigned char lst = buffer().at(buffer().length() - 1);\n      if (!isspace(lst) || scheduled_delimiter) {\n        if (last_char() != '(') {\n          append_mandatory_space();\n        }\n      }\n    }\n  }\n\n  void Emitter::append_special_linefeed()\n  {\n    if (output_style() == COMPACT) {\n      append_mandatory_linefeed();\n      for (size_t p = 0; p < indentation; p++)\n        append_string(opt.indent);\n    }\n  }\n\n  void Emitter::append_optional_linefeed()\n  {\n    if (in_declaration && in_comma_array) return;\n    if (output_style() == COMPACT) {\n      append_mandatory_space();\n    } else {\n      append_mandatory_linefeed();\n    }\n  }\n\n  void Emitter::append_mandatory_linefeed()\n  {\n    if (output_style() != COMPRESSED) {\n      scheduled_linefeed = 1;\n      scheduled_space = 0;\n      // flush_schedules();\n    }\n  }\n\n  void Emitter::append_scope_opener(AST_Node* node)\n  {\n    scheduled_linefeed = 0;\n    append_optional_space();\n    flush_schedules();\n    if (node) add_open_mapping(node);\n    append_string(\"{\");\n    append_optional_linefeed();\n    // append_optional_space();\n    ++ indentation;\n  }\n  void Emitter::append_scope_closer(AST_Node* node)\n  {\n    -- indentation;\n    scheduled_linefeed = 0;\n    if (output_style() == COMPRESSED)\n      scheduled_delimiter = false;\n    if (output_style() == EXPANDED) {\n      append_optional_linefeed();\n      append_indentation();\n    } else {\n      append_optional_space();\n    }\n    append_string(\"}\");\n    if (node) add_close_mapping(node);\n    append_optional_linefeed();\n    if (indentation != 0) return;\n    if (output_style() != COMPRESSED)\n      scheduled_linefeed = 2;\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/emitter.hpp",
    "content": "#ifndef SASS_EMITTER_H\n#define SASS_EMITTER_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"sass/base.h\"\n#include \"source_map.hpp\"\n#include \"ast_fwd_decl.hpp\"\n\nnamespace Sass {\n  class Context;\n\n  class Emitter {\n\n    public:\n      Emitter(struct Sass_Output_Options& opt);\n      virtual ~Emitter() { }\n\n    protected:\n      OutputBuffer wbuf;\n    public:\n      const sass::string& buffer(void) { return wbuf.buffer; }\n      const SourceMap smap(void) { return wbuf.smap; }\n      const OutputBuffer output(void) { return wbuf; }\n      // proxy methods for source maps\n      void add_source_index(size_t idx);\n      void set_filename(const sass::string& str);\n      void add_open_mapping(const AST_Node* node);\n      void add_close_mapping(const AST_Node* node);\n      void schedule_mapping(const AST_Node* node);\n      sass::string render_srcmap(Context &ctx);\n      SourceSpan remap(const SourceSpan& pstate);\n\n    public:\n      struct Sass_Output_Options& opt;\n      size_t indentation;\n      size_t scheduled_space;\n      size_t scheduled_linefeed;\n      bool scheduled_delimiter;\n      const AST_Node* scheduled_crutch;\n      const AST_Node* scheduled_mapping;\n\n    public:\n      // output strings different in custom css properties\n      bool in_custom_property;\n      // output strings different in comments\n      bool in_comment;\n      // selector list does not get linefeeds\n      bool in_wrapped;\n      // lists always get a space after delimiter\n      bool in_media_block;\n      // nested list must not have parentheses\n      bool in_declaration;\n      // nested lists need parentheses\n      bool in_space_array;\n      bool in_comma_array;\n\n    public:\n      // return buffer as sass::string\n      sass::string get_buffer(void);\n      // flush scheduled space/linefeed\n      Sass_Output_Style output_style(void) const;\n      // add outstanding linefeed\n      void finalize(bool final = true);\n      // flush scheduled space/linefeed\n      void flush_schedules(void);\n      // prepend some text or token to the buffer\n      void prepend_string(const sass::string& text);\n      void prepend_output(const OutputBuffer& out);\n      // append some text or token to the buffer\n      void append_string(const sass::string& text);\n      // append a single character to buffer\n      void append_char(const char chr);\n      // append some white-space only text\n      void append_wspace(const sass::string& text);\n      // append some text or token to the buffer\n      // this adds source-mappings for node start and end\n      void append_token(const sass::string& text, const AST_Node* node);\n      // query last appended character\n      char last_char();\n\n    public: // syntax sugar\n      void append_indentation();\n      void append_optional_space(void);\n      void append_mandatory_space(void);\n      void append_special_linefeed(void);\n      void append_optional_linefeed(void);\n      void append_mandatory_linefeed(void);\n      void append_scope_opener(AST_Node* node = 0);\n      void append_scope_closer(AST_Node* node = 0);\n      void append_comma_separator(void);\n      void append_colon_separator(void);\n      void append_delimiter(void);\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/environment.cpp",
    "content": "#include \"sass.hpp\"\n#include \"ast.hpp\"\n#include \"environment.hpp\"\n\nnamespace Sass {\n\n  template <typename T>\n  Environment<T>::Environment(bool is_shadow)\n  : local_frame_(environment_map<sass::string, T>()),\n    parent_(0), is_shadow_(false)\n  { }\n  template <typename T>\n  Environment<T>::Environment(Environment<T>* env, bool is_shadow)\n  : local_frame_(environment_map<sass::string, T>()),\n    parent_(env), is_shadow_(is_shadow)\n  { }\n  template <typename T>\n  Environment<T>::Environment(Environment<T>& env, bool is_shadow)\n  : local_frame_(environment_map<sass::string, T>()),\n    parent_(&env), is_shadow_(is_shadow)\n  { }\n\n  // link parent to create a stack\n  template <typename T>\n  void Environment<T>::link(Environment& env) { parent_ = &env; }\n  template <typename T>\n  void Environment<T>::link(Environment* env) { parent_ = env; }\n\n  // this is used to find the global frame\n  // which is the second last on the stack\n  template <typename T>\n  bool Environment<T>::is_lexical() const\n  {\n    return !! parent_ && parent_->parent_;\n  }\n\n  // only match the real root scope\n  // there is still a parent around\n  // not sure what it is actually use for\n  // I guess we store functions etc. there\n  template <typename T>\n  bool Environment<T>::is_global() const\n  {\n    return parent_ && ! parent_->parent_;\n  }\n\n  template <typename T>\n  environment_map<sass::string, T>& Environment<T>::local_frame() {\n    return local_frame_;\n  }\n\n  template <typename T>\n  bool Environment<T>::has_local(const sass::string& key) const\n  { return local_frame_.find(key) != local_frame_.end(); }\n\n  template <typename T> EnvResult\n  Environment<T>::find_local(const sass::string& key)\n  {\n    auto end = local_frame_.end();\n    auto it = local_frame_.find(key);\n    return EnvResult(it, it != end);\n  }\n\n  template <typename T>\n  T& Environment<T>::get_local(const sass::string& key)\n  { return local_frame_[key]; }\n\n  template <typename T>\n  void Environment<T>::set_local(const sass::string& key, const T& val)\n  {\n    local_frame_[key] = val;\n  }\n  template <typename T>\n  void Environment<T>::set_local(const sass::string& key, T&& val)\n  {\n    local_frame_[key] = val;\n  }\n\n  template <typename T>\n  void Environment<T>::del_local(const sass::string& key)\n  { local_frame_.erase(key); }\n\n  template <typename T>\n  Environment<T>* Environment<T>::global_env()\n  {\n    Environment* cur = this;\n    while (cur->is_lexical()) {\n      cur = cur->parent_;\n    }\n    return cur;\n  }\n\n  template <typename T>\n  bool Environment<T>::has_global(const sass::string& key)\n  { return global_env()->has(key); }\n\n  template <typename T>\n  T& Environment<T>::get_global(const sass::string& key)\n  { return (*global_env())[key]; }\n\n  template <typename T>\n  void Environment<T>::set_global(const sass::string& key, const T& val)\n  {\n    global_env()->local_frame_[key] = val;\n  }\n  template <typename T>\n  void Environment<T>::set_global(const sass::string& key, T&& val)\n  {\n    global_env()->local_frame_[key] = val;\n  }\n\n  template <typename T>\n  void Environment<T>::del_global(const sass::string& key)\n  { global_env()->local_frame_.erase(key); }\n\n  template <typename T>\n  Environment<T>* Environment<T>::lexical_env(const sass::string& key)\n  {\n    Environment* cur = this;\n    while (cur) {\n      if (cur->has_local(key)) {\n        return cur;\n      }\n      cur = cur->parent_;\n    }\n    return this;\n  }\n\n  // see if we have a lexical variable\n  // move down the stack but stop before we\n  // reach the global frame (is not included)\n  template <typename T>\n  bool Environment<T>::has_lexical(const sass::string& key) const\n  {\n    auto cur = this;\n    while (cur->is_lexical()) {\n      if (cur->has_local(key)) return true;\n      cur = cur->parent_;\n    }\n    return false;\n  }\n\n  // see if we have a lexical we could update\n  // either update already existing lexical value\n  // or if flag is set, we create one if no lexical found\n  template <typename T>\n  void Environment<T>::set_lexical(const sass::string& key, const T& val)\n  {\n    Environment<T>* cur = this;\n    bool shadow = false;\n    while ((cur && cur->is_lexical()) || shadow) {\n      EnvResult rv(cur->find_local(key));\n      if (rv.found) {\n        rv.it->second = val;\n        return;\n      }\n      shadow = cur->is_shadow();\n      cur = cur->parent_;\n    }\n    set_local(key, val);\n  }\n  // this one moves the value\n  template <typename T>\n  void Environment<T>::set_lexical(const sass::string& key, T&& val)\n  {\n    Environment<T>* cur = this;\n    bool shadow = false;\n    while ((cur && cur->is_lexical()) || shadow) {\n      EnvResult rv(cur->find_local(key));\n      if (rv.found) {\n        rv.it->second = val;\n        return;\n      }\n      shadow = cur->is_shadow();\n      cur = cur->parent_;\n    }\n    set_local(key, val);\n  }\n\n  // look on the full stack for key\n  // include all scopes available\n  template <typename T>\n  bool Environment<T>::has(const sass::string& key) const\n  {\n    auto cur = this;\n    while (cur) {\n      if (cur->has_local(key)) {\n        return true;\n      }\n      cur = cur->parent_;\n    }\n    return false;\n  }\n\n  // look on the full stack for key\n  // include all scopes available\n  template <typename T> EnvResult\n  Environment<T>::find(const sass::string& key)\n  {\n    auto cur = this;\n    while (true) {\n      EnvResult rv(cur->find_local(key));\n      if (rv.found) return rv;\n      cur = cur->parent_;\n      if (!cur) return rv;\n    }\n  };\n\n  // use array access for getter and setter functions\n  template <typename T>\n  T& Environment<T>::get(const sass::string& key)\n  {\n    auto cur = this;\n    while (cur) {\n      if (cur->has_local(key)) {\n        return cur->get_local(key);\n      }\n      cur = cur->parent_;\n    }\n    return get_local(key);\n  }\n\n  // use array access for getter and setter functions\n  template <typename T>\n  T& Environment<T>::operator[](const sass::string& key)\n  {\n    auto cur = this;\n    while (cur) {\n      if (cur->has_local(key)) {\n        return cur->get_local(key);\n      }\n      cur = cur->parent_;\n    }\n    return get_local(key);\n  }\n/*\n  #ifdef DEBUG\n  template <typename T>\n  size_t Environment<T>::print(sass::string prefix)\n  {\n    size_t indent = 0;\n    if (parent_) indent = parent_->print(prefix) + 1;\n    std::cerr << prefix << sass::string(indent, ' ') << \"== \" << this << std::endl;\n    for (typename environment_map<sass::string, T>::iterator i = local_frame_.begin(); i != local_frame_.end(); ++i) {\n      if (!ends_with(i->first, \"[f]\") && !ends_with(i->first, \"[f]4\") && !ends_with(i->first, \"[f]2\")) {\n        std::cerr << prefix << sass::string(indent, ' ') << i->first << \" \" << i->second;\n        if (Value* val = Cast<Value>(i->second))\n        { std::cerr << \" : \" << val->to_string(); }\n        std::cerr << std::endl;\n      }\n    }\n    return indent ;\n  }\n  #endif\n*/\n  // compile implementation for AST_Node\n  template class Environment<AST_Node_Obj>;\n\n}\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/environment.hpp",
    "content": "#ifndef SASS_ENVIRONMENT_H\n#define SASS_ENVIRONMENT_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <map>\n#include <string>\n#include \"ast_fwd_decl.hpp\"\n#include \"ast_def_macros.hpp\"\n\nnamespace Sass {\n\n  // this defeats the whole purpose of environment being templatable!!\n  typedef environment_map<sass::string, AST_Node_Obj>::iterator EnvIter;\n\n  class EnvResult {\n    public:\n      EnvIter it;\n      bool found;\n    public:\n      EnvResult(EnvIter it, bool found)\n      : it(it), found(found) {}\n  };\n\n  template <typename T>\n  class Environment {\n    // TODO: test with map\n    environment_map<sass::string, T> local_frame_;\n    ADD_PROPERTY(Environment*, parent)\n    ADD_PROPERTY(bool, is_shadow)\n\n  public:\n    Environment(bool is_shadow = false);\n    Environment(Environment* env, bool is_shadow = false);\n    Environment(Environment& env, bool is_shadow = false);\n\n    // link parent to create a stack\n    void link(Environment& env);\n    void link(Environment* env);\n\n    // this is used to find the global frame\n    // which is the second last on the stack\n    bool is_lexical() const;\n\n    // only match the real root scope\n    // there is still a parent around\n    // not sure what it is actually use for\n    // I guess we store functions etc. there\n    bool is_global() const;\n\n    // scope operates on the current frame\n\n    environment_map<sass::string, T>& local_frame();\n\n    bool has_local(const sass::string& key) const;\n\n    EnvResult find_local(const sass::string& key);\n\n    T& get_local(const sass::string& key);\n\n    // set variable on the current frame\n    void set_local(const sass::string& key, const T& val);\n    void set_local(const sass::string& key, T&& val);\n\n    void del_local(const sass::string& key);\n\n    // global operates on the global frame\n    // which is the second last on the stack\n    Environment* global_env();\n    // get the env where the variable already exists\n    // if it does not yet exist, we return current env\n    Environment* lexical_env(const sass::string& key);\n\n    bool has_global(const sass::string& key);\n\n    T& get_global(const sass::string& key);\n\n    // set a variable on the global frame\n    void set_global(const sass::string& key, const T& val);\n    void set_global(const sass::string& key, T&& val);\n\n    void del_global(const sass::string& key);\n\n    // see if we have a lexical variable\n    // move down the stack but stop before we\n    // reach the global frame (is not included)\n    bool has_lexical(const sass::string& key) const;\n\n    // see if we have a lexical we could update\n    // either update already existing lexical value\n    // or we create a new one on the current frame\n    void set_lexical(const sass::string& key, T&& val);\n    void set_lexical(const sass::string& key, const T& val);\n\n    // look on the full stack for key\n    // include all scopes available\n    bool has(const sass::string& key) const;\n\n    // look on the full stack for key\n    // include all scopes available\n    T& get(const sass::string& key);\n\n    // look on the full stack for key\n    // include all scopes available\n    EnvResult find(const sass::string& key);\n\n    // use array access for getter and setter functions\n    T& operator[](const sass::string& key);\n\n    #ifdef DEBUG\n    size_t print(sass::string prefix = \"\");\n    #endif\n\n  };\n\n  // define typedef for our use case\n  typedef Environment<AST_Node_Obj> Env;\n  typedef sass::vector<Env*> EnvStack;\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/error_handling.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast.hpp\"\n#include \"prelexer.hpp\"\n#include \"backtrace.hpp\"\n#include \"error_handling.hpp\"\n\n#include <iostream>\n\nnamespace Sass {\n\n  namespace Exception {\n\n    Base::Base(SourceSpan pstate, sass::string msg, Backtraces traces)\n    : std::runtime_error(msg.c_str()), msg(msg),\n      prefix(\"Error\"), pstate(pstate), traces(traces)\n    { }\n\n    InvalidSass::InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg)\n    : Base(pstate, msg, traces)\n    { }\n\n\n    InvalidParent::InvalidParent(Selector* parent, Backtraces traces, Selector* selector)\n    : Base(selector->pstate(), def_msg, traces), parent(parent), selector(selector)\n    {\n      msg = \"Invalid parent selector for \"\n        \"\\\"\" + selector->to_string(Sass_Inspect_Options()) + \"\\\": \"\n        \"\\\"\" + parent->to_string(Sass_Inspect_Options()) + \"\\\"\";\n    }\n\n    InvalidVarKwdType::InvalidVarKwdType(SourceSpan pstate, Backtraces traces, sass::string name, const Argument* arg)\n    : Base(pstate, def_msg, traces), name(name), arg(arg)\n    {\n      msg = \"Variable keyword argument map must have string keys.\\n\" +\n        name + \" is not a string in \" + arg->to_string() + \".\";\n    }\n\n    InvalidArgumentType::InvalidArgumentType(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string type, const Value* value)\n    : Base(pstate, def_msg, traces), fn(fn), arg(arg), type(type), value(value)\n    {\n      msg = arg + \": \\\"\";\n      if (value) msg += value->to_string(Sass_Inspect_Options());\n      msg += \"\\\" is not a \" + type + \" for `\" + fn + \"'\";\n    }\n\n    MissingArgument::MissingArgument(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string fntype)\n    : Base(pstate, def_msg, traces), fn(fn), arg(arg), fntype(fntype)\n    {\n      msg = fntype + \" \" + fn + \" is missing argument \" + arg + \".\";\n    }\n\n    InvalidSyntax::InvalidSyntax(SourceSpan pstate, Backtraces traces, sass::string msg)\n    : Base(pstate, msg, traces)\n    { }\n\n    NestingLimitError::NestingLimitError(SourceSpan pstate, Backtraces traces, sass::string msg)\n    : Base(pstate, msg, traces)\n    { }\n\n    DuplicateKeyError::DuplicateKeyError(Backtraces traces, const Map& dup, const Expression& org)\n    : Base(org.pstate(), def_msg, traces), dup(dup), org(org)\n    {\n      msg = \"Duplicate key \" + dup.get_duplicate_key()->inspect() + \" in map (\" + org.inspect() + \").\";\n    }\n\n    TypeMismatch::TypeMismatch(Backtraces traces, const Expression& var, const sass::string type)\n    : Base(var.pstate(), def_msg, traces), var(var), type(type)\n    {\n      msg = var.to_string() + \" is not an \" + type + \".\";\n    }\n\n    InvalidValue::InvalidValue(Backtraces traces, const Expression& val)\n    : Base(val.pstate(), def_msg, traces), val(val)\n    {\n      msg = val.to_string() + \" isn't a valid CSS value.\";\n    }\n\n    StackError::StackError(Backtraces traces, const AST_Node& node)\n    : Base(node.pstate(), def_msg, traces), node(node)\n    {\n      msg = \"stack level too deep\";\n    }\n\n    EndlessExtendError::EndlessExtendError(Backtraces traces, const AST_Node& node)\n      : Base(node.pstate(), def_msg, traces), node(node)\n    {\n      msg = \"Extend is creating an absurdly big selector, aborting!\";\n    }\n\n    IncompatibleUnits::IncompatibleUnits(const Units& lhs, const Units& rhs)\n    {\n      msg = \"Incompatible units: '\" + rhs.unit() + \"' and '\" + lhs.unit() + \"'.\";\n    }\n\n    IncompatibleUnits::IncompatibleUnits(const UnitType lhs, const UnitType rhs)\n    {\n      msg = sass::string(\"Incompatible units: '\") + unit_to_string(rhs) + \"' and '\" + unit_to_string(lhs) + \"'.\";\n    }\n\n    AlphaChannelsNotEqual::AlphaChannelsNotEqual(const Expression* lhs, const Expression* rhs, enum Sass_OP op)\n    : OperationError(), lhs(lhs), rhs(rhs), op(op)\n    {\n      msg = \"Alpha channels must be equal: \" +\n        lhs->to_string({ NESTED, 5 }) +\n        \" \" + sass_op_to_name(op) + \" \" +\n        rhs->to_string({ NESTED, 5 }) + \".\";\n    }\n\n    ZeroDivisionError::ZeroDivisionError(const Expression& lhs, const Expression& rhs)\n    : OperationError(), lhs(lhs), rhs(rhs)\n    {\n      msg = \"divided by 0\";\n    }\n\n    UndefinedOperation::UndefinedOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op)\n    : OperationError(), lhs(lhs), rhs(rhs), op(op)\n    {\n      msg = def_op_msg + \": \\\"\" +\n        lhs->to_string({ NESTED, 5 }) +\n        \" \" + sass_op_to_name(op) + \" \" +\n        rhs->to_string({ TO_SASS, 5 }) +\n        \"\\\".\";\n    }\n\n    InvalidNullOperation::InvalidNullOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op)\n    : UndefinedOperation(lhs, rhs, op)\n    {\n      msg = def_op_null_msg + \": \\\"\" + lhs->inspect() + \" \" + sass_op_to_name(op) + \" \" + rhs->inspect() + \"\\\".\";\n    }\n\n    SassValueError::SassValueError(Backtraces traces, SourceSpan pstate, OperationError& err)\n    : Base(pstate, err.what(), traces)\n    {\n      msg = err.what();\n      prefix = err.errtype();\n    }\n\n    TopLevelParent::TopLevelParent(Backtraces traces, SourceSpan pstate)\n      : Base(pstate, \"Top-level selectors may not contain the parent selector \\\"&\\\".\", traces)\n    {\n\n    }\n\n    UnsatisfiedExtend::UnsatisfiedExtend(Backtraces traces, Extension extension)\n      : Base(extension.target->pstate(), \"The target selector was not found.\\n\"\n        \"Use \\\"@extend \" + extension.target->to_string() + \" !optional\\\" to avoid this error.\", traces)\n    {\n\n    }\n\n    ExtendAcrossMedia::ExtendAcrossMedia(Backtraces traces, Extension extension)\n      : Base(extension.target->pstate(), \"You may not @extend selectors across media queries.\\n\"\n        \"Use \\\"@extend \" + extension.target->to_string() + \" !optional\\\" to avoid this error.\", traces)\n    {\n\n    }\n    \n\n  }\n\n\n  void warn(sass::string msg, SourceSpan pstate)\n  {\n    std::cerr << \"Warning: \" << msg << std::endl;\n  }\n\n  void warning(sass::string msg, SourceSpan pstate)\n  {\n    sass::string cwd(Sass::File::get_cwd());\n    sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));\n    sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));\n    sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));\n\n    std::cerr << \"WARNING on line \" << pstate.getLine() << \", column \" << pstate.getColumn() << \" of \" << output_path << \":\" << std::endl;\n    std::cerr << msg << std::endl << std::endl;\n  }\n\n  void warn(sass::string msg, SourceSpan pstate, Backtrace* bt)\n  {\n    warn(msg, pstate);\n  }\n\n  void deprecated_function(sass::string msg, SourceSpan pstate)\n  {\n    sass::string cwd(Sass::File::get_cwd());\n    sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));\n    sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));\n    sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));\n\n    std::cerr << \"DEPRECATION WARNING: \" << msg << std::endl;\n    std::cerr << \"will be an error in future versions of Sass.\" << std::endl;\n    std::cerr << \"        on line \" << pstate.getLine() << \" of \" << output_path << std::endl;\n  }\n\n  void deprecated(sass::string msg, sass::string msg2, bool with_column, SourceSpan pstate)\n  {\n    sass::string cwd(Sass::File::get_cwd());\n    sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));\n    sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));\n    sass::string output_path(Sass::File::path_for_console(rel_path, pstate.getPath(), pstate.getPath()));\n\n    std::cerr << \"DEPRECATION WARNING on line \" << pstate.getLine();\n    // if (with_column) std::cerr << \", column \" << pstate.column + pstate.offset.column + 1;\n    if (output_path.length()) std::cerr << \" of \" << output_path;\n    std::cerr << \":\" << std::endl;\n    std::cerr << msg << std::endl;\n    if (msg2.length()) std::cerr << msg2 << std::endl;\n    std::cerr << std::endl;\n  }\n\n  void deprecated_bind(sass::string msg, SourceSpan pstate)\n  {\n    sass::string cwd(Sass::File::get_cwd());\n    sass::string abs_path(Sass::File::rel2abs(pstate.getPath(), cwd, cwd));\n    sass::string rel_path(Sass::File::abs2rel(pstate.getPath(), cwd, cwd));\n    sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, pstate.getPath()));\n\n    std::cerr << \"WARNING: \" << msg << std::endl;\n    std::cerr << \"        on line \" << pstate.getLine() << \" of \" << output_path << std::endl;\n    std::cerr << \"This will be an error in future versions of Sass.\" << std::endl;\n  }\n\n  // should be replaced with error with backtraces\n  void coreError(sass::string msg, SourceSpan pstate)\n  {\n    Backtraces traces;\n    throw Exception::InvalidSyntax(pstate, traces, msg);\n  }\n\n  void error(sass::string msg, SourceSpan pstate, Backtraces& traces)\n  {\n    traces.push_back(Backtrace(pstate));\n    throw Exception::InvalidSyntax(pstate, traces, msg);\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/error_handling.hpp",
    "content": "#ifndef SASS_ERROR_HANDLING_H\n#define SASS_ERROR_HANDLING_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <string>\n#include <sstream>\n#include <stdexcept>\n#include \"units.hpp\"\n#include \"position.hpp\"\n#include \"backtrace.hpp\"\n#include \"ast_fwd_decl.hpp\"\n#include \"sass/functions.h\"\n\nnamespace Sass {\n\n  struct Backtrace;\n\n  namespace Exception {\n\n    const sass::string def_msg = \"Invalid sass detected\";\n    const sass::string def_op_msg = \"Undefined operation\";\n    const sass::string def_op_null_msg = \"Invalid null operation\";\n    const sass::string def_nesting_limit = \"Code too deeply nested\";\n\n    class Base : public std::runtime_error {\n      protected:\n        sass::string msg;\n        sass::string prefix;\n      public:\n        SourceSpan pstate;\n        Backtraces traces;\n      public:\n        Base(SourceSpan pstate, sass::string msg, Backtraces traces);\n        virtual const char* errtype() const { return prefix.c_str(); }\n        virtual const char* what() const throw() { return msg.c_str(); }\n        virtual ~Base() throw() {};\n    };\n\n    class InvalidSass : public Base {\n      public:\n        InvalidSass(SourceSpan pstate, Backtraces traces, sass::string msg);\n        virtual ~InvalidSass() throw() {};\n    };\n\n    class InvalidParent : public Base {\n      protected:\n        Selector* parent;\n        Selector* selector;\n      public:\n        InvalidParent(Selector* parent, Backtraces traces, Selector* selector);\n        virtual ~InvalidParent() throw() {};\n    };\n\n    class MissingArgument : public Base {\n      protected:\n        sass::string fn;\n        sass::string arg;\n        sass::string fntype;\n      public:\n        MissingArgument(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string fntype);\n        virtual ~MissingArgument() throw() {};\n    };\n\n    class InvalidArgumentType : public Base {\n      protected:\n        sass::string fn;\n        sass::string arg;\n        sass::string type;\n        const Value* value;\n      public:\n        InvalidArgumentType(SourceSpan pstate, Backtraces traces, sass::string fn, sass::string arg, sass::string type, const Value* value = 0);\n        virtual ~InvalidArgumentType() throw() {};\n    };\n\n    class InvalidVarKwdType : public Base {\n      protected:\n        sass::string name;\n        const Argument* arg;\n      public:\n        InvalidVarKwdType(SourceSpan pstate, Backtraces traces, sass::string name, const Argument* arg = 0);\n        virtual ~InvalidVarKwdType() throw() {};\n    };\n\n    class InvalidSyntax : public Base {\n      public:\n        InvalidSyntax(SourceSpan pstate, Backtraces traces, sass::string msg);\n        virtual ~InvalidSyntax() throw() {};\n    };\n\n    class NestingLimitError : public Base {\n      public:\n        NestingLimitError(SourceSpan pstate, Backtraces traces, sass::string msg = def_nesting_limit);\n        virtual ~NestingLimitError() throw() {};\n    };\n\n    class DuplicateKeyError : public Base {\n      protected:\n        const Map& dup;\n        const Expression& org;\n      public:\n        DuplicateKeyError(Backtraces traces, const Map& dup, const Expression& org);\n        virtual const char* errtype() const { return \"Error\"; }\n        virtual ~DuplicateKeyError() throw() {};\n    };\n\n    class TypeMismatch : public Base {\n      protected:\n        const Expression& var;\n        const sass::string type;\n      public:\n        TypeMismatch(Backtraces traces, const Expression& var, const sass::string type);\n        virtual const char* errtype() const { return \"Error\"; }\n        virtual ~TypeMismatch() throw() {};\n    };\n\n    class InvalidValue : public Base {\n      protected:\n        const Expression& val;\n      public:\n        InvalidValue(Backtraces traces, const Expression& val);\n        virtual const char* errtype() const { return \"Error\"; }\n        virtual ~InvalidValue() throw() {};\n    };\n\n    class StackError : public Base {\n      protected:\n        const AST_Node& node;\n      public:\n        StackError(Backtraces traces, const AST_Node& node);\n        virtual const char* errtype() const { return \"SystemStackError\"; }\n        virtual ~StackError() throw() {};\n    };\n\n    class EndlessExtendError : public Base {\n    protected:\n      const AST_Node& node;\n    public:\n      EndlessExtendError(Backtraces traces, const AST_Node& node);\n      virtual const char* errtype() const { return \"EndlessExtendError\"; }\n      virtual ~EndlessExtendError() throw() {};\n    };\n\n    /* common virtual base class (has no pstate or trace) */\n    class OperationError : public std::runtime_error {\n      protected:\n        sass::string msg;\n      public:\n        OperationError(sass::string msg = def_op_msg)\n        : std::runtime_error(msg.c_str()), msg(msg)\n        {};\n      public:\n        virtual const char* errtype() const { return \"Error\"; }\n        virtual const char* what() const throw() { return msg.c_str(); }\n        virtual ~OperationError() throw() {};\n    };\n\n    class ZeroDivisionError : public OperationError {\n      protected:\n        const Expression& lhs;\n        const Expression& rhs;\n      public:\n        ZeroDivisionError(const Expression& lhs, const Expression& rhs);\n        virtual const char* errtype() const { return \"ZeroDivisionError\"; }\n        virtual ~ZeroDivisionError() throw() {};\n    };\n\n    class IncompatibleUnits : public OperationError {\n      protected:\n        // const Sass::UnitType lhs;\n        // const Sass::UnitType rhs;\n      public:\n        IncompatibleUnits(const Units& lhs, const Units& rhs);\n        IncompatibleUnits(const UnitType lhs, const UnitType rhs);\n        virtual ~IncompatibleUnits() throw() {};\n    };\n\n    class UndefinedOperation : public OperationError {\n      protected:\n        const Expression* lhs;\n        const Expression* rhs;\n        const Sass_OP op;\n      public:\n        UndefinedOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op);\n        // virtual const char* errtype() const { return \"Error\"; }\n        virtual ~UndefinedOperation() throw() {};\n    };\n\n    class InvalidNullOperation : public UndefinedOperation {\n      public:\n        InvalidNullOperation(const Expression* lhs, const Expression* rhs, enum Sass_OP op);\n        virtual ~InvalidNullOperation() throw() {};\n    };\n\n    class AlphaChannelsNotEqual : public OperationError {\n      protected:\n        const Expression* lhs;\n        const Expression* rhs;\n        const Sass_OP op;\n      public:\n        AlphaChannelsNotEqual(const Expression* lhs, const Expression* rhs, enum Sass_OP op);\n        // virtual const char* errtype() const { return \"Error\"; }\n        virtual ~AlphaChannelsNotEqual() throw() {};\n    };\n\n    class SassValueError : public Base {\n    public:\n      SassValueError(Backtraces traces, SourceSpan pstate, OperationError& err);\n      virtual ~SassValueError() throw() {};\n    };\n\n    class TopLevelParent : public Base {\n    public:\n      TopLevelParent(Backtraces traces, SourceSpan pstate);\n      virtual ~TopLevelParent() throw() {};\n    };\n\n    class UnsatisfiedExtend : public Base {\n    public:\n      UnsatisfiedExtend(Backtraces traces, Extension extension);\n      virtual ~UnsatisfiedExtend() throw() {};\n    };\n\n    class ExtendAcrossMedia : public Base {\n    public:\n      ExtendAcrossMedia(Backtraces traces, Extension extension);\n      virtual ~ExtendAcrossMedia() throw() {};\n    };\n\n  }\n\n  void warn(sass::string msg, SourceSpan pstate);\n  void warn(sass::string msg, SourceSpan pstate, Backtrace* bt);\n  void warning(sass::string msg, SourceSpan pstate);\n\n  void deprecated_function(sass::string msg, SourceSpan pstate);\n  void deprecated(sass::string msg, sass::string msg2, bool with_column, SourceSpan pstate);\n  void deprecated_bind(sass::string msg, SourceSpan pstate);\n  // void deprecated(sass::string msg, SourceSpan pstate, Backtrace* bt);\n\n  void coreError(sass::string msg, SourceSpan pstate);\n  void error(sass::string msg, SourceSpan pstate, Backtraces& traces);\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/eval.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <cstdlib>\n#include <cmath>\n#include <iostream>\n#include <sstream>\n#include <iomanip>\n#include <typeinfo>\n\n#include \"file.hpp\"\n#include \"eval.hpp\"\n#include \"ast.hpp\"\n#include \"bind.hpp\"\n#include \"util.hpp\"\n#include \"inspect.hpp\"\n#include \"operators.hpp\"\n#include \"environment.hpp\"\n#include \"position.hpp\"\n#include \"sass/values.h\"\n#include \"to_value.hpp\"\n#include \"ast2c.hpp\"\n#include \"c2ast.hpp\"\n#include \"context.hpp\"\n#include \"backtrace.hpp\"\n#include \"lexer.hpp\"\n#include \"prelexer.hpp\"\n#include \"parser.hpp\"\n#include \"expand.hpp\"\n#include \"color_maps.hpp\"\n#include \"sass_functions.hpp\"\n#include \"error_handling.hpp\"\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  Eval::Eval(Expand& exp)\n  : exp(exp),\n    ctx(exp.ctx),\n    traces(exp.traces),\n    force(false),\n    is_in_comment(false),\n    is_in_selector_schema(false)\n  {\n    bool_true = SASS_MEMORY_NEW(Boolean, \"[NA]\", true);\n    bool_false = SASS_MEMORY_NEW(Boolean, \"[NA]\", false);\n  }\n  Eval::~Eval() { }\n\n  Env* Eval::environment()\n  {\n    return exp.environment();\n  }\n\n  const sass::string Eval::cwd()\n  {\n    return ctx.cwd();\n  }\n\n  struct Sass_Inspect_Options& Eval::options()\n  {\n    return ctx.c_options;\n  }\n\n  struct Sass_Compiler* Eval::compiler()\n  {\n    return ctx.c_compiler;\n  }\n\n  EnvStack& Eval::env_stack()\n  {\n    return exp.env_stack;\n  }\n\n  sass::vector<Sass_Callee>& Eval::callee_stack()\n  {\n    return ctx.callee_stack;\n  }\n\n  Expression* Eval::operator()(Block* b)\n  {\n    Expression* val = 0;\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      val = b->at(i)->perform(this);\n      if (val) return val;\n    }\n    return val;\n  }\n\n  Expression* Eval::operator()(Assignment* a)\n  {\n    Env* env = environment();\n    sass::string var(a->variable());\n    if (a->is_global()) {\n      if (!env->has_global(var)) {\n        deprecated(\n          \"!global assignments won't be able to declare new variables in future versions.\",\n          \"Consider adding `\" + var + \": null` at the top level.\",\n          true, a->pstate());\n      }\n      if (a->is_default()) {\n        if (env->has_global(var)) {\n          Expression* e = Cast<Expression>(env->get_global(var));\n          if (!e || e->concrete_type() == Expression::NULL_VAL) {\n            env->set_global(var, a->value()->perform(this));\n          }\n        }\n        else {\n          env->set_global(var, a->value()->perform(this));\n        }\n      }\n      else {\n        env->set_global(var, a->value()->perform(this));\n      }\n    }\n    else if (a->is_default()) {\n      if (env->has_lexical(var)) {\n        auto cur = env;\n        while (cur && cur->is_lexical()) {\n          if (cur->has_local(var)) {\n            if (AST_Node_Obj node = cur->get_local(var)) {\n              Expression* e = Cast<Expression>(node);\n              if (!e || e->concrete_type() == Expression::NULL_VAL) {\n                cur->set_local(var, a->value()->perform(this));\n              }\n            }\n            else {\n              throw std::runtime_error(\"Env not in sync\");\n            }\n            return 0;\n          }\n          cur = cur->parent();\n        }\n        throw std::runtime_error(\"Env not in sync\");\n      }\n      else if (env->has_global(var)) {\n        if (AST_Node_Obj node = env->get_global(var)) {\n          Expression* e = Cast<Expression>(node);\n          if (!e || e->concrete_type() == Expression::NULL_VAL) {\n            env->set_global(var, a->value()->perform(this));\n          }\n        }\n      }\n      else if (env->is_lexical()) {\n        env->set_local(var, a->value()->perform(this));\n      }\n      else {\n        env->set_local(var, a->value()->perform(this));\n      }\n    }\n    else {\n      env->set_lexical(var, a->value()->perform(this));\n    }\n    return 0;\n  }\n\n  Expression* Eval::operator()(If* i)\n  {\n    ExpressionObj rv;\n    Env env(environment());\n    env_stack().push_back(&env);\n    ExpressionObj cond = i->predicate()->perform(this);\n    if (!cond->is_false()) {\n      rv = i->block()->perform(this);\n    }\n    else {\n      Block_Obj alt = i->alternative();\n      if (alt) rv = alt->perform(this);\n    }\n    env_stack().pop_back();\n    return rv.detach();\n  }\n\n  // For does not create a new env scope\n  // But iteration vars are reset afterwards\n  Expression* Eval::operator()(ForRule* f)\n  {\n    sass::string variable(f->variable());\n    ExpressionObj low = f->lower_bound()->perform(this);\n    if (low->concrete_type() != Expression::NUMBER) {\n      traces.push_back(Backtrace(low->pstate()));\n      throw Exception::TypeMismatch(traces, *low, \"integer\");\n    }\n    ExpressionObj high = f->upper_bound()->perform(this);\n    if (high->concrete_type() != Expression::NUMBER) {\n      traces.push_back(Backtrace(high->pstate()));\n      throw Exception::TypeMismatch(traces, *high, \"integer\");\n    }\n    Number_Obj sass_start = Cast<Number>(low);\n    Number_Obj sass_end = Cast<Number>(high);\n    // check if units are valid for sequence\n    if (sass_start->unit() != sass_end->unit()) {\n      sass::ostream msg; msg << \"Incompatible units: '\"\n        << sass_end->unit() << \"' and '\"\n        << sass_start->unit() << \"'.\";\n      error(msg.str(), low->pstate(), traces);\n    }\n    double start = sass_start->value();\n    double end = sass_end->value();\n    // only create iterator once in this environment\n    Env env(environment(), true);\n    env_stack().push_back(&env);\n    Block_Obj body = f->block();\n    Expression* val = 0;\n    if (start < end) {\n      if (f->is_inclusive()) ++end;\n      for (double i = start;\n           i < end;\n           ++i) {\n        Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());\n        env.set_local(variable, it);\n        val = body->perform(this);\n        if (val) break;\n      }\n    } else {\n      if (f->is_inclusive()) --end;\n      for (double i = start;\n           i > end;\n           --i) {\n        Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());\n        env.set_local(variable, it);\n        val = body->perform(this);\n        if (val) break;\n      }\n    }\n    env_stack().pop_back();\n    return val;\n  }\n\n  // Eval does not create a new env scope\n  // But iteration vars are reset afterwards\n  Expression* Eval::operator()(EachRule* e)\n  {\n    sass::vector<sass::string> variables(e->variables());\n    ExpressionObj expr = e->list()->perform(this);\n    Env env(environment(), true);\n    env_stack().push_back(&env);\n    List_Obj list;\n    Map* map = nullptr;\n    if (expr->concrete_type() == Expression::MAP) {\n      map = Cast<Map>(expr);\n    }\n    else if (SelectorList * ls = Cast<SelectorList>(expr)) {\n      ExpressionObj rv = Listize::perform(ls);\n      list = Cast<List>(rv);\n    }\n    else if (expr->concrete_type() != Expression::LIST) {\n      list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA);\n      list->append(expr);\n    }\n    else {\n      list = Cast<List>(expr);\n    }\n\n    Block_Obj body = e->block();\n    ExpressionObj val;\n\n    if (map) {\n      for (ExpressionObj key : map->keys()) {\n        ExpressionObj value = map->at(key);\n\n        if (variables.size() == 1) {\n          List* variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);\n          variable->append(key);\n          variable->append(value);\n          env.set_local(variables[0], variable);\n        } else {\n          env.set_local(variables[0], key);\n          env.set_local(variables[1], value);\n        }\n\n        val = body->perform(this);\n        if (val) break;\n      }\n    }\n    else {\n      if (list->length() == 1 && Cast<SelectorList>(list)) {\n        list = Cast<List>(list);\n      }\n      for (size_t i = 0, L = list->length(); i < L; ++i) {\n        Expression* item = list->at(i);\n        // unwrap value if the expression is an argument\n        if (Argument* arg = Cast<Argument>(item)) item = arg->value();\n        // check if we got passed a list of args (investigate)\n        if (List* scalars = Cast<List>(item)) {\n          if (variables.size() == 1) {\n            Expression* var = scalars;\n            env.set_local(variables[0], var);\n          } else {\n            // https://github.com/sass/libsass/issues/3078\n            for (size_t j = 0, K = variables.size(); j < K; ++j) {\n              env.set_local(variables[j], j >= scalars->length()\n                ? SASS_MEMORY_NEW(Null, expr->pstate()) : scalars->at(j));\n            }\n          }\n        } else {\n          if (variables.size() > 0) {\n            env.set_local(variables.at(0), item);\n            for (size_t j = 1, K = variables.size(); j < K; ++j) {\n              // XXX: this is never hit via spec tests\n              Expression* res = SASS_MEMORY_NEW(Null, expr->pstate());\n              env.set_local(variables[j], res);\n            }\n          }\n        }\n        val = body->perform(this);\n        if (val) break;\n      }\n    }\n    env_stack().pop_back();\n    return val.detach();\n  }\n\n  Expression* Eval::operator()(WhileRule* w)\n  {\n    ExpressionObj pred = w->predicate();\n    Block_Obj body = w->block();\n    Env env(environment(), true);\n    env_stack().push_back(&env);\n    ExpressionObj cond = pred->perform(this);\n    while (!cond->is_false()) {\n      ExpressionObj val = body->perform(this);\n      if (val) {\n        env_stack().pop_back();\n        return val.detach();\n      }\n      cond = pred->perform(this);\n    }\n    env_stack().pop_back();\n    return 0;\n  }\n\n  Expression* Eval::operator()(Return* r)\n  {\n    return r->value()->perform(this);\n  }\n\n  Expression* Eval::operator()(WarningRule* w)\n  {\n    Sass_Output_Style outstyle = options().output_style;\n    options().output_style = NESTED;\n    ExpressionObj message = w->message()->perform(this);\n    Env* env = environment();\n\n    // try to use generic function\n    if (env->has(\"@warn[f]\")) {\n\n      // add call stack entry\n      callee_stack().push_back({\n        \"@warn\",\n        w->pstate().getPath(),\n        w->pstate().getLine(),\n        w->pstate().getColumn(),\n        SASS_CALLEE_FUNCTION,\n        { env }\n      });\n\n      Definition* def = Cast<Definition>((*env)[\"@warn[f]\"]);\n      // Block_Obj          body   = def->block();\n      // Native_Function func   = def->native_function();\n      Sass_Function_Entry c_function = def->c_function();\n      Sass_Function_Fn c_func = sass_function_get_function(c_function);\n\n      AST2C ast2c;\n      union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);\n      sass_list_set_value(c_args, 0, message->perform(&ast2c));\n      union Sass_Value* c_val = c_func(c_args, c_function, compiler());\n      options().output_style = outstyle;\n      callee_stack().pop_back();\n      sass_delete_value(c_args);\n      sass_delete_value(c_val);\n      return 0;\n\n    }\n\n    sass::string result(unquote(message->to_sass()));\n    std::cerr << \"WARNING: \" << result << std::endl;\n    traces.push_back(Backtrace(w->pstate()));\n    std::cerr << traces_to_string(traces, \"         \");\n    std::cerr << std::endl;\n    options().output_style = outstyle;\n    traces.pop_back();\n    return 0;\n  }\n\n  Expression* Eval::operator()(ErrorRule* e)\n  {\n    Sass_Output_Style outstyle = options().output_style;\n    options().output_style = NESTED;\n    ExpressionObj message = e->message()->perform(this);\n    Env* env = environment();\n\n    // try to use generic function\n    if (env->has(\"@error[f]\")) {\n\n      // add call stack entry\n      callee_stack().push_back({\n        \"@error\",\n        e->pstate().getPath(),\n        e->pstate().getLine(),\n        e->pstate().getColumn(),\n        SASS_CALLEE_FUNCTION,\n        { env }\n      });\n\n      Definition* def = Cast<Definition>((*env)[\"@error[f]\"]);\n      // Block_Obj          body   = def->block();\n      // Native_Function func   = def->native_function();\n      Sass_Function_Entry c_function = def->c_function();\n      Sass_Function_Fn c_func = sass_function_get_function(c_function);\n\n      AST2C ast2c;\n      union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);\n      sass_list_set_value(c_args, 0, message->perform(&ast2c));\n      union Sass_Value* c_val = c_func(c_args, c_function, compiler());\n      options().output_style = outstyle;\n      callee_stack().pop_back();\n      sass_delete_value(c_args);\n      sass_delete_value(c_val);\n      return 0;\n\n    }\n\n    sass::string result(unquote(message->to_sass()));\n    options().output_style = outstyle;\n    error(result, e->pstate(), traces);\n    return 0;\n  }\n\n  Expression* Eval::operator()(DebugRule* d)\n  {\n    Sass_Output_Style outstyle = options().output_style;\n    options().output_style = NESTED;\n    ExpressionObj message = d->value()->perform(this);\n    Env* env = environment();\n\n    // try to use generic function\n    if (env->has(\"@debug[f]\")) {\n\n      // add call stack entry\n      callee_stack().push_back({\n        \"@debug\",\n        d->pstate().getPath(),\n        d->pstate().getLine(),\n        d->pstate().getColumn(),\n        SASS_CALLEE_FUNCTION,\n        { env }\n      });\n\n      Definition* def = Cast<Definition>((*env)[\"@debug[f]\"]);\n      // Block_Obj          body   = def->block();\n      // Native_Function func   = def->native_function();\n      Sass_Function_Entry c_function = def->c_function();\n      Sass_Function_Fn c_func = sass_function_get_function(c_function);\n\n      AST2C ast2c;\n      union Sass_Value* c_args = sass_make_list(1, SASS_COMMA, false);\n      sass_list_set_value(c_args, 0, message->perform(&ast2c));\n      union Sass_Value* c_val = c_func(c_args, c_function, compiler());\n      options().output_style = outstyle;\n      callee_stack().pop_back();\n      sass_delete_value(c_args);\n      sass_delete_value(c_val);\n      return 0;\n\n    }\n\n    sass::string result(unquote(message->to_sass()));\n    sass::string abs_path(Sass::File::rel2abs(d->pstate().getPath(), cwd(), cwd()));\n    sass::string rel_path(Sass::File::abs2rel(d->pstate().getPath(), cwd(), cwd()));\n    sass::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().getPath()));\n    options().output_style = outstyle;\n\n    std::cerr << output_path << \":\" << d->pstate().getLine() << \" DEBUG: \" << result;\n    std::cerr << std::endl;\n    return 0;\n  }\n\n\n  Expression* Eval::operator()(List* l)\n  {\n    // special case for unevaluated map\n    if (l->separator() == SASS_HASH) {\n      Map_Obj lm = SASS_MEMORY_NEW(Map,\n                                l->pstate(),\n                                l->length() / 2);\n      for (size_t i = 0, L = l->length(); i < L; i += 2)\n      {\n        ExpressionObj key = (*l)[i+0]->perform(this);\n        ExpressionObj val = (*l)[i+1]->perform(this);\n        // make sure the color key never displays its real name\n        key->is_delayed(true); // verified\n        *lm << std::make_pair(key, val);\n      }\n      if (lm->has_duplicate_key()) {\n        traces.push_back(Backtrace(l->pstate()));\n        throw Exception::DuplicateKeyError(traces, *lm, *l);\n      }\n\n      lm->is_interpolant(l->is_interpolant());\n      return lm->perform(this);\n    }\n    // check if we should expand it\n    if (l->is_expanded()) return l;\n    // regular case for unevaluated lists\n    List_Obj ll = SASS_MEMORY_NEW(List,\n                               l->pstate(),\n                               l->length(),\n                               l->separator(),\n                               l->is_arglist(),\n                               l->is_bracketed());\n    for (size_t i = 0, L = l->length(); i < L; ++i) {\n      ll->append((*l)[i]->perform(this));\n    }\n    ll->is_interpolant(l->is_interpolant());\n    ll->from_selector(l->from_selector());\n    ll->is_expanded(true);\n    return ll.detach();\n  }\n\n  Expression* Eval::operator()(Map* m)\n  {\n    if (m->is_expanded()) return m;\n\n    // make sure we're not starting with duplicate keys.\n    // the duplicate key state will have been set in the parser phase.\n    if (m->has_duplicate_key()) {\n      traces.push_back(Backtrace(m->pstate()));\n      throw Exception::DuplicateKeyError(traces, *m, *m);\n    }\n\n    Map_Obj mm = SASS_MEMORY_NEW(Map,\n                                m->pstate(),\n                                m->length());\n    for (auto key : m->keys()) {\n      Expression* ex_key = key->perform(this);\n      Expression* ex_val = m->at(key);\n      if (ex_val == NULL) continue;\n      ex_val = ex_val->perform(this);\n      *mm << std::make_pair(ex_key, ex_val);\n    }\n\n    // check the evaluated keys aren't duplicates.\n    if (mm->has_duplicate_key()) {\n      traces.push_back(Backtrace(m->pstate()));\n      throw Exception::DuplicateKeyError(traces, *mm, *m);\n    }\n\n    mm->is_expanded(true);\n    return mm.detach();\n  }\n\n  Expression* Eval::operator()(Binary_Expression* b_in)\n  {\n\n    ExpressionObj lhs = b_in->left();\n    ExpressionObj rhs = b_in->right();\n    enum Sass_OP op_type = b_in->optype();\n\n    if (op_type == Sass_OP::AND) {\n      // LOCAL_FLAG(force, true);\n      lhs = lhs->perform(this);\n      if (!*lhs) return lhs.detach();\n      return rhs->perform(this);\n    }\n    else if (op_type == Sass_OP::OR) {\n      // LOCAL_FLAG(force, true);\n      lhs = lhs->perform(this);\n      if (*lhs) return lhs.detach();\n      return rhs->perform(this);\n    }\n\n    // Evaluate variables as early o\n    while (Variable* l_v = Cast<Variable>(lhs)) {\n      lhs = operator()(l_v);\n    }\n    while (Variable* r_v = Cast<Variable>(rhs)) {\n      rhs = operator()(r_v);\n    }\n\n    Binary_ExpressionObj b = b_in;\n\n    // Evaluate sub-expressions early on\n    while (Binary_Expression* l_b = Cast<Binary_Expression>(lhs)) {\n      if (!force && l_b->is_delayed()) break;\n      lhs = operator()(l_b);\n    }\n    while (Binary_Expression* r_b = Cast<Binary_Expression>(rhs)) {\n      if (!force && r_b->is_delayed()) break;\n      rhs = operator()(r_b);\n    }\n\n    // don't eval delayed expressions (the '/' when used as a separator)\n    if (!force && op_type == Sass_OP::DIV && b->is_delayed()) {\n      b->right(b->right()->perform(this));\n      b->left(b->left()->perform(this));\n      return b.detach();\n    }\n\n    // specific types we know are final\n    // handle them early to avoid overhead\n    if (Number* l_n = Cast<Number>(lhs)) {\n      // lhs is number and rhs is number\n      if (Number* r_n = Cast<Number>(rhs)) {\n        try {\n          switch (op_type) {\n            case Sass_OP::EQ: return *l_n == *r_n ? bool_true : bool_false;\n            case Sass_OP::NEQ: return *l_n == *r_n ? bool_false : bool_true;\n            case Sass_OP::LT: return *l_n < *r_n ? bool_true : bool_false;\n            case Sass_OP::GTE: return *l_n < *r_n ? bool_false : bool_true;\n            case Sass_OP::LTE: return *l_n < *r_n || *l_n == *r_n ? bool_true : bool_false;\n            case Sass_OP::GT: return *l_n < *r_n || *l_n == *r_n ? bool_false : bool_true;\n            case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:\n              return Operators::op_numbers(op_type, *l_n, *r_n, options(), b_in->pstate());\n            default: break;\n          }\n        }\n        catch (Exception::OperationError& err)\n        {\n          traces.push_back(Backtrace(b_in->pstate()));\n          throw Exception::SassValueError(traces, b_in->pstate(), err);\n        }\n      }\n      // lhs is number and rhs is color\n      // Todo: allow to work with HSLA colors\n      else if (Color* r_col = Cast<Color>(rhs)) {\n        Color_RGBA_Obj r_c = r_col->toRGBA();\n        try {\n          switch (op_type) {\n            case Sass_OP::EQ: return *l_n == *r_c ? bool_true : bool_false;\n            case Sass_OP::NEQ: return *l_n == *r_c ? bool_false : bool_true;\n            case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:\n              return Operators::op_number_color(op_type, *l_n, *r_c, options(), b_in->pstate());\n            default: break;\n          }\n        }\n        catch (Exception::OperationError& err)\n        {\n          traces.push_back(Backtrace(b_in->pstate()));\n          throw Exception::SassValueError(traces, b_in->pstate(), err);\n        }\n      }\n    }\n    else if (Color* l_col = Cast<Color>(lhs)) {\n      Color_RGBA_Obj l_c = l_col->toRGBA();\n      // lhs is color and rhs is color\n      if (Color* r_col = Cast<Color>(rhs)) {\n        Color_RGBA_Obj r_c = r_col->toRGBA();\n        try {\n          switch (op_type) {\n            case Sass_OP::EQ: return *l_c == *r_c ? bool_true : bool_false;\n            case Sass_OP::NEQ: return *l_c == *r_c ? bool_false : bool_true;\n            case Sass_OP::LT: return *l_c < *r_c ? bool_true : bool_false;\n            case Sass_OP::GTE: return *l_c < *r_c ? bool_false : bool_true;\n            case Sass_OP::LTE: return *l_c < *r_c || *l_c == *r_c ? bool_true : bool_false;\n            case Sass_OP::GT: return *l_c < *r_c || *l_c == *r_c ? bool_false : bool_true;\n            case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:\n              return Operators::op_colors(op_type, *l_c, *r_c, options(), b_in->pstate());\n            default: break;\n          }\n        }\n        catch (Exception::OperationError& err)\n        {\n          traces.push_back(Backtrace(b_in->pstate()));\n          throw Exception::SassValueError(traces, b_in->pstate(), err);\n        }\n      }\n      // lhs is color and rhs is number\n      else if (Number* r_n = Cast<Number>(rhs)) {\n        try {\n          switch (op_type) {\n            case Sass_OP::EQ: return *l_c == *r_n ? bool_true : bool_false;\n            case Sass_OP::NEQ: return *l_c == *r_n ? bool_false : bool_true;\n            case Sass_OP::ADD: case Sass_OP::SUB: case Sass_OP::MUL: case Sass_OP::DIV: case Sass_OP::MOD:\n              return Operators::op_color_number(op_type, *l_c, *r_n, options(), b_in->pstate());\n            default: break;\n          }\n        }\n        catch (Exception::OperationError& err)\n        {\n          traces.push_back(Backtrace(b_in->pstate()));\n          throw Exception::SassValueError(traces, b_in->pstate(), err);\n        }\n      }\n    }\n\n    String_Schema_Obj ret_schema;\n\n    // only the last item will be used to eval the binary expression\n    if (String_Schema* s_l = Cast<String_Schema>(b->left())) {\n      if (!s_l->has_interpolant() && (!s_l->is_right_interpolant())) {\n        ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate());\n        Binary_ExpressionObj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(),\n                                                    b->op(), s_l->last(), b->right());\n        bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // unverified\n        for (size_t i = 0; i < s_l->length() - 1; ++i) {\n          ret_schema->append(s_l->at(i)->perform(this));\n        }\n        ret_schema->append(bin_ex->perform(this));\n        return ret_schema->perform(this);\n      }\n    }\n    if (String_Schema* s_r = Cast<String_Schema>(b->right())) {\n\n      if (!s_r->has_interpolant() && (!s_r->is_left_interpolant() || op_type == Sass_OP::DIV)) {\n        ret_schema = SASS_MEMORY_NEW(String_Schema, b->pstate());\n        Binary_ExpressionObj bin_ex = SASS_MEMORY_NEW(Binary_Expression, b->pstate(),\n                                                    b->op(), b->left(), s_r->first());\n        bin_ex->is_delayed(b->left()->is_delayed() || b->right()->is_delayed()); // verified\n        ret_schema->append(bin_ex->perform(this));\n        for (size_t i = 1; i < s_r->length(); ++i) {\n          ret_schema->append(s_r->at(i)->perform(this));\n        }\n        return ret_schema->perform(this);\n      }\n    }\n\n    // fully evaluate their values\n    if (op_type == Sass_OP::EQ ||\n        op_type == Sass_OP::NEQ ||\n        op_type == Sass_OP::GT ||\n        op_type == Sass_OP::GTE ||\n        op_type == Sass_OP::LT ||\n        op_type == Sass_OP::LTE)\n    {\n      LOCAL_FLAG(force, true);\n      lhs->is_expanded(false);\n      lhs->set_delayed(false);\n      lhs = lhs->perform(this);\n      rhs->is_expanded(false);\n      rhs->set_delayed(false);\n      rhs = rhs->perform(this);\n    }\n    else {\n      lhs = lhs->perform(this);\n    }\n\n    // not a logical connective, so go ahead and eval the rhs\n    rhs = rhs->perform(this);\n    AST_Node_Obj lu = lhs;\n    AST_Node_Obj ru = rhs;\n\n    Expression::Type l_type;\n    Expression::Type r_type;\n\n    // Is one of the operands an interpolant?\n    String_Schema_Obj s1 = Cast<String_Schema>(b->left());\n    String_Schema_Obj s2 = Cast<String_Schema>(b->right());\n    Binary_ExpressionObj b1 = Cast<Binary_Expression>(b->left());\n    Binary_ExpressionObj b2 = Cast<Binary_Expression>(b->right());\n\n    bool schema_op = false;\n\n    bool force_delay = (s2 && s2->is_left_interpolant()) ||\n                       (s1 && s1->is_right_interpolant()) ||\n                       (b1 && b1->is_right_interpolant()) ||\n                       (b2 && b2->is_left_interpolant());\n\n    if ((s1 && s1->has_interpolants()) || (s2 && s2->has_interpolants()) || force_delay)\n    {\n      if (op_type == Sass_OP::DIV || op_type == Sass_OP::MUL || op_type == Sass_OP::MOD || op_type == Sass_OP::ADD || op_type == Sass_OP::SUB ||\n          op_type == Sass_OP::EQ) {\n        // If possible upgrade LHS to a number (for number to string compare)\n        if (String_Constant* str = Cast<String_Constant>(lhs)) {\n          sass::string value(str->value());\n          const char* start = value.c_str();\n          if (Prelexer::sequence < Prelexer::dimension, Prelexer::end_of_file >(start) != 0) {\n            lhs = Parser::lexed_dimension(b->pstate(), str->value());\n          }\n        }\n        // If possible upgrade RHS to a number (for string to number compare)\n        if (String_Constant* str = Cast<String_Constant>(rhs)) {\n          sass::string value(str->value());\n          const char* start = value.c_str();\n          if (Prelexer::sequence < Prelexer::dimension, Prelexer::number >(start) != 0) {\n            rhs = Parser::lexed_dimension(b->pstate(), str->value());\n          }\n        }\n      }\n\n      To_Value to_value(ctx);\n      ValueObj v_l = Cast<Value>(lhs->perform(&to_value));\n      ValueObj v_r = Cast<Value>(rhs->perform(&to_value));\n\n      if (force_delay) {\n        sass::string str(\"\");\n        str += v_l->to_string(options());\n        if (b->op().ws_before) str += \" \";\n        str += b->separator();\n        if (b->op().ws_after) str += \" \";\n        str += v_r->to_string(options());\n        String_Constant* val = SASS_MEMORY_NEW(String_Constant, b->pstate(), str);\n        val->is_interpolant(b->left()->has_interpolant());\n        return val;\n      }\n    }\n\n    // see if it's a relational expression\n    try {\n      switch(op_type) {\n        case Sass_OP::EQ:  return SASS_MEMORY_NEW(Boolean, b->pstate(), Operators::eq(lhs, rhs));\n        case Sass_OP::NEQ: return SASS_MEMORY_NEW(Boolean, b->pstate(), Operators::neq(lhs, rhs));\n        case Sass_OP::GT:  return SASS_MEMORY_NEW(Boolean, b->pstate(), Operators::gt(lhs, rhs));\n        case Sass_OP::GTE: return SASS_MEMORY_NEW(Boolean, b->pstate(), Operators::gte(lhs, rhs));\n        case Sass_OP::LT:  return SASS_MEMORY_NEW(Boolean, b->pstate(), Operators::lt(lhs, rhs));\n        case Sass_OP::LTE: return SASS_MEMORY_NEW(Boolean, b->pstate(), Operators::lte(lhs, rhs));\n        default: break;\n      }\n    }\n    catch (Exception::OperationError& err)\n    {\n      traces.push_back(Backtrace(b->pstate()));\n      throw Exception::SassValueError(traces, b->pstate(), err);\n    }\n\n    l_type = lhs->concrete_type();\n    r_type = rhs->concrete_type();\n\n    // ToDo: throw error in op functions\n    // ToDo: then catch and re-throw them\n    ExpressionObj rv;\n    try {\n      SourceSpan pstate(b->pstate());\n      if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {\n        Number* l_n = Cast<Number>(lhs);\n        Number* r_n = Cast<Number>(rhs);\n        l_n->reduce(); r_n->reduce();\n        rv = Operators::op_numbers(op_type, *l_n, *r_n, options(), pstate);\n      }\n      else if (l_type == Expression::NUMBER && r_type == Expression::COLOR) {\n        Number* l_n = Cast<Number>(lhs);\n        Color_RGBA_Obj r_c = Cast<Color>(rhs)->toRGBA();\n        rv = Operators::op_number_color(op_type, *l_n, *r_c, options(), pstate);\n      }\n      else if (l_type == Expression::COLOR && r_type == Expression::NUMBER) {\n        Color_RGBA_Obj l_c = Cast<Color>(lhs)->toRGBA();\n        Number* r_n = Cast<Number>(rhs);\n        rv = Operators::op_color_number(op_type, *l_c, *r_n, options(), pstate);\n      }\n      else if (l_type == Expression::COLOR && r_type == Expression::COLOR) {\n        Color_RGBA_Obj l_c = Cast<Color>(lhs)->toRGBA();\n        Color_RGBA_Obj r_c = Cast<Color>(rhs)->toRGBA();\n        rv = Operators::op_colors(op_type, *l_c, *r_c, options(), pstate);\n      }\n      else {\n        To_Value to_value(ctx);\n        // this will leak if perform does not return a value!\n        ValueObj v_l = Cast<Value>(lhs->perform(&to_value));\n        ValueObj v_r = Cast<Value>(rhs->perform(&to_value));\n        bool interpolant = b->is_right_interpolant() ||\n                           b->is_left_interpolant() ||\n                           b->is_interpolant();\n        if (op_type == Sass_OP::SUB) interpolant = false;\n        // if (op_type == Sass_OP::DIV) interpolant = true;\n        // check for type violations\n        if (l_type == Expression::MAP || l_type == Expression::FUNCTION_VAL) {\n          traces.push_back(Backtrace(v_l->pstate()));\n          throw Exception::InvalidValue(traces, *v_l);\n        }\n        if (r_type == Expression::MAP || l_type == Expression::FUNCTION_VAL) {\n          traces.push_back(Backtrace(v_r->pstate()));\n          throw Exception::InvalidValue(traces, *v_r);\n        }\n        Value* ex = Operators::op_strings(b->op(), *v_l, *v_r, options(), pstate, !interpolant); // pass true to compress\n        if (String_Constant* str = Cast<String_Constant>(ex))\n        {\n          if (str->concrete_type() == Expression::STRING)\n          {\n            String_Constant* lstr = Cast<String_Constant>(lhs);\n            String_Constant* rstr = Cast<String_Constant>(rhs);\n            if (op_type != Sass_OP::SUB) {\n              if (String_Constant* org = lstr ? lstr : rstr)\n              { str->quote_mark(org->quote_mark()); }\n            }\n          }\n        }\n        ex->is_interpolant(b->is_interpolant());\n        rv = ex;\n      }\n    }\n    catch (Exception::OperationError& err)\n    {\n      traces.push_back(Backtrace(b->pstate()));\n      // throw Exception::Base(b->pstate(), err.what());\n      throw Exception::SassValueError(traces, b->pstate(), err);\n    }\n\n    if (rv) {\n      if (schema_op) {\n        // XXX: this is never hit via spec tests\n        (*s2)[0] = rv;\n        rv = s2->perform(this);\n      }\n    }\n\n    return rv.detach();\n\n  }\n\n  Expression* Eval::operator()(Unary_Expression* u)\n  {\n    ExpressionObj operand = u->operand()->perform(this);\n    if (u->optype() == Unary_Expression::NOT) {\n      Boolean* result = SASS_MEMORY_NEW(Boolean, u->pstate(), (bool)*operand);\n      result->value(!result->value());\n      return result;\n    }\n    else if (Number_Obj nr = Cast<Number>(operand)) {\n      // negate value for minus unary expression\n      if (u->optype() == Unary_Expression::MINUS) {\n        Number_Obj cpy = SASS_MEMORY_COPY(nr);\n        cpy->value( - cpy->value() ); // negate value\n        return cpy.detach(); // return the copy\n      }\n      else if (u->optype() == Unary_Expression::SLASH) {\n        sass::string str = '/' + nr->to_string(options());\n        return SASS_MEMORY_NEW(String_Constant, u->pstate(), str);\n      }\n      // nothing for positive\n      return nr.detach();\n    }\n    else {\n      // Special cases: +/- variables which evaluate to null output just +/-,\n      // but +/- null itself outputs the string\n      if (operand->concrete_type() == Expression::NULL_VAL && Cast<Variable>(u->operand())) {\n        u->operand(SASS_MEMORY_NEW(String_Quoted, u->pstate(), \"\"));\n      }\n      // Never apply unary opertions on colors @see #2140\n      else if (Color* color = Cast<Color>(operand)) {\n        // Use the color name if this was eval with one\n        if (color->disp().length() > 0) {\n          Unary_ExpressionObj cpy = SASS_MEMORY_COPY(u);\n          cpy->operand(SASS_MEMORY_NEW(String_Constant, operand->pstate(), color->disp()));\n          return SASS_MEMORY_NEW(String_Quoted,\n                                 cpy->pstate(),\n                                 cpy->inspect());\n        }\n      }\n      else {\n        Unary_ExpressionObj cpy = SASS_MEMORY_COPY(u);\n        cpy->operand(operand);\n        return SASS_MEMORY_NEW(String_Quoted,\n                               cpy->pstate(),\n                               cpy->inspect());\n      }\n\n      return SASS_MEMORY_NEW(String_Quoted,\n                             u->pstate(),\n                             u->inspect());\n    }\n    // unreachable\n    return u;\n  }\n\n  Expression* Eval::operator()(Function_Call* c)\n  {\n    if (traces.size() > Constants::MaxCallStack) {\n        // XXX: this is never hit via spec tests\n        sass::ostream stm;\n        stm << \"Stack depth exceeded max of \" << Constants::MaxCallStack;\n        error(stm.str(), c->pstate(), traces);\n    }\n\n    if (Cast<String_Schema>(c->sname())) {\n      ExpressionObj evaluated_name = c->sname()->perform(this);\n      ExpressionObj evaluated_args = c->arguments()->perform(this);\n      sass::string str(evaluated_name->to_string());\n      str += evaluated_args->to_string();\n      return SASS_MEMORY_NEW(String_Constant, c->pstate(), str);\n    }\n\n    sass::string name(Util::normalize_underscores(c->name()));\n    sass::string full_name(name + \"[f]\");\n\n    // we make a clone here, need to implement that further\n    Arguments_Obj args = c->arguments();\n\n    Env* env = environment();\n    if (!env->has(full_name) || (!c->via_call() && Prelexer::re_special_fun(name.c_str()))) {\n      if (!env->has(\"*[f]\")) {\n        for (Argument_Obj arg : args->elements()) {\n          if (List_Obj ls = Cast<List>(arg->value())) {\n            if (ls->size() == 0) error(\"() isn't a valid CSS value.\", c->pstate(), traces);\n          }\n        }\n        args = Cast<Arguments>(args->perform(this));\n        Function_Call_Obj lit = SASS_MEMORY_NEW(Function_Call,\n                                             c->pstate(),\n                                             c->name(),\n                                             args);\n        if (args->has_named_arguments()) {\n          error(\"Plain CSS function \" + c->name() + \" doesn't support keyword arguments\", c->pstate(), traces);\n        }\n        String_Quoted* str = SASS_MEMORY_NEW(String_Quoted,\n                                             c->pstate(),\n                                             lit->to_string(options()));\n        str->is_interpolant(c->is_interpolant());\n        return str;\n      } else {\n        // call generic function\n        full_name = \"*[f]\";\n      }\n    }\n\n    // further delay for calls\n    if (full_name != \"call[f]\") {\n      args->set_delayed(false); // verified\n    }\n    if (full_name != \"if[f]\") {\n      args = Cast<Arguments>(args->perform(this));\n    }\n    Definition* def = Cast<Definition>((*env)[full_name]);\n\n    if (c->func()) def = c->func()->definition();\n\n    if (def->is_overload_stub()) {\n      sass::ostream ss;\n      size_t L = args->length();\n      // account for rest arguments\n      if (args->has_rest_argument() && args->length() > 0) {\n        // get the rest arguments list\n        List* rest = Cast<List>(args->last()->value());\n        // arguments before rest argument plus rest\n        if (rest) L += rest->length() - 1;\n      }\n      ss << full_name << L;\n      full_name = ss.str();\n      sass::string resolved_name(full_name);\n      if (!env->has(resolved_name)) error(\"overloaded function `\" + sass::string(c->name()) + \"` given wrong number of arguments\", c->pstate(), traces);\n      def = Cast<Definition>((*env)[resolved_name]);\n    }\n\n    ExpressionObj     result = c;\n    Block_Obj          body   = def->block();\n    Native_Function func   = def->native_function();\n    Sass_Function_Entry c_function = def->c_function();\n\n    if (c->is_css()) return result.detach();\n\n    Parameters_Obj params = def->parameters();\n    Env fn_env(def->environment());\n    env_stack().push_back(&fn_env);\n\n    if (func || body) {\n      bind(sass::string(\"Function\"), c->name(), params, args, &fn_env, this, traces);\n      sass::string msg(\", in function `\" + c->name() + \"`\");\n      traces.push_back(Backtrace(c->pstate(), msg));\n      callee_stack().push_back({\n        c->name().c_str(),\n        c->pstate().getPath(),\n        c->pstate().getLine(),\n        c->pstate().getColumn(),\n        SASS_CALLEE_FUNCTION,\n        { env }\n      });\n\n      // eval the body if user-defined or special, invoke underlying CPP function if native\n      if (body /* && !Prelexer::re_special_fun(name.c_str()) */) {\n        result = body->perform(this);\n      }\n      else if (func) {\n        result = func(fn_env, *env, ctx, def->signature(), c->pstate(), traces, exp.getSelectorStack(), exp.originalStack);\n      }\n      if (!result) {\n        error(sass::string(\"Function \") + c->name() + \" finished without @return\", c->pstate(), traces);\n      }\n      callee_stack().pop_back();\n      traces.pop_back();\n    }\n\n    // else if it's a user-defined c function\n    // convert call into C-API compatible form\n    else if (c_function) {\n      Sass_Function_Fn c_func = sass_function_get_function(c_function);\n      if (full_name == \"*[f]\") {\n        String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, c->pstate(), c->name());\n        Arguments_Obj new_args = SASS_MEMORY_NEW(Arguments, c->pstate());\n        new_args->append(SASS_MEMORY_NEW(Argument, c->pstate(), str));\n        new_args->concat(args);\n        args = new_args;\n      }\n\n      // populates env with default values for params\n      sass::string ff(c->name());\n      bind(sass::string(\"Function\"), c->name(), params, args, &fn_env, this, traces);\n      sass::string msg(\", in function `\" + c->name() + \"`\");\n      traces.push_back(Backtrace(c->pstate(), msg));\n      callee_stack().push_back({\n        c->name().c_str(),\n        c->pstate().getPath(),\n        c->pstate().getLine(),\n        c->pstate().getColumn(),\n        SASS_CALLEE_C_FUNCTION,\n        { env }\n      });\n\n      AST2C ast2c;\n      union Sass_Value* c_args = sass_make_list(params->length(), SASS_COMMA, false);\n      for(size_t i = 0; i < params->length(); i++) {\n        Parameter_Obj param = params->at(i);\n        sass::string key = param->name();\n        AST_Node_Obj node = fn_env.get_local(key);\n        ExpressionObj arg = Cast<Expression>(node);\n        sass_list_set_value(c_args, i, arg->perform(&ast2c));\n      }\n      union Sass_Value* c_val = c_func(c_args, c_function, compiler());\n      if (sass_value_get_tag(c_val) == SASS_ERROR) {\n        sass::string message(\"error in C function \" + c->name() + \": \" + sass_error_get_message(c_val));\n        sass_delete_value(c_val);\n        sass_delete_value(c_args);\n        error(message, c->pstate(), traces);\n      } else if (sass_value_get_tag(c_val) == SASS_WARNING) {\n        sass::string message(\"warning in C function \" + c->name() + \": \" + sass_warning_get_message(c_val));\n        sass_delete_value(c_val);\n        sass_delete_value(c_args);\n        error(message, c->pstate(), traces);\n      }\n      result = c2ast(c_val, traces, c->pstate());\n\n      callee_stack().pop_back();\n      traces.pop_back();\n      sass_delete_value(c_args);\n      if (c_val != c_args)\n        sass_delete_value(c_val);\n    }\n\n    // link back to function definition\n    // only do this for custom functions\n    if (result->pstate().getSrcId() == sass::string::npos)\n      result->pstate(c->pstate());\n\n    result = result->perform(this);\n    result->is_interpolant(c->is_interpolant());\n    env_stack().pop_back();\n    return result.detach();\n  }\n\n  Expression* Eval::operator()(Variable* v)\n  {\n    ExpressionObj value;\n    Env* env = environment();\n    const sass::string& name(v->name());\n    EnvResult rv(env->find(name));\n    if (rv.found) value = static_cast<Expression*>(rv.it->second.ptr());\n    else error(\"Undefined variable: \\\"\" + v->name() + \"\\\".\", v->pstate(), traces);\n    if (Argument* arg = Cast<Argument>(value)) value = arg->value();\n    if (Number* nr = Cast<Number>(value)) nr->zero(true); // force flag\n    value->is_interpolant(v->is_interpolant());\n    if (force) value->is_expanded(false);\n    value->set_delayed(false); // verified\n    value = value->perform(this);\n    if(!force) rv.it->second = value;\n    return value.detach();\n  }\n\n  Expression* Eval::operator()(Color_RGBA* c)\n  {\n    return c;\n  }\n\n  Expression* Eval::operator()(Color_HSLA* c)\n  {\n    return c;\n  }\n\n  Expression* Eval::operator()(Number* n)\n  {\n    return n;\n  }\n\n  Expression* Eval::operator()(Boolean* b)\n  {\n    return b;\n  }\n\n  void Eval::interpolation(Context& ctx, sass::string& res, ExpressionObj ex, bool into_quotes, bool was_itpl) {\n\n    bool needs_closing_brace = false;\n\n    if (Arguments* args = Cast<Arguments>(ex)) {\n      List* ll = SASS_MEMORY_NEW(List, args->pstate(), 0, SASS_COMMA);\n      for(auto arg : args->elements()) {\n        ll->append(arg->value());\n      }\n      ll->is_interpolant(args->is_interpolant());\n      needs_closing_brace = true;\n      res += \"(\";\n      ex = ll;\n    }\n    if (Number* nr = Cast<Number>(ex)) {\n      Number reduced(nr);\n      reduced.reduce();\n      if (!reduced.is_valid_css_unit()) {\n        traces.push_back(Backtrace(nr->pstate()));\n        throw Exception::InvalidValue(traces, *nr);\n      }\n    }\n    if (Argument* arg = Cast<Argument>(ex)) {\n      ex = arg->value();\n    }\n    if (String_Quoted* sq = Cast<String_Quoted>(ex)) {\n      if (was_itpl) {\n        bool was_interpolant = ex->is_interpolant();\n        ex = SASS_MEMORY_NEW(String_Constant, sq->pstate(), sq->value());\n        ex->is_interpolant(was_interpolant);\n      }\n    }\n\n    if (Cast<Null>(ex)) { return; }\n\n    // parent selector needs another go\n    if (Cast<Parent_Reference>(ex)) {\n      // XXX: this is never hit via spec tests\n      ex = ex->perform(this);\n    }\n\n    if (List* l = Cast<List>(ex)) {\n      List_Obj ll = SASS_MEMORY_NEW(List, l->pstate(), 0, l->separator());\n      // this fixes an issue with bourbon sample, not really sure why\n      // if (l->size() && Cast<Null>((*l)[0])) { res += \"\"; }\n      for(ExpressionObj item : *l) {\n        item->is_interpolant(l->is_interpolant());\n        sass::string rl(\"\"); interpolation(ctx, rl, item, into_quotes, l->is_interpolant());\n        bool is_null = Cast<Null>(item) != 0; // rl != \"\"\n        if (!is_null) ll->append(SASS_MEMORY_NEW(String_Quoted, item->pstate(), rl));\n      }\n      // Check indicates that we probably should not get a list\n      // here. Normally single list items are already unwrapped.\n      if (l->size() > 1) {\n        // string_to_output would fail \"#{'_\\a' '_\\a'}\";\n        sass::string str(ll->to_string(options()));\n        str = read_hex_escapes(str); // read escapes\n        newline_to_space(str); // replace directly\n        res += str; // append to result string\n      } else {\n        res += (ll->to_string(options()));\n      }\n      ll->is_interpolant(l->is_interpolant());\n    }\n\n    // Value\n    // Function_Call\n    // Selector_List\n    // String_Quoted\n    // String_Constant\n    // Binary_Expression\n    else {\n      // ex = ex->perform(this);\n      if (into_quotes && ex->is_interpolant()) {\n        res += evacuate_escapes(ex ? ex->to_string(options()) : \"\");\n      } else {\n        sass::string str(ex ? ex->to_string(options()) : \"\");\n        if (into_quotes) str = read_hex_escapes(str);\n        res += str; // append to result string\n      }\n    }\n\n    if (needs_closing_brace) res += \")\";\n\n  }\n\n  Expression* Eval::operator()(String_Schema* s)\n  {\n    size_t L = s->length();\n    bool into_quotes = false;\n    if (L > 1) {\n      if (!Cast<String_Quoted>((*s)[0]) && !Cast<String_Quoted>((*s)[L - 1])) {\n      if (String_Constant* l = Cast<String_Constant>((*s)[0])) {\n        if (String_Constant* r = Cast<String_Constant>((*s)[L - 1])) {\n          if (r->value().size() > 0) {\n            if (l->value()[0] == '\"' && r->value()[r->value().size() - 1] == '\"') into_quotes = true;\n            if (l->value()[0] == '\\'' && r->value()[r->value().size() - 1] == '\\'') into_quotes = true;\n          }\n        }\n      }\n      }\n    }\n    bool was_quoted = false;\n    bool was_interpolant = false;\n    sass::string res(\"\");\n    for (size_t i = 0; i < L; ++i) {\n      bool is_quoted = Cast<String_Quoted>((*s)[i]) != NULL;\n      if (was_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += \" \"; }\n      else if (i > 0 && is_quoted && !(*s)[i]->is_interpolant() && !was_interpolant) { res += \" \"; }\n      ExpressionObj ex = (*s)[i]->perform(this);\n      interpolation(ctx, res, ex, into_quotes, ex->is_interpolant());\n      was_quoted = Cast<String_Quoted>((*s)[i]) != NULL;\n      was_interpolant = (*s)[i]->is_interpolant();\n\n    }\n    if (!s->is_interpolant()) {\n      if (s->length() > 1 && res == \"\") return SASS_MEMORY_NEW(Null, s->pstate());\n      String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res, s->css());\n      return str.detach();\n    }\n    // string schema seems to have a special unquoting behavior (also handles \"nested\" quotes)\n    String_Quoted_Obj str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), res, 0, false, false, false, s->css());\n    // if (s->is_interpolant()) str->quote_mark(0);\n    // String_Constant* str = SASS_MEMORY_NEW(String_Constant, s->pstate(), res);\n    if (str->quote_mark()) str->quote_mark('*');\n    else if (!is_in_comment) str->value(string_to_output(str->value()));\n    str->is_interpolant(s->is_interpolant());\n    return str.detach();\n  }\n\n\n  Expression* Eval::operator()(String_Constant* s)\n  {\n    return s;\n  }\n\n  Expression* Eval::operator()(String_Quoted* s)\n  {\n    String_Quoted* str = SASS_MEMORY_NEW(String_Quoted, s->pstate(), \"\");\n    str->value(s->value());\n    str->quote_mark(s->quote_mark());\n    str->is_interpolant(s->is_interpolant());\n    return str;\n  }\n\n  Expression* Eval::operator()(SupportsOperation* c)\n  {\n    Expression* left = c->left()->perform(this);\n    Expression* right = c->right()->perform(this);\n    SupportsOperation* cc = SASS_MEMORY_NEW(SupportsOperation,\n                                 c->pstate(),\n                                 Cast<SupportsCondition>(left),\n                                 Cast<SupportsCondition>(right),\n                                 c->operand());\n    return cc;\n  }\n\n  Expression* Eval::operator()(SupportsNegation* c)\n  {\n    Expression* condition = c->condition()->perform(this);\n    SupportsNegation* cc = SASS_MEMORY_NEW(SupportsNegation,\n                                 c->pstate(),\n                                 Cast<SupportsCondition>(condition));\n    return cc;\n  }\n\n  Expression* Eval::operator()(SupportsDeclaration* c)\n  {\n    Expression* feature = c->feature()->perform(this);\n    Expression* value = c->value()->perform(this);\n    SupportsDeclaration* cc = SASS_MEMORY_NEW(SupportsDeclaration,\n                              c->pstate(),\n                              feature,\n                              value);\n    return cc;\n  }\n\n  Expression* Eval::operator()(Supports_Interpolation* c)\n  {\n    Expression* value = c->value()->perform(this);\n    Supports_Interpolation* cc = SASS_MEMORY_NEW(Supports_Interpolation,\n                            c->pstate(),\n                            value);\n    return cc;\n  }\n\n  Expression* Eval::operator()(At_Root_Query* e)\n  {\n    ExpressionObj feature = e->feature();\n    feature = (feature ? feature->perform(this) : 0);\n    ExpressionObj value = e->value();\n    value = (value ? value->perform(this) : 0);\n    Expression* ee = SASS_MEMORY_NEW(At_Root_Query,\n                                     e->pstate(),\n                                     Cast<String>(feature),\n                                     value);\n    return ee;\n  }\n\n  Media_Query* Eval::operator()(Media_Query* q)\n  {\n    String_Obj t = q->media_type();\n    t = static_cast<String*>(t.isNull() ? 0 : t->perform(this));\n    Media_Query_Obj qq = SASS_MEMORY_NEW(Media_Query,\n                                      q->pstate(),\n                                      t,\n                                      q->length(),\n                                      q->is_negated(),\n                                      q->is_restricted());\n    for (size_t i = 0, L = q->length(); i < L; ++i) {\n      qq->append(static_cast<Media_Query_Expression*>((*q)[i]->perform(this)));\n    }\n    return qq.detach();\n  }\n\n  Expression* Eval::operator()(Media_Query_Expression* e)\n  {\n    ExpressionObj feature = e->feature();\n    feature = (feature ? feature->perform(this) : 0);\n    if (feature && Cast<String_Quoted>(feature)) {\n      feature = SASS_MEMORY_NEW(String_Quoted,\n                                  feature->pstate(),\n                                  Cast<String_Quoted>(feature)->value());\n    }\n    ExpressionObj value = e->value();\n    value = (value ? value->perform(this) : 0);\n    if (value && Cast<String_Quoted>(value)) {\n      // XXX: this is never hit via spec tests\n      value = SASS_MEMORY_NEW(String_Quoted,\n                                value->pstate(),\n                                Cast<String_Quoted>(value)->value());\n    }\n    return SASS_MEMORY_NEW(Media_Query_Expression,\n                           e->pstate(),\n                           feature,\n                           value,\n                           e->is_interpolated());\n  }\n\n  Expression* Eval::operator()(Null* n)\n  {\n    return n;\n  }\n\n  Expression* Eval::operator()(Argument* a)\n  {\n    ExpressionObj val = a->value()->perform(this);\n    bool is_rest_argument = a->is_rest_argument();\n    bool is_keyword_argument = a->is_keyword_argument();\n\n    if (a->is_rest_argument()) {\n      if (val->concrete_type() == Expression::MAP) {\n        is_rest_argument = false;\n        is_keyword_argument = true;\n      }\n      else if(val->concrete_type() != Expression::LIST) {\n        List_Obj wrapper = SASS_MEMORY_NEW(List,\n                                        val->pstate(),\n                                        0,\n                                        SASS_COMMA,\n                                        true);\n        wrapper->append(val);\n        val = wrapper;\n      }\n    }\n    return SASS_MEMORY_NEW(Argument,\n                           a->pstate(),\n                           val,\n                           a->name(),\n                           is_rest_argument,\n                           is_keyword_argument);\n  }\n\n  Expression* Eval::operator()(Arguments* a)\n  {\n    Arguments_Obj aa = SASS_MEMORY_NEW(Arguments, a->pstate());\n    if (a->length() == 0) return aa.detach();\n    for (size_t i = 0, L = a->length(); i < L; ++i) {\n      ExpressionObj rv = (*a)[i]->perform(this);\n      Argument* arg = Cast<Argument>(rv);\n      if (!(arg->is_rest_argument() || arg->is_keyword_argument())) {\n        aa->append(arg);\n      }\n    }\n\n    if (a->has_rest_argument()) {\n      ExpressionObj rest = a->get_rest_argument()->perform(this);\n      ExpressionObj splat = Cast<Argument>(rest)->value()->perform(this);\n\n      Sass_Separator separator = SASS_COMMA;\n      List* ls = Cast<List>(splat);\n      Map* ms = Cast<Map>(splat);\n\n      List_Obj arglist = SASS_MEMORY_NEW(List,\n                                      splat->pstate(),\n                                      0,\n                                      ls ? ls->separator() : separator,\n                                      true);\n\n      if (ls && ls->is_arglist()) {\n        arglist->concat(ls);\n      } else if (ms) {\n        aa->append(SASS_MEMORY_NEW(Argument, splat->pstate(), ms, \"\", false, true));\n      } else if (ls) {\n        arglist->concat(ls);\n      } else {\n        arglist->append(splat);\n      }\n      if (arglist->length()) {\n        aa->append(SASS_MEMORY_NEW(Argument, splat->pstate(), arglist, \"\", true));\n      }\n    }\n\n    if (a->has_keyword_argument()) {\n      ExpressionObj rv = a->get_keyword_argument()->perform(this);\n      Argument* rvarg = Cast<Argument>(rv);\n      ExpressionObj kwarg = rvarg->value()->perform(this);\n\n      aa->append(SASS_MEMORY_NEW(Argument, kwarg->pstate(), kwarg, \"\", false, true));\n    }\n    return aa.detach();\n  }\n\n  Expression* Eval::operator()(Comment* c)\n  {\n    return 0;\n  }\n\n  SelectorList* Eval::operator()(Selector_Schema* s)\n  {\n    LOCAL_FLAG(is_in_selector_schema, true);\n    // the parser will look for a brace to end the selector\n    ExpressionObj sel = s->contents()->perform(this);\n    sass::string result_str(sel->to_string(options()));\n    result_str = unquote(Util::rtrim(result_str));\n    ItplFile* source = SASS_MEMORY_NEW(ItplFile,\n      result_str.c_str(), s->pstate());\n    Parser p(source, ctx, traces);\n\n    // If a schema contains a reference to parent it is already\n    // connected to it, so don't connect implicitly anymore\n    SelectorListObj parsed = p.parseSelectorList(true);\n    flag_is_in_selector_schema.reset();\n    return parsed.detach();\n  }\n\n  Expression* Eval::operator()(Parent_Reference* p)\n  {\n    if (SelectorListObj pr = exp.original()) {\n      return operator()(pr);\n    } else {\n      return SASS_MEMORY_NEW(Null, p->pstate());\n    }\n  }\n\n  SimpleSelector* Eval::operator()(SimpleSelector* s)\n  {\n    return s;\n  }\n\n  PseudoSelector* Eval::operator()(PseudoSelector* pseudo)\n  {\n    // ToDo: should we eval selector?\n    return pseudo;\n  };\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/eval.hpp",
    "content": "#ifndef SASS_EVAL_H\n#define SASS_EVAL_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\n#include \"context.hpp\"\n#include \"listize.hpp\"\n#include \"operation.hpp\"\n#include \"environment.hpp\"\n\nnamespace Sass {\n\n  class Expand;\n  class Context;\n\n  class Eval : public Operation_CRTP<Expression*, Eval> {\n\n   public:\n    Expand& exp;\n    Context& ctx;\n    Backtraces& traces;\n    Eval(Expand& exp);\n    ~Eval();\n\n    bool force;\n    bool is_in_comment;\n    bool is_in_selector_schema;\n\n    Boolean_Obj bool_true;\n    Boolean_Obj bool_false;\n\n    Env* environment();\n    EnvStack& env_stack();\n    const sass::string cwd();\n    CalleeStack& callee_stack();\n    struct Sass_Inspect_Options& options();\n    struct Sass_Compiler* compiler();\n\n    // for evaluating function bodies\n    Expression* operator()(Block*);\n    Expression* operator()(Assignment*);\n    Expression* operator()(If*);\n    Expression* operator()(ForRule*);\n    Expression* operator()(EachRule*);\n    Expression* operator()(WhileRule*);\n    Expression* operator()(Return*);\n    Expression* operator()(WarningRule*);\n    Expression* operator()(ErrorRule*);\n    Expression* operator()(DebugRule*);\n\n    Expression* operator()(List*);\n    Expression* operator()(Map*);\n    Expression* operator()(Binary_Expression*);\n    Expression* operator()(Unary_Expression*);\n    Expression* operator()(Function_Call*);\n    Expression* operator()(Variable*);\n    Expression* operator()(Number*);\n    Expression* operator()(Color_RGBA*);\n    Expression* operator()(Color_HSLA*);\n    Expression* operator()(Boolean*);\n    Expression* operator()(String_Schema*);\n    Expression* operator()(String_Quoted*);\n    Expression* operator()(String_Constant*);\n    Media_Query* operator()(Media_Query*);\n    Expression* operator()(Media_Query_Expression*);\n    Expression* operator()(At_Root_Query*);\n    Expression* operator()(SupportsOperation*);\n    Expression* operator()(SupportsNegation*);\n    Expression* operator()(SupportsDeclaration*);\n    Expression* operator()(Supports_Interpolation*);\n    Expression* operator()(Null*);\n    Expression* operator()(Argument*);\n    Expression* operator()(Arguments*);\n    Expression* operator()(Comment*);\n\n    // these will return selectors\n    SelectorList* operator()(SelectorList*);\n    SelectorList* operator()(ComplexSelector*);\n    CompoundSelector* operator()(CompoundSelector*);\n    SelectorComponent* operator()(SelectorComponent*);\n    SimpleSelector* operator()(SimpleSelector* s);\n    PseudoSelector* operator()(PseudoSelector* s);\n\n    // they don't have any specific implementation (yet)\n    IDSelector* operator()(IDSelector* s) { return s; };\n    ClassSelector* operator()(ClassSelector* s) { return s; };\n    TypeSelector* operator()(TypeSelector* s) { return s; };\n    AttributeSelector* operator()(AttributeSelector* s) { return s; };\n    PlaceholderSelector* operator()(PlaceholderSelector* s) { return s; };\n\n    // actual evaluated selectors\n    SelectorList* operator()(Selector_Schema*);\n    Expression* operator()(Parent_Reference*);\n\n    // generic fallback\n    template <typename U>\n    Expression* fallback(U x)\n    { return Cast<Expression>(x); }\n\n  private:\n    void interpolation(Context& ctx, sass::string& res, ExpressionObj ex, bool into_quotes, bool was_itpl = false);\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/eval_selectors.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"expand.hpp\"\n#include \"eval.hpp\"\n#include \"ast.hpp\"\n\n\nnamespace Sass {\n\n  SelectorList* Eval::operator()(SelectorList* s)\n  {\n    sass::vector<SelectorListObj> rv;\n    SelectorListObj sl = SASS_MEMORY_NEW(SelectorList, s->pstate());\n    for (size_t i = 0, iL = s->length(); i < iL; ++i) {\n      rv.push_back(operator()(s->get(i)));\n    }\n\n    // we should actually permutate parent first\n    // but here we have permutated the selector first\n    size_t round = 0;\n    while (round != sass::string::npos) {\n      bool abort = true;\n      for (size_t i = 0, iL = rv.size(); i < iL; ++i) {\n        if (rv[i]->length() > round) {\n          sl->append((*rv[i])[round]);\n          abort = false;\n        }\n      }\n      if (abort) {\n        round = sass::string::npos;\n      }\n      else {\n        ++round;\n      }\n\n    }\n    return sl.detach();\n  }\n\n  SelectorComponent* Eval::operator()(SelectorComponent* s)\n  {\n    return {};\n  }\n\n  SelectorList* Eval::operator()(ComplexSelector* s)\n  {\n    bool implicit_parent = !exp.old_at_root_without_rule;\n    if (is_in_selector_schema) exp.pushNullSelector();\n    SelectorListObj other = s->resolve_parent_refs(\n      exp.getOriginalStack(), traces, implicit_parent);\n    if (is_in_selector_schema) exp.popNullSelector();\n\n    for (size_t i = 0; i < other->length(); i++) {\n      ComplexSelectorObj sel = other->at(i);\n      for (size_t n = 0; n < sel->length(); n++) {\n        if (CompoundSelectorObj comp = Cast<CompoundSelector>(sel->at(n))) {\n          sel->at(n) = operator()(comp);\n        }\n      }\n    }\n\n    return other.detach();\n  }\n\n  CompoundSelector* Eval::operator()(CompoundSelector* s)\n  {\n    for (size_t i = 0; i < s->length(); i++) {\n      SimpleSelector* ss = s->at(i);\n      // skip parents here (called via resolve_parent_refs)\n      s->at(i) = Cast<SimpleSelector>(ss->perform(this));\n    }\n    return s;\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/expand.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <iostream>\n#include <typeinfo>\n\n#include \"ast.hpp\"\n#include \"expand.hpp\"\n#include \"bind.hpp\"\n#include \"eval.hpp\"\n#include \"backtrace.hpp\"\n#include \"context.hpp\"\n#include \"parser.hpp\"\n#include \"sass_functions.hpp\"\n#include \"error_handling.hpp\"\n\nnamespace Sass {\n\n  // simple endless recursion protection\n  const size_t maxRecursion = 500;\n\n  Expand::Expand(Context& ctx, Env* env, SelectorStack* stack, SelectorStack* originals)\n  : ctx(ctx),\n    traces(ctx.traces),\n    eval(Eval(*this)),\n    recursions(0),\n    in_keyframes(false),\n    at_root_without_rule(false),\n    old_at_root_without_rule(false),\n    env_stack(),\n    block_stack(),\n    call_stack(),\n    selector_stack(),\n    originalStack(),\n    mediaStack()\n  {\n    env_stack.push_back(nullptr);\n    env_stack.push_back(env);\n    block_stack.push_back(nullptr);\n    call_stack.push_back({});\n    if (stack == NULL) { pushToSelectorStack({}); }\n    else {\n      for (auto item : *stack) {\n        if (item.isNull()) pushToSelectorStack({});\n        else pushToSelectorStack(item);\n      }\n    }\n    if (originals == NULL) { pushToOriginalStack({}); }\n    else {\n      for (auto item : *stack) {\n        if (item.isNull()) pushToOriginalStack({});\n        else pushToOriginalStack(item);\n      }\n    }\n    mediaStack.push_back({});\n  }\n\n  Env* Expand::environment()\n  {\n    if (env_stack.size() > 0)\n      return env_stack.back();\n    return 0;\n  }\n\n  void Expand::pushNullSelector()\n  {\n    pushToSelectorStack({});\n    pushToOriginalStack({});\n  }\n\n  void Expand::popNullSelector()\n  {\n    popFromOriginalStack();\n    popFromSelectorStack();\n  }\n\n  SelectorStack Expand::getOriginalStack()\n  {\n    return originalStack;\n  }\n\n  SelectorStack Expand::getSelectorStack()\n  {\n    return selector_stack;\n  }\n\n  SelectorListObj& Expand::selector()\n  {\n    if (selector_stack.size() > 0) {\n      auto& sel = selector_stack.back();\n      if (sel.isNull()) return sel;\n      return sel;\n    }\n    // Avoid the need to return copies\n    // We always want an empty first item\n    selector_stack.push_back({});\n    return selector_stack.back();;\n  }\n\n  SelectorListObj& Expand::original()\n  {\n    if (originalStack.size() > 0) {\n      auto& sel = originalStack.back();\n      if (sel.isNull()) return sel;\n      return sel;\n    }\n    // Avoid the need to return copies\n    // We always want an empty first item\n    originalStack.push_back({});\n    return originalStack.back();\n  }\n\n  SelectorListObj Expand::popFromSelectorStack()\n  {\n    SelectorListObj last = selector_stack.back();\n    if (selector_stack.size() > 0)    \n      selector_stack.pop_back();\n    if (last.isNull()) return {};\n    return last;\n  }\n\n  void Expand::pushToSelectorStack(SelectorListObj selector)\n  {\n    selector_stack.push_back(selector);\n  }\n\n  SelectorListObj Expand::popFromOriginalStack()\n  {\n    SelectorListObj last = originalStack.back();\n    if (originalStack.size() > 0)\n      originalStack.pop_back();\n    if (last.isNull()) return {};\n    return last;\n  }\n\n  void Expand::pushToOriginalStack(SelectorListObj selector)\n  {\n    originalStack.push_back(selector);\n  }\n\n  // blocks create new variable scopes\n  Block* Expand::operator()(Block* b)\n  {\n    // create new local environment\n    // set the current env as parent\n    Env env(environment());\n    // copy the block object (add items later)\n    Block_Obj bb = SASS_MEMORY_NEW(Block,\n                                b->pstate(),\n                                b->length(),\n                                b->is_root());\n    // setup block and env stack\n    this->block_stack.push_back(bb);\n    this->env_stack.push_back(&env);\n    // operate on block\n    // this may throw up!\n    this->append_block(b);\n    // revert block and env stack\n    this->block_stack.pop_back();\n    this->env_stack.pop_back();\n    // return copy\n    return bb.detach();\n  }\n\n  Statement* Expand::operator()(StyleRule* r)\n  {\n    LOCAL_FLAG(old_at_root_without_rule, at_root_without_rule);\n\n    if (in_keyframes) {\n      Block* bb = operator()(r->block());\n      Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);\n      if (r->schema()) {\n        pushNullSelector();\n        k->name(eval(r->schema()));\n        popNullSelector();\n      }\n      else if (r->selector()) {\n        if (SelectorListObj s = r->selector()) {\n          pushNullSelector();\n          k->name(eval(s));\n          popNullSelector();\n        }\n      }\n\n      return k.detach();\n    }\n\n    if (r->schema()) {\n      SelectorListObj sel = eval(r->schema());\n      r->selector(sel);\n      for (auto complex : sel->elements()) {\n        // ToDo: maybe we can get rid of chroots?\n        complex->chroots(complex->has_real_parent_ref());\n      }\n\n    }\n\n    // reset when leaving scope\n    LOCAL_FLAG(at_root_without_rule, false);\n\n    SelectorListObj evaled = eval(r->selector());\n    // do not connect parent again\n    Env env(environment());\n    if (block_stack.back()->is_root()) {\n      env_stack.push_back(&env);\n    }\n    Block_Obj blk;\n    pushToSelectorStack(evaled);\n    // The copy is needed for parent reference evaluation\n    // dart-sass stores it as `originalSelector` member\n    pushToOriginalStack(SASS_MEMORY_COPY(evaled));\n    ctx.extender.addSelector(evaled, mediaStack.back());\n    if (r->block()) blk = operator()(r->block());\n    popFromOriginalStack();\n    popFromSelectorStack();\n    StyleRule* rr = SASS_MEMORY_NEW(StyleRule,\n                                  r->pstate(),\n                                  evaled,\n                                  blk);\n\n    if (block_stack.back()->is_root()) {\n      env_stack.pop_back();\n    }\n\n    rr->is_root(r->is_root());\n    rr->tabs(r->tabs());\n\n    return rr;\n  }\n\n  Statement* Expand::operator()(SupportsRule* f)\n  {\n    ExpressionObj condition = f->condition()->perform(&eval);\n    SupportsRuleObj ff = SASS_MEMORY_NEW(SupportsRule,\n                                       f->pstate(),\n                                       Cast<SupportsCondition>(condition),\n                                       operator()(f->block()));\n    return ff.detach();\n  }\n\n  sass::vector<CssMediaQuery_Obj> Expand::mergeMediaQueries(\n    const sass::vector<CssMediaQuery_Obj>& lhs,\n    const sass::vector<CssMediaQuery_Obj>& rhs)\n  {\n    sass::vector<CssMediaQuery_Obj> queries;\n    for (CssMediaQuery_Obj query1 : lhs) {\n      for (CssMediaQuery_Obj query2 : rhs) {\n        CssMediaQuery_Obj result = query1->merge(query2);\n        if (result && !result->empty()) {\n          queries.push_back(result);\n        }\n      }\n    }\n    return queries;\n  }\n\n  Statement* Expand::operator()(MediaRule* m)\n  {\n    ExpressionObj mq = eval(m->schema());\n    sass::string str_mq(mq->to_css(ctx.c_options));\n    ItplFile* source = SASS_MEMORY_NEW(ItplFile,\n      str_mq.c_str(), m->pstate());\n    Parser parser(source, ctx, traces);\n    // Create a new CSS only representation of the media rule\n    CssMediaRuleObj css = SASS_MEMORY_NEW(CssMediaRule, m->pstate(), m->block());\n    sass::vector<CssMediaQuery_Obj> parsed = parser.parseCssMediaQueries();\n    if (mediaStack.size() && mediaStack.back()) {\n      auto& parent = mediaStack.back()->elements();\n      css->concat(mergeMediaQueries(parent, parsed));\n    }\n    else {\n      css->concat(parsed);\n    }\n    mediaStack.push_back(css);\n    css->block(operator()(m->block()));\n    mediaStack.pop_back();\n    return css.detach();\n\n  }\n\n  Statement* Expand::operator()(AtRootRule* a)\n  {\n    Block_Obj ab = a->block();\n    ExpressionObj ae = a->expression();\n\n    if (ae) ae = ae->perform(&eval);\n    else ae = SASS_MEMORY_NEW(At_Root_Query, a->pstate());\n\n    LOCAL_FLAG(at_root_without_rule, Cast<At_Root_Query>(ae)->exclude(\"rule\"));\n    LOCAL_FLAG(in_keyframes, false);\n\n                                       ;\n\n    Block_Obj bb = ab ? operator()(ab) : NULL;\n    AtRootRuleObj aa = SASS_MEMORY_NEW(AtRootRule,\n                                        a->pstate(),\n                                        bb,\n                                        Cast<At_Root_Query>(ae));\n    return aa.detach();\n  }\n\n  Statement* Expand::operator()(AtRule* a)\n  {\n    LOCAL_FLAG(in_keyframes, a->is_keyframes());\n    Block* ab = a->block();\n    SelectorList* as = a->selector();\n    Expression* av = a->value();\n    pushNullSelector();\n    if (av) av = av->perform(&eval);\n    if (as) as = eval(as);\n    popNullSelector();\n    Block* bb = ab ? operator()(ab) : NULL;\n    AtRule* aa = SASS_MEMORY_NEW(AtRule,\n                                  a->pstate(),\n                                  a->keyword(),\n                                  as,\n                                  bb,\n                                  av);\n    return aa;\n  }\n\n  Statement* Expand::operator()(Declaration* d)\n  {\n    Block_Obj ab = d->block();\n    String_Obj old_p = d->property();\n    ExpressionObj prop = old_p->perform(&eval);\n    String_Obj new_p = Cast<String>(prop);\n    // we might get a color back\n    if (!new_p) {\n      sass::string str(prop->to_string(ctx.c_options));\n      new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str);\n    }\n    ExpressionObj value = d->value();\n    if (value) value = value->perform(&eval);\n    Block_Obj bb = ab ? operator()(ab) : NULL;\n    if (!bb) {\n      if (!value || (value->is_invisible() && !d->is_important())) {\n        if (d->is_custom_property()) {\n          error(\"Custom property values may not be empty.\", d->value()->pstate(), traces);\n        } else {\n          return nullptr;\n        }\n      }\n    }\n    Declaration* decl = SASS_MEMORY_NEW(Declaration,\n                                        d->pstate(),\n                                        new_p,\n                                        value,\n                                        d->is_important(),\n                                        d->is_custom_property(),\n                                        bb);\n    decl->tabs(d->tabs());\n    return decl;\n  }\n\n  Statement* Expand::operator()(Assignment* a)\n  {\n    Env* env = environment();\n    const sass::string& var(a->variable());\n    if (a->is_global()) {\n      if (!env->has_global(var)) {\n        deprecated(\n          \"!global assignments won't be able to declare new variables in future versions.\",\n          \"Consider adding `\" + var + \": null` at the top level.\",\n          true, a->pstate());\n      }\n      if (a->is_default()) {\n        if (env->has_global(var)) {\n          ExpressionObj e = Cast<Expression>(env->get_global(var));\n          if (!e || e->concrete_type() == Expression::NULL_VAL) {\n            env->set_global(var, a->value()->perform(&eval));\n          }\n        }\n        else {\n          env->set_global(var, a->value()->perform(&eval));\n        }\n      }\n      else {\n        env->set_global(var, a->value()->perform(&eval));\n      }\n    }\n    else if (a->is_default()) {\n      if (env->has_lexical(var)) {\n        auto cur = env;\n        while (cur && cur->is_lexical()) {\n          if (cur->has_local(var)) {\n            if (AST_Node_Obj node = cur->get_local(var)) {\n              ExpressionObj e = Cast<Expression>(node);\n              if (!e || e->concrete_type() == Expression::NULL_VAL) {\n                cur->set_local(var, a->value()->perform(&eval));\n              }\n            }\n            else {\n              throw std::runtime_error(\"Env not in sync\");\n            }\n            return 0;\n          }\n          cur = cur->parent();\n        }\n        throw std::runtime_error(\"Env not in sync\");\n      }\n      else if (env->has_global(var)) {\n        if (AST_Node_Obj node = env->get_global(var)) {\n          ExpressionObj e = Cast<Expression>(node);\n          if (!e || e->concrete_type() == Expression::NULL_VAL) {\n            env->set_global(var, a->value()->perform(&eval));\n          }\n        }\n      }\n      else if (env->is_lexical()) {\n        env->set_local(var, a->value()->perform(&eval));\n      }\n      else {\n        env->set_local(var, a->value()->perform(&eval));\n      }\n    }\n    else {\n      env->set_lexical(var, a->value()->perform(&eval));\n    }\n    return 0;\n  }\n\n  Statement* Expand::operator()(Import* imp)\n  {\n    Import_Obj result = SASS_MEMORY_NEW(Import, imp->pstate());\n    if (imp->import_queries() && imp->import_queries()->size()) {\n      ExpressionObj ex = imp->import_queries()->perform(&eval);\n      result->import_queries(Cast<List>(ex));\n    }\n    for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {\n      result->urls().push_back(imp->urls()[i]->perform(&eval));\n    }\n    // all resources have been dropped for Input_Stubs\n    // for ( size_t i = 0, S = imp->incs().size(); i < S; ++i) {}\n    return result.detach();\n  }\n\n  Statement* Expand::operator()(Import_Stub* i)\n  {\n    traces.push_back(Backtrace(i->pstate()));\n    // get parent node from call stack\n    AST_Node_Obj parent = call_stack.back();\n    if (Cast<Block>(parent) == NULL) {\n      error(\"Import directives may not be used within control directives or mixins.\", i->pstate(), traces);\n    }\n    // we don't seem to need that actually afterall\n    Sass_Import_Entry import = sass_make_import(\n      i->imp_path().c_str(),\n      i->abs_path().c_str(),\n      0, 0\n    );\n    ctx.import_stack.push_back(import);\n\n    Block_Obj trace_block = SASS_MEMORY_NEW(Block, i->pstate());\n    Trace_Obj trace = SASS_MEMORY_NEW(Trace, i->pstate(), i->imp_path(), trace_block, 'i');\n    block_stack.back()->append(trace);\n    block_stack.push_back(trace_block);\n\n    const sass::string& abs_path(i->resource().abs_path);\n    append_block(ctx.sheets.at(abs_path).root);\n    sass_delete_import(ctx.import_stack.back());\n    ctx.import_stack.pop_back();\n    block_stack.pop_back();\n    traces.pop_back();\n    return 0;\n  }\n\n  Statement* Expand::operator()(WarningRule* w)\n  {\n    // eval handles this too, because warnings may occur in functions\n    w->perform(&eval);\n    return 0;\n  }\n\n  Statement* Expand::operator()(ErrorRule* e)\n  {\n    // eval handles this too, because errors may occur in functions\n    e->perform(&eval);\n    return 0;\n  }\n\n  Statement* Expand::operator()(DebugRule* d)\n  {\n    // eval handles this too, because warnings may occur in functions\n    d->perform(&eval);\n    return 0;\n  }\n\n  Statement* Expand::operator()(Comment* c)\n  {\n    if (ctx.output_style() == COMPRESSED) {\n      // comments should not be evaluated in compact\n      // https://github.com/sass/libsass/issues/2359\n      if (!c->is_important()) return NULL;\n    }\n    eval.is_in_comment = true;\n    Comment* rv = SASS_MEMORY_NEW(Comment, c->pstate(), Cast<String>(c->text()->perform(&eval)), c->is_important());\n    eval.is_in_comment = false;\n    // TODO: eval the text, once we're parsing/storing it as a String_Schema\n    return rv;\n  }\n\n  Statement* Expand::operator()(If* i)\n  {\n    Env env(environment(), true);\n    env_stack.push_back(&env);\n    call_stack.push_back(i);\n    ExpressionObj rv = i->predicate()->perform(&eval);\n    if (*rv) {\n      append_block(i->block());\n    }\n    else {\n      Block* alt = i->alternative();\n      if (alt) append_block(alt);\n    }\n    call_stack.pop_back();\n    env_stack.pop_back();\n    return 0;\n  }\n\n  // For does not create a new env scope\n  // But iteration vars are reset afterwards\n  Statement* Expand::operator()(ForRule* f)\n  {\n    sass::string variable(f->variable());\n    ExpressionObj low = f->lower_bound()->perform(&eval);\n    if (low->concrete_type() != Expression::NUMBER) {\n      traces.push_back(Backtrace(low->pstate()));\n      throw Exception::TypeMismatch(traces, *low, \"integer\");\n    }\n    ExpressionObj high = f->upper_bound()->perform(&eval);\n    if (high->concrete_type() != Expression::NUMBER) {\n      traces.push_back(Backtrace(high->pstate()));\n      throw Exception::TypeMismatch(traces, *high, \"integer\");\n    }\n    Number_Obj sass_start = Cast<Number>(low);\n    Number_Obj sass_end = Cast<Number>(high);\n    // check if units are valid for sequence\n    if (sass_start->unit() != sass_end->unit()) {\n      sass::ostream msg; msg << \"Incompatible units: '\"\n        << sass_start->unit() << \"' and '\"\n        << sass_end->unit() << \"'.\";\n      error(msg.str(), low->pstate(), traces);\n    }\n    double start = sass_start->value();\n    double end = sass_end->value();\n    // only create iterator once in this environment\n    Env env(environment(), true);\n    env_stack.push_back(&env);\n    call_stack.push_back(f);\n    Block* body = f->block();\n    if (start < end) {\n      if (f->is_inclusive()) ++end;\n      for (double i = start;\n           i < end;\n           ++i) {\n        Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());\n        env.set_local(variable, it);\n        append_block(body);\n      }\n    } else {\n      if (f->is_inclusive()) --end;\n      for (double i = start;\n           i > end;\n           --i) {\n        Number_Obj it = SASS_MEMORY_NEW(Number, low->pstate(), i, sass_end->unit());\n        env.set_local(variable, it);\n        append_block(body);\n      }\n    }\n    call_stack.pop_back();\n    env_stack.pop_back();\n    return 0;\n  }\n\n  // Eval does not create a new env scope\n  // But iteration vars are reset afterwards\n  Statement* Expand::operator()(EachRule* e)\n  {\n    sass::vector<sass::string> variables(e->variables());\n    ExpressionObj expr = e->list()->perform(&eval);\n    List_Obj list;\n    Map_Obj map;\n    if (expr->concrete_type() == Expression::MAP) {\n      map = Cast<Map>(expr);\n    }\n    else if (SelectorList * ls = Cast<SelectorList>(expr)) {\n      ExpressionObj rv = Listize::perform(ls);\n      list = Cast<List>(rv);\n    }\n    else if (expr->concrete_type() != Expression::LIST) {\n      list = SASS_MEMORY_NEW(List, expr->pstate(), 1, SASS_COMMA);\n      list->append(expr);\n    }\n    else {\n      list = Cast<List>(expr);\n    }\n    // remember variables and then reset them\n    Env env(environment(), true);\n    env_stack.push_back(&env);\n    call_stack.push_back(e);\n    Block* body = e->block();\n\n    if (map) {\n      for (auto key : map->keys()) {\n        ExpressionObj k = key->perform(&eval);\n        ExpressionObj v = map->at(key)->perform(&eval);\n\n        if (variables.size() == 1) {\n          List_Obj variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);\n          variable->append(k);\n          variable->append(v);\n          env.set_local(variables[0], variable);\n        } else {\n          env.set_local(variables[0], k);\n          env.set_local(variables[1], v);\n        }\n        append_block(body);\n      }\n    }\n    else {\n      // bool arglist = list->is_arglist();\n      if (list->length() == 1 && Cast<SelectorList>(list)) {\n        list = Cast<List>(list);\n      }\n      for (size_t i = 0, L = list->length(); i < L; ++i) {\n        ExpressionObj item = list->at(i);\n        // unwrap value if the expression is an argument\n        if (Argument_Obj arg = Cast<Argument>(item)) item = arg->value();\n        // check if we got passed a list of args (investigate)\n        if (List_Obj scalars = Cast<List>(item)) {\n          if (variables.size() == 1) {\n            List_Obj var = scalars;\n            // if (arglist) var = (*scalars)[0];\n            env.set_local(variables[0], var);\n          } else {\n            for (size_t j = 0, K = variables.size(); j < K; ++j) {\n              env.set_local(variables[j], j >= scalars->length()\n                ? SASS_MEMORY_NEW(Null, expr->pstate())\n                : (*scalars)[j]->perform(&eval));\n            }\n          }\n        } else {\n          if (variables.size() > 0) {\n            env.set_local(variables.at(0), item);\n            for (size_t j = 1, K = variables.size(); j < K; ++j) {\n              ExpressionObj res = SASS_MEMORY_NEW(Null, expr->pstate());\n              env.set_local(variables[j], res);\n            }\n          }\n        }\n        append_block(body);\n      }\n    }\n    call_stack.pop_back();\n    env_stack.pop_back();\n    return 0;\n  }\n\n  Statement* Expand::operator()(WhileRule* w)\n  {\n    ExpressionObj pred = w->predicate();\n    Block* body = w->block();\n    Env env(environment(), true);\n    env_stack.push_back(&env);\n    call_stack.push_back(w);\n    ExpressionObj cond = pred->perform(&eval);\n    while (!cond->is_false()) {\n      append_block(body);\n      cond = pred->perform(&eval);\n    }\n    call_stack.pop_back();\n    env_stack.pop_back();\n    return 0;\n  }\n\n  Statement* Expand::operator()(Return* r)\n  {\n    error(\"@return may only be used within a function\", r->pstate(), traces);\n    return 0;\n  }\n\n  Statement* Expand::operator()(ExtendRule* e)\n  {\n\n    // evaluate schema first\n    if (e->schema()) {\n      e->selector(eval(e->schema()));\n      e->isOptional(e->selector()->is_optional());\n    }\n    // evaluate the selector\n    e->selector(eval(e->selector()));\n\n    if (e->selector()) {\n\n      for (auto complex : e->selector()->elements()) {\n\n        if (complex->length() != 1) {\n          error(\"complex selectors may not be extended.\", complex->pstate(), traces);\n        }\n\n        if (const CompoundSelector* compound = complex->first()->getCompound()) {\n\n          if (compound->length() != 1) {\n\n            sass::ostream sels; bool addComma = false;\n            sels << \"Compound selectors may no longer be extended.\\n\";\n            sels << \"Consider `@extend \";\n            for (auto sel : compound->elements()) {\n              if (addComma) sels << \", \";\n              sels << sel->to_sass();\n              addComma = true;\n            }\n            sels << \"` instead.\\n\";\n            sels << \"See http://bit.ly/ExtendCompound for details.\";\n\n            warning(sels.str(), compound->pstate());\n\n            // Make this an error once deprecation is over\n            for (SimpleSelectorObj simple : compound->elements()) {\n              // Pass every selector we ever see to extender (to make them findable for extend)\n              ctx.extender.addExtension(selector(), simple, mediaStack.back(), e->isOptional());\n            }\n\n          }\n          else {\n            // Pass every selector we ever see to extender (to make them findable for extend)\n            ctx.extender.addExtension(selector(), compound->first(), mediaStack.back(), e->isOptional());\n          }\n\n        }\n        else {\n          error(\"complex selectors may not be extended.\", complex->pstate(), traces);\n        }\n      }\n    }\n\n    return nullptr;\n\n  }\n\n  Statement* Expand::operator()(Definition* d)\n  {\n    Env* env = environment();\n    Definition_Obj dd = SASS_MEMORY_COPY(d);\n    env->local_frame()[d->name() +\n                        (d->type() == Definition::MIXIN ? \"[m]\" : \"[f]\")] = dd;\n\n    if (d->type() == Definition::FUNCTION && (\n      Prelexer::calc_fn_call(d->name().c_str()) ||\n      d->name() == \"element\"    ||\n      d->name() == \"expression\" ||\n      d->name() == \"url\"\n    )) {\n      deprecated(\n        \"Naming a function \\\"\" + d->name() + \"\\\" is disallowed and will be an error in future versions of Sass.\",\n        \"This name conflicts with an existing CSS function with special parse rules.\",\n        false, d->pstate()\n      );\n    }\n\n    // set the static link so we can have lexical scoping\n    dd->environment(env);\n    return 0;\n  }\n\n  Statement* Expand::operator()(Mixin_Call* c)\n  {\n\n    if (recursions > maxRecursion) {\n      throw Exception::StackError(traces, *c);\n    }\n\n    recursions ++;\n\n    Env* env = environment();\n    sass::string full_name(c->name() + \"[m]\");\n    if (!env->has(full_name)) {\n      error(\"no mixin named \" + c->name(), c->pstate(), traces);\n    }\n    Definition_Obj def = Cast<Definition>((*env)[full_name]);\n    Block_Obj body = def->block();\n    Parameters_Obj params = def->parameters();\n\n    if (c->block() && c->name() != \"@content\" && !body->has_content()) {\n      error(\"Mixin \\\"\" + c->name() + \"\\\" does not accept a content block.\", c->pstate(), traces);\n    }\n    ExpressionObj rv = c->arguments()->perform(&eval);\n    Arguments_Obj args = Cast<Arguments>(rv);\n    sass::string msg(\", in mixin `\" + c->name() + \"`\");\n    traces.push_back(Backtrace(c->pstate(), msg));\n    ctx.callee_stack.push_back({\n      c->name().c_str(),\n      c->pstate().getPath(),\n      c->pstate().getLine(),\n      c->pstate().getColumn(),\n      SASS_CALLEE_MIXIN,\n      { env }\n    });\n\n    Env new_env(def->environment());\n    env_stack.push_back(&new_env);\n    if (c->block()) {\n      Parameters_Obj params = c->block_parameters();\n      if (!params) params = SASS_MEMORY_NEW(Parameters, c->pstate());\n      // represent mixin content blocks as thunks/closures\n      Definition_Obj thunk = SASS_MEMORY_NEW(Definition,\n                                          c->pstate(),\n                                          \"@content\",\n                                          params,\n                                          c->block(),\n                                          Definition::MIXIN);\n      thunk->environment(env);\n      new_env.local_frame()[\"@content[m]\"] = thunk;\n    }\n\n    bind(sass::string(\"Mixin\"), c->name(), params, args, &new_env, &eval, traces);\n\n    Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate());\n    Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block);\n\n    env->set_global(\"is_in_mixin\", bool_true);\n    if (Block* pr = block_stack.back()) {\n      trace_block->is_root(pr->is_root());\n    }\n    block_stack.push_back(trace_block);\n    for (auto bb : body->elements()) {\n      if (StyleRule* r = Cast<StyleRule>(bb)) {\n        r->is_root(trace_block->is_root());\n      }\n      Statement_Obj ith = bb->perform(this);\n      if (ith) trace->block()->append(ith);\n    }\n    block_stack.pop_back();\n    env->del_global(\"is_in_mixin\");\n\n    ctx.callee_stack.pop_back();\n    env_stack.pop_back();\n    traces.pop_back();\n\n    recursions --;\n    return trace.detach();\n  }\n\n  Statement* Expand::operator()(Content* c)\n  {\n    Env* env = environment();\n    // convert @content directives into mixin calls to the underlying thunk\n    if (!env->has(\"@content[m]\")) return 0;\n    Arguments_Obj args = c->arguments();\n    if (!args) args = SASS_MEMORY_NEW(Arguments, c->pstate());\n\n    Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call,\n                                       c->pstate(),\n                                       \"@content\",\n                                       args);\n\n    Trace_Obj trace = Cast<Trace>(call->perform(this));\n    return trace.detach();\n  }\n\n  // process and add to last block on stack\n  inline void Expand::append_block(Block* b)\n  {\n    if (b->is_root()) call_stack.push_back(b);\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      Statement* stm = b->at(i);\n      Statement_Obj ith = stm->perform(this);\n      if (ith) block_stack.back()->append(ith);\n    }\n    if (b->is_root()) call_stack.pop_back();\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/expand.hpp",
    "content": "#ifndef SASS_EXPAND_H\n#define SASS_EXPAND_H\n\n#include <vector>\n\n#include \"ast.hpp\"\n#include \"eval.hpp\"\n#include \"operation.hpp\"\n#include \"environment.hpp\"\n\nnamespace Sass {\n\n  class Listize;\n  class Context;\n  class Eval;\n  struct Backtrace;\n\n  class Expand : public Operation_CRTP<Statement*, Expand> {\n  public:\n\n    Env* environment();\n    SelectorListObj& selector();\n    SelectorListObj& original();\n    SelectorListObj popFromSelectorStack();\n    SelectorStack getOriginalStack();\n    SelectorStack getSelectorStack();\n    void pushNullSelector();\n    void popNullSelector();\n    void pushToSelectorStack(SelectorListObj selector);\n\n    SelectorListObj popFromOriginalStack();\n\n    void pushToOriginalStack(SelectorListObj selector);\n\n    Context&          ctx;\n    Backtraces&       traces;\n    Eval              eval;\n    size_t            recursions;\n    bool              in_keyframes;\n    bool              at_root_without_rule;\n    bool              old_at_root_without_rule;\n\n    // it's easier to work with vectors\n    EnvStack      env_stack;\n    BlockStack    block_stack;\n    CallStack     call_stack;\n  private:\n    SelectorStack selector_stack;\n  public:\n    SelectorStack originalStack;\n    MediaStack    mediaStack;\n\n    Boolean_Obj bool_true;\n\n  private:\n\n    sass::vector<CssMediaQuery_Obj> mergeMediaQueries(const sass::vector<CssMediaQuery_Obj>& lhs, const sass::vector<CssMediaQuery_Obj>& rhs);\n\n  public:\n    Expand(Context&, Env*, SelectorStack* stack = nullptr, SelectorStack* original = nullptr);\n    ~Expand() { }\n\n    Block* operator()(Block*);\n    Statement* operator()(StyleRule*);\n\n    Statement* operator()(MediaRule*);\n\n    // Css StyleRule is already static\n    // Statement* operator()(CssMediaRule*);\n\n    Statement* operator()(SupportsRule*);\n    Statement* operator()(AtRootRule*);\n    Statement* operator()(AtRule*);\n    Statement* operator()(Declaration*);\n    Statement* operator()(Assignment*);\n    Statement* operator()(Import*);\n    Statement* operator()(Import_Stub*);\n    Statement* operator()(WarningRule*);\n    Statement* operator()(ErrorRule*);\n    Statement* operator()(DebugRule*);\n    Statement* operator()(Comment*);\n    Statement* operator()(If*);\n    Statement* operator()(ForRule*);\n    Statement* operator()(EachRule*);\n    Statement* operator()(WhileRule*);\n    Statement* operator()(Return*);\n    Statement* operator()(ExtendRule*);\n    Statement* operator()(Definition*);\n    Statement* operator()(Mixin_Call*);\n    Statement* operator()(Content*);\n\n    void append_block(Block*);\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/extender.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\n#include \"extender.hpp\"\n#include \"permutate.hpp\"\n#include \"dart_helpers.hpp\"\n\nnamespace Sass {\n\n  // ##########################################################################\n  // Constructor without default [mode].\n  // [traces] are needed to throw errors.\n  // ##########################################################################\n  Extender::Extender(Backtraces& traces) :\n    mode(NORMAL),\n    traces(traces),\n    selectors(),\n    extensions(),\n    extensionsByExtender(),\n    mediaContexts(),\n    sourceSpecificity(),\n    originals()\n  {}\n\n  // ##########################################################################\n  // Constructor with specific [mode].\n  // [traces] are needed to throw errors.\n  // ##########################################################################\n  Extender::Extender(ExtendMode mode, Backtraces& traces) :\n    mode(mode),\n    traces(traces),\n    selectors(),\n    extensions(),\n    extensionsByExtender(),\n    mediaContexts(),\n    sourceSpecificity(),\n    originals()\n  {}\n\n  // ##########################################################################\n  // Extends [selector] with [source] extender and [targets] extendees.\n  // This works as though `source {@extend target}` were written in the\n  // stylesheet, with the exception that [target] can contain compound\n  // selectors which must be extended as a unit.\n  // ##########################################################################\n  SelectorListObj Extender::extend(\n    SelectorListObj& selector,\n    const SelectorListObj& source,\n    const SelectorListObj& targets,\n    Backtraces& traces)\n  {\n    return extendOrReplace(selector, source, targets, ExtendMode::TARGETS, traces);\n  }\n  // EO Extender::extend\n\n  // ##########################################################################\n  // Returns a copy of [selector] with [targets] replaced by [source].\n  // ##########################################################################\n  SelectorListObj Extender::replace(\n    SelectorListObj& selector,\n    const SelectorListObj& source,\n    const SelectorListObj& targets,\n    Backtraces& traces)\n  {\n    return extendOrReplace(selector, source, targets, ExtendMode::REPLACE, traces);\n  }\n  // EO Extender::replace\n\n  // ##########################################################################\n  // A helper function for [extend] and [replace].\n  // ##########################################################################\n  SelectorListObj Extender::extendOrReplace(\n    SelectorListObj& selector,\n    const SelectorListObj& source,\n    const SelectorListObj& targets,\n    const ExtendMode mode,\n    Backtraces& traces)\n  {\n    ExtSelExtMapEntry extenders;\n\n    for (auto complex : source->elements()) {\n      // Extension.oneOff(complex as ComplexSelector)\n      extenders.insert(complex, Extension(complex));\n    }\n\n    for (auto complex : targets->elements()) {\n\n      // This seems superfluous, check is done before!?\n      // if (complex->length() != 1) {\n      //   error(\"complex selectors may not be extended.\", complex->pstate(), traces);\n      // }\n\n      if (const CompoundSelector* compound = complex->first()->getCompound()) {\n\n        ExtSelExtMap extensions;\n\n        for (const SimpleSelectorObj& simple : compound->elements()) {\n          extensions.insert(std::make_pair(simple, extenders));\n        }\n\n        Extender extender(mode, traces);\n\n        if (!selector->is_invisible()) {\n          for (auto sel : selector->elements()) {\n            extender.originals.insert(sel);\n          }\n        }\n\n        selector = extender.extendList(selector, extensions, {});\n\n      }\n\n    }\n\n    return selector;\n\n  }\n  // EO extendOrReplace\n\n  // ##########################################################################\n  // The set of all simple selectors in style rules handled\n  // by this extender. This includes simple selectors that\n  // were added because of downstream extensions.\n  // ##########################################################################\n  ExtSmplSelSet Extender::getSimpleSelectors() const\n  {\n    ExtSmplSelSet set;\n    for (auto& entry : selectors) {\n      set.insert(entry.first);\n    }\n    return set;\n  }\n  // EO getSimpleSelectors\n\n  // ##########################################################################\n  // Check for extends that have not been satisfied.\n  // Returns true if any non-optional extension did not\n  // extend any selector. Updates the passed reference\n  // to point to that Extension for further analysis.\n  // ##########################################################################\n  bool Extender::checkForUnsatisfiedExtends(Extension& unsatisfied) const\n  {\n    if (selectors.empty()) return false;\n    ExtSmplSelSet originals = getSimpleSelectors();\n    for (auto target : extensions) {\n      SimpleSelector* key = target.first;\n      ExtSelExtMapEntry& val = target.second;\n      if (val.empty()) continue;\n      if (originals.find(key) == originals.end()) {\n        const Extension& extension = val.front().second;\n        if (extension.isOptional) continue;\n        unsatisfied = extension;\n        return true;\n      }\n    }\n    return false;\n  }\n  // EO checkUnsatisfiedExtends\n\n  // ##########################################################################\n  // Adds [selector] to this extender, with [selectorSpan] as the span covering\n  // the selector and [ruleSpan] as the span covering the entire style rule.\n  // Extends [selector] using any registered extensions, then returns an empty\n  // [ModifiableCssStyleRule] with the resulting selector. If any more relevant\n  // extensions are added, the returned rule is automatically updated.\n  // The [mediaContext] is the media query context in which the selector was\n  // defined, or `null` if it was defined at the top level of the document.\n  // ##########################################################################\n  void Extender::addSelector(\n    const SelectorListObj& selector,\n    const CssMediaRuleObj& mediaContext)\n  {\n\n    // Note: dart-sass makes a copy here AFAICT\n    // Note: probably why we have originalStack\n    // SelectorListObj original = selector;\n\n    if (!selector->isInvisible()) {\n      for (auto complex : selector->elements()) {\n        originals.insert(complex);\n      }\n    }\n\n    if (!extensions.empty()) {\n\n      SelectorListObj res = extendList(selector, extensions, mediaContext);\n\n      selector->elements(res->elements());\n\n    }\n\n    if (!mediaContext.isNull()) {\n      mediaContexts.insert(selector, mediaContext);\n    }\n\n    registerSelector(selector, selector);\n\n  }\n  // EO addSelector\n\n  // ##########################################################################\n  // Registers the [SimpleSelector]s in [list]\n  // to point to [rule] in [selectors].\n  // ##########################################################################\n  void Extender::registerSelector(\n    const SelectorListObj& list,\n    const SelectorListObj& rule)\n  {\n    if (list.isNull() || list->empty()) return;\n    for (auto complex : list->elements()) {\n      for (auto component : complex->elements()) {\n        if (auto compound = component->getCompound()) {\n          for (SimpleSelector* simple : compound->elements()) {\n            selectors[simple].insert(rule);\n            if (auto pseudo = simple->getPseudoSelector()) {\n              if (pseudo->selector()) {\n                auto sel = pseudo->selector();\n                registerSelector(sel, rule);\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n  // EO registerSelector\n\n  // ##########################################################################\n  // Returns an extension that combines [left] and [right]. Throws\n  // a [SassException] if [left] and [right] have incompatible\n  // media contexts. Throws an [ArgumentError] if [left]\n  // and [right] don't have the same extender and target.\n  // ##########################################################################\n  Extension Extender::mergeExtension(\n    const Extension& lhs,\n    const Extension& rhs)\n  {\n    // If one extension is optional and doesn't add a\n    // special media context, it doesn't need to be merged.\n    if (rhs.isOptional && rhs.mediaContext.isNull()) return lhs;\n    if (lhs.isOptional && lhs.mediaContext.isNull()) return rhs;\n\n    Extension rv(lhs);\n    // ToDo: is this right?\n    rv.isOptional = true;\n    rv.isOriginal = false;\n    return rv;\n  }\n  // EO mergeExtension\n\n  // ##########################################################################\n  // Helper function to copy extension between maps\n  // ##########################################################################\n  // Seems only relevant for sass 4.0 modules\n  // ##########################################################################\n  /* void mapCopyExts(\n    ExtSelExtMap& dest,\n    const ExtSelExtMap& source)\n  {\n    for (auto it : source) {\n      SimpleSelectorObj key = it.first;\n      ExtSelExtMapEntry& inner = it.second;\n      ExtSelExtMap::iterator dmap = dest.find(key);\n      if (dmap == dest.end()) {\n        dest.insert(std::make_pair(key, inner));\n      }\n      else {\n        ExtSelExtMapEntry& imap = dmap->second;\n        // ToDo: optimize ordered_map API!\n        // ToDo: we iterate and fetch the value\n        for (ComplexSelectorObj& it2 : inner) {\n          imap.insert(it2, inner.get(it2));\n        }\n      }\n    }\n  } */\n  // EO mapCopyExts\n\n  // ##########################################################################\n  // Adds an extension to this extender. The [extender] is the selector for the\n  // style rule in which the extension is defined, and [target] is the selector\n  // passed to `@extend`. The [extend] provides the extend span and indicates\n  // whether the extension is optional. The [mediaContext] defines the media query\n  // context in which the extension is defined. It can only extend selectors\n  // within the same context. A `null` context indicates no media queries.\n  // ##########################################################################\n  // ToDo: rename extender to parent, since it is not involved in extending stuff\n  // ToDo: check why dart sass passes the ExtendRule around (is this the main selector?)\n  // ##########################################################################\n  // Note: this function could need some logic cleanup\n  // ##########################################################################\n  void Extender::addExtension(\n    const SelectorListObj& extender,\n    const SimpleSelectorObj& target,\n    const CssMediaRuleObj& mediaQueryContext,\n    bool is_optional)\n  {\n\n    auto rules = selectors.find(target);\n    bool hasRule = rules != selectors.end();\n\n    ExtSelExtMapEntry newExtensions;\n\n    // ToDo: we check this here first and fetch the same? item again after the loop!?\n    bool hasExistingExtensions = extensionsByExtender.find(target) != extensionsByExtender.end();\n\n    ExtSelExtMapEntry& sources = extensions[target];\n\n    for (auto& complex : extender->elements()) {\n\n      Extension state(complex);\n      // ToDo: fine-tune public API\n      state.target = target;\n      state.isOptional = is_optional;\n      state.mediaContext = mediaQueryContext;\n\n      if (sources.hasKey(complex)) {\n        // If there's already an extend from [extender] to [target],\n        // we don't need to re-run the extension. We may need to\n        // mark the extension as mandatory, though.\n        // sources.insert(complex, mergeExtension(existingState->second, state);\n        // ToDo: implement behavior once use case is found!?\n        continue;\n      }\n\n      sources.insert(complex, state);\n\n      for (auto& component : complex->elements()) {\n        if (auto compound = component->getCompound()) {\n          for (auto& simple : compound->elements()) {\n            extensionsByExtender[simple].push_back(state);\n            if (sourceSpecificity.find(simple) == sourceSpecificity.end()) {\n              // Only source specificity for the original selector is relevant.\n              // Selectors generated by `@extend` don't get new specificity.\n              sourceSpecificity[simple] = complex->maxSpecificity();\n            }\n          }\n        }\n      }\n\n      if (hasRule || hasExistingExtensions) {\n        newExtensions.insert(complex, state);\n      }\n\n    }\n    // EO foreach complex\n\n    if (newExtensions.empty()) {\n      return;\n    }\n\n    ExtSelExtMap newExtensionsByTarget;\n    newExtensionsByTarget.insert(std::make_pair(target, newExtensions));\n    // ToDo: do we really need to fetch again (see top off fn)\n    auto existingExtensions = extensionsByExtender.find(target);\n    if (existingExtensions != extensionsByExtender.end()) {\n      if (hasExistingExtensions && !existingExtensions->second.empty()) {\n        // Seems only relevant for sass 4.0 modules\n        // auto additionalExtensions =\n          extendExistingExtensions(existingExtensions->second, newExtensionsByTarget);\n        // Seems only relevant for sass 4.0 modules\n        /* if (!additionalExtensions.empty()) {\n          mapCopyExts(newExtensionsByTarget, additionalExtensions);\n        } */\n      }\n    }\n\n    if (hasRule) {\n      extendExistingStyleRules(selectors[target], newExtensionsByTarget);\n    }\n\n  }\n  // EO addExtension\n\n  // ##########################################################################\n  // Extend [extensions] using [newExtensions].\n  // ##########################################################################\n  // Note: dart-sass throws an error in here\n  // ##########################################################################\n  void Extender::extendExistingStyleRules(\n    const ExtListSelSet& rules,\n    const ExtSelExtMap& newExtensions)\n  {\n    // Is a modifyableCssStyleRUle in dart sass\n    for (const SelectorListObj& rule : rules) {\n      const SelectorListObj& oldValue = SASS_MEMORY_COPY(rule);\n      CssMediaRuleObj mediaContext;\n      if (mediaContexts.hasKey(rule)) mediaContext = mediaContexts.get(rule);\n      SelectorListObj ext = extendList(rule, newExtensions, mediaContext);\n      // If no extends actually happened (for example because unification\n      // failed), we don't need to re-register the selector.\n      if (ObjEqualityFn(oldValue, ext)) continue;\n      rule->elements(ext->elements());\n      registerSelector(rule, rule);\n\n    }\n  }\n  // EO extendExistingStyleRules\n\n  // ##########################################################################\n  // Extend [extensions] using [newExtensions]. Note that this does duplicate\n  // some work done by [_extendExistingStyleRules],  but it's necessary to\n  // expand each extension's extender separately without reference to the full\n  // selector list, so that relevant results don't get trimmed too early.\n  //\n  // Returns extensions that should be added to [newExtensions] before\n  // extending selectors in order to properly handle extension loops such as:\n  //\n  //     .c {x: y; @extend .a}\n  //     .x.y.a {@extend .b}\n  //     .z.b {@extend .c}\n  //\n  // Returns `null` (Note: empty map) if there are no extensions to add.\n  // ##########################################################################\n  // Note: maybe refactor to return `bool` (and pass reference)\n  // Note: dart-sass throws an error in here\n  // ##########################################################################\n  ExtSelExtMap Extender::extendExistingExtensions(\n    // Taking in a reference here makes MSVC debug stuck!?\n    const sass::vector<Extension>& oldExtensions,\n    const ExtSelExtMap& newExtensions)\n  {\n\n    ExtSelExtMap additionalExtensions;\n\n    // During the loop `oldExtensions` vector might be changed.\n    // Callers normally pass this from `extensionsByExtender` and\n    // that points back to the `sources` vector from `extensions`.\n    for (size_t i = 0, iL = oldExtensions.size(); i < iL; i += 1) {\n      const Extension& extension = oldExtensions[i];\n      ExtSelExtMapEntry& sources = extensions[extension.target];\n      sass::vector<ComplexSelectorObj> selectors(extendComplex(\n        extension.extender,\n        newExtensions,\n        extension.mediaContext\n      ));\n\n      if (selectors.empty()) {\n        continue;\n      }\n\n      // ToDo: \"catch\" error from extend\n\n      bool first = false, containsExtension =\n        ObjEqualityFn(selectors.front(), extension.extender);\n      for (const ComplexSelectorObj& complex : selectors) {\n        // If the output contains the original complex\n        // selector, there's no need to recreate it.\n        if (containsExtension && first) {\n          first = false;\n          continue;\n        }\n\n        const Extension withExtender =\n          extension.withExtender(complex);\n        if (sources.hasKey(complex)) {\n          sources.insert(complex, mergeExtension(\n            sources.get(complex), withExtender));\n        }\n        else {\n          sources.insert(complex, withExtender);\n          /*\n          // Seems only relevant for sass 4.0 modules\n          for (auto& component : complex->elements()) {\n            if (auto compound = component->getCompound()) {\n              for (auto& simple : compound->elements()) {\n                extensionsByExtender[simple].push_back(withExtender);\n              }\n            }\n          }\n          if (newExtensions.find(extension.target) != newExtensions.end()) {\n            additionalExtensions[extension.target].insert(complex, withExtender);\n          }\n          */\n        }\n      }\n\n      // If [selectors] doesn't contain [extension.extender],\n      // for example if it was replaced due to :not() expansion,\n      // we must get rid of the old version.\n      /*\n      // Seems only relevant for sass 4.0 modules\n      if (!containsExtension) {\n        sources.erase(extension.extender);\n      }\n      */\n\n    }\n\n    return additionalExtensions;\n\n  }\n  // EO extendExistingExtensions\n\n  // ##########################################################################\n  // Extends [list] using [extensions].\n  // ##########################################################################\n  SelectorListObj Extender::extendList(\n    const SelectorListObj& list,\n    const ExtSelExtMap& extensions,\n    const CssMediaRuleObj& mediaQueryContext)\n  {\n\n    // This could be written more simply using [List.map], but we want to\n    // avoid any allocations in the common case where no extends apply.\n    sass::vector<ComplexSelectorObj> extended;\n    for (size_t i = 0; i < list->length(); i++) {\n      const ComplexSelectorObj& complex = list->get(i);\n      sass::vector<ComplexSelectorObj> result =\n        extendComplex(complex, extensions, mediaQueryContext);\n      if (result.empty()) {\n        if (!extended.empty()) {\n          extended.push_back(complex);\n        }\n      }\n      else {\n        if (extended.empty()) {\n          for (size_t n = 0; n < i; n += 1) {\n            extended.push_back(list->get(n));\n          }\n        }\n        for (auto sel : result) {\n          extended.push_back(sel);\n        }\n      }\n    }\n\n    if (extended.empty()) {\n      return list;\n    }\n\n    SelectorListObj rv = SASS_MEMORY_NEW(SelectorList, list->pstate());\n    rv->concat(trim(extended, originals));\n    return rv;\n\n  }\n  // EO extendList\n\n  // ##########################################################################\n  // Extends [complex] using [extensions], and\n  // returns the contents of a [SelectorList].\n  // ##########################################################################\n  sass::vector<ComplexSelectorObj> Extender::extendComplex(\n    // Taking in a reference here makes MSVC debug stuck!?\n    const ComplexSelectorObj& complex,\n    const ExtSelExtMap& extensions,\n    const CssMediaRuleObj& mediaQueryContext)\n  {\n\n    // The complex selectors that each compound selector in [complex.components]\n    // can expand to.\n    //\n    // For example, given\n    //\n    //     .a .b {...}\n    //     .x .y {@extend .b}\n    //\n    // this will contain\n    //\n    //     [\n    //       [.a],\n    //       [.b, .x .y]\n    //     ]\n    //\n    // This could be written more simply using [List.map], but we want to avoid\n    // any allocations in the common case where no extends apply.\n\n    sass::vector<ComplexSelectorObj> result;\n    sass::vector<sass::vector<ComplexSelectorObj>> extendedNotExpanded;\n    bool isOriginal = originals.find(complex) != originals.end();\n    for (size_t i = 0; i < complex->length(); i += 1) {\n      const SelectorComponentObj& component = complex->get(i);\n      if (CompoundSelector* compound = Cast<CompoundSelector>(component)) {\n        sass::vector<ComplexSelectorObj> extended = extendCompound(\n          compound, extensions, mediaQueryContext, isOriginal);\n        if (extended.empty()) {\n          if (!extendedNotExpanded.empty()) {\n            extendedNotExpanded.push_back({\n              compound->wrapInComplex()\n            });\n          }\n        }\n        else {\n          // Note: dart-sass checks for null!?\n          if (extendedNotExpanded.empty()) {\n            for (size_t n = 0; n < i; n++) {\n                extendedNotExpanded.push_back({\n                  complex->at(n)->wrapInComplex()\n                });\n            }\n          }\n          extendedNotExpanded.push_back(extended);\n        }\n      }\n      else {\n        // Note: dart-sass checks for null!?\n        if (!extendedNotExpanded.empty()) {\n          extendedNotExpanded.push_back({\n            component->wrapInComplex()\n          });\n        }\n      }\n    }\n\n    // Note: dart-sass checks for null!?\n    if (extendedNotExpanded.empty()) {\n      return {};\n    }\n\n    bool first = true;\n\n    // ToDo: either change weave or paths to work with the same data?\n    sass::vector<sass::vector<ComplexSelectorObj>>\n      paths = permutate(extendedNotExpanded);\n\n    for (const sass::vector<ComplexSelectorObj>& path : paths) {\n      // Unpack the inner complex selector to component list\n      sass::vector<sass::vector<SelectorComponentObj>> _paths;\n      for (const ComplexSelectorObj& sel : path) {\n        _paths.insert(_paths.end(), sel->elements());\n      }\n\n      sass::vector<sass::vector<SelectorComponentObj>> weaved = weave(_paths);\n\n      for (sass::vector<SelectorComponentObj>& components : weaved) {\n\n        ComplexSelectorObj cplx = SASS_MEMORY_NEW(ComplexSelector, complex->pstate());\n        cplx->hasPreLineFeed(complex->hasPreLineFeed());\n        for (auto& pp : path) {\n          if (pp->hasPreLineFeed()) {\n            cplx->hasPreLineFeed(true);\n          }\n        }\n        cplx->elements(components);\n\n        // Make sure that copies of [complex] retain their status\n        // as \"original\" selectors. This includes selectors that\n        // are modified because a :not() was extended into.\n        if (first && originals.find(complex) != originals.end()) {\n          originals.insert(cplx);\n        }\n        first = false;\n\n        auto it = result.begin();\n        while (it != result.end()) {\n          if (ObjEqualityFn(*it, cplx)) break;\n          it += 1;\n        }\n        if (it == result.end()) {\n          result.push_back(cplx);\n        }\n\n        if (result.size() > 500) {\n          throw Exception::EndlessExtendError(traces, complex);\n        }\n\n      }\n\n    }\n\n    return result;\n  }\n  // EO extendComplex\n\n  // ##########################################################################\n  // Returns a one-off [Extension] whose\n  // extender is composed solely of [simple].\n  // ##########################################################################\n  Extension Extender::extensionForSimple(\n    const SimpleSelectorObj& simple) const\n  {\n    Extension extension(simple->wrapInComplex());\n    extension.specificity = maxSourceSpecificity(simple);\n    extension.isOriginal = true;\n    return extension;\n  }\n  // Extender::extensionForSimple\n\n  // ##########################################################################\n  // Returns a one-off [Extension] whose extender is composed\n  // solely of a compound selector containing [simples].\n  // ##########################################################################\n  Extension Extender::extensionForCompound(\n    // Taking in a reference here makes MSVC debug stuck!?\n    const sass::vector<SimpleSelectorObj>& simples) const\n  {\n    CompoundSelectorObj compound = SASS_MEMORY_NEW(CompoundSelector, SourceSpan(\"[ext]\"));\n    compound->concat(simples);\n    Extension extension(compound->wrapInComplex());\n    // extension.specificity = sourceSpecificity[simple];\n    extension.isOriginal = true;\n    return extension;\n  }\n  // EO extensionForCompound\n\n  // ##########################################################################\n  // Extends [compound] using [extensions], and returns the\n  // contents of a [SelectorList]. The [inOriginal] parameter\n  // indicates whether this is in an original complex selector,\n  // meaning that [compound] should not be trimmed out.\n  // ##########################################################################\n  sass::vector<ComplexSelectorObj> Extender::extendCompound(\n    const CompoundSelectorObj& compound,\n    const ExtSelExtMap& extensions,\n    const CssMediaRuleObj& mediaQueryContext,\n    bool inOriginal)\n  {\n\n    // If there's more than one target and they all need to\n    // match, we track which targets are actually extended.\n    ExtSmplSelSet targetsUsed2;\n\n    ExtSmplSelSet* targetsUsed = nullptr;\n\n    if (mode != ExtendMode::NORMAL && extensions.size() > 1) {\n      targetsUsed = &targetsUsed2;\n    }\n\n    sass::vector<ComplexSelectorObj> result;\n    // The complex selectors produced from each component of [compound].\n    sass::vector<sass::vector<Extension>> options;\n\n    for (size_t i = 0; i < compound->length(); i++) {\n      const SimpleSelectorObj& simple = compound->get(i);\n      auto extended = extendSimple(simple, extensions, mediaQueryContext, targetsUsed);\n      if (extended.empty()) {\n        if (!options.empty()) {\n          options.push_back({ extensionForSimple(simple) });\n        }\n      }\n      else {\n        if (options.empty()) {\n          if (i != 0) {\n            sass::vector<SimpleSelectorObj> in;\n            for (size_t n = 0; n < i; n += 1) {\n              in.push_back(compound->get(n));\n            }\n            options.push_back({ extensionForCompound(in) });\n          }\n        }\n        options.insert(options.end(),\n          extended.begin(), extended.end());\n      }\n    }\n\n    if (options.empty()) {\n      return {};\n    }\n\n    // If [_mode] isn't [ExtendMode.normal] and we didn't use all\n    // the targets in [extensions], extension fails for [compound].\n    if (targetsUsed != nullptr) {\n\n      if (targetsUsed->size() != extensions.size()) {\n        if (!targetsUsed->empty()) {\n          return {};\n        }\n      }\n    }\n\n    // Optimize for the simple case of a single simple\n    // selector that doesn't need any unification.\n    if (options.size() == 1) {\n      sass::vector<Extension> exts = options[0];\n      for (size_t n = 0; n < exts.size(); n += 1) {\n        exts[n].assertCompatibleMediaContext(mediaQueryContext, traces);\n        // To fix invalid css we need to re-order some\n        // Therefore we need to make copies for them\n        if (exts[n].extender->isInvalidCss()) {\n          exts[n].extender = SASS_MEMORY_COPY(exts[n].extender);\n          for (SelectorComponentObj& component : exts[n].extender->elements()) {\n            if (CompoundSelector* compound = component->getCompound()) {\n              if (compound->isInvalidCss()) {\n                CompoundSelector* copy = SASS_MEMORY_COPY(compound);\n                copy->sortChildren();\n                component = copy;\n              }\n            }\n          }\n        }\n        result.push_back(exts[n].extender);\n      }\n      return result;\n    }\n\n    // Find all paths through [options]. In this case, each path represents a\n    // different unification of the base selector. For example, if we have:\n    //\n    //     .a.b {...}\n    //     .w .x {@extend .a}\n    //     .y .z {@extend .b}\n    //\n    // then [options] is `[[.a, .w .x], [.b, .y .z]]` and `paths(options)` is\n    //\n    //     [\n    //       [.a, .b],\n    //       [.a, .y .z],\n    //       [.w .x, .b],\n    //       [.w .x, .y .z]\n    //     ]\n    //\n    // We then unify each path to get a list of complex selectors:\n    //\n    //     [\n    //       [.a.b],\n    //       [.y .a.z],\n    //       [.w .x.b],\n    //       [.w .y .x.z, .y .w .x.z]\n    //     ]\n\n    bool first = mode != ExtendMode::REPLACE;\n    sass::vector<ComplexSelectorObj> unifiedPaths;\n    sass::vector<sass::vector<Extension>> prePaths = permutate(options);\n\n    for (size_t i = 0; i < prePaths.size(); i += 1) {\n      sass::vector<sass::vector<SelectorComponentObj>> complexes;\n      const sass::vector<Extension>& path = prePaths[i];\n      if (first) {\n        // The first path is always the original selector. We can't just\n        // return [compound] directly because pseudo selectors may be\n        // modified, but we don't have to do any unification.\n        first = false;\n        CompoundSelectorObj mergedSelector =\n          SASS_MEMORY_NEW(CompoundSelector, \"[ext]\");\n        for (size_t n = 0; n < path.size(); n += 1) {\n          const ComplexSelectorObj& sel = path[n].extender;\n          if (CompoundSelectorObj compound = Cast<CompoundSelector>(sel->last())) {\n            mergedSelector->concat(compound->elements());\n          }\n        }\n        complexes.push_back({ mergedSelector });\n      }\n      else {\n        sass::vector<SimpleSelectorObj> originals;\n        sass::vector<sass::vector<SelectorComponentObj>> toUnify;\n\n        for (auto& state : path) {\n          if (state.isOriginal) {\n            const ComplexSelectorObj& sel = state.extender;\n            if (const CompoundSelector* compound = Cast<CompoundSelector>(sel->last())) {\n              originals.insert(originals.end(), compound->last());\n            }\n          }\n          else {\n            toUnify.push_back(state.extender->elements());\n          }\n        }\n        if (!originals.empty()) {\n          CompoundSelectorObj merged =\n            SASS_MEMORY_NEW(CompoundSelector, \"[compound]\");\n          merged->concat(originals);\n          toUnify.insert(toUnify.begin(), { merged });\n        }\n        complexes = unifyComplex(toUnify);\n        if (complexes.empty()) {\n          return {};\n        }\n\n      }\n\n      bool lineBreak = false;\n      // var specificity = _sourceSpecificityFor(compound);\n      for (const Extension& state : path) {\n        state.assertCompatibleMediaContext(mediaQueryContext, traces);\n        lineBreak = lineBreak || state.extender->hasPreLineFeed();\n        // specificity = math.max(specificity, state.specificity);\n      }\n\n      for (sass::vector<SelectorComponentObj>& components : complexes) {\n        auto sel = SASS_MEMORY_NEW(ComplexSelector, \"[unified]\");\n        sel->hasPreLineFeed(lineBreak);\n        sel->elements(components);\n\n        /* This seems to do too much in regard of previous behavior\n        for (SelectorComponentObj& component : sel->elements()) {\n          if (CompoundSelector* compound = component->getCompound()) {\n            if (compound->isInvalidCss()) {\n              CompoundSelector* copy = SASS_MEMORY_COPY(compound);\n              copy->sortChildren();\n              component = copy;\n            }\n          }\n        }*/\n\n        unifiedPaths.push_back(sel);\n\n      }\n\n    }\n\n    return unifiedPaths;\n  }\n  // EO extendCompound\n\n  // ##########################################################################\n  // Extends [simple] without extending the\n  // contents of any selector pseudos it contains.\n  // ##########################################################################\n  sass::vector<Extension> Extender::extendWithoutPseudo(\n    const SimpleSelectorObj& simple,\n    const ExtSelExtMap& extensions,\n    ExtSmplSelSet* targetsUsed) const\n  {\n\n    auto extension = extensions.find(simple);\n    if (extension == extensions.end()) return {};\n    const ExtSelExtMapEntry& extenders = extension->second;\n\n    if (targetsUsed != nullptr) {\n      targetsUsed->insert(simple);\n    }\n    if (mode == ExtendMode::REPLACE) {\n      return extenders.values();\n    }\n\n    const sass::vector<Extension>&\n      values = extenders.values();\n    sass::vector<Extension> result;\n    result.reserve(values.size() + 1);\n    result.push_back(extensionForSimple(simple));\n    result.insert(result.end(), values.begin(), values.end());\n    return result;\n  }\n  // EO extendWithoutPseudo\n\n  // ##########################################################################\n  // Extends [simple] and also extending the\n  // contents of any selector pseudos it contains.\n  // ##########################################################################\n  sass::vector<sass::vector<Extension>> Extender::extendSimple(\n    const SimpleSelectorObj& simple,\n    const ExtSelExtMap& extensions,\n    const CssMediaRuleObj& mediaQueryContext,\n    ExtSmplSelSet* targetsUsed)\n  {\n    if (PseudoSelector* pseudo = Cast<PseudoSelector>(simple)) {\n      if (pseudo->selector()) {\n        sass::vector<sass::vector<Extension>> merged;\n        sass::vector<PseudoSelectorObj> extended =\n          extendPseudo(pseudo, extensions, mediaQueryContext);\n        for (PseudoSelectorObj& extend : extended) {\n          SimpleSelectorObj simple = extend;\n          sass::vector<Extension> result =\n            extendWithoutPseudo(simple, extensions, targetsUsed);\n          if (result.empty()) result = { extensionForSimple(extend) };\n          merged.push_back(result);\n        }\n        if (!extended.empty()) {\n          return merged;\n        }\n      }\n    }\n    sass::vector<Extension> result =\n      extendWithoutPseudo(simple, extensions, targetsUsed);\n    if (result.empty()) return {};\n    return { result };\n  }\n  // extendSimple\n\n  // ##########################################################################\n  // Inner loop helper for [extendPseudo] function\n  // ##########################################################################\n  sass::vector<ComplexSelectorObj> Extender::extendPseudoComplex(\n    const ComplexSelectorObj& complex,\n    const PseudoSelectorObj& pseudo,\n    const CssMediaRuleObj& mediaQueryContext)\n  {\n\n    if (complex->length() != 1) { return { complex }; }\n    auto compound = Cast<CompoundSelector>(complex->get(0));\n    if (compound == nullptr) { return { complex }; }\n    if (compound->length() != 1) { return { complex }; }\n    auto innerPseudo = Cast<PseudoSelector>(compound->get(0));\n    if (innerPseudo == nullptr) { return { complex }; }\n    if (!innerPseudo->selector()) { return { complex }; }\n\n    sass::string name(pseudo->normalized());\n\n    if (name == \"not\") {\n      // In theory, if there's a `:not` nested within another `:not`, the\n      // inner `:not`'s contents should be unified with the return value.\n      // For example, if `:not(.foo)` extends `.bar`, `:not(.bar)` should\n      // become `.foo:not(.bar)`. However, this is a narrow edge case and\n      // supporting it properly would make this code and the code calling it\n      // a lot more complicated, so it's not supported for now.\n      if (innerPseudo->normalized() != \"matches\") return {};\n      return innerPseudo->selector()->elements();\n    }\n    else if (name == \"matches\" || name == \"any\" || name == \"current\" || name == \"nth-child\" || name == \"nth-last-child\") {\n      // As above, we could theoretically support :not within :matches, but\n      // doing so would require this method and its callers to handle much\n      // more complex cases that likely aren't worth the pain.\n      if (innerPseudo->name() != pseudo->name()) return {};\n      if (!ObjEquality()(innerPseudo->argument(), pseudo->argument())) return {};\n      return innerPseudo->selector()->elements();\n    }\n    else if (name == \"has\" || name == \"host\" || name == \"host-context\" || name == \"slotted\") {\n      // We can't expand nested selectors here, because each layer adds an\n      // additional layer of semantics. For example, `:has(:has(img))`\n      // doesn't match `<div><img></div>` but `:has(img)` does.\n      return { complex };\n    }\n\n    return {};\n\n  }\n  // EO extendPseudoComplex\n\n  // ##########################################################################\n  // Extends [pseudo] using [extensions], and returns\n  // a list of resulting pseudo selectors.\n  // ##########################################################################\n  sass::vector<PseudoSelectorObj> Extender::extendPseudo(\n    const PseudoSelectorObj& pseudo,\n    const ExtSelExtMap& extensions,\n    const CssMediaRuleObj& mediaQueryContext)\n  {\n    auto selector = pseudo->selector();\n    SelectorListObj extended = extendList(\n      selector, extensions, mediaQueryContext);\n    if (!extended || !pseudo || !pseudo->selector()) { return {}; }\n    if (ObjEqualityFn(pseudo->selector(), extended)) { return {}; }\n\n    // For `:not()`, we usually want to get rid of any complex selectors because\n    // that will cause the selector to fail to parse on all browsers at time of\n    // writing. We can keep them if either the original selector had a complex\n    // selector, or the result of extending has only complex selectors, because\n    // either way we aren't breaking anything that isn't already broken.\n    sass::vector<ComplexSelectorObj> complexes = extended->elements();\n\n    if (pseudo->normalized() == \"not\") {\n      if (!hasAny(pseudo->selector()->elements(), hasMoreThanOne)) {\n        if (hasAny(extended->elements(), hasExactlyOne)) {\n          complexes.clear();\n          for (auto& complex : extended->elements()) {\n            if (complex->length() <= 1) {\n              complexes.push_back(complex);\n            }\n          }\n        }\n      }\n    }\n\n    sass::vector<ComplexSelectorObj> expanded = expand(\n      complexes, extendPseudoComplex, pseudo, mediaQueryContext);\n\n    // Older browsers support `:not`, but only with a single complex selector.\n    // In order to support those browsers, we break up the contents of a `:not`\n    // unless it originally contained a selector list.\n    if (pseudo->normalized() == \"not\") {\n      if (pseudo->selector()->length() == 1) {\n        sass::vector<PseudoSelectorObj> pseudos;\n        for (size_t i = 0; i < expanded.size(); i += 1) {\n          pseudos.push_back(pseudo->withSelector(\n            expanded[i]->wrapInList()\n          ));\n        }\n        return pseudos;\n      }\n    }\n\n    SelectorListObj list = SASS_MEMORY_NEW(SelectorList, \"[pseudo]\");\n    list->concat(expanded);\n    return { pseudo->withSelector(list) };\n\n  }\n  // EO extendPseudo\n\n  // ##########################################################################\n  // Rotates the element in list from [start] (inclusive) to [end] (exclusive)\n  // one index higher, looping the final element back to [start].\n  // ##########################################################################\n  void Extender::rotateSlice(\n    sass::vector<ComplexSelectorObj>& list,\n    size_t start, size_t end)\n  {\n    auto element = list[end - 1];\n    for (size_t i = start; i < end; i++) {\n      auto next = list[i];\n      list[i] = element;\n      element = next;\n    }\n  }\n  // EO rotateSlice\n\n  // ##########################################################################\n  // Removes elements from [selectors] if they're subselectors of other\n  // elements. The [isOriginal] callback indicates which selectors are\n  // original to the document, and thus should never be trimmed.\n  // ##########################################################################\n  // Note: for adaption I pass in the set directly, there is some\n  // code path in selector-trim that might need this special callback\n  // ##########################################################################\n  sass::vector<ComplexSelectorObj> Extender::trim(\n    const sass::vector<ComplexSelectorObj>& selectors,\n    const ExtCplxSelSet& existing) const\n  {\n\n    // Avoid truly horrific quadratic behavior.\n    // TODO(nweiz): I think there may be a way to get perfect trimming\n    // without going quadratic by building some sort of trie-like\n    // data structure that can be used to look up superselectors.\n    // TODO(mgreter): Check how this performs in C++ (up the limit)\n    if (selectors.size() > 100) return selectors;\n\n    // This is n² on the sequences, but only comparing between separate sequences\n    // should limit the quadratic behavior. We iterate from last to first and reverse\n    // the result so that, if two selectors are identical, we keep the first one.\n    sass::vector<ComplexSelectorObj> result; size_t numOriginals = 0;\n\n    size_t i = selectors.size();\n  outer: // Use label to continue loop\n    while (--i != sass::string::npos) {\n\n      const ComplexSelectorObj& complex1 = selectors[i];\n      // Check if selector in known in existing \"originals\"\n      // For custom behavior dart-sass had `isOriginal(complex1)`\n      if (existing.find(complex1) != existing.end()) {\n        // Make sure we don't include duplicate originals, which could\n        // happen if a style rule extends a component of its own selector.\n        for (size_t j = 0; j < numOriginals; j++) {\n          if (ObjEqualityFn(result[j], complex1)) {\n            rotateSlice(result, 0, j + 1);\n            goto outer;\n          }\n        }\n        result.insert(result.begin(), complex1);\n        numOriginals++;\n        continue;\n      }\n\n      // The maximum specificity of the sources that caused [complex1]\n      // to be generated. In order for [complex1] to be removed, there\n      // must be another selector that's a superselector of it *and*\n      // that has specificity greater or equal to this.\n      size_t maxSpecificity = 0;\n      for (const SelectorComponentObj& component : complex1->elements()) {\n        if (const CompoundSelectorObj compound = Cast<CompoundSelector>(component)) {\n          maxSpecificity = std::max(maxSpecificity, maxSourceSpecificity(compound));\n        }\n      }\n\n\n      // Look in [result] rather than [selectors] for selectors after [i]. This\n      // ensures we aren't comparing against a selector that's already been trimmed,\n      // and thus that if there are two identical selectors only one is trimmed.\n      if (hasAny(result, dontTrimComplex, complex1, maxSpecificity)) {\n        continue;\n      }\n\n      // Check if any element (up to [i]) from [selector] returns true\n      // when passed to [dontTrimComplex]. The arguments [complex1] and\n      // [maxSepcificity] will be passed to the invoked function.\n      if (hasSubAny(selectors, i, dontTrimComplex, complex1, maxSpecificity)) {\n        continue;\n      }\n\n      // ToDo: Maybe use deque for front insert?\n      result.insert(result.begin(), complex1);\n\n    }\n\n    return result;\n\n  }\n  // EO trim\n\n  // ##########################################################################\n  // Returns the maximum specificity of the given [simple] source selector.\n  // ##########################################################################\n  size_t Extender::maxSourceSpecificity(const SimpleSelectorObj& simple) const\n  {\n    auto it = sourceSpecificity.find(simple);\n    if (it == sourceSpecificity.end()) return 0;\n    return it->second;\n  }\n  // EO maxSourceSpecificity(SimpleSelectorObj)\n\n  // ##########################################################################\n  // Returns the maximum specificity for sources that went into producing [compound].\n  // ##########################################################################\n  size_t Extender::maxSourceSpecificity(const CompoundSelectorObj& compound) const\n  {\n    size_t specificity = 0;\n    for (auto simple : compound->elements()) {\n      size_t src = maxSourceSpecificity(simple);\n      specificity = std::max(specificity, src);\n    }\n    return specificity;\n  }\n  // EO maxSourceSpecificity(CompoundSelectorObj)\n\n  // ##########################################################################\n  // Helper function used as callbacks on lists\n  // ##########################################################################\n  bool Extender::dontTrimComplex(\n    const ComplexSelector* complex2,\n    const ComplexSelector* complex1,\n    const size_t maxSpecificity)\n  {\n    if (complex2->minSpecificity() < maxSpecificity) return false;\n    return complex2->isSuperselectorOf(complex1);\n  }\n  // EO dontTrimComplex\n\n  // ##########################################################################\n  // Helper function used as callbacks on lists\n  // ##########################################################################\n  bool Extender::hasExactlyOne(const ComplexSelectorObj& vec)\n  {\n    return vec->length() == 1;\n  }\n  // EO hasExactlyOne\n\n  // ##########################################################################\n  // Helper function used as callbacks on lists\n  // ##########################################################################\n  bool Extender::hasMoreThanOne(const ComplexSelectorObj& vec)\n  {\n    return vec->length() > 1;\n  }\n  // hasMoreThanOne\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/extender.hpp",
    "content": "#ifndef SASS_EXTENDER_H\n#define SASS_EXTENDER_H\n\n#include <set>\n#include <map>\n#include <string>\n\n#include \"ast_helpers.hpp\"\n#include \"ast_fwd_decl.hpp\"\n#include \"operation.hpp\"\n#include \"extension.hpp\"\n#include \"backtrace.hpp\"\n#include \"ordered_map.hpp\"\n\nnamespace Sass {\n\n  // ##########################################################################\n  // Different hash map types used by extender\n  // ##########################################################################\n\n  // This is special (ptrs!)\n  typedef std::unordered_set<\n    ComplexSelectorObj,\n    ObjPtrHash,\n    ObjPtrEquality\n  > ExtCplxSelSet;\n\n  typedef std::unordered_set<\n    SimpleSelectorObj,\n    ObjHash,\n    ObjEquality\n  > ExtSmplSelSet;\n\n  typedef std::unordered_set<\n    SelectorListObj,\n    ObjPtrHash,\n    ObjPtrEquality\n  > ExtListSelSet;\n\n  typedef std::unordered_map<\n    SimpleSelectorObj,\n    ExtListSelSet,\n    ObjHash,\n    ObjEquality\n  > ExtSelMap;\n\n  typedef ordered_map<\n    ComplexSelectorObj,\n    Extension,\n    ObjHash,\n    ObjEquality\n  > ExtSelExtMapEntry;\n\n  typedef std::unordered_map<\n    SimpleSelectorObj,\n    ExtSelExtMapEntry,\n    ObjHash,\n    ObjEquality\n  > ExtSelExtMap;\n\n  typedef std::unordered_map <\n    SimpleSelectorObj,\n    sass::vector<\n      Extension\n    >,\n    ObjHash,\n    ObjEquality\n  > ExtByExtMap;\n\n  class Extender : public Operation_CRTP<void, Extender> {\n\n  public:\n\n    enum ExtendMode { TARGETS, REPLACE, NORMAL, };\n\n  private:\n\n    // ##########################################################################\n    // The mode that controls this extender's behavior.\n    // ##########################################################################\n    ExtendMode mode;\n\n    // ##########################################################################\n    // Shared backtraces with context and expander. Needed the throw\n    // errors when e.g. extending across media query boundaries.\n    // ##########################################################################\n    Backtraces& traces;\n\n    // ##########################################################################\n    // A map from all simple selectors in the stylesheet to the rules that\n    // contain them.This is used to find which rules an `@extend` applies to.\n    // ##########################################################################\n    ExtSelMap selectors;\n\n    // ##########################################################################\n    // A map from all extended simple selectors\n    // to the sources of those extensions.\n    // ##########################################################################\n    ExtSelExtMap extensions;\n\n    // ##########################################################################\n    // A map from all simple selectors in extenders to\n    // the extensions that those extenders define.\n    // ##########################################################################\n    ExtByExtMap extensionsByExtender;\n\n    // ##########################################################################\n    // A map from CSS rules to the media query contexts they're defined in.\n    // This tracks the contexts in which each style rule is defined.\n    // If a rule is defined at the top level, it doesn't have an entry.\n    // ##########################################################################\n    ordered_map<\n      SelectorListObj,\n      CssMediaRuleObj,\n      ObjPtrHash,\n      ObjPtrEquality\n    > mediaContexts;\n    \n    // ##########################################################################\n    // A map from [SimpleSelector]s to the specificity of their source selectors.\n    // This tracks the maximum specificity of the [ComplexSelector] that originally \n    // contained each [SimpleSelector]. This allows us to ensure we don't trim any\n    // selectors that need to exist to satisfy the [second law that of extend][].\n    // [second law of extend]: https://github.com/sass/sass/issues/324#issuecomment-4607184\n    // ##########################################################################\n    std::unordered_map<\n      SimpleSelectorObj,\n      size_t,\n      ObjPtrHash,\n      ObjPtrEquality\n    > sourceSpecificity;\n\n    // ##########################################################################\n    // A set of [ComplexSelector]s that were originally part of their\n    // component [SelectorList]s, as opposed to being added by `@extend`.\n    // This allows us to ensure that we don't trim any selectors\n    // that need to exist to satisfy the [first law of extend][].\n    // ##########################################################################\n    ExtCplxSelSet originals;\n\n  public:\n\n    // Constructor without default [mode].\n    // [traces] are needed to throw errors.\n    Extender(Backtraces& traces);\n\n    // ##########################################################################\n    // Constructor with specific [mode].\n    // [traces] are needed to throw errors.\n    // ##########################################################################\n    Extender(ExtendMode mode, Backtraces& traces);\n\n    // ##########################################################################\n    // Empty desctructor\n    // ##########################################################################\n    ~Extender() {};\n\n    // ##########################################################################\n    // Extends [selector] with [source] extender and [targets] extendees.\n    // This works as though `source {@extend target}` were written in the\n    // stylesheet, with the exception that [target] can contain compound\n    // selectors which must be extended as a unit.\n    // ##########################################################################\n    static SelectorListObj extend(\n      SelectorListObj& selector,\n      const SelectorListObj& source,\n      const SelectorListObj& target,\n      Backtraces& traces);\n\n    // ##########################################################################\n    // Returns a copy of [selector] with [targets] replaced by [source].\n    // ##########################################################################\n    static SelectorListObj replace(\n      SelectorListObj& selector,\n      const SelectorListObj& source,\n      const SelectorListObj& target,\n      Backtraces& traces);\n\n    // ##########################################################################\n    // Adds [selector] to this extender, with [selectorSpan] as the span covering\n    // the selector and [ruleSpan] as the span covering the entire style rule.\n    // Extends [selector] using any registered extensions, then returns an empty\n    // [ModifiableCssStyleRule] with the resulting selector. If any more relevant\n    // extensions are added, the returned rule is automatically updated.\n    // The [mediaContext] is the media query context in which the selector was\n    // defined, or `null` if it was defined at the top level of the document.\n    // ##########################################################################\n    void addSelector(\n      const SelectorListObj& selector,\n      const CssMediaRuleObj& mediaContext);\n\n    // ##########################################################################\n    // Registers the [SimpleSelector]s in [list]\n    // to point to [rule] in [selectors].\n    // ##########################################################################\n    void registerSelector(\n      const SelectorListObj& list,\n      const SelectorListObj& rule);\n\n    // ##########################################################################\n    // Adds an extension to this extender. The [extender] is the selector for the\n    // style rule in which the extension is defined, and [target] is the selector\n    // passed to `@extend`. The [extend] provides the extend span and indicates \n    // whether the extension is optional. The [mediaContext] defines the media query\n    // context in which the extension is defined. It can only extend selectors\n    // within the same context. A `null` context indicates no media queries.\n    // ##########################################################################\n    void addExtension(\n      const SelectorListObj& extender,\n      const SimpleSelectorObj& target,\n      const CssMediaRuleObj& mediaQueryContext,\n      bool is_optional = false);\n\n    // ##########################################################################\n    // The set of all simple selectors in style rules handled\n    // by this extender. This includes simple selectors that\n    // were added because of downstream extensions.\n    // ##########################################################################\n    ExtSmplSelSet getSimpleSelectors() const;\n\n    // ##########################################################################\n    // Check for extends that have not been satisfied.\n    // Returns true if any non-optional extension did not\n    // extend any selector. Updates the passed reference\n    // to point to that Extension for further analysis.\n    // ##########################################################################\n    bool checkForUnsatisfiedExtends(\n      Extension& unsatisfied) const;\n\n  private:\n\n    // ##########################################################################\n    // A helper function for [extend] and [replace].\n    // ##########################################################################\n    static SelectorListObj extendOrReplace(\n      SelectorListObj& selector,\n      const SelectorListObj& source,\n      const SelectorListObj& target,\n      const ExtendMode mode,\n      Backtraces& traces);\n\n    // ##########################################################################\n    // Returns an extension that combines [left] and [right]. Throws \n    // a [SassException] if [left] and [right] have incompatible \n    // media contexts. Throws an [ArgumentError] if [left]\n    // and [right] don't have the same extender and target.\n    // ##########################################################################\n    static Extension mergeExtension(\n      const Extension& lhs,\n      const Extension& rhs);\n\n    // ##########################################################################\n    // Extend [extensions] using [newExtensions].\n    // ##########################################################################\n    // Note: dart-sass throws an error in here\n    // ##########################################################################\n    void extendExistingStyleRules(\n      const ExtListSelSet& rules,\n      const ExtSelExtMap& newExtensions);\n\n    // ##########################################################################\n    // Extend [extensions] using [newExtensions]. Note that this does duplicate\n    // some work done by [_extendExistingStyleRules],  but it's necessary to\n    // expand each extension's extender separately without reference to the full\n    // selector list, so that relevant results don't get trimmed too early.\n    // Returns `null` (Note: empty map) if there are no extensions to add.\n    // ##########################################################################\n    ExtSelExtMap extendExistingExtensions(\n      // Taking in a reference here makes MSVC debug stuck!?\n      const sass::vector<Extension>& extensions,\n      const ExtSelExtMap& newExtensions);\n\n    // ##########################################################################\n    // Extends [list] using [extensions].\n    // ##########################################################################\n    SelectorListObj extendList(\n      const SelectorListObj& list,\n      const ExtSelExtMap& extensions,\n      const CssMediaRuleObj& mediaContext);\n\n    // ##########################################################################\n    // Extends [complex] using [extensions], and\n    // returns the contents of a [SelectorList].\n    // ##########################################################################\n    sass::vector<ComplexSelectorObj> extendComplex(\n      // Taking in a reference here makes MSVC debug stuck!?\n      const ComplexSelectorObj& list,\n      const ExtSelExtMap& extensions,\n      const CssMediaRuleObj& mediaQueryContext);\n\n    // ##########################################################################\n    // Returns a one-off [Extension] whose\n    // extender is composed solely of [simple].\n    // ##########################################################################\n    Extension extensionForSimple(\n      const SimpleSelectorObj& simple) const;\n\n    // ##########################################################################\n    // Returns a one-off [Extension] whose extender is composed\n    // solely of a compound selector containing [simples].\n    // ##########################################################################\n    Extension extensionForCompound(\n      // Taking in a reference here makes MSVC debug stuck!?\n      const sass::vector<SimpleSelectorObj>& simples) const;\n\n    // ##########################################################################\n    // Extends [compound] using [extensions], and returns the\n    // contents of a [SelectorList]. The [inOriginal] parameter\n    // indicates whether this is in an original complex selector,\n    // meaning that [compound] should not be trimmed out.\n    // ##########################################################################\n    sass::vector<ComplexSelectorObj> extendCompound(\n      const CompoundSelectorObj& compound,\n      const ExtSelExtMap& extensions,\n      const CssMediaRuleObj& mediaQueryContext,\n      bool inOriginal = false);\n\n    // ##########################################################################\n    // Extends [simple] without extending the\n    // contents of any selector pseudos it contains.\n    // ##########################################################################\n    sass::vector<Extension> extendWithoutPseudo(\n      const SimpleSelectorObj& simple,\n      const ExtSelExtMap& extensions,\n      ExtSmplSelSet* targetsUsed) const;\n\n    // ##########################################################################\n    // Extends [simple] and also extending the\n    // contents of any selector pseudos it contains.\n    // ##########################################################################\n    sass::vector<sass::vector<Extension>> extendSimple(\n      const SimpleSelectorObj& simple,\n      const ExtSelExtMap& extensions,\n      const CssMediaRuleObj& mediaQueryContext,\n      ExtSmplSelSet* targetsUsed);\n\n    // ##########################################################################\n    // Inner loop helper for [extendPseudo] function\n    // ##########################################################################\n    static sass::vector<ComplexSelectorObj> extendPseudoComplex(\n      const ComplexSelectorObj& complex,\n      const PseudoSelectorObj& pseudo,\n      const CssMediaRuleObj& mediaQueryContext);\n\n    // ##########################################################################\n    // Extends [pseudo] using [extensions], and returns\n    // a list of resulting pseudo selectors.\n    // ##########################################################################\n    sass::vector<PseudoSelectorObj> extendPseudo(\n      const PseudoSelectorObj& pseudo,\n      const ExtSelExtMap& extensions,\n      const CssMediaRuleObj& mediaQueryContext);\n\n    // ##########################################################################\n    // Rotates the element in list from [start] (inclusive) to [end] (exclusive)\n    // one index higher, looping the final element back to [start].\n    // ##########################################################################\n    static void rotateSlice(\n      sass::vector<ComplexSelectorObj>& list,\n      size_t start, size_t end);\n\n    // ##########################################################################\n    // Removes elements from [selectors] if they're subselectors of other\n    // elements. The [isOriginal] callback indicates which selectors are\n    // original to the document, and thus should never be trimmed.\n    // ##########################################################################\n    sass::vector<ComplexSelectorObj> trim(\n      const sass::vector<ComplexSelectorObj>& selectors,\n      const ExtCplxSelSet& set) const;\n\n    // ##########################################################################\n    // Returns the maximum specificity of the given [simple] source selector.\n    // ##########################################################################\n    size_t maxSourceSpecificity(const SimpleSelectorObj& simple) const;\n\n    // ##########################################################################\n    // Returns the maximum specificity for sources that went into producing [compound].\n    // ##########################################################################\n    size_t maxSourceSpecificity(const CompoundSelectorObj& compound) const;\n\n    // ##########################################################################\n    // Helper function used as callbacks on lists\n    // ##########################################################################\n    static bool dontTrimComplex(\n      const ComplexSelector* complex2,\n      const ComplexSelector* complex1,\n      const size_t maxSpecificity);\n\n    // ##########################################################################\n    // Helper function used as callbacks on lists\n    // ##########################################################################\n    static bool hasExactlyOne(const ComplexSelectorObj& vec);\n    static bool hasMoreThanOne(const ComplexSelectorObj& vec);\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/extension.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast_helpers.hpp\"\n#include \"extension.hpp\"\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  // ##########################################################################\n  // Static function to create a copy with a new extender\n  // ##########################################################################\n  Extension Extension::withExtender(const ComplexSelectorObj& newExtender) const\n  {\n    Extension extension(newExtender);\n    extension.specificity = specificity;\n    extension.isOptional = isOptional;\n    extension.target = target;\n    return extension;\n  }\n\n  // ##########################################################################\n  // Asserts that the [mediaContext] for a selector is\n  // compatible with the query context for this extender.\n  // ##########################################################################\n  void Extension::assertCompatibleMediaContext(CssMediaRuleObj mediaQueryContext, Backtraces& traces) const\n  {\n\n    if (this->mediaContext.isNull()) return;\n\n    if (mediaQueryContext && ObjPtrEqualityFn(mediaContext->block(), mediaQueryContext->block())) return;\n\n    if (ObjEqualityFn<CssMediaRuleObj>(mediaQueryContext, mediaContext)) return;\n\n    throw Exception::ExtendAcrossMedia(traces, *this);\n\n  }\n\n  // ##########################################################################\n  // ##########################################################################\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/extension.hpp",
    "content": "#ifndef SASS_EXTENSION_H\n#define SASS_EXTENSION_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <unordered_map>\n#include <unordered_set>\n#include \"ast_fwd_decl.hpp\"\n#include \"backtrace.hpp\"\n\nnamespace Sass {\n\n  class Extension {\n\n  public:\n\n    // The selector in which the `@extend` appeared.\n    ComplexSelectorObj extender;\n\n    // The selector that's being extended.\n    // `null` for one-off extensions.\n    SimpleSelectorObj target;\n\n    // The minimum specificity required for any\n    // selector generated from this extender.\n    size_t specificity;\n\n    // Whether this extension is optional.\n    bool isOptional;\n\n    // Whether this is a one-off extender representing a selector that was\n    // originally in the document, rather than one defined with `@extend`.\n    bool isOriginal;\n\n    bool isSatisfied;\n\n    // The media query context to which this extend is restricted,\n    // or `null` if it can apply within any context.\n    CssMediaRuleObj mediaContext;\n\n    // Creates a one-off extension that's not intended to be modified over time.\n    // If [specificity] isn't passed, it defaults to `extender.maxSpecificity`.\n    Extension(ComplexSelectorObj extender) :\n      extender(extender),\n      target({}),\n      specificity(0),\n      isOptional(true),\n      isOriginal(false),\n      isSatisfied(false),\n      mediaContext({}) {\n\n    }\n\n    // Copy constructor\n    Extension(const Extension& extension) :\n      extender(extension.extender),\n      target(extension.target),\n      specificity(extension.specificity),\n      isOptional(extension.isOptional),\n      isOriginal(extension.isOriginal),\n      isSatisfied(extension.isSatisfied),\n      mediaContext(extension.mediaContext) {\n\n    }\n\n    // Default constructor\n    Extension() :\n      extender({}),\n      target({}),\n      specificity(0),\n      isOptional(false),\n      isOriginal(false),\n      isSatisfied(false),\n      mediaContext({}) {\n    }\n\n    // Asserts that the [mediaContext] for a selector is \n    // compatible with the query context for this extender.\n    void assertCompatibleMediaContext(CssMediaRuleObj mediaContext, Backtraces& traces) const;\n\n    Extension withExtender(const ComplexSelectorObj& newExtender) const;\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/file.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#ifdef _WIN32\n# ifdef __MINGW32__\n#  ifndef off64_t\n#   define off64_t _off64_t    /* Workaround for http://sourceforge.net/p/mingw/bugs/2024/ */\n#  endif\n# endif\n# include <direct.h>\n# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)\n#else\n# include <unistd.h>\n#endif\n#include <cstdio>\n#include <vector>\n#include <algorithm>\n#include <sys/stat.h>\n#include \"file.hpp\"\n#include \"context.hpp\"\n#include \"prelexer.hpp\"\n#include \"utf8_string.hpp\"\n#include \"sass_functions.hpp\"\n#include \"error_handling.hpp\"\n#include \"util.hpp\"\n#include \"util_string.hpp\"\n#include \"sass2scss.h\"\n\n#ifdef _WIN32\n# include <windows.h>\n\n# ifdef _MSC_VER\n# include <codecvt>\ninline static Sass::sass::string wstring_to_string(const std::wstring& wstr)\n{\n    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> wchar_converter;\n    return wchar_converter.to_bytes(wstr);\n}\n# else // mingw(/gcc) does not support C++11's codecvt yet.\ninline static Sass::sass::string wstring_to_string(const std::wstring &wstr)\n{\n    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);\n    Sass::sass::string strTo(size_needed, 0);\n    WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);\n    return strTo;\n}\n# endif\n#endif\n\nnamespace Sass {\n  namespace File {\n\n    // return the current directory\n    // always with forward slashes\n    // always with trailing slash\n    sass::string get_cwd()\n    {\n      const size_t wd_len = 4096;\n      #ifndef _WIN32\n        char wd[wd_len];\n        char* pwd = getcwd(wd, wd_len);\n        // we should check error for more detailed info (e.g. ENOENT)\n        // http://man7.org/linux/man-pages/man2/getcwd.2.html#ERRORS\n        if (pwd == NULL) throw Exception::OperationError(\"cwd gone missing\");\n        sass::string cwd = pwd;\n      #else\n        wchar_t wd[wd_len];\n        wchar_t* pwd = _wgetcwd(wd, wd_len);\n        if (pwd == NULL) throw Exception::OperationError(\"cwd gone missing\");\n        sass::string cwd = wstring_to_string(pwd);\n        //convert backslashes to forward slashes\n        replace(cwd.begin(), cwd.end(), '\\\\', '/');\n      #endif\n      if (cwd[cwd.length() - 1] != '/') cwd += '/';\n      return cwd;\n    }\n\n    // test if path exists and is a file\n    bool file_exists(const sass::string& path)\n    {\n      #ifdef _WIN32\n        wchar_t resolved[32768];\n        // windows unicode filepaths are encoded in utf16\n        sass::string abspath(join_paths(get_cwd(), path));\n        if (!(abspath[0] == '/' && abspath[1] == '/')) {\n          abspath = \"//?/\" + abspath;\n        }\n        std::wstring wpath(UTF_8::convert_to_utf16(abspath));\n        std::replace(wpath.begin(), wpath.end(), '/', '\\\\');\n        DWORD rv = GetFullPathNameW(wpath.c_str(), 32767, resolved, NULL);\n        if (rv > 32767) throw Exception::OperationError(\"Path is too long\");\n        if (rv == 0) throw Exception::OperationError(\"Path could not be resolved\");\n        DWORD dwAttrib = GetFileAttributesW(resolved);\n        return (dwAttrib != INVALID_FILE_ATTRIBUTES &&\n               (!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)));\n      #else\n        struct stat st_buf;\n        return (stat (path.c_str(), &st_buf) == 0) &&\n               (!S_ISDIR (st_buf.st_mode));\n      #endif\n    }\n\n    // return if given path is absolute\n    // works with *nix and windows paths\n    bool is_absolute_path(const sass::string& path)\n    {\n      #ifdef _WIN32\n        if (path.length() >= 2 && Util::ascii_isalpha(path[0]) && path[1] == ':') return true;\n      #endif\n      size_t i = 0;\n      // check if we have a protocol\n      if (path[i] && Util::ascii_isalpha(static_cast<unsigned char>(path[i]))) {\n        // skip over all alphanumeric characters\n        while (path[i] && Util::ascii_isalnum(static_cast<unsigned char>(path[i]))) ++i;\n        i = i && path[i] == ':' ? i + 1 : 0;\n      }\n      return path[i] == '/';\n    }\n\n    // helper function to find the last directory separator\n    inline size_t find_last_folder_separator(const sass::string& path, size_t limit = sass::string::npos)\n    {\n      size_t pos;\n      size_t pos_p = path.find_last_of('/', limit);\n      #ifdef _WIN32\n        size_t pos_w = path.find_last_of('\\\\', limit);\n      #else\n        size_t pos_w = sass::string::npos;\n      #endif\n      if (pos_p != sass::string::npos && pos_w != sass::string::npos) {\n        pos = std::max(pos_p, pos_w);\n      }\n      else if (pos_p != sass::string::npos) {\n        pos = pos_p;\n      }\n      else {\n        pos = pos_w;\n      }\n      return pos;\n    }\n\n    // return only the directory part of path\n    sass::string dir_name(const sass::string& path)\n    {\n      size_t pos = find_last_folder_separator(path);\n      if (pos == sass::string::npos) return \"\";\n      else return path.substr(0, pos+1);\n    }\n\n    // return only the filename part of path\n    sass::string base_name(const sass::string& path)\n    {\n      size_t pos = find_last_folder_separator(path);\n      if (pos == sass::string::npos) return path;\n      else return path.substr(pos+1);\n    }\n\n    // do a logical clean up of the path\n    // no physical check on the filesystem\n    sass::string make_canonical_path (sass::string path)\n    {\n\n      // declarations\n      size_t pos;\n\n      #ifdef _WIN32\n        //convert backslashes to forward slashes\n        replace(path.begin(), path.end(), '\\\\', '/');\n      #endif\n\n      pos = 0; // remove all self references inside the path string\n      while((pos = path.find(\"/./\", pos)) != sass::string::npos) path.erase(pos, 2);\n\n      // remove all leading and trailing self references\n      while(path.size() >= 2 && path[0] == '.' && path[1] == '/') path.erase(0, 2);\n      while((pos = path.length()) > 1 && path[pos - 2] == '/' && path[pos - 1] == '.') path.erase(pos - 2);\n\n\n      size_t proto = 0;\n      // check if we have a protocol\n      if (path[proto] && Util::ascii_isalpha(static_cast<unsigned char>(path[proto]))) {\n        // skip over all alphanumeric characters\n        while (path[proto] && Util::ascii_isalnum(static_cast<unsigned char>(path[proto++]))) {}\n        // then skip over the mandatory colon\n        if (proto && path[proto] == ':') ++ proto;\n      }\n\n      // then skip over start slashes\n      while (path[proto++] == '/') {}\n\n      pos = proto; // collapse multiple delimiters into a single one\n      while((pos = path.find(\"//\", pos)) != sass::string::npos) path.erase(pos, 1);\n\n      return path;\n\n    }\n\n    // join two path segments cleanly together\n    // but only if right side is not absolute yet\n    sass::string join_paths(sass::string l, sass::string r)\n    {\n\n      #ifdef _WIN32\n        // convert Windows backslashes to URL forward slashes\n        replace(l.begin(), l.end(), '\\\\', '/');\n        replace(r.begin(), r.end(), '\\\\', '/');\n      #endif\n\n      if (l.empty()) return r;\n      if (r.empty()) return l;\n\n      if (is_absolute_path(r)) return r;\n      if (l[l.length()-1] != '/') l += '/';\n\n      // this does a logical cleanup of the right hand path\n      // Note that this does collapse x/../y sections into y.\n      // This is by design. If /foo on your system is a symlink\n      // to /bar/baz, then /foo/../cd is actually /bar/cd,\n      // not /cd as a naive ../ removal would give you.\n      // will only work on leading double dot dirs on rhs\n      // therefore it is safe if lhs is already resolved cwd\n      while ((r.length() > 3) && ((r.substr(0, 3) == \"../\") || (r.substr(0, 3)) == \"..\\\\\")) {\n        size_t L = l.length(), pos = find_last_folder_separator(l, L - 2);\n        bool is_slash = pos + 2 == L && (l[pos+1] == '/' || l[pos+1] == '\\\\');\n        bool is_self = pos + 3 == L && (l[pos+1] == '.');\n        if (!is_self && !is_slash) r = r.substr(3);\n        else if (pos == sass::string::npos) break;\n        l = l.substr(0, pos == sass::string::npos ? pos : pos + 1);\n      }\n\n      return l + r;\n    }\n\n    sass::string path_for_console(const sass::string& rel_path, const sass::string& abs_path, const sass::string& orig_path)\n    {\n      // magic algorithm goes here!!\n\n      // if the file is outside this directory show the absolute path\n      if (rel_path.substr(0, 3) == \"../\") {\n        return orig_path;\n      }\n      // this seems to work most of the time\n      return abs_path == orig_path ? abs_path : rel_path;\n    }\n\n    // create an absolute path by resolving relative paths with cwd\n    sass::string rel2abs(const sass::string& path, const sass::string& base, const sass::string& cwd)\n    {\n      sass::string rv = make_canonical_path(join_paths(join_paths(cwd + \"/\", base + \"/\"), path));\n      #ifdef _WIN32\n      // On windows we may get an absolute path without directory\n      // In that case we should prepend the directory from the root\n      if (rv[0] == '/' && rv[1] != '/') {\n        rv.insert(0, cwd, 0, 2);\n      }\n      #endif\n      return rv;\n    }\n\n    // create a path that is relative to the given base directory\n    // path and base will first be resolved against cwd to make them absolute\n    sass::string abs2rel(const sass::string& path, const sass::string& base, const sass::string& cwd)\n    {\n\n      sass::string abs_path = rel2abs(path, cwd);\n      sass::string abs_base = rel2abs(base, cwd);\n\n      size_t proto = 0;\n      // check if we have a protocol\n      if (path[proto] && Util::ascii_isalpha(static_cast<unsigned char>(path[proto]))) {\n        // skip over all alphanumeric characters\n        while (path[proto] && Util::ascii_isalnum(static_cast<unsigned char>(path[proto++]))) {}\n        // then skip over the mandatory colon\n        if (proto && path[proto] == ':') ++ proto;\n      }\n\n      // distinguish between windows absolute paths and valid protocols\n      // we assume that protocols must at least have two chars to be valid\n      if (proto && path[proto++] == '/' && proto > 3) return path;\n\n      #ifdef _WIN32\n        // absolute link must have a drive letter, and we know that we\n        // can only create relative links if both are on the same drive\n        if (abs_base[0] != abs_path[0]) return abs_path;\n      #endif\n\n      sass::string stripped_uri = \"\";\n      sass::string stripped_base = \"\";\n\n      size_t index = 0;\n      size_t minSize = std::min(abs_path.size(), abs_base.size());\n      for (size_t i = 0; i < minSize; ++i) {\n        #ifdef FS_CASE_SENSITIVE\n          if (abs_path[i] != abs_base[i]) break;\n        #else\n          // compare the charactes in a case insensitive manner\n          // windows fs is only case insensitive in ascii ranges\n          if (Util::ascii_tolower(static_cast<unsigned char>(abs_path[i])) !=\n              Util::ascii_tolower(static_cast<unsigned char>(abs_base[i]))) break;\n        #endif\n        if (abs_path[i] == '/') index = i + 1;\n      }\n      for (size_t i = index; i < abs_path.size(); ++i) {\n        stripped_uri += abs_path[i];\n      }\n      for (size_t i = index; i < abs_base.size(); ++i) {\n        stripped_base += abs_base[i];\n      }\n\n      size_t left = 0;\n      size_t directories = 0;\n      for (size_t right = 0; right < stripped_base.size(); ++right) {\n        if (stripped_base[right] == '/') {\n          if (stripped_base.substr(left, 2) != \"..\") {\n            ++directories;\n          }\n          else if (directories > 1) {\n            --directories;\n          }\n          else {\n            directories = 0;\n          }\n          left = right + 1;\n        }\n      }\n\n      sass::string result = \"\";\n      for (size_t i = 0; i < directories; ++i) {\n        result += \"../\";\n      }\n      result += stripped_uri;\n\n      return result;\n    }\n\n    // Resolution order for ambiguous imports:\n    // (1) filename as given\n    // (2) underscore + given\n    // (3) underscore + given + extension\n    // (4) given + extension\n    // (5) given + _index.scss\n    // (6) given + _index.sass\n    sass::vector<Include> resolve_includes(const sass::string& root, const sass::string& file, const sass::vector<sass::string>& exts)\n    {\n      sass::string filename = join_paths(root, file);\n      // split the filename\n      sass::string base(dir_name(file));\n      sass::string name(base_name(file));\n      sass::vector<Include> includes;\n      // create full path (maybe relative)\n      sass::string rel_path(join_paths(base, name));\n      sass::string abs_path(join_paths(root, rel_path));\n      if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });\n      // next test variation with underscore\n      rel_path = join_paths(base, \"_\" + name);\n      abs_path = join_paths(root, rel_path);\n      if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });\n      // next test exts plus underscore\n      for(auto ext : exts) {\n        rel_path = join_paths(base, \"_\" + name + ext);\n        abs_path = join_paths(root, rel_path);\n        if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });\n      }\n      // next test plain name with exts\n      for(auto ext : exts) {\n        rel_path = join_paths(base, name + ext);\n        abs_path = join_paths(root, rel_path);\n        if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });\n      }\n      // index files\n      if (includes.size() == 0) {\n        // ignore directories that look like @import'able filename\n        for(auto ext : exts) {\n          if (ends_with(name, ext)) return includes;\n        }\n        // next test underscore index exts\n        for(auto ext : exts) {\n          rel_path = join_paths(base, join_paths(name, \"_index\" + ext));\n          abs_path = join_paths(root, rel_path);\n          if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });\n        }\n        // next test plain index exts\n        for(auto ext : exts) {\n          rel_path = join_paths(base, join_paths(name, \"index\" + ext));\n          abs_path = join_paths(root, rel_path);\n          if (file_exists(abs_path)) includes.push_back({{ rel_path, root }, abs_path });\n        }\n      }\n      // nothing found\n      return includes;\n    }\n\n    sass::vector<sass::string> find_files(const sass::string& file, const sass::vector<sass::string> paths)\n    {\n      sass::vector<sass::string> includes;\n      for (sass::string path : paths) {\n        sass::string abs_path(join_paths(path, file));\n        if (file_exists(abs_path)) includes.push_back(abs_path);\n      }\n      return includes;\n    }\n\n    sass::vector<sass::string> find_files(const sass::string& file, struct Sass_Compiler* compiler)\n    {\n      // get the last import entry to get current base directory\n      // struct Sass_Options* options = sass_compiler_get_options(compiler);\n      Sass_Import_Entry import = sass_compiler_get_last_import(compiler);\n      const sass::vector<sass::string>& incs = compiler->cpp_ctx->include_paths;\n      // create the vector with paths to lookup\n      sass::vector<sass::string> paths(1 + incs.size());\n      paths.push_back(dir_name(import->abs_path));\n      paths.insert(paths.end(), incs.begin(), incs.end());\n      // dispatch to find files in paths\n      return find_files(file, paths);\n    }\n\n    // helper function to search one file in all include paths\n    // this is normally not used internally by libsass (C-API sugar)\n    sass::string find_file(const sass::string& file, const sass::vector<sass::string> paths)\n    {\n      if (file.empty()) return file;\n      auto res = find_files(file, paths);\n      return res.empty() ? \"\" : res.front();\n    }\n\n    // helper function to resolve a filename\n    sass::string find_include(const sass::string& file, const sass::vector<sass::string> paths)\n    {\n      // search in every include path for a match\n      for (size_t i = 0, S = paths.size(); i < S; ++i)\n      {\n        sass::vector<Include> resolved(resolve_includes(paths[i], file));\n        if (resolved.size()) return resolved[0].abs_path;\n      }\n      // nothing found\n      return sass::string(\"\");\n    }\n\n    // try to load the given filename\n    // returned memory must be freed\n    // will auto convert .sass files\n    char* read_file(const sass::string& path)\n    {\n      #ifdef _WIN32\n        BYTE* pBuffer;\n        DWORD dwBytes;\n        wchar_t resolved[32768];\n        // windows unicode filepaths are encoded in utf16\n        sass::string abspath(join_paths(get_cwd(), path));\n        if (!(abspath[0] == '/' && abspath[1] == '/')) {\n          abspath = \"//?/\" + abspath;\n        }\n        std::wstring wpath(UTF_8::convert_to_utf16(abspath));\n        std::replace(wpath.begin(), wpath.end(), '/', '\\\\');\n        DWORD rv = GetFullPathNameW(wpath.c_str(), 32767, resolved, NULL);\n        if (rv > 32767) throw Exception::OperationError(\"Path is too long\");\n        if (rv == 0) throw Exception::OperationError(\"Path could not be resolved\");\n        HANDLE hFile = CreateFileW(resolved, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);\n        if (hFile == INVALID_HANDLE_VALUE) return 0;\n        DWORD dwFileLength = GetFileSize(hFile, NULL);\n        if (dwFileLength == INVALID_FILE_SIZE) return 0;\n        // allocate an extra byte for the null char\n        // and another one for edge-cases in lexer\n        pBuffer = (BYTE*)malloc((dwFileLength+2)*sizeof(BYTE));\n        ReadFile(hFile, pBuffer, dwFileLength, &dwBytes, NULL);\n        pBuffer[dwFileLength+0] = '\\0';\n        pBuffer[dwFileLength+1] = '\\0';\n        CloseHandle(hFile);\n        // just convert from unsigned char*\n        char* contents = (char*) pBuffer;\n      #else\n        // Read the file using `<cstdio>` instead of `<fstream>` for better portability.\n        // The `<fstream>` header initializes `<locale>` and this buggy in GCC4/5 with static linking.\n        // See:\n        // https://www.spinics.net/lists/gcchelp/msg46851.html\n        // https://github.com/sass/sassc-ruby/issues/128\n        struct stat st;\n        if (stat(path.c_str(), &st) == -1 || S_ISDIR(st.st_mode)) return 0;\n        FILE* fd = std::fopen(path.c_str(), \"rb\");\n        if (fd == nullptr) return nullptr;\n        const std::size_t size = st.st_size;\n        char* contents = static_cast<char*>(malloc(st.st_size + 2 * sizeof(char)));\n        if (std::fread(static_cast<void*>(contents), 1, size, fd) != size) {\n          free(contents);\n          std::fclose(fd);\n          return nullptr;\n        }\n        if (std::fclose(fd) != 0) {\n          free(contents);\n          return nullptr;\n        }\n        contents[size] = '\\0';\n        contents[size + 1] = '\\0';\n      #endif\n      sass::string extension;\n      if (path.length() > 5) {\n        extension = path.substr(path.length() - 5, 5);\n      }\n      Util::ascii_str_tolower(&extension);\n      if (extension == \".sass\" && contents != 0) {\n        char * converted = sass2scss(contents, SASS2SCSS_PRETTIFY_1 | SASS2SCSS_KEEP_COMMENT);\n        free(contents); // free the indented contents\n        return converted; // should be freed by caller\n      } else {\n        return contents;\n      }\n    }\n\n    // split a path string delimited by semicolons or colons (OS dependent)\n    sass::vector<sass::string> split_path_list(const char* str)\n    {\n      sass::vector<sass::string> paths;\n      if (str == NULL) return paths;\n      // find delimiter via prelexer (return zero at end)\n      const char* end = Prelexer::find_first<PATH_SEP>(str);\n      // search until null delimiter\n      while (end) {\n        // add path from current position to delimiter\n        paths.push_back(sass::string(str, end - str));\n        str = end + 1; // skip delimiter\n        end = Prelexer::find_first<PATH_SEP>(str);\n      }\n      // add path from current position to end\n      paths.push_back(sass::string(str));\n      // return back\n      return paths;\n    }\n\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/file.hpp",
    "content": "#ifndef SASS_FILE_H\n#define SASS_FILE_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <string>\n#include <vector>\n\n#include \"sass/context.h\"\n#include \"ast_fwd_decl.hpp\"\n\nnamespace Sass {\n\n  namespace File {\n\n    // return the current directory\n    // always with forward slashes\n    sass::string get_cwd();\n\n    // test if path exists and is a file\n    bool file_exists(const sass::string& file);\n\n    // return if given path is absolute\n    // works with *nix and windows paths\n    bool is_absolute_path(const sass::string& path);\n\n    // return only the directory part of path\n    sass::string dir_name(const sass::string& path);\n\n    // return only the filename part of path\n    sass::string base_name(const sass::string&);\n\n    // do a locigal clean up of the path\n    // no physical check on the filesystem\n    sass::string make_canonical_path (sass::string path);\n\n    // join two path segments cleanly together\n    // but only if right side is not absolute yet\n    sass::string join_paths(sass::string root, sass::string name);\n\n    // if the relative path is outside of the cwd we want want to\n    // show the absolute path in console messages\n    sass::string path_for_console(const sass::string& rel_path, const sass::string& abs_path, const sass::string& orig_path);\n\n    // create an absolute path by resolving relative paths with cwd\n    sass::string rel2abs(const sass::string& path, const sass::string& base = \".\", const sass::string& cwd = get_cwd());\n\n    // create a path that is relative to the given base directory\n    // path and base will first be resolved against cwd to make them absolute\n    sass::string abs2rel(const sass::string& path, const sass::string& base = \".\", const sass::string& cwd = get_cwd());\n\n    // helper function to resolve a filename\n    // searching without variations in all paths\n    sass::string find_file(const sass::string& file, struct Sass_Compiler* options);\n    sass::string find_file(const sass::string& file, const sass::vector<sass::string> paths);\n\n    // helper function to resolve a include filename\n    // this has the original resolve logic for sass include\n    sass::string find_include(const sass::string& file, const sass::vector<sass::string> paths);\n\n    // split a path string delimited by semicolons or colons (OS dependent)\n    sass::vector<sass::string> split_path_list(const char* paths);\n\n    // try to load the given filename\n    // returned memory must be freed\n    // will auto convert .sass files\n    char* read_file(const sass::string& file);\n\n  }\n\n  // requested import\n  class Importer {\n    public:\n      // requested import path\n      sass::string imp_path;\n      // parent context path\n      sass::string ctx_path;\n      // base derived from context path\n      // this really just acts as a cache\n      sass::string base_path;\n    public:\n      Importer(sass::string imp_path, sass::string ctx_path)\n      : imp_path(File::make_canonical_path(imp_path)),\n        ctx_path(File::make_canonical_path(ctx_path)),\n        base_path(File::dir_name(ctx_path))\n      { }\n  };\n\n  // a resolved include (final import)\n  class Include : public Importer {\n    public:\n      // resolved absolute path\n      sass::string abs_path;\n    public:\n      Include(const Importer& imp, sass::string abs_path)\n      : Importer(imp), abs_path(abs_path)\n      { }\n  };\n\n  // a loaded resource\n  class Resource {\n    public:\n      // the file contents\n      char* contents;\n      // connected sourcemap\n      char* srcmap;\n    public:\n      Resource(char* contents, char* srcmap)\n      : contents(contents), srcmap(srcmap)\n      { }\n  };\n\n  namespace File {\n\n    sass::vector<Include> resolve_includes(const sass::string& root, const sass::string& file,\n      const sass::vector<sass::string>& exts = { \".scss\", \".sass\", \".css\" });\n\n  }\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_colors.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <iomanip>\n#include \"ast.hpp\"\n#include \"fn_utils.hpp\"\n#include \"fn_colors.hpp\"\n#include \"util.hpp\"\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    bool string_argument(AST_Node_Obj obj) {\n      String_Constant* s = Cast<String_Constant>(obj);\n      if (s == nullptr) return false;\n      const sass::string& str = s->value();\n      return starts_with(str, \"calc(\") ||\n             starts_with(str, \"var(\");\n    }\n\n    void hsla_alpha_percent_deprecation(const SourceSpan& pstate, const sass::string val)\n    {\n\n      sass::string msg(\"Passing a percentage as the alpha value to hsla() will be interpreted\");\n      sass::string tail(\"differently in future versions of Sass. For now, use \" + val + \" instead.\");\n\n      deprecated(msg, tail, false, pstate);\n\n    }\n\n    Signature rgb_sig = \"rgb($red, $green, $blue)\";\n    BUILT_IN(rgb)\n    {\n      if (\n        string_argument(env[\"$red\"]) ||\n        string_argument(env[\"$green\"]) ||\n        string_argument(env[\"$blue\"])\n      ) {\n        return SASS_MEMORY_NEW(String_Constant, pstate, \"rgb(\"\n                                                        + env[\"$red\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$green\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$blue\"]->to_string()\n                                                        + \")\"\n        );\n      }\n\n      return SASS_MEMORY_NEW(Color_RGBA,\n                             pstate,\n                             COLOR_NUM(\"$red\"),\n                             COLOR_NUM(\"$green\"),\n                             COLOR_NUM(\"$blue\"));\n    }\n\n    Signature rgba_4_sig = \"rgba($red, $green, $blue, $alpha)\";\n    BUILT_IN(rgba_4)\n    {\n      if (\n        string_argument(env[\"$red\"]) ||\n        string_argument(env[\"$green\"]) ||\n        string_argument(env[\"$blue\"]) ||\n        string_argument(env[\"$alpha\"])\n      ) {\n        return SASS_MEMORY_NEW(String_Constant, pstate, \"rgba(\"\n                                                        + env[\"$red\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$green\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$blue\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$alpha\"]->to_string()\n                                                        + \")\"\n        );\n      }\n\n      return SASS_MEMORY_NEW(Color_RGBA,\n                             pstate,\n                             COLOR_NUM(\"$red\"),\n                             COLOR_NUM(\"$green\"),\n                             COLOR_NUM(\"$blue\"),\n                             ALPHA_NUM(\"$alpha\"));\n    }\n\n    Signature rgba_2_sig = \"rgba($color, $alpha)\";\n    BUILT_IN(rgba_2)\n    {\n      if (\n        string_argument(env[\"$color\"])\n      ) {\n        return SASS_MEMORY_NEW(String_Constant, pstate, \"rgba(\"\n                                                        + env[\"$color\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$alpha\"]->to_string()\n                                                        + \")\"\n        );\n      }\n\n      Color_RGBA_Obj c_arg = ARG(\"$color\", Color)->toRGBA();\n\n      if (\n        string_argument(env[\"$alpha\"])\n      ) {\n        sass::ostream strm;\n        strm << \"rgba(\"\n                 << (int)c_arg->r() << \", \"\n                 << (int)c_arg->g() << \", \"\n                 << (int)c_arg->b() << \", \"\n                 << env[\"$alpha\"]->to_string()\n             << \")\";\n        return SASS_MEMORY_NEW(String_Constant, pstate, strm.str());\n      }\n\n      Color_RGBA_Obj new_c = SASS_MEMORY_COPY(c_arg);\n      new_c->a(ALPHA_NUM(\"$alpha\"));\n      new_c->disp(\"\");\n      return new_c.detach();\n    }\n\n    ////////////////\n    // RGB FUNCTIONS\n    ////////////////\n\n    Signature red_sig = \"red($color)\";\n    BUILT_IN(red)\n    {\n      Color_RGBA_Obj color = ARG(\"$color\", Color)->toRGBA();\n      return SASS_MEMORY_NEW(Number, pstate, color->r());\n    }\n\n    Signature green_sig = \"green($color)\";\n    BUILT_IN(green)\n    {\n      Color_RGBA_Obj color = ARG(\"$color\", Color)->toRGBA();\n      return SASS_MEMORY_NEW(Number, pstate, color->g());\n    }\n\n    Signature blue_sig = \"blue($color)\";\n    BUILT_IN(blue)\n    {\n      Color_RGBA_Obj color = ARG(\"$color\", Color)->toRGBA();\n      return SASS_MEMORY_NEW(Number, pstate, color->b());\n    }\n\n    Color_RGBA* colormix(Context& ctx, SourceSpan& pstate, Color* color1, Color* color2, double weight) {\n      Color_RGBA_Obj c1 = color1->toRGBA();\n      Color_RGBA_Obj c2 = color2->toRGBA();\n      double p = weight/100;\n      double w = 2*p - 1;\n      double a = c1->a() - c2->a();\n\n      double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0;\n      double w2 = 1 - w1;\n\n      return SASS_MEMORY_NEW(Color_RGBA,\n                             pstate,\n                             Sass::round(w1*c1->r() + w2*c2->r(), ctx.c_options.precision),\n                             Sass::round(w1*c1->g() + w2*c2->g(), ctx.c_options.precision),\n                             Sass::round(w1*c1->b() + w2*c2->b(), ctx.c_options.precision),\n                             c1->a()*p + c2->a()*(1-p));\n    }\n\n    Signature mix_sig = \"mix($color1, $color2, $weight: 50%)\";\n    BUILT_IN(mix)\n    {\n      Color_Obj  color1 = ARG(\"$color1\", Color);\n      Color_Obj  color2 = ARG(\"$color2\", Color);\n      double weight = DARG_U_PRCT(\"$weight\");\n      return colormix(ctx, pstate, color1, color2, weight);\n\n    }\n\n    ////////////////\n    // HSL FUNCTIONS\n    ////////////////\n\n    Signature hsl_sig = \"hsl($hue, $saturation, $lightness)\";\n    BUILT_IN(hsl)\n    {\n      if (\n        string_argument(env[\"$hue\"]) ||\n        string_argument(env[\"$saturation\"]) ||\n        string_argument(env[\"$lightness\"])\n      ) {\n        return SASS_MEMORY_NEW(String_Constant, pstate, \"hsl(\"\n                                                        + env[\"$hue\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$saturation\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$lightness\"]->to_string()\n                                                        + \")\"\n        );\n      }\n\n      return SASS_MEMORY_NEW(Color_HSLA,\n        pstate,\n        ARGVAL(\"$hue\"),\n        ARGVAL(\"$saturation\"),\n        ARGVAL(\"$lightness\"),\n        1.0);\n\n    }\n\n    Signature hsla_sig = \"hsla($hue, $saturation, $lightness, $alpha)\";\n    BUILT_IN(hsla)\n    {\n      if (\n        string_argument(env[\"$hue\"]) ||\n        string_argument(env[\"$saturation\"]) ||\n        string_argument(env[\"$lightness\"]) ||\n        string_argument(env[\"$alpha\"])\n      ) {\n        return SASS_MEMORY_NEW(String_Constant, pstate, \"hsla(\"\n                                                        + env[\"$hue\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$saturation\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$lightness\"]->to_string()\n                                                        + \", \"\n                                                        + env[\"$alpha\"]->to_string()\n                                                        + \")\"\n        );\n      }\n\n      Number* alpha = ARG(\"$alpha\", Number);\n      if (alpha && alpha->unit() == \"%\") {\n        Number_Obj val = SASS_MEMORY_COPY(alpha);\n        val->numerators.clear(); // convert\n        val->value(val->value() / 100.0);\n        sass::string nr(val->to_string(ctx.c_options));\n        hsla_alpha_percent_deprecation(pstate, nr);\n      }\n\n      return SASS_MEMORY_NEW(Color_HSLA,\n        pstate,\n        ARGVAL(\"$hue\"),\n        ARGVAL(\"$saturation\"),\n        ARGVAL(\"$lightness\"),\n        ARGVAL(\"$alpha\"));\n\n    }\n\n    /////////////////////////////////////////////////////////////////////////\n    // Query functions\n    /////////////////////////////////////////////////////////////////////////\n\n    Signature hue_sig = \"hue($color)\";\n    BUILT_IN(hue)\n    {\n      Color_HSLA_Obj col = ARG(\"$color\", Color)->toHSLA();\n      return SASS_MEMORY_NEW(Number, pstate, col->h(), \"deg\");\n    }\n\n    Signature saturation_sig = \"saturation($color)\";\n    BUILT_IN(saturation)\n    {\n      Color_HSLA_Obj col = ARG(\"$color\", Color)->toHSLA();\n      return SASS_MEMORY_NEW(Number, pstate, col->s(), \"%\");\n    }\n\n    Signature lightness_sig = \"lightness($color)\";\n    BUILT_IN(lightness)\n    {\n      Color_HSLA_Obj col = ARG(\"$color\", Color)->toHSLA();\n      return SASS_MEMORY_NEW(Number, pstate, col->l(), \"%\");\n    }\n\n    /////////////////////////////////////////////////////////////////////////\n    // HSL manipulation functions\n    /////////////////////////////////////////////////////////////////////////\n\n    Signature adjust_hue_sig = \"adjust-hue($color, $degrees)\";\n    BUILT_IN(adjust_hue)\n    {\n      Color* col = ARG(\"$color\", Color);\n      double degrees = ARGVAL(\"$degrees\");\n      Color_HSLA_Obj copy = col->copyAsHSLA();\n      copy->h(absmod(copy->h() + degrees, 360.0));\n      return copy.detach();\n    }\n\n    Signature lighten_sig = \"lighten($color, $amount)\";\n    BUILT_IN(lighten)\n    {\n      Color* col = ARG(\"$color\", Color);\n      double amount = DARG_U_PRCT(\"$amount\");\n      Color_HSLA_Obj copy = col->copyAsHSLA();\n      copy->l(clip(copy->l() + amount, 0.0, 100.0));\n      return copy.detach();\n\n    }\n\n    Signature darken_sig = \"darken($color, $amount)\";\n    BUILT_IN(darken)\n    {\n      Color* col = ARG(\"$color\", Color);\n      double amount = DARG_U_PRCT(\"$amount\");\n      Color_HSLA_Obj copy = col->copyAsHSLA();\n      copy->l(clip(copy->l() - amount, 0.0, 100.0));\n      return copy.detach();\n    }\n\n    Signature saturate_sig = \"saturate($color, $amount: false)\";\n    BUILT_IN(saturate)\n    {\n      // CSS3 filter function overload: pass literal through directly\n      if (!Cast<Number>(env[\"$amount\"])) {\n        return SASS_MEMORY_NEW(String_Quoted, pstate, \"saturate(\" + env[\"$color\"]->to_string(ctx.c_options) + \")\");\n      }\n\n      Color* col = ARG(\"$color\", Color);\n      double amount = DARG_U_PRCT(\"$amount\");\n      Color_HSLA_Obj copy = col->copyAsHSLA();\n      copy->s(clip(copy->s() + amount, 0.0, 100.0));\n      return copy.detach();\n    }\n\n    Signature desaturate_sig = \"desaturate($color, $amount)\";\n    BUILT_IN(desaturate)\n    {\n      Color* col = ARG(\"$color\", Color);\n      double amount = DARG_U_PRCT(\"$amount\");\n      Color_HSLA_Obj copy = col->copyAsHSLA();\n      copy->s(clip(copy->s() - amount, 0.0, 100.0));\n      return copy.detach();\n    }\n\n    Signature grayscale_sig = \"grayscale($color)\";\n    BUILT_IN(grayscale)\n    {\n      // CSS3 filter function overload: pass literal through directly\n      Number* amount = Cast<Number>(env[\"$color\"]);\n      if (amount) {\n        return SASS_MEMORY_NEW(String_Quoted, pstate, \"grayscale(\" + amount->to_string(ctx.c_options) + \")\");\n      }\n\n      Color* col = ARG(\"$color\", Color);\n      Color_HSLA_Obj copy = col->copyAsHSLA();\n      copy->s(0.0); // just reset saturation\n      return copy.detach();\n    }\n\n    /////////////////////////////////////////////////////////////////////////\n    // Misc manipulation functions\n    /////////////////////////////////////////////////////////////////////////\n\n    Signature complement_sig = \"complement($color)\";\n    BUILT_IN(complement)\n    {\n      Color* col = ARG(\"$color\", Color);\n      Color_HSLA_Obj copy = col->copyAsHSLA();\n      copy->h(absmod(copy->h() - 180.0, 360.0));\n      return copy.detach();\n    }\n\n    Signature invert_sig = \"invert($color, $weight: 100%)\";\n    BUILT_IN(invert)\n    {\n      // CSS3 filter function overload: pass literal through directly\n      Number* amount = Cast<Number>(env[\"$color\"]);\n      double weight = DARG_U_PRCT(\"$weight\");\n      if (amount) {\n        // TODO: does not throw on 100% manually passed as value\n        if (weight < 100.0) {\n          error(\"Only one argument may be passed to the plain-CSS invert() function.\", pstate, traces);\n        }\n        return SASS_MEMORY_NEW(String_Quoted, pstate, \"invert(\" + amount->to_string(ctx.c_options) + \")\");\n      }\n\n      Color* col = ARG(\"$color\", Color);\n      Color_RGBA_Obj inv = col->copyAsRGBA();\n      inv->r(clip(255.0 - inv->r(), 0.0, 255.0));\n      inv->g(clip(255.0 - inv->g(), 0.0, 255.0));\n      inv->b(clip(255.0 - inv->b(), 0.0, 255.0));\n      return colormix(ctx, pstate, inv, col, weight);\n    }\n\n    /////////////////////////////////////////////////////////////////////////\n    // Opacity functions\n    /////////////////////////////////////////////////////////////////////////\n\n    Signature alpha_sig = \"alpha($color)\";\n    Signature opacity_sig = \"opacity($color)\";\n    BUILT_IN(alpha)\n    {\n      String_Constant* ie_kwd = Cast<String_Constant>(env[\"$color\"]);\n      if (ie_kwd) {\n        return SASS_MEMORY_NEW(String_Quoted, pstate, \"alpha(\" + ie_kwd->value() + \")\");\n      }\n\n      // CSS3 filter function overload: pass literal through directly\n      Number* amount = Cast<Number>(env[\"$color\"]);\n      if (amount) {\n        return SASS_MEMORY_NEW(String_Quoted, pstate, \"opacity(\" + amount->to_string(ctx.c_options) + \")\");\n      }\n\n      return SASS_MEMORY_NEW(Number, pstate, ARG(\"$color\", Color)->a());\n    }\n\n    Signature opacify_sig = \"opacify($color, $amount)\";\n    Signature fade_in_sig = \"fade-in($color, $amount)\";\n    BUILT_IN(opacify)\n    {\n      Color* col = ARG(\"$color\", Color);\n      double amount = DARG_U_FACT(\"$amount\");\n      Color_Obj copy = SASS_MEMORY_COPY(col);\n      copy->a(clip(col->a() + amount, 0.0, 1.0));\n      return copy.detach();\n    }\n\n    Signature transparentize_sig = \"transparentize($color, $amount)\";\n    Signature fade_out_sig = \"fade-out($color, $amount)\";\n    BUILT_IN(transparentize)\n    {\n      Color* col = ARG(\"$color\", Color);\n      double amount = DARG_U_FACT(\"$amount\");\n      Color_Obj copy = SASS_MEMORY_COPY(col);\n      copy->a(std::max(col->a() - amount, 0.0));\n      return copy.detach();\n    }\n\n    ////////////////////////\n    // OTHER COLOR FUNCTIONS\n    ////////////////////////\n\n    Signature adjust_color_sig = \"adjust-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)\";\n    BUILT_IN(adjust_color)\n    {\n      Color* col = ARG(\"$color\", Color);\n      Number* r = Cast<Number>(env[\"$red\"]);\n      Number* g = Cast<Number>(env[\"$green\"]);\n      Number* b = Cast<Number>(env[\"$blue\"]);\n      Number* h = Cast<Number>(env[\"$hue\"]);\n      Number* s = Cast<Number>(env[\"$saturation\"]);\n      Number* l = Cast<Number>(env[\"$lightness\"]);\n      Number* a = Cast<Number>(env[\"$alpha\"]);\n\n      bool rgb = r || g || b;\n      bool hsl = h || s || l;\n\n      if (rgb && hsl) {\n        error(\"Cannot specify HSL and RGB values for a color at the same time for `adjust-color'\", pstate, traces);\n      }\n      else if (rgb) {\n        Color_RGBA_Obj c = col->copyAsRGBA();\n        if (r) c->r(c->r() + DARG_R_BYTE(\"$red\"));\n        if (g) c->g(c->g() + DARG_R_BYTE(\"$green\"));\n        if (b) c->b(c->b() + DARG_R_BYTE(\"$blue\"));\n        if (a) c->a(c->a() + DARG_R_FACT(\"$alpha\"));\n        return c.detach();\n      }\n      else if (hsl) {\n        Color_HSLA_Obj c = col->copyAsHSLA();\n        if (h) c->h(c->h() + absmod(h->value(), 360.0));\n        if (s) c->s(c->s() + DARG_R_PRCT(\"$saturation\"));\n        if (l) c->l(c->l() + DARG_R_PRCT(\"$lightness\"));\n        if (a) c->a(c->a() + DARG_R_FACT(\"$alpha\"));\n        return c.detach();\n      }\n      else if (a) {\n        Color_Obj c = SASS_MEMORY_COPY(col);\n        c->a(c->a() + DARG_R_FACT(\"$alpha\"));\n        c->a(clip(c->a(), 0.0, 1.0));\n        return c.detach();\n      }\n      error(\"not enough arguments for `adjust-color'\", pstate, traces);\n      // unreachable\n      return col;\n    }\n\n    Signature scale_color_sig = \"scale-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)\";\n    BUILT_IN(scale_color)\n    {\n      Color* col = ARG(\"$color\", Color);\n      Number* r = Cast<Number>(env[\"$red\"]);\n      Number* g = Cast<Number>(env[\"$green\"]);\n      Number* b = Cast<Number>(env[\"$blue\"]);\n      Number* h = Cast<Number>(env[\"$hue\"]);\n      Number* s = Cast<Number>(env[\"$saturation\"]);\n      Number* l = Cast<Number>(env[\"$lightness\"]);\n      Number* a = Cast<Number>(env[\"$alpha\"]);\n\n      bool rgb = r || g || b;\n      bool hsl = h || s || l;\n\n      if (rgb && hsl) {\n        error(\"Cannot specify HSL and RGB values for a color at the same time for `scale-color'\", pstate, traces);\n      }\n      else if (rgb) {\n        Color_RGBA_Obj c = col->copyAsRGBA();\n        double rscale = (r ? DARG_R_PRCT(\"$red\") : 0.0) / 100.0;\n        double gscale = (g ? DARG_R_PRCT(\"$green\") : 0.0) / 100.0;\n        double bscale = (b ? DARG_R_PRCT(\"$blue\") : 0.0) / 100.0;\n        double ascale = (a ? DARG_R_PRCT(\"$alpha\") : 0.0) / 100.0;\n        if (rscale) c->r(c->r() + rscale * (rscale > 0.0 ? 255.0 - c->r() : c->r()));\n        if (gscale) c->g(c->g() + gscale * (gscale > 0.0 ? 255.0 - c->g() : c->g()));\n        if (bscale) c->b(c->b() + bscale * (bscale > 0.0 ? 255.0 - c->b() : c->b()));\n        if (ascale) c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));\n        return c.detach();\n      }\n      else if (hsl) {\n        Color_HSLA_Obj c = col->copyAsHSLA();\n        double hscale = (h ? DARG_R_PRCT(\"$hue\") : 0.0) / 100.0;\n        double sscale = (s ? DARG_R_PRCT(\"$saturation\") : 0.0) / 100.0;\n        double lscale = (l ? DARG_R_PRCT(\"$lightness\") : 0.0) / 100.0;\n        double ascale = (a ? DARG_R_PRCT(\"$alpha\") : 0.0) / 100.0;\n        if (hscale) c->h(c->h() + hscale * (hscale > 0.0 ? 360.0 - c->h() : c->h()));\n        if (sscale) c->s(c->s() + sscale * (sscale > 0.0 ? 100.0 - c->s() : c->s()));\n        if (lscale) c->l(c->l() + lscale * (lscale > 0.0 ? 100.0 - c->l() : c->l()));\n        if (ascale) c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));\n        return c.detach();\n      }\n      else if (a) {\n        Color_Obj c = SASS_MEMORY_COPY(col);\n        double ascale = DARG_R_PRCT(\"$alpha\") / 100.0;\n        c->a(c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));\n        c->a(clip(c->a(), 0.0, 1.0));\n        return c.detach();\n      }\n      error(\"not enough arguments for `scale-color'\", pstate, traces);\n      // unreachable\n      return col;\n    }\n\n    Signature change_color_sig = \"change-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)\";\n    BUILT_IN(change_color)\n    {\n      Color* col = ARG(\"$color\", Color);\n      Number* r = Cast<Number>(env[\"$red\"]);\n      Number* g = Cast<Number>(env[\"$green\"]);\n      Number* b = Cast<Number>(env[\"$blue\"]);\n      Number* h = Cast<Number>(env[\"$hue\"]);\n      Number* s = Cast<Number>(env[\"$saturation\"]);\n      Number* l = Cast<Number>(env[\"$lightness\"]);\n      Number* a = Cast<Number>(env[\"$alpha\"]);\n\n      bool rgb = r || g || b;\n      bool hsl = h || s || l;\n\n      if (rgb && hsl) {\n        error(\"Cannot specify HSL and RGB values for a color at the same time for `change-color'\", pstate, traces);\n      }\n      else if (rgb) {\n        Color_RGBA_Obj c = col->copyAsRGBA();\n        if (r) c->r(DARG_U_BYTE(\"$red\"));\n        if (g) c->g(DARG_U_BYTE(\"$green\"));\n        if (b) c->b(DARG_U_BYTE(\"$blue\"));\n        if (a) c->a(DARG_U_FACT(\"$alpha\"));\n        return c.detach();\n      }\n      else if (hsl) {\n        Color_HSLA_Obj c = col->copyAsHSLA();\n        if (h) c->h(absmod(h->value(), 360.0));\n        if (s) c->s(DARG_U_PRCT(\"$saturation\"));\n        if (l) c->l(DARG_U_PRCT(\"$lightness\"));\n        if (a) c->a(DARG_U_FACT(\"$alpha\"));\n        return c.detach();\n      }\n      else if (a) {\n        Color_Obj c = SASS_MEMORY_COPY(col);\n        c->a(clip(DARG_U_FACT(\"$alpha\"), 0.0, 1.0));\n        return c.detach();\n      }\n      error(\"not enough arguments for `change-color'\", pstate, traces);\n      // unreachable\n      return col;\n    }\n\n    Signature ie_hex_str_sig = \"ie-hex-str($color)\";\n    BUILT_IN(ie_hex_str)\n    {\n      Color* col = ARG(\"$color\", Color);\n      Color_RGBA_Obj c = col->toRGBA();\n      double r = clip(c->r(), 0.0, 255.0);\n      double g = clip(c->g(), 0.0, 255.0);\n      double b = clip(c->b(), 0.0, 255.0);\n      double a = clip(c->a(), 0.0, 1.0) * 255.0;\n\n      sass::ostream ss;\n      ss << '#' << std::setw(2) << std::setfill('0');\n      ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(a, ctx.c_options.precision));\n      ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(r, ctx.c_options.precision));\n      ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(g, ctx.c_options.precision));\n      ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(b, ctx.c_options.precision));\n\n      sass::string result = ss.str();\n      Util::ascii_str_toupper(&result);\n      return SASS_MEMORY_NEW(String_Quoted, pstate, result);\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_colors.hpp",
    "content": "#ifndef SASS_FN_COLORS_H\n#define SASS_FN_COLORS_H\n\n#include \"fn_utils.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    // macros for common ranges (u mean unsigned or upper, r for full range)\n    #define DARG_U_FACT(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 1.0) // double\n    #define DARG_R_FACT(argname) get_arg_r(argname, env, sig, pstate, traces, - 1.0, 1.0) // double\n    #define DARG_U_BYTE(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 255.0) // double\n    #define DARG_R_BYTE(argname) get_arg_r(argname, env, sig, pstate, traces, - 255.0, 255.0) // double\n    #define DARG_U_PRCT(argname) get_arg_r(argname, env, sig, pstate, traces, - 0.0, 100.0) // double\n    #define DARG_R_PRCT(argname) get_arg_r(argname, env, sig, pstate, traces, - 100.0, 100.0) // double\n\n    // macros for color related inputs (rbg and alpha/opacity values)\n    #define COLOR_NUM(argname) color_num(argname, env, sig, pstate, traces) // double\n    #define ALPHA_NUM(argname) alpha_num(argname, env, sig, pstate, traces) // double\n\n    extern Signature rgb_sig;\n    extern Signature rgba_4_sig;\n    extern Signature rgba_2_sig;\n    extern Signature red_sig;\n    extern Signature green_sig;\n    extern Signature blue_sig;\n    extern Signature mix_sig;\n    extern Signature hsl_sig;\n    extern Signature hsla_sig;\n    extern Signature hue_sig;\n    extern Signature saturation_sig;\n    extern Signature lightness_sig;\n    extern Signature adjust_hue_sig;\n    extern Signature lighten_sig;\n    extern Signature darken_sig;\n    extern Signature saturate_sig;\n    extern Signature desaturate_sig;\n    extern Signature grayscale_sig;\n    extern Signature complement_sig;\n    extern Signature invert_sig;\n    extern Signature alpha_sig;\n    extern Signature opacity_sig;\n    extern Signature opacify_sig;\n    extern Signature fade_in_sig;\n    extern Signature transparentize_sig;\n    extern Signature fade_out_sig;\n    extern Signature adjust_color_sig;\n    extern Signature scale_color_sig;\n    extern Signature change_color_sig;\n    extern Signature ie_hex_str_sig;\n\n    BUILT_IN(rgb);\n    BUILT_IN(rgba_4);\n    BUILT_IN(rgba_2);\n    BUILT_IN(red);\n    BUILT_IN(green);\n    BUILT_IN(blue);\n    BUILT_IN(mix);\n    BUILT_IN(hsl);\n    BUILT_IN(hsla);\n    BUILT_IN(hue);\n    BUILT_IN(saturation);\n    BUILT_IN(lightness);\n    BUILT_IN(adjust_hue);\n    BUILT_IN(lighten);\n    BUILT_IN(darken);\n    BUILT_IN(saturate);\n    BUILT_IN(desaturate);\n    BUILT_IN(grayscale);\n    BUILT_IN(complement);\n    BUILT_IN(invert);\n    BUILT_IN(alpha);\n    BUILT_IN(opacify);\n    BUILT_IN(transparentize);\n    BUILT_IN(adjust_color);\n    BUILT_IN(scale_color);\n    BUILT_IN(change_color);\n    BUILT_IN(ie_hex_str);\n\n  }\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_lists.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"listize.hpp\"\n#include \"operators.hpp\"\n#include \"fn_utils.hpp\"\n#include \"fn_lists.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    /////////////////\n    // LIST FUNCTIONS\n    /////////////////\n\n    Signature keywords_sig = \"keywords($args)\";\n    BUILT_IN(keywords)\n    {\n      List_Obj arglist = SASS_MEMORY_COPY(ARG(\"$args\", List)); // copy\n      Map_Obj result = SASS_MEMORY_NEW(Map, pstate, 1);\n      for (size_t i = arglist->size(), L = arglist->length(); i < L; ++i) {\n        ExpressionObj obj = arglist->at(i);\n        Argument_Obj arg = (Argument*) obj.ptr(); // XXX\n        sass::string name = sass::string(arg->name());\n        name = name.erase(0, 1); // sanitize name (remove dollar sign)\n        *result << std::make_pair(SASS_MEMORY_NEW(String_Quoted,\n                 pstate, name),\n                 arg->value());\n      }\n      return result.detach();\n    }\n\n    Signature length_sig = \"length($list)\";\n    BUILT_IN(length)\n    {\n      if (SelectorList * sl = Cast<SelectorList>(env[\"$list\"])) {\n        return SASS_MEMORY_NEW(Number, pstate, (double) sl->length());\n      }\n      Expression* v = ARG(\"$list\", Expression);\n      if (v->concrete_type() == Expression::MAP) {\n        Map* map = Cast<Map>(env[\"$list\"]);\n        return SASS_MEMORY_NEW(Number, pstate, (double)(map ? map->length() : 1));\n      }\n      if (v->concrete_type() == Expression::SELECTOR) {\n        if (CompoundSelector * h = Cast<CompoundSelector>(v)) {\n          return SASS_MEMORY_NEW(Number, pstate, (double)h->length());\n        } else if (SelectorList * ls = Cast<SelectorList>(v)) {\n          return SASS_MEMORY_NEW(Number, pstate, (double)ls->length());\n        } else {\n          return SASS_MEMORY_NEW(Number, pstate, 1);\n        }\n      }\n\n      List* list = Cast<List>(env[\"$list\"]);\n      return SASS_MEMORY_NEW(Number,\n                             pstate,\n                             (double)(list ? list->size() : 1));\n    }\n\n    Signature nth_sig = \"nth($list, $n)\";\n    BUILT_IN(nth)\n    {\n      double nr = ARGVAL(\"$n\");\n      Map* m = Cast<Map>(env[\"$list\"]);\n      if (SelectorList * sl = Cast<SelectorList>(env[\"$list\"])) {\n        size_t len = m ? m->length() : sl->length();\n        bool empty = m ? m->empty() : sl->empty();\n        if (empty) error(\"argument `$list` of `\" + sass::string(sig) + \"` must not be empty\", pstate, traces);\n        double index = std::floor(nr < 0 ? len + nr : nr - 1);\n        if (index < 0 || index > len - 1) error(\"index out of bounds for `\" + sass::string(sig) + \"`\", pstate, traces);\n        return Cast<Value>(Listize::perform(sl->get(static_cast<int>(index))));\n      }\n      List_Obj l = Cast<List>(env[\"$list\"]);\n      if (nr == 0) error(\"argument `$n` of `\" + sass::string(sig) + \"` must be non-zero\", pstate, traces);\n      // if the argument isn't a list, then wrap it in a singleton list\n      if (!m && !l) {\n        l = SASS_MEMORY_NEW(List, pstate, 1);\n        l->append(ARG(\"$list\", Expression));\n      }\n      size_t len = m ? m->length() : l->length();\n      bool empty = m ? m->empty() : l->empty();\n      if (empty) error(\"argument `$list` of `\" + sass::string(sig) + \"` must not be empty\", pstate, traces);\n      double index = std::floor(nr < 0 ? len + nr : nr - 1);\n      if (index < 0 || index > len - 1) error(\"index out of bounds for `\" + sass::string(sig) + \"`\", pstate, traces);\n\n      if (m) {\n        l = SASS_MEMORY_NEW(List, pstate, 2);\n        l->append(m->keys()[static_cast<unsigned int>(index)]);\n        l->append(m->at(m->keys()[static_cast<unsigned int>(index)]));\n        return l.detach();\n      }\n      else {\n        ValueObj rv = l->value_at_index(static_cast<int>(index));\n        rv->set_delayed(false);\n        return rv.detach();\n      }\n    }\n\n    Signature set_nth_sig = \"set-nth($list, $n, $value)\";\n    BUILT_IN(set_nth)\n    {\n      Map_Obj m = Cast<Map>(env[\"$list\"]);\n      List_Obj l = Cast<List>(env[\"$list\"]);\n      Number_Obj n = ARG(\"$n\", Number);\n      ExpressionObj v = ARG(\"$value\", Expression);\n      if (!l) {\n        l = SASS_MEMORY_NEW(List, pstate, 1);\n        l->append(ARG(\"$list\", Expression));\n      }\n      if (m) {\n        l = m->to_list(pstate);\n      }\n      if (l->empty()) error(\"argument `$list` of `\" + sass::string(sig) + \"` must not be empty\", pstate, traces);\n      double index = std::floor(n->value() < 0 ? l->length() + n->value() : n->value() - 1);\n      if (index < 0 || index > l->length() - 1) error(\"index out of bounds for `\" + sass::string(sig) + \"`\", pstate, traces);\n      List* result = SASS_MEMORY_NEW(List, pstate, l->length(), l->separator(), false, l->is_bracketed());\n      for (size_t i = 0, L = l->length(); i < L; ++i) {\n        result->append(((i == index) ? v : (*l)[i]));\n      }\n      return result;\n    }\n\n    Signature index_sig = \"index($list, $value)\";\n    BUILT_IN(index)\n    {\n      Map_Obj m = Cast<Map>(env[\"$list\"]);\n      List_Obj l = Cast<List>(env[\"$list\"]);\n      ExpressionObj v = ARG(\"$value\", Expression);\n      if (!l) {\n        l = SASS_MEMORY_NEW(List, pstate, 1);\n        l->append(ARG(\"$list\", Expression));\n      }\n      if (m) {\n        l = m->to_list(pstate);\n      }\n      for (size_t i = 0, L = l->length(); i < L; ++i) {\n        if (Operators::eq(l->value_at_index(i), v)) return SASS_MEMORY_NEW(Number, pstate, (double)(i+1));\n      }\n      return SASS_MEMORY_NEW(Null, pstate);\n    }\n\n    Signature join_sig = \"join($list1, $list2, $separator: auto, $bracketed: auto)\";\n    BUILT_IN(join)\n    {\n      Map_Obj m1 = Cast<Map>(env[\"$list1\"]);\n      Map_Obj m2 = Cast<Map>(env[\"$list2\"]);\n      List_Obj l1 = Cast<List>(env[\"$list1\"]);\n      List_Obj l2 = Cast<List>(env[\"$list2\"]);\n      String_Constant_Obj sep = ARG(\"$separator\", String_Constant);\n      enum Sass_Separator sep_val = (l1 ? l1->separator() : SASS_SPACE);\n      Value* bracketed = ARG(\"$bracketed\", Value);\n      bool is_bracketed = (l1 ? l1->is_bracketed() : false);\n      if (!l1) {\n        l1 = SASS_MEMORY_NEW(List, pstate, 1);\n        l1->append(ARG(\"$list1\", Expression));\n        sep_val = (l2 ? l2->separator() : SASS_SPACE);\n        is_bracketed = (l2 ? l2->is_bracketed() : false);\n      }\n      if (!l2) {\n        l2 = SASS_MEMORY_NEW(List, pstate, 1);\n        l2->append(ARG(\"$list2\", Expression));\n      }\n      if (m1) {\n        l1 = m1->to_list(pstate);\n        sep_val = SASS_COMMA;\n      }\n      if (m2) {\n        l2 = m2->to_list(pstate);\n      }\n      size_t len = l1->length() + l2->length();\n      sass::string sep_str = unquote(sep->value());\n      if (sep_str == \"space\") sep_val = SASS_SPACE;\n      else if (sep_str == \"comma\") sep_val = SASS_COMMA;\n      else if (sep_str != \"auto\") error(\"argument `$separator` of `\" + sass::string(sig) + \"` must be `space`, `comma`, or `auto`\", pstate, traces);\n      String_Constant_Obj bracketed_as_str = Cast<String_Constant>(bracketed);\n      bool bracketed_is_auto = bracketed_as_str && unquote(bracketed_as_str->value()) == \"auto\";\n      if (!bracketed_is_auto) {\n        is_bracketed = !bracketed->is_false();\n      }\n      List_Obj result = SASS_MEMORY_NEW(List, pstate, len, sep_val, false, is_bracketed);\n      result->concat(l1);\n      result->concat(l2);\n      return result.detach();\n    }\n\n    Signature append_sig = \"append($list, $val, $separator: auto)\";\n    BUILT_IN(append)\n    {\n      Map_Obj m = Cast<Map>(env[\"$list\"]);\n      List_Obj l = Cast<List>(env[\"$list\"]);\n      ExpressionObj v = ARG(\"$val\", Expression);\n      if (SelectorList * sl = Cast<SelectorList>(env[\"$list\"])) {\n        l = Cast<List>(Listize::perform(sl));\n      }\n      String_Constant_Obj sep = ARG(\"$separator\", String_Constant);\n      if (!l) {\n        l = SASS_MEMORY_NEW(List, pstate, 1);\n        l->append(ARG(\"$list\", Expression));\n      }\n      if (m) {\n        l = m->to_list(pstate);\n      }\n      List* result = SASS_MEMORY_COPY(l);\n      sass::string sep_str(unquote(sep->value()));\n      if (sep_str != \"auto\") { // check default first\n        if (sep_str == \"space\") result->separator(SASS_SPACE);\n        else if (sep_str == \"comma\") result->separator(SASS_COMMA);\n        else error(\"argument `$separator` of `\" + sass::string(sig) + \"` must be `space`, `comma`, or `auto`\", pstate, traces);\n      }\n      if (l->is_arglist()) {\n        result->append(SASS_MEMORY_NEW(Argument,\n                                       v->pstate(),\n                                       v,\n                                       \"\",\n                                       false,\n                                       false));\n\n      } else {\n        result->append(v);\n      }\n      return result;\n    }\n\n    Signature zip_sig = \"zip($lists...)\";\n    BUILT_IN(zip)\n    {\n      List_Obj arglist = SASS_MEMORY_COPY(ARG(\"$lists\", List));\n      size_t shortest = 0;\n      for (size_t i = 0, L = arglist->length(); i < L; ++i) {\n        List_Obj ith = Cast<List>(arglist->value_at_index(i));\n        Map_Obj mith = Cast<Map>(arglist->value_at_index(i));\n        if (!ith) {\n          if (mith) {\n            ith = mith->to_list(pstate);\n          } else {\n            ith = SASS_MEMORY_NEW(List, pstate, 1);\n            ith->append(arglist->value_at_index(i));\n          }\n          if (arglist->is_arglist()) {\n            Argument_Obj arg = (Argument*)(arglist->at(i).ptr()); // XXX\n            arg->value(ith);\n          } else {\n            (*arglist)[i] = ith;\n          }\n        }\n        shortest = (i ? std::min(shortest, ith->length()) : ith->length());\n      }\n      List* zippers = SASS_MEMORY_NEW(List, pstate, shortest, SASS_COMMA);\n      size_t L = arglist->length();\n      for (size_t i = 0; i < shortest; ++i) {\n        List* zipper = SASS_MEMORY_NEW(List, pstate, L);\n        for (size_t j = 0; j < L; ++j) {\n          zipper->append(Cast<List>(arglist->value_at_index(j))->at(i));\n        }\n        zippers->append(zipper);\n      }\n      return zippers;\n    }\n\n    Signature list_separator_sig = \"list_separator($list)\";\n    BUILT_IN(list_separator)\n    {\n      List_Obj l = Cast<List>(env[\"$list\"]);\n      if (!l) {\n        l = SASS_MEMORY_NEW(List, pstate, 1);\n        l->append(ARG(\"$list\", Expression));\n      }\n      return SASS_MEMORY_NEW(String_Quoted,\n                               pstate,\n                               l->separator() == SASS_COMMA ? \"comma\" : \"space\");\n    }\n\n    Signature is_bracketed_sig = \"is-bracketed($list)\";\n    BUILT_IN(is_bracketed)\n    {\n      ValueObj value = ARG(\"$list\", Value);\n      List_Obj list = Cast<List>(value);\n      return SASS_MEMORY_NEW(Boolean, pstate, list && list->is_bracketed());\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_lists.hpp",
    "content": "#ifndef SASS_FN_LISTS_H\n#define SASS_FN_LISTS_H\n\n#include \"fn_utils.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    extern Signature length_sig;\n    extern Signature nth_sig;\n    extern Signature index_sig;\n    extern Signature join_sig;\n    extern Signature append_sig;\n    extern Signature zip_sig;\n    extern Signature list_separator_sig;\n    extern Signature is_bracketed_sig;\n    extern Signature keywords_sig;\n\n    BUILT_IN(length);\n    BUILT_IN(nth);\n    BUILT_IN(index);\n    BUILT_IN(join);\n    BUILT_IN(append);\n    BUILT_IN(zip);\n    BUILT_IN(list_separator);\n    BUILT_IN(is_bracketed);\n    BUILT_IN(keywords);\n\n  }\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_maps.cpp",
    "content": "#include \"operators.hpp\"\n#include \"fn_utils.hpp\"\n#include \"fn_maps.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    /////////////////\n    // MAP FUNCTIONS\n    /////////////////\n\n    Signature map_get_sig = \"map-get($map, $key)\";\n    BUILT_IN(map_get)\n    {\n      // leaks for \"map-get((), foo)\" if not Obj\n      // investigate why this is (unexpected)\n      Map_Obj m = ARGM(\"$map\", Map);\n      ExpressionObj v = ARG(\"$key\", Expression);\n      try {\n        ValueObj val = m->at(v);\n        if (!val) return SASS_MEMORY_NEW(Null, pstate);\n        val->set_delayed(false);\n        return val.detach();\n      } catch (const std::out_of_range&) {\n        return SASS_MEMORY_NEW(Null, pstate);\n      }\n      catch (...) { throw; }\n    }\n\n    Signature map_has_key_sig = \"map-has-key($map, $key)\";\n    BUILT_IN(map_has_key)\n    {\n      Map_Obj m = ARGM(\"$map\", Map);\n      ExpressionObj v = ARG(\"$key\", Expression);\n      return SASS_MEMORY_NEW(Boolean, pstate, m->has(v));\n    }\n\n    Signature map_keys_sig = \"map-keys($map)\";\n    BUILT_IN(map_keys)\n    {\n      Map_Obj m = ARGM(\"$map\", Map);\n      List* result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA);\n      for ( auto key : m->keys()) {\n        result->append(key);\n      }\n      return result;\n    }\n\n    Signature map_values_sig = \"map-values($map)\";\n    BUILT_IN(map_values)\n    {\n      Map_Obj m = ARGM(\"$map\", Map);\n      List* result = SASS_MEMORY_NEW(List, pstate, m->length(), SASS_COMMA);\n      for ( auto key : m->keys()) {\n        result->append(m->at(key));\n      }\n      return result;\n    }\n\n    Signature map_merge_sig = \"map-merge($map1, $map2)\";\n    BUILT_IN(map_merge)\n    {\n      Map_Obj m1 = ARGM(\"$map1\", Map);\n      Map_Obj m2 = ARGM(\"$map2\", Map);\n\n      size_t len = m1->length() + m2->length();\n      Map* result = SASS_MEMORY_NEW(Map, pstate, len);\n      // concat not implemented for maps\n      *result += m1;\n      *result += m2;\n      return result;\n    }\n\n    Signature map_remove_sig = \"map-remove($map, $keys...)\";\n    BUILT_IN(map_remove)\n    {\n      bool remove;\n      Map_Obj m = ARGM(\"$map\", Map);\n      List_Obj arglist = ARG(\"$keys\", List);\n      Map* result = SASS_MEMORY_NEW(Map, pstate, 1);\n      for (auto key : m->keys()) {\n        remove = false;\n        for (size_t j = 0, K = arglist->length(); j < K && !remove; ++j) {\n          remove = Operators::eq(key, arglist->value_at_index(j));\n        }\n        if (!remove) *result << std::make_pair(key, m->at(key));\n      }\n      return result;\n    }\n\n  }\n\n}"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_maps.hpp",
    "content": "#ifndef SASS_FN_MAPS_H\n#define SASS_FN_MAPS_H\n\n#include \"fn_utils.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    #define ARGM(argname, argtype) get_arg_m(argname, env, sig, pstate, traces)\n\n    extern Signature map_get_sig;\n    extern Signature map_merge_sig;\n    extern Signature map_remove_sig;\n    extern Signature map_keys_sig;\n    extern Signature map_values_sig;\n    extern Signature map_has_key_sig;\n\n    BUILT_IN(map_get);\n    BUILT_IN(map_merge);\n    BUILT_IN(map_remove);\n    BUILT_IN(map_keys);\n    BUILT_IN(map_values);\n    BUILT_IN(map_has_key);\n\n  }\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_miscs.cpp",
    "content": "#include \"ast.hpp\"\n#include \"expand.hpp\"\n#include \"fn_utils.hpp\"\n#include \"fn_miscs.hpp\"\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    //////////////////////////\n    // INTROSPECTION FUNCTIONS\n    //////////////////////////\n\n    Signature type_of_sig = \"type-of($value)\";\n    BUILT_IN(type_of)\n    {\n      Expression* v = ARG(\"$value\", Expression);\n      return SASS_MEMORY_NEW(String_Quoted, pstate, v->type());\n    }\n\n    Signature variable_exists_sig = \"variable-exists($name)\";\n    BUILT_IN(variable_exists)\n    {\n      sass::string s = Util::normalize_underscores(unquote(ARG(\"$name\", String_Constant)->value()));\n\n      if(d_env.has(\"$\"+s)) {\n        return SASS_MEMORY_NEW(Boolean, pstate, true);\n      }\n      else {\n        return SASS_MEMORY_NEW(Boolean, pstate, false);\n      }\n    }\n\n    Signature global_variable_exists_sig = \"global-variable-exists($name)\";\n    BUILT_IN(global_variable_exists)\n    {\n      sass::string s = Util::normalize_underscores(unquote(ARG(\"$name\", String_Constant)->value()));\n\n      if(d_env.has_global(\"$\"+s)) {\n        return SASS_MEMORY_NEW(Boolean, pstate, true);\n      }\n      else {\n        return SASS_MEMORY_NEW(Boolean, pstate, false);\n      }\n    }\n\n    Signature function_exists_sig = \"function-exists($name)\";\n    BUILT_IN(function_exists)\n    {\n      String_Constant* ss = Cast<String_Constant>(env[\"$name\"]);\n      if (!ss) {\n        error(\"$name: \" + (env[\"$name\"]->to_string()) + \" is not a string for `function-exists'\", pstate, traces);\n      }\n\n      sass::string name = Util::normalize_underscores(unquote(ss->value()));\n\n      if(d_env.has(name+\"[f]\")) {\n        return SASS_MEMORY_NEW(Boolean, pstate, true);\n      }\n      else {\n        return SASS_MEMORY_NEW(Boolean, pstate, false);\n      }\n    }\n\n    Signature mixin_exists_sig = \"mixin-exists($name)\";\n    BUILT_IN(mixin_exists)\n    {\n      sass::string s = Util::normalize_underscores(unquote(ARG(\"$name\", String_Constant)->value()));\n\n      if(d_env.has(s+\"[m]\")) {\n        return SASS_MEMORY_NEW(Boolean, pstate, true);\n      }\n      else {\n        return SASS_MEMORY_NEW(Boolean, pstate, false);\n      }\n    }\n\n    Signature feature_exists_sig = \"feature-exists($feature)\";\n    BUILT_IN(feature_exists)\n    {\n      sass::string s = unquote(ARG(\"$feature\", String_Constant)->value());\n\n      static const auto *const features = new std::unordered_set<sass::string> {\n        \"global-variable-shadowing\",\n        \"extend-selector-pseudoclass\",\n        \"at-error\",\n        \"units-level-3\",\n        \"custom-property\"\n      };\n      return SASS_MEMORY_NEW(Boolean, pstate, features->find(s) != features->end());\n    }\n\n    Signature call_sig = \"call($function, $args...)\";\n    BUILT_IN(call)\n    {\n      sass::string function;\n      Function* ff = Cast<Function>(env[\"$function\"]);\n      String_Constant* ss = Cast<String_Constant>(env[\"$function\"]);\n\n      if (ss) {\n        function = Util::normalize_underscores(unquote(ss->value()));\n        std::cerr << \"DEPRECATION WARNING: \";\n        std::cerr << \"Passing a string to call() is deprecated and will be illegal\" << std::endl;\n        std::cerr << \"in Sass 4.0. Use call(get-function(\" + quote(function) + \")) instead.\" << std::endl;\n        std::cerr << std::endl;\n      } else if (ff) {\n        function = ff->name();\n      }\n\n      List_Obj arglist = SASS_MEMORY_COPY(ARG(\"$args\", List));\n\n      Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);\n      // sass::string full_name(name + \"[f]\");\n      // Definition* def = d_env.has(full_name) ? Cast<Definition>((d_env)[full_name]) : 0;\n      // Parameters* params = def ? def->parameters() : 0;\n      // size_t param_size = params ? params->length() : 0;\n      for (size_t i = 0, L = arglist->length(); i < L; ++i) {\n        ExpressionObj expr = arglist->value_at_index(i);\n        // if (params && params->has_rest_parameter()) {\n        //   Parameter_Obj p = param_size > i ? (*params)[i] : 0;\n        //   List* list = Cast<List>(expr);\n        //   if (list && p && !p->is_rest_parameter()) expr = (*list)[0];\n        // }\n        if (arglist->is_arglist()) {\n          ExpressionObj obj = arglist->at(i);\n          Argument_Obj arg = (Argument*) obj.ptr(); // XXX\n          args->append(SASS_MEMORY_NEW(Argument,\n                                       pstate,\n                                       expr,\n                                       arg ? arg->name() : \"\",\n                                       arg ? arg->is_rest_argument() : false,\n                                       arg ? arg->is_keyword_argument() : false));\n        } else {\n          args->append(SASS_MEMORY_NEW(Argument, pstate, expr));\n        }\n      }\n      Function_Call_Obj func = SASS_MEMORY_NEW(Function_Call, pstate, function, args);\n\n      Expand expand(ctx, &d_env, &selector_stack, &original_stack);\n      func->via_call(true); // calc invoke is allowed\n      if (ff) func->func(ff);\n      return Cast<PreValue>(func->perform(&expand.eval));\n    }\n\n    ////////////////////\n    // BOOLEAN FUNCTIONS\n    ////////////////////\n\n    Signature not_sig = \"not($value)\";\n    BUILT_IN(sass_not)\n    {\n      return SASS_MEMORY_NEW(Boolean, pstate, ARG(\"$value\", Expression)->is_false());\n    }\n\n    Signature if_sig = \"if($condition, $if-true, $if-false)\";\n    BUILT_IN(sass_if)\n    {\n      Expand expand(ctx, &d_env, &selector_stack, &original_stack);\n      ExpressionObj cond = ARG(\"$condition\", Expression)->perform(&expand.eval);\n      bool is_true = !cond->is_false();\n      ExpressionObj res = ARG(is_true ? \"$if-true\" : \"$if-false\", Expression);\n      ValueObj qwe = Cast<Value>(res->perform(&expand.eval));\n      // res = res->perform(&expand.eval.val_eval);\n      qwe->set_delayed(false); // clone?\n      return qwe.detach();\n    }\n\n    //////////////////////////\n    // MISCELLANEOUS FUNCTIONS\n    //////////////////////////\n\n    Signature inspect_sig = \"inspect($value)\";\n    BUILT_IN(inspect)\n    {\n      Expression* v = ARG(\"$value\", Expression);\n      if (v->concrete_type() == Expression::NULL_VAL) {\n        return SASS_MEMORY_NEW(String_Constant, pstate, \"null\");\n      } else if (v->concrete_type() == Expression::BOOLEAN && v->is_false()) {\n        return SASS_MEMORY_NEW(String_Constant, pstate, \"false\");\n      } else if (v->concrete_type() == Expression::STRING) {\n        String_Constant *s = Cast<String_Constant>(v);\n        if (s->quote_mark()) {\n          return SASS_MEMORY_NEW(String_Constant, pstate, quote(s->value(), s->quote_mark()));\n        } else {\n          return s;\n        }\n      } else {\n        // ToDo: fix to_sass for nested parentheses\n        Sass_Output_Style old_style;\n        old_style = ctx.c_options.output_style;\n        ctx.c_options.output_style = TO_SASS;\n        Emitter emitter(ctx.c_options);\n        Inspect i(emitter);\n        i.in_declaration = false;\n        v->perform(&i);\n        ctx.c_options.output_style = old_style;\n        return SASS_MEMORY_NEW(String_Quoted, pstate, i.get_buffer());\n      }\n    }\n\n    Signature content_exists_sig = \"content-exists()\";\n    BUILT_IN(content_exists)\n    {\n      if (!d_env.has_global(\"is_in_mixin\")) {\n        error(\"Cannot call content-exists() except within a mixin.\", pstate, traces);\n      }\n      return SASS_MEMORY_NEW(Boolean, pstate, d_env.has_lexical(\"@content[m]\"));\n    }\n\n    Signature get_function_sig = \"get-function($name, $css: false)\";\n    BUILT_IN(get_function)\n    {\n      String_Constant* ss = Cast<String_Constant>(env[\"$name\"]);\n      if (!ss) {\n        error(\"$name: \" + (env[\"$name\"]->to_string()) + \" is not a string for `get-function'\", pstate, traces);\n      }\n\n      sass::string name = Util::normalize_underscores(unquote(ss->value()));\n      sass::string full_name = name + \"[f]\";\n\n      Boolean_Obj css = ARG(\"$css\", Boolean);\n      if (!css->is_false()) {\n        Definition* def = SASS_MEMORY_NEW(Definition,\n                                         pstate,\n                                         name,\n                                         SASS_MEMORY_NEW(Parameters, pstate),\n                                         SASS_MEMORY_NEW(Block, pstate, 0, false),\n                                         Definition::FUNCTION);\n        return SASS_MEMORY_NEW(Function, pstate, def, true);\n      }\n\n\n      if (!d_env.has_global(full_name)) {\n        error(\"Function not found: \" + name, pstate, traces);\n      }\n\n      Definition* def = Cast<Definition>(d_env[full_name]);\n      return SASS_MEMORY_NEW(Function, pstate, def, false);\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_miscs.hpp",
    "content": "#ifndef SASS_FN_MISCS_H\n#define SASS_FN_MISCS_H\n\n#include \"fn_utils.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    extern Signature type_of_sig;\n    extern Signature variable_exists_sig;\n    extern Signature global_variable_exists_sig;\n    extern Signature function_exists_sig;\n    extern Signature mixin_exists_sig;\n    extern Signature feature_exists_sig;\n    extern Signature call_sig;\n    extern Signature not_sig;\n    extern Signature if_sig;\n    extern Signature set_nth_sig;\n    extern Signature content_exists_sig;\n    extern Signature get_function_sig;\n\n    BUILT_IN(type_of);\n    BUILT_IN(variable_exists);\n    BUILT_IN(global_variable_exists);\n    BUILT_IN(function_exists);\n    BUILT_IN(mixin_exists);\n    BUILT_IN(feature_exists);\n    BUILT_IN(call);\n    BUILT_IN(sass_not);\n    BUILT_IN(sass_if);\n    BUILT_IN(set_nth);\n    BUILT_IN(content_exists);\n    BUILT_IN(get_function);\n\n  }\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_numbers.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <cstdint>\n#include <cstdlib>\n#include <cmath>\n#include <ctime>\n#include <random>\n#include <sstream>\n#include <iomanip>\n#include <algorithm>\n#include <thread>\n\n#include \"ast.hpp\"\n#include \"units.hpp\"\n#include \"fn_utils.hpp\"\n#include \"fn_numbers.hpp\"\n\n#ifdef __MINGW32__\n#include \"windows.h\"\n#include \"wincrypt.h\"\n#endif\n\nnamespace Sass {\n\n  namespace Functions {\n\n    #ifdef __MINGW32__\n      uint64_t GetSeed()\n      {\n        HCRYPTPROV hp = 0;\n        BYTE rb[8];\n        CryptAcquireContext(&hp, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);\n        CryptGenRandom(hp, sizeof(rb), rb);\n        CryptReleaseContext(hp, 0);\n\n        uint64_t seed;\n        memcpy(&seed, &rb[0], sizeof(seed));\n\n        return seed;\n      }\n    #else\n      uint64_t GetSeed()\n      {\n        // Init universe entropy\n        uint64_t rnd = 42;\n        // Try to get random number from system\n        try {\n          std::random_device rd;\n          rnd = rd();\n        }\n        // On certain system this can throw since either\n        // underlying hardware or software can be buggy.\n        // https://github.com/sass/libsass/issues/3151\n        catch (std::exception&) {\n        }\n        // Don't trust anyone to be random, so we\n        // add a little entropy of our own.\n        rnd ^= std::time(NULL) ^ std::clock() ^\n          std::hash<std::thread::id>()\n          (std::this_thread::get_id());\n        // Return entropy\n        return rnd;\n      }\n    #endif\n\n    // note: the performance of many implementations of\n    // random_device degrades sharply once the entropy pool\n    // is exhausted. For practical use, random_device is\n    // generally only used to seed a PRNG such as mt19937.\n    static std::mt19937 rand(static_cast<unsigned int>(GetSeed()));\n\n    ///////////////////\n    // NUMBER FUNCTIONS\n    ///////////////////\n\n    Signature percentage_sig = \"percentage($number)\";\n    BUILT_IN(percentage)\n    {\n      Number_Obj n = ARGN(\"$number\");\n      if (!n->is_unitless()) error(\"argument $number of `\" + sass::string(sig) + \"` must be unitless\", pstate, traces);\n      return SASS_MEMORY_NEW(Number, pstate, n->value() * 100, \"%\");\n    }\n\n    Signature round_sig = \"round($number)\";\n    BUILT_IN(round)\n    {\n      Number_Obj r = ARGN(\"$number\");\n      r->value(Sass::round(r->value(), ctx.c_options.precision));\n      r->pstate(pstate);\n      return r.detach();\n    }\n\n    Signature ceil_sig = \"ceil($number)\";\n    BUILT_IN(ceil)\n    {\n      Number_Obj r = ARGN(\"$number\");\n      r->value(std::ceil(r->value()));\n      r->pstate(pstate);\n      return r.detach();\n    }\n\n    Signature floor_sig = \"floor($number)\";\n    BUILT_IN(floor)\n    {\n      Number_Obj r = ARGN(\"$number\");\n      r->value(std::floor(r->value()));\n      r->pstate(pstate);\n      return r.detach();\n    }\n\n    Signature abs_sig = \"abs($number)\";\n    BUILT_IN(abs)\n    {\n      Number_Obj r = ARGN(\"$number\");\n      r->value(std::abs(r->value()));\n      r->pstate(pstate);\n      return r.detach();\n    }\n\n    Signature min_sig = \"min($numbers...)\";\n    BUILT_IN(min)\n    {\n      List* arglist = ARG(\"$numbers\", List);\n      Number_Obj least;\n      size_t L = arglist->length();\n      if (L == 0) {\n        error(\"At least one argument must be passed.\", pstate, traces);\n      }\n      for (size_t i = 0; i < L; ++i) {\n        ExpressionObj val = arglist->value_at_index(i);\n        Number_Obj xi = Cast<Number>(val);\n        if (!xi) {\n          error(\"\\\"\" + val->to_string(ctx.c_options) + \"\\\" is not a number for `min'\", pstate, traces);\n        }\n        if (least) {\n          if (*xi < *least) least = xi;\n        } else least = xi;\n      }\n      return least.detach();\n    }\n\n    Signature max_sig = \"max($numbers...)\";\n    BUILT_IN(max)\n    {\n      List* arglist = ARG(\"$numbers\", List);\n      Number_Obj greatest;\n      size_t L = arglist->length();\n      if (L == 0) {\n        error(\"At least one argument must be passed.\", pstate, traces);\n      }\n      for (size_t i = 0; i < L; ++i) {\n        ExpressionObj val = arglist->value_at_index(i);\n        Number_Obj xi = Cast<Number>(val);\n        if (!xi) {\n          error(\"\\\"\" + val->to_string(ctx.c_options) + \"\\\" is not a number for `max'\", pstate, traces);\n        }\n        if (greatest) {\n          if (*greatest < *xi) greatest = xi;\n        } else greatest = xi;\n      }\n      return greatest.detach();\n    }\n\n    Signature random_sig = \"random($limit:false)\";\n    BUILT_IN(random)\n    {\n      AST_Node_Obj arg = env[\"$limit\"];\n      Value* v = Cast<Value>(arg);\n      Number* l = Cast<Number>(arg);\n      Boolean* b = Cast<Boolean>(arg);\n      if (l) {\n        double lv = l->value();\n        if (lv < 1) {\n          sass::ostream err;\n          err << \"$limit \" << lv << \" must be greater than or equal to 1 for `random'\";\n          error(err.str(), pstate, traces);\n        }\n        bool eq_int = std::fabs(trunc(lv) - lv) < NUMBER_EPSILON;\n        if (!eq_int) {\n          sass::ostream err;\n          err << \"Expected $limit to be an integer but got \" << lv << \" for `random'\";\n          error(err.str(), pstate, traces);\n        }\n        std::uniform_real_distribution<> distributor(1, lv + 1);\n        uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));\n        return SASS_MEMORY_NEW(Number, pstate, (double)distributed);\n      }\n      else if (b) {\n        std::uniform_real_distribution<> distributor(0, 1);\n        double distributed = static_cast<double>(distributor(rand));\n        return SASS_MEMORY_NEW(Number, pstate, distributed);\n      } else if (v) {\n        traces.push_back(Backtrace(pstate));\n        throw Exception::InvalidArgumentType(pstate, traces, \"random\", \"$limit\", \"number\", v);\n      } else {\n        traces.push_back(Backtrace(pstate));\n        throw Exception::InvalidArgumentType(pstate, traces, \"random\", \"$limit\", \"number\");\n      }\n    }\n\n    Signature unique_id_sig = \"unique-id()\";\n    BUILT_IN(unique_id)\n    {\n      sass::ostream ss;\n      std::uniform_real_distribution<> distributor(0, 4294967296); // 16^8\n      uint_fast32_t distributed = static_cast<uint_fast32_t>(distributor(rand));\n      ss << \"u\" << std::setfill('0') << std::setw(8) << std::hex << distributed;\n      return SASS_MEMORY_NEW(String_Quoted, pstate, ss.str());\n    }\n\n    Signature unit_sig = \"unit($number)\";\n    BUILT_IN(unit)\n    {\n      Number_Obj arg = ARGN(\"$number\");\n      sass::string str(quote(arg->unit(), '\"'));\n      return SASS_MEMORY_NEW(String_Quoted, pstate, str);\n    }\n\n    Signature unitless_sig = \"unitless($number)\";\n    BUILT_IN(unitless)\n    {\n      Number_Obj arg = ARGN(\"$number\");\n      bool unitless = arg->is_unitless();\n      return SASS_MEMORY_NEW(Boolean, pstate, unitless);\n    }\n\n    Signature comparable_sig = \"comparable($number1, $number2)\";\n    BUILT_IN(comparable)\n    {\n      Number_Obj n1 = ARGN(\"$number1\");\n      Number_Obj n2 = ARGN(\"$number2\");\n      if (n1->is_unitless() || n2->is_unitless()) {\n        return SASS_MEMORY_NEW(Boolean, pstate, true);\n      }\n      // normalize into main units\n      n1->normalize(); n2->normalize();\n      Units &lhs_unit = *n1, &rhs_unit = *n2;\n      bool is_comparable = (lhs_unit == rhs_unit);\n      return SASS_MEMORY_NEW(Boolean, pstate, is_comparable);\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_numbers.hpp",
    "content": "#ifndef SASS_FN_NUMBERS_H\n#define SASS_FN_NUMBERS_H\n\n#include \"fn_utils.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    // return a number object (copied since we want to have reduced units)\n    #define ARGN(argname) get_arg_n(argname, env, sig, pstate, traces) // Number copy\n\n    extern Signature percentage_sig;\n    extern Signature round_sig;\n    extern Signature ceil_sig;\n    extern Signature floor_sig;\n    extern Signature abs_sig;\n    extern Signature min_sig;\n    extern Signature max_sig;\n    extern Signature inspect_sig;\n    extern Signature random_sig;\n    extern Signature unique_id_sig;\n    extern Signature unit_sig;\n    extern Signature unitless_sig;\n    extern Signature comparable_sig;\n\n    BUILT_IN(percentage);\n    BUILT_IN(round);\n    BUILT_IN(ceil);\n    BUILT_IN(floor);\n    BUILT_IN(abs);\n    BUILT_IN(min);\n    BUILT_IN(max);\n    BUILT_IN(inspect);\n    BUILT_IN(random);\n    BUILT_IN(unique_id);\n    BUILT_IN(unit);\n    BUILT_IN(unitless);\n    BUILT_IN(comparable);\n\n  }\n\n}\n\n#endif"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_selectors.cpp",
    "content": "#include <numeric>\n\n#include \"parser.hpp\"\n#include \"extender.hpp\"\n#include \"listize.hpp\"\n#include \"fn_utils.hpp\"\n#include \"fn_selectors.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    Signature selector_nest_sig = \"selector-nest($selectors...)\";\n    BUILT_IN(selector_nest)\n    {\n      List* arglist = ARG(\"$selectors\", List);\n\n      // Not enough parameters\n      if (arglist->length() == 0) {\n        error(\n          \"$selectors: At least one selector must be passed for `selector-nest'\",\n          pstate, traces);\n      }\n\n      // Parse args into vector of selectors\n      SelectorStack parsedSelectors;\n      for (size_t i = 0, L = arglist->length(); i < L; ++i) {\n        ExpressionObj exp = Cast<Expression>(arglist->value_at_index(i));\n        if (exp->concrete_type() == Expression::NULL_VAL) {\n          error(\n            \"$selectors: null is not a valid selector: it must be a string,\\n\"\n            \"a list of strings, or a list of lists of strings for 'selector-nest'\",\n            pstate, traces);\n        }\n        if (String_Constant_Obj str = Cast<String_Constant>(exp)) {\n          str->quote_mark(0);\n        }\n        sass::string exp_src = exp->to_string(ctx.c_options);\n        ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());\n        SelectorListObj sel = Parser::parse_selector(source, ctx, traces);\n        parsedSelectors.push_back(sel);\n      }\n\n      // Nothing to do\n      if( parsedSelectors.empty() ) {\n        return SASS_MEMORY_NEW(Null, pstate);\n      }\n\n      // Set the first element as the `result`, keep\n      // appending to as we go down the parsedSelector vector.\n      SelectorStack::iterator itr = parsedSelectors.begin();\n      SelectorListObj& result = *itr;\n      ++itr;\n\n      for(;itr != parsedSelectors.end(); ++itr) {\n        SelectorListObj& child = *itr;\n        original_stack.push_back(result);\n        SelectorListObj rv = child->resolve_parent_refs(original_stack, traces);\n        result->elements(rv->elements());\n        original_stack.pop_back();\n      }\n\n      return Cast<Value>(Listize::perform(result));\n    }\n\n    Signature selector_append_sig = \"selector-append($selectors...)\";\n    BUILT_IN(selector_append)\n    {\n      List* arglist = ARG(\"$selectors\", List);\n\n      // Not enough parameters\n      if (arglist->empty()) {\n        error(\n          \"$selectors: At least one selector must be \"\n          \"passed for `selector-append'\",\n          pstate, traces);\n      }\n\n      // Parse args into vector of selectors\n      SelectorStack parsedSelectors;\n      parsedSelectors.push_back({});\n      for (size_t i = 0, L = arglist->length(); i < L; ++i) {\n        Expression* exp = Cast<Expression>(arglist->value_at_index(i));\n        if (exp->concrete_type() == Expression::NULL_VAL) {\n          error(\n            \"$selectors: null is not a valid selector: it must be a string,\\n\"\n             \"a list of strings, or a list of lists of strings for 'selector-append'\",\n            pstate, traces);\n        }\n        if (String_Constant* str = Cast<String_Constant>(exp)) {\n          str->quote_mark(0);\n        }\n        sass::string exp_src = exp->to_string();\n        ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());\n        SelectorListObj sel = Parser::parse_selector(source, ctx, traces, true);\n\n        for (auto& complex : sel->elements()) {\n          if (complex->empty()) {\n            complex->append(SASS_MEMORY_NEW(CompoundSelector, \"[append]\"));\n          }\n          if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {\n            comp->hasRealParent(true);\n            complex->chroots(true);\n          }\n        }\n\n        if (parsedSelectors.size() > 1) {\n\n          if (!sel->has_real_parent_ref()) {\n            auto parent = parsedSelectors.back();\n            for (auto& complex : parent->elements()) {\n              if (CompoundSelector* comp = Cast<CompoundSelector>(complex->first())) {\n                comp->hasRealParent(false);\n              }\n            }\n            error(\"Can't append \\\"\" + sel->to_string() + \"\\\" to \\\"\" +\n              parent->to_string() + \"\\\" for `selector-append'\",\n              pstate, traces);\n          }\n\n          // Build the resolved stack from the left. It's cheaper to directly\n          // calculate and update each resolved selcted from the left, than to\n          // recursively calculate them from the right side, as we would need\n          // to go through the whole stack depth to build the final results.\n          // E.g. 'a', 'b', 'x, y' => 'a' => 'a b' => 'a b x, a b y'\n          // vs 'a', 'b', 'x, y' => 'x' => 'b x' => 'a b x', 'y' ...\n          parsedSelectors.push_back(sel->resolve_parent_refs(parsedSelectors, traces, true));\n        }\n        else {\n          parsedSelectors.push_back(sel);\n        }\n      }\n\n      // Nothing to do\n      if( parsedSelectors.empty() ) {\n        return SASS_MEMORY_NEW(Null, pstate);\n      }\n\n      return Cast<Value>(Listize::perform(parsedSelectors.back()));\n    }\n\n    Signature selector_unify_sig = \"selector-unify($selector1, $selector2)\";\n    BUILT_IN(selector_unify)\n    {\n      SelectorListObj selector1 = ARGSELS(\"$selector1\");\n      SelectorListObj selector2 = ARGSELS(\"$selector2\");\n      SelectorListObj result = selector1->unifyWith(selector2);\n      return Cast<Value>(Listize::perform(result));\n    }\n\n    Signature simple_selectors_sig = \"simple-selectors($selector)\";\n    BUILT_IN(simple_selectors)\n    {\n      CompoundSelectorObj sel = ARGSEL(\"$selector\");\n\n      List* l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);\n\n      for (size_t i = 0, L = sel->length(); i < L; ++i) {\n        const SimpleSelectorObj& ss = sel->get(i);\n        sass::string ss_string = ss->to_string() ;\n        l->append(SASS_MEMORY_NEW(String_Quoted, ss->pstate(), ss_string));\n      }\n\n      return l;\n    }\n\n    Signature selector_extend_sig = \"selector-extend($selector, $extendee, $extender)\";\n    BUILT_IN(selector_extend)\n    {\n      SelectorListObj selector = ARGSELS(\"$selector\");\n      SelectorListObj target = ARGSELS(\"$extendee\");\n      SelectorListObj source = ARGSELS(\"$extender\");\n      SelectorListObj result = Extender::extend(selector, source, target, traces);\n      return Cast<Value>(Listize::perform(result));\n    }\n\n    Signature selector_replace_sig = \"selector-replace($selector, $original, $replacement)\";\n    BUILT_IN(selector_replace)\n    {\n      SelectorListObj selector = ARGSELS(\"$selector\");\n      SelectorListObj target = ARGSELS(\"$original\");\n      SelectorListObj source = ARGSELS(\"$replacement\");\n      SelectorListObj result = Extender::replace(selector, source, target, traces);\n      return Cast<Value>(Listize::perform(result));\n    }\n\n    Signature selector_parse_sig = \"selector-parse($selector)\";\n    BUILT_IN(selector_parse)\n    {\n      SelectorListObj selector = ARGSELS(\"$selector\");\n      return Cast<Value>(Listize::perform(selector));\n    }\n\n    Signature is_superselector_sig = \"is-superselector($super, $sub)\";\n    BUILT_IN(is_superselector)\n    {\n      SelectorListObj sel_sup = ARGSELS(\"$super\");\n      SelectorListObj sel_sub = ARGSELS(\"$sub\");\n      bool result = sel_sup->isSuperselectorOf(sel_sub);\n      return SASS_MEMORY_NEW(Boolean, pstate, result);\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_selectors.hpp",
    "content": "#ifndef SASS_FN_SELECTORS_H\n#define SASS_FN_SELECTORS_H\n\n#include \"fn_utils.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    #define ARGSEL(argname) get_arg_sel(argname, env, sig, pstate, traces, ctx)\n    #define ARGSELS(argname) get_arg_sels(argname, env, sig, pstate, traces, ctx)\n\n    BUILT_IN(selector_nest);\n    BUILT_IN(selector_append);\n    BUILT_IN(selector_extend);\n    BUILT_IN(selector_replace);\n    BUILT_IN(selector_unify);\n    BUILT_IN(is_superselector);\n    BUILT_IN(simple_selectors);\n    BUILT_IN(selector_parse);\n\n    extern Signature selector_nest_sig;\n    extern Signature selector_append_sig;\n    extern Signature selector_extend_sig;\n    extern Signature selector_replace_sig;\n    extern Signature selector_unify_sig;\n    extern Signature is_superselector_sig;\n    extern Signature simple_selectors_sig;\n    extern Signature selector_parse_sig;\n\n  }\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_strings.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"utf8.h\"\n#include \"ast.hpp\"\n#include \"fn_utils.hpp\"\n#include \"fn_strings.hpp\"\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    void handle_utf8_error (const SourceSpan& pstate, Backtraces traces)\n    {\n      try {\n       throw;\n      }\n      catch (utf8::invalid_code_point&) {\n        sass::string msg(\"utf8::invalid_code_point\");\n        error(msg, pstate, traces);\n      }\n      catch (utf8::not_enough_room&) {\n        sass::string msg(\"utf8::not_enough_room\");\n        error(msg, pstate, traces);\n      }\n      catch (utf8::invalid_utf8&) {\n        sass::string msg(\"utf8::invalid_utf8\");\n        error(msg, pstate, traces);\n      }\n      catch (...) { throw; }\n    }\n\n    ///////////////////\n    // STRING FUNCTIONS\n    ///////////////////\n\n    Signature unquote_sig = \"unquote($string)\";\n    BUILT_IN(sass_unquote)\n    {\n      AST_Node_Obj arg = env[\"$string\"];\n      if (String_Quoted* string_quoted = Cast<String_Quoted>(arg)) {\n        String_Constant* result = SASS_MEMORY_NEW(String_Constant, pstate, string_quoted->value());\n        // remember if the string was quoted (color tokens)\n        result->is_delayed(true); // delay colors\n        return result;\n      }\n      else if (String_Constant* str = Cast<String_Constant>(arg)) {\n        return str;\n      }\n      else if (Value* ex = Cast<Value>(arg)) {\n        Sass_Output_Style oldstyle = ctx.c_options.output_style;\n        ctx.c_options.output_style = SASS_STYLE_NESTED;\n        sass::string val(arg->to_string(ctx.c_options));\n        val = Cast<Null>(arg) ? \"null\" : val;\n        ctx.c_options.output_style = oldstyle;\n\n        deprecated_function(\"Passing \" + val + \", a non-string value, to unquote()\", pstate);\n        return ex;\n      }\n      throw std::runtime_error(\"Invalid Data Type for unquote\");\n    }\n\n    Signature quote_sig = \"quote($string)\";\n    BUILT_IN(sass_quote)\n    {\n      const String_Constant* s = ARG(\"$string\", String_Constant);\n      String_Quoted *result = SASS_MEMORY_NEW(\n          String_Quoted, pstate, s->value(),\n          /*q=*/'\\0', /*keep_utf8_escapes=*/false, /*skip_unquoting=*/true);\n      result->quote_mark('*');\n      return result;\n    }\n\n    Signature str_length_sig = \"str-length($string)\";\n    BUILT_IN(str_length)\n    {\n      size_t len = sass::string::npos;\n      try {\n        String_Constant* s = ARG(\"$string\", String_Constant);\n        len = UTF_8::code_point_count(s->value(), 0, s->value().size());\n\n      }\n      // handle any invalid utf8 errors\n      // other errors will be re-thrown\n      catch (...) { handle_utf8_error(pstate, traces); }\n      // return something even if we had an error (-1)\n      return SASS_MEMORY_NEW(Number, pstate, (double)len);\n    }\n\n    Signature str_insert_sig = \"str-insert($string, $insert, $index)\";\n    BUILT_IN(str_insert)\n    {\n      sass::string str;\n      try {\n        String_Constant* s = ARG(\"$string\", String_Constant);\n        str = s->value();\n        String_Constant* i = ARG(\"$insert\", String_Constant);\n        sass::string ins = i->value();\n        double index = ARGVAL(\"$index\");\n        if (index != (int)index) {\n          sass::ostream strm;\n          strm << \"$index: \";\n          strm << std::to_string(index);\n          strm << \" is not an int\";\n          error(strm.str(), pstate, traces);\n        }\n        size_t len = UTF_8::code_point_count(str, 0, str.size());\n\n        if (index > 0 && index <= len) {\n          // positive and within string length\n          str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index) - 1), ins);\n        }\n        else if (index > len) {\n          // positive and past string length\n          str += ins;\n        }\n        else if (index == 0) {\n          str = ins + str;\n        }\n        else if (std::abs(index) <= len) {\n          // negative and within string length\n          index += len + 1;\n          str.insert(UTF_8::offset_at_position(str, static_cast<size_t>(index)), ins);\n        }\n        else {\n          // negative and past string length\n          str = ins + str;\n        }\n\n        if (String_Quoted* ss = Cast<String_Quoted>(s)) {\n          if (ss->quote_mark()) str = quote(str);\n        }\n      }\n      // handle any invalid utf8 errors\n      // other errors will be re-thrown\n      catch (...) { handle_utf8_error(pstate, traces); }\n      return SASS_MEMORY_NEW(String_Quoted, pstate, str);\n    }\n\n    Signature str_index_sig = \"str-index($string, $substring)\";\n    BUILT_IN(str_index)\n    {\n      size_t index = sass::string::npos;\n      try {\n        String_Constant* s = ARG(\"$string\", String_Constant);\n        String_Constant* t = ARG(\"$substring\", String_Constant);\n        sass::string str = s->value();\n        sass::string substr = t->value();\n\n        size_t c_index = str.find(substr);\n        if(c_index == sass::string::npos) {\n          return SASS_MEMORY_NEW(Null, pstate);\n        }\n        index = UTF_8::code_point_count(str, 0, c_index) + 1;\n      }\n      // handle any invalid utf8 errors\n      // other errors will be re-thrown\n      catch (...) { handle_utf8_error(pstate, traces); }\n      // return something even if we had an error (-1)\n      return SASS_MEMORY_NEW(Number, pstate, (double)index);\n    }\n\n    Signature str_slice_sig = \"str-slice($string, $start-at, $end-at:-1)\";\n    BUILT_IN(str_slice)\n    {\n      sass::string newstr;\n      try {\n        String_Constant* s = ARG(\"$string\", String_Constant);\n        double start_at = ARGVAL(\"$start-at\");\n        double end_at = ARGVAL(\"$end-at\");\n\n        if (start_at != (int)start_at) {\n          sass::ostream strm;\n          strm << \"$start-at: \";\n          strm << std::to_string(start_at);\n          strm << \" is not an int\";\n          error(strm.str(), pstate, traces);\n        }\n\n        String_Quoted* ss = Cast<String_Quoted>(s);\n\n        sass::string str(s->value());\n\n        size_t size = utf8::distance(str.begin(), str.end());\n\n        if (!Cast<Number>(env[\"$end-at\"])) {\n          end_at = -1;\n        }\n\n        if (end_at != (int)end_at) {\n          sass::ostream strm;\n          strm << \"$end-at: \";\n          strm << std::to_string(end_at);\n          strm << \" is not an int\";\n          error(strm.str(), pstate, traces);\n        }\n\n        if (end_at == 0 || (end_at + size) < 0) {\n          if (ss && ss->quote_mark()) newstr = quote(\"\");\n          return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);\n        }\n\n        if (end_at < 0) {\n          end_at += size + 1;\n          if (end_at == 0) end_at = 1;\n        }\n        if (end_at > size) { end_at = (double)size; }\n        if (start_at < 0) {\n          start_at += size + 1;\n          if (start_at <= 0) start_at = 1;\n        }\n        else if (start_at == 0) { ++ start_at; }\n\n        if (start_at <= end_at)\n        {\n          sass::string::iterator start = str.begin();\n          utf8::advance(start, start_at - 1, str.end());\n          sass::string::iterator end = start;\n          utf8::advance(end, end_at - start_at + 1, str.end());\n          newstr = sass::string(start, end);\n        }\n        if (ss) {\n          if(ss->quote_mark()) newstr = quote(newstr);\n        }\n      }\n      // handle any invalid utf8 errors\n      // other errors will be re-thrown\n      catch (...) { handle_utf8_error(pstate, traces); }\n      return SASS_MEMORY_NEW(String_Quoted, pstate, newstr);\n    }\n\n    Signature to_upper_case_sig = \"to-upper-case($string)\";\n    BUILT_IN(to_upper_case)\n    {\n      String_Constant* s = ARG(\"$string\", String_Constant);\n      sass::string str = s->value();\n      Util::ascii_str_toupper(&str);\n\n      if (String_Quoted* ss = Cast<String_Quoted>(s)) {\n        String_Quoted* cpy = SASS_MEMORY_COPY(ss);\n        cpy->value(str);\n        return cpy;\n      } else {\n        return SASS_MEMORY_NEW(String_Quoted, pstate, str);\n      }\n    }\n\n    Signature to_lower_case_sig = \"to-lower-case($string)\";\n    BUILT_IN(to_lower_case)\n    {\n      String_Constant* s = ARG(\"$string\", String_Constant);\n      sass::string str = s->value();\n      Util::ascii_str_tolower(&str);\n\n      if (String_Quoted* ss = Cast<String_Quoted>(s)) {\n        String_Quoted* cpy = SASS_MEMORY_COPY(ss);\n        cpy->value(str);\n        return cpy;\n      } else {\n        return SASS_MEMORY_NEW(String_Quoted, pstate, str);\n      }\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_strings.hpp",
    "content": "#ifndef SASS_FN_STRINGS_H\n#define SASS_FN_STRINGS_H\n\n#include \"fn_utils.hpp\"\n\nnamespace Sass {\n\n  namespace Functions {\n\n    extern Signature unquote_sig;\n    extern Signature quote_sig;\n    extern Signature str_length_sig;\n    extern Signature str_insert_sig;\n    extern Signature str_index_sig;\n    extern Signature str_slice_sig;\n    extern Signature to_upper_case_sig;\n    extern Signature to_lower_case_sig;\n    extern Signature length_sig;\n\n    BUILT_IN(sass_unquote);\n    BUILT_IN(sass_quote);\n    BUILT_IN(str_length);\n    BUILT_IN(str_insert);\n    BUILT_IN(str_index);\n    BUILT_IN(str_slice);\n    BUILT_IN(to_upper_case);\n    BUILT_IN(to_lower_case);\n    BUILT_IN(length);\n\n  }\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_utils.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"parser.hpp\"\n#include \"fn_utils.hpp\"\n#include \"util_string.hpp\"\n\nnamespace Sass {\n\n  Definition* make_native_function(Signature sig, Native_Function func, Context& ctx)\n  {\n    SourceFile* source = SASS_MEMORY_NEW(SourceFile, \"[built-in function]\", sig, std::string::npos);\n    Parser sig_parser(source, ctx, ctx.traces);\n    sig_parser.lex<Prelexer::identifier>();\n    sass::string name(Util::normalize_underscores(sig_parser.lexed));\n    Parameters_Obj params = sig_parser.parse_parameters();\n    return SASS_MEMORY_NEW(Definition,\n                          SourceSpan(source),\n                          sig,\n                          name,\n                          params,\n                          func,\n                          false);\n  }\n\n  Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx)\n  {\n    using namespace Prelexer;\n    const char* sig = sass_function_get_signature(c_func);\n    SourceFile* source = SASS_MEMORY_NEW(SourceFile, \"[c function]\", sig, std::string::npos);\n    Parser sig_parser(source, ctx, ctx.traces);\n    // allow to overload generic callback plus @warn, @error and @debug with custom functions\n    sig_parser.lex < alternatives < identifier, exactly <'*'>,\n                                    exactly < Constants::warn_kwd >,\n                                    exactly < Constants::error_kwd >,\n                                    exactly < Constants::debug_kwd >\n                  >              >();\n    sass::string name(Util::normalize_underscores(sig_parser.lexed));\n    Parameters_Obj params = sig_parser.parse_parameters();\n    return SASS_MEMORY_NEW(Definition,\n                          SourceSpan(source),\n                          sig,\n                          name,\n                          params,\n                          c_func);\n  }\n\n  namespace Functions {\n\n    sass::string function_name(Signature sig)\n    {\n      sass::string str(sig);\n      return str.substr(0, str.find('('));\n    }\n\n    Map* get_arg_m(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)\n    {\n      AST_Node* value = env[argname];\n      if (Map* map = Cast<Map>(value)) return map;\n      List* list = Cast<List>(value);\n      if (list && list->length() == 0) {\n        return SASS_MEMORY_NEW(Map, pstate, 0);\n      }\n      return get_arg<Map>(argname, env, sig, pstate, traces);\n    }\n\n    double get_arg_r(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, double lo, double hi)\n    {\n      Number* val = get_arg<Number>(argname, env, sig, pstate, traces);\n      Number tmpnr(val);\n      tmpnr.reduce();\n      double v = tmpnr.value();\n      if (!(lo <= v && v <= hi)) {\n        sass::ostream msg;\n        msg << \"argument `\" << argname << \"` of `\" << sig << \"` must be between \";\n        msg << lo << \" and \" << hi;\n        error(msg.str(), pstate, traces);\n      }\n      return v;\n    }\n\n    Number* get_arg_n(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)\n    {\n      Number* val = get_arg<Number>(argname, env, sig, pstate, traces);\n      val = SASS_MEMORY_COPY(val);\n      val->reduce();\n      return val;\n    }\n\n    double get_arg_val(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)\n    {\n      Number* val = get_arg<Number>(argname, env, sig, pstate, traces);\n      Number tmpnr(val);\n      tmpnr.reduce();\n      return tmpnr.value();\n    }\n\n    double color_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)\n    {\n      Number* val = get_arg<Number>(argname, env, sig, pstate, traces);\n      Number tmpnr(val);\n      tmpnr.reduce();\n      if (tmpnr.unit() == \"%\") {\n        return std::min(std::max(tmpnr.value() * 255 / 100.0, 0.0), 255.0);\n      } else {\n        return std::min(std::max(tmpnr.value(), 0.0), 255.0);\n      }\n    }\n\n    double alpha_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces) {\n      Number* val = get_arg<Number>(argname, env, sig, pstate, traces);\n      Number tmpnr(val);\n      tmpnr.reduce();\n      if (tmpnr.unit() == \"%\") {\n        return std::min(std::max(tmpnr.value(), 0.0), 100.0);\n      } else {\n        return std::min(std::max(tmpnr.value(), 0.0), 1.0);\n      }\n    }\n\n    SelectorListObj get_arg_sels(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx) {\n      ExpressionObj exp = ARG(argname, Expression);\n      if (exp->concrete_type() == Expression::NULL_VAL) {\n        sass::ostream msg;\n        msg << argname << \": null is not a valid selector: it must be a string,\\n\";\n        msg << \"a list of strings, or a list of lists of strings for `\" << function_name(sig) << \"'\";\n        error(msg.str(), exp->pstate(), traces);\n      }\n      if (String_Constant* str = Cast<String_Constant>(exp)) {\n        str->quote_mark(0);\n      }\n      sass::string exp_src = exp->to_string(ctx.c_options);\n      ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());\n      return Parser::parse_selector(source, ctx, traces, false);\n    }\n\n    CompoundSelectorObj get_arg_sel(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx) {\n      ExpressionObj exp = ARG(argname, Expression);\n      if (exp->concrete_type() == Expression::NULL_VAL) {\n        sass::ostream msg;\n        msg << argname << \": null is not a string for `\" << function_name(sig) << \"'\";\n        error(msg.str(), exp->pstate(), traces);\n      }\n      if (String_Constant* str = Cast<String_Constant>(exp)) {\n        str->quote_mark(0);\n      }\n      sass::string exp_src = exp->to_string(ctx.c_options);\n      ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());\n      SelectorListObj sel_list = Parser::parse_selector(source, ctx, traces, false);\n      if (sel_list->length() == 0) return {};\n      return sel_list->first()->first();\n    }\n\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/fn_utils.hpp",
    "content": "#ifndef SASS_FN_UTILS_H\n#define SASS_FN_UTILS_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"units.hpp\"\n#include \"backtrace.hpp\"\n#include \"environment.hpp\"\n#include \"ast_fwd_decl.hpp\"\n#include \"error_handling.hpp\"\n\nnamespace Sass {\n\n  #define FN_PROTOTYPE \\\n    Env& env, \\\n    Env& d_env, \\\n    Context& ctx, \\\n    Signature sig, \\\n    SourceSpan pstate, \\\n    Backtraces& traces, \\\n    SelectorStack selector_stack, \\\n    SelectorStack original_stack \\\n\n  typedef const char* Signature;\n  typedef PreValue* (*Native_Function)(FN_PROTOTYPE);\n  #define BUILT_IN(name) PreValue* name(FN_PROTOTYPE)\n\n  #define ARG(argname, argtype) get_arg<argtype>(argname, env, sig, pstate, traces)\n  // special function for weird hsla percent (10px == 10% == 10 != 0.1)\n  #define ARGVAL(argname) get_arg_val(argname, env, sig, pstate, traces) // double\n\n  Definition* make_native_function(Signature, Native_Function, Context& ctx);\n  Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx);\n\n  namespace Functions {\n\n    template <typename T>\n    T* get_arg(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)\n    {\n      T* val = Cast<T>(env[argname]);\n      if (!val) {\n        error(\"argument `\" + argname + \"` of `\" + sig + \"` must be a \" + T::type_name(), pstate, traces);\n      }\n      return val;\n    }\n\n    Map* get_arg_m(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // maps only\n    Number* get_arg_n(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // numbers only\n    double alpha_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // colors only\n    double color_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // colors only\n    double get_arg_r(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, double lo, double hi); // colors only\n    double get_arg_val(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // shared\n    SelectorListObj get_arg_sels(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx); // selectors only\n    CompoundSelectorObj get_arg_sel(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx); // selectors only\n\n  }\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/include/sass/base.h",
    "content": "#ifndef SASS_BASE_H\n#define SASS_BASE_H\n\n// #define DEBUG\n// #define DEBUG_SHARED_PTR\n\n#ifdef _MSC_VER\n  #pragma warning(disable : 4503)\n  #ifndef _SCL_SECURE_NO_WARNINGS\n    #define _SCL_SECURE_NO_WARNINGS\n  #endif\n  #ifndef _CRT_SECURE_NO_WARNINGS\n    #define _CRT_SECURE_NO_WARNINGS\n  #endif\n  #ifndef _CRT_NONSTDC_NO_DEPRECATE\n    #define _CRT_NONSTDC_NO_DEPRECATE\n  #endif\n#endif\n\n// Work around lack of `noexcept` keyword support in VS2013\n#if defined(_MSC_VER) && (_MSC_VER <= 1800) && !defined(_ALLOW_KEYWORD_MACROS)\n#define _ALLOW_KEYWORD_MACROS 1\n#define noexcept throw( )\n#endif\n\n#include <stddef.h>\n#include <stdbool.h>\n\n#ifdef __GNUC__\n  #define DEPRECATED(func) func __attribute__ ((deprecated))\n#elif defined(_MSC_VER)\n  #define DEPRECATED(func) __declspec(deprecated) func\n#else\n  #pragma message(\"WARNING: You need to implement DEPRECATED for this compiler\")\n  #define DEPRECATED(func) func\n#endif\n\n#ifdef _WIN32\n\n  /* You should define ADD_EXPORTS *only* when building the DLL. */\n  #ifdef ADD_EXPORTS\n    #define ADDAPI __declspec(dllexport)\n    #define ADDCALL __cdecl\n  #else\n    #define ADDAPI\n    #define ADDCALL\n  #endif\n\n#else /* _WIN32 not defined. */\n\n  /* Define with no value on non-Windows OSes. */\n  #define ADDAPI\n  #define ADDCALL\n\n#endif\n\n/* Make sure functions are exported with C linkage under C++ compilers. */\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n// Different render styles\nenum Sass_Output_Style {\n  SASS_STYLE_NESTED,\n  SASS_STYLE_EXPANDED,\n  SASS_STYLE_COMPACT,\n  SASS_STYLE_COMPRESSED,\n  // only used internaly\n  SASS_STYLE_INSPECT,\n  SASS_STYLE_TO_SASS,\n  SASS_STYLE_TO_CSS\n};\n\n// to allocate buffer to be filled\nADDAPI void* ADDCALL sass_alloc_memory(size_t size);\n// to allocate a buffer from existing string\nADDAPI char* ADDCALL sass_copy_c_string(const char* str);\n// to free overtaken memory when done\nADDAPI void ADDCALL sass_free_memory(void* ptr);\n\n// Some convenient string helper function\nADDAPI char* ADDCALL sass_string_quote (const char* str, const char quote_mark);\nADDAPI char* ADDCALL sass_string_unquote (const char* str);\n\n// Implemented sass language version\n// Hardcoded version 3.4 for time being\nADDAPI const char* ADDCALL libsass_version(void);\n\n// Get compiled libsass language\nADDAPI const char* ADDCALL libsass_language_version(void);\n\n#ifdef __cplusplus\n} // __cplusplus defined.\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/include/sass/context.h",
    "content": "#ifndef SASS_C_CONTEXT_H\n#define SASS_C_CONTEXT_H\n\n#include <stddef.h>\n#include <stdbool.h>\n#include <sass/base.h>\n#include <sass/values.h>\n#include <sass/functions.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n// Forward declaration\nstruct Sass_Compiler;\n\n// Forward declaration\nstruct Sass_Options; // base struct\nstruct Sass_Context; // : Sass_Options\nstruct Sass_File_Context; // : Sass_Context\nstruct Sass_Data_Context; // : Sass_Context\n\n// Compiler states\nenum Sass_Compiler_State {\n  SASS_COMPILER_CREATED,\n  SASS_COMPILER_PARSED,\n  SASS_COMPILER_EXECUTED\n};\n\n// Create and initialize an option struct\nADDAPI struct Sass_Options* ADDCALL sass_make_options (void);\n// Create and initialize a specific context\nADDAPI struct Sass_File_Context* ADDCALL sass_make_file_context (const char* input_path);\nADDAPI struct Sass_Data_Context* ADDCALL sass_make_data_context (char* source_string);\n\n// Call the compilation step for the specific context\nADDAPI int ADDCALL sass_compile_file_context (struct Sass_File_Context* ctx);\nADDAPI int ADDCALL sass_compile_data_context (struct Sass_Data_Context* ctx);\n\n// Create a sass compiler instance for more control\nADDAPI struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* file_ctx);\nADDAPI struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx);\n\n// Execute the different compilation steps individually\n// Useful if you only want to query the included files\nADDAPI int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler);\nADDAPI int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler);\n\n// Release all memory allocated with the compiler\n// This does _not_ include any contexts or options\nADDAPI void ADDCALL sass_delete_compiler(struct Sass_Compiler* compiler);\nADDAPI void ADDCALL sass_delete_options(struct Sass_Options* options);\n\n// Release all memory allocated and also ourself\nADDAPI void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx);\nADDAPI void ADDCALL sass_delete_data_context (struct Sass_Data_Context* ctx);\n\n// Getters for context from specific implementation\nADDAPI struct Sass_Context* ADDCALL sass_file_context_get_context (struct Sass_File_Context* file_ctx);\nADDAPI struct Sass_Context* ADDCALL sass_data_context_get_context (struct Sass_Data_Context* data_ctx);\n\n// Getters for Context_Options from Sass_Context\nADDAPI struct Sass_Options* ADDCALL sass_context_get_options (struct Sass_Context* ctx);\nADDAPI struct Sass_Options* ADDCALL sass_file_context_get_options (struct Sass_File_Context* file_ctx);\nADDAPI struct Sass_Options* ADDCALL sass_data_context_get_options (struct Sass_Data_Context* data_ctx);\nADDAPI void ADDCALL sass_file_context_set_options (struct Sass_File_Context* file_ctx, struct Sass_Options* opt);\nADDAPI void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* data_ctx, struct Sass_Options* opt);\n\n\n// Getters for Context_Option values\nADDAPI int ADDCALL sass_option_get_precision (struct Sass_Options* options);\nADDAPI enum Sass_Output_Style ADDCALL sass_option_get_output_style (struct Sass_Options* options);\nADDAPI bool ADDCALL sass_option_get_source_comments (struct Sass_Options* options);\nADDAPI bool ADDCALL sass_option_get_source_map_embed (struct Sass_Options* options);\nADDAPI bool ADDCALL sass_option_get_source_map_contents (struct Sass_Options* options);\nADDAPI bool ADDCALL sass_option_get_source_map_file_urls (struct Sass_Options* options);\nADDAPI bool ADDCALL sass_option_get_omit_source_map_url (struct Sass_Options* options);\nADDAPI bool ADDCALL sass_option_get_is_indented_syntax_src (struct Sass_Options* options);\nADDAPI const char* ADDCALL sass_option_get_indent (struct Sass_Options* options);\nADDAPI const char* ADDCALL sass_option_get_linefeed (struct Sass_Options* options);\nADDAPI const char* ADDCALL sass_option_get_input_path (struct Sass_Options* options);\nADDAPI const char* ADDCALL sass_option_get_output_path (struct Sass_Options* options);\nADDAPI const char* ADDCALL sass_option_get_source_map_file (struct Sass_Options* options);\nADDAPI const char* ADDCALL sass_option_get_source_map_root (struct Sass_Options* options);\nADDAPI Sass_Importer_List ADDCALL sass_option_get_c_headers (struct Sass_Options* options);\nADDAPI Sass_Importer_List ADDCALL sass_option_get_c_importers (struct Sass_Options* options);\nADDAPI Sass_Function_List ADDCALL sass_option_get_c_functions (struct Sass_Options* options);\n\n// Setters for Context_Option values\nADDAPI void ADDCALL sass_option_set_precision (struct Sass_Options* options, int precision);\nADDAPI void ADDCALL sass_option_set_output_style (struct Sass_Options* options, enum Sass_Output_Style output_style);\nADDAPI void ADDCALL sass_option_set_source_comments (struct Sass_Options* options, bool source_comments);\nADDAPI void ADDCALL sass_option_set_source_map_embed (struct Sass_Options* options, bool source_map_embed);\nADDAPI void ADDCALL sass_option_set_source_map_contents (struct Sass_Options* options, bool source_map_contents);\nADDAPI void ADDCALL sass_option_set_source_map_file_urls (struct Sass_Options* options, bool source_map_file_urls);\nADDAPI void ADDCALL sass_option_set_omit_source_map_url (struct Sass_Options* options, bool omit_source_map_url);\nADDAPI void ADDCALL sass_option_set_is_indented_syntax_src (struct Sass_Options* options, bool is_indented_syntax_src);\nADDAPI void ADDCALL sass_option_set_indent (struct Sass_Options* options, const char* indent);\nADDAPI void ADDCALL sass_option_set_linefeed (struct Sass_Options* options, const char* linefeed);\nADDAPI void ADDCALL sass_option_set_input_path (struct Sass_Options* options, const char* input_path);\nADDAPI void ADDCALL sass_option_set_output_path (struct Sass_Options* options, const char* output_path);\nADDAPI void ADDCALL sass_option_set_plugin_path (struct Sass_Options* options, const char* plugin_path);\nADDAPI void ADDCALL sass_option_set_include_path (struct Sass_Options* options, const char* include_path);\nADDAPI void ADDCALL sass_option_set_source_map_file (struct Sass_Options* options, const char* source_map_file);\nADDAPI void ADDCALL sass_option_set_source_map_root (struct Sass_Options* options, const char* source_map_root);\nADDAPI void ADDCALL sass_option_set_c_headers (struct Sass_Options* options, Sass_Importer_List c_headers);\nADDAPI void ADDCALL sass_option_set_c_importers (struct Sass_Options* options, Sass_Importer_List c_importers);\nADDAPI void ADDCALL sass_option_set_c_functions (struct Sass_Options* options, Sass_Function_List c_functions);\n\n\n// Getters for Sass_Context values\nADDAPI const char* ADDCALL sass_context_get_output_string (struct Sass_Context* ctx);\nADDAPI int ADDCALL sass_context_get_error_status (struct Sass_Context* ctx);\nADDAPI const char* ADDCALL sass_context_get_error_json (struct Sass_Context* ctx);\nADDAPI const char* ADDCALL sass_context_get_error_text (struct Sass_Context* ctx);\nADDAPI const char* ADDCALL sass_context_get_error_message (struct Sass_Context* ctx);\nADDAPI const char* ADDCALL sass_context_get_error_file (struct Sass_Context* ctx);\nADDAPI const char* ADDCALL sass_context_get_error_src (struct Sass_Context* ctx);\nADDAPI size_t ADDCALL sass_context_get_error_line (struct Sass_Context* ctx);\nADDAPI size_t ADDCALL sass_context_get_error_column (struct Sass_Context* ctx);\nADDAPI const char* ADDCALL sass_context_get_source_map_string (struct Sass_Context* ctx);\nADDAPI char** ADDCALL sass_context_get_included_files (struct Sass_Context* ctx);\n\n// Getters for options include path array\nADDAPI size_t ADDCALL sass_option_get_include_path_size(struct Sass_Options* options);\nADDAPI const char* ADDCALL sass_option_get_include_path(struct Sass_Options* options, size_t i);\n// Plugin paths to load dynamic libraries work the same\nADDAPI size_t ADDCALL sass_option_get_plugin_path_size(struct Sass_Options* options);\nADDAPI const char* ADDCALL sass_option_get_plugin_path(struct Sass_Options* options, size_t i);\n\n// Calculate the size of the stored null terminated array\nADDAPI size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx);\n\n// Take ownership of memory (value on context is set to 0)\nADDAPI char* ADDCALL sass_context_take_error_json (struct Sass_Context* ctx);\nADDAPI char* ADDCALL sass_context_take_error_text (struct Sass_Context* ctx);\nADDAPI char* ADDCALL sass_context_take_error_message (struct Sass_Context* ctx);\nADDAPI char* ADDCALL sass_context_take_error_file (struct Sass_Context* ctx);\nADDAPI char* ADDCALL sass_context_take_error_src (struct Sass_Context* ctx);\nADDAPI char* ADDCALL sass_context_take_output_string (struct Sass_Context* ctx);\nADDAPI char* ADDCALL sass_context_take_source_map_string (struct Sass_Context* ctx);\nADDAPI char** ADDCALL sass_context_take_included_files (struct Sass_Context* ctx);\n\n// Getters for Sass_Compiler options\nADDAPI enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler);\nADDAPI struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler);\nADDAPI struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compiler* compiler);\nADDAPI size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler);\nADDAPI Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler);\nADDAPI Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx);\nADDAPI size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler);\nADDAPI Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler);\nADDAPI Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx);\n\n// Push function for paths (no manipulation support for now)\nADDAPI void ADDCALL sass_option_push_plugin_path (struct Sass_Options* options, const char* path);\nADDAPI void ADDCALL sass_option_push_include_path (struct Sass_Options* options, const char* path);\n\n// Resolve a file via the given include paths in the sass option struct\n// find_file looks for the exact file name while find_include does a regular sass include\nADDAPI char* ADDCALL sass_find_file (const char* path, struct Sass_Options* opt);\nADDAPI char* ADDCALL sass_find_include (const char* path, struct Sass_Options* opt);\n\n// Resolve a file relative to last import or include paths in the sass option struct\n// find_file looks for the exact file name while find_include does a regular sass include\nADDAPI char* ADDCALL sass_compiler_find_file (const char* path, struct Sass_Compiler* compiler);\nADDAPI char* ADDCALL sass_compiler_find_include (const char* path, struct Sass_Compiler* compiler);\n\n#ifdef __cplusplus\n} // __cplusplus defined.\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/include/sass/functions.h",
    "content": "#ifndef SASS_C_FUNCTIONS_H\n#define SASS_C_FUNCTIONS_H\n\n#include <stddef.h>\n#include <stdbool.h>\n#include <sass/base.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n// Forward declaration\nstruct Sass_Env;\nstruct Sass_Callee;\nstruct Sass_Import;\nstruct Sass_Options;\nstruct Sass_Compiler;\nstruct Sass_Importer;\nstruct Sass_Function;\n\n// Typedef helpers for callee lists\ntypedef struct Sass_Env (*Sass_Env_Frame);\n// Typedef helpers for callee lists\ntypedef struct Sass_Callee (*Sass_Callee_Entry);\n// Typedef helpers for import lists\ntypedef struct Sass_Import (*Sass_Import_Entry);\ntypedef struct Sass_Import* (*Sass_Import_List);\n// Typedef helpers for custom importer lists\ntypedef struct Sass_Importer (*Sass_Importer_Entry);\ntypedef struct Sass_Importer* (*Sass_Importer_List);\n// Typedef defining importer signature and return type\ntypedef Sass_Import_List (*Sass_Importer_Fn)\n  (const char* url, Sass_Importer_Entry cb, struct Sass_Compiler* compiler);\n\n// Typedef helpers for custom functions lists\ntypedef struct Sass_Function (*Sass_Function_Entry);\ntypedef struct Sass_Function* (*Sass_Function_List);\n// Typedef defining function signature and return type\ntypedef union Sass_Value* (*Sass_Function_Fn)\n  (const union Sass_Value*, Sass_Function_Entry cb, struct Sass_Compiler* compiler);\n\n// Type of function calls\nenum Sass_Callee_Type {\n  SASS_CALLEE_MIXIN,\n  SASS_CALLEE_FUNCTION,\n  SASS_CALLEE_C_FUNCTION,\n};\n\n// Creator for sass custom importer return argument list\nADDAPI Sass_Importer_List ADDCALL sass_make_importer_list (size_t length);\nADDAPI Sass_Importer_Entry ADDCALL sass_importer_get_list_entry (Sass_Importer_List list, size_t idx);\nADDAPI void ADDCALL sass_importer_set_list_entry (Sass_Importer_List list, size_t idx, Sass_Importer_Entry entry);\nADDAPI void ADDCALL sass_delete_importer_list (Sass_Importer_List list);\n\n\n// Creators for custom importer callback (with some additional pointer)\n// The pointer is mostly used to store the callback into the actual binding\nADDAPI Sass_Importer_Entry ADDCALL sass_make_importer (Sass_Importer_Fn importer, double priority, void* cookie);\n\n// Getters for import function descriptors\nADDAPI Sass_Importer_Fn ADDCALL sass_importer_get_function (Sass_Importer_Entry cb);\nADDAPI double ADDCALL sass_importer_get_priority (Sass_Importer_Entry cb);\nADDAPI void* ADDCALL sass_importer_get_cookie (Sass_Importer_Entry cb);\n\n// Deallocator for associated memory\nADDAPI void ADDCALL sass_delete_importer (Sass_Importer_Entry cb);\n\n// Creator for sass custom importer return argument list\nADDAPI Sass_Import_List ADDCALL sass_make_import_list (size_t length);\n// Creator for a single import entry returned by the custom importer inside the list\nADDAPI Sass_Import_Entry ADDCALL sass_make_import_entry (const char* path, char* source, char* srcmap);\nADDAPI Sass_Import_Entry ADDCALL sass_make_import (const char* imp_path, const char* abs_base, char* source, char* srcmap);\n// set error message to abort import and to print out a message (path from existing object is used in output)\nADDAPI Sass_Import_Entry ADDCALL sass_import_set_error(Sass_Import_Entry import, const char* message, size_t line, size_t col);\n\n// Setters to insert an entry into the import list (you may also use [] access directly)\n// Since we are dealing with pointers they should have a guaranteed and fixed size\nADDAPI void ADDCALL sass_import_set_list_entry (Sass_Import_List list, size_t idx, Sass_Import_Entry entry);\nADDAPI Sass_Import_Entry ADDCALL sass_import_get_list_entry (Sass_Import_List list, size_t idx);\n\n// Getters for callee entry\nADDAPI const char* ADDCALL sass_callee_get_name (Sass_Callee_Entry);\nADDAPI const char* ADDCALL sass_callee_get_path (Sass_Callee_Entry);\nADDAPI size_t ADDCALL sass_callee_get_line (Sass_Callee_Entry);\nADDAPI size_t ADDCALL sass_callee_get_column (Sass_Callee_Entry);\nADDAPI enum Sass_Callee_Type ADDCALL sass_callee_get_type (Sass_Callee_Entry);\nADDAPI Sass_Env_Frame ADDCALL sass_callee_get_env (Sass_Callee_Entry);\n\n// Getters and Setters for environments (lexical, local and global)\nADDAPI union Sass_Value* ADDCALL sass_env_get_lexical (Sass_Env_Frame, const char*);\nADDAPI void ADDCALL sass_env_set_lexical (Sass_Env_Frame, const char*, union Sass_Value*);\nADDAPI union Sass_Value* ADDCALL sass_env_get_local (Sass_Env_Frame, const char*);\nADDAPI void ADDCALL sass_env_set_local (Sass_Env_Frame, const char*, union Sass_Value*);\nADDAPI union Sass_Value* ADDCALL sass_env_get_global (Sass_Env_Frame, const char*);\nADDAPI void ADDCALL sass_env_set_global (Sass_Env_Frame, const char*, union Sass_Value*);\n\n// Getters for import entry\nADDAPI const char* ADDCALL sass_import_get_imp_path (Sass_Import_Entry);\nADDAPI const char* ADDCALL sass_import_get_abs_path (Sass_Import_Entry);\nADDAPI const char* ADDCALL sass_import_get_source (Sass_Import_Entry);\nADDAPI const char* ADDCALL sass_import_get_srcmap (Sass_Import_Entry);\n// Explicit functions to take ownership of these items\n// The property on our struct will be reset to NULL\nADDAPI char* ADDCALL sass_import_take_source (Sass_Import_Entry);\nADDAPI char* ADDCALL sass_import_take_srcmap (Sass_Import_Entry);\n// Getters from import error entry\nADDAPI size_t ADDCALL sass_import_get_error_line (Sass_Import_Entry);\nADDAPI size_t ADDCALL sass_import_get_error_column (Sass_Import_Entry);\nADDAPI const char* ADDCALL sass_import_get_error_message (Sass_Import_Entry);\n\n// Deallocator for associated memory (incl. entries)\nADDAPI void ADDCALL sass_delete_import_list (Sass_Import_List);\n// Just in case we have some stray import structs\nADDAPI void ADDCALL sass_delete_import (Sass_Import_Entry);\n\n\n\n// Creators for sass function list and function descriptors\nADDAPI Sass_Function_List ADDCALL sass_make_function_list (size_t length);\nADDAPI Sass_Function_Entry ADDCALL sass_make_function (const char* signature, Sass_Function_Fn cb, void* cookie);\nADDAPI void ADDCALL sass_delete_function (Sass_Function_Entry entry);\nADDAPI void ADDCALL sass_delete_function_list (Sass_Function_List list);\n\n// Setters and getters for callbacks on function lists\nADDAPI Sass_Function_Entry ADDCALL sass_function_get_list_entry(Sass_Function_List list, size_t pos);\nADDAPI void ADDCALL sass_function_set_list_entry(Sass_Function_List list, size_t pos, Sass_Function_Entry cb);\n\n// Getters for custom function descriptors\nADDAPI const char* ADDCALL sass_function_get_signature (Sass_Function_Entry cb);\nADDAPI Sass_Function_Fn ADDCALL sass_function_get_function (Sass_Function_Entry cb);\nADDAPI void* ADDCALL sass_function_get_cookie (Sass_Function_Entry cb);\n\n\n#ifdef __cplusplus\n} // __cplusplus defined.\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/include/sass/values.h",
    "content": "#ifndef SASS_C_VALUES_H\n#define SASS_C_VALUES_H\n\n#include <stddef.h>\n#include <stdbool.h>\n#include <sass/base.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n\n// Forward declaration\nunion Sass_Value;\n\n// Type for Sass values\nenum Sass_Tag {\n  SASS_BOOLEAN,\n  SASS_NUMBER,\n  SASS_COLOR,\n  SASS_STRING,\n  SASS_LIST,\n  SASS_MAP,\n  SASS_NULL,\n  SASS_ERROR,\n  SASS_WARNING\n};\n\n// Tags for denoting Sass list separators\nenum Sass_Separator {\n  SASS_COMMA,\n  SASS_SPACE,\n  // only used internally to represent a hash map before evaluation\n  // otherwise we would be too early to check for duplicate keys\n  SASS_HASH\n};\n\n// Value Operators\nenum Sass_OP {\n  AND, OR,                   // logical connectives\n  EQ, NEQ, GT, GTE, LT, LTE, // arithmetic relations\n  ADD, SUB, MUL, DIV, MOD,   // arithmetic functions\n  NUM_OPS                    // so we know how big to make the op table\n};\n\n// Creator functions for all value types\nADDAPI union Sass_Value* ADDCALL sass_make_null    (void);\nADDAPI union Sass_Value* ADDCALL sass_make_boolean (bool val);\nADDAPI union Sass_Value* ADDCALL sass_make_string  (const char* val);\nADDAPI union Sass_Value* ADDCALL sass_make_qstring (const char* val);\nADDAPI union Sass_Value* ADDCALL sass_make_number  (double val, const char* unit);\nADDAPI union Sass_Value* ADDCALL sass_make_color   (double r, double g, double b, double a);\nADDAPI union Sass_Value* ADDCALL sass_make_list    (size_t len, enum Sass_Separator sep, bool is_bracketed);\nADDAPI union Sass_Value* ADDCALL sass_make_map     (size_t len);\nADDAPI union Sass_Value* ADDCALL sass_make_error   (const char* msg);\nADDAPI union Sass_Value* ADDCALL sass_make_warning (const char* msg);\n\n// Generic destructor function for all types\n// Will release memory of all associated Sass_Values\n// Means we will delete recursively for lists and maps\nADDAPI void ADDCALL sass_delete_value (union Sass_Value* val);\n\n// Make a deep cloned copy of the given sass value\nADDAPI union Sass_Value* ADDCALL sass_clone_value (const union Sass_Value* val);\n\n// Execute an operation for two Sass_Values and return the result as a Sass_Value too\nADDAPI union Sass_Value* ADDCALL sass_value_op (enum Sass_OP op, const union Sass_Value* a, const union Sass_Value* b);\n\n// Stringify a Sass_Values and also return the result as a Sass_Value (of type STRING)\nADDAPI union Sass_Value* ADDCALL sass_value_stringify (const union Sass_Value* a, bool compressed, int precision);\n\n// Return the sass tag for a generic sass value\n// Check is needed before accessing specific values!\nADDAPI enum Sass_Tag ADDCALL sass_value_get_tag (const union Sass_Value* v);\n\n// Check value to be of a specific type\n// Can also be used before accessing properties!\nADDAPI bool ADDCALL sass_value_is_null (const union Sass_Value* v);\nADDAPI bool ADDCALL sass_value_is_number (const union Sass_Value* v);\nADDAPI bool ADDCALL sass_value_is_string (const union Sass_Value* v);\nADDAPI bool ADDCALL sass_value_is_boolean (const union Sass_Value* v);\nADDAPI bool ADDCALL sass_value_is_color (const union Sass_Value* v);\nADDAPI bool ADDCALL sass_value_is_list (const union Sass_Value* v);\nADDAPI bool ADDCALL sass_value_is_map (const union Sass_Value* v);\nADDAPI bool ADDCALL sass_value_is_error (const union Sass_Value* v);\nADDAPI bool ADDCALL sass_value_is_warning (const union Sass_Value* v);\n\n// Getters and setters for Sass_Number\nADDAPI double ADDCALL sass_number_get_value (const union Sass_Value* v);\nADDAPI void ADDCALL sass_number_set_value (union Sass_Value* v, double value);\nADDAPI const char* ADDCALL sass_number_get_unit (const union Sass_Value* v);\nADDAPI void ADDCALL sass_number_set_unit (union Sass_Value* v, char* unit);\n\n// Getters and setters for Sass_String\nADDAPI const char* ADDCALL sass_string_get_value (const union Sass_Value* v);\nADDAPI void ADDCALL sass_string_set_value (union Sass_Value* v, char* value);\nADDAPI bool ADDCALL sass_string_is_quoted(const union Sass_Value* v);\nADDAPI void ADDCALL sass_string_set_quoted(union Sass_Value* v, bool quoted);\n\n// Getters and setters for Sass_Boolean\nADDAPI bool ADDCALL sass_boolean_get_value (const union Sass_Value* v);\nADDAPI void ADDCALL sass_boolean_set_value (union Sass_Value* v, bool value);\n\n// Getters and setters for Sass_Color\nADDAPI double ADDCALL sass_color_get_r (const union Sass_Value* v);\nADDAPI void ADDCALL sass_color_set_r (union Sass_Value* v, double r);\nADDAPI double ADDCALL sass_color_get_g (const union Sass_Value* v);\nADDAPI void ADDCALL sass_color_set_g (union Sass_Value* v, double g);\nADDAPI double ADDCALL sass_color_get_b (const union Sass_Value* v);\nADDAPI void ADDCALL sass_color_set_b (union Sass_Value* v, double b);\nADDAPI double ADDCALL sass_color_get_a (const union Sass_Value* v);\nADDAPI void ADDCALL sass_color_set_a (union Sass_Value* v, double a);\n\n// Getter for the number of items in list\nADDAPI size_t ADDCALL sass_list_get_length (const union Sass_Value* v);\n// Getters and setters for Sass_List\nADDAPI enum Sass_Separator ADDCALL sass_list_get_separator (const union Sass_Value* v);\nADDAPI void ADDCALL sass_list_set_separator (union Sass_Value* v, enum Sass_Separator value);\nADDAPI bool ADDCALL sass_list_get_is_bracketed (const union Sass_Value* v);\nADDAPI void ADDCALL sass_list_set_is_bracketed (union Sass_Value* v, bool value);\n// Getters and setters for Sass_List values\nADDAPI union Sass_Value* ADDCALL sass_list_get_value (const union Sass_Value* v, size_t i);\nADDAPI void ADDCALL sass_list_set_value (union Sass_Value* v, size_t i, union Sass_Value* value);\n\n// Getter for the number of items in map\nADDAPI size_t ADDCALL sass_map_get_length (const union Sass_Value* v);\n// Getters and setters for Sass_Map keys and values\nADDAPI union Sass_Value* ADDCALL sass_map_get_key (const union Sass_Value* v, size_t i);\nADDAPI void ADDCALL sass_map_set_key (union Sass_Value* v, size_t i, union Sass_Value*);\nADDAPI union Sass_Value* ADDCALL sass_map_get_value (const union Sass_Value* v, size_t i);\nADDAPI void ADDCALL sass_map_set_value (union Sass_Value* v, size_t i, union Sass_Value*);\n\n// Getters and setters for Sass_Error\nADDAPI char* ADDCALL sass_error_get_message (const union Sass_Value* v);\nADDAPI void ADDCALL sass_error_set_message (union Sass_Value* v, char* msg);\n\n// Getters and setters for Sass_Warning\nADDAPI char* ADDCALL sass_warning_get_message (const union Sass_Value* v);\nADDAPI void ADDCALL sass_warning_set_message (union Sass_Value* v, char* msg);\n\n#ifdef __cplusplus\n} // __cplusplus defined.\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/include/sass/version.h",
    "content": "#ifndef SASS_VERSION_H\n#define SASS_VERSION_H\n\n#ifndef LIBSASS_VERSION\n#define LIBSASS_VERSION \"[NA]\"\n#endif\n\n#ifndef LIBSASS_LANGUAGE_VERSION\n#define LIBSASS_LANGUAGE_VERSION \"3.5\"\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/include/sass/version.h.in",
    "content": "#ifndef SASS_VERSION_H\n#define SASS_VERSION_H\n\n#ifndef LIBSASS_VERSION\n#define LIBSASS_VERSION \"@PACKAGE_VERSION@\"\n#endif\n\n#ifndef LIBSASS_LANGUAGE_VERSION\n#define LIBSASS_LANGUAGE_VERSION \"3.5\"\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/include/sass.h",
    "content": "#ifndef SASS_H\n#define SASS_H\n\n// #define DEBUG 1\n\n// include API headers\n#include <sass/base.h>\n#include <sass/version.h>\n#include <sass/values.h>\n#include <sass/functions.h>\n#include <sass/context.h>\n#include <sass2scss.h>\n\n#endif\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/include/sass2scss.h",
    "content": "/**\n * sass2scss\n * Licensed under the MIT License\n * Copyright (c) Marcel Greter\n */\n\n#ifndef SASS2SCSS_H\n#define SASS2SCSS_H\n\n#ifdef _WIN32\n\n  /* You should define ADD_EXPORTS *only* when building the DLL. */\n  #ifdef ADD_EXPORTS\n    #define ADDAPI __declspec(dllexport)\n\t#define ADDCALL __cdecl\n  #else\n    #define ADDAPI\n\t#define ADDCALL\n  #endif\n\n#else /* _WIN32 not defined. */\n\n  /* Define with no value on non-Windows OSes. */\n  #define ADDAPI\n  #define ADDCALL\n\n#endif\n\n#ifdef __cplusplus\n\n#include <stack>\n#include <string>\n#include <cstring>\n#include <sstream>\n#include <iostream>\n\n#ifndef SASS2SCSS_VERSION\n// Hardcode once the file is copied from\n// https://github.com/mgreter/sass2scss\n#define SASS2SCSS_VERSION \"1.1.1\"\n#endif\n\n// add namespace for c++\nnamespace Sass\n{\n\n\t// pretty print options\n\tconst int SASS2SCSS_PRETTIFY_0 = 0;\n\tconst int SASS2SCSS_PRETTIFY_1 = 1;\n\tconst int SASS2SCSS_PRETTIFY_2 = 2;\n\tconst int SASS2SCSS_PRETTIFY_3 = 3;\n\n\t// remove one-line comment\n\tconst int SASS2SCSS_KEEP_COMMENT    =  32;\n\t// remove multi-line comments\n\tconst int SASS2SCSS_STRIP_COMMENT   =  64;\n\t// convert one-line to multi-line\n\tconst int SASS2SCSS_CONVERT_COMMENT = 128;\n\n\t// String for finding something interesting\n\tconst std::string SASS2SCSS_FIND_WHITESPACE = \" \\t\\n\\v\\f\\r\";\n\n\t// converter struct\n\t// holding all states\n\tstruct converter\n\t{\n\t\t// bit options\n\t\tint options;\n\t\t// is selector\n\t\tbool selector;\n\t\t// concat lists\n\t\tbool comma;\n\t\t// has property\n\t\tbool property;\n\t\t// has semicolon\n\t\tbool semicolon;\n\t\t// comment context\n\t\tstd::string comment;\n\t\t// flag end of file\n\t\tbool end_of_file;\n\t\t// whitespace buffer\n\t\tstd::string whitespace;\n\t\t// context/block stack\n\t\tstd::stack<std::string> indents;\n\t};\n\n\t// function only available in c++ code\n\tchar* sass2scss (const std::string& sass, const int options);\n\n}\n// EO namespace\n\n// declare for c\nextern \"C\" {\n#endif\n\n\t// prettyfy print options\n\t#define SASS2SCSS_PRETTIFY_0   0\n\t#define SASS2SCSS_PRETTIFY_1   1\n\t#define SASS2SCSS_PRETTIFY_2   2\n\t#define SASS2SCSS_PRETTIFY_3   3\n\n\t// keep one-line comments\n\t#define SASS2SCSS_KEEP_COMMENT     32\n\t// remove multi-line comments\n\t#define SASS2SCSS_STRIP_COMMENT    64\n\t// convert one-line to multi-line\n\t#define SASS2SCSS_CONVERT_COMMENT  128\n\n\t// available to c and c++ code\n\tADDAPI char* ADDCALL sass2scss (const char* sass, const int options);\n\n\t// Get compiled sass2scss version\n\tADDAPI const char* ADDCALL sass2scss_version(void);\n\n#ifdef __cplusplus\n} // __cplusplus defined.\n#endif\n\n#endif"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/inspect.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <cmath>\n#include <string>\n#include <iostream>\n#include <iomanip>\n#include <stdint.h>\n#include <stdint.h>\n\n#include \"ast.hpp\"\n#include \"inspect.hpp\"\n#include \"context.hpp\"\n#include \"listize.hpp\"\n#include \"color_maps.hpp\"\n#include \"utf8/checked.h\"\n\nnamespace Sass {\n\n  Inspect::Inspect(const Emitter& emi)\n  : Emitter(emi)\n  { }\n  Inspect::~Inspect() { }\n\n  // statements\n  void Inspect::operator()(Block* block)\n  {\n    if (!block->is_root()) {\n      add_open_mapping(block);\n      append_scope_opener();\n    }\n    if (output_style() == NESTED) indentation += block->tabs();\n    for (size_t i = 0, L = block->length(); i < L; ++i) {\n      (*block)[i]->perform(this);\n    }\n    if (output_style() == NESTED) indentation -= block->tabs();\n    if (!block->is_root()) {\n      append_scope_closer();\n      add_close_mapping(block);\n    }\n\n  }\n\n  void Inspect::operator()(StyleRule* ruleset)\n  {\n    if (ruleset->selector()) {\n      ruleset->selector()->perform(this);\n    }\n    if (ruleset->block()) {\n      ruleset->block()->perform(this);\n    }\n  }\n\n  void Inspect::operator()(Keyframe_Rule* rule)\n  {\n    if (rule->name()) rule->name()->perform(this);\n    if (rule->block()) rule->block()->perform(this);\n  }\n\n  void Inspect::operator()(Bubble* bubble)\n  {\n    append_indentation();\n    append_token(\"::BUBBLE\", bubble);\n    append_scope_opener();\n    bubble->node()->perform(this);\n    append_scope_closer();\n  }\n\n  void Inspect::operator()(MediaRule* rule)\n  {\n    append_indentation();\n    append_token(\"@media\", rule);\n    append_mandatory_space();\n    if (rule->block()) {\n      rule->block()->perform(this);\n    }\n  }\n\n  void Inspect::operator()(CssMediaRule* rule)\n  {\n    if (output_style() == NESTED)\n      indentation += rule->tabs();\n    append_indentation();\n    append_token(\"@media\", rule);\n    append_mandatory_space();\n    in_media_block = true;\n    bool joinIt = false;\n    for (auto query : rule->elements()) {\n      if (joinIt) {\n        append_comma_separator();\n        append_optional_space();\n      }\n      operator()(query);\n      joinIt = true;\n    }\n    if (rule->block()) {\n      rule->block()->perform(this);\n    }\n    in_media_block = false;\n    if (output_style() == NESTED)\n      indentation -= rule->tabs();\n  }\n\n  void Inspect::operator()(CssMediaQuery* query)\n  {\n    bool joinIt = false;\n    if (!query->modifier().empty()) {\n      append_string(query->modifier());\n      append_mandatory_space();\n    }\n    if (!query->type().empty()) {\n      append_string(query->type());\n      joinIt = true;\n    }\n    for (auto feature : query->features()) {\n      if (joinIt) {\n        append_mandatory_space();\n        append_string(\"and\");\n        append_mandatory_space();\n      }\n      append_string(feature);\n      joinIt = true;\n    }\n  }\n\n  void Inspect::operator()(SupportsRule* feature_block)\n  {\n    append_indentation();\n    append_token(\"@supports\", feature_block);\n    append_mandatory_space();\n    feature_block->condition()->perform(this);\n    feature_block->block()->perform(this);\n  }\n\n  void Inspect::operator()(AtRootRule* at_root_block)\n  {\n    append_indentation();\n    append_token(\"@at-root \", at_root_block);\n    append_mandatory_space();\n    if(at_root_block->expression()) at_root_block->expression()->perform(this);\n    if(at_root_block->block()) at_root_block->block()->perform(this);\n  }\n\n  void Inspect::operator()(AtRule* at_rule)\n  {\n    append_indentation();\n    append_token(at_rule->keyword(), at_rule);\n    if (at_rule->selector()) {\n      append_mandatory_space();\n      bool was_wrapped = in_wrapped;\n      in_wrapped = true;\n      at_rule->selector()->perform(this);\n      in_wrapped = was_wrapped;\n    }\n    if (at_rule->value()) {\n      append_mandatory_space();\n      at_rule->value()->perform(this);\n    }\n    if (at_rule->block()) {\n      at_rule->block()->perform(this);\n    }\n    else {\n      append_delimiter();\n    }\n  }\n\n  void Inspect::operator()(Declaration* dec)\n  {\n    if (dec->value()->concrete_type() == Expression::NULL_VAL) return;\n    bool was_decl = in_declaration;\n    in_declaration = true;\n    LOCAL_FLAG(in_custom_property, dec->is_custom_property());\n\n    if (output_style() == NESTED)\n      indentation += dec->tabs();\n    append_indentation();\n    if (dec->property())\n      dec->property()->perform(this);\n    append_colon_separator();\n\n    if (dec->value()->concrete_type() == Expression::SELECTOR) {\n      ExpressionObj ls = Listize::perform(dec->value());\n      ls->perform(this);\n    } else {\n      dec->value()->perform(this);\n    }\n\n    if (dec->is_important()) {\n      append_optional_space();\n      append_string(\"!important\");\n    }\n    append_delimiter();\n    if (output_style() == NESTED)\n      indentation -= dec->tabs();\n    in_declaration = was_decl;\n  }\n\n  void Inspect::operator()(Assignment* assn)\n  {\n    append_token(assn->variable(), assn);\n    append_colon_separator();\n    assn->value()->perform(this);\n    if (assn->is_default()) {\n      append_optional_space();\n      append_string(\"!default\");\n    }\n    append_delimiter();\n  }\n\n  void Inspect::operator()(Import* import)\n  {\n    if (!import->urls().empty()) {\n      append_token(\"@import\", import);\n      append_mandatory_space();\n\n      import->urls().front()->perform(this);\n      if (import->urls().size() == 1) {\n        if (import->import_queries()) {\n          append_mandatory_space();\n          import->import_queries()->perform(this);\n        }\n      }\n      append_delimiter();\n      for (size_t i = 1, S = import->urls().size(); i < S; ++i) {\n        append_mandatory_linefeed();\n        append_token(\"@import\", import);\n        append_mandatory_space();\n\n        import->urls()[i]->perform(this);\n        if (import->urls().size() - 1 == i) {\n          if (import->import_queries()) {\n            append_mandatory_space();\n            import->import_queries()->perform(this);\n          }\n        }\n        append_delimiter();\n      }\n    }\n  }\n\n  void Inspect::operator()(Import_Stub* import)\n  {\n    append_indentation();\n    append_token(\"@import\", import);\n    append_mandatory_space();\n    append_string(import->imp_path());\n    append_delimiter();\n  }\n\n  void Inspect::operator()(WarningRule* warning)\n  {\n    append_indentation();\n    append_token(\"@warn\", warning);\n    append_mandatory_space();\n    warning->message()->perform(this);\n    append_delimiter();\n  }\n\n  void Inspect::operator()(ErrorRule* error)\n  {\n    append_indentation();\n    append_token(\"@error\", error);\n    append_mandatory_space();\n    error->message()->perform(this);\n    append_delimiter();\n  }\n\n  void Inspect::operator()(DebugRule* debug)\n  {\n    append_indentation();\n    append_token(\"@debug\", debug);\n    append_mandatory_space();\n    debug->value()->perform(this);\n    append_delimiter();\n  }\n\n  void Inspect::operator()(Comment* comment)\n  {\n    in_comment = true;\n    comment->text()->perform(this);\n    in_comment = false;\n  }\n\n  void Inspect::operator()(If* cond)\n  {\n    append_indentation();\n    append_token(\"@if\", cond);\n    append_mandatory_space();\n    cond->predicate()->perform(this);\n    cond->block()->perform(this);\n    if (cond->alternative()) {\n      append_optional_linefeed();\n      append_indentation();\n      append_string(\"else\");\n      cond->alternative()->perform(this);\n    }\n  }\n\n  void Inspect::operator()(ForRule* loop)\n  {\n    append_indentation();\n    append_token(\"@for\", loop);\n    append_mandatory_space();\n    append_string(loop->variable());\n    append_string(\" from \");\n    loop->lower_bound()->perform(this);\n    append_string(loop->is_inclusive() ? \" through \" : \" to \");\n    loop->upper_bound()->perform(this);\n    loop->block()->perform(this);\n  }\n\n  void Inspect::operator()(EachRule* loop)\n  {\n    append_indentation();\n    append_token(\"@each\", loop);\n    append_mandatory_space();\n    append_string(loop->variables()[0]);\n    for (size_t i = 1, L = loop->variables().size(); i < L; ++i) {\n      append_comma_separator();\n      append_string(loop->variables()[i]);\n    }\n    append_string(\" in \");\n    loop->list()->perform(this);\n    loop->block()->perform(this);\n  }\n\n  void Inspect::operator()(WhileRule* loop)\n  {\n    append_indentation();\n    append_token(\"@while\", loop);\n    append_mandatory_space();\n    loop->predicate()->perform(this);\n    loop->block()->perform(this);\n  }\n\n  void Inspect::operator()(Return* ret)\n  {\n    append_indentation();\n    append_token(\"@return\", ret);\n    append_mandatory_space();\n    ret->value()->perform(this);\n    append_delimiter();\n  }\n\n  void Inspect::operator()(ExtendRule* extend)\n  {\n    append_indentation();\n    append_token(\"@extend\", extend);\n    append_mandatory_space();\n    extend->selector()->perform(this);\n    append_delimiter();\n  }\n\n  void Inspect::operator()(Definition* def)\n  {\n    append_indentation();\n    if (def->type() == Definition::MIXIN) {\n      append_token(\"@mixin\", def);\n      append_mandatory_space();\n    } else {\n      append_token(\"@function\", def);\n      append_mandatory_space();\n    }\n    append_string(def->name());\n    def->parameters()->perform(this);\n    def->block()->perform(this);\n  }\n\n  void Inspect::operator()(Mixin_Call* call)\n  {\n    append_indentation();\n    append_token(\"@include\", call);\n    append_mandatory_space();\n    append_string(call->name());\n    if (call->arguments()) {\n      call->arguments()->perform(this);\n    }\n    if (call->block()) {\n      append_optional_space();\n      call->block()->perform(this);\n    }\n    if (!call->block()) append_delimiter();\n  }\n\n  void Inspect::operator()(Content* content)\n  {\n    append_indentation();\n    append_token(\"@content\", content);\n    append_delimiter();\n  }\n\n  void Inspect::operator()(Map* map)\n  {\n    if (output_style() == TO_SASS && map->empty()) {\n      append_string(\"()\");\n      return;\n    }\n    if (map->empty()) return;\n    if (map->is_invisible()) return;\n    bool items_output = false;\n    append_string(\"(\");\n    for (auto key : map->keys()) {\n      if (items_output) append_comma_separator();\n      key->perform(this);\n      append_colon_separator();\n      LOCAL_FLAG(in_space_array, true);\n      LOCAL_FLAG(in_comma_array, true);\n      map->at(key)->perform(this);\n      items_output = true;\n    }\n    append_string(\")\");\n  }\n\n  sass::string Inspect::lbracket(List* list) {\n    return list->is_bracketed() ? \"[\" : \"(\";\n  }\n\n  sass::string Inspect::rbracket(List* list) {\n    return list->is_bracketed() ? \"]\" : \")\";\n  }\n\n  void Inspect::operator()(List* list)\n  {\n    if (list->empty() && (output_style() == TO_SASS || list->is_bracketed())) {\n      append_string(lbracket(list));\n      append_string(rbracket(list));\n      return;\n    }\n    sass::string sep(list->separator() == SASS_SPACE ? \" \" : \",\");\n    if ((output_style() != COMPRESSED) && sep == \",\") sep += \" \";\n    else if (in_media_block && sep != \" \") sep += \" \"; // verified\n    if (list->empty()) return;\n    bool items_output = false;\n\n    bool was_space_array = in_space_array;\n    bool was_comma_array = in_comma_array;\n    // if the list is bracketed, always include the left bracket\n    if (list->is_bracketed()) {\n      append_string(lbracket(list));\n    }\n    // probably ruby sass equivalent of element_needs_parens\n    else if (output_style() == TO_SASS &&\n        list->length() == 1 &&\n        !list->from_selector() &&\n        !Cast<List>(list->at(0)) &&\n        !Cast<SelectorList>(list->at(0))\n    ) {\n      append_string(lbracket(list));\n    }\n    else if (!in_declaration && (list->separator() == SASS_HASH ||\n        (list->separator() == SASS_SPACE && in_space_array) ||\n        (list->separator() == SASS_COMMA && in_comma_array)\n    )) {\n      append_string(lbracket(list));\n    }\n\n    if (list->separator() == SASS_SPACE) in_space_array = true;\n    else if (list->separator() == SASS_COMMA) in_comma_array = true;\n\n    for (size_t i = 0, L = list->size(); i < L; ++i) {\n      if (list->separator() == SASS_HASH)\n      { sep[0] = i % 2 ? ':' : ','; }\n      ExpressionObj list_item = list->at(i);\n      if (output_style() != TO_SASS) {\n        if (list_item->is_invisible()) {\n          // this fixes an issue with \"\" in a list\n          if (!Cast<String_Constant>(list_item)) {\n            continue;\n          }\n        }\n      }\n      if (items_output) {\n        append_string(sep);\n      }\n      if (items_output && sep != \" \")\n        append_optional_space();\n      list_item->perform(this);\n      items_output = true;\n    }\n\n    in_comma_array = was_comma_array;\n    in_space_array = was_space_array;\n\n    // if the list is bracketed, always include the right bracket\n    if (list->is_bracketed()) {\n      if (list->separator() == SASS_COMMA && list->size() == 1) {\n        append_string(\",\");\n      }\n      append_string(rbracket(list));\n    }\n    // probably ruby sass equivalent of element_needs_parens\n    else if (output_style() == TO_SASS &&\n        list->length() == 1 &&\n        !list->from_selector() &&\n        !Cast<List>(list->at(0)) &&\n        !Cast<SelectorList>(list->at(0))\n    ) {\n      append_string(\",\");\n      append_string(rbracket(list));\n    }\n    else if (!in_declaration && (list->separator() == SASS_HASH ||\n        (list->separator() == SASS_SPACE && in_space_array) ||\n        (list->separator() == SASS_COMMA && in_comma_array)\n    )) {\n      append_string(rbracket(list));\n    }\n\n  }\n\n  void Inspect::operator()(Binary_Expression* expr)\n  {\n    expr->left()->perform(this);\n    if ( in_media_block ||\n         (output_style() == INSPECT) || (\n          expr->op().ws_before\n          && (!expr->is_interpolant())\n          && (expr->is_left_interpolant() ||\n              expr->is_right_interpolant())\n\n    )) append_string(\" \");\n    switch (expr->optype()) {\n      case Sass_OP::AND: append_string(\"&&\"); break;\n      case Sass_OP::OR:  append_string(\"||\");  break;\n      case Sass_OP::EQ:  append_string(\"==\");  break;\n      case Sass_OP::NEQ: append_string(\"!=\");  break;\n      case Sass_OP::GT:  append_string(\">\");   break;\n      case Sass_OP::GTE: append_string(\">=\");  break;\n      case Sass_OP::LT:  append_string(\"<\");   break;\n      case Sass_OP::LTE: append_string(\"<=\");  break;\n      case Sass_OP::ADD: append_string(\"+\");   break;\n      case Sass_OP::SUB: append_string(\"-\");   break;\n      case Sass_OP::MUL: append_string(\"*\");   break;\n      case Sass_OP::DIV: append_string(\"/\"); break;\n      case Sass_OP::MOD: append_string(\"%\");   break;\n      default: break; // shouldn't get here\n    }\n    if ( in_media_block ||\n         (output_style() == INSPECT) || (\n          expr->op().ws_after\n          && (!expr->is_interpolant())\n          && (expr->is_left_interpolant() ||\n              expr->is_right_interpolant())\n    )) append_string(\" \");\n    expr->right()->perform(this);\n  }\n\n  void Inspect::operator()(Unary_Expression* expr)\n  {\n    if (expr->optype() == Unary_Expression::PLUS)       append_string(\"+\");\n    else if (expr->optype() == Unary_Expression::SLASH) append_string(\"/\");\n    else                                                append_string(\"-\");\n    expr->operand()->perform(this);\n  }\n\n  void Inspect::operator()(Function_Call* call)\n  {\n    append_token(call->name(), call);\n    call->arguments()->perform(this);\n  }\n\n  void Inspect::operator()(Variable* var)\n  {\n    append_token(var->name(), var);\n  }\n\n  void Inspect::operator()(Number* n)\n  {\n\n    // reduce units\n    n->reduce();\n\n    sass::ostream ss;\n    ss.precision(opt.precision);\n    ss << std::fixed << n->value();\n\n    sass::string res = ss.str();\n    size_t s = res.length();\n\n    // delete trailing zeros\n    for(s = s - 1; s > 0; --s)\n    {\n        if(res[s] == '0') {\n          res.erase(s, 1);\n        }\n        else break;\n    }\n\n    // delete trailing decimal separator\n    if(res[s] == '.') res.erase(s, 1);\n\n    // some final cosmetics\n    if (res == \"0.0\") res = \"0\";\n    else if (res == \"\") res = \"0\";\n    else if (res == \"-0\") res = \"0\";\n    else if (res == \"-0.0\") res = \"0\";\n    else if (opt.output_style == COMPRESSED)\n    {\n      if (n->zero()) {\n        // check if handling negative nr\n        size_t off = res[0] == '-' ? 1 : 0;\n        // remove leading zero from floating point in compressed mode\n        if (res[off] == '0' && res[off+1] == '.') res.erase(off, 1);\n      }\n    }\n\n    // add unit now\n    res += n->unit();\n\n    if (opt.output_style == TO_CSS && !n->is_valid_css_unit()) {\n      // traces.push_back(Backtrace(nr->pstate()));\n      throw Exception::InvalidValue({}, *n);\n    }\n\n    // output the final token\n    append_token(res, n);\n  }\n\n  // helper function for serializing colors\n  template <size_t range>\n  static double cap_channel(double c) {\n    if      (c > range) return range;\n    else if (c < 0)     return 0;\n    else                return c;\n  }\n\n  void Inspect::operator()(Color_RGBA* c)\n  {\n    // output the final token\n    sass::ostream ss;\n\n    // original color name\n    // maybe an unknown token\n    sass::string name = c->disp();\n\n    // resolved color\n    sass::string res_name = name;\n\n    double r = Sass::round(cap_channel<0xff>(c->r()), opt.precision);\n    double g = Sass::round(cap_channel<0xff>(c->g()), opt.precision);\n    double b = Sass::round(cap_channel<0xff>(c->b()), opt.precision);\n    double a = cap_channel<1>   (c->a());\n\n    // get color from given name (if one was given at all)\n    if (name != \"\" && name_to_color(name)) {\n      const Color_RGBA* n = name_to_color(name);\n      r = Sass::round(cap_channel<0xff>(n->r()), opt.precision);\n      g = Sass::round(cap_channel<0xff>(n->g()), opt.precision);\n      b = Sass::round(cap_channel<0xff>(n->b()), opt.precision);\n      a = cap_channel<1>   (n->a());\n    }\n    // otherwise get the possible resolved color name\n    else {\n      double numval = r * 0x10000 + g * 0x100 + b;\n      if (color_to_name(numval))\n        res_name = color_to_name(numval);\n    }\n\n    sass::ostream hexlet;\n    // dart sass compressed all colors in regular css always\n    // ruby sass and libsass does it only when not delayed\n    // since color math is going to be removed, this can go too\n    bool compressed = opt.output_style == COMPRESSED;\n    hexlet << '#' << std::setw(1) << std::setfill('0');\n    // create a short color hexlet if there is any need for it\n    if (compressed && is_color_doublet(r, g, b) && a == 1) {\n      hexlet << std::hex << std::setw(1) << (static_cast<unsigned long>(r) >> 4);\n      hexlet << std::hex << std::setw(1) << (static_cast<unsigned long>(g) >> 4);\n      hexlet << std::hex << std::setw(1) << (static_cast<unsigned long>(b) >> 4);\n    } else {\n      hexlet << std::hex << std::setw(2) << static_cast<unsigned long>(r);\n      hexlet << std::hex << std::setw(2) << static_cast<unsigned long>(g);\n      hexlet << std::hex << std::setw(2) << static_cast<unsigned long>(b);\n    }\n\n    if (compressed && !c->is_delayed()) name = \"\";\n    if (opt.output_style == INSPECT && a >= 1) {\n      append_token(hexlet.str(), c);\n      return;\n    }\n\n    // retain the originally specified color definition if unchanged\n    if (name != \"\") {\n      ss << name;\n    }\n    else if (a >= 1) {\n      if (res_name != \"\") {\n        if (compressed && hexlet.str().size() < res_name.size()) {\n          ss << hexlet.str();\n        } else {\n          ss << res_name;\n        }\n      }\n      else {\n        ss << hexlet.str();\n      }\n    }\n    else {\n      ss << \"rgba(\";\n      ss << static_cast<unsigned long>(r) << \",\";\n      if (!compressed) ss << \" \";\n      ss << static_cast<unsigned long>(g) << \",\";\n      if (!compressed) ss << \" \";\n      ss << static_cast<unsigned long>(b) << \",\";\n      if (!compressed) ss << \" \";\n      ss << a << ')';\n    }\n\n    append_token(ss.str(), c);\n\n  }\n\n  void Inspect::operator()(Color_HSLA* c)\n  {\n    Color_RGBA_Obj rgba = c->toRGBA();\n    operator()(rgba);\n  }\n\n  void Inspect::operator()(Boolean* b)\n  {\n    // output the final token\n    append_token(b->value() ? \"true\" : \"false\", b);\n  }\n\n  void Inspect::operator()(String_Schema* ss)\n  {\n    // Evaluation should turn these into String_Constants,\n    // so this method is only for inspection purposes.\n    for (size_t i = 0, L = ss->length(); i < L; ++i) {\n      if ((*ss)[i]->is_interpolant()) append_string(\"#{\");\n      (*ss)[i]->perform(this);\n      if ((*ss)[i]->is_interpolant()) append_string(\"}\");\n    }\n  }\n\n  void Inspect::operator()(String_Constant* s)\n  {\n    append_token(s->value(), s);\n  }\n\n  void Inspect::operator()(String_Quoted* s)\n  {\n    if (const char q = s->quote_mark()) {\n      append_token(quote(s->value(), q), s);\n    } else {\n      append_token(s->value(), s);\n    }\n  }\n\n  void Inspect::operator()(Custom_Error* e)\n  {\n    append_token(e->message(), e);\n  }\n\n  void Inspect::operator()(Custom_Warning* w)\n  {\n    append_token(w->message(), w);\n  }\n\n  void Inspect::operator()(SupportsOperation* so)\n  {\n\n    if (so->needs_parens(so->left())) append_string(\"(\");\n    so->left()->perform(this);\n    if (so->needs_parens(so->left())) append_string(\")\");\n\n    if (so->operand() == SupportsOperation::AND) {\n      append_mandatory_space();\n      append_token(\"and\", so);\n      append_mandatory_space();\n    } else if (so->operand() == SupportsOperation::OR) {\n      append_mandatory_space();\n      append_token(\"or\", so);\n      append_mandatory_space();\n    }\n\n    if (so->needs_parens(so->right())) append_string(\"(\");\n    so->right()->perform(this);\n    if (so->needs_parens(so->right())) append_string(\")\");\n  }\n\n  void Inspect::operator()(SupportsNegation* sn)\n  {\n    append_token(\"not\", sn);\n    append_mandatory_space();\n    if (sn->needs_parens(sn->condition())) append_string(\"(\");\n    sn->condition()->perform(this);\n    if (sn->needs_parens(sn->condition())) append_string(\")\");\n  }\n\n  void Inspect::operator()(SupportsDeclaration* sd)\n  {\n    append_string(\"(\");\n    sd->feature()->perform(this);\n    append_string(\": \");\n    sd->value()->perform(this);\n    append_string(\")\");\n  }\n\n  void Inspect::operator()(Supports_Interpolation* sd)\n  {\n    sd->value()->perform(this);\n  }\n\n  void Inspect::operator()(Media_Query* mq)\n  {\n    size_t i = 0;\n    if (mq->media_type()) {\n      if      (mq->is_negated())    append_string(\"not \");\n      else if (mq->is_restricted()) append_string(\"only \");\n      mq->media_type()->perform(this);\n    }\n    else {\n      (*mq)[i++]->perform(this);\n    }\n    for (size_t L = mq->length(); i < L; ++i) {\n      append_string(\" and \");\n      (*mq)[i]->perform(this);\n    }\n  }\n\n  void Inspect::operator()(Media_Query_Expression* mqe)\n  {\n    if (mqe->is_interpolated()) {\n      mqe->feature()->perform(this);\n    }\n    else {\n      append_string(\"(\");\n      mqe->feature()->perform(this);\n      if (mqe->value()) {\n        append_string(\": \"); // verified\n        mqe->value()->perform(this);\n      }\n      append_string(\")\");\n    }\n  }\n\n  void Inspect::operator()(At_Root_Query* ae)\n  {\n    if (ae->feature()) {\n      append_string(\"(\");\n      ae->feature()->perform(this);\n      if (ae->value()) {\n        append_colon_separator();\n        ae->value()->perform(this);\n      }\n      append_string(\")\");\n    }\n  }\n\n  void Inspect::operator()(Function* f)\n  {\n    append_token(\"get-function\", f);\n    append_string(\"(\");\n    append_string(quote(f->name()));\n    append_string(\")\");\n  }\n\n  void Inspect::operator()(Null* n)\n  {\n    // output the final token\n    append_token(\"null\", n);\n  }\n\n  // parameters and arguments\n  void Inspect::operator()(Parameter* p)\n  {\n    append_token(p->name(), p);\n    if (p->default_value()) {\n      append_colon_separator();\n      p->default_value()->perform(this);\n    }\n    else if (p->is_rest_parameter()) {\n      append_string(\"...\");\n    }\n  }\n\n  void Inspect::operator()(Parameters* p)\n  {\n    append_string(\"(\");\n    if (!p->empty()) {\n      (*p)[0]->perform(this);\n      for (size_t i = 1, L = p->length(); i < L; ++i) {\n        append_comma_separator();\n        (*p)[i]->perform(this);\n      }\n    }\n    append_string(\")\");\n  }\n\n  void Inspect::operator()(Argument* a)\n  {\n    if (!a->name().empty()) {\n      append_token(a->name(), a);\n      append_colon_separator();\n    }\n    if (!a->value()) return;\n    // Special case: argument nulls can be ignored\n    if (a->value()->concrete_type() == Expression::NULL_VAL) {\n      return;\n    }\n    if (a->value()->concrete_type() == Expression::STRING) {\n      String_Constant* s = Cast<String_Constant>(a->value());\n      if (s) s->perform(this);\n    } else {\n      a->value()->perform(this);\n    }\n    if (a->is_rest_argument()) {\n      append_string(\"...\");\n    }\n  }\n\n  void Inspect::operator()(Arguments* a)\n  {\n    append_string(\"(\");\n    if (!a->empty()) {\n      (*a)[0]->perform(this);\n      for (size_t i = 1, L = a->length(); i < L; ++i) {\n        append_string(\", \"); // verified\n        // Sass Bug? append_comma_separator();\n        (*a)[i]->perform(this);\n      }\n    }\n    append_string(\")\");\n  }\n\n  void Inspect::operator()(Selector_Schema* s)\n  {\n    s->contents()->perform(this);\n  }\n\n  void Inspect::operator()(Parent_Reference* p)\n  {\n    append_string(\"&\");\n  }\n\n  void Inspect::operator()(PlaceholderSelector* s)\n  {\n    append_token(s->name(), s);\n\n  }\n\n  void Inspect::operator()(TypeSelector* s)\n  {\n    append_token(s->ns_name(), s);\n  }\n\n  void Inspect::operator()(ClassSelector* s)\n  {\n    append_token(s->ns_name(), s);\n  }\n\n  void Inspect::operator()(IDSelector* s)\n  {\n    append_token(s->ns_name(), s);\n  }\n\n  void Inspect::operator()(AttributeSelector* s)\n  {\n    append_string(\"[\");\n    add_open_mapping(s);\n    append_token(s->ns_name(), s);\n    if (!s->matcher().empty()) {\n      append_string(s->matcher());\n      if (s->value() && *s->value()) {\n        s->value()->perform(this);\n      }\n    }\n    add_close_mapping(s);\n    if (s->modifier() != 0) {\n      append_mandatory_space();\n      append_char(s->modifier());\n    }\n    append_string(\"]\");\n  }\n\n  void Inspect::operator()(PseudoSelector* s)\n  {\n\n    if (s->name() != \"\") {\n      append_string(\":\");\n      if (s->isSyntacticElement()) {\n        append_string(\":\");\n      }\n      append_token(s->ns_name(), s);\n      if (s->selector() || s->argument()) {\n        bool was = in_wrapped;\n        in_wrapped = true;\n        append_string(\"(\");\n        if (s->argument()) {\n          s->argument()->perform(this);\n        }\n        if (s->selector() && s->argument()) {\n          append_mandatory_space();\n        }\n        bool was_comma_array = in_comma_array;\n        in_comma_array = false;\n        if (s->selector()) {\n          s->selector()->perform(this);\n        }\n        in_comma_array = was_comma_array;\n        append_string(\")\");\n        in_wrapped = was;\n      }\n    }\n  }\n\n  void Inspect::operator()(SelectorList* g)\n  {\n\n    if (g->empty()) {\n      if (output_style() == TO_SASS) {\n        append_token(\"()\", g);\n      }\n      return;\n    }\n\n\n    bool was_comma_array = in_comma_array;\n    // probably ruby sass equivalent of element_needs_parens\n    if (output_style() == TO_SASS && g->length() == 1 &&\n      (!Cast<List>((*g)[0]) &&\n        !Cast<SelectorList>((*g)[0]))) {\n      append_string(\"(\");\n    }\n    else if (!in_declaration && in_comma_array) {\n      append_string(\"(\");\n    }\n\n    if (in_declaration) in_comma_array = true;\n\n    for (size_t i = 0, L = g->length(); i < L; ++i) {\n\n      if (!in_wrapped && i == 0) append_indentation();\n      if ((*g)[i] == nullptr) continue;\n      if (g->at(i)->length() == 0) continue;\n      schedule_mapping(g->at(i)->last());\n      // add_open_mapping((*g)[i]->last());\n      (*g)[i]->perform(this);\n      // add_close_mapping((*g)[i]->last());\n      if (i < L - 1) {\n        scheduled_space = 0;\n        append_comma_separator();\n      }\n    }\n\n    in_comma_array = was_comma_array;\n    // probably ruby sass equivalent of element_needs_parens\n    if (output_style() == TO_SASS && g->length() == 1 &&\n      (!Cast<List>((*g)[0]) &&\n        !Cast<SelectorList>((*g)[0]))) {\n      append_string(\",)\");\n    }\n    else if (!in_declaration && in_comma_array) {\n      append_string(\")\");\n    }\n\n  }\n  void Inspect::operator()(ComplexSelector* sel)\n  {\n    if (sel->hasPreLineFeed()) {\n      append_optional_linefeed();\n      if (!in_wrapped && output_style() == NESTED) {\n        append_indentation();\n      }\n    }\n    const SelectorComponent* prev = nullptr;\n    for (auto& item : sel->elements()) {\n      if (prev != nullptr) {\n        if (item->getCombinator() || prev->getCombinator()) {\n          append_optional_space();\n        } else {\n          append_mandatory_space();\n        }\n      }\n      item->perform(this);\n      prev = item.ptr();\n    }\n  }\n\n  void Inspect::operator()(SelectorComponent* sel)\n  {\n    // You should probably never call this method directly\n    // But in case anyone does, we will do the up-casting\n    if (auto comp = Cast<CompoundSelector>(sel)) operator()(comp);\n    if (auto comb = Cast<SelectorCombinator>(sel)) operator()(comb);\n  }\n\n  void Inspect::operator()(CompoundSelector* sel)\n  {\n    if (sel->hasRealParent()) {\n      append_string(\"&\");\n    }\n    for (auto& item : sel->elements()) {\n      item->perform(this);\n    }\n    // Add the post line break (from ruby sass)\n    // Dart sass uses another logic for newlines\n    if (sel->hasPostLineBreak()) {\n      if (output_style() != COMPACT) {\n        append_optional_linefeed();\n      }\n    }\n  }\n\n  void Inspect::operator()(SelectorCombinator* sel)\n  {\n    append_optional_space();\n    switch (sel->combinator()) {\n      case SelectorCombinator::Combinator::CHILD: append_string(\">\"); break;\n      case SelectorCombinator::Combinator::GENERAL: append_string(\"~\"); break;\n      case SelectorCombinator::Combinator::ADJACENT: append_string(\"+\"); break;\n    }\n    append_optional_space();\n    // Add the post line break (from ruby sass)\n    // Dart sass uses another logic for newlines\n    if (sel->hasPostLineBreak()) {\n      if (output_style() != COMPACT) {\n        // append_optional_linefeed();\n      }\n    }\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/inspect.hpp",
    "content": "#ifndef SASS_INSPECT_H\n#define SASS_INSPECT_H\n\n#include \"position.hpp\"\n#include \"operation.hpp\"\n#include \"emitter.hpp\"\n\nnamespace Sass {\n  class Context;\n\n  class Inspect : public Operation_CRTP<void, Inspect>, public Emitter {\n  protected:\n    // import all the class-specific methods and override as desired\n    using Operation_CRTP<void, Inspect>::operator();\n\n  public:\n\n    Inspect(const Emitter& emi);\n    virtual ~Inspect();\n\n    // statements\n    virtual void operator()(Block*);\n    virtual void operator()(StyleRule*);\n    virtual void operator()(Bubble*);\n    virtual void operator()(SupportsRule*);\n    virtual void operator()(AtRootRule*);\n    virtual void operator()(AtRule*);\n    virtual void operator()(Keyframe_Rule*);\n    virtual void operator()(Declaration*);\n    virtual void operator()(Assignment*);\n    virtual void operator()(Import*);\n    virtual void operator()(Import_Stub*);\n    virtual void operator()(WarningRule*);\n    virtual void operator()(ErrorRule*);\n    virtual void operator()(DebugRule*);\n    virtual void operator()(Comment*);\n    virtual void operator()(If*);\n    virtual void operator()(ForRule*);\n    virtual void operator()(EachRule*);\n    virtual void operator()(WhileRule*);\n    virtual void operator()(Return*);\n    virtual void operator()(ExtendRule*);\n    virtual void operator()(Definition*);\n    virtual void operator()(Mixin_Call*);\n    virtual void operator()(Content*);\n    // expressions\n    virtual void operator()(Map*);\n    virtual void operator()(Function*);\n    virtual void operator()(List*);\n    virtual void operator()(Binary_Expression*);\n    virtual void operator()(Unary_Expression*);\n    virtual void operator()(Function_Call*);\n    // virtual void operator()(Custom_Warning*);\n    // virtual void operator()(Custom_Error*);\n    virtual void operator()(Variable*);\n    virtual void operator()(Number*);\n    virtual void operator()(Color_RGBA*);\n    virtual void operator()(Color_HSLA*);\n    virtual void operator()(Boolean*);\n    virtual void operator()(String_Schema*);\n    virtual void operator()(String_Constant*);\n    virtual void operator()(String_Quoted*);\n    virtual void operator()(Custom_Error*);\n    virtual void operator()(Custom_Warning*);\n    virtual void operator()(SupportsOperation*);\n    virtual void operator()(SupportsNegation*);\n    virtual void operator()(SupportsDeclaration*);\n    virtual void operator()(Supports_Interpolation*);\n    virtual void operator()(MediaRule*);\n    virtual void operator()(CssMediaRule*);\n    virtual void operator()(CssMediaQuery*);\n    virtual void operator()(Media_Query*);\n    virtual void operator()(Media_Query_Expression*);\n    virtual void operator()(At_Root_Query*);\n    virtual void operator()(Null*);\n    virtual void operator()(Parent_Reference* p);\n    // parameters and arguments\n    virtual void operator()(Parameter*);\n    virtual void operator()(Parameters*);\n    virtual void operator()(Argument*);\n    virtual void operator()(Arguments*);\n    // selectors\n    virtual void operator()(Selector_Schema*);\n    virtual void operator()(PlaceholderSelector*);\n    virtual void operator()(TypeSelector*);\n    virtual void operator()(ClassSelector*);\n    virtual void operator()(IDSelector*);\n    virtual void operator()(AttributeSelector*);\n    virtual void operator()(PseudoSelector*);\n    virtual void operator()(SelectorComponent*);\n    virtual void operator()(SelectorCombinator*);\n    virtual void operator()(CompoundSelector*);\n    virtual void operator()(ComplexSelector*);\n    virtual void operator()(SelectorList*);\n    virtual sass::string lbracket(List*);\n    virtual sass::string rbracket(List*);\n\n  };\n\n}\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/json.cpp",
    "content": "/*\n  Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com)\n  All rights reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n*/\n\n#ifdef _MSC_VER\n#define _CRT_SECURE_NO_WARNINGS\n#define _CRT_NONSTDC_NO_DEPRECATE\n#endif\n\n#include \"json.hpp\"\n\n// include utf8 library used by libsass\n// ToDo: replace internal json utf8 code\n#include \"utf8.h\"\n\n#include <assert.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#if defined(_MSC_VER) && _MSC_VER < 1900\n#include <stdarg.h>\n#ifdef snprintf\n#undef snprintf\n#endif\nextern \"C\" int snprintf(char *, size_t, const char *, ...);\n#endif\n\n#define out_of_memory() do {                    \\\n    fprintf(stderr, \"Out of memory.\\n\");    \\\n    exit(EXIT_FAILURE);                     \\\n  } while (0)\n\n/* Sadly, strdup is not portable. */\nstatic char *json_strdup(const char *str)\n{\n  char *ret = (char*) malloc(strlen(str) + 1);\n  if (ret == NULL)\n    out_of_memory();\n  strcpy(ret, str);\n  return ret;\n}\n\n/* String buffer */\n\ntypedef struct\n{\n  char *cur;\n  char *end;\n  char *start;\n} SB;\n\nstatic void sb_init(SB *sb)\n{\n  sb->start = (char*) malloc(17);\n  if (sb->start == NULL)\n    out_of_memory();\n  sb->cur = sb->start;\n  sb->end = sb->start + 16;\n}\n\n/* sb and need may be evaluated multiple times. */\n#define sb_need(sb, need) do {                  \\\n    if ((sb)->end - (sb)->cur < (need))     \\\n      sb_grow(sb, need);                  \\\n  } while (0)\n\nstatic void sb_grow(SB *sb, int need)\n{\n  size_t length = sb->cur - sb->start;\n  size_t alloc = sb->end - sb->start;\n\n  do {\n    alloc *= 2;\n  } while (alloc < length + need);\n\n  sb->start = (char*) realloc(sb->start, alloc + 1);\n  if (sb->start == NULL)\n    out_of_memory();\n  sb->cur = sb->start + length;\n  sb->end = sb->start + alloc;\n}\n\nstatic void sb_put(SB *sb, const char *bytes, int count)\n{\n  sb_need(sb, count);\n  memcpy(sb->cur, bytes, count);\n  sb->cur += count;\n}\n\n#define sb_putc(sb, c) do {         \\\n    if ((sb)->cur >= (sb)->end) \\\n      sb_grow(sb, 1);         \\\n    *(sb)->cur++ = (c);         \\\n  } while (0)\n\nstatic void sb_puts(SB *sb, const char *str)\n{\n  sb_put(sb, str, (int)strlen(str));\n}\n\nstatic char *sb_finish(SB *sb)\n{\n  *sb->cur = 0;\n  assert(sb->start <= sb->cur && strlen(sb->start) == (size_t)(sb->cur - sb->start));\n  return sb->start;\n}\n\nstatic void sb_free(SB *sb)\n{\n  free(sb->start);\n}\n\n/*\n * Unicode helper functions\n *\n * These are taken from the ccan/charset module and customized a bit.\n * Putting them here means the compiler can (choose to) inline them,\n * and it keeps ccan/json from having a dependency.\n *\n * We use uint32_t Type for Unicode codepoints.\n * We need our own because wchar_t might be 16 bits.\n */\n\n/*\n * Validate a single UTF-8 character starting at @s.\n * The string must be null-terminated.\n *\n * If it's valid, return its length (1 thru 4).\n * If it's invalid or clipped, return 0.\n *\n * This function implements the syntax given in RFC3629, which is\n * the same as that given in The Unicode Standard, Version 6.0.\n *\n * It has the following properties:\n *\n *  * All codepoints U+0000..U+10FFFF may be encoded,\n *    except for U+D800..U+DFFF, which are reserved\n *    for UTF-16 surrogate pair encoding.\n *  * UTF-8 byte sequences longer than 4 bytes are not permitted,\n *    as they exceed the range of Unicode.\n *  * The sixty-six Unicode \"non-characters\" are permitted\n *    (namely, U+FDD0..U+FDEF, U+xxFFFE, and U+xxFFFF).\n */\nstatic int utf8_validate_cz(const char *s)\n{\n  unsigned char c = *s++;\n\n  if (c <= 0x7F) {        /* 00..7F */\n    return 1;\n  } else if (c <= 0xC1) { /* 80..C1 */\n    /* Disallow overlong 2-byte sequence. */\n    return 0;\n  } else if (c <= 0xDF) { /* C2..DF */\n    /* Make sure subsequent byte is in the range 0x80..0xBF. */\n    if (((unsigned char)*s++ & 0xC0) != 0x80)\n      return 0;\n\n    return 2;\n  } else if (c <= 0xEF) { /* E0..EF */\n    /* Disallow overlong 3-byte sequence. */\n    if (c == 0xE0 && (unsigned char)*s < 0xA0)\n      return 0;\n\n    /* Disallow U+D800..U+DFFF. */\n    if (c == 0xED && (unsigned char)*s > 0x9F)\n      return 0;\n\n    /* Make sure subsequent bytes are in the range 0x80..0xBF. */\n    if (((unsigned char)*s++ & 0xC0) != 0x80)\n      return 0;\n    if (((unsigned char)*s++ & 0xC0) != 0x80)\n      return 0;\n\n    return 3;\n  } else if (c <= 0xF4) { /* F0..F4 */\n    /* Disallow overlong 4-byte sequence. */\n    if (c == 0xF0 && (unsigned char)*s < 0x90)\n      return 0;\n\n    /* Disallow codepoints beyond U+10FFFF. */\n    if (c == 0xF4 && (unsigned char)*s > 0x8F)\n      return 0;\n\n    /* Make sure subsequent bytes are in the range 0x80..0xBF. */\n    if (((unsigned char)*s++ & 0xC0) != 0x80)\n      return 0;\n    if (((unsigned char)*s++ & 0xC0) != 0x80)\n      return 0;\n    if (((unsigned char)*s++ & 0xC0) != 0x80)\n      return 0;\n\n    return 4;\n  } else {                /* F5..FF */\n    return 0;\n  }\n}\n\n/* Validate a null-terminated UTF-8 string. */\nstatic bool utf8_validate(const char *s)\n{\n  int len;\n\n  for (; *s != 0; s += len) {\n    len = utf8_validate_cz(s);\n    if (len == 0)\n      return false;\n  }\n\n  return true;\n}\n\n/*\n * Read a single UTF-8 character starting at @s,\n * returning the length, in bytes, of the character read.\n *\n * This function assumes input is valid UTF-8,\n * and that there are enough characters in front of @s.\n */\nstatic int utf8_read_char(const char *s, uint32_t *out)\n{\n  const unsigned char *c = (const unsigned char*) s;\n\n  assert(utf8_validate_cz(s));\n\n  if (c[0] <= 0x7F) {\n    /* 00..7F */\n    *out = c[0];\n    return 1;\n  } else if (c[0] <= 0xDF) {\n    /* C2..DF (unless input is invalid) */\n    *out = ((uint32_t)c[0] & 0x1F) << 6 |\n           ((uint32_t)c[1] & 0x3F);\n    return 2;\n  } else if (c[0] <= 0xEF) {\n    /* E0..EF */\n    *out = ((uint32_t)c[0] &  0xF) << 12 |\n           ((uint32_t)c[1] & 0x3F) << 6  |\n           ((uint32_t)c[2] & 0x3F);\n    return 3;\n  } else {\n    /* F0..F4 (unless input is invalid) */\n    *out = ((uint32_t)c[0] &  0x7) << 18 |\n           ((uint32_t)c[1] & 0x3F) << 12 |\n           ((uint32_t)c[2] & 0x3F) << 6  |\n           ((uint32_t)c[3] & 0x3F);\n    return 4;\n  }\n}\n\n/*\n * Write a single UTF-8 character to @s,\n * returning the length, in bytes, of the character written.\n *\n * @unicode must be U+0000..U+10FFFF, but not U+D800..U+DFFF.\n *\n * This function will write up to 4 bytes to @out.\n */\nstatic int utf8_write_char(uint32_t unicode, char *out)\n{\n  unsigned char *o = (unsigned char*) out;\n\n  assert(unicode <= 0x10FFFF && !(unicode >= 0xD800 && unicode <= 0xDFFF));\n\n  if (unicode <= 0x7F) {\n    /* U+0000..U+007F */\n    *o++ = unicode;\n    return 1;\n  } else if (unicode <= 0x7FF) {\n    /* U+0080..U+07FF */\n    *o++ = 0xC0 | unicode >> 6;\n    *o++ = 0x80 | (unicode & 0x3F);\n    return 2;\n  } else if (unicode <= 0xFFFF) {\n    /* U+0800..U+FFFF */\n    *o++ = 0xE0 | unicode >> 12;\n    *o++ = 0x80 | (unicode >> 6 & 0x3F);\n    *o++ = 0x80 | (unicode & 0x3F);\n    return 3;\n  } else {\n    /* U+10000..U+10FFFF */\n    *o++ = 0xF0 | unicode >> 18;\n    *o++ = 0x80 | (unicode >> 12 & 0x3F);\n    *o++ = 0x80 | (unicode >> 6 & 0x3F);\n    *o++ = 0x80 | (unicode & 0x3F);\n    return 4;\n  }\n}\n\n/*\n * Compute the Unicode codepoint of a UTF-16 surrogate pair.\n *\n * @uc should be 0xD800..0xDBFF, and @lc should be 0xDC00..0xDFFF.\n * If they aren't, this function returns false.\n */\nstatic bool from_surrogate_pair(uint16_t uc, uint16_t lc, uint32_t *unicode)\n{\n  if (uc >= 0xD800 && uc <= 0xDBFF && lc >= 0xDC00 && lc <= 0xDFFF) {\n    *unicode = 0x10000 + ((((uint32_t)uc & 0x3FF) << 10) | (lc & 0x3FF));\n    return true;\n  } else {\n    return false;\n  }\n}\n\n/*\n * Construct a UTF-16 surrogate pair given a Unicode codepoint.\n *\n * @unicode must be U+10000..U+10FFFF.\n */\nstatic void to_surrogate_pair(uint32_t unicode, uint16_t *uc, uint16_t *lc)\n{\n  uint32_t n;\n\n  assert(unicode >= 0x10000 && unicode <= 0x10FFFF);\n\n  n = unicode - 0x10000;\n  *uc = ((n >> 10) & 0x3FF) | 0xD800;\n  *lc = (n & 0x3FF) | 0xDC00;\n}\n\nstatic bool is_space        (const char *c);\nstatic bool is_digit        (const char *c);\nstatic bool parse_value     (const char **sp, JsonNode        **out);\nstatic bool parse_string    (const char **sp, char            **out);\nstatic bool parse_number    (const char **sp, double           *out);\nstatic bool parse_array     (const char **sp, JsonNode        **out);\nstatic bool parse_object    (const char **sp, JsonNode        **out);\nstatic bool parse_hex16     (const char **sp, uint16_t         *out);\n\nstatic bool expect_literal  (const char **sp, const char *str);\nstatic void skip_space      (const char **sp);\n\nstatic void emit_value              (SB *out, const JsonNode *node);\nstatic void emit_value_indented     (SB *out, const JsonNode *node, const char *space, int indent_level);\nstatic void emit_string             (SB *out, const char *str);\nstatic void emit_number             (SB *out, double num);\nstatic void emit_array              (SB *out, const JsonNode *array);\nstatic void emit_array_indented     (SB *out, const JsonNode *array, const char *space, int indent_level);\nstatic void emit_object             (SB *out, const JsonNode *object);\nstatic void emit_object_indented    (SB *out, const JsonNode *object, const char *space, int indent_level);\n\nstatic int write_hex16(char *out, uint16_t val);\n\nstatic JsonNode *mknode(JsonTag tag);\nstatic void append_node(JsonNode *parent, JsonNode *child);\nstatic void prepend_node(JsonNode *parent, JsonNode *child);\nstatic void append_member(JsonNode *object, char *key, JsonNode *value);\n\n/* Assertion-friendly validity checks */\nstatic bool tag_is_valid(unsigned int tag);\nstatic bool number_is_valid(const char *num);\n\nJsonNode *json_decode(const char *json)\n{\n  const char *s = json;\n  JsonNode *ret;\n\n  skip_space(&s);\n  if (!parse_value(&s, &ret))\n    return NULL;\n\n  skip_space(&s);\n  if (*s != 0) {\n    json_delete(ret);\n    return NULL;\n  }\n\n  return ret;\n}\n\nchar *json_encode(const JsonNode *node)\n{\n  return json_stringify(node, NULL);\n}\n\nchar *json_encode_string(const char *str)\n{\n  SB sb;\n  sb_init(&sb);\n\n  try {\n    emit_string(&sb, str);\n  }\n  catch (std::exception&) {\n    sb_free(&sb);\n    throw;\n  }\n\n  return sb_finish(&sb);\n}\n\nchar *json_stringify(const JsonNode *node, const char *space)\n{\n  SB sb;\n  sb_init(&sb);\n\n  try {\n    if (space != NULL)\n      emit_value_indented(&sb, node, space, 0);\n    else\n      emit_value(&sb, node);\n  }\n  catch (std::exception&) {\n    sb_free(&sb);\n    throw;\n  }\n\n  return sb_finish(&sb);\n}\n\nvoid json_delete(JsonNode *node)\n{\n  if (node != NULL) {\n    json_remove_from_parent(node);\n\n    switch (node->tag) {\n      case JSON_STRING:\n        free(node->string_);\n        break;\n      case JSON_ARRAY:\n      case JSON_OBJECT:\n      {\n        JsonNode *child, *next;\n        for (child = node->children.head; child != NULL; child = next) {\n          next = child->next;\n          json_delete(child);\n        }\n        break;\n      }\n      default:;\n    }\n\n    free(node);\n  }\n}\n\nbool json_validate(const char *json)\n{\n  const char *s = json;\n\n  skip_space(&s);\n  if (!parse_value(&s, NULL))\n    return false;\n\n  skip_space(&s);\n  if (*s != 0)\n    return false;\n\n  return true;\n}\n\nJsonNode *json_find_element(JsonNode *array, int index)\n{\n  JsonNode *element;\n  int i = 0;\n\n  if (array == NULL || array->tag != JSON_ARRAY)\n    return NULL;\n\n  json_foreach(element, array) {\n    if (i == index)\n      return element;\n    i++;\n  }\n\n  return NULL;\n}\n\nJsonNode *json_find_member(JsonNode *object, const char *name)\n{\n  JsonNode *member;\n\n  if (object == NULL || object->tag != JSON_OBJECT)\n    return NULL;\n\n  json_foreach(member, object)\n    if (strcmp(member->key, name) == 0)\n      return member;\n\n  return NULL;\n}\n\nJsonNode *json_first_child(const JsonNode *node)\n{\n  if (node != NULL && (node->tag == JSON_ARRAY || node->tag == JSON_OBJECT))\n    return node->children.head;\n  return NULL;\n}\n\nstatic JsonNode *mknode(JsonTag tag)\n{\n  JsonNode *ret = (JsonNode*) calloc(1, sizeof(JsonNode));\n  if (ret == NULL)\n    out_of_memory();\n  ret->tag = tag;\n  return ret;\n}\n\nJsonNode *json_mknull(void)\n{\n  return mknode(JSON_NULL);\n}\n\nJsonNode *json_mkbool(bool b)\n{\n  JsonNode *ret = mknode(JSON_BOOL);\n  ret->bool_ = b;\n  return ret;\n}\n\nstatic JsonNode *mkstring(char *s)\n{\n  JsonNode *ret = mknode(JSON_STRING);\n  ret->string_ = s;\n  return ret;\n}\n\nJsonNode *json_mkstring(const char *s)\n{\n  return mkstring(json_strdup(s));\n}\n\nJsonNode *json_mknumber(double n)\n{\n  JsonNode *node = mknode(JSON_NUMBER);\n  node->number_ = n;\n  return node;\n}\n\nJsonNode *json_mkarray(void)\n{\n  return mknode(JSON_ARRAY);\n}\n\nJsonNode *json_mkobject(void)\n{\n  return mknode(JSON_OBJECT);\n}\n\nstatic void append_node(JsonNode *parent, JsonNode *child)\n{\n  if (child != NULL && parent != NULL) {\n      child->parent = parent;\n      child->prev = parent->children.tail;\n      child->next = NULL;\n\n      if (parent->children.tail != NULL)\n          parent->children.tail->next = child;\n      else\n          parent->children.head = child;\n      parent->children.tail = child;\n  }\n}\n\nstatic void prepend_node(JsonNode *parent, JsonNode *child)\n{\n  if (child != NULL && parent != NULL) {\n      child->parent = parent;\n      child->prev = NULL;\n      child->next = parent->children.head;\n\n      if (parent->children.head != NULL)\n          parent->children.head->prev = child;\n      else\n          parent->children.tail = child;\n      parent->children.head = child;\n  }\n}\n\nstatic void append_member(JsonNode *object, char *key, JsonNode *value)\n{\n  if (value != NULL && object != NULL) {\n      value->key = key;\n      append_node(object, value);\n  }\n}\n\nvoid json_append_element(JsonNode *array, JsonNode *element)\n{\n  if (array != NULL && element !=NULL) {\n      assert(array->tag == JSON_ARRAY);\n      assert(element->parent == NULL);\n\n      append_node(array, element);\n  }\n}\n\nvoid json_prepend_element(JsonNode *array, JsonNode *element)\n{\n  assert(array->tag == JSON_ARRAY);\n  assert(element->parent == NULL);\n\n  prepend_node(array, element);\n}\n\nvoid json_append_member(JsonNode *object, const char *key, JsonNode *value)\n{\n  if (object != NULL && key != NULL && value != NULL) {\n      assert(object->tag == JSON_OBJECT);\n      assert(value->parent == NULL);\n\n      append_member(object, json_strdup(key), value);\n  }\n}\n\nvoid json_prepend_member(JsonNode *object, const char *key, JsonNode *value)\n{\n  if (object != NULL && key != NULL && value != NULL) {\n      assert(object->tag == JSON_OBJECT);\n      assert(value->parent == NULL);\n\n      value->key = json_strdup(key);\n      prepend_node(object, value);\n  }\n}\n\nvoid json_remove_from_parent(JsonNode *node)\n{\n  if (node != NULL) {\n      JsonNode *parent = node->parent;\n\n      if (parent != NULL) {\n          if (node->prev != NULL)\n              node->prev->next = node->next;\n          else\n              parent->children.head = node->next;\n\n          if (node->next != NULL)\n              node->next->prev = node->prev;\n          else\n              parent->children.tail = node->prev;\n\n          free(node->key);\n\n          node->parent = NULL;\n          node->prev = node->next = NULL;\n          node->key = NULL;\n      }\n  }\n}\n\nstatic bool parse_value(const char **sp, JsonNode **out)\n{\n  const char *s = *sp;\n\n  switch (*s) {\n    case 'n':\n      if (expect_literal(&s, \"null\")) {\n        if (out)\n          *out = json_mknull();\n        *sp = s;\n        return true;\n      }\n      return false;\n\n    case 'f':\n      if (expect_literal(&s, \"false\")) {\n        if (out)\n          *out = json_mkbool(false);\n        *sp = s;\n        return true;\n      }\n      return false;\n\n    case 't':\n      if (expect_literal(&s, \"true\")) {\n        if (out)\n          *out = json_mkbool(true);\n        *sp = s;\n        return true;\n      }\n      return false;\n\n    case '\"': {\n      char *str = NULL;\n      if (parse_string(&s, out ? &str : NULL)) {\n        if (out)\n          *out = mkstring(str);\n        *sp = s;\n        return true;\n      }\n      return false;\n    }\n\n    case '[':\n      if (parse_array(&s, out)) {\n        *sp = s;\n        return true;\n      }\n      return false;\n\n    case '{':\n      if (parse_object(&s, out)) {\n        *sp = s;\n        return true;\n      }\n      return false;\n\n    default: {\n      double num;\n      if (parse_number(&s, out ? &num : NULL)) {\n        if (out)\n          *out = json_mknumber(num);\n        *sp = s;\n        return true;\n      }\n      return false;\n    }\n  }\n}\n\nstatic bool parse_array(const char **sp, JsonNode **out)\n{\n  const char *s = *sp;\n  JsonNode *ret = out ? json_mkarray() : NULL;\n  JsonNode *element = NULL;\n\n  if (*s++ != '[')\n    goto failure;\n  skip_space(&s);\n\n  if (*s == ']') {\n    s++;\n    goto success;\n  }\n\n  for (;;) {\n    if (!parse_value(&s, out ? &element : NULL))\n      goto failure;\n    skip_space(&s);\n\n    if (out)\n      json_append_element(ret, element);\n\n    if (*s == ']') {\n      s++;\n      goto success;\n    }\n\n    if (*s++ != ',')\n      goto failure;\n    skip_space(&s);\n  }\n\nsuccess:\n  *sp = s;\n  if (out)\n    *out = ret;\n  return true;\n\nfailure:\n  json_delete(ret);\n  return false;\n}\n\nstatic bool parse_object(const char **sp, JsonNode **out)\n{\n  const char *s = *sp;\n  JsonNode *ret = out ? json_mkobject() : NULL;\n  char *key = NULL;\n  JsonNode *value = NULL;\n\n  if (*s++ != '{')\n    goto failure;\n  skip_space(&s);\n\n  if (*s == '}') {\n    s++;\n    goto success;\n  }\n\n  for (;;) {\n    if (!parse_string(&s, out ? &key : NULL))\n      goto failure;\n    skip_space(&s);\n\n    if (*s++ != ':')\n      goto failure_free_key;\n    skip_space(&s);\n\n    if (!parse_value(&s, out ? &value : NULL))\n      goto failure_free_key;\n    skip_space(&s);\n\n    if (out)\n      append_member(ret, key, value);\n\n    if (*s == '}') {\n      s++;\n      goto success;\n    }\n\n    if (*s++ != ',')\n      goto failure;\n    skip_space(&s);\n  }\n\nsuccess:\n  *sp = s;\n  if (out)\n    *out = ret;\n  return true;\n\nfailure_free_key:\n  if (out)\n    free(key);\nfailure:\n  json_delete(ret);\n  return false;\n}\n\nbool parse_string(const char **sp, char **out)\n{\n  const char *s = *sp;\n  SB sb = { 0, 0, 0 };\n  char throwaway_buffer[4];\n    /* enough space for a UTF-8 character */\n  char *b;\n\n  if (*s++ != '\"')\n    return false;\n\n  if (out) {\n    sb_init(&sb);\n    sb_need(&sb, 4);\n    b = sb.cur;\n  } else {\n    b = throwaway_buffer;\n  }\n\n  while (*s != '\"') {\n    unsigned char c = *s++;\n\n    /* Parse next character, and write it to b. */\n    if (c == '\\\\') {\n      c = *s++;\n      switch (c) {\n        case '\"':\n        case '\\\\':\n        case '/':\n          *b++ = c;\n          break;\n        case 'b':\n          *b++ = '\\b';\n          break;\n        case 'f':\n          *b++ = '\\f';\n          break;\n        case 'n':\n          *b++ = '\\n';\n          break;\n        case 'r':\n          *b++ = '\\r';\n          break;\n        case 't':\n          *b++ = '\\t';\n          break;\n        case 'u':\n        {\n          uint16_t uc, lc;\n          uint32_t unicode;\n\n          if (!parse_hex16(&s, &uc))\n            goto failed;\n\n          if (uc >= 0xD800 && uc <= 0xDFFF) {\n            /* Handle UTF-16 surrogate pair. */\n            if (*s++ != '\\\\' || *s++ != 'u' || !parse_hex16(&s, &lc))\n              goto failed; /* Incomplete surrogate pair. */\n            if (!from_surrogate_pair(uc, lc, &unicode))\n              goto failed; /* Invalid surrogate pair. */\n          } else if (uc == 0) {\n            /* Disallow \"\\u0000\". */\n            goto failed;\n          } else {\n            unicode = uc;\n          }\n\n          b += utf8_write_char(unicode, b);\n          break;\n        }\n        default:\n          /* Invalid escape */\n          goto failed;\n      }\n    } else if (c <= 0x1F) {\n      /* Control characters are not allowed in string literals. */\n      goto failed;\n    } else {\n      /* Validate and echo a UTF-8 character. */\n      int len;\n\n      s--;\n      len = utf8_validate_cz(s);\n      if (len == 0)\n        goto failed; /* Invalid UTF-8 character. */\n\n      while (len--)\n        *b++ = *s++;\n    }\n\n    /*\n     * Update sb to know about the new bytes,\n     * and set up b to write another character.\n     */\n    if (out) {\n      sb.cur = b;\n      sb_need(&sb, 4);\n      b = sb.cur;\n    } else {\n      b = throwaway_buffer;\n    }\n  }\n  s++;\n\n  if (out)\n    *out = sb_finish(&sb);\n  *sp = s;\n  return true;\n\nfailed:\n  if (out)\n    sb_free(&sb);\n  return false;\n}\n\nbool is_space(const char *c) {\n  return ((*c) == '\\t' || (*c) == '\\n' || (*c) == '\\r' || (*c) == ' ');\n}\n\nbool is_digit(const char *c){\n  return ((*c) >= '0' && (*c) <= '9');\n}\n\n/*\n * The JSON spec says that a number shall follow this precise pattern\n * (spaces and quotes added for readability):\n *   '-'? (0 | [1-9][0-9]*) ('.' [0-9]+)? ([Ee] [+-]? [0-9]+)?\n *\n * However, some JSON parsers are more liberal.  For instance, PHP accepts\n * '.5' and '1.'.  JSON.parse accepts '+3'.\n *\n * This function takes the strict approach.\n */\nbool parse_number(const char **sp, double *out)\n{\n  const char *s = *sp;\n\n  /* '-'? */\n  if (*s == '-')\n    s++;\n\n  /* (0 | [1-9][0-9]*) */\n  if (*s == '0') {\n    s++;\n  } else {\n    if (!is_digit(s))\n      return false;\n    do {\n      s++;\n    } while (is_digit(s));\n  }\n\n  /* ('.' [0-9]+)? */\n  if (*s == '.') {\n    s++;\n    if (!is_digit(s))\n      return false;\n    do {\n      s++;\n    } while (is_digit(s));\n  }\n\n  /* ([Ee] [+-]? [0-9]+)? */\n  if (*s == 'E' || *s == 'e') {\n    s++;\n    if (*s == '+' || *s == '-')\n      s++;\n    if (!is_digit(s))\n      return false;\n    do {\n      s++;\n    } while (is_digit(s));\n  }\n\n  if (out)\n    *out = strtod(*sp, NULL);\n\n  *sp = s;\n  return true;\n}\n\nstatic void skip_space(const char **sp)\n{\n  const char *s = *sp;\n  while (is_space(s))\n    s++;\n  *sp = s;\n}\n\nstatic void emit_value(SB *out, const JsonNode *node)\n{\n  assert(tag_is_valid(node->tag));\n  switch (node->tag) {\n    case JSON_NULL:\n      sb_puts(out, \"null\");\n      break;\n    case JSON_BOOL:\n      sb_puts(out, node->bool_ ? \"true\" : \"false\");\n      break;\n    case JSON_STRING:\n      emit_string(out, node->string_);\n      break;\n    case JSON_NUMBER:\n      emit_number(out, node->number_);\n      break;\n    case JSON_ARRAY:\n      emit_array(out, node);\n      break;\n    case JSON_OBJECT:\n      emit_object(out, node);\n      break;\n    default:\n      assert(false);\n  }\n}\n\nvoid emit_value_indented(SB *out, const JsonNode *node, const char *space, int indent_level)\n{\n  assert(tag_is_valid(node->tag));\n  switch (node->tag) {\n    case JSON_NULL:\n      sb_puts(out, \"null\");\n      break;\n    case JSON_BOOL:\n      sb_puts(out, node->bool_ ? \"true\" : \"false\");\n      break;\n    case JSON_STRING:\n      emit_string(out, node->string_);\n      break;\n    case JSON_NUMBER:\n      emit_number(out, node->number_);\n      break;\n    case JSON_ARRAY:\n      emit_array_indented(out, node, space, indent_level);\n      break;\n    case JSON_OBJECT:\n      emit_object_indented(out, node, space, indent_level);\n      break;\n    default:\n      assert(false);\n  }\n}\n\nstatic void emit_array(SB *out, const JsonNode *array)\n{\n  const JsonNode *element;\n\n  sb_putc(out, '[');\n  json_foreach(element, array) {\n    emit_value(out, element);\n    if (element->next != NULL)\n      sb_putc(out, ',');\n  }\n  sb_putc(out, ']');\n}\n\nstatic void emit_array_indented(SB *out, const JsonNode *array, const char *space, int indent_level)\n{\n  const JsonNode *element = array->children.head;\n  int i;\n\n  if (element == NULL) {\n    sb_puts(out, \"[]\");\n    return;\n  }\n\n  sb_puts(out, \"[\\n\");\n  while (element != NULL) {\n    for (i = 0; i < indent_level + 1; i++)\n      sb_puts(out, space);\n    emit_value_indented(out, element, space, indent_level + 1);\n\n    element = element->next;\n    sb_puts(out, element != NULL ? \",\\n\" : \"\\n\");\n  }\n  for (i = 0; i < indent_level; i++)\n    sb_puts(out, space);\n  sb_putc(out, ']');\n}\n\nstatic void emit_object(SB *out, const JsonNode *object)\n{\n  const JsonNode *member;\n\n  sb_putc(out, '{');\n  json_foreach(member, object) {\n    emit_string(out, member->key);\n    sb_putc(out, ':');\n    emit_value(out, member);\n    if (member->next != NULL)\n      sb_putc(out, ',');\n  }\n  sb_putc(out, '}');\n}\n\nstatic void emit_object_indented(SB *out, const JsonNode *object, const char *space, int indent_level)\n{\n  const JsonNode *member = object->children.head;\n  int i;\n\n  if (member == NULL) {\n    sb_puts(out, \"{}\");\n    return;\n  }\n\n  sb_puts(out, \"{\\n\");\n  while (member != NULL) {\n    for (i = 0; i < indent_level + 1; i++)\n      sb_puts(out, space);\n    emit_string(out, member->key);\n    sb_puts(out, \": \");\n    emit_value_indented(out, member, space, indent_level + 1);\n\n    member = member->next;\n    sb_puts(out, member != NULL ? \",\\n\" : \"\\n\");\n  }\n  for (i = 0; i < indent_level; i++)\n    sb_puts(out, space);\n  sb_putc(out, '}');\n}\n\nvoid emit_string(SB *out, const char *str)\n{\n  bool escape_unicode = false;\n  const char *s = str;\n  char *b;\n\n// make assertion catchable\n#ifndef NDEBUG\n  if (!utf8_validate(str)) {\n    throw utf8::invalid_utf8(0);\n  }\n#endif\n\n  assert(utf8_validate(str));\n\n  /*\n   * 14 bytes is enough space to write up to two\n   * \\uXXXX escapes and two quotation marks.\n   */\n  sb_need(out, 14);\n  b = out->cur;\n\n  *b++ = '\"';\n  while (*s != 0) {\n    unsigned char c = *s++;\n\n    /* Encode the next character, and write it to b. */\n    switch (c) {\n      case '\"':\n        *b++ = '\\\\';\n        *b++ = '\"';\n        break;\n      case '\\\\':\n        *b++ = '\\\\';\n        *b++ = '\\\\';\n        break;\n      case '\\b':\n        *b++ = '\\\\';\n        *b++ = 'b';\n        break;\n      case '\\f':\n        *b++ = '\\\\';\n        *b++ = 'f';\n        break;\n      case '\\n':\n        *b++ = '\\\\';\n        *b++ = 'n';\n        break;\n      case '\\r':\n        *b++ = '\\\\';\n        *b++ = 'r';\n        break;\n      case '\\t':\n        *b++ = '\\\\';\n        *b++ = 't';\n        break;\n      default: {\n        int len;\n\n        s--;\n        len = utf8_validate_cz(s);\n\n        if (len == 0) {\n          /*\n           * Handle invalid UTF-8 character gracefully in production\n           * by writing a replacement character (U+FFFD)\n           * and skipping a single byte.\n           *\n           * This should never happen when assertions are enabled\n           * due to the assertion at the beginning of this function.\n           */\n          assert(false);\n          if (escape_unicode) {\n            strcpy(b, \"\\\\uFFFD\");\n            b += 6;\n          } else {\n            *b++ = 0xEFu;\n            *b++ = 0xBFu;\n            *b++ = 0xBDu;\n          }\n          s++;\n        } else if (c < 0x1F || (c >= 0x80 && escape_unicode)) {\n          /* Encode using \\u.... */\n          uint32_t unicode;\n\n          s += utf8_read_char(s, &unicode);\n\n          if (unicode <= 0xFFFF) {\n            *b++ = '\\\\';\n            *b++ = 'u';\n            b += write_hex16(b, unicode);\n          } else {\n            /* Produce a surrogate pair. */\n            uint16_t uc, lc;\n            assert(unicode <= 0x10FFFF);\n            to_surrogate_pair(unicode, &uc, &lc);\n            *b++ = '\\\\';\n            *b++ = 'u';\n            b += write_hex16(b, uc);\n            *b++ = '\\\\';\n            *b++ = 'u';\n            b += write_hex16(b, lc);\n          }\n        } else {\n          /* Write the character directly. */\n          while (len--)\n            *b++ = *s++;\n        }\n\n        break;\n      }\n    }\n\n    /*\n     * Update *out to know about the new bytes,\n     * and set up b to write another encoded character.\n     */\n    out->cur = b;\n    sb_need(out, 14);\n    b = out->cur;\n  }\n  *b++ = '\"';\n\n  out->cur = b;\n}\n\nstatic void emit_number(SB *out, double num)\n{\n  /*\n   * This isn't exactly how JavaScript renders numbers,\n   * but it should produce valid JSON for reasonable numbers\n   * preserve precision well enough, and avoid some oddities\n   * like 0.3 -> 0.299999999999999988898 .\n   */\n  char buf[64];\n  sprintf(buf, \"%.16g\", num);\n\n  if (number_is_valid(buf))\n    sb_puts(out, buf);\n  else\n    sb_puts(out, \"null\");\n}\n\nstatic bool tag_is_valid(unsigned int tag)\n{\n  return (/* tag >= JSON_NULL && */ tag <= JSON_OBJECT);\n}\n\nstatic bool number_is_valid(const char *num)\n{\n  return (parse_number(&num, NULL) && *num == '\\0');\n}\n\nstatic bool expect_literal(const char **sp, const char *str)\n{\n  const char *s = *sp;\n\n  while (*str != '\\0')\n    if (*s++ != *str++)\n      return false;\n\n  *sp = s;\n  return true;\n}\n\n/*\n * Parses exactly 4 hex characters (capital or lowercase).\n * Fails if any input chars are not [0-9A-Fa-f].\n */\nstatic bool parse_hex16(const char **sp, uint16_t *out)\n{\n  const char *s = *sp;\n  uint16_t ret = 0;\n  uint16_t i;\n  uint16_t tmp;\n  char c;\n\n  for (i = 0; i < 4; i++) {\n    c = *s++;\n    if (c >= '0' && c <= '9')\n      tmp = c - '0';\n    else if (c >= 'A' && c <= 'F')\n      tmp = c - 'A' + 10;\n    else if (c >= 'a' && c <= 'f')\n      tmp = c - 'a' + 10;\n    else\n      return false;\n\n    ret <<= 4;\n    ret += tmp;\n  }\n\n  if (out)\n    *out = ret;\n  *sp = s;\n  return true;\n}\n\n/*\n * Encodes a 16-bit number into hexadecimal,\n * writing exactly 4 hex chars.\n */\nstatic int write_hex16(char *out, uint16_t val)\n{\n  const char *hex = \"0123456789ABCDEF\";\n\n  *out++ = hex[(val >> 12) & 0xF];\n  *out++ = hex[(val >> 8)  & 0xF];\n  *out++ = hex[(val >> 4)  & 0xF];\n  *out++ = hex[ val        & 0xF];\n\n  return 4;\n}\n\nbool json_check(const JsonNode *node, char errmsg[256])\n{\n  #define problem(...) do { \\\n      if (errmsg != NULL) \\\n        snprintf(errmsg, 256, __VA_ARGS__); \\\n      return false; \\\n    } while (0)\n\n  if (node->key != NULL && !utf8_validate(node->key))\n    problem(\"key contains invalid UTF-8\");\n\n  if (!tag_is_valid(node->tag))\n    problem(\"tag is invalid (%u)\", node->tag);\n\n  if (node->tag == JSON_BOOL) {\n    if (node->bool_ != false && node->bool_ != true)\n      problem(\"bool_ is neither false (%d) nor true (%d)\", (int)false, (int)true);\n  } else if (node->tag == JSON_STRING) {\n    if (node->string_ == NULL)\n      problem(\"string_ is NULL\");\n    if (!utf8_validate(node->string_))\n      problem(\"string_ contains invalid UTF-8\");\n  } else if (node->tag == JSON_ARRAY || node->tag == JSON_OBJECT) {\n    JsonNode *head = node->children.head;\n    JsonNode *tail = node->children.tail;\n\n    if (head == NULL || tail == NULL) {\n      if (head != NULL)\n        problem(\"tail is NULL, but head is not\");\n      if (tail != NULL)\n        problem(\"head is NULL, but tail is not\");\n    } else {\n      JsonNode *child;\n      JsonNode *last = NULL;\n\n      if (head->prev != NULL)\n        problem(\"First child's prev pointer is not NULL\");\n\n      for (child = head; child != NULL; last = child, child = child->next) {\n        if (child == node)\n          problem(\"node is its own child\");\n        if (child->next == child)\n          problem(\"child->next == child (cycle)\");\n        if (child->next == head)\n          problem(\"child->next == head (cycle)\");\n\n        if (child->parent != node)\n          problem(\"child does not point back to parent\");\n        if (child->next != NULL && child->next->prev != child)\n          problem(\"child->next does not point back to child\");\n\n        if (node->tag == JSON_ARRAY && child->key != NULL)\n          problem(\"Array element's key is not NULL\");\n        if (node->tag == JSON_OBJECT && child->key == NULL)\n          problem(\"Object member's key is NULL\");\n\n        if (!json_check(child, errmsg))\n          return false;\n      }\n\n      if (last != tail)\n        problem(\"tail does not match pointer found by starting at head and following next links\");\n    }\n  }\n\n  return true;\n\n  #undef problem\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/json.hpp",
    "content": "/*\n  Copyright (C) 2011 Joseph A. Adams (joeyadams3.14159@gmail.com)\n  All rights reserved.\n\n  Permission is hereby granted, free of charge, to any person obtaining a copy\n  of this software and associated documentation files (the \"Software\"), to deal\n  in the Software without restriction, including without limitation the rights\n  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n  copies of the Software, and to permit persons to whom the Software is\n  furnished to do so, subject to the following conditions:\n\n  The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\n  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n  THE SOFTWARE.\n*/\n\n#ifndef CCAN_JSON_H\n#define CCAN_JSON_H\n\n#include <stdbool.h>\n#include <stddef.h>\n\ntypedef enum {\n  JSON_NULL,\n  JSON_BOOL,\n  JSON_STRING,\n  JSON_NUMBER,\n  JSON_ARRAY,\n  JSON_OBJECT,\n} JsonTag;\n\ntypedef struct JsonNode JsonNode;\n\nstruct JsonNode\n{\n  /* only if parent is an object or array (NULL otherwise) */\n  JsonNode *parent;\n  JsonNode *prev, *next;\n\n  /* only if parent is an object (NULL otherwise) */\n  char *key; /* Must be valid UTF-8. */\n\n  JsonTag tag;\n  union {\n    /* JSON_BOOL */\n    bool bool_;\n\n    /* JSON_STRING */\n    char *string_; /* Must be valid UTF-8. */\n\n    /* JSON_NUMBER */\n    double number_;\n\n    /* JSON_ARRAY */\n    /* JSON_OBJECT */\n    struct {\n      JsonNode *head, *tail;\n    } children;\n  };\n};\n\n/*** Encoding, decoding, and validation ***/\n\nJsonNode   *json_decode         (const char *json);\nchar       *json_encode         (const JsonNode *node);\nchar       *json_encode_string  (const char *str);\nchar       *json_stringify      (const JsonNode *node, const char *space);\nvoid        json_delete         (JsonNode *node);\n\nbool        json_validate       (const char *json);\n\n/*** Lookup and traversal ***/\n\nJsonNode   *json_find_element   (JsonNode *array, int index);\nJsonNode   *json_find_member    (JsonNode *object, const char *key);\n\nJsonNode   *json_first_child    (const JsonNode *node);\n\n#define json_foreach(i, object_or_array)            \\\n  for ((i) = json_first_child(object_or_array);   \\\n     (i) != NULL;                               \\\n     (i) = (i)->next)\n\n/*** Construction and manipulation ***/\n\nJsonNode *json_mknull(void);\nJsonNode *json_mkbool(bool b);\nJsonNode *json_mkstring(const char *s);\nJsonNode *json_mknumber(double n);\nJsonNode *json_mkarray(void);\nJsonNode *json_mkobject(void);\n\nvoid json_append_element(JsonNode *array, JsonNode *element);\nvoid json_prepend_element(JsonNode *array, JsonNode *element);\nvoid json_append_member(JsonNode *object, const char *key, JsonNode *value);\nvoid json_prepend_member(JsonNode *object, const char *key, JsonNode *value);\n\nvoid json_remove_from_parent(JsonNode *node);\n\n/*** Debugging ***/\n\n/*\n * Look for structure and encoding problems in a JsonNode or its descendents.\n *\n * If a problem is detected, return false, writing a description of the problem\n * to errmsg (unless errmsg is NULL).\n */\nbool json_check(const JsonNode *node, char errmsg[256]);\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/kwd_arg_macros.hpp",
    "content": "#ifndef SASS_KWD_ARG_MACROS_H\n#define SASS_KWD_ARG_MACROS_H\n\n// Example usage:\n// KWD_ARG_SET(Args) {\n//   KWD_ARG(Args, string, foo);\n//   KWD_ARG(Args, int, bar);\n//   ...\n// };\n//\n// ... and later ...\n//\n// something(Args().foo(\"hey\").bar(3));\n\n#define KWD_ARG_SET(set_name) class set_name\n\n#define KWD_ARG(set_name, type, name) \\\nprivate: \\\n  type name##_; \\\npublic: \\\n  set_name& name(type name##__) { \\\n    name##_ = name##__; \\\n    return *this; \\\n  } \\\n  type name() { return name##_; } \\\nprivate:\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/lexer.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <iostream>\n#include <iomanip>\n#include \"lexer.hpp\"\n#include \"constants.hpp\"\n#include \"util_string.hpp\"\n\n\nnamespace Sass {\n  using namespace Constants;\n\n  namespace Prelexer {\n\n    //####################################\n    // BASIC CHARACTER MATCHERS\n    //####################################\n\n    // Match standard control chars\n    const char* kwd_at(const char* src) { return exactly<'@'>(src); }\n    const char* kwd_dot(const char* src) { return exactly<'.'>(src); }\n    const char* kwd_comma(const char* src) { return exactly<','>(src); };\n    const char* kwd_colon(const char* src) { return exactly<':'>(src); };\n    const char* kwd_star(const char* src) { return exactly<'*'>(src); };\n    const char* kwd_plus(const char* src) { return exactly<'+'>(src); };\n    const char* kwd_minus(const char* src) { return exactly<'-'>(src); };\n    const char* kwd_slash(const char* src) { return exactly<'/'>(src); };\n\n    bool is_number(char chr) {\n      return Util::ascii_isdigit(static_cast<unsigned char>(chr)) ||\n        chr == '-' || chr == '+';\n    }\n\n    // check if char is within a reduced ascii range\n    // valid in a uri (copied from Ruby Sass)\n    bool is_uri_character(char chr)\n    {\n      unsigned int cmp = unsigned(chr);\n      return (cmp > 41 && cmp < 127) ||\n             cmp == ':' || cmp == '/' || cmp == '|';\n    }\n\n    // check if char is within a reduced ascii range\n    // valid for escaping (copied from Ruby Sass)\n    bool is_escapable_character(char chr)\n    {\n      unsigned int cmp = unsigned(chr);\n      return cmp > 31 && cmp < 127;\n    }\n\n    // Match word character (look ahead)\n    bool is_character(char chr)\n    {\n      // valid alpha, numeric or unicode char (plus hyphen)\n      return Util::ascii_isalnum(static_cast<unsigned char>(chr)) ||\n        !Util::ascii_isascii(static_cast<unsigned char>(chr)) ||\n        chr == '-';\n    }\n\n    //####################################\n    // BASIC CLASS MATCHERS\n    //####################################\n\n    // create matchers that advance the position\n    const char* space(const char* src) { return Util::ascii_isspace(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }\n    const char* alpha(const char* src) { return Util::ascii_isalpha(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }\n    const char* nonascii(const char* src) { return Util::ascii_isascii(static_cast<unsigned char>(*src)) ? nullptr : src + 1; }\n    const char* digit(const char* src) { return Util::ascii_isdigit(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }\n    const char* xdigit(const char* src) { return Util::ascii_isxdigit(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }\n    const char* alnum(const char* src) { return Util::ascii_isalnum(static_cast<unsigned char>(*src)) ? src + 1 : nullptr; }\n    const char* hyphen(const char* src) { return *src == '-' ? src + 1 : 0; }\n    const char* uri_character(const char* src) { return is_uri_character(*src) ? src + 1 : 0; }\n    const char* escapable_character(const char* src) { return is_escapable_character(*src) ? src + 1 : 0; }\n\n    // Match multiple ctype characters.\n    const char* spaces(const char* src) { return one_plus<space>(src); }\n    const char* digits(const char* src) { return one_plus<digit>(src); }\n    const char* hyphens(const char* src) { return one_plus<hyphen>(src); }\n\n    // Whitespace handling.\n    const char* no_spaces(const char* src) { return negate< space >(src); }\n    const char* optional_spaces(const char* src) { return zero_plus< space >(src); }\n\n    // Match any single character.\n    const char* any_char(const char* src) { return *src ? src + 1 : src; }\n\n    // Match word boundary (zero-width lookahead).\n    const char* word_boundary(const char* src) { return is_character(*src) || *src == '#' ? 0 : src; }\n\n    // Match linefeed /(?:\\n|\\r\\n?|\\f)/\n    const char* re_linebreak(const char* src)\n    {\n      // end of file or unix linefeed return here\n      if (*src == 0) return src;\n      // end of file or unix linefeed return here\n      if (*src == '\\n' || *src == '\\f') return src + 1;\n      // a carriage return may optionally be followed by a linefeed\n      if (*src == '\\r') return *(src + 1) == '\\n' ? src + 2 : src + 1;\n      // no linefeed\n      return 0;\n    }\n\n    // Assert string boundaries (/\\Z|\\z|\\A/)\n    // This is a zero-width positive lookahead\n    const char* end_of_line(const char* src)\n    {\n      // end of file or unix linefeed return here\n      return *src == 0 || *src == '\\n' || *src == '\\r' || *src == '\\f' ? src : 0;\n    }\n\n    // Assert end_of_file boundary (/\\z/)\n    // This is a zero-width positive lookahead\n    const char* end_of_file(const char* src)\n    {\n      // end of file or unix linefeed return here\n      return *src == 0 ? src : 0;\n    }\n\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/lexer.hpp",
    "content": "#ifndef SASS_LEXER_H\n#define SASS_LEXER_H\n\n#include <cstring>\n\nnamespace Sass {\n  namespace Prelexer {\n\n    //####################################\n    // BASIC CHARACTER MATCHERS\n    //####################################\n\n    // Match standard control chars\n    const char* kwd_at(const char* src);\n    const char* kwd_dot(const char* src);\n    const char* kwd_comma(const char* src);\n    const char* kwd_colon(const char* src);\n    const char* kwd_star(const char* src);\n    const char* kwd_plus(const char* src);\n    const char* kwd_minus(const char* src);\n    const char* kwd_slash(const char* src);\n\n    //####################################\n    // BASIC CLASS MATCHERS\n    //####################################\n\n    // Matches ASCII digits, +, and -.\n    bool is_number(char src);\n\n    bool is_uri_character(char src);\n    bool escapable_character(char src);\n\n    // Match a single ctype predicate.\n    const char* space(const char* src);\n    const char* alpha(const char* src);\n    const char* digit(const char* src);\n    const char* xdigit(const char* src);\n    const char* alnum(const char* src);\n    const char* hyphen(const char* src);\n    const char* nonascii(const char* src);\n    const char* uri_character(const char* src);\n    const char* escapable_character(const char* src);\n\n    // Match multiple ctype characters.\n    const char* spaces(const char* src);\n    const char* digits(const char* src);\n    const char* hyphens(const char* src);\n\n    // Whitespace handling.\n    const char* no_spaces(const char* src);\n    const char* optional_spaces(const char* src);\n\n    // Match any single character (/./).\n    const char* any_char(const char* src);\n\n    // Assert word boundary (/\\b/)\n    // Is a zero-width positive lookaheads\n    const char* word_boundary(const char* src);\n\n    // Match a single linebreak (/(?:\\n|\\r\\n?)/).\n    const char* re_linebreak(const char* src);\n\n    // Assert string boundaries (/\\Z|\\z|\\A/)\n    // There are zero-width positive lookaheads\n    const char* end_of_line(const char* src);\n\n    // Assert end_of_file boundary (/\\z/)\n    const char* end_of_file(const char* src);\n    // const char* start_of_string(const char* src);\n\n    // Type definition for prelexer functions\n    typedef const char* (*prelexer)(const char*);\n\n    //####################################\n    // BASIC \"REGEX\" CONSTRUCTORS\n    //####################################\n\n    // Match a single character literal.\n    // Regex equivalent: /(?:x)/\n    template <char chr>\n    const char* exactly(const char* src) {\n      return *src == chr ? src + 1 : 0;\n    }\n\n    // Match the full string literal.\n    // Regex equivalent: /(?:literal)/\n    template <const char* str>\n    const char* exactly(const char* src) {\n      if (str == NULL) return 0;\n      const char* pre = str;\n      if (src == NULL) return 0;\n      // there is a small chance that the search string\n      // is longer than the rest of the string to look at\n      while (*pre && *src == *pre) {\n        ++src, ++pre;\n      }\n      // did the matcher finish?\n      return *pre == 0 ? src : 0;\n    }\n\n\n    // Match a single character literal.\n    // Regex equivalent: /(?:x)/i\n    // only define lower case alpha chars\n    template <char chr>\n    const char* insensitive(const char* src) {\n      return *src == chr || *src+32 == chr ? src + 1 : 0;\n    }\n\n    // Match the full string literal.\n    // Regex equivalent: /(?:literal)/i\n    // only define lower case alpha chars\n    template <const char* str>\n    const char* insensitive(const char* src) {\n      if (str == NULL) return 0;\n      const char* pre = str;\n      if (src == NULL) return 0;\n      // there is a small chance that the search string\n      // is longer than the rest of the string to look at\n      while (*pre && (*src == *pre || *src+32 == *pre)) {\n        ++src, ++pre;\n      }\n      // did the matcher finish?\n      return *pre == 0 ? src : 0;\n    }\n\n    // Match for members of char class.\n    // Regex equivalent: /[axy]/\n    template <const char* char_class>\n    const char* class_char(const char* src) {\n      const char* cc = char_class;\n      while (*cc && *src != *cc) ++cc;\n      return *cc ? src + 1 : 0;\n    }\n\n    // Match for members of char class.\n    // Regex equivalent: /[axy]+/\n    template <const char* char_class>\n    const char* class_chars(const char* src) {\n      const char* p = src;\n      while (class_char<char_class>(p)) ++p;\n      return p == src ? 0 : p;\n    }\n\n    // Match for members of char class.\n    // Regex equivalent: /[^axy]/\n    template <const char* neg_char_class>\n    const char* neg_class_char(const char* src) {\n      if (*src == 0) return 0;\n      const char* cc = neg_char_class;\n      while (*cc && *src != *cc) ++cc;\n      return *cc ? 0 : src + 1;\n    }\n\n    // Match for members of char class.\n    // Regex equivalent: /[^axy]+/\n    template <const char* neg_char_class>\n    const char* neg_class_chars(const char* src) {\n      const char* p = src;\n      while (neg_class_char<neg_char_class>(p)) ++p;\n      return p == src ? 0 : p;\n    }\n\n    // Match all except the supplied one.\n    // Regex equivalent: /[^x]/\n    template <const char chr>\n    const char* any_char_but(const char* src) {\n      return (*src && *src != chr) ? src + 1 : 0;\n    }\n\n    // Succeeds if the matcher fails.\n    // Aka. zero-width negative lookahead.\n    // Regex equivalent: /(?!literal)/\n    template <prelexer mx>\n    const char* negate(const char* src) {\n      return mx(src) ? 0 : src;\n    }\n\n    // Succeeds if the matcher succeeds.\n    // Aka. zero-width positive lookahead.\n    // Regex equivalent: /(?=literal)/\n    // just hangs around until we need it\n    template <prelexer mx>\n    const char* lookahead(const char* src) {\n      return mx(src) ? src : 0;\n    }\n\n    // Tries supplied matchers in order.\n    // Succeeds if one of them succeeds.\n    // Regex equivalent: /(?:FOO|BAR)/\n    template <const prelexer mx>\n    const char* alternatives(const char* src) {\n      const char* rslt;\n      if ((rslt = mx(src))) return rslt;\n      return 0;\n    }\n    template <const prelexer mx1, const prelexer mx2, const prelexer... mxs>\n    const char* alternatives(const char* src) {\n      const char* rslt;\n      if ((rslt = mx1(src))) return rslt;\n      return alternatives<mx2, mxs...>(src);\n    }\n\n    // Tries supplied matchers in order.\n    // Succeeds if all of them succeeds.\n    // Regex equivalent: /(?:FOO)(?:BAR)/\n    template <const prelexer mx1>\n    const char* sequence(const char* src) {\n      const char* rslt = src;\n      if (!(rslt = mx1(rslt))) return 0;\n      return rslt;\n    }\n    template <const prelexer mx1, const prelexer mx2, const prelexer... mxs>\n    const char* sequence(const char* src) {\n      const char* rslt = src;\n      if (!(rslt = mx1(rslt))) return 0;\n      return sequence<mx2, mxs...>(rslt);\n    }\n\n\n    // Match a pattern or not. Always succeeds.\n    // Regex equivalent: /(?:literal)?/\n    template <prelexer mx>\n    const char* optional(const char* src) {\n      const char* p = mx(src);\n      return p ? p : src;\n    }\n\n    // Match zero or more of the patterns.\n    // Regex equivalent: /(?:literal)*/\n    template <prelexer mx>\n    const char* zero_plus(const char* src) {\n      const char* p = mx(src);\n      while (p) src = p, p = mx(src);\n      return src;\n    }\n\n    // Match one or more of the patterns.\n    // Regex equivalent: /(?:literal)+/\n    template <prelexer mx>\n    const char* one_plus(const char* src) {\n      const char* p = mx(src);\n      if (!p) return 0;\n      while (p) src = p, p = mx(src);\n      return src;\n    }\n\n    // Match mx non-greedy until delimiter.\n    // Other prelexers are greedy by default.\n    // Regex equivalent: /(?:$mx)*?(?=$delim)\\b/\n    template <prelexer mx, prelexer delim>\n    const char* non_greedy(const char* src) {\n      while (!delim(src)) {\n        const char* p = mx(src);\n        if (p == src) return 0;\n        if (p == 0) return 0;\n        src = p;\n      }\n      return src;\n    }\n\n    //####################################\n    // ADVANCED \"REGEX\" CONSTRUCTORS\n    //####################################\n\n    // Match with word boundary rule.\n    // Regex equivalent: /(?:$mx)\\b/i\n    template <const char* str>\n    const char* keyword(const char* src) {\n      return sequence <\n               insensitive < str >,\n               word_boundary\n             >(src);\n    }\n\n    // Match with word boundary rule.\n    // Regex equivalent: /(?:$mx)\\b/\n    template <const char* str>\n    const char* word(const char* src) {\n      return sequence <\n               exactly < str >,\n               word_boundary\n             >(src);\n    }\n\n    template <char chr>\n    const char* loosely(const char* src) {\n      return sequence <\n               optional_spaces,\n               exactly < chr >\n             >(src);\n    }\n    template <const char* str>\n    const char* loosely(const char* src) {\n      return sequence <\n               optional_spaces,\n               exactly < str >\n             >(src);\n    }\n\n  }\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/listize.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <iostream>\n#include <typeinfo>\n#include <string>\n\n#include \"listize.hpp\"\n#include \"context.hpp\"\n#include \"backtrace.hpp\"\n#include \"error_handling.hpp\"\n\nnamespace Sass {\n\n  Listize::Listize()\n  {  }\n\n  Expression* Listize::perform(AST_Node* node)\n  {\n    Listize listize;\n    return node->perform(&listize);\n  }\n\n  Expression* Listize::operator()(SelectorList* sel)\n  {\n    List_Obj l = SASS_MEMORY_NEW(List, sel->pstate(), sel->length(), SASS_COMMA);\n    l->from_selector(true);\n    for (size_t i = 0, L = sel->length(); i < L; ++i) {\n      if (!sel->at(i)) continue;\n      l->append(sel->at(i)->perform(this));\n    }\n    if (l->length()) return l.detach();\n    return SASS_MEMORY_NEW(Null, l->pstate());\n  }\n\n  Expression* Listize::operator()(CompoundSelector* sel)\n  {\n    sass::string str;\n    for (size_t i = 0, L = sel->length(); i < L; ++i) {\n      Expression* e = (*sel)[i]->perform(this);\n      if (e) str += e->to_string();\n    }\n    return SASS_MEMORY_NEW(String_Quoted, sel->pstate(), str);\n  }\n\n  Expression* Listize::operator()(ComplexSelector* sel)\n  {\n    List_Obj l = SASS_MEMORY_NEW(List, sel->pstate());\n    // ToDo: investigate what this does\n    // Note: seems reated to parent ref\n    l->from_selector(true);\n\n    for (auto component : sel->elements()) {\n      if (CompoundSelectorObj compound = Cast<CompoundSelector>(component)) {\n        if (!compound->empty()) {\n          ExpressionObj hh = compound->perform(this);\n          if (hh) l->append(hh);\n        }\n      }\n      else if (component) {\n        l->append(SASS_MEMORY_NEW(String_Quoted, component->pstate(), component->to_string()));\n      }\n    }\n\n    if (l->length() == 0) return 0;\n    return l.detach();\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/listize.hpp",
    "content": "#ifndef SASS_LISTIZE_H\n#define SASS_LISTIZE_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast_fwd_decl.hpp\"\n#include \"operation.hpp\"\n\nnamespace Sass {\n\n  struct Backtrace;\n\n  class Listize : public Operation_CRTP<Expression*, Listize> {\n\n  public:\n\n    static Expression* perform(AST_Node* node);\n\n  public:\n    Listize();\n    ~Listize() { }\n\n    Expression* operator()(SelectorList*);\n    Expression* operator()(ComplexSelector*);\n    Expression* operator()(CompoundSelector*);\n\n    // generic fallback\n    template <typename U>\n    Expression* fallback(U x)\n    { return Cast<Expression>(x); }\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/mapping.hpp",
    "content": "#ifndef SASS_MAPPING_H\n#define SASS_MAPPING_H\n\n#include \"position.hpp\"\n#include \"backtrace.hpp\"\n\nnamespace Sass {\n\n  struct Mapping {\n    Position original_position;\n    Position generated_position;\n\n    Mapping(const Position& original_position, const Position& generated_position)\n    : original_position(original_position), generated_position(generated_position) { }\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/memory/allocator.cpp",
    "content": "#include \"../sass.hpp\"\n#include \"allocator.hpp\"\n#include \"memory_pool.hpp\"\n\n#if defined (_MSC_VER) // Visual studio\n#define thread_local __declspec( thread )\n#elif defined (__GCC__) // GCC\n#define thread_local __thread\n#endif\n\nnamespace Sass {\n\n#ifdef SASS_CUSTOM_ALLOCATOR\n\n  // Only use PODs for thread_local\n  // Objects get unpredictable init order\n  static thread_local MemoryPool* pool;\n  static thread_local size_t allocations;\n\n  void* allocateMem(size_t size)\n  {\n    if (pool == nullptr) {\n      pool = new MemoryPool();\n    }\n    allocations++;\n    return pool->allocate(size);\n  }\n\n  void deallocateMem(void* ptr, size_t size)\n  {\n\n    // It seems thread_local variable might be discharged!?\n    // But the destructors of e.g. static strings is still\n    // called, although their memory was discharged too.\n    // Fine with me as long as address sanitizer is happy.\n    if (pool == nullptr || allocations == 0) { return; }\n\n    pool->deallocate(ptr);\n    if (--allocations == 0) {\n      delete pool;\n      pool = nullptr;\n    }\n\n  }\n\n#endif\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/memory/allocator.hpp",
    "content": "#ifndef SASS_ALLOCATOR_H\n#define SASS_ALLOCATOR_H\n\n#include \"config.hpp\"\n#include \"../settings.hpp\"\n#include \"../MurmurHash2.hpp\"\n\n#include <vector>\n#include <limits>\n#include <iostream>\n#include <algorithm>\n#include <functional>\n\nnamespace Sass {\n\n#ifndef SASS_CUSTOM_ALLOCATOR\n\n  template <typename T> using Allocator = std::allocator<T>;\n\n#else\n\n  void* allocateMem(size_t size);\n\n  void deallocateMem(void* ptr, size_t size = 1);\n\n  template<typename T>\n  class Allocator\n  {\n  public:\n\n    // Allocator traits\n    typedef T                 type;            \n    typedef type              value_type;      \n    typedef value_type*       pointer;         \n    typedef value_type const* const_pointer;   \n    typedef value_type&       reference;       \n    typedef value_type const& const_reference; \n    typedef std::size_t       size_type;       \n    typedef std::ptrdiff_t    difference_type; \n\n    template<typename U>\n    struct rebind\n    {\n      typedef Allocator<U> other;\n    };\n\n    // Constructor\n    Allocator(void) {}\n\n    // Copy Constructor\n    template<typename U>\n    Allocator(Allocator<U> const&)\n    {}\n\n    // allocate but don't initialize count of elements of type T\n    pointer allocate(size_type count, const_pointer /* hint */ = 0)\n    {\n      return (pointer)(Sass::allocateMem(count * sizeof(T)));\n    }\n\n    // deallocate storage ptr of deleted elements\n    void deallocate(pointer ptr, size_type count)\n    {\n      Sass::deallocateMem(ptr, count);\n    }\n\n    // return maximum number of elements that can be allocated\n    size_type max_size() const throw()\n    {\n      return std::numeric_limits<size_type>::max() / sizeof(T);\n    }\n\n    // Address of object\n    type* address(type& obj) const { return &obj; }\n    type const* address(type const& obj) const { return &obj; }\n\n    // Construct object\n    void construct(type* ptr, type const& ref) const\n    {\n      // In-place copy construct\n      new(ptr) type(ref);\n    }\n\n    // Destroy object\n    void destroy(type* ptr) const\n    {\n      // Call destructor\n      ptr->~type();\n    }\n\n  };\n\n  template<typename T, typename U>\n    bool operator==(Allocator<T> const& left,\n      Allocator<U> const& right)\n  {\n    return true;\n  }\n\n  template<typename T, typename U>\n    bool operator!=(Allocator<T> const& left,\n      Allocator<U> const& right)\n  {\n    return !(left == right);\n  }\n\n#endif\n\n  namespace sass {\n    template <typename T> using vector = std::vector<T, Sass::Allocator<T>>;\n    using string = std::basic_string<char, std::char_traits<char>, Sass::Allocator<char>>;\n    using sstream = std::basic_stringstream<char, std::char_traits<char>, Sass::Allocator<char>>;\n    using ostream = std::basic_ostringstream<char, std::char_traits<char>, Sass::Allocator<char>>;\n    using istream = std::basic_istringstream<char, std::char_traits<char>, Sass::Allocator<char>>;\n  }\n\n}\n\n#ifdef SASS_CUSTOM_ALLOCATOR\n\nnamespace std {\n  // Only GCC seems to need this specialization!?\n  template <> struct hash<Sass::sass::string> {\n  public:\n    inline size_t operator()(\n      const Sass::sass::string& name) const\n    {\n      return MurmurHash2(\n        (void*)name.c_str(),\n        (int)name.size(),\n        0x73617373);\n    }\n  };\n}\n\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/memory/config.hpp",
    "content": "#ifndef SASS_MEMORY_CONFIG_H\n#define SASS_MEMORY_CONFIG_H\n\n// Define memory alignment requirements\n#define SASS_MEM_ALIGN sizeof(unsigned int)\n\n// Minimal alignment for memory fragments. Must be a multiple\n// of `SASS_MEM_ALIGN` and should not be too big (maybe 1 or 2)\n#define SassAllocatorHeadSize sizeof(unsigned int)\n\n// The number of bytes we use for our book-keeping before every\n// memory fragment. Needed to know to which bucket we belongs on\n// deallocations, or if it should go directly to the `free` call.\n#define SassAllocatorBookSize sizeof(unsigned int)\n\n// Bytes reserve for book-keeping on the arenas\n// Currently unused and for later optimization\n#define SassAllocatorArenaHeadSize 0\n\n#endif"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/memory/memory_pool.hpp",
    "content": "#ifndef SASS_MEMORY_POOL_H\n#define SASS_MEMORY_POOL_H\n\n#include <stdlib.h>\n#include <iostream>\n#include <algorithm>\n#include <climits>\n#include <vector>\n\nnamespace Sass {\n\n  // SIMPLE MEMORY-POOL ALLOCATOR WITH FREE-LIST ON TOP\n\n  // This is a memory pool allocator with a free list on top.\n  // We only allocate memory arenas from the system in specific\n  // sizes (`SassAllocatorArenaSize`). Users claim memory slices\n  // of certain sizes from the pool. If the allocation is too big\n  // to fit into our buckets, we use regular malloc/free instead.\n\n  // When the systems starts, we allocate the first arena and then\n  // start to give out addresses to memory slices. During that\n  // we steadily increase `offset` until the current arena is full.\n  // Once that happens we allocate a new arena and continue.\n  // https://en.wikipedia.org/wiki/Memory_pool\n\n  // Fragments that get deallocated are not really freed, we put\n  // them on our free-list. For every bucket we have a pointer to\n  // the first item for reuse. That item itself holds a pointer to\n  // the previously free item (regular free-list implementation).\n  // https://en.wikipedia.org/wiki/Free_list\n\n  // On allocation calls we first check if there is any suitable\n  // item on the free-list. If there is we pop it from the stack\n  // and return it to the caller. Otherwise we have to take out\n  // a new slice from the current `arena` and increase `offset`.\n\n  // Note that this is not thread safe. This is on purpose as we\n  // want to use the memory pool in a thread local usage. In order\n  // to get this thread safe you need to only allocate one pool\n  // per thread. This can be achieved by using thread local PODs.\n  // Simply create a pool on the first allocation and dispose\n  // it once all allocations have been returned. E.g. by using:\n  // static thread_local size_t allocations;\n  // static thread_local MemoryPool* pool;\n\n  class MemoryPool {\n\n    // Current arena we fill up\n    char* arena;\n\n    // Position into the arena\n    size_t offset = std::string::npos;\n\n    // A list of full arenas\n    std::vector<void*> arenas;\n\n    // One pointer for every bucket (zero init)\n    #ifdef _MSC_VER\n    #pragma warning (suppress:4351)\n    #endif\n    void* freeList[SassAllocatorBuckets]{};\n\n    // Increase the address until it sits on a\n    // memory aligned address (maybe use `aligned`).\n    inline static size_t alignMemAddr(size_t addr) {\n      return (addr + SASS_MEM_ALIGN - 1) & ~(SASS_MEM_ALIGN - 1);\n    }\n\n  public:\n\n    // Default ctor\n    MemoryPool() :\n      // Wait for first allocation\n      arena(nullptr),\n      // Set to maximum value in order to\n      // make an allocation on the first run\n      offset(std::string::npos)\n    {\n    }\n\n    // Destructor\n    ~MemoryPool() {\n      // Delete full arenas\n      for (auto area : arenas) {\n        free(area);\n      }\n      // Delete current arena\n      free(arena);\n\n    }\n\n    // Allocate a slice of the memory pool\n    void* allocate(size_t size)\n    {\n\n      // Increase size so its memory is aligned\n      size = alignMemAddr(\n        // Make sure we have enough space for us to\n        // create the pointer to the free list later\n        std::max(sizeof(void*), size)\n        // and the size needed for our book-keeping\n        + SassAllocatorBookSize);\n\n      // Size must be multiple of alignment\n      // So we can derive bucket index from it\n      size_t bucket = size / SASS_MEM_ALIGN;\n\n      // Everything bigger is allocated via malloc\n      // Malloc is optimized for exactly this case\n      if (bucket >= SassAllocatorBuckets) {\n        char* buffer = (char*)malloc(size);\n        if (buffer == nullptr) {\n          throw std::bad_alloc();\n        }\n        // Mark it for deallocation via free\n        ((unsigned int*)buffer)[0] = UINT_MAX;\n        // Return pointer after our book-keeping space\n        return (void*)(buffer + SassAllocatorBookSize);\n      }\n      // Use custom allocator\n      else {\n        // Get item from free list\n        void*& free = freeList[bucket];\n        // Do we have a free item?\n        if (free != nullptr) {\n          // Copy pointer to return\n          void* ptr = free;\n          // Update free list pointer\n          free = ((void**)ptr)[0];\n          // Return popped item\n          return ptr;\n        }\n      }\n\n      // Make sure we have enough space in the arena\n      if (!arena || offset > SassAllocatorArenaSize - size) {\n        if (arena) arenas.emplace_back(arena);\n        arena = (char*)malloc(SassAllocatorArenaSize);\n        if (arena == nullptr) throw std::bad_alloc();\n        offset = SassAllocatorArenaHeadSize;\n      }\n\n      // Get pointer into the arena\n      char* buffer = arena + offset;\n      // Consume object size\n      offset += size;\n\n      // Set the bucket index for this slice\n      ((unsigned int*)buffer)[0] = (unsigned int)bucket;\n\n      // Return pointer after our book-keeping space\n      return (void*)(buffer + SassAllocatorBookSize);\n\n    }\n    // EO allocate\n\n    void deallocate(void* ptr)\n    {\n\n      // Rewind buffer from pointer\n      char* buffer = (char*)ptr -\n        SassAllocatorBookSize;\n\n      // Get the bucket index stored in the header\n      unsigned int bucket = ((unsigned int*)buffer)[0];\n\n      // Check allocation method\n      if (bucket != UINT_MAX) {\n        // Let memory point to previous item in free list\n        ((void**)ptr)[0] = freeList[bucket];\n        // Free list now points to our memory\n        freeList[bucket] = (void*)ptr;\n      }\n      else {\n        // Release memory\n        free(buffer);\n      }\n\n    }\n    // EO deallocate\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/memory/shared_ptr.cpp",
    "content": "#include \"../sass.hpp\"\n#include <iostream>\n#include <typeinfo>\n\n#include \"shared_ptr.hpp\"\n#include \"../ast_fwd_decl.hpp\"\n\n#ifdef DEBUG_SHARED_PTR\n#include \"../debugger.hpp\"\n#endif\n\nnamespace Sass {\n\n  #ifdef DEBUG_SHARED_PTR\n  void SharedObj::dumpMemLeaks() {\n    if (!all.empty()) {\n      std::cerr << \"###################################\\n\";\n      std::cerr << \"# REPORTING MISSING DEALLOCATIONS #\\n\";\n      std::cerr << \"###################################\\n\";\n      for (SharedObj* var : all) {\n        if (AST_Node* ast = dynamic_cast<AST_Node*>(var)) {\n          debug_ast(ast);\n        } else {\n          std::cerr << \"LEAKED \" << var << \"\\n\";\n        }\n      }\n    }\n  }\n  sass::vector<SharedObj*> SharedObj::all;\n  #endif\n\n  bool SharedObj::taint = false;\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/memory/shared_ptr.hpp",
    "content": "#ifndef SASS_MEMORY_SHARED_PTR_H\n#define SASS_MEMORY_SHARED_PTR_H\n\n#include \"sass/base.h\"\n\n#include \"../sass.hpp\"\n#include \"allocator.hpp\"\n#include <cstddef>\n#include <iostream>\n#include <string>\n#include <type_traits>\n#include <vector>\n\n// https://lokiastari.com/blog/2014/12/30/c-plus-plus-by-example-smart-pointer/index.html\n// https://lokiastari.com/blog/2015/01/15/c-plus-plus-by-example-smart-pointer-part-ii/index.html\n// https://lokiastari.com/blog/2015/01/23/c-plus-plus-by-example-smart-pointer-part-iii/index.html\n\nnamespace Sass {\n\n  // Forward declaration\n  class SharedPtr;\n\n  ///////////////////////////////////////////////////////////////////////////////\n  // Use macros for the allocation task, since overloading operator `new`\n  // has been proven to be flaky under certain compilers (see comment below).\n  ///////////////////////////////////////////////////////////////////////////////\n\n  #ifdef DEBUG_SHARED_PTR\n\n    #define SASS_MEMORY_NEW(Class, ...) \\\n      ((Class*)(new Class(__VA_ARGS__))->trace(__FILE__, __LINE__)) \\\n\n    #define SASS_MEMORY_COPY(obj) \\\n      ((obj)->copy(__FILE__, __LINE__)) \\\n\n    #define SASS_MEMORY_CLONE(obj) \\\n      ((obj)->clone(__FILE__, __LINE__)) \\\n\n  #else\n\n    #define SASS_MEMORY_NEW(Class, ...) \\\n      new Class(__VA_ARGS__) \\\n\n    #define SASS_MEMORY_COPY(obj) \\\n      ((obj)->copy()) \\\n\n    #define SASS_MEMORY_CLONE(obj) \\\n      ((obj)->clone()) \\\n\n  #endif\n\n  // SharedObj is the base class for all objects that can be stored as a shared object\n  // It adds the reference counter and other values directly to the objects\n  // This gives a slight overhead when directly used as a stack object, but has some\n  // advantages for our code. It is safe to create two shared pointers from the same\n  // objects, as the \"control block\" is directly attached to it. This would lead\n  // to undefined behavior with std::shared_ptr. This also avoids the need to\n  // allocate additional control blocks and/or the need to dereference two\n  // pointers on each operation. This can be optimized in `std::shared_ptr`\n  // too by using `std::make_shared` (where the control block and the actual\n  // object are allocated in one continuous memory block via one single call).\n  class SharedObj {\n   public:\n    SharedObj() : refcount(0), detached(false) {\n      #ifdef DEBUG_SHARED_PTR\n      if (taint) all.push_back(this);\n      #endif\n    }\n    virtual ~SharedObj() {\n      #ifdef DEBUG_SHARED_PTR\n      for (size_t i = 0; i < all.size(); i++) {\n        if (all[i] == this) {\n          all.erase(all.begin() + i);\n          break;\n        }\n      }\n      #endif\n    }\n\n    #ifdef DEBUG_SHARED_PTR\n    static void dumpMemLeaks();\n    SharedObj* trace(sass::string file, size_t line) {\n      this->file = file;\n      this->line = line;\n      return this;\n    }\n    sass::string getDbgFile() { return file; }\n    size_t getDbgLine() { return line; }\n    void setDbg(bool dbg) { this->dbg = dbg; }\n    size_t getRefCount() const { return refcount; }\n    #endif\n\n    static void setTaint(bool val) { taint = val; }\n\n    #ifdef SASS_CUSTOM_ALLOCATOR\n    inline void* operator new(size_t nbytes) {\n      return allocateMem(nbytes);\n    }\n    inline void operator delete(void* ptr) {\n      return deallocateMem(ptr);\n    }\n    #endif\n\n    virtual sass::string to_string() const = 0;\n   protected:\n    friend class SharedPtr;\n    friend class Memory_Manager;\n    size_t refcount;\n    bool detached;\n    static bool taint;\n    #ifdef DEBUG_SHARED_PTR\n    sass::string file;\n    size_t line;\n    bool dbg = false;\n    static sass::vector<SharedObj*> all;\n    #endif\n  };\n\n  // SharedPtr is a intermediate (template-less) base class for SharedImpl.\n  // ToDo: there should be a way to include this in SharedImpl and to get\n  // ToDo: rid of all the static_cast that are now needed in SharedImpl.\n  class SharedPtr {\n   public:\n    SharedPtr() : node(nullptr) {}\n    SharedPtr(SharedObj* ptr) : node(ptr) {\n      incRefCount();\n    }\n    SharedPtr(const SharedPtr& obj) : SharedPtr(obj.node) {}\n    ~SharedPtr() {\n      decRefCount();\n    }\n\n    SharedPtr& operator=(SharedObj* other_node) {\n      if (node != other_node) {\n        decRefCount();\n        node = other_node;\n        incRefCount();\n      } else if (node != nullptr) {\n        node->detached = false;\n      }\n      return *this;\n    }\n\n    SharedPtr& operator=(const SharedPtr& obj) {\n      return *this = obj.node;\n    }\n\n    // Prevents all SharedPtrs from freeing this node until it is assigned to another SharedPtr.\n    SharedObj* detach() {\n      if (node != nullptr) node->detached = true;\n      #ifdef DEBUG_SHARED_PTR\n      if (node->dbg) {\n        std::cerr << \"DETACHING NODE\\n\";\n      }\n      #endif \n      return node;\n    }\n\n    SharedObj* obj() const { return node; }\n    SharedObj* operator->() const { return node; }\n    bool isNull() const { return node == nullptr; }\n    operator bool() const { return node != nullptr; }\n\n   protected:\n    SharedObj* node;\n    void decRefCount() {\n      if (node == nullptr) return;\n      --node->refcount;\n      #ifdef DEBUG_SHARED_PTR\n      if (node->dbg) std::cerr << \"- \" << node << \" X \" << node->refcount << \" (\" << this << \") \" << \"\\n\";\n      #endif\n      if (node->refcount == 0 && !node->detached) {\n        #ifdef DEBUG_SHARED_PTR\n        if (node->dbg) std::cerr << \"DELETE NODE \" << node << \"\\n\";\n        #endif\n        delete node;\n      }\n      else if (node->refcount == 0) {\n        #ifdef DEBUG_SHARED_PTR\n        if (node->dbg) std::cerr << \"NODE EVAEDED DELETE \" << node << \"\\n\";\n        #endif\n      }\n    }\n    void incRefCount() {\n      if (node == nullptr) return;\n      node->detached = false;\n      ++node->refcount;\n      #ifdef DEBUG_SHARED_PTR\n      if (node->dbg) std::cerr << \"+ \" << node << \" X \" << node->refcount << \" (\" << this << \") \" << \"\\n\";\n      #endif\n    }\n  };\n\n  template <class T>\n  class SharedImpl : private SharedPtr {\n\n  public:\n    SharedImpl() : SharedPtr(nullptr) {}\n\n    template <class U>\n    SharedImpl(U* node) :\n      SharedPtr(static_cast<T*>(node)) {}\n\n    template <class U>\n    SharedImpl(const SharedImpl<U>& impl) :\n      SharedImpl(impl.ptr()) {}\n\n    template <class U>\n    SharedImpl<T>& operator=(U *rhs) {\n      return static_cast<SharedImpl<T>&>(\n        SharedPtr::operator=(static_cast<T*>(rhs)));\n    }\n\n    template <class U>\n    SharedImpl<T>& operator=(const SharedImpl<U>& rhs) {\n      return static_cast<SharedImpl<T>&>(\n        SharedPtr::operator=(static_cast<const SharedImpl<T>&>(rhs)));\n    }\n\n    operator sass::string() const {\n      if (node) return node->to_string();\n      return \"null\";\n    }\n\n    using SharedPtr::isNull;\n    using SharedPtr::operator bool;\n    operator T*() const { return static_cast<T*>(this->obj()); }\n    operator T&() const { return *static_cast<T*>(this->obj()); }\n    T& operator* () const { return *static_cast<T*>(this->obj()); };\n    T* operator-> () const { return static_cast<T*>(this->obj()); };\n    T* ptr () const { return static_cast<T*>(this->obj()); };\n    T* detach() { return static_cast<T*>(SharedPtr::detach()); }\n\n  };\n\n  // Comparison operators, based on:\n  // https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_cmp\n\n  template<class T1, class T2>\n  bool operator==(const SharedImpl<T1>& x, const SharedImpl<T2>& y) {\n    return x.ptr() == y.ptr();\n  }\n\n  template<class T1, class T2>\n  bool operator!=(const SharedImpl<T1>& x, const SharedImpl<T2>& y) {\n    return x.ptr() != y.ptr();\n  }\n\n  template<class T1, class T2>\n  bool operator<(const SharedImpl<T1>& x, const SharedImpl<T2>& y) {\n    using CT = typename std::common_type<T1*, T2*>::type;\n    return std::less<CT>()(x.get(), y.get());\n  }\n\n  template<class T1, class T2>\n  bool operator<=(const SharedImpl<T1>& x, const SharedImpl<T2>& y) {\n    return !(y < x);\n  }\n\n  template<class T1, class T2>\n  bool operator>(const SharedImpl<T1>& x, const SharedImpl<T2>& y) {\n    return y < x;\n  }\n\n  template<class T1, class T2>\n  bool operator>=(const SharedImpl<T1>& x, const SharedImpl<T2>& y) {\n    return !(x < y);\n  }\n\n  template <class T>\n  bool operator==(const SharedImpl<T>& x, std::nullptr_t) noexcept {\n    return x.isNull();\n  }\n\n  template <class T>\n  bool operator==(std::nullptr_t, const SharedImpl<T>& x) noexcept {\n    return x.isNull();\n  }\n\n  template <class T>\n  bool operator!=(const SharedImpl<T>& x, std::nullptr_t) noexcept {\n    return !x.isNull();\n  }\n\n  template <class T>\n  bool operator!=(std::nullptr_t, const SharedImpl<T>& x) noexcept {\n    return !x.isNull();\n  }\n\n  template <class T>\n  bool operator<(const SharedImpl<T>& x, std::nullptr_t) {\n    return std::less<T*>()(x.get(), nullptr);\n  }\n\n  template <class T>\n  bool operator<(std::nullptr_t, const SharedImpl<T>& y) {\n    return std::less<T*>()(nullptr, y.get());\n  }\n\n  template <class T>\n  bool operator<=(const SharedImpl<T>& x, std::nullptr_t) {\n    return !(nullptr < x);\n  }\n\n  template <class T>\n  bool operator<=(std::nullptr_t, const SharedImpl<T>& y) {\n    return !(y < nullptr);\n  }\n\n  template <class T>\n  bool operator>(const SharedImpl<T>& x, std::nullptr_t) {\n    return nullptr < x;\n  }\n\n  template <class T>\n  bool operator>(std::nullptr_t, const SharedImpl<T>& y) {\n    return y < nullptr;\n  }\n\n  template <class T>\n  bool operator>=(const SharedImpl<T>& x, std::nullptr_t) {\n    return !(x < nullptr);\n  }\n\n  template <class T>\n  bool operator>=(std::nullptr_t, const SharedImpl<T>& y) {\n    return !(nullptr < y);\n  }\n\n}  // namespace Sass\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/memory.hpp",
    "content": "#ifndef SASS_MEMORY_H\n#define SASS_MEMORY_H\n\n#include \"settings.hpp\"\n\n// Include memory headers\n#include \"memory/config.hpp\"\n#include \"memory/allocator.hpp\"\n#include \"memory/shared_ptr.hpp\"\n#include \"memory/memory_pool.hpp\"\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/operation.hpp",
    "content": "#ifndef SASS_OPERATION_H\n#define SASS_OPERATION_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n// base classes to implement curiously recurring template pattern (CRTP)\n// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern\n\n#include <typeinfo>\n#include <stdexcept>\n\n#include \"ast_fwd_decl.hpp\"\n#include \"ast_def_macros.hpp\"\n\nnamespace Sass {\n\n  #define ATTACH_ABSTRACT_CRTP_PERFORM_METHODS()\\\n    virtual void perform(Operation<void>* op) = 0; \\\n    virtual Value* perform(Operation<Value*>* op) = 0; \\\n    virtual sass::string perform(Operation<sass::string>* op) = 0; \\\n    virtual AST_Node* perform(Operation<AST_Node*>* op) = 0; \\\n    virtual Selector* perform(Operation<Selector*>* op) = 0; \\\n    virtual Statement* perform(Operation<Statement*>* op) = 0; \\\n    virtual Expression* perform(Operation<Expression*>* op) = 0; \\\n    virtual union Sass_Value* perform(Operation<union Sass_Value*>* op) = 0; \\\n    virtual SupportsCondition* perform(Operation<SupportsCondition*>* op) = 0; \\\n\n  // you must add operators to every class\n  // ensures `this` of actual instance type\n  // we therefore call the specific operator\n  // they are virtual so most specific is used\n  #define ATTACH_CRTP_PERFORM_METHODS()\\\n    virtual void perform(Operation<void>* op) override { return (*op)(this); } \\\n    virtual Value* perform(Operation<Value*>* op) override { return (*op)(this); } \\\n    virtual sass::string perform(Operation<sass::string>* op) override { return (*op)(this); } \\\n    virtual AST_Node* perform(Operation<AST_Node*>* op) override { return (*op)(this); } \\\n    virtual Selector* perform(Operation<Selector*>* op) override { return (*op)(this); } \\\n    virtual Statement* perform(Operation<Statement*>* op) override { return (*op)(this); } \\\n    virtual Expression* perform(Operation<Expression*>* op) override { return (*op)(this); } \\\n    virtual union Sass_Value* perform(Operation<union Sass_Value*>* op) override { return (*op)(this); } \\\n    virtual SupportsCondition* perform(Operation<SupportsCondition*>* op) override { return (*op)(this); } \\\n\n  template<typename T>\n  class Operation {\n  public:\n    virtual T operator()(AST_Node* x)               = 0;\n    // statements\n    virtual T operator()(Block* x)                  = 0;\n    virtual T operator()(StyleRule* x)                = 0;\n    virtual T operator()(Bubble* x)                 = 0;\n    virtual T operator()(Trace* x)                  = 0;\n    virtual T operator()(SupportsRule* x)         = 0;\n    virtual T operator()(MediaRule* x) = 0;\n    virtual T operator()(CssMediaRule* x) = 0;\n    virtual T operator()(CssMediaQuery* x) = 0;\n    virtual T operator()(AtRootRule* x)          = 0;\n    virtual T operator()(AtRule* x)              = 0;\n    virtual T operator()(Keyframe_Rule* x)          = 0;\n    virtual T operator()(Declaration* x)            = 0;\n    virtual T operator()(Assignment* x)             = 0;\n    virtual T operator()(Import* x)                 = 0;\n    virtual T operator()(Import_Stub* x)            = 0;\n    virtual T operator()(WarningRule* x)                = 0;\n    virtual T operator()(ErrorRule* x)                  = 0;\n    virtual T operator()(DebugRule* x)                  = 0;\n    virtual T operator()(Comment* x)                = 0;\n    virtual T operator()(If* x)                     = 0;\n    virtual T operator()(ForRule* x)                    = 0;\n    virtual T operator()(EachRule* x)                   = 0;\n    virtual T operator()(WhileRule* x)                  = 0;\n    virtual T operator()(Return* x)                 = 0;\n    virtual T operator()(Content* x)                = 0;\n    virtual T operator()(ExtendRule* x)              = 0;\n    virtual T operator()(Definition* x)             = 0;\n    virtual T operator()(Mixin_Call* x)             = 0;\n    // expressions\n    virtual T operator()(Null* x)                   = 0;\n    virtual T operator()(List* x)                   = 0;\n    virtual T operator()(Map* x)                    = 0;\n    virtual T operator()(Function* x)               = 0;\n    virtual T operator()(Binary_Expression* x)      = 0;\n    virtual T operator()(Unary_Expression* x)       = 0;\n    virtual T operator()(Function_Call* x)          = 0;\n    virtual T operator()(Custom_Warning* x)         = 0;\n    virtual T operator()(Custom_Error* x)           = 0;\n    virtual T operator()(Variable* x)               = 0;\n    virtual T operator()(Number* x)                 = 0;\n    virtual T operator()(Color* x)                  = 0;\n    virtual T operator()(Color_RGBA* x)             = 0;\n    virtual T operator()(Color_HSLA* x)             = 0;\n    virtual T operator()(Boolean* x)                = 0;\n    virtual T operator()(String_Schema* x)          = 0;\n    virtual T operator()(String_Quoted* x)          = 0;\n    virtual T operator()(String_Constant* x)        = 0;\n    virtual T operator()(SupportsCondition* x)     = 0;\n    virtual T operator()(SupportsOperation* x)      = 0;\n    virtual T operator()(SupportsNegation* x)      = 0;\n    virtual T operator()(SupportsDeclaration* x)   = 0;\n    virtual T operator()(Supports_Interpolation* x) = 0;\n    virtual T operator()(Media_Query* x) = 0;\n    virtual T operator()(Media_Query_Expression* x) = 0;\n    virtual T operator()(At_Root_Query* x)          = 0;\n    virtual T operator()(Parent_Reference* x)        = 0;\n    // parameters and arguments\n    virtual T operator()(Parameter* x)              = 0;\n    virtual T operator()(Parameters* x)             = 0;\n    virtual T operator()(Argument* x)               = 0;\n    virtual T operator()(Arguments* x)              = 0;\n    // selectors\n    virtual T operator()(Selector_Schema* x)        = 0;\n    virtual T operator()(PlaceholderSelector* x)   = 0;\n    virtual T operator()(TypeSelector* x)       = 0;\n    virtual T operator()(ClassSelector* x)         = 0;\n    virtual T operator()(IDSelector* x)            = 0;\n    virtual T operator()(AttributeSelector* x)     = 0;\n    virtual T operator()(PseudoSelector* x)        = 0;\n    virtual T operator()(SelectorComponent* x) = 0;\n    virtual T operator()(SelectorCombinator* x) = 0;\n    virtual T operator()(CompoundSelector* x) = 0;\n    virtual T operator()(ComplexSelector* x) = 0;\n    virtual T operator()(SelectorList* x) = 0;\n\n  };\n\n  // example: Operation_CRTP<Expression*, Eval>\n  // T is the base return type of all visitors\n  // D is the class derived visitor class\n  // normally you want to implement all operators\n  template <typename T, typename D>\n  class Operation_CRTP : public Operation<T> {\n  public:\n    T operator()(AST_Node* x)               { return static_cast<D*>(this)->fallback(x); }\n    // statements\n    T operator()(Block* x)                  { return static_cast<D*>(this)->fallback(x); }\n    T operator()(StyleRule* x)                { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Bubble* x)                 { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Trace* x)                  { return static_cast<D*>(this)->fallback(x); }\n    T operator()(SupportsRule* x)         { return static_cast<D*>(this)->fallback(x); }\n    T operator()(MediaRule* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(CssMediaRule* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(CssMediaQuery* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(AtRootRule* x)          { return static_cast<D*>(this)->fallback(x); }\n    T operator()(AtRule* x)              { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Keyframe_Rule* x)          { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Declaration* x)            { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Assignment* x)             { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Import* x)                 { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Import_Stub* x)            { return static_cast<D*>(this)->fallback(x); }\n    T operator()(WarningRule* x)                { return static_cast<D*>(this)->fallback(x); }\n    T operator()(ErrorRule* x)                  { return static_cast<D*>(this)->fallback(x); }\n    T operator()(DebugRule* x)                  { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Comment* x)                { return static_cast<D*>(this)->fallback(x); }\n    T operator()(If* x)                     { return static_cast<D*>(this)->fallback(x); }\n    T operator()(ForRule* x)                    { return static_cast<D*>(this)->fallback(x); }\n    T operator()(EachRule* x)                   { return static_cast<D*>(this)->fallback(x); }\n    T operator()(WhileRule* x)                  { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Return* x)                 { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Content* x)                { return static_cast<D*>(this)->fallback(x); }\n    T operator()(ExtendRule* x)              { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Definition* x)             { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Mixin_Call* x)             { return static_cast<D*>(this)->fallback(x); }\n    // expressions\n    T operator()(Null* x)                   { return static_cast<D*>(this)->fallback(x); }\n    T operator()(List* x)                   { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Map* x)                    { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Function* x)               { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Binary_Expression* x)      { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Unary_Expression* x)       { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Function_Call* x)          { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Custom_Warning* x)         { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Custom_Error* x)           { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Variable* x)               { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Number* x)                 { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Color* x)                  { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Color_RGBA* x)             { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Color_HSLA* x)             { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Boolean* x)                { return static_cast<D*>(this)->fallback(x); }\n    T operator()(String_Schema* x)          { return static_cast<D*>(this)->fallback(x); }\n    T operator()(String_Constant* x)        { return static_cast<D*>(this)->fallback(x); }\n    T operator()(String_Quoted* x)          { return static_cast<D*>(this)->fallback(x); }\n    T operator()(SupportsCondition* x)     { return static_cast<D*>(this)->fallback(x); }\n    T operator()(SupportsOperation* x)      { return static_cast<D*>(this)->fallback(x); }\n    T operator()(SupportsNegation* x)      { return static_cast<D*>(this)->fallback(x); }\n    T operator()(SupportsDeclaration* x)   { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Supports_Interpolation* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Media_Query* x)            { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Media_Query_Expression* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(At_Root_Query* x)          { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Parent_Reference* x)        { return static_cast<D*>(this)->fallback(x); }\n    // parameters and arguments\n    T operator()(Parameter* x)              { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Parameters* x)             { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Argument* x)               { return static_cast<D*>(this)->fallback(x); }\n    T operator()(Arguments* x)              { return static_cast<D*>(this)->fallback(x); }\n    // selectors\n    T operator()(Selector_Schema* x)        { return static_cast<D*>(this)->fallback(x); }\n    T operator()(PlaceholderSelector* x)   { return static_cast<D*>(this)->fallback(x); }\n    T operator()(TypeSelector* x)       { return static_cast<D*>(this)->fallback(x); }\n    T operator()(ClassSelector* x)         { return static_cast<D*>(this)->fallback(x); }\n    T operator()(IDSelector* x)            { return static_cast<D*>(this)->fallback(x); }\n    T operator()(AttributeSelector* x)     { return static_cast<D*>(this)->fallback(x); }\n    T operator()(PseudoSelector* x)        { return static_cast<D*>(this)->fallback(x); }\n    T operator()(SelectorComponent* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(SelectorCombinator* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(CompoundSelector* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(ComplexSelector* x) { return static_cast<D*>(this)->fallback(x); }\n    T operator()(SelectorList* x) { return static_cast<D*>(this)->fallback(x); }\n\n    // fallback with specific type U\n    // will be called if not overloaded\n    template <typename U> inline T fallback(U x)\n    {\n      throw std::runtime_error(\n        std::string(typeid(*this).name()) + \": CRTP not implemented for \" + typeid(x).name());\n    }\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/operators.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <cmath>\n#include \"operators.hpp\"\n\nnamespace Sass {\n\n  namespace Operators {\n\n    inline double add(double x, double y) { return x + y; }\n    inline double sub(double x, double y) { return x - y; }\n    inline double mul(double x, double y) { return x * y; }\n    inline double div(double x, double y) { return x / y; } // x/0 checked by caller\n\n    inline double mod(double x, double y) { // x/0 checked by caller\n      if ((x > 0 && y < 0) || (x < 0 && y > 0)) {\n        double ret = std::fmod(x, y);\n        return ret ? ret + y : ret;\n      } else {\n        return std::fmod(x, y);\n      }\n    }\n\n    typedef double (*bop)(double, double);\n    bop ops[Sass_OP::NUM_OPS] = {\n      0, 0, // and, or\n      0, 0, 0, 0, 0, 0, // eq, neq, gt, gte, lt, lte\n      add, sub, mul, div, mod\n    };\n\n    /* static function, has no pstate or traces */\n    bool eq(ExpressionObj lhs, ExpressionObj rhs)\n    {\n      // operation is undefined if one is not a number\n      if (!lhs || !rhs) throw Exception::UndefinedOperation(lhs, rhs, Sass_OP::EQ);\n      // use compare operator from ast node\n      return *lhs == *rhs;\n    }\n\n    /* static function, throws OperationError, has no pstate or traces */\n    bool cmp(ExpressionObj lhs, ExpressionObj rhs, const Sass_OP op)\n    {\n      // can only compare numbers!?\n      Number_Obj l = Cast<Number>(lhs);\n      Number_Obj r = Cast<Number>(rhs);\n      // operation is undefined if one is not a number\n      if (!l || !r) throw Exception::UndefinedOperation(lhs, rhs, op);\n      // use compare operator from ast node\n      return *l < *r;\n    }\n\n    /* static functions, throws OperationError, has no pstate or traces */\n    bool lt(ExpressionObj lhs, ExpressionObj rhs) { return cmp(lhs, rhs, Sass_OP::LT); }\n    bool neq(ExpressionObj lhs, ExpressionObj rhs) { return eq(lhs, rhs) == false; }\n    bool gt(ExpressionObj lhs, ExpressionObj rhs) { return !cmp(lhs, rhs, Sass_OP::GT) && neq(lhs, rhs); }\n    bool lte(ExpressionObj lhs, ExpressionObj rhs) { return cmp(lhs, rhs, Sass_OP::LTE) || eq(lhs, rhs); }\n    bool gte(ExpressionObj lhs, ExpressionObj rhs) { return !cmp(lhs, rhs, Sass_OP::GTE) || eq(lhs, rhs); }\n\n    /* colour math deprecation warning */\n    void op_color_deprecation(enum Sass_OP op, sass::string lsh, sass::string rhs, const SourceSpan& pstate)\n    {\n      deprecated(\n        \"The operation `\" + lsh + \" \" + sass_op_to_name(op) + \" \" + rhs +\n        \"` is deprecated and will be an error in future versions.\",\n        \"Consider using Sass's color functions instead.\\n\"\n        \"https://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions\",\n        /*with_column=*/false, pstate);\n    }\n\n    /* static function, throws OperationError, has no traces but optional pstate for returned value */\n    Value* op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)\n    {\n      enum Sass_OP op = operand.operand;\n\n      String_Quoted* lqstr = Cast<String_Quoted>(&lhs);\n      String_Quoted* rqstr = Cast<String_Quoted>(&rhs);\n\n      sass::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt));\n      sass::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt));\n\n      if (Cast<Null>(&lhs)) throw Exception::InvalidNullOperation(&lhs, &rhs, op);\n      if (Cast<Null>(&rhs)) throw Exception::InvalidNullOperation(&lhs, &rhs, op);\n\n      sass::string sep;\n      switch (op) {\n        case Sass_OP::ADD: sep = \"\";   break;\n        case Sass_OP::SUB: sep = \"-\";  break;\n        case Sass_OP::DIV: sep = \"/\";  break;\n        case Sass_OP::EQ:  sep = \"==\"; break;\n        case Sass_OP::NEQ: sep = \"!=\"; break;\n        case Sass_OP::LT:  sep = \"<\";  break;\n        case Sass_OP::GT:  sep = \">\";  break;\n        case Sass_OP::LTE: sep = \"<=\"; break;\n        case Sass_OP::GTE: sep = \">=\"; break;\n        default:\n          throw Exception::UndefinedOperation(&lhs, &rhs, op);\n        break;\n      }\n\n      if (op == Sass_OP::ADD) {\n        // create string that might be quoted on output (but do not unquote what we pass)\n        return SASS_MEMORY_NEW(String_Quoted, pstate, lstr + rstr, 0, false, true);\n      }\n\n      // add whitespace around operator\n      // but only if result is not delayed\n      if (sep != \"\" && delayed == false) {\n        if (operand.ws_before) sep = \" \" + sep;\n        if (operand.ws_after) sep = sep + \" \";\n      }\n\n      if (op == Sass_OP::SUB || op == Sass_OP::DIV) {\n        if (lqstr && lqstr->quote_mark()) lstr = quote(lstr);\n        if (rqstr && rqstr->quote_mark()) rstr = quote(rstr);\n      }\n\n      return SASS_MEMORY_NEW(String_Constant, pstate, lstr + sep + rstr);\n    }\n\n    /* ToDo: allow to operate also with hsla colors */\n    /* static function, throws OperationError, has no traces but optional pstate for returned value */\n    Value* op_colors(enum Sass_OP op, const Color_RGBA& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)\n    {\n\n      if (lhs.a() != rhs.a()) {\n        throw Exception::AlphaChannelsNotEqual(&lhs, &rhs, op);\n      }\n      if ((op == Sass_OP::DIV || op == Sass_OP::MOD) && (!rhs.r() || !rhs.g() || !rhs.b())) {\n        throw Exception::ZeroDivisionError(lhs, rhs);\n      }\n\n      op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);\n\n      return SASS_MEMORY_NEW(Color_RGBA,\n                             pstate,\n                             ops[op](lhs.r(), rhs.r()),\n                             ops[op](lhs.g(), rhs.g()),\n                             ops[op](lhs.b(), rhs.b()),\n                             lhs.a());\n    }\n\n    /* static function, throws OperationError, has no traces but optional pstate for returned value */\n    Value* op_numbers(enum Sass_OP op, const Number& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)\n    {\n      double lval = lhs.value();\n      double rval = rhs.value();\n\n      if (op == Sass_OP::MOD && rval == 0) {\n        return SASS_MEMORY_NEW(String_Quoted, pstate, \"NaN\");\n      }\n\n      if (op == Sass_OP::DIV && rval == 0) {\n        sass::string result(lval ? \"Infinity\" : \"NaN\");\n        return SASS_MEMORY_NEW(String_Quoted, pstate, result);\n      }\n\n      size_t l_n_units = lhs.numerators.size();\n      size_t l_d_units = lhs.numerators.size();\n      size_t r_n_units = rhs.denominators.size();\n      size_t r_d_units = rhs.denominators.size();\n      // optimize out the most common and simplest case\n      if (l_n_units == r_n_units && l_d_units == r_d_units) {\n        if (l_n_units + l_d_units <= 1 && r_n_units + r_d_units <= 1) {\n          if (lhs.numerators == rhs.numerators) {\n            if (lhs.denominators == rhs.denominators) {\n              Number* v = SASS_MEMORY_COPY(&lhs);\n              v->value(ops[op](lval, rval));\n              return v;\n            }\n          }\n        }\n      }\n\n      Number_Obj v = SASS_MEMORY_COPY(&lhs);\n\n      if (lhs.is_unitless() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) {\n        v->numerators = rhs.numerators;\n        v->denominators = rhs.denominators;\n      }\n\n      if (op == Sass_OP::MUL) {\n        v->value(ops[op](lval, rval));\n        v->numerators.insert(v->numerators.end(),\n          rhs.numerators.begin(), rhs.numerators.end()\n        );\n        v->denominators.insert(v->denominators.end(),\n          rhs.denominators.begin(), rhs.denominators.end()\n        );\n        v->reduce();\n      }\n      else if (op == Sass_OP::DIV) {\n        v->value(ops[op](lval, rval));\n        v->numerators.insert(v->numerators.end(),\n          rhs.denominators.begin(), rhs.denominators.end()\n        );\n        v->denominators.insert(v->denominators.end(),\n          rhs.numerators.begin(), rhs.numerators.end()\n        );\n        v->reduce();\n      }\n      else {\n        Number ln(lhs), rn(rhs);\n        ln.reduce(); rn.reduce();\n        double f(rn.convert_factor(ln));\n        v->value(ops[op](lval, rn.value() * f));\n      }\n\n      v->pstate(pstate);\n      return v.detach();\n    }\n\n    /* static function, throws OperationError, has no traces but optional pstate for returned value */\n    Value* op_number_color(enum Sass_OP op, const Number& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)\n    {\n      double lval = lhs.value();\n\n      switch (op) {\n        case Sass_OP::ADD:\n        case Sass_OP::MUL: {\n          op_color_deprecation(op, lhs.to_string(), rhs.to_string(opt), pstate);\n          return SASS_MEMORY_NEW(Color_RGBA,\n                                pstate,\n                                ops[op](lval, rhs.r()),\n                                ops[op](lval, rhs.g()),\n                                ops[op](lval, rhs.b()),\n                                rhs.a());\n        }\n        case Sass_OP::SUB:\n        case Sass_OP::DIV: {\n          sass::string color(rhs.to_string(opt));\n          op_color_deprecation(op, lhs.to_string(), color, pstate);\n          return SASS_MEMORY_NEW(String_Quoted,\n                                pstate,\n                                lhs.to_string(opt)\n                                + sass_op_separator(op)\n                                + color);\n        }\n        default: break;\n      }\n      throw Exception::UndefinedOperation(&lhs, &rhs, op);\n    }\n\n    /* static function, throws OperationError, has no traces but optional pstate for returned value */\n    Value* op_color_number(enum Sass_OP op, const Color_RGBA& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed)\n    {\n      double rval = rhs.value();\n\n      if ((op == Sass_OP::DIV || op == Sass_OP::MOD) && rval == 0) {\n        // comparison of Fixnum with Float failed?\n        throw Exception::ZeroDivisionError(lhs, rhs);\n      }\n\n      op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);\n\n      return SASS_MEMORY_NEW(Color_RGBA,\n                            pstate,\n                            ops[op](lhs.r(), rval),\n                            ops[op](lhs.g(), rval),\n                            ops[op](lhs.b(), rval),\n                            lhs.a());\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/operators.hpp",
    "content": "#ifndef SASS_OPERATORS_H\n#define SASS_OPERATORS_H\n\n#include \"values.hpp\"\n#include \"sass/values.h\"\n\nnamespace Sass {\n\n  namespace Operators {\n\n    // equality operator using AST Node operator==\n    bool eq(ExpressionObj, ExpressionObj);\n    bool neq(ExpressionObj, ExpressionObj);\n    // specific operators based on cmp and eq\n    bool lt(ExpressionObj, ExpressionObj);\n    bool gt(ExpressionObj, ExpressionObj);\n    bool lte(ExpressionObj, ExpressionObj);\n    bool gte(ExpressionObj, ExpressionObj);\n    // arithmetic for all the combinations that matter\n    Value* op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);\n    Value* op_colors(enum Sass_OP, const Color_RGBA&, const Color_RGBA&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);\n    Value* op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);\n    Value* op_number_color(enum Sass_OP, const Number&, const Color_RGBA&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);\n    Value* op_color_number(enum Sass_OP, const Color_RGBA&, const Number&, struct Sass_Inspect_Options opt, const SourceSpan& pstate, bool delayed = false);\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/ordered_map.hpp",
    "content": "#ifndef SASS_ORDERED_MAP_H\n#define SASS_ORDERED_MAP_H\n\nnamespace Sass {\n\n  // ##########################################################################\n  // Very simple and limited container for insert ordered hash map.\n  // Piggy-back implementation on std::unordered_map and sass::vector\n  // ##########################################################################\n  template<\n    class Key,\n    class T,\n    class Hash = std::hash<Key>,\n    class KeyEqual = std::equal_to<Key>,\n    class Allocator = std::allocator<std::pair<const Key, T>>\n  >\n  class ordered_map {\n\n  private:\n\n    using map_type = typename std::unordered_map< Key, T, Hash, KeyEqual, Allocator>;\n    using map_iterator = typename std::unordered_map< Key, T, Hash, KeyEqual, Allocator>::iterator;\n    using map_const_iterator = typename std::unordered_map< Key, T, Hash, KeyEqual, Allocator>::const_iterator;\n\n    // The main unordered map\n    map_type _map;\n\n    // Keep insertion order\n    sass::vector<Key> _keys;\n    sass::vector<T> _values;\n\n    const KeyEqual _keyEqual;\n\n  public:\n\n    ordered_map() :\n      _keyEqual(KeyEqual())\n    {\n    }\n\n    ordered_map& operator= (const ordered_map& other) {\n      _map = other._map;\n      _keys = other._keys;\n      _values = other._values;\n      return *this;\n    }\n\n    std::pair<Key, T> front() {\n      return std::make_pair(\n        _keys.front(),\n        _values.front()\n      );\n    }\n\n    bool empty() const {\n      return _keys.empty();\n    }\n\n    void insert(const Key& key, const T& val) {\n      if (!hasKey(key)) {\n        _values.push_back(val);\n        _keys.push_back(key);\n      }\n      _map[key] = val;\n    }\n\n    bool hasKey(const Key& key) const {\n      return _map.find(key) != _map.end();\n    }\n\n    bool erase(const Key& key) {\n      _map.erase(key);\n      // find the position in the array\n      for (size_t i = 0; i < _keys.size(); i += 1) {\n        if (_keyEqual(key, _keys[i])) {\n          _keys.erase(_keys.begin() + i);\n          _values.erase(_values.begin() + i);\n          return true;\n        }\n      }\n      return false;\n    }\n\n    const sass::vector<Key>& keys() const { return _keys; }\n    const sass::vector<T>& values() const { return _values; }\n\n    const T& get(const Key& key) {\n      if (hasKey(key)) {\n        return _map[key];\n      }\n      throw std::runtime_error(\"Key does not exist\");\n    }\n\n    using iterator = typename sass::vector<Key>::iterator;\n    using const_iterator = typename sass::vector<Key>::const_iterator;\n    using reverse_iterator = typename sass::vector<Key>::reverse_iterator;\n    using const_reverse_iterator = typename sass::vector<Key>::const_reverse_iterator;\n\n    typename sass::vector<Key>::iterator end() { return _keys.end(); }\n    typename sass::vector<Key>::iterator begin() { return _keys.begin(); }\n    typename sass::vector<Key>::reverse_iterator rend() { return _keys.rend(); }\n    typename sass::vector<Key>::reverse_iterator rbegin() { return _keys.rbegin(); }\n    typename sass::vector<Key>::const_iterator end() const { return _keys.end(); }\n    typename sass::vector<Key>::const_iterator begin() const { return _keys.begin(); }\n    typename sass::vector<Key>::const_reverse_iterator rend() const { return _keys.rend(); }\n    typename sass::vector<Key>::const_reverse_iterator rbegin() const { return _keys.rbegin(); }\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/output.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast.hpp\"\n#include \"output.hpp\"\n#include \"util.hpp\"\n\nnamespace Sass {\n\n  Output::Output(Sass_Output_Options& opt)\n  : Inspect(Emitter(opt)),\n    charset(\"\"),\n    top_nodes(0)\n  {}\n\n  Output::~Output() { }\n\n  void Output::fallback_impl(AST_Node* n)\n  {\n    return n->perform(this);\n  }\n\n  void Output::operator()(Number* n)\n  {\n    // check for a valid unit here\n    // includes result for reporting\n    if (!n->is_valid_css_unit()) {\n      // should be handle in check_expression\n      throw Exception::InvalidValue({}, *n);\n    }\n    // use values to_string facility\n    sass::string res = n->to_string(opt);\n    // output the final token\n    append_token(res, n);\n  }\n\n  void Output::operator()(Import* imp)\n  {\n    top_nodes.push_back(imp);\n  }\n\n  void Output::operator()(Map* m)\n  {\n    // should be handle in check_expression\n    throw Exception::InvalidValue({}, *m);\n  }\n\n  OutputBuffer Output::get_buffer(void)\n  {\n\n    Emitter emitter(opt);\n    Inspect inspect(emitter);\n\n    size_t size_nodes = top_nodes.size();\n    for (size_t i = 0; i < size_nodes; i++) {\n      top_nodes[i]->perform(&inspect);\n      inspect.append_mandatory_linefeed();\n    }\n\n    // flush scheduled outputs\n    // maybe omit semicolon if possible\n    inspect.finalize(wbuf.buffer.size() == 0);\n    // prepend buffer on top\n    prepend_output(inspect.output());\n    // make sure we end with a linefeed\n    if (!ends_with(wbuf.buffer, opt.linefeed)) {\n      // if the output is not completely empty\n      if (!wbuf.buffer.empty()) append_string(opt.linefeed);\n    }\n\n    // search for unicode char\n    for(const char& chr : wbuf.buffer) {\n      // skip all ascii chars\n      // static cast to unsigned to handle `char` being signed / unsigned\n      if (static_cast<unsigned>(chr) < 128) continue;\n      // declare the charset\n      if (output_style() != COMPRESSED)\n        charset = \"@charset \\\"UTF-8\\\";\"\n                + sass::string(opt.linefeed);\n      else charset = \"\\xEF\\xBB\\xBF\";\n      // abort search\n      break;\n    }\n\n    // add charset as first line, before comments and imports\n    if (!charset.empty()) prepend_string(charset);\n\n    return wbuf;\n\n  }\n\n  void Output::operator()(Comment* c)\n  {\n    // if (indentation && txt == \"/**/\") return;\n    bool important = c->is_important();\n    if (output_style() != COMPRESSED || important) {\n      if (buffer().size() == 0) {\n        top_nodes.push_back(c);\n      } else {\n        in_comment = true;\n        append_indentation();\n        c->text()->perform(this);\n        in_comment = false;\n        if (indentation == 0) {\n          append_mandatory_linefeed();\n        } else {\n          append_optional_linefeed();\n        }\n      }\n    }\n  }\n\n  void Output::operator()(StyleRule* r)\n  {\n    Block_Obj b = r->block();\n    SelectorListObj s = r->selector();\n\n    if (!s || s->empty()) return;\n\n    // Filter out rulesets that aren't printable (process its children though)\n    if (!Util::isPrintable(r, output_style())) {\n      for (size_t i = 0, L = b->length(); i < L; ++i) {\n        const Statement_Obj& stm = b->get(i);\n        if (Cast<ParentStatement>(stm)) {\n          if (!Cast<Declaration>(stm)) {\n            stm->perform(this);\n          }\n        }\n      }\n      return;\n    }\n\n    if (output_style() == NESTED) {\n      indentation += r->tabs();\n    }\n    if (opt.source_comments) {\n      sass::ostream ss;\n      append_indentation();\n      sass::string path(File::abs2rel(r->pstate().getPath()));\n      ss << \"/* line \" << r->pstate().getLine() << \", \" << path << \" */\";\n      append_string(ss.str());\n      append_optional_linefeed();\n    }\n    scheduled_crutch = s;\n    if (s) s->perform(this);\n    append_scope_opener(b);\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      Statement_Obj stm = b->get(i);\n      bool bPrintExpression = true;\n      // Check print conditions\n      if (Declaration* dec = Cast<Declaration>(stm)) {\n        if (const String_Constant* valConst = Cast<String_Constant>(dec->value())) {\n          const sass::string& val = valConst->value();\n          if (const String_Quoted* qstr = Cast<const String_Quoted>(valConst)) {\n            if (!qstr->quote_mark() && val.empty()) {\n              bPrintExpression = false;\n            }\n          }\n        }\n        else if (List* list = Cast<List>(dec->value())) {\n          bool all_invisible = true;\n          for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {\n            Expression* item = list->get(list_i);\n            if (!item->is_invisible()) all_invisible = false;\n          }\n          if (all_invisible && !list->is_bracketed()) bPrintExpression = false;\n        }\n      }\n      // Print if OK\n      if (bPrintExpression) {\n        stm->perform(this);\n      }\n    }\n    if (output_style() == NESTED) indentation -= r->tabs();\n    append_scope_closer(b);\n\n  }\n  void Output::operator()(Keyframe_Rule* r)\n  {\n    Block_Obj b = r->block();\n    Selector_Obj v = r->name();\n\n    if (!v.isNull()) {\n      v->perform(this);\n    }\n\n    if (!b) {\n      append_colon_separator();\n      return;\n    }\n\n    append_scope_opener();\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      Statement_Obj stm = b->get(i);\n      stm->perform(this);\n      if (i < L - 1) append_special_linefeed();\n    }\n    append_scope_closer();\n  }\n\n  void Output::operator()(SupportsRule* f)\n  {\n    if (f->is_invisible()) return;\n\n    SupportsConditionObj c = f->condition();\n    Block_Obj b              = f->block();\n\n    // Filter out feature blocks that aren't printable (process its children though)\n    if (!Util::isPrintable(f, output_style())) {\n      for (size_t i = 0, L = b->length(); i < L; ++i) {\n        Statement_Obj stm = b->get(i);\n        if (Cast<ParentStatement>(stm)) {\n          stm->perform(this);\n        }\n      }\n      return;\n    }\n\n    if (output_style() == NESTED) indentation += f->tabs();\n    append_indentation();\n    append_token(\"@supports\", f);\n    append_mandatory_space();\n    c->perform(this);\n    append_scope_opener();\n\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      Statement_Obj stm = b->get(i);\n      stm->perform(this);\n      if (i < L - 1) append_special_linefeed();\n    }\n\n    if (output_style() == NESTED) indentation -= f->tabs();\n\n    append_scope_closer();\n\n  }\n\n  void Output::operator()(CssMediaRule* rule)\n  {\n    // Avoid null pointer exception\n    if (rule == nullptr) return;\n    // Skip empty/invisible rule\n    if (rule->isInvisible()) return;\n    // Avoid null pointer exception\n    if (rule->block() == nullptr) return;\n    // Skip empty/invisible rule\n    if (rule->block()->isInvisible()) return;\n    // Skip if block is empty/invisible\n    if (Util::isPrintable(rule, output_style())) {\n      // Let inspect do its magic\n      Inspect::operator()(rule);\n    }\n  }\n\n  void Output::operator()(AtRule* a)\n  {\n    sass::string      kwd   = a->keyword();\n    Selector_Obj   s     = a->selector();\n    ExpressionObj v     = a->value();\n    Block_Obj      b     = a->block();\n\n    append_indentation();\n    append_token(kwd, a);\n    if (s) {\n      append_mandatory_space();\n      in_wrapped = true;\n      s->perform(this);\n      in_wrapped = false;\n    }\n    if (v) {\n      append_mandatory_space();\n      // ruby sass bug? should use options?\n      append_token(v->to_string(/* opt */), v);\n    }\n    if (!b) {\n      append_delimiter();\n      return;\n    }\n\n    if (b->is_invisible() || b->length() == 0) {\n      append_optional_space();\n      return append_string(\"{}\");\n    }\n\n    append_scope_opener();\n\n    bool format = kwd != \"@font-face\";;\n\n    for (size_t i = 0, L = b->length(); i < L; ++i) {\n      Statement_Obj stm = b->get(i);\n      if (stm) stm->perform(this);\n      if (i < L - 1 && format) append_special_linefeed();\n    }\n\n    append_scope_closer();\n  }\n\n  void Output::operator()(String_Quoted* s)\n  {\n    if (s->quote_mark()) {\n      append_token(quote(s->value(), s->quote_mark()), s);\n    } else if (!in_comment) {\n      append_token(string_to_output(s->value()), s);\n    } else {\n      append_token(s->value(), s);\n    }\n  }\n\n  void Output::operator()(String_Constant* s)\n  {\n    sass::string value(s->value());\n    if (!in_comment && !in_custom_property) {\n      append_token(string_to_output(value), s);\n    } else {\n      append_token(value, s);\n    }\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/output.hpp",
    "content": "#ifndef SASS_OUTPUT_H\n#define SASS_OUTPUT_H\n\n#include <string>\n#include <vector>\n\n#include \"util.hpp\"\n#include \"inspect.hpp\"\n#include \"operation.hpp\"\n\nnamespace Sass {\n  class Context;\n\n  class Output : public Inspect {\n  protected:\n    using Inspect::operator();\n\n  public:\n    Output(Sass_Output_Options& opt);\n    virtual ~Output();\n\n  protected:\n    sass::string charset;\n    sass::vector<AST_Node*> top_nodes;\n\n  public:\n    OutputBuffer get_buffer(void);\n\n    virtual void operator()(Map*);\n    virtual void operator()(StyleRule*);\n    virtual void operator()(SupportsRule*);\n    virtual void operator()(CssMediaRule*);\n    virtual void operator()(AtRule*);\n    virtual void operator()(Keyframe_Rule*);\n    virtual void operator()(Import*);\n    virtual void operator()(Comment*);\n    virtual void operator()(Number*);\n    virtual void operator()(String_Quoted*);\n    virtual void operator()(String_Constant*);\n\n    void fallback_impl(AST_Node* n);\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/parser.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"parser.hpp\"\n#include \"color_maps.hpp\"\n#include \"util_string.hpp\"\n\n// Notes about delayed: some ast nodes can have delayed evaluation so\n// they can preserve their original semantics if needed. This is most\n// prominently exhibited by the division operation, since it is not\n// only a valid operation, but also a valid css statement (i.e. for\n// fonts, as in `16px/24px`). When parsing lists and expression we\n// unwrap single items from lists and other operations. A nested list\n// must not be delayed, only the items of the first level sometimes\n// are delayed (as with argument lists). To achieve this we need to\n// pass status to the list parser, so this can be set correctly.\n// Another case with delayed values are colors. In compressed mode\n// only processed values get compressed (other are left as written).\n\n\nnamespace Sass {\n  using namespace Constants;\n  using namespace Prelexer;\n\n\n  Parser::Parser(SourceData* source, Context& ctx, Backtraces traces, bool allow_parent) :\n    SourceSpan(source),\n    ctx(ctx),\n    source(source),\n    begin(source->begin()),\n    position(source->begin()),\n    end(source->end()),\n    before_token(0, 0),\n    after_token(0, 0),\n    pstate(source->getSourceSpan()),\n    traces(traces),\n    indentation(0),\n    nestings(0),\n    allow_parent(allow_parent)\n  {\n    Block_Obj root = SASS_MEMORY_NEW(Block, pstate);\n    stack.push_back(Scope::Root);\n    block_stack.push_back(root);\n    root->is_root(true);\n  }\n\n  void Parser::advanceToNextToken() {\n      lex < css_comments >(false);\n      // advance to position\n      pstate.position += pstate.offset;\n      pstate.offset.column = 0;\n      pstate.offset.line = 0;\n    }\n\n  SelectorListObj Parser::parse_selector(SourceData* source, Context& ctx, Backtraces traces, bool allow_parent)\n  {\n    Parser p(source, ctx, traces, allow_parent);\n    // ToDo: remap the source-map entries somehow\n    return p.parseSelectorList(false);\n  }\n\n  bool Parser::peek_newline(const char* start)\n  {\n    return peek_linefeed(start ? start : position)\n           && ! peek_css<exactly<'{'>>(start);\n  }\n\n  /* main entry point to parse root block */\n  Block_Obj Parser::parse()\n  {\n\n    // consume unicode BOM\n    read_bom();\n\n    // scan the input to find invalid utf8 sequences\n    const char* it = utf8::find_invalid(position, end);\n\n    // report invalid utf8\n    if (it != end) {\n      pstate.position += Offset::init(position, it);\n      traces.push_back(Backtrace(pstate));\n      throw Exception::InvalidSass(pstate, traces, \"Invalid UTF-8 sequence\");\n    }\n\n    // create a block AST node to hold children\n    Block_Obj root = SASS_MEMORY_NEW(Block, pstate, 0, true);\n\n    // check seems a bit esoteric but works\n    if (ctx.resources.size() == 1) {\n      // apply headers only on very first include\n      ctx.apply_custom_headers(root, getPath(), pstate);\n    }\n\n    // parse children nodes\n    block_stack.push_back(root);\n    parse_block_nodes(true);\n    block_stack.pop_back();\n\n    // update final position\n    root->update_pstate(pstate);\n\n    if (position != end) {\n      css_error(\"Invalid CSS\", \" after \", \": expected selector or at-rule, was \");\n    }\n\n    return root;\n  }\n\n\n  // convenience function for block parsing\n  // will create a new block ad-hoc for you\n  // this is the base block parsing function\n  Block_Obj Parser::parse_css_block(bool is_root)\n  {\n\n    // parse comments before block\n    // lex < optional_css_comments >();\n\n    // lex mandatory opener or error out\n    if (!lex_css < exactly<'{'> >()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected \\\"{\\\", was \");\n    }\n    // create new block and push to the selector stack\n    Block_Obj block = SASS_MEMORY_NEW(Block, pstate, 0, is_root);\n    block_stack.push_back(block);\n\n    if (!parse_block_nodes(is_root)) css_error(\"Invalid CSS\", \" after \", \": expected \\\"}\\\", was \");\n\n    if (!lex_css < exactly<'}'> >()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected \\\"}\\\", was \");\n    }\n\n    // update for end position\n    // this seems to be done somewhere else\n    // but that fixed selector schema issue\n    // block->update_pstate(pstate);\n\n    // parse comments after block\n    // lex < optional_css_comments >();\n\n    block_stack.pop_back();\n\n    return block;\n  }\n\n  // convenience function for block parsing\n  // will create a new block ad-hoc for you\n  // also updates the `in_at_root` flag\n  Block_Obj Parser::parse_block(bool is_root)\n  {\n    return parse_css_block(is_root);\n  }\n\n  // the main block parsing function\n  // parses stuff between `{` and `}`\n  bool Parser::parse_block_nodes(bool is_root)\n  {\n\n    // loop until end of string\n    while (position < end) {\n\n      // we should be able to refactor this\n      parse_block_comments();\n      lex < css_whitespace >();\n\n      if (lex < exactly<';'> >()) continue;\n      if (peek < end_of_file >()) return true;\n      if (peek < exactly<'}'> >()) return true;\n\n      if (parse_block_node(is_root)) continue;\n\n      parse_block_comments();\n\n      if (lex_css < exactly<';'> >()) continue;\n      if (peek_css < end_of_file >()) return true;\n      if (peek_css < exactly<'}'> >()) return true;\n\n      // illegal sass\n      return false;\n    }\n    // return success\n    return true;\n  }\n\n  // parser for a single node in a block\n  // semicolons must be lexed beforehand\n  bool Parser::parse_block_node(bool is_root) {\n\n    Block_Obj block = block_stack.back();\n\n    parse_block_comments();\n\n    // throw away white-space\n    // includes line comments\n    lex < css_whitespace >();\n\n    Lookahead lookahead_result;\n\n    // also parse block comments\n\n    // first parse everything that is allowed in functions\n    if (lex < variable >(true)) { block->append(parse_assignment()); }\n    else if (lex < kwd_err >(true)) { block->append(parse_error()); }\n    else if (lex < kwd_dbg >(true)) { block->append(parse_debug()); }\n    else if (lex < kwd_warn >(true)) { block->append(parse_warning()); }\n    else if (lex < kwd_if_directive >(true)) { block->append(parse_if_directive()); }\n    else if (lex < kwd_for_directive >(true)) { block->append(parse_for_directive()); }\n    else if (lex < kwd_each_directive >(true)) { block->append(parse_each_directive()); }\n    else if (lex < kwd_while_directive >(true)) { block->append(parse_while_directive()); }\n    else if (lex < kwd_return_directive >(true)) { block->append(parse_return_directive()); }\n\n    // parse imports to process later\n    else if (lex < kwd_import >(true)) {\n      Scope parent = stack.empty() ? Scope::Rules : stack.back();\n      if (parent != Scope::Function && parent != Scope::Root && parent != Scope::Rules && parent != Scope::Media) {\n        if (! peek_css< uri_prefix >(position)) { // this seems to go in ruby sass 3.4.20\n          error(\"Import directives may not be used within control directives or mixins.\");\n        }\n      }\n      // this puts the parsed doc into sheets\n      // import stub will fetch this in expand\n      Import_Obj imp = parse_import();\n      // if it is a url, we only add the statement\n      if (!imp->urls().empty()) block->append(imp);\n      // process all resources now (add Import_Stub nodes)\n      for (size_t i = 0, S = imp->incs().size(); i < S; ++i) {\n        block->append(SASS_MEMORY_NEW(Import_Stub, pstate, imp->incs()[i]));\n      }\n    }\n\n    else if (lex < kwd_extend >(true)) {\n      Lookahead lookahead = lookahead_for_include(position);\n      if (!lookahead.found) css_error(\"Invalid CSS\", \" after \", \": expected selector, was \");\n      SelectorListObj target;\n      if (!lookahead.has_interpolants) {\n        LOCAL_FLAG(allow_parent, false);\n        auto selector = parseSelectorList(true);\n        auto extender = SASS_MEMORY_NEW(ExtendRule, pstate, selector);\n        extender->isOptional(selector && selector->is_optional());\n        block->append(extender);\n      }\n      else {\n        LOCAL_FLAG(allow_parent, false);\n        auto selector = parse_selector_schema(lookahead.found, true);\n        auto extender = SASS_MEMORY_NEW(ExtendRule, pstate, selector);\n        // A schema is not optional yet, check once it is evaluated\n        // extender->isOptional(selector && selector->is_optional());\n        block->append(extender);\n      }\n\n    }\n\n    // selector may contain interpolations which need delayed evaluation\n    else if (\n      !(lookahead_result = lookahead_for_selector(position)).error &&\n      !lookahead_result.is_custom_property\n    )\n    {\n      block->append(parse_ruleset(lookahead_result));\n    }\n\n    // parse multiple specific keyword directives\n    else if (lex < kwd_media >(true)) { block->append(parseMediaRule()); }\n    else if (lex < kwd_at_root >(true)) { block->append(parse_at_root_block()); }\n    else if (lex < kwd_include_directive >(true)) { block->append(parse_include_directive()); }\n    else if (lex < kwd_content_directive >(true)) { block->append(parse_content_directive()); }\n    else if (lex < kwd_supports_directive >(true)) { block->append(parse_supports_directive()); }\n    else if (lex < kwd_mixin >(true)) { block->append(parse_definition(Definition::MIXIN)); }\n    else if (lex < kwd_function >(true)) { block->append(parse_definition(Definition::FUNCTION)); }\n\n    // ignore the @charset directive for now\n    else if (lex< kwd_charset_directive >(true)) { parse_charset_directive(); }\n\n    else if (lex < exactly < else_kwd >>(true)) { error(\"Invalid CSS: @else must come after @if\"); }\n\n    // generic at keyword (keep last)\n    else if (lex< at_keyword >(true)) { block->append(parse_directive()); }\n\n    else if (is_root && stack.back() != Scope::AtRoot /* && block->is_root() */) {\n      lex< css_whitespace >();\n      if (position >= end) return true;\n      css_error(\"Invalid CSS\", \" after \", \": expected 1 selector or at-rule, was \");\n    }\n    // parse a declaration\n    else\n    {\n      // ToDo: how does it handle parse errors?\n      // maybe we are expected to parse something?\n      Declaration_Obj decl = parse_declaration();\n      decl->tabs(indentation);\n      block->append(decl);\n      // maybe we have a \"sub-block\"\n      if (peek< exactly<'{'> >()) {\n        if (decl->is_indented()) ++ indentation;\n        // parse a propset that rides on the declaration's property\n        stack.push_back(Scope::Properties);\n        decl->block(parse_block());\n        stack.pop_back();\n        if (decl->is_indented()) -- indentation;\n      }\n    }\n    // something matched\n    return true;\n  }\n  // EO parse_block_nodes\n\n  // parse imports inside the\n  Import_Obj Parser::parse_import()\n  {\n    Import_Obj imp = SASS_MEMORY_NEW(Import, pstate);\n    sass::vector<std::pair<sass::string,Function_Call_Obj>> to_import;\n    bool first = true;\n    do {\n      while (lex< block_comment >());\n      if (lex< quoted_string >()) {\n        to_import.push_back(std::pair<sass::string,Function_Call_Obj>(sass::string(lexed), {}));\n      }\n      else if (lex< uri_prefix >()) {\n        Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);\n        Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, sass::string(\"url\"), args);\n\n        if (lex< quoted_string >()) {\n          ExpressionObj quoted_url = parse_string();\n          args->append(SASS_MEMORY_NEW(Argument, quoted_url->pstate(), quoted_url));\n        }\n        else if (String_Obj string_url = parse_url_function_argument()) {\n          args->append(SASS_MEMORY_NEW(Argument, string_url->pstate(), string_url));\n        }\n        else if (peek < skip_over_scopes < exactly < '(' >, exactly < ')' > > >(position)) {\n          ExpressionObj braced_url = parse_list(); // parse_interpolated_chunk(lexed);\n          args->append(SASS_MEMORY_NEW(Argument, braced_url->pstate(), braced_url));\n        }\n        else {\n          error(\"malformed URL\");\n        }\n        if (!lex< exactly<')'> >()) error(\"URI is missing ')'\");\n        to_import.push_back(std::pair<sass::string, Function_Call_Obj>(\"\", result));\n      }\n      else {\n        if (first) error(\"@import directive requires a url or quoted path\");\n        else error(\"expecting another url or quoted path in @import list\");\n      }\n      first = false;\n    } while (lex_css< exactly<','> >());\n\n    if (!peek_css< alternatives< exactly<';'>, exactly<'}'>, end_of_file > >()) {\n      List_Obj import_queries = parse_media_queries();\n      imp->import_queries(import_queries);\n    }\n\n    for(auto location : to_import) {\n      if (location.second) {\n        imp->urls().push_back(location.second);\n      }\n      // check if custom importers want to take over the handling\n      else if (!ctx.call_importers(unquote(location.first), getPath(), pstate, imp)) {\n        // nobody wants it, so we do our import\n        ctx.import_url(imp, location.first, getPath());\n      }\n    }\n\n    return imp;\n  }\n\n  Definition_Obj Parser::parse_definition(Definition::Type which_type)\n  {\n    sass::string which_str(lexed);\n    if (!lex< identifier >()) error(\"invalid name in \" + which_str + \" definition\");\n    sass::string name(Util::normalize_underscores(lexed));\n    if (which_type == Definition::FUNCTION && (name == \"and\" || name == \"or\" || name == \"not\"))\n    { error(\"Invalid function name \\\"\" + name + \"\\\".\"); }\n    SourceSpan source_position_of_def = pstate;\n    Parameters_Obj params = parse_parameters();\n    if (which_type == Definition::MIXIN) stack.push_back(Scope::Mixin);\n    else stack.push_back(Scope::Function);\n    Block_Obj body = parse_block();\n    stack.pop_back();\n    return SASS_MEMORY_NEW(Definition, source_position_of_def, name, params, body, which_type);\n  }\n\n  Parameters_Obj Parser::parse_parameters()\n  {\n    Parameters_Obj params = SASS_MEMORY_NEW(Parameters, pstate);\n    if (lex_css< exactly<'('> >()) {\n      // if there's anything there at all\n      if (!peek_css< exactly<')'> >()) {\n        do {\n          if (peek< exactly<')'> >()) break;\n          params->append(parse_parameter());\n        } while (lex_css< exactly<','> >());\n      }\n      if (!lex_css< exactly<')'> >()) {\n        css_error(\"Invalid CSS\", \" after \", \": expected \\\")\\\", was \");\n      }\n    }\n    return params;\n  }\n\n  Parameter_Obj Parser::parse_parameter()\n  {\n    if (peek< alternatives< exactly<','>, exactly< '{' >, exactly<';'> > >()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected variable (e.g. $foo), was \");\n    }\n    while (lex< alternatives < spaces, block_comment > >());\n    lex < variable >();\n    sass::string name(Util::normalize_underscores(lexed));\n    SourceSpan pos = pstate;\n    ExpressionObj val;\n    bool is_rest = false;\n    while (lex< alternatives < spaces, block_comment > >());\n    if (lex< exactly<':'> >()) { // there's a default value\n      while (lex< block_comment >());\n      val = parse_space_list();\n    }\n    else if (lex< exactly< ellipsis > >()) {\n      is_rest = true;\n    }\n    return SASS_MEMORY_NEW(Parameter, pos, name, val, is_rest);\n  }\n\n  Arguments_Obj Parser::parse_arguments()\n  {\n    Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);\n    if (lex_css< exactly<'('> >()) {\n      // if there's anything there at all\n      if (!peek_css< exactly<')'> >()) {\n        do {\n          if (peek< exactly<')'> >()) break;\n          args->append(parse_argument());\n        } while (lex_css< exactly<','> >());\n      }\n      if (!lex_css< exactly<')'> >()) {\n        css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n      }\n    }\n    return args;\n  }\n\n  Argument_Obj Parser::parse_argument()\n  {\n    if (peek< alternatives< exactly<','>, exactly< '{' >, exactly<';'> > >()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected \\\")\\\", was \");\n    }\n    if (peek_css< sequence < exactly< hash_lbrace >, exactly< rbrace > > >()) {\n      position += 2;\n      css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n    }\n\n    Argument_Obj arg;\n    if (peek_css< sequence < variable, optional_css_comments, exactly<':'> > >()) {\n      lex_css< variable >();\n      sass::string name(Util::normalize_underscores(lexed));\n      SourceSpan p = pstate;\n      lex_css< exactly<':'> >();\n      ExpressionObj val = parse_space_list();\n      arg = SASS_MEMORY_NEW(Argument, p, val, name);\n    }\n    else {\n      bool is_arglist = false;\n      bool is_keyword = false;\n      ExpressionObj val = parse_space_list();\n      List* l = Cast<List>(val);\n      if (lex_css< exactly< ellipsis > >()) {\n        if (val->concrete_type() == Expression::MAP || (\n           (l != NULL && l->separator() == SASS_HASH)\n        )) is_keyword = true;\n        else is_arglist = true;\n      }\n      arg = SASS_MEMORY_NEW(Argument, pstate, val, \"\", is_arglist, is_keyword);\n    }\n    return arg;\n  }\n\n  Assignment_Obj Parser::parse_assignment()\n  {\n    sass::string name(Util::normalize_underscores(lexed));\n    SourceSpan var_source_position = pstate;\n    if (!lex< exactly<':'> >()) error(\"expected ':' after \" + name + \" in assignment statement\");\n    if (peek_css< alternatives < exactly<';'>, end_of_file > >()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n    }\n    ExpressionObj val;\n    Lookahead lookahead = lookahead_for_value(position);\n    if (lookahead.has_interpolants && lookahead.found) {\n      val = parse_value_schema(lookahead.found);\n    } else {\n      val = parse_list();\n    }\n    bool is_default = false;\n    bool is_global = false;\n    while (peek< alternatives < default_flag, global_flag > >()) {\n      if (lex< default_flag >()) is_default = true;\n      else if (lex< global_flag >()) is_global = true;\n    }\n    return SASS_MEMORY_NEW(Assignment, var_source_position, name, val, is_default, is_global);\n  }\n\n  // a ruleset connects a selector and a block\n  StyleRuleObj Parser::parse_ruleset(Lookahead lookahead)\n  {\n    NESTING_GUARD(nestings);\n    // inherit is_root from parent block\n    Block_Obj parent = block_stack.back();\n    bool is_root = parent && parent->is_root();\n    // make sure to move up the the last position\n    lex < optional_css_whitespace >(false, true);\n    // create the connector object (add parts later)\n    StyleRuleObj ruleset = SASS_MEMORY_NEW(StyleRule, pstate);\n    // parse selector static or as schema to be evaluated later\n    if (lookahead.parsable) {\n      ruleset->selector(parseSelectorList(false));\n    }\n    else {\n      SelectorListObj list = SASS_MEMORY_NEW(SelectorList, pstate);\n      auto sc = parse_selector_schema(lookahead.position, false);\n      ruleset->schema(sc);\n      ruleset->selector(list);\n    }\n    // then parse the inner block\n    stack.push_back(Scope::Rules);\n    ruleset->block(parse_block());\n    stack.pop_back();\n    // update for end position\n    ruleset->update_pstate(pstate);\n    ruleset->block()->update_pstate(pstate);\n    // need this info for coherence checks\n    ruleset->is_root(is_root);\n    // return AST Node\n    return ruleset;\n  }\n\n  // parse a selector schema that will be evaluated in the eval stage\n  // uses a string schema internally to do the actual schema handling\n  // in the eval stage we will be re-parse it into an actual selector\n  Selector_Schema_Obj Parser::parse_selector_schema(const char* end_of_selector, bool chroot)\n  {\n    NESTING_GUARD(nestings);\n    // move up to the start\n    lex< optional_spaces >();\n    const char* i = position;\n    // selector schema re-uses string schema implementation\n    String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);\n    // the selector schema is pretty much just a wrapper for the string schema\n    Selector_Schema_Obj selector_schema = SASS_MEMORY_NEW(Selector_Schema, pstate, schema);\n    selector_schema->connect_parent(chroot == false);\n\n    // process until end\n    while (i < end_of_selector) {\n      // try to parse multiple interpolants\n      if (const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, end_of_selector)) {\n        // accumulate the preceding segment if the position has advanced\n        if (i < p) {\n          sass::string parsed(i, p);\n          String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed);\n          pstate.position += Offset(parsed);\n          str->update_pstate(pstate);\n          schema->append(str);\n        }\n\n        // skip over all nested inner interpolations up to our own delimiter\n        const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p + 2, end_of_selector);\n        // check if the interpolation never ends of only contains white-space (error out)\n        if (!j || peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) {\n          position = p+2;\n          css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n        }\n        // pass inner expression to the parser to resolve nested interpolations\n        LocalOption<const char*> partEnd(end, j);\n        LocalOption<const char*> partBeg(position, p + 2);\n        ExpressionObj interpolant = parse_list();\n        // set status on the list expression\n        interpolant->is_interpolant(true);\n        // schema->has_interpolants(true);\n        // add to the string schema\n        schema->append(interpolant);\n        // advance parser state\n        pstate.position.add(p+2, j);\n        // advance position\n        i = j;\n      }\n      // no more interpolants have been found\n      // add the last segment if there is one\n      else {\n        // make sure to add the last bits of the string up to the end (if any)\n        if (i < end_of_selector) {\n          sass::string parsed(i, end_of_selector);\n          String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed);\n          pstate.position += Offset(parsed);\n          str->update_pstate(pstate);\n          i = end_of_selector;\n          schema->append(str);\n        }\n        // exit loop\n      }\n    }\n    // EO until eos\n\n    // update position\n    position = i;\n\n    // update for end position\n    selector_schema->update_pstate(pstate);\n    schema->update_pstate(pstate);\n\n    after_token = before_token = pstate.position;\n\n    // return parsed result\n    return selector_schema.detach();\n  }\n  // EO parse_selector_schema\n\n  void Parser::parse_charset_directive()\n  {\n    lex <\n      sequence <\n        quoted_string,\n        optional_spaces,\n        exactly <';'>\n      >\n    >();\n  }\n\n  // called after parsing `kwd_include_directive`\n  Mixin_Call_Obj Parser::parse_include_directive()\n  {\n    // lex identifier into `lexed` var\n    lex_identifier(); // may error out\n    // normalize underscores to hyphens\n    sass::string name(Util::normalize_underscores(lexed));\n    // create the initial mixin call object\n    Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, Arguments_Obj{});\n    // parse mandatory arguments\n    call->arguments(parse_arguments());\n    // parse using and optional block parameters\n    bool has_parameters = lex< kwd_using >() != nullptr;\n\n    if (has_parameters) {\n      if (!peek< exactly<'('> >()) css_error(\"Invalid CSS\", \" after \", \": expected \\\"(\\\", was \");\n    } else {\n      if (peek< exactly<'('> >()) css_error(\"Invalid CSS\", \" after \", \": expected \\\";\\\", was \");\n    }\n\n    if (has_parameters) call->block_parameters(parse_parameters());\n\n    // parse optional block\n    if (peek < exactly <'{'> >()) {\n      call->block(parse_block());\n    }\n    else if (has_parameters)  {\n      css_error(\"Invalid CSS\", \" after \", \": expected \\\"{\\\", was \");\n    }\n    // return ast node\n    return call.detach();\n  }\n  // EO parse_include_directive\n\n\n  SimpleSelectorObj Parser::parse_simple_selector()\n  {\n    lex < css_comments >(false);\n    if (lex< class_name >()) {\n      return SASS_MEMORY_NEW(ClassSelector, pstate, lexed);\n    }\n    else if (lex< id_name >()) {\n      return SASS_MEMORY_NEW(IDSelector, pstate, lexed);\n    }\n    else if (lex< alternatives < variable, number, static_reference_combinator > >()) {\n      return SASS_MEMORY_NEW(TypeSelector, pstate, lexed);\n    }\n    else if (peek< pseudo_not >()) {\n      return parse_negated_selector2();\n    }\n    else if (peek< re_pseudo_selector >()) {\n      return parse_pseudo_selector();\n    }\n    else if (peek< exactly<':'> >()) {\n      return parse_pseudo_selector();\n    }\n    else if (lex < exactly<'['> >()) {\n      return parse_attribute_selector();\n    }\n    else if (lex< placeholder >()) {\n      return SASS_MEMORY_NEW(PlaceholderSelector, pstate, lexed);\n    }\n    else {\n      css_error(\"Invalid CSS\", \" after \", \": expected selector, was \");\n    }\n    // failed\n    return {};\n  }\n\n  PseudoSelectorObj Parser::parse_negated_selector2()\n  {\n    lex< pseudo_not >();\n    sass::string name(lexed);\n    SourceSpan nsource_position = pstate;\n    SelectorListObj negated = parseSelectorList(true);\n    if (!lex< exactly<')'> >()) {\n      error(\"negated selector is missing ')'\");\n    }\n    name.erase(name.size() - 1);\n\n    PseudoSelector* sel = SASS_MEMORY_NEW(PseudoSelector, nsource_position, name.substr(1));\n    sel->selector(negated);\n    return sel;\n  }\n\n  // Helper to clean binominal string\n  bool BothAreSpaces(char lhs, char rhs) { return isspace(lhs) && isspace(rhs); }\n\n  // a pseudo selector often starts with one or two colons\n  // it can contain more selectors inside parentheses\n  SimpleSelectorObj Parser::parse_pseudo_selector() {\n\n    // Lex one or two colon characters\n    if (lex<pseudo_prefix>()) {\n      sass::string colons(lexed);\n      // Check if it is a pseudo element\n      bool element = colons.size() == 2;\n\n      if (lex< sequence<\n        // we keep the space within the name, strange enough\n        // ToDo: refactor output to schedule the space for it\n        // or do we really want to keep the real white-space?\n        sequence< identifier, optional < block_comment >, exactly<'('> >\n      > >())\n      {\n\n        sass::string name(lexed);\n        name.erase(name.size() - 1);\n        SourceSpan p = pstate;\n\n        // specially parse nth-child pseudo selectors\n        if (lex_css < sequence < binomial, word_boundary >>()) {\n          sass::string parsed(lexed); // always compacting binominals (as dart-sass)\n          parsed.erase(std::unique(parsed.begin(), parsed.end(), BothAreSpaces), parsed.end());\n          String_Constant_Obj arg = SASS_MEMORY_NEW(String_Constant, pstate, parsed);\n          PseudoSelector* pseudo = SASS_MEMORY_NEW(PseudoSelector, p, name, element);\n          if (lex < sequence < css_whitespace, insensitive < of_kwd >>>(false)) {\n            pseudo->selector(parseSelectorList(true));\n          }\n          pseudo->argument(arg);\n          if (lex_css< exactly<')'> >()) {\n            return pseudo;\n          }\n        }\n        else {\n          if (peek_css< exactly<')'>>()  && Util::equalsLiteral(\"nth-\", name.substr(0, 4))) {\n            css_error(\"Invalid CSS\", \" after \", \": expected An+B expression, was \");\n          }\n\n          sass::string unvendored = Util::unvendor(name);\n\n          if (unvendored == \"not\" || unvendored == \"matches\" || unvendored == \"current\"  || unvendored == \"any\" || unvendored == \"has\" || unvendored == \"host\" || unvendored == \"host-context\" || unvendored == \"slotted\") {\n             if (SelectorListObj wrapped = parseSelectorList(true)) {\n                if (wrapped && lex_css< exactly<')'> >()) {\n                  PseudoSelector* pseudo = SASS_MEMORY_NEW(PseudoSelector, p, name, element);\n                  pseudo->selector(wrapped);\n                  return pseudo;\n                }\n              }\n          } else {\n            String_Schema_Obj arg = parse_css_variable_value();\n            PseudoSelector* pseudo = SASS_MEMORY_NEW(PseudoSelector, p, name, element);\n            pseudo->argument(arg);\n\n            if (lex_css< exactly<')'> >()) {\n              return pseudo;\n            }\n          }\n        }\n\n      }\n      // EO if pseudo selector\n\n      else if (lex < sequence< optional < pseudo_prefix >, identifier > >()) {\n        return SASS_MEMORY_NEW(PseudoSelector, pstate, lexed, element);\n      }\n      else if (lex < pseudo_prefix >()) {\n        css_error(\"Invalid CSS\", \" after \", \": expected pseudoclass or pseudoelement, was \");\n      }\n\n    }\n    else {\n      lex < identifier >(); // needed for error message?\n      css_error(\"Invalid CSS\", \" after \", \": expected selector, was \");\n    }\n\n\n    css_error(\"Invalid CSS\", \" after \", \": expected \\\")\\\", was \");\n\n    // unreachable statement\n    return {};\n  }\n\n  const char* Parser::re_attr_sensitive_close(const char* src)\n  {\n    return alternatives < exactly<']'>, exactly<'/'> >(src);\n  }\n\n  const char* Parser::re_attr_insensitive_close(const char* src)\n  {\n    return sequence < insensitive<'i'>, re_attr_sensitive_close >(src);\n  }\n\n  AttributeSelectorObj Parser::parse_attribute_selector()\n  {\n    SourceSpan p = pstate;\n    if (!lex_css< attribute_name >()) error(\"invalid attribute name in attribute selector\");\n    sass::string name(lexed);\n    if (lex_css< re_attr_sensitive_close >()) {\n      return SASS_MEMORY_NEW(AttributeSelector, p, name, \"\", String_Obj{});\n    }\n    else if (lex_css< re_attr_insensitive_close >()) {\n      char modifier = lexed.begin[0];\n      return SASS_MEMORY_NEW(AttributeSelector, p, name, \"\", String_Obj{}, modifier);\n    }\n    if (!lex_css< alternatives< exact_match, class_match, dash_match,\n                                prefix_match, suffix_match, substring_match > >()) {\n      error(\"invalid operator in attribute selector for \" + name);\n    }\n    sass::string matcher(lexed);\n\n    String_Obj value;\n    if (lex_css< identifier >()) {\n      value = SASS_MEMORY_NEW(String_Constant, p, lexed);\n    }\n    else if (lex_css< quoted_string >()) {\n      value = parse_interpolated_chunk(lexed, true); // needed!\n    }\n    else {\n      error(\"expected a string constant or identifier in attribute selector for \" + name);\n    }\n\n    if (lex_css< re_attr_sensitive_close >()) {\n      return SASS_MEMORY_NEW(AttributeSelector, p, name, matcher, value, 0);\n    }\n    else if (lex_css< re_attr_insensitive_close >()) {\n      char modifier = lexed.begin[0];\n      return SASS_MEMORY_NEW(AttributeSelector, p, name, matcher, value, modifier);\n    }\n    error(\"unterminated attribute selector for \" + name);\n    return {}; // to satisfy compilers (error must not return)\n  }\n\n  /* parse block comment and add to block */\n  void Parser::parse_block_comments(bool store)\n  {\n    Block_Obj block = block_stack.back();\n\n    while (lex< block_comment >()) {\n      bool is_important = lexed.begin[2] == '!';\n      // flag on second param is to skip loosely over comments\n      String_Obj contents = parse_interpolated_chunk(lexed, true, false);\n      if (store) block->append(SASS_MEMORY_NEW(Comment, pstate, contents, is_important));\n    }\n  }\n\n  Declaration_Obj Parser::parse_declaration() {\n    String_Obj prop;\n    bool is_custom_property = false;\n    if (lex< sequence< optional< exactly<'*'> >, identifier_schema > >()) {\n      const sass::string property(lexed);\n      is_custom_property = property.compare(0, 2, \"--\") == 0;\n      prop = parse_identifier_schema();\n    }\n    else if (lex< sequence< optional< exactly<'*'> >, identifier, zero_plus< block_comment > > >()) {\n      const sass::string property(lexed);\n      is_custom_property = property.compare(0, 2, \"--\") == 0;\n      prop = SASS_MEMORY_NEW(String_Constant, pstate, lexed);\n    }\n    else {\n      css_error(\"Invalid CSS\", \" after \", \": expected \\\"}\\\", was \");\n    }\n    bool is_indented = true;\n    const sass::string property(lexed);\n    if (!lex_css< one_plus< exactly<':'> > >()) error(\"property \\\"\" + escape_string(property)  + \"\\\" must be followed by a ':'\");\n    if (!is_custom_property && match< sequence< optional_css_comments, exactly<';'> > >()) error(\"style declaration must contain a value\");\n    if (match< sequence< optional_css_comments, exactly<'{'> > >()) is_indented = false; // don't indent if value is empty\n    if (is_custom_property) {\n      return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, parse_css_variable_value(), false, true);\n    }\n    lex < css_comments >(false);\n    if (peek_css< static_value >()) {\n      return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, parse_static_value()/*, lex<kwd_important>()*/);\n    }\n    else {\n      ExpressionObj value;\n      Lookahead lookahead = lookahead_for_value(position);\n      if (lookahead.found) {\n        if (lookahead.has_interpolants) {\n          value = parse_value_schema(lookahead.found);\n        } else {\n          value = parse_list(DELAYED);\n        }\n      }\n      else {\n        value = parse_list(DELAYED);\n        if (List* list = Cast<List>(value)) {\n          if (!list->is_bracketed() && list->length() == 0 && !peek< exactly <'{'> >()) {\n            css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n          }\n        }\n      }\n      lex < css_comments >(false);\n      Declaration_Obj decl = SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, value/*, lex<kwd_important>()*/);\n      decl->is_indented(is_indented);\n      decl->update_pstate(pstate);\n      return decl;\n    }\n  }\n\n  ExpressionObj Parser::parse_map()\n  {\n    NESTING_GUARD(nestings);\n    ExpressionObj key = parse_list();\n    List_Obj map = SASS_MEMORY_NEW(List, pstate, 0, SASS_HASH);\n\n    // it's not a map so return the lexed value as a list value\n    if (!lex_css< exactly<':'> >())\n    { return key; }\n\n    List_Obj l = Cast<List>(key);\n    if (l && l->separator() == SASS_COMMA) {\n      css_error(\"Invalid CSS\", \" after \", \": expected \\\")\\\", was \");\n    }\n\n    ExpressionObj value = parse_space_list();\n\n    map->append(key);\n    map->append(value);\n\n    while (lex_css< exactly<','> >())\n    {\n      // allow trailing commas - #495\n      if (peek_css< exactly<')'> >(position))\n      { break; }\n\n      key = parse_space_list();\n\n      if (!(lex< exactly<':'> >()))\n      { css_error(\"Invalid CSS\", \" after \", \": expected \\\":\\\", was \"); }\n\n      value = parse_space_list();\n\n      map->append(key);\n      map->append(value);\n    }\n\n    SourceSpan ps = map->pstate();\n    ps.offset = pstate.position - ps.position + pstate.offset;\n    map->pstate(ps);\n\n    return map;\n  }\n\n  ExpressionObj Parser::parse_bracket_list()\n  {\n    NESTING_GUARD(nestings);\n    // check if we have an empty list\n    // return the empty list as such\n    if (peek_css< list_terminator >(position))\n    {\n      // return an empty list (nothing to delay)\n      return SASS_MEMORY_NEW(List, pstate, 0, SASS_SPACE, false, true);\n    }\n\n    bool has_paren = peek_css< exactly<'('> >() != NULL;\n\n    // now try to parse a space list\n    ExpressionObj list = parse_space_list();\n    // if it's a singleton, return it (don't wrap it)\n    if (!peek_css< exactly<','> >(position)) {\n      List_Obj l = Cast<List>(list);\n      if (!l || l->is_bracketed() || has_paren) {\n        List_Obj bracketed_list = SASS_MEMORY_NEW(List, pstate, 1, SASS_SPACE, false, true);\n        bracketed_list->append(list);\n        return bracketed_list;\n      }\n      l->is_bracketed(true);\n      return l;\n    }\n\n    // if we got so far, we actually do have a comma list\n    List_Obj bracketed_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_COMMA, false, true);\n    // wrap the first expression\n    bracketed_list->append(list);\n\n    while (lex_css< exactly<','> >())\n    {\n      // check for abort condition\n      if (peek_css< list_terminator >(position)\n      ) { break; }\n      // otherwise add another expression\n      bracketed_list->append(parse_space_list());\n    }\n    // return the list\n    return bracketed_list;\n  }\n\n  // parse list returns either a space separated list,\n  // a comma separated list or any bare expression found.\n  // so to speak: we unwrap items from lists if possible here!\n  ExpressionObj Parser::parse_list(bool delayed)\n  {\n    NESTING_GUARD(nestings);\n    return parse_comma_list(delayed);\n  }\n\n  // will return singletons unwrapped\n  ExpressionObj Parser::parse_comma_list(bool delayed)\n  {\n    NESTING_GUARD(nestings);\n    // check if we have an empty list\n    // return the empty list as such\n    if (peek_css< list_terminator >(position))\n    {\n      // return an empty list (nothing to delay)\n      return SASS_MEMORY_NEW(List, pstate, 0);\n    }\n\n    // now try to parse a space list\n    ExpressionObj list = parse_space_list();\n    // if it's a singleton, return it (don't wrap it)\n    if (!peek_css< exactly<','> >(position)) {\n      // set_delay doesn't apply to list children\n      // so this will only undelay single values\n      if (!delayed) list->set_delayed(false);\n      return list;\n    }\n\n    // if we got so far, we actually do have a comma list\n    List_Obj comma_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_COMMA);\n    // wrap the first expression\n    comma_list->append(list);\n\n    while (lex_css< exactly<','> >())\n    {\n      // check for abort condition\n      if (peek_css< list_terminator >(position)\n      ) { break; }\n      // otherwise add another expression\n      comma_list->append(parse_space_list());\n    }\n    // return the list\n    return comma_list;\n  }\n  // EO parse_comma_list\n\n  // will return singletons unwrapped\n  ExpressionObj Parser::parse_space_list()\n  {\n    NESTING_GUARD(nestings);\n    ExpressionObj disj1 = parse_disjunction();\n    // if it's a singleton, return it (don't wrap it)\n    if (peek_css< space_list_terminator >(position)\n    ) {\n      return disj1; }\n\n    List_Obj space_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_SPACE);\n    space_list->append(disj1);\n\n    while (\n      !(peek_css< space_list_terminator >(position)) &&\n      peek_css< optional_css_whitespace >() != end\n    ) {\n      // the space is parsed implicitly?\n      space_list->append(parse_disjunction());\n    }\n    // return the list\n    return space_list;\n  }\n  // EO parse_space_list\n\n  // parse logical OR operation\n  ExpressionObj Parser::parse_disjunction()\n  {\n    NESTING_GUARD(nestings);\n    advanceToNextToken();\n    SourceSpan state(pstate);\n    // parse the left hand side conjunction\n    ExpressionObj conj = parse_conjunction();\n    // parse multiple right hand sides\n    sass::vector<ExpressionObj> operands;\n    while (lex_css< kwd_or >())\n      operands.push_back(parse_conjunction());\n    // if it's a singleton, return it directly\n    if (operands.size() == 0) return conj;\n    // fold all operands into one binary expression\n    ExpressionObj ex = fold_operands(conj, operands, { Sass_OP::OR });\n    state.offset = pstate.position - state.position + pstate.offset;\n    ex->pstate(state);\n    return ex;\n  }\n  // EO parse_disjunction\n\n  // parse logical AND operation\n  ExpressionObj Parser::parse_conjunction()\n  {\n    NESTING_GUARD(nestings);\n    advanceToNextToken();\n    SourceSpan state(pstate);\n    // parse the left hand side relation\n    ExpressionObj rel = parse_relation();\n    // parse multiple right hand sides\n    sass::vector<ExpressionObj> operands;\n    while (lex_css< kwd_and >()) {\n      operands.push_back(parse_relation());\n    }\n    // if it's a singleton, return it directly\n    if (operands.size() == 0) return rel;\n    // fold all operands into one binary expression\n    ExpressionObj ex = fold_operands(rel, operands, { Sass_OP::AND });\n    state.offset = pstate.position - state.position + pstate.offset;\n    ex->pstate(state);\n    return ex;\n  }\n  // EO parse_conjunction\n\n  // parse comparison operations\n  ExpressionObj Parser::parse_relation()\n  {\n    NESTING_GUARD(nestings);\n    advanceToNextToken();\n    SourceSpan state(pstate);\n    // parse the left hand side expression\n    ExpressionObj lhs = parse_expression();\n    sass::vector<ExpressionObj> operands;\n    sass::vector<Operand> operators;\n    // if it's a singleton, return it (don't wrap it)\n    while (peek< alternatives <\n            kwd_eq,\n            kwd_neq,\n            kwd_gte,\n            kwd_gt,\n            kwd_lte,\n            kwd_lt\n          > >(position))\n    {\n      // is directly adjancent to expression?\n      bool left_ws = peek < css_comments >() != NULL;\n      // parse the operator\n      enum Sass_OP op\n      = lex<kwd_eq>()  ? Sass_OP::EQ\n      : lex<kwd_neq>() ? Sass_OP::NEQ\n      : lex<kwd_gte>() ? Sass_OP::GTE\n      : lex<kwd_lte>() ? Sass_OP::LTE\n      : lex<kwd_gt>()  ? Sass_OP::GT\n      : lex<kwd_lt>()  ? Sass_OP::LT\n      // we checked the possibilities on top of fn\n      :                  Sass_OP::EQ;\n      // is directly adjacent to expression?\n      bool right_ws = peek < css_comments >() != NULL;\n      operators.push_back({ op, left_ws, right_ws });\n      operands.push_back(parse_expression());\n    }\n    // we are called recursively for list, so we first\n    // fold inner binary expression which has delayed\n    // correctly set to zero. After folding we also unwrap\n    // single nested items. So we cannot set delay on the\n    // returned result here, as we have lost nestings ...\n    ExpressionObj ex = fold_operands(lhs, operands, operators);\n    state.offset = pstate.position - state.position + pstate.offset;\n    ex->pstate(state);\n    return ex;\n  }\n  // parse_relation\n\n  // parse expression valid for operations\n  // called from parse_relation\n  // called from parse_for_directive\n  // called from parse_media_expression\n  // parse addition and subtraction operations\n  ExpressionObj Parser::parse_expression()\n  {\n    NESTING_GUARD(nestings);\n    advanceToNextToken();\n    SourceSpan state(pstate);\n    // parses multiple add and subtract operations\n    // NOTE: make sure that identifiers starting with\n    // NOTE: dashes do NOT count as subtract operation\n    ExpressionObj lhs = parse_operators();\n    // if it's a singleton, return it (don't wrap it)\n    if (!(peek_css< exactly<'+'> >(position) ||\n          // condition is a bit mysterious, but some combinations should not be counted as operations\n          (peek< no_spaces >(position) && peek< sequence< negate< unsigned_number >, exactly<'-'>, negate< space > > >(position)) ||\n          (peek< sequence< negate< unsigned_number >, exactly<'-'>, negate< unsigned_number > > >(position))) ||\n          peek< sequence < zero_plus < exactly <'-' > >, identifier > >(position))\n    { return lhs; }\n\n    sass::vector<ExpressionObj> operands;\n    sass::vector<Operand> operators;\n    bool left_ws = peek < css_comments >() != NULL;\n    while (\n      lex_css< exactly<'+'> >() ||\n\n      (\n      ! peek_css< sequence < zero_plus < exactly <'-' > >, identifier > >(position)\n      && lex_css< sequence< negate< digit >, exactly<'-'> > >()\n      )\n\n    ) {\n\n      bool right_ws = peek < css_comments >() != NULL;\n      operators.push_back({ lexed.to_string() == \"+\" ? Sass_OP::ADD : Sass_OP::SUB, left_ws, right_ws });\n      operands.push_back(parse_operators());\n      left_ws = peek < css_comments >() != NULL;\n    }\n\n    if (operands.size() == 0) return lhs;\n    ExpressionObj ex = fold_operands(lhs, operands, operators);\n    state.offset = pstate.position - state.position + pstate.offset;\n    ex->pstate(state);\n    return ex;\n  }\n\n  // parse addition and subtraction operations\n  ExpressionObj Parser::parse_operators()\n  {\n    NESTING_GUARD(nestings);\n    advanceToNextToken();\n    SourceSpan state(pstate);\n    ExpressionObj factor = parse_factor();\n    // if it's a singleton, return it (don't wrap it)\n    sass::vector<ExpressionObj> operands; // factors\n    sass::vector<Operand> operators; // ops\n    // lex operations to apply to lhs\n    const char* left_ws = peek < css_comments >();\n    while (lex_css< class_char< static_ops > >()) {\n      const char* right_ws = peek < css_comments >();\n      switch(*lexed.begin) {\n        case '*': operators.push_back({ Sass_OP::MUL, left_ws != 0, right_ws != 0 }); break;\n        case '/': operators.push_back({ Sass_OP::DIV, left_ws != 0, right_ws != 0 }); break;\n        case '%': operators.push_back({ Sass_OP::MOD, left_ws != 0, right_ws != 0 }); break;\n        default: throw std::runtime_error(\"unknown static op parsed\");\n      }\n      operands.push_back(parse_factor());\n      left_ws = peek < css_comments >();\n    }\n    // operands and operators to binary expression\n    ExpressionObj ex = fold_operands(factor, operands, operators);\n    state.offset = pstate.position - state.position + pstate.offset;\n    ex->pstate(state);\n    return ex;\n  }\n  // EO parse_operators\n\n\n  // called from parse_operators\n  // called from parse_value_schema\n  ExpressionObj Parser::parse_factor()\n  {\n    NESTING_GUARD(nestings);\n    lex < css_comments >(false);\n    if (lex_css< exactly<'('> >()) {\n      // parse_map may return a list\n      ExpressionObj value = parse_map();\n      // lex the expected closing parenthesis\n      if (!lex_css< exactly<')'> >()) error(\"unclosed parenthesis\");\n      // expression can be evaluated\n      return value;\n    }\n    else if (lex_css< exactly<'['> >()) {\n      // explicit bracketed\n      ExpressionObj value = parse_bracket_list();\n      // lex the expected closing square bracket\n      if (!lex_css< exactly<']'> >()) error(\"unclosed squared bracket\");\n      return value;\n    }\n    // string may be interpolated\n    // if (lex< quoted_string >()) {\n    //   return &parse_string();\n    // }\n    else if (peek< ie_property >()) {\n      return parse_ie_property();\n    }\n    else if (peek< ie_keyword_arg >()) {\n      return parse_ie_keyword_arg();\n    }\n    else if (peek< sequence < calc_fn_call, exactly <'('> > >()) {\n      return parse_calc_function();\n    }\n    else if (lex < functional_schema >()) {\n      return parse_function_call_schema();\n    }\n    else if (lex< identifier_schema >()) {\n      String_Obj string = parse_identifier_schema();\n      if (String_Schema* schema = Cast<String_Schema>(string)) {\n        if (lex < exactly < '(' > >()) {\n          schema->append(parse_list());\n          lex < exactly < ')' > >();\n        }\n      }\n      return string;\n    }\n    else if (peek< sequence< uri_prefix, W, real_uri_value > >()) {\n      return parse_url_function_string();\n    }\n    else if (peek< re_functional >()) {\n      return parse_function_call();\n    }\n    else if (lex< exactly<'+'> >()) {\n      Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::PLUS, parse_factor());\n      if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());\n      return ex;\n    }\n    else if (lex< exactly<'-'> >()) {\n      Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_factor());\n      if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());\n      return ex;\n    }\n    else if (lex< exactly<'/'> >()) {\n      Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::SLASH, parse_factor());\n      if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());\n      return ex;\n    }\n    else if (lex< sequence< kwd_not > >()) {\n      Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::NOT, parse_factor());\n      if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());\n      return ex;\n    }\n    else {\n      return parse_value();\n    }\n  }\n\n  bool number_has_zero(const sass::string& parsed)\n  {\n    size_t L = parsed.length();\n    return !( (L > 0 && parsed.substr(0, 1) == \".\") ||\n              (L > 1 && parsed.substr(0, 2) == \"0.\") ||\n              (L > 1 && parsed.substr(0, 2) == \"-.\")  ||\n              (L > 2 && parsed.substr(0, 3) == \"-0.\") );\n  }\n\n  Number* Parser::lexed_number(const SourceSpan& pstate, const sass::string& parsed)\n  {\n    Number* nr = SASS_MEMORY_NEW(Number,\n                                    pstate,\n                                    sass_strtod(parsed.c_str()),\n                                    \"\",\n                                    number_has_zero(parsed));\n    nr->is_interpolant(false);\n    nr->is_delayed(true);\n    return nr;\n  }\n\n  Number* Parser::lexed_percentage(const SourceSpan& pstate, const sass::string& parsed)\n  {\n    Number* nr = SASS_MEMORY_NEW(Number,\n                                    pstate,\n                                    sass_strtod(parsed.c_str()),\n                                    \"%\",\n                                    true);\n    nr->is_interpolant(false);\n    nr->is_delayed(true);\n    return nr;\n  }\n\n  Number* Parser::lexed_dimension(const SourceSpan& pstate, const sass::string& parsed)\n  {\n    size_t L = parsed.length();\n    size_t num_pos = parsed.find_first_not_of(\" \\n\\r\\t\");\n    if (num_pos == sass::string::npos) num_pos = L;\n    size_t unit_pos = parsed.find_first_not_of(\"-+0123456789.\", num_pos);\n    if (parsed[unit_pos] == 'e' && is_number(parsed[unit_pos+1]) ) {\n      unit_pos = parsed.find_first_not_of(\"-+0123456789.\", ++ unit_pos);\n    }\n    if (unit_pos == sass::string::npos) unit_pos = L;\n    const sass::string& num = parsed.substr(num_pos, unit_pos - num_pos);\n    Number* nr = SASS_MEMORY_NEW(Number,\n                                    pstate,\n                                    sass_strtod(num.c_str()),\n                                    Token(number(parsed.c_str())),\n                                    number_has_zero(parsed));\n    nr->is_interpolant(false);\n    nr->is_delayed(true);\n    return nr;\n  }\n\n  Value* Parser::lexed_hex_color(const SourceSpan& pstate, const sass::string& parsed)\n  {\n    Color_RGBA* color = NULL;\n    if (parsed[0] != '#') {\n      return SASS_MEMORY_NEW(String_Quoted, pstate, parsed);\n    }\n    // chop off the '#'\n    sass::string hext(parsed.substr(1));\n    if (parsed.length() == 4) {\n      sass::string r(2, parsed[1]);\n      sass::string g(2, parsed[2]);\n      sass::string b(2, parsed[3]);\n      color = SASS_MEMORY_NEW(Color_RGBA,\n                               pstate,\n                               static_cast<double>(strtol(r.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(g.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(b.c_str(), NULL, 16)),\n                               1, // alpha channel\n                               parsed);\n    }\n    else if (parsed.length() == 5) {\n      sass::string r(2, parsed[1]);\n      sass::string g(2, parsed[2]);\n      sass::string b(2, parsed[3]);\n      sass::string a(2, parsed[4]);\n      color = SASS_MEMORY_NEW(Color_RGBA,\n                               pstate,\n                               static_cast<double>(strtol(r.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(g.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(b.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(a.c_str(), NULL, 16)) / 255,\n                               parsed);\n    }\n    else if (parsed.length() == 7) {\n      sass::string r(parsed.substr(1,2));\n      sass::string g(parsed.substr(3,2));\n      sass::string b(parsed.substr(5,2));\n      color = SASS_MEMORY_NEW(Color_RGBA,\n                               pstate,\n                               static_cast<double>(strtol(r.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(g.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(b.c_str(), NULL, 16)),\n                               1, // alpha channel\n                               parsed);\n    }\n    else if (parsed.length() == 9) {\n      sass::string r(parsed.substr(1,2));\n      sass::string g(parsed.substr(3,2));\n      sass::string b(parsed.substr(5,2));\n      sass::string a(parsed.substr(7,2));\n      color = SASS_MEMORY_NEW(Color_RGBA,\n                               pstate,\n                               static_cast<double>(strtol(r.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(g.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(b.c_str(), NULL, 16)),\n                               static_cast<double>(strtol(a.c_str(), NULL, 16)) / 255,\n                               parsed);\n    }\n    color->is_interpolant(false);\n    color->is_delayed(false);\n    return color;\n  }\n\n  Value* Parser::color_or_string(const sass::string& lexed) const\n  {\n    if (auto color = name_to_color(lexed)) {\n      auto c = SASS_MEMORY_NEW(Color_RGBA, color);\n      c->is_delayed(true);\n      c->pstate(pstate);\n      c->disp(lexed);\n      return c;\n    } else {\n      return SASS_MEMORY_NEW(String_Constant, pstate, lexed);\n    }\n  }\n\n  // parse one value for a list\n  ExpressionObj Parser::parse_value()\n  {\n    lex< css_comments >(false);\n    if (lex< ampersand >())\n    {\n      if (match< ampersand >()) {\n        warning(\"In Sass, \\\"&&\\\" means two copies of the parent selector. You probably want to use \\\"and\\\" instead.\", pstate);\n      }\n      return SASS_MEMORY_NEW(Parent_Reference, pstate); }\n\n    if (lex< kwd_important >())\n    { return SASS_MEMORY_NEW(String_Constant, pstate, \"!important\"); }\n\n    // parse `10%4px` into separated items and not a schema\n    if (lex< sequence < percentage, lookahead < number > > >())\n    { return lexed_percentage(lexed); }\n\n    if (lex< sequence < number, lookahead< sequence < op, number > > > >())\n    { return lexed_number(lexed); }\n\n    // string may be interpolated\n    if (lex< sequence < quoted_string, lookahead < exactly <'-'> > > >())\n    { return parse_string(); }\n\n    if (const char* stop = peek< value_schema >())\n    { return parse_value_schema(stop); }\n\n    // string may be interpolated\n    if (lex< quoted_string >())\n    { return parse_string(); }\n\n    if (lex< kwd_true >())\n    { return SASS_MEMORY_NEW(Boolean, pstate, true); }\n\n    if (lex< kwd_false >())\n    { return SASS_MEMORY_NEW(Boolean, pstate, false); }\n\n    if (lex< kwd_null >())\n    { return SASS_MEMORY_NEW(Null, pstate); }\n\n    if (lex< identifier >()) {\n      return color_or_string(lexed);\n    }\n\n    if (lex< percentage >())\n    { return lexed_percentage(lexed); }\n\n    // match hex number first because 0x000 looks like a number followed by an identifier\n    if (lex< sequence < alternatives< hex, hex0 >, negate < exactly<'-'> > > >())\n    { return lexed_hex_color(lexed); }\n\n    if (lex< hexa >())\n    { return lexed_hex_color(lexed); }\n\n    if (lex< sequence < exactly <'#'>, identifier > >())\n    { return SASS_MEMORY_NEW(String_Quoted, pstate, lexed); }\n\n    // also handle the 10em- foo special case\n    // alternatives < exactly < '.' >, .. > -- `1.5em-.75em` is split into a list, not a binary expression\n    if (lex< sequence< dimension, optional< sequence< exactly<'-'>, lookahead< alternatives < space > > > > > >())\n    { return lexed_dimension(lexed); }\n\n    if (lex< sequence< static_component, one_plus< strict_identifier > > >())\n    { return SASS_MEMORY_NEW(String_Constant, pstate, lexed); }\n\n    if (lex< number >())\n    { return lexed_number(lexed); }\n\n    if (lex< variable >())\n    { return SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)); }\n\n    css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n\n    // unreachable statement\n    return {};\n  }\n\n  // this parses interpolation inside other strings\n  // means the result should later be quoted again\n  String_Obj Parser::parse_interpolated_chunk(Token chunk, bool constant, bool css)\n  {\n    const char* i = chunk.begin;\n    // see if there any interpolants\n    const char* p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :\n                    find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);\n\n    if (!p) {\n      String_Quoted* str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, sass::string(i, chunk.end), 0, false, false, true, css);\n      if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*');\n      return str_quoted;\n    }\n\n    String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate, 0, css);\n    schema->is_interpolant(true);\n    while (i < chunk.end) {\n      p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :\n          find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);\n      if (p) {\n        if (i < p) {\n          // accumulate the preceding segment if it's nonempty\n          schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(i, p), css));\n        }\n        // we need to skip anything inside strings\n        // create a new target in parser/prelexer\n        if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p+2;\n          css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n        }\n        const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p + 2, chunk.end); // find the closing brace\n        if (j) { --j;\n          // parse the interpolant and accumulate it\n          LocalOption<const char*> partEnd(end, j);\n          LocalOption<const char*> partBeg(position, p + 2);\n          ExpressionObj interp_node = parse_list();\n          interp_node->is_interpolant(true);\n          schema->append(interp_node);\n          i = j;\n        }\n        else {\n          // throw an error if the interpolant is unterminated\n          error(\"unterminated interpolant inside string constant \" + chunk.to_string());\n        }\n      }\n      else { // no interpolants left; add the last segment if nonempty\n        // check if we need quotes here (was not sure after merge)\n        if (i < chunk.end) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(i, chunk.end), css));\n        break;\n      }\n      ++ i;\n    }\n\n    return schema.detach();\n  }\n\n  String_Schema_Obj Parser::parse_css_variable_value()\n  {\n    String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);\n    sass::vector<char> brackets;\n    while (true) {\n      if (\n        (brackets.empty() && lex< css_variable_top_level_value >(false)) ||\n        (!brackets.empty() && lex< css_variable_value >(false))\n      ) {\n        Token str(lexed);\n        schema->append(SASS_MEMORY_NEW(String_Constant, pstate, str));\n      } else if (ExpressionObj tok = lex_interpolation()) {\n        if (String_Schema* s = Cast<String_Schema>(tok)) {\n          if (s->empty()) break;\n          schema->concat(s);\n        } else {\n          schema->append(tok);\n        }\n      } else if (lex< quoted_string >()) {\n        ExpressionObj tok = parse_string();\n        if (tok.isNull()) break;\n        if (String_Schema* s = Cast<String_Schema>(tok)) {\n          if (s->empty()) break;\n          schema->concat(s);\n        } else {\n          schema->append(tok);\n        }\n      } else if (lex< alternatives< exactly<'('>, exactly<'['>, exactly<'{'> > >()) {\n        const char opening_bracket = *(position - 1);\n        brackets.push_back(opening_bracket);\n        schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(1, opening_bracket)));\n      } else if (const char *match = peek< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >()) {\n        if (brackets.empty()) break;\n        const char closing_bracket = *(match - 1);\n        if (brackets.back() != Util::opening_bracket_for(closing_bracket)) {\n          sass::string message = \": expected \\\"\";\n          message += Util::closing_bracket_for(brackets.back());\n          message += \"\\\", was \";\n          css_error(\"Invalid CSS\", \" after \", message);\n        }\n        lex< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >();\n        schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(1, closing_bracket)));\n        brackets.pop_back();\n      } else {\n        break;\n      }\n    }\n\n    if (!brackets.empty()) {\n      sass::string message = \": expected \\\"\";\n      message += Util::closing_bracket_for(brackets.back());\n      message += \"\\\", was \";\n      css_error(\"Invalid CSS\", \" after \", message);\n    }\n\n    if (schema->empty()) error(\"Custom property values may not be empty.\");\n    return schema.detach();\n  }\n\n  ValueObj Parser::parse_static_value()\n  {\n    lex< static_value >();\n    Token str(lexed);\n    // static values always have trailing white-\n    // space and end delimiter (\\s*[;]$) included\n    --pstate.offset.column;\n    --after_token.column;\n    --str.end;\n    --position;\n\n    return color_or_string(str.time_wspace());;\n  }\n\n  String_Obj Parser::parse_string()\n  {\n    return parse_interpolated_chunk(Token(lexed));\n  }\n\n  String_Obj Parser::parse_ie_property()\n  {\n    lex< ie_property >();\n    Token str(lexed);\n    const char* i = str.begin;\n    // see if there any interpolants\n    const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(str.begin, str.end);\n    if (!p) {\n      return SASS_MEMORY_NEW(String_Quoted, pstate, sass::string(str.begin, str.end));\n    }\n\n    String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);\n    while (i < str.end) {\n      p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, str.end);\n      if (p) {\n        if (i < p) {\n          schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(i, p))); // accumulate the preceding segment if it's nonempty\n        }\n        if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p+2;\n          css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n        }\n        const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p+2, str.end); // find the closing brace\n        if (j) {\n          // parse the interpolant and accumulate it\n          LocalOption<const char*> partEnd(end, j);\n          LocalOption<const char*> partBeg(position, p + 2);\n          ExpressionObj interp_node = parse_list();\n          interp_node->is_interpolant(true);\n          schema->append(interp_node);\n          i = j;\n        }\n        else {\n          // throw an error if the interpolant is unterminated\n          error(\"unterminated interpolant inside IE function \" + str.to_string());\n        }\n      }\n      else { // no interpolants left; add the last segment if nonempty\n        if (i < str.end) {\n          schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(i, str.end)));\n        }\n        break;\n      }\n    }\n    return schema;\n  }\n\n  String_Obj Parser::parse_ie_keyword_arg()\n  {\n    String_Schema_Obj kwd_arg = SASS_MEMORY_NEW(String_Schema, pstate, 3);\n    if (lex< variable >()) {\n      kwd_arg->append(SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)));\n    } else {\n      lex< alternatives< identifier_schema, identifier > >();\n      kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));\n    }\n    lex< exactly<'='> >();\n    kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));\n    if (peek< variable >()) kwd_arg->append(parse_list());\n    else if (lex< number >()) {\n      sass::string parsed(lexed);\n      Util::normalize_decimals(parsed);\n      kwd_arg->append(lexed_number(parsed));\n    }\n    else if (peek < ie_keyword_arg_value >()) { kwd_arg->append(parse_list()); }\n    return kwd_arg;\n  }\n\n  String_Schema_Obj Parser::parse_value_schema(const char* stop)\n  {\n    // initialize the string schema object to add tokens\n    String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);\n\n    if (peek<exactly<'}'>>()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n    }\n\n    const char* e;\n    const char* ee = end;\n    end = stop;\n    size_t num_items = 0;\n    bool need_space = false;\n    while (position < stop) {\n      // parse space between tokens\n      if (lex< spaces >() && num_items) {\n        need_space = true;\n      }\n      if (need_space) {\n        need_space = false;\n        // schema->append(SASS_MEMORY_NEW(String_Constant, pstate, \" \"));\n      }\n      if ((e = peek< re_functional >()) && e < stop) {\n        schema->append(parse_function_call());\n      }\n      // lex an interpolant /#{...}/\n      else if (lex< exactly < hash_lbrace > >()) {\n        // Try to lex static expression first\n        if (peek< exactly< rbrace > >()) {\n          css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n        }\n        ExpressionObj ex;\n        if (lex< re_static_expression >()) {\n          ex = SASS_MEMORY_NEW(String_Constant, pstate, lexed);\n        } else {\n          ex = parse_list(true);\n        }\n        ex->is_interpolant(true);\n        schema->append(ex);\n        if (!lex < exactly < rbrace > >()) {\n          css_error(\"Invalid CSS\", \" after \", \": expected \\\"}\\\", was \");\n        }\n      }\n      // lex some string constants or other valid token\n      // Note: [-+] chars are left over from i.e. `#{3}+3`\n      else if (lex< alternatives < exactly<'%'>, exactly < '-' >, exactly < '+' > > >()) {\n        schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));\n      }\n      // lex a quoted string\n      else if (lex< quoted_string >()) {\n        // need_space = true;\n        // if (schema->length()) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, \" \"));\n        // else need_space = true;\n        schema->append(parse_string());\n        if ((*position == '\"' || *position == '\\'') || peek < alternatives < alpha > >()) {\n          // need_space = true;\n        }\n        if (peek < exactly < '-' > >()) break;\n      }\n      else if (lex< identifier >()) {\n        schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));\n        if ((*position == '\"' || *position == '\\'') || peek < alternatives < alpha > >()) {\n           // need_space = true;\n        }\n      }\n      // lex (normalized) variable\n      else if (lex< variable >()) {\n        sass::string name(Util::normalize_underscores(lexed));\n        schema->append(SASS_MEMORY_NEW(Variable, pstate, name));\n      }\n      // lex percentage value\n      else if (lex< percentage >()) {\n        schema->append(lexed_percentage(lexed));\n      }\n      // lex dimension value\n      else if (lex< dimension >()) {\n        schema->append(lexed_dimension(lexed));\n      }\n      // lex number value\n      else if (lex< number >()) {\n        schema->append(lexed_number(lexed));\n      }\n      // lex hex color value\n      else if (lex< sequence < hex, negate < exactly < '-' > > > >()) {\n        schema->append(lexed_hex_color(lexed));\n      }\n      else if (lex< sequence < exactly <'#'>, identifier > >()) {\n        schema->append(SASS_MEMORY_NEW(String_Quoted, pstate, lexed));\n      }\n      // lex a value in parentheses\n      else if (peek< parenthese_scope >()) {\n        schema->append(parse_factor());\n      }\n      else {\n        break;\n      }\n      ++num_items;\n    }\n    if (position != stop) {\n      schema->append(SASS_MEMORY_NEW(String_Constant, pstate, sass::string(position, stop)));\n      position = stop;\n    }\n    end = ee;\n    return schema;\n  }\n\n  // this parses interpolation outside other strings\n  // means the result must not be quoted again later\n  String_Obj Parser::parse_identifier_schema()\n  {\n    Token id(lexed);\n    const char* i = id.begin;\n    // see if there any interpolants\n    const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(id.begin, id.end);\n    if (!p) {\n      return SASS_MEMORY_NEW(String_Constant, pstate, sass::string(id.begin, id.end));\n    }\n\n    String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);\n    while (i < id.end) {\n      p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, id.end);\n      if (p) {\n        if (i < p) {\n          // accumulate the preceding segment if it's nonempty\n          const char* o = position; position = i;\n          schema->append(parse_value_schema(p));\n          position = o;\n        }\n        // we need to skip anything inside strings\n        // create a new target in parser/prelexer\n        if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p;\n          css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \");\n        }\n        const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p+2, id.end); // find the closing brace\n        if (j) {\n          // parse the interpolant and accumulate it\n          LocalOption<const char*> partEnd(end, j);\n          LocalOption<const char*> partBeg(position, p + 2);\n          ExpressionObj interp_node = parse_list(DELAYED);\n          interp_node->is_interpolant(true);\n          schema->append(interp_node);\n          // schema->has_interpolants(true);\n          i = j;\n        }\n        else {\n          // throw an error if the interpolant is unterminated\n          error(\"unterminated interpolant inside interpolated identifier \" + id.to_string());\n        }\n      }\n      else { // no interpolants left; add the last segment if nonempty\n        if (i < end) {\n          const char* o = position; position = i;\n          schema->append(parse_value_schema(id.end));\n          position = o;\n        }\n        break;\n      }\n    }\n    return schema ? schema.detach() : 0;\n  }\n\n  // calc functions should preserve arguments\n  Function_Call_Obj Parser::parse_calc_function()\n  {\n    lex< identifier >();\n    sass::string name(lexed);\n    SourceSpan call_pos = pstate;\n    lex< exactly<'('> >();\n    SourceSpan arg_pos = pstate;\n    const char* arg_beg = position;\n    parse_list();\n    const char* arg_end = position;\n    lex< skip_over_scopes <\n          exactly < '(' >,\n          exactly < ')' >\n        > >();\n\n    Argument_Obj arg = SASS_MEMORY_NEW(Argument, arg_pos, parse_interpolated_chunk(Token(arg_beg, arg_end)));\n    Arguments_Obj args = SASS_MEMORY_NEW(Arguments, arg_pos);\n    args->append(arg);\n    return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);\n  }\n\n  String_Obj Parser::parse_url_function_string()\n  {\n    sass::string prefix(\"\");\n    if (lex< uri_prefix >()) {\n      prefix = sass::string(lexed);\n    }\n\n    lex < optional_spaces >();\n    String_Obj url_string = parse_url_function_argument();\n\n    sass::string suffix(\"\");\n    if (lex< real_uri_suffix >()) {\n      suffix = sass::string(lexed);\n    }\n\n    sass::string uri(\"\");\n    if (url_string) {\n      uri = url_string->to_string({ NESTED, 5 });\n    }\n\n    if (String_Schema* schema = Cast<String_Schema>(url_string)) {\n      String_Schema_Obj res = SASS_MEMORY_NEW(String_Schema, pstate);\n      res->append(SASS_MEMORY_NEW(String_Constant, pstate, prefix));\n      res->append(schema);\n      res->append(SASS_MEMORY_NEW(String_Constant, pstate, suffix));\n      return res;\n    } else {\n      sass::string res = prefix + uri + suffix;\n      return SASS_MEMORY_NEW(String_Constant, pstate, res);\n    }\n  }\n\n  String_Obj Parser::parse_url_function_argument()\n  {\n    const char* p = position;\n\n    sass::string uri(\"\");\n    if (lex< real_uri_value >(false)) {\n      uri = lexed.to_string();\n    }\n\n    if (peek< exactly< hash_lbrace > >()) {\n      const char* pp = position;\n      // TODO: error checking for unclosed interpolants\n      while (pp && peek< exactly< hash_lbrace > >(pp)) {\n        pp = sequence< interpolant, real_uri_value >(pp);\n      }\n      if (!pp) return {};\n      position = pp;\n      return parse_interpolated_chunk(Token(p, position));\n    }\n    else if (uri != \"\") {\n      sass::string res = Util::rtrim(uri);\n      return SASS_MEMORY_NEW(String_Constant, pstate, res);\n    }\n\n    return {};\n  }\n\n  Function_Call_Obj Parser::parse_function_call()\n  {\n    lex< identifier >();\n    sass::string name(lexed);\n\n    if (Util::normalize_underscores(name) == \"content-exists\" && stack.back() != Scope::Mixin)\n    { error(\"Cannot call content-exists() except within a mixin.\"); }\n\n    SourceSpan call_pos = pstate;\n    Arguments_Obj args = parse_arguments();\n    return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);\n  }\n\n  Function_Call_Obj Parser::parse_function_call_schema()\n  {\n    String_Obj name = parse_identifier_schema();\n    SourceSpan source_position_of_call = pstate;\n    Arguments_Obj args = parse_arguments();\n\n    return SASS_MEMORY_NEW(Function_Call, source_position_of_call, name, args);\n  }\n\n  Content_Obj Parser::parse_content_directive()\n  {\n    SourceSpan call_pos = pstate;\n    Arguments_Obj args = parse_arguments();\n\n    return SASS_MEMORY_NEW(Content, call_pos, args);\n  }\n\n  If_Obj Parser::parse_if_directive(bool else_if)\n  {\n    stack.push_back(Scope::Control);\n    SourceSpan if_source_position = pstate;\n    bool root = block_stack.back()->is_root();\n    ExpressionObj predicate = parse_list();\n    Block_Obj block = parse_block(root);\n    Block_Obj alternative;\n\n    // only throw away comment if we parse a case\n    // we want all other comments to be parsed\n    if (lex_css< elseif_directive >()) {\n      alternative = SASS_MEMORY_NEW(Block, pstate);\n      alternative->append(parse_if_directive(true));\n    }\n    else if (lex_css< kwd_else_directive >()) {\n      alternative = parse_block(root);\n    }\n    stack.pop_back();\n    return SASS_MEMORY_NEW(If, if_source_position, predicate, block, alternative);\n  }\n\n  ForRuleObj Parser::parse_for_directive()\n  {\n    stack.push_back(Scope::Control);\n    SourceSpan for_source_position = pstate;\n    bool root = block_stack.back()->is_root();\n    lex_variable();\n    sass::string var(Util::normalize_underscores(lexed));\n    if (!lex< kwd_from >()) error(\"expected 'from' keyword in @for directive\");\n    ExpressionObj lower_bound = parse_expression();\n    bool inclusive = false;\n    if (lex< kwd_through >()) inclusive = true;\n    else if (lex< kwd_to >()) inclusive = false;\n    else                  error(\"expected 'through' or 'to' keyword in @for directive\");\n    ExpressionObj upper_bound = parse_expression();\n    Block_Obj body = parse_block(root);\n    stack.pop_back();\n    return SASS_MEMORY_NEW(ForRule, for_source_position, var, lower_bound, upper_bound, body, inclusive);\n  }\n\n  // helper to parse a var token\n  Token Parser::lex_variable()\n  {\n    // peek for dollar sign first\n    if (!peek< exactly <'$'> >()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected \\\"$\\\", was \");\n    }\n    // we expect a simple identifier as the call name\n    if (!lex< sequence < exactly <'$'>, identifier > >()) {\n      lex< exactly <'$'> >(); // move pstate and position up\n      css_error(\"Invalid CSS\", \" after \", \": expected identifier, was \");\n    }\n    // return object\n    return lexed;\n  }\n  // helper to parse identifier\n  Token Parser::lex_identifier()\n  {\n    // we expect a simple identifier as the call name\n    if (!lex< identifier >()) { // ToDo: pstate wrong?\n      css_error(\"Invalid CSS\", \" after \", \": expected identifier, was \");\n    }\n    // return object\n    return lexed;\n  }\n\n  EachRuleObj Parser::parse_each_directive()\n  {\n    stack.push_back(Scope::Control);\n    SourceSpan each_source_position = pstate;\n    bool root = block_stack.back()->is_root();\n    sass::vector<sass::string> vars;\n    lex_variable();\n    vars.push_back(Util::normalize_underscores(lexed));\n    while (lex< exactly<','> >()) {\n      if (!lex< variable >()) error(\"@each directive requires an iteration variable\");\n      vars.push_back(Util::normalize_underscores(lexed));\n    }\n    if (!lex< kwd_in >()) error(\"expected 'in' keyword in @each directive\");\n    ExpressionObj list = parse_list();\n    Block_Obj body = parse_block(root);\n    stack.pop_back();\n    return SASS_MEMORY_NEW(EachRule, each_source_position, vars, list, body);\n  }\n\n  // called after parsing `kwd_while_directive`\n  WhileRuleObj Parser::parse_while_directive()\n  {\n    stack.push_back(Scope::Control);\n    bool root = block_stack.back()->is_root();\n    // create the initial while call object\n    WhileRuleObj call = SASS_MEMORY_NEW(WhileRule, pstate, ExpressionObj{}, Block_Obj{});\n    // parse mandatory predicate\n    ExpressionObj predicate = parse_list();\n    List_Obj l = Cast<List>(predicate);\n    if (!predicate || (l && !l->length())) {\n      css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \", false);\n    }\n    call->predicate(predicate);\n    // parse mandatory block\n    call->block(parse_block(root));\n    // return ast node\n    stack.pop_back();\n    // return ast node\n    return call.detach();\n  }\n\n\n  sass::vector<CssMediaQuery_Obj> Parser::parseCssMediaQueries()\n  {\n    sass::vector<CssMediaQuery_Obj> result;\n    do {\n      if (auto query = parseCssMediaQuery()) {\n        result.push_back(query);\n      }\n    } while (lex<exactly<','>>());\n    return result;\n  }\n\n  sass::string Parser::parseIdentifier()\n  {\n    if (lex < identifier >(false)) {\n      return sass::string(lexed);\n    }\n    return sass::string();\n  }\n\n  CssMediaQuery_Obj Parser::parseCssMediaQuery()\n  {\n    CssMediaQuery_Obj result = SASS_MEMORY_NEW(CssMediaQuery, pstate);\n    lex<css_comments>(false);\n\n    // Check if any tokens are to parse\n    if (!peek_css<exactly<'('>>()) {\n\n      sass::string token1(parseIdentifier());\n      lex<css_comments>(false);\n\n      if (token1.empty()) {\n        return {};\n      }\n\n      sass::string token2(parseIdentifier());\n      lex<css_comments>(false);\n\n      if (Util::equalsLiteral(\"and\", token2)) {\n        result->type(token1);\n      }\n      else {\n        if (token2.empty()) {\n          result->type(token1);\n        }\n        else {\n          result->modifier(token1);\n          result->type(token2);\n        }\n\n        if (lex < kwd_and >()) {\n          lex<css_comments>(false);\n        }\n        else {\n          return result;\n        }\n\n      }\n\n    }\n\n    sass::vector<sass::string> queries;\n\n    do {\n      lex<css_comments>(false);\n\n      if (lex<exactly<'('>>()) {\n        // In dart sass parser returns a pure string\n        if (lex < skip_over_scopes < exactly < '(' >, exactly < ')' > > >()) {\n          sass::string decl(\"(\" + sass::string(lexed));\n          queries.push_back(decl);\n        }\n        // Should be: parseDeclarationValue;\n        if (!lex<exactly<')'>>()) {\n          // Should we throw an error here?\n        }\n      }\n    } while (lex < kwd_and >());\n\n    result->features(queries);\n\n    if (result->features().empty()) {\n      if (result->type().empty()) {\n        return {};\n      }\n    }\n\n    return result;\n  }\n\n\n  // EO parse_while_directive\n  MediaRule_Obj Parser::parseMediaRule()\n  {\n    MediaRule_Obj rule = SASS_MEMORY_NEW(MediaRule, pstate);\n    stack.push_back(Scope::Media);\n    rule->schema(parse_media_queries());\n    parse_block_comments(false);\n    rule->block(parse_css_block());\n    stack.pop_back();\n    return rule;\n  }\n\n  List_Obj Parser::parse_media_queries()\n  {\n    advanceToNextToken();\n    List_Obj queries = SASS_MEMORY_NEW(List, pstate, 0, SASS_COMMA);\n    if (!peek_css < exactly <'{'> >()) queries->append(parse_media_query());\n    while (lex_css < exactly <','> >()) queries->append(parse_media_query());\n    queries->update_pstate(pstate);\n    return queries.detach();\n  }\n\n  // Expression* Parser::parse_media_query()\n  Media_Query_Obj Parser::parse_media_query()\n  {\n    advanceToNextToken();\n    Media_Query_Obj media_query = SASS_MEMORY_NEW(Media_Query, pstate);\n    if (lex < kwd_not >()) { media_query->is_negated(true); lex < css_comments >(false); }\n    else if (lex < kwd_only >()) { media_query->is_restricted(true); lex < css_comments >(false); }\n\n    if (lex < identifier_schema >()) media_query->media_type(parse_identifier_schema());\n    else if (lex < identifier >())   media_query->media_type(parse_interpolated_chunk(lexed));\n    else                             media_query->append(parse_media_expression());\n\n    while (lex_css < kwd_and >()) media_query->append(parse_media_expression());\n    if (lex < identifier_schema >()) {\n      String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);\n      if (media_query->media_type()) {\n        schema->append(media_query->media_type());\n        schema->append(SASS_MEMORY_NEW(String_Constant, pstate, \" \"));\n      }\n      schema->append(parse_identifier_schema());\n      media_query->media_type(schema);\n    }\n    while (lex_css < kwd_and >()) media_query->append(parse_media_expression());\n\n    media_query->update_pstate(pstate);\n\n    return media_query;\n  }\n\n  Media_Query_ExpressionObj Parser::parse_media_expression()\n  {\n    if (lex < identifier_schema >()) {\n      String_Obj ss = parse_identifier_schema();\n      return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss, ExpressionObj{}, true);\n    }\n    if (!lex_css< exactly<'('> >()) {\n      error(\"media query expression must begin with '('\");\n    }\n    ExpressionObj feature;\n    if (peek_css< exactly<')'> >()) {\n      error(\"media feature required in media query expression\");\n    }\n    feature = parse_expression();\n    ExpressionObj expression;\n    if (lex_css< exactly<':'> >()) {\n      expression = parse_list(DELAYED);\n    }\n    if (!lex_css< exactly<')'> >()) {\n      error(\"unclosed parenthesis in media query expression\");\n    }\n    return SASS_MEMORY_NEW(Media_Query_Expression, feature->pstate(), feature, expression);\n  }\n\n  // lexed after `kwd_supports_directive`\n  // these are very similar to media blocks\n  SupportsRuleObj Parser::parse_supports_directive()\n  {\n    SupportsConditionObj cond = parse_supports_condition(/*top_level=*/true);\n    // create the ast node object for the support queries\n    SupportsRuleObj query = SASS_MEMORY_NEW(SupportsRule, pstate, cond);\n    // additional block is mandatory\n    // parse inner block\n    query->block(parse_block());\n    // return ast node\n    return query;\n  }\n\n  // parse one query operation\n  // may encounter nested queries\n  SupportsConditionObj Parser::parse_supports_condition(bool top_level)\n  {\n    lex < css_whitespace >();\n    SupportsConditionObj cond;\n    if ((cond = parse_supports_negation())) return cond;\n    if ((cond = parse_supports_operator(top_level))) return cond;\n    if ((cond = parse_supports_interpolation())) return cond;\n    return cond;\n  }\n\n  SupportsConditionObj Parser::parse_supports_negation()\n  {\n    if (!lex < kwd_not >()) return {};\n    SupportsConditionObj cond = parse_supports_condition_in_parens(/*parens_required=*/true);\n    return SASS_MEMORY_NEW(SupportsNegation, pstate, cond);\n  }\n\n  SupportsConditionObj Parser::parse_supports_operator(bool top_level)\n  {\n    SupportsConditionObj cond = parse_supports_condition_in_parens(/*parens_required=*/top_level);\n    if (cond.isNull()) return {};\n\n    while (true) {\n      SupportsOperation::Operand op = SupportsOperation::OR;\n      if (lex < kwd_and >()) { op = SupportsOperation::AND; }\n      else if(!lex < kwd_or >()) { break; }\n\n      lex < css_whitespace >();\n      SupportsConditionObj right = parse_supports_condition_in_parens(/*parens_required=*/true);\n\n      // SupportsCondition* cc = SASS_MEMORY_NEW(SupportsCondition, *static_cast<SupportsCondition*>(cond));\n      cond = SASS_MEMORY_NEW(SupportsOperation, pstate, cond, right, op);\n    }\n    return cond;\n  }\n\n  SupportsConditionObj Parser::parse_supports_interpolation()\n  {\n    if (!lex < interpolant >()) return {};\n\n    String_Obj interp = parse_interpolated_chunk(lexed);\n    if (!interp) return {};\n\n    return SASS_MEMORY_NEW(Supports_Interpolation, pstate, interp);\n  }\n\n  // TODO: This needs some major work. Although feature conditions\n  // look like declarations their semantics differ significantly\n  SupportsConditionObj Parser::parse_supports_declaration()\n  {\n    SupportsCondition* cond;\n    // parse something declaration like\n    ExpressionObj feature = parse_expression();\n    ExpressionObj expression;\n    if (lex_css< exactly<':'> >()) {\n      expression = parse_list(DELAYED);\n    }\n    if (!feature || !expression) error(\"@supports condition expected declaration\");\n    cond = SASS_MEMORY_NEW(SupportsDeclaration,\n                     feature->pstate(),\n                     feature,\n                     expression);\n    // ToDo: maybe we need an additional error condition?\n    return cond;\n  }\n\n  SupportsConditionObj Parser::parse_supports_condition_in_parens(bool parens_required)\n  {\n    SupportsConditionObj interp = parse_supports_interpolation();\n    if (interp != nullptr) return interp;\n\n    if (!lex < exactly <'('> >()) {\n      if (parens_required) {\n        css_error(\"Invalid CSS\", \" after \", \": expected @supports condition (e.g. (display: flexbox)), was \", /*trim=*/false);\n      } else {\n        return {};\n      }\n    }\n    lex < css_whitespace >();\n\n    SupportsConditionObj cond = parse_supports_condition(/*top_level=*/false);\n    if (cond.isNull()) cond = parse_supports_declaration();\n    if (!lex < exactly <')'> >()) error(\"unclosed parenthesis in @supports declaration\");\n\n    lex < css_whitespace >();\n    return cond;\n  }\n\n  AtRootRuleObj Parser::parse_at_root_block()\n  {\n    stack.push_back(Scope::AtRoot);\n    SourceSpan at_source_position = pstate;\n    Block_Obj body;\n    At_Root_Query_Obj expr;\n    Lookahead lookahead_result;\n    if (lex_css< exactly<'('> >()) {\n      expr = parse_at_root_query();\n    }\n    if (peek_css < exactly<'{'> >()) {\n      lex <optional_spaces>();\n      body = parse_block(true);\n    }\n    else if ((lookahead_result = lookahead_for_selector(position)).found) {\n      StyleRuleObj r = parse_ruleset(lookahead_result);\n      body = SASS_MEMORY_NEW(Block, r->pstate(), 1, true);\n      body->append(r);\n    }\n    AtRootRuleObj at_root = SASS_MEMORY_NEW(AtRootRule, at_source_position, body);\n    if (!expr.isNull()) at_root->expression(expr);\n    stack.pop_back();\n    return at_root;\n  }\n\n  At_Root_Query_Obj Parser::parse_at_root_query()\n  {\n    if (peek< exactly<')'> >()) error(\"at-root feature required in at-root expression\");\n\n    if (!peek< alternatives< kwd_with_directive, kwd_without_directive > >()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected \\\"with\\\" or \\\"without\\\", was \");\n    }\n\n    ExpressionObj feature = parse_list();\n    if (!lex_css< exactly<':'> >()) error(\"style declaration must contain a value\");\n    ExpressionObj expression = parse_list();\n    List_Obj value = SASS_MEMORY_NEW(List, feature->pstate(), 1);\n\n    if (expression->concrete_type() == Expression::LIST) {\n        value = Cast<List>(expression);\n    }\n    else value->append(expression);\n\n    At_Root_Query_Obj cond = SASS_MEMORY_NEW(At_Root_Query,\n                                          value->pstate(),\n                                          feature,\n                                          value);\n    if (!lex_css< exactly<')'> >()) error(\"unclosed parenthesis in @at-root expression\");\n    return cond;\n  }\n\n  AtRuleObj Parser::parse_directive()\n  {\n    AtRuleObj directive = SASS_MEMORY_NEW(AtRule, pstate, lexed);\n    String_Schema_Obj val = parse_almost_any_value();\n    // strip left and right if they are of type string\n    directive->value(val);\n    if (peek< exactly<'{'> >()) {\n      directive->block(parse_block());\n    }\n    return directive;\n  }\n\n  ExpressionObj Parser::lex_interpolation()\n  {\n    if (lex < interpolant >(true) != NULL) {\n      return parse_interpolated_chunk(lexed, true);\n    }\n    return {};\n  }\n\n  ExpressionObj Parser::lex_interp_uri()\n  {\n    // create a string schema by lexing optional interpolations\n    return lex_interp< re_string_uri_open, re_string_uri_close >();\n  }\n\n  ExpressionObj Parser::lex_interp_string()\n  {\n    ExpressionObj rv;\n    if ((rv = lex_interp< re_string_double_open, re_string_double_close >())) return rv;\n    if ((rv = lex_interp< re_string_single_open, re_string_single_close >())) return rv;\n    return rv;\n  }\n\n  ExpressionObj Parser::lex_almost_any_value_chars()\n  {\n    const char* match =\n    lex <\n      one_plus <\n        alternatives <\n          exactly <'>'>,\n          sequence <\n            exactly <'\\\\'>,\n            any_char\n          >,\n          sequence <\n            negate <\n              sequence <\n                exactly < url_kwd >,\n                exactly <'('>\n              >\n            >,\n            neg_class_char <\n              almost_any_value_class\n            >\n          >,\n          sequence <\n            exactly <'/'>,\n            negate <\n              alternatives <\n                exactly <'/'>,\n                exactly <'*'>\n              >\n            >\n          >,\n          sequence <\n            exactly <'\\\\'>,\n            exactly <'#'>,\n            negate <\n              exactly <'{'>\n            >\n          >,\n          sequence <\n            exactly <'!'>,\n            negate <\n              alpha\n            >\n          >\n        >\n      >\n    >(false);\n    if (match) {\n      return SASS_MEMORY_NEW(String_Constant, pstate, lexed);\n    }\n    return {};\n  }\n\n  ExpressionObj Parser::lex_almost_any_value_token()\n  {\n    ExpressionObj rv;\n    if (*position == 0) return {};\n    if ((rv = lex_almost_any_value_chars())) return rv;\n    // if ((rv = lex_block_comment())) return rv;\n    // if ((rv = lex_single_line_comment())) return rv;\n    if ((rv = lex_interp_string())) return rv;\n    if ((rv = lex_interp_uri())) return rv;\n    if ((rv = lex_interpolation())) return rv;\n     if (lex< alternatives< hex, hex0 > >())\n    { return lexed_hex_color(lexed); }\n   return rv;\n  }\n\n  String_Schema_Obj Parser::parse_almost_any_value()\n  {\n\n    String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);\n    if (*position == 0) return {};\n    lex < spaces >(false);\n    ExpressionObj token = lex_almost_any_value_token();\n    if (!token) return {};\n    schema->append(token);\n    if (*position == 0) {\n      schema->rtrim();\n      return schema.detach();\n    }\n\n    while ((token = lex_almost_any_value_token())) {\n      schema->append(token);\n    }\n\n    lex < css_whitespace >();\n\n    schema->rtrim();\n\n    return schema.detach();\n  }\n\n  WarningRuleObj Parser::parse_warning()\n  {\n    if (stack.back() != Scope::Root &&\n        stack.back() != Scope::Function &&\n        stack.back() != Scope::Mixin &&\n        stack.back() != Scope::Control &&\n        stack.back() != Scope::Rules) {\n      error(\"Illegal nesting: Only properties may be nested beneath properties.\");\n    }\n    return SASS_MEMORY_NEW(WarningRule, pstate, parse_list(DELAYED));\n  }\n\n  ErrorRuleObj Parser::parse_error()\n  {\n    if (stack.back() != Scope::Root &&\n        stack.back() != Scope::Function &&\n        stack.back() != Scope::Mixin &&\n        stack.back() != Scope::Control &&\n        stack.back() != Scope::Rules) {\n      error(\"Illegal nesting: Only properties may be nested beneath properties.\");\n    }\n    return SASS_MEMORY_NEW(ErrorRule, pstate, parse_list(DELAYED));\n  }\n\n  DebugRuleObj Parser::parse_debug()\n  {\n    if (stack.back() != Scope::Root &&\n        stack.back() != Scope::Function &&\n        stack.back() != Scope::Mixin &&\n        stack.back() != Scope::Control &&\n        stack.back() != Scope::Rules) {\n      error(\"Illegal nesting: Only properties may be nested beneath properties.\");\n    }\n    return SASS_MEMORY_NEW(DebugRule, pstate, parse_list(DELAYED));\n  }\n\n  Return_Obj Parser::parse_return_directive()\n  {\n    // check that we do not have an empty list (ToDo: check if we got all cases)\n    if (peek_css < alternatives < exactly < ';' >, exactly < '}' >, end_of_file > >())\n    { css_error(\"Invalid CSS\", \" after \", \": expected expression (e.g. 1px, bold), was \"); }\n    return SASS_MEMORY_NEW(Return, pstate, parse_list());\n  }\n\n  Lookahead Parser::lookahead_for_selector(const char* start)\n  {\n    // init result struct\n    Lookahead rv = Lookahead();\n    // get start position\n    const char* p = start ? start : position;\n    // match in one big \"regex\"\n    rv.error = p;\n    if (const char* q =\n      peek <\n        re_selector_list\n      >(p)\n    ) {\n      bool could_be_property = peek< sequence< exactly<'-'>, exactly<'-'> > >(p) != 0;\n      bool could_be_escaped = false;\n      while (p < q) {\n        // did we have interpolations?\n        if (*p == '#' && *(p+1) == '{') {\n          rv.has_interpolants = true;\n          p = q; break;\n        }\n        // A property that's ambiguous with a nested selector is interpreted as a\n        // custom property.\n        if (*p == ':' && !could_be_escaped) {\n          rv.is_custom_property = could_be_property || p+1 == q || peek< space >(p+1);\n        }\n        could_be_escaped = *p == '\\\\';\n        ++ p;\n      }\n      // store anyway  }\n\n\n      // ToDo: remove\n      rv.error = q;\n      rv.position = q;\n      // check expected opening bracket\n      // only after successful matching\n      if (peek < exactly<'{'> >(q)) rv.found = q;\n      // else if (peek < end_of_file >(q)) rv.found = q;\n      else if (peek < exactly<'('> >(q)) rv.found = q;\n      // else if (peek < exactly<';'> >(q)) rv.found = q;\n      // else if (peek < exactly<'}'> >(q)) rv.found = q;\n      if (rv.found || *p == 0) rv.error = 0;\n    }\n\n    rv.parsable = ! rv.has_interpolants;\n\n    // return result\n    return rv;\n\n  }\n  // EO lookahead_for_selector\n\n  // used in parse_block_nodes and parse_special_directive\n  // ToDo: actual usage is still not really clear to me?\n  Lookahead Parser::lookahead_for_include(const char* start)\n  {\n    // we actually just lookahead for a selector\n    Lookahead rv = lookahead_for_selector(start);\n    // but the \"found\" rules are different\n    if (const char* p = rv.position) {\n      // check for additional abort condition\n      if (peek < exactly<';'> >(p)) rv.found = p;\n      else if (peek < exactly<'}'> >(p)) rv.found = p;\n    }\n    // return result\n    return rv;\n  }\n  // EO lookahead_for_include\n\n  // look ahead for a token with interpolation in it\n  // we mostly use the result if there is an interpolation\n  // everything that passes here gets parsed as one schema\n  // meaning it will not be parsed as a space separated list\n  Lookahead Parser::lookahead_for_value(const char* start)\n  {\n    // init result struct\n    Lookahead rv = Lookahead();\n    // get start position\n    const char* p = start ? start : position;\n    // match in one big \"regex\"\n    if (const char* q =\n      peek <\n        non_greedy <\n          alternatives <\n            // consume whitespace\n            block_comment, // spaces,\n            // main tokens\n            sequence <\n              interpolant,\n              optional <\n                quoted_string\n              >\n            >,\n            identifier,\n            variable,\n            // issue #442\n            sequence <\n              parenthese_scope,\n              interpolant,\n              optional <\n                quoted_string\n              >\n            >\n          >,\n          sequence <\n            // optional_spaces,\n            alternatives <\n              // end_of_file,\n              exactly<'{'>,\n              exactly<'}'>,\n              exactly<';'>\n            >\n          >\n        >\n      >(p)\n    ) {\n      if (p == q) return rv;\n      while (p < q) {\n        // did we have interpolations?\n        if (*p == '#' && *(p+1) == '{') {\n          rv.has_interpolants = true;\n          p = q; break;\n        }\n        ++ p;\n      }\n      // store anyway\n      // ToDo: remove\n      rv.position = q;\n      // check expected opening bracket\n      // only after successful matching\n      if (peek < exactly<'{'> >(q)) rv.found = q;\n      else if (peek < exactly<';'> >(q)) rv.found = q;\n      else if (peek < exactly<'}'> >(q)) rv.found = q;\n    }\n\n    // return result\n    return rv;\n  }\n  // EO lookahead_for_value\n\n  void Parser::read_bom()\n  {\n    size_t skip = 0;\n    sass::string encoding;\n    bool utf_8 = false;\n    switch ((unsigned char)position[0]) {\n    case 0xEF:\n      skip = check_bom_chars(position, end, utf_8_bom, 3);\n      encoding = \"UTF-8\";\n      utf_8 = true;\n      break;\n    case 0xFE:\n      skip = check_bom_chars(position, end, utf_16_bom_be, 2);\n      encoding = \"UTF-16 (big endian)\";\n      break;\n    case 0xFF:\n      skip = check_bom_chars(position, end, utf_16_bom_le, 2);\n      skip += (skip ? check_bom_chars(position, end, utf_32_bom_le, 4) : 0);\n      encoding = (skip == 2 ? \"UTF-16 (little endian)\" : \"UTF-32 (little endian)\");\n      break;\n    case 0x00:\n      skip = check_bom_chars(position, end, utf_32_bom_be, 4);\n      encoding = \"UTF-32 (big endian)\";\n      break;\n    case 0x2B:\n      skip = check_bom_chars(position, end, utf_7_bom_1, 4)\n           | check_bom_chars(position, end, utf_7_bom_2, 4)\n           | check_bom_chars(position, end, utf_7_bom_3, 4)\n           | check_bom_chars(position, end, utf_7_bom_4, 4)\n           | check_bom_chars(position, end, utf_7_bom_5, 5);\n      encoding = \"UTF-7\";\n      break;\n    case 0xF7:\n      skip = check_bom_chars(position, end, utf_1_bom, 3);\n      encoding = \"UTF-1\";\n      break;\n    case 0xDD:\n      skip = check_bom_chars(position, end, utf_ebcdic_bom, 4);\n      encoding = \"UTF-EBCDIC\";\n      break;\n    case 0x0E:\n      skip = check_bom_chars(position, end, scsu_bom, 3);\n      encoding = \"SCSU\";\n      break;\n    case 0xFB:\n      skip = check_bom_chars(position, end, bocu_1_bom, 3);\n      encoding = \"BOCU-1\";\n      break;\n    case 0x84:\n      skip = check_bom_chars(position, end, gb_18030_bom, 4);\n      encoding = \"GB-18030\";\n      break;\n    default: break;\n    }\n    if (skip > 0 && !utf_8) error(\"only UTF-8 documents are currently supported; your document appears to be \" + encoding);\n    position += skip;\n  }\n\n  size_t check_bom_chars(const char* src, const char *end, const unsigned char* bom, size_t len)\n  {\n    size_t skip = 0;\n    if (src + len > end) return 0;\n    for (size_t i = 0; i < len; ++i, ++skip) {\n      if ((unsigned char) src[i] != bom[i]) return 0;\n    }\n    return skip;\n  }\n\n\n  ExpressionObj Parser::fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, Operand op)\n  {\n    for (size_t i = 0, S = operands.size(); i < S; ++i) {\n      base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), op, base, operands[i]);\n    }\n    return base;\n  }\n\n  ExpressionObj Parser::fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, sass::vector<Operand>& ops, size_t i)\n  {\n    if (String_Schema* schema = Cast<String_Schema>(base)) {\n      // return schema;\n      if (schema->has_interpolants()) {\n        if (i + 1 < operands.size() && (\n             (ops[0].operand == Sass_OP::EQ)\n          || (ops[0].operand == Sass_OP::ADD)\n          || (ops[0].operand == Sass_OP::DIV)\n          || (ops[0].operand == Sass_OP::MUL)\n          || (ops[0].operand == Sass_OP::NEQ)\n          || (ops[0].operand == Sass_OP::LT)\n          || (ops[0].operand == Sass_OP::GT)\n          || (ops[0].operand == Sass_OP::LTE)\n          || (ops[0].operand == Sass_OP::GTE)\n        )) {\n          ExpressionObj rhs = fold_operands(operands[i], operands, ops, i + 1);\n          rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[0], schema, rhs);\n          return rhs;\n        }\n        // return schema;\n      }\n    }\n\n    if (operands.size() > Constants::MaxCallStack) {\n        // XXX: this is never hit via spec tests\n        sass::ostream stm;\n        stm << \"Stack depth exceeded max of \" << Constants::MaxCallStack;\n        error(stm.str());\n    }\n\n    for (size_t S = operands.size(); i < S; ++i) {\n      if (String_Schema* schema = Cast<String_Schema>(operands[i])) {\n        if (schema->has_interpolants()) {\n          if (i + 1 < S) {\n            // this whole branch is never hit via spec tests\n            ExpressionObj rhs = fold_operands(operands[i+1], operands, ops, i + 2);\n            rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], schema, rhs);\n            base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, rhs);\n            return base;\n          }\n          base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]);\n          return base;\n        } else {\n          base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]);\n        }\n      } else {\n        base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]);\n      }\n      Binary_Expression* b = Cast<Binary_Expression>(base.ptr());\n      if (b && ops[i].operand == Sass_OP::DIV && b->left()->is_delayed() && b->right()->is_delayed()) {\n        base->is_delayed(true);\n      }\n    }\n    // nested binary expression are never to be delayed\n    if (Binary_Expression* b = Cast<Binary_Expression>(base)) {\n      if (Cast<Binary_Expression>(b->left())) base->set_delayed(false);\n      if (Cast<Binary_Expression>(b->right())) base->set_delayed(false);\n    }\n    return base;\n  }\n\n  void Parser::error(sass::string msg)\n  {\n    traces.push_back(Backtrace(pstate));\n    throw Exception::InvalidSass(pstate, traces, msg);\n  }\n\n  // print a css parsing error with actual context information from parsed source\n  void Parser::css_error(const sass::string& msg, const sass::string& prefix, const sass::string& middle, const bool trim)\n  {\n    int max_len = 18;\n    const char* end = this->end;\n    while (*end != 0) ++ end;\n    const char* pos = peek < optional_spaces >();\n    if (!pos) pos = position;\n\n    const char* last_pos(pos);\n    if (last_pos > begin) {\n      utf8::prior(last_pos, begin);\n    }\n    // backup position to last significant char\n    while (trim && last_pos > begin&& last_pos < end) {\n      if (!Util::ascii_isspace(static_cast<unsigned char>(*last_pos))) break;\n      utf8::prior(last_pos, begin);\n    }\n\n    bool ellipsis_left = false;\n    const char* pos_left(last_pos);\n    const char* end_left(last_pos);\n\n    if (*pos_left) utf8::next(pos_left, end);\n    if (*end_left) utf8::next(end_left, end);\n    while (pos_left > begin) {\n      if (utf8::distance(pos_left, end_left) >= max_len) {\n        utf8::prior(pos_left, begin);\n        ellipsis_left = *(pos_left) != '\\n' &&\n                        *(pos_left) != '\\r';\n        utf8::next(pos_left, end);\n        break;\n      }\n\n      const char* prev = pos_left;\n      utf8::prior(prev, begin);\n      if (*prev == '\\r') break;\n      if (*prev == '\\n') break;\n      pos_left = prev;\n    }\n    if (pos_left < begin) {\n      pos_left = begin;\n    }\n\n    bool ellipsis_right = false;\n    const char* end_right(pos);\n    const char* pos_right(pos);\n    while (end_right < end) {\n      if (utf8::distance(pos_right, end_right) > max_len) {\n        ellipsis_left = *(pos_right) != '\\n' &&\n                        *(pos_right) != '\\r';\n        break;\n      }\n      if (*end_right == '\\r') break;\n      if (*end_right == '\\n') break;\n      utf8::next(end_right, end);\n    }\n    // if (*end_right == 0) end_right ++;\n\n    sass::string left(pos_left, end_left);\n    sass::string right(pos_right, end_right);\n    size_t left_subpos = left.size() > 15 ? left.size() - 15 : 0;\n    size_t right_subpos = right.size() > 15 ? right.size() - 15 : 0;\n    if (left_subpos && ellipsis_left) left = ellipsis + left.substr(left_subpos);\n    if (right_subpos && ellipsis_right) right = right.substr(right_subpos) + ellipsis;\n    // now pass new message to the more generic error function\n    error(msg + prefix + quote(left) + middle + quote(right));\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/parser.hpp",
    "content": "#ifndef SASS_PARSER_H\n#define SASS_PARSER_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <string>\n#include <vector>\n\n#include \"ast.hpp\"\n#include \"position.hpp\"\n#include \"context.hpp\"\n#include \"position.hpp\"\n#include \"prelexer.hpp\"\n#include \"source.hpp\"\n\n#ifndef MAX_NESTING\n// Note that this limit is not an exact science\n// it depends on various factors, which some are\n// not under our control (compile time or even OS\n// dependent settings on the available stack size)\n// It should fix most common segfault cases though.\n#define MAX_NESTING 512\n#endif\n\nstruct Lookahead {\n  const char* found;\n  const char* error;\n  const char* position;\n  bool parsable;\n  bool has_interpolants;\n  bool is_custom_property;\n};\n\nnamespace Sass {\n\n  class Parser : public SourceSpan {\n  public:\n\n    enum Scope { Root, Mixin, Function, Media, Control, Properties, Rules, AtRoot };\n\n    Context& ctx;\n    sass::vector<Block_Obj> block_stack;\n    sass::vector<Scope> stack;\n    SourceDataObj source;\n    const char* begin;\n    const char* position;\n    const char* end;\n    Offset before_token;\n    Offset after_token;\n    SourceSpan pstate;\n    Backtraces traces;\n    size_t indentation;\n    size_t nestings;\n    bool allow_parent;\n    Token lexed;\n\n    Parser(SourceData* source, Context& ctx, Backtraces, bool allow_parent = true);\n\n    // special static parsers to convert strings into certain selectors\n    static SelectorListObj parse_selector(SourceData* source, Context& ctx, Backtraces, bool allow_parent = true);\n\n#ifdef __clang__\n\n    // lex and peak uses the template parameter to branch on the action, which\n    // triggers clangs tautological comparison on the single-comparison\n    // branches. This is not a bug, just a merging of behaviour into\n    // one function\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wtautological-compare\"\n\n#endif\n\n\n    // skip current token and next whitespace\n    // moves SourceSpan right before next token\n    void advanceToNextToken();\n\n    bool peek_newline(const char* start = 0);\n\n    // skip over spaces, tabs and line comments\n    template <Prelexer::prelexer mx>\n    const char* sneak(const char* start = 0)\n    {\n      using namespace Prelexer;\n\n      // maybe use optional start position from arguments?\n      const char* it_position = start ? start : position;\n\n      // skip white-space?\n      if (mx == spaces ||\n          mx == no_spaces ||\n          mx == css_comments ||\n          mx == css_whitespace ||\n          mx == optional_spaces ||\n          mx == optional_css_comments ||\n          mx == optional_css_whitespace\n      ) {\n        return it_position;\n      }\n\n      // skip over spaces, tabs and sass line comments\n      const char* pos = optional_css_whitespace(it_position);\n      // always return a valid position\n      return pos ? pos : it_position;\n\n    }\n\n    // match will not skip over space, tabs and line comment\n    // return the position where the lexer match will occur\n    template <Prelexer::prelexer mx>\n    const char* match(const char* start = 0)\n    {\n      // match the given prelexer\n      return mx(position);\n    }\n\n    // peek will only skip over space, tabs and line comment\n    // return the position where the lexer match will occur\n    template <Prelexer::prelexer mx>\n    const char* peek(const char* start = 0)\n    {\n\n      // sneak up to the actual token we want to lex\n      // this should skip over white-space if desired\n      const char* it_before_token = sneak < mx >(start);\n\n      // match the given prelexer\n      const char* match = mx(it_before_token);\n\n      // check if match is in valid range\n      return match <= end ? match : 0;\n\n    }\n\n    // white-space handling is built into the lexer\n    // this way you do not need to parse it yourself\n    // some matchers don't accept certain white-space\n    // we do not support start arg, since we manipulate\n    // sourcemap offset and we modify the position pointer!\n    // lex will only skip over space, tabs and line comment\n    template <Prelexer::prelexer mx>\n    const char* lex(bool lazy = true, bool force = false)\n    {\n\n      if (*position == 0) return 0;\n\n      // position considered before lexed token\n      // we can skip whitespace or comments for\n      // lazy developers (but we need control)\n      const char* it_before_token = position;\n\n      // sneak up to the actual token we want to lex\n      // this should skip over white-space if desired\n      if (lazy) it_before_token = sneak < mx >(position);\n\n      // now call matcher to get position after token\n      const char* it_after_token = mx(it_before_token);\n\n      // check if match is in valid range\n      if (it_after_token > end) return 0;\n\n      // maybe we want to update the parser state anyway?\n      if (force == false) {\n        // assertion that we got a valid match\n        if (it_after_token == 0) return 0;\n        // assertion that we actually lexed something\n        if (it_after_token == it_before_token) return 0;\n      }\n\n      // create new lexed token object (holds the parse results)\n      lexed = Token(position, it_before_token, it_after_token);\n\n      // advance position (add whitespace before current token)\n      before_token = after_token.add(position, it_before_token);\n\n      // update after_token position for current token\n      after_token.add(it_before_token, it_after_token);\n\n      // ToDo: could probably do this incremental on original object (API wants offset?)\n      pstate = SourceSpan(source, before_token, after_token - before_token);\n\n      // advance internal char iterator\n      return position = it_after_token;\n\n    }\n\n    // lex_css skips over space, tabs, line and block comment\n    // all block comments will be consumed and thrown away\n    // source-map position will point to token after the comment\n    template <Prelexer::prelexer mx>\n    const char* lex_css()\n    {\n      // copy old token\n      Token prev = lexed;\n      // store previous pointer\n      const char* oldpos = position;\n      Offset bt = before_token;\n      Offset at = after_token;\n      SourceSpan op = pstate;\n      // throw away comments\n      // update srcmap position\n      lex < Prelexer::css_comments >();\n      // now lex a new token\n      const char* pos = lex< mx >();\n      // maybe restore prev state\n      if (pos == 0) {\n        pstate = op;\n        lexed = prev;\n        position = oldpos;\n        after_token = at;\n        before_token = bt;\n      }\n      // return match\n      return pos;\n    }\n\n    // all block comments will be skipped and thrown away\n    template <Prelexer::prelexer mx>\n    const char* peek_css(const char* start = 0)\n    {\n      // now peek a token (skip comments first)\n      return peek< mx >(peek < Prelexer::css_comments >(start));\n    }\n\n#ifdef __clang__\n\n#pragma clang diagnostic pop\n\n#endif\n\n    void error(sass::string msg);\n    // generate message with given and expected sample\n    // text before and in the middle are configurable\n    void css_error(const sass::string& msg,\n                   const sass::string& prefix = \" after \",\n                   const sass::string& middle = \", was: \",\n                   const bool trim = true);\n    void read_bom();\n\n    Block_Obj parse();\n    Import_Obj parse_import();\n    Definition_Obj parse_definition(Definition::Type which_type);\n    Parameters_Obj parse_parameters();\n    Parameter_Obj parse_parameter();\n    Mixin_Call_Obj parse_include_directive();\n    Arguments_Obj parse_arguments();\n    Argument_Obj parse_argument();\n    Assignment_Obj parse_assignment();\n    StyleRuleObj parse_ruleset(Lookahead lookahead);\n    SelectorListObj parseSelectorList(bool chroot);\n    ComplexSelectorObj parseComplexSelector(bool chroot);\n    Selector_Schema_Obj parse_selector_schema(const char* end_of_selector, bool chroot);\n    CompoundSelectorObj parseCompoundSelector();\n    SimpleSelectorObj parse_simple_selector();\n    PseudoSelectorObj parse_negated_selector2();\n    Expression* parse_binominal();\n    SimpleSelectorObj parse_pseudo_selector();\n    AttributeSelectorObj parse_attribute_selector();\n    Block_Obj parse_block(bool is_root = false);\n    Block_Obj parse_css_block(bool is_root = false);\n    bool parse_block_nodes(bool is_root = false);\n    bool parse_block_node(bool is_root = false);\n\n    Declaration_Obj parse_declaration();\n    ExpressionObj parse_map();\n    ExpressionObj parse_bracket_list();\n    ExpressionObj parse_list(bool delayed = false);\n    ExpressionObj parse_comma_list(bool delayed = false);\n    ExpressionObj parse_space_list();\n    ExpressionObj parse_disjunction();\n    ExpressionObj parse_conjunction();\n    ExpressionObj parse_relation();\n    ExpressionObj parse_expression();\n    ExpressionObj parse_operators();\n    ExpressionObj parse_factor();\n    ExpressionObj parse_value();\n    Function_Call_Obj parse_calc_function();\n    Function_Call_Obj parse_function_call();\n    Function_Call_Obj parse_function_call_schema();\n    String_Obj parse_url_function_string();\n    String_Obj parse_url_function_argument();\n    String_Obj parse_interpolated_chunk(Token, bool constant = false, bool css = true);\n    String_Obj parse_string();\n    ValueObj parse_static_value();\n    String_Schema_Obj parse_css_variable_value();\n    String_Obj parse_ie_property();\n    String_Obj parse_ie_keyword_arg();\n    String_Schema_Obj parse_value_schema(const char* stop);\n    String_Obj parse_identifier_schema();\n    If_Obj parse_if_directive(bool else_if = false);\n    ForRuleObj parse_for_directive();\n    EachRuleObj parse_each_directive();\n    WhileRuleObj parse_while_directive();\n    MediaRule_Obj parseMediaRule();\n    sass::vector<CssMediaQuery_Obj> parseCssMediaQueries();\n    sass::string parseIdentifier();\n    CssMediaQuery_Obj parseCssMediaQuery();\n    Return_Obj parse_return_directive();\n    Content_Obj parse_content_directive();\n    void parse_charset_directive();\n    List_Obj parse_media_queries();\n    Media_Query_Obj parse_media_query();\n    Media_Query_ExpressionObj parse_media_expression();\n    SupportsRuleObj parse_supports_directive();\n    SupportsConditionObj parse_supports_condition(bool top_level);\n    SupportsConditionObj parse_supports_negation();\n    SupportsConditionObj parse_supports_operator(bool top_level);\n    SupportsConditionObj parse_supports_interpolation();\n    SupportsConditionObj parse_supports_declaration();\n    SupportsConditionObj parse_supports_condition_in_parens(bool parens_required);\n    AtRootRuleObj parse_at_root_block();\n    At_Root_Query_Obj parse_at_root_query();\n    String_Schema_Obj parse_almost_any_value();\n    AtRuleObj parse_directive();\n    WarningRuleObj parse_warning();\n    ErrorRuleObj parse_error();\n    DebugRuleObj parse_debug();\n\n    Value* color_or_string(const sass::string& lexed) const;\n\n    // be more like ruby sass\n    ExpressionObj lex_almost_any_value_token();\n    ExpressionObj lex_almost_any_value_chars();\n    ExpressionObj lex_interp_string();\n    ExpressionObj lex_interp_uri();\n    ExpressionObj lex_interpolation();\n\n    // these will throw errors\n    Token lex_variable();\n    Token lex_identifier();\n\n    void parse_block_comments(bool store = true);\n\n    Lookahead lookahead_for_value(const char* start = 0);\n    Lookahead lookahead_for_selector(const char* start = 0);\n    Lookahead lookahead_for_include(const char* start = 0);\n\n    ExpressionObj fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, Operand op);\n    ExpressionObj fold_operands(ExpressionObj base, sass::vector<ExpressionObj>& operands, sass::vector<Operand>& ops, size_t i = 0);\n\n    void throw_syntax_error(sass::string message, size_t ln = 0);\n    void throw_read_error(sass::string message, size_t ln = 0);\n\n\n    template <Prelexer::prelexer open, Prelexer::prelexer close>\n    ExpressionObj lex_interp()\n    {\n      if (lex < open >(false)) {\n        String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);\n        // std::cerr << \"LEX [[\" << sass::string(lexed) << \"]]\\n\";\n        schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));\n        if (position[0] == '#' && position[1] == '{') {\n          ExpressionObj itpl = lex_interpolation();\n          if (!itpl.isNull()) schema->append(itpl);\n          while (lex < close >(false)) {\n            // std::cerr << \"LEX [[\" << sass::string(lexed) << \"]]\\n\";\n            schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));\n            if (position[0] == '#' && position[1] == '{') {\n              ExpressionObj itpl = lex_interpolation();\n              if (!itpl.isNull()) schema->append(itpl);\n            } else {\n              return schema;\n            }\n          }\n        } else {\n          return SASS_MEMORY_NEW(String_Constant, pstate, lexed);\n        }\n      }\n      return {};\n    }\n\n  public:\n    static Number* lexed_number(const SourceSpan& pstate, const sass::string& parsed);\n    static Number* lexed_dimension(const SourceSpan& pstate, const sass::string& parsed);\n    static Number* lexed_percentage(const SourceSpan& pstate, const sass::string& parsed);\n    static Value* lexed_hex_color(const SourceSpan& pstate, const sass::string& parsed);\n  private:\n    Number* lexed_number(const sass::string& parsed) { return lexed_number(pstate, parsed); };\n    Number* lexed_dimension(const sass::string& parsed) { return lexed_dimension(pstate, parsed); };\n    Number* lexed_percentage(const sass::string& parsed) { return lexed_percentage(pstate, parsed); };\n    Value* lexed_hex_color(const sass::string& parsed) { return lexed_hex_color(pstate, parsed); };\n\n    static const char* re_attr_sensitive_close(const char* src);\n    static const char* re_attr_insensitive_close(const char* src);\n\n  };\n\n  size_t check_bom_chars(const char* src, const char *end, const unsigned char* bom, size_t len);\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/parser_selectors.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"parser.hpp\"\n\nnamespace Sass {\n\n  using namespace Prelexer;\n  using namespace Constants;\n\n  ComplexSelectorObj Parser::parseComplexSelector(bool chroot)\n  {\n\n    NESTING_GUARD(nestings);\n\n    lex < block_comment >();\n    advanceToNextToken();\n\n    ComplexSelectorObj sel = SASS_MEMORY_NEW(ComplexSelector, pstate);\n\n    if (peek < end_of_file >()) return sel;\n\n    while (true) {\n\n      lex < block_comment >();\n      advanceToNextToken();\n\n      // check for child (+) combinator\n      if (lex < exactly < selector_combinator_child > >()) {\n        sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::CHILD, peek_newline()));\n      }\n      // check for general sibling (~) combinator\n      else if (lex < exactly < selector_combinator_general > >()) {\n        sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::GENERAL, peek_newline()));\n      }\n      // check for adjecant sibling (+) combinator\n      else if (lex < exactly < selector_combinator_adjacent > >()) {\n        sel->append(SASS_MEMORY_NEW(SelectorCombinator, pstate, SelectorCombinator::ADJACENT, peek_newline()));\n      }\n      // check if we can parse a compound selector\n      else if (CompoundSelectorObj compound = parseCompoundSelector()) {\n        sel->append(compound);\n      }\n      else {\n        break;\n      }\n    }\n\n    if (sel->empty()) return {};\n\n    // check if we parsed any parent references\n    sel->chroots(sel->has_real_parent_ref() || chroot);\n\n    sel->update_pstate(pstate);\n\n    return sel;\n\n  }\n\n  SelectorListObj Parser::parseSelectorList(bool chroot)\n  {\n\n    bool reloop;\n    bool had_linefeed = false;\n    NESTING_GUARD(nestings);\n    SelectorListObj list = SASS_MEMORY_NEW(SelectorList, pstate);\n\n    if (peek_css< alternatives < end_of_file, exactly <'{'>, exactly <','> > >()) {\n      css_error(\"Invalid CSS\", \" after \", \": expected selector, was \");\n    }\n\n    do {\n      reloop = false;\n\n      had_linefeed = had_linefeed || peek_newline();\n\n      if (peek_css< alternatives < class_char < selector_list_delims > > >())\n        break; // in case there are superfluous commas at the end\n\n      // now parse the complex selector\n      ComplexSelectorObj complex = parseComplexSelector(chroot);\n      if (complex.isNull()) return list.detach();\n      complex->hasPreLineFeed(had_linefeed);\n\n      had_linefeed = false;\n\n      while (peek_css< exactly<','> >())\n      {\n        lex< css_comments >(false);\n        // consume everything up and including the comma separator\n        reloop = lex< exactly<','> >() != 0;\n        // remember line break (also between some commas)\n        had_linefeed = had_linefeed || peek_newline();\n        // remember line break (also between some commas)\n      }\n      list->append(complex);\n\n    } while (reloop);\n\n    while (lex_css< kwd_optional >()) {\n      list->is_optional(true);\n    }\n\n    // update for end position\n    list->update_pstate(pstate);\n\n    return list.detach();\n  }\n\n  // parse one compound selector, which is basically\n  // a list of simple selectors (directly adjacent)\n  // lex them exactly (without skipping white-space)\n  CompoundSelectorObj Parser::parseCompoundSelector()\n  {\n    // init an empty compound selector wrapper\n    CompoundSelectorObj seq = SASS_MEMORY_NEW(CompoundSelector, pstate);\n\n    // skip initial white-space\n    lex < block_comment >();\n    advanceToNextToken();\n\n    if (lex< exactly<'&'> >(false))\n    {\n      // ToDo: check the conditions and try to simplify flag passing\n      if (!allow_parent) error(\"Parent selectors aren't allowed here.\");\n      // Create and append a new parent selector object\n      seq->hasRealParent(true);\n    }\n\n    // parse list\n    while (true)\n    {\n      // remove all block comments\n      // leaves trailing white-space\n      lex < block_comment >();\n      // parse parent selector\n      if (lex< exactly<'&'> >(false))\n      {\n        // parent selector only allowed at start\n        // upcoming Sass may allow also trailing\n        SourceSpan state(pstate);\n        sass::string found(\"&\");\n        if (lex < identifier >()) {\n          found += sass::string(lexed);\n        }\n        sass::string sel(seq->hasRealParent() ? \"&\" : \"\");\n        if (!seq->empty()) { sel = seq->last()->to_string({ NESTED, 5 }); }\n        // ToDo: parser should throw parser exceptions\n        error(\"Invalid CSS after \\\"\" + sel + \"\\\": expected \\\"{\\\", was \\\"\" + found + \"\\\"\\n\\n\"\n          \"\\\"\" + found + \"\\\" may only be used at the beginning of a compound selector.\");\n      }\n      // parse functional\n      else if (match < re_functional >())\n        {\n          seq->append(parse_simple_selector());\n        }\n\n      // parse type selector\n      else if (lex< re_type_selector >(false))\n      {\n        seq->append(SASS_MEMORY_NEW(TypeSelector, pstate, lexed));\n      }\n      // peek for abort conditions\n      else if (peek< spaces >()) break;\n      else if (peek< end_of_file >()) { break; }\n      else if (peek_css < class_char < selector_combinator_ops > >()) break;\n      else if (peek_css < class_char < complex_selector_delims > >()) break;\n      // otherwise parse another simple selector\n      else {\n        SimpleSelectorObj sel = parse_simple_selector();\n        if (!sel) return {};\n        seq->append(sel);\n      }\n    }\n    // EO while true\n\n    if (seq && !peek_css<alternatives<end_of_file,exactly<'{'>>>()) {\n      seq->hasPostLineBreak(peek_newline());\n    }\n\n    // We may have set hasRealParent\n    if (seq && seq->empty() && !seq->hasRealParent()) return {};\n\n    return seq;\n  }\n\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/permutate.hpp",
    "content": "#ifndef SASS_PATHS_H\n#define SASS_PATHS_H\n\n#include <vector>\n\nnamespace Sass {\n\n  // Returns a list of all possible paths through the given lists.\n  //\n  // For example, given `[[1, 2], [3, 4], [5, 6]]`, this returns:\n  //\n  // ```\n  // [[1, 3, 5],\n  //  [2, 3, 5],\n  //  [1, 4, 5],\n  //  [2, 4, 5],\n  //  [1, 3, 6],\n  //  [2, 3, 6],\n  //  [1, 4, 6],\n  //  [2, 4, 6]]\n  // ```\n  // \n  // Note: called `paths` in dart-sass\n  template <class T>\n  sass::vector<sass::vector<T>> permutate(\n    const sass::vector<sass::vector<T>>& in)\n  {\n\n    size_t L = in.size(), n = 0;\n\n    if (L == 0) return {};\n    // Exit early if any entry is empty\n    for (size_t i = 0; i < L; i += 1) {\n      if (in[i].size() == 0) return {};\n    }\n\n    size_t* state = new size_t[L + 1];\n    sass::vector<sass::vector<T>> out;\n\n    // First initialize all states for every permutation group\n    for (size_t i = 0; i < L; i += 1) {\n      state[i] = in[i].size() - 1;\n    }\n    while (true) {\n      sass::vector<T> perm;\n      // Create one permutation for state\n      for (size_t i = 0; i < L; i += 1) {\n        perm.push_back(in.at(i).at(in[i].size() - state[i] - 1));\n      }\n      // Current group finished\n      if (state[n] == 0) {\n        // Find position of next decrement\n        while (n < L && state[++n] == 0) {}\n\n        if (n == L) {\n          out.push_back(perm);\n          break;\n        }\n\n        state[n] -= 1;\n\n        for (size_t p = 0; p < n; p += 1) {\n          state[p] = in[p].size() - 1;\n        }\n\n        // Restart from front\n        n = 0;\n\n      }\n      else {\n        state[n] -= 1;\n      }\n      out.push_back(perm);\n    }\n\n    delete[] state;\n    return out;\n  }\n  // EO permutate\n\n  // ToDo: this variant is used in resolveParentSelectors\n  // Returns a list of all possible paths through the given lists.\n  //\n  // For example, given `[[1, 2], [3, 4], [5, 6]]`, this returns:\n  //\n  // ```\n  // [[1, 3, 5],\n  //  [1, 3, 6],\n  //  [1, 4, 5],\n  //  [1, 4, 6],\n  //  [2, 3, 5],\n  //  [2, 3, 6],\n  //  [2, 4, 5],\n  //  [2, 4, 6]]\n  // ```\n  // \n  template <class T>\n  sass::vector<sass::vector<T>>\n    permutateAlt(const sass::vector<sass::vector<T>>& in) {\n\n    size_t L = in.size();\n    size_t n = in.size() - 1;\n\n    if (L == 0) return {};\n    // Exit early if any entry is empty\n    for (size_t i = 0; i < L; i += 1) {\n      if (in[i].size() == 0) return {};\n    }\n\n    size_t* state = new size_t[L];\n    sass::vector<sass::vector<T>> out;\n\n    // First initialize all states for every permutation group\n    for (size_t i = 0; i < L; i += 1) {\n      state[i] = in[i].size() - 1;\n    }\n\n    while (true) {\n      /*\n      // std::cerr << \"PERM: \";\n      for (size_t p = 0; p < L; p++)\n      { // std::cerr << state[p] << \" \"; }\n      // std::cerr << \"\\n\";\n      */\n      sass::vector<T> perm;\n      // Create one permutation for state\n      for (size_t i = 0; i < L; i += 1) {\n        perm.push_back(in.at(i).at(in[i].size() - state[i] - 1));\n      }\n      // Current group finished\n      if (state[n] == 0) {\n        // Find position of next decrement\n        while (n > 0 && state[--n] == 0) {}\n\n        // Check for end condition\n        if (state[n] != 0) {\n          // Decrease next on the left side\n          state[n] -= 1;\n          // Reset all counters to the right\n          for (size_t p = n + 1; p < L; p += 1) {\n            state[p] = in[p].size() - 1;\n          }\n          // Restart from end\n          n = L - 1;\n        }\n        else {\n          out.push_back(perm);\n          break;\n        }\n      }\n      else {\n        state[n] -= 1;\n      }\n      out.push_back(perm);\n    }\n\n    delete[] state;\n    return out;\n  }\n  // EO permutateAlt\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/plugins.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <iostream>\n#include \"output.hpp\"\n#include \"plugins.hpp\"\n#include \"util.hpp\"\n\n#ifdef _WIN32\n#include <windows.h>\n#else\n#include <sys/types.h>\n#include <dirent.h>\n#include <errno.h>\n#include <dlfcn.h>\n#endif\n\nnamespace Sass {\n\n  Plugins::Plugins(void) { }\n  Plugins::~Plugins(void)\n  {\n    for (auto function : functions) {\n      sass_delete_function(function);\n    }\n    for (auto importer : importers) {\n      sass_delete_importer(importer);\n    }\n    for (auto header : headers) {\n      sass_delete_importer(header);\n    }\n  }\n\n  // check if plugin is compatible with this version\n  // plugins may be linked static against libsass\n  // we try to be compatible between major versions\n  inline bool compatibility(const char* their_version)\n  {\n// const char* their_version = \"3.1.2\";\n    // first check if anyone has an unknown version\n    const char* our_version = libsass_version();\n    if (!strcmp(their_version, \"[na]\")) return false;\n    if (!strcmp(our_version, \"[na]\")) return false;\n\n    // find the position of the second dot\n    size_t pos = sass::string(our_version).find('.', 0);\n    if (pos != sass::string::npos) pos = sass::string(our_version).find('.', pos + 1);\n\n    // if we do not have two dots we fallback to compare complete string\n    if (pos == sass::string::npos) { return strcmp(their_version, our_version) ? 0 : 1; }\n    // otherwise only compare up to the second dot (major versions)\n    else { return strncmp(their_version, our_version, pos) ? 0 : 1; }\n\n  }\n\n  // load one specific plugin\n  bool Plugins::load_plugin (const sass::string& path)\n  {\n\n    typedef const char* (*__plugin_version__)(void);\n    typedef Sass_Function_List (*__plugin_load_fns__)(void);\n    typedef Sass_Importer_List (*__plugin_load_imps__)(void);\n\n    if (LOAD_LIB(plugin, path))\n    {\n      // try to load initial function to query libsass version suppor\n      if (LOAD_LIB_FN(__plugin_version__, plugin_version, \"libsass_get_version\"))\n      {\n        // get the libsass version of the plugin\n        if (!compatibility(plugin_version())) return false;\n        // try to get import address for \"libsass_load_functions\"\n        if (LOAD_LIB_FN(__plugin_load_fns__, plugin_load_functions, \"libsass_load_functions\"))\n        {\n          Sass_Function_List fns = plugin_load_functions(), _p = fns;\n          while (fns && *fns) { functions.push_back(*fns); ++ fns; }\n          sass_free_memory(_p); // only delete the container, items not yet\n        }\n        // try to get import address for \"libsass_load_importers\"\n        if (LOAD_LIB_FN(__plugin_load_imps__, plugin_load_importers, \"libsass_load_importers\"))\n        {\n          Sass_Importer_List imps = plugin_load_importers(), _p = imps;\n          while (imps && *imps) { importers.push_back(*imps); ++ imps; }\n          sass_free_memory(_p); // only delete the container, items not yet\n        }\n        // try to get import address for \"libsass_load_headers\"\n        if (LOAD_LIB_FN(__plugin_load_imps__, plugin_load_headers, \"libsass_load_headers\"))\n        {\n          Sass_Importer_List imps = plugin_load_headers(), _p = imps;\n          while (imps && *imps) { headers.push_back(*imps); ++ imps; }\n          sass_free_memory(_p); // only delete the container, items not yet\n        }\n        // success\n        return true;\n      }\n      else\n      {\n        // print debug message to stderr (should not happen)\n        std::cerr << \"failed loading 'libsass_support' in <\" << path << \">\" << std::endl;\n        if (const char* dlsym_error = dlerror()) std::cerr << dlsym_error << std::endl;\n        CLOSE_LIB(plugin);\n      }\n    }\n    else\n    {\n      // print debug message to stderr (should not happen)\n      std::cerr << \"failed loading plugin <\" << path << \">\" << std::endl;\n      if (const char* dlopen_error = dlerror()) std::cerr << dlopen_error << std::endl;\n    }\n\n    return false;\n\n  }\n\n  size_t Plugins::load_plugins(const sass::string& path)\n  {\n\n    // count plugins\n    size_t loaded = 0;\n\n    #ifdef _WIN32\n\n      try\n      {\n\n        // use wchar (utf16)\n        WIN32_FIND_DATAW data;\n        // trailing slash is guaranteed\n        sass::string globsrch(path + \"*.dll\");\n        // convert to wide chars (utf16) for system call\n        std::wstring wglobsrch(UTF_8::convert_to_utf16(globsrch));\n        HANDLE hFile = FindFirstFileW(wglobsrch.c_str(), &data);\n        // check if system called returned a result\n        // ToDo: maybe we should print a debug message\n        if (hFile == INVALID_HANDLE_VALUE) return -1;\n\n        // read directory\n        while (true)\n        {\n          try\n          {\n            // the system will report the filenames with wide chars (utf16)\n            sass::string entry = UTF_8::convert_from_utf16(data.cFileName);\n            // check if file ending matches exactly\n            if (!ends_with(entry, \".dll\")) continue;\n            // load the plugin and increase counter\n            if (load_plugin(path + entry)) ++ loaded;\n            // check if there should be more entries\n            if (GetLastError() == ERROR_NO_MORE_FILES) break;\n            // load next entry (check for return type)\n            if (!FindNextFileW(hFile, &data)) break;\n          }\n          catch (...)\n          {\n            // report the error to the console (should not happen)\n            // seems like we got strange data from the system call?\n            std::cerr << \"filename in plugin path has invalid utf8?\" << std::endl;\n          }\n        }\n      }\n      catch (utf8::invalid_utf8&)\n      {\n        // report the error to the console (should not happen)\n        // implementors should make sure to provide valid utf8\n        std::cerr << \"plugin path contains invalid utf8\" << std::endl;\n      }\n\n    #else\n\n      DIR *dp;\n      struct dirent *dirp;\n      if((dp  = opendir(path.c_str())) == NULL) return -1;\n      while ((dirp = readdir(dp)) != NULL) {\n        #if __APPLE__\n          if (!ends_with(dirp->d_name, \".dylib\")) continue;\n        #else\n          if (!ends_with(dirp->d_name, \".so\")) continue;\n        #endif\n        if (load_plugin(path + dirp->d_name)) ++ loaded;\n      }\n      closedir(dp);\n\n    #endif\n    return loaded;\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/plugins.hpp",
    "content": "#ifndef SASS_PLUGINS_H\n#define SASS_PLUGINS_H\n\n#include <string>\n#include <vector>\n#include \"utf8_string.hpp\"\n#include \"sass/functions.h\"\n\n#ifdef _WIN32\n\n  #define LOAD_LIB(var, path) HMODULE var = LoadLibraryW(UTF_8::convert_to_utf16(path).c_str())\n  #define LOAD_LIB_WCHR(var, path_wide_str) HMODULE var = LoadLibraryW(path_wide_str.c_str())\n  #define LOAD_LIB_FN(type, var, name) type var = (type) GetProcAddress(plugin, name)\n  #define CLOSE_LIB(var) FreeLibrary(var)\n\n  #ifndef dlerror\n  #define dlerror() 0\n  #endif\n\n#else\n\n  #define LOAD_LIB(var, path) void* var = dlopen(path.c_str(), RTLD_LAZY)\n  #define LOAD_LIB_FN(type, var, name) type var = (type) dlsym(plugin, name)\n  #define CLOSE_LIB(var) dlclose(var)\n\n#endif\n\nnamespace Sass {\n\n\n  class Plugins {\n\n    public: // c-tor\n      Plugins(void);\n      ~Plugins(void);\n\n    public: // methods\n      // load one specific plugin\n      bool load_plugin(const sass::string& path);\n      // load all plugins from a directory\n      size_t load_plugins(const sass::string& path);\n\n    public: // public accessors\n      const sass::vector<Sass_Importer_Entry> get_headers(void) { return headers; }\n      const sass::vector<Sass_Importer_Entry> get_importers(void) { return importers; }\n      const sass::vector<Sass_Function_Entry> get_functions(void) { return functions; }\n\n    private: // private vars\n      sass::vector<Sass_Importer_Entry> headers;\n      sass::vector<Sass_Importer_Entry> importers;\n      sass::vector<Sass_Function_Entry> functions;\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/position.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"position.hpp\"\n#include \"source.hpp\"\n\nnamespace Sass {\n\n\n  Offset::Offset(const char chr)\n  : line(chr == '\\n' ? 1 : 0),\n    column(chr == '\\n' ? 0 : 1)\n  {}\n\n  Offset::Offset(const char* string)\n  : line(0), column(0)\n  {\n    *this = inc(string, string + strlen(string));\n  }\n\n  Offset::Offset(const sass::string& text)\n  : line(0), column(0)\n  {\n    *this = inc(text.c_str(), text.c_str() + text.size());\n  }\n\n  Offset::Offset(const size_t line, const size_t column)\n  : line(line), column(column) { }\n\n  // init/create instance from const char substring\n  Offset Offset::init(const char* beg, const char* end)\n  {\n    Offset offset(0, 0);\n    if (end == 0) {\n      end = beg + strlen(beg);\n    }\n    offset.add(beg, end);\n    return offset;\n  }\n\n  // increase offset by given string (mostly called by lexer)\n  // increase line counter and count columns on the last line\n  Offset Offset::add(const char* begin, const char* end)\n  {\n    if (end == 0) return *this;\n    while (begin < end && *begin) {\n      if (*begin == '\\n') {\n        ++ line;\n        // start new line\n        column = 0;\n      } else {\n        // do not count any utf8 continuation bytes\n        // https://stackoverflow.com/a/9356203/1550314\n        // https://en.wikipedia.org/wiki/UTF-8#Description\n        unsigned char chr = *begin;\n        // Ignore all `10xxxxxx` chars\n        // '0xxxxxxx' are ASCII chars\n        // '11xxxxxx' are utf8 starts\n        // 64 => initial utf8 byte\n        // 128 => regular ASCII char\n        if ((chr & 192) != 128) {\n          // regular ASCII char\n          column += 1;\n        }\n      }\n      ++ begin;\n    }\n    return *this;\n  }\n\n  // increase offset by given string (mostly called by lexer)\n  // increase line counter and count columns on the last line\n  Offset Offset::inc(const char* begin, const char* end) const\n  {\n    Offset offset(line, column);\n    offset.add(begin, end);\n    return offset;\n  }\n\n  bool Offset::operator== (const Offset &pos) const\n  {\n    return line == pos.line && column == pos.column;\n  }\n\n  bool Offset::operator!= (const Offset &pos) const\n  {\n    return line != pos.line || column != pos.column;\n  }\n\n  void Offset::operator+= (const Offset &off)\n  {\n    *this = Offset(line + off.line, off.line > 0 ? off.column : column + off.column);\n  }\n\n  Offset Offset::operator+ (const Offset &off) const\n  {\n    return Offset(line + off.line, off.line > 0 ? off.column : column + off.column);\n  }\n\n  Offset Offset::operator- (const Offset &off) const\n  {\n    return Offset(line - off.line, off.line == line ? column - off.column : column);\n  }\n\n  Position::Position(const size_t file)\n  : Offset(0, 0), file(file) { }\n\n  Position::Position(const size_t file, const Offset& offset)\n  : Offset(offset), file(file) { }\n\n  Position::Position(const size_t line, const size_t column)\n  : Offset(line, column), file(-1) { }\n\n  Position::Position(const size_t file, const size_t line, const size_t column)\n  : Offset(line, column), file(file) { }\n\n\n  SourceSpan::SourceSpan(const char* path)\n  : source(SASS_MEMORY_NEW(SynthFile, path)), position(0, 0), offset(0, 0) { }\n\n  SourceSpan::SourceSpan(SourceDataObj source, const Offset& position, const Offset& offset)\n    : source(source), position(position), offset(offset) { }\n\n  Position Position::add(const char* begin, const char* end)\n  {\n    Offset::add(begin, end);\n    return *this;\n  }\n\n  Position Position::inc(const char* begin, const char* end) const\n  {\n    Offset offset(line, column);\n    offset = offset.inc(begin, end);\n    return Position(file, offset);\n  }\n\n  bool Position::operator== (const Position &pos) const\n  {\n    return file == pos.file && line == pos.line && column == pos.column;\n  }\n\n  bool Position::operator!= (const Position &pos) const\n  {\n    return file == pos.file || line != pos.line || column != pos.column;\n  }\n\n  void Position::operator+= (const Offset &off)\n  {\n    *this = Position(file, line + off.line, off.line > 0 ? off.column : column + off.column);\n  }\n\n  const Position Position::operator+ (const Offset &off) const\n  {\n    return Position(file, line + off.line, off.line > 0 ? off.column : column + off.column);\n  }\n\n  const Offset Position::operator- (const Offset &off) const\n  {\n    return Offset(line - off.line, off.line == line ? column - off.column : column);\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/position.hpp",
    "content": "#ifndef SASS_POSITION_H\n#define SASS_POSITION_H\n\n#include <string>\n#include <cstring>\n#include \"source_data.hpp\"\n#include \"ast_fwd_decl.hpp\"\n\nnamespace Sass {\n\n\n  class Offset {\n\n    public: // c-tor\n      Offset(const char chr);\n      Offset(const char* string);\n      Offset(const sass::string& text);\n      Offset(const size_t line, const size_t column);\n\n      // return new position, incremented by the given string\n      Offset add(const char* begin, const char* end);\n      Offset inc(const char* begin, const char* end) const;\n\n      // init/create instance from const char substring\n      static Offset init(const char* beg, const char* end);\n\n    public: // overload operators for position\n      void operator+= (const Offset &pos);\n      bool operator== (const Offset &pos) const;\n      bool operator!= (const Offset &pos) const;\n      Offset operator+ (const Offset &off) const;\n      Offset operator- (const Offset &off) const;\n\n    public: // overload output stream operator\n      // friend std::ostream& operator<<(std::ostream& strm, const Offset& off);\n\n    public:\n      Offset off() { return *this; }\n\n    public:\n      size_t line;\n      size_t column;\n\n  };\n\n  class Position : public Offset {\n\n    public: // c-tor\n      Position(const size_t file); // line(0), column(0)\n      Position(const size_t file, const Offset& offset);\n      Position(const size_t line, const size_t column); // file(-1)\n      Position(const size_t file, const size_t line, const size_t column);\n\n    public: // overload operators for position\n      void operator+= (const Offset &off);\n      bool operator== (const Position &pos) const;\n      bool operator!= (const Position &pos) const;\n      const Position operator+ (const Offset &off) const;\n      const Offset operator- (const Offset &off) const;\n      // return new position, incremented by the given string\n      Position add(const char* begin, const char* end);\n      Position inc(const char* begin, const char* end) const;\n\n    public: // overload output stream operator\n      // friend std::ostream& operator<<(std::ostream& strm, const Position& pos);\n\n    public:\n      size_t file;\n\n  };\n\n  // Token type for representing lexed chunks of text\n  class Token {\n  public:\n    const char* prefix;\n    const char* begin;\n    const char* end;\n\n    Token()\n    : prefix(0), begin(0), end(0) { }\n    Token(const char* b, const char* e)\n    : prefix(b), begin(b), end(e) { }\n    Token(const char* str)\n    : prefix(str), begin(str), end(str + strlen(str)) { }\n    Token(const char* p, const char* b, const char* e)\n    : prefix(p), begin(b), end(e) { }\n\n    size_t length()    const { return end - begin; }\n    sass::string ws_before() const { return sass::string(prefix, begin); }\n    sass::string to_string() const { return sass::string(begin, end); }\n    sass::string time_wspace() const {\n      sass::string str(to_string());\n      sass::string whitespaces(\" \\t\\f\\v\\n\\r\");\n      return str.erase(str.find_last_not_of(whitespaces)+1);\n    }\n\n    operator bool()        { return begin && end && begin >= end; }\n    operator sass::string() { return to_string(); }\n\n    bool operator==(Token t)  { return to_string() == t.to_string(); }\n  };\n\n  class SourceSpan {\n\n    public:\n\n      SourceSpan(const char* path);\n\n      SourceSpan(SourceDataObj source,\n        const Offset& position = Offset(0, 0),\n        const Offset& offset = Offset(0, 0));\n\n      const char* getPath() const {\n        return source->getPath();\n      }\n\n      const char* getRawData() const {\n        return source->getRawData();\n      }\n\n      Offset getPosition() const {\n        return position;\n      }\n\n      size_t getLine() const {\n        return position.line + 1;\n      }\n\n      size_t getColumn() const {\n        return position.column + 1;\n      }\n\n      size_t getSrcId() const {\n        return source == nullptr\n          ? std::string::npos\n          : source->getSrcId();\n      }\n\n      SourceDataObj source;\n      Offset position;\n      Offset offset;\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/prelexer.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <iostream>\n#include <iomanip>\n#include \"util.hpp\"\n#include \"util_string.hpp\"\n#include \"position.hpp\"\n#include \"prelexer.hpp\"\n#include \"constants.hpp\"\n\n\nnamespace Sass {\n  // using namespace Lexer;\n  using namespace Constants;\n\n  namespace Prelexer {\n\n\n    /*\n\n        def string_re(open, close)\n          /#{open}((?:\\\\.|\\#(?!\\{)|[^#{close}\\\\#])*)(#{close}|#\\{)/m\n        end\n      end\n\n      # A hash of regular expressions that are used for tokenizing strings.\n      #\n      # The key is a `[Symbol, Boolean]` pair.\n      # The symbol represents which style of quotation to use,\n      # while the boolean represents whether or not the string\n      # is following an interpolated segment.\n      STRING_REGULAR_EXPRESSIONS = {\n        :double => {\n          /#{open}((?:\\\\.|\\#(?!\\{)|[^#{close}\\\\#])*)(#{close}|#\\{)/m\n          false => string_re('\"', '\"'),\n          true => string_re('', '\"')\n        },\n        :single => {\n          false => string_re(\"'\", \"'\"),\n          true => string_re('', \"'\")\n        },\n        :uri => {\n          false => /url\\(#{W}(#{URLCHAR}*?)(#{W}\\)|#\\{)/,\n          true => /(#{URLCHAR}*?)(#{W}\\)|#\\{)/\n        },\n        # Defined in https://developer.mozilla.org/en/CSS/@-moz-document as a\n        # non-standard version of http://www.w3.org/TR/css3-conditional/\n        :url_prefix => {\n          false => /url-prefix\\(#{W}(#{URLCHAR}*?)(#{W}\\)|#\\{)/,\n          true => /(#{URLCHAR}*?)(#{W}\\)|#\\{)/\n        },\n        :domain => {\n          false => /domain\\(#{W}(#{URLCHAR}*?)(#{W}\\)|#\\{)/,\n          true => /(#{URLCHAR}*?)(#{W}\\)|#\\{)/\n        }\n      }\n    */\n\n    /*\n      /#{open}\n        (\n          \\\\.\n          |\n          \\# (?!\\{)\n          |\n          [^#{close}\\\\#]\n        )*\n        (#{close}|#\\{)\n      /m\n      false => string_re('\"', '\"'),\n      true => string_re('', '\"')\n    */\n    extern const char string_double_negates[] = \"\\\"\\\\#\";\n    const char* re_string_double_close(const char* src)\n    {\n      return sequence <\n        // valid chars\n        zero_plus <\n          alternatives <\n            // escaped char\n            sequence <\n              exactly <'\\\\'>,\n              any_char\n            >,\n            // non interpolate hash\n            sequence <\n              exactly <'#'>,\n              negate <\n                exactly <'{'>\n              >\n            >,\n            // other valid chars\n            neg_class_char <\n              string_double_negates\n            >\n          >\n        >,\n        // quoted string closer\n        // or interpolate opening\n        alternatives <\n          exactly <'\"'>,\n          lookahead < exactly< hash_lbrace > >\n        >\n      >(src);\n    }\n\n    const char* re_string_double_open(const char* src)\n    {\n      return sequence <\n        // quoted string opener\n        exactly <'\"'>,\n        // valid chars\n        zero_plus <\n          alternatives <\n            // escaped char\n            sequence <\n              exactly <'\\\\'>,\n              any_char\n            >,\n            // non interpolate hash\n            sequence <\n              exactly <'#'>,\n              negate <\n                exactly <'{'>\n              >\n            >,\n            // other valid chars\n            neg_class_char <\n              string_double_negates\n            >\n          >\n        >,\n        // quoted string closer\n        // or interpolate opening\n        alternatives <\n          exactly <'\"'>,\n          lookahead < exactly< hash_lbrace > >\n        >\n      >(src);\n    }\n\n    extern const char string_single_negates[] = \"'\\\\#\";\n    const char* re_string_single_close(const char* src)\n    {\n      return sequence <\n        // valid chars\n        zero_plus <\n          alternatives <\n            // escaped char\n            sequence <\n              exactly <'\\\\'>,\n              any_char\n            >,\n            // non interpolate hash\n            sequence <\n              exactly <'#'>,\n              negate <\n                exactly <'{'>\n              >\n            >,\n            // other valid chars\n            neg_class_char <\n              string_single_negates\n            >\n          >\n        >,\n        // quoted string closer\n        // or interpolate opening\n        alternatives <\n          exactly <'\\''>,\n          lookahead < exactly< hash_lbrace > >\n        >\n      >(src);\n    }\n\n    const char* re_string_single_open(const char* src)\n    {\n      return sequence <\n        // quoted string opener\n        exactly <'\\''>,\n        // valid chars\n        zero_plus <\n          alternatives <\n            // escaped char\n            sequence <\n              exactly <'\\\\'>,\n              any_char\n            >,\n            // non interpolate hash\n            sequence <\n              exactly <'#'>,\n              negate <\n                exactly <'{'>\n              >\n            >,\n            // other valid chars\n            neg_class_char <\n              string_single_negates\n            >\n          >\n        >,\n        // quoted string closer\n        // or interpolate opening\n        alternatives <\n          exactly <'\\''>,\n          lookahead < exactly< hash_lbrace > >\n        >\n      >(src);\n    }\n\n    /*\n      :uri => {\n        false => /url\\(#{W}(#{URLCHAR}*?)(#{W}\\)|#\\{)/,\n        true => /(#{URLCHAR}*?)(#{W}\\)|#\\{)/\n      },\n    */\n    const char* re_string_uri_close(const char* src)\n    {\n      return sequence <\n        non_greedy<\n          alternatives<\n            class_char< real_uri_chars >,\n            uri_character,\n            NONASCII,\n            ESCAPE\n          >,\n          alternatives<\n            sequence < optional < W >, exactly <')'> >,\n            lookahead < exactly< hash_lbrace > >\n          >\n        >,\n        optional <\n          sequence < optional < W >, exactly <')'> >\n        >\n      >(src);\n    }\n\n    const char* re_string_uri_open(const char* src)\n    {\n      return sequence <\n        exactly <'u'>,\n        exactly <'r'>,\n        exactly <'l'>,\n        exactly <'('>,\n        W,\n        alternatives<\n          quoted_string,\n          non_greedy<\n            alternatives<\n              class_char< real_uri_chars >,\n              uri_character,\n              NONASCII,\n              ESCAPE\n            >,\n            alternatives<\n              sequence < W, exactly <')'> >,\n              exactly< hash_lbrace >\n            >\n          >\n        >\n      >(src);\n    }\n\n    // Match a line comment (/.*?(?=\\n|\\r\\n?|\\f|\\Z)/.\n    const char* line_comment(const char* src)\n    {\n      return sequence<\n               exactly <\n                 slash_slash\n               >,\n               non_greedy<\n                 any_char,\n                 end_of_line\n               >\n             >(src);\n    }\n\n    // Match a block comment.\n    const char* block_comment(const char* src)\n    {\n      return sequence<\n               delimited_by<\n                 slash_star,\n                 star_slash,\n                 false\n               >\n             >(src);\n    }\n    /* not use anymore - remove?\n    const char* block_comment_prefix(const char* src) {\n      return exactly<slash_star>(src);\n    }\n    // Match either comment.\n    const char* comment(const char* src) {\n      return line_comment(src);\n    }\n    */\n\n    // Match zero plus white-space or line_comments\n    const char* optional_css_whitespace(const char* src) {\n      return zero_plus< alternatives<spaces, line_comment> >(src);\n    }\n    const char* css_whitespace(const char* src) {\n      return one_plus< alternatives<spaces, line_comment> >(src);\n    }\n    // Match optional_css_whitepace plus block_comments\n    const char* optional_css_comments(const char* src) {\n      return zero_plus< alternatives<spaces, line_comment, block_comment> >(src);\n    }\n    const char* css_comments(const char* src) {\n      return one_plus< alternatives<spaces, line_comment, block_comment> >(src);\n    }\n\n    // Match one backslash escaped char /\\\\./\n    const char* escape_seq(const char* src)\n    {\n      return sequence<\n        exactly<'\\\\'>,\n        alternatives <\n          minmax_range<\n            1, 3, xdigit\n          >,\n          any_char\n        >,\n        optional <\n          exactly <' '>\n        >\n      >(src);\n    }\n\n    // Match identifier start\n    const char* identifier_alpha(const char* src)\n    {\n      return alternatives<\n               unicode_seq,\n               alpha,\n               nonascii,\n               exactly<'-'>,\n               exactly<'_'>,\n               NONASCII,\n               ESCAPE,\n               escape_seq\n             >(src);\n    }\n\n    // Match identifier after start\n    const char* identifier_alnum(const char* src)\n    {\n      return alternatives<\n               unicode_seq,\n               alnum,\n               nonascii,\n               exactly<'-'>,\n               exactly<'_'>,\n               NONASCII,\n               ESCAPE,\n               escape_seq\n             >(src);\n    }\n\n    // Match CSS identifiers.\n    const char* strict_identifier(const char* src)\n    {\n      return sequence<\n               one_plus < strict_identifier_alpha >,\n               zero_plus < strict_identifier_alnum >\n               // word_boundary not needed\n             >(src);\n    }\n\n    // Match CSS identifiers.\n    const char* identifier(const char* src)\n    {\n      return sequence<\n               zero_plus< exactly<'-'> >,\n               one_plus < identifier_alpha >,\n               zero_plus < identifier_alnum >\n               // word_boundary not needed\n             >(src);\n    }\n\n    const char* strict_identifier_alpha(const char* src)\n    {\n      return alternatives <\n               alpha,\n               nonascii,\n               escape_seq,\n               exactly<'_'>\n             >(src);\n    }\n\n    const char* strict_identifier_alnum(const char* src)\n    {\n      return alternatives <\n               alnum,\n               nonascii,\n               escape_seq,\n               exactly<'_'>\n             >(src);\n    }\n\n    // Match a single CSS unit\n    const char* one_unit(const char* src)\n    {\n      return sequence <\n               optional < exactly <'-'> >,\n               strict_identifier_alpha,\n               zero_plus < alternatives<\n                 strict_identifier_alnum,\n                 sequence <\n                   one_plus < exactly<'-'> >,\n                   strict_identifier_alpha\n                 >\n               > >\n             >(src);\n    }\n\n    // Match numerator/denominator CSS units\n    const char* multiple_units(const char* src)\n    {\n      return\n        sequence <\n          one_unit,\n          zero_plus <\n            sequence <\n              exactly <'*'>,\n              one_unit\n            >\n          >\n        >(src);\n    }\n\n    // Match complex CSS unit identifiers\n    const char* unit_identifier(const char* src)\n    {\n      return sequence <\n        multiple_units,\n        optional <\n          sequence <\n          exactly <'/'>,\n          negate < sequence <\n            exactly < calc_fn_kwd >,\n            exactly < '(' >\n          > >,\n          multiple_units\n        > >\n      >(src);\n    }\n\n    const char* identifier_alnums(const char* src)\n    {\n      return one_plus< identifier_alnum >(src);\n    }\n\n    // Match number prefix ([\\+\\-]+)\n    const char* number_prefix(const char* src) {\n      return alternatives <\n        exactly < '+' >,\n        sequence <\n          exactly < '-' >,\n          optional_css_whitespace,\n          exactly< '-' >\n        >\n      >(src);\n    }\n\n    // Match interpolant schemas\n    const char* identifier_schema(const char* src) {\n\n      return sequence <\n               one_plus <\n                 sequence <\n                   zero_plus <\n                     alternatives <\n                       sequence <\n                         optional <\n                           exactly <'$'>\n                         >,\n                         identifier\n                       >,\n                       exactly <'-'>\n                     >\n                   >,\n                   interpolant,\n                   zero_plus <\n                     alternatives <\n                       digits,\n                       sequence <\n                         optional <\n                           exactly <'$'>\n                         >,\n                         identifier\n                       >,\n                       quoted_string,\n                       exactly<'-'>\n                     >\n                   >\n                 >\n               >,\n               negate <\n                 exactly<'%'>\n               >\n             > (src);\n    }\n\n    // interpolants can be recursive/nested\n    const char* interpolant(const char* src) {\n      return recursive_scopes< exactly<hash_lbrace>, exactly<rbrace> >(src);\n    }\n\n    // $re_squote = /'(?:$re_itplnt|\\\\.|[^'])*'/\n    const char* single_quoted_string(const char* src) {\n      // match a single quoted string, while skipping interpolants\n      return sequence <\n        exactly <'\\''>,\n        zero_plus <\n          alternatives <\n            // skip escapes\n            sequence <\n              exactly < '\\\\' >,\n              re_linebreak\n            >,\n            escape_seq,\n            unicode_seq,\n            // skip interpolants\n            interpolant,\n            // skip non delimiters\n            any_char_but < '\\'' >\n          >\n        >,\n        exactly <'\\''>\n      >(src);\n    }\n\n    // $re_dquote = /\"(?:$re_itp|\\\\.|[^\"])*\"/\n    const char* double_quoted_string(const char* src) {\n      // match a single quoted string, while skipping interpolants\n      return sequence <\n        exactly <'\"'>,\n        zero_plus <\n          alternatives <\n            // skip escapes\n            sequence <\n              exactly < '\\\\' >,\n              re_linebreak\n            >,\n            escape_seq,\n            unicode_seq,\n            // skip interpolants\n            interpolant,\n            // skip non delimiters\n            any_char_but < '\"' >\n          >\n        >,\n        exactly <'\"'>\n      >(src);\n    }\n\n    // $re_quoted = /(?:$re_squote|$re_dquote)/\n    const char* quoted_string(const char* src) {\n      // match a quoted string, while skipping interpolants\n      return alternatives<\n        single_quoted_string,\n        double_quoted_string\n      >(src);\n    }\n\n    const char* sass_value(const char* src) {\n      return alternatives <\n        quoted_string,\n        identifier,\n        percentage,\n        hex,\n        dimension,\n        number\n      >(src);\n    }\n\n    // this is basically `one_plus < sass_value >`\n    // takes care to not parse invalid combinations\n    const char* value_combinations(const char* src) {\n      // `2px-2px` is invalid combo\n      bool was_number = false;\n      const char* pos;\n      while (src) {\n        if ((pos = alternatives < quoted_string, identifier, percentage, hex >(src))) {\n          was_number = false;\n          src = pos;\n        } else if (!was_number && !exactly<'+'>(src) && (pos = alternatives < dimension, number >(src))) {\n          was_number = true;\n          src = pos;\n        } else {\n          break;\n        }\n      }\n      return src;\n    }\n\n    // must be at least one interpolant\n    // can be surrounded by sass values\n    // make sure to never parse (dim)(dim)\n    // since this wrongly consumes `2px-1px`\n    // `2px1px` is valid number (unit `px1px`)\n    const char* value_schema(const char* src)\n    {\n      return sequence <\n        one_plus <\n          sequence <\n            optional < value_combinations >,\n            interpolant,\n            optional < value_combinations >\n          >\n        >\n      >(src);\n    }\n\n    // Match CSS '@' keywords.\n    const char* at_keyword(const char* src) {\n      return sequence<exactly<'@'>, identifier>(src);\n    }\n\n    /*\n        tok(%r{\n          (\n            \\\\.\n          |\n            (?!url\\()\n            [^\"'/\\#!;\\{\\}] # \"\n          |\n            /(?![\\*\\/])\n          |\n            \\#(?!\\{)\n          |\n            !(?![a-z]) # TODO: never consume \"!\" when issue 1126 is fixed.\n          )+\n        }xi) || tok(COMMENT) || tok(SINGLE_LINE_COMMENT) || interp_string || interp_uri ||\n                interpolation(:warn_for_color)\n    */\n    const char* re_almost_any_value_token(const char* src) {\n\n      return alternatives <\n        one_plus <\n          alternatives <\n            sequence <\n              exactly <'\\\\'>,\n              any_char\n            >,\n            sequence <\n              negate <\n                uri_prefix\n              >,\n              neg_class_char <\n                almost_any_value_class\n              >\n            >,\n            sequence <\n              exactly <'/'>,\n              negate <\n                alternatives <\n                  exactly <'/'>,\n                  exactly <'*'>\n                >\n              >\n            >,\n            sequence <\n              exactly <'\\\\'>,\n              exactly <'#'>,\n              negate <\n                exactly <'{'>\n              >\n            >,\n            sequence <\n              exactly <'!'>,\n              negate <\n                alpha\n              >\n            >\n          >\n        >,\n        block_comment,\n        line_comment,\n        interpolant,\n        space,\n        sequence <\n          exactly<'u'>,\n          exactly<'r'>,\n          exactly<'l'>,\n          exactly<'('>,\n          zero_plus <\n            alternatives <\n              class_char< real_uri_chars >,\n              uri_character,\n              NONASCII,\n              ESCAPE\n            >\n          >,\n          // false => /url\\(#{W}(#{URLCHAR}*?)(#{W}\\)|#\\{)/,\n          // true => /(#{URLCHAR}*?)(#{W}\\)|#\\{)/\n          exactly<')'>\n        >\n      >(src);\n    }\n\n    /*\n      DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for,\n        :each, :while, :if, :else, :extend, :import, :media, :charset, :content,\n        :_moz_document, :at_root, :error]\n    */\n    const char* re_special_directive(const char* src) {\n      return alternatives <\n        word < mixin_kwd >,\n        word < include_kwd >,\n        word < function_kwd >,\n        word < return_kwd >,\n        word < debug_kwd >,\n        word < warn_kwd >,\n        word < for_kwd >,\n        word < each_kwd >,\n        word < while_kwd >,\n        word < if_kwd >,\n        word < else_kwd >,\n        word < extend_kwd >,\n        word < import_kwd >,\n        word < media_kwd >,\n        word < charset_kwd >,\n        word < content_kwd >,\n        // exactly < moz_document_kwd >,\n        word < at_root_kwd >,\n        word < error_kwd >\n      >(src);\n    }\n\n    const char* re_prefixed_directive(const char* src) {\n      return sequence <\n        optional <\n          sequence <\n            exactly <'-'>,\n            one_plus < alnum >,\n            exactly <'-'>\n          >\n        >,\n        exactly < supports_kwd >\n      >(src);\n    }\n\n    const char* re_reference_combinator(const char* src) {\n      return sequence <\n        optional <\n          sequence <\n            zero_plus <\n              exactly <'-'>\n            >,\n            identifier,\n            exactly <'|'>\n          >\n        >,\n        zero_plus <\n          exactly <'-'>\n        >,\n        identifier\n      >(src);\n    }\n\n    const char* static_reference_combinator(const char* src) {\n      return sequence <\n        exactly <'/'>,\n        re_reference_combinator,\n        exactly <'/'>\n      >(src);\n    }\n\n    const char* schema_reference_combinator(const char* src) {\n      return sequence <\n        exactly <'/'>,\n        optional <\n          sequence <\n            css_ip_identifier,\n            exactly <'|'>\n          >\n        >,\n        css_ip_identifier,\n        exactly <'/'>\n      > (src);\n    }\n\n    const char* kwd_import(const char* src) {\n      return word<import_kwd>(src);\n    }\n\n    const char* kwd_at_root(const char* src) {\n      return word<at_root_kwd>(src);\n    }\n\n    const char* kwd_with_directive(const char* src) {\n      return word<with_kwd>(src);\n    }\n\n    const char* kwd_without_directive(const char* src) {\n      return word<without_kwd>(src);\n    }\n\n    const char* kwd_media(const char* src) {\n      return word<media_kwd>(src);\n    }\n\n    const char* kwd_supports_directive(const char* src) {\n      return word<supports_kwd>(src);\n    }\n\n    const char* kwd_mixin(const char* src) {\n      return word<mixin_kwd>(src);\n    }\n\n    const char* kwd_function(const char* src) {\n      return word<function_kwd>(src);\n    }\n\n    const char* kwd_return_directive(const char* src) {\n      return word<return_kwd>(src);\n    }\n\n    const char* kwd_include_directive(const char* src) {\n      return word<include_kwd>(src);\n    }\n\n    const char* kwd_content_directive(const char* src) {\n      return word<content_kwd>(src);\n    }\n\n    const char* kwd_charset_directive(const char* src) {\n      return word<charset_kwd>(src);\n    }\n\n    const char* kwd_extend(const char* src) {\n      return word<extend_kwd>(src);\n    }\n\n\n    const char* kwd_if_directive(const char* src) {\n      return word<if_kwd>(src);\n    }\n\n    const char* kwd_else_directive(const char* src) {\n      return word<else_kwd>(src);\n    }\n    const char* elseif_directive(const char* src) {\n      return sequence< exactly< else_kwd >,\n                                optional_css_comments,\n                                word< if_after_else_kwd > >(src);\n    }\n\n    const char* kwd_for_directive(const char* src) {\n      return word<for_kwd>(src);\n    }\n\n    const char* kwd_from(const char* src) {\n      return word<from_kwd>(src);\n    }\n\n    const char* kwd_to(const char* src) {\n      return word<to_kwd>(src);\n    }\n\n    const char* kwd_through(const char* src) {\n      return word<through_kwd>(src);\n    }\n\n    const char* kwd_each_directive(const char* src) {\n      return word<each_kwd>(src);\n    }\n\n    const char* kwd_in(const char* src) {\n      return word<in_kwd>(src);\n    }\n\n    const char* kwd_while_directive(const char* src) {\n      return word<while_kwd>(src);\n    }\n\n    const char* name(const char* src) {\n      return one_plus< alternatives< alnum,\n                                     exactly<'-'>,\n                                     exactly<'_'>,\n                                     escape_seq > >(src);\n    }\n\n    const char* kwd_warn(const char* src) {\n      return word<warn_kwd>(src);\n    }\n\n    const char* kwd_err(const char* src) {\n      return word<error_kwd>(src);\n    }\n\n    const char* kwd_dbg(const char* src) {\n      return word<debug_kwd>(src);\n    }\n\n    /* not used anymore - remove?\n    const char* directive(const char* src) {\n      return sequence< exactly<'@'>, identifier >(src);\n    } */\n\n    const char* kwd_null(const char* src) {\n      return word<null_kwd>(src);\n    }\n\n    const char* css_identifier(const char* src) {\n      return sequence <\n               zero_plus <\n                 exactly <'-'>\n               >,\n               identifier\n             >(src);\n    }\n\n    const char* css_ip_identifier(const char* src) {\n      return sequence <\n               zero_plus <\n                 exactly <'-'>\n               >,\n               alternatives <\n                 identifier,\n                 interpolant\n               >\n             >(src);\n    }\n\n    // Match CSS type selectors\n    const char* namespace_prefix(const char* src) {\n      return sequence <\n               optional <\n                 alternatives <\n                   exactly <'*'>,\n                   css_identifier\n                 >\n               >,\n               exactly <'|'>,\n               negate <\n                 exactly <'='>\n               >\n             >(src);\n    }\n\n    // Match CSS type selectors\n    const char* namespace_schema(const char* src) {\n      return sequence <\n               optional <\n                 alternatives <\n                   exactly <'*'>,\n                   css_ip_identifier\n                 >\n               >,\n               exactly<'|'>,\n               negate <\n                 exactly <'='>\n               >\n             >(src);\n    }\n\n    const char* hyphens_and_identifier(const char* src) {\n      return sequence< zero_plus< exactly< '-' > >, identifier_alnums >(src);\n    }\n    const char* hyphens_and_name(const char* src) {\n      return sequence< zero_plus< exactly< '-' > >, name >(src);\n    }\n    const char* universal(const char* src) {\n      return sequence< optional<namespace_schema>, exactly<'*'> >(src);\n    }\n    // Match CSS id names.\n    const char* id_name(const char* src) {\n      return sequence<exactly<'#'>, identifier_alnums >(src);\n    }\n    // Match CSS class names.\n    const char* class_name(const char* src) {\n      return sequence<exactly<'.'>, identifier >(src);\n    }\n    // Attribute name in an attribute selector.\n    const char* attribute_name(const char* src) {\n      return alternatives< sequence< optional<namespace_schema>, identifier>,\n                           identifier >(src);\n    }\n    // match placeholder selectors\n    const char* placeholder(const char* src) {\n      return sequence<exactly<'%'>, identifier_alnums >(src);\n    }\n    // Match CSS numeric constants.\n\n    const char* op(const char* src) {\n      return class_char<op_chars>(src);\n    }\n    const char* sign(const char* src) {\n      return class_char<sign_chars>(src);\n    }\n    const char* unsigned_number(const char* src) {\n      return alternatives<sequence< zero_plus<digits>,\n                                    exactly<'.'>,\n                                    one_plus<digits> >,\n                          digits>(src);\n    }\n    const char* number(const char* src) {\n      return sequence<\n          optional<sign>,\n          unsigned_number,\n          optional<\n            sequence<\n              exactly<'e'>,\n              optional<sign>,\n              unsigned_number\n            >\n          >\n        >(src);\n    }\n    const char* coefficient(const char* src) {\n      return alternatives< sequence< optional<sign>, digits >,\n                           sign >(src);\n    }\n    const char* binomial(const char* src) {\n      return sequence <\n               optional < sign >,\n               optional < digits >,\n               exactly <'n'>,\n               zero_plus < sequence <\n                 optional_css_whitespace, sign,\n                 optional_css_whitespace, digits\n               > >\n             >(src);\n    }\n    const char* percentage(const char* src) {\n      return sequence< number, exactly<'%'> >(src);\n    }\n    const char* ampersand(const char* src) {\n      return exactly<'&'>(src);\n    }\n\n    /* not used anymore - remove?\n    const char* em(const char* src) {\n      return sequence< number, exactly<em_kwd> >(src);\n    } */\n    const char* dimension(const char* src) {\n      return sequence<number, unit_identifier >(src);\n    }\n    const char* hex(const char* src) {\n      const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);\n      ptrdiff_t len = p - src;\n      return (len != 4 && len != 7) ? 0 : p;\n    }\n    const char* hexa(const char* src) {\n      const char* p = sequence< exactly<'#'>, one_plus<xdigit> >(src);\n      ptrdiff_t len = p - src;\n      return (len != 5 && len != 9) ? 0 : p;\n    }\n    const char* hex0(const char* src) {\n      const char* p = sequence< exactly<'0'>, exactly<'x'>, one_plus<xdigit> >(src);\n      ptrdiff_t len = p - src;\n      return (len != 5 && len != 8) ? 0 : p;\n    }\n\n    /* no longer used - remove?\n    const char* rgb_prefix(const char* src) {\n      return word<rgb_fn_kwd>(src);\n    }*/\n    // Match CSS uri specifiers.\n\n    const char* uri_prefix(const char* src) {\n      return sequence <\n        exactly <\n          url_kwd\n        >,\n        zero_plus <\n          sequence <\n            exactly <'-'>,\n            one_plus <\n              alpha\n            >\n          >\n        >,\n        exactly <'('>\n      >(src);\n    }\n\n    // TODO: rename the following two functions\n    /* no longer used - remove?\n    const char* uri(const char* src) {\n      return sequence< exactly<url_kwd>,\n                       optional<spaces>,\n                       quoted_string,\n                       optional<spaces>,\n                       exactly<')'> >(src);\n    }*/\n    /* no longer used - remove?\n    const char* url_value(const char* src) {\n      return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol\n                       one_plus< sequence< zero_plus< exactly<'/'> >, filename > >, // one or more folders and/or trailing filename\n                       optional< exactly<'/'> > >(src);\n    }*/\n    /* no longer used - remove?\n    const char* url_schema(const char* src) {\n      return sequence< optional< sequence< identifier, exactly<':'> > >, // optional protocol\n                       filename_schema >(src); // optional trailing slash\n    }*/\n    // Match CSS \"!important\" keyword.\n    const char* kwd_important(const char* src) {\n      return sequence< exactly<'!'>,\n                       optional_css_whitespace,\n                       word<important_kwd> >(src);\n    }\n    // Match CSS \"!optional\" keyword.\n    const char* kwd_optional(const char* src) {\n      return sequence< exactly<'!'>,\n      optional_css_whitespace,\n      word<optional_kwd> >(src);\n    }\n    // Match Sass \"!default\" keyword.\n    const char* default_flag(const char* src) {\n      return sequence< exactly<'!'>,\n                       optional_css_whitespace,\n                       word<default_kwd> >(src);\n    }\n    // Match Sass \"!global\" keyword.\n    const char* global_flag(const char* src) {\n      return sequence< exactly<'!'>,\n                       optional_css_whitespace,\n                       word<global_kwd> >(src);\n    }\n    // Match CSS pseudo-class/element prefixes.\n    const char* pseudo_prefix(const char* src) {\n      return sequence< exactly<':'>, optional< exactly<':'> > >(src);\n    }\n    // Match CSS function call openers.\n    const char* functional_schema(const char* src) {\n      return sequence <\n               one_plus <\n                 sequence <\n                   zero_plus <\n                     alternatives <\n                       identifier,\n                       exactly <'-'>\n                     >\n                   >,\n                   one_plus <\n                     sequence <\n                       interpolant,\n                       alternatives <\n                         digits,\n                         identifier,\n                         exactly<'+'>,\n                         exactly<'-'>\n                       >\n                     >\n                   >\n                 >\n               >,\n               negate <\n                 exactly <'%'>\n               >,\n               lookahead <\n                 exactly <'('>\n               >\n             > (src);\n    }\n\n    const char* re_nothing(const char* src) {\n      return src;\n    }\n\n    const char* re_functional(const char* src) {\n      return sequence< identifier, optional < block_comment >, exactly<'('> >(src);\n    }\n    const char* re_pseudo_selector(const char* src) {\n      return sequence< identifier, optional < block_comment >, exactly<'('> >(src);\n    }\n    // Match the CSS negation pseudo-class.\n    const char* pseudo_not(const char* src) {\n      return word< pseudo_not_fn_kwd >(src);\n    }\n    // Match CSS 'odd' and 'even' keywords for functional pseudo-classes.\n    const char* even(const char* src) {\n      return word<even_kwd>(src);\n    }\n    const char* odd(const char* src) {\n      return word<odd_kwd>(src);\n    }\n    // Match CSS attribute-matching operators.\n    const char* exact_match(const char* src) { return exactly<'='>(src); }\n    const char* class_match(const char* src) { return exactly<tilde_equal>(src); }\n    const char* dash_match(const char* src) { return exactly<pipe_equal>(src); }\n    const char* prefix_match(const char* src) { return exactly<caret_equal>(src); }\n    const char* suffix_match(const char* src) { return exactly<dollar_equal>(src); }\n    const char* substring_match(const char* src) { return exactly<star_equal>(src); }\n    // Match CSS combinators.\n    /* not used anymore - remove?\n    const char* adjacent_to(const char* src) {\n      return sequence< optional_spaces, exactly<'+'> >(src);\n    }\n    const char* precedes(const char* src) {\n      return sequence< optional_spaces, exactly<'~'> >(src);\n    }\n    const char* parent_of(const char* src) {\n      return sequence< optional_spaces, exactly<'>'> >(src);\n    }\n    const char* ancestor_of(const char* src) {\n      return sequence< spaces, negate< exactly<'{'> > >(src);\n    }*/\n\n    // Match SCSS variable names.\n    const char* variable(const char* src) {\n      return sequence<exactly<'$'>, identifier>(src);\n    }\n\n    // parse `calc`, `-a-calc` and `--b-c-calc`\n    // but do not parse `foocalc` or `foo-calc`\n    const char* calc_fn_call(const char* src) {\n      return sequence <\n        optional < sequence <\n          hyphens,\n          one_plus < sequence <\n            strict_identifier,\n            hyphens\n          > >\n        > >,\n        exactly < calc_fn_kwd >,\n        word_boundary\n      >(src);\n    }\n\n    // Match Sass boolean keywords.\n    const char* kwd_true(const char* src) {\n      return word<true_kwd>(src);\n    }\n    const char* kwd_false(const char* src) {\n      return word<false_kwd>(src);\n    }\n    const char* kwd_only(const char* src) {\n      return keyword < only_kwd >(src);\n    }\n    const char* kwd_and(const char* src) {\n      return keyword < and_kwd >(src);\n    }\n    const char* kwd_or(const char* src) {\n      return keyword < or_kwd >(src);\n    }\n    const char* kwd_not(const char* src) {\n      return keyword < not_kwd >(src);\n    }\n    const char* kwd_eq(const char* src) {\n      return exactly<eq>(src);\n    }\n    const char* kwd_neq(const char* src) {\n      return exactly<neq>(src);\n    }\n    const char* kwd_gt(const char* src) {\n      return exactly<gt>(src);\n    }\n    const char* kwd_gte(const char* src) {\n      return exactly<gte>(src);\n    }\n    const char* kwd_lt(const char* src) {\n      return exactly<lt>(src);\n    }\n    const char* kwd_lte(const char* src) {\n      return exactly<lte>(src);\n    }\n    const char* kwd_using(const char* src) {\n      return keyword<using_kwd>(src);\n    }\n\n    // match specific IE syntax\n    const char* ie_progid(const char* src) {\n      return sequence <\n        word<progid_kwd>,\n        exactly<':'>,\n        alternatives< identifier_schema, identifier >,\n        zero_plus< sequence<\n          exactly<'.'>,\n          alternatives< identifier_schema, identifier >\n        > >,\n        zero_plus < sequence<\n          exactly<'('>,\n          optional_css_whitespace,\n          optional < sequence<\n            alternatives< variable, identifier_schema, identifier >,\n            optional_css_whitespace,\n            exactly<'='>,\n            optional_css_whitespace,\n            alternatives< variable, identifier_schema, identifier, quoted_string, number, hex, hexa >,\n            zero_plus< sequence<\n              optional_css_whitespace,\n              exactly<','>,\n              optional_css_whitespace,\n              sequence<\n                alternatives< variable, identifier_schema, identifier >,\n                optional_css_whitespace,\n                exactly<'='>,\n                optional_css_whitespace,\n                alternatives< variable, identifier_schema, identifier, quoted_string, number, hex, hexa >\n              >\n            > >\n          > >,\n          optional_css_whitespace,\n          exactly<')'>\n        > >\n      >(src);\n    }\n    const char* ie_expression(const char* src) {\n      return sequence < word<expression_kwd>, exactly<'('>, skip_over_scopes< exactly<'('>, exactly<')'> > >(src);\n    }\n    const char* ie_property(const char* src) {\n      return alternatives < ie_expression, ie_progid >(src);\n    }\n\n    // const char* ie_args(const char* src) {\n    //   return sequence< alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by< '(', ')', true> >,\n    //                    zero_plus< sequence< optional_css_whitespace, exactly<','>, optional_css_whitespace, alternatives< ie_keyword_arg, value_schema, quoted_string, interpolant, number, identifier, delimited_by<'(', ')', true> > > > >(src);\n    // }\n\n    const char* ie_keyword_arg_property(const char* src) {\n      return alternatives <\n          variable,\n          identifier_schema,\n          identifier\n        >(src);\n    }\n    const char* ie_keyword_arg_value(const char* src) {\n      return alternatives <\n          variable,\n          identifier_schema,\n          identifier,\n          quoted_string,\n          number,\n          hex,\n          hexa,\n          sequence <\n            exactly < '(' >,\n            skip_over_scopes <\n              exactly < '(' >,\n              exactly < ')' >\n            >\n          >\n        >(src);\n    }\n\n    const char* ie_keyword_arg(const char* src) {\n      return sequence <\n        ie_keyword_arg_property,\n        optional_css_whitespace,\n        exactly<'='>,\n        optional_css_whitespace,\n        ie_keyword_arg_value\n      >(src);\n    }\n\n    // Path matching functions.\n    /* not used anymore - remove?\n    const char* folder(const char* src) {\n      return sequence< zero_plus< any_char_except<'/'> >,\n                       exactly<'/'> >(src);\n    }\n    const char* folders(const char* src) {\n      return zero_plus< folder >(src);\n    }*/\n    /* not used anymore - remove?\n    const char* chunk(const char* src) {\n      char inside_str = 0;\n      const char* p = src;\n      size_t depth = 0;\n      while (true) {\n        if (!*p) {\n          return 0;\n        }\n        else if (!inside_str && (*p == '\"' || *p == '\\'')) {\n          inside_str = *p;\n        }\n        else if (*p == inside_str && *(p-1) != '\\\\') {\n          inside_str = 0;\n        }\n        else if (*p == '(' && !inside_str) {\n          ++depth;\n        }\n        else if (*p == ')' && !inside_str) {\n          if (depth == 0) return p;\n          else            --depth;\n        }\n        ++p;\n      }\n      // unreachable\n      return 0;\n    }\n    */\n\n    // follow the CSS spec more closely and see if this helps us scan URLs correctly\n    /* not used anymore - remove?\n    const char* NL(const char* src) {\n      return alternatives< exactly<'\\n'>,\n                           sequence< exactly<'\\r'>, exactly<'\\n'> >,\n                           exactly<'\\r'>,\n                           exactly<'\\f'> >(src);\n    }*/\n\n    const char* H(const char* src) {\n      return Util::ascii_isxdigit(static_cast<unsigned char>(*src)) ? src+1 : 0;\n    }\n\n    const char* W(const char* src) {\n      return zero_plus< alternatives<\n        space,\n        exactly< '\\t' >,\n        exactly< '\\r' >,\n        exactly< '\\n' >,\n        exactly< '\\f' >\n      > >(src);\n    }\n\n    const char* UUNICODE(const char* src) {\n      return sequence< exactly<'\\\\'>,\n                       between<H, 1, 6>,\n                       optional< W >\n                       >(src);\n    }\n\n    const char* NONASCII(const char* src) {\n      return nonascii(src);\n    }\n\n    const char* ESCAPE(const char* src) {\n      return alternatives<\n        UUNICODE,\n        sequence<\n          exactly<'\\\\'>,\n          alternatives<\n            NONASCII,\n            escapable_character\n          >\n        >\n      >(src);\n    }\n\n    const char* list_terminator(const char* src) {\n      return alternatives <\n        exactly<';'>,\n        exactly<'}'>,\n        exactly<'{'>,\n        exactly<')'>,\n        exactly<']'>,\n        exactly<':'>,\n        end_of_file,\n        exactly<ellipsis>,\n        default_flag,\n        global_flag\n      >(src);\n    };\n\n    const char* space_list_terminator(const char* src) {\n      return alternatives <\n        exactly<','>,\n        list_terminator\n      >(src);\n    };\n\n\n    // const char* real_uri_prefix(const char* src) {\n    //   return alternatives<\n    //     exactly< url_kwd >,\n    //     exactly< url_prefix_kwd >\n    //   >(src);\n    // }\n\n    const char* real_uri(const char* src) {\n      return sequence<\n        exactly< url_kwd >,\n        exactly< '(' >,\n        W,\n        real_uri_value,\n        exactly< ')' >\n      >(src);\n    }\n\n    const char* real_uri_suffix(const char* src) {\n      return sequence< W, exactly< ')' > >(src);\n    }\n\n    const char* real_uri_value(const char* src) {\n      return\n      sequence<\n        non_greedy<\n          alternatives<\n            class_char< real_uri_chars >,\n            uri_character,\n            NONASCII,\n            ESCAPE\n          >,\n          alternatives<\n            real_uri_suffix,\n            exactly< hash_lbrace >\n          >\n        >\n      >\n      (src);\n    }\n\n    const char* static_string(const char* src) {\n      const char* pos = src;\n      const char * s = quoted_string(pos);\n      Token t(pos, s);\n      const unsigned int p = count_interval< interpolant >(t.begin, t.end);\n      return (p == 0) ? t.end : 0;\n    }\n\n    const char* unicode_seq(const char* src) {\n      return sequence <\n        alternatives <\n          exactly< 'U' >,\n          exactly< 'u' >\n        >,\n        exactly< '+' >,\n        padded_token <\n          6, xdigit,\n          exactly < '?' >\n        >\n      >(src);\n    }\n\n    const char* static_component(const char* src) {\n      return alternatives< identifier,\n                           static_string,\n                           percentage,\n                           hex,\n                           hexa,\n                           exactly<'|'>,\n                           // exactly<'+'>,\n                           sequence < number, unit_identifier >,\n                           number,\n                           sequence< exactly<'!'>, word<important_kwd> >\n                          >(src);\n    }\n\n    const char* static_property(const char* src) {\n      return\n        sequence <\n          zero_plus<\n            sequence <\n              optional_css_comments,\n              alternatives <\n                exactly<','>,\n                exactly<'('>,\n                exactly<')'>,\n                kwd_optional,\n                quoted_string,\n                interpolant,\n                identifier,\n                percentage,\n                dimension,\n                variable,\n                alnum,\n                sequence <\n                  exactly <'\\\\'>,\n                  any_char\n                >\n              >\n            >\n          >,\n          lookahead <\n            sequence <\n              optional_css_comments,\n              alternatives <\n                exactly <';'>,\n                exactly <'}'>,\n                end_of_file\n              >\n            >\n          >\n        >(src);\n    }\n\n    const char* static_value(const char* src) {\n      return sequence< sequence<\n                         static_component,\n                         zero_plus< identifier >\n                       >,\n                       zero_plus < sequence<\n                                     alternatives<\n                                       sequence< optional_spaces, alternatives<\n                                         exactly < '/' >,\n                                         exactly < ',' >,\n                                         exactly < ' ' >\n                                       >, optional_spaces >,\n                                       spaces\n                                     >,\n                                     static_component\n                       > >,\n                       zero_plus < spaces >,\n                       alternatives< exactly<';'>, exactly<'}'> >\n                      >(src);\n    }\n\n    extern const char css_variable_url_negates[] = \"()[]{}\\\"'#/\";\n    const char* css_variable_value(const char* src) {\n      return sequence<\n        alternatives<\n          sequence<\n            negate< exactly< url_fn_kwd > >,\n            one_plus< neg_class_char< css_variable_url_negates > >\n          >,\n          sequence< exactly<'#'>, negate< exactly<'{'> > >,\n          sequence< exactly<'/'>, negate< exactly<'*'> > >,\n          static_string,\n          real_uri,\n          block_comment\n        >\n      >(src);\n    }\n\n    extern const char css_variable_url_top_level_negates[] = \"()[]{}\\\"'#/;\";\n    const char* css_variable_top_level_value(const char* src) {\n      return sequence<\n        alternatives<\n          sequence<\n            negate< exactly< url_fn_kwd > >,\n            one_plus< neg_class_char< css_variable_url_top_level_negates > >\n          >,\n          sequence< exactly<'#'>, negate< exactly<'{'> > >,\n          sequence< exactly<'/'>, negate< exactly<'*'> > >,\n          static_string,\n          real_uri,\n          block_comment\n        >\n      >(src);\n    }\n\n    const char* parenthese_scope(const char* src) {\n      return sequence <\n        exactly < '(' >,\n        skip_over_scopes <\n          exactly < '(' >,\n          exactly < ')' >\n        >\n      >(src);\n    }\n\n    const char* re_selector_list(const char* src) {\n      return alternatives <\n        // partial bem selector\n        sequence <\n          ampersand,\n          one_plus <\n            exactly < '-' >\n          >,\n          word_boundary,\n          optional_spaces\n        >,\n        // main selector matching\n        one_plus <\n          alternatives <\n            // consume whitespace and comments\n            spaces, block_comment, line_comment,\n            // match `/deep/` selector (pass-trough)\n            // there is no functionality for it yet\n            schema_reference_combinator,\n            // match selector ops /[*&%,\\[\\]]/\n            class_char < selector_lookahead_ops >,\n            // match selector combinators /[>+~]/\n            class_char < selector_combinator_ops >,\n            // match pseudo selectors\n            sequence <\n              exactly <'('>,\n              optional_spaces,\n              optional <re_selector_list>,\n              optional_spaces,\n              exactly <')'>\n            >,\n            // match attribute compare operators\n            alternatives <\n              exact_match, class_match, dash_match,\n              prefix_match, suffix_match, substring_match\n            >,\n            // main selector match\n            sequence <\n              // allow namespace prefix\n              optional < namespace_schema >,\n              // modifiers prefixes\n              alternatives <\n                sequence <\n                  exactly <'#'>,\n                  // not for interpolation\n                  negate < exactly <'{'> >\n                >,\n                // class match\n                exactly <'.'>,\n                // single or double colon\n                sequence <\n                  optional < pseudo_prefix >,\n                  // fix libsass issue 2376\n                  negate < uri_prefix >\n                >\n              >,\n              // accept hypens in token\n              one_plus < sequence <\n                // can start with hyphens\n                zero_plus <\n                  sequence <\n                    exactly <'-'>,\n                    optional_spaces\n                  >\n                >,\n                // now the main token\n                alternatives <\n                  kwd_optional,\n                  exactly <'*'>,\n                  quoted_string,\n                  interpolant,\n                  identifier,\n                  variable,\n                  percentage,\n                  binomial,\n                  dimension,\n                  alnum\n                >\n              > >,\n              // can also end with hyphens\n              zero_plus < exactly<'-'> >\n            >\n          >\n        >\n      >(src);\n    }\n\n    const char* type_selector(const char* src) {\n      return sequence< optional<namespace_schema>, identifier>(src);\n    }\n    const char* re_type_selector(const char* src) {\n      return alternatives< type_selector, universal, dimension, percentage, number, identifier_alnums >(src);\n    }\n    const char* re_static_expression(const char* src) {\n      return sequence< number, optional_spaces, exactly<'/'>, optional_spaces, number >(src);\n    }\n\n    // lexer special_fn: these functions cannot be overloaded\n    // (/((-[\\w-]+-)?(calc|element)|expression|progid:[a-z\\.]*)\\(/i)\n    const char* re_special_fun(const char* src) {\n\n      // match this first as we test prefix hyphens\n      if (const char* calc = calc_fn_call(src)) {\n        return calc;\n      }\n\n      return sequence <\n        optional <\n          sequence <\n            exactly <'-'>,\n            one_plus <\n              alternatives <\n                alpha,\n                exactly <'+'>,\n                exactly <'-'>\n              >\n            >\n          >\n        >,\n        alternatives <\n          word < expression_kwd >,\n          sequence <\n            sequence <\n              exactly < progid_kwd >,\n              exactly <':'>\n            >,\n            zero_plus <\n              alternatives <\n                char_range <'a', 'z'>,\n                exactly <'.'>\n              >\n            >\n          >\n        >\n      >(src);\n    }\n\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/prelexer.hpp",
    "content": "#ifndef SASS_PRELEXER_H\n#define SASS_PRELEXER_H\n\n#include <cstring>\n#include \"lexer.hpp\"\n\nnamespace Sass {\n  // using namespace Lexer;\n  namespace Prelexer {\n\n    //####################################\n    // KEYWORD \"REGEX\" MATCHERS\n    //####################################\n\n    // Match Sass boolean keywords.\n    const char* kwd_true(const char* src);\n    const char* kwd_false(const char* src);\n    const char* kwd_only(const char* src);\n    const char* kwd_and(const char* src);\n    const char* kwd_or(const char* src);\n    const char* kwd_not(const char* src);\n    const char* kwd_eq(const char* src);\n    const char* kwd_neq(const char* src);\n    const char* kwd_gt(const char* src);\n    const char* kwd_gte(const char* src);\n    const char* kwd_lt(const char* src);\n    const char* kwd_lte(const char* src);\n    const char* kwd_using(const char* src);\n\n    // Match standard control chars\n    const char* kwd_at(const char* src);\n    const char* kwd_dot(const char* src);\n    const char* kwd_comma(const char* src);\n    const char* kwd_colon(const char* src);\n    const char* kwd_slash(const char* src);\n    const char* kwd_star(const char* src);\n    const char* kwd_plus(const char* src);\n    const char* kwd_minus(const char* src);\n\n    //####################################\n    // SPECIAL \"REGEX\" CONSTRUCTS\n    //####################################\n\n    // Match a sequence of characters delimited by the supplied chars.\n    template <char beg, char end, bool esc>\n    const char* delimited_by(const char* src) {\n      src = exactly<beg>(src);\n      if (!src) return 0;\n      const char* stop;\n      while (true) {\n        if (!*src) return 0;\n        stop = exactly<end>(src);\n        if (stop && (!esc || *(src - 1) != '\\\\')) return stop;\n        src = stop ? stop : src + 1;\n      }\n    }\n\n    // skip to delimiter (mx) inside given range\n    // this will savely skip over all quoted strings\n    // recursive skip stuff delimited by start/stop\n    // first start/opener must be consumed already!\n    template<prelexer start, prelexer stop>\n    const char* skip_over_scopes(const char* src, const char* end) {\n\n      size_t level = 0;\n      bool in_squote = false;\n      bool in_dquote = false;\n      bool in_backslash_escape = false;\n\n      while ((end == nullptr || src < end) && *src != '\\0') {\n        // has escaped sequence?\n        if (in_backslash_escape) {\n          in_backslash_escape = false;\n        }\n        else if (*src == '\\\\') {\n          in_backslash_escape = true;\n        }\n        else if (*src == '\"') {\n          in_dquote = ! in_dquote;\n        }\n        else if (*src == '\\'') {\n          in_squote = ! in_squote;\n        }\n        else if (in_dquote || in_squote) {\n          // take everything literally\n        }\n\n        // find another opener inside?\n        else if (const char* pos = start(src)) {\n          ++ level; // increase counter\n          src = pos - 1; // advance position\n        }\n\n        // look for the closer (maybe final, maybe not)\n        else if (const char* final = stop(src)) {\n          // only close one level?\n          if (level > 0) -- level;\n          // return position at end of stop\n          // delimiter may be multiple chars\n          else return final;\n          // advance position\n          src = final - 1;\n        }\n\n        // next\n        ++ src;\n      }\n\n      return 0;\n    }\n\n    // skip to a skip delimited by parentheses\n    // uses smart `skip_over_scopes` internally\n    const char* parenthese_scope(const char* src);\n\n    // skip to delimiter (mx) inside given range\n    // this will savely skip over all quoted strings\n    // recursive skip stuff delimited by start/stop\n    // first start/opener must be consumed already!\n    template<prelexer start, prelexer stop>\n    const char* skip_over_scopes(const char* src) {\n      return skip_over_scopes<start, stop>(src, nullptr);\n    }\n\n    // Match a sequence of characters delimited by the supplied chars.\n    template <prelexer start, prelexer stop>\n    const char* recursive_scopes(const char* src) {\n      // parse opener\n      src = start(src);\n      // abort if not found\n      if (!src) return 0;\n      // parse the rest until final closer\n      return skip_over_scopes<start, stop>(src);\n    }\n\n    // Match a sequence of characters delimited by the supplied strings.\n    template <const char* beg, const char* end, bool esc>\n    const char* delimited_by(const char* src) {\n      src = exactly<beg>(src);\n      if (!src) return 0;\n      const char* stop;\n      while (true) {\n        if (!*src) return 0;\n        stop = exactly<end>(src);\n        if (stop && (!esc || *(src - 1) != '\\\\')) return stop;\n        src = stop ? stop : src + 1;\n      }\n    }\n\n    // Tries to match a certain number of times (between the supplied interval).\n    template<prelexer mx, size_t lo, size_t hi>\n    const char* between(const char* src) {\n      for (size_t i = 0; i < lo; ++i) {\n        src = mx(src);\n        if (!src) return 0;\n      }\n      for (size_t i = lo; i <= hi; ++i) {\n        const char* new_src = mx(src);\n        if (!new_src) return src;\n        src = new_src;\n      }\n      return src;\n    }\n\n    // equivalent of STRING_REGULAR_EXPRESSIONS\n    const char* re_string_double_open(const char* src);\n    const char* re_string_double_close(const char* src);\n    const char* re_string_single_open(const char* src);\n    const char* re_string_single_close(const char* src);\n    const char* re_string_uri_open(const char* src);\n    const char* re_string_uri_close(const char* src);\n\n    // Match a line comment.\n    const char* line_comment(const char* src);\n\n    // Match a block comment.\n    const char* block_comment(const char* src);\n    // Match either.\n    const char* comment(const char* src);\n    // Match double- and single-quoted strings.\n    const char* double_quoted_string(const char* src);\n    const char* single_quoted_string(const char* src);\n    const char* quoted_string(const char* src);\n    // Match interpolants.\n    const char* interpolant(const char* src);\n    // Match number prefix ([\\+\\-]+)\n    const char* number_prefix(const char* src);\n\n    // Match zero plus white-space or line_comments\n    const char* optional_css_whitespace(const char* src);\n    const char* css_whitespace(const char* src);\n    // Match optional_css_whitepace plus block_comments\n    const char* optional_css_comments(const char* src);\n    const char* css_comments(const char* src);\n\n    // Match one backslash escaped char\n    const char* escape_seq(const char* src);\n\n    // Match CSS css variables.\n    const char* custom_property_name(const char* src);\n    // Match a CSS identifier.\n    const char* identifier(const char* src);\n    const char* identifier_alpha(const char* src);\n    const char* identifier_alnum(const char* src);\n    const char* strict_identifier(const char* src);\n    const char* strict_identifier_alpha(const char* src);\n    const char* strict_identifier_alnum(const char* src);\n    // Match a CSS unit identifier.\n    const char* one_unit(const char* src);\n    const char* multiple_units(const char* src);\n    const char* unit_identifier(const char* src);\n    // const char* strict_identifier_alnums(const char* src);\n    // Match reference selector.\n    const char* re_reference_combinator(const char* src);\n    const char* static_reference_combinator(const char* src);\n    const char* schema_reference_combinator(const char* src);\n\n    // Match interpolant schemas\n    const char* identifier_schema(const char* src);\n    const char* value_schema(const char* src);\n    const char* sass_value(const char* src);\n    // const char* filename(const char* src);\n    // const char* filename_schema(const char* src);\n    // const char* url_schema(const char* src);\n    // const char* url_value(const char* src);\n    const char* vendor_prefix(const char* src);\n\n    const char* re_special_directive(const char* src);\n    const char* re_prefixed_directive(const char* src);\n    const char* re_almost_any_value_token(const char* src);\n\n    // Match CSS '@' keywords.\n    const char* at_keyword(const char* src);\n    const char* kwd_import(const char* src);\n    const char* kwd_at_root(const char* src);\n    const char* kwd_with_directive(const char* src);\n    const char* kwd_without_directive(const char* src);\n    const char* kwd_media(const char* src);\n    const char* kwd_supports_directive(const char* src);\n    // const char* keyframes(const char* src);\n    // const char* keyf(const char* src);\n    const char* kwd_mixin(const char* src);\n    const char* kwd_function(const char* src);\n    const char* kwd_return_directive(const char* src);\n    const char* kwd_include_directive(const char* src);\n    const char* kwd_content_directive(const char* src);\n    const char* kwd_charset_directive(const char* src);\n    const char* kwd_extend(const char* src);\n\n    const char* unicode_seq(const char* src);\n\n    const char* kwd_if_directive(const char* src);\n    const char* kwd_else_directive(const char* src);\n    const char* elseif_directive(const char* src);\n\n    const char* kwd_for_directive(const char* src);\n    const char* kwd_from(const char* src);\n    const char* kwd_to(const char* src);\n    const char* kwd_through(const char* src);\n\n    const char* kwd_each_directive(const char* src);\n    const char* kwd_in(const char* src);\n\n    const char* kwd_while_directive(const char* src);\n\n    const char* re_nothing(const char* src);\n\n    const char* re_special_fun(const char* src);\n\n    const char* kwd_warn(const char* src);\n    const char* kwd_err(const char* src);\n    const char* kwd_dbg(const char* src);\n\n    const char* kwd_null(const char* src);\n\n    const char* re_selector_list(const char* src);\n    const char* re_type_selector(const char* src);\n    const char* re_static_expression(const char* src);\n\n    // identifier that can start with hyphens\n    const char* css_identifier(const char* src);\n    const char* css_ip_identifier(const char* src);\n\n    // Match CSS type selectors\n    const char* namespace_schema(const char* src);\n    const char* namespace_prefix(const char* src);\n    const char* type_selector(const char* src);\n    const char* hyphens_and_identifier(const char* src);\n    const char* hyphens_and_name(const char* src);\n    const char* universal(const char* src);\n    // Match CSS id names.\n    const char* id_name(const char* src);\n    // Match CSS class names.\n    const char* class_name(const char* src);\n    // Attribute name in an attribute selector\n    const char* attribute_name(const char* src);\n    // Match placeholder selectors.\n    const char* placeholder(const char* src);\n    // Match CSS numeric constants.\n    const char* op(const char* src);\n    const char* sign(const char* src);\n    const char* unsigned_number(const char* src);\n    const char* number(const char* src);\n    const char* coefficient(const char* src);\n    const char* binomial(const char* src);\n    const char* percentage(const char* src);\n    const char* ampersand(const char* src);\n    const char* dimension(const char* src);\n    const char* hex(const char* src);\n    const char* hexa(const char* src);\n    const char* hex0(const char* src);\n    // const char* rgb_prefix(const char* src);\n    // Match CSS uri specifiers.\n    const char* uri_prefix(const char* src);\n    // Match CSS \"!important\" keyword.\n    const char* kwd_important(const char* src);\n    // Match CSS \"!optional\" keyword.\n    const char* kwd_optional(const char* src);\n    // Match Sass \"!default\" keyword.\n    const char* default_flag(const char* src);\n    const char* global_flag(const char* src);\n    // Match CSS pseudo-class/element prefixes\n    const char* pseudo_prefix(const char* src);\n    // Match CSS function call openers.\n    const char* re_functional(const char* src);\n    const char* re_pseudo_selector(const char* src);\n    const char* functional_schema(const char* src);\n    const char* pseudo_not(const char* src);\n    // Match CSS 'odd' and 'even' keywords for functional pseudo-classes.\n    const char* even(const char* src);\n    const char* odd(const char* src);\n    // Match CSS attribute-matching operators.\n    const char* exact_match(const char* src);\n    const char* class_match(const char* src);\n    const char* dash_match(const char* src);\n    const char* prefix_match(const char* src);\n    const char* suffix_match(const char* src);\n    const char* substring_match(const char* src);\n    // Match CSS combinators.\n    // const char* adjacent_to(const char* src);\n    // const char* precedes(const char* src);\n    // const char* parent_of(const char* src);\n    // const char* ancestor_of(const char* src);\n\n    // Match SCSS variable names.\n    const char* variable(const char* src);\n    const char* calc_fn_call(const char* src);\n\n    // IE stuff\n    const char* ie_progid(const char* src);\n    const char* ie_expression(const char* src);\n    const char* ie_property(const char* src);\n    const char* ie_keyword_arg(const char* src);\n    const char* ie_keyword_arg_value(const char* src);\n    const char* ie_keyword_arg_property(const char* src);\n\n    // characters that terminate parsing of a list\n    const char* list_terminator(const char* src);\n    const char* space_list_terminator(const char* src);\n\n    // match url()\n    const char* H(const char* src);\n    const char* W(const char* src);\n    // `UNICODE` makes VS sad\n    const char* UUNICODE(const char* src);\n    const char* NONASCII(const char* src);\n    const char* ESCAPE(const char* src);\n    const char* real_uri(const char* src);\n    const char* real_uri_suffix(const char* src);\n    // const char* real_uri_prefix(const char* src);\n    const char* real_uri_value(const char* src);\n\n    // Path matching functions.\n    // const char* folder(const char* src);\n    // const char* folders(const char* src);\n\n\n    const char* static_string(const char* src);\n    const char* static_component(const char* src);\n    const char* static_property(const char* src);\n    const char* static_value(const char* src);\n\n    const char* css_variable_value(const char* src);\n    const char* css_variable_top_level_value(const char* src);\n\n    // Utility functions for finding and counting characters in a string.\n    template<char c>\n    const char* find_first(const char* src) {\n      while (*src && *src != c) ++src;\n      return *src ? src : 0;\n    }\n    template<prelexer mx>\n    const char* find_first(const char* src) {\n      while (*src && !mx(src)) ++src;\n      return *src ? src : 0;\n    }\n    template<prelexer mx>\n    const char* find_first_in_interval(const char* beg, const char* end) {\n      bool esc = false;\n      while ((beg < end) && *beg) {\n        if (esc) esc = false;\n        else if (*beg == '\\\\') esc = true;\n        else if (mx(beg)) return beg;\n        ++beg;\n      }\n      return 0;\n    }\n    template<prelexer mx, prelexer skip>\n    const char* find_first_in_interval(const char* beg, const char* end) {\n      bool esc = false;\n      while ((beg < end) && *beg) {\n        if (esc) esc = false;\n        else if (*beg == '\\\\') esc = true;\n        else if (const char* pos = skip(beg)) beg = pos;\n        else if (mx(beg)) return beg;\n        ++beg;\n      }\n      return 0;\n    }\n    template <prelexer mx>\n    unsigned int count_interval(const char* beg, const char* end) {\n      unsigned int counter = 0;\n      bool esc = false;\n      while (beg < end && *beg) {\n        const char* p;\n        if (esc) {\n          esc = false;\n          ++beg;\n        } else if (*beg == '\\\\') {\n          esc = true;\n          ++beg;\n        } else if ((p = mx(beg))) {\n          ++counter;\n          beg = p;\n        }\n        else {\n          ++beg;\n        }\n      }\n      return counter;\n    }\n\n    template <size_t size, prelexer mx, prelexer pad>\n    const char* padded_token(const char* src)\n    {\n      size_t got = 0;\n      const char* pos = src;\n      while (got < size) {\n        if (!mx(pos)) break;\n        ++ pos; ++ got;\n      }\n      while (got < size) {\n        if (!pad(pos)) break;\n        ++ pos; ++ got;\n      }\n      return got ? pos : 0;\n    }\n\n    template <size_t min, size_t max, prelexer mx>\n    const char* minmax_range(const char* src)\n    {\n      size_t got = 0;\n      const char* pos = src;\n      while (got < max) {\n        if (!mx(pos)) break;\n        ++ pos; ++ got;\n      }\n      if (got < min) return 0;\n      if (got > max) return 0;\n      return pos;\n    }\n\n    template <char min, char max>\n    const char* char_range(const char* src)\n    {\n      if (*src < min) return 0;\n      if (*src > max) return 0;\n      return src + 1;\n    }\n\n  }\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/remove_placeholders.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\n#include \"remove_placeholders.hpp\"\n\nnamespace Sass {\n\n    Remove_Placeholders::Remove_Placeholders()\n    { }\n\n    void Remove_Placeholders::operator()(Block* b) {\n      for (size_t i = 0, L = b->length(); i < L; ++i) {\n        if (b->get(i)) b->get(i)->perform(this);\n      }\n    }\n\n    void Remove_Placeholders::remove_placeholders(SimpleSelector* simple)\n    {\n      if (PseudoSelector * pseudo = simple->getPseudoSelector()) {\n        if (pseudo->selector()) remove_placeholders(pseudo->selector());\n      }\n    }\n\n    void Remove_Placeholders::remove_placeholders(CompoundSelector* compound)\n    {\n      for (size_t i = 0, L = compound->length(); i < L; ++i) {\n        if (compound->get(i)) remove_placeholders(compound->get(i));\n      }\n      listEraseItemIf(compound->elements(), listIsEmpty<SimpleSelector>);\n    }\n\n    void Remove_Placeholders::remove_placeholders(ComplexSelector* complex)\n    {\n      if (complex->has_placeholder()) {\n        complex->clear(); // remove all\n      }\n      else {\n        for (size_t i = 0, L = complex->length(); i < L; ++i) {\n          if (CompoundSelector * compound = complex->get(i)->getCompound()) {\n            if (compound) remove_placeholders(compound);\n          }\n        }\n        listEraseItemIf(complex->elements(), listIsEmpty<SelectorComponent>);\n      }\n    }\n\n    SelectorList* Remove_Placeholders::remove_placeholders(SelectorList* sl)\n    {\n      for (size_t i = 0, L = sl->length(); i < L; ++i) {\n        if (sl->get(i)) remove_placeholders(sl->get(i));\n      }\n      listEraseItemIf(sl->elements(), listIsEmpty<ComplexSelector>);\n      return sl;\n    }\n\n    void Remove_Placeholders::operator()(CssMediaRule* rule)\n    {\n      if (rule->block()) operator()(rule->block());\n    }\n\n    void Remove_Placeholders::operator()(StyleRule* r)\n    {\n      if (SelectorListObj sl = r->selector()) {\n        // Set the new placeholder selector list\n        r->selector((remove_placeholders(sl)));\n      }\n      // Iterate into child blocks\n      Block_Obj b = r->block();\n      for (size_t i = 0, L = b->length(); i < L; ++i) {\n        if (b->get(i)) { b->get(i)->perform(this); }\n      }\n    }\n\n    void Remove_Placeholders::operator()(SupportsRule* m)\n    {\n      if (m->block()) operator()(m->block());\n    }\n\n    void Remove_Placeholders::operator()(AtRule* a)\n    {\n      if (a->block()) a->block()->perform(this);\n    }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/remove_placeholders.hpp",
    "content": "#ifndef SASS_REMOVE_PLACEHOLDERS_H\n#define SASS_REMOVE_PLACEHOLDERS_H\n\n#include \"ast_fwd_decl.hpp\"\n#include \"operation.hpp\"\n\nnamespace Sass {\n\n  class Remove_Placeholders : public Operation_CRTP<void, Remove_Placeholders> {\n\n  public:\n\n    SelectorList* remove_placeholders(SelectorList*);\n    void remove_placeholders(SimpleSelector* simple);\n    void remove_placeholders(CompoundSelector* complex);\n    void remove_placeholders(ComplexSelector* complex);\n\n\n  public:\n    Remove_Placeholders();\n    ~Remove_Placeholders() { }\n\n    void operator()(Block*);\n    void operator()(StyleRule*);\n    void operator()(CssMediaRule*);\n    void operator()(SupportsRule*);\n    void operator()(AtRule*);\n\n    // ignore missed types\n    template <typename U>\n    void fallback(U x) {}\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <cstdlib>\n#include <cstring>\n#include <vector>\n#include <sstream>\n\n#include \"sass.h\"\n#include \"file.hpp\"\n#include \"util.hpp\"\n#include \"context.hpp\"\n#include \"sass_context.hpp\"\n#include \"sass_functions.hpp\"\n\nnamespace Sass {\n\n  // helper to convert string list to vector\n  sass::vector<sass::string> list2vec(struct string_list* cur)\n  {\n    sass::vector<sass::string> list;\n    while (cur) {\n      list.push_back(cur->string);\n      cur = cur->next;\n    }\n    return list;\n  }\n\n}\n\nextern \"C\" {\n  using namespace Sass;\n\n  // Allocate libsass heap memory\n  // Don't forget string termination!\n  void* ADDCALL sass_alloc_memory(size_t size)\n  {\n    void* ptr = malloc(size);\n    if (ptr == NULL) {\n      std::cerr << \"Out of memory.\\n\";\n      exit(EXIT_FAILURE);\n    }\n    return ptr;\n  }\n\n  char* ADDCALL sass_copy_c_string(const char* str)\n  {\n    if (str == nullptr) return nullptr;\n    size_t len = strlen(str) + 1;\n    char* cpy = (char*) sass_alloc_memory(len);\n    std::memcpy(cpy, str, len);\n    return cpy;\n  }\n\n  // Deallocate libsass heap memory\n  void ADDCALL sass_free_memory(void* ptr)\n  {\n    if (ptr) free (ptr);\n  }\n\n  // caller must free the returned memory\n  char* ADDCALL sass_string_quote (const char *str, const char quote_mark)\n  {\n    sass::string quoted = quote(str, quote_mark);\n    return sass_copy_c_string(quoted.c_str());\n  }\n\n  // caller must free the returned memory\n  char* ADDCALL sass_string_unquote (const char *str)\n  {\n    sass::string unquoted = unquote(str);\n    return sass_copy_c_string(unquoted.c_str());\n  }\n\n  char* ADDCALL sass_compiler_find_include (const char* file, struct Sass_Compiler* compiler)\n  {\n    // get the last import entry to get current base directory\n    Sass_Import_Entry import = sass_compiler_get_last_import(compiler);\n    const sass::vector<sass::string>& incs = compiler->cpp_ctx->include_paths;\n    // create the vector with paths to lookup\n    sass::vector<sass::string> paths(1 + incs.size());\n    paths.push_back(File::dir_name(import->abs_path));\n    paths.insert( paths.end(), incs.begin(), incs.end() );\n    // now resolve the file path relative to lookup paths\n    sass::string resolved(File::find_include(file, paths));\n    return sass_copy_c_string(resolved.c_str());\n  }\n\n  char* ADDCALL sass_compiler_find_file (const char* file, struct Sass_Compiler* compiler)\n  {\n    // get the last import entry to get current base directory\n    Sass_Import_Entry import = sass_compiler_get_last_import(compiler);\n    const sass::vector<sass::string>& incs = compiler->cpp_ctx->include_paths;\n    // create the vector with paths to lookup\n    sass::vector<sass::string> paths(1 + incs.size());\n    paths.push_back(File::dir_name(import->abs_path));\n    paths.insert( paths.end(), incs.begin(), incs.end() );\n    // now resolve the file path relative to lookup paths\n    sass::string resolved(File::find_file(file, paths));\n    return sass_copy_c_string(resolved.c_str());\n  }\n\n  // Make sure to free the returned value!\n  // Incs array has to be null terminated!\n  // this has the original resolve logic for sass include\n  char* ADDCALL sass_find_include (const char* file, struct Sass_Options* opt)\n  {\n    sass::vector<sass::string> vec(list2vec(opt->include_paths));\n    sass::string resolved(File::find_include(file, vec));\n    return sass_copy_c_string(resolved.c_str());\n  }\n\n  // Make sure to free the returned value!\n  // Incs array has to be null terminated!\n  char* ADDCALL sass_find_file (const char* file, struct Sass_Options* opt)\n  {\n    sass::vector<sass::string> vec(list2vec(opt->include_paths));\n    sass::string resolved(File::find_file(file, vec));\n    return sass_copy_c_string(resolved.c_str());\n  }\n\n  // Get compiled libsass version\n  const char* ADDCALL libsass_version(void)\n  {\n    return LIBSASS_VERSION;\n  }\n\n  // Get compiled libsass version\n  const char* ADDCALL libsass_language_version(void)\n  {\n    return LIBSASS_LANGUAGE_VERSION;\n  }\n\n}\n\nnamespace Sass {\n\n  // helper to aid dreaded MSVC debug mode\n  char* sass_copy_string(sass::string str)\n  {\n    // In MSVC the following can lead to segfault:\n    // sass_copy_c_string(stream.str().c_str());\n    // Reason is that the string returned by str() is disposed before\n    // sass_copy_c_string is invoked. The string is actually a stack\n    // object, so indeed nobody is holding on to it. So it seems\n    // perfectly fair to release it right away. So the const char*\n    // by c_str will point to invalid memory. I'm not sure if this is\n    // the behavior for all compiler, but I'm pretty sure we would\n    // have gotten more issues reported if that would be the case.\n    // Wrapping it in a functions seems the cleanest approach as the\n    // function must hold on to the stack variable until it's done.\n    return sass_copy_c_string(str.c_str());\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass.hpp",
    "content": "// must be the first include in all compile units\n#ifndef SASS_SASS_H\n#define SASS_SASS_H\n\n// undefine extensions macro to tell sys includes\n// that we do not want any macros to be exported\n// mainly fixes an issue on SmartOS (SEC macro)\n#undef __EXTENSIONS__\n\n#ifdef _MSC_VER\n#pragma warning(disable : 4005)\n#endif\n\n// applies to MSVC and MinGW\n#ifdef _WIN32\n// we do not want the ERROR macro\n# ifndef NOGDI\n#  define NOGDI\n# endif\n// we do not want the min/max macro\n# ifndef NOMINMAX\n#  define NOMINMAX\n# endif\n// we do not want the IN/OUT macro\n# ifndef _NO_W32_PSEUDO_MODIFIERS\n#  define _NO_W32_PSEUDO_MODIFIERS\n# endif\n#endif\n\n\n// should we be case insensitive\n// when dealing with files or paths\n#ifndef FS_CASE_SENSITIVE\n# ifdef _WIN32\n#  define FS_CASE_SENSITIVE 0\n# else\n#  define FS_CASE_SENSITIVE 1\n# endif\n#endif\n\n// path separation char\n#ifndef PATH_SEP\n# ifdef _WIN32\n#  define PATH_SEP ';'\n# else\n#  define PATH_SEP ':'\n# endif\n#endif\n\n\n// Include C-API header\n#include \"sass/base.h\"\n\n// Include allocator\n#include \"memory.hpp\"\n\n// For C++ helper\n#include <string>\n#include <vector>\n\n// output behavior\nnamespace Sass {\n\n  // create some C++ aliases for the most used options\n  const static Sass_Output_Style NESTED = SASS_STYLE_NESTED;\n  const static Sass_Output_Style COMPACT = SASS_STYLE_COMPACT;\n  const static Sass_Output_Style EXPANDED = SASS_STYLE_EXPANDED;\n  const static Sass_Output_Style COMPRESSED = SASS_STYLE_COMPRESSED;\n  // only used internal to trigger ruby inspect behavior\n  const static Sass_Output_Style INSPECT = SASS_STYLE_INSPECT;\n  const static Sass_Output_Style TO_SASS = SASS_STYLE_TO_SASS;\n  const static Sass_Output_Style TO_CSS = SASS_STYLE_TO_CSS;\n\n  // helper to aid dreaded MSVC debug mode\n  // see implementation for more details\n  char* sass_copy_string(sass::string str);\n\n}\n\n// input behaviors\nenum Sass_Input_Style {\n  SASS_CONTEXT_NULL,\n  SASS_CONTEXT_FILE,\n  SASS_CONTEXT_DATA,\n  SASS_CONTEXT_FOLDER\n};\n\n// simple linked list\nstruct string_list {\n  string_list* next;\n  char* string;\n};\n\n// sass config options structure\nstruct Sass_Inspect_Options {\n\n  // Output style for the generated css code\n  // A value from above SASS_STYLE_* constants\n  enum Sass_Output_Style output_style;\n\n  // Precision for fractional numbers\n  int precision;\n\n  // initialization list (constructor with defaults)\n  Sass_Inspect_Options(Sass_Output_Style style = Sass::NESTED,\n                       int precision = 10)\n  : output_style(style), precision(precision)\n  { }\n\n};\n\n// sass config options structure\nstruct Sass_Output_Options : Sass_Inspect_Options {\n\n  // String to be used for indentation\n  const char* indent;\n  // String to be used to for line feeds\n  const char* linefeed;\n\n  // Emit comments in the generated CSS indicating\n  // the corresponding source line.\n  bool source_comments;\n\n  // initialization list (constructor with defaults)\n  Sass_Output_Options(struct Sass_Inspect_Options opt,\n                      const char* indent = \"  \",\n                      const char* linefeed = \"\\n\",\n                      bool source_comments = false)\n  : Sass_Inspect_Options(opt),\n    indent(indent), linefeed(linefeed),\n    source_comments(source_comments)\n  { }\n\n  // initialization list (constructor with defaults)\n  Sass_Output_Options(Sass_Output_Style style = Sass::NESTED,\n                      int precision = 10,\n                      const char* indent = \"  \",\n                      const char* linefeed = \"\\n\",\n                      bool source_comments = false)\n  : Sass_Inspect_Options(style, precision),\n    indent(indent), linefeed(linefeed),\n    source_comments(source_comments)\n  { }\n\n};\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass2scss.cpp",
    "content": "/**\n * sass2scss\n * Licensed under the MIT License\n * Copyright (c) Marcel Greter\n */\n\n#ifdef _MSC_VER\n#define _CRT_SECURE_NO_WARNINGS\n#define _CRT_NONSTDC_NO_DEPRECATE\n#endif\n\n// include library\n#include <stack>\n#include <string>\n#include <cstring>\n#include <cstdlib>\n#include <sstream>\n#include <iostream>\n#include <stdio.h>\n\n///*\n//\n// src comments: comments in sass syntax (staring with //)\n// css comments: multiline comments in css syntax (starting with /*)\n//\n// KEEP_COMMENT: keep src comments in the resulting css code\n// STRIP_COMMENT: strip out all comments (either src or css)\n// CONVERT_COMMENT: convert all src comments to css comments\n//\n//*/\n\n// our own header\n#include \"sass2scss.h\"\n\n// add namespace for c++\nnamespace Sass\n{\n\n\t// return the actual prettify value from options\n\t#define PRETTIFY(converter) (converter.options - (converter.options & 248))\n\t// query the options integer to check if the option is enables\n\t#define KEEP_COMMENT(converter) ((converter.options & SASS2SCSS_KEEP_COMMENT) == SASS2SCSS_KEEP_COMMENT)\n\t#define STRIP_COMMENT(converter) ((converter.options & SASS2SCSS_STRIP_COMMENT) == SASS2SCSS_STRIP_COMMENT)\n\t#define CONVERT_COMMENT(converter) ((converter.options & SASS2SCSS_CONVERT_COMMENT) == SASS2SCSS_CONVERT_COMMENT)\n\n\t// some makros to access the indentation stack\n\t#define INDENT(converter) (converter.indents.top())\n\n\t// some makros to query comment parser status\n\t#define IS_PARSING(converter) (converter.comment == \"\")\n\t#define IS_COMMENT(converter) (converter.comment != \"\")\n\t#define IS_SRC_COMMENT(converter) (converter.comment == \"//\" && ! CONVERT_COMMENT(converter))\n\t#define IS_CSS_COMMENT(converter) (converter.comment == \"/*\" || (converter.comment == \"//\" && CONVERT_COMMENT(converter)))\n\n\t// pretty printer helper function\n\tstatic std::string closer (const converter& converter)\n\t{\n\t\treturn PRETTIFY(converter) == 0 ? \" }\" :\n\t\t     PRETTIFY(converter) <= 1 ? \" }\" :\n\t\t       \"\\n\" + INDENT(converter) + \"}\";\n\t}\n\n\t// pretty printer helper function\n\tstatic std::string opener (const converter& converter)\n\t{\n\t\treturn PRETTIFY(converter) == 0 ? \" { \" :\n\t\t     PRETTIFY(converter) <= 2 ? \" {\" :\n\t\t       \"\\n\" + INDENT(converter) + \"{\";\n\t}\n\n\t// check if the given string is a pseudo selector\n\t// needed to differentiate from sass property syntax\n\tstatic bool isPseudoSelector (std::string& sel)\n\t{\n\n\t\tsize_t len = sel.length();\n\t\tif (len < 1) return false;\n\t\tsize_t pos = sel.find_first_not_of(\"abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ\", 1);\n\t\tif (pos != std::string::npos) sel.erase(pos, std::string::npos);\n\t\tsize_t i = sel.length();\n\t\twhile (i -- > 0) { sel.at(i) = tolower(sel.at(i)); }\n\n\t\t// CSS Level 1 - Recommendation\n\t\tif (sel == \":link\") return true;\n\t\tif (sel == \":visited\") return true;\n\t\tif (sel == \":active\") return true;\n\n\t\t// CSS Level 2 (Revision 1) - Recommendation\n\t\tif (sel == \":lang\") return true;\n\t\tif (sel == \":first-child\") return true;\n\t\tif (sel == \":hover\") return true;\n\t\tif (sel == \":focus\") return true;\n\t\t// disabled - also valid properties\n\t\t// if (sel == \":left\") return true;\n\t\t// if (sel == \":right\") return true;\n\t\tif (sel == \":first\") return true;\n\n\t\t// Selectors Level 3 - Recommendation\n\t\tif (sel == \":target\") return true;\n\t\tif (sel == \":root\") return true;\n\t\tif (sel == \":nth-child\") return true;\n\t\tif (sel == \":nth-last-of-child\") return true;\n\t\tif (sel == \":nth-of-type\") return true;\n\t\tif (sel == \":nth-last-of-type\") return true;\n\t\tif (sel == \":last-child\") return true;\n\t\tif (sel == \":first-of-type\") return true;\n\t\tif (sel == \":last-of-type\") return true;\n\t\tif (sel == \":only-child\") return true;\n\t\tif (sel == \":only-of-type\") return true;\n\t\tif (sel == \":empty\") return true;\n\t\tif (sel == \":not\") return true;\n\n\t\t// CSS Basic User Interface Module Level 3 - Working Draft\n\t\tif (sel == \":default\") return true;\n\t\tif (sel == \":valid\") return true;\n\t\tif (sel == \":invalid\") return true;\n\t\tif (sel == \":in-range\") return true;\n\t\tif (sel == \":out-of-range\") return true;\n\t\tif (sel == \":required\") return true;\n\t\tif (sel == \":optional\") return true;\n\t\tif (sel == \":read-only\") return true;\n\t\tif (sel == \":read-write\") return true;\n\t\tif (sel == \":dir\") return true;\n\t\tif (sel == \":enabled\") return true;\n\t\tif (sel == \":disabled\") return true;\n\t\tif (sel == \":checked\") return true;\n\t\tif (sel == \":indeterminate\") return true;\n\t\tif (sel == \":nth-last-child\") return true;\n\n\t\t// Selectors Level 4 - Working Draft\n\t\tif (sel == \":any-link\") return true;\n\t\tif (sel == \":local-link\") return true;\n\t\tif (sel == \":scope\") return true;\n\t\tif (sel == \":active-drop-target\") return true;\n\t\tif (sel == \":valid-drop-target\") return true;\n\t\tif (sel == \":invalid-drop-target\") return true;\n\t\tif (sel == \":current\") return true;\n\t\tif (sel == \":past\") return true;\n\t\tif (sel == \":future\") return true;\n\t\tif (sel == \":placeholder-shown\") return true;\n\t\tif (sel == \":user-error\") return true;\n\t\tif (sel == \":blank\") return true;\n\t\tif (sel == \":nth-match\") return true;\n\t\tif (sel == \":nth-last-match\") return true;\n\t\tif (sel == \":nth-column\") return true;\n\t\tif (sel == \":nth-last-column\") return true;\n\t\tif (sel == \":matches\") return true;\n\n\t\t// Fullscreen API - Living Standard\n\t\tif (sel == \":fullscreen\") return true;\n\n\t\t// not a pseudo selector\n\t\treturn false;\n\n\t}\n\n\tstatic size_t findFirstCharacter (std::string& sass, size_t pos)\n\t{\n\t\treturn sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE, pos);\n\t}\n\n\tstatic size_t findLastCharacter (std::string& sass, size_t pos)\n\t{\n\t\treturn sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE, pos);\n\t}\n\n\tstatic bool isUrl (std::string& sass, size_t pos)\n\t{\n\t\treturn sass[pos] == 'u' && sass[pos+1] == 'r' && sass[pos+2] == 'l' && sass[pos+3] == '(';\n\t}\n\n\t// check if there is some char data\n\t// will ignore everything in comments\n\tstatic bool hasCharData (std::string& sass)\n\t{\n\n\t\tsize_t col_pos = 0;\n\n\t\twhile (true)\n\t\t{\n\n\t\t\t// try to find some meaningfull char\n\t\t\tcol_pos = sass.find_first_not_of(\" \\t\\n\\v\\f\\r\", col_pos);\n\n\t\t\t// there was no meaningfull char found\n\t\t\tif (col_pos == std::string::npos) return false;\n\n\t\t\t// found a multiline comment opener\n\t\t\tif (sass.substr(col_pos, 2) == \"/*\")\n\t\t\t{\n\t\t\t\t// find the multiline comment closer\n\t\t\t\tcol_pos = sass.find(\"*/\", col_pos);\n\t\t\t\t// maybe we did not find the closer here\n\t\t\t\tif (col_pos == std::string::npos) return false;\n\t\t\t\t// skip closer\n\t\t\t\tcol_pos += 2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t}\n\n\t}\n\t// EO hasCharData\n\n\t// find src comment opener\n\t// correctly skips quoted strings\n\tstatic size_t findCommentOpener (std::string& sass)\n\t{\n\n\t\tsize_t col_pos = 0;\n\t\tbool apoed = false;\n\t\tbool quoted = false;\n\t\tbool comment = false;\n\t\tsize_t brackets = 0;\n\n\t\twhile (col_pos != std::string::npos)\n\t\t{\n\n\t\t\t// process all interesting chars\n\t\t\tcol_pos = sass.find_first_of(\"\\\"\\'/\\\\*()\", col_pos);\n\n\t\t\t// assertion for valid result\n\t\t\tif (col_pos != std::string::npos)\n\t\t\t{\n\t\t\t\tchar character = sass.at(col_pos);\n\n\t\t\t\tif (character == '(')\n\t\t\t\t{\n\t\t\t\t\tif (!quoted && !apoed) brackets ++;\n\t\t\t\t}\n\t\t\t\telse if (character == ')')\n\t\t\t\t{\n\t\t\t\t\tif (!quoted && !apoed) brackets --;\n\t\t\t\t}\n\t\t\t\telse if (character == '\\\"')\n\t\t\t\t{\n\t\t\t\t\t// invert quote bool\n\t\t\t\t\tif (!apoed && !comment) quoted = !quoted;\n\t\t\t\t}\n\t\t\t\telse if (character == '\\'')\n\t\t\t\t{\n\t\t\t\t\t// invert quote bool\n\t\t\t\t\tif (!quoted && !comment) apoed = !apoed;\n\t\t\t\t}\n\t\t\t\telse if (col_pos > 0 && character == '/')\n\t\t\t\t{\n\t\t\t\t\tif (sass.at(col_pos - 1) == '*')\n\t\t\t\t\t{\n\t\t\t\t\t\tcomment = false;\n\t\t\t\t\t}\n\t\t\t\t\t// next needs to be a slash too\n\t\t\t\t\telse if (sass.at(col_pos - 1) == '/')\n\t\t\t\t\t{\n\t\t\t\t\t\t// only found if not in single or double quote, bracket or comment\n\t\t\t\t\t\tif (!quoted && !apoed && !comment && brackets == 0) return col_pos - 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (character == '\\\\')\n\t\t\t\t{\n\t\t\t\t\t// skip next char if in quote\n\t\t\t\t\tif (quoted || apoed) col_pos ++;\n\t\t\t\t}\n\t\t\t\t// this might be a comment opener\n\t\t\t\telse if (col_pos > 0 && character == '*')\n\t\t\t\t{\n\t\t\t\t\t// opening a multiline comment\n\t\t\t\t\tif (sass.at(col_pos - 1) == '/')\n\t\t\t\t\t{\n\t\t\t\t\t\t// we are now in a comment\n\t\t\t\t\t\tif (!quoted && !apoed) comment = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// skip char\n\t\t\t\tcol_pos ++;\n\n\t\t\t}\n\n\t\t}\n\t\t// EO while\n\n\t\treturn col_pos;\n\n\t}\n\t// EO findCommentOpener\n\n\t// remove multiline comments from sass string\n\t// correctly skips quoted strings\n\tstatic std::string removeMultilineComment (std::string &sass)\n\t{\n\n\t\tstd::string clean = \"\";\n\t\tsize_t col_pos = 0;\n\t\tsize_t open_pos = 0;\n\t\tsize_t close_pos = 0;\n\t\tbool apoed = false;\n\t\tbool quoted = false;\n\t\tbool comment = false;\n\n\t\t// process sass til string end\n\t\twhile (col_pos != std::string::npos)\n\t\t{\n\n\t\t\t// process all interesting chars\n\t\t\tcol_pos = sass.find_first_of(\"\\\"\\'/\\\\*\", col_pos);\n\n\t\t\t// assertion for valid result\n\t\t\tif (col_pos != std::string::npos)\n\t\t\t{\n\t\t\t\tchar character = sass.at(col_pos);\n\n\t\t\t\t// found quoted string delimiter\n\t\t\t\tif (character == '\\\"')\n\t\t\t\t{\n\t\t\t\t\tif (!apoed && !comment) quoted = !quoted;\n\t\t\t\t}\n\t\t\t\telse if (character == '\\'')\n\t\t\t\t{\n\t\t\t\t\tif (!quoted && !comment) apoed = !apoed;\n\t\t\t\t}\n\t\t\t\t// found possible comment closer\n\t\t\t\telse if (character == '/')\n\t\t\t\t{\n\t\t\t\t\t// look back to see if it is actually a closer\n\t\t\t\t\tif (comment && col_pos > 0 && sass.at(col_pos - 1) == '*')\n\t\t\t\t\t{\n\t\t\t\t\t\tclose_pos = col_pos + 1; comment = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (character == '\\\\')\n\t\t\t\t{\n\t\t\t\t\t// skip escaped char\n\t\t\t\t\tif (quoted || apoed) col_pos ++;\n\t\t\t\t}\n\t\t\t\t// this might be a comment opener\n\t\t\t\telse if (character == '*')\n\t\t\t\t{\n\t\t\t\t\t// look back to see if it is actually an opener\n\t\t\t\t\tif (!quoted && !apoed && col_pos > 0 && sass.at(col_pos - 1) == '/')\n\t\t\t\t\t{\n\t\t\t\t\t\tcomment = true; open_pos = col_pos - 1;\n\t\t\t\t\t\tclean += sass.substr(close_pos, open_pos - close_pos);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// skip char\n\t\t\t\tcol_pos ++;\n\n\t\t\t}\n\n\t\t}\n\t\t// EO while\n\n\t\t// add final parts (add half open comment text)\n\t\tif (comment) clean += sass.substr(open_pos);\n\t\telse clean += sass.substr(close_pos);\n\n\t\t// return string\n\t\treturn clean;\n\n\t}\n\t// EO removeMultilineComment\n\n\t// right trim a given string\n\tstd::string rtrim(const std::string &sass)\n\t{\n\t\tstd::string trimmed = sass;\n\t\tsize_t pos_ws = trimmed.find_last_not_of(\" \\t\\n\\v\\f\\r\");\n\t\tif (pos_ws != std::string::npos)\n\t\t{ trimmed.erase(pos_ws + 1); }\n\t\telse { trimmed.clear(); }\n\t\treturn trimmed;\n\t}\n\t// EO rtrim\n\n\t// flush whitespace and print additional text, but\n\t// only print additional chars and buffer whitespace\n\tstd::string flush (std::string& sass, converter& converter)\n\t{\n\n\t\t// return flushed\n\t\tstd::string scss = \"\";\n\n\t\t// print whitespace buffer\n\t\tscss += PRETTIFY(converter) > 0 ?\n\t\t        converter.whitespace : \"\";\n\t\t// reset whitespace buffer\n\t\tconverter.whitespace = \"\";\n\n\t\t// remove possible newlines from string\n\t\tsize_t pos_right = sass.find_last_not_of(\"\\n\\r\");\n\t\tif (pos_right == std::string::npos) return scss;\n\n\t\t// get the linefeeds from the string\n\t\tstd::string lfs = sass.substr(pos_right + 1);\n\t\tsass = sass.substr(0, pos_right + 1);\n\n\t\t// find some source comment opener\n\t\tsize_t comment_pos = findCommentOpener(sass);\n\t\t// check if there was a source comment\n\t\tif (comment_pos != std::string::npos)\n\t\t{\n\t\t\t// convert comment (but only outside other coments)\n\t\t\tif (CONVERT_COMMENT(converter) && !IS_COMMENT(converter))\n\t\t\t{\n\t\t\t\t// convert to multiline comment\n\t\t\t\tsass.at(comment_pos + 1) = '*';\n\t\t\t\t// add comment node to the whitespace\n\t\t\t\tsass += \" */\";\n\t\t\t}\n\t\t\t// not at line start\n\t\t\tif (comment_pos > 0)\n\t\t\t{\n\t\t\t\t// also include whitespace before the actual comment opener\n\t\t\t\tsize_t ws_pos = sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE, comment_pos - 1);\n\t\t\t\tcomment_pos = ws_pos == std::string::npos ? 0 : ws_pos + 1;\n\t\t\t}\n\t\t\tif (!STRIP_COMMENT(converter))\n\t\t\t{\n\t\t\t\t// add comment node to the whitespace\n\t\t\t\tconverter.whitespace += sass.substr(comment_pos);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// sass = removeMultilineComments(sass);\n\t\t\t}\n\t\t\t// update the actual sass code\n\t\t\tsass = sass.substr(0, comment_pos);\n\t\t}\n\n\t\t// add newline as getline discharged it\n\t\tconverter.whitespace += lfs + \"\\n\";\n\n\t\t// maybe remove any leading whitespace\n\t\tif (PRETTIFY(converter) == 0)\n\t\t{\n\t\t\t// remove leading whitespace and update string\n\t\t\tsize_t pos_left = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE);\n\t\t\tif (pos_left != std::string::npos) sass = sass.substr(pos_left);\n\t\t}\n\n\t\t// add flushed data\n\t\tscss += sass;\n\n\t\t// return string\n\t\treturn scss;\n\n\t}\n\t// EO flush\n\n\t// process a line of the sass text\n\tstd::string process (std::string& sass, converter& converter)\n\t{\n\n\t\t// resulting string\n\t\tstd::string scss = \"\";\n\n\t\t// strip multi line comments\n\t\tif (STRIP_COMMENT(converter))\n\t\t{\n\t\t\tsass = removeMultilineComment(sass);\n\t\t}\n\n\t\t// right trim input\n\t\tsass = rtrim(sass);\n\n\t\t// get position of first meaningfull character in string\n\t\tsize_t pos_left = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE);\n\n\t\t// special case for final run\n\t\tif (converter.end_of_file) pos_left = 0;\n\n\t\t// maybe has only whitespace\n\t\tif (pos_left == std::string::npos)\n\t\t{\n\t\t\t// just add complete whitespace\n\t\t\tconverter.whitespace += sass + \"\\n\";\n\t\t}\n\t\t// have meaningfull first char\n\t\telse\n\t\t{\n\n\t\t\t// extract and store indentation string\n\t\t\tstd::string indent = sass.substr(0, pos_left);\n\n\t\t\t// check if current line starts a comment\n\t\t\tstd::string open = sass.substr(pos_left, 2);\n\n\t\t\t// line has less or same indentation\n\t\t\t// finalize previous open parser context\n\t\t\tif (indent.length() <= INDENT(converter).length())\n\t\t\t{\n\n\t\t\t\t// close multilinie comment\n\t\t\t\tif (IS_CSS_COMMENT(converter))\n\t\t\t\t{\n\t\t\t\t\t// check if comments will be stripped anyway\n\t\t\t\t\tif (!STRIP_COMMENT(converter)) scss += \" */\";\n\t\t\t\t}\n\t\t\t\t// close src comment comment\n\t\t\t\telse if (IS_SRC_COMMENT(converter))\n\t\t\t\t{\n\t\t\t\t\t// add a newline to avoid closer on same line\n\t\t\t\t\t// this would put the bracket in the comment node\n\t\t\t\t\t// no longer needed since we parse them correctly\n\t\t\t\t\t// if (KEEP_COMMENT(converter)) scss += \"\\n\";\n\t\t\t\t}\n\t\t\t\t// close css properties\n\t\t\t\telse if (converter.property)\n\t\t\t\t{\n\t\t\t\t\t// add closer unless in concat mode\n\t\t\t\t\tif (!converter.comma)\n\t\t\t\t\t{\n\t\t\t\t\t\t// if there was no colon we have a selector\n\t\t\t\t\t\t// looks like there were no inner properties\n\t\t\t\t\t\tif (converter.selector) scss += \" {}\";\n\t\t\t\t\t\t// add final semicolon\n\t\t\t\t\t\telse if (!converter.semicolon) scss += \";\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// reset comment state\n\t\t\t\tconverter.comment = \"\";\n\n\t\t\t}\n\n\t\t\t// make sure we close every \"higher\" block\n\t\t\twhile (indent.length() < INDENT(converter).length())\n\t\t\t{\n\t\t\t\t// pop stacked context\n\t\t\t\tconverter.indents.pop();\n\t\t\t\t// print close bracket\n\t\t\t\tif (IS_PARSING(converter))\n\t\t\t\t{ scss += closer(converter); }\n\t\t\t\telse { scss += \" */\"; }\n\t\t\t\t// reset comment state\n\t\t\t\tconverter.comment = \"\";\n\t\t\t}\n\n\t\t\t// reset converter state\n\t\t\tconverter.selector = false;\n\n\t\t\t// looks like some undocumented behavior ...\n\t\t\t// https://github.com/mgreter/sass2scss/issues/29\n\t\t\tif (sass.substr(pos_left, 1) == \"\\\\\") {\n\t\t\t\tconverter.selector = true;\n\t\t\t\tsass[pos_left] = ' ';\n\t\t\t}\n\n\t\t\t// check if we have sass property syntax\n\t\t\tif (sass.substr(pos_left, 1) == \":\" && sass.substr(pos_left, 2) != \"::\")\n\t\t\t{\n\n\t\t\t\t// default to a selector\n\t\t\t\t// change back if property found\n\t\t\t\tconverter.selector = true;\n\t\t\t\t// get position of first whitespace char\n\t\t\t\tsize_t pos_wspace = sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left);\n\t\t\t\t// assertion check for valid result\n\t\t\t\tif (pos_wspace != std::string::npos)\n\t\t\t\t{\n\t\t\t\t\t// get the possible pseudo selector\n\t\t\t\t\tstd::string pseudo = sass.substr(pos_left, pos_wspace - pos_left);\n\t\t\t\t\t// get position of the first real property value char\n\t\t\t\t\t// pseudo selectors get this far, but have no actual value\n\t\t\t\t\tsize_t pos_value =  sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE, pos_wspace);\n\t\t\t\t\t// assertion check for valid result\n\t\t\t\t\tif (pos_value != std::string::npos)\n\t\t\t\t\t{\n\t\t\t\t\t\t// only process if not (fallowed by a semicolon or is a pseudo selector)\n\t\t\t\t\t\tif (!(sass.at(pos_value) == ':' || isPseudoSelector(pseudo)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// create new string by interchanging the colon sign for property and value\n\t\t\t\t\t\t\tsass = indent + sass.substr(pos_left + 1, pos_wspace - pos_left - 1) + \":\" + sass.substr(pos_wspace);\n\t\t\t\t\t\t\t// try to find a colon in the current line, but only ...\n\t\t\t\t\t\t\tsize_t pos_colon = sass.find_first_not_of(\":\", pos_left);\n\t\t\t\t\t\t\t// assertion for valid result\n\t\t\t\t\t\t\tif (pos_colon != std::string::npos)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// ... after the first word (skip beginning colons)\n\t\t\t\t\t\t\t\tpos_colon = sass.find_first_of(\":\", pos_colon);\n\t\t\t\t\t\t\t\t// it is a selector if there was no colon found\n\t\t\t\t\t\t\t\tconverter.selector = pos_colon == std::string::npos;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// check if we have a BEM property (one colon and no selector)\n\t\t\t\tif (sass.substr(pos_left, 1) == \":\" && converter.selector == true) {\n\t\t\t\t\tsize_t pos_wspace = sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left);\n\t\t\t\t\tsass = indent + sass.substr(pos_left + 1, pos_wspace) + \":\";\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// terminate some statements immediately\n\t\t\telse if (\n\t\t\t\tsass.substr(pos_left, 5) == \"@warn\" ||\n\t\t\t\tsass.substr(pos_left, 6) == \"@debug\" ||\n\t\t\t\tsass.substr(pos_left, 6) == \"@error\" ||\n\t\t\t\tsass.substr(pos_left, 6) == \"@value\" ||\n\t\t\t\tsass.substr(pos_left, 8) == \"@charset\" ||\n\t\t\t\tsass.substr(pos_left, 10) == \"@namespace\"\n\t\t\t) { sass = indent + sass.substr(pos_left); }\n\t\t\t// replace some specific sass shorthand directives (if not fallowed by a white space character)\n\t\t\telse if (sass.substr(pos_left, 1) == \"=\")\n\t\t\t{ sass = indent + \"@mixin \" + sass.substr(pos_left + 1); }\n\t\t\telse if (sass.substr(pos_left, 1) == \"+\")\n\t\t\t{\n\t\t\t\t// must be followed by a mixin call (no whitespace afterwards or at ending directly)\n\t\t\t\tif (sass[pos_left+1] != 0 && sass[pos_left+1] != ' ' && sass[pos_left+1] != '\\t') {\n\t\t\t\t\tsass = indent + \"@include \" + sass.substr(pos_left + 1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// add quotes for import if needed\n\t\t\telse if (sass.substr(pos_left, 7) == \"@import\")\n\t\t\t{\n\t\t\t\t// get positions for the actual import url\n\t\t\t\tsize_t pos_import = sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left + 7);\n\t\t\t\tsize_t pos = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE, pos_import);\n\t\t\t\tsize_t start = pos;\n\t\t\t\tbool in_dqstr = false;\n\t\t\t\tbool in_sqstr = false;\n\t\t\t\tbool is_escaped = false;\n\t\t\t\tdo {\n\t\t\t\t\tif (is_escaped) {\n\t\t\t\t\t\tis_escaped = false;\n\t\t\t\t\t}\n\t\t\t\t\telse if (sass[pos] == '\\\\') {\n\t\t\t\t\t\tis_escaped = true;\n\t\t\t\t\t}\n\t\t\t\t\telse if (sass[pos] == '\"') {\n\t\t\t\t\t\tif (!in_sqstr) in_dqstr = ! in_dqstr;\n\t\t\t\t\t}\n\t\t\t\t\telse if (sass[pos] == '\\'') {\n\t\t\t\t\t\tif (!in_dqstr) in_sqstr = ! in_sqstr;\n\t\t\t\t\t}\n\t\t\t\t\telse if (in_dqstr || in_sqstr) {\n\t\t\t\t\t\t// skip over quoted stuff\n\t\t\t\t\t}\n\t\t\t\t\telse if (sass[pos] == ',' || sass[pos] == 0) {\n\t\t\t\t\t\tif (sass[start] != '\"' && sass[start] != '\\'' && !isUrl(sass, start)) {\n\t\t\t\t\t\t\tsize_t end = findLastCharacter(sass, pos - 1) + 1;\n\t\t\t\t\t\t\tsass = sass.replace(end, 0, \"\\\"\");\n\t\t\t\t\t\t\tsass = sass.replace(start, 0, \"\\\"\");\n\t\t\t\t\t\t\tpos += 2;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstart = findFirstCharacter(sass, pos + 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\twhile (sass[pos++] != 0);\n\n\t\t\t}\n\t\t\telse if (\n\t\t\t\tsass.substr(pos_left, 7) != \"@return\" &&\n\t\t\t\tsass.substr(pos_left, 7) != \"@extend\" &&\n\t\t\t\tsass.substr(pos_left, 8) != \"@include\" &&\n\t\t\t\tsass.substr(pos_left, 8) != \"@content\"\n\t\t\t) {\n\n\t\t\t\t// probably a selector anyway\n\t\t\t\tconverter.selector = true;\n\t\t\t\t// try to find first colon in the current line\n\t\t\t\tsize_t pos_colon = sass.find_first_of(\":\", pos_left);\n\t\t\t\t// assertion that we have a colon\n\t\t\t\tif (pos_colon != std::string::npos)\n\t\t\t\t{\n\t\t\t\t\t// it is not a selector if we have a space after a colon\n\t\t\t\t\tif (sass[pos_colon+1] == ' ') converter.selector = false;\n\t\t\t\t\tif (sass[pos_colon+1] == '\t') converter.selector = false;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// current line has more indentation\n\t\t\tif (indent.length() >= INDENT(converter).length())\n\t\t\t{\n\t\t\t\t// not in comment mode\n\t\t\t\tif (IS_PARSING(converter))\n\t\t\t\t{\n\t\t\t\t\t// has meaningfull chars\n\t\t\t\t\tif (hasCharData(sass))\n\t\t\t\t\t{\n\t\t\t\t\t\t// is probably a property\n\t\t\t\t\t\t// also true for selectors\n\t\t\t\t\t\tconverter.property = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// current line has more indentation\n\t\t\tif (indent.length() > INDENT(converter).length())\n\t\t\t{\n\t\t\t\t// not in comment mode\n\t\t\t\tif (IS_PARSING(converter))\n\t\t\t\t{\n\t\t\t\t\t// had meaningfull chars\n\t\t\t\t\tif (converter.property)\n\t\t\t\t\t{\n\t\t\t\t\t\t// print block opener\n\t\t\t\t\t\tscss += opener(converter);\n\t\t\t\t\t\t// push new stack context\n\t\t\t\t\t\tconverter.indents.push(\"\");\n\t\t\t\t\t\t// store block indentation\n\t\t\t\t\t\tINDENT(converter) = indent;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// is and will be a src comment\n\t\t\t\telse if (!IS_CSS_COMMENT(converter))\n\t\t\t\t{\n\t\t\t\t\t// scss does not allow multiline src comments\n\t\t\t\t\t// therefore add forward slashes to all lines\n\t\t\t\t\tsass.at(INDENT(converter).length()+0) = '/';\n\t\t\t\t\t// there is an edge case here if indentation\n\t\t\t\t\t// is minimal (will overwrite the fist char)\n\t\t\t\t\tsass.at(INDENT(converter).length()+1) = '/';\n\t\t\t\t\t// could code around that, but I dont' think\n\t\t\t\t\t// this will ever be the cause for any trouble\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// line is opening a new comment\n\t\t\tif (open == \"/*\" || open == \"//\")\n\t\t\t{\n\t\t\t\t// reset the property state\n\t\t\t\tconverter.property = false;\n\t\t\t\t// close previous comment\n\t\t\t\tif (IS_CSS_COMMENT(converter) && open != \"\")\n\t\t\t\t{\n\t\t\t\t\tif (!STRIP_COMMENT(converter) && !CONVERT_COMMENT(converter)) scss += \" */\";\n\t\t\t\t}\n\t\t\t\t// force single line comments\n\t\t\t\t// into a correct css comment\n\t\t\t\tif (CONVERT_COMMENT(converter))\n\t\t\t\t{\n\t\t\t\t\tif (IS_PARSING(converter))\n\t\t\t\t\t{ sass.at(pos_left + 1) = '*'; }\n\t\t\t\t}\n\t\t\t\t// set comment flag\n\t\t\t\tconverter.comment = open;\n\n\t\t\t}\n\n\t\t\t// flush data only under certain conditions\n\t\t\tif (!(\n\t\t\t\t// strip css and src comments if option is set\n\t\t\t\t(IS_COMMENT(converter) && STRIP_COMMENT(converter)) ||\n\t\t\t\t// strip src comment even if strip option is not set\n\t\t\t\t// but only if the keep src comment option is not set\n\t\t\t\t(IS_SRC_COMMENT(converter) && ! KEEP_COMMENT(converter))\n\t\t\t))\n\t\t\t{\n\t\t\t\t// flush data and buffer whitespace\n\t\t\t\tscss += flush(sass, converter);\n\t\t\t}\n\n\t\t\t// get position of last meaningfull char\n\t\t\tsize_t pos_right = sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE);\n\n\t\t\t// check for invalid result\n\t\t\tif (pos_right != std::string::npos)\n\t\t\t{\n\n\t\t\t\t// get the last meaningfull char\n\t\t\t\tstd::string close = sass.substr(pos_right, 1);\n\n\t\t\t\t// check if next line should be concatenated (list mode)\n\t\t\t\tconverter.comma = IS_PARSING(converter) && close == \",\";\n\t\t\t\tconverter.semicolon = IS_PARSING(converter) && close == \";\";\n\n\t\t\t\t// check if we have more than\n\t\t\t\t// one meaningfull char\n\t\t\t\tif (pos_right > 0)\n\t\t\t\t{\n\n\t\t\t\t\t// get the last two chars from string\n\t\t\t\t\tstd::string close = sass.substr(pos_right - 1, 2);\n\t\t\t\t\t// update parser status for expicitly closed comment\n\t\t\t\t\tif (close == \"*/\") converter.comment = \"\";\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t\t// EO have meaningfull chars from end\n\n\t\t}\n\t\t// EO have meaningfull chars from start\n\n\t\t// return scss\n\t\treturn scss;\n\n\t}\n\t// EO process\n\n\t// read line with either CR, LF or CR LF format\n\t// http://stackoverflow.com/a/6089413/1550314\n\tstatic std::istream& safeGetline(std::istream& is, std::string& t)\n\t{\n\t\tt.clear();\n\n\t\t// The characters in the stream are read one-by-one using a std::streambuf.\n\t\t// That is faster than reading them one-by-one using the std::istream.\n\t\t// Code that uses streambuf this way must be guarded by a sentry object.\n\t\t// The sentry object performs various tasks,\n\t\t// such as thread synchronization and updating the stream state.\n\n\t\tstd::istream::sentry se(is, true);\n\t\tstd::streambuf* sb = is.rdbuf();\n\n\t\tfor(;;) {\n\t\t\tint c = sb->sbumpc();\n\t\t\tswitch (c) {\n\t\t\t\tcase '\\n':\n\t\t\t\t\treturn is;\n\t\t\t\tcase '\\r':\n\t\t\t\t\tif(sb->sgetc() == '\\n')\n\t\t\t\t\t\tsb->sbumpc();\n\t\t\t\t\treturn is;\n\t\t\t\tcase EOF:\n\t\t\t\t\t// Also handle the case when the last line has no line ending\n\t\t\t\t\tif(t.empty())\n\t\t\t\t\t\tis.setstate(std::ios::eofbit);\n\t\t\t\t\treturn is;\n\t\t\t\tdefault:\n\t\t\t\t\tt += (char)c;\n\t\t\t}\n\t\t}\n\t}\n\n\t// the main converter function for c++\n\tchar* sass2scss (const std::string& sass, const int options)\n\t{\n\n\t\t// local variables\n\t\tstd::string line;\n\t\tstd::string scss = \"\";\n\t\tstd::stringstream stream(sass);\n\n\t\t// create converter variable\n\t\tconverter converter;\n\t\t// initialise all options\n\t\tconverter.comma = false;\n\t\tconverter.property = false;\n\t\tconverter.selector = false;\n\t\tconverter.semicolon = false;\n\t\tconverter.end_of_file = false;\n\t\tconverter.comment = \"\";\n\t\tconverter.whitespace = \"\";\n\t\tconverter.indents.push(\"\");\n\t\tconverter.options = options;\n\n\t\t// read line by line and process them\n\t\twhile(safeGetline(stream, line) && !stream.eof())\n\t\t{ scss += process(line, converter); }\n\n\t\t// create mutable string\n\t\tstd::string closer = \"\";\n\t\t// set the end of file flag\n\t\tconverter.end_of_file = true;\n\t\t// process to close all open blocks\n\t\tscss += process(closer, converter);\n\n\t\t// allocate new memory on the heap\n\t\t// caller has to free it after use\n\t\tchar * cstr = (char*) malloc (scss.length() + 1);\n\t\t// create a copy of the string\n\t\tstrcpy (cstr, scss.c_str());\n\t\t// return pointer\n\t\treturn &cstr[0];\n\n\t}\n\t// EO sass2scss\n\n}\n// EO namespace\n\n// implement for c\nextern \"C\"\n{\n\n\tchar* ADDCALL sass2scss (const char* sass, const int options)\n\t{\n\t\treturn Sass::sass2scss(sass, options);\n\t}\n\n\t// Get compiled sass2scss version\n\tconst char* ADDCALL sass2scss_version(void) {\n\t\treturn SASS2SCSS_VERSION;\n\t}\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass_context.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n#include \"ast.hpp\"\n\n#include \"sass_functions.hpp\"\n#include \"json.hpp\"\n\n#define LFEED \"\\n\"\n\n// C++ helper\nnamespace Sass {\n  // see sass_copy_c_string(sass::string str)\n  static inline JsonNode* json_mkstream(const sass::ostream& stream)\n  {\n    // hold on to string on stack!\n    sass::string str(stream.str());\n    return json_mkstring(str.c_str());\n  }\n\n  static void handle_string_error(Sass_Context* c_ctx, const sass::string& msg, int severety)\n  {\n    sass::ostream msg_stream;\n    JsonNode* json_err = json_mkobject();\n    msg_stream << \"Internal Error: \" << msg << std::endl;\n    json_append_member(json_err, \"status\", json_mknumber(severety));\n    json_append_member(json_err, \"message\", json_mkstring(msg.c_str()));\n    json_append_member(json_err, \"formatted\", json_mkstream(msg_stream));\n    try { c_ctx->error_json = json_stringify(json_err, \"  \"); }\n    catch (...) {}\n    c_ctx->error_message = sass_copy_string(msg_stream.str());\n    c_ctx->error_text = sass_copy_c_string(msg.c_str());\n    c_ctx->error_status = severety;\n    c_ctx->output_string = 0;\n    c_ctx->source_map_string = 0;\n    json_delete(json_err);\n  }\n\n  static int handle_error(Sass_Context* c_ctx) {\n    try {\n      throw;\n    }\n    catch (Exception::Base& e) {\n      sass::ostream msg_stream;\n      sass::string cwd(Sass::File::get_cwd());\n      sass::string msg_prefix(e.errtype());\n      bool got_newline = false;\n      msg_stream << msg_prefix << \": \";\n      const char* msg = e.what();\n      while (msg && *msg) {\n        if (*msg == '\\r') {\n          got_newline = true;\n        }\n        else if (*msg == '\\n') {\n          got_newline = true;\n        }\n        else if (got_newline) {\n          msg_stream << sass::string(msg_prefix.size() + 2, ' ');\n          got_newline = false;\n        }\n        msg_stream << *msg;\n        ++msg;\n      }\n      if (!got_newline) msg_stream << \"\\n\";\n\n      if (e.traces.empty()) {\n        // we normally should have some traces, still here as a fallback\n        sass::string rel_path(Sass::File::abs2rel(e.pstate.getPath(), cwd, cwd));\n        msg_stream << sass::string(msg_prefix.size() + 2, ' ');\n        msg_stream << \" on line \" << e.pstate.getLine() << \" of \" << rel_path << \"\\n\";\n      }\n      else {\n        sass::string rel_path(Sass::File::abs2rel(e.pstate.getPath(), cwd, cwd));\n        msg_stream << traces_to_string(e.traces, \"        \");\n      }\n\n      // now create the code trace (ToDo: maybe have util functions?)\n      if (e.pstate.position.line != sass::string::npos &&\n          e.pstate.position.column != sass::string::npos &&\n          e.pstate.getRawData() != nullptr &&\n          e.pstate.source != nullptr) {\n        Offset offset(e.pstate.position);\n        size_t lines = offset.line;\n        // scan through src until target line\n        // move line_beg pointer to line start\n        const char* line_beg;\n        for (line_beg = e.pstate.getRawData(); *line_beg != '\\0'; ++line_beg) {\n          if (lines == 0) break;\n          if (*line_beg == '\\n') --lines;\n        }\n        // move line_end before next newline character\n        const char* line_end;\n        for (line_end = line_beg; *line_end != '\\0'; ++line_end) {\n          if (*line_end == '\\n' || *line_end == '\\r') break;\n        }\n        if (*line_end != '\\0') ++line_end;\n        size_t line_len = line_end - line_beg;\n        size_t move_in = 0; size_t shorten = 0;\n        size_t left_chars = 42; size_t max_chars = 76;\n        // reported excerpt should not exceed `max_chars` chars\n        if (offset.column > line_len) left_chars = offset.column;\n        if (offset.column > left_chars) move_in = offset.column - left_chars;\n        if (line_len > max_chars + move_in) shorten = line_len - move_in - max_chars;\n        utf8::advance(line_beg, move_in, line_end);\n        utf8::retreat(line_end, shorten, line_beg);\n        sass::string sanitized; sass::string marker(offset.column - move_in, '-');\n        utf8::replace_invalid(line_beg, line_end, std::back_inserter(sanitized));\n        msg_stream << \">> \" << sanitized << \"\\n\";\n        msg_stream << \"   \" << marker << \"^\\n\";\n      }\n\n      JsonNode* json_err = json_mkobject();\n      json_append_member(json_err, \"status\", json_mknumber(1));\n      json_append_member(json_err, \"file\", json_mkstring(e.pstate.getPath()));\n      json_append_member(json_err, \"line\", json_mknumber((double)(e.pstate.getLine())));\n      json_append_member(json_err, \"column\", json_mknumber((double)(e.pstate.getColumn())));\n      json_append_member(json_err, \"message\", json_mkstring(e.what()));\n      json_append_member(json_err, \"formatted\", json_mkstream(msg_stream));\n      try { c_ctx->error_json = json_stringify(json_err, \"  \"); }\n      catch (...) {} // silently ignore this error?\n      c_ctx->error_message = sass_copy_string(msg_stream.str());\n      c_ctx->error_text = sass_copy_c_string(e.what());\n      c_ctx->error_status = 1;\n      c_ctx->error_file = sass_copy_c_string(e.pstate.getPath());\n      c_ctx->error_line = e.pstate.getLine();\n      c_ctx->error_column = e.pstate.getColumn();\n      c_ctx->error_src = sass_copy_c_string(e.pstate.getRawData());\n      c_ctx->output_string = 0;\n      c_ctx->source_map_string = 0;\n      json_delete(json_err);\n    }\n    catch (std::bad_alloc& ba) {\n      sass::ostream msg_stream;\n      msg_stream << \"Unable to allocate memory: \" << ba.what();\n      handle_string_error(c_ctx, msg_stream.str(), 2);\n    }\n    catch (std::exception& e) {\n      handle_string_error(c_ctx, e.what(), 3);\n    }\n    catch (sass::string& e) {\n      handle_string_error(c_ctx, e, 4);\n    }\n    catch (const char* e) {\n      handle_string_error(c_ctx, e, 4);\n    }\n    catch (...) {\n      handle_string_error(c_ctx, \"unknown\", 5);\n    }\n    return c_ctx->error_status;\n  }\n\n  // allow one error handler to throw another error\n  // this can happen with invalid utf8 and json lib\n  static int handle_errors(Sass_Context* c_ctx) {\n    try { return handle_error(c_ctx); }\n    catch (...) { return handle_error(c_ctx); }\n  }\n\n  static Block_Obj sass_parse_block(Sass_Compiler* compiler) throw()\n  {\n\n    // assert valid pointer\n    if (compiler == 0) return {};\n    // The cpp context must be set by now\n    Context* cpp_ctx = compiler->cpp_ctx;\n    Sass_Context* c_ctx = compiler->c_ctx;\n    // We will take care to wire up the rest\n    compiler->cpp_ctx->c_compiler = compiler;\n    compiler->state = SASS_COMPILER_PARSED;\n\n    try {\n\n      // get input/output path from options\n      sass::string input_path = safe_str(c_ctx->input_path);\n      sass::string output_path = safe_str(c_ctx->output_path);\n\n      // maybe skip some entries of included files\n      // we do not include stdin for data contexts\n      bool skip = c_ctx->type == SASS_CONTEXT_DATA;\n\n      // dispatch parse call\n      Block_Obj root(cpp_ctx->parse());\n      // abort on errors\n      if (!root) return {};\n\n      // skip all prefixed files? (ToDo: check srcmap)\n      // IMO source-maps should point to headers already\n      // therefore don't skip it for now. re-enable or\n      // remove completely once this is tested\n      size_t headers = cpp_ctx->head_imports;\n\n      // copy the included files on to the context (dont forget to free later)\n      if (copy_strings(cpp_ctx->get_included_files(skip, headers), &c_ctx->included_files) == NULL)\n        throw(std::bad_alloc());\n\n      // return parsed block\n      return root;\n\n    }\n    // pass errors to generic error handler\n    catch (...) { handle_errors(c_ctx); }\n\n    // error\n    return {};\n\n  }\n\n}\n\nextern \"C\" {\n  using namespace Sass;\n\n  static void sass_clear_options (struct Sass_Options* options);\n  static void sass_reset_options (struct Sass_Options* options);\n  static void copy_options(struct Sass_Options* to, struct Sass_Options* from) {\n    // do not overwrite ourself\n    if (to == from) return;\n    // free assigned memory\n    sass_clear_options(to);\n    // move memory\n    *to = *from;\n    // Reset pointers on source\n    sass_reset_options(from);\n  }\n\n  #define IMPLEMENT_SASS_OPTION_ACCESSOR(type, option) \\\n    type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return options->option; } \\\n    void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) { options->option = option; }\n  #define IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \\\n    type ADDCALL sass_option_get_##option (struct Sass_Options* options) { return safe_str(options->option, def); }\n  #define IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def) \\\n    void ADDCALL sass_option_set_##option (struct Sass_Options* options, type option) \\\n    { free(options->option); options->option = option || def ? sass_copy_c_string(option ? option : def) : 0; }\n  #define IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(type, option, def) \\\n    IMPLEMENT_SASS_OPTION_STRING_GETTER(type, option, def) \\\n    IMPLEMENT_SASS_OPTION_STRING_SETTER(type, option, def)\n\n  #define IMPLEMENT_SASS_CONTEXT_GETTER(type, option) \\\n    type ADDCALL sass_context_get_##option (struct Sass_Context* ctx) { return ctx->option; }\n  #define IMPLEMENT_SASS_CONTEXT_TAKER(type, option) \\\n    type sass_context_take_##option (struct Sass_Context* ctx) \\\n    { type foo = ctx->option; ctx->option = 0; return foo; }\n\n\n  // generic compilation function (not exported, use file/data compile instead)\n  static Sass_Compiler* sass_prepare_context (Sass_Context* c_ctx, Context* cpp_ctx) throw()\n  {\n    try {\n      // register our custom functions\n      if (c_ctx->c_functions) {\n        auto this_func_data = c_ctx->c_functions;\n        while (this_func_data && *this_func_data) {\n          cpp_ctx->add_c_function(*this_func_data);\n          ++this_func_data;\n        }\n      }\n\n      // register our custom headers\n      if (c_ctx->c_headers) {\n        auto this_head_data = c_ctx->c_headers;\n        while (this_head_data && *this_head_data) {\n          cpp_ctx->add_c_header(*this_head_data);\n          ++this_head_data;\n        }\n      }\n\n      // register our custom importers\n      if (c_ctx->c_importers) {\n        auto this_imp_data = c_ctx->c_importers;\n        while (this_imp_data && *this_imp_data) {\n          cpp_ctx->add_c_importer(*this_imp_data);\n          ++this_imp_data;\n        }\n      }\n\n      // reset error status\n      c_ctx->error_json = 0;\n      c_ctx->error_text = 0;\n      c_ctx->error_message = 0;\n      c_ctx->error_status = 0;\n      // reset error position\n      c_ctx->error_file = 0;\n      c_ctx->error_src = 0;\n      c_ctx->error_line = sass::string::npos;\n      c_ctx->error_column = sass::string::npos;\n\n      // allocate a new compiler instance\n      void* ctxmem = calloc(1, sizeof(struct Sass_Compiler));\n      if (ctxmem == 0) { std::cerr << \"Error allocating memory for context\" << std::endl; return 0; }\n      Sass_Compiler* compiler = (struct Sass_Compiler*) ctxmem;\n      compiler->state = SASS_COMPILER_CREATED;\n\n      // store in sass compiler\n      compiler->c_ctx = c_ctx;\n      compiler->cpp_ctx = cpp_ctx;\n      cpp_ctx->c_compiler = compiler;\n\n      // use to parse block\n      return compiler;\n\n    }\n    // pass errors to generic error handler\n    catch (...) { handle_errors(c_ctx); }\n\n    // error\n    return 0;\n\n  }\n\n  // generic compilation function (not exported, use file/data compile instead)\n  static int sass_compile_context (Sass_Context* c_ctx, Context* cpp_ctx)\n  {\n\n    // prepare sass compiler with context and options\n    Sass_Compiler* compiler = sass_prepare_context(c_ctx, cpp_ctx);\n\n    try {\n      // call each compiler step\n      sass_compiler_parse(compiler);\n      sass_compiler_execute(compiler);\n    }\n    // pass errors to generic error handler\n    catch (...) { handle_errors(c_ctx); }\n\n    sass_delete_compiler(compiler);\n\n    return c_ctx->error_status;\n  }\n\n  inline void init_options (struct Sass_Options* options)\n  {\n    options->precision = 10;\n    options->indent = \"  \";\n    options->linefeed = LFEED;\n  }\n\n  Sass_Options* ADDCALL sass_make_options (void)\n  {\n    struct Sass_Options* options = (struct Sass_Options*) calloc(1, sizeof(struct Sass_Options));\n    if (options == 0) { std::cerr << \"Error allocating memory for options\" << std::endl; return 0; }\n    init_options(options);\n    return options;\n  }\n\n  Sass_File_Context* ADDCALL sass_make_file_context(const char* input_path)\n  {\n    #ifdef DEBUG_SHARED_PTR\n    SharedObj::setTaint(true);\n    #endif\n    struct Sass_File_Context* ctx = (struct Sass_File_Context*) calloc(1, sizeof(struct Sass_File_Context));\n    if (ctx == 0) { std::cerr << \"Error allocating memory for file context\" << std::endl; return 0; }\n    ctx->type = SASS_CONTEXT_FILE;\n    init_options(ctx);\n    try {\n      if (input_path == 0) { throw(std::runtime_error(\"File context created without an input path\")); }\n      if (*input_path == 0) { throw(std::runtime_error(\"File context created with empty input path\")); }\n      sass_option_set_input_path(ctx, input_path);\n    } catch (...) {\n      handle_errors(ctx);\n    }\n    return ctx;\n  }\n\n  Sass_Data_Context* ADDCALL sass_make_data_context(char* source_string)\n  {\n    #ifdef DEBUG_SHARED_PTR\n    SharedObj::setTaint(true);\n    #endif\n    struct Sass_Data_Context* ctx = (struct Sass_Data_Context*) calloc(1, sizeof(struct Sass_Data_Context));\n    if (ctx == 0) { std::cerr << \"Error allocating memory for data context\" << std::endl; return 0; }\n    ctx->type = SASS_CONTEXT_DATA;\n    init_options(ctx);\n    try {\n      if (source_string == 0) { throw(std::runtime_error(\"Data context created without a source string\")); }\n      if (*source_string == 0) { throw(std::runtime_error(\"Data context created with empty source string\")); }\n      ctx->source_string = source_string;\n    } catch (...) {\n      handle_errors(ctx);\n    }\n    return ctx;\n  }\n\n  struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx)\n  {\n    if (data_ctx == 0) return 0;\n    Context* cpp_ctx = new Data_Context(*data_ctx);\n    return sass_prepare_context(data_ctx, cpp_ctx);\n  }\n\n  struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_Context* file_ctx)\n  {\n    if (file_ctx == 0) return 0;\n    Context* cpp_ctx = new File_Context(*file_ctx);\n    return sass_prepare_context(file_ctx, cpp_ctx);\n  }\n\n  int ADDCALL sass_compile_data_context(Sass_Data_Context* data_ctx)\n  {\n    if (data_ctx == 0) return 1;\n    if (data_ctx->error_status)\n      return data_ctx->error_status;\n    try {\n      if (data_ctx->source_string == 0) { throw(std::runtime_error(\"Data context has no source string\")); }\n      // empty source string is a valid case, even if not really useful (different than with file context)\n      // if (*data_ctx->source_string == 0) { throw(std::runtime_error(\"Data context has empty source string\")); }\n    }\n    catch (...) { return handle_errors(data_ctx) | 1; }\n    Context* cpp_ctx = new Data_Context(*data_ctx);\n    return sass_compile_context(data_ctx, cpp_ctx);\n  }\n\n  int ADDCALL sass_compile_file_context(Sass_File_Context* file_ctx)\n  {\n    if (file_ctx == 0) return 1;\n    if (file_ctx->error_status)\n      return file_ctx->error_status;\n    try {\n      if (file_ctx->input_path == 0) { throw(std::runtime_error(\"File context has no input path\")); }\n      if (*file_ctx->input_path == 0) { throw(std::runtime_error(\"File context has empty input path\")); }\n    }\n    catch (...) { return handle_errors(file_ctx) | 1; }\n    Context* cpp_ctx = new File_Context(*file_ctx);\n    return sass_compile_context(file_ctx, cpp_ctx);\n  }\n\n  int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler)\n  {\n    if (compiler == 0) return 1;\n    if (compiler->state == SASS_COMPILER_PARSED) return 0;\n    if (compiler->state != SASS_COMPILER_CREATED) return -1;\n    if (compiler->c_ctx == NULL) return 1;\n    if (compiler->cpp_ctx == NULL) return 1;\n    if (compiler->c_ctx->error_status)\n      return compiler->c_ctx->error_status;\n    // parse the context we have set up (file or data)\n    compiler->root = sass_parse_block(compiler);\n    // success\n    return 0;\n  }\n\n  int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler)\n  {\n    if (compiler == 0) return 1;\n    if (compiler->state == SASS_COMPILER_EXECUTED) return 0;\n    if (compiler->state != SASS_COMPILER_PARSED) return -1;\n    if (compiler->c_ctx == NULL) return 1;\n    if (compiler->cpp_ctx == NULL) return 1;\n    if (compiler->root.isNull()) return 1;\n    if (compiler->c_ctx->error_status)\n      return compiler->c_ctx->error_status;\n    compiler->state = SASS_COMPILER_EXECUTED;\n    Context* cpp_ctx = compiler->cpp_ctx;\n    Block_Obj root = compiler->root;\n    // compile the parsed root block\n    try { compiler->c_ctx->output_string = cpp_ctx->render(root); }\n    // pass catched errors to generic error handler\n    catch (...) { return handle_errors(compiler->c_ctx) | 1; }\n    // generate source map json and store on context\n    compiler->c_ctx->source_map_string = cpp_ctx->render_srcmap();\n    // success\n    return 0;\n  }\n\n  // helper function, not exported, only accessible locally\n  static void sass_reset_options (struct Sass_Options* options)\n  {\n    // free pointer before\n    // or copy/move them\n    options->input_path = 0;\n    options->output_path = 0;\n    options->plugin_path = 0;\n    options->include_path = 0;\n    options->source_map_file = 0;\n    options->source_map_root = 0;\n    options->c_functions = 0;\n    options->c_importers = 0;\n    options->c_headers = 0;\n    options->plugin_paths = 0;\n    options->include_paths = 0;\n  }\n\n  // helper function, not exported, only accessible locally\n  static void sass_clear_options (struct Sass_Options* options)\n  {\n    if (options == 0) return;\n    // Deallocate custom functions, headers and imports\n    sass_delete_function_list(options->c_functions);\n    sass_delete_importer_list(options->c_importers);\n    sass_delete_importer_list(options->c_headers);\n    // Deallocate inc paths\n    if (options->plugin_paths) {\n      struct string_list* cur;\n      struct string_list* next;\n      cur = options->plugin_paths;\n      while (cur) {\n        next = cur->next;\n        free(cur->string);\n        free(cur);\n        cur = next;\n      }\n    }\n    // Deallocate inc paths\n    if (options->include_paths) {\n      struct string_list* cur;\n      struct string_list* next;\n      cur = options->include_paths;\n      while (cur) {\n        next = cur->next;\n        free(cur->string);\n        free(cur);\n        cur = next;\n      }\n    }\n    // Free options strings\n    free(options->input_path);\n    free(options->output_path);\n    free(options->plugin_path);\n    free(options->include_path);\n    free(options->source_map_file);\n    free(options->source_map_root);\n    // Reset our pointers\n    options->input_path = 0;\n    options->output_path = 0;\n    options->plugin_path = 0;\n    options->include_path = 0;\n    options->source_map_file = 0;\n    options->source_map_root = 0;\n    options->c_functions = 0;\n    options->c_importers = 0;\n    options->c_headers = 0;\n    options->plugin_paths = 0;\n    options->include_paths = 0;\n  }\n\n  // helper function, not exported, only accessible locally\n  // sass_free_context is also defined in old sass_interface\n  static void sass_clear_context (struct Sass_Context* ctx)\n  {\n    if (ctx == 0) return;\n    // release the allocated memory (mostly via sass_copy_c_string)\n    if (ctx->output_string)     free(ctx->output_string);\n    if (ctx->source_map_string) free(ctx->source_map_string);\n    if (ctx->error_message)     free(ctx->error_message);\n    if (ctx->error_text)        free(ctx->error_text);\n    if (ctx->error_json)        free(ctx->error_json);\n    if (ctx->error_file)        free(ctx->error_file);\n    if (ctx->error_src)         free(ctx->error_src);\n    free_string_array(ctx->included_files);\n    // play safe and reset properties\n    ctx->output_string = 0;\n    ctx->source_map_string = 0;\n    ctx->error_message = 0;\n    ctx->error_text = 0;\n    ctx->error_json = 0;\n    ctx->error_file = 0;\n    ctx->error_src = 0;\n    ctx->included_files = 0;\n    // debug leaked memory\n    #ifdef DEBUG_SHARED_PTR\n      SharedObj::dumpMemLeaks();\n    #endif\n    // now clear the options\n    sass_clear_options(ctx);\n  }\n\n  void ADDCALL sass_delete_compiler (struct Sass_Compiler* compiler)\n  {\n    if (compiler == 0) {\n      return;\n    }\n    Context* cpp_ctx = compiler->cpp_ctx;\n    if (cpp_ctx) delete(cpp_ctx);\n    compiler->cpp_ctx = NULL;\n    compiler->c_ctx = NULL;\n    compiler->root = {};\n    free(compiler);\n  }\n\n  void ADDCALL sass_delete_options (struct Sass_Options* options)\n  {\n    sass_clear_options(options); free(options);\n  }\n\n  // Deallocate all associated memory with file context\n  void ADDCALL sass_delete_file_context (struct Sass_File_Context* ctx)\n  {\n    // clear the context and free it\n    sass_clear_context(ctx); free(ctx);\n  }\n  // Deallocate all associated memory with data context\n  void ADDCALL sass_delete_data_context (struct Sass_Data_Context* ctx)\n  {\n    // clean the source string if it was not passed\n    // we reset this member once we start parsing\n    if (ctx->source_string) free(ctx->source_string);\n    // clear the context and free it\n    sass_clear_context(ctx); free(ctx);\n  }\n\n  // Getters for sass context from specific implementations\n  struct Sass_Context* ADDCALL sass_file_context_get_context(struct Sass_File_Context* ctx) { return ctx; }\n  struct Sass_Context* ADDCALL sass_data_context_get_context(struct Sass_Data_Context* ctx) { return ctx; }\n\n  // Getters for context options from Sass_Context\n  struct Sass_Options* ADDCALL sass_context_get_options(struct Sass_Context* ctx) { return ctx; }\n  struct Sass_Options* ADDCALL sass_file_context_get_options(struct Sass_File_Context* ctx) { return ctx; }\n  struct Sass_Options* ADDCALL sass_data_context_get_options(struct Sass_Data_Context* ctx) { return ctx; }\n  void ADDCALL sass_file_context_set_options (struct Sass_File_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }\n  void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }\n\n  // Getters for Sass_Compiler options (get connected sass context)\n  enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler) { return compiler->state; }\n  struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler) { return compiler->c_ctx; }\n  struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compiler* compiler) { return compiler->c_ctx; }\n  // Getters for Sass_Compiler options (query import stack)\n  size_t ADDCALL sass_compiler_get_import_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.size(); }\n  Sass_Import_Entry ADDCALL sass_compiler_get_last_import(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->import_stack.back(); }\n  Sass_Import_Entry ADDCALL sass_compiler_get_import_entry(struct Sass_Compiler* compiler, size_t idx) { return compiler->cpp_ctx->import_stack[idx]; }\n  // Getters for Sass_Compiler options (query function stack)\n  size_t ADDCALL sass_compiler_get_callee_stack_size(struct Sass_Compiler* compiler) { return compiler->cpp_ctx->callee_stack.size(); }\n  Sass_Callee_Entry ADDCALL sass_compiler_get_last_callee(struct Sass_Compiler* compiler) { return &compiler->cpp_ctx->callee_stack.back(); }\n  Sass_Callee_Entry ADDCALL sass_compiler_get_callee_entry(struct Sass_Compiler* compiler, size_t idx) { return &compiler->cpp_ctx->callee_stack[idx]; }\n\n  // Calculate the size of the stored null terminated array\n  size_t ADDCALL sass_context_get_included_files_size (struct Sass_Context* ctx)\n  { size_t l = 0; auto i = ctx->included_files; while (i && *i) { ++i; ++l; } return l; }\n\n  // Create getter and setters for options\n  IMPLEMENT_SASS_OPTION_ACCESSOR(int, precision);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(enum Sass_Output_Style, output_style);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_comments);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_embed);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_contents);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, source_map_file_urls);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, omit_source_map_url);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(bool, is_indented_syntax_src);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Function_List, c_functions);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_importers);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(Sass_Importer_List, c_headers);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, indent);\n  IMPLEMENT_SASS_OPTION_ACCESSOR(const char*, linefeed);\n  IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, plugin_path, 0);\n  IMPLEMENT_SASS_OPTION_STRING_SETTER(const char*, include_path, 0);\n  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, input_path, 0);\n  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, output_path, 0);\n  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_file, 0);\n  IMPLEMENT_SASS_OPTION_STRING_ACCESSOR(const char*, source_map_root, 0);\n\n  // Create getter and setters for context\n  IMPLEMENT_SASS_CONTEXT_GETTER(int, error_status);\n  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_json);\n  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_message);\n  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_text);\n  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_file);\n  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_src);\n  IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_line);\n  IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_column);\n  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, output_string);\n  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, source_map_string);\n  IMPLEMENT_SASS_CONTEXT_GETTER(char**, included_files);\n\n  // Take ownership of memory (value on context is set to 0)\n  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_json);\n  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_message);\n  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_text);\n  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_file);\n  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_src);\n  IMPLEMENT_SASS_CONTEXT_TAKER(char*, output_string);\n  IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string);\n  IMPLEMENT_SASS_CONTEXT_TAKER(char**, included_files);\n\n  // Push function for include paths (no manipulation support for now)\n  void ADDCALL sass_option_push_include_path(struct Sass_Options* options, const char* path)\n  {\n\n    struct string_list* include_path = (struct string_list*) calloc(1, sizeof(struct string_list));\n    if (include_path == 0) return;\n    include_path->string = path ? sass_copy_c_string(path) : 0;\n    struct string_list* last = options->include_paths;\n    if (!options->include_paths) {\n      options->include_paths = include_path;\n    } else {\n      while (last->next)\n        last = last->next;\n      last->next = include_path;\n    }\n\n  }\n\n  // Push function for include paths (no manipulation support for now)\n  size_t ADDCALL sass_option_get_include_path_size(struct Sass_Options* options)\n  {\n    size_t len = 0;\n    struct string_list* cur = options->include_paths;\n    while (cur) { len ++; cur = cur->next; }\n    return len;\n  }\n\n  // Push function for include paths (no manipulation support for now)\n  const char* ADDCALL sass_option_get_include_path(struct Sass_Options* options, size_t i)\n  {\n    struct string_list* cur = options->include_paths;\n    while (i) { i--; cur = cur->next; }\n    return cur->string;\n  }\n\n  // Push function for plugin paths (no manipulation support for now)\n  size_t ADDCALL sass_option_get_plugin_path_size(struct Sass_Options* options)\n  {\n    size_t len = 0;\n    struct string_list* cur = options->plugin_paths;\n    while (cur) { len++; cur = cur->next; }\n    return len;\n  }\n\n  // Push function for plugin paths (no manipulation support for now)\n  const char* ADDCALL sass_option_get_plugin_path(struct Sass_Options* options, size_t i)\n  {\n    struct string_list* cur = options->plugin_paths;\n    while (i) { i--; cur = cur->next; }\n    return cur->string;\n  }\n\n  // Push function for plugin paths (no manipulation support for now)\n  void ADDCALL sass_option_push_plugin_path(struct Sass_Options* options, const char* path)\n  {\n\n    struct string_list* plugin_path = (struct string_list*) calloc(1, sizeof(struct string_list));\n    if (plugin_path == 0) return;\n    plugin_path->string = path ? sass_copy_c_string(path) : 0;\n    struct string_list* last = options->plugin_paths;\n    if (!options->plugin_paths) {\n      options->plugin_paths = plugin_path;\n    } else {\n      while (last->next)\n        last = last->next;\n      last->next = plugin_path;\n    }\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass_context.hpp",
    "content": "#ifndef SASS_SASS_CONTEXT_H\n#define SASS_SASS_CONTEXT_H\n\n#include \"sass/base.h\"\n#include \"sass/context.h\"\n#include \"ast_fwd_decl.hpp\"\n\n// sass config options structure\nstruct Sass_Options : Sass_Output_Options {\n\n  // embed sourceMappingUrl as data uri\n  bool source_map_embed;\n\n  // embed include contents in maps\n  bool source_map_contents;\n\n  // create file urls for sources\n  bool source_map_file_urls;\n\n  // Disable sourceMappingUrl in css output\n  bool omit_source_map_url;\n\n  // Treat source_string as sass (as opposed to scss)\n  bool is_indented_syntax_src;\n\n  // The input path is used for source map\n  // generation. It can be used to define\n  // something with string compilation or to\n  // overload the input file path. It is\n  // set to \"stdin\" for data contexts and\n  // to the input file on file contexts.\n  char* input_path;\n\n  // The output path is used for source map\n  // generation. LibSass will not write to\n  // this file, it is just used to create\n  // information in source-maps etc.\n  char* output_path;\n\n  // Colon-separated list of paths\n  // Semicolon-separated on Windows\n  // Maybe use array interface instead?\n  char* include_path;\n  char* plugin_path;\n\n  // Include paths (linked string list)\n  struct string_list* include_paths;\n  // Plugin paths (linked string list)\n  struct string_list* plugin_paths;\n\n  // Path to source map file\n  // Enables source map generation\n  // Used to create sourceMappingUrl\n  char* source_map_file;\n\n  // Directly inserted in source maps\n  char* source_map_root;\n\n  // Custom functions that can be called from sccs code\n  Sass_Function_List c_functions;\n\n  // List of custom importers\n  Sass_Importer_List c_importers;\n\n  // List of custom headers\n  Sass_Importer_List c_headers;\n\n};\n\n\n// base for all contexts\nstruct Sass_Context : Sass_Options\n{\n\n  // store context type info\n  enum Sass_Input_Style type;\n\n  // generated output data\n  char* output_string;\n\n  // generated source map json\n  char* source_map_string;\n\n  // error status\n  int error_status;\n  char* error_json;\n  char* error_text;\n  char* error_message;\n  // error position\n  char* error_file;\n  size_t error_line;\n  size_t error_column;\n  char* error_src;\n\n  // report imported files\n  char** included_files;\n\n};\n\n// struct for file compilation\nstruct Sass_File_Context : Sass_Context {\n\n  // no additional fields required\n  // input_path is already on options\n\n};\n\n// struct for data compilation\nstruct Sass_Data_Context : Sass_Context {\n\n  // provided source string\n  char* source_string;\n  char* srcmap_string;\n\n};\n\n// link c and cpp context\nstruct Sass_Compiler {\n  // progress status\n  Sass_Compiler_State state;\n  // original c context\n  Sass_Context* c_ctx;\n  // Sass::Context\n  Sass::Context* cpp_ctx;\n  // Sass::Block\n  Sass::Block_Obj root;\n};\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass_functions.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <cstring>\n#include \"util.hpp\"\n#include \"context.hpp\"\n#include \"values.hpp\"\n#include \"sass/functions.h\"\n#include \"sass_functions.hpp\"\n\nextern \"C\" {\n  using namespace Sass;\n\n  Sass_Function_List ADDCALL sass_make_function_list(size_t length)\n  {\n    return (Sass_Function_List) calloc(length + 1, sizeof(Sass_Function_Entry));\n  }\n\n  Sass_Function_Entry ADDCALL sass_make_function(const char* signature, Sass_Function_Fn function, void* cookie)\n  {\n    Sass_Function_Entry cb = (Sass_Function_Entry) calloc(1, sizeof(Sass_Function));\n    if (cb == 0) return 0;\n    cb->signature = sass_copy_c_string(signature);\n    cb->function = function;\n    cb->cookie = cookie;\n    return cb;\n  }\n\n  void ADDCALL sass_delete_function(Sass_Function_Entry entry)\n  {\n    free(entry->signature);\n    free(entry);\n  }\n\n  // Deallocator for the allocated memory\n  void ADDCALL sass_delete_function_list(Sass_Function_List list)\n  {\n    Sass_Function_List it = list;\n    if (list == 0) return;\n    while(*list) {\n      sass_delete_function(*list);\n      ++list;\n    }\n    free(it);\n  }\n\n  // Setters and getters for callbacks on function lists\n  Sass_Function_Entry ADDCALL sass_function_get_list_entry(Sass_Function_List list, size_t pos) { return list[pos]; }\n  void sass_function_set_list_entry(Sass_Function_List list, size_t pos, Sass_Function_Entry cb) { list[pos] = cb; }\n\n  const char* ADDCALL sass_function_get_signature(Sass_Function_Entry cb) { return cb->signature; }\n  Sass_Function_Fn ADDCALL sass_function_get_function(Sass_Function_Entry cb) { return cb->function; }\n  void* ADDCALL sass_function_get_cookie(Sass_Function_Entry cb) { return cb->cookie; }\n\n  Sass_Importer_Entry ADDCALL sass_make_importer(Sass_Importer_Fn importer, double priority, void* cookie)\n  {\n    Sass_Importer_Entry cb = (Sass_Importer_Entry) calloc(1, sizeof(Sass_Importer));\n    if (cb == 0) return 0;\n    cb->importer = importer;\n    cb->priority = priority;\n    cb->cookie = cookie;\n    return cb;\n  }\n\n  Sass_Importer_Fn ADDCALL sass_importer_get_function(Sass_Importer_Entry cb) { return cb->importer; }\n  double ADDCALL sass_importer_get_priority (Sass_Importer_Entry cb) { return cb->priority; }\n  void* ADDCALL sass_importer_get_cookie(Sass_Importer_Entry cb) { return cb->cookie; }\n\n  // Just in case we have some stray import structs\n  void ADDCALL sass_delete_importer (Sass_Importer_Entry cb)\n  {\n    free(cb);\n  }\n\n  // Creator for sass custom importer function list\n  Sass_Importer_List ADDCALL sass_make_importer_list(size_t length)\n  {\n    return (Sass_Importer_List) calloc(length + 1, sizeof(Sass_Importer_Entry));\n  }\n\n  // Deallocator for the allocated memory\n  void ADDCALL sass_delete_importer_list(Sass_Importer_List list)\n  {\n    Sass_Importer_List it = list;\n    if (list == 0) return;\n    while(*list) {\n      sass_delete_importer(*list);\n      ++list;\n    }\n    free(it);\n  }\n\n  Sass_Importer_Entry ADDCALL sass_importer_get_list_entry(Sass_Importer_List list, size_t idx) { return list[idx]; }\n  void ADDCALL sass_importer_set_list_entry(Sass_Importer_List list, size_t idx, Sass_Importer_Entry cb) { list[idx] = cb; }\n\n  // Creator for sass custom importer return argument list\n  Sass_Import_List ADDCALL sass_make_import_list(size_t length)\n  {\n    return (Sass_Import**) calloc(length + 1, sizeof(Sass_Import*));\n  }\n\n  // Creator for a single import entry returned by the custom importer inside the list\n  // We take ownership of the memory for source and srcmap (freed when context is destroyed)\n  Sass_Import_Entry ADDCALL sass_make_import(const char* imp_path, const char* abs_path, char* source, char* srcmap)\n  {\n    Sass_Import* v = (Sass_Import*) calloc(1, sizeof(Sass_Import));\n    if (v == 0) return 0;\n    v->imp_path = imp_path ? sass_copy_c_string(imp_path) : 0;\n    v->abs_path = abs_path ? sass_copy_c_string(abs_path) : 0;\n    v->source = source;\n    v->srcmap = srcmap;\n    v->error = 0;\n    v->line = -1;\n    v->column = -1;\n    return v;\n  }\n\n  // Older style, but somehow still valid - keep around or deprecate?\n  Sass_Import_Entry ADDCALL sass_make_import_entry(const char* path, char* source, char* srcmap)\n  {\n    return sass_make_import(path, path, source, srcmap);\n  }\n\n  // Upgrade a normal import entry to throw an error (original path can be re-used by error reporting)\n  Sass_Import_Entry ADDCALL sass_import_set_error(Sass_Import_Entry import, const char* error, size_t line, size_t col)\n  {\n    if (import == 0) return 0;\n    if (import->error) free(import->error);\n    import->error = error ? sass_copy_c_string(error) : 0;\n    import->line = line ? line : -1;\n    import->column = col ? col : -1;\n    return import;\n  }\n\n  // Setters and getters for entries on the import list\n  void ADDCALL sass_import_set_list_entry(Sass_Import_List list, size_t idx, Sass_Import_Entry entry) { list[idx] = entry; }\n  Sass_Import_Entry ADDCALL sass_import_get_list_entry(Sass_Import_List list, size_t idx) { return list[idx]; }\n\n  // Deallocator for the allocated memory\n  void ADDCALL sass_delete_import_list(Sass_Import_List list)\n  {\n    Sass_Import_List it = list;\n    if (list == 0) return;\n    while(*list) {\n      sass_delete_import(*list);\n      ++list;\n    }\n    free(it);\n  }\n\n  // Just in case we have some stray import structs\n  void ADDCALL sass_delete_import(Sass_Import_Entry import)\n  {\n    free(import->imp_path);\n    free(import->abs_path);\n    free(import->source);\n    free(import->srcmap);\n    free(import->error);\n    free(import);\n  }\n\n  // Getter for callee entry\n  const char* ADDCALL sass_callee_get_name(Sass_Callee_Entry entry) { return entry->name; }\n  const char* ADDCALL sass_callee_get_path(Sass_Callee_Entry entry) { return entry->path; }\n  size_t ADDCALL sass_callee_get_line(Sass_Callee_Entry entry) { return entry->line; }\n  size_t ADDCALL sass_callee_get_column(Sass_Callee_Entry entry) { return entry->column; }\n  enum Sass_Callee_Type ADDCALL sass_callee_get_type(Sass_Callee_Entry entry) { return entry->type; }\n  Sass_Env_Frame ADDCALL sass_callee_get_env (Sass_Callee_Entry entry) { return &entry->env; }\n\n  // Getters and Setters for environments (lexical, local and global)\n  union Sass_Value* ADDCALL sass_env_get_lexical (Sass_Env_Frame env, const char* name) {\n    Expression* ex = Cast<Expression>((*env->frame)[name]);\n    return ex != NULL ? ast_node_to_sass_value(ex) : NULL;\n  }\n  void ADDCALL sass_env_set_lexical (Sass_Env_Frame env, const char* name, union Sass_Value* val) {\n    (*env->frame)[name] = sass_value_to_ast_node(val);\n  }\n  union Sass_Value* ADDCALL sass_env_get_local (Sass_Env_Frame env, const char* name) {\n    Expression* ex = Cast<Expression>(env->frame->get_local(name));\n    return ex != NULL ? ast_node_to_sass_value(ex) : NULL;\n  }\n  void ADDCALL sass_env_set_local (Sass_Env_Frame env, const char* name, union Sass_Value* val) {\n    env->frame->set_local(name, sass_value_to_ast_node(val));\n  }\n  union Sass_Value* ADDCALL sass_env_get_global (Sass_Env_Frame env, const char* name) {\n    Expression* ex = Cast<Expression>(env->frame->get_global(name));\n    return ex != NULL ? ast_node_to_sass_value(ex) : NULL;\n  }\n  void ADDCALL sass_env_set_global (Sass_Env_Frame env, const char* name, union Sass_Value* val) {\n    env->frame->set_global(name, sass_value_to_ast_node(val));\n  }\n\n  // Getter for import entry\n  const char* ADDCALL sass_import_get_imp_path(Sass_Import_Entry entry) { return entry->imp_path; }\n  const char* ADDCALL sass_import_get_abs_path(Sass_Import_Entry entry) { return entry->abs_path; }\n  const char* ADDCALL sass_import_get_source(Sass_Import_Entry entry) { return entry->source; }\n  const char* ADDCALL sass_import_get_srcmap(Sass_Import_Entry entry) { return entry->srcmap; }\n\n  // Getter for import error entry\n  size_t ADDCALL sass_import_get_error_line(Sass_Import_Entry entry) { return entry->line; }\n  size_t ADDCALL sass_import_get_error_column(Sass_Import_Entry entry) { return entry->column; }\n  const char* ADDCALL sass_import_get_error_message(Sass_Import_Entry entry) { return entry->error; }\n\n  // Explicit functions to take ownership of the memory\n  // Resets our own property since we do not know if it is still alive\n  char* ADDCALL sass_import_take_source(Sass_Import_Entry entry) { char* ptr = entry->source; entry->source = 0; return ptr; }\n  char* ADDCALL sass_import_take_srcmap(Sass_Import_Entry entry) { char* ptr = entry->srcmap; entry->srcmap = 0; return ptr; }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass_functions.hpp",
    "content": "#ifndef SASS_SASS_FUNCTIONS_H\n#define SASS_SASS_FUNCTIONS_H\n\n#include \"sass.h\"\n#include \"environment.hpp\"\n#include \"fn_utils.hpp\"\n\n// Struct to hold custom function callback\nstruct Sass_Function {\n  char*            signature;\n  Sass_Function_Fn function;\n  void*            cookie;\n};\n\n// External import entry\nstruct Sass_Import {\n  char* imp_path; // path as found in the import statement\n  char *abs_path; // path after importer has resolved it\n  char* source;\n  char* srcmap;\n  // error handling\n  char* error;\n  size_t line;\n  size_t column;\n};\n\n// External environments\nstruct Sass_Env {\n  // links to parent frames\n  Sass::Env* frame;\n};\n\n// External call entry\nstruct Sass_Callee {\n  const char* name;\n  const char* path;\n  size_t line;\n  size_t column;\n  enum Sass_Callee_Type type;\n  struct Sass_Env env;\n};\n\n// Struct to hold importer callback\nstruct Sass_Importer {\n  Sass_Importer_Fn importer;\n  double           priority;\n  void*            cookie;\n};\n\n#endif"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass_values.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <cstdlib>\n#include <cstring>\n#include \"util.hpp\"\n#include \"eval.hpp\"\n#include \"operators.hpp\"\n#include \"sass/values.h\"\n#include \"sass_values.hpp\"\n\nextern \"C\" {\n  using namespace Sass;\n\n  // Return the sass tag for a generic sass value\n  enum Sass_Tag ADDCALL sass_value_get_tag(const union Sass_Value* v) { return v->unknown.tag; }\n\n  // Check value for specified type\n  bool ADDCALL sass_value_is_null(const union Sass_Value* v) { return v->unknown.tag == SASS_NULL; }\n  bool ADDCALL sass_value_is_number(const union Sass_Value* v) { return v->unknown.tag == SASS_NUMBER; }\n  bool ADDCALL sass_value_is_string(const union Sass_Value* v) { return v->unknown.tag == SASS_STRING; }\n  bool ADDCALL sass_value_is_boolean(const union Sass_Value* v) { return v->unknown.tag == SASS_BOOLEAN; }\n  bool ADDCALL sass_value_is_color(const union Sass_Value* v) { return v->unknown.tag == SASS_COLOR; }\n  bool ADDCALL sass_value_is_list(const union Sass_Value* v) { return v->unknown.tag == SASS_LIST; }\n  bool ADDCALL sass_value_is_map(const union Sass_Value* v) { return v->unknown.tag == SASS_MAP; }\n  bool ADDCALL sass_value_is_error(const union Sass_Value* v) { return v->unknown.tag == SASS_ERROR; }\n  bool ADDCALL sass_value_is_warning(const union Sass_Value* v) { return v->unknown.tag == SASS_WARNING; }\n\n  // Getters and setters for Sass_Number\n  double ADDCALL sass_number_get_value(const union Sass_Value* v) { return v->number.value; }\n  void ADDCALL sass_number_set_value(union Sass_Value* v, double value) { v->number.value = value; }\n  const char* ADDCALL sass_number_get_unit(const union Sass_Value* v) { return v->number.unit; }\n  void ADDCALL sass_number_set_unit(union Sass_Value* v, char* unit) { v->number.unit = unit; }\n\n  // Getters and setters for Sass_String\n  const char* ADDCALL sass_string_get_value(const union Sass_Value* v) { return v->string.value; }\n  void ADDCALL sass_string_set_value(union Sass_Value* v, char* value) { v->string.value = value; }\n  bool ADDCALL sass_string_is_quoted(const union Sass_Value* v) { return v->string.quoted; }\n  void ADDCALL sass_string_set_quoted(union Sass_Value* v, bool quoted) { v->string.quoted = quoted; }\n\n  // Getters and setters for Sass_Boolean\n  bool ADDCALL sass_boolean_get_value(const union Sass_Value* v) { return v->boolean.value; }\n  void ADDCALL sass_boolean_set_value(union Sass_Value* v, bool value) { v->boolean.value = value; }\n\n  // Getters and setters for Sass_Color\n  double ADDCALL sass_color_get_r(const union Sass_Value* v) { return v->color.r; }\n  void ADDCALL sass_color_set_r(union Sass_Value* v, double r) { v->color.r = r; }\n  double ADDCALL sass_color_get_g(const union Sass_Value* v) { return v->color.g; }\n  void ADDCALL sass_color_set_g(union Sass_Value* v, double g) { v->color.g = g; }\n  double ADDCALL sass_color_get_b(const union Sass_Value* v) { return v->color.b; }\n  void ADDCALL sass_color_set_b(union Sass_Value* v, double b) { v->color.b = b; }\n  double ADDCALL sass_color_get_a(const union Sass_Value* v) { return v->color.a; }\n  void ADDCALL sass_color_set_a(union Sass_Value* v, double a) { v->color.a = a; }\n\n  // Getters and setters for Sass_List\n  size_t ADDCALL sass_list_get_length(const union Sass_Value* v) { return v->list.length; }\n  enum Sass_Separator ADDCALL sass_list_get_separator(const union Sass_Value* v) { return v->list.separator; }\n  void ADDCALL sass_list_set_separator(union Sass_Value* v, enum Sass_Separator separator) { v->list.separator = separator; }\n  bool ADDCALL sass_list_get_is_bracketed(const union Sass_Value* v) { return v->list.is_bracketed; }\n  void ADDCALL sass_list_set_is_bracketed(union Sass_Value* v, bool is_bracketed) { v->list.is_bracketed = is_bracketed; }\n  // Getters and setters for Sass_List values\n  union Sass_Value* ADDCALL sass_list_get_value(const union Sass_Value* v, size_t i) { return v->list.values[i]; }\n  void ADDCALL sass_list_set_value(union Sass_Value* v, size_t i, union Sass_Value* value) { v->list.values[i] = value; }\n\n  // Getters and setters for Sass_Map\n  size_t ADDCALL sass_map_get_length(const union Sass_Value* v) { return v->map.length; }\n  // Getters and setters for Sass_List keys and values\n  union Sass_Value* ADDCALL sass_map_get_key(const union Sass_Value* v, size_t i) { return v->map.pairs[i].key; }\n  union Sass_Value* ADDCALL sass_map_get_value(const union Sass_Value* v, size_t i) { return v->map.pairs[i].value; }\n  void ADDCALL sass_map_set_key(union Sass_Value* v, size_t i, union Sass_Value* key) { v->map.pairs[i].key = key; }\n  void ADDCALL sass_map_set_value(union Sass_Value* v, size_t i, union Sass_Value* val) { v->map.pairs[i].value = val; }\n\n  // Getters and setters for Sass_Error\n  char* ADDCALL sass_error_get_message(const union Sass_Value* v) { return v->error.message; };\n  void ADDCALL sass_error_set_message(union Sass_Value* v, char* msg) { v->error.message = msg; };\n\n  // Getters and setters for Sass_Warning\n  char* ADDCALL sass_warning_get_message(const union Sass_Value* v) { return v->warning.message; };\n  void ADDCALL sass_warning_set_message(union Sass_Value* v, char* msg) { v->warning.message = msg; };\n\n  // Creator functions for all value types\n\n  union Sass_Value* ADDCALL sass_make_boolean(bool val)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->boolean.tag = SASS_BOOLEAN;\n    v->boolean.value = val;\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_number(double val, const char* unit)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->number.tag = SASS_NUMBER;\n    v->number.value = val;\n    v->number.unit = unit ? sass_copy_c_string(unit) : 0;\n    if (v->number.unit == 0) { free(v); return 0; }\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_color(double r, double g, double b, double a)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->color.tag = SASS_COLOR;\n    v->color.r = r;\n    v->color.g = g;\n    v->color.b = b;\n    v->color.a = a;\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_string(const char* val)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->string.quoted = false;\n    v->string.tag = SASS_STRING;\n    v->string.value = val ? sass_copy_c_string(val) : 0;\n    if (v->string.value == 0) { free(v); return 0; }\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_qstring(const char* val)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->string.quoted = true;\n    v->string.tag = SASS_STRING;\n    v->string.value = val ? sass_copy_c_string(val) : 0;\n    if (v->string.value == 0) { free(v); return 0; }\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_list(size_t len, enum Sass_Separator sep, bool is_bracketed)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->list.tag = SASS_LIST;\n    v->list.length = len;\n    v->list.separator = sep;\n    v->list.is_bracketed = is_bracketed;\n    v->list.values = (union Sass_Value**) calloc(len, sizeof(union Sass_Value*));\n    if (v->list.values == 0) { free(v); return 0; }\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_map(size_t len)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->map.tag = SASS_MAP;\n    v->map.length = len;\n    v->map.pairs = (struct Sass_MapPair*) calloc(len, sizeof(struct Sass_MapPair));\n    if (v->map.pairs == 0) { free(v); return 0; }\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_null(void)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->null.tag = SASS_NULL;\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_error(const char* msg)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->error.tag = SASS_ERROR;\n    v->error.message = msg ? sass_copy_c_string(msg) : 0;\n    if (v->error.message == 0) { free(v); return 0; }\n    return v;\n  }\n\n  union Sass_Value* ADDCALL sass_make_warning(const char* msg)\n  {\n    union Sass_Value* v = (Sass_Value*) calloc(1, sizeof(Sass_Value));\n    if (v == 0) return 0;\n    v->warning.tag = SASS_WARNING;\n    v->warning.message = msg ? sass_copy_c_string(msg) : 0;\n    if (v->warning.message == 0) { free(v); return 0; }\n    return v;\n  }\n\n  // will free all associated sass values\n  void ADDCALL sass_delete_value(union Sass_Value* val) {\n\n    size_t i;\n    if (val == 0) return;\n    switch(val->unknown.tag) {\n        case SASS_NULL: {\n        }   break;\n        case SASS_BOOLEAN: {\n        }   break;\n        case SASS_NUMBER: {\n                free(val->number.unit);\n        }   break;\n        case SASS_COLOR: {\n        }   break;\n        case SASS_STRING: {\n                free(val->string.value);\n        }   break;\n        case SASS_LIST: {\n                for (i=0; i<val->list.length; i++) {\n                    sass_delete_value(val->list.values[i]);\n                }\n                free(val->list.values);\n        }   break;\n        case SASS_MAP: {\n                for (i=0; i<val->map.length; i++) {\n                    sass_delete_value(val->map.pairs[i].key);\n                    sass_delete_value(val->map.pairs[i].value);\n                }\n                free(val->map.pairs);\n        }   break;\n        case SASS_ERROR: {\n                free(val->error.message);\n        }   break;\n        case SASS_WARNING: {\n                free(val->error.message);\n        }   break;\n        default: break;\n    }\n\n    free(val);\n\n    }\n\n  // Make a deep cloned copy of the given sass value\n  union Sass_Value* ADDCALL sass_clone_value (const union Sass_Value* val)\n  {\n\n    size_t i;\n    if (val == 0) return 0;\n    switch(val->unknown.tag) {\n        case SASS_NULL: {\n                return sass_make_null();\n        }\n        case SASS_BOOLEAN: {\n                return sass_make_boolean(val->boolean.value);\n        }\n        case SASS_NUMBER: {\n                return sass_make_number(val->number.value, val->number.unit);\n        }\n        case SASS_COLOR: {\n                return sass_make_color(val->color.r, val->color.g, val->color.b, val->color.a);\n        }\n        case SASS_STRING: {\n                return sass_string_is_quoted(val) ? sass_make_qstring(val->string.value) : sass_make_string(val->string.value);\n        }\n        case SASS_LIST: {\n                union Sass_Value* list = sass_make_list(val->list.length, val->list.separator, val->list.is_bracketed);\n                for (i = 0; i < list->list.length; i++) {\n                    list->list.values[i] = sass_clone_value(val->list.values[i]);\n                }\n                return list;\n        }\n        case SASS_MAP: {\n                union Sass_Value* map = sass_make_map(val->map.length);\n                for (i = 0; i < val->map.length; i++) {\n                    map->map.pairs[i].key = sass_clone_value(val->map.pairs[i].key);\n                    map->map.pairs[i].value = sass_clone_value(val->map.pairs[i].value);\n                }\n                return map;\n        }\n        case SASS_ERROR: {\n                return sass_make_error(val->error.message);\n        }\n        case SASS_WARNING: {\n                return sass_make_warning(val->warning.message);\n        }\n        default: break;\n    }\n\n    return 0;\n\n  }\n\n  union Sass_Value* ADDCALL sass_value_stringify (const union Sass_Value* v, bool compressed, int precision)\n  {\n    ValueObj val = sass_value_to_ast_node(v);\n    Sass_Inspect_Options options(compressed ? COMPRESSED : NESTED, precision);\n    sass::string str(val->to_string(options));\n    return sass_make_qstring(str.c_str());\n  }\n\n  union Sass_Value* ADDCALL sass_value_op (enum Sass_OP op, const union Sass_Value* a, const union Sass_Value* b)\n  {\n\n    Sass::ValueObj rv;\n\n    try {\n\n      ValueObj lhs = sass_value_to_ast_node(a);\n      ValueObj rhs = sass_value_to_ast_node(b);\n      struct Sass_Inspect_Options options(NESTED, 5);\n\n      // see if it's a relational expression\n      switch(op) {\n        case Sass_OP::EQ:  return sass_make_boolean(Operators::eq(lhs, rhs));\n        case Sass_OP::NEQ: return sass_make_boolean(Operators::neq(lhs, rhs));\n        case Sass_OP::GT:  return sass_make_boolean(Operators::gt(lhs, rhs));\n        case Sass_OP::GTE: return sass_make_boolean(Operators::gte(lhs, rhs));\n        case Sass_OP::LT:  return sass_make_boolean(Operators::lt(lhs, rhs));\n        case Sass_OP::LTE: return sass_make_boolean(Operators::lte(lhs, rhs));\n        case Sass_OP::AND: return ast_node_to_sass_value(lhs->is_false() ? lhs : rhs);\n        case Sass_OP::OR:  return ast_node_to_sass_value(lhs->is_false() ? rhs : lhs);\n        default: break;\n      }\n\n      if (sass_value_is_number(a) && sass_value_is_number(b)) {\n        const Number* l_n = Cast<Number>(lhs);\n        const Number* r_n = Cast<Number>(rhs);\n        rv = Operators::op_numbers(op, *l_n, *r_n, options, l_n->pstate());\n      }\n      else if (sass_value_is_number(a) && sass_value_is_color(a)) {\n        const Number* l_n = Cast<Number>(lhs);\n        // Direct HSLA operations are not supported\n        // All color maths will be deprecated anyway\n        Color_RGBA_Obj r_c = Cast<Color>(rhs)->toRGBA();\n        rv = Operators::op_number_color(op, *l_n, *r_c, options, l_n->pstate());\n      }\n      else if (sass_value_is_color(a) && sass_value_is_number(b)) {\n        // Direct HSLA operations are not supported\n        // All color maths will be deprecated anyway\n        Color_RGBA_Obj l_c = Cast<Color>(lhs)->toRGBA();\n        const Number* r_n = Cast<Number>(rhs);\n        rv = Operators::op_color_number(op, *l_c, *r_n, options, l_c->pstate());\n      }\n      else if (sass_value_is_color(a) && sass_value_is_color(b)) {\n        // Direct HSLA operations are not supported\n        // All color maths will be deprecated anyway\n        Color_RGBA_Obj l_c = Cast<Color>(lhs)->toRGBA();\n        Color_RGBA_Obj r_c = Cast<Color>(rhs)->toRGBA();\n        rv = Operators::op_colors(op, *l_c, *r_c, options, l_c->pstate());\n      }\n      else /* convert other stuff to string and apply operation */ {\n        rv = Operators::op_strings(op, *lhs, *rhs, options, lhs->pstate());\n      }\n\n      // ToDo: maybe we should return null value?\n      if (!rv) return sass_make_error(\"invalid return value\");\n\n      // convert result back to ast node\n      return ast_node_to_sass_value(rv.ptr());\n    }\n\n    // simply pass the error message back to the caller for now\n    catch (Exception::InvalidSass& e) { return sass_make_error(e.what()); }\n    catch (std::bad_alloc&) { return sass_make_error(\"memory exhausted\"); }\n    catch (std::exception& e) { return sass_make_error(e.what()); }\n    catch (sass::string& e) { return sass_make_error(e.c_str()); }\n    catch (const char* e) { return sass_make_error(e); }\n    catch (...) { return sass_make_error(\"unknown\"); }\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/sass_values.hpp",
    "content": "#ifndef SASS_SASS_VALUES_H\n#define SASS_SASS_VALUES_H\n\n#include \"sass.h\"\n\nstruct Sass_Unknown {\n  enum Sass_Tag tag;\n};\n\nstruct Sass_Boolean {\n  enum Sass_Tag tag;\n  bool          value;\n};\n\nstruct Sass_Number {\n  enum Sass_Tag tag;\n  double        value;\n  char*         unit;\n};\n\nstruct Sass_Color {\n  enum Sass_Tag tag;\n  double        r;\n  double        g;\n  double        b;\n  double        a;\n};\n\nstruct Sass_String {\n  enum Sass_Tag tag;\n  bool          quoted;\n  char*         value;\n};\n\nstruct Sass_List {\n  enum Sass_Tag       tag;\n  enum Sass_Separator separator;\n  bool                is_bracketed;\n  size_t              length;\n  // null terminated \"array\"\n  union Sass_Value**  values;\n};\n\nstruct Sass_Map {\n  enum Sass_Tag        tag;\n  size_t               length;\n  struct Sass_MapPair* pairs;\n};\n\nstruct Sass_Null {\n  enum Sass_Tag tag;\n};\n\nstruct Sass_Error {\n  enum Sass_Tag tag;\n  char*         message;\n};\n\nstruct Sass_Warning {\n  enum Sass_Tag tag;\n  char*         message;\n};\n\nunion Sass_Value {\n  struct Sass_Unknown unknown;\n  struct Sass_Boolean boolean;\n  struct Sass_Number  number;\n  struct Sass_Color   color;\n  struct Sass_String  string;\n  struct Sass_List    list;\n  struct Sass_Map     map;\n  struct Sass_Null    null;\n  struct Sass_Error   error;\n  struct Sass_Warning warning;\n};\n\nstruct Sass_MapPair {\n  union Sass_Value* key;\n  union Sass_Value* value;\n};\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/settings.hpp",
    "content": "#ifndef SASS_SETTINGS_H\n#define SASS_SETTINGS_H\n\n// Global compile time settings should go here\n\n// When enabled we use our custom memory pool allocator\n// With intense workloads this can double the performance\n// Max memory usage mostly only grows by a slight amount\n// #define SASS_CUSTOM_ALLOCATOR\n\n// How many buckets should we have for the free-list\n// Determines when allocations go directly to malloc/free\n// For maximum size of managed items multiply by alignment\n#define SassAllocatorBuckets 512\n\n// The size of the memory pool arenas in bytes.\n#define SassAllocatorArenaSize (1024 * 256)\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/source.cpp",
    "content": "#include <stdio.h>\n#include <string.h>\n#include \"source.hpp\"\n#include \"utf8/checked.h\"\n#include \"position.hpp\"\n\nnamespace Sass {\n\n  SourceData::SourceData()\n    : SharedObj()\n  {\n  }\n\n  SourceFile::SourceFile(\n    const char* path,\n    const char* data,\n    size_t srcid) :\n    SourceData(),\n    path(sass_copy_c_string(path)),\n    data(sass_copy_c_string(data)),\n    length(0),\n    srcid(srcid)\n  {\n    length = strlen(data);\n  }\n\n  SourceFile::~SourceFile() {\n    sass_free_memory(path);\n    sass_free_memory(data);\n  }\n\n  const char* SourceFile::end() const\n  {\n    return data + length;\n  }\n\n  const char* SourceFile::begin() const\n  {\n    return data;\n  }\n\n  const char* SourceFile::getRawData() const\n  {\n    return data;\n  }\n\n  SourceSpan SourceFile::getSourceSpan()\n  {\n    return SourceSpan(this);\n  }\n\n  ItplFile::ItplFile(const char* data, const SourceSpan& pstate) :\n    SourceFile(pstate.getPath(),\n      data, pstate.getSrcId()),\n    pstate(pstate)\n  {}\n\n  const char* ItplFile::getRawData() const\n  {\n    return pstate.getRawData();\n  }\n\n  SourceSpan ItplFile::getSourceSpan()\n  {\n    return SourceSpan(pstate);\n  }\n\n}\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/source.hpp",
    "content": "#ifndef SASS_SOURCE_H\n#define SASS_SOURCE_H\n\n#include \"sass.hpp\"\n#include \"memory.hpp\"\n#include \"position.hpp\"\n#include \"source_data.hpp\"\n\nnamespace Sass {\n\n  class SourceFile :\n    public SourceData {\n  protected:\n    char* path;\n    char* data;\n    size_t length;\n    size_t srcid;\n  public:\n\n    SourceFile(\n      const char* path,\n      const char* data,\n      size_t srcid);\n\n    ~SourceFile();\n\n    const char* end() const override final;\n    const char* begin() const override final;\n    virtual const char* getRawData() const override;\n    virtual SourceSpan getSourceSpan() override;\n\n    size_t size() const override final {\n      return length;\n    }\n\n    virtual const char* getPath() const override {\n      return path;\n    }\n\n    virtual size_t getSrcId() const override {\n      return srcid;\n    }\n\n  };\n\n  class SynthFile :\n    public SourceData {\n  protected:\n    const char* path;\n  public:\n\n    SynthFile(\n      const char* path) :\n      path(path)\n    {}\n\n    ~SynthFile() {}\n\n    const char* end() const override final { return nullptr; }\n    const char* begin() const override final { return nullptr; };\n    virtual const char* getRawData() const override { return nullptr; };\n    virtual SourceSpan getSourceSpan() override { return SourceSpan(path); };\n\n    size_t size() const override final {\n      return 0;\n    }\n\n    virtual const char* getPath() const override {\n      return path;\n    }\n\n    virtual size_t getSrcId() const override {\n      return std::string::npos;\n    }\n\n  };\n  \n\n  class ItplFile :\n    public SourceFile {\n  private:\n    SourceSpan pstate;\n  public:\n\n    ItplFile(const char* data,\n      const SourceSpan& pstate);\n\n    // Offset getPosition() const override final;\n    const char* getRawData() const override final;\n    SourceSpan getSourceSpan() override final;\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/source_data.hpp",
    "content": "#ifndef SASS_SOURCE_DATA_H\n#define SASS_SOURCE_DATA_H\n\n#include \"sass.hpp\"\n#include \"memory.hpp\"\n\nnamespace Sass {\n\n  class SourceSpan;\n\n  class SourceData :\n    public SharedObj {\n  public:\n    SourceData();\n    virtual size_t size() const = 0;\n    virtual size_t getSrcId() const = 0;\n    virtual const char* end() const = 0;\n    virtual const char* begin() const = 0;\n    virtual const char* getPath() const = 0;\n    // virtual Offset getPosition() const = 0;\n    virtual const char* getRawData() const = 0;\n    virtual SourceSpan getSourceSpan() = 0;\n\n    sass::string to_string() const override {\n      return sass::string{ begin(), end() };\n    }\n    ~SourceData() {}\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/source_map.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <string>\n#include <sstream>\n#include <iostream>\n#include <iomanip>\n\n#include \"ast.hpp\"\n#include \"json.hpp\"\n#include \"context.hpp\"\n#include \"position.hpp\"\n#include \"source_map.hpp\"\n\nnamespace Sass {\n  SourceMap::SourceMap() : current_position(0, 0, 0), file(\"stdin\") { }\n  SourceMap::SourceMap(const sass::string& file) : current_position(0, 0, 0), file(file) { }\n\n  sass::string SourceMap::render_srcmap(Context &ctx) {\n\n    const bool include_sources = ctx.c_options.source_map_contents;\n    const sass::vector<sass::string> links = ctx.srcmap_links;\n    const sass::vector<Resource>& sources(ctx.resources);\n\n    JsonNode* json_srcmap = json_mkobject();\n\n    json_append_member(json_srcmap, \"version\", json_mknumber(3));\n\n    const char *file_name = file.c_str();\n    JsonNode *json_file_name = json_mkstring(file_name);\n    json_append_member(json_srcmap, \"file\", json_file_name);\n\n    // pass-through sourceRoot option\n    if (!ctx.source_map_root.empty()) {\n      JsonNode* root = json_mkstring(ctx.source_map_root.c_str());\n      json_append_member(json_srcmap, \"sourceRoot\", root);\n    }\n\n    JsonNode *json_sources = json_mkarray();\n    for (size_t i = 0; i < source_index.size(); ++i) {\n      sass::string source(links[source_index[i]]);\n      if (ctx.c_options.source_map_file_urls) {\n        source = File::rel2abs(source);\n        // check for windows abs path\n        if (source[0] == '/') {\n          // ends up with three slashes\n          source = \"file://\" + source;\n        } else {\n          // needs an additional slash\n          source = \"file:///\" + source;\n        }\n      }\n      const char* source_name = source.c_str();\n      JsonNode *json_source_name = json_mkstring(source_name);\n      json_append_element(json_sources, json_source_name);\n    }\n    json_append_member(json_srcmap, \"sources\", json_sources);\n\n    if (include_sources && source_index.size()) {\n      JsonNode *json_contents = json_mkarray();\n      for (size_t i = 0; i < source_index.size(); ++i) {\n        const Resource& resource(sources[source_index[i]]);\n        JsonNode *json_content = json_mkstring(resource.contents);\n        json_append_element(json_contents, json_content);\n      }\n      json_append_member(json_srcmap, \"sourcesContent\", json_contents);\n    }\n\n    JsonNode *json_names = json_mkarray();\n    // so far we have no implementation for names\n    // no problem as we do not alter any identifiers\n    json_append_member(json_srcmap, \"names\", json_names);\n\n    sass::string mappings = serialize_mappings();\n    JsonNode *json_mappings = json_mkstring(mappings.c_str());\n    json_append_member(json_srcmap, \"mappings\", json_mappings);\n\n    char *str = json_stringify(json_srcmap, \"\\t\");\n    sass::string result = sass::string(str);\n    free(str);\n    json_delete(json_srcmap);\n    return result;\n  }\n\n  sass::string SourceMap::serialize_mappings() {\n    sass::string result = \"\";\n\n    size_t previous_generated_line = 0;\n    size_t previous_generated_column = 0;\n    size_t previous_original_line = 0;\n    size_t previous_original_column = 0;\n    size_t previous_original_file = 0;\n    for (size_t i = 0; i < mappings.size(); ++i) {\n      const size_t generated_line = mappings[i].generated_position.line;\n      const size_t generated_column = mappings[i].generated_position.column;\n      const size_t original_line = mappings[i].original_position.line;\n      const size_t original_column = mappings[i].original_position.column;\n      const size_t original_file = mappings[i].original_position.file;\n\n      if (generated_line != previous_generated_line) {\n        previous_generated_column = 0;\n        if (generated_line > previous_generated_line) {\n          result += sass::string(generated_line - previous_generated_line, ';');\n          previous_generated_line = generated_line;\n        }\n      }\n      else if (i > 0) {\n        result += \",\";\n      }\n\n      // generated column\n      result += base64vlq.encode(static_cast<int>(generated_column) - static_cast<int>(previous_generated_column));\n      previous_generated_column = generated_column;\n      // file\n      result += base64vlq.encode(static_cast<int>(original_file) - static_cast<int>(previous_original_file));\n      previous_original_file = original_file;\n      // source line\n      result += base64vlq.encode(static_cast<int>(original_line) - static_cast<int>(previous_original_line));\n      previous_original_line = original_line;\n      // source column\n      result += base64vlq.encode(static_cast<int>(original_column) - static_cast<int>(previous_original_column));\n      previous_original_column = original_column;\n    }\n\n    return result;\n  }\n\n  void SourceMap::prepend(const OutputBuffer& out)\n  {\n    Offset size(out.smap.current_position);\n    for (Mapping mapping : out.smap.mappings) {\n      if (mapping.generated_position.line > size.line) {\n        throw(std::runtime_error(\"prepend sourcemap has illegal line\"));\n      }\n      if (mapping.generated_position.line == size.line) {\n        if (mapping.generated_position.column > size.column) {\n          throw(std::runtime_error(\"prepend sourcemap has illegal column\"));\n        }\n      }\n    }\n    // adjust the buffer offset\n    prepend(Offset(out.buffer));\n    // now add the new mappings\n    VECTOR_UNSHIFT(mappings, out.smap.mappings);\n  }\n\n  void SourceMap::append(const OutputBuffer& out)\n  {\n    append(Offset(out.buffer));\n  }\n\n  void SourceMap::prepend(const Offset& offset)\n  {\n    if (offset.line != 0 || offset.column != 0) {\n      for (Mapping& mapping : mappings) {\n        // move stuff on the first old line\n        if (mapping.generated_position.line == 0) {\n          mapping.generated_position.column += offset.column;\n        }\n        // make place for the new lines\n        mapping.generated_position.line += offset.line;\n      }\n    }\n    if (current_position.line == 0) {\n      current_position.column += offset.column;\n    }\n    current_position.line += offset.line;\n  }\n\n  void SourceMap::append(const Offset& offset)\n  {\n    current_position += offset;\n  }\n\n  void SourceMap::add_open_mapping(const AST_Node* node)\n  {\n    const SourceSpan& span(node->pstate());\n    Position from(span.getSrcId(), span.position);\n    mappings.push_back(Mapping(from, current_position));\n  }\n\n  void SourceMap::add_close_mapping(const AST_Node* node)\n  {\n    const SourceSpan& span(node->pstate());\n    Position to(span.getSrcId(), span.position + span.offset);\n    mappings.push_back(Mapping(to, current_position));\n  }\n\n  SourceSpan SourceMap::remap(const SourceSpan& pstate) {\n    for (size_t i = 0; i < mappings.size(); ++i) {\n      if (\n        mappings[i].generated_position.file == pstate.getSrcId() &&\n        mappings[i].generated_position.line == pstate.position.line &&\n        mappings[i].generated_position.column == pstate.position.column\n      ) return SourceSpan(pstate.source, mappings[i].original_position, pstate.offset);\n    }\n    return SourceSpan(pstate.source, Position(-1, -1, -1), Offset(0, 0));\n\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/source_map.hpp",
    "content": "#ifndef SASS_SOURCE_MAP_H\n#define SASS_SOURCE_MAP_H\n\n#include <string>\n#include <vector>\n\n#include \"ast_fwd_decl.hpp\"\n#include \"base64vlq.hpp\"\n#include \"position.hpp\"\n#include \"mapping.hpp\"\n\n#include \"backtrace.hpp\"\n#include \"memory.hpp\"\n\n#define VECTOR_PUSH(vec, ins) vec.insert(vec.end(), ins.begin(), ins.end())\n#define VECTOR_UNSHIFT(vec, ins) vec.insert(vec.begin(), ins.begin(), ins.end())\n\nnamespace Sass {\n\n  class Context;\n  class OutputBuffer;\n\n  class SourceMap {\n\n  public:\n    sass::vector<size_t> source_index;\n    SourceMap();\n    SourceMap(const sass::string& file);\n\n    void append(const Offset& offset);\n    void prepend(const Offset& offset);\n    void append(const OutputBuffer& out);\n    void prepend(const OutputBuffer& out);\n    void add_open_mapping(const AST_Node* node);\n    void add_close_mapping(const AST_Node* node);\n\n    sass::string render_srcmap(Context &ctx);\n    SourceSpan remap(const SourceSpan& pstate);\n\n  private:\n\n    sass::string serialize_mappings();\n\n    sass::vector<Mapping> mappings;\n    Position current_position;\npublic:\n    sass::string file;\nprivate:\n    Base64VLQ base64vlq;\n  };\n\n  class OutputBuffer {\n    public:\n      OutputBuffer(void)\n      : buffer(),\n        smap()\n      { }\n    public:\n      sass::string buffer;\n      SourceMap smap;\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/stylesheet.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"stylesheet.hpp\"\n\nnamespace Sass {\n\n  // Constructor\n  Sass::StyleSheet::StyleSheet(const Resource& res, Block_Obj root) :\n    Resource(res),\n    root(root)\n  {\n  }\n\n  StyleSheet::StyleSheet(const StyleSheet& sheet) :\n    Resource(sheet),\n    root(sheet.root)\n  {\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/stylesheet.hpp",
    "content": "#ifndef SASS_STYLESHEET_H\n#define SASS_STYLESHEET_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast_fwd_decl.hpp\"\n#include \"extender.hpp\"\n#include \"file.hpp\"\n\nnamespace Sass {\n\n  // parsed stylesheet from loaded resource\n  // this should be a `Module` for sass 4.0\n  class StyleSheet : public Resource {\n    public:\n\n      // The canonical URL for this module's source file. This may be `null`\n      // if the module was loaded from a string without a URL provided.\n      // Uri get url;\n\n      // Modules that this module uses.\n      // List<Module> get upstream;\n\n      // The module's variables.\n      // Map<String, Value> get variables;\n\n      // The module's functions. Implementations must ensure\n      // that each [Callable] is stored under its own name.\n      // Map<String, Callable> get functions;\n\n      // The module's mixins. Implementations must ensure that\n      // each [Callable] is stored under its own name.\n      // Map<String, Callable> get mixins;\n\n      // The extensions defined in this module, which is also able to update\n      // [css]'s style rules in-place based on downstream extensions.\n      // Extender extender;\n\n      // The module's CSS tree.\n      Block_Obj root;\n\n    public:\n\n      // default argument constructor\n      StyleSheet(const Resource& res, Block_Obj root);\n\n      // Copy constructor\n      StyleSheet(const StyleSheet& res);\n\n  };\n\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/support/libsass.pc.in",
    "content": "prefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nincludedir=@includedir@\n\nName: libsass\nURL: https://github.com/sass/libsass\nDescription: A C implementation of a Sass compiler\nVersion: @VERSION@\nLibs: -L${libdir} -lsass\nCflags: -I${includedir}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/to_value.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"ast.hpp\"\n#include \"to_value.hpp\"\n\nnamespace Sass {\n\n  // Custom_Error is a valid value\n  Value* To_Value::operator()(Custom_Error* e)\n  {\n    return e;\n  }\n\n  // Custom_Warning is a valid value\n  Value* To_Value::operator()(Custom_Warning* w)\n  {\n    return w;\n  }\n\n  // Boolean is a valid value\n  Value* To_Value::operator()(Boolean* b)\n  {\n    return b;\n  }\n\n  // Number is a valid value\n  Value* To_Value::operator()(Number* n)\n  {\n    return n;\n  }\n\n  // Color is a valid value\n  Value* To_Value::operator()(Color_RGBA* c)\n  {\n    return c;\n  }\n\n  // Color is a valid value\n  Value* To_Value::operator()(Color_HSLA* c)\n  {\n    return c;\n  }\n\n  // String_Constant is a valid value\n  Value* To_Value::operator()(String_Constant* s)\n  {\n    return s;\n  }\n\n  // String_Quoted is a valid value\n  Value* To_Value::operator()(String_Quoted* s)\n  {\n    return s;\n  }\n\n  // List is a valid value\n  Value* To_Value::operator()(List* l)\n  {\n    List_Obj ll = SASS_MEMORY_NEW(List,\n                               l->pstate(),\n                               l->length(),\n                               l->separator(),\n                               l->is_arglist(),\n                               l->is_bracketed());\n    for (size_t i = 0, L = l->length(); i < L; ++i) {\n      ll->append((*l)[i]->perform(this));\n    }\n    return ll.detach();\n  }\n\n  // Map is a valid value\n  Value* To_Value::operator()(Map* m)\n  {\n    return m;\n  }\n\n  // Null is a valid value\n  Value* To_Value::operator()(Null* n)\n  {\n    return n;\n  }\n\n  // Function is a valid value\n  Value* To_Value::operator()(Function* n)\n  {\n    return n;\n  }\n\n  // Argument returns its value\n  Value* To_Value::operator()(Argument* arg)\n  {\n    if (!arg->name().empty()) return 0;\n    return arg->value()->perform(this);\n  }\n\n  // SelectorList is converted to a string\n  Value* To_Value::operator()(SelectorList* s)\n  {\n    return SASS_MEMORY_NEW(String_Quoted,\n                           s->pstate(),\n                           s->to_string(ctx.c_options));\n  }\n\n  // Binary_Expression is converted to a string\n  Value* To_Value::operator()(Binary_Expression* s)\n  {\n    return SASS_MEMORY_NEW(String_Quoted,\n                           s->pstate(),\n                           s->to_string(ctx.c_options));\n  }\n\n};\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/to_value.hpp",
    "content": "#ifndef SASS_TO_VALUE_H\n#define SASS_TO_VALUE_H\n\n#include \"operation.hpp\"\n#include \"sass/values.h\"\n#include \"ast_fwd_decl.hpp\"\n\nnamespace Sass {\n\n  class To_Value : public Operation_CRTP<Value*, To_Value> {\n\n  private:\n\n    Context& ctx;\n\n  public:\n\n    To_Value(Context& ctx)\n    : ctx(ctx)\n    { }\n    ~To_Value() { }\n    using Operation<Value*>::operator();\n\n    Value* operator()(Argument*);\n    Value* operator()(Boolean*);\n    Value* operator()(Number*);\n    Value* operator()(Color_RGBA*);\n    Value* operator()(Color_HSLA*);\n    Value* operator()(String_Constant*);\n    Value* operator()(String_Quoted*);\n    Value* operator()(Custom_Warning*);\n    Value* operator()(Custom_Error*);\n    Value* operator()(List*);\n    Value* operator()(Map*);\n    Value* operator()(Null*);\n    Value* operator()(Function*);\n\n    // convert to string via `To_String`\n    Value* operator()(SelectorList*);\n    Value* operator()(Binary_Expression*);\n\n  };\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/units.cpp",
    "content": "#include \"sass.hpp\"\n#include <map>\n#include <stdexcept>\n#include <algorithm>\n#include \"units.hpp\"\n#include \"error_handling.hpp\"\n\nnamespace Sass {\n\n  /* the conversion matrix can be readed the following way */\n  /* if you go down, the factor is for the numerator (multiply) */\n  /* if you go right, the factor is for the denominator (divide) */\n  /* and yes, we actually use both, not sure why, but why not!? */\n\n  const double size_conversion_factors[6][6] =\n  {\n             /*  in         cm         pc         mm         pt         px        */\n    /* in   */ { 1,         2.54,      6,         25.4,      72,        96,       },\n    /* cm   */ { 1.0/2.54,  1,         6.0/2.54,  10,        72.0/2.54, 96.0/2.54 },\n    /* pc   */ { 1.0/6.0,   2.54/6.0,  1,         25.4/6.0,  72.0/6.0,  96.0/6.0  },\n    /* mm   */ { 1.0/25.4,  1.0/10.0,  6.0/25.4,  1,         72.0/25.4, 96.0/25.4 },\n    /* pt   */ { 1.0/72.0,  2.54/72.0, 6.0/72.0,  25.4/72.0, 1,         96.0/72.0 },\n    /* px   */ { 1.0/96.0,  2.54/96.0, 6.0/96.0,  25.4/96.0, 72.0/96.0, 1,        }\n  };\n\n  const double angle_conversion_factors[4][4] =\n  {\n             /*  deg        grad       rad        turn      */\n    /* deg  */ { 1,         40.0/36.0, PI/180.0,  1.0/360.0 },\n    /* grad */ { 36.0/40.0, 1,         PI/200.0,  1.0/400.0 },\n    /* rad  */ { 180.0/PI,  200.0/PI,  1,         0.5/PI    },\n    /* turn */ { 360.0,     400.0,     2.0*PI,    1         }\n  };\n\n  const double time_conversion_factors[2][2] =\n  {\n             /*  s          ms        */\n    /* s    */ { 1,         1000.0    },\n    /* ms   */ { 1/1000.0,  1         }\n  };\n  const double frequency_conversion_factors[2][2] =\n  {\n             /*  Hz         kHz       */\n    /* Hz   */ { 1,         1/1000.0  },\n    /* kHz  */ { 1000.0,    1         }\n  };\n  const double resolution_conversion_factors[3][3] =\n  {\n             /*  dpi        dpcm       dppx     */\n    /* dpi  */ { 1,         1/2.54,    1/96.0   },\n    /* dpcm */ { 2.54,      1,         2.54/96  },\n    /* dppx */ { 96,        96/2.54,   1        }\n  };\n\n  UnitClass get_unit_type(UnitType unit)\n  {\n    switch (unit & 0xFF00)\n    {\n      case UnitClass::LENGTH:      return UnitClass::LENGTH;\n      case UnitClass::ANGLE:       return UnitClass::ANGLE;\n      case UnitClass::TIME:        return UnitClass::TIME;\n      case UnitClass::FREQUENCY:   return UnitClass::FREQUENCY;\n      case UnitClass::RESOLUTION:  return UnitClass::RESOLUTION;\n      default:                     return UnitClass::INCOMMENSURABLE;\n    }\n  };\n\n  sass::string get_unit_class(UnitType unit)\n  {\n    switch (unit & 0xFF00)\n    {\n      case UnitClass::LENGTH:      return \"LENGTH\";\n      case UnitClass::ANGLE:       return \"ANGLE\";\n      case UnitClass::TIME:        return \"TIME\";\n      case UnitClass::FREQUENCY:   return \"FREQUENCY\";\n      case UnitClass::RESOLUTION:  return \"RESOLUTION\";\n      default:                     return \"INCOMMENSURABLE\";\n    }\n  };\n\n  UnitType get_main_unit(const UnitClass unit)\n  {\n    switch (unit)\n    {\n      case UnitClass::LENGTH:      return UnitType::PX;\n      case UnitClass::ANGLE:       return UnitType::DEG;\n      case UnitClass::TIME:        return UnitType::SEC;\n      case UnitClass::FREQUENCY:   return UnitType::HERTZ;\n      case UnitClass::RESOLUTION:  return UnitType::DPI;\n      default:                     return UnitType::UNKNOWN;\n    }\n  };\n\n  UnitType string_to_unit(const sass::string& s)\n  {\n    // size units\n    if      (s == \"px\")   return UnitType::PX;\n    else if (s == \"pt\")   return UnitType::PT;\n    else if (s == \"pc\")   return UnitType::PC;\n    else if (s == \"mm\")   return UnitType::MM;\n    else if (s == \"cm\")   return UnitType::CM;\n    else if (s == \"in\")   return UnitType::IN;\n    // angle units\n    else if (s == \"deg\")  return UnitType::DEG;\n    else if (s == \"grad\") return UnitType::GRAD;\n    else if (s == \"rad\")  return UnitType::RAD;\n    else if (s == \"turn\") return UnitType::TURN;\n    // time units\n    else if (s == \"s\")    return UnitType::SEC;\n    else if (s == \"ms\")   return UnitType::MSEC;\n    // frequency units\n    else if (s == \"Hz\")   return UnitType::HERTZ;\n    else if (s == \"kHz\")  return UnitType::KHERTZ;\n    // resolutions units\n    else if (s == \"dpi\")  return UnitType::DPI;\n    else if (s == \"dpcm\") return UnitType::DPCM;\n    else if (s == \"dppx\") return UnitType::DPPX;\n    // for unknown units\n    else return UnitType::UNKNOWN;\n  }\n\n  const char* unit_to_string(UnitType unit)\n  {\n    switch (unit) {\n      // size units\n      case UnitType::PX:      return \"px\";\n      case UnitType::PT:      return \"pt\";\n      case UnitType::PC:      return \"pc\";\n      case UnitType::MM:      return \"mm\";\n      case UnitType::CM:      return \"cm\";\n      case UnitType::IN:      return \"in\";\n      // angle units\n      case UnitType::DEG:     return \"deg\";\n      case UnitType::GRAD:    return \"grad\";\n      case UnitType::RAD:     return \"rad\";\n      case UnitType::TURN:    return \"turn\";\n      // time units\n      case UnitType::SEC:     return \"s\";\n      case UnitType::MSEC:    return \"ms\";\n      // frequency units\n      case UnitType::HERTZ:   return \"Hz\";\n      case UnitType::KHERTZ:  return \"kHz\";\n      // resolutions units\n      case UnitType::DPI:     return \"dpi\";\n      case UnitType::DPCM:    return \"dpcm\";\n      case UnitType::DPPX:    return \"dppx\";\n      // for unknown units\n      default:                return \"\";\n    }\n  }\n\n  sass::string unit_to_class(const sass::string& s)\n  {\n    if      (s == \"px\")   return \"LENGTH\";\n    else if (s == \"pt\")   return \"LENGTH\";\n    else if (s == \"pc\")   return \"LENGTH\";\n    else if (s == \"mm\")   return \"LENGTH\";\n    else if (s == \"cm\")   return \"LENGTH\";\n    else if (s == \"in\")   return \"LENGTH\";\n    // angle units\n    else if (s == \"deg\")  return \"ANGLE\";\n    else if (s == \"grad\") return \"ANGLE\";\n    else if (s == \"rad\")  return \"ANGLE\";\n    else if (s == \"turn\") return \"ANGLE\";\n    // time units\n    else if (s == \"s\")    return \"TIME\";\n    else if (s == \"ms\")   return \"TIME\";\n    // frequency units\n    else if (s == \"Hz\")   return \"FREQUENCY\";\n    else if (s == \"kHz\")  return \"FREQUENCY\";\n    // resolutions units\n    else if (s == \"dpi\")  return \"RESOLUTION\";\n    else if (s == \"dpcm\") return \"RESOLUTION\";\n    else if (s == \"dppx\") return \"RESOLUTION\";\n    // for unknown units\n    return \"CUSTOM:\" + s;\n  }\n\n  // throws incompatibleUnits exceptions\n  double conversion_factor(const sass::string& s1, const sass::string& s2)\n  {\n    // assert for same units\n    if (s1 == s2) return 1;\n    // get unit enum from string\n    UnitType u1 = string_to_unit(s1);\n    UnitType u2 = string_to_unit(s2);\n    // query unit group types\n    UnitClass t1 = get_unit_type(u1);\n    UnitClass t2 = get_unit_type(u2);\n    // return the conversion factor\n    return conversion_factor(u1, u2, t1, t2);\n  }\n\n  // throws incompatibleUnits exceptions\n  double conversion_factor(UnitType u1, UnitType u2, UnitClass t1, UnitClass t2)\n  {\n    // can't convert between groups\n    if (t1 != t2) return 0;\n    // get absolute offset\n    // used for array acces\n    size_t i1 = u1 - t1;\n    size_t i2 = u2 - t2;\n    // process known units\n    switch (t1) {\n      case LENGTH:\n        return size_conversion_factors[i1][i2];\n      case ANGLE:\n        return angle_conversion_factors[i1][i2];\n      case TIME:\n        return time_conversion_factors[i1][i2];\n      case FREQUENCY:\n        return frequency_conversion_factors[i1][i2];\n      case RESOLUTION:\n        return resolution_conversion_factors[i1][i2];\n      case INCOMMENSURABLE:\n        return 0;\n    }\n    // fallback\n    return 0;\n  }\n\n  double convert_units(const sass::string& lhs, const sass::string& rhs, int& lhsexp, int& rhsexp)\n  {\n    double f = 0;\n    // do not convert same ones\n    if (lhs == rhs) return 0;\n    // skip already canceled out unit\n    if (lhsexp == 0) return 0;\n    if (rhsexp == 0) return 0;\n    // check if it can be converted\n    UnitType ulhs = string_to_unit(lhs);\n    UnitType urhs = string_to_unit(rhs);\n    // skip units we cannot convert\n    if (ulhs == UNKNOWN) return 0;\n    if (urhs == UNKNOWN) return 0;\n    // query unit group types\n    UnitClass clhs = get_unit_type(ulhs);\n    UnitClass crhs = get_unit_type(urhs);\n    // skip units we cannot convert\n    if (clhs != crhs) return 0;\n    // if right denominator is bigger than lhs, we want to keep it in rhs unit\n    if (rhsexp < 0 && lhsexp > 0 && - rhsexp > lhsexp) {\n      // get the conversion factor for units\n      f = conversion_factor(urhs, ulhs, clhs, crhs);\n      // left hand side has been consumned\n      f = std::pow(f, lhsexp);\n      rhsexp += lhsexp;\n      lhsexp = 0;\n    }\n    else {\n      // get the conversion factor for units\n      f = conversion_factor(ulhs, urhs, clhs, crhs);\n      // right hand side has been consumned\n      f = std::pow(f, rhsexp);\n      lhsexp += rhsexp;\n      rhsexp = 0;\n    }\n    return f;\n  }\n\n  bool Units::operator< (const Units& rhs) const\n  {\n    return (numerators < rhs.numerators) &&\n           (denominators < rhs.denominators);\n  }\n  bool Units::operator== (const Units& rhs) const\n  {\n    return (numerators == rhs.numerators) &&\n           (denominators == rhs.denominators);\n  }\n  bool Units::operator!= (const Units& rhs) const\n  {\n    return ! (*this == rhs);\n  }\n\n  double Units::normalize()\n  {\n\n    size_t iL = numerators.size();\n    size_t nL = denominators.size();\n\n    // the final conversion factor\n    double factor = 1;\n\n    for (size_t i = 0; i < iL; i++) {\n      sass::string &lhs = numerators[i];\n      UnitType ulhs = string_to_unit(lhs);\n      if (ulhs == UNKNOWN) continue;\n      UnitClass clhs = get_unit_type(ulhs);\n      UnitType umain = get_main_unit(clhs);\n      if (ulhs == umain) continue;\n      double f(conversion_factor(umain, ulhs, clhs, clhs));\n      if (f == 0) throw std::runtime_error(\"INVALID\");\n      numerators[i] = unit_to_string(umain);\n      factor /= f;\n    }\n\n    for (size_t n = 0; n < nL; n++) {\n      sass::string &rhs = denominators[n];\n      UnitType urhs = string_to_unit(rhs);\n      if (urhs == UNKNOWN) continue;\n      UnitClass crhs = get_unit_type(urhs);\n      UnitType umain = get_main_unit(crhs);\n      if (urhs == umain) continue;\n      double f(conversion_factor(umain, urhs, crhs, crhs));\n      if (f == 0) throw std::runtime_error(\"INVALID\");\n      denominators[n] = unit_to_string(umain);\n      factor /= f;\n    }\n\n    std::sort (numerators.begin(), numerators.end());\n    std::sort (denominators.begin(), denominators.end());\n\n    // return for conversion\n    return factor;\n  }\n\n  double Units::reduce()\n  {\n\n    size_t iL = numerators.size();\n    size_t nL = denominators.size();\n\n    // have less than two units?\n    if (iL + nL < 2) return 1;\n\n    // first make sure same units cancel each other out\n    // it seems that a map table will fit nicely to do this\n    // we basically construct exponents for each unit\n    // has the advantage that they will be pre-sorted\n    std::map<sass::string, int> exponents;\n\n    // initialize by summing up occurrences in unit vectors\n    // this will already cancel out equivalent units (e.q. px/px)\n    for (size_t i = 0; i < iL; i ++) exponents[numerators[i]] += 1;\n    for (size_t n = 0; n < nL; n ++) exponents[denominators[n]] -= 1;\n\n    // the final conversion factor\n    double factor = 1;\n\n    // convert between compatible units\n    for (size_t i = 0; i < iL; i++) {\n      for (size_t n = 0; n < nL; n++) {\n        sass::string &lhs = numerators[i], &rhs = denominators[n];\n        int &lhsexp = exponents[lhs], &rhsexp = exponents[rhs];\n        double f(convert_units(lhs, rhs, lhsexp, rhsexp));\n        if (f == 0) continue;\n        factor /= f;\n      }\n    }\n\n    // now we can build up the new unit arrays\n    numerators.clear();\n    denominators.clear();\n\n    // recreate sorted units vectors\n    for (auto exp : exponents) {\n      int &exponent = exp.second;\n      while (exponent > 0 && exponent --)\n        numerators.push_back(exp.first);\n      while (exponent < 0 && exponent ++)\n        denominators.push_back(exp.first);\n    }\n\n    // return for conversion\n    return factor;\n\n  }\n\n  sass::string Units::unit() const\n  {\n    sass::string u;\n    size_t iL = numerators.size();\n    size_t nL = denominators.size();\n    for (size_t i = 0; i < iL; i += 1) {\n      if (i) u += '*';\n      u += numerators[i];\n    }\n    if (nL != 0) u += '/';\n    for (size_t n = 0; n < nL; n += 1) {\n      if (n) u += '*';\n      u += denominators[n];\n    }\n    return u;\n  }\n\n  bool Units::is_unitless() const\n  {\n    return numerators.empty() &&\n           denominators.empty();\n  }\n\n  bool Units::is_valid_css_unit() const\n  {\n    return numerators.size() <= 1 &&\n           denominators.size() == 0;\n  }\n\n  // this does not cover all cases (multiple preferred units)\n  double Units::convert_factor(const Units& r) const\n  {\n\n    sass::vector<sass::string> miss_nums(0);\n    sass::vector<sass::string> miss_dens(0);\n    // create copy since we need these for state keeping\n    sass::vector<sass::string> r_nums(r.numerators);\n    sass::vector<sass::string> r_dens(r.denominators);\n\n    auto l_num_it = numerators.begin();\n    auto l_num_end = numerators.end();\n\n    bool l_unitless = is_unitless();\n    auto r_unitless = r.is_unitless();\n\n    // overall conversion\n    double factor = 1;\n\n    // process all left numerators\n    while (l_num_it != l_num_end)\n    {\n      // get and increment afterwards\n      const sass::string l_num = *(l_num_it ++);\n\n      auto r_num_it = r_nums.begin(), r_num_end = r_nums.end();\n\n      bool found = false;\n      // search for compatible numerator\n      while (r_num_it != r_num_end)\n      {\n        // get and increment afterwards\n        const sass::string r_num = *(r_num_it);\n        // get possible conversion factor for units\n        double conversion = conversion_factor(l_num, r_num);\n        // skip incompatible numerator\n        if (conversion == 0) {\n          ++ r_num_it;\n          continue;\n        }\n        // apply to global factor\n        factor *= conversion;\n        // remove item from vector\n        r_nums.erase(r_num_it);\n        // found numerator\n        found = true;\n        break;\n      }\n      // maybe we did not find any\n      // left numerator is leftover\n      if (!found) miss_nums.push_back(l_num);\n    }\n\n    auto l_den_it = denominators.begin();\n    auto l_den_end = denominators.end();\n\n    // process all left denominators\n    while (l_den_it != l_den_end)\n    {\n      // get and increment afterwards\n      const sass::string l_den = *(l_den_it ++);\n\n      auto r_den_it = r_dens.begin();\n      auto r_den_end = r_dens.end();\n\n      bool found = false;\n      // search for compatible denominator\n      while (r_den_it != r_den_end)\n      {\n        // get and increment afterwards\n        const sass::string r_den = *(r_den_it);\n        // get possible conversion factor for units\n        double conversion = conversion_factor(l_den, r_den);\n        // skip incompatible denominator\n        if (conversion == 0) {\n          ++ r_den_it;\n          continue;\n        }\n        // apply to global factor\n        factor /= conversion;\n        // remove item from vector\n        r_dens.erase(r_den_it);\n        // found denominator\n        found = true;\n        break;\n      }\n      // maybe we did not find any\n      // left denominator is leftover\n      if (!found) miss_dens.push_back(l_den);\n    }\n\n    // check left-overs (ToDo: might cancel out?)\n    if (miss_nums.size() > 0 && !r_unitless) {\n      throw Exception::IncompatibleUnits(r, *this);\n    }\n    else if (miss_dens.size() > 0 && !r_unitless) {\n      throw Exception::IncompatibleUnits(r, *this);\n    }\n    else if (r_nums.size() > 0 && !l_unitless) {\n      throw Exception::IncompatibleUnits(r, *this);\n    }\n    else if (r_dens.size() > 0 && !l_unitless) {\n      throw Exception::IncompatibleUnits(r, *this);\n    }\n\n    return factor;\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/units.hpp",
    "content": "#ifndef SASS_UNITS_H\n#define SASS_UNITS_H\n\n#include <cmath>\n#include <string>\n#include <sstream>\n#include <vector>\n\nnamespace Sass {\n\n  const double PI = std::acos(-1);\n\n  enum UnitClass {\n    LENGTH = 0x000,\n    ANGLE = 0x100,\n    TIME = 0x200,\n    FREQUENCY = 0x300,\n    RESOLUTION = 0x400,\n    INCOMMENSURABLE = 0x500\n  };\n\n  enum UnitType {\n\n    // size units\n    IN = UnitClass::LENGTH,\n    CM,\n    PC,\n    MM,\n    PT,\n    PX,\n\n    // angle units\n    DEG = ANGLE,\n    GRAD,\n    RAD,\n    TURN,\n\n    // time units\n    SEC = TIME,\n    MSEC,\n\n    // frequency units\n    HERTZ = FREQUENCY,\n    KHERTZ,\n\n    // resolutions units\n    DPI = RESOLUTION,\n    DPCM,\n    DPPX,\n\n    // for unknown units\n    UNKNOWN = INCOMMENSURABLE\n\n  };\n\n  class Units {\n  public:\n    sass::vector<sass::string> numerators;\n    sass::vector<sass::string> denominators;\n  public:\n    // default constructor\n    Units() :\n      numerators(),\n      denominators()\n    { }\n    // copy constructor\n    Units(const Units* ptr) :\n      numerators(ptr->numerators),\n      denominators(ptr->denominators)\n    { }\n    // convert to string\n    sass::string unit() const;\n    // get if units are empty\n    bool is_unitless() const;\n    // return if valid for css\n    bool is_valid_css_unit() const;\n    // reduce units for output\n    // returns conversion factor\n    double reduce();\n    // normalize units for compare\n    // returns conversion factor\n    double normalize();\n    // compare operations\n    bool operator< (const Units& rhs) const;\n    bool operator== (const Units& rhs) const;\n    bool operator!= (const Units& rhs) const;\n    // factor to convert into given units\n    double convert_factor(const Units&) const;\n  };\n\n  extern const double size_conversion_factors[6][6];\n  extern const double angle_conversion_factors[4][4];\n  extern const double time_conversion_factors[2][2];\n  extern const double frequency_conversion_factors[2][2];\n  extern const double resolution_conversion_factors[3][3];\n\n  UnitType get_main_unit(const UnitClass unit);\n  enum Sass::UnitType string_to_unit(const sass::string&);\n  const char* unit_to_string(Sass::UnitType unit);\n  enum Sass::UnitClass get_unit_type(Sass::UnitType unit);\n  sass::string get_unit_class(Sass::UnitType unit);\n  sass::string unit_to_class(const sass::string&);\n  // throws incompatibleUnits exceptions\n  double conversion_factor(const sass::string&, const sass::string&);\n  double conversion_factor(UnitType, UnitType, UnitClass, UnitClass);\n  double convert_units(const sass::string&, const sass::string&, int&, int&);\n\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/utf8/checked.h",
    "content": "// Copyright 2006-2016 Nemanja Trifunovic\n\n/*\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n*/\n\n\n#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731\n#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731\n\n#include \"core.h\"\n#include <stdexcept>\n\nnamespace utf8\n{\n    // Base for the exceptions that may be thrown from the library\n    class exception : public ::std::exception {\n    };\n\n    // Exceptions that may be thrown from the library functions.\n    class invalid_code_point : public exception {\n        uint32_t cp;\n    public:\n        invalid_code_point(uint32_t codepoint) : cp(codepoint) {}\n        virtual const char* what() const throw() { return \"Invalid code point\"; }\n        uint32_t code_point() const {return cp;}\n    };\n\n    class invalid_utf8 : public exception {\n        uint8_t u8;\n    public:\n        invalid_utf8 (uint8_t u) : u8(u) {}\n        virtual const char* what() const throw() { return \"Invalid UTF-8\"; }\n        uint8_t utf8_octet() const {return u8;}\n    };\n\n    class invalid_utf16 : public exception {\n        uint16_t u16;\n    public:\n        invalid_utf16 (uint16_t u) : u16(u) {}\n        virtual const char* what() const throw() { return \"Invalid UTF-16\"; }\n        uint16_t utf16_word() const {return u16;}\n    };\n\n    class not_enough_room : public exception {\n    public:\n        virtual const char* what() const throw() { return \"Not enough space\"; }\n    };\n\n    /// The library API - functions intended to be called by the users\n\n    template <typename octet_iterator>\n    octet_iterator append(uint32_t cp, octet_iterator result)\n    {\n        if (!utf8::internal::is_code_point_valid(cp))\n            throw invalid_code_point(cp);\n\n        if (cp < 0x80)                        // one octet\n            *(result++) = static_cast<uint8_t>(cp);\n        else if (cp < 0x800) {                // two octets\n            *(result++) = static_cast<uint8_t>((cp >> 6)            | 0xc0);\n            *(result++) = static_cast<uint8_t>((cp & 0x3f)          | 0x80);\n        }\n        else if (cp < 0x10000) {              // three octets\n            *(result++) = static_cast<uint8_t>((cp >> 12)           | 0xe0);\n            *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f)   | 0x80);\n            *(result++) = static_cast<uint8_t>((cp & 0x3f)          | 0x80);\n        }\n        else {                                // four octets\n            *(result++) = static_cast<uint8_t>((cp >> 18)           | 0xf0);\n            *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)  | 0x80);\n            *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f)   | 0x80);\n            *(result++) = static_cast<uint8_t>((cp & 0x3f)          | 0x80);\n        }\n        return result;\n    }\n\n    template <typename octet_iterator, typename output_iterator>\n    output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)\n    {\n        while (start != end) {\n            octet_iterator sequence_start = start;\n            internal::utf_error err_code = utf8::internal::validate_next(start, end);\n            switch (err_code) {\n                case internal::UTF8_OK :\n                    for (octet_iterator it = sequence_start; it != start; ++it)\n                        *out++ = *it;\n                    break;\n                case internal::NOT_ENOUGH_ROOM:\n                    out = utf8::append (replacement, out);\n                    start = end;\n                    break;\n                case internal::INVALID_LEAD:\n                    out = utf8::append (replacement, out);\n                    ++start;\n                    break;\n                case internal::INCOMPLETE_SEQUENCE:\n                case internal::OVERLONG_SEQUENCE:\n                case internal::INVALID_CODE_POINT:\n                    out = utf8::append (replacement, out);\n                    ++start;\n                    // just one replacement mark for the sequence\n                    while (start != end && utf8::internal::is_trail(*start))\n                        ++start;\n                    break;\n            }\n        }\n        return out;\n    }\n\n    template <typename octet_iterator, typename output_iterator>\n    inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)\n    {\n        static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);\n        return utf8::replace_invalid(start, end, out, replacement_marker);\n    }\n\n    template <typename octet_iterator>\n    uint32_t next(octet_iterator& it, octet_iterator end)\n    {\n        uint32_t cp = 0;\n        internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);\n        switch (err_code) {\n            case internal::UTF8_OK :\n                break;\n            case internal::NOT_ENOUGH_ROOM :\n                throw not_enough_room();\n            case internal::INVALID_LEAD :\n            case internal::INCOMPLETE_SEQUENCE :\n            case internal::OVERLONG_SEQUENCE :\n                throw invalid_utf8(*it);\n            case internal::INVALID_CODE_POINT :\n                throw invalid_code_point(cp);\n        }\n        return cp;\n    }\n\n    template <typename octet_iterator>\n    uint32_t peek_next(octet_iterator it, octet_iterator end)\n    {\n        return utf8::next(it, end);\n    }\n\n    template <typename octet_iterator>\n    uint32_t prior(octet_iterator& it, octet_iterator start)\n    {\n        // can't do much if it == start\n        if (it == start)\n            throw not_enough_room();\n\n        octet_iterator end = it;\n        // Go back until we hit either a lead octet or start\n        while (utf8::internal::is_trail(*(--it)))\n            if (it == start)\n                throw invalid_utf8(*it); // error - no lead byte in the sequence\n        return utf8::peek_next(it, end);\n    }\n\n    /// Deprecated in versions that include \"prior\"\n    template <typename octet_iterator>\n    uint32_t previous(octet_iterator& it, octet_iterator pass_start)\n    {\n        octet_iterator end = it;\n        while (utf8::internal::is_trail(*(--it)))\n            if (it == pass_start)\n                throw invalid_utf8(*it); // error - no lead byte in the sequence\n        octet_iterator temp = it;\n        return utf8::next(temp, end);\n    }\n\n    template <typename octet_iterator, typename distance_type>\n    void advance (octet_iterator& it, distance_type n, octet_iterator end)\n    {\n        for (distance_type i = 0; i < n; ++i)\n            utf8::next(it, end);\n    }\n\n    template <typename octet_iterator, typename distance_type>\n    void retreat (octet_iterator& it, distance_type n, octet_iterator end)\n    {\n        for (distance_type i = 0; i < n; ++i)\n            utf8::prior(it, end);\n    }\n\n    template <typename octet_iterator>\n    typename std::iterator_traits<octet_iterator>::difference_type\n    distance (octet_iterator first, octet_iterator last)\n    {\n        typename std::iterator_traits<octet_iterator>::difference_type dist;\n        for (dist = 0; first < last; ++dist)\n            utf8::next(first, last);\n        return dist;\n    }\n\n    template <typename u16bit_iterator, typename octet_iterator>\n    octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)\n    {\n        while (start != end) {\n            uint32_t cp = utf8::internal::mask16(*start++);\n            // Take care of surrogate pairs first\n            if (utf8::internal::is_lead_surrogate(cp)) {\n                if (start != end) {\n                    uint32_t trail_surrogate = utf8::internal::mask16(*start++);\n                    if (utf8::internal::is_trail_surrogate(trail_surrogate))\n                        cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;\n                    else\n                        throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));\n                }\n                else\n                    throw invalid_utf16(static_cast<uint16_t>(cp));\n\n            }\n            // Lone trail surrogate\n            else if (utf8::internal::is_trail_surrogate(cp))\n                throw invalid_utf16(static_cast<uint16_t>(cp));\n\n            result = utf8::append(cp, result);\n        }\n        return result;\n    }\n\n    template <typename u16bit_iterator, typename octet_iterator>\n    u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)\n    {\n        while (start < end) {\n            uint32_t cp = utf8::next(start, end);\n            if (cp > 0xffff) { //make a surrogate pair\n                *result++ = static_cast<uint16_t>((cp >> 10)   + internal::LEAD_OFFSET);\n                *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);\n            }\n            else\n                *result++ = static_cast<uint16_t>(cp);\n        }\n        return result;\n    }\n\n    template <typename octet_iterator, typename u32bit_iterator>\n    octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)\n    {\n        while (start != end)\n            result = utf8::append(*(start++), result);\n\n        return result;\n    }\n\n    template <typename octet_iterator, typename u32bit_iterator>\n    u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)\n    {\n        while (start < end)\n            (*result++) = utf8::next(start, end);\n\n        return result;\n    }\n\n    // The iterator class\n    template <typename octet_iterator>\n    class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {\n      octet_iterator it;\n      octet_iterator range_start;\n      octet_iterator range_end;\n      public:\n      iterator () {}\n      explicit iterator (const octet_iterator& octet_it,\n                         const octet_iterator& rangestart,\n                         const octet_iterator& rangeend) :\n               it(octet_it), range_start(rangestart), range_end(rangeend)\n      {\n          if (it < range_start || it > range_end)\n              throw std::out_of_range(\"Invalid utf-8 iterator position\");\n      }\n      // the default \"big three\" are OK\n      octet_iterator base () const { return it; }\n      uint32_t operator * () const\n      {\n          octet_iterator temp = it;\n          return utf8::next(temp, range_end);\n      }\n      bool operator == (const iterator& rhs) const\n      {\n          if (range_start != rhs.range_start || range_end != rhs.range_end)\n              throw std::logic_error(\"Comparing utf-8 iterators defined with different ranges\");\n          return (it == rhs.it);\n      }\n      bool operator != (const iterator& rhs) const\n      {\n          return !(operator == (rhs));\n      }\n      iterator& operator ++ ()\n      {\n          utf8::next(it, range_end);\n          return *this;\n      }\n      iterator operator ++ (int)\n      {\n          iterator temp = *this;\n          utf8::next(it, range_end);\n          return temp;\n      }\n      iterator& operator -- ()\n      {\n          utf8::prior(it, range_start);\n          return *this;\n      }\n      iterator operator -- (int)\n      {\n          iterator temp = *this;\n          utf8::prior(it, range_start);\n          return temp;\n      }\n    }; // class iterator\n\n} // namespace utf8\n\n#endif //header guard\n\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/utf8/core.h",
    "content": "// Copyright 2006 Nemanja Trifunovic\n\n/*\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n*/\n\n\n#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731\n#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731\n\n#include <iterator>\n\nnamespace utf8\n{\n    // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers\n    // You may need to change them to match your system.\n    // These typedefs have the same names as ones from cstdint, or boost/cstdint\n    typedef unsigned char   uint8_t;\n    typedef unsigned short  uint16_t;\n    typedef unsigned int    uint32_t;\n\n// Helper code - not intended to be directly called by the library users. May be changed at any time\nnamespace internal\n{\n    // Unicode constants\n    // Leading (high) surrogates: 0xd800 - 0xdbff\n    // Trailing (low) surrogates: 0xdc00 - 0xdfff\n    const uint16_t LEAD_SURROGATE_MIN  = 0xd800u;\n    const uint16_t LEAD_SURROGATE_MAX  = 0xdbffu;\n    const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;\n    const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;\n    const uint16_t LEAD_OFFSET         = LEAD_SURROGATE_MIN - (0x10000 >> 10);\n    const uint32_t SURROGATE_OFFSET    = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;\n\n    // Maximum valid value for a Unicode code point\n    const uint32_t CODE_POINT_MAX      = 0x0010ffffu;\n\n    template<typename octet_type>\n    inline uint8_t mask8(octet_type oc)\n    {\n        return static_cast<uint8_t>(0xff & oc);\n    }\n    template<typename u16_type>\n    inline uint16_t mask16(u16_type oc)\n    {\n        return static_cast<uint16_t>(0xffff & oc);\n    }\n    template<typename octet_type>\n    inline bool is_trail(octet_type oc)\n    {\n        return ((utf8::internal::mask8(oc) >> 6) == 0x2);\n    }\n\n    template <typename u16>\n    inline bool is_lead_surrogate(u16 cp)\n    {\n        return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);\n    }\n\n    template <typename u16>\n    inline bool is_trail_surrogate(u16 cp)\n    {\n        return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);\n    }\n\n    template <typename u16>\n    inline bool is_surrogate(u16 cp)\n    {\n        return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);\n    }\n\n    template <typename u32>\n    inline bool is_code_point_valid(u32 cp)\n    {\n        return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));\n    }\n\n    template <typename octet_iterator>\n    inline typename std::iterator_traits<octet_iterator>::difference_type\n    sequence_length(octet_iterator lead_it)\n    {\n        uint8_t lead = utf8::internal::mask8(*lead_it);\n        if (lead < 0x80)\n            return 1;\n        else if ((lead >> 5) == 0x6)\n            return 2;\n        else if ((lead >> 4) == 0xe)\n            return 3;\n        else if ((lead >> 3) == 0x1e)\n            return 4;\n        else\n            return 0;\n    }\n\n    template <typename octet_difference_type>\n    inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)\n    {\n        if (cp < 0x80) {\n            if (length != 1)\n                return true;\n        }\n        else if (cp < 0x800) {\n            if (length != 2)\n                return true;\n        }\n        else if (cp < 0x10000) {\n            if (length != 3)\n                return true;\n        }\n\n        return false;\n    }\n\n    enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};\n\n    /// Helper for get_sequence_x\n    template <typename octet_iterator>\n    utf_error increase_safely(octet_iterator& it, octet_iterator end)\n    {\n        if (++it == end)\n            return NOT_ENOUGH_ROOM;\n\n        if (!utf8::internal::is_trail(*it))\n            return INCOMPLETE_SEQUENCE;\n\n        return UTF8_OK;\n    }\n\n    #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}\n\n    /// get_sequence_x functions decode utf-8 sequences of the length x\n    template <typename octet_iterator>\n    utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)\n    {\n        if (it == end)\n            return NOT_ENOUGH_ROOM;\n\n        code_point = utf8::internal::mask8(*it);\n\n        return UTF8_OK;\n    }\n\n    template <typename octet_iterator>\n    utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)\n    {\n        if (it == end)\n            return NOT_ENOUGH_ROOM;\n\n        code_point = utf8::internal::mask8(*it);\n\n        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)\n\n        code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);\n\n        return UTF8_OK;\n    }\n\n    template <typename octet_iterator>\n    utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)\n    {\n        if (it == end)\n            return NOT_ENOUGH_ROOM;\n\n        code_point = utf8::internal::mask8(*it);\n\n        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)\n\n        code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);\n\n        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)\n\n        code_point += (*it) & 0x3f;\n\n        return UTF8_OK;\n    }\n\n    template <typename octet_iterator>\n    utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)\n    {\n        if (it == end)\n           return NOT_ENOUGH_ROOM;\n\n        code_point = utf8::internal::mask8(*it);\n\n        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)\n\n        code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);\n\n        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)\n\n        code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;\n\n        UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)\n\n        code_point += (*it) & 0x3f;\n\n        return UTF8_OK;\n    }\n\n    #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR\n\n    template <typename octet_iterator>\n    utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)\n    {\n        if (it == end)\n            return NOT_ENOUGH_ROOM;\n\n        // Save the original value of it so we can go back in case of failure\n        // Of course, it does not make much sense with i.e. stream iterators\n        octet_iterator original_it = it;\n\n        uint32_t cp = 0;\n        // Determine the sequence length based on the lead octet\n        typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;\n        const octet_difference_type length = utf8::internal::sequence_length(it);\n\n        // Get trail octets and calculate the code point\n        utf_error err = UTF8_OK;\n        switch (length) {\n            case 0:\n                return INVALID_LEAD;\n            case 1:\n                err = utf8::internal::get_sequence_1(it, end, cp);\n                break;\n            case 2:\n                err = utf8::internal::get_sequence_2(it, end, cp);\n            break;\n            case 3:\n                err = utf8::internal::get_sequence_3(it, end, cp);\n            break;\n            case 4:\n                err = utf8::internal::get_sequence_4(it, end, cp);\n            break;\n        }\n\n        if (err == UTF8_OK) {\n            // Decoding succeeded. Now, security checks...\n            if (utf8::internal::is_code_point_valid(cp)) {\n                if (!utf8::internal::is_overlong_sequence(cp, length)){\n                    // Passed! Return here.\n                    code_point = cp;\n                    ++it;\n                    return UTF8_OK;\n                }\n                else\n                    err = OVERLONG_SEQUENCE;\n            }\n            else\n                err = INVALID_CODE_POINT;\n        }\n\n        // Failure branch - restore the original value of the iterator\n        it = original_it;\n        return err;\n    }\n\n    template <typename octet_iterator>\n    inline utf_error validate_next(octet_iterator& it, octet_iterator end) {\n        uint32_t ignored;\n        return utf8::internal::validate_next(it, end, ignored);\n    }\n\n} // namespace internal\n\n    /// The library API - functions intended to be called by the users\n\n    // Byte order mark\n    const uint8_t bom[] = {0xef, 0xbb, 0xbf};\n\n    template <typename octet_iterator>\n    octet_iterator find_invalid(octet_iterator start, octet_iterator end)\n    {\n        octet_iterator result = start;\n        while (result != end) {\n            utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);\n            if (err_code != internal::UTF8_OK)\n                return result;\n        }\n        return result;\n    }\n\n    template <typename octet_iterator>\n    inline bool is_valid(octet_iterator start, octet_iterator end)\n    {\n        return (utf8::find_invalid(start, end) == end);\n    }\n\n    template <typename octet_iterator>\n    inline bool starts_with_bom (octet_iterator it, octet_iterator end)\n    {\n        return (\n            ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&\n            ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&\n            ((it != end) && (utf8::internal::mask8(*it))   == bom[2])\n           );\n    }\n\n    //Deprecated in release 2.3\n    template <typename octet_iterator>\n    inline bool is_bom (octet_iterator it)\n    {\n        return (\n            (utf8::internal::mask8(*it++)) == bom[0] &&\n            (utf8::internal::mask8(*it++)) == bom[1] &&\n            (utf8::internal::mask8(*it))   == bom[2]\n           );\n    }\n} // namespace utf8\n\n#endif // header guard\n\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/utf8/unchecked.h",
    "content": "// Copyright 2006 Nemanja Trifunovic\n\n/*\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n*/\n\n\n#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731\n#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731\n\n#include \"core.h\"\n\nnamespace utf8\n{\n    namespace unchecked\n    {\n        template <typename octet_iterator>\n        octet_iterator append(uint32_t cp, octet_iterator result)\n        {\n            if (cp < 0x80)                        // one octet\n                *(result++) = static_cast<uint8_t>(cp);\n            else if (cp < 0x800) {                // two octets\n                *(result++) = static_cast<uint8_t>((cp >> 6)          | 0xc0);\n                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);\n            }\n            else if (cp < 0x10000) {              // three octets\n                *(result++) = static_cast<uint8_t>((cp >> 12)         | 0xe0);\n                *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);\n                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);\n            }\n            else {                                // four octets\n                *(result++) = static_cast<uint8_t>((cp >> 18)         | 0xf0);\n                *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);\n                *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);\n                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);\n            }\n            return result;\n        }\n\n        template <typename octet_iterator>\n        uint32_t next(octet_iterator& it)\n        {\n            uint32_t cp = utf8::internal::mask8(*it);\n            typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);\n            switch (length) {\n                case 1:\n                    break;\n                case 2:\n                    it++;\n                    cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);\n                    break;\n                case 3:\n                    ++it;\n                    cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);\n                    ++it;\n                    cp += (*it) & 0x3f;\n                    break;\n                case 4:\n                    ++it;\n                    cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);\n                    ++it;\n                    cp += (utf8::internal::mask8(*it) << 6) & 0xfff;\n                    ++it;\n                    cp += (*it) & 0x3f;\n                    break;\n            }\n            ++it;\n            return cp;\n        }\n\n        template <typename octet_iterator>\n        uint32_t peek_next(octet_iterator it)\n        {\n            return utf8::unchecked::next(it);\n        }\n\n        template <typename octet_iterator>\n        uint32_t prior(octet_iterator& it)\n        {\n            while (utf8::internal::is_trail(*(--it))) ;\n            octet_iterator temp = it;\n            return utf8::unchecked::next(temp);\n        }\n\n        // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)\n        template <typename octet_iterator>\n        inline uint32_t previous(octet_iterator& it)\n        {\n            return utf8::unchecked::prior(it);\n        }\n\n        template <typename octet_iterator, typename distance_type>\n        void advance (octet_iterator& it, distance_type n)\n        {\n            for (distance_type i = 0; i < n; ++i)\n                utf8::unchecked::next(it);\n        }\n\n        template <typename octet_iterator, typename distance_type>\n        void retreat (octet_iterator& it, distance_type n)\n        {\n            for (distance_type i = 0; i < n; ++i)\n                utf8::unchecked::prior(it);\n        }\n\n        template <typename octet_iterator>\n        typename std::iterator_traits<octet_iterator>::difference_type\n        distance (octet_iterator first, octet_iterator last)\n        {\n            typename std::iterator_traits<octet_iterator>::difference_type dist;\n            for (dist = 0; first < last; ++dist)\n                utf8::unchecked::next(first);\n            return dist;\n        }\n\n        template <typename u16bit_iterator, typename octet_iterator>\n        octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)\n        {\n            while (start != end) {\n                uint32_t cp = utf8::internal::mask16(*start++);\n            // Take care of surrogate pairs first\n                if (utf8::internal::is_lead_surrogate(cp)) {\n                    uint32_t trail_surrogate = utf8::internal::mask16(*start++);\n                    cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;\n                }\n                result = utf8::unchecked::append(cp, result);\n            }\n            return result;\n        }\n\n        template <typename u16bit_iterator, typename octet_iterator>\n        u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)\n        {\n            while (start < end) {\n                uint32_t cp = utf8::unchecked::next(start);\n                if (cp > 0xffff) { //make a surrogate pair\n                    *result++ = static_cast<uint16_t>((cp >> 10)   + internal::LEAD_OFFSET);\n                    *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);\n                }\n                else\n                    *result++ = static_cast<uint16_t>(cp);\n            }\n            return result;\n        }\n\n        template <typename octet_iterator, typename u32bit_iterator>\n        octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)\n        {\n            while (start != end)\n                result = utf8::unchecked::append(*(start++), result);\n\n            return result;\n        }\n\n        template <typename octet_iterator, typename u32bit_iterator>\n        u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)\n        {\n            while (start < end)\n                (*result++) = utf8::unchecked::next(start);\n\n            return result;\n        }\n\n        // The iterator class\n        template <typename octet_iterator>\n          class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {\n            octet_iterator it;\n            public:\n            iterator () {}\n            explicit iterator (const octet_iterator& octet_it): it(octet_it) {}\n            // the default \"big three\" are OK\n            octet_iterator base () const { return it; }\n            uint32_t operator * () const\n            {\n                octet_iterator temp = it;\n                return utf8::unchecked::next(temp);\n            }\n            bool operator == (const iterator& rhs) const\n            {\n                return (it == rhs.it);\n            }\n            bool operator != (const iterator& rhs) const\n            {\n                return !(operator == (rhs));\n            }\n            iterator& operator ++ ()\n            {\n                ::std::advance(it, utf8::internal::sequence_length(it));\n                return *this;\n            }\n            iterator operator ++ (int)\n            {\n                iterator temp = *this;\n                ::std::advance(it, utf8::internal::sequence_length(it));\n                return temp;\n            }\n            iterator& operator -- ()\n            {\n                utf8::unchecked::prior(it);\n                return *this;\n            }\n            iterator operator -- (int)\n            {\n                iterator temp = *this;\n                utf8::unchecked::prior(it);\n                return temp;\n            }\n          }; // class iterator\n\n    } // namespace utf8::unchecked\n} // namespace utf8\n\n\n#endif // header guard\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/utf8.h",
    "content": "// Copyright 2006 Nemanja Trifunovic\n\n/*\nPermission is hereby granted, free of charge, to any person or organization\nobtaining a copy of the software and accompanying documentation covered by\nthis license (the \"Software\") to use, reproduce, display, distribute,\nexecute, and transmit the Software, and to prepare derivative works of the\nSoftware, and to permit third-parties to whom the Software is furnished to\ndo so, all subject to the following:\n\nThe copyright notices in the Software and this entire statement, including\nthe above license grant, this restriction and the following disclaimer,\nmust be included in all copies of the Software, in whole or in part, and\nall derivative works of the Software, unless such copies or derivative\nworks are solely in the form of machine-executable object code generated by\na source language processor.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\nSHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\nFOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\nARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n*/\n\n\n#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731\n#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731\n\n#include \"utf8/checked.h\"\n#include \"utf8/unchecked.h\"\n\n#endif // header guard\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/utf8_string.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include <string>\n#include <vector>\n#include <cstdlib>\n#include <cmath>\n\n#include \"utf8.h\"\n\nnamespace Sass {\n  namespace UTF_8 {\n\n    // naming conventions:\n    // offset: raw byte offset (0 based)\n    // position: code point offset (0 based)\n    // index: code point offset (1 based or negative)\n\n    // function that will count the number of code points (utf-8 characters) from the given beginning to the given end\n    size_t code_point_count(const sass::string& str, size_t start, size_t end) {\n      return utf8::distance(str.begin() + start, str.begin() + end);\n    }\n\n    size_t code_point_count(const sass::string& str) {\n      return utf8::distance(str.begin(), str.end());\n    }\n\n    // function that will return the byte offset at a code point position\n    size_t offset_at_position(const sass::string& str, size_t position) {\n      sass::string::const_iterator it = str.begin();\n      utf8::advance(it, position, str.end());\n      return std::distance(str.begin(), it);\n    }\n\n    // function that returns number of bytes in a character at offset\n    size_t code_point_size_at_offset(const sass::string& str, size_t offset) {\n      // get iterator from string and forward by offset\n      sass::string::const_iterator stop = str.begin() + offset;\n      // check if beyond boundary\n      if (stop == str.end()) return 0;\n      // advance by one code point\n      utf8::advance(stop, 1, str.end());\n      // calculate offset for code point\n      return  stop - str.begin() - offset;\n    }\n\n    // function that will return a normalized index, given a crazy one\n    size_t normalize_index(int index, size_t len) {\n      long signed_len = static_cast<long>(len);\n      // assuming the index is 1-based\n      // we are returning a 0-based index\n      if (index > 0 && index <= signed_len) {\n        // positive and within string length\n        return index-1;\n      }\n      else if (index > signed_len) {\n        // positive and past string length\n        return len;\n      }\n      else if (index == 0) {\n        return 0;\n      }\n      else if (std::abs((double)index) <= signed_len) {\n        // negative and within string length\n        return index + signed_len;\n      }\n      else {\n        // negative and past string length\n        return 0;\n      }\n    }\n\n    #ifdef _WIN32\n\n    // utf16 functions\n    using std::wstring;\n\n    // convert from utf16/wide string to utf8 string\n    sass::string convert_from_utf16(const wstring& utf16)\n    {\n      sass::string utf8;\n      // pre-allocate expected memory\n      utf8.reserve(sizeof(utf16)/2);\n      utf8::utf16to8(utf16.begin(), utf16.end(),\n                     back_inserter(utf8));\n      return utf8;\n    }\n\n    // convert from utf8 string to utf16/wide string\n    wstring convert_to_utf16(const sass::string& utf8)\n    {\n      wstring utf16;\n      // pre-allocate expected memory\n      utf16.reserve(code_point_count(utf8)*2);\n      utf8::utf8to16(utf8.begin(), utf8.end(),\n                     back_inserter(utf16));\n      return utf16;\n    }\n\n    #endif\n\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/utf8_string.hpp",
    "content": "#ifndef SASS_UTF8_STRING_H\n#define SASS_UTF8_STRING_H\n\n#include <string>\n#include \"utf8.h\"\n#include \"memory.hpp\"\n\nnamespace Sass {\n  namespace UTF_8 {\n\n    // naming conventions:\n    // offset: raw byte offset (0 based)\n    // position: code point offset (0 based)\n    // index: code point offset (1 based or negative)\n\n    // function that will count the number of code points (utf-8 characters) from the beginning to the given end\n    size_t code_point_count(const sass::string& str, size_t start, size_t end);\n    size_t code_point_count(const sass::string& str);\n\n    // function that will return the byte offset of a code point in a\n    size_t offset_at_position(const sass::string& str, size_t position);\n\n    // function that returns number of bytes in a character in a string\n    size_t code_point_size_at_offset(const sass::string& str, size_t offset);\n\n    // function that will return a normalized index, given a crazy one\n    size_t normalize_index(int index, size_t len);\n\n    #ifdef _WIN32\n    // functions to handle unicode paths on windows\n    sass::string convert_from_utf16(const std::wstring& wstr);\n    std::wstring convert_to_utf16(const sass::string& str);\n    #endif\n\n  }\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/util.cpp",
    "content": "#include \"sass.hpp\"\n#include \"sass.h\"\n#include \"ast.hpp\"\n#include \"util.hpp\"\n#include \"util_string.hpp\"\n#include \"lexer.hpp\"\n#include \"prelexer.hpp\"\n#include \"constants.hpp\"\n#include \"utf8/checked.h\"\n\n#include <cmath>\n#include <stdint.h>\n#if defined(_MSC_VER) && _MSC_VER >= 1800 && _MSC_VER < 1900 && defined(_M_X64)\n#include <mutex>\n#endif\n\nnamespace Sass {\n\n  double round(double val, size_t precision)\n  {\n    // Disable FMA3-optimized implementation when compiling with VS2013 for x64 targets\n    // See https://github.com/sass/node-sass/issues/1854 for details\n    // FIXME: Remove this workaround when we switch to VS2015+\n    #if defined(_MSC_VER) && _MSC_VER >= 1800 && _MSC_VER < 1900 && defined(_M_X64)\n      static std::once_flag flag;\n      std::call_once(flag, []() { _set_FMA3_enable(0); });\n    #endif\n\n    // https://github.com/sass/sass/commit/4e3e1d5684cc29073a507578fc977434ff488c93\n    if (std::fmod(val, 1) - 0.5 > - std::pow(0.1, precision + 1)) return std::ceil(val);\n    else if (std::fmod(val, 1) - 0.5 > std::pow(0.1, precision)) return std::floor(val);\n    // work around some compiler issue\n    // cygwin has it not defined in std\n    using namespace std;\n    return ::round(val);\n  }\n\n  /* Locale unspecific atof function. */\n  double sass_strtod(const char *str)\n  {\n    char separator = *(localeconv()->decimal_point);\n    if(separator != '.'){\n      // The current locale specifies another\n      // separator. convert the separator to the\n      // one understood by the locale if needed\n      const char *found = strchr(str, '.');\n      if(found != NULL){\n        // substitution is required. perform the substitution on a copy\n        // of the string. This is slower but it is thread safe.\n        char *copy = sass_copy_c_string(str);\n        *(copy + (found - str)) = separator;\n        double res = strtod(copy, NULL);\n        free(copy);\n        return res;\n      }\n    }\n\n    return strtod(str, NULL);\n  }\n\n  // helper for safe access to c_ctx\n  const char* safe_str (const char* str, const char* alt) {\n    return str == NULL ? alt : str;\n  }\n\n  void free_string_array(char ** arr) {\n    if(!arr)\n        return;\n\n    char **it = arr;\n    while (it && (*it)) {\n      free(*it);\n      ++it;\n    }\n\n    free(arr);\n  }\n\n  char **copy_strings(const sass::vector<sass::string>& strings, char*** array, int skip) {\n    int num = static_cast<int>(strings.size()) - skip;\n    char** arr = (char**) calloc(num + 1, sizeof(char*));\n    if (arr == 0)\n      return *array = (char **)NULL;\n\n    for(int i = 0; i < num; i++) {\n      arr[i] = (char*) malloc(sizeof(char) * (strings[i + skip].size() + 1));\n      if (arr[i] == 0) {\n        free_string_array(arr);\n        return *array = (char **)NULL;\n      }\n      std::copy(strings[i + skip].begin(), strings[i + skip].end(), arr[i]);\n      arr[i][strings[i + skip].size()] = '\\0';\n    }\n\n    arr[num] = 0;\n    return *array = arr;\n  }\n\n  // read css string (handle multiline DELIM)\n  sass::string read_css_string(const sass::string& str, bool css)\n  {\n    if (!css) return str;\n    sass::string out(\"\");\n    bool esc = false;\n    for (auto i : str) {\n      if (i == '\\\\') {\n        esc = ! esc;\n      } else if (esc && i == '\\r') {\n        continue;\n      } else if (esc && i == '\\n') {\n        out.resize (out.size () - 1);\n        esc = false;\n        continue;\n      } else {\n        esc = false;\n      }\n      out.push_back(i);\n    }\n    // happens when parsing does not correctly skip\n    // over escaped sequences for ie. interpolations\n    // one example: foo\\#{interpolate}\n    // if (esc) out += '\\\\';\n    return out;\n  }\n\n  // double escape all escape sequences\n  // keep unescaped quotes and backslashes\n  sass::string evacuate_escapes(const sass::string& str)\n  {\n    sass::string out(\"\");\n    bool esc = false;\n    for (auto i : str) {\n      if (i == '\\\\' && !esc) {\n        out += '\\\\';\n        out += '\\\\';\n        esc = true;\n      } else if (esc && i == '\"') {\n        out += '\\\\';\n        out += i;\n        esc = false;\n      } else if (esc && i == '\\'') {\n        out += '\\\\';\n        out += i;\n        esc = false;\n      } else if (esc && i == '\\\\') {\n        out += '\\\\';\n        out += i;\n        esc = false;\n      } else {\n        esc = false;\n        out += i;\n      }\n    }\n    // happens when parsing does not correctly skip\n    // over escaped sequences for ie. interpolations\n    // one example: foo\\#{interpolate}\n    // if (esc) out += '\\\\';\n    return out;\n  }\n\n  // bell characters are replaced with spaces\n  void newline_to_space(sass::string& str)\n  {\n    std::replace(str.begin(), str.end(), '\\n', ' ');\n  }\n\n  // 1. Removes whitespace after newlines.\n  // 2. Replaces newlines with spaces.\n  //\n  // This method only considers LF and CRLF as newlines.\n  sass::string string_to_output(const sass::string& str)\n  {\n    sass::string result;\n    result.reserve(str.size());\n    std::size_t pos = 0;\n    while (true) {\n      const std::size_t newline = str.find_first_of(\"\\n\\r\", pos);\n      if (newline == sass::string::npos) break;\n      result.append(str, pos, newline - pos);\n      if (str[newline] == '\\r') {\n        if (str[newline + 1] == '\\n') {\n          pos = newline + 2;\n        } else {\n          // CR without LF: append as-is and continue.\n          result += '\\r';\n          pos = newline + 1;\n          continue;\n        }\n      } else {\n        pos = newline + 1;\n      }\n      result += ' ';\n      const std::size_t non_space = str.find_first_not_of(\" \\f\\n\\r\\t\\v\", pos);\n      if (non_space != sass::string::npos) {\n        pos = non_space;\n      }\n    }\n    result.append(str, pos, sass::string::npos);\n    return result;\n  }\n\n  sass::string escape_string(const sass::string& str)\n  {\n    sass::string out;\n    out.reserve(str.size());\n    for (char c : str) {\n      switch (c) {\n        case '\\n':\n          out.append(\"\\\\n\");\n          break;\n        case '\\r':\n          out.append(\"\\\\r\");\n          break;\n        case '\\f':\n          out.append(\"\\\\f\");\n          break;\n        default:\n          out += c;\n      }\n    }\n    return out;\n  }\n\n  sass::string comment_to_compact_string(const sass::string& text)\n  {\n    sass::string str = \"\";\n    size_t has = 0;\n    char prev = 0;\n    bool clean = false;\n    for (auto i : text) {\n      if (clean) {\n        if (i == '\\n') { has = 0; }\n        else if (i == '\\t') { ++ has; }\n        else if (i == ' ') { ++ has; }\n        else if (i == '*') {}\n        else {\n          clean = false;\n          str += ' ';\n          if (prev == '*' && i == '/') str += \"*/\";\n          else str += i;\n        }\n      } else if (i == '\\n') {\n        clean = true;\n      } else {\n        str += i;\n      }\n      prev = i;\n    }\n    if (has) return str;\n    else return text;\n  }\n\n  // find best quote_mark by detecting if the string contains any single\n  // or double quotes. When a single quote is found, we not we want a double\n  // quote as quote_mark. Otherwise we check if the string cotains any double\n  // quotes, which will trigger the use of single quotes as best quote_mark.\n  char detect_best_quotemark(const char* s, char qm)\n  {\n    // ensure valid fallback quote_mark\n    char quote_mark = qm && qm != '*' ? qm : '\"';\n    while (*s) {\n      // force double quotes as soon\n      // as one single quote is found\n      if (*s == '\\'') { return '\"'; }\n      // a single does not force quote_mark\n      // maybe we see a double quote later\n      else if (*s == '\"') { quote_mark = '\\''; }\n      ++ s;\n    }\n    return quote_mark;\n  }\n\n  sass::string read_hex_escapes(const sass::string& s)\n  {\n\n    sass::string result;\n    bool skipped = false;\n\n    for (size_t i = 0, L = s.length(); i < L; ++i) {\n\n      // implement the same strange ruby sass behavior\n      // an escape sequence can also mean a unicode char\n      if (s[i] == '\\\\' && !skipped) {\n\n        // remember\n        skipped = true;\n\n        // escape length\n        size_t len = 1;\n\n        // parse as many sequence chars as possible\n        // ToDo: Check if ruby aborts after possible max\n        while (i + len < L && s[i + len] && Util::ascii_isxdigit(static_cast<unsigned char>(s[i + len]))) ++ len;\n\n        if (len > 1) {\n\n          // convert the extracted hex string to code point value\n          // ToDo: Maybe we could do this without creating a substring\n          uint32_t cp = strtol(s.substr (i + 1, len - 1).c_str(), NULL, 16);\n\n          if (s[i + len] == ' ') ++ len;\n\n          // assert invalid code points\n          if (cp == 0) cp = 0xFFFD;\n          // replace bell character\n          // if (cp == '\\n') cp = 32;\n\n          // use a very simple approach to convert via utf8 lib\n          // maybe there is a more elegant way; maybe we shoud\n          // convert the whole output from string to a stream!?\n          // allocate memory for utf8 char and convert to utf8\n          unsigned char u[5] = {0,0,0,0,0}; utf8::append(cp, u);\n          for(size_t m = 0; m < 5 && u[m]; m++) result.push_back(u[m]);\n\n          // skip some more chars?\n          i += len - 1; skipped = false;\n\n        }\n\n        else {\n\n          skipped = false;\n\n          result.push_back(s[i]);\n\n        }\n\n      }\n\n      else {\n\n        result.push_back(s[i]);\n\n      }\n\n    }\n\n    return result;\n\n  }\n\n  sass::string unquote(const sass::string& s, char* qd, bool keep_utf8_sequences, bool strict)\n  {\n\n    // not enough room for quotes\n    // no possibility to unquote\n    if (s.length() < 2) return s;\n\n    char q;\n    bool skipped = false;\n\n    // this is no guarantee that the unquoting will work\n    // what about whitespace before/after the quote_mark?\n    if      (*s.begin() == '\"'  && *s.rbegin() == '\"')  q = '\"';\n    else if (*s.begin() == '\\'' && *s.rbegin() == '\\'') q = '\\'';\n    else                                                return s;\n\n    sass::string unq;\n    unq.reserve(s.length()-2);\n\n    for (size_t i = 1, L = s.length() - 1; i < L; ++i) {\n\n      // implement the same strange ruby sass behavior\n      // an escape sequence can also mean a unicode char\n      if (s[i] == '\\\\' && !skipped) {\n        // remember\n        skipped = true;\n\n        // skip it\n        // ++ i;\n\n        // if (i == L) break;\n\n        // escape length\n        size_t len = 1;\n\n        // parse as many sequence chars as possible\n        // ToDo: Check if ruby aborts after possible max\n        while (i + len < L && s[i + len] && Util::ascii_isxdigit(static_cast<unsigned char>(s[i + len]))) ++ len;\n\n        // hex string?\n        if (keep_utf8_sequences) {\n          unq.push_back(s[i]);\n        } else if (len > 1) {\n\n          // convert the extracted hex string to code point value\n          // ToDo: Maybe we could do this without creating a substring\n          uint32_t cp = strtol(s.substr (i + 1, len - 1).c_str(), NULL, 16);\n\n          if (s[i + len] == ' ') ++ len;\n\n          // assert invalid code points\n          if (cp == 0) cp = 0xFFFD;\n          // replace bell character\n          // if (cp == '\\n') cp = 32;\n\n          // use a very simple approach to convert via utf8 lib\n          // maybe there is a more elegant way; maybe we shoud\n          // convert the whole output from string to a stream!?\n          // allocate memory for utf8 char and convert to utf8\n          unsigned char u[5] = {0,0,0,0,0}; utf8::append(cp, u);\n          for(size_t m = 0; m < 5 && u[m]; m++) unq.push_back(u[m]);\n\n          // skip some more chars?\n          i += len - 1; skipped = false;\n\n        }\n\n\n      }\n      // check for unexpected delimiter\n      // be strict and throw error back\n      // else if (!skipped && q == s[i]) {\n      //   // don't be that strict\n      //   return s;\n      //   // this basically always means an internal error and not users fault\n      //   error(\"Unescaped delimiter in string to unquote found. [\" + s + \"]\", SourceSpan(\"[UNQUOTE]\"));\n      // }\n      else {\n        if (strict && !skipped) {\n          if (s[i] == q) return s;\n        }\n        skipped = false;\n        unq.push_back(s[i]);\n      }\n\n    }\n    if (skipped) { return s; }\n    if (qd) *qd = q;\n    return unq;\n\n  }\n\n  sass::string quote(const sass::string& s, char q)\n  {\n\n    // autodetect with fallback to given quote\n    q = detect_best_quotemark(s.c_str(), q);\n\n    // return an empty quoted string\n    if (s.empty()) return sass::string(2, q ? q : '\"');\n\n    sass::string quoted;\n    quoted.reserve(s.length()+2);\n    quoted.push_back(q);\n\n    const char* it = s.c_str();\n    const char* end = it + strlen(it) + 1;\n    while (*it && it < end) {\n      const char* now = it;\n\n      if (*it == q) {\n        quoted.push_back('\\\\');\n      } else if (*it == '\\\\') {\n        quoted.push_back('\\\\');\n      }\n\n      int cp = utf8::next(it, end);\n\n      // in case of \\r, check if the next in sequence\n      // is \\n and then advance the iterator and skip \\r\n      if (cp == '\\r' && it < end && utf8::peek_next(it, end) == '\\n') {\n        cp = utf8::next(it, end);\n      }\n\n      if (cp == '\\n') {\n        quoted.push_back('\\\\');\n        quoted.push_back('a');\n        // we hope we can remove this flag once we figure out\n        // why ruby sass has these different output behaviors\n        // gsub(/\\n(?![a-fA-F0-9\\s])/, \"\\\\a\").gsub(\"\\n\", \"\\\\a \")\n        using namespace Prelexer;\n        if (alternatives <\n          Prelexer::char_range<'a', 'f'>,\n          Prelexer::char_range<'A', 'F'>,\n          Prelexer::char_range<'0', '9'>,\n          space\n        >(it) != NULL) {\n          quoted.push_back(' ');\n        }\n      } else if (cp < 127) {\n        quoted.push_back((char) cp);\n      } else {\n        while (now < it) {\n          quoted.push_back(*now);\n          ++ now;\n        }\n      }\n    }\n\n    quoted.push_back(q);\n    return quoted;\n  }\n\n  bool is_hex_doublet(double n)\n  {\n    return n == 0x00 || n == 0x11 || n == 0x22 || n == 0x33 ||\n           n == 0x44 || n == 0x55 || n == 0x66 || n == 0x77 ||\n           n == 0x88 || n == 0x99 || n == 0xAA || n == 0xBB ||\n           n == 0xCC || n == 0xDD || n == 0xEE || n == 0xFF ;\n  }\n\n  bool is_color_doublet(double r, double g, double b)\n  {\n    return is_hex_doublet(r) && is_hex_doublet(g) && is_hex_doublet(b);\n  }\n\n  bool peek_linefeed(const char* start)\n  {\n    using namespace Prelexer;\n    using namespace Constants;\n    return sequence <\n             zero_plus <\n               alternatives <\n                 exactly <' '>,\n                 exactly <'\\t'>,\n                 line_comment,\n                 block_comment,\n                 delimited_by <\n                   slash_star,\n                   star_slash,\n                   false\n                 >\n               >\n             >,\n             re_linebreak\n           >(start) != 0;\n  }\n\n  namespace Util {\n\n    bool isPrintable(StyleRule* r, Sass_Output_Style style) {\n      if (r == NULL) {\n        return false;\n      }\n\n      Block_Obj b = r->block();\n\n      SelectorList* sl = r->selector();\n      bool hasSelectors = sl ? sl->length() > 0 : false;\n\n      if (!hasSelectors) {\n        return false;\n      }\n\n      bool hasDeclarations = false;\n      bool hasPrintableChildBlocks = false;\n      for (size_t i = 0, L = b->length(); i < L; ++i) {\n        Statement_Obj stm = b->at(i);\n        if (Cast<AtRule>(stm)) {\n          return true;\n        } else if (Declaration* d = Cast<Declaration>(stm)) {\n          return isPrintable(d, style);\n        } else if (ParentStatement* p = Cast<ParentStatement>(stm)) {\n          Block_Obj pChildBlock = p->block();\n          if (isPrintable(pChildBlock, style)) {\n            hasPrintableChildBlocks = true;\n          }\n        } else if (Comment* c = Cast<Comment>(stm)) {\n          // keep for uncompressed\n          if (style != COMPRESSED) {\n            hasDeclarations = true;\n          }\n          // output style compressed\n          if (c->is_important()) {\n            hasDeclarations = c->is_important();\n          }\n        } else {\n          hasDeclarations = true;\n        }\n\n        if (hasDeclarations || hasPrintableChildBlocks) {\n          return true;\n        }\n      }\n\n      return false;\n    }\n\n    bool isPrintable(String_Constant* s, Sass_Output_Style style)\n    {\n      return ! s->value().empty();\n    }\n\n    bool isPrintable(String_Quoted* s, Sass_Output_Style style)\n    {\n      return true;\n    }\n\n    bool isPrintable(Declaration* d, Sass_Output_Style style)\n    {\n      ExpressionObj val = d->value();\n      if (String_Quoted_Obj sq = Cast<String_Quoted>(val)) return isPrintable(sq.ptr(), style);\n      if (String_Constant_Obj sc = Cast<String_Constant>(val)) return isPrintable(sc.ptr(), style);\n      return true;\n    }\n\n    bool isPrintable(SupportsRule* f, Sass_Output_Style style) {\n      if (f == NULL) {\n        return false;\n      }\n\n      Block_Obj b = f->block();\n\n      bool hasDeclarations = false;\n      bool hasPrintableChildBlocks = false;\n      for (size_t i = 0, L = b->length(); i < L; ++i) {\n        Statement_Obj stm = b->at(i);\n        if (Cast<Declaration>(stm) || Cast<AtRule>(stm)) {\n          hasDeclarations = true;\n        }\n        else if (ParentStatement* b = Cast<ParentStatement>(stm)) {\n          Block_Obj pChildBlock = b->block();\n          if (!b->is_invisible()) {\n            if (isPrintable(pChildBlock, style)) {\n              hasPrintableChildBlocks = true;\n            }\n          }\n        }\n\n        if (hasDeclarations || hasPrintableChildBlocks) {\n          return true;\n        }\n      }\n\n      return false;\n    }\n\n    bool isPrintable(CssMediaRule* m, Sass_Output_Style style)\n    {\n      if (m == nullptr) return false;\n      Block_Obj b = m->block();\n      if (b == nullptr) return false;\n      if (m->empty()) return false;\n      for (size_t i = 0, L = b->length(); i < L; ++i) {\n        Statement_Obj stm = b->at(i);\n        if (Cast<AtRule>(stm)) return true;\n        else if (Cast<Declaration>(stm)) return true;\n        else if (Comment* c = Cast<Comment>(stm)) {\n          if (isPrintable(c, style)) {\n            return true;\n          }\n        }\n        else if (StyleRule* r = Cast<StyleRule>(stm)) {\n          if (isPrintable(r, style)) {\n            return true;\n          }\n        }\n        else if (SupportsRule* f = Cast<SupportsRule>(stm)) {\n          if (isPrintable(f, style)) {\n            return true;\n          }\n        }\n        else if (CssMediaRule* mb = Cast<CssMediaRule>(stm)) {\n          if (isPrintable(mb, style)) {\n            return true;\n          }\n        }\n        else if (ParentStatement* b = Cast<ParentStatement>(stm)) {\n          if (isPrintable(b->block(), style)) {\n            return true;\n          }\n        }\n      }\n      return false;\n    }\n\n    bool isPrintable(Comment* c, Sass_Output_Style style)\n    {\n      // keep for uncompressed\n      if (style != COMPRESSED) {\n        return true;\n      }\n      // output style compressed\n      if (c->is_important()) {\n        return true;\n      }\n      // not printable\n      return false;\n    };\n\n    bool isPrintable(Block_Obj b, Sass_Output_Style style) {\n      if (!b) {\n        return false;\n      }\n\n      for (size_t i = 0, L = b->length(); i < L; ++i) {\n        Statement_Obj stm = b->at(i);\n        if (Cast<Declaration>(stm) || Cast<AtRule>(stm)) {\n          return true;\n        }\n        else if (Comment* c = Cast<Comment>(stm)) {\n          if (isPrintable(c, style)) {\n            return true;\n          }\n        }\n        else if (StyleRule* r = Cast<StyleRule>(stm)) {\n          if (isPrintable(r, style)) {\n            return true;\n          }\n        }\n        else if (SupportsRule* f = Cast<SupportsRule>(stm)) {\n          if (isPrintable(f, style)) {\n            return true;\n          }\n        }\n        else if (CssMediaRule * m = Cast<CssMediaRule>(stm)) {\n          if (isPrintable(m, style)) {\n            return true;\n          }\n        }\n        else if (ParentStatement* b = Cast<ParentStatement>(stm)) {\n          if (isPrintable(b->block(), style)) {\n            return true;\n          }\n        }\n      }\n\n      return false;\n    }\n\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/util.hpp",
    "content": "#ifndef SASS_UTIL_H\n#define SASS_UTIL_H\n\n// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"sass/base.h\"\n#include \"ast_fwd_decl.hpp\"\n\n#include <cmath>\n#include <cstring>\n#include <vector>\n#include <string>\n#include <assert.h>\n\n#define SASS_ASSERT(cond, msg) assert(cond && msg)\n\nnamespace Sass {\n\n  template <typename T>\n  T clip(const T& n, const T& lower, const T& upper) {\n    return std::max(lower, std::min(n, upper));\n  }\n\n  template <typename T>\n  T absmod(const T& n, const T& r) {\n    T m = std::fmod(n, r);\n    if (m < 0.0) m += r;\n    return m;\n  }\n\n  double round(double val, size_t precision = 0);\n  double sass_strtod(const char* str);\n  const char* safe_str(const char *, const char* = \"\");\n  void free_string_array(char **);\n  char **copy_strings(const sass::vector<sass::string>&, char ***, int = 0);\n  sass::string read_css_string(const sass::string& str, bool css = true);\n  sass::string evacuate_escapes(const sass::string& str);\n  sass::string string_to_output(const sass::string& str);\n  sass::string comment_to_compact_string(const sass::string& text);\n  sass::string read_hex_escapes(const sass::string& str);\n  sass::string escape_string(const sass::string& str);\n  void newline_to_space(sass::string& str);\n\n  sass::string quote(const sass::string&, char q = 0);\n  sass::string unquote(const sass::string&, char* q = 0, bool keep_utf8_sequences = false, bool strict = true);\n  char detect_best_quotemark(const char* s, char qm = '\"');\n\n  bool is_hex_doublet(double n);\n  bool is_color_doublet(double r, double g, double b);\n\n  bool peek_linefeed(const char* start);\n\n  // Returns true iff `elements` ⊆ `container`.\n  template <typename C, typename T>\n  bool contains_all(C container, T elements) {\n    for (const auto &el : elements) {\n      if (container.find(el) == container.end()) return false;\n    }\n    return true;\n  }\n\n  // C++20 `starts_with` equivalent.\n  // See https://en.cppreference.com/w/cpp/string/basic_string/starts_with\n  inline bool starts_with(const sass::string& str, const char* prefix, size_t prefix_len) {\n    return str.compare(0, prefix_len, prefix) == 0;\n  }\n\n  inline bool starts_with(const sass::string& str, const char* prefix) {\n    return starts_with(str, prefix, std::strlen(prefix));\n  }\n\n  // C++20 `ends_with` equivalent.\n  // See https://en.cppreference.com/w/cpp/string/basic_string/ends_with\n  inline bool ends_with(const sass::string& str, const sass::string& suffix) {\n    return suffix.size() <= str.size() && std::equal(suffix.rbegin(), suffix.rend(), str.rbegin());\n  }\n\n  inline bool ends_with(const sass::string& str, const char* suffix, size_t suffix_len) {\n    if (suffix_len > str.size()) return false;\n    const char* suffix_it = suffix + suffix_len;\n    const char* str_it = str.c_str() + str.size();\n    while (suffix_it != suffix) if (*(--suffix_it) != *(--str_it)) return false;\n    return true;\n  }\n\n  inline bool ends_with(const sass::string& str, const char* suffix) {\n    return ends_with(str, suffix, std::strlen(suffix));\n  }\n\n  namespace Util {\n\n    bool isPrintable(StyleRule* r, Sass_Output_Style style = NESTED);\n    bool isPrintable(SupportsRule* r, Sass_Output_Style style = NESTED);\n    bool isPrintable(CssMediaRule* r, Sass_Output_Style style = NESTED);\n    bool isPrintable(Comment* b, Sass_Output_Style style = NESTED);\n    bool isPrintable(Block_Obj b, Sass_Output_Style style = NESTED);\n    bool isPrintable(String_Constant* s, Sass_Output_Style style = NESTED);\n    bool isPrintable(String_Quoted* s, Sass_Output_Style style = NESTED);\n    bool isPrintable(Declaration* d, Sass_Output_Style style = NESTED);\n\n  }\n}\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/util_string.cpp",
    "content": "#include \"util_string.hpp\"\n\n#include <iostream>\n#include <algorithm>\n\nnamespace Sass {\n  namespace Util {\n\n    // ##########################################################################\n    // Special case insensitive string matcher. We can optimize\n    // the more general compare case quite a bit by requiring\n    // consumers to obey some rules (lowercase and no space).\n    // - `literal` must only contain lower case ascii characters\n    // there is one edge case where this could give false positives\n    // test could contain a (non-ascii) char exactly 32 below literal\n    // ##########################################################################\n    bool equalsLiteral(const char* lit, const sass::string& test) {\n      // Work directly on characters\n      const char* src = test.c_str();\n      // There is a small chance that the search string\n      // Is longer than the rest of the string to look at\n      while (*lit && (*src == *lit || *src + 32 == *lit)) {\n        ++src, ++lit;\n      }\n      // True if literal is at end\n      // If not test was too long\n      return *lit == 0;\n    }\n\n    void ascii_str_tolower(sass::string* s) {\n      for (auto& ch : *s) {\n        ch = ascii_tolower(static_cast<unsigned char>(ch));\n      }\n    }\n\n    void ascii_str_toupper(sass::string* s) {\n      for (auto& ch : *s) {\n        ch = ascii_toupper(static_cast<unsigned char>(ch));\n      }\n    }\n\n    sass::string rtrim(sass::string str) {\n      auto it = std::find_if_not(str.rbegin(), str.rend(), ascii_isspace);\n      str.erase(str.rend() - it);\n      return str;\n    }\n\n    // ###########################################################################\n    // Returns [name] without a vendor prefix.\n    // If [name] has no vendor prefix, it's returned as-is.\n    // ###########################################################################\n    sass::string unvendor(const sass::string& name)\n    {\n      if (name.size() < 2) return name;\n      if (name[0] != '-') return name;\n      if (name[1] == '-') return name;\n      for (size_t i = 2; i < name.size(); i++) {\n        if (name[i] == '-') return name.substr(i + 1);\n      }\n      return name;\n    }\n    // EO unvendor\n\n    sass::string normalize_newlines(const sass::string& str) {\n      sass::string result;\n      result.reserve(str.size());\n      std::size_t pos = 0;\n      while (true) {\n        const std::size_t newline = str.find_first_of(\"\\n\\f\\r\", pos);\n        if (newline == sass::string::npos) break;\n        result.append(str, pos, newline - pos);\n        result += '\\n';\n        if (str[newline] == '\\r' && str[newline + 1] == '\\n') {\n          pos = newline + 2;\n        }\n        else {\n          pos = newline + 1;\n        }\n      }\n      result.append(str, pos, sass::string::npos);\n      return result;\n    }\n\n    sass::string normalize_underscores(const sass::string& str) {\n      sass::string normalized = str;\n      std::replace(normalized.begin(), normalized.end(), '_', '-');\n      return normalized;\n    }\n\n    sass::string normalize_decimals(const sass::string& str) {\n      sass::string normalized;\n      if (!str.empty() && str[0] == '.') {\n        normalized.reserve(str.size() + 1);\n        normalized += '0';\n        normalized += str;\n      }\n      else {\n        normalized = str;\n      }\n      return normalized;\n    }\n\n    char opening_bracket_for(char closing_bracket) {\n      switch (closing_bracket) {\n      case ')': return '(';\n      case ']': return '[';\n      case '}': return '{';\n      default: return '\\0';\n      }\n    }\n\n    char closing_bracket_for(char opening_bracket) {\n      switch (opening_bracket) {\n      case '(': return ')';\n      case '[': return ']';\n      case '{': return '}';\n      default: return '\\0';\n      }\n    }\n\n  }\n  // namespace Util\n\n}\n// namespace Sass\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/util_string.hpp",
    "content": "#ifndef SASS_UTIL_STRING_H\n#define SASS_UTIL_STRING_H\n\n#include \"sass.hpp\"\n#include <string>\n\nnamespace Sass {\n  namespace Util {\n\n    // ##########################################################################\n    // Special case insensitive string matcher. We can optimize\n    // the more general compare case quite a bit by requiring\n    // consumers to obey some rules (lowercase and no space).\n    // - `literal` must only contain lower case ascii characters\n    // there is one edge case where this could give false positives\n    // test could contain a (non-ascii) char exactly 32 below literal\n    // ##########################################################################\n    bool equalsLiteral(const char* lit, const sass::string& test);\n\n    // ###########################################################################\n    // Returns [name] without a vendor prefix.\n    // If [name] has no vendor prefix, it's returned as-is.\n    // ###########################################################################\n    sass::string unvendor(const sass::string& name);\n\n    sass::string rtrim(sass::string str);\n    sass::string normalize_newlines(const sass::string& str);\n    sass::string normalize_underscores(const sass::string& str);\n    sass::string normalize_decimals(const sass::string& str);\n    char opening_bracket_for(char closing_bracket);\n    char closing_bracket_for(char opening_bracket);\n\n    // Locale-independent ASCII character routines.\n\n    inline bool ascii_isalpha(unsigned char c) {\n      return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');\n    }\n\n    inline bool ascii_isdigit(unsigned char c) {\n      return (c >= '0' && c <= '9');\n    }\n\n    inline bool ascii_isalnum(unsigned char c) {\n      return ascii_isalpha(c) || ascii_isdigit(c);\n    }\n\n    inline bool ascii_isascii(unsigned char c) { return c < 128; }\n\n    inline bool ascii_isxdigit(unsigned char c) {\n      return ascii_isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');\n    }\n\n    inline bool ascii_isspace(unsigned char c) {\n      return c == ' ' || c == '\\t' || c == '\\v' || c == '\\f' || c == '\\r' || c == '\\n';\n    }\n\n    inline char ascii_tolower(unsigned char c) {\n      if (c >= 'A' && c <= 'Z') return c + 32;\n      return c;\n    }\n\n    void ascii_str_tolower(sass::string* s);\n\n    inline char ascii_toupper(unsigned char c) {\n      if (c >= 'a' && c <= 'z') return c - 32;\n      return c;\n    }\n\n    void ascii_str_toupper(sass::string* s);\n\n  }  // namespace Sass\n}  // namespace Util\n#endif  // SASS_UTIL_STRING_H\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/values.cpp",
    "content": "// sass.hpp must go before all system headers to get the\n// __EXTENSIONS__ fix on Solaris.\n#include \"sass.hpp\"\n\n#include \"sass.h\"\n#include \"values.hpp\"\n\n#include <stdint.h>\n\nnamespace Sass {\n\n  // convert value from C++ side to C-API\n  union Sass_Value* ast_node_to_sass_value (const Expression* val)\n  {\n    if (val->concrete_type() == Expression::NUMBER)\n    {\n      const Number* res = Cast<Number>(val);\n      return sass_make_number(res->value(), res->unit().c_str());\n    }\n    else if (val->concrete_type() == Expression::COLOR)\n    {\n      if (const Color_RGBA* rgba = Cast<Color_RGBA>(val)) {\n        return sass_make_color(rgba->r(), rgba->g(), rgba->b(), rgba->a());\n      } else {\n        // ToDo: allow to also use HSLA colors!!\n        Color_RGBA_Obj col = Cast<Color>(val)->copyAsRGBA();\n        return sass_make_color(col->r(), col->g(), col->b(), col->a());\n      }\n    }\n    else if (val->concrete_type() == Expression::LIST)\n    {\n      const List* l = Cast<List>(val);\n      union Sass_Value* list = sass_make_list(l->size(), l->separator(), l->is_bracketed());\n      for (size_t i = 0, L = l->length(); i < L; ++i) {\n        ExpressionObj obj = l->at(i);\n        auto val = ast_node_to_sass_value(obj);\n        sass_list_set_value(list, i, val);\n      }\n      return list;\n    }\n    else if (val->concrete_type() == Expression::MAP)\n    {\n      const Map* m = Cast<Map>(val);\n      union Sass_Value* map = sass_make_map(m->length());\n      size_t i = 0; for (ExpressionObj key : m->keys()) {\n        sass_map_set_key(map, i, ast_node_to_sass_value(key));\n        sass_map_set_value(map, i, ast_node_to_sass_value(m->at(key)));\n        ++ i;\n      }\n      return map;\n    }\n    else if (val->concrete_type() == Expression::NULL_VAL)\n    {\n      return sass_make_null();\n    }\n    else if (val->concrete_type() == Expression::BOOLEAN)\n    {\n      const Boolean* res = Cast<Boolean>(val);\n      return sass_make_boolean(res->value());\n    }\n    else if (val->concrete_type() == Expression::STRING)\n    {\n      if (const String_Quoted* qstr = Cast<String_Quoted>(val))\n      {\n        return sass_make_qstring(qstr->value().c_str());\n      }\n      else if (const String_Constant* cstr = Cast<String_Constant>(val))\n      {\n        return sass_make_string(cstr->value().c_str());\n      }\n    }\n    return sass_make_error(\"unknown sass value type\");\n  }\n\n  // convert value from C-API to C++ side\n  Value* sass_value_to_ast_node (const union Sass_Value* val)\n  {\n    switch (sass_value_get_tag(val)) {\n      case SASS_NUMBER:\n        return SASS_MEMORY_NEW(Number,\n                               SourceSpan(\"[C-VALUE]\"),\n                               sass_number_get_value(val),\n                               sass_number_get_unit(val));\n      case SASS_BOOLEAN:\n        return SASS_MEMORY_NEW(Boolean,\n                               SourceSpan(\"[C-VALUE]\"),\n                               sass_boolean_get_value(val));\n      case SASS_COLOR:\n        // ToDo: allow to also use HSLA colors!!\n        return SASS_MEMORY_NEW(Color_RGBA,\n                               SourceSpan(\"[C-VALUE]\"),\n                               sass_color_get_r(val),\n                               sass_color_get_g(val),\n                               sass_color_get_b(val),\n                               sass_color_get_a(val));\n      case SASS_STRING:\n        if (sass_string_is_quoted(val)) {\n          return SASS_MEMORY_NEW(String_Quoted,\n                                 SourceSpan(\"[C-VALUE]\"),\n                                 sass_string_get_value(val));\n        }\n        return SASS_MEMORY_NEW(String_Constant,\n                                 SourceSpan(\"[C-VALUE]\"),\n                                 sass_string_get_value(val));\n      case SASS_LIST: {\n        List* l = SASS_MEMORY_NEW(List,\n                                  SourceSpan(\"[C-VALUE]\"),\n                                  sass_list_get_length(val),\n                                  sass_list_get_separator(val));\n        for (size_t i = 0, L = sass_list_get_length(val); i < L; ++i) {\n          l->append(sass_value_to_ast_node(sass_list_get_value(val, i)));\n        }\n        l->is_bracketed(sass_list_get_is_bracketed(val));\n        return l;\n      }\n      case SASS_MAP: {\n        Map* m = SASS_MEMORY_NEW(Map, SourceSpan(\"[C-VALUE]\"));\n        for (size_t i = 0, L = sass_map_get_length(val); i < L; ++i) {\n          *m << std::make_pair(\n            sass_value_to_ast_node(sass_map_get_key(val, i)),\n            sass_value_to_ast_node(sass_map_get_value(val, i)));\n        }\n        return m;\n      }\n      case SASS_NULL:\n        return SASS_MEMORY_NEW(Null, SourceSpan(\"[C-VALUE]\"));\n      case SASS_ERROR:\n        return SASS_MEMORY_NEW(Custom_Error,\n                               SourceSpan(\"[C-VALUE]\"),\n                               sass_error_get_message(val));\n      case SASS_WARNING:\n        return SASS_MEMORY_NEW(Custom_Warning,\n                               SourceSpan(\"[C-VALUE]\"),\n                               sass_warning_get_message(val));\n      default: break;\n    }\n    return 0;\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/Sources/values.hpp",
    "content": "#ifndef SASS_VALUES_H\n#define SASS_VALUES_H\n\n#include \"ast.hpp\"\n\nnamespace Sass {\n\n  union Sass_Value* ast_node_to_sass_value (const Expression* val);\n  Value* sass_value_to_ast_node (const union Sass_Value* val);\n\n}\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Clibsass/VERSION.txt",
    "content": "3.6.5\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/SwiftCSSParser/Package.resolved",
    "content": "{\n  \"object\": {\n    \"pins\": [\n\n    ]\n  },\n  \"version\": 1\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/SwiftCSSParser/Package.swift",
    "content": "// swift-tools-version:5.0\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"SwiftCSSParser\",\n    products: [\n        .library(name: \"SwiftCSSParser\", targets: [\"SwiftCSSParser\"])\n    ],\n    dependencies: [\n        .package(path: \"../katana-parser\")\n    ],\n    targets: [\n        .target(\n            name: \"SwiftCSSParser\",\n            dependencies: [\n                \"KatanaParser\"\n            ],\n            path: \"Sources\")\n    ]\n)"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/SwiftCSSParser/Sources/README",
    "content": "From https://github.com/mcudich/CSSParser/commit/4cf02718fd59279147b3b201551c3809a2a96727 ,\nwith modifications.\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/SwiftCSSParser/Sources/StyleElement.swift",
    "content": "//\n//  StyleElement.swift\n//  TemplateKit\n//\n//  Created by Matias Cudich on 9/27/16.\n//  Copyright © 2016 Matias Cudich. All rights reserved.\n//\n\nimport Foundation\n\npublic protocol StyleElement {\n  var id: String? { get }\n  var classNames: [String]? { get }\n  var tagName: String? { get }\n  var parentElement: StyleElement? { get }\n  var childElements: [StyleElement]? { get }\n\n  var isFocused: Bool { get }\n  var isEnabled: Bool { get }\n  var isActive: Bool { get }\n\n  func has(attribute: String, with value: String) -> Bool\n  func equals(_ other: StyleElement) -> Bool\n  func apply(styles: [String: Any])\n}\n\nextension StyleElement {\n  public func directAdjacent(of element: StyleElement) -> StyleElement? {\n    guard let childElements = childElements, let index = index(of: element), index > 0 else {\n      return nil\n    }\n\n    return childElements[index - 1]\n  }\n\n  public func indirectAdjacents(of element: StyleElement) -> [StyleElement] {\n    guard let childElements = childElements, let index = index(of: element), index > 0 else {\n      return []\n    }\n\n    return Array(childElements[0..<index])\n  }\n\n  public func subsequentAdjacents(of element: StyleElement) -> [StyleElement] {\n    guard let childElements = childElements, let index = index(of: element), index < childElements.count - 1 else {\n      return []\n    }\n\n    return Array(childElements[index + 1..<childElements.count])\n  }\n\n  private func index(of child: StyleElement) -> Int? {\n    guard let childElements = childElements else {\n      return nil\n    }\n\n    return childElements.firstIndex { element in\n      return child.equals(element)\n    }\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/SwiftCSSParser/Sources/StyleSheet.swift",
    "content": "//\n//  Stylesheet.swift\n//  TemplateKit\n//\n//  Created by Matias Cudich on 9/27/16.\n//  Copyright © 2016 Matias Cudich. All rights reserved.\n//\n\nimport Foundation\nimport KatanaParser\n\npublic enum Match {\n  case tag\n  case id\n  case className\n  case attributeExact\n  case pseudoClass\n\n  init(_ rawValue: KatanaSelectorMatch) {\n    switch rawValue {\n    case KatanaSelectorMatchTag:\n      self = .tag\n    case KatanaSelectorMatchId:\n      self = .id\n    case KatanaSelectorMatchClass:\n      self = .className\n    case KatanaSelectorMatchAttributeExact:\n      self = .attributeExact\n    case KatanaSelectorMatchPseudoClass:\n      self = .pseudoClass\n    default:\n      fatalError()\n    }\n  }\n}\n\npublic enum Relation {\n  case subselector\n  case descendant\n  case child\n  case directAdjacent\n  case indirectAdjacent\n\n  init(_ rawValue: KatanaSelectorRelation) {\n    switch rawValue {\n    case KatanaSelectorRelationSubSelector:\n      self = .subselector\n    case KatanaSelectorRelationDescendant:\n      self = .descendant\n    case KatanaSelectorRelationChild:\n      self = .child\n    case KatanaSelectorRelationDirectAdjacent:\n      self = .directAdjacent\n    case KatanaSelectorRelationIndirectAdjacent:\n      self = .indirectAdjacent\n    default:\n      fatalError()\n    }\n  }\n}\n\npublic struct Rule {\n  public let selectors: [StyleSelector]\n  public let declarations: [StyleDeclaration]\n\n  public init(selectors: [StyleSelector], declarations: [StyleDeclaration]) {\n    self.selectors = selectors\n    self.declarations = declarations\n  }\n\n  public func matches(_ element: StyleElement) -> Bool {\n    return selectors.contains { selector in\n      return selector.matches(element)\n    }\n  }\n\n  public func greatestSpecificity(for element: StyleElement) -> Int {\n    var specificity = 0\n    for selector in selectors {\n      if selector.matches(element) {\n        var underlyingSelector = selector.selector!\n        specificity = max(specificity, Int(katana_calc_specificity_for_selector(&underlyingSelector)))\n      }\n    }\n    return specificity\n  }\n}\n\npublic struct RareData {\n  public var value: String?\n  public var attribute: String?\n  public var argument: String?\n}\n\npublic enum PseudoType {\n  case empty\n  case firstChild\n  case firstOfType\n  case lastChild\n  case lastOfType\n  case onlyChild\n  case onlyOfType\n  case nthChild\n  case nthOfType\n  case nthLastChild\n  case nthLastOfType\n  case pseudoFocus\n  case pseudoActive\n  case pseudoEnabled\n  case pseudoDisabled\n\n  public init?(_ rawValue: KatanaPseudoType) {\n    switch rawValue {\n    case KatanaPseudoEmpty:\n      self = .empty\n    case KatanaPseudoFirstChild:\n      self = .firstChild\n    case KatanaPseudoFirstOfType:\n      self = .firstOfType\n    case KatanaPseudoLastChild:\n      self = .lastChild\n    case KatanaPseudoLastOfType:\n      self = .lastOfType\n    case KatanaPseudoOnlyChild:\n      self = .onlyChild\n    case KatanaPseudoOnlyOfType:\n      self = .onlyOfType\n    case KatanaPseudoNthChild:\n      self = .nthChild\n    case KatanaPseudoNthOfType:\n      self = .nthOfType\n    case KatanaPseudoNthLastChild:\n      self = .nthLastChild\n    case KatanaPseudoNthLastOfType:\n      self = .nthLastOfType\n    case KatanaPseudoFocus:\n      self = .pseudoFocus\n    case KatanaPseudoActive:\n      self = .pseudoActive\n    case KatanaPseudoEnabled:\n      self = .pseudoEnabled\n    case KatanaPseudoDisabled:\n      self = .pseudoDisabled\n    default:\n      return nil\n    }\n  }\n}\n\npublic struct StyleSelectorData {\n  var match: Match?\n  var relation: Relation?\n  var selector: KatanaSelector?\n  var data: RareData?\n  var pseudoType: PseudoType?\n  var value: String?\n}\n\npublic indirect enum StyleSelector {\n  case none\n  case some(StyleSelectorData, StyleSelector)\n\n  public var match: Match? {\n    if case let .some(data, _) = self {\n      return data.match\n    }\n    return nil\n  }\n\n  public var related: StyleSelector? {\n    if case let .some(_, related) = self {\n      return related\n    }\n    return nil\n  }\n\n  public var relation: Relation? {\n    if case let .some(data, _) = self {\n      return data.relation\n    }\n    return nil\n  }\n\n  public var selector: KatanaSelector? {\n    if case let .some(data, _) = self {\n      return data.selector\n    }\n    return nil\n  }\n\n  public var psuedoType: PseudoType? {\n    if case let .some(data, _) = self {\n      return data.pseudoType\n    }\n    return nil\n  }\n\n  public var data: RareData? {\n    if case let .some(data, _) = self {\n      return data.data\n    }\n    return nil\n  }\n\n  public var value: String? {\n    if case let .some(data, _) = self {\n      return data.value\n    }\n    return nil\n  }\n\n    public var specificity: Int? {\n        if case let .some(data, _) = self {\n            var underlyingSelector = data.selector!\n            return Int(katana_calc_specificity_for_selector(&underlyingSelector))\n        }\n        return nil\n    }\n\n  public func matches(_ element: StyleElement) -> Bool {\n    if case .none = self {\n      return true\n    }\n\n    guard let match = match, let value = value else {\n      return false\n    }\n\n    var matches: Bool\n    switch match {\n    case .id:\n      matches = element.id == value\n    case .className:\n      matches = element.classNames?.contains(value) ?? false\n    case .tag:\n      matches = element.tagName == value\n    case .attributeExact:\n      if let data = data, let attribute = data.attribute, let value = data.value {\n        matches = element.has(attribute: attribute, with: value)\n      } else {\n        matches = false\n      }\n    case .pseudoClass:\n      guard let psuedoType = psuedoType else {\n        matches = false\n        break\n      }\n      switch psuedoType {\n      case .firstChild:\n        let precedingSiblings = element.parentElement?.indirectAdjacents(of: element) ?? []\n        matches = precedingSiblings.count == 0\n      case .firstOfType:\n        let precedingSiblings = element.parentElement?.indirectAdjacents(of: element) ?? []\n        matches = !precedingSiblings.contains { sibling in\n          return sibling.tagName == element.tagName\n        }\n      case .lastChild:\n        let precedingSiblings = element.parentElement?.indirectAdjacents(of: element) ?? []\n        matches = precedingSiblings.count == (element.parentElement?.childElements?.count ?? 0) - 1\n      case .lastOfType:\n        let subsequentSiblings = element.parentElement?.subsequentAdjacents(of: element) ?? []\n        matches = !subsequentSiblings.contains { sibling in\n          sibling.tagName == element.tagName\n        }\n      case .onlyChild:\n        matches = element.parentElement?.childElements?.count == 1\n      case .onlyOfType:\n        let precedingSiblings = element.parentElement?.indirectAdjacents(of: element) ?? []\n        let subsequentSiblings = element.parentElement?.subsequentAdjacents(of: element) ?? []\n        matches = !(precedingSiblings + subsequentSiblings).contains { sibling in\n          return sibling.tagName == element.tagName\n        }\n      case .pseudoFocus:\n        matches = element.isFocused\n      case .pseudoEnabled:\n        matches = element.isEnabled\n      case .pseudoDisabled:\n        matches = !element.isEnabled\n      case .pseudoActive:\n        matches = element.isActive\n      default:\n        matches = false\n      }\n    }\n\n    if !matches {\n      return false\n    }\n\n    guard let relation = relation, let related = related else {\n      return true\n    }\n\n    switch relation {\n    case .subselector:\n      return related.matches(element)\n    case .descendant:\n      var parent = element.parentElement\n      while let currentParent = parent {\n        if related.matches(currentParent) {\n          return true\n        }\n        parent = currentParent.parentElement\n      }\n      return false\n    case .child:\n      guard let parent = element.parentElement else {\n        return false\n      }\n      return related.matches(parent)\n    case .directAdjacent:\n      guard let directAdjacent = element.parentElement?.directAdjacent(of: element) else {\n        return false\n      }\n      return related.matches(directAdjacent)\n    case .indirectAdjacent:\n      guard let indirectAdjacents = element.parentElement?.indirectAdjacents(of: element) else {\n        return false\n      }\n      return indirectAdjacents.contains { indirectAdjacent in\n        return related.matches(indirectAdjacent)\n      }\n    }\n  }\n}\n\npublic struct StyleDeclaration {\n  public let name: String\n  public let value: String\n  public let important: Bool\n}\n\npublic struct CSSError: Error {\n  let message: String\n  let atZeroIndexedLine: Int\n  let column: Int\n}\n\npublic struct StyleSheet: Equatable {\n  public var rules = [Rule]()\n  public var importFilenames = [String]()\n  public private(set) var errors = [CSSError]()\n\n  fileprivate let data: Data?\n  private let inheritedProperties: Set<String>\n\n  public init() {\n    data = nil\n    inheritedProperties = Set([])\n  }\n\n  public init?(string: String, inheritedProperties: [String]? = nil) {\n    guard !string.isEmpty, let data = string.data(using: String.Encoding.utf8) else {\n      return nil\n    }\n    self.data = data\n    self.inheritedProperties = Set(inheritedProperties ?? [])\n\n    data.withUnsafeBytes { unsafeRawBufferPointer in\n      let unsafeBufferPointer = unsafeRawBufferPointer.bindMemory(to: Int8.self)\n      guard let bytes = unsafeBufferPointer.baseAddress else {\n        return\n      }\n      guard let parsed = katana_parse(bytes, data.count, KatanaParserModeStylesheet) else {\n        return\n      }\n      let stylesheet = parsed.pointee.stylesheet.pointee\n\n      let errors: [KatanaError] = fromKatanaArray(array: parsed.pointee.errors)\n      self.errors = errors.map() { err -> CSSError in\n        return CSSError(message: \"invalid syntax\", atZeroIndexedLine: Int(err.last_line), column: Int(err.last_column))\n      }\n\n      let importStatements: [KatanaImportRule] = fromKatanaArray(array: stylesheet.imports)\n      self.importFilenames = importStatements.map() { String(cString: $0.href) }\n\n      let rules: [KatanaStyleRule] = fromKatanaArray(array: stylesheet.rules)\n      self.rules = rules.map { rule in\n        let parsedSelectors: [KatanaSelector] = fromKatanaArray(array: rule.selectors.pointee)\n        let selectors = parsedSelectors.map { selector in\n          return makeSelector(selector)\n        }\n        let parsedDeclarations: [KatanaDeclaration] = fromKatanaArray(array: rule.declarations.pointee)\n        let declarations = parsedDeclarations.map { declaration in\n          return makeDeclaration(declaration)\n        }\n        return Rule(selectors: selectors, declarations: declarations)\n      }\n    }\n  }\n\n  public func rulesForElement(_ element: StyleElement) -> [Rule] {\n    return rules.filter { rule in\n      return rule.matches(element)\n    }\n  }\n\n  public func stylesForElement(_ element: StyleElement) -> [String: StyleDeclaration] {\n    var declarations = [String: (Rule, StyleDeclaration)]()\n    for rule in rulesForElement(element) {\n      for declaration in rule.declarations {\n        if let (existingRule, _) = declarations[declaration.name] {\n          let existingSpecificity = existingRule.greatestSpecificity(for: element)\n          let newSpecificity = rule.greatestSpecificity(for: element)\n          if newSpecificity >= existingSpecificity {\n            declarations[declaration.name] = (rule, declaration)\n          }\n        } else {\n          declarations[declaration.name] = (rule, declaration)\n        }\n      }\n    }\n\n    var declarationMap = [String: StyleDeclaration]()\n    var keys = Set<String>()\n    for (key, (_, declaration)) in declarations {\n      declarationMap[key] = declaration\n      keys.insert(key)\n    }\n    let remainingInheritedProperties = inheritedProperties.subtracting(keys)\n\n    if let parent = element.parentElement, remainingInheritedProperties.count > 0 {\n      let parentStyles = stylesForElement(parent)\n      for (property, declaration) in parentStyles {\n        if remainingInheritedProperties.contains(property) {\n          declarationMap[property] = declaration\n        }\n      }\n    }\n\n    return declarationMap\n  }\n\n  public func apply(to element: StyleElement) {\n    let matchingStyles = stylesForElement(element)\n    var styleSheetProperties = [String: Any]()\n    for (name, declaration) in matchingStyles {\n      styleSheetProperties[name] = declaration.value\n    }\n\n    element.apply(styles: styleSheetProperties)\n\n    for child in element.childElements ?? [] {\n      apply(to: child)\n    }\n  }\n\n  private func makeSelector(_ selector: KatanaSelector) -> StyleSelector {\n    let parent = selector.tagHistory == nil ? .none : makeSelector(selector.tagHistory.pointee)\n\n    var value = \"\"\n    if selector.tag != nil {\n      value = String(cString: selector.tag.pointee.local)\n    } else {\n      value = String(cString: selector.data.pointee.value)\n    }\n\n    var rareData = RareData()\n    if selector.data.pointee.value != nil {\n      rareData.value = String(cString: selector.data.pointee.value)\n    }\n    if selector.data.pointee.attribute != nil {\n      rareData.attribute = String(cString: selector.data.pointee.attribute.pointee.local)\n    }\n    if selector.data.pointee.argument != nil {\n        rareData.argument = String(cString: selector.data.pointee.argument)\n    }\n\n    let data = StyleSelectorData(match: Match(selector.match), relation: Relation(selector.relation), selector: selector, data: rareData, pseudoType: PseudoType(selector.pseudo), value: value)\n\n    return .some(data, parent)\n  }\n\n  private func makeDeclaration(_ declaration: KatanaDeclaration) -> StyleDeclaration {\n    return StyleDeclaration(name: String(cString: declaration.property), value: String(cString: declaration.raw), important: declaration.important)\n    // return StyleDeclaration(name: String(cString: declaration.property), value: makeValue(declaration.values.pointee), important: declaration.important)\n  }\n\n  private func makeValue(_ values: KatanaArray) -> String {\n    let values: [KatanaValue] = fromKatanaArray(array: values)\n    return values.map { value in\n      if value.isInt {\n        return String(cString: value.raw) + stringForUnit(value.unit)\n      } else if value.fValue >= Double.leastNormalMagnitude {\n        return \"\\(value.fValue)\" + stringForUnit(value.unit)\n      } else {\n        return String(cString: value.string)\n      }\n    }.joined(separator: \" \")\n  }\n\n  private func fromKatanaArray<T>(array: KatanaArray) -> [T] {\n    var data = array.data\n    var results = [T]()\n    for _ in 0..<array.length {\n      guard let rule = data?.pointee?.assumingMemoryBound(to: T.self).pointee else {\n        continue\n      }\n      data = data?.advanced(by: 1)\n      results.append(rule)\n    }\n    return results\n  }\n}\n\npublic func ==(lhs: StyleSheet, rhs: StyleSheet) -> Bool {\n  return lhs.data == rhs.data\n}\n\nprivate func stringForUnit(_ unit: KatanaValueUnit) -> String {\n    switch unit {\n    case KATANA_VALUE_PX:\n        return \"px\"\n    case KATANA_VALUE_PT:\n        return \"pt\"\n    case KATANA_VALUE_VW:\n        return \"vw\"\n    case KATANA_VALUE_VH:\n        return \"vh\"\n    case KATANA_VALUE_PERCENTAGE:\n        return \"%\"\n    default:\n        return \"\"\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Yaml/Package.swift",
    "content": "// swift-tools-version:5.0\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"Yaml\",\n    products: [\n        .library(name: \"Yaml\", targets: [\"Yaml\"])\n    ],\n    dependencies: [],\n    targets: [\n        .target(\n            name: \"Yaml\",\n            path: \"Sources\")\n    ]\n)"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Yaml/Sources/YAMLOperators.swift",
    "content": "infix operator |>: Functional\nfunc |> <T, U> (x: T, f: (T) -> U) -> U {\n  return f(x)\n}\n\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Yaml/Sources/YAMLParser.swift",
    "content": "import Foundation\n\nprivate typealias Resulter = Yaml\n\n\nextension Yaml {\n\nstruct Context {\n  let tokens: [Yaml.TokenMatch]\n  let aliases: [String.SubSequence: Yaml]\n\n  init (_ tokens: [Yaml.TokenMatch], _ aliases: [String.SubSequence: Yaml] = [:]) {\n    self.tokens = tokens\n    self.aliases = aliases\n  }\n  static func parseDoc (_ tokens: [Yaml.TokenMatch]) -> YAMLResult<Yaml> {\n    let c = Resulter.lift(Context(tokens))\n    let cv = c >>=- parseHeader >>=- parse\n    let v = cv >>- getValue\n    return cv\n      >>- getContext\n      >>- ignoreDocEnd\n      >>=- expect(Yaml.TokenType.end, message: \"expected end\")\n      >>| v\n  }\n  \n  static func parseDocs (_ tokens: [Yaml.TokenMatch]) -> YAMLResult<[Yaml]> {\n    return parseDocs([])(Context(tokens))\n  }\n  \n  static func parseDocs (_ acc: [Yaml]) -> (Context) -> YAMLResult<[Yaml]> {\n    return { context in\n      if peekType(context) == .end {\n        return Resulter.lift(acc)\n      }\n      let cv = Resulter.lift(context)\n        >>=- parseHeader\n        >>=- parse\n      let v = cv\n        >>- getValue\n      let c = cv\n        >>- getContext\n        >>- ignoreDocEnd\n      let a = appendToArray(acc) <^> v\n      return parseDocs <^> a <*> c |> Resulter.join\n    }\n  }\n  \n  static func error (_ message: String) -> (Context) -> String {\n    return { context in\n      let text = recreateText(\"\", context: context) |> Yaml.escapeErrorContext\n      return \"\\(message), \\(text)\"\n    }\n  }\n\n  \n\n}\n\n}\n\nprivate typealias Context = Yaml.Context\n\nprivate var error = Yaml.Context.error\n\nprivate typealias ContextValue = (context: Context, value: Yaml)\n\nprivate func createContextValue (_ context: Context) -> (Yaml) -> ContextValue {\n  return { value in (context, value) }\n}\n\nprivate func getContext (_ cv: ContextValue) -> Context {\n  return cv.context\n}\n\nprivate func getValue (_ cv: ContextValue) -> Yaml {\n  return cv.value\n}\n\n\nprivate func peekType (_ context: Context) -> Yaml.TokenType {\n  return context.tokens[0].type\n}\n\n\nprivate func peekMatch (_ context: Context) -> String {\n  return context.tokens[0].match\n}\n\n\nprivate func advance (_ context: Context) -> Context {\n  var tokens = context.tokens\n  tokens.remove(at: 0)\n  return Context(tokens, context.aliases)\n}\n\nprivate func ignoreSpace (_ context: Context) -> Context {\n  if ![.comment, .space, .newLine].contains(peekType(context)) {\n    return context\n  }\n  return ignoreSpace(advance(context))\n}\n\nprivate func ignoreDocEnd (_ context: Context) -> Context {\n  if ![.comment, .space, .newLine, .docend].contains(peekType(context)) {\n    return context\n  }\n  return ignoreDocEnd(advance(context))\n}\n\nprivate func expect (_ type: Yaml.TokenType, message: String) -> (Context) -> YAMLResult<Context> {\n  return { context in\n    let check = peekType(context) == type\n    return Resulter.`guard`(error(message)(context), check: check)\n        >>| Resulter.lift(advance(context))\n  }\n}\n\nprivate func expectVersion (_ context: Context) -> YAMLResult<Context> {\n  let version = peekMatch(context)\n  let check = [\"1.1\", \"1.2\"].contains(version)\n  return Resulter.`guard`(error(\"invalid yaml version\")(context), check: check)\n      >>| Resulter.lift(advance(context))\n}\n\n\nprivate func recreateText (_ string: String, context: Context) -> String {\n  if string.count >= 50 || peekType(context) == .end {\n    return string\n  }\n  return recreateText(string + peekMatch(context), context: advance(context))\n}\n\nprivate func parseHeader (_ context: Context) -> YAMLResult<Context> {\n  return parseHeader(true)(Context(context.tokens, [:]))\n}\n\nprivate func parseHeader (_ yamlAllowed: Bool) -> (Context) -> YAMLResult<Context> {\n  return { context in\n    switch peekType(context) {\n\n    case .comment, .space, .newLine:\n      return Resulter.lift(context)\n          >>- advance\n          >>=- parseHeader(yamlAllowed)\n\n    case .yamlDirective:\n      let err = \"duplicate yaml directive\"\n      return Resulter.`guard`(error(err)(context), check: yamlAllowed)\n          >>| Resulter.lift(context)\n          >>- advance\n          >>=- expect(Yaml.TokenType.space, message: \"expected space\")\n          >>=- expectVersion\n          >>=- parseHeader(false)\n\n    case .docStart:\n      return Resulter.lift(advance(context))\n\n    default:\n      return Resulter.`guard`(error(\"expected ---\")(context), check: yamlAllowed)\n          >>| Resulter.lift(context)\n    }\n  }\n}\n\nprivate func parse (_ context: Context) -> YAMLResult<ContextValue> {\n  switch peekType(context) {\n\n  case .comment, .space, .newLine:\n    return parse(ignoreSpace(context))\n\n  case .null:\n    return Resulter.lift((advance(context), nil))\n\n  case ._true:\n    return Resulter.lift((advance(context), true))\n\n  case ._false:\n    return Resulter.lift((advance(context), false))\n\n  case .int:\n    let m = peekMatch(context)\n    // will throw runtime error if overflows\n    let v = Yaml.int(parseInt(m, radix: 10))\n    return Resulter.lift((advance(context), v))\n\n  case .intOct:\n    let m = peekMatch(context) |> Yaml.Regex.replace(Yaml.Regex.regex(\"0o\"), template: \"\")\n    // will throw runtime error if overflows\n    let v = Yaml.int(parseInt(m, radix: 8))\n    return Resulter.lift((advance(context), v))\n\n  case .intHex:\n    let m = peekMatch(context) |> Yaml.Regex.replace(Yaml.Regex.regex(\"0x\"), template: \"\")\n    // will throw runtime error if overflows\n    let v = Yaml.int(parseInt(m, radix: 16))\n    return Resulter.lift((advance(context), v))\n\n  case .intSex:\n    let m = peekMatch(context)\n    let v = Yaml.int(parseInt(m, radix: 60))\n    return Resulter.lift((advance(context), v))\n\n  case .infinityP:\n    return Resulter.lift((advance(context), .double(Double.infinity)))\n\n  case .infinityN:\n    return Resulter.lift((advance(context), .double(-Double.infinity)))\n\n  case .nan:\n    return Resulter.lift((advance(context), .double(Double.nan)))\n\n  case .double:\n    let m = NSString(string: peekMatch(context))\n    return Resulter.lift((advance(context), .double(m.doubleValue)))\n\n  case .dash:\n    return parseBlockSeq(context)\n\n  case .openSB:\n    return parseFlowSeq(context)\n\n  case .openCB:\n    return parseFlowMap(context)\n\n  case .questionMark:\n    return parseBlockMap(context)\n\n  case .stringDQ, .stringSQ, .string:\n    return parseBlockMapOrString(context)\n\n  case .literal:\n    return parseliteral(context)\n\n  case .folded:\n    let cv = parseliteral(context)\n    let c = cv >>- getContext\n    let v = cv\n        >>- getValue\n        >>- { value in Yaml.string(foldBlock(value.string ?? \"\")) }\n    return createContextValue <^> c <*> v\n\n  case .indent:\n    let cv = parse(advance(context))\n    let v = cv >>- getValue\n    let c = cv\n        >>- getContext\n        >>- ignoreSpace\n        >>=- expect(Yaml.TokenType.dedent, message: \"expected dedent\")\n    return createContextValue <^> c <*> v\n\n  case .anchor:\n    let m = peekMatch(context)\n    let name = m[m.index(after: m.startIndex)...]\n    let cv = parse(advance(context))\n    let v = cv >>- getValue\n    let c = addAlias(name) <^> v <*> (cv >>- getContext)\n    return createContextValue <^> c <*> v\n\n  case .alias:\n    let m = peekMatch(context)\n    let name = m[m.index(after: m.startIndex)...]\n    let value = context.aliases[name]\n    let err = \"unknown alias \\(name)\"\n    return Resulter.`guard`(error(err)(context), check: value != nil)\n        >>| Resulter.lift((advance(context), value ?? nil))\n\n  case .end, .dedent:\n    return Resulter.lift((context, nil))\n\n  default:\n    return Resulter.fail(error(\"unexpected type \\(peekType(context))\")(context))\n\n  }\n}\n\nprivate func addAlias (_ name: String.SubSequence) -> (Yaml) -> (Context) -> Context {\n  return { value in\n    return { context in\n      var aliases = context.aliases\n      aliases[name] = value\n      return Context(context.tokens, aliases)\n    }\n  }\n}\n\nprivate func appendToArray (_ array: [Yaml]) -> (Yaml) -> [Yaml] {\n  return { value in\n    return array + [value]\n  }\n}\n\nprivate func putToMap (_ map: [Yaml: Yaml]) -> (Yaml) -> (Yaml) -> [Yaml: Yaml] {\n  return { key in\n    return { value in\n      var map = map\n      map[key] = value\n      return map\n    }\n  }\n}\n\nprivate func checkKeyUniqueness (_ acc: [Yaml: Yaml]) -> (_ context: Context, _ key: Yaml)\n    -> YAMLResult<ContextValue> {\n      return { (context, key) in\n        let err = \"duplicate key \\(key)\"\n        return Resulter.`guard`(error(err)(context), check: !acc.keys.contains(key))\n            >>| Resulter.lift((context, key))\n      }\n}\n\nprivate func parseFlowSeq (_ context: Context) -> YAMLResult<ContextValue> {\n  return Resulter.lift(context)\n      >>=- expect(Yaml.TokenType.openSB, message: \"expected [\")\n      >>=- parseFlowSeq([])\n}\n\nprivate func parseFlowSeq (_ acc: [Yaml]) -> (Context) -> YAMLResult<ContextValue> {\n  return { context in\n    if peekType(context) == .closeSB {\n      return Resulter.lift((advance(context), .array(acc)))\n    }\n    let cv = Resulter.lift(context)\n        >>- ignoreSpace\n        >>=- (acc.count == 0 ? Resulter.lift : expect(Yaml.TokenType.comma, message: \"expected comma\"))\n        >>- ignoreSpace\n        >>=- parse\n    let v = cv >>- getValue\n    let c = cv\n        >>- getContext\n        >>- ignoreSpace\n    let a = appendToArray(acc) <^> v\n    return parseFlowSeq <^> a <*> c |> Resulter.join\n  }\n}\n\n\nprivate func parseFlowMap (_ context: Context) -> YAMLResult<ContextValue> {\n  return Resulter.lift(context)\n      >>=- expect(Yaml.TokenType.openCB, message: \"expected {\")\n      >>=- parseFlowMap([:])\n}\n\nprivate func parseFlowMap (_ acc: [Yaml: Yaml]) -> (Context) -> YAMLResult<ContextValue> {\n  return { context in\n    if peekType(context) == .closeCB {\n      return Resulter.lift((advance(context), .dictionary(acc)))\n    }\n    let ck = Resulter.lift(context)\n        >>- ignoreSpace\n        >>=- (acc.count == 0 ? Resulter.lift : expect(Yaml.TokenType.comma, message: \"expected comma\"))\n        >>- ignoreSpace\n        >>=- parseString\n        >>=- checkKeyUniqueness(acc)\n    let k = ck >>- getValue\n    let cv = ck\n        >>- getContext\n        >>=- expect(Yaml.TokenType.colon, message: \"expected colon\")\n        >>=- parse\n    let v = cv >>- getValue\n    let c = cv\n        >>- getContext\n        >>- ignoreSpace\n    let a = putToMap(acc) <^> k <*> v\n    return parseFlowMap <^> a <*> c |> Resulter.join\n  }\n}\n\nprivate func parseBlockSeq (_ context: Context) -> YAMLResult<ContextValue> {\n  return parseBlockSeq([])(context)\n}\n\nprivate func parseBlockSeq (_ acc: [Yaml]) -> (Context) -> YAMLResult<ContextValue> {\n  return { context in\n    if peekType(context) != .dash {\n      return Resulter.lift((context, .array(acc)))\n    }\n    let cv = Resulter.lift(context)\n        >>- advance\n        >>=- expect(Yaml.TokenType.indent, message: \"expected indent after dash\")\n        >>- ignoreSpace\n        >>=- parse\n    let v = cv >>- getValue\n    let c = cv\n        >>- getContext\n        >>- ignoreSpace\n        >>=- expect(Yaml.TokenType.dedent, message: \"expected dedent after dash indent\")\n        >>- ignoreSpace\n    let a = appendToArray(acc) <^> v\n    return parseBlockSeq <^> a <*> c |> Resulter.join\n  }\n}\n\nprivate func parseBlockMap (_ context: Context) -> YAMLResult<ContextValue> {\n  return parseBlockMap([:])(context)\n}\n\nprivate func parseBlockMap (_ acc: [Yaml: Yaml]) -> (Context) -> YAMLResult<ContextValue> {\n  return { context in\n    switch peekType(context) {\n\n    case .questionMark:\n      return parseQuestionMarkkeyValue(acc)(context)\n\n    case .string, .stringDQ, .stringSQ:\n      return parseStringKeyValue(acc)(context)\n\n    default:\n      return Resulter.lift((context, .dictionary(acc)))\n    }\n  }\n}\n\nprivate func parseQuestionMarkkeyValue (_ acc: [Yaml: Yaml]) -> (Context) -> YAMLResult<ContextValue> {\n  return { context in\n    let ck = Resulter.lift(context)\n        >>=- expect(Yaml.TokenType.questionMark, message: \"expected ?\")\n        >>=- parse\n        >>=- checkKeyUniqueness(acc)\n    let k = ck >>- getValue\n    let cv = ck\n        >>- getContext\n        >>- ignoreSpace\n        >>=- parseColonValueOrNil\n    let v = cv >>- getValue\n    let c = cv\n        >>- getContext\n        >>- ignoreSpace\n    let a = putToMap(acc) <^> k <*> v\n    return parseBlockMap <^> a <*> c |> Resulter.join\n  }\n}\n\nprivate func parseColonValueOrNil (_ context: Context) -> YAMLResult<ContextValue> {\n  if peekType(context) != .colon {\n    return Resulter.lift((context, nil))\n  }\n  return parseColonValue(context)\n}\n\nprivate func parseColonValue (_ context: Context) -> YAMLResult<ContextValue> {\n  return Resulter.lift(context)\n      >>=- expect(Yaml.TokenType.colon, message: \"expected colon\")\n      >>- ignoreSpace\n      >>=- parse\n}\n\nprivate func parseStringKeyValue (_ acc: [Yaml: Yaml]) -> (Context) -> YAMLResult<ContextValue> {\n  return { context in\n    let ck = Resulter.lift(context)\n        >>=- parseString\n        >>=- checkKeyUniqueness(acc)\n    let k = ck >>- getValue\n    let cv = ck\n        >>- getContext\n        >>- ignoreSpace\n        >>=- parseColonValue\n    let v = cv >>- getValue\n    let c = cv\n        >>- getContext\n        >>- ignoreSpace\n    let a = putToMap(acc) <^> k <*> v\n    return parseBlockMap <^> a <*> c |> Resulter.join\n  }\n}\n\nprivate func parseString (_ context: Context) -> YAMLResult<ContextValue> {\n  switch peekType(context) {\n\n  case .string:\n    let m = normalizeBreaks(peekMatch(context))\n    let folded = m |> Yaml.Regex.replace(Yaml.Regex.regex(\"^[ \\\\t\\\\n]+|[ \\\\t\\\\n]+$\"), template: \"\") |> foldFlow\n    return Resulter.lift((advance(context), .string(folded)))\n\n  case .stringDQ:\n    let m = unwrapQuotedString(normalizeBreaks(peekMatch(context)))\n    return Resulter.lift((advance(context), .string(unescapeDoubleQuotes(foldFlow(m)))))\n\n  case .stringSQ:\n    let m = unwrapQuotedString(normalizeBreaks(peekMatch(context)))\n    return Resulter.lift((advance(context), .string(unescapeSingleQuotes(foldFlow(m)))))\n\n  default:\n    return Resulter.fail(error(\"expected string\")(context))\n  }\n}\n\n\nprivate func parseBlockMapOrString (_ context: Context) -> YAMLResult<ContextValue> {\n  let match = peekMatch(context)\n  // should spaces before colon be ignored?\n  return context.tokens[1].type != .colon || Yaml.Regex.matches(match, regex: Yaml.Regex.regex(\"\\n\"))\n      ? parseString(context)\n      : parseBlockMap(context)\n}\n\nprivate func foldBlock (_ block: String) -> String {\n  let (body, trail) = block |> Yaml.Regex.splitTrail(Yaml.Regex.regex(\"\\\\n*$\"))\n  return (body\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"^([^ \\\\t\\\\n].*)\\\\n(?=[^ \\\\t\\\\n])\", options: \"m\"), template: \"$1 \")\n      |> Yaml.Regex.replace(\n            Yaml.Regex.regex(\"^([^ \\\\t\\\\n].*)\\\\n(\\\\n+)(?![ \\\\t])\", options: \"m\"), template: \"$1$2\")\n      ) + trail\n}\n\nprivate func foldFlow (_ flow: String) -> String {\n  let (lead, rest) = flow |> Yaml.Regex.splitLead(Yaml.Regex.regex(\"^[ \\\\t]+\"))\n  let (body, trail) = rest |> Yaml.Regex.splitTrail(Yaml.Regex.regex(\"[ \\\\t]+$\"))\n  let folded = body\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"^[ \\\\t]+|[ \\\\t]+$|\\\\\\\\\\\\n\", options: \"m\"), template: \"\")\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"(^|.)\\\\n(?=.|$)\"), template: \"$1 \")\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"(.)\\\\n(\\\\n+)\"), template: \"$1$2\")\n  return lead + folded + trail\n}\n\nprivate func count(string: String) -> Int {\n  return string.count\n}\n\nprivate func parseliteral (_ context: Context) -> YAMLResult<ContextValue> {\n  let literal = peekMatch(context)\n  let blockContext = advance(context)\n  let chomps = [\"-\": -1, \"+\": 1]\n  let chomp = chomps[literal |> Yaml.Regex.replace(Yaml.Regex.regex(\"[^-+]\"), template: \"\")] ?? 0\n  let indent = parseInt(literal |> Yaml.Regex.replace(Yaml.Regex.regex(\"[^1-9]\"), template: \"\"), radix: 10)\n  let headerPattern = Yaml.Regex.regex(\"^(\\\\||>)([1-9][-+]|[-+]?[1-9]?)( |$)\")\n  let error0 = \"invalid chomp or indent header\"\n  let c = Resulter.`guard`(error(error0)(context),\n        check: Yaml.Regex.matches(literal, regex: headerPattern!))\n      >>| Resulter.lift(blockContext)\n      >>=- expect(Yaml.TokenType.string, message: \"expected scalar block\")\n  let block = peekMatch(blockContext)\n      |> normalizeBreaks\n  let (lead, _) = block\n      |> Yaml.Regex.splitLead(Yaml.Regex.regex(\"^( *\\\\n)* {1,}(?! |\\\\n|$)\"))\n  let foundindent = lead\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"^( *\\\\n)*\"), template: \"\")\n      |> count\n  let effectiveindent = indent > 0 ? indent : foundindent\n  let invalidPattern =\n      Yaml.Regex.regex(\"^( {0,\\(effectiveindent)}\\\\n)* {\\(effectiveindent + 1),}\\\\n\")\n  let check1 = Yaml.Regex.matches(block, regex: invalidPattern!)\n  let check2 = indent > 0 && foundindent < indent\n  let trimmed = block\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"^ {0,\\(effectiveindent)}\"), template: \"\")\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\\\n {0,\\(effectiveindent)}\"), template: \"\\n\")\n      |> (chomp == -1\n          ? Yaml.Regex.replace(Yaml.Regex.regex(\"(\\\\n *)*$\"), template: \"\")\n          : chomp == 0\n          ? Yaml.Regex.replace(Yaml.Regex.regex(\"(?=[^ ])(\\\\n *)*$\"), template: \"\\n\")\n          : { s in s }\n      )\n  let error1 = \"leading all-space line must not have too many spaces\"\n  let error2 = \"less indented block scalar than the indicated level\"\n  return c\n      >>| Resulter.`guard`(error(error1)(blockContext), check: !check1)\n      >>| Resulter.`guard`(error(error2)(blockContext), check: !check2)\n      >>| c\n      >>- { context in (context, .string(trimmed))}\n}\n\n\nprivate func parseInt (_ string: String, radix: Int) -> Int {\n  let (sign, str) = Yaml.Regex.splitLead(Yaml.Regex.regex(\"^[-+]\"))(string)\n  let multiplier = (sign == \"-\" ? -1 : 1)\n  let ints = radix == 60\n      ? toSexints(str)\n      : toints(str)\n  return multiplier * ints.reduce(0, { acc, i in acc * radix + i })\n}\n\nprivate func toSexints (_ string: String) -> [Int] {\n  return string.components(separatedBy: \":\").map {\n    c in Int(c) ?? 0\n  }\n}\n\nprivate func toints (_ string: String) -> [Int] {\n  return string.unicodeScalars.map {\n    c in\n    switch c {\n    case \"0\"...\"9\": return Int(c.value) - Int((\"0\" as UnicodeScalar).value)\n    case \"a\"...\"z\": return Int(c.value) - Int((\"a\" as UnicodeScalar).value) + 10\n    case \"A\"...\"Z\": return Int(c.value) - Int((\"A\" as UnicodeScalar).value) + 10\n    default: fatalError(\"invalid digit \\(c)\")\n    }\n  }\n}\n\nprivate func normalizeBreaks (_ s: String) -> String {\n  return Yaml.Regex.replace(Yaml.Regex.regex(\"\\\\r\\\\n|\\\\r\"), template: \"\\n\")(s)\n}\n\nprivate func unwrapQuotedString (_ s: String) -> String {\n  return String(s[s.index(after: s.startIndex)..<s.index(before: s.endIndex)])\n}\n\nprivate func unescapeSingleQuotes (_ s: String) -> String {\n  return Yaml.Regex.replace(Yaml.Regex.regex(\"''\"), template: \"'\")(s)\n}\n\nprivate func unescapeDoubleQuotes (_ input: String) -> String {\n  return input\n    |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\\\\\\\([0abtnvfre \\\"\\\\/N_LP])\"))\n        { escapeCharacters[$0[1]] ?? \"\" }\n    |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\\\\\\\x([0-9A-Fa-f]{2})\"))\n        { String(describing: UnicodeScalar(parseInt($0[1], radix: 16))) }\n    |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\\\\\\\u([0-9A-Fa-f]{4})\"))\n        { String(describing: UnicodeScalar(parseInt($0[1], radix: 16))) }\n    |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\\\\\\\U([0-9A-Fa-f]{8})\"))\n        { String(describing: UnicodeScalar(parseInt($0[1], radix: 16))) }\n}\n\nprivate let escapeCharacters = [\n  \"0\": \"\\0\",\n  \"a\": \"\\u{7}\",\n  \"b\": \"\\u{8}\",\n  \"t\": \"\\t\",\n  \"n\": \"\\n\",\n  \"v\": \"\\u{B}\",\n  \"f\": \"\\u{C}\",\n  \"r\": \"\\r\",\n  \"e\": \"\\u{1B}\",\n  \" \": \" \",\n  \"\\\"\": \"\\\"\",\n  \"\\\\\": \"\\\\\",\n  \"/\": \"/\",\n  \"N\": \"\\u{85}\",\n  \"_\": \"\\u{A0}\",\n  \"L\": \"\\u{2028}\",\n  \"P\": \"\\u{2029}\"\n]\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Yaml/Sources/YAMLRegex.swift",
    "content": "import Foundation\n\n\nprivate let invalidOptionsPattern =\n  try! NSRegularExpression(pattern: \"[^ixsm]\", options: [])\n\nprivate let regexOptions: [Character: NSRegularExpression.Options] = [\n  \"i\": .caseInsensitive,\n  \"x\": .allowCommentsAndWhitespace,\n  \"s\": .dotMatchesLineSeparators,\n  \"m\": .anchorsMatchLines\n]\n\nextension Yaml {\n  struct Regex {\n\nstatic func matchRange (_ string: String, regex: NSRegularExpression) -> NSRange {\n  let sr = NSMakeRange(0, string.utf16.count)\n  return regex.rangeOfFirstMatch(in: string, options: [], range: sr)\n}\n\nstatic func matches (_ string: String, regex: NSRegularExpression) -> Bool {\n  return matchRange(string, regex: regex).location != NSNotFound\n}\n\nstatic func regex (_ pattern: String, options: String = \"\") -> NSRegularExpression! {\n  if matches(options, regex: invalidOptionsPattern) {\n    return nil\n  }\n\n  let opts = options.reduce(NSRegularExpression.Options()) { (acc, opt) -> NSRegularExpression.Options in\n    return NSRegularExpression.Options(rawValue:acc.rawValue | (regexOptions[opt] ?? NSRegularExpression.Options()).rawValue)\n  }\n  return try? NSRegularExpression(pattern: pattern, options: opts)\n}\n\n\n\n\n\nstatic func replace (_ regex: NSRegularExpression, template: String) -> (String)\n    -> String {\n      return { string in\n        let s = NSMutableString(string: string)\n        let range = NSMakeRange(0, string.utf16.count)\n        _ = regex.replaceMatches(in: s, options: [], range: range,\n                                 withTemplate: template)\n#if os(Linux)\n        return s._bridgeToSwift()\n#else\n        return s as String\n#endif\n      }\n}\n\nstatic func replace (_ regex: NSRegularExpression, block: @escaping ([String]) -> String)\n    -> (String) -> String {\n      return { string in\n        let s = NSMutableString(string: string)\n        let range = NSMakeRange(0, string.utf16.count)\n        var offset = 0\n        regex.enumerateMatches(in: string, options: [], range: range) {\n          result, _, _ in\n          if let result = result {\n              var captures = [String](repeating: \"\", count: result.numberOfRanges)\n              for i in 0..<result.numberOfRanges {\n                let rangeAt = result.range(at: i)\n                if let r = Range(rangeAt) {\n                  captures[i] = NSString(string: string).substring(with: NSRange(r))\n                }\n              }\n              let replacement = block(captures)\n              let offR = NSMakeRange(result.range.location + offset, result.range.length)\n              offset += replacement.count - result.range.length\n              s.replaceCharacters(in: offR, with: replacement)\n          }\n        }\n#if os(Linux)\n        return s._bridgeToSwift()\n#else\n        return s as String\n#endif\n      }\n}\n\nstatic func splitLead (_ regex: NSRegularExpression) -> (String)\n    -> (String, String) {\n      return { string in\n        let r = matchRange(string, regex: regex)\n        if r.location == NSNotFound {\n          return (\"\", string)\n        } else {\n          let s = NSString(string: string)\n          let i = r.location + r.length\n          return (s.substring(to: i), s.substring(from: i))\n        }\n      }\n}\n\nstatic func splitTrail (_ regex: NSRegularExpression) -> (String)\n    -> (String, String) {\n      return { string in\n        let r = matchRange(string, regex: regex)\n        if r.location == NSNotFound {\n          return (string, \"\")\n        } else {\n          let s = NSString(string: string)\n          let i = r.location\n          return (s.substring(to: i), s.substring(from: i))\n        }\n      }\n}\n\nstatic func substring (_ range: NSRange, _ string : String ) -> String {\n    return NSString(string: string).substring(with: range)\n}\n\nstatic func substring (_ index: Int, _ string: String ) -> String {\n    return NSString(string: string).substring(from: index)\n}\n  }\n\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Yaml/Sources/YAMLResult.swift",
    "content": "internal enum YAMLResult<T> {\n  case error(String)\n  case value(T)\n  \n  public var error: String? {\n    switch self {\n    case .error(let e): return e\n    case .value: return nil\n    }\n  }\n  \n  public var value: T? {\n    switch self {\n    case .error: return nil\n    case .value(let v): return v\n    }\n  }\n  \n  public func map <U> (f: (T) -> U) -> YAMLResult<U> {\n    switch self {\n    case .error(let e): return .error(e)\n    case .value(let v): return .value(f(v))\n    }\n  }\n  \n  public func flatMap <U> (f: (T) -> YAMLResult<U>) -> YAMLResult<U> {\n    switch self {\n    case .error(let e): return .error(e)\n    case .value(let v): return f(v)\n    }\n  }\n}\n\n\nprecedencegroup Functional {\n  associativity: left\n  higherThan: DefaultPrecedence\n}\n\ninfix operator <*>: Functional\nfunc <*> <T, U> (f: YAMLResult<(T) -> U>, x: YAMLResult<T>) -> YAMLResult<U> {\n  switch (x, f) {\n  case (.error(let e), _): return .error(e)\n  case (.value, .error(let e)): return .error(e)\n  case (.value(let x), .value(let f)): return . value(f(x))\n  }\n}\n\ninfix operator <^>: Functional\nfunc <^> <T, U> (f: (T) -> U, x: YAMLResult<T>) -> YAMLResult<U> {\n  return x.map(f: f)\n}\n\ninfix operator >>-: Functional\nfunc >>- <T, U> (x: YAMLResult<T>, f: (T) -> U) -> YAMLResult<U> {\n  return x.map(f: f)\n}\n\ninfix operator >>=-: Functional\nfunc >>=- <T, U> (x: YAMLResult<T>, f: (T) -> YAMLResult<U>) -> YAMLResult<U> {\n  return x.flatMap(f: f)\n}\n\ninfix operator >>|: Functional\nfunc >>| <T, U> (x: YAMLResult<T>, y: YAMLResult<U>) -> YAMLResult<U> {\n  return x.flatMap { _ in y }\n}\n\nextension Yaml  {\n  static func lift <V> (_ v: V) -> YAMLResult<V> {\n    return .value(v)\n  }\n  \n  static func fail <T> (_ e: String) -> YAMLResult<T> {\n    return .error(e)\n  }\n  \n  static func join <T> (_ x: YAMLResult<YAMLResult<T>>) -> YAMLResult<T> {\n    return x >>=- { i in i }\n  }\n  \n  static func `guard` (_ error: @autoclosure() -> String, check: Bool) -> YAMLResult<()> {\n    return check ? lift(()) : .error(error())\n  }\n  \n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Yaml/Sources/YAMLTokenizer.swift",
    "content": "import Foundation\n\n\nextension Yaml {\n  enum TokenType: String {\n    case yamlDirective = \"%YAML\"\n    case docStart = \"doc-start\"\n    case docend = \"doc-end\"\n    case comment = \"comment\"\n    case space = \"space\"\n    case newLine = \"newline\"\n    case indent = \"indent\"\n    case dedent = \"dedent\"\n    case null = \"null\"\n    case _true = \"true\"\n    case _false = \"false\"\n    case infinityP = \"+infinity\"\n    case infinityN = \"-infinity\"\n    case nan = \"nan\"\n    case double = \"double\"\n    case int = \"int\"\n    case intOct = \"int-oct\"\n    case intHex = \"int-hex\"\n    case intSex = \"int-sex\"\n    case anchor = \"&\"\n    case alias = \"*\"\n    case comma = \",\"\n    case openSB = \"[\"\n    case closeSB = \"]\"\n    case dash = \"-\"\n    case openCB = \"{\"\n    case closeCB = \"}\"\n    case key = \"key\"\n    case keyDQ = \"key-dq\"\n    case keySQ = \"key-sq\"\n    case questionMark = \"?\"\n    case colonFO = \":-flow-out\"\n    case colonFI = \":-flow-in\"\n    case colon = \":\"\n    case literal = \"|\"\n    case folded = \">\"\n    case reserved = \"reserved\"\n    case stringDQ = \"string-dq\"\n    case stringSQ = \"string-sq\"\n    case stringFI = \"string-flow-in\"\n    case stringFO = \"string-flow-out\"\n    case string = \"string\"\n    case end = \"end\"\n  }\n}\n\nprivate typealias TokenPattern = (type: Yaml.TokenType, pattern: NSRegularExpression)\n\nextension Yaml {\n  typealias TokenMatch = (type: Yaml.TokenType, match: String)\n}\n\nprivate let bBreak = \"(?:\\\\r\\\\n|\\\\r|\\\\n)\"\n\n// printable non-space chars,\n// except `:`(3a), `#`(23), `,`(2c), `[`(5b), `]`(5d), `{`(7b), `}`(7d)\nprivate let safeIn = \"\\\\x21\\\\x22\\\\x24-\\\\x2b\\\\x2d-\\\\x39\\\\x3b-\\\\x5a\\\\x5c\\\\x5e-\\\\x7a\" +\n  \"\\\\x7c\\\\x7e\\\\x85\\\\xa0-\\\\ud7ff\\\\ue000-\\\\ufefe\\\\uff00\\\\ufffd\" +\n\"\\\\U00010000-\\\\U0010ffff\"\n// with flow indicators: `,`, `[`, `]`, `{`, `}`\nprivate let safeOut = \"\\\\x2c\\\\x5b\\\\x5d\\\\x7b\\\\x7d\" + safeIn\nprivate let plainOutPattern =\n\"([\\(safeOut)]#|:(?![ \\\\t]|\\(bBreak))|[\\(safeOut)]|[ \\\\t])+\"\nprivate let plainInPattern =\n\"([\\(safeIn)]#|:(?![ \\\\t]|\\(bBreak))|[\\(safeIn)]|[ \\\\t]|\\(bBreak))+\"\nprivate let dashPattern = Yaml.Regex.regex(\"^-([ \\\\t]+(?!#|\\(bBreak))|(?=[ \\\\t\\\\n]))\")\nprivate let finish = \"(?= *(,|\\\\]|\\\\}|( #.*)?(\\(bBreak)|$)))\"\n\nprivate let tokenPatterns: [TokenPattern] = [\n  (.yamlDirective, Yaml.Regex.regex(\"^%YAML(?= )\")),\n  (.docStart, Yaml.Regex.regex(\"^---\")),\n  (.docend, Yaml.Regex.regex(\"^\\\\.\\\\.\\\\.\")),\n  (.comment, Yaml.Regex.regex(\"^#.*|^\\(bBreak) *(#.*)?(?=\\(bBreak)|$)\")),\n  (.space, Yaml.Regex.regex(\"^ +\")),\n  (.newLine, Yaml.Regex.regex(\"^\\(bBreak) *\")),\n  (.dash, dashPattern!),\n  (.null, Yaml.Regex.regex(\"^(null|Null|NULL|~)\\(finish)\")),\n  (._true, Yaml.Regex.regex(\"^(true|True|TRUE)\\(finish)\")),\n  (._false, Yaml.Regex.regex(\"^(false|False|FALSE)\\(finish)\")),\n  (.infinityP, Yaml.Regex.regex(\"^\\\\+?\\\\.(inf|Inf|INF)\\(finish)\")),\n  (.infinityN, Yaml.Regex.regex(\"^-\\\\.(inf|Inf|INF)\\(finish)\")),\n  (.nan, Yaml.Regex.regex(\"^\\\\.(nan|NaN|NAN)\\(finish)\")),\n  (.int, Yaml.Regex.regex(\"^[-+]?[0-9]+\\(finish)\")),\n  (.intOct, Yaml.Regex.regex(\"^0o[0-7]+\\(finish)\")),\n  (.intHex, Yaml.Regex.regex(\"^0x[0-9a-fA-F]+\\(finish)\")),\n  (.intSex, Yaml.Regex.regex(\"^[0-9]{2}(:[0-9]{2})+\\(finish)\")),\n  (.double, Yaml.Regex.regex(\"^[-+]?(\\\\.[0-9]+|[0-9]+(\\\\.[0-9]*)?)([eE][-+]?[0-9]+)?\\(finish)\")),\n  (.anchor, Yaml.Regex.regex(\"^&\\\\w+\")),\n  (.alias, Yaml.Regex.regex(\"^\\\\*\\\\w+\")),\n  (.comma, Yaml.Regex.regex(\"^,\")),\n  (.openSB, Yaml.Regex.regex(\"^\\\\[\")),\n  (.closeSB, Yaml.Regex.regex(\"^\\\\]\")),\n  (.openCB, Yaml.Regex.regex(\"^\\\\{\")),\n  (.closeCB, Yaml.Regex.regex(\"^\\\\}\")),\n  (.questionMark, Yaml.Regex.regex(\"^\\\\?( +|(?=\\(bBreak)))\")),\n  (.colonFO, Yaml.Regex.regex(\"^:(?!:)\")),\n  (.colonFI, Yaml.Regex.regex(\"^:(?!:)\")),\n  (.literal, Yaml.Regex.regex(\"^\\\\|.*\")),\n  (.folded, Yaml.Regex.regex(\"^>.*\")),\n  (.reserved, Yaml.Regex.regex(\"^[@`]\")),\n  (.stringDQ, Yaml.Regex.regex(\"^\\\"([^\\\\\\\\\\\"]|\\\\\\\\(.|\\(bBreak)))*\\\"\")),\n  (.stringSQ, Yaml.Regex.regex(\"^'([^']|'')*'\")),\n  (.stringFO, Yaml.Regex.regex(\"^\\(plainOutPattern)(?=:([ \\\\t]|\\(bBreak))|\\(bBreak)|$)\")),\n  (.stringFI, Yaml.Regex.regex(\"^\\(plainInPattern)\")),\n]\n\nextension Yaml {\n  static func escapeErrorContext (_ text: String) -> String {\n    let endIndex = text.index(text.startIndex, offsetBy: 50, limitedBy: text.endIndex) ?? text.endIndex\n    let escaped = String(text[..<endIndex])\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\\\r\"), template: \"\\\\\\\\r\")\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\\\n\"), template: \"\\\\\\\\n\")\n      |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\\"\"), template: \"\\\\\\\\\\\"\")\n    return \"near \\\"\\(escaped)\\\"\"\n  }\n  \n  \n  static func tokenize (_ text: String) -> YAMLResult<[TokenMatch]> {\n    var text = text\n    var matchList: [TokenMatch] = []\n    var indents = [0]\n    var insideFlow = 0\n    next:\n      while text.endIndex > text.startIndex {\n        for tokenPattern in tokenPatterns {\n          let range = Yaml.Regex.matchRange(text, regex: tokenPattern.pattern)\n          if range.location != NSNotFound {\n            let rangeEnd = range.location + range.length\n            switch tokenPattern.type {\n              \n            case .newLine:\n              let match = (range, text) |> Yaml.Regex.substring\n              let lastindent = indents.last ?? 0\n              let rest = match[match.index(after: match.startIndex)...]\n              let spaces = rest.count\n              let nestedBlockSequence =\n                Yaml.Regex.matches((rangeEnd, text) |> Yaml.Regex.substring, regex: dashPattern!)\n              if spaces == lastindent {\n                matchList.append(TokenMatch(.newLine, match))\n              } else if spaces > lastindent {\n                if insideFlow == 0 {\n                  if matchList.last != nil &&\n                    matchList[matchList.endIndex - 1].type == .indent {\n                    indents[indents.endIndex - 1] = spaces\n                    matchList[matchList.endIndex - 1] = TokenMatch(.indent, match)\n                  } else {\n                    indents.append(spaces)\n                    matchList.append(TokenMatch(.indent, match))\n                  }\n                }\n              } else if nestedBlockSequence && spaces == lastindent - 1 {\n                matchList.append(TokenMatch(.newLine, match))\n              } else {\n                while nestedBlockSequence && spaces < (indents.last ?? 0) - 1\n                  || !nestedBlockSequence && spaces < indents.last ?? 0 {\n                    indents.removeLast()\n                    matchList.append(TokenMatch(.dedent, \"\"))\n                }\n                matchList.append(TokenMatch(.newLine, match))\n              }\n              \n            case .dash, .questionMark:\n              let match = (range, text) |> Yaml.Regex.substring\n              let index = match.index(after: match.startIndex)\n              let indent = match.count\n              indents.append((indents.last ?? 0) + indent)\n              matchList.append(\n                TokenMatch(tokenPattern.type, String(match[..<index])))\n              matchList.append(TokenMatch(.indent, String(match[index...])))\n              \n            case .colonFO:\n              if insideFlow > 0 {\n                continue\n              }\n              fallthrough\n              \n            case .colonFI:\n              let match = (range, text) |> Yaml.Regex.substring\n              matchList.append(TokenMatch(.colon, match))\n              if insideFlow == 0 {\n                indents.append((indents.last ?? 0) + 1)\n                matchList.append(TokenMatch(.indent, \"\"))\n              }\n              \n            case .openSB, .openCB:\n              insideFlow += 1\n              matchList.append(TokenMatch(tokenPattern.type, (range, text) |> Yaml.Regex.substring))\n              \n            case .closeSB, .closeCB:\n              insideFlow -= 1\n              matchList.append(TokenMatch(tokenPattern.type, (range, text) |> Yaml.Regex.substring))\n              \n            case .literal, .folded:\n              matchList.append(TokenMatch(tokenPattern.type, (range, text) |> Yaml.Regex.substring))\n              text = (rangeEnd, text) |> Yaml.Regex.substring\n              let lastindent = indents.last ?? 0\n              let minindent = 1 + lastindent\n              let blockPattern = Yaml.Regex.regex((\"^(\\(bBreak) *)*(\\(bBreak)\" +\n                \"( {\\(minindent),})[^ ].*(\\(bBreak)( *|\\\\3.*))*)(?=\\(bBreak)|$)\"))\n              let (lead, rest) = text |> Yaml.Regex.splitLead(blockPattern!)\n              text = rest\n              let block = (lead\n                |> Yaml.Regex.replace(Yaml.Regex.regex(\"^\\(bBreak)\"), template: \"\")\n                |> Yaml.Regex.replace(Yaml.Regex.regex(\"^ {0,\\(lastindent)}\"), template: \"\")\n                |> Yaml.Regex.replace(Yaml.Regex.regex(\"\\(bBreak) {0,\\(lastindent)}\"), template: \"\\n\")\n                ) + (Yaml.Regex.matches(text, regex: Yaml.Regex.regex(\"^\\(bBreak)\")) && lead.endIndex > lead.startIndex\n                  ? \"\\n\" : \"\")\n              matchList.append(TokenMatch(.string, block))\n              continue next\n              \n            case .stringFO:\n              if insideFlow > 0 {\n                continue\n              }\n              let indent = (indents.last ?? 0)\n              let blockPattern = Yaml.Regex.regex((\"^\\(bBreak)( *| {\\(indent),}\" +\n                \"\\(plainOutPattern))(?=\\(bBreak)|$)\"))\n              var block = (range, text)\n                |> Yaml.Regex.substring\n                |> Yaml.Regex.replace(Yaml.Regex.regex(\"^[ \\\\t]+|[ \\\\t]+$\"), template: \"\")\n              text = (rangeEnd, text) |> Yaml.Regex.substring\n              while true {\n                let range = Yaml.Regex.matchRange(text, regex: blockPattern!)\n                if range.location == NSNotFound {\n                  break\n                }\n                let s = (range, text) |> Yaml.Regex.substring\n                block += \"\\n\" +\n                  Yaml.Regex.replace(Yaml.Regex.regex(\"^\\(bBreak)[ \\\\t]*|[ \\\\t]+$\"), template: \"\")(s)\n                text = (range.location + range.length, text) |> Yaml.Regex.substring\n              }\n              matchList.append(TokenMatch(.string, block))\n              continue next\n              \n            case .stringFI:\n              let match = (range, text)\n                |> Yaml.Regex.substring\n                |> Yaml.Regex.replace(Yaml.Regex.regex(\"^[ \\\\t]|[ \\\\t]$\"), template: \"\")\n              matchList.append(TokenMatch(.string, match))\n              \n            case .reserved:\n              return fail(escapeErrorContext(text))\n              \n            default:\n              matchList.append(TokenMatch(tokenPattern.type, (range, text) |> Yaml.Regex.substring))\n            }\n            text = (rangeEnd, text) |> Yaml.Regex.substring\n            continue next\n          }\n        }\n        return fail(escapeErrorContext(text))\n    }\n    while indents.count > 1 {\n      indents.removeLast()\n      matchList.append((.dedent, \"\"))\n    }\n    matchList.append((.end, \"\"))\n    return lift(matchList)\n  }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Yaml/Sources/Yaml.swift",
    "content": "import Foundation\n\npublic enum Yaml: Hashable {\n  case null\n  case bool(Bool)\n  case int(Int)\n  case double(Double)\n  case string(String)\n  case array([Yaml])\n  case dictionary([Yaml: Yaml])\n    \n    static public func == (lhs: Yaml, rhs: Yaml) -> Bool {\n        switch (lhs, rhs) {\n        case (.null, .null):\n            return true\n        case (.bool(let lv), .bool(let rv)):\n            return lv == rv\n        case (.int(let lv), .int(let rv)):\n            return lv == rv\n        case (.int(let lv), .double(let rv)):\n            return Double(lv) == rv\n        case (.double(let lv), .double(let rv)):\n            return lv == rv\n        case (.double(let lv), .int(let rv)):\n            return lv == Double(rv)\n        case (.string(let lv), .string(let rv)):\n            return lv == rv\n        case (.array(let lv), .array(let rv)):\n            return lv == rv\n        case (.dictionary(let lv), .dictionary(let rv)):\n            return lv == rv\n        default:\n            return false\n        }\n    }\n    \n    // unary `-` operator\n    static public prefix func - (value: Yaml) -> Yaml {\n        switch value {\n        case .int(let v):\n            return .int(-v)\n        case .double(let v):\n            return .double(-v)\n        default:\n            fatalError(\"`-` operator may only be used on .int or .double Yaml values\")\n        }\n    }\n}\n\nextension Yaml {\n  public enum ResultError: Error {\n    case message(String?)\n  }\n}\n\nextension Yaml: ExpressibleByNilLiteral {\n  public init(nilLiteral: ()) {\n    self = .null\n  }\n}\n\nextension Yaml: ExpressibleByBooleanLiteral {\n  public init(booleanLiteral: BooleanLiteralType) {\n    self = .bool(booleanLiteral)\n  }\n}\n\nextension Yaml: ExpressibleByIntegerLiteral {\n  public init(integerLiteral: IntegerLiteralType) {\n    self = .int(integerLiteral)\n  }\n}\n\nextension Yaml: ExpressibleByFloatLiteral {\n  public init(floatLiteral: FloatLiteralType) {\n    self = .double(floatLiteral)\n  }\n}\n\nextension Yaml: ExpressibleByStringLiteral {\n  public init(stringLiteral: StringLiteralType) {\n    self = .string(stringLiteral)\n  }\n\n  public init(extendedGraphemeClusterLiteral: StringLiteralType) {\n    self = .string(extendedGraphemeClusterLiteral)\n  }\n\n  public init(unicodeScalarLiteral: StringLiteralType) {\n    self = .string(unicodeScalarLiteral)\n  }\n}\n\nextension Yaml: ExpressibleByArrayLiteral {\n  public init(arrayLiteral elements: Yaml...) {\n    self = .array(elements)\n  }\n}\n\nextension Yaml: ExpressibleByDictionaryLiteral {\n  public init(dictionaryLiteral elements: (Yaml, Yaml)...) {\n    var dictionary = [Yaml: Yaml]()\n    for (k, v) in elements {\n      dictionary[k] = v\n    }\n    self = .dictionary(dictionary)\n  }\n}\n\nextension Yaml: CustomStringConvertible {\n  public var description: String {\n    switch self {\n    case .null:\n      return \"Null\"\n    case .bool(let b):\n      return \"Bool(\\(b))\"\n    case .int(let i):\n      return \"Int(\\(i))\"\n    case .double(let f):\n      return \"Double(\\(f))\"\n    case .string(let s):\n      return \"String(\\(s))\"\n    case .array(let s):\n      return \"Array(\\(s))\"\n    case .dictionary(let m):\n      return \"Dictionary(\\(m))\"\n    }\n  }\n}\n\n\nextension Yaml {\n  \n  public static func load (_ text: String) throws -> Yaml {\n    let result = tokenize(text) >>=- Context.parseDoc\n    if let value = result.value { return value } else { throw ResultError.message(result.error) }\n  }\n\n  public static func loadMultiple (_ text: String) throws -> [Yaml] {\n    let result = tokenize(text) >>=- Context.parseDocs\n    if let value = result.value { return value } else { throw ResultError.message(result.error) }\n\n  }\n\n  public static func debug (_ text: String) -> Yaml? {\n    let result = tokenize(text)\n        >>- { tokens in print(\"\\n====== Tokens:\\n\\(tokens)\"); return tokens }\n        >>=- Context.parseDoc\n        >>- { value -> Yaml in print(\"------ Doc:\\n\\(value)\"); return value }\n    if let error = result.error {\n      print(\"~~~~~~\\n\\(error)\")\n    }\n    return result.value\n  }\n\n  public static func debugMultiple (_ text: String) -> [Yaml]? {\n    let result = tokenize(text)\n        >>- { tokens in print(\"\\n====== Tokens:\\n\\(tokens)\"); return tokens }\n        >>=- Context.parseDocs\n        >>- { values -> [Yaml] in values.forEach {\n              v in print(\"------ Doc:\\n\\(v)\")\n            }; return values }\n    if let error = result.error {\n      print(\"~~~~~~\\n\\(error)\")\n    }\n    return result.value\n  }\n}\n\nextension Yaml {\n  public subscript(index: Int) -> Yaml {\n    get {\n      assert(index >= 0)\n      switch self {\n      case .array(let array):\n        if array.indices.contains(index) {\n          return array[index]\n        } else {\n          return .null\n        }\n      default:\n        return .null\n      }\n    }\n    set {\n      assert(index >= 0)\n      switch self {\n      case .array(let array):\n        let emptyCount = max(0, index + 1 - array.count)\n        let empty = [Yaml](repeating: .null, count: emptyCount)\n        var new = array\n        new.append(contentsOf: empty)\n        new[index] = newValue\n        self = .array(new)\n      default:\n        var array = [Yaml](repeating: .null, count: index + 1)\n        array[index] = newValue\n        self = .array(array)\n      }\n    }\n  }\n\n  public subscript(key: Yaml) -> Yaml {\n    get {\n      switch self {\n      case .dictionary(let dictionary):\n        return dictionary[key] ?? .null\n      default:\n        return .null\n      }\n    }\n    set {\n      switch self {\n      case .dictionary(let dictionary):\n        var new = dictionary\n        new[key] = newValue\n        self = .dictionary(new)\n      default:\n        var dictionary = [Yaml: Yaml]()\n        dictionary[key] = newValue\n        self = .dictionary(dictionary)\n      }\n    }\n  }\n}\n\nextension Yaml {\n  public var bool: Bool? {\n    switch self {\n    case .bool(let b):\n      return b\n    default:\n      return nil\n    }\n  }\n\n  public var int: Int? {\n    switch self {\n    case .int(let i):\n      return i\n    case .double(let f):\n      if Double(Int(f)) == f {\n        return Int(f)\n      } else {\n        return nil\n      }\n    default:\n      return nil\n    }\n  }\n\n  public var double: Double? {\n    switch self {\n    case .double(let f):\n      return f\n    case .int(let i):\n      return Double(i)\n    default:\n      return nil\n    }\n  }\n\n  public var string: String? {\n    switch self {\n    case .string(let s):\n      return s\n    default:\n      return nil\n    }\n  }\n\n  public var array: [Yaml]? {\n    switch self {\n    case .array(let array):\n      return array\n    default:\n      return nil\n    }\n  }\n\n  public var dictionary: [Yaml: Yaml]? {\n    switch self {\n    case .dictionary(let dictionary):\n      return dictionary\n    default:\n      return nil\n    }\n  }\n\n  public var count: Int? {\n    switch self {\n    case .array(let array):\n      return array.count\n    case .dictionary(let dictionary):\n      return dictionary.count\n    default:\n      return nil\n    }\n  }\n}\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Package.swift",
    "content": "// swift-tools-version:4.2\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"Zstd\",\n    products: [\n        .library(name: \"Zstd\", targets: [\"Zstd\"])\n    ],\n    dependencies: [],\n    targets: [\n        .target(\n            name: \"Zstd\",\n            path: \"Sources\")\n    ]\n)\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/bitstream.h",
    "content": "/* ******************************************************************\n   bitstream\n   Part of FSE library\n   Copyright (C) 2013-present, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n   You can contact the author at :\n   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy\n****************************************************************** */\n#ifndef BITSTREAM_H_MODULE\n#define BITSTREAM_H_MODULE\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n/*\n*  This API consists of small unitary functions, which must be inlined for best performance.\n*  Since link-time-optimization is not available for all compilers,\n*  these functions are defined into a .h to be included.\n*/\n\n/*-****************************************\n*  Dependencies\n******************************************/\n#include \"mem.h\"            /* unaligned access routines */\n#include \"debug.h\"          /* assert(), DEBUGLOG(), RAWLOG() */\n#include \"error_private.h\"  /* error codes and messages */\n\n\n/*=========================================\n*  Target specific\n=========================================*/\n#if defined(__BMI__) && defined(__GNUC__)\n#  include <immintrin.h>   /* support for bextr (experimental) */\n#elif defined(__ICCARM__)\n#  include <intrinsics.h>\n#endif\n\n#define STREAM_ACCUMULATOR_MIN_32  25\n#define STREAM_ACCUMULATOR_MIN_64  57\n#define STREAM_ACCUMULATOR_MIN    ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))\n\n\n/*-******************************************\n*  bitStream encoding API (write forward)\n********************************************/\n/* bitStream can mix input from multiple sources.\n * A critical property of these streams is that they encode and decode in **reverse** direction.\n * So the first bit sequence you add will be the last to be read, like a LIFO stack.\n */\ntypedef struct {\n    size_t bitContainer;\n    unsigned bitPos;\n    char*  startPtr;\n    char*  ptr;\n    char*  endPtr;\n} BIT_CStream_t;\n\nMEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);\nMEM_STATIC void   BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);\nMEM_STATIC void   BIT_flushBits(BIT_CStream_t* bitC);\nMEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);\n\n/* Start with initCStream, providing the size of buffer to write into.\n*  bitStream will never write outside of this buffer.\n*  `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.\n*\n*  bits are first added to a local register.\n*  Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.\n*  Writing data into memory is an explicit operation, performed by the flushBits function.\n*  Hence keep track how many bits are potentially stored into local register to avoid register overflow.\n*  After a flushBits, a maximum of 7 bits might still be stored into local register.\n*\n*  Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers.\n*\n*  Last operation is to close the bitStream.\n*  The function returns the final size of CStream in bytes.\n*  If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)\n*/\n\n\n/*-********************************************\n*  bitStream decoding API (read backward)\n**********************************************/\ntypedef struct {\n    size_t   bitContainer;\n    unsigned bitsConsumed;\n    const char* ptr;\n    const char* start;\n    const char* limitPtr;\n} BIT_DStream_t;\n\ntypedef enum { BIT_DStream_unfinished = 0,\n               BIT_DStream_endOfBuffer = 1,\n               BIT_DStream_completed = 2,\n               BIT_DStream_overflow = 3 } BIT_DStream_status;  /* result of BIT_reloadDStream() */\n               /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */\n\nMEM_STATIC size_t   BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);\nMEM_STATIC size_t   BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);\nMEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);\nMEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);\n\n\n/* Start by invoking BIT_initDStream().\n*  A chunk of the bitStream is then stored into a local register.\n*  Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).\n*  You can then retrieve bitFields stored into the local register, **in reverse order**.\n*  Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.\n*  A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.\n*  Otherwise, it can be less than that, so proceed accordingly.\n*  Checking if DStream has reached its end can be performed with BIT_endOfDStream().\n*/\n\n\n/*-****************************************\n*  unsafe API\n******************************************/\nMEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);\n/* faster, but works only if value is \"clean\", meaning all high bits above nbBits are 0 */\n\nMEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);\n/* unsafe version; does not check buffer overflow */\n\nMEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);\n/* faster, but works only if nbBits >= 1 */\n\n\n\n/*-**************************************************************\n*  Internal functions\n****************************************************************/\nMEM_STATIC unsigned BIT_highbit32 (U32 val)\n{\n    assert(val != 0);\n    {\n#   if defined(_MSC_VER)   /* Visual */\n        unsigned long r=0;\n        _BitScanReverse ( &r, val );\n        return (unsigned) r;\n#   elif defined(__GNUC__) && (__GNUC__ >= 3)   /* Use GCC Intrinsic */\n        return __builtin_clz (val) ^ 31;\n#   elif defined(__ICCARM__)    /* IAR Intrinsic */\n        return 31 - __CLZ(val);\n#   else   /* Software version */\n        static const unsigned DeBruijnClz[32] = { 0,  9,  1, 10, 13, 21,  2, 29,\n                                                 11, 14, 16, 18, 22, 25,  3, 30,\n                                                  8, 12, 20, 28, 15, 17, 24,  7,\n                                                 19, 27, 23,  6, 26,  5,  4, 31 };\n        U32 v = val;\n        v |= v >> 1;\n        v |= v >> 2;\n        v |= v >> 4;\n        v |= v >> 8;\n        v |= v >> 16;\n        return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];\n#   endif\n    }\n}\n\n/*=====    Local Constants   =====*/\nstatic const unsigned BIT_mask[] = {\n    0,          1,         3,         7,         0xF,       0x1F,\n    0x3F,       0x7F,      0xFF,      0x1FF,     0x3FF,     0x7FF,\n    0xFFF,      0x1FFF,    0x3FFF,    0x7FFF,    0xFFFF,    0x1FFFF,\n    0x3FFFF,    0x7FFFF,   0xFFFFF,   0x1FFFFF,  0x3FFFFF,  0x7FFFFF,\n    0xFFFFFF,   0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF,\n    0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */\n#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0]))\n\n/*-**************************************************************\n*  bitStream encoding\n****************************************************************/\n/*! BIT_initCStream() :\n *  `dstCapacity` must be > sizeof(size_t)\n *  @return : 0 if success,\n *            otherwise an error code (can be tested using ERR_isError()) */\nMEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,\n                                  void* startPtr, size_t dstCapacity)\n{\n    bitC->bitContainer = 0;\n    bitC->bitPos = 0;\n    bitC->startPtr = (char*)startPtr;\n    bitC->ptr = bitC->startPtr;\n    bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer);\n    if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall);\n    return 0;\n}\n\n/*! BIT_addBits() :\n *  can add up to 31 bits into `bitC`.\n *  Note : does not check for register overflow ! */\nMEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,\n                            size_t value, unsigned nbBits)\n{\n    MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32);\n    assert(nbBits < BIT_MASK_SIZE);\n    assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);\n    bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;\n    bitC->bitPos += nbBits;\n}\n\n/*! BIT_addBitsFast() :\n *  works only if `value` is _clean_,\n *  meaning all high bits above nbBits are 0 */\nMEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,\n                                size_t value, unsigned nbBits)\n{\n    assert((value>>nbBits) == 0);\n    assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);\n    bitC->bitContainer |= value << bitC->bitPos;\n    bitC->bitPos += nbBits;\n}\n\n/*! BIT_flushBitsFast() :\n *  assumption : bitContainer has not overflowed\n *  unsafe version; does not check buffer overflow */\nMEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)\n{\n    size_t const nbBytes = bitC->bitPos >> 3;\n    assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);\n    assert(bitC->ptr <= bitC->endPtr);\n    MEM_writeLEST(bitC->ptr, bitC->bitContainer);\n    bitC->ptr += nbBytes;\n    bitC->bitPos &= 7;\n    bitC->bitContainer >>= nbBytes*8;\n}\n\n/*! BIT_flushBits() :\n *  assumption : bitContainer has not overflowed\n *  safe version; check for buffer overflow, and prevents it.\n *  note : does not signal buffer overflow.\n *  overflow will be revealed later on using BIT_closeCStream() */\nMEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)\n{\n    size_t const nbBytes = bitC->bitPos >> 3;\n    assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);\n    assert(bitC->ptr <= bitC->endPtr);\n    MEM_writeLEST(bitC->ptr, bitC->bitContainer);\n    bitC->ptr += nbBytes;\n    if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;\n    bitC->bitPos &= 7;\n    bitC->bitContainer >>= nbBytes*8;\n}\n\n/*! BIT_closeCStream() :\n *  @return : size of CStream, in bytes,\n *            or 0 if it could not fit into dstBuffer */\nMEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)\n{\n    BIT_addBitsFast(bitC, 1, 1);   /* endMark */\n    BIT_flushBits(bitC);\n    if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */\n    return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);\n}\n\n\n/*-********************************************************\n*  bitStream decoding\n**********************************************************/\n/*! BIT_initDStream() :\n *  Initialize a BIT_DStream_t.\n * `bitD` : a pointer to an already allocated BIT_DStream_t structure.\n * `srcSize` must be the *exact* size of the bitStream, in bytes.\n * @return : size of stream (== srcSize), or an errorCode if a problem is detected\n */\nMEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)\n{\n    if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }\n\n    bitD->start = (const char*)srcBuffer;\n    bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);\n\n    if (srcSize >=  sizeof(bitD->bitContainer)) {  /* normal case */\n        bitD->ptr   = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);\n        bitD->bitContainer = MEM_readLEST(bitD->ptr);\n        { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];\n          bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;  /* ensures bitsConsumed is always set */\n          if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }\n    } else {\n        bitD->ptr   = bitD->start;\n        bitD->bitContainer = *(const BYTE*)(bitD->start);\n        switch(srcSize)\n        {\n        case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);\n                /* fall-through */\n\n        case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);\n                /* fall-through */\n\n        case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);\n                /* fall-through */\n\n        case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;\n                /* fall-through */\n\n        case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;\n                /* fall-through */\n\n        case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) <<  8;\n                /* fall-through */\n\n        default: break;\n        }\n        {   BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];\n            bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;\n            if (lastByte == 0) return ERROR(corruption_detected);  /* endMark not present */\n        }\n        bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;\n    }\n\n    return srcSize;\n}\n\nMEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)\n{\n    return bitContainer >> start;\n}\n\nMEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)\n{\n    U32 const regMask = sizeof(bitContainer)*8 - 1;\n    /* if start > regMask, bitstream is corrupted, and result is undefined */\n    assert(nbBits < BIT_MASK_SIZE);\n    return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];\n}\n\nMEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)\n{\n    assert(nbBits < BIT_MASK_SIZE);\n    return bitContainer & BIT_mask[nbBits];\n}\n\n/*! BIT_lookBits() :\n *  Provides next n bits from local register.\n *  local register is not modified.\n *  On 32-bits, maxNbBits==24.\n *  On 64-bits, maxNbBits==56.\n * @return : value extracted */\nMEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)\n{\n    /* arbitrate between double-shift and shift+mask */\n#if 1\n    /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8,\n     * bitstream is likely corrupted, and result is undefined */\n    return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);\n#else\n    /* this code path is slower on my os-x laptop */\n    U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;\n    return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);\n#endif\n}\n\n/*! BIT_lookBitsFast() :\n *  unsafe version; only works if nbBits >= 1 */\nMEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)\n{\n    U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;\n    assert(nbBits >= 1);\n    return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);\n}\n\nMEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)\n{\n    bitD->bitsConsumed += nbBits;\n}\n\n/*! BIT_readBits() :\n *  Read (consume) next n bits from local register and update.\n *  Pay attention to not read more than nbBits contained into local register.\n * @return : extracted value. */\nMEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)\n{\n    size_t const value = BIT_lookBits(bitD, nbBits);\n    BIT_skipBits(bitD, nbBits);\n    return value;\n}\n\n/*! BIT_readBitsFast() :\n *  unsafe version; only works only if nbBits >= 1 */\nMEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)\n{\n    size_t const value = BIT_lookBitsFast(bitD, nbBits);\n    assert(nbBits >= 1);\n    BIT_skipBits(bitD, nbBits);\n    return value;\n}\n\n/*! BIT_reloadDStream() :\n *  Refill `bitD` from buffer previously set in BIT_initDStream() .\n *  This function is safe, it guarantees it will not read beyond src buffer.\n * @return : status of `BIT_DStream_t` internal register.\n *           when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */\nMEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)\n{\n    if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8))  /* overflow detected, like end of stream */\n        return BIT_DStream_overflow;\n\n    if (bitD->ptr >= bitD->limitPtr) {\n        bitD->ptr -= bitD->bitsConsumed >> 3;\n        bitD->bitsConsumed &= 7;\n        bitD->bitContainer = MEM_readLEST(bitD->ptr);\n        return BIT_DStream_unfinished;\n    }\n    if (bitD->ptr == bitD->start) {\n        if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;\n        return BIT_DStream_completed;\n    }\n    /* start < ptr < limitPtr */\n    {   U32 nbBytes = bitD->bitsConsumed >> 3;\n        BIT_DStream_status result = BIT_DStream_unfinished;\n        if (bitD->ptr - nbBytes < bitD->start) {\n            nbBytes = (U32)(bitD->ptr - bitD->start);  /* ptr > start */\n            result = BIT_DStream_endOfBuffer;\n        }\n        bitD->ptr -= nbBytes;\n        bitD->bitsConsumed -= nbBytes*8;\n        bitD->bitContainer = MEM_readLEST(bitD->ptr);   /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */\n        return result;\n    }\n}\n\n/*! BIT_endOfDStream() :\n * @return : 1 if DStream has _exactly_ reached its end (all bits consumed).\n */\nMEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)\n{\n    return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));\n}\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* BITSTREAM_H_MODULE */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/compiler.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_COMPILER_H\n#define ZSTD_COMPILER_H\n\n/*-*******************************************************\n*  Compiler specifics\n*********************************************************/\n/* force inlining */\n\n#if !defined(ZSTD_NO_INLINE)\n#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */\n#  define INLINE_KEYWORD inline\n#else\n#  define INLINE_KEYWORD\n#endif\n\n#if defined(__GNUC__) || defined(__ICCARM__)\n#  define FORCE_INLINE_ATTR __attribute__((always_inline))\n#elif defined(_MSC_VER)\n#  define FORCE_INLINE_ATTR __forceinline\n#else\n#  define FORCE_INLINE_ATTR\n#endif\n\n#else\n\n#define INLINE_KEYWORD\n#define FORCE_INLINE_ATTR\n\n#endif\n\n/**\n * FORCE_INLINE_TEMPLATE is used to define C \"templates\", which take constant\n * parameters. They must be inlined for the compiler to eliminate the constant\n * branches.\n */\n#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR\n/**\n * HINT_INLINE is used to help the compiler generate better code. It is *not*\n * used for \"templates\", so it can be tweaked based on the compilers\n * performance.\n *\n * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the\n * always_inline attribute.\n *\n * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline\n * attribute.\n */\n#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5\n#  define HINT_INLINE static INLINE_KEYWORD\n#else\n#  define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR\n#endif\n\n/* UNUSED_ATTR tells the compiler it is okay if the function is unused. */\n#if defined(__GNUC__)\n#  define UNUSED_ATTR __attribute__((unused))\n#else\n#  define UNUSED_ATTR\n#endif\n\n/* force no inlining */\n#ifdef _MSC_VER\n#  define FORCE_NOINLINE static __declspec(noinline)\n#else\n#  if defined(__GNUC__) || defined(__ICCARM__)\n#    define FORCE_NOINLINE static __attribute__((__noinline__))\n#  else\n#    define FORCE_NOINLINE static\n#  endif\n#endif\n\n/* target attribute */\n#ifndef __has_attribute\n  #define __has_attribute(x) 0  /* Compatibility with non-clang compilers. */\n#endif\n#if defined(__GNUC__) || defined(__ICCARM__)\n#  define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))\n#else\n#  define TARGET_ATTRIBUTE(target)\n#endif\n\n/* Enable runtime BMI2 dispatch based on the CPU.\n * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.\n */\n#ifndef DYNAMIC_BMI2\n  #if ((defined(__clang__) && __has_attribute(__target__)) \\\n      || (defined(__GNUC__) \\\n          && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \\\n      && (defined(__x86_64__) || defined(_M_X86)) \\\n      && !defined(__BMI2__)\n  #  define DYNAMIC_BMI2 1\n  #else\n  #  define DYNAMIC_BMI2 0\n  #endif\n#endif\n\n/* prefetch\n * can be disabled, by declaring NO_PREFETCH build macro */\n#if defined(NO_PREFETCH)\n#  define PREFETCH_L1(ptr)  (void)(ptr)  /* disabled */\n#  define PREFETCH_L2(ptr)  (void)(ptr)  /* disabled */\n#else\n#  if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86))  /* _mm_prefetch() is not defined outside of x86/x64 */\n#    include <mmintrin.h>   /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */\n#    define PREFETCH_L1(ptr)  _mm_prefetch((const char*)(ptr), _MM_HINT_T0)\n#    define PREFETCH_L2(ptr)  _mm_prefetch((const char*)(ptr), _MM_HINT_T1)\n#  elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )\n#    define PREFETCH_L1(ptr)  __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)\n#    define PREFETCH_L2(ptr)  __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)\n#  else\n#    define PREFETCH_L1(ptr) (void)(ptr)  /* disabled */\n#    define PREFETCH_L2(ptr) (void)(ptr)  /* disabled */\n#  endif\n#endif  /* NO_PREFETCH */\n\n#define CACHELINE_SIZE 64\n\n#define PREFETCH_AREA(p, s)  {            \\\n    const char* const _ptr = (const char*)(p);  \\\n    size_t const _size = (size_t)(s);     \\\n    size_t _pos;                          \\\n    for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) {  \\\n        PREFETCH_L2(_ptr + _pos);         \\\n    }                                     \\\n}\n\n/* vectorization\n * older GCC (pre gcc-4.3 picked as the cutoff) uses a different syntax */\n#if !defined(__clang__) && defined(__GNUC__)\n#  if (__GNUC__ == 4 && __GNUC_MINOR__ > 3) || (__GNUC__ >= 5)\n#    define DONT_VECTORIZE __attribute__((optimize(\"no-tree-vectorize\")))\n#  else\n#    define DONT_VECTORIZE _Pragma(\"GCC optimize(\\\"no-tree-vectorize\\\")\")\n#  endif\n#else\n#  define DONT_VECTORIZE\n#endif\n\n/* disable warnings */\n#ifdef _MSC_VER    /* Visual Studio */\n#  include <intrin.h>                    /* For Visual 2005 */\n#  pragma warning(disable : 4100)        /* disable: C4100: unreferenced formal parameter */\n#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */\n#  pragma warning(disable : 4204)        /* disable: C4204: non-constant aggregate initializer */\n#  pragma warning(disable : 4214)        /* disable: C4214: non-int bitfields */\n#  pragma warning(disable : 4324)        /* disable: C4324: padded structure */\n#endif\n\n#endif /* ZSTD_COMPILER_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/cpu.h",
    "content": "/*\n * Copyright (c) 2018-present, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_COMMON_CPU_H\n#define ZSTD_COMMON_CPU_H\n\n/**\n * Implementation taken from folly/CpuId.h\n * https://github.com/facebook/folly/blob/master/folly/CpuId.h\n */\n\n#include <string.h>\n\n#include \"mem.h\"\n\n#ifdef _MSC_VER\n#include <intrin.h>\n#endif\n\ntypedef struct {\n    U32 f1c;\n    U32 f1d;\n    U32 f7b;\n    U32 f7c;\n} ZSTD_cpuid_t;\n\nMEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {\n    U32 f1c = 0;\n    U32 f1d = 0;\n    U32 f7b = 0;\n    U32 f7c = 0;\n#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))\n    int reg[4];\n    __cpuid((int*)reg, 0);\n    {\n        int const n = reg[0];\n        if (n >= 1) {\n            __cpuid((int*)reg, 1);\n            f1c = (U32)reg[2];\n            f1d = (U32)reg[3];\n        }\n        if (n >= 7) {\n            __cpuidex((int*)reg, 7, 0);\n            f7b = (U32)reg[1];\n            f7c = (U32)reg[2];\n        }\n    }\n#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)\n    /* The following block like the normal cpuid branch below, but gcc\n     * reserves ebx for use of its pic register so we must specially\n     * handle the save and restore to avoid clobbering the register\n     */\n    U32 n;\n    __asm__(\n        \"pushl %%ebx\\n\\t\"\n        \"cpuid\\n\\t\"\n        \"popl %%ebx\\n\\t\"\n        : \"=a\"(n)\n        : \"a\"(0)\n        : \"ecx\", \"edx\");\n    if (n >= 1) {\n      U32 f1a;\n      __asm__(\n          \"pushl %%ebx\\n\\t\"\n          \"cpuid\\n\\t\"\n          \"popl %%ebx\\n\\t\"\n          : \"=a\"(f1a), \"=c\"(f1c), \"=d\"(f1d)\n          : \"a\"(1));\n    }\n    if (n >= 7) {\n      __asm__(\n          \"pushl %%ebx\\n\\t\"\n          \"cpuid\\n\\t\"\n          \"movl %%ebx, %%eax\\n\\t\"\n          \"popl %%ebx\"\n          : \"=a\"(f7b), \"=c\"(f7c)\n          : \"a\"(7), \"c\"(0)\n          : \"edx\");\n    }\n#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386__)\n    U32 n;\n    __asm__(\"cpuid\" : \"=a\"(n) : \"a\"(0) : \"ebx\", \"ecx\", \"edx\");\n    if (n >= 1) {\n      U32 f1a;\n      __asm__(\"cpuid\" : \"=a\"(f1a), \"=c\"(f1c), \"=d\"(f1d) : \"a\"(1) : \"ebx\");\n    }\n    if (n >= 7) {\n      U32 f7a;\n      __asm__(\"cpuid\"\n              : \"=a\"(f7a), \"=b\"(f7b), \"=c\"(f7c)\n              : \"a\"(7), \"c\"(0)\n              : \"edx\");\n    }\n#endif\n    {\n        ZSTD_cpuid_t cpuid;\n        cpuid.f1c = f1c;\n        cpuid.f1d = f1d;\n        cpuid.f7b = f7b;\n        cpuid.f7c = f7c;\n        return cpuid;\n    }\n}\n\n#define X(name, r, bit)                                                        \\\n  MEM_STATIC int ZSTD_cpuid_##name(ZSTD_cpuid_t const cpuid) {                 \\\n    return ((cpuid.r) & (1U << bit)) != 0;                                     \\\n  }\n\n/* cpuid(1): Processor Info and Feature Bits. */\n#define C(name, bit) X(name, f1c, bit)\n  C(sse3, 0)\n  C(pclmuldq, 1)\n  C(dtes64, 2)\n  C(monitor, 3)\n  C(dscpl, 4)\n  C(vmx, 5)\n  C(smx, 6)\n  C(eist, 7)\n  C(tm2, 8)\n  C(ssse3, 9)\n  C(cnxtid, 10)\n  C(fma, 12)\n  C(cx16, 13)\n  C(xtpr, 14)\n  C(pdcm, 15)\n  C(pcid, 17)\n  C(dca, 18)\n  C(sse41, 19)\n  C(sse42, 20)\n  C(x2apic, 21)\n  C(movbe, 22)\n  C(popcnt, 23)\n  C(tscdeadline, 24)\n  C(aes, 25)\n  C(xsave, 26)\n  C(osxsave, 27)\n  C(avx, 28)\n  C(f16c, 29)\n  C(rdrand, 30)\n#undef C\n#define D(name, bit) X(name, f1d, bit)\n  D(fpu, 0)\n  D(vme, 1)\n  D(de, 2)\n  D(pse, 3)\n  D(tsc, 4)\n  D(msr, 5)\n  D(pae, 6)\n  D(mce, 7)\n  D(cx8, 8)\n  D(apic, 9)\n  D(sep, 11)\n  D(mtrr, 12)\n  D(pge, 13)\n  D(mca, 14)\n  D(cmov, 15)\n  D(pat, 16)\n  D(pse36, 17)\n  D(psn, 18)\n  D(clfsh, 19)\n  D(ds, 21)\n  D(acpi, 22)\n  D(mmx, 23)\n  D(fxsr, 24)\n  D(sse, 25)\n  D(sse2, 26)\n  D(ss, 27)\n  D(htt, 28)\n  D(tm, 29)\n  D(pbe, 31)\n#undef D\n\n/* cpuid(7): Extended Features. */\n#define B(name, bit) X(name, f7b, bit)\n  B(bmi1, 3)\n  B(hle, 4)\n  B(avx2, 5)\n  B(smep, 7)\n  B(bmi2, 8)\n  B(erms, 9)\n  B(invpcid, 10)\n  B(rtm, 11)\n  B(mpx, 14)\n  B(avx512f, 16)\n  B(avx512dq, 17)\n  B(rdseed, 18)\n  B(adx, 19)\n  B(smap, 20)\n  B(avx512ifma, 21)\n  B(pcommit, 22)\n  B(clflushopt, 23)\n  B(clwb, 24)\n  B(avx512pf, 26)\n  B(avx512er, 27)\n  B(avx512cd, 28)\n  B(sha, 29)\n  B(avx512bw, 30)\n  B(avx512vl, 31)\n#undef B\n#define C(name, bit) X(name, f7c, bit)\n  C(prefetchwt1, 0)\n  C(avx512vbmi, 1)\n#undef C\n\n#undef X\n\n#endif /* ZSTD_COMMON_CPU_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/debug.c",
    "content": "/* ******************************************************************\n   debug\n   Part of FSE library\n   Copyright (C) 2013-present, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n   You can contact the author at :\n   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy\n****************************************************************** */\n\n\n/*\n * This module only hosts one global variable\n * which can be used to dynamically influence the verbosity of traces,\n * such as DEBUGLOG and RAWLOG\n */\n\n#include \"debug.h\"\n\nint g_debuglevel = DEBUGLEVEL;\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/debug.h",
    "content": "/* ******************************************************************\n   debug\n   Part of FSE library\n   Copyright (C) 2013-present, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n   You can contact the author at :\n   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy\n****************************************************************** */\n\n\n/*\n * The purpose of this header is to enable debug functions.\n * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time,\n * and DEBUG_STATIC_ASSERT() for compile-time.\n *\n * By default, DEBUGLEVEL==0, which means run-time debug is disabled.\n *\n * Level 1 enables assert() only.\n * Starting level 2, traces can be generated and pushed to stderr.\n * The higher the level, the more verbose the traces.\n *\n * It's possible to dynamically adjust level using variable g_debug_level,\n * which is only declared if DEBUGLEVEL>=2,\n * and is a global variable, not multi-thread protected (use with care)\n */\n\n#ifndef DEBUG_H_12987983217\n#define DEBUG_H_12987983217\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n\n/* static assert is triggered at compile time, leaving no runtime artefact.\n * static assert only works with compile-time constants.\n * Also, this variant can only be used inside a function. */\n#define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1])\n\n\n/* DEBUGLEVEL is expected to be defined externally,\n * typically through compiler command line.\n * Value must be a number. */\n#ifndef DEBUGLEVEL\n#  define DEBUGLEVEL 0\n#endif\n\n\n/* DEBUGFILE can be defined externally,\n * typically through compiler command line.\n * note : currently useless.\n * Value must be stderr or stdout */\n#ifndef DEBUGFILE\n#  define DEBUGFILE stderr\n#endif\n\n\n/* recommended values for DEBUGLEVEL :\n * 0 : release mode, no debug, all run-time checks disabled\n * 1 : enables assert() only, no display\n * 2 : reserved, for currently active debug path\n * 3 : events once per object lifetime (CCtx, CDict, etc.)\n * 4 : events once per frame\n * 5 : events once per block\n * 6 : events once per sequence (verbose)\n * 7+: events at every position (*very* verbose)\n *\n * It's generally inconvenient to output traces > 5.\n * In which case, it's possible to selectively trigger high verbosity levels\n * by modifying g_debug_level.\n */\n\n#if (DEBUGLEVEL>=1)\n#  include <assert.h>\n#else\n#  ifndef assert   /* assert may be already defined, due to prior #include <assert.h> */\n#    define assert(condition) ((void)0)   /* disable assert (default) */\n#  endif\n#endif\n\n#if (DEBUGLEVEL>=2)\n#  include <stdio.h>\nextern int g_debuglevel; /* the variable is only declared,\n                            it actually lives in debug.c,\n                            and is shared by the whole process.\n                            It's not thread-safe.\n                            It's useful when enabling very verbose levels\n                            on selective conditions (such as position in src) */\n\n#  define RAWLOG(l, ...) {                                      \\\n                if (l<=g_debuglevel) {                          \\\n                    fprintf(stderr, __VA_ARGS__);               \\\n            }   }\n#  define DEBUGLOG(l, ...) {                                    \\\n                if (l<=g_debuglevel) {                          \\\n                    fprintf(stderr, __FILE__ \": \" __VA_ARGS__); \\\n                    fprintf(stderr, \" \\n\");                     \\\n            }   }\n#else\n#  define RAWLOG(l, ...)      {}    /* disabled */\n#  define DEBUGLOG(l, ...)    {}    /* disabled */\n#endif\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* DEBUG_H_12987983217 */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/entropy_common.c",
    "content": "/*\n   Common functions of New Generation Entropy library\n   Copyright (C) 2016, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n    You can contact the author at :\n    - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy\n    - Public forum : https://groups.google.com/forum/#!forum/lz4c\n*************************************************************************** */\n\n/* *************************************\n*  Dependencies\n***************************************/\n#include \"mem.h\"\n#include \"error_private.h\"       /* ERR_*, ERROR */\n#define FSE_STATIC_LINKING_ONLY  /* FSE_MIN_TABLELOG */\n#include \"fse.h\"\n#define HUF_STATIC_LINKING_ONLY  /* HUF_TABLELOG_ABSOLUTEMAX */\n#include \"huf.h\"\n\n\n/*===   Version   ===*/\nunsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; }\n\n\n/*===   Error Management   ===*/\nunsigned FSE_isError(size_t code) { return ERR_isError(code); }\nconst char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); }\n\nunsigned HUF_isError(size_t code) { return ERR_isError(code); }\nconst char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }\n\n\n/*-**************************************************************\n*  FSE NCount encoding-decoding\n****************************************************************/\nsize_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,\n                 const void* headerBuffer, size_t hbSize)\n{\n    const BYTE* const istart = (const BYTE*) headerBuffer;\n    const BYTE* const iend = istart + hbSize;\n    const BYTE* ip = istart;\n    int nbBits;\n    int remaining;\n    int threshold;\n    U32 bitStream;\n    int bitCount;\n    unsigned charnum = 0;\n    int previous0 = 0;\n\n    if (hbSize < 4) {\n        /* This function only works when hbSize >= 4 */\n        char buffer[4];\n        memset(buffer, 0, sizeof(buffer));\n        memcpy(buffer, headerBuffer, hbSize);\n        {   size_t const countSize = FSE_readNCount(normalizedCounter, maxSVPtr, tableLogPtr,\n                                                    buffer, sizeof(buffer));\n            if (FSE_isError(countSize)) return countSize;\n            if (countSize > hbSize) return ERROR(corruption_detected);\n            return countSize;\n    }   }\n    assert(hbSize >= 4);\n\n    /* init */\n    memset(normalizedCounter, 0, (*maxSVPtr+1) * sizeof(normalizedCounter[0]));   /* all symbols not present in NCount have a frequency of 0 */\n    bitStream = MEM_readLE32(ip);\n    nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG;   /* extract tableLog */\n    if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);\n    bitStream >>= 4;\n    bitCount = 4;\n    *tableLogPtr = nbBits;\n    remaining = (1<<nbBits)+1;\n    threshold = 1<<nbBits;\n    nbBits++;\n\n    while ((remaining>1) & (charnum<=*maxSVPtr)) {\n        if (previous0) {\n            unsigned n0 = charnum;\n            while ((bitStream & 0xFFFF) == 0xFFFF) {\n                n0 += 24;\n                if (ip < iend-5) {\n                    ip += 2;\n                    bitStream = MEM_readLE32(ip) >> bitCount;\n                } else {\n                    bitStream >>= 16;\n                    bitCount   += 16;\n            }   }\n            while ((bitStream & 3) == 3) {\n                n0 += 3;\n                bitStream >>= 2;\n                bitCount += 2;\n            }\n            n0 += bitStream & 3;\n            bitCount += 2;\n            if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);\n            while (charnum < n0) normalizedCounter[charnum++] = 0;\n            if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {\n                assert((bitCount >> 3) <= 3); /* For first condition to work */\n                ip += bitCount>>3;\n                bitCount &= 7;\n                bitStream = MEM_readLE32(ip) >> bitCount;\n            } else {\n                bitStream >>= 2;\n        }   }\n        {   int const max = (2*threshold-1) - remaining;\n            int count;\n\n            if ((bitStream & (threshold-1)) < (U32)max) {\n                count = bitStream & (threshold-1);\n                bitCount += nbBits-1;\n            } else {\n                count = bitStream & (2*threshold-1);\n                if (count >= threshold) count -= max;\n                bitCount += nbBits;\n            }\n\n            count--;   /* extra accuracy */\n            remaining -= count < 0 ? -count : count;   /* -1 means +1 */\n            normalizedCounter[charnum++] = (short)count;\n            previous0 = !count;\n            while (remaining < threshold) {\n                nbBits--;\n                threshold >>= 1;\n            }\n\n            if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {\n                ip += bitCount>>3;\n                bitCount &= 7;\n            } else {\n                bitCount -= (int)(8 * (iend - 4 - ip));\n                ip = iend - 4;\n            }\n            bitStream = MEM_readLE32(ip) >> (bitCount & 31);\n    }   }   /* while ((remaining>1) & (charnum<=*maxSVPtr)) */\n    if (remaining != 1) return ERROR(corruption_detected);\n    if (bitCount > 32) return ERROR(corruption_detected);\n    *maxSVPtr = charnum-1;\n\n    ip += (bitCount+7)>>3;\n    return ip-istart;\n}\n\n\n/*! HUF_readStats() :\n    Read compact Huffman tree, saved by HUF_writeCTable().\n    `huffWeight` is destination buffer.\n    `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32.\n    @return : size read from `src` , or an error Code .\n    Note : Needed by HUF_readCTable() and HUF_readDTableX?() .\n*/\nsize_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,\n                     U32* nbSymbolsPtr, U32* tableLogPtr,\n                     const void* src, size_t srcSize)\n{\n    U32 weightTotal;\n    const BYTE* ip = (const BYTE*) src;\n    size_t iSize;\n    size_t oSize;\n\n    if (!srcSize) return ERROR(srcSize_wrong);\n    iSize = ip[0];\n    /* memset(huffWeight, 0, hwSize);   *//* is not necessary, even though some analyzer complain ... */\n\n    if (iSize >= 128) {  /* special header */\n        oSize = iSize - 127;\n        iSize = ((oSize+1)/2);\n        if (iSize+1 > srcSize) return ERROR(srcSize_wrong);\n        if (oSize >= hwSize) return ERROR(corruption_detected);\n        ip += 1;\n        {   U32 n;\n            for (n=0; n<oSize; n+=2) {\n                huffWeight[n]   = ip[n/2] >> 4;\n                huffWeight[n+1] = ip[n/2] & 15;\n    }   }   }\n    else  {   /* header compressed with FSE (normal case) */\n        FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)];  /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */\n        if (iSize+1 > srcSize) return ERROR(srcSize_wrong);\n        oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6);   /* max (hwSize-1) values decoded, as last one is implied */\n        if (FSE_isError(oSize)) return oSize;\n    }\n\n    /* collect weight stats */\n    memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));\n    weightTotal = 0;\n    {   U32 n; for (n=0; n<oSize; n++) {\n            if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected);\n            rankStats[huffWeight[n]]++;\n            weightTotal += (1 << huffWeight[n]) >> 1;\n    }   }\n    if (weightTotal == 0) return ERROR(corruption_detected);\n\n    /* get last non-null symbol weight (implied, total must be 2^n) */\n    {   U32 const tableLog = BIT_highbit32(weightTotal) + 1;\n        if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);\n        *tableLogPtr = tableLog;\n        /* determine last weight */\n        {   U32 const total = 1 << tableLog;\n            U32 const rest = total - weightTotal;\n            U32 const verif = 1 << BIT_highbit32(rest);\n            U32 const lastWeight = BIT_highbit32(rest) + 1;\n            if (verif != rest) return ERROR(corruption_detected);    /* last value must be a clean power of 2 */\n            huffWeight[oSize] = (BYTE)lastWeight;\n            rankStats[lastWeight]++;\n    }   }\n\n    /* check tree construction validity */\n    if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected);   /* by construction : at least 2 elts of rank 1, must be even */\n\n    /* results */\n    *nbSymbolsPtr = (U32)(oSize+1);\n    return iSize+1;\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/error_private.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n/* The purpose of this file is to have a single list of error strings embedded in binary */\n\n#include \"error_private.h\"\n\nconst char* ERR_getErrorString(ERR_enum code)\n{\n#ifdef ZSTD_STRIP_ERROR_STRINGS\n    (void)code;\n    return \"Error strings stripped\";\n#else\n    static const char* const notErrorCode = \"Unspecified error code\";\n    switch( code )\n    {\n    case PREFIX(no_error): return \"No error detected\";\n    case PREFIX(GENERIC):  return \"Error (generic)\";\n    case PREFIX(prefix_unknown): return \"Unknown frame descriptor\";\n    case PREFIX(version_unsupported): return \"Version not supported\";\n    case PREFIX(frameParameter_unsupported): return \"Unsupported frame parameter\";\n    case PREFIX(frameParameter_windowTooLarge): return \"Frame requires too much memory for decoding\";\n    case PREFIX(corruption_detected): return \"Corrupted block detected\";\n    case PREFIX(checksum_wrong): return \"Restored data doesn't match checksum\";\n    case PREFIX(parameter_unsupported): return \"Unsupported parameter\";\n    case PREFIX(parameter_outOfBound): return \"Parameter is out of bound\";\n    case PREFIX(init_missing): return \"Context should be init first\";\n    case PREFIX(memory_allocation): return \"Allocation error : not enough memory\";\n    case PREFIX(workSpace_tooSmall): return \"workSpace buffer is not large enough\";\n    case PREFIX(stage_wrong): return \"Operation not authorized at current processing stage\";\n    case PREFIX(tableLog_tooLarge): return \"tableLog requires too much memory : unsupported\";\n    case PREFIX(maxSymbolValue_tooLarge): return \"Unsupported max Symbol Value : too large\";\n    case PREFIX(maxSymbolValue_tooSmall): return \"Specified maxSymbolValue is too small\";\n    case PREFIX(dictionary_corrupted): return \"Dictionary is corrupted\";\n    case PREFIX(dictionary_wrong): return \"Dictionary mismatch\";\n    case PREFIX(dictionaryCreation_failed): return \"Cannot create Dictionary from provided samples\";\n    case PREFIX(dstSize_tooSmall): return \"Destination buffer is too small\";\n    case PREFIX(srcSize_wrong): return \"Src size is incorrect\";\n    case PREFIX(dstBuffer_null): return \"Operation on NULL destination buffer\";\n        /* following error codes are not stable and may be removed or changed in a future version */\n    case PREFIX(frameIndex_tooLarge): return \"Frame index is too large\";\n    case PREFIX(seekableIO): return \"An I/O error occurred when reading/seeking\";\n    case PREFIX(maxCode):\n    default: return notErrorCode;\n    }\n#endif\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/error_private.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n/* Note : this module is expected to remain private, do not expose it */\n\n#ifndef ERROR_H_MODULE\n#define ERROR_H_MODULE\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n\n/* ****************************************\n*  Dependencies\n******************************************/\n#include <stddef.h>        /* size_t */\n#include \"zstd_errors.h\"  /* enum list */\n\n\n/* ****************************************\n*  Compiler-specific\n******************************************/\n#if defined(__GNUC__)\n#  define ERR_STATIC static __attribute__((unused))\n#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)\n#  define ERR_STATIC static inline\n#elif defined(_MSC_VER)\n#  define ERR_STATIC static __inline\n#else\n#  define ERR_STATIC static  /* this version may generate warnings for unused static functions; disable the relevant warning */\n#endif\n\n\n/*-****************************************\n*  Customization (error_public.h)\n******************************************/\ntypedef ZSTD_ErrorCode ERR_enum;\n#define PREFIX(name) ZSTD_error_##name\n\n\n/*-****************************************\n*  Error codes handling\n******************************************/\n#undef ERROR   /* reported already defined on VS 2015 (Rich Geldreich) */\n#define ERROR(name) ZSTD_ERROR(name)\n#define ZSTD_ERROR(name) ((size_t)-PREFIX(name))\n\nERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }\n\nERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }\n\n\n/*-****************************************\n*  Error Strings\n******************************************/\n\nconst char* ERR_getErrorString(ERR_enum code);   /* error_private.c */\n\nERR_STATIC const char* ERR_getErrorName(size_t code)\n{\n    return ERR_getErrorString(ERR_getErrorCode(code));\n}\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* ERROR_H_MODULE */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/fse.h",
    "content": "/* ******************************************************************\n   FSE : Finite State Entropy codec\n   Public Prototypes declaration\n   Copyright (C) 2013-2016, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n   You can contact the author at :\n   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy\n****************************************************************** */\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#ifndef FSE_H\n#define FSE_H\n\n\n/*-*****************************************\n*  Dependencies\n******************************************/\n#include <stddef.h>    /* size_t, ptrdiff_t */\n\n\n/*-*****************************************\n*  FSE_PUBLIC_API : control library symbols visibility\n******************************************/\n#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)\n#  define FSE_PUBLIC_API __attribute__ ((visibility (\"default\")))\n#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1)   /* Visual expected */\n#  define FSE_PUBLIC_API __declspec(dllexport)\n#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)\n#  define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/\n#else\n#  define FSE_PUBLIC_API\n#endif\n\n/*------   Version   ------*/\n#define FSE_VERSION_MAJOR    0\n#define FSE_VERSION_MINOR    9\n#define FSE_VERSION_RELEASE  0\n\n#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE\n#define FSE_QUOTE(str) #str\n#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str)\n#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION)\n\n#define FSE_VERSION_NUMBER  (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE)\nFSE_PUBLIC_API unsigned FSE_versionNumber(void);   /**< library version number; to be used when checking dll version */\n\n\n/*-****************************************\n*  FSE simple functions\n******************************************/\n/*! FSE_compress() :\n    Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'.\n    'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize).\n    @return : size of compressed data (<= dstCapacity).\n    Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!\n                     if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead.\n                     if FSE_isError(return), compression failed (more details using FSE_getErrorName())\n*/\nFSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity,\n                             const void* src, size_t srcSize);\n\n/*! FSE_decompress():\n    Decompress FSE data from buffer 'cSrc', of size 'cSrcSize',\n    into already allocated destination buffer 'dst', of size 'dstCapacity'.\n    @return : size of regenerated data (<= maxDstSize),\n              or an error code, which can be tested using FSE_isError() .\n\n    ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!!\n    Why ? : making this distinction requires a header.\n    Header management is intentionally delegated to the user layer, which can better manage special cases.\n*/\nFSE_PUBLIC_API size_t FSE_decompress(void* dst,  size_t dstCapacity,\n                               const void* cSrc, size_t cSrcSize);\n\n\n/*-*****************************************\n*  Tool functions\n******************************************/\nFSE_PUBLIC_API size_t FSE_compressBound(size_t size);       /* maximum compressed size */\n\n/* Error Management */\nFSE_PUBLIC_API unsigned    FSE_isError(size_t code);        /* tells if a return value is an error code */\nFSE_PUBLIC_API const char* FSE_getErrorName(size_t code);   /* provides error code string (useful for debugging) */\n\n\n/*-*****************************************\n*  FSE advanced functions\n******************************************/\n/*! FSE_compress2() :\n    Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog'\n    Both parameters can be defined as '0' to mean : use default value\n    @return : size of compressed data\n    Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!!\n                     if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression.\n                     if FSE_isError(return), it's an error code.\n*/\nFSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);\n\n\n/*-*****************************************\n*  FSE detailed API\n******************************************/\n/*!\nFSE_compress() does the following:\n1. count symbol occurrence from source[] into table count[] (see hist.h)\n2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog)\n3. save normalized counters to memory buffer using writeNCount()\n4. build encoding table 'CTable' from normalized counters\n5. encode the data stream using encoding table 'CTable'\n\nFSE_decompress() does the following:\n1. read normalized counters with readNCount()\n2. build decoding table 'DTable' from normalized counters\n3. decode the data stream using decoding table 'DTable'\n\nThe following API allows targeting specific sub-functions for advanced tasks.\nFor example, it's possible to compress several blocks using the same 'CTable',\nor to save and provide normalized distribution using external method.\n*/\n\n/* *** COMPRESSION *** */\n\n/*! FSE_optimalTableLog():\n    dynamically downsize 'tableLog' when conditions are met.\n    It saves CPU time, by using smaller tables, while preserving or even improving compression ratio.\n    @return : recommended tableLog (necessarily <= 'maxTableLog') */\nFSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);\n\n/*! FSE_normalizeCount():\n    normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)\n    'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).\n    @return : tableLog,\n              or an errorCode, which can be tested using FSE_isError() */\nFSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog,\n                    const unsigned* count, size_t srcSize, unsigned maxSymbolValue);\n\n/*! FSE_NCountWriteBound():\n    Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.\n    Typically useful for allocation purpose. */\nFSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog);\n\n/*! FSE_writeNCount():\n    Compactly save 'normalizedCounter' into 'buffer'.\n    @return : size of the compressed table,\n              or an errorCode, which can be tested using FSE_isError(). */\nFSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize,\n                                 const short* normalizedCounter,\n                                 unsigned maxSymbolValue, unsigned tableLog);\n\n/*! Constructor and Destructor of FSE_CTable.\n    Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */\ntypedef unsigned FSE_CTable;   /* don't allocate that. It's only meant to be more restrictive than void* */\nFSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog);\nFSE_PUBLIC_API void        FSE_freeCTable (FSE_CTable* ct);\n\n/*! FSE_buildCTable():\n    Builds `ct`, which must be already allocated, using FSE_createCTable().\n    @return : 0, or an errorCode, which can be tested using FSE_isError() */\nFSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);\n\n/*! FSE_compress_usingCTable():\n    Compress `src` using `ct` into `dst` which must be already allocated.\n    @return : size of compressed data (<= `dstCapacity`),\n              or 0 if compressed data could not fit into `dst`,\n              or an errorCode, which can be tested using FSE_isError() */\nFSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);\n\n/*!\nTutorial :\n----------\nThe first step is to count all symbols. FSE_count() does this job very fast.\nResult will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells.\n'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0]\nmaxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value)\nFSE_count() will return the number of occurrence of the most frequent symbol.\nThis can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility.\nIf there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).\n\nThe next step is to normalize the frequencies.\nFSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'.\nIt also guarantees a minimum of 1 to any Symbol with frequency >= 1.\nYou can use 'tableLog'==0 to mean \"use default tableLog value\".\nIf you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(),\nwhich will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means \"default\").\n\nThe result of FSE_normalizeCount() will be saved into a table,\ncalled 'normalizedCounter', which is a table of signed short.\n'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells.\nThe return value is tableLog if everything proceeded as expected.\nIt is 0 if there is a single symbol within distribution.\nIf there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()).\n\n'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount().\n'buffer' must be already allocated.\nFor guaranteed success, buffer size must be at least FSE_headerBound().\nThe result of the function is the number of bytes written into 'buffer'.\nIf there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small).\n\n'normalizedCounter' can then be used to create the compression table 'CTable'.\nThe space required by 'CTable' must be already allocated, using FSE_createCTable().\nYou can then use FSE_buildCTable() to fill 'CTable'.\nIf there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()).\n\n'CTable' can then be used to compress 'src', with FSE_compress_usingCTable().\nSimilar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize'\nThe function returns the size of compressed data (without header), necessarily <= `dstCapacity`.\nIf it returns '0', compressed data could not fit into 'dst'.\nIf there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).\n*/\n\n\n/* *** DECOMPRESSION *** */\n\n/*! FSE_readNCount():\n    Read compactly saved 'normalizedCounter' from 'rBuffer'.\n    @return : size read from 'rBuffer',\n              or an errorCode, which can be tested using FSE_isError().\n              maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */\nFSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter,\n                           unsigned* maxSymbolValuePtr, unsigned* tableLogPtr,\n                           const void* rBuffer, size_t rBuffSize);\n\n/*! Constructor and Destructor of FSE_DTable.\n    Note that its size depends on 'tableLog' */\ntypedef unsigned FSE_DTable;   /* don't allocate that. It's just a way to be more restrictive than void* */\nFSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog);\nFSE_PUBLIC_API void        FSE_freeDTable(FSE_DTable* dt);\n\n/*! FSE_buildDTable():\n    Builds 'dt', which must be already allocated, using FSE_createDTable().\n    return : 0, or an errorCode, which can be tested using FSE_isError() */\nFSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);\n\n/*! FSE_decompress_usingDTable():\n    Decompress compressed source `cSrc` of size `cSrcSize` using `dt`\n    into `dst` which must be already allocated.\n    @return : size of regenerated data (necessarily <= `dstCapacity`),\n              or an errorCode, which can be tested using FSE_isError() */\nFSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);\n\n/*!\nTutorial :\n----------\n(Note : these functions only decompress FSE-compressed blocks.\n If block is uncompressed, use memcpy() instead\n If block is a single repeated byte, use memset() instead )\n\nThe first step is to obtain the normalized frequencies of symbols.\nThis can be performed by FSE_readNCount() if it was saved using FSE_writeNCount().\n'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short.\nIn practice, that means it's necessary to know 'maxSymbolValue' beforehand,\nor size the table to handle worst case situations (typically 256).\nFSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'.\nThe result of FSE_readNCount() is the number of bytes read from 'rBuffer'.\nNote that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that.\nIf there is an error, the function will return an error code, which can be tested using FSE_isError().\n\nThe next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'.\nThis is performed by the function FSE_buildDTable().\nThe space required by 'FSE_DTable' must be already allocated using FSE_createDTable().\nIf there is an error, the function will return an error code, which can be tested using FSE_isError().\n\n`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable().\n`cSrcSize` must be strictly correct, otherwise decompression will fail.\nFSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`).\nIf there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small)\n*/\n\n#endif  /* FSE_H */\n\n#if defined(FSE_STATIC_LINKING_ONLY) && !defined(FSE_H_FSE_STATIC_LINKING_ONLY)\n#define FSE_H_FSE_STATIC_LINKING_ONLY\n\n/* *** Dependency *** */\n#include \"bitstream.h\"\n\n\n/* *****************************************\n*  Static allocation\n*******************************************/\n/* FSE buffer bounds */\n#define FSE_NCOUNTBOUND 512\n#define FSE_BLOCKBOUND(size) (size + (size>>7) + 4 /* fse states */ + sizeof(size_t) /* bitContainer */)\n#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size))   /* Macro version, useful for static allocation */\n\n/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */\n#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue)   (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))\n#define FSE_DTABLE_SIZE_U32(maxTableLog)                   (1 + (1<<maxTableLog))\n\n/* or use the size to malloc() space directly. Pay attention to alignment restrictions though */\n#define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue)   (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable))\n#define FSE_DTABLE_SIZE(maxTableLog)                   (FSE_DTABLE_SIZE_U32(maxTableLog) * sizeof(FSE_DTable))\n\n\n/* *****************************************\n *  FSE advanced API\n ***************************************** */\n\nunsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);\n/**< same as FSE_optimalTableLog(), which used `minus==2` */\n\n/* FSE_compress_wksp() :\n * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).\n * FSE_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable.\n */\n#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue)   ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) )\nsize_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);\n\nsize_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);\n/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */\n\nsize_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);\n/**< build a fake FSE_CTable, designed to compress always the same symbolValue */\n\n/* FSE_buildCTable_wksp() :\n * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).\n * `wkspSize` must be >= `(1<<tableLog)`.\n */\nsize_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);\n\nsize_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);\n/**< build a fake FSE_DTable, designed to read a flat distribution where each symbol uses nbBits */\n\nsize_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);\n/**< build a fake FSE_DTable, designed to always generate the same symbolValue */\n\nsize_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog);\n/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DTABLE_SIZE_U32(maxLog)` */\n\ntypedef enum {\n   FSE_repeat_none,  /**< Cannot use the previous table */\n   FSE_repeat_check, /**< Can use the previous table but it must be checked */\n   FSE_repeat_valid  /**< Can use the previous table and it is assumed to be valid */\n } FSE_repeat;\n\n/* *****************************************\n*  FSE symbol compression API\n*******************************************/\n/*!\n   This API consists of small unitary functions, which highly benefit from being inlined.\n   Hence their body are included in next section.\n*/\ntypedef struct {\n    ptrdiff_t   value;\n    const void* stateTable;\n    const void* symbolTT;\n    unsigned    stateLog;\n} FSE_CState_t;\n\nstatic void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct);\n\nstatic void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol);\n\nstatic void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr);\n\n/**<\nThese functions are inner components of FSE_compress_usingCTable().\nThey allow the creation of custom streams, mixing multiple tables and bit sources.\n\nA key property to keep in mind is that encoding and decoding are done **in reverse direction**.\nSo the first symbol you will encode is the last you will decode, like a LIFO stack.\n\nYou will need a few variables to track your CStream. They are :\n\nFSE_CTable    ct;         // Provided by FSE_buildCTable()\nBIT_CStream_t bitStream;  // bitStream tracking structure\nFSE_CState_t  state;      // State tracking structure (can have several)\n\n\nThe first thing to do is to init bitStream and state.\n    size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize);\n    FSE_initCState(&state, ct);\n\nNote that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError();\nYou can then encode your input data, byte after byte.\nFSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time.\nRemember decoding will be done in reverse direction.\n    FSE_encodeByte(&bitStream, &state, symbol);\n\nAt any time, you can also add any bit sequence.\nNote : maximum allowed nbBits is 25, for compatibility with 32-bits decoders\n    BIT_addBits(&bitStream, bitField, nbBits);\n\nThe above methods don't commit data to memory, they just store it into local register, for speed.\nLocal register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).\nWriting data to memory is a manual operation, performed by the flushBits function.\n    BIT_flushBits(&bitStream);\n\nYour last FSE encoding operation shall be to flush your last state value(s).\n    FSE_flushState(&bitStream, &state);\n\nFinally, you must close the bitStream.\nThe function returns the size of CStream in bytes.\nIf data couldn't fit into dstBuffer, it will return a 0 ( == not compressible)\nIf there is an error, it returns an errorCode (which can be tested using FSE_isError()).\n    size_t size = BIT_closeCStream(&bitStream);\n*/\n\n\n/* *****************************************\n*  FSE symbol decompression API\n*******************************************/\ntypedef struct {\n    size_t      state;\n    const void* table;   /* precise table may vary, depending on U16 */\n} FSE_DState_t;\n\n\nstatic void     FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt);\n\nstatic unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);\n\nstatic unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);\n\n/**<\nLet's now decompose FSE_decompress_usingDTable() into its unitary components.\nYou will decode FSE-encoded symbols from the bitStream,\nand also any other bitFields you put in, **in reverse order**.\n\nYou will need a few variables to track your bitStream. They are :\n\nBIT_DStream_t DStream;    // Stream context\nFSE_DState_t  DState;     // State context. Multiple ones are possible\nFSE_DTable*   DTablePtr;  // Decoding table, provided by FSE_buildDTable()\n\nThe first thing to do is to init the bitStream.\n    errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize);\n\nYou should then retrieve your initial state(s)\n(in reverse flushing order if you have several ones) :\n    errorCode = FSE_initDState(&DState, &DStream, DTablePtr);\n\nYou can then decode your data, symbol after symbol.\nFor information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'.\nKeep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).\n    unsigned char symbol = FSE_decodeSymbol(&DState, &DStream);\n\nYou can retrieve any bitfield you eventually stored into the bitStream (in reverse order)\nNote : maximum allowed nbBits is 25, for 32-bits compatibility\n    size_t bitField = BIT_readBits(&DStream, nbBits);\n\nAll above operations only read from local register (which size depends on size_t).\nRefueling the register from memory is manually performed by the reload method.\n    endSignal = FSE_reloadDStream(&DStream);\n\nBIT_reloadDStream() result tells if there is still some more data to read from DStream.\nBIT_DStream_unfinished : there is still some data left into the DStream.\nBIT_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled.\nBIT_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed.\nBIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted.\n\nWhen reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,\nto properly detect the exact end of stream.\nAfter each decoded symbol, check if DStream is fully consumed using this simple test :\n    BIT_reloadDStream(&DStream) >= BIT_DStream_completed\n\nWhen it's done, verify decompression is fully completed, by checking both DStream and the relevant states.\nChecking if DStream has reached its end is performed by :\n    BIT_endOfDStream(&DStream);\nCheck also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.\n    FSE_endOfDState(&DState);\n*/\n\n\n/* *****************************************\n*  FSE unsafe API\n*******************************************/\nstatic unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);\n/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */\n\n\n/* *****************************************\n*  Implementation of inlined functions\n*******************************************/\ntypedef struct {\n    int deltaFindState;\n    U32 deltaNbBits;\n} FSE_symbolCompressionTransform; /* total 8 bytes */\n\nMEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)\n{\n    const void* ptr = ct;\n    const U16* u16ptr = (const U16*) ptr;\n    const U32 tableLog = MEM_read16(ptr);\n    statePtr->value = (ptrdiff_t)1<<tableLog;\n    statePtr->stateTable = u16ptr+2;\n    statePtr->symbolTT = ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1);\n    statePtr->stateLog = tableLog;\n}\n\n\n/*! FSE_initCState2() :\n*   Same as FSE_initCState(), but the first symbol to include (which will be the last to be read)\n*   uses the smallest state value possible, saving the cost of this symbol */\nMEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)\n{\n    FSE_initCState(statePtr, ct);\n    {   const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];\n        const U16* stateTable = (const U16*)(statePtr->stateTable);\n        U32 nbBitsOut  = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);\n        statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;\n        statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];\n    }\n}\n\nMEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, unsigned symbol)\n{\n    FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];\n    const U16* const stateTable = (const U16*)(statePtr->stateTable);\n    U32 const nbBitsOut  = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);\n    BIT_addBits(bitC, statePtr->value, nbBitsOut);\n    statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];\n}\n\nMEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)\n{\n    BIT_addBits(bitC, statePtr->value, statePtr->stateLog);\n    BIT_flushBits(bitC);\n}\n\n\n/* FSE_getMaxNbBits() :\n * Approximate maximum cost of a symbol, in bits.\n * Fractional get rounded up (i.e : a symbol with a normalized frequency of 3 gives the same result as a frequency of 2)\n * note 1 : assume symbolValue is valid (<= maxSymbolValue)\n * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */\nMEM_STATIC U32 FSE_getMaxNbBits(const void* symbolTTPtr, U32 symbolValue)\n{\n    const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr;\n    return (symbolTT[symbolValue].deltaNbBits + ((1<<16)-1)) >> 16;\n}\n\n/* FSE_bitCost() :\n * Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits)\n * note 1 : assume symbolValue is valid (<= maxSymbolValue)\n * note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits */\nMEM_STATIC U32 FSE_bitCost(const void* symbolTTPtr, U32 tableLog, U32 symbolValue, U32 accuracyLog)\n{\n    const FSE_symbolCompressionTransform* symbolTT = (const FSE_symbolCompressionTransform*) symbolTTPtr;\n    U32 const minNbBits = symbolTT[symbolValue].deltaNbBits >> 16;\n    U32 const threshold = (minNbBits+1) << 16;\n    assert(tableLog < 16);\n    assert(accuracyLog < 31-tableLog);  /* ensure enough room for renormalization double shift */\n    {   U32 const tableSize = 1 << tableLog;\n        U32 const deltaFromThreshold = threshold - (symbolTT[symbolValue].deltaNbBits + tableSize);\n        U32 const normalizedDeltaFromThreshold = (deltaFromThreshold << accuracyLog) >> tableLog;   /* linear interpolation (very approximate) */\n        U32 const bitMultiplier = 1 << accuracyLog;\n        assert(symbolTT[symbolValue].deltaNbBits + tableSize <= threshold);\n        assert(normalizedDeltaFromThreshold <= bitMultiplier);\n        return (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold;\n    }\n}\n\n\n/* ======    Decompression    ====== */\n\ntypedef struct {\n    U16 tableLog;\n    U16 fastMode;\n} FSE_DTableHeader;   /* sizeof U32 */\n\ntypedef struct\n{\n    unsigned short newState;\n    unsigned char  symbol;\n    unsigned char  nbBits;\n} FSE_decode_t;   /* size == U32 */\n\nMEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)\n{\n    const void* ptr = dt;\n    const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;\n    DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);\n    BIT_reloadDStream(bitD);\n    DStatePtr->table = dt + 1;\n}\n\nMEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)\n{\n    FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];\n    return DInfo.symbol;\n}\n\nMEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)\n{\n    FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];\n    U32 const nbBits = DInfo.nbBits;\n    size_t const lowBits = BIT_readBits(bitD, nbBits);\n    DStatePtr->state = DInfo.newState + lowBits;\n}\n\nMEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)\n{\n    FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];\n    U32 const nbBits = DInfo.nbBits;\n    BYTE const symbol = DInfo.symbol;\n    size_t const lowBits = BIT_readBits(bitD, nbBits);\n\n    DStatePtr->state = DInfo.newState + lowBits;\n    return symbol;\n}\n\n/*! FSE_decodeSymbolFast() :\n    unsafe, only works if no symbol has a probability > 50% */\nMEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)\n{\n    FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];\n    U32 const nbBits = DInfo.nbBits;\n    BYTE const symbol = DInfo.symbol;\n    size_t const lowBits = BIT_readBitsFast(bitD, nbBits);\n\n    DStatePtr->state = DInfo.newState + lowBits;\n    return symbol;\n}\n\nMEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)\n{\n    return DStatePtr->state == 0;\n}\n\n\n\n#ifndef FSE_COMMONDEFS_ONLY\n\n/* **************************************************************\n*  Tuning parameters\n****************************************************************/\n/*!MEMORY_USAGE :\n*  Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)\n*  Increasing memory usage improves compression ratio\n*  Reduced memory usage can improve speed, due to cache effect\n*  Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */\n#ifndef FSE_MAX_MEMORY_USAGE\n#  define FSE_MAX_MEMORY_USAGE 14\n#endif\n#ifndef FSE_DEFAULT_MEMORY_USAGE\n#  define FSE_DEFAULT_MEMORY_USAGE 13\n#endif\n\n/*!FSE_MAX_SYMBOL_VALUE :\n*  Maximum symbol value authorized.\n*  Required for proper stack allocation */\n#ifndef FSE_MAX_SYMBOL_VALUE\n#  define FSE_MAX_SYMBOL_VALUE 255\n#endif\n\n/* **************************************************************\n*  template functions type & suffix\n****************************************************************/\n#define FSE_FUNCTION_TYPE BYTE\n#define FSE_FUNCTION_EXTENSION\n#define FSE_DECODE_TYPE FSE_decode_t\n\n\n#endif   /* !FSE_COMMONDEFS_ONLY */\n\n\n/* ***************************************************************\n*  Constants\n*****************************************************************/\n#define FSE_MAX_TABLELOG  (FSE_MAX_MEMORY_USAGE-2)\n#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)\n#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)\n#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)\n#define FSE_MIN_TABLELOG 5\n\n#define FSE_TABLELOG_ABSOLUTE_MAX 15\n#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX\n#  error \"FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported\"\n#endif\n\n#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)\n\n\n#endif /* FSE_STATIC_LINKING_ONLY */\n\n\n#if defined (__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/fse_compress.c",
    "content": "/* ******************************************************************\n   FSE : Finite State Entropy encoder\n   Copyright (C) 2013-present, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n    You can contact the author at :\n    - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy\n    - Public forum : https://groups.google.com/forum/#!forum/lz4c\n****************************************************************** */\n\n/* **************************************************************\n*  Includes\n****************************************************************/\n#include <stdlib.h>     /* malloc, free, qsort */\n#include <string.h>     /* memcpy, memset */\n#include \"compiler.h\"\n#include \"mem.h\"        /* U32, U16, etc. */\n#include \"debug.h\"      /* assert, DEBUGLOG */\n#include \"hist.h\"       /* HIST_count_wksp */\n#include \"bitstream.h\"\n#define FSE_STATIC_LINKING_ONLY\n#include \"fse.h\"\n#include \"error_private.h\"\n\n\n/* **************************************************************\n*  Error Management\n****************************************************************/\n#define FSE_isError ERR_isError\n\n\n/* **************************************************************\n*  Templates\n****************************************************************/\n/*\n  designed to be included\n  for type-specific functions (template emulation in C)\n  Objective is to write these functions only once, for improved maintenance\n*/\n\n/* safety checks */\n#ifndef FSE_FUNCTION_EXTENSION\n#  error \"FSE_FUNCTION_EXTENSION must be defined\"\n#endif\n#ifndef FSE_FUNCTION_TYPE\n#  error \"FSE_FUNCTION_TYPE must be defined\"\n#endif\n\n/* Function names */\n#define FSE_CAT(X,Y) X##Y\n#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)\n#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)\n\n\n/* Function templates */\n\n/* FSE_buildCTable_wksp() :\n * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).\n * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)`\n * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements\n */\nsize_t FSE_buildCTable_wksp(FSE_CTable* ct,\n                      const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,\n                            void* workSpace, size_t wkspSize)\n{\n    U32 const tableSize = 1 << tableLog;\n    U32 const tableMask = tableSize - 1;\n    void* const ptr = ct;\n    U16* const tableU16 = ( (U16*) ptr) + 2;\n    void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;\n    FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);\n    U32 const step = FSE_TABLESTEP(tableSize);\n    U32 cumul[FSE_MAX_SYMBOL_VALUE+2];\n\n    FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;\n    U32 highThreshold = tableSize-1;\n\n    /* CTable header */\n    if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);\n    tableU16[-2] = (U16) tableLog;\n    tableU16[-1] = (U16) maxSymbolValue;\n    assert(tableLog < 16);   /* required for threshold strategy to work */\n\n    /* For explanations on how to distribute symbol values over the table :\n     * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */\n\n     #ifdef __clang_analyzer__\n     memset(tableSymbol, 0, sizeof(*tableSymbol) * tableSize);   /* useless initialization, just to keep scan-build happy */\n     #endif\n\n    /* symbol start positions */\n    {   U32 u;\n        cumul[0] = 0;\n        for (u=1; u <= maxSymbolValue+1; u++) {\n            if (normalizedCounter[u-1]==-1) {  /* Low proba symbol */\n                cumul[u] = cumul[u-1] + 1;\n                tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);\n            } else {\n                cumul[u] = cumul[u-1] + normalizedCounter[u-1];\n        }   }\n        cumul[maxSymbolValue+1] = tableSize+1;\n    }\n\n    /* Spread symbols */\n    {   U32 position = 0;\n        U32 symbol;\n        for (symbol=0; symbol<=maxSymbolValue; symbol++) {\n            int nbOccurrences;\n            int const freq = normalizedCounter[symbol];\n            for (nbOccurrences=0; nbOccurrences<freq; nbOccurrences++) {\n                tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;\n                position = (position + step) & tableMask;\n                while (position > highThreshold)\n                    position = (position + step) & tableMask;   /* Low proba area */\n        }   }\n\n        assert(position==0);  /* Must have initialized all positions */\n    }\n\n    /* Build table */\n    {   U32 u; for (u=0; u<tableSize; u++) {\n        FSE_FUNCTION_TYPE s = tableSymbol[u];   /* note : static analyzer may not understand tableSymbol is properly initialized */\n        tableU16[cumul[s]++] = (U16) (tableSize+u);   /* TableU16 : sorted by symbol order; gives next state value */\n    }   }\n\n    /* Build Symbol Transformation Table */\n    {   unsigned total = 0;\n        unsigned s;\n        for (s=0; s<=maxSymbolValue; s++) {\n            switch (normalizedCounter[s])\n            {\n            case  0:\n                /* filling nonetheless, for compatibility with FSE_getMaxNbBits() */\n                symbolTT[s].deltaNbBits = ((tableLog+1) << 16) - (1<<tableLog);\n                break;\n\n            case -1:\n            case  1:\n                symbolTT[s].deltaNbBits = (tableLog << 16) - (1<<tableLog);\n                symbolTT[s].deltaFindState = total - 1;\n                total ++;\n                break;\n            default :\n                {\n                    U32 const maxBitsOut = tableLog - BIT_highbit32 (normalizedCounter[s]-1);\n                    U32 const minStatePlus = normalizedCounter[s] << maxBitsOut;\n                    symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;\n                    symbolTT[s].deltaFindState = total - normalizedCounter[s];\n                    total +=  normalizedCounter[s];\n    }   }   }   }\n\n#if 0  /* debug : symbol costs */\n    DEBUGLOG(5, \"\\n --- table statistics : \");\n    {   U32 symbol;\n        for (symbol=0; symbol<=maxSymbolValue; symbol++) {\n            DEBUGLOG(5, \"%3u: w=%3i,   maxBits=%u, fracBits=%.2f\",\n                symbol, normalizedCounter[symbol],\n                FSE_getMaxNbBits(symbolTT, symbol),\n                (double)FSE_bitCost(symbolTT, tableLog, symbol, 8) / 256);\n        }\n    }\n#endif\n\n    return 0;\n}\n\n\nsize_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)\n{\n    FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE];   /* memset() is not necessary, even if static analyzer complain about it */\n    return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol));\n}\n\n\n\n#ifndef FSE_COMMONDEFS_ONLY\n\n\n/*-**************************************************************\n*  FSE NCount encoding\n****************************************************************/\nsize_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)\n{\n    size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;\n    return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND;  /* maxSymbolValue==0 ? use default */\n}\n\nstatic size_t\nFSE_writeNCount_generic (void* header, size_t headerBufferSize,\n                   const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,\n                         unsigned writeIsSafe)\n{\n    BYTE* const ostart = (BYTE*) header;\n    BYTE* out = ostart;\n    BYTE* const oend = ostart + headerBufferSize;\n    int nbBits;\n    const int tableSize = 1 << tableLog;\n    int remaining;\n    int threshold;\n    U32 bitStream = 0;\n    int bitCount = 0;\n    unsigned symbol = 0;\n    unsigned const alphabetSize = maxSymbolValue + 1;\n    int previousIs0 = 0;\n\n    /* Table Size */\n    bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;\n    bitCount  += 4;\n\n    /* Init */\n    remaining = tableSize+1;   /* +1 for extra accuracy */\n    threshold = tableSize;\n    nbBits = tableLog+1;\n\n    while ((symbol < alphabetSize) && (remaining>1)) {  /* stops at 1 */\n        if (previousIs0) {\n            unsigned start = symbol;\n            while ((symbol < alphabetSize) && !normalizedCounter[symbol]) symbol++;\n            if (symbol == alphabetSize) break;   /* incorrect distribution */\n            while (symbol >= start+24) {\n                start+=24;\n                bitStream += 0xFFFFU << bitCount;\n                if ((!writeIsSafe) && (out > oend-2))\n                    return ERROR(dstSize_tooSmall);   /* Buffer overflow */\n                out[0] = (BYTE) bitStream;\n                out[1] = (BYTE)(bitStream>>8);\n                out+=2;\n                bitStream>>=16;\n            }\n            while (symbol >= start+3) {\n                start+=3;\n                bitStream += 3 << bitCount;\n                bitCount += 2;\n            }\n            bitStream += (symbol-start) << bitCount;\n            bitCount += 2;\n            if (bitCount>16) {\n                if ((!writeIsSafe) && (out > oend - 2))\n                    return ERROR(dstSize_tooSmall);   /* Buffer overflow */\n                out[0] = (BYTE)bitStream;\n                out[1] = (BYTE)(bitStream>>8);\n                out += 2;\n                bitStream >>= 16;\n                bitCount -= 16;\n        }   }\n        {   int count = normalizedCounter[symbol++];\n            int const max = (2*threshold-1) - remaining;\n            remaining -= count < 0 ? -count : count;\n            count++;   /* +1 for extra accuracy */\n            if (count>=threshold)\n                count += max;   /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */\n            bitStream += count << bitCount;\n            bitCount  += nbBits;\n            bitCount  -= (count<max);\n            previousIs0  = (count==1);\n            if (remaining<1) return ERROR(GENERIC);\n            while (remaining<threshold) { nbBits--; threshold>>=1; }\n        }\n        if (bitCount>16) {\n            if ((!writeIsSafe) && (out > oend - 2))\n                return ERROR(dstSize_tooSmall);   /* Buffer overflow */\n            out[0] = (BYTE)bitStream;\n            out[1] = (BYTE)(bitStream>>8);\n            out += 2;\n            bitStream >>= 16;\n            bitCount -= 16;\n    }   }\n\n    if (remaining != 1)\n        return ERROR(GENERIC);  /* incorrect normalized distribution */\n    assert(symbol <= alphabetSize);\n\n    /* flush remaining bitStream */\n    if ((!writeIsSafe) && (out > oend - 2))\n        return ERROR(dstSize_tooSmall);   /* Buffer overflow */\n    out[0] = (BYTE)bitStream;\n    out[1] = (BYTE)(bitStream>>8);\n    out+= (bitCount+7) /8;\n\n    return (out-ostart);\n}\n\n\nsize_t FSE_writeNCount (void* buffer, size_t bufferSize,\n                  const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)\n{\n    if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported */\n    if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported */\n\n    if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))\n        return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);\n\n    return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1 /* write in buffer is safe */);\n}\n\n\n/*-**************************************************************\n*  FSE Compression Code\n****************************************************************/\n\nFSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)\n{\n    size_t size;\n    if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;\n    size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);\n    return (FSE_CTable*)malloc(size);\n}\n\nvoid FSE_freeCTable (FSE_CTable* ct) { free(ct); }\n\n/* provides the minimum logSize to safely represent a distribution */\nstatic unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)\n{\n    U32 minBitsSrc = BIT_highbit32((U32)(srcSize)) + 1;\n    U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;\n    U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;\n    assert(srcSize > 1); /* Not supported, RLE should be used instead */\n    return minBits;\n}\n\nunsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)\n{\n    U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;\n    U32 tableLog = maxTableLog;\n    U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);\n    assert(srcSize > 1); /* Not supported, RLE should be used instead */\n    if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;\n    if (maxBitsSrc < tableLog) tableLog = maxBitsSrc;   /* Accuracy can be reduced */\n    if (minBits > tableLog) tableLog = minBits;   /* Need a minimum to safely represent all symbol values */\n    if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;\n    if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;\n    return tableLog;\n}\n\nunsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)\n{\n    return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);\n}\n\n\n/* Secondary normalization method.\n   To be used when primary method fails. */\n\nstatic size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)\n{\n    short const NOT_YET_ASSIGNED = -2;\n    U32 s;\n    U32 distributed = 0;\n    U32 ToDistribute;\n\n    /* Init */\n    U32 const lowThreshold = (U32)(total >> tableLog);\n    U32 lowOne = (U32)((total * 3) >> (tableLog + 1));\n\n    for (s=0; s<=maxSymbolValue; s++) {\n        if (count[s] == 0) {\n            norm[s]=0;\n            continue;\n        }\n        if (count[s] <= lowThreshold) {\n            norm[s] = -1;\n            distributed++;\n            total -= count[s];\n            continue;\n        }\n        if (count[s] <= lowOne) {\n            norm[s] = 1;\n            distributed++;\n            total -= count[s];\n            continue;\n        }\n\n        norm[s]=NOT_YET_ASSIGNED;\n    }\n    ToDistribute = (1 << tableLog) - distributed;\n\n    if (ToDistribute == 0)\n        return 0;\n\n    if ((total / ToDistribute) > lowOne) {\n        /* risk of rounding to zero */\n        lowOne = (U32)((total * 3) / (ToDistribute * 2));\n        for (s=0; s<=maxSymbolValue; s++) {\n            if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) {\n                norm[s] = 1;\n                distributed++;\n                total -= count[s];\n                continue;\n        }   }\n        ToDistribute = (1 << tableLog) - distributed;\n    }\n\n    if (distributed == maxSymbolValue+1) {\n        /* all values are pretty poor;\n           probably incompressible data (should have already been detected);\n           find max, then give all remaining points to max */\n        U32 maxV = 0, maxC = 0;\n        for (s=0; s<=maxSymbolValue; s++)\n            if (count[s] > maxC) { maxV=s; maxC=count[s]; }\n        norm[maxV] += (short)ToDistribute;\n        return 0;\n    }\n\n    if (total == 0) {\n        /* all of the symbols were low enough for the lowOne or lowThreshold */\n        for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1))\n            if (norm[s] > 0) { ToDistribute--; norm[s]++; }\n        return 0;\n    }\n\n    {   U64 const vStepLog = 62 - tableLog;\n        U64 const mid = (1ULL << (vStepLog-1)) - 1;\n        U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total;   /* scale on remaining */\n        U64 tmpTotal = mid;\n        for (s=0; s<=maxSymbolValue; s++) {\n            if (norm[s]==NOT_YET_ASSIGNED) {\n                U64 const end = tmpTotal + (count[s] * rStep);\n                U32 const sStart = (U32)(tmpTotal >> vStepLog);\n                U32 const sEnd = (U32)(end >> vStepLog);\n                U32 const weight = sEnd - sStart;\n                if (weight < 1)\n                    return ERROR(GENERIC);\n                norm[s] = (short)weight;\n                tmpTotal = end;\n    }   }   }\n\n    return 0;\n}\n\n\nsize_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,\n                           const unsigned* count, size_t total,\n                           unsigned maxSymbolValue)\n{\n    /* Sanity checks */\n    if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;\n    if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC);   /* Unsupported size */\n    if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);   /* Unsupported size */\n    if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC);   /* Too small tableLog, compression potentially impossible */\n\n    {   static U32 const rtbTable[] = {     0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };\n        U64 const scale = 62 - tableLog;\n        U64 const step = ((U64)1<<62) / total;   /* <== here, one division ! */\n        U64 const vStep = 1ULL<<(scale-20);\n        int stillToDistribute = 1<<tableLog;\n        unsigned s;\n        unsigned largest=0;\n        short largestP=0;\n        U32 lowThreshold = (U32)(total >> tableLog);\n\n        for (s=0; s<=maxSymbolValue; s++) {\n            if (count[s] == total) return 0;   /* rle special case */\n            if (count[s] == 0) { normalizedCounter[s]=0; continue; }\n            if (count[s] <= lowThreshold) {\n                normalizedCounter[s] = -1;\n                stillToDistribute--;\n            } else {\n                short proba = (short)((count[s]*step) >> scale);\n                if (proba<8) {\n                    U64 restToBeat = vStep * rtbTable[proba];\n                    proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;\n                }\n                if (proba > largestP) { largestP=proba; largest=s; }\n                normalizedCounter[s] = proba;\n                stillToDistribute -= proba;\n        }   }\n        if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {\n            /* corner case, need another normalization method */\n            size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);\n            if (FSE_isError(errorCode)) return errorCode;\n        }\n        else normalizedCounter[largest] += (short)stillToDistribute;\n    }\n\n#if 0\n    {   /* Print Table (debug) */\n        U32 s;\n        U32 nTotal = 0;\n        for (s=0; s<=maxSymbolValue; s++)\n            RAWLOG(2, \"%3i: %4i \\n\", s, normalizedCounter[s]);\n        for (s=0; s<=maxSymbolValue; s++)\n            nTotal += abs(normalizedCounter[s]);\n        if (nTotal != (1U<<tableLog))\n            RAWLOG(2, \"Warning !!! Total == %u != %u !!!\", nTotal, 1U<<tableLog);\n        getchar();\n    }\n#endif\n\n    return tableLog;\n}\n\n\n/* fake FSE_CTable, for raw (uncompressed) input */\nsize_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)\n{\n    const unsigned tableSize = 1 << nbBits;\n    const unsigned tableMask = tableSize - 1;\n    const unsigned maxSymbolValue = tableMask;\n    void* const ptr = ct;\n    U16* const tableU16 = ( (U16*) ptr) + 2;\n    void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableSize>>1);   /* assumption : tableLog >= 1 */\n    FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);\n    unsigned s;\n\n    /* Sanity checks */\n    if (nbBits < 1) return ERROR(GENERIC);             /* min size */\n\n    /* header */\n    tableU16[-2] = (U16) nbBits;\n    tableU16[-1] = (U16) maxSymbolValue;\n\n    /* Build table */\n    for (s=0; s<tableSize; s++)\n        tableU16[s] = (U16)(tableSize + s);\n\n    /* Build Symbol Transformation Table */\n    {   const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);\n        for (s=0; s<=maxSymbolValue; s++) {\n            symbolTT[s].deltaNbBits = deltaNbBits;\n            symbolTT[s].deltaFindState = s-1;\n    }   }\n\n    return 0;\n}\n\n/* fake FSE_CTable, for rle input (always same symbol) */\nsize_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)\n{\n    void* ptr = ct;\n    U16* tableU16 = ( (U16*) ptr) + 2;\n    void* FSCTptr = (U32*)ptr + 2;\n    FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) FSCTptr;\n\n    /* header */\n    tableU16[-2] = (U16) 0;\n    tableU16[-1] = (U16) symbolValue;\n\n    /* Build table */\n    tableU16[0] = 0;\n    tableU16[1] = 0;   /* just in case */\n\n    /* Build Symbol Transformation Table */\n    symbolTT[symbolValue].deltaNbBits = 0;\n    symbolTT[symbolValue].deltaFindState = 0;\n\n    return 0;\n}\n\n\nstatic size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,\n                           const void* src, size_t srcSize,\n                           const FSE_CTable* ct, const unsigned fast)\n{\n    const BYTE* const istart = (const BYTE*) src;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* ip=iend;\n\n    BIT_CStream_t bitC;\n    FSE_CState_t CState1, CState2;\n\n    /* init */\n    if (srcSize <= 2) return 0;\n    { size_t const initError = BIT_initCStream(&bitC, dst, dstSize);\n      if (FSE_isError(initError)) return 0; /* not enough space available to write a bitstream */ }\n\n#define FSE_FLUSHBITS(s)  (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))\n\n    if (srcSize & 1) {\n        FSE_initCState2(&CState1, ct, *--ip);\n        FSE_initCState2(&CState2, ct, *--ip);\n        FSE_encodeSymbol(&bitC, &CState1, *--ip);\n        FSE_FLUSHBITS(&bitC);\n    } else {\n        FSE_initCState2(&CState2, ct, *--ip);\n        FSE_initCState2(&CState1, ct, *--ip);\n    }\n\n    /* join to mod 4 */\n    srcSize -= 2;\n    if ((sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) {  /* test bit 2 */\n        FSE_encodeSymbol(&bitC, &CState2, *--ip);\n        FSE_encodeSymbol(&bitC, &CState1, *--ip);\n        FSE_FLUSHBITS(&bitC);\n    }\n\n    /* 2 or 4 encoding per loop */\n    while ( ip>istart ) {\n\n        FSE_encodeSymbol(&bitC, &CState2, *--ip);\n\n        if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 )   /* this test must be static */\n            FSE_FLUSHBITS(&bitC);\n\n        FSE_encodeSymbol(&bitC, &CState1, *--ip);\n\n        if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) {  /* this test must be static */\n            FSE_encodeSymbol(&bitC, &CState2, *--ip);\n            FSE_encodeSymbol(&bitC, &CState1, *--ip);\n        }\n\n        FSE_FLUSHBITS(&bitC);\n    }\n\n    FSE_flushCState(&bitC, &CState2);\n    FSE_flushCState(&bitC, &CState1);\n    return BIT_closeCStream(&bitC);\n}\n\nsize_t FSE_compress_usingCTable (void* dst, size_t dstSize,\n                           const void* src, size_t srcSize,\n                           const FSE_CTable* ct)\n{\n    unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize));\n\n    if (fast)\n        return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);\n    else\n        return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);\n}\n\n\nsize_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }\n\n#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e\n#define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }\n\n/* FSE_compress_wksp() :\n * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).\n * `wkspSize` size must be `(1<<tableLog)`.\n */\nsize_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)\n{\n    BYTE* const ostart = (BYTE*) dst;\n    BYTE* op = ostart;\n    BYTE* const oend = ostart + dstSize;\n\n    unsigned count[FSE_MAX_SYMBOL_VALUE+1];\n    S16   norm[FSE_MAX_SYMBOL_VALUE+1];\n    FSE_CTable* CTable = (FSE_CTable*)workSpace;\n    size_t const CTableSize = FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue);\n    void* scratchBuffer = (void*)(CTable + CTableSize);\n    size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable));\n\n    /* init conditions */\n    if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge);\n    if (srcSize <= 1) return 0;  /* Not compressible */\n    if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;\n    if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;\n\n    /* Scan input and build symbol stats */\n    {   CHECK_V_F(maxCount, HIST_count_wksp(count, &maxSymbolValue, src, srcSize, scratchBuffer, scratchBufferSize) );\n        if (maxCount == srcSize) return 1;   /* only a single symbol in src : rle */\n        if (maxCount == 1) return 0;         /* each symbol present maximum once => not compressible */\n        if (maxCount < (srcSize >> 7)) return 0;   /* Heuristic : not compressible enough */\n    }\n\n    tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);\n    CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );\n\n    /* Write table description header */\n    {   CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );\n        op += nc_err;\n    }\n\n    /* Compress */\n    CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );\n    {   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );\n        if (cSize == 0) return 0;   /* not enough space for compressed data */\n        op += cSize;\n    }\n\n    /* check compressibility */\n    if ( (size_t)(op-ostart) >= srcSize-1 ) return 0;\n\n    return op-ostart;\n}\n\ntypedef struct {\n    FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];\n    BYTE scratchBuffer[1 << FSE_MAX_TABLELOG];\n} fseWkspMax_t;\n\nsize_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)\n{\n    fseWkspMax_t scratchBuffer;\n    DEBUG_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE));   /* compilation failures here means scratchBuffer is not large enough */\n    if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);\n    return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer));\n}\n\nsize_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize)\n{\n    return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);\n}\n\n\n#endif   /* FSE_COMMONDEFS_ONLY */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/fse_decompress.c",
    "content": "/* ******************************************************************\n   FSE : Finite State Entropy decoder\n   Copyright (C) 2013-2015, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n    You can contact the author at :\n    - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy\n    - Public forum : https://groups.google.com/forum/#!forum/lz4c\n****************************************************************** */\n\n\n/* **************************************************************\n*  Includes\n****************************************************************/\n#include <stdlib.h>     /* malloc, free, qsort */\n#include <string.h>     /* memcpy, memset */\n#include \"bitstream.h\"\n#include \"compiler.h\"\n#define FSE_STATIC_LINKING_ONLY\n#include \"fse.h\"\n#include \"error_private.h\"\n\n\n/* **************************************************************\n*  Error Management\n****************************************************************/\n#define FSE_isError ERR_isError\n#define FSE_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)   /* use only *after* variable declarations */\n\n/* check and forward error code */\n#ifndef CHECK_F\n#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; }\n#endif\n\n\n/* **************************************************************\n*  Templates\n****************************************************************/\n/*\n  designed to be included\n  for type-specific functions (template emulation in C)\n  Objective is to write these functions only once, for improved maintenance\n*/\n\n/* safety checks */\n#ifndef FSE_FUNCTION_EXTENSION\n#  error \"FSE_FUNCTION_EXTENSION must be defined\"\n#endif\n#ifndef FSE_FUNCTION_TYPE\n#  error \"FSE_FUNCTION_TYPE must be defined\"\n#endif\n\n/* Function names */\n#define FSE_CAT(X,Y) X##Y\n#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)\n#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)\n\n\n/* Function templates */\nFSE_DTable* FSE_createDTable (unsigned tableLog)\n{\n    if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;\n    return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );\n}\n\nvoid FSE_freeDTable (FSE_DTable* dt)\n{\n    free(dt);\n}\n\nsize_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)\n{\n    void* const tdPtr = dt+1;   /* because *dt is unsigned, 32-bits aligned on 32-bits */\n    FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);\n    U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];\n\n    U32 const maxSV1 = maxSymbolValue + 1;\n    U32 const tableSize = 1 << tableLog;\n    U32 highThreshold = tableSize-1;\n\n    /* Sanity Checks */\n    if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);\n    if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);\n\n    /* Init, lay down lowprob symbols */\n    {   FSE_DTableHeader DTableH;\n        DTableH.tableLog = (U16)tableLog;\n        DTableH.fastMode = 1;\n        {   S16 const largeLimit= (S16)(1 << (tableLog-1));\n            U32 s;\n            for (s=0; s<maxSV1; s++) {\n                if (normalizedCounter[s]==-1) {\n                    tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;\n                    symbolNext[s] = 1;\n                } else {\n                    if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;\n                    symbolNext[s] = normalizedCounter[s];\n        }   }   }\n        memcpy(dt, &DTableH, sizeof(DTableH));\n    }\n\n    /* Spread symbols */\n    {   U32 const tableMask = tableSize-1;\n        U32 const step = FSE_TABLESTEP(tableSize);\n        U32 s, position = 0;\n        for (s=0; s<maxSV1; s++) {\n            int i;\n            for (i=0; i<normalizedCounter[s]; i++) {\n                tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;\n                position = (position + step) & tableMask;\n                while (position > highThreshold) position = (position + step) & tableMask;   /* lowprob area */\n        }   }\n        if (position!=0) return ERROR(GENERIC);   /* position must reach all cells once, otherwise normalizedCounter is incorrect */\n    }\n\n    /* Build Decoding table */\n    {   U32 u;\n        for (u=0; u<tableSize; u++) {\n            FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol);\n            U32 const nextState = symbolNext[symbol]++;\n            tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) );\n            tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);\n    }   }\n\n    return 0;\n}\n\n\n#ifndef FSE_COMMONDEFS_ONLY\n\n/*-*******************************************************\n*  Decompression (Byte symbols)\n*********************************************************/\nsize_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)\n{\n    void* ptr = dt;\n    FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;\n    void* dPtr = dt + 1;\n    FSE_decode_t* const cell = (FSE_decode_t*)dPtr;\n\n    DTableH->tableLog = 0;\n    DTableH->fastMode = 0;\n\n    cell->newState = 0;\n    cell->symbol = symbolValue;\n    cell->nbBits = 0;\n\n    return 0;\n}\n\n\nsize_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)\n{\n    void* ptr = dt;\n    FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;\n    void* dPtr = dt + 1;\n    FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;\n    const unsigned tableSize = 1 << nbBits;\n    const unsigned tableMask = tableSize - 1;\n    const unsigned maxSV1 = tableMask+1;\n    unsigned s;\n\n    /* Sanity checks */\n    if (nbBits < 1) return ERROR(GENERIC);         /* min size */\n\n    /* Build Decoding Table */\n    DTableH->tableLog = (U16)nbBits;\n    DTableH->fastMode = 1;\n    for (s=0; s<maxSV1; s++) {\n        dinfo[s].newState = 0;\n        dinfo[s].symbol = (BYTE)s;\n        dinfo[s].nbBits = (BYTE)nbBits;\n    }\n\n    return 0;\n}\n\nFORCE_INLINE_TEMPLATE size_t FSE_decompress_usingDTable_generic(\n          void* dst, size_t maxDstSize,\n    const void* cSrc, size_t cSrcSize,\n    const FSE_DTable* dt, const unsigned fast)\n{\n    BYTE* const ostart = (BYTE*) dst;\n    BYTE* op = ostart;\n    BYTE* const omax = op + maxDstSize;\n    BYTE* const olimit = omax-3;\n\n    BIT_DStream_t bitD;\n    FSE_DState_t state1;\n    FSE_DState_t state2;\n\n    /* Init */\n    CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize));\n\n    FSE_initDState(&state1, &bitD, dt);\n    FSE_initDState(&state2, &bitD, dt);\n\n#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)\n\n    /* 4 symbols per loop */\n    for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) & (op<olimit) ; op+=4) {\n        op[0] = FSE_GETSYMBOL(&state1);\n\n        if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */\n            BIT_reloadDStream(&bitD);\n\n        op[1] = FSE_GETSYMBOL(&state2);\n\n        if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */\n            { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }\n\n        op[2] = FSE_GETSYMBOL(&state1);\n\n        if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8)    /* This test must be static */\n            BIT_reloadDStream(&bitD);\n\n        op[3] = FSE_GETSYMBOL(&state2);\n    }\n\n    /* tail */\n    /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */\n    while (1) {\n        if (op>(omax-2)) return ERROR(dstSize_tooSmall);\n        *op++ = FSE_GETSYMBOL(&state1);\n        if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {\n            *op++ = FSE_GETSYMBOL(&state2);\n            break;\n        }\n\n        if (op>(omax-2)) return ERROR(dstSize_tooSmall);\n        *op++ = FSE_GETSYMBOL(&state2);\n        if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {\n            *op++ = FSE_GETSYMBOL(&state1);\n            break;\n    }   }\n\n    return op-ostart;\n}\n\n\nsize_t FSE_decompress_usingDTable(void* dst, size_t originalSize,\n                            const void* cSrc, size_t cSrcSize,\n                            const FSE_DTable* dt)\n{\n    const void* ptr = dt;\n    const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;\n    const U32 fastMode = DTableH->fastMode;\n\n    /* select fast mode (static) */\n    if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);\n    return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);\n}\n\n\nsize_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog)\n{\n    const BYTE* const istart = (const BYTE*)cSrc;\n    const BYTE* ip = istart;\n    short counting[FSE_MAX_SYMBOL_VALUE+1];\n    unsigned tableLog;\n    unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;\n\n    /* normal FSE decoding mode */\n    size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);\n    if (FSE_isError(NCountLength)) return NCountLength;\n    //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong);   /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */\n    if (tableLog > maxLog) return ERROR(tableLog_tooLarge);\n    ip += NCountLength;\n    cSrcSize -= NCountLength;\n\n    CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) );\n\n    return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace);   /* always return, even if it is an error code */\n}\n\n\ntypedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];\n\nsize_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize)\n{\n    DTable_max_t dt;   /* Static analyzer seems unable to understand this table will be properly initialized later */\n    return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG);\n}\n\n\n\n#endif   /* FSE_COMMONDEFS_ONLY */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/hist.c",
    "content": "/* ******************************************************************\n   hist : Histogram functions\n   part of Finite State Entropy project\n   Copyright (C) 2013-present, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n    You can contact the author at :\n    - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy\n    - Public forum : https://groups.google.com/forum/#!forum/lz4c\n****************************************************************** */\n\n/* --- dependencies --- */\n#include \"mem.h\"             /* U32, BYTE, etc. */\n#include \"debug.h\"           /* assert, DEBUGLOG */\n#include \"error_private.h\"   /* ERROR */\n#include \"hist.h\"\n\n\n/* --- Error management --- */\nunsigned HIST_isError(size_t code) { return ERR_isError(code); }\n\n/*-**************************************************************\n *  Histogram functions\n ****************************************************************/\nunsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,\n                           const void* src, size_t srcSize)\n{\n    const BYTE* ip = (const BYTE*)src;\n    const BYTE* const end = ip + srcSize;\n    unsigned maxSymbolValue = *maxSymbolValuePtr;\n    unsigned largestCount=0;\n\n    memset(count, 0, (maxSymbolValue+1) * sizeof(*count));\n    if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }\n\n    while (ip<end) {\n        assert(*ip <= maxSymbolValue);\n        count[*ip++]++;\n    }\n\n    while (!count[maxSymbolValue]) maxSymbolValue--;\n    *maxSymbolValuePtr = maxSymbolValue;\n\n    {   U32 s;\n        for (s=0; s<=maxSymbolValue; s++)\n            if (count[s] > largestCount) largestCount = count[s];\n    }\n\n    return largestCount;\n}\n\ntypedef enum { trustInput, checkMaxSymbolValue } HIST_checkInput_e;\n\n/* HIST_count_parallel_wksp() :\n * store histogram into 4 intermediate tables, recombined at the end.\n * this design makes better use of OoO cpus,\n * and is noticeably faster when some values are heavily repeated.\n * But it needs some additional workspace for intermediate tables.\n * `workSpace` size must be a table of size >= HIST_WKSP_SIZE_U32.\n * @return : largest histogram frequency,\n *           or an error code (notably when histogram would be larger than *maxSymbolValuePtr). */\nstatic size_t HIST_count_parallel_wksp(\n                                unsigned* count, unsigned* maxSymbolValuePtr,\n                                const void* source, size_t sourceSize,\n                                HIST_checkInput_e check,\n                                U32* const workSpace)\n{\n    const BYTE* ip = (const BYTE*)source;\n    const BYTE* const iend = ip+sourceSize;\n    unsigned maxSymbolValue = *maxSymbolValuePtr;\n    unsigned max=0;\n    U32* const Counting1 = workSpace;\n    U32* const Counting2 = Counting1 + 256;\n    U32* const Counting3 = Counting2 + 256;\n    U32* const Counting4 = Counting3 + 256;\n\n    memset(workSpace, 0, 4*256*sizeof(unsigned));\n\n    /* safety checks */\n    if (!sourceSize) {\n        memset(count, 0, maxSymbolValue + 1);\n        *maxSymbolValuePtr = 0;\n        return 0;\n    }\n    if (!maxSymbolValue) maxSymbolValue = 255;            /* 0 == default */\n\n    /* by stripes of 16 bytes */\n    {   U32 cached = MEM_read32(ip); ip += 4;\n        while (ip < iend-15) {\n            U32 c = cached; cached = MEM_read32(ip); ip += 4;\n            Counting1[(BYTE) c     ]++;\n            Counting2[(BYTE)(c>>8) ]++;\n            Counting3[(BYTE)(c>>16)]++;\n            Counting4[       c>>24 ]++;\n            c = cached; cached = MEM_read32(ip); ip += 4;\n            Counting1[(BYTE) c     ]++;\n            Counting2[(BYTE)(c>>8) ]++;\n            Counting3[(BYTE)(c>>16)]++;\n            Counting4[       c>>24 ]++;\n            c = cached; cached = MEM_read32(ip); ip += 4;\n            Counting1[(BYTE) c     ]++;\n            Counting2[(BYTE)(c>>8) ]++;\n            Counting3[(BYTE)(c>>16)]++;\n            Counting4[       c>>24 ]++;\n            c = cached; cached = MEM_read32(ip); ip += 4;\n            Counting1[(BYTE) c     ]++;\n            Counting2[(BYTE)(c>>8) ]++;\n            Counting3[(BYTE)(c>>16)]++;\n            Counting4[       c>>24 ]++;\n        }\n        ip-=4;\n    }\n\n    /* finish last symbols */\n    while (ip<iend) Counting1[*ip++]++;\n\n    if (check) {   /* verify stats will fit into destination table */\n        U32 s; for (s=255; s>maxSymbolValue; s--) {\n            Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];\n            if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);\n    }   }\n\n    {   U32 s;\n        if (maxSymbolValue > 255) maxSymbolValue = 255;\n        for (s=0; s<=maxSymbolValue; s++) {\n            count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];\n            if (count[s] > max) max = count[s];\n    }   }\n\n    while (!count[maxSymbolValue]) maxSymbolValue--;\n    *maxSymbolValuePtr = maxSymbolValue;\n    return (size_t)max;\n}\n\n/* HIST_countFast_wksp() :\n * Same as HIST_countFast(), but using an externally provided scratch buffer.\n * `workSpace` is a writable buffer which must be 4-bytes aligned,\n * `workSpaceSize` must be >= HIST_WKSP_SIZE\n */\nsize_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,\n                          const void* source, size_t sourceSize,\n                          void* workSpace, size_t workSpaceSize)\n{\n    if (sourceSize < 1500) /* heuristic threshold */\n        return HIST_count_simple(count, maxSymbolValuePtr, source, sourceSize);\n    if ((size_t)workSpace & 3) return ERROR(GENERIC);  /* must be aligned on 4-bytes boundaries */\n    if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);\n    return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, trustInput, (U32*)workSpace);\n}\n\n/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */\nsize_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,\n                     const void* source, size_t sourceSize)\n{\n    unsigned tmpCounters[HIST_WKSP_SIZE_U32];\n    return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters, sizeof(tmpCounters));\n}\n\n/* HIST_count_wksp() :\n * Same as HIST_count(), but using an externally provided scratch buffer.\n * `workSpace` size must be table of >= HIST_WKSP_SIZE_U32 unsigned */\nsize_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,\n                       const void* source, size_t sourceSize,\n                       void* workSpace, size_t workSpaceSize)\n{\n    if ((size_t)workSpace & 3) return ERROR(GENERIC);  /* must be aligned on 4-bytes boundaries */\n    if (workSpaceSize < HIST_WKSP_SIZE) return ERROR(workSpace_tooSmall);\n    if (*maxSymbolValuePtr < 255)\n        return HIST_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, checkMaxSymbolValue, (U32*)workSpace);\n    *maxSymbolValuePtr = 255;\n    return HIST_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace, workSpaceSize);\n}\n\nsize_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,\n                 const void* src, size_t srcSize)\n{\n    unsigned tmpCounters[HIST_WKSP_SIZE_U32];\n    return HIST_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters, sizeof(tmpCounters));\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/hist.h",
    "content": "/* ******************************************************************\n   hist : Histogram functions\n   part of Finite State Entropy project\n   Copyright (C) 2013-present, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n    You can contact the author at :\n    - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy\n    - Public forum : https://groups.google.com/forum/#!forum/lz4c\n****************************************************************** */\n\n/* --- dependencies --- */\n#include <stddef.h>   /* size_t */\n\n\n/* --- simple histogram functions --- */\n\n/*! HIST_count():\n *  Provides the precise count of each byte within a table 'count'.\n * 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).\n *  Updates *maxSymbolValuePtr with actual largest symbol value detected.\n * @return : count of the most frequent symbol (which isn't identified).\n *           or an error code, which can be tested using HIST_isError().\n *           note : if return == srcSize, there is only one symbol.\n */\nsize_t HIST_count(unsigned* count, unsigned* maxSymbolValuePtr,\n                  const void* src, size_t srcSize);\n\nunsigned HIST_isError(size_t code);  /**< tells if a return value is an error code */\n\n\n/* --- advanced histogram functions --- */\n\n#define HIST_WKSP_SIZE_U32 1024\n#define HIST_WKSP_SIZE    (HIST_WKSP_SIZE_U32 * sizeof(unsigned))\n/** HIST_count_wksp() :\n *  Same as HIST_count(), but using an externally provided scratch buffer.\n *  Benefit is this function will use very little stack space.\n * `workSpace` is a writable buffer which must be 4-bytes aligned,\n * `workSpaceSize` must be >= HIST_WKSP_SIZE\n */\nsize_t HIST_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,\n                       const void* src, size_t srcSize,\n                       void* workSpace, size_t workSpaceSize);\n\n/** HIST_countFast() :\n *  same as HIST_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr.\n *  This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr`\n */\nsize_t HIST_countFast(unsigned* count, unsigned* maxSymbolValuePtr,\n                      const void* src, size_t srcSize);\n\n/** HIST_countFast_wksp() :\n *  Same as HIST_countFast(), but using an externally provided scratch buffer.\n * `workSpace` is a writable buffer which must be 4-bytes aligned,\n * `workSpaceSize` must be >= HIST_WKSP_SIZE\n */\nsize_t HIST_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,\n                           const void* src, size_t srcSize,\n                           void* workSpace, size_t workSpaceSize);\n\n/*! HIST_count_simple() :\n *  Same as HIST_countFast(), this function is unsafe,\n *  and will segfault if any value within `src` is `> *maxSymbolValuePtr`.\n *  It is also a bit slower for large inputs.\n *  However, it does not need any additional memory (not even on stack).\n * @return : count of the most frequent symbol.\n *  Note this function doesn't produce any error (i.e. it must succeed).\n */\nunsigned HIST_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,\n                           const void* src, size_t srcSize);\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/huf.h",
    "content": "/* ******************************************************************\n   huff0 huffman codec,\n   part of Finite State Entropy library\n   Copyright (C) 2013-present, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n   You can contact the author at :\n   - Source repository : https://github.com/Cyan4973/FiniteStateEntropy\n****************************************************************** */\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#ifndef HUF_H_298734234\n#define HUF_H_298734234\n\n/* *** Dependencies *** */\n#include <stddef.h>    /* size_t */\n\n\n/* *** library symbols visibility *** */\n/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual,\n *        HUF symbols remain \"private\" (internal symbols for library only).\n *        Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */\n#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)\n#  define HUF_PUBLIC_API __attribute__ ((visibility (\"default\")))\n#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1)   /* Visual expected */\n#  define HUF_PUBLIC_API __declspec(dllexport)\n#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)\n#  define HUF_PUBLIC_API __declspec(dllimport)  /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */\n#else\n#  define HUF_PUBLIC_API\n#endif\n\n\n/* ========================== */\n/* ***  simple functions  *** */\n/* ========================== */\n\n/** HUF_compress() :\n *  Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'.\n * 'dst' buffer must be already allocated.\n *  Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize).\n * `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB.\n * @return : size of compressed data (<= `dstCapacity`).\n *  Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!\n *                   if HUF_isError(return), compression failed (more details using HUF_getErrorName())\n */\nHUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity,\n                             const void* src, size_t srcSize);\n\n/** HUF_decompress() :\n *  Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',\n *  into already allocated buffer 'dst', of minimum size 'dstSize'.\n * `originalSize` : **must** be the ***exact*** size of original (uncompressed) data.\n *  Note : in contrast with FSE, HUF_decompress can regenerate\n *         RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,\n *         because it knows size to regenerate (originalSize).\n * @return : size of regenerated data (== originalSize),\n *           or an error code, which can be tested using HUF_isError()\n */\nHUF_PUBLIC_API size_t HUF_decompress(void* dst,  size_t originalSize,\n                               const void* cSrc, size_t cSrcSize);\n\n\n/* ***   Tool functions *** */\n#define HUF_BLOCKSIZE_MAX (128 * 1024)                  /**< maximum input size for a single block compressed with HUF_compress */\nHUF_PUBLIC_API size_t HUF_compressBound(size_t size);   /**< maximum compressed size (worst case) */\n\n/* Error Management */\nHUF_PUBLIC_API unsigned    HUF_isError(size_t code);       /**< tells if a return value is an error code */\nHUF_PUBLIC_API const char* HUF_getErrorName(size_t code);  /**< provides error code string (useful for debugging) */\n\n\n/* ***   Advanced function   *** */\n\n/** HUF_compress2() :\n *  Same as HUF_compress(), but offers control over `maxSymbolValue` and `tableLog`.\n * `maxSymbolValue` must be <= HUF_SYMBOLVALUE_MAX .\n * `tableLog` must be `<= HUF_TABLELOG_MAX` . */\nHUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity,\n                               const void* src, size_t srcSize,\n                               unsigned maxSymbolValue, unsigned tableLog);\n\n/** HUF_compress4X_wksp() :\n *  Same as HUF_compress2(), but uses externally allocated `workSpace`.\n * `workspace` must have minimum alignment of 4, and be at least as large as HUF_WORKSPACE_SIZE */\n#define HUF_WORKSPACE_SIZE (6 << 10)\n#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))\nHUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity,\n                                     const void* src, size_t srcSize,\n                                     unsigned maxSymbolValue, unsigned tableLog,\n                                     void* workSpace, size_t wkspSize);\n\n#endif   /* HUF_H_298734234 */\n\n/* ******************************************************************\n *  WARNING !!\n *  The following section contains advanced and experimental definitions\n *  which shall never be used in the context of a dynamic library,\n *  because they are not guaranteed to remain stable in the future.\n *  Only consider them in association with static linking.\n * *****************************************************************/\n#if defined(HUF_STATIC_LINKING_ONLY) && !defined(HUF_H_HUF_STATIC_LINKING_ONLY)\n#define HUF_H_HUF_STATIC_LINKING_ONLY\n\n/* *** Dependencies *** */\n#include \"mem.h\"   /* U32 */\n\n\n/* *** Constants *** */\n#define HUF_TABLELOG_MAX      12      /* max runtime value of tableLog (due to static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */\n#define HUF_TABLELOG_DEFAULT  11      /* default tableLog value when none specified */\n#define HUF_SYMBOLVALUE_MAX  255\n\n#define HUF_TABLELOG_ABSOLUTEMAX  15  /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */\n#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)\n#  error \"HUF_TABLELOG_MAX is too large !\"\n#endif\n\n\n/* ****************************************\n*  Static allocation\n******************************************/\n/* HUF buffer bounds */\n#define HUF_CTABLEBOUND 129\n#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8)   /* only true when incompressible is pre-filtered with fast heuristic */\n#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size))   /* Macro version, useful for static allocation */\n\n/* static allocation of HUF's Compression Table */\n#define HUF_CTABLE_SIZE_U32(maxSymbolValue)   ((maxSymbolValue)+1)   /* Use tables of U32, for proper alignment */\n#define HUF_CTABLE_SIZE(maxSymbolValue)       (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32))\n#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \\\n    U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \\\n    void* name##hv = &(name##hb); \\\n    HUF_CElt* name = (HUF_CElt*)(name##hv)   /* no final ; */\n\n/* static allocation of HUF's DTable */\ntypedef U32 HUF_DTable;\n#define HUF_DTABLE_SIZE(maxTableLog)   (1 + (1<<(maxTableLog)))\n#define HUF_CREATE_STATIC_DTABLEX1(DTable, maxTableLog) \\\n        HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) }\n#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \\\n        HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }\n\n\n/* ****************************************\n*  Advanced decompression functions\n******************************************/\nsize_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */\n#ifndef HUF_FORCE_DECOMPRESS_X1\nsize_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */\n#endif\n\nsize_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< decodes RLE and uncompressed */\nsize_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */\nsize_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize); /**< considers RLE and uncompressed as errors */\nsize_t HUF_decompress4X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */\nsize_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);   /**< single-symbol decoder */\n#ifndef HUF_FORCE_DECOMPRESS_X1\nsize_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */\nsize_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);   /**< double-symbols decoder */\n#endif\n\n\n/* ****************************************\n *  HUF detailed API\n * ****************************************/\n\n/*! HUF_compress() does the following:\n *  1. count symbol occurrence from source[] into table count[] using FSE_count() (exposed within \"fse.h\")\n *  2. (optional) refine tableLog using HUF_optimalTableLog()\n *  3. build Huffman table from count using HUF_buildCTable()\n *  4. save Huffman table to memory buffer using HUF_writeCTable()\n *  5. encode the data stream using HUF_compress4X_usingCTable()\n *\n *  The following API allows targeting specific sub-functions for advanced tasks.\n *  For example, it's possible to compress several blocks using the same 'CTable',\n *  or to save and regenerate 'CTable' using external methods.\n */\nunsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);\ntypedef struct HUF_CElt_s HUF_CElt;   /* incomplete type */\nsize_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits);   /* @return : maxNbBits; CTable and count can overlap. In which case, CTable will overwrite count content */\nsize_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);\nsize_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);\n\ntypedef enum {\n   HUF_repeat_none,  /**< Cannot use the previous table */\n   HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */\n   HUF_repeat_valid  /**< Can use the previous table and it is assumed to be valid */\n } HUF_repeat;\n/** HUF_compress4X_repeat() :\n *  Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.\n *  If it uses hufTable it does not modify hufTable or repeat.\n *  If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.\n *  If preferRepeat then the old table will always be used if valid. */\nsize_t HUF_compress4X_repeat(void* dst, size_t dstSize,\n                       const void* src, size_t srcSize,\n                       unsigned maxSymbolValue, unsigned tableLog,\n                       void* workSpace, size_t wkspSize,    /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */\n                       HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2);\n\n/** HUF_buildCTable_wksp() :\n *  Same as HUF_buildCTable(), but using externally allocated scratch buffer.\n * `workSpace` must be aligned on 4-bytes boundaries, and its size must be >= HUF_CTABLE_WORKSPACE_SIZE.\n */\n#define HUF_CTABLE_WORKSPACE_SIZE_U32 (2*HUF_SYMBOLVALUE_MAX +1 +1)\n#define HUF_CTABLE_WORKSPACE_SIZE (HUF_CTABLE_WORKSPACE_SIZE_U32 * sizeof(unsigned))\nsize_t HUF_buildCTable_wksp (HUF_CElt* tree,\n                       const unsigned* count, U32 maxSymbolValue, U32 maxNbBits,\n                             void* workSpace, size_t wkspSize);\n\n/*! HUF_readStats() :\n *  Read compact Huffman tree, saved by HUF_writeCTable().\n * `huffWeight` is destination buffer.\n * @return : size read from `src` , or an error Code .\n *  Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */\nsize_t HUF_readStats(BYTE* huffWeight, size_t hwSize,\n                     U32* rankStats, U32* nbSymbolsPtr, U32* tableLogPtr,\n                     const void* src, size_t srcSize);\n\n/** HUF_readCTable() :\n *  Loading a CTable saved with HUF_writeCTable() */\nsize_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);\n\n/** HUF_getNbBits() :\n *  Read nbBits from CTable symbolTable, for symbol `symbolValue` presumed <= HUF_SYMBOLVALUE_MAX\n *  Note 1 : is not inlined, as HUF_CElt definition is private\n *  Note 2 : const void* used, so that it can provide a statically allocated table as argument (which uses type U32) */\nU32 HUF_getNbBits(const void* symbolTable, U32 symbolValue);\n\n/*\n * HUF_decompress() does the following:\n * 1. select the decompression algorithm (X1, X2) based on pre-computed heuristics\n * 2. build Huffman table from save, using HUF_readDTableX?()\n * 3. decode 1 or 4 segments in parallel using HUF_decompress?X?_usingDTable()\n */\n\n/** HUF_selectDecoder() :\n *  Tells which decoder is likely to decode faster,\n *  based on a set of pre-computed metrics.\n * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 .\n *  Assumption : 0 < dstSize <= 128 KB */\nU32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);\n\n/**\n *  The minimum workspace size for the `workSpace` used in\n *  HUF_readDTableX1_wksp() and HUF_readDTableX2_wksp().\n *\n *  The space used depends on HUF_TABLELOG_MAX, ranging from ~1500 bytes when\n *  HUF_TABLE_LOG_MAX=12 to ~1850 bytes when HUF_TABLE_LOG_MAX=15.\n *  Buffer overflow errors may potentially occur if code modifications result in\n *  a required workspace size greater than that specified in the following\n *  macro.\n */\n#define HUF_DECOMPRESS_WORKSPACE_SIZE (2 << 10)\n#define HUF_DECOMPRESS_WORKSPACE_SIZE_U32 (HUF_DECOMPRESS_WORKSPACE_SIZE / sizeof(U32))\n\n#ifndef HUF_FORCE_DECOMPRESS_X2\nsize_t HUF_readDTableX1 (HUF_DTable* DTable, const void* src, size_t srcSize);\nsize_t HUF_readDTableX1_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize);\n#endif\n#ifndef HUF_FORCE_DECOMPRESS_X1\nsize_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize);\nsize_t HUF_readDTableX2_wksp (HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize);\n#endif\n\nsize_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);\n#ifndef HUF_FORCE_DECOMPRESS_X2\nsize_t HUF_decompress4X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);\n#endif\n#ifndef HUF_FORCE_DECOMPRESS_X1\nsize_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);\n#endif\n\n\n/* ====================== */\n/* single stream variants */\n/* ====================== */\n\nsize_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);\nsize_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);  /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */\nsize_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);\n/** HUF_compress1X_repeat() :\n *  Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.\n *  If it uses hufTable it does not modify hufTable or repeat.\n *  If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.\n *  If preferRepeat then the old table will always be used if valid. */\nsize_t HUF_compress1X_repeat(void* dst, size_t dstSize,\n                       const void* src, size_t srcSize,\n                       unsigned maxSymbolValue, unsigned tableLog,\n                       void* workSpace, size_t wkspSize,   /**< `workSpace` must be aligned on 4-bytes boundaries, `wkspSize` must be >= HUF_WORKSPACE_SIZE */\n                       HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2);\n\nsize_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /* single-symbol decoder */\n#ifndef HUF_FORCE_DECOMPRESS_X1\nsize_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /* double-symbol decoder */\n#endif\n\nsize_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);\nsize_t HUF_decompress1X_DCtx_wksp (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);\n#ifndef HUF_FORCE_DECOMPRESS_X2\nsize_t HUF_decompress1X1_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< single-symbol decoder */\nsize_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);   /**< single-symbol decoder */\n#endif\n#ifndef HUF_FORCE_DECOMPRESS_X1\nsize_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);   /**< double-symbols decoder */\nsize_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize);   /**< double-symbols decoder */\n#endif\n\nsize_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);   /**< automatic selection of sing or double symbol decoder, based on DTable */\n#ifndef HUF_FORCE_DECOMPRESS_X2\nsize_t HUF_decompress1X1_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);\n#endif\n#ifndef HUF_FORCE_DECOMPRESS_X1\nsize_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);\n#endif\n\n/* BMI2 variants.\n * If the CPU has BMI2 support, pass bmi2=1, otherwise pass bmi2=0.\n */\nsize_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);\n#ifndef HUF_FORCE_DECOMPRESS_X2\nsize_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);\n#endif\nsize_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2);\nsize_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2);\n\n#endif /* HUF_STATIC_LINKING_ONLY */\n\n#if defined (__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/huf_compress.c",
    "content": "/* ******************************************************************\n   Huffman encoder, part of New Generation Entropy library\n   Copyright (C) 2013-2016, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n    You can contact the author at :\n    - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy\n    - Public forum : https://groups.google.com/forum/#!forum/lz4c\n****************************************************************** */\n\n/* **************************************************************\n*  Compiler specifics\n****************************************************************/\n#ifdef _MSC_VER    /* Visual Studio */\n#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */\n#endif\n\n\n/* **************************************************************\n*  Includes\n****************************************************************/\n#include <string.h>     /* memcpy, memset */\n#include <stdio.h>      /* printf (debug) */\n#include \"compiler.h\"\n#include \"bitstream.h\"\n#include \"hist.h\"\n#define FSE_STATIC_LINKING_ONLY   /* FSE_optimalTableLog_internal */\n#include \"fse.h\"        /* header compression */\n#define HUF_STATIC_LINKING_ONLY\n#include \"huf.h\"\n#include \"error_private.h\"\n\n\n/* **************************************************************\n*  Error Management\n****************************************************************/\n#define HUF_isError ERR_isError\n#define HUF_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)   /* use only *after* variable declarations */\n#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return e\n#define CHECK_F(f)   { CHECK_V_F(_var_err__, f); }\n\n\n/* **************************************************************\n*  Utils\n****************************************************************/\nunsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)\n{\n    return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);\n}\n\n\n/* *******************************************************\n*  HUF : Huffman block compression\n*********************************************************/\n/* HUF_compressWeights() :\n * Same as FSE_compress(), but dedicated to huff0's weights compression.\n * The use case needs much less stack memory.\n * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.\n */\n#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6\nstatic size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)\n{\n    BYTE* const ostart = (BYTE*) dst;\n    BYTE* op = ostart;\n    BYTE* const oend = ostart + dstSize;\n\n    unsigned maxSymbolValue = HUF_TABLELOG_MAX;\n    U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;\n\n    FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];\n    BYTE scratchBuffer[1<<MAX_FSE_TABLELOG_FOR_HUFF_HEADER];\n\n    unsigned count[HUF_TABLELOG_MAX+1];\n    S16 norm[HUF_TABLELOG_MAX+1];\n\n    /* init conditions */\n    if (wtSize <= 1) return 0;  /* Not compressible */\n\n    /* Scan input and build symbol stats */\n    {   unsigned const maxCount = HIST_count_simple(count, &maxSymbolValue, weightTable, wtSize);   /* never fails */\n        if (maxCount == wtSize) return 1;   /* only a single symbol in src : rle */\n        if (maxCount == 1) return 0;        /* each symbol present maximum once => not compressible */\n    }\n\n    tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);\n    CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );\n\n    /* Write table description header */\n    {   CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );\n        op += hSize;\n    }\n\n    /* Compress */\n    CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );\n    {   CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );\n        if (cSize == 0) return 0;   /* not enough space for compressed data */\n        op += cSize;\n    }\n\n    return op-ostart;\n}\n\n\nstruct HUF_CElt_s {\n  U16  val;\n  BYTE nbBits;\n};   /* typedef'd to HUF_CElt within \"huf.h\" */\n\n/*! HUF_writeCTable() :\n    `CTable` : Huffman tree to save, using huf representation.\n    @return : size of saved CTable */\nsize_t HUF_writeCTable (void* dst, size_t maxDstSize,\n                        const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog)\n{\n    BYTE bitsToWeight[HUF_TABLELOG_MAX + 1];   /* precomputed conversion table */\n    BYTE huffWeight[HUF_SYMBOLVALUE_MAX];\n    BYTE* op = (BYTE*)dst;\n    U32 n;\n\n     /* check conditions */\n    if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);\n\n    /* convert to weight */\n    bitsToWeight[0] = 0;\n    for (n=1; n<huffLog+1; n++)\n        bitsToWeight[n] = (BYTE)(huffLog + 1 - n);\n    for (n=0; n<maxSymbolValue; n++)\n        huffWeight[n] = bitsToWeight[CTable[n].nbBits];\n\n    /* attempt weights compression by FSE */\n    {   CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) );\n        if ((hSize>1) & (hSize < maxSymbolValue/2)) {   /* FSE compressed */\n            op[0] = (BYTE)hSize;\n            return hSize+1;\n    }   }\n\n    /* write raw values as 4-bits (max : 15) */\n    if (maxSymbolValue > (256-128)) return ERROR(GENERIC);   /* should not happen : likely means source cannot be compressed */\n    if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall);   /* not enough space within dst buffer */\n    op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));\n    huffWeight[maxSymbolValue] = 0;   /* to be sure it doesn't cause msan issue in final combination */\n    for (n=0; n<maxSymbolValue; n+=2)\n        op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);\n    return ((maxSymbolValue+1)/2) + 1;\n}\n\n\nsize_t HUF_readCTable (HUF_CElt* CTable, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize)\n{\n    BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];   /* init not required, even though some static analyzer may complain */\n    U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1];   /* large enough for values from 0 to 16 */\n    U32 tableLog = 0;\n    U32 nbSymbols = 0;\n\n    /* get symbol weights */\n    CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize));\n\n    /* check result */\n    if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);\n    if (nbSymbols > *maxSymbolValuePtr+1) return ERROR(maxSymbolValue_tooSmall);\n\n    /* Prepare base value per rank */\n    {   U32 n, nextRankStart = 0;\n        for (n=1; n<=tableLog; n++) {\n            U32 current = nextRankStart;\n            nextRankStart += (rankVal[n] << (n-1));\n            rankVal[n] = current;\n    }   }\n\n    /* fill nbBits */\n    {   U32 n; for (n=0; n<nbSymbols; n++) {\n            const U32 w = huffWeight[n];\n            CTable[n].nbBits = (BYTE)(tableLog + 1 - w);\n    }   }\n\n    /* fill val */\n    {   U16 nbPerRank[HUF_TABLELOG_MAX+2]  = {0};  /* support w=0=>n=tableLog+1 */\n        U16 valPerRank[HUF_TABLELOG_MAX+2] = {0};\n        { U32 n; for (n=0; n<nbSymbols; n++) nbPerRank[CTable[n].nbBits]++; }\n        /* determine stating value per rank */\n        valPerRank[tableLog+1] = 0;   /* for w==0 */\n        {   U16 min = 0;\n            U32 n; for (n=tableLog; n>0; n--) {  /* start at n=tablelog <-> w=1 */\n                valPerRank[n] = min;     /* get starting value within each rank */\n                min += nbPerRank[n];\n                min >>= 1;\n        }   }\n        /* assign value within rank, symbol order */\n        { U32 n; for (n=0; n<nbSymbols; n++) CTable[n].val = valPerRank[CTable[n].nbBits]++; }\n    }\n\n    *maxSymbolValuePtr = nbSymbols - 1;\n    return readSize;\n}\n\nU32 HUF_getNbBits(const void* symbolTable, U32 symbolValue)\n{\n    const HUF_CElt* table = (const HUF_CElt*)symbolTable;\n    assert(symbolValue <= HUF_SYMBOLVALUE_MAX);\n    return table[symbolValue].nbBits;\n}\n\n\ntypedef struct nodeElt_s {\n    U32 count;\n    U16 parent;\n    BYTE byte;\n    BYTE nbBits;\n} nodeElt;\n\nstatic U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)\n{\n    const U32 largestBits = huffNode[lastNonNull].nbBits;\n    if (largestBits <= maxNbBits) return largestBits;   /* early exit : no elt > maxNbBits */\n\n    /* there are several too large elements (at least >= 2) */\n    {   int totalCost = 0;\n        const U32 baseCost = 1 << (largestBits - maxNbBits);\n        U32 n = lastNonNull;\n\n        while (huffNode[n].nbBits > maxNbBits) {\n            totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));\n            huffNode[n].nbBits = (BYTE)maxNbBits;\n            n --;\n        }  /* n stops at huffNode[n].nbBits <= maxNbBits */\n        while (huffNode[n].nbBits == maxNbBits) n--;   /* n end at index of smallest symbol using < maxNbBits */\n\n        /* renorm totalCost */\n        totalCost >>= (largestBits - maxNbBits);  /* note : totalCost is necessarily a multiple of baseCost */\n\n        /* repay normalized cost */\n        {   U32 const noSymbol = 0xF0F0F0F0;\n            U32 rankLast[HUF_TABLELOG_MAX+2];\n            int pos;\n\n            /* Get pos of last (smallest) symbol per rank */\n            memset(rankLast, 0xF0, sizeof(rankLast));\n            {   U32 currentNbBits = maxNbBits;\n                for (pos=n ; pos >= 0; pos--) {\n                    if (huffNode[pos].nbBits >= currentNbBits) continue;\n                    currentNbBits = huffNode[pos].nbBits;   /* < maxNbBits */\n                    rankLast[maxNbBits-currentNbBits] = pos;\n            }   }\n\n            while (totalCost > 0) {\n                U32 nBitsToDecrease = BIT_highbit32(totalCost) + 1;\n                for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {\n                    U32 highPos = rankLast[nBitsToDecrease];\n                    U32 lowPos = rankLast[nBitsToDecrease-1];\n                    if (highPos == noSymbol) continue;\n                    if (lowPos == noSymbol) break;\n                    {   U32 const highTotal = huffNode[highPos].count;\n                        U32 const lowTotal = 2 * huffNode[lowPos].count;\n                        if (highTotal <= lowTotal) break;\n                }   }\n                /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */\n                /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */\n                while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))\n                    nBitsToDecrease ++;\n                totalCost -= 1 << (nBitsToDecrease-1);\n                if (rankLast[nBitsToDecrease-1] == noSymbol)\n                    rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease];   /* this rank is no longer empty */\n                huffNode[rankLast[nBitsToDecrease]].nbBits ++;\n                if (rankLast[nBitsToDecrease] == 0)    /* special case, reached largest symbol */\n                    rankLast[nBitsToDecrease] = noSymbol;\n                else {\n                    rankLast[nBitsToDecrease]--;\n                    if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)\n                        rankLast[nBitsToDecrease] = noSymbol;   /* this rank is now empty */\n            }   }   /* while (totalCost > 0) */\n\n            while (totalCost < 0) {  /* Sometimes, cost correction overshoot */\n                if (rankLast[1] == noSymbol) {  /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */\n                    while (huffNode[n].nbBits == maxNbBits) n--;\n                    huffNode[n+1].nbBits--;\n                    rankLast[1] = n+1;\n                    totalCost++;\n                    continue;\n                }\n                huffNode[ rankLast[1] + 1 ].nbBits--;\n                rankLast[1]++;\n                totalCost ++;\n    }   }   }   /* there are several too large elements (at least >= 2) */\n\n    return maxNbBits;\n}\n\n\ntypedef struct {\n    U32 base;\n    U32 current;\n} rankPos;\n\nstatic void HUF_sort(nodeElt* huffNode, const unsigned* count, U32 maxSymbolValue)\n{\n    rankPos rank[32];\n    U32 n;\n\n    memset(rank, 0, sizeof(rank));\n    for (n=0; n<=maxSymbolValue; n++) {\n        U32 r = BIT_highbit32(count[n] + 1);\n        rank[r].base ++;\n    }\n    for (n=30; n>0; n--) rank[n-1].base += rank[n].base;\n    for (n=0; n<32; n++) rank[n].current = rank[n].base;\n    for (n=0; n<=maxSymbolValue; n++) {\n        U32 const c = count[n];\n        U32 const r = BIT_highbit32(c+1) + 1;\n        U32 pos = rank[r].current++;\n        while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) {\n            huffNode[pos] = huffNode[pos-1];\n            pos--;\n        }\n        huffNode[pos].count = c;\n        huffNode[pos].byte  = (BYTE)n;\n    }\n}\n\n\n/** HUF_buildCTable_wksp() :\n *  Same as HUF_buildCTable(), but using externally allocated scratch buffer.\n *  `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of HUF_CTABLE_WORKSPACE_SIZE_U32 unsigned.\n */\n#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)\ntypedef nodeElt huffNodeTable[HUF_CTABLE_WORKSPACE_SIZE_U32];\nsize_t HUF_buildCTable_wksp (HUF_CElt* tree, const unsigned* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)\n{\n    nodeElt* const huffNode0 = (nodeElt*)workSpace;\n    nodeElt* const huffNode = huffNode0+1;\n    U32 n, nonNullRank;\n    int lowS, lowN;\n    U16 nodeNb = STARTNODE;\n    U32 nodeRoot;\n\n    /* safety checks */\n    if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC);  /* must be aligned on 4-bytes boundaries */\n    if (wkspSize < sizeof(huffNodeTable)) return ERROR(workSpace_tooSmall);\n    if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;\n    if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);\n    memset(huffNode0, 0, sizeof(huffNodeTable));\n\n    /* sort, decreasing order */\n    HUF_sort(huffNode, count, maxSymbolValue);\n\n    /* init for parents */\n    nonNullRank = maxSymbolValue;\n    while(huffNode[nonNullRank].count == 0) nonNullRank--;\n    lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb;\n    huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count;\n    huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;\n    nodeNb++; lowS-=2;\n    for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);\n    huffNode0[0].count = (U32)(1U<<31);  /* fake entry, strong barrier */\n\n    /* create parents */\n    while (nodeNb <= nodeRoot) {\n        U32 n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;\n        U32 n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;\n        huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count;\n        huffNode[n1].parent = huffNode[n2].parent = nodeNb;\n        nodeNb++;\n    }\n\n    /* distribute weights (unlimited tree height) */\n    huffNode[nodeRoot].nbBits = 0;\n    for (n=nodeRoot-1; n>=STARTNODE; n--)\n        huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;\n    for (n=0; n<=nonNullRank; n++)\n        huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;\n\n    /* enforce maxTableLog */\n    maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);\n\n    /* fill result into tree (val, nbBits) */\n    {   U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};\n        U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};\n        if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC);   /* check fit into table */\n        for (n=0; n<=nonNullRank; n++)\n            nbPerRank[huffNode[n].nbBits]++;\n        /* determine stating value per rank */\n        {   U16 min = 0;\n            for (n=maxNbBits; n>0; n--) {\n                valPerRank[n] = min;      /* get starting value within each rank */\n                min += nbPerRank[n];\n                min >>= 1;\n        }   }\n        for (n=0; n<=maxSymbolValue; n++)\n            tree[huffNode[n].byte].nbBits = huffNode[n].nbBits;   /* push nbBits per symbol, symbol order */\n        for (n=0; n<=maxSymbolValue; n++)\n            tree[n].val = valPerRank[tree[n].nbBits]++;   /* assign value within rank, symbol order */\n    }\n\n    return maxNbBits;\n}\n\n/** HUF_buildCTable() :\n * @return : maxNbBits\n *  Note : count is used before tree is written, so they can safely overlap\n */\nsize_t HUF_buildCTable (HUF_CElt* tree, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits)\n{\n    huffNodeTable nodeTable;\n    return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, nodeTable, sizeof(nodeTable));\n}\n\nstatic size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)\n{\n    size_t nbBits = 0;\n    int s;\n    for (s = 0; s <= (int)maxSymbolValue; ++s) {\n        nbBits += CTable[s].nbBits * count[s];\n    }\n    return nbBits >> 3;\n}\n\nstatic int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) {\n  int bad = 0;\n  int s;\n  for (s = 0; s <= (int)maxSymbolValue; ++s) {\n    bad |= (count[s] != 0) & (CTable[s].nbBits == 0);\n  }\n  return !bad;\n}\n\nsize_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }\n\nFORCE_INLINE_TEMPLATE void\nHUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)\n{\n    BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);\n}\n\n#define HUF_FLUSHBITS(s)  BIT_flushBits(s)\n\n#define HUF_FLUSHBITS_1(stream) \\\n    if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*2+7) HUF_FLUSHBITS(stream)\n\n#define HUF_FLUSHBITS_2(stream) \\\n    if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream)\n\nFORCE_INLINE_TEMPLATE size_t\nHUF_compress1X_usingCTable_internal_body(void* dst, size_t dstSize,\n                                   const void* src, size_t srcSize,\n                                   const HUF_CElt* CTable)\n{\n    const BYTE* ip = (const BYTE*) src;\n    BYTE* const ostart = (BYTE*)dst;\n    BYTE* const oend = ostart + dstSize;\n    BYTE* op = ostart;\n    size_t n;\n    BIT_CStream_t bitC;\n\n    /* init */\n    if (dstSize < 8) return 0;   /* not enough space to compress */\n    { size_t const initErr = BIT_initCStream(&bitC, op, oend-op);\n      if (HUF_isError(initErr)) return 0; }\n\n    n = srcSize & ~3;  /* join to mod 4 */\n    switch (srcSize & 3)\n    {\n        case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);\n                 HUF_FLUSHBITS_2(&bitC);\n\t\t /* fall-through */\n        case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);\n                 HUF_FLUSHBITS_1(&bitC);\n\t\t /* fall-through */\n        case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);\n                 HUF_FLUSHBITS(&bitC);\n\t\t /* fall-through */\n        case 0 : /* fall-through */\n        default: break;\n    }\n\n    for (; n>0; n-=4) {  /* note : n&3==0 at this stage */\n        HUF_encodeSymbol(&bitC, ip[n- 1], CTable);\n        HUF_FLUSHBITS_1(&bitC);\n        HUF_encodeSymbol(&bitC, ip[n- 2], CTable);\n        HUF_FLUSHBITS_2(&bitC);\n        HUF_encodeSymbol(&bitC, ip[n- 3], CTable);\n        HUF_FLUSHBITS_1(&bitC);\n        HUF_encodeSymbol(&bitC, ip[n- 4], CTable);\n        HUF_FLUSHBITS(&bitC);\n    }\n\n    return BIT_closeCStream(&bitC);\n}\n\n#if DYNAMIC_BMI2\n\nstatic TARGET_ATTRIBUTE(\"bmi2\") size_t\nHUF_compress1X_usingCTable_internal_bmi2(void* dst, size_t dstSize,\n                                   const void* src, size_t srcSize,\n                                   const HUF_CElt* CTable)\n{\n    return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);\n}\n\nstatic size_t\nHUF_compress1X_usingCTable_internal_default(void* dst, size_t dstSize,\n                                      const void* src, size_t srcSize,\n                                      const HUF_CElt* CTable)\n{\n    return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);\n}\n\nstatic size_t\nHUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,\n                              const void* src, size_t srcSize,\n                              const HUF_CElt* CTable, const int bmi2)\n{\n    if (bmi2) {\n        return HUF_compress1X_usingCTable_internal_bmi2(dst, dstSize, src, srcSize, CTable);\n    }\n    return HUF_compress1X_usingCTable_internal_default(dst, dstSize, src, srcSize, CTable);\n}\n\n#else\n\nstatic size_t\nHUF_compress1X_usingCTable_internal(void* dst, size_t dstSize,\n                              const void* src, size_t srcSize,\n                              const HUF_CElt* CTable, const int bmi2)\n{\n    (void)bmi2;\n    return HUF_compress1X_usingCTable_internal_body(dst, dstSize, src, srcSize, CTable);\n}\n\n#endif\n\nsize_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)\n{\n    return HUF_compress1X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);\n}\n\n\nstatic size_t\nHUF_compress4X_usingCTable_internal(void* dst, size_t dstSize,\n                              const void* src, size_t srcSize,\n                              const HUF_CElt* CTable, int bmi2)\n{\n    size_t const segmentSize = (srcSize+3)/4;   /* first 3 segments */\n    const BYTE* ip = (const BYTE*) src;\n    const BYTE* const iend = ip + srcSize;\n    BYTE* const ostart = (BYTE*) dst;\n    BYTE* const oend = ostart + dstSize;\n    BYTE* op = ostart;\n\n    if (dstSize < 6 + 1 + 1 + 1 + 8) return 0;   /* minimum space to compress successfully */\n    if (srcSize < 12) return 0;   /* no saving possible : too small input */\n    op += 6;   /* jumpTable */\n\n    {   CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );\n        if (cSize==0) return 0;\n        assert(cSize <= 65535);\n        MEM_writeLE16(ostart, (U16)cSize);\n        op += cSize;\n    }\n\n    ip += segmentSize;\n    {   CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );\n        if (cSize==0) return 0;\n        assert(cSize <= 65535);\n        MEM_writeLE16(ostart+2, (U16)cSize);\n        op += cSize;\n    }\n\n    ip += segmentSize;\n    {   CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, segmentSize, CTable, bmi2) );\n        if (cSize==0) return 0;\n        assert(cSize <= 65535);\n        MEM_writeLE16(ostart+4, (U16)cSize);\n        op += cSize;\n    }\n\n    ip += segmentSize;\n    {   CHECK_V_F(cSize, HUF_compress1X_usingCTable_internal(op, oend-op, ip, iend-ip, CTable, bmi2) );\n        if (cSize==0) return 0;\n        op += cSize;\n    }\n\n    return op-ostart;\n}\n\nsize_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)\n{\n    return HUF_compress4X_usingCTable_internal(dst, dstSize, src, srcSize, CTable, /* bmi2 */ 0);\n}\n\ntypedef enum { HUF_singleStream, HUF_fourStreams } HUF_nbStreams_e;\n\nstatic size_t HUF_compressCTable_internal(\n                BYTE* const ostart, BYTE* op, BYTE* const oend,\n                const void* src, size_t srcSize,\n                HUF_nbStreams_e nbStreams, const HUF_CElt* CTable, const int bmi2)\n{\n    size_t const cSize = (nbStreams==HUF_singleStream) ?\n                         HUF_compress1X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2) :\n                         HUF_compress4X_usingCTable_internal(op, oend - op, src, srcSize, CTable, bmi2);\n    if (HUF_isError(cSize)) { return cSize; }\n    if (cSize==0) { return 0; }   /* uncompressible */\n    op += cSize;\n    /* check compressibility */\n    if ((size_t)(op-ostart) >= srcSize-1) { return 0; }\n    return op-ostart;\n}\n\ntypedef struct {\n    unsigned count[HUF_SYMBOLVALUE_MAX + 1];\n    HUF_CElt CTable[HUF_SYMBOLVALUE_MAX + 1];\n    huffNodeTable nodeTable;\n} HUF_compress_tables_t;\n\n/* HUF_compress_internal() :\n * `workSpace` must a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */\nstatic size_t\nHUF_compress_internal (void* dst, size_t dstSize,\n                 const void* src, size_t srcSize,\n                       unsigned maxSymbolValue, unsigned huffLog,\n                       HUF_nbStreams_e nbStreams,\n                       void* workSpace, size_t wkspSize,\n                       HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat,\n                 const int bmi2)\n{\n    HUF_compress_tables_t* const table = (HUF_compress_tables_t*)workSpace;\n    BYTE* const ostart = (BYTE*)dst;\n    BYTE* const oend = ostart + dstSize;\n    BYTE* op = ostart;\n\n    /* checks & inits */\n    if (((size_t)workSpace & 3) != 0) return ERROR(GENERIC);  /* must be aligned on 4-bytes boundaries */\n    if (wkspSize < HUF_WORKSPACE_SIZE) return ERROR(workSpace_tooSmall);\n    if (!srcSize) return 0;  /* Uncompressed */\n    if (!dstSize) return 0;  /* cannot fit anything within dst budget */\n    if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong);   /* current block size limit */\n    if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);\n    if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);\n    if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;\n    if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;\n\n    /* Heuristic : If old table is valid, use it for small inputs */\n    if (preferRepeat && repeat && *repeat == HUF_repeat_valid) {\n        return HUF_compressCTable_internal(ostart, op, oend,\n                                           src, srcSize,\n                                           nbStreams, oldHufTable, bmi2);\n    }\n\n    /* Scan input and build symbol stats */\n    {   CHECK_V_F(largest, HIST_count_wksp (table->count, &maxSymbolValue, (const BYTE*)src, srcSize, workSpace, wkspSize) );\n        if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; }   /* single symbol, rle */\n        if (largest <= (srcSize >> 7)+4) return 0;   /* heuristic : probably not compressible enough */\n    }\n\n    /* Check validity of previous table */\n    if ( repeat\n      && *repeat == HUF_repeat_check\n      && !HUF_validateCTable(oldHufTable, table->count, maxSymbolValue)) {\n        *repeat = HUF_repeat_none;\n    }\n    /* Heuristic : use existing table for small inputs */\n    if (preferRepeat && repeat && *repeat != HUF_repeat_none) {\n        return HUF_compressCTable_internal(ostart, op, oend,\n                                           src, srcSize,\n                                           nbStreams, oldHufTable, bmi2);\n    }\n\n    /* Build Huffman Tree */\n    huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);\n    {   size_t const maxBits = HUF_buildCTable_wksp(table->CTable, table->count,\n                                            maxSymbolValue, huffLog,\n                                            table->nodeTable, sizeof(table->nodeTable));\n        CHECK_F(maxBits);\n        huffLog = (U32)maxBits;\n        /* Zero unused symbols in CTable, so we can check it for validity */\n        memset(table->CTable + (maxSymbolValue + 1), 0,\n               sizeof(table->CTable) - ((maxSymbolValue + 1) * sizeof(HUF_CElt)));\n    }\n\n    /* Write table description header */\n    {   CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, table->CTable, maxSymbolValue, huffLog) );\n        /* Check if using previous huffman table is beneficial */\n        if (repeat && *repeat != HUF_repeat_none) {\n            size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, table->count, maxSymbolValue);\n            size_t const newSize = HUF_estimateCompressedSize(table->CTable, table->count, maxSymbolValue);\n            if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {\n                return HUF_compressCTable_internal(ostart, op, oend,\n                                                   src, srcSize,\n                                                   nbStreams, oldHufTable, bmi2);\n        }   }\n\n        /* Use the new huffman table */\n        if (hSize + 12ul >= srcSize) { return 0; }\n        op += hSize;\n        if (repeat) { *repeat = HUF_repeat_none; }\n        if (oldHufTable)\n            memcpy(oldHufTable, table->CTable, sizeof(table->CTable));  /* Save new table */\n    }\n    return HUF_compressCTable_internal(ostart, op, oend,\n                                       src, srcSize,\n                                       nbStreams, table->CTable, bmi2);\n}\n\n\nsize_t HUF_compress1X_wksp (void* dst, size_t dstSize,\n                      const void* src, size_t srcSize,\n                      unsigned maxSymbolValue, unsigned huffLog,\n                      void* workSpace, size_t wkspSize)\n{\n    return HUF_compress_internal(dst, dstSize, src, srcSize,\n                                 maxSymbolValue, huffLog, HUF_singleStream,\n                                 workSpace, wkspSize,\n                                 NULL, NULL, 0, 0 /*bmi2*/);\n}\n\nsize_t HUF_compress1X_repeat (void* dst, size_t dstSize,\n                      const void* src, size_t srcSize,\n                      unsigned maxSymbolValue, unsigned huffLog,\n                      void* workSpace, size_t wkspSize,\n                      HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2)\n{\n    return HUF_compress_internal(dst, dstSize, src, srcSize,\n                                 maxSymbolValue, huffLog, HUF_singleStream,\n                                 workSpace, wkspSize, hufTable,\n                                 repeat, preferRepeat, bmi2);\n}\n\nsize_t HUF_compress1X (void* dst, size_t dstSize,\n                 const void* src, size_t srcSize,\n                 unsigned maxSymbolValue, unsigned huffLog)\n{\n    unsigned workSpace[HUF_WORKSPACE_SIZE_U32];\n    return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));\n}\n\n/* HUF_compress4X_repeat():\n * compress input using 4 streams.\n * provide workspace to generate compression tables */\nsize_t HUF_compress4X_wksp (void* dst, size_t dstSize,\n                      const void* src, size_t srcSize,\n                      unsigned maxSymbolValue, unsigned huffLog,\n                      void* workSpace, size_t wkspSize)\n{\n    return HUF_compress_internal(dst, dstSize, src, srcSize,\n                                 maxSymbolValue, huffLog, HUF_fourStreams,\n                                 workSpace, wkspSize,\n                                 NULL, NULL, 0, 0 /*bmi2*/);\n}\n\n/* HUF_compress4X_repeat():\n * compress input using 4 streams.\n * re-use an existing huffman compression table */\nsize_t HUF_compress4X_repeat (void* dst, size_t dstSize,\n                      const void* src, size_t srcSize,\n                      unsigned maxSymbolValue, unsigned huffLog,\n                      void* workSpace, size_t wkspSize,\n                      HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat, int bmi2)\n{\n    return HUF_compress_internal(dst, dstSize, src, srcSize,\n                                 maxSymbolValue, huffLog, HUF_fourStreams,\n                                 workSpace, wkspSize,\n                                 hufTable, repeat, preferRepeat, bmi2);\n}\n\nsize_t HUF_compress2 (void* dst, size_t dstSize,\n                const void* src, size_t srcSize,\n                unsigned maxSymbolValue, unsigned huffLog)\n{\n    unsigned workSpace[HUF_WORKSPACE_SIZE_U32];\n    return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));\n}\n\nsize_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)\n{\n    return HUF_compress2(dst, maxDstSize, src, srcSize, 255, HUF_TABLELOG_DEFAULT);\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/huf_decompress.c",
    "content": "/* ******************************************************************\n   huff0 huffman decoder,\n   part of Finite State Entropy library\n   Copyright (C) 2013-present, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n    You can contact the author at :\n    - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy\n****************************************************************** */\n\n/* **************************************************************\n*  Dependencies\n****************************************************************/\n#include <string.h>     /* memcpy, memset */\n#include \"compiler.h\"\n#include \"bitstream.h\"  /* BIT_* */\n#include \"fse.h\"        /* to compress headers */\n#define HUF_STATIC_LINKING_ONLY\n#include \"huf.h\"\n#include \"error_private.h\"\n\n/* **************************************************************\n*  Macros\n****************************************************************/\n\n/* These two optional macros force the use one way or another of the two\n * Huffman decompression implementations. You can't force in both directions\n * at the same time.\n */\n#if defined(HUF_FORCE_DECOMPRESS_X1) && \\\n    defined(HUF_FORCE_DECOMPRESS_X2)\n#error \"Cannot force the use of the X1 and X2 decoders at the same time!\"\n#endif\n\n\n/* **************************************************************\n*  Error Management\n****************************************************************/\n#define HUF_isError ERR_isError\n#ifndef CHECK_F\n#define CHECK_F(f) { size_t const err_ = (f); if (HUF_isError(err_)) return err_; }\n#endif\n\n\n/* **************************************************************\n*  Byte alignment for workSpace management\n****************************************************************/\n#define HUF_ALIGN(x, a)         HUF_ALIGN_MASK((x), (a) - 1)\n#define HUF_ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))\n\n\n/* **************************************************************\n*  BMI2 Variant Wrappers\n****************************************************************/\n#if DYNAMIC_BMI2\n\n#define HUF_DGEN(fn)                                                        \\\n                                                                            \\\n    static size_t fn##_default(                                             \\\n                  void* dst,  size_t dstSize,                               \\\n            const void* cSrc, size_t cSrcSize,                              \\\n            const HUF_DTable* DTable)                                       \\\n    {                                                                       \\\n        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \\\n    }                                                                       \\\n                                                                            \\\n    static TARGET_ATTRIBUTE(\"bmi2\") size_t fn##_bmi2(                       \\\n                  void* dst,  size_t dstSize,                               \\\n            const void* cSrc, size_t cSrcSize,                              \\\n            const HUF_DTable* DTable)                                       \\\n    {                                                                       \\\n        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \\\n    }                                                                       \\\n                                                                            \\\n    static size_t fn(void* dst, size_t dstSize, void const* cSrc,           \\\n                     size_t cSrcSize, HUF_DTable const* DTable, int bmi2)   \\\n    {                                                                       \\\n        if (bmi2) {                                                         \\\n            return fn##_bmi2(dst, dstSize, cSrc, cSrcSize, DTable);         \\\n        }                                                                   \\\n        return fn##_default(dst, dstSize, cSrc, cSrcSize, DTable);          \\\n    }\n\n#else\n\n#define HUF_DGEN(fn)                                                        \\\n    static size_t fn(void* dst, size_t dstSize, void const* cSrc,           \\\n                     size_t cSrcSize, HUF_DTable const* DTable, int bmi2)   \\\n    {                                                                       \\\n        (void)bmi2;                                                         \\\n        return fn##_body(dst, dstSize, cSrc, cSrcSize, DTable);             \\\n    }\n\n#endif\n\n\n/*-***************************/\n/*  generic DTableDesc       */\n/*-***************************/\ntypedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;\n\nstatic DTableDesc HUF_getDTableDesc(const HUF_DTable* table)\n{\n    DTableDesc dtd;\n    memcpy(&dtd, table, sizeof(dtd));\n    return dtd;\n}\n\n\n#ifndef HUF_FORCE_DECOMPRESS_X2\n\n/*-***************************/\n/*  single-symbol decoding   */\n/*-***************************/\ntypedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX1;   /* single-symbol decoding */\n\nsize_t HUF_readDTableX1_wksp(HUF_DTable* DTable, const void* src, size_t srcSize, void* workSpace, size_t wkspSize)\n{\n    U32 tableLog = 0;\n    U32 nbSymbols = 0;\n    size_t iSize;\n    void* const dtPtr = DTable + 1;\n    HUF_DEltX1* const dt = (HUF_DEltX1*)dtPtr;\n\n    U32* rankVal;\n    BYTE* huffWeight;\n    size_t spaceUsed32 = 0;\n\n    rankVal = (U32 *)workSpace + spaceUsed32;\n    spaceUsed32 += HUF_TABLELOG_ABSOLUTEMAX + 1;\n    huffWeight = (BYTE *)((U32 *)workSpace + spaceUsed32);\n    spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;\n\n    if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);\n\n    DEBUG_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));\n    /* memset(huffWeight, 0, sizeof(huffWeight)); */   /* is not necessary, even though some analyzer complain ... */\n\n    iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);\n    if (HUF_isError(iSize)) return iSize;\n\n    /* Table header */\n    {   DTableDesc dtd = HUF_getDTableDesc(DTable);\n        if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge);   /* DTable too small, Huffman tree cannot fit in */\n        dtd.tableType = 0;\n        dtd.tableLog = (BYTE)tableLog;\n        memcpy(DTable, &dtd, sizeof(dtd));\n    }\n\n    /* Calculate starting value for each rank */\n    {   U32 n, nextRankStart = 0;\n        for (n=1; n<tableLog+1; n++) {\n            U32 const current = nextRankStart;\n            nextRankStart += (rankVal[n] << (n-1));\n            rankVal[n] = current;\n    }   }\n\n    /* fill DTable */\n    {   U32 n;\n        for (n=0; n<nbSymbols; n++) {\n            U32 const w = huffWeight[n];\n            U32 const length = (1 << w) >> 1;\n            U32 u;\n            HUF_DEltX1 D;\n            D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);\n            for (u = rankVal[w]; u < rankVal[w] + length; u++)\n                dt[u] = D;\n            rankVal[w] += length;\n    }   }\n\n    return iSize;\n}\n\nsize_t HUF_readDTableX1(HUF_DTable* DTable, const void* src, size_t srcSize)\n{\n    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];\n    return HUF_readDTableX1_wksp(DTable, src, srcSize,\n                                 workSpace, sizeof(workSpace));\n}\n\nFORCE_INLINE_TEMPLATE BYTE\nHUF_decodeSymbolX1(BIT_DStream_t* Dstream, const HUF_DEltX1* dt, const U32 dtLog)\n{\n    size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */\n    BYTE const c = dt[val].byte;\n    BIT_skipBits(Dstream, dt[val].nbBits);\n    return c;\n}\n\n#define HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr) \\\n    *ptr++ = HUF_decodeSymbolX1(DStreamPtr, dt, dtLog)\n\n#define HUF_DECODE_SYMBOLX1_1(ptr, DStreamPtr)  \\\n    if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \\\n        HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)\n\n#define HUF_DECODE_SYMBOLX1_2(ptr, DStreamPtr) \\\n    if (MEM_64bits()) \\\n        HUF_DECODE_SYMBOLX1_0(ptr, DStreamPtr)\n\nHINT_INLINE size_t\nHUF_decodeStreamX1(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX1* const dt, const U32 dtLog)\n{\n    BYTE* const pStart = p;\n\n    /* up to 4 symbols at a time */\n    while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-3)) {\n        HUF_DECODE_SYMBOLX1_2(p, bitDPtr);\n        HUF_DECODE_SYMBOLX1_1(p, bitDPtr);\n        HUF_DECODE_SYMBOLX1_2(p, bitDPtr);\n        HUF_DECODE_SYMBOLX1_0(p, bitDPtr);\n    }\n\n    /* [0-3] symbols remaining */\n    if (MEM_32bits())\n        while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd))\n            HUF_DECODE_SYMBOLX1_0(p, bitDPtr);\n\n    /* no more data to retrieve from bitstream, no need to reload */\n    while (p < pEnd)\n        HUF_DECODE_SYMBOLX1_0(p, bitDPtr);\n\n    return pEnd-pStart;\n}\n\nFORCE_INLINE_TEMPLATE size_t\nHUF_decompress1X1_usingDTable_internal_body(\n          void* dst,  size_t dstSize,\n    const void* cSrc, size_t cSrcSize,\n    const HUF_DTable* DTable)\n{\n    BYTE* op = (BYTE*)dst;\n    BYTE* const oend = op + dstSize;\n    const void* dtPtr = DTable + 1;\n    const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;\n    BIT_DStream_t bitD;\n    DTableDesc const dtd = HUF_getDTableDesc(DTable);\n    U32 const dtLog = dtd.tableLog;\n\n    CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );\n\n    HUF_decodeStreamX1(op, &bitD, oend, dt, dtLog);\n\n    if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);\n\n    return dstSize;\n}\n\nFORCE_INLINE_TEMPLATE size_t\nHUF_decompress4X1_usingDTable_internal_body(\n          void* dst,  size_t dstSize,\n    const void* cSrc, size_t cSrcSize,\n    const HUF_DTable* DTable)\n{\n    /* Check */\n    if (cSrcSize < 10) return ERROR(corruption_detected);  /* strict minimum : jump table + 1 byte per stream */\n\n    {   const BYTE* const istart = (const BYTE*) cSrc;\n        BYTE* const ostart = (BYTE*) dst;\n        BYTE* const oend = ostart + dstSize;\n        const void* const dtPtr = DTable + 1;\n        const HUF_DEltX1* const dt = (const HUF_DEltX1*)dtPtr;\n\n        /* Init */\n        BIT_DStream_t bitD1;\n        BIT_DStream_t bitD2;\n        BIT_DStream_t bitD3;\n        BIT_DStream_t bitD4;\n        size_t const length1 = MEM_readLE16(istart);\n        size_t const length2 = MEM_readLE16(istart+2);\n        size_t const length3 = MEM_readLE16(istart+4);\n        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);\n        const BYTE* const istart1 = istart + 6;  /* jumpTable */\n        const BYTE* const istart2 = istart1 + length1;\n        const BYTE* const istart3 = istart2 + length2;\n        const BYTE* const istart4 = istart3 + length3;\n        const size_t segmentSize = (dstSize+3) / 4;\n        BYTE* const opStart2 = ostart + segmentSize;\n        BYTE* const opStart3 = opStart2 + segmentSize;\n        BYTE* const opStart4 = opStart3 + segmentSize;\n        BYTE* op1 = ostart;\n        BYTE* op2 = opStart2;\n        BYTE* op3 = opStart3;\n        BYTE* op4 = opStart4;\n        U32 endSignal = BIT_DStream_unfinished;\n        DTableDesc const dtd = HUF_getDTableDesc(DTable);\n        U32 const dtLog = dtd.tableLog;\n\n        if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */\n        CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );\n        CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );\n        CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );\n        CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );\n\n        /* up to 16 symbols per loop (4 symbols per stream) in 64-bit mode */\n        endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);\n        while ( (endSignal==BIT_DStream_unfinished) && (op4<(oend-3)) ) {\n            HUF_DECODE_SYMBOLX1_2(op1, &bitD1);\n            HUF_DECODE_SYMBOLX1_2(op2, &bitD2);\n            HUF_DECODE_SYMBOLX1_2(op3, &bitD3);\n            HUF_DECODE_SYMBOLX1_2(op4, &bitD4);\n            HUF_DECODE_SYMBOLX1_1(op1, &bitD1);\n            HUF_DECODE_SYMBOLX1_1(op2, &bitD2);\n            HUF_DECODE_SYMBOLX1_1(op3, &bitD3);\n            HUF_DECODE_SYMBOLX1_1(op4, &bitD4);\n            HUF_DECODE_SYMBOLX1_2(op1, &bitD1);\n            HUF_DECODE_SYMBOLX1_2(op2, &bitD2);\n            HUF_DECODE_SYMBOLX1_2(op3, &bitD3);\n            HUF_DECODE_SYMBOLX1_2(op4, &bitD4);\n            HUF_DECODE_SYMBOLX1_0(op1, &bitD1);\n            HUF_DECODE_SYMBOLX1_0(op2, &bitD2);\n            HUF_DECODE_SYMBOLX1_0(op3, &bitD3);\n            HUF_DECODE_SYMBOLX1_0(op4, &bitD4);\n            BIT_reloadDStream(&bitD1);\n            BIT_reloadDStream(&bitD2);\n            BIT_reloadDStream(&bitD3);\n            BIT_reloadDStream(&bitD4);\n        }\n\n        /* check corruption */\n        /* note : should not be necessary : op# advance in lock step, and we control op4.\n         *        but curiously, binary generated by gcc 7.2 & 7.3 with -mbmi2 runs faster when >=1 test is present */\n        if (op1 > opStart2) return ERROR(corruption_detected);\n        if (op2 > opStart3) return ERROR(corruption_detected);\n        if (op3 > opStart4) return ERROR(corruption_detected);\n        /* note : op4 supposed already verified within main loop */\n\n        /* finish bitStreams one by one */\n        HUF_decodeStreamX1(op1, &bitD1, opStart2, dt, dtLog);\n        HUF_decodeStreamX1(op2, &bitD2, opStart3, dt, dtLog);\n        HUF_decodeStreamX1(op3, &bitD3, opStart4, dt, dtLog);\n        HUF_decodeStreamX1(op4, &bitD4, oend,     dt, dtLog);\n\n        /* check */\n        { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);\n          if (!endCheck) return ERROR(corruption_detected); }\n\n        /* decoded size */\n        return dstSize;\n    }\n}\n\n\ntypedef size_t (*HUF_decompress_usingDTable_t)(void *dst, size_t dstSize,\n                                               const void *cSrc,\n                                               size_t cSrcSize,\n                                               const HUF_DTable *DTable);\n\nHUF_DGEN(HUF_decompress1X1_usingDTable_internal)\nHUF_DGEN(HUF_decompress4X1_usingDTable_internal)\n\n\n\nsize_t HUF_decompress1X1_usingDTable(\n          void* dst,  size_t dstSize,\n    const void* cSrc, size_t cSrcSize,\n    const HUF_DTable* DTable)\n{\n    DTableDesc dtd = HUF_getDTableDesc(DTable);\n    if (dtd.tableType != 0) return ERROR(GENERIC);\n    return HUF_decompress1X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n}\n\nsize_t HUF_decompress1X1_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,\n                                   const void* cSrc, size_t cSrcSize,\n                                   void* workSpace, size_t wkspSize)\n{\n    const BYTE* ip = (const BYTE*) cSrc;\n\n    size_t const hSize = HUF_readDTableX1_wksp(DCtx, cSrc, cSrcSize, workSpace, wkspSize);\n    if (HUF_isError(hSize)) return hSize;\n    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);\n    ip += hSize; cSrcSize -= hSize;\n\n    return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0);\n}\n\n\nsize_t HUF_decompress1X1_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,\n                              const void* cSrc, size_t cSrcSize)\n{\n    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];\n    return HUF_decompress1X1_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,\n                                       workSpace, sizeof(workSpace));\n}\n\nsize_t HUF_decompress1X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)\n{\n    HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);\n    return HUF_decompress1X1_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);\n}\n\nsize_t HUF_decompress4X1_usingDTable(\n          void* dst,  size_t dstSize,\n    const void* cSrc, size_t cSrcSize,\n    const HUF_DTable* DTable)\n{\n    DTableDesc dtd = HUF_getDTableDesc(DTable);\n    if (dtd.tableType != 0) return ERROR(GENERIC);\n    return HUF_decompress4X1_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n}\n\nstatic size_t HUF_decompress4X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize,\n                                   const void* cSrc, size_t cSrcSize,\n                                   void* workSpace, size_t wkspSize, int bmi2)\n{\n    const BYTE* ip = (const BYTE*) cSrc;\n\n    size_t const hSize = HUF_readDTableX1_wksp (dctx, cSrc, cSrcSize,\n                                                workSpace, wkspSize);\n    if (HUF_isError(hSize)) return hSize;\n    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);\n    ip += hSize; cSrcSize -= hSize;\n\n    return HUF_decompress4X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);\n}\n\nsize_t HUF_decompress4X1_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,\n                                   const void* cSrc, size_t cSrcSize,\n                                   void* workSpace, size_t wkspSize)\n{\n    return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, 0);\n}\n\n\nsize_t HUF_decompress4X1_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)\n{\n    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];\n    return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,\n                                       workSpace, sizeof(workSpace));\n}\nsize_t HUF_decompress4X1 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)\n{\n    HUF_CREATE_STATIC_DTABLEX1(DTable, HUF_TABLELOG_MAX);\n    return HUF_decompress4X1_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);\n}\n\n#endif /* HUF_FORCE_DECOMPRESS_X2 */\n\n\n#ifndef HUF_FORCE_DECOMPRESS_X1\n\n/* *************************/\n/* double-symbols decoding */\n/* *************************/\n\ntypedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX2;  /* double-symbols decoding */\ntypedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;\ntypedef U32 rankValCol_t[HUF_TABLELOG_MAX + 1];\ntypedef rankValCol_t rankVal_t[HUF_TABLELOG_MAX];\n\n\n/* HUF_fillDTableX2Level2() :\n * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */\nstatic void HUF_fillDTableX2Level2(HUF_DEltX2* DTable, U32 sizeLog, const U32 consumed,\n                           const U32* rankValOrigin, const int minWeight,\n                           const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,\n                           U32 nbBitsBaseline, U16 baseSeq)\n{\n    HUF_DEltX2 DElt;\n    U32 rankVal[HUF_TABLELOG_MAX + 1];\n\n    /* get pre-calculated rankVal */\n    memcpy(rankVal, rankValOrigin, sizeof(rankVal));\n\n    /* fill skipped values */\n    if (minWeight>1) {\n        U32 i, skipSize = rankVal[minWeight];\n        MEM_writeLE16(&(DElt.sequence), baseSeq);\n        DElt.nbBits   = (BYTE)(consumed);\n        DElt.length   = 1;\n        for (i = 0; i < skipSize; i++)\n            DTable[i] = DElt;\n    }\n\n    /* fill DTable */\n    {   U32 s; for (s=0; s<sortedListSize; s++) {   /* note : sortedSymbols already skipped */\n            const U32 symbol = sortedSymbols[s].symbol;\n            const U32 weight = sortedSymbols[s].weight;\n            const U32 nbBits = nbBitsBaseline - weight;\n            const U32 length = 1 << (sizeLog-nbBits);\n            const U32 start = rankVal[weight];\n            U32 i = start;\n            const U32 end = start + length;\n\n            MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));\n            DElt.nbBits = (BYTE)(nbBits + consumed);\n            DElt.length = 2;\n            do { DTable[i++] = DElt; } while (i<end);   /* since length >= 1 */\n\n            rankVal[weight] += length;\n    }   }\n}\n\n\nstatic void HUF_fillDTableX2(HUF_DEltX2* DTable, const U32 targetLog,\n                           const sortedSymbol_t* sortedList, const U32 sortedListSize,\n                           const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,\n                           const U32 nbBitsBaseline)\n{\n    U32 rankVal[HUF_TABLELOG_MAX + 1];\n    const int scaleLog = nbBitsBaseline - targetLog;   /* note : targetLog >= srcLog, hence scaleLog <= 1 */\n    const U32 minBits  = nbBitsBaseline - maxWeight;\n    U32 s;\n\n    memcpy(rankVal, rankValOrigin, sizeof(rankVal));\n\n    /* fill DTable */\n    for (s=0; s<sortedListSize; s++) {\n        const U16 symbol = sortedList[s].symbol;\n        const U32 weight = sortedList[s].weight;\n        const U32 nbBits = nbBitsBaseline - weight;\n        const U32 start = rankVal[weight];\n        const U32 length = 1 << (targetLog-nbBits);\n\n        if (targetLog-nbBits >= minBits) {   /* enough room for a second symbol */\n            U32 sortedRank;\n            int minWeight = nbBits + scaleLog;\n            if (minWeight < 1) minWeight = 1;\n            sortedRank = rankStart[minWeight];\n            HUF_fillDTableX2Level2(DTable+start, targetLog-nbBits, nbBits,\n                           rankValOrigin[nbBits], minWeight,\n                           sortedList+sortedRank, sortedListSize-sortedRank,\n                           nbBitsBaseline, symbol);\n        } else {\n            HUF_DEltX2 DElt;\n            MEM_writeLE16(&(DElt.sequence), symbol);\n            DElt.nbBits = (BYTE)(nbBits);\n            DElt.length = 1;\n            {   U32 const end = start + length;\n                U32 u;\n                for (u = start; u < end; u++) DTable[u] = DElt;\n        }   }\n        rankVal[weight] += length;\n    }\n}\n\nsize_t HUF_readDTableX2_wksp(HUF_DTable* DTable,\n                       const void* src, size_t srcSize,\n                             void* workSpace, size_t wkspSize)\n{\n    U32 tableLog, maxW, sizeOfSort, nbSymbols;\n    DTableDesc dtd = HUF_getDTableDesc(DTable);\n    U32 const maxTableLog = dtd.maxTableLog;\n    size_t iSize;\n    void* dtPtr = DTable+1;   /* force compiler to avoid strict-aliasing */\n    HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;\n    U32 *rankStart;\n\n    rankValCol_t* rankVal;\n    U32* rankStats;\n    U32* rankStart0;\n    sortedSymbol_t* sortedSymbol;\n    BYTE* weightList;\n    size_t spaceUsed32 = 0;\n\n    rankVal = (rankValCol_t *)((U32 *)workSpace + spaceUsed32);\n    spaceUsed32 += (sizeof(rankValCol_t) * HUF_TABLELOG_MAX) >> 2;\n    rankStats = (U32 *)workSpace + spaceUsed32;\n    spaceUsed32 += HUF_TABLELOG_MAX + 1;\n    rankStart0 = (U32 *)workSpace + spaceUsed32;\n    spaceUsed32 += HUF_TABLELOG_MAX + 2;\n    sortedSymbol = (sortedSymbol_t *)workSpace + (spaceUsed32 * sizeof(U32)) / sizeof(sortedSymbol_t);\n    spaceUsed32 += HUF_ALIGN(sizeof(sortedSymbol_t) * (HUF_SYMBOLVALUE_MAX + 1), sizeof(U32)) >> 2;\n    weightList = (BYTE *)((U32 *)workSpace + spaceUsed32);\n    spaceUsed32 += HUF_ALIGN(HUF_SYMBOLVALUE_MAX + 1, sizeof(U32)) >> 2;\n\n    if ((spaceUsed32 << 2) > wkspSize) return ERROR(tableLog_tooLarge);\n\n    rankStart = rankStart0 + 1;\n    memset(rankStats, 0, sizeof(U32) * (2 * HUF_TABLELOG_MAX + 2 + 1));\n\n    DEBUG_STATIC_ASSERT(sizeof(HUF_DEltX2) == sizeof(HUF_DTable));   /* if compiler fails here, assertion is wrong */\n    if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);\n    /* memset(weightList, 0, sizeof(weightList)); */  /* is not necessary, even though some analyzer complain ... */\n\n    iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);\n    if (HUF_isError(iSize)) return iSize;\n\n    /* check result */\n    if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge);   /* DTable can't fit code depth */\n\n    /* find maxWeight */\n    for (maxW = tableLog; rankStats[maxW]==0; maxW--) {}  /* necessarily finds a solution before 0 */\n\n    /* Get start index of each weight */\n    {   U32 w, nextRankStart = 0;\n        for (w=1; w<maxW+1; w++) {\n            U32 current = nextRankStart;\n            nextRankStart += rankStats[w];\n            rankStart[w] = current;\n        }\n        rankStart[0] = nextRankStart;   /* put all 0w symbols at the end of sorted list*/\n        sizeOfSort = nextRankStart;\n    }\n\n    /* sort symbols by weight */\n    {   U32 s;\n        for (s=0; s<nbSymbols; s++) {\n            U32 const w = weightList[s];\n            U32 const r = rankStart[w]++;\n            sortedSymbol[r].symbol = (BYTE)s;\n            sortedSymbol[r].weight = (BYTE)w;\n        }\n        rankStart[0] = 0;   /* forget 0w symbols; this is beginning of weight(1) */\n    }\n\n    /* Build rankVal */\n    {   U32* const rankVal0 = rankVal[0];\n        {   int const rescale = (maxTableLog-tableLog) - 1;   /* tableLog <= maxTableLog */\n            U32 nextRankVal = 0;\n            U32 w;\n            for (w=1; w<maxW+1; w++) {\n                U32 current = nextRankVal;\n                nextRankVal += rankStats[w] << (w+rescale);\n                rankVal0[w] = current;\n        }   }\n        {   U32 const minBits = tableLog+1 - maxW;\n            U32 consumed;\n            for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {\n                U32* const rankValPtr = rankVal[consumed];\n                U32 w;\n                for (w = 1; w < maxW+1; w++) {\n                    rankValPtr[w] = rankVal0[w] >> consumed;\n    }   }   }   }\n\n    HUF_fillDTableX2(dt, maxTableLog,\n                   sortedSymbol, sizeOfSort,\n                   rankStart0, rankVal, maxW,\n                   tableLog+1);\n\n    dtd.tableLog = (BYTE)maxTableLog;\n    dtd.tableType = 1;\n    memcpy(DTable, &dtd, sizeof(dtd));\n    return iSize;\n}\n\nsize_t HUF_readDTableX2(HUF_DTable* DTable, const void* src, size_t srcSize)\n{\n  U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];\n  return HUF_readDTableX2_wksp(DTable, src, srcSize,\n                               workSpace, sizeof(workSpace));\n}\n\n\nFORCE_INLINE_TEMPLATE U32\nHUF_decodeSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)\n{\n    size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */\n    memcpy(op, dt+val, 2);\n    BIT_skipBits(DStream, dt[val].nbBits);\n    return dt[val].length;\n}\n\nFORCE_INLINE_TEMPLATE U32\nHUF_decodeLastSymbolX2(void* op, BIT_DStream_t* DStream, const HUF_DEltX2* dt, const U32 dtLog)\n{\n    size_t const val = BIT_lookBitsFast(DStream, dtLog);   /* note : dtLog >= 1 */\n    memcpy(op, dt+val, 1);\n    if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);\n    else {\n        if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {\n            BIT_skipBits(DStream, dt[val].nbBits);\n            if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))\n                /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */\n                DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8);\n    }   }\n    return 1;\n}\n\n#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \\\n    ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)\n\n#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \\\n    if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \\\n        ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)\n\n#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \\\n    if (MEM_64bits()) \\\n        ptr += HUF_decodeSymbolX2(ptr, DStreamPtr, dt, dtLog)\n\nHINT_INLINE size_t\nHUF_decodeStreamX2(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd,\n                const HUF_DEltX2* const dt, const U32 dtLog)\n{\n    BYTE* const pStart = p;\n\n    /* up to 8 symbols at a time */\n    while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {\n        HUF_DECODE_SYMBOLX2_2(p, bitDPtr);\n        HUF_DECODE_SYMBOLX2_1(p, bitDPtr);\n        HUF_DECODE_SYMBOLX2_2(p, bitDPtr);\n        HUF_DECODE_SYMBOLX2_0(p, bitDPtr);\n    }\n\n    /* closer to end : up to 2 symbols at a time */\n    while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))\n        HUF_DECODE_SYMBOLX2_0(p, bitDPtr);\n\n    while (p <= pEnd-2)\n        HUF_DECODE_SYMBOLX2_0(p, bitDPtr);   /* no need to reload : reached the end of DStream */\n\n    if (p < pEnd)\n        p += HUF_decodeLastSymbolX2(p, bitDPtr, dt, dtLog);\n\n    return p-pStart;\n}\n\nFORCE_INLINE_TEMPLATE size_t\nHUF_decompress1X2_usingDTable_internal_body(\n          void* dst,  size_t dstSize,\n    const void* cSrc, size_t cSrcSize,\n    const HUF_DTable* DTable)\n{\n    BIT_DStream_t bitD;\n\n    /* Init */\n    CHECK_F( BIT_initDStream(&bitD, cSrc, cSrcSize) );\n\n    /* decode */\n    {   BYTE* const ostart = (BYTE*) dst;\n        BYTE* const oend = ostart + dstSize;\n        const void* const dtPtr = DTable+1;   /* force compiler to not use strict-aliasing */\n        const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;\n        DTableDesc const dtd = HUF_getDTableDesc(DTable);\n        HUF_decodeStreamX2(ostart, &bitD, oend, dt, dtd.tableLog);\n    }\n\n    /* check */\n    if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);\n\n    /* decoded size */\n    return dstSize;\n}\n\n\nFORCE_INLINE_TEMPLATE size_t\nHUF_decompress4X2_usingDTable_internal_body(\n          void* dst,  size_t dstSize,\n    const void* cSrc, size_t cSrcSize,\n    const HUF_DTable* DTable)\n{\n    if (cSrcSize < 10) return ERROR(corruption_detected);   /* strict minimum : jump table + 1 byte per stream */\n\n    {   const BYTE* const istart = (const BYTE*) cSrc;\n        BYTE* const ostart = (BYTE*) dst;\n        BYTE* const oend = ostart + dstSize;\n        const void* const dtPtr = DTable+1;\n        const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;\n\n        /* Init */\n        BIT_DStream_t bitD1;\n        BIT_DStream_t bitD2;\n        BIT_DStream_t bitD3;\n        BIT_DStream_t bitD4;\n        size_t const length1 = MEM_readLE16(istart);\n        size_t const length2 = MEM_readLE16(istart+2);\n        size_t const length3 = MEM_readLE16(istart+4);\n        size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);\n        const BYTE* const istart1 = istart + 6;  /* jumpTable */\n        const BYTE* const istart2 = istart1 + length1;\n        const BYTE* const istart3 = istart2 + length2;\n        const BYTE* const istart4 = istart3 + length3;\n        size_t const segmentSize = (dstSize+3) / 4;\n        BYTE* const opStart2 = ostart + segmentSize;\n        BYTE* const opStart3 = opStart2 + segmentSize;\n        BYTE* const opStart4 = opStart3 + segmentSize;\n        BYTE* op1 = ostart;\n        BYTE* op2 = opStart2;\n        BYTE* op3 = opStart3;\n        BYTE* op4 = opStart4;\n        U32 endSignal;\n        DTableDesc const dtd = HUF_getDTableDesc(DTable);\n        U32 const dtLog = dtd.tableLog;\n\n        if (length4 > cSrcSize) return ERROR(corruption_detected);   /* overflow */\n        CHECK_F( BIT_initDStream(&bitD1, istart1, length1) );\n        CHECK_F( BIT_initDStream(&bitD2, istart2, length2) );\n        CHECK_F( BIT_initDStream(&bitD3, istart3, length3) );\n        CHECK_F( BIT_initDStream(&bitD4, istart4, length4) );\n\n        /* 16-32 symbols per loop (4-8 symbols per stream) */\n        endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);\n        for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) {\n            HUF_DECODE_SYMBOLX2_2(op1, &bitD1);\n            HUF_DECODE_SYMBOLX2_2(op2, &bitD2);\n            HUF_DECODE_SYMBOLX2_2(op3, &bitD3);\n            HUF_DECODE_SYMBOLX2_2(op4, &bitD4);\n            HUF_DECODE_SYMBOLX2_1(op1, &bitD1);\n            HUF_DECODE_SYMBOLX2_1(op2, &bitD2);\n            HUF_DECODE_SYMBOLX2_1(op3, &bitD3);\n            HUF_DECODE_SYMBOLX2_1(op4, &bitD4);\n            HUF_DECODE_SYMBOLX2_2(op1, &bitD1);\n            HUF_DECODE_SYMBOLX2_2(op2, &bitD2);\n            HUF_DECODE_SYMBOLX2_2(op3, &bitD3);\n            HUF_DECODE_SYMBOLX2_2(op4, &bitD4);\n            HUF_DECODE_SYMBOLX2_0(op1, &bitD1);\n            HUF_DECODE_SYMBOLX2_0(op2, &bitD2);\n            HUF_DECODE_SYMBOLX2_0(op3, &bitD3);\n            HUF_DECODE_SYMBOLX2_0(op4, &bitD4);\n\n            endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);\n        }\n\n        /* check corruption */\n        if (op1 > opStart2) return ERROR(corruption_detected);\n        if (op2 > opStart3) return ERROR(corruption_detected);\n        if (op3 > opStart4) return ERROR(corruption_detected);\n        /* note : op4 already verified within main loop */\n\n        /* finish bitStreams one by one */\n        HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);\n        HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);\n        HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);\n        HUF_decodeStreamX2(op4, &bitD4, oend,     dt, dtLog);\n\n        /* check */\n        { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);\n          if (!endCheck) return ERROR(corruption_detected); }\n\n        /* decoded size */\n        return dstSize;\n    }\n}\n\nHUF_DGEN(HUF_decompress1X2_usingDTable_internal)\nHUF_DGEN(HUF_decompress4X2_usingDTable_internal)\n\nsize_t HUF_decompress1X2_usingDTable(\n          void* dst,  size_t dstSize,\n    const void* cSrc, size_t cSrcSize,\n    const HUF_DTable* DTable)\n{\n    DTableDesc dtd = HUF_getDTableDesc(DTable);\n    if (dtd.tableType != 1) return ERROR(GENERIC);\n    return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n}\n\nsize_t HUF_decompress1X2_DCtx_wksp(HUF_DTable* DCtx, void* dst, size_t dstSize,\n                                   const void* cSrc, size_t cSrcSize,\n                                   void* workSpace, size_t wkspSize)\n{\n    const BYTE* ip = (const BYTE*) cSrc;\n\n    size_t const hSize = HUF_readDTableX2_wksp(DCtx, cSrc, cSrcSize,\n                                               workSpace, wkspSize);\n    if (HUF_isError(hSize)) return hSize;\n    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);\n    ip += hSize; cSrcSize -= hSize;\n\n    return HUF_decompress1X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, DCtx, /* bmi2 */ 0);\n}\n\n\nsize_t HUF_decompress1X2_DCtx(HUF_DTable* DCtx, void* dst, size_t dstSize,\n                              const void* cSrc, size_t cSrcSize)\n{\n    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];\n    return HUF_decompress1X2_DCtx_wksp(DCtx, dst, dstSize, cSrc, cSrcSize,\n                                       workSpace, sizeof(workSpace));\n}\n\nsize_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)\n{\n    HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);\n    return HUF_decompress1X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);\n}\n\nsize_t HUF_decompress4X2_usingDTable(\n          void* dst,  size_t dstSize,\n    const void* cSrc, size_t cSrcSize,\n    const HUF_DTable* DTable)\n{\n    DTableDesc dtd = HUF_getDTableDesc(DTable);\n    if (dtd.tableType != 1) return ERROR(GENERIC);\n    return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n}\n\nstatic size_t HUF_decompress4X2_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize,\n                                   const void* cSrc, size_t cSrcSize,\n                                   void* workSpace, size_t wkspSize, int bmi2)\n{\n    const BYTE* ip = (const BYTE*) cSrc;\n\n    size_t hSize = HUF_readDTableX2_wksp(dctx, cSrc, cSrcSize,\n                                         workSpace, wkspSize);\n    if (HUF_isError(hSize)) return hSize;\n    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);\n    ip += hSize; cSrcSize -= hSize;\n\n    return HUF_decompress4X2_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);\n}\n\nsize_t HUF_decompress4X2_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,\n                                   const void* cSrc, size_t cSrcSize,\n                                   void* workSpace, size_t wkspSize)\n{\n    return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, /* bmi2 */ 0);\n}\n\n\nsize_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,\n                              const void* cSrc, size_t cSrcSize)\n{\n    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];\n    return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,\n                                       workSpace, sizeof(workSpace));\n}\n\nsize_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)\n{\n    HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);\n    return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);\n}\n\n#endif /* HUF_FORCE_DECOMPRESS_X1 */\n\n\n/* ***********************************/\n/* Universal decompression selectors */\n/* ***********************************/\n\nsize_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize,\n                                    const void* cSrc, size_t cSrcSize,\n                                    const HUF_DTable* DTable)\n{\n    DTableDesc const dtd = HUF_getDTableDesc(DTable);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n    (void)dtd;\n    assert(dtd.tableType == 0);\n    return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n    (void)dtd;\n    assert(dtd.tableType == 1);\n    return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n#else\n    return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) :\n                           HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n#endif\n}\n\nsize_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,\n                                    const void* cSrc, size_t cSrcSize,\n                                    const HUF_DTable* DTable)\n{\n    DTableDesc const dtd = HUF_getDTableDesc(DTable);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n    (void)dtd;\n    assert(dtd.tableType == 0);\n    return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n    (void)dtd;\n    assert(dtd.tableType == 1);\n    return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n#else\n    return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0) :\n                           HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, /* bmi2 */ 0);\n#endif\n}\n\n\n#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)\ntypedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;\nstatic const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =\n{\n    /* single, double, quad */\n    {{0,0}, {1,1}, {2,2}},  /* Q==0 : impossible */\n    {{0,0}, {1,1}, {2,2}},  /* Q==1 : impossible */\n    {{  38,130}, {1313, 74}, {2151, 38}},   /* Q == 2 : 12-18% */\n    {{ 448,128}, {1353, 74}, {2238, 41}},   /* Q == 3 : 18-25% */\n    {{ 556,128}, {1353, 74}, {2238, 47}},   /* Q == 4 : 25-32% */\n    {{ 714,128}, {1418, 74}, {2436, 53}},   /* Q == 5 : 32-38% */\n    {{ 883,128}, {1437, 74}, {2464, 61}},   /* Q == 6 : 38-44% */\n    {{ 897,128}, {1515, 75}, {2622, 68}},   /* Q == 7 : 44-50% */\n    {{ 926,128}, {1613, 75}, {2730, 75}},   /* Q == 8 : 50-56% */\n    {{ 947,128}, {1729, 77}, {3359, 77}},   /* Q == 9 : 56-62% */\n    {{1107,128}, {2083, 81}, {4006, 84}},   /* Q ==10 : 62-69% */\n    {{1177,128}, {2379, 87}, {4785, 88}},   /* Q ==11 : 69-75% */\n    {{1242,128}, {2415, 93}, {5155, 84}},   /* Q ==12 : 75-81% */\n    {{1349,128}, {2644,106}, {5260,106}},   /* Q ==13 : 81-87% */\n    {{1455,128}, {2422,124}, {4174,124}},   /* Q ==14 : 87-93% */\n    {{ 722,128}, {1891,145}, {1936,146}},   /* Q ==15 : 93-99% */\n};\n#endif\n\n/** HUF_selectDecoder() :\n *  Tells which decoder is likely to decode faster,\n *  based on a set of pre-computed metrics.\n * @return : 0==HUF_decompress4X1, 1==HUF_decompress4X2 .\n *  Assumption : 0 < dstSize <= 128 KB */\nU32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)\n{\n    assert(dstSize > 0);\n    assert(dstSize <= 128*1024);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n    (void)dstSize;\n    (void)cSrcSize;\n    return 0;\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n    (void)dstSize;\n    (void)cSrcSize;\n    return 1;\n#else\n    /* decoder timing evaluation */\n    {   U32 const Q = (cSrcSize >= dstSize) ? 15 : (U32)(cSrcSize * 16 / dstSize);   /* Q < 16 */\n        U32 const D256 = (U32)(dstSize >> 8);\n        U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);\n        U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);\n        DTime1 += DTime1 >> 3;  /* advantage to algorithm using less memory, to reduce cache eviction */\n        return DTime1 < DTime0;\n    }\n#endif\n}\n\n\ntypedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);\n\nsize_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)\n{\n#if !defined(HUF_FORCE_DECOMPRESS_X1) && !defined(HUF_FORCE_DECOMPRESS_X2)\n    static const decompressionAlgo decompress[2] = { HUF_decompress4X1, HUF_decompress4X2 };\n#endif\n\n    /* validation checks */\n    if (dstSize == 0) return ERROR(dstSize_tooSmall);\n    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */\n    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */\n    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */\n\n    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n        (void)algoNb;\n        assert(algoNb == 0);\n        return HUF_decompress4X1(dst, dstSize, cSrc, cSrcSize);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n        (void)algoNb;\n        assert(algoNb == 1);\n        return HUF_decompress4X2(dst, dstSize, cSrc, cSrcSize);\n#else\n        return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);\n#endif\n    }\n}\n\nsize_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)\n{\n    /* validation checks */\n    if (dstSize == 0) return ERROR(dstSize_tooSmall);\n    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */\n    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */\n    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */\n\n    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n        (void)algoNb;\n        assert(algoNb == 0);\n        return HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n        (void)algoNb;\n        assert(algoNb == 1);\n        return HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize);\n#else\n        return algoNb ? HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :\n                        HUF_decompress4X1_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;\n#endif\n    }\n}\n\nsize_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)\n{\n    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];\n    return HUF_decompress4X_hufOnly_wksp(dctx, dst, dstSize, cSrc, cSrcSize,\n                                         workSpace, sizeof(workSpace));\n}\n\n\nsize_t HUF_decompress4X_hufOnly_wksp(HUF_DTable* dctx, void* dst,\n                                     size_t dstSize, const void* cSrc,\n                                     size_t cSrcSize, void* workSpace,\n                                     size_t wkspSize)\n{\n    /* validation checks */\n    if (dstSize == 0) return ERROR(dstSize_tooSmall);\n    if (cSrcSize == 0) return ERROR(corruption_detected);\n\n    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n        (void)algoNb;\n        assert(algoNb == 0);\n        return HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n        (void)algoNb;\n        assert(algoNb == 1);\n        return HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);\n#else\n        return algoNb ? HUF_decompress4X2_DCtx_wksp(dctx, dst, dstSize, cSrc,\n                            cSrcSize, workSpace, wkspSize):\n                        HUF_decompress4X1_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize);\n#endif\n    }\n}\n\nsize_t HUF_decompress1X_DCtx_wksp(HUF_DTable* dctx, void* dst, size_t dstSize,\n                                  const void* cSrc, size_t cSrcSize,\n                                  void* workSpace, size_t wkspSize)\n{\n    /* validation checks */\n    if (dstSize == 0) return ERROR(dstSize_tooSmall);\n    if (cSrcSize > dstSize) return ERROR(corruption_detected);   /* invalid */\n    if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; }   /* not compressed */\n    if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; }   /* RLE */\n\n    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n        (void)algoNb;\n        assert(algoNb == 0);\n        return HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,\n                                cSrcSize, workSpace, wkspSize);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n        (void)algoNb;\n        assert(algoNb == 1);\n        return HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,\n                                cSrcSize, workSpace, wkspSize);\n#else\n        return algoNb ? HUF_decompress1X2_DCtx_wksp(dctx, dst, dstSize, cSrc,\n                                cSrcSize, workSpace, wkspSize):\n                        HUF_decompress1X1_DCtx_wksp(dctx, dst, dstSize, cSrc,\n                                cSrcSize, workSpace, wkspSize);\n#endif\n    }\n}\n\nsize_t HUF_decompress1X_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize,\n                             const void* cSrc, size_t cSrcSize)\n{\n    U32 workSpace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];\n    return HUF_decompress1X_DCtx_wksp(dctx, dst, dstSize, cSrc, cSrcSize,\n                                      workSpace, sizeof(workSpace));\n}\n\n\nsize_t HUF_decompress1X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2)\n{\n    DTableDesc const dtd = HUF_getDTableDesc(DTable);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n    (void)dtd;\n    assert(dtd.tableType == 0);\n    return HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n    (void)dtd;\n    assert(dtd.tableType == 1);\n    return HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);\n#else\n    return dtd.tableType ? HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) :\n                           HUF_decompress1X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);\n#endif\n}\n\n#ifndef HUF_FORCE_DECOMPRESS_X2\nsize_t HUF_decompress1X1_DCtx_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2)\n{\n    const BYTE* ip = (const BYTE*) cSrc;\n\n    size_t const hSize = HUF_readDTableX1_wksp(dctx, cSrc, cSrcSize, workSpace, wkspSize);\n    if (HUF_isError(hSize)) return hSize;\n    if (hSize >= cSrcSize) return ERROR(srcSize_wrong);\n    ip += hSize; cSrcSize -= hSize;\n\n    return HUF_decompress1X1_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx, bmi2);\n}\n#endif\n\nsize_t HUF_decompress4X_usingDTable_bmi2(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable, int bmi2)\n{\n    DTableDesc const dtd = HUF_getDTableDesc(DTable);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n    (void)dtd;\n    assert(dtd.tableType == 0);\n    return HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n    (void)dtd;\n    assert(dtd.tableType == 1);\n    return HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);\n#else\n    return dtd.tableType ? HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2) :\n                           HUF_decompress4X1_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable, bmi2);\n#endif\n}\n\nsize_t HUF_decompress4X_hufOnly_wksp_bmi2(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize, void* workSpace, size_t wkspSize, int bmi2)\n{\n    /* validation checks */\n    if (dstSize == 0) return ERROR(dstSize_tooSmall);\n    if (cSrcSize == 0) return ERROR(corruption_detected);\n\n    {   U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);\n#if defined(HUF_FORCE_DECOMPRESS_X1)\n        (void)algoNb;\n        assert(algoNb == 0);\n        return HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);\n#elif defined(HUF_FORCE_DECOMPRESS_X2)\n        (void)algoNb;\n        assert(algoNb == 1);\n        return HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);\n#else\n        return algoNb ? HUF_decompress4X2_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2) :\n                        HUF_decompress4X1_DCtx_wksp_bmi2(dctx, dst, dstSize, cSrc, cSrcSize, workSpace, wkspSize, bmi2);\n#endif\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/include/zstd.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#ifndef ZSTD_H_235446\n#define ZSTD_H_235446\n\n/* ======   Dependency   ======*/\n#include <limits.h>   /* INT_MAX */\n#include <stddef.h>   /* size_t */\n\n\n/* =====   ZSTDLIB_API : control library symbols visibility   ===== */\n#ifndef ZSTDLIB_VISIBILITY\n#  if defined(__GNUC__) && (__GNUC__ >= 4)\n#    define ZSTDLIB_VISIBILITY __attribute__ ((visibility (\"default\")))\n#  else\n#    define ZSTDLIB_VISIBILITY\n#  endif\n#endif\n#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)\n#  define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBILITY\n#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)\n#  define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/\n#else\n#  define ZSTDLIB_API ZSTDLIB_VISIBILITY\n#endif\n\n\n/*******************************************************************************\n  Introduction\n\n  zstd, short for Zstandard, is a fast lossless compression algorithm, targeting\n  real-time compression scenarios at zlib-level and better compression ratios.\n  The zstd compression library provides in-memory compression and decompression\n  functions.\n\n  The library supports regular compression levels from 1 up to ZSTD_maxCLevel(),\n  which is currently 22. Levels >= 20, labeled `--ultra`, should be used with\n  caution, as they require more memory. The library also offers negative\n  compression levels, which extend the range of speed vs. ratio preferences.\n  The lower the level, the faster the speed (at the cost of compression).\n\n  Compression can be done in:\n    - a single step (described as Simple API)\n    - a single step, reusing a context (described as Explicit context)\n    - unbounded multiple steps (described as Streaming compression)\n\n  The compression ratio achievable on small data can be highly improved using\n  a dictionary. Dictionary compression can be performed in:\n    - a single step (described as Simple dictionary API)\n    - a single step, reusing a dictionary (described as Bulk-processing\n      dictionary API)\n\n  Advanced experimental functions can be accessed using\n  `#define ZSTD_STATIC_LINKING_ONLY` before including zstd.h.\n\n  Advanced experimental APIs should never be used with a dynamically-linked\n  library. They are not \"stable\"; their definitions or signatures may change in\n  the future. Only static linking is allowed.\n*******************************************************************************/\n\n/*------   Version   ------*/\n#define ZSTD_VERSION_MAJOR    1\n#define ZSTD_VERSION_MINOR    4\n#define ZSTD_VERSION_RELEASE  4\n\n#define ZSTD_VERSION_NUMBER  (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)\nZSTDLIB_API unsigned ZSTD_versionNumber(void);   /**< to check runtime library version */\n\n#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE\n#define ZSTD_QUOTE(str) #str\n#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str)\n#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)\nZSTDLIB_API const char* ZSTD_versionString(void);   /* requires v1.3.0+ */\n\n/* *************************************\n *  Default constant\n ***************************************/\n#ifndef ZSTD_CLEVEL_DEFAULT\n#  define ZSTD_CLEVEL_DEFAULT 3\n#endif\n\n/* *************************************\n *  Constants\n ***************************************/\n\n/* All magic numbers are supposed read/written to/from files/memory using little-endian convention */\n#define ZSTD_MAGICNUMBER            0xFD2FB528    /* valid since v0.8.0 */\n#define ZSTD_MAGIC_DICTIONARY       0xEC30A437    /* valid since v0.7.0 */\n#define ZSTD_MAGIC_SKIPPABLE_START  0x184D2A50    /* all 16 values, from 0x184D2A50 to 0x184D2A5F, signal the beginning of a skippable frame */\n#define ZSTD_MAGIC_SKIPPABLE_MASK   0xFFFFFFF0\n\n#define ZSTD_BLOCKSIZELOG_MAX  17\n#define ZSTD_BLOCKSIZE_MAX     (1<<ZSTD_BLOCKSIZELOG_MAX)\n\n\n\n/***************************************\n*  Simple API\n***************************************/\n/*! ZSTD_compress() :\n *  Compresses `src` content as a single zstd compressed frame into already allocated `dst`.\n *  Hint : compression runs faster if `dstCapacity` >=  `ZSTD_compressBound(srcSize)`.\n *  @return : compressed size written into `dst` (<= `dstCapacity),\n *            or an error code if it fails (which can be tested using ZSTD_isError()). */\nZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,\n                            const void* src, size_t srcSize,\n                                  int compressionLevel);\n\n/*! ZSTD_decompress() :\n *  `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames.\n *  `dstCapacity` is an upper bound of originalSize to regenerate.\n *  If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.\n *  @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),\n *            or an errorCode if it fails (which can be tested using ZSTD_isError()). */\nZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,\n                              const void* src, size_t compressedSize);\n\n/*! ZSTD_getFrameContentSize() : requires v1.3.0+\n *  `src` should point to the start of a ZSTD encoded frame.\n *  `srcSize` must be at least as large as the frame header.\n *            hint : any size >= `ZSTD_frameHeaderSize_max` is large enough.\n *  @return : - decompressed size of `src` frame content, if known\n *            - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined\n *            - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small)\n *   note 1 : a 0 return value means the frame is valid but \"empty\".\n *   note 2 : decompressed size is an optional field, it may not be present, typically in streaming mode.\n *            When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size.\n *            In which case, it's necessary to use streaming mode to decompress data.\n *            Optionally, application can rely on some implicit limit,\n *            as ZSTD_decompress() only needs an upper bound of decompressed size.\n *            (For example, data could be necessarily cut into blocks <= 16 KB).\n *   note 3 : decompressed size is always present when compression is completed using single-pass functions,\n *            such as ZSTD_compress(), ZSTD_compressCCtx() ZSTD_compress_usingDict() or ZSTD_compress_usingCDict().\n *   note 4 : decompressed size can be very large (64-bits value),\n *            potentially larger than what local system can handle as a single memory segment.\n *            In which case, it's necessary to use streaming mode to decompress data.\n *   note 5 : If source is untrusted, decompressed size could be wrong or intentionally modified.\n *            Always ensure return value fits within application's authorized limits.\n *            Each application can set its own limits.\n *   note 6 : This function replaces ZSTD_getDecompressedSize() */\n#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)\n#define ZSTD_CONTENTSIZE_ERROR   (0ULL - 2)\nZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);\n\n/*! ZSTD_getDecompressedSize() :\n *  NOTE: This function is now obsolete, in favor of ZSTD_getFrameContentSize().\n *  Both functions work the same way, but ZSTD_getDecompressedSize() blends\n *  \"empty\", \"unknown\" and \"error\" results to the same return value (0),\n *  while ZSTD_getFrameContentSize() gives them separate return values.\n * @return : decompressed size of `src` frame content _if known and not empty_, 0 otherwise. */\nZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);\n\n/*! ZSTD_findFrameCompressedSize() :\n * `src` should point to the start of a ZSTD frame or skippable frame.\n * `srcSize` must be >= first frame size\n * @return : the compressed size of the first frame starting at `src`,\n *           suitable to pass as `srcSize` to `ZSTD_decompress` or similar,\n *        or an error code if input is invalid */\nZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);\n\n\n/*======  Helper functions  ======*/\n#define ZSTD_COMPRESSBOUND(srcSize)   ((srcSize) + ((srcSize)>>8) + (((srcSize) < (128<<10)) ? (((128<<10) - (srcSize)) >> 11) /* margin, from 64 to 0 */ : 0))  /* this formula ensures that bound(A) + bound(B) <= bound(A+B) as long as A and B >= 128 KB */\nZSTDLIB_API size_t      ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case single-pass scenario */\nZSTDLIB_API unsigned    ZSTD_isError(size_t code);          /*!< tells if a `size_t` function result is an error code */\nZSTDLIB_API const char* ZSTD_getErrorName(size_t code);     /*!< provides readable string from an error code */\nZSTDLIB_API int         ZSTD_minCLevel(void);               /*!< minimum negative compression level allowed */\nZSTDLIB_API int         ZSTD_maxCLevel(void);               /*!< maximum compression level available */\n\n\n/***************************************\n*  Explicit context\n***************************************/\n/*= Compression context\n *  When compressing many times,\n *  it is recommended to allocate a context just once,\n *  and re-use it for each successive compression operation.\n *  This will make workload friendlier for system's memory.\n *  Note : re-using context is just a speed / resource optimization.\n *         It doesn't change the compression ratio, which remains identical.\n *  Note 2 : In multi-threaded environments,\n *         use one different context per thread for parallel execution.\n */\ntypedef struct ZSTD_CCtx_s ZSTD_CCtx;\nZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);\nZSTDLIB_API size_t     ZSTD_freeCCtx(ZSTD_CCtx* cctx);\n\n/*! ZSTD_compressCCtx() :\n *  Same as ZSTD_compress(), using an explicit ZSTD_CCtx.\n *  Important : in order to behave similarly to `ZSTD_compress()`,\n *  this function compresses at requested compression level,\n *  __ignoring any other parameter__ .\n *  If any advanced parameter was set using the advanced API,\n *  they will all be reset. Only `compressionLevel` remains.\n */\nZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,\n                                     void* dst, size_t dstCapacity,\n                               const void* src, size_t srcSize,\n                                     int compressionLevel);\n\n/*= Decompression context\n *  When decompressing many times,\n *  it is recommended to allocate a context only once,\n *  and re-use it for each successive compression operation.\n *  This will make workload friendlier for system's memory.\n *  Use one context per thread for parallel execution. */\ntypedef struct ZSTD_DCtx_s ZSTD_DCtx;\nZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);\nZSTDLIB_API size_t     ZSTD_freeDCtx(ZSTD_DCtx* dctx);\n\n/*! ZSTD_decompressDCtx() :\n *  Same as ZSTD_decompress(),\n *  requires an allocated ZSTD_DCtx.\n *  Compatible with sticky parameters.\n */\nZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx,\n                                       void* dst, size_t dstCapacity,\n                                 const void* src, size_t srcSize);\n\n\n/***************************************\n*  Advanced compression API\n***************************************/\n\n/* API design :\n *   Parameters are pushed one by one into an existing context,\n *   using ZSTD_CCtx_set*() functions.\n *   Pushed parameters are sticky : they are valid for next compressed frame, and any subsequent frame.\n *   \"sticky\" parameters are applicable to `ZSTD_compress2()` and `ZSTD_compressStream*()` !\n *   __They do not apply to \"simple\" one-shot variants such as ZSTD_compressCCtx()__ .\n *\n *   It's possible to reset all parameters to \"default\" using ZSTD_CCtx_reset().\n *\n *   This API supercedes all other \"advanced\" API entry points in the experimental section.\n *   In the future, we expect to remove from experimental API entry points which are redundant with this API.\n */\n\n\n/* Compression strategies, listed from fastest to strongest */\ntypedef enum { ZSTD_fast=1,\n               ZSTD_dfast=2,\n               ZSTD_greedy=3,\n               ZSTD_lazy=4,\n               ZSTD_lazy2=5,\n               ZSTD_btlazy2=6,\n               ZSTD_btopt=7,\n               ZSTD_btultra=8,\n               ZSTD_btultra2=9\n               /* note : new strategies _might_ be added in the future.\n                         Only the order (from fast to strong) is guaranteed */\n} ZSTD_strategy;\n\n\ntypedef enum {\n\n    /* compression parameters\n     * Note: When compressing with a ZSTD_CDict these parameters are superseded\n     * by the parameters used to construct the ZSTD_CDict.\n     * See ZSTD_CCtx_refCDict() for more info (superseded-by-cdict). */\n    ZSTD_c_compressionLevel=100, /* Set compression parameters according to pre-defined cLevel table.\n                              * Note that exact compression parameters are dynamically determined,\n                              * depending on both compression level and srcSize (when known).\n                              * Default level is ZSTD_CLEVEL_DEFAULT==3.\n                              * Special: value 0 means default, which is controlled by ZSTD_CLEVEL_DEFAULT.\n                              * Note 1 : it's possible to pass a negative compression level.\n                              * Note 2 : setting a level resets all other compression parameters to default */\n    /* Advanced compression parameters :\n     * It's possible to pin down compression parameters to some specific values.\n     * In which case, these values are no longer dynamically selected by the compressor */\n    ZSTD_c_windowLog=101,    /* Maximum allowed back-reference distance, expressed as power of 2.\n                              * This will set a memory budget for streaming decompression,\n                              * with larger values requiring more memory\n                              * and typically compressing more.\n                              * Must be clamped between ZSTD_WINDOWLOG_MIN and ZSTD_WINDOWLOG_MAX.\n                              * Special: value 0 means \"use default windowLog\".\n                              * Note: Using a windowLog greater than ZSTD_WINDOWLOG_LIMIT_DEFAULT\n                              *       requires explicitly allowing such size at streaming decompression stage. */\n    ZSTD_c_hashLog=102,      /* Size of the initial probe table, as a power of 2.\n                              * Resulting memory usage is (1 << (hashLog+2)).\n                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX.\n                              * Larger tables improve compression ratio of strategies <= dFast,\n                              * and improve speed of strategies > dFast.\n                              * Special: value 0 means \"use default hashLog\". */\n    ZSTD_c_chainLog=103,     /* Size of the multi-probe search table, as a power of 2.\n                              * Resulting memory usage is (1 << (chainLog+2)).\n                              * Must be clamped between ZSTD_CHAINLOG_MIN and ZSTD_CHAINLOG_MAX.\n                              * Larger tables result in better and slower compression.\n                              * This parameter is useless for \"fast\" strategy.\n                              * It's still useful when using \"dfast\" strategy,\n                              * in which case it defines a secondary probe table.\n                              * Special: value 0 means \"use default chainLog\". */\n    ZSTD_c_searchLog=104,    /* Number of search attempts, as a power of 2.\n                              * More attempts result in better and slower compression.\n                              * This parameter is useless for \"fast\" and \"dFast\" strategies.\n                              * Special: value 0 means \"use default searchLog\". */\n    ZSTD_c_minMatch=105,     /* Minimum size of searched matches.\n                              * Note that Zstandard can still find matches of smaller size,\n                              * it just tweaks its search algorithm to look for this size and larger.\n                              * Larger values increase compression and decompression speed, but decrease ratio.\n                              * Must be clamped between ZSTD_MINMATCH_MIN and ZSTD_MINMATCH_MAX.\n                              * Note that currently, for all strategies < btopt, effective minimum is 4.\n                              *                    , for all strategies > fast, effective maximum is 6.\n                              * Special: value 0 means \"use default minMatchLength\". */\n    ZSTD_c_targetLength=106, /* Impact of this field depends on strategy.\n                              * For strategies btopt, btultra & btultra2:\n                              *     Length of Match considered \"good enough\" to stop search.\n                              *     Larger values make compression stronger, and slower.\n                              * For strategy fast:\n                              *     Distance between match sampling.\n                              *     Larger values make compression faster, and weaker.\n                              * Special: value 0 means \"use default targetLength\". */\n    ZSTD_c_strategy=107,     /* See ZSTD_strategy enum definition.\n                              * The higher the value of selected strategy, the more complex it is,\n                              * resulting in stronger and slower compression.\n                              * Special: value 0 means \"use default strategy\". */\n\n    /* LDM mode parameters */\n    ZSTD_c_enableLongDistanceMatching=160, /* Enable long distance matching.\n                                     * This parameter is designed to improve compression ratio\n                                     * for large inputs, by finding large matches at long distance.\n                                     * It increases memory usage and window size.\n                                     * Note: enabling this parameter increases default ZSTD_c_windowLog to 128 MB\n                                     * except when expressly set to a different value. */\n    ZSTD_c_ldmHashLog=161,   /* Size of the table for long distance matching, as a power of 2.\n                              * Larger values increase memory usage and compression ratio,\n                              * but decrease compression speed.\n                              * Must be clamped between ZSTD_HASHLOG_MIN and ZSTD_HASHLOG_MAX\n                              * default: windowlog - 7.\n                              * Special: value 0 means \"automatically determine hashlog\". */\n    ZSTD_c_ldmMinMatch=162,  /* Minimum match size for long distance matcher.\n                              * Larger/too small values usually decrease compression ratio.\n                              * Must be clamped between ZSTD_LDM_MINMATCH_MIN and ZSTD_LDM_MINMATCH_MAX.\n                              * Special: value 0 means \"use default value\" (default: 64). */\n    ZSTD_c_ldmBucketSizeLog=163, /* Log size of each bucket in the LDM hash table for collision resolution.\n                              * Larger values improve collision resolution but decrease compression speed.\n                              * The maximum value is ZSTD_LDM_BUCKETSIZELOG_MAX.\n                              * Special: value 0 means \"use default value\" (default: 3). */\n    ZSTD_c_ldmHashRateLog=164, /* Frequency of inserting/looking up entries into the LDM hash table.\n                              * Must be clamped between 0 and (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN).\n                              * Default is MAX(0, (windowLog - ldmHashLog)), optimizing hash table usage.\n                              * Larger values improve compression speed.\n                              * Deviating far from default value will likely result in a compression ratio decrease.\n                              * Special: value 0 means \"automatically determine hashRateLog\". */\n\n    /* frame parameters */\n    ZSTD_c_contentSizeFlag=200, /* Content size will be written into frame header _whenever known_ (default:1)\n                              * Content size must be known at the beginning of compression.\n                              * This is automatically the case when using ZSTD_compress2(),\n                              * For streaming scenarios, content size must be provided with ZSTD_CCtx_setPledgedSrcSize() */\n    ZSTD_c_checksumFlag=201, /* A 32-bits checksum of content is written at end of frame (default:0) */\n    ZSTD_c_dictIDFlag=202,   /* When applicable, dictionary's ID is written into frame header (default:1) */\n\n    /* multi-threading parameters */\n    /* These parameters are only useful if multi-threading is enabled (compiled with build macro ZSTD_MULTITHREAD).\n     * They return an error otherwise. */\n    ZSTD_c_nbWorkers=400,    /* Select how many threads will be spawned to compress in parallel.\n                              * When nbWorkers >= 1, triggers asynchronous mode when used with ZSTD_compressStream*() :\n                              * ZSTD_compressStream*() consumes input and flush output if possible, but immediately gives back control to caller,\n                              * while compression work is performed in parallel, within worker threads.\n                              * (note : a strong exception to this rule is when first invocation of ZSTD_compressStream2() sets ZSTD_e_end :\n                              *  in which case, ZSTD_compressStream2() delegates to ZSTD_compress2(), which is always a blocking call).\n                              * More workers improve speed, but also increase memory usage.\n                              * Default value is `0`, aka \"single-threaded mode\" : no worker is spawned, compression is performed inside Caller's thread, all invocations are blocking */\n    ZSTD_c_jobSize=401,      /* Size of a compression job. This value is enforced only when nbWorkers >= 1.\n                              * Each compression job is completed in parallel, so this value can indirectly impact the nb of active threads.\n                              * 0 means default, which is dynamically determined based on compression parameters.\n                              * Job size must be a minimum of overlap size, or 1 MB, whichever is largest.\n                              * The minimum size is automatically and transparently enforced. */\n    ZSTD_c_overlapLog=402,   /* Control the overlap size, as a fraction of window size.\n                              * The overlap size is an amount of data reloaded from previous job at the beginning of a new job.\n                              * It helps preserve compression ratio, while each job is compressed in parallel.\n                              * This value is enforced only when nbWorkers >= 1.\n                              * Larger values increase compression ratio, but decrease speed.\n                              * Possible values range from 0 to 9 :\n                              * - 0 means \"default\" : value will be determined by the library, depending on strategy\n                              * - 1 means \"no overlap\"\n                              * - 9 means \"full overlap\", using a full window size.\n                              * Each intermediate rank increases/decreases load size by a factor 2 :\n                              * 9: full window;  8: w/2;  7: w/4;  6: w/8;  5:w/16;  4: w/32;  3:w/64;  2:w/128;  1:no overlap;  0:default\n                              * default value varies between 6 and 9, depending on strategy */\n\n    /* note : additional experimental parameters are also available\n     * within the experimental section of the API.\n     * At the time of this writing, they include :\n     * ZSTD_c_rsyncable\n     * ZSTD_c_format\n     * ZSTD_c_forceMaxWindow\n     * ZSTD_c_forceAttachDict\n     * ZSTD_c_literalCompressionMode\n     * ZSTD_c_targetCBlockSize\n     * ZSTD_c_srcSizeHint\n     * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.\n     * note : never ever use experimentalParam? names directly;\n     *        also, the enums values themselves are unstable and can still change.\n     */\n     ZSTD_c_experimentalParam1=500,\n     ZSTD_c_experimentalParam2=10,\n     ZSTD_c_experimentalParam3=1000,\n     ZSTD_c_experimentalParam4=1001,\n     ZSTD_c_experimentalParam5=1002,\n     ZSTD_c_experimentalParam6=1003,\n     ZSTD_c_experimentalParam7=1004\n} ZSTD_cParameter;\n\ntypedef struct {\n    size_t error;\n    int lowerBound;\n    int upperBound;\n} ZSTD_bounds;\n\n/*! ZSTD_cParam_getBounds() :\n *  All parameters must belong to an interval with lower and upper bounds,\n *  otherwise they will either trigger an error or be automatically clamped.\n * @return : a structure, ZSTD_bounds, which contains\n *         - an error status field, which must be tested using ZSTD_isError()\n *         - lower and upper bounds, both inclusive\n */\nZSTDLIB_API ZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter cParam);\n\n/*! ZSTD_CCtx_setParameter() :\n *  Set one compression parameter, selected by enum ZSTD_cParameter.\n *  All parameters have valid bounds. Bounds can be queried using ZSTD_cParam_getBounds().\n *  Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter).\n *  Setting a parameter is generally only possible during frame initialization (before starting compression).\n *  Exception : when using multi-threading mode (nbWorkers >= 1),\n *              the following parameters can be updated _during_ compression (within same frame):\n *              => compressionLevel, hashLog, chainLog, searchLog, minMatch, targetLength and strategy.\n *              new parameters will be active for next job only (after a flush()).\n * @return : an error code (which can be tested using ZSTD_isError()).\n */\nZSTDLIB_API size_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value);\n\n/*! ZSTD_CCtx_setPledgedSrcSize() :\n *  Total input data size to be compressed as a single frame.\n *  Value will be written in frame header, unless if explicitly forbidden using ZSTD_c_contentSizeFlag.\n *  This value will also be controlled at end of frame, and trigger an error if not respected.\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n *  Note 1 : pledgedSrcSize==0 actually means zero, aka an empty frame.\n *           In order to mean \"unknown content size\", pass constant ZSTD_CONTENTSIZE_UNKNOWN.\n *           ZSTD_CONTENTSIZE_UNKNOWN is default value for any new frame.\n *  Note 2 : pledgedSrcSize is only valid once, for the next frame.\n *           It's discarded at the end of the frame, and replaced by ZSTD_CONTENTSIZE_UNKNOWN.\n *  Note 3 : Whenever all input data is provided and consumed in a single round,\n *           for example with ZSTD_compress2(),\n *           or invoking immediately ZSTD_compressStream2(,,,ZSTD_e_end),\n *           this value is automatically overridden by srcSize instead.\n */\nZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize);\n\ntypedef enum {\n    ZSTD_reset_session_only = 1,\n    ZSTD_reset_parameters = 2,\n    ZSTD_reset_session_and_parameters = 3\n} ZSTD_ResetDirective;\n\n/*! ZSTD_CCtx_reset() :\n *  There are 2 different things that can be reset, independently or jointly :\n *  - The session : will stop compressing current frame, and make CCtx ready to start a new one.\n *                  Useful after an error, or to interrupt any ongoing compression.\n *                  Any internal data not yet flushed is cancelled.\n *                  Compression parameters and dictionary remain unchanged.\n *                  They will be used to compress next frame.\n *                  Resetting session never fails.\n *  - The parameters : changes all parameters back to \"default\".\n *                  This removes any reference to any dictionary too.\n *                  Parameters can only be changed between 2 sessions (i.e. no compression is currently ongoing)\n *                  otherwise the reset fails, and function returns an error value (which can be tested using ZSTD_isError())\n *  - Both : similar to resetting the session, followed by resetting parameters.\n */\nZSTDLIB_API size_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset);\n\n/*! ZSTD_compress2() :\n *  Behave the same as ZSTD_compressCCtx(), but compression parameters are set using the advanced API.\n *  ZSTD_compress2() always starts a new frame.\n *  Should cctx hold data from a previously unfinished frame, everything about it is forgotten.\n *  - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*()\n *  - The function is always blocking, returns when compression is completed.\n *  Hint : compression runs faster if `dstCapacity` >=  `ZSTD_compressBound(srcSize)`.\n * @return : compressed size written into `dst` (<= `dstCapacity),\n *           or an error code if it fails (which can be tested using ZSTD_isError()).\n */\nZSTDLIB_API size_t ZSTD_compress2( ZSTD_CCtx* cctx,\n                                   void* dst, size_t dstCapacity,\n                             const void* src, size_t srcSize);\n\n\n/***************************************\n*  Advanced decompression API\n***************************************/\n\n/* The advanced API pushes parameters one by one into an existing DCtx context.\n * Parameters are sticky, and remain valid for all following frames\n * using the same DCtx context.\n * It's possible to reset parameters to default values using ZSTD_DCtx_reset().\n * Note : This API is compatible with existing ZSTD_decompressDCtx() and ZSTD_decompressStream().\n *        Therefore, no new decompression function is necessary.\n */\n\ntypedef enum {\n\n    ZSTD_d_windowLogMax=100, /* Select a size limit (in power of 2) beyond which\n                              * the streaming API will refuse to allocate memory buffer\n                              * in order to protect the host from unreasonable memory requirements.\n                              * This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode.\n                              * By default, a decompression context accepts window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT).\n                              * Special: value 0 means \"use default maximum windowLog\". */\n\n    /* note : additional experimental parameters are also available\n     * within the experimental section of the API.\n     * At the time of this writing, they include :\n     * ZSTD_c_format\n     * Because they are not stable, it's necessary to define ZSTD_STATIC_LINKING_ONLY to access them.\n     * note : never ever use experimentalParam? names directly\n     */\n     ZSTD_d_experimentalParam1=1000\n\n} ZSTD_dParameter;\n\n/*! ZSTD_dParam_getBounds() :\n *  All parameters must belong to an interval with lower and upper bounds,\n *  otherwise they will either trigger an error or be automatically clamped.\n * @return : a structure, ZSTD_bounds, which contains\n *         - an error status field, which must be tested using ZSTD_isError()\n *         - both lower and upper bounds, inclusive\n */\nZSTDLIB_API ZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam);\n\n/*! ZSTD_DCtx_setParameter() :\n *  Set one compression parameter, selected by enum ZSTD_dParameter.\n *  All parameters have valid bounds. Bounds can be queried using ZSTD_dParam_getBounds().\n *  Providing a value beyond bound will either clamp it, or trigger an error (depending on parameter).\n *  Setting a parameter is only possible during frame initialization (before starting decompression).\n * @return : 0, or an error code (which can be tested using ZSTD_isError()).\n */\nZSTDLIB_API size_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter param, int value);\n\n/*! ZSTD_DCtx_reset() :\n *  Return a DCtx to clean state.\n *  Session and parameters can be reset jointly or separately.\n *  Parameters can only be reset when no active frame is being decompressed.\n * @return : 0, or an error code, which can be tested with ZSTD_isError()\n */\nZSTDLIB_API size_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset);\n\n\n/****************************\n*  Streaming\n****************************/\n\ntypedef struct ZSTD_inBuffer_s {\n  const void* src;    /**< start of input buffer */\n  size_t size;        /**< size of input buffer */\n  size_t pos;         /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */\n} ZSTD_inBuffer;\n\ntypedef struct ZSTD_outBuffer_s {\n  void*  dst;         /**< start of output buffer */\n  size_t size;        /**< size of output buffer */\n  size_t pos;         /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */\n} ZSTD_outBuffer;\n\n\n\n/*-***********************************************************************\n*  Streaming compression - HowTo\n*\n*  A ZSTD_CStream object is required to track streaming operation.\n*  Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.\n*  ZSTD_CStream objects can be reused multiple times on consecutive compression operations.\n*  It is recommended to re-use ZSTD_CStream since it will play nicer with system's memory, by re-using already allocated memory.\n*\n*  For parallel execution, use one separate ZSTD_CStream per thread.\n*\n*  note : since v1.3.0, ZSTD_CStream and ZSTD_CCtx are the same thing.\n*\n*  Parameters are sticky : when starting a new compression on the same context,\n*  it will re-use the same sticky parameters as previous compression session.\n*  When in doubt, it's recommended to fully initialize the context before usage.\n*  Use ZSTD_CCtx_reset() to reset the context and ZSTD_CCtx_setParameter(),\n*  ZSTD_CCtx_setPledgedSrcSize(), or ZSTD_CCtx_loadDictionary() and friends to\n*  set more specific parameters, the pledged source size, or load a dictionary.\n*\n*  Use ZSTD_compressStream2() with ZSTD_e_continue as many times as necessary to\n*  consume input stream. The function will automatically update both `pos`\n*  fields within `input` and `output`.\n*  Note that the function may not consume the entire input, for example, because\n*  the output buffer is already full, in which case `input.pos < input.size`.\n*  The caller must check if input has been entirely consumed.\n*  If not, the caller must make some room to receive more compressed data,\n*  and then present again remaining input data.\n*  note: ZSTD_e_continue is guaranteed to make some forward progress when called,\n*        but doesn't guarantee maximal forward progress. This is especially relevant\n*        when compressing with multiple threads. The call won't block if it can\n*        consume some input, but if it can't it will wait for some, but not all,\n*        output to be flushed.\n* @return : provides a minimum amount of data remaining to be flushed from internal buffers\n*           or an error code, which can be tested using ZSTD_isError().\n*\n*  At any moment, it's possible to flush whatever data might remain stuck within internal buffer,\n*  using ZSTD_compressStream2() with ZSTD_e_flush. `output->pos` will be updated.\n*  Note that, if `output->size` is too small, a single invocation with ZSTD_e_flush might not be enough (return code > 0).\n*  In which case, make some room to receive more compressed data, and call again ZSTD_compressStream2() with ZSTD_e_flush.\n*  You must continue calling ZSTD_compressStream2() with ZSTD_e_flush until it returns 0, at which point you can change the\n*  operation.\n*  note: ZSTD_e_flush will flush as much output as possible, meaning when compressing with multiple threads, it will\n*        block until the flush is complete or the output buffer is full.\n*  @return : 0 if internal buffers are entirely flushed,\n*            >0 if some data still present within internal buffer (the value is minimal estimation of remaining size),\n*            or an error code, which can be tested using ZSTD_isError().\n*\n*  Calling ZSTD_compressStream2() with ZSTD_e_end instructs to finish a frame.\n*  It will perform a flush and write frame epilogue.\n*  The epilogue is required for decoders to consider a frame completed.\n*  flush operation is the same, and follows same rules as calling ZSTD_compressStream2() with ZSTD_e_flush.\n*  You must continue calling ZSTD_compressStream2() with ZSTD_e_end until it returns 0, at which point you are free to\n*  start a new frame.\n*  note: ZSTD_e_end will flush as much output as possible, meaning when compressing with multiple threads, it will\n*        block until the flush is complete or the output buffer is full.\n*  @return : 0 if frame fully completed and fully flushed,\n*            >0 if some data still present within internal buffer (the value is minimal estimation of remaining size),\n*            or an error code, which can be tested using ZSTD_isError().\n*\n* *******************************************************************/\n\ntypedef ZSTD_CCtx ZSTD_CStream;  /**< CCtx and CStream are now effectively same object (>= v1.3.0) */\n                                 /* Continue to distinguish them for compatibility with older versions <= v1.2.0 */\n/*===== ZSTD_CStream management functions =====*/\nZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void);\nZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs);\n\n/*===== Streaming compression functions =====*/\ntypedef enum {\n    ZSTD_e_continue=0, /* collect more data, encoder decides when to output compressed result, for optimal compression ratio */\n    ZSTD_e_flush=1,    /* flush any data provided so far,\n                        * it creates (at least) one new block, that can be decoded immediately on reception;\n                        * frame will continue: any future data can still reference previously compressed data, improving compression.\n                        * note : multithreaded compression will block to flush as much output as possible. */\n    ZSTD_e_end=2       /* flush any remaining data _and_ close current frame.\n                        * note that frame is only closed after compressed data is fully flushed (return value == 0).\n                        * After that point, any additional data starts a new frame.\n                        * note : each frame is independent (does not reference any content from previous frame).\n                        : note : multithreaded compression will block to flush as much output as possible. */\n} ZSTD_EndDirective;\n\n/*! ZSTD_compressStream2() :\n *  Behaves about the same as ZSTD_compressStream, with additional control on end directive.\n *  - Compression parameters are pushed into CCtx before starting compression, using ZSTD_CCtx_set*()\n *  - Compression parameters cannot be changed once compression is started (save a list of exceptions in multi-threading mode)\n *  - output->pos must be <= dstCapacity, input->pos must be <= srcSize\n *  - output->pos and input->pos will be updated. They are guaranteed to remain below their respective limit.\n *  - When nbWorkers==0 (default), function is blocking : it completes its job before returning to caller.\n *  - When nbWorkers>=1, function is non-blocking : it just acquires a copy of input, and distributes jobs to internal worker threads, flush whatever is available,\n *                                                  and then immediately returns, just indicating that there is some data remaining to be flushed.\n *                                                  The function nonetheless guarantees forward progress : it will return only after it reads or write at least 1+ byte.\n *  - Exception : if the first call requests a ZSTD_e_end directive and provides enough dstCapacity, the function delegates to ZSTD_compress2() which is always blocking.\n *  - @return provides a minimum amount of data remaining to be flushed from internal buffers\n *            or an error code, which can be tested using ZSTD_isError().\n *            if @return != 0, flush is not fully completed, there is still some data left within internal buffers.\n *            This is useful for ZSTD_e_flush, since in this case more flushes are necessary to empty all buffers.\n *            For ZSTD_e_end, @return == 0 when internal buffers are fully flushed and frame is completed.\n *  - after a ZSTD_e_end directive, if internal buffer is not fully flushed (@return != 0),\n *            only ZSTD_e_end or ZSTD_e_flush operations are allowed.\n *            Before starting a new compression job, or changing compression parameters,\n *            it is required to fully flush internal buffers.\n */\nZSTDLIB_API size_t ZSTD_compressStream2( ZSTD_CCtx* cctx,\n                                         ZSTD_outBuffer* output,\n                                         ZSTD_inBuffer* input,\n                                         ZSTD_EndDirective endOp);\n\n\n/* These buffer sizes are softly recommended.\n * They are not required : ZSTD_compressStream*() happily accepts any buffer size, for both input and output.\n * Respecting the recommended size just makes it a bit easier for ZSTD_compressStream*(),\n * reducing the amount of memory shuffling and buffering, resulting in minor performance savings.\n *\n * However, note that these recommendations are from the perspective of a C caller program.\n * If the streaming interface is invoked from some other language,\n * especially managed ones such as Java or Go, through a foreign function interface such as jni or cgo,\n * a major performance rule is to reduce crossing such interface to an absolute minimum.\n * It's not rare that performance ends being spent more into the interface, rather than compression itself.\n * In which cases, prefer using large buffers, as large as practical,\n * for both input and output, to reduce the nb of roundtrips.\n */\nZSTDLIB_API size_t ZSTD_CStreamInSize(void);    /**< recommended size for input buffer */\nZSTDLIB_API size_t ZSTD_CStreamOutSize(void);   /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block. */\n\n\n/* *****************************************************************************\n * This following is a legacy streaming API.\n * It can be replaced by ZSTD_CCtx_reset() and ZSTD_compressStream2().\n * It is redundant, but remains fully supported.\n * Advanced parameters and dictionary compression can only be used through the\n * new API.\n ******************************************************************************/\n\n/*!\n * Equivalent to:\n *\n *     ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n *     ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any)\n *     ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);\n */\nZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);\n/*!\n * Alternative for ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue).\n * NOTE: The return value is different. ZSTD_compressStream() returns a hint for\n * the next read size (if non-zero and not an error). ZSTD_compressStream2()\n * returns the minimum nb of bytes left to flush (if non-zero and not an error).\n */\nZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);\n/*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_flush). */\nZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);\n/*! Equivalent to ZSTD_compressStream2(zcs, output, &emptyInput, ZSTD_e_end). */\nZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);\n\n\n/*-***************************************************************************\n*  Streaming decompression - HowTo\n*\n*  A ZSTD_DStream object is required to track streaming operations.\n*  Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.\n*  ZSTD_DStream objects can be re-used multiple times.\n*\n*  Use ZSTD_initDStream() to start a new decompression operation.\n* @return : recommended first input size\n*  Alternatively, use advanced API to set specific properties.\n*\n*  Use ZSTD_decompressStream() repetitively to consume your input.\n*  The function will update both `pos` fields.\n*  If `input.pos < input.size`, some input has not been consumed.\n*  It's up to the caller to present again remaining data.\n*  The function tries to flush all data decoded immediately, respecting output buffer size.\n*  If `output.pos < output.size`, decoder has flushed everything it could.\n*  But if `output.pos == output.size`, there might be some data left within internal buffers.,\n*  In which case, call ZSTD_decompressStream() again to flush whatever remains in the buffer.\n*  Note : with no additional input provided, amount of data flushed is necessarily <= ZSTD_BLOCKSIZE_MAX.\n* @return : 0 when a frame is completely decoded and fully flushed,\n*        or an error code, which can be tested using ZSTD_isError(),\n*        or any other value > 0, which means there is still some decoding or flushing to do to complete current frame :\n*                                the return value is a suggested next input size (just a hint for better latency)\n*                                that will never request more than the remaining frame size.\n* *******************************************************************************/\n\ntypedef ZSTD_DCtx ZSTD_DStream;  /**< DCtx and DStream are now effectively same object (>= v1.3.0) */\n                                 /* For compatibility with versions <= v1.2.0, prefer differentiating them. */\n/*===== ZSTD_DStream management functions =====*/\nZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void);\nZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds);\n\n/*===== Streaming decompression functions =====*/\n\n/* This function is redundant with the advanced API and equivalent to:\n *\n *     ZSTD_DCtx_reset(zds);\n *     ZSTD_DCtx_refDDict(zds, NULL);\n */\nZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds);\n\nZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);\n\nZSTDLIB_API size_t ZSTD_DStreamInSize(void);    /*!< recommended size for input buffer */\nZSTDLIB_API size_t ZSTD_DStreamOutSize(void);   /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */\n\n\n/**************************\n*  Simple dictionary API\n***************************/\n/*! ZSTD_compress_usingDict() :\n *  Compression at an explicit compression level using a Dictionary.\n *  A dictionary can be any arbitrary data segment (also called a prefix),\n *  or a buffer with specified information (see dictBuilder/zdict.h).\n *  Note : This function loads the dictionary, resulting in significant startup delay.\n *         It's intended for a dictionary used only once.\n *  Note 2 : When `dict == NULL || dictSize < 8` no dictionary is used. */\nZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,\n                                           void* dst, size_t dstCapacity,\n                                     const void* src, size_t srcSize,\n                                     const void* dict,size_t dictSize,\n                                           int compressionLevel);\n\n/*! ZSTD_decompress_usingDict() :\n *  Decompression using a known Dictionary.\n *  Dictionary must be identical to the one used during compression.\n *  Note : This function loads the dictionary, resulting in significant startup delay.\n *         It's intended for a dictionary used only once.\n *  Note : When `dict == NULL || dictSize < 8` no dictionary is used. */\nZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,\n                                             void* dst, size_t dstCapacity,\n                                       const void* src, size_t srcSize,\n                                       const void* dict,size_t dictSize);\n\n\n/***********************************\n *  Bulk processing dictionary API\n **********************************/\ntypedef struct ZSTD_CDict_s ZSTD_CDict;\n\n/*! ZSTD_createCDict() :\n *  When compressing multiple messages or blocks using the same dictionary,\n *  it's recommended to digest the dictionary only once, since it's a costly operation.\n *  ZSTD_createCDict() will create a state from digesting a dictionary.\n *  The resulting state can be used for future compression operations with very limited startup cost.\n *  ZSTD_CDict can be created once and shared by multiple threads concurrently, since its usage is read-only.\n * @dictBuffer can be released after ZSTD_CDict creation, because its content is copied within CDict.\n *  Note 1 : Consider experimental function `ZSTD_createCDict_byReference()` if you prefer to not duplicate @dictBuffer content.\n *  Note 2 : A ZSTD_CDict can be created from an empty @dictBuffer,\n *      in which case the only thing that it transports is the @compressionLevel.\n *      This can be useful in a pipeline featuring ZSTD_compress_usingCDict() exclusively,\n *      expecting a ZSTD_CDict parameter with any data, including those without a known dictionary. */\nZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize,\n                                         int compressionLevel);\n\n/*! ZSTD_freeCDict() :\n *  Function frees memory allocated by ZSTD_createCDict(). */\nZSTDLIB_API size_t      ZSTD_freeCDict(ZSTD_CDict* CDict);\n\n/*! ZSTD_compress_usingCDict() :\n *  Compression using a digested Dictionary.\n *  Recommended when same dictionary is used multiple times.\n *  Note : compression level is _decided at dictionary creation time_,\n *     and frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) */\nZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,\n                                            void* dst, size_t dstCapacity,\n                                      const void* src, size_t srcSize,\n                                      const ZSTD_CDict* cdict);\n\n\ntypedef struct ZSTD_DDict_s ZSTD_DDict;\n\n/*! ZSTD_createDDict() :\n *  Create a digested dictionary, ready to start decompression operation without startup delay.\n *  dictBuffer can be released after DDict creation, as its content is copied inside DDict. */\nZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize);\n\n/*! ZSTD_freeDDict() :\n *  Function frees memory allocated with ZSTD_createDDict() */\nZSTDLIB_API size_t      ZSTD_freeDDict(ZSTD_DDict* ddict);\n\n/*! ZSTD_decompress_usingDDict() :\n *  Decompression using a digested Dictionary.\n *  Recommended when same dictionary is used multiple times. */\nZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,\n                                              void* dst, size_t dstCapacity,\n                                        const void* src, size_t srcSize,\n                                        const ZSTD_DDict* ddict);\n\n\n/********************************\n *  Dictionary helper functions\n *******************************/\n\n/*! ZSTD_getDictID_fromDict() :\n *  Provides the dictID stored within dictionary.\n *  if @return == 0, the dictionary is not conformant with Zstandard specification.\n *  It can still be loaded, but as a content-only dictionary. */\nZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);\n\n/*! ZSTD_getDictID_fromDDict() :\n *  Provides the dictID of the dictionary loaded into `ddict`.\n *  If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.\n *  Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */\nZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);\n\n/*! ZSTD_getDictID_fromFrame() :\n *  Provides the dictID required to decompressed the frame stored within `src`.\n *  If @return == 0, the dictID could not be decoded.\n *  This could for one of the following reasons :\n *  - The frame does not require a dictionary to be decoded (most common case).\n *  - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.\n *    Note : this use case also happens when using a non-conformant dictionary.\n *  - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).\n *  - This is not a Zstandard frame.\n *  When identifying the exact failure cause, it's possible to use ZSTD_getFrameHeader(), which will provide a more precise error code. */\nZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);\n\n\n/*******************************************************************************\n * Advanced dictionary and prefix API\n *\n * This API allows dictionaries to be used with ZSTD_compress2(),\n * ZSTD_compressStream2(), and ZSTD_decompress(). Dictionaries are sticky, and\n * only reset with the context is reset with ZSTD_reset_parameters or\n * ZSTD_reset_session_and_parameters. Prefixes are single-use.\n ******************************************************************************/\n\n\n/*! ZSTD_CCtx_loadDictionary() :\n *  Create an internal CDict from `dict` buffer.\n *  Decompression will have to use same dictionary.\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n *  Special: Loading a NULL (or 0-size) dictionary invalidates previous dictionary,\n *           meaning \"return to no-dictionary mode\".\n *  Note 1 : Dictionary is sticky, it will be used for all future compressed frames.\n *           To return to \"no-dictionary\" situation, load a NULL dictionary (or reset parameters).\n *  Note 2 : Loading a dictionary involves building tables.\n *           It's also a CPU consuming operation, with non-negligible impact on latency.\n *           Tables are dependent on compression parameters, and for this reason,\n *           compression parameters can no longer be changed after loading a dictionary.\n *  Note 3 :`dict` content will be copied internally.\n *           Use experimental ZSTD_CCtx_loadDictionary_byReference() to reference content instead.\n *           In such a case, dictionary buffer must outlive its users.\n *  Note 4 : Use ZSTD_CCtx_loadDictionary_advanced()\n *           to precisely select how dictionary content must be interpreted. */\nZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);\n\n/*! ZSTD_CCtx_refCDict() :\n *  Reference a prepared dictionary, to be used for all next compressed frames.\n *  Note that compression parameters are enforced from within CDict,\n *  and supersede any compression parameter previously set within CCtx.\n *  The parameters ignored are labled as \"superseded-by-cdict\" in the ZSTD_cParameter enum docs.\n *  The ignored parameters will be used again if the CCtx is returned to no-dictionary mode.\n *  The dictionary will remain valid for future compressed frames using same CCtx.\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n *  Special : Referencing a NULL CDict means \"return to no-dictionary mode\".\n *  Note 1 : Currently, only one dictionary can be managed.\n *           Referencing a new dictionary effectively \"discards\" any previous one.\n *  Note 2 : CDict is just referenced, its lifetime must outlive its usage within CCtx. */\nZSTDLIB_API size_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict);\n\n/*! ZSTD_CCtx_refPrefix() :\n *  Reference a prefix (single-usage dictionary) for next compressed frame.\n *  A prefix is **only used once**. Tables are discarded at end of frame (ZSTD_e_end).\n *  Decompression will need same prefix to properly regenerate data.\n *  Compressing with a prefix is similar in outcome as performing a diff and compressing it,\n *  but performs much faster, especially during decompression (compression speed is tunable with compression level).\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n *  Special: Adding any prefix (including NULL) invalidates any previous prefix or dictionary\n *  Note 1 : Prefix buffer is referenced. It **must** outlive compression.\n *           Its content must remain unmodified during compression.\n *  Note 2 : If the intention is to diff some large src data blob with some prior version of itself,\n *           ensure that the window size is large enough to contain the entire source.\n *           See ZSTD_c_windowLog.\n *  Note 3 : Referencing a prefix involves building tables, which are dependent on compression parameters.\n *           It's a CPU consuming operation, with non-negligible impact on latency.\n *           If there is a need to use the same prefix multiple times, consider loadDictionary instead.\n *  Note 4 : By default, the prefix is interpreted as raw content (ZSTD_dct_rawContent).\n *           Use experimental ZSTD_CCtx_refPrefix_advanced() to alter dictionary interpretation. */\nZSTDLIB_API size_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx,\n                                 const void* prefix, size_t prefixSize);\n\n/*! ZSTD_DCtx_loadDictionary() :\n *  Create an internal DDict from dict buffer,\n *  to be used to decompress next frames.\n *  The dictionary remains valid for all future frames, until explicitly invalidated.\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n *  Special : Adding a NULL (or 0-size) dictionary invalidates any previous dictionary,\n *            meaning \"return to no-dictionary mode\".\n *  Note 1 : Loading a dictionary involves building tables,\n *           which has a non-negligible impact on CPU usage and latency.\n *           It's recommended to \"load once, use many times\", to amortize the cost\n *  Note 2 :`dict` content will be copied internally, so `dict` can be released after loading.\n *           Use ZSTD_DCtx_loadDictionary_byReference() to reference dictionary content instead.\n *  Note 3 : Use ZSTD_DCtx_loadDictionary_advanced() to take control of\n *           how dictionary content is loaded and interpreted.\n */\nZSTDLIB_API size_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);\n\n/*! ZSTD_DCtx_refDDict() :\n *  Reference a prepared dictionary, to be used to decompress next frames.\n *  The dictionary remains active for decompression of future frames using same DCtx.\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n *  Note 1 : Currently, only one dictionary can be managed.\n *           Referencing a new dictionary effectively \"discards\" any previous one.\n *  Special: referencing a NULL DDict means \"return to no-dictionary mode\".\n *  Note 2 : DDict is just referenced, its lifetime must outlive its usage from DCtx.\n */\nZSTDLIB_API size_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);\n\n/*! ZSTD_DCtx_refPrefix() :\n *  Reference a prefix (single-usage dictionary) to decompress next frame.\n *  This is the reverse operation of ZSTD_CCtx_refPrefix(),\n *  and must use the same prefix as the one used during compression.\n *  Prefix is **only used once**. Reference is discarded at end of frame.\n *  End of frame is reached when ZSTD_decompressStream() returns 0.\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n *  Note 1 : Adding any prefix (including NULL) invalidates any previously set prefix or dictionary\n *  Note 2 : Prefix buffer is referenced. It **must** outlive decompression.\n *           Prefix buffer must remain unmodified up to the end of frame,\n *           reached when ZSTD_decompressStream() returns 0.\n *  Note 3 : By default, the prefix is treated as raw content (ZSTD_dct_rawContent).\n *           Use ZSTD_CCtx_refPrefix_advanced() to alter dictMode (Experimental section)\n *  Note 4 : Referencing a raw content prefix has almost no cpu nor memory cost.\n *           A full dictionary is more costly, as it requires building tables.\n */\nZSTDLIB_API size_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx,\n                                 const void* prefix, size_t prefixSize);\n\n/* ===   Memory management   === */\n\n/*! ZSTD_sizeof_*() :\n *  These functions give the _current_ memory usage of selected object.\n *  Note that object memory usage can evolve (increase or decrease) over time. */\nZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);\nZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);\nZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs);\nZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);\nZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);\nZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);\n\n#endif  /* ZSTD_H_235446 */\n\n\n/* **************************************************************************************\n *   ADVANCED AND EXPERIMENTAL FUNCTIONS\n ****************************************************************************************\n * The definitions in the following section are considered experimental.\n * They are provided for advanced scenarios.\n * They should never be used with a dynamic library, as prototypes may change in the future.\n * Use them only in association with static linking.\n * ***************************************************************************************/\n\n#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY)\n#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY\n\n/****************************************************************************************\n *   experimental API (static linking only)\n ****************************************************************************************\n * The following symbols and constants\n * are not planned to join \"stable API\" status in the near future.\n * They can still change in future versions.\n * Some of them are planned to remain in the static_only section indefinitely.\n * Some of them might be removed in the future (especially when redundant with existing stable functions)\n * ***************************************************************************************/\n\n#define ZSTD_FRAMEHEADERSIZE_PREFIX(format) ((format) == ZSTD_f_zstd1 ? 5 : 1)   /* minimum input size required to query frame header size */\n#define ZSTD_FRAMEHEADERSIZE_MIN(format)    ((format) == ZSTD_f_zstd1 ? 6 : 2)\n#define ZSTD_FRAMEHEADERSIZE_MAX   18   /* can be useful for static allocation */\n#define ZSTD_SKIPPABLEHEADERSIZE    8\n\n/* compression parameter bounds */\n#define ZSTD_WINDOWLOG_MAX_32    30\n#define ZSTD_WINDOWLOG_MAX_64    31\n#define ZSTD_WINDOWLOG_MAX     ((int)(sizeof(size_t) == 4 ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64))\n#define ZSTD_WINDOWLOG_MIN       10\n#define ZSTD_HASHLOG_MAX       ((ZSTD_WINDOWLOG_MAX < 30) ? ZSTD_WINDOWLOG_MAX : 30)\n#define ZSTD_HASHLOG_MIN          6\n#define ZSTD_CHAINLOG_MAX_32     29\n#define ZSTD_CHAINLOG_MAX_64     30\n#define ZSTD_CHAINLOG_MAX      ((int)(sizeof(size_t) == 4 ? ZSTD_CHAINLOG_MAX_32 : ZSTD_CHAINLOG_MAX_64))\n#define ZSTD_CHAINLOG_MIN        ZSTD_HASHLOG_MIN\n#define ZSTD_SEARCHLOG_MAX      (ZSTD_WINDOWLOG_MAX-1)\n#define ZSTD_SEARCHLOG_MIN        1\n#define ZSTD_MINMATCH_MAX         7   /* only for ZSTD_fast, other strategies are limited to 6 */\n#define ZSTD_MINMATCH_MIN         3   /* only for ZSTD_btopt+, faster strategies are limited to 4 */\n#define ZSTD_TARGETLENGTH_MAX    ZSTD_BLOCKSIZE_MAX\n#define ZSTD_TARGETLENGTH_MIN     0   /* note : comparing this constant to an unsigned results in a tautological test */\n#define ZSTD_STRATEGY_MIN        ZSTD_fast\n#define ZSTD_STRATEGY_MAX        ZSTD_btultra2\n\n\n#define ZSTD_OVERLAPLOG_MIN       0\n#define ZSTD_OVERLAPLOG_MAX       9\n\n#define ZSTD_WINDOWLOG_LIMIT_DEFAULT 27   /* by default, the streaming decoder will refuse any frame\n                                           * requiring larger than (1<<ZSTD_WINDOWLOG_LIMIT_DEFAULT) window size,\n                                           * to preserve host's memory from unreasonable requirements.\n                                           * This limit can be overridden using ZSTD_DCtx_setParameter(,ZSTD_d_windowLogMax,).\n                                           * The limit does not apply for one-pass decoders (such as ZSTD_decompress()), since no additional memory is allocated */\n\n\n/* LDM parameter bounds */\n#define ZSTD_LDM_HASHLOG_MIN      ZSTD_HASHLOG_MIN\n#define ZSTD_LDM_HASHLOG_MAX      ZSTD_HASHLOG_MAX\n#define ZSTD_LDM_MINMATCH_MIN        4\n#define ZSTD_LDM_MINMATCH_MAX     4096\n#define ZSTD_LDM_BUCKETSIZELOG_MIN   1\n#define ZSTD_LDM_BUCKETSIZELOG_MAX   8\n#define ZSTD_LDM_HASHRATELOG_MIN     0\n#define ZSTD_LDM_HASHRATELOG_MAX (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)\n\n/* Advanced parameter bounds */\n#define ZSTD_TARGETCBLOCKSIZE_MIN   64\n#define ZSTD_TARGETCBLOCKSIZE_MAX   ZSTD_BLOCKSIZE_MAX\n#define ZSTD_SRCSIZEHINT_MIN        0\n#define ZSTD_SRCSIZEHINT_MAX        INT_MAX\n\n/* internal */\n#define ZSTD_HASHLOG3_MAX           17\n\n\n/* ---  Advanced types  --- */\n\ntypedef struct ZSTD_CCtx_params_s ZSTD_CCtx_params;\n\ntypedef struct {\n    unsigned int matchPos; /* Match pos in dst */\n    /* If seqDef.offset > 3, then this is seqDef.offset - 3\n     * If seqDef.offset < 3, then this is the corresponding repeat offset\n     * But if seqDef.offset < 3 and litLength == 0, this is the\n     *   repeat offset before the corresponding repeat offset\n     * And if seqDef.offset == 3 and litLength == 0, this is the\n     *   most recent repeat offset - 1\n     */\n    unsigned int offset;\n    unsigned int litLength; /* Literal length */\n    unsigned int matchLength; /* Match length */\n    /* 0 when seq not rep and seqDef.offset otherwise\n     * when litLength == 0 this will be <= 4, otherwise <= 3 like normal\n     */\n    unsigned int rep;\n} ZSTD_Sequence;\n\ntypedef struct {\n    unsigned windowLog;       /**< largest match distance : larger == more compression, more memory needed during decompression */\n    unsigned chainLog;        /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */\n    unsigned hashLog;         /**< dispatch table : larger == faster, more memory */\n    unsigned searchLog;       /**< nb of searches : larger == more compression, slower */\n    unsigned minMatch;        /**< match length searched : larger == faster decompression, sometimes less compression */\n    unsigned targetLength;    /**< acceptable match size for optimal parser (only) : larger == more compression, slower */\n    ZSTD_strategy strategy;   /**< see ZSTD_strategy definition above */\n} ZSTD_compressionParameters;\n\ntypedef struct {\n    int contentSizeFlag; /**< 1: content size will be in frame header (when known) */\n    int checksumFlag;    /**< 1: generate a 32-bits checksum using XXH64 algorithm at end of frame, for error detection */\n    int noDictIDFlag;    /**< 1: no dictID will be saved into frame header (dictID is only useful for dictionary compression) */\n} ZSTD_frameParameters;\n\ntypedef struct {\n    ZSTD_compressionParameters cParams;\n    ZSTD_frameParameters fParams;\n} ZSTD_parameters;\n\ntypedef enum {\n    ZSTD_dct_auto = 0,       /* dictionary is \"full\" when starting with ZSTD_MAGIC_DICTIONARY, otherwise it is \"rawContent\" */\n    ZSTD_dct_rawContent = 1, /* ensures dictionary is always loaded as rawContent, even if it starts with ZSTD_MAGIC_DICTIONARY */\n    ZSTD_dct_fullDict = 2    /* refuses to load a dictionary if it does not respect Zstandard's specification, starting with ZSTD_MAGIC_DICTIONARY */\n} ZSTD_dictContentType_e;\n\ntypedef enum {\n    ZSTD_dlm_byCopy = 0,  /**< Copy dictionary content internally */\n    ZSTD_dlm_byRef = 1    /**< Reference dictionary content -- the dictionary buffer must outlive its users. */\n} ZSTD_dictLoadMethod_e;\n\ntypedef enum {\n    ZSTD_f_zstd1 = 0,           /* zstd frame format, specified in zstd_compression_format.md (default) */\n    ZSTD_f_zstd1_magicless = 1  /* Variant of zstd frame format, without initial 4-bytes magic number.\n                                 * Useful to save 4 bytes per generated frame.\n                                 * Decoder cannot recognise automatically this format, requiring this instruction. */\n} ZSTD_format_e;\n\ntypedef enum {\n    /* Note: this enum and the behavior it controls are effectively internal\n     * implementation details of the compressor. They are expected to continue\n     * to evolve and should be considered only in the context of extremely\n     * advanced performance tuning.\n     *\n     * Zstd currently supports the use of a CDict in three ways:\n     *\n     * - The contents of the CDict can be copied into the working context. This\n     *   means that the compression can search both the dictionary and input\n     *   while operating on a single set of internal tables. This makes\n     *   the compression faster per-byte of input. However, the initial copy of\n     *   the CDict's tables incurs a fixed cost at the beginning of the\n     *   compression. For small compressions (< 8 KB), that copy can dominate\n     *   the cost of the compression.\n     *\n     * - The CDict's tables can be used in-place. In this model, compression is\n     *   slower per input byte, because the compressor has to search two sets of\n     *   tables. However, this model incurs no start-up cost (as long as the\n     *   working context's tables can be reused). For small inputs, this can be\n     *   faster than copying the CDict's tables.\n     *\n     * - The CDict's tables are not used at all, and instead we use the working\n     *   context alone to reload the dictionary and use params based on the source\n     *   size. See ZSTD_compress_insertDictionary() and ZSTD_compress_usingDict().\n     *   This method is effective when the dictionary sizes are very small relative\n     *   to the input size, and the input size is fairly large to begin with.\n     *\n     * Zstd has a simple internal heuristic that selects which strategy to use\n     * at the beginning of a compression. However, if experimentation shows that\n     * Zstd is making poor choices, it is possible to override that choice with\n     * this enum.\n     */\n    ZSTD_dictDefaultAttach = 0, /* Use the default heuristic. */\n    ZSTD_dictForceAttach   = 1, /* Never copy the dictionary. */\n    ZSTD_dictForceCopy     = 2, /* Always copy the dictionary. */\n    ZSTD_dictForceLoad     = 3  /* Always reload the dictionary */\n} ZSTD_dictAttachPref_e;\n\ntypedef enum {\n  ZSTD_lcm_auto = 0,          /**< Automatically determine the compression mode based on the compression level.\n                               *   Negative compression levels will be uncompressed, and positive compression\n                               *   levels will be compressed. */\n  ZSTD_lcm_huffman = 1,       /**< Always attempt Huffman compression. Uncompressed literals will still be\n                               *   emitted if Huffman compression is not profitable. */\n  ZSTD_lcm_uncompressed = 2   /**< Always emit uncompressed literals. */\n} ZSTD_literalCompressionMode_e;\n\n\n/***************************************\n*  Frame size functions\n***************************************/\n\n/*! ZSTD_findDecompressedSize() :\n *  `src` should point to the start of a series of ZSTD encoded and/or skippable frames\n *  `srcSize` must be the _exact_ size of this series\n *       (i.e. there should be a frame boundary at `src + srcSize`)\n *  @return : - decompressed size of all data in all successive frames\n *            - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN\n *            - if an error occurred: ZSTD_CONTENTSIZE_ERROR\n *\n *   note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.\n *            When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size.\n *            In which case, it's necessary to use streaming mode to decompress data.\n *   note 2 : decompressed size is always present when compression is done with ZSTD_compress()\n *   note 3 : decompressed size can be very large (64-bits value),\n *            potentially larger than what local system can handle as a single memory segment.\n *            In which case, it's necessary to use streaming mode to decompress data.\n *   note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.\n *            Always ensure result fits within application's authorized limits.\n *            Each application can set its own limits.\n *   note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to\n *            read each contained frame header.  This is fast as most of the data is skipped,\n *            however it does mean that all frame data must be present and valid. */\nZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);\n\n/*! ZSTD_decompressBound() :\n *  `src` should point to the start of a series of ZSTD encoded and/or skippable frames\n *  `srcSize` must be the _exact_ size of this series\n *       (i.e. there should be a frame boundary at `src + srcSize`)\n *  @return : - upper-bound for the decompressed size of all data in all successive frames\n *            - if an error occured: ZSTD_CONTENTSIZE_ERROR\n *\n *  note 1  : an error can occur if `src` contains an invalid or incorrectly formatted frame.\n *  note 2  : the upper-bound is exact when the decompressed size field is available in every ZSTD encoded frame of `src`.\n *            in this case, `ZSTD_findDecompressedSize` and `ZSTD_decompressBound` return the same value.\n *  note 3  : when the decompressed size field isn't available, the upper-bound for that frame is calculated by:\n *              upper-bound = # blocks * min(128 KB, Window_Size)\n */\nZSTDLIB_API unsigned long long ZSTD_decompressBound(const void* src, size_t srcSize);\n\n/*! ZSTD_frameHeaderSize() :\n *  srcSize must be >= ZSTD_FRAMEHEADERSIZE_PREFIX.\n * @return : size of the Frame Header,\n *           or an error code (if srcSize is too small) */\nZSTDLIB_API size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize);\n\n/*! ZSTD_getSequences() :\n * Extract sequences from the sequence store\n * zc can be used to insert custom compression params.\n * This function invokes ZSTD_compress2\n * @return : number of sequences extracted\n */\nZSTDLIB_API size_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,\n    size_t outSeqsSize, const void* src, size_t srcSize);\n\n\n/***************************************\n*  Memory management\n***************************************/\n\n/*! ZSTD_estimate*() :\n *  These functions make it possible to estimate memory usage of a future\n *  {D,C}Ctx, before its creation.\n *\n *  ZSTD_estimateCCtxSize() will provide a budget large enough for any\n *  compression level up to selected one. Unlike ZSTD_estimateCStreamSize*(),\n *  this estimate does not include space for a window buffer, so this estimate\n *  is guaranteed to be enough for single-shot compressions, but not streaming\n *  compressions. It will however assume the input may be arbitrarily large,\n *  which is the worst case. If srcSize is known to always be small,\n *  ZSTD_estimateCCtxSize_usingCParams() can provide a tighter estimation.\n *  ZSTD_estimateCCtxSize_usingCParams() can be used in tandem with\n *  ZSTD_getCParams() to create cParams from compressionLevel.\n *  ZSTD_estimateCCtxSize_usingCCtxParams() can be used in tandem with\n *  ZSTD_CCtxParams_setParameter().\n *\n *  Note: only single-threaded compression is supported. This function will\n *  return an error code if ZSTD_c_nbWorkers is >= 1. */\nZSTDLIB_API size_t ZSTD_estimateCCtxSize(int compressionLevel);\nZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams);\nZSTDLIB_API size_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params);\nZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);\n\n/*! ZSTD_estimateCStreamSize() :\n *  ZSTD_estimateCStreamSize() will provide a budget large enough for any compression level up to selected one.\n *  It will also consider src size to be arbitrarily \"large\", which is worst case.\n *  If srcSize is known to always be small, ZSTD_estimateCStreamSize_usingCParams() can provide a tighter estimation.\n *  ZSTD_estimateCStreamSize_usingCParams() can be used in tandem with ZSTD_getCParams() to create cParams from compressionLevel.\n *  ZSTD_estimateCStreamSize_usingCCtxParams() can be used in tandem with ZSTD_CCtxParams_setParameter(). Only single-threaded compression is supported. This function will return an error code if ZSTD_c_nbWorkers is >= 1.\n *  Note : CStream size estimation is only correct for single-threaded compression.\n *  ZSTD_DStream memory budget depends on window Size.\n *  This information can be passed manually, using ZSTD_estimateDStreamSize,\n *  or deducted from a valid frame Header, using ZSTD_estimateDStreamSize_fromFrame();\n *  Note : if streaming is init with function ZSTD_init?Stream_usingDict(),\n *         an internal ?Dict will be created, which additional size is not estimated here.\n *         In this case, get total size by adding ZSTD_estimate?DictSize */\nZSTDLIB_API size_t ZSTD_estimateCStreamSize(int compressionLevel);\nZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams);\nZSTDLIB_API size_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params);\nZSTDLIB_API size_t ZSTD_estimateDStreamSize(size_t windowSize);\nZSTDLIB_API size_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize);\n\n/*! ZSTD_estimate?DictSize() :\n *  ZSTD_estimateCDictSize() will bet that src size is relatively \"small\", and content is copied, like ZSTD_createCDict().\n *  ZSTD_estimateCDictSize_advanced() makes it possible to control compression parameters precisely, like ZSTD_createCDict_advanced().\n *  Note : dictionaries created by reference (`ZSTD_dlm_byRef`) are logically smaller.\n */\nZSTDLIB_API size_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel);\nZSTDLIB_API size_t ZSTD_estimateCDictSize_advanced(size_t dictSize, ZSTD_compressionParameters cParams, ZSTD_dictLoadMethod_e dictLoadMethod);\nZSTDLIB_API size_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod);\n\n/*! ZSTD_initStatic*() :\n *  Initialize an object using a pre-allocated fixed-size buffer.\n *  workspace: The memory area to emplace the object into.\n *             Provided pointer *must be 8-bytes aligned*.\n *             Buffer must outlive object.\n *  workspaceSize: Use ZSTD_estimate*Size() to determine\n *                 how large workspace must be to support target scenario.\n * @return : pointer to object (same address as workspace, just different type),\n *           or NULL if error (size too small, incorrect alignment, etc.)\n *  Note : zstd will never resize nor malloc() when using a static buffer.\n *         If the object requires more memory than available,\n *         zstd will just error out (typically ZSTD_error_memory_allocation).\n *  Note 2 : there is no corresponding \"free\" function.\n *           Since workspace is allocated externally, it must be freed externally too.\n *  Note 3 : cParams : use ZSTD_getCParams() to convert a compression level\n *           into its associated cParams.\n *  Limitation 1 : currently not compatible with internal dictionary creation, triggered by\n *                 ZSTD_CCtx_loadDictionary(), ZSTD_initCStream_usingDict() or ZSTD_initDStream_usingDict().\n *  Limitation 2 : static cctx currently not compatible with multi-threading.\n *  Limitation 3 : static dctx is incompatible with legacy support.\n */\nZSTDLIB_API ZSTD_CCtx*    ZSTD_initStaticCCtx(void* workspace, size_t workspaceSize);\nZSTDLIB_API ZSTD_CStream* ZSTD_initStaticCStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticCCtx() */\n\nZSTDLIB_API ZSTD_DCtx*    ZSTD_initStaticDCtx(void* workspace, size_t workspaceSize);\nZSTDLIB_API ZSTD_DStream* ZSTD_initStaticDStream(void* workspace, size_t workspaceSize);    /**< same as ZSTD_initStaticDCtx() */\n\nZSTDLIB_API const ZSTD_CDict* ZSTD_initStaticCDict(\n                                        void* workspace, size_t workspaceSize,\n                                        const void* dict, size_t dictSize,\n                                        ZSTD_dictLoadMethod_e dictLoadMethod,\n                                        ZSTD_dictContentType_e dictContentType,\n                                        ZSTD_compressionParameters cParams);\n\nZSTDLIB_API const ZSTD_DDict* ZSTD_initStaticDDict(\n                                        void* workspace, size_t workspaceSize,\n                                        const void* dict, size_t dictSize,\n                                        ZSTD_dictLoadMethod_e dictLoadMethod,\n                                        ZSTD_dictContentType_e dictContentType);\n\n\n/*! Custom memory allocation :\n *  These prototypes make it possible to pass your own allocation/free functions.\n *  ZSTD_customMem is provided at creation time, using ZSTD_create*_advanced() variants listed below.\n *  All allocation/free operations will be completed using these custom variants instead of regular <stdlib.h> ones.\n */\ntypedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);\ntypedef void  (*ZSTD_freeFunction) (void* opaque, void* address);\ntypedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;\nstatic ZSTD_customMem const ZSTD_defaultCMem = { NULL, NULL, NULL };  /**< this constant defers to stdlib's functions */\n\nZSTDLIB_API ZSTD_CCtx*    ZSTD_createCCtx_advanced(ZSTD_customMem customMem);\nZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);\nZSTDLIB_API ZSTD_DCtx*    ZSTD_createDCtx_advanced(ZSTD_customMem customMem);\nZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);\n\nZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize,\n                                                  ZSTD_dictLoadMethod_e dictLoadMethod,\n                                                  ZSTD_dictContentType_e dictContentType,\n                                                  ZSTD_compressionParameters cParams,\n                                                  ZSTD_customMem customMem);\n\nZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,\n                                                  ZSTD_dictLoadMethod_e dictLoadMethod,\n                                                  ZSTD_dictContentType_e dictContentType,\n                                                  ZSTD_customMem customMem);\n\n\n\n/***************************************\n*  Advanced compression functions\n***************************************/\n\n/*! ZSTD_createCDict_byReference() :\n *  Create a digested dictionary for compression\n *  Dictionary content is just referenced, not duplicated.\n *  As a consequence, `dictBuffer` **must** outlive CDict,\n *  and its content must remain unmodified throughout the lifetime of CDict.\n *  note: equivalent to ZSTD_createCDict_advanced(), with dictLoadMethod==ZSTD_dlm_byRef */\nZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);\n\n/*! ZSTD_getCParams() :\n * @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.\n * `estimatedSrcSize` value is optional, select 0 if not known */\nZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);\n\n/*! ZSTD_getParams() :\n *  same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`.\n *  All fields of `ZSTD_frameParameters` are set to default : contentSize=1, checksum=0, noDictID=0 */\nZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);\n\n/*! ZSTD_checkCParams() :\n *  Ensure param values remain within authorized range.\n * @return 0 on success, or an error code (can be checked with ZSTD_isError()) */\nZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);\n\n/*! ZSTD_adjustCParams() :\n *  optimize params for a given `srcSize` and `dictSize`.\n * `srcSize` can be unknown, in which case use ZSTD_CONTENTSIZE_UNKNOWN.\n * `dictSize` must be `0` when there is no dictionary.\n *  cPar can be invalid : all parameters will be clamped within valid range in the @return struct.\n *  This function never fails (wide contract) */\nZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);\n\n/*! ZSTD_compress_advanced() :\n *  Note : this function is now DEPRECATED.\n *         It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_setParameter() and other parameter setters.\n *  This prototype will be marked as deprecated and generate compilation warning on reaching v1.5.x */\nZSTDLIB_API size_t ZSTD_compress_advanced(ZSTD_CCtx* cctx,\n                                          void* dst, size_t dstCapacity,\n                                    const void* src, size_t srcSize,\n                                    const void* dict,size_t dictSize,\n                                          ZSTD_parameters params);\n\n/*! ZSTD_compress_usingCDict_advanced() :\n *  Note : this function is now REDUNDANT.\n *         It can be replaced by ZSTD_compress2(), in combination with ZSTD_CCtx_loadDictionary() and other parameter setters.\n *  This prototype will be marked as deprecated and generate compilation warning in some future version */\nZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,\n                                              void* dst, size_t dstCapacity,\n                                        const void* src, size_t srcSize,\n                                        const ZSTD_CDict* cdict,\n                                              ZSTD_frameParameters fParams);\n\n\n/*! ZSTD_CCtx_loadDictionary_byReference() :\n *  Same as ZSTD_CCtx_loadDictionary(), but dictionary content is referenced, instead of being copied into CCtx.\n *  It saves some memory, but also requires that `dict` outlives its usage within `cctx` */\nZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(ZSTD_CCtx* cctx, const void* dict, size_t dictSize);\n\n/*! ZSTD_CCtx_loadDictionary_advanced() :\n *  Same as ZSTD_CCtx_loadDictionary(), but gives finer control over\n *  how to load the dictionary (by copy ? by reference ?)\n *  and how to interpret it (automatic ? force raw mode ? full mode only ?) */\nZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);\n\n/*! ZSTD_CCtx_refPrefix_advanced() :\n *  Same as ZSTD_CCtx_refPrefix(), but gives finer control over\n *  how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */\nZSTDLIB_API size_t ZSTD_CCtx_refPrefix_advanced(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);\n\n/* ===   experimental parameters   === */\n/* these parameters can be used with ZSTD_setParameter()\n * they are not guaranteed to remain supported in the future */\n\n /* Enables rsyncable mode,\n  * which makes compressed files more rsync friendly\n  * by adding periodic synchronization points to the compressed data.\n  * The target average block size is ZSTD_c_jobSize / 2.\n  * It's possible to modify the job size to increase or decrease\n  * the granularity of the synchronization point.\n  * Once the jobSize is smaller than the window size,\n  * it will result in compression ratio degradation.\n  * NOTE 1: rsyncable mode only works when multithreading is enabled.\n  * NOTE 2: rsyncable performs poorly in combination with long range mode,\n  * since it will decrease the effectiveness of synchronization points,\n  * though mileage may vary.\n  * NOTE 3: Rsyncable mode limits maximum compression speed to ~400 MB/s.\n  * If the selected compression level is already running significantly slower,\n  * the overall speed won't be significantly impacted.\n  */\n #define ZSTD_c_rsyncable ZSTD_c_experimentalParam1\n\n/* Select a compression format.\n * The value must be of type ZSTD_format_e.\n * See ZSTD_format_e enum definition for details */\n#define ZSTD_c_format ZSTD_c_experimentalParam2\n\n/* Force back-reference distances to remain < windowSize,\n * even when referencing into Dictionary content (default:0) */\n#define ZSTD_c_forceMaxWindow ZSTD_c_experimentalParam3\n\n/* Controls whether the contents of a CDict\n * are used in place, or copied into the working context.\n * Accepts values from the ZSTD_dictAttachPref_e enum.\n * See the comments on that enum for an explanation of the feature. */\n#define ZSTD_c_forceAttachDict ZSTD_c_experimentalParam4\n\n/* Controls how the literals are compressed (default is auto).\n * The value must be of type ZSTD_literalCompressionMode_e.\n * See ZSTD_literalCompressionMode_t enum definition for details.\n */\n#define ZSTD_c_literalCompressionMode ZSTD_c_experimentalParam5\n\n/* Tries to fit compressed block size to be around targetCBlockSize.\n * No target when targetCBlockSize == 0.\n * There is no guarantee on compressed block size (default:0) */\n#define ZSTD_c_targetCBlockSize ZSTD_c_experimentalParam6\n\n/* User's best guess of source size.\n * Hint is not valid when srcSizeHint == 0.\n * There is no guarantee that hint is close to actual source size,\n * but compression ratio may regress significantly if guess considerably underestimates */\n#define ZSTD_c_srcSizeHint ZSTD_c_experimentalParam7\n\n/*! ZSTD_CCtx_getParameter() :\n *  Get the requested compression parameter value, selected by enum ZSTD_cParameter,\n *  and store it into int* value.\n * @return : 0, or an error code (which can be tested with ZSTD_isError()).\n */\nZSTDLIB_API size_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value);\n\n\n/*! ZSTD_CCtx_params :\n *  Quick howto :\n *  - ZSTD_createCCtxParams() : Create a ZSTD_CCtx_params structure\n *  - ZSTD_CCtxParams_setParameter() : Push parameters one by one into\n *                                     an existing ZSTD_CCtx_params structure.\n *                                     This is similar to\n *                                     ZSTD_CCtx_setParameter().\n *  - ZSTD_CCtx_setParametersUsingCCtxParams() : Apply parameters to\n *                                    an existing CCtx.\n *                                    These parameters will be applied to\n *                                    all subsequent frames.\n *  - ZSTD_compressStream2() : Do compression using the CCtx.\n *  - ZSTD_freeCCtxParams() : Free the memory.\n *\n *  This can be used with ZSTD_estimateCCtxSize_advanced_usingCCtxParams()\n *  for static allocation of CCtx for single-threaded compression.\n */\nZSTDLIB_API ZSTD_CCtx_params* ZSTD_createCCtxParams(void);\nZSTDLIB_API size_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params);\n\n/*! ZSTD_CCtxParams_reset() :\n *  Reset params to default values.\n */\nZSTDLIB_API size_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params);\n\n/*! ZSTD_CCtxParams_init() :\n *  Initializes the compression parameters of cctxParams according to\n *  compression level. All other parameters are reset to their default values.\n */\nZSTDLIB_API size_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel);\n\n/*! ZSTD_CCtxParams_init_advanced() :\n *  Initializes the compression and frame parameters of cctxParams according to\n *  params. All other parameters are reset to their default values.\n */\nZSTDLIB_API size_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params);\n\n/*! ZSTD_CCtxParams_setParameter() :\n *  Similar to ZSTD_CCtx_setParameter.\n *  Set one compression parameter, selected by enum ZSTD_cParameter.\n *  Parameters must be applied to a ZSTD_CCtx using ZSTD_CCtx_setParametersUsingCCtxParams().\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n */\nZSTDLIB_API size_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int value);\n\n/*! ZSTD_CCtxParams_getParameter() :\n * Similar to ZSTD_CCtx_getParameter.\n * Get the requested value of one compression parameter, selected by enum ZSTD_cParameter.\n * @result : 0, or an error code (which can be tested with ZSTD_isError()).\n */\nZSTDLIB_API size_t ZSTD_CCtxParams_getParameter(ZSTD_CCtx_params* params, ZSTD_cParameter param, int* value);\n\n/*! ZSTD_CCtx_setParametersUsingCCtxParams() :\n *  Apply a set of ZSTD_CCtx_params to the compression context.\n *  This can be done even after compression is started,\n *    if nbWorkers==0, this will have no impact until a new compression is started.\n *    if nbWorkers>=1, new parameters will be picked up at next job,\n *       with a few restrictions (windowLog, pledgedSrcSize, nbWorkers, jobSize, and overlapLog are not updated).\n */\nZSTDLIB_API size_t ZSTD_CCtx_setParametersUsingCCtxParams(\n        ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params);\n\n/*! ZSTD_compressStream2_simpleArgs() :\n *  Same as ZSTD_compressStream2(),\n *  but using only integral types as arguments.\n *  This variant might be helpful for binders from dynamic languages\n *  which have troubles handling structures containing memory pointers.\n */\nZSTDLIB_API size_t ZSTD_compressStream2_simpleArgs (\n                            ZSTD_CCtx* cctx,\n                            void* dst, size_t dstCapacity, size_t* dstPos,\n                      const void* src, size_t srcSize, size_t* srcPos,\n                            ZSTD_EndDirective endOp);\n\n\n/***************************************\n*  Advanced decompression functions\n***************************************/\n\n/*! ZSTD_isFrame() :\n *  Tells if the content of `buffer` starts with a valid Frame Identifier.\n *  Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.\n *  Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.\n *  Note 3 : Skippable Frame Identifiers are considered valid. */\nZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size);\n\n/*! ZSTD_createDDict_byReference() :\n *  Create a digested dictionary, ready to start decompression operation without startup delay.\n *  Dictionary content is referenced, and therefore stays in dictBuffer.\n *  It is important that dictBuffer outlives DDict,\n *  it must remain read accessible throughout the lifetime of DDict */\nZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);\n\n/*! ZSTD_DCtx_loadDictionary_byReference() :\n *  Same as ZSTD_DCtx_loadDictionary(),\n *  but references `dict` content instead of copying it into `dctx`.\n *  This saves memory if `dict` remains around.,\n *  However, it's imperative that `dict` remains accessible (and unmodified) while being used, so it must outlive decompression. */\nZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);\n\n/*! ZSTD_DCtx_loadDictionary_advanced() :\n *  Same as ZSTD_DCtx_loadDictionary(),\n *  but gives direct control over\n *  how to load the dictionary (by copy ? by reference ?)\n *  and how to interpret it (automatic ? force raw mode ? full mode only ?). */\nZSTDLIB_API size_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx, const void* dict, size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType);\n\n/*! ZSTD_DCtx_refPrefix_advanced() :\n *  Same as ZSTD_DCtx_refPrefix(), but gives finer control over\n *  how to interpret prefix content (automatic ? force raw mode (default) ? full mode only ?) */\nZSTDLIB_API size_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType);\n\n/*! ZSTD_DCtx_setMaxWindowSize() :\n *  Refuses allocating internal buffers for frames requiring a window size larger than provided limit.\n *  This protects a decoder context from reserving too much memory for itself (potential attack scenario).\n *  This parameter is only useful in streaming mode, since no internal buffer is allocated in single-pass mode.\n *  By default, a decompression context accepts all window sizes <= (1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT)\n * @return : 0, or an error code (which can be tested using ZSTD_isError()).\n */\nZSTDLIB_API size_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize);\n\n/* ZSTD_d_format\n * experimental parameter,\n * allowing selection between ZSTD_format_e input compression formats\n */\n#define ZSTD_d_format ZSTD_d_experimentalParam1\n\n/*! ZSTD_DCtx_setFormat() :\n *  Instruct the decoder context about what kind of data to decode next.\n *  This instruction is mandatory to decode data without a fully-formed header,\n *  such ZSTD_f_zstd1_magicless for example.\n * @return : 0, or an error code (which can be tested using ZSTD_isError()). */\nZSTDLIB_API size_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format);\n\n/*! ZSTD_decompressStream_simpleArgs() :\n *  Same as ZSTD_decompressStream(),\n *  but using only integral types as arguments.\n *  This can be helpful for binders from dynamic languages\n *  which have troubles handling structures containing memory pointers.\n */\nZSTDLIB_API size_t ZSTD_decompressStream_simpleArgs (\n                            ZSTD_DCtx* dctx,\n                            void* dst, size_t dstCapacity, size_t* dstPos,\n                      const void* src, size_t srcSize, size_t* srcPos);\n\n\n/********************************************************************\n*  Advanced streaming functions\n*  Warning : most of these functions are now redundant with the Advanced API.\n*  Once Advanced API reaches \"stable\" status,\n*  redundant functions will be deprecated, and then at some point removed.\n********************************************************************/\n\n/*=====   Advanced Streaming compression functions  =====*/\n/**! ZSTD_initCStream_srcSize() :\n * This function is deprecated, and equivalent to:\n *     ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n *     ZSTD_CCtx_refCDict(zcs, NULL); // clear the dictionary (if any)\n *     ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);\n *     ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);\n *\n * pledgedSrcSize must be correct. If it is not known at init time, use\n * ZSTD_CONTENTSIZE_UNKNOWN. Note that, for compatibility with older programs,\n * \"0\" also disables frame content size field. It may be enabled in the future.\n * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t\nZSTD_initCStream_srcSize(ZSTD_CStream* zcs,\n                         int compressionLevel,\n                         unsigned long long pledgedSrcSize);\n\n/**! ZSTD_initCStream_usingDict() :\n * This function is deprecated, and is equivalent to:\n *     ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n *     ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel);\n *     ZSTD_CCtx_loadDictionary(zcs, dict, dictSize);\n *\n * Creates of an internal CDict (incompatible with static CCtx), except if\n * dict == NULL or dictSize < 8, in which case no dict is used.\n * Note: dict is loaded with ZSTD_dct_auto (treated as a full zstd dictionary if\n * it begins with ZSTD_MAGIC_DICTIONARY, else as raw content) and ZSTD_dlm_byCopy.\n * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t\nZSTD_initCStream_usingDict(ZSTD_CStream* zcs,\n                     const void* dict, size_t dictSize,\n                           int compressionLevel);\n\n/**! ZSTD_initCStream_advanced() :\n * This function is deprecated, and is approximately equivalent to:\n *     ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n *     // Pseudocode: Set each zstd parameter and leave the rest as-is.\n *     for ((param, value) : params) {\n *         ZSTD_CCtx_setParameter(zcs, param, value);\n *     }\n *     ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);\n *     ZSTD_CCtx_loadDictionary(zcs, dict, dictSize);\n *\n * dict is loaded with ZSTD_dct_auto and ZSTD_dlm_byCopy.\n * pledgedSrcSize must be correct.\n * If srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.\n * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t\nZSTD_initCStream_advanced(ZSTD_CStream* zcs,\n                    const void* dict, size_t dictSize,\n                          ZSTD_parameters params,\n                          unsigned long long pledgedSrcSize);\n\n/**! ZSTD_initCStream_usingCDict() :\n * This function is deprecated, and equivalent to:\n *     ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n *     ZSTD_CCtx_refCDict(zcs, cdict);\n *\n * note : cdict will just be referenced, and must outlive compression session\n * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict);\n\n/**! ZSTD_initCStream_usingCDict_advanced() :\n *   This function is DEPRECATED, and is approximately equivalent to:\n *     ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n *     // Pseudocode: Set each zstd frame parameter and leave the rest as-is.\n *     for ((fParam, value) : fParams) {\n *         ZSTD_CCtx_setParameter(zcs, fParam, value);\n *     }\n *     ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);\n *     ZSTD_CCtx_refCDict(zcs, cdict);\n *\n * same as ZSTD_initCStream_usingCDict(), with control over frame parameters.\n * pledgedSrcSize must be correct. If srcSize is not known at init time, use\n * value ZSTD_CONTENTSIZE_UNKNOWN.\n * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t\nZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,\n                               const ZSTD_CDict* cdict,\n                                     ZSTD_frameParameters fParams,\n                                     unsigned long long pledgedSrcSize);\n\n/*! ZSTD_resetCStream() :\n * This function is deprecated, and is equivalent to:\n *     ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n *     ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize);\n *\n *  start a new frame, using same parameters from previous frame.\n *  This is typically useful to skip dictionary loading stage, since it will re-use it in-place.\n *  Note that zcs must be init at least once before using ZSTD_resetCStream().\n *  If pledgedSrcSize is not known at reset time, use macro ZSTD_CONTENTSIZE_UNKNOWN.\n *  If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end.\n *  For the time being, pledgedSrcSize==0 is interpreted as \"srcSize unknown\" for compatibility with older programs,\n *  but it will change to mean \"empty\" in future version, so use macro ZSTD_CONTENTSIZE_UNKNOWN instead.\n * @return : 0, or an error code (which can be tested using ZSTD_isError())\n *  Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);\n\n\ntypedef struct {\n    unsigned long long ingested;   /* nb input bytes read and buffered */\n    unsigned long long consumed;   /* nb input bytes actually compressed */\n    unsigned long long produced;   /* nb of compressed bytes generated and buffered */\n    unsigned long long flushed;    /* nb of compressed bytes flushed : not provided; can be tracked from caller side */\n    unsigned currentJobID;         /* MT only : latest started job nb */\n    unsigned nbActiveWorkers;      /* MT only : nb of workers actively compressing at probe time */\n} ZSTD_frameProgression;\n\n/* ZSTD_getFrameProgression() :\n * tells how much data has been ingested (read from input)\n * consumed (input actually compressed) and produced (output) for current frame.\n * Note : (ingested - consumed) is amount of input data buffered internally, not yet compressed.\n * Aggregates progression inside active worker threads.\n */\nZSTDLIB_API ZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx);\n\n/*! ZSTD_toFlushNow() :\n *  Tell how many bytes are ready to be flushed immediately.\n *  Useful for multithreading scenarios (nbWorkers >= 1).\n *  Probe the oldest active job, defined as oldest job not yet entirely flushed,\n *  and check its output buffer.\n * @return : amount of data stored in oldest job and ready to be flushed immediately.\n *  if @return == 0, it means either :\n *  + there is no active job (could be checked with ZSTD_frameProgression()), or\n *  + oldest job is still actively compressing data,\n *    but everything it has produced has also been flushed so far,\n *    therefore flush speed is limited by production speed of oldest job\n *    irrespective of the speed of concurrent (and newer) jobs.\n */\nZSTDLIB_API size_t ZSTD_toFlushNow(ZSTD_CCtx* cctx);\n\n\n/*=====   Advanced Streaming decompression functions  =====*/\n/**\n * This function is deprecated, and is equivalent to:\n *\n *     ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);\n *     ZSTD_DCtx_loadDictionary(zds, dict, dictSize);\n *\n * note: no dictionary will be used if dict == NULL or dictSize < 8\n * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize);\n\n/**\n * This function is deprecated, and is equivalent to:\n *\n *     ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);\n *     ZSTD_DCtx_refDDict(zds, ddict);\n *\n * note : ddict is referenced, it must outlive decompression session\n * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict);\n\n/**\n * This function is deprecated, and is equivalent to:\n *\n *     ZSTD_DCtx_reset(zds, ZSTD_reset_session_only);\n *\n * re-use decompression parameters from previous init; saves dictionary loading\n * Note : this prototype will be marked as deprecated and generate compilation warnings on reaching v1.5.x\n */\nZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds);\n\n\n/*********************************************************************\n*  Buffer-less and synchronous inner streaming functions\n*\n*  This is an advanced API, giving full control over buffer management, for users which need direct control over memory.\n*  But it's also a complex one, with several restrictions, documented below.\n*  Prefer normal streaming API for an easier experience.\n********************************************************************* */\n\n/**\n  Buffer-less streaming compression (synchronous mode)\n\n  A ZSTD_CCtx object is required to track streaming operations.\n  Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.\n  ZSTD_CCtx object can be re-used multiple times within successive compression operations.\n\n  Start by initializing a context.\n  Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,\n  or ZSTD_compressBegin_advanced(), for finer parameter control.\n  It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()\n\n  Then, consume your input using ZSTD_compressContinue().\n  There are some important considerations to keep in mind when using this advanced function :\n  - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffers only.\n  - Interface is synchronous : input is consumed entirely and produces 1+ compressed blocks.\n  - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.\n    Worst case evaluation is provided by ZSTD_compressBound().\n    ZSTD_compressContinue() doesn't guarantee recover after a failed compression.\n  - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).\n    It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)\n  - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.\n    In which case, it will \"discard\" the relevant memory section from its history.\n\n  Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.\n  It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame.\n  Without last block mark, frames are considered unfinished (hence corrupted) by compliant decoders.\n\n  `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress again.\n*/\n\n/*=====   Buffer-less streaming compression functions  =====*/\nZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);\nZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);\nZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize : If srcSize is not known at init time, use ZSTD_CONTENTSIZE_UNKNOWN */\nZSTDLIB_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */\nZSTDLIB_API size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize);   /* compression parameters are already set within cdict. pledgedSrcSize must be correct. If srcSize is not known, use macro ZSTD_CONTENTSIZE_UNKNOWN */\nZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**<  note: if pledgedSrcSize is not known, use ZSTD_CONTENTSIZE_UNKNOWN */\n\nZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);\nZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);\n\n\n/*-\n  Buffer-less streaming decompression (synchronous mode)\n\n  A ZSTD_DCtx object is required to track streaming operations.\n  Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.\n  A ZSTD_DCtx object can be re-used multiple times.\n\n  First typical operation is to retrieve frame parameters, using ZSTD_getFrameHeader().\n  Frame header is extracted from the beginning of compressed frame, so providing only the frame's beginning is enough.\n  Data fragment must be large enough to ensure successful decoding.\n `ZSTD_frameHeaderSize_max` bytes is guaranteed to always be large enough.\n  @result : 0 : successful decoding, the `ZSTD_frameHeader` structure is correctly filled.\n           >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.\n           errorCode, which can be tested using ZSTD_isError().\n\n  It fills a ZSTD_frameHeader structure with important information to correctly decode the frame,\n  such as the dictionary ID, content size, or maximum back-reference distance (`windowSize`).\n  Note that these values could be wrong, either because of data corruption, or because a 3rd party deliberately spoofs false information.\n  As a consequence, check that values remain within valid application range.\n  For example, do not allocate memory blindly, check that `windowSize` is within expectation.\n  Each application can set its own limits, depending on local restrictions.\n  For extended interoperability, it is recommended to support `windowSize` of at least 8 MB.\n\n  ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize` bytes.\n  ZSTD_decompressContinue() is very sensitive to contiguity,\n  if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,\n  or that previous contiguous segment is large enough to properly handle maximum back-reference distance.\n  There are multiple ways to guarantee this condition.\n\n  The most memory efficient way is to use a round buffer of sufficient size.\n  Sufficient size is determined by invoking ZSTD_decodingBufferSize_min(),\n  which can @return an error code if required value is too large for current system (in 32-bits mode).\n  In a round buffer methodology, ZSTD_decompressContinue() decompresses each block next to previous one,\n  up to the moment there is not enough room left in the buffer to guarantee decoding another full block,\n  which maximum size is provided in `ZSTD_frameHeader` structure, field `blockSizeMax`.\n  At which point, decoding can resume from the beginning of the buffer.\n  Note that already decoded data stored in the buffer should be flushed before being overwritten.\n\n  There are alternatives possible, for example using two or more buffers of size `windowSize` each, though they consume more memory.\n\n  Finally, if you control the compression process, you can also ignore all buffer size rules,\n  as long as the encoder and decoder progress in \"lock-step\",\n  aka use exactly the same buffer sizes, break contiguity at the same place, etc.\n\n  Once buffers are setup, start decompression, with ZSTD_decompressBegin().\n  If decompression requires a dictionary, use ZSTD_decompressBegin_usingDict() or ZSTD_decompressBegin_usingDDict().\n\n  Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.\n  ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().\n  ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.\n\n @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).\n  It can be zero : it just means ZSTD_decompressContinue() has decoded some metadata item.\n  It can also be an error code, which can be tested with ZSTD_isError().\n\n  A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.\n  Context can then be reset to start a new decompression.\n\n  Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().\n  This information is not required to properly decode a frame.\n\n  == Special case : skippable frames ==\n\n  Skippable frames allow integration of user-defined data into a flow of concatenated frames.\n  Skippable frames will be ignored (skipped) by decompressor.\n  The format of skippable frames is as follows :\n  a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F\n  b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits\n  c) Frame Content - any content (User Data) of length equal to Frame Size\n  For skippable frames ZSTD_getFrameHeader() returns zfhPtr->frameType==ZSTD_skippableFrame.\n  For skippable frames ZSTD_decompressContinue() always returns 0 : it only skips the content.\n*/\n\n/*=====   Buffer-less streaming decompression functions  =====*/\ntypedef enum { ZSTD_frame, ZSTD_skippableFrame } ZSTD_frameType_e;\ntypedef struct {\n    unsigned long long frameContentSize; /* if == ZSTD_CONTENTSIZE_UNKNOWN, it means this field is not available. 0 means \"empty\" */\n    unsigned long long windowSize;       /* can be very large, up to <= frameContentSize */\n    unsigned blockSizeMax;\n    ZSTD_frameType_e frameType;          /* if == ZSTD_skippableFrame, frameContentSize is the size of skippable content */\n    unsigned headerSize;\n    unsigned dictID;\n    unsigned checksumFlag;\n} ZSTD_frameHeader;\n\n/*! ZSTD_getFrameHeader() :\n *  decode Frame Header, or requires larger `srcSize`.\n * @return : 0, `zfhPtr` is correctly filled,\n *          >0, `srcSize` is too small, value is wanted `srcSize` amount,\n *           or an error code, which can be tested using ZSTD_isError() */\nZSTDLIB_API size_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize);   /**< doesn't consume input */\n/*! ZSTD_getFrameHeader_advanced() :\n *  same as ZSTD_getFrameHeader(),\n *  with added capability to select a format (like ZSTD_f_zstd1_magicless) */\nZSTDLIB_API size_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format);\nZSTDLIB_API size_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize);  /**< when frame content size is not known, pass in frameContentSize == ZSTD_CONTENTSIZE_UNKNOWN */\n\nZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);\nZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);\nZSTDLIB_API size_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);\n\nZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);\nZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);\n\n/* misc */\nZSTDLIB_API void   ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);\ntypedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;\nZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);\n\n\n\n\n/* ============================ */\n/**       Block level API       */\n/* ============================ */\n\n/*!\n    Block functions produce and decode raw zstd blocks, without frame metadata.\n    Frame metadata cost is typically ~12 bytes, which can be non-negligible for very small blocks (< 100 bytes).\n    But users will have to take in charge needed metadata to regenerate data, such as compressed and content sizes.\n\n    A few rules to respect :\n    - Compressing and decompressing require a context structure\n      + Use ZSTD_createCCtx() and ZSTD_createDCtx()\n    - It is necessary to init context before starting\n      + compression : any ZSTD_compressBegin*() variant, including with dictionary\n      + decompression : any ZSTD_decompressBegin*() variant, including with dictionary\n      + copyCCtx() and copyDCtx() can be used too\n    - Block size is limited, it must be <= ZSTD_getBlockSize() <= ZSTD_BLOCKSIZE_MAX == 128 KB\n      + If input is larger than a block size, it's necessary to split input data into multiple blocks\n      + For inputs larger than a single block, consider using regular ZSTD_compress() instead.\n        Frame metadata is not that costly, and quickly becomes negligible as source size grows larger than a block.\n    - When a block is considered not compressible enough, ZSTD_compressBlock() result will be 0 (zero) !\n      ===> In which case, nothing is produced into `dst` !\n      + User __must__ test for such outcome and deal directly with uncompressed data\n      + A block cannot be declared incompressible if ZSTD_compressBlock() return value was != 0.\n        Doing so would mess up with statistics history, leading to potential data corruption.\n      + ZSTD_decompressBlock() _doesn't accept uncompressed data as input_ !!\n      + In case of multiple successive blocks, should some of them be uncompressed,\n        decoder must be informed of their existence in order to follow proper history.\n        Use ZSTD_insertBlock() for such a case.\n*/\n\n/*=====   Raw zstd block functions  =====*/\nZSTDLIB_API size_t ZSTD_getBlockSize   (const ZSTD_CCtx* cctx);\nZSTDLIB_API size_t ZSTD_compressBlock  (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);\nZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);\nZSTDLIB_API size_t ZSTD_insertBlock    (ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize);  /**< insert uncompressed block into `dctx` history. Useful for multi-blocks decompression. */\n\n\n#endif   /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */\n\n#if defined (__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/mem.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef MEM_H_MODULE\n#define MEM_H_MODULE\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n/*-****************************************\n*  Dependencies\n******************************************/\n#include <stddef.h>     /* size_t, ptrdiff_t */\n#include <string.h>     /* memcpy */\n\n\n/*-****************************************\n*  Compiler specifics\n******************************************/\n#if defined(_MSC_VER)   /* Visual Studio */\n#   include <stdlib.h>  /* _byteswap_ulong */\n#   include <intrin.h>  /* _byteswap_* */\n#endif\n#if defined(__GNUC__)\n#  define MEM_STATIC static __inline __attribute__((unused))\n#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)\n#  define MEM_STATIC static inline\n#elif defined(_MSC_VER)\n#  define MEM_STATIC static __inline\n#else\n#  define MEM_STATIC static  /* this version may generate warnings for unused static functions; disable the relevant warning */\n#endif\n\n#ifndef __has_builtin\n#  define __has_builtin(x) 0  /* compat. with non-clang compilers */\n#endif\n\n/* code only tested on 32 and 64 bits systems */\n#define MEM_STATIC_ASSERT(c)   { enum { MEM_static_assert = 1/(int)(!!(c)) }; }\nMEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }\n\n/* detects whether we are being compiled under msan */\n#if defined (__has_feature)\n#  if __has_feature(memory_sanitizer)\n#    define MEMORY_SANITIZER 1\n#  endif\n#endif\n\n#if defined (MEMORY_SANITIZER)\n/* Not all platforms that support msan provide sanitizers/msan_interface.h.\n * We therefore declare the functions we need ourselves, rather than trying to\n * include the header file... */\n\n#include <stdint.h> /* intptr_t */\n\n/* Make memory region fully initialized (without changing its contents). */\nvoid __msan_unpoison(const volatile void *a, size_t size);\n\n/* Make memory region fully uninitialized (without changing its contents).\n   This is a legacy interface that does not update origin information. Use\n   __msan_allocated_memory() instead. */\nvoid __msan_poison(const volatile void *a, size_t size);\n\n/* Returns the offset of the first (at least partially) poisoned byte in the\n   memory range, or -1 if the whole range is good. */\nintptr_t __msan_test_shadow(const volatile void *x, size_t size);\n#endif\n\n/* detects whether we are being compiled under asan */\n#if defined (__has_feature)\n#  if __has_feature(address_sanitizer)\n#    define ADDRESS_SANITIZER 1\n#  endif\n#elif defined(__SANITIZE_ADDRESS__)\n#  define ADDRESS_SANITIZER 1\n#endif\n\n#if defined (ADDRESS_SANITIZER)\n/* Not all platforms that support asan provide sanitizers/asan_interface.h.\n * We therefore declare the functions we need ourselves, rather than trying to\n * include the header file... */\n\n/**\n * Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.\n *\n * This memory must be previously allocated by your program. Instrumented\n * code is forbidden from accessing addresses in this region until it is\n * unpoisoned. This function is not guaranteed to poison the entire region -\n * it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan\n * alignment restrictions.\n *\n * \\note This function is not thread-safe because no two threads can poison or\n * unpoison memory in the same memory region simultaneously.\n *\n * \\param addr Start of memory region.\n * \\param size Size of memory region. */\nvoid __asan_poison_memory_region(void const volatile *addr, size_t size);\n\n/**\n * Marks a memory region (<c>[addr, addr+size)</c>) as addressable.\n *\n * This memory must be previously allocated by your program. Accessing\n * addresses in this region is allowed until this region is poisoned again.\n * This function could unpoison a super-region of <c>[addr, addr+size)</c> due\n * to ASan alignment restrictions.\n *\n * \\note This function is not thread-safe because no two threads can\n * poison or unpoison memory in the same memory region simultaneously.\n *\n * \\param addr Start of memory region.\n * \\param size Size of memory region. */\nvoid __asan_unpoison_memory_region(void const volatile *addr, size_t size);\n#endif\n\n\n/*-**************************************************************\n*  Basic Types\n*****************************************************************/\n#if  !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )\n# include <stdint.h>\n  typedef   uint8_t BYTE;\n  typedef  uint16_t U16;\n  typedef   int16_t S16;\n  typedef  uint32_t U32;\n  typedef   int32_t S32;\n  typedef  uint64_t U64;\n  typedef   int64_t S64;\n#else\n# include <limits.h>\n#if CHAR_BIT != 8\n#  error \"this implementation requires char to be exactly 8-bit type\"\n#endif\n  typedef unsigned char      BYTE;\n#if USHRT_MAX != 65535\n#  error \"this implementation requires short to be exactly 16-bit type\"\n#endif\n  typedef unsigned short      U16;\n  typedef   signed short      S16;\n#if UINT_MAX != 4294967295\n#  error \"this implementation requires int to be exactly 32-bit type\"\n#endif\n  typedef unsigned int        U32;\n  typedef   signed int        S32;\n/* note : there are no limits defined for long long type in C90.\n * limits exist in C99, however, in such case, <stdint.h> is preferred */\n  typedef unsigned long long  U64;\n  typedef   signed long long  S64;\n#endif\n\n\n/*-**************************************************************\n*  Memory I/O\n*****************************************************************/\n/* MEM_FORCE_MEMORY_ACCESS :\n * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.\n * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.\n * The below switch allow to select different access method for improved performance.\n * Method 0 (default) : use `memcpy()`. Safe and portable.\n * Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable).\n *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.\n * Method 2 : direct access. This method is portable but violate C standard.\n *            It can generate buggy code on targets depending on alignment.\n *            In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6)\n * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.\n * Prefer these methods in priority order (0 > 1 > 2)\n */\n#ifndef MEM_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */\n#  if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )\n#    define MEM_FORCE_MEMORY_ACCESS 2\n#  elif defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__ICCARM__)\n#    define MEM_FORCE_MEMORY_ACCESS 1\n#  endif\n#endif\n\nMEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }\nMEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }\n\nMEM_STATIC unsigned MEM_isLittleEndian(void)\n{\n    const union { U32 u; BYTE c[4]; } one = { 1 };   /* don't use static : performance detrimental  */\n    return one.c[0];\n}\n\n#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)\n\n/* violates C standard, by lying on structure alignment.\nOnly use if no other choice to achieve best performance on target platform */\nMEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }\nMEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }\nMEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }\nMEM_STATIC size_t MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }\n\nMEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }\nMEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }\nMEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }\n\n#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)\n\n/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */\n/* currently only defined for gcc and icc */\n#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))\n    __pragma( pack(push, 1) )\n    typedef struct { U16 v; } unalign16;\n    typedef struct { U32 v; } unalign32;\n    typedef struct { U64 v; } unalign64;\n    typedef struct { size_t v; } unalignArch;\n    __pragma( pack(pop) )\n#else\n    typedef struct { U16 v; } __attribute__((packed)) unalign16;\n    typedef struct { U32 v; } __attribute__((packed)) unalign32;\n    typedef struct { U64 v; } __attribute__((packed)) unalign64;\n    typedef struct { size_t v; } __attribute__((packed)) unalignArch;\n#endif\n\nMEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign16*)ptr)->v; }\nMEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign32*)ptr)->v; }\nMEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign64*)ptr)->v; }\nMEM_STATIC size_t MEM_readST(const void* ptr) { return ((const unalignArch*)ptr)->v; }\n\nMEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign16*)memPtr)->v = value; }\nMEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign32*)memPtr)->v = value; }\nMEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign64*)memPtr)->v = value; }\n\n#else\n\n/* default method, safe and standard.\n   can sometimes prove slower */\n\nMEM_STATIC U16 MEM_read16(const void* memPtr)\n{\n    U16 val; memcpy(&val, memPtr, sizeof(val)); return val;\n}\n\nMEM_STATIC U32 MEM_read32(const void* memPtr)\n{\n    U32 val; memcpy(&val, memPtr, sizeof(val)); return val;\n}\n\nMEM_STATIC U64 MEM_read64(const void* memPtr)\n{\n    U64 val; memcpy(&val, memPtr, sizeof(val)); return val;\n}\n\nMEM_STATIC size_t MEM_readST(const void* memPtr)\n{\n    size_t val; memcpy(&val, memPtr, sizeof(val)); return val;\n}\n\nMEM_STATIC void MEM_write16(void* memPtr, U16 value)\n{\n    memcpy(memPtr, &value, sizeof(value));\n}\n\nMEM_STATIC void MEM_write32(void* memPtr, U32 value)\n{\n    memcpy(memPtr, &value, sizeof(value));\n}\n\nMEM_STATIC void MEM_write64(void* memPtr, U64 value)\n{\n    memcpy(memPtr, &value, sizeof(value));\n}\n\n#endif /* MEM_FORCE_MEMORY_ACCESS */\n\nMEM_STATIC U32 MEM_swap32(U32 in)\n{\n#if defined(_MSC_VER)     /* Visual Studio */\n    return _byteswap_ulong(in);\n#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \\\n  || (defined(__clang__) && __has_builtin(__builtin_bswap32))\n    return __builtin_bswap32(in);\n#else\n    return  ((in << 24) & 0xff000000 ) |\n            ((in <<  8) & 0x00ff0000 ) |\n            ((in >>  8) & 0x0000ff00 ) |\n            ((in >> 24) & 0x000000ff );\n#endif\n}\n\nMEM_STATIC U64 MEM_swap64(U64 in)\n{\n#if defined(_MSC_VER)     /* Visual Studio */\n    return _byteswap_uint64(in);\n#elif (defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)) \\\n  || (defined(__clang__) && __has_builtin(__builtin_bswap64))\n    return __builtin_bswap64(in);\n#else\n    return  ((in << 56) & 0xff00000000000000ULL) |\n            ((in << 40) & 0x00ff000000000000ULL) |\n            ((in << 24) & 0x0000ff0000000000ULL) |\n            ((in << 8)  & 0x000000ff00000000ULL) |\n            ((in >> 8)  & 0x00000000ff000000ULL) |\n            ((in >> 24) & 0x0000000000ff0000ULL) |\n            ((in >> 40) & 0x000000000000ff00ULL) |\n            ((in >> 56) & 0x00000000000000ffULL);\n#endif\n}\n\nMEM_STATIC size_t MEM_swapST(size_t in)\n{\n    if (MEM_32bits())\n        return (size_t)MEM_swap32((U32)in);\n    else\n        return (size_t)MEM_swap64((U64)in);\n}\n\n/*=== Little endian r/w ===*/\n\nMEM_STATIC U16 MEM_readLE16(const void* memPtr)\n{\n    if (MEM_isLittleEndian())\n        return MEM_read16(memPtr);\n    else {\n        const BYTE* p = (const BYTE*)memPtr;\n        return (U16)(p[0] + (p[1]<<8));\n    }\n}\n\nMEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)\n{\n    if (MEM_isLittleEndian()) {\n        MEM_write16(memPtr, val);\n    } else {\n        BYTE* p = (BYTE*)memPtr;\n        p[0] = (BYTE)val;\n        p[1] = (BYTE)(val>>8);\n    }\n}\n\nMEM_STATIC U32 MEM_readLE24(const void* memPtr)\n{\n    return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);\n}\n\nMEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)\n{\n    MEM_writeLE16(memPtr, (U16)val);\n    ((BYTE*)memPtr)[2] = (BYTE)(val>>16);\n}\n\nMEM_STATIC U32 MEM_readLE32(const void* memPtr)\n{\n    if (MEM_isLittleEndian())\n        return MEM_read32(memPtr);\n    else\n        return MEM_swap32(MEM_read32(memPtr));\n}\n\nMEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)\n{\n    if (MEM_isLittleEndian())\n        MEM_write32(memPtr, val32);\n    else\n        MEM_write32(memPtr, MEM_swap32(val32));\n}\n\nMEM_STATIC U64 MEM_readLE64(const void* memPtr)\n{\n    if (MEM_isLittleEndian())\n        return MEM_read64(memPtr);\n    else\n        return MEM_swap64(MEM_read64(memPtr));\n}\n\nMEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)\n{\n    if (MEM_isLittleEndian())\n        MEM_write64(memPtr, val64);\n    else\n        MEM_write64(memPtr, MEM_swap64(val64));\n}\n\nMEM_STATIC size_t MEM_readLEST(const void* memPtr)\n{\n    if (MEM_32bits())\n        return (size_t)MEM_readLE32(memPtr);\n    else\n        return (size_t)MEM_readLE64(memPtr);\n}\n\nMEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)\n{\n    if (MEM_32bits())\n        MEM_writeLE32(memPtr, (U32)val);\n    else\n        MEM_writeLE64(memPtr, (U64)val);\n}\n\n/*=== Big endian r/w ===*/\n\nMEM_STATIC U32 MEM_readBE32(const void* memPtr)\n{\n    if (MEM_isLittleEndian())\n        return MEM_swap32(MEM_read32(memPtr));\n    else\n        return MEM_read32(memPtr);\n}\n\nMEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)\n{\n    if (MEM_isLittleEndian())\n        MEM_write32(memPtr, MEM_swap32(val32));\n    else\n        MEM_write32(memPtr, val32);\n}\n\nMEM_STATIC U64 MEM_readBE64(const void* memPtr)\n{\n    if (MEM_isLittleEndian())\n        return MEM_swap64(MEM_read64(memPtr));\n    else\n        return MEM_read64(memPtr);\n}\n\nMEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)\n{\n    if (MEM_isLittleEndian())\n        MEM_write64(memPtr, MEM_swap64(val64));\n    else\n        MEM_write64(memPtr, val64);\n}\n\nMEM_STATIC size_t MEM_readBEST(const void* memPtr)\n{\n    if (MEM_32bits())\n        return (size_t)MEM_readBE32(memPtr);\n    else\n        return (size_t)MEM_readBE64(memPtr);\n}\n\nMEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)\n{\n    if (MEM_32bits())\n        MEM_writeBE32(memPtr, (U32)val);\n    else\n        MEM_writeBE64(memPtr, (U64)val);\n}\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* MEM_H_MODULE */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/pool.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n\n/* ======   Dependencies   ======= */\n#include <stddef.h>    /* size_t */\n#include \"debug.h\"     /* assert */\n#include \"zstd_internal.h\"  /* ZSTD_malloc, ZSTD_free */\n#include \"pool.h\"\n\n/* ======   Compiler specifics   ====== */\n#if defined(_MSC_VER)\n#  pragma warning(disable : 4204)        /* disable: C4204: non-constant aggregate initializer */\n#endif\n\n\n#ifdef ZSTD_MULTITHREAD\n\n#include \"threading.h\"   /* pthread adaptation */\n\n/* A job is a function and an opaque argument */\ntypedef struct POOL_job_s {\n    POOL_function function;\n    void *opaque;\n} POOL_job;\n\nstruct POOL_ctx_s {\n    ZSTD_customMem customMem;\n    /* Keep track of the threads */\n    ZSTD_pthread_t* threads;\n    size_t threadCapacity;\n    size_t threadLimit;\n\n    /* The queue is a circular buffer */\n    POOL_job *queue;\n    size_t queueHead;\n    size_t queueTail;\n    size_t queueSize;\n\n    /* The number of threads working on jobs */\n    size_t numThreadsBusy;\n    /* Indicates if the queue is empty */\n    int queueEmpty;\n\n    /* The mutex protects the queue */\n    ZSTD_pthread_mutex_t queueMutex;\n    /* Condition variable for pushers to wait on when the queue is full */\n    ZSTD_pthread_cond_t queuePushCond;\n    /* Condition variables for poppers to wait on when the queue is empty */\n    ZSTD_pthread_cond_t queuePopCond;\n    /* Indicates if the queue is shutting down */\n    int shutdown;\n};\n\n/* POOL_thread() :\n * Work thread for the thread pool.\n * Waits for jobs and executes them.\n * @returns : NULL on failure else non-null.\n */\nstatic void* POOL_thread(void* opaque) {\n    POOL_ctx* const ctx = (POOL_ctx*)opaque;\n    if (!ctx) { return NULL; }\n    for (;;) {\n        /* Lock the mutex and wait for a non-empty queue or until shutdown */\n        ZSTD_pthread_mutex_lock(&ctx->queueMutex);\n\n        while ( ctx->queueEmpty\n            || (ctx->numThreadsBusy >= ctx->threadLimit) ) {\n            if (ctx->shutdown) {\n                /* even if !queueEmpty, (possible if numThreadsBusy >= threadLimit),\n                 * a few threads will be shutdown while !queueEmpty,\n                 * but enough threads will remain active to finish the queue */\n                ZSTD_pthread_mutex_unlock(&ctx->queueMutex);\n                return opaque;\n            }\n            ZSTD_pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);\n        }\n        /* Pop a job off the queue */\n        {   POOL_job const job = ctx->queue[ctx->queueHead];\n            ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;\n            ctx->numThreadsBusy++;\n            ctx->queueEmpty = ctx->queueHead == ctx->queueTail;\n            /* Unlock the mutex, signal a pusher, and run the job */\n            ZSTD_pthread_cond_signal(&ctx->queuePushCond);\n            ZSTD_pthread_mutex_unlock(&ctx->queueMutex);\n\n            job.function(job.opaque);\n\n            /* If the intended queue size was 0, signal after finishing job */\n            ZSTD_pthread_mutex_lock(&ctx->queueMutex);\n            ctx->numThreadsBusy--;\n            if (ctx->queueSize == 1) {\n                ZSTD_pthread_cond_signal(&ctx->queuePushCond);\n            }\n            ZSTD_pthread_mutex_unlock(&ctx->queueMutex);\n        }\n    }  /* for (;;) */\n    assert(0);  /* Unreachable */\n}\n\nPOOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {\n    return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);\n}\n\nPOOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,\n                               ZSTD_customMem customMem) {\n    POOL_ctx* ctx;\n    /* Check parameters */\n    if (!numThreads) { return NULL; }\n    /* Allocate the context and zero initialize */\n    ctx = (POOL_ctx*)ZSTD_calloc(sizeof(POOL_ctx), customMem);\n    if (!ctx) { return NULL; }\n    /* Initialize the job queue.\n     * It needs one extra space since one space is wasted to differentiate\n     * empty and full queues.\n     */\n    ctx->queueSize = queueSize + 1;\n    ctx->queue = (POOL_job*)ZSTD_malloc(ctx->queueSize * sizeof(POOL_job), customMem);\n    ctx->queueHead = 0;\n    ctx->queueTail = 0;\n    ctx->numThreadsBusy = 0;\n    ctx->queueEmpty = 1;\n    {\n        int error = 0;\n        error |= ZSTD_pthread_mutex_init(&ctx->queueMutex, NULL);\n        error |= ZSTD_pthread_cond_init(&ctx->queuePushCond, NULL);\n        error |= ZSTD_pthread_cond_init(&ctx->queuePopCond, NULL);\n        if (error) { POOL_free(ctx); return NULL; }\n    }\n    ctx->shutdown = 0;\n    /* Allocate space for the thread handles */\n    ctx->threads = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), customMem);\n    ctx->threadCapacity = 0;\n    ctx->customMem = customMem;\n    /* Check for errors */\n    if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }\n    /* Initialize the threads */\n    {   size_t i;\n        for (i = 0; i < numThreads; ++i) {\n            if (ZSTD_pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {\n                ctx->threadCapacity = i;\n                POOL_free(ctx);\n                return NULL;\n        }   }\n        ctx->threadCapacity = numThreads;\n        ctx->threadLimit = numThreads;\n    }\n    return ctx;\n}\n\n/*! POOL_join() :\n    Shutdown the queue, wake any sleeping threads, and join all of the threads.\n*/\nstatic void POOL_join(POOL_ctx* ctx) {\n    /* Shut down the queue */\n    ZSTD_pthread_mutex_lock(&ctx->queueMutex);\n    ctx->shutdown = 1;\n    ZSTD_pthread_mutex_unlock(&ctx->queueMutex);\n    /* Wake up sleeping threads */\n    ZSTD_pthread_cond_broadcast(&ctx->queuePushCond);\n    ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);\n    /* Join all of the threads */\n    {   size_t i;\n        for (i = 0; i < ctx->threadCapacity; ++i) {\n            ZSTD_pthread_join(ctx->threads[i], NULL);  /* note : could fail */\n    }   }\n}\n\nvoid POOL_free(POOL_ctx *ctx) {\n    if (!ctx) { return; }\n    POOL_join(ctx);\n    ZSTD_pthread_mutex_destroy(&ctx->queueMutex);\n    ZSTD_pthread_cond_destroy(&ctx->queuePushCond);\n    ZSTD_pthread_cond_destroy(&ctx->queuePopCond);\n    ZSTD_free(ctx->queue, ctx->customMem);\n    ZSTD_free(ctx->threads, ctx->customMem);\n    ZSTD_free(ctx, ctx->customMem);\n}\n\n\n\nsize_t POOL_sizeof(POOL_ctx *ctx) {\n    if (ctx==NULL) return 0;  /* supports sizeof NULL */\n    return sizeof(*ctx)\n        + ctx->queueSize * sizeof(POOL_job)\n        + ctx->threadCapacity * sizeof(ZSTD_pthread_t);\n}\n\n\n/* @return : 0 on success, 1 on error */\nstatic int POOL_resize_internal(POOL_ctx* ctx, size_t numThreads)\n{\n    if (numThreads <= ctx->threadCapacity) {\n        if (!numThreads) return 1;\n        ctx->threadLimit = numThreads;\n        return 0;\n    }\n    /* numThreads > threadCapacity */\n    {   ZSTD_pthread_t* const threadPool = (ZSTD_pthread_t*)ZSTD_malloc(numThreads * sizeof(ZSTD_pthread_t), ctx->customMem);\n        if (!threadPool) return 1;\n        /* replace existing thread pool */\n        memcpy(threadPool, ctx->threads, ctx->threadCapacity * sizeof(*threadPool));\n        ZSTD_free(ctx->threads, ctx->customMem);\n        ctx->threads = threadPool;\n        /* Initialize additional threads */\n        {   size_t threadId;\n            for (threadId = ctx->threadCapacity; threadId < numThreads; ++threadId) {\n                if (ZSTD_pthread_create(&threadPool[threadId], NULL, &POOL_thread, ctx)) {\n                    ctx->threadCapacity = threadId;\n                    return 1;\n            }   }\n    }   }\n    /* successfully expanded */\n    ctx->threadCapacity = numThreads;\n    ctx->threadLimit = numThreads;\n    return 0;\n}\n\n/* @return : 0 on success, 1 on error */\nint POOL_resize(POOL_ctx* ctx, size_t numThreads)\n{\n    int result;\n    if (ctx==NULL) return 1;\n    ZSTD_pthread_mutex_lock(&ctx->queueMutex);\n    result = POOL_resize_internal(ctx, numThreads);\n    ZSTD_pthread_cond_broadcast(&ctx->queuePopCond);\n    ZSTD_pthread_mutex_unlock(&ctx->queueMutex);\n    return result;\n}\n\n/**\n * Returns 1 if the queue is full and 0 otherwise.\n *\n * When queueSize is 1 (pool was created with an intended queueSize of 0),\n * then a queue is empty if there is a thread free _and_ no job is waiting.\n */\nstatic int isQueueFull(POOL_ctx const* ctx) {\n    if (ctx->queueSize > 1) {\n        return ctx->queueHead == ((ctx->queueTail + 1) % ctx->queueSize);\n    } else {\n        return (ctx->numThreadsBusy == ctx->threadLimit) ||\n               !ctx->queueEmpty;\n    }\n}\n\n\nstatic void POOL_add_internal(POOL_ctx* ctx, POOL_function function, void *opaque)\n{\n    POOL_job const job = {function, opaque};\n    assert(ctx != NULL);\n    if (ctx->shutdown) return;\n\n    ctx->queueEmpty = 0;\n    ctx->queue[ctx->queueTail] = job;\n    ctx->queueTail = (ctx->queueTail + 1) % ctx->queueSize;\n    ZSTD_pthread_cond_signal(&ctx->queuePopCond);\n}\n\nvoid POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque)\n{\n    assert(ctx != NULL);\n    ZSTD_pthread_mutex_lock(&ctx->queueMutex);\n    /* Wait until there is space in the queue for the new job */\n    while (isQueueFull(ctx) && (!ctx->shutdown)) {\n        ZSTD_pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);\n    }\n    POOL_add_internal(ctx, function, opaque);\n    ZSTD_pthread_mutex_unlock(&ctx->queueMutex);\n}\n\n\nint POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque)\n{\n    assert(ctx != NULL);\n    ZSTD_pthread_mutex_lock(&ctx->queueMutex);\n    if (isQueueFull(ctx)) {\n        ZSTD_pthread_mutex_unlock(&ctx->queueMutex);\n        return 0;\n    }\n    POOL_add_internal(ctx, function, opaque);\n    ZSTD_pthread_mutex_unlock(&ctx->queueMutex);\n    return 1;\n}\n\n\n#else  /* ZSTD_MULTITHREAD  not defined */\n\n/* ========================== */\n/* No multi-threading support */\n/* ========================== */\n\n\n/* We don't need any data, but if it is empty, malloc() might return NULL. */\nstruct POOL_ctx_s {\n    int dummy;\n};\nstatic POOL_ctx g_ctx;\n\nPOOL_ctx* POOL_create(size_t numThreads, size_t queueSize) {\n    return POOL_create_advanced(numThreads, queueSize, ZSTD_defaultCMem);\n}\n\nPOOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize, ZSTD_customMem customMem) {\n    (void)numThreads;\n    (void)queueSize;\n    (void)customMem;\n    return &g_ctx;\n}\n\nvoid POOL_free(POOL_ctx* ctx) {\n    assert(!ctx || ctx == &g_ctx);\n    (void)ctx;\n}\n\nint POOL_resize(POOL_ctx* ctx, size_t numThreads) {\n    (void)ctx; (void)numThreads;\n    return 0;\n}\n\nvoid POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque) {\n    (void)ctx;\n    function(opaque);\n}\n\nint POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque) {\n    (void)ctx;\n    function(opaque);\n    return 1;\n}\n\nsize_t POOL_sizeof(POOL_ctx* ctx) {\n    if (ctx==NULL) return 0;  /* supports sizeof NULL */\n    assert(ctx == &g_ctx);\n    return sizeof(*ctx);\n}\n\n#endif  /* ZSTD_MULTITHREAD */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/pool.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef POOL_H\n#define POOL_H\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n\n#include <stddef.h>   /* size_t */\n#define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_customMem */\n#include \"zstd.h\"\n\ntypedef struct POOL_ctx_s POOL_ctx;\n\n/*! POOL_create() :\n *  Create a thread pool with at most `numThreads` threads.\n * `numThreads` must be at least 1.\n *  The maximum number of queued jobs before blocking is `queueSize`.\n * @return : POOL_ctx pointer on success, else NULL.\n*/\nPOOL_ctx* POOL_create(size_t numThreads, size_t queueSize);\n\nPOOL_ctx* POOL_create_advanced(size_t numThreads, size_t queueSize,\n                               ZSTD_customMem customMem);\n\n/*! POOL_free() :\n *  Free a thread pool returned by POOL_create().\n */\nvoid POOL_free(POOL_ctx* ctx);\n\n/*! POOL_resize() :\n *  Expands or shrinks pool's number of threads.\n *  This is more efficient than releasing + creating a new context,\n *  since it tries to preserve and re-use existing threads.\n * `numThreads` must be at least 1.\n * @return : 0 when resize was successful,\n *           !0 (typically 1) if there is an error.\n *    note : only numThreads can be resized, queueSize remains unchanged.\n */\nint POOL_resize(POOL_ctx* ctx, size_t numThreads);\n\n/*! POOL_sizeof() :\n * @return threadpool memory usage\n *  note : compatible with NULL (returns 0 in this case)\n */\nsize_t POOL_sizeof(POOL_ctx* ctx);\n\n/*! POOL_function :\n *  The function type that can be added to a thread pool.\n */\ntypedef void (*POOL_function)(void*);\n\n/*! POOL_add() :\n *  Add the job `function(opaque)` to the thread pool. `ctx` must be valid.\n *  Possibly blocks until there is room in the queue.\n *  Note : The function may be executed asynchronously,\n *         therefore, `opaque` must live until function has been completed.\n */\nvoid POOL_add(POOL_ctx* ctx, POOL_function function, void* opaque);\n\n\n/*! POOL_tryAdd() :\n *  Add the job `function(opaque)` to thread pool _if_ a worker is available.\n *  Returns immediately even if not (does not block).\n * @return : 1 if successful, 0 if not.\n */\nint POOL_tryAdd(POOL_ctx* ctx, POOL_function function, void* opaque);\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/threading.c",
    "content": "/**\n * Copyright (c) 2016 Tino Reichardt\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n *\n * You can contact the author at:\n * - zstdmt source repository: https://github.com/mcmilk/zstdmt\n */\n\n/**\n * This file will hold wrapper for systems, which do not support pthreads\n */\n\n#include \"threading.h\"\n\n/* create fake symbol to avoid empty translation unit warning */\nint g_ZSTD_threading_useless_symbol;\n\n#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)\n\n/**\n * Windows minimalist Pthread Wrapper, based on :\n * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html\n */\n\n\n/* ===  Dependencies  === */\n#include <process.h>\n#include <errno.h>\n\n\n/* ===  Implementation  === */\n\nstatic unsigned __stdcall worker(void *arg)\n{\n    ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;\n    thread->arg = thread->start_routine(thread->arg);\n    return 0;\n}\n\nint ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,\n            void* (*start_routine) (void*), void* arg)\n{\n    (void)unused;\n    thread->arg = arg;\n    thread->start_routine = start_routine;\n    thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);\n\n    if (!thread->handle)\n        return errno;\n    else\n        return 0;\n}\n\nint ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)\n{\n    DWORD result;\n\n    if (!thread.handle) return 0;\n\n    result = WaitForSingleObject(thread.handle, INFINITE);\n    switch (result) {\n    case WAIT_OBJECT_0:\n        if (value_ptr) *value_ptr = thread.arg;\n        return 0;\n    case WAIT_ABANDONED:\n        return EINVAL;\n    default:\n        return GetLastError();\n    }\n}\n\n#endif   /* ZSTD_MULTITHREAD */\n\n#if defined(ZSTD_MULTITHREAD) && DEBUGLEVEL >= 1 && !defined(_WIN32)\n\n#include <stdlib.h>\n\nint ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr)\n{\n    *mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));\n    if (!*mutex)\n        return 1;\n    return pthread_mutex_init(*mutex, attr);\n}\n\nint ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex)\n{\n    if (!*mutex)\n        return 0;\n    {\n        int const ret = pthread_mutex_destroy(*mutex);\n        free(*mutex);\n        return ret;\n    }\n}\n\nint ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr)\n{\n    *cond = (pthread_cond_t*)malloc(sizeof(pthread_cond_t));\n    if (!*cond)\n        return 1;\n    return pthread_cond_init(*cond, attr);\n}\n\nint ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond)\n{\n    if (!*cond)\n        return 0;\n    {\n        int const ret = pthread_cond_destroy(*cond);\n        free(*cond);\n        return ret;\n    }\n}\n\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/threading.h",
    "content": "/**\n * Copyright (c) 2016 Tino Reichardt\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n *\n * You can contact the author at:\n * - zstdmt source repository: https://github.com/mcmilk/zstdmt\n */\n\n#ifndef THREADING_H_938743\n#define THREADING_H_938743\n\n#include \"debug.h\"\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)\n\n/**\n * Windows minimalist Pthread Wrapper, based on :\n * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html\n */\n#ifdef WINVER\n#  undef WINVER\n#endif\n#define WINVER       0x0600\n\n#ifdef _WIN32_WINNT\n#  undef _WIN32_WINNT\n#endif\n#define _WIN32_WINNT 0x0600\n\n#ifndef WIN32_LEAN_AND_MEAN\n#  define WIN32_LEAN_AND_MEAN\n#endif\n\n#undef ERROR   /* reported already defined on VS 2015 (Rich Geldreich) */\n#include <windows.h>\n#undef ERROR\n#define ERROR(name) ZSTD_ERROR(name)\n\n\n/* mutex */\n#define ZSTD_pthread_mutex_t           CRITICAL_SECTION\n#define ZSTD_pthread_mutex_init(a, b)  ((void)(b), InitializeCriticalSection((a)), 0)\n#define ZSTD_pthread_mutex_destroy(a)  DeleteCriticalSection((a))\n#define ZSTD_pthread_mutex_lock(a)     EnterCriticalSection((a))\n#define ZSTD_pthread_mutex_unlock(a)   LeaveCriticalSection((a))\n\n/* condition variable */\n#define ZSTD_pthread_cond_t             CONDITION_VARIABLE\n#define ZSTD_pthread_cond_init(a, b)    ((void)(b), InitializeConditionVariable((a)), 0)\n#define ZSTD_pthread_cond_destroy(a)    ((void)(a))\n#define ZSTD_pthread_cond_wait(a, b)    SleepConditionVariableCS((a), (b), INFINITE)\n#define ZSTD_pthread_cond_signal(a)     WakeConditionVariable((a))\n#define ZSTD_pthread_cond_broadcast(a)  WakeAllConditionVariable((a))\n\n/* ZSTD_pthread_create() and ZSTD_pthread_join() */\ntypedef struct {\n    HANDLE handle;\n    void* (*start_routine)(void*);\n    void* arg;\n} ZSTD_pthread_t;\n\nint ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,\n                   void* (*start_routine) (void*), void* arg);\n\nint ZSTD_pthread_join(ZSTD_pthread_t thread, void** value_ptr);\n\n/**\n * add here more wrappers as required\n */\n\n\n#elif defined(ZSTD_MULTITHREAD)    /* posix assumed ; need a better detection method */\n/* ===   POSIX Systems   === */\n#  include <pthread.h>\n\n#if DEBUGLEVEL < 1\n\n#define ZSTD_pthread_mutex_t            pthread_mutex_t\n#define ZSTD_pthread_mutex_init(a, b)   pthread_mutex_init((a), (b))\n#define ZSTD_pthread_mutex_destroy(a)   pthread_mutex_destroy((a))\n#define ZSTD_pthread_mutex_lock(a)      pthread_mutex_lock((a))\n#define ZSTD_pthread_mutex_unlock(a)    pthread_mutex_unlock((a))\n\n#define ZSTD_pthread_cond_t             pthread_cond_t\n#define ZSTD_pthread_cond_init(a, b)    pthread_cond_init((a), (b))\n#define ZSTD_pthread_cond_destroy(a)    pthread_cond_destroy((a))\n#define ZSTD_pthread_cond_wait(a, b)    pthread_cond_wait((a), (b))\n#define ZSTD_pthread_cond_signal(a)     pthread_cond_signal((a))\n#define ZSTD_pthread_cond_broadcast(a)  pthread_cond_broadcast((a))\n\n#define ZSTD_pthread_t                  pthread_t\n#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))\n#define ZSTD_pthread_join(a, b)         pthread_join((a),(b))\n\n#else /* DEBUGLEVEL >= 1 */\n\n/* Debug implementation of threading.\n * In this implementation we use pointers for mutexes and condition variables.\n * This way, if we forget to init/destroy them the program will crash or ASAN\n * will report leaks.\n */\n\n#define ZSTD_pthread_mutex_t            pthread_mutex_t*\nint ZSTD_pthread_mutex_init(ZSTD_pthread_mutex_t* mutex, pthread_mutexattr_t const* attr);\nint ZSTD_pthread_mutex_destroy(ZSTD_pthread_mutex_t* mutex);\n#define ZSTD_pthread_mutex_lock(a)      pthread_mutex_lock(*(a))\n#define ZSTD_pthread_mutex_unlock(a)    pthread_mutex_unlock(*(a))\n\n#define ZSTD_pthread_cond_t             pthread_cond_t*\nint ZSTD_pthread_cond_init(ZSTD_pthread_cond_t* cond, pthread_condattr_t const* attr);\nint ZSTD_pthread_cond_destroy(ZSTD_pthread_cond_t* cond);\n#define ZSTD_pthread_cond_wait(a, b)    pthread_cond_wait(*(a), *(b))\n#define ZSTD_pthread_cond_signal(a)     pthread_cond_signal(*(a))\n#define ZSTD_pthread_cond_broadcast(a)  pthread_cond_broadcast(*(a))\n\n#define ZSTD_pthread_t                  pthread_t\n#define ZSTD_pthread_create(a, b, c, d) pthread_create((a), (b), (c), (d))\n#define ZSTD_pthread_join(a, b)         pthread_join((a),(b))\n\n#endif\n\n#else  /* ZSTD_MULTITHREAD not defined */\n/* No multithreading support */\n\ntypedef int ZSTD_pthread_mutex_t;\n#define ZSTD_pthread_mutex_init(a, b)   ((void)(a), (void)(b), 0)\n#define ZSTD_pthread_mutex_destroy(a)   ((void)(a))\n#define ZSTD_pthread_mutex_lock(a)      ((void)(a))\n#define ZSTD_pthread_mutex_unlock(a)    ((void)(a))\n\ntypedef int ZSTD_pthread_cond_t;\n#define ZSTD_pthread_cond_init(a, b)    ((void)(a), (void)(b), 0)\n#define ZSTD_pthread_cond_destroy(a)    ((void)(a))\n#define ZSTD_pthread_cond_wait(a, b)    ((void)(a), (void)(b))\n#define ZSTD_pthread_cond_signal(a)     ((void)(a))\n#define ZSTD_pthread_cond_broadcast(a)  ((void)(a))\n\n/* do not use ZSTD_pthread_t */\n\n#endif /* ZSTD_MULTITHREAD */\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* THREADING_H_938743 */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/xxhash.c",
    "content": "/*\n*  xxHash - Fast Hash algorithm\n*  Copyright (C) 2012-2016, Yann Collet\n*\n*  BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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*\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*\n*  You can contact the author at :\n*  - xxHash homepage: http://www.xxhash.com\n*  - xxHash source repository : https://github.com/Cyan4973/xxHash\n*/\n\n\n/* *************************************\n*  Tuning parameters\n***************************************/\n/*!XXH_FORCE_MEMORY_ACCESS :\n * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.\n * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.\n * The below switch allow to select different access method for improved performance.\n * Method 0 (default) : use `memcpy()`. Safe and portable.\n * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).\n *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.\n * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.\n *            It can generate buggy code on targets which do not support unaligned memory accesses.\n *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)\n * See http://stackoverflow.com/a/32095106/646947 for details.\n * Prefer these methods in priority order (0 > 1 > 2)\n */\n#ifndef XXH_FORCE_MEMORY_ACCESS   /* can be defined externally, on command line for example */\n#  if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )\n#    define XXH_FORCE_MEMORY_ACCESS 2\n#  elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \\\n  (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) )) || \\\n  defined(__ICCARM__)\n#    define XXH_FORCE_MEMORY_ACCESS 1\n#  endif\n#endif\n\n/*!XXH_ACCEPT_NULL_INPUT_POINTER :\n * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.\n * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.\n * By default, this option is disabled. To enable it, uncomment below define :\n */\n/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */\n\n/*!XXH_FORCE_NATIVE_FORMAT :\n * By default, xxHash library provides endian-independent Hash values, based on little-endian convention.\n * Results are therefore identical for little-endian and big-endian CPU.\n * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.\n * Should endian-independence be of no importance for your application, you may set the #define below to 1,\n * to improve speed for Big-endian CPU.\n * This option has no impact on Little_Endian CPU.\n */\n#ifndef XXH_FORCE_NATIVE_FORMAT   /* can be defined externally */\n#  define XXH_FORCE_NATIVE_FORMAT 0\n#endif\n\n/*!XXH_FORCE_ALIGN_CHECK :\n * This is a minor performance trick, only useful with lots of very small keys.\n * It means : check for aligned/unaligned input.\n * The check costs one initial branch per hash; set to 0 when the input data\n * is guaranteed to be aligned.\n */\n#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */\n#  if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)\n#    define XXH_FORCE_ALIGN_CHECK 0\n#  else\n#    define XXH_FORCE_ALIGN_CHECK 1\n#  endif\n#endif\n\n\n/* *************************************\n*  Includes & Memory related functions\n***************************************/\n/* Modify the local functions below should you wish to use some other memory routines */\n/* for malloc(), free() */\n#include <stdlib.h>\n#include <stddef.h>     /* size_t */\nstatic void* XXH_malloc(size_t s) { return malloc(s); }\nstatic void  XXH_free  (void* p)  { free(p); }\n/* for memcpy() */\n#include <string.h>\nstatic void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }\n\n#ifndef XXH_STATIC_LINKING_ONLY\n#  define XXH_STATIC_LINKING_ONLY\n#endif\n#include \"xxhash.h\"\n\n\n/* *************************************\n*  Compiler Specific Options\n***************************************/\n#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */\n#  define INLINE_KEYWORD inline\n#else\n#  define INLINE_KEYWORD\n#endif\n\n#if defined(__GNUC__) || defined(__ICCARM__)\n#  define FORCE_INLINE_ATTR __attribute__((always_inline))\n#elif defined(_MSC_VER)\n#  define FORCE_INLINE_ATTR __forceinline\n#else\n#  define FORCE_INLINE_ATTR\n#endif\n\n#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR\n\n\n#ifdef _MSC_VER\n#  pragma warning(disable : 4127)      /* disable: C4127: conditional expression is constant */\n#endif\n\n\n/* *************************************\n*  Basic Types\n***************************************/\n#ifndef MEM_MODULE\n# define MEM_MODULE\n# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )\n#   include <stdint.h>\n    typedef uint8_t  BYTE;\n    typedef uint16_t U16;\n    typedef uint32_t U32;\n    typedef  int32_t S32;\n    typedef uint64_t U64;\n#  else\n    typedef unsigned char      BYTE;\n    typedef unsigned short     U16;\n    typedef unsigned int       U32;\n    typedef   signed int       S32;\n    typedef unsigned long long U64;   /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */\n#  endif\n#endif\n\n\n#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))\n\n/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */\nstatic U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }\nstatic U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }\n\n#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))\n\n/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */\n/* currently only defined for gcc and icc */\ntypedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign;\n\nstatic U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }\nstatic U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }\n\n#else\n\n/* portable and safe solution. Generally efficient.\n * see : http://stackoverflow.com/a/32095106/646947\n */\n\nstatic U32 XXH_read32(const void* memPtr)\n{\n    U32 val;\n    memcpy(&val, memPtr, sizeof(val));\n    return val;\n}\n\nstatic U64 XXH_read64(const void* memPtr)\n{\n    U64 val;\n    memcpy(&val, memPtr, sizeof(val));\n    return val;\n}\n\n#endif   /* XXH_FORCE_DIRECT_MEMORY_ACCESS */\n\n\n/* ****************************************\n*  Compiler-specific Functions and Macros\n******************************************/\n#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)\n\n/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */\n#if defined(_MSC_VER)\n#  define XXH_rotl32(x,r) _rotl(x,r)\n#  define XXH_rotl64(x,r) _rotl64(x,r)\n#else\n#if defined(__ICCARM__)\n#  include <intrinsics.h>\n#  define XXH_rotl32(x,r) __ROR(x,(32 - r))\n#else\n#  define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))\n#endif\n#  define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))\n#endif\n\n#if defined(_MSC_VER)     /* Visual Studio */\n#  define XXH_swap32 _byteswap_ulong\n#  define XXH_swap64 _byteswap_uint64\n#elif GCC_VERSION >= 403\n#  define XXH_swap32 __builtin_bswap32\n#  define XXH_swap64 __builtin_bswap64\n#else\nstatic U32 XXH_swap32 (U32 x)\n{\n    return  ((x << 24) & 0xff000000 ) |\n            ((x <<  8) & 0x00ff0000 ) |\n            ((x >>  8) & 0x0000ff00 ) |\n            ((x >> 24) & 0x000000ff );\n}\nstatic U64 XXH_swap64 (U64 x)\n{\n    return  ((x << 56) & 0xff00000000000000ULL) |\n            ((x << 40) & 0x00ff000000000000ULL) |\n            ((x << 24) & 0x0000ff0000000000ULL) |\n            ((x << 8)  & 0x000000ff00000000ULL) |\n            ((x >> 8)  & 0x00000000ff000000ULL) |\n            ((x >> 24) & 0x0000000000ff0000ULL) |\n            ((x >> 40) & 0x000000000000ff00ULL) |\n            ((x >> 56) & 0x00000000000000ffULL);\n}\n#endif\n\n\n/* *************************************\n*  Architecture Macros\n***************************************/\ntypedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;\n\n/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */\n#ifndef XXH_CPU_LITTLE_ENDIAN\n    static const int g_one = 1;\n#   define XXH_CPU_LITTLE_ENDIAN   (*(const char*)(&g_one))\n#endif\n\n\n/* ***************************\n*  Memory reads\n*****************************/\ntypedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;\n\nFORCE_INLINE_TEMPLATE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)\n{\n    if (align==XXH_unaligned)\n        return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));\n    else\n        return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);\n}\n\nFORCE_INLINE_TEMPLATE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)\n{\n    return XXH_readLE32_align(ptr, endian, XXH_unaligned);\n}\n\nstatic U32 XXH_readBE32(const void* ptr)\n{\n    return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);\n}\n\nFORCE_INLINE_TEMPLATE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)\n{\n    if (align==XXH_unaligned)\n        return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));\n    else\n        return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);\n}\n\nFORCE_INLINE_TEMPLATE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)\n{\n    return XXH_readLE64_align(ptr, endian, XXH_unaligned);\n}\n\nstatic U64 XXH_readBE64(const void* ptr)\n{\n    return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);\n}\n\n\n/* *************************************\n*  Macros\n***************************************/\n#define XXH_STATIC_ASSERT(c)   { enum { XXH_static_assert = 1/(int)(!!(c)) }; }    /* use only *after* variable declarations */\n\n\n/* *************************************\n*  Constants\n***************************************/\nstatic const U32 PRIME32_1 = 2654435761U;\nstatic const U32 PRIME32_2 = 2246822519U;\nstatic const U32 PRIME32_3 = 3266489917U;\nstatic const U32 PRIME32_4 =  668265263U;\nstatic const U32 PRIME32_5 =  374761393U;\n\nstatic const U64 PRIME64_1 = 11400714785074694791ULL;\nstatic const U64 PRIME64_2 = 14029467366897019727ULL;\nstatic const U64 PRIME64_3 =  1609587929392839161ULL;\nstatic const U64 PRIME64_4 =  9650029242287828579ULL;\nstatic const U64 PRIME64_5 =  2870177450012600261ULL;\n\nXXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }\n\n\n/* **************************\n*  Utils\n****************************/\nXXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState)\n{\n    memcpy(dstState, srcState, sizeof(*dstState));\n}\n\nXXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState)\n{\n    memcpy(dstState, srcState, sizeof(*dstState));\n}\n\n\n/* ***************************\n*  Simple Hash Functions\n*****************************/\n\nstatic U32 XXH32_round(U32 seed, U32 input)\n{\n    seed += input * PRIME32_2;\n    seed  = XXH_rotl32(seed, 13);\n    seed *= PRIME32_1;\n    return seed;\n}\n\nFORCE_INLINE_TEMPLATE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)\n{\n    const BYTE* p = (const BYTE*)input;\n    const BYTE* bEnd = p + len;\n    U32 h32;\n#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)\n\n#ifdef XXH_ACCEPT_NULL_INPUT_POINTER\n    if (p==NULL) {\n        len=0;\n        bEnd=p=(const BYTE*)(size_t)16;\n    }\n#endif\n\n    if (len>=16) {\n        const BYTE* const limit = bEnd - 16;\n        U32 v1 = seed + PRIME32_1 + PRIME32_2;\n        U32 v2 = seed + PRIME32_2;\n        U32 v3 = seed + 0;\n        U32 v4 = seed - PRIME32_1;\n\n        do {\n            v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;\n            v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;\n            v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;\n            v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;\n        } while (p<=limit);\n\n        h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);\n    } else {\n        h32  = seed + PRIME32_5;\n    }\n\n    h32 += (U32) len;\n\n    while (p+4<=bEnd) {\n        h32 += XXH_get32bits(p) * PRIME32_3;\n        h32  = XXH_rotl32(h32, 17) * PRIME32_4 ;\n        p+=4;\n    }\n\n    while (p<bEnd) {\n        h32 += (*p) * PRIME32_5;\n        h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;\n        p++;\n    }\n\n    h32 ^= h32 >> 15;\n    h32 *= PRIME32_2;\n    h32 ^= h32 >> 13;\n    h32 *= PRIME32_3;\n    h32 ^= h32 >> 16;\n\n    return h32;\n}\n\n\nXXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)\n{\n#if 0\n    /* Simple version, good for code maintenance, but unfortunately slow for small inputs */\n    XXH32_CREATESTATE_STATIC(state);\n    XXH32_reset(state, seed);\n    XXH32_update(state, input, len);\n    return XXH32_digest(state);\n#else\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if (XXH_FORCE_ALIGN_CHECK) {\n        if ((((size_t)input) & 3) == 0) {   /* Input is 4-bytes aligned, leverage the speed benefit */\n            if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n                return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);\n            else\n                return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);\n    }   }\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);\n    else\n        return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);\n#endif\n}\n\n\nstatic U64 XXH64_round(U64 acc, U64 input)\n{\n    acc += input * PRIME64_2;\n    acc  = XXH_rotl64(acc, 31);\n    acc *= PRIME64_1;\n    return acc;\n}\n\nstatic U64 XXH64_mergeRound(U64 acc, U64 val)\n{\n    val  = XXH64_round(0, val);\n    acc ^= val;\n    acc  = acc * PRIME64_1 + PRIME64_4;\n    return acc;\n}\n\nFORCE_INLINE_TEMPLATE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)\n{\n    const BYTE* p = (const BYTE*)input;\n    const BYTE* const bEnd = p + len;\n    U64 h64;\n#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)\n\n#ifdef XXH_ACCEPT_NULL_INPUT_POINTER\n    if (p==NULL) {\n        len=0;\n        bEnd=p=(const BYTE*)(size_t)32;\n    }\n#endif\n\n    if (len>=32) {\n        const BYTE* const limit = bEnd - 32;\n        U64 v1 = seed + PRIME64_1 + PRIME64_2;\n        U64 v2 = seed + PRIME64_2;\n        U64 v3 = seed + 0;\n        U64 v4 = seed - PRIME64_1;\n\n        do {\n            v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;\n            v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;\n            v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;\n            v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;\n        } while (p<=limit);\n\n        h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);\n        h64 = XXH64_mergeRound(h64, v1);\n        h64 = XXH64_mergeRound(h64, v2);\n        h64 = XXH64_mergeRound(h64, v3);\n        h64 = XXH64_mergeRound(h64, v4);\n\n    } else {\n        h64  = seed + PRIME64_5;\n    }\n\n    h64 += (U64) len;\n\n    while (p+8<=bEnd) {\n        U64 const k1 = XXH64_round(0, XXH_get64bits(p));\n        h64 ^= k1;\n        h64  = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;\n        p+=8;\n    }\n\n    if (p+4<=bEnd) {\n        h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;\n        h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;\n        p+=4;\n    }\n\n    while (p<bEnd) {\n        h64 ^= (*p) * PRIME64_5;\n        h64 = XXH_rotl64(h64, 11) * PRIME64_1;\n        p++;\n    }\n\n    h64 ^= h64 >> 33;\n    h64 *= PRIME64_2;\n    h64 ^= h64 >> 29;\n    h64 *= PRIME64_3;\n    h64 ^= h64 >> 32;\n\n    return h64;\n}\n\n\nXXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)\n{\n#if 0\n    /* Simple version, good for code maintenance, but unfortunately slow for small inputs */\n    XXH64_CREATESTATE_STATIC(state);\n    XXH64_reset(state, seed);\n    XXH64_update(state, input, len);\n    return XXH64_digest(state);\n#else\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if (XXH_FORCE_ALIGN_CHECK) {\n        if ((((size_t)input) & 7)==0) {  /* Input is aligned, let's leverage the speed advantage */\n            if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n                return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);\n            else\n                return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);\n    }   }\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);\n    else\n        return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);\n#endif\n}\n\n\n/* **************************************************\n*  Advanced Hash Functions\n****************************************************/\n\nXXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)\n{\n    return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));\n}\nXXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)\n{\n    XXH_free(statePtr);\n    return XXH_OK;\n}\n\nXXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)\n{\n    return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));\n}\nXXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)\n{\n    XXH_free(statePtr);\n    return XXH_OK;\n}\n\n\n/*** Hash feed ***/\n\nXXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)\n{\n    XXH32_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */\n    memset(&state, 0, sizeof(state)-4);   /* do not write into reserved, for future removal */\n    state.v1 = seed + PRIME32_1 + PRIME32_2;\n    state.v2 = seed + PRIME32_2;\n    state.v3 = seed + 0;\n    state.v4 = seed - PRIME32_1;\n    memcpy(statePtr, &state, sizeof(state));\n    return XXH_OK;\n}\n\n\nXXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)\n{\n    XXH64_state_t state;   /* using a local state to memcpy() in order to avoid strict-aliasing warnings */\n    memset(&state, 0, sizeof(state)-8);   /* do not write into reserved, for future removal */\n    state.v1 = seed + PRIME64_1 + PRIME64_2;\n    state.v2 = seed + PRIME64_2;\n    state.v3 = seed + 0;\n    state.v4 = seed - PRIME64_1;\n    memcpy(statePtr, &state, sizeof(state));\n    return XXH_OK;\n}\n\n\nFORCE_INLINE_TEMPLATE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)\n{\n    const BYTE* p = (const BYTE*)input;\n    const BYTE* const bEnd = p + len;\n\n#ifdef XXH_ACCEPT_NULL_INPUT_POINTER\n    if (input==NULL) return XXH_ERROR;\n#endif\n\n    state->total_len_32 += (unsigned)len;\n    state->large_len |= (len>=16) | (state->total_len_32>=16);\n\n    if (state->memsize + len < 16)  {   /* fill in tmp buffer */\n        XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);\n        state->memsize += (unsigned)len;\n        return XXH_OK;\n    }\n\n    if (state->memsize) {   /* some data left from previous update */\n        XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);\n        {   const U32* p32 = state->mem32;\n            state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;\n            state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;\n            state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;\n            state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++;\n        }\n        p += 16-state->memsize;\n        state->memsize = 0;\n    }\n\n    if (p <= bEnd-16) {\n        const BYTE* const limit = bEnd - 16;\n        U32 v1 = state->v1;\n        U32 v2 = state->v2;\n        U32 v3 = state->v3;\n        U32 v4 = state->v4;\n\n        do {\n            v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;\n            v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;\n            v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;\n            v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;\n        } while (p<=limit);\n\n        state->v1 = v1;\n        state->v2 = v2;\n        state->v3 = v3;\n        state->v4 = v4;\n    }\n\n    if (p < bEnd) {\n        XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));\n        state->memsize = (unsigned)(bEnd-p);\n    }\n\n    return XXH_OK;\n}\n\nXXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)\n{\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH32_update_endian(state_in, input, len, XXH_littleEndian);\n    else\n        return XXH32_update_endian(state_in, input, len, XXH_bigEndian);\n}\n\n\n\nFORCE_INLINE_TEMPLATE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)\n{\n    const BYTE * p = (const BYTE*)state->mem32;\n    const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;\n    U32 h32;\n\n    if (state->large_len) {\n        h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);\n    } else {\n        h32 = state->v3 /* == seed */ + PRIME32_5;\n    }\n\n    h32 += state->total_len_32;\n\n    while (p+4<=bEnd) {\n        h32 += XXH_readLE32(p, endian) * PRIME32_3;\n        h32  = XXH_rotl32(h32, 17) * PRIME32_4;\n        p+=4;\n    }\n\n    while (p<bEnd) {\n        h32 += (*p) * PRIME32_5;\n        h32  = XXH_rotl32(h32, 11) * PRIME32_1;\n        p++;\n    }\n\n    h32 ^= h32 >> 15;\n    h32 *= PRIME32_2;\n    h32 ^= h32 >> 13;\n    h32 *= PRIME32_3;\n    h32 ^= h32 >> 16;\n\n    return h32;\n}\n\n\nXXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)\n{\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH32_digest_endian(state_in, XXH_littleEndian);\n    else\n        return XXH32_digest_endian(state_in, XXH_bigEndian);\n}\n\n\n\n/* **** XXH64 **** */\n\nFORCE_INLINE_TEMPLATE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)\n{\n    const BYTE* p = (const BYTE*)input;\n    const BYTE* const bEnd = p + len;\n\n#ifdef XXH_ACCEPT_NULL_INPUT_POINTER\n    if (input==NULL) return XXH_ERROR;\n#endif\n\n    state->total_len += len;\n\n    if (state->memsize + len < 32) {  /* fill in tmp buffer */\n        XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);\n        state->memsize += (U32)len;\n        return XXH_OK;\n    }\n\n    if (state->memsize) {   /* tmp buffer is full */\n        XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);\n        state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));\n        state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));\n        state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));\n        state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));\n        p += 32-state->memsize;\n        state->memsize = 0;\n    }\n\n    if (p+32 <= bEnd) {\n        const BYTE* const limit = bEnd - 32;\n        U64 v1 = state->v1;\n        U64 v2 = state->v2;\n        U64 v3 = state->v3;\n        U64 v4 = state->v4;\n\n        do {\n            v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;\n            v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;\n            v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;\n            v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;\n        } while (p<=limit);\n\n        state->v1 = v1;\n        state->v2 = v2;\n        state->v3 = v3;\n        state->v4 = v4;\n    }\n\n    if (p < bEnd) {\n        XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));\n        state->memsize = (unsigned)(bEnd-p);\n    }\n\n    return XXH_OK;\n}\n\nXXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)\n{\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH64_update_endian(state_in, input, len, XXH_littleEndian);\n    else\n        return XXH64_update_endian(state_in, input, len, XXH_bigEndian);\n}\n\n\n\nFORCE_INLINE_TEMPLATE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)\n{\n    const BYTE * p = (const BYTE*)state->mem64;\n    const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;\n    U64 h64;\n\n    if (state->total_len >= 32) {\n        U64 const v1 = state->v1;\n        U64 const v2 = state->v2;\n        U64 const v3 = state->v3;\n        U64 const v4 = state->v4;\n\n        h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);\n        h64 = XXH64_mergeRound(h64, v1);\n        h64 = XXH64_mergeRound(h64, v2);\n        h64 = XXH64_mergeRound(h64, v3);\n        h64 = XXH64_mergeRound(h64, v4);\n    } else {\n        h64  = state->v3 + PRIME64_5;\n    }\n\n    h64 += (U64) state->total_len;\n\n    while (p+8<=bEnd) {\n        U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian));\n        h64 ^= k1;\n        h64  = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;\n        p+=8;\n    }\n\n    if (p+4<=bEnd) {\n        h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;\n        h64  = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;\n        p+=4;\n    }\n\n    while (p<bEnd) {\n        h64 ^= (*p) * PRIME64_5;\n        h64  = XXH_rotl64(h64, 11) * PRIME64_1;\n        p++;\n    }\n\n    h64 ^= h64 >> 33;\n    h64 *= PRIME64_2;\n    h64 ^= h64 >> 29;\n    h64 *= PRIME64_3;\n    h64 ^= h64 >> 32;\n\n    return h64;\n}\n\n\nXXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)\n{\n    XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;\n\n    if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)\n        return XXH64_digest_endian(state_in, XXH_littleEndian);\n    else\n        return XXH64_digest_endian(state_in, XXH_bigEndian);\n}\n\n\n/* **************************\n*  Canonical representation\n****************************/\n\n/*! Default XXH result types are basic unsigned 32 and 64 bits.\n*   The canonical representation follows human-readable write convention, aka big-endian (large digits first).\n*   These functions allow transformation of hash result into and from its canonical format.\n*   This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.\n*/\n\nXXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)\n{\n    XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));\n    if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);\n    memcpy(dst, &hash, sizeof(*dst));\n}\n\nXXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)\n{\n    XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));\n    if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);\n    memcpy(dst, &hash, sizeof(*dst));\n}\n\nXXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)\n{\n    return XXH_readBE32(src);\n}\n\nXXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)\n{\n    return XXH_readBE64(src);\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/xxhash.h",
    "content": "/*\n   xxHash - Extremely Fast Hash algorithm\n   Header File\n   Copyright (C) 2012-2016, Yann Collet.\n\n   BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)\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\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\n   You can contact the author at :\n   - xxHash source repository : https://github.com/Cyan4973/xxHash\n*/\n\n/* Notice extracted from xxHash homepage :\n\nxxHash is an extremely fast Hash algorithm, running at RAM speed limits.\nIt also successfully passes all tests from the SMHasher suite.\n\nComparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)\n\nName            Speed       Q.Score   Author\nxxHash          5.4 GB/s     10\nCrapWow         3.2 GB/s      2       Andrew\nMumurHash 3a    2.7 GB/s     10       Austin Appleby\nSpookyHash      2.0 GB/s     10       Bob Jenkins\nSBox            1.4 GB/s      9       Bret Mulvey\nLookup3         1.2 GB/s      9       Bob Jenkins\nSuperFastHash   1.2 GB/s      1       Paul Hsieh\nCityHash64      1.05 GB/s    10       Pike & Alakuijala\nFNV             0.55 GB/s     5       Fowler, Noll, Vo\nCRC32           0.43 GB/s     9\nMD5-32          0.33 GB/s    10       Ronald L. Rivest\nSHA1-32         0.28 GB/s    10\n\nQ.Score is a measure of quality of the hash function.\nIt depends on successfully passing SMHasher test set.\n10 is a perfect score.\n\nA 64-bits version, named XXH64, is available since r35.\nIt offers much better speed, but for 64-bits applications only.\nName     Speed on 64 bits    Speed on 32 bits\nXXH64       13.8 GB/s            1.9 GB/s\nXXH32        6.8 GB/s            6.0 GB/s\n*/\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#ifndef XXHASH_H_5627135585666179\n#define XXHASH_H_5627135585666179 1\n\n\n/* ****************************\n*  Definitions\n******************************/\n#include <stddef.h>   /* size_t */\ntypedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;\n\n\n/* ****************************\n*  API modifier\n******************************/\n/** XXH_PRIVATE_API\n*   This is useful if you want to include xxhash functions in `static` mode\n*   in order to inline them, and remove their symbol from the public list.\n*   Methodology :\n*     #define XXH_PRIVATE_API\n*     #include \"xxhash.h\"\n*   `xxhash.c` is automatically included.\n*   It's not useful to compile and link it as a separate module anymore.\n*/\n#ifdef XXH_PRIVATE_API\n#  ifndef XXH_STATIC_LINKING_ONLY\n#    define XXH_STATIC_LINKING_ONLY\n#  endif\n#  if defined(__GNUC__)\n#    define XXH_PUBLIC_API static __inline __attribute__((unused))\n#  elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)\n#    define XXH_PUBLIC_API static inline\n#  elif defined(_MSC_VER)\n#    define XXH_PUBLIC_API static __inline\n#  else\n#    define XXH_PUBLIC_API static   /* this version may generate warnings for unused static functions; disable the relevant warning */\n#  endif\n#else\n#  define XXH_PUBLIC_API   /* do nothing */\n#endif /* XXH_PRIVATE_API */\n\n/*!XXH_NAMESPACE, aka Namespace Emulation :\n\nIf you want to include _and expose_ xxHash functions from within your own library,\nbut also want to avoid symbol collisions with another library which also includes xxHash,\n\nyou can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library\nwith the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values).\n\nNote that no change is required within the calling program as long as it includes `xxhash.h` :\nregular symbol name will be automatically translated by this header.\n*/\n#ifdef XXH_NAMESPACE\n#  define XXH_CAT(A,B) A##B\n#  define XXH_NAME2(A,B) XXH_CAT(A,B)\n#  define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)\n#  define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)\n#  define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)\n#  define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)\n#  define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)\n#  define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)\n#  define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)\n#  define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)\n#  define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)\n#  define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)\n#  define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)\n#  define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)\n#  define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)\n#  define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)\n#  define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)\n#  define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)\n#  define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)\n#  define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)\n#  define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)\n#endif\n\n\n/* *************************************\n*  Version\n***************************************/\n#define XXH_VERSION_MAJOR    0\n#define XXH_VERSION_MINOR    6\n#define XXH_VERSION_RELEASE  2\n#define XXH_VERSION_NUMBER  (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)\nXXH_PUBLIC_API unsigned XXH_versionNumber (void);\n\n\n/* ****************************\n*  Simple Hash Functions\n******************************/\ntypedef unsigned int       XXH32_hash_t;\ntypedef unsigned long long XXH64_hash_t;\n\nXXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);\nXXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);\n\n/*!\nXXH32() :\n    Calculate the 32-bits hash of sequence \"length\" bytes stored at memory address \"input\".\n    The memory between input & input+length must be valid (allocated and read-accessible).\n    \"seed\" can be used to alter the result predictably.\n    Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s\nXXH64() :\n    Calculate the 64-bits hash of sequence of length \"len\" stored at memory address \"input\".\n    \"seed\" can be used to alter the result predictably.\n    This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark).\n*/\n\n\n/* ****************************\n*  Streaming Hash Functions\n******************************/\ntypedef struct XXH32_state_s XXH32_state_t;   /* incomplete type */\ntypedef struct XXH64_state_s XXH64_state_t;   /* incomplete type */\n\n/*! State allocation, compatible with dynamic libraries */\n\nXXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);\nXXH_PUBLIC_API XXH_errorcode  XXH32_freeState(XXH32_state_t* statePtr);\n\nXXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);\nXXH_PUBLIC_API XXH_errorcode  XXH64_freeState(XXH64_state_t* statePtr);\n\n\n/* hash streaming */\n\nXXH_PUBLIC_API XXH_errorcode XXH32_reset  (XXH32_state_t* statePtr, unsigned int seed);\nXXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);\nXXH_PUBLIC_API XXH32_hash_t  XXH32_digest (const XXH32_state_t* statePtr);\n\nXXH_PUBLIC_API XXH_errorcode XXH64_reset  (XXH64_state_t* statePtr, unsigned long long seed);\nXXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);\nXXH_PUBLIC_API XXH64_hash_t  XXH64_digest (const XXH64_state_t* statePtr);\n\n/*\nThese functions generate the xxHash of an input provided in multiple segments.\nNote that, for small input, they are slower than single-call functions, due to state management.\nFor small input, prefer `XXH32()` and `XXH64()` .\n\nXXH state must first be allocated, using XXH*_createState() .\n\nStart a new hash by initializing state with a seed, using XXH*_reset().\n\nThen, feed the hash state by calling XXH*_update() as many times as necessary.\nObviously, input must be allocated and read accessible.\nThe function returns an error code, with 0 meaning OK, and any other value meaning there is an error.\n\nFinally, a hash value can be produced anytime, by using XXH*_digest().\nThis function returns the nn-bits hash as an int or long long.\n\nIt's still possible to continue inserting input into the hash state after a digest,\nand generate some new hashes later on, by calling again XXH*_digest().\n\nWhen done, free XXH state space if it was allocated dynamically.\n*/\n\n\n/* **************************\n*  Utils\n****************************/\n#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L))   /* ! C99 */\n#  define restrict   /* disable restrict */\n#endif\n\nXXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state);\nXXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state);\n\n\n/* **************************\n*  Canonical representation\n****************************/\n/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.\n*  The canonical representation uses human-readable write convention, aka big-endian (large digits first).\n*  These functions allow transformation of hash result into and from its canonical format.\n*  This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.\n*/\ntypedef struct { unsigned char digest[4]; } XXH32_canonical_t;\ntypedef struct { unsigned char digest[8]; } XXH64_canonical_t;\n\nXXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);\nXXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);\n\nXXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);\nXXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);\n\n#endif /* XXHASH_H_5627135585666179 */\n\n\n\n/* ================================================================================================\n   This section contains definitions which are not guaranteed to remain stable.\n   They may change in future versions, becoming incompatible with a different version of the library.\n   They shall only be used with static linking.\n   Never use these definitions in association with dynamic linking !\n=================================================================================================== */\n#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXH_STATIC_H_3543687687345)\n#define XXH_STATIC_H_3543687687345\n\n/* These definitions are only meant to allow allocation of XXH state\n   statically, on stack, or in a struct for example.\n   Do not use members directly. */\n\n   struct XXH32_state_s {\n       unsigned total_len_32;\n       unsigned large_len;\n       unsigned v1;\n       unsigned v2;\n       unsigned v3;\n       unsigned v4;\n       unsigned mem32[4];   /* buffer defined as U32 for alignment */\n       unsigned memsize;\n       unsigned reserved;   /* never read nor write, will be removed in a future version */\n   };   /* typedef'd to XXH32_state_t */\n\n   struct XXH64_state_s {\n       unsigned long long total_len;\n       unsigned long long v1;\n       unsigned long long v2;\n       unsigned long long v3;\n       unsigned long long v4;\n       unsigned long long mem64[4];   /* buffer defined as U64 for alignment */\n       unsigned memsize;\n       unsigned reserved[2];          /* never read nor write, will be removed in a future version */\n   };   /* typedef'd to XXH64_state_t */\n\n\n#  ifdef XXH_PRIVATE_API\n#    include \"xxhash.c\"   /* include xxhash functions as `static`, for inlining */\n#  endif\n\n#endif /* XXH_STATIC_LINKING_ONLY && XXH_STATIC_H_3543687687345 */\n\n\n#if defined (__cplusplus)\n}\n#endif\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_common.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n\n\n/*-*************************************\n*  Dependencies\n***************************************/\n#include <stdlib.h>      /* malloc, calloc, free */\n#include <string.h>      /* memset */\n#include \"error_private.h\"\n#include \"zstd_internal.h\"\n\n\n/*-****************************************\n*  Version\n******************************************/\nunsigned ZSTD_versionNumber(void) { return ZSTD_VERSION_NUMBER; }\n\nconst char* ZSTD_versionString(void) { return ZSTD_VERSION_STRING; }\n\n\n/*-****************************************\n*  ZSTD Error Management\n******************************************/\n#undef ZSTD_isError   /* defined within zstd_internal.h */\n/*! ZSTD_isError() :\n *  tells if a return value is an error code\n *  symbol is required for external callers */\nunsigned ZSTD_isError(size_t code) { return ERR_isError(code); }\n\n/*! ZSTD_getErrorName() :\n *  provides error code string from function result (useful for debugging) */\nconst char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }\n\n/*! ZSTD_getError() :\n *  convert a `size_t` function result into a proper ZSTD_errorCode enum */\nZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); }\n\n/*! ZSTD_getErrorString() :\n *  provides error code string from enum */\nconst char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); }\n\n\n\n/*=**************************************************************\n*  Custom allocator\n****************************************************************/\nvoid* ZSTD_malloc(size_t size, ZSTD_customMem customMem)\n{\n    if (customMem.customAlloc)\n        return customMem.customAlloc(customMem.opaque, size);\n    return malloc(size);\n}\n\nvoid* ZSTD_calloc(size_t size, ZSTD_customMem customMem)\n{\n    if (customMem.customAlloc) {\n        /* calloc implemented as malloc+memset;\n         * not as efficient as calloc, but next best guess for custom malloc */\n        void* const ptr = customMem.customAlloc(customMem.opaque, size);\n        memset(ptr, 0, size);\n        return ptr;\n    }\n    return calloc(1, size);\n}\n\nvoid ZSTD_free(void* ptr, ZSTD_customMem customMem)\n{\n    if (ptr!=NULL) {\n        if (customMem.customFree)\n            customMem.customFree(customMem.opaque, ptr);\n        else\n            free(ptr);\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_compress.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n/*-*************************************\n*  Dependencies\n***************************************/\n#include <limits.h>         /* INT_MAX */\n#include <string.h>         /* memset */\n#include \"cpu.h\"\n#include \"mem.h\"\n#include \"hist.h\"           /* HIST_countFast_wksp */\n#define FSE_STATIC_LINKING_ONLY   /* FSE_encodeSymbol */\n#include \"fse.h\"\n#define HUF_STATIC_LINKING_ONLY\n#include \"huf.h\"\n#include \"zstd_compress_internal.h\"\n#include \"zstd_compress_sequences.h\"\n#include \"zstd_compress_literals.h\"\n#include \"zstd_fast.h\"\n#include \"zstd_double_fast.h\"\n#include \"zstd_lazy.h\"\n#include \"zstd_opt.h\"\n#include \"zstd_ldm.h\"\n\n\n/*-*************************************\n*  Helper functions\n***************************************/\nsize_t ZSTD_compressBound(size_t srcSize) {\n    return ZSTD_COMPRESSBOUND(srcSize);\n}\n\n\n/*-*************************************\n*  Context memory management\n***************************************/\nstruct ZSTD_CDict_s {\n    const void* dictContent;\n    size_t dictContentSize;\n    U32* entropyWorkspace; /* entropy workspace of HUF_WORKSPACE_SIZE bytes */\n    ZSTD_cwksp workspace;\n    ZSTD_matchState_t matchState;\n    ZSTD_compressedBlockState_t cBlockState;\n    ZSTD_customMem customMem;\n    U32 dictID;\n    int compressionLevel; /* 0 indicates that advanced API was used to select CDict params */\n};  /* typedef'd to ZSTD_CDict within \"zstd.h\" */\n\nZSTD_CCtx* ZSTD_createCCtx(void)\n{\n    return ZSTD_createCCtx_advanced(ZSTD_defaultCMem);\n}\n\nstatic void ZSTD_initCCtx(ZSTD_CCtx* cctx, ZSTD_customMem memManager)\n{\n    assert(cctx != NULL);\n    memset(cctx, 0, sizeof(*cctx));\n    cctx->customMem = memManager;\n    cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());\n    {   size_t const err = ZSTD_CCtx_reset(cctx, ZSTD_reset_parameters);\n        assert(!ZSTD_isError(err));\n        (void)err;\n    }\n}\n\nZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)\n{\n    ZSTD_STATIC_ASSERT(zcss_init==0);\n    ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN==(0ULL - 1));\n    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;\n    {   ZSTD_CCtx* const cctx = (ZSTD_CCtx*)ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);\n        if (!cctx) return NULL;\n        ZSTD_initCCtx(cctx, customMem);\n        return cctx;\n    }\n}\n\nZSTD_CCtx* ZSTD_initStaticCCtx(void *workspace, size_t workspaceSize)\n{\n    ZSTD_cwksp ws;\n    ZSTD_CCtx* cctx;\n    if (workspaceSize <= sizeof(ZSTD_CCtx)) return NULL;  /* minimum size */\n    if ((size_t)workspace & 7) return NULL;  /* must be 8-aligned */\n    ZSTD_cwksp_init(&ws, workspace, workspaceSize);\n\n    cctx = (ZSTD_CCtx*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CCtx));\n    if (cctx == NULL) {\n        return NULL;\n    }\n    memset(cctx, 0, sizeof(ZSTD_CCtx));\n    ZSTD_cwksp_move(&cctx->workspace, &ws);\n    cctx->staticSize = workspaceSize;\n\n    /* statically sized space. entropyWorkspace never moves (but prev/next block swap places) */\n    if (!ZSTD_cwksp_check_available(&cctx->workspace, HUF_WORKSPACE_SIZE + 2 * sizeof(ZSTD_compressedBlockState_t))) return NULL;\n    cctx->blockState.prevCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));\n    cctx->blockState.nextCBlock = (ZSTD_compressedBlockState_t*)ZSTD_cwksp_reserve_object(&cctx->workspace, sizeof(ZSTD_compressedBlockState_t));\n    cctx->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(\n        &cctx->workspace, HUF_WORKSPACE_SIZE);\n    cctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());\n    return cctx;\n}\n\n/**\n * Clears and frees all of the dictionaries in the CCtx.\n */\nstatic void ZSTD_clearAllDicts(ZSTD_CCtx* cctx)\n{\n    ZSTD_free(cctx->localDict.dictBuffer, cctx->customMem);\n    ZSTD_freeCDict(cctx->localDict.cdict);\n    memset(&cctx->localDict, 0, sizeof(cctx->localDict));\n    memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));\n    cctx->cdict = NULL;\n}\n\nstatic size_t ZSTD_sizeof_localDict(ZSTD_localDict dict)\n{\n    size_t const bufferSize = dict.dictBuffer != NULL ? dict.dictSize : 0;\n    size_t const cdictSize = ZSTD_sizeof_CDict(dict.cdict);\n    return bufferSize + cdictSize;\n}\n\nstatic void ZSTD_freeCCtxContent(ZSTD_CCtx* cctx)\n{\n    assert(cctx != NULL);\n    assert(cctx->staticSize == 0);\n    ZSTD_clearAllDicts(cctx);\n#ifdef ZSTD_MULTITHREAD\n    ZSTDMT_freeCCtx(cctx->mtctx); cctx->mtctx = NULL;\n#endif\n    ZSTD_cwksp_free(&cctx->workspace, cctx->customMem);\n}\n\nsize_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)\n{\n    if (cctx==NULL) return 0;   /* support free on NULL */\n    RETURN_ERROR_IF(cctx->staticSize, memory_allocation,\n                    \"not compatible with static CCtx\");\n    {\n        int cctxInWorkspace = ZSTD_cwksp_owns_buffer(&cctx->workspace, cctx);\n        ZSTD_freeCCtxContent(cctx);\n        if (!cctxInWorkspace) {\n            ZSTD_free(cctx, cctx->customMem);\n        }\n    }\n    return 0;\n}\n\n\nstatic size_t ZSTD_sizeof_mtctx(const ZSTD_CCtx* cctx)\n{\n#ifdef ZSTD_MULTITHREAD\n    return ZSTDMT_sizeof_CCtx(cctx->mtctx);\n#else\n    (void)cctx;\n    return 0;\n#endif\n}\n\n\nsize_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)\n{\n    if (cctx==NULL) return 0;   /* support sizeof on NULL */\n    /* cctx may be in the workspace */\n    return (cctx->workspace.workspace == cctx ? 0 : sizeof(*cctx))\n           + ZSTD_cwksp_sizeof(&cctx->workspace)\n           + ZSTD_sizeof_localDict(cctx->localDict)\n           + ZSTD_sizeof_mtctx(cctx);\n}\n\nsize_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)\n{\n    return ZSTD_sizeof_CCtx(zcs);  /* same object */\n}\n\n/* private API call, for dictBuilder only */\nconst seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) { return &(ctx->seqStore); }\n\nstatic ZSTD_CCtx_params ZSTD_makeCCtxParamsFromCParams(\n        ZSTD_compressionParameters cParams)\n{\n    ZSTD_CCtx_params cctxParams;\n    memset(&cctxParams, 0, sizeof(cctxParams));\n    cctxParams.cParams = cParams;\n    cctxParams.compressionLevel = ZSTD_CLEVEL_DEFAULT;  /* should not matter, as all cParams are presumed properly defined */\n    assert(!ZSTD_checkCParams(cParams));\n    cctxParams.fParams.contentSizeFlag = 1;\n    return cctxParams;\n}\n\nstatic ZSTD_CCtx_params* ZSTD_createCCtxParams_advanced(\n        ZSTD_customMem customMem)\n{\n    ZSTD_CCtx_params* params;\n    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;\n    params = (ZSTD_CCtx_params*)ZSTD_calloc(\n            sizeof(ZSTD_CCtx_params), customMem);\n    if (!params) { return NULL; }\n    params->customMem = customMem;\n    params->compressionLevel = ZSTD_CLEVEL_DEFAULT;\n    params->fParams.contentSizeFlag = 1;\n    return params;\n}\n\nZSTD_CCtx_params* ZSTD_createCCtxParams(void)\n{\n    return ZSTD_createCCtxParams_advanced(ZSTD_defaultCMem);\n}\n\nsize_t ZSTD_freeCCtxParams(ZSTD_CCtx_params* params)\n{\n    if (params == NULL) { return 0; }\n    ZSTD_free(params, params->customMem);\n    return 0;\n}\n\nsize_t ZSTD_CCtxParams_reset(ZSTD_CCtx_params* params)\n{\n    return ZSTD_CCtxParams_init(params, ZSTD_CLEVEL_DEFAULT);\n}\n\nsize_t ZSTD_CCtxParams_init(ZSTD_CCtx_params* cctxParams, int compressionLevel) {\n    RETURN_ERROR_IF(!cctxParams, GENERIC);\n    memset(cctxParams, 0, sizeof(*cctxParams));\n    cctxParams->compressionLevel = compressionLevel;\n    cctxParams->fParams.contentSizeFlag = 1;\n    return 0;\n}\n\nsize_t ZSTD_CCtxParams_init_advanced(ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)\n{\n    RETURN_ERROR_IF(!cctxParams, GENERIC);\n    FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );\n    memset(cctxParams, 0, sizeof(*cctxParams));\n    assert(!ZSTD_checkCParams(params.cParams));\n    cctxParams->cParams = params.cParams;\n    cctxParams->fParams = params.fParams;\n    cctxParams->compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* should not matter, as all cParams are presumed properly defined */\n    return 0;\n}\n\n/* ZSTD_assignParamsToCCtxParams() :\n * params is presumed valid at this stage */\nstatic ZSTD_CCtx_params ZSTD_assignParamsToCCtxParams(\n        const ZSTD_CCtx_params* cctxParams, ZSTD_parameters params)\n{\n    ZSTD_CCtx_params ret = *cctxParams;\n    assert(!ZSTD_checkCParams(params.cParams));\n    ret.cParams = params.cParams;\n    ret.fParams = params.fParams;\n    ret.compressionLevel = ZSTD_CLEVEL_DEFAULT;   /* should not matter, as all cParams are presumed properly defined */\n    return ret;\n}\n\nZSTD_bounds ZSTD_cParam_getBounds(ZSTD_cParameter param)\n{\n    ZSTD_bounds bounds = { 0, 0, 0 };\n\n    switch(param)\n    {\n    case ZSTD_c_compressionLevel:\n        bounds.lowerBound = ZSTD_minCLevel();\n        bounds.upperBound = ZSTD_maxCLevel();\n        return bounds;\n\n    case ZSTD_c_windowLog:\n        bounds.lowerBound = ZSTD_WINDOWLOG_MIN;\n        bounds.upperBound = ZSTD_WINDOWLOG_MAX;\n        return bounds;\n\n    case ZSTD_c_hashLog:\n        bounds.lowerBound = ZSTD_HASHLOG_MIN;\n        bounds.upperBound = ZSTD_HASHLOG_MAX;\n        return bounds;\n\n    case ZSTD_c_chainLog:\n        bounds.lowerBound = ZSTD_CHAINLOG_MIN;\n        bounds.upperBound = ZSTD_CHAINLOG_MAX;\n        return bounds;\n\n    case ZSTD_c_searchLog:\n        bounds.lowerBound = ZSTD_SEARCHLOG_MIN;\n        bounds.upperBound = ZSTD_SEARCHLOG_MAX;\n        return bounds;\n\n    case ZSTD_c_minMatch:\n        bounds.lowerBound = ZSTD_MINMATCH_MIN;\n        bounds.upperBound = ZSTD_MINMATCH_MAX;\n        return bounds;\n\n    case ZSTD_c_targetLength:\n        bounds.lowerBound = ZSTD_TARGETLENGTH_MIN;\n        bounds.upperBound = ZSTD_TARGETLENGTH_MAX;\n        return bounds;\n\n    case ZSTD_c_strategy:\n        bounds.lowerBound = ZSTD_STRATEGY_MIN;\n        bounds.upperBound = ZSTD_STRATEGY_MAX;\n        return bounds;\n\n    case ZSTD_c_contentSizeFlag:\n        bounds.lowerBound = 0;\n        bounds.upperBound = 1;\n        return bounds;\n\n    case ZSTD_c_checksumFlag:\n        bounds.lowerBound = 0;\n        bounds.upperBound = 1;\n        return bounds;\n\n    case ZSTD_c_dictIDFlag:\n        bounds.lowerBound = 0;\n        bounds.upperBound = 1;\n        return bounds;\n\n    case ZSTD_c_nbWorkers:\n        bounds.lowerBound = 0;\n#ifdef ZSTD_MULTITHREAD\n        bounds.upperBound = ZSTDMT_NBWORKERS_MAX;\n#else\n        bounds.upperBound = 0;\n#endif\n        return bounds;\n\n    case ZSTD_c_jobSize:\n        bounds.lowerBound = 0;\n#ifdef ZSTD_MULTITHREAD\n        bounds.upperBound = ZSTDMT_JOBSIZE_MAX;\n#else\n        bounds.upperBound = 0;\n#endif\n        return bounds;\n\n    case ZSTD_c_overlapLog:\n        bounds.lowerBound = ZSTD_OVERLAPLOG_MIN;\n        bounds.upperBound = ZSTD_OVERLAPLOG_MAX;\n        return bounds;\n\n    case ZSTD_c_enableLongDistanceMatching:\n        bounds.lowerBound = 0;\n        bounds.upperBound = 1;\n        return bounds;\n\n    case ZSTD_c_ldmHashLog:\n        bounds.lowerBound = ZSTD_LDM_HASHLOG_MIN;\n        bounds.upperBound = ZSTD_LDM_HASHLOG_MAX;\n        return bounds;\n\n    case ZSTD_c_ldmMinMatch:\n        bounds.lowerBound = ZSTD_LDM_MINMATCH_MIN;\n        bounds.upperBound = ZSTD_LDM_MINMATCH_MAX;\n        return bounds;\n\n    case ZSTD_c_ldmBucketSizeLog:\n        bounds.lowerBound = ZSTD_LDM_BUCKETSIZELOG_MIN;\n        bounds.upperBound = ZSTD_LDM_BUCKETSIZELOG_MAX;\n        return bounds;\n\n    case ZSTD_c_ldmHashRateLog:\n        bounds.lowerBound = ZSTD_LDM_HASHRATELOG_MIN;\n        bounds.upperBound = ZSTD_LDM_HASHRATELOG_MAX;\n        return bounds;\n\n    /* experimental parameters */\n    case ZSTD_c_rsyncable:\n        bounds.lowerBound = 0;\n        bounds.upperBound = 1;\n        return bounds;\n\n    case ZSTD_c_forceMaxWindow :\n        bounds.lowerBound = 0;\n        bounds.upperBound = 1;\n        return bounds;\n\n    case ZSTD_c_format:\n        ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);\n        bounds.lowerBound = ZSTD_f_zstd1;\n        bounds.upperBound = ZSTD_f_zstd1_magicless;   /* note : how to ensure at compile time that this is the highest value enum ? */\n        return bounds;\n\n    case ZSTD_c_forceAttachDict:\n        ZSTD_STATIC_ASSERT(ZSTD_dictDefaultAttach < ZSTD_dictForceCopy);\n        bounds.lowerBound = ZSTD_dictDefaultAttach;\n        bounds.upperBound = ZSTD_dictForceLoad;       /* note : how to ensure at compile time that this is the highest value enum ? */\n        return bounds;\n\n    case ZSTD_c_literalCompressionMode:\n        ZSTD_STATIC_ASSERT(ZSTD_lcm_auto < ZSTD_lcm_huffman && ZSTD_lcm_huffman < ZSTD_lcm_uncompressed);\n        bounds.lowerBound = ZSTD_lcm_auto;\n        bounds.upperBound = ZSTD_lcm_uncompressed;\n        return bounds;\n\n    case ZSTD_c_targetCBlockSize:\n        bounds.lowerBound = ZSTD_TARGETCBLOCKSIZE_MIN;\n        bounds.upperBound = ZSTD_TARGETCBLOCKSIZE_MAX;\n        return bounds;\n\n    case ZSTD_c_srcSizeHint:\n        bounds.lowerBound = ZSTD_SRCSIZEHINT_MIN;\n        bounds.upperBound = ZSTD_SRCSIZEHINT_MAX;\n        return bounds;\n\n    default:\n        {   ZSTD_bounds const boundError = { ERROR(parameter_unsupported), 0, 0 };\n            return boundError;\n        }\n    }\n}\n\n/* ZSTD_cParam_clampBounds:\n * Clamps the value into the bounded range.\n */\nstatic size_t ZSTD_cParam_clampBounds(ZSTD_cParameter cParam, int* value)\n{\n    ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);\n    if (ZSTD_isError(bounds.error)) return bounds.error;\n    if (*value < bounds.lowerBound) *value = bounds.lowerBound;\n    if (*value > bounds.upperBound) *value = bounds.upperBound;\n    return 0;\n}\n\n#define BOUNDCHECK(cParam, val) { \\\n    RETURN_ERROR_IF(!ZSTD_cParam_withinBounds(cParam,val), \\\n                    parameter_outOfBound); \\\n}\n\n\nstatic int ZSTD_isUpdateAuthorized(ZSTD_cParameter param)\n{\n    switch(param)\n    {\n    case ZSTD_c_compressionLevel:\n    case ZSTD_c_hashLog:\n    case ZSTD_c_chainLog:\n    case ZSTD_c_searchLog:\n    case ZSTD_c_minMatch:\n    case ZSTD_c_targetLength:\n    case ZSTD_c_strategy:\n        return 1;\n\n    case ZSTD_c_format:\n    case ZSTD_c_windowLog:\n    case ZSTD_c_contentSizeFlag:\n    case ZSTD_c_checksumFlag:\n    case ZSTD_c_dictIDFlag:\n    case ZSTD_c_forceMaxWindow :\n    case ZSTD_c_nbWorkers:\n    case ZSTD_c_jobSize:\n    case ZSTD_c_overlapLog:\n    case ZSTD_c_rsyncable:\n    case ZSTD_c_enableLongDistanceMatching:\n    case ZSTD_c_ldmHashLog:\n    case ZSTD_c_ldmMinMatch:\n    case ZSTD_c_ldmBucketSizeLog:\n    case ZSTD_c_ldmHashRateLog:\n    case ZSTD_c_forceAttachDict:\n    case ZSTD_c_literalCompressionMode:\n    case ZSTD_c_targetCBlockSize:\n    case ZSTD_c_srcSizeHint:\n    default:\n        return 0;\n    }\n}\n\nsize_t ZSTD_CCtx_setParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int value)\n{\n    DEBUGLOG(4, \"ZSTD_CCtx_setParameter (%i, %i)\", (int)param, value);\n    if (cctx->streamStage != zcss_init) {\n        if (ZSTD_isUpdateAuthorized(param)) {\n            cctx->cParamsChanged = 1;\n        } else {\n            RETURN_ERROR(stage_wrong);\n    }   }\n\n    switch(param)\n    {\n    case ZSTD_c_nbWorkers:\n        RETURN_ERROR_IF((value!=0) && cctx->staticSize, parameter_unsupported,\n                        \"MT not compatible with static alloc\");\n        break;\n\n    case ZSTD_c_compressionLevel:\n    case ZSTD_c_windowLog:\n    case ZSTD_c_hashLog:\n    case ZSTD_c_chainLog:\n    case ZSTD_c_searchLog:\n    case ZSTD_c_minMatch:\n    case ZSTD_c_targetLength:\n    case ZSTD_c_strategy:\n    case ZSTD_c_ldmHashRateLog:\n    case ZSTD_c_format:\n    case ZSTD_c_contentSizeFlag:\n    case ZSTD_c_checksumFlag:\n    case ZSTD_c_dictIDFlag:\n    case ZSTD_c_forceMaxWindow:\n    case ZSTD_c_forceAttachDict:\n    case ZSTD_c_literalCompressionMode:\n    case ZSTD_c_jobSize:\n    case ZSTD_c_overlapLog:\n    case ZSTD_c_rsyncable:\n    case ZSTD_c_enableLongDistanceMatching:\n    case ZSTD_c_ldmHashLog:\n    case ZSTD_c_ldmMinMatch:\n    case ZSTD_c_ldmBucketSizeLog:\n    case ZSTD_c_targetCBlockSize:\n    case ZSTD_c_srcSizeHint:\n        break;\n\n    default: RETURN_ERROR(parameter_unsupported);\n    }\n    return ZSTD_CCtxParams_setParameter(&cctx->requestedParams, param, value);\n}\n\nsize_t ZSTD_CCtxParams_setParameter(ZSTD_CCtx_params* CCtxParams,\n                                    ZSTD_cParameter param, int value)\n{\n    DEBUGLOG(4, \"ZSTD_CCtxParams_setParameter (%i, %i)\", (int)param, value);\n    switch(param)\n    {\n    case ZSTD_c_format :\n        BOUNDCHECK(ZSTD_c_format, value);\n        CCtxParams->format = (ZSTD_format_e)value;\n        return (size_t)CCtxParams->format;\n\n    case ZSTD_c_compressionLevel : {\n        FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));\n        if (value) {  /* 0 : does not change current level */\n            CCtxParams->compressionLevel = value;\n        }\n        if (CCtxParams->compressionLevel >= 0) return (size_t)CCtxParams->compressionLevel;\n        return 0;  /* return type (size_t) cannot represent negative values */\n    }\n\n    case ZSTD_c_windowLog :\n        if (value!=0)   /* 0 => use default */\n            BOUNDCHECK(ZSTD_c_windowLog, value);\n        CCtxParams->cParams.windowLog = (U32)value;\n        return CCtxParams->cParams.windowLog;\n\n    case ZSTD_c_hashLog :\n        if (value!=0)   /* 0 => use default */\n            BOUNDCHECK(ZSTD_c_hashLog, value);\n        CCtxParams->cParams.hashLog = (U32)value;\n        return CCtxParams->cParams.hashLog;\n\n    case ZSTD_c_chainLog :\n        if (value!=0)   /* 0 => use default */\n            BOUNDCHECK(ZSTD_c_chainLog, value);\n        CCtxParams->cParams.chainLog = (U32)value;\n        return CCtxParams->cParams.chainLog;\n\n    case ZSTD_c_searchLog :\n        if (value!=0)   /* 0 => use default */\n            BOUNDCHECK(ZSTD_c_searchLog, value);\n        CCtxParams->cParams.searchLog = (U32)value;\n        return (size_t)value;\n\n    case ZSTD_c_minMatch :\n        if (value!=0)   /* 0 => use default */\n            BOUNDCHECK(ZSTD_c_minMatch, value);\n        CCtxParams->cParams.minMatch = value;\n        return CCtxParams->cParams.minMatch;\n\n    case ZSTD_c_targetLength :\n        BOUNDCHECK(ZSTD_c_targetLength, value);\n        CCtxParams->cParams.targetLength = value;\n        return CCtxParams->cParams.targetLength;\n\n    case ZSTD_c_strategy :\n        if (value!=0)   /* 0 => use default */\n            BOUNDCHECK(ZSTD_c_strategy, value);\n        CCtxParams->cParams.strategy = (ZSTD_strategy)value;\n        return (size_t)CCtxParams->cParams.strategy;\n\n    case ZSTD_c_contentSizeFlag :\n        /* Content size written in frame header _when known_ (default:1) */\n        DEBUGLOG(4, \"set content size flag = %u\", (value!=0));\n        CCtxParams->fParams.contentSizeFlag = value != 0;\n        return CCtxParams->fParams.contentSizeFlag;\n\n    case ZSTD_c_checksumFlag :\n        /* A 32-bits content checksum will be calculated and written at end of frame (default:0) */\n        CCtxParams->fParams.checksumFlag = value != 0;\n        return CCtxParams->fParams.checksumFlag;\n\n    case ZSTD_c_dictIDFlag : /* When applicable, dictionary's dictID is provided in frame header (default:1) */\n        DEBUGLOG(4, \"set dictIDFlag = %u\", (value!=0));\n        CCtxParams->fParams.noDictIDFlag = !value;\n        return !CCtxParams->fParams.noDictIDFlag;\n\n    case ZSTD_c_forceMaxWindow :\n        CCtxParams->forceWindow = (value != 0);\n        return CCtxParams->forceWindow;\n\n    case ZSTD_c_forceAttachDict : {\n        const ZSTD_dictAttachPref_e pref = (ZSTD_dictAttachPref_e)value;\n        BOUNDCHECK(ZSTD_c_forceAttachDict, pref);\n        CCtxParams->attachDictPref = pref;\n        return CCtxParams->attachDictPref;\n    }\n\n    case ZSTD_c_literalCompressionMode : {\n        const ZSTD_literalCompressionMode_e lcm = (ZSTD_literalCompressionMode_e)value;\n        BOUNDCHECK(ZSTD_c_literalCompressionMode, lcm);\n        CCtxParams->literalCompressionMode = lcm;\n        return CCtxParams->literalCompressionMode;\n    }\n\n    case ZSTD_c_nbWorkers :\n#ifndef ZSTD_MULTITHREAD\n        RETURN_ERROR_IF(value!=0, parameter_unsupported, \"not compiled with multithreading\");\n        return 0;\n#else\n        FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));\n        CCtxParams->nbWorkers = value;\n        return CCtxParams->nbWorkers;\n#endif\n\n    case ZSTD_c_jobSize :\n#ifndef ZSTD_MULTITHREAD\n        RETURN_ERROR_IF(value!=0, parameter_unsupported, \"not compiled with multithreading\");\n        return 0;\n#else\n        /* Adjust to the minimum non-default value. */\n        if (value != 0 && value < ZSTDMT_JOBSIZE_MIN)\n            value = ZSTDMT_JOBSIZE_MIN;\n        FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(param, &value));\n        assert(value >= 0);\n        CCtxParams->jobSize = value;\n        return CCtxParams->jobSize;\n#endif\n\n    case ZSTD_c_overlapLog :\n#ifndef ZSTD_MULTITHREAD\n        RETURN_ERROR_IF(value!=0, parameter_unsupported, \"not compiled with multithreading\");\n        return 0;\n#else\n        FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value));\n        CCtxParams->overlapLog = value;\n        return CCtxParams->overlapLog;\n#endif\n\n    case ZSTD_c_rsyncable :\n#ifndef ZSTD_MULTITHREAD\n        RETURN_ERROR_IF(value!=0, parameter_unsupported, \"not compiled with multithreading\");\n        return 0;\n#else\n        FORWARD_IF_ERROR(ZSTD_cParam_clampBounds(ZSTD_c_overlapLog, &value));\n        CCtxParams->rsyncable = value;\n        return CCtxParams->rsyncable;\n#endif\n\n    case ZSTD_c_enableLongDistanceMatching :\n        CCtxParams->ldmParams.enableLdm = (value!=0);\n        return CCtxParams->ldmParams.enableLdm;\n\n    case ZSTD_c_ldmHashLog :\n        if (value!=0)   /* 0 ==> auto */\n            BOUNDCHECK(ZSTD_c_ldmHashLog, value);\n        CCtxParams->ldmParams.hashLog = value;\n        return CCtxParams->ldmParams.hashLog;\n\n    case ZSTD_c_ldmMinMatch :\n        if (value!=0)   /* 0 ==> default */\n            BOUNDCHECK(ZSTD_c_ldmMinMatch, value);\n        CCtxParams->ldmParams.minMatchLength = value;\n        return CCtxParams->ldmParams.minMatchLength;\n\n    case ZSTD_c_ldmBucketSizeLog :\n        if (value!=0)   /* 0 ==> default */\n            BOUNDCHECK(ZSTD_c_ldmBucketSizeLog, value);\n        CCtxParams->ldmParams.bucketSizeLog = value;\n        return CCtxParams->ldmParams.bucketSizeLog;\n\n    case ZSTD_c_ldmHashRateLog :\n        RETURN_ERROR_IF(value > ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN,\n                        parameter_outOfBound);\n        CCtxParams->ldmParams.hashRateLog = value;\n        return CCtxParams->ldmParams.hashRateLog;\n\n    case ZSTD_c_targetCBlockSize :\n        if (value!=0)   /* 0 ==> default */\n            BOUNDCHECK(ZSTD_c_targetCBlockSize, value);\n        CCtxParams->targetCBlockSize = value;\n        return CCtxParams->targetCBlockSize;\n\n    case ZSTD_c_srcSizeHint :\n        if (value!=0)    /* 0 ==> default */\n            BOUNDCHECK(ZSTD_c_srcSizeHint, value);\n        CCtxParams->srcSizeHint = value;\n        return CCtxParams->srcSizeHint;\n\n    default: RETURN_ERROR(parameter_unsupported, \"unknown parameter\");\n    }\n}\n\nsize_t ZSTD_CCtx_getParameter(ZSTD_CCtx* cctx, ZSTD_cParameter param, int* value)\n{\n    return ZSTD_CCtxParams_getParameter(&cctx->requestedParams, param, value);\n}\n\nsize_t ZSTD_CCtxParams_getParameter(\n        ZSTD_CCtx_params* CCtxParams, ZSTD_cParameter param, int* value)\n{\n    switch(param)\n    {\n    case ZSTD_c_format :\n        *value = CCtxParams->format;\n        break;\n    case ZSTD_c_compressionLevel :\n        *value = CCtxParams->compressionLevel;\n        break;\n    case ZSTD_c_windowLog :\n        *value = (int)CCtxParams->cParams.windowLog;\n        break;\n    case ZSTD_c_hashLog :\n        *value = (int)CCtxParams->cParams.hashLog;\n        break;\n    case ZSTD_c_chainLog :\n        *value = (int)CCtxParams->cParams.chainLog;\n        break;\n    case ZSTD_c_searchLog :\n        *value = CCtxParams->cParams.searchLog;\n        break;\n    case ZSTD_c_minMatch :\n        *value = CCtxParams->cParams.minMatch;\n        break;\n    case ZSTD_c_targetLength :\n        *value = CCtxParams->cParams.targetLength;\n        break;\n    case ZSTD_c_strategy :\n        *value = (unsigned)CCtxParams->cParams.strategy;\n        break;\n    case ZSTD_c_contentSizeFlag :\n        *value = CCtxParams->fParams.contentSizeFlag;\n        break;\n    case ZSTD_c_checksumFlag :\n        *value = CCtxParams->fParams.checksumFlag;\n        break;\n    case ZSTD_c_dictIDFlag :\n        *value = !CCtxParams->fParams.noDictIDFlag;\n        break;\n    case ZSTD_c_forceMaxWindow :\n        *value = CCtxParams->forceWindow;\n        break;\n    case ZSTD_c_forceAttachDict :\n        *value = CCtxParams->attachDictPref;\n        break;\n    case ZSTD_c_literalCompressionMode :\n        *value = CCtxParams->literalCompressionMode;\n        break;\n    case ZSTD_c_nbWorkers :\n#ifndef ZSTD_MULTITHREAD\n        assert(CCtxParams->nbWorkers == 0);\n#endif\n        *value = CCtxParams->nbWorkers;\n        break;\n    case ZSTD_c_jobSize :\n#ifndef ZSTD_MULTITHREAD\n        RETURN_ERROR(parameter_unsupported, \"not compiled with multithreading\");\n#else\n        assert(CCtxParams->jobSize <= INT_MAX);\n        *value = (int)CCtxParams->jobSize;\n        break;\n#endif\n    case ZSTD_c_overlapLog :\n#ifndef ZSTD_MULTITHREAD\n        RETURN_ERROR(parameter_unsupported, \"not compiled with multithreading\");\n#else\n        *value = CCtxParams->overlapLog;\n        break;\n#endif\n    case ZSTD_c_rsyncable :\n#ifndef ZSTD_MULTITHREAD\n        RETURN_ERROR(parameter_unsupported, \"not compiled with multithreading\");\n#else\n        *value = CCtxParams->rsyncable;\n        break;\n#endif\n    case ZSTD_c_enableLongDistanceMatching :\n        *value = CCtxParams->ldmParams.enableLdm;\n        break;\n    case ZSTD_c_ldmHashLog :\n        *value = CCtxParams->ldmParams.hashLog;\n        break;\n    case ZSTD_c_ldmMinMatch :\n        *value = CCtxParams->ldmParams.minMatchLength;\n        break;\n    case ZSTD_c_ldmBucketSizeLog :\n        *value = CCtxParams->ldmParams.bucketSizeLog;\n        break;\n    case ZSTD_c_ldmHashRateLog :\n        *value = CCtxParams->ldmParams.hashRateLog;\n        break;\n    case ZSTD_c_targetCBlockSize :\n        *value = (int)CCtxParams->targetCBlockSize;\n        break;\n    case ZSTD_c_srcSizeHint :\n        *value = (int)CCtxParams->srcSizeHint;\n        break;\n    default: RETURN_ERROR(parameter_unsupported, \"unknown parameter\");\n    }\n    return 0;\n}\n\n/** ZSTD_CCtx_setParametersUsingCCtxParams() :\n *  just applies `params` into `cctx`\n *  no action is performed, parameters are merely stored.\n *  If ZSTDMT is enabled, parameters are pushed to cctx->mtctx.\n *    This is possible even if a compression is ongoing.\n *    In which case, new parameters will be applied on the fly, starting with next compression job.\n */\nsize_t ZSTD_CCtx_setParametersUsingCCtxParams(\n        ZSTD_CCtx* cctx, const ZSTD_CCtx_params* params)\n{\n    DEBUGLOG(4, \"ZSTD_CCtx_setParametersUsingCCtxParams\");\n    RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);\n    RETURN_ERROR_IF(cctx->cdict, stage_wrong);\n\n    cctx->requestedParams = *params;\n    return 0;\n}\n\nZSTDLIB_API size_t ZSTD_CCtx_setPledgedSrcSize(ZSTD_CCtx* cctx, unsigned long long pledgedSrcSize)\n{\n    DEBUGLOG(4, \"ZSTD_CCtx_setPledgedSrcSize to %u bytes\", (U32)pledgedSrcSize);\n    RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);\n    cctx->pledgedSrcSizePlusOne = pledgedSrcSize+1;\n    return 0;\n}\n\n/**\n * Initializes the local dict using the requested parameters.\n * NOTE: This does not use the pledged src size, because it may be used for more\n * than one compression.\n */\nstatic size_t ZSTD_initLocalDict(ZSTD_CCtx* cctx)\n{\n    ZSTD_localDict* const dl = &cctx->localDict;\n    ZSTD_compressionParameters const cParams = ZSTD_getCParamsFromCCtxParams(\n            &cctx->requestedParams, 0, dl->dictSize);\n    if (dl->dict == NULL) {\n        /* No local dictionary. */\n        assert(dl->dictBuffer == NULL);\n        assert(dl->cdict == NULL);\n        assert(dl->dictSize == 0);\n        return 0;\n    }\n    if (dl->cdict != NULL) {\n        assert(cctx->cdict == dl->cdict);\n        /* Local dictionary already initialized. */\n        return 0;\n    }\n    assert(dl->dictSize > 0);\n    assert(cctx->cdict == NULL);\n    assert(cctx->prefixDict.dict == NULL);\n\n    dl->cdict = ZSTD_createCDict_advanced(\n            dl->dict,\n            dl->dictSize,\n            ZSTD_dlm_byRef,\n            dl->dictContentType,\n            cParams,\n            cctx->customMem);\n    RETURN_ERROR_IF(!dl->cdict, memory_allocation);\n    cctx->cdict = dl->cdict;\n    return 0;\n}\n\nsize_t ZSTD_CCtx_loadDictionary_advanced(\n        ZSTD_CCtx* cctx, const void* dict, size_t dictSize,\n        ZSTD_dictLoadMethod_e dictLoadMethod, ZSTD_dictContentType_e dictContentType)\n{\n    RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);\n    RETURN_ERROR_IF(cctx->staticSize, memory_allocation,\n                    \"no malloc for static CCtx\");\n    DEBUGLOG(4, \"ZSTD_CCtx_loadDictionary_advanced (size: %u)\", (U32)dictSize);\n    ZSTD_clearAllDicts(cctx);  /* in case one already exists */\n    if (dict == NULL || dictSize == 0)  /* no dictionary mode */\n        return 0;\n    if (dictLoadMethod == ZSTD_dlm_byRef) {\n        cctx->localDict.dict = dict;\n    } else {\n        void* dictBuffer = ZSTD_malloc(dictSize, cctx->customMem);\n        RETURN_ERROR_IF(!dictBuffer, memory_allocation);\n        memcpy(dictBuffer, dict, dictSize);\n        cctx->localDict.dictBuffer = dictBuffer;\n        cctx->localDict.dict = dictBuffer;\n    }\n    cctx->localDict.dictSize = dictSize;\n    cctx->localDict.dictContentType = dictContentType;\n    return 0;\n}\n\nZSTDLIB_API size_t ZSTD_CCtx_loadDictionary_byReference(\n      ZSTD_CCtx* cctx, const void* dict, size_t dictSize)\n{\n    return ZSTD_CCtx_loadDictionary_advanced(\n            cctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);\n}\n\nZSTDLIB_API size_t ZSTD_CCtx_loadDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)\n{\n    return ZSTD_CCtx_loadDictionary_advanced(\n            cctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);\n}\n\n\nsize_t ZSTD_CCtx_refCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)\n{\n    RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);\n    /* Free the existing local cdict (if any) to save memory. */\n    ZSTD_clearAllDicts(cctx);\n    cctx->cdict = cdict;\n    return 0;\n}\n\nsize_t ZSTD_CCtx_refPrefix(ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize)\n{\n    return ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, ZSTD_dct_rawContent);\n}\n\nsize_t ZSTD_CCtx_refPrefix_advanced(\n        ZSTD_CCtx* cctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)\n{\n    RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);\n    ZSTD_clearAllDicts(cctx);\n    cctx->prefixDict.dict = prefix;\n    cctx->prefixDict.dictSize = prefixSize;\n    cctx->prefixDict.dictContentType = dictContentType;\n    return 0;\n}\n\n/*! ZSTD_CCtx_reset() :\n *  Also dumps dictionary */\nsize_t ZSTD_CCtx_reset(ZSTD_CCtx* cctx, ZSTD_ResetDirective reset)\n{\n    if ( (reset == ZSTD_reset_session_only)\n      || (reset == ZSTD_reset_session_and_parameters) ) {\n        cctx->streamStage = zcss_init;\n        cctx->pledgedSrcSizePlusOne = 0;\n    }\n    if ( (reset == ZSTD_reset_parameters)\n      || (reset == ZSTD_reset_session_and_parameters) ) {\n        RETURN_ERROR_IF(cctx->streamStage != zcss_init, stage_wrong);\n        ZSTD_clearAllDicts(cctx);\n        return ZSTD_CCtxParams_reset(&cctx->requestedParams);\n    }\n    return 0;\n}\n\n\n/** ZSTD_checkCParams() :\n    control CParam values remain within authorized range.\n    @return : 0, or an error code if one value is beyond authorized range */\nsize_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)\n{\n    BOUNDCHECK(ZSTD_c_windowLog, (int)cParams.windowLog);\n    BOUNDCHECK(ZSTD_c_chainLog,  (int)cParams.chainLog);\n    BOUNDCHECK(ZSTD_c_hashLog,   (int)cParams.hashLog);\n    BOUNDCHECK(ZSTD_c_searchLog, (int)cParams.searchLog);\n    BOUNDCHECK(ZSTD_c_minMatch,  (int)cParams.minMatch);\n    BOUNDCHECK(ZSTD_c_targetLength,(int)cParams.targetLength);\n    BOUNDCHECK(ZSTD_c_strategy,  cParams.strategy);\n    return 0;\n}\n\n/** ZSTD_clampCParams() :\n *  make CParam values within valid range.\n *  @return : valid CParams */\nstatic ZSTD_compressionParameters\nZSTD_clampCParams(ZSTD_compressionParameters cParams)\n{\n#   define CLAMP_TYPE(cParam, val, type) {                                \\\n        ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);         \\\n        if ((int)val<bounds.lowerBound) val=(type)bounds.lowerBound;      \\\n        else if ((int)val>bounds.upperBound) val=(type)bounds.upperBound; \\\n    }\n#   define CLAMP(cParam, val) CLAMP_TYPE(cParam, val, unsigned)\n    CLAMP(ZSTD_c_windowLog, cParams.windowLog);\n    CLAMP(ZSTD_c_chainLog,  cParams.chainLog);\n    CLAMP(ZSTD_c_hashLog,   cParams.hashLog);\n    CLAMP(ZSTD_c_searchLog, cParams.searchLog);\n    CLAMP(ZSTD_c_minMatch,  cParams.minMatch);\n    CLAMP(ZSTD_c_targetLength,cParams.targetLength);\n    CLAMP_TYPE(ZSTD_c_strategy,cParams.strategy, ZSTD_strategy);\n    return cParams;\n}\n\n/** ZSTD_cycleLog() :\n *  condition for correct operation : hashLog > 1 */\nstatic U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)\n{\n    U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);\n    return hashLog - btScale;\n}\n\n/** ZSTD_adjustCParams_internal() :\n *  optimize `cPar` for a specified input (`srcSize` and `dictSize`).\n *  mostly downsize to reduce memory consumption and initialization latency.\n * `srcSize` can be ZSTD_CONTENTSIZE_UNKNOWN when not known.\n *  note : for the time being, `srcSize==0` means \"unknown\" too, for compatibility with older convention.\n *  condition : cPar is presumed validated (can be checked using ZSTD_checkCParams()). */\nstatic ZSTD_compressionParameters\nZSTD_adjustCParams_internal(ZSTD_compressionParameters cPar,\n                            unsigned long long srcSize,\n                            size_t dictSize)\n{\n    static const U64 minSrcSize = 513; /* (1<<9) + 1 */\n    static const U64 maxWindowResize = 1ULL << (ZSTD_WINDOWLOG_MAX-1);\n    assert(ZSTD_checkCParams(cPar)==0);\n\n    if (dictSize && (srcSize+1<2) /* ZSTD_CONTENTSIZE_UNKNOWN and 0 mean \"unknown\" */ )\n        srcSize = minSrcSize;  /* presumed small when there is a dictionary */\n    else if (srcSize == 0)\n        srcSize = ZSTD_CONTENTSIZE_UNKNOWN;  /* 0 == unknown : presumed large */\n\n    /* resize windowLog if input is small enough, to use less memory */\n    if ( (srcSize < maxWindowResize)\n      && (dictSize < maxWindowResize) )  {\n        U32 const tSize = (U32)(srcSize + dictSize);\n        static U32 const hashSizeMin = 1 << ZSTD_HASHLOG_MIN;\n        U32 const srcLog = (tSize < hashSizeMin) ? ZSTD_HASHLOG_MIN :\n                            ZSTD_highbit32(tSize-1) + 1;\n        if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;\n    }\n    if (cPar.hashLog > cPar.windowLog+1) cPar.hashLog = cPar.windowLog+1;\n    {   U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);\n        if (cycleLog > cPar.windowLog)\n            cPar.chainLog -= (cycleLog - cPar.windowLog);\n    }\n\n    if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN)\n        cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN;  /* minimum wlog required for valid frame header */\n\n    return cPar;\n}\n\nZSTD_compressionParameters\nZSTD_adjustCParams(ZSTD_compressionParameters cPar,\n                   unsigned long long srcSize,\n                   size_t dictSize)\n{\n    cPar = ZSTD_clampCParams(cPar);   /* resulting cPar is necessarily valid (all parameters within range) */\n    return ZSTD_adjustCParams_internal(cPar, srcSize, dictSize);\n}\n\nZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(\n        const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize)\n{\n    ZSTD_compressionParameters cParams;\n    if (srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN && CCtxParams->srcSizeHint > 0) {\n      srcSizeHint = CCtxParams->srcSizeHint;\n    }\n    cParams = ZSTD_getCParams(CCtxParams->compressionLevel, srcSizeHint, dictSize);\n    if (CCtxParams->ldmParams.enableLdm) cParams.windowLog = ZSTD_LDM_DEFAULT_WINDOW_LOG;\n    if (CCtxParams->cParams.windowLog) cParams.windowLog = CCtxParams->cParams.windowLog;\n    if (CCtxParams->cParams.hashLog) cParams.hashLog = CCtxParams->cParams.hashLog;\n    if (CCtxParams->cParams.chainLog) cParams.chainLog = CCtxParams->cParams.chainLog;\n    if (CCtxParams->cParams.searchLog) cParams.searchLog = CCtxParams->cParams.searchLog;\n    if (CCtxParams->cParams.minMatch) cParams.minMatch = CCtxParams->cParams.minMatch;\n    if (CCtxParams->cParams.targetLength) cParams.targetLength = CCtxParams->cParams.targetLength;\n    if (CCtxParams->cParams.strategy) cParams.strategy = CCtxParams->cParams.strategy;\n    assert(!ZSTD_checkCParams(cParams));\n    return ZSTD_adjustCParams_internal(cParams, srcSizeHint, dictSize);\n}\n\nstatic size_t\nZSTD_sizeof_matchState(const ZSTD_compressionParameters* const cParams,\n                       const U32 forCCtx)\n{\n    size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);\n    size_t const hSize = ((size_t)1) << cParams->hashLog;\n    U32    const hashLog3 = (forCCtx && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;\n    size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;\n    /* We don't use ZSTD_cwksp_alloc_size() here because the tables aren't\n     * surrounded by redzones in ASAN. */\n    size_t const tableSpace = chainSize * sizeof(U32)\n                            + hSize * sizeof(U32)\n                            + h3Size * sizeof(U32);\n    size_t const optPotentialSpace =\n        ZSTD_cwksp_alloc_size((MaxML+1) * sizeof(U32))\n      + ZSTD_cwksp_alloc_size((MaxLL+1) * sizeof(U32))\n      + ZSTD_cwksp_alloc_size((MaxOff+1) * sizeof(U32))\n      + ZSTD_cwksp_alloc_size((1<<Litbits) * sizeof(U32))\n      + ZSTD_cwksp_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t))\n      + ZSTD_cwksp_alloc_size((ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));\n    size_t const optSpace = (forCCtx && (cParams->strategy >= ZSTD_btopt))\n                                ? optPotentialSpace\n                                : 0;\n    DEBUGLOG(4, \"chainSize: %u - hSize: %u - h3Size: %u\",\n                (U32)chainSize, (U32)hSize, (U32)h3Size);\n    return tableSpace + optSpace;\n}\n\nsize_t ZSTD_estimateCCtxSize_usingCCtxParams(const ZSTD_CCtx_params* params)\n{\n    RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, \"Estimate CCtx size is supported for single-threaded compression only.\");\n    {   ZSTD_compressionParameters const cParams =\n                ZSTD_getCParamsFromCCtxParams(params, 0, 0);\n        size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);\n        U32    const divider = (cParams.minMatch==3) ? 3 : 4;\n        size_t const maxNbSeq = blockSize / divider;\n        size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)\n                                + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))\n                                + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));\n        size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE);\n        size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));\n        size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 1);\n\n        size_t const ldmSpace = ZSTD_ldm_getTableSize(params->ldmParams);\n        size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(ZSTD_ldm_getMaxNbSeq(params->ldmParams, blockSize) * sizeof(rawSeq));\n\n        size_t const neededSpace = entropySpace + blockStateSpace + tokenSpace +\n                                   matchStateSize + ldmSpace + ldmSeqSpace;\n        size_t const cctxSpace = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx));\n\n        DEBUGLOG(5, \"sizeof(ZSTD_CCtx) : %u\", (U32)cctxSpace);\n        DEBUGLOG(5, \"estimate workspace : %u\", (U32)neededSpace);\n        return cctxSpace + neededSpace;\n    }\n}\n\nsize_t ZSTD_estimateCCtxSize_usingCParams(ZSTD_compressionParameters cParams)\n{\n    ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);\n    return ZSTD_estimateCCtxSize_usingCCtxParams(&params);\n}\n\nstatic size_t ZSTD_estimateCCtxSize_internal(int compressionLevel)\n{\n    ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);\n    return ZSTD_estimateCCtxSize_usingCParams(cParams);\n}\n\nsize_t ZSTD_estimateCCtxSize(int compressionLevel)\n{\n    int level;\n    size_t memBudget = 0;\n    for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) {\n        size_t const newMB = ZSTD_estimateCCtxSize_internal(level);\n        if (newMB > memBudget) memBudget = newMB;\n    }\n    return memBudget;\n}\n\nsize_t ZSTD_estimateCStreamSize_usingCCtxParams(const ZSTD_CCtx_params* params)\n{\n    RETURN_ERROR_IF(params->nbWorkers > 0, GENERIC, \"Estimate CCtx size is supported for single-threaded compression only.\");\n    {   ZSTD_compressionParameters const cParams =\n                ZSTD_getCParamsFromCCtxParams(params, 0, 0);\n        size_t const CCtxSize = ZSTD_estimateCCtxSize_usingCCtxParams(params);\n        size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, (size_t)1 << cParams.windowLog);\n        size_t const inBuffSize = ((size_t)1 << cParams.windowLog) + blockSize;\n        size_t const outBuffSize = ZSTD_compressBound(blockSize) + 1;\n        size_t const streamingSize = ZSTD_cwksp_alloc_size(inBuffSize)\n                                   + ZSTD_cwksp_alloc_size(outBuffSize);\n\n        return CCtxSize + streamingSize;\n    }\n}\n\nsize_t ZSTD_estimateCStreamSize_usingCParams(ZSTD_compressionParameters cParams)\n{\n    ZSTD_CCtx_params const params = ZSTD_makeCCtxParamsFromCParams(cParams);\n    return ZSTD_estimateCStreamSize_usingCCtxParams(&params);\n}\n\nstatic size_t ZSTD_estimateCStreamSize_internal(int compressionLevel)\n{\n    ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, 0);\n    return ZSTD_estimateCStreamSize_usingCParams(cParams);\n}\n\nsize_t ZSTD_estimateCStreamSize(int compressionLevel)\n{\n    int level;\n    size_t memBudget = 0;\n    for (level=MIN(compressionLevel, 1); level<=compressionLevel; level++) {\n        size_t const newMB = ZSTD_estimateCStreamSize_internal(level);\n        if (newMB > memBudget) memBudget = newMB;\n    }\n    return memBudget;\n}\n\n/* ZSTD_getFrameProgression():\n * tells how much data has been consumed (input) and produced (output) for current frame.\n * able to count progression inside worker threads (non-blocking mode).\n */\nZSTD_frameProgression ZSTD_getFrameProgression(const ZSTD_CCtx* cctx)\n{\n#ifdef ZSTD_MULTITHREAD\n    if (cctx->appliedParams.nbWorkers > 0) {\n        return ZSTDMT_getFrameProgression(cctx->mtctx);\n    }\n#endif\n    {   ZSTD_frameProgression fp;\n        size_t const buffered = (cctx->inBuff == NULL) ? 0 :\n                                cctx->inBuffPos - cctx->inToCompress;\n        if (buffered) assert(cctx->inBuffPos >= cctx->inToCompress);\n        assert(buffered <= ZSTD_BLOCKSIZE_MAX);\n        fp.ingested = cctx->consumedSrcSize + buffered;\n        fp.consumed = cctx->consumedSrcSize;\n        fp.produced = cctx->producedCSize;\n        fp.flushed  = cctx->producedCSize;   /* simplified; some data might still be left within streaming output buffer */\n        fp.currentJobID = 0;\n        fp.nbActiveWorkers = 0;\n        return fp;\n}   }\n\n/*! ZSTD_toFlushNow()\n *  Only useful for multithreading scenarios currently (nbWorkers >= 1).\n */\nsize_t ZSTD_toFlushNow(ZSTD_CCtx* cctx)\n{\n#ifdef ZSTD_MULTITHREAD\n    if (cctx->appliedParams.nbWorkers > 0) {\n        return ZSTDMT_toFlushNow(cctx->mtctx);\n    }\n#endif\n    (void)cctx;\n    return 0;   /* over-simplification; could also check if context is currently running in streaming mode, and in which case, report how many bytes are left to be flushed within output buffer */\n}\n\nstatic void ZSTD_assertEqualCParams(ZSTD_compressionParameters cParams1,\n                                    ZSTD_compressionParameters cParams2)\n{\n    (void)cParams1;\n    (void)cParams2;\n    assert(cParams1.windowLog    == cParams2.windowLog);\n    assert(cParams1.chainLog     == cParams2.chainLog);\n    assert(cParams1.hashLog      == cParams2.hashLog);\n    assert(cParams1.searchLog    == cParams2.searchLog);\n    assert(cParams1.minMatch     == cParams2.minMatch);\n    assert(cParams1.targetLength == cParams2.targetLength);\n    assert(cParams1.strategy     == cParams2.strategy);\n}\n\nstatic void ZSTD_reset_compressedBlockState(ZSTD_compressedBlockState_t* bs)\n{\n    int i;\n    for (i = 0; i < ZSTD_REP_NUM; ++i)\n        bs->rep[i] = repStartValue[i];\n    bs->entropy.huf.repeatMode = HUF_repeat_none;\n    bs->entropy.fse.offcode_repeatMode = FSE_repeat_none;\n    bs->entropy.fse.matchlength_repeatMode = FSE_repeat_none;\n    bs->entropy.fse.litlength_repeatMode = FSE_repeat_none;\n}\n\n/*! ZSTD_invalidateMatchState()\n *  Invalidate all the matches in the match finder tables.\n *  Requires nextSrc and base to be set (can be NULL).\n */\nstatic void ZSTD_invalidateMatchState(ZSTD_matchState_t* ms)\n{\n    ZSTD_window_clear(&ms->window);\n\n    ms->nextToUpdate = ms->window.dictLimit;\n    ms->loadedDictEnd = 0;\n    ms->opt.litLengthSum = 0;  /* force reset of btopt stats */\n    ms->dictMatchState = NULL;\n}\n\n/**\n * Indicates whether this compression proceeds directly from user-provided\n * source buffer to user-provided destination buffer (ZSTDb_not_buffered), or\n * whether the context needs to buffer the input/output (ZSTDb_buffered).\n */\ntypedef enum {\n    ZSTDb_not_buffered,\n    ZSTDb_buffered\n} ZSTD_buffered_policy_e;\n\n/**\n * Controls, for this matchState reset, whether the tables need to be cleared /\n * prepared for the coming compression (ZSTDcrp_makeClean), or whether the\n * tables can be left unclean (ZSTDcrp_leaveDirty), because we know that a\n * subsequent operation will overwrite the table space anyways (e.g., copying\n * the matchState contents in from a CDict).\n */\ntypedef enum {\n    ZSTDcrp_makeClean,\n    ZSTDcrp_leaveDirty\n} ZSTD_compResetPolicy_e;\n\n/**\n * Controls, for this matchState reset, whether indexing can continue where it\n * left off (ZSTDirp_continue), or whether it needs to be restarted from zero\n * (ZSTDirp_reset).\n */\ntypedef enum {\n    ZSTDirp_continue,\n    ZSTDirp_reset\n} ZSTD_indexResetPolicy_e;\n\ntypedef enum {\n    ZSTD_resetTarget_CDict,\n    ZSTD_resetTarget_CCtx\n} ZSTD_resetTarget_e;\n\nstatic size_t\nZSTD_reset_matchState(ZSTD_matchState_t* ms,\n                      ZSTD_cwksp* ws,\n                const ZSTD_compressionParameters* cParams,\n                const ZSTD_compResetPolicy_e crp,\n                const ZSTD_indexResetPolicy_e forceResetIndex,\n                const ZSTD_resetTarget_e forWho)\n{\n    size_t const chainSize = (cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cParams->chainLog);\n    size_t const hSize = ((size_t)1) << cParams->hashLog;\n    U32    const hashLog3 = ((forWho == ZSTD_resetTarget_CCtx) && cParams->minMatch==3) ? MIN(ZSTD_HASHLOG3_MAX, cParams->windowLog) : 0;\n    size_t const h3Size = hashLog3 ? ((size_t)1) << hashLog3 : 0;\n\n    DEBUGLOG(4, \"reset indices : %u\", forceResetIndex == ZSTDirp_reset);\n    if (forceResetIndex == ZSTDirp_reset) {\n        memset(&ms->window, 0, sizeof(ms->window));\n        ms->window.dictLimit = 1;    /* start from 1, so that 1st position is valid */\n        ms->window.lowLimit = 1;     /* it ensures first and later CCtx usages compress the same */\n        ms->window.nextSrc = ms->window.base + 1;   /* see issue #1241 */\n        ZSTD_cwksp_mark_tables_dirty(ws);\n    }\n\n    ms->hashLog3 = hashLog3;\n\n    ZSTD_invalidateMatchState(ms);\n\n    assert(!ZSTD_cwksp_reserve_failed(ws)); /* check that allocation hasn't already failed */\n\n    ZSTD_cwksp_clear_tables(ws);\n\n    DEBUGLOG(5, \"reserving table space\");\n    /* table Space */\n    ms->hashTable = (U32*)ZSTD_cwksp_reserve_table(ws, hSize * sizeof(U32));\n    ms->chainTable = (U32*)ZSTD_cwksp_reserve_table(ws, chainSize * sizeof(U32));\n    ms->hashTable3 = (U32*)ZSTD_cwksp_reserve_table(ws, h3Size * sizeof(U32));\n    RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,\n                    \"failed a workspace allocation in ZSTD_reset_matchState\");\n\n    DEBUGLOG(4, \"reset table : %u\", crp!=ZSTDcrp_leaveDirty);\n    if (crp!=ZSTDcrp_leaveDirty) {\n        /* reset tables only */\n        ZSTD_cwksp_clean_tables(ws);\n    }\n\n    /* opt parser space */\n    if ((forWho == ZSTD_resetTarget_CCtx) && (cParams->strategy >= ZSTD_btopt)) {\n        DEBUGLOG(4, \"reserving optimal parser space\");\n        ms->opt.litFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (1<<Litbits) * sizeof(unsigned));\n        ms->opt.litLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxLL+1) * sizeof(unsigned));\n        ms->opt.matchLengthFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxML+1) * sizeof(unsigned));\n        ms->opt.offCodeFreq = (unsigned*)ZSTD_cwksp_reserve_aligned(ws, (MaxOff+1) * sizeof(unsigned));\n        ms->opt.matchTable = (ZSTD_match_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_match_t));\n        ms->opt.priceTable = (ZSTD_optimal_t*)ZSTD_cwksp_reserve_aligned(ws, (ZSTD_OPT_NUM+1) * sizeof(ZSTD_optimal_t));\n    }\n\n    ms->cParams = *cParams;\n\n    RETURN_ERROR_IF(ZSTD_cwksp_reserve_failed(ws), memory_allocation,\n                    \"failed a workspace allocation in ZSTD_reset_matchState\");\n\n    return 0;\n}\n\n/* ZSTD_indexTooCloseToMax() :\n * minor optimization : prefer memset() rather than reduceIndex()\n * which is measurably slow in some circumstances (reported for Visual Studio).\n * Works when re-using a context for a lot of smallish inputs :\n * if all inputs are smaller than ZSTD_INDEXOVERFLOW_MARGIN,\n * memset() will be triggered before reduceIndex().\n */\n#define ZSTD_INDEXOVERFLOW_MARGIN (16 MB)\nstatic int ZSTD_indexTooCloseToMax(ZSTD_window_t w)\n{\n    return (size_t)(w.nextSrc - w.base) > (ZSTD_CURRENT_MAX - ZSTD_INDEXOVERFLOW_MARGIN);\n}\n\n/*! ZSTD_resetCCtx_internal() :\n    note : `params` are assumed fully validated at this stage */\nstatic size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,\n                                      ZSTD_CCtx_params params,\n                                      U64 const pledgedSrcSize,\n                                      ZSTD_compResetPolicy_e const crp,\n                                      ZSTD_buffered_policy_e const zbuff)\n{\n    ZSTD_cwksp* const ws = &zc->workspace;\n    DEBUGLOG(4, \"ZSTD_resetCCtx_internal: pledgedSrcSize=%u, wlog=%u\",\n                (U32)pledgedSrcSize, params.cParams.windowLog);\n    assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));\n\n    zc->isFirstBlock = 1;\n\n    if (params.ldmParams.enableLdm) {\n        /* Adjust long distance matching parameters */\n        ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);\n        assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);\n        assert(params.ldmParams.hashRateLog < 32);\n        zc->ldmState.hashPower = ZSTD_rollingHash_primePower(params.ldmParams.minMatchLength);\n    }\n\n    {   size_t const windowSize = MAX(1, (size_t)MIN(((U64)1 << params.cParams.windowLog), pledgedSrcSize));\n        size_t const blockSize = MIN(ZSTD_BLOCKSIZE_MAX, windowSize);\n        U32    const divider = (params.cParams.minMatch==3) ? 3 : 4;\n        size_t const maxNbSeq = blockSize / divider;\n        size_t const tokenSpace = ZSTD_cwksp_alloc_size(WILDCOPY_OVERLENGTH + blockSize)\n                                + ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(seqDef))\n                                + 3 * ZSTD_cwksp_alloc_size(maxNbSeq * sizeof(BYTE));\n        size_t const buffOutSize = (zbuff==ZSTDb_buffered) ? ZSTD_compressBound(blockSize)+1 : 0;\n        size_t const buffInSize = (zbuff==ZSTDb_buffered) ? windowSize + blockSize : 0;\n        size_t const matchStateSize = ZSTD_sizeof_matchState(&params.cParams, /* forCCtx */ 1);\n        size_t const maxNbLdmSeq = ZSTD_ldm_getMaxNbSeq(params.ldmParams, blockSize);\n\n        ZSTD_indexResetPolicy_e needsIndexReset = ZSTDirp_continue;\n\n        if (ZSTD_indexTooCloseToMax(zc->blockState.matchState.window)) {\n            needsIndexReset = ZSTDirp_reset;\n        }\n\n        ZSTD_cwksp_bump_oversized_duration(ws, 0);\n\n        /* Check if workspace is large enough, alloc a new one if needed */\n        {   size_t const cctxSpace = zc->staticSize ? ZSTD_cwksp_alloc_size(sizeof(ZSTD_CCtx)) : 0;\n            size_t const entropySpace = ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE);\n            size_t const blockStateSpace = 2 * ZSTD_cwksp_alloc_size(sizeof(ZSTD_compressedBlockState_t));\n            size_t const bufferSpace = ZSTD_cwksp_alloc_size(buffInSize) + ZSTD_cwksp_alloc_size(buffOutSize);\n            size_t const ldmSpace = ZSTD_ldm_getTableSize(params.ldmParams);\n            size_t const ldmSeqSpace = ZSTD_cwksp_alloc_size(maxNbLdmSeq * sizeof(rawSeq));\n\n            size_t const neededSpace =\n                cctxSpace +\n                entropySpace +\n                blockStateSpace +\n                ldmSpace +\n                ldmSeqSpace +\n                matchStateSize +\n                tokenSpace +\n                bufferSpace;\n\n            int const workspaceTooSmall = ZSTD_cwksp_sizeof(ws) < neededSpace;\n            int const workspaceWasteful = ZSTD_cwksp_check_wasteful(ws, neededSpace);\n\n            DEBUGLOG(4, \"Need %zuKB workspace, including %zuKB for match state, and %zuKB for buffers\",\n                        neededSpace>>10, matchStateSize>>10, bufferSpace>>10);\n            DEBUGLOG(4, \"windowSize: %zu - blockSize: %zu\", windowSize, blockSize);\n\n            if (workspaceTooSmall || workspaceWasteful) {\n                DEBUGLOG(4, \"Resize workspaceSize from %zuKB to %zuKB\",\n                            ZSTD_cwksp_sizeof(ws) >> 10,\n                            neededSpace >> 10);\n\n                RETURN_ERROR_IF(zc->staticSize, memory_allocation, \"static cctx : no resize\");\n\n                needsIndexReset = ZSTDirp_reset;\n\n                ZSTD_cwksp_free(ws, zc->customMem);\n                FORWARD_IF_ERROR(ZSTD_cwksp_create(ws, neededSpace, zc->customMem));\n\n                DEBUGLOG(5, \"reserving object space\");\n                /* Statically sized space.\n                 * entropyWorkspace never moves,\n                 * though prev/next block swap places */\n                assert(ZSTD_cwksp_check_available(ws, 2 * sizeof(ZSTD_compressedBlockState_t)));\n                zc->blockState.prevCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));\n                RETURN_ERROR_IF(zc->blockState.prevCBlock == NULL, memory_allocation, \"couldn't allocate prevCBlock\");\n                zc->blockState.nextCBlock = (ZSTD_compressedBlockState_t*) ZSTD_cwksp_reserve_object(ws, sizeof(ZSTD_compressedBlockState_t));\n                RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, \"couldn't allocate nextCBlock\");\n                zc->entropyWorkspace = (U32*) ZSTD_cwksp_reserve_object(ws, HUF_WORKSPACE_SIZE);\n                RETURN_ERROR_IF(zc->blockState.nextCBlock == NULL, memory_allocation, \"couldn't allocate entropyWorkspace\");\n        }   }\n\n        ZSTD_cwksp_clear(ws);\n\n        /* init params */\n        zc->appliedParams = params;\n        zc->blockState.matchState.cParams = params.cParams;\n        zc->pledgedSrcSizePlusOne = pledgedSrcSize+1;\n        zc->consumedSrcSize = 0;\n        zc->producedCSize = 0;\n        if (pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN)\n            zc->appliedParams.fParams.contentSizeFlag = 0;\n        DEBUGLOG(4, \"pledged content size : %u ; flag : %u\",\n            (unsigned)pledgedSrcSize, zc->appliedParams.fParams.contentSizeFlag);\n        zc->blockSize = blockSize;\n\n        XXH64_reset(&zc->xxhState, 0);\n        zc->stage = ZSTDcs_init;\n        zc->dictID = 0;\n\n        ZSTD_reset_compressedBlockState(zc->blockState.prevCBlock);\n\n        /* ZSTD_wildcopy() is used to copy into the literals buffer,\n         * so we have to oversize the buffer by WILDCOPY_OVERLENGTH bytes.\n         */\n        zc->seqStore.litStart = ZSTD_cwksp_reserve_buffer(ws, blockSize + WILDCOPY_OVERLENGTH);\n        zc->seqStore.maxNbLit = blockSize;\n\n        /* buffers */\n        zc->inBuffSize = buffInSize;\n        zc->inBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffInSize);\n        zc->outBuffSize = buffOutSize;\n        zc->outBuff = (char*)ZSTD_cwksp_reserve_buffer(ws, buffOutSize);\n\n        /* ldm bucketOffsets table */\n        if (params.ldmParams.enableLdm) {\n            /* TODO: avoid memset? */\n            size_t const ldmBucketSize =\n                  ((size_t)1) << (params.ldmParams.hashLog -\n                                  params.ldmParams.bucketSizeLog);\n            zc->ldmState.bucketOffsets = ZSTD_cwksp_reserve_buffer(ws, ldmBucketSize);\n            memset(zc->ldmState.bucketOffsets, 0, ldmBucketSize);\n        }\n\n        /* sequences storage */\n        ZSTD_referenceExternalSequences(zc, NULL, 0);\n        zc->seqStore.maxNbSeq = maxNbSeq;\n        zc->seqStore.llCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));\n        zc->seqStore.mlCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));\n        zc->seqStore.ofCode = ZSTD_cwksp_reserve_buffer(ws, maxNbSeq * sizeof(BYTE));\n        zc->seqStore.sequencesStart = (seqDef*)ZSTD_cwksp_reserve_aligned(ws, maxNbSeq * sizeof(seqDef));\n\n        FORWARD_IF_ERROR(ZSTD_reset_matchState(\n            &zc->blockState.matchState,\n            ws,\n            &params.cParams,\n            crp,\n            needsIndexReset,\n            ZSTD_resetTarget_CCtx));\n\n        /* ldm hash table */\n        if (params.ldmParams.enableLdm) {\n            /* TODO: avoid memset? */\n            size_t const ldmHSize = ((size_t)1) << params.ldmParams.hashLog;\n            zc->ldmState.hashTable = (ldmEntry_t*)ZSTD_cwksp_reserve_aligned(ws, ldmHSize * sizeof(ldmEntry_t));\n            memset(zc->ldmState.hashTable, 0, ldmHSize * sizeof(ldmEntry_t));\n            zc->ldmSequences = (rawSeq*)ZSTD_cwksp_reserve_aligned(ws, maxNbLdmSeq * sizeof(rawSeq));\n            zc->maxNbLdmSequences = maxNbLdmSeq;\n\n            memset(&zc->ldmState.window, 0, sizeof(zc->ldmState.window));\n            ZSTD_window_clear(&zc->ldmState.window);\n        }\n\n        DEBUGLOG(3, \"wksp: finished allocating, %zd bytes remain available\", ZSTD_cwksp_available_space(ws));\n\n        return 0;\n    }\n}\n\n/* ZSTD_invalidateRepCodes() :\n * ensures next compression will not use repcodes from previous block.\n * Note : only works with regular variant;\n *        do not use with extDict variant ! */\nvoid ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {\n    int i;\n    for (i=0; i<ZSTD_REP_NUM; i++) cctx->blockState.prevCBlock->rep[i] = 0;\n    assert(!ZSTD_window_hasExtDict(cctx->blockState.matchState.window));\n}\n\n/* These are the approximate sizes for each strategy past which copying the\n * dictionary tables into the working context is faster than using them\n * in-place.\n */\nstatic const size_t attachDictSizeCutoffs[ZSTD_STRATEGY_MAX+1] = {\n    8 KB,  /* unused */\n    8 KB,  /* ZSTD_fast */\n    16 KB, /* ZSTD_dfast */\n    32 KB, /* ZSTD_greedy */\n    32 KB, /* ZSTD_lazy */\n    32 KB, /* ZSTD_lazy2 */\n    32 KB, /* ZSTD_btlazy2 */\n    32 KB, /* ZSTD_btopt */\n    8 KB,  /* ZSTD_btultra */\n    8 KB   /* ZSTD_btultra2 */\n};\n\nstatic int ZSTD_shouldAttachDict(const ZSTD_CDict* cdict,\n                                 const ZSTD_CCtx_params* params,\n                                 U64 pledgedSrcSize)\n{\n    size_t cutoff = attachDictSizeCutoffs[cdict->matchState.cParams.strategy];\n    return ( pledgedSrcSize <= cutoff\n          || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN\n          || params->attachDictPref == ZSTD_dictForceAttach )\n        && params->attachDictPref != ZSTD_dictForceCopy\n        && !params->forceWindow; /* dictMatchState isn't correctly\n                                 * handled in _enforceMaxDist */\n}\n\nstatic size_t\nZSTD_resetCCtx_byAttachingCDict(ZSTD_CCtx* cctx,\n                        const ZSTD_CDict* cdict,\n                        ZSTD_CCtx_params params,\n                        U64 pledgedSrcSize,\n                        ZSTD_buffered_policy_e zbuff)\n{\n    {   const ZSTD_compressionParameters* const cdict_cParams = &cdict->matchState.cParams;\n        unsigned const windowLog = params.cParams.windowLog;\n        assert(windowLog != 0);\n        /* Resize working context table params for input only, since the dict\n         * has its own tables. */\n        params.cParams = ZSTD_adjustCParams_internal(*cdict_cParams, pledgedSrcSize, 0);\n        params.cParams.windowLog = windowLog;\n        FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,\n                                                 ZSTDcrp_makeClean, zbuff));\n        assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);\n    }\n\n    {   const U32 cdictEnd = (U32)( cdict->matchState.window.nextSrc\n                                  - cdict->matchState.window.base);\n        const U32 cdictLen = cdictEnd - cdict->matchState.window.dictLimit;\n        if (cdictLen == 0) {\n            /* don't even attach dictionaries with no contents */\n            DEBUGLOG(4, \"skipping attaching empty dictionary\");\n        } else {\n            DEBUGLOG(4, \"attaching dictionary into context\");\n            cctx->blockState.matchState.dictMatchState = &cdict->matchState;\n\n            /* prep working match state so dict matches never have negative indices\n             * when they are translated to the working context's index space. */\n            if (cctx->blockState.matchState.window.dictLimit < cdictEnd) {\n                cctx->blockState.matchState.window.nextSrc =\n                    cctx->blockState.matchState.window.base + cdictEnd;\n                ZSTD_window_clear(&cctx->blockState.matchState.window);\n            }\n            /* loadedDictEnd is expressed within the referential of the active context */\n            cctx->blockState.matchState.loadedDictEnd = cctx->blockState.matchState.window.dictLimit;\n    }   }\n\n    cctx->dictID = cdict->dictID;\n\n    /* copy block state */\n    memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));\n\n    return 0;\n}\n\nstatic size_t ZSTD_resetCCtx_byCopyingCDict(ZSTD_CCtx* cctx,\n                            const ZSTD_CDict* cdict,\n                            ZSTD_CCtx_params params,\n                            U64 pledgedSrcSize,\n                            ZSTD_buffered_policy_e zbuff)\n{\n    const ZSTD_compressionParameters *cdict_cParams = &cdict->matchState.cParams;\n\n    DEBUGLOG(4, \"copying dictionary into context\");\n\n    {   unsigned const windowLog = params.cParams.windowLog;\n        assert(windowLog != 0);\n        /* Copy only compression parameters related to tables. */\n        params.cParams = *cdict_cParams;\n        params.cParams.windowLog = windowLog;\n        FORWARD_IF_ERROR(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize,\n                                                 ZSTDcrp_leaveDirty, zbuff));\n        assert(cctx->appliedParams.cParams.strategy == cdict_cParams->strategy);\n        assert(cctx->appliedParams.cParams.hashLog == cdict_cParams->hashLog);\n        assert(cctx->appliedParams.cParams.chainLog == cdict_cParams->chainLog);\n    }\n\n    ZSTD_cwksp_mark_tables_dirty(&cctx->workspace);\n\n    /* copy tables */\n    {   size_t const chainSize = (cdict_cParams->strategy == ZSTD_fast) ? 0 : ((size_t)1 << cdict_cParams->chainLog);\n        size_t const hSize =  (size_t)1 << cdict_cParams->hashLog;\n\n        memcpy(cctx->blockState.matchState.hashTable,\n               cdict->matchState.hashTable,\n               hSize * sizeof(U32));\n        memcpy(cctx->blockState.matchState.chainTable,\n               cdict->matchState.chainTable,\n               chainSize * sizeof(U32));\n    }\n\n    /* Zero the hashTable3, since the cdict never fills it */\n    {   int const h3log = cctx->blockState.matchState.hashLog3;\n        size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;\n        assert(cdict->matchState.hashLog3 == 0);\n        memset(cctx->blockState.matchState.hashTable3, 0, h3Size * sizeof(U32));\n    }\n\n    ZSTD_cwksp_mark_tables_clean(&cctx->workspace);\n\n    /* copy dictionary offsets */\n    {   ZSTD_matchState_t const* srcMatchState = &cdict->matchState;\n        ZSTD_matchState_t* dstMatchState = &cctx->blockState.matchState;\n        dstMatchState->window       = srcMatchState->window;\n        dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;\n        dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;\n    }\n\n    cctx->dictID = cdict->dictID;\n\n    /* copy block state */\n    memcpy(cctx->blockState.prevCBlock, &cdict->cBlockState, sizeof(cdict->cBlockState));\n\n    return 0;\n}\n\n/* We have a choice between copying the dictionary context into the working\n * context, or referencing the dictionary context from the working context\n * in-place. We decide here which strategy to use. */\nstatic size_t ZSTD_resetCCtx_usingCDict(ZSTD_CCtx* cctx,\n                            const ZSTD_CDict* cdict,\n                            const ZSTD_CCtx_params* params,\n                            U64 pledgedSrcSize,\n                            ZSTD_buffered_policy_e zbuff)\n{\n\n    DEBUGLOG(4, \"ZSTD_resetCCtx_usingCDict (pledgedSrcSize=%u)\",\n                (unsigned)pledgedSrcSize);\n\n    if (ZSTD_shouldAttachDict(cdict, params, pledgedSrcSize)) {\n        return ZSTD_resetCCtx_byAttachingCDict(\n            cctx, cdict, *params, pledgedSrcSize, zbuff);\n    } else {\n        return ZSTD_resetCCtx_byCopyingCDict(\n            cctx, cdict, *params, pledgedSrcSize, zbuff);\n    }\n}\n\n/*! ZSTD_copyCCtx_internal() :\n *  Duplicate an existing context `srcCCtx` into another one `dstCCtx`.\n *  Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).\n *  The \"context\", in this case, refers to the hash and chain tables,\n *  entropy tables, and dictionary references.\n * `windowLog` value is enforced if != 0, otherwise value is copied from srcCCtx.\n * @return : 0, or an error code */\nstatic size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx,\n                            const ZSTD_CCtx* srcCCtx,\n                            ZSTD_frameParameters fParams,\n                            U64 pledgedSrcSize,\n                            ZSTD_buffered_policy_e zbuff)\n{\n    DEBUGLOG(5, \"ZSTD_copyCCtx_internal\");\n    RETURN_ERROR_IF(srcCCtx->stage!=ZSTDcs_init, stage_wrong);\n\n    memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));\n    {   ZSTD_CCtx_params params = dstCCtx->requestedParams;\n        /* Copy only compression parameters related to tables. */\n        params.cParams = srcCCtx->appliedParams.cParams;\n        params.fParams = fParams;\n        ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize,\n                                ZSTDcrp_leaveDirty, zbuff);\n        assert(dstCCtx->appliedParams.cParams.windowLog == srcCCtx->appliedParams.cParams.windowLog);\n        assert(dstCCtx->appliedParams.cParams.strategy == srcCCtx->appliedParams.cParams.strategy);\n        assert(dstCCtx->appliedParams.cParams.hashLog == srcCCtx->appliedParams.cParams.hashLog);\n        assert(dstCCtx->appliedParams.cParams.chainLog == srcCCtx->appliedParams.cParams.chainLog);\n        assert(dstCCtx->blockState.matchState.hashLog3 == srcCCtx->blockState.matchState.hashLog3);\n    }\n\n    ZSTD_cwksp_mark_tables_dirty(&dstCCtx->workspace);\n\n    /* copy tables */\n    {   size_t const chainSize = (srcCCtx->appliedParams.cParams.strategy == ZSTD_fast) ? 0 : ((size_t)1 << srcCCtx->appliedParams.cParams.chainLog);\n        size_t const hSize =  (size_t)1 << srcCCtx->appliedParams.cParams.hashLog;\n        int const h3log = srcCCtx->blockState.matchState.hashLog3;\n        size_t const h3Size = h3log ? ((size_t)1 << h3log) : 0;\n\n        memcpy(dstCCtx->blockState.matchState.hashTable,\n               srcCCtx->blockState.matchState.hashTable,\n               hSize * sizeof(U32));\n        memcpy(dstCCtx->blockState.matchState.chainTable,\n               srcCCtx->blockState.matchState.chainTable,\n               chainSize * sizeof(U32));\n        memcpy(dstCCtx->blockState.matchState.hashTable3,\n               srcCCtx->blockState.matchState.hashTable3,\n               h3Size * sizeof(U32));\n    }\n\n    ZSTD_cwksp_mark_tables_clean(&dstCCtx->workspace);\n\n    /* copy dictionary offsets */\n    {\n        const ZSTD_matchState_t* srcMatchState = &srcCCtx->blockState.matchState;\n        ZSTD_matchState_t* dstMatchState = &dstCCtx->blockState.matchState;\n        dstMatchState->window       = srcMatchState->window;\n        dstMatchState->nextToUpdate = srcMatchState->nextToUpdate;\n        dstMatchState->loadedDictEnd= srcMatchState->loadedDictEnd;\n    }\n    dstCCtx->dictID = srcCCtx->dictID;\n\n    /* copy block state */\n    memcpy(dstCCtx->blockState.prevCBlock, srcCCtx->blockState.prevCBlock, sizeof(*srcCCtx->blockState.prevCBlock));\n\n    return 0;\n}\n\n/*! ZSTD_copyCCtx() :\n *  Duplicate an existing context `srcCCtx` into another one `dstCCtx`.\n *  Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).\n *  pledgedSrcSize==0 means \"unknown\".\n*   @return : 0, or an error code */\nsize_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)\n{\n    ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };\n    ZSTD_buffered_policy_e const zbuff = (ZSTD_buffered_policy_e)(srcCCtx->inBuffSize>0);\n    ZSTD_STATIC_ASSERT((U32)ZSTDb_buffered==1);\n    if (pledgedSrcSize==0) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;\n    fParams.contentSizeFlag = (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN);\n\n    return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx,\n                                fParams, pledgedSrcSize,\n                                zbuff);\n}\n\n\n#define ZSTD_ROWSIZE 16\n/*! ZSTD_reduceTable() :\n *  reduce table indexes by `reducerValue`, or squash to zero.\n *  PreserveMark preserves \"unsorted mark\" for btlazy2 strategy.\n *  It must be set to a clear 0/1 value, to remove branch during inlining.\n *  Presume table size is a multiple of ZSTD_ROWSIZE\n *  to help auto-vectorization */\nFORCE_INLINE_TEMPLATE void\nZSTD_reduceTable_internal (U32* const table, U32 const size, U32 const reducerValue, int const preserveMark)\n{\n    int const nbRows = (int)size / ZSTD_ROWSIZE;\n    int cellNb = 0;\n    int rowNb;\n    assert((size & (ZSTD_ROWSIZE-1)) == 0);  /* multiple of ZSTD_ROWSIZE */\n    assert(size < (1U<<31));   /* can be casted to int */\n\n#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)\n    /* To validate that the table re-use logic is sound, and that we don't\n     * access table space that we haven't cleaned, we re-\"poison\" the table\n     * space every time we mark it dirty.\n     *\n     * This function however is intended to operate on those dirty tables and\n     * re-clean them. So when this function is used correctly, we can unpoison\n     * the memory it operated on. This introduces a blind spot though, since\n     * if we now try to operate on __actually__ poisoned memory, we will not\n     * detect that. */\n    __msan_unpoison(table, size * sizeof(U32));\n#endif\n\n    for (rowNb=0 ; rowNb < nbRows ; rowNb++) {\n        int column;\n        for (column=0; column<ZSTD_ROWSIZE; column++) {\n            if (preserveMark) {\n                U32 const adder = (table[cellNb] == ZSTD_DUBT_UNSORTED_MARK) ? reducerValue : 0;\n                table[cellNb] += adder;\n            }\n            if (table[cellNb] < reducerValue) table[cellNb] = 0;\n            else table[cellNb] -= reducerValue;\n            cellNb++;\n    }   }\n}\n\nstatic void ZSTD_reduceTable(U32* const table, U32 const size, U32 const reducerValue)\n{\n    ZSTD_reduceTable_internal(table, size, reducerValue, 0);\n}\n\nstatic void ZSTD_reduceTable_btlazy2(U32* const table, U32 const size, U32 const reducerValue)\n{\n    ZSTD_reduceTable_internal(table, size, reducerValue, 1);\n}\n\n/*! ZSTD_reduceIndex() :\n*   rescale all indexes to avoid future overflow (indexes are U32) */\nstatic void ZSTD_reduceIndex (ZSTD_matchState_t* ms, ZSTD_CCtx_params const* params, const U32 reducerValue)\n{\n    {   U32 const hSize = (U32)1 << params->cParams.hashLog;\n        ZSTD_reduceTable(ms->hashTable, hSize, reducerValue);\n    }\n\n    if (params->cParams.strategy != ZSTD_fast) {\n        U32 const chainSize = (U32)1 << params->cParams.chainLog;\n        if (params->cParams.strategy == ZSTD_btlazy2)\n            ZSTD_reduceTable_btlazy2(ms->chainTable, chainSize, reducerValue);\n        else\n            ZSTD_reduceTable(ms->chainTable, chainSize, reducerValue);\n    }\n\n    if (ms->hashLog3) {\n        U32 const h3Size = (U32)1 << ms->hashLog3;\n        ZSTD_reduceTable(ms->hashTable3, h3Size, reducerValue);\n    }\n}\n\n\n/*-*******************************************************\n*  Block entropic compression\n*********************************************************/\n\n/* See doc/zstd_compression_format.md for detailed format description */\n\nstatic size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize, U32 lastBlock)\n{\n    U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(srcSize << 3);\n    RETURN_ERROR_IF(srcSize + ZSTD_blockHeaderSize > dstCapacity,\n                    dstSize_tooSmall);\n    MEM_writeLE24(dst, cBlockHeader24);\n    memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);\n    return ZSTD_blockHeaderSize + srcSize;\n}\n\nvoid ZSTD_seqToCodes(const seqStore_t* seqStorePtr)\n{\n    const seqDef* const sequences = seqStorePtr->sequencesStart;\n    BYTE* const llCodeTable = seqStorePtr->llCode;\n    BYTE* const ofCodeTable = seqStorePtr->ofCode;\n    BYTE* const mlCodeTable = seqStorePtr->mlCode;\n    U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);\n    U32 u;\n    assert(nbSeq <= seqStorePtr->maxNbSeq);\n    for (u=0; u<nbSeq; u++) {\n        U32 const llv = sequences[u].litLength;\n        U32 const mlv = sequences[u].matchLength;\n        llCodeTable[u] = (BYTE)ZSTD_LLcode(llv);\n        ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);\n        mlCodeTable[u] = (BYTE)ZSTD_MLcode(mlv);\n    }\n    if (seqStorePtr->longLengthID==1)\n        llCodeTable[seqStorePtr->longLengthPos] = MaxLL;\n    if (seqStorePtr->longLengthID==2)\n        mlCodeTable[seqStorePtr->longLengthPos] = MaxML;\n}\n\nstatic int ZSTD_disableLiteralsCompression(const ZSTD_CCtx_params* cctxParams)\n{\n    switch (cctxParams->literalCompressionMode) {\n    case ZSTD_lcm_huffman:\n        return 0;\n    case ZSTD_lcm_uncompressed:\n        return 1;\n    default:\n        assert(0 /* impossible: pre-validated */);\n        /* fall-through */\n    case ZSTD_lcm_auto:\n        return (cctxParams->cParams.strategy == ZSTD_fast) && (cctxParams->cParams.targetLength > 0);\n    }\n}\n\n/* ZSTD_compressSequences_internal():\n * actually compresses both literals and sequences */\nMEM_STATIC size_t\nZSTD_compressSequences_internal(seqStore_t* seqStorePtr,\n                          const ZSTD_entropyCTables_t* prevEntropy,\n                                ZSTD_entropyCTables_t* nextEntropy,\n                          const ZSTD_CCtx_params* cctxParams,\n                                void* dst, size_t dstCapacity,\n                                void* entropyWorkspace, size_t entropyWkspSize,\n                          const int bmi2)\n{\n    const int longOffsets = cctxParams->cParams.windowLog > STREAM_ACCUMULATOR_MIN;\n    ZSTD_strategy const strategy = cctxParams->cParams.strategy;\n    unsigned count[MaxSeq+1];\n    FSE_CTable* CTable_LitLength = nextEntropy->fse.litlengthCTable;\n    FSE_CTable* CTable_OffsetBits = nextEntropy->fse.offcodeCTable;\n    FSE_CTable* CTable_MatchLength = nextEntropy->fse.matchlengthCTable;\n    U32 LLtype, Offtype, MLtype;   /* compressed, raw or rle */\n    const seqDef* const sequences = seqStorePtr->sequencesStart;\n    const BYTE* const ofCodeTable = seqStorePtr->ofCode;\n    const BYTE* const llCodeTable = seqStorePtr->llCode;\n    const BYTE* const mlCodeTable = seqStorePtr->mlCode;\n    BYTE* const ostart = (BYTE*)dst;\n    BYTE* const oend = ostart + dstCapacity;\n    BYTE* op = ostart;\n    size_t const nbSeq = (size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart);\n    BYTE* seqHead;\n    BYTE* lastNCount = NULL;\n\n    DEBUGLOG(5, \"ZSTD_compressSequences_internal (nbSeq=%zu)\", nbSeq);\n    ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));\n\n    /* Compress literals */\n    {   const BYTE* const literals = seqStorePtr->litStart;\n        size_t const litSize = (size_t)(seqStorePtr->lit - literals);\n        size_t const cSize = ZSTD_compressLiterals(\n                                    &prevEntropy->huf, &nextEntropy->huf,\n                                    cctxParams->cParams.strategy,\n                                    ZSTD_disableLiteralsCompression(cctxParams),\n                                    op, dstCapacity,\n                                    literals, litSize,\n                                    entropyWorkspace, entropyWkspSize,\n                                    bmi2);\n        FORWARD_IF_ERROR(cSize);\n        assert(cSize <= dstCapacity);\n        op += cSize;\n    }\n\n    /* Sequences Header */\n    RETURN_ERROR_IF((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead*/,\n                    dstSize_tooSmall);\n    if (nbSeq < 128) {\n        *op++ = (BYTE)nbSeq;\n    } else if (nbSeq < LONGNBSEQ) {\n        op[0] = (BYTE)((nbSeq>>8) + 0x80);\n        op[1] = (BYTE)nbSeq;\n        op+=2;\n    } else {\n        op[0]=0xFF;\n        MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ));\n        op+=3;\n    }\n    assert(op <= oend);\n    if (nbSeq==0) {\n        /* Copy the old tables over as if we repeated them */\n        memcpy(&nextEntropy->fse, &prevEntropy->fse, sizeof(prevEntropy->fse));\n        return (size_t)(op - ostart);\n    }\n\n    /* seqHead : flags for FSE encoding type */\n    seqHead = op++;\n    assert(op <= oend);\n\n    /* convert length/distances into codes */\n    ZSTD_seqToCodes(seqStorePtr);\n    /* build CTable for Literal Lengths */\n    {   unsigned max = MaxLL;\n        size_t const mostFrequent = HIST_countFast_wksp(count, &max, llCodeTable, nbSeq, entropyWorkspace, entropyWkspSize);   /* can't fail */\n        DEBUGLOG(5, \"Building LL table\");\n        nextEntropy->fse.litlength_repeatMode = prevEntropy->fse.litlength_repeatMode;\n        LLtype = ZSTD_selectEncodingType(&nextEntropy->fse.litlength_repeatMode,\n                                        count, max, mostFrequent, nbSeq,\n                                        LLFSELog, prevEntropy->fse.litlengthCTable,\n                                        LL_defaultNorm, LL_defaultNormLog,\n                                        ZSTD_defaultAllowed, strategy);\n        assert(set_basic < set_compressed && set_rle < set_compressed);\n        assert(!(LLtype < set_compressed && nextEntropy->fse.litlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */\n        {   size_t const countSize = ZSTD_buildCTable(\n                op, (size_t)(oend - op),\n                CTable_LitLength, LLFSELog, (symbolEncodingType_e)LLtype,\n                count, max, llCodeTable, nbSeq,\n                LL_defaultNorm, LL_defaultNormLog, MaxLL,\n                prevEntropy->fse.litlengthCTable,\n                sizeof(prevEntropy->fse.litlengthCTable),\n                entropyWorkspace, entropyWkspSize);\n            FORWARD_IF_ERROR(countSize);\n            if (LLtype == set_compressed)\n                lastNCount = op;\n            op += countSize;\n            assert(op <= oend);\n    }   }\n    /* build CTable for Offsets */\n    {   unsigned max = MaxOff;\n        size_t const mostFrequent = HIST_countFast_wksp(\n            count, &max, ofCodeTable, nbSeq, entropyWorkspace, entropyWkspSize);  /* can't fail */\n        /* We can only use the basic table if max <= DefaultMaxOff, otherwise the offsets are too large */\n        ZSTD_defaultPolicy_e const defaultPolicy = (max <= DefaultMaxOff) ? ZSTD_defaultAllowed : ZSTD_defaultDisallowed;\n        DEBUGLOG(5, \"Building OF table\");\n        nextEntropy->fse.offcode_repeatMode = prevEntropy->fse.offcode_repeatMode;\n        Offtype = ZSTD_selectEncodingType(&nextEntropy->fse.offcode_repeatMode,\n                                        count, max, mostFrequent, nbSeq,\n                                        OffFSELog, prevEntropy->fse.offcodeCTable,\n                                        OF_defaultNorm, OF_defaultNormLog,\n                                        defaultPolicy, strategy);\n        assert(!(Offtype < set_compressed && nextEntropy->fse.offcode_repeatMode != FSE_repeat_none)); /* We don't copy tables */\n        {   size_t const countSize = ZSTD_buildCTable(\n                op, (size_t)(oend - op),\n                CTable_OffsetBits, OffFSELog, (symbolEncodingType_e)Offtype,\n                count, max, ofCodeTable, nbSeq,\n                OF_defaultNorm, OF_defaultNormLog, DefaultMaxOff,\n                prevEntropy->fse.offcodeCTable,\n                sizeof(prevEntropy->fse.offcodeCTable),\n                entropyWorkspace, entropyWkspSize);\n            FORWARD_IF_ERROR(countSize);\n            if (Offtype == set_compressed)\n                lastNCount = op;\n            op += countSize;\n            assert(op <= oend);\n    }   }\n    /* build CTable for MatchLengths */\n    {   unsigned max = MaxML;\n        size_t const mostFrequent = HIST_countFast_wksp(\n            count, &max, mlCodeTable, nbSeq, entropyWorkspace, entropyWkspSize);   /* can't fail */\n        DEBUGLOG(5, \"Building ML table (remaining space : %i)\", (int)(oend-op));\n        nextEntropy->fse.matchlength_repeatMode = prevEntropy->fse.matchlength_repeatMode;\n        MLtype = ZSTD_selectEncodingType(&nextEntropy->fse.matchlength_repeatMode,\n                                        count, max, mostFrequent, nbSeq,\n                                        MLFSELog, prevEntropy->fse.matchlengthCTable,\n                                        ML_defaultNorm, ML_defaultNormLog,\n                                        ZSTD_defaultAllowed, strategy);\n        assert(!(MLtype < set_compressed && nextEntropy->fse.matchlength_repeatMode != FSE_repeat_none)); /* We don't copy tables */\n        {   size_t const countSize = ZSTD_buildCTable(\n                op, (size_t)(oend - op),\n                CTable_MatchLength, MLFSELog, (symbolEncodingType_e)MLtype,\n                count, max, mlCodeTable, nbSeq,\n                ML_defaultNorm, ML_defaultNormLog, MaxML,\n                prevEntropy->fse.matchlengthCTable,\n                sizeof(prevEntropy->fse.matchlengthCTable),\n                entropyWorkspace, entropyWkspSize);\n            FORWARD_IF_ERROR(countSize);\n            if (MLtype == set_compressed)\n                lastNCount = op;\n            op += countSize;\n            assert(op <= oend);\n    }   }\n\n    *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));\n\n    {   size_t const bitstreamSize = ZSTD_encodeSequences(\n                                        op, (size_t)(oend - op),\n                                        CTable_MatchLength, mlCodeTable,\n                                        CTable_OffsetBits, ofCodeTable,\n                                        CTable_LitLength, llCodeTable,\n                                        sequences, nbSeq,\n                                        longOffsets, bmi2);\n        FORWARD_IF_ERROR(bitstreamSize);\n        op += bitstreamSize;\n        assert(op <= oend);\n        /* zstd versions <= 1.3.4 mistakenly report corruption when\n         * FSE_readNCount() receives a buffer < 4 bytes.\n         * Fixed by https://github.com/facebook/zstd/pull/1146.\n         * This can happen when the last set_compressed table present is 2\n         * bytes and the bitstream is only one byte.\n         * In this exceedingly rare case, we will simply emit an uncompressed\n         * block, since it isn't worth optimizing.\n         */\n        if (lastNCount && (op - lastNCount) < 4) {\n            /* NCountSize >= 2 && bitstreamSize > 0 ==> lastCountSize == 3 */\n            assert(op - lastNCount == 3);\n            DEBUGLOG(5, \"Avoiding bug in zstd decoder in versions <= 1.3.4 by \"\n                        \"emitting an uncompressed block.\");\n            return 0;\n        }\n    }\n\n    DEBUGLOG(5, \"compressed block size : %u\", (unsigned)(op - ostart));\n    return (size_t)(op - ostart);\n}\n\nMEM_STATIC size_t\nZSTD_compressSequences(seqStore_t* seqStorePtr,\n                       const ZSTD_entropyCTables_t* prevEntropy,\n                             ZSTD_entropyCTables_t* nextEntropy,\n                       const ZSTD_CCtx_params* cctxParams,\n                             void* dst, size_t dstCapacity,\n                             size_t srcSize,\n                             void* entropyWorkspace, size_t entropyWkspSize,\n                             int bmi2)\n{\n    size_t const cSize = ZSTD_compressSequences_internal(\n                            seqStorePtr, prevEntropy, nextEntropy, cctxParams,\n                            dst, dstCapacity,\n                            entropyWorkspace, entropyWkspSize, bmi2);\n    if (cSize == 0) return 0;\n    /* When srcSize <= dstCapacity, there is enough space to write a raw uncompressed block.\n     * Since we ran out of space, block must be not compressible, so fall back to raw uncompressed block.\n     */\n    if ((cSize == ERROR(dstSize_tooSmall)) & (srcSize <= dstCapacity))\n        return 0;  /* block not compressed */\n    FORWARD_IF_ERROR(cSize);\n\n    /* Check compressibility */\n    {   size_t const maxCSize = srcSize - ZSTD_minGain(srcSize, cctxParams->cParams.strategy);\n        if (cSize >= maxCSize) return 0;  /* block not compressed */\n    }\n\n    return cSize;\n}\n\n/* ZSTD_selectBlockCompressor() :\n * Not static, but internal use only (used by long distance matcher)\n * assumption : strat is a valid strategy */\nZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode)\n{\n    static const ZSTD_blockCompressor blockCompressor[3][ZSTD_STRATEGY_MAX+1] = {\n        { ZSTD_compressBlock_fast  /* default for 0 */,\n          ZSTD_compressBlock_fast,\n          ZSTD_compressBlock_doubleFast,\n          ZSTD_compressBlock_greedy,\n          ZSTD_compressBlock_lazy,\n          ZSTD_compressBlock_lazy2,\n          ZSTD_compressBlock_btlazy2,\n          ZSTD_compressBlock_btopt,\n          ZSTD_compressBlock_btultra,\n          ZSTD_compressBlock_btultra2 },\n        { ZSTD_compressBlock_fast_extDict  /* default for 0 */,\n          ZSTD_compressBlock_fast_extDict,\n          ZSTD_compressBlock_doubleFast_extDict,\n          ZSTD_compressBlock_greedy_extDict,\n          ZSTD_compressBlock_lazy_extDict,\n          ZSTD_compressBlock_lazy2_extDict,\n          ZSTD_compressBlock_btlazy2_extDict,\n          ZSTD_compressBlock_btopt_extDict,\n          ZSTD_compressBlock_btultra_extDict,\n          ZSTD_compressBlock_btultra_extDict },\n        { ZSTD_compressBlock_fast_dictMatchState  /* default for 0 */,\n          ZSTD_compressBlock_fast_dictMatchState,\n          ZSTD_compressBlock_doubleFast_dictMatchState,\n          ZSTD_compressBlock_greedy_dictMatchState,\n          ZSTD_compressBlock_lazy_dictMatchState,\n          ZSTD_compressBlock_lazy2_dictMatchState,\n          ZSTD_compressBlock_btlazy2_dictMatchState,\n          ZSTD_compressBlock_btopt_dictMatchState,\n          ZSTD_compressBlock_btultra_dictMatchState,\n          ZSTD_compressBlock_btultra_dictMatchState }\n    };\n    ZSTD_blockCompressor selectedCompressor;\n    ZSTD_STATIC_ASSERT((unsigned)ZSTD_fast == 1);\n\n    assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));\n    selectedCompressor = blockCompressor[(int)dictMode][(int)strat];\n    assert(selectedCompressor != NULL);\n    return selectedCompressor;\n}\n\nstatic void ZSTD_storeLastLiterals(seqStore_t* seqStorePtr,\n                                   const BYTE* anchor, size_t lastLLSize)\n{\n    memcpy(seqStorePtr->lit, anchor, lastLLSize);\n    seqStorePtr->lit += lastLLSize;\n}\n\nvoid ZSTD_resetSeqStore(seqStore_t* ssPtr)\n{\n    ssPtr->lit = ssPtr->litStart;\n    ssPtr->sequences = ssPtr->sequencesStart;\n    ssPtr->longLengthID = 0;\n}\n\ntypedef enum { ZSTDbss_compress, ZSTDbss_noCompress } ZSTD_buildSeqStore_e;\n\nstatic size_t ZSTD_buildSeqStore(ZSTD_CCtx* zc, const void* src, size_t srcSize)\n{\n    ZSTD_matchState_t* const ms = &zc->blockState.matchState;\n    DEBUGLOG(5, \"ZSTD_buildSeqStore (srcSize=%zu)\", srcSize);\n    assert(srcSize <= ZSTD_BLOCKSIZE_MAX);\n    /* Assert that we have correctly flushed the ctx params into the ms's copy */\n    ZSTD_assertEqualCParams(zc->appliedParams.cParams, ms->cParams);\n    if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) {\n        ZSTD_ldm_skipSequences(&zc->externSeqStore, srcSize, zc->appliedParams.cParams.minMatch);\n        return ZSTDbss_noCompress; /* don't even attempt compression below a certain srcSize */\n    }\n    ZSTD_resetSeqStore(&(zc->seqStore));\n    /* required for optimal parser to read stats from dictionary */\n    ms->opt.symbolCosts = &zc->blockState.prevCBlock->entropy;\n    /* tell the optimal parser how we expect to compress literals */\n    ms->opt.literalCompressionMode = zc->appliedParams.literalCompressionMode;\n    /* a gap between an attached dict and the current window is not safe,\n     * they must remain adjacent,\n     * and when that stops being the case, the dict must be unset */\n    assert(ms->dictMatchState == NULL || ms->loadedDictEnd == ms->window.dictLimit);\n\n    /* limited update after a very long match */\n    {   const BYTE* const base = ms->window.base;\n        const BYTE* const istart = (const BYTE*)src;\n        const U32 current = (U32)(istart-base);\n        if (sizeof(ptrdiff_t)==8) assert(istart - base < (ptrdiff_t)(U32)(-1));   /* ensure no overflow */\n        if (current > ms->nextToUpdate + 384)\n            ms->nextToUpdate = current - MIN(192, (U32)(current - ms->nextToUpdate - 384));\n    }\n\n    /* select and store sequences */\n    {   ZSTD_dictMode_e const dictMode = ZSTD_matchState_dictMode(ms);\n        size_t lastLLSize;\n        {   int i;\n            for (i = 0; i < ZSTD_REP_NUM; ++i)\n                zc->blockState.nextCBlock->rep[i] = zc->blockState.prevCBlock->rep[i];\n        }\n        if (zc->externSeqStore.pos < zc->externSeqStore.size) {\n            assert(!zc->appliedParams.ldmParams.enableLdm);\n            /* Updates ldmSeqStore.pos */\n            lastLLSize =\n                ZSTD_ldm_blockCompress(&zc->externSeqStore,\n                                       ms, &zc->seqStore,\n                                       zc->blockState.nextCBlock->rep,\n                                       src, srcSize);\n            assert(zc->externSeqStore.pos <= zc->externSeqStore.size);\n        } else if (zc->appliedParams.ldmParams.enableLdm) {\n            rawSeqStore_t ldmSeqStore = {NULL, 0, 0, 0};\n\n            ldmSeqStore.seq = zc->ldmSequences;\n            ldmSeqStore.capacity = zc->maxNbLdmSequences;\n            /* Updates ldmSeqStore.size */\n            FORWARD_IF_ERROR(ZSTD_ldm_generateSequences(&zc->ldmState, &ldmSeqStore,\n                                               &zc->appliedParams.ldmParams,\n                                               src, srcSize));\n            /* Updates ldmSeqStore.pos */\n            lastLLSize =\n                ZSTD_ldm_blockCompress(&ldmSeqStore,\n                                       ms, &zc->seqStore,\n                                       zc->blockState.nextCBlock->rep,\n                                       src, srcSize);\n            assert(ldmSeqStore.pos == ldmSeqStore.size);\n        } else {   /* not long range mode */\n            ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->appliedParams.cParams.strategy, dictMode);\n            lastLLSize = blockCompressor(ms, &zc->seqStore, zc->blockState.nextCBlock->rep, src, srcSize);\n        }\n        {   const BYTE* const lastLiterals = (const BYTE*)src + srcSize - lastLLSize;\n            ZSTD_storeLastLiterals(&zc->seqStore, lastLiterals, lastLLSize);\n    }   }\n    return ZSTDbss_compress;\n}\n\nstatic void ZSTD_copyBlockSequences(ZSTD_CCtx* zc)\n{\n    const seqStore_t* seqStore = ZSTD_getSeqStore(zc);\n    const seqDef* seqs = seqStore->sequencesStart;\n    size_t seqsSize = seqStore->sequences - seqs;\n\n    ZSTD_Sequence* outSeqs = &zc->seqCollector.seqStart[zc->seqCollector.seqIndex];\n    size_t i; size_t position; int repIdx;\n\n    assert(zc->seqCollector.seqIndex + 1 < zc->seqCollector.maxSequences);\n    for (i = 0, position = 0; i < seqsSize; ++i) {\n        outSeqs[i].offset = seqs[i].offset;\n        outSeqs[i].litLength = seqs[i].litLength;\n        outSeqs[i].matchLength = seqs[i].matchLength + MINMATCH;\n\n        if (i == seqStore->longLengthPos) {\n            if (seqStore->longLengthID == 1) {\n                outSeqs[i].litLength += 0x10000;\n            } else if (seqStore->longLengthID == 2) {\n                outSeqs[i].matchLength += 0x10000;\n            }\n        }\n\n        if (outSeqs[i].offset <= ZSTD_REP_NUM) {\n            outSeqs[i].rep = outSeqs[i].offset;\n            repIdx = (unsigned int)i - outSeqs[i].offset;\n\n            if (outSeqs[i].litLength == 0) {\n                if (outSeqs[i].offset < 3) {\n                    --repIdx;\n                } else {\n                    repIdx = (unsigned int)i - 1;\n                }\n                ++outSeqs[i].rep;\n            }\n            assert(repIdx >= -3);\n            outSeqs[i].offset = repIdx >= 0 ? outSeqs[repIdx].offset : repStartValue[-repIdx - 1];\n            if (outSeqs[i].rep == 4) {\n                --outSeqs[i].offset;\n            }\n        } else {\n            outSeqs[i].offset -= ZSTD_REP_NUM;\n        }\n\n        position += outSeqs[i].litLength;\n        outSeqs[i].matchPos = (unsigned int)position;\n        position += outSeqs[i].matchLength;\n    }\n    zc->seqCollector.seqIndex += seqsSize;\n}\n\nsize_t ZSTD_getSequences(ZSTD_CCtx* zc, ZSTD_Sequence* outSeqs,\n    size_t outSeqsSize, const void* src, size_t srcSize)\n{\n    const size_t dstCapacity = ZSTD_compressBound(srcSize);\n    void* dst = ZSTD_malloc(dstCapacity, ZSTD_defaultCMem);\n    SeqCollector seqCollector;\n\n    RETURN_ERROR_IF(dst == NULL, memory_allocation);\n\n    seqCollector.collectSequences = 1;\n    seqCollector.seqStart = outSeqs;\n    seqCollector.seqIndex = 0;\n    seqCollector.maxSequences = outSeqsSize;\n    zc->seqCollector = seqCollector;\n\n    ZSTD_compress2(zc, dst, dstCapacity, src, srcSize);\n    ZSTD_free(dst, ZSTD_defaultCMem);\n    return zc->seqCollector.seqIndex;\n}\n\n/* Returns true if the given block is a RLE block */\nstatic int ZSTD_isRLE(const BYTE *ip, size_t length) {\n    size_t i;\n    if (length < 2) return 1;\n    for (i = 1; i < length; ++i) {\n        if (ip[0] != ip[i]) return 0;\n    }\n    return 1;\n}\n\nstatic size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc,\n                                        void* dst, size_t dstCapacity,\n                                        const void* src, size_t srcSize, U32 frame)\n{\n    /* This the upper bound for the length of an rle block.\n     * This isn't the actual upper bound. Finding the real threshold\n     * needs further investigation.\n     */\n    const U32 rleMaxLength = 25;\n    size_t cSize;\n    const BYTE* ip = (const BYTE*)src;\n    BYTE* op = (BYTE*)dst;\n    DEBUGLOG(5, \"ZSTD_compressBlock_internal (dstCapacity=%u, dictLimit=%u, nextToUpdate=%u)\",\n                (unsigned)dstCapacity, (unsigned)zc->blockState.matchState.window.dictLimit,\n                (unsigned)zc->blockState.matchState.nextToUpdate);\n\n    {   const size_t bss = ZSTD_buildSeqStore(zc, src, srcSize);\n        FORWARD_IF_ERROR(bss);\n        if (bss == ZSTDbss_noCompress) { cSize = 0; goto out; }\n    }\n\n    if (zc->seqCollector.collectSequences) {\n        ZSTD_copyBlockSequences(zc);\n        return 0;\n    }\n\n    /* encode sequences and literals */\n    cSize = ZSTD_compressSequences(&zc->seqStore,\n            &zc->blockState.prevCBlock->entropy, &zc->blockState.nextCBlock->entropy,\n            &zc->appliedParams,\n            dst, dstCapacity,\n            srcSize,\n            zc->entropyWorkspace, HUF_WORKSPACE_SIZE /* statically allocated in resetCCtx */,\n            zc->bmi2);\n\n    if (frame &&\n        /* We don't want to emit our first block as a RLE even if it qualifies because\n         * doing so will cause the decoder (cli only) to throw a \"should consume all input error.\"\n         * This is only an issue for zstd <= v1.4.3\n         */\n        !zc->isFirstBlock &&\n        cSize < rleMaxLength &&\n        ZSTD_isRLE(ip, srcSize))\n    {\n        cSize = 1;\n        op[0] = ip[0];\n    }\n\nout:\n    if (!ZSTD_isError(cSize) && cSize > 1) {\n        /* confirm repcodes and entropy tables when emitting a compressed block */\n        ZSTD_compressedBlockState_t* const tmp = zc->blockState.prevCBlock;\n        zc->blockState.prevCBlock = zc->blockState.nextCBlock;\n        zc->blockState.nextCBlock = tmp;\n    }\n    /* We check that dictionaries have offset codes available for the first\n     * block. After the first block, the offcode table might not have large\n     * enough codes to represent the offsets in the data.\n     */\n    if (zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode == FSE_repeat_valid)\n        zc->blockState.prevCBlock->entropy.fse.offcode_repeatMode = FSE_repeat_check;\n\n    return cSize;\n}\n\n\nstatic void ZSTD_overflowCorrectIfNeeded(ZSTD_matchState_t* ms,\n                                         ZSTD_cwksp* ws,\n                                         ZSTD_CCtx_params const* params,\n                                         void const* ip,\n                                         void const* iend)\n{\n    if (ZSTD_window_needOverflowCorrection(ms->window, iend)) {\n        U32 const maxDist = (U32)1 << params->cParams.windowLog;\n        U32 const cycleLog = ZSTD_cycleLog(params->cParams.chainLog, params->cParams.strategy);\n        U32 const correction = ZSTD_window_correctOverflow(&ms->window, cycleLog, maxDist, ip);\n        ZSTD_STATIC_ASSERT(ZSTD_CHAINLOG_MAX <= 30);\n        ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_32 <= 30);\n        ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX <= 31);\n        ZSTD_cwksp_mark_tables_dirty(ws);\n        ZSTD_reduceIndex(ms, params, correction);\n        ZSTD_cwksp_mark_tables_clean(ws);\n        if (ms->nextToUpdate < correction) ms->nextToUpdate = 0;\n        else ms->nextToUpdate -= correction;\n        /* invalidate dictionaries on overflow correction */\n        ms->loadedDictEnd = 0;\n        ms->dictMatchState = NULL;\n    }\n}\n\n/*! ZSTD_compress_frameChunk() :\n*   Compress a chunk of data into one or multiple blocks.\n*   All blocks will be terminated, all input will be consumed.\n*   Function will issue an error if there is not enough `dstCapacity` to hold the compressed content.\n*   Frame is supposed already started (header already produced)\n*   @return : compressed size, or an error code\n*/\nstatic size_t ZSTD_compress_frameChunk (ZSTD_CCtx* cctx,\n                                     void* dst, size_t dstCapacity,\n                               const void* src, size_t srcSize,\n                                     U32 lastFrameChunk)\n{\n    size_t blockSize = cctx->blockSize;\n    size_t remaining = srcSize;\n    const BYTE* ip = (const BYTE*)src;\n    BYTE* const ostart = (BYTE*)dst;\n    BYTE* op = ostart;\n    U32 const maxDist = (U32)1 << cctx->appliedParams.cParams.windowLog;\n    assert(cctx->appliedParams.cParams.windowLog <= ZSTD_WINDOWLOG_MAX);\n\n    DEBUGLOG(5, \"ZSTD_compress_frameChunk (blockSize=%u)\", (unsigned)blockSize);\n    if (cctx->appliedParams.fParams.checksumFlag && srcSize)\n        XXH64_update(&cctx->xxhState, src, srcSize);\n\n    while (remaining) {\n        ZSTD_matchState_t* const ms = &cctx->blockState.matchState;\n        U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);\n\n        RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE,\n                        dstSize_tooSmall,\n                        \"not enough space to store compressed block\");\n        if (remaining < blockSize) blockSize = remaining;\n\n        ZSTD_overflowCorrectIfNeeded(\n            ms, &cctx->workspace, &cctx->appliedParams, ip, ip + blockSize);\n        ZSTD_checkDictValidity(&ms->window, ip + blockSize, maxDist, &ms->loadedDictEnd, &ms->dictMatchState);\n\n        /* Ensure hash/chain table insertion resumes no sooner than lowlimit */\n        if (ms->nextToUpdate < ms->window.lowLimit) ms->nextToUpdate = ms->window.lowLimit;\n\n        {   size_t cSize = ZSTD_compressBlock_internal(cctx,\n                                op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize,\n                                ip, blockSize, 1 /* frame */);\n            FORWARD_IF_ERROR(cSize);\n            if (cSize == 0) {  /* block is not compressible */\n                cSize = ZSTD_noCompressBlock(op, dstCapacity, ip, blockSize, lastBlock);\n                FORWARD_IF_ERROR(cSize);\n            } else {\n                const U32 cBlockHeader = cSize == 1 ?\n                    lastBlock + (((U32)bt_rle)<<1) + (U32)(blockSize << 3) :\n                    lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);\n                MEM_writeLE24(op, cBlockHeader);\n                cSize += ZSTD_blockHeaderSize;\n            }\n\n            ip += blockSize;\n            assert(remaining >= blockSize);\n            remaining -= blockSize;\n            op += cSize;\n            assert(dstCapacity >= cSize);\n            dstCapacity -= cSize;\n            cctx->isFirstBlock = 0;\n            DEBUGLOG(5, \"ZSTD_compress_frameChunk: adding a block of size %u\",\n                        (unsigned)cSize);\n    }   }\n\n    if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;\n    return (size_t)(op-ostart);\n}\n\n\nstatic size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,\n                                    const ZSTD_CCtx_params* params, U64 pledgedSrcSize, U32 dictID)\n{   BYTE* const op = (BYTE*)dst;\n    U32   const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536);   /* 0-3 */\n    U32   const dictIDSizeCode = params->fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength;   /* 0-3 */\n    U32   const checksumFlag = params->fParams.checksumFlag>0;\n    U32   const windowSize = (U32)1 << params->cParams.windowLog;\n    U32   const singleSegment = params->fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);\n    BYTE  const windowLogByte = (BYTE)((params->cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);\n    U32   const fcsCode = params->fParams.contentSizeFlag ?\n                     (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : 0;  /* 0-3 */\n    BYTE  const frameHeaderDescriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );\n    size_t pos=0;\n\n    assert(!(params->fParams.contentSizeFlag && pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN));\n    RETURN_ERROR_IF(dstCapacity < ZSTD_FRAMEHEADERSIZE_MAX, dstSize_tooSmall);\n    DEBUGLOG(4, \"ZSTD_writeFrameHeader : dictIDFlag : %u ; dictID : %u ; dictIDSizeCode : %u\",\n                !params->fParams.noDictIDFlag, (unsigned)dictID, (unsigned)dictIDSizeCode);\n\n    if (params->format == ZSTD_f_zstd1) {\n        MEM_writeLE32(dst, ZSTD_MAGICNUMBER);\n        pos = 4;\n    }\n    op[pos++] = frameHeaderDescriptionByte;\n    if (!singleSegment) op[pos++] = windowLogByte;\n    switch(dictIDSizeCode)\n    {\n        default:  assert(0); /* impossible */\n        case 0 : break;\n        case 1 : op[pos] = (BYTE)(dictID); pos++; break;\n        case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;\n        case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;\n    }\n    switch(fcsCode)\n    {\n        default:  assert(0); /* impossible */\n        case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;\n        case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;\n        case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;\n        case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;\n    }\n    return pos;\n}\n\n/* ZSTD_writeLastEmptyBlock() :\n * output an empty Block with end-of-frame mark to complete a frame\n * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))\n *           or an error code if `dstCapacity` is too small (<ZSTD_blockHeaderSize)\n */\nsize_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity)\n{\n    RETURN_ERROR_IF(dstCapacity < ZSTD_blockHeaderSize, dstSize_tooSmall);\n    {   U32 const cBlockHeader24 = 1 /*lastBlock*/ + (((U32)bt_raw)<<1);  /* 0 size */\n        MEM_writeLE24(dst, cBlockHeader24);\n        return ZSTD_blockHeaderSize;\n    }\n}\n\nsize_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq)\n{\n    RETURN_ERROR_IF(cctx->stage != ZSTDcs_init, stage_wrong);\n    RETURN_ERROR_IF(cctx->appliedParams.ldmParams.enableLdm,\n                    parameter_unsupported);\n    cctx->externSeqStore.seq = seq;\n    cctx->externSeqStore.size = nbSeq;\n    cctx->externSeqStore.capacity = nbSeq;\n    cctx->externSeqStore.pos = 0;\n    return 0;\n}\n\n\nstatic size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,\n                              void* dst, size_t dstCapacity,\n                        const void* src, size_t srcSize,\n                               U32 frame, U32 lastFrameChunk)\n{\n    ZSTD_matchState_t* const ms = &cctx->blockState.matchState;\n    size_t fhSize = 0;\n\n    DEBUGLOG(5, \"ZSTD_compressContinue_internal, stage: %u, srcSize: %u\",\n                cctx->stage, (unsigned)srcSize);\n    RETURN_ERROR_IF(cctx->stage==ZSTDcs_created, stage_wrong,\n                    \"missing init (ZSTD_compressBegin)\");\n\n    if (frame && (cctx->stage==ZSTDcs_init)) {\n        fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams,\n                                       cctx->pledgedSrcSizePlusOne-1, cctx->dictID);\n        FORWARD_IF_ERROR(fhSize);\n        assert(fhSize <= dstCapacity);\n        dstCapacity -= fhSize;\n        dst = (char*)dst + fhSize;\n        cctx->stage = ZSTDcs_ongoing;\n    }\n\n    if (!srcSize) return fhSize;  /* do not generate an empty block if no input */\n\n    if (!ZSTD_window_update(&ms->window, src, srcSize)) {\n        ms->nextToUpdate = ms->window.dictLimit;\n    }\n    if (cctx->appliedParams.ldmParams.enableLdm) {\n        ZSTD_window_update(&cctx->ldmState.window, src, srcSize);\n    }\n\n    if (!frame) {\n        /* overflow check and correction for block mode */\n        ZSTD_overflowCorrectIfNeeded(\n            ms, &cctx->workspace, &cctx->appliedParams,\n            src, (BYTE const*)src + srcSize);\n    }\n\n    DEBUGLOG(5, \"ZSTD_compressContinue_internal (blockSize=%u)\", (unsigned)cctx->blockSize);\n    {   size_t const cSize = frame ?\n                             ZSTD_compress_frameChunk (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :\n                             ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize, 0 /* frame */);\n        FORWARD_IF_ERROR(cSize);\n        cctx->consumedSrcSize += srcSize;\n        cctx->producedCSize += (cSize + fhSize);\n        assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));\n        if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */\n            ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);\n            RETURN_ERROR_IF(\n                cctx->consumedSrcSize+1 > cctx->pledgedSrcSizePlusOne,\n                srcSize_wrong,\n                \"error : pledgedSrcSize = %u, while realSrcSize >= %u\",\n                (unsigned)cctx->pledgedSrcSizePlusOne-1,\n                (unsigned)cctx->consumedSrcSize);\n        }\n        return cSize + fhSize;\n    }\n}\n\nsize_t ZSTD_compressContinue (ZSTD_CCtx* cctx,\n                              void* dst, size_t dstCapacity,\n                        const void* src, size_t srcSize)\n{\n    DEBUGLOG(5, \"ZSTD_compressContinue (srcSize=%u)\", (unsigned)srcSize);\n    return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */);\n}\n\n\nsize_t ZSTD_getBlockSize(const ZSTD_CCtx* cctx)\n{\n    ZSTD_compressionParameters const cParams = cctx->appliedParams.cParams;\n    assert(!ZSTD_checkCParams(cParams));\n    return MIN (ZSTD_BLOCKSIZE_MAX, (U32)1 << cParams.windowLog);\n}\n\nsize_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)\n{\n    DEBUGLOG(5, \"ZSTD_compressBlock: srcSize = %u\", (unsigned)srcSize);\n    { size_t const blockSizeMax = ZSTD_getBlockSize(cctx);\n      RETURN_ERROR_IF(srcSize > blockSizeMax, srcSize_wrong); }\n\n    return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);\n}\n\n/*! ZSTD_loadDictionaryContent() :\n *  @return : 0, or an error code\n */\nstatic size_t ZSTD_loadDictionaryContent(ZSTD_matchState_t* ms,\n                                         ZSTD_cwksp* ws,\n                                         ZSTD_CCtx_params const* params,\n                                         const void* src, size_t srcSize,\n                                         ZSTD_dictTableLoadMethod_e dtlm)\n{\n    const BYTE* ip = (const BYTE*) src;\n    const BYTE* const iend = ip + srcSize;\n\n    ZSTD_window_update(&ms->window, src, srcSize);\n    ms->loadedDictEnd = params->forceWindow ? 0 : (U32)(iend - ms->window.base);\n\n    /* Assert that we the ms params match the params we're being given */\n    ZSTD_assertEqualCParams(params->cParams, ms->cParams);\n\n    if (srcSize <= HASH_READ_SIZE) return 0;\n\n    while (iend - ip > HASH_READ_SIZE) {\n        size_t const remaining = (size_t)(iend - ip);\n        size_t const chunk = MIN(remaining, ZSTD_CHUNKSIZE_MAX);\n        const BYTE* const ichunk = ip + chunk;\n\n        ZSTD_overflowCorrectIfNeeded(ms, ws, params, ip, ichunk);\n\n        switch(params->cParams.strategy)\n        {\n        case ZSTD_fast:\n            ZSTD_fillHashTable(ms, ichunk, dtlm);\n            break;\n        case ZSTD_dfast:\n            ZSTD_fillDoubleHashTable(ms, ichunk, dtlm);\n            break;\n\n        case ZSTD_greedy:\n        case ZSTD_lazy:\n        case ZSTD_lazy2:\n            if (chunk >= HASH_READ_SIZE)\n                ZSTD_insertAndFindFirstIndex(ms, ichunk-HASH_READ_SIZE);\n            break;\n\n        case ZSTD_btlazy2:   /* we want the dictionary table fully sorted */\n        case ZSTD_btopt:\n        case ZSTD_btultra:\n        case ZSTD_btultra2:\n            if (chunk >= HASH_READ_SIZE)\n                ZSTD_updateTree(ms, ichunk-HASH_READ_SIZE, ichunk);\n            break;\n\n        default:\n            assert(0);  /* not possible : not a valid strategy id */\n        }\n\n        ip = ichunk;\n    }\n\n    ms->nextToUpdate = (U32)(iend - ms->window.base);\n    return 0;\n}\n\n\n/* Dictionaries that assign zero probability to symbols that show up causes problems\n   when FSE encoding.  Refuse dictionaries that assign zero probability to symbols\n   that we may encounter during compression.\n   NOTE: This behavior is not standard and could be improved in the future. */\nstatic size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {\n    U32 s;\n    RETURN_ERROR_IF(dictMaxSymbolValue < maxSymbolValue, dictionary_corrupted);\n    for (s = 0; s <= maxSymbolValue; ++s) {\n        RETURN_ERROR_IF(normalizedCounter[s] == 0, dictionary_corrupted);\n    }\n    return 0;\n}\n\n\n/* Dictionary format :\n * See :\n * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format\n */\n/*! ZSTD_loadZstdDictionary() :\n * @return : dictID, or an error code\n *  assumptions : magic number supposed already checked\n *                dictSize supposed >= 8\n */\nstatic size_t ZSTD_loadZstdDictionary(ZSTD_compressedBlockState_t* bs,\n                                      ZSTD_matchState_t* ms,\n                                      ZSTD_cwksp* ws,\n                                      ZSTD_CCtx_params const* params,\n                                      const void* dict, size_t dictSize,\n                                      ZSTD_dictTableLoadMethod_e dtlm,\n                                      void* workspace)\n{\n    const BYTE* dictPtr = (const BYTE*)dict;\n    const BYTE* const dictEnd = dictPtr + dictSize;\n    short offcodeNCount[MaxOff+1];\n    unsigned offcodeMaxValue = MaxOff;\n    size_t dictID;\n\n    ZSTD_STATIC_ASSERT(HUF_WORKSPACE_SIZE >= (1<<MAX(MLFSELog,LLFSELog)));\n    assert(dictSize >= 8);\n    assert(MEM_readLE32(dictPtr) == ZSTD_MAGIC_DICTIONARY);\n\n    dictPtr += 4;   /* skip magic number */\n    dictID = params->fParams.noDictIDFlag ? 0 :  MEM_readLE32(dictPtr);\n    dictPtr += 4;\n\n    {   unsigned maxSymbolValue = 255;\n        size_t const hufHeaderSize = HUF_readCTable((HUF_CElt*)bs->entropy.huf.CTable, &maxSymbolValue, dictPtr, dictEnd-dictPtr);\n        RETURN_ERROR_IF(HUF_isError(hufHeaderSize), dictionary_corrupted);\n        RETURN_ERROR_IF(maxSymbolValue < 255, dictionary_corrupted);\n        dictPtr += hufHeaderSize;\n    }\n\n    {   unsigned offcodeLog;\n        size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);\n        RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted);\n        RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted);\n        /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */\n        /* fill all offset symbols to avoid garbage at end of table */\n        RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(\n                bs->entropy.fse.offcodeCTable,\n                offcodeNCount, MaxOff, offcodeLog,\n                workspace, HUF_WORKSPACE_SIZE)),\n            dictionary_corrupted);\n        dictPtr += offcodeHeaderSize;\n    }\n\n    {   short matchlengthNCount[MaxML+1];\n        unsigned matchlengthMaxValue = MaxML, matchlengthLog;\n        size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);\n        RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted);\n        RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted);\n        /* Every match length code must have non-zero probability */\n        FORWARD_IF_ERROR( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));\n        RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(\n                bs->entropy.fse.matchlengthCTable,\n                matchlengthNCount, matchlengthMaxValue, matchlengthLog,\n                workspace, HUF_WORKSPACE_SIZE)),\n            dictionary_corrupted);\n        dictPtr += matchlengthHeaderSize;\n    }\n\n    {   short litlengthNCount[MaxLL+1];\n        unsigned litlengthMaxValue = MaxLL, litlengthLog;\n        size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);\n        RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted);\n        RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted);\n        /* Every literal length code must have non-zero probability */\n        FORWARD_IF_ERROR( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));\n        RETURN_ERROR_IF(FSE_isError(FSE_buildCTable_wksp(\n                bs->entropy.fse.litlengthCTable,\n                litlengthNCount, litlengthMaxValue, litlengthLog,\n                workspace, HUF_WORKSPACE_SIZE)),\n            dictionary_corrupted);\n        dictPtr += litlengthHeaderSize;\n    }\n\n    RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted);\n    bs->rep[0] = MEM_readLE32(dictPtr+0);\n    bs->rep[1] = MEM_readLE32(dictPtr+4);\n    bs->rep[2] = MEM_readLE32(dictPtr+8);\n    dictPtr += 12;\n\n    {   size_t const dictContentSize = (size_t)(dictEnd - dictPtr);\n        U32 offcodeMax = MaxOff;\n        if (dictContentSize <= ((U32)-1) - 128 KB) {\n            U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */\n            offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */\n        }\n        /* All offset values <= dictContentSize + 128 KB must be representable */\n        FORWARD_IF_ERROR(ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));\n        /* All repCodes must be <= dictContentSize and != 0*/\n        {   U32 u;\n            for (u=0; u<3; u++) {\n                RETURN_ERROR_IF(bs->rep[u] == 0, dictionary_corrupted);\n                RETURN_ERROR_IF(bs->rep[u] > dictContentSize, dictionary_corrupted);\n        }   }\n\n        bs->entropy.huf.repeatMode = HUF_repeat_valid;\n        bs->entropy.fse.offcode_repeatMode = FSE_repeat_valid;\n        bs->entropy.fse.matchlength_repeatMode = FSE_repeat_valid;\n        bs->entropy.fse.litlength_repeatMode = FSE_repeat_valid;\n        FORWARD_IF_ERROR(ZSTD_loadDictionaryContent(\n            ms, ws, params, dictPtr, dictContentSize, dtlm));\n        return dictID;\n    }\n}\n\n/** ZSTD_compress_insertDictionary() :\n*   @return : dictID, or an error code */\nstatic size_t\nZSTD_compress_insertDictionary(ZSTD_compressedBlockState_t* bs,\n                               ZSTD_matchState_t* ms,\n                               ZSTD_cwksp* ws,\n                         const ZSTD_CCtx_params* params,\n                         const void* dict, size_t dictSize,\n                               ZSTD_dictContentType_e dictContentType,\n                               ZSTD_dictTableLoadMethod_e dtlm,\n                               void* workspace)\n{\n    DEBUGLOG(4, \"ZSTD_compress_insertDictionary (dictSize=%u)\", (U32)dictSize);\n    if ((dict==NULL) || (dictSize<8)) {\n        RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);\n        return 0;\n    }\n\n    ZSTD_reset_compressedBlockState(bs);\n\n    /* dict restricted modes */\n    if (dictContentType == ZSTD_dct_rawContent)\n        return ZSTD_loadDictionaryContent(ms, ws, params, dict, dictSize, dtlm);\n\n    if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) {\n        if (dictContentType == ZSTD_dct_auto) {\n            DEBUGLOG(4, \"raw content dictionary detected\");\n            return ZSTD_loadDictionaryContent(\n                ms, ws, params, dict, dictSize, dtlm);\n        }\n        RETURN_ERROR_IF(dictContentType == ZSTD_dct_fullDict, dictionary_wrong);\n        assert(0);   /* impossible */\n    }\n\n    /* dict as full zstd dictionary */\n    return ZSTD_loadZstdDictionary(\n        bs, ms, ws, params, dict, dictSize, dtlm, workspace);\n}\n\n#define ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF (128 KB)\n#define ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER (6)\n\n/*! ZSTD_compressBegin_internal() :\n * @return : 0, or an error code */\nstatic size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,\n                                    const void* dict, size_t dictSize,\n                                    ZSTD_dictContentType_e dictContentType,\n                                    ZSTD_dictTableLoadMethod_e dtlm,\n                                    const ZSTD_CDict* cdict,\n                                    const ZSTD_CCtx_params* params, U64 pledgedSrcSize,\n                                    ZSTD_buffered_policy_e zbuff)\n{\n    DEBUGLOG(4, \"ZSTD_compressBegin_internal: wlog=%u\", params->cParams.windowLog);\n    /* params are supposed to be fully validated at this point */\n    assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));\n    assert(!((dict) && (cdict)));  /* either dict or cdict, not both */\n    if ( (cdict)\n      && (cdict->dictContentSize > 0)\n      && ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF\n        || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER\n        || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN\n        || cdict->compressionLevel == 0)\n      && (params->attachDictPref != ZSTD_dictForceLoad) ) {\n        return ZSTD_resetCCtx_usingCDict(cctx, cdict, params, pledgedSrcSize, zbuff);\n    }\n\n    FORWARD_IF_ERROR( ZSTD_resetCCtx_internal(cctx, *params, pledgedSrcSize,\n                                     ZSTDcrp_makeClean, zbuff) );\n    {   size_t const dictID = cdict ?\n                ZSTD_compress_insertDictionary(\n                        cctx->blockState.prevCBlock, &cctx->blockState.matchState,\n                        &cctx->workspace, params, cdict->dictContent, cdict->dictContentSize,\n                        dictContentType, dtlm, cctx->entropyWorkspace)\n              : ZSTD_compress_insertDictionary(\n                        cctx->blockState.prevCBlock, &cctx->blockState.matchState,\n                        &cctx->workspace, params, dict, dictSize,\n                        dictContentType, dtlm, cctx->entropyWorkspace);\n        FORWARD_IF_ERROR(dictID);\n        assert(dictID <= UINT_MAX);\n        cctx->dictID = (U32)dictID;\n    }\n    return 0;\n}\n\nsize_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,\n                                    const void* dict, size_t dictSize,\n                                    ZSTD_dictContentType_e dictContentType,\n                                    ZSTD_dictTableLoadMethod_e dtlm,\n                                    const ZSTD_CDict* cdict,\n                                    const ZSTD_CCtx_params* params,\n                                    unsigned long long pledgedSrcSize)\n{\n    DEBUGLOG(4, \"ZSTD_compressBegin_advanced_internal: wlog=%u\", params->cParams.windowLog);\n    /* compression parameters verification and optimization */\n    FORWARD_IF_ERROR( ZSTD_checkCParams(params->cParams) );\n    return ZSTD_compressBegin_internal(cctx,\n                                       dict, dictSize, dictContentType, dtlm,\n                                       cdict,\n                                       params, pledgedSrcSize,\n                                       ZSTDb_not_buffered);\n}\n\n/*! ZSTD_compressBegin_advanced() :\n*   @return : 0, or an error code */\nsize_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,\n                             const void* dict, size_t dictSize,\n                                   ZSTD_parameters params, unsigned long long pledgedSrcSize)\n{\n    ZSTD_CCtx_params const cctxParams =\n            ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);\n    return ZSTD_compressBegin_advanced_internal(cctx,\n                                            dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast,\n                                            NULL /*cdict*/,\n                                            &cctxParams, pledgedSrcSize);\n}\n\nsize_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)\n{\n    ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, dictSize);\n    ZSTD_CCtx_params const cctxParams =\n            ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);\n    DEBUGLOG(4, \"ZSTD_compressBegin_usingDict (dictSize=%u)\", (unsigned)dictSize);\n    return ZSTD_compressBegin_internal(cctx, dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,\n                                       &cctxParams, ZSTD_CONTENTSIZE_UNKNOWN, ZSTDb_not_buffered);\n}\n\nsize_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)\n{\n    return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel);\n}\n\n\n/*! ZSTD_writeEpilogue() :\n*   Ends a frame.\n*   @return : nb of bytes written into dst (or an error code) */\nstatic size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)\n{\n    BYTE* const ostart = (BYTE*)dst;\n    BYTE* op = ostart;\n    size_t fhSize = 0;\n\n    DEBUGLOG(4, \"ZSTD_writeEpilogue\");\n    RETURN_ERROR_IF(cctx->stage == ZSTDcs_created, stage_wrong, \"init missing\");\n\n    /* special case : empty frame */\n    if (cctx->stage == ZSTDcs_init) {\n        fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, &cctx->appliedParams, 0, 0);\n        FORWARD_IF_ERROR(fhSize);\n        dstCapacity -= fhSize;\n        op += fhSize;\n        cctx->stage = ZSTDcs_ongoing;\n    }\n\n    if (cctx->stage != ZSTDcs_ending) {\n        /* write one last empty block, make it the \"last\" block */\n        U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;\n        RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall);\n        MEM_writeLE32(op, cBlockHeader24);\n        op += ZSTD_blockHeaderSize;\n        dstCapacity -= ZSTD_blockHeaderSize;\n    }\n\n    if (cctx->appliedParams.fParams.checksumFlag) {\n        U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);\n        RETURN_ERROR_IF(dstCapacity<4, dstSize_tooSmall);\n        DEBUGLOG(4, \"ZSTD_writeEpilogue: write checksum : %08X\", (unsigned)checksum);\n        MEM_writeLE32(op, checksum);\n        op += 4;\n    }\n\n    cctx->stage = ZSTDcs_created;  /* return to \"created but no init\" status */\n    return op-ostart;\n}\n\nsize_t ZSTD_compressEnd (ZSTD_CCtx* cctx,\n                         void* dst, size_t dstCapacity,\n                   const void* src, size_t srcSize)\n{\n    size_t endResult;\n    size_t const cSize = ZSTD_compressContinue_internal(cctx,\n                                dst, dstCapacity, src, srcSize,\n                                1 /* frame mode */, 1 /* last chunk */);\n    FORWARD_IF_ERROR(cSize);\n    endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);\n    FORWARD_IF_ERROR(endResult);\n    assert(!(cctx->appliedParams.fParams.contentSizeFlag && cctx->pledgedSrcSizePlusOne == 0));\n    if (cctx->pledgedSrcSizePlusOne != 0) {  /* control src size */\n        ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_UNKNOWN == (unsigned long long)-1);\n        DEBUGLOG(4, \"end of frame : controlling src size\");\n        RETURN_ERROR_IF(\n            cctx->pledgedSrcSizePlusOne != cctx->consumedSrcSize+1,\n            srcSize_wrong,\n             \"error : pledgedSrcSize = %u, while realSrcSize = %u\",\n            (unsigned)cctx->pledgedSrcSizePlusOne-1,\n            (unsigned)cctx->consumedSrcSize);\n    }\n    return cSize + endResult;\n}\n\n\nstatic size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,\n                                      void* dst, size_t dstCapacity,\n                                const void* src, size_t srcSize,\n                                const void* dict,size_t dictSize,\n                                      ZSTD_parameters params)\n{\n    ZSTD_CCtx_params const cctxParams =\n            ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);\n    DEBUGLOG(4, \"ZSTD_compress_internal\");\n    return ZSTD_compress_advanced_internal(cctx,\n                                           dst, dstCapacity,\n                                           src, srcSize,\n                                           dict, dictSize,\n                                           &cctxParams);\n}\n\nsize_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,\n                               void* dst, size_t dstCapacity,\n                         const void* src, size_t srcSize,\n                         const void* dict,size_t dictSize,\n                               ZSTD_parameters params)\n{\n    DEBUGLOG(4, \"ZSTD_compress_advanced\");\n    FORWARD_IF_ERROR(ZSTD_checkCParams(params.cParams));\n    return ZSTD_compress_internal(cctx,\n                                  dst, dstCapacity,\n                                  src, srcSize,\n                                  dict, dictSize,\n                                  params);\n}\n\n/* Internal */\nsize_t ZSTD_compress_advanced_internal(\n        ZSTD_CCtx* cctx,\n        void* dst, size_t dstCapacity,\n        const void* src, size_t srcSize,\n        const void* dict,size_t dictSize,\n        const ZSTD_CCtx_params* params)\n{\n    DEBUGLOG(4, \"ZSTD_compress_advanced_internal (srcSize:%u)\", (unsigned)srcSize);\n    FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,\n                         dict, dictSize, ZSTD_dct_auto, ZSTD_dtlm_fast, NULL,\n                         params, srcSize, ZSTDb_not_buffered) );\n    return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);\n}\n\nsize_t ZSTD_compress_usingDict(ZSTD_CCtx* cctx,\n                               void* dst, size_t dstCapacity,\n                         const void* src, size_t srcSize,\n                         const void* dict, size_t dictSize,\n                               int compressionLevel)\n{\n    ZSTD_parameters const params = ZSTD_getParams(compressionLevel, srcSize + (!srcSize), dict ? dictSize : 0);\n    ZSTD_CCtx_params cctxParams = ZSTD_assignParamsToCCtxParams(&cctx->requestedParams, params);\n    assert(params.fParams.contentSizeFlag == 1);\n    return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, &cctxParams);\n}\n\nsize_t ZSTD_compressCCtx(ZSTD_CCtx* cctx,\n                         void* dst, size_t dstCapacity,\n                   const void* src, size_t srcSize,\n                         int compressionLevel)\n{\n    DEBUGLOG(4, \"ZSTD_compressCCtx (srcSize=%u)\", (unsigned)srcSize);\n    assert(cctx != NULL);\n    return ZSTD_compress_usingDict(cctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);\n}\n\nsize_t ZSTD_compress(void* dst, size_t dstCapacity,\n               const void* src, size_t srcSize,\n                     int compressionLevel)\n{\n    size_t result;\n    ZSTD_CCtx ctxBody;\n    ZSTD_initCCtx(&ctxBody, ZSTD_defaultCMem);\n    result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);\n    ZSTD_freeCCtxContent(&ctxBody);   /* can't free ctxBody itself, as it's on stack; free only heap content */\n    return result;\n}\n\n\n/* =====  Dictionary API  ===== */\n\n/*! ZSTD_estimateCDictSize_advanced() :\n *  Estimate amount of memory that will be needed to create a dictionary with following arguments */\nsize_t ZSTD_estimateCDictSize_advanced(\n        size_t dictSize, ZSTD_compressionParameters cParams,\n        ZSTD_dictLoadMethod_e dictLoadMethod)\n{\n    DEBUGLOG(5, \"sizeof(ZSTD_CDict) : %u\", (unsigned)sizeof(ZSTD_CDict));\n    return ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))\n         + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE)\n         + ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0)\n         + (dictLoadMethod == ZSTD_dlm_byRef ? 0\n            : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void *))));\n}\n\nsize_t ZSTD_estimateCDictSize(size_t dictSize, int compressionLevel)\n{\n    ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);\n    return ZSTD_estimateCDictSize_advanced(dictSize, cParams, ZSTD_dlm_byCopy);\n}\n\nsize_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)\n{\n    if (cdict==NULL) return 0;   /* support sizeof on NULL */\n    DEBUGLOG(5, \"sizeof(*cdict) : %u\", (unsigned)sizeof(*cdict));\n    /* cdict may be in the workspace */\n    return (cdict->workspace.workspace == cdict ? 0 : sizeof(*cdict))\n        + ZSTD_cwksp_sizeof(&cdict->workspace);\n}\n\nstatic size_t ZSTD_initCDict_internal(\n                    ZSTD_CDict* cdict,\n              const void* dictBuffer, size_t dictSize,\n                    ZSTD_dictLoadMethod_e dictLoadMethod,\n                    ZSTD_dictContentType_e dictContentType,\n                    ZSTD_compressionParameters cParams)\n{\n    DEBUGLOG(3, \"ZSTD_initCDict_internal (dictContentType:%u)\", (unsigned)dictContentType);\n    assert(!ZSTD_checkCParams(cParams));\n    cdict->matchState.cParams = cParams;\n    if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dictBuffer) || (!dictSize)) {\n        cdict->dictContent = dictBuffer;\n    } else {\n         void *internalBuffer = ZSTD_cwksp_reserve_object(&cdict->workspace, ZSTD_cwksp_align(dictSize, sizeof(void*)));\n        RETURN_ERROR_IF(!internalBuffer, memory_allocation);\n        cdict->dictContent = internalBuffer;\n        memcpy(internalBuffer, dictBuffer, dictSize);\n    }\n    cdict->dictContentSize = dictSize;\n\n    cdict->entropyWorkspace = (U32*)ZSTD_cwksp_reserve_object(&cdict->workspace, HUF_WORKSPACE_SIZE);\n\n\n    /* Reset the state to no dictionary */\n    ZSTD_reset_compressedBlockState(&cdict->cBlockState);\n    FORWARD_IF_ERROR(ZSTD_reset_matchState(\n        &cdict->matchState,\n        &cdict->workspace,\n        &cParams,\n        ZSTDcrp_makeClean,\n        ZSTDirp_reset,\n        ZSTD_resetTarget_CDict));\n    /* (Maybe) load the dictionary\n     * Skips loading the dictionary if it is < 8 bytes.\n     */\n    {   ZSTD_CCtx_params params;\n        memset(&params, 0, sizeof(params));\n        params.compressionLevel = ZSTD_CLEVEL_DEFAULT;\n        params.fParams.contentSizeFlag = 1;\n        params.cParams = cParams;\n        {   size_t const dictID = ZSTD_compress_insertDictionary(\n                    &cdict->cBlockState, &cdict->matchState, &cdict->workspace,\n                    &params, cdict->dictContent, cdict->dictContentSize,\n                    dictContentType, ZSTD_dtlm_full, cdict->entropyWorkspace);\n            FORWARD_IF_ERROR(dictID);\n            assert(dictID <= (size_t)(U32)-1);\n            cdict->dictID = (U32)dictID;\n        }\n    }\n\n    return 0;\n}\n\nZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize,\n                                      ZSTD_dictLoadMethod_e dictLoadMethod,\n                                      ZSTD_dictContentType_e dictContentType,\n                                      ZSTD_compressionParameters cParams, ZSTD_customMem customMem)\n{\n    DEBUGLOG(3, \"ZSTD_createCDict_advanced, mode %u\", (unsigned)dictContentType);\n    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;\n\n    {   size_t const workspaceSize =\n            ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict)) +\n            ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE) +\n            ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0) +\n            (dictLoadMethod == ZSTD_dlm_byRef ? 0\n             : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))));\n        void* const workspace = ZSTD_malloc(workspaceSize, customMem);\n        ZSTD_cwksp ws;\n        ZSTD_CDict* cdict;\n\n        if (!workspace) {\n            ZSTD_free(workspace, customMem);\n            return NULL;\n        }\n\n        ZSTD_cwksp_init(&ws, workspace, workspaceSize);\n\n        cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));\n        assert(cdict != NULL);\n        ZSTD_cwksp_move(&cdict->workspace, &ws);\n        cdict->customMem = customMem;\n        cdict->compressionLevel = 0; /* signals advanced API usage */\n\n        if (ZSTD_isError( ZSTD_initCDict_internal(cdict,\n                                        dictBuffer, dictSize,\n                                        dictLoadMethod, dictContentType,\n                                        cParams) )) {\n            ZSTD_freeCDict(cdict);\n            return NULL;\n        }\n\n        return cdict;\n    }\n}\n\nZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)\n{\n    ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);\n    ZSTD_CDict* cdict = ZSTD_createCDict_advanced(dict, dictSize,\n                                                  ZSTD_dlm_byCopy, ZSTD_dct_auto,\n                                                  cParams, ZSTD_defaultCMem);\n    if (cdict)\n        cdict->compressionLevel = compressionLevel == 0 ? ZSTD_CLEVEL_DEFAULT : compressionLevel;\n    return cdict;\n}\n\nZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)\n{\n    ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);\n    return ZSTD_createCDict_advanced(dict, dictSize,\n                                     ZSTD_dlm_byRef, ZSTD_dct_auto,\n                                     cParams, ZSTD_defaultCMem);\n}\n\nsize_t ZSTD_freeCDict(ZSTD_CDict* cdict)\n{\n    if (cdict==NULL) return 0;   /* support free on NULL */\n    {   ZSTD_customMem const cMem = cdict->customMem;\n        int cdictInWorkspace = ZSTD_cwksp_owns_buffer(&cdict->workspace, cdict);\n        ZSTD_cwksp_free(&cdict->workspace, cMem);\n        if (!cdictInWorkspace) {\n            ZSTD_free(cdict, cMem);\n        }\n        return 0;\n    }\n}\n\n/*! ZSTD_initStaticCDict_advanced() :\n *  Generate a digested dictionary in provided memory area.\n *  workspace: The memory area to emplace the dictionary into.\n *             Provided pointer must 8-bytes aligned.\n *             It must outlive dictionary usage.\n *  workspaceSize: Use ZSTD_estimateCDictSize()\n *                 to determine how large workspace must be.\n *  cParams : use ZSTD_getCParams() to transform a compression level\n *            into its relevants cParams.\n * @return : pointer to ZSTD_CDict*, or NULL if error (size too small)\n *  Note : there is no corresponding \"free\" function.\n *         Since workspace was allocated externally, it must be freed externally.\n */\nconst ZSTD_CDict* ZSTD_initStaticCDict(\n                                 void* workspace, size_t workspaceSize,\n                           const void* dict, size_t dictSize,\n                                 ZSTD_dictLoadMethod_e dictLoadMethod,\n                                 ZSTD_dictContentType_e dictContentType,\n                                 ZSTD_compressionParameters cParams)\n{\n    size_t const matchStateSize = ZSTD_sizeof_matchState(&cParams, /* forCCtx */ 0);\n    size_t const neededSize = ZSTD_cwksp_alloc_size(sizeof(ZSTD_CDict))\n                            + (dictLoadMethod == ZSTD_dlm_byRef ? 0\n                               : ZSTD_cwksp_alloc_size(ZSTD_cwksp_align(dictSize, sizeof(void*))))\n                            + ZSTD_cwksp_alloc_size(HUF_WORKSPACE_SIZE)\n                            + matchStateSize;\n    ZSTD_CDict* cdict;\n\n    if ((size_t)workspace & 7) return NULL;  /* 8-aligned */\n\n    {\n        ZSTD_cwksp ws;\n        ZSTD_cwksp_init(&ws, workspace, workspaceSize);\n        cdict = (ZSTD_CDict*)ZSTD_cwksp_reserve_object(&ws, sizeof(ZSTD_CDict));\n        if (cdict == NULL) return NULL;\n        ZSTD_cwksp_move(&cdict->workspace, &ws);\n    }\n\n    DEBUGLOG(4, \"(workspaceSize < neededSize) : (%u < %u) => %u\",\n        (unsigned)workspaceSize, (unsigned)neededSize, (unsigned)(workspaceSize < neededSize));\n    if (workspaceSize < neededSize) return NULL;\n\n    if (ZSTD_isError( ZSTD_initCDict_internal(cdict,\n                                              dict, dictSize,\n                                              dictLoadMethod, dictContentType,\n                                              cParams) ))\n        return NULL;\n\n    return cdict;\n}\n\nZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict)\n{\n    assert(cdict != NULL);\n    return cdict->matchState.cParams;\n}\n\n/* ZSTD_compressBegin_usingCDict_advanced() :\n * cdict must be != NULL */\nsize_t ZSTD_compressBegin_usingCDict_advanced(\n    ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,\n    ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)\n{\n    DEBUGLOG(4, \"ZSTD_compressBegin_usingCDict_advanced\");\n    RETURN_ERROR_IF(cdict==NULL, dictionary_wrong);\n    {   ZSTD_CCtx_params params = cctx->requestedParams;\n        params.cParams = ( pledgedSrcSize < ZSTD_USE_CDICT_PARAMS_SRCSIZE_CUTOFF\n                        || pledgedSrcSize < cdict->dictContentSize * ZSTD_USE_CDICT_PARAMS_DICTSIZE_MULTIPLIER\n                        || pledgedSrcSize == ZSTD_CONTENTSIZE_UNKNOWN\n                        || cdict->compressionLevel == 0 )\n                      && (params.attachDictPref != ZSTD_dictForceLoad) ?\n                ZSTD_getCParamsFromCDict(cdict)\n              : ZSTD_getCParams(cdict->compressionLevel,\n                                pledgedSrcSize,\n                                cdict->dictContentSize);\n        /* Increase window log to fit the entire dictionary and source if the\n         * source size is known. Limit the increase to 19, which is the\n         * window log for compression level 1 with the largest source size.\n         */\n        if (pledgedSrcSize != ZSTD_CONTENTSIZE_UNKNOWN) {\n            U32 const limitedSrcSize = (U32)MIN(pledgedSrcSize, 1U << 19);\n            U32 const limitedSrcLog = limitedSrcSize > 1 ? ZSTD_highbit32(limitedSrcSize - 1) + 1 : 1;\n            params.cParams.windowLog = MAX(params.cParams.windowLog, limitedSrcLog);\n        }\n        params.fParams = fParams;\n        return ZSTD_compressBegin_internal(cctx,\n                                           NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast,\n                                           cdict,\n                                           &params, pledgedSrcSize,\n                                           ZSTDb_not_buffered);\n    }\n}\n\n/* ZSTD_compressBegin_usingCDict() :\n * pledgedSrcSize=0 means \"unknown\"\n * if pledgedSrcSize>0, it will enable contentSizeFlag */\nsize_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)\n{\n    ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };\n    DEBUGLOG(4, \"ZSTD_compressBegin_usingCDict : dictIDFlag == %u\", !fParams.noDictIDFlag);\n    return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, ZSTD_CONTENTSIZE_UNKNOWN);\n}\n\nsize_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,\n                                void* dst, size_t dstCapacity,\n                                const void* src, size_t srcSize,\n                                const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)\n{\n    FORWARD_IF_ERROR(ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize));   /* will check if cdict != NULL */\n    return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);\n}\n\n/*! ZSTD_compress_usingCDict() :\n *  Compression using a digested Dictionary.\n *  Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.\n *  Note that compression parameters are decided at CDict creation time\n *  while frame parameters are hardcoded */\nsize_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,\n                                void* dst, size_t dstCapacity,\n                                const void* src, size_t srcSize,\n                                const ZSTD_CDict* cdict)\n{\n    ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };\n    return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, fParams);\n}\n\n\n\n/* ******************************************************************\n*  Streaming\n********************************************************************/\n\nZSTD_CStream* ZSTD_createCStream(void)\n{\n    DEBUGLOG(3, \"ZSTD_createCStream\");\n    return ZSTD_createCStream_advanced(ZSTD_defaultCMem);\n}\n\nZSTD_CStream* ZSTD_initStaticCStream(void *workspace, size_t workspaceSize)\n{\n    return ZSTD_initStaticCCtx(workspace, workspaceSize);\n}\n\nZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)\n{   /* CStream and CCtx are now same object */\n    return ZSTD_createCCtx_advanced(customMem);\n}\n\nsize_t ZSTD_freeCStream(ZSTD_CStream* zcs)\n{\n    return ZSTD_freeCCtx(zcs);   /* same object */\n}\n\n\n\n/*======   Initialization   ======*/\n\nsize_t ZSTD_CStreamInSize(void)  { return ZSTD_BLOCKSIZE_MAX; }\n\nsize_t ZSTD_CStreamOutSize(void)\n{\n    return ZSTD_compressBound(ZSTD_BLOCKSIZE_MAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;\n}\n\nstatic size_t ZSTD_resetCStream_internal(ZSTD_CStream* cctx,\n                    const void* const dict, size_t const dictSize, ZSTD_dictContentType_e const dictContentType,\n                    const ZSTD_CDict* const cdict,\n                    ZSTD_CCtx_params params, unsigned long long const pledgedSrcSize)\n{\n    DEBUGLOG(4, \"ZSTD_resetCStream_internal\");\n    /* Finalize the compression parameters */\n    params.cParams = ZSTD_getCParamsFromCCtxParams(&params, pledgedSrcSize, dictSize);\n    /* params are supposed to be fully validated at this point */\n    assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));\n    assert(!((dict) && (cdict)));  /* either dict or cdict, not both */\n\n    FORWARD_IF_ERROR( ZSTD_compressBegin_internal(cctx,\n                                         dict, dictSize, dictContentType, ZSTD_dtlm_fast,\n                                         cdict,\n                                         &params, pledgedSrcSize,\n                                         ZSTDb_buffered) );\n\n    cctx->inToCompress = 0;\n    cctx->inBuffPos = 0;\n    cctx->inBuffTarget = cctx->blockSize\n                      + (cctx->blockSize == pledgedSrcSize);   /* for small input: avoid automatic flush on reaching end of block, since it would require to add a 3-bytes null block to end frame */\n    cctx->outBuffContentSize = cctx->outBuffFlushedSize = 0;\n    cctx->streamStage = zcss_load;\n    cctx->frameEnded = 0;\n    return 0;   /* ready to go */\n}\n\n/* ZSTD_resetCStream():\n * pledgedSrcSize == 0 means \"unknown\" */\nsize_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pss)\n{\n    /* temporary : 0 interpreted as \"unknown\" during transition period.\n     * Users willing to specify \"unknown\" **must** use ZSTD_CONTENTSIZE_UNKNOWN.\n     * 0 will be interpreted as \"empty\" in the future.\n     */\n    U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;\n    DEBUGLOG(4, \"ZSTD_resetCStream: pledgedSrcSize = %u\", (unsigned)pledgedSrcSize);\n    FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );\n    return 0;\n}\n\n/*! ZSTD_initCStream_internal() :\n *  Note : for lib/compress only. Used by zstdmt_compress.c.\n *  Assumption 1 : params are valid\n *  Assumption 2 : either dict, or cdict, is defined, not both */\nsize_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,\n                    const void* dict, size_t dictSize, const ZSTD_CDict* cdict,\n                    const ZSTD_CCtx_params* params,\n                    unsigned long long pledgedSrcSize)\n{\n    DEBUGLOG(4, \"ZSTD_initCStream_internal\");\n    FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );\n    assert(!ZSTD_isError(ZSTD_checkCParams(params->cParams)));\n    zcs->requestedParams = *params;\n    assert(!((dict) && (cdict)));  /* either dict or cdict, not both */\n    if (dict) {\n        FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );\n    } else {\n        /* Dictionary is cleared if !cdict */\n        FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );\n    }\n    return 0;\n}\n\n/* ZSTD_initCStream_usingCDict_advanced() :\n * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */\nsize_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs,\n                                            const ZSTD_CDict* cdict,\n                                            ZSTD_frameParameters fParams,\n                                            unsigned long long pledgedSrcSize)\n{\n    DEBUGLOG(4, \"ZSTD_initCStream_usingCDict_advanced\");\n    FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );\n    zcs->requestedParams.fParams = fParams;\n    FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );\n    return 0;\n}\n\n/* note : cdict must outlive compression session */\nsize_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)\n{\n    DEBUGLOG(4, \"ZSTD_initCStream_usingCDict\");\n    FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, cdict) );\n    return 0;\n}\n\n\n/* ZSTD_initCStream_advanced() :\n * pledgedSrcSize must be exact.\n * if srcSize is not known at init time, use value ZSTD_CONTENTSIZE_UNKNOWN.\n * dict is loaded with default parameters ZSTD_dct_auto and ZSTD_dlm_byCopy. */\nsize_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,\n                                 const void* dict, size_t dictSize,\n                                 ZSTD_parameters params, unsigned long long pss)\n{\n    /* for compatibility with older programs relying on this behavior.\n     * Users should now specify ZSTD_CONTENTSIZE_UNKNOWN.\n     * This line will be removed in the future.\n     */\n    U64 const pledgedSrcSize = (pss==0 && params.fParams.contentSizeFlag==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;\n    DEBUGLOG(4, \"ZSTD_initCStream_advanced\");\n    FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );\n    FORWARD_IF_ERROR( ZSTD_checkCParams(params.cParams) );\n    zcs->requestedParams = ZSTD_assignParamsToCCtxParams(&zcs->requestedParams, params);\n    FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );\n    return 0;\n}\n\nsize_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)\n{\n    DEBUGLOG(4, \"ZSTD_initCStream_usingDict\");\n    FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_loadDictionary(zcs, dict, dictSize) );\n    return 0;\n}\n\nsize_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pss)\n{\n    /* temporary : 0 interpreted as \"unknown\" during transition period.\n     * Users willing to specify \"unknown\" **must** use ZSTD_CONTENTSIZE_UNKNOWN.\n     * 0 will be interpreted as \"empty\" in the future.\n     */\n    U64 const pledgedSrcSize = (pss==0) ? ZSTD_CONTENTSIZE_UNKNOWN : pss;\n    DEBUGLOG(4, \"ZSTD_initCStream_srcSize\");\n    FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_setPledgedSrcSize(zcs, pledgedSrcSize) );\n    return 0;\n}\n\nsize_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)\n{\n    DEBUGLOG(4, \"ZSTD_initCStream\");\n    FORWARD_IF_ERROR( ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_refCDict(zcs, NULL) );\n    FORWARD_IF_ERROR( ZSTD_CCtx_setParameter(zcs, ZSTD_c_compressionLevel, compressionLevel) );\n    return 0;\n}\n\n/*======   Compression   ======*/\n\nstatic size_t ZSTD_nextInputSizeHint(const ZSTD_CCtx* cctx)\n{\n    size_t hintInSize = cctx->inBuffTarget - cctx->inBuffPos;\n    if (hintInSize==0) hintInSize = cctx->blockSize;\n    return hintInSize;\n}\n\nstatic size_t ZSTD_limitCopy(void* dst, size_t dstCapacity,\n                       const void* src, size_t srcSize)\n{\n    size_t const length = MIN(dstCapacity, srcSize);\n    if (length) memcpy(dst, src, length);\n    return length;\n}\n\n/** ZSTD_compressStream_generic():\n *  internal function for all *compressStream*() variants\n *  non-static, because can be called from zstdmt_compress.c\n * @return : hint size for next input */\nstatic size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,\n                                          ZSTD_outBuffer* output,\n                                          ZSTD_inBuffer* input,\n                                          ZSTD_EndDirective const flushMode)\n{\n    const char* const istart = (const char*)input->src;\n    const char* const iend = istart + input->size;\n    const char* ip = istart + input->pos;\n    char* const ostart = (char*)output->dst;\n    char* const oend = ostart + output->size;\n    char* op = ostart + output->pos;\n    U32 someMoreWork = 1;\n\n    /* check expectations */\n    DEBUGLOG(5, \"ZSTD_compressStream_generic, flush=%u\", (unsigned)flushMode);\n    assert(zcs->inBuff != NULL);\n    assert(zcs->inBuffSize > 0);\n    assert(zcs->outBuff !=  NULL);\n    assert(zcs->outBuffSize > 0);\n    assert(output->pos <= output->size);\n    assert(input->pos <= input->size);\n\n    while (someMoreWork) {\n        switch(zcs->streamStage)\n        {\n        case zcss_init:\n            RETURN_ERROR(init_missing, \"call ZSTD_initCStream() first!\");\n\n        case zcss_load:\n            if ( (flushMode == ZSTD_e_end)\n              && ((size_t)(oend-op) >= ZSTD_compressBound(iend-ip))  /* enough dstCapacity */\n              && (zcs->inBuffPos == 0) ) {\n                /* shortcut to compression pass directly into output buffer */\n                size_t const cSize = ZSTD_compressEnd(zcs,\n                                                op, oend-op, ip, iend-ip);\n                DEBUGLOG(4, \"ZSTD_compressEnd : cSize=%u\", (unsigned)cSize);\n                FORWARD_IF_ERROR(cSize);\n                ip = iend;\n                op += cSize;\n                zcs->frameEnded = 1;\n                ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n                someMoreWork = 0; break;\n            }\n            /* complete loading into inBuffer */\n            {   size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;\n                size_t const loaded = ZSTD_limitCopy(\n                                        zcs->inBuff + zcs->inBuffPos, toLoad,\n                                        ip, iend-ip);\n                zcs->inBuffPos += loaded;\n                ip += loaded;\n                if ( (flushMode == ZSTD_e_continue)\n                  && (zcs->inBuffPos < zcs->inBuffTarget) ) {\n                    /* not enough input to fill full block : stop here */\n                    someMoreWork = 0; break;\n                }\n                if ( (flushMode == ZSTD_e_flush)\n                  && (zcs->inBuffPos == zcs->inToCompress) ) {\n                    /* empty */\n                    someMoreWork = 0; break;\n                }\n            }\n            /* compress current block (note : this stage cannot be stopped in the middle) */\n            DEBUGLOG(5, \"stream compression stage (flushMode==%u)\", flushMode);\n            {   void* cDst;\n                size_t cSize;\n                size_t const iSize = zcs->inBuffPos - zcs->inToCompress;\n                size_t oSize = oend-op;\n                unsigned const lastBlock = (flushMode == ZSTD_e_end) && (ip==iend);\n                if (oSize >= ZSTD_compressBound(iSize))\n                    cDst = op;   /* compress into output buffer, to skip flush stage */\n                else\n                    cDst = zcs->outBuff, oSize = zcs->outBuffSize;\n                cSize = lastBlock ?\n                        ZSTD_compressEnd(zcs, cDst, oSize,\n                                    zcs->inBuff + zcs->inToCompress, iSize) :\n                        ZSTD_compressContinue(zcs, cDst, oSize,\n                                    zcs->inBuff + zcs->inToCompress, iSize);\n                FORWARD_IF_ERROR(cSize);\n                zcs->frameEnded = lastBlock;\n                /* prepare next block */\n                zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;\n                if (zcs->inBuffTarget > zcs->inBuffSize)\n                    zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize;\n                DEBUGLOG(5, \"inBuffTarget:%u / inBuffSize:%u\",\n                         (unsigned)zcs->inBuffTarget, (unsigned)zcs->inBuffSize);\n                if (!lastBlock)\n                    assert(zcs->inBuffTarget <= zcs->inBuffSize);\n                zcs->inToCompress = zcs->inBuffPos;\n                if (cDst == op) {  /* no need to flush */\n                    op += cSize;\n                    if (zcs->frameEnded) {\n                        DEBUGLOG(5, \"Frame completed directly in outBuffer\");\n                        someMoreWork = 0;\n                        ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n                    }\n                    break;\n                }\n                zcs->outBuffContentSize = cSize;\n                zcs->outBuffFlushedSize = 0;\n                zcs->streamStage = zcss_flush; /* pass-through to flush stage */\n            }\n\t    /* fall-through */\n        case zcss_flush:\n            DEBUGLOG(5, \"flush stage\");\n            {   size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;\n                size_t const flushed = ZSTD_limitCopy(op, (size_t)(oend-op),\n                            zcs->outBuff + zcs->outBuffFlushedSize, toFlush);\n                DEBUGLOG(5, \"toFlush: %u into %u ==> flushed: %u\",\n                            (unsigned)toFlush, (unsigned)(oend-op), (unsigned)flushed);\n                op += flushed;\n                zcs->outBuffFlushedSize += flushed;\n                if (toFlush!=flushed) {\n                    /* flush not fully completed, presumably because dst is too small */\n                    assert(op==oend);\n                    someMoreWork = 0;\n                    break;\n                }\n                zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;\n                if (zcs->frameEnded) {\n                    DEBUGLOG(5, \"Frame completed on flush\");\n                    someMoreWork = 0;\n                    ZSTD_CCtx_reset(zcs, ZSTD_reset_session_only);\n                    break;\n                }\n                zcs->streamStage = zcss_load;\n                break;\n            }\n\n        default: /* impossible */\n            assert(0);\n        }\n    }\n\n    input->pos = ip - istart;\n    output->pos = op - ostart;\n    if (zcs->frameEnded) return 0;\n    return ZSTD_nextInputSizeHint(zcs);\n}\n\nstatic size_t ZSTD_nextInputSizeHint_MTorST(const ZSTD_CCtx* cctx)\n{\n#ifdef ZSTD_MULTITHREAD\n    if (cctx->appliedParams.nbWorkers >= 1) {\n        assert(cctx->mtctx != NULL);\n        return ZSTDMT_nextInputSizeHint(cctx->mtctx);\n    }\n#endif\n    return ZSTD_nextInputSizeHint(cctx);\n\n}\n\nsize_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)\n{\n    FORWARD_IF_ERROR( ZSTD_compressStream2(zcs, output, input, ZSTD_e_continue) );\n    return ZSTD_nextInputSizeHint_MTorST(zcs);\n}\n\n\nsize_t ZSTD_compressStream2( ZSTD_CCtx* cctx,\n                             ZSTD_outBuffer* output,\n                             ZSTD_inBuffer* input,\n                             ZSTD_EndDirective endOp)\n{\n    DEBUGLOG(5, \"ZSTD_compressStream2, endOp=%u \", (unsigned)endOp);\n    /* check conditions */\n    RETURN_ERROR_IF(output->pos > output->size, GENERIC);\n    RETURN_ERROR_IF(input->pos  > input->size, GENERIC);\n    assert(cctx!=NULL);\n\n    /* transparent initialization stage */\n    if (cctx->streamStage == zcss_init) {\n        ZSTD_CCtx_params params = cctx->requestedParams;\n        ZSTD_prefixDict const prefixDict = cctx->prefixDict;\n        FORWARD_IF_ERROR( ZSTD_initLocalDict(cctx) ); /* Init the local dict if present. */\n        memset(&cctx->prefixDict, 0, sizeof(cctx->prefixDict));   /* single usage */\n        assert(prefixDict.dict==NULL || cctx->cdict==NULL);    /* only one can be set */\n        DEBUGLOG(4, \"ZSTD_compressStream2 : transparent init stage\");\n        if (endOp == ZSTD_e_end) cctx->pledgedSrcSizePlusOne = input->size + 1;  /* auto-fix pledgedSrcSize */\n        params.cParams = ZSTD_getCParamsFromCCtxParams(\n                &cctx->requestedParams, cctx->pledgedSrcSizePlusOne-1, 0 /*dictSize*/);\n\n\n#ifdef ZSTD_MULTITHREAD\n        if ((cctx->pledgedSrcSizePlusOne-1) <= ZSTDMT_JOBSIZE_MIN) {\n            params.nbWorkers = 0; /* do not invoke multi-threading when src size is too small */\n        }\n        if (params.nbWorkers > 0) {\n            /* mt context creation */\n            if (cctx->mtctx == NULL) {\n                DEBUGLOG(4, \"ZSTD_compressStream2: creating new mtctx for nbWorkers=%u\",\n                            params.nbWorkers);\n                cctx->mtctx = ZSTDMT_createCCtx_advanced((U32)params.nbWorkers, cctx->customMem);\n                RETURN_ERROR_IF(cctx->mtctx == NULL, memory_allocation);\n            }\n            /* mt compression */\n            DEBUGLOG(4, \"call ZSTDMT_initCStream_internal as nbWorkers=%u\", params.nbWorkers);\n            FORWARD_IF_ERROR( ZSTDMT_initCStream_internal(\n                        cctx->mtctx,\n                        prefixDict.dict, prefixDict.dictSize, ZSTD_dct_rawContent,\n                        cctx->cdict, params, cctx->pledgedSrcSizePlusOne-1) );\n            cctx->streamStage = zcss_load;\n            cctx->appliedParams.nbWorkers = params.nbWorkers;\n        } else\n#endif\n        {   FORWARD_IF_ERROR( ZSTD_resetCStream_internal(cctx,\n                            prefixDict.dict, prefixDict.dictSize, prefixDict.dictContentType,\n                            cctx->cdict,\n                            params, cctx->pledgedSrcSizePlusOne-1) );\n            assert(cctx->streamStage == zcss_load);\n            assert(cctx->appliedParams.nbWorkers == 0);\n    }   }\n    /* end of transparent initialization stage */\n\n    /* compression stage */\n#ifdef ZSTD_MULTITHREAD\n    if (cctx->appliedParams.nbWorkers > 0) {\n        int const forceMaxProgress = (endOp == ZSTD_e_flush || endOp == ZSTD_e_end);\n        size_t flushMin;\n        assert(forceMaxProgress || endOp == ZSTD_e_continue /* Protection for a new flush type */);\n        if (cctx->cParamsChanged) {\n            ZSTDMT_updateCParams_whileCompressing(cctx->mtctx, &cctx->requestedParams);\n            cctx->cParamsChanged = 0;\n        }\n        do {\n            flushMin = ZSTDMT_compressStream_generic(cctx->mtctx, output, input, endOp);\n            if ( ZSTD_isError(flushMin)\n              || (endOp == ZSTD_e_end && flushMin == 0) ) { /* compression completed */\n                ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);\n            }\n            FORWARD_IF_ERROR(flushMin);\n        } while (forceMaxProgress && flushMin != 0 && output->pos < output->size);\n        DEBUGLOG(5, \"completed ZSTD_compressStream2 delegating to ZSTDMT_compressStream_generic\");\n        /* Either we don't require maximum forward progress, we've finished the\n         * flush, or we are out of output space.\n         */\n        assert(!forceMaxProgress || flushMin == 0 || output->pos == output->size);\n        return flushMin;\n    }\n#endif\n    FORWARD_IF_ERROR( ZSTD_compressStream_generic(cctx, output, input, endOp) );\n    DEBUGLOG(5, \"completed ZSTD_compressStream2\");\n    return cctx->outBuffContentSize - cctx->outBuffFlushedSize; /* remaining to flush */\n}\n\nsize_t ZSTD_compressStream2_simpleArgs (\n                            ZSTD_CCtx* cctx,\n                            void* dst, size_t dstCapacity, size_t* dstPos,\n                      const void* src, size_t srcSize, size_t* srcPos,\n                            ZSTD_EndDirective endOp)\n{\n    ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };\n    ZSTD_inBuffer  input  = { src, srcSize, *srcPos };\n    /* ZSTD_compressStream2() will check validity of dstPos and srcPos */\n    size_t const cErr = ZSTD_compressStream2(cctx, &output, &input, endOp);\n    *dstPos = output.pos;\n    *srcPos = input.pos;\n    return cErr;\n}\n\nsize_t ZSTD_compress2(ZSTD_CCtx* cctx,\n                      void* dst, size_t dstCapacity,\n                      const void* src, size_t srcSize)\n{\n    ZSTD_CCtx_reset(cctx, ZSTD_reset_session_only);\n    {   size_t oPos = 0;\n        size_t iPos = 0;\n        size_t const result = ZSTD_compressStream2_simpleArgs(cctx,\n                                        dst, dstCapacity, &oPos,\n                                        src, srcSize, &iPos,\n                                        ZSTD_e_end);\n        FORWARD_IF_ERROR(result);\n        if (result != 0) {  /* compression not completed, due to lack of output space */\n            assert(oPos == dstCapacity);\n            RETURN_ERROR(dstSize_tooSmall);\n        }\n        assert(iPos == srcSize);   /* all input is expected consumed */\n        return oPos;\n    }\n}\n\n/*======   Finalize   ======*/\n\n/*! ZSTD_flushStream() :\n * @return : amount of data remaining to flush */\nsize_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)\n{\n    ZSTD_inBuffer input = { NULL, 0, 0 };\n    return ZSTD_compressStream2(zcs, output, &input, ZSTD_e_flush);\n}\n\n\nsize_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)\n{\n    ZSTD_inBuffer input = { NULL, 0, 0 };\n    size_t const remainingToFlush = ZSTD_compressStream2(zcs, output, &input, ZSTD_e_end);\n    FORWARD_IF_ERROR( remainingToFlush );\n    if (zcs->appliedParams.nbWorkers > 0) return remainingToFlush;   /* minimal estimation */\n    /* single thread mode : attempt to calculate remaining to flush more precisely */\n    {   size_t const lastBlockSize = zcs->frameEnded ? 0 : ZSTD_BLOCKHEADERSIZE;\n        size_t const checksumSize = (size_t)(zcs->frameEnded ? 0 : zcs->appliedParams.fParams.checksumFlag * 4);\n        size_t const toFlush = remainingToFlush + lastBlockSize + checksumSize;\n        DEBUGLOG(4, \"ZSTD_endStream : remaining to flush : %u\", (unsigned)toFlush);\n        return toFlush;\n    }\n}\n\n\n/*-=====  Pre-defined compression levels  =====-*/\n\n#define ZSTD_MAX_CLEVEL     22\nint ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }\nint ZSTD_minCLevel(void) { return (int)-ZSTD_TARGETLENGTH_MAX; }\n\nstatic const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {\n{   /* \"default\" - for any srcSize > 256 KB */\n    /* W,  C,  H,  S,  L, TL, strat */\n    { 19, 12, 13,  1,  6,  1, ZSTD_fast    },  /* base for negative levels */\n    { 19, 13, 14,  1,  7,  0, ZSTD_fast    },  /* level  1 */\n    { 20, 15, 16,  1,  6,  0, ZSTD_fast    },  /* level  2 */\n    { 21, 16, 17,  1,  5,  0, ZSTD_dfast   },  /* level  3 */\n    { 21, 18, 18,  1,  5,  0, ZSTD_dfast   },  /* level  4 */\n    { 21, 18, 19,  2,  5,  2, ZSTD_greedy  },  /* level  5 */\n    { 21, 19, 19,  3,  5,  4, ZSTD_greedy  },  /* level  6 */\n    { 21, 19, 19,  3,  5,  8, ZSTD_lazy    },  /* level  7 */\n    { 21, 19, 19,  3,  5, 16, ZSTD_lazy2   },  /* level  8 */\n    { 21, 19, 20,  4,  5, 16, ZSTD_lazy2   },  /* level  9 */\n    { 22, 20, 21,  4,  5, 16, ZSTD_lazy2   },  /* level 10 */\n    { 22, 21, 22,  4,  5, 16, ZSTD_lazy2   },  /* level 11 */\n    { 22, 21, 22,  5,  5, 16, ZSTD_lazy2   },  /* level 12 */\n    { 22, 21, 22,  5,  5, 32, ZSTD_btlazy2 },  /* level 13 */\n    { 22, 22, 23,  5,  5, 32, ZSTD_btlazy2 },  /* level 14 */\n    { 22, 23, 23,  6,  5, 32, ZSTD_btlazy2 },  /* level 15 */\n    { 22, 22, 22,  5,  5, 48, ZSTD_btopt   },  /* level 16 */\n    { 23, 23, 22,  5,  4, 64, ZSTD_btopt   },  /* level 17 */\n    { 23, 23, 22,  6,  3, 64, ZSTD_btultra },  /* level 18 */\n    { 23, 24, 22,  7,  3,256, ZSTD_btultra2},  /* level 19 */\n    { 25, 25, 23,  7,  3,256, ZSTD_btultra2},  /* level 20 */\n    { 26, 26, 24,  7,  3,512, ZSTD_btultra2},  /* level 21 */\n    { 27, 27, 25,  9,  3,999, ZSTD_btultra2},  /* level 22 */\n},\n{   /* for srcSize <= 256 KB */\n    /* W,  C,  H,  S,  L,  T, strat */\n    { 18, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */\n    { 18, 13, 14,  1,  6,  0, ZSTD_fast    },  /* level  1 */\n    { 18, 14, 14,  1,  5,  0, ZSTD_dfast   },  /* level  2 */\n    { 18, 16, 16,  1,  4,  0, ZSTD_dfast   },  /* level  3 */\n    { 18, 16, 17,  2,  5,  2, ZSTD_greedy  },  /* level  4.*/\n    { 18, 18, 18,  3,  5,  2, ZSTD_greedy  },  /* level  5.*/\n    { 18, 18, 19,  3,  5,  4, ZSTD_lazy    },  /* level  6.*/\n    { 18, 18, 19,  4,  4,  4, ZSTD_lazy    },  /* level  7 */\n    { 18, 18, 19,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */\n    { 18, 18, 19,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */\n    { 18, 18, 19,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */\n    { 18, 18, 19,  5,  4, 12, ZSTD_btlazy2 },  /* level 11.*/\n    { 18, 19, 19,  7,  4, 12, ZSTD_btlazy2 },  /* level 12.*/\n    { 18, 18, 19,  4,  4, 16, ZSTD_btopt   },  /* level 13 */\n    { 18, 18, 19,  4,  3, 32, ZSTD_btopt   },  /* level 14.*/\n    { 18, 18, 19,  6,  3,128, ZSTD_btopt   },  /* level 15.*/\n    { 18, 19, 19,  6,  3,128, ZSTD_btultra },  /* level 16.*/\n    { 18, 19, 19,  8,  3,256, ZSTD_btultra },  /* level 17.*/\n    { 18, 19, 19,  6,  3,128, ZSTD_btultra2},  /* level 18.*/\n    { 18, 19, 19,  8,  3,256, ZSTD_btultra2},  /* level 19.*/\n    { 18, 19, 19, 10,  3,512, ZSTD_btultra2},  /* level 20.*/\n    { 18, 19, 19, 12,  3,512, ZSTD_btultra2},  /* level 21.*/\n    { 18, 19, 19, 13,  3,999, ZSTD_btultra2},  /* level 22.*/\n},\n{   /* for srcSize <= 128 KB */\n    /* W,  C,  H,  S,  L,  T, strat */\n    { 17, 12, 12,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */\n    { 17, 12, 13,  1,  6,  0, ZSTD_fast    },  /* level  1 */\n    { 17, 13, 15,  1,  5,  0, ZSTD_fast    },  /* level  2 */\n    { 17, 15, 16,  2,  5,  0, ZSTD_dfast   },  /* level  3 */\n    { 17, 17, 17,  2,  4,  0, ZSTD_dfast   },  /* level  4 */\n    { 17, 16, 17,  3,  4,  2, ZSTD_greedy  },  /* level  5 */\n    { 17, 17, 17,  3,  4,  4, ZSTD_lazy    },  /* level  6 */\n    { 17, 17, 17,  3,  4,  8, ZSTD_lazy2   },  /* level  7 */\n    { 17, 17, 17,  4,  4,  8, ZSTD_lazy2   },  /* level  8 */\n    { 17, 17, 17,  5,  4,  8, ZSTD_lazy2   },  /* level  9 */\n    { 17, 17, 17,  6,  4,  8, ZSTD_lazy2   },  /* level 10 */\n    { 17, 17, 17,  5,  4,  8, ZSTD_btlazy2 },  /* level 11 */\n    { 17, 18, 17,  7,  4, 12, ZSTD_btlazy2 },  /* level 12 */\n    { 17, 18, 17,  3,  4, 12, ZSTD_btopt   },  /* level 13.*/\n    { 17, 18, 17,  4,  3, 32, ZSTD_btopt   },  /* level 14.*/\n    { 17, 18, 17,  6,  3,256, ZSTD_btopt   },  /* level 15.*/\n    { 17, 18, 17,  6,  3,128, ZSTD_btultra },  /* level 16.*/\n    { 17, 18, 17,  8,  3,256, ZSTD_btultra },  /* level 17.*/\n    { 17, 18, 17, 10,  3,512, ZSTD_btultra },  /* level 18.*/\n    { 17, 18, 17,  5,  3,256, ZSTD_btultra2},  /* level 19.*/\n    { 17, 18, 17,  7,  3,512, ZSTD_btultra2},  /* level 20.*/\n    { 17, 18, 17,  9,  3,512, ZSTD_btultra2},  /* level 21.*/\n    { 17, 18, 17, 11,  3,999, ZSTD_btultra2},  /* level 22.*/\n},\n{   /* for srcSize <= 16 KB */\n    /* W,  C,  H,  S,  L,  T, strat */\n    { 14, 12, 13,  1,  5,  1, ZSTD_fast    },  /* base for negative levels */\n    { 14, 14, 15,  1,  5,  0, ZSTD_fast    },  /* level  1 */\n    { 14, 14, 15,  1,  4,  0, ZSTD_fast    },  /* level  2 */\n    { 14, 14, 15,  2,  4,  0, ZSTD_dfast   },  /* level  3 */\n    { 14, 14, 14,  4,  4,  2, ZSTD_greedy  },  /* level  4 */\n    { 14, 14, 14,  3,  4,  4, ZSTD_lazy    },  /* level  5.*/\n    { 14, 14, 14,  4,  4,  8, ZSTD_lazy2   },  /* level  6 */\n    { 14, 14, 14,  6,  4,  8, ZSTD_lazy2   },  /* level  7 */\n    { 14, 14, 14,  8,  4,  8, ZSTD_lazy2   },  /* level  8.*/\n    { 14, 15, 14,  5,  4,  8, ZSTD_btlazy2 },  /* level  9.*/\n    { 14, 15, 14,  9,  4,  8, ZSTD_btlazy2 },  /* level 10.*/\n    { 14, 15, 14,  3,  4, 12, ZSTD_btopt   },  /* level 11.*/\n    { 14, 15, 14,  4,  3, 24, ZSTD_btopt   },  /* level 12.*/\n    { 14, 15, 14,  5,  3, 32, ZSTD_btultra },  /* level 13.*/\n    { 14, 15, 15,  6,  3, 64, ZSTD_btultra },  /* level 14.*/\n    { 14, 15, 15,  7,  3,256, ZSTD_btultra },  /* level 15.*/\n    { 14, 15, 15,  5,  3, 48, ZSTD_btultra2},  /* level 16.*/\n    { 14, 15, 15,  6,  3,128, ZSTD_btultra2},  /* level 17.*/\n    { 14, 15, 15,  7,  3,256, ZSTD_btultra2},  /* level 18.*/\n    { 14, 15, 15,  8,  3,256, ZSTD_btultra2},  /* level 19.*/\n    { 14, 15, 15,  8,  3,512, ZSTD_btultra2},  /* level 20.*/\n    { 14, 15, 15,  9,  3,512, ZSTD_btultra2},  /* level 21.*/\n    { 14, 15, 15, 10,  3,999, ZSTD_btultra2},  /* level 22.*/\n},\n};\n\n/*! ZSTD_getCParams() :\n * @return ZSTD_compressionParameters structure for a selected compression level, srcSize and dictSize.\n *  Size values are optional, provide 0 if not known or unused */\nZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize)\n{\n    size_t const addedSize = srcSizeHint ? 0 : 500;\n    U64 const rSize = srcSizeHint+dictSize ? srcSizeHint+dictSize+addedSize : ZSTD_CONTENTSIZE_UNKNOWN;  /* intentional overflow for srcSizeHint == ZSTD_CONTENTSIZE_UNKNOWN */\n    U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB);\n    int row = compressionLevel;\n    DEBUGLOG(5, \"ZSTD_getCParams (cLevel=%i)\", compressionLevel);\n    if (compressionLevel == 0) row = ZSTD_CLEVEL_DEFAULT;   /* 0 == default */\n    if (compressionLevel < 0) row = 0;   /* entry 0 is baseline for fast mode */\n    if (compressionLevel > ZSTD_MAX_CLEVEL) row = ZSTD_MAX_CLEVEL;\n    {   ZSTD_compressionParameters cp = ZSTD_defaultCParameters[tableID][row];\n        if (compressionLevel < 0) cp.targetLength = (unsigned)(-compressionLevel);   /* acceleration factor */\n        return ZSTD_adjustCParams_internal(cp, srcSizeHint, dictSize);               /* refine parameters based on srcSize & dictSize */\n    }\n}\n\n/*! ZSTD_getParams() :\n *  same idea as ZSTD_getCParams()\n * @return a `ZSTD_parameters` structure (instead of `ZSTD_compressionParameters`).\n *  Fields of `ZSTD_frameParameters` are set to default values */\nZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSizeHint, size_t dictSize) {\n    ZSTD_parameters params;\n    ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSizeHint, dictSize);\n    DEBUGLOG(5, \"ZSTD_getParams (cLevel=%i)\", compressionLevel);\n    memset(&params, 0, sizeof(params));\n    params.cParams = cParams;\n    params.fParams.contentSizeFlag = 1;\n    return params;\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_compress_internal.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n/* This header contains definitions\n * that shall **only** be used by modules within lib/compress.\n */\n\n#ifndef ZSTD_COMPRESS_H\n#define ZSTD_COMPRESS_H\n\n/*-*************************************\n*  Dependencies\n***************************************/\n#include \"zstd_internal.h\"\n#include \"zstd_cwksp.h\"\n#ifdef ZSTD_MULTITHREAD\n#  include \"zstdmt_compress.h\"\n#endif\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n\n/*-*************************************\n*  Constants\n***************************************/\n#define kSearchStrength      8\n#define HASH_READ_SIZE       8\n#define ZSTD_DUBT_UNSORTED_MARK 1   /* For btlazy2 strategy, index ZSTD_DUBT_UNSORTED_MARK==1 means \"unsorted\".\n                                       It could be confused for a real successor at index \"1\", if sorted as larger than its predecessor.\n                                       It's not a big deal though : candidate will just be sorted again.\n                                       Additionally, candidate position 1 will be lost.\n                                       But candidate 1 cannot hide a large tree of candidates, so it's a minimal loss.\n                                       The benefit is that ZSTD_DUBT_UNSORTED_MARK cannot be mishandled after table re-use with a different strategy.\n                                       This constant is required by ZSTD_compressBlock_btlazy2() and ZSTD_reduceTable_internal() */\n\n\n/*-*************************************\n*  Context memory management\n***************************************/\ntypedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;\ntypedef enum { zcss_init=0, zcss_load, zcss_flush } ZSTD_cStreamStage;\n\ntypedef struct ZSTD_prefixDict_s {\n    const void* dict;\n    size_t dictSize;\n    ZSTD_dictContentType_e dictContentType;\n} ZSTD_prefixDict;\n\ntypedef struct {\n    void* dictBuffer;\n    void const* dict;\n    size_t dictSize;\n    ZSTD_dictContentType_e dictContentType;\n    ZSTD_CDict* cdict;\n} ZSTD_localDict;\n\ntypedef struct {\n    U32 CTable[HUF_CTABLE_SIZE_U32(255)];\n    HUF_repeat repeatMode;\n} ZSTD_hufCTables_t;\n\ntypedef struct {\n    FSE_CTable offcodeCTable[FSE_CTABLE_SIZE_U32(OffFSELog, MaxOff)];\n    FSE_CTable matchlengthCTable[FSE_CTABLE_SIZE_U32(MLFSELog, MaxML)];\n    FSE_CTable litlengthCTable[FSE_CTABLE_SIZE_U32(LLFSELog, MaxLL)];\n    FSE_repeat offcode_repeatMode;\n    FSE_repeat matchlength_repeatMode;\n    FSE_repeat litlength_repeatMode;\n} ZSTD_fseCTables_t;\n\ntypedef struct {\n    ZSTD_hufCTables_t huf;\n    ZSTD_fseCTables_t fse;\n} ZSTD_entropyCTables_t;\n\ntypedef struct {\n    U32 off;\n    U32 len;\n} ZSTD_match_t;\n\ntypedef struct {\n    int price;\n    U32 off;\n    U32 mlen;\n    U32 litlen;\n    U32 rep[ZSTD_REP_NUM];\n} ZSTD_optimal_t;\n\ntypedef enum { zop_dynamic=0, zop_predef } ZSTD_OptPrice_e;\n\ntypedef struct {\n    /* All tables are allocated inside cctx->workspace by ZSTD_resetCCtx_internal() */\n    unsigned* litFreq;           /* table of literals statistics, of size 256 */\n    unsigned* litLengthFreq;     /* table of litLength statistics, of size (MaxLL+1) */\n    unsigned* matchLengthFreq;   /* table of matchLength statistics, of size (MaxML+1) */\n    unsigned* offCodeFreq;       /* table of offCode statistics, of size (MaxOff+1) */\n    ZSTD_match_t* matchTable;    /* list of found matches, of size ZSTD_OPT_NUM+1 */\n    ZSTD_optimal_t* priceTable;  /* All positions tracked by optimal parser, of size ZSTD_OPT_NUM+1 */\n\n    U32  litSum;                 /* nb of literals */\n    U32  litLengthSum;           /* nb of litLength codes */\n    U32  matchLengthSum;         /* nb of matchLength codes */\n    U32  offCodeSum;             /* nb of offset codes */\n    U32  litSumBasePrice;        /* to compare to log2(litfreq) */\n    U32  litLengthSumBasePrice;  /* to compare to log2(llfreq)  */\n    U32  matchLengthSumBasePrice;/* to compare to log2(mlfreq)  */\n    U32  offCodeSumBasePrice;    /* to compare to log2(offreq)  */\n    ZSTD_OptPrice_e priceType;   /* prices can be determined dynamically, or follow a pre-defined cost structure */\n    const ZSTD_entropyCTables_t* symbolCosts;  /* pre-calculated dictionary statistics */\n    ZSTD_literalCompressionMode_e literalCompressionMode;\n} optState_t;\n\ntypedef struct {\n  ZSTD_entropyCTables_t entropy;\n  U32 rep[ZSTD_REP_NUM];\n} ZSTD_compressedBlockState_t;\n\ntypedef struct {\n    BYTE const* nextSrc;    /* next block here to continue on current prefix */\n    BYTE const* base;       /* All regular indexes relative to this position */\n    BYTE const* dictBase;   /* extDict indexes relative to this position */\n    U32 dictLimit;          /* below that point, need extDict */\n    U32 lowLimit;           /* below that point, no more valid data */\n} ZSTD_window_t;\n\ntypedef struct ZSTD_matchState_t ZSTD_matchState_t;\nstruct ZSTD_matchState_t {\n    ZSTD_window_t window;   /* State for window round buffer management */\n    U32 loadedDictEnd;      /* index of end of dictionary, within context's referential.\n                             * When loadedDictEnd != 0, a dictionary is in use, and still valid.\n                             * This relies on a mechanism to set loadedDictEnd=0 when dictionary is no longer within distance.\n                             * Such mechanism is provided within ZSTD_window_enforceMaxDist() and ZSTD_checkDictValidity().\n                             * When dict referential is copied into active context (i.e. not attached),\n                             * loadedDictEnd == dictSize, since referential starts from zero.\n                             */\n    U32 nextToUpdate;       /* index from which to continue table update */\n    U32 hashLog3;           /* dispatch table for matches of len==3 : larger == faster, more memory */\n    U32* hashTable;\n    U32* hashTable3;\n    U32* chainTable;\n    optState_t opt;         /* optimal parser state */\n    const ZSTD_matchState_t* dictMatchState;\n    ZSTD_compressionParameters cParams;\n};\n\ntypedef struct {\n    ZSTD_compressedBlockState_t* prevCBlock;\n    ZSTD_compressedBlockState_t* nextCBlock;\n    ZSTD_matchState_t matchState;\n} ZSTD_blockState_t;\n\ntypedef struct {\n    U32 offset;\n    U32 checksum;\n} ldmEntry_t;\n\ntypedef struct {\n    ZSTD_window_t window;   /* State for the window round buffer management */\n    ldmEntry_t* hashTable;\n    BYTE* bucketOffsets;    /* Next position in bucket to insert entry */\n    U64 hashPower;          /* Used to compute the rolling hash.\n                             * Depends on ldmParams.minMatchLength */\n} ldmState_t;\n\ntypedef struct {\n    U32 enableLdm;          /* 1 if enable long distance matching */\n    U32 hashLog;            /* Log size of hashTable */\n    U32 bucketSizeLog;      /* Log bucket size for collision resolution, at most 8 */\n    U32 minMatchLength;     /* Minimum match length */\n    U32 hashRateLog;       /* Log number of entries to skip */\n    U32 windowLog;          /* Window log for the LDM */\n} ldmParams_t;\n\ntypedef struct {\n    U32 offset;\n    U32 litLength;\n    U32 matchLength;\n} rawSeq;\n\ntypedef struct {\n  rawSeq* seq;     /* The start of the sequences */\n  size_t pos;      /* The position where reading stopped. <= size. */\n  size_t size;     /* The number of sequences. <= capacity. */\n  size_t capacity; /* The capacity starting from `seq` pointer */\n} rawSeqStore_t;\n\ntypedef struct {\n    int collectSequences;\n    ZSTD_Sequence* seqStart;\n    size_t seqIndex;\n    size_t maxSequences;\n} SeqCollector;\n\nstruct ZSTD_CCtx_params_s {\n    ZSTD_format_e format;\n    ZSTD_compressionParameters cParams;\n    ZSTD_frameParameters fParams;\n\n    int compressionLevel;\n    int forceWindow;           /* force back-references to respect limit of\n                                * 1<<wLog, even for dictionary */\n    size_t targetCBlockSize;   /* Tries to fit compressed block size to be around targetCBlockSize.\n                                * No target when targetCBlockSize == 0.\n                                * There is no guarantee on compressed block size */\n    int srcSizeHint;           /* User's best guess of source size.\n                                * Hint is not valid when srcSizeHint == 0.\n                                * There is no guarantee that hint is close to actual source size */\n\n    ZSTD_dictAttachPref_e attachDictPref;\n    ZSTD_literalCompressionMode_e literalCompressionMode;\n\n    /* Multithreading: used to pass parameters to mtctx */\n    int nbWorkers;\n    size_t jobSize;\n    int overlapLog;\n    int rsyncable;\n\n    /* Long distance matching parameters */\n    ldmParams_t ldmParams;\n\n    /* Internal use, for createCCtxParams() and freeCCtxParams() only */\n    ZSTD_customMem customMem;\n};  /* typedef'd to ZSTD_CCtx_params within \"zstd.h\" */\n\nstruct ZSTD_CCtx_s {\n    ZSTD_compressionStage_e stage;\n    int cParamsChanged;                  /* == 1 if cParams(except wlog) or compression level are changed in requestedParams. Triggers transmission of new params to ZSTDMT (if available) then reset to 0. */\n    int bmi2;                            /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */\n    ZSTD_CCtx_params requestedParams;\n    ZSTD_CCtx_params appliedParams;\n    U32   dictID;\n\n    ZSTD_cwksp workspace; /* manages buffer for dynamic allocations */\n    size_t blockSize;\n    unsigned long long pledgedSrcSizePlusOne;  /* this way, 0 (default) == unknown */\n    unsigned long long consumedSrcSize;\n    unsigned long long producedCSize;\n    XXH64_state_t xxhState;\n    ZSTD_customMem customMem;\n    size_t staticSize;\n    SeqCollector seqCollector;\n    int isFirstBlock;\n\n    seqStore_t seqStore;      /* sequences storage ptrs */\n    ldmState_t ldmState;      /* long distance matching state */\n    rawSeq* ldmSequences;     /* Storage for the ldm output sequences */\n    size_t maxNbLdmSequences;\n    rawSeqStore_t externSeqStore; /* Mutable reference to external sequences */\n    ZSTD_blockState_t blockState;\n    U32* entropyWorkspace;  /* entropy workspace of HUF_WORKSPACE_SIZE bytes */\n\n    /* streaming */\n    char*  inBuff;\n    size_t inBuffSize;\n    size_t inToCompress;\n    size_t inBuffPos;\n    size_t inBuffTarget;\n    char*  outBuff;\n    size_t outBuffSize;\n    size_t outBuffContentSize;\n    size_t outBuffFlushedSize;\n    ZSTD_cStreamStage streamStage;\n    U32    frameEnded;\n\n    /* Dictionary */\n    ZSTD_localDict localDict;\n    const ZSTD_CDict* cdict;\n    ZSTD_prefixDict prefixDict;   /* single-usage dictionary */\n\n    /* Multi-threading */\n#ifdef ZSTD_MULTITHREAD\n    ZSTDMT_CCtx* mtctx;\n#endif\n};\n\ntypedef enum { ZSTD_dtlm_fast, ZSTD_dtlm_full } ZSTD_dictTableLoadMethod_e;\n\ntypedef enum { ZSTD_noDict = 0, ZSTD_extDict = 1, ZSTD_dictMatchState = 2 } ZSTD_dictMode_e;\n\n\ntypedef size_t (*ZSTD_blockCompressor) (\n        ZSTD_matchState_t* bs, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, ZSTD_dictMode_e dictMode);\n\n\nMEM_STATIC U32 ZSTD_LLcode(U32 litLength)\n{\n    static const BYTE LL_Code[64] = {  0,  1,  2,  3,  4,  5,  6,  7,\n                                       8,  9, 10, 11, 12, 13, 14, 15,\n                                      16, 16, 17, 17, 18, 18, 19, 19,\n                                      20, 20, 20, 20, 21, 21, 21, 21,\n                                      22, 22, 22, 22, 22, 22, 22, 22,\n                                      23, 23, 23, 23, 23, 23, 23, 23,\n                                      24, 24, 24, 24, 24, 24, 24, 24,\n                                      24, 24, 24, 24, 24, 24, 24, 24 };\n    static const U32 LL_deltaCode = 19;\n    return (litLength > 63) ? ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];\n}\n\n/* ZSTD_MLcode() :\n * note : mlBase = matchLength - MINMATCH;\n *        because it's the format it's stored in seqStore->sequences */\nMEM_STATIC U32 ZSTD_MLcode(U32 mlBase)\n{\n    static const BYTE ML_Code[128] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,\n                                      16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n                                      32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,\n                                      38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,\n                                      40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n                                      41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,\n                                      42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,\n                                      42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };\n    static const U32 ML_deltaCode = 36;\n    return (mlBase > 127) ? ZSTD_highbit32(mlBase) + ML_deltaCode : ML_Code[mlBase];\n}\n\n/* ZSTD_cParam_withinBounds:\n * @return 1 if value is within cParam bounds,\n * 0 otherwise */\nMEM_STATIC int ZSTD_cParam_withinBounds(ZSTD_cParameter cParam, int value)\n{\n    ZSTD_bounds const bounds = ZSTD_cParam_getBounds(cParam);\n    if (ZSTD_isError(bounds.error)) return 0;\n    if (value < bounds.lowerBound) return 0;\n    if (value > bounds.upperBound) return 0;\n    return 1;\n}\n\n/* ZSTD_minGain() :\n * minimum compression required\n * to generate a compress block or a compressed literals section.\n * note : use same formula for both situations */\nMEM_STATIC size_t ZSTD_minGain(size_t srcSize, ZSTD_strategy strat)\n{\n    U32 const minlog = (strat>=ZSTD_btultra) ? (U32)(strat) - 1 : 6;\n    ZSTD_STATIC_ASSERT(ZSTD_btultra == 8);\n    assert(ZSTD_cParam_withinBounds(ZSTD_c_strategy, strat));\n    return (srcSize >> minlog) + 2;\n}\n\n/*! ZSTD_safecopyLiterals() :\n *  memcpy() function that won't read beyond more than WILDCOPY_OVERLENGTH bytes past ilimit_w.\n *  Only called when the sequence ends past ilimit_w, so it only needs to be optimized for single\n *  large copies.\n */\nstatic void ZSTD_safecopyLiterals(BYTE* op, BYTE const* ip, BYTE const* const iend, BYTE const* ilimit_w) {\n    assert(iend > ilimit_w);\n    if (ip <= ilimit_w) {\n        ZSTD_wildcopy(op, ip, ilimit_w - ip, ZSTD_no_overlap);\n        op += ilimit_w - ip;\n        ip = ilimit_w;\n    }\n    while (ip < iend) *op++ = *ip++;\n}\n\n/*! ZSTD_storeSeq() :\n *  Store a sequence (litlen, litPtr, offCode and mlBase) into seqStore_t.\n *  `offCode` : distance to match + ZSTD_REP_MOVE (values <= ZSTD_REP_MOVE are repCodes).\n *  `mlBase` : matchLength - MINMATCH\n *  Allowed to overread literals up to litLimit.\n*/\nHINT_INLINE UNUSED_ATTR\nvoid ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const BYTE* literals, const BYTE* litLimit, U32 offCode, size_t mlBase)\n{\n    BYTE const* const litLimit_w = litLimit - WILDCOPY_OVERLENGTH;\n    BYTE const* const litEnd = literals + litLength;\n#if defined(DEBUGLEVEL) && (DEBUGLEVEL >= 6)\n    static const BYTE* g_start = NULL;\n    if (g_start==NULL) g_start = (const BYTE*)literals;  /* note : index only works for compression within a single segment */\n    {   U32 const pos = (U32)((const BYTE*)literals - g_start);\n        DEBUGLOG(6, \"Cpos%7u :%3u literals, match%4u bytes at offCode%7u\",\n               pos, (U32)litLength, (U32)mlBase+MINMATCH, (U32)offCode);\n    }\n#endif\n    assert((size_t)(seqStorePtr->sequences - seqStorePtr->sequencesStart) < seqStorePtr->maxNbSeq);\n    /* copy Literals */\n    assert(seqStorePtr->maxNbLit <= 128 KB);\n    assert(seqStorePtr->lit + litLength <= seqStorePtr->litStart + seqStorePtr->maxNbLit);\n    assert(literals + litLength <= litLimit);\n    if (litEnd <= litLimit_w) {\n        /* Common case we can use wildcopy.\n\t * First copy 16 bytes, because literals are likely short.\n\t */\n        assert(WILDCOPY_OVERLENGTH >= 16);\n        ZSTD_copy16(seqStorePtr->lit, literals);\n        if (litLength > 16) {\n            ZSTD_wildcopy(seqStorePtr->lit+16, literals+16, (ptrdiff_t)litLength-16, ZSTD_no_overlap);\n        }\n    } else {\n        ZSTD_safecopyLiterals(seqStorePtr->lit, literals, litEnd, litLimit_w);\n    }\n    seqStorePtr->lit += litLength;\n\n    /* literal Length */\n    if (litLength>0xFFFF) {\n        assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */\n        seqStorePtr->longLengthID = 1;\n        seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);\n    }\n    seqStorePtr->sequences[0].litLength = (U16)litLength;\n\n    /* match offset */\n    seqStorePtr->sequences[0].offset = offCode + 1;\n\n    /* match Length */\n    if (mlBase>0xFFFF) {\n        assert(seqStorePtr->longLengthID == 0); /* there can only be a single long length */\n        seqStorePtr->longLengthID = 2;\n        seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);\n    }\n    seqStorePtr->sequences[0].matchLength = (U16)mlBase;\n\n    seqStorePtr->sequences++;\n}\n\n\n/*-*************************************\n*  Match length counter\n***************************************/\nstatic unsigned ZSTD_NbCommonBytes (size_t val)\n{\n    if (MEM_isLittleEndian()) {\n        if (MEM_64bits()) {\n#       if defined(_MSC_VER) && defined(_WIN64)\n            unsigned long r = 0;\n            _BitScanForward64( &r, (U64)val );\n            return (unsigned)(r>>3);\n#       elif defined(__GNUC__) && (__GNUC__ >= 4)\n            return (__builtin_ctzll((U64)val) >> 3);\n#       else\n            static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,\n                                                     0, 3, 1, 3, 1, 4, 2, 7,\n                                                     0, 2, 3, 6, 1, 5, 3, 5,\n                                                     1, 3, 4, 4, 2, 5, 6, 7,\n                                                     7, 0, 1, 2, 3, 3, 4, 6,\n                                                     2, 6, 5, 5, 3, 4, 5, 6,\n                                                     7, 1, 2, 4, 6, 4, 4, 5,\n                                                     7, 2, 6, 5, 7, 6, 7, 7 };\n            return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];\n#       endif\n        } else { /* 32 bits */\n#       if defined(_MSC_VER)\n            unsigned long r=0;\n            _BitScanForward( &r, (U32)val );\n            return (unsigned)(r>>3);\n#       elif defined(__GNUC__) && (__GNUC__ >= 3)\n            return (__builtin_ctz((U32)val) >> 3);\n#       else\n            static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,\n                                                     3, 2, 2, 1, 3, 2, 0, 1,\n                                                     3, 3, 1, 2, 2, 2, 2, 0,\n                                                     3, 1, 2, 0, 1, 0, 1, 1 };\n            return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];\n#       endif\n        }\n    } else {  /* Big Endian CPU */\n        if (MEM_64bits()) {\n#       if defined(_MSC_VER) && defined(_WIN64)\n            unsigned long r = 0;\n            _BitScanReverse64( &r, val );\n            return (unsigned)(r>>3);\n#       elif defined(__GNUC__) && (__GNUC__ >= 4)\n            return (__builtin_clzll(val) >> 3);\n#       else\n            unsigned r;\n            const unsigned n32 = sizeof(size_t)*4;   /* calculate this way due to compiler complaining in 32-bits mode */\n            if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }\n            if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }\n            r += (!val);\n            return r;\n#       endif\n        } else { /* 32 bits */\n#       if defined(_MSC_VER)\n            unsigned long r = 0;\n            _BitScanReverse( &r, (unsigned long)val );\n            return (unsigned)(r>>3);\n#       elif defined(__GNUC__) && (__GNUC__ >= 3)\n            return (__builtin_clz((U32)val) >> 3);\n#       else\n            unsigned r;\n            if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }\n            r += (!val);\n            return r;\n#       endif\n    }   }\n}\n\n\nMEM_STATIC size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)\n{\n    const BYTE* const pStart = pIn;\n    const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);\n\n    if (pIn < pInLoopLimit) {\n        { size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);\n          if (diff) return ZSTD_NbCommonBytes(diff); }\n        pIn+=sizeof(size_t); pMatch+=sizeof(size_t);\n        while (pIn < pInLoopLimit) {\n            size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);\n            if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }\n            pIn += ZSTD_NbCommonBytes(diff);\n            return (size_t)(pIn - pStart);\n    }   }\n    if (MEM_64bits() && (pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }\n    if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }\n    if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;\n    return (size_t)(pIn - pStart);\n}\n\n/** ZSTD_count_2segments() :\n *  can count match length with `ip` & `match` in 2 different segments.\n *  convention : on reaching mEnd, match count continue starting from iStart\n */\nMEM_STATIC size_t\nZSTD_count_2segments(const BYTE* ip, const BYTE* match,\n                     const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)\n{\n    const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd);\n    size_t const matchLength = ZSTD_count(ip, match, vEnd);\n    if (match + matchLength != mEnd) return matchLength;\n    DEBUGLOG(7, \"ZSTD_count_2segments: found a 2-parts match (current length==%zu)\", matchLength);\n    DEBUGLOG(7, \"distance from match beginning to end dictionary = %zi\", mEnd - match);\n    DEBUGLOG(7, \"distance from current pos to end buffer = %zi\", iEnd - ip);\n    DEBUGLOG(7, \"next byte : ip==%02X, istart==%02X\", ip[matchLength], *iStart);\n    DEBUGLOG(7, \"final match length = %zu\", matchLength + ZSTD_count(ip+matchLength, iStart, iEnd));\n    return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd);\n}\n\n\n/*-*************************************\n *  Hashes\n ***************************************/\nstatic const U32 prime3bytes = 506832829U;\nstatic U32    ZSTD_hash3(U32 u, U32 h) { return ((u << (32-24)) * prime3bytes)  >> (32-h) ; }\nMEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */\n\nstatic const U32 prime4bytes = 2654435761U;\nstatic U32    ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }\nstatic size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }\n\nstatic const U64 prime5bytes = 889523592379ULL;\nstatic size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u  << (64-40)) * prime5bytes) >> (64-h)) ; }\nstatic size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }\n\nstatic const U64 prime6bytes = 227718039650203ULL;\nstatic size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u  << (64-48)) * prime6bytes) >> (64-h)) ; }\nstatic size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }\n\nstatic const U64 prime7bytes = 58295818150454627ULL;\nstatic size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u  << (64-56)) * prime7bytes) >> (64-h)) ; }\nstatic size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }\n\nstatic const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;\nstatic size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }\nstatic size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }\n\nMEM_STATIC size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)\n{\n    switch(mls)\n    {\n    default:\n    case 4: return ZSTD_hash4Ptr(p, hBits);\n    case 5: return ZSTD_hash5Ptr(p, hBits);\n    case 6: return ZSTD_hash6Ptr(p, hBits);\n    case 7: return ZSTD_hash7Ptr(p, hBits);\n    case 8: return ZSTD_hash8Ptr(p, hBits);\n    }\n}\n\n/** ZSTD_ipow() :\n * Return base^exponent.\n */\nstatic U64 ZSTD_ipow(U64 base, U64 exponent)\n{\n    U64 power = 1;\n    while (exponent) {\n      if (exponent & 1) power *= base;\n      exponent >>= 1;\n      base *= base;\n    }\n    return power;\n}\n\n#define ZSTD_ROLL_HASH_CHAR_OFFSET 10\n\n/** ZSTD_rollingHash_append() :\n * Add the buffer to the hash value.\n */\nstatic U64 ZSTD_rollingHash_append(U64 hash, void const* buf, size_t size)\n{\n    BYTE const* istart = (BYTE const*)buf;\n    size_t pos;\n    for (pos = 0; pos < size; ++pos) {\n        hash *= prime8bytes;\n        hash += istart[pos] + ZSTD_ROLL_HASH_CHAR_OFFSET;\n    }\n    return hash;\n}\n\n/** ZSTD_rollingHash_compute() :\n * Compute the rolling hash value of the buffer.\n */\nMEM_STATIC U64 ZSTD_rollingHash_compute(void const* buf, size_t size)\n{\n    return ZSTD_rollingHash_append(0, buf, size);\n}\n\n/** ZSTD_rollingHash_primePower() :\n * Compute the primePower to be passed to ZSTD_rollingHash_rotate() for a hash\n * over a window of length bytes.\n */\nMEM_STATIC U64 ZSTD_rollingHash_primePower(U32 length)\n{\n    return ZSTD_ipow(prime8bytes, length - 1);\n}\n\n/** ZSTD_rollingHash_rotate() :\n * Rotate the rolling hash by one byte.\n */\nMEM_STATIC U64 ZSTD_rollingHash_rotate(U64 hash, BYTE toRemove, BYTE toAdd, U64 primePower)\n{\n    hash -= (toRemove + ZSTD_ROLL_HASH_CHAR_OFFSET) * primePower;\n    hash *= prime8bytes;\n    hash += toAdd + ZSTD_ROLL_HASH_CHAR_OFFSET;\n    return hash;\n}\n\n/*-*************************************\n*  Round buffer management\n***************************************/\n#if (ZSTD_WINDOWLOG_MAX_64 > 31)\n# error \"ZSTD_WINDOWLOG_MAX is too large : would overflow ZSTD_CURRENT_MAX\"\n#endif\n/* Max current allowed */\n#define ZSTD_CURRENT_MAX ((3U << 29) + (1U << ZSTD_WINDOWLOG_MAX))\n/* Maximum chunk size before overflow correction needs to be called again */\n#define ZSTD_CHUNKSIZE_MAX                                                     \\\n    ( ((U32)-1)                  /* Maximum ending current index */            \\\n    - ZSTD_CURRENT_MAX)          /* Maximum beginning lowLimit */\n\n/**\n * ZSTD_window_clear():\n * Clears the window containing the history by simply setting it to empty.\n */\nMEM_STATIC void ZSTD_window_clear(ZSTD_window_t* window)\n{\n    size_t const endT = (size_t)(window->nextSrc - window->base);\n    U32 const end = (U32)endT;\n\n    window->lowLimit = end;\n    window->dictLimit = end;\n}\n\n/**\n * ZSTD_window_hasExtDict():\n * Returns non-zero if the window has a non-empty extDict.\n */\nMEM_STATIC U32 ZSTD_window_hasExtDict(ZSTD_window_t const window)\n{\n    return window.lowLimit < window.dictLimit;\n}\n\n/**\n * ZSTD_matchState_dictMode():\n * Inspects the provided matchState and figures out what dictMode should be\n * passed to the compressor.\n */\nMEM_STATIC ZSTD_dictMode_e ZSTD_matchState_dictMode(const ZSTD_matchState_t *ms)\n{\n    return ZSTD_window_hasExtDict(ms->window) ?\n        ZSTD_extDict :\n        ms->dictMatchState != NULL ?\n            ZSTD_dictMatchState :\n            ZSTD_noDict;\n}\n\n/**\n * ZSTD_window_needOverflowCorrection():\n * Returns non-zero if the indices are getting too large and need overflow\n * protection.\n */\nMEM_STATIC U32 ZSTD_window_needOverflowCorrection(ZSTD_window_t const window,\n                                                  void const* srcEnd)\n{\n    U32 const current = (U32)((BYTE const*)srcEnd - window.base);\n    return current > ZSTD_CURRENT_MAX;\n}\n\n/**\n * ZSTD_window_correctOverflow():\n * Reduces the indices to protect from index overflow.\n * Returns the correction made to the indices, which must be applied to every\n * stored index.\n *\n * The least significant cycleLog bits of the indices must remain the same,\n * which may be 0. Every index up to maxDist in the past must be valid.\n * NOTE: (maxDist & cycleMask) must be zero.\n */\nMEM_STATIC U32 ZSTD_window_correctOverflow(ZSTD_window_t* window, U32 cycleLog,\n                                           U32 maxDist, void const* src)\n{\n    /* preemptive overflow correction:\n     * 1. correction is large enough:\n     *    lowLimit > (3<<29) ==> current > 3<<29 + 1<<windowLog\n     *    1<<windowLog <= newCurrent < 1<<chainLog + 1<<windowLog\n     *\n     *    current - newCurrent\n     *    > (3<<29 + 1<<windowLog) - (1<<windowLog + 1<<chainLog)\n     *    > (3<<29) - (1<<chainLog)\n     *    > (3<<29) - (1<<30)             (NOTE: chainLog <= 30)\n     *    > 1<<29\n     *\n     * 2. (ip+ZSTD_CHUNKSIZE_MAX - cctx->base) doesn't overflow:\n     *    After correction, current is less than (1<<chainLog + 1<<windowLog).\n     *    In 64-bit mode we are safe, because we have 64-bit ptrdiff_t.\n     *    In 32-bit mode we are safe, because (chainLog <= 29), so\n     *    ip+ZSTD_CHUNKSIZE_MAX - cctx->base < 1<<32.\n     * 3. (cctx->lowLimit + 1<<windowLog) < 1<<32:\n     *    windowLog <= 31 ==> 3<<29 + 1<<windowLog < 7<<29 < 1<<32.\n     */\n    U32 const cycleMask = (1U << cycleLog) - 1;\n    U32 const current = (U32)((BYTE const*)src - window->base);\n    U32 const newCurrent = (current & cycleMask) + maxDist;\n    U32 const correction = current - newCurrent;\n    assert((maxDist & cycleMask) == 0);\n    assert(current > newCurrent);\n    /* Loose bound, should be around 1<<29 (see above) */\n    assert(correction > 1<<28);\n\n    window->base += correction;\n    window->dictBase += correction;\n    window->lowLimit -= correction;\n    window->dictLimit -= correction;\n\n    DEBUGLOG(4, \"Correction of 0x%x bytes to lowLimit=0x%x\", correction,\n             window->lowLimit);\n    return correction;\n}\n\n/**\n * ZSTD_window_enforceMaxDist():\n * Updates lowLimit so that:\n *    (srcEnd - base) - lowLimit == maxDist + loadedDictEnd\n *\n * It ensures index is valid as long as index >= lowLimit.\n * This must be called before a block compression call.\n *\n * loadedDictEnd is only defined if a dictionary is in use for current compression.\n * As the name implies, loadedDictEnd represents the index at end of dictionary.\n * The value lies within context's referential, it can be directly compared to blockEndIdx.\n *\n * If loadedDictEndPtr is NULL, no dictionary is in use, and we use loadedDictEnd == 0.\n * If loadedDictEndPtr is not NULL, we set it to zero after updating lowLimit.\n * This is because dictionaries are allowed to be referenced fully\n * as long as the last byte of the dictionary is in the window.\n * Once input has progressed beyond window size, dictionary cannot be referenced anymore.\n *\n * In normal dict mode, the dictionary lies between lowLimit and dictLimit.\n * In dictMatchState mode, lowLimit and dictLimit are the same,\n * and the dictionary is below them.\n * forceWindow and dictMatchState are therefore incompatible.\n */\nMEM_STATIC void\nZSTD_window_enforceMaxDist(ZSTD_window_t* window,\n                     const void* blockEnd,\n                           U32   maxDist,\n                           U32*  loadedDictEndPtr,\n                     const ZSTD_matchState_t** dictMatchStatePtr)\n{\n    U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);\n    U32 const loadedDictEnd = (loadedDictEndPtr != NULL) ? *loadedDictEndPtr : 0;\n    DEBUGLOG(5, \"ZSTD_window_enforceMaxDist: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u\",\n                (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);\n\n    /* - When there is no dictionary : loadedDictEnd == 0.\n         In which case, the test (blockEndIdx > maxDist) is merely to avoid\n         overflowing next operation `newLowLimit = blockEndIdx - maxDist`.\n       - When there is a standard dictionary :\n         Index referential is copied from the dictionary,\n         which means it starts from 0.\n         In which case, loadedDictEnd == dictSize,\n         and it makes sense to compare `blockEndIdx > maxDist + dictSize`\n         since `blockEndIdx` also starts from zero.\n       - When there is an attached dictionary :\n         loadedDictEnd is expressed within the referential of the context,\n         so it can be directly compared against blockEndIdx.\n    */\n    if (blockEndIdx > maxDist + loadedDictEnd) {\n        U32 const newLowLimit = blockEndIdx - maxDist;\n        if (window->lowLimit < newLowLimit) window->lowLimit = newLowLimit;\n        if (window->dictLimit < window->lowLimit) {\n            DEBUGLOG(5, \"Update dictLimit to match lowLimit, from %u to %u\",\n                        (unsigned)window->dictLimit, (unsigned)window->lowLimit);\n            window->dictLimit = window->lowLimit;\n        }\n        /* On reaching window size, dictionaries are invalidated */\n        if (loadedDictEndPtr) *loadedDictEndPtr = 0;\n        if (dictMatchStatePtr) *dictMatchStatePtr = NULL;\n    }\n}\n\n/* Similar to ZSTD_window_enforceMaxDist(),\n * but only invalidates dictionary\n * when input progresses beyond window size.\n * assumption : loadedDictEndPtr and dictMatchStatePtr are valid (non NULL)\n *              loadedDictEnd uses same referential as window->base\n *              maxDist is the window size */\nMEM_STATIC void\nZSTD_checkDictValidity(const ZSTD_window_t* window,\n                       const void* blockEnd,\n                             U32   maxDist,\n                             U32*  loadedDictEndPtr,\n                       const ZSTD_matchState_t** dictMatchStatePtr)\n{\n    assert(loadedDictEndPtr != NULL);\n    assert(dictMatchStatePtr != NULL);\n    {   U32 const blockEndIdx = (U32)((BYTE const*)blockEnd - window->base);\n        U32 const loadedDictEnd = *loadedDictEndPtr;\n        DEBUGLOG(5, \"ZSTD_checkDictValidity: blockEndIdx=%u, maxDist=%u, loadedDictEnd=%u\",\n                    (unsigned)blockEndIdx, (unsigned)maxDist, (unsigned)loadedDictEnd);\n        assert(blockEndIdx >= loadedDictEnd);\n\n        if (blockEndIdx > loadedDictEnd + maxDist) {\n            /* On reaching window size, dictionaries are invalidated.\n             * For simplification, if window size is reached anywhere within next block,\n             * the dictionary is invalidated for the full block.\n             */\n            DEBUGLOG(6, \"invalidating dictionary for current block (distance > windowSize)\");\n            *loadedDictEndPtr = 0;\n            *dictMatchStatePtr = NULL;\n        } else {\n            if (*loadedDictEndPtr != 0) {\n                DEBUGLOG(6, \"dictionary considered valid for current block\");\n    }   }   }\n}\n\n/**\n * ZSTD_window_update():\n * Updates the window by appending [src, src + srcSize) to the window.\n * If it is not contiguous, the current prefix becomes the extDict, and we\n * forget about the extDict. Handles overlap of the prefix and extDict.\n * Returns non-zero if the segment is contiguous.\n */\nMEM_STATIC U32 ZSTD_window_update(ZSTD_window_t* window,\n                                  void const* src, size_t srcSize)\n{\n    BYTE const* const ip = (BYTE const*)src;\n    U32 contiguous = 1;\n    DEBUGLOG(5, \"ZSTD_window_update\");\n    /* Check if blocks follow each other */\n    if (src != window->nextSrc) {\n        /* not contiguous */\n        size_t const distanceFromBase = (size_t)(window->nextSrc - window->base);\n        DEBUGLOG(5, \"Non contiguous blocks, new segment starts at %u\", window->dictLimit);\n        window->lowLimit = window->dictLimit;\n        assert(distanceFromBase == (size_t)(U32)distanceFromBase);  /* should never overflow */\n        window->dictLimit = (U32)distanceFromBase;\n        window->dictBase = window->base;\n        window->base = ip - distanceFromBase;\n        // ms->nextToUpdate = window->dictLimit;\n        if (window->dictLimit - window->lowLimit < HASH_READ_SIZE) window->lowLimit = window->dictLimit;   /* too small extDict */\n        contiguous = 0;\n    }\n    window->nextSrc = ip + srcSize;\n    /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */\n    if ( (ip+srcSize > window->dictBase + window->lowLimit)\n       & (ip < window->dictBase + window->dictLimit)) {\n        ptrdiff_t const highInputIdx = (ip + srcSize) - window->dictBase;\n        U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)window->dictLimit) ? window->dictLimit : (U32)highInputIdx;\n        window->lowLimit = lowLimitMax;\n        DEBUGLOG(5, \"Overlapping extDict and input : new lowLimit = %u\", window->lowLimit);\n    }\n    return contiguous;\n}\n\nMEM_STATIC U32 ZSTD_getLowestMatchIndex(const ZSTD_matchState_t* ms, U32 current, unsigned windowLog)\n{\n    U32    const maxDistance = 1U << windowLog;\n    U32    const lowestValid = ms->window.lowLimit;\n    U32    const withinWindow = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;\n    U32    const isDictionary = (ms->loadedDictEnd != 0);\n    U32    const matchLowest = isDictionary ? lowestValid : withinWindow;\n    return matchLowest;\n}\n\n\n\n/* debug functions */\n#if (DEBUGLEVEL>=2)\n\nMEM_STATIC double ZSTD_fWeight(U32 rawStat)\n{\n    U32 const fp_accuracy = 8;\n    U32 const fp_multiplier = (1 << fp_accuracy);\n    U32 const newStat = rawStat + 1;\n    U32 const hb = ZSTD_highbit32(newStat);\n    U32 const BWeight = hb * fp_multiplier;\n    U32 const FWeight = (newStat << fp_accuracy) >> hb;\n    U32 const weight = BWeight + FWeight;\n    assert(hb + fp_accuracy < 31);\n    return (double)weight / fp_multiplier;\n}\n\n/* display a table content,\n * listing each element, its frequency, and its predicted bit cost */\nMEM_STATIC void ZSTD_debugTable(const U32* table, U32 max)\n{\n    unsigned u, sum;\n    for (u=0, sum=0; u<=max; u++) sum += table[u];\n    DEBUGLOG(2, \"total nb elts: %u\", sum);\n    for (u=0; u<=max; u++) {\n        DEBUGLOG(2, \"%2u: %5u  (%.2f)\",\n                u, table[u], ZSTD_fWeight(sum) - ZSTD_fWeight(table[u]) );\n    }\n}\n\n#endif\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n\n/* ==============================================================\n * Private declarations\n * These prototypes shall only be called from within lib/compress\n * ============================================================== */\n\n/* ZSTD_getCParamsFromCCtxParams() :\n * cParams are built depending on compressionLevel, src size hints,\n * LDM and manually set compression parameters.\n */\nZSTD_compressionParameters ZSTD_getCParamsFromCCtxParams(\n        const ZSTD_CCtx_params* CCtxParams, U64 srcSizeHint, size_t dictSize);\n\n/*! ZSTD_initCStream_internal() :\n *  Private use only. Init streaming operation.\n *  expects params to be valid.\n *  must receive dict, or cdict, or none, but not both.\n *  @return : 0, or an error code */\nsize_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,\n                     const void* dict, size_t dictSize,\n                     const ZSTD_CDict* cdict,\n                     const ZSTD_CCtx_params* params, unsigned long long pledgedSrcSize);\n\nvoid ZSTD_resetSeqStore(seqStore_t* ssPtr);\n\n/*! ZSTD_getCParamsFromCDict() :\n *  as the name implies */\nZSTD_compressionParameters ZSTD_getCParamsFromCDict(const ZSTD_CDict* cdict);\n\n/* ZSTD_compressBegin_advanced_internal() :\n * Private use only. To be called from zstdmt_compress.c. */\nsize_t ZSTD_compressBegin_advanced_internal(ZSTD_CCtx* cctx,\n                                    const void* dict, size_t dictSize,\n                                    ZSTD_dictContentType_e dictContentType,\n                                    ZSTD_dictTableLoadMethod_e dtlm,\n                                    const ZSTD_CDict* cdict,\n                                    const ZSTD_CCtx_params* params,\n                                    unsigned long long pledgedSrcSize);\n\n/* ZSTD_compress_advanced_internal() :\n * Private use only. To be called from zstdmt_compress.c. */\nsize_t ZSTD_compress_advanced_internal(ZSTD_CCtx* cctx,\n                                       void* dst, size_t dstCapacity,\n                                 const void* src, size_t srcSize,\n                                 const void* dict,size_t dictSize,\n                                 const ZSTD_CCtx_params* params);\n\n\n/* ZSTD_writeLastEmptyBlock() :\n * output an empty Block with end-of-frame mark to complete a frame\n * @return : size of data written into `dst` (== ZSTD_blockHeaderSize (defined in zstd_internal.h))\n *           or an error code if `dstCapacity` is too small (<ZSTD_blockHeaderSize)\n */\nsize_t ZSTD_writeLastEmptyBlock(void* dst, size_t dstCapacity);\n\n\n/* ZSTD_referenceExternalSequences() :\n * Must be called before starting a compression operation.\n * seqs must parse a prefix of the source.\n * This cannot be used when long range matching is enabled.\n * Zstd will use these sequences, and pass the literals to a secondary block\n * compressor.\n * @return : An error code on failure.\n * NOTE: seqs are not verified! Invalid sequences can cause out-of-bounds memory\n * access and data corruption.\n */\nsize_t ZSTD_referenceExternalSequences(ZSTD_CCtx* cctx, rawSeq* seq, size_t nbSeq);\n\n\n#endif /* ZSTD_COMPRESS_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_compress_literals.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n /*-*************************************\n *  Dependencies\n ***************************************/\n#include \"zstd_compress_literals.h\"\n\nsize_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)\n{\n    BYTE* const ostart = (BYTE* const)dst;\n    U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);\n\n    RETURN_ERROR_IF(srcSize + flSize > dstCapacity, dstSize_tooSmall);\n\n    switch(flSize)\n    {\n        case 1: /* 2 - 1 - 5 */\n            ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));\n            break;\n        case 2: /* 2 - 2 - 12 */\n            MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));\n            break;\n        case 3: /* 2 - 2 - 20 */\n            MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));\n            break;\n        default:   /* not necessary : flSize is {1,2,3} */\n            assert(0);\n    }\n\n    memcpy(ostart + flSize, src, srcSize);\n    return srcSize + flSize;\n}\n\nsize_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)\n{\n    BYTE* const ostart = (BYTE* const)dst;\n    U32   const flSize = 1 + (srcSize>31) + (srcSize>4095);\n\n    (void)dstCapacity;  /* dstCapacity already guaranteed to be >=4, hence large enough */\n\n    switch(flSize)\n    {\n        case 1: /* 2 - 1 - 5 */\n            ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));\n            break;\n        case 2: /* 2 - 2 - 12 */\n            MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));\n            break;\n        case 3: /* 2 - 2 - 20 */\n            MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));\n            break;\n        default:   /* not necessary : flSize is {1,2,3} */\n            assert(0);\n    }\n\n    ostart[flSize] = *(const BYTE*)src;\n    return flSize+1;\n}\n\nsize_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,\n                              ZSTD_hufCTables_t* nextHuf,\n                              ZSTD_strategy strategy, int disableLiteralCompression,\n                              void* dst, size_t dstCapacity,\n                        const void* src, size_t srcSize,\n                              void* entropyWorkspace, size_t entropyWorkspaceSize,\n                        const int bmi2)\n{\n    size_t const minGain = ZSTD_minGain(srcSize, strategy);\n    size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);\n    BYTE*  const ostart = (BYTE*)dst;\n    U32 singleStream = srcSize < 256;\n    symbolEncodingType_e hType = set_compressed;\n    size_t cLitSize;\n\n    DEBUGLOG(5,\"ZSTD_compressLiterals (disableLiteralCompression=%i)\",\n                disableLiteralCompression);\n\n    /* Prepare nextEntropy assuming reusing the existing table */\n    memcpy(nextHuf, prevHuf, sizeof(*prevHuf));\n\n    if (disableLiteralCompression)\n        return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);\n\n    /* small ? don't even attempt compression (speed opt) */\n#   define COMPRESS_LITERALS_SIZE_MIN 63\n    {   size_t const minLitSize = (prevHuf->repeatMode == HUF_repeat_valid) ? 6 : COMPRESS_LITERALS_SIZE_MIN;\n        if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);\n    }\n\n    RETURN_ERROR_IF(dstCapacity < lhSize+1, dstSize_tooSmall, \"not enough space for compression\");\n    {   HUF_repeat repeat = prevHuf->repeatMode;\n        int const preferRepeat = strategy < ZSTD_lazy ? srcSize <= 1024 : 0;\n        if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;\n        cLitSize = singleStream ?\n            HUF_compress1X_repeat(\n                ostart+lhSize, dstCapacity-lhSize, src, srcSize,\n                255, 11, entropyWorkspace, entropyWorkspaceSize,\n                (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2) :\n            HUF_compress4X_repeat(\n                ostart+lhSize, dstCapacity-lhSize, src, srcSize,\n                255, 11, entropyWorkspace, entropyWorkspaceSize,\n                (HUF_CElt*)nextHuf->CTable, &repeat, preferRepeat, bmi2);\n        if (repeat != HUF_repeat_none) {\n            /* reused the existing table */\n            hType = set_repeat;\n        }\n    }\n\n    if ((cLitSize==0) | (cLitSize >= srcSize - minGain) | ERR_isError(cLitSize)) {\n        memcpy(nextHuf, prevHuf, sizeof(*prevHuf));\n        return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);\n    }\n    if (cLitSize==1) {\n        memcpy(nextHuf, prevHuf, sizeof(*prevHuf));\n        return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);\n    }\n\n    if (hType == set_compressed) {\n        /* using a newly constructed table */\n        nextHuf->repeatMode = HUF_repeat_check;\n    }\n\n    /* Build header */\n    switch(lhSize)\n    {\n    case 3: /* 2 - 2 - 10 - 10 */\n        {   U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);\n            MEM_writeLE24(ostart, lhc);\n            break;\n        }\n    case 4: /* 2 - 2 - 14 - 14 */\n        {   U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);\n            MEM_writeLE32(ostart, lhc);\n            break;\n        }\n    case 5: /* 2 - 2 - 18 - 18 */\n        {   U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);\n            MEM_writeLE32(ostart, lhc);\n            ostart[4] = (BYTE)(cLitSize >> 10);\n            break;\n        }\n    default:  /* not possible : lhSize is {3,4,5} */\n        assert(0);\n    }\n    return lhSize+cLitSize;\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_compress_literals.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_COMPRESS_LITERALS_H\n#define ZSTD_COMPRESS_LITERALS_H\n\n#include \"zstd_compress_internal.h\" /* ZSTD_hufCTables_t, ZSTD_minGain() */\n\n\nsize_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize);\n\nsize_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize);\n\nsize_t ZSTD_compressLiterals (ZSTD_hufCTables_t const* prevHuf,\n                              ZSTD_hufCTables_t* nextHuf,\n                              ZSTD_strategy strategy, int disableLiteralCompression,\n                              void* dst, size_t dstCapacity,\n                        const void* src, size_t srcSize,\n                              void* entropyWorkspace, size_t entropyWorkspaceSize,\n                        const int bmi2);\n\n#endif /* ZSTD_COMPRESS_LITERALS_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_compress_sequences.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n /*-*************************************\n *  Dependencies\n ***************************************/\n#include \"zstd_compress_sequences.h\"\n\n/**\n * -log2(x / 256) lookup table for x in [0, 256).\n * If x == 0: Return 0\n * Else: Return floor(-log2(x / 256) * 256)\n */\nstatic unsigned const kInverseProbabilityLog256[256] = {\n    0,    2048, 1792, 1642, 1536, 1453, 1386, 1329, 1280, 1236, 1197, 1162,\n    1130, 1100, 1073, 1047, 1024, 1001, 980,  960,  941,  923,  906,  889,\n    874,  859,  844,  830,  817,  804,  791,  779,  768,  756,  745,  734,\n    724,  714,  704,  694,  685,  676,  667,  658,  650,  642,  633,  626,\n    618,  610,  603,  595,  588,  581,  574,  567,  561,  554,  548,  542,\n    535,  529,  523,  517,  512,  506,  500,  495,  489,  484,  478,  473,\n    468,  463,  458,  453,  448,  443,  438,  434,  429,  424,  420,  415,\n    411,  407,  402,  398,  394,  390,  386,  382,  377,  373,  370,  366,\n    362,  358,  354,  350,  347,  343,  339,  336,  332,  329,  325,  322,\n    318,  315,  311,  308,  305,  302,  298,  295,  292,  289,  286,  282,\n    279,  276,  273,  270,  267,  264,  261,  258,  256,  253,  250,  247,\n    244,  241,  239,  236,  233,  230,  228,  225,  222,  220,  217,  215,\n    212,  209,  207,  204,  202,  199,  197,  194,  192,  190,  187,  185,\n    182,  180,  178,  175,  173,  171,  168,  166,  164,  162,  159,  157,\n    155,  153,  151,  149,  146,  144,  142,  140,  138,  136,  134,  132,\n    130,  128,  126,  123,  121,  119,  117,  115,  114,  112,  110,  108,\n    106,  104,  102,  100,  98,   96,   94,   93,   91,   89,   87,   85,\n    83,   82,   80,   78,   76,   74,   73,   71,   69,   67,   66,   64,\n    62,   61,   59,   57,   55,   54,   52,   50,   49,   47,   46,   44,\n    42,   41,   39,   37,   36,   34,   33,   31,   30,   28,   26,   25,\n    23,   22,   20,   19,   17,   16,   14,   13,   11,   10,   8,    7,\n    5,    4,    2,    1,\n};\n\nstatic unsigned ZSTD_getFSEMaxSymbolValue(FSE_CTable const* ctable) {\n  void const* ptr = ctable;\n  U16 const* u16ptr = (U16 const*)ptr;\n  U32 const maxSymbolValue = MEM_read16(u16ptr + 1);\n  return maxSymbolValue;\n}\n\n/**\n * Returns the cost in bytes of encoding the normalized count header.\n * Returns an error if any of the helper functions return an error.\n */\nstatic size_t ZSTD_NCountCost(unsigned const* count, unsigned const max,\n                              size_t const nbSeq, unsigned const FSELog)\n{\n    BYTE wksp[FSE_NCOUNTBOUND];\n    S16 norm[MaxSeq + 1];\n    const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);\n    FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq, max));\n    return FSE_writeNCount(wksp, sizeof(wksp), norm, max, tableLog);\n}\n\n/**\n * Returns the cost in bits of encoding the distribution described by count\n * using the entropy bound.\n */\nstatic size_t ZSTD_entropyCost(unsigned const* count, unsigned const max, size_t const total)\n{\n    unsigned cost = 0;\n    unsigned s;\n    for (s = 0; s <= max; ++s) {\n        unsigned norm = (unsigned)((256 * count[s]) / total);\n        if (count[s] != 0 && norm == 0)\n            norm = 1;\n        assert(count[s] < total);\n        cost += count[s] * kInverseProbabilityLog256[norm];\n    }\n    return cost >> 8;\n}\n\n/**\n * Returns the cost in bits of encoding the distribution in count using ctable.\n * Returns an error if ctable cannot represent all the symbols in count.\n */\nstatic size_t ZSTD_fseBitCost(\n    FSE_CTable const* ctable,\n    unsigned const* count,\n    unsigned const max)\n{\n    unsigned const kAccuracyLog = 8;\n    size_t cost = 0;\n    unsigned s;\n    FSE_CState_t cstate;\n    FSE_initCState(&cstate, ctable);\n    RETURN_ERROR_IF(ZSTD_getFSEMaxSymbolValue(ctable) < max, GENERIC,\n                    \"Repeat FSE_CTable has maxSymbolValue %u < %u\",\n                    ZSTD_getFSEMaxSymbolValue(ctable), max);\n    for (s = 0; s <= max; ++s) {\n        unsigned const tableLog = cstate.stateLog;\n        unsigned const badCost = (tableLog + 1) << kAccuracyLog;\n        unsigned const bitCost = FSE_bitCost(cstate.symbolTT, tableLog, s, kAccuracyLog);\n        if (count[s] == 0)\n            continue;\n        RETURN_ERROR_IF(bitCost >= badCost, GENERIC,\n                        \"Repeat FSE_CTable has Prob[%u] == 0\", s);\n        cost += count[s] * bitCost;\n    }\n    return cost >> kAccuracyLog;\n}\n\n/**\n * Returns the cost in bits of encoding the distribution in count using the\n * table described by norm. The max symbol support by norm is assumed >= max.\n * norm must be valid for every symbol with non-zero probability in count.\n */\nstatic size_t ZSTD_crossEntropyCost(short const* norm, unsigned accuracyLog,\n                                    unsigned const* count, unsigned const max)\n{\n    unsigned const shift = 8 - accuracyLog;\n    size_t cost = 0;\n    unsigned s;\n    assert(accuracyLog <= 8);\n    for (s = 0; s <= max; ++s) {\n        unsigned const normAcc = norm[s] != -1 ? norm[s] : 1;\n        unsigned const norm256 = normAcc << shift;\n        assert(norm256 > 0);\n        assert(norm256 < 256);\n        cost += count[s] * kInverseProbabilityLog256[norm256];\n    }\n    return cost >> 8;\n}\n\nsymbolEncodingType_e\nZSTD_selectEncodingType(\n        FSE_repeat* repeatMode, unsigned const* count, unsigned const max,\n        size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,\n        FSE_CTable const* prevCTable,\n        short const* defaultNorm, U32 defaultNormLog,\n        ZSTD_defaultPolicy_e const isDefaultAllowed,\n        ZSTD_strategy const strategy)\n{\n    ZSTD_STATIC_ASSERT(ZSTD_defaultDisallowed == 0 && ZSTD_defaultAllowed != 0);\n    if (mostFrequent == nbSeq) {\n        *repeatMode = FSE_repeat_none;\n        if (isDefaultAllowed && nbSeq <= 2) {\n            /* Prefer set_basic over set_rle when there are 2 or less symbols,\n             * since RLE uses 1 byte, but set_basic uses 5-6 bits per symbol.\n             * If basic encoding isn't possible, always choose RLE.\n             */\n            DEBUGLOG(5, \"Selected set_basic\");\n            return set_basic;\n        }\n        DEBUGLOG(5, \"Selected set_rle\");\n        return set_rle;\n    }\n    if (strategy < ZSTD_lazy) {\n        if (isDefaultAllowed) {\n            size_t const staticFse_nbSeq_max = 1000;\n            size_t const mult = 10 - strategy;\n            size_t const baseLog = 3;\n            size_t const dynamicFse_nbSeq_min = (((size_t)1 << defaultNormLog) * mult) >> baseLog;  /* 28-36 for offset, 56-72 for lengths */\n            assert(defaultNormLog >= 5 && defaultNormLog <= 6);  /* xx_DEFAULTNORMLOG */\n            assert(mult <= 9 && mult >= 7);\n            if ( (*repeatMode == FSE_repeat_valid)\n              && (nbSeq < staticFse_nbSeq_max) ) {\n                DEBUGLOG(5, \"Selected set_repeat\");\n                return set_repeat;\n            }\n            if ( (nbSeq < dynamicFse_nbSeq_min)\n              || (mostFrequent < (nbSeq >> (defaultNormLog-1))) ) {\n                DEBUGLOG(5, \"Selected set_basic\");\n                /* The format allows default tables to be repeated, but it isn't useful.\n                 * When using simple heuristics to select encoding type, we don't want\n                 * to confuse these tables with dictionaries. When running more careful\n                 * analysis, we don't need to waste time checking both repeating tables\n                 * and default tables.\n                 */\n                *repeatMode = FSE_repeat_none;\n                return set_basic;\n            }\n        }\n    } else {\n        size_t const basicCost = isDefaultAllowed ? ZSTD_crossEntropyCost(defaultNorm, defaultNormLog, count, max) : ERROR(GENERIC);\n        size_t const repeatCost = *repeatMode != FSE_repeat_none ? ZSTD_fseBitCost(prevCTable, count, max) : ERROR(GENERIC);\n        size_t const NCountCost = ZSTD_NCountCost(count, max, nbSeq, FSELog);\n        size_t const compressedCost = (NCountCost << 3) + ZSTD_entropyCost(count, max, nbSeq);\n\n        if (isDefaultAllowed) {\n            assert(!ZSTD_isError(basicCost));\n            assert(!(*repeatMode == FSE_repeat_valid && ZSTD_isError(repeatCost)));\n        }\n        assert(!ZSTD_isError(NCountCost));\n        assert(compressedCost < ERROR(maxCode));\n        DEBUGLOG(5, \"Estimated bit costs: basic=%u\\trepeat=%u\\tcompressed=%u\",\n                    (unsigned)basicCost, (unsigned)repeatCost, (unsigned)compressedCost);\n        if (basicCost <= repeatCost && basicCost <= compressedCost) {\n            DEBUGLOG(5, \"Selected set_basic\");\n            assert(isDefaultAllowed);\n            *repeatMode = FSE_repeat_none;\n            return set_basic;\n        }\n        if (repeatCost <= compressedCost) {\n            DEBUGLOG(5, \"Selected set_repeat\");\n            assert(!ZSTD_isError(repeatCost));\n            return set_repeat;\n        }\n        assert(compressedCost < basicCost && compressedCost < repeatCost);\n    }\n    DEBUGLOG(5, \"Selected set_compressed\");\n    *repeatMode = FSE_repeat_check;\n    return set_compressed;\n}\n\nsize_t\nZSTD_buildCTable(void* dst, size_t dstCapacity,\n                FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,\n                unsigned* count, U32 max,\n                const BYTE* codeTable, size_t nbSeq,\n                const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,\n                const FSE_CTable* prevCTable, size_t prevCTableSize,\n                void* entropyWorkspace, size_t entropyWorkspaceSize)\n{\n    BYTE* op = (BYTE*)dst;\n    const BYTE* const oend = op + dstCapacity;\n    DEBUGLOG(6, \"ZSTD_buildCTable (dstCapacity=%u)\", (unsigned)dstCapacity);\n\n    switch (type) {\n    case set_rle:\n        FORWARD_IF_ERROR(FSE_buildCTable_rle(nextCTable, (BYTE)max));\n        RETURN_ERROR_IF(dstCapacity==0, dstSize_tooSmall);\n        *op = codeTable[0];\n        return 1;\n    case set_repeat:\n        memcpy(nextCTable, prevCTable, prevCTableSize);\n        return 0;\n    case set_basic:\n        FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, defaultNorm, defaultMax, defaultNormLog, entropyWorkspace, entropyWorkspaceSize));  /* note : could be pre-calculated */\n        return 0;\n    case set_compressed: {\n        S16 norm[MaxSeq + 1];\n        size_t nbSeq_1 = nbSeq;\n        const U32 tableLog = FSE_optimalTableLog(FSELog, nbSeq, max);\n        if (count[codeTable[nbSeq-1]] > 1) {\n            count[codeTable[nbSeq-1]]--;\n            nbSeq_1--;\n        }\n        assert(nbSeq_1 > 1);\n        FORWARD_IF_ERROR(FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max));\n        {   size_t const NCountSize = FSE_writeNCount(op, oend - op, norm, max, tableLog);   /* overflow protected */\n            FORWARD_IF_ERROR(NCountSize);\n            FORWARD_IF_ERROR(FSE_buildCTable_wksp(nextCTable, norm, max, tableLog, entropyWorkspace, entropyWorkspaceSize));\n            return NCountSize;\n        }\n    }\n    default: assert(0); RETURN_ERROR(GENERIC);\n    }\n}\n\nFORCE_INLINE_TEMPLATE size_t\nZSTD_encodeSequences_body(\n            void* dst, size_t dstCapacity,\n            FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,\n            FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,\n            FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,\n            seqDef const* sequences, size_t nbSeq, int longOffsets)\n{\n    BIT_CStream_t blockStream;\n    FSE_CState_t  stateMatchLength;\n    FSE_CState_t  stateOffsetBits;\n    FSE_CState_t  stateLitLength;\n\n    RETURN_ERROR_IF(\n        ERR_isError(BIT_initCStream(&blockStream, dst, dstCapacity)),\n        dstSize_tooSmall, \"not enough space remaining\");\n    DEBUGLOG(6, \"available space for bitstream : %i  (dstCapacity=%u)\",\n                (int)(blockStream.endPtr - blockStream.startPtr),\n                (unsigned)dstCapacity);\n\n    /* first symbols */\n    FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);\n    FSE_initCState2(&stateOffsetBits,  CTable_OffsetBits,  ofCodeTable[nbSeq-1]);\n    FSE_initCState2(&stateLitLength,   CTable_LitLength,   llCodeTable[nbSeq-1]);\n    BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);\n    if (MEM_32bits()) BIT_flushBits(&blockStream);\n    BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);\n    if (MEM_32bits()) BIT_flushBits(&blockStream);\n    if (longOffsets) {\n        U32 const ofBits = ofCodeTable[nbSeq-1];\n        int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);\n        if (extraBits) {\n            BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);\n            BIT_flushBits(&blockStream);\n        }\n        BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,\n                    ofBits - extraBits);\n    } else {\n        BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);\n    }\n    BIT_flushBits(&blockStream);\n\n    {   size_t n;\n        for (n=nbSeq-2 ; n<nbSeq ; n--) {      /* intentional underflow */\n            BYTE const llCode = llCodeTable[n];\n            BYTE const ofCode = ofCodeTable[n];\n            BYTE const mlCode = mlCodeTable[n];\n            U32  const llBits = LL_bits[llCode];\n            U32  const ofBits = ofCode;\n            U32  const mlBits = ML_bits[mlCode];\n            DEBUGLOG(6, \"encoding: litlen:%2u - matchlen:%2u - offCode:%7u\",\n                        (unsigned)sequences[n].litLength,\n                        (unsigned)sequences[n].matchLength + MINMATCH,\n                        (unsigned)sequences[n].offset);\n                                                                            /* 32b*/  /* 64b*/\n                                                                            /* (7)*/  /* (7)*/\n            FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode);       /* 15 */  /* 15 */\n            FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode);      /* 24 */  /* 24 */\n            if (MEM_32bits()) BIT_flushBits(&blockStream);                  /* (7)*/\n            FSE_encodeSymbol(&blockStream, &stateLitLength, llCode);        /* 16 */  /* 33 */\n            if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))\n                BIT_flushBits(&blockStream);                                /* (7)*/\n            BIT_addBits(&blockStream, sequences[n].litLength, llBits);\n            if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);\n            BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);\n            if (MEM_32bits() || (ofBits+mlBits+llBits > 56)) BIT_flushBits(&blockStream);\n            if (longOffsets) {\n                int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);\n                if (extraBits) {\n                    BIT_addBits(&blockStream, sequences[n].offset, extraBits);\n                    BIT_flushBits(&blockStream);                            /* (7)*/\n                }\n                BIT_addBits(&blockStream, sequences[n].offset >> extraBits,\n                            ofBits - extraBits);                            /* 31 */\n            } else {\n                BIT_addBits(&blockStream, sequences[n].offset, ofBits);     /* 31 */\n            }\n            BIT_flushBits(&blockStream);                                    /* (7)*/\n            DEBUGLOG(7, \"remaining space : %i\", (int)(blockStream.endPtr - blockStream.ptr));\n    }   }\n\n    DEBUGLOG(6, \"ZSTD_encodeSequences: flushing ML state with %u bits\", stateMatchLength.stateLog);\n    FSE_flushCState(&blockStream, &stateMatchLength);\n    DEBUGLOG(6, \"ZSTD_encodeSequences: flushing Off state with %u bits\", stateOffsetBits.stateLog);\n    FSE_flushCState(&blockStream, &stateOffsetBits);\n    DEBUGLOG(6, \"ZSTD_encodeSequences: flushing LL state with %u bits\", stateLitLength.stateLog);\n    FSE_flushCState(&blockStream, &stateLitLength);\n\n    {   size_t const streamSize = BIT_closeCStream(&blockStream);\n        RETURN_ERROR_IF(streamSize==0, dstSize_tooSmall, \"not enough space\");\n        return streamSize;\n    }\n}\n\nstatic size_t\nZSTD_encodeSequences_default(\n            void* dst, size_t dstCapacity,\n            FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,\n            FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,\n            FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,\n            seqDef const* sequences, size_t nbSeq, int longOffsets)\n{\n    return ZSTD_encodeSequences_body(dst, dstCapacity,\n                                    CTable_MatchLength, mlCodeTable,\n                                    CTable_OffsetBits, ofCodeTable,\n                                    CTable_LitLength, llCodeTable,\n                                    sequences, nbSeq, longOffsets);\n}\n\n\n#if DYNAMIC_BMI2\n\nstatic TARGET_ATTRIBUTE(\"bmi2\") size_t\nZSTD_encodeSequences_bmi2(\n            void* dst, size_t dstCapacity,\n            FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,\n            FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,\n            FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,\n            seqDef const* sequences, size_t nbSeq, int longOffsets)\n{\n    return ZSTD_encodeSequences_body(dst, dstCapacity,\n                                    CTable_MatchLength, mlCodeTable,\n                                    CTable_OffsetBits, ofCodeTable,\n                                    CTable_LitLength, llCodeTable,\n                                    sequences, nbSeq, longOffsets);\n}\n\n#endif\n\nsize_t ZSTD_encodeSequences(\n            void* dst, size_t dstCapacity,\n            FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,\n            FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,\n            FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,\n            seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2)\n{\n    DEBUGLOG(5, \"ZSTD_encodeSequences: dstCapacity = %u\", (unsigned)dstCapacity);\n#if DYNAMIC_BMI2\n    if (bmi2) {\n        return ZSTD_encodeSequences_bmi2(dst, dstCapacity,\n                                         CTable_MatchLength, mlCodeTable,\n                                         CTable_OffsetBits, ofCodeTable,\n                                         CTable_LitLength, llCodeTable,\n                                         sequences, nbSeq, longOffsets);\n    }\n#endif\n    (void)bmi2;\n    return ZSTD_encodeSequences_default(dst, dstCapacity,\n                                        CTable_MatchLength, mlCodeTable,\n                                        CTable_OffsetBits, ofCodeTable,\n                                        CTable_LitLength, llCodeTable,\n                                        sequences, nbSeq, longOffsets);\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_compress_sequences.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_COMPRESS_SEQUENCES_H\n#define ZSTD_COMPRESS_SEQUENCES_H\n\n#include \"fse.h\" /* FSE_repeat, FSE_CTable */\n#include \"zstd_internal.h\" /* symbolEncodingType_e, ZSTD_strategy */\n\ntypedef enum {\n    ZSTD_defaultDisallowed = 0,\n    ZSTD_defaultAllowed = 1\n} ZSTD_defaultPolicy_e;\n\nsymbolEncodingType_e\nZSTD_selectEncodingType(\n        FSE_repeat* repeatMode, unsigned const* count, unsigned const max,\n        size_t const mostFrequent, size_t nbSeq, unsigned const FSELog,\n        FSE_CTable const* prevCTable,\n        short const* defaultNorm, U32 defaultNormLog,\n        ZSTD_defaultPolicy_e const isDefaultAllowed,\n        ZSTD_strategy const strategy);\n\nsize_t\nZSTD_buildCTable(void* dst, size_t dstCapacity,\n                FSE_CTable* nextCTable, U32 FSELog, symbolEncodingType_e type,\n                unsigned* count, U32 max,\n                const BYTE* codeTable, size_t nbSeq,\n                const S16* defaultNorm, U32 defaultNormLog, U32 defaultMax,\n                const FSE_CTable* prevCTable, size_t prevCTableSize,\n                void* entropyWorkspace, size_t entropyWorkspaceSize);\n\nsize_t ZSTD_encodeSequences(\n            void* dst, size_t dstCapacity,\n            FSE_CTable const* CTable_MatchLength, BYTE const* mlCodeTable,\n            FSE_CTable const* CTable_OffsetBits, BYTE const* ofCodeTable,\n            FSE_CTable const* CTable_LitLength, BYTE const* llCodeTable,\n            seqDef const* sequences, size_t nbSeq, int longOffsets, int bmi2);\n\n#endif /* ZSTD_COMPRESS_SEQUENCES_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_cwksp.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_CWKSP_H\n#define ZSTD_CWKSP_H\n\n/*-*************************************\n*  Dependencies\n***************************************/\n#include \"zstd_internal.h\"\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n/*-*************************************\n*  Constants\n***************************************/\n\n/* define \"workspace is too large\" as this number of times larger than needed */\n#define ZSTD_WORKSPACETOOLARGE_FACTOR 3\n\n/* when workspace is continuously too large\n * during at least this number of times,\n * context's memory usage is considered wasteful,\n * because it's sized to handle a worst case scenario which rarely happens.\n * In which case, resize it down to free some memory */\n#define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128\n\n/* Since the workspace is effectively its own little malloc implementation /\n * arena, when we run under ASAN, we should similarly insert redzones between\n * each internal element of the workspace, so ASAN will catch overruns that\n * reach outside an object but that stay inside the workspace.\n *\n * This defines the size of that redzone.\n */\n#ifndef ZSTD_CWKSP_ASAN_REDZONE_SIZE\n#define ZSTD_CWKSP_ASAN_REDZONE_SIZE 128\n#endif\n\n/*-*************************************\n*  Structures\n***************************************/\ntypedef enum {\n    ZSTD_cwksp_alloc_objects,\n    ZSTD_cwksp_alloc_buffers,\n    ZSTD_cwksp_alloc_aligned\n} ZSTD_cwksp_alloc_phase_e;\n\n/**\n * Zstd fits all its internal datastructures into a single continuous buffer,\n * so that it only needs to perform a single OS allocation (or so that a buffer\n * can be provided to it and it can perform no allocations at all). This buffer\n * is called the workspace.\n *\n * Several optimizations complicate that process of allocating memory ranges\n * from this workspace for each internal datastructure:\n *\n * - These different internal datastructures have different setup requirements:\n *\n *   - The static objects need to be cleared once and can then be trivially\n *     reused for each compression.\n *\n *   - Various buffers don't need to be initialized at all--they are always\n *     written into before they're read.\n *\n *   - The matchstate tables have a unique requirement that they don't need\n *     their memory to be totally cleared, but they do need the memory to have\n *     some bound, i.e., a guarantee that all values in the memory they've been\n *     allocated is less than some maximum value (which is the starting value\n *     for the indices that they will then use for compression). When this\n *     guarantee is provided to them, they can use the memory without any setup\n *     work. When it can't, they have to clear the area.\n *\n * - These buffers also have different alignment requirements.\n *\n * - We would like to reuse the objects in the workspace for multiple\n *   compressions without having to perform any expensive reallocation or\n *   reinitialization work.\n *\n * - We would like to be able to efficiently reuse the workspace across\n *   multiple compressions **even when the compression parameters change** and\n *   we need to resize some of the objects (where possible).\n *\n * To attempt to manage this buffer, given these constraints, the ZSTD_cwksp\n * abstraction was created. It works as follows:\n *\n * Workspace Layout:\n *\n * [                        ... workspace ...                         ]\n * [objects][tables ... ->] free space [<- ... aligned][<- ... buffers]\n *\n * The various objects that live in the workspace are divided into the\n * following categories, and are allocated separately:\n *\n * - Static objects: this is optionally the enclosing ZSTD_CCtx or ZSTD_CDict,\n *   so that literally everything fits in a single buffer. Note: if present,\n *   this must be the first object in the workspace, since ZSTD_free{CCtx,\n *   CDict}() rely on a pointer comparison to see whether one or two frees are\n *   required.\n *\n * - Fixed size objects: these are fixed-size, fixed-count objects that are\n *   nonetheless \"dynamically\" allocated in the workspace so that we can\n *   control how they're initialized separately from the broader ZSTD_CCtx.\n *   Examples:\n *   - Entropy Workspace\n *   - 2 x ZSTD_compressedBlockState_t\n *   - CDict dictionary contents\n *\n * - Tables: these are any of several different datastructures (hash tables,\n *   chain tables, binary trees) that all respect a common format: they are\n *   uint32_t arrays, all of whose values are between 0 and (nextSrc - base).\n *   Their sizes depend on the cparams.\n *\n * - Aligned: these buffers are used for various purposes that require 4 byte\n *   alignment, but don't require any initialization before they're used.\n *\n * - Buffers: these buffers are used for various purposes that don't require\n *   any alignment or initialization before they're used. This means they can\n *   be moved around at no cost for a new compression.\n *\n * Allocating Memory:\n *\n * The various types of objects must be allocated in order, so they can be\n * correctly packed into the workspace buffer. That order is:\n *\n * 1. Objects\n * 2. Buffers\n * 3. Aligned\n * 4. Tables\n *\n * Attempts to reserve objects of different types out of order will fail.\n */\ntypedef struct {\n    void* workspace;\n    void* workspaceEnd;\n\n    void* objectEnd;\n    void* tableEnd;\n    void* tableValidEnd;\n    void* allocStart;\n\n    int allocFailed;\n    int workspaceOversizedDuration;\n    ZSTD_cwksp_alloc_phase_e phase;\n} ZSTD_cwksp;\n\n/*-*************************************\n*  Functions\n***************************************/\n\nMEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws);\n\nMEM_STATIC void ZSTD_cwksp_assert_internal_consistency(ZSTD_cwksp* ws) {\n    (void)ws;\n    assert(ws->workspace <= ws->objectEnd);\n    assert(ws->objectEnd <= ws->tableEnd);\n    assert(ws->objectEnd <= ws->tableValidEnd);\n    assert(ws->tableEnd <= ws->allocStart);\n    assert(ws->tableValidEnd <= ws->allocStart);\n    assert(ws->allocStart <= ws->workspaceEnd);\n}\n\n/**\n * Align must be a power of 2.\n */\nMEM_STATIC size_t ZSTD_cwksp_align(size_t size, size_t const align) {\n    size_t const mask = align - 1;\n    assert((align & mask) == 0);\n    return (size + mask) & ~mask;\n}\n\n/**\n * Use this to determine how much space in the workspace we will consume to\n * allocate this object. (Normally it should be exactly the size of the object,\n * but under special conditions, like ASAN, where we pad each object, it might\n * be larger.)\n *\n * Since tables aren't currently redzoned, you don't need to call through this\n * to figure out how much space you need for the matchState tables. Everything\n * else is though.\n */\nMEM_STATIC size_t ZSTD_cwksp_alloc_size(size_t size) {\n#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)\n    return size + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;\n#else\n    return size;\n#endif\n}\n\nMEM_STATIC void ZSTD_cwksp_internal_advance_phase(\n        ZSTD_cwksp* ws, ZSTD_cwksp_alloc_phase_e phase) {\n    assert(phase >= ws->phase);\n    if (phase > ws->phase) {\n        if (ws->phase < ZSTD_cwksp_alloc_buffers &&\n                phase >= ZSTD_cwksp_alloc_buffers) {\n            ws->tableValidEnd = ws->objectEnd;\n        }\n        if (ws->phase < ZSTD_cwksp_alloc_aligned &&\n                phase >= ZSTD_cwksp_alloc_aligned) {\n            /* If unaligned allocations down from a too-large top have left us\n             * unaligned, we need to realign our alloc ptr. Technically, this\n             * can consume space that is unaccounted for in the neededSpace\n             * calculation. However, I believe this can only happen when the\n             * workspace is too large, and specifically when it is too large\n             * by a larger margin than the space that will be consumed. */\n            /* TODO: cleaner, compiler warning friendly way to do this??? */\n            ws->allocStart = (BYTE*)ws->allocStart - ((size_t)ws->allocStart & (sizeof(U32)-1));\n            if (ws->allocStart < ws->tableValidEnd) {\n                ws->tableValidEnd = ws->allocStart;\n            }\n        }\n        ws->phase = phase;\n    }\n}\n\n/**\n * Returns whether this object/buffer/etc was allocated in this workspace.\n */\nMEM_STATIC int ZSTD_cwksp_owns_buffer(const ZSTD_cwksp* ws, const void* ptr) {\n    return (ptr != NULL) && (ws->workspace <= ptr) && (ptr <= ws->workspaceEnd);\n}\n\n/**\n * Internal function. Do not use directly.\n */\nMEM_STATIC void* ZSTD_cwksp_reserve_internal(\n        ZSTD_cwksp* ws, size_t bytes, ZSTD_cwksp_alloc_phase_e phase) {\n    void* alloc;\n    void* bottom = ws->tableEnd;\n    ZSTD_cwksp_internal_advance_phase(ws, phase);\n    alloc = (BYTE *)ws->allocStart - bytes;\n\n#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)\n    /* over-reserve space */\n    alloc = (BYTE *)alloc - 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;\n#endif\n\n    DEBUGLOG(5, \"cwksp: reserving %p %zd bytes, %zd bytes remaining\",\n        alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes);\n    ZSTD_cwksp_assert_internal_consistency(ws);\n    assert(alloc >= bottom);\n    if (alloc < bottom) {\n        DEBUGLOG(4, \"cwksp: alloc failed!\");\n        ws->allocFailed = 1;\n        return NULL;\n    }\n    if (alloc < ws->tableValidEnd) {\n        ws->tableValidEnd = alloc;\n    }\n    ws->allocStart = alloc;\n\n#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)\n    /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on\n     * either size. */\n    alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;\n    __asan_unpoison_memory_region(alloc, bytes);\n#endif\n\n    return alloc;\n}\n\n/**\n * Reserves and returns unaligned memory.\n */\nMEM_STATIC BYTE* ZSTD_cwksp_reserve_buffer(ZSTD_cwksp* ws, size_t bytes) {\n    return (BYTE*)ZSTD_cwksp_reserve_internal(ws, bytes, ZSTD_cwksp_alloc_buffers);\n}\n\n/**\n * Reserves and returns memory sized on and aligned on sizeof(unsigned).\n */\nMEM_STATIC void* ZSTD_cwksp_reserve_aligned(ZSTD_cwksp* ws, size_t bytes) {\n    assert((bytes & (sizeof(U32)-1)) == 0);\n    return ZSTD_cwksp_reserve_internal(ws, ZSTD_cwksp_align(bytes, sizeof(U32)), ZSTD_cwksp_alloc_aligned);\n}\n\n/**\n * Aligned on sizeof(unsigned). These buffers have the special property that\n * their values remain constrained, allowing us to re-use them without\n * memset()-ing them.\n */\nMEM_STATIC void* ZSTD_cwksp_reserve_table(ZSTD_cwksp* ws, size_t bytes) {\n    const ZSTD_cwksp_alloc_phase_e phase = ZSTD_cwksp_alloc_aligned;\n    void* alloc = ws->tableEnd;\n    void* end = (BYTE *)alloc + bytes;\n    void* top = ws->allocStart;\n\n    DEBUGLOG(5, \"cwksp: reserving %p table %zd bytes, %zd bytes remaining\",\n        alloc, bytes, ZSTD_cwksp_available_space(ws) - bytes);\n    assert((bytes & (sizeof(U32)-1)) == 0);\n    ZSTD_cwksp_internal_advance_phase(ws, phase);\n    ZSTD_cwksp_assert_internal_consistency(ws);\n    assert(end <= top);\n    if (end > top) {\n        DEBUGLOG(4, \"cwksp: table alloc failed!\");\n        ws->allocFailed = 1;\n        return NULL;\n    }\n    ws->tableEnd = end;\n\n#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)\n    __asan_unpoison_memory_region(alloc, bytes);\n#endif\n\n    return alloc;\n}\n\n/**\n * Aligned on sizeof(void*).\n */\nMEM_STATIC void* ZSTD_cwksp_reserve_object(ZSTD_cwksp* ws, size_t bytes) {\n    size_t roundedBytes = ZSTD_cwksp_align(bytes, sizeof(void*));\n    void* alloc = ws->objectEnd;\n    void* end = (BYTE*)alloc + roundedBytes;\n\n#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)\n    /* over-reserve space */\n    end = (BYTE *)end + 2 * ZSTD_CWKSP_ASAN_REDZONE_SIZE;\n#endif\n\n    DEBUGLOG(5,\n        \"cwksp: reserving %p object %zd bytes (rounded to %zd), %zd bytes remaining\",\n        alloc, bytes, roundedBytes, ZSTD_cwksp_available_space(ws) - roundedBytes);\n    assert(((size_t)alloc & (sizeof(void*)-1)) == 0);\n    assert((bytes & (sizeof(void*)-1)) == 0);\n    ZSTD_cwksp_assert_internal_consistency(ws);\n    /* we must be in the first phase, no advance is possible */\n    if (ws->phase != ZSTD_cwksp_alloc_objects || end > ws->workspaceEnd) {\n        DEBUGLOG(4, \"cwksp: object alloc failed!\");\n        ws->allocFailed = 1;\n        return NULL;\n    }\n    ws->objectEnd = end;\n    ws->tableEnd = end;\n    ws->tableValidEnd = end;\n\n#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)\n    /* Move alloc so there's ZSTD_CWKSP_ASAN_REDZONE_SIZE unused space on\n     * either size. */\n    alloc = (BYTE *)alloc + ZSTD_CWKSP_ASAN_REDZONE_SIZE;\n    __asan_unpoison_memory_region(alloc, bytes);\n#endif\n\n    return alloc;\n}\n\nMEM_STATIC void ZSTD_cwksp_mark_tables_dirty(ZSTD_cwksp* ws) {\n    DEBUGLOG(4, \"cwksp: ZSTD_cwksp_mark_tables_dirty\");\n\n#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)\n    /* To validate that the table re-use logic is sound, and that we don't\n     * access table space that we haven't cleaned, we re-\"poison\" the table\n     * space every time we mark it dirty. */\n    {\n        size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd;\n        assert(__msan_test_shadow(ws->objectEnd, size) == -1);\n        __msan_poison(ws->objectEnd, size);\n    }\n#endif\n\n    assert(ws->tableValidEnd >= ws->objectEnd);\n    assert(ws->tableValidEnd <= ws->allocStart);\n    ws->tableValidEnd = ws->objectEnd;\n    ZSTD_cwksp_assert_internal_consistency(ws);\n}\n\nMEM_STATIC void ZSTD_cwksp_mark_tables_clean(ZSTD_cwksp* ws) {\n    DEBUGLOG(4, \"cwksp: ZSTD_cwksp_mark_tables_clean\");\n    assert(ws->tableValidEnd >= ws->objectEnd);\n    assert(ws->tableValidEnd <= ws->allocStart);\n    if (ws->tableValidEnd < ws->tableEnd) {\n        ws->tableValidEnd = ws->tableEnd;\n    }\n    ZSTD_cwksp_assert_internal_consistency(ws);\n}\n\n/**\n * Zero the part of the allocated tables not already marked clean.\n */\nMEM_STATIC void ZSTD_cwksp_clean_tables(ZSTD_cwksp* ws) {\n    DEBUGLOG(4, \"cwksp: ZSTD_cwksp_clean_tables\");\n    assert(ws->tableValidEnd >= ws->objectEnd);\n    assert(ws->tableValidEnd <= ws->allocStart);\n    if (ws->tableValidEnd < ws->tableEnd) {\n        memset(ws->tableValidEnd, 0, (BYTE*)ws->tableEnd - (BYTE*)ws->tableValidEnd);\n    }\n    ZSTD_cwksp_mark_tables_clean(ws);\n}\n\n/**\n * Invalidates table allocations.\n * All other allocations remain valid.\n */\nMEM_STATIC void ZSTD_cwksp_clear_tables(ZSTD_cwksp* ws) {\n    DEBUGLOG(4, \"cwksp: clearing tables!\");\n\n#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)\n    {\n        size_t size = (BYTE*)ws->tableValidEnd - (BYTE*)ws->objectEnd;\n        __asan_poison_memory_region(ws->objectEnd, size);\n    }\n#endif\n\n    ws->tableEnd = ws->objectEnd;\n    ZSTD_cwksp_assert_internal_consistency(ws);\n}\n\n/**\n * Invalidates all buffer, aligned, and table allocations.\n * Object allocations remain valid.\n */\nMEM_STATIC void ZSTD_cwksp_clear(ZSTD_cwksp* ws) {\n    DEBUGLOG(4, \"cwksp: clearing!\");\n\n#if defined (MEMORY_SANITIZER) && !defined (ZSTD_MSAN_DONT_POISON_WORKSPACE)\n    /* To validate that the context re-use logic is sound, and that we don't\n     * access stuff that this compression hasn't initialized, we re-\"poison\"\n     * the workspace (or at least the non-static, non-table parts of it)\n     * every time we start a new compression. */\n    {\n        size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->tableValidEnd;\n        __msan_poison(ws->tableValidEnd, size);\n    }\n#endif\n\n#if defined (ADDRESS_SANITIZER) && !defined (ZSTD_ASAN_DONT_POISON_WORKSPACE)\n    {\n        size_t size = (BYTE*)ws->workspaceEnd - (BYTE*)ws->objectEnd;\n        __asan_poison_memory_region(ws->objectEnd, size);\n    }\n#endif\n\n    ws->tableEnd = ws->objectEnd;\n    ws->allocStart = ws->workspaceEnd;\n    ws->allocFailed = 0;\n    if (ws->phase > ZSTD_cwksp_alloc_buffers) {\n        ws->phase = ZSTD_cwksp_alloc_buffers;\n    }\n    ZSTD_cwksp_assert_internal_consistency(ws);\n}\n\n/**\n * The provided workspace takes ownership of the buffer [start, start+size).\n * Any existing values in the workspace are ignored (the previously managed\n * buffer, if present, must be separately freed).\n */\nMEM_STATIC void ZSTD_cwksp_init(ZSTD_cwksp* ws, void* start, size_t size) {\n    DEBUGLOG(4, \"cwksp: init'ing workspace with %zd bytes\", size);\n    assert(((size_t)start & (sizeof(void*)-1)) == 0); /* ensure correct alignment */\n    ws->workspace = start;\n    ws->workspaceEnd = (BYTE*)start + size;\n    ws->objectEnd = ws->workspace;\n    ws->tableValidEnd = ws->objectEnd;\n    ws->phase = ZSTD_cwksp_alloc_objects;\n    ZSTD_cwksp_clear(ws);\n    ws->workspaceOversizedDuration = 0;\n    ZSTD_cwksp_assert_internal_consistency(ws);\n}\n\nMEM_STATIC size_t ZSTD_cwksp_create(ZSTD_cwksp* ws, size_t size, ZSTD_customMem customMem) {\n    void* workspace = ZSTD_malloc(size, customMem);\n    DEBUGLOG(4, \"cwksp: creating new workspace with %zd bytes\", size);\n    RETURN_ERROR_IF(workspace == NULL, memory_allocation);\n    ZSTD_cwksp_init(ws, workspace, size);\n    return 0;\n}\n\nMEM_STATIC void ZSTD_cwksp_free(ZSTD_cwksp* ws, ZSTD_customMem customMem) {\n    void *ptr = ws->workspace;\n    DEBUGLOG(4, \"cwksp: freeing workspace\");\n    memset(ws, 0, sizeof(ZSTD_cwksp));\n    ZSTD_free(ptr, customMem);\n}\n\n/**\n * Moves the management of a workspace from one cwksp to another. The src cwksp\n * is left in an invalid state (src must be re-init()'ed before its used again).\n */\nMEM_STATIC void ZSTD_cwksp_move(ZSTD_cwksp* dst, ZSTD_cwksp* src) {\n    *dst = *src;\n    memset(src, 0, sizeof(ZSTD_cwksp));\n}\n\nMEM_STATIC size_t ZSTD_cwksp_sizeof(const ZSTD_cwksp* ws) {\n    return (size_t)((BYTE*)ws->workspaceEnd - (BYTE*)ws->workspace);\n}\n\nMEM_STATIC int ZSTD_cwksp_reserve_failed(const ZSTD_cwksp* ws) {\n    return ws->allocFailed;\n}\n\n/*-*************************************\n*  Functions Checking Free Space\n***************************************/\n\nMEM_STATIC size_t ZSTD_cwksp_available_space(ZSTD_cwksp* ws) {\n    return (size_t)((BYTE*)ws->allocStart - (BYTE*)ws->tableEnd);\n}\n\nMEM_STATIC int ZSTD_cwksp_check_available(ZSTD_cwksp* ws, size_t additionalNeededSpace) {\n    return ZSTD_cwksp_available_space(ws) >= additionalNeededSpace;\n}\n\nMEM_STATIC int ZSTD_cwksp_check_too_large(ZSTD_cwksp* ws, size_t additionalNeededSpace) {\n    return ZSTD_cwksp_check_available(\n        ws, additionalNeededSpace * ZSTD_WORKSPACETOOLARGE_FACTOR);\n}\n\nMEM_STATIC int ZSTD_cwksp_check_wasteful(ZSTD_cwksp* ws, size_t additionalNeededSpace) {\n    return ZSTD_cwksp_check_too_large(ws, additionalNeededSpace)\n        && ws->workspaceOversizedDuration > ZSTD_WORKSPACETOOLARGE_MAXDURATION;\n}\n\nMEM_STATIC void ZSTD_cwksp_bump_oversized_duration(\n        ZSTD_cwksp* ws, size_t additionalNeededSpace) {\n    if (ZSTD_cwksp_check_too_large(ws, additionalNeededSpace)) {\n        ws->workspaceOversizedDuration++;\n    } else {\n        ws->workspaceOversizedDuration = 0;\n    }\n}\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* ZSTD_CWKSP_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_ddict.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n/* zstd_ddict.c :\n * concentrates all logic that needs to know the internals of ZSTD_DDict object */\n\n/*-*******************************************************\n*  Dependencies\n*********************************************************/\n#include <string.h>      /* memcpy, memmove, memset */\n#include \"cpu.h\"         /* bmi2 */\n#include \"mem.h\"         /* low level memory routines */\n#define FSE_STATIC_LINKING_ONLY\n#include \"fse.h\"\n#define HUF_STATIC_LINKING_ONLY\n#include \"huf.h\"\n#include \"zstd_decompress_internal.h\"\n#include \"zstd_ddict.h\"\n\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)\n#  include \"zstd_legacy.h\"\n#endif\n\n\n\n/*-*******************************************************\n*  Types\n*********************************************************/\nstruct ZSTD_DDict_s {\n    void* dictBuffer;\n    const void* dictContent;\n    size_t dictSize;\n    ZSTD_entropyDTables_t entropy;\n    U32 dictID;\n    U32 entropyPresent;\n    ZSTD_customMem cMem;\n};  /* typedef'd to ZSTD_DDict within \"zstd.h\" */\n\nconst void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict)\n{\n    assert(ddict != NULL);\n    return ddict->dictContent;\n}\n\nsize_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict)\n{\n    assert(ddict != NULL);\n    return ddict->dictSize;\n}\n\nvoid ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)\n{\n    DEBUGLOG(4, \"ZSTD_copyDDictParameters\");\n    assert(dctx != NULL);\n    assert(ddict != NULL);\n    dctx->dictID = ddict->dictID;\n    dctx->prefixStart = ddict->dictContent;\n    dctx->virtualStart = ddict->dictContent;\n    dctx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;\n    dctx->previousDstEnd = dctx->dictEnd;\n    if (ddict->entropyPresent) {\n        dctx->litEntropy = 1;\n        dctx->fseEntropy = 1;\n        dctx->LLTptr = ddict->entropy.LLTable;\n        dctx->MLTptr = ddict->entropy.MLTable;\n        dctx->OFTptr = ddict->entropy.OFTable;\n        dctx->HUFptr = ddict->entropy.hufTable;\n        dctx->entropy.rep[0] = ddict->entropy.rep[0];\n        dctx->entropy.rep[1] = ddict->entropy.rep[1];\n        dctx->entropy.rep[2] = ddict->entropy.rep[2];\n    } else {\n        dctx->litEntropy = 0;\n        dctx->fseEntropy = 0;\n    }\n}\n\n\nstatic size_t\nZSTD_loadEntropy_intoDDict(ZSTD_DDict* ddict,\n                           ZSTD_dictContentType_e dictContentType)\n{\n    ddict->dictID = 0;\n    ddict->entropyPresent = 0;\n    if (dictContentType == ZSTD_dct_rawContent) return 0;\n\n    if (ddict->dictSize < 8) {\n        if (dictContentType == ZSTD_dct_fullDict)\n            return ERROR(dictionary_corrupted);   /* only accept specified dictionaries */\n        return 0;   /* pure content mode */\n    }\n    {   U32 const magic = MEM_readLE32(ddict->dictContent);\n        if (magic != ZSTD_MAGIC_DICTIONARY) {\n            if (dictContentType == ZSTD_dct_fullDict)\n                return ERROR(dictionary_corrupted);   /* only accept specified dictionaries */\n            return 0;   /* pure content mode */\n        }\n    }\n    ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + ZSTD_FRAMEIDSIZE);\n\n    /* load entropy tables */\n    RETURN_ERROR_IF(ZSTD_isError(ZSTD_loadDEntropy(\n            &ddict->entropy, ddict->dictContent, ddict->dictSize)),\n        dictionary_corrupted);\n    ddict->entropyPresent = 1;\n    return 0;\n}\n\n\nstatic size_t ZSTD_initDDict_internal(ZSTD_DDict* ddict,\n                                      const void* dict, size_t dictSize,\n                                      ZSTD_dictLoadMethod_e dictLoadMethod,\n                                      ZSTD_dictContentType_e dictContentType)\n{\n    if ((dictLoadMethod == ZSTD_dlm_byRef) || (!dict) || (!dictSize)) {\n        ddict->dictBuffer = NULL;\n        ddict->dictContent = dict;\n        if (!dict) dictSize = 0;\n    } else {\n        void* const internalBuffer = ZSTD_malloc(dictSize, ddict->cMem);\n        ddict->dictBuffer = internalBuffer;\n        ddict->dictContent = internalBuffer;\n        if (!internalBuffer) return ERROR(memory_allocation);\n        memcpy(internalBuffer, dict, dictSize);\n    }\n    ddict->dictSize = dictSize;\n    ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */\n\n    /* parse dictionary content */\n    FORWARD_IF_ERROR( ZSTD_loadEntropy_intoDDict(ddict, dictContentType) );\n\n    return 0;\n}\n\nZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,\n                                      ZSTD_dictLoadMethod_e dictLoadMethod,\n                                      ZSTD_dictContentType_e dictContentType,\n                                      ZSTD_customMem customMem)\n{\n    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;\n\n    {   ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);\n        if (ddict == NULL) return NULL;\n        ddict->cMem = customMem;\n        {   size_t const initResult = ZSTD_initDDict_internal(ddict,\n                                            dict, dictSize,\n                                            dictLoadMethod, dictContentType);\n            if (ZSTD_isError(initResult)) {\n                ZSTD_freeDDict(ddict);\n                return NULL;\n        }   }\n        return ddict;\n    }\n}\n\n/*! ZSTD_createDDict() :\n*   Create a digested dictionary, to start decompression without startup delay.\n*   `dict` content is copied inside DDict.\n*   Consequently, `dict` can be released after `ZSTD_DDict` creation */\nZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)\n{\n    ZSTD_customMem const allocator = { NULL, NULL, NULL };\n    return ZSTD_createDDict_advanced(dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto, allocator);\n}\n\n/*! ZSTD_createDDict_byReference() :\n *  Create a digested dictionary, to start decompression without startup delay.\n *  Dictionary content is simply referenced, it will be accessed during decompression.\n *  Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */\nZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)\n{\n    ZSTD_customMem const allocator = { NULL, NULL, NULL };\n    return ZSTD_createDDict_advanced(dictBuffer, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto, allocator);\n}\n\n\nconst ZSTD_DDict* ZSTD_initStaticDDict(\n                                void* sBuffer, size_t sBufferSize,\n                                const void* dict, size_t dictSize,\n                                ZSTD_dictLoadMethod_e dictLoadMethod,\n                                ZSTD_dictContentType_e dictContentType)\n{\n    size_t const neededSpace = sizeof(ZSTD_DDict)\n                             + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);\n    ZSTD_DDict* const ddict = (ZSTD_DDict*)sBuffer;\n    assert(sBuffer != NULL);\n    assert(dict != NULL);\n    if ((size_t)sBuffer & 7) return NULL;   /* 8-aligned */\n    if (sBufferSize < neededSpace) return NULL;\n    if (dictLoadMethod == ZSTD_dlm_byCopy) {\n        memcpy(ddict+1, dict, dictSize);  /* local copy */\n        dict = ddict+1;\n    }\n    if (ZSTD_isError( ZSTD_initDDict_internal(ddict,\n                                              dict, dictSize,\n                                              ZSTD_dlm_byRef, dictContentType) ))\n        return NULL;\n    return ddict;\n}\n\n\nsize_t ZSTD_freeDDict(ZSTD_DDict* ddict)\n{\n    if (ddict==NULL) return 0;   /* support free on NULL */\n    {   ZSTD_customMem const cMem = ddict->cMem;\n        ZSTD_free(ddict->dictBuffer, cMem);\n        ZSTD_free(ddict, cMem);\n        return 0;\n    }\n}\n\n/*! ZSTD_estimateDDictSize() :\n *  Estimate amount of memory that will be needed to create a dictionary for decompression.\n *  Note : dictionary created by reference using ZSTD_dlm_byRef are smaller */\nsize_t ZSTD_estimateDDictSize(size_t dictSize, ZSTD_dictLoadMethod_e dictLoadMethod)\n{\n    return sizeof(ZSTD_DDict) + (dictLoadMethod == ZSTD_dlm_byRef ? 0 : dictSize);\n}\n\nsize_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)\n{\n    if (ddict==NULL) return 0;   /* support sizeof on NULL */\n    return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ;\n}\n\n/*! ZSTD_getDictID_fromDDict() :\n *  Provides the dictID of the dictionary loaded into `ddict`.\n *  If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.\n *  Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */\nunsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)\n{\n    if (ddict==NULL) return 0;\n    return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize);\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_ddict.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n\n#ifndef ZSTD_DDICT_H\n#define ZSTD_DDICT_H\n\n/*-*******************************************************\n *  Dependencies\n *********************************************************/\n#include <stddef.h>   /* size_t */\n#include \"zstd.h\"     /* ZSTD_DDict, and several public functions */\n\n\n/*-*******************************************************\n *  Interface\n *********************************************************/\n\n/* note: several prototypes are already published in `zstd.h` :\n * ZSTD_createDDict()\n * ZSTD_createDDict_byReference()\n * ZSTD_createDDict_advanced()\n * ZSTD_freeDDict()\n * ZSTD_initStaticDDict()\n * ZSTD_sizeof_DDict()\n * ZSTD_estimateDDictSize()\n * ZSTD_getDictID_fromDict()\n */\n\nconst void* ZSTD_DDict_dictContent(const ZSTD_DDict* ddict);\nsize_t ZSTD_DDict_dictSize(const ZSTD_DDict* ddict);\n\nvoid ZSTD_copyDDictParameters(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict);\n\n\n\n#endif /* ZSTD_DDICT_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_decompress.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n\n/* ***************************************************************\n*  Tuning parameters\n*****************************************************************/\n/*!\n * HEAPMODE :\n * Select how default decompression function ZSTD_decompress() allocates its context,\n * on stack (0), or into heap (1, default; requires malloc()).\n * Note that functions with explicit context such as ZSTD_decompressDCtx() are unaffected.\n */\n#ifndef ZSTD_HEAPMODE\n#  define ZSTD_HEAPMODE 1\n#endif\n\n/*!\n*  LEGACY_SUPPORT :\n*  if set to 1+, ZSTD_decompress() can decode older formats (v0.1+)\n*/\n#ifndef ZSTD_LEGACY_SUPPORT\n#  define ZSTD_LEGACY_SUPPORT 0\n#endif\n\n/*!\n *  MAXWINDOWSIZE_DEFAULT :\n *  maximum window size accepted by DStream __by default__.\n *  Frames requiring more memory will be rejected.\n *  It's possible to set a different limit using ZSTD_DCtx_setMaxWindowSize().\n */\n#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT\n#  define ZSTD_MAXWINDOWSIZE_DEFAULT (((U32)1 << ZSTD_WINDOWLOG_LIMIT_DEFAULT) + 1)\n#endif\n\n/*!\n *  NO_FORWARD_PROGRESS_MAX :\n *  maximum allowed nb of calls to ZSTD_decompressStream()\n *  without any forward progress\n *  (defined as: no byte read from input, and no byte flushed to output)\n *  before triggering an error.\n */\n#ifndef ZSTD_NO_FORWARD_PROGRESS_MAX\n#  define ZSTD_NO_FORWARD_PROGRESS_MAX 16\n#endif\n\n\n/*-*******************************************************\n*  Dependencies\n*********************************************************/\n#include <string.h>      /* memcpy, memmove, memset */\n#include \"cpu.h\"         /* bmi2 */\n#include \"mem.h\"         /* low level memory routines */\n#define FSE_STATIC_LINKING_ONLY\n#include \"fse.h\"\n#define HUF_STATIC_LINKING_ONLY\n#include \"huf.h\"\n#include \"zstd_internal.h\"  /* blockProperties_t */\n#include \"zstd_decompress_internal.h\"   /* ZSTD_DCtx */\n#include \"zstd_ddict.h\"  /* ZSTD_DDictDictContent */\n#include \"zstd_decompress_block.h\"   /* ZSTD_decompressBlock_internal */\n\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)\n#  include \"zstd_legacy.h\"\n#endif\n\n\n/*-*************************************************************\n*   Context management\n***************************************************************/\nsize_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx)\n{\n    if (dctx==NULL) return 0;   /* support sizeof NULL */\n    return sizeof(*dctx)\n           + ZSTD_sizeof_DDict(dctx->ddictLocal)\n           + dctx->inBuffSize + dctx->outBuffSize;\n}\n\nsize_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }\n\n\nstatic size_t ZSTD_startingInputLength(ZSTD_format_e format)\n{\n    size_t const startingInputLength = ZSTD_FRAMEHEADERSIZE_PREFIX(format);\n    /* only supports formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless */\n    assert( (format == ZSTD_f_zstd1) || (format == ZSTD_f_zstd1_magicless) );\n    return startingInputLength;\n}\n\nstatic void ZSTD_initDCtx_internal(ZSTD_DCtx* dctx)\n{\n    dctx->format = ZSTD_f_zstd1;  /* ZSTD_decompressBegin() invokes ZSTD_startingInputLength() with argument dctx->format */\n    dctx->staticSize  = 0;\n    dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;\n    dctx->ddict       = NULL;\n    dctx->ddictLocal  = NULL;\n    dctx->dictEnd     = NULL;\n    dctx->ddictIsCold = 0;\n    dctx->dictUses = ZSTD_dont_use;\n    dctx->inBuff      = NULL;\n    dctx->inBuffSize  = 0;\n    dctx->outBuffSize = 0;\n    dctx->streamStage = zdss_init;\n    dctx->legacyContext = NULL;\n    dctx->previousLegacyVersion = 0;\n    dctx->noForwardProgress = 0;\n    dctx->bmi2 = ZSTD_cpuid_bmi2(ZSTD_cpuid());\n}\n\nZSTD_DCtx* ZSTD_initStaticDCtx(void *workspace, size_t workspaceSize)\n{\n    ZSTD_DCtx* const dctx = (ZSTD_DCtx*) workspace;\n\n    if ((size_t)workspace & 7) return NULL;  /* 8-aligned */\n    if (workspaceSize < sizeof(ZSTD_DCtx)) return NULL;  /* minimum size */\n\n    ZSTD_initDCtx_internal(dctx);\n    dctx->staticSize = workspaceSize;\n    dctx->inBuff = (char*)(dctx+1);\n    return dctx;\n}\n\nZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)\n{\n    if (!customMem.customAlloc ^ !customMem.customFree) return NULL;\n\n    {   ZSTD_DCtx* const dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(*dctx), customMem);\n        if (!dctx) return NULL;\n        dctx->customMem = customMem;\n        ZSTD_initDCtx_internal(dctx);\n        return dctx;\n    }\n}\n\nZSTD_DCtx* ZSTD_createDCtx(void)\n{\n    DEBUGLOG(3, \"ZSTD_createDCtx\");\n    return ZSTD_createDCtx_advanced(ZSTD_defaultCMem);\n}\n\nstatic void ZSTD_clearDict(ZSTD_DCtx* dctx)\n{\n    ZSTD_freeDDict(dctx->ddictLocal);\n    dctx->ddictLocal = NULL;\n    dctx->ddict = NULL;\n    dctx->dictUses = ZSTD_dont_use;\n}\n\nsize_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)\n{\n    if (dctx==NULL) return 0;   /* support free on NULL */\n    RETURN_ERROR_IF(dctx->staticSize, memory_allocation, \"not compatible with static DCtx\");\n    {   ZSTD_customMem const cMem = dctx->customMem;\n        ZSTD_clearDict(dctx);\n        ZSTD_free(dctx->inBuff, cMem);\n        dctx->inBuff = NULL;\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)\n        if (dctx->legacyContext)\n            ZSTD_freeLegacyStreamContext(dctx->legacyContext, dctx->previousLegacyVersion);\n#endif\n        ZSTD_free(dctx, cMem);\n        return 0;\n    }\n}\n\n/* no longer useful */\nvoid ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)\n{\n    size_t const toCopy = (size_t)((char*)(&dstDCtx->inBuff) - (char*)dstDCtx);\n    memcpy(dstDCtx, srcDCtx, toCopy);  /* no need to copy workspace */\n}\n\n\n/*-*************************************************************\n *   Frame header decoding\n ***************************************************************/\n\n/*! ZSTD_isFrame() :\n *  Tells if the content of `buffer` starts with a valid Frame Identifier.\n *  Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.\n *  Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.\n *  Note 3 : Skippable Frame Identifiers are considered valid. */\nunsigned ZSTD_isFrame(const void* buffer, size_t size)\n{\n    if (size < ZSTD_FRAMEIDSIZE) return 0;\n    {   U32 const magic = MEM_readLE32(buffer);\n        if (magic == ZSTD_MAGICNUMBER) return 1;\n        if ((magic & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) return 1;\n    }\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)\n    if (ZSTD_isLegacy(buffer, size)) return 1;\n#endif\n    return 0;\n}\n\n/** ZSTD_frameHeaderSize_internal() :\n *  srcSize must be large enough to reach header size fields.\n *  note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless.\n * @return : size of the Frame Header\n *           or an error code, which can be tested with ZSTD_isError() */\nstatic size_t ZSTD_frameHeaderSize_internal(const void* src, size_t srcSize, ZSTD_format_e format)\n{\n    size_t const minInputSize = ZSTD_startingInputLength(format);\n    RETURN_ERROR_IF(srcSize < minInputSize, srcSize_wrong);\n\n    {   BYTE const fhd = ((const BYTE*)src)[minInputSize-1];\n        U32 const dictID= fhd & 3;\n        U32 const singleSegment = (fhd >> 5) & 1;\n        U32 const fcsId = fhd >> 6;\n        return minInputSize + !singleSegment\n             + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]\n             + (singleSegment && !fcsId);\n    }\n}\n\n/** ZSTD_frameHeaderSize() :\n *  srcSize must be >= ZSTD_frameHeaderSize_prefix.\n * @return : size of the Frame Header,\n *           or an error code (if srcSize is too small) */\nsize_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)\n{\n    return ZSTD_frameHeaderSize_internal(src, srcSize, ZSTD_f_zstd1);\n}\n\n\n/** ZSTD_getFrameHeader_advanced() :\n *  decode Frame Header, or require larger `srcSize`.\n *  note : only works for formats ZSTD_f_zstd1 and ZSTD_f_zstd1_magicless\n * @return : 0, `zfhPtr` is correctly filled,\n *          >0, `srcSize` is too small, value is wanted `srcSize` amount,\n *           or an error code, which can be tested using ZSTD_isError() */\nsize_t ZSTD_getFrameHeader_advanced(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize, ZSTD_format_e format)\n{\n    const BYTE* ip = (const BYTE*)src;\n    size_t const minInputSize = ZSTD_startingInputLength(format);\n\n    memset(zfhPtr, 0, sizeof(*zfhPtr));   /* not strictly necessary, but static analyzer do not understand that zfhPtr is only going to be read only if return value is zero, since they are 2 different signals */\n    if (srcSize < minInputSize) return minInputSize;\n    RETURN_ERROR_IF(src==NULL, GENERIC, \"invalid parameter\");\n\n    if ( (format != ZSTD_f_zstd1_magicless)\n      && (MEM_readLE32(src) != ZSTD_MAGICNUMBER) ) {\n        if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {\n            /* skippable frame */\n            if (srcSize < ZSTD_SKIPPABLEHEADERSIZE)\n                return ZSTD_SKIPPABLEHEADERSIZE; /* magic number + frame length */\n            memset(zfhPtr, 0, sizeof(*zfhPtr));\n            zfhPtr->frameContentSize = MEM_readLE32((const char *)src + ZSTD_FRAMEIDSIZE);\n            zfhPtr->frameType = ZSTD_skippableFrame;\n            return 0;\n        }\n        RETURN_ERROR(prefix_unknown);\n    }\n\n    /* ensure there is enough `srcSize` to fully read/decode frame header */\n    {   size_t const fhsize = ZSTD_frameHeaderSize_internal(src, srcSize, format);\n        if (srcSize < fhsize) return fhsize;\n        zfhPtr->headerSize = (U32)fhsize;\n    }\n\n    {   BYTE const fhdByte = ip[minInputSize-1];\n        size_t pos = minInputSize;\n        U32 const dictIDSizeCode = fhdByte&3;\n        U32 const checksumFlag = (fhdByte>>2)&1;\n        U32 const singleSegment = (fhdByte>>5)&1;\n        U32 const fcsID = fhdByte>>6;\n        U64 windowSize = 0;\n        U32 dictID = 0;\n        U64 frameContentSize = ZSTD_CONTENTSIZE_UNKNOWN;\n        RETURN_ERROR_IF((fhdByte & 0x08) != 0, frameParameter_unsupported,\n                        \"reserved bits, must be zero\");\n\n        if (!singleSegment) {\n            BYTE const wlByte = ip[pos++];\n            U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;\n            RETURN_ERROR_IF(windowLog > ZSTD_WINDOWLOG_MAX, frameParameter_windowTooLarge);\n            windowSize = (1ULL << windowLog);\n            windowSize += (windowSize >> 3) * (wlByte&7);\n        }\n        switch(dictIDSizeCode)\n        {\n            default: assert(0);  /* impossible */\n            case 0 : break;\n            case 1 : dictID = ip[pos]; pos++; break;\n            case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;\n            case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;\n        }\n        switch(fcsID)\n        {\n            default: assert(0);  /* impossible */\n            case 0 : if (singleSegment) frameContentSize = ip[pos]; break;\n            case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;\n            case 2 : frameContentSize = MEM_readLE32(ip+pos); break;\n            case 3 : frameContentSize = MEM_readLE64(ip+pos); break;\n        }\n        if (singleSegment) windowSize = frameContentSize;\n\n        zfhPtr->frameType = ZSTD_frame;\n        zfhPtr->frameContentSize = frameContentSize;\n        zfhPtr->windowSize = windowSize;\n        zfhPtr->blockSizeMax = (unsigned) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);\n        zfhPtr->dictID = dictID;\n        zfhPtr->checksumFlag = checksumFlag;\n    }\n    return 0;\n}\n\n/** ZSTD_getFrameHeader() :\n *  decode Frame Header, or require larger `srcSize`.\n *  note : this function does not consume input, it only reads it.\n * @return : 0, `zfhPtr` is correctly filled,\n *          >0, `srcSize` is too small, value is wanted `srcSize` amount,\n *           or an error code, which can be tested using ZSTD_isError() */\nsize_t ZSTD_getFrameHeader(ZSTD_frameHeader* zfhPtr, const void* src, size_t srcSize)\n{\n    return ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, ZSTD_f_zstd1);\n}\n\n\n/** ZSTD_getFrameContentSize() :\n *  compatible with legacy mode\n * @return : decompressed size of the single frame pointed to be `src` if known, otherwise\n *         - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined\n *         - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */\nunsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)\n{\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)\n    if (ZSTD_isLegacy(src, srcSize)) {\n        unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize);\n        return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret;\n    }\n#endif\n    {   ZSTD_frameHeader zfh;\n        if (ZSTD_getFrameHeader(&zfh, src, srcSize) != 0)\n            return ZSTD_CONTENTSIZE_ERROR;\n        if (zfh.frameType == ZSTD_skippableFrame) {\n            return 0;\n        } else {\n            return zfh.frameContentSize;\n    }   }\n}\n\nstatic size_t readSkippableFrameSize(void const* src, size_t srcSize)\n{\n    size_t const skippableHeaderSize = ZSTD_SKIPPABLEHEADERSIZE;\n    U32 sizeU32;\n\n    RETURN_ERROR_IF(srcSize < ZSTD_SKIPPABLEHEADERSIZE, srcSize_wrong);\n\n    sizeU32 = MEM_readLE32((BYTE const*)src + ZSTD_FRAMEIDSIZE);\n    RETURN_ERROR_IF((U32)(sizeU32 + ZSTD_SKIPPABLEHEADERSIZE) < sizeU32,\n                    frameParameter_unsupported);\n    {\n        size_t const skippableSize = skippableHeaderSize + sizeU32;\n        RETURN_ERROR_IF(skippableSize > srcSize, srcSize_wrong);\n        return skippableSize;\n    }\n}\n\n/** ZSTD_findDecompressedSize() :\n *  compatible with legacy mode\n *  `srcSize` must be the exact length of some number of ZSTD compressed and/or\n *      skippable frames\n *  @return : decompressed size of the frames contained */\nunsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)\n{\n    unsigned long long totalDstSize = 0;\n\n    while (srcSize >= ZSTD_startingInputLength(ZSTD_f_zstd1)) {\n        U32 const magicNumber = MEM_readLE32(src);\n\n        if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {\n            size_t const skippableSize = readSkippableFrameSize(src, srcSize);\n            if (ZSTD_isError(skippableSize)) {\n                return ZSTD_CONTENTSIZE_ERROR;\n            }\n            assert(skippableSize <= srcSize);\n\n            src = (const BYTE *)src + skippableSize;\n            srcSize -= skippableSize;\n            continue;\n        }\n\n        {   unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);\n            if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;\n\n            /* check for overflow */\n            if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;\n            totalDstSize += ret;\n        }\n        {   size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);\n            if (ZSTD_isError(frameSrcSize)) {\n                return ZSTD_CONTENTSIZE_ERROR;\n            }\n\n            src = (const BYTE *)src + frameSrcSize;\n            srcSize -= frameSrcSize;\n        }\n    }  /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */\n\n    if (srcSize) return ZSTD_CONTENTSIZE_ERROR;\n\n    return totalDstSize;\n}\n\n/** ZSTD_getDecompressedSize() :\n *  compatible with legacy mode\n * @return : decompressed size if known, 0 otherwise\n             note : 0 can mean any of the following :\n                   - frame content is empty\n                   - decompressed size field is not present in frame header\n                   - frame header unknown / not supported\n                   - frame header not complete (`srcSize` too small) */\nunsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)\n{\n    unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);\n    ZSTD_STATIC_ASSERT(ZSTD_CONTENTSIZE_ERROR < ZSTD_CONTENTSIZE_UNKNOWN);\n    return (ret >= ZSTD_CONTENTSIZE_ERROR) ? 0 : ret;\n}\n\n\n/** ZSTD_decodeFrameHeader() :\n * `headerSize` must be the size provided by ZSTD_frameHeaderSize().\n * @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */\nstatic size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)\n{\n    size_t const result = ZSTD_getFrameHeader_advanced(&(dctx->fParams), src, headerSize, dctx->format);\n    if (ZSTD_isError(result)) return result;    /* invalid header */\n    RETURN_ERROR_IF(result>0, srcSize_wrong, \"headerSize too small\");\n#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION\n    /* Skip the dictID check in fuzzing mode, because it makes the search\n     * harder.\n     */\n    RETURN_ERROR_IF(dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID),\n                    dictionary_wrong);\n#endif\n    if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);\n    return 0;\n}\n\nstatic ZSTD_frameSizeInfo ZSTD_errorFrameSizeInfo(size_t ret)\n{\n    ZSTD_frameSizeInfo frameSizeInfo;\n    frameSizeInfo.compressedSize = ret;\n    frameSizeInfo.decompressedBound = ZSTD_CONTENTSIZE_ERROR;\n    return frameSizeInfo;\n}\n\nstatic ZSTD_frameSizeInfo ZSTD_findFrameSizeInfo(const void* src, size_t srcSize)\n{\n    ZSTD_frameSizeInfo frameSizeInfo;\n    memset(&frameSizeInfo, 0, sizeof(ZSTD_frameSizeInfo));\n\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)\n    if (ZSTD_isLegacy(src, srcSize))\n        return ZSTD_findFrameSizeInfoLegacy(src, srcSize);\n#endif\n\n    if ((srcSize >= ZSTD_SKIPPABLEHEADERSIZE)\n        && (MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {\n        frameSizeInfo.compressedSize = readSkippableFrameSize(src, srcSize);\n        assert(ZSTD_isError(frameSizeInfo.compressedSize) ||\n               frameSizeInfo.compressedSize <= srcSize);\n        return frameSizeInfo;\n    } else {\n        const BYTE* ip = (const BYTE*)src;\n        const BYTE* const ipstart = ip;\n        size_t remainingSize = srcSize;\n        size_t nbBlocks = 0;\n        ZSTD_frameHeader zfh;\n\n        /* Extract Frame Header */\n        {   size_t const ret = ZSTD_getFrameHeader(&zfh, src, srcSize);\n            if (ZSTD_isError(ret))\n                return ZSTD_errorFrameSizeInfo(ret);\n            if (ret > 0)\n                return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));\n        }\n\n        ip += zfh.headerSize;\n        remainingSize -= zfh.headerSize;\n\n        /* Iterate over each block */\n        while (1) {\n            blockProperties_t blockProperties;\n            size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);\n            if (ZSTD_isError(cBlockSize))\n                return ZSTD_errorFrameSizeInfo(cBlockSize);\n\n            if (ZSTD_blockHeaderSize + cBlockSize > remainingSize)\n                return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));\n\n            ip += ZSTD_blockHeaderSize + cBlockSize;\n            remainingSize -= ZSTD_blockHeaderSize + cBlockSize;\n            nbBlocks++;\n\n            if (blockProperties.lastBlock) break;\n        }\n\n        /* Final frame content checksum */\n        if (zfh.checksumFlag) {\n            if (remainingSize < 4)\n                return ZSTD_errorFrameSizeInfo(ERROR(srcSize_wrong));\n            ip += 4;\n        }\n\n        frameSizeInfo.compressedSize = ip - ipstart;\n        frameSizeInfo.decompressedBound = (zfh.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN)\n                                        ? zfh.frameContentSize\n                                        : nbBlocks * zfh.blockSizeMax;\n        return frameSizeInfo;\n    }\n}\n\n/** ZSTD_findFrameCompressedSize() :\n *  compatible with legacy mode\n *  `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame\n *  `srcSize` must be at least as large as the frame contained\n *  @return : the compressed size of the frame starting at `src` */\nsize_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)\n{\n    ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);\n    return frameSizeInfo.compressedSize;\n}\n\n/** ZSTD_decompressBound() :\n *  compatible with legacy mode\n *  `src` must point to the start of a ZSTD frame or a skippeable frame\n *  `srcSize` must be at least as large as the frame contained\n *  @return : the maximum decompressed size of the compressed source\n */\nunsigned long long ZSTD_decompressBound(const void* src, size_t srcSize)\n{\n    unsigned long long bound = 0;\n    /* Iterate over each frame */\n    while (srcSize > 0) {\n        ZSTD_frameSizeInfo const frameSizeInfo = ZSTD_findFrameSizeInfo(src, srcSize);\n        size_t const compressedSize = frameSizeInfo.compressedSize;\n        unsigned long long const decompressedBound = frameSizeInfo.decompressedBound;\n        if (ZSTD_isError(compressedSize) || decompressedBound == ZSTD_CONTENTSIZE_ERROR)\n            return ZSTD_CONTENTSIZE_ERROR;\n        assert(srcSize >= compressedSize);\n        src = (const BYTE*)src + compressedSize;\n        srcSize -= compressedSize;\n        bound += decompressedBound;\n    }\n    return bound;\n}\n\n\n/*-*************************************************************\n *   Frame decoding\n ***************************************************************/\n\n\nvoid ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)\n{\n    if (dst != dctx->previousDstEnd) {   /* not contiguous */\n        dctx->dictEnd = dctx->previousDstEnd;\n        dctx->virtualStart = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));\n        dctx->prefixStart = dst;\n        dctx->previousDstEnd = dst;\n    }\n}\n\n/** ZSTD_insertBlock() :\n *  insert `src` block into `dctx` history. Useful to track uncompressed blocks. */\nsize_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)\n{\n    DEBUGLOG(5, \"ZSTD_insertBlock: %u bytes\", (unsigned)blockSize);\n    ZSTD_checkContinuity(dctx, blockStart);\n    dctx->previousDstEnd = (const char*)blockStart + blockSize;\n    return blockSize;\n}\n\n\nstatic size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,\n                          const void* src, size_t srcSize)\n{\n    DEBUGLOG(5, \"ZSTD_copyRawBlock\");\n    if (dst == NULL) {\n        if (srcSize == 0) return 0;\n        RETURN_ERROR(dstBuffer_null);\n    }\n    RETURN_ERROR_IF(srcSize > dstCapacity, dstSize_tooSmall);\n    memcpy(dst, src, srcSize);\n    return srcSize;\n}\n\nstatic size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,\n                               BYTE b,\n                               size_t regenSize)\n{\n    if (dst == NULL) {\n        if (regenSize == 0) return 0;\n        RETURN_ERROR(dstBuffer_null);\n    }\n    RETURN_ERROR_IF(regenSize > dstCapacity, dstSize_tooSmall);\n    memset(dst, b, regenSize);\n    return regenSize;\n}\n\n\n/*! ZSTD_decompressFrame() :\n * @dctx must be properly initialized\n *  will update *srcPtr and *srcSizePtr,\n *  to make *srcPtr progress by one frame. */\nstatic size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,\n                                   void* dst, size_t dstCapacity,\n                             const void** srcPtr, size_t *srcSizePtr)\n{\n    const BYTE* ip = (const BYTE*)(*srcPtr);\n    BYTE* const ostart = (BYTE* const)dst;\n    BYTE* const oend = ostart + dstCapacity;\n    BYTE* op = ostart;\n    size_t remainingSrcSize = *srcSizePtr;\n\n    DEBUGLOG(4, \"ZSTD_decompressFrame (srcSize:%i)\", (int)*srcSizePtr);\n\n    /* check */\n    RETURN_ERROR_IF(\n        remainingSrcSize < ZSTD_FRAMEHEADERSIZE_MIN(dctx->format)+ZSTD_blockHeaderSize,\n        srcSize_wrong);\n\n    /* Frame Header */\n    {   size_t const frameHeaderSize = ZSTD_frameHeaderSize_internal(\n                ip, ZSTD_FRAMEHEADERSIZE_PREFIX(dctx->format), dctx->format);\n        if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;\n        RETURN_ERROR_IF(remainingSrcSize < frameHeaderSize+ZSTD_blockHeaderSize,\n                        srcSize_wrong);\n        FORWARD_IF_ERROR( ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize) );\n        ip += frameHeaderSize; remainingSrcSize -= frameHeaderSize;\n    }\n\n    /* Loop on each block */\n    while (1) {\n        size_t decodedSize;\n        blockProperties_t blockProperties;\n        size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSrcSize, &blockProperties);\n        if (ZSTD_isError(cBlockSize)) return cBlockSize;\n\n        ip += ZSTD_blockHeaderSize;\n        remainingSrcSize -= ZSTD_blockHeaderSize;\n        RETURN_ERROR_IF(cBlockSize > remainingSrcSize, srcSize_wrong);\n\n        switch(blockProperties.blockType)\n        {\n        case bt_compressed:\n            decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize, /* frame */ 1);\n            break;\n        case bt_raw :\n            decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);\n            break;\n        case bt_rle :\n            decodedSize = ZSTD_setRleBlock(op, oend-op, *ip, blockProperties.origSize);\n            break;\n        case bt_reserved :\n        default:\n            RETURN_ERROR(corruption_detected);\n        }\n\n        if (ZSTD_isError(decodedSize)) return decodedSize;\n        if (dctx->fParams.checksumFlag)\n            XXH64_update(&dctx->xxhState, op, decodedSize);\n        op += decodedSize;\n        ip += cBlockSize;\n        remainingSrcSize -= cBlockSize;\n        if (blockProperties.lastBlock) break;\n    }\n\n    if (dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN) {\n        RETURN_ERROR_IF((U64)(op-ostart) != dctx->fParams.frameContentSize,\n                        corruption_detected);\n    }\n    if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */\n        U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);\n        U32 checkRead;\n        RETURN_ERROR_IF(remainingSrcSize<4, checksum_wrong);\n        checkRead = MEM_readLE32(ip);\n        RETURN_ERROR_IF(checkRead != checkCalc, checksum_wrong);\n        ip += 4;\n        remainingSrcSize -= 4;\n    }\n\n    /* Allow caller to get size read */\n    *srcPtr = ip;\n    *srcSizePtr = remainingSrcSize;\n    return op-ostart;\n}\n\nstatic size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,\n                                        void* dst, size_t dstCapacity,\n                                  const void* src, size_t srcSize,\n                                  const void* dict, size_t dictSize,\n                                  const ZSTD_DDict* ddict)\n{\n    void* const dststart = dst;\n    int moreThan1Frame = 0;\n\n    DEBUGLOG(5, \"ZSTD_decompressMultiFrame\");\n    assert(dict==NULL || ddict==NULL);  /* either dict or ddict set, not both */\n\n    if (ddict) {\n        dict = ZSTD_DDict_dictContent(ddict);\n        dictSize = ZSTD_DDict_dictSize(ddict);\n    }\n\n    while (srcSize >= ZSTD_startingInputLength(dctx->format)) {\n\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)\n        if (ZSTD_isLegacy(src, srcSize)) {\n            size_t decodedSize;\n            size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);\n            if (ZSTD_isError(frameSize)) return frameSize;\n            RETURN_ERROR_IF(dctx->staticSize, memory_allocation,\n                \"legacy support is not compatible with static dctx\");\n\n            decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);\n            if (ZSTD_isError(decodedSize)) return decodedSize;\n\n            assert(decodedSize <=- dstCapacity);\n            dst = (BYTE*)dst + decodedSize;\n            dstCapacity -= decodedSize;\n\n            src = (const BYTE*)src + frameSize;\n            srcSize -= frameSize;\n\n            continue;\n        }\n#endif\n\n        {   U32 const magicNumber = MEM_readLE32(src);\n            DEBUGLOG(4, \"reading magic number %08X (expecting %08X)\",\n                        (unsigned)magicNumber, ZSTD_MAGICNUMBER);\n            if ((magicNumber & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {\n                size_t const skippableSize = readSkippableFrameSize(src, srcSize);\n                FORWARD_IF_ERROR(skippableSize);\n                assert(skippableSize <= srcSize);\n\n                src = (const BYTE *)src + skippableSize;\n                srcSize -= skippableSize;\n                continue;\n        }   }\n\n        if (ddict) {\n            /* we were called from ZSTD_decompress_usingDDict */\n            FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(dctx, ddict));\n        } else {\n            /* this will initialize correctly with no dict if dict == NULL, so\n             * use this in all cases but ddict */\n            FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize));\n        }\n        ZSTD_checkContinuity(dctx, dst);\n\n        {   const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,\n                                                    &src, &srcSize);\n            RETURN_ERROR_IF(\n                (ZSTD_getErrorCode(res) == ZSTD_error_prefix_unknown)\n             && (moreThan1Frame==1),\n                srcSize_wrong,\n                \"at least one frame successfully completed, but following \"\n                \"bytes are garbage: it's more likely to be a srcSize error, \"\n                \"specifying more bytes than compressed size of frame(s). This \"\n                \"error message replaces ERROR(prefix_unknown), which would be \"\n                \"confusing, as the first header is actually correct. Note that \"\n                \"one could be unlucky, it might be a corruption error instead, \"\n                \"happening right at the place where we expect zstd magic \"\n                \"bytes. But this is _much_ less likely than a srcSize field \"\n                \"error.\");\n            if (ZSTD_isError(res)) return res;\n            assert(res <= dstCapacity);\n            dst = (BYTE*)dst + res;\n            dstCapacity -= res;\n        }\n        moreThan1Frame = 1;\n    }  /* while (srcSize >= ZSTD_frameHeaderSize_prefix) */\n\n    RETURN_ERROR_IF(srcSize, srcSize_wrong, \"input not entirely consumed\");\n\n    return (BYTE*)dst - (BYTE*)dststart;\n}\n\nsize_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,\n                                 void* dst, size_t dstCapacity,\n                           const void* src, size_t srcSize,\n                           const void* dict, size_t dictSize)\n{\n    return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL);\n}\n\n\nstatic ZSTD_DDict const* ZSTD_getDDict(ZSTD_DCtx* dctx)\n{\n    switch (dctx->dictUses) {\n    default:\n        assert(0 /* Impossible */);\n        /* fall-through */\n    case ZSTD_dont_use:\n        ZSTD_clearDict(dctx);\n        return NULL;\n    case ZSTD_use_indefinitely:\n        return dctx->ddict;\n    case ZSTD_use_once:\n        dctx->dictUses = ZSTD_dont_use;\n        return dctx->ddict;\n    }\n}\n\nsize_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)\n{\n    return ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ZSTD_getDDict(dctx));\n}\n\n\nsize_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)\n{\n#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE>=1)\n    size_t regenSize;\n    ZSTD_DCtx* const dctx = ZSTD_createDCtx();\n    RETURN_ERROR_IF(dctx==NULL, memory_allocation);\n    regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);\n    ZSTD_freeDCtx(dctx);\n    return regenSize;\n#else   /* stack mode */\n    ZSTD_DCtx dctx;\n    ZSTD_initDCtx_internal(&dctx);\n    return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);\n#endif\n}\n\n\n/*-**************************************\n*   Advanced Streaming Decompression API\n*   Bufferless and synchronous\n****************************************/\nsize_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }\n\nZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {\n    switch(dctx->stage)\n    {\n    default:   /* should not happen */\n        assert(0);\n    case ZSTDds_getFrameHeaderSize:\n    case ZSTDds_decodeFrameHeader:\n        return ZSTDnit_frameHeader;\n    case ZSTDds_decodeBlockHeader:\n        return ZSTDnit_blockHeader;\n    case ZSTDds_decompressBlock:\n        return ZSTDnit_block;\n    case ZSTDds_decompressLastBlock:\n        return ZSTDnit_lastBlock;\n    case ZSTDds_checkChecksum:\n        return ZSTDnit_checksum;\n    case ZSTDds_decodeSkippableHeader:\n    case ZSTDds_skipFrame:\n        return ZSTDnit_skippableFrame;\n    }\n}\n\nstatic int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; }\n\n/** ZSTD_decompressContinue() :\n *  srcSize : must be the exact nb of bytes expected (see ZSTD_nextSrcSizeToDecompress())\n *  @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)\n *            or an error code, which can be tested using ZSTD_isError() */\nsize_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)\n{\n    DEBUGLOG(5, \"ZSTD_decompressContinue (srcSize:%u)\", (unsigned)srcSize);\n    /* Sanity check */\n    RETURN_ERROR_IF(srcSize != dctx->expected, srcSize_wrong, \"not allowed\");\n    if (dstCapacity) ZSTD_checkContinuity(dctx, dst);\n\n    switch (dctx->stage)\n    {\n    case ZSTDds_getFrameHeaderSize :\n        assert(src != NULL);\n        if (dctx->format == ZSTD_f_zstd1) {  /* allows header */\n            assert(srcSize >= ZSTD_FRAMEIDSIZE);  /* to read skippable magic number */\n            if ((MEM_readLE32(src) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {        /* skippable frame */\n                memcpy(dctx->headerBuffer, src, srcSize);\n                dctx->expected = ZSTD_SKIPPABLEHEADERSIZE - srcSize;  /* remaining to load to get full skippable frame header */\n                dctx->stage = ZSTDds_decodeSkippableHeader;\n                return 0;\n        }   }\n        dctx->headerSize = ZSTD_frameHeaderSize_internal(src, srcSize, dctx->format);\n        if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;\n        memcpy(dctx->headerBuffer, src, srcSize);\n        dctx->expected = dctx->headerSize - srcSize;\n        dctx->stage = ZSTDds_decodeFrameHeader;\n        return 0;\n\n    case ZSTDds_decodeFrameHeader:\n        assert(src != NULL);\n        memcpy(dctx->headerBuffer + (dctx->headerSize - srcSize), src, srcSize);\n        FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));\n        dctx->expected = ZSTD_blockHeaderSize;\n        dctx->stage = ZSTDds_decodeBlockHeader;\n        return 0;\n\n    case ZSTDds_decodeBlockHeader:\n        {   blockProperties_t bp;\n            size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);\n            if (ZSTD_isError(cBlockSize)) return cBlockSize;\n            RETURN_ERROR_IF(cBlockSize > dctx->fParams.blockSizeMax, corruption_detected, \"Block Size Exceeds Maximum\");\n            dctx->expected = cBlockSize;\n            dctx->bType = bp.blockType;\n            dctx->rleSize = bp.origSize;\n            if (cBlockSize) {\n                dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;\n                return 0;\n            }\n            /* empty block */\n            if (bp.lastBlock) {\n                if (dctx->fParams.checksumFlag) {\n                    dctx->expected = 4;\n                    dctx->stage = ZSTDds_checkChecksum;\n                } else {\n                    dctx->expected = 0; /* end of frame */\n                    dctx->stage = ZSTDds_getFrameHeaderSize;\n                }\n            } else {\n                dctx->expected = ZSTD_blockHeaderSize;  /* jump to next header */\n                dctx->stage = ZSTDds_decodeBlockHeader;\n            }\n            return 0;\n        }\n\n    case ZSTDds_decompressLastBlock:\n    case ZSTDds_decompressBlock:\n        DEBUGLOG(5, \"ZSTD_decompressContinue: case ZSTDds_decompressBlock\");\n        {   size_t rSize;\n            switch(dctx->bType)\n            {\n            case bt_compressed:\n                DEBUGLOG(5, \"ZSTD_decompressContinue: case bt_compressed\");\n                rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 1);\n                break;\n            case bt_raw :\n                rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);\n                break;\n            case bt_rle :\n                rSize = ZSTD_setRleBlock(dst, dstCapacity, *(const BYTE*)src, dctx->rleSize);\n                break;\n            case bt_reserved :   /* should never happen */\n            default:\n                RETURN_ERROR(corruption_detected);\n            }\n            if (ZSTD_isError(rSize)) return rSize;\n            RETURN_ERROR_IF(rSize > dctx->fParams.blockSizeMax, corruption_detected, \"Decompressed Block Size Exceeds Maximum\");\n            DEBUGLOG(5, \"ZSTD_decompressContinue: decoded size from block : %u\", (unsigned)rSize);\n            dctx->decodedSize += rSize;\n            if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);\n\n            if (dctx->stage == ZSTDds_decompressLastBlock) {   /* end of frame */\n                DEBUGLOG(4, \"ZSTD_decompressContinue: decoded size from frame : %u\", (unsigned)dctx->decodedSize);\n                RETURN_ERROR_IF(\n                    dctx->fParams.frameContentSize != ZSTD_CONTENTSIZE_UNKNOWN\n                 && dctx->decodedSize != dctx->fParams.frameContentSize,\n                    corruption_detected);\n                if (dctx->fParams.checksumFlag) {  /* another round for frame checksum */\n                    dctx->expected = 4;\n                    dctx->stage = ZSTDds_checkChecksum;\n                } else {\n                    dctx->expected = 0;   /* ends here */\n                    dctx->stage = ZSTDds_getFrameHeaderSize;\n                }\n            } else {\n                dctx->stage = ZSTDds_decodeBlockHeader;\n                dctx->expected = ZSTD_blockHeaderSize;\n                dctx->previousDstEnd = (char*)dst + rSize;\n            }\n            return rSize;\n        }\n\n    case ZSTDds_checkChecksum:\n        assert(srcSize == 4);  /* guaranteed by dctx->expected */\n        {   U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);\n            U32 const check32 = MEM_readLE32(src);\n            DEBUGLOG(4, \"ZSTD_decompressContinue: checksum : calculated %08X :: %08X read\", (unsigned)h32, (unsigned)check32);\n            RETURN_ERROR_IF(check32 != h32, checksum_wrong);\n            dctx->expected = 0;\n            dctx->stage = ZSTDds_getFrameHeaderSize;\n            return 0;\n        }\n\n    case ZSTDds_decodeSkippableHeader:\n        assert(src != NULL);\n        assert(srcSize <= ZSTD_SKIPPABLEHEADERSIZE);\n        memcpy(dctx->headerBuffer + (ZSTD_SKIPPABLEHEADERSIZE - srcSize), src, srcSize);   /* complete skippable header */\n        dctx->expected = MEM_readLE32(dctx->headerBuffer + ZSTD_FRAMEIDSIZE);   /* note : dctx->expected can grow seriously large, beyond local buffer size */\n        dctx->stage = ZSTDds_skipFrame;\n        return 0;\n\n    case ZSTDds_skipFrame:\n        dctx->expected = 0;\n        dctx->stage = ZSTDds_getFrameHeaderSize;\n        return 0;\n\n    default:\n        assert(0);   /* impossible */\n        RETURN_ERROR(GENERIC);   /* some compiler require default to do something */\n    }\n}\n\n\nstatic size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)\n{\n    dctx->dictEnd = dctx->previousDstEnd;\n    dctx->virtualStart = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->prefixStart));\n    dctx->prefixStart = dict;\n    dctx->previousDstEnd = (const char*)dict + dictSize;\n    return 0;\n}\n\n/*! ZSTD_loadDEntropy() :\n *  dict : must point at beginning of a valid zstd dictionary.\n * @return : size of entropy tables read */\nsize_t\nZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,\n                  const void* const dict, size_t const dictSize)\n{\n    const BYTE* dictPtr = (const BYTE*)dict;\n    const BYTE* const dictEnd = dictPtr + dictSize;\n\n    RETURN_ERROR_IF(dictSize <= 8, dictionary_corrupted);\n    assert(MEM_readLE32(dict) == ZSTD_MAGIC_DICTIONARY);   /* dict must be valid */\n    dictPtr += 8;   /* skip header = magic + dictID */\n\n    ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, OFTable) == offsetof(ZSTD_entropyDTables_t, LLTable) + sizeof(entropy->LLTable));\n    ZSTD_STATIC_ASSERT(offsetof(ZSTD_entropyDTables_t, MLTable) == offsetof(ZSTD_entropyDTables_t, OFTable) + sizeof(entropy->OFTable));\n    ZSTD_STATIC_ASSERT(sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable) >= HUF_DECOMPRESS_WORKSPACE_SIZE);\n    {   void* const workspace = &entropy->LLTable;   /* use fse tables as temporary workspace; implies fse tables are grouped together */\n        size_t const workspaceSize = sizeof(entropy->LLTable) + sizeof(entropy->OFTable) + sizeof(entropy->MLTable);\n#ifdef HUF_FORCE_DECOMPRESS_X1\n        /* in minimal huffman, we always use X1 variants */\n        size_t const hSize = HUF_readDTableX1_wksp(entropy->hufTable,\n                                                dictPtr, dictEnd - dictPtr,\n                                                workspace, workspaceSize);\n#else\n        size_t const hSize = HUF_readDTableX2_wksp(entropy->hufTable,\n                                                dictPtr, dictEnd - dictPtr,\n                                                workspace, workspaceSize);\n#endif\n        RETURN_ERROR_IF(HUF_isError(hSize), dictionary_corrupted);\n        dictPtr += hSize;\n    }\n\n    {   short offcodeNCount[MaxOff+1];\n        unsigned offcodeMaxValue = MaxOff, offcodeLog;\n        size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);\n        RETURN_ERROR_IF(FSE_isError(offcodeHeaderSize), dictionary_corrupted);\n        RETURN_ERROR_IF(offcodeMaxValue > MaxOff, dictionary_corrupted);\n        RETURN_ERROR_IF(offcodeLog > OffFSELog, dictionary_corrupted);\n        ZSTD_buildFSETable( entropy->OFTable,\n                            offcodeNCount, offcodeMaxValue,\n                            OF_base, OF_bits,\n                            offcodeLog);\n        dictPtr += offcodeHeaderSize;\n    }\n\n    {   short matchlengthNCount[MaxML+1];\n        unsigned matchlengthMaxValue = MaxML, matchlengthLog;\n        size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);\n        RETURN_ERROR_IF(FSE_isError(matchlengthHeaderSize), dictionary_corrupted);\n        RETURN_ERROR_IF(matchlengthMaxValue > MaxML, dictionary_corrupted);\n        RETURN_ERROR_IF(matchlengthLog > MLFSELog, dictionary_corrupted);\n        ZSTD_buildFSETable( entropy->MLTable,\n                            matchlengthNCount, matchlengthMaxValue,\n                            ML_base, ML_bits,\n                            matchlengthLog);\n        dictPtr += matchlengthHeaderSize;\n    }\n\n    {   short litlengthNCount[MaxLL+1];\n        unsigned litlengthMaxValue = MaxLL, litlengthLog;\n        size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);\n        RETURN_ERROR_IF(FSE_isError(litlengthHeaderSize), dictionary_corrupted);\n        RETURN_ERROR_IF(litlengthMaxValue > MaxLL, dictionary_corrupted);\n        RETURN_ERROR_IF(litlengthLog > LLFSELog, dictionary_corrupted);\n        ZSTD_buildFSETable( entropy->LLTable,\n                            litlengthNCount, litlengthMaxValue,\n                            LL_base, LL_bits,\n                            litlengthLog);\n        dictPtr += litlengthHeaderSize;\n    }\n\n    RETURN_ERROR_IF(dictPtr+12 > dictEnd, dictionary_corrupted);\n    {   int i;\n        size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));\n        for (i=0; i<3; i++) {\n            U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;\n            RETURN_ERROR_IF(rep==0 || rep > dictContentSize,\n                            dictionary_corrupted);\n            entropy->rep[i] = rep;\n    }   }\n\n    return dictPtr - (const BYTE*)dict;\n}\n\nstatic size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)\n{\n    if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);\n    {   U32 const magic = MEM_readLE32(dict);\n        if (magic != ZSTD_MAGIC_DICTIONARY) {\n            return ZSTD_refDictContent(dctx, dict, dictSize);   /* pure content mode */\n    }   }\n    dctx->dictID = MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);\n\n    /* load entropy tables */\n    {   size_t const eSize = ZSTD_loadDEntropy(&dctx->entropy, dict, dictSize);\n        RETURN_ERROR_IF(ZSTD_isError(eSize), dictionary_corrupted);\n        dict = (const char*)dict + eSize;\n        dictSize -= eSize;\n    }\n    dctx->litEntropy = dctx->fseEntropy = 1;\n\n    /* reference dictionary content */\n    return ZSTD_refDictContent(dctx, dict, dictSize);\n}\n\nsize_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)\n{\n    assert(dctx != NULL);\n    dctx->expected = ZSTD_startingInputLength(dctx->format);  /* dctx->format must be properly set */\n    dctx->stage = ZSTDds_getFrameHeaderSize;\n    dctx->decodedSize = 0;\n    dctx->previousDstEnd = NULL;\n    dctx->prefixStart = NULL;\n    dctx->virtualStart = NULL;\n    dctx->dictEnd = NULL;\n    dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001);  /* cover both little and big endian */\n    dctx->litEntropy = dctx->fseEntropy = 0;\n    dctx->dictID = 0;\n    ZSTD_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));\n    memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue));  /* initial repcodes */\n    dctx->LLTptr = dctx->entropy.LLTable;\n    dctx->MLTptr = dctx->entropy.MLTable;\n    dctx->OFTptr = dctx->entropy.OFTable;\n    dctx->HUFptr = dctx->entropy.hufTable;\n    return 0;\n}\n\nsize_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)\n{\n    FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) );\n    if (dict && dictSize)\n        RETURN_ERROR_IF(\n            ZSTD_isError(ZSTD_decompress_insertDictionary(dctx, dict, dictSize)),\n            dictionary_corrupted);\n    return 0;\n}\n\n\n/* ======   ZSTD_DDict   ====== */\n\nsize_t ZSTD_decompressBegin_usingDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)\n{\n    DEBUGLOG(4, \"ZSTD_decompressBegin_usingDDict\");\n    assert(dctx != NULL);\n    if (ddict) {\n        const char* const dictStart = (const char*)ZSTD_DDict_dictContent(ddict);\n        size_t const dictSize = ZSTD_DDict_dictSize(ddict);\n        const void* const dictEnd = dictStart + dictSize;\n        dctx->ddictIsCold = (dctx->dictEnd != dictEnd);\n        DEBUGLOG(4, \"DDict is %s\",\n                    dctx->ddictIsCold ? \"~cold~\" : \"hot!\");\n    }\n    FORWARD_IF_ERROR( ZSTD_decompressBegin(dctx) );\n    if (ddict) {   /* NULL ddict is equivalent to no dictionary */\n        ZSTD_copyDDictParameters(dctx, ddict);\n    }\n    return 0;\n}\n\n/*! ZSTD_getDictID_fromDict() :\n *  Provides the dictID stored within dictionary.\n *  if @return == 0, the dictionary is not conformant with Zstandard specification.\n *  It can still be loaded, but as a content-only dictionary. */\nunsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)\n{\n    if (dictSize < 8) return 0;\n    if (MEM_readLE32(dict) != ZSTD_MAGIC_DICTIONARY) return 0;\n    return MEM_readLE32((const char*)dict + ZSTD_FRAMEIDSIZE);\n}\n\n/*! ZSTD_getDictID_fromFrame() :\n *  Provides the dictID required to decompress frame stored within `src`.\n *  If @return == 0, the dictID could not be decoded.\n *  This could for one of the following reasons :\n *  - The frame does not require a dictionary (most common case).\n *  - The frame was built with dictID intentionally removed.\n *    Needed dictionary is a hidden information.\n *    Note : this use case also happens when using a non-conformant dictionary.\n *  - `srcSize` is too small, and as a result, frame header could not be decoded.\n *    Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.\n *  - This is not a Zstandard frame.\n *  When identifying the exact failure cause, it's possible to use\n *  ZSTD_getFrameHeader(), which will provide a more precise error code. */\nunsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)\n{\n    ZSTD_frameHeader zfp = { 0, 0, 0, ZSTD_frame, 0, 0, 0 };\n    size_t const hError = ZSTD_getFrameHeader(&zfp, src, srcSize);\n    if (ZSTD_isError(hError)) return 0;\n    return zfp.dictID;\n}\n\n\n/*! ZSTD_decompress_usingDDict() :\n*   Decompression using a pre-digested Dictionary\n*   Use dictionary without significant overhead. */\nsize_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,\n                                  void* dst, size_t dstCapacity,\n                            const void* src, size_t srcSize,\n                            const ZSTD_DDict* ddict)\n{\n    /* pass content and size in case legacy frames are encountered */\n    return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize,\n                                     NULL, 0,\n                                     ddict);\n}\n\n\n/*=====================================\n*   Streaming decompression\n*====================================*/\n\nZSTD_DStream* ZSTD_createDStream(void)\n{\n    DEBUGLOG(3, \"ZSTD_createDStream\");\n    return ZSTD_createDStream_advanced(ZSTD_defaultCMem);\n}\n\nZSTD_DStream* ZSTD_initStaticDStream(void *workspace, size_t workspaceSize)\n{\n    return ZSTD_initStaticDCtx(workspace, workspaceSize);\n}\n\nZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)\n{\n    return ZSTD_createDCtx_advanced(customMem);\n}\n\nsize_t ZSTD_freeDStream(ZSTD_DStream* zds)\n{\n    return ZSTD_freeDCtx(zds);\n}\n\n\n/* ***  Initialization  *** */\n\nsize_t ZSTD_DStreamInSize(void)  { return ZSTD_BLOCKSIZE_MAX + ZSTD_blockHeaderSize; }\nsize_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_MAX; }\n\nsize_t ZSTD_DCtx_loadDictionary_advanced(ZSTD_DCtx* dctx,\n                                   const void* dict, size_t dictSize,\n                                         ZSTD_dictLoadMethod_e dictLoadMethod,\n                                         ZSTD_dictContentType_e dictContentType)\n{\n    RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);\n    ZSTD_clearDict(dctx);\n    if (dict && dictSize != 0) {\n        dctx->ddictLocal = ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, dctx->customMem);\n        RETURN_ERROR_IF(dctx->ddictLocal == NULL, memory_allocation);\n        dctx->ddict = dctx->ddictLocal;\n        dctx->dictUses = ZSTD_use_indefinitely;\n    }\n    return 0;\n}\n\nsize_t ZSTD_DCtx_loadDictionary_byReference(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)\n{\n    return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byRef, ZSTD_dct_auto);\n}\n\nsize_t ZSTD_DCtx_loadDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)\n{\n    return ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, ZSTD_dlm_byCopy, ZSTD_dct_auto);\n}\n\nsize_t ZSTD_DCtx_refPrefix_advanced(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize, ZSTD_dictContentType_e dictContentType)\n{\n    FORWARD_IF_ERROR(ZSTD_DCtx_loadDictionary_advanced(dctx, prefix, prefixSize, ZSTD_dlm_byRef, dictContentType));\n    dctx->dictUses = ZSTD_use_once;\n    return 0;\n}\n\nsize_t ZSTD_DCtx_refPrefix(ZSTD_DCtx* dctx, const void* prefix, size_t prefixSize)\n{\n    return ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, ZSTD_dct_rawContent);\n}\n\n\n/* ZSTD_initDStream_usingDict() :\n * return : expected size, aka ZSTD_startingInputLength().\n * this function cannot fail */\nsize_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)\n{\n    DEBUGLOG(4, \"ZSTD_initDStream_usingDict\");\n    FORWARD_IF_ERROR( ZSTD_DCtx_reset(zds, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_DCtx_loadDictionary(zds, dict, dictSize) );\n    return ZSTD_startingInputLength(zds->format);\n}\n\n/* note : this variant can't fail */\nsize_t ZSTD_initDStream(ZSTD_DStream* zds)\n{\n    DEBUGLOG(4, \"ZSTD_initDStream\");\n    return ZSTD_initDStream_usingDDict(zds, NULL);\n}\n\n/* ZSTD_initDStream_usingDDict() :\n * ddict will just be referenced, and must outlive decompression session\n * this function cannot fail */\nsize_t ZSTD_initDStream_usingDDict(ZSTD_DStream* dctx, const ZSTD_DDict* ddict)\n{\n    FORWARD_IF_ERROR( ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only) );\n    FORWARD_IF_ERROR( ZSTD_DCtx_refDDict(dctx, ddict) );\n    return ZSTD_startingInputLength(dctx->format);\n}\n\n/* ZSTD_resetDStream() :\n * return : expected size, aka ZSTD_startingInputLength().\n * this function cannot fail */\nsize_t ZSTD_resetDStream(ZSTD_DStream* dctx)\n{\n    FORWARD_IF_ERROR(ZSTD_DCtx_reset(dctx, ZSTD_reset_session_only));\n    return ZSTD_startingInputLength(dctx->format);\n}\n\n\nsize_t ZSTD_DCtx_refDDict(ZSTD_DCtx* dctx, const ZSTD_DDict* ddict)\n{\n    RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);\n    ZSTD_clearDict(dctx);\n    if (ddict) {\n        dctx->ddict = ddict;\n        dctx->dictUses = ZSTD_use_indefinitely;\n    }\n    return 0;\n}\n\n/* ZSTD_DCtx_setMaxWindowSize() :\n * note : no direct equivalence in ZSTD_DCtx_setParameter,\n * since this version sets windowSize, and the other sets windowLog */\nsize_t ZSTD_DCtx_setMaxWindowSize(ZSTD_DCtx* dctx, size_t maxWindowSize)\n{\n    ZSTD_bounds const bounds = ZSTD_dParam_getBounds(ZSTD_d_windowLogMax);\n    size_t const min = (size_t)1 << bounds.lowerBound;\n    size_t const max = (size_t)1 << bounds.upperBound;\n    RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);\n    RETURN_ERROR_IF(maxWindowSize < min, parameter_outOfBound);\n    RETURN_ERROR_IF(maxWindowSize > max, parameter_outOfBound);\n    dctx->maxWindowSize = maxWindowSize;\n    return 0;\n}\n\nsize_t ZSTD_DCtx_setFormat(ZSTD_DCtx* dctx, ZSTD_format_e format)\n{\n    return ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, format);\n}\n\nZSTD_bounds ZSTD_dParam_getBounds(ZSTD_dParameter dParam)\n{\n    ZSTD_bounds bounds = { 0, 0, 0 };\n    switch(dParam) {\n        case ZSTD_d_windowLogMax:\n            bounds.lowerBound = ZSTD_WINDOWLOG_ABSOLUTEMIN;\n            bounds.upperBound = ZSTD_WINDOWLOG_MAX;\n            return bounds;\n        case ZSTD_d_format:\n            bounds.lowerBound = (int)ZSTD_f_zstd1;\n            bounds.upperBound = (int)ZSTD_f_zstd1_magicless;\n            ZSTD_STATIC_ASSERT(ZSTD_f_zstd1 < ZSTD_f_zstd1_magicless);\n            return bounds;\n        default:;\n    }\n    bounds.error = ERROR(parameter_unsupported);\n    return bounds;\n}\n\n/* ZSTD_dParam_withinBounds:\n * @return 1 if value is within dParam bounds,\n * 0 otherwise */\nstatic int ZSTD_dParam_withinBounds(ZSTD_dParameter dParam, int value)\n{\n    ZSTD_bounds const bounds = ZSTD_dParam_getBounds(dParam);\n    if (ZSTD_isError(bounds.error)) return 0;\n    if (value < bounds.lowerBound) return 0;\n    if (value > bounds.upperBound) return 0;\n    return 1;\n}\n\n#define CHECK_DBOUNDS(p,v) {                \\\n    RETURN_ERROR_IF(!ZSTD_dParam_withinBounds(p, v), parameter_outOfBound); \\\n}\n\nsize_t ZSTD_DCtx_setParameter(ZSTD_DCtx* dctx, ZSTD_dParameter dParam, int value)\n{\n    RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);\n    switch(dParam) {\n        case ZSTD_d_windowLogMax:\n            if (value == 0) value = ZSTD_WINDOWLOG_LIMIT_DEFAULT;\n            CHECK_DBOUNDS(ZSTD_d_windowLogMax, value);\n            dctx->maxWindowSize = ((size_t)1) << value;\n            return 0;\n        case ZSTD_d_format:\n            CHECK_DBOUNDS(ZSTD_d_format, value);\n            dctx->format = (ZSTD_format_e)value;\n            return 0;\n        default:;\n    }\n    RETURN_ERROR(parameter_unsupported);\n}\n\nsize_t ZSTD_DCtx_reset(ZSTD_DCtx* dctx, ZSTD_ResetDirective reset)\n{\n    if ( (reset == ZSTD_reset_session_only)\n      || (reset == ZSTD_reset_session_and_parameters) ) {\n        dctx->streamStage = zdss_init;\n        dctx->noForwardProgress = 0;\n    }\n    if ( (reset == ZSTD_reset_parameters)\n      || (reset == ZSTD_reset_session_and_parameters) ) {\n        RETURN_ERROR_IF(dctx->streamStage != zdss_init, stage_wrong);\n        ZSTD_clearDict(dctx);\n        dctx->format = ZSTD_f_zstd1;\n        dctx->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;\n    }\n    return 0;\n}\n\n\nsize_t ZSTD_sizeof_DStream(const ZSTD_DStream* dctx)\n{\n    return ZSTD_sizeof_DCtx(dctx);\n}\n\nsize_t ZSTD_decodingBufferSize_min(unsigned long long windowSize, unsigned long long frameContentSize)\n{\n    size_t const blockSize = (size_t) MIN(windowSize, ZSTD_BLOCKSIZE_MAX);\n    unsigned long long const neededRBSize = windowSize + blockSize + (WILDCOPY_OVERLENGTH * 2);\n    unsigned long long const neededSize = MIN(frameContentSize, neededRBSize);\n    size_t const minRBSize = (size_t) neededSize;\n    RETURN_ERROR_IF((unsigned long long)minRBSize != neededSize,\n                    frameParameter_windowTooLarge);\n    return minRBSize;\n}\n\nsize_t ZSTD_estimateDStreamSize(size_t windowSize)\n{\n    size_t const blockSize = MIN(windowSize, ZSTD_BLOCKSIZE_MAX);\n    size_t const inBuffSize = blockSize;  /* no block can be larger */\n    size_t const outBuffSize = ZSTD_decodingBufferSize_min(windowSize, ZSTD_CONTENTSIZE_UNKNOWN);\n    return ZSTD_estimateDCtxSize() + inBuffSize + outBuffSize;\n}\n\nsize_t ZSTD_estimateDStreamSize_fromFrame(const void* src, size_t srcSize)\n{\n    U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;   /* note : should be user-selectable, but requires an additional parameter (or a dctx) */\n    ZSTD_frameHeader zfh;\n    size_t const err = ZSTD_getFrameHeader(&zfh, src, srcSize);\n    if (ZSTD_isError(err)) return err;\n    RETURN_ERROR_IF(err>0, srcSize_wrong);\n    RETURN_ERROR_IF(zfh.windowSize > windowSizeMax,\n                    frameParameter_windowTooLarge);\n    return ZSTD_estimateDStreamSize((size_t)zfh.windowSize);\n}\n\n\n/* *****   Decompression   ***** */\n\nMEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)\n{\n    size_t const length = MIN(dstCapacity, srcSize);\n    memcpy(dst, src, length);\n    return length;\n}\n\n\nsize_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)\n{\n    const char* const istart = (const char*)(input->src) + input->pos;\n    const char* const iend = (const char*)(input->src) + input->size;\n    const char* ip = istart;\n    char* const ostart = (char*)(output->dst) + output->pos;\n    char* const oend = (char*)(output->dst) + output->size;\n    char* op = ostart;\n    U32 someMoreWork = 1;\n\n    DEBUGLOG(5, \"ZSTD_decompressStream\");\n    RETURN_ERROR_IF(\n        input->pos > input->size,\n        srcSize_wrong,\n        \"forbidden. in: pos: %u   vs size: %u\",\n        (U32)input->pos, (U32)input->size);\n    RETURN_ERROR_IF(\n        output->pos > output->size,\n        dstSize_tooSmall,\n        \"forbidden. out: pos: %u   vs size: %u\",\n        (U32)output->pos, (U32)output->size);\n    DEBUGLOG(5, \"input size : %u\", (U32)(input->size - input->pos));\n\n    while (someMoreWork) {\n        switch(zds->streamStage)\n        {\n        case zdss_init :\n            DEBUGLOG(5, \"stage zdss_init => transparent reset \");\n            zds->streamStage = zdss_loadHeader;\n            zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;\n            zds->legacyVersion = 0;\n            zds->hostageByte = 0;\n            /* fall-through */\n\n        case zdss_loadHeader :\n            DEBUGLOG(5, \"stage zdss_loadHeader (srcSize : %u)\", (U32)(iend - ip));\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)\n            if (zds->legacyVersion) {\n                RETURN_ERROR_IF(zds->staticSize, memory_allocation,\n                    \"legacy support is incompatible with static dctx\");\n                {   size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);\n                    if (hint==0) zds->streamStage = zdss_init;\n                    return hint;\n            }   }\n#endif\n            {   size_t const hSize = ZSTD_getFrameHeader_advanced(&zds->fParams, zds->headerBuffer, zds->lhSize, zds->format);\n                DEBUGLOG(5, \"header size : %u\", (U32)hSize);\n                if (ZSTD_isError(hSize)) {\n#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)\n                    U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);\n                    if (legacyVersion) {\n                        ZSTD_DDict const* const ddict = ZSTD_getDDict(zds);\n                        const void* const dict = ddict ? ZSTD_DDict_dictContent(ddict) : NULL;\n                        size_t const dictSize = ddict ? ZSTD_DDict_dictSize(ddict) : 0;\n                        DEBUGLOG(5, \"ZSTD_decompressStream: detected legacy version v0.%u\", legacyVersion);\n                        RETURN_ERROR_IF(zds->staticSize, memory_allocation,\n                            \"legacy support is incompatible with static dctx\");\n                        FORWARD_IF_ERROR(ZSTD_initLegacyStream(&zds->legacyContext,\n                                    zds->previousLegacyVersion, legacyVersion,\n                                    dict, dictSize));\n                        zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;\n                        {   size_t const hint = ZSTD_decompressLegacyStream(zds->legacyContext, legacyVersion, output, input);\n                            if (hint==0) zds->streamStage = zdss_init;   /* or stay in stage zdss_loadHeader */\n                            return hint;\n                    }   }\n#endif\n                    return hSize;   /* error */\n                }\n                if (hSize != 0) {   /* need more input */\n                    size_t const toLoad = hSize - zds->lhSize;   /* if hSize!=0, hSize > zds->lhSize */\n                    size_t const remainingInput = (size_t)(iend-ip);\n                    assert(iend >= ip);\n                    if (toLoad > remainingInput) {   /* not enough input to load full header */\n                        if (remainingInput > 0) {\n                            memcpy(zds->headerBuffer + zds->lhSize, ip, remainingInput);\n                            zds->lhSize += remainingInput;\n                        }\n                        input->pos = input->size;\n                        return (MAX((size_t)ZSTD_FRAMEHEADERSIZE_MIN(zds->format), hSize) - zds->lhSize) + ZSTD_blockHeaderSize;   /* remaining header bytes + next block header */\n                    }\n                    assert(ip != NULL);\n                    memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;\n                    break;\n            }   }\n\n            /* check for single-pass mode opportunity */\n            if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */\n                && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {\n                size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);\n                if (cSize <= (size_t)(iend-istart)) {\n                    /* shortcut : using single-pass mode */\n                    size_t const decompressedSize = ZSTD_decompress_usingDDict(zds, op, oend-op, istart, cSize, ZSTD_getDDict(zds));\n                    if (ZSTD_isError(decompressedSize)) return decompressedSize;\n                    DEBUGLOG(4, \"shortcut to single-pass ZSTD_decompress_usingDDict()\")\n                    ip = istart + cSize;\n                    op += decompressedSize;\n                    zds->expected = 0;\n                    zds->streamStage = zdss_init;\n                    someMoreWork = 0;\n                    break;\n            }   }\n\n            /* Consume header (see ZSTDds_decodeFrameHeader) */\n            DEBUGLOG(4, \"Consume header\");\n            FORWARD_IF_ERROR(ZSTD_decompressBegin_usingDDict(zds, ZSTD_getDDict(zds)));\n\n            if ((MEM_readLE32(zds->headerBuffer) & ZSTD_MAGIC_SKIPPABLE_MASK) == ZSTD_MAGIC_SKIPPABLE_START) {  /* skippable frame */\n                zds->expected = MEM_readLE32(zds->headerBuffer + ZSTD_FRAMEIDSIZE);\n                zds->stage = ZSTDds_skipFrame;\n            } else {\n                FORWARD_IF_ERROR(ZSTD_decodeFrameHeader(zds, zds->headerBuffer, zds->lhSize));\n                zds->expected = ZSTD_blockHeaderSize;\n                zds->stage = ZSTDds_decodeBlockHeader;\n            }\n\n            /* control buffer memory usage */\n            DEBUGLOG(4, \"Control max memory usage (%u KB <= max %u KB)\",\n                        (U32)(zds->fParams.windowSize >>10),\n                        (U32)(zds->maxWindowSize >> 10) );\n            zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);\n            RETURN_ERROR_IF(zds->fParams.windowSize > zds->maxWindowSize,\n                            frameParameter_windowTooLarge);\n\n            /* Adapt buffer sizes to frame header instructions */\n            {   size_t const neededInBuffSize = MAX(zds->fParams.blockSizeMax, 4 /* frame checksum */);\n                size_t const neededOutBuffSize = ZSTD_decodingBufferSize_min(zds->fParams.windowSize, zds->fParams.frameContentSize);\n                if ((zds->inBuffSize < neededInBuffSize) || (zds->outBuffSize < neededOutBuffSize)) {\n                    size_t const bufferSize = neededInBuffSize + neededOutBuffSize;\n                    DEBUGLOG(4, \"inBuff  : from %u to %u\",\n                                (U32)zds->inBuffSize, (U32)neededInBuffSize);\n                    DEBUGLOG(4, \"outBuff : from %u to %u\",\n                                (U32)zds->outBuffSize, (U32)neededOutBuffSize);\n                    if (zds->staticSize) {  /* static DCtx */\n                        DEBUGLOG(4, \"staticSize : %u\", (U32)zds->staticSize);\n                        assert(zds->staticSize >= sizeof(ZSTD_DCtx));  /* controlled at init */\n                        RETURN_ERROR_IF(\n                            bufferSize > zds->staticSize - sizeof(ZSTD_DCtx),\n                            memory_allocation);\n                    } else {\n                        ZSTD_free(zds->inBuff, zds->customMem);\n                        zds->inBuffSize = 0;\n                        zds->outBuffSize = 0;\n                        zds->inBuff = (char*)ZSTD_malloc(bufferSize, zds->customMem);\n                        RETURN_ERROR_IF(zds->inBuff == NULL, memory_allocation);\n                    }\n                    zds->inBuffSize = neededInBuffSize;\n                    zds->outBuff = zds->inBuff + zds->inBuffSize;\n                    zds->outBuffSize = neededOutBuffSize;\n            }   }\n            zds->streamStage = zdss_read;\n            /* fall-through */\n\n        case zdss_read:\n            DEBUGLOG(5, \"stage zdss_read\");\n            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);\n                DEBUGLOG(5, \"neededInSize = %u\", (U32)neededInSize);\n                if (neededInSize==0) {  /* end of frame */\n                    zds->streamStage = zdss_init;\n                    someMoreWork = 0;\n                    break;\n                }\n                if ((size_t)(iend-ip) >= neededInSize) {  /* decode directly from src */\n                    int const isSkipFrame = ZSTD_isSkipFrame(zds);\n                    size_t const decodedSize = ZSTD_decompressContinue(zds,\n                        zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),\n                        ip, neededInSize);\n                    if (ZSTD_isError(decodedSize)) return decodedSize;\n                    ip += neededInSize;\n                    if (!decodedSize && !isSkipFrame) break;   /* this was just a header */\n                    zds->outEnd = zds->outStart + decodedSize;\n                    zds->streamStage = zdss_flush;\n                    break;\n            }   }\n            if (ip==iend) { someMoreWork = 0; break; }   /* no more input */\n            zds->streamStage = zdss_load;\n            /* fall-through */\n\n        case zdss_load:\n            {   size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds);\n                size_t const toLoad = neededInSize - zds->inPos;\n                int const isSkipFrame = ZSTD_isSkipFrame(zds);\n                size_t loadedSize;\n                if (isSkipFrame) {\n                    loadedSize = MIN(toLoad, (size_t)(iend-ip));\n                } else {\n                    RETURN_ERROR_IF(toLoad > zds->inBuffSize - zds->inPos,\n                                    corruption_detected,\n                                    \"should never happen\");\n                    loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);\n                }\n                ip += loadedSize;\n                zds->inPos += loadedSize;\n                if (loadedSize < toLoad) { someMoreWork = 0; break; }   /* not enough input, wait for more */\n\n                /* decode loaded input */\n                {   size_t const decodedSize = ZSTD_decompressContinue(zds,\n                        zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,\n                        zds->inBuff, neededInSize);\n                    if (ZSTD_isError(decodedSize)) return decodedSize;\n                    zds->inPos = 0;   /* input is consumed */\n                    if (!decodedSize && !isSkipFrame) { zds->streamStage = zdss_read; break; }   /* this was just a header */\n                    zds->outEnd = zds->outStart +  decodedSize;\n            }   }\n            zds->streamStage = zdss_flush;\n            /* fall-through */\n\n        case zdss_flush:\n            {   size_t const toFlushSize = zds->outEnd - zds->outStart;\n                size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);\n                op += flushedSize;\n                zds->outStart += flushedSize;\n                if (flushedSize == toFlushSize) {  /* flush completed */\n                    zds->streamStage = zdss_read;\n                    if ( (zds->outBuffSize < zds->fParams.frameContentSize)\n                      && (zds->outStart + zds->fParams.blockSizeMax > zds->outBuffSize) ) {\n                        DEBUGLOG(5, \"restart filling outBuff from beginning (left:%i, needed:%u)\",\n                                (int)(zds->outBuffSize - zds->outStart),\n                                (U32)zds->fParams.blockSizeMax);\n                        zds->outStart = zds->outEnd = 0;\n                    }\n                    break;\n            }   }\n            /* cannot complete flush */\n            someMoreWork = 0;\n            break;\n\n        default:\n            assert(0);    /* impossible */\n            RETURN_ERROR(GENERIC);   /* some compiler require default to do something */\n    }   }\n\n    /* result */\n    input->pos = (size_t)(ip - (const char*)(input->src));\n    output->pos = (size_t)(op - (char*)(output->dst));\n    if ((ip==istart) && (op==ostart)) {  /* no forward progress */\n        zds->noForwardProgress ++;\n        if (zds->noForwardProgress >= ZSTD_NO_FORWARD_PROGRESS_MAX) {\n            RETURN_ERROR_IF(op==oend, dstSize_tooSmall);\n            RETURN_ERROR_IF(ip==iend, srcSize_wrong);\n            assert(0);\n        }\n    } else {\n        zds->noForwardProgress = 0;\n    }\n    {   size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds);\n        if (!nextSrcSizeHint) {   /* frame fully decoded */\n            if (zds->outEnd == zds->outStart) {  /* output fully flushed */\n                if (zds->hostageByte) {\n                    if (input->pos >= input->size) {\n                        /* can't release hostage (not present) */\n                        zds->streamStage = zdss_read;\n                        return 1;\n                    }\n                    input->pos++;  /* release hostage */\n                }   /* zds->hostageByte */\n                return 0;\n            }  /* zds->outEnd == zds->outStart */\n            if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */\n                input->pos--;   /* note : pos > 0, otherwise, impossible to finish reading last block */\n                zds->hostageByte=1;\n            }\n            return 1;\n        }  /* nextSrcSizeHint==0 */\n        nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds) == ZSTDnit_block);   /* preload header of next block */\n        assert(zds->inPos <= nextSrcSizeHint);\n        nextSrcSizeHint -= zds->inPos;   /* part already loaded*/\n        return nextSrcSizeHint;\n    }\n}\n\nsize_t ZSTD_decompressStream_simpleArgs (\n                            ZSTD_DCtx* dctx,\n                            void* dst, size_t dstCapacity, size_t* dstPos,\n                      const void* src, size_t srcSize, size_t* srcPos)\n{\n    ZSTD_outBuffer output = { dst, dstCapacity, *dstPos };\n    ZSTD_inBuffer  input  = { src, srcSize, *srcPos };\n    /* ZSTD_compress_generic() will check validity of dstPos and srcPos */\n    size_t const cErr = ZSTD_decompressStream(dctx, &output, &input);\n    *dstPos = output.pos;\n    *srcPos = input.pos;\n    return cErr;\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_decompress_block.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n/* zstd_decompress_block :\n * this module takes care of decompressing _compressed_ block */\n\n/*-*******************************************************\n*  Dependencies\n*********************************************************/\n#include <string.h>      /* memcpy, memmove, memset */\n#include \"compiler.h\"    /* prefetch */\n#include \"cpu.h\"         /* bmi2 */\n#include \"mem.h\"         /* low level memory routines */\n#define FSE_STATIC_LINKING_ONLY\n#include \"fse.h\"\n#define HUF_STATIC_LINKING_ONLY\n#include \"huf.h\"\n#include \"zstd_internal.h\"\n#include \"zstd_decompress_internal.h\"   /* ZSTD_DCtx */\n#include \"zstd_ddict.h\"  /* ZSTD_DDictDictContent */\n#include \"zstd_decompress_block.h\"\n\n/*_*******************************************************\n*  Macros\n**********************************************************/\n\n/* These two optional macros force the use one way or another of the two\n * ZSTD_decompressSequences implementations. You can't force in both directions\n * at the same time.\n */\n#if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \\\n    defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)\n#error \"Cannot force the use of the short and the long ZSTD_decompressSequences variants!\"\n#endif\n\n\n/*_*******************************************************\n*  Memory operations\n**********************************************************/\nstatic void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }\n\n\n/*-*************************************************************\n *   Block decoding\n ***************************************************************/\n\n/*! ZSTD_getcBlockSize() :\n *  Provides the size of compressed block from block header `src` */\nsize_t ZSTD_getcBlockSize(const void* src, size_t srcSize,\n                          blockProperties_t* bpPtr)\n{\n    RETURN_ERROR_IF(srcSize < ZSTD_blockHeaderSize, srcSize_wrong);\n\n    {   U32 const cBlockHeader = MEM_readLE24(src);\n        U32 const cSize = cBlockHeader >> 3;\n        bpPtr->lastBlock = cBlockHeader & 1;\n        bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);\n        bpPtr->origSize = cSize;   /* only useful for RLE */\n        if (bpPtr->blockType == bt_rle) return 1;\n        RETURN_ERROR_IF(bpPtr->blockType == bt_reserved, corruption_detected);\n        return cSize;\n    }\n}\n\n\n/* Hidden declaration for fullbench */\nsize_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,\n                          const void* src, size_t srcSize);\n/*! ZSTD_decodeLiteralsBlock() :\n * @return : nb of bytes read from src (< srcSize )\n *  note : symbol not declared but exposed for fullbench */\nsize_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,\n                          const void* src, size_t srcSize)   /* note : srcSize < BLOCKSIZE */\n{\n    DEBUGLOG(5, \"ZSTD_decodeLiteralsBlock\");\n    RETURN_ERROR_IF(srcSize < MIN_CBLOCK_SIZE, corruption_detected);\n\n    {   const BYTE* const istart = (const BYTE*) src;\n        symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);\n\n        switch(litEncType)\n        {\n        case set_repeat:\n            DEBUGLOG(5, \"set_repeat flag : re-using stats from previous compressed literals block\");\n            RETURN_ERROR_IF(dctx->litEntropy==0, dictionary_corrupted);\n            /* fall-through */\n\n        case set_compressed:\n            RETURN_ERROR_IF(srcSize < 5, corruption_detected, \"srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3\");\n            {   size_t lhSize, litSize, litCSize;\n                U32 singleStream=0;\n                U32 const lhlCode = (istart[0] >> 2) & 3;\n                U32 const lhc = MEM_readLE32(istart);\n                size_t hufSuccess;\n                switch(lhlCode)\n                {\n                case 0: case 1: default:   /* note : default is impossible, since lhlCode into [0..3] */\n                    /* 2 - 2 - 10 - 10 */\n                    singleStream = !lhlCode;\n                    lhSize = 3;\n                    litSize  = (lhc >> 4) & 0x3FF;\n                    litCSize = (lhc >> 14) & 0x3FF;\n                    break;\n                case 2:\n                    /* 2 - 2 - 14 - 14 */\n                    lhSize = 4;\n                    litSize  = (lhc >> 4) & 0x3FFF;\n                    litCSize = lhc >> 18;\n                    break;\n                case 3:\n                    /* 2 - 2 - 18 - 18 */\n                    lhSize = 5;\n                    litSize  = (lhc >> 4) & 0x3FFFF;\n                    litCSize = (lhc >> 22) + ((size_t)istart[4] << 10);\n                    break;\n                }\n                RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected);\n                RETURN_ERROR_IF(litCSize + lhSize > srcSize, corruption_detected);\n\n                /* prefetch huffman table if cold */\n                if (dctx->ddictIsCold && (litSize > 768 /* heuristic */)) {\n                    PREFETCH_AREA(dctx->HUFptr, sizeof(dctx->entropy.hufTable));\n                }\n\n                if (litEncType==set_repeat) {\n                    if (singleStream) {\n                        hufSuccess = HUF_decompress1X_usingDTable_bmi2(\n                            dctx->litBuffer, litSize, istart+lhSize, litCSize,\n                            dctx->HUFptr, dctx->bmi2);\n                    } else {\n                        hufSuccess = HUF_decompress4X_usingDTable_bmi2(\n                            dctx->litBuffer, litSize, istart+lhSize, litCSize,\n                            dctx->HUFptr, dctx->bmi2);\n                    }\n                } else {\n                    if (singleStream) {\n#if defined(HUF_FORCE_DECOMPRESS_X2)\n                        hufSuccess = HUF_decompress1X_DCtx_wksp(\n                            dctx->entropy.hufTable, dctx->litBuffer, litSize,\n                            istart+lhSize, litCSize, dctx->workspace,\n                            sizeof(dctx->workspace));\n#else\n                        hufSuccess = HUF_decompress1X1_DCtx_wksp_bmi2(\n                            dctx->entropy.hufTable, dctx->litBuffer, litSize,\n                            istart+lhSize, litCSize, dctx->workspace,\n                            sizeof(dctx->workspace), dctx->bmi2);\n#endif\n                    } else {\n                        hufSuccess = HUF_decompress4X_hufOnly_wksp_bmi2(\n                            dctx->entropy.hufTable, dctx->litBuffer, litSize,\n                            istart+lhSize, litCSize, dctx->workspace,\n                            sizeof(dctx->workspace), dctx->bmi2);\n                    }\n                }\n\n                RETURN_ERROR_IF(HUF_isError(hufSuccess), corruption_detected);\n\n                dctx->litPtr = dctx->litBuffer;\n                dctx->litSize = litSize;\n                dctx->litEntropy = 1;\n                if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;\n                memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);\n                return litCSize + lhSize;\n            }\n\n        case set_basic:\n            {   size_t litSize, lhSize;\n                U32 const lhlCode = ((istart[0]) >> 2) & 3;\n                switch(lhlCode)\n                {\n                case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */\n                    lhSize = 1;\n                    litSize = istart[0] >> 3;\n                    break;\n                case 1:\n                    lhSize = 2;\n                    litSize = MEM_readLE16(istart) >> 4;\n                    break;\n                case 3:\n                    lhSize = 3;\n                    litSize = MEM_readLE24(istart) >> 4;\n                    break;\n                }\n\n                if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) {  /* risk reading beyond src buffer with wildcopy */\n                    RETURN_ERROR_IF(litSize+lhSize > srcSize, corruption_detected);\n                    memcpy(dctx->litBuffer, istart+lhSize, litSize);\n                    dctx->litPtr = dctx->litBuffer;\n                    dctx->litSize = litSize;\n                    memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);\n                    return lhSize+litSize;\n                }\n                /* direct reference into compressed stream */\n                dctx->litPtr = istart+lhSize;\n                dctx->litSize = litSize;\n                return lhSize+litSize;\n            }\n\n        case set_rle:\n            {   U32 const lhlCode = ((istart[0]) >> 2) & 3;\n                size_t litSize, lhSize;\n                switch(lhlCode)\n                {\n                case 0: case 2: default:   /* note : default is impossible, since lhlCode into [0..3] */\n                    lhSize = 1;\n                    litSize = istart[0] >> 3;\n                    break;\n                case 1:\n                    lhSize = 2;\n                    litSize = MEM_readLE16(istart) >> 4;\n                    break;\n                case 3:\n                    lhSize = 3;\n                    litSize = MEM_readLE24(istart) >> 4;\n                    RETURN_ERROR_IF(srcSize<4, corruption_detected, \"srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4\");\n                    break;\n                }\n                RETURN_ERROR_IF(litSize > ZSTD_BLOCKSIZE_MAX, corruption_detected);\n                memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);\n                dctx->litPtr = dctx->litBuffer;\n                dctx->litSize = litSize;\n                return lhSize+1;\n            }\n        default:\n            RETURN_ERROR(corruption_detected, \"impossible\");\n        }\n    }\n}\n\n/* Default FSE distribution tables.\n * These are pre-calculated FSE decoding tables using default distributions as defined in specification :\n * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#default-distributions\n * They were generated programmatically with following method :\n * - start from default distributions, present in /lib/common/zstd_internal.h\n * - generate tables normally, using ZSTD_buildFSETable()\n * - printout the content of tables\n * - pretify output, report below, test with fuzzer to ensure it's correct */\n\n/* Default FSE distribution table for Literal Lengths */\nstatic const ZSTD_seqSymbol LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {\n     {  1,  1,  1, LL_DEFAULTNORMLOG},  /* header : fastMode, tableLog */\n     /* nextState, nbAddBits, nbBits, baseVal */\n     {  0,  0,  4,    0},  { 16,  0,  4,    0},\n     { 32,  0,  5,    1},  {  0,  0,  5,    3},\n     {  0,  0,  5,    4},  {  0,  0,  5,    6},\n     {  0,  0,  5,    7},  {  0,  0,  5,    9},\n     {  0,  0,  5,   10},  {  0,  0,  5,   12},\n     {  0,  0,  6,   14},  {  0,  1,  5,   16},\n     {  0,  1,  5,   20},  {  0,  1,  5,   22},\n     {  0,  2,  5,   28},  {  0,  3,  5,   32},\n     {  0,  4,  5,   48},  { 32,  6,  5,   64},\n     {  0,  7,  5,  128},  {  0,  8,  6,  256},\n     {  0, 10,  6, 1024},  {  0, 12,  6, 4096},\n     { 32,  0,  4,    0},  {  0,  0,  4,    1},\n     {  0,  0,  5,    2},  { 32,  0,  5,    4},\n     {  0,  0,  5,    5},  { 32,  0,  5,    7},\n     {  0,  0,  5,    8},  { 32,  0,  5,   10},\n     {  0,  0,  5,   11},  {  0,  0,  6,   13},\n     { 32,  1,  5,   16},  {  0,  1,  5,   18},\n     { 32,  1,  5,   22},  {  0,  2,  5,   24},\n     { 32,  3,  5,   32},  {  0,  3,  5,   40},\n     {  0,  6,  4,   64},  { 16,  6,  4,   64},\n     { 32,  7,  5,  128},  {  0,  9,  6,  512},\n     {  0, 11,  6, 2048},  { 48,  0,  4,    0},\n     { 16,  0,  4,    1},  { 32,  0,  5,    2},\n     { 32,  0,  5,    3},  { 32,  0,  5,    5},\n     { 32,  0,  5,    6},  { 32,  0,  5,    8},\n     { 32,  0,  5,    9},  { 32,  0,  5,   11},\n     { 32,  0,  5,   12},  {  0,  0,  6,   15},\n     { 32,  1,  5,   18},  { 32,  1,  5,   20},\n     { 32,  2,  5,   24},  { 32,  2,  5,   28},\n     { 32,  3,  5,   40},  { 32,  4,  5,   48},\n     {  0, 16,  6,65536},  {  0, 15,  6,32768},\n     {  0, 14,  6,16384},  {  0, 13,  6, 8192},\n};   /* LL_defaultDTable */\n\n/* Default FSE distribution table for Offset Codes */\nstatic const ZSTD_seqSymbol OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {\n    {  1,  1,  1, OF_DEFAULTNORMLOG},  /* header : fastMode, tableLog */\n    /* nextState, nbAddBits, nbBits, baseVal */\n    {  0,  0,  5,    0},     {  0,  6,  4,   61},\n    {  0,  9,  5,  509},     {  0, 15,  5,32765},\n    {  0, 21,  5,2097149},   {  0,  3,  5,    5},\n    {  0,  7,  4,  125},     {  0, 12,  5, 4093},\n    {  0, 18,  5,262141},    {  0, 23,  5,8388605},\n    {  0,  5,  5,   29},     {  0,  8,  4,  253},\n    {  0, 14,  5,16381},     {  0, 20,  5,1048573},\n    {  0,  2,  5,    1},     { 16,  7,  4,  125},\n    {  0, 11,  5, 2045},     {  0, 17,  5,131069},\n    {  0, 22,  5,4194301},   {  0,  4,  5,   13},\n    { 16,  8,  4,  253},     {  0, 13,  5, 8189},\n    {  0, 19,  5,524285},    {  0,  1,  5,    1},\n    { 16,  6,  4,   61},     {  0, 10,  5, 1021},\n    {  0, 16,  5,65533},     {  0, 28,  5,268435453},\n    {  0, 27,  5,134217725}, {  0, 26,  5,67108861},\n    {  0, 25,  5,33554429},  {  0, 24,  5,16777213},\n};   /* OF_defaultDTable */\n\n\n/* Default FSE distribution table for Match Lengths */\nstatic const ZSTD_seqSymbol ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {\n    {  1,  1,  1, ML_DEFAULTNORMLOG},  /* header : fastMode, tableLog */\n    /* nextState, nbAddBits, nbBits, baseVal */\n    {  0,  0,  6,    3},  {  0,  0,  4,    4},\n    { 32,  0,  5,    5},  {  0,  0,  5,    6},\n    {  0,  0,  5,    8},  {  0,  0,  5,    9},\n    {  0,  0,  5,   11},  {  0,  0,  6,   13},\n    {  0,  0,  6,   16},  {  0,  0,  6,   19},\n    {  0,  0,  6,   22},  {  0,  0,  6,   25},\n    {  0,  0,  6,   28},  {  0,  0,  6,   31},\n    {  0,  0,  6,   34},  {  0,  1,  6,   37},\n    {  0,  1,  6,   41},  {  0,  2,  6,   47},\n    {  0,  3,  6,   59},  {  0,  4,  6,   83},\n    {  0,  7,  6,  131},  {  0,  9,  6,  515},\n    { 16,  0,  4,    4},  {  0,  0,  4,    5},\n    { 32,  0,  5,    6},  {  0,  0,  5,    7},\n    { 32,  0,  5,    9},  {  0,  0,  5,   10},\n    {  0,  0,  6,   12},  {  0,  0,  6,   15},\n    {  0,  0,  6,   18},  {  0,  0,  6,   21},\n    {  0,  0,  6,   24},  {  0,  0,  6,   27},\n    {  0,  0,  6,   30},  {  0,  0,  6,   33},\n    {  0,  1,  6,   35},  {  0,  1,  6,   39},\n    {  0,  2,  6,   43},  {  0,  3,  6,   51},\n    {  0,  4,  6,   67},  {  0,  5,  6,   99},\n    {  0,  8,  6,  259},  { 32,  0,  4,    4},\n    { 48,  0,  4,    4},  { 16,  0,  4,    5},\n    { 32,  0,  5,    7},  { 32,  0,  5,    8},\n    { 32,  0,  5,   10},  { 32,  0,  5,   11},\n    {  0,  0,  6,   14},  {  0,  0,  6,   17},\n    {  0,  0,  6,   20},  {  0,  0,  6,   23},\n    {  0,  0,  6,   26},  {  0,  0,  6,   29},\n    {  0,  0,  6,   32},  {  0, 16,  6,65539},\n    {  0, 15,  6,32771},  {  0, 14,  6,16387},\n    {  0, 13,  6, 8195},  {  0, 12,  6, 4099},\n    {  0, 11,  6, 2051},  {  0, 10,  6, 1027},\n};   /* ML_defaultDTable */\n\n\nstatic void ZSTD_buildSeqTable_rle(ZSTD_seqSymbol* dt, U32 baseValue, U32 nbAddBits)\n{\n    void* ptr = dt;\n    ZSTD_seqSymbol_header* const DTableH = (ZSTD_seqSymbol_header*)ptr;\n    ZSTD_seqSymbol* const cell = dt + 1;\n\n    DTableH->tableLog = 0;\n    DTableH->fastMode = 0;\n\n    cell->nbBits = 0;\n    cell->nextState = 0;\n    assert(nbAddBits < 255);\n    cell->nbAdditionalBits = (BYTE)nbAddBits;\n    cell->baseValue = baseValue;\n}\n\n\n/* ZSTD_buildFSETable() :\n * generate FSE decoding table for one symbol (ll, ml or off)\n * cannot fail if input is valid =>\n * all inputs are presumed validated at this stage */\nvoid\nZSTD_buildFSETable(ZSTD_seqSymbol* dt,\n            const short* normalizedCounter, unsigned maxSymbolValue,\n            const U32* baseValue, const U32* nbAdditionalBits,\n            unsigned tableLog)\n{\n    ZSTD_seqSymbol* const tableDecode = dt+1;\n    U16 symbolNext[MaxSeq+1];\n\n    U32 const maxSV1 = maxSymbolValue + 1;\n    U32 const tableSize = 1 << tableLog;\n    U32 highThreshold = tableSize-1;\n\n    /* Sanity Checks */\n    assert(maxSymbolValue <= MaxSeq);\n    assert(tableLog <= MaxFSELog);\n\n    /* Init, lay down lowprob symbols */\n    {   ZSTD_seqSymbol_header DTableH;\n        DTableH.tableLog = tableLog;\n        DTableH.fastMode = 1;\n        {   S16 const largeLimit= (S16)(1 << (tableLog-1));\n            U32 s;\n            for (s=0; s<maxSV1; s++) {\n                if (normalizedCounter[s]==-1) {\n                    tableDecode[highThreshold--].baseValue = s;\n                    symbolNext[s] = 1;\n                } else {\n                    if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;\n                    assert(normalizedCounter[s]>=0);\n                    symbolNext[s] = (U16)normalizedCounter[s];\n        }   }   }\n        memcpy(dt, &DTableH, sizeof(DTableH));\n    }\n\n    /* Spread symbols */\n    {   U32 const tableMask = tableSize-1;\n        U32 const step = FSE_TABLESTEP(tableSize);\n        U32 s, position = 0;\n        for (s=0; s<maxSV1; s++) {\n            int i;\n            for (i=0; i<normalizedCounter[s]; i++) {\n                tableDecode[position].baseValue = s;\n                position = (position + step) & tableMask;\n                while (position > highThreshold) position = (position + step) & tableMask;   /* lowprob area */\n        }   }\n        assert(position == 0); /* position must reach all cells once, otherwise normalizedCounter is incorrect */\n    }\n\n    /* Build Decoding table */\n    {   U32 u;\n        for (u=0; u<tableSize; u++) {\n            U32 const symbol = tableDecode[u].baseValue;\n            U32 const nextState = symbolNext[symbol]++;\n            tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32(nextState) );\n            tableDecode[u].nextState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);\n            assert(nbAdditionalBits[symbol] < 255);\n            tableDecode[u].nbAdditionalBits = (BYTE)nbAdditionalBits[symbol];\n            tableDecode[u].baseValue = baseValue[symbol];\n    }   }\n}\n\n\n/*! ZSTD_buildSeqTable() :\n * @return : nb bytes read from src,\n *           or an error code if it fails */\nstatic size_t ZSTD_buildSeqTable(ZSTD_seqSymbol* DTableSpace, const ZSTD_seqSymbol** DTablePtr,\n                                 symbolEncodingType_e type, unsigned max, U32 maxLog,\n                                 const void* src, size_t srcSize,\n                                 const U32* baseValue, const U32* nbAdditionalBits,\n                                 const ZSTD_seqSymbol* defaultTable, U32 flagRepeatTable,\n                                 int ddictIsCold, int nbSeq)\n{\n    switch(type)\n    {\n    case set_rle :\n        RETURN_ERROR_IF(!srcSize, srcSize_wrong);\n        RETURN_ERROR_IF((*(const BYTE*)src) > max, corruption_detected);\n        {   U32 const symbol = *(const BYTE*)src;\n            U32 const baseline = baseValue[symbol];\n            U32 const nbBits = nbAdditionalBits[symbol];\n            ZSTD_buildSeqTable_rle(DTableSpace, baseline, nbBits);\n        }\n        *DTablePtr = DTableSpace;\n        return 1;\n    case set_basic :\n        *DTablePtr = defaultTable;\n        return 0;\n    case set_repeat:\n        RETURN_ERROR_IF(!flagRepeatTable, corruption_detected);\n        /* prefetch FSE table if used */\n        if (ddictIsCold && (nbSeq > 24 /* heuristic */)) {\n            const void* const pStart = *DTablePtr;\n            size_t const pSize = sizeof(ZSTD_seqSymbol) * (SEQSYMBOL_TABLE_SIZE(maxLog));\n            PREFETCH_AREA(pStart, pSize);\n        }\n        return 0;\n    case set_compressed :\n        {   unsigned tableLog;\n            S16 norm[MaxSeq+1];\n            size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);\n            RETURN_ERROR_IF(FSE_isError(headerSize), corruption_detected);\n            RETURN_ERROR_IF(tableLog > maxLog, corruption_detected);\n            ZSTD_buildFSETable(DTableSpace, norm, max, baseValue, nbAdditionalBits, tableLog);\n            *DTablePtr = DTableSpace;\n            return headerSize;\n        }\n    default :\n        assert(0);\n        RETURN_ERROR(GENERIC, \"impossible\");\n    }\n}\n\nsize_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,\n                             const void* src, size_t srcSize)\n{\n    const BYTE* const istart = (const BYTE* const)src;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* ip = istart;\n    int nbSeq;\n    DEBUGLOG(5, \"ZSTD_decodeSeqHeaders\");\n\n    /* check */\n    RETURN_ERROR_IF(srcSize < MIN_SEQUENCES_SIZE, srcSize_wrong);\n\n    /* SeqHead */\n    nbSeq = *ip++;\n    if (!nbSeq) {\n        *nbSeqPtr=0;\n        RETURN_ERROR_IF(srcSize != 1, srcSize_wrong);\n        return 1;\n    }\n    if (nbSeq > 0x7F) {\n        if (nbSeq == 0xFF) {\n            RETURN_ERROR_IF(ip+2 > iend, srcSize_wrong);\n            nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;\n        } else {\n            RETURN_ERROR_IF(ip >= iend, srcSize_wrong);\n            nbSeq = ((nbSeq-0x80)<<8) + *ip++;\n        }\n    }\n    *nbSeqPtr = nbSeq;\n\n    /* FSE table descriptors */\n    RETURN_ERROR_IF(ip+1 > iend, srcSize_wrong); /* minimum possible size: 1 byte for symbol encoding types */\n    {   symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);\n        symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);\n        symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);\n        ip++;\n\n        /* Build DTables */\n        {   size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,\n                                                      LLtype, MaxLL, LLFSELog,\n                                                      ip, iend-ip,\n                                                      LL_base, LL_bits,\n                                                      LL_defaultDTable, dctx->fseEntropy,\n                                                      dctx->ddictIsCold, nbSeq);\n            RETURN_ERROR_IF(ZSTD_isError(llhSize), corruption_detected);\n            ip += llhSize;\n        }\n\n        {   size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,\n                                                      OFtype, MaxOff, OffFSELog,\n                                                      ip, iend-ip,\n                                                      OF_base, OF_bits,\n                                                      OF_defaultDTable, dctx->fseEntropy,\n                                                      dctx->ddictIsCold, nbSeq);\n            RETURN_ERROR_IF(ZSTD_isError(ofhSize), corruption_detected);\n            ip += ofhSize;\n        }\n\n        {   size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,\n                                                      MLtype, MaxML, MLFSELog,\n                                                      ip, iend-ip,\n                                                      ML_base, ML_bits,\n                                                      ML_defaultDTable, dctx->fseEntropy,\n                                                      dctx->ddictIsCold, nbSeq);\n            RETURN_ERROR_IF(ZSTD_isError(mlhSize), corruption_detected);\n            ip += mlhSize;\n        }\n    }\n\n    return ip-istart;\n}\n\n\ntypedef struct {\n    size_t litLength;\n    size_t matchLength;\n    size_t offset;\n    const BYTE* match;\n} seq_t;\n\ntypedef struct {\n    size_t state;\n    const ZSTD_seqSymbol* table;\n} ZSTD_fseState;\n\ntypedef struct {\n    BIT_DStream_t DStream;\n    ZSTD_fseState stateLL;\n    ZSTD_fseState stateOffb;\n    ZSTD_fseState stateML;\n    size_t prevOffset[ZSTD_REP_NUM];\n    const BYTE* prefixStart;\n    const BYTE* dictEnd;\n    size_t pos;\n} seqState_t;\n\n/*! ZSTD_overlapCopy8() :\n *  Copies 8 bytes from ip to op and updates op and ip where ip <= op.\n *  If the offset is < 8 then the offset is spread to at least 8 bytes.\n *\n *  Precondition: *ip <= *op\n *  Postcondition: *op - *op >= 8\n */\nstatic void ZSTD_overlapCopy8(BYTE** op, BYTE const** ip, size_t offset) {\n    assert(*ip <= *op);\n    if (offset < 8) {\n        /* close range match, overlap */\n        static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };   /* added */\n        static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 };   /* subtracted */\n        int const sub2 = dec64table[offset];\n        (*op)[0] = (*ip)[0];\n        (*op)[1] = (*ip)[1];\n        (*op)[2] = (*ip)[2];\n        (*op)[3] = (*ip)[3];\n        *ip += dec32table[offset];\n        ZSTD_copy4(*op+4, *ip);\n        *ip -= sub2;\n    } else {\n        ZSTD_copy8(*op, *ip);\n    }\n    *ip += 8;\n    *op += 8;\n    assert(*op - *ip >= 8);\n}\n\n/*! ZSTD_safecopy() :\n *  Specialized version of memcpy() that is allowed to READ up to WILDCOPY_OVERLENGTH past the input buffer\n *  and write up to 16 bytes past oend_w (op >= oend_w is allowed).\n *  This function is only called in the uncommon case where the sequence is near the end of the block. It\n *  should be fast for a single long sequence, but can be slow for several short sequences.\n *\n *  @param ovtype controls the overlap detection\n *         - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.\n *         - ZSTD_overlap_src_before_dst: The src and dst may overlap and may be any distance apart.\n *           The src buffer must be before the dst buffer.\n */\nstatic void ZSTD_safecopy(BYTE* op, BYTE* const oend_w, BYTE const* ip, ptrdiff_t length, ZSTD_overlap_e ovtype) {\n    ptrdiff_t const diff = op - ip;\n    BYTE* const oend = op + length;\n\n    assert((ovtype == ZSTD_no_overlap && (diff <= -8 || diff >= 8 || op >= oend_w)) ||\n           (ovtype == ZSTD_overlap_src_before_dst && diff >= 0));\n\n    if (length < 8) {\n        /* Handle short lengths. */\n        while (op < oend) *op++ = *ip++;\n        return;\n    }\n    if (ovtype == ZSTD_overlap_src_before_dst) {\n        /* Copy 8 bytes and ensure the offset >= 8 when there can be overlap. */\n        assert(length >= 8);\n        ZSTD_overlapCopy8(&op, &ip, diff);\n        assert(op - ip >= 8);\n        assert(op <= oend);\n    }\n\n    if (oend <= oend_w) {\n        /* No risk of overwrite. */\n        ZSTD_wildcopy(op, ip, length, ovtype);\n        return;\n    }\n    if (op <= oend_w) {\n        /* Wildcopy until we get close to the end. */\n        assert(oend > oend_w);\n        ZSTD_wildcopy(op, ip, oend_w - op, ovtype);\n        ip += oend_w - op;\n        op = oend_w;\n    }\n    /* Handle the leftovers. */\n    while (op < oend) *op++ = *ip++;\n}\n\n/* ZSTD_execSequenceEnd():\n * This version handles cases that are near the end of the output buffer. It requires\n * more careful checks to make sure there is no overflow. By separating out these hard\n * and unlikely cases, we can speed up the common cases.\n *\n * NOTE: This function needs to be fast for a single long sequence, but doesn't need\n * to be optimized for many small sequences, since those fall into ZSTD_execSequence().\n */\nFORCE_NOINLINE\nsize_t ZSTD_execSequenceEnd(BYTE* op,\n                            BYTE* const oend, seq_t sequence,\n                            const BYTE** litPtr, const BYTE* const litLimit,\n                            const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)\n{\n    BYTE* const oLitEnd = op + sequence.litLength;\n    size_t const sequenceLength = sequence.litLength + sequence.matchLength;\n    BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */\n    const BYTE* const iLitEnd = *litPtr + sequence.litLength;\n    const BYTE* match = oLitEnd - sequence.offset;\n    BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;\n\n    /* bounds checks */\n    assert(oLitEnd < oMatchEnd);\n    RETURN_ERROR_IF(oMatchEnd > oend, dstSize_tooSmall, \"last match must fit within dstBuffer\");\n    RETURN_ERROR_IF(iLitEnd > litLimit, corruption_detected, \"try to read beyond literal buffer\");\n\n    /* copy literals */\n    ZSTD_safecopy(op, oend_w, *litPtr, sequence.litLength, ZSTD_no_overlap);\n    op = oLitEnd;\n    *litPtr = iLitEnd;\n\n    /* copy Match */\n    if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {\n        /* offset beyond prefix */\n        RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected);\n        match = dictEnd - (prefixStart-match);\n        if (match + sequence.matchLength <= dictEnd) {\n            memmove(oLitEnd, match, sequence.matchLength);\n            return sequenceLength;\n        }\n        /* span extDict & currentPrefixSegment */\n        {   size_t const length1 = dictEnd - match;\n            memmove(oLitEnd, match, length1);\n            op = oLitEnd + length1;\n            sequence.matchLength -= length1;\n            match = prefixStart;\n    }   }\n    ZSTD_safecopy(op, oend_w, match, sequence.matchLength, ZSTD_overlap_src_before_dst);\n    return sequenceLength;\n}\n\nHINT_INLINE\nsize_t ZSTD_execSequence(BYTE* op,\n                         BYTE* const oend, seq_t sequence,\n                         const BYTE** litPtr, const BYTE* const litLimit,\n                         const BYTE* const prefixStart, const BYTE* const virtualStart, const BYTE* const dictEnd)\n{\n    BYTE* const oLitEnd = op + sequence.litLength;\n    size_t const sequenceLength = sequence.litLength + sequence.matchLength;\n    BYTE* const oMatchEnd = op + sequenceLength;   /* risk : address space overflow (32-bits) */\n    BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;\n    const BYTE* const iLitEnd = *litPtr + sequence.litLength;\n    const BYTE* match = oLitEnd - sequence.offset;\n\n    /* Errors and uncommon cases handled here. */\n    assert(oLitEnd < oMatchEnd);\n    if (iLitEnd > litLimit || oMatchEnd > oend_w)\n        return ZSTD_execSequenceEnd(op, oend, sequence, litPtr, litLimit, prefixStart, virtualStart, dictEnd);\n\n    /* Assumptions (everything else goes into ZSTD_execSequenceEnd()) */\n    assert(iLitEnd <= litLimit /* Literal length is in bounds */);\n    assert(oLitEnd <= oend_w /* Can wildcopy literals */);\n    assert(oMatchEnd <= oend_w /* Can wildcopy matches */);\n\n    /* Copy Literals:\n     * Split out litLength <= 16 since it is nearly always true. +1.6% on gcc-9.\n     * We likely don't need the full 32-byte wildcopy.\n     */\n    assert(WILDCOPY_OVERLENGTH >= 16);\n    ZSTD_copy16(op, (*litPtr));\n    if (sequence.litLength > 16) {\n        ZSTD_wildcopy(op+16, (*litPtr)+16, sequence.litLength-16, ZSTD_no_overlap);\n    }\n    op = oLitEnd;\n    *litPtr = iLitEnd;   /* update for next sequence */\n\n    /* Copy Match */\n    if (sequence.offset > (size_t)(oLitEnd - prefixStart)) {\n        /* offset beyond prefix -> go into extDict */\n        RETURN_ERROR_IF(sequence.offset > (size_t)(oLitEnd - virtualStart), corruption_detected);\n        match = dictEnd + (match - prefixStart);\n        if (match + sequence.matchLength <= dictEnd) {\n            memmove(oLitEnd, match, sequence.matchLength);\n            return sequenceLength;\n        }\n        /* span extDict & currentPrefixSegment */\n        {   size_t const length1 = dictEnd - match;\n            memmove(oLitEnd, match, length1);\n            op = oLitEnd + length1;\n            sequence.matchLength -= length1;\n            match = prefixStart;\n    }   }\n    /* Match within prefix of 1 or more bytes */\n    assert(op <= oMatchEnd);\n    assert(oMatchEnd <= oend_w);\n    assert(match >= prefixStart);\n    assert(sequence.matchLength >= 1);\n\n    /* Nearly all offsets are >= WILDCOPY_VECLEN bytes, which means we can use wildcopy\n     * without overlap checking.\n     */\n    if (sequence.offset >= WILDCOPY_VECLEN) {\n        /* We bet on a full wildcopy for matches, since we expect matches to be\n         * longer than literals (in general). In silesia, ~10% of matches are longer\n         * than 16 bytes.\n         */\n        ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength, ZSTD_no_overlap);\n        return sequenceLength;\n    }\n    assert(sequence.offset < WILDCOPY_VECLEN);\n\n    /* Copy 8 bytes and spread the offset to be >= 8. */\n    ZSTD_overlapCopy8(&op, &match, sequence.offset);\n\n    /* If the match length is > 8 bytes, then continue with the wildcopy. */\n    if (sequence.matchLength > 8) {\n        assert(op < oMatchEnd);\n        ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8, ZSTD_overlap_src_before_dst);\n    }\n    return sequenceLength;\n}\n\nstatic void\nZSTD_initFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD, const ZSTD_seqSymbol* dt)\n{\n    const void* ptr = dt;\n    const ZSTD_seqSymbol_header* const DTableH = (const ZSTD_seqSymbol_header*)ptr;\n    DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);\n    DEBUGLOG(6, \"ZSTD_initFseState : val=%u using %u bits\",\n                (U32)DStatePtr->state, DTableH->tableLog);\n    BIT_reloadDStream(bitD);\n    DStatePtr->table = dt + 1;\n}\n\nFORCE_INLINE_TEMPLATE void\nZSTD_updateFseState(ZSTD_fseState* DStatePtr, BIT_DStream_t* bitD)\n{\n    ZSTD_seqSymbol const DInfo = DStatePtr->table[DStatePtr->state];\n    U32 const nbBits = DInfo.nbBits;\n    size_t const lowBits = BIT_readBits(bitD, nbBits);\n    DStatePtr->state = DInfo.nextState + lowBits;\n}\n\n/* We need to add at most (ZSTD_WINDOWLOG_MAX_32 - 1) bits to read the maximum\n * offset bits. But we can only read at most (STREAM_ACCUMULATOR_MIN_32 - 1)\n * bits before reloading. This value is the maximum number of bytes we read\n * after reloading when we are decoding long offsets.\n */\n#define LONG_OFFSETS_MAX_EXTRA_BITS_32                       \\\n    (ZSTD_WINDOWLOG_MAX_32 > STREAM_ACCUMULATOR_MIN_32       \\\n        ? ZSTD_WINDOWLOG_MAX_32 - STREAM_ACCUMULATOR_MIN_32  \\\n        : 0)\n\ntypedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset_e;\n\n#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG\nFORCE_INLINE_TEMPLATE seq_t\nZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)\n{\n    seq_t seq;\n    U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits;\n    U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits;\n    U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits;\n    U32 const totalBits = llBits+mlBits+ofBits;\n    U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue;\n    U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue;\n    U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue;\n\n    /* sequence */\n    {   size_t offset;\n        if (!ofBits)\n            offset = 0;\n        else {\n            ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);\n            ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);\n            assert(ofBits <= MaxOff);\n            if (MEM_32bits() && longOffsets && (ofBits >= STREAM_ACCUMULATOR_MIN_32)) {\n                U32 const extraBits = ofBits - MIN(ofBits, 32 - seqState->DStream.bitsConsumed);\n                offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);\n                BIT_reloadDStream(&seqState->DStream);\n                if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);\n                assert(extraBits <= LONG_OFFSETS_MAX_EXTRA_BITS_32);   /* to avoid another reload */\n            } else {\n                offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits/*>0*/);   /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */\n                if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);\n            }\n        }\n\n        if (ofBits <= 1) {\n            offset += (llBase==0);\n            if (offset) {\n                size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];\n                temp += !temp;   /* 0 is not valid; input is corrupted; force offset to 1 */\n                if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];\n                seqState->prevOffset[1] = seqState->prevOffset[0];\n                seqState->prevOffset[0] = offset = temp;\n            } else {  /* offset == 0 */\n                offset = seqState->prevOffset[0];\n            }\n        } else {\n            seqState->prevOffset[2] = seqState->prevOffset[1];\n            seqState->prevOffset[1] = seqState->prevOffset[0];\n            seqState->prevOffset[0] = offset;\n        }\n        seq.offset = offset;\n    }\n\n    seq.matchLength = mlBase\n                    + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits/*>0*/) : 0);  /* <=  16 bits */\n    if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))\n        BIT_reloadDStream(&seqState->DStream);\n    if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))\n        BIT_reloadDStream(&seqState->DStream);\n    /* Ensure there are enough bits to read the rest of data in 64-bit mode. */\n    ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);\n\n    seq.litLength = llBase\n                  + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits/*>0*/) : 0);    /* <=  16 bits */\n    if (MEM_32bits())\n        BIT_reloadDStream(&seqState->DStream);\n\n    DEBUGLOG(6, \"seq: litL=%u, matchL=%u, offset=%u\",\n                (U32)seq.litLength, (U32)seq.matchLength, (U32)seq.offset);\n\n    /* ANS state update */\n    ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */\n    ZSTD_updateFseState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */\n    if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */\n    ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */\n\n    return seq;\n}\n\nFORCE_INLINE_TEMPLATE size_t\nDONT_VECTORIZE\nZSTD_decompressSequences_body( ZSTD_DCtx* dctx,\n                               void* dst, size_t maxDstSize,\n                         const void* seqStart, size_t seqSize, int nbSeq,\n                         const ZSTD_longOffset_e isLongOffset)\n{\n    const BYTE* ip = (const BYTE*)seqStart;\n    const BYTE* const iend = ip + seqSize;\n    BYTE* const ostart = (BYTE* const)dst;\n    BYTE* const oend = ostart + maxDstSize;\n    BYTE* op = ostart;\n    const BYTE* litPtr = dctx->litPtr;\n    const BYTE* const litEnd = litPtr + dctx->litSize;\n    const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);\n    const BYTE* const vBase = (const BYTE*) (dctx->virtualStart);\n    const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);\n    DEBUGLOG(5, \"ZSTD_decompressSequences_body\");\n\n    /* Regen sequences */\n    if (nbSeq) {\n        seqState_t seqState;\n        dctx->fseEntropy = 1;\n        { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }\n        RETURN_ERROR_IF(\n            ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),\n            corruption_detected);\n        ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);\n        ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);\n        ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);\n\n        ZSTD_STATIC_ASSERT(\n                BIT_DStream_unfinished < BIT_DStream_completed &&\n                BIT_DStream_endOfBuffer < BIT_DStream_completed &&\n                BIT_DStream_completed < BIT_DStream_overflow);\n\n        for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {\n            nbSeq--;\n            {   seq_t const sequence = ZSTD_decodeSequence(&seqState, isLongOffset);\n                size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, prefixStart, vBase, dictEnd);\n                DEBUGLOG(6, \"regenerated sequence size : %u\", (U32)oneSeqSize);\n                if (ZSTD_isError(oneSeqSize)) return oneSeqSize;\n                op += oneSeqSize;\n        }   }\n\n        /* check if reached exact end */\n        DEBUGLOG(5, \"ZSTD_decompressSequences_body: after decode loop, remaining nbSeq : %i\", nbSeq);\n        RETURN_ERROR_IF(nbSeq, corruption_detected);\n        RETURN_ERROR_IF(BIT_reloadDStream(&seqState.DStream) < BIT_DStream_completed, corruption_detected);\n        /* save reps for next block */\n        { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }\n    }\n\n    /* last literal segment */\n    {   size_t const lastLLSize = litEnd - litPtr;\n        RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall);\n        memcpy(op, litPtr, lastLLSize);\n        op += lastLLSize;\n    }\n\n    return op-ostart;\n}\n\nstatic size_t\nZSTD_decompressSequences_default(ZSTD_DCtx* dctx,\n                                 void* dst, size_t maxDstSize,\n                           const void* seqStart, size_t seqSize, int nbSeq,\n                           const ZSTD_longOffset_e isLongOffset)\n{\n    return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);\n}\n#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */\n\n\n\n#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT\nFORCE_INLINE_TEMPLATE seq_t\nZSTD_decodeSequenceLong(seqState_t* seqState, ZSTD_longOffset_e const longOffsets)\n{\n    seq_t seq;\n    U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits;\n    U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits;\n    U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits;\n    U32 const totalBits = llBits+mlBits+ofBits;\n    U32 const llBase = seqState->stateLL.table[seqState->stateLL.state].baseValue;\n    U32 const mlBase = seqState->stateML.table[seqState->stateML.state].baseValue;\n    U32 const ofBase = seqState->stateOffb.table[seqState->stateOffb.state].baseValue;\n\n    /* sequence */\n    {   size_t offset;\n        if (!ofBits)\n            offset = 0;\n        else {\n            ZSTD_STATIC_ASSERT(ZSTD_lo_isLongOffset == 1);\n            ZSTD_STATIC_ASSERT(LONG_OFFSETS_MAX_EXTRA_BITS_32 == 5);\n            assert(ofBits <= MaxOff);\n            if (MEM_32bits() && longOffsets) {\n                U32 const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN_32-1);\n                offset = ofBase + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);\n                if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);\n                if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);\n            } else {\n                offset = ofBase + BIT_readBitsFast(&seqState->DStream, ofBits);   /* <=  (ZSTD_WINDOWLOG_MAX-1) bits */\n                if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);\n            }\n        }\n\n        if (ofBits <= 1) {\n            offset += (llBase==0);\n            if (offset) {\n                size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];\n                temp += !temp;   /* 0 is not valid; input is corrupted; force offset to 1 */\n                if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];\n                seqState->prevOffset[1] = seqState->prevOffset[0];\n                seqState->prevOffset[0] = offset = temp;\n            } else {\n                offset = seqState->prevOffset[0];\n            }\n        } else {\n            seqState->prevOffset[2] = seqState->prevOffset[1];\n            seqState->prevOffset[1] = seqState->prevOffset[0];\n            seqState->prevOffset[0] = offset;\n        }\n        seq.offset = offset;\n    }\n\n    seq.matchLength = mlBase + ((mlBits>0) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0);  /* <=  16 bits */\n    if (MEM_32bits() && (mlBits+llBits >= STREAM_ACCUMULATOR_MIN_32-LONG_OFFSETS_MAX_EXTRA_BITS_32))\n        BIT_reloadDStream(&seqState->DStream);\n    if (MEM_64bits() && (totalBits >= STREAM_ACCUMULATOR_MIN_64-(LLFSELog+MLFSELog+OffFSELog)))\n        BIT_reloadDStream(&seqState->DStream);\n    /* Verify that there is enough bits to read the rest of the data in 64-bit mode. */\n    ZSTD_STATIC_ASSERT(16+LLFSELog+MLFSELog+OffFSELog < STREAM_ACCUMULATOR_MIN_64);\n\n    seq.litLength = llBase + ((llBits>0) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0);    /* <=  16 bits */\n    if (MEM_32bits())\n        BIT_reloadDStream(&seqState->DStream);\n\n    {   size_t const pos = seqState->pos + seq.litLength;\n        const BYTE* const matchBase = (seq.offset > pos) ? seqState->dictEnd : seqState->prefixStart;\n        seq.match = matchBase + pos - seq.offset;  /* note : this operation can overflow when seq.offset is really too large, which can only happen when input is corrupted.\n                                                    * No consequence though : no memory access will occur, overly large offset will be detected in ZSTD_execSequenceLong() */\n        seqState->pos = pos + seq.matchLength;\n    }\n\n    /* ANS state update */\n    ZSTD_updateFseState(&seqState->stateLL, &seqState->DStream);    /* <=  9 bits */\n    ZSTD_updateFseState(&seqState->stateML, &seqState->DStream);    /* <=  9 bits */\n    if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);    /* <= 18 bits */\n    ZSTD_updateFseState(&seqState->stateOffb, &seqState->DStream);  /* <=  8 bits */\n\n    return seq;\n}\n\nFORCE_INLINE_TEMPLATE size_t\nZSTD_decompressSequencesLong_body(\n                               ZSTD_DCtx* dctx,\n                               void* dst, size_t maxDstSize,\n                         const void* seqStart, size_t seqSize, int nbSeq,\n                         const ZSTD_longOffset_e isLongOffset)\n{\n    const BYTE* ip = (const BYTE*)seqStart;\n    const BYTE* const iend = ip + seqSize;\n    BYTE* const ostart = (BYTE* const)dst;\n    BYTE* const oend = ostart + maxDstSize;\n    BYTE* op = ostart;\n    const BYTE* litPtr = dctx->litPtr;\n    const BYTE* const litEnd = litPtr + dctx->litSize;\n    const BYTE* const prefixStart = (const BYTE*) (dctx->prefixStart);\n    const BYTE* const dictStart = (const BYTE*) (dctx->virtualStart);\n    const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);\n\n    /* Regen sequences */\n    if (nbSeq) {\n#define STORED_SEQS 4\n#define STORED_SEQS_MASK (STORED_SEQS-1)\n#define ADVANCED_SEQS 4\n        seq_t sequences[STORED_SEQS];\n        int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);\n        seqState_t seqState;\n        int seqNb;\n        dctx->fseEntropy = 1;\n        { int i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }\n        seqState.prefixStart = prefixStart;\n        seqState.pos = (size_t)(op-prefixStart);\n        seqState.dictEnd = dictEnd;\n        assert(iend >= ip);\n        RETURN_ERROR_IF(\n            ERR_isError(BIT_initDStream(&seqState.DStream, ip, iend-ip)),\n            corruption_detected);\n        ZSTD_initFseState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);\n        ZSTD_initFseState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);\n        ZSTD_initFseState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);\n\n        /* prepare in advance */\n        for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && (seqNb<seqAdvance); seqNb++) {\n            sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, isLongOffset);\n            PREFETCH_L1(sequences[seqNb].match); PREFETCH_L1(sequences[seqNb].match + sequences[seqNb].matchLength - 1); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */\n        }\n        RETURN_ERROR_IF(seqNb<seqAdvance, corruption_detected);\n\n        /* decode and decompress */\n        for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && (seqNb<nbSeq) ; seqNb++) {\n            seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, isLongOffset);\n            size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);\n            if (ZSTD_isError(oneSeqSize)) return oneSeqSize;\n            PREFETCH_L1(sequence.match); PREFETCH_L1(sequence.match + sequence.matchLength - 1); /* note : it's safe to invoke PREFETCH() on any memory address, including invalid ones */\n            sequences[seqNb & STORED_SEQS_MASK] = sequence;\n            op += oneSeqSize;\n        }\n        RETURN_ERROR_IF(seqNb<nbSeq, corruption_detected);\n\n        /* finish queue */\n        seqNb -= seqAdvance;\n        for ( ; seqNb<nbSeq ; seqNb++) {\n            size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequences[seqNb&STORED_SEQS_MASK], &litPtr, litEnd, prefixStart, dictStart, dictEnd);\n            if (ZSTD_isError(oneSeqSize)) return oneSeqSize;\n            op += oneSeqSize;\n        }\n\n        /* save reps for next block */\n        { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }\n    }\n\n    /* last literal segment */\n    {   size_t const lastLLSize = litEnd - litPtr;\n        RETURN_ERROR_IF(lastLLSize > (size_t)(oend-op), dstSize_tooSmall);\n        memcpy(op, litPtr, lastLLSize);\n        op += lastLLSize;\n    }\n\n    return op-ostart;\n}\n\nstatic size_t\nZSTD_decompressSequencesLong_default(ZSTD_DCtx* dctx,\n                                 void* dst, size_t maxDstSize,\n                           const void* seqStart, size_t seqSize, int nbSeq,\n                           const ZSTD_longOffset_e isLongOffset)\n{\n    return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);\n}\n#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */\n\n\n\n#if DYNAMIC_BMI2\n\n#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG\nstatic TARGET_ATTRIBUTE(\"bmi2\") size_t\nDONT_VECTORIZE\nZSTD_decompressSequences_bmi2(ZSTD_DCtx* dctx,\n                                 void* dst, size_t maxDstSize,\n                           const void* seqStart, size_t seqSize, int nbSeq,\n                           const ZSTD_longOffset_e isLongOffset)\n{\n    return ZSTD_decompressSequences_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);\n}\n#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */\n\n#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT\nstatic TARGET_ATTRIBUTE(\"bmi2\") size_t\nZSTD_decompressSequencesLong_bmi2(ZSTD_DCtx* dctx,\n                                 void* dst, size_t maxDstSize,\n                           const void* seqStart, size_t seqSize, int nbSeq,\n                           const ZSTD_longOffset_e isLongOffset)\n{\n    return ZSTD_decompressSequencesLong_body(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);\n}\n#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */\n\n#endif /* DYNAMIC_BMI2 */\n\ntypedef size_t (*ZSTD_decompressSequences_t)(\n                            ZSTD_DCtx* dctx,\n                            void* dst, size_t maxDstSize,\n                            const void* seqStart, size_t seqSize, int nbSeq,\n                            const ZSTD_longOffset_e isLongOffset);\n\n#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG\nstatic size_t\nZSTD_decompressSequences(ZSTD_DCtx* dctx, void* dst, size_t maxDstSize,\n                   const void* seqStart, size_t seqSize, int nbSeq,\n                   const ZSTD_longOffset_e isLongOffset)\n{\n    DEBUGLOG(5, \"ZSTD_decompressSequences\");\n#if DYNAMIC_BMI2\n    if (dctx->bmi2) {\n        return ZSTD_decompressSequences_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);\n    }\n#endif\n  return ZSTD_decompressSequences_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);\n}\n#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG */\n\n\n#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT\n/* ZSTD_decompressSequencesLong() :\n * decompression function triggered when a minimum share of offsets is considered \"long\",\n * aka out of cache.\n * note : \"long\" definition seems overloaded here, sometimes meaning \"wider than bitstream register\", and sometimes meaning \"farther than memory cache distance\".\n * This function will try to mitigate main memory latency through the use of prefetching */\nstatic size_t\nZSTD_decompressSequencesLong(ZSTD_DCtx* dctx,\n                             void* dst, size_t maxDstSize,\n                             const void* seqStart, size_t seqSize, int nbSeq,\n                             const ZSTD_longOffset_e isLongOffset)\n{\n    DEBUGLOG(5, \"ZSTD_decompressSequencesLong\");\n#if DYNAMIC_BMI2\n    if (dctx->bmi2) {\n        return ZSTD_decompressSequencesLong_bmi2(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);\n    }\n#endif\n  return ZSTD_decompressSequencesLong_default(dctx, dst, maxDstSize, seqStart, seqSize, nbSeq, isLongOffset);\n}\n#endif /* ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT */\n\n\n\n#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \\\n    !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)\n/* ZSTD_getLongOffsetsShare() :\n * condition : offTable must be valid\n * @return : \"share\" of long offsets (arbitrarily defined as > (1<<23))\n *           compared to maximum possible of (1<<OffFSELog) */\nstatic unsigned\nZSTD_getLongOffsetsShare(const ZSTD_seqSymbol* offTable)\n{\n    const void* ptr = offTable;\n    U32 const tableLog = ((const ZSTD_seqSymbol_header*)ptr)[0].tableLog;\n    const ZSTD_seqSymbol* table = offTable + 1;\n    U32 const max = 1 << tableLog;\n    U32 u, total = 0;\n    DEBUGLOG(5, \"ZSTD_getLongOffsetsShare: (tableLog=%u)\", tableLog);\n\n    assert(max <= (1 << OffFSELog));  /* max not too large */\n    for (u=0; u<max; u++) {\n        if (table[u].nbAdditionalBits > 22) total += 1;\n    }\n\n    assert(tableLog <= OffFSELog);\n    total <<= (OffFSELog - tableLog);  /* scale to OffFSELog */\n\n    return total;\n}\n#endif\n\n\nsize_t\nZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,\n                              void* dst, size_t dstCapacity,\n                        const void* src, size_t srcSize, const int frame)\n{   /* blockType == blockCompressed */\n    const BYTE* ip = (const BYTE*)src;\n    /* isLongOffset must be true if there are long offsets.\n     * Offsets are long if they are larger than 2^STREAM_ACCUMULATOR_MIN.\n     * We don't expect that to be the case in 64-bit mode.\n     * In block mode, window size is not known, so we have to be conservative.\n     * (note: but it could be evaluated from current-lowLimit)\n     */\n    ZSTD_longOffset_e const isLongOffset = (ZSTD_longOffset_e)(MEM_32bits() && (!frame || (dctx->fParams.windowSize > (1ULL << STREAM_ACCUMULATOR_MIN))));\n    DEBUGLOG(5, \"ZSTD_decompressBlock_internal (size : %u)\", (U32)srcSize);\n\n    RETURN_ERROR_IF(srcSize >= ZSTD_BLOCKSIZE_MAX, srcSize_wrong);\n\n    /* Decode literals section */\n    {   size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);\n        DEBUGLOG(5, \"ZSTD_decodeLiteralsBlock : %u\", (U32)litCSize);\n        if (ZSTD_isError(litCSize)) return litCSize;\n        ip += litCSize;\n        srcSize -= litCSize;\n    }\n\n    /* Build Decoding Tables */\n    {\n        /* These macros control at build-time which decompressor implementation\n         * we use. If neither is defined, we do some inspection and dispatch at\n         * runtime.\n         */\n#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \\\n    !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)\n        int usePrefetchDecoder = dctx->ddictIsCold;\n#endif\n        int nbSeq;\n        size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, srcSize);\n        if (ZSTD_isError(seqHSize)) return seqHSize;\n        ip += seqHSize;\n        srcSize -= seqHSize;\n\n#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \\\n    !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)\n        if ( !usePrefetchDecoder\n          && (!frame || (dctx->fParams.windowSize > (1<<24)))\n          && (nbSeq>ADVANCED_SEQS) ) {  /* could probably use a larger nbSeq limit */\n            U32 const shareLongOffsets = ZSTD_getLongOffsetsShare(dctx->OFTptr);\n            U32 const minShare = MEM_64bits() ? 7 : 20; /* heuristic values, correspond to 2.73% and 7.81% */\n            usePrefetchDecoder = (shareLongOffsets >= minShare);\n        }\n#endif\n\n        dctx->ddictIsCold = 0;\n\n#if !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \\\n    !defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG)\n        if (usePrefetchDecoder)\n#endif\n#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT\n            return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);\n#endif\n\n#ifndef ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG\n        /* else */\n        return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize, nbSeq, isLongOffset);\n#endif\n    }\n}\n\n\nsize_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,\n                            void* dst, size_t dstCapacity,\n                      const void* src, size_t srcSize)\n{\n    size_t dSize;\n    ZSTD_checkContinuity(dctx, dst);\n    dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize, /* frame */ 0);\n    dctx->previousDstEnd = (char*)dst + dSize;\n    return dSize;\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_decompress_block.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n\n#ifndef ZSTD_DEC_BLOCK_H\n#define ZSTD_DEC_BLOCK_H\n\n/*-*******************************************************\n *  Dependencies\n *********************************************************/\n#include <stddef.h>   /* size_t */\n#include \"zstd.h\"    /* DCtx, and some public functions */\n#include \"zstd_internal.h\"  /* blockProperties_t, and some public functions */\n#include \"zstd_decompress_internal.h\"  /* ZSTD_seqSymbol */\n\n\n/* ===   Prototypes   === */\n\n/* note: prototypes already published within `zstd.h` :\n * ZSTD_decompressBlock()\n */\n\n/* note: prototypes already published within `zstd_internal.h` :\n * ZSTD_getcBlockSize()\n * ZSTD_decodeSeqHeaders()\n */\n\n\n/* ZSTD_decompressBlock_internal() :\n * decompress block, starting at `src`,\n * into destination buffer `dst`.\n * @return : decompressed block size,\n *           or an error code (which can be tested using ZSTD_isError())\n */\nsize_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,\n                               void* dst, size_t dstCapacity,\n                         const void* src, size_t srcSize, const int frame);\n\n/* ZSTD_buildFSETable() :\n * generate FSE decoding table for one symbol (ll, ml or off)\n * this function must be called with valid parameters only\n * (dt is large enough, normalizedCounter distribution total is a power of 2, max is within range, etc.)\n * in which case it cannot fail.\n * Internal use only.\n */\nvoid ZSTD_buildFSETable(ZSTD_seqSymbol* dt,\n             const short* normalizedCounter, unsigned maxSymbolValue,\n             const U32* baseValue, const U32* nbAdditionalBits,\n                   unsigned tableLog);\n\n\n#endif /* ZSTD_DEC_BLOCK_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_decompress_internal.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n\n/* zstd_decompress_internal:\n * objects and definitions shared within lib/decompress modules */\n\n #ifndef ZSTD_DECOMPRESS_INTERNAL_H\n #define ZSTD_DECOMPRESS_INTERNAL_H\n\n\n/*-*******************************************************\n *  Dependencies\n *********************************************************/\n#include \"mem.h\"             /* BYTE, U16, U32 */\n#include \"zstd_internal.h\"   /* ZSTD_seqSymbol */\n\n\n\n/*-*******************************************************\n *  Constants\n *********************************************************/\nstatic const U32 LL_base[MaxLL+1] = {\n                 0,    1,    2,     3,     4,     5,     6,      7,\n                 8,    9,   10,    11,    12,    13,    14,     15,\n                16,   18,   20,    22,    24,    28,    32,     40,\n                48,   64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,\n                0x2000, 0x4000, 0x8000, 0x10000 };\n\nstatic const U32 OF_base[MaxOff+1] = {\n                 0,        1,       1,       5,     0xD,     0x1D,     0x3D,     0x7D,\n                 0xFD,   0x1FD,   0x3FD,   0x7FD,   0xFFD,   0x1FFD,   0x3FFD,   0x7FFD,\n                 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,\n                 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD, 0x1FFFFFFD, 0x3FFFFFFD, 0x7FFFFFFD };\n\nstatic const U32 OF_bits[MaxOff+1] = {\n                     0,  1,  2,  3,  4,  5,  6,  7,\n                     8,  9, 10, 11, 12, 13, 14, 15,\n                    16, 17, 18, 19, 20, 21, 22, 23,\n                    24, 25, 26, 27, 28, 29, 30, 31 };\n\nstatic const U32 ML_base[MaxML+1] = {\n                     3,  4,  5,    6,     7,     8,     9,    10,\n                    11, 12, 13,   14,    15,    16,    17,    18,\n                    19, 20, 21,   22,    23,    24,    25,    26,\n                    27, 28, 29,   30,    31,    32,    33,    34,\n                    35, 37, 39,   41,    43,    47,    51,    59,\n                    67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,\n                    0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };\n\n\n/*-*******************************************************\n *  Decompression types\n *********************************************************/\n typedef struct {\n     U32 fastMode;\n     U32 tableLog;\n } ZSTD_seqSymbol_header;\n\n typedef struct {\n     U16  nextState;\n     BYTE nbAdditionalBits;\n     BYTE nbBits;\n     U32  baseValue;\n } ZSTD_seqSymbol;\n\n #define SEQSYMBOL_TABLE_SIZE(log)   (1 + (1 << (log)))\n\ntypedef struct {\n    ZSTD_seqSymbol LLTable[SEQSYMBOL_TABLE_SIZE(LLFSELog)];    /* Note : Space reserved for FSE Tables */\n    ZSTD_seqSymbol OFTable[SEQSYMBOL_TABLE_SIZE(OffFSELog)];   /* is also used as temporary workspace while building hufTable during DDict creation */\n    ZSTD_seqSymbol MLTable[SEQSYMBOL_TABLE_SIZE(MLFSELog)];    /* and therefore must be at least HUF_DECOMPRESS_WORKSPACE_SIZE large */\n    HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)];  /* can accommodate HUF_decompress4X */\n    U32 rep[ZSTD_REP_NUM];\n} ZSTD_entropyDTables_t;\n\ntypedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,\n               ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,\n               ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,\n               ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;\n\ntypedef enum { zdss_init=0, zdss_loadHeader,\n               zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;\n\ntypedef enum {\n    ZSTD_use_indefinitely = -1,  /* Use the dictionary indefinitely */\n    ZSTD_dont_use = 0,           /* Do not use the dictionary (if one exists free it) */\n    ZSTD_use_once = 1            /* Use the dictionary once and set to ZSTD_dont_use */\n} ZSTD_dictUses_e;\n\nstruct ZSTD_DCtx_s\n{\n    const ZSTD_seqSymbol* LLTptr;\n    const ZSTD_seqSymbol* MLTptr;\n    const ZSTD_seqSymbol* OFTptr;\n    const HUF_DTable* HUFptr;\n    ZSTD_entropyDTables_t entropy;\n    U32 workspace[HUF_DECOMPRESS_WORKSPACE_SIZE_U32];   /* space needed when building huffman tables */\n    const void* previousDstEnd;   /* detect continuity */\n    const void* prefixStart;      /* start of current segment */\n    const void* virtualStart;     /* virtual start of previous segment if it was just before current one */\n    const void* dictEnd;          /* end of previous segment */\n    size_t expected;\n    ZSTD_frameHeader fParams;\n    U64 decodedSize;\n    blockType_e bType;            /* used in ZSTD_decompressContinue(), store blockType between block header decoding and block decompression stages */\n    ZSTD_dStage stage;\n    U32 litEntropy;\n    U32 fseEntropy;\n    XXH64_state_t xxhState;\n    size_t headerSize;\n    ZSTD_format_e format;\n    const BYTE* litPtr;\n    ZSTD_customMem customMem;\n    size_t litSize;\n    size_t rleSize;\n    size_t staticSize;\n    int bmi2;                     /* == 1 if the CPU supports BMI2 and 0 otherwise. CPU support is determined dynamically once per context lifetime. */\n\n    /* dictionary */\n    ZSTD_DDict* ddictLocal;\n    const ZSTD_DDict* ddict;     /* set by ZSTD_initDStream_usingDDict(), or ZSTD_DCtx_refDDict() */\n    U32 dictID;\n    int ddictIsCold;             /* if == 1 : dictionary is \"new\" for working context, and presumed \"cold\" (not in cpu cache) */\n    ZSTD_dictUses_e dictUses;\n\n    /* streaming */\n    ZSTD_dStreamStage streamStage;\n    char*  inBuff;\n    size_t inBuffSize;\n    size_t inPos;\n    size_t maxWindowSize;\n    char*  outBuff;\n    size_t outBuffSize;\n    size_t outStart;\n    size_t outEnd;\n    size_t lhSize;\n    void* legacyContext;\n    U32 previousLegacyVersion;\n    U32 legacyVersion;\n    U32 hostageByte;\n    int noForwardProgress;\n\n    /* workspace */\n    BYTE litBuffer[ZSTD_BLOCKSIZE_MAX + WILDCOPY_OVERLENGTH];\n    BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];\n};  /* typedef'd to ZSTD_DCtx within \"zstd.h\" */\n\n\n/*-*******************************************************\n *  Shared internal functions\n *********************************************************/\n\n/*! ZSTD_loadDEntropy() :\n *  dict : must point at beginning of a valid zstd dictionary.\n * @return : size of entropy tables read */\nsize_t ZSTD_loadDEntropy(ZSTD_entropyDTables_t* entropy,\n                   const void* const dict, size_t const dictSize);\n\n/*! ZSTD_checkContinuity() :\n *  check if next `dst` follows previous position, where decompression ended.\n *  If yes, do nothing (continue on current segment).\n *  If not, classify previous segment as \"external dictionary\", and start a new segment.\n *  This function cannot fail. */\nvoid ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst);\n\n\n#endif /* ZSTD_DECOMPRESS_INTERNAL_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_double_fast.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#include \"zstd_compress_internal.h\"\n#include \"zstd_double_fast.h\"\n\n\nvoid ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,\n                              void const* end, ZSTD_dictTableLoadMethod_e dtlm)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32* const hashLarge = ms->hashTable;\n    U32  const hBitsL = cParams->hashLog;\n    U32  const mls = cParams->minMatch;\n    U32* const hashSmall = ms->chainTable;\n    U32  const hBitsS = cParams->chainLog;\n    const BYTE* const base = ms->window.base;\n    const BYTE* ip = base + ms->nextToUpdate;\n    const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;\n    const U32 fastHashFillStep = 3;\n\n    /* Always insert every fastHashFillStep position into the hash tables.\n     * Insert the other positions into the large hash table if their entry\n     * is empty.\n     */\n    for (; ip + fastHashFillStep - 1 <= iend; ip += fastHashFillStep) {\n        U32 const current = (U32)(ip - base);\n        U32 i;\n        for (i = 0; i < fastHashFillStep; ++i) {\n            size_t const smHash = ZSTD_hashPtr(ip + i, hBitsS, mls);\n            size_t const lgHash = ZSTD_hashPtr(ip + i, hBitsL, 8);\n            if (i == 0)\n                hashSmall[smHash] = current + i;\n            if (i == 0 || hashLarge[lgHash] == 0)\n                hashLarge[lgHash] = current + i;\n            /* Only load extra positions for ZSTD_dtlm_full */\n            if (dtlm == ZSTD_dtlm_fast)\n                break;\n    }   }\n}\n\n\nFORCE_INLINE_TEMPLATE\nsize_t ZSTD_compressBlock_doubleFast_generic(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize,\n        U32 const mls /* template */, ZSTD_dictMode_e const dictMode)\n{\n    ZSTD_compressionParameters const* cParams = &ms->cParams;\n    U32* const hashLong = ms->hashTable;\n    const U32 hBitsL = cParams->hashLog;\n    U32* const hashSmall = ms->chainTable;\n    const U32 hBitsS = cParams->chainLog;\n    const BYTE* const base = ms->window.base;\n    const BYTE* const istart = (const BYTE*)src;\n    const BYTE* ip = istart;\n    const BYTE* anchor = istart;\n    const U32 endIndex = (U32)((size_t)(istart - base) + srcSize);\n    const U32 lowestValid = ms->window.dictLimit;\n    const U32 maxDistance = 1U << cParams->windowLog;\n    /* presumes that, if there is a dictionary, it must be using Attach mode */\n    const U32 prefixLowestIndex = (endIndex - lowestValid > maxDistance) ? endIndex - maxDistance : lowestValid;\n    const BYTE* const prefixLowest = base + prefixLowestIndex;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* const ilimit = iend - HASH_READ_SIZE;\n    U32 offset_1=rep[0], offset_2=rep[1];\n    U32 offsetSaved = 0;\n\n    const ZSTD_matchState_t* const dms = ms->dictMatchState;\n    const ZSTD_compressionParameters* const dictCParams =\n                                     dictMode == ZSTD_dictMatchState ?\n                                     &dms->cParams : NULL;\n    const U32* const dictHashLong  = dictMode == ZSTD_dictMatchState ?\n                                     dms->hashTable : NULL;\n    const U32* const dictHashSmall = dictMode == ZSTD_dictMatchState ?\n                                     dms->chainTable : NULL;\n    const U32 dictStartIndex       = dictMode == ZSTD_dictMatchState ?\n                                     dms->window.dictLimit : 0;\n    const BYTE* const dictBase     = dictMode == ZSTD_dictMatchState ?\n                                     dms->window.base : NULL;\n    const BYTE* const dictStart    = dictMode == ZSTD_dictMatchState ?\n                                     dictBase + dictStartIndex : NULL;\n    const BYTE* const dictEnd      = dictMode == ZSTD_dictMatchState ?\n                                     dms->window.nextSrc : NULL;\n    const U32 dictIndexDelta       = dictMode == ZSTD_dictMatchState ?\n                                     prefixLowestIndex - (U32)(dictEnd - dictBase) :\n                                     0;\n    const U32 dictHBitsL           = dictMode == ZSTD_dictMatchState ?\n                                     dictCParams->hashLog : hBitsL;\n    const U32 dictHBitsS           = dictMode == ZSTD_dictMatchState ?\n                                     dictCParams->chainLog : hBitsS;\n    const U32 dictAndPrefixLength  = (U32)(ip - prefixLowest + dictEnd - dictStart);\n\n    DEBUGLOG(5, \"ZSTD_compressBlock_doubleFast_generic\");\n\n    assert(dictMode == ZSTD_noDict || dictMode == ZSTD_dictMatchState);\n\n    /* if a dictionary is attached, it must be within window range */\n    if (dictMode == ZSTD_dictMatchState) {\n        assert(lowestValid + maxDistance >= endIndex);\n    }\n\n    /* init */\n    ip += (dictAndPrefixLength == 0);\n    if (dictMode == ZSTD_noDict) {\n        U32 const maxRep = (U32)(ip - prefixLowest);\n        if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;\n        if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;\n    }\n    if (dictMode == ZSTD_dictMatchState) {\n        /* dictMatchState repCode checks don't currently handle repCode == 0\n         * disabling. */\n        assert(offset_1 <= dictAndPrefixLength);\n        assert(offset_2 <= dictAndPrefixLength);\n    }\n\n    /* Main Search Loop */\n    while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */\n        size_t mLength;\n        U32 offset;\n        size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);\n        size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);\n        size_t const dictHL = ZSTD_hashPtr(ip, dictHBitsL, 8);\n        size_t const dictHS = ZSTD_hashPtr(ip, dictHBitsS, mls);\n        U32 const current = (U32)(ip-base);\n        U32 const matchIndexL = hashLong[h2];\n        U32 matchIndexS = hashSmall[h];\n        const BYTE* matchLong = base + matchIndexL;\n        const BYTE* match = base + matchIndexS;\n        const U32 repIndex = current + 1 - offset_1;\n        const BYTE* repMatch = (dictMode == ZSTD_dictMatchState\n                            && repIndex < prefixLowestIndex) ?\n                               dictBase + (repIndex - dictIndexDelta) :\n                               base + repIndex;\n        hashLong[h2] = hashSmall[h] = current;   /* update hash tables */\n\n        /* check dictMatchState repcode */\n        if (dictMode == ZSTD_dictMatchState\n            && ((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)\n            && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {\n            const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;\n            mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;\n            ip++;\n            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);\n            goto _match_stored;\n        }\n\n        /* check noDict repcode */\n        if ( dictMode == ZSTD_noDict\n          && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {\n            mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;\n            ip++;\n            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);\n            goto _match_stored;\n        }\n\n        if (matchIndexL > prefixLowestIndex) {\n            /* check prefix long match */\n            if (MEM_read64(matchLong) == MEM_read64(ip)) {\n                mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;\n                offset = (U32)(ip-matchLong);\n                while (((ip>anchor) & (matchLong>prefixLowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */\n                goto _match_found;\n            }\n        } else if (dictMode == ZSTD_dictMatchState) {\n            /* check dictMatchState long match */\n            U32 const dictMatchIndexL = dictHashLong[dictHL];\n            const BYTE* dictMatchL = dictBase + dictMatchIndexL;\n            assert(dictMatchL < dictEnd);\n\n            if (dictMatchL > dictStart && MEM_read64(dictMatchL) == MEM_read64(ip)) {\n                mLength = ZSTD_count_2segments(ip+8, dictMatchL+8, iend, dictEnd, prefixLowest) + 8;\n                offset = (U32)(current - dictMatchIndexL - dictIndexDelta);\n                while (((ip>anchor) & (dictMatchL>dictStart)) && (ip[-1] == dictMatchL[-1])) { ip--; dictMatchL--; mLength++; } /* catch up */\n                goto _match_found;\n        }   }\n\n        if (matchIndexS > prefixLowestIndex) {\n            /* check prefix short match */\n            if (MEM_read32(match) == MEM_read32(ip)) {\n                goto _search_next_long;\n            }\n        } else if (dictMode == ZSTD_dictMatchState) {\n            /* check dictMatchState short match */\n            U32 const dictMatchIndexS = dictHashSmall[dictHS];\n            match = dictBase + dictMatchIndexS;\n            matchIndexS = dictMatchIndexS + dictIndexDelta;\n\n            if (match > dictStart && MEM_read32(match) == MEM_read32(ip)) {\n                goto _search_next_long;\n        }   }\n\n        ip += ((ip-anchor) >> kSearchStrength) + 1;\n        continue;\n\n_search_next_long:\n\n        {   size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);\n            size_t const dictHLNext = ZSTD_hashPtr(ip+1, dictHBitsL, 8);\n            U32 const matchIndexL3 = hashLong[hl3];\n            const BYTE* matchL3 = base + matchIndexL3;\n            hashLong[hl3] = current + 1;\n\n            /* check prefix long +1 match */\n            if (matchIndexL3 > prefixLowestIndex) {\n                if (MEM_read64(matchL3) == MEM_read64(ip+1)) {\n                    mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8;\n                    ip++;\n                    offset = (U32)(ip-matchL3);\n                    while (((ip>anchor) & (matchL3>prefixLowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */\n                    goto _match_found;\n                }\n            } else if (dictMode == ZSTD_dictMatchState) {\n                /* check dict long +1 match */\n                U32 const dictMatchIndexL3 = dictHashLong[dictHLNext];\n                const BYTE* dictMatchL3 = dictBase + dictMatchIndexL3;\n                assert(dictMatchL3 < dictEnd);\n                if (dictMatchL3 > dictStart && MEM_read64(dictMatchL3) == MEM_read64(ip+1)) {\n                    mLength = ZSTD_count_2segments(ip+1+8, dictMatchL3+8, iend, dictEnd, prefixLowest) + 8;\n                    ip++;\n                    offset = (U32)(current + 1 - dictMatchIndexL3 - dictIndexDelta);\n                    while (((ip>anchor) & (dictMatchL3>dictStart)) && (ip[-1] == dictMatchL3[-1])) { ip--; dictMatchL3--; mLength++; } /* catch up */\n                    goto _match_found;\n        }   }   }\n\n        /* if no long +1 match, explore the short match we found */\n        if (dictMode == ZSTD_dictMatchState && matchIndexS < prefixLowestIndex) {\n            mLength = ZSTD_count_2segments(ip+4, match+4, iend, dictEnd, prefixLowest) + 4;\n            offset = (U32)(current - matchIndexS);\n            while (((ip>anchor) & (match>dictStart)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */\n        } else {\n            mLength = ZSTD_count(ip+4, match+4, iend) + 4;\n            offset = (U32)(ip - match);\n            while (((ip>anchor) & (match>prefixLowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */\n        }\n\n        /* fall-through */\n\n_match_found:\n        offset_2 = offset_1;\n        offset_1 = offset;\n\n        ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);\n\n_match_stored:\n        /* match found */\n        ip += mLength;\n        anchor = ip;\n\n        if (ip <= ilimit) {\n            /* Complementary insertion */\n            /* done after iLimit test, as candidates could be > iend-8 */\n            {   U32 const indexToInsert = current+2;\n                hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;\n                hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);\n                hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;\n                hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);\n            }\n\n            /* check immediate repcode */\n            if (dictMode == ZSTD_dictMatchState) {\n                while (ip <= ilimit) {\n                    U32 const current2 = (U32)(ip-base);\n                    U32 const repIndex2 = current2 - offset_2;\n                    const BYTE* repMatch2 = dictMode == ZSTD_dictMatchState\n                        && repIndex2 < prefixLowestIndex ?\n                            dictBase - dictIndexDelta + repIndex2 :\n                            base + repIndex2;\n                    if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)\n                       && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {\n                        const BYTE* const repEnd2 = repIndex2 < prefixLowestIndex ? dictEnd : iend;\n                        size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixLowest) + 4;\n                        U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */\n                        ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);\n                        hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;\n                        hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;\n                        ip += repLength2;\n                        anchor = ip;\n                        continue;\n                    }\n                    break;\n            }   }\n\n            if (dictMode == ZSTD_noDict) {\n                while ( (ip <= ilimit)\n                     && ( (offset_2>0)\n                        & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {\n                    /* store sequence */\n                    size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;\n                    U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff;  /* swap offset_2 <=> offset_1 */\n                    hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);\n                    hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);\n                    ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, rLength-MINMATCH);\n                    ip += rLength;\n                    anchor = ip;\n                    continue;   /* faster when present ... (?) */\n        }   }   }\n    }   /* while (ip < ilimit) */\n\n    /* save reps for next block */\n    rep[0] = offset_1 ? offset_1 : offsetSaved;\n    rep[1] = offset_2 ? offset_2 : offsetSaved;\n\n    /* Return the last literals size */\n    return (size_t)(iend - anchor);\n}\n\n\nsize_t ZSTD_compressBlock_doubleFast(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    const U32 mls = ms->cParams.minMatch;\n    switch(mls)\n    {\n    default: /* includes case 3 */\n    case 4 :\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_noDict);\n    case 5 :\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_noDict);\n    case 6 :\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_noDict);\n    case 7 :\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_noDict);\n    }\n}\n\n\nsize_t ZSTD_compressBlock_doubleFast_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    const U32 mls = ms->cParams.minMatch;\n    switch(mls)\n    {\n    default: /* includes case 3 */\n    case 4 :\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 4, ZSTD_dictMatchState);\n    case 5 :\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 5, ZSTD_dictMatchState);\n    case 6 :\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 6, ZSTD_dictMatchState);\n    case 7 :\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, 7, ZSTD_dictMatchState);\n    }\n}\n\n\nstatic size_t ZSTD_compressBlock_doubleFast_extDict_generic(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize,\n        U32 const mls /* template */)\n{\n    ZSTD_compressionParameters const* cParams = &ms->cParams;\n    U32* const hashLong = ms->hashTable;\n    U32  const hBitsL = cParams->hashLog;\n    U32* const hashSmall = ms->chainTable;\n    U32  const hBitsS = cParams->chainLog;\n    const BYTE* const istart = (const BYTE*)src;\n    const BYTE* ip = istart;\n    const BYTE* anchor = istart;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* const ilimit = iend - 8;\n    const BYTE* const base = ms->window.base;\n    const U32   endIndex = (U32)((size_t)(istart - base) + srcSize);\n    const U32   lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);\n    const U32   dictStartIndex = lowLimit;\n    const U32   dictLimit = ms->window.dictLimit;\n    const U32   prefixStartIndex = (dictLimit > lowLimit) ? dictLimit : lowLimit;\n    const BYTE* const prefixStart = base + prefixStartIndex;\n    const BYTE* const dictBase = ms->window.dictBase;\n    const BYTE* const dictStart = dictBase + dictStartIndex;\n    const BYTE* const dictEnd = dictBase + prefixStartIndex;\n    U32 offset_1=rep[0], offset_2=rep[1];\n\n    DEBUGLOG(5, \"ZSTD_compressBlock_doubleFast_extDict_generic (srcSize=%zu)\", srcSize);\n\n    /* if extDict is invalidated due to maxDistance, switch to \"regular\" variant */\n    if (prefixStartIndex == dictStartIndex)\n        return ZSTD_compressBlock_doubleFast_generic(ms, seqStore, rep, src, srcSize, mls, ZSTD_noDict);\n\n    /* Search Loop */\n    while (ip < ilimit) {  /* < instead of <=, because (ip+1) */\n        const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);\n        const U32 matchIndex = hashSmall[hSmall];\n        const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base;\n        const BYTE* match = matchBase + matchIndex;\n\n        const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);\n        const U32 matchLongIndex = hashLong[hLong];\n        const BYTE* const matchLongBase = matchLongIndex < prefixStartIndex ? dictBase : base;\n        const BYTE* matchLong = matchLongBase + matchLongIndex;\n\n        const U32 current = (U32)(ip-base);\n        const U32 repIndex = current + 1 - offset_1;   /* offset_1 expected <= current +1 */\n        const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;\n        const BYTE* const repMatch = repBase + repIndex;\n        size_t mLength;\n        hashSmall[hSmall] = hashLong[hLong] = current;   /* update hash table */\n\n        if ((((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex doesn't overlap dict + prefix */\n            & (repIndex > dictStartIndex))\n          && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {\n            const BYTE* repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;\n            mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;\n            ip++;\n            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);\n        } else {\n            if ((matchLongIndex > dictStartIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {\n                const BYTE* const matchEnd = matchLongIndex < prefixStartIndex ? dictEnd : iend;\n                const BYTE* const lowMatchPtr = matchLongIndex < prefixStartIndex ? dictStart : prefixStart;\n                U32 offset;\n                mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, prefixStart) + 8;\n                offset = current - matchLongIndex;\n                while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; }   /* catch up */\n                offset_2 = offset_1;\n                offset_1 = offset;\n                ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);\n\n            } else if ((matchIndex > dictStartIndex) && (MEM_read32(match) == MEM_read32(ip))) {\n                size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);\n                U32 const matchIndex3 = hashLong[h3];\n                const BYTE* const match3Base = matchIndex3 < prefixStartIndex ? dictBase : base;\n                const BYTE* match3 = match3Base + matchIndex3;\n                U32 offset;\n                hashLong[h3] = current + 1;\n                if ( (matchIndex3 > dictStartIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {\n                    const BYTE* const matchEnd = matchIndex3 < prefixStartIndex ? dictEnd : iend;\n                    const BYTE* const lowMatchPtr = matchIndex3 < prefixStartIndex ? dictStart : prefixStart;\n                    mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, prefixStart) + 8;\n                    ip++;\n                    offset = current+1 - matchIndex3;\n                    while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */\n                } else {\n                    const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;\n                    const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;\n                    mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;\n                    offset = current - matchIndex;\n                    while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */\n                }\n                offset_2 = offset_1;\n                offset_1 = offset;\n                ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);\n\n            } else {\n                ip += ((ip-anchor) >> kSearchStrength) + 1;\n                continue;\n        }   }\n\n        /* move to next sequence start */\n        ip += mLength;\n        anchor = ip;\n\n        if (ip <= ilimit) {\n            /* Complementary insertion */\n            /* done after iLimit test, as candidates could be > iend-8 */\n            {   U32 const indexToInsert = current+2;\n                hashLong[ZSTD_hashPtr(base+indexToInsert, hBitsL, 8)] = indexToInsert;\n                hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);\n                hashSmall[ZSTD_hashPtr(base+indexToInsert, hBitsS, mls)] = indexToInsert;\n                hashSmall[ZSTD_hashPtr(ip-1, hBitsS, mls)] = (U32)(ip-1-base);\n            }\n\n            /* check immediate repcode */\n            while (ip <= ilimit) {\n                U32 const current2 = (U32)(ip-base);\n                U32 const repIndex2 = current2 - offset_2;\n                const BYTE* repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;\n                if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3)   /* intentional overflow : ensure repIndex2 doesn't overlap dict + prefix */\n                    & (repIndex2 > dictStartIndex))\n                  && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {\n                    const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;\n                    size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;\n                    U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */\n                    ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);\n                    hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;\n                    hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;\n                    ip += repLength2;\n                    anchor = ip;\n                    continue;\n                }\n                break;\n    }   }   }\n\n    /* save reps for next block */\n    rep[0] = offset_1;\n    rep[1] = offset_2;\n\n    /* Return the last literals size */\n    return (size_t)(iend - anchor);\n}\n\n\nsize_t ZSTD_compressBlock_doubleFast_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    U32 const mls = ms->cParams.minMatch;\n    switch(mls)\n    {\n    default: /* includes case 3 */\n    case 4 :\n        return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 4);\n    case 5 :\n        return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 5);\n    case 6 :\n        return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 6);\n    case 7 :\n        return ZSTD_compressBlock_doubleFast_extDict_generic(ms, seqStore, rep, src, srcSize, 7);\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_double_fast.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_DOUBLE_FAST_H\n#define ZSTD_DOUBLE_FAST_H\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#include \"mem.h\"      /* U32 */\n#include \"zstd_compress_internal.h\"     /* ZSTD_CCtx, size_t */\n\nvoid ZSTD_fillDoubleHashTable(ZSTD_matchState_t* ms,\n                              void const* end, ZSTD_dictTableLoadMethod_e dtlm);\nsize_t ZSTD_compressBlock_doubleFast(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_doubleFast_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_doubleFast_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* ZSTD_DOUBLE_FAST_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_errors.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_ERRORS_H_398273423\n#define ZSTD_ERRORS_H_398273423\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n/*===== dependency =====*/\n#include <stddef.h>   /* size_t */\n\n\n/* =====   ZSTDERRORLIB_API : control library symbols visibility   ===== */\n#ifndef ZSTDERRORLIB_VISIBILITY\n#  if defined(__GNUC__) && (__GNUC__ >= 4)\n#    define ZSTDERRORLIB_VISIBILITY __attribute__ ((visibility (\"default\")))\n#  else\n#    define ZSTDERRORLIB_VISIBILITY\n#  endif\n#endif\n#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)\n#  define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBILITY\n#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)\n#  define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/\n#else\n#  define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBILITY\n#endif\n\n/*-*********************************************\n *  Error codes list\n *-*********************************************\n *  Error codes _values_ are pinned down since v1.3.1 only.\n *  Therefore, don't rely on values if you may link to any version < v1.3.1.\n *\n *  Only values < 100 are considered stable.\n *\n *  note 1 : this API shall be used with static linking only.\n *           dynamic linking is not yet officially supported.\n *  note 2 : Prefer relying on the enum than on its value whenever possible\n *           This is the only supported way to use the error list < v1.3.1\n *  note 3 : ZSTD_isError() is always correct, whatever the library version.\n **********************************************/\ntypedef enum {\n  ZSTD_error_no_error = 0,\n  ZSTD_error_GENERIC  = 1,\n  ZSTD_error_prefix_unknown                = 10,\n  ZSTD_error_version_unsupported           = 12,\n  ZSTD_error_frameParameter_unsupported    = 14,\n  ZSTD_error_frameParameter_windowTooLarge = 16,\n  ZSTD_error_corruption_detected = 20,\n  ZSTD_error_checksum_wrong      = 22,\n  ZSTD_error_dictionary_corrupted      = 30,\n  ZSTD_error_dictionary_wrong          = 32,\n  ZSTD_error_dictionaryCreation_failed = 34,\n  ZSTD_error_parameter_unsupported   = 40,\n  ZSTD_error_parameter_outOfBound    = 42,\n  ZSTD_error_tableLog_tooLarge       = 44,\n  ZSTD_error_maxSymbolValue_tooLarge = 46,\n  ZSTD_error_maxSymbolValue_tooSmall = 48,\n  ZSTD_error_stage_wrong       = 60,\n  ZSTD_error_init_missing      = 62,\n  ZSTD_error_memory_allocation = 64,\n  ZSTD_error_workSpace_tooSmall= 66,\n  ZSTD_error_dstSize_tooSmall = 70,\n  ZSTD_error_srcSize_wrong    = 72,\n  ZSTD_error_dstBuffer_null   = 74,\n  /* following error codes are __NOT STABLE__, they can be removed or changed in future versions */\n  ZSTD_error_frameIndex_tooLarge = 100,\n  ZSTD_error_seekableIO          = 102,\n  ZSTD_error_maxCode = 120  /* never EVER use this value directly, it can change in future versions! Use ZSTD_isError() instead */\n} ZSTD_ErrorCode;\n\n/*! ZSTD_getErrorCode() :\n    convert a `size_t` function result into a `ZSTD_ErrorCode` enum type,\n    which can be used to compare with enum list published above */\nZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);\nZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code);   /**< Same as ZSTD_getErrorName, but using a `ZSTD_ErrorCode` enum argument */\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* ZSTD_ERRORS_H_398273423 */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_fast.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#include \"zstd_compress_internal.h\"  /* ZSTD_hashPtr, ZSTD_count, ZSTD_storeSeq */\n#include \"zstd_fast.h\"\n\n\nvoid ZSTD_fillHashTable(ZSTD_matchState_t* ms,\n                        const void* const end,\n                        ZSTD_dictTableLoadMethod_e dtlm)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32* const hashTable = ms->hashTable;\n    U32  const hBits = cParams->hashLog;\n    U32  const mls = cParams->minMatch;\n    const BYTE* const base = ms->window.base;\n    const BYTE* ip = base + ms->nextToUpdate;\n    const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;\n    const U32 fastHashFillStep = 3;\n\n    /* Always insert every fastHashFillStep position into the hash table.\n     * Insert the other positions if their hash entry is empty.\n     */\n    for ( ; ip + fastHashFillStep < iend + 2; ip += fastHashFillStep) {\n        U32 const current = (U32)(ip - base);\n        size_t const hash0 = ZSTD_hashPtr(ip, hBits, mls);\n        hashTable[hash0] = current;\n        if (dtlm == ZSTD_dtlm_fast) continue;\n        /* Only load extra positions for ZSTD_dtlm_full */\n        {   U32 p;\n            for (p = 1; p < fastHashFillStep; ++p) {\n                size_t const hash = ZSTD_hashPtr(ip + p, hBits, mls);\n                if (hashTable[hash] == 0) {  /* not yet filled */\n                    hashTable[hash] = current + p;\n    }   }   }   }\n}\n\n\nFORCE_INLINE_TEMPLATE size_t\nZSTD_compressBlock_fast_generic(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize,\n        U32 const mls)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32* const hashTable = ms->hashTable;\n    U32 const hlog = cParams->hashLog;\n    /* support stepSize of 0 */\n    size_t const stepSize = cParams->targetLength + !(cParams->targetLength) + 1;\n    const BYTE* const base = ms->window.base;\n    const BYTE* const istart = (const BYTE*)src;\n    /* We check ip0 (ip + 0) and ip1 (ip + 1) each loop */\n    const BYTE* ip0 = istart;\n    const BYTE* ip1;\n    const BYTE* anchor = istart;\n    const U32   endIndex = (U32)((size_t)(istart - base) + srcSize);\n    const U32   maxDistance = 1U << cParams->windowLog;\n    const U32   validStartIndex = ms->window.dictLimit;\n    const U32   prefixStartIndex = (endIndex - validStartIndex > maxDistance) ? endIndex - maxDistance : validStartIndex;\n    const BYTE* const prefixStart = base + prefixStartIndex;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* const ilimit = iend - HASH_READ_SIZE;\n    U32 offset_1=rep[0], offset_2=rep[1];\n    U32 offsetSaved = 0;\n\n    /* init */\n    DEBUGLOG(5, \"ZSTD_compressBlock_fast_generic\");\n    ip0 += (ip0 == prefixStart);\n    ip1 = ip0 + 1;\n    {   U32 const maxRep = (U32)(ip0 - prefixStart);\n        if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;\n        if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;\n    }\n\n    /* Main Search Loop */\n    while (ip1 < ilimit) {   /* < instead of <=, because check at ip0+2 */\n        size_t mLength;\n        BYTE const* ip2 = ip0 + 2;\n        size_t const h0 = ZSTD_hashPtr(ip0, hlog, mls);\n        U32 const val0 = MEM_read32(ip0);\n        size_t const h1 = ZSTD_hashPtr(ip1, hlog, mls);\n        U32 const val1 = MEM_read32(ip1);\n        U32 const current0 = (U32)(ip0-base);\n        U32 const current1 = (U32)(ip1-base);\n        U32 const matchIndex0 = hashTable[h0];\n        U32 const matchIndex1 = hashTable[h1];\n        BYTE const* repMatch = ip2-offset_1;\n        const BYTE* match0 = base + matchIndex0;\n        const BYTE* match1 = base + matchIndex1;\n        U32 offcode;\n        hashTable[h0] = current0;   /* update hash table */\n        hashTable[h1] = current1;   /* update hash table */\n\n        assert(ip0 + 1 == ip1);\n\n        if ((offset_1 > 0) & (MEM_read32(repMatch) == MEM_read32(ip2))) {\n            mLength = ip2[-1] == repMatch[-1] ? 1 : 0;\n            ip0 = ip2 - mLength;\n            match0 = repMatch - mLength;\n            offcode = 0;\n            goto _match;\n        }\n        if ((matchIndex0 > prefixStartIndex) && MEM_read32(match0) == val0) {\n            /* found a regular match */\n            goto _offset;\n        }\n        if ((matchIndex1 > prefixStartIndex) && MEM_read32(match1) == val1) {\n            /* found a regular match after one literal */\n            ip0 = ip1;\n            match0 = match1;\n            goto _offset;\n        }\n        {   size_t const step = ((size_t)(ip0-anchor) >> (kSearchStrength - 1)) + stepSize;\n            assert(step >= 2);\n            ip0 += step;\n            ip1 += step;\n            continue;\n        }\n_offset: /* Requires: ip0, match0 */\n        /* Compute the offset code */\n        offset_2 = offset_1;\n        offset_1 = (U32)(ip0-match0);\n        offcode = offset_1 + ZSTD_REP_MOVE;\n        mLength = 0;\n        /* Count the backwards match length */\n        while (((ip0>anchor) & (match0>prefixStart))\n             && (ip0[-1] == match0[-1])) { ip0--; match0--; mLength++; } /* catch up */\n\n_match: /* Requires: ip0, match0, offcode */\n        /* Count the forward length */\n        mLength += ZSTD_count(ip0+mLength+4, match0+mLength+4, iend) + 4;\n        ZSTD_storeSeq(seqStore, (size_t)(ip0-anchor), anchor, iend, offcode, mLength-MINMATCH);\n        /* match found */\n        ip0 += mLength;\n        anchor = ip0;\n        ip1 = ip0 + 1;\n\n        if (ip0 <= ilimit) {\n            /* Fill Table */\n            assert(base+current0+2 > istart);  /* check base overflow */\n            hashTable[ZSTD_hashPtr(base+current0+2, hlog, mls)] = current0+2;  /* here because current+2 could be > iend-8 */\n            hashTable[ZSTD_hashPtr(ip0-2, hlog, mls)] = (U32)(ip0-2-base);\n\n            while ( ((ip0 <= ilimit) & (offset_2>0))  /* offset_2==0 means offset_2 is invalidated */\n                 && (MEM_read32(ip0) == MEM_read32(ip0 - offset_2)) ) {\n                /* store sequence */\n                size_t const rLength = ZSTD_count(ip0+4, ip0+4-offset_2, iend) + 4;\n                { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */\n                hashTable[ZSTD_hashPtr(ip0, hlog, mls)] = (U32)(ip0-base);\n                ip0 += rLength;\n                ip1 = ip0 + 1;\n                ZSTD_storeSeq(seqStore, 0 /*litLen*/, anchor, iend, 0 /*offCode*/, rLength-MINMATCH);\n                anchor = ip0;\n                continue;   /* faster when present (confirmed on gcc-8) ... (?) */\n            }\n        }\n    }\n\n    /* save reps for next block */\n    rep[0] = offset_1 ? offset_1 : offsetSaved;\n    rep[1] = offset_2 ? offset_2 : offsetSaved;\n\n    /* Return the last literals size */\n    return (size_t)(iend - anchor);\n}\n\n\nsize_t ZSTD_compressBlock_fast(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    U32 const mls = ms->cParams.minMatch;\n    assert(ms->dictMatchState == NULL);\n    switch(mls)\n    {\n    default: /* includes case 3 */\n    case 4 :\n        return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 4);\n    case 5 :\n        return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 5);\n    case 6 :\n        return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 6);\n    case 7 :\n        return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, 7);\n    }\n}\n\nFORCE_INLINE_TEMPLATE\nsize_t ZSTD_compressBlock_fast_dictMatchState_generic(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize, U32 const mls)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32* const hashTable = ms->hashTable;\n    U32 const hlog = cParams->hashLog;\n    /* support stepSize of 0 */\n    U32 const stepSize = cParams->targetLength + !(cParams->targetLength);\n    const BYTE* const base = ms->window.base;\n    const BYTE* const istart = (const BYTE*)src;\n    const BYTE* ip = istart;\n    const BYTE* anchor = istart;\n    const U32   prefixStartIndex = ms->window.dictLimit;\n    const BYTE* const prefixStart = base + prefixStartIndex;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* const ilimit = iend - HASH_READ_SIZE;\n    U32 offset_1=rep[0], offset_2=rep[1];\n    U32 offsetSaved = 0;\n\n    const ZSTD_matchState_t* const dms = ms->dictMatchState;\n    const ZSTD_compressionParameters* const dictCParams = &dms->cParams ;\n    const U32* const dictHashTable = dms->hashTable;\n    const U32 dictStartIndex       = dms->window.dictLimit;\n    const BYTE* const dictBase     = dms->window.base;\n    const BYTE* const dictStart    = dictBase + dictStartIndex;\n    const BYTE* const dictEnd      = dms->window.nextSrc;\n    const U32 dictIndexDelta       = prefixStartIndex - (U32)(dictEnd - dictBase);\n    const U32 dictAndPrefixLength  = (U32)(ip - prefixStart + dictEnd - dictStart);\n    const U32 dictHLog             = dictCParams->hashLog;\n\n    /* if a dictionary is still attached, it necessarily means that\n     * it is within window size. So we just check it. */\n    const U32 maxDistance = 1U << cParams->windowLog;\n    const U32 endIndex = (U32)((size_t)(ip - base) + srcSize);\n    assert(endIndex - prefixStartIndex <= maxDistance);\n    (void)maxDistance; (void)endIndex;   /* these variables are not used when assert() is disabled */\n\n    /* ensure there will be no no underflow\n     * when translating a dict index into a local index */\n    assert(prefixStartIndex >= (U32)(dictEnd - dictBase));\n\n    /* init */\n    DEBUGLOG(5, \"ZSTD_compressBlock_fast_dictMatchState_generic\");\n    ip += (dictAndPrefixLength == 0);\n    /* dictMatchState repCode checks don't currently handle repCode == 0\n     * disabling. */\n    assert(offset_1 <= dictAndPrefixLength);\n    assert(offset_2 <= dictAndPrefixLength);\n\n    /* Main Search Loop */\n    while (ip < ilimit) {   /* < instead of <=, because repcode check at (ip+1) */\n        size_t mLength;\n        size_t const h = ZSTD_hashPtr(ip, hlog, mls);\n        U32 const current = (U32)(ip-base);\n        U32 const matchIndex = hashTable[h];\n        const BYTE* match = base + matchIndex;\n        const U32 repIndex = current + 1 - offset_1;\n        const BYTE* repMatch = (repIndex < prefixStartIndex) ?\n                               dictBase + (repIndex - dictIndexDelta) :\n                               base + repIndex;\n        hashTable[h] = current;   /* update hash table */\n\n        if ( ((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow : ensure repIndex isn't overlapping dict + prefix */\n          && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {\n            const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;\n            mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixStart) + 4;\n            ip++;\n            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, mLength-MINMATCH);\n        } else if ( (matchIndex <= prefixStartIndex) ) {\n            size_t const dictHash = ZSTD_hashPtr(ip, dictHLog, mls);\n            U32 const dictMatchIndex = dictHashTable[dictHash];\n            const BYTE* dictMatch = dictBase + dictMatchIndex;\n            if (dictMatchIndex <= dictStartIndex ||\n                MEM_read32(dictMatch) != MEM_read32(ip)) {\n                assert(stepSize >= 1);\n                ip += ((ip-anchor) >> kSearchStrength) + stepSize;\n                continue;\n            } else {\n                /* found a dict match */\n                U32 const offset = (U32)(current-dictMatchIndex-dictIndexDelta);\n                mLength = ZSTD_count_2segments(ip+4, dictMatch+4, iend, dictEnd, prefixStart) + 4;\n                while (((ip>anchor) & (dictMatch>dictStart))\n                     && (ip[-1] == dictMatch[-1])) {\n                    ip--; dictMatch--; mLength++;\n                } /* catch up */\n                offset_2 = offset_1;\n                offset_1 = offset;\n                ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);\n            }\n        } else if (MEM_read32(match) != MEM_read32(ip)) {\n            /* it's not a match, and we're not going to check the dictionary */\n            assert(stepSize >= 1);\n            ip += ((ip-anchor) >> kSearchStrength) + stepSize;\n            continue;\n        } else {\n            /* found a regular match */\n            U32 const offset = (U32)(ip-match);\n            mLength = ZSTD_count(ip+4, match+4, iend) + 4;\n            while (((ip>anchor) & (match>prefixStart))\n                 && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */\n            offset_2 = offset_1;\n            offset_1 = offset;\n            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);\n        }\n\n        /* match found */\n        ip += mLength;\n        anchor = ip;\n\n        if (ip <= ilimit) {\n            /* Fill Table */\n            assert(base+current+2 > istart);  /* check base overflow */\n            hashTable[ZSTD_hashPtr(base+current+2, hlog, mls)] = current+2;  /* here because current+2 could be > iend-8 */\n            hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base);\n\n            /* check immediate repcode */\n            while (ip <= ilimit) {\n                U32 const current2 = (U32)(ip-base);\n                U32 const repIndex2 = current2 - offset_2;\n                const BYTE* repMatch2 = repIndex2 < prefixStartIndex ?\n                        dictBase - dictIndexDelta + repIndex2 :\n                        base + repIndex2;\n                if ( ((U32)((prefixStartIndex-1) - (U32)repIndex2) >= 3 /* intentional overflow */)\n                   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {\n                    const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;\n                    size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;\n                    U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset;   /* swap offset_2 <=> offset_1 */\n                    ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, repLength2-MINMATCH);\n                    hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;\n                    ip += repLength2;\n                    anchor = ip;\n                    continue;\n                }\n                break;\n            }\n        }\n    }\n\n    /* save reps for next block */\n    rep[0] = offset_1 ? offset_1 : offsetSaved;\n    rep[1] = offset_2 ? offset_2 : offsetSaved;\n\n    /* Return the last literals size */\n    return (size_t)(iend - anchor);\n}\n\nsize_t ZSTD_compressBlock_fast_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    U32 const mls = ms->cParams.minMatch;\n    assert(ms->dictMatchState != NULL);\n    switch(mls)\n    {\n    default: /* includes case 3 */\n    case 4 :\n        return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 4);\n    case 5 :\n        return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 5);\n    case 6 :\n        return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 6);\n    case 7 :\n        return ZSTD_compressBlock_fast_dictMatchState_generic(ms, seqStore, rep, src, srcSize, 7);\n    }\n}\n\n\nstatic size_t ZSTD_compressBlock_fast_extDict_generic(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize, U32 const mls)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32* const hashTable = ms->hashTable;\n    U32 const hlog = cParams->hashLog;\n    /* support stepSize of 0 */\n    U32 const stepSize = cParams->targetLength + !(cParams->targetLength);\n    const BYTE* const base = ms->window.base;\n    const BYTE* const dictBase = ms->window.dictBase;\n    const BYTE* const istart = (const BYTE*)src;\n    const BYTE* ip = istart;\n    const BYTE* anchor = istart;\n    const U32   endIndex = (U32)((size_t)(istart - base) + srcSize);\n    const U32   lowLimit = ZSTD_getLowestMatchIndex(ms, endIndex, cParams->windowLog);\n    const U32   dictStartIndex = lowLimit;\n    const BYTE* const dictStart = dictBase + dictStartIndex;\n    const U32   dictLimit = ms->window.dictLimit;\n    const U32   prefixStartIndex = dictLimit < lowLimit ? lowLimit : dictLimit;\n    const BYTE* const prefixStart = base + prefixStartIndex;\n    const BYTE* const dictEnd = dictBase + prefixStartIndex;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* const ilimit = iend - 8;\n    U32 offset_1=rep[0], offset_2=rep[1];\n\n    DEBUGLOG(5, \"ZSTD_compressBlock_fast_extDict_generic\");\n\n    /* switch to \"regular\" variant if extDict is invalidated due to maxDistance */\n    if (prefixStartIndex == dictStartIndex)\n        return ZSTD_compressBlock_fast_generic(ms, seqStore, rep, src, srcSize, mls);\n\n    /* Search Loop */\n    while (ip < ilimit) {  /* < instead of <=, because (ip+1) */\n        const size_t h = ZSTD_hashPtr(ip, hlog, mls);\n        const U32    matchIndex = hashTable[h];\n        const BYTE* const matchBase = matchIndex < prefixStartIndex ? dictBase : base;\n        const BYTE*  match = matchBase + matchIndex;\n        const U32    current = (U32)(ip-base);\n        const U32    repIndex = current + 1 - offset_1;\n        const BYTE* const repBase = repIndex < prefixStartIndex ? dictBase : base;\n        const BYTE* const repMatch = repBase + repIndex;\n        hashTable[h] = current;   /* update hash table */\n        assert(offset_1 <= current +1);   /* check repIndex */\n\n        if ( (((U32)((prefixStartIndex-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > dictStartIndex))\n           && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {\n            const BYTE* const repMatchEnd = repIndex < prefixStartIndex ? dictEnd : iend;\n            size_t const rLength = ZSTD_count_2segments(ip+1 +4, repMatch +4, iend, repMatchEnd, prefixStart) + 4;\n            ip++;\n            ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, 0, rLength-MINMATCH);\n            ip += rLength;\n            anchor = ip;\n        } else {\n            if ( (matchIndex < dictStartIndex) ||\n                 (MEM_read32(match) != MEM_read32(ip)) ) {\n                assert(stepSize >= 1);\n                ip += ((ip-anchor) >> kSearchStrength) + stepSize;\n                continue;\n            }\n            {   const BYTE* const matchEnd = matchIndex < prefixStartIndex ? dictEnd : iend;\n                const BYTE* const lowMatchPtr = matchIndex < prefixStartIndex ? dictStart : prefixStart;\n                U32 const offset = current - matchIndex;\n                size_t mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, prefixStart) + 4;\n                while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; }   /* catch up */\n                offset_2 = offset_1; offset_1 = offset;  /* update offset history */\n                ZSTD_storeSeq(seqStore, (size_t)(ip-anchor), anchor, iend, offset + ZSTD_REP_MOVE, mLength-MINMATCH);\n                ip += mLength;\n                anchor = ip;\n        }   }\n\n        if (ip <= ilimit) {\n            /* Fill Table */\n            hashTable[ZSTD_hashPtr(base+current+2, hlog, mls)] = current+2;\n            hashTable[ZSTD_hashPtr(ip-2, hlog, mls)] = (U32)(ip-2-base);\n            /* check immediate repcode */\n            while (ip <= ilimit) {\n                U32 const current2 = (U32)(ip-base);\n                U32 const repIndex2 = current2 - offset_2;\n                const BYTE* const repMatch2 = repIndex2 < prefixStartIndex ? dictBase + repIndex2 : base + repIndex2;\n                if ( (((U32)((prefixStartIndex-1) - repIndex2) >= 3) & (repIndex2 > dictStartIndex))  /* intentional overflow */\n                   && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {\n                    const BYTE* const repEnd2 = repIndex2 < prefixStartIndex ? dictEnd : iend;\n                    size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, prefixStart) + 4;\n                    { U32 const tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; }  /* swap offset_2 <=> offset_1 */\n                    ZSTD_storeSeq(seqStore, 0 /*litlen*/, anchor, iend, 0 /*offcode*/, repLength2-MINMATCH);\n                    hashTable[ZSTD_hashPtr(ip, hlog, mls)] = current2;\n                    ip += repLength2;\n                    anchor = ip;\n                    continue;\n                }\n                break;\n    }   }   }\n\n    /* save reps for next block */\n    rep[0] = offset_1;\n    rep[1] = offset_2;\n\n    /* Return the last literals size */\n    return (size_t)(iend - anchor);\n}\n\n\nsize_t ZSTD_compressBlock_fast_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    U32 const mls = ms->cParams.minMatch;\n    switch(mls)\n    {\n    default: /* includes case 3 */\n    case 4 :\n        return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 4);\n    case 5 :\n        return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 5);\n    case 6 :\n        return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 6);\n    case 7 :\n        return ZSTD_compressBlock_fast_extDict_generic(ms, seqStore, rep, src, srcSize, 7);\n    }\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_fast.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_FAST_H\n#define ZSTD_FAST_H\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#include \"mem.h\"      /* U32 */\n#include \"zstd_compress_internal.h\"\n\nvoid ZSTD_fillHashTable(ZSTD_matchState_t* ms,\n                        void const* end, ZSTD_dictTableLoadMethod_e dtlm);\nsize_t ZSTD_compressBlock_fast(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_fast_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_fast_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* ZSTD_FAST_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_internal.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_CCOMMON_H_MODULE\n#define ZSTD_CCOMMON_H_MODULE\n\n/* this module contains definitions which must be identical\n * across compression, decompression and dictBuilder.\n * It also contains a few functions useful to at least 2 of them\n * and which benefit from being inlined */\n\n/*-*************************************\n*  Dependencies\n***************************************/\n#include \"compiler.h\"\n#include \"mem.h\"\n#include \"debug.h\"                 /* assert, DEBUGLOG, RAWLOG, g_debuglevel */\n#include \"error_private.h\"\n#define ZSTD_STATIC_LINKING_ONLY\n#include \"zstd.h\"\n#define FSE_STATIC_LINKING_ONLY\n#include \"fse.h\"\n#define HUF_STATIC_LINKING_ONLY\n#include \"huf.h\"\n#ifndef XXH_STATIC_LINKING_ONLY\n#  define XXH_STATIC_LINKING_ONLY  /* XXH64_state_t */\n#endif\n#include \"xxhash.h\"                /* XXH_reset, update, digest */\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n/* ---- static assert (debug) --- */\n#define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)\n#define ZSTD_isError ERR_isError   /* for inlining */\n#define FSE_isError  ERR_isError\n#define HUF_isError  ERR_isError\n\n\n/*-*************************************\n*  shared macros\n***************************************/\n#undef MIN\n#undef MAX\n#define MIN(a,b) ((a)<(b) ? (a) : (b))\n#define MAX(a,b) ((a)>(b) ? (a) : (b))\n\n/**\n * Return the specified error if the condition evaluates to true.\n *\n * In debug modes, prints additional information.\n * In order to do that (particularly, printing the conditional that failed),\n * this can't just wrap RETURN_ERROR().\n */\n#define RETURN_ERROR_IF(cond, err, ...) \\\n  if (cond) { \\\n    RAWLOG(3, \"%s:%d: ERROR!: check %s failed, returning %s\", __FILE__, __LINE__, ZSTD_QUOTE(cond), ZSTD_QUOTE(ERROR(err))); \\\n    RAWLOG(3, \": \" __VA_ARGS__); \\\n    RAWLOG(3, \"\\n\"); \\\n    return ERROR(err); \\\n  }\n\n/**\n * Unconditionally return the specified error.\n *\n * In debug modes, prints additional information.\n */\n#define RETURN_ERROR(err, ...) \\\n  do { \\\n    RAWLOG(3, \"%s:%d: ERROR!: unconditional check failed, returning %s\", __FILE__, __LINE__, ZSTD_QUOTE(ERROR(err))); \\\n    RAWLOG(3, \": \" __VA_ARGS__); \\\n    RAWLOG(3, \"\\n\"); \\\n    return ERROR(err); \\\n  } while(0);\n\n/**\n * If the provided expression evaluates to an error code, returns that error code.\n *\n * In debug modes, prints additional information.\n */\n#define FORWARD_IF_ERROR(err, ...) \\\n  do { \\\n    size_t const err_code = (err); \\\n    if (ERR_isError(err_code)) { \\\n      RAWLOG(3, \"%s:%d: ERROR!: forwarding error in %s: %s\", __FILE__, __LINE__, ZSTD_QUOTE(err), ERR_getErrorName(err_code)); \\\n      RAWLOG(3, \": \" __VA_ARGS__); \\\n      RAWLOG(3, \"\\n\"); \\\n      return err_code; \\\n    } \\\n  } while(0);\n\n\n/*-*************************************\n*  Common constants\n***************************************/\n#define ZSTD_OPT_NUM    (1<<12)\n\n#define ZSTD_REP_NUM      3                 /* number of repcodes */\n#define ZSTD_REP_MOVE     (ZSTD_REP_NUM-1)\nstatic const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };\n\n#define KB *(1 <<10)\n#define MB *(1 <<20)\n#define GB *(1U<<30)\n\n#define BIT7 128\n#define BIT6  64\n#define BIT5  32\n#define BIT4  16\n#define BIT1   2\n#define BIT0   1\n\n#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10\nstatic const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };\nstatic const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };\n\n#define ZSTD_FRAMEIDSIZE 4   /* magic number size */\n\n#define ZSTD_BLOCKHEADERSIZE 3   /* C standard doesn't allow `static const` variable to be init using another `static const` variable */\nstatic const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;\ntypedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;\n\n#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */\n#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */)   /* for a non-null block */\n\n#define HufLog 12\ntypedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;\n\n#define LONGNBSEQ 0x7F00\n\n#define MINMATCH 3\n\n#define Litbits  8\n#define MaxLit ((1<<Litbits) - 1)\n#define MaxML   52\n#define MaxLL   35\n#define DefaultMaxOff 28\n#define MaxOff  31\n#define MaxSeq MAX(MaxLL, MaxML)   /* Assumption : MaxOff < MaxLL,MaxML */\n#define MLFSELog    9\n#define LLFSELog    9\n#define OffFSELog   8\n#define MaxFSELog  MAX(MAX(MLFSELog, LLFSELog), OffFSELog)\n\nstatic const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0,\n                                      0, 0, 0, 0, 0, 0, 0, 0,\n                                      1, 1, 1, 1, 2, 2, 3, 3,\n                                      4, 6, 7, 8, 9,10,11,12,\n                                     13,14,15,16 };\nstatic const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2,\n                                             2, 2, 2, 2, 2, 1, 1, 1,\n                                             2, 2, 2, 2, 2, 2, 2, 2,\n                                             2, 3, 2, 1, 1, 1, 1, 1,\n                                            -1,-1,-1,-1 };\n#define LL_DEFAULTNORMLOG 6  /* for static allocation */\nstatic const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;\n\nstatic const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0,\n                                      0, 0, 0, 0, 0, 0, 0, 0,\n                                      0, 0, 0, 0, 0, 0, 0, 0,\n                                      0, 0, 0, 0, 0, 0, 0, 0,\n                                      1, 1, 1, 1, 2, 2, 3, 3,\n                                      4, 4, 5, 7, 8, 9,10,11,\n                                     12,13,14,15,16 };\nstatic const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2,\n                                             2, 1, 1, 1, 1, 1, 1, 1,\n                                             1, 1, 1, 1, 1, 1, 1, 1,\n                                             1, 1, 1, 1, 1, 1, 1, 1,\n                                             1, 1, 1, 1, 1, 1, 1, 1,\n                                             1, 1, 1, 1, 1, 1,-1,-1,\n                                            -1,-1,-1,-1,-1 };\n#define ML_DEFAULTNORMLOG 6  /* for static allocation */\nstatic const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;\n\nstatic const S16 OF_defaultNorm[DefaultMaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2,\n                                                     2, 1, 1, 1, 1, 1, 1, 1,\n                                                     1, 1, 1, 1, 1, 1, 1, 1,\n                                                    -1,-1,-1,-1,-1 };\n#define OF_DEFAULTNORMLOG 5  /* for static allocation */\nstatic const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;\n\n\n/*-*******************************************\n*  Shared functions to include for inlining\n*********************************************/\nstatic void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }\n\n#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }\nstatic void ZSTD_copy16(void* dst, const void* src) { memcpy(dst, src, 16); }\n#define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }\n\n#define WILDCOPY_OVERLENGTH 32\n#define WILDCOPY_VECLEN 16\n\ntypedef enum {\n    ZSTD_no_overlap,\n    ZSTD_overlap_src_before_dst\n    /*  ZSTD_overlap_dst_before_src, */\n} ZSTD_overlap_e;\n\n/*! ZSTD_wildcopy() :\n *  Custom version of memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)\n *  @param ovtype controls the overlap detection\n *         - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.\n *         - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.\n *           The src buffer must be before the dst buffer.\n */\nMEM_STATIC FORCE_INLINE_ATTR DONT_VECTORIZE\nvoid ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)\n{\n    ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;\n    const BYTE* ip = (const BYTE*)src;\n    BYTE* op = (BYTE*)dst;\n    BYTE* const oend = op + length;\n\n    assert(diff >= 8 || (ovtype == ZSTD_no_overlap && diff <= -WILDCOPY_VECLEN));\n\n    if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {\n        /* Handle short offset copies. */\n        do {\n            COPY8(op, ip)\n        } while (op < oend);\n    } else {\n        assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);\n        /* Separate out the first two COPY16() calls because the copy length is\n         * almost certain to be short, so the branches have different\n         * probabilities.\n         * On gcc-9 unrolling once is +1.6%, twice is +2%, thrice is +1.8%.\n         * On clang-8 unrolling once is +1.4%, twice is +3.3%, thrice is +3%.\n         */\n        COPY16(op, ip);\n        COPY16(op, ip);\n        if (op >= oend) return;\n        do {\n            COPY16(op, ip);\n            COPY16(op, ip);\n        }\n        while (op < oend);\n    }\n}\n\n\n/*-*******************************************\n*  Private declarations\n*********************************************/\ntypedef struct seqDef_s {\n    U32 offset;\n    U16 litLength;\n    U16 matchLength;\n} seqDef;\n\ntypedef struct {\n    seqDef* sequencesStart;\n    seqDef* sequences;\n    BYTE* litStart;\n    BYTE* lit;\n    BYTE* llCode;\n    BYTE* mlCode;\n    BYTE* ofCode;\n    size_t maxNbSeq;\n    size_t maxNbLit;\n    U32   longLengthID;   /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */\n    U32   longLengthPos;\n} seqStore_t;\n\n/**\n * Contains the compressed frame size and an upper-bound for the decompressed frame size.\n * Note: before using `compressedSize`, check for errors using ZSTD_isError().\n *       similarly, before using `decompressedBound`, check for errors using:\n *          `decompressedBound != ZSTD_CONTENTSIZE_ERROR`\n */\ntypedef struct {\n    size_t compressedSize;\n    unsigned long long decompressedBound;\n} ZSTD_frameSizeInfo;   /* decompress & legacy */\n\nconst seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);   /* compress & dictBuilder */\nvoid ZSTD_seqToCodes(const seqStore_t* seqStorePtr);   /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */\n\n/* custom memory allocation functions */\nvoid* ZSTD_malloc(size_t size, ZSTD_customMem customMem);\nvoid* ZSTD_calloc(size_t size, ZSTD_customMem customMem);\nvoid ZSTD_free(void* ptr, ZSTD_customMem customMem);\n\n\nMEM_STATIC U32 ZSTD_highbit32(U32 val)   /* compress, dictBuilder, decodeCorpus */\n{\n    assert(val != 0);\n    {\n#   if defined(_MSC_VER)   /* Visual */\n        unsigned long r=0;\n        _BitScanReverse(&r, val);\n        return (unsigned)r;\n#   elif defined(__GNUC__) && (__GNUC__ >= 3)   /* GCC Intrinsic */\n        return __builtin_clz (val) ^ 31;\n#   elif defined(__ICCARM__)    /* IAR Intrinsic */\n        return 31 - __CLZ(val);\n#   else   /* Software version */\n        static const U32 DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };\n        U32 v = val;\n        v |= v >> 1;\n        v |= v >> 2;\n        v |= v >> 4;\n        v |= v >> 8;\n        v |= v >> 16;\n        return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];\n#   endif\n    }\n}\n\n\n/* ZSTD_invalidateRepCodes() :\n * ensures next compression will not use repcodes from previous block.\n * Note : only works with regular variant;\n *        do not use with extDict variant ! */\nvoid ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);   /* zstdmt, adaptive_compression (shouldn't get this definition from here) */\n\n\ntypedef struct {\n    blockType_e blockType;\n    U32 lastBlock;\n    U32 origSize;\n} blockProperties_t;   /* declared here for decompress and fullbench */\n\n/*! ZSTD_getcBlockSize() :\n *  Provides the size of compressed block from block header `src` */\n/* Used by: decompress, fullbench (does not get its definition from here) */\nsize_t ZSTD_getcBlockSize(const void* src, size_t srcSize,\n                          blockProperties_t* bpPtr);\n\n/*! ZSTD_decodeSeqHeaders() :\n *  decode sequence header from src */\n/* Used by: decompress, fullbench (does not get its definition from here) */\nsize_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,\n                       const void* src, size_t srcSize);\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif   /* ZSTD_CCOMMON_H_MODULE */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_lazy.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#include \"zstd_compress_internal.h\"\n#include \"zstd_lazy.h\"\n\n\n/*-*************************************\n*  Binary Tree search\n***************************************/\n\nstatic void\nZSTD_updateDUBT(ZSTD_matchState_t* ms,\n                const BYTE* ip, const BYTE* iend,\n                U32 mls)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32* const hashTable = ms->hashTable;\n    U32  const hashLog = cParams->hashLog;\n\n    U32* const bt = ms->chainTable;\n    U32  const btLog  = cParams->chainLog - 1;\n    U32  const btMask = (1 << btLog) - 1;\n\n    const BYTE* const base = ms->window.base;\n    U32 const target = (U32)(ip - base);\n    U32 idx = ms->nextToUpdate;\n\n    if (idx != target)\n        DEBUGLOG(7, \"ZSTD_updateDUBT, from %u to %u (dictLimit:%u)\",\n                    idx, target, ms->window.dictLimit);\n    assert(ip + 8 <= iend);   /* condition for ZSTD_hashPtr */\n    (void)iend;\n\n    assert(idx >= ms->window.dictLimit);   /* condition for valid base+idx */\n    for ( ; idx < target ; idx++) {\n        size_t const h  = ZSTD_hashPtr(base + idx, hashLog, mls);   /* assumption : ip + 8 <= iend */\n        U32    const matchIndex = hashTable[h];\n\n        U32*   const nextCandidatePtr = bt + 2*(idx&btMask);\n        U32*   const sortMarkPtr  = nextCandidatePtr + 1;\n\n        DEBUGLOG(8, \"ZSTD_updateDUBT: insert %u\", idx);\n        hashTable[h] = idx;   /* Update Hash Table */\n        *nextCandidatePtr = matchIndex;   /* update BT like a chain */\n        *sortMarkPtr = ZSTD_DUBT_UNSORTED_MARK;\n    }\n    ms->nextToUpdate = target;\n}\n\n\n/** ZSTD_insertDUBT1() :\n *  sort one already inserted but unsorted position\n *  assumption : current >= btlow == (current - btmask)\n *  doesn't fail */\nstatic void\nZSTD_insertDUBT1(ZSTD_matchState_t* ms,\n                 U32 current, const BYTE* inputEnd,\n                 U32 nbCompares, U32 btLow,\n                 const ZSTD_dictMode_e dictMode)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32* const bt = ms->chainTable;\n    U32  const btLog  = cParams->chainLog - 1;\n    U32  const btMask = (1 << btLog) - 1;\n    size_t commonLengthSmaller=0, commonLengthLarger=0;\n    const BYTE* const base = ms->window.base;\n    const BYTE* const dictBase = ms->window.dictBase;\n    const U32 dictLimit = ms->window.dictLimit;\n    const BYTE* const ip = (current>=dictLimit) ? base + current : dictBase + current;\n    const BYTE* const iend = (current>=dictLimit) ? inputEnd : dictBase + dictLimit;\n    const BYTE* const dictEnd = dictBase + dictLimit;\n    const BYTE* const prefixStart = base + dictLimit;\n    const BYTE* match;\n    U32* smallerPtr = bt + 2*(current&btMask);\n    U32* largerPtr  = smallerPtr + 1;\n    U32 matchIndex = *smallerPtr;   /* this candidate is unsorted : next sorted candidate is reached through *smallerPtr, while *largerPtr contains previous unsorted candidate (which is already saved and can be overwritten) */\n    U32 dummy32;   /* to be nullified at the end */\n    U32 const windowValid = ms->window.lowLimit;\n    U32 const maxDistance = 1U << cParams->windowLog;\n    U32 const windowLow = (current - windowValid > maxDistance) ? current - maxDistance : windowValid;\n\n\n    DEBUGLOG(8, \"ZSTD_insertDUBT1(%u) (dictLimit=%u, lowLimit=%u)\",\n                current, dictLimit, windowLow);\n    assert(current >= btLow);\n    assert(ip < iend);   /* condition for ZSTD_count */\n\n    while (nbCompares-- && (matchIndex > windowLow)) {\n        U32* const nextPtr = bt + 2*(matchIndex & btMask);\n        size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */\n        assert(matchIndex < current);\n        /* note : all candidates are now supposed sorted,\n         * but it's still possible to have nextPtr[1] == ZSTD_DUBT_UNSORTED_MARK\n         * when a real index has the same value as ZSTD_DUBT_UNSORTED_MARK */\n\n        if ( (dictMode != ZSTD_extDict)\n          || (matchIndex+matchLength >= dictLimit)  /* both in current segment*/\n          || (current < dictLimit) /* both in extDict */) {\n            const BYTE* const mBase = ( (dictMode != ZSTD_extDict)\n                                     || (matchIndex+matchLength >= dictLimit)) ?\n                                        base : dictBase;\n            assert( (matchIndex+matchLength >= dictLimit)   /* might be wrong if extDict is incorrectly set to 0 */\n                 || (current < dictLimit) );\n            match = mBase + matchIndex;\n            matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);\n        } else {\n            match = dictBase + matchIndex;\n            matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);\n            if (matchIndex+matchLength >= dictLimit)\n                match = base + matchIndex;   /* preparation for next read of match[matchLength] */\n        }\n\n        DEBUGLOG(8, \"ZSTD_insertDUBT1: comparing %u with %u : found %u common bytes \",\n                    current, matchIndex, (U32)matchLength);\n\n        if (ip+matchLength == iend) {   /* equal : no way to know if inf or sup */\n            break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */\n        }\n\n        if (match[matchLength] < ip[matchLength]) {  /* necessarily within buffer */\n            /* match is smaller than current */\n            *smallerPtr = matchIndex;             /* update smaller idx */\n            commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */\n            if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop searching */\n            DEBUGLOG(8, \"ZSTD_insertDUBT1: %u (>btLow=%u) is smaller : next => %u\",\n                        matchIndex, btLow, nextPtr[1]);\n            smallerPtr = nextPtr+1;               /* new \"candidate\" => larger than match, which was smaller than target */\n            matchIndex = nextPtr[1];              /* new matchIndex, larger than previous and closer to current */\n        } else {\n            /* match is larger than current */\n            *largerPtr = matchIndex;\n            commonLengthLarger = matchLength;\n            if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop searching */\n            DEBUGLOG(8, \"ZSTD_insertDUBT1: %u (>btLow=%u) is larger => %u\",\n                        matchIndex, btLow, nextPtr[0]);\n            largerPtr = nextPtr;\n            matchIndex = nextPtr[0];\n    }   }\n\n    *smallerPtr = *largerPtr = 0;\n}\n\n\nstatic size_t\nZSTD_DUBT_findBetterDictMatch (\n        ZSTD_matchState_t* ms,\n        const BYTE* const ip, const BYTE* const iend,\n        size_t* offsetPtr,\n        size_t bestLength,\n        U32 nbCompares,\n        U32 const mls,\n        const ZSTD_dictMode_e dictMode)\n{\n    const ZSTD_matchState_t * const dms = ms->dictMatchState;\n    const ZSTD_compressionParameters* const dmsCParams = &dms->cParams;\n    const U32 * const dictHashTable = dms->hashTable;\n    U32         const hashLog = dmsCParams->hashLog;\n    size_t      const h  = ZSTD_hashPtr(ip, hashLog, mls);\n    U32               dictMatchIndex = dictHashTable[h];\n\n    const BYTE* const base = ms->window.base;\n    const BYTE* const prefixStart = base + ms->window.dictLimit;\n    U32         const current = (U32)(ip-base);\n    const BYTE* const dictBase = dms->window.base;\n    const BYTE* const dictEnd = dms->window.nextSrc;\n    U32         const dictHighLimit = (U32)(dms->window.nextSrc - dms->window.base);\n    U32         const dictLowLimit = dms->window.lowLimit;\n    U32         const dictIndexDelta = ms->window.lowLimit - dictHighLimit;\n\n    U32*        const dictBt = dms->chainTable;\n    U32         const btLog  = dmsCParams->chainLog - 1;\n    U32         const btMask = (1 << btLog) - 1;\n    U32         const btLow = (btMask >= dictHighLimit - dictLowLimit) ? dictLowLimit : dictHighLimit - btMask;\n\n    size_t commonLengthSmaller=0, commonLengthLarger=0;\n\n    (void)dictMode;\n    assert(dictMode == ZSTD_dictMatchState);\n\n    while (nbCompares-- && (dictMatchIndex > dictLowLimit)) {\n        U32* const nextPtr = dictBt + 2*(dictMatchIndex & btMask);\n        size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */\n        const BYTE* match = dictBase + dictMatchIndex;\n        matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);\n        if (dictMatchIndex+matchLength >= dictHighLimit)\n            match = base + dictMatchIndex + dictIndexDelta;   /* to prepare for next usage of match[matchLength] */\n\n        if (matchLength > bestLength) {\n            U32 matchIndex = dictMatchIndex + dictIndexDelta;\n            if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) ) {\n                DEBUGLOG(9, \"ZSTD_DUBT_findBetterDictMatch(%u) : found better match length %u -> %u and offsetCode %u -> %u (dictMatchIndex %u, matchIndex %u)\",\n                    current, (U32)bestLength, (U32)matchLength, (U32)*offsetPtr, ZSTD_REP_MOVE + current - matchIndex, dictMatchIndex, matchIndex);\n                bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;\n            }\n            if (ip+matchLength == iend) {   /* reached end of input : ip[matchLength] is not valid, no way to know if it's larger or smaller than match */\n                break;   /* drop, to guarantee consistency (miss a little bit of compression) */\n            }\n        }\n\n        if (match[matchLength] < ip[matchLength]) {\n            if (dictMatchIndex <= btLow) { break; }   /* beyond tree size, stop the search */\n            commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */\n            dictMatchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */\n        } else {\n            /* match is larger than current */\n            if (dictMatchIndex <= btLow) { break; }   /* beyond tree size, stop the search */\n            commonLengthLarger = matchLength;\n            dictMatchIndex = nextPtr[0];\n        }\n    }\n\n    if (bestLength >= MINMATCH) {\n        U32 const mIndex = current - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;\n        DEBUGLOG(8, \"ZSTD_DUBT_findBetterDictMatch(%u) : found match of length %u and offsetCode %u (pos %u)\",\n                    current, (U32)bestLength, (U32)*offsetPtr, mIndex);\n    }\n    return bestLength;\n\n}\n\n\nstatic size_t\nZSTD_DUBT_findBestMatch(ZSTD_matchState_t* ms,\n                        const BYTE* const ip, const BYTE* const iend,\n                        size_t* offsetPtr,\n                        U32 const mls,\n                        const ZSTD_dictMode_e dictMode)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32*   const hashTable = ms->hashTable;\n    U32    const hashLog = cParams->hashLog;\n    size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);\n    U32          matchIndex  = hashTable[h];\n\n    const BYTE* const base = ms->window.base;\n    U32    const current = (U32)(ip-base);\n    U32    const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog);\n\n    U32*   const bt = ms->chainTable;\n    U32    const btLog  = cParams->chainLog - 1;\n    U32    const btMask = (1 << btLog) - 1;\n    U32    const btLow = (btMask >= current) ? 0 : current - btMask;\n    U32    const unsortLimit = MAX(btLow, windowLow);\n\n    U32*         nextCandidate = bt + 2*(matchIndex&btMask);\n    U32*         unsortedMark = bt + 2*(matchIndex&btMask) + 1;\n    U32          nbCompares = 1U << cParams->searchLog;\n    U32          nbCandidates = nbCompares;\n    U32          previousCandidate = 0;\n\n    DEBUGLOG(7, \"ZSTD_DUBT_findBestMatch (%u) \", current);\n    assert(ip <= iend-8);   /* required for h calculation */\n\n    /* reach end of unsorted candidates list */\n    while ( (matchIndex > unsortLimit)\n         && (*unsortedMark == ZSTD_DUBT_UNSORTED_MARK)\n         && (nbCandidates > 1) ) {\n        DEBUGLOG(8, \"ZSTD_DUBT_findBestMatch: candidate %u is unsorted\",\n                    matchIndex);\n        *unsortedMark = previousCandidate;  /* the unsortedMark becomes a reversed chain, to move up back to original position */\n        previousCandidate = matchIndex;\n        matchIndex = *nextCandidate;\n        nextCandidate = bt + 2*(matchIndex&btMask);\n        unsortedMark = bt + 2*(matchIndex&btMask) + 1;\n        nbCandidates --;\n    }\n\n    /* nullify last candidate if it's still unsorted\n     * simplification, detrimental to compression ratio, beneficial for speed */\n    if ( (matchIndex > unsortLimit)\n      && (*unsortedMark==ZSTD_DUBT_UNSORTED_MARK) ) {\n        DEBUGLOG(7, \"ZSTD_DUBT_findBestMatch: nullify last unsorted candidate %u\",\n                    matchIndex);\n        *nextCandidate = *unsortedMark = 0;\n    }\n\n    /* batch sort stacked candidates */\n    matchIndex = previousCandidate;\n    while (matchIndex) {  /* will end on matchIndex == 0 */\n        U32* const nextCandidateIdxPtr = bt + 2*(matchIndex&btMask) + 1;\n        U32 const nextCandidateIdx = *nextCandidateIdxPtr;\n        ZSTD_insertDUBT1(ms, matchIndex, iend,\n                         nbCandidates, unsortLimit, dictMode);\n        matchIndex = nextCandidateIdx;\n        nbCandidates++;\n    }\n\n    /* find longest match */\n    {   size_t commonLengthSmaller = 0, commonLengthLarger = 0;\n        const BYTE* const dictBase = ms->window.dictBase;\n        const U32 dictLimit = ms->window.dictLimit;\n        const BYTE* const dictEnd = dictBase + dictLimit;\n        const BYTE* const prefixStart = base + dictLimit;\n        U32* smallerPtr = bt + 2*(current&btMask);\n        U32* largerPtr  = bt + 2*(current&btMask) + 1;\n        U32 matchEndIdx = current + 8 + 1;\n        U32 dummy32;   /* to be nullified at the end */\n        size_t bestLength = 0;\n\n        matchIndex  = hashTable[h];\n        hashTable[h] = current;   /* Update Hash Table */\n\n        while (nbCompares-- && (matchIndex > windowLow)) {\n            U32* const nextPtr = bt + 2*(matchIndex & btMask);\n            size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */\n            const BYTE* match;\n\n            if ((dictMode != ZSTD_extDict) || (matchIndex+matchLength >= dictLimit)) {\n                match = base + matchIndex;\n                matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);\n            } else {\n                match = dictBase + matchIndex;\n                matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);\n                if (matchIndex+matchLength >= dictLimit)\n                    match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */\n            }\n\n            if (matchLength > bestLength) {\n                if (matchLength > matchEndIdx - matchIndex)\n                    matchEndIdx = matchIndex + (U32)matchLength;\n                if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )\n                    bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;\n                if (ip+matchLength == iend) {   /* equal : no way to know if inf or sup */\n                    if (dictMode == ZSTD_dictMatchState) {\n                        nbCompares = 0; /* in addition to avoiding checking any\n                                         * further in this loop, make sure we\n                                         * skip checking in the dictionary. */\n                    }\n                    break;   /* drop, to guarantee consistency (miss a little bit of compression) */\n                }\n            }\n\n            if (match[matchLength] < ip[matchLength]) {\n                /* match is smaller than current */\n                *smallerPtr = matchIndex;             /* update smaller idx */\n                commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */\n                if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */\n                smallerPtr = nextPtr+1;               /* new \"smaller\" => larger of match */\n                matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */\n            } else {\n                /* match is larger than current */\n                *largerPtr = matchIndex;\n                commonLengthLarger = matchLength;\n                if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */\n                largerPtr = nextPtr;\n                matchIndex = nextPtr[0];\n        }   }\n\n        *smallerPtr = *largerPtr = 0;\n\n        if (dictMode == ZSTD_dictMatchState && nbCompares) {\n            bestLength = ZSTD_DUBT_findBetterDictMatch(\n                    ms, ip, iend,\n                    offsetPtr, bestLength, nbCompares,\n                    mls, dictMode);\n        }\n\n        assert(matchEndIdx > current+8); /* ensure nextToUpdate is increased */\n        ms->nextToUpdate = matchEndIdx - 8;   /* skip repetitive patterns */\n        if (bestLength >= MINMATCH) {\n            U32 const mIndex = current - ((U32)*offsetPtr - ZSTD_REP_MOVE); (void)mIndex;\n            DEBUGLOG(8, \"ZSTD_DUBT_findBestMatch(%u) : found match of length %u and offsetCode %u (pos %u)\",\n                        current, (U32)bestLength, (U32)*offsetPtr, mIndex);\n        }\n        return bestLength;\n    }\n}\n\n\n/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */\nFORCE_INLINE_TEMPLATE size_t\nZSTD_BtFindBestMatch( ZSTD_matchState_t* ms,\n                const BYTE* const ip, const BYTE* const iLimit,\n                      size_t* offsetPtr,\n                const U32 mls /* template */,\n                const ZSTD_dictMode_e dictMode)\n{\n    DEBUGLOG(7, \"ZSTD_BtFindBestMatch\");\n    if (ip < ms->window.base + ms->nextToUpdate) return 0;   /* skipped area */\n    ZSTD_updateDUBT(ms, ip, iLimit, mls);\n    return ZSTD_DUBT_findBestMatch(ms, ip, iLimit, offsetPtr, mls, dictMode);\n}\n\n\nstatic size_t\nZSTD_BtFindBestMatch_selectMLS (  ZSTD_matchState_t* ms,\n                            const BYTE* ip, const BYTE* const iLimit,\n                                  size_t* offsetPtr)\n{\n    switch(ms->cParams.minMatch)\n    {\n    default : /* includes case 3 */\n    case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_noDict);\n    case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_noDict);\n    case 7 :\n    case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_noDict);\n    }\n}\n\n\nstatic size_t ZSTD_BtFindBestMatch_dictMatchState_selectMLS (\n                        ZSTD_matchState_t* ms,\n                        const BYTE* ip, const BYTE* const iLimit,\n                        size_t* offsetPtr)\n{\n    switch(ms->cParams.minMatch)\n    {\n    default : /* includes case 3 */\n    case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState);\n    case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState);\n    case 7 :\n    case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState);\n    }\n}\n\n\nstatic size_t ZSTD_BtFindBestMatch_extDict_selectMLS (\n                        ZSTD_matchState_t* ms,\n                        const BYTE* ip, const BYTE* const iLimit,\n                        size_t* offsetPtr)\n{\n    switch(ms->cParams.minMatch)\n    {\n    default : /* includes case 3 */\n    case 4 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 4, ZSTD_extDict);\n    case 5 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 5, ZSTD_extDict);\n    case 7 :\n    case 6 : return ZSTD_BtFindBestMatch(ms, ip, iLimit, offsetPtr, 6, ZSTD_extDict);\n    }\n}\n\n\n\n/* *********************************\n*  Hash Chain\n***********************************/\n#define NEXT_IN_CHAIN(d, mask)   chainTable[(d) & (mask)]\n\n/* Update chains up to ip (excluded)\n   Assumption : always within prefix (i.e. not within extDict) */\nstatic U32 ZSTD_insertAndFindFirstIndex_internal(\n                        ZSTD_matchState_t* ms,\n                        const ZSTD_compressionParameters* const cParams,\n                        const BYTE* ip, U32 const mls)\n{\n    U32* const hashTable  = ms->hashTable;\n    const U32 hashLog = cParams->hashLog;\n    U32* const chainTable = ms->chainTable;\n    const U32 chainMask = (1 << cParams->chainLog) - 1;\n    const BYTE* const base = ms->window.base;\n    const U32 target = (U32)(ip - base);\n    U32 idx = ms->nextToUpdate;\n\n    while(idx < target) { /* catch up */\n        size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);\n        NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];\n        hashTable[h] = idx;\n        idx++;\n    }\n\n    ms->nextToUpdate = target;\n    return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];\n}\n\nU32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip) {\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    return ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, ms->cParams.minMatch);\n}\n\n\n/* inlining is important to hardwire a hot branch (template emulation) */\nFORCE_INLINE_TEMPLATE\nsize_t ZSTD_HcFindBestMatch_generic (\n                        ZSTD_matchState_t* ms,\n                        const BYTE* const ip, const BYTE* const iLimit,\n                        size_t* offsetPtr,\n                        const U32 mls, const ZSTD_dictMode_e dictMode)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32* const chainTable = ms->chainTable;\n    const U32 chainSize = (1 << cParams->chainLog);\n    const U32 chainMask = chainSize-1;\n    const BYTE* const base = ms->window.base;\n    const BYTE* const dictBase = ms->window.dictBase;\n    const U32 dictLimit = ms->window.dictLimit;\n    const BYTE* const prefixStart = base + dictLimit;\n    const BYTE* const dictEnd = dictBase + dictLimit;\n    const U32 current = (U32)(ip-base);\n    const U32 maxDistance = 1U << cParams->windowLog;\n    const U32 lowestValid = ms->window.lowLimit;\n    const U32 withinMaxDistance = (current - lowestValid > maxDistance) ? current - maxDistance : lowestValid;\n    const U32 isDictionary = (ms->loadedDictEnd != 0);\n    const U32 lowLimit = isDictionary ? lowestValid : withinMaxDistance;\n    const U32 minChain = current > chainSize ? current - chainSize : 0;\n    U32 nbAttempts = 1U << cParams->searchLog;\n    size_t ml=4-1;\n\n    /* HC4 match finder */\n    U32 matchIndex = ZSTD_insertAndFindFirstIndex_internal(ms, cParams, ip, mls);\n\n    for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {\n        size_t currentMl=0;\n        if ((dictMode != ZSTD_extDict) || matchIndex >= dictLimit) {\n            const BYTE* const match = base + matchIndex;\n            assert(matchIndex >= dictLimit);   /* ensures this is true if dictMode != ZSTD_extDict */\n            if (match[ml] == ip[ml])   /* potentially better */\n                currentMl = ZSTD_count(ip, match, iLimit);\n        } else {\n            const BYTE* const match = dictBase + matchIndex;\n            assert(match+4 <= dictEnd);\n            if (MEM_read32(match) == MEM_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */\n                currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;\n        }\n\n        /* save best solution */\n        if (currentMl > ml) {\n            ml = currentMl;\n            *offsetPtr = current - matchIndex + ZSTD_REP_MOVE;\n            if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */\n        }\n\n        if (matchIndex <= minChain) break;\n        matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);\n    }\n\n    if (dictMode == ZSTD_dictMatchState) {\n        const ZSTD_matchState_t* const dms = ms->dictMatchState;\n        const U32* const dmsChainTable = dms->chainTable;\n        const U32 dmsChainSize         = (1 << dms->cParams.chainLog);\n        const U32 dmsChainMask         = dmsChainSize - 1;\n        const U32 dmsLowestIndex       = dms->window.dictLimit;\n        const BYTE* const dmsBase      = dms->window.base;\n        const BYTE* const dmsEnd       = dms->window.nextSrc;\n        const U32 dmsSize              = (U32)(dmsEnd - dmsBase);\n        const U32 dmsIndexDelta        = dictLimit - dmsSize;\n        const U32 dmsMinChain = dmsSize > dmsChainSize ? dmsSize - dmsChainSize : 0;\n\n        matchIndex = dms->hashTable[ZSTD_hashPtr(ip, dms->cParams.hashLog, mls)];\n\n        for ( ; (matchIndex>dmsLowestIndex) & (nbAttempts>0) ; nbAttempts--) {\n            size_t currentMl=0;\n            const BYTE* const match = dmsBase + matchIndex;\n            assert(match+4 <= dmsEnd);\n            if (MEM_read32(match) == MEM_read32(ip))   /* assumption : matchIndex <= dictLimit-4 (by table construction) */\n                currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dmsEnd, prefixStart) + 4;\n\n            /* save best solution */\n            if (currentMl > ml) {\n                ml = currentMl;\n                *offsetPtr = current - (matchIndex + dmsIndexDelta) + ZSTD_REP_MOVE;\n                if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */\n            }\n\n            if (matchIndex <= dmsMinChain) break;\n            matchIndex = dmsChainTable[matchIndex & dmsChainMask];\n        }\n    }\n\n    return ml;\n}\n\n\nFORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_selectMLS (\n                        ZSTD_matchState_t* ms,\n                        const BYTE* ip, const BYTE* const iLimit,\n                        size_t* offsetPtr)\n{\n    switch(ms->cParams.minMatch)\n    {\n    default : /* includes case 3 */\n    case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_noDict);\n    case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_noDict);\n    case 7 :\n    case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_noDict);\n    }\n}\n\n\nstatic size_t ZSTD_HcFindBestMatch_dictMatchState_selectMLS (\n                        ZSTD_matchState_t* ms,\n                        const BYTE* ip, const BYTE* const iLimit,\n                        size_t* offsetPtr)\n{\n    switch(ms->cParams.minMatch)\n    {\n    default : /* includes case 3 */\n    case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_dictMatchState);\n    case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_dictMatchState);\n    case 7 :\n    case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_dictMatchState);\n    }\n}\n\n\nFORCE_INLINE_TEMPLATE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (\n                        ZSTD_matchState_t* ms,\n                        const BYTE* ip, const BYTE* const iLimit,\n                        size_t* offsetPtr)\n{\n    switch(ms->cParams.minMatch)\n    {\n    default : /* includes case 3 */\n    case 4 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 4, ZSTD_extDict);\n    case 5 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 5, ZSTD_extDict);\n    case 7 :\n    case 6 : return ZSTD_HcFindBestMatch_generic(ms, ip, iLimit, offsetPtr, 6, ZSTD_extDict);\n    }\n}\n\n\n/* *******************************\n*  Common parser - lazy strategy\n*********************************/\ntypedef enum { search_hashChain, search_binaryTree } searchMethod_e;\n\nFORCE_INLINE_TEMPLATE size_t\nZSTD_compressBlock_lazy_generic(\n                        ZSTD_matchState_t* ms, seqStore_t* seqStore,\n                        U32 rep[ZSTD_REP_NUM],\n                        const void* src, size_t srcSize,\n                        const searchMethod_e searchMethod, const U32 depth,\n                        ZSTD_dictMode_e const dictMode)\n{\n    const BYTE* const istart = (const BYTE*)src;\n    const BYTE* ip = istart;\n    const BYTE* anchor = istart;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* const ilimit = iend - 8;\n    const BYTE* const base = ms->window.base;\n    const U32 prefixLowestIndex = ms->window.dictLimit;\n    const BYTE* const prefixLowest = base + prefixLowestIndex;\n\n    typedef size_t (*searchMax_f)(\n                        ZSTD_matchState_t* ms,\n                        const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);\n    searchMax_f const searchMax = dictMode == ZSTD_dictMatchState ?\n        (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_dictMatchState_selectMLS\n                                         : ZSTD_HcFindBestMatch_dictMatchState_selectMLS) :\n        (searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_selectMLS\n                                         : ZSTD_HcFindBestMatch_selectMLS);\n    U32 offset_1 = rep[0], offset_2 = rep[1], savedOffset=0;\n\n    const ZSTD_matchState_t* const dms = ms->dictMatchState;\n    const U32 dictLowestIndex      = dictMode == ZSTD_dictMatchState ?\n                                     dms->window.dictLimit : 0;\n    const BYTE* const dictBase     = dictMode == ZSTD_dictMatchState ?\n                                     dms->window.base : NULL;\n    const BYTE* const dictLowest   = dictMode == ZSTD_dictMatchState ?\n                                     dictBase + dictLowestIndex : NULL;\n    const BYTE* const dictEnd      = dictMode == ZSTD_dictMatchState ?\n                                     dms->window.nextSrc : NULL;\n    const U32 dictIndexDelta       = dictMode == ZSTD_dictMatchState ?\n                                     prefixLowestIndex - (U32)(dictEnd - dictBase) :\n                                     0;\n    const U32 dictAndPrefixLength = (U32)(ip - prefixLowest + dictEnd - dictLowest);\n\n    /* init */\n    ip += (dictAndPrefixLength == 0);\n    if (dictMode == ZSTD_noDict) {\n        U32 const maxRep = (U32)(ip - prefixLowest);\n        if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;\n        if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;\n    }\n    if (dictMode == ZSTD_dictMatchState) {\n        /* dictMatchState repCode checks don't currently handle repCode == 0\n         * disabling. */\n        assert(offset_1 <= dictAndPrefixLength);\n        assert(offset_2 <= dictAndPrefixLength);\n    }\n\n    /* Match Loop */\n    while (ip < ilimit) {\n        size_t matchLength=0;\n        size_t offset=0;\n        const BYTE* start=ip+1;\n\n        /* check repCode */\n        if (dictMode == ZSTD_dictMatchState) {\n            const U32 repIndex = (U32)(ip - base) + 1 - offset_1;\n            const BYTE* repMatch = (dictMode == ZSTD_dictMatchState\n                                && repIndex < prefixLowestIndex) ?\n                                   dictBase + (repIndex - dictIndexDelta) :\n                                   base + repIndex;\n            if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)\n                && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {\n                const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;\n                matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;\n                if (depth==0) goto _storeSequence;\n            }\n        }\n        if ( dictMode == ZSTD_noDict\n          && ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1)))) {\n            matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;\n            if (depth==0) goto _storeSequence;\n        }\n\n        /* first search (depth 0) */\n        {   size_t offsetFound = 999999999;\n            size_t const ml2 = searchMax(ms, ip, iend, &offsetFound);\n            if (ml2 > matchLength)\n                matchLength = ml2, start = ip, offset=offsetFound;\n        }\n\n        if (matchLength < 4) {\n            ip += ((ip-anchor) >> kSearchStrength) + 1;   /* jump faster over incompressible sections */\n            continue;\n        }\n\n        /* let's try to find a better solution */\n        if (depth>=1)\n        while (ip<ilimit) {\n            ip ++;\n            if ( (dictMode == ZSTD_noDict)\n              && (offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {\n                size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;\n                int const gain2 = (int)(mlRep * 3);\n                int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);\n                if ((mlRep >= 4) && (gain2 > gain1))\n                    matchLength = mlRep, offset = 0, start = ip;\n            }\n            if (dictMode == ZSTD_dictMatchState) {\n                const U32 repIndex = (U32)(ip - base) - offset_1;\n                const BYTE* repMatch = repIndex < prefixLowestIndex ?\n                               dictBase + (repIndex - dictIndexDelta) :\n                               base + repIndex;\n                if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)\n                    && (MEM_read32(repMatch) == MEM_read32(ip)) ) {\n                    const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;\n                    size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;\n                    int const gain2 = (int)(mlRep * 3);\n                    int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);\n                    if ((mlRep >= 4) && (gain2 > gain1))\n                        matchLength = mlRep, offset = 0, start = ip;\n                }\n            }\n            {   size_t offset2=999999999;\n                size_t const ml2 = searchMax(ms, ip, iend, &offset2);\n                int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */\n                int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);\n                if ((ml2 >= 4) && (gain2 > gain1)) {\n                    matchLength = ml2, offset = offset2, start = ip;\n                    continue;   /* search a better one */\n            }   }\n\n            /* let's find an even better one */\n            if ((depth==2) && (ip<ilimit)) {\n                ip ++;\n                if ( (dictMode == ZSTD_noDict)\n                  && (offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {\n                    size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;\n                    int const gain2 = (int)(mlRep * 4);\n                    int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);\n                    if ((mlRep >= 4) && (gain2 > gain1))\n                        matchLength = mlRep, offset = 0, start = ip;\n                }\n                if (dictMode == ZSTD_dictMatchState) {\n                    const U32 repIndex = (U32)(ip - base) - offset_1;\n                    const BYTE* repMatch = repIndex < prefixLowestIndex ?\n                                   dictBase + (repIndex - dictIndexDelta) :\n                                   base + repIndex;\n                    if (((U32)((prefixLowestIndex-1) - repIndex) >= 3 /* intentional underflow */)\n                        && (MEM_read32(repMatch) == MEM_read32(ip)) ) {\n                        const BYTE* repMatchEnd = repIndex < prefixLowestIndex ? dictEnd : iend;\n                        size_t const mlRep = ZSTD_count_2segments(ip+4, repMatch+4, iend, repMatchEnd, prefixLowest) + 4;\n                        int const gain2 = (int)(mlRep * 4);\n                        int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);\n                        if ((mlRep >= 4) && (gain2 > gain1))\n                            matchLength = mlRep, offset = 0, start = ip;\n                    }\n                }\n                {   size_t offset2=999999999;\n                    size_t const ml2 = searchMax(ms, ip, iend, &offset2);\n                    int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */\n                    int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);\n                    if ((ml2 >= 4) && (gain2 > gain1)) {\n                        matchLength = ml2, offset = offset2, start = ip;\n                        continue;\n            }   }   }\n            break;  /* nothing found : store previous solution */\n        }\n\n        /* NOTE:\n         * start[-offset+ZSTD_REP_MOVE-1] is undefined behavior.\n         * (-offset+ZSTD_REP_MOVE-1) is unsigned, and is added to start, which\n         * overflows the pointer, which is undefined behavior.\n         */\n        /* catch up */\n        if (offset) {\n            if (dictMode == ZSTD_noDict) {\n                while ( ((start > anchor) & (start - (offset-ZSTD_REP_MOVE) > prefixLowest))\n                     && (start[-1] == (start-(offset-ZSTD_REP_MOVE))[-1]) )  /* only search for offset within prefix */\n                    { start--; matchLength++; }\n            }\n            if (dictMode == ZSTD_dictMatchState) {\n                U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));\n                const BYTE* match = (matchIndex < prefixLowestIndex) ? dictBase + matchIndex - dictIndexDelta : base + matchIndex;\n                const BYTE* const mStart = (matchIndex < prefixLowestIndex) ? dictLowest : prefixLowest;\n                while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; }  /* catch up */\n            }\n            offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);\n        }\n        /* store sequence */\n_storeSequence:\n        {   size_t const litLength = start - anchor;\n            ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offset, matchLength-MINMATCH);\n            anchor = ip = start + matchLength;\n        }\n\n        /* check immediate repcode */\n        if (dictMode == ZSTD_dictMatchState) {\n            while (ip <= ilimit) {\n                U32 const current2 = (U32)(ip-base);\n                U32 const repIndex = current2 - offset_2;\n                const BYTE* repMatch = dictMode == ZSTD_dictMatchState\n                    && repIndex < prefixLowestIndex ?\n                        dictBase - dictIndexDelta + repIndex :\n                        base + repIndex;\n                if ( ((U32)((prefixLowestIndex-1) - (U32)repIndex) >= 3 /* intentional overflow */)\n                   && (MEM_read32(repMatch) == MEM_read32(ip)) ) {\n                    const BYTE* const repEnd2 = repIndex < prefixLowestIndex ? dictEnd : iend;\n                    matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd2, prefixLowest) + 4;\n                    offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset;   /* swap offset_2 <=> offset_1 */\n                    ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);\n                    ip += matchLength;\n                    anchor = ip;\n                    continue;\n                }\n                break;\n            }\n        }\n\n        if (dictMode == ZSTD_noDict) {\n            while ( ((ip <= ilimit) & (offset_2>0))\n                 && (MEM_read32(ip) == MEM_read32(ip - offset_2)) ) {\n                /* store sequence */\n                matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;\n                offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */\n                ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);\n                ip += matchLength;\n                anchor = ip;\n                continue;   /* faster when present ... (?) */\n    }   }   }\n\n    /* Save reps for next block */\n    rep[0] = offset_1 ? offset_1 : savedOffset;\n    rep[1] = offset_2 ? offset_2 : savedOffset;\n\n    /* Return the last literals size */\n    return (size_t)(iend - anchor);\n}\n\n\nsize_t ZSTD_compressBlock_btlazy2(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_noDict);\n}\n\nsize_t ZSTD_compressBlock_lazy2(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_noDict);\n}\n\nsize_t ZSTD_compressBlock_lazy(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_noDict);\n}\n\nsize_t ZSTD_compressBlock_greedy(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_noDict);\n}\n\nsize_t ZSTD_compressBlock_btlazy2_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2, ZSTD_dictMatchState);\n}\n\nsize_t ZSTD_compressBlock_lazy2_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2, ZSTD_dictMatchState);\n}\n\nsize_t ZSTD_compressBlock_lazy_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1, ZSTD_dictMatchState);\n}\n\nsize_t ZSTD_compressBlock_greedy_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0, ZSTD_dictMatchState);\n}\n\n\nFORCE_INLINE_TEMPLATE\nsize_t ZSTD_compressBlock_lazy_extDict_generic(\n                        ZSTD_matchState_t* ms, seqStore_t* seqStore,\n                        U32 rep[ZSTD_REP_NUM],\n                        const void* src, size_t srcSize,\n                        const searchMethod_e searchMethod, const U32 depth)\n{\n    const BYTE* const istart = (const BYTE*)src;\n    const BYTE* ip = istart;\n    const BYTE* anchor = istart;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* const ilimit = iend - 8;\n    const BYTE* const base = ms->window.base;\n    const U32 dictLimit = ms->window.dictLimit;\n    const U32 lowestIndex = ms->window.lowLimit;\n    const BYTE* const prefixStart = base + dictLimit;\n    const BYTE* const dictBase = ms->window.dictBase;\n    const BYTE* const dictEnd  = dictBase + dictLimit;\n    const BYTE* const dictStart  = dictBase + lowestIndex;\n\n    typedef size_t (*searchMax_f)(\n                        ZSTD_matchState_t* ms,\n                        const BYTE* ip, const BYTE* iLimit, size_t* offsetPtr);\n    searchMax_f searchMax = searchMethod==search_binaryTree ? ZSTD_BtFindBestMatch_extDict_selectMLS : ZSTD_HcFindBestMatch_extDict_selectMLS;\n\n    U32 offset_1 = rep[0], offset_2 = rep[1];\n\n    /* init */\n    ip += (ip == prefixStart);\n\n    /* Match Loop */\n    while (ip < ilimit) {\n        size_t matchLength=0;\n        size_t offset=0;\n        const BYTE* start=ip+1;\n        U32 current = (U32)(ip-base);\n\n        /* check repCode */\n        {   const U32 repIndex = (U32)(current+1 - offset_1);\n            const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;\n            const BYTE* const repMatch = repBase + repIndex;\n            if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))   /* intentional overflow */\n            if (MEM_read32(ip+1) == MEM_read32(repMatch)) {\n                /* repcode detected we should take it */\n                const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;\n                matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4;\n                if (depth==0) goto _storeSequence;\n        }   }\n\n        /* first search (depth 0) */\n        {   size_t offsetFound = 999999999;\n            size_t const ml2 = searchMax(ms, ip, iend, &offsetFound);\n            if (ml2 > matchLength)\n                matchLength = ml2, start = ip, offset=offsetFound;\n        }\n\n         if (matchLength < 4) {\n            ip += ((ip-anchor) >> kSearchStrength) + 1;   /* jump faster over incompressible sections */\n            continue;\n        }\n\n        /* let's try to find a better solution */\n        if (depth>=1)\n        while (ip<ilimit) {\n            ip ++;\n            current++;\n            /* check repCode */\n            if (offset) {\n                const U32 repIndex = (U32)(current - offset_1);\n                const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;\n                const BYTE* const repMatch = repBase + repIndex;\n                if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */\n                if (MEM_read32(ip) == MEM_read32(repMatch)) {\n                    /* repcode detected */\n                    const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;\n                    size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;\n                    int const gain2 = (int)(repLength * 3);\n                    int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);\n                    if ((repLength >= 4) && (gain2 > gain1))\n                        matchLength = repLength, offset = 0, start = ip;\n            }   }\n\n            /* search match, depth 1 */\n            {   size_t offset2=999999999;\n                size_t const ml2 = searchMax(ms, ip, iend, &offset2);\n                int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */\n                int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);\n                if ((ml2 >= 4) && (gain2 > gain1)) {\n                    matchLength = ml2, offset = offset2, start = ip;\n                    continue;   /* search a better one */\n            }   }\n\n            /* let's find an even better one */\n            if ((depth==2) && (ip<ilimit)) {\n                ip ++;\n                current++;\n                /* check repCode */\n                if (offset) {\n                    const U32 repIndex = (U32)(current - offset_1);\n                    const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;\n                    const BYTE* const repMatch = repBase + repIndex;\n                    if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */\n                    if (MEM_read32(ip) == MEM_read32(repMatch)) {\n                        /* repcode detected */\n                        const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;\n                        size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;\n                        int const gain2 = (int)(repLength * 4);\n                        int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);\n                        if ((repLength >= 4) && (gain2 > gain1))\n                            matchLength = repLength, offset = 0, start = ip;\n                }   }\n\n                /* search match, depth 2 */\n                {   size_t offset2=999999999;\n                    size_t const ml2 = searchMax(ms, ip, iend, &offset2);\n                    int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1));   /* raw approx */\n                    int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);\n                    if ((ml2 >= 4) && (gain2 > gain1)) {\n                        matchLength = ml2, offset = offset2, start = ip;\n                        continue;\n            }   }   }\n            break;  /* nothing found : store previous solution */\n        }\n\n        /* catch up */\n        if (offset) {\n            U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));\n            const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;\n            const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;\n            while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; }  /* catch up */\n            offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);\n        }\n\n        /* store sequence */\n_storeSequence:\n        {   size_t const litLength = start - anchor;\n            ZSTD_storeSeq(seqStore, litLength, anchor, iend, (U32)offset, matchLength-MINMATCH);\n            anchor = ip = start + matchLength;\n        }\n\n        /* check immediate repcode */\n        while (ip <= ilimit) {\n            const U32 repIndex = (U32)((ip-base) - offset_2);\n            const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;\n            const BYTE* const repMatch = repBase + repIndex;\n            if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex))  /* intentional overflow */\n            if (MEM_read32(ip) == MEM_read32(repMatch)) {\n                /* repcode detected we should take it */\n                const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;\n                matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;\n                offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset;   /* swap offset history */\n                ZSTD_storeSeq(seqStore, 0, anchor, iend, 0, matchLength-MINMATCH);\n                ip += matchLength;\n                anchor = ip;\n                continue;   /* faster when present ... (?) */\n            }\n            break;\n    }   }\n\n    /* Save reps for next block */\n    rep[0] = offset_1;\n    rep[1] = offset_2;\n\n    /* Return the last literals size */\n    return (size_t)(iend - anchor);\n}\n\n\nsize_t ZSTD_compressBlock_greedy_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 0);\n}\n\nsize_t ZSTD_compressBlock_lazy_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n\n{\n    return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 1);\n}\n\nsize_t ZSTD_compressBlock_lazy2_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n\n{\n    return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_hashChain, 2);\n}\n\nsize_t ZSTD_compressBlock_btlazy2_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize)\n\n{\n    return ZSTD_compressBlock_lazy_extDict_generic(ms, seqStore, rep, src, srcSize, search_binaryTree, 2);\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_lazy.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_LAZY_H\n#define ZSTD_LAZY_H\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#include \"zstd_compress_internal.h\"\n\nU32 ZSTD_insertAndFindFirstIndex(ZSTD_matchState_t* ms, const BYTE* ip);\n\nvoid ZSTD_preserveUnsortedMark (U32* const table, U32 const size, U32 const reducerValue);  /*! used in ZSTD_reduceIndex(). preemptively increase value of ZSTD_DUBT_UNSORTED_MARK */\n\nsize_t ZSTD_compressBlock_btlazy2(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_lazy2(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_lazy(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_greedy(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\n\nsize_t ZSTD_compressBlock_btlazy2_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_lazy2_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_lazy_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_greedy_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\n\nsize_t ZSTD_compressBlock_greedy_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_lazy_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_lazy2_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_btlazy2_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* ZSTD_LAZY_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_ldm.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n */\n\n#include \"zstd_ldm.h\"\n\n#include \"debug.h\"\n#include \"zstd_fast.h\"          /* ZSTD_fillHashTable() */\n#include \"zstd_double_fast.h\"   /* ZSTD_fillDoubleHashTable() */\n\n#define LDM_BUCKET_SIZE_LOG 3\n#define LDM_MIN_MATCH_LENGTH 64\n#define LDM_HASH_RLOG 7\n#define LDM_HASH_CHAR_OFFSET 10\n\nvoid ZSTD_ldm_adjustParameters(ldmParams_t* params,\n                               ZSTD_compressionParameters const* cParams)\n{\n    params->windowLog = cParams->windowLog;\n    ZSTD_STATIC_ASSERT(LDM_BUCKET_SIZE_LOG <= ZSTD_LDM_BUCKETSIZELOG_MAX);\n    DEBUGLOG(4, \"ZSTD_ldm_adjustParameters\");\n    if (!params->bucketSizeLog) params->bucketSizeLog = LDM_BUCKET_SIZE_LOG;\n    if (!params->minMatchLength) params->minMatchLength = LDM_MIN_MATCH_LENGTH;\n    if (cParams->strategy >= ZSTD_btopt) {\n      /* Get out of the way of the optimal parser */\n      U32 const minMatch = MAX(cParams->targetLength, params->minMatchLength);\n      assert(minMatch >= ZSTD_LDM_MINMATCH_MIN);\n      assert(minMatch <= ZSTD_LDM_MINMATCH_MAX);\n      params->minMatchLength = minMatch;\n    }\n    if (params->hashLog == 0) {\n        params->hashLog = MAX(ZSTD_HASHLOG_MIN, params->windowLog - LDM_HASH_RLOG);\n        assert(params->hashLog <= ZSTD_HASHLOG_MAX);\n    }\n    if (params->hashRateLog == 0) {\n        params->hashRateLog = params->windowLog < params->hashLog\n                                   ? 0\n                                   : params->windowLog - params->hashLog;\n    }\n    params->bucketSizeLog = MIN(params->bucketSizeLog, params->hashLog);\n}\n\nsize_t ZSTD_ldm_getTableSize(ldmParams_t params)\n{\n    size_t const ldmHSize = ((size_t)1) << params.hashLog;\n    size_t const ldmBucketSizeLog = MIN(params.bucketSizeLog, params.hashLog);\n    size_t const ldmBucketSize = ((size_t)1) << (params.hashLog - ldmBucketSizeLog);\n    size_t const totalSize = ZSTD_cwksp_alloc_size(ldmBucketSize)\n                           + ZSTD_cwksp_alloc_size(ldmHSize * sizeof(ldmEntry_t));\n    return params.enableLdm ? totalSize : 0;\n}\n\nsize_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize)\n{\n    return params.enableLdm ? (maxChunkSize / params.minMatchLength) : 0;\n}\n\n/** ZSTD_ldm_getSmallHash() :\n *  numBits should be <= 32\n *  If numBits==0, returns 0.\n *  @return : the most significant numBits of value. */\nstatic U32 ZSTD_ldm_getSmallHash(U64 value, U32 numBits)\n{\n    assert(numBits <= 32);\n    return numBits == 0 ? 0 : (U32)(value >> (64 - numBits));\n}\n\n/** ZSTD_ldm_getChecksum() :\n *  numBitsToDiscard should be <= 32\n *  @return : the next most significant 32 bits after numBitsToDiscard */\nstatic U32 ZSTD_ldm_getChecksum(U64 hash, U32 numBitsToDiscard)\n{\n    assert(numBitsToDiscard <= 32);\n    return (hash >> (64 - 32 - numBitsToDiscard)) & 0xFFFFFFFF;\n}\n\n/** ZSTD_ldm_getTag() ;\n *  Given the hash, returns the most significant numTagBits bits\n *  after (32 + hbits) bits.\n *\n *  If there are not enough bits remaining, return the last\n *  numTagBits bits. */\nstatic U32 ZSTD_ldm_getTag(U64 hash, U32 hbits, U32 numTagBits)\n{\n    assert(numTagBits < 32 && hbits <= 32);\n    if (32 - hbits < numTagBits) {\n        return hash & (((U32)1 << numTagBits) - 1);\n    } else {\n        return (hash >> (32 - hbits - numTagBits)) & (((U32)1 << numTagBits) - 1);\n    }\n}\n\n/** ZSTD_ldm_getBucket() :\n *  Returns a pointer to the start of the bucket associated with hash. */\nstatic ldmEntry_t* ZSTD_ldm_getBucket(\n        ldmState_t* ldmState, size_t hash, ldmParams_t const ldmParams)\n{\n    return ldmState->hashTable + (hash << ldmParams.bucketSizeLog);\n}\n\n/** ZSTD_ldm_insertEntry() :\n *  Insert the entry with corresponding hash into the hash table */\nstatic void ZSTD_ldm_insertEntry(ldmState_t* ldmState,\n                                 size_t const hash, const ldmEntry_t entry,\n                                 ldmParams_t const ldmParams)\n{\n    BYTE* const bucketOffsets = ldmState->bucketOffsets;\n    *(ZSTD_ldm_getBucket(ldmState, hash, ldmParams) + bucketOffsets[hash]) = entry;\n    bucketOffsets[hash]++;\n    bucketOffsets[hash] &= ((U32)1 << ldmParams.bucketSizeLog) - 1;\n}\n\n/** ZSTD_ldm_makeEntryAndInsertByTag() :\n *\n *  Gets the small hash, checksum, and tag from the rollingHash.\n *\n *  If the tag matches (1 << ldmParams.hashRateLog)-1, then\n *  creates an ldmEntry from the offset, and inserts it into the hash table.\n *\n *  hBits is the length of the small hash, which is the most significant hBits\n *  of rollingHash. The checksum is the next 32 most significant bits, followed\n *  by ldmParams.hashRateLog bits that make up the tag. */\nstatic void ZSTD_ldm_makeEntryAndInsertByTag(ldmState_t* ldmState,\n                                             U64 const rollingHash,\n                                             U32 const hBits,\n                                             U32 const offset,\n                                             ldmParams_t const ldmParams)\n{\n    U32 const tag = ZSTD_ldm_getTag(rollingHash, hBits, ldmParams.hashRateLog);\n    U32 const tagMask = ((U32)1 << ldmParams.hashRateLog) - 1;\n    if (tag == tagMask) {\n        U32 const hash = ZSTD_ldm_getSmallHash(rollingHash, hBits);\n        U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);\n        ldmEntry_t entry;\n        entry.offset = offset;\n        entry.checksum = checksum;\n        ZSTD_ldm_insertEntry(ldmState, hash, entry, ldmParams);\n    }\n}\n\n/** ZSTD_ldm_countBackwardsMatch() :\n *  Returns the number of bytes that match backwards before pIn and pMatch.\n *\n *  We count only bytes where pMatch >= pBase and pIn >= pAnchor. */\nstatic size_t ZSTD_ldm_countBackwardsMatch(\n            const BYTE* pIn, const BYTE* pAnchor,\n            const BYTE* pMatch, const BYTE* pBase)\n{\n    size_t matchLength = 0;\n    while (pIn > pAnchor && pMatch > pBase && pIn[-1] == pMatch[-1]) {\n        pIn--;\n        pMatch--;\n        matchLength++;\n    }\n    return matchLength;\n}\n\n/** ZSTD_ldm_fillFastTables() :\n *\n *  Fills the relevant tables for the ZSTD_fast and ZSTD_dfast strategies.\n *  This is similar to ZSTD_loadDictionaryContent.\n *\n *  The tables for the other strategies are filled within their\n *  block compressors. */\nstatic size_t ZSTD_ldm_fillFastTables(ZSTD_matchState_t* ms,\n                                      void const* end)\n{\n    const BYTE* const iend = (const BYTE*)end;\n\n    switch(ms->cParams.strategy)\n    {\n    case ZSTD_fast:\n        ZSTD_fillHashTable(ms, iend, ZSTD_dtlm_fast);\n        break;\n\n    case ZSTD_dfast:\n        ZSTD_fillDoubleHashTable(ms, iend, ZSTD_dtlm_fast);\n        break;\n\n    case ZSTD_greedy:\n    case ZSTD_lazy:\n    case ZSTD_lazy2:\n    case ZSTD_btlazy2:\n    case ZSTD_btopt:\n    case ZSTD_btultra:\n    case ZSTD_btultra2:\n        break;\n    default:\n        assert(0);  /* not possible : not a valid strategy id */\n    }\n\n    return 0;\n}\n\n/** ZSTD_ldm_fillLdmHashTable() :\n *\n *  Fills hashTable from (lastHashed + 1) to iend (non-inclusive).\n *  lastHash is the rolling hash that corresponds to lastHashed.\n *\n *  Returns the rolling hash corresponding to position iend-1. */\nstatic U64 ZSTD_ldm_fillLdmHashTable(ldmState_t* state,\n                                     U64 lastHash, const BYTE* lastHashed,\n                                     const BYTE* iend, const BYTE* base,\n                                     U32 hBits, ldmParams_t const ldmParams)\n{\n    U64 rollingHash = lastHash;\n    const BYTE* cur = lastHashed + 1;\n\n    while (cur < iend) {\n        rollingHash = ZSTD_rollingHash_rotate(rollingHash, cur[-1],\n                                              cur[ldmParams.minMatchLength-1],\n                                              state->hashPower);\n        ZSTD_ldm_makeEntryAndInsertByTag(state,\n                                         rollingHash, hBits,\n                                         (U32)(cur - base), ldmParams);\n        ++cur;\n    }\n    return rollingHash;\n}\n\n\n/** ZSTD_ldm_limitTableUpdate() :\n *\n *  Sets cctx->nextToUpdate to a position corresponding closer to anchor\n *  if it is far way\n *  (after a long match, only update tables a limited amount). */\nstatic void ZSTD_ldm_limitTableUpdate(ZSTD_matchState_t* ms, const BYTE* anchor)\n{\n    U32 const current = (U32)(anchor - ms->window.base);\n    if (current > ms->nextToUpdate + 1024) {\n        ms->nextToUpdate =\n            current - MIN(512, current - ms->nextToUpdate - 1024);\n    }\n}\n\nstatic size_t ZSTD_ldm_generateSequences_internal(\n        ldmState_t* ldmState, rawSeqStore_t* rawSeqStore,\n        ldmParams_t const* params, void const* src, size_t srcSize)\n{\n    /* LDM parameters */\n    int const extDict = ZSTD_window_hasExtDict(ldmState->window);\n    U32 const minMatchLength = params->minMatchLength;\n    U64 const hashPower = ldmState->hashPower;\n    U32 const hBits = params->hashLog - params->bucketSizeLog;\n    U32 const ldmBucketSize = 1U << params->bucketSizeLog;\n    U32 const hashRateLog = params->hashRateLog;\n    U32 const ldmTagMask = (1U << params->hashRateLog) - 1;\n    /* Prefix and extDict parameters */\n    U32 const dictLimit = ldmState->window.dictLimit;\n    U32 const lowestIndex = extDict ? ldmState->window.lowLimit : dictLimit;\n    BYTE const* const base = ldmState->window.base;\n    BYTE const* const dictBase = extDict ? ldmState->window.dictBase : NULL;\n    BYTE const* const dictStart = extDict ? dictBase + lowestIndex : NULL;\n    BYTE const* const dictEnd = extDict ? dictBase + dictLimit : NULL;\n    BYTE const* const lowPrefixPtr = base + dictLimit;\n    /* Input bounds */\n    BYTE const* const istart = (BYTE const*)src;\n    BYTE const* const iend = istart + srcSize;\n    BYTE const* const ilimit = iend - MAX(minMatchLength, HASH_READ_SIZE);\n    /* Input positions */\n    BYTE const* anchor = istart;\n    BYTE const* ip = istart;\n    /* Rolling hash */\n    BYTE const* lastHashed = NULL;\n    U64 rollingHash = 0;\n\n    while (ip <= ilimit) {\n        size_t mLength;\n        U32 const current = (U32)(ip - base);\n        size_t forwardMatchLength = 0, backwardMatchLength = 0;\n        ldmEntry_t* bestEntry = NULL;\n        if (ip != istart) {\n            rollingHash = ZSTD_rollingHash_rotate(rollingHash, lastHashed[0],\n                                                  lastHashed[minMatchLength],\n                                                  hashPower);\n        } else {\n            rollingHash = ZSTD_rollingHash_compute(ip, minMatchLength);\n        }\n        lastHashed = ip;\n\n        /* Do not insert and do not look for a match */\n        if (ZSTD_ldm_getTag(rollingHash, hBits, hashRateLog) != ldmTagMask) {\n           ip++;\n           continue;\n        }\n\n        /* Get the best entry and compute the match lengths */\n        {\n            ldmEntry_t* const bucket =\n                ZSTD_ldm_getBucket(ldmState,\n                                   ZSTD_ldm_getSmallHash(rollingHash, hBits),\n                                   *params);\n            ldmEntry_t* cur;\n            size_t bestMatchLength = 0;\n            U32 const checksum = ZSTD_ldm_getChecksum(rollingHash, hBits);\n\n            for (cur = bucket; cur < bucket + ldmBucketSize; ++cur) {\n                size_t curForwardMatchLength, curBackwardMatchLength,\n                       curTotalMatchLength;\n                if (cur->checksum != checksum || cur->offset <= lowestIndex) {\n                    continue;\n                }\n                if (extDict) {\n                    BYTE const* const curMatchBase =\n                        cur->offset < dictLimit ? dictBase : base;\n                    BYTE const* const pMatch = curMatchBase + cur->offset;\n                    BYTE const* const matchEnd =\n                        cur->offset < dictLimit ? dictEnd : iend;\n                    BYTE const* const lowMatchPtr =\n                        cur->offset < dictLimit ? dictStart : lowPrefixPtr;\n\n                    curForwardMatchLength = ZSTD_count_2segments(\n                                                ip, pMatch, iend,\n                                                matchEnd, lowPrefixPtr);\n                    if (curForwardMatchLength < minMatchLength) {\n                        continue;\n                    }\n                    curBackwardMatchLength =\n                        ZSTD_ldm_countBackwardsMatch(ip, anchor, pMatch,\n                                                     lowMatchPtr);\n                    curTotalMatchLength = curForwardMatchLength +\n                                          curBackwardMatchLength;\n                } else { /* !extDict */\n                    BYTE const* const pMatch = base + cur->offset;\n                    curForwardMatchLength = ZSTD_count(ip, pMatch, iend);\n                    if (curForwardMatchLength < minMatchLength) {\n                        continue;\n                    }\n                    curBackwardMatchLength =\n                        ZSTD_ldm_countBackwardsMatch(ip, anchor, pMatch,\n                                                     lowPrefixPtr);\n                    curTotalMatchLength = curForwardMatchLength +\n                                          curBackwardMatchLength;\n                }\n\n                if (curTotalMatchLength > bestMatchLength) {\n                    bestMatchLength = curTotalMatchLength;\n                    forwardMatchLength = curForwardMatchLength;\n                    backwardMatchLength = curBackwardMatchLength;\n                    bestEntry = cur;\n                }\n            }\n        }\n\n        /* No match found -- continue searching */\n        if (bestEntry == NULL) {\n            ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash,\n                                             hBits, current,\n                                             *params);\n            ip++;\n            continue;\n        }\n\n        /* Match found */\n        mLength = forwardMatchLength + backwardMatchLength;\n        ip -= backwardMatchLength;\n\n        {\n            /* Store the sequence:\n             * ip = current - backwardMatchLength\n             * The match is at (bestEntry->offset - backwardMatchLength)\n             */\n            U32 const matchIndex = bestEntry->offset;\n            U32 const offset = current - matchIndex;\n            rawSeq* const seq = rawSeqStore->seq + rawSeqStore->size;\n\n            /* Out of sequence storage */\n            if (rawSeqStore->size == rawSeqStore->capacity)\n                return ERROR(dstSize_tooSmall);\n            seq->litLength = (U32)(ip - anchor);\n            seq->matchLength = (U32)mLength;\n            seq->offset = offset;\n            rawSeqStore->size++;\n        }\n\n        /* Insert the current entry into the hash table */\n        ZSTD_ldm_makeEntryAndInsertByTag(ldmState, rollingHash, hBits,\n                                         (U32)(lastHashed - base),\n                                         *params);\n\n        assert(ip + backwardMatchLength == lastHashed);\n\n        /* Fill the hash table from lastHashed+1 to ip+mLength*/\n        /* Heuristic: don't need to fill the entire table at end of block */\n        if (ip + mLength <= ilimit) {\n            rollingHash = ZSTD_ldm_fillLdmHashTable(\n                              ldmState, rollingHash, lastHashed,\n                              ip + mLength, base, hBits, *params);\n            lastHashed = ip + mLength - 1;\n        }\n        ip += mLength;\n        anchor = ip;\n    }\n    return iend - anchor;\n}\n\n/*! ZSTD_ldm_reduceTable() :\n *  reduce table indexes by `reducerValue` */\nstatic void ZSTD_ldm_reduceTable(ldmEntry_t* const table, U32 const size,\n                                 U32 const reducerValue)\n{\n    U32 u;\n    for (u = 0; u < size; u++) {\n        if (table[u].offset < reducerValue) table[u].offset = 0;\n        else table[u].offset -= reducerValue;\n    }\n}\n\nsize_t ZSTD_ldm_generateSequences(\n        ldmState_t* ldmState, rawSeqStore_t* sequences,\n        ldmParams_t const* params, void const* src, size_t srcSize)\n{\n    U32 const maxDist = 1U << params->windowLog;\n    BYTE const* const istart = (BYTE const*)src;\n    BYTE const* const iend = istart + srcSize;\n    size_t const kMaxChunkSize = 1 << 20;\n    size_t const nbChunks = (srcSize / kMaxChunkSize) + ((srcSize % kMaxChunkSize) != 0);\n    size_t chunk;\n    size_t leftoverSize = 0;\n\n    assert(ZSTD_CHUNKSIZE_MAX >= kMaxChunkSize);\n    /* Check that ZSTD_window_update() has been called for this chunk prior\n     * to passing it to this function.\n     */\n    assert(ldmState->window.nextSrc >= (BYTE const*)src + srcSize);\n    /* The input could be very large (in zstdmt), so it must be broken up into\n     * chunks to enforce the maximum distance and handle overflow correction.\n     */\n    assert(sequences->pos <= sequences->size);\n    assert(sequences->size <= sequences->capacity);\n    for (chunk = 0; chunk < nbChunks && sequences->size < sequences->capacity; ++chunk) {\n        BYTE const* const chunkStart = istart + chunk * kMaxChunkSize;\n        size_t const remaining = (size_t)(iend - chunkStart);\n        BYTE const *const chunkEnd =\n            (remaining < kMaxChunkSize) ? iend : chunkStart + kMaxChunkSize;\n        size_t const chunkSize = chunkEnd - chunkStart;\n        size_t newLeftoverSize;\n        size_t const prevSize = sequences->size;\n\n        assert(chunkStart < iend);\n        /* 1. Perform overflow correction if necessary. */\n        if (ZSTD_window_needOverflowCorrection(ldmState->window, chunkEnd)) {\n            U32 const ldmHSize = 1U << params->hashLog;\n            U32 const correction = ZSTD_window_correctOverflow(\n                &ldmState->window, /* cycleLog */ 0, maxDist, chunkStart);\n            ZSTD_ldm_reduceTable(ldmState->hashTable, ldmHSize, correction);\n        }\n        /* 2. We enforce the maximum offset allowed.\n         *\n         * kMaxChunkSize should be small enough that we don't lose too much of\n         * the window through early invalidation.\n         * TODO: * Test the chunk size.\n         *       * Try invalidation after the sequence generation and test the\n         *         the offset against maxDist directly.\n         */\n        ZSTD_window_enforceMaxDist(&ldmState->window, chunkEnd, maxDist, NULL, NULL);\n        /* 3. Generate the sequences for the chunk, and get newLeftoverSize. */\n        newLeftoverSize = ZSTD_ldm_generateSequences_internal(\n            ldmState, sequences, params, chunkStart, chunkSize);\n        if (ZSTD_isError(newLeftoverSize))\n            return newLeftoverSize;\n        /* 4. We add the leftover literals from previous iterations to the first\n         *    newly generated sequence, or add the `newLeftoverSize` if none are\n         *    generated.\n         */\n        /* Prepend the leftover literals from the last call */\n        if (prevSize < sequences->size) {\n            sequences->seq[prevSize].litLength += (U32)leftoverSize;\n            leftoverSize = newLeftoverSize;\n        } else {\n            assert(newLeftoverSize == chunkSize);\n            leftoverSize += chunkSize;\n        }\n    }\n    return 0;\n}\n\nvoid ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize, U32 const minMatch) {\n    while (srcSize > 0 && rawSeqStore->pos < rawSeqStore->size) {\n        rawSeq* seq = rawSeqStore->seq + rawSeqStore->pos;\n        if (srcSize <= seq->litLength) {\n            /* Skip past srcSize literals */\n            seq->litLength -= (U32)srcSize;\n            return;\n        }\n        srcSize -= seq->litLength;\n        seq->litLength = 0;\n        if (srcSize < seq->matchLength) {\n            /* Skip past the first srcSize of the match */\n            seq->matchLength -= (U32)srcSize;\n            if (seq->matchLength < minMatch) {\n                /* The match is too short, omit it */\n                if (rawSeqStore->pos + 1 < rawSeqStore->size) {\n                    seq[1].litLength += seq[0].matchLength;\n                }\n                rawSeqStore->pos++;\n            }\n            return;\n        }\n        srcSize -= seq->matchLength;\n        seq->matchLength = 0;\n        rawSeqStore->pos++;\n    }\n}\n\n/**\n * If the sequence length is longer than remaining then the sequence is split\n * between this block and the next.\n *\n * Returns the current sequence to handle, or if the rest of the block should\n * be literals, it returns a sequence with offset == 0.\n */\nstatic rawSeq maybeSplitSequence(rawSeqStore_t* rawSeqStore,\n                                 U32 const remaining, U32 const minMatch)\n{\n    rawSeq sequence = rawSeqStore->seq[rawSeqStore->pos];\n    assert(sequence.offset > 0);\n    /* Likely: No partial sequence */\n    if (remaining >= sequence.litLength + sequence.matchLength) {\n        rawSeqStore->pos++;\n        return sequence;\n    }\n    /* Cut the sequence short (offset == 0 ==> rest is literals). */\n    if (remaining <= sequence.litLength) {\n        sequence.offset = 0;\n    } else if (remaining < sequence.litLength + sequence.matchLength) {\n        sequence.matchLength = remaining - sequence.litLength;\n        if (sequence.matchLength < minMatch) {\n            sequence.offset = 0;\n        }\n    }\n    /* Skip past `remaining` bytes for the future sequences. */\n    ZSTD_ldm_skipSequences(rawSeqStore, remaining, minMatch);\n    return sequence;\n}\n\nsize_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,\n    ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n    void const* src, size_t srcSize)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    unsigned const minMatch = cParams->minMatch;\n    ZSTD_blockCompressor const blockCompressor =\n        ZSTD_selectBlockCompressor(cParams->strategy, ZSTD_matchState_dictMode(ms));\n    /* Input bounds */\n    BYTE const* const istart = (BYTE const*)src;\n    BYTE const* const iend = istart + srcSize;\n    /* Input positions */\n    BYTE const* ip = istart;\n\n    DEBUGLOG(5, \"ZSTD_ldm_blockCompress: srcSize=%zu\", srcSize);\n    assert(rawSeqStore->pos <= rawSeqStore->size);\n    assert(rawSeqStore->size <= rawSeqStore->capacity);\n    /* Loop through each sequence and apply the block compressor to the lits */\n    while (rawSeqStore->pos < rawSeqStore->size && ip < iend) {\n        /* maybeSplitSequence updates rawSeqStore->pos */\n        rawSeq const sequence = maybeSplitSequence(rawSeqStore,\n                                                   (U32)(iend - ip), minMatch);\n        int i;\n        /* End signal */\n        if (sequence.offset == 0)\n            break;\n\n        assert(sequence.offset <= (1U << cParams->windowLog));\n        assert(ip + sequence.litLength + sequence.matchLength <= iend);\n\n        /* Fill tables for block compressor */\n        ZSTD_ldm_limitTableUpdate(ms, ip);\n        ZSTD_ldm_fillFastTables(ms, ip);\n        /* Run the block compressor */\n        DEBUGLOG(5, \"calling block compressor on segment of size %u\", sequence.litLength);\n        {\n            size_t const newLitLength =\n                blockCompressor(ms, seqStore, rep, ip, sequence.litLength);\n            ip += sequence.litLength;\n            /* Update the repcodes */\n            for (i = ZSTD_REP_NUM - 1; i > 0; i--)\n                rep[i] = rep[i-1];\n            rep[0] = sequence.offset;\n            /* Store the sequence */\n            ZSTD_storeSeq(seqStore, newLitLength, ip - newLitLength, iend,\n                          sequence.offset + ZSTD_REP_MOVE,\n                          sequence.matchLength - MINMATCH);\n            ip += sequence.matchLength;\n        }\n    }\n    /* Fill the tables for the block compressor */\n    ZSTD_ldm_limitTableUpdate(ms, ip);\n    ZSTD_ldm_fillFastTables(ms, ip);\n    /* Compress the last literals */\n    return blockCompressor(ms, seqStore, rep, ip, iend - ip);\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_ldm.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n */\n\n#ifndef ZSTD_LDM_H\n#define ZSTD_LDM_H\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#include \"zstd_compress_internal.h\"   /* ldmParams_t, U32 */\n#include \"zstd.h\"   /* ZSTD_CCtx, size_t */\n\n/*-*************************************\n*  Long distance matching\n***************************************/\n\n#define ZSTD_LDM_DEFAULT_WINDOW_LOG ZSTD_WINDOWLOG_LIMIT_DEFAULT\n\n/**\n * ZSTD_ldm_generateSequences():\n *\n * Generates the sequences using the long distance match finder.\n * Generates long range matching sequences in `sequences`, which parse a prefix\n * of the source. `sequences` must be large enough to store every sequence,\n * which can be checked with `ZSTD_ldm_getMaxNbSeq()`.\n * @returns 0 or an error code.\n *\n * NOTE: The user must have called ZSTD_window_update() for all of the input\n * they have, even if they pass it to ZSTD_ldm_generateSequences() in chunks.\n * NOTE: This function returns an error if it runs out of space to store\n *       sequences.\n */\nsize_t ZSTD_ldm_generateSequences(\n            ldmState_t* ldms, rawSeqStore_t* sequences,\n            ldmParams_t const* params, void const* src, size_t srcSize);\n\n/**\n * ZSTD_ldm_blockCompress():\n *\n * Compresses a block using the predefined sequences, along with a secondary\n * block compressor. The literals section of every sequence is passed to the\n * secondary block compressor, and those sequences are interspersed with the\n * predefined sequences. Returns the length of the last literals.\n * Updates `rawSeqStore.pos` to indicate how many sequences have been consumed.\n * `rawSeqStore.seq` may also be updated to split the last sequence between two\n * blocks.\n * @return The length of the last literals.\n *\n * NOTE: The source must be at most the maximum block size, but the predefined\n * sequences can be any size, and may be longer than the block. In the case that\n * they are longer than the block, the last sequences may need to be split into\n * two. We handle that case correctly, and update `rawSeqStore` appropriately.\n * NOTE: This function does not return any errors.\n */\nsize_t ZSTD_ldm_blockCompress(rawSeqStore_t* rawSeqStore,\n            ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n            void const* src, size_t srcSize);\n\n/**\n * ZSTD_ldm_skipSequences():\n *\n * Skip past `srcSize` bytes worth of sequences in `rawSeqStore`.\n * Avoids emitting matches less than `minMatch` bytes.\n * Must be called for data with is not passed to ZSTD_ldm_blockCompress().\n */\nvoid ZSTD_ldm_skipSequences(rawSeqStore_t* rawSeqStore, size_t srcSize,\n    U32 const minMatch);\n\n\n/** ZSTD_ldm_getTableSize() :\n *  Estimate the space needed for long distance matching tables or 0 if LDM is\n *  disabled.\n */\nsize_t ZSTD_ldm_getTableSize(ldmParams_t params);\n\n/** ZSTD_ldm_getSeqSpace() :\n *  Return an upper bound on the number of sequences that can be produced by\n *  the long distance matcher, or 0 if LDM is disabled.\n */\nsize_t ZSTD_ldm_getMaxNbSeq(ldmParams_t params, size_t maxChunkSize);\n\n/** ZSTD_ldm_adjustParameters() :\n *  If the params->hashRateLog is not set, set it to its default value based on\n *  windowLog and params->hashLog.\n *\n *  Ensures that params->bucketSizeLog is <= params->hashLog (setting it to\n *  params->hashLog if it is not).\n *\n *  Ensures that the minMatchLength >= targetLength during optimal parsing.\n */\nvoid ZSTD_ldm_adjustParameters(ldmParams_t* params,\n                               ZSTD_compressionParameters const* cParams);\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* ZSTD_FAST_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_opt.c",
    "content": "/*\n * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#include \"zstd_compress_internal.h\"\n#include \"hist.h\"\n#include \"zstd_opt.h\"\n\n\n#define ZSTD_LITFREQ_ADD    2   /* scaling factor for litFreq, so that frequencies adapt faster to new stats */\n#define ZSTD_FREQ_DIV       4   /* log factor when using previous stats to init next stats */\n#define ZSTD_MAX_PRICE     (1<<30)\n\n#define ZSTD_PREDEF_THRESHOLD 1024   /* if srcSize < ZSTD_PREDEF_THRESHOLD, symbols' cost is assumed static, directly determined by pre-defined distributions */\n\n\n/*-*************************************\n*  Price functions for optimal parser\n***************************************/\n\n#if 0    /* approximation at bit level */\n#  define BITCOST_ACCURACY 0\n#  define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)\n#  define WEIGHT(stat)  ((void)opt, ZSTD_bitWeight(stat))\n#elif 0  /* fractional bit accuracy */\n#  define BITCOST_ACCURACY 8\n#  define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)\n#  define WEIGHT(stat,opt) ((void)opt, ZSTD_fracWeight(stat))\n#else    /* opt==approx, ultra==accurate */\n#  define BITCOST_ACCURACY 8\n#  define BITCOST_MULTIPLIER (1 << BITCOST_ACCURACY)\n#  define WEIGHT(stat,opt) (opt ? ZSTD_fracWeight(stat) : ZSTD_bitWeight(stat))\n#endif\n\nMEM_STATIC U32 ZSTD_bitWeight(U32 stat)\n{\n    return (ZSTD_highbit32(stat+1) * BITCOST_MULTIPLIER);\n}\n\nMEM_STATIC U32 ZSTD_fracWeight(U32 rawStat)\n{\n    U32 const stat = rawStat + 1;\n    U32 const hb = ZSTD_highbit32(stat);\n    U32 const BWeight = hb * BITCOST_MULTIPLIER;\n    U32 const FWeight = (stat << BITCOST_ACCURACY) >> hb;\n    U32 const weight = BWeight + FWeight;\n    assert(hb + BITCOST_ACCURACY < 31);\n    return weight;\n}\n\n#if (DEBUGLEVEL>=2)\n/* debugging function,\n * @return price in bytes as fractional value\n * for debug messages only */\nMEM_STATIC double ZSTD_fCost(U32 price)\n{\n    return (double)price / (BITCOST_MULTIPLIER*8);\n}\n#endif\n\nstatic int ZSTD_compressedLiterals(optState_t const* const optPtr)\n{\n    return optPtr->literalCompressionMode != ZSTD_lcm_uncompressed;\n}\n\nstatic void ZSTD_setBasePrices(optState_t* optPtr, int optLevel)\n{\n    if (ZSTD_compressedLiterals(optPtr))\n        optPtr->litSumBasePrice = WEIGHT(optPtr->litSum, optLevel);\n    optPtr->litLengthSumBasePrice = WEIGHT(optPtr->litLengthSum, optLevel);\n    optPtr->matchLengthSumBasePrice = WEIGHT(optPtr->matchLengthSum, optLevel);\n    optPtr->offCodeSumBasePrice = WEIGHT(optPtr->offCodeSum, optLevel);\n}\n\n\n/* ZSTD_downscaleStat() :\n * reduce all elements in table by a factor 2^(ZSTD_FREQ_DIV+malus)\n * return the resulting sum of elements */\nstatic U32 ZSTD_downscaleStat(unsigned* table, U32 lastEltIndex, int malus)\n{\n    U32 s, sum=0;\n    DEBUGLOG(5, \"ZSTD_downscaleStat (nbElts=%u)\", (unsigned)lastEltIndex+1);\n    assert(ZSTD_FREQ_DIV+malus > 0 && ZSTD_FREQ_DIV+malus < 31);\n    for (s=0; s<lastEltIndex+1; s++) {\n        table[s] = 1 + (table[s] >> (ZSTD_FREQ_DIV+malus));\n        sum += table[s];\n    }\n    return sum;\n}\n\n/* ZSTD_rescaleFreqs() :\n * if first block (detected by optPtr->litLengthSum == 0) : init statistics\n *    take hints from dictionary if there is one\n *    or init from zero, using src for literals stats, or flat 1 for match symbols\n * otherwise downscale existing stats, to be used as seed for next block.\n */\nstatic void\nZSTD_rescaleFreqs(optState_t* const optPtr,\n            const BYTE* const src, size_t const srcSize,\n                  int const optLevel)\n{\n    int const compressedLiterals = ZSTD_compressedLiterals(optPtr);\n    DEBUGLOG(5, \"ZSTD_rescaleFreqs (srcSize=%u)\", (unsigned)srcSize);\n    optPtr->priceType = zop_dynamic;\n\n    if (optPtr->litLengthSum == 0) {  /* first block : init */\n        if (srcSize <= ZSTD_PREDEF_THRESHOLD) {  /* heuristic */\n            DEBUGLOG(5, \"(srcSize <= ZSTD_PREDEF_THRESHOLD) => zop_predef\");\n            optPtr->priceType = zop_predef;\n        }\n\n        assert(optPtr->symbolCosts != NULL);\n        if (optPtr->symbolCosts->huf.repeatMode == HUF_repeat_valid) {\n            /* huffman table presumed generated by dictionary */\n            optPtr->priceType = zop_dynamic;\n\n            if (compressedLiterals) {\n                unsigned lit;\n                assert(optPtr->litFreq != NULL);\n                optPtr->litSum = 0;\n                for (lit=0; lit<=MaxLit; lit++) {\n                    U32 const scaleLog = 11;   /* scale to 2K */\n                    U32 const bitCost = HUF_getNbBits(optPtr->symbolCosts->huf.CTable, lit);\n                    assert(bitCost <= scaleLog);\n                    optPtr->litFreq[lit] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;\n                    optPtr->litSum += optPtr->litFreq[lit];\n            }   }\n\n            {   unsigned ll;\n                FSE_CState_t llstate;\n                FSE_initCState(&llstate, optPtr->symbolCosts->fse.litlengthCTable);\n                optPtr->litLengthSum = 0;\n                for (ll=0; ll<=MaxLL; ll++) {\n                    U32 const scaleLog = 10;   /* scale to 1K */\n                    U32 const bitCost = FSE_getMaxNbBits(llstate.symbolTT, ll);\n                    assert(bitCost < scaleLog);\n                    optPtr->litLengthFreq[ll] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;\n                    optPtr->litLengthSum += optPtr->litLengthFreq[ll];\n            }   }\n\n            {   unsigned ml;\n                FSE_CState_t mlstate;\n                FSE_initCState(&mlstate, optPtr->symbolCosts->fse.matchlengthCTable);\n                optPtr->matchLengthSum = 0;\n                for (ml=0; ml<=MaxML; ml++) {\n                    U32 const scaleLog = 10;\n                    U32 const bitCost = FSE_getMaxNbBits(mlstate.symbolTT, ml);\n                    assert(bitCost < scaleLog);\n                    optPtr->matchLengthFreq[ml] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;\n                    optPtr->matchLengthSum += optPtr->matchLengthFreq[ml];\n            }   }\n\n            {   unsigned of;\n                FSE_CState_t ofstate;\n                FSE_initCState(&ofstate, optPtr->symbolCosts->fse.offcodeCTable);\n                optPtr->offCodeSum = 0;\n                for (of=0; of<=MaxOff; of++) {\n                    U32 const scaleLog = 10;\n                    U32 const bitCost = FSE_getMaxNbBits(ofstate.symbolTT, of);\n                    assert(bitCost < scaleLog);\n                    optPtr->offCodeFreq[of] = bitCost ? 1 << (scaleLog-bitCost) : 1 /*minimum to calculate cost*/;\n                    optPtr->offCodeSum += optPtr->offCodeFreq[of];\n            }   }\n\n        } else {  /* not a dictionary */\n\n            assert(optPtr->litFreq != NULL);\n            if (compressedLiterals) {\n                unsigned lit = MaxLit;\n                HIST_count_simple(optPtr->litFreq, &lit, src, srcSize);   /* use raw first block to init statistics */\n                optPtr->litSum = ZSTD_downscaleStat(optPtr->litFreq, MaxLit, 1);\n            }\n\n            {   unsigned ll;\n                for (ll=0; ll<=MaxLL; ll++)\n                    optPtr->litLengthFreq[ll] = 1;\n            }\n            optPtr->litLengthSum = MaxLL+1;\n\n            {   unsigned ml;\n                for (ml=0; ml<=MaxML; ml++)\n                    optPtr->matchLengthFreq[ml] = 1;\n            }\n            optPtr->matchLengthSum = MaxML+1;\n\n            {   unsigned of;\n                for (of=0; of<=MaxOff; of++)\n                    optPtr->offCodeFreq[of] = 1;\n            }\n            optPtr->offCodeSum = MaxOff+1;\n\n        }\n\n    } else {   /* new block : re-use previous statistics, scaled down */\n\n        if (compressedLiterals)\n            optPtr->litSum = ZSTD_downscaleStat(optPtr->litFreq, MaxLit, 1);\n        optPtr->litLengthSum = ZSTD_downscaleStat(optPtr->litLengthFreq, MaxLL, 0);\n        optPtr->matchLengthSum = ZSTD_downscaleStat(optPtr->matchLengthFreq, MaxML, 0);\n        optPtr->offCodeSum = ZSTD_downscaleStat(optPtr->offCodeFreq, MaxOff, 0);\n    }\n\n    ZSTD_setBasePrices(optPtr, optLevel);\n}\n\n/* ZSTD_rawLiteralsCost() :\n * price of literals (only) in specified segment (which length can be 0).\n * does not include price of literalLength symbol */\nstatic U32 ZSTD_rawLiteralsCost(const BYTE* const literals, U32 const litLength,\n                                const optState_t* const optPtr,\n                                int optLevel)\n{\n    if (litLength == 0) return 0;\n\n    if (!ZSTD_compressedLiterals(optPtr))\n        return (litLength << 3) * BITCOST_MULTIPLIER;  /* Uncompressed - 8 bytes per literal. */\n\n    if (optPtr->priceType == zop_predef)\n        return (litLength*6) * BITCOST_MULTIPLIER;  /* 6 bit per literal - no statistic used */\n\n    /* dynamic statistics */\n    {   U32 price = litLength * optPtr->litSumBasePrice;\n        U32 u;\n        for (u=0; u < litLength; u++) {\n            assert(WEIGHT(optPtr->litFreq[literals[u]], optLevel) <= optPtr->litSumBasePrice);   /* literal cost should never be negative */\n            price -= WEIGHT(optPtr->litFreq[literals[u]], optLevel);\n        }\n        return price;\n    }\n}\n\n/* ZSTD_litLengthPrice() :\n * cost of literalLength symbol */\nstatic U32 ZSTD_litLengthPrice(U32 const litLength, const optState_t* const optPtr, int optLevel)\n{\n    if (optPtr->priceType == zop_predef) return WEIGHT(litLength, optLevel);\n\n    /* dynamic statistics */\n    {   U32 const llCode = ZSTD_LLcode(litLength);\n        return (LL_bits[llCode] * BITCOST_MULTIPLIER)\n             + optPtr->litLengthSumBasePrice\n             - WEIGHT(optPtr->litLengthFreq[llCode], optLevel);\n    }\n}\n\n/* ZSTD_litLengthContribution() :\n * @return ( cost(litlength) - cost(0) )\n * this value can then be added to rawLiteralsCost()\n * to provide a cost which is directly comparable to a match ending at same position */\nstatic int ZSTD_litLengthContribution(U32 const litLength, const optState_t* const optPtr, int optLevel)\n{\n    if (optPtr->priceType >= zop_predef) return (int)WEIGHT(litLength, optLevel);\n\n    /* dynamic statistics */\n    {   U32 const llCode = ZSTD_LLcode(litLength);\n        int const contribution = (int)(LL_bits[llCode] * BITCOST_MULTIPLIER)\n                               + (int)WEIGHT(optPtr->litLengthFreq[0], optLevel)   /* note: log2litLengthSum cancel out */\n                               - (int)WEIGHT(optPtr->litLengthFreq[llCode], optLevel);\n#if 1\n        return contribution;\n#else\n        return MAX(0, contribution); /* sometimes better, sometimes not ... */\n#endif\n    }\n}\n\n/* ZSTD_literalsContribution() :\n * creates a fake cost for the literals part of a sequence\n * which can be compared to the ending cost of a match\n * should a new match start at this position */\nstatic int ZSTD_literalsContribution(const BYTE* const literals, U32 const litLength,\n                                     const optState_t* const optPtr,\n                                     int optLevel)\n{\n    int const contribution = (int)ZSTD_rawLiteralsCost(literals, litLength, optPtr, optLevel)\n                           + ZSTD_litLengthContribution(litLength, optPtr, optLevel);\n    return contribution;\n}\n\n/* ZSTD_getMatchPrice() :\n * Provides the cost of the match part (offset + matchLength) of a sequence\n * Must be combined with ZSTD_fullLiteralsCost() to get the full cost of a sequence.\n * optLevel: when <2, favors small offset for decompression speed (improved cache efficiency) */\nFORCE_INLINE_TEMPLATE U32\nZSTD_getMatchPrice(U32 const offset,\n                   U32 const matchLength,\n             const optState_t* const optPtr,\n                   int const optLevel)\n{\n    U32 price;\n    U32 const offCode = ZSTD_highbit32(offset+1);\n    U32 const mlBase = matchLength - MINMATCH;\n    assert(matchLength >= MINMATCH);\n\n    if (optPtr->priceType == zop_predef)  /* fixed scheme, do not use statistics */\n        return WEIGHT(mlBase, optLevel) + ((16 + offCode) * BITCOST_MULTIPLIER);\n\n    /* dynamic statistics */\n    price = (offCode * BITCOST_MULTIPLIER) + (optPtr->offCodeSumBasePrice - WEIGHT(optPtr->offCodeFreq[offCode], optLevel));\n    if ((optLevel<2) /*static*/ && offCode >= 20)\n        price += (offCode-19)*2 * BITCOST_MULTIPLIER; /* handicap for long distance offsets, favor decompression speed */\n\n    /* match Length */\n    {   U32 const mlCode = ZSTD_MLcode(mlBase);\n        price += (ML_bits[mlCode] * BITCOST_MULTIPLIER) + (optPtr->matchLengthSumBasePrice - WEIGHT(optPtr->matchLengthFreq[mlCode], optLevel));\n    }\n\n    price += BITCOST_MULTIPLIER / 5;   /* heuristic : make matches a bit more costly to favor less sequences -> faster decompression speed */\n\n    DEBUGLOG(8, \"ZSTD_getMatchPrice(ml:%u) = %u\", matchLength, price);\n    return price;\n}\n\n/* ZSTD_updateStats() :\n * assumption : literals + litLengtn <= iend */\nstatic void ZSTD_updateStats(optState_t* const optPtr,\n                             U32 litLength, const BYTE* literals,\n                             U32 offsetCode, U32 matchLength)\n{\n    /* literals */\n    if (ZSTD_compressedLiterals(optPtr)) {\n        U32 u;\n        for (u=0; u < litLength; u++)\n            optPtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;\n        optPtr->litSum += litLength*ZSTD_LITFREQ_ADD;\n    }\n\n    /* literal Length */\n    {   U32 const llCode = ZSTD_LLcode(litLength);\n        optPtr->litLengthFreq[llCode]++;\n        optPtr->litLengthSum++;\n    }\n\n    /* match offset code (0-2=>repCode; 3+=>offset+2) */\n    {   U32 const offCode = ZSTD_highbit32(offsetCode+1);\n        assert(offCode <= MaxOff);\n        optPtr->offCodeFreq[offCode]++;\n        optPtr->offCodeSum++;\n    }\n\n    /* match Length */\n    {   U32 const mlBase = matchLength - MINMATCH;\n        U32 const mlCode = ZSTD_MLcode(mlBase);\n        optPtr->matchLengthFreq[mlCode]++;\n        optPtr->matchLengthSum++;\n    }\n}\n\n\n/* ZSTD_readMINMATCH() :\n * function safe only for comparisons\n * assumption : memPtr must be at least 4 bytes before end of buffer */\nMEM_STATIC U32 ZSTD_readMINMATCH(const void* memPtr, U32 length)\n{\n    switch (length)\n    {\n    default :\n    case 4 : return MEM_read32(memPtr);\n    case 3 : if (MEM_isLittleEndian())\n                return MEM_read32(memPtr)<<8;\n             else\n                return MEM_read32(memPtr)>>8;\n    }\n}\n\n\n/* Update hashTable3 up to ip (excluded)\n   Assumption : always within prefix (i.e. not within extDict) */\nstatic U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_matchState_t* ms,\n                                              U32* nextToUpdate3,\n                                              const BYTE* const ip)\n{\n    U32* const hashTable3 = ms->hashTable3;\n    U32 const hashLog3 = ms->hashLog3;\n    const BYTE* const base = ms->window.base;\n    U32 idx = *nextToUpdate3;\n    U32 const target = (U32)(ip - base);\n    size_t const hash3 = ZSTD_hash3Ptr(ip, hashLog3);\n    assert(hashLog3 > 0);\n\n    while(idx < target) {\n        hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx;\n        idx++;\n    }\n\n    *nextToUpdate3 = target;\n    return hashTable3[hash3];\n}\n\n\n/*-*************************************\n*  Binary Tree search\n***************************************/\n/** ZSTD_insertBt1() : add one or multiple positions to tree.\n *  ip : assumed <= iend-8 .\n * @return : nb of positions added */\nstatic U32 ZSTD_insertBt1(\n                ZSTD_matchState_t* ms,\n                const BYTE* const ip, const BYTE* const iend,\n                U32 const mls, const int extDict)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32*   const hashTable = ms->hashTable;\n    U32    const hashLog = cParams->hashLog;\n    size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);\n    U32*   const bt = ms->chainTable;\n    U32    const btLog  = cParams->chainLog - 1;\n    U32    const btMask = (1 << btLog) - 1;\n    U32 matchIndex = hashTable[h];\n    size_t commonLengthSmaller=0, commonLengthLarger=0;\n    const BYTE* const base = ms->window.base;\n    const BYTE* const dictBase = ms->window.dictBase;\n    const U32 dictLimit = ms->window.dictLimit;\n    const BYTE* const dictEnd = dictBase + dictLimit;\n    const BYTE* const prefixStart = base + dictLimit;\n    const BYTE* match;\n    const U32 current = (U32)(ip-base);\n    const U32 btLow = btMask >= current ? 0 : current - btMask;\n    U32* smallerPtr = bt + 2*(current&btMask);\n    U32* largerPtr  = smallerPtr + 1;\n    U32 dummy32;   /* to be nullified at the end */\n    U32 const windowLow = ms->window.lowLimit;\n    U32 matchEndIdx = current+8+1;\n    size_t bestLength = 8;\n    U32 nbCompares = 1U << cParams->searchLog;\n#ifdef ZSTD_C_PREDICT\n    U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);\n    U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);\n    predictedSmall += (predictedSmall>0);\n    predictedLarge += (predictedLarge>0);\n#endif /* ZSTD_C_PREDICT */\n\n    DEBUGLOG(8, \"ZSTD_insertBt1 (%u)\", current);\n\n    assert(ip <= iend-8);   /* required for h calculation */\n    hashTable[h] = current;   /* Update Hash Table */\n\n    assert(windowLow > 0);\n    while (nbCompares-- && (matchIndex >= windowLow)) {\n        U32* const nextPtr = bt + 2*(matchIndex & btMask);\n        size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */\n        assert(matchIndex < current);\n\n#ifdef ZSTD_C_PREDICT   /* note : can create issues when hlog small <= 11 */\n        const U32* predictPtr = bt + 2*((matchIndex-1) & btMask);   /* written this way, as bt is a roll buffer */\n        if (matchIndex == predictedSmall) {\n            /* no need to check length, result known */\n            *smallerPtr = matchIndex;\n            if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */\n            smallerPtr = nextPtr+1;               /* new \"smaller\" => larger of match */\n            matchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */\n            predictedSmall = predictPtr[1] + (predictPtr[1]>0);\n            continue;\n        }\n        if (matchIndex == predictedLarge) {\n            *largerPtr = matchIndex;\n            if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */\n            largerPtr = nextPtr;\n            matchIndex = nextPtr[0];\n            predictedLarge = predictPtr[0] + (predictPtr[0]>0);\n            continue;\n        }\n#endif\n\n        if (!extDict || (matchIndex+matchLength >= dictLimit)) {\n            assert(matchIndex+matchLength >= dictLimit);   /* might be wrong if actually extDict */\n            match = base + matchIndex;\n            matchLength += ZSTD_count(ip+matchLength, match+matchLength, iend);\n        } else {\n            match = dictBase + matchIndex;\n            matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);\n            if (matchIndex+matchLength >= dictLimit)\n                match = base + matchIndex;   /* to prepare for next usage of match[matchLength] */\n        }\n\n        if (matchLength > bestLength) {\n            bestLength = matchLength;\n            if (matchLength > matchEndIdx - matchIndex)\n                matchEndIdx = matchIndex + (U32)matchLength;\n        }\n\n        if (ip+matchLength == iend) {   /* equal : no way to know if inf or sup */\n            break;   /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt tree */\n        }\n\n        if (match[matchLength] < ip[matchLength]) {  /* necessarily within buffer */\n            /* match is smaller than current */\n            *smallerPtr = matchIndex;             /* update smaller idx */\n            commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */\n            if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop searching */\n            smallerPtr = nextPtr+1;               /* new \"candidate\" => larger than match, which was smaller than target */\n            matchIndex = nextPtr[1];              /* new matchIndex, larger than previous and closer to current */\n        } else {\n            /* match is larger than current */\n            *largerPtr = matchIndex;\n            commonLengthLarger = matchLength;\n            if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop searching */\n            largerPtr = nextPtr;\n            matchIndex = nextPtr[0];\n    }   }\n\n    *smallerPtr = *largerPtr = 0;\n    {   U32 positions = 0;\n        if (bestLength > 384) positions = MIN(192, (U32)(bestLength - 384));   /* speed optimization */\n        assert(matchEndIdx > current + 8);\n        return MAX(positions, matchEndIdx - (current + 8));\n    }\n}\n\nFORCE_INLINE_TEMPLATE\nvoid ZSTD_updateTree_internal(\n                ZSTD_matchState_t* ms,\n                const BYTE* const ip, const BYTE* const iend,\n                const U32 mls, const ZSTD_dictMode_e dictMode)\n{\n    const BYTE* const base = ms->window.base;\n    U32 const target = (U32)(ip - base);\n    U32 idx = ms->nextToUpdate;\n    DEBUGLOG(6, \"ZSTD_updateTree_internal, from %u to %u  (dictMode:%u)\",\n                idx, target, dictMode);\n\n    while(idx < target) {\n        U32 const forward = ZSTD_insertBt1(ms, base+idx, iend, mls, dictMode == ZSTD_extDict);\n        assert(idx < (U32)(idx + forward));\n        idx += forward;\n    }\n    assert((size_t)(ip - base) <= (size_t)(U32)(-1));\n    assert((size_t)(iend - base) <= (size_t)(U32)(-1));\n    ms->nextToUpdate = target;\n}\n\nvoid ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend) {\n    ZSTD_updateTree_internal(ms, ip, iend, ms->cParams.minMatch, ZSTD_noDict);\n}\n\nFORCE_INLINE_TEMPLATE\nU32 ZSTD_insertBtAndGetAllMatches (\n                    ZSTD_match_t* matches,   /* store result (found matches) in this table (presumed large enough) */\n                    ZSTD_matchState_t* ms,\n                    U32* nextToUpdate3,\n                    const BYTE* const ip, const BYTE* const iLimit, const ZSTD_dictMode_e dictMode,\n                    const U32 rep[ZSTD_REP_NUM],\n                    U32 const ll0,   /* tells if associated literal length is 0 or not. This value must be 0 or 1 */\n                    const U32 lengthToBeat,\n                    U32 const mls /* template */)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);\n    const BYTE* const base = ms->window.base;\n    U32 const current = (U32)(ip-base);\n    U32 const hashLog = cParams->hashLog;\n    U32 const minMatch = (mls==3) ? 3 : 4;\n    U32* const hashTable = ms->hashTable;\n    size_t const h  = ZSTD_hashPtr(ip, hashLog, mls);\n    U32 matchIndex  = hashTable[h];\n    U32* const bt   = ms->chainTable;\n    U32 const btLog = cParams->chainLog - 1;\n    U32 const btMask= (1U << btLog) - 1;\n    size_t commonLengthSmaller=0, commonLengthLarger=0;\n    const BYTE* const dictBase = ms->window.dictBase;\n    U32 const dictLimit = ms->window.dictLimit;\n    const BYTE* const dictEnd = dictBase + dictLimit;\n    const BYTE* const prefixStart = base + dictLimit;\n    U32 const btLow = (btMask >= current) ? 0 : current - btMask;\n    U32 const windowLow = ZSTD_getLowestMatchIndex(ms, current, cParams->windowLog);\n    U32 const matchLow = windowLow ? windowLow : 1;\n    U32* smallerPtr = bt + 2*(current&btMask);\n    U32* largerPtr  = bt + 2*(current&btMask) + 1;\n    U32 matchEndIdx = current+8+1;   /* farthest referenced position of any match => detects repetitive patterns */\n    U32 dummy32;   /* to be nullified at the end */\n    U32 mnum = 0;\n    U32 nbCompares = 1U << cParams->searchLog;\n\n    const ZSTD_matchState_t* dms    = dictMode == ZSTD_dictMatchState ? ms->dictMatchState : NULL;\n    const ZSTD_compressionParameters* const dmsCParams =\n                                      dictMode == ZSTD_dictMatchState ? &dms->cParams : NULL;\n    const BYTE* const dmsBase       = dictMode == ZSTD_dictMatchState ? dms->window.base : NULL;\n    const BYTE* const dmsEnd        = dictMode == ZSTD_dictMatchState ? dms->window.nextSrc : NULL;\n    U32         const dmsHighLimit  = dictMode == ZSTD_dictMatchState ? (U32)(dmsEnd - dmsBase) : 0;\n    U32         const dmsLowLimit   = dictMode == ZSTD_dictMatchState ? dms->window.lowLimit : 0;\n    U32         const dmsIndexDelta = dictMode == ZSTD_dictMatchState ? windowLow - dmsHighLimit : 0;\n    U32         const dmsHashLog    = dictMode == ZSTD_dictMatchState ? dmsCParams->hashLog : hashLog;\n    U32         const dmsBtLog      = dictMode == ZSTD_dictMatchState ? dmsCParams->chainLog - 1 : btLog;\n    U32         const dmsBtMask     = dictMode == ZSTD_dictMatchState ? (1U << dmsBtLog) - 1 : 0;\n    U32         const dmsBtLow      = dictMode == ZSTD_dictMatchState && dmsBtMask < dmsHighLimit - dmsLowLimit ? dmsHighLimit - dmsBtMask : dmsLowLimit;\n\n    size_t bestLength = lengthToBeat-1;\n    DEBUGLOG(8, \"ZSTD_insertBtAndGetAllMatches: current=%u\", current);\n\n    /* check repCode */\n    assert(ll0 <= 1);   /* necessarily 1 or 0 */\n    {   U32 const lastR = ZSTD_REP_NUM + ll0;\n        U32 repCode;\n        for (repCode = ll0; repCode < lastR; repCode++) {\n            U32 const repOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];\n            U32 const repIndex = current - repOffset;\n            U32 repLen = 0;\n            assert(current >= dictLimit);\n            if (repOffset-1 /* intentional overflow, discards 0 and -1 */ < current-dictLimit) {  /* equivalent to `current > repIndex >= dictLimit` */\n                if (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(ip - repOffset, minMatch)) {\n                    repLen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repOffset, iLimit) + minMatch;\n                }\n            } else {  /* repIndex < dictLimit || repIndex >= current */\n                const BYTE* const repMatch = dictMode == ZSTD_dictMatchState ?\n                                             dmsBase + repIndex - dmsIndexDelta :\n                                             dictBase + repIndex;\n                assert(current >= windowLow);\n                if ( dictMode == ZSTD_extDict\n                  && ( ((repOffset-1) /*intentional overflow*/ < current - windowLow)  /* equivalent to `current > repIndex >= windowLow` */\n                     & (((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */)\n                  && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {\n                    repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dictEnd, prefixStart) + minMatch;\n                }\n                if (dictMode == ZSTD_dictMatchState\n                  && ( ((repOffset-1) /*intentional overflow*/ < current - (dmsLowLimit + dmsIndexDelta))  /* equivalent to `current > repIndex >= dmsLowLimit` */\n                     & ((U32)((dictLimit-1) - repIndex) >= 3) ) /* intentional overflow : do not test positions overlapping 2 memory segments */\n                  && (ZSTD_readMINMATCH(ip, minMatch) == ZSTD_readMINMATCH(repMatch, minMatch)) ) {\n                    repLen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iLimit, dmsEnd, prefixStart) + minMatch;\n            }   }\n            /* save longer solution */\n            if (repLen > bestLength) {\n                DEBUGLOG(8, \"found repCode %u (ll0:%u, offset:%u) of length %u\",\n                            repCode, ll0, repOffset, repLen);\n                bestLength = repLen;\n                matches[mnum].off = repCode - ll0;\n                matches[mnum].len = (U32)repLen;\n                mnum++;\n                if ( (repLen > sufficient_len)\n                   | (ip+repLen == iLimit) ) {  /* best possible */\n                    return mnum;\n    }   }   }   }\n\n    /* HC3 match finder */\n    if ((mls == 3) /*static*/ && (bestLength < mls)) {\n        U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3(ms, nextToUpdate3, ip);\n        if ((matchIndex3 >= matchLow)\n          & (current - matchIndex3 < (1<<18)) /*heuristic : longer distance likely too expensive*/ ) {\n            size_t mlen;\n            if ((dictMode == ZSTD_noDict) /*static*/ || (dictMode == ZSTD_dictMatchState) /*static*/ || (matchIndex3 >= dictLimit)) {\n                const BYTE* const match = base + matchIndex3;\n                mlen = ZSTD_count(ip, match, iLimit);\n            } else {\n                const BYTE* const match = dictBase + matchIndex3;\n                mlen = ZSTD_count_2segments(ip, match, iLimit, dictEnd, prefixStart);\n            }\n\n            /* save best solution */\n            if (mlen >= mls /* == 3 > bestLength */) {\n                DEBUGLOG(8, \"found small match with hlog3, of length %u\",\n                            (U32)mlen);\n                bestLength = mlen;\n                assert(current > matchIndex3);\n                assert(mnum==0);  /* no prior solution */\n                matches[0].off = (current - matchIndex3) + ZSTD_REP_MOVE;\n                matches[0].len = (U32)mlen;\n                mnum = 1;\n                if ( (mlen > sufficient_len) |\n                     (ip+mlen == iLimit) ) {  /* best possible length */\n                    ms->nextToUpdate = current+1;  /* skip insertion */\n                    return 1;\n        }   }   }\n        /* no dictMatchState lookup: dicts don't have a populated HC3 table */\n    }\n\n    hashTable[h] = current;   /* Update Hash Table */\n\n    while (nbCompares-- && (matchIndex >= matchLow)) {\n        U32* const nextPtr = bt + 2*(matchIndex & btMask);\n        const BYTE* match;\n        size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */\n        assert(current > matchIndex);\n\n        if ((dictMode == ZSTD_noDict) || (dictMode == ZSTD_dictMatchState) || (matchIndex+matchLength >= dictLimit)) {\n            assert(matchIndex+matchLength >= dictLimit);  /* ensure the condition is correct when !extDict */\n            match = base + matchIndex;\n            if (matchIndex >= dictLimit) assert(memcmp(match, ip, matchLength) == 0);  /* ensure early section of match is equal as expected */\n            matchLength += ZSTD_count(ip+matchLength, match+matchLength, iLimit);\n        } else {\n            match = dictBase + matchIndex;\n            assert(memcmp(match, ip, matchLength) == 0);  /* ensure early section of match is equal as expected */\n            matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);\n            if (matchIndex+matchLength >= dictLimit)\n                match = base + matchIndex;   /* prepare for match[matchLength] read */\n        }\n\n        if (matchLength > bestLength) {\n            DEBUGLOG(8, \"found match of length %u at distance %u (offCode=%u)\",\n                    (U32)matchLength, current - matchIndex, current - matchIndex + ZSTD_REP_MOVE);\n            assert(matchEndIdx > matchIndex);\n            if (matchLength > matchEndIdx - matchIndex)\n                matchEndIdx = matchIndex + (U32)matchLength;\n            bestLength = matchLength;\n            matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE;\n            matches[mnum].len = (U32)matchLength;\n            mnum++;\n            if ( (matchLength > ZSTD_OPT_NUM)\n               | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {\n                if (dictMode == ZSTD_dictMatchState) nbCompares = 0; /* break should also skip searching dms */\n                break; /* drop, to preserve bt consistency (miss a little bit of compression) */\n            }\n        }\n\n        if (match[matchLength] < ip[matchLength]) {\n            /* match smaller than current */\n            *smallerPtr = matchIndex;             /* update smaller idx */\n            commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */\n            if (matchIndex <= btLow) { smallerPtr=&dummy32; break; }   /* beyond tree size, stop the search */\n            smallerPtr = nextPtr+1;               /* new candidate => larger than match, which was smaller than current */\n            matchIndex = nextPtr[1];              /* new matchIndex, larger than previous, closer to current */\n        } else {\n            *largerPtr = matchIndex;\n            commonLengthLarger = matchLength;\n            if (matchIndex <= btLow) { largerPtr=&dummy32; break; }   /* beyond tree size, stop the search */\n            largerPtr = nextPtr;\n            matchIndex = nextPtr[0];\n    }   }\n\n    *smallerPtr = *largerPtr = 0;\n\n    if (dictMode == ZSTD_dictMatchState && nbCompares) {\n        size_t const dmsH = ZSTD_hashPtr(ip, dmsHashLog, mls);\n        U32 dictMatchIndex = dms->hashTable[dmsH];\n        const U32* const dmsBt = dms->chainTable;\n        commonLengthSmaller = commonLengthLarger = 0;\n        while (nbCompares-- && (dictMatchIndex > dmsLowLimit)) {\n            const U32* const nextPtr = dmsBt + 2*(dictMatchIndex & dmsBtMask);\n            size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger);   /* guaranteed minimum nb of common bytes */\n            const BYTE* match = dmsBase + dictMatchIndex;\n            matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dmsEnd, prefixStart);\n            if (dictMatchIndex+matchLength >= dmsHighLimit)\n                match = base + dictMatchIndex + dmsIndexDelta;   /* to prepare for next usage of match[matchLength] */\n\n            if (matchLength > bestLength) {\n                matchIndex = dictMatchIndex + dmsIndexDelta;\n                DEBUGLOG(8, \"found dms match of length %u at distance %u (offCode=%u)\",\n                        (U32)matchLength, current - matchIndex, current - matchIndex + ZSTD_REP_MOVE);\n                if (matchLength > matchEndIdx - matchIndex)\n                    matchEndIdx = matchIndex + (U32)matchLength;\n                bestLength = matchLength;\n                matches[mnum].off = (current - matchIndex) + ZSTD_REP_MOVE;\n                matches[mnum].len = (U32)matchLength;\n                mnum++;\n                if ( (matchLength > ZSTD_OPT_NUM)\n                   | (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */) {\n                    break;   /* drop, to guarantee consistency (miss a little bit of compression) */\n                }\n            }\n\n            if (dictMatchIndex <= dmsBtLow) { break; }   /* beyond tree size, stop the search */\n            if (match[matchLength] < ip[matchLength]) {\n                commonLengthSmaller = matchLength;    /* all smaller will now have at least this guaranteed common length */\n                dictMatchIndex = nextPtr[1];              /* new matchIndex larger than previous (closer to current) */\n            } else {\n                /* match is larger than current */\n                commonLengthLarger = matchLength;\n                dictMatchIndex = nextPtr[0];\n            }\n        }\n    }\n\n    assert(matchEndIdx > current+8);\n    ms->nextToUpdate = matchEndIdx - 8;  /* skip repetitive patterns */\n    return mnum;\n}\n\n\nFORCE_INLINE_TEMPLATE U32 ZSTD_BtGetAllMatches (\n                        ZSTD_match_t* matches,   /* store result (match found, increasing size) in this table */\n                        ZSTD_matchState_t* ms,\n                        U32* nextToUpdate3,\n                        const BYTE* ip, const BYTE* const iHighLimit, const ZSTD_dictMode_e dictMode,\n                        const U32 rep[ZSTD_REP_NUM],\n                        U32 const ll0,\n                        U32 const lengthToBeat)\n{\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n    U32 const matchLengthSearch = cParams->minMatch;\n    DEBUGLOG(8, \"ZSTD_BtGetAllMatches\");\n    if (ip < ms->window.base + ms->nextToUpdate) return 0;   /* skipped area */\n    ZSTD_updateTree_internal(ms, ip, iHighLimit, matchLengthSearch, dictMode);\n    switch(matchLengthSearch)\n    {\n    case 3 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 3);\n    default :\n    case 4 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 4);\n    case 5 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 5);\n    case 7 :\n    case 6 : return ZSTD_insertBtAndGetAllMatches(matches, ms, nextToUpdate3, ip, iHighLimit, dictMode, rep, ll0, lengthToBeat, 6);\n    }\n}\n\n\n/*-*******************************\n*  Optimal parser\n*********************************/\ntypedef struct repcodes_s {\n    U32 rep[3];\n} repcodes_t;\n\nstatic repcodes_t ZSTD_updateRep(U32 const rep[3], U32 const offset, U32 const ll0)\n{\n    repcodes_t newReps;\n    if (offset >= ZSTD_REP_NUM) {  /* full offset */\n        newReps.rep[2] = rep[1];\n        newReps.rep[1] = rep[0];\n        newReps.rep[0] = offset - ZSTD_REP_MOVE;\n    } else {   /* repcode */\n        U32 const repCode = offset + ll0;\n        if (repCode > 0) {  /* note : if repCode==0, no change */\n            U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];\n            newReps.rep[2] = (repCode >= 2) ? rep[1] : rep[2];\n            newReps.rep[1] = rep[0];\n            newReps.rep[0] = currentOffset;\n        } else {   /* repCode == 0 */\n            memcpy(&newReps, rep, sizeof(newReps));\n        }\n    }\n    return newReps;\n}\n\n\nstatic U32 ZSTD_totalLen(ZSTD_optimal_t sol)\n{\n    return sol.litlen + sol.mlen;\n}\n\n#if 0 /* debug */\n\nstatic void\nlistStats(const U32* table, int lastEltID)\n{\n    int const nbElts = lastEltID + 1;\n    int enb;\n    for (enb=0; enb < nbElts; enb++) {\n        (void)table;\n        //RAWLOG(2, \"%3i:%3i,  \", enb, table[enb]);\n        RAWLOG(2, \"%4i,\", table[enb]);\n    }\n    RAWLOG(2, \" \\n\");\n}\n\n#endif\n\nFORCE_INLINE_TEMPLATE size_t\nZSTD_compressBlock_opt_generic(ZSTD_matchState_t* ms,\n                               seqStore_t* seqStore,\n                               U32 rep[ZSTD_REP_NUM],\n                         const void* src, size_t srcSize,\n                         const int optLevel,\n                         const ZSTD_dictMode_e dictMode)\n{\n    optState_t* const optStatePtr = &ms->opt;\n    const BYTE* const istart = (const BYTE*)src;\n    const BYTE* ip = istart;\n    const BYTE* anchor = istart;\n    const BYTE* const iend = istart + srcSize;\n    const BYTE* const ilimit = iend - 8;\n    const BYTE* const base = ms->window.base;\n    const BYTE* const prefixStart = base + ms->window.dictLimit;\n    const ZSTD_compressionParameters* const cParams = &ms->cParams;\n\n    U32 const sufficient_len = MIN(cParams->targetLength, ZSTD_OPT_NUM -1);\n    U32 const minMatch = (cParams->minMatch == 3) ? 3 : 4;\n    U32 nextToUpdate3 = ms->nextToUpdate;\n\n    ZSTD_optimal_t* const opt = optStatePtr->priceTable;\n    ZSTD_match_t* const matches = optStatePtr->matchTable;\n    ZSTD_optimal_t lastSequence;\n\n    /* init */\n    DEBUGLOG(5, \"ZSTD_compressBlock_opt_generic: current=%u, prefix=%u, nextToUpdate=%u\",\n                (U32)(ip - base), ms->window.dictLimit, ms->nextToUpdate);\n    assert(optLevel <= 2);\n    ZSTD_rescaleFreqs(optStatePtr, (const BYTE*)src, srcSize, optLevel);\n    ip += (ip==prefixStart);\n\n    /* Match Loop */\n    while (ip < ilimit) {\n        U32 cur, last_pos = 0;\n\n        /* find first match */\n        {   U32 const litlen = (U32)(ip - anchor);\n            U32 const ll0 = !litlen;\n            U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, ip, iend, dictMode, rep, ll0, minMatch);\n            if (!nbMatches) { ip++; continue; }\n\n            /* initialize opt[0] */\n            { U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }\n            opt[0].mlen = 0;  /* means is_a_literal */\n            opt[0].litlen = litlen;\n            opt[0].price = ZSTD_literalsContribution(anchor, litlen, optStatePtr, optLevel);\n\n            /* large match -> immediate encoding */\n            {   U32 const maxML = matches[nbMatches-1].len;\n                U32 const maxOffset = matches[nbMatches-1].off;\n                DEBUGLOG(6, \"found %u matches of maxLength=%u and maxOffCode=%u at cPos=%u => start new series\",\n                            nbMatches, maxML, maxOffset, (U32)(ip-prefixStart));\n\n                if (maxML > sufficient_len) {\n                    lastSequence.litlen = litlen;\n                    lastSequence.mlen = maxML;\n                    lastSequence.off = maxOffset;\n                    DEBUGLOG(6, \"large match (%u>%u), immediate encoding\",\n                                maxML, sufficient_len);\n                    cur = 0;\n                    last_pos = ZSTD_totalLen(lastSequence);\n                    goto _shortestPath;\n            }   }\n\n            /* set prices for first matches starting position == 0 */\n            {   U32 const literalsPrice = opt[0].price + ZSTD_litLengthPrice(0, optStatePtr, optLevel);\n                U32 pos;\n                U32 matchNb;\n                for (pos = 1; pos < minMatch; pos++) {\n                    opt[pos].price = ZSTD_MAX_PRICE;   /* mlen, litlen and price will be fixed during forward scanning */\n                }\n                for (matchNb = 0; matchNb < nbMatches; matchNb++) {\n                    U32 const offset = matches[matchNb].off;\n                    U32 const end = matches[matchNb].len;\n                    repcodes_t const repHistory = ZSTD_updateRep(rep, offset, ll0);\n                    for ( ; pos <= end ; pos++ ) {\n                        U32 const matchPrice = ZSTD_getMatchPrice(offset, pos, optStatePtr, optLevel);\n                        U32 const sequencePrice = literalsPrice + matchPrice;\n                        DEBUGLOG(7, \"rPos:%u => set initial price : %.2f\",\n                                    pos, ZSTD_fCost(sequencePrice));\n                        opt[pos].mlen = pos;\n                        opt[pos].off = offset;\n                        opt[pos].litlen = litlen;\n                        opt[pos].price = sequencePrice;\n                        ZSTD_STATIC_ASSERT(sizeof(opt[pos].rep) == sizeof(repHistory));\n                        memcpy(opt[pos].rep, &repHistory, sizeof(repHistory));\n                }   }\n                last_pos = pos-1;\n            }\n        }\n\n        /* check further positions */\n        for (cur = 1; cur <= last_pos; cur++) {\n            const BYTE* const inr = ip + cur;\n            assert(cur < ZSTD_OPT_NUM);\n            DEBUGLOG(7, \"cPos:%zi==rPos:%u\", inr-istart, cur)\n\n            /* Fix current position with one literal if cheaper */\n            {   U32 const litlen = (opt[cur-1].mlen == 0) ? opt[cur-1].litlen + 1 : 1;\n                int const price = opt[cur-1].price\n                                + ZSTD_rawLiteralsCost(ip+cur-1, 1, optStatePtr, optLevel)\n                                + ZSTD_litLengthPrice(litlen, optStatePtr, optLevel)\n                                - ZSTD_litLengthPrice(litlen-1, optStatePtr, optLevel);\n                assert(price < 1000000000); /* overflow check */\n                if (price <= opt[cur].price) {\n                    DEBUGLOG(7, \"cPos:%zi==rPos:%u : better price (%.2f<=%.2f) using literal (ll==%u) (hist:%u,%u,%u)\",\n                                inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price), litlen,\n                                opt[cur-1].rep[0], opt[cur-1].rep[1], opt[cur-1].rep[2]);\n                    opt[cur].mlen = 0;\n                    opt[cur].off = 0;\n                    opt[cur].litlen = litlen;\n                    opt[cur].price = price;\n                    memcpy(opt[cur].rep, opt[cur-1].rep, sizeof(opt[cur].rep));\n                } else {\n                    DEBUGLOG(7, \"cPos:%zi==rPos:%u : literal would cost more (%.2f>%.2f) (hist:%u,%u,%u)\",\n                                inr-istart, cur, ZSTD_fCost(price), ZSTD_fCost(opt[cur].price),\n                                opt[cur].rep[0], opt[cur].rep[1], opt[cur].rep[2]);\n                }\n            }\n\n            /* last match must start at a minimum distance of 8 from oend */\n            if (inr > ilimit) continue;\n\n            if (cur == last_pos) break;\n\n            if ( (optLevel==0) /*static_test*/\n              && (opt[cur+1].price <= opt[cur].price + (BITCOST_MULTIPLIER/2)) ) {\n                DEBUGLOG(7, \"move to next rPos:%u : price is <=\", cur+1);\n                continue;  /* skip unpromising positions; about ~+6% speed, -0.01 ratio */\n            }\n\n            {   U32 const ll0 = (opt[cur].mlen != 0);\n                U32 const litlen = (opt[cur].mlen == 0) ? opt[cur].litlen : 0;\n                U32 const previousPrice = opt[cur].price;\n                U32 const basePrice = previousPrice + ZSTD_litLengthPrice(0, optStatePtr, optLevel);\n                U32 const nbMatches = ZSTD_BtGetAllMatches(matches, ms, &nextToUpdate3, inr, iend, dictMode, opt[cur].rep, ll0, minMatch);\n                U32 matchNb;\n                if (!nbMatches) {\n                    DEBUGLOG(7, \"rPos:%u : no match found\", cur);\n                    continue;\n                }\n\n                {   U32 const maxML = matches[nbMatches-1].len;\n                    DEBUGLOG(7, \"cPos:%zi==rPos:%u, found %u matches, of maxLength=%u\",\n                                inr-istart, cur, nbMatches, maxML);\n\n                    if ( (maxML > sufficient_len)\n                      || (cur + maxML >= ZSTD_OPT_NUM) ) {\n                        lastSequence.mlen = maxML;\n                        lastSequence.off = matches[nbMatches-1].off;\n                        lastSequence.litlen = litlen;\n                        cur -= (opt[cur].mlen==0) ? opt[cur].litlen : 0;  /* last sequence is actually only literals, fix cur to last match - note : may underflow, in which case, it's first sequence, and it's okay */\n                        last_pos = cur + ZSTD_totalLen(lastSequence);\n                        if (cur > ZSTD_OPT_NUM) cur = 0;   /* underflow => first match */\n                        goto _shortestPath;\n                }   }\n\n                /* set prices using matches found at position == cur */\n                for (matchNb = 0; matchNb < nbMatches; matchNb++) {\n                    U32 const offset = matches[matchNb].off;\n                    repcodes_t const repHistory = ZSTD_updateRep(opt[cur].rep, offset, ll0);\n                    U32 const lastML = matches[matchNb].len;\n                    U32 const startML = (matchNb>0) ? matches[matchNb-1].len+1 : minMatch;\n                    U32 mlen;\n\n                    DEBUGLOG(7, \"testing match %u => offCode=%4u, mlen=%2u, llen=%2u\",\n                                matchNb, matches[matchNb].off, lastML, litlen);\n\n                    for (mlen = lastML; mlen >= startML; mlen--) {  /* scan downward */\n                        U32 const pos = cur + mlen;\n                        int const price = basePrice + ZSTD_getMatchPrice(offset, mlen, optStatePtr, optLevel);\n\n                        if ((pos > last_pos) || (price < opt[pos].price)) {\n                            DEBUGLOG(7, \"rPos:%u (ml=%2u) => new better price (%.2f<%.2f)\",\n                                        pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));\n                            while (last_pos < pos) { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; }   /* fill empty positions */\n                            opt[pos].mlen = mlen;\n                            opt[pos].off = offset;\n                            opt[pos].litlen = litlen;\n                            opt[pos].price = price;\n                            ZSTD_STATIC_ASSERT(sizeof(opt[pos].rep) == sizeof(repHistory));\n                            memcpy(opt[pos].rep, &repHistory, sizeof(repHistory));\n                        } else {\n                            DEBUGLOG(7, \"rPos:%u (ml=%2u) => new price is worse (%.2f>=%.2f)\",\n                                        pos, mlen, ZSTD_fCost(price), ZSTD_fCost(opt[pos].price));\n                            if (optLevel==0) break;  /* early update abort; gets ~+10% speed for about -0.01 ratio loss */\n                        }\n            }   }   }\n        }  /* for (cur = 1; cur <= last_pos; cur++) */\n\n        lastSequence = opt[last_pos];\n        cur = last_pos > ZSTD_totalLen(lastSequence) ? last_pos - ZSTD_totalLen(lastSequence) : 0;  /* single sequence, and it starts before `ip` */\n        assert(cur < ZSTD_OPT_NUM);  /* control overflow*/\n\n_shortestPath:   /* cur, last_pos, best_mlen, best_off have to be set */\n        assert(opt[0].mlen == 0);\n\n        {   U32 const storeEnd = cur + 1;\n            U32 storeStart = storeEnd;\n            U32 seqPos = cur;\n\n            DEBUGLOG(6, \"start reverse traversal (last_pos:%u, cur:%u)\",\n                        last_pos, cur); (void)last_pos;\n            assert(storeEnd < ZSTD_OPT_NUM);\n            DEBUGLOG(6, \"last sequence copied into pos=%u (llen=%u,mlen=%u,ofc=%u)\",\n                        storeEnd, lastSequence.litlen, lastSequence.mlen, lastSequence.off);\n            opt[storeEnd] = lastSequence;\n            while (seqPos > 0) {\n                U32 const backDist = ZSTD_totalLen(opt[seqPos]);\n                storeStart--;\n                DEBUGLOG(6, \"sequence from rPos=%u copied into pos=%u (llen=%u,mlen=%u,ofc=%u)\",\n                            seqPos, storeStart, opt[seqPos].litlen, opt[seqPos].mlen, opt[seqPos].off);\n                opt[storeStart] = opt[seqPos];\n                seqPos = (seqPos > backDist) ? seqPos - backDist : 0;\n            }\n\n            /* save sequences */\n            DEBUGLOG(6, \"sending selected sequences into seqStore\")\n            {   U32 storePos;\n                for (storePos=storeStart; storePos <= storeEnd; storePos++) {\n                    U32 const llen = opt[storePos].litlen;\n                    U32 const mlen = opt[storePos].mlen;\n                    U32 const offCode = opt[storePos].off;\n                    U32 const advance = llen + mlen;\n                    DEBUGLOG(6, \"considering seq starting at %zi, llen=%u, mlen=%u\",\n                                anchor - istart, (unsigned)llen, (unsigned)mlen);\n\n                    if (mlen==0) {  /* only literals => must be last \"sequence\", actually starting a new stream of sequences */\n                        assert(storePos == storeEnd);   /* must be last sequence */\n                        ip = anchor + llen;     /* last \"sequence\" is a bunch of literals => don't progress anchor */\n                        continue;   /* will finish */\n                    }\n\n                    /* repcodes update : like ZSTD_updateRep(), but update in place */\n                    if (offCode >= ZSTD_REP_NUM) {  /* full offset */\n                        rep[2] = rep[1];\n                        rep[1] = rep[0];\n                        rep[0] = offCode - ZSTD_REP_MOVE;\n                    } else {   /* repcode */\n                        U32 const repCode = offCode + (llen==0);\n                        if (repCode) {  /* note : if repCode==0, no change */\n                            U32 const currentOffset = (repCode==ZSTD_REP_NUM) ? (rep[0] - 1) : rep[repCode];\n                            if (repCode >= 2) rep[2] = rep[1];\n                            rep[1] = rep[0];\n                            rep[0] = currentOffset;\n                    }   }\n\n                    assert(anchor + llen <= iend);\n                    ZSTD_updateStats(optStatePtr, llen, anchor, offCode, mlen);\n                    ZSTD_storeSeq(seqStore, llen, anchor, iend, offCode, mlen-MINMATCH);\n                    anchor += advance;\n                    ip = anchor;\n            }   }\n            ZSTD_setBasePrices(optStatePtr, optLevel);\n        }\n\n    }   /* while (ip < ilimit) */\n\n    /* Return the last literals size */\n    return (size_t)(iend - anchor);\n}\n\n\nsize_t ZSTD_compressBlock_btopt(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        const void* src, size_t srcSize)\n{\n    DEBUGLOG(5, \"ZSTD_compressBlock_btopt\");\n    return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_noDict);\n}\n\n\n/* used in 2-pass strategy */\nstatic U32 ZSTD_upscaleStat(unsigned* table, U32 lastEltIndex, int bonus)\n{\n    U32 s, sum=0;\n    assert(ZSTD_FREQ_DIV+bonus >= 0);\n    for (s=0; s<lastEltIndex+1; s++) {\n        table[s] <<= ZSTD_FREQ_DIV+bonus;\n        table[s]--;\n        sum += table[s];\n    }\n    return sum;\n}\n\n/* used in 2-pass strategy */\nMEM_STATIC void ZSTD_upscaleStats(optState_t* optPtr)\n{\n    if (ZSTD_compressedLiterals(optPtr))\n        optPtr->litSum = ZSTD_upscaleStat(optPtr->litFreq, MaxLit, 0);\n    optPtr->litLengthSum = ZSTD_upscaleStat(optPtr->litLengthFreq, MaxLL, 0);\n    optPtr->matchLengthSum = ZSTD_upscaleStat(optPtr->matchLengthFreq, MaxML, 0);\n    optPtr->offCodeSum = ZSTD_upscaleStat(optPtr->offCodeFreq, MaxOff, 0);\n}\n\n/* ZSTD_initStats_ultra():\n * make a first compression pass, just to seed stats with more accurate starting values.\n * only works on first block, with no dictionary and no ldm.\n * this function cannot error, hence its contract must be respected.\n */\nstatic void\nZSTD_initStats_ultra(ZSTD_matchState_t* ms,\n                     seqStore_t* seqStore,\n                     U32 rep[ZSTD_REP_NUM],\n               const void* src, size_t srcSize)\n{\n    U32 tmpRep[ZSTD_REP_NUM];  /* updated rep codes will sink here */\n    memcpy(tmpRep, rep, sizeof(tmpRep));\n\n    DEBUGLOG(4, \"ZSTD_initStats_ultra (srcSize=%zu)\", srcSize);\n    assert(ms->opt.litLengthSum == 0);    /* first block */\n    assert(seqStore->sequences == seqStore->sequencesStart);   /* no ldm */\n    assert(ms->window.dictLimit == ms->window.lowLimit);   /* no dictionary */\n    assert(ms->window.dictLimit - ms->nextToUpdate <= 1);  /* no prefix (note: intentional overflow, defined as 2-complement) */\n\n    ZSTD_compressBlock_opt_generic(ms, seqStore, tmpRep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict);   /* generate stats into ms->opt*/\n\n    /* invalidate first scan from history */\n    ZSTD_resetSeqStore(seqStore);\n    ms->window.base -= srcSize;\n    ms->window.dictLimit += (U32)srcSize;\n    ms->window.lowLimit = ms->window.dictLimit;\n    ms->nextToUpdate = ms->window.dictLimit;\n\n    /* re-inforce weight of collected statistics */\n    ZSTD_upscaleStats(&ms->opt);\n}\n\nsize_t ZSTD_compressBlock_btultra(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        const void* src, size_t srcSize)\n{\n    DEBUGLOG(5, \"ZSTD_compressBlock_btultra (srcSize=%zu)\", srcSize);\n    return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict);\n}\n\nsize_t ZSTD_compressBlock_btultra2(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        const void* src, size_t srcSize)\n{\n    U32 const current = (U32)((const BYTE*)src - ms->window.base);\n    DEBUGLOG(5, \"ZSTD_compressBlock_btultra2 (srcSize=%zu)\", srcSize);\n\n    /* 2-pass strategy:\n     * this strategy makes a first pass over first block to collect statistics\n     * and seed next round's statistics with it.\n     * After 1st pass, function forgets everything, and starts a new block.\n     * Consequently, this can only work if no data has been previously loaded in tables,\n     * aka, no dictionary, no prefix, no ldm preprocessing.\n     * The compression ratio gain is generally small (~0.5% on first block),\n     * the cost is 2x cpu time on first block. */\n    assert(srcSize <= ZSTD_BLOCKSIZE_MAX);\n    if ( (ms->opt.litLengthSum==0)   /* first block */\n      && (seqStore->sequences == seqStore->sequencesStart)  /* no ldm */\n      && (ms->window.dictLimit == ms->window.lowLimit)   /* no dictionary */\n      && (current == ms->window.dictLimit)   /* start of frame, nothing already loaded nor skipped */\n      && (srcSize > ZSTD_PREDEF_THRESHOLD)\n      ) {\n        ZSTD_initStats_ultra(ms, seqStore, rep, src, srcSize);\n    }\n\n    return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_noDict);\n}\n\nsize_t ZSTD_compressBlock_btopt_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        const void* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_dictMatchState);\n}\n\nsize_t ZSTD_compressBlock_btultra_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        const void* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_dictMatchState);\n}\n\nsize_t ZSTD_compressBlock_btopt_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        const void* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 0 /*optLevel*/, ZSTD_extDict);\n}\n\nsize_t ZSTD_compressBlock_btultra_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        const void* src, size_t srcSize)\n{\n    return ZSTD_compressBlock_opt_generic(ms, seqStore, rep, src, srcSize, 2 /*optLevel*/, ZSTD_extDict);\n}\n\n/* note : no btultra2 variant for extDict nor dictMatchState,\n * because btultra2 is not meant to work with dictionaries\n * and is only specific for the first block (no prefix) */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstd_opt.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n#ifndef ZSTD_OPT_H\n#define ZSTD_OPT_H\n\n#if defined (__cplusplus)\nextern \"C\" {\n#endif\n\n#include \"zstd_compress_internal.h\"\n\n/* used in ZSTD_loadDictionaryContent() */\nvoid ZSTD_updateTree(ZSTD_matchState_t* ms, const BYTE* ip, const BYTE* iend);\n\nsize_t ZSTD_compressBlock_btopt(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_btultra(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_btultra2(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\n\n\nsize_t ZSTD_compressBlock_btopt_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_btultra_dictMatchState(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\n\nsize_t ZSTD_compressBlock_btopt_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\nsize_t ZSTD_compressBlock_btultra_extDict(\n        ZSTD_matchState_t* ms, seqStore_t* seqStore, U32 rep[ZSTD_REP_NUM],\n        void const* src, size_t srcSize);\n\n        /* note : no btultra2 variant for extDict nor dictMatchState,\n         * because btultra2 is not meant to work with dictionaries\n         * and is only specific for the first block (no prefix) */\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif /* ZSTD_OPT_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstdmt_compress.c",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n\n/* ======   Compiler specifics   ====== */\n#if defined(_MSC_VER)\n#  pragma warning(disable : 4204)   /* disable: C4204: non-constant aggregate initializer */\n#endif\n\n\n/* ======   Constants   ====== */\n#define ZSTDMT_OVERLAPLOG_DEFAULT 0\n\n\n/* ======   Dependencies   ====== */\n#include <string.h>      /* memcpy, memset */\n#include <limits.h>      /* INT_MAX, UINT_MAX */\n#include \"mem.h\"         /* MEM_STATIC */\n#include \"pool.h\"        /* threadpool */\n#include \"threading.h\"   /* mutex */\n#include \"zstd_compress_internal.h\"  /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */\n#include \"zstd_ldm.h\"\n#include \"zstdmt_compress.h\"\n\n/* Guards code to support resizing the SeqPool.\n * We will want to resize the SeqPool to save memory in the future.\n * Until then, comment the code out since it is unused.\n */\n#define ZSTD_RESIZE_SEQPOOL 0\n\n/* ======   Debug   ====== */\n#if defined(DEBUGLEVEL) && (DEBUGLEVEL>=2) \\\n    && !defined(_MSC_VER) \\\n    && !defined(__MINGW32__)\n\n#  include <stdio.h>\n#  include <unistd.h>\n#  include <sys/times.h>\n\n#  define DEBUG_PRINTHEX(l,p,n) {            \\\n    unsigned debug_u;                        \\\n    for (debug_u=0; debug_u<(n); debug_u++)  \\\n        RAWLOG(l, \"%02X \", ((const unsigned char*)(p))[debug_u]); \\\n    RAWLOG(l, \" \\n\");                        \\\n}\n\nstatic unsigned long long GetCurrentClockTimeMicroseconds(void)\n{\n   static clock_t _ticksPerSecond = 0;\n   if (_ticksPerSecond <= 0) _ticksPerSecond = sysconf(_SC_CLK_TCK);\n\n   {   struct tms junk; clock_t newTicks = (clock_t) times(&junk);\n       return ((((unsigned long long)newTicks)*(1000000))/_ticksPerSecond);\n}  }\n\n#define MUTEX_WAIT_TIME_DLEVEL 6\n#define ZSTD_PTHREAD_MUTEX_LOCK(mutex) {          \\\n    if (DEBUGLEVEL >= MUTEX_WAIT_TIME_DLEVEL) {   \\\n        unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \\\n        ZSTD_pthread_mutex_lock(mutex);           \\\n        {   unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \\\n            unsigned long long const elapsedTime = (afterTime-beforeTime); \\\n            if (elapsedTime > 1000) {  /* or whatever threshold you like; I'm using 1 millisecond here */ \\\n                DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, \"Thread took %llu microseconds to acquire mutex %s \\n\", \\\n                   elapsedTime, #mutex);          \\\n        }   }                                     \\\n    } else {                                      \\\n        ZSTD_pthread_mutex_lock(mutex);           \\\n    }                                             \\\n}\n\n#else\n\n#  define ZSTD_PTHREAD_MUTEX_LOCK(m) ZSTD_pthread_mutex_lock(m)\n#  define DEBUG_PRINTHEX(l,p,n) {}\n\n#endif\n\n\n/* =====   Buffer Pool   ===== */\n/* a single Buffer Pool can be invoked from multiple threads in parallel */\n\ntypedef struct buffer_s {\n    void* start;\n    size_t capacity;\n} buffer_t;\n\nstatic const buffer_t g_nullBuffer = { NULL, 0 };\n\ntypedef struct ZSTDMT_bufferPool_s {\n    ZSTD_pthread_mutex_t poolMutex;\n    size_t bufferSize;\n    unsigned totalBuffers;\n    unsigned nbBuffers;\n    ZSTD_customMem cMem;\n    buffer_t bTable[1];   /* variable size */\n} ZSTDMT_bufferPool;\n\nstatic ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbWorkers, ZSTD_customMem cMem)\n{\n    unsigned const maxNbBuffers = 2*nbWorkers + 3;\n    ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)ZSTD_calloc(\n        sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t), cMem);\n    if (bufPool==NULL) return NULL;\n    if (ZSTD_pthread_mutex_init(&bufPool->poolMutex, NULL)) {\n        ZSTD_free(bufPool, cMem);\n        return NULL;\n    }\n    bufPool->bufferSize = 64 KB;\n    bufPool->totalBuffers = maxNbBuffers;\n    bufPool->nbBuffers = 0;\n    bufPool->cMem = cMem;\n    return bufPool;\n}\n\nstatic void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)\n{\n    unsigned u;\n    DEBUGLOG(3, \"ZSTDMT_freeBufferPool (address:%08X)\", (U32)(size_t)bufPool);\n    if (!bufPool) return;   /* compatibility with free on NULL */\n    for (u=0; u<bufPool->totalBuffers; u++) {\n        DEBUGLOG(4, \"free buffer %2u (address:%08X)\", u, (U32)(size_t)bufPool->bTable[u].start);\n        ZSTD_free(bufPool->bTable[u].start, bufPool->cMem);\n    }\n    ZSTD_pthread_mutex_destroy(&bufPool->poolMutex);\n    ZSTD_free(bufPool, bufPool->cMem);\n}\n\n/* only works at initialization, not during compression */\nstatic size_t ZSTDMT_sizeof_bufferPool(ZSTDMT_bufferPool* bufPool)\n{\n    size_t const poolSize = sizeof(*bufPool)\n                          + (bufPool->totalBuffers - 1) * sizeof(buffer_t);\n    unsigned u;\n    size_t totalBufferSize = 0;\n    ZSTD_pthread_mutex_lock(&bufPool->poolMutex);\n    for (u=0; u<bufPool->totalBuffers; u++)\n        totalBufferSize += bufPool->bTable[u].capacity;\n    ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);\n\n    return poolSize + totalBufferSize;\n}\n\n/* ZSTDMT_setBufferSize() :\n * all future buffers provided by this buffer pool will have _at least_ this size\n * note : it's better for all buffers to have same size,\n * as they become freely interchangeable, reducing malloc/free usages and memory fragmentation */\nstatic void ZSTDMT_setBufferSize(ZSTDMT_bufferPool* const bufPool, size_t const bSize)\n{\n    ZSTD_pthread_mutex_lock(&bufPool->poolMutex);\n    DEBUGLOG(4, \"ZSTDMT_setBufferSize: bSize = %u\", (U32)bSize);\n    bufPool->bufferSize = bSize;\n    ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);\n}\n\n\nstatic ZSTDMT_bufferPool* ZSTDMT_expandBufferPool(ZSTDMT_bufferPool* srcBufPool, U32 nbWorkers)\n{\n    unsigned const maxNbBuffers = 2*nbWorkers + 3;\n    if (srcBufPool==NULL) return NULL;\n    if (srcBufPool->totalBuffers >= maxNbBuffers) /* good enough */\n        return srcBufPool;\n    /* need a larger buffer pool */\n    {   ZSTD_customMem const cMem = srcBufPool->cMem;\n        size_t const bSize = srcBufPool->bufferSize;   /* forward parameters */\n        ZSTDMT_bufferPool* newBufPool;\n        ZSTDMT_freeBufferPool(srcBufPool);\n        newBufPool = ZSTDMT_createBufferPool(nbWorkers, cMem);\n        if (newBufPool==NULL) return newBufPool;\n        ZSTDMT_setBufferSize(newBufPool, bSize);\n        return newBufPool;\n    }\n}\n\n/** ZSTDMT_getBuffer() :\n *  assumption : bufPool must be valid\n * @return : a buffer, with start pointer and size\n *  note: allocation may fail, in this case, start==NULL and size==0 */\nstatic buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* bufPool)\n{\n    size_t const bSize = bufPool->bufferSize;\n    DEBUGLOG(5, \"ZSTDMT_getBuffer: bSize = %u\", (U32)bufPool->bufferSize);\n    ZSTD_pthread_mutex_lock(&bufPool->poolMutex);\n    if (bufPool->nbBuffers) {   /* try to use an existing buffer */\n        buffer_t const buf = bufPool->bTable[--(bufPool->nbBuffers)];\n        size_t const availBufferSize = buf.capacity;\n        bufPool->bTable[bufPool->nbBuffers] = g_nullBuffer;\n        if ((availBufferSize >= bSize) & ((availBufferSize>>3) <= bSize)) {\n            /* large enough, but not too much */\n            DEBUGLOG(5, \"ZSTDMT_getBuffer: provide buffer %u of size %u\",\n                        bufPool->nbBuffers, (U32)buf.capacity);\n            ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);\n            return buf;\n        }\n        /* size conditions not respected : scratch this buffer, create new one */\n        DEBUGLOG(5, \"ZSTDMT_getBuffer: existing buffer does not meet size conditions => freeing\");\n        ZSTD_free(buf.start, bufPool->cMem);\n    }\n    ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);\n    /* create new buffer */\n    DEBUGLOG(5, \"ZSTDMT_getBuffer: create a new buffer\");\n    {   buffer_t buffer;\n        void* const start = ZSTD_malloc(bSize, bufPool->cMem);\n        buffer.start = start;   /* note : start can be NULL if malloc fails ! */\n        buffer.capacity = (start==NULL) ? 0 : bSize;\n        if (start==NULL) {\n            DEBUGLOG(5, \"ZSTDMT_getBuffer: buffer allocation failure !!\");\n        } else {\n            DEBUGLOG(5, \"ZSTDMT_getBuffer: created buffer of size %u\", (U32)bSize);\n        }\n        return buffer;\n    }\n}\n\n#if ZSTD_RESIZE_SEQPOOL\n/** ZSTDMT_resizeBuffer() :\n * assumption : bufPool must be valid\n * @return : a buffer that is at least the buffer pool buffer size.\n *           If a reallocation happens, the data in the input buffer is copied.\n */\nstatic buffer_t ZSTDMT_resizeBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buffer)\n{\n    size_t const bSize = bufPool->bufferSize;\n    if (buffer.capacity < bSize) {\n        void* const start = ZSTD_malloc(bSize, bufPool->cMem);\n        buffer_t newBuffer;\n        newBuffer.start = start;\n        newBuffer.capacity = start == NULL ? 0 : bSize;\n        if (start != NULL) {\n            assert(newBuffer.capacity >= buffer.capacity);\n            memcpy(newBuffer.start, buffer.start, buffer.capacity);\n            DEBUGLOG(5, \"ZSTDMT_resizeBuffer: created buffer of size %u\", (U32)bSize);\n            return newBuffer;\n        }\n        DEBUGLOG(5, \"ZSTDMT_resizeBuffer: buffer allocation failure !!\");\n    }\n    return buffer;\n}\n#endif\n\n/* store buffer for later re-use, up to pool capacity */\nstatic void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* bufPool, buffer_t buf)\n{\n    DEBUGLOG(5, \"ZSTDMT_releaseBuffer\");\n    if (buf.start == NULL) return;   /* compatible with release on NULL */\n    ZSTD_pthread_mutex_lock(&bufPool->poolMutex);\n    if (bufPool->nbBuffers < bufPool->totalBuffers) {\n        bufPool->bTable[bufPool->nbBuffers++] = buf;  /* stored for later use */\n        DEBUGLOG(5, \"ZSTDMT_releaseBuffer: stored buffer of size %u in slot %u\",\n                    (U32)buf.capacity, (U32)(bufPool->nbBuffers-1));\n        ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);\n        return;\n    }\n    ZSTD_pthread_mutex_unlock(&bufPool->poolMutex);\n    /* Reached bufferPool capacity (should not happen) */\n    DEBUGLOG(5, \"ZSTDMT_releaseBuffer: pool capacity reached => freeing \");\n    ZSTD_free(buf.start, bufPool->cMem);\n}\n\n\n/* =====   Seq Pool Wrapper   ====== */\n\nstatic rawSeqStore_t kNullRawSeqStore = {NULL, 0, 0, 0};\n\ntypedef ZSTDMT_bufferPool ZSTDMT_seqPool;\n\nstatic size_t ZSTDMT_sizeof_seqPool(ZSTDMT_seqPool* seqPool)\n{\n    return ZSTDMT_sizeof_bufferPool(seqPool);\n}\n\nstatic rawSeqStore_t bufferToSeq(buffer_t buffer)\n{\n    rawSeqStore_t seq = {NULL, 0, 0, 0};\n    seq.seq = (rawSeq*)buffer.start;\n    seq.capacity = buffer.capacity / sizeof(rawSeq);\n    return seq;\n}\n\nstatic buffer_t seqToBuffer(rawSeqStore_t seq)\n{\n    buffer_t buffer;\n    buffer.start = seq.seq;\n    buffer.capacity = seq.capacity * sizeof(rawSeq);\n    return buffer;\n}\n\nstatic rawSeqStore_t ZSTDMT_getSeq(ZSTDMT_seqPool* seqPool)\n{\n    if (seqPool->bufferSize == 0) {\n        return kNullRawSeqStore;\n    }\n    return bufferToSeq(ZSTDMT_getBuffer(seqPool));\n}\n\n#if ZSTD_RESIZE_SEQPOOL\nstatic rawSeqStore_t ZSTDMT_resizeSeq(ZSTDMT_seqPool* seqPool, rawSeqStore_t seq)\n{\n  return bufferToSeq(ZSTDMT_resizeBuffer(seqPool, seqToBuffer(seq)));\n}\n#endif\n\nstatic void ZSTDMT_releaseSeq(ZSTDMT_seqPool* seqPool, rawSeqStore_t seq)\n{\n  ZSTDMT_releaseBuffer(seqPool, seqToBuffer(seq));\n}\n\nstatic void ZSTDMT_setNbSeq(ZSTDMT_seqPool* const seqPool, size_t const nbSeq)\n{\n  ZSTDMT_setBufferSize(seqPool, nbSeq * sizeof(rawSeq));\n}\n\nstatic ZSTDMT_seqPool* ZSTDMT_createSeqPool(unsigned nbWorkers, ZSTD_customMem cMem)\n{\n    ZSTDMT_seqPool* const seqPool = ZSTDMT_createBufferPool(nbWorkers, cMem);\n    if (seqPool == NULL) return NULL;\n    ZSTDMT_setNbSeq(seqPool, 0);\n    return seqPool;\n}\n\nstatic void ZSTDMT_freeSeqPool(ZSTDMT_seqPool* seqPool)\n{\n    ZSTDMT_freeBufferPool(seqPool);\n}\n\nstatic ZSTDMT_seqPool* ZSTDMT_expandSeqPool(ZSTDMT_seqPool* pool, U32 nbWorkers)\n{\n    return ZSTDMT_expandBufferPool(pool, nbWorkers);\n}\n\n\n/* =====   CCtx Pool   ===== */\n/* a single CCtx Pool can be invoked from multiple threads in parallel */\n\ntypedef struct {\n    ZSTD_pthread_mutex_t poolMutex;\n    int totalCCtx;\n    int availCCtx;\n    ZSTD_customMem cMem;\n    ZSTD_CCtx* cctx[1];   /* variable size */\n} ZSTDMT_CCtxPool;\n\n/* note : all CCtx borrowed from the pool should be released back to the pool _before_ freeing the pool */\nstatic void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)\n{\n    int cid;\n    for (cid=0; cid<pool->totalCCtx; cid++)\n        ZSTD_freeCCtx(pool->cctx[cid]);  /* note : compatible with free on NULL */\n    ZSTD_pthread_mutex_destroy(&pool->poolMutex);\n    ZSTD_free(pool, pool->cMem);\n}\n\n/* ZSTDMT_createCCtxPool() :\n * implies nbWorkers >= 1 , checked by caller ZSTDMT_createCCtx() */\nstatic ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(int nbWorkers,\n                                              ZSTD_customMem cMem)\n{\n    ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) ZSTD_calloc(\n        sizeof(ZSTDMT_CCtxPool) + (nbWorkers-1)*sizeof(ZSTD_CCtx*), cMem);\n    assert(nbWorkers > 0);\n    if (!cctxPool) return NULL;\n    if (ZSTD_pthread_mutex_init(&cctxPool->poolMutex, NULL)) {\n        ZSTD_free(cctxPool, cMem);\n        return NULL;\n    }\n    cctxPool->cMem = cMem;\n    cctxPool->totalCCtx = nbWorkers;\n    cctxPool->availCCtx = 1;   /* at least one cctx for single-thread mode */\n    cctxPool->cctx[0] = ZSTD_createCCtx_advanced(cMem);\n    if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; }\n    DEBUGLOG(3, \"cctxPool created, with %u workers\", nbWorkers);\n    return cctxPool;\n}\n\nstatic ZSTDMT_CCtxPool* ZSTDMT_expandCCtxPool(ZSTDMT_CCtxPool* srcPool,\n                                              int nbWorkers)\n{\n    if (srcPool==NULL) return NULL;\n    if (nbWorkers <= srcPool->totalCCtx) return srcPool;   /* good enough */\n    /* need a larger cctx pool */\n    {   ZSTD_customMem const cMem = srcPool->cMem;\n        ZSTDMT_freeCCtxPool(srcPool);\n        return ZSTDMT_createCCtxPool(nbWorkers, cMem);\n    }\n}\n\n/* only works during initialization phase, not during compression */\nstatic size_t ZSTDMT_sizeof_CCtxPool(ZSTDMT_CCtxPool* cctxPool)\n{\n    ZSTD_pthread_mutex_lock(&cctxPool->poolMutex);\n    {   unsigned const nbWorkers = cctxPool->totalCCtx;\n        size_t const poolSize = sizeof(*cctxPool)\n                                + (nbWorkers-1) * sizeof(ZSTD_CCtx*);\n        unsigned u;\n        size_t totalCCtxSize = 0;\n        for (u=0; u<nbWorkers; u++) {\n            totalCCtxSize += ZSTD_sizeof_CCtx(cctxPool->cctx[u]);\n        }\n        ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex);\n        assert(nbWorkers > 0);\n        return poolSize + totalCCtxSize;\n    }\n}\n\nstatic ZSTD_CCtx* ZSTDMT_getCCtx(ZSTDMT_CCtxPool* cctxPool)\n{\n    DEBUGLOG(5, \"ZSTDMT_getCCtx\");\n    ZSTD_pthread_mutex_lock(&cctxPool->poolMutex);\n    if (cctxPool->availCCtx) {\n        cctxPool->availCCtx--;\n        {   ZSTD_CCtx* const cctx = cctxPool->cctx[cctxPool->availCCtx];\n            ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex);\n            return cctx;\n    }   }\n    ZSTD_pthread_mutex_unlock(&cctxPool->poolMutex);\n    DEBUGLOG(5, \"create one more CCtx\");\n    return ZSTD_createCCtx_advanced(cctxPool->cMem);   /* note : can be NULL, when creation fails ! */\n}\n\nstatic void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool* pool, ZSTD_CCtx* cctx)\n{\n    if (cctx==NULL) return;   /* compatibility with release on NULL */\n    ZSTD_pthread_mutex_lock(&pool->poolMutex);\n    if (pool->availCCtx < pool->totalCCtx)\n        pool->cctx[pool->availCCtx++] = cctx;\n    else {\n        /* pool overflow : should not happen, since totalCCtx==nbWorkers */\n        DEBUGLOG(4, \"CCtx pool overflow : free cctx\");\n        ZSTD_freeCCtx(cctx);\n    }\n    ZSTD_pthread_mutex_unlock(&pool->poolMutex);\n}\n\n/* ====   Serial State   ==== */\n\ntypedef struct {\n    void const* start;\n    size_t size;\n} range_t;\n\ntypedef struct {\n    /* All variables in the struct are protected by mutex. */\n    ZSTD_pthread_mutex_t mutex;\n    ZSTD_pthread_cond_t cond;\n    ZSTD_CCtx_params params;\n    ldmState_t ldmState;\n    XXH64_state_t xxhState;\n    unsigned nextJobID;\n    /* Protects ldmWindow.\n     * Must be acquired after the main mutex when acquiring both.\n     */\n    ZSTD_pthread_mutex_t ldmWindowMutex;\n    ZSTD_pthread_cond_t ldmWindowCond;  /* Signaled when ldmWindow is updated */\n    ZSTD_window_t ldmWindow;  /* A thread-safe copy of ldmState.window */\n} serialState_t;\n\nstatic int ZSTDMT_serialState_reset(serialState_t* serialState, ZSTDMT_seqPool* seqPool, ZSTD_CCtx_params params, size_t jobSize)\n{\n    /* Adjust parameters */\n    if (params.ldmParams.enableLdm) {\n        DEBUGLOG(4, \"LDM window size = %u KB\", (1U << params.cParams.windowLog) >> 10);\n        ZSTD_ldm_adjustParameters(&params.ldmParams, &params.cParams);\n        assert(params.ldmParams.hashLog >= params.ldmParams.bucketSizeLog);\n        assert(params.ldmParams.hashRateLog < 32);\n        serialState->ldmState.hashPower =\n                ZSTD_rollingHash_primePower(params.ldmParams.minMatchLength);\n    } else {\n        memset(&params.ldmParams, 0, sizeof(params.ldmParams));\n    }\n    serialState->nextJobID = 0;\n    if (params.fParams.checksumFlag)\n        XXH64_reset(&serialState->xxhState, 0);\n    if (params.ldmParams.enableLdm) {\n        ZSTD_customMem cMem = params.customMem;\n        unsigned const hashLog = params.ldmParams.hashLog;\n        size_t const hashSize = ((size_t)1 << hashLog) * sizeof(ldmEntry_t);\n        unsigned const bucketLog =\n            params.ldmParams.hashLog - params.ldmParams.bucketSizeLog;\n        size_t const bucketSize = (size_t)1 << bucketLog;\n        unsigned const prevBucketLog =\n            serialState->params.ldmParams.hashLog -\n            serialState->params.ldmParams.bucketSizeLog;\n        /* Size the seq pool tables */\n        ZSTDMT_setNbSeq(seqPool, ZSTD_ldm_getMaxNbSeq(params.ldmParams, jobSize));\n        /* Reset the window */\n        ZSTD_window_clear(&serialState->ldmState.window);\n        serialState->ldmWindow = serialState->ldmState.window;\n        /* Resize tables and output space if necessary. */\n        if (serialState->ldmState.hashTable == NULL || serialState->params.ldmParams.hashLog < hashLog) {\n            ZSTD_free(serialState->ldmState.hashTable, cMem);\n            serialState->ldmState.hashTable = (ldmEntry_t*)ZSTD_malloc(hashSize, cMem);\n        }\n        if (serialState->ldmState.bucketOffsets == NULL || prevBucketLog < bucketLog) {\n            ZSTD_free(serialState->ldmState.bucketOffsets, cMem);\n            serialState->ldmState.bucketOffsets = (BYTE*)ZSTD_malloc(bucketSize, cMem);\n        }\n        if (!serialState->ldmState.hashTable || !serialState->ldmState.bucketOffsets)\n            return 1;\n        /* Zero the tables */\n        memset(serialState->ldmState.hashTable, 0, hashSize);\n        memset(serialState->ldmState.bucketOffsets, 0, bucketSize);\n    }\n    serialState->params = params;\n    serialState->params.jobSize = (U32)jobSize;\n    return 0;\n}\n\nstatic int ZSTDMT_serialState_init(serialState_t* serialState)\n{\n    int initError = 0;\n    memset(serialState, 0, sizeof(*serialState));\n    initError |= ZSTD_pthread_mutex_init(&serialState->mutex, NULL);\n    initError |= ZSTD_pthread_cond_init(&serialState->cond, NULL);\n    initError |= ZSTD_pthread_mutex_init(&serialState->ldmWindowMutex, NULL);\n    initError |= ZSTD_pthread_cond_init(&serialState->ldmWindowCond, NULL);\n    return initError;\n}\n\nstatic void ZSTDMT_serialState_free(serialState_t* serialState)\n{\n    ZSTD_customMem cMem = serialState->params.customMem;\n    ZSTD_pthread_mutex_destroy(&serialState->mutex);\n    ZSTD_pthread_cond_destroy(&serialState->cond);\n    ZSTD_pthread_mutex_destroy(&serialState->ldmWindowMutex);\n    ZSTD_pthread_cond_destroy(&serialState->ldmWindowCond);\n    ZSTD_free(serialState->ldmState.hashTable, cMem);\n    ZSTD_free(serialState->ldmState.bucketOffsets, cMem);\n}\n\nstatic void ZSTDMT_serialState_update(serialState_t* serialState,\n                                      ZSTD_CCtx* jobCCtx, rawSeqStore_t seqStore,\n                                      range_t src, unsigned jobID)\n{\n    /* Wait for our turn */\n    ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);\n    while (serialState->nextJobID < jobID) {\n        DEBUGLOG(5, \"wait for serialState->cond\");\n        ZSTD_pthread_cond_wait(&serialState->cond, &serialState->mutex);\n    }\n    /* A future job may error and skip our job */\n    if (serialState->nextJobID == jobID) {\n        /* It is now our turn, do any processing necessary */\n        if (serialState->params.ldmParams.enableLdm) {\n            size_t error;\n            assert(seqStore.seq != NULL && seqStore.pos == 0 &&\n                   seqStore.size == 0 && seqStore.capacity > 0);\n            assert(src.size <= serialState->params.jobSize);\n            ZSTD_window_update(&serialState->ldmState.window, src.start, src.size);\n            error = ZSTD_ldm_generateSequences(\n                &serialState->ldmState, &seqStore,\n                &serialState->params.ldmParams, src.start, src.size);\n            /* We provide a large enough buffer to never fail. */\n            assert(!ZSTD_isError(error)); (void)error;\n            /* Update ldmWindow to match the ldmState.window and signal the main\n             * thread if it is waiting for a buffer.\n             */\n            ZSTD_PTHREAD_MUTEX_LOCK(&serialState->ldmWindowMutex);\n            serialState->ldmWindow = serialState->ldmState.window;\n            ZSTD_pthread_cond_signal(&serialState->ldmWindowCond);\n            ZSTD_pthread_mutex_unlock(&serialState->ldmWindowMutex);\n        }\n        if (serialState->params.fParams.checksumFlag && src.size > 0)\n            XXH64_update(&serialState->xxhState, src.start, src.size);\n    }\n    /* Now it is the next jobs turn */\n    serialState->nextJobID++;\n    ZSTD_pthread_cond_broadcast(&serialState->cond);\n    ZSTD_pthread_mutex_unlock(&serialState->mutex);\n\n    if (seqStore.size > 0) {\n        size_t const err = ZSTD_referenceExternalSequences(\n            jobCCtx, seqStore.seq, seqStore.size);\n        assert(serialState->params.ldmParams.enableLdm);\n        assert(!ZSTD_isError(err));\n        (void)err;\n    }\n}\n\nstatic void ZSTDMT_serialState_ensureFinished(serialState_t* serialState,\n                                              unsigned jobID, size_t cSize)\n{\n    ZSTD_PTHREAD_MUTEX_LOCK(&serialState->mutex);\n    if (serialState->nextJobID <= jobID) {\n        assert(ZSTD_isError(cSize)); (void)cSize;\n        DEBUGLOG(5, \"Skipping past job %u because of error\", jobID);\n        serialState->nextJobID = jobID + 1;\n        ZSTD_pthread_cond_broadcast(&serialState->cond);\n\n        ZSTD_PTHREAD_MUTEX_LOCK(&serialState->ldmWindowMutex);\n        ZSTD_window_clear(&serialState->ldmWindow);\n        ZSTD_pthread_cond_signal(&serialState->ldmWindowCond);\n        ZSTD_pthread_mutex_unlock(&serialState->ldmWindowMutex);\n    }\n    ZSTD_pthread_mutex_unlock(&serialState->mutex);\n\n}\n\n\n/* ------------------------------------------ */\n/* =====          Worker thread         ===== */\n/* ------------------------------------------ */\n\nstatic const range_t kNullRange = { NULL, 0 };\n\ntypedef struct {\n    size_t   consumed;                   /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx */\n    size_t   cSize;                      /* SHARED - set0 by mtctx, then modified by worker AND read by mtctx, then set0 by mtctx */\n    ZSTD_pthread_mutex_t job_mutex;      /* Thread-safe - used by mtctx and worker */\n    ZSTD_pthread_cond_t job_cond;        /* Thread-safe - used by mtctx and worker */\n    ZSTDMT_CCtxPool* cctxPool;           /* Thread-safe - used by mtctx and (all) workers */\n    ZSTDMT_bufferPool* bufPool;          /* Thread-safe - used by mtctx and (all) workers */\n    ZSTDMT_seqPool* seqPool;             /* Thread-safe - used by mtctx and (all) workers */\n    serialState_t* serial;               /* Thread-safe - used by mtctx and (all) workers */\n    buffer_t dstBuff;                    /* set by worker (or mtctx), then read by worker & mtctx, then modified by mtctx => no barrier */\n    range_t prefix;                      /* set by mtctx, then read by worker & mtctx => no barrier */\n    range_t src;                         /* set by mtctx, then read by worker & mtctx => no barrier */\n    unsigned jobID;                      /* set by mtctx, then read by worker => no barrier */\n    unsigned firstJob;                   /* set by mtctx, then read by worker => no barrier */\n    unsigned lastJob;                    /* set by mtctx, then read by worker => no barrier */\n    ZSTD_CCtx_params params;             /* set by mtctx, then read by worker => no barrier */\n    const ZSTD_CDict* cdict;             /* set by mtctx, then read by worker => no barrier */\n    unsigned long long fullFrameSize;    /* set by mtctx, then read by worker => no barrier */\n    size_t   dstFlushed;                 /* used only by mtctx */\n    unsigned frameChecksumNeeded;        /* used only by mtctx */\n} ZSTDMT_jobDescription;\n\n#define JOB_ERROR(e) {                          \\\n    ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex);   \\\n    job->cSize = e;                             \\\n    ZSTD_pthread_mutex_unlock(&job->job_mutex); \\\n    goto _endJob;                               \\\n}\n\n/* ZSTDMT_compressionJob() is a POOL_function type */\nstatic void ZSTDMT_compressionJob(void* jobDescription)\n{\n    ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription;\n    ZSTD_CCtx_params jobParams = job->params;   /* do not modify job->params ! copy it, modify the copy */\n    ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(job->cctxPool);\n    rawSeqStore_t rawSeqStore = ZSTDMT_getSeq(job->seqPool);\n    buffer_t dstBuff = job->dstBuff;\n    size_t lastCBlockSize = 0;\n\n    /* resources */\n    if (cctx==NULL) JOB_ERROR(ERROR(memory_allocation));\n    if (dstBuff.start == NULL) {   /* streaming job : doesn't provide a dstBuffer */\n        dstBuff = ZSTDMT_getBuffer(job->bufPool);\n        if (dstBuff.start==NULL) JOB_ERROR(ERROR(memory_allocation));\n        job->dstBuff = dstBuff;   /* this value can be read in ZSTDMT_flush, when it copies the whole job */\n    }\n    if (jobParams.ldmParams.enableLdm && rawSeqStore.seq == NULL)\n        JOB_ERROR(ERROR(memory_allocation));\n\n    /* Don't compute the checksum for chunks, since we compute it externally,\n     * but write it in the header.\n     */\n    if (job->jobID != 0) jobParams.fParams.checksumFlag = 0;\n    /* Don't run LDM for the chunks, since we handle it externally */\n    jobParams.ldmParams.enableLdm = 0;\n\n\n    /* init */\n    if (job->cdict) {\n        size_t const initError = ZSTD_compressBegin_advanced_internal(cctx, NULL, 0, ZSTD_dct_auto, ZSTD_dtlm_fast, job->cdict, &jobParams, job->fullFrameSize);\n        assert(job->firstJob);  /* only allowed for first job */\n        if (ZSTD_isError(initError)) JOB_ERROR(initError);\n    } else {  /* srcStart points at reloaded section */\n        U64 const pledgedSrcSize = job->firstJob ? job->fullFrameSize : job->src.size;\n        {   size_t const forceWindowError = ZSTD_CCtxParams_setParameter(&jobParams, ZSTD_c_forceMaxWindow, !job->firstJob);\n            if (ZSTD_isError(forceWindowError)) JOB_ERROR(forceWindowError);\n        }\n        {   size_t const initError = ZSTD_compressBegin_advanced_internal(cctx,\n                                        job->prefix.start, job->prefix.size, ZSTD_dct_rawContent, /* load dictionary in \"content-only\" mode (no header analysis) */\n                                        ZSTD_dtlm_fast,\n                                        NULL, /*cdict*/\n                                        &jobParams, pledgedSrcSize);\n            if (ZSTD_isError(initError)) JOB_ERROR(initError);\n    }   }\n\n    /* Perform serial step as early as possible, but after CCtx initialization */\n    ZSTDMT_serialState_update(job->serial, cctx, rawSeqStore, job->src, job->jobID);\n\n    if (!job->firstJob) {  /* flush and overwrite frame header when it's not first job */\n        size_t const hSize = ZSTD_compressContinue(cctx, dstBuff.start, dstBuff.capacity, job->src.start, 0);\n        if (ZSTD_isError(hSize)) JOB_ERROR(hSize);\n        DEBUGLOG(5, \"ZSTDMT_compressionJob: flush and overwrite %u bytes of frame header (not first job)\", (U32)hSize);\n        ZSTD_invalidateRepCodes(cctx);\n    }\n\n    /* compress */\n    {   size_t const chunkSize = 4*ZSTD_BLOCKSIZE_MAX;\n        int const nbChunks = (int)((job->src.size + (chunkSize-1)) / chunkSize);\n        const BYTE* ip = (const BYTE*) job->src.start;\n        BYTE* const ostart = (BYTE*)dstBuff.start;\n        BYTE* op = ostart;\n        BYTE* oend = op + dstBuff.capacity;\n        int chunkNb;\n        if (sizeof(size_t) > sizeof(int)) assert(job->src.size < ((size_t)INT_MAX) * chunkSize);   /* check overflow */\n        DEBUGLOG(5, \"ZSTDMT_compressionJob: compress %u bytes in %i blocks\", (U32)job->src.size, nbChunks);\n        assert(job->cSize == 0);\n        for (chunkNb = 1; chunkNb < nbChunks; chunkNb++) {\n            size_t const cSize = ZSTD_compressContinue(cctx, op, oend-op, ip, chunkSize);\n            if (ZSTD_isError(cSize)) JOB_ERROR(cSize);\n            ip += chunkSize;\n            op += cSize; assert(op < oend);\n            /* stats */\n            ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex);\n            job->cSize += cSize;\n            job->consumed = chunkSize * chunkNb;\n            DEBUGLOG(5, \"ZSTDMT_compressionJob: compress new block : cSize==%u bytes (total: %u)\",\n                        (U32)cSize, (U32)job->cSize);\n            ZSTD_pthread_cond_signal(&job->job_cond);   /* warns some more data is ready to be flushed */\n            ZSTD_pthread_mutex_unlock(&job->job_mutex);\n        }\n        /* last block */\n        assert(chunkSize > 0);\n        assert((chunkSize & (chunkSize - 1)) == 0);  /* chunkSize must be power of 2 for mask==(chunkSize-1) to work */\n        if ((nbChunks > 0) | job->lastJob /*must output a \"last block\" flag*/ ) {\n            size_t const lastBlockSize1 = job->src.size & (chunkSize-1);\n            size_t const lastBlockSize = ((lastBlockSize1==0) & (job->src.size>=chunkSize)) ? chunkSize : lastBlockSize1;\n            size_t const cSize = (job->lastJob) ?\n                 ZSTD_compressEnd     (cctx, op, oend-op, ip, lastBlockSize) :\n                 ZSTD_compressContinue(cctx, op, oend-op, ip, lastBlockSize);\n            if (ZSTD_isError(cSize)) JOB_ERROR(cSize);\n            lastCBlockSize = cSize;\n    }   }\n\n_endJob:\n    ZSTDMT_serialState_ensureFinished(job->serial, job->jobID, job->cSize);\n    if (job->prefix.size > 0)\n        DEBUGLOG(5, \"Finished with prefix: %zx\", (size_t)job->prefix.start);\n    DEBUGLOG(5, \"Finished with source: %zx\", (size_t)job->src.start);\n    /* release resources */\n    ZSTDMT_releaseSeq(job->seqPool, rawSeqStore);\n    ZSTDMT_releaseCCtx(job->cctxPool, cctx);\n    /* report */\n    ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex);\n    if (ZSTD_isError(job->cSize)) assert(lastCBlockSize == 0);\n    job->cSize += lastCBlockSize;\n    job->consumed = job->src.size;  /* when job->consumed == job->src.size , compression job is presumed completed */\n    ZSTD_pthread_cond_signal(&job->job_cond);\n    ZSTD_pthread_mutex_unlock(&job->job_mutex);\n}\n\n\n/* ------------------------------------------ */\n/* =====   Multi-threaded compression   ===== */\n/* ------------------------------------------ */\n\ntypedef struct {\n    range_t prefix;         /* read-only non-owned prefix buffer */\n    buffer_t buffer;\n    size_t filled;\n} inBuff_t;\n\ntypedef struct {\n  BYTE* buffer;     /* The round input buffer. All jobs get references\n                     * to pieces of the buffer. ZSTDMT_tryGetInputRange()\n                     * handles handing out job input buffers, and makes\n                     * sure it doesn't overlap with any pieces still in use.\n                     */\n  size_t capacity;  /* The capacity of buffer. */\n  size_t pos;       /* The position of the current inBuff in the round\n                     * buffer. Updated past the end if the inBuff once\n                     * the inBuff is sent to the worker thread.\n                     * pos <= capacity.\n                     */\n} roundBuff_t;\n\nstatic const roundBuff_t kNullRoundBuff = {NULL, 0, 0};\n\n#define RSYNC_LENGTH 32\n\ntypedef struct {\n  U64 hash;\n  U64 hitMask;\n  U64 primePower;\n} rsyncState_t;\n\nstruct ZSTDMT_CCtx_s {\n    POOL_ctx* factory;\n    ZSTDMT_jobDescription* jobs;\n    ZSTDMT_bufferPool* bufPool;\n    ZSTDMT_CCtxPool* cctxPool;\n    ZSTDMT_seqPool* seqPool;\n    ZSTD_CCtx_params params;\n    size_t targetSectionSize;\n    size_t targetPrefixSize;\n    int jobReady;        /* 1 => one job is already prepared, but pool has shortage of workers. Don't create a new job. */\n    inBuff_t inBuff;\n    roundBuff_t roundBuff;\n    serialState_t serial;\n    rsyncState_t rsync;\n    unsigned singleBlockingThread;\n    unsigned jobIDMask;\n    unsigned doneJobID;\n    unsigned nextJobID;\n    unsigned frameEnded;\n    unsigned allJobsCompleted;\n    unsigned long long frameContentSize;\n    unsigned long long consumed;\n    unsigned long long produced;\n    ZSTD_customMem cMem;\n    ZSTD_CDict* cdictLocal;\n    const ZSTD_CDict* cdict;\n};\n\nstatic void ZSTDMT_freeJobsTable(ZSTDMT_jobDescription* jobTable, U32 nbJobs, ZSTD_customMem cMem)\n{\n    U32 jobNb;\n    if (jobTable == NULL) return;\n    for (jobNb=0; jobNb<nbJobs; jobNb++) {\n        ZSTD_pthread_mutex_destroy(&jobTable[jobNb].job_mutex);\n        ZSTD_pthread_cond_destroy(&jobTable[jobNb].job_cond);\n    }\n    ZSTD_free(jobTable, cMem);\n}\n\n/* ZSTDMT_allocJobsTable()\n * allocate and init a job table.\n * update *nbJobsPtr to next power of 2 value, as size of table */\nstatic ZSTDMT_jobDescription* ZSTDMT_createJobsTable(U32* nbJobsPtr, ZSTD_customMem cMem)\n{\n    U32 const nbJobsLog2 = ZSTD_highbit32(*nbJobsPtr) + 1;\n    U32 const nbJobs = 1 << nbJobsLog2;\n    U32 jobNb;\n    ZSTDMT_jobDescription* const jobTable = (ZSTDMT_jobDescription*)\n                ZSTD_calloc(nbJobs * sizeof(ZSTDMT_jobDescription), cMem);\n    int initError = 0;\n    if (jobTable==NULL) return NULL;\n    *nbJobsPtr = nbJobs;\n    for (jobNb=0; jobNb<nbJobs; jobNb++) {\n        initError |= ZSTD_pthread_mutex_init(&jobTable[jobNb].job_mutex, NULL);\n        initError |= ZSTD_pthread_cond_init(&jobTable[jobNb].job_cond, NULL);\n    }\n    if (initError != 0) {\n        ZSTDMT_freeJobsTable(jobTable, nbJobs, cMem);\n        return NULL;\n    }\n    return jobTable;\n}\n\nstatic size_t ZSTDMT_expandJobsTable (ZSTDMT_CCtx* mtctx, U32 nbWorkers) {\n    U32 nbJobs = nbWorkers + 2;\n    if (nbJobs > mtctx->jobIDMask+1) {  /* need more job capacity */\n        ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem);\n        mtctx->jobIDMask = 0;\n        mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, mtctx->cMem);\n        if (mtctx->jobs==NULL) return ERROR(memory_allocation);\n        assert((nbJobs != 0) && ((nbJobs & (nbJobs - 1)) == 0));  /* ensure nbJobs is a power of 2 */\n        mtctx->jobIDMask = nbJobs - 1;\n    }\n    return 0;\n}\n\n\n/* ZSTDMT_CCtxParam_setNbWorkers():\n * Internal use only */\nsize_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers)\n{\n    return ZSTD_CCtxParams_setParameter(params, ZSTD_c_nbWorkers, (int)nbWorkers);\n}\n\nMEM_STATIC ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced_internal(unsigned nbWorkers, ZSTD_customMem cMem)\n{\n    ZSTDMT_CCtx* mtctx;\n    U32 nbJobs = nbWorkers + 2;\n    int initError;\n    DEBUGLOG(3, \"ZSTDMT_createCCtx_advanced (nbWorkers = %u)\", nbWorkers);\n\n    if (nbWorkers < 1) return NULL;\n    nbWorkers = MIN(nbWorkers , ZSTDMT_NBWORKERS_MAX);\n    if ((cMem.customAlloc!=NULL) ^ (cMem.customFree!=NULL))\n        /* invalid custom allocator */\n        return NULL;\n\n    mtctx = (ZSTDMT_CCtx*) ZSTD_calloc(sizeof(ZSTDMT_CCtx), cMem);\n    if (!mtctx) return NULL;\n    ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers);\n    mtctx->cMem = cMem;\n    mtctx->allJobsCompleted = 1;\n    mtctx->factory = POOL_create_advanced(nbWorkers, 0, cMem);\n    mtctx->jobs = ZSTDMT_createJobsTable(&nbJobs, cMem);\n    assert(nbJobs > 0); assert((nbJobs & (nbJobs - 1)) == 0);  /* ensure nbJobs is a power of 2 */\n    mtctx->jobIDMask = nbJobs - 1;\n    mtctx->bufPool = ZSTDMT_createBufferPool(nbWorkers, cMem);\n    mtctx->cctxPool = ZSTDMT_createCCtxPool(nbWorkers, cMem);\n    mtctx->seqPool = ZSTDMT_createSeqPool(nbWorkers, cMem);\n    initError = ZSTDMT_serialState_init(&mtctx->serial);\n    mtctx->roundBuff = kNullRoundBuff;\n    if (!mtctx->factory | !mtctx->jobs | !mtctx->bufPool | !mtctx->cctxPool | !mtctx->seqPool | initError) {\n        ZSTDMT_freeCCtx(mtctx);\n        return NULL;\n    }\n    DEBUGLOG(3, \"mt_cctx created, for %u threads\", nbWorkers);\n    return mtctx;\n}\n\nZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers, ZSTD_customMem cMem)\n{\n#ifdef ZSTD_MULTITHREAD\n    return ZSTDMT_createCCtx_advanced_internal(nbWorkers, cMem);\n#else\n    (void)nbWorkers;\n    (void)cMem;\n    return NULL;\n#endif\n}\n\nZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbWorkers)\n{\n    return ZSTDMT_createCCtx_advanced(nbWorkers, ZSTD_defaultCMem);\n}\n\n\n/* ZSTDMT_releaseAllJobResources() :\n * note : ensure all workers are killed first ! */\nstatic void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)\n{\n    unsigned jobID;\n    DEBUGLOG(3, \"ZSTDMT_releaseAllJobResources\");\n    for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) {\n        /* Copy the mutex/cond out */\n        ZSTD_pthread_mutex_t const mutex = mtctx->jobs[jobID].job_mutex;\n        ZSTD_pthread_cond_t const cond = mtctx->jobs[jobID].job_cond;\n\n        DEBUGLOG(4, \"job%02u: release dst address %08X\", jobID, (U32)(size_t)mtctx->jobs[jobID].dstBuff.start);\n        ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);\n\n        /* Clear the job description, but keep the mutex/cond */\n        memset(&mtctx->jobs[jobID], 0, sizeof(mtctx->jobs[jobID]));\n        mtctx->jobs[jobID].job_mutex = mutex;\n        mtctx->jobs[jobID].job_cond = cond;\n    }\n    mtctx->inBuff.buffer = g_nullBuffer;\n    mtctx->inBuff.filled = 0;\n    mtctx->allJobsCompleted = 1;\n}\n\nstatic void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* mtctx)\n{\n    DEBUGLOG(4, \"ZSTDMT_waitForAllJobsCompleted\");\n    while (mtctx->doneJobID < mtctx->nextJobID) {\n        unsigned const jobID = mtctx->doneJobID & mtctx->jobIDMask;\n        ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex);\n        while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) {\n            DEBUGLOG(4, \"waiting for jobCompleted signal from job %u\", mtctx->doneJobID);   /* we want to block when waiting for data to flush */\n            ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex);\n        }\n        ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex);\n        mtctx->doneJobID++;\n    }\n}\n\nsize_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)\n{\n    if (mtctx==NULL) return 0;   /* compatible with free on NULL */\n    POOL_free(mtctx->factory);   /* stop and free worker threads */\n    ZSTDMT_releaseAllJobResources(mtctx);  /* release job resources into pools first */\n    ZSTDMT_freeJobsTable(mtctx->jobs, mtctx->jobIDMask+1, mtctx->cMem);\n    ZSTDMT_freeBufferPool(mtctx->bufPool);\n    ZSTDMT_freeCCtxPool(mtctx->cctxPool);\n    ZSTDMT_freeSeqPool(mtctx->seqPool);\n    ZSTDMT_serialState_free(&mtctx->serial);\n    ZSTD_freeCDict(mtctx->cdictLocal);\n    if (mtctx->roundBuff.buffer)\n        ZSTD_free(mtctx->roundBuff.buffer, mtctx->cMem);\n    ZSTD_free(mtctx, mtctx->cMem);\n    return 0;\n}\n\nsize_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx)\n{\n    if (mtctx == NULL) return 0;   /* supports sizeof NULL */\n    return sizeof(*mtctx)\n            + POOL_sizeof(mtctx->factory)\n            + ZSTDMT_sizeof_bufferPool(mtctx->bufPool)\n            + (mtctx->jobIDMask+1) * sizeof(ZSTDMT_jobDescription)\n            + ZSTDMT_sizeof_CCtxPool(mtctx->cctxPool)\n            + ZSTDMT_sizeof_seqPool(mtctx->seqPool)\n            + ZSTD_sizeof_CDict(mtctx->cdictLocal)\n            + mtctx->roundBuff.capacity;\n}\n\n/* Internal only */\nsize_t\nZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params,\n                                   ZSTDMT_parameter parameter,\n                                   int value)\n{\n    DEBUGLOG(4, \"ZSTDMT_CCtxParam_setMTCtxParameter\");\n    switch(parameter)\n    {\n    case ZSTDMT_p_jobSize :\n        DEBUGLOG(4, \"ZSTDMT_CCtxParam_setMTCtxParameter : set jobSize to %i\", value);\n        return ZSTD_CCtxParams_setParameter(params, ZSTD_c_jobSize, value);\n    case ZSTDMT_p_overlapLog :\n        DEBUGLOG(4, \"ZSTDMT_p_overlapLog : %i\", value);\n        return ZSTD_CCtxParams_setParameter(params, ZSTD_c_overlapLog, value);\n    case ZSTDMT_p_rsyncable :\n        DEBUGLOG(4, \"ZSTD_p_rsyncable : %i\", value);\n        return ZSTD_CCtxParams_setParameter(params, ZSTD_c_rsyncable, value);\n    default :\n        return ERROR(parameter_unsupported);\n    }\n}\n\nsize_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int value)\n{\n    DEBUGLOG(4, \"ZSTDMT_setMTCtxParameter\");\n    return ZSTDMT_CCtxParam_setMTCtxParameter(&mtctx->params, parameter, value);\n}\n\nsize_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int* value)\n{\n    switch (parameter) {\n    case ZSTDMT_p_jobSize:\n        return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_jobSize, value);\n    case ZSTDMT_p_overlapLog:\n        return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_overlapLog, value);\n    case ZSTDMT_p_rsyncable:\n        return ZSTD_CCtxParams_getParameter(&mtctx->params, ZSTD_c_rsyncable, value);\n    default:\n        return ERROR(parameter_unsupported);\n    }\n}\n\n/* Sets parameters relevant to the compression job,\n * initializing others to default values. */\nstatic ZSTD_CCtx_params ZSTDMT_initJobCCtxParams(const ZSTD_CCtx_params* params)\n{\n    ZSTD_CCtx_params jobParams = *params;\n    /* Clear parameters related to multithreading */\n    jobParams.forceWindow = 0;\n    jobParams.nbWorkers = 0;\n    jobParams.jobSize = 0;\n    jobParams.overlapLog = 0;\n    jobParams.rsyncable = 0;\n    memset(&jobParams.ldmParams, 0, sizeof(ldmParams_t));\n    memset(&jobParams.customMem, 0, sizeof(ZSTD_customMem));\n    return jobParams;\n}\n\n\n/* ZSTDMT_resize() :\n * @return : error code if fails, 0 on success */\nstatic size_t ZSTDMT_resize(ZSTDMT_CCtx* mtctx, unsigned nbWorkers)\n{\n    if (POOL_resize(mtctx->factory, nbWorkers)) return ERROR(memory_allocation);\n    FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbWorkers) );\n    mtctx->bufPool = ZSTDMT_expandBufferPool(mtctx->bufPool, nbWorkers);\n    if (mtctx->bufPool == NULL) return ERROR(memory_allocation);\n    mtctx->cctxPool = ZSTDMT_expandCCtxPool(mtctx->cctxPool, nbWorkers);\n    if (mtctx->cctxPool == NULL) return ERROR(memory_allocation);\n    mtctx->seqPool = ZSTDMT_expandSeqPool(mtctx->seqPool, nbWorkers);\n    if (mtctx->seqPool == NULL) return ERROR(memory_allocation);\n    ZSTDMT_CCtxParam_setNbWorkers(&mtctx->params, nbWorkers);\n    return 0;\n}\n\n\n/*! ZSTDMT_updateCParams_whileCompressing() :\n *  Updates a selected set of compression parameters, remaining compatible with currently active frame.\n *  New parameters will be applied to next compression job. */\nvoid ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_params* cctxParams)\n{\n    U32 const saved_wlog = mtctx->params.cParams.windowLog;   /* Do not modify windowLog while compressing */\n    int const compressionLevel = cctxParams->compressionLevel;\n    DEBUGLOG(5, \"ZSTDMT_updateCParams_whileCompressing (level:%i)\",\n                compressionLevel);\n    mtctx->params.compressionLevel = compressionLevel;\n    {   ZSTD_compressionParameters cParams = ZSTD_getCParamsFromCCtxParams(cctxParams, 0, 0);\n        cParams.windowLog = saved_wlog;\n        mtctx->params.cParams = cParams;\n    }\n}\n\n/* ZSTDMT_getFrameProgression():\n * tells how much data has been consumed (input) and produced (output) for current frame.\n * able to count progression inside worker threads.\n * Note : mutex will be acquired during statistics collection inside workers. */\nZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx)\n{\n    ZSTD_frameProgression fps;\n    DEBUGLOG(5, \"ZSTDMT_getFrameProgression\");\n    fps.ingested = mtctx->consumed + mtctx->inBuff.filled;\n    fps.consumed = mtctx->consumed;\n    fps.produced = fps.flushed = mtctx->produced;\n    fps.currentJobID = mtctx->nextJobID;\n    fps.nbActiveWorkers = 0;\n    {   unsigned jobNb;\n        unsigned lastJobNb = mtctx->nextJobID + mtctx->jobReady; assert(mtctx->jobReady <= 1);\n        DEBUGLOG(6, \"ZSTDMT_getFrameProgression: jobs: from %u to <%u (jobReady:%u)\",\n                    mtctx->doneJobID, lastJobNb, mtctx->jobReady)\n        for (jobNb = mtctx->doneJobID ; jobNb < lastJobNb ; jobNb++) {\n            unsigned const wJobID = jobNb & mtctx->jobIDMask;\n            ZSTDMT_jobDescription* jobPtr = &mtctx->jobs[wJobID];\n            ZSTD_pthread_mutex_lock(&jobPtr->job_mutex);\n            {   size_t const cResult = jobPtr->cSize;\n                size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;\n                size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;\n                assert(flushed <= produced);\n                fps.ingested += jobPtr->src.size;\n                fps.consumed += jobPtr->consumed;\n                fps.produced += produced;\n                fps.flushed  += flushed;\n                fps.nbActiveWorkers += (jobPtr->consumed < jobPtr->src.size);\n            }\n            ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);\n        }\n    }\n    return fps;\n}\n\n\nsize_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx)\n{\n    size_t toFlush;\n    unsigned const jobID = mtctx->doneJobID;\n    assert(jobID <= mtctx->nextJobID);\n    if (jobID == mtctx->nextJobID) return 0;   /* no active job => nothing to flush */\n\n    /* look into oldest non-fully-flushed job */\n    {   unsigned const wJobID = jobID & mtctx->jobIDMask;\n        ZSTDMT_jobDescription* const jobPtr = &mtctx->jobs[wJobID];\n        ZSTD_pthread_mutex_lock(&jobPtr->job_mutex);\n        {   size_t const cResult = jobPtr->cSize;\n            size_t const produced = ZSTD_isError(cResult) ? 0 : cResult;\n            size_t const flushed = ZSTD_isError(cResult) ? 0 : jobPtr->dstFlushed;\n            assert(flushed <= produced);\n            assert(jobPtr->consumed <= jobPtr->src.size);\n            toFlush = produced - flushed;\n            /* if toFlush==0, nothing is available to flush.\n             * However, jobID is expected to still be active:\n             * if jobID was already completed and fully flushed,\n             * ZSTDMT_flushProduced() should have already moved onto next job.\n             * Therefore, some input has not yet been consumed. */\n            if (toFlush==0) {\n                assert(jobPtr->consumed < jobPtr->src.size);\n            }\n        }\n        ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);\n    }\n\n    return toFlush;\n}\n\n\n/* ------------------------------------------ */\n/* =====   Multi-threaded compression   ===== */\n/* ------------------------------------------ */\n\nstatic unsigned ZSTDMT_computeTargetJobLog(const ZSTD_CCtx_params* params)\n{\n    unsigned jobLog;\n    if (params->ldmParams.enableLdm) {\n        /* In Long Range Mode, the windowLog is typically oversized.\n         * In which case, it's preferable to determine the jobSize\n         * based on chainLog instead. */\n        jobLog = MAX(21, params->cParams.chainLog + 4);\n    } else {\n        jobLog = MAX(20, params->cParams.windowLog + 2);\n    }\n    return MIN(jobLog, (unsigned)ZSTDMT_JOBLOG_MAX);\n}\n\nstatic int ZSTDMT_overlapLog_default(ZSTD_strategy strat)\n{\n    switch(strat)\n    {\n        case ZSTD_btultra2:\n            return 9;\n        case ZSTD_btultra:\n        case ZSTD_btopt:\n            return 8;\n        case ZSTD_btlazy2:\n        case ZSTD_lazy2:\n            return 7;\n        case ZSTD_lazy:\n        case ZSTD_greedy:\n        case ZSTD_dfast:\n        case ZSTD_fast:\n        default:;\n    }\n    return 6;\n}\n\nstatic int ZSTDMT_overlapLog(int ovlog, ZSTD_strategy strat)\n{\n    assert(0 <= ovlog && ovlog <= 9);\n    if (ovlog == 0) return ZSTDMT_overlapLog_default(strat);\n    return ovlog;\n}\n\nstatic size_t ZSTDMT_computeOverlapSize(const ZSTD_CCtx_params* params)\n{\n    int const overlapRLog = 9 - ZSTDMT_overlapLog(params->overlapLog, params->cParams.strategy);\n    int ovLog = (overlapRLog >= 8) ? 0 : (params->cParams.windowLog - overlapRLog);\n    assert(0 <= overlapRLog && overlapRLog <= 8);\n    if (params->ldmParams.enableLdm) {\n        /* In Long Range Mode, the windowLog is typically oversized.\n         * In which case, it's preferable to determine the jobSize\n         * based on chainLog instead.\n         * Then, ovLog becomes a fraction of the jobSize, rather than windowSize */\n        ovLog = MIN(params->cParams.windowLog, ZSTDMT_computeTargetJobLog(params) - 2)\n                - overlapRLog;\n    }\n    assert(0 <= ovLog && ovLog <= ZSTD_WINDOWLOG_MAX);\n    DEBUGLOG(4, \"overlapLog : %i\", params->overlapLog);\n    DEBUGLOG(4, \"overlap size : %i\", 1 << ovLog);\n    return (ovLog==0) ? 0 : (size_t)1 << ovLog;\n}\n\nstatic unsigned\nZSTDMT_computeNbJobs(const ZSTD_CCtx_params* params, size_t srcSize, unsigned nbWorkers)\n{\n    assert(nbWorkers>0);\n    {   size_t const jobSizeTarget = (size_t)1 << ZSTDMT_computeTargetJobLog(params);\n        size_t const jobMaxSize = jobSizeTarget << 2;\n        size_t const passSizeMax = jobMaxSize * nbWorkers;\n        unsigned const multiplier = (unsigned)(srcSize / passSizeMax) + 1;\n        unsigned const nbJobsLarge = multiplier * nbWorkers;\n        unsigned const nbJobsMax = (unsigned)(srcSize / jobSizeTarget) + 1;\n        unsigned const nbJobsSmall = MIN(nbJobsMax, nbWorkers);\n        return (multiplier>1) ? nbJobsLarge : nbJobsSmall;\n}   }\n\n/* ZSTDMT_compress_advanced_internal() :\n * This is a blocking function : it will only give back control to caller after finishing its compression job.\n */\nstatic size_t ZSTDMT_compress_advanced_internal(\n                ZSTDMT_CCtx* mtctx,\n                void* dst, size_t dstCapacity,\n          const void* src, size_t srcSize,\n          const ZSTD_CDict* cdict,\n                ZSTD_CCtx_params params)\n{\n    ZSTD_CCtx_params const jobParams = ZSTDMT_initJobCCtxParams(&params);\n    size_t const overlapSize = ZSTDMT_computeOverlapSize(&params);\n    unsigned const nbJobs = ZSTDMT_computeNbJobs(&params, srcSize, params.nbWorkers);\n    size_t const proposedJobSize = (srcSize + (nbJobs-1)) / nbJobs;\n    size_t const avgJobSize = (((proposedJobSize-1) & 0x1FFFF) < 0x7FFF) ? proposedJobSize + 0xFFFF : proposedJobSize;   /* avoid too small last block */\n    const char* const srcStart = (const char*)src;\n    size_t remainingSrcSize = srcSize;\n    unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbJobs : (unsigned)(dstCapacity / ZSTD_compressBound(avgJobSize));  /* presumes avgJobSize >= 256 KB, which should be the case */\n    size_t frameStartPos = 0, dstBufferPos = 0;\n    assert(jobParams.nbWorkers == 0);\n    assert(mtctx->cctxPool->totalCCtx == params.nbWorkers);\n\n    params.jobSize = (U32)avgJobSize;\n    DEBUGLOG(4, \"ZSTDMT_compress_advanced_internal: nbJobs=%2u (rawSize=%u bytes; fixedSize=%u) \",\n                nbJobs, (U32)proposedJobSize, (U32)avgJobSize);\n\n    if ((nbJobs==1) | (params.nbWorkers<=1)) {   /* fallback to single-thread mode : this is a blocking invocation anyway */\n        ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];\n        DEBUGLOG(4, \"ZSTDMT_compress_advanced_internal: fallback to single-thread mode\");\n        if (cdict) return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, jobParams.fParams);\n        return ZSTD_compress_advanced_internal(cctx, dst, dstCapacity, src, srcSize, NULL, 0, &jobParams);\n    }\n\n    assert(avgJobSize >= 256 KB);  /* condition for ZSTD_compressBound(A) + ZSTD_compressBound(B) <= ZSTD_compressBound(A+B), required to compress directly into Dst (no additional buffer) */\n    ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(avgJobSize) );\n    if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, avgJobSize))\n        return ERROR(memory_allocation);\n\n    FORWARD_IF_ERROR( ZSTDMT_expandJobsTable(mtctx, nbJobs) );  /* only expands if necessary */\n\n    {   unsigned u;\n        for (u=0; u<nbJobs; u++) {\n            size_t const jobSize = MIN(remainingSrcSize, avgJobSize);\n            size_t const dstBufferCapacity = ZSTD_compressBound(jobSize);\n            buffer_t const dstAsBuffer = { (char*)dst + dstBufferPos, dstBufferCapacity };\n            buffer_t const dstBuffer = u < compressWithinDst ? dstAsBuffer : g_nullBuffer;\n            size_t dictSize = u ? overlapSize : 0;\n\n            mtctx->jobs[u].prefix.start = srcStart + frameStartPos - dictSize;\n            mtctx->jobs[u].prefix.size = dictSize;\n            mtctx->jobs[u].src.start = srcStart + frameStartPos;\n            mtctx->jobs[u].src.size = jobSize; assert(jobSize > 0);  /* avoid job.src.size == 0 */\n            mtctx->jobs[u].consumed = 0;\n            mtctx->jobs[u].cSize = 0;\n            mtctx->jobs[u].cdict = (u==0) ? cdict : NULL;\n            mtctx->jobs[u].fullFrameSize = srcSize;\n            mtctx->jobs[u].params = jobParams;\n            /* do not calculate checksum within sections, but write it in header for first section */\n            mtctx->jobs[u].dstBuff = dstBuffer;\n            mtctx->jobs[u].cctxPool = mtctx->cctxPool;\n            mtctx->jobs[u].bufPool = mtctx->bufPool;\n            mtctx->jobs[u].seqPool = mtctx->seqPool;\n            mtctx->jobs[u].serial = &mtctx->serial;\n            mtctx->jobs[u].jobID = u;\n            mtctx->jobs[u].firstJob = (u==0);\n            mtctx->jobs[u].lastJob = (u==nbJobs-1);\n\n            DEBUGLOG(5, \"ZSTDMT_compress_advanced_internal: posting job %u  (%u bytes)\", u, (U32)jobSize);\n            DEBUG_PRINTHEX(6, mtctx->jobs[u].prefix.start, 12);\n            POOL_add(mtctx->factory, ZSTDMT_compressionJob, &mtctx->jobs[u]);\n\n            frameStartPos += jobSize;\n            dstBufferPos += dstBufferCapacity;\n            remainingSrcSize -= jobSize;\n    }   }\n\n    /* collect result */\n    {   size_t error = 0, dstPos = 0;\n        unsigned jobID;\n        for (jobID=0; jobID<nbJobs; jobID++) {\n            DEBUGLOG(5, \"waiting for job %u \", jobID);\n            ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex);\n            while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) {\n                DEBUGLOG(5, \"waiting for jobCompleted signal from job %u\", jobID);\n                ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex);\n            }\n            ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex);\n            DEBUGLOG(5, \"ready to write job %u \", jobID);\n\n            {   size_t const cSize = mtctx->jobs[jobID].cSize;\n                if (ZSTD_isError(cSize)) error = cSize;\n                if ((!error) && (dstPos + cSize > dstCapacity)) error = ERROR(dstSize_tooSmall);\n                if (jobID) {   /* note : job 0 is written directly at dst, which is correct position */\n                    if (!error)\n                        memmove((char*)dst + dstPos, mtctx->jobs[jobID].dstBuff.start, cSize);  /* may overlap when job compressed within dst */\n                    if (jobID >= compressWithinDst) {  /* job compressed into its own buffer, which must be released */\n                        DEBUGLOG(5, \"releasing buffer %u>=%u\", jobID, compressWithinDst);\n                        ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[jobID].dstBuff);\n                }   }\n                mtctx->jobs[jobID].dstBuff = g_nullBuffer;\n                mtctx->jobs[jobID].cSize = 0;\n                dstPos += cSize ;\n            }\n        }  /* for (jobID=0; jobID<nbJobs; jobID++) */\n\n        DEBUGLOG(4, \"checksumFlag : %u \", params.fParams.checksumFlag);\n        if (params.fParams.checksumFlag) {\n            U32 const checksum = (U32)XXH64_digest(&mtctx->serial.xxhState);\n            if (dstPos + 4 > dstCapacity) {\n                error = ERROR(dstSize_tooSmall);\n            } else {\n                DEBUGLOG(4, \"writing checksum : %08X \\n\", checksum);\n                MEM_writeLE32((char*)dst + dstPos, checksum);\n                dstPos += 4;\n        }   }\n\n        if (!error) DEBUGLOG(4, \"compressed size : %u  \", (U32)dstPos);\n        return error ? error : dstPos;\n    }\n}\n\nsize_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,\n                                void* dst, size_t dstCapacity,\n                          const void* src, size_t srcSize,\n                          const ZSTD_CDict* cdict,\n                                ZSTD_parameters params,\n                                int overlapLog)\n{\n    ZSTD_CCtx_params cctxParams = mtctx->params;\n    cctxParams.cParams = params.cParams;\n    cctxParams.fParams = params.fParams;\n    assert(ZSTD_OVERLAPLOG_MIN <= overlapLog && overlapLog <= ZSTD_OVERLAPLOG_MAX);\n    cctxParams.overlapLog = overlapLog;\n    return ZSTDMT_compress_advanced_internal(mtctx,\n                                             dst, dstCapacity,\n                                             src, srcSize,\n                                             cdict, cctxParams);\n}\n\n\nsize_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,\n                           void* dst, size_t dstCapacity,\n                     const void* src, size_t srcSize,\n                           int compressionLevel)\n{\n    ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0);\n    int const overlapLog = ZSTDMT_overlapLog_default(params.cParams.strategy);\n    params.fParams.contentSizeFlag = 1;\n    return ZSTDMT_compress_advanced(mtctx, dst, dstCapacity, src, srcSize, NULL, params, overlapLog);\n}\n\n\n/* ====================================== */\n/* =======      Streaming API     ======= */\n/* ====================================== */\n\nsize_t ZSTDMT_initCStream_internal(\n        ZSTDMT_CCtx* mtctx,\n        const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,\n        const ZSTD_CDict* cdict, ZSTD_CCtx_params params,\n        unsigned long long pledgedSrcSize)\n{\n    DEBUGLOG(4, \"ZSTDMT_initCStream_internal (pledgedSrcSize=%u, nbWorkers=%u, cctxPool=%u)\",\n                (U32)pledgedSrcSize, params.nbWorkers, mtctx->cctxPool->totalCCtx);\n\n    /* params supposed partially fully validated at this point */\n    assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));\n    assert(!((dict) && (cdict)));  /* either dict or cdict, not both */\n\n    /* init */\n    if (params.nbWorkers != mtctx->params.nbWorkers)\n        FORWARD_IF_ERROR( ZSTDMT_resize(mtctx, params.nbWorkers) );\n\n    if (params.jobSize != 0 && params.jobSize < ZSTDMT_JOBSIZE_MIN) params.jobSize = ZSTDMT_JOBSIZE_MIN;\n    if (params.jobSize > (size_t)ZSTDMT_JOBSIZE_MAX) params.jobSize = (size_t)ZSTDMT_JOBSIZE_MAX;\n\n    mtctx->singleBlockingThread = (pledgedSrcSize <= ZSTDMT_JOBSIZE_MIN);  /* do not trigger multi-threading when srcSize is too small */\n    if (mtctx->singleBlockingThread) {\n        ZSTD_CCtx_params const singleThreadParams = ZSTDMT_initJobCCtxParams(&params);\n        DEBUGLOG(5, \"ZSTDMT_initCStream_internal: switch to single blocking thread mode\");\n        assert(singleThreadParams.nbWorkers == 0);\n        return ZSTD_initCStream_internal(mtctx->cctxPool->cctx[0],\n                                         dict, dictSize, cdict,\n                                         &singleThreadParams, pledgedSrcSize);\n    }\n\n    DEBUGLOG(4, \"ZSTDMT_initCStream_internal: %u workers\", params.nbWorkers);\n\n    if (mtctx->allJobsCompleted == 0) {   /* previous compression not correctly finished */\n        ZSTDMT_waitForAllJobsCompleted(mtctx);\n        ZSTDMT_releaseAllJobResources(mtctx);\n        mtctx->allJobsCompleted = 1;\n    }\n\n    mtctx->params = params;\n    mtctx->frameContentSize = pledgedSrcSize;\n    if (dict) {\n        ZSTD_freeCDict(mtctx->cdictLocal);\n        mtctx->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize,\n                                                    ZSTD_dlm_byCopy, dictContentType, /* note : a loadPrefix becomes an internal CDict */\n                                                    params.cParams, mtctx->cMem);\n        mtctx->cdict = mtctx->cdictLocal;\n        if (mtctx->cdictLocal == NULL) return ERROR(memory_allocation);\n    } else {\n        ZSTD_freeCDict(mtctx->cdictLocal);\n        mtctx->cdictLocal = NULL;\n        mtctx->cdict = cdict;\n    }\n\n    mtctx->targetPrefixSize = ZSTDMT_computeOverlapSize(&params);\n    DEBUGLOG(4, \"overlapLog=%i => %u KB\", params.overlapLog, (U32)(mtctx->targetPrefixSize>>10));\n    mtctx->targetSectionSize = params.jobSize;\n    if (mtctx->targetSectionSize == 0) {\n        mtctx->targetSectionSize = 1ULL << ZSTDMT_computeTargetJobLog(&params);\n    }\n    assert(mtctx->targetSectionSize <= (size_t)ZSTDMT_JOBSIZE_MAX);\n\n    if (params.rsyncable) {\n        /* Aim for the targetsectionSize as the average job size. */\n        U32 const jobSizeMB = (U32)(mtctx->targetSectionSize >> 20);\n        U32 const rsyncBits = ZSTD_highbit32(jobSizeMB) + 20;\n        assert(jobSizeMB >= 1);\n        DEBUGLOG(4, \"rsyncLog = %u\", rsyncBits);\n        mtctx->rsync.hash = 0;\n        mtctx->rsync.hitMask = (1ULL << rsyncBits) - 1;\n        mtctx->rsync.primePower = ZSTD_rollingHash_primePower(RSYNC_LENGTH);\n    }\n    if (mtctx->targetSectionSize < mtctx->targetPrefixSize) mtctx->targetSectionSize = mtctx->targetPrefixSize;  /* job size must be >= overlap size */\n    DEBUGLOG(4, \"Job Size : %u KB (note : set to %u)\", (U32)(mtctx->targetSectionSize>>10), (U32)params.jobSize);\n    DEBUGLOG(4, \"inBuff Size : %u KB\", (U32)(mtctx->targetSectionSize>>10));\n    ZSTDMT_setBufferSize(mtctx->bufPool, ZSTD_compressBound(mtctx->targetSectionSize));\n    {\n        /* If ldm is enabled we need windowSize space. */\n        size_t const windowSize = mtctx->params.ldmParams.enableLdm ? (1U << mtctx->params.cParams.windowLog) : 0;\n        /* Two buffers of slack, plus extra space for the overlap\n         * This is the minimum slack that LDM works with. One extra because\n         * flush might waste up to targetSectionSize-1 bytes. Another extra\n         * for the overlap (if > 0), then one to fill which doesn't overlap\n         * with the LDM window.\n         */\n        size_t const nbSlackBuffers = 2 + (mtctx->targetPrefixSize > 0);\n        size_t const slackSize = mtctx->targetSectionSize * nbSlackBuffers;\n        /* Compute the total size, and always have enough slack */\n        size_t const nbWorkers = MAX(mtctx->params.nbWorkers, 1);\n        size_t const sectionsSize = mtctx->targetSectionSize * nbWorkers;\n        size_t const capacity = MAX(windowSize, sectionsSize) + slackSize;\n        if (mtctx->roundBuff.capacity < capacity) {\n            if (mtctx->roundBuff.buffer)\n                ZSTD_free(mtctx->roundBuff.buffer, mtctx->cMem);\n            mtctx->roundBuff.buffer = (BYTE*)ZSTD_malloc(capacity, mtctx->cMem);\n            if (mtctx->roundBuff.buffer == NULL) {\n                mtctx->roundBuff.capacity = 0;\n                return ERROR(memory_allocation);\n            }\n            mtctx->roundBuff.capacity = capacity;\n        }\n    }\n    DEBUGLOG(4, \"roundBuff capacity : %u KB\", (U32)(mtctx->roundBuff.capacity>>10));\n    mtctx->roundBuff.pos = 0;\n    mtctx->inBuff.buffer = g_nullBuffer;\n    mtctx->inBuff.filled = 0;\n    mtctx->inBuff.prefix = kNullRange;\n    mtctx->doneJobID = 0;\n    mtctx->nextJobID = 0;\n    mtctx->frameEnded = 0;\n    mtctx->allJobsCompleted = 0;\n    mtctx->consumed = 0;\n    mtctx->produced = 0;\n    if (ZSTDMT_serialState_reset(&mtctx->serial, mtctx->seqPool, params, mtctx->targetSectionSize))\n        return ERROR(memory_allocation);\n    return 0;\n}\n\nsize_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,\n                             const void* dict, size_t dictSize,\n                                   ZSTD_parameters params,\n                                   unsigned long long pledgedSrcSize)\n{\n    ZSTD_CCtx_params cctxParams = mtctx->params;  /* retrieve sticky params */\n    DEBUGLOG(4, \"ZSTDMT_initCStream_advanced (pledgedSrcSize=%u)\", (U32)pledgedSrcSize);\n    cctxParams.cParams = params.cParams;\n    cctxParams.fParams = params.fParams;\n    return ZSTDMT_initCStream_internal(mtctx, dict, dictSize, ZSTD_dct_auto, NULL,\n                                       cctxParams, pledgedSrcSize);\n}\n\nsize_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,\n                               const ZSTD_CDict* cdict,\n                                     ZSTD_frameParameters fParams,\n                                     unsigned long long pledgedSrcSize)\n{\n    ZSTD_CCtx_params cctxParams = mtctx->params;\n    if (cdict==NULL) return ERROR(dictionary_wrong);   /* method incompatible with NULL cdict */\n    cctxParams.cParams = ZSTD_getCParamsFromCDict(cdict);\n    cctxParams.fParams = fParams;\n    return ZSTDMT_initCStream_internal(mtctx, NULL, 0 /*dictSize*/, ZSTD_dct_auto, cdict,\n                                       cctxParams, pledgedSrcSize);\n}\n\n\n/* ZSTDMT_resetCStream() :\n * pledgedSrcSize can be zero == unknown (for the time being)\n * prefer using ZSTD_CONTENTSIZE_UNKNOWN,\n * as `0` might mean \"empty\" in the future */\nsize_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize)\n{\n    if (!pledgedSrcSize) pledgedSrcSize = ZSTD_CONTENTSIZE_UNKNOWN;\n    return ZSTDMT_initCStream_internal(mtctx, NULL, 0, ZSTD_dct_auto, 0, mtctx->params,\n                                       pledgedSrcSize);\n}\n\nsize_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel) {\n    ZSTD_parameters const params = ZSTD_getParams(compressionLevel, ZSTD_CONTENTSIZE_UNKNOWN, 0);\n    ZSTD_CCtx_params cctxParams = mtctx->params;   /* retrieve sticky params */\n    DEBUGLOG(4, \"ZSTDMT_initCStream (cLevel=%i)\", compressionLevel);\n    cctxParams.cParams = params.cParams;\n    cctxParams.fParams = params.fParams;\n    return ZSTDMT_initCStream_internal(mtctx, NULL, 0, ZSTD_dct_auto, NULL, cctxParams, ZSTD_CONTENTSIZE_UNKNOWN);\n}\n\n\n/* ZSTDMT_writeLastEmptyBlock()\n * Write a single empty block with an end-of-frame to finish a frame.\n * Job must be created from streaming variant.\n * This function is always successful if expected conditions are fulfilled.\n */\nstatic void ZSTDMT_writeLastEmptyBlock(ZSTDMT_jobDescription* job)\n{\n    assert(job->lastJob == 1);\n    assert(job->src.size == 0);   /* last job is empty -> will be simplified into a last empty block */\n    assert(job->firstJob == 0);   /* cannot be first job, as it also needs to create frame header */\n    assert(job->dstBuff.start == NULL);   /* invoked from streaming variant only (otherwise, dstBuff might be user's output) */\n    job->dstBuff = ZSTDMT_getBuffer(job->bufPool);\n    if (job->dstBuff.start == NULL) {\n      job->cSize = ERROR(memory_allocation);\n      return;\n    }\n    assert(job->dstBuff.capacity >= ZSTD_blockHeaderSize);   /* no buffer should ever be that small */\n    job->src = kNullRange;\n    job->cSize = ZSTD_writeLastEmptyBlock(job->dstBuff.start, job->dstBuff.capacity);\n    assert(!ZSTD_isError(job->cSize));\n    assert(job->consumed == 0);\n}\n\nstatic size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* mtctx, size_t srcSize, ZSTD_EndDirective endOp)\n{\n    unsigned const jobID = mtctx->nextJobID & mtctx->jobIDMask;\n    int const endFrame = (endOp == ZSTD_e_end);\n\n    if (mtctx->nextJobID > mtctx->doneJobID + mtctx->jobIDMask) {\n        DEBUGLOG(5, \"ZSTDMT_createCompressionJob: will not create new job : table is full\");\n        assert((mtctx->nextJobID & mtctx->jobIDMask) == (mtctx->doneJobID & mtctx->jobIDMask));\n        return 0;\n    }\n\n    if (!mtctx->jobReady) {\n        BYTE const* src = (BYTE const*)mtctx->inBuff.buffer.start;\n        DEBUGLOG(5, \"ZSTDMT_createCompressionJob: preparing job %u to compress %u bytes with %u preload \",\n                    mtctx->nextJobID, (U32)srcSize, (U32)mtctx->inBuff.prefix.size);\n        mtctx->jobs[jobID].src.start = src;\n        mtctx->jobs[jobID].src.size = srcSize;\n        assert(mtctx->inBuff.filled >= srcSize);\n        mtctx->jobs[jobID].prefix = mtctx->inBuff.prefix;\n        mtctx->jobs[jobID].consumed = 0;\n        mtctx->jobs[jobID].cSize = 0;\n        mtctx->jobs[jobID].params = mtctx->params;\n        mtctx->jobs[jobID].cdict = mtctx->nextJobID==0 ? mtctx->cdict : NULL;\n        mtctx->jobs[jobID].fullFrameSize = mtctx->frameContentSize;\n        mtctx->jobs[jobID].dstBuff = g_nullBuffer;\n        mtctx->jobs[jobID].cctxPool = mtctx->cctxPool;\n        mtctx->jobs[jobID].bufPool = mtctx->bufPool;\n        mtctx->jobs[jobID].seqPool = mtctx->seqPool;\n        mtctx->jobs[jobID].serial = &mtctx->serial;\n        mtctx->jobs[jobID].jobID = mtctx->nextJobID;\n        mtctx->jobs[jobID].firstJob = (mtctx->nextJobID==0);\n        mtctx->jobs[jobID].lastJob = endFrame;\n        mtctx->jobs[jobID].frameChecksumNeeded = mtctx->params.fParams.checksumFlag && endFrame && (mtctx->nextJobID>0);\n        mtctx->jobs[jobID].dstFlushed = 0;\n\n        /* Update the round buffer pos and clear the input buffer to be reset */\n        mtctx->roundBuff.pos += srcSize;\n        mtctx->inBuff.buffer = g_nullBuffer;\n        mtctx->inBuff.filled = 0;\n        /* Set the prefix */\n        if (!endFrame) {\n            size_t const newPrefixSize = MIN(srcSize, mtctx->targetPrefixSize);\n            mtctx->inBuff.prefix.start = src + srcSize - newPrefixSize;\n            mtctx->inBuff.prefix.size = newPrefixSize;\n        } else {   /* endFrame==1 => no need for another input buffer */\n            mtctx->inBuff.prefix = kNullRange;\n            mtctx->frameEnded = endFrame;\n            if (mtctx->nextJobID == 0) {\n                /* single job exception : checksum is already calculated directly within worker thread */\n                mtctx->params.fParams.checksumFlag = 0;\n        }   }\n\n        if ( (srcSize == 0)\n          && (mtctx->nextJobID>0)/*single job must also write frame header*/ ) {\n            DEBUGLOG(5, \"ZSTDMT_createCompressionJob: creating a last empty block to end frame\");\n            assert(endOp == ZSTD_e_end);  /* only possible case : need to end the frame with an empty last block */\n            ZSTDMT_writeLastEmptyBlock(mtctx->jobs + jobID);\n            mtctx->nextJobID++;\n            return 0;\n        }\n    }\n\n    DEBUGLOG(5, \"ZSTDMT_createCompressionJob: posting job %u : %u bytes  (end:%u, jobNb == %u (mod:%u))\",\n                mtctx->nextJobID,\n                (U32)mtctx->jobs[jobID].src.size,\n                mtctx->jobs[jobID].lastJob,\n                mtctx->nextJobID,\n                jobID);\n    if (POOL_tryAdd(mtctx->factory, ZSTDMT_compressionJob, &mtctx->jobs[jobID])) {\n        mtctx->nextJobID++;\n        mtctx->jobReady = 0;\n    } else {\n        DEBUGLOG(5, \"ZSTDMT_createCompressionJob: no worker available for job %u\", mtctx->nextJobID);\n        mtctx->jobReady = 1;\n    }\n    return 0;\n}\n\n\n/*! ZSTDMT_flushProduced() :\n *  flush whatever data has been produced but not yet flushed in current job.\n *  move to next job if current one is fully flushed.\n * `output` : `pos` will be updated with amount of data flushed .\n * `blockToFlush` : if >0, the function will block and wait if there is no data available to flush .\n * @return : amount of data remaining within internal buffer, 0 if no more, 1 if unknown but > 0, or an error code */\nstatic size_t ZSTDMT_flushProduced(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, unsigned blockToFlush, ZSTD_EndDirective end)\n{\n    unsigned const wJobID = mtctx->doneJobID & mtctx->jobIDMask;\n    DEBUGLOG(5, \"ZSTDMT_flushProduced (blocking:%u , job %u <= %u)\",\n                blockToFlush, mtctx->doneJobID, mtctx->nextJobID);\n    assert(output->size >= output->pos);\n\n    ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[wJobID].job_mutex);\n    if (  blockToFlush\n      && (mtctx->doneJobID < mtctx->nextJobID) ) {\n        assert(mtctx->jobs[wJobID].dstFlushed <= mtctx->jobs[wJobID].cSize);\n        while (mtctx->jobs[wJobID].dstFlushed == mtctx->jobs[wJobID].cSize) {  /* nothing to flush */\n            if (mtctx->jobs[wJobID].consumed == mtctx->jobs[wJobID].src.size) {\n                DEBUGLOG(5, \"job %u is completely consumed (%u == %u) => don't wait for cond, there will be none\",\n                            mtctx->doneJobID, (U32)mtctx->jobs[wJobID].consumed, (U32)mtctx->jobs[wJobID].src.size);\n                break;\n            }\n            DEBUGLOG(5, \"waiting for something to flush from job %u (currently flushed: %u bytes)\",\n                        mtctx->doneJobID, (U32)mtctx->jobs[wJobID].dstFlushed);\n            ZSTD_pthread_cond_wait(&mtctx->jobs[wJobID].job_cond, &mtctx->jobs[wJobID].job_mutex);  /* block when nothing to flush but some to come */\n    }   }\n\n    /* try to flush something */\n    {   size_t cSize = mtctx->jobs[wJobID].cSize;                  /* shared */\n        size_t const srcConsumed = mtctx->jobs[wJobID].consumed;   /* shared */\n        size_t const srcSize = mtctx->jobs[wJobID].src.size;       /* read-only, could be done after mutex lock, but no-declaration-after-statement */\n        ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);\n        if (ZSTD_isError(cSize)) {\n            DEBUGLOG(5, \"ZSTDMT_flushProduced: job %u : compression error detected : %s\",\n                        mtctx->doneJobID, ZSTD_getErrorName(cSize));\n            ZSTDMT_waitForAllJobsCompleted(mtctx);\n            ZSTDMT_releaseAllJobResources(mtctx);\n            return cSize;\n        }\n        /* add frame checksum if necessary (can only happen once) */\n        assert(srcConsumed <= srcSize);\n        if ( (srcConsumed == srcSize)   /* job completed -> worker no longer active */\n          && mtctx->jobs[wJobID].frameChecksumNeeded ) {\n            U32 const checksum = (U32)XXH64_digest(&mtctx->serial.xxhState);\n            DEBUGLOG(4, \"ZSTDMT_flushProduced: writing checksum : %08X \\n\", checksum);\n            MEM_writeLE32((char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].cSize, checksum);\n            cSize += 4;\n            mtctx->jobs[wJobID].cSize += 4;  /* can write this shared value, as worker is no longer active */\n            mtctx->jobs[wJobID].frameChecksumNeeded = 0;\n        }\n\n        if (cSize > 0) {   /* compression is ongoing or completed */\n            size_t const toFlush = MIN(cSize - mtctx->jobs[wJobID].dstFlushed, output->size - output->pos);\n            DEBUGLOG(5, \"ZSTDMT_flushProduced: Flushing %u bytes from job %u (completion:%u/%u, generated:%u)\",\n                        (U32)toFlush, mtctx->doneJobID, (U32)srcConsumed, (U32)srcSize, (U32)cSize);\n            assert(mtctx->doneJobID < mtctx->nextJobID);\n            assert(cSize >= mtctx->jobs[wJobID].dstFlushed);\n            assert(mtctx->jobs[wJobID].dstBuff.start != NULL);\n            memcpy((char*)output->dst + output->pos,\n                   (const char*)mtctx->jobs[wJobID].dstBuff.start + mtctx->jobs[wJobID].dstFlushed,\n                   toFlush);\n            output->pos += toFlush;\n            mtctx->jobs[wJobID].dstFlushed += toFlush;  /* can write : this value is only used by mtctx */\n\n            if ( (srcConsumed == srcSize)    /* job is completed */\n              && (mtctx->jobs[wJobID].dstFlushed == cSize) ) {   /* output buffer fully flushed => free this job position */\n                DEBUGLOG(5, \"Job %u completed (%u bytes), moving to next one\",\n                        mtctx->doneJobID, (U32)mtctx->jobs[wJobID].dstFlushed);\n                ZSTDMT_releaseBuffer(mtctx->bufPool, mtctx->jobs[wJobID].dstBuff);\n                DEBUGLOG(5, \"dstBuffer released\");\n                mtctx->jobs[wJobID].dstBuff = g_nullBuffer;\n                mtctx->jobs[wJobID].cSize = 0;   /* ensure this job slot is considered \"not started\" in future check */\n                mtctx->consumed += srcSize;\n                mtctx->produced += cSize;\n                mtctx->doneJobID++;\n        }   }\n\n        /* return value : how many bytes left in buffer ; fake it to 1 when unknown but >0 */\n        if (cSize > mtctx->jobs[wJobID].dstFlushed) return (cSize - mtctx->jobs[wJobID].dstFlushed);\n        if (srcSize > srcConsumed) return 1;   /* current job not completely compressed */\n    }\n    if (mtctx->doneJobID < mtctx->nextJobID) return 1;   /* some more jobs ongoing */\n    if (mtctx->jobReady) return 1;      /* one job is ready to push, just not yet in the list */\n    if (mtctx->inBuff.filled > 0) return 1;   /* input is not empty, and still needs to be converted into a job */\n    mtctx->allJobsCompleted = mtctx->frameEnded;   /* all jobs are entirely flushed => if this one is last one, frame is completed */\n    if (end == ZSTD_e_end) return !mtctx->frameEnded;  /* for ZSTD_e_end, question becomes : is frame completed ? instead of : are internal buffers fully flushed ? */\n    return 0;   /* internal buffers fully flushed */\n}\n\n/**\n * Returns the range of data used by the earliest job that is not yet complete.\n * If the data of the first job is broken up into two segments, we cover both\n * sections.\n */\nstatic range_t ZSTDMT_getInputDataInUse(ZSTDMT_CCtx* mtctx)\n{\n    unsigned const firstJobID = mtctx->doneJobID;\n    unsigned const lastJobID = mtctx->nextJobID;\n    unsigned jobID;\n\n    for (jobID = firstJobID; jobID < lastJobID; ++jobID) {\n        unsigned const wJobID = jobID & mtctx->jobIDMask;\n        size_t consumed;\n\n        ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[wJobID].job_mutex);\n        consumed = mtctx->jobs[wJobID].consumed;\n        ZSTD_pthread_mutex_unlock(&mtctx->jobs[wJobID].job_mutex);\n\n        if (consumed < mtctx->jobs[wJobID].src.size) {\n            range_t range = mtctx->jobs[wJobID].prefix;\n            if (range.size == 0) {\n                /* Empty prefix */\n                range = mtctx->jobs[wJobID].src;\n            }\n            /* Job source in multiple segments not supported yet */\n            assert(range.start <= mtctx->jobs[wJobID].src.start);\n            return range;\n        }\n    }\n    return kNullRange;\n}\n\n/**\n * Returns non-zero iff buffer and range overlap.\n */\nstatic int ZSTDMT_isOverlapped(buffer_t buffer, range_t range)\n{\n    BYTE const* const bufferStart = (BYTE const*)buffer.start;\n    BYTE const* const bufferEnd = bufferStart + buffer.capacity;\n    BYTE const* const rangeStart = (BYTE const*)range.start;\n    BYTE const* const rangeEnd = rangeStart + range.size;\n\n    if (rangeStart == NULL || bufferStart == NULL)\n        return 0;\n    /* Empty ranges cannot overlap */\n    if (bufferStart == bufferEnd || rangeStart == rangeEnd)\n        return 0;\n\n    return bufferStart < rangeEnd && rangeStart < bufferEnd;\n}\n\nstatic int ZSTDMT_doesOverlapWindow(buffer_t buffer, ZSTD_window_t window)\n{\n    range_t extDict;\n    range_t prefix;\n\n    DEBUGLOG(5, \"ZSTDMT_doesOverlapWindow\");\n    extDict.start = window.dictBase + window.lowLimit;\n    extDict.size = window.dictLimit - window.lowLimit;\n\n    prefix.start = window.base + window.dictLimit;\n    prefix.size = window.nextSrc - (window.base + window.dictLimit);\n    DEBUGLOG(5, \"extDict [0x%zx, 0x%zx)\",\n                (size_t)extDict.start,\n                (size_t)extDict.start + extDict.size);\n    DEBUGLOG(5, \"prefix  [0x%zx, 0x%zx)\",\n                (size_t)prefix.start,\n                (size_t)prefix.start + prefix.size);\n\n    return ZSTDMT_isOverlapped(buffer, extDict)\n        || ZSTDMT_isOverlapped(buffer, prefix);\n}\n\nstatic void ZSTDMT_waitForLdmComplete(ZSTDMT_CCtx* mtctx, buffer_t buffer)\n{\n    if (mtctx->params.ldmParams.enableLdm) {\n        ZSTD_pthread_mutex_t* mutex = &mtctx->serial.ldmWindowMutex;\n        DEBUGLOG(5, \"ZSTDMT_waitForLdmComplete\");\n        DEBUGLOG(5, \"source  [0x%zx, 0x%zx)\",\n                    (size_t)buffer.start,\n                    (size_t)buffer.start + buffer.capacity);\n        ZSTD_PTHREAD_MUTEX_LOCK(mutex);\n        while (ZSTDMT_doesOverlapWindow(buffer, mtctx->serial.ldmWindow)) {\n            DEBUGLOG(5, \"Waiting for LDM to finish...\");\n            ZSTD_pthread_cond_wait(&mtctx->serial.ldmWindowCond, mutex);\n        }\n        DEBUGLOG(6, \"Done waiting for LDM to finish\");\n        ZSTD_pthread_mutex_unlock(mutex);\n    }\n}\n\n/**\n * Attempts to set the inBuff to the next section to fill.\n * If any part of the new section is still in use we give up.\n * Returns non-zero if the buffer is filled.\n */\nstatic int ZSTDMT_tryGetInputRange(ZSTDMT_CCtx* mtctx)\n{\n    range_t const inUse = ZSTDMT_getInputDataInUse(mtctx);\n    size_t const spaceLeft = mtctx->roundBuff.capacity - mtctx->roundBuff.pos;\n    size_t const target = mtctx->targetSectionSize;\n    buffer_t buffer;\n\n    DEBUGLOG(5, \"ZSTDMT_tryGetInputRange\");\n    assert(mtctx->inBuff.buffer.start == NULL);\n    assert(mtctx->roundBuff.capacity >= target);\n\n    if (spaceLeft < target) {\n        /* ZSTD_invalidateRepCodes() doesn't work for extDict variants.\n         * Simply copy the prefix to the beginning in that case.\n         */\n        BYTE* const start = (BYTE*)mtctx->roundBuff.buffer;\n        size_t const prefixSize = mtctx->inBuff.prefix.size;\n\n        buffer.start = start;\n        buffer.capacity = prefixSize;\n        if (ZSTDMT_isOverlapped(buffer, inUse)) {\n            DEBUGLOG(5, \"Waiting for buffer...\");\n            return 0;\n        }\n        ZSTDMT_waitForLdmComplete(mtctx, buffer);\n        memmove(start, mtctx->inBuff.prefix.start, prefixSize);\n        mtctx->inBuff.prefix.start = start;\n        mtctx->roundBuff.pos = prefixSize;\n    }\n    buffer.start = mtctx->roundBuff.buffer + mtctx->roundBuff.pos;\n    buffer.capacity = target;\n\n    if (ZSTDMT_isOverlapped(buffer, inUse)) {\n        DEBUGLOG(5, \"Waiting for buffer...\");\n        return 0;\n    }\n    assert(!ZSTDMT_isOverlapped(buffer, mtctx->inBuff.prefix));\n\n    ZSTDMT_waitForLdmComplete(mtctx, buffer);\n\n    DEBUGLOG(5, \"Using prefix range [%zx, %zx)\",\n                (size_t)mtctx->inBuff.prefix.start,\n                (size_t)mtctx->inBuff.prefix.start + mtctx->inBuff.prefix.size);\n    DEBUGLOG(5, \"Using source range [%zx, %zx)\",\n                (size_t)buffer.start,\n                (size_t)buffer.start + buffer.capacity);\n\n\n    mtctx->inBuff.buffer = buffer;\n    mtctx->inBuff.filled = 0;\n    assert(mtctx->roundBuff.pos + buffer.capacity <= mtctx->roundBuff.capacity);\n    return 1;\n}\n\ntypedef struct {\n  size_t toLoad;  /* The number of bytes to load from the input. */\n  int flush;      /* Boolean declaring if we must flush because we found a synchronization point. */\n} syncPoint_t;\n\n/**\n * Searches through the input for a synchronization point. If one is found, we\n * will instruct the caller to flush, and return the number of bytes to load.\n * Otherwise, we will load as many bytes as possible and instruct the caller\n * to continue as normal.\n */\nstatic syncPoint_t\nfindSynchronizationPoint(ZSTDMT_CCtx const* mtctx, ZSTD_inBuffer const input)\n{\n    BYTE const* const istart = (BYTE const*)input.src + input.pos;\n    U64 const primePower = mtctx->rsync.primePower;\n    U64 const hitMask = mtctx->rsync.hitMask;\n\n    syncPoint_t syncPoint;\n    U64 hash;\n    BYTE const* prev;\n    size_t pos;\n\n    syncPoint.toLoad = MIN(input.size - input.pos, mtctx->targetSectionSize - mtctx->inBuff.filled);\n    syncPoint.flush = 0;\n    if (!mtctx->params.rsyncable)\n        /* Rsync is disabled. */\n        return syncPoint;\n    if (mtctx->inBuff.filled + syncPoint.toLoad < RSYNC_LENGTH)\n        /* Not enough to compute the hash.\n         * We will miss any synchronization points in this RSYNC_LENGTH byte\n         * window. However, since it depends only in the internal buffers, if the\n         * state is already synchronized, we will remain synchronized.\n         * Additionally, the probability that we miss a synchronization point is\n         * low: RSYNC_LENGTH / targetSectionSize.\n         */\n        return syncPoint;\n    /* Initialize the loop variables. */\n    if (mtctx->inBuff.filled >= RSYNC_LENGTH) {\n        /* We have enough bytes buffered to initialize the hash.\n         * Start scanning at the beginning of the input.\n         */\n        pos = 0;\n        prev = (BYTE const*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled - RSYNC_LENGTH;\n        hash = ZSTD_rollingHash_compute(prev, RSYNC_LENGTH);\n    } else {\n        /* We don't have enough bytes buffered to initialize the hash, but\n         * we know we have at least RSYNC_LENGTH bytes total.\n         * Start scanning after the first RSYNC_LENGTH bytes less the bytes\n         * already buffered.\n         */\n        pos = RSYNC_LENGTH - mtctx->inBuff.filled;\n        prev = (BYTE const*)mtctx->inBuff.buffer.start - pos;\n        hash = ZSTD_rollingHash_compute(mtctx->inBuff.buffer.start, mtctx->inBuff.filled);\n        hash = ZSTD_rollingHash_append(hash, istart, pos);\n    }\n    /* Starting with the hash of the previous RSYNC_LENGTH bytes, roll\n     * through the input. If we hit a synchronization point, then cut the\n     * job off, and tell the compressor to flush the job. Otherwise, load\n     * all the bytes and continue as normal.\n     * If we go too long without a synchronization point (targetSectionSize)\n     * then a block will be emitted anyways, but this is okay, since if we\n     * are already synchronized we will remain synchronized.\n     */\n    for (; pos < syncPoint.toLoad; ++pos) {\n        BYTE const toRemove = pos < RSYNC_LENGTH ? prev[pos] : istart[pos - RSYNC_LENGTH];\n        /* if (pos >= RSYNC_LENGTH) assert(ZSTD_rollingHash_compute(istart + pos - RSYNC_LENGTH, RSYNC_LENGTH) == hash); */\n        hash = ZSTD_rollingHash_rotate(hash, toRemove, istart[pos], primePower);\n        if ((hash & hitMask) == hitMask) {\n            syncPoint.toLoad = pos + 1;\n            syncPoint.flush = 1;\n            break;\n        }\n    }\n    return syncPoint;\n}\n\nsize_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx)\n{\n    size_t hintInSize = mtctx->targetSectionSize - mtctx->inBuff.filled;\n    if (hintInSize==0) hintInSize = mtctx->targetSectionSize;\n    return hintInSize;\n}\n\n/** ZSTDMT_compressStream_generic() :\n *  internal use only - exposed to be invoked from zstd_compress.c\n *  assumption : output and input are valid (pos <= size)\n * @return : minimum amount of data remaining to flush, 0 if none */\nsize_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,\n                                     ZSTD_outBuffer* output,\n                                     ZSTD_inBuffer* input,\n                                     ZSTD_EndDirective endOp)\n{\n    unsigned forwardInputProgress = 0;\n    DEBUGLOG(5, \"ZSTDMT_compressStream_generic (endOp=%u, srcSize=%u)\",\n                (U32)endOp, (U32)(input->size - input->pos));\n    assert(output->pos <= output->size);\n    assert(input->pos  <= input->size);\n\n    if (mtctx->singleBlockingThread) {  /* delegate to single-thread (synchronous) */\n        return ZSTD_compressStream2(mtctx->cctxPool->cctx[0], output, input, endOp);\n    }\n\n    if ((mtctx->frameEnded) && (endOp==ZSTD_e_continue)) {\n        /* current frame being ended. Only flush/end are allowed */\n        return ERROR(stage_wrong);\n    }\n\n    /* single-pass shortcut (note : synchronous-mode) */\n    if ( (!mtctx->params.rsyncable)   /* rsyncable mode is disabled */\n      && (mtctx->nextJobID == 0)      /* just started */\n      && (mtctx->inBuff.filled == 0)  /* nothing buffered */\n      && (!mtctx->jobReady)           /* no job already created */\n      && (endOp == ZSTD_e_end)        /* end order */\n      && (output->size - output->pos >= ZSTD_compressBound(input->size - input->pos)) ) { /* enough space in dst */\n        size_t const cSize = ZSTDMT_compress_advanced_internal(mtctx,\n                (char*)output->dst + output->pos, output->size - output->pos,\n                (const char*)input->src + input->pos, input->size - input->pos,\n                mtctx->cdict, mtctx->params);\n        if (ZSTD_isError(cSize)) return cSize;\n        input->pos = input->size;\n        output->pos += cSize;\n        mtctx->allJobsCompleted = 1;\n        mtctx->frameEnded = 1;\n        return 0;\n    }\n\n    /* fill input buffer */\n    if ( (!mtctx->jobReady)\n      && (input->size > input->pos) ) {   /* support NULL input */\n        if (mtctx->inBuff.buffer.start == NULL) {\n            assert(mtctx->inBuff.filled == 0); /* Can't fill an empty buffer */\n            if (!ZSTDMT_tryGetInputRange(mtctx)) {\n                /* It is only possible for this operation to fail if there are\n                 * still compression jobs ongoing.\n                 */\n                DEBUGLOG(5, \"ZSTDMT_tryGetInputRange failed\");\n                assert(mtctx->doneJobID != mtctx->nextJobID);\n            } else\n                DEBUGLOG(5, \"ZSTDMT_tryGetInputRange completed successfully : mtctx->inBuff.buffer.start = %p\", mtctx->inBuff.buffer.start);\n        }\n        if (mtctx->inBuff.buffer.start != NULL) {\n            syncPoint_t const syncPoint = findSynchronizationPoint(mtctx, *input);\n            if (syncPoint.flush && endOp == ZSTD_e_continue) {\n                endOp = ZSTD_e_flush;\n            }\n            assert(mtctx->inBuff.buffer.capacity >= mtctx->targetSectionSize);\n            DEBUGLOG(5, \"ZSTDMT_compressStream_generic: adding %u bytes on top of %u to buffer of size %u\",\n                        (U32)syncPoint.toLoad, (U32)mtctx->inBuff.filled, (U32)mtctx->targetSectionSize);\n            memcpy((char*)mtctx->inBuff.buffer.start + mtctx->inBuff.filled, (const char*)input->src + input->pos, syncPoint.toLoad);\n            input->pos += syncPoint.toLoad;\n            mtctx->inBuff.filled += syncPoint.toLoad;\n            forwardInputProgress = syncPoint.toLoad>0;\n        }\n        if ((input->pos < input->size) && (endOp == ZSTD_e_end))\n            endOp = ZSTD_e_flush;   /* can't end now : not all input consumed */\n    }\n\n    if ( (mtctx->jobReady)\n      || (mtctx->inBuff.filled >= mtctx->targetSectionSize)  /* filled enough : let's compress */\n      || ((endOp != ZSTD_e_continue) && (mtctx->inBuff.filled > 0))  /* something to flush : let's go */\n      || ((endOp == ZSTD_e_end) && (!mtctx->frameEnded)) ) {   /* must finish the frame with a zero-size block */\n        size_t const jobSize = mtctx->inBuff.filled;\n        assert(mtctx->inBuff.filled <= mtctx->targetSectionSize);\n        FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, jobSize, endOp) );\n    }\n\n    /* check for potential compressed data ready to be flushed */\n    {   size_t const remainingToFlush = ZSTDMT_flushProduced(mtctx, output, !forwardInputProgress, endOp); /* block if there was no forward input progress */\n        if (input->pos < input->size) return MAX(remainingToFlush, 1);  /* input not consumed : do not end flush yet */\n        DEBUGLOG(5, \"end of ZSTDMT_compressStream_generic: remainingToFlush = %u\", (U32)remainingToFlush);\n        return remainingToFlush;\n    }\n}\n\n\nsize_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input)\n{\n    FORWARD_IF_ERROR( ZSTDMT_compressStream_generic(mtctx, output, input, ZSTD_e_continue) );\n\n    /* recommended next input size : fill current input buffer */\n    return mtctx->targetSectionSize - mtctx->inBuff.filled;   /* note : could be zero when input buffer is fully filled and no more availability to create new job */\n}\n\n\nstatic size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_EndDirective endFrame)\n{\n    size_t const srcSize = mtctx->inBuff.filled;\n    DEBUGLOG(5, \"ZSTDMT_flushStream_internal\");\n\n    if ( mtctx->jobReady     /* one job ready for a worker to pick up */\n      || (srcSize > 0)       /* still some data within input buffer */\n      || ((endFrame==ZSTD_e_end) && !mtctx->frameEnded)) {  /* need a last 0-size block to end frame */\n           DEBUGLOG(5, \"ZSTDMT_flushStream_internal : create a new job (%u bytes, end:%u)\",\n                        (U32)srcSize, (U32)endFrame);\n        FORWARD_IF_ERROR( ZSTDMT_createCompressionJob(mtctx, srcSize, endFrame) );\n    }\n\n    /* check if there is any data available to flush */\n    return ZSTDMT_flushProduced(mtctx, output, 1 /* blockToFlush */, endFrame);\n}\n\n\nsize_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output)\n{\n    DEBUGLOG(5, \"ZSTDMT_flushStream\");\n    if (mtctx->singleBlockingThread)\n        return ZSTD_flushStream(mtctx->cctxPool->cctx[0], output);\n    return ZSTDMT_flushStream_internal(mtctx, output, ZSTD_e_flush);\n}\n\nsize_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output)\n{\n    DEBUGLOG(4, \"ZSTDMT_endStream\");\n    if (mtctx->singleBlockingThread)\n        return ZSTD_endStream(mtctx->cctxPool->cctx[0], output);\n    return ZSTDMT_flushStream_internal(mtctx, output, ZSTD_e_end);\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/Zstd/Sources/zstdmt_compress.h",
    "content": "/*\n * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.\n * All rights reserved.\n *\n * This source code is licensed under both the BSD-style license (found in the\n * LICENSE file in the root directory of this source tree) and the GPLv2 (found\n * in the COPYING file in the root directory of this source tree).\n * You may select, at your option, one of the above-listed licenses.\n */\n\n #ifndef ZSTDMT_COMPRESS_H\n #define ZSTDMT_COMPRESS_H\n\n #if defined (__cplusplus)\n extern \"C\" {\n #endif\n\n\n/* Note : This is an internal API.\n *        These APIs used to be exposed with ZSTDLIB_API,\n *        because it used to be the only way to invoke MT compression.\n *        Now, it's recommended to use ZSTD_compress2 and ZSTD_compressStream2()\n *        instead.\n *\n *        If you depend on these APIs and can't switch, then define\n *        ZSTD_LEGACY_MULTITHREADED_API when making the dynamic library.\n *        However, we may completely remove these functions in a future\n *        release, so please switch soon.\n *\n *        This API requires ZSTD_MULTITHREAD to be defined during compilation,\n *        otherwise ZSTDMT_createCCtx*() will fail.\n */\n\n#ifdef ZSTD_LEGACY_MULTITHREADED_API\n#  define ZSTDMT_API ZSTDLIB_API\n#else\n#  define ZSTDMT_API\n#endif\n\n/* ===   Dependencies   === */\n#include <stddef.h>                /* size_t */\n#define ZSTD_STATIC_LINKING_ONLY   /* ZSTD_parameters */\n#include \"zstd.h\"            /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */\n\n\n/* ===   Constants   === */\n#ifndef ZSTDMT_NBWORKERS_MAX\n#  define ZSTDMT_NBWORKERS_MAX 200\n#endif\n#ifndef ZSTDMT_JOBSIZE_MIN\n#  define ZSTDMT_JOBSIZE_MIN (1 MB)\n#endif\n#define ZSTDMT_JOBLOG_MAX   (MEM_32bits() ? 29 : 30)\n#define ZSTDMT_JOBSIZE_MAX  (MEM_32bits() ? (512 MB) : (1024 MB))\n\n\n/* ===   Memory management   === */\ntypedef struct ZSTDMT_CCtx_s ZSTDMT_CCtx;\n/* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */\nZSTDMT_API ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbWorkers);\n/* Requires ZSTD_MULTITHREAD to be defined during compilation, otherwise it will return NULL. */\nZSTDMT_API ZSTDMT_CCtx* ZSTDMT_createCCtx_advanced(unsigned nbWorkers,\n                                                    ZSTD_customMem cMem);\nZSTDMT_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx);\n\nZSTDMT_API size_t ZSTDMT_sizeof_CCtx(ZSTDMT_CCtx* mtctx);\n\n\n/* ===   Simple one-pass compression function   === */\n\nZSTDMT_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,\n                                       void* dst, size_t dstCapacity,\n                                 const void* src, size_t srcSize,\n                                       int compressionLevel);\n\n\n\n/* ===   Streaming functions   === */\n\nZSTDMT_API size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel);\nZSTDMT_API size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize);  /**< if srcSize is not known at reset time, use ZSTD_CONTENTSIZE_UNKNOWN. Note: for compatibility with older programs, 0 means the same as ZSTD_CONTENTSIZE_UNKNOWN, but it will change in the future to mean \"empty\" */\n\nZSTDMT_API size_t ZSTDMT_nextInputSizeHint(const ZSTDMT_CCtx* mtctx);\nZSTDMT_API size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input);\n\nZSTDMT_API size_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output);   /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */\nZSTDMT_API size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output);     /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */\n\n\n/* ===   Advanced functions and parameters  === */\n\nZSTDMT_API size_t ZSTDMT_compress_advanced(ZSTDMT_CCtx* mtctx,\n                                          void* dst, size_t dstCapacity,\n                                    const void* src, size_t srcSize,\n                                    const ZSTD_CDict* cdict,\n                                          ZSTD_parameters params,\n                                          int overlapLog);\n\nZSTDMT_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx,\n                                        const void* dict, size_t dictSize,   /* dict can be released after init, a local copy is preserved within zcs */\n                                        ZSTD_parameters params,\n                                        unsigned long long pledgedSrcSize);  /* pledgedSrcSize is optional and can be zero == unknown */\n\nZSTDMT_API size_t ZSTDMT_initCStream_usingCDict(ZSTDMT_CCtx* mtctx,\n                                        const ZSTD_CDict* cdict,\n                                        ZSTD_frameParameters fparams,\n                                        unsigned long long pledgedSrcSize);  /* note : zero means empty */\n\n/* ZSTDMT_parameter :\n * List of parameters that can be set using ZSTDMT_setMTCtxParameter() */\ntypedef enum {\n    ZSTDMT_p_jobSize,     /* Each job is compressed in parallel. By default, this value is dynamically determined depending on compression parameters. Can be set explicitly here. */\n    ZSTDMT_p_overlapLog,  /* Each job may reload a part of previous job to enhance compression ratio; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window. This is a \"sticky\" parameter : its value will be re-used on next compression job */\n    ZSTDMT_p_rsyncable    /* Enables rsyncable mode. */\n} ZSTDMT_parameter;\n\n/* ZSTDMT_setMTCtxParameter() :\n * allow setting individual parameters, one at a time, among a list of enums defined in ZSTDMT_parameter.\n * The function must be called typically after ZSTD_createCCtx() but __before ZSTDMT_init*() !__\n * Parameters not explicitly reset by ZSTDMT_init*() remain the same in consecutive compression sessions.\n * @return : 0, or an error code (which can be tested using ZSTD_isError()) */\nZSTDMT_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int value);\n\n/* ZSTDMT_getMTCtxParameter() :\n * Query the ZSTDMT_CCtx for a parameter value.\n * @return : 0, or an error code (which can be tested using ZSTD_isError()) */\nZSTDMT_API size_t ZSTDMT_getMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSTDMT_parameter parameter, int* value);\n\n\n/*! ZSTDMT_compressStream_generic() :\n *  Combines ZSTDMT_compressStream() with optional ZSTDMT_flushStream() or ZSTDMT_endStream()\n *  depending on flush directive.\n * @return : minimum amount of data still to be flushed\n *           0 if fully flushed\n *           or an error code\n *  note : needs to be init using any ZSTD_initCStream*() variant */\nZSTDMT_API size_t ZSTDMT_compressStream_generic(ZSTDMT_CCtx* mtctx,\n                                                ZSTD_outBuffer* output,\n                                                ZSTD_inBuffer* input,\n                                                ZSTD_EndDirective endOp);\n\n\n/* ========================================================\n * ===  Private interface, for use by ZSTD_compress.c   ===\n * ===  Not exposed in libzstd. Never invoke directly   ===\n * ======================================================== */\n\n /*! ZSTDMT_toFlushNow()\n  *  Tell how many bytes are ready to be flushed immediately.\n  *  Probe the oldest active job (not yet entirely flushed) and check its output buffer.\n  *  If return 0, it means there is no active job,\n  *  or, it means oldest job is still active, but everything produced has been flushed so far,\n  *  therefore flushing is limited by speed of oldest job. */\nsize_t ZSTDMT_toFlushNow(ZSTDMT_CCtx* mtctx);\n\n/*! ZSTDMT_CCtxParam_setMTCtxParameter()\n *  like ZSTDMT_setMTCtxParameter(), but into a ZSTD_CCtx_Params */\nsize_t ZSTDMT_CCtxParam_setMTCtxParameter(ZSTD_CCtx_params* params, ZSTDMT_parameter parameter, int value);\n\n/*! ZSTDMT_CCtxParam_setNbWorkers()\n *  Set nbWorkers, and clamp it.\n *  Also reset jobSize and overlapLog */\nsize_t ZSTDMT_CCtxParam_setNbWorkers(ZSTD_CCtx_params* params, unsigned nbWorkers);\n\n/*! ZSTDMT_updateCParams_whileCompressing() :\n *  Updates only a selected set of compression parameters, to remain compatible with current frame.\n *  New parameters will be applied to next compression job. */\nvoid ZSTDMT_updateCParams_whileCompressing(ZSTDMT_CCtx* mtctx, const ZSTD_CCtx_params* cctxParams);\n\n/*! ZSTDMT_getFrameProgression():\n *  tells how much data has been consumed (input) and produced (output) for current frame.\n *  able to count progression inside worker threads.\n */\nZSTD_frameProgression ZSTDMT_getFrameProgression(ZSTDMT_CCtx* mtctx);\n\n\n/*! ZSTDMT_initCStream_internal() :\n *  Private use only. Init streaming operation.\n *  expects params to be valid.\n *  must receive dict, or cdict, or none, but not both.\n *  @return : 0, or an error code */\nsize_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,\n                    const void* dict, size_t dictSize, ZSTD_dictContentType_e dictContentType,\n                    const ZSTD_CDict* cdict,\n                    ZSTD_CCtx_params params, unsigned long long pledgedSrcSize);\n\n\n#if defined (__cplusplus)\n}\n#endif\n\n#endif   /* ZSTDMT_COMPRESS_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Package.swift",
    "content": "// swift-tools-version:5.0\n// The swift-tools-version declares the minimum version of Swift required to build this package.\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"KatanaParser\",\n    products: [\n        .library(name: \"KatanaParser\", targets: [\"KatanaParser\"])\n    ],\n    targets: [\n        // Targets are the basic building blocks of a package. A target can define a module or a test suite.\n        // Targets can depend on other targets in this package, and on products in packages which this package depends on.\n        .target(\n            name: \"KatanaParser\",\n            dependencies: [],\n            path: \"Sources\")\n    ]\n)\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/README",
    "content": "From https://github.com/hackers-painters/katana-parser/commit/f410834ca549bcfec5d556ae28f1a604108da12a"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/foundation.c",
    "content": "//\n//  foundation.c\n//  Katana\n//\n//  Created by QFish on 3/19/15.\n//  Copyright (c) 2015 QFish. All rights reserved.\n//\n\n#include \"foundation.h\"\n#include \"parser.h\"\n\n#include <string.h>\n#include <strings.h>\n#include <stdbool.h>\n#include <assert.h>\n\n//#undef\tassert\n//#define assert(x)\n\nstruct KatanaInternalParser;\n\nconst KatanaParserString kKatanaAsteriskString = {\"*\", 1};\n\nstatic const size_t kDefaultStringBufferSize = 12;\n\nstatic void maybe_resize_string(struct KatanaInternalParser* parser,\n                                size_t additional_chars,\n                                KatanaParserString* str) {\n    size_t new_length = str->length + additional_chars;\n    size_t new_capacity = str->capacity;\n    while (new_capacity < new_length) {\n        new_capacity *= 2;\n    }\n    if (new_capacity != str->capacity) {\n        char* new_data = katana_parser_allocate(parser, new_capacity);\n        memset(new_data, 0, str->length);\n        memcpy(new_data, str->data, str->length);\n        katana_parser_deallocate(parser, str->data);\n        str->data = new_data;\n        str->capacity = new_capacity;\n    }\n}\n\nvoid katana_string_init(struct KatanaInternalParser* parser,\n                        KatanaParserString* output) {\n    output->data = katana_parser_allocate(parser, kDefaultStringBufferSize);\n    memset( output->data, 0, sizeof(kDefaultStringBufferSize) );\n    output->length = 0;\n    output->capacity = kDefaultStringBufferSize;\n}\n\nvoid katana_string_append_characters(struct KatanaInternalParser* parser,\n                                     const char* str, KatanaParserString* output)\n{\n    size_t len = strlen(str);\n    maybe_resize_string(parser, len, output);\n    memcpy(output->data + output->length, str, len);\n    output->length += len;\n}\n\nvoid katana_string_prepend_characters(struct KatanaInternalParser* parser,\n                                      const char* str,\n                                      KatanaParserString* output)\n{\n    size_t len = strlen(str);\n    size_t new_length = output->length + len;\n    char* new_data = katana_parser_allocate(parser, new_length);\n    memcpy(new_data, str, len);\n    memcpy(new_data+len, output->data, output->length);\n    katana_parser_deallocate(parser, output->data);\n    output->data = new_data;\n    output->length = new_length;\n    output->capacity = new_length;\n}\n\nvoid katana_string_append_string(struct KatanaInternalParser* parser,\n                                 KatanaParserString* str,\n                                 KatanaParserString* output) {\n    maybe_resize_string(parser, str->length, output);\n    memcpy(output->data + output->length, str->data, str->length);\n    output->length += str->length;\n}\n\nbool katana_string_has_prefix(const char* str, const char* prefix)\n{\n    size_t pre_len = strlen(prefix);\n    size_t str_len = strlen(str);\n    return pre_len <= str_len && strncasecmp(prefix, str, pre_len);\n}\n\nvoid katana_string_to_lowercase(struct KatanaInternalParser* parser,\n                                KatanaParserString* str)\n{\n    if ( !str )\n        return;\n    // FIXME: @(QFish) the char* in string piece is const, to find a better way\n    char *c = (char*)str->data;\n    for (int i=0; i < str->length; i++) {\n        *c = tolower(*c);\n        c++;\n    }\n}\n\n\n\nconst char* katana_string_to_characters(struct KatanaInternalParser * parser, const KatanaParserString* str)\n{\n    assert(NULL != str);\n    if (NULL == str)\n        return NULL;\n    \n    char* buffer = katana_parser_allocate(parser, sizeof(char) * (str->length + 1));\n    memcpy(buffer, str->data, str->length);\n    buffer[str->length] = '\\0';\n    return buffer;\n}\n\nconst char* katana_string_to_characters_with_prefix_char(struct KatanaInternalParser * parser, const KatanaParserString* str, const char prefix)\n{\n    assert(str);\n    if (NULL == str)\n        return NULL;\n    \n    char* buffer = katana_parser_allocate(parser, sizeof(char) * (str->length + 2));\n    memcpy((buffer + 1), str->data, str->length);\n    buffer[0] = prefix;\n    buffer[str->length] = '\\0';\n    return buffer;\n}\n\n/**\n * Array\n */\nvoid katana_array_init(struct KatanaInternalParser* parser,\n                       size_t initial_capacity, KatanaArray* array) {\n    array->length = 0;\n    array->capacity = (unsigned int)initial_capacity;\n    if (initial_capacity > 0) {\n        array->data = katana_parser_allocate(parser, sizeof(void*) * initial_capacity);\n    } else {\n        array->data = NULL;\n    }\n}\n\nvoid katana_array_destroy(struct KatanaInternalParser* parser,\n                          KatanaArray* array) {\n    if (array->capacity > 0) {\n        katana_parser_deallocate(parser, array->data);\n    }\n}\n\nstatic void enlarge_array_if_full(struct KatanaInternalParser* parser,\n                                  KatanaArray* array) {\n    if (array->length >= array->capacity) {\n        if (array->capacity) {\n            size_t old_num_bytes = sizeof(void*) * array->capacity;\n            array->capacity *= 2;\n            size_t num_bytes = sizeof(void*) * array->capacity;\n            void** temp = katana_parser_allocate(parser, num_bytes);\n            memcpy(temp, array->data, old_num_bytes);\n            katana_parser_deallocate(parser, array->data);\n            array->data = temp;\n        } else {\n            // 0-capacity array; no previous array to deallocate.\n            array->capacity = 2;\n            array->data = katana_parser_allocate(parser, sizeof(void*) * array->capacity);\n        }\n    }\n}\n\nvoid katana_array_add(struct KatanaInternalParser* parser,\n                      void* element, KatanaArray* array) {\n    enlarge_array_if_full(parser, array);\n    assert(array->data);\n    assert(array->length < array->capacity);\n    array->data[array->length++] = element;\n}\n\nvoid* katana_array_pop(struct KatanaInternalParser* parser,\n                       KatanaArray* array) {\n    if (array->length == 0) {\n        return NULL;\n    }\n    return array->data[--array->length];\n}\n\nint katana_array_index_of(KatanaArray* array, void* element) {\n    for (int i = 0; i < array->length; ++i) {\n        if (array->data[i] == element) {\n            return i;\n        }\n    }\n    return -1;\n}\n\nvoid katana_array_insert_at(struct KatanaInternalParser* parser,\n                            void* element, int index,\n                            KatanaArray* array) {\n    assert(index >= 0);\n    assert(index <= array->length);\n    enlarge_array_if_full(parser, array);\n    ++array->length;\n    memmove(&array->data[index + 1], &array->data[index],\n            sizeof(void*) * (array->length - index - 1));\n    array->data[index] = element;\n}\n\nvoid katana_array_remove(struct KatanaInternalParser* parser,\n                         void* node, KatanaArray* array) {\n    int index = katana_array_index_of(array, node);\n    if (index == -1) {\n        return;\n    }\n    katana_array_remove_at(parser, index, array);\n}\n\nvoid* katana_array_remove_at(struct KatanaInternalParser* parser,\n                             int index, KatanaArray* array) {\n    assert(index >= 0);\n    assert(index < array->length);\n    void* result = array->data[index];\n    memmove(&array->data[index], &array->data[index + 1],\n            sizeof(void*) * (array->length - index - 1));\n    --array->length;\n    return result;\n}\n\n/**\n *  An alloc / free method\n */\nvoid* katana_parser_allocate(struct KatanaInternalParser* parser, size_t size) {\n    return parser->options->allocator(parser->options->userdata, size);\n}\n\nvoid katana_parser_deallocate(struct KatanaInternalParser* parser, void* ptr) {\n    parser->options->deallocator(parser->options->userdata, ptr);\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/include/foundation.h",
    "content": "/**\n * Copyright (c) 2015 QFish <im@qfi.sh>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n#ifndef __Katana__foundation__\n#define __Katana__foundation__\n\n#include <stdio.h>\n#include <ctype.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include \"katana.h\"\n    \nstruct KatanaInternalParser;\n\n/**\n *  Positon, for error debug\n */\ntypedef struct {\n    unsigned int line;\n    unsigned int column;\n    unsigned int offset;\n} KatanaSourcePosition;\n\n/**\n *  String\n */\ntypedef struct {\n    char* data;\n    size_t length;\n    size_t capacity;\n} KatanaParserString;\n\nextern const KatanaParserString kKatanaAsteriskString;\n\nvoid katana_string_to_lowercase(struct KatanaInternalParser* parser, KatanaParserString* string);\n\n// Initializes a new KatanaParserString.\nvoid katana_string_init(struct KatanaInternalParser* parser, KatanaParserString* output);\n\n// Appends some characters onto the end of the KatanaParserString.\nvoid katana_string_append_characters(struct KatanaInternalParser* parser, const char* str, KatanaParserString* output);\n\n// Prepends some characters at the start of the KatanaParserString.\nvoid katana_string_prepend_characters(struct KatanaInternalParser* parser, const char* str, KatanaParserString* output);\n\n// Transforms a KatanaParserString to characters.\nconst char* katana_string_to_characters(struct KatanaInternalParser * parser, const KatanaParserString* str);\n// Transforms a KatanaParserString to characters with a char prepended at the start of the KatanaParserString.\nconst char* katana_string_to_characters_with_prefix_char(struct KatanaInternalParser * parser, const KatanaParserString* str, const char prefix);\n    \n// Appends a string onto the end of the KatanaParserString.\nvoid katana_string_append_string(struct KatanaInternalParser* parser, KatanaParserString* str, KatanaParserString* output);\n// Returns a bool value that indicates whether a given string matches the beginning characters of the receiver.\nbool katana_string_has_prefix(const char* str, const char* prefix);\n\n/**\n *  Number\n */\ntypedef struct {\n    KatanaParserString raw;\n    double val;\n} KatanaParserNumber;\n\n/**\n *  Array \n */\n// Initializes a new KatanaArray with the specified initial capacity.\nvoid katana_array_init(struct KatanaInternalParser* parser, size_t initial_capacity,\n                       KatanaArray* array);\n\n// Frees the memory used by an KatanaArray.  Does not free the contained\n// pointers, but you should free the pointers if necessary.\nvoid katana_array_destroy(struct KatanaInternalParser* parser, KatanaArray* array);\n\n// Adds a new element to an KatanaArray.\nvoid katana_array_add(struct KatanaInternalParser* parser, void* element, KatanaArray* array);\n\n// Removes and returns the element most recently added to the KatanaArray.\n// Ownership is transferred to caller.  Capacity is unchanged.  If the array is\n// empty, NULL is returned.\nvoid* katana_array_pop(struct KatanaInternalParser* parser, KatanaArray* array);\n\n// Inserts an element at a specific index.  This is potentially O(N) time, but\n// is necessary for some of the spec's behavior.\nvoid katana_array_insert_at(struct KatanaInternalParser* parser, void* element, int index,\n                            KatanaArray* array);\n\n// Removes an element from the array, or does nothing if the element is not in\n// the array.\nvoid katana_array_remove(struct KatanaInternalParser* parser, void* element, KatanaArray* array);\n\n// Removes and returns an element at a specific index.  Note that this is\n// potentially O(N) time and should be used sparingly.\nvoid* katana_array_remove_at(struct KatanaInternalParser* parser, int index, KatanaArray* array);\n\n/**\n *  An alloc / free method wrapper\n */\nvoid* katana_parser_allocate(struct KatanaInternalParser* parser, size_t size);\nvoid katana_parser_deallocate(struct KatanaInternalParser* parser, void* ptr);\n    \n#ifdef __cplusplus\n}\n#endif\n\n\n#endif /* defined(__Katana__foundation__) */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/include/katana.h",
    "content": "/**\n * Copyright (c) 2015 QFish <im@qfi.sh>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n// CSS Spec: http://www.w3.org/TR/css-syntax-3/\n\n#ifndef __Katana__katana__\n#define __Katana__katana__\n\n#include <stdio.h>\n#include <stdbool.h>\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define KATANA_ERROR_MESSAGE_SIZE 100\n\ntypedef enum {\n    KatanaRuleUnkown,\n    KatanaRuleStyle,\n    KatanaRuleImport,\n    KatanaRuleMedia,\n    KatanaRuleFontFace,\n    KatanaRuleSupports,\n    KatanaRuleKeyframes,\n    KatanaRuleCharset,\n    KatanaRuleHost,\n} KatanaRuleType;\n\ntypedef enum {\n    KatanaMediaQueryRestrictorNone,\n    KatanaMediaQueryRestrictorOnly,\n    KatanaMediaQueryRestrictorNot,\n} KatanaMediaQueryRestrictor;\n\ntypedef enum {\n    KatanaSelectorMatchUnknown = 0,\n    KatanaSelectorMatchTag,                 // Example: div\n    KatanaSelectorMatchId,                  // Example: #id\n    KatanaSelectorMatchClass,               // example: .class\n    KatanaSelectorMatchPseudoClass,         // Example:  :nth-child(2)\n    KatanaSelectorMatchPseudoElement,       // Example: ::first-line\n    KatanaSelectorMatchPagePseudoClass,     // ??\n    KatanaSelectorMatchAttributeExact,      // Example: E[foo=\"bar\"]\n    KatanaSelectorMatchAttributeSet,        // Example: E[foo]\n    KatanaSelectorMatchAttributeList,       // Example: E[foo~=\"bar\"]\n    KatanaSelectorMatchAttributeHyphen,     // Example: E[foo|=\"bar\"]\n    KatanaSelectorMatchAttributeContain,    // css3: E[foo*=\"bar\"]\n    KatanaSelectorMatchAttributeBegin,      // css3: E[foo^=\"bar\"]\n    KatanaSelectorMatchAttributeEnd,        // css3: E[foo$=\"bar\"]\n    KatanaSelectorMatchFirstAttribute = KatanaSelectorMatchAttributeExact,\n} KatanaSelectorMatch;\n\ntypedef enum {\n    KatanaSelectorRelationSubSelector,      // \"No space\" combinator\n    KatanaSelectorRelationDescendant,       // \"Space\" combinator\n    KatanaSelectorRelationChild,            // > combinator\n    KatanaSelectorRelationDirectAdjacent,   // + combinator\n    KatanaSelectorRelationIndirectAdjacent, // ~ combinator\n    KatanaSelectorRelationShadowPseudo,     // Special case of shadow DOM pseudo elements / shadow pseudo element\n    KatanaSelectorRelationShadowDeep        // /shadow-deep/ combinator\n} KatanaSelectorRelation;\n    \ntypedef enum {\n    KatanaPseudoNotParsed,\n    KatanaPseudoUnknown,\n    KatanaPseudoEmpty,\n    KatanaPseudoFirstChild,\n    KatanaPseudoFirstOfType,\n    KatanaPseudoLastChild,\n    KatanaPseudoLastOfType,\n    KatanaPseudoOnlyChild,\n    KatanaPseudoOnlyOfType,\n    KatanaPseudoFirstLine,\n    KatanaPseudoFirstLetter,\n    KatanaPseudoNthChild,\n    KatanaPseudoNthOfType,\n    KatanaPseudoNthLastChild,\n    KatanaPseudoNthLastOfType,\n    KatanaPseudoLink,\n    KatanaPseudoVisited,\n    KatanaPseudoAny,\n    KatanaPseudoAnyLink,\n    KatanaPseudoAutofill,\n    KatanaPseudoHover,\n    KatanaPseudoDrag,\n    KatanaPseudoFocus,\n    KatanaPseudoActive,\n    KatanaPseudoChecked,\n    KatanaPseudoEnabled,\n    KatanaPseudoFullPageMedia,\n    KatanaPseudoDefault,\n    KatanaPseudoDisabled,\n    KatanaPseudoOptional,\n    KatanaPseudoRequired,\n    KatanaPseudoReadOnly,\n    KatanaPseudoReadWrite,\n    KatanaPseudoValid,\n    KatanaPseudoInvalid,\n    KatanaPseudoIndeterminate,\n    KatanaPseudoTarget,\n    KatanaPseudoBefore,\n    KatanaPseudoAfter,\n    KatanaPseudoBackdrop,\n    KatanaPseudoLang,\n    KatanaPseudoNot, // :not(selector), selector is Kind of KatanaSelector\n    KatanaPseudoResizer,\n    KatanaPseudoRoot,\n    KatanaPseudoScope,\n    KatanaPseudoScrollbar,\n    KatanaPseudoScrollbarButton,\n    KatanaPseudoScrollbarCorner,\n    KatanaPseudoScrollbarThumb,\n    KatanaPseudoScrollbarTrack,\n    KatanaPseudoScrollbarTrackPiece,\n    KatanaPseudoWindowInactive,\n    KatanaPseudoCornerPresent,\n    KatanaPseudoDecrement,\n    KatanaPseudoIncrement,\n    KatanaPseudoHorizontal,\n    KatanaPseudoVertical,\n    KatanaPseudoStart,\n    KatanaPseudoEnd,\n    KatanaPseudoDoubleButton,\n    KatanaPseudoSingleButton,\n    KatanaPseudoNoButton,\n    KatanaPseudoSelection,\n    KatanaPseudoLeftPage,\n    KatanaPseudoRightPage,\n    KatanaPseudoFirstPage,\n    KatanaPseudoFullScreen,\n    KatanaPseudoFullScreenDocument,\n    KatanaPseudoFullScreenAncestor,\n    KatanaPseudoInRange,\n    KatanaPseudoOutOfRange,\n    KatanaPseudoWebKitCustomElement,\n    KatanaPseudoCue,\n    KatanaPseudoFutureCue,\n    KatanaPseudoPastCue,\n    KatanaPseudoUnresolved,\n    KatanaPseudoContent,\n    KatanaPseudoHost,\n    KatanaPseudoHostContext,\n    KatanaPseudoShadow,\n    KatanaPseudoSpatialNavigationFocus,\n    KatanaPseudoListBox\n} KatanaPseudoType;\n\ntypedef enum {\n    KatanaAttributeMatchTypeCaseSensitive,\n    KatanaAttributeMatchTypeCaseInsensitive,\n} KatanaAttributeMatchType;\n\ntypedef enum {\n    KATANA_VALUE_UNKNOWN = 0,\n    KATANA_VALUE_NUMBER = 1,\n    KATANA_VALUE_PERCENTAGE = 2,\n    KATANA_VALUE_EMS = 3,\n    KATANA_VALUE_EXS = 4,\n\n\t// double\n    KATANA_VALUE_PX = 5,\n    KATANA_VALUE_CM = 6,\n    KATANA_VALUE_MM = 7,\n    KATANA_VALUE_IN = 8,\n    KATANA_VALUE_PT = 9,\n    KATANA_VALUE_PC = 10,\n    KATANA_VALUE_DEG = 11,\n    KATANA_VALUE_RAD = 12,\n    KATANA_VALUE_GRAD = 13,\n    KATANA_VALUE_MS = 14,\n    KATANA_VALUE_S = 15,\n    KATANA_VALUE_HZ = 16,\n    KATANA_VALUE_KHZ = 17,\n    KATANA_VALUE_DIMENSION = 18,\n    KATANA_VALUE_STRING = 19,\n    KATANA_VALUE_URI = 20,\n    KATANA_VALUE_IDENT = 21,\n    KATANA_VALUE_ATTR = 22,\n    KATANA_VALUE_COUNTER = 23,\n    KATANA_VALUE_RECT = 24,\n    KATANA_VALUE_RGBCOLOR = 25,\n\n    KATANA_VALUE_VW = 26,\n    KATANA_VALUE_VH = 27,\n    KATANA_VALUE_VMIN = 28,\n    KATANA_VALUE_VMAX = 29,\n    KATANA_VALUE_DPPX = 30,\n    KATANA_VALUE_DPI = 31,\n    KATANA_VALUE_DPCM = 32,\n    KATANA_VALUE_FR = 33,\n    KATANA_VALUE_UNICODE_RANGE = 102,\n    \n    KATANA_VALUE_PARSER_OPERATOR = 103,\n    KATANA_VALUE_PARSER_INTEGER = 104,\n    KATANA_VALUE_PARSER_HEXCOLOR = 105,\n    KATANA_VALUE_PARSER_FUNCTION = 0x100001,\n    KATANA_VALUE_PARSER_LIST     = 0x100002,\n    KATANA_VALUE_PARSER_Q_EMS    = 0x100003,\n    \n    KATANA_VALUE_PARSER_IDENTIFIER = 106,\n    \n    KATANA_VALUE_TURN = 107,\n    KATANA_VALUE_REMS = 108,\n    KATANA_VALUE_CHS = 109,\n    \n    KATANA_VALUE_COUNTER_NAME = 110,\n    \n    KATANA_VALUE_SHAPE = 111,\n    \n    KATANA_VALUE_QUAD = 112,\n    \n    KATANA_VALUE_CALC = 113,\n    KATANA_VALUE_CALC_PERCENTAGE_WITH_NUMBER = 114,\n    KATANA_VALUE_CALC_PERCENTAGE_WITH_LENGTH = 115,\n    KATANA_VALUE_VARIABLE_NAME = 116,\n    \n    KATANA_VALUE_PROPERTY_ID = 117,\n    KATANA_VALUE_VALUE_ID = 118\n} KatanaValueUnit;\n\n//typedef enum {\n//    KATANA_VALUE_PARSER_OPERATOR = 0x100000,\n//    KATANA_VALUE_PARSER_FUNCTION = 0x100001,\n//    KATANA_VALUE_PARSER_LIST     = 0x100002,\n//    KATANA_VALUE_PARSER_Q_EMS    = 0x100003,\n//} KatanaParserValueUnit;\n\ntypedef enum {\n    KatanaValueInvalid = 0,\n    KatanaValueInherit = 1,\n    KatanaValueInitial = 2,\n    KatanaValueNone = 3,\n    KatanaValueCustom = 0x100010,\n} KatanaValueID;\n\ntypedef enum { KatanaParseError } KatanaErrorType;\n\ntypedef struct {\n    const char* local; // tag local name\n    const char* prefix; // namesapce identifier\n    const char* uri; // namesapce uri\n} KatanaQualifiedName;\n\ntypedef struct {\n  /** Data elements. This points to a dynamically-allocated array of capacity\n   * elements, each a void* to the element itself, remember free each element.\n   */\n  void** data;\n\n  /** Number of elements currently in the array. */\n  unsigned int length;\n\n  /** Current array capacity. */\n  unsigned int capacity;\n\n} KatanaArray;\n\ntypedef struct {\n    const char* encoding;\n    KatanaArray /* KatanaRule */ rules;\n    KatanaArray /* KatanaImportRule */ imports;\n} KatanaStylesheet;\n\ntypedef struct {\n    const char* name;\n    KatanaRuleType type;\n} KatanaRule;\n    \ntypedef struct {\n    KatanaRule base;\n    KatanaArray* /* KatanaSelector */ selectors;\n    KatanaArray* /* KatanaDeclaration */ declarations;\n} KatanaStyleRule;\n\ntypedef struct {\n    const char* comment;\n} KatanaComment; // unused for right\n\n/**\n * The `@font-face` at-rule.\n */\ntypedef struct {\n    KatanaRule base;\n    KatanaArray* /* KatanaDeclaration */ declarations;\n} KatanaFontFaceRule;\n\n/**\n * The `@host` at-rule.\n */\ntypedef struct {\n    KatanaRule base;\n    KatanaArray* /* KatanaRule */ host;\n} KatanaHostRule;\n\n/**\n * The `@import` at-rule.\n */\ntypedef struct {\n    KatanaRule base;\n    /**\n     * The part following `@import `\n     */\n    const char* href;\n    /**\n     * The media list belonging to this import rule\n     */\n    KatanaArray* /* KatanaMediaQuery* */ medias;\n} KatanaImportRule;\n\n/**\n * The `@keyframes` at-rule.\n * Spec: http://www.w3.org/TR/css3-animations/#keyframes\n */\ntypedef struct {\n    KatanaRule base;\n    /**\n     * The vendor prefix in `@keyframes`, or `undefined` if there is none.\n     */\n    const char* name;\n    KatanaArray* /* KatanaKeyframe */ keyframes;\n} KatanaKeyframesRule;\n    \ntypedef struct {\n    KatanaArray* /* KatanaValue: `percentage`, `from`, `to` */ selectors;\n    KatanaArray* /* KatanaDeclaration */ declarations;\n} KatanaKeyframe;\n\n/**\n * The `@media` at-rule.\n */\ntypedef struct {\n    KatanaRule base;\n    /**\n     * The part following `@media `\n     */\n    KatanaArray* medias;\n    /**\n     * An `Array` of nodes with the types `rule`, `comment` and any of the\n     at-rule types.\n     */\n    KatanaArray* /* KatanaRule */ rules;\n} KatanaMediaRule;\n\n/**\n * Media Query Exp List\n * Spec: http://www.w3.org/TR/mediaqueries-4/\n */\n\ntypedef struct {\n    KatanaMediaQueryRestrictor restrictor;\n    const char* type;\n    KatanaArray* expressions;\n    bool ignored;\n} KatanaMediaQuery;\n\ntypedef struct {\n    const char* feature;\n    KatanaArray* values;\n    const char* raw;\n} KatanaMediaQueryExp;\n\ntypedef struct {\n    const char* value;\n    union {\n        struct {\n            int a; // Used for :nth-*\n            int b; // Used for :nth-*\n        } nth;\n        KatanaAttributeMatchType attributeMatchType; // used for attribute selector (with value)\n    } bits;\n    KatanaQualifiedName* attribute;\n    const char* argument; // Used for :contains, :lang, :nth-*\n    KatanaArray* selectors; // Used for :any and :not\n} KatanaSelectorRareData;\n\ntypedef struct KatanaSelector {\n    size_t specificity;\n    KatanaSelectorMatch match;\n    KatanaPseudoType pseudo;\n    KatanaSelectorRelation relation;\n    KatanaQualifiedName* tag;\n    KatanaSelectorRareData* data;\n    struct KatanaSelector* tagHistory;\n} KatanaSelector;\n    \nunsigned katana_calc_specificity_for_selector(KatanaSelector* selector);\n\ntypedef struct {\n\t// property name\n    const char* property;\n\t\n\t// property value\n    KatanaArray* /* KatanaValue */ values;\n    const char* string;\n\n\t// is this property marked important\n    bool important;\n\n\t// origin css text of the property\n    const char* raw;\n} KatanaDeclaration;\n\ntypedef struct {\n    const char* name;\n    KatanaArray* args;\n} KatanaValueFunction;\n\ntypedef struct KatanaValue {\n    KatanaValueID id;\n    bool isInt;\n    union {\n        int iValue;\n        double fValue;\n        const char* string;\n        KatanaValueFunction* function;\n        KatanaArray* list;\n    };\n    KatanaValueUnit unit;\n    const char* raw;\n} KatanaValue;\n\n/**\n * The `@charset` at-rule.\n */\ntypedef struct {\n    KatanaRule base;\n    /**\n     * The encoding information\n     */\n    const char* encoding;\n} KatanaCharsetRule;\n    \ntypedef struct {\n    KatanaErrorType type;\n    int first_line;\n    int first_column;\n    int last_line;\n    int last_column;\n    char message[KATANA_ERROR_MESSAGE_SIZE];\n} KatanaError;\n\n// TODO: @document\n// TODO: @page\n// TODO: @supports\n// TODO: custom-at-rule\n\n/**\n * Parser mode\n */\ntypedef enum KatanaParserMode {\n\t// Normal CSS content used in External CSS files or Internal CSS, may include more than 1 css rules.\n    KatanaParserModeStylesheet,\n\n\t// Single CSS rule like \"@import\", \"selector{...}\"\n    KatanaParserModeRule,\n\n    KatanaParserModeKeyframeRule,\n    KatanaParserModeKeyframeKeyList,\n    KatanaParserModeMediaList,\n\n\t// CSS property value like \"1px\", \"1em\", \"#eee\"\n    KatanaParserModeValue,\n\n\t// CSS selector like \".pages.active\"\n    KatanaParserModeSelector,\n\n\t// Inline stylesheet like \"width: 20px; height: 20px;\"\n    KatanaParserModeDeclarationList,\n} KatanaParserMode;\n    \ntypedef struct KatanaInternalOutput {\n    // Complete CSS string\n    KatanaStylesheet* stylesheet;\n    union {\n        // fragmental CSS string\n        KatanaRule* rule;\n        KatanaKeyframe* keyframe;\n        KatanaArray* keyframe_keys;\n        KatanaArray* values;\n        KatanaArray* medias;\n        KatanaArray* /* KatanaDeclaration */ declarations;\n        KatanaArray* selectors;\n    };\n    KatanaParserMode mode;\n    KatanaArray /* KatanaError */ errors;\n} KatanaOutput;\n\n/**\n *  Parse a complete or fragmental CSS string\n *\n *  @param str  Input CSS string\n *  @param len  Length of the input CSS string\n *  @param mode Parser mode, depends on the input\n *\n *  @return The result of parsing\n */\nKatanaOutput* katana_parse(const char* str, size_t len, KatanaParserMode mode);\n\n/**\n *  Parse a complete CSS file\n *\n *  @param fp `FILE` point to the CSS file\n *\n *  @return The result of parsing\n */\nKatanaOutput* katana_parse_in(FILE* fp);\n\n/**\n *  Free the output\n *\n *  @param output The result of parsing\n */\nvoid katana_destroy_output(KatanaOutput* output);\n\n/**\n *  Print the formatted CSS string\n *\n *  @param output The result of parsing\n *\n *  @return The origin output\n */\nKatanaOutput* katana_dump_output(KatanaOutput* output);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* defined(__Katana__katana__) */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/include/katana.lex.h",
    "content": "#include \"katana.tab.h\"\n\n/* Substitute the type names.  */\n#define YYSTYPE         KATANASTYPE\n#define YYLTYPE         KATANALTYPE\n\n#ifndef katanaHEADER_H\n#define katanaHEADER_H 1\n#define katanaIN_HEADER 1\n\n// #line 6 \"katana.lex.h\"\n\n#define  YY_INT_ALIGNED short int\n\n/* A lexical scanner generated by flex */\n\n#define FLEX_SCANNER\n#define YY_FLEX_MAJOR_VERSION 2\n#define YY_FLEX_MINOR_VERSION 5\n#define YY_FLEX_SUBMINOR_VERSION 37\n#if YY_FLEX_SUBMINOR_VERSION > 0\n#define FLEX_BETA\n#endif\n\n/* First, we deal with  platform-specific or compiler-specific issues. */\n\n/* begin standard C headers. */\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <stdlib.h>\n\n/* end standard C headers. */\n\n/* flex integer type definitions */\n\n#ifndef FLEXINT_H\n#define FLEXINT_H\n\n/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */\n\n#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n\n/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,\n * if you want the limit (max/min) macros for int types. \n */\n#ifndef __STDC_LIMIT_MACROS\n#define __STDC_LIMIT_MACROS 1\n#endif\n\n#include <inttypes.h>\ntypedef int8_t flex_int8_t;\ntypedef uint8_t flex_uint8_t;\ntypedef int16_t flex_int16_t;\ntypedef uint16_t flex_uint16_t;\ntypedef int32_t flex_int32_t;\ntypedef uint32_t flex_uint32_t;\n#else\ntypedef signed char flex_int8_t;\ntypedef short int flex_int16_t;\ntypedef int flex_int32_t;\ntypedef unsigned char flex_uint8_t; \ntypedef unsigned short int flex_uint16_t;\ntypedef unsigned int flex_uint32_t;\n\n/* Limits of integral types. */\n#ifndef INT8_MIN\n#define INT8_MIN               (-128)\n#endif\n#ifndef INT16_MIN\n#define INT16_MIN              (-32767-1)\n#endif\n#ifndef INT32_MIN\n#define INT32_MIN              (-2147483647-1)\n#endif\n#ifndef INT8_MAX\n#define INT8_MAX               (127)\n#endif\n#ifndef INT16_MAX\n#define INT16_MAX              (32767)\n#endif\n#ifndef INT32_MAX\n#define INT32_MAX              (2147483647)\n#endif\n#ifndef UINT8_MAX\n#define UINT8_MAX              (255U)\n#endif\n#ifndef UINT16_MAX\n#define UINT16_MAX             (65535U)\n#endif\n#ifndef UINT32_MAX\n#define UINT32_MAX             (4294967295U)\n#endif\n\n#endif /* ! C99 */\n\n#endif /* ! FLEXINT_H */\n\n#ifdef __cplusplus\n\n/* The \"const\" storage-class-modifier is valid. */\n#define YY_USE_CONST\n\n#else\t/* ! __cplusplus */\n\n/* C99 requires __STDC__ to be defined as 1. */\n#if defined (__STDC__)\n\n#define YY_USE_CONST\n\n#endif\t/* defined (__STDC__) */\n#endif\t/* ! __cplusplus */\n\n#ifdef YY_USE_CONST\n#define yyconst const\n#else\n#define yyconst\n#endif\n\n/* An opaque pointer. */\n#ifndef YY_TYPEDEF_YY_SCANNER_T\n#define YY_TYPEDEF_YY_SCANNER_T\ntypedef void* yyscan_t;\n#endif\n\n/* For convenience, these vars (plus the bison vars far below)\n   are macros in the reentrant scanner. */\n#define yyin yyg->yyin_r\n#define yyout yyg->yyout_r\n#define yyextra yyg->yyextra_r\n#define yyleng yyg->yyleng_r\n#define yytext yyg->yytext_r\n#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)\n#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)\n#define yy_flex_debug yyg->yy_flex_debug_r\n\n/* Size of default input buffer. */\n#ifndef YY_BUF_SIZE\n#define YY_BUF_SIZE 16384\n#endif\n\n#ifndef YY_TYPEDEF_YY_BUFFER_STATE\n#define YY_TYPEDEF_YY_BUFFER_STATE\ntypedef struct yy_buffer_state *YY_BUFFER_STATE;\n#endif\n\n#ifndef YY_TYPEDEF_YY_SIZE_T\n#define YY_TYPEDEF_YY_SIZE_T\ntypedef size_t yy_size_t;\n#endif\n\n#ifndef YY_STRUCT_YY_BUFFER_STATE\n#define YY_STRUCT_YY_BUFFER_STATE\nstruct yy_buffer_state\n\t{\n\tFILE *yy_input_file;\n\n\tchar *yy_ch_buf;\t\t/* input buffer */\n\tchar *yy_buf_pos;\t\t/* current position in input buffer */\n\n\t/* Size of input buffer in bytes, not including room for EOB\n\t * characters.\n\t */\n\tyy_size_t yy_buf_size;\n\n\t/* Number of characters read into yy_ch_buf, not including EOB\n\t * characters.\n\t */\n\tyy_size_t yy_n_chars;\n\n\t/* Whether we \"own\" the buffer - i.e., we know we created it,\n\t * and can realloc() it to grow it, and should free() it to\n\t * delete it.\n\t */\n\tint yy_is_our_buffer;\n\n\t/* Whether this is an \"interactive\" input source; if so, and\n\t * if we're using stdio for input, then we want to use getc()\n\t * instead of fread(), to make sure we stop fetching input after\n\t * each newline.\n\t */\n\tint yy_is_interactive;\n\n\t/* Whether we're considered to be at the beginning of a line.\n\t * If so, '^' rules will be active on the next match, otherwise\n\t * not.\n\t */\n\tint yy_at_bol;\n\n    int yy_bs_lineno; /**< The line count. */\n    int yy_bs_column; /**< The column count. */\n    \n\t/* Whether to try to fill the input buffer when we reach the\n\t * end of it.\n\t */\n\tint yy_fill_buffer;\n\n\tint yy_buffer_status;\n\n\t};\n#endif /* !YY_STRUCT_YY_BUFFER_STATE */\n\nvoid katanarestart (FILE *input_file ,yyscan_t yyscanner );\nvoid katana_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );\nYY_BUFFER_STATE katana_create_buffer (FILE *file,int size ,yyscan_t yyscanner );\nvoid katana_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );\nvoid katana_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );\nvoid katanapush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );\nvoid katanapop_buffer_state (yyscan_t yyscanner );\n\nYY_BUFFER_STATE katana_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );\nYY_BUFFER_STATE katana_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );\nYY_BUFFER_STATE katana_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );\n\nvoid *katanaalloc (yy_size_t ,yyscan_t yyscanner );\nvoid *katanarealloc (void *,yy_size_t ,yyscan_t yyscanner );\nvoid katanafree (void * ,yyscan_t yyscanner );\n\n/* Begin user sect3 */\n\n#define katanawrap(yyscanner) 1\n#define YY_SKIP_YYWRAP\n\n#define yytext_ptr yytext_r\n\n#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n#define INITIAL 0\n#define mediaquery 1\n#define supports 2\n\n#endif\n\n#ifndef YY_NO_UNISTD_H\n/* Special case for \"unistd.h\", since it is non-ANSI. We include it way\n * down here because we want the user's section 1 to have been scanned first.\n * The user has a chance to override it with an option.\n */\n#include <unistd.h>\n#endif\n\n#ifndef YY_EXTRA_TYPE\n#define YY_EXTRA_TYPE void *\n#endif\n\nint katanalex_init (yyscan_t* scanner);\n\nint katanalex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);\n\n/* Accessor methods to globals.\n   These are made visible to non-reentrant scanners for convenience. */\n\nint katanalex_destroy (yyscan_t yyscanner );\n\nint katanaget_debug (yyscan_t yyscanner );\n\nvoid katanaset_debug (int debug_flag ,yyscan_t yyscanner );\n\nYY_EXTRA_TYPE katanaget_extra (yyscan_t yyscanner );\n\nvoid katanaset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );\n\nFILE *katanaget_in (yyscan_t yyscanner );\n\nvoid katanaset_in  (FILE * in_str ,yyscan_t yyscanner );\n\nFILE *katanaget_out (yyscan_t yyscanner );\n\nvoid katanaset_out  (FILE * out_str ,yyscan_t yyscanner );\n\nyy_size_t katanaget_leng (yyscan_t yyscanner );\n\nchar *katanaget_text (yyscan_t yyscanner );\n\nint katanaget_lineno (yyscan_t yyscanner );\n\nvoid katanaset_lineno (int line_number ,yyscan_t yyscanner );\n\nint katanaget_column  (yyscan_t yyscanner );\n\nvoid katanaset_column (int column_no ,yyscan_t yyscanner );\n\nYYSTYPE * katanaget_lval (yyscan_t yyscanner );\n\nvoid katanaset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );\n\n       YYLTYPE *katanaget_lloc (yyscan_t yyscanner );\n    \n        void katanaset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );\n    \n/* Macros after this point can all be overridden by user definitions in\n * section 1.\n */\n\n#ifndef YY_SKIP_YYWRAP\n#ifdef __cplusplus\nextern \"C\" int katanawrap (yyscan_t yyscanner );\n#else\nextern int katanawrap (yyscan_t yyscanner );\n#endif\n#endif\n\n#ifndef yytext_ptr\nstatic void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);\n#endif\n\n#ifdef YY_NEED_STRLEN\nstatic int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);\n#endif\n\n#ifndef YY_NO_INPUT\n\n#endif\n\n/* Amount of stuff to slurp up with each read. */\n#ifndef YY_READ_BUF_SIZE\n#define YY_READ_BUF_SIZE 8192\n#endif\n\n/* Number of entries by which start-condition stack grows. */\n#ifndef YY_START_STACK_INCR\n#define YY_START_STACK_INCR 25\n#endif\n\n/* Default declaration of generated scanner - a define so the user can\n * easily add parameters.\n */\n#ifndef YY_DECL\n#define YY_DECL_IS_OURS 1\n\nextern int katanalex \\\n                (YYSTYPE* yylval_param, YYLTYPE* yylloc, yyscan_t yyscanner, void* parser);\n\n#define YY_DECL int katanalex \\\n                (YYSTYPE * yylval_param, YYLTYPE* yylloc, yyscan_t yyscanner, void* parser)\n\n#endif /* !YY_DECL */\n\n/* yy_get_previous_state - get the state just before the EOB char was reached */\n\n//#undef YY_NEW_FILE\n#undef YY_FLUSH_BUFFER\n#undef yy_set_bol\n#undef yy_new_buffer\n#undef yy_set_interactive\n//#undef YY_DO_BEFORE_ACTION\n\n#ifdef YY_DECL_IS_OURS\n#undef YY_DECL_IS_OURS\n#undef YY_DECL\n#endif\n\n// #line 346 \"katana.lex.h\"\n#undef katanaIN_HEADER\n#endif /* katanaHEADER_H */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/include/katana.tab.h",
    "content": "/* A Bison parser, made by GNU Bison 3.0.4.  */\n\n/* Bison interface for Yacc-like parsers in C\n\n   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n\n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n#ifndef YY_KATANA_KATANA_TAB_H_INCLUDED\n# define YY_KATANA_KATANA_TAB_H_INCLUDED\n/* Debug traces.  */\n#ifndef KATANADEBUG\n# if defined YYDEBUG\n#if YYDEBUG\n#   define KATANADEBUG 1\n#  else\n#   define KATANADEBUG 0\n#  endif\n# else /* ! defined YYDEBUG */\n#  define KATANADEBUG 1\n# endif /* ! defined YYDEBUG */\n#endif  /* ! defined KATANADEBUG */\n#if KATANADEBUG\nextern int katanadebug;\n#endif\n/* \"%code requires\" blocks.  */\n\n\n/*\n*  Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)\n*  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.\n*  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)\n*  Copyright (C) 2008 Eric Seidel <eric@webkit.org>\n*  Copyright (C) 2012 Intel Corporation. All rights reserved.\n*  Copyright (C) 2015 QFish (im@qfi.sh)\n*\n*  This library is free software; you can redistribute it and/or\n*  modify it under the terms of the GNU Lesser General Public\n*  License as published by the Free Software Foundation; either\n*  version 2 of the License, or (at your option) any later version.\n*\n*  This library is distributed in the hope that it will be useful,\n*  but WITHOUT ANY WARRANTY; without even the implied warranty of\n*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n*  Lesser General Public License for more details.\n*\n*  You should have received a copy of the GNU Lesser General Public\n*  License along with this library; if not, write to the Free Software\n*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n*\n*/\n\n#include \"foundation.h\"\n#include \"katana.h\"\n\n\n\n/* Token type.  */\n#ifndef KATANATOKENTYPE\n# define KATANATOKENTYPE\n  enum katanatokentype\n  {\n    TOKEN_EOF = 0,\n    LOWEST_PREC = 258,\n    UNIMPORTANT_TOK = 259,\n    KATANA_CSS_SGML_CD = 260,\n    KATANA_CSS_WHITESPACE = 261,\n    KATANA_CSS_INCLUDES = 262,\n    KATANA_CSS_DASHMATCH = 263,\n    KATANA_CSS_BEGINSWITH = 264,\n    KATANA_CSS_ENDSWITH = 265,\n    KATANA_CSS_CONTAINS = 266,\n    KATANA_CSS_STRING = 267,\n    KATANA_CSS_IDENT = 268,\n    KATANA_CSS_NTH = 269,\n    KATANA_CSS_HEX = 270,\n    KATANA_CSS_IDSEL = 271,\n    KATANA_CSS_IMPORT_SYM = 272,\n    KATANA_CSS_PAGE_SYM = 273,\n    KATANA_CSS_MEDIA_SYM = 274,\n    KATANA_CSS_SUPPORTS_SYM = 275,\n    KATANA_CSS_FONT_FACE_SYM = 276,\n    KATANA_CSS_CHARSET_SYM = 277,\n    KATANA_CSS_NAMESPACE_SYM = 278,\n    KATANA_INTERNAL_DECLS_SYM = 279,\n    KATANA_INTERNAL_MEDIALIST_SYM = 280,\n    KATANA_INTERNAL_RULE_SYM = 281,\n    KATANA_INTERNAL_SELECTOR_SYM = 282,\n    KATANA_INTERNAL_VALUE_SYM = 283,\n    KATANA_INTERNAL_KEYFRAME_RULE_SYM = 284,\n    KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM = 285,\n    KATANA_INTERNAL_SUPPORTS_CONDITION_SYM = 286,\n    KATANA_CSS_KEYFRAMES_SYM = 287,\n    KATANA_CSS_ATKEYWORD = 288,\n    KATANA_CSS_IMPORTANT_SYM = 289,\n    KATANA_CSS_MEDIA_NOT = 290,\n    KATANA_CSS_MEDIA_ONLY = 291,\n    KATANA_CSS_MEDIA_AND = 292,\n    KATANA_CSS_MEDIA_OR = 293,\n    KATANA_CSS_SUPPORTS_NOT = 294,\n    KATANA_CSS_SUPPORTS_AND = 295,\n    KATANA_CSS_SUPPORTS_OR = 296,\n    KATANA_CSS_REMS = 297,\n    KATANA_CSS_CHS = 298,\n    KATANA_CSS_QEMS = 299,\n    KATANA_CSS_EMS = 300,\n    KATANA_CSS_EXS = 301,\n    KATANA_CSS_PXS = 302,\n    KATANA_CSS_CMS = 303,\n    KATANA_CSS_MMS = 304,\n    KATANA_CSS_INS = 305,\n    KATANA_CSS_PTS = 306,\n    KATANA_CSS_PCS = 307,\n    KATANA_CSS_DEGS = 308,\n    KATANA_CSS_RADS = 309,\n    KATANA_CSS_GRADS = 310,\n    KATANA_CSS_TURNS = 311,\n    KATANA_CSS_MSECS = 312,\n    KATANA_CSS_SECS = 313,\n    KATANA_CSS_HERTZ = 314,\n    KATANA_CSS_KHERTZ = 315,\n    KATANA_CSS_DIMEN = 316,\n    KATANA_CSS_INVALIDDIMEN = 317,\n    KATANA_CSS_PERCENTAGE = 318,\n    KATANA_CSS_FLOATTOKEN = 319,\n    KATANA_CSS_INTEGER = 320,\n    KATANA_CSS_VW = 321,\n    KATANA_CSS_VH = 322,\n    KATANA_CSS_VMIN = 323,\n    KATANA_CSS_VMAX = 324,\n    KATANA_CSS_DPPX = 325,\n    KATANA_CSS_DPI = 326,\n    KATANA_CSS_DPCM = 327,\n    KATANA_CSS_FR = 328,\n    KATANA_CSS_URI = 329,\n    KATANA_CSS_FUNCTION = 330,\n    KATANA_CSS_ANYFUNCTION = 331,\n    KATANA_CSS_CUEFUNCTION = 332,\n    KATANA_CSS_NOTFUNCTION = 333,\n    KATANA_CSS_CALCFUNCTION = 334,\n    KATANA_CSS_MINFUNCTION = 335,\n    KATANA_CSS_MAXFUNCTION = 336,\n    KATANA_CSS_HOSTFUNCTION = 337,\n    KATANA_CSS_HOSTCONTEXTFUNCTION = 338,\n    KATANA_CSS_UNICODERANGE = 339\n  };\n#endif\n\n/* Value type.  */\n#if ! defined KATANASTYPE && ! defined KATANASTYPE_IS_DECLARED\n\nunion KATANASTYPE\n{\n\n\n\n    bool boolean;\n    char character;\n    int integer;\n    KatanaParserNumber number;\n    KatanaParserString string;\n\n    KatanaRule* rule;\n    // The content of the three below HeapVectors are guaranteed to be kept alive by\n    // the corresponding parsedRules, floatingMediaQueryExpList, and parsedKeyFrames\n    // lists\n    KatanaArray* ruleList;\n    KatanaArray* mediaQueryExpList;\n    KatanaArray* keyframeRuleList;\n\n    KatanaSelector* selector;\n    KatanaArray* selectorList;\n    // CSSSelector::MarginBoxType marginBox;\n    KatanaSelectorRelation relation;\n    KatanaAttributeMatchType attributeMatchType;\n    KatanaArray* mediaList;\n    KatanaMediaQuery* mediaQuery;\n    KatanaMediaQueryRestrictor mediaQueryRestrictor;\n    KatanaMediaQueryExp* mediaQueryExp;\n    KatanaValue* value;\n    KatanaArray* valueList;\n    KatanaKeyframe* keyframe;\n    KatanaSourcePosition* location;\n\n\n};\n\ntypedef union KATANASTYPE KATANASTYPE;\n# define KATANASTYPE_IS_TRIVIAL 1\n# define KATANASTYPE_IS_DECLARED 1\n#endif\n\n/* Location type.  */\n#if ! defined KATANALTYPE && ! defined KATANALTYPE_IS_DECLARED\ntypedef struct KATANALTYPE KATANALTYPE;\nstruct KATANALTYPE\n{\n  int first_line;\n  int first_column;\n  int last_line;\n  int last_column;\n};\n# define KATANALTYPE_IS_DECLARED 1\n# define KATANALTYPE_IS_TRIVIAL 1\n#endif\n\n\n\nint katanaparse (void* scanner, struct KatanaInternalParser * parser);\n\n#endif /* !YY_KATANA_KATANA_TAB_H_INCLUDED  */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/include/parser.h",
    "content": "﻿/**\n * Copyright (c) 2015 QFish <im@qfi.sh>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n#ifndef __Katana__parser__\n#define __Katana__parser__\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"katana.lex.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n    \n#define KATANA_FELX_DEBUG            0\n#define KATANA_BISON_DEBUG           0\n#define KATANA_PARSER_DEBUG          0\n#define KATANA_PARSER_LOG_ENABLE     0\n    \n\nstruct KatanaInternalOutput;\nstruct KatanaInternalOptions;\n\ntypedef void* (*KatanaAllocatorFunction)(void* userdata, size_t size);\n\ntypedef void (*KatanaDeallocatorFunction)(void* userdata, void* ptr);\n\ntypedef struct KatanaInternalOptions {\n    KatanaAllocatorFunction allocator;\n    KatanaDeallocatorFunction deallocator;\n    void* userdata;\n} KatanaOptions;\n\nextern const KatanaOptions kKatanaDefaultOptions;\n\ntypedef struct KatanaInternalParser {\n    // Settings for this parse run.\n    const struct KatanaInternalOptions* options;\n    \n    // Output for the parse.\n    struct KatanaInternalOutput* output;\n    \n    // The flex tokenizer info\n    yyscan_t* scanner;\n    \n    // The floating declarations\n    KatanaArray* parsed_declarations;\n#if KATANA_PARSER_DEBUG\n    // The floating selectors\n    KatanaArray* parsed_selectors;\n#endif // #if KATANA_PARSER_DEBUG\n    \n    KatanaSourcePosition* position;\n    KatanaParserString default_namespace;\n    \n} KatanaParser;\n    \n\nKatanaArray* katana_new_array(KatanaParser* parser);\n\n\nKatanaStylesheet* katana_new_stylesheet(KatanaParser* parser);\nvoid katana_parser_reset_declarations(KatanaParser* parser);\n\n\nvoid katana_add_namespace(KatanaParser* parser, KatanaParserString* prefix, KatanaParserString* uri);\n\n\nKatanaRule* katana_new_font_face(KatanaParser* parser);\n\n\nKatanaRule* katana_new_keyframes_rule(KatanaParser* parser, KatanaParserString* name, KatanaArray* keyframes, bool isPrefixed);\nKatanaKeyframe* katana_new_keyframe(KatanaParser* parser, KatanaArray* selectors);\nKatanaArray* katana_new_Keyframe_list(KatanaParser* parser);\nvoid katana_keyframe_rule_list_add(KatanaParser* parser, KatanaKeyframe* keyframe, KatanaArray* list);\nvoid katana_parser_clear_keyframes(KatanaParser* parser, KatanaArray* keyframes);\n\n\nvoid katana_set_charset(KatanaParser* parser, KatanaParserString* charset);\n\n\nKatanaRule* katana_new_import_rule(KatanaParser* parser, KatanaParserString* href, KatanaArray* media);\n\n\nKatanaValue* katana_new_value(KatanaParser* parser);\nKatanaValue* katana_new_dimension_value(KatanaParser* parser, KatanaParserNumber* value, KatanaValueUnit unit);\nKatanaValue* katana_new_number_value(KatanaParser* parser, int sign, KatanaParserNumber* value, KatanaValueUnit unit);\nKatanaValue* katana_new_operator_value(KatanaParser* parser, int value);\nKatanaValue* katana_new_ident_value(KatanaParser* parser, KatanaParserString* value);\nKatanaValue* katana_new_function_value(KatanaParser* parser, KatanaParserString* name, KatanaArray* args);\nKatanaValue* katana_new_list_value(KatanaParser* parser, KatanaArray* list);\n\nvoid katana_value_set_string(KatanaParser* parser, KatanaValue* value, KatanaParserString* string);\nvoid katana_value_set_sign(KatanaParser* parser, KatanaValue* value, int sign);\n\n\nKatanaArray* katana_new_value_list(KatanaParser* parser);\nvoid katana_value_list_add(KatanaParser* parser, KatanaValue* value, KatanaArray* list);\nvoid katana_value_list_insert(KatanaParser* parser, KatanaValue* value, int index, KatanaArray* list);\nvoid katana_value_list_steal_values(KatanaParser* parser, KatanaArray* values, KatanaArray* list);\n\n\nKatanaRule* katana_new_media_rule(KatanaParser* parser, KatanaArray* medias, KatanaArray* rules);\n\n\nKatanaArray* katana_new_media_list(KatanaParser* parser);\nvoid katana_media_list_add(KatanaParser* parser, KatanaMediaQuery* media_query, KatanaArray* medias);\n\n\nKatanaMediaQuery* katana_new_media_query(KatanaParser* parser, KatanaMediaQueryRestrictor r, KatanaParserString *type, KatanaArray* exps);\n\n\n// i.e. (min-width: 960px)\nKatanaMediaQueryExp * katana_new_media_query_exp(KatanaParser* parser, KatanaParserString* feature, KatanaArray* values);\n\n\nKatanaArray* katana_new_media_query_exp_list(KatanaParser* parser);\nvoid katana_media_query_exp_list_add(KatanaParser* parser, KatanaMediaQueryExp* exp, KatanaArray* list);\n\n\nKatanaArray* katana_new_rule_list(KatanaParser* parser);\nKatanaArray* katana_rule_list_add(KatanaParser* parser, KatanaRule* rule, KatanaArray* rule_list);\n\n\nKatanaRule* katana_new_style_rule(KatanaParser* parser, KatanaArray* selectors);\n\n\nvoid katana_start_declaration(KatanaParser* parser);\nvoid katana_end_declaration(KatanaParser* parser, bool flag, bool ended);\nvoid katana_set_current_declaration(KatanaParser* parser, KatanaParserString* tag);\nbool katana_new_declaration(KatanaParser* parser, KatanaParserString* name, bool important, KatanaArray* values);\nvoid katana_parser_clear_declarations(KatanaParser* parser);\n\n\nvoid katana_start_selector(KatanaParser* parser);\nvoid katana_end_selector(KatanaParser* parser);\n\nKatanaQualifiedName * katana_new_qualified_name(KatanaParser* parser, KatanaParserString* prefix, KatanaParserString* localName, KatanaParserString* uri);\n\nKatanaSelector* katana_new_selector(KatanaParser* parser);\nKatanaSelector* katana_sink_floating_selector(KatanaParser* parser, KatanaSelector* selector);\nKatanaSelector* katana_rewrite_specifier_with_element_name(KatanaParser* parser, KatanaParserString* tag, KatanaSelector* specifier);\nKatanaSelector* katana_rewrite_specifier_with_namespace_if_needed(KatanaParser* parser, KatanaSelector* specifier);\nKatanaSelector* katana_rewrite_specifiers(KatanaParser* parser, KatanaSelector* specifiers, KatanaSelector* newSpecifier);\n\nvoid katana_adopt_selector_list(KatanaParser* parser, KatanaArray* selectors, KatanaSelector* selector);\nvoid katana_selector_append(KatanaParser* parser, KatanaSelector* selector, KatanaSelector* new_selector, KatanaSelectorRelation relation);\nvoid katana_selector_insert(KatanaParser* parser, KatanaSelector* selector, KatanaSelector* new_selector, KatanaSelectorRelation before, KatanaSelectorRelation after);\nvoid katana_selector_prepend_with_element_name(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* tag);\n\nKatanaArray* katana_new_selector_list(KatanaParser* parser);\nKatanaArray* katana_reusable_selector_list(KatanaParser* parser);\nvoid katana_selector_list_shink(KatanaParser* parser, int capacity, KatanaArray* list);\nvoid katana_selector_list_add(KatanaParser* parser, KatanaSelector* selector, KatanaArray* list);\n\nvoid katana_selector_set_value(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* value);\nvoid katana_selector_set_argument(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* argument);\nvoid katana_selector_set_argument_with_number(KatanaParser* parser, KatanaSelector* selector, int sign, KatanaParserNumber* value);\n\nbool katana_parse_attribute_match_type(KatanaParser* parser, KatanaAttributeMatchType, KatanaParserString* attr);\n\nbool katana_selector_is_simple(KatanaParser* parser, KatanaSelector* selector);\nvoid katana_selector_extract_pseudo_type(KatanaSelector* selector);\n    \n\nvoid katana_add_rule(KatanaParser* parser, KatanaRule* rule);\n\nvoid katana_start_rule(KatanaParser* parser);\nvoid katana_end_rule(KatanaParser* parser, bool ended);\n\nvoid katana_start_rule_header(KatanaParser* parser, KatanaRuleType type);\nvoid katana_end_rule_header(KatanaParser* parser);\nvoid katana_end_invalid_rule_header(KatanaParser* parser);\nvoid katana_start_rule_body(KatanaParser* parser);\n\n\nbool katana_string_is_function(KatanaParserString* string);\nvoid katana_string_clear(KatanaParser* parser, KatanaParserString* string);\n\n    \nvoid katana_parse_internal_rule(KatanaParser* parser, KatanaRule* e);\nvoid katana_parse_internal_keyframe_rule(KatanaParser* parser, KatanaKeyframe* e);\nvoid katana_parse_internal_keyframe_key_list(KatanaParser* parser, KatanaArray* e);\nvoid katana_parse_internal_value(KatanaParser* parser, KatanaArray* e);\nvoid katana_parse_internal_media_list(KatanaParser* parser, KatanaArray* e);\nvoid katana_parse_internal_declaration_list(KatanaParser* parser, bool e);\nvoid katana_parse_internal_selector(KatanaParser* parser, KatanaArray* e);\n    \n\n// Bison error\nvoid katanaerror(KATANALTYPE* yyloc, void* scanner, KatanaParser * parser, char*);\n\n// Bison parser location\nKatanaSourcePosition* katana_parser_current_location(KatanaParser* parser, KATANALTYPE* yylloc);\n\n// Log\nvoid katana_parser_log(KatanaParser* parser, const char * format, ...);\n\n// Error\nvoid katana_parser_resume_error_logging();\nvoid katana_parser_report_error(KatanaParser* parser, KatanaSourcePosition* pos, const char *, ...);\n\n// print\nvoid katana_print(const char * format, ...);\n    \nvoid katana_print_stylesheet(KatanaParser* parser, KatanaStylesheet* sheet);\nvoid katana_print_rule(KatanaParser* parser, KatanaRule* rule);\nvoid katana_print_font_face_rule(KatanaParser* parser, KatanaFontFaceRule* rule);\nvoid katana_print_import_rule(KatanaParser* parser, KatanaImportRule* rule);\n    \nvoid katana_print_media_query_exp(KatanaParser* parser, KatanaMediaQueryExp* exp);\nvoid katana_print_media_query(KatanaParser* parser, KatanaMediaQuery* query);\nvoid katana_print_media_list(KatanaParser* parser, KatanaArray* medias);\nvoid katana_print_media_rule(KatanaParser* parser, KatanaMediaRule* rule);\n\nvoid katana_print_keyframes_rule(KatanaParser* parser, KatanaKeyframesRule* rule);\nvoid katana_print_keyframe(KatanaParser* parser, KatanaKeyframe* keyframe);\n\nvoid katana_print_style_rule(KatanaParser* parser, KatanaStyleRule* rule);\nvoid katana_print_selector(KatanaParser* parser, KatanaSelector* selector);\nvoid katana_print_selector_list(KatanaParser* parser, KatanaArray* selectors);\nvoid katana_print_declaration(KatanaParser* parser, KatanaDeclaration* decl);\nvoid katana_print_declaration_list(KatanaParser* parser, KatanaArray* declarations);\nvoid katana_print_value_list(KatanaParser* parser, KatanaArray* values);\n\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* defined(__Katana__parser__) */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/include/selector.h",
    "content": "/**\n * Copyright (c) 2015 QFish <im@qfi.sh>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n#ifndef __Katana__selector__\n#define __Katana__selector__\n\n#include <stdio.h>\n#include \"katana.h\"\n#include \"parser.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nKatanaParserString* katana_selector_to_string(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* next);\n    \nbool katana_selector_crosses_tree_scopes(const KatanaSelector* selector);\nbool katana_selector_matches_pseudo_element(KatanaSelector* selector);\nbool katana_selector_is_custom_pseudo_element(KatanaSelector* selector);\nbool katana_selector_is_direct_adjacent(KatanaSelector* selector);\nbool katana_selector_is_adjacent(KatanaSelector* selector);\nbool katana_selector_is_shadow(KatanaSelector* selector);\nbool katana_selector_is_sibling(KatanaSelector* selector);\nbool katana_selector_is_attribute(const KatanaSelector* selector);\nbool katana_selector_is_content_pseudo_element(KatanaSelector* selector);\nbool katana_selector_is_shadow_pseudo_element(KatanaSelector* selector);\nbool katana_selector_is_host_pseudo_class(KatanaSelector* selector);\nbool katana_selector_is_tree_boundary_crossing(KatanaSelector* selector);\nbool katana_selector_is_insertion_point_crossing(KatanaSelector* selector);\n    \n#ifdef __cplusplus\n}\n#endif\n\n#endif /* defined(__Katana__selector__) */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/include/tokenizer.h",
    "content": "/**\n * Copyright (c) 2015 QFish <im@qfi.sh>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n#ifndef __Katana__tokenizer__\n#define __Katana__tokenizer__\n\n#include <stdio.h>\n#include \"katana.lex.h\"\n#include \"katana.tab.h\"\n#include \"parser.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nint katana_tokenize(KATANASTYPE* lval , KATANALTYPE* loc, yyscan_t scanner, KatanaParser* parser, int tok);\n\n#ifdef __cplusplus\n}\n#endif\n    \n#endif /* defined(__Katana__tokenizer__) */\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/katana.lex.c",
    "content": "\n#line 3 \"katana.lex.c\"\n\n#define  YY_INT_ALIGNED short int\n\n/* A lexical scanner generated by flex */\n\n#define FLEX_SCANNER\n#define YY_FLEX_MAJOR_VERSION 2\n#define YY_FLEX_MINOR_VERSION 5\n#define YY_FLEX_SUBMINOR_VERSION 37\n#if YY_FLEX_SUBMINOR_VERSION > 0\n#define FLEX_BETA\n#endif\n\n/* First, we deal with  platform-specific or compiler-specific issues. */\n\n/* begin standard C headers. */\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <stdlib.h>\n\n/* end standard C headers. */\n\n/* flex integer type definitions */\n\n#ifndef FLEXINT_H\n#define FLEXINT_H\n\n/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */\n\n#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n\n/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,\n * if you want the limit (max/min) macros for int types. \n */\n#ifndef __STDC_LIMIT_MACROS\n#define __STDC_LIMIT_MACROS 1\n#endif\n\n#include <inttypes.h>\ntypedef int8_t flex_int8_t;\ntypedef uint8_t flex_uint8_t;\ntypedef int16_t flex_int16_t;\ntypedef uint16_t flex_uint16_t;\ntypedef int32_t flex_int32_t;\ntypedef uint32_t flex_uint32_t;\n#else\ntypedef signed char flex_int8_t;\ntypedef short int flex_int16_t;\ntypedef int flex_int32_t;\ntypedef unsigned char flex_uint8_t; \ntypedef unsigned short int flex_uint16_t;\ntypedef unsigned int flex_uint32_t;\n\n/* Limits of integral types. */\n#ifndef INT8_MIN\n#define INT8_MIN               (-128)\n#endif\n#ifndef INT16_MIN\n#define INT16_MIN              (-32767-1)\n#endif\n#ifndef INT32_MIN\n#define INT32_MIN              (-2147483647-1)\n#endif\n#ifndef INT8_MAX\n#define INT8_MAX               (127)\n#endif\n#ifndef INT16_MAX\n#define INT16_MAX              (32767)\n#endif\n#ifndef INT32_MAX\n#define INT32_MAX              (2147483647)\n#endif\n#ifndef UINT8_MAX\n#define UINT8_MAX              (255U)\n#endif\n#ifndef UINT16_MAX\n#define UINT16_MAX             (65535U)\n#endif\n#ifndef UINT32_MAX\n#define UINT32_MAX             (4294967295U)\n#endif\n\n#endif /* ! C99 */\n\n#endif /* ! FLEXINT_H */\n\n#ifdef __cplusplus\n\n/* The \"const\" storage-class-modifier is valid. */\n#define YY_USE_CONST\n\n#else\t/* ! __cplusplus */\n\n/* C99 requires __STDC__ to be defined as 1. */\n#if defined (__STDC__)\n\n#define YY_USE_CONST\n\n#endif\t/* defined (__STDC__) */\n#endif\t/* ! __cplusplus */\n\n#ifdef YY_USE_CONST\n#define yyconst const\n#else\n#define yyconst\n#endif\n\n/* Returned upon end-of-file. */\n#define YY_NULL 0\n\n/* Promotes a possibly negative, possibly signed char to an unsigned\n * integer for use as an array index.  If the signed char is negative,\n * we want to instead treat it as an 8-bit unsigned char, hence the\n * double cast.\n */\n#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)\n\n/* An opaque pointer. */\n#ifndef YY_TYPEDEF_YY_SCANNER_T\n#define YY_TYPEDEF_YY_SCANNER_T\ntypedef void* yyscan_t;\n#endif\n\n/* For convenience, these vars (plus the bison vars far below)\n   are macros in the reentrant scanner. */\n#define yyin yyg->yyin_r\n#define yyout yyg->yyout_r\n#define yyextra yyg->yyextra_r\n#define yyleng yyg->yyleng_r\n#define yytext yyg->yytext_r\n#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)\n#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)\n#define yy_flex_debug yyg->yy_flex_debug_r\n\n/* Enter a start condition.  This macro really ought to take a parameter,\n * but we do it the disgusting crufty way forced on us by the ()-less\n * definition of BEGIN.\n */\n#define BEGIN yyg->yy_start = 1 + 2 *\n\n/* Translate the current start state into a value that can be later handed\n * to BEGIN to return to the state.  The YYSTATE alias is for lex\n * compatibility.\n */\n#define YY_START ((yyg->yy_start - 1) / 2)\n#define YYSTATE YY_START\n\n/* Action number for EOF rule of a given start state. */\n#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)\n\n/* Special action meaning \"start processing a new file\". */\n#define YY_NEW_FILE katanarestart(yyin ,yyscanner )\n\n#define YY_END_OF_BUFFER_CHAR 0\n\n/* Size of default input buffer. */\n#ifndef YY_BUF_SIZE\n#define YY_BUF_SIZE 16384\n#endif\n\n/* The state buf must be large enough to hold one state per character in the main buffer.\n */\n#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))\n\n#ifndef YY_TYPEDEF_YY_BUFFER_STATE\n#define YY_TYPEDEF_YY_BUFFER_STATE\ntypedef struct yy_buffer_state *YY_BUFFER_STATE;\n#endif\n\n#ifndef YY_TYPEDEF_YY_SIZE_T\n#define YY_TYPEDEF_YY_SIZE_T\ntypedef size_t yy_size_t;\n#endif\n\n#define EOB_ACT_CONTINUE_SCAN 0\n#define EOB_ACT_END_OF_FILE 1\n#define EOB_ACT_LAST_MATCH 2\n\n    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires\n     *       access to the local variable yy_act. Since yyless() is a macro, it would break\n     *       existing scanners that call yyless() from OUTSIDE katanalex. \n     *       One obvious solution it to make yy_act a global. I tried that, and saw\n     *       a 5% performance hit in a non-yylineno scanner, because yy_act is\n     *       normally declared as a register variable-- so it is not worth it.\n     */\n    #define  YY_LESS_LINENO(n) \\\n            do { \\\n                int yyl;\\\n                for ( yyl = n; yyl < yyleng; ++yyl )\\\n                    if ( yytext[yyl] == '\\n' )\\\n                        --yylineno;\\\n            }while(0)\n    \n/* Return all but the first \"n\" matched characters back to the input stream. */\n#define yyless(n) \\\n\tdo \\\n\t\t{ \\\n\t\t/* Undo effects of setting up yytext. */ \\\n        int yyless_macro_arg = (n); \\\n        YY_LESS_LINENO(yyless_macro_arg);\\\n\t\t*yy_cp = yyg->yy_hold_char; \\\n\t\tYY_RESTORE_YY_MORE_OFFSET \\\n\t\tyyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \\\n\t\tYY_DO_BEFORE_ACTION; /* set up yytext again */ \\\n\t\t} \\\n\twhile ( 0 )\n\n#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )\n\n#ifndef YY_STRUCT_YY_BUFFER_STATE\n#define YY_STRUCT_YY_BUFFER_STATE\nstruct yy_buffer_state\n\t{\n\tFILE *yy_input_file;\n\n\tchar *yy_ch_buf;\t\t/* input buffer */\n\tchar *yy_buf_pos;\t\t/* current position in input buffer */\n\n\t/* Size of input buffer in bytes, not including room for EOB\n\t * characters.\n\t */\n\tyy_size_t yy_buf_size;\n\n\t/* Number of characters read into yy_ch_buf, not including EOB\n\t * characters.\n\t */\n\tyy_size_t yy_n_chars;\n\n\t/* Whether we \"own\" the buffer - i.e., we know we created it,\n\t * and can realloc() it to grow it, and should free() it to\n\t * delete it.\n\t */\n\tint yy_is_our_buffer;\n\n\t/* Whether this is an \"interactive\" input source; if so, and\n\t * if we're using stdio for input, then we want to use getc()\n\t * instead of fread(), to make sure we stop fetching input after\n\t * each newline.\n\t */\n\tint yy_is_interactive;\n\n\t/* Whether we're considered to be at the beginning of a line.\n\t * If so, '^' rules will be active on the next match, otherwise\n\t * not.\n\t */\n\tint yy_at_bol;\n\n    int yy_bs_lineno; /**< The line count. */\n    int yy_bs_column; /**< The column count. */\n    \n\t/* Whether to try to fill the input buffer when we reach the\n\t * end of it.\n\t */\n\tint yy_fill_buffer;\n\n\tint yy_buffer_status;\n\n#define YY_BUFFER_NEW 0\n#define YY_BUFFER_NORMAL 1\n\t/* When an EOF's been seen but there's still some text to process\n\t * then we mark the buffer as YY_EOF_PENDING, to indicate that we\n\t * shouldn't try reading from the input source any more.  We might\n\t * still have a bunch of tokens to match, though, because of\n\t * possible backing-up.\n\t *\n\t * When we actually see the EOF, we change the status to \"new\"\n\t * (via katanarestart()), so that the user can continue scanning by\n\t * just pointing yyin at a new input file.\n\t */\n#define YY_BUFFER_EOF_PENDING 2\n\n\t};\n#endif /* !YY_STRUCT_YY_BUFFER_STATE */\n\n/* We provide macros for accessing buffer states in case in the\n * future we want to put the buffer states in a more general\n * \"scanner state\".\n *\n * Returns the top of the stack, or NULL.\n */\n#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \\\n                          ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \\\n                          : NULL)\n\n/* Same as previous macro, but useful when we know that the buffer stack is not\n * NULL or when we need an lvalue. For internal use only.\n */\n#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]\n\nvoid katanarestart (FILE *input_file ,yyscan_t yyscanner );\nvoid katana_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );\nYY_BUFFER_STATE katana_create_buffer (FILE *file,int size ,yyscan_t yyscanner );\nvoid katana_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );\nvoid katana_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );\nvoid katanapush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );\nvoid katanapop_buffer_state (yyscan_t yyscanner );\n\nstatic void katanaensure_buffer_stack (yyscan_t yyscanner );\nstatic void katana_load_buffer_state (yyscan_t yyscanner );\nstatic void katana_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );\n\n#define YY_FLUSH_BUFFER katana_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)\n\nYY_BUFFER_STATE katana_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );\nYY_BUFFER_STATE katana_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );\nYY_BUFFER_STATE katana_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );\n\nvoid *katanaalloc (yy_size_t ,yyscan_t yyscanner );\nvoid *katanarealloc (void *,yy_size_t ,yyscan_t yyscanner );\nvoid katanafree (void * ,yyscan_t yyscanner );\n\n#define yy_new_buffer katana_create_buffer\n\n#define yy_set_interactive(is_interactive) \\\n\t{ \\\n\tif ( ! YY_CURRENT_BUFFER ){ \\\n        katanaensure_buffer_stack (yyscanner); \\\n\t\tYY_CURRENT_BUFFER_LVALUE =    \\\n            katana_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \\\n\t} \\\n\tYY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \\\n\t}\n\n#define yy_set_bol(at_bol) \\\n\t{ \\\n\tif ( ! YY_CURRENT_BUFFER ){\\\n        katanaensure_buffer_stack (yyscanner); \\\n\t\tYY_CURRENT_BUFFER_LVALUE =    \\\n            katana_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \\\n\t} \\\n\tYY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \\\n\t}\n\n#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)\n\n/* Begin user sect3 */\n\n#define katanawrap(yyscanner) 1\n#define YY_SKIP_YYWRAP\n\ntypedef unsigned char YY_CHAR;\n\ntypedef int yy_state_type;\n\n#define yytext_ptr yytext_r\n\nstatic yy_state_type yy_get_previous_state (yyscan_t yyscanner );\nstatic yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);\nstatic int yy_get_next_buffer (yyscan_t yyscanner );\nstatic void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );\n\n/* Done after the current pattern has been matched and before the\n * corresponding action - sets up yytext.\n */\n#define YY_DO_BEFORE_ACTION \\\n\tyyg->yytext_ptr = yy_bp; \\\n\tyyleng = (size_t) (yy_cp - yy_bp); \\\n\tyyg->yy_hold_char = *yy_cp; \\\n\t*yy_cp = '\\0'; \\\n\tyyg->yy_c_buf_p = yy_cp;\n\n#define YY_NUM_RULES 90\n#define YY_END_OF_BUFFER 91\n/* This struct is not used in this scanner,\n   but its presence is necessary. */\nstruct yy_trans_info\n\t{\n\tflex_int32_t yy_verify;\n\tflex_int32_t yy_nxt;\n\t};\nstatic yyconst flex_int16_t yy_accept[551] =\n    {   0,\n        0,    0,    0,    0,    0,    0,   91,   89,    2,    2,\n       89,   89,   89,   89,   89,   89,   89,   89,   89,   89,\n       71,   89,   89,   18,   18,   18,   18,   18,   18,   18,\n       89,   89,   89,   89,   88,   18,   18,   18,   87,   18,\n       18,   18,    2,    0,    0,    0,   17,    0,    0,   20,\n       20,   21,    0,    8,    0,    0,    9,    0,   19,    0,\n       18,   18,   18,    0,   72,    0,   70,    0,    0,   71,\n       68,   68,   68,   68,   68,   68,   68,   68,   68,   68,\n       19,   68,   68,   57,   68,   68,    0,   68,    0,    0,\n       39,   39,   39,   39,   39,   39,   39,   39,   39,    0,\n\n       84,   18,   18,    0,   18,   18,   18,   18,   18,    0,\n        0,   18,   18,    0,   18,   18,   18,    7,    6,    5,\n       18,   18,   18,   13,   18,   18,   16,    0,    0,    0,\n       17,    0,    0,   21,   20,    0,   21,   21,    0,    0,\n       17,    0,    0,    4,   18,    0,    0,   69,   68,    0,\n       42,   47,   68,   68,   44,   45,   67,   68,   58,   49,\n       68,   48,   56,   69,   68,   51,   50,   46,   68,   68,\n       68,   61,   60,   68,   68,   68,    0,   39,   39,   39,\n        0,   39,   39,   39,   39,   39,   39,   39,   39,   39,\n       39,   18,   18,   18,   18,   18,   18,   18,   18,    0,\n\n       19,   18,   18,   85,   85,   18,   18,   12,   10,   18,\n       15,   14,    0,    0,    0,   21,   21,   21,    0,    0,\n       18,    0,    1,   68,   68,   52,   68,   65,   68,   68,\n       59,   19,   53,   41,   68,   68,   68,   68,   68,    3,\n       39,   39,   39,   39,   39,   39,   39,   39,   39,   39,\n       39,   39,   39,   75,   18,   18,   76,   18,   81,   80,\n       77,    0,   85,   85,   85,   84,   18,   11,    0,    0,\n       21,   21,    0,   18,    0,    0,   68,   66,   64,   54,\n       55,   63,   62,   68,   68,   39,   39,   39,   39,   39,\n       39,   39,   39,   39,   23,   39,   39,   18,   78,   82,\n\n       18,   86,   85,   85,   85,   85,    0,    0,    0,    0,\n       74,    0,   18,    0,    0,   21,   21,    0,   18,   68,\n       68,   43,   39,   39,   39,   39,   39,   39,   39,   24,\n       39,   39,   39,   18,   18,   86,   85,   85,   85,   85,\n       85,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       74,    0,    0,   18,    0,    0,   21,   21,    0,   18,\n       68,   68,   39,   39,   39,   39,   39,   22,   39,   39,\n       39,   39,   18,   18,   86,   85,   85,   85,   85,   85,\n       85,    0,   73,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,   18,    0,    0,   21,   21,    0,\n\n       18,   68,   68,   39,   39,   39,   26,   39,   39,   39,\n       39,   39,   18,   18,   86,   85,   85,   85,   85,   85,\n       85,   85,    0,   73,    0,    0,    0,   73,    0,    0,\n        0,    0,   21,   18,   68,   39,   39,   39,   39,   39,\n       39,   30,   18,   86,    0,    0,    0,   40,   18,   39,\n       39,   25,   28,   27,   18,   86,    0,    0,    0,   18,\n       39,   39,   18,    0,    0,    0,   18,   39,   39,   39,\n       39,   39,   39,   39,   18,    0,    0,   79,   39,   39,\n       39,   39,   39,   39,   39,   39,   83,   39,   39,   39,\n       39,   39,   39,   39,   39,   39,   39,   39,   31,   39,\n\n       39,   39,   39,   32,   39,   39,   39,   39,   33,   39,\n       39,   39,   39,   39,   39,   39,   39,   39,   39,   29,\n       39,   39,   34,   39,   39,   39,   39,   39,   39,   35,\n       39,   39,   39,   39,   39,   39,   39,   39,   36,   39,\n       39,   39,   39,   39,   39,   39,   37,   39,   38,    0\n    } ;\n\nstatic yyconst flex_int32_t yy_ec[256] =\n    {   0,\n        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,\n        1,    4,    5,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    6,    7,    8,    9,   10,   11,   12,   13,   14,\n       15,   16,   17,   12,   18,   19,   20,   21,   21,   21,\n       21,   21,   21,   21,   21,   21,   21,   12,   22,   23,\n       24,   25,   26,   27,   28,   29,   30,   31,   32,   33,\n       34,   35,   36,   37,   38,   39,   40,   41,   42,   43,\n       44,   45,   46,   47,   48,   49,   50,   51,   52,   53,\n       12,   54,   12,   55,   56,   12,   57,   58,   59,   60,\n\n       61,   62,   63,   64,   65,   37,   66,   67,   68,   69,\n       70,   71,   72,   73,   74,   75,   76,   77,   78,   79,\n       80,   81,   82,   83,   12,   84,    1,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85,   85,   85,   85,   85,   85,\n       85,   85,   85,   85,   85\n    } ;\n\nstatic yyconst flex_int32_t yy_meta[86] =\n    {   0,\n        1,    2,    3,    4,    4,    5,    6,    7,    6,    6,\n        6,    6,    7,    8,    6,    6,    9,   10,    6,    6,\n       11,    6,    6,    6,    6,   12,    6,   13,   13,   13,\n       13,   13,   13,   14,   14,   14,   14,   14,   14,   14,\n       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,\n       14,   14,   14,   14,    6,   14,   13,   13,   13,   13,\n       13,   13,   14,   14,   14,   14,   14,   14,   14,   14,\n       14,   14,   14,   14,   14,   14,   14,   14,   14,   14,\n       14,    6,    6,    6,   14\n    } ;\n\nstatic yyconst flex_int16_t yy_base[608] =\n    {   0,\n        0,    0,   64,   66,   59,   61, 1576, 5465,   93,  107,\n      135,   96,  183, 1549,   78, 1538,  101,  106, 1511, 1512,\n      235, 1493,  303,  103,  100,  131,  111,  138,  349,  144,\n      399, 1471, 1464, 1434, 5465,  137,  379,  179, 5465,  169,\n      384,  154,  226,  323,   75,  155, 5465,  460,   72,    0,\n      502, 1383,  544, 5465,  136,  605, 5465,  156,  405, 1408,\n      148,  492,  380,  647,  337, 1416, 1384, 1335, 1342,    0,\n      165,  461,  382,  487,  401,  430,  363,  306,  532,  431,\n      534,  540,  595,  201,  541,  603,  689,  204, 1334,  596,\n     1282,  132,  180,  277,  381,  418,  296,  307,  294,  731,\n\n     5465,  276,  531,  773,  514,  568,  570,  633,  628,  683,\n      690,  721,  711, 1309,  616,  386,  834, 5465, 5465, 5465,\n      764,  722,  676,  391,  765,  723,  453,  333,  329,  172,\n      197,  895,  956, 1276,  998, 1040, 1260, 1101,  470,  181,\n      325, 1162, 1223, 5465,  644, 1255,  153, 5465,  398, 1265,\n      422,  494,  766, 1274,  496,  525,  526,  717,  637,  677,\n      686,  699,  712,  805,  851,  727,  755,  767,  768,  806,\n      796,  853,  795,  797, 1344,  858, 1249,  687,  826, 1194,\n     1386,  819,  863,  865,  428,  538,  714,  597,  866, 1179,\n     1447,  472,  719, 1508,  892,  773,  915,  828,  829,  942,\n\n     1103,  857,  917,  221, 1094,  919, 1550,  920,  921,  924,\n      925,  926,  367,  416, 1611, 1039, 1672, 1714,  659, 1756,\n      927, 1050, 5465,  798, 1817,  860,  955,  867,  983,  951,\n      896,  949,  966,  979,  981,  985,  984, 1859, 1031, 5465,\n     1000,  458,  997, 1920,  967, 1020,  571, 1032,  825, 1055,\n     1056, 1037, 1962, 5465, 2004,  953, 5465, 1027, 5465, 5465,\n     5465,    0,  231,  998,  971, 1133, 2065,  978,  548, 2126,\n     2168, 2210, 2252, 1135,  978,  302, 2294,  989, 1025, 1029,\n     1059, 1060, 1061, 2336, 1072, 1064, 1089, 2378, 1096,  101,\n     1074, 1099, 1123, 1127,  888, 1115, 2420, 2462, 5465, 5465,\n\n     1183,    0,  622,  833,  754,  731, 1255, 1354,  536,  701,\n     5465, 2523, 2584,  868, 2645, 2706, 2767, 2828, 1160, 2870,\n     2912, 1067, 1157, 1150, 2954, 1091, 1155, 1156, 1151,  684,\n     1175, 1189, 2996, 3038, 1142,    0,  973,  706,  673,  619,\n      613, 1297, 1036, 1338, 3099,  995, 3160, 1376, 1381, 1407,\n     1467, 3221, 3282, 3343, 1054, 3404, 3465, 3526, 3587, 1251,\n     3648, 3709, 1238, 1191, 3751, 1259, 1219,  574, 1210, 1261,\n     1317, 3793, 3835, 1297,    0, 1180,  571,  552,  545,  528,\n      521, 1421, 5465, 1385, 1233, 1481, 3896, 3957, 1186, 1236,\n     1540, 4018, 4079, 4140, 1520, 1113, 1546, 4201, 1461, 1582,\n\n     1340, 4243, 4304, 1400,  448, 4365,  446, 1278, 1336, 1401,\n     1388, 1599, 1643, 1427,    0,  451, 5465, 5465, 5465, 5465,\n     5465, 5465, 1683, 1266, 1267, 4407, 1704, 1544, 1625, 4449,\n     4510, 1241, 1657, 1502, 1488, 1464, 1523, 1710, 1466, 1518,\n     1564,  397, 1667,    0, 4552, 4594, 4636, 5465, 1583, 1301,\n     1597,  341,  338,  319, 1576, 5465, 4678, 4720, 4762, 1666,\n     4794, 1572, 1708, 4851, 4893, 1746, 1218, 1706, 1709, 1736,\n     1545, 1748, 1638, 1367, 1445, 1802, 1827, 5465, 1664, 1602,\n     1705, 1715, 1727, 1782, 1772, 1789, 5465, 1788, 1804, 1805,\n     1803, 1839, 1811, 1819, 1699, 1798, 1840, 1855,  286, 1856,\n\n     1521, 1873, 1566,  280, 1874, 1402, 1854, 1885,  265, 1879,\n     1892, 1830, 1893, 1889, 1891, 1912, 1902, 1914, 1915,  208,\n     1479, 1930,  182, 1613, 1972, 1952, 1942, 1953, 1954,  133,\n     1900, 1951, 1961, 1975, 1672, 1986, 2018, 2020,  122, 1921,\n     2019, 2004, 2002, 2045, 2028, 2035,  110, 2047,   66, 5465,\n     4954, 4959, 4972, 4977, 4982, 4989, 4999, 5012,  248, 5017,\n     5027, 5040, 5054,  872, 5060, 5070, 5075, 5085, 5095, 5099,\n     5108, 5121, 5135, 5145, 5155, 5160, 5173, 1165, 5178, 5190,\n     5204, 1318, 5209, 5221, 5234, 5247, 5260, 5273, 5286, 5299,\n     1427, 5304, 5316, 5329, 5342, 5355, 5368, 5381, 5394, 1506,\n\n     5399, 5411, 5424, 5437, 5450, 1547, 1622\n    } ;\n\nstatic yyconst flex_int16_t yy_def[608] =\n    {   0,\n      550,    1,    1,    1,    1,    1,  550,  550,  550,  550,\n      550,  551,  552,  550,  553,  550,  550,  554,  550,  550,\n      550,  550,  555,  556,  556,  556,  556,  556,  556,  556,\n      557,  550,  550,  550,  550,  556,  556,  556,  550,  556,\n      556,  556,  550,  550,  550,  551,  550,  558,  552,  559,\n      560,  560,  561,  550,  553,  562,  550,  550,  550,  550,\n      556,  556,  556,  557,   21,  563,  550,  564,  550,   21,\n      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,\n      565,  565,  565,  565,  565,  565,  566,  565,  550,  555,\n      567,  567,  567,  567,  567,  567,  567,  567,  567,  568,\n\n      550,  556,  556,  569,  556,  556,  556,  556,  556,  550,\n      550,  556,  556,  570,  556,  556,  556,  550,  550,  550,\n      556,  556,  556,  556,  556,  556,  556,  550,  551,  551,\n      551,  551,  558,  560,  560,  571,  560,  135,  553,  553,\n      553,  553,  572,  550,  556,  563,  573,  550,  565,  574,\n      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,\n      565,  565,  565,  550,  565,  565,  565,  565,  565,  565,\n      565,  565,  565,  565,  565,  565,  550,  567,  567,  567,\n      575,  567,  567,  567,  567,  567,  567,  567,  567,  567,\n      567,  556,  556,  117,  556,  556,  556,  556,  556,  550,\n\n      550,  556,  556,  576,  550,  556,  117,  556,  556,  556,\n      556,  556,  550,  551,  551,  560,  135,  138,  553,  142,\n      556,  577,  550,  565,  175,  565,  565,  565,  565,  565,\n      565,  565,  565,  565,  565,  565,  565,  175,  565,  550,\n      567,  567,  567,  191,  567,  567,  567,  567,  567,  567,\n      567,  567,  191,  550,  194,  556,  550,  556,  550,  550,\n      550,  578,  579,  550,  550,  580,  255,  556,  550,  551,\n      217,  138,  142,  556,  577,  581,  225,  565,  565,  565,\n      565,  565,  565,  175,  565,  567,  567,  244,  567,  567,\n      567,  567,  567,  567,  567,  567,  191,  255,  550,  550,\n\n      556,  582,  583,  550,  550,  550,  584,  584,  585,  586,\n      550,  587,  255,  550,  588,  589,  589,  590,  556,  225,\n      175,  565,  567,  567,  288,  567,  567,  567,  567,  567,\n      567,  567,  191,  255,  556,  591,  592,  550,  550,  550,\n      550,  550,  585,  550,  593,  586,  594,  595,  595,  595,\n      595,  595,  596,  255,  550,  597,  598,  598,  599,  556,\n      175,  361,  567,  567,  325,  567,  567,  567,  567,  567,\n      567,  191,  255,  556,  600,  601,  550,  550,  550,  550,\n      550,  550,  550,  585,  585,  585,  585,  602,  603,  603,\n      603,  603,  604,  605,  556,  550,  597,  358,  598,  599,\n\n      556,  361,  361,  567,  567,  191,  567,  567,  567,  567,\n      567,  567,  556,  556,  606,  550,  550,  550,  550,  550,\n      550,  550,  585,  585,  585,  387,  603,  603,  603,  392,\n      605,  550,  598,  556,  403,  567,  567,  567,  567,  567,\n      567,  567,  556,  607,  387,  392,  431,  550,  556,  567,\n      567,  567,  567,  567,  556,  550,  387,  392,  431,  556,\n      567,  567,  556,  387,  392,  605,  556,  567,  567,  567,\n      567,  567,  567,  567,  556,  585,  603,  550,  567,  567,\n      567,  567,  567,  567,  567,  567,  550,  567,  567,  567,\n      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,\n\n      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,\n      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,\n      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,\n      567,  567,  567,  567,  567,  567,  567,  567,  567,  567,\n      567,  567,  567,  567,  567,  567,  567,  567,  567,    0,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550\n    } ;\n\nstatic yyconst flex_int16_t yy_nxt[5551] =\n    {   0,\n        8,    9,   10,    9,    9,    9,   11,   12,   13,   14,\n        8,    8,   15,    8,    8,   16,   17,   18,   19,   20,\n       21,    8,   22,    8,    8,    8,   23,   24,   25,   26,\n       25,   25,   25,   25,   27,   25,   25,   25,   25,   28,\n       29,   25,   25,   25,   25,   25,   25,   30,   25,   25,\n       25,   25,   25,   31,   32,   25,   24,   25,   26,   25,\n       25,   25,   25,   27,   25,   25,   25,   28,   29,   25,\n       25,   25,   25,   25,   25,   30,   25,   25,   25,   25,\n       25,    8,   33,   34,   25,   35,   40,   35,   40,  550,\n       47,   36,  550,   36,   43,   43,   43,   43,   43,   41,\n\n       42,   41,   42,   47,   37,   38,   37,   38,   43,   43,\n       43,   43,   43,  101,  128,   40,  101,   40,  327,  181,\n       36,   58,   36,   60,  101,   53,   58,   41,   42,   41,\n       42,   56,   37,   38,   37,   38,   44,   44,   44,   44,\n       44,   59,  128,  103,  101,   39,   62,   39,   47,   48,\n      101,  101,  107,  104,  181,   63,  104,  101,  105,   64,\n      114,  101,   47,  181,  104,  108,  182,  101,  147,   59,\n       45,  103,  223,  109,   62,  181,   58,  121,  106,   47,\n      107,  148,  101,   63,  104,  181,  181,  105,  115,   56,\n      104,  104,  101,   47,  108,  182,   59,  104,  127,   45,\n\n       49,  104,  109,   50,   47,  121,  106,  104,   48,  125,\n       51,   51,   51,   51,   51,   51,  115,  148,  150,  123,\n      148,  183,  104,  124,   59,   48,  127,   43,   43,   43,\n       43,   43,  104,  181,   56,  181,   53,  125,  262,   51,\n       51,   51,   51,   51,   51,   67,  264,  123,  262,  183,\n       48,  124,   68,   69,  150,   70,  304,  150,   50,  176,\n       50,  181,   71,   71,   72,   73,   74,   75,   76,   77,\n       78,   71,   79,   71,   80,   81,   71,   82,   71,   83,\n       84,   85,   71,   86,   71,   71,   71,   71,   87,  101,\n       88,   71,   71,   72,   73,   74,   75,   76,   77,   78,\n\n       79,   71,   80,   81,   71,   82,   71,   83,   84,   85,\n       71,   86,   71,   71,   71,   71,  184,  276,  181,   71,\n       90,  223,  148,  187,   44,   44,   44,   44,   44,  104,\n      181,   46,   92,  181,  188,   93,   47,   47,   94,  181,\n       95,  189,   96,   97,  184,   98,  160,  181,   99,  181,\n      110,  110,  187,  110,  110,  550,  100,   65,   45,  150,\n      181,   92,  101,  188,   93,  111,  112,   94,   95,  189,\n       96,   97,  181,   98,  160,  213,   99,   71,   56,  148,\n      110,  110,   48,  110,  110,  110,  110,   45,  110,  110,\n      113,  181,  101,  101,  181,  111,  112,  101,  148,  101,\n\n      111,  112,  104,  213,  101,   71,  110,  110,  269,  110,\n      110,  145,  185,  153,  148,  159,  150,  148,  113,  117,\n      122,  111,  111,   47,  154,  126,  117,  117,  117,  117,\n      117,  117,  104,  104,  181,  150,  269,  104,  148,  104,\n      145,  185,  153,  159,  104,  157,  148,  148,  122,  186,\n      181,  150,  154,  126,  150,  117,  117,  117,  117,  117,\n      117,   46,   46,   46,  129,  437,  101,  131,  262,   48,\n      162,  181,   55,  157,  158,  150,  163,  148,  186,  248,\n      132,  181,   47,  150,  150,  254,  287,  132,  132,  132,\n      132,  132,  132,  110,  110,  151,  110,  110,  162,  181,\n\n      152,  181,  158,  148,  163,  101,  104,  248,  111,  112,\n      148,  181,  148,  133,  150,  287,  132,  132,  132,  132,\n      132,  132,  135,   56,  151,  104,  155,  101,  152,  135,\n      135,  135,  135,  135,  135,  110,  110,  156,  110,  110,\n      150,  148,  148,  344,  101,  104,  422,  150,  148,  150,\n      164,  165,  195,  421,  155,  136,  148,  148,  135,  135,\n      135,  135,  135,  135,  138,  156,  161,  104,  249,  166,\n      420,  138,  138,  138,  138,  138,  138,  419,  150,  150,\n      195,  101,  192,  101,  104,  150,  167,  150,  171,  345,\n      168,  181,  314,  150,  150,  161,  418,  249,  166,  196,\n\n      138,  138,  138,  138,  138,  138,   55,   55,   55,  139,\n      192,  148,  291,  550,  167,  197,  171,  141,  168,  148,\n      314,  104,  169,  104,  181,  142,  170,  181,  196,  101,\n      251,  178,  142,  142,  142,  142,  142,  142,  381,  262,\n      291,  101,  172,  197,  380,  179,  101,  338,  150,  100,\n      181,  169,  173,  148,  206,  170,  150,  101,  143,  251,\n      178,  142,  142,  142,  142,  142,  142,  117,  199,  104,\n      172,   47,  221,  179,  117,  117,  117,  117,  117,  117,\n      173,  104,  206,  198,  110,  110,  104,  110,  110,  101,\n      150,  200,  200,  148,  200,  200,  199,  104,  379,  111,\n\n      111,  221,  148,  117,  117,  117,  117,  117,  117,  175,\n      201,  198,   56,  344,  210,  148,  175,  175,  175,  175,\n      175,  175,  200,  200,  101,  200,  200,  241,  148,  104,\n      150,  378,  101,  148,  101,  101,  101,  181,  231,  150,\n      181,  202,  210,  148,  230,  175,  175,  175,  175,  175,\n      175,  191,  150,  250,  347,  241,  341,  203,  191,  191,\n      191,  191,  191,  191,  104,  150,  231,  181,  209,  212,\n      150,  148,  104,  230,  104,  104,  104,  101,  101,  340,\n      150,  250,  148,  148,  148,  203,  257,  191,  191,  191,\n      191,  191,  191,  194,  208,  211,  209,  212,  233,  226,\n\n      194,  194,  194,  194,  194,  194,  200,  200,  150,  200,\n      200,  148,  148,  148,  148,  192,  192,  104,  104,  150,\n      150,  150,  148,  208,  211,  201,  104,  233,  226,  194,\n      194,  194,  194,  194,  194,  116,  116,  116,  116,  116,\n      235,  259,  260,  192,  192,  234,  245,  101,  150,  150,\n      150,  150,  200,  200,  207,  200,  200,  242,  339,  150,\n      293,  207,  207,  207,  207,  207,  207,  148,  235,  148,\n      101,  232,  181,  234,  148,  245,  148,  202,  181,  181,\n      236,  104,  104,  148,   71,   71,  242,  104,  237,  293,\n      207,  207,  207,  207,  207,  207,  130,  214,  214,  214,\n\n      130,  239,   47,  246,  150,  101,  150,  247,  252,  236,\n      104,  150,  148,  150,  355,  215,  181,  237,  181,  181,\n      150,  256,  215,  215,  215,  215,  215,  215,  101,  239,\n      261,  246,  266,  101,  261,  247,  252,  101,  101,  261,\n      101,  181,  355,  200,  200,  104,  200,  200,   48,  150,\n      256,  215,  215,  215,  215,  215,  215,   46,   46,   46,\n      129,  258,  201,  131,  274,  148,  299,  148,  104,  232,\n      104,  148,  104,  104,  104,  268,  132,  104,  104,  104,\n      104,  280,  148,  132,  132,  132,  132,  132,  132,  258,\n      262,  101,  274,  276,  278,  148,  306,  148,  377,  148,\n\n      148,  148,  150,  268,  150,  148,  104,  344,  150,  133,\n      280,  289,  132,  132,  132,  132,  132,  132,  135,  150,\n      181,  281,  278,  305,  283,  135,  135,  135,  135,  135,\n      135,  104,  150,  279,  150,  282,  150,  150,  150,  289,\n      300,  148,  150,  344,  301,  148,  286,  148,  347,  281,\n      181,  136,  283,  181,  135,  135,  135,  135,  135,  135,\n      217,  279,  285,  282,  292,  276,  290,  217,  217,  217,\n      217,  217,  217,  181,  286,  148,  148,  148,  150,  296,\n      104,  396,  150,  148,  150,  181,  294,  295,  148,  345,\n      181,  285,  136,  292,  290,  323,  217,  217,  217,  217,\n\n      217,  217,  137,  137,  137,  137,  137,  296,  181,  181,\n      396,  322,  150,  150,  150,  294,  295,  181,  328,  265,\n      150,  218,  366,  201,  323,  150,  324,  181,  218,  218,\n      218,  218,  218,  218,  307,  307,  307,  307,  307,  322,\n      309,  326,  181,  329,  181,  310,  328,  311,  101,  181,\n      330,  366,  181,  432,  324,  101,  332,  218,  218,  218,\n      218,  218,  218,  140,  219,  219,  219,  140,  181,  326,\n      319,  329,  331,  101,   47,  302,  181,  302,  369,  330,\n      181,  432,  220,  374,  332,  364,  312,  367,  104,  220,\n      220,  220,  220,  220,  220,  104,  101,  262,  344,  319,\n\n      331,  363,  368,  181,  181,  417,  360,  369,  181,  181,\n      181,  374,  335,  104,  364,   56,  367,  370,  220,  220,\n      220,  220,  220,  220,   55,   55,   55,  139,  181,  363,\n      368,  478,  181,  371,  360,  141,  104,  405,  550,  347,\n      344,  335,  181,  142,  181,  370,  408,  181,  344,  409,\n      142,  142,  142,  142,  142,  142,  307,  307,  307,  307,\n      307,  371,  309,  181,  101,  405,  240,  310,  401,  311,\n      147,  104,  181,  344,  344,  408,  143,  409,  404,  142,\n      142,  142,  142,  142,  142,  225,  345,  448,  410,  347,\n      148,  181,  225,  225,  225,  225,  225,  225,  342,  342,\n\n      342,  342,  342,  227,  104,  407,  404,  439,  312,  228,\n      101,  311,  181,  136,  181,  448,  229,  410,  461,  345,\n      345,  225,  225,  225,  225,  225,  225,  150,  336,  136,\n      336,  181,  227,  407,  205,  181,  439,  414,  228,  382,\n      382,  382,  382,  382,  229,  174,  174,  174,  174,  174,\n      104,  177,  383,  101,  181,  342,  342,  342,  342,  342,\n      148,  550,   65,  411,  238,  414,  550,  440,  311,  434,\n      181,  238,  238,  238,  238,  238,  238,  342,  342,  342,\n      342,  342,  342,  342,  342,  342,  342,  343,   87,  181,\n      311,  411,  344,  104,   67,  311,  440,  150,  434,  486,\n\n      238,  238,  238,  238,  238,  238,  244,  312,  342,  342,\n      342,  342,  342,  244,  244,  244,  244,  244,  244,  512,\n      181,  311,  382,  382,  382,  382,  382,  436,  486,  312,\n      441,  147,  144,  442,  312,  383,  136,  375,  345,  375,\n      101,  181,  244,  244,  244,  244,  244,  244,  190,  190,\n      190,  190,  190,  181,  181,  181,  436,  120,  487,  441,\n      312,  442,  137,  137,  137,  137,  137,  253,  342,  342,\n      342,  342,  342,  443,  253,  253,  253,  253,  253,  253,\n      104,  311,  423,  382,  382,  382,  423,  119,  344,  224,\n      224,  224,  224,  224,  118,  424,  525,  452,  104,   89,\n\n      181,  443,  450,  253,  253,  253,  253,  253,  253,  193,\n      193,  193,  193,  193,  136,  101,  415,  181,  415,  181,\n      312,  116,  116,  116,  116,  116,  452,   66,  255,  449,\n      450,   65,  181,  101,  345,  255,  255,  255,  255,  255,\n      255,  427,  382,  382,  382,  427,  550,  130,  214,  214,\n      214,  130,  344,   47,  428,  104,  344,  444,  449,  444,\n      451,   57,  508,  453,  255,  255,  255,  255,  255,  255,\n      267,  181,   54,  104,  181,  550,  181,  267,  267,  267,\n      267,  267,  267,  140,  219,  219,  219,  140,  451,  101,\n      508,  453,  482,  347,   47,  454,  101,  347,  181,   48,\n\n      190,  190,  190,  190,  190,  510,  267,  267,  267,  267,\n      267,  267,  130,  214,  214,  214,  130,  181,   47,  181,\n      482,  460,  550,  474,  454,  181,  463,  550,  462,  104,\n      527,  270,  456,  510,  456,   56,  104,  344,  270,  270,\n      270,  270,  270,  270,  193,  193,  193,  193,  193,  460,\n      181,  474,  181,  489,  463,  181,  101,  462,  216,  216,\n      216,  216,  216,  550,   48,  485,  181,  270,  270,  270,\n      270,  270,  270,  216,  216,  216,  216,  216,  347,  101,\n      101,  489,  550,  550,  423,  382,  382,  382,  423,  538,\n      344,  181,  271,  488,  485,  467,  104,  424,  455,  271,\n\n      271,  271,  271,  271,  271,  427,  382,  382,  382,  427,\n      136,  243,  243,  243,  243,  243,  344,  181,  428,  104,\n      104,  101,  488,  550,  467,  181,  503,  455,  271,  271,\n      271,  271,  271,  271,  272,  490,  345,  479,  550,  550,\n      480,  272,  272,  272,  272,  272,  272,  348,  348,  348,\n      348,  348,  181,  491,  475,  503,  550,  347,  181,  181,\n      311,  104,  181,  181,  490,  492,  479,  481,  181,  480,\n      272,  272,  272,  272,  272,  272,  273,  550,  550,  483,\n      181,  491,  475,  273,  273,  273,  273,  273,  273,  181,\n      550,  550,  550,  492,  550,  484,  481,  550,  550,  312,\n\n      550,  181,  550,  385,  425,  425,  425,  385,  483,  344,\n      494,  550,  273,  273,  273,  273,  273,  273,  224,  224,\n      224,  224,  224,  484,  493,  181,  496,  550,  390,  429,\n      429,  429,  390,  495,  499,  181,  497,  277,  494,  344,\n      498,  181,  181,  504,  277,  277,  277,  277,  277,  277,\n      550,  181,  493,  501,  496,  345,  181,  181,  181,  550,\n      550,  495,  550,  499,  181,  497,  502,  550,  517,  498,\n      500,  504,  181,  277,  277,  277,  277,  277,  277,  284,\n      347,  501,  506,  181,  505,  507,  284,  284,  284,  284,\n      284,  284,  181,  181,  502,  550,  517,  550,  550,  500,\n\n      513,  511,  550,  550,  509,  550,  550,  181,  181,  181,\n      515,  506,  505,  550,  507,  284,  284,  284,  284,  284,\n      284,  243,  243,  243,  243,  243,  181,  181,  513,  514,\n      511,  516,  181,  509,  518,  519,  520,  522,  181,  515,\n      288,  534,  181,  521,  181,  181,  181,  288,  288,  288,\n      288,  288,  288,  181,  550,  181,  542,  514,  523,  516,\n      524,  550,  518,  519,  520,  181,  522,  181,  181,  534,\n      550,  531,  521,  550,  181,  526,  288,  288,  288,  288,\n      288,  288,  297,  181,  532,  542,  523,  550,  524,  297,\n      297,  297,  297,  297,  297,  181,  550,  550,  530,  536,\n\n      531,  533,  535,  526,  181,  181,  181,  181,  550,  528,\n      550,  550,  550,  532,  181,  537,  529,  539,  297,  297,\n      297,  297,  297,  297,  298,  181,  530,  536,  181,  533,\n      535,  298,  298,  298,  298,  298,  298,  528,  550,  181,\n      550,  550,  550,  537,  529,  550,  539,  545,  540,  550,\n      544,  550,  550,  550,  543,  181,  550,  181,  541,  550,\n      298,  298,  298,  298,  298,  298,  116,  116,  116,  116,\n      116,  181,  181,  181,  547,  545,  548,  540,  544,  550,\n      546,  181,  550,  543,  550,  313,  541,  549,  181,  550,\n      550,  550,  313,  313,  313,  313,  313,  313,  181,  550,\n\n      181,  550,  547,  550,  548,  550,  550,  550,  550,  546,\n      550,  550,  550,  550,  550,  549,  550,  550,  550,  550,\n      550,  313,  313,  313,  313,  313,  313,  130,  214,  214,\n      214,  130,  550,   47,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  315,  550,  550,  550,\n      550,  550,  550,  315,  315,  315,  315,  315,  315,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,   48,\n      550,  550,  315,  315,  315,  315,  315,  315,  316,  550,\n      550,  550,  550,  550,  550,  316,  316,  316,  316,  316,\n\n      316,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  316,  316,  316,  316,  316,  316,\n      317,  550,  550,  550,  550,  550,  550,  317,  317,  317,\n      317,  317,  317,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  317,  317,  317,  317,\n      317,  317,  318,  550,  550,  550,  550,  550,  550,  318,\n      318,  318,  318,  318,  318,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  318,  318,\n      318,  318,  318,  318,  320,  550,  550,  550,  550,  550,\n      550,  320,  320,  320,  320,  320,  320,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      320,  320,  320,  320,  320,  320,  321,  550,  550,  550,\n      550,  550,  550,  321,  321,  321,  321,  321,  321,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  321,  321,  321,  321,  321,  321,  325,  550,\n\n      550,  550,  550,  550,  550,  325,  325,  325,  325,  325,\n      325,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  325,  325,  325,  325,  325,  325,\n      333,  550,  550,  550,  550,  550,  550,  333,  333,  333,\n      333,  333,  333,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  333,  333,  333,  333,\n      333,  333,  334,  550,  550,  550,  550,  550,  550,  334,\n      334,  334,  334,  334,  334,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  334,  334,\n      334,  334,  334,  334,  342,  342,  342,  342,  348,  550,\n      350,  550,  550,  550,  550,  350,  350,  351,  550,  550,\n      550,  550,  550,  352,  550,  550,  550,  550,  550,  550,\n      352,  352,  352,  352,  352,  352,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  353,  550,  550,  352,\n      352,  352,  352,  352,  352,  116,  116,  116,  116,  116,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  354,  550,  550,  550,  550,  550,\n      550,  354,  354,  354,  354,  354,  354,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      354,  354,  354,  354,  354,  354,  130,  214,  214,  214,\n      130,  550,   47,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  356,  550,  550,  550,  550,\n      550,  550,  356,  356,  356,  356,  356,  356,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,   48,  550,\n\n      550,  356,  356,  356,  356,  356,  356,  216,  216,  216,\n      216,  216,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  357,  550,  550,  550,\n      550,  550,  550,  357,  357,  357,  357,  357,  357,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  136,\n      550,  550,  357,  357,  357,  357,  357,  357,  137,  137,\n      137,  137,  137,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  358,  550,  550,\n      550,  550,  550,  550,  358,  358,  358,  358,  358,  358,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      136,  550,  550,  358,  358,  358,  358,  358,  358,  140,\n      219,  219,  219,  140,  550,  550,  550,  550,  550,  550,\n       47,  550,  550,  550,  550,  550,  550,  550,  359,  550,\n      550,  550,  550,  550,  550,  359,  359,  359,  359,  359,\n      359,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,   56,  550,  550,  359,  359,  359,  359,  359,  359,\n      361,  550,  550,  550,  550,  550,  550,  361,  361,  361,\n\n      361,  361,  361,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  361,  361,  361,  361,\n      361,  361,  362,  550,  550,  550,  550,  550,  550,  362,\n      362,  362,  362,  362,  362,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  362,  362,\n      362,  362,  362,  362,  365,  550,  550,  550,  550,  550,\n      550,  365,  365,  365,  365,  365,  365,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      365,  365,  365,  365,  365,  365,  372,  550,  550,  550,\n      550,  550,  550,  372,  372,  372,  372,  372,  372,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  372,  372,  372,  372,  372,  372,  373,  550,\n      550,  550,  550,  550,  550,  373,  373,  373,  373,  373,\n      373,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  373,  373,  373,  373,  373,  373,\n\n      343,  343,  343,  384,  550,  550,  386,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  387,\n      550,  550,  550,  550,  550,  550,  387,  387,  387,  387,\n      387,  387,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  388,  550,  550,  387,  387,  387,  387,  387,\n      387,  346,  346,  346,  389,  550,  550,  550,  550,  550,\n      550,  550,  391,  550,  550,  550,  550,  550,  550,  550,\n      392,  550,  550,  550,  550,  550,  550,  392,  392,  392,\n      392,  392,  392,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  393,  550,  550,  392,  392,  392,  392,\n      392,  392,  348,  348,  348,  348,  348,  550,  550,  550,\n      550,  550,  550,  550,  550,  311,  550,  550,  550,  550,\n      550,  394,  550,  550,  550,  550,  550,  550,  394,  394,\n      394,  394,  394,  394,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  312,  550,  550,  394,  394,  394,\n      394,  394,  394,  342,  342,  342,  342,  348,  550,  350,\n      550,  550,  550,  550,  350,  350,  351,  550,  550,  550,\n\n      550,  550,  352,  550,  550,  550,  550,  550,  550,  352,\n      352,  352,  352,  352,  352,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  353,  550,  550,  352,  352,\n      352,  352,  352,  352,  116,  116,  116,  116,  116,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  395,  550,  550,  550,  550,  550,  550,\n      395,  395,  395,  395,  395,  395,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  395,\n\n      395,  395,  395,  395,  395,  130,  214,  214,  214,  130,\n      550,   47,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  397,  550,  550,  550,  550,  550,\n      550,  397,  397,  397,  397,  397,  397,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,   48,  550,  550,\n      397,  397,  397,  397,  397,  397,  216,  216,  216,  216,\n      216,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  398,  550,  550,  550,  550,\n      550,  550,  398,  398,  398,  398,  398,  398,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  136,  550,\n      550,  398,  398,  398,  398,  398,  398,  137,  137,  137,\n      137,  137,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  399,  550,  550,  550,\n      550,  550,  550,  399,  399,  399,  399,  399,  399,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  136,\n      550,  550,  399,  399,  399,  399,  399,  399,  140,  219,\n      219,  219,  140,  550,  550,  550,  550,  550,  550,   47,\n\n      550,  550,  550,  550,  550,  550,  550,  400,  550,  550,\n      550,  550,  550,  550,  400,  400,  400,  400,  400,  400,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n       56,  550,  550,  400,  400,  400,  400,  400,  400,  224,\n      224,  224,  224,  224,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  402,  550,\n      550,  550,  550,  550,  550,  402,  402,  402,  402,  402,\n      402,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  402,  402,  402,  402,  402,  402,\n      174,  174,  174,  174,  174,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  403,\n      550,  550,  550,  550,  550,  550,  403,  403,  403,  403,\n      403,  403,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  403,  403,  403,  403,  403,\n      403,  406,  550,  550,  550,  550,  550,  550,  406,  406,\n      406,  406,  406,  406,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  406,  406,  406,\n      406,  406,  406,  412,  550,  550,  550,  550,  550,  550,\n      412,  412,  412,  412,  412,  412,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  412,\n      412,  412,  412,  412,  412,  413,  550,  550,  550,  550,\n      550,  550,  413,  413,  413,  413,  413,  413,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  413,  413,  413,  413,  413,  413,  385,  425,  425,\n\n      425,  385,  550,  344,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  426,  550,  550,  550,\n      550,  550,  550,  426,  426,  426,  426,  426,  426,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  345,\n      550,  550,  426,  426,  426,  426,  426,  426,  343,  343,\n      343,  384,  550,  550,  386,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  387,  550,  550,\n      550,  550,  550,  550,  387,  387,  387,  387,  387,  387,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      388,  550,  550,  387,  387,  387,  387,  387,  387,  390,\n      429,  429,  429,  390,  550,  550,  550,  550,  550,  550,\n      344,  550,  550,  550,  550,  550,  550,  550,  430,  550,\n      550,  550,  550,  550,  550,  430,  430,  430,  430,  430,\n      430,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  347,  550,  550,  430,  430,  430,  430,  430,  430,\n      346,  346,  346,  389,  550,  550,  550,  550,  550,  550,\n      550,  391,  550,  550,  550,  550,  550,  550,  550,  392,\n\n      550,  550,  550,  550,  550,  550,  392,  392,  392,  392,\n      392,  392,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  393,  550,  550,  392,  392,  392,  392,  392,\n      392,  348,  348,  348,  348,  348,  550,  550,  550,  550,\n      550,  550,  550,  550,  311,  550,  550,  550,  550,  550,\n      431,  550,  550,  550,  550,  550,  550,  431,  431,  431,\n      431,  431,  431,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  312,  550,  550,  431,  431,  431,  431,\n\n      431,  431,  216,  216,  216,  216,  216,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  433,  550,  550,  550,  550,  550,  550,  433,  433,\n      433,  433,  433,  433,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  433,  433,  433,\n      433,  433,  433,  435,  550,  550,  550,  550,  550,  550,\n      435,  435,  435,  435,  435,  435,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  435,\n\n      435,  435,  435,  435,  435,  174,  174,  174,  174,  174,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  149,  550,  550,  550,  550,  550,\n      550,  149,  149,  149,  149,  149,  149,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      149,  149,  149,  149,  149,  149,  243,  243,  243,  243,\n      243,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  438,  550,  550,  550,  550,\n      550,  550,  438,  438,  438,  438,  438,  438,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  438,  438,  438,  438,  438,  438,  445,  550,  550,\n      550,  550,  550,  550,  445,  445,  445,  445,  445,  445,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  445,  445,  445,  445,  445,  445,  446,\n      550,  550,  550,  550,  550,  550,  446,  446,  446,  446,\n      446,  446,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  446,  446,  446,  446,  446,\n      446,  348,  348,  348,  348,  348,  550,  550,  550,  550,\n      550,  550,  550,  550,  311,  550,  550,  550,  550,  550,\n      447,  550,  550,  550,  550,  550,  550,  447,  447,  447,\n      447,  447,  447,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  312,  550,  550,  447,  447,  447,  447,\n      447,  447,  457,  550,  550,  550,  550,  550,  550,  457,\n      457,  457,  457,  457,  457,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  457,  457,\n      457,  457,  457,  457,  458,  550,  550,  550,  550,  550,\n      550,  458,  458,  458,  458,  458,  458,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      458,  458,  458,  458,  458,  458,  459,  550,  550,  550,\n      550,  550,  550,  459,  459,  459,  459,  459,  459,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  459,  459,  459,  459,  459,  459,  464,  550,\n\n      550,  550,  550,  550,  550,  464,  464,  464,  464,  464,\n      464,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  464,  464,  464,  464,  464,  464,\n      465,  550,  550,  550,  550,  550,  550,  465,  465,  465,\n      465,  465,  465,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  465,  465,  465,  465,\n      465,  465,  466,  550,  550,  550,  550,  550,  550,  466,\n      466,  466,  466,  466,  466,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  466,  466,\n      466,  466,  466,  466,  468,  550,  550,  550,  550,  550,\n      550,  469,  550,  470,  550,  550,  550,  550,  471,  472,\n      550,  550,  473,  550,  550,  550,  550,  181,  550,  550,\n      550,  550,  550,  468,  550,  550,  550,  550,  550,  469,\n      550,  470,  550,  550,  550,  550,  471,  472,  550,  550,\n      473,  476,  550,  550,  550,  550,  550,  550,  476,  476,\n      476,  476,  476,  476,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  476,  476,  476,\n      476,  476,  476,  477,  550,  550,  550,  550,  550,  550,\n      477,  477,  477,  477,  477,  477,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  477,\n      477,  477,  477,  477,  477,   46,  550,  550,   46,   46,\n       46,   46,   46,   46,   46,   46,   46,   46,   52,   52,\n      550,   52,   52,   55,  550,  550,   55,   55,   55,   55,\n       55,   55,   55,   55,   55,   55,   61,   61,  550,   61,\n       61,   91,  550,  550,   91,   91,  102,  550,  102,  102,\n\n      550,  102,  102,  116,  116,  116,  116,  116,  116,  116,\n      116,  116,  116,  130,  130,  130,  130,  130,  130,  130,\n      130,  130,  130,  130,  130,  130,  134,  134,  550,  134,\n      134,  137,  137,  137,  137,  137,  137,  137,  137,  137,\n      137,  140,  140,  140,  140,  140,  140,  140,  140,  140,\n      140,  140,  140,  140,  146,  146,  146,  146,  146,  146,\n      146,  146,  146,  146,  146,  146,  146,  146,  149,  149,\n      149,  550,  149,  149,  174,  174,  174,  174,  174,  174,\n      174,  174,  174,  174,  180,  180,  550,  180,  180,  190,\n      190,  190,  190,  190,  190,  190,  190,  190,  190,  193,\n\n      193,  193,  193,  193,  193,  193,  193,  193,  193,  204,\n      204,  204,  216,  216,  216,  216,  216,  216,  216,  216,\n      216,  216,  140,  140,  140,  140,  140,  140,  140,  140,\n      140,  140,  140,  140,  140,  222,  222,  222,  222,  222,\n      222,  222,  222,  222,  222,  222,  222,  222,  222,  224,\n      224,  224,  224,  224,  224,  224,  224,  224,  224,  243,\n      243,  243,  243,  243,  243,  243,  243,  243,  243,  263,\n      263,  263,  263,  275,  275,  275,  275,  275,  275,  275,\n      275,  275,  275,  275,  275,  275,  275,  303,  303,  303,\n      303,  308,  308,  308,  308,  308,  308,  550,  308,  308,\n\n      308,  308,  308,  308,  222,  222,  222,  222,  222,  222,\n      222,  222,  222,  222,  222,  222,  222,  222,  337,  337,\n      337,  337,  308,  308,  308,  308,  308,  308,  550,  308,\n      308,  308,  308,  308,  308,  343,  550,  550,  343,  343,\n      343,  343,  343,  343,  343,  343,  343,  343,  346,  550,\n      550,  346,  346,  346,  346,  346,  346,  346,  346,  346,\n      346,  349,  349,  349,  349,  349,  349,  349,  349,  349,\n      349,  349,  349,  349,   46,   46,   46,   46,   46,   46,\n       46,   46,   46,   46,   46,   46,   46,  134,  134,  134,\n      134,  550,  550,  550,  550,  134,  134,  550,  134,  134,\n\n       55,   55,   55,   55,   55,   55,   55,   55,   55,   55,\n       55,   55,   55,  376,  376,  376,  376,  385,  385,  385,\n      385,  385,  385,  385,  385,  385,  385,  385,  385,  385,\n      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,\n      390,  390,  390,  308,  308,  308,  308,  308,  550,  550,\n      308,  308,  308,  308,  308,  308,  349,  349,  349,  349,\n      349,  349,  349,  349,  349,  349,  349,  349,  349,   46,\n       46,   46,   46,   46,   46,   46,   46,   46,   46,   46,\n       46,   46,  134,  134,  134,  134,  550,  550,  550,  550,\n      134,  134,  550,  134,  134,   55,   55,   55,   55,   55,\n\n       55,   55,   55,   55,   55,   55,   55,   55,  416,  416,\n      416,  416,  385,  385,  385,  385,  385,  385,  385,  385,\n      385,  385,  385,  385,  385,  346,  346,  550,  346,  346,\n      346,  346,  346,  346,  346,  346,  346,  346,  390,  390,\n      390,  390,  390,  390,  390,  390,  390,  390,  390,  390,\n      390,  308,  308,  308,  308,  308,  550,  550,  308,  308,\n      308,  308,  308,  308,    7,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550\n    } ;\n\nstatic yyconst flex_int16_t yy_chk[5551] =\n    {   0,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    3,    5,    4,    6,   49,\n       15,    3,   49,    4,    9,    9,    9,    9,    9,    5,\n\n        5,    6,    6,   12,    3,    3,    4,    4,   10,   10,\n       10,   10,   10,   25,   45,    5,   24,    6,  290,  549,\n        3,   17,    4,   18,   27,   49,   18,    5,    5,    6,\n        6,   15,    3,    3,    4,    4,   11,   11,   11,   11,\n       11,   17,   45,   24,   26,    3,   18,    4,   55,   12,\n       36,   28,   27,   25,  290,   18,   24,   30,   26,   18,\n       30,   61,   46,  547,   27,   28,   92,   42,  147,   17,\n       11,   24,  147,   28,   18,  539,   58,   36,   26,  130,\n       27,   71,   40,   18,   26,   92,  530,   26,   30,   55,\n       36,   28,   38,  140,   28,   92,   58,   30,   42,   11,\n\n       13,   61,   28,   13,  131,   36,   26,   42,   46,   40,\n       13,   13,   13,   13,   13,   13,   30,   84,   71,   38,\n       88,   93,   40,   38,   58,  130,   42,   43,   43,   43,\n       43,   43,   38,   93,  140,  523,   13,   40,  204,   13,\n       13,   13,   13,   13,   13,   21,  204,   38,  263,   93,\n      131,   38,   21,   21,   84,   21,  263,   88,  559,   88,\n      559,  520,   21,   21,   21,   21,   21,   21,   21,   21,\n       21,   21,   21,   21,   21,   21,   21,   21,   21,   21,\n       21,   21,   21,   21,   21,   21,   21,   21,   21,  102,\n       21,   21,   21,   21,   21,   21,   21,   21,   21,   21,\n\n       21,   21,   21,   21,   21,   21,   21,   21,   21,   21,\n       21,   21,   21,   21,   21,   21,   94,  276,  509,   21,\n       23,  276,   78,   97,   44,   44,   44,   44,   44,  102,\n       94,  129,   23,  504,   98,   23,  129,  141,   23,  499,\n       23,   99,   23,   23,   94,   23,   78,   99,   23,   97,\n       29,   29,   97,   29,   29,   65,   23,   65,   44,   78,\n       98,   23,   29,   98,   23,   29,   29,   23,   23,   99,\n       23,   23,  454,   23,   78,  128,   23,   65,  141,   77,\n       37,   37,  129,   37,   37,   41,   41,   44,   41,   41,\n       29,  453,   37,   63,  452,   37,   37,   41,   73,  116,\n\n       41,   41,   29,  128,  124,   65,   59,   59,  213,   59,\n       59,   63,   95,   73,  149,   77,   77,   75,   29,   31,\n       37,   59,   59,  214,   73,   41,   31,   31,   31,   31,\n       31,   31,   37,   63,   95,   73,  213,   41,  151,  116,\n       63,   95,   73,   77,  124,   75,   76,   80,   37,   96,\n      442,  149,   73,   41,   75,   31,   31,   31,   31,   31,\n       31,   48,   48,   48,   48,  405,  127,   48,  416,  214,\n       80,   96,  139,   75,   76,  151,   80,   72,   96,  185,\n       48,  185,  139,   76,   80,  192,  242,   48,   48,   48,\n       48,   48,   48,   62,   62,   72,   62,   62,   80,  407,\n\n       72,  405,   76,   74,   80,   62,  127,  185,   62,   62,\n      152,  242,  155,   48,   72,  242,   48,   48,   48,   48,\n       48,   48,   51,  139,   72,  192,   74,  105,   72,   51,\n       51,   51,   51,   51,   51,   81,   81,   74,   81,   81,\n       74,  156,  157,  309,  103,   62,  381,  152,   79,  155,\n       81,   81,  105,  380,   74,   51,   82,   85,   51,   51,\n       51,   51,   51,   51,   53,   74,   79,  105,  186,   82,\n      379,   53,   53,   53,   53,   53,   53,  378,  156,  157,\n      105,  106,  103,  107,  103,   79,   82,   81,   85,  309,\n       82,  186,  269,   82,   85,   79,  377,  186,   82,  106,\n\n       53,   53,   53,   53,   53,   53,   56,   56,   56,   56,\n      103,   83,  247,   90,   82,  107,   85,   56,   82,   86,\n      269,  106,   83,  107,  247,   56,   83,  368,  106,  115,\n      188,   90,   56,   56,   56,   56,   56,   56,  341,  303,\n      247,  109,   86,  107,  340,   90,  108,  303,   83,   90,\n      188,   83,   86,  159,  115,   83,   86,  145,   56,  188,\n       90,   56,   56,   56,   56,   56,   56,   64,  109,  115,\n       86,  219,  145,   90,   64,   64,   64,   64,   64,   64,\n       86,  109,  115,  108,  110,  110,  108,  110,  110,  123,\n      159,  111,  111,  160,  111,  111,  109,  145,  339,  110,\n\n      110,  145,  161,   64,   64,   64,   64,   64,   64,   87,\n      111,  108,  219,  310,  123,  162,   87,   87,   87,   87,\n       87,   87,  112,  112,  113,  112,  112,  178,  163,  123,\n      160,  338,  193,  158,  112,  122,  126,  330,  161,  161,\n      178,  112,  123,  166,  158,   87,   87,   87,   87,   87,\n       87,  100,  162,  187,  310,  178,  306,  113,  100,  100,\n      100,  100,  100,  100,  113,  163,  161,  187,  122,  126,\n      158,  167,  193,  158,  112,  122,  126,  121,  125,  305,\n      166,  187,  153,  168,  169,  113,  196,  100,  100,  100,\n      100,  100,  100,  104,  121,  125,  122,  126,  169,  153,\n\n      104,  104,  104,  104,  104,  104,  164,  164,  167,  164,\n      164,  173,  171,  174,  224,  121,  125,  121,  125,  153,\n      168,  169,  170,  121,  125,  164,  196,  169,  153,  104,\n      104,  104,  104,  104,  104,  117,  117,  117,  117,  117,\n      171,  198,  199,  121,  125,  170,  182,  117,  173,  171,\n      174,  224,  165,  165,  117,  165,  165,  179,  304,  170,\n      249,  117,  117,  117,  117,  117,  117,  165,  171,  172,\n      202,  165,  182,  170,  176,  182,  226,  202,  249,  179,\n      172,  198,  199,  228,  564,  564,  179,  117,  172,  249,\n      117,  117,  117,  117,  117,  117,  132,  132,  132,  132,\n\n      132,  176,  132,  183,  165,  195,  172,  184,  189,  172,\n      202,  176,  231,  226,  314,  132,  183,  172,  184,  189,\n      228,  195,  132,  132,  132,  132,  132,  132,  197,  176,\n      203,  183,  206,  208,  209,  184,  189,  210,  211,  212,\n      221,  295,  314,  200,  200,  195,  200,  200,  132,  231,\n      195,  132,  132,  132,  132,  132,  132,  133,  133,  133,\n      133,  197,  200,  133,  221,  232,  256,  230,  197,  232,\n      203,  227,  206,  208,  209,  210,  133,  210,  211,  212,\n      221,  230,  233,  133,  133,  133,  133,  133,  133,  197,\n      337,  268,  221,  275,  227,  234,  265,  235,  337,  229,\n\n      237,  236,  232,  210,  230,  278,  256,  346,  227,  133,\n      230,  245,  133,  133,  133,  133,  133,  133,  135,  233,\n      245,  235,  227,  264,  237,  135,  135,  135,  135,  135,\n      135,  268,  234,  229,  235,  236,  229,  237,  236,  245,\n      258,  279,  278,  343,  258,  280,  241,  239,  346,  235,\n      243,  135,  237,  241,  135,  135,  135,  135,  135,  135,\n      136,  229,  239,  236,  248,  222,  246,  136,  136,  136,\n      136,  136,  136,  246,  241,  281,  282,  283,  279,  252,\n      258,  355,  280,  322,  239,  248,  250,  251,  285,  343,\n      252,  239,  216,  248,  246,  286,  136,  136,  136,  136,\n\n      136,  136,  138,  138,  138,  138,  138,  252,  250,  251,\n      355,  285,  281,  282,  283,  250,  251,  286,  291,  205,\n      322,  138,  326,  201,  286,  285,  287,  291,  138,  138,\n      138,  138,  138,  138,  266,  266,  266,  266,  266,  285,\n      266,  289,  287,  292,  326,  266,  291,  266,  274,  289,\n      293,  326,  292,  396,  287,  335,  296,  138,  138,  138,\n      138,  138,  138,  142,  142,  142,  142,  142,  296,  289,\n      274,  292,  294,  319,  142,  578,  293,  578,  329,  293,\n      294,  396,  142,  335,  296,  324,  266,  327,  274,  142,\n      142,  142,  142,  142,  142,  335,  301,  376,  389,  274,\n\n      294,  323,  328,  324,  329,  376,  319,  329,  327,  328,\n      323,  335,  301,  319,  324,  142,  327,  331,  142,  142,\n      142,  142,  142,  142,  143,  143,  143,  143,  331,  323,\n      328,  467,  190,  332,  319,  143,  301,  364,  390,  389,\n      385,  301,  332,  143,  364,  331,  367,  180,  390,  369,\n      143,  143,  143,  143,  143,  143,  307,  307,  307,  307,\n      307,  332,  307,  369,  360,  364,  177,  307,  360,  307,\n      146,  467,  367,  424,  425,  367,  143,  369,  363,  143,\n      143,  143,  143,  143,  143,  150,  385,  432,  370,  390,\n      154,  363,  150,  150,  150,  150,  150,  150,  342,  342,\n\n      342,  342,  342,  154,  360,  366,  363,  408,  307,  154,\n      374,  342,  366,  137,  370,  432,  154,  370,  450,  424,\n      425,  150,  150,  150,  150,  150,  150,  154,  582,  134,\n      582,  408,  154,  366,  114,   91,  408,  374,  154,  344,\n      344,  344,  344,  344,  154,  175,  175,  175,  175,  175,\n      374,   89,  344,  401,  450,  308,  308,  308,  308,  308,\n      175,  308,   69,  371,  175,  374,  308,  409,  308,  401,\n      371,  175,  175,  175,  175,  175,  175,  348,  348,  348,\n      348,  348,  349,  349,  349,  349,  349,  384,   68,  409,\n      348,  371,  384,  401,   67,  349,  409,  175,  401,  474,\n\n      175,  175,  175,  175,  175,  175,  181,  308,  350,  350,\n      350,  350,  350,  181,  181,  181,  181,  181,  181,  506,\n      474,  350,  382,  382,  382,  382,  382,  404,  474,  348,\n      410,   66,   60,  411,  349,  382,   52,  591,  384,  591,\n      414,  411,  181,  181,  181,  181,  181,  181,  191,  191,\n      191,  191,  191,  404,  410,  506,  404,   34,  475,  410,\n      350,  411,  399,  399,  399,  399,  399,  191,  351,  351,\n      351,  351,  351,  414,  191,  191,  191,  191,  191,  191,\n      414,  351,  386,  386,  386,  386,  386,   33,  386,  435,\n      435,  435,  435,  435,   32,  386,  521,  439,  475,   22,\n\n      191,  414,  436,  191,  191,  191,  191,  191,  191,  194,\n      194,  194,  194,  194,  399,  434,  600,  436,  600,  439,\n      351,  395,  395,  395,  395,  395,  439,   20,  194,  434,\n      436,   19,  521,  395,  386,  194,  194,  194,  194,  194,\n      194,  391,  391,  391,  391,  391,  428,  397,  397,  397,\n      397,  397,  391,  397,  391,  434,  428,  606,  434,  606,\n      437,   16,  501,  440,  194,  194,  194,  194,  194,  194,\n      207,  440,   14,  395,  501,    7,  437,  207,  207,  207,\n      207,  207,  207,  400,  400,  400,  400,  400,  437,  455,\n      501,  440,  471,  391,  400,  441,  449,  428,  471,  397,\n\n      412,  412,  412,  412,  412,  503,  207,  207,  207,  207,\n      207,  207,  215,  215,  215,  215,  215,  441,  215,  503,\n      471,  449,    0,  462,  441,  462,  455,  429,  451,  455,\n      524,  215,  607,  503,  607,  400,  449,  429,  215,  215,\n      215,  215,  215,  215,  413,  413,  413,  413,  413,  449,\n      451,  462,  412,  480,  455,  480,  413,  451,  433,  433,\n      433,  433,  433,    0,  215,  473,  524,  215,  215,  215,\n      215,  215,  215,  217,  217,  217,  217,  217,  429,  460,\n      443,  480,    0,    0,  423,  423,  423,  423,  423,  535,\n      423,  473,  217,  479,  473,  460,  413,  423,  443,  217,\n\n      217,  217,  217,  217,  217,  427,  427,  427,  427,  427,\n      433,  438,  438,  438,  438,  438,  427,  479,  427,  460,\n      443,  463,  479,    0,  460,  535,  495,  443,  217,  217,\n      217,  217,  217,  217,  218,  481,  423,  468,    0,    0,\n      469,  218,  218,  218,  218,  218,  218,  466,  466,  466,\n      466,  466,  495,  482,  463,  495,    0,  427,  481,  468,\n      466,  463,  469,  438,  481,  483,  468,  470,  482,  469,\n      218,  218,  218,  218,  218,  218,  220,    0,    0,  472,\n      483,  482,  463,  220,  220,  220,  220,  220,  220,  470,\n        0,    0,    0,  483,    0,  472,  470,    0,    0,  466,\n\n        0,  472,    0,  476,  476,  476,  476,  476,  472,  476,\n      485,    0,  220,  220,  220,  220,  220,  220,  225,  225,\n      225,  225,  225,  472,  484,  485,  488,    0,  477,  477,\n      477,  477,  477,  486,  491,  484,  489,  225,  485,  477,\n      490,  488,  486,  496,  225,  225,  225,  225,  225,  225,\n        0,  496,  484,  493,  488,  476,  491,  489,  490,    0,\n        0,  486,    0,  491,  493,  489,  494,    0,  512,  490,\n      492,  496,  494,  225,  225,  225,  225,  225,  225,  238,\n      477,  493,  498,  512,  497,  500,  238,  238,  238,  238,\n      238,  238,  492,  497,  494,    0,  512,    0,    0,  492,\n\n      507,  505,    0,    0,  502,    0,    0,  507,  498,  500,\n      510,  498,  497,    0,  500,  238,  238,  238,  238,  238,\n      238,  244,  244,  244,  244,  244,  502,  505,  507,  508,\n      505,  511,  510,  502,  513,  514,  515,  517,  508,  510,\n      244,  531,  514,  516,  515,  511,  513,  244,  244,  244,\n      244,  244,  244,  531,    0,  517,  540,  508,  518,  511,\n      519,    0,  513,  514,  515,  516,  517,  518,  519,  531,\n        0,  527,  516,    0,  540,  522,  244,  244,  244,  244,\n      244,  244,  253,  522,  528,  540,  518,    0,  519,  253,\n      253,  253,  253,  253,  253,  527,    0,    0,  526,  533,\n\n      527,  529,  532,  522,  532,  526,  528,  529,    0,  525,\n        0,    0,    0,  528,  533,  534,  525,  536,  253,  253,\n      253,  253,  253,  253,  255,  525,  526,  533,  534,  529,\n      532,  255,  255,  255,  255,  255,  255,  525,    0,  536,\n        0,    0,    0,  534,  525,    0,  536,  543,  537,    0,\n      542,    0,    0,    0,  541,  543,    0,  542,  538,    0,\n      255,  255,  255,  255,  255,  255,  267,  267,  267,  267,\n      267,  537,  541,  538,  545,  543,  546,  537,  542,    0,\n      544,  545,    0,  541,    0,  267,  538,  548,  546,    0,\n        0,    0,  267,  267,  267,  267,  267,  267,  544,    0,\n\n      548,    0,  545,    0,  546,    0,    0,    0,    0,  544,\n        0,    0,    0,    0,    0,  548,    0,    0,    0,    0,\n        0,  267,  267,  267,  267,  267,  267,  270,  270,  270,\n      270,  270,    0,  270,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  270,    0,    0,    0,\n        0,    0,    0,  270,  270,  270,  270,  270,  270,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  270,\n        0,    0,  270,  270,  270,  270,  270,  270,  271,    0,\n        0,    0,    0,    0,    0,  271,  271,  271,  271,  271,\n\n      271,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  271,  271,  271,  271,  271,  271,\n      272,    0,    0,    0,    0,    0,    0,  272,  272,  272,\n      272,  272,  272,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  272,  272,  272,  272,\n      272,  272,  273,    0,    0,    0,    0,    0,    0,  273,\n      273,  273,  273,  273,  273,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,  273,  273,\n      273,  273,  273,  273,  277,    0,    0,    0,    0,    0,\n        0,  277,  277,  277,  277,  277,  277,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      277,  277,  277,  277,  277,  277,  284,    0,    0,    0,\n        0,    0,    0,  284,  284,  284,  284,  284,  284,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  284,  284,  284,  284,  284,  284,  288,    0,\n\n        0,    0,    0,    0,    0,  288,  288,  288,  288,  288,\n      288,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  288,  288,  288,  288,  288,  288,\n      297,    0,    0,    0,    0,    0,    0,  297,  297,  297,\n      297,  297,  297,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  297,  297,  297,  297,\n      297,  297,  298,    0,    0,    0,    0,    0,    0,  298,\n      298,  298,  298,  298,  298,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  298,  298,\n      298,  298,  298,  298,  312,  312,  312,  312,  312,    0,\n      312,    0,    0,    0,    0,  312,  312,  312,    0,    0,\n        0,    0,    0,  312,    0,    0,    0,    0,    0,    0,\n      312,  312,  312,  312,  312,  312,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  312,    0,    0,  312,\n      312,  312,  312,  312,  312,  313,  313,  313,  313,  313,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,  313,    0,    0,    0,    0,    0,\n        0,  313,  313,  313,  313,  313,  313,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      313,  313,  313,  313,  313,  313,  315,  315,  315,  315,\n      315,    0,  315,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  315,    0,    0,    0,    0,\n        0,    0,  315,  315,  315,  315,  315,  315,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  315,    0,\n\n        0,  315,  315,  315,  315,  315,  315,  316,  316,  316,\n      316,  316,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  316,    0,    0,    0,\n        0,    0,    0,  316,  316,  316,  316,  316,  316,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  316,\n        0,    0,  316,  316,  316,  316,  316,  316,  317,  317,\n      317,  317,  317,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  317,    0,    0,\n        0,    0,    0,    0,  317,  317,  317,  317,  317,  317,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      317,    0,    0,  317,  317,  317,  317,  317,  317,  318,\n      318,  318,  318,  318,    0,    0,    0,    0,    0,    0,\n      318,    0,    0,    0,    0,    0,    0,    0,  318,    0,\n        0,    0,    0,    0,    0,  318,  318,  318,  318,  318,\n      318,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  318,    0,    0,  318,  318,  318,  318,  318,  318,\n      320,    0,    0,    0,    0,    0,    0,  320,  320,  320,\n\n      320,  320,  320,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  320,  320,  320,  320,\n      320,  320,  321,    0,    0,    0,    0,    0,    0,  321,\n      321,  321,  321,  321,  321,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  321,  321,\n      321,  321,  321,  321,  325,    0,    0,    0,    0,    0,\n        0,  325,  325,  325,  325,  325,  325,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      325,  325,  325,  325,  325,  325,  333,    0,    0,    0,\n        0,    0,    0,  333,  333,  333,  333,  333,  333,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  333,  333,  333,  333,  333,  333,  334,    0,\n        0,    0,    0,    0,    0,  334,  334,  334,  334,  334,\n      334,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  334,  334,  334,  334,  334,  334,\n\n      345,  345,  345,  345,    0,    0,  345,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  345,\n        0,    0,    0,    0,    0,    0,  345,  345,  345,  345,\n      345,  345,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  345,    0,    0,  345,  345,  345,  345,  345,\n      345,  347,  347,  347,  347,    0,    0,    0,    0,    0,\n        0,    0,  347,    0,    0,    0,    0,    0,    0,    0,\n      347,    0,    0,    0,    0,    0,    0,  347,  347,  347,\n      347,  347,  347,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  347,    0,    0,  347,  347,  347,  347,\n      347,  347,  352,  352,  352,  352,  352,    0,    0,    0,\n        0,    0,    0,    0,    0,  352,    0,    0,    0,    0,\n        0,  352,    0,    0,    0,    0,    0,    0,  352,  352,\n      352,  352,  352,  352,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  352,    0,    0,  352,  352,  352,\n      352,  352,  352,  353,  353,  353,  353,  353,    0,  353,\n        0,    0,    0,    0,  353,  353,  353,    0,    0,    0,\n\n        0,    0,  353,    0,    0,    0,    0,    0,    0,  353,\n      353,  353,  353,  353,  353,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  353,    0,    0,  353,  353,\n      353,  353,  353,  353,  354,  354,  354,  354,  354,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  354,    0,    0,    0,    0,    0,    0,\n      354,  354,  354,  354,  354,  354,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  354,\n\n      354,  354,  354,  354,  354,  356,  356,  356,  356,  356,\n        0,  356,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  356,    0,    0,    0,    0,    0,\n        0,  356,  356,  356,  356,  356,  356,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  356,    0,    0,\n      356,  356,  356,  356,  356,  356,  357,  357,  357,  357,\n      357,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  357,    0,    0,    0,    0,\n        0,    0,  357,  357,  357,  357,  357,  357,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  357,    0,\n        0,  357,  357,  357,  357,  357,  357,  358,  358,  358,\n      358,  358,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  358,    0,    0,    0,\n        0,    0,    0,  358,  358,  358,  358,  358,  358,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  358,\n        0,    0,  358,  358,  358,  358,  358,  358,  359,  359,\n      359,  359,  359,    0,    0,    0,    0,    0,    0,  359,\n\n        0,    0,    0,    0,    0,    0,    0,  359,    0,    0,\n        0,    0,    0,    0,  359,  359,  359,  359,  359,  359,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      359,    0,    0,  359,  359,  359,  359,  359,  359,  361,\n      361,  361,  361,  361,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  361,    0,\n        0,    0,    0,    0,    0,  361,  361,  361,  361,  361,\n      361,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,  361,  361,  361,  361,  361,  361,\n      362,  362,  362,  362,  362,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  362,\n        0,    0,    0,    0,    0,    0,  362,  362,  362,  362,\n      362,  362,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  362,  362,  362,  362,  362,\n      362,  365,    0,    0,    0,    0,    0,    0,  365,  365,\n      365,  365,  365,  365,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,  365,  365,  365,\n      365,  365,  365,  372,    0,    0,    0,    0,    0,    0,\n      372,  372,  372,  372,  372,  372,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  372,\n      372,  372,  372,  372,  372,  373,    0,    0,    0,    0,\n        0,    0,  373,  373,  373,  373,  373,  373,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  373,  373,  373,  373,  373,  373,  387,  387,  387,\n\n      387,  387,    0,  387,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  387,    0,    0,    0,\n        0,    0,    0,  387,  387,  387,  387,  387,  387,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  387,\n        0,    0,  387,  387,  387,  387,  387,  387,  388,  388,\n      388,  388,    0,    0,  388,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  388,    0,    0,\n        0,    0,    0,    0,  388,  388,  388,  388,  388,  388,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      388,    0,    0,  388,  388,  388,  388,  388,  388,  392,\n      392,  392,  392,  392,    0,    0,    0,    0,    0,    0,\n      392,    0,    0,    0,    0,    0,    0,    0,  392,    0,\n        0,    0,    0,    0,    0,  392,  392,  392,  392,  392,\n      392,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  392,    0,    0,  392,  392,  392,  392,  392,  392,\n      393,  393,  393,  393,    0,    0,    0,    0,    0,    0,\n        0,  393,    0,    0,    0,    0,    0,    0,    0,  393,\n\n        0,    0,    0,    0,    0,    0,  393,  393,  393,  393,\n      393,  393,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  393,    0,    0,  393,  393,  393,  393,  393,\n      393,  394,  394,  394,  394,  394,    0,    0,    0,    0,\n        0,    0,    0,    0,  394,    0,    0,    0,    0,    0,\n      394,    0,    0,    0,    0,    0,    0,  394,  394,  394,\n      394,  394,  394,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  394,    0,    0,  394,  394,  394,  394,\n\n      394,  394,  398,  398,  398,  398,  398,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  398,    0,    0,    0,    0,    0,    0,  398,  398,\n      398,  398,  398,  398,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  398,  398,  398,\n      398,  398,  398,  402,    0,    0,    0,    0,    0,    0,\n      402,  402,  402,  402,  402,  402,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  402,\n\n      402,  402,  402,  402,  402,  403,  403,  403,  403,  403,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  403,    0,    0,    0,    0,    0,\n        0,  403,  403,  403,  403,  403,  403,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      403,  403,  403,  403,  403,  403,  406,  406,  406,  406,\n      406,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  406,    0,    0,    0,    0,\n        0,    0,  406,  406,  406,  406,  406,  406,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  406,  406,  406,  406,  406,  406,  426,    0,    0,\n        0,    0,    0,    0,  426,  426,  426,  426,  426,  426,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  426,  426,  426,  426,  426,  426,  430,\n        0,    0,    0,    0,    0,    0,  430,  430,  430,  430,\n      430,  430,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,  430,  430,  430,  430,  430,\n      430,  431,  431,  431,  431,  431,    0,    0,    0,    0,\n        0,    0,    0,    0,  431,    0,    0,    0,    0,    0,\n      431,    0,    0,    0,    0,    0,    0,  431,  431,  431,\n      431,  431,  431,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  431,    0,    0,  431,  431,  431,  431,\n      431,  431,  445,    0,    0,    0,    0,    0,    0,  445,\n      445,  445,  445,  445,  445,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,  445,  445,\n      445,  445,  445,  445,  446,    0,    0,    0,    0,    0,\n        0,  446,  446,  446,  446,  446,  446,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      446,  446,  446,  446,  446,  446,  447,    0,    0,    0,\n        0,    0,    0,  447,  447,  447,  447,  447,  447,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  447,  447,  447,  447,  447,  447,  457,    0,\n\n        0,    0,    0,    0,    0,  457,  457,  457,  457,  457,\n      457,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  457,  457,  457,  457,  457,  457,\n      458,    0,    0,    0,    0,    0,    0,  458,  458,  458,\n      458,  458,  458,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  458,  458,  458,  458,\n      458,  458,  459,    0,    0,    0,    0,    0,    0,  459,\n      459,  459,  459,  459,  459,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  459,  459,\n      459,  459,  459,  459,  461,    0,    0,    0,    0,    0,\n        0,  461,    0,  461,    0,    0,    0,    0,  461,  461,\n        0,    0,  461,    0,    0,    0,    0,  461,    0,    0,\n        0,    0,    0,  461,    0,    0,    0,    0,    0,  461,\n        0,  461,    0,    0,    0,    0,  461,  461,    0,    0,\n      461,  464,    0,    0,    0,    0,    0,    0,  464,  464,\n      464,  464,  464,  464,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,  464,  464,  464,\n      464,  464,  464,  465,    0,    0,    0,    0,    0,    0,\n      465,  465,  465,  465,  465,  465,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  465,\n      465,  465,  465,  465,  465,  551,    0,    0,  551,  551,\n      551,  551,  551,  551,  551,  551,  551,  551,  552,  552,\n        0,  552,  552,  553,    0,    0,  553,  553,  553,  553,\n      553,  553,  553,  553,  553,  553,  554,  554,    0,  554,\n      554,  555,    0,    0,  555,  555,  556,    0,  556,  556,\n\n        0,  556,  556,  557,  557,  557,  557,  557,  557,  557,\n      557,  557,  557,  558,  558,  558,  558,  558,  558,  558,\n      558,  558,  558,  558,  558,  558,  560,  560,    0,  560,\n      560,  561,  561,  561,  561,  561,  561,  561,  561,  561,\n      561,  562,  562,  562,  562,  562,  562,  562,  562,  562,\n      562,  562,  562,  562,  563,  563,  563,  563,  563,  563,\n      563,  563,  563,  563,  563,  563,  563,  563,  565,  565,\n      565,    0,  565,  565,  566,  566,  566,  566,  566,  566,\n      566,  566,  566,  566,  567,  567,    0,  567,  567,  568,\n      568,  568,  568,  568,  568,  568,  568,  568,  568,  569,\n\n      569,  569,  569,  569,  569,  569,  569,  569,  569,  570,\n      570,  570,  571,  571,  571,  571,  571,  571,  571,  571,\n      571,  571,  572,  572,  572,  572,  572,  572,  572,  572,\n      572,  572,  572,  572,  572,  573,  573,  573,  573,  573,\n      573,  573,  573,  573,  573,  573,  573,  573,  573,  574,\n      574,  574,  574,  574,  574,  574,  574,  574,  574,  575,\n      575,  575,  575,  575,  575,  575,  575,  575,  575,  576,\n      576,  576,  576,  577,  577,  577,  577,  577,  577,  577,\n      577,  577,  577,  577,  577,  577,  577,  579,  579,  579,\n      579,  580,  580,  580,  580,  580,  580,    0,  580,  580,\n\n      580,  580,  580,  580,  581,  581,  581,  581,  581,  581,\n      581,  581,  581,  581,  581,  581,  581,  581,  583,  583,\n      583,  583,  584,  584,  584,  584,  584,  584,    0,  584,\n      584,  584,  584,  584,  584,  585,    0,    0,  585,  585,\n      585,  585,  585,  585,  585,  585,  585,  585,  586,    0,\n        0,  586,  586,  586,  586,  586,  586,  586,  586,  586,\n      586,  587,  587,  587,  587,  587,  587,  587,  587,  587,\n      587,  587,  587,  587,  588,  588,  588,  588,  588,  588,\n      588,  588,  588,  588,  588,  588,  588,  589,  589,  589,\n      589,    0,    0,    0,    0,  589,  589,    0,  589,  589,\n\n      590,  590,  590,  590,  590,  590,  590,  590,  590,  590,\n      590,  590,  590,  592,  592,  592,  592,  593,  593,  593,\n      593,  593,  593,  593,  593,  593,  593,  593,  593,  593,\n      594,  594,  594,  594,  594,  594,  594,  594,  594,  594,\n      594,  594,  594,  595,  595,  595,  595,  595,    0,    0,\n      595,  595,  595,  595,  595,  595,  596,  596,  596,  596,\n      596,  596,  596,  596,  596,  596,  596,  596,  596,  597,\n      597,  597,  597,  597,  597,  597,  597,  597,  597,  597,\n      597,  597,  598,  598,  598,  598,    0,    0,    0,    0,\n      598,  598,    0,  598,  598,  599,  599,  599,  599,  599,\n\n      599,  599,  599,  599,  599,  599,  599,  599,  601,  601,\n      601,  601,  602,  602,  602,  602,  602,  602,  602,  602,\n      602,  602,  602,  602,  602,  603,  603,    0,  603,  603,\n      603,  603,  603,  603,  603,  603,  603,  603,  604,  604,\n      604,  604,  604,  604,  604,  604,  604,  604,  604,  604,\n      604,  605,  605,  605,  605,  605,    0,    0,  605,  605,\n      605,  605,  605,  605,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550,\n      550,  550,  550,  550,  550,  550,  550,  550,  550,  550\n    } ;\n\n/* Table of booleans, true if rule could match eol. */\nstatic yyconst flex_int32_t yy_rule_can_match_eol[91] =\n    {   0,\n1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, \n    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, \n    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \n    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, \n    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,     };\n\n/* The intent behind this definition is that it'll catch\n * any uses of REJECT which flex missed.\n */\n#define REJECT reject_used_but_not_detected\n#define yymore() yymore_used_but_not_detected\n#define YY_MORE_ADJ 0\n#define YY_RESTORE_YY_MORE_OFFSET\n/**\n* Copyright (c) 2015 QFish <im@QFi.sh>\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in\n* all copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n* THE SOFTWARE.\n*/\n/* Scanner-Options */\n\n/* // Unused options\n %option fast | meta-ecs\n %option noline\n %option header-file=\"katana.lex.h\"\n %option tables-file=\"katana.lex.tables\"\n %option bison-locations\n %option stack noyy_push_state noyy_pop_state noyy_top_state\n */\n\n/* Substitute the type names.  */\n#define YYSTYPE         KATANASTYPE\n#define YYLTYPE         KATANALTYPE\n\n#include \"tokenizer.h\"\n\nextern int katanalex \\\n            (YYSTYPE* yylval_param, YYLTYPE* yylloc, yyscan_t yyscanner, void* parser);\n\n#define YY_DECL int katanalex \\\n            (YYSTYPE * yylval_param, YYLTYPE* yylloc, yyscan_t yyscanner, void* parser)\n\n#define KATANA_TOKEN(x) katana_tokenize(yylval, yylloc, yyscanner, parser, x); return (x);\n#define YY_NO_INPUT\n\n#define YY_USER_ACTION /*yylloc->filename = filename;*/ \\\n        yylloc->first_line = yylloc->last_line = yylineno; \\\n        yylloc->first_column = yycolumn; yylloc->last_column = yycolumn+(int)yyleng-1; \\\n        yycolumn += (int)yyleng;\n\n#define INITIAL 0\n#define mediaquery 1\n#define supports 2\n\n#ifndef YY_NO_UNISTD_H\n/* Special case for \"unistd.h\", since it is non-ANSI. We include it way\n * down here because we want the user's section 1 to have been scanned first.\n * The user has a chance to override it with an option.\n */\n#include <unistd.h>\n#endif\n\n#ifndef YY_EXTRA_TYPE\n#define YY_EXTRA_TYPE void *\n#endif\n\n/* Holds the entire state of the reentrant scanner. */\nstruct yyguts_t\n    {\n\n    /* User-defined. Not touched by flex. */\n    YY_EXTRA_TYPE yyextra_r;\n\n    /* The rest are the same as the globals declared in the non-reentrant scanner. */\n    FILE *yyin_r, *yyout_r;\n    size_t yy_buffer_stack_top; /**< index of top of stack. */\n    size_t yy_buffer_stack_max; /**< capacity of stack. */\n    YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */\n    char yy_hold_char;\n    yy_size_t yy_n_chars;\n    yy_size_t yyleng_r;\n    char *yy_c_buf_p;\n    int yy_init;\n    int yy_start;\n    int yy_did_buffer_switch_on_eof;\n    int yy_start_stack_ptr;\n    int yy_start_stack_depth;\n    int *yy_start_stack;\n    yy_state_type yy_last_accepting_state;\n    char* yy_last_accepting_cpos;\n\n    int yylineno_r;\n    int yy_flex_debug_r;\n\n    char *yytext_r;\n    int yy_more_flag;\n    int yy_more_len;\n\n    YYSTYPE * yylval_r;\n\n    }; /* end struct yyguts_t */\n\nstatic int yy_init_globals (yyscan_t yyscanner );\n\n    /* This must go here because YYSTYPE and YYLTYPE are included\n     * from bison output in section 1.*/\n    #    define yylval yyg->yylval_r\n    \nint katanalex_init (yyscan_t* scanner);\n\nint katanalex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);\n\n/* Accessor methods to globals.\n   These are made visible to non-reentrant scanners for convenience. */\n\nint katanalex_destroy (yyscan_t yyscanner );\n\nint katanaget_debug (yyscan_t yyscanner );\n\nvoid katanaset_debug (int debug_flag ,yyscan_t yyscanner );\n\nYY_EXTRA_TYPE katanaget_extra (yyscan_t yyscanner );\n\nvoid katanaset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );\n\nFILE *katanaget_in (yyscan_t yyscanner );\n\nvoid katanaset_in  (FILE * in_str ,yyscan_t yyscanner );\n\nFILE *katanaget_out (yyscan_t yyscanner );\n\nvoid katanaset_out  (FILE * out_str ,yyscan_t yyscanner );\n\nyy_size_t katanaget_leng (yyscan_t yyscanner );\n\nchar *katanaget_text (yyscan_t yyscanner );\n\nint katanaget_lineno (yyscan_t yyscanner );\n\nvoid katanaset_lineno (int line_number ,yyscan_t yyscanner );\n\nint katanaget_column  (yyscan_t yyscanner );\n\nvoid katanaset_column (int column_no ,yyscan_t yyscanner );\n\nYYSTYPE * katanaget_lval (yyscan_t yyscanner );\n\nvoid katanaset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );\n\n/* Macros after this point can all be overridden by user definitions in\n * section 1.\n */\n\n#ifndef YY_SKIP_YYWRAP\n#ifdef __cplusplus\nextern \"C\" int katanawrap (yyscan_t yyscanner );\n#else\nextern int katanawrap (yyscan_t yyscanner );\n#endif\n#endif\n\n#ifndef yytext_ptr\nstatic void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);\n#endif\n\n#ifdef YY_NEED_STRLEN\nstatic int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);\n#endif\n\n#ifndef YY_NO_INPUT\n\n#ifdef __cplusplus\nstatic int yyinput (yyscan_t yyscanner );\n#else\nstatic int input (yyscan_t yyscanner );\n#endif\n\n#endif\n\n/* Amount of stuff to slurp up with each read. */\n#ifndef YY_READ_BUF_SIZE\n#define YY_READ_BUF_SIZE 8192\n#endif\n\n/* Copy whatever the last rule matched to the standard output. */\n#ifndef ECHO\n/* This used to be an fputs(), but since the string might contain NUL's,\n * we now use fwrite().\n */\n#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)\n#endif\n\n/* Gets input and stuffs it into \"buf\".  number of characters read, or YY_NULL,\n * is returned in \"result\".\n */\n#ifndef YY_INPUT\n#define YY_INPUT(buf,result,max_size) \\\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\\n\t\t{ \\\n\t\tint c = '*'; \\\n\t\tsize_t n; \\\n\t\tfor ( n = 0; n < max_size && \\\n\t\t\t     (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\\n\t\t\tbuf[n] = (char) c; \\\n\t\tif ( c == '\\n' ) \\\n\t\t\tbuf[n++] = (char) c; \\\n\t\tif ( c == EOF && ferror( yyin ) ) \\\n\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\\n\t\tresult = n; \\\n\t\t} \\\n\telse \\\n\t\t{ \\\n\t\terrno=0; \\\n\t\twhile ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \\\n\t\t\t{ \\\n\t\t\tif( errno != EINTR) \\\n\t\t\t\t{ \\\n\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\\n\t\t\t\tbreak; \\\n\t\t\t\t} \\\n\t\t\terrno=0; \\\n\t\t\tclearerr(yyin); \\\n\t\t\t} \\\n\t\t}\\\n\\\n\n#endif\n\n/* No semi-colon after return; correct usage is to write \"yyterminate();\" -\n * we don't want an extra ';' after the \"return\" because that will cause\n * some compilers to complain about unreachable statements.\n */\n#ifndef yyterminate\n#define yyterminate() return YY_NULL\n#endif\n\n/* Number of entries by which start-condition stack grows. */\n#ifndef YY_START_STACK_INCR\n#define YY_START_STACK_INCR 25\n#endif\n\n/* Report a fatal error. */\n#ifndef YY_FATAL_ERROR\n#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)\n#endif\n\n/* end tables serialization structures and prototypes */\n\n/* Default declaration of generated scanner - a define so the user can\n * easily add parameters.\n */\n#ifndef YY_DECL\n#define YY_DECL_IS_OURS 1\n\nextern int katanalex \\\n               (YYSTYPE * yylval_param ,yyscan_t yyscanner);\n\n#define YY_DECL int katanalex \\\n               (YYSTYPE * yylval_param , yyscan_t yyscanner)\n#endif /* !YY_DECL */\n\n/* Code executed at the beginning of each rule, after yytext and yyleng\n * have been set up.\n */\n#ifndef YY_USER_ACTION\n#define YY_USER_ACTION\n#endif\n\n/* Code executed at the end of each rule. */\n#ifndef YY_BREAK\n#define YY_BREAK break;\n#endif\n\n#define YY_RULE_SETUP \\\n\tYY_USER_ACTION\n\n/** The main scanner function which does all the work.\n */\nYY_DECL\n{\n\tregister yy_state_type yy_current_state;\n\tregister char *yy_cp, *yy_bp;\n\tregister int yy_act;\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n    yylval = yylval_param;\n\n\tif ( !yyg->yy_init )\n\t\t{\n\t\tyyg->yy_init = 1;\n\n#ifdef YY_USER_INIT\n\t\tYY_USER_INIT;\n#endif\n\n\t\tif ( ! yyg->yy_start )\n\t\t\tyyg->yy_start = 1;\t/* first start state */\n\n\t\tif ( ! yyin )\n\t\t\tyyin = stdin;\n\n\t\tif ( ! yyout )\n\t\t\tyyout = stdout;\n\n\t\tif ( ! YY_CURRENT_BUFFER ) {\n\t\t\tkatanaensure_buffer_stack (yyscanner);\n\t\t\tYY_CURRENT_BUFFER_LVALUE =\n\t\t\t\tkatana_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);\n\t\t}\n\n\t\tkatana_load_buffer_state(yyscanner );\n\t\t}\n\n\twhile ( 1 )\t\t/* loops until end-of-file is reached */\n\t\t{\n\t\tyy_cp = yyg->yy_c_buf_p;\n\n\t\t/* Support of yytext. */\n\t\t*yy_cp = yyg->yy_hold_char;\n\n\t\t/* yy_bp points to the position in yy_ch_buf of the start of\n\t\t * the current run.\n\t\t */\n\t\tyy_bp = yy_cp;\n\n\t\tyy_current_state = yyg->yy_start;\nyy_match:\n\t\tdo\n\t\t\t{\n\t\t\tregister YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];\n\t\t\tif ( yy_accept[yy_current_state] )\n\t\t\t\t{\n\t\t\t\tyyg->yy_last_accepting_state = yy_current_state;\n\t\t\t\tyyg->yy_last_accepting_cpos = yy_cp;\n\t\t\t\t}\n\t\t\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t\t\t{\n\t\t\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\t\t\tif ( yy_current_state >= 551 )\n\t\t\t\t\tyy_c = yy_meta[(unsigned int) yy_c];\n\t\t\t\t}\n\t\t\tyy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\n\t\t\t++yy_cp;\n\t\t\t}\n\t\twhile ( yy_base[yy_current_state] != 5465 );\n\nyy_find_action:\n\t\tyy_act = yy_accept[yy_current_state];\n\t\tif ( yy_act == 0 )\n\t\t\t{ /* have to back up */\n\t\t\tyy_cp = yyg->yy_last_accepting_cpos;\n\t\t\tyy_current_state = yyg->yy_last_accepting_state;\n\t\t\tyy_act = yy_accept[yy_current_state];\n\t\t\t}\n\n\t\tYY_DO_BEFORE_ACTION;\n\n\t\tif ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )\n\t\t\t{\n\t\t\tint yyl;\n\t\t\tfor ( yyl = 0; yyl < yyleng; ++yyl )\n\t\t\t\tif ( yytext[yyl] == '\\n' )\n\t\t\t\t\t   \n    do{ yylineno++;\n        yycolumn=0;\n    }while(0)\n;\n\t\t\t}\n\ndo_action:\t/* This label is used only to access EOF actions. */\n\n\t\tswitch ( yy_act )\n\t{ /* beginning of action switch */\n\t\t\tcase 0: /* must back up */\n\t\t\t/* undo the effects of YY_DO_BEFORE_ACTION */\n\t\t\t*yy_cp = yyg->yy_hold_char;\n\t\t\tyy_cp = yyg->yy_last_accepting_cpos;\n\t\t\tyy_current_state = yyg->yy_last_accepting_state;\n\t\t\tgoto yy_find_action;\n\ncase 1:\n/* rule 1 can match eol */\nYY_RULE_SETUP\n{ /* ignore comments */ }\n\tYY_BREAK\ncase 2:\n/* rule 2 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_WHITESPACE)}\n\tYY_BREAK\ncase 3:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_SGML_CD)}\n\tYY_BREAK\ncase 4:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_SGML_CD)}\n\tYY_BREAK\ncase 5:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_INCLUDES)}\n\tYY_BREAK\ncase 6:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_DASHMATCH)}\n\tYY_BREAK\ncase 7:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_BEGINSWITH)}\n\tYY_BREAK\ncase 8:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_ENDSWITH)}\n\tYY_BREAK\ncase 9:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_CONTAINS)}\n\tYY_BREAK\ncase 10:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_MEDIA_NOT)}\n\tYY_BREAK\ncase 11:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_MEDIA_ONLY)}\n\tYY_BREAK\ncase 12:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_MEDIA_AND)}\n\tYY_BREAK\ncase 13:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_MEDIA_OR)}\n\tYY_BREAK\ncase 14:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_SUPPORTS_NOT)}\n\tYY_BREAK\ncase 15:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_SUPPORTS_AND)}\n\tYY_BREAK\ncase 16:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_SUPPORTS_OR)}\n\tYY_BREAK\ncase 17:\n/* rule 17 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_STRING)}\n\tYY_BREAK\ncase 18:\n/* rule 18 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_IDENT)}\n\tYY_BREAK\ncase 19:\n/* rule 19 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_NTH)}\n\tYY_BREAK\ncase 20:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_HEX)}\n\tYY_BREAK\ncase 21:\n/* rule 21 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_IDSEL)}\n\tYY_BREAK\ncase 22:\nYY_RULE_SETUP\n{BEGIN(mediaquery); KATANA_TOKEN(KATANA_CSS_IMPORT_SYM)}\n\tYY_BREAK\ncase 23:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_PAGE_SYM)}\n\tYY_BREAK\ncase 24:\nYY_RULE_SETUP\n{BEGIN(mediaquery); KATANA_TOKEN(KATANA_CSS_MEDIA_SYM)}\n\tYY_BREAK\ncase 25:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_FONT_FACE_SYM)}\n\tYY_BREAK\ncase 26:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_CHARSET_SYM)}\n\tYY_BREAK\ncase 27:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_NAMESPACE_SYM)}\n\tYY_BREAK\ncase 28:\ncase 29:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_KEYFRAMES_SYM)}\n\tYY_BREAK\ncase 30:\nYY_RULE_SETUP\n{BEGIN(supports); KATANA_TOKEN(KATANA_CSS_SUPPORTS_SYM)}\\\n\tYY_BREAK\ncase 31:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_INTERNAL_RULE_SYM)}\n\tYY_BREAK\ncase 32:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_INTERNAL_DECLS_SYM)}\n\tYY_BREAK\ncase 33:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_INTERNAL_VALUE_SYM)}\n\tYY_BREAK\ncase 34:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_INTERNAL_SELECTOR_SYM)}\n\tYY_BREAK\ncase 35:\nYY_RULE_SETUP\n{BEGIN(mediaquery); KATANA_TOKEN(KATANA_INTERNAL_MEDIALIST_SYM)}\n\tYY_BREAK\ncase 36:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_INTERNAL_KEYFRAME_RULE_SYM)}\n\tYY_BREAK\ncase 37:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM)}\n\tYY_BREAK\ncase 38:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_INTERNAL_SUPPORTS_CONDITION_SYM)}\n\tYY_BREAK\ncase 39:\n/* rule 39 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_ATKEYWORD)}\n\tYY_BREAK\ncase 40:\n/* rule 40 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_IMPORTANT_SYM)}\n\tYY_BREAK\ncase 41:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_REMS)}\n\tYY_BREAK\ncase 42:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_CHS)}\n\tYY_BREAK\ncase 43:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_QEMS)}\n\tYY_BREAK\ncase 44:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_EMS)}\n\tYY_BREAK\ncase 45:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_EXS)}\n\tYY_BREAK\ncase 46:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_PXS)}\n\tYY_BREAK\ncase 47:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_CMS)}\n\tYY_BREAK\ncase 48:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_MMS)}\n\tYY_BREAK\ncase 49:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_INS)}\n\tYY_BREAK\ncase 50:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_PTS)}\n\tYY_BREAK\ncase 51:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_PCS)}\n\tYY_BREAK\ncase 52:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_DEGS)}\n\tYY_BREAK\ncase 53:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_RADS)}\n\tYY_BREAK\ncase 54:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_GRADS)}\n\tYY_BREAK\ncase 55:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_TURNS)}\n\tYY_BREAK\ncase 56:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_MSECS)}\n\tYY_BREAK\ncase 57:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_SECS)}\n\tYY_BREAK\ncase 58:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_HERTZ)}\n\tYY_BREAK\ncase 59:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_KHERTZ)}\n\tYY_BREAK\ncase 60:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_VW)}\n\tYY_BREAK\ncase 61:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_VH)}\n\tYY_BREAK\ncase 62:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_VMIN)}\n\tYY_BREAK\ncase 63:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_VMAX)}\n\tYY_BREAK\ncase 64:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_DPPX)}\n\tYY_BREAK\ncase 65:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_DPI)}\n\tYY_BREAK\ncase 66:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_DPCM)}\n\tYY_BREAK\ncase 67:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_FR)}\n\tYY_BREAK\ncase 68:\n/* rule 68 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_DIMEN)}\n\tYY_BREAK\ncase 69:\n/* rule 69 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_INVALIDDIMEN)}\n\tYY_BREAK\ncase 70:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_PERCENTAGE)}\n\tYY_BREAK\ncase 71:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_INTEGER)}\n\tYY_BREAK\ncase 72:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_FLOATTOKEN)}\n\tYY_BREAK\ncase 73:\n/* rule 73 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_URI)}\n\tYY_BREAK\ncase 74:\n/* rule 74 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_URI)}\n\tYY_BREAK\ncase 75:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_ANYFUNCTION)}\n\tYY_BREAK\ncase 76:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_CUEFUNCTION)}\n\tYY_BREAK\ncase 77:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_NOTFUNCTION)}\n\tYY_BREAK\ncase 78:\ncase 79:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_CALCFUNCTION)}\n\tYY_BREAK\ncase 80:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_MINFUNCTION)}\n\tYY_BREAK\ncase 81:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_MAXFUNCTION)}\n\tYY_BREAK\ncase 82:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_HOSTFUNCTION)}\n\tYY_BREAK\ncase 83:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_HOSTCONTEXTFUNCTION)}\n\tYY_BREAK\ncase 84:\n/* rule 84 can match eol */\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_FUNCTION)}\n\tYY_BREAK\ncase 85:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_UNICODERANGE)}\n\tYY_BREAK\ncase 86:\nYY_RULE_SETUP\n{KATANA_TOKEN(KATANA_CSS_UNICODERANGE)}\n\tYY_BREAK\ncase 87:\ncase 88:\nYY_RULE_SETUP\n{BEGIN(INITIAL); KATANA_TOKEN(*yytext)}\n\tYY_BREAK\ncase 89:\nYY_RULE_SETUP\n{KATANA_TOKEN(*yytext)}\n\tYY_BREAK\ncase 90:\nYY_RULE_SETUP\nYY_FATAL_ERROR( \"flex scanner jammed\" );\n\tYY_BREAK\ncase YY_STATE_EOF(INITIAL):\ncase YY_STATE_EOF(mediaquery):\ncase YY_STATE_EOF(supports):\n\tyyterminate();\n\n\tcase YY_END_OF_BUFFER:\n\t\t{\n\t\t/* Amount of text matched not including the EOB char. */\n\t\tint yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;\n\n\t\t/* Undo the effects of YY_DO_BEFORE_ACTION. */\n\t\t*yy_cp = yyg->yy_hold_char;\n\t\tYY_RESTORE_YY_MORE_OFFSET\n\n\t\tif ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )\n\t\t\t{\n\t\t\t/* We're scanning a new file or input source.  It's\n\t\t\t * possible that this happened because the user\n\t\t\t * just pointed yyin at a new source and called\n\t\t\t * katanalex().  If so, then we have to assure\n\t\t\t * consistency between YY_CURRENT_BUFFER and our\n\t\t\t * globals.  Here is the right place to do so, because\n\t\t\t * this is the first action (other than possibly a\n\t\t\t * back-up) that will match for the new input source.\n\t\t\t */\n\t\t\tyyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;\n\t\t\t}\n\n\t\t/* Note that here we test for yy_c_buf_p \"<=\" to the position\n\t\t * of the first EOB in the buffer, since yy_c_buf_p will\n\t\t * already have been incremented past the NUL character\n\t\t * (since all states make transitions on EOB to the\n\t\t * end-of-buffer state).  Contrast this with the test\n\t\t * in input().\n\t\t */\n\t\tif ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )\n\t\t\t{ /* This was really a NUL. */\n\t\t\tyy_state_type yy_next_state;\n\n\t\t\tyyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;\n\n\t\t\tyy_current_state = yy_get_previous_state( yyscanner );\n\n\t\t\t/* Okay, we're now positioned to make the NUL\n\t\t\t * transition.  We couldn't have\n\t\t\t * yy_get_previous_state() go ahead and do it\n\t\t\t * for us because it doesn't know how to deal\n\t\t\t * with the possibility of jamming (and we don't\n\t\t\t * want to build jamming into it because then it\n\t\t\t * will run more slowly).\n\t\t\t */\n\n\t\t\tyy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);\n\n\t\t\tyy_bp = yyg->yytext_ptr + YY_MORE_ADJ;\n\n\t\t\tif ( yy_next_state )\n\t\t\t\t{\n\t\t\t\t/* Consume the NUL. */\n\t\t\t\tyy_cp = ++yyg->yy_c_buf_p;\n\t\t\t\tyy_current_state = yy_next_state;\n\t\t\t\tgoto yy_match;\n\t\t\t\t}\n\n\t\t\telse\n\t\t\t\t{\n\t\t\t\tyy_cp = yyg->yy_c_buf_p;\n\t\t\t\tgoto yy_find_action;\n\t\t\t\t}\n\t\t\t}\n\n\t\telse switch ( yy_get_next_buffer( yyscanner ) )\n\t\t\t{\n\t\t\tcase EOB_ACT_END_OF_FILE:\n\t\t\t\t{\n\t\t\t\tyyg->yy_did_buffer_switch_on_eof = 0;\n\n\t\t\t\tif ( katanawrap(yyscanner ) )\n\t\t\t\t\t{\n\t\t\t\t\t/* Note: because we've taken care in\n\t\t\t\t\t * yy_get_next_buffer() to have set up\n\t\t\t\t\t * yytext, we can now set up\n\t\t\t\t\t * yy_c_buf_p so that if some total\n\t\t\t\t\t * hoser (like flex itself) wants to\n\t\t\t\t\t * call the scanner after we return the\n\t\t\t\t\t * YY_NULL, it'll still work - another\n\t\t\t\t\t * YY_NULL will get returned.\n\t\t\t\t\t */\n\t\t\t\t\tyyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;\n\n\t\t\t\t\tyy_act = YY_STATE_EOF(YY_START);\n\t\t\t\t\tgoto do_action;\n\t\t\t\t\t}\n\n\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\tif ( ! yyg->yy_did_buffer_switch_on_eof )\n\t\t\t\t\t\tYY_NEW_FILE;\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\tcase EOB_ACT_CONTINUE_SCAN:\n\t\t\t\tyyg->yy_c_buf_p =\n\t\t\t\t\tyyg->yytext_ptr + yy_amount_of_matched_text;\n\n\t\t\t\tyy_current_state = yy_get_previous_state( yyscanner );\n\n\t\t\t\tyy_cp = yyg->yy_c_buf_p;\n\t\t\t\tyy_bp = yyg->yytext_ptr + YY_MORE_ADJ;\n\t\t\t\tgoto yy_match;\n\n\t\t\tcase EOB_ACT_LAST_MATCH:\n\t\t\t\tyyg->yy_c_buf_p =\n\t\t\t\t&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];\n\n\t\t\t\tyy_current_state = yy_get_previous_state( yyscanner );\n\n\t\t\t\tyy_cp = yyg->yy_c_buf_p;\n\t\t\t\tyy_bp = yyg->yytext_ptr + YY_MORE_ADJ;\n\t\t\t\tgoto yy_find_action;\n\t\t\t}\n\t\tbreak;\n\t\t}\n\n\tdefault:\n\t\tYY_FATAL_ERROR(\n\t\t\t\"fatal flex scanner internal error--no action found\" );\n\t} /* end of action switch */\n\t\t} /* end of scanning one token */\n} /* end of katanalex */\n\n/* yy_get_next_buffer - try to read in a new buffer\n *\n * Returns a code representing an action:\n *\tEOB_ACT_LAST_MATCH -\n *\tEOB_ACT_CONTINUE_SCAN - continue scanning from current position\n *\tEOB_ACT_END_OF_FILE - end of file\n */\nstatic int yy_get_next_buffer (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\tregister char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;\n\tregister char *source = yyg->yytext_ptr;\n\tregister int number_to_move, i;\n\tint ret_val;\n\n\tif ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )\n\t\tYY_FATAL_ERROR(\n\t\t\"fatal flex scanner internal error--end of buffer missed\" );\n\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )\n\t\t{ /* Don't try to fill the buffer, so this is an EOF. */\n\t\tif ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )\n\t\t\t{\n\t\t\t/* We matched a single character, the EOB, so\n\t\t\t * treat this as a final EOF.\n\t\t\t */\n\t\t\treturn EOB_ACT_END_OF_FILE;\n\t\t\t}\n\n\t\telse\n\t\t\t{\n\t\t\t/* We matched some text prior to the EOB, first\n\t\t\t * process it.\n\t\t\t */\n\t\t\treturn EOB_ACT_LAST_MATCH;\n\t\t\t}\n\t\t}\n\n\t/* Try to read more data. */\n\n\t/* First move last chars to start of buffer. */\n\tnumber_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;\n\n\tfor ( i = 0; i < number_to_move; ++i )\n\t\t*(dest++) = *(source++);\n\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )\n\t\t/* don't do the read, it's not guaranteed to return an EOF,\n\t\t * just force an EOF\n\t\t */\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;\n\n\telse\n\t\t{\n\t\t\tyy_size_t num_to_read =\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;\n\n\t\twhile ( num_to_read <= 0 )\n\t\t\t{ /* Not enough room in the buffer - grow it. */\n\n\t\t\t/* just a shorter name for the current buffer */\n\t\t\tYY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;\n\n\t\t\tint yy_c_buf_p_offset =\n\t\t\t\t(int) (yyg->yy_c_buf_p - b->yy_ch_buf);\n\n\t\t\tif ( b->yy_is_our_buffer )\n\t\t\t\t{\n\t\t\t\tyy_size_t new_size = b->yy_buf_size * 2;\n\n\t\t\t\tif ( new_size <= 0 )\n\t\t\t\t\tb->yy_buf_size += b->yy_buf_size / 8;\n\t\t\t\telse\n\t\t\t\t\tb->yy_buf_size *= 2;\n\n\t\t\t\tb->yy_ch_buf = (char *)\n\t\t\t\t\t/* Include room in for 2 EOB chars. */\n\t\t\t\t\tkatanarealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );\n\t\t\t\t}\n\t\t\telse\n\t\t\t\t/* Can't grow it, we don't own it. */\n\t\t\t\tb->yy_ch_buf = 0;\n\n\t\t\tif ( ! b->yy_ch_buf )\n\t\t\t\tYY_FATAL_ERROR(\n\t\t\t\t\"fatal error - scanner input buffer overflow\" );\n\n\t\t\tyyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];\n\n\t\t\tnum_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -\n\t\t\t\t\t\tnumber_to_move - 1;\n\n\t\t\t}\n\n\t\tif ( num_to_read > YY_READ_BUF_SIZE )\n\t\t\tnum_to_read = YY_READ_BUF_SIZE;\n\n\t\t/* Read in more data. */\n\t\tYY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),\n\t\t\tyyg->yy_n_chars, num_to_read );\n\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;\n\t\t}\n\n\tif ( yyg->yy_n_chars == 0 )\n\t\t{\n\t\tif ( number_to_move == YY_MORE_ADJ )\n\t\t\t{\n\t\t\tret_val = EOB_ACT_END_OF_FILE;\n\t\t\tkatanarestart(yyin  ,yyscanner);\n\t\t\t}\n\n\t\telse\n\t\t\t{\n\t\t\tret_val = EOB_ACT_LAST_MATCH;\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buffer_status =\n\t\t\t\tYY_BUFFER_EOF_PENDING;\n\t\t\t}\n\t\t}\n\n\telse\n\t\tret_val = EOB_ACT_CONTINUE_SCAN;\n\n\tif ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {\n\t\t/* Extend the array by 50%, plus the number we really need. */\n\t\tyy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) katanarealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );\n\t\tif ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in yy_get_next_buffer()\" );\n\t}\n\n\tyyg->yy_n_chars += number_to_move;\n\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;\n\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;\n\n\tyyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];\n\n\treturn ret_val;\n}\n\n/* yy_get_previous_state - get the state just before the EOB char was reached */\n\n    static yy_state_type yy_get_previous_state (yyscan_t yyscanner)\n{\n\tregister yy_state_type yy_current_state;\n\tregister char *yy_cp;\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n\tyy_current_state = yyg->yy_start;\n\n\tfor ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )\n\t\t{\n\t\tregister YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);\n\t\tif ( yy_accept[yy_current_state] )\n\t\t\t{\n\t\t\tyyg->yy_last_accepting_state = yy_current_state;\n\t\t\tyyg->yy_last_accepting_cpos = yy_cp;\n\t\t\t}\n\t\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t\t{\n\t\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\t\tif ( yy_current_state >= 551 )\n\t\t\t\tyy_c = yy_meta[(unsigned int) yy_c];\n\t\t\t}\n\t\tyy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\n\t\t}\n\n\treturn yy_current_state;\n}\n\n/* yy_try_NUL_trans - try to make a transition on the NUL character\n *\n * synopsis\n *\tnext_state = yy_try_NUL_trans( current_state );\n */\n    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)\n{\n\tregister int yy_is_jam;\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */\n\tregister char *yy_cp = yyg->yy_c_buf_p;\n\n\tregister YY_CHAR yy_c = 1;\n\tif ( yy_accept[yy_current_state] )\n\t\t{\n\t\tyyg->yy_last_accepting_state = yy_current_state;\n\t\tyyg->yy_last_accepting_cpos = yy_cp;\n\t\t}\n\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t{\n\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\tif ( yy_current_state >= 551 )\n\t\t\tyy_c = yy_meta[(unsigned int) yy_c];\n\t\t}\n\tyy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];\n\tyy_is_jam = (yy_current_state == 550);\n\n\t(void)yyg;\n\treturn yy_is_jam ? 0 : yy_current_state;\n}\n\n#ifndef YY_NO_INPUT\n#ifdef __cplusplus\n    static int yyinput (yyscan_t yyscanner)\n#else\n    static int input  (yyscan_t yyscanner)\n#endif\n\n{\n\tint c;\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n\t*yyg->yy_c_buf_p = yyg->yy_hold_char;\n\n\tif ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )\n\t\t{\n\t\t/* yy_c_buf_p now points to the character we want to return.\n\t\t * If this occurs *before* the EOB characters, then it's a\n\t\t * valid NUL; if not, then we've hit the end of the buffer.\n\t\t */\n\t\tif ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )\n\t\t\t/* This was really a NUL. */\n\t\t\t*yyg->yy_c_buf_p = '\\0';\n\n\t\telse\n\t\t\t{ /* need more input */\n\t\t\tyy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;\n\t\t\t++yyg->yy_c_buf_p;\n\n\t\t\tswitch ( yy_get_next_buffer( yyscanner ) )\n\t\t\t\t{\n\t\t\t\tcase EOB_ACT_LAST_MATCH:\n\t\t\t\t\t/* This happens because yy_g_n_b()\n\t\t\t\t\t * sees that we've accumulated a\n\t\t\t\t\t * token and flags that we need to\n\t\t\t\t\t * try matching the token before\n\t\t\t\t\t * proceeding.  But for input(),\n\t\t\t\t\t * there's no matching to consider.\n\t\t\t\t\t * So convert the EOB_ACT_LAST_MATCH\n\t\t\t\t\t * to EOB_ACT_END_OF_FILE.\n\t\t\t\t\t */\n\n\t\t\t\t\t/* Reset buffer status. */\n\t\t\t\t\tkatanarestart(yyin ,yyscanner);\n\n\t\t\t\t\t/*FALLTHROUGH*/\n\n\t\t\t\tcase EOB_ACT_END_OF_FILE:\n\t\t\t\t\t{\n\t\t\t\t\tif ( katanawrap(yyscanner ) )\n\t\t\t\t\t\treturn EOF;\n\n\t\t\t\t\tif ( ! yyg->yy_did_buffer_switch_on_eof )\n\t\t\t\t\t\tYY_NEW_FILE;\n#ifdef __cplusplus\n\t\t\t\t\treturn yyinput(yyscanner);\n#else\n\t\t\t\t\treturn input(yyscanner);\n#endif\n\t\t\t\t\t}\n\n\t\t\t\tcase EOB_ACT_CONTINUE_SCAN:\n\t\t\t\t\tyyg->yy_c_buf_p = yyg->yytext_ptr + offset;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tc = *(unsigned char *) yyg->yy_c_buf_p;\t/* cast for 8-bit char's */\n\t*yyg->yy_c_buf_p = '\\0';\t/* preserve yytext */\n\tyyg->yy_hold_char = *++yyg->yy_c_buf_p;\n\n\tif ( c == '\\n' )\n\t\t   \n    do{ yylineno++;\n        yycolumn=0;\n    }while(0)\n;\n\n\treturn c;\n}\n#endif\t/* ifndef YY_NO_INPUT */\n\n/** Immediately switch to a different input stream.\n * @param input_file A readable stream.\n * @param yyscanner The scanner object.\n * @note This function does not reset the start condition to @c INITIAL .\n */\n    void katanarestart  (FILE * input_file , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n\tif ( ! YY_CURRENT_BUFFER ){\n        katanaensure_buffer_stack (yyscanner);\n\t\tYY_CURRENT_BUFFER_LVALUE =\n            katana_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);\n\t}\n\n\tkatana_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);\n\tkatana_load_buffer_state(yyscanner );\n}\n\n/** Switch to a different input buffer.\n * @param new_buffer The new input buffer.\n * @param yyscanner The scanner object.\n */\n    void katana_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n\t/* TODO. We should be able to replace this entire function body\n\t * with\n\t *\t\tkatanapop_buffer_state();\n\t *\t\tkatanapush_buffer_state(new_buffer);\n     */\n\tkatanaensure_buffer_stack (yyscanner);\n\tif ( YY_CURRENT_BUFFER == new_buffer )\n\t\treturn;\n\n\tif ( YY_CURRENT_BUFFER )\n\t\t{\n\t\t/* Flush out information for old buffer. */\n\t\t*yyg->yy_c_buf_p = yyg->yy_hold_char;\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;\n\t\t}\n\n\tYY_CURRENT_BUFFER_LVALUE = new_buffer;\n\tkatana_load_buffer_state(yyscanner );\n\n\t/* We don't actually know whether we did this switch during\n\t * EOF (katanawrap()) processing, but the only time this flag\n\t * is looked at is after katanawrap() is called, so it's safe\n\t * to go ahead and always set it.\n\t */\n\tyyg->yy_did_buffer_switch_on_eof = 1;\n}\n\nstatic void katana_load_buffer_state  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\tyyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;\n\tyyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;\n\tyyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;\n\tyyg->yy_hold_char = *yyg->yy_c_buf_p;\n}\n\n/** Allocate and initialize an input buffer state.\n * @param file A readable stream.\n * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.\n * @param yyscanner The scanner object.\n * @return the allocated buffer state.\n */\n    YY_BUFFER_STATE katana_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)\n{\n\tYY_BUFFER_STATE b;\n    \n\tb = (YY_BUFFER_STATE) katanaalloc(sizeof( struct yy_buffer_state ) ,yyscanner );\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in katana_create_buffer()\" );\n    memset(b, 0, sizeof(struct yy_buffer_state));\n\n\tb->yy_buf_size = size;\n\n\t/* yy_ch_buf has to be 2 characters longer than the size given because\n\t * we need to put in 2 end-of-buffer characters.\n\t */\n\tb->yy_ch_buf = (char *) katanaalloc(b->yy_buf_size + 2 ,yyscanner );\n\tif ( ! b->yy_ch_buf )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in katana_create_buffer()\" );\n\n\tb->yy_is_our_buffer = 1;\n\n\tkatana_init_buffer(b,file ,yyscanner);\n\n\treturn b;\n}\n\n/** Destroy the buffer.\n * @param b a buffer created with katana_create_buffer()\n * @param yyscanner The scanner object.\n */\n    void katana_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n\tif ( ! b )\n\t\treturn;\n\n\tif ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */\n\t\tYY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;\n\n\tif ( b->yy_is_our_buffer )\n\t\tkatanafree((void *) b->yy_ch_buf ,yyscanner );\n\n\tkatanafree((void *) b ,yyscanner );\n}\n\n/* Initializes or reinitializes a buffer.\n * This function is sometimes called more than once on the same buffer,\n * such as during a katanarestart() or at EOF.\n */\n    static void katana_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)\n\n{\n\tint oerrno = errno;\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n\tkatana_flush_buffer(b ,yyscanner);\n\n\tb->yy_input_file = file;\n\tb->yy_fill_buffer = 1;\n\n    /* If b is the current buffer, then katana_init_buffer was _probably_\n     * called from katanarestart() or through yy_get_next_buffer.\n     * In that case, we don't want to reset the lineno or column.\n     */\n    if (b != YY_CURRENT_BUFFER){\n        b->yy_bs_lineno = 1;\n        b->yy_bs_column = 0;\n    }\n\n        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;\n    \n\terrno = oerrno;\n}\n\n/** Discard all buffered characters. On the next scan, YY_INPUT will be called.\n * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.\n * @param yyscanner The scanner object.\n */\n    void katana_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\tif ( ! b )\n\t\treturn;\n\n\tb->yy_n_chars = 0;\n\n\t/* We always need two end-of-buffer characters.  The first causes\n\t * a transition to the end-of-buffer state.  The second causes\n\t * a jam in that state.\n\t */\n\tb->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;\n\tb->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;\n\n\tb->yy_buf_pos = &b->yy_ch_buf[0];\n\n\tb->yy_at_bol = 1;\n\tb->yy_buffer_status = YY_BUFFER_NEW;\n\n\tif ( b == YY_CURRENT_BUFFER )\n\t\tkatana_load_buffer_state(yyscanner );\n}\n\n/** Pushes the new state onto the stack. The new state becomes\n *  the current state. This function will allocate the stack\n *  if necessary.\n *  @param new_buffer The new state.\n *  @param yyscanner The scanner object.\n */\nvoid katanapush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\tif (new_buffer == NULL)\n\t\treturn;\n\n\tkatanaensure_buffer_stack(yyscanner);\n\n\t/* This block is copied from katana_switch_to_buffer. */\n\tif ( YY_CURRENT_BUFFER )\n\t\t{\n\t\t/* Flush out information for old buffer. */\n\t\t*yyg->yy_c_buf_p = yyg->yy_hold_char;\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;\n\t\t}\n\n\t/* Only push if top exists. Otherwise, replace top. */\n\tif (YY_CURRENT_BUFFER)\n\t\tyyg->yy_buffer_stack_top++;\n\tYY_CURRENT_BUFFER_LVALUE = new_buffer;\n\n\t/* copied from katana_switch_to_buffer. */\n\tkatana_load_buffer_state(yyscanner );\n\tyyg->yy_did_buffer_switch_on_eof = 1;\n}\n\n/** Removes and deletes the top of the stack, if present.\n *  The next element becomes the new top.\n *  @param yyscanner The scanner object.\n */\nvoid katanapop_buffer_state (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\tif (!YY_CURRENT_BUFFER)\n\t\treturn;\n\n\tkatana_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);\n\tYY_CURRENT_BUFFER_LVALUE = NULL;\n\tif (yyg->yy_buffer_stack_top > 0)\n\t\t--yyg->yy_buffer_stack_top;\n\n\tif (YY_CURRENT_BUFFER) {\n\t\tkatana_load_buffer_state(yyscanner );\n\t\tyyg->yy_did_buffer_switch_on_eof = 1;\n\t}\n}\n\n/* Allocates the stack if it does not exist.\n *  Guarantees space for at least one push.\n */\nstatic void katanaensure_buffer_stack (yyscan_t yyscanner)\n{\n\tyy_size_t num_to_alloc;\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n\tif (!yyg->yy_buffer_stack) {\n\t\t/* First allocation is just for 2 elements, since we don't know if this\n\t\t * scanner will even need a stack. We use 2 instead of 1 to avoid an\n\t\t * immediate realloc on the next call.\n         */\n\t\tnum_to_alloc = 1;\n\t\tyyg->yy_buffer_stack = (struct yy_buffer_state**)katanaalloc\n\t\t\t\t\t\t\t\t(num_to_alloc * sizeof(struct yy_buffer_state*)\n\t\t\t\t\t\t\t\t, yyscanner);\n\t\tif ( ! yyg->yy_buffer_stack )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in katanaensure_buffer_stack()\" );\n\t\t\t\t\t\t\t\t  \n        memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));\n\n\t\tyyg->yy_buffer_stack_max = num_to_alloc;\n\t\tyyg->yy_buffer_stack_top = 0;\n\t\treturn;\n\t}\n\n\tif (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){\n\t\t/* Increase the buffer to prepare for a possible push. */\n\t\tint grow_size = 8 /* arbitrary grow size */;\n\n\t\tnum_to_alloc = yyg->yy_buffer_stack_max + grow_size;\n\t\tyyg->yy_buffer_stack = (struct yy_buffer_state**)katanarealloc\n\t\t\t\t\t\t\t\t(yyg->yy_buffer_stack,\n\t\t\t\t\t\t\t\tnum_to_alloc * sizeof(struct yy_buffer_state*)\n\t\t\t\t\t\t\t\t, yyscanner);\n\t\tif ( ! yyg->yy_buffer_stack )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in katanaensure_buffer_stack()\" );\n\n\t\t/* zero only the new slots.*/\n\t\tmemset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));\n\t\tyyg->yy_buffer_stack_max = num_to_alloc;\n\t}\n}\n\n/** Setup the input buffer state to scan directly from a user-specified character buffer.\n * @param base the character buffer\n * @param size the size in bytes of the character buffer\n * @param yyscanner The scanner object.\n * @return the newly allocated buffer state object. \n */\nYY_BUFFER_STATE katana_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)\n{\n\tYY_BUFFER_STATE b;\n    \n\tif ( size < 2 ||\n\t     base[size-2] != YY_END_OF_BUFFER_CHAR ||\n\t     base[size-1] != YY_END_OF_BUFFER_CHAR )\n\t\t/* They forgot to leave room for the EOB's. */\n\t\treturn 0;\n\n\tb = (YY_BUFFER_STATE) katanaalloc(sizeof( struct yy_buffer_state ) ,yyscanner );\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in katana_scan_buffer()\" );\n    memset(b, 0, sizeof(struct yy_buffer_state));\n\n\tb->yy_buf_size = size - 2;\t/* \"- 2\" to take care of EOB's */\n\tb->yy_buf_pos = b->yy_ch_buf = base;\n\tb->yy_is_our_buffer = 0;\n\tb->yy_input_file = 0;\n\tb->yy_n_chars = b->yy_buf_size;\n\tb->yy_is_interactive = 0;\n\tb->yy_at_bol = 1;\n\tb->yy_fill_buffer = 0;\n\tb->yy_buffer_status = YY_BUFFER_NEW;\n\n\tkatana_switch_to_buffer(b ,yyscanner );\n\n\treturn b;\n}\n\n/** Setup the input buffer state to scan a string. The next call to katanalex() will\n * scan from a @e copy of @a str.\n * @param yystr a NUL-terminated string to scan\n * @param yyscanner The scanner object.\n * @return the newly allocated buffer state object.\n * @note If you want to scan bytes that may contain NUL values, then use\n *       katana_scan_bytes() instead.\n */\nYY_BUFFER_STATE katana_scan_string (yyconst char * yystr , yyscan_t yyscanner)\n{\n    \n\treturn katana_scan_bytes(yystr,strlen(yystr) ,yyscanner);\n}\n\n/** Setup the input buffer state to scan the given bytes. The next call to katanalex() will\n * scan from a @e copy of @a bytes.\n * @param yybytes the byte buffer to scan\n * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.\n * @param yyscanner The scanner object.\n * @return the newly allocated buffer state object.\n */\nYY_BUFFER_STATE katana_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len , yyscan_t yyscanner)\n{\n\tYY_BUFFER_STATE b;\n\tchar *buf;\n\tyy_size_t n;\n\tint i;\n    \n\t/* Get memory for full buffer, including space for trailing EOB's. */\n\tn = _yybytes_len + 2;\n\tbuf = (char *) katanaalloc(n ,yyscanner );\n\tif ( ! buf )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in katana_scan_bytes()\" );\n\n\tfor ( i = 0; i < _yybytes_len; ++i )\n\t\tbuf[i] = yybytes[i];\n\n\tbuf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;\n\n\tb = katana_scan_buffer(buf,n ,yyscanner);\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"bad buffer in katana_scan_bytes()\" );\n\n\t/* It's okay to grow etc. this buffer, and we should throw it\n\t * away when we're done.\n\t */\n\tb->yy_is_our_buffer = 1;\n\n\treturn b;\n}\n\n#ifndef YY_EXIT_FAILURE\n#define YY_EXIT_FAILURE 2\n#endif\n\nstatic void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)\n{\n    \t(void) fprintf( stderr, \"%s\\n\", msg );\n\texit( YY_EXIT_FAILURE );\n}\n\n/* Redefine yyless() so it works in section 3 code. */\n\n#undef yyless\n#define yyless(n) \\\n\tdo \\\n\t\t{ \\\n\t\t/* Undo effects of setting up yytext. */ \\\n        int yyless_macro_arg = (n); \\\n        YY_LESS_LINENO(yyless_macro_arg);\\\n\t\tyytext[yyleng] = yyg->yy_hold_char; \\\n\t\tyyg->yy_c_buf_p = yytext + yyless_macro_arg; \\\n\t\tyyg->yy_hold_char = *yyg->yy_c_buf_p; \\\n\t\t*yyg->yy_c_buf_p = '\\0'; \\\n\t\tyyleng = yyless_macro_arg; \\\n\t\t} \\\n\twhile ( 0 )\n\n/* Accessor  methods (get/set functions) to struct members. */\n\n/** Get the user-defined data for this scanner.\n * @param yyscanner The scanner object.\n */\nYY_EXTRA_TYPE katanaget_extra  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    return yyextra;\n}\n\n/** Get the current line number.\n * @param yyscanner The scanner object.\n */\nint katanaget_lineno  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    \n    if (! YY_CURRENT_BUFFER)\n        return 0;\n\n    return yylineno;\n}\n\n/** Get the current column number.\n * @param yyscanner The scanner object.\n */\nint katanaget_column  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    \n        if (! YY_CURRENT_BUFFER)\n            return 0;\n    \n    return yycolumn;\n}\n\n/** Get the input stream.\n * @param yyscanner The scanner object.\n */\nFILE *katanaget_in  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    return yyin;\n}\n\n/** Get the output stream.\n * @param yyscanner The scanner object.\n */\nFILE *katanaget_out  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    return yyout;\n}\n\n/** Get the length of the current token.\n * @param yyscanner The scanner object.\n */\nyy_size_t katanaget_leng  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    return yyleng;\n}\n\n/** Get the current token.\n * @param yyscanner The scanner object.\n */\n\nchar *katanaget_text  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    return yytext;\n}\n\n/** Set the user-defined data. This data is never touched by the scanner.\n * @param user_defined The data to be associated with this scanner.\n * @param yyscanner The scanner object.\n */\nvoid katanaset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    yyextra = user_defined ;\n}\n\n/** Set the current line number.\n * @param line_number\n * @param yyscanner The scanner object.\n */\nvoid katanaset_lineno (int  line_number , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n        /* lineno is only valid if an input buffer exists. */\n        if (! YY_CURRENT_BUFFER )\n           YY_FATAL_ERROR( \"katanaset_lineno called with no buffer\" );\n    \n    yylineno = line_number;\n}\n\n/** Set the current column.\n * @param line_number\n * @param yyscanner The scanner object.\n */\nvoid katanaset_column (int  column_no , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n        /* column is only valid if an input buffer exists. */\n        if (! YY_CURRENT_BUFFER )\n           YY_FATAL_ERROR( \"katanaset_column called with no buffer\" );\n    \n    yycolumn = column_no;\n}\n\n/** Set the input stream. This does not discard the current\n * input buffer.\n * @param in_str A readable stream.\n * @param yyscanner The scanner object.\n * @see katana_switch_to_buffer\n */\nvoid katanaset_in (FILE *  in_str , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    yyin = in_str ;\n}\n\nvoid katanaset_out (FILE *  out_str , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    yyout = out_str ;\n}\n\nint katanaget_debug  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    return yy_flex_debug;\n}\n\nvoid katanaset_debug (int  bdebug , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    yy_flex_debug = bdebug ;\n}\n\n/* Accessor methods for yylval and yylloc */\n\nYYSTYPE * katanaget_lval  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    return yylval;\n}\n\nvoid katanaset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    yylval = yylval_param;\n}\n\n/* User-visible API */\n\n/* katanalex_init is special because it creates the scanner itself, so it is\n * the ONLY reentrant function that doesn't take the scanner as the last argument.\n * That's why we explicitly handle the declaration, instead of using our macros.\n */\n\nint katanalex_init(yyscan_t* ptr_yy_globals)\n\n{\n    if (ptr_yy_globals == NULL){\n        errno = EINVAL;\n        return 1;\n    }\n\n    *ptr_yy_globals = (yyscan_t) katanaalloc ( sizeof( struct yyguts_t ), NULL );\n\n    if (*ptr_yy_globals == NULL){\n        errno = ENOMEM;\n        return 1;\n    }\n\n    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */\n    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));\n\n    return yy_init_globals ( *ptr_yy_globals );\n}\n\n/* katanalex_init_extra has the same functionality as katanalex_init, but follows the\n * convention of taking the scanner as the last argument. Note however, that\n * this is a *pointer* to a scanner, as it will be allocated by this call (and\n * is the reason, too, why this function also must handle its own declaration).\n * The user defined value in the first argument will be available to katanaalloc in\n * the yyextra field.\n */\n\nint katanalex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )\n\n{\n    struct yyguts_t dummy_yyguts;\n\n    katanaset_extra (yy_user_defined, &dummy_yyguts);\n\n    if (ptr_yy_globals == NULL){\n        errno = EINVAL;\n        return 1;\n    }\n\t\n    *ptr_yy_globals = (yyscan_t) katanaalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );\n\t\n    if (*ptr_yy_globals == NULL){\n        errno = ENOMEM;\n        return 1;\n    }\n    \n    /* By setting to 0xAA, we expose bugs in\n    yy_init_globals. Leave at 0x00 for releases. */\n    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));\n    \n    katanaset_extra (yy_user_defined, *ptr_yy_globals);\n    \n    return yy_init_globals ( *ptr_yy_globals );\n}\n\nstatic int yy_init_globals (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n    /* Initialization is the same as for the non-reentrant scanner.\n     * This function is called from katanalex_destroy(), so don't allocate here.\n     */\n\n    yyg->yy_buffer_stack = 0;\n    yyg->yy_buffer_stack_top = 0;\n    yyg->yy_buffer_stack_max = 0;\n    yyg->yy_c_buf_p = (char *) 0;\n    yyg->yy_init = 0;\n    yyg->yy_start = 0;\n\n    yyg->yy_start_stack_ptr = 0;\n    yyg->yy_start_stack_depth = 0;\n    yyg->yy_start_stack =  NULL;\n\n/* Defined in main.c */\n#ifdef YY_STDINIT\n    yyin = stdin;\n    yyout = stdout;\n#else\n    yyin = (FILE *) 0;\n    yyout = (FILE *) 0;\n#endif\n\n    /* For future reference: Set errno on error, since we are called by\n     * katanalex_init()\n     */\n    return 0;\n}\n\n/* katanalex_destroy is for both reentrant and non-reentrant scanners. */\nint katanalex_destroy  (yyscan_t yyscanner)\n{\n    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;\n\n    /* Pop the buffer stack, destroying each element. */\n\twhile(YY_CURRENT_BUFFER){\n\t\tkatana_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );\n\t\tYY_CURRENT_BUFFER_LVALUE = NULL;\n\t\tkatanapop_buffer_state(yyscanner);\n\t}\n\n\t/* Destroy the stack itself. */\n\tkatanafree(yyg->yy_buffer_stack ,yyscanner);\n\tyyg->yy_buffer_stack = NULL;\n\n    /* Destroy the start condition stack. */\n        katanafree(yyg->yy_start_stack ,yyscanner );\n        yyg->yy_start_stack = NULL;\n\n    /* Reset the globals. This is important in a non-reentrant scanner so the next time\n     * katanalex() is called, initialization will occur. */\n    yy_init_globals( yyscanner);\n\n    /* Destroy the main struct (reentrant only). */\n    katanafree ( yyscanner , yyscanner );\n    yyscanner = NULL;\n    return 0;\n}\n\n/*\n * Internal utility routines.\n */\n\n#ifndef yytext_ptr\nstatic void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)\n{\n\tregister int i;\n\tfor ( i = 0; i < n; ++i )\n\t\ts1[i] = s2[i];\n}\n#endif\n\n#ifdef YY_NEED_STRLEN\nstatic int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)\n{\n\tregister int n;\n\tfor ( n = 0; s[n]; ++n )\n\t\t;\n\n\treturn n;\n}\n#endif\n\nvoid *katanaalloc (yy_size_t  size , yyscan_t yyscanner)\n{\n\treturn (void *) malloc( size );\n}\n\nvoid *katanarealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)\n{\n\t/* The cast to (char *) in the following accommodates both\n\t * implementations that use char* generic pointers, and those\n\t * that use void* generic pointers.  It works with the latter\n\t * because both ANSI C and C++ allow castless assignment from\n\t * any pointer type to void*, and deal with argument conversions\n\t * as though doing an assignment.\n\t */\n\treturn (void *) realloc( (char *) ptr, size );\n}\n\nvoid katanafree (void * ptr , yyscan_t yyscanner)\n{\n\tfree( (char *) ptr );\t/* see katanarealloc() for (char *) cast */\n}\n\n#define YYTABLES_NAME \"yytables\"\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/katana.tab.c",
    "content": "﻿/* A Bison parser, made by GNU Bison 3.0.4.  */\n\n/* Bison implementation for Yacc-like parsers in C\n\n   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.\n\n   This program is free software: you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation, either version 3 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */\n\n/* As a special exception, you may create a larger work that contains\n   part or all of the Bison parser skeleton and distribute that work\n   under terms of your choice, so long as that work isn't itself a\n   parser generator using the skeleton or a modified version thereof\n   as a parser skeleton.  Alternatively, if you modify or redistribute\n   the parser skeleton itself, you may (at your option) remove this\n   special exception, which will cause the skeleton and the resulting\n   Bison output files to be licensed under the GNU General Public\n   License without this special exception.\n\n   This special exception was added by the Free Software Foundation in\n   version 2.2 of Bison.  */\n\n/* C LALR(1) parser skeleton written by Richard Stallman, by\n   simplifying the original so-called \"semantic\" parser.  */\n\n/* All symbols defined below should begin with yy or YY, to avoid\n   infringing on user name space.  This should be done even for local\n   variables, as they might otherwise be expanded by user macros.\n   There are some unavoidable exceptions within include files to\n   define necessary library symbols; they are noted \"INFRINGES ON\n   USER NAME SPACE\" below.  */\n\n#include <strings.h>\n\n/* Identify Bison output.  */\n#define YYBISON 1\n\n/* Bison version.  */\n#define YYBISON_VERSION \"3.0.4\"\n\n/* Skeleton name.  */\n#define YYSKELETON_NAME \"yacc.c\"\n\n/* Pure parsers.  */\n#define YYPURE 2\n\n/* Push parsers.  */\n#define YYPUSH 0\n\n/* Pull parsers.  */\n#define YYPULL 1\n\n/* Substitute the type names.  */\n#define YYSTYPE         KATANASTYPE\n#define YYLTYPE         KATANALTYPE\n/* Substitute the variable and function names.  */\n#define yyparse         katanaparse\n#define yylex           katanalex\n#define yyerror         katanaerror\n#define yydebug         katanadebug\n#define yynerrs         katananerrs\n\n\n/* Copy the first part of user declarations.  */\n\n\n\n#include \"tokenizer.h\"\n\n#define YYENABLE_NLS 0\n#define YYLTYPE_IS_TRIVIAL 1\n#define YYMAXDEPTH 10000\n    \n#ifdef KATANA_BISON_DEBUG\n#if KATANA_BISON_DEBUG\n#ifdef YYDEBUG\n#undef YYDEBUG\n#define YYDEBUG 1\n#endif\nint yydebug = 1;\n#endif // #ifdef KATANA_BISON_DEBUG\n#endif // #ifdef KATANA_BISON_DEBUG\n\n\n\n# ifndef YY_NULLPTR\n#  if defined __cplusplus && 201103L <= __cplusplus\n#   define YY_NULLPTR nullptr\n#  else\n#   define YY_NULLPTR 0\n#  endif\n# endif\n\n/* Enabling verbose error messages.  */\n#ifdef YYERROR_VERBOSE\n# undef YYERROR_VERBOSE\n# define YYERROR_VERBOSE 1\n#else\n# define YYERROR_VERBOSE 0\n#endif\n\n/* In a future release of Bison, this section will be replaced\n   by #include \"katana.tab.h\".  */\n#ifndef YY_KATANA_KATANA_TAB_H_INCLUDED\n# define YY_KATANA_KATANA_TAB_H_INCLUDED\n/* Debug traces.  */\n#ifndef KATANADEBUG\n# if defined YYDEBUG\n#if YYDEBUG\n#   define KATANADEBUG 1\n#  else\n#   define KATANADEBUG 0\n#  endif\n# else /* ! defined YYDEBUG */\n#  define KATANADEBUG 1\n# endif /* ! defined YYDEBUG */\n#endif  /* ! defined KATANADEBUG */\n#if KATANADEBUG\nextern int katanadebug;\n#endif\n/* \"%code requires\" blocks.  */\n\n\n/*\n*  Copyright (C) 2002-2003 Lars Knoll (knoll@kde.org)\n*  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.\n*  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)\n*  Copyright (C) 2008 Eric Seidel <eric@webkit.org>\n*  Copyright (C) 2012 Intel Corporation. All rights reserved.\n*  Copyright (C) 2015 QFish (im@qfi.sh)\n*\n*  This library is free software; you can redistribute it and/or\n*  modify it under the terms of the GNU Lesser General Public\n*  License as published by the Free Software Foundation; either\n*  version 2 of the License, or (at your option) any later version.\n*\n*  This library is distributed in the hope that it will be useful,\n*  but WITHOUT ANY WARRANTY; without even the implied warranty of\n*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n*  Lesser General Public License for more details.\n*\n*  You should have received a copy of the GNU Lesser General Public\n*  License along with this library; if not, write to the Free Software\n*  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n*\n*/\n\n#include \"foundation.h\"\n#include \"katana.h\"\n\n\n\n/* Token type.  */\n#ifndef KATANATOKENTYPE\n# define KATANATOKENTYPE\n  enum katanatokentype\n  {\n    TOKEN_EOF = 0,\n    LOWEST_PREC = 258,\n    UNIMPORTANT_TOK = 259,\n    KATANA_CSS_SGML_CD = 260,\n    KATANA_CSS_WHITESPACE = 261,\n    KATANA_CSS_INCLUDES = 262,\n    KATANA_CSS_DASHMATCH = 263,\n    KATANA_CSS_BEGINSWITH = 264,\n    KATANA_CSS_ENDSWITH = 265,\n    KATANA_CSS_CONTAINS = 266,\n    KATANA_CSS_STRING = 267,\n    KATANA_CSS_IDENT = 268,\n    KATANA_CSS_NTH = 269,\n    KATANA_CSS_HEX = 270,\n    KATANA_CSS_IDSEL = 271,\n    KATANA_CSS_IMPORT_SYM = 272,\n    KATANA_CSS_PAGE_SYM = 273,\n    KATANA_CSS_MEDIA_SYM = 274,\n    KATANA_CSS_SUPPORTS_SYM = 275,\n    KATANA_CSS_FONT_FACE_SYM = 276,\n    KATANA_CSS_CHARSET_SYM = 277,\n    KATANA_CSS_NAMESPACE_SYM = 278,\n    KATANA_INTERNAL_DECLS_SYM = 279,\n    KATANA_INTERNAL_MEDIALIST_SYM = 280,\n    KATANA_INTERNAL_RULE_SYM = 281,\n    KATANA_INTERNAL_SELECTOR_SYM = 282,\n    KATANA_INTERNAL_VALUE_SYM = 283,\n    KATANA_INTERNAL_KEYFRAME_RULE_SYM = 284,\n    KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM = 285,\n    KATANA_INTERNAL_SUPPORTS_CONDITION_SYM = 286,\n    KATANA_CSS_KEYFRAMES_SYM = 287,\n    KATANA_CSS_ATKEYWORD = 288,\n    KATANA_CSS_IMPORTANT_SYM = 289,\n    KATANA_CSS_MEDIA_NOT = 290,\n    KATANA_CSS_MEDIA_ONLY = 291,\n    KATANA_CSS_MEDIA_AND = 292,\n    KATANA_CSS_MEDIA_OR = 293,\n    KATANA_CSS_SUPPORTS_NOT = 294,\n    KATANA_CSS_SUPPORTS_AND = 295,\n    KATANA_CSS_SUPPORTS_OR = 296,\n    KATANA_CSS_REMS = 297,\n    KATANA_CSS_CHS = 298,\n    KATANA_CSS_QEMS = 299,\n    KATANA_CSS_EMS = 300,\n    KATANA_CSS_EXS = 301,\n    KATANA_CSS_PXS = 302,\n    KATANA_CSS_CMS = 303,\n    KATANA_CSS_MMS = 304,\n    KATANA_CSS_INS = 305,\n    KATANA_CSS_PTS = 306,\n    KATANA_CSS_PCS = 307,\n    KATANA_CSS_DEGS = 308,\n    KATANA_CSS_RADS = 309,\n    KATANA_CSS_GRADS = 310,\n    KATANA_CSS_TURNS = 311,\n    KATANA_CSS_MSECS = 312,\n    KATANA_CSS_SECS = 313,\n    KATANA_CSS_HERTZ = 314,\n    KATANA_CSS_KHERTZ = 315,\n    KATANA_CSS_DIMEN = 316,\n    KATANA_CSS_INVALIDDIMEN = 317,\n    KATANA_CSS_PERCENTAGE = 318,\n    KATANA_CSS_FLOATTOKEN = 319,\n    KATANA_CSS_INTEGER = 320,\n    KATANA_CSS_VW = 321,\n    KATANA_CSS_VH = 322,\n    KATANA_CSS_VMIN = 323,\n    KATANA_CSS_VMAX = 324,\n    KATANA_CSS_DPPX = 325,\n    KATANA_CSS_DPI = 326,\n    KATANA_CSS_DPCM = 327,\n    KATANA_CSS_FR = 328,\n    KATANA_CSS_URI = 329,\n    KATANA_CSS_FUNCTION = 330,\n    KATANA_CSS_ANYFUNCTION = 331,\n    KATANA_CSS_CUEFUNCTION = 332,\n    KATANA_CSS_NOTFUNCTION = 333,\n    KATANA_CSS_CALCFUNCTION = 334,\n    KATANA_CSS_MINFUNCTION = 335,\n    KATANA_CSS_MAXFUNCTION = 336,\n    KATANA_CSS_HOSTFUNCTION = 337,\n    KATANA_CSS_HOSTCONTEXTFUNCTION = 338,\n    KATANA_CSS_UNICODERANGE = 339\n  };\n#endif\n\n/* Value type.  */\n#if ! defined KATANASTYPE && ! defined KATANASTYPE_IS_DECLARED\n\nunion KATANASTYPE\n{\n\n\n\n    bool boolean;\n    char character;\n    int integer;\n    KatanaParserNumber number;\n    KatanaParserString string;\n\n    KatanaRule* rule;\n    // The content of the three below HeapVectors are guaranteed to be kept alive by\n    // the corresponding parsedRules, floatingMediaQueryExpList, and parsedKeyFrames\n    // lists\n    KatanaArray* ruleList;\n    KatanaArray* mediaQueryExpList;\n    KatanaArray* keyframeRuleList;\n\n    KatanaSelector* selector;\n    KatanaArray* selectorList;\n    // CSSSelector::MarginBoxType marginBox;\n    KatanaSelectorRelation relation;\n    KatanaAttributeMatchType attributeMatchType;\n    KatanaArray* mediaList;\n    KatanaMediaQuery* mediaQuery;\n    KatanaMediaQueryRestrictor mediaQueryRestrictor;\n    KatanaMediaQueryExp* mediaQueryExp;\n    KatanaValue* value;\n    KatanaArray* valueList;\n    KatanaKeyframe* keyframe;\n    KatanaSourcePosition* location;\n\n\n};\n\ntypedef union KATANASTYPE KATANASTYPE;\n# define KATANASTYPE_IS_TRIVIAL 1\n# define KATANASTYPE_IS_DECLARED 1\n#endif\n\n/* Location type.  */\n#if ! defined KATANALTYPE && ! defined KATANALTYPE_IS_DECLARED\ntypedef struct KATANALTYPE KATANALTYPE;\nstruct KATANALTYPE\n{\n  int first_line;\n  int first_column;\n  int last_line;\n  int last_column;\n};\n# define KATANALTYPE_IS_DECLARED 1\n# define KATANALTYPE_IS_TRIVIAL 1\n#endif\n\n\n\nint katanaparse (void* scanner, struct KatanaInternalParser * parser);\n\n#endif /* !YY_KATANA_KATANA_TAB_H_INCLUDED  */\n\n/* Copy the second part of user declarations.  */\n\n\n\n#ifdef short\n# undef short\n#endif\n\n#ifdef YYTYPE_UINT8\ntypedef YYTYPE_UINT8 yytype_uint8;\n#else\ntypedef unsigned char yytype_uint8;\n#endif\n\n#ifdef YYTYPE_INT8\ntypedef YYTYPE_INT8 yytype_int8;\n#else\ntypedef signed char yytype_int8;\n#endif\n\n#ifdef YYTYPE_UINT16\ntypedef YYTYPE_UINT16 yytype_uint16;\n#else\ntypedef unsigned short int yytype_uint16;\n#endif\n\n#ifdef YYTYPE_INT16\ntypedef YYTYPE_INT16 yytype_int16;\n#else\ntypedef short int yytype_int16;\n#endif\n\n#ifndef YYSIZE_T\n# ifdef __SIZE_TYPE__\n#  define YYSIZE_T __SIZE_TYPE__\n# elif defined size_t\n#  define YYSIZE_T size_t\n# elif ! defined YYSIZE_T\n#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYSIZE_T size_t\n# else\n#  define YYSIZE_T unsigned int\n# endif\n#endif\n\n#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)\n\n#ifndef YY_\n# if defined YYENABLE_NLS && YYENABLE_NLS\n#  if ENABLE_NLS\n#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */\n#   define YY_(Msgid) dgettext (\"bison-runtime\", Msgid)\n#  endif\n# endif\n# ifndef YY_\n#  define YY_(Msgid) Msgid\n# endif\n#endif\n\n#ifndef YY_ATTRIBUTE\n# if (defined __GNUC__                                               \\\n      && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__)))  \\\n     || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C\n#  define YY_ATTRIBUTE(Spec) __attribute__(Spec)\n# else\n#  define YY_ATTRIBUTE(Spec) /* empty */\n# endif\n#endif\n\n#ifndef YY_ATTRIBUTE_PURE\n# define YY_ATTRIBUTE_PURE   YY_ATTRIBUTE ((__pure__))\n#endif\n\n#ifndef YY_ATTRIBUTE_UNUSED\n# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))\n#endif\n\n#if !defined _Noreturn \\\n     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)\n# if defined _MSC_VER && 1200 <= _MSC_VER\n#  define _Noreturn __declspec (noreturn)\n# else\n#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))\n# endif\n#endif\n\n/* Suppress unused-variable warnings by \"using\" E.  */\n#if ! defined lint || defined __GNUC__\n# define YYUSE(E) ((void) (E))\n#else\n# define YYUSE(E) /* empty */\n#endif\n\n#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__\n/* Suppress an incorrect diagnostic about yylval being uninitialized.  */\n# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \\\n    _Pragma (\"GCC diagnostic push\") \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wuninitialized\\\"\")\\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wmaybe-uninitialized\\\"\")\n# define YY_IGNORE_MAYBE_UNINITIALIZED_END \\\n    _Pragma (\"GCC diagnostic pop\")\n#else\n# define YY_INITIAL_VALUE(Value) Value\n#endif\n#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN\n# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN\n# define YY_IGNORE_MAYBE_UNINITIALIZED_END\n#endif\n#ifndef YY_INITIAL_VALUE\n# define YY_INITIAL_VALUE(Value) /* Nothing. */\n#endif\n\n\n#if ! defined yyoverflow || YYERROR_VERBOSE\n\n/* The parser invokes alloca or malloc; define the necessary symbols.  */\n\n# ifdef YYSTACK_USE_ALLOCA\n#  if YYSTACK_USE_ALLOCA\n#   ifdef __GNUC__\n#    define YYSTACK_ALLOC __builtin_alloca\n#   elif defined __BUILTIN_VA_ARG_INCR\n#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */\n#   elif defined _AIX\n#    define YYSTACK_ALLOC __alloca\n#   elif defined _MSC_VER\n#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */\n#    define alloca _alloca\n#   else\n#    define YYSTACK_ALLOC alloca\n#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS\n#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */\n#     ifndef EXIT_SUCCESS\n#      define EXIT_SUCCESS 0\n#     endif\n#    endif\n#   endif\n#  endif\n# endif\n\n# ifdef YYSTACK_ALLOC\n   /* Pacify GCC's 'empty if-body' warning.  */\n#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)\n#  ifndef YYSTACK_ALLOC_MAXIMUM\n    /* The OS might guarantee only one guard page at the bottom of the stack,\n       and a page size can be as small as 4096 bytes.  So we cannot safely\n       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number\n       to allow for a few compiler-allocated temporary stack slots.  */\n#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */\n#  endif\n# else\n#  define YYSTACK_ALLOC YYMALLOC\n#  define YYSTACK_FREE YYFREE\n#  ifndef YYSTACK_ALLOC_MAXIMUM\n#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM\n#  endif\n#  if (defined __cplusplus && ! defined EXIT_SUCCESS \\\n       && ! ((defined YYMALLOC || defined malloc) \\\n             && (defined YYFREE || defined free)))\n#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */\n#   ifndef EXIT_SUCCESS\n#    define EXIT_SUCCESS 0\n#   endif\n#  endif\n#  ifndef YYMALLOC\n#   define YYMALLOC malloc\n#   if ! defined malloc && ! defined EXIT_SUCCESS\nvoid *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */\n#   endif\n#  endif\n#  ifndef YYFREE\n#   define YYFREE free\n#   if ! defined free && ! defined EXIT_SUCCESS\nvoid free (void *); /* INFRINGES ON USER NAME SPACE */\n#   endif\n#  endif\n# endif\n#endif /* ! defined yyoverflow || YYERROR_VERBOSE */\n\n\n#if (! defined yyoverflow \\\n     && (! defined __cplusplus \\\n         || (defined KATANALTYPE_IS_TRIVIAL && KATANALTYPE_IS_TRIVIAL \\\n             && defined KATANASTYPE_IS_TRIVIAL && KATANASTYPE_IS_TRIVIAL)))\n\n/* A type that is properly aligned for any stack member.  */\nunion yyalloc\n{\n  yytype_int16 yyss_alloc;\n  YYSTYPE yyvs_alloc;\n  YYLTYPE yyls_alloc;\n};\n\n/* The size of the maximum gap between one aligned stack and the next.  */\n# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)\n\n/* The size of an array large to enough to hold all stacks, each with\n   N elements.  */\n# define YYSTACK_BYTES(N) \\\n     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \\\n      + 2 * YYSTACK_GAP_MAXIMUM)\n\n# define YYCOPY_NEEDED 1\n\n/* Relocate STACK from its old location to the new one.  The\n   local variables YYSIZE and YYSTACKSIZE give the old and new number of\n   elements in the stack, and YYPTR gives the new location of the\n   stack.  Advance YYPTR to a properly aligned location for the next\n   stack.  */\n# define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \\\n    do                                                                  \\\n      {                                                                 \\\n        YYSIZE_T yynewbytes;                                            \\\n        YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \\\n        Stack = &yyptr->Stack_alloc;                                    \\\n        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \\\n        yyptr += yynewbytes / sizeof (*yyptr);                          \\\n      }                                                                 \\\n    while (0)\n\n#endif\n\n#if defined YYCOPY_NEEDED && YYCOPY_NEEDED\n/* Copy COUNT objects from SRC to DST.  The source and destination do\n   not overlap.  */\n# ifndef YYCOPY\n#  if defined __GNUC__ && 1 < __GNUC__\n#   define YYCOPY(Dst, Src, Count) \\\n      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))\n#  else\n#   define YYCOPY(Dst, Src, Count)              \\\n      do                                        \\\n        {                                       \\\n          YYSIZE_T yyi;                         \\\n          for (yyi = 0; yyi < (Count); yyi++)   \\\n            (Dst)[yyi] = (Src)[yyi];            \\\n        }                                       \\\n      while (0)\n#  endif\n# endif\n#endif /* !YYCOPY_NEEDED */\n\n/* YYFINAL -- State number of the termination state.  */\n#define YYFINAL  32\n/* YYLAST -- Last index in YYTABLE.  */\n#define YYLAST   1536\n\n/* YYNTOKENS -- Number of terminals.  */\n#define YYNTOKENS  105\n/* YYNNTS -- Number of nonterminals.  */\n#define YYNNTS  129\n/* YYNRULES -- Number of rules.  */\n#define YYNRULES  323\n/* YYNSTATES -- Number of states.  */\n#define YYNSTATES  613\n\n/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned\n   by yylex, with out-of-bounds checking.  */\n#define YYUNDEFTOK  2\n#define YYMAXUTOK   339\n\n#define YYTRANSLATE(YYX)                                                \\\n  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)\n\n/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM\n   as returned by yylex, without out-of-bounds checking.  */\nstatic const yytype_uint8 yytranslate[] =\n{\n       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,   103,     2,   104,     2,     2,\n      94,    91,    20,    97,    95,   101,    18,   100,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,    17,    93,\n       2,   102,    99,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,    19,     2,    92,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,    96,    21,    90,    98,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,\n       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,\n      15,    16,    22,    23,    24,    25,    26,    27,    28,    29,\n      30,    31,    32,    33,    34,    35,    36,    37,    38,    39,\n      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,\n      50,    51,    52,    53,    54,    55,    56,    57,    58,    59,\n      60,    61,    62,    63,    64,    65,    66,    67,    68,    69,\n      70,    71,    72,    73,    74,    75,    76,    77,    78,    79,\n      80,    81,    82,    83,    84,    85,    86,    87,    88,    89\n};\n\n#if KATANADEBUG\n  /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */\nstatic const yytype_uint16 yyrline[] =\n{\n       0,   344,   344,   345,   346,   347,   348,   349,   350,   351,\n     356,   362,   368,   374,   381,   387,   393,   405,   406,   410,\n     411,   414,   416,   417,   421,   422,   426,   427,   431,   432,\n     436,   437,   440,   442,   446,   449,   451,   458,   459,   461,\n     462,   463,   464,   465,   470,   476,   481,   488,   489,   493,\n     494,   500,   506,   508,   509,   510,   511,   513,   517,   521,\n     528,   534,   541,   544,   550,   557,   558,   562,   563,   567,\n     570,   576,   582,   588,   592,   599,   602,   608,   611,   614,\n     620,   623,   630,   631,   635,   642,   645,   649,   653,   657,\n     665,   669,   676,   682,   688,   694,   697,   702,   706,   712,\n     719,   726,   727,   728,   729,   733,   739,   742,   748,   751,\n     757,   760,   761,   768,   782,   789,   795,   804,   810,   811,\n     815,   816,   822,   826,   830,   838,   844,   848,   855,   858,\n     878,   991,   997,  1019,  1020,  1021,  1022,  1031,  1032,  1036,\n    1037,  1041,  1047,  1054,  1060,  1066,  1072,  1077,  1082,  1089,\n    1090,  1091,  1104,  1119,  1122,  1125,  1129,  1134,  1139,  1144,\n    1152,  1157,  1176,  1182,  1188,  1189,  1195,  1202,  1213,  1214,\n    1215,  1219,  1229,  1237,  1246,  1247,  1251,  1257,  1264,  1269,\n    1275,  1281,  1284,  1287,  1290,  1293,  1296,  1302,  1303,  1320,\n    1332,  1374,  1378,  1389,  1404,  1423,  1427,  1443,  1456,  1470,\n    1476,  1479,  1480,  1481,  1484,  1488,  1492,  1499,  1513,  1520,\n    1526,  1532,  1539,  1550,  1551,  1555,  1559,  1566,  1569,  1572,\n    1578,  1582,  1587,  1594,  1600,  1603,  1606,  1612,  1613,  1619,\n    1620,  1622,  1623,  1624,  1625,  1626,  1627,  1629,  1630,  1631,\n    1632,  1636,  1637,  1638,  1639,  1640,  1641,  1642,  1643,  1644,\n    1645,  1646,  1647,  1648,  1649,  1650,  1651,  1652,  1653,  1654,\n    1655,  1656,  1657,  1658,  1659,  1660,  1661,  1662,  1663,  1664,\n    1665,  1669,  1672,  1675,  1681,  1682,  1686,  1689,  1692,  1695,\n    1700,  1702,  1706,  1712,  1718,  1722,  1727,  1732,  1736,  1739,\n    1745,  1749,  1753,  1759,  1760,  1764,  1766,  1767,  1774,  1776,\n    1783,  1786,  1787,  1788,  1792,  1795,  1796,  1800,  1806,  1812,\n    1816,  1819,  1819,  1822,  1827,  1832,  1834,  1835,  1836,  1837,\n    1840,  1842,  1843,  1844\n};\n#endif\n\n#if KATANADEBUG || YYERROR_VERBOSE || 1\n/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.\n   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */\nstatic const char *const yytname[] =\n{\n  \"TOKEN_EOF\", \"error\", \"$undefined\", \"LOWEST_PREC\", \"UNIMPORTANT_TOK\",\n  \"KATANA_CSS_SGML_CD\", \"KATANA_CSS_WHITESPACE\", \"KATANA_CSS_INCLUDES\",\n  \"KATANA_CSS_DASHMATCH\", \"KATANA_CSS_BEGINSWITH\", \"KATANA_CSS_ENDSWITH\",\n  \"KATANA_CSS_CONTAINS\", \"KATANA_CSS_STRING\", \"KATANA_CSS_IDENT\",\n  \"KATANA_CSS_NTH\", \"KATANA_CSS_HEX\", \"KATANA_CSS_IDSEL\", \"':'\", \"'.'\",\n  \"'['\", \"'*'\", \"'|'\", \"KATANA_CSS_IMPORT_SYM\", \"KATANA_CSS_PAGE_SYM\",\n  \"KATANA_CSS_MEDIA_SYM\", \"KATANA_CSS_SUPPORTS_SYM\",\n  \"KATANA_CSS_FONT_FACE_SYM\", \"KATANA_CSS_CHARSET_SYM\",\n  \"KATANA_CSS_NAMESPACE_SYM\", \"KATANA_INTERNAL_DECLS_SYM\",\n  \"KATANA_INTERNAL_MEDIALIST_SYM\", \"KATANA_INTERNAL_RULE_SYM\",\n  \"KATANA_INTERNAL_SELECTOR_SYM\", \"KATANA_INTERNAL_VALUE_SYM\",\n  \"KATANA_INTERNAL_KEYFRAME_RULE_SYM\",\n  \"KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM\",\n  \"KATANA_INTERNAL_SUPPORTS_CONDITION_SYM\", \"KATANA_CSS_KEYFRAMES_SYM\",\n  \"KATANA_CSS_ATKEYWORD\", \"KATANA_CSS_IMPORTANT_SYM\",\n  \"KATANA_CSS_MEDIA_NOT\", \"KATANA_CSS_MEDIA_ONLY\", \"KATANA_CSS_MEDIA_AND\",\n  \"KATANA_CSS_MEDIA_OR\", \"KATANA_CSS_SUPPORTS_NOT\",\n  \"KATANA_CSS_SUPPORTS_AND\", \"KATANA_CSS_SUPPORTS_OR\", \"KATANA_CSS_REMS\",\n  \"KATANA_CSS_CHS\", \"KATANA_CSS_QEMS\", \"KATANA_CSS_EMS\", \"KATANA_CSS_EXS\",\n  \"KATANA_CSS_PXS\", \"KATANA_CSS_CMS\", \"KATANA_CSS_MMS\", \"KATANA_CSS_INS\",\n  \"KATANA_CSS_PTS\", \"KATANA_CSS_PCS\", \"KATANA_CSS_DEGS\", \"KATANA_CSS_RADS\",\n  \"KATANA_CSS_GRADS\", \"KATANA_CSS_TURNS\", \"KATANA_CSS_MSECS\",\n  \"KATANA_CSS_SECS\", \"KATANA_CSS_HERTZ\", \"KATANA_CSS_KHERTZ\",\n  \"KATANA_CSS_DIMEN\", \"KATANA_CSS_INVALIDDIMEN\", \"KATANA_CSS_PERCENTAGE\",\n  \"KATANA_CSS_FLOATTOKEN\", \"KATANA_CSS_INTEGER\", \"KATANA_CSS_VW\",\n  \"KATANA_CSS_VH\", \"KATANA_CSS_VMIN\", \"KATANA_CSS_VMAX\", \"KATANA_CSS_DPPX\",\n  \"KATANA_CSS_DPI\", \"KATANA_CSS_DPCM\", \"KATANA_CSS_FR\", \"KATANA_CSS_URI\",\n  \"KATANA_CSS_FUNCTION\", \"KATANA_CSS_ANYFUNCTION\",\n  \"KATANA_CSS_CUEFUNCTION\", \"KATANA_CSS_NOTFUNCTION\",\n  \"KATANA_CSS_CALCFUNCTION\", \"KATANA_CSS_MINFUNCTION\",\n  \"KATANA_CSS_MAXFUNCTION\", \"KATANA_CSS_HOSTFUNCTION\",\n  \"KATANA_CSS_HOSTCONTEXTFUNCTION\", \"KATANA_CSS_UNICODERANGE\", \"'}'\",\n  \"')'\", \"']'\", \"';'\", \"'('\", \"','\", \"'{'\", \"'+'\", \"'~'\", \"'>'\", \"'/'\",\n  \"'-'\", \"'='\", \"'#'\", \"'%'\", \"$accept\", \"stylesheet\",\n  \"katana_internal_rule\", \"katana_internal_keyframe_rule\",\n  \"katana_internal_keyframe_key_list\", \"katana_internal_decls\",\n  \"katana_internal_value\", \"katana_internal_medialist\",\n  \"katana_internal_selector\", \"space\", \"maybe_space\", \"maybe_sgml\",\n  \"closing_brace\", \"closing_parenthesis\", \"closing_square_bracket\",\n  \"semi_or_eof\", \"maybe_charset\", \"rule_list\", \"valid_rule\", \"before_rule\",\n  \"rule\", \"block_rule_body\", \"block_rule_list\", \"block_rule_recovery\",\n  \"block_valid_rule\", \"block_rule\", \"before_import_rule\",\n  \"import_rule_start\", \"import\", \"namespace\", \"maybe_ns_prefix\",\n  \"string_or_uri\", \"maybe_media_value\", \"media_query_exp\",\n  \"media_query_exp_list\", \"maybe_and_media_query_exp_list\",\n  \"maybe_media_restrictor\", \"valid_media_query\", \"media_query\",\n  \"maybe_media_list\", \"media_list\", \"mq_list\", \"at_rule_body_start\",\n  \"before_media_rule\", \"at_rule_header_end_maybe_space\",\n  \"media_rule_start\", \"media\", \"medium\", \"supports\",\n  \"before_supports_rule\", \"at_supports_rule_header_end\",\n  \"supports_condition\", \"supports_negation\", \"supports_conjunction\",\n  \"supports_disjunction\", \"supports_condition_in_parens\",\n  \"supports_declaration_condition\", \"before_keyframes_rule\",\n  \"keyframes_rule_start\", \"keyframes\", \"keyframe_name\", \"keyframes_rule\",\n  \"keyframe_rule_list\", \"keyframe_rule\", \"key_list\", \"key\",\n  \"keyframes_error_recovery\", \"before_font_face_rule\", \"font_face\",\n  \"combinator\", \"maybe_unary_operator\", \"unary_operator\",\n  \"maybe_space_before_declaration\", \"before_selector_list\",\n  \"at_rule_header_end\", \"at_selector_end\", \"ruleset\",\n  \"before_selector_group_item\", \"selector_list\", \"selector\",\n  \"namespace_selector\", \"simple_selector\", \"element_name\",\n  \"specifier_list\", \"specifier\", \"class\", \"attr_name\", \"attr_match_type\",\n  \"maybe_attr_match_type\", \"attrib\", \"match\", \"ident_or_string\", \"pseudo\",\n  \"selector_recovery\", \"declaration_list\", \"decl_list\", \"declaration\",\n  \"property\", \"prio\", \"ident_list\", \"track_names_list\", \"expr\",\n  \"expr_recovery\", \"operator\", \"term\", \"unary_term\", \"function\",\n  \"calc_func_term\", \"calc_func_operator\", \"calc_maybe_space\",\n  \"calc_func_paren_expr\", \"calc_func_expr\", \"calc_function\", \"invalid_at\",\n  \"at_rule_recovery\", \"at_rule_header_recovery\", \"at_rule_end\",\n  \"regular_invalid_at_rule_header\", \"invalid_rule\", \"invalid_rule_header\",\n  \"at_invalid_rule_header_end\", \"invalid_block\",\n  \"invalid_square_brackets_block\", \"invalid_parentheses_block\",\n  \"opening_parenthesis\", \"error_location\", \"location_label\",\n  \"error_recovery\", \"rule_error_recovery\", YY_NULLPTR\n};\n#endif\n\n# ifdef YYPRINT\n/* YYTOKNUM[NUM] -- (External) token number corresponding to the\n   (internal) symbol number NUM (which must be that of a token).  */\nstatic const yytype_uint16 yytoknum[] =\n{\n       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,\n     265,   266,   267,   268,   269,   270,   271,    58,    46,    91,\n      42,   124,   272,   273,   274,   275,   276,   277,   278,   279,\n     280,   281,   282,   283,   284,   285,   286,   287,   288,   289,\n     290,   291,   292,   293,   294,   295,   296,   297,   298,   299,\n     300,   301,   302,   303,   304,   305,   306,   307,   308,   309,\n     310,   311,   312,   313,   314,   315,   316,   317,   318,   319,\n     320,   321,   322,   323,   324,   325,   326,   327,   328,   329,\n     330,   331,   332,   333,   334,   335,   336,   337,   338,   339,\n     125,    41,    93,    59,    40,    44,   123,    43,   126,    62,\n      47,    45,    61,    35,    37\n};\n# endif\n\n#define YYPACT_NINF -413\n\n#define yypact_value_is_default(Yystate) \\\n  (!!((Yystate) == (-413)))\n\n#define YYTABLE_NINF -314\n\n#define yytable_value_is_error(Yytable_value) \\\n  0\n\n  /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing\n     STATE-NUM.  */\nstatic const yytype_int16 yypact[] =\n{\n    1014,   491,    23,    23,    23,    23,    23,    23,    23,    53,\n    -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,\n      66,    75,  -413,  -413,  -413,    78,  -413,   760,   876,  1289,\n     272,   272,  -413,   183,  -413,  -413,    23,  -413,  -413,    93,\n      61,     8,    49,    90,    99,    23,    23,   101,     9,  -413,\n    -413,   110,   539,  -413,  -413,   111,   153,   192,  -413,   181,\n    -413,   876,  -413,   188,  -413,  -413,   715,   205,    84,   204,\n    -413,   233,   113,   759,  -413,   519,   519,  -413,  -413,  -413,\n    -413,    23,    23,    23,  -413,  -413,  -413,  -413,  -413,  -413,\n    -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,\n    -413,  -413,  -413,    23,  -413,  -413,  -413,  -413,  -413,  -413,\n    -413,  -413,  -413,  -413,  -413,    23,    23,    23,    23,    23,\n    -413,  -413,    23,    23,  1426,    23,   758,  -413,    23,    23,\n      23,  -413,    23,   165,    23,   172,  -413,    46,  -413,  -413,\n     243,   107,    86,  -413,    39,  -413,  -413,   158,    23,  -413,\n      23,    23,  -413,    23,    23,    64,  -413,    23,   242,   312,\n     168,   271,  -413,   253,   268,   287,    23,  -413,  -413,    23,\n      23,   195,    23,    23,  -413,  -413,    23,    23,  -413,  -413,\n    -413,   218,   298,   955,   298,   298,   291,  -413,  -413,   431,\n      38,  -413,  -413,   211,   876,    23,    23,    23,   309,   876,\n    -413,  -413,   519,   519,   519,  -413,  -413,  -413,  -413,  -413,\n    -413,   856,  1082,  -413,    83,  -413,  -413,    23,    23,  -413,\n    -413,    23,    23,    23,  1289,  -413,  -413,  -413,  -413,   342,\n      23,    23,  -413,  -413,  -413,   862,  -413,  -413,  -413,  -413,\n    -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,\n     481,    23,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,\n     340,   315,  -413,    23,  -413,    23,  -413,   264,    23,     9,\n    -413,  -413,  -413,  -413,  -413,   -18,  -413,  -413,   274,   302,\n     211,   381,   371,    20,    20,   876,    20,    20,    20,  -413,\n    -413,    50,   204,   396,   269,  -413,  -413,  -413,    23,  -413,\n    -413,  -413,  -413,   313,  -413,   519,  -413,  -413,  -413,  -413,\n     665,    20,    23,  1458,    20,  -413,  -413,  -413,   411,    23,\n    -413,    47,    20,  -413,  -413,  -413,  -413,  -413,  -413,  -413,\n     272,   339,  -413,  -413,   295,   750,   398,   374,   400,  -413,\n    -413,   389,   183,   326,   572,   593,  -413,  -413,  -413,  -413,\n    -413,   524,   936,   415,   572,    23,    23,   386,  -413,  -413,\n    -413,    23,  -413,    23,   549,  -413,    23,   661,  -413,  -413,\n     385,   399,   335,  -413,  -413,  -413,   336,  -413,    23,    23,\n     372,  -413,  -413,    23,  -413,  -413,  -413,   143,  -413,    23,\n     269,  -413,  -413,  -413,  -413,  -413,  -413,  -413,    23,  -413,\n      23,  -413,  -413,  -413,  1082,  -413,  -413,    63,   155,  1347,\n      55,  -413,    23,  -413,  -413,    23,   109,  -413,  -413,   -39,\n     240,  -413,    67,    -4,  -413,   453,  -413,  -413,  -413,  -413,\n    -413,  -413,  1149,  -413,   445,   373,    23,   424,  -413,  -413,\n      86,    39,    23,   382,  -413,   214,   378,    23,    23,    23,\n      23,    23,    23,  -413,    20,    20,    23,    20,  -413,    23,\n     380,   876,  -413,   602,    20,   411,    23,    23,  -413,  -413,\n      23,    23,  -413,  -413,  -413,  -413,   316,  -413,  -413,  -413,\n    -413,  -413,  -413,   529,    23,   248,    23,    20,  -413,   373,\n    -413,  -413,  -413,  -413,  -413,  -413,  -413,    23,    20,  -413,\n     382,   382,   382,   382,  -413,   339,    23,  -413,  -413,    20,\n    -413,   380,  -413,  -413,    23,   113,  -413,    55,    66,    66,\n    -413,  -413,   379,  -413,  -413,  -413,  1289,  -413,    23,   109,\n     208,   572,   460,    23,    23,  -413,  -413,  -413,  -413,  -413,\n     109,   339,  -413,    23,   466,  -413,  -413,   557,   564,  1219,\n     315,  -413,  1434,  -413,  -413,    23,    23,  -413,  -413,   109,\n     282,  -413,   109,   466,    23,  -413,    38,  -413,  -413,   453,\n    -413,   363,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,\n     183,  -413,  1016,   109,  -413,  -413,    23,   379,  -413,    38,\n    -413,  -413,  -413,   -39,    -4,  -413,  1149,  -413,   605,  -413,\n      23,  -413,   610,   572,    20,  -413,  -413,   379,    23,    23,\n    -413,  -413,  -413\n};\n\n  /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.\n     Performed when YYTABLE does not specify something else to do.  Zero\n     means the default is an error.  */\nstatic const yytype_uint16 yydefact[] =\n{\n      32,     0,    19,    19,    19,    19,    19,    19,    19,     0,\n       4,     8,     9,     3,     6,     7,     5,    21,   313,    17,\n      20,     0,    34,   307,   141,     0,   314,   142,     0,     0,\n     138,   138,     1,    35,   320,    18,    19,   307,   313,     0,\n       0,   202,     0,     0,     0,    19,    19,     0,     0,    42,\n      41,     0,     0,    38,    43,     0,     0,     0,    40,     0,\n      39,     0,    37,   162,   167,   166,   313,     0,     0,   163,\n     153,   144,   147,     0,   149,   156,   158,   164,   168,   169,\n     170,    19,    19,    19,   261,   262,   259,   258,   260,   244,\n     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,\n     255,   256,   257,    19,   243,   242,   241,   263,   264,   265,\n     266,   267,   268,   269,   270,    19,    19,    19,    19,    19,\n     140,   139,    19,    19,     0,    19,     0,   220,    19,    19,\n      19,   129,    19,     0,    19,     0,   137,     0,    22,    23,\n      44,     0,     0,   291,     0,   315,    13,   203,    19,   313,\n      19,    19,   313,    19,    19,     0,    73,    19,     0,     0,\n      87,     0,    86,     0,    65,     0,    19,    67,    68,    19,\n      19,     0,    19,    19,   119,   118,    19,    19,   144,   155,\n     313,     0,     0,     0,     0,     0,     0,   171,   313,     0,\n       0,   154,    16,     0,   150,    19,    19,    19,     0,     0,\n     162,   163,   159,   161,   157,   165,   229,   230,   235,   231,\n     233,     0,     0,   234,     0,   236,   239,    19,    19,   240,\n      14,    19,    19,    19,     0,   222,   227,   237,   238,     0,\n      19,    19,   126,   128,    12,     0,    21,   321,   315,   312,\n     311,   322,   323,   315,    31,    30,    33,   315,   293,   294,\n       0,    19,   205,   315,   313,   212,   320,    79,    78,   315,\n       0,    80,    97,    19,   313,    19,    15,    88,    19,     0,\n      10,    61,   314,    95,   143,     0,   116,    94,     0,     0,\n     143,     0,   138,     0,     0,     0,     0,     0,     0,   189,\n     315,    19,     0,     0,     0,    29,    28,   180,    19,   151,\n     133,   134,   135,     0,   152,   160,    27,   313,    26,   272,\n       0,     0,    19,     0,     0,   274,   284,   287,   280,    19,\n     217,     0,     0,   232,   228,   225,   224,   226,   221,    11,\n     138,     0,   313,    45,     0,     0,     0,     0,     0,   307,\n      46,     0,    36,     0,     0,     0,   316,   317,   318,   319,\n     206,     0,     0,     0,     0,    19,    19,    75,    81,   320,\n     314,    19,    66,    19,     0,    92,    19,     0,   100,   102,\n     103,   104,   101,   111,    92,    92,     0,   190,    19,    19,\n       0,   195,   191,    19,   197,   198,   199,     0,   172,    19,\n       0,   182,   183,   184,   185,   186,   181,   176,    19,   146,\n      19,   315,   271,   273,     0,   275,   289,   281,     0,     0,\n       0,   215,    19,   218,   219,    19,     0,   320,   298,     0,\n       0,   295,     0,     0,   290,     0,   309,   310,    25,    24,\n     308,   315,   214,    72,    69,     0,    19,     0,    90,   314,\n       0,     0,    19,     0,   313,     0,     0,    19,    19,    19,\n      19,    19,    19,    92,     0,     0,    19,     0,   178,    19,\n       0,     0,   136,     0,     0,   280,     0,     0,   285,   286,\n      19,    19,   288,   216,   127,   125,     0,   303,   313,   296,\n     301,   302,   299,     0,    19,     0,    19,     0,    74,     0,\n      91,    64,    62,    63,    49,   105,   315,    19,     0,    92,\n       0,     0,     0,     0,   314,     0,    19,   194,   192,     0,\n     196,     0,   188,   187,    19,   148,   283,     0,   276,   277,\n     278,   279,     0,   320,   213,   315,     0,    71,    19,     0,\n      44,     0,     0,    19,    19,   107,   109,   106,   108,   122,\n       0,     0,   193,    19,   175,   282,   300,     0,     0,    70,\n      76,    96,     0,    48,    21,    19,    19,   110,    49,     0,\n       0,   132,     0,   175,    19,   174,     0,   313,    58,     0,\n      57,     0,    54,    56,    55,    53,    52,   307,    59,    51,\n      50,   112,     0,     0,   117,   320,    19,   121,   145,     0,\n     173,   177,   320,   306,   305,   315,   214,    98,     0,   314,\n      19,   179,     0,     0,     0,   123,   314,   304,    19,    19,\n     124,   114,   113\n};\n\n  /* YYPGOTO[NTERM-NUM].  */\nstatic const yytype_int16 yypgoto[] =\n{\n    -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -413,  -281,\n      -1,  -223,  -392,   177,  -280,  -117,  -413,  -413,   245,   -29,\n    -413,   -74,  -413,  -413,  -413,  -413,  -413,  -220,  -413,   -50,\n    -413,   237,  -413,    72,    26,  -413,  -413,  -413,   349,   -43,\n    -413,  -413,  -333,  -413,   346,  -216,   -26,  -413,   -13,   489,\n    -413,   102,  -413,  -413,  -413,  -228,  -413,  -413,   496,    -8,\n    -413,  -413,  -413,    -9,   522,   226,  -413,   532,    15,  -413,\n     286,   -14,  -412,  -413,   289,   392,    29,  -413,   517,   121,\n     395,    71,   513,   -24,   -46,  -413,   299,  -413,    25,  -413,\n     206,    87,  -413,   781,  -303,  -413,   555,  -413,     1,  -413,\n    -413,  -193,  -178,  -413,  -118,   -99,  -413,   191,  -413,   136,\n     207,   209,  -413,  -413,  -413,    11,  -413,    74,    76,  -413,\n     -36,  -121,  -109,  -108,  -413,    -7,  -262,  -195,  -234\n};\n\n  /* YYDEFGOTO[NTERM-NUM].  */\nstatic const yytype_int16 yydefgoto[] =\n{\n      -1,     9,    10,    11,    12,    13,    14,    15,    16,    20,\n      24,    33,   430,   309,   297,   246,    17,   140,    46,   235,\n     236,   529,   530,   553,   568,   554,    47,    48,    49,    50,\n     269,   169,   487,   156,   157,   358,   158,   159,   160,   161,\n     162,   163,   442,    51,   279,    52,    53,   263,    54,   336,\n     446,   368,   369,   370,   371,   372,   373,    56,   337,    58,\n     176,   559,   560,   132,   133,   134,   587,   338,    60,   199,\n     135,   124,    25,    61,   365,   193,    62,   461,    71,    72,\n      73,    74,    75,    76,    77,    78,   294,   565,   566,    79,\n     398,   514,    80,   190,    39,    40,    41,    42,   485,   321,\n     125,   126,   311,   224,   127,   128,   129,   316,   409,   410,\n     317,   318,   130,   425,    22,   418,   143,   339,   340,   579,\n      37,   347,   348,   349,   243,    43,    44,   250,   141\n};\n\n  /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If\n     positive, shift that token.  If negative, reduce the rule whose\n     number is the opposite.  If YYTABLE_NINF, syntax error.  */\nstatic const yytype_int16 yytable[] =\n{\n      21,   144,    26,    27,    28,    29,    30,    31,   225,   171,\n     364,    34,    23,   342,   397,   334,   136,   136,   310,   335,\n     306,   167,   353,   249,   475,   218,   366,   248,   416,    19,\n     205,   145,   241,   242,   314,   142,   322,   408,   295,   244,\n     505,   451,   452,   343,   164,   165,   234,   306,   344,   203,\n     149,   204,   345,    32,   477,   306,    19,   274,   351,   186,\n     412,  -204,    38,   426,   354,   259,   150,   189,    18,   -17,\n      19,   179,    35,    19,  -313,   470,   367,   -19,  -201,    38,\n     206,   207,   208,   306,   307,   188,   244,    36,   168,   480,\n      19,  -313,   247,   146,   541,   387,   319,   -19,   438,   -85,\n     152,   148,   209,   151,   -19,   -19,   328,  -292,   237,   428,\n     458,   308,   -77,   315,   210,   211,   212,   213,   214,   194,\n     506,   215,   216,   166,   219,   437,   238,   226,   227,   228,\n     296,   229,   245,   232,   170,   247,   172,   551,   308,   153,\n     154,   230,   253,  -200,   346,   256,   308,   252,   561,   254,\n     255,  -204,   257,   258,   260,   471,   261,   205,   205,   432,\n     -17,    35,   238,   -19,   -17,   271,   534,   584,   272,   273,\n     588,   275,   276,   281,   308,   277,   277,   490,   305,   245,\n     282,   290,   285,   476,   408,   518,   519,   239,   138,   139,\n     173,   597,   225,   155,   300,   301,   302,  -292,   313,   429,\n    -292,   240,   540,  -292,   174,   175,   463,   177,   -47,   179,\n     195,   196,   197,   198,   405,   495,   323,   324,   187,   188,\n     325,   326,   327,   239,    19,   191,   464,   497,   341,   330,\n     331,   -19,   -19,   192,  -200,  -200,   483,   240,   562,   247,\n     233,   478,   539,    -2,   241,   242,    19,   352,  -207,   525,\n     350,   251,   466,   -89,   152,   262,   467,   359,   366,   205,\n     230,   231,   357,   265,   360,   299,   -77,   362,   136,   295,\n     304,   266,   535,   536,   537,   538,   391,   392,   393,   394,\n     395,   268,  -120,   585,   -19,   131,   591,   270,   -19,   547,\n     388,   274,   419,   153,   154,   131,    18,   399,   -47,   188,\n     401,   531,   481,   423,   289,   315,   298,   167,   367,   601,\n     315,   404,   -82,   264,   225,   -19,   136,   237,   411,   -19,\n     493,   441,   303,   491,   492,   417,   295,   346,   241,   242,\n     548,   580,   569,   549,   -19,   238,   571,   605,  -207,  -201,\n      38,  -207,   329,   -89,   610,   238,   -89,   155,   421,   -89,\n    -138,   598,  -313,   355,   434,   435,   383,   356,   602,   361,\n     439,   296,   440,   -85,   152,   443,   445,   241,   242,   120,\n     374,   396,  -120,   121,   168,    18,   -77,   454,   455,   120,\n     449,   450,   457,   121,   378,   379,   174,   175,   388,   596,\n     313,   320,   512,   513,   377,   313,   239,   460,   375,   462,\n     603,   546,   -82,   153,   154,   -82,   239,   -82,   -82,   389,\n     240,   473,  -307,   400,   474,   -84,   237,   407,   296,   275,\n     240,   277,   247,   420,   -83,   237,   422,   424,   436,  -201,\n     447,   225,   453,   479,   238,   489,   482,   496,   241,   242,\n     522,   494,   456,   238,   291,   448,   500,   501,   502,   503,\n     504,   292,    70,   -85,    18,   509,   -85,   155,   511,   -85,\n     381,   382,   486,   384,   385,   386,   600,   155,   120,   520,\n     521,   523,   121,   481,   499,   247,   367,   556,   225,   564,\n     333,  -211,   346,   524,   583,   526,   546,   402,   403,   241,\n     242,   406,    18,   241,   242,   239,   532,    19,   413,   414,\n     238,   552,   570,   -19,   239,   -84,   363,   488,   -84,   240,\n     -84,   -84,   267,   544,   -83,   528,    55,   -83,   240,   -83,\n     -83,   427,   278,    57,  -210,   346,   572,   550,   593,  -209,\n     346,   433,   557,   558,    64,    65,    66,    67,    68,   573,\n     152,   594,   563,   238,   574,   341,   136,   498,   238,   -85,\n     152,   586,   -77,   137,   581,   582,   415,  -297,   237,    59,\n     592,   239,   -77,   590,  -208,   346,   607,   575,   380,   376,\n     280,  -211,   306,   346,  -211,   240,   238,   247,   178,   153,\n     154,   576,   515,   238,   293,   599,   202,   472,   589,   153,\n     154,   238,   390,   428,   346,   147,   459,   604,   543,   606,\n     468,   517,  -223,   346,   239,  -130,   237,   611,   612,   239,\n    -307,   237,   238,   465,  -210,     0,   469,  -210,   240,  -209,\n     247,   238,  -209,   240,   238,   247,   577,     0,   578,   238,\n       0,   507,   508,   155,   510,   -85,     0,   239,     0,     0,\n       0,   516,   -85,   155,   239,   -85,     0,  -297,     0,     0,\n    -297,   240,   239,  -297,  -208,     0,     0,  -208,   240,     0,\n     247,     0,   444,   308,   527,   306,   240,    19,   247,     0,\n       0,     0,     0,   239,   -19,   533,     0,    81,    82,     0,\n      83,     0,   239,   429,     0,   239,   542,   240,     0,   247,\n     239,     0,     0,  -223,   545,  -130,   240,     0,   247,   240,\n    -307,  -130,     0,     0,   240,   -19,  -307,     0,   555,     0,\n       0,     0,    84,    85,    86,    87,    88,    89,    90,    91,\n      92,    93,    94,    95,    96,    97,    98,    99,   100,   101,\n     102,   103,   180,   104,   105,   106,   107,   108,   109,   110,\n     111,   112,   113,   114,   115,   116,     0,     0,     0,   117,\n       0,   152,     0,     0,   118,   -19,   308,     0,   220,   119,\n     221,     0,   120,   -77,     0,   222,   121,   223,   122,   123,\n      81,    82,   200,    83,    64,    65,    66,    67,    68,   201,\n     608,   609,   -60,     0,   -93,   -99,  -131,     0,    45,     0,\n     153,   154,     0,     0,     0,   181,   182,  -115,   183,     0,\n       0,     0,   184,   185,     0,    84,    85,    86,    87,    88,\n      89,    90,    91,    92,    93,    94,    95,    96,    97,    98,\n      99,   100,   101,   102,   103,     0,   104,   105,   106,   107,\n     108,   109,   110,   111,   112,   113,   114,   115,   116,     0,\n       0,     0,   117,   -85,   155,     0,   -85,   118,     0,     0,\n       0,     0,   119,   221,     0,   120,   306,   307,   222,   121,\n     223,   122,   123,   332,     0,     0,     0,     0,    81,    82,\n       0,    83,     0,     0,     0,  -142,     0,  -142,  -142,  -142,\n    -142,  -142,  -142,  -142,   -60,     0,   -93,   -99,  -131,    63,\n      45,    64,    65,    66,    67,    68,    69,    70,     0,  -115,\n    -313,     0,     0,    84,    85,    86,    87,    88,    89,    90,\n      91,    92,    93,    94,    95,    96,    97,    98,    99,   100,\n     101,   102,   103,     0,   104,   105,   106,   107,   108,   109,\n     110,   111,   112,   113,   114,   115,   116,   431,     0,     0,\n     117,     0,     0,     0,     0,   118,     0,   308,    81,    82,\n     119,    83,     0,   120,     0,     0,   188,   121,     0,   122,\n     123,    19,   283,   284,   286,   287,   288,     0,   -19,     0,\n     -19,   -19,   -19,   -19,   -19,   -19,   -19,     0,     0,     0,\n       0,     0,     0,    84,    85,    86,    87,    88,    89,    90,\n      91,    92,    93,    94,    95,    96,    97,    98,    99,   100,\n     101,   102,   103,     0,   104,   105,   106,   107,   108,   109,\n     110,   111,   112,   113,   114,   115,   116,   595,     0,     0,\n     117,     0,     0,     0,     0,   118,     0,     0,    81,    82,\n     119,    83,     0,   120,     0,     0,     0,   121,     0,   122,\n     123,     1,     0,     2,     3,     4,     5,     6,     7,     8,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,    84,    85,    86,    87,    88,    89,    90,\n      91,    92,    93,    94,    95,    96,    97,    98,    99,   100,\n     101,   102,   103,   307,   104,   105,   106,   107,   108,   109,\n     110,   111,   112,   113,   114,   115,   116,     0,     0,     0,\n     117,     0,     0,     0,     0,   118,     0,     0,     0,     0,\n     119,     0,     0,   120,     0,     0,     0,   121,     0,   122,\n     123,     0,     0,     0,     0,     0,     0,     0,     0,    84,\n      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,\n      95,    96,    97,    98,    99,   100,   101,   102,     0,     0,\n     104,   105,   106,   107,   108,   109,   110,   111,   112,   113,\n     114,    81,    82,     0,    83,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,   312,     0,     0,   120,\n       0,     0,     0,   121,     0,     0,     0,     0,   484,     0,\n       0,     0,     0,     0,     0,     0,    84,    85,    86,    87,\n      88,    89,    90,    91,    92,    93,    94,    95,    96,    97,\n      98,    99,   100,   101,   102,   103,     0,   104,   105,   106,\n     107,   108,   109,   110,   111,   112,   113,   114,   115,   116,\n       0,    81,    82,   117,    83,     0,     0,     0,   118,     0,\n       0,     0,     0,   119,   221,     0,   120,     0,     0,   222,\n     121,   223,   122,   123,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,    84,    85,    86,    87,\n      88,    89,    90,    91,    92,    93,    94,    95,    96,    97,\n      98,    99,   100,   101,   102,   103,     0,   104,   105,   106,\n     107,   108,   109,   110,   111,   112,   113,   114,   115,   116,\n       0,    81,    82,   117,    83,     0,     0,     0,   118,     0,\n       0,     0,     0,   119,   221,     0,   120,     0,     0,   222,\n     121,   223,   122,   123,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,    84,    85,    86,    87,\n      88,    89,    90,    91,    92,    93,    94,    95,    96,    97,\n      98,    99,   100,   101,   102,   103,     0,   104,   105,   106,\n     107,   108,   109,   110,   111,   112,   113,   114,   115,   116,\n       0,     0,     0,   117,     0,     0,     0,     0,   118,     0,\n       0,     0,     0,   119,     0,     0,   120,     0,     0,     0,\n     121,     0,   122,   123,    84,    85,    86,    87,    88,    89,\n      90,    91,    92,    93,    94,    95,    96,    97,    98,    99,\n     100,   101,   102,     0,     0,   104,   105,   106,   107,   108,\n     109,   110,   111,   112,   113,   114,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,   567,     0,     0,     0,     0,\n       0,   312,     0,     0,   120,     0,     0,  -142,   121,  -142,\n    -142,  -142,  -142,  -142,  -142,  -142,   -60,     0,   -93,   -99,\n    -131,     0,    45,     0,     0,     0,     0,     0,     0,     0,\n       0,  -115,  -313,    84,    85,    86,    87,    88,    89,    90,\n      91,    92,    93,    94,    95,    96,    97,    98,    99,   100,\n     101,   102,   217,     0,   104,   105,   106,   107,   108,   109,\n     110,   111,   112,   113,   114,    84,    85,    86,    87,    88,\n      89,    90,    91,    92,    93,    94,    95,    96,    97,    98,\n      99,   100,   101,   102,     0,     0,   104,   105,   106,   107,\n     108,   109,   110,   111,   112,   113,   114\n};\n\nstatic const yytype_int16 yycheck[] =\n{\n       1,    37,     3,     4,     5,     6,     7,     8,   126,    52,\n     272,    18,     1,   236,   294,   235,    30,    31,   211,   235,\n       0,    12,   256,   144,   416,   124,    44,   144,   331,     6,\n      76,    38,   141,   141,   212,    36,   214,   318,     0,     0,\n     452,   374,   375,   238,    45,    46,     0,     0,   243,    73,\n       1,    75,   247,     0,    93,     0,     6,    96,   253,    66,\n      13,     0,     1,   343,   259,     1,    17,    68,     1,     6,\n       6,    21,     6,     6,    13,    20,    94,    13,     0,     1,\n      81,    82,    83,     0,     1,     1,     0,    12,    79,    93,\n       6,    13,    96,     0,   506,   290,    13,    13,   360,     0,\n       1,    93,   103,    13,    20,    21,   224,     0,     1,     0,\n     390,    91,    13,   212,   115,   116,   117,   118,   119,     6,\n     453,   122,   123,    22,   125,   359,    19,   128,   129,   130,\n      92,   132,    93,   134,    24,    96,    25,   529,    91,    40,\n      41,    95,   149,     0,     1,   152,    91,   148,   540,   150,\n     151,    90,   153,   154,   155,   100,   157,   203,   204,   352,\n      97,     6,    19,    96,   101,   166,   499,   559,   169,   170,\n     562,   172,   173,   180,    91,   176,   177,   439,   202,    93,\n     181,   188,   183,   417,   465,   466,   467,    80,     5,     6,\n      37,   583,   310,    94,   195,   196,   197,    90,   212,    90,\n      93,    94,   505,    96,    12,    13,   401,    26,     0,    21,\n      97,    98,    99,   100,   313,   443,   217,   218,    13,     1,\n     221,   222,   223,    80,     6,    21,   404,    13,   235,   230,\n     231,    13,    14,     0,    91,    92,   431,    94,   541,    96,\n      68,     1,   504,     0,   353,   353,     6,   254,     0,     1,\n     251,    93,    97,     0,     1,    13,   101,   264,    44,   305,\n      95,    96,   263,    95,   265,   194,    13,   268,   282,     0,\n     199,     0,   500,   501,   502,   503,     7,     8,     9,    10,\n      11,    13,     0,     1,    44,    13,   566,     0,    70,   523,\n     291,    96,   335,    40,    41,    13,     1,   298,    90,     1,\n     307,   496,   423,   339,    13,   404,    95,    12,    94,   589,\n     409,   312,     0,     1,   432,    97,   330,     1,   319,   101,\n     441,   364,    13,   440,   441,   332,     0,     1,   437,   437,\n     525,   554,   552,   526,    94,    19,   552,   599,    90,     0,\n       1,    93,     0,    90,   606,    19,    93,    94,   337,    96,\n      68,   585,    13,    13,   355,   356,   285,    42,   592,    95,\n     361,    92,   363,     0,     1,   366,   367,   476,   476,    97,\n      96,   102,    90,   101,    79,     1,    13,   378,   379,    97,\n      45,    46,   383,   101,    13,    14,    12,    13,   389,   582,\n     404,   214,    12,    13,    13,   409,    80,   398,    96,   400,\n     595,   522,    90,    40,    41,    93,    80,    95,    96,    13,\n      94,   412,    96,   100,   415,     0,     1,     6,    92,   420,\n      94,   422,    96,    25,     0,     1,    26,    38,    42,    90,\n      45,   549,    96,   422,    19,   436,   425,   444,   547,   547,\n     476,   442,    70,    19,    13,    46,   447,   448,   449,   450,\n     451,    20,    21,    90,     1,   456,    93,    94,   459,    96,\n     283,   284,    17,   286,   287,   288,   587,    94,    97,   470,\n     471,   478,   101,   594,    96,    96,    94,    17,   596,    13,\n     235,     0,     1,   484,   558,   486,   607,   310,   311,   598,\n     598,   314,     1,   602,   602,    80,   497,     6,   321,   322,\n      19,   530,   552,    12,    80,    90,   269,   435,    93,    94,\n      95,    96,   163,   514,    90,   489,    27,    93,    94,    95,\n      96,   344,   176,    27,     0,     1,   552,   528,   571,     0,\n       1,   354,   533,   534,    15,    16,    17,    18,    19,   552,\n       1,   577,   543,    19,   552,   552,   560,   445,    19,     0,\n       1,   560,    13,    31,   555,   556,   330,     0,     1,    27,\n     567,    80,    13,   564,     0,     1,   602,   552,   282,   280,\n     178,    90,     0,     1,    93,    94,    19,    96,    61,    40,\n      41,   552,   461,    19,   189,   586,    73,   410,   563,    40,\n      41,    19,   293,     0,     1,    40,   390,   596,   511,   600,\n     409,   465,     0,     1,    80,     0,     1,   608,   609,    80,\n       0,     1,    19,   404,    90,    -1,   409,    93,    94,    90,\n      96,    19,    93,    94,    19,    96,   552,    -1,   552,    19,\n      -1,   454,   455,    94,   457,    96,    -1,    80,    -1,    -1,\n      -1,   464,    93,    94,    80,    96,    -1,    90,    -1,    -1,\n      93,    94,    80,    96,    90,    -1,    -1,    93,    94,    -1,\n      96,    -1,     1,    91,   487,     0,    94,     6,    96,    -1,\n      -1,    -1,    -1,    80,    13,   498,    -1,    12,    13,    -1,\n      15,    -1,    80,    90,    -1,    80,   509,    94,    -1,    96,\n      80,    -1,    -1,    91,   517,    90,    94,    -1,    96,    94,\n      90,    96,    -1,    -1,    94,    44,    96,    -1,   531,    -1,\n      -1,    -1,    47,    48,    49,    50,    51,    52,    53,    54,\n      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,\n      65,    66,    17,    68,    69,    70,    71,    72,    73,    74,\n      75,    76,    77,    78,    79,    80,    -1,    -1,    -1,    84,\n      -1,     1,    -1,    -1,    89,    94,    91,    -1,     0,    94,\n      95,    -1,    97,    13,    -1,   100,   101,   102,   103,   104,\n      12,    13,    13,    15,    15,    16,    17,    18,    19,    20,\n     603,   604,    22,    -1,    24,    25,    26,    -1,    28,    -1,\n      40,    41,    -1,    -1,    -1,    80,    81,    37,    83,    -1,\n      -1,    -1,    87,    88,    -1,    47,    48,    49,    50,    51,\n      52,    53,    54,    55,    56,    57,    58,    59,    60,    61,\n      62,    63,    64,    65,    66,    -1,    68,    69,    70,    71,\n      72,    73,    74,    75,    76,    77,    78,    79,    80,    -1,\n      -1,    -1,    84,    93,    94,    -1,    96,    89,    -1,    -1,\n      -1,    -1,    94,    95,    -1,    97,     0,     1,   100,   101,\n     102,   103,   104,     1,    -1,    -1,    -1,    -1,    12,    13,\n      -1,    15,    -1,    -1,    -1,    13,    -1,    15,    16,    17,\n      18,    19,    20,    21,    22,    -1,    24,    25,    26,    13,\n      28,    15,    16,    17,    18,    19,    20,    21,    -1,    37,\n      38,    -1,    -1,    47,    48,    49,    50,    51,    52,    53,\n      54,    55,    56,    57,    58,    59,    60,    61,    62,    63,\n      64,    65,    66,    -1,    68,    69,    70,    71,    72,    73,\n      74,    75,    76,    77,    78,    79,    80,     1,    -1,    -1,\n      84,    -1,    -1,    -1,    -1,    89,    -1,    91,    12,    13,\n      94,    15,    -1,    97,    -1,    -1,     1,   101,    -1,   103,\n     104,     6,   181,   182,   183,   184,   185,    -1,    13,    -1,\n      15,    16,    17,    18,    19,    20,    21,    -1,    -1,    -1,\n      -1,    -1,    -1,    47,    48,    49,    50,    51,    52,    53,\n      54,    55,    56,    57,    58,    59,    60,    61,    62,    63,\n      64,    65,    66,    -1,    68,    69,    70,    71,    72,    73,\n      74,    75,    76,    77,    78,    79,    80,     1,    -1,    -1,\n      84,    -1,    -1,    -1,    -1,    89,    -1,    -1,    12,    13,\n      94,    15,    -1,    97,    -1,    -1,    -1,   101,    -1,   103,\n     104,    27,    -1,    29,    30,    31,    32,    33,    34,    35,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    47,    48,    49,    50,    51,    52,    53,\n      54,    55,    56,    57,    58,    59,    60,    61,    62,    63,\n      64,    65,    66,     1,    68,    69,    70,    71,    72,    73,\n      74,    75,    76,    77,    78,    79,    80,    -1,    -1,    -1,\n      84,    -1,    -1,    -1,    -1,    89,    -1,    -1,    -1,    -1,\n      94,    -1,    -1,    97,    -1,    -1,    -1,   101,    -1,   103,\n     104,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    47,\n      48,    49,    50,    51,    52,    53,    54,    55,    56,    57,\n      58,    59,    60,    61,    62,    63,    64,    65,    -1,    -1,\n      68,    69,    70,    71,    72,    73,    74,    75,    76,    77,\n      78,    12,    13,    -1,    15,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    94,    -1,    -1,    97,\n      -1,    -1,    -1,   101,    -1,    -1,    -1,    -1,    39,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    47,    48,    49,    50,\n      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,\n      61,    62,    63,    64,    65,    66,    -1,    68,    69,    70,\n      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,\n      -1,    12,    13,    84,    15,    -1,    -1,    -1,    89,    -1,\n      -1,    -1,    -1,    94,    95,    -1,    97,    -1,    -1,   100,\n     101,   102,   103,   104,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    47,    48,    49,    50,\n      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,\n      61,    62,    63,    64,    65,    66,    -1,    68,    69,    70,\n      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,\n      -1,    12,    13,    84,    15,    -1,    -1,    -1,    89,    -1,\n      -1,    -1,    -1,    94,    95,    -1,    97,    -1,    -1,   100,\n     101,   102,   103,   104,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    47,    48,    49,    50,\n      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,\n      61,    62,    63,    64,    65,    66,    -1,    68,    69,    70,\n      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,\n      -1,    -1,    -1,    84,    -1,    -1,    -1,    -1,    89,    -1,\n      -1,    -1,    -1,    94,    -1,    -1,    97,    -1,    -1,    -1,\n     101,    -1,   103,   104,    47,    48,    49,    50,    51,    52,\n      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,\n      63,    64,    65,    -1,    -1,    68,    69,    70,    71,    72,\n      73,    74,    75,    76,    77,    78,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,     1,    -1,    -1,    -1,    -1,\n      -1,    94,    -1,    -1,    97,    -1,    -1,    13,   101,    15,\n      16,    17,    18,    19,    20,    21,    22,    -1,    24,    25,\n      26,    -1,    28,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    37,    38,    47,    48,    49,    50,    51,    52,    53,\n      54,    55,    56,    57,    58,    59,    60,    61,    62,    63,\n      64,    65,    66,    -1,    68,    69,    70,    71,    72,    73,\n      74,    75,    76,    77,    78,    47,    48,    49,    50,    51,\n      52,    53,    54,    55,    56,    57,    58,    59,    60,    61,\n      62,    63,    64,    65,    -1,    -1,    68,    69,    70,    71,\n      72,    73,    74,    75,    76,    77,    78\n};\n\n  /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing\n     symbol of state STATE-NUM.  */\nstatic const yytype_uint8 yystos[] =\n{\n       0,    27,    29,    30,    31,    32,    33,    34,    35,   106,\n     107,   108,   109,   110,   111,   112,   113,   121,     1,     6,\n     114,   115,   219,   220,   115,   177,   115,   115,   115,   115,\n     115,   115,     0,   116,   230,     6,    12,   225,     1,   199,\n     200,   201,   202,   230,   231,    28,   123,   131,   132,   133,\n     134,   148,   150,   151,   153,   154,   162,   163,   164,   172,\n     173,   178,   181,    13,    15,    16,    17,    18,    19,    20,\n      21,   183,   184,   185,   186,   187,   188,   189,   190,   194,\n     197,    12,    13,    15,    47,    48,    49,    50,    51,    52,\n      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,\n      63,    64,    65,    66,    68,    69,    70,    71,    72,    73,\n      74,    75,    76,    77,    78,    79,    80,    84,    89,    94,\n      97,   101,   103,   104,   176,   205,   206,   209,   210,   211,\n     217,    13,   168,   169,   170,   175,   176,   169,     5,     6,\n     122,   233,   115,   221,   225,   230,     0,   201,    93,     1,\n      17,    13,     1,    40,    41,    94,   138,   139,   141,   142,\n     143,   144,   145,   146,   115,   115,    22,    12,    79,   136,\n      24,   144,    25,    37,    12,    13,   165,    26,   183,    21,\n      17,    80,    81,    83,    87,    88,   230,    13,     1,   115,\n     198,    21,     0,   180,     6,    97,    98,    99,   100,   174,\n      13,    20,   187,   188,   188,   189,   115,   115,   115,   115,\n     115,   115,   115,   115,   115,   115,   115,    66,   210,   115,\n       0,    95,   100,   102,   208,   209,   115,   115,   115,   115,\n      95,    96,   115,    68,     0,   124,   125,     1,    19,    80,\n      94,   227,   228,   229,     0,    93,   120,    96,   120,   226,\n     232,    93,   115,   230,   115,   115,   230,   115,   115,     1,\n     115,   115,    13,   152,     1,    95,     0,   143,    13,   135,\n       0,   115,   115,   115,    96,   115,   115,   115,   149,   149,\n     180,   230,   115,   198,   198,   115,   198,   198,   198,    13,\n     230,    13,    20,   185,   191,     0,    92,   119,    95,   186,\n     115,   115,   115,    13,   186,   188,     0,     1,    91,   118,\n     206,   207,    94,   176,   207,   210,   212,   215,   216,    13,\n     118,   204,   207,   115,   115,   115,   115,   115,   209,     0,\n     115,   115,     1,   123,   132,   150,   154,   163,   172,   222,\n     223,   230,   116,   232,   232,   232,     1,   226,   227,   228,\n     115,   232,   230,   233,   232,    13,    42,   115,   140,   230,\n     115,    95,   115,   136,   231,   179,    44,    94,   156,   157,\n     158,   159,   160,   161,    96,    96,   179,    13,    13,    14,\n     175,   118,   118,   186,   118,   118,   118,   232,   115,    13,\n     191,     7,     8,     9,    10,    11,   102,   119,   195,   115,\n     100,   230,   118,   118,   115,   210,   118,     6,   114,   213,\n     214,   115,    13,   118,   118,   170,   199,   230,   220,   144,\n      25,   220,    26,   225,    38,   218,   119,   118,     0,    90,\n     117,     1,   206,   118,   115,   115,    42,   233,   231,   115,\n     115,   144,   147,   115,     1,   115,   155,    45,    46,    45,\n      46,   147,   147,    96,   115,   115,    70,   115,   119,   195,\n     115,   182,   115,   232,   207,   216,    97,   101,   212,   215,\n      20,   100,   118,   115,   115,   117,   233,    93,     1,   220,\n      93,   226,   220,   232,    39,   203,    17,   137,   138,   115,\n     231,   120,   120,   226,   115,   160,   230,    13,   156,    96,\n     115,   115,   115,   115,   115,   177,   147,   118,   118,   115,\n     118,   115,    12,    13,   196,   184,   118,   214,   114,   114,\n     115,   115,   225,   230,   115,     1,   115,   118,   139,   126,\n     127,   232,   115,   118,   147,   160,   160,   160,   160,   231,\n     199,   177,   118,   196,   115,   118,   226,   233,   232,   206,\n     115,   117,   124,   128,   130,   118,    17,   115,   115,   166,\n     167,   117,   199,   115,    13,   192,   193,     1,   129,   132,\n     134,   150,   151,   153,   164,   173,   181,   222,   223,   224,\n     116,   115,   115,   126,   117,     1,   168,   171,   117,   193,\n     115,   119,   230,   144,   225,     1,   206,   117,   233,   115,\n     226,   119,   233,   232,   203,   231,   115,   225,   118,   118,\n     231,   115,   115\n};\n\n  /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */\nstatic const yytype_uint8 yyr1[] =\n{\n       0,   105,   106,   106,   106,   106,   106,   106,   106,   106,\n     107,   108,   109,   110,   111,   112,   113,   114,   114,   115,\n     115,   116,   116,   116,   117,   117,   118,   118,   119,   119,\n     120,   120,   121,   121,   121,   122,   122,   123,   123,   123,\n     123,   123,   123,   123,   124,   125,   125,   126,   126,   127,\n     127,   128,   129,   129,   129,   129,   129,   129,   130,   130,\n     131,   132,   133,   133,   134,   135,   135,   136,   136,   137,\n     137,   138,   138,   139,   139,   140,   140,   141,   141,   141,\n     142,   142,   143,   143,   143,   144,   144,   145,   145,   145,\n     146,   146,   147,   148,   149,   150,   151,   152,   153,   154,\n     155,   156,   156,   156,   156,   157,   158,   158,   159,   159,\n     160,   160,   160,   161,   161,   162,   163,   164,   165,   165,\n     166,   166,   167,   167,   167,   168,   169,   169,   170,   170,\n     171,   172,   173,   174,   174,   174,   174,   175,   175,   176,\n     176,   177,   178,   179,   180,   181,   182,   183,   183,   184,\n     184,   184,   184,   185,   185,   185,   186,   186,   186,   186,\n     186,   186,   187,   187,   188,   188,   189,   189,   189,   189,\n     189,   190,   191,   192,   193,   193,   194,   194,   194,   194,\n     194,   195,   195,   195,   195,   195,   195,   196,   196,   197,\n     197,   197,   197,   197,   197,   197,   197,   197,   197,   197,\n     198,   199,   199,   199,   199,   200,   200,   201,   201,   201,\n     201,   201,   202,   203,   203,   204,   204,   205,   205,   205,\n     206,   206,   206,   207,   208,   208,   208,   209,   209,   209,\n     209,   209,   209,   209,   209,   209,   209,   209,   209,   209,\n     209,   210,   210,   210,   210,   210,   210,   210,   210,   210,\n     210,   210,   210,   210,   210,   210,   210,   210,   210,   210,\n     210,   210,   210,   210,   210,   210,   210,   210,   210,   210,\n     210,   211,   211,   211,   212,   212,   213,   213,   213,   213,\n     214,   214,   215,   215,   216,   216,   216,   216,   217,   217,\n     218,   219,   220,   221,   221,   222,   222,   222,   222,   222,\n     223,   223,   223,   223,   224,   224,   224,   225,   226,   227,\n     228,   229,   229,   230,   231,   232,   232,   232,   232,   232,\n     233,   233,   233,   233\n};\n\n  /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */\nstatic const yytype_uint8 yyr2[] =\n{\n       0,     2,     3,     1,     1,     1,     1,     1,     1,     1,\n       5,     5,     4,     4,     4,     5,     4,     1,     2,     0,\n       1,     0,     2,     2,     1,     1,     1,     1,     1,     1,\n       1,     1,     0,     5,     2,     0,     3,     1,     1,     1,\n       1,     1,     1,     1,     0,     2,     2,     1,     2,     0,\n       3,     2,     1,     1,     1,     1,     1,     1,     2,     2,\n       0,     3,     6,     6,     6,     0,     2,     1,     1,     0,\n       3,     6,     4,     1,     5,     1,     5,     0,     2,     2,\n       2,     3,     1,     4,     3,     0,     1,     1,     2,     1,\n       4,     5,     0,     0,     1,     3,     8,     1,    10,     0,\n       0,     1,     1,     1,     1,     3,     4,     4,     4,     4,\n       5,     1,     6,    10,    10,     0,     3,     9,     1,     1,\n       1,     2,     0,     4,     5,     5,     2,     5,     2,     1,\n       2,     0,     8,     2,     2,     2,     4,     1,     0,     1,\n       1,     1,     0,     0,     0,     9,     0,     1,     6,     1,\n       2,     3,     3,     1,     2,     2,     1,     2,     1,     2,\n       3,     2,     1,     1,     1,     2,     1,     1,     1,     1,\n       1,     2,     2,     2,     1,     0,     4,     9,     5,    10,\n       3,     1,     1,     1,     1,     1,     1,     1,     1,     3,\n       4,     4,     6,     7,     6,     4,     6,     4,     4,     4,\n       3,     0,     1,     2,     1,     3,     4,     6,     8,     6,\n       4,     3,     3,     2,     0,     2,     3,     3,     4,     4,\n       1,     3,     2,     3,     2,     2,     2,     2,     3,     2,\n       2,     2,     3,     2,     2,     2,     2,     2,     2,     2,\n       2,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     4,     3,     4,     1,     2,     3,     3,     3,     3,\n       0,     1,     5,     4,     1,     3,     3,     1,     5,     4,\n       1,     3,     3,     2,     2,     2,     3,     5,     2,     3,\n       5,     3,     3,     3,     4,     2,     2,     0,     3,     3,\n       3,     1,     1,     0,     0,     0,     2,     2,     2,     2,\n       0,     2,     2,     2\n};\n\n\n#define yyerrok         (yyerrstatus = 0)\n#define yyclearin       (yychar = YYEMPTY)\n#define YYEMPTY         (-2)\n#define YYEOF           0\n\n#define YYACCEPT        goto yyacceptlab\n#define YYABORT         goto yyabortlab\n#define YYERROR         goto yyerrorlab\n\n\n#define YYRECOVERING()  (!!yyerrstatus)\n\n#define YYBACKUP(Token, Value)                                  \\\ndo                                                              \\\n  if (yychar == YYEMPTY)                                        \\\n    {                                                           \\\n      yychar = (Token);                                         \\\n      yylval = (Value);                                         \\\n      YYPOPSTACK (yylen);                                       \\\n      yystate = *yyssp;                                         \\\n      goto yybackup;                                            \\\n    }                                                           \\\n  else                                                          \\\n    {                                                           \\\n      yyerror (&yylloc, scanner, parser, YY_(\"syntax error: cannot back up\")); \\\n      YYERROR;                                                  \\\n    }                                                           \\\nwhile (0)\n\n/* Error token number */\n#define YYTERROR        1\n#define YYERRCODE       256\n\n\n/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].\n   If N is 0, then set CURRENT to the empty location which ends\n   the previous symbol: RHS[0] (always defined).  */\n\n#ifndef YYLLOC_DEFAULT\n# define YYLLOC_DEFAULT(Current, Rhs, N)                                \\\n    do                                                                  \\\n      if (N)                                                            \\\n        {                                                               \\\n          (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \\\n          (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \\\n          (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \\\n          (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \\\n        }                                                               \\\n      else                                                              \\\n        {                                                               \\\n          (Current).first_line   = (Current).last_line   =              \\\n            YYRHSLOC (Rhs, 0).last_line;                                \\\n          (Current).first_column = (Current).last_column =              \\\n            YYRHSLOC (Rhs, 0).last_column;                              \\\n        }                                                               \\\n    while (0)\n#endif\n\n#define YYRHSLOC(Rhs, K) ((Rhs)[K])\n\n\n/* Enable debugging if requested.  */\n#if KATANADEBUG\n\n# ifndef YYFPRINTF\n#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */\n#  define YYFPRINTF fprintf\n# endif\n\n# define YYDPRINTF(Args)                        \\\ndo {                                            \\\n  if (yydebug)                                  \\\n    YYFPRINTF Args;                             \\\n} while (0)\n\n\n/* YY_LOCATION_PRINT -- Print the location on the stream.\n   This macro was not mandated originally: define only if we know\n   we won't break user code: when these are the locations we know.  */\n\n#ifndef YY_LOCATION_PRINT\n# if defined KATANALTYPE_IS_TRIVIAL && KATANALTYPE_IS_TRIVIAL\n\n/* Print *YYLOCP on YYO.  Private, do not rely on its existence. */\n\nYY_ATTRIBUTE_UNUSED\nstatic unsigned\nyy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)\n{\n  unsigned res = 0;\n  int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0;\n  if (0 <= yylocp->first_line)\n    {\n      res += YYFPRINTF (yyo, \"%d\", yylocp->first_line);\n      if (0 <= yylocp->first_column)\n        res += YYFPRINTF (yyo, \".%d\", yylocp->first_column);\n    }\n  if (0 <= yylocp->last_line)\n    {\n      if (yylocp->first_line < yylocp->last_line)\n        {\n          res += YYFPRINTF (yyo, \"-%d\", yylocp->last_line);\n          if (0 <= end_col)\n            res += YYFPRINTF (yyo, \".%d\", end_col);\n        }\n      else if (0 <= end_col && yylocp->first_column < end_col)\n        res += YYFPRINTF (yyo, \"-%d\", end_col);\n    }\n  return res;\n }\n\n#  define YY_LOCATION_PRINT(File, Loc)          \\\n  yy_location_print_ (File, &(Loc))\n\n# else\n#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)\n# endif\n#endif\n\n\n# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                    \\\ndo {                                                                      \\\n  if (yydebug)                                                            \\\n    {                                                                     \\\n      YYFPRINTF (stderr, \"%s \", Title);                                   \\\n      yy_symbol_print (stderr,                                            \\\n                  Type, Value, Location, scanner, parser); \\\n      YYFPRINTF (stderr, \"\\n\");                                           \\\n    }                                                                     \\\n} while (0)\n\n\n/*----------------------------------------.\n| Print this symbol's value on YYOUTPUT.  |\n`----------------------------------------*/\n\nstatic void\nyy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, void* scanner, struct KatanaInternalParser * parser)\n{\n  FILE *yyo = yyoutput;\n  YYUSE (yyo);\n  YYUSE (yylocationp);\n  YYUSE (scanner);\n  YYUSE (parser);\n  if (!yyvaluep)\n    return;\n# ifdef YYPRINT\n  if (yytype < YYNTOKENS)\n    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);\n# endif\n  YYUSE (yytype);\n}\n\n\n/*--------------------------------.\n| Print this symbol on YYOUTPUT.  |\n`--------------------------------*/\n\nstatic void\nyy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, void* scanner, struct KatanaInternalParser * parser)\n{\n  YYFPRINTF (yyoutput, \"%s %s (\",\n             yytype < YYNTOKENS ? \"token\" : \"nterm\", yytname[yytype]);\n\n  YY_LOCATION_PRINT (yyoutput, *yylocationp);\n  YYFPRINTF (yyoutput, \": \");\n  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, scanner, parser);\n  YYFPRINTF (yyoutput, \")\");\n}\n\n/*------------------------------------------------------------------.\n| yy_stack_print -- Print the state stack from its BOTTOM up to its |\n| TOP (included).                                                   |\n`------------------------------------------------------------------*/\n\nstatic void\nyy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)\n{\n  YYFPRINTF (stderr, \"Stack now\");\n  for (; yybottom <= yytop; yybottom++)\n    {\n      int yybot = *yybottom;\n      YYFPRINTF (stderr, \" %d\", yybot);\n    }\n  YYFPRINTF (stderr, \"\\n\");\n}\n\n# define YY_STACK_PRINT(Bottom, Top)                            \\\ndo {                                                            \\\n  if (yydebug)                                                  \\\n    yy_stack_print ((Bottom), (Top));                           \\\n} while (0)\n\n\n/*------------------------------------------------.\n| Report that the YYRULE is going to be reduced.  |\n`------------------------------------------------*/\n\nstatic void\nyy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, void* scanner, struct KatanaInternalParser * parser)\n{\n  unsigned long int yylno = yyrline[yyrule];\n  int yynrhs = yyr2[yyrule];\n  int yyi;\n  YYFPRINTF (stderr, \"Reducing stack by rule %d (line %lu):\\n\",\n             yyrule - 1, yylno);\n  /* The symbols being reduced.  */\n  for (yyi = 0; yyi < yynrhs; yyi++)\n    {\n      YYFPRINTF (stderr, \"   $%d = \", yyi + 1);\n      yy_symbol_print (stderr,\n                       yystos[yyssp[yyi + 1 - yynrhs]],\n                       &(yyvsp[(yyi + 1) - (yynrhs)])\n                       , &(yylsp[(yyi + 1) - (yynrhs)])                       , scanner, parser);\n      YYFPRINTF (stderr, \"\\n\");\n    }\n}\n\n# define YY_REDUCE_PRINT(Rule)          \\\ndo {                                    \\\n  if (yydebug)                          \\\n    yy_reduce_print (yyssp, yyvsp, yylsp, Rule, scanner, parser); \\\n} while (0)\n\n/* Nonzero means print parse trace.  It is left uninitialized so that\n   multiple parsers can coexist.  */\nint yydebug;\n#else /* !KATANADEBUG */\n# define YYDPRINTF(Args)\n# define YY_SYMBOL_PRINT(Title, Type, Value, Location)\n# define YY_STACK_PRINT(Bottom, Top)\n# define YY_REDUCE_PRINT(Rule)\n#endif /* !KATANADEBUG */\n\n\n/* YYINITDEPTH -- initial size of the parser's stacks.  */\n#ifndef YYINITDEPTH\n# define YYINITDEPTH 200\n#endif\n\n/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only\n   if the built-in stack extension method is used).\n\n   Do not make this value too large; the results are undefined if\n   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)\n   evaluated with infinite-precision integer arithmetic.  */\n\n#ifndef YYMAXDEPTH\n# define YYMAXDEPTH 10000\n#endif\n\n\n#if YYERROR_VERBOSE\n\n# ifndef yystrlen\n#  if defined __GLIBC__ && defined _STRING_H\n#   define yystrlen strlen\n#  else\n/* Return the length of YYSTR.  */\nstatic YYSIZE_T\nyystrlen (const char *yystr)\n{\n  YYSIZE_T yylen;\n  for (yylen = 0; yystr[yylen]; yylen++)\n    continue;\n  return yylen;\n}\n#  endif\n# endif\n\n# ifndef yystpcpy\n#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE\n#   define yystpcpy stpcpy\n#  else\n/* Copy YYSRC to YYDEST, returning the address of the terminating '\\0' in\n   YYDEST.  */\nstatic char *\nyystpcpy (char *yydest, const char *yysrc)\n{\n  char *yyd = yydest;\n  const char *yys = yysrc;\n\n  while ((*yyd++ = *yys++) != '\\0')\n    continue;\n\n  return yyd - 1;\n}\n#  endif\n# endif\n\n# ifndef yytnamerr\n/* Copy to YYRES the contents of YYSTR after stripping away unnecessary\n   quotes and backslashes, so that it's suitable for yyerror.  The\n   heuristic is that double-quoting is unnecessary unless the string\n   contains an apostrophe, a comma, or backslash (other than\n   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is\n   null, do not copy; instead, return the length of what the result\n   would have been.  */\nstatic YYSIZE_T\nyytnamerr (char *yyres, const char *yystr)\n{\n  if (*yystr == '\"')\n    {\n      YYSIZE_T yyn = 0;\n      char const *yyp = yystr;\n\n      for (;;)\n        switch (*++yyp)\n          {\n          case '\\'':\n          case ',':\n            goto do_not_strip_quotes;\n\n          case '\\\\':\n            if (*++yyp != '\\\\')\n              goto do_not_strip_quotes;\n            /* Fall through.  */\n          default:\n            if (yyres)\n              yyres[yyn] = *yyp;\n            yyn++;\n            break;\n\n          case '\"':\n            if (yyres)\n              yyres[yyn] = '\\0';\n            return yyn;\n          }\n    do_not_strip_quotes: ;\n    }\n\n  if (! yyres)\n    return yystrlen (yystr);\n\n  return yystpcpy (yyres, yystr) - yyres;\n}\n# endif\n\n/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message\n   about the unexpected token YYTOKEN for the state stack whose top is\n   YYSSP.\n\n   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is\n   not large enough to hold the message.  In that case, also set\n   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the\n   required number of bytes is too large to store.  */\nstatic int\nyysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,\n                yytype_int16 *yyssp, int yytoken)\n{\n  YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);\n  YYSIZE_T yysize = yysize0;\n  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };\n  /* Internationalized format string. */\n  const char *yyformat = YY_NULLPTR;\n  /* Arguments of yyformat. */\n  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];\n  /* Number of reported tokens (one for the \"unexpected\", one per\n     \"expected\"). */\n  int yycount = 0;\n\n  /* There are many possibilities here to consider:\n     - If this state is a consistent state with a default action, then\n       the only way this function was invoked is if the default action\n       is an error action.  In that case, don't check for expected\n       tokens because there are none.\n     - The only way there can be no lookahead present (in yychar) is if\n       this state is a consistent state with a default action.  Thus,\n       detecting the absence of a lookahead is sufficient to determine\n       that there is no unexpected or expected token to report.  In that\n       case, just report a simple \"syntax error\".\n     - Don't assume there isn't a lookahead just because this state is a\n       consistent state with a default action.  There might have been a\n       previous inconsistent state, consistent state with a non-default\n       action, or user semantic action that manipulated yychar.\n     - Of course, the expected token list depends on states to have\n       correct lookahead information, and it depends on the parser not\n       to perform extra reductions after fetching a lookahead from the\n       scanner and before detecting a syntax error.  Thus, state merging\n       (from LALR or IELR) and default reductions corrupt the expected\n       token list.  However, the list is correct for canonical LR with\n       one exception: it will still contain any token that will not be\n       accepted due to an error action in a later state.\n  */\n  if (yytoken != YYEMPTY)\n    {\n      int yyn = yypact[*yyssp];\n      yyarg[yycount++] = yytname[yytoken];\n      if (!yypact_value_is_default (yyn))\n        {\n          /* Start YYX at -YYN if negative to avoid negative indexes in\n             YYCHECK.  In other words, skip the first -YYN actions for\n             this state because they are default actions.  */\n          int yyxbegin = yyn < 0 ? -yyn : 0;\n          /* Stay within bounds of both yycheck and yytname.  */\n          int yychecklim = YYLAST - yyn + 1;\n          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;\n          int yyx;\n\n          for (yyx = yyxbegin; yyx < yyxend; ++yyx)\n            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR\n                && !yytable_value_is_error (yytable[yyx + yyn]))\n              {\n                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)\n                  {\n                    yycount = 1;\n                    yysize = yysize0;\n                    break;\n                  }\n                yyarg[yycount++] = yytname[yyx];\n                {\n                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);\n                  if (! (yysize <= yysize1\n                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))\n                    return 2;\n                  yysize = yysize1;\n                }\n              }\n        }\n    }\n\n  switch (yycount)\n    {\n# define YYCASE_(N, S)                      \\\n      case N:                               \\\n        yyformat = S;                       \\\n      break\n      YYCASE_(0, YY_(\"syntax error\"));\n      YYCASE_(1, YY_(\"syntax error, unexpected %s\"));\n      YYCASE_(2, YY_(\"syntax error, unexpected %s, expecting %s\"));\n      YYCASE_(3, YY_(\"syntax error, unexpected %s, expecting %s or %s\"));\n      YYCASE_(4, YY_(\"syntax error, unexpected %s, expecting %s or %s or %s\"));\n      YYCASE_(5, YY_(\"syntax error, unexpected %s, expecting %s or %s or %s or %s\"));\n# undef YYCASE_\n    }\n\n  {\n    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);\n    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))\n      return 2;\n    yysize = yysize1;\n  }\n\n  if (*yymsg_alloc < yysize)\n    {\n      *yymsg_alloc = 2 * yysize;\n      if (! (yysize <= *yymsg_alloc\n             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))\n        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;\n      return 1;\n    }\n\n  /* Avoid sprintf, as that infringes on the user's name space.\n     Don't have undefined behavior even if the translation\n     produced a string with the wrong number of \"%s\"s.  */\n  {\n    char *yyp = *yymsg;\n    int yyi = 0;\n    while ((*yyp = *yyformat) != '\\0')\n      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)\n        {\n          yyp += yytnamerr (yyp, yyarg[yyi++]);\n          yyformat += 2;\n        }\n      else\n        {\n          yyp++;\n          yyformat++;\n        }\n  }\n  return 0;\n}\n#endif /* YYERROR_VERBOSE */\n\n/*-----------------------------------------------.\n| Release the memory associated to this symbol.  |\n`-----------------------------------------------*/\n\nstatic void\nyydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, void* scanner, struct KatanaInternalParser * parser)\n{\n  YYUSE (yyvaluep);\n  YYUSE (yylocationp);\n  YYUSE (scanner);\n  YYUSE (parser);\n  if (!yymsg)\n    yymsg = \"Deleting\";\n  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);\n\n  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN\n  YYUSE (yytype);\n  YY_IGNORE_MAYBE_UNINITIALIZED_END\n}\n\n\n\n\n/*----------.\n| yyparse.  |\n`----------*/\n\nint\nyyparse (void* scanner, struct KatanaInternalParser * parser)\n{\n/* The lookahead symbol.  */\nint yychar;\n\n\n/* The semantic value of the lookahead symbol.  */\n/* Default value used for initialization, for pacifying older GCCs\n   or non-GCC compilers.  */\nYY_INITIAL_VALUE (static YYSTYPE yyval_default;)\nYYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);\n\n/* Location data for the lookahead symbol.  */\nstatic YYLTYPE yyloc_default\n# if defined KATANALTYPE_IS_TRIVIAL && KATANALTYPE_IS_TRIVIAL\n  = { 1, 1, 1, 1 }\n# endif\n;\nYYLTYPE yylloc = yyloc_default;\n\n    /* Number of syntax errors so far.  */\n    int yynerrs;\n\n    int yystate;\n    /* Number of tokens to shift before error messages enabled.  */\n    int yyerrstatus;\n\n    /* The stacks and their tools:\n       'yyss': related to states.\n       'yyvs': related to semantic values.\n       'yyls': related to locations.\n\n       Refer to the stacks through separate pointers, to allow yyoverflow\n       to reallocate them elsewhere.  */\n\n    /* The state stack.  */\n    yytype_int16 yyssa[YYINITDEPTH];\n    yytype_int16 *yyss;\n    yytype_int16 *yyssp;\n\n    /* The semantic value stack.  */\n    YYSTYPE yyvsa[YYINITDEPTH];\n    YYSTYPE *yyvs;\n    YYSTYPE *yyvsp;\n\n    /* The location stack.  */\n    YYLTYPE yylsa[YYINITDEPTH];\n    YYLTYPE *yyls;\n    YYLTYPE *yylsp;\n\n    /* The locations where the error started and ended.  */\n    YYLTYPE yyerror_range[3];\n\n    YYSIZE_T yystacksize;\n\n  int yyn;\n  int yyresult;\n  /* Lookahead token as an internal (translated) token number.  */\n  int yytoken = 0;\n  /* The variables used to return semantic value and location from the\n     action routines.  */\n  YYSTYPE yyval;\n  YYLTYPE yyloc;\n\n#if YYERROR_VERBOSE\n  /* Buffer for error messages, and its allocated size.  */\n  char yymsgbuf[128];\n  char *yymsg = yymsgbuf;\n  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;\n#endif\n\n#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))\n\n  /* The number of symbols on the RHS of the reduced rule.\n     Keep to zero when no symbol should be popped.  */\n  int yylen = 0;\n\n  yyssp = yyss = yyssa;\n  yyvsp = yyvs = yyvsa;\n  yylsp = yyls = yylsa;\n  yystacksize = YYINITDEPTH;\n\n  YYDPRINTF ((stderr, \"Starting parse\\n\"));\n\n  yystate = 0;\n  yyerrstatus = 0;\n  yynerrs = 0;\n  yychar = YYEMPTY; /* Cause a token to be read.  */\n  yylsp[0] = yylloc;\n  goto yysetstate;\n\n/*------------------------------------------------------------.\n| yynewstate -- Push a new state, which is found in yystate.  |\n`------------------------------------------------------------*/\n yynewstate:\n  /* In all cases, when you get here, the value and location stacks\n     have just been pushed.  So pushing a state here evens the stacks.  */\n  yyssp++;\n\n yysetstate:\n  *yyssp = yystate;\n\n  if (yyss + yystacksize - 1 <= yyssp)\n    {\n      /* Get the current used size of the three stacks, in elements.  */\n      YYSIZE_T yysize = yyssp - yyss + 1;\n\n#ifdef yyoverflow\n      {\n        /* Give user a chance to reallocate the stack.  Use copies of\n           these so that the &'s don't force the real ones into\n           memory.  */\n        YYSTYPE *yyvs1 = yyvs;\n        yytype_int16 *yyss1 = yyss;\n        YYLTYPE *yyls1 = yyls;\n\n        /* Each stack pointer address is followed by the size of the\n           data in use in that stack, in bytes.  This used to be a\n           conditional around just the two extra args, but that might\n           be undefined if yyoverflow is a macro.  */\n        yyoverflow (YY_(\"memory exhausted\"),\n                    &yyss1, yysize * sizeof (*yyssp),\n                    &yyvs1, yysize * sizeof (*yyvsp),\n                    &yyls1, yysize * sizeof (*yylsp),\n                    &yystacksize);\n\n        yyls = yyls1;\n        yyss = yyss1;\n        yyvs = yyvs1;\n      }\n#else /* no yyoverflow */\n# ifndef YYSTACK_RELOCATE\n      goto yyexhaustedlab;\n# else\n      /* Extend the stack our own way.  */\n      if (YYMAXDEPTH <= yystacksize)\n        goto yyexhaustedlab;\n      yystacksize *= 2;\n      if (YYMAXDEPTH < yystacksize)\n        yystacksize = YYMAXDEPTH;\n\n      {\n        yytype_int16 *yyss1 = yyss;\n        union yyalloc *yyptr =\n          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));\n        if (! yyptr)\n          goto yyexhaustedlab;\n        YYSTACK_RELOCATE (yyss_alloc, yyss);\n        YYSTACK_RELOCATE (yyvs_alloc, yyvs);\n        YYSTACK_RELOCATE (yyls_alloc, yyls);\n#  undef YYSTACK_RELOCATE\n        if (yyss1 != yyssa)\n          YYSTACK_FREE (yyss1);\n      }\n# endif\n#endif /* no yyoverflow */\n\n      yyssp = yyss + yysize - 1;\n      yyvsp = yyvs + yysize - 1;\n      yylsp = yyls + yysize - 1;\n\n      YYDPRINTF ((stderr, \"Stack size increased to %lu\\n\",\n                  (unsigned long int) yystacksize));\n\n      if (yyss + yystacksize - 1 <= yyssp)\n        YYABORT;\n    }\n\n  YYDPRINTF ((stderr, \"Entering state %d\\n\", yystate));\n\n  if (yystate == YYFINAL)\n    YYACCEPT;\n\n  goto yybackup;\n\n/*-----------.\n| yybackup.  |\n`-----------*/\nyybackup:\n\n  /* Do appropriate processing given the current state.  Read a\n     lookahead token if we need one and don't already have one.  */\n\n  /* First try to decide what to do without reference to lookahead token.  */\n  yyn = yypact[yystate];\n  if (yypact_value_is_default (yyn))\n    goto yydefault;\n\n  /* Not known => get a lookahead token if don't already have one.  */\n\n  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */\n  if (yychar == YYEMPTY)\n    {\n      YYDPRINTF ((stderr, \"Reading a token: \"));\n      yychar = yylex (&yylval, &yylloc, scanner, parser);\n    }\n\n  if (yychar <= YYEOF)\n    {\n      yychar = yytoken = YYEOF;\n      YYDPRINTF ((stderr, \"Now at end of input.\\n\"));\n    }\n  else\n    {\n      yytoken = YYTRANSLATE (yychar);\n      YY_SYMBOL_PRINT (\"Next token is\", yytoken, &yylval, &yylloc);\n    }\n\n  /* If the proper action on seeing token YYTOKEN is to reduce or to\n     detect an error, take that action.  */\n  yyn += yytoken;\n  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)\n    goto yydefault;\n  yyn = yytable[yyn];\n  if (yyn <= 0)\n    {\n      if (yytable_value_is_error (yyn))\n        goto yyerrlab;\n      yyn = -yyn;\n      goto yyreduce;\n    }\n\n  /* Count tokens shifted since error; after three, turn off error\n     status.  */\n  if (yyerrstatus)\n    yyerrstatus--;\n\n  /* Shift the lookahead token.  */\n  YY_SYMBOL_PRINT (\"Shifting\", yytoken, &yylval, &yylloc);\n\n  /* Discard the shifted token.  */\n  yychar = YYEMPTY;\n\n  yystate = yyn;\n  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN\n  *++yyvsp = yylval;\n  YY_IGNORE_MAYBE_UNINITIALIZED_END\n  *++yylsp = yylloc;\n  goto yynewstate;\n\n\n/*-----------------------------------------------------------.\n| yydefault -- do the default action for the current state.  |\n`-----------------------------------------------------------*/\nyydefault:\n  yyn = yydefact[yystate];\n  if (yyn == 0)\n    goto yyerrlab;\n  goto yyreduce;\n\n\n/*-----------------------------.\n| yyreduce -- Do a reduction.  |\n`-----------------------------*/\nyyreduce:\n  /* yyn is the number of a rule to reduce with.  */\n  yylen = yyr2[yyn];\n\n  /* If YYLEN is nonzero, implement the default value of the action:\n     '$$ = $1'.\n\n     Otherwise, the following line sets YYVAL to garbage.\n     This behavior is undocumented and Bison\n     users should not rely upon it.  Assigning to YYVAL\n     unconditionally makes the parser a bit smaller, and it avoids a\n     GCC warning that YYVAL may be used uninitialized.  */\n  yyval = yyvsp[1-yylen];\n\n  /* Default location.  */\n  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);\n  YY_REDUCE_PRINT (yyn);\n  switch (yyn)\n    {\n        case 10:\n\n    {\n        katana_parse_internal_rule(parser, (yyvsp[-2].rule));\n    }\n\n    break;\n\n  case 11:\n\n    {\n        katana_parse_internal_keyframe_rule(parser, (yyvsp[-2].keyframe));\n    }\n\n    break;\n\n  case 12:\n\n    {\n        katana_parse_internal_keyframe_key_list(parser, (yyvsp[-1].valueList));\n    }\n\n    break;\n\n  case 13:\n\n    {\n        /* can be empty */\n        katana_parse_internal_declaration_list(parser, (yyvsp[-1].boolean));\n    }\n\n    break;\n\n  case 14:\n\n    {\n        katana_parse_internal_value(parser, (yyvsp[-1].valueList));\n    }\n\n    break;\n\n  case 15:\n\n    {\n        katana_parse_internal_media_list(parser, (yyvsp[-1].mediaList));\n    }\n\n    break;\n\n  case 16:\n\n    {\n        katana_parse_internal_selector(parser, (yyvsp[-1].selectorList));\n    }\n\n    break;\n\n  case 33:\n\n    {\n        /* create a charset rule and push to stylesheet rules */\n        katana_set_charset(parser, &(yyvsp[-2].string));\n    }\n\n    break;\n\n  case 36:\n\n    {\n        if ((yyvsp[-1].rule))\n            katana_add_rule(parser, (yyvsp[-1].rule));\n    }\n\n    break;\n\n  case 44:\n\n    {\n        katana_start_rule(parser);\n    }\n\n    break;\n\n  case 45:\n\n    {\n        (yyval.rule) = (yyvsp[0].rule);\n        // parser->m_hadSyntacticallyValidCSSRule = true;\n        katana_end_rule(parser, !!(yyval.rule));\n    }\n\n    break;\n\n  case 46:\n\n    {\n        (yyval.rule) = 0;\n        katana_end_rule(parser, false);\n    }\n\n    break;\n\n  case 49:\n\n    { (yyval.ruleList) = 0; }\n\n    break;\n\n  case 50:\n\n    {\n      (yyval.ruleList) = katana_rule_list_add(parser, (yyvsp[-1].rule), (yyvsp[-2].ruleList));\n    }\n\n    break;\n\n  case 51:\n\n    {\n        katana_end_rule(parser, false);\n    }\n\n    break;\n\n  case 58:\n\n    {\n        (yyval.rule) = (yyvsp[0].rule);\n        katana_end_rule(parser, !!(yyval.rule));\n    }\n\n    break;\n\n  case 59:\n\n    {\n        (yyval.rule) = 0;\n        katana_end_rule(parser, false);\n    }\n\n    break;\n\n  case 60:\n\n    {\n        katana_start_rule_header(parser, KatanaRuleImport);\n    }\n\n    break;\n\n  case 61:\n\n    {\n        katana_end_rule_header(parser);\n        katana_start_rule_body(parser);\n    }\n\n    break;\n\n  case 62:\n\n    {\n        (yyval.rule) = katana_new_import_rule(parser, &(yyvsp[-4].string), (yyvsp[-1].mediaList));\n    }\n\n    break;\n\n  case 63:\n\n    {\n        (yyval.rule) = 0;\n    }\n\n    break;\n\n  case 64:\n\n    {\n        katana_add_namespace(parser, &(yyvsp[-3].string), &(yyvsp[-2].string));\n        (yyval.rule) = 0;\n    }\n\n    break;\n\n  case 65:\n\n    { /*$$.clear()*/ }\n\n    break;\n\n  case 69:\n\n    {\n        (yyval.valueList) = 0;\n    }\n\n    break;\n\n  case 70:\n\n    {\n        (yyval.valueList) = (yyvsp[0].valueList);\n    }\n\n    break;\n\n  case 71:\n\n    {\n        katana_string_to_lowercase(parser, &(yyvsp[-3].string));\n        (yyval.mediaQueryExp) = katana_new_media_query_exp(parser, &(yyvsp[-3].string), (yyvsp[-1].valueList));\n        if (!(yyval.mediaQueryExp))\n            YYERROR;\n    }\n\n    break;\n\n  case 72:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 73:\n\n    {\n        (yyval.mediaQueryExpList) = katana_new_media_query_exp_list(parser);\n        katana_media_query_exp_list_add(parser, (yyvsp[0].mediaQueryExp), (yyval.mediaQueryExpList));   \n    }\n\n    break;\n\n  case 74:\n\n    {\n        (yyval.mediaQueryExpList) = (yyvsp[-4].mediaQueryExpList);\n        katana_media_query_exp_list_add(parser, (yyvsp[0].mediaQueryExp), (yyval.mediaQueryExpList));   \n    }\n\n    break;\n\n  case 75:\n\n    {\n        (yyval.mediaQueryExpList) = katana_new_media_query_exp_list(parser);\n    }\n\n    break;\n\n  case 76:\n\n    {\n        (yyval.mediaQueryExpList) = (yyvsp[-1].mediaQueryExpList);\n    }\n\n    break;\n\n  case 77:\n\n    {\n        (yyval.mediaQueryRestrictor) = KatanaMediaQueryRestrictorNone;\n    }\n\n    break;\n\n  case 78:\n\n    {\n        (yyval.mediaQueryRestrictor) = KatanaMediaQueryRestrictorOnly;\n    }\n\n    break;\n\n  case 79:\n\n    {\n        (yyval.mediaQueryRestrictor) = KatanaMediaQueryRestrictorNot;\n    }\n\n    break;\n\n  case 80:\n\n    {\n        (yyval.mediaQuery) = katana_new_media_query(parser, KatanaMediaQueryRestrictorNone, NULL, (yyvsp[-1].mediaQueryExpList));\n    }\n\n    break;\n\n  case 81:\n\n    {\n        katana_string_to_lowercase(parser, &(yyvsp[-1].string));\n        (yyval.mediaQuery) = katana_new_media_query(parser, (yyvsp[-2].mediaQueryRestrictor), &(yyvsp[-1].string), (yyvsp[0].mediaQueryExpList));\n    }\n\n    break;\n\n  case 83:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-1].location), \"parser->lastLocationLabel(), InvalidMediaQueryCSSError\");\n        (yyval.mediaQuery) = katana_new_media_query(parser, KatanaMediaQueryRestrictorNot, NULL, NULL);\n    }\n\n    break;\n\n  case 84:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-1].location), \"parser->lastLocationLabel(), InvalidMediaQueryCSSError\");\n        (yyval.mediaQuery) = katana_new_media_query(parser, KatanaMediaQueryRestrictorNot, NULL, NULL);\n    }\n\n    break;\n\n  case 85:\n\n    {\n        (yyval.mediaList) = katana_new_media_list(parser);\n    }\n\n    break;\n\n  case 87:\n\n    {\n        (yyval.mediaList) = katana_new_media_list(parser);\n        katana_media_list_add(parser, (yyvsp[0].mediaQuery), (yyval.mediaList));\n    }\n\n    break;\n\n  case 88:\n\n    {\n        (yyval.mediaList) = (yyvsp[-1].mediaList);\n        katana_media_list_add(parser, (yyvsp[0].mediaQuery), (yyval.mediaList));\n    }\n\n    break;\n\n  case 89:\n\n    {\n        (yyval.mediaList) = (yyvsp[0].mediaList);\n        // $$->addMediaQuery(parser->sinkFloatingMediaQuery(parser->createFloatingNotAllQuery()));\n        katana_parser_log(parser, \"createFloatingNotAllQuery\");\n    }\n\n    break;\n\n  case 90:\n\n    {\n        (yyval.mediaList) = katana_new_media_list(parser);\n        katana_media_list_add(parser, (yyvsp[-3].mediaQuery), (yyval.mediaList));\n    }\n\n    break;\n\n  case 91:\n\n    {\n        (yyval.mediaList) = (yyvsp[-4].mediaList);\n        katana_media_list_add(parser, (yyvsp[-3].mediaQuery), (yyval.mediaList));\n    }\n\n    break;\n\n  case 92:\n\n    {\n        katana_start_rule_body(parser);\n    }\n\n    break;\n\n  case 93:\n\n    {\n        katana_start_rule_header(parser, KatanaRuleMedia);\n    }\n\n    break;\n\n  case 94:\n\n    {\n        katana_end_rule_header(parser);\n    }\n\n    break;\n\n  case 96:\n\n    {\n        (yyval.rule) = katana_new_media_rule(parser, (yyvsp[-6].mediaList), (yyvsp[-1].ruleList));\n    }\n\n    break;\n\n  case 98:\n\n    {\n        // $$ = parser->createSupportsRule($4, $9);\n    }\n\n    break;\n\n  case 99:\n\n    {\n        // parser->startRuleHeader(CSSRuleSourceData::SUPPORTS_RULE);\n        // parser->markSupportsRuleHeaderStart();\n    }\n\n    break;\n\n  case 100:\n\n    {\n        // parser->endRuleHeader();\n        // parser->markSupportsRuleHeaderEnd();\n    }\n\n    break;\n\n  case 105:\n\n    {\n        // $$ = !$3;\n    }\n\n    break;\n\n  case 106:\n\n    {\n        // $$ = $1 && $4;\n    }\n\n    break;\n\n  case 107:\n\n    {\n        // $$ = $1 && $4;\n    }\n\n    break;\n\n  case 108:\n\n    {\n        // $$ = $1 || $4;\n    }\n\n    break;\n\n  case 109:\n\n    {\n        // $$ = $1 || $4;\n    }\n\n    break;\n\n  case 110:\n\n    {\n        // $$ = $3;\n    }\n\n    break;\n\n  case 112:\n\n    {\n        // katana_parser_report_error(parser, $3, InvalidSupportsConditionCSSError);\n        // $$ = false;\n    }\n\n    break;\n\n  case 113:\n\n    {\n        // $$ = false;\n        // CSSPropertyID id = cssPropertyID($3);\n        // if (id != CSSPropertyInvalid) {\n        //     parser->m_valueList = parser->sinkFloatingValueList($7);\n        //     int oldParsedProperties = parser->m_parsedProperties.size();\n        //     $$ = parser->parseValue(id, $8);\n        //     // We just need to know if the declaration is supported as it is written. Rollback any additions.\n        //     if ($$)\n        //         parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);\n        // }\n        // parser->m_valueList = nullptr;\n        // parser->endProperty($8, false);\n    }\n\n    break;\n\n  case 114:\n\n    {\n        // $$ = false;\n        // parser->endProperty(false, false, GeneralCSSError);\n    }\n\n    break;\n\n  case 115:\n\n    {\n        katana_start_rule_header(parser, KatanaRuleKeyframes);\n    }\n\n    break;\n\n  case 116:\n\n    {\n        (yyval.boolean) = false;\n    }\n\n    break;\n\n  case 117:\n\n    {\n        (yyval.rule) = katana_new_keyframes_rule(parser, &(yyvsp[-7].string), (yyvsp[-1].keyframeRuleList), (yyvsp[-8].boolean));\n    }\n\n    break;\n\n  case 121:\n\n    {\n        katana_parser_clear_declarations(parser);\n        katana_parser_reset_declarations(parser);\n    }\n\n    break;\n\n  case 122:\n\n    {\n        (yyval.keyframeRuleList) = katana_new_Keyframe_list(parser);\n        katana_parser_resume_error_logging();\n    }\n\n    break;\n\n  case 123:\n\n    {\n        (yyval.keyframeRuleList) = (yyvsp[-3].keyframeRuleList);\n        katana_keyframe_rule_list_add(parser, (yyvsp[-2].keyframe), (yyval.keyframeRuleList));\n    }\n\n    break;\n\n  case 124:\n\n    {\n        katana_parser_clear_declarations(parser);\n        katana_parser_reset_declarations(parser);\n        katana_parser_resume_error_logging();\n    }\n\n    break;\n\n  case 125:\n\n    {\n        (yyval.keyframe) = katana_new_keyframe(parser, (yyvsp[-4].valueList));\n    }\n\n    break;\n\n  case 126:\n\n    {\n        (yyval.valueList) = katana_new_value_list(parser);\n        katana_value_list_add(parser, (yyvsp[-1].value), (yyval.valueList));\n    }\n\n    break;\n\n  case 127:\n\n    {\n        (yyval.valueList) = (yyvsp[-4].valueList);\n        katana_value_list_add(parser, (yyvsp[-1].value), (yyval.valueList));\n    }\n\n    break;\n\n  case 128:\n\n    {\n        (yyval.value) = katana_new_number_value(parser, (yyvsp[-1].integer), &(yyvsp[0].number), KATANA_VALUE_NUMBER);\n    }\n\n    break;\n\n  case 129:\n\n    {\n        if (!strcasecmp((yyvsp[0].string).data, \"from\")) {\n            KatanaParserNumber number;\n            number.val = 0;\n            number.raw = (KatanaParserString){\"from\", 4};\n            (yyval.value) = katana_new_number_value(parser, 1, &number, KATANA_VALUE_NUMBER);\n        }\n        else if (!strcasecmp((yyvsp[0].string).data, \"to\")) {\n            KatanaParserNumber number;\n            number.val = 100;\n            number.raw = (KatanaParserString){\"to\", 4};\n            (yyval.value) = katana_new_number_value(parser, 1, &number, KATANA_VALUE_NUMBER);\n        }\n        else {\n            YYERROR;\n        }\n    }\n\n    break;\n\n  case 130:\n\n    {\n        // katana_parser_report_error(parser, parser->lastLocationLabel(), InvalidKeyframeSelectorCSSError);\n        katana_parser_clear_declarations(parser);\n        katana_parser_reset_declarations(parser);\n        katana_parser_report_error(parser, NULL, \"InvalidKeyframeSelectorCSSError\");\n    }\n\n    break;\n\n  case 131:\n\n    {\n        katana_start_rule_header(parser, KatanaRuleFontFace);\n    }\n\n    break;\n\n  case 132:\n\n    {\n        (yyval.rule) = katana_new_font_face(parser);\n    }\n\n    break;\n\n  case 133:\n\n    { (yyval.relation) = KatanaSelectorRelationDirectAdjacent; }\n\n    break;\n\n  case 134:\n\n    { (yyval.relation) = KatanaSelectorRelationIndirectAdjacent; }\n\n    break;\n\n  case 135:\n\n    { (yyval.relation) = KatanaSelectorRelationChild; }\n\n    break;\n\n  case 136:\n\n    {\n        if (!strcasecmp((yyvsp[-2].string).data, \"deep\"))\n            (yyval.relation) = KatanaSelectorRelationShadowDeep;\n        else\n            YYERROR;\n    }\n\n    break;\n\n  case 138:\n\n    { (yyval.integer) = 1; }\n\n    break;\n\n  case 139:\n\n    { (yyval.integer) = -1; }\n\n    break;\n\n  case 140:\n\n    { (yyval.integer) = 1; }\n\n    break;\n\n  case 141:\n\n    {\n        katana_start_declaration(parser);\n    }\n\n    break;\n\n  case 142:\n\n    {\n        katana_start_rule_header(parser, KatanaRuleStyle);\n        katana_start_selector(parser);\n    }\n\n    break;\n\n  case 143:\n\n    {\n        katana_end_rule_header(parser);\n    }\n\n    break;\n\n  case 144:\n\n    {\n        katana_end_selector(parser);\n    }\n\n    break;\n\n  case 145:\n\n    {\n        (yyval.rule) = katana_new_style_rule(parser, (yyvsp[-7].selectorList));\n    }\n\n    break;\n\n  case 146:\n\n    {\n        katana_start_selector(parser);\n    }\n\n    break;\n\n  case 147:\n\n    {\n        (yyval.selectorList) = katana_reusable_selector_list(parser);\n        katana_selector_list_shink(parser, 0, (yyval.selectorList));\n        katana_selector_list_add(parser, katana_sink_floating_selector(parser, (yyvsp[0].selector)), (yyval.selectorList));\n    }\n\n    break;\n\n  case 148:\n\n    {\n        (yyval.selectorList) = (yyvsp[-5].selectorList);\n        katana_selector_list_add(parser, katana_sink_floating_selector(parser, (yyvsp[0].selector)), (yyval.selectorList));\n    }\n\n    break;\n\n  case 151:\n\n    {\n        (yyval.selector) = (yyvsp[0].selector);\n        KatanaSelector * end = (yyval.selector);\n        if ( NULL != end ) {\n            while (NULL != end->tagHistory)\n                end = end->tagHistory;\n            end->relation = KatanaSelectorRelationDescendant;\n            // if ($1->isContentPseudoElement())\n            //     end->setRelationIsAffectedByPseudoContent();\n            end->tagHistory = katana_sink_floating_selector(parser, (yyvsp[-2].selector));\n        }\n    }\n\n    break;\n\n  case 152:\n\n    {\n        (yyval.selector) = (yyvsp[0].selector);\n        KatanaSelector * end = (yyval.selector);\n        if ( NULL != end ) {\n            while (NULL != end->tagHistory)\n                end = end->tagHistory;\n            end->relation = (yyvsp[-1].relation);\n            // if ($1->isContentPseudoElement())\n            //     end->setRelationIsAffectedByPseudoContent();\n            end->tagHistory = katana_sink_floating_selector(parser, (yyvsp[-2].selector));\n        }\n    }\n\n    break;\n\n  case 153:\n\n    { \n        katana_string_clear(parser, &(yyval.string));\n    }\n\n    break;\n\n  case 154:\n\n    {\n        (yyval.string) = kKatanaAsteriskString;\n    }\n\n    break;\n\n  case 156:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match = KatanaSelectorMatchTag;\n        (yyval.selector)->tag = katana_new_qualified_name(parser, NULL, &(yyvsp[0].string), &parser->default_namespace);\n    }\n\n    break;\n\n  case 157:\n\n    {\n        (yyval.selector) = katana_rewrite_specifier_with_element_name(parser, &(yyvsp[-1].string), (yyvsp[0].selector));\n        if (!(yyval.selector))\n            YYERROR;\n    }\n\n    break;\n\n  case 158:\n\n    {\n        (yyval.selector) = katana_rewrite_specifier_with_namespace_if_needed(parser, (yyvsp[0].selector));\n        if (!(yyval.selector))\n            YYERROR;\n    }\n\n    break;\n\n  case 159:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match = KatanaSelectorMatchTag;\n        (yyval.selector)->tag = katana_new_qualified_name(parser, &(yyvsp[-1].string), &(yyvsp[0].string), &(yyvsp[-1].string));\n        // $$ = parser->createFloatingSelectorWithTagName(parser->determineNameInNamespace($1, $2));\n        // if (!$$)\n        //     YYERROR;\n    }\n\n    break;\n\n  case 160:\n\n    {\n        // $$ = parser->rewriteSpecifiersWithElementName($1, $2, $3);\n        // if (!$$)\n        //     YYERROR;\n    }\n\n    break;\n\n  case 161:\n\n    {\n        // $$ = parser->rewriteSpecifiersWithElementName($1, starAtom, $2);\n        // if (!$$)\n        //     YYERROR;\n    }\n\n    break;\n\n  case 162:\n\n    {\n        // FIXME: 标签名是否区分大写\n        // if (parser->m_context.isHTMLDocument())\n        //     parser->tokenToLowerCase($1);\n        (yyval.string) = (yyvsp[0].string);\n    }\n\n    break;\n\n  case 163:\n\n    {\n        (yyval.string) = kKatanaAsteriskString;\n    }\n\n    break;\n\n  case 165:\n\n    {\n        (yyval.selector) = katana_rewrite_specifiers(parser, (yyvsp[-1].selector), (yyvsp[0].selector));\n    }\n\n    break;\n\n  case 166:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match =KatanaSelectorMatchId;\n        // if (isQuirksModeBehavior(parser->m_context.mode()))\n            // parser->tokenToLowerCase($1);\n        katana_selector_set_value(parser, (yyval.selector), &(yyvsp[0].string));\n    }\n\n    break;\n\n  case 167:\n\n    {\n        if ((yyvsp[0].string).data[0] >= '0' && (yyvsp[0].string).data[0] <= '9') {\n            YYERROR;\n        } else {\n            (yyval.selector) = katana_new_selector(parser);\n            (yyval.selector)->match =KatanaSelectorMatchId;\n            // if (isQuirksModeBehavior(parser->m_context.mode()))\n                // parser->tokenToLowerCase($1);\n            katana_selector_set_value(parser, (yyval.selector), &(yyvsp[0].string));\n        }\n    }\n\n    break;\n\n  case 171:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match = KatanaSelectorMatchClass;\n        // if (isQuirksModeBehavior(parser->m_context.mode()))\n        //     parser->tokenToLowerCase($2);\n        katana_selector_set_value(parser, (yyval.selector), &(yyvsp[0].string));\n    }\n\n    break;\n\n  case 172:\n\n    {\n        // if (parser->m_context.isHTMLDocument())\n        //     parser->tokenToLowerCase($1);\n        (yyval.string) = (yyvsp[-1].string);\n    }\n\n    break;\n\n  case 173:\n\n    {\n        KatanaAttributeMatchType attrMatchType = KatanaAttributeMatchTypeCaseSensitive;\n        if (!katana_parse_attribute_match_type(parser, attrMatchType, &(yyvsp[-1].string)))\n            YYERROR;\n        (yyval.attributeMatchType) = attrMatchType;\n    }\n\n    break;\n\n  case 175:\n\n    { (yyval.attributeMatchType) = KatanaAttributeMatchTypeCaseSensitive; }\n\n    break;\n\n  case 176:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->data->attribute = katana_new_qualified_name(parser, NULL, &(yyvsp[-1].string), NULL);\n        (yyval.selector)->data->bits.attributeMatchType = KatanaAttributeMatchTypeCaseSensitive;\n        (yyval.selector)->match = KatanaSelectorMatchAttributeSet;\n    }\n\n    break;\n\n  case 177:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->data->attribute = katana_new_qualified_name(parser, NULL, &(yyvsp[-6].string), NULL);\n        (yyval.selector)->data->bits.attributeMatchType = (yyvsp[-1].attributeMatchType);\n        (yyval.selector)->match = (yyvsp[-5].integer);\n        katana_selector_set_value(parser, (yyval.selector), &(yyvsp[-3].string));\n    }\n\n    break;\n\n  case 178:\n\n    {\n        // $$ = parser->createFloatingSelector();\n        // $$->setAttribute(parser->determineNameInNamespace($3, $4), CSSSelector::CaseSensitive);\n        // $$->setMatch(CSSSelector::Set);\n    }\n\n    break;\n\n  case 179:\n\n    {\n        // $$ = parser->createFloatingSelector();\n        // $$->setAttribute(parser->determineNameInNamespace($3, $4), $9);\n        // $$->setMatch((CSSSelector::Match)$5);\n        // $$->setValue($7);\n    }\n\n    break;\n\n  case 180:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 181:\n\n    {\n        (yyval.integer) = KatanaSelectorMatchAttributeExact;\n    }\n\n    break;\n\n  case 182:\n\n    {\n        (yyval.integer) = KatanaSelectorMatchAttributeList;\n    }\n\n    break;\n\n  case 183:\n\n    {\n        (yyval.integer) = KatanaSelectorMatchAttributeHyphen;\n    }\n\n    break;\n\n  case 184:\n\n    {\n        (yyval.integer) = KatanaSelectorMatchAttributeBegin;\n    }\n\n    break;\n\n  case 185:\n\n    {\n        (yyval.integer) = KatanaSelectorMatchAttributeEnd;\n    }\n\n    break;\n\n  case 186:\n\n    {\n        (yyval.integer) = KatanaSelectorMatchAttributeContain;\n    }\n\n    break;\n\n  case 189:\n\n    {\n        if (katana_string_is_function(&(yyvsp[0].string)))\n            YYERROR;\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match = KatanaSelectorMatchPseudoClass;\n        katana_string_to_lowercase(parser, &(yyvsp[0].string));\n        katana_selector_set_value(parser, (yyval.selector), &(yyvsp[0].string));\n        katana_selector_extract_pseudo_type((yyval.selector));\n        // if ($$->pseudo == KatanaSelectorPseudoUnknown) {\n        //     katana_parser_report_error(parser, $2, InvalidSelectorPseudoCSSError);\n        //     YYERROR;\n    }\n\n    break;\n\n  case 190:\n\n    {\n        if (katana_string_is_function(&(yyvsp[0].string)))\n            YYERROR;\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match = KatanaSelectorMatchPseudoElement;\n        katana_string_to_lowercase(parser, &(yyvsp[0].string));\n        katana_selector_set_value(parser, (yyval.selector), &(yyvsp[0].string));\n        katana_selector_extract_pseudo_type((yyval.selector));\n        // FIXME: This call is needed to force selector to compute the pseudoType early enough.\n        // CSSSelector::PseudoType type = $$->pseudoType();\n        // if (type == CSSSelector::PseudoUnknown) {\n        //     katana_parser_report_error(parser, $3, InvalidSelectorPseudoCSSError);\n        //     YYERROR;\n    }\n\n    break;\n\n  case 191:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 192:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match = KatanaSelectorMatchPseudoClass;\n        katana_selector_set_argument(parser, (yyval.selector), &(yyvsp[-2].string));\n        katana_selector_set_value(parser, (yyval.selector), &(yyvsp[-4].string));\n        katana_selector_extract_pseudo_type((yyval.selector));\n        // CSSSelector::PseudoType type = $$->pseudoType();\n        // if (type == CSSSelector::PseudoUnknown)\n        //     YYERROR;\n    }\n\n    break;\n\n  case 193:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match = KatanaSelectorMatchPseudoClass;\n        katana_selector_set_argument_with_number(parser, (yyval.selector), (yyvsp[-3].integer), &(yyvsp[-2].number));\n        katana_selector_set_value(parser, (yyval.selector), &(yyvsp[-5].string));\n        katana_selector_extract_pseudo_type((yyval.selector));\n    //     $$ = parser->createFloatingSelector();\n    //     $$->setMatch(CSSSelector::PseudoClass);\n    //     $$->setArgument(AtomicString::number($4 * $5));\n    //     $$->setValue($2);\n    //     CSSSelector::PseudoType type = $$->pseudoType();\n    //     if (type == CSSSelector::PseudoUnknown)\n            // YYERROR;\n    }\n\n    break;\n\n  case 194:\n\n    {\n        (yyval.selector) = katana_new_selector(parser);\n        (yyval.selector)->match = KatanaSelectorMatchPseudoClass;\n        katana_selector_set_argument(parser, (yyval.selector), &(yyvsp[-2].string));\n        \n        katana_string_to_lowercase(parser, &(yyvsp[-4].string));\n        katana_selector_set_value(parser, (yyval.selector), &(yyvsp[-4].string));\n        katana_selector_extract_pseudo_type((yyval.selector));\n        // CSSSelector::PseudoType type = $$->pseudoType();\n        // if (type == CSSSelector::PseudoUnknown)\n        //     YYERROR;\n        // else if (type == CSSSelector::PseudoNthChild ||\n        //          type == CSSSelector::PseudoNthOfType ||\n        //          type == CSSSelector::PseudoNthLastChild ||\n        //          type == CSSSelector::PseudoNthLastOfType) {\n        //     if (!isValidNthToken($4))\n        //         YYERROR;\n        // }\n    }\n\n    break;\n\n  case 195:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 196:\n\n    {\n        if (!katana_selector_is_simple(parser, (yyvsp[-2].selector)))\n            YYERROR;\n        else {\n            (yyval.selector) = katana_new_selector(parser);\n            (yyval.selector)->match = KatanaSelectorMatchPseudoClass;\n            (yyval.selector)->pseudo = KatanaPseudoNot;\n\n            KatanaArray* array = katana_new_array(parser);\n            katana_selector_list_add(parser, katana_sink_floating_selector(parser, (yyvsp[-2].selector)), array);\n            katana_adopt_selector_list(parser, array, (yyval.selector));\n\n            katana_string_to_lowercase(parser, &(yyvsp[-4].string));\n            katana_selector_set_value(parser, (yyval.selector), &(yyvsp[-4].string));\n        }\n    }\n\n    break;\n\n  case 197:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 198:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 199:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 201:\n\n    { (yyval.boolean) = false; }\n\n    break;\n\n  case 203:\n\n    {\n        (yyval.boolean) = (yyvsp[-1].boolean) || (yyvsp[0].boolean);\n    }\n\n    break;\n\n  case 205:\n\n    {\n        katana_start_declaration(parser);\n        (yyval.boolean) = (yyvsp[-2].boolean);\n    }\n\n    break;\n\n  case 206:\n\n    {\n        katana_start_declaration(parser);\n        (yyval.boolean) = (yyvsp[-3].boolean) || (yyvsp[-2].boolean);\n    }\n\n    break;\n\n  case 207:\n\n    {\n        (yyval.boolean) = false;\n        bool isPropertyParsed = false;\n        // unsigned int oldParsedProperties = parser->parsedProperties->length;\n        (yyval.boolean) = katana_new_declaration(parser, &(yyvsp[-5].string), (yyvsp[0].boolean), (yyvsp[-1].valueList));\n        if (!(yyval.boolean)) {\n            // parser->rollbackLastProperties(parser->m_parsedProperties.size() - oldParsedProperties);\n            katana_parser_report_error(parser, (yyvsp[-2].location), \"InvalidPropertyValueCSSError\");\n        } else {\n            isPropertyParsed = true;\n        }\n        katana_end_declaration(parser, (yyvsp[0].boolean), isPropertyParsed);\n    }\n\n    break;\n\n  case 208:\n\n    {\n        /* When we encounter something like p {color: red !important fail;} we should drop the declaration */\n        katana_parser_report_error(parser, (yyvsp[-4].location), \"InvalidPropertyValueCSSError\");\n        katana_end_declaration(parser, false, false);\n        (yyval.boolean) = false;\n    }\n\n    break;\n\n  case 209:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-2].location), \"InvalidPropertyValueCSSError\");\n        katana_end_declaration(parser, false, false);\n        (yyval.boolean) = false;\n    }\n\n    break;\n\n  case 210:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-1].location), \"PropertyDeclarationCSSError\");\n        katana_end_declaration(parser, false, false);\n        (yyval.boolean) = false;\n    }\n\n    break;\n\n  case 211:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-1].location), \"PropertyDeclarationCSSError\");\n        (yyval.boolean) = false;\n    }\n\n    break;\n\n  case 212:\n\n    {\n        // $$ = cssPropertyID($2);\n        // parser->setCurrentProperty($$);\n        // if ($$ == CSSPropertyInvalid)\n        //     katana_parser_report_error(parser, $1, InvalidPropertyCSSError);\n        (yyval.string) = (yyvsp[-1].string);\n        katana_set_current_declaration(parser, &(yyval.string));\n    }\n\n    break;\n\n  case 213:\n\n    { (yyval.boolean) = true; }\n\n    break;\n\n  case 214:\n\n    { (yyval.boolean) = false; }\n\n    break;\n\n  case 215:\n\n    {\n        (yyval.valueList) = katana_new_value_list(parser);\n        katana_value_list_add(parser, katana_new_ident_value(parser, &(yyvsp[-1].string)), (yyval.valueList));\n    }\n\n    break;\n\n  case 216:\n\n    {\n        (yyval.valueList) = (yyvsp[-2].valueList);\n        katana_value_list_add(parser, katana_new_ident_value(parser, &(yyvsp[-1].string)), (yyval.valueList));\n    }\n\n    break;\n\n  case 217:\n\n    {\n        (yyval.value) = katana_new_list_value(parser, NULL);\n    }\n\n    break;\n\n  case 218:\n\n    {\n        (yyval.value) = katana_new_list_value(parser, (yyvsp[-1].valueList));\n    }\n\n    break;\n\n  case 219:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 220:\n\n    {\n        (yyval.valueList) = katana_new_value_list(parser);\n        katana_value_list_add(parser, (yyvsp[0].value), (yyval.valueList));\n    }\n\n    break;\n\n  case 221:\n\n    {\n        (yyval.valueList) = (yyvsp[-2].valueList);\n        katana_value_list_add(parser, katana_new_operator_value(parser, (yyvsp[-1].character)), (yyval.valueList));\n        katana_value_list_add(parser, (yyvsp[0].value), (yyval.valueList));\n    }\n\n    break;\n\n  case 222:\n\n    {\n        (yyval.valueList) = (yyvsp[-1].valueList);\n        katana_value_list_add(parser, (yyvsp[0].value), (yyval.valueList));\n    }\n\n    break;\n\n  case 223:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-1].location), \"PropertyDeclarationCSSError\");\n    }\n\n    break;\n\n  case 224:\n\n    {\n        (yyval.character) = '/';\n    }\n\n    break;\n\n  case 225:\n\n    {\n        (yyval.character) = ',';\n    }\n\n    break;\n\n  case 226:\n\n    {\n        (yyval.character) = '=';\n    }\n\n    break;\n\n  case 228:\n\n    {\n      (yyval.value) = (yyvsp[-1].value);\n      // $$->fValue *= $1;\n      katana_value_set_sign(parser, (yyval.value), (yyvsp[-2].integer));\n\n  }\n\n    break;\n\n  case 229:\n\n    { (yyval.value) = katana_new_value(parser); (yyval.value)->id = KatanaValueInvalid; (yyval.value)->isInt = false; katana_value_set_string(parser, (yyval.value), &(yyvsp[-1].string)); (yyval.value)->unit = KATANA_VALUE_STRING; }\n\n    break;\n\n  case 230:\n\n    { (yyval.value) = katana_new_ident_value(parser, &(yyvsp[-1].string)); }\n\n    break;\n\n  case 231:\n\n    { (yyval.value) = katana_new_value(parser); (yyval.value)->id = KatanaValueInvalid; katana_value_set_string(parser, (yyval.value), &(yyvsp[-1].string)); (yyval.value)->isInt = false; (yyval.value)->unit = KATANA_VALUE_DIMENSION; }\n\n    break;\n\n  case 232:\n\n    { (yyval.value) = katana_new_value(parser); (yyval.value)->id = KatanaValueInvalid; katana_value_set_string(parser, (yyval.value), &(yyvsp[-1].string)); (yyval.value)->isInt = false; (yyval.value)->unit = KATANA_VALUE_DIMENSION; }\n\n    break;\n\n  case 233:\n\n    { (yyval.value) = katana_new_value(parser); (yyval.value)->id = KatanaValueInvalid; katana_value_set_string(parser, (yyval.value), &(yyvsp[-1].string)); (yyval.value)->isInt = false; (yyval.value)->unit = KATANA_VALUE_URI; }\n\n    break;\n\n  case 234:\n\n    { (yyval.value) = katana_new_value(parser); (yyval.value)->id = KatanaValueInvalid; katana_value_set_string(parser, (yyval.value), &(yyvsp[-1].string)); (yyval.value)->isInt = false; (yyval.value)->unit = KATANA_VALUE_UNICODE_RANGE; }\n\n    break;\n\n  case 235:\n\n    { (yyval.value) = katana_new_value(parser); (yyval.value)->id = KatanaValueInvalid; katana_value_set_string(parser, (yyval.value), &(yyvsp[-1].string)); (yyval.value)->isInt = false; (yyval.value)->unit = KATANA_VALUE_PARSER_HEXCOLOR; }\n\n    break;\n\n  case 236:\n\n    { (yyval.value) = katana_new_value(parser); (yyval.value)->id = KatanaValueInvalid; \n    //(yyval.value)->string = \"#\"; \n    KatanaParserString tmp = {\"#\", 1};\n    katana_value_set_string(parser, yyval.value, &tmp); \n    (yyval.value)->isInt = false; (yyval.value)->unit = KATANA_VALUE_PARSER_HEXCOLOR; }\n\n    break;\n\n  case 239:\n\n    { /* Handle width: %; */ (yyval.value) = katana_new_value(parser); (yyval.value)->id = KatanaValueInvalid; (yyval.value)->isInt = false; (yyval.value)->unit = 0; }\n\n    break;\n\n  case 241:\n\n    { (yyval.value) = katana_new_number_value(parser, 1, &(yyvsp[0].number), KATANA_VALUE_NUMBER); (yyval.value)->isInt = true; }\n\n    break;\n\n  case 242:\n\n    { (yyval.value) = katana_new_number_value(parser, 1, &(yyvsp[0].number), KATANA_VALUE_NUMBER); }\n\n    break;\n\n  case 243:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_PERCENTAGE); }\n\n    break;\n\n  case 244:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_PX); }\n\n    break;\n\n  case 245:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_CM); }\n\n    break;\n\n  case 246:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_MM); }\n\n    break;\n\n  case 247:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_IN); }\n\n    break;\n\n  case 248:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_PT); }\n\n    break;\n\n  case 249:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_PC); }\n\n    break;\n\n  case 250:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_DEG); }\n\n    break;\n\n  case 251:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_RAD); }\n\n    break;\n\n  case 252:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_GRAD); }\n\n    break;\n\n  case 253:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_TURN); }\n\n    break;\n\n  case 254:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_MS); }\n\n    break;\n\n  case 255:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_S); }\n\n    break;\n\n  case 256:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_HZ); }\n\n    break;\n\n  case 257:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_KHZ); }\n\n    break;\n\n  case 258:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_EMS); }\n\n    break;\n\n  case 259:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_PARSER_Q_EMS); }\n\n    break;\n\n  case 260:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_EXS); }\n\n    break;\n\n  case 261:\n\n    {  (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_REMS); /* if (parser->m_styleSheet) parser->m_styleSheet->parserSetUsesRemUnits(true); */ }\n\n    break;\n\n  case 262:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_CHS); }\n\n    break;\n\n  case 263:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_VW); }\n\n    break;\n\n  case 264:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_VH); }\n\n    break;\n\n  case 265:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_VMIN); }\n\n    break;\n\n  case 266:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_VMAX); }\n\n    break;\n\n  case 267:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_DPPX); }\n\n    break;\n\n  case 268:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_DPI); }\n\n    break;\n\n  case 269:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_DPCM); }\n\n    break;\n\n  case 270:\n\n    { (yyval.value) = katana_new_dimension_value(parser, &(yyvsp[0].number), KATANA_VALUE_FR); }\n\n    break;\n\n  case 271:\n\n    {\n        (yyval.value) = katana_new_function_value(parser, &(yyvsp[-3].string), (yyvsp[-1].valueList));\n    }\n\n    break;\n\n  case 272:\n\n    {\n        (yyval.value) = katana_new_function_value(parser, &(yyvsp[-2].string), NULL);\n    }\n\n    break;\n\n  case 273:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 275:\n\n    { (yyval.value) = (yyvsp[0].value); (yyval.value)->fValue *= (yyvsp[-1].integer); }\n\n    break;\n\n  case 276:\n\n    {\n        (yyval.character) = '+';\n    }\n\n    break;\n\n  case 277:\n\n    {\n        (yyval.character) = '-';\n    }\n\n    break;\n\n  case 278:\n\n    {\n        (yyval.character) = '*';\n    }\n\n    break;\n\n  case 279:\n\n    {\n        (yyval.character) = '/';\n    }\n\n    break;\n\n  case 282:\n\n    {\n        (yyval.valueList) = (yyvsp[-2].valueList);\n        katana_value_list_insert(parser, katana_new_operator_value(parser, '('), 0, (yyval.valueList));\n        katana_new_operator_value(parser, ')');\n        katana_value_list_add(parser, katana_new_operator_value(parser, ')'), (yyval.valueList));\n    }\n\n    break;\n\n  case 283:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 284:\n\n    {\n        (yyval.valueList) = katana_new_value_list(parser);\n        katana_value_list_add(parser, (yyvsp[0].value), (yyval.valueList));\n    }\n\n    break;\n\n  case 285:\n\n    {\n        (yyval.valueList) = (yyvsp[-2].valueList);\n        katana_value_list_add(parser, katana_new_operator_value(parser, (yyvsp[-1].character)), (yyval.valueList));\n        katana_value_list_add(parser, (yyvsp[0].value), (yyval.valueList));\n    }\n\n    break;\n\n  case 286:\n\n    {\n        (yyval.valueList) = (yyvsp[-2].valueList);\n        katana_value_list_add(parser, katana_new_operator_value(parser, (yyvsp[-1].character)), (yyval.valueList));\n        katana_value_list_steal_values(parser, (yyvsp[0].valueList), (yyval.valueList));\n    }\n\n    break;\n\n  case 288:\n\n    {\n        (yyval.value) = katana_new_function_value(parser, &(yyvsp[-4].string), (yyvsp[-2].valueList));\n    }\n\n    break;\n\n  case 289:\n\n    {\n        YYERROR;\n    }\n\n    break;\n\n  case 292:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-1].location), \"InvalidRuleCSSError\");\n    }\n\n    break;\n\n  case 297:\n\n    {\n        // katana_parser_report_error(parser, $4, InvalidSupportsConditionCSSError);\n        // parser->popSupportsRuleData();\n    }\n\n    break;\n\n  case 299:\n\n    {\n        // katana_parser_resume_error_logging();\n        // katana_parser_report_error(parser, $1, \"InvalidRuleCSSError regular_invalid_at_rule_header\");\n    }\n\n    break;\n\n  case 300:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-3].location), \"InvalidRuleCSSError invalid_rule\");\n    }\n\n    break;\n\n  case 304:\n\n    {\n        katana_parser_report_error(parser, (yyvsp[-2].location), \"InvalidRuleCSSError invalid_rule_header\");\n    }\n\n    break;\n\n  case 307:\n\n    {\n        katana_end_invalid_rule_header(parser);\n   }\n\n    break;\n\n  case 308:\n\n    {\n        katana_parser_report_error(parser, parser->position, \"invalidBlockHit\");\n    }\n\n    break;\n\n  case 313:\n\n    {\n        (yyval.location) = katana_parser_current_location(parser, &yylloc);\n    }\n\n    break;\n\n  case 314:\n\n    {\n        // parser->setLocationLabel(parser->currentLocation());\n    }\n\n    break;\n\n\n\n      default: break;\n    }\n  /* User semantic actions sometimes alter yychar, and that requires\n     that yytoken be updated with the new translation.  We take the\n     approach of translating immediately before every use of yytoken.\n     One alternative is translating here after every semantic action,\n     but that translation would be missed if the semantic action invokes\n     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or\n     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an\n     incorrect destructor might then be invoked immediately.  In the\n     case of YYERROR or YYBACKUP, subsequent parser actions might lead\n     to an incorrect destructor call or verbose syntax error message\n     before the lookahead is translated.  */\n  YY_SYMBOL_PRINT (\"-> $$ =\", yyr1[yyn], &yyval, &yyloc);\n\n  YYPOPSTACK (yylen);\n  yylen = 0;\n  YY_STACK_PRINT (yyss, yyssp);\n\n  *++yyvsp = yyval;\n  *++yylsp = yyloc;\n\n  /* Now 'shift' the result of the reduction.  Determine what state\n     that goes to, based on the state we popped back to and the rule\n     number reduced by.  */\n\n  yyn = yyr1[yyn];\n\n  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;\n  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)\n    yystate = yytable[yystate];\n  else\n    yystate = yydefgoto[yyn - YYNTOKENS];\n\n  goto yynewstate;\n\n\n/*--------------------------------------.\n| yyerrlab -- here on detecting error.  |\n`--------------------------------------*/\nyyerrlab:\n  /* Make sure we have latest lookahead translation.  See comments at\n     user semantic actions for why this is necessary.  */\n  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);\n\n  /* If not already recovering from an error, report this error.  */\n  if (!yyerrstatus)\n    {\n      ++yynerrs;\n#if ! YYERROR_VERBOSE\n      yyerror (&yylloc, scanner, parser, YY_(\"syntax error\"));\n#else\n# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \\\n                                        yyssp, yytoken)\n      {\n        char const *yymsgp = YY_(\"syntax error\");\n        int yysyntax_error_status;\n        yysyntax_error_status = YYSYNTAX_ERROR;\n        if (yysyntax_error_status == 0)\n          yymsgp = yymsg;\n        else if (yysyntax_error_status == 1)\n          {\n            if (yymsg != yymsgbuf)\n              YYSTACK_FREE (yymsg);\n            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);\n            if (!yymsg)\n              {\n                yymsg = yymsgbuf;\n                yymsg_alloc = sizeof yymsgbuf;\n                yysyntax_error_status = 2;\n              }\n            else\n              {\n                yysyntax_error_status = YYSYNTAX_ERROR;\n                yymsgp = yymsg;\n              }\n          }\n        yyerror (&yylloc, scanner, parser, yymsgp);\n        if (yysyntax_error_status == 2)\n          goto yyexhaustedlab;\n      }\n# undef YYSYNTAX_ERROR\n#endif\n    }\n\n  yyerror_range[1] = yylloc;\n\n  if (yyerrstatus == 3)\n    {\n      /* If just tried and failed to reuse lookahead token after an\n         error, discard it.  */\n\n      if (yychar <= YYEOF)\n        {\n          /* Return failure if at end of input.  */\n          if (yychar == YYEOF)\n            YYABORT;\n        }\n      else\n        {\n          yydestruct (\"Error: discarding\",\n                      yytoken, &yylval, &yylloc, scanner, parser);\n          yychar = YYEMPTY;\n        }\n    }\n\n  /* Else will try to reuse lookahead token after shifting the error\n     token.  */\n  goto yyerrlab1;\n\n\n/*---------------------------------------------------.\n| yyerrorlab -- error raised explicitly by YYERROR.  |\n`---------------------------------------------------*/\nyyerrorlab:\n\n  /* Pacify compilers like GCC when the user code never invokes\n     YYERROR and the label yyerrorlab therefore never appears in user\n     code.  */\n  if (/*CONSTCOND*/ /* DISABLES CODE */ (0))\n     goto yyerrorlab;\n\n  yyerror_range[1] = yylsp[1-yylen];\n  /* Do not reclaim the symbols of the rule whose action triggered\n     this YYERROR.  */\n  YYPOPSTACK (yylen);\n  yylen = 0;\n  YY_STACK_PRINT (yyss, yyssp);\n  yystate = *yyssp;\n  goto yyerrlab1;\n\n\n/*-------------------------------------------------------------.\n| yyerrlab1 -- common code for both syntax error and YYERROR.  |\n`-------------------------------------------------------------*/\nyyerrlab1:\n  yyerrstatus = 3;      /* Each real token shifted decrements this.  */\n\n  for (;;)\n    {\n      yyn = yypact[yystate];\n      if (!yypact_value_is_default (yyn))\n        {\n          yyn += YYTERROR;\n          if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)\n            {\n              yyn = yytable[yyn];\n              if (0 < yyn)\n                break;\n            }\n        }\n\n      /* Pop the current state because it cannot handle the error token.  */\n      if (yyssp == yyss)\n        YYABORT;\n\n      yyerror_range[1] = *yylsp;\n      yydestruct (\"Error: popping\",\n                  yystos[yystate], yyvsp, yylsp, scanner, parser);\n      YYPOPSTACK (1);\n      yystate = *yyssp;\n      YY_STACK_PRINT (yyss, yyssp);\n    }\n\n  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN\n  *++yyvsp = yylval;\n  YY_IGNORE_MAYBE_UNINITIALIZED_END\n\n  yyerror_range[2] = yylloc;\n  /* Using YYLLOC is tempting, but would change the location of\n     the lookahead.  YYLOC is available though.  */\n  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);\n  *++yylsp = yyloc;\n\n  /* Shift the error token.  */\n  YY_SYMBOL_PRINT (\"Shifting\", yystos[yyn], yyvsp, yylsp);\n\n  yystate = yyn;\n  goto yynewstate;\n\n\n/*-------------------------------------.\n| yyacceptlab -- YYACCEPT comes here.  |\n`-------------------------------------*/\nyyacceptlab:\n  yyresult = 0;\n  goto yyreturn;\n\n/*-----------------------------------.\n| yyabortlab -- YYABORT comes here.  |\n`-----------------------------------*/\nyyabortlab:\n  yyresult = 1;\n  goto yyreturn;\n\n#if !defined yyoverflow || YYERROR_VERBOSE\n/*-------------------------------------------------.\n| yyexhaustedlab -- memory exhaustion comes here.  |\n`-------------------------------------------------*/\nyyexhaustedlab:\n  yyerror (&yylloc, scanner, parser, YY_(\"memory exhausted\"));\n  yyresult = 2;\n  /* Fall through.  */\n#endif\n\nyyreturn:\n  if (yychar != YYEMPTY)\n    {\n      /* Make sure we have latest lookahead translation.  See comments at\n         user semantic actions for why this is necessary.  */\n      yytoken = YYTRANSLATE (yychar);\n      yydestruct (\"Cleanup: discarding lookahead\",\n                  yytoken, &yylval, &yylloc, scanner, parser);\n    }\n  /* Do not reclaim the symbols of the rule whose action triggered\n     this YYABORT or YYACCEPT.  */\n  YYPOPSTACK (yylen);\n  YY_STACK_PRINT (yyss, yyssp);\n  while (yyssp != yyss)\n    {\n      yydestruct (\"Cleanup: popping\",\n                  yystos[*yyssp], yyvsp, yylsp, scanner, parser);\n      YYPOPSTACK (1);\n    }\n#ifndef yyoverflow\n  if (yyss != yyssa)\n    YYSTACK_FREE (yyss);\n#endif\n#if YYERROR_VERBOSE\n  if (yymsg != yymsgbuf)\n    YYSTACK_FREE (yymsg);\n#endif\n  return yyresult;\n}\n\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/parser.c",
    "content": "/**\n * Copyright (c) 2015 QFish <im@qfi.sh>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n#include <assert.h>\n#include <ctype.h>\n#include <stdarg.h>\n#include <stdlib.h>\n#include <string.h>\n#include <strings.h>\n\n#include \"katana.h\"\n#include \"selector.h\"\n#include \"katana.tab.h\"\n#include \"parser.h\"\n#include \"tokenizer.h\"\n\n#include \"foundation.h\"\n\n//#undef\tassert\n//#define assert(x)\n\n#define breakpoint\n#define KATANA_PARSER_STRING(literal) { literal, sizeof(literal) - 1 }\n\n\ntypedef void (*KatanaArrayDeallocator)(KatanaParser* parser, void* e);\n\n#undef  katana_destroy_array\n#define katana_destroy_array(parser, callback, e) \\\n        katana_destroy_array_using_deallocator((parser), \\\n                    (KatanaArrayDeallocator)(&(callback)), (e))\n\n\nvoid katana_destroy_stylesheet(KatanaParser* parser, KatanaStylesheet* e);\nvoid katana_destroy_rule(KatanaParser* parser, KatanaRule* e);\nvoid katana_destroy_font_face_rule(KatanaParser* parser, KatanaFontFaceRule* e);\nvoid katana_destroy_import_rule(KatanaParser* parser, KatanaImportRule* e);\nvoid katana_destroy_media_rule(KatanaParser* parser, KatanaMediaRule* e);\nvoid katana_destroy_media_query(KatanaParser* parser, KatanaMediaQuery* e);\nvoid katana_destroy_media_query_exp(KatanaParser* parser, KatanaMediaQueryExp* e);\nvoid katana_destroy_keyframes_rule(KatanaParser* parser, KatanaKeyframesRule* e);\nvoid katana_destroy_keyframe(KatanaParser* parser, KatanaKeyframe* e);\nvoid katana_destroy_media_list(KatanaParser* parser, KatanaArray* e);\nvoid katana_destroy_rule_list(KatanaParser* parser, KatanaArray* e);\nvoid katana_destroy_style_rule(KatanaParser* parser, KatanaStyleRule* e);\nvoid katana_destroy_qualified_name(KatanaParser* parser, KatanaQualifiedName* e);\nvoid katana_destroy_selector(KatanaParser* parser, KatanaSelector* e);\nvoid katana_destroy_rare_data(KatanaParser* parser, KatanaSelectorRareData* e);\nvoid katana_destroy_declaration(KatanaParser* parser, KatanaDeclaration* e);\nvoid katana_destroy_value(KatanaParser* parser, KatanaValue* e);\nvoid katana_destroy_function(KatanaParser* parser, KatanaValueFunction* e);\n\nvoid katana_destroy_array_using_deallocator(KatanaParser* parser,\n                          KatanaArrayDeallocator deallocator, KatanaArray* array);\n\n\n\nextern int katanaparse(void* scanner, struct KatanaInternalParser * parser);\n\nstatic KatanaOutput* katana_parse_with_options(const KatanaOptions* options,\n                                               yyconst char* bytes,\n                                               size_t len,\n                                               KatanaParserMode mode);\n\nstatic KatanaOutput* katana_parse_fragment(const char* prefix,\n                                           size_t pre_len,\n                                           const char* string,\n                                           size_t str_len,\n                                           KatanaParserMode mode);\n\nstatic const char* katana_stringify_value_list(KatanaParser* parser, KatanaArray* value_list);\nstatic const char* katana_stringify_value(KatanaParser* parser, KatanaValue* value);\n\nstatic void* malloc_wrapper(void* unused, size_t size) {\n    return malloc(size);\n}\n\nstatic void free_wrapper(void* unused, void* ptr) {\n    free(ptr);\n}\n\nconst KatanaOptions kKatanaDefaultOptions = {\n    &malloc_wrapper,\n    &free_wrapper,\n    NULL\n};\n\nstatic void output_init(KatanaParser* parser, KatanaParserMode mode)\n{\n    KatanaOutput* output = katana_parser_allocate(parser, sizeof(KatanaOutput));\n    output->stylesheet = katana_new_stylesheet(parser);\n    output->mode = mode;\n    katana_array_init(parser, 0, &output->errors);\n    parser->output = output;\n}\n\nvoid katana_destroy_output(KatanaOutput* output)\n{\n    if ( NULL == output )\n        return;\n\n    KatanaParser parser;\n    parser.options = &kKatanaDefaultOptions;\n    switch (output->mode) {\n        case KatanaParserModeStylesheet:\n            break;\n        case KatanaParserModeRule:\n            if ( NULL != output->rule ) {\n                katana_destroy_rule(&parser, output->rule);\n            }\n            break;\n        case KatanaParserModeKeyframeRule:\n            if ( NULL != output->keyframe ) {\n                katana_destroy_keyframe(&parser, output->keyframe);\n            }\n            break;\n        case KatanaParserModeKeyframeKeyList:\n            if ( NULL != output->keyframe_keys ) {\n                katana_destroy_array(&parser, katana_destroy_value, output->keyframe_keys);\n                katana_parser_deallocate(&parser, (void*) output->keyframe_keys);\n                output->keyframe_keys = NULL;\n            }\n            break;\n        case KatanaParserModeMediaList:\n            if ( NULL != output->medias ) {\n                katana_destroy_media_list(&parser, output->medias);\n            }\n            break;\n        case KatanaParserModeValue:\n            if ( NULL != output->values ) {\n                katana_destroy_array(&parser, katana_destroy_value, output->values);\n                katana_parser_deallocate(&parser, (void*) output->values);\n                output->values = NULL;\n            }\n            break;\n        case KatanaParserModeSelector:\n            if ( NULL != output->selectors ) {\n                katana_destroy_array(&parser, katana_destroy_selector, output->selectors);\n                katana_parser_deallocate(&parser, (void*) output->selectors);\n                output->selectors = NULL;\n            }\n            break;\n        case KatanaParserModeDeclarationList:\n            if ( NULL != output->declarations ) {\n                katana_destroy_array(&parser, katana_destroy_declaration, output->declarations);\n                katana_parser_deallocate(&parser, (void*) output->declarations);\n                output->declarations = NULL;\n            }\n            break;\n    }\n    katana_destroy_stylesheet(&parser, output->stylesheet);\n    katana_array_destroy(&parser, &output->errors);\n    katana_parser_deallocate(&parser, output);\n}\n\n\nstatic const KatanaParserString kKatanaParserModePrefixs[] = {\n    KATANA_PARSER_STRING(\"\"),\n    KATANA_PARSER_STRING(\"@-internal-rule \"), // 16\n    KATANA_PARSER_STRING(\"@-internal-keyframe-rule \"), // 25\n    KATANA_PARSER_STRING(\"@-internal-keyframe-key-list \"), // 29\n    KATANA_PARSER_STRING(\"@-internal-media-list \"), // 22\n    KATANA_PARSER_STRING(\"@-internal-value \"), // 17\n    KATANA_PARSER_STRING(\"@-internal-selector \"), // 20\n    KATANA_PARSER_STRING(\"@-internal-decls \"), // 17\n};\n\nKatanaOutput* katana_parse(const char* str, size_t len, KatanaParserMode mode)\n{\n    switch (mode) {\n        case KatanaParserModeStylesheet:\n            return katana_parse_with_options(&kKatanaDefaultOptions, (yyconst char*)str, len, mode);\n        case KatanaParserModeRule:\n        case KatanaParserModeKeyframeRule:\n        case KatanaParserModeKeyframeKeyList:\n        case KatanaParserModeMediaList:\n        case KatanaParserModeValue:\n        case KatanaParserModeSelector:\n        case KatanaParserModeDeclarationList: {\n            KatanaParserString prefix = kKatanaParserModePrefixs[mode];\n            return katana_parse_fragment(prefix.data, prefix.length, str, len, mode);\n        }\n        default:\n            katana_print(\"Whoops, not support yet!\");\n            return NULL;\n    }\n}\n\nKatanaOutput* katana_parse_in(FILE* fp)\n{\n    assert(NULL != fp);\n    if ( NULL == fp )\n        return NULL;\n    \n    yyscan_t scanner;\n    if (katanalex_init(&scanner)) {\n        katana_print(\"no scanning today!\");\n        return NULL;\n    }\n    \n    katanaset_in(fp, scanner);\n    \n    KatanaParser parser;\n    parser.options = &kKatanaDefaultOptions;\n    parser.scanner = &scanner;\n    parser.default_namespace = kKatanaAsteriskString;\n    parser.parsed_declarations = katana_new_array(&parser);\n#if KATANA_PARSER_DEBUG\n    parser.parsed_selectors = katana_new_array(&parser);\n#endif // #if KATANA_PARSER_DEBUG\n    parser.position = katana_parser_allocate(&parser, sizeof(KatanaSourcePosition));\n    output_init(&parser, KatanaParserModeStylesheet);\n    katanaparse(scanner, &parser);\n    katanalex_destroy(scanner);\n    katana_parser_clear_declarations(&parser);\n    katana_parser_deallocate(&parser, parser.position);\n#if KATANA_PARSER_DEBUG\n    katana_destroy_array(&parser, katana_destroy_selector, parser.parsed_selectors);\n    katana_parser_deallocate(&parser, parser.parsed_selectors);\n#endif // #if KATANA_PARSER_DEBUG\n    parser.scanner = NULL;\n    KatanaOutput* output = parser.output;\n    return output;\n}\n\n\nstatic KatanaOutput* katana_parse_fragment(const char* prefix,\n                                           size_t pre_len,\n                                           const char* str,\n                                           size_t str_len,\n                                           KatanaParserMode mode) {\n    size_t len = pre_len + str_len + 1;\n    char * source = malloc_wrapper(NULL, len);\n    if ( source == NULL )\n        return NULL;\n    memcpy(source, prefix, pre_len);\n    memcpy(source+pre_len, str, str_len);\n    source[pre_len + str_len] = '\\0';\n    KatanaOutput * output = katana_parse_with_options(&kKatanaDefaultOptions, (void*)source, len, mode);\n    free_wrapper(NULL, source);\n    return output;\n}\n\nstatic KatanaOutput* katana_parse_with_options(const KatanaOptions* options,\n                                               yyconst char* bytes,\n                                               size_t len,\n                                               KatanaParserMode mode) {\n    assert(NULL != bytes);\n    if ( NULL == bytes )\n        return NULL;\n    \n    yyscan_t scanner;\n    if (katanalex_init(&scanner)) {\n        katana_print(\"no scanning today!\");\n        return NULL;\n    }\n\n    katana_scan_bytes(bytes, len, scanner);\n    \n    KatanaParser parser;\n    parser.options = options;\n    parser.scanner = &scanner;\n    parser.default_namespace = kKatanaAsteriskString;\n    parser.parsed_declarations = katana_new_array(&parser);\n#if KATANA_PARSER_DEBUG\n    parser.parsed_selectors = katana_new_array(&parser);\n#endif // #if KATANA_PARSER_DEBUG\n    parser.position = katana_parser_allocate(&parser, sizeof(KatanaSourcePosition));\n    output_init(&parser, mode);\n    katanaparse(scanner, &parser);\n    katanalex_destroy(scanner);\n    if ( KatanaParserModeDeclarationList != mode ) {\n        katana_parser_clear_declarations(&parser);\n    }\n    katana_parser_deallocate(&parser, parser.position);\n#if KATANA_PARSER_DEBUG\n    katana_destroy_array(&parser, katana_destroy_selector, parser.parsed_selectors);\n    katana_parser_deallocate(&parser, parser.parsed_selectors);\n#endif // #if KATANA_PARSER_DEBUG\n    parser.scanner = NULL;\n    KatanaOutput* output = parser.output;\n    return output;\n}\n\n\nvoid katana_parse_internal_rule(KatanaParser* parser, KatanaRule* e)\n{\n    parser->output->rule = e;\n}\n\nvoid katana_parse_internal_keyframe_rule(KatanaParser* parser, KatanaKeyframe* e)\n{\n    parser->output->keyframe = e;\n}\n\nvoid katana_parse_internal_keyframe_key_list(KatanaParser* parser, KatanaArray* e)\n{\n    parser->output->keyframe_keys = e;\n}\n\nvoid katana_parse_internal_value(KatanaParser* parser, KatanaArray* e)\n{\n    parser->output->values = e;\n}\n\nvoid katana_parse_internal_media_list(KatanaParser* parser, KatanaArray* e)\n{\n    parser->output->medias = e;\n}\n\nvoid katana_parse_internal_declaration_list(KatanaParser* parser, bool e)\n{\n    parser->output->declarations = parser->parsed_declarations;\n}\n\nvoid katana_parse_internal_selector(KatanaParser* parser, KatanaArray* e)\n{\n    parser->output->selectors = e;\n}\n\n\nKatanaArray* katana_new_array(KatanaParser* parser) {\n    KatanaArray* array = katana_parser_allocate(parser, sizeof(KatanaArray));\n    katana_array_init(parser, 0, array);\n    return array;\n}\n\nvoid katana_destroy_array_using_deallocator(KatanaParser* parser,\n                          KatanaArrayDeallocator callback, KatanaArray* array) {\n    //assert(NULL != array);\n    if ( NULL == array )\n        return;\n    for (size_t i = 0; i < array->length; ++i) {\n        callback(parser, array->data[i]);\n    }\n    katana_array_destroy(parser, array);\n}\n\n\nKatanaStylesheet* katana_new_stylesheet(KatanaParser* parser) {\n    KatanaStylesheet* stylesheet =\n        katana_parser_allocate(parser, sizeof(KatanaStylesheet));\n    stylesheet->encoding = NULL;\n    katana_array_init(parser, 0, &stylesheet->rules);\n    katana_array_init(parser, 0, &stylesheet->imports);\n    return stylesheet;\n}\n\nvoid katana_destroy_stylesheet(KatanaParser* parser, KatanaStylesheet* e)\n{\n    assert(NULL != e);\n    if ( NULL == e )\n        return;\n    \n    // free encoding\n    if ( e->encoding )\n        katana_parser_deallocate(parser, (void*) e->encoding);\n\n    // free imports\n    for (size_t i = 0; i < e->imports.length; ++i) {\n        katana_destroy_import_rule(parser, e->imports.data[i]);\n    }\n    katana_parser_deallocate(parser, (void*) e->imports.data);\n\n    // free rules\n    for (size_t i = 0; i < e->rules.length; ++i) {\n        katana_destroy_rule(parser, e->rules.data[i]);\n    }\n    katana_parser_deallocate(parser, (void*) e->rules.data);\n\n    // free e\n    katana_parser_deallocate(parser, (void*) e);\n}\n\nvoid katana_destroy_rule(KatanaParser* parser, KatanaRule* rule)\n{\n    switch (rule->type) {\n        case KatanaRuleStyle:\n            katana_destroy_style_rule(parser, (KatanaStyleRule*)rule);\n            break;\n        case KatanaRuleImport:\n            katana_destroy_import_rule(parser, (KatanaImportRule*)rule);\n            break;\n        case KatanaRuleFontFace:\n            katana_destroy_font_face_rule(parser, (KatanaFontFaceRule*)rule);\n            break;\n        case KatanaRuleKeyframes:\n            katana_destroy_keyframes_rule(parser, (KatanaKeyframesRule*)rule);\n            break;\n        case KatanaRuleMedia:\n            katana_destroy_media_rule(parser, (KatanaMediaRule*)rule);\n            break;\n            \n        default:\n            break;\n    }\n}\n\nvoid katana_destroy_rule_list(KatanaParser* parser, KatanaArray* rules)\n{\n    katana_destroy_array(parser, katana_destroy_rule, rules);\n    katana_parser_deallocate(parser, (void*) rules);\n}\n\n\nKatanaRule* katana_new_style_rule(KatanaParser* parser, KatanaArray* selectors)\n{\n    assert(NULL != selectors);\n    if ( NULL == selectors )\n        return NULL;\n    \n    KatanaStyleRule* rule = katana_parser_allocate(parser, sizeof(KatanaStyleRule));\n    rule->base.name = \"style\";\n    rule->base.type = KatanaRuleStyle;\n    rule->selectors = selectors;\n    // Do not check parser->parsed_declarations, when we encounter something like `selectors {}`, treat it as valid.\n    rule->declarations = parser->parsed_declarations;\n    katana_parser_reset_declarations(parser);\n    \n    return (KatanaRule*)rule;\n}\n\nvoid katana_destroy_style_rule(KatanaParser* parser, KatanaStyleRule* e)\n{\n    assert(e->selectors->length);\n\n    katana_destroy_array(parser, katana_destroy_selector, e->selectors);\n    katana_parser_deallocate(parser, (void*) e->selectors);\n\n    katana_destroy_array(parser, katana_destroy_declaration, e->declarations);\n    katana_parser_deallocate(parser, (void*) e->declarations);\n    \n    // katana_parser_deallocate(parser, (void*) e->base.name);\n    katana_parser_deallocate(parser, (void*) e);\n}\n\n\nvoid katana_add_namespace(KatanaParser* parser, KatanaParserString* prefix, KatanaParserString* uri)\n{\n    // TODO: No need for right now\n}\n\n\nKatanaRule* katana_new_font_face(KatanaParser* parser)\n{\n    KatanaFontFaceRule* rule = katana_parser_allocate(parser, sizeof(KatanaFontFaceRule));\n    rule->base.name = \"font-face\";\n    rule->base.type = KatanaRuleFontFace;\n    rule->declarations = parser->parsed_declarations;\n\n    katana_parser_reset_declarations(parser);\n    \n    return (KatanaRule*)rule;\n}\n\nvoid katana_destroy_font_face_rule(KatanaParser* parser, KatanaFontFaceRule* e)\n{\n    katana_destroy_array(parser, katana_destroy_declaration, e->declarations);\n    katana_parser_deallocate(parser, (void*) e->declarations);\n    // katana_parser_deallocate(parser, (void*) e->base.name);\n    katana_parser_deallocate(parser, (void*) e);\n}\n\n\nKatanaRule* katana_new_keyframes_rule(KatanaParser* parser, KatanaParserString* name, KatanaArray* keyframes, bool isPrefixed)\n{\n    KatanaKeyframesRule * rule = katana_parser_allocate(parser, sizeof(KatanaKeyframesRule));\n    rule->base.name = \"keyframes\";\n    rule->base.type = KatanaRuleKeyframes;\n    rule->name = katana_string_to_characters(parser, name);\n    rule->keyframes = keyframes;\n    return (KatanaRule*)rule;\n}\n\nvoid katana_destroy_keyframes_rule(KatanaParser* parser, KatanaKeyframesRule * e)\n{\n    katana_parser_clear_keyframes(parser, e->keyframes);\n    katana_parser_deallocate(parser, (void*) e->name);\n    katana_parser_deallocate(parser, (void*) e);\n}\n\nKatanaKeyframe* katana_new_keyframe(KatanaParser* parser, KatanaArray* selectors)\n{\n    KatanaKeyframe* keyframe = katana_parser_allocate(parser, sizeof(KatanaKeyframe));\n    keyframe->selectors = selectors;\n    keyframe->declarations = parser->parsed_declarations;\n    katana_parser_reset_declarations(parser);\n    return keyframe;\n}\n\nvoid katana_destroy_keyframe(KatanaParser* parser, KatanaKeyframe* e)\n{\n    katana_destroy_array(parser, katana_destroy_value, e->selectors);\n    katana_parser_deallocate(parser, (void*) e->selectors);\n    \n    katana_destroy_array(parser, katana_destroy_declaration, e->declarations);\n    katana_parser_deallocate(parser, (void*) e->declarations);\n\n    katana_parser_deallocate(parser, (void*) e);\n}\n\nKatanaArray* katana_new_Keyframe_list(KatanaParser* parser)\n{\n    return katana_new_array(parser);\n}\n\nvoid katana_keyframe_rule_list_add(KatanaParser* parser, KatanaKeyframe* keyframe, KatanaArray* list)\n{\n    assert(keyframe);\n    katana_array_add(parser, keyframe, list);\n}\n\nvoid katana_parser_clear_keyframes(KatanaParser* parser, KatanaArray* keyframes)\n{\n    katana_destroy_array(parser, katana_destroy_keyframe, keyframes);\n    katana_parser_deallocate(parser, (void*) keyframes);\n}\n\n\nvoid katana_set_charset(KatanaParser* parser, KatanaParserString* charset)\n{\n//    parser->output->stylesheet->encoding = katana_string_to_characters(parser, charset);\n}\n\n\nKatanaRule* katana_new_import_rule(KatanaParser* parser, KatanaParserString* href, KatanaArray* media)\n{\n    KatanaImportRule* rule = katana_parser_allocate(parser, sizeof(KatanaImportRule));\n    rule->base.name = \"import\";\n    rule->base.type = KatanaRuleImport;\n    rule->href = katana_string_to_characters(parser, href);\n    rule->medias = media;\n    return (KatanaRule*)rule;\n}\n\nvoid katana_destroy_import_rule(KatanaParser* parser, KatanaImportRule* e)\n{\n    katana_destroy_array(parser, katana_destroy_media_query, e->medias);\n    katana_parser_deallocate(parser, (void*) e->medias);\n    // katana_parser_deallocate(parser, (void*) e->base.name);\n    katana_parser_deallocate(parser, (void*) e->href);\n    katana_parser_deallocate(parser, (void*) e);\n}\n\n\nKatanaValue* katana_new_value(KatanaParser* parser)\n{\n    return katana_parser_allocate(parser, sizeof(KatanaValue));\n}\n\nvoid katana_destroy_value(KatanaParser* parser, KatanaValue* e)\n{\n    switch (e->unit) {\n        case KATANA_VALUE_URI:\n        case KATANA_VALUE_IDENT:\n        case KATANA_VALUE_STRING:\n        case KATANA_VALUE_DIMENSION:\n        case KATANA_VALUE_UNICODE_RANGE:\n        case KATANA_VALUE_PARSER_HEXCOLOR:\n        {\n            katana_parser_deallocate(parser, (void*) e->string);\n        }\n            break;\n        case KATANA_VALUE_PARSER_LIST:\n        {\n            katana_destroy_array(parser, katana_destroy_value, e->list);\n            katana_parser_deallocate(parser, (void*) e->list);\n        }\n            break;\n        case KATANA_VALUE_PARSER_FUNCTION:\n        {\n            katana_destroy_function(parser, e->function);\n        }\n            break;\n        case KATANA_VALUE_NUMBER:\n        case KATANA_VALUE_PERCENTAGE:\n        case KATANA_VALUE_PX:\n        case KATANA_VALUE_CM:\n        case KATANA_VALUE_MM:\n        case KATANA_VALUE_IN:\n        case KATANA_VALUE_PT:\n        case KATANA_VALUE_PC:\n        case KATANA_VALUE_DEG:\n        case KATANA_VALUE_RAD:\n        case KATANA_VALUE_GRAD:\n        case KATANA_VALUE_TURN:\n        case KATANA_VALUE_MS:\n        case KATANA_VALUE_S:\n        case KATANA_VALUE_HZ:\n        case KATANA_VALUE_KHZ:\n        case KATANA_VALUE_EMS:\n        case KATANA_VALUE_PARSER_Q_EMS:\n        case KATANA_VALUE_EXS:\n        case KATANA_VALUE_REMS:\n        case KATANA_VALUE_CHS:\n        case KATANA_VALUE_VW:\n        case KATANA_VALUE_VH:\n        case KATANA_VALUE_VMIN:\n        case KATANA_VALUE_VMAX:\n        case KATANA_VALUE_DPPX:\n        case KATANA_VALUE_DPI:\n        case KATANA_VALUE_DPCM:\n        case KATANA_VALUE_FR:\n            katana_parser_deallocate(parser, (void*) e->raw);\n            break;\n        default:\n            break;\n    }\n    \n    katana_parser_deallocate(parser, (void*) e);\n}\n\nKatanaValueFunction* katana_new_function(KatanaParser* parser, KatanaParserString* name, KatanaArray* args)\n{\n    KatanaValueFunction* func = katana_parser_allocate(parser, sizeof(KatanaValueFunction));\n    func->name = katana_string_to_characters(parser, name);\n    func->args = args;\n    return func;\n}\n\nvoid katana_destroy_function(KatanaParser* parser, KatanaValueFunction* e)\n{\n    katana_destroy_array(parser, katana_destroy_value, e->args);\n    katana_parser_deallocate(parser, (void*) e->args);\n    katana_parser_deallocate(parser, (void*) e->name);\n    katana_parser_deallocate(parser, (void*) e);\n}\n\nKatanaValue* katana_new_number_value(KatanaParser* parser, int sign, KatanaParserNumber* value, KatanaValueUnit unit)\n{\n    KatanaValue* v = katana_new_value(parser);\n    v->id = KatanaValueInvalid;\n    v->isInt = false;\n    v->fValue = sign * value->val;\n    v->unit = unit;\n    if ( 1 == sign ) {\n        v->raw = katana_string_to_characters(parser, &value->raw);\n    } else {\n        v->raw = katana_string_to_characters_with_prefix_char(parser, &value->raw, '-');\n    }\n    return v;\n}\n\nKatanaValue* katana_new_dimension_value(KatanaParser* parser, KatanaParserNumber* value, KatanaValueUnit unit)\n{\n    KatanaValue* v = katana_new_value(parser);\n    v->id = KatanaValueInvalid;\n    v->isInt = false;\n    v->fValue = value->val;\n    v->raw = katana_string_to_characters(parser, &value->raw);\n    v->unit = unit;\n    return v;\n}\n\nKatanaValue* katana_new_operator_value(KatanaParser* parser, int value)\n{\n    KatanaValue* v = katana_new_value(parser);\n    v->id = KatanaValueInvalid;\n    v->isInt = false;\n    v->unit = KATANA_VALUE_PARSER_OPERATOR;\n    v->iValue = value;\n    return v;\n}\n\nKatanaValue* katana_new_ident_value(KatanaParser* parser, KatanaParserString* value)\n{\n    KatanaValue* v = katana_new_value(parser);\n    // is it necessary to do this ?\n    // v.id = cssValueKeywordID(string);\n    v->id = KatanaValueCustom;\n    v->isInt = false;\n    v->unit = KATANA_VALUE_IDENT;\n    v->string = katana_string_to_characters(parser, value);\n    return v;\n}\n\nKatanaValue* katana_new_function_value(KatanaParser* parser, KatanaParserString* name, KatanaArray* args)\n{\n    KatanaValueFunction* func = katana_new_function(parser, name, args);\n    KatanaValue* value = katana_new_value(parser);\n    value->unit = KATANA_VALUE_PARSER_FUNCTION;\n    value->function = func;\n    return value;\n}\n\nKatanaValue* katana_new_list_value(KatanaParser* parser, KatanaArray* list)\n{\n    KatanaValue* value = katana_new_value(parser);\n    value->unit = KATANA_VALUE_PARSER_LIST;\n    value->list = list;\n    return value;\n}\n\nvoid katana_value_set_string(KatanaParser* parser, KatanaValue* value, KatanaParserString* string)\n{\n    value->string = katana_string_to_characters(parser, string);\n}\n\nvoid katana_value_set_sign(KatanaParser* parser, KatanaValue* value, int sign)\n{\n    value->fValue *= sign;\n    \n    if ( sign < 0 ) {\n        const char* raw = value->raw;\n        size_t len = strlen(raw);\n        char* new_str = katana_parser_allocate(parser, sizeof(char) * (len + 2));\n        strcpy(new_str + 1, raw);\n        new_str[0] = '-';\n        new_str[len + 1] = '\\0';\n        value->raw = new_str;\n        katana_parser_deallocate(parser, (void*) raw);\n    }\n}\n\n\nKatanaArray* katana_new_value_list(KatanaParser* parser)\n{\n    return katana_new_array(parser);\n}\n\nvoid katana_value_list_insert(KatanaParser* parser, KatanaValue* value, int index, KatanaArray* list)\n{\n    assert(NULL != value);\n    if ( value == NULL)\n        return;\n    katana_array_insert_at(parser, value, index, list);\n}\n\nvoid katana_value_list_add(KatanaParser* parser, KatanaValue* value, KatanaArray* list)\n{\n    assert(NULL != value);\n    if ( value == NULL)\n        return;\n    katana_array_add(parser, value, list);\n}\n\nvoid katana_value_list_steal_values(KatanaParser* parser, KatanaArray* values, KatanaArray* list)\n{\n    assert(NULL != values && values->length);\n    if ( values == NULL || 0 == values->length )\n        return;\n    for (size_t i = 0; i < values->length; ++i)\n        katana_value_list_add(parser, values->data[i], list);\n    katana_parser_deallocate(parser, (void*) values);\n}\n\n\nbool katana_new_declaration(KatanaParser* parser, KatanaParserString* name, bool important, KatanaArray* values)\n{\n    KatanaDeclaration * decl = katana_parser_allocate(parser, sizeof(KatanaDeclaration));\n    decl->property = katana_string_to_characters(parser, name);\n    decl->important = important;\n    decl->values = values;\n    decl->raw = katana_stringify_value_list(parser, values);\n    katana_array_add(parser, decl, parser->parsed_declarations);\n    \n    return true;\n}\n\nvoid katana_destroy_declaration(KatanaParser* parser, KatanaDeclaration* e)\n{\n    katana_destroy_array(parser, katana_destroy_value, e->values);\n    katana_parser_deallocate(parser, (void*) e->values);\n    katana_parser_deallocate(parser, (void*) e->raw);\n    katana_parser_deallocate(parser, (void*) e->property);\n    katana_parser_deallocate(parser, (void*) e);\n}\n\nvoid katana_parser_clear_declarations(KatanaParser* parser)\n{\n    katana_destroy_array(parser, katana_destroy_declaration, parser->parsed_declarations);\n    katana_parser_deallocate(parser, (void*) parser->parsed_declarations);\n    parser->parsed_declarations = NULL;\n}\n\nvoid katana_parser_reset_declarations(KatanaParser* parser)\n{\n    parser->parsed_declarations = katana_new_array(parser);\n}\n\n\nKatanaRule* katana_new_media_rule(KatanaParser* parser, KatanaArray* medias, KatanaArray* rules)\n{\n//\tassert(NULL != medias && NULL != rules);\n    \n    if ( medias == NULL || rules == NULL )\n        return NULL;\n    \n    KatanaMediaRule* rule = katana_parser_allocate(parser, sizeof(KatanaMediaRule));\n    rule->base.name = \"media\";\n    rule->base.type = KatanaRuleMedia;\n    rule->medias = medias;\n    rule->rules = rules;\n    return (KatanaRule*)rule;\n}\n\nvoid katana_destroy_media_rule(KatanaParser* parser, KatanaMediaRule* e)\n{\n    katana_destroy_media_list(parser, (void*) e->medias);\n    katana_destroy_rule_list(parser,  (void*) e->rules),\n    // katana_parser_deallocate(parser,  (void*) e->base.name);\n    katana_parser_deallocate(parser,  (void*) e);\n}\n\n\nKatanaArray* katana_new_media_list(KatanaParser* parser)\n{\n    return katana_new_array(parser);\n}\n\nvoid katana_media_list_add(KatanaParser* parser, KatanaMediaQuery* media_query, KatanaArray* medias)\n{\n    // debug here\n//    katana_print_media_query(parser, media_query);\n    if ( NULL != media_query ) {\n        katana_array_add(parser, media_query, medias);\n    }\n}\n\nvoid katana_destroy_media_list(KatanaParser* parser, KatanaArray* medias)\n{\n    katana_destroy_array(parser, katana_destroy_media_query, medias);\n    katana_parser_deallocate(parser, (void*) medias);\n}\n\n\nKatanaMediaQuery* katana_new_media_query(KatanaParser* parser, KatanaMediaQueryRestrictor r, KatanaParserString *type, KatanaArray* exps)\n{\n    KatanaMediaQuery* media_query = katana_parser_allocate(parser, sizeof(KatanaMediaQuery));\n    media_query->restrictor = r;\n    media_query->type = type == NULL ? NULL : katana_string_to_characters(parser, type);\n    media_query->expressions = exps;\n    return media_query;\n}\n\nvoid katana_destroy_media_query(KatanaParser* parser, KatanaMediaQuery* e)\n{\n    katana_destroy_array(parser, katana_destroy_media_query_exp, e->expressions);\n    katana_parser_deallocate(parser, (void*) e->expressions);\n    if ( NULL != e->type ) {\n        katana_parser_deallocate(parser, (void*) e->type);\n    }\n    katana_parser_deallocate(parser, (void*) e);\n}\n\n\nKatanaMediaQueryExp * katana_new_media_query_exp(KatanaParser* parser, KatanaParserString* feature, KatanaArray* values)\n{\n    assert( NULL != feature );\n    if ( NULL == feature )\n        return NULL;\n    \n    KatanaMediaQueryExp* exp = katana_parser_allocate(parser, sizeof(KatanaMediaQueryExp));\n    exp->feature = katana_string_to_characters(parser, feature);\n    exp->values = values;\n    exp->raw = katana_stringify_value_list(parser, values);\n    return exp;\n}\n\nvoid katana_destroy_media_query_exp(KatanaParser* parser, KatanaMediaQueryExp* e)\n{\n    if ( NULL != e->values ) {\n        katana_destroy_array(parser, katana_destroy_value, e->values);\n        katana_parser_deallocate(parser, e->values);\n    }\n    katana_parser_deallocate(parser, (void*) e->raw);\n    katana_parser_deallocate(parser, (void*) e->feature);\n    katana_parser_deallocate(parser, (void*) e);\n}\n\n\nvoid katana_media_query_exp_list_add(KatanaParser* parser, KatanaMediaQueryExp* exp, KatanaArray* list)\n{\n    assert(NULL != exp);\n    if ( NULL == exp )\n        return;\n    katana_array_add(parser, exp, list);\n}\n\nKatanaArray* katana_new_media_query_exp_list(KatanaParser* parser)\n{\n    return katana_new_array(parser);\n}\n\n\nKatanaArray* katana_new_rule_list(KatanaParser* parser)\n{\n    return katana_new_array(parser);\n}\n\nKatanaArray* katana_rule_list_add(KatanaParser* parser, KatanaRule* rule, KatanaArray* rule_list)\n{\n    if ( NULL != rule ) {\n        if ( NULL == rule_list )\n            rule_list = katana_new_rule_list(parser);\n        katana_array_add(parser, rule, rule_list);\n    }\n    \n    return rule_list;\n}\n\n\nvoid katana_start_declaration(KatanaParser* parser)\n{\n    katana_parser_log(parser, \"katana_start_declaration\");   \n}\n\nvoid katana_end_declaration(KatanaParser* parser, bool flag, bool ended)\n{\n    katana_parser_log(parser, \"katana_end_declaration\");\n}\n\nvoid katana_set_current_declaration(KatanaParser* parser, KatanaParserString* tag)\n{\n    katana_parser_log(parser, \"katana_set_current_declaration\");\n}\n\n\nvoid katana_start_selector(KatanaParser* parser)\n{\n    katana_parser_log(parser, \"katana_start_selector\");\n}\n\nvoid katana_end_selector(KatanaParser* parser)\n{\n    katana_parser_log(parser, \"katana_end_selector\");\n}\n\nKatanaQualifiedName * katana_new_qualified_name(KatanaParser* parser, KatanaParserString* prefix, KatanaParserString* local, KatanaParserString* uri)\n{\n    KatanaQualifiedName* name = katana_parser_allocate(parser, sizeof(KatanaQualifiedName));\n    name->prefix = prefix == NULL ? NULL : katana_string_to_characters(parser, prefix);\n    name->local = local == NULL ? NULL : katana_string_to_characters(parser, local);\n    name->uri = uri == NULL ? NULL : katana_string_to_characters(parser, uri);\n    return name;\n}\n\nvoid katana_destroy_qualified_name(KatanaParser* parser,  KatanaQualifiedName* e)\n{\n    katana_parser_deallocate(parser, (void*) e->local);\n    katana_parser_deallocate(parser, (void*) e->prefix);\n    katana_parser_deallocate(parser, (void*) e->uri);\n    katana_parser_deallocate(parser, (void*) e);\n}\n\nKatanaSelectorRareData* katana_new_rare_data(KatanaParser* parser)\n{\n    KatanaSelectorRareData* data = katana_parser_allocate(parser, sizeof(KatanaSelectorRareData));\n    data->value = NULL;\n    data->attribute = NULL;\n    data->argument = NULL;\n    data->selectors = NULL;\n    return data;\n}\n\nvoid katana_destroy_rare_data(KatanaParser* parser, KatanaSelectorRareData* e)\n{\n    if ( NULL != e->value )\n        katana_parser_deallocate(parser, (void*) e->value);\n    \n    if ( NULL != e->argument )\n        katana_parser_deallocate(parser, (void*) e->argument);\n    \n    if ( NULL != e->attribute )\n        katana_destroy_qualified_name(parser, e->attribute);\n\n    if ( NULL != e->selectors ) {\n        katana_destroy_array(parser, katana_destroy_selector, e->selectors);\n        katana_parser_deallocate(parser, (void*) e->selectors);\n    }\n    \n    katana_parser_deallocate(parser, e);\n}\n\nKatanaSelector* katana_new_selector(KatanaParser* parser)\n{\n    KatanaSelector* selector = katana_parser_allocate(parser, sizeof(KatanaSelector));\n    selector->data = katana_new_rare_data(parser);\n    selector->tag = NULL;\n    selector->match = 0;\n    selector->pseudo = KatanaPseudoNotParsed;\n    selector->relation = 0;\n    selector->specificity = 0;\n    selector->tag = NULL;\n    selector->tagHistory = NULL;\n#if KATANA_PARSER_DEBUG\n    katana_array_add(parser, selector, parser->parsed_selectors);\n#endif // #if KATANA_PARSER_DEBUG\n    return selector;\n}\n\nKatanaSelector* katana_sink_floating_selector(KatanaParser* parser, KatanaSelector* selector)\n{\n#if KATANA_PARSER_DEBUG\n    katana_array_remove(parser, selector, parser->parsed_selectors);\n#endif // #if KATANA_PARSER_DEBUG\n    return selector;\n}\n\nvoid katana_destroy_one_selector(KatanaParser* parser, KatanaSelector* e)\n{\n    katana_destroy_rare_data(parser, e->data);\n    \n    if ( e->tag  != NULL )\n        katana_destroy_qualified_name(parser, e->tag);\n    \n    katana_parser_deallocate(parser, e);\n}\n\nvoid katana_destroy_selector(KatanaParser* parser, KatanaSelector* e)\n{\n    KatanaSelector *p = e, *q;\n    while ( p ) {\n        q = p->tagHistory;\n        katana_destroy_one_selector(parser, p);\n        p = q;\n    }\n}\n\nKatanaSelector* katana_rewrite_specifier_with_element_name(KatanaParser* parser, KatanaParserString* tag, KatanaSelector* specifier)\n{\n    // TODO: (@QFish) check if css3 support\n    bool supported = true;\n    \n    if ( supported ) {\n        KatanaSelector* prepend = katana_new_selector(parser);\n        prepend->tag = katana_new_qualified_name(parser, NULL, tag, &parser->default_namespace);\n        prepend->match = KatanaSelectorMatchTag;\n        prepend->tagHistory = katana_sink_floating_selector(parser, specifier);\n        prepend->relation = KatanaSelectorRelationSubSelector;\n        return prepend;\n    }\n    \n    return specifier;\n}\n\nKatanaSelector* katana_rewrite_specifier_with_namespace_if_needed(KatanaParser* parser, KatanaSelector* specifiers)\n{\n    // TODO: @(QFish) add logic\n    return specifiers;\n}\n\nKatanaSelector* katana_rewrite_specifiers(KatanaParser* parser, KatanaSelector* specifiers, KatanaSelector* newSpecifier)\n{\n    if (katana_selector_crosses_tree_scopes(newSpecifier)) {\n        // Unknown pseudo element always goes at the top of selector chain.\n        katana_selector_append(parser, newSpecifier, katana_sink_floating_selector(parser, specifiers), KatanaSelectorRelationShadowPseudo);\n        return newSpecifier;\n    }\n    if (katana_selector_is_content_pseudo_element(newSpecifier)) {\n        katana_selector_append(parser, newSpecifier, katana_sink_floating_selector(parser, specifiers), KatanaSelectorRelationSubSelector);\n        return newSpecifier;\n    }\n    if (katana_selector_crosses_tree_scopes(specifiers)) {\n        // Specifiers for unknown pseudo element go right behind it in the chain.\n        katana_selector_insert(parser, specifiers, katana_sink_floating_selector(parser, newSpecifier), KatanaSelectorRelationSubSelector, KatanaSelectorRelationShadowPseudo);\n        return specifiers;\n    }\n    if (katana_selector_is_content_pseudo_element(specifiers)) {\n        katana_selector_insert(parser, specifiers, katana_sink_floating_selector(parser, newSpecifier), KatanaSelectorRelationSubSelector, KatanaSelectorRelationSubSelector);\n        return specifiers;\n    }\n\n    katana_selector_append(parser, specifiers, katana_sink_floating_selector(parser, newSpecifier), KatanaSelectorRelationSubSelector);\n    return specifiers;\n}\n\nvoid katana_adopt_selector_list(KatanaParser* parser, KatanaArray* selectors, KatanaSelector* selector)\n{\n    katana_parser_log(parser, \"katana_adopt_selector_list\");\n    selector->data->selectors = selectors;\n}\n\nvoid katana_selector_append(KatanaParser* parser, KatanaSelector* selector, KatanaSelector* new_selector, KatanaSelectorRelation relation)\n{\n    katana_parser_log(parser, \"katana_selector_append\");\n    KatanaSelector* end = selector;\n    while (NULL != end->tagHistory)\n        end = end->tagHistory;\n    end->relation = relation;\n    end->tagHistory = new_selector;\n}\n\nvoid katana_selector_insert(KatanaParser* parser, KatanaSelector* selector, KatanaSelector* new_selector, KatanaSelectorRelation before, KatanaSelectorRelation after)\n{\n    katana_parser_log(parser, \"katana_selector_insert\");\n\n    if (selector->tagHistory)\n        new_selector->tagHistory = selector;\n    selector->relation = before;\n    new_selector->relation = after;\n    selector->tagHistory = selector;\n}\n\nvoid katana_selector_prepend_with_element_name(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* tag)\n{\n    katana_parser_log(parser, \"katana_selector_prepend_with_element_name\");\n\n    KatanaSelector* prev = katana_new_selector(parser);\n    prev->tag = katana_new_qualified_name(parser, NULL, tag, &parser->default_namespace);\n    selector->tagHistory = prev;\n    selector->relation = KatanaSelectorRelationSubSelector;\n}\n\nKatanaArray* katana_new_selector_list(KatanaParser* parser)\n{\n    return katana_new_array(parser);\n}\n\nKatanaArray* katana_reusable_selector_list(KatanaParser* parser)\n{\n    return katana_new_array(parser);\n}\n\nvoid katana_selector_list_shink(KatanaParser* parser, int capacity, KatanaArray* list)\n{\n\n}\n\nvoid katana_selector_list_add(KatanaParser* parser, KatanaSelector* selector, KatanaArray* list)\n{\n    assert(NULL != selector);\n    if ( NULL == selector )\n        return;\n        \n    katana_array_add(parser, selector, list);\n}\n\nvoid katana_selector_set_value(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* value)\n{\n    selector->data->value = katana_string_to_characters(parser, value);\n}\n\nvoid katana_selector_set_argument_with_number(KatanaParser* parser, KatanaSelector* selector, int sign, KatanaParserNumber* value)\n{\n    if ( 1 == sign ) {\n        selector->data->argument = katana_string_to_characters(parser, &value->raw);\n    } else {\n        selector->data->argument = katana_string_to_characters_with_prefix_char(parser, &value->raw, '-');\n    }\n}\n\nvoid katana_selector_set_argument(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* argument)\n{\n    selector->data->argument = katana_string_to_characters(parser, argument);\n}\n\nbool katana_parse_attribute_match_type(KatanaParser* parser, KatanaAttributeMatchType type, KatanaParserString* attr)\n{\n    return true;\n}\n\nbool katana_selector_is_simple(KatanaParser* parser, KatanaSelector* selector)\n{\n    if (NULL != selector->data->selectors)\n        return false;\n    \n    if (NULL == selector->tagHistory)\n        return true;\n    // TODO: @(QFish) check more.\n    return false;\n}\n\n\nvoid katana_add_rule(KatanaParser* parser, KatanaRule* rule)\n{\n    assert( NULL != rule );\n    if ( NULL == rule )\n        return;\n    \n    switch ( rule->type ) {\n        case KatanaRuleImport:\n            katana_array_add(parser, rule, &parser->output->stylesheet->imports);\n            break;\n        default:\n            katana_array_add(parser, rule, &parser->output->stylesheet->rules);\n            break;\n    }\n}\n\nvoid katana_start_rule(KatanaParser* parser)\n{\n    katana_parser_log(parser, \"katana_start_rule\");\n}\n\nvoid katana_end_rule(KatanaParser* parser, bool ended)\n{\n    katana_parser_log(parser, \"katana_end_rule\");\n}\n\nvoid katana_start_rule_header(KatanaParser* parser, KatanaRuleType type)\n{\n    katana_parser_log(parser, \"katana_start_rule_header\");\n}\n\nvoid katana_end_rule_header(KatanaParser* parser)\n{\n    katana_parser_log(parser, \"katana_end_rule_header\");\n}\n\nvoid katana_end_invalid_rule_header(KatanaParser* parser)\n{\n    katana_parser_log(parser, \"katana_end_invalid_rule_header\");\n}\n\nvoid katana_start_rule_body(KatanaParser* parser)\n{\n    katana_parser_log(parser, \"katana_start_rule_body\");\n}\n\n\nbool katana_string_is_function(KatanaParserString* string)\n{\n    return string && (string->length > 0) && (string->data[string->length - 1] == '(');\n}\n\nvoid katana_string_clear(KatanaParser* parser, KatanaParserString* string)\n{\n\tprintf(\"==%s==\\n\", string->data);\n    katana_parser_deallocate(parser, (void*) string->data);\n    katana_parser_deallocate(parser, (void*) string);\n}\n\n\nvoid katanaerror(YYLTYPE* yyloc, void* scanner, struct KatanaInternalParser * parser, char* error)\n{\n#ifdef KATANA_PARSER_DEBUG\n#if KATANA_PARSER_DEBUG\n    katana_print(\"[Error] %d.%d - %d.%d: %s at %s\\n\",\n           yyloc->first_line,\n           yyloc->first_column,\n           yyloc->last_line,\n           yyloc->last_column,\n           error,\n           katanaget_text(parser->scanner));\n\n    YYSTYPE * s = katanaget_lval(parser->scanner);\n\n//\tstruct yy_buffer_state state = katana_get_previous_state(parser->scanner);\n//    s, (*yy_buffer_stack[0]).yy_ch_buf);\n//    \n//    katana_print(\"%s\", s->);\n#endif // #if KATANA_PARSER_DEBUG\n#endif // #ifdef KATANA_PARSER_DEBUG\n\n    KatanaError *e = (KatanaError *)malloc(sizeof(KatanaError));\n    e->type = KatanaParseError;\n    e->first_line = yyloc->first_line;\n    e->first_column = yyloc->first_column;\n    e->last_line = yyloc->last_line;\n    e->last_column = yyloc->last_column;\n    snprintf(e->message, KATANA_ERROR_MESSAGE_SIZE, \"%s at %s\", error,\n             katanaget_text(parser->scanner));\n    katana_array_add(parser, e, &(parser->output->errors));\n}\n\nvoid katana_parser_log(KatanaParser* parser, const char * format, ...)\n{\n#ifdef KATANA_PARSER_LOG_ENABLE\n#if KATANA_PARSER_LOG_ENABLE\n    va_list args;\n    va_start(args, format);\n    printf(\" -> \");\n    vprintf(format, args);\n    printf(\"\\n\");\n    va_end(args);\n    fflush(stdout);\n#endif // #if KATANA_PARSER_LOG_ENABLE\n#endif // #ifdef KATANA_PARSER_LOG_ENABLE\n}\n\nvoid katana_parser_resume_error_logging()\n{\n    \n}\n\nvoid katana_parser_report_error(KatanaParser* parser, KatanaSourcePosition* pos, const char* format, ...)\n{\n#ifdef KATANA_PARSER_DEBUG\n#if KATANA_PARSER_DEBUG\n    printf(\"[ERROR] %d.%d - %d.%d : \", pos->line, pos->column, katanaget_lineno(*parser->scanner), katanaget_column(*parser->scanner) );\n    va_list args;\n    va_start(args, format);\n    vprintf(format, args);\n    va_end(args);\n    printf(\"\\n\");\n    fflush(stdout);\n#endif // #if KATANA_PARSER_DEBUG\n#endif // #ifdef KATANA_PARSER_DEBUG\n}\n\n\nvoid katana_print_position(YYLTYPE* yyloc)\n{\n    katana_print(NULL,\n                 \"Loaction %d.%d - %d.%d\",\n                 yyloc->first_line,\n                 yyloc->first_column,\n                 yyloc->last_line,\n                 yyloc->last_column\n                 );\n}\n\nKatanaSourcePosition* katana_parser_current_location(KatanaParser* parser, YYLTYPE* yylloc)\n{\n    parser->position->line = katanaget_lineno(*parser->scanner);\n    parser->position->column = katanaget_column(*parser->scanner);\n    //    katana_print_position(yylloc);\n    return parser->position;\n}\n\n\nvoid katana_print(const char * format, ...)\n{\n    va_list args;\n    va_start(args, format);\n    vprintf(format, args);\n\tprintf(\"\\n\");\n    va_end(args);\n    fflush(stdout);\n}\n\nvoid katana_print_stylesheet(KatanaParser* parser, KatanaStylesheet* sheet)\n{\n    katana_print(\"stylesheet with \");\n    katana_print(\"%d rules.\\n\", sheet->rules.length);\n    for (size_t i = 0; i < sheet->imports.length; ++i) {\n        katana_print_rule(parser, sheet->imports.data[i]);\n    }\n    for (size_t i = 0; i < sheet->rules.length; ++i) {\n        katana_print_rule(parser, sheet->rules.data[i]);\n    }\n    katana_print(\"\\n\");\n}\n\nvoid katana_print_rule(KatanaParser* parser, KatanaRule* rule)\n{\n    if ( NULL == rule ) {\n        breakpoint;\n        return;\n    }\n    \n    switch (rule->type) {\n        case KatanaRuleStyle:\n            katana_print_style_rule(parser, (KatanaStyleRule*)rule);\n            break;\n        case KatanaRuleImport:\n            katana_print_import_rule(parser, (KatanaImportRule*)rule);\n            break;\n        case KatanaRuleFontFace:\n            katana_print_font_face_rule(parser, (KatanaFontFaceRule*)rule);\n            break;\n        case KatanaRuleKeyframes:\n            katana_print_keyframes_rule(parser, (KatanaKeyframesRule*)rule);\n            break;\n        case KatanaRuleMedia:\n            katana_print_media_rule(parser, (KatanaMediaRule*)rule);\n            break;\n        case KatanaRuleSupports:\n            break;\n        case KatanaRuleUnkown:\n            break;\n            \n        default:\n            break;\n    }\n}\n\nvoid katana_print_import_rule(KatanaParser* parser, KatanaImportRule* rule)\n{\n    katana_print(\"@%s \", rule->base.name);\n    katana_print(\"url(%s)\", rule->href);\n    katana_print(\";\\n\");\n}\n\nvoid katana_print_keyframes_rule(KatanaParser* parser, KatanaKeyframesRule* rule)\n{\n    katana_print(\"@%s \", rule->base.name);\n    katana_print(\"%s {\\n\", rule->name);\n    for (size_t i = 0; i < rule->keyframes->length; ++i) {\n        katana_print_keyframe(parser, rule->keyframes->data[i]);\n    }\n    katana_print(\"}\\n\");\n}\n\nvoid katana_print_keyframe(KatanaParser* parser, KatanaKeyframe* keyframe)\n{\n    assert( NULL != keyframe );\n    if ( NULL == keyframe )\n        return;\n    \n    for (size_t i = 0; i < keyframe->selectors->length; ++i) {\n        KatanaValue* value = keyframe->selectors->data[i];\n        if ( value->unit == KATANA_VALUE_NUMBER ) {\n            katana_print(\"%s\", value->raw);\n        }\n        if ( i != keyframe->selectors->length -1 ) {\n            katana_print(\", \");\n        }\n    }\n    katana_print(\" {\\n\");\n    katana_print_declaration_list(parser, keyframe->declarations);\n    katana_print(\"}\\n\");\n}\n\nvoid katana_print_media_query_exp(KatanaParser* parser, KatanaMediaQueryExp* exp)\n{\n    katana_print(\"(\");\n    if (NULL != exp->feature) {\n        katana_print(\"%s\", exp->feature);\n    }\n    if ( exp->values && exp->values->length ) {\n        const char* str = katana_stringify_value_list(parser, exp->values);\n        katana_print(\": %s\", str);\n        katana_parser_deallocate(parser, (void*) str);\n    }\n    katana_print(\")\");\n}\n\nvoid katana_print_media_query(KatanaParser* parser, KatanaMediaQuery* query)\n{\n    // For now ignored is always false\n//    if ( !query->ignored ) {\n        // print restrictor\n        switch ( query->restrictor ) {\n            case KatanaMediaQueryRestrictorOnly:\n                katana_print(\"only \");\n                break;\n            case KatanaMediaQueryRestrictorNot:\n                katana_print(\"not \");\n                break;\n            case KatanaMediaQueryRestrictorNone:\n                break;\n        }\n        \n        if ( NULL == query->expressions || 0 == query->expressions->length ) {\n            if ( NULL != query->type ) {\n                katana_print(\"%s\", query->type);\n            }\n            return;\n        }\n        \n        if ( (NULL != query->type && strcasecmp(query->type, \"all\")) || query->restrictor != KatanaMediaQueryRestrictorNone) {\n            if ( NULL != query->type ) {\n                katana_print(\"%s\", query->type);\n            }\n            katana_print(\" and \");\n        }\n        \n        katana_print_media_query_exp(parser, query->expressions->data[0]);\n        \n        for (size_t i = 1; i < query->expressions->length; ++i) {\n            katana_print(\" and \");\n            katana_print_media_query_exp(parser, query->expressions->data[i]);\n        }\n//    } else {\n//        // If query is invalid, serialized text should turn into \"not all\".\n//        katana_print(\"not all\");\n//    }\n}\n\nvoid katana_print_media_list(KatanaParser* parser, KatanaArray* medias)\n{\n    bool first = true;\n    for (size_t i = 0; i < medias->length; ++i) {\n        if (!first)\n            katana_print(\", \");\n        else\n            first = false;\n        katana_print_media_query(parser, (KatanaMediaQuery*)medias->data[i]);\n    }\n}\n\nvoid katana_print_media_rule(KatanaParser* parser, KatanaMediaRule* rule)\n{\n    katana_print(\"@%s \", rule->base.name);\n    \n    if ( rule->medias->length ) {\n        katana_print_media_list(parser, rule->medias);\n    }\n    \n    if ( rule->medias->length ) {\n        katana_print(\" {\\n\");\n        for (size_t i = 0; i < rule->rules->length; ++i) {\n            katana_print_style_rule(parser, rule->rules->data[i]);\n        }\n        katana_print(\"}\\n\");\n    } else {\n        katana_print(\";\\n\");\n    }\n}\n\nvoid katana_print_selector(KatanaParser* parser, KatanaSelector* selector)\n{\n    KatanaParserString * string = katana_selector_to_string(parser, selector, NULL);\n    const char* text = katana_string_to_characters(parser, string);\n    katana_parser_deallocate(parser, (void*) string->data);\n    katana_parser_deallocate(parser, (void*) string);\n    katana_print(\"%s\", text);\n    katana_parser_deallocate(parser, (void*) text);\n}\n\nvoid katana_print_selector_list(KatanaParser* parser, KatanaArray* selectors)\n{\n    for (size_t i = 0; i < selectors->length; ++i) {\n        katana_print_selector(parser, selectors->data[i]);\n        if ( i != selectors->length -1 ) {\n            katana_print(\",\\n\");\n        }\n    }\n}\n\nvoid katana_print_style_rule(KatanaParser* parser, KatanaStyleRule* rule)\n{\n    katana_print_selector_list(parser, rule->selectors);\n    katana_print(\" {\\n\");\n    \n    if ( rule->declarations->length ) {\n        katana_print_declaration_list(parser, rule->declarations);\n    } else {\n        katana_print(\"  /*no rule*/\\n\");\n    }\n    \n    katana_print(\"}\\n\");\n}\n\nvoid katana_print_declaration(KatanaParser* parser, KatanaDeclaration* decl)\n{\n    const char* str = katana_stringify_value_list(parser, decl->values);\n    katana_print(\"%s: %s\", decl->property, str);\n    katana_parser_deallocate(parser, (void*) str);\n    if ( decl->important ) {\n        katana_print(\" !important\");\n    }\n}\n\nvoid katana_print_declaration_list(KatanaParser* parser, KatanaArray* declarations)\n{\n    for (size_t i = 0; i < declarations->length; ++i) {\n        katana_print(\"  \");\n        katana_print_declaration(parser, declarations->data[i]);\n        katana_print(\";\\n\");\n    }\n}\n\nvoid katana_print_value_list(KatanaParser* parser, KatanaArray* values)\n{\n    const char* str = katana_stringify_value_list(parser, values);\n    katana_print(\"%s\", str);\n    katana_parser_deallocate(parser, (void*) str);\n}\n\nvoid katana_print_font_face_rule(KatanaParser* parser, KatanaFontFaceRule* rule)\n{\n    katana_print(\"@%s {\", rule->base.name);\n    katana_print_declaration_list(parser, rule->declarations);\n    katana_print(\"}\\n\");\n}\n\nKatanaOutput* katana_dump_output(KatanaOutput* output)\n{\n    if ( NULL == output )\n        return output;\n    \n    KatanaParser parser;\n    parser.options = &kKatanaDefaultOptions;\n\n    switch (output->mode) {\n        case KatanaParserModeStylesheet:\n            katana_print_stylesheet(&parser, output->stylesheet);\n            break;\n        case KatanaParserModeRule:\n            katana_print_rule(&parser, output->rule);\n            break;\n        case KatanaParserModeKeyframeRule:\n            katana_print_keyframe(&parser, output->keyframe);\n            break;\n        case KatanaParserModeKeyframeKeyList:\n            katana_print_value_list(&parser, output->keyframe_keys);\n            break;\n        case KatanaParserModeMediaList:\n            katana_print_media_list(&parser, output->medias);\n            break;\n        case KatanaParserModeValue:\n            katana_print_value_list(&parser, output->values);\n            break;\n        case KatanaParserModeSelector:\n            katana_print_selector_list(&parser, output->selectors);\n            break;\n        case KatanaParserModeDeclarationList:\n            katana_print_declaration_list(&parser, output->declarations);\n            break;\n    }\n    katana_print(\"\\n\");\n    return output;\n}\n\n\nstatic const char* katana_stringify_value_list(KatanaParser* parser, KatanaArray* values)\n{\n    if (NULL == values)\n        return NULL;\n    KatanaParserString * buffer = katana_parser_allocate(parser, sizeof(KatanaParserString));\n    katana_string_init(parser, buffer);\n    for (size_t i = 0; i < values->length; ++i) {\n        KatanaValue* value = values->data[i];\n        const char* value_str = katana_stringify_value(parser, value);\n        katana_string_append_characters(parser, value_str, buffer);\n        katana_parser_deallocate(parser, (void*) value_str);\n        value_str = NULL;\n        if ( i < values->length - 1 ) {\n            if ( value->unit != KATANA_VALUE_PARSER_OPERATOR ) {\n                if ( i < values->length - 2 ) {\n                    value = values->data[i+1];\n                    if ( value->unit != KATANA_VALUE_PARSER_OPERATOR ) {\n                        katana_string_append_characters(parser, \" \", buffer);\n                    }\n                } else {\n                    katana_string_append_characters(parser, \" \", buffer);\n                }\n            }\n        }\n    }\n    const char * str = katana_string_to_characters(parser, (KatanaParserString*)buffer);\n    katana_parser_deallocate(parser, buffer->data);\n    katana_parser_deallocate(parser, (void*) buffer);\n    return str;\n}\n\nstatic const char* katana_stringify_value(KatanaParser* parser, KatanaValue* value)\n{\n    // TODO: @(QFish) Handle this more gracefully X).\n    char str[256];\n    \n    switch (value->unit) {\n        case KATANA_VALUE_NUMBER:\n        case KATANA_VALUE_PERCENTAGE:\n        case KATANA_VALUE_EMS:\n        case KATANA_VALUE_EXS:\n        case KATANA_VALUE_REMS:\n        case KATANA_VALUE_CHS:\n        case KATANA_VALUE_PX:\n        case KATANA_VALUE_CM:\n        case KATANA_VALUE_DPPX:\n        case KATANA_VALUE_DPI:\n        case KATANA_VALUE_DPCM:\n        case KATANA_VALUE_MM:\n        case KATANA_VALUE_IN:\n        case KATANA_VALUE_PT:\n        case KATANA_VALUE_PC:\n        case KATANA_VALUE_DEG:\n        case KATANA_VALUE_RAD:\n        case KATANA_VALUE_GRAD:\n        case KATANA_VALUE_MS:\n        case KATANA_VALUE_S:\n        case KATANA_VALUE_HZ:\n        case KATANA_VALUE_KHZ:\n        case KATANA_VALUE_TURN:\n            snprintf(str, sizeof(str), \"%s\", value->raw);\n            break;\n        case KATANA_VALUE_IDENT:\n            snprintf(str, sizeof(str), \"%s\", value->string);\n            break;\n        case KATANA_VALUE_STRING:\n            // FIXME: @(QFish) Do we need double quote or not ?\n//            snprintf(str, sizeof(str), \"\\\"%s\\\"\", value->string);\n            snprintf(str, sizeof(str), \"%s\", value->string);\n            break;\n        case KATANA_VALUE_PARSER_FUNCTION:\n        {\n            const char* args_str = katana_stringify_value_list(parser, value->function->args);\n            snprintf(str, sizeof(str), \"%s%s)\", value->function->name, args_str);\n            katana_parser_deallocate(parser, (void*) args_str);\n            break;\n        }\n        case KATANA_VALUE_PARSER_OPERATOR:\n            if (value->iValue != '=') {\n                snprintf(str, sizeof(str), \" %c \", value->iValue);\n            } else {\n                snprintf(str, sizeof(str), \" %c\", value->iValue);\n            }\n            break;\n        case KATANA_VALUE_PARSER_LIST:\n            return katana_stringify_value_list(parser, value->list);\n            break;\n        case KATANA_VALUE_PARSER_HEXCOLOR:\n            snprintf(str, sizeof(str), \"#%s\", value->string);\n            break;\n        case KATANA_VALUE_URI:\n            snprintf(str, sizeof(str), \"url(%s)\", value->string);\n            break;\n        default:\n            katana_print(\"KATANA: Unknown Value unit.\");\n            break;\n    }\n\n    size_t len = strlen(str);\n    char* dest = katana_parser_allocate(parser, len+1);\n    strcpy(dest, str);\n    dest[len] = '\\0';\n    return dest;\n}\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/selector.c",
    "content": "/**\n * Copyright (c) 2015 QFish <im@qfi.sh>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n#include \"selector.h\"\n#include <string.h>\n#include <assert.h>\n#include <strings.h>\n\n#undef\tassert\n#define assert(x)\n\n// Refs:\n// http://www.w3.org/TR/css3-selectors/\n//\n\nstatic KatanaPseudoType name_to_pseudo_type(const char* name, bool hasArguments);\n\nbool katana_selector_crosses_tree_scopes(const KatanaSelector* selector)\n{\n    // TODO: To be supported\n    return false;\n}\n\n// bool katana_is_attribute_selector(const KatanaSelector* selector)\n// {\n//     return selector->match == KatanaSelectorMatchAttributeExact\n//     || selector->match == KatanaSelectorMatchAttributeSet\n//     || selector->match == KatanaSelectorMatchAttributeList\n//     || selector->match == KatanaSelectorMatchAttributeHyphen\n//     || selector->match == KatanaSelectorMatchAttributeContain\n//     || selector->match == KatanaSelectorMatchAttributeBegin\n//     || selector->match == KatanaSelectorMatchAttributeEnd;\n// }\n\nKatanaPseudoType katana_parse_pseudo_type(const char* name, bool hasArguments)\n{\n    KatanaPseudoType pseudoType = name_to_pseudo_type(name, hasArguments);\n    if (pseudoType != KatanaPseudoUnknown)\n        return pseudoType;\n    \n    if (katana_string_has_prefix(name, \"-webkit-\"))\n        return KatanaPseudoWebKitCustomElement;\n    \n    return KatanaPseudoUnknown;\n}\n\nvoid katana_selector_extract_pseudo_type(KatanaSelector* selector)\n{\n    if (selector->pseudo == KatanaPseudoNotParsed)\n        selector->pseudo = KatanaPseudoUnknown;\n    \n    if (selector->match != KatanaSelectorMatchPseudoClass && selector->match != KatanaSelectorMatchPseudoElement && selector->match != KatanaSelectorMatchPagePseudoClass)\n        return;\n    bool hasArguments = (NULL != selector->data->argument) || (NULL != selector->data->selectors);    \n    selector->pseudo = katana_parse_pseudo_type(selector->data->value, hasArguments);\n    \n    bool element = false; // pseudo-element\n    bool compat = false; // single colon compatbility mode\n    bool isPagePseudoClass = false; // Page pseudo-class\n    \n    switch (selector->pseudo) {\n        case KatanaPseudoAfter:\n        case KatanaPseudoBefore:\n        case KatanaPseudoFirstLetter:\n        case KatanaPseudoFirstLine:\n            compat = true;\n        case KatanaPseudoBackdrop:\n        case KatanaPseudoCue:\n        case KatanaPseudoResizer:\n        case KatanaPseudoScrollbar:\n        case KatanaPseudoScrollbarCorner:\n        case KatanaPseudoScrollbarButton:\n        case KatanaPseudoScrollbarThumb:\n        case KatanaPseudoScrollbarTrack:\n        case KatanaPseudoScrollbarTrackPiece:\n        case KatanaPseudoSelection:\n        case KatanaPseudoWebKitCustomElement:\n        case KatanaPseudoContent:\n        case KatanaPseudoShadow:\n            element = true;\n            break;\n        case KatanaPseudoUnknown:\n        case KatanaPseudoEmpty:\n        case KatanaPseudoFirstChild:\n        case KatanaPseudoFirstOfType:\n        case KatanaPseudoLastChild:\n        case KatanaPseudoLastOfType:\n        case KatanaPseudoOnlyChild:\n        case KatanaPseudoOnlyOfType:\n        case KatanaPseudoNthChild:\n        case KatanaPseudoNthOfType:\n        case KatanaPseudoNthLastChild:\n        case KatanaPseudoNthLastOfType:\n        case KatanaPseudoLink:\n        case KatanaPseudoVisited:\n        case KatanaPseudoAny:\n        case KatanaPseudoAnyLink:\n        case KatanaPseudoAutofill:\n        case KatanaPseudoHover:\n        case KatanaPseudoDrag:\n        case KatanaPseudoFocus:\n        case KatanaPseudoActive:\n        case KatanaPseudoChecked:\n        case KatanaPseudoEnabled:\n        case KatanaPseudoFullPageMedia:\n        case KatanaPseudoDefault:\n        case KatanaPseudoDisabled:\n        case KatanaPseudoOptional:\n        case KatanaPseudoRequired:\n        case KatanaPseudoReadOnly:\n        case KatanaPseudoReadWrite:\n        case KatanaPseudoScope:\n        case KatanaPseudoValid:\n        case KatanaPseudoInvalid:\n        case KatanaPseudoIndeterminate:\n        case KatanaPseudoTarget:\n        case KatanaPseudoLang:\n        case KatanaPseudoNot:\n        case KatanaPseudoRoot:\n        case KatanaPseudoWindowInactive:\n        case KatanaPseudoCornerPresent:\n        case KatanaPseudoDecrement:\n        case KatanaPseudoIncrement:\n        case KatanaPseudoHorizontal:\n        case KatanaPseudoVertical:\n        case KatanaPseudoStart:\n        case KatanaPseudoEnd:\n        case KatanaPseudoDoubleButton:\n        case KatanaPseudoSingleButton:\n        case KatanaPseudoNoButton:\n        case KatanaPseudoNotParsed:\n        case KatanaPseudoFullScreen:\n        case KatanaPseudoFullScreenDocument:\n        case KatanaPseudoFullScreenAncestor:\n        case KatanaPseudoInRange:\n        case KatanaPseudoOutOfRange:\n        case KatanaPseudoFutureCue:\n        case KatanaPseudoPastCue:\n        case KatanaPseudoHost:\n        case KatanaPseudoHostContext:\n        case KatanaPseudoUnresolved:\n        case KatanaPseudoSpatialNavigationFocus:\n        case KatanaPseudoListBox:\n            break;\n        case KatanaPseudoFirstPage:\n        case KatanaPseudoLeftPage:\n        case KatanaPseudoRightPage:\n            isPagePseudoClass = true;\n            break;\n    }\n    \n    bool matchPagePseudoClass = (selector->match == KatanaSelectorMatchPagePseudoClass);\n    if (matchPagePseudoClass != isPagePseudoClass)\n        selector->pseudo = KatanaPseudoUnknown;\n    else if (selector->match == KatanaSelectorMatchPseudoClass && element) {\n        if (!compat)\n            selector->pseudo = KatanaPseudoUnknown;\n        else\n            selector->match = KatanaSelectorMatchPseudoElement;\n    } else if (selector->match == KatanaSelectorMatchPseudoElement && !element)\n        selector->pseudo = KatanaPseudoUnknown;\n}\n\nbool katana_selector_matches_pseudo_element(KatanaSelector* selector)\n{\n    if (selector->pseudo == KatanaPseudoUnknown)\n        katana_selector_extract_pseudo_type(selector);\n    return selector->match == KatanaSelectorMatchPseudoElement;\n}\n\nbool katana_selector_is_custom_pseudo_element(KatanaSelector* selector)\n{\n    return selector->match == KatanaSelectorMatchPseudoElement && selector->pseudo == KatanaPseudoWebKitCustomElement;\n}\n\nbool katana_selector_is_direct_adjacent(KatanaSelector* selector)\n{\n    return selector->relation == KatanaSelectorRelationDirectAdjacent || selector->relation == KatanaSelectorRelationIndirectAdjacent;\n}\n\nbool katana_selector_is_adjacent(KatanaSelector* selector)\n{\n    return selector->relation == KatanaSelectorRelationDirectAdjacent;\n}\n\nbool katana_selector_is_shadow(KatanaSelector* selector)\n{\n    return selector->relation == KatanaSelectorRelationShadowPseudo || selector->relation == KatanaSelectorRelationShadowDeep;\n}\n\nbool katana_selector_is_sibling(KatanaSelector* selector)\n{\n    katana_selector_extract_pseudo_type(selector);\n\n    KatanaPseudoType type = selector->pseudo;\n    return selector->relation == KatanaSelectorRelationDirectAdjacent\n        || selector->relation == KatanaSelectorRelationIndirectAdjacent\n        || type == KatanaPseudoEmpty\n        || type == KatanaPseudoFirstChild\n        || type == KatanaPseudoFirstOfType\n        || type == KatanaPseudoLastChild\n        || type == KatanaPseudoLastOfType\n        || type == KatanaPseudoOnlyChild\n        || type == KatanaPseudoOnlyOfType\n        || type == KatanaPseudoNthChild\n        || type == KatanaPseudoNthOfType\n        || type == KatanaPseudoNthLastChild\n        || type == KatanaPseudoNthLastOfType;\n}\n\nbool katana_selector_is_attribute(const KatanaSelector* selector)\n{\n    return selector->match >= KatanaSelectorMatchFirstAttribute;\n}\n\nbool katana_selector_is_content_pseudo_element(KatanaSelector* selector)\n{\n    katana_selector_extract_pseudo_type(selector);\n    return selector->match == KatanaSelectorMatchPseudoElement && selector->pseudo == KatanaPseudoContent;\n}\n\nbool katana_selector_is_shadow_pseudo_element(KatanaSelector* selector)\n{\n    return selector->match == KatanaSelectorMatchPseudoElement\n            && selector->pseudo == KatanaPseudoShadow;\n}\n\nbool katana_selector_is_host_pseudo_class(KatanaSelector* selector)\n{\n    return selector->match == KatanaSelectorMatchPseudoClass && (selector->pseudo == KatanaPseudoHost || selector->pseudo == KatanaPseudoHostContext);\n}\n\nbool katana_selector_is_tree_boundary_crossing(KatanaSelector* selector)\n{\n    katana_selector_extract_pseudo_type(selector);\n    return selector->match == KatanaSelectorMatchPseudoClass && (selector->pseudo == KatanaPseudoHost || selector->pseudo == KatanaPseudoHostContext);\n}\n\nbool katana_selector_is_insertion_point_crossing(KatanaSelector* selector)\n{\n    katana_selector_extract_pseudo_type(selector);\n    return (selector->match == KatanaSelectorMatchPseudoClass && selector->pseudo == KatanaPseudoHostContext)\n        || (selector->match == KatanaSelectorMatchPseudoElement && selector->pseudo == KatanaPseudoContent);\n}\n\nKatanaParserString* katana_build_relation_selector_string(KatanaParser* parser, const char* relation, KatanaParserString* string, KatanaParserString* next, KatanaSelector* tagHistory)\n{\n    if ( NULL != relation ) {\n        katana_string_prepend_characters(parser, relation, string);\n    }\n    \n    if ( NULL != next ) {\n        katana_string_append_string(parser, next, string);\n    }\n    \n    KatanaParserString * result = katana_selector_to_string(parser, tagHistory, (KatanaParserString*)string);\n    katana_parser_deallocate(parser, (void*) string->data);\n    katana_parser_deallocate(parser, (void*) string);\n    return result;\n}\n\nKatanaParserString* katana_selector_to_string(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* next)\n{\n    KatanaParserString* string = katana_parser_allocate(parser, sizeof(KatanaParserString));\n    katana_string_init(parser, string);\n    \n    bool tag_is_implicit = true;\n    \n    if (selector->match == KatanaSelectorMatchTag && tag_is_implicit)\n    {\n        if ( NULL == selector->tag->prefix )\n            katana_string_append_characters(parser, selector->tag->local, string);\n        else {\n            katana_string_append_characters(parser, selector->tag->prefix, string);\n            katana_string_append_characters(parser, \"|\", string);\n            katana_string_append_characters(parser, selector->tag->local, string);\n        }\n    }\n\n    const KatanaSelector* cs = selector;\n\n    while (true) {\n        if (cs->match == KatanaSelectorMatchId) {\n            katana_string_append_characters(parser, \"#\", string);\n            katana_string_append_characters(parser, cs->data->value, string);\n        } else if (cs->match == KatanaSelectorMatchClass) {\n            katana_string_append_characters(parser, \".\", string);\n            katana_string_append_characters(parser, cs->data->value, string);\n        } else if (cs->match == KatanaSelectorMatchPseudoClass || cs->match == KatanaSelectorMatchPagePseudoClass) {\n            katana_string_append_characters(parser, \":\", string);\n            katana_string_append_characters(parser, cs->data->value, string);\n            \n            switch (cs->pseudo) {\n                case KatanaPseudoAny:\n                case KatanaPseudoNot:\n                case KatanaPseudoHost:\n                case KatanaPseudoHostContext: {\n                    if ( cs->data->selectors ) {\n                        KatanaArray* sels = cs->data->selectors;\n                        for (size_t i=0; i<sels->length; i++) {\n                            KatanaParserString* str = katana_selector_to_string(parser, sels->data[i], NULL);\n                            katana_string_append_string(parser, str, string);\n                            katana_parser_deallocate(parser, (void*) str->data);\n                            katana_parser_deallocate(parser, (void*) str);\n                            if ( i != sels->length -1 ) {\n                                katana_string_append_characters(parser, \", \", string);\n                            }\n                        }\n                        katana_string_append_characters(parser, \")\", string);\n                    }\n                }\n                    break;\n                case KatanaPseudoLang:\n                case KatanaPseudoNthChild:\n                case KatanaPseudoNthLastChild:\n                case KatanaPseudoNthOfType:\n                case KatanaPseudoNthLastOfType: {\n                    katana_string_append_characters(parser, cs->data->argument, string);\n                    katana_string_append_characters(parser, \")\", string);\n                }\n                    break;\n                default:\n                    break;\n            }\n        } else if (cs->match == KatanaSelectorMatchPseudoElement) {\n            katana_string_append_characters(parser, \"::\", string);\n            katana_string_append_characters(parser, cs->data->value, string);\n        } else if (katana_selector_is_attribute(cs)) {\n            katana_string_append_characters(parser, \"[\", string);\n            if (NULL != cs->data->attribute->prefix) {\n                katana_string_append_characters(parser, cs->data->attribute->prefix, string);\n                katana_string_append_characters(parser, \"|\", string);\n            }\n            katana_string_append_characters(parser, cs->data->attribute->local, string);\n            switch (cs->match) {\n                case KatanaSelectorMatchAttributeExact:\n                    katana_string_append_characters(parser, \"=\", string);\n                    break;\n                case KatanaSelectorMatchAttributeSet:\n                    katana_string_append_characters(parser, \"]\", string);\n                    break;\n                case KatanaSelectorMatchAttributeList:\n                    katana_string_append_characters(parser, \"~=\", string);\n                    break;\n                case KatanaSelectorMatchAttributeHyphen:\n                    katana_string_append_characters(parser, \"|=\", string);\n                    break;\n                case KatanaSelectorMatchAttributeBegin:\n                    katana_string_append_characters(parser, \"^=\", string);\n                    break;\n                case KatanaSelectorMatchAttributeEnd:\n                    katana_string_append_characters(parser, \"$=\", string);\n                    break;\n                case KatanaSelectorMatchAttributeContain:\n                    katana_string_append_characters(parser, \"*=\", string);\n                    break;\n                default:\n                    break;\n            }\n            if (cs->match != KatanaSelectorMatchAttributeSet) {\n                katana_string_append_characters(parser, \"\\\"\", string);\n                katana_string_append_characters(parser, cs->data->value, string);\n                katana_string_append_characters(parser, \"\\\"\", string);\n                if (cs->data->bits.attributeMatchType == KatanaAttributeMatchTypeCaseInsensitive)\n                    katana_string_append_characters(parser, \" i\", string);\n                katana_string_append_characters(parser, \"]\", string);\n            }\n        }\n        if (cs->relation != KatanaSelectorRelationSubSelector || !cs->tagHistory)\n            break;\n        cs = cs->tagHistory;\n    }\n\n    KatanaSelector* tagHistory = cs->tagHistory;\n\n    if ( NULL != tagHistory ) {\n        switch (cs->relation) {\n            case KatanaSelectorRelationDescendant:\n            {\n                return katana_build_relation_selector_string(parser, \" \", string, next, tagHistory);\n            }\n            case KatanaSelectorRelationChild:\n            {\n                return katana_build_relation_selector_string(parser, \" > \", string, next, tagHistory);\n            }\n            case KatanaSelectorRelationShadowDeep:\n            {\n                return katana_build_relation_selector_string(parser, \" /deep/ \", string, next, tagHistory);\n            }\n            case KatanaSelectorRelationDirectAdjacent:\n            {\n                return katana_build_relation_selector_string(parser, \" + \", string, next, tagHistory);\n            }\n            case KatanaSelectorRelationIndirectAdjacent:\n            {\n                return katana_build_relation_selector_string(parser, \" ~ \", string, next, tagHistory);\n            }\n            case KatanaSelectorRelationSubSelector:\n            {\n                return NULL;\n            }\n            case KatanaSelectorRelationShadowPseudo:\n            {\n                return katana_build_relation_selector_string(parser, NULL, string, next, tagHistory);\n            }\n        }\n    }\n    \n    if ( NULL != next ) {\n        katana_string_append_string(parser, (KatanaParserString*)next, string);\n    }\n    \n    return (KatanaParserString*)string;\n}\n\nunsigned calc_specificity_for_one_selector(const KatanaSelector* selector)\n{\n    switch ( selector->match ) {\n        case KatanaSelectorMatchId:\n            return 0x10000;\n            \n        case KatanaSelectorMatchPseudoClass:\n        case KatanaSelectorMatchAttributeExact:\n        case KatanaSelectorMatchClass:\n        case KatanaSelectorMatchAttributeSet:\n        case KatanaSelectorMatchAttributeList:\n        case KatanaSelectorMatchAttributeHyphen:\n        case KatanaSelectorMatchPseudoElement:\n        case KatanaSelectorMatchAttributeContain:\n        case KatanaSelectorMatchAttributeBegin:\n        case KatanaSelectorMatchAttributeEnd:\n            return 0x100;\n            \n        case KatanaSelectorMatchTag:\n            return !strcasecmp(selector->tag->local, \"*\") ? 0 : 1;\n        case KatanaSelectorMatchUnknown:\n        case KatanaSelectorMatchPagePseudoClass:\n            return 0;\n    }\n    \n    return 0;\n}\n\nunsigned katana_calc_specificity_for_selector(KatanaSelector* selector)\n{\n    if ( NULL == selector ) {\n        return 0;\n    }\n    \n    static const unsigned idMask = 0xff0000;\n    static const unsigned classMask = 0xff00;\n    static const unsigned elementMask = 0xff;\n    \n    unsigned total = 0;\n    unsigned temp = 0;\n    \n    for (const KatanaSelector * next = selector; next; next = next->tagHistory)\n    {\n        temp = total + calc_specificity_for_one_selector(next);\n\n        if ((temp & idMask) < (total & idMask))\n            total |= idMask;\n        else if ((temp & classMask) < (total & classMask))\n            total |= classMask;\n        else if ((temp & elementMask) < (total & elementMask))\n            total |= elementMask;\n        else\n            total = temp;\n    }\n        \n    return total;\n}\n\n// Could be made smaller and faster by replacing pointer with an\n// offset into a string buffer and making the bit fields smaller but\n// that could not be maintained by hand.\ntypedef struct {\n    const char* string;\n    unsigned type:8;\n} KatanaNameToPseudoStruct;\n\n// These tables should be kept sorted.\nconst static KatanaNameToPseudoStruct kPseudoTypeWithoutArgumentsMap[] = {\n    {\"-internal-list-box\",            KatanaPseudoListBox},\n    {\"-internal-media-controls-cast-button\", KatanaPseudoWebKitCustomElement},\n    {\"-internal-media-controls-overlay-cast-button\", KatanaPseudoWebKitCustomElement},\n    {\"-internal-spatial-navigation-focus\", KatanaPseudoSpatialNavigationFocus},\n    {\"-webkit-any-link\",              KatanaPseudoAnyLink},\n    {\"-webkit-autofill\",              KatanaPseudoAutofill},\n    {\"-webkit-drag\",                  KatanaPseudoDrag},\n    {\"-webkit-full-page-media\",       KatanaPseudoFullPageMedia},\n    {\"-webkit-full-screen\",           KatanaPseudoFullScreen},\n    {\"-webkit-full-screen-ancestor\",  KatanaPseudoFullScreenAncestor},\n    {\"-webkit-full-screen-document\",  KatanaPseudoFullScreenDocument},\n    {\"-webkit-resizer\",               KatanaPseudoResizer},\n    {\"-webkit-scrollbar\",             KatanaPseudoScrollbar},\n    {\"-webkit-scrollbar-button\",      KatanaPseudoScrollbarButton},\n    {\"-webkit-scrollbar-corner\",      KatanaPseudoScrollbarCorner},\n    {\"-webkit-scrollbar-thumb\",       KatanaPseudoScrollbarThumb},\n    {\"-webkit-scrollbar-track\",       KatanaPseudoScrollbarTrack},\n    {\"-webkit-scrollbar-track-piece\", KatanaPseudoScrollbarTrackPiece},\n    {\"active\",                        KatanaPseudoActive},\n    {\"after\",                         KatanaPseudoAfter},\n    {\"backdrop\",                      KatanaPseudoBackdrop},\n    {\"before\",                        KatanaPseudoBefore},\n    {\"checked\",                       KatanaPseudoChecked},\n    {\"content\",                       KatanaPseudoContent},\n    {\"corner-present\",                KatanaPseudoCornerPresent},\n    {\"cue\",                           KatanaPseudoWebKitCustomElement},\n    {\"decrement\",                     KatanaPseudoDecrement},\n    {\"default\",                       KatanaPseudoDefault},\n    {\"disabled\",                      KatanaPseudoDisabled},\n    {\"double-button\",                 KatanaPseudoDoubleButton},\n    {\"empty\",                         KatanaPseudoEmpty},\n    {\"enabled\",                       KatanaPseudoEnabled},\n    {\"end\",                           KatanaPseudoEnd},\n    {\"first\",                         KatanaPseudoFirstPage},\n    {\"first-child\",                   KatanaPseudoFirstChild},\n    {\"first-letter\",                  KatanaPseudoFirstLetter},\n    {\"first-line\",                    KatanaPseudoFirstLine},\n    {\"first-of-type\",                 KatanaPseudoFirstOfType},\n    {\"focus\",                         KatanaPseudoFocus},\n    {\"future\",                        KatanaPseudoFutureCue},\n    {\"horizontal\",                    KatanaPseudoHorizontal},\n    {\"host\",                          KatanaPseudoHost},\n    {\"hover\",                         KatanaPseudoHover},\n    {\"in-range\",                      KatanaPseudoInRange},\n    {\"increment\",                     KatanaPseudoIncrement},\n    {\"indeterminate\",                 KatanaPseudoIndeterminate},\n    {\"invalid\",                       KatanaPseudoInvalid},\n    {\"last-child\",                    KatanaPseudoLastChild},\n    {\"last-of-type\",                  KatanaPseudoLastOfType},\n    {\"left\",                          KatanaPseudoLeftPage},\n    {\"link\",                          KatanaPseudoLink},\n    {\"no-button\",                     KatanaPseudoNoButton},\n    {\"only-child\",                    KatanaPseudoOnlyChild},\n    {\"only-of-type\",                  KatanaPseudoOnlyOfType},\n    {\"optional\",                      KatanaPseudoOptional},\n    {\"out-of-range\",                  KatanaPseudoOutOfRange},\n    {\"past\",                          KatanaPseudoPastCue},\n    {\"read-only\",                     KatanaPseudoReadOnly},\n    {\"read-write\",                    KatanaPseudoReadWrite},\n    {\"required\",                      KatanaPseudoRequired},\n    {\"right\",                         KatanaPseudoRightPage},\n    {\"root\",                          KatanaPseudoRoot},\n    {\"scope\",                         KatanaPseudoScope},\n    {\"selection\",                     KatanaPseudoSelection},\n    {\"shadow\",                        KatanaPseudoShadow},\n    {\"single-button\",                 KatanaPseudoSingleButton},\n    {\"start\",                         KatanaPseudoStart},\n    {\"target\",                        KatanaPseudoTarget},\n    {\"unresolved\",                    KatanaPseudoUnresolved},\n    {\"valid\",                         KatanaPseudoValid},\n    {\"vertical\",                      KatanaPseudoVertical},\n    {\"visited\",                       KatanaPseudoVisited},\n    {\"window-inactive\",               KatanaPseudoWindowInactive},\n};\n\nconst static KatanaNameToPseudoStruct kPseudoTypeWithArgumentsMap[] = {\n    {\"-webkit-any(\",      KatanaPseudoAny},\n    {\"cue(\",              KatanaPseudoCue},\n    {\"host(\",             KatanaPseudoHost},\n    {\"host-context(\",     KatanaPseudoHostContext},\n    {\"lang(\",             KatanaPseudoLang},\n    {\"not(\",              KatanaPseudoNot},\n    {\"nth-child(\",        KatanaPseudoNthChild},\n    {\"nth-last-child(\",   KatanaPseudoNthLastChild},\n    {\"nth-last-of-type(\", KatanaPseudoNthLastOfType},\n    {\"nth-of-type(\",      KatanaPseudoNthOfType},\n};\n\nstatic const KatanaNameToPseudoStruct* lower_bound(const KatanaNameToPseudoStruct *map,\n                                                   size_t count, const char* key);\n\nstatic KatanaPseudoType name_to_pseudo_type(const char* name, bool hasArguments)\n{\n    if (NULL == name)\n        return KatanaPseudoUnknown;\n    \n    const KatanaNameToPseudoStruct* pseudoTypeMap;\n    size_t count;\n    \n    if (hasArguments) {\n        pseudoTypeMap = kPseudoTypeWithArgumentsMap;\n        count = sizeof(kPseudoTypeWithArgumentsMap) / sizeof(KatanaNameToPseudoStruct);\n    } else {\n        pseudoTypeMap = kPseudoTypeWithoutArgumentsMap;\n        count = sizeof(kPseudoTypeWithoutArgumentsMap) / sizeof(KatanaNameToPseudoStruct);\n    }\n    \n    const KatanaNameToPseudoStruct* match = lower_bound(pseudoTypeMap, count, name);\n    if ( match == (pseudoTypeMap + count)\n         || 0 != strcasecmp(match->string, name) )\n        return KatanaPseudoUnknown;\n    \n    return match->type;\n}\n\nstatic const KatanaNameToPseudoStruct* lower_bound(const KatanaNameToPseudoStruct *array,\n                                                   size_t size, const char* key) {\n    const KatanaNameToPseudoStruct* it;\n    const KatanaNameToPseudoStruct* first = array;\n    size_t count = size, step;\n    while (count > 0) {\n        it = first;\n        step = count / 2;\n        it += step;\n        if (strncmp(it->string, key, strlen(key)) < 0) {\n            first = ++it;\n            count -= step + 1;\n        } else count = step;\n    }\n    return first;\n}\n\n#if KATANA_PARSER_DEBUG\n\nvoid test_lower_bound()\n{\n    const KatanaNameToPseudoStruct* pseudoTypeMap;\n    size_t count;\n    \n    pseudoTypeMap = kPseudoTypeWithArgumentsMap;\n    count = sizeof(kPseudoTypeWithArgumentsMap) / sizeof(KatanaNameToPseudoStruct);\n    \n    for ( size_t i = 0; i < count; i++ ) {\n        const KatanaNameToPseudoStruct* res = lower_bound(pseudoTypeMap, count, pseudoTypeMap[i].string);\n        assert(pseudoTypeMap[i].type == res->type);\n    }\n    \n    pseudoTypeMap = kPseudoTypeWithoutArgumentsMap;\n    count = sizeof(kPseudoTypeWithoutArgumentsMap) / sizeof(KatanaNameToPseudoStruct);\n    \n    for ( size_t i = 0; i < count; i++ ) {\n        const KatanaNameToPseudoStruct* res = lower_bound(pseudoTypeMap, count, pseudoTypeMap[i].string);\n        assert(pseudoTypeMap[i].type == res->type);\n    }\n}\n\n#endif // #if KATANA_PARSER_DEBUG\n"
  },
  {
    "path": "compiler/compiler/Compiler/Vendors/katana-parser/Sources/tokenizer.c",
    "content": "﻿/**\n * Copyright (c) 2015 QFish <im@qfi.sh>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n#include <assert.h>\n\n#include \"tokenizer.h\"\n#include \"katana.tab.h\"\n#include \"katana.lex.h\"\n#include \"parser.h\"\n#include \"foundation.h\"\n\n#undef\tassert\n#define assert(x)\n\nstatic inline double katana_characters_to_double(const char* data, size_t length, bool* ok);\nstatic inline bool katana_is_html_space(char c);\nstatic inline char* katana_normalize_text(yy_size_t* length, char *origin_text, yy_size_t origin_length, int tok);\n\n#ifdef KATANA_FELX_DEBUG\n#if KATANA_FELX_DEBUG\nstatic char * katana_token_string(int tok);\n#endif // #if KATANA_FELX_DEBUG\n#endif // #ifdef KATANA_FELX_DEBUG\n\n/**\n *  A hook function of flex, processing tokens which will be passed to bison\n *\n *  @param yylval    the medium for flex and bison\n *  @param yyscanner flex state\n *  @param tok       the type of token\n *\n *  @return the type of token\n */\nint katana_tokenize(KATANASTYPE* lval , KATANALTYPE* loc, yyscan_t scanner, KatanaParser* parser, int tok)\n{\n    char* origin_text = katanaget_text(scanner);\n    \n    yy_size_t len = 0;\n    \n    char* text = katana_normalize_text(&len, origin_text, katanaget_leng(scanner), tok);\n    \n#ifdef KATANA_FELX_DEBUG\n#if KATANA_FELX_DEBUG\n    if ( tok == KATANA_CSS_WHITESPACE ) {\n        katana_parser_log(parser, \"【%30s】=>【%30s】: %s\", \"\", \"\", katana_token_string(tok));\n    } else {\n        katana_parser_log(parser, \"【%30s】=>【%30s】: %s\", origin_text, text, katana_token_string(tok));\n    }\n#endif // #if KATANA_FELX_DEBUG\n#endif // #ifdef KATANA_FELX_DEBUG\n    yy_size_t length = len;\n    switch ( tok ) {\n        case KATANA_CSS_INCLUDES:\n        case KATANA_CSS_DASHMATCH:\n        case KATANA_CSS_BEGINSWITH:\n        case KATANA_CSS_ENDSWITH:\n        case KATANA_CSS_CONTAINS:\n            break;\n        case KATANA_CSS_STRING:\n        case KATANA_CSS_IDENT:\n        case KATANA_CSS_NTH:\n            \n        case KATANA_CSS_HEX:\n        case KATANA_CSS_IDSEL:\n            \n        case KATANA_CSS_DIMEN:\n        case KATANA_CSS_INVALIDDIMEN:\n        case KATANA_CSS_URI:\n        case KATANA_CSS_FUNCTION:\n        case KATANA_CSS_ANYFUNCTION:\n        case KATANA_CSS_CUEFUNCTION:\n        case KATANA_CSS_NOTFUNCTION:\n        case KATANA_CSS_CALCFUNCTION:\n        case KATANA_CSS_MINFUNCTION:\n        case KATANA_CSS_MAXFUNCTION:\n        case KATANA_CSS_HOSTFUNCTION:\n        case KATANA_CSS_HOSTCONTEXTFUNCTION:\n        case KATANA_CSS_UNICODERANGE:\n        {\n            lval->string.data = text;\n            lval->string.length = length;\n        }\n            break;\n            \n        case KATANA_CSS_IMPORT_SYM:\n        case KATANA_CSS_PAGE_SYM:\n        case KATANA_CSS_MEDIA_SYM:\n        case KATANA_CSS_SUPPORTS_SYM:\n        case KATANA_CSS_FONT_FACE_SYM:\n        case KATANA_CSS_CHARSET_SYM:\n        case KATANA_CSS_NAMESPACE_SYM:\n//        case KATANA_CSS_VIEWPORT_RULE_SYM:\n        case KATANA_INTERNAL_DECLS_SYM:\n        case KATANA_INTERNAL_MEDIALIST_SYM:\n        case KATANA_INTERNAL_RULE_SYM:\n        case KATANA_INTERNAL_SELECTOR_SYM:\n        case KATANA_INTERNAL_VALUE_SYM:\n        case KATANA_INTERNAL_KEYFRAME_RULE_SYM:\n        case KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM:\n        case KATANA_INTERNAL_SUPPORTS_CONDITION_SYM:\n        case KATANA_CSS_KEYFRAMES_SYM:\n            break;\n        case KATANA_CSS_QEMS:\n            length--;\n        case KATANA_CSS_GRADS:\n        case KATANA_CSS_TURNS:\n            length--;\n        case KATANA_CSS_DEGS:\n        case KATANA_CSS_RADS:\n        case KATANA_CSS_KHERTZ:\n        case KATANA_CSS_REMS:\n            length--;\n        case KATANA_CSS_MSECS:\n        case KATANA_CSS_HERTZ:\n        case KATANA_CSS_EMS:\n        case KATANA_CSS_EXS:\n        case KATANA_CSS_PXS:\n        case KATANA_CSS_CMS:\n        case KATANA_CSS_MMS:\n        case KATANA_CSS_INS:\n        case KATANA_CSS_PTS:\n        case KATANA_CSS_PCS:\n            length--;\n        case KATANA_CSS_SECS:\n        case KATANA_CSS_PERCENTAGE:\n            length--;\n        case KATANA_CSS_FLOATTOKEN:\n            lval->number.val = katana_characters_to_double(text, length, NULL);\n            lval->number.raw.data = text;\n            lval->number.raw.length = len;\n            break;\n        case KATANA_CSS_INTEGER:\n            lval->number.val = (int)katana_characters_to_double(text, length, NULL);\n            lval->number.raw.data = text;\n            lval->number.raw.length = len;\n\n            break;\n        default:\n            break;\n    }\n    \n    return tok;\n}\n\n/**\n *  Format token\n *\n *  @param length\n *  @param origin_text   original text from the flex\n *  @param origin_length formatted length\n *  @param tok\n *\n *  @return normalized text\n */\nstatic inline char* katana_normalize_text(yy_size_t* length, char *origin_text, yy_size_t origin_length, int tok)\n{\n    char * start = origin_text;\n    yy_size_t l = origin_length;\n    switch ( tok ) {\n        case KATANA_CSS_STRING:\n            l--;\n            /* nobreak */\n        case KATANA_CSS_HEX:\n        case KATANA_CSS_IDSEL:\n            start++;\n            l--;\n            break;\n        case KATANA_CSS_URI:\n            // \"url(\"{w}{string}{w}\")\"\n            // \"url(\"{w}{url}{w}\")\"\n            // strip \"url(\" and \")\"\n            start += 4;\n            l -= 5;\n            // strip {w}\n            while (l && katana_is_html_space(*start)) {\n                ++start;\n                --l;\n            }\n            while (l && katana_is_html_space(start[l - 1]))\n                --l;\n            if (l && (*start == '\"' || *start == '\\'')) {\n                assert(l >= 2 && start[l - 1] == *start);\n                ++start;\n                l -= 2;\n            }\n            break;\n        default:\n            break;\n    }\n    \n    *length = l;\n    return start;\n}\n\ndouble katana_characters_to_double(const char* data, size_t length, bool* ok)\n{\n    if (!length) {\n        if (ok)\n            *ok = false;\n        return 0.0;\n    }\n    \n    char* bytes = malloc(sizeof(char) * (length + 1));\n    for (unsigned i = 0; i < length; ++i)\n        bytes[i] = data[i] < 0x7F ? data[i] : '?';\n    bytes[length] = '\\0';\n    char* end;\n    double val = strtod(bytes, &end);\n    if (ok)\n        *ok = (end == 0 || *end == '\\0');\n\tfree(bytes);\n    return val;\n}\n\n#ifdef KATANA_FELX_DEBUG\n#if KATANA_FELX_DEBUG\nstatic char * katana_token_table[] = {\n    \"TOKEN_EOF\", \"LOWEST_PREC\", \"UNIMPORTANT_TOK\",\n    \"KATANA_CSS_SGML_CD\", \"KATANA_CSS_WHITESPACE\", \"KATANA_CSS_INCLUDES\",\n    \"KATANA_CSS_DASHMATCH\", \"KATANA_CSS_BEGINSWITH\", \"KATANA_CSS_ENDSWITH\",\n    \"KATANA_CSS_CONTAINS\", \"KATANA_CSS_STRING\", \"KATANA_CSS_IDENT\",\n    \"KATANA_CSS_NTH\", \"KATANA_CSS_HEX\", \"KATANA_CSS_IDSEL\", \"KATANA_CSS_IMPORT_SYM\", \"KATANA_CSS_PAGE_SYM\",\n    \"KATANA_CSS_MEDIA_SYM\", \"KATANA_CSS_SUPPORTS_SYM\",\n    \"KATANA_CSS_FONT_FACE_SYM\", \"KATANA_CSS_CHARSET_SYM\",\n    \"KATANA_CSS_NAMESPACE_SYM\", \"KATANA_INTERNAL_DECLS_SYM\",\n    \"KATANA_INTERNAL_MEDIALIST_SYM\", \"KATANA_INTERNAL_RULE_SYM\",\n    \"KATANA_INTERNAL_SELECTOR_SYM\", \"KATANA_INTERNAL_VALUE_SYM\",\n    \"KATANA_INTERNAL_KEYFRAME_RULE_SYM\",\n    \"KATANA_INTERNAL_KEYFRAME_KEY_LIST_SYM\",\n    \"KATANA_INTERNAL_SUPPORTS_CONDITION_SYM\", \"KATANA_CSS_KEYFRAMES_SYM\",\n    \"KATANA_CSS_ATKEYWORD\", \"KATANA_CSS_IMPORTANT_SYM\",\n    \"KATANA_CSS_MEDIA_NOT\", \"KATANA_CSS_MEDIA_ONLY\", \"KATANA_CSS_MEDIA_AND\",\n    \"KATANA_CSS_MEDIA_OR\", \"KATANA_CSS_SUPPORTS_NOT\",\n    \"KATANA_CSS_SUPPORTS_AND\", \"KATANA_CSS_SUPPORTS_OR\", \"KATANA_CSS_REMS\",\n    \"KATANA_CSS_CHS\", \"KATANA_CSS_QEMS\", \"KATANA_CSS_EMS\", \"KATANA_CSS_EXS\",\n    \"KATANA_CSS_PXS\", \"KATANA_CSS_CMS\", \"KATANA_CSS_MMS\", \"KATANA_CSS_INS\",\n    \"KATANA_CSS_PTS\", \"KATANA_CSS_PCS\", \"KATANA_CSS_DEGS\", \"KATANA_CSS_RADS\",\n    \"KATANA_CSS_GRADS\", \"KATANA_CSS_TURNS\", \"KATANA_CSS_MSECS\",\n    \"KATANA_CSS_SECS\", \"KATANA_CSS_HERTZ\", \"KATANA_CSS_KHERTZ\",\n    \"KATANA_CSS_DIMEN\", \"KATANA_CSS_INVALIDDIMEN\", \"KATANA_CSS_PERCENTAGE\",\n    \"KATANA_CSS_FLOATTOKEN\", \"KATANA_CSS_INTEGER\", \"KATANA_CSS_VW\",\n    \"KATANA_CSS_VH\", \"KATANA_CSS_VMIN\", \"KATANA_CSS_VMAX\", \"KATANA_CSS_DPPX\",\n    \"KATANA_CSS_DPI\", \"KATANA_CSS_DPCM\", \"KATANA_CSS_FR\", \"KATANA_CSS_URI\",\n    \"KATANA_CSS_FUNCTION\", \"KATANA_CSS_ANYFUNCTION\",\n    \"KATANA_CSS_CUEFUNCTION\", \"KATANA_CSS_NOTFUNCTION\",\n    \"KATANA_CSS_CALCFUNCTION\", \"KATANA_CSS_MINFUNCTION\",\n    \"KATANA_CSS_MAXFUNCTION\", \"KATANA_CSS_HOSTFUNCTION\",\n    \"KATANA_CSS_HOSTCONTEXTFUNCTION\", \"KATANA_CSS_UNICODERANGE\" };\n\nstatic char * katana_token_string(int tok)\n{\n    if (tok > 257)\n    {\n        return katana_token_table[tok-257];\n    }\n    else if ( 0 == tok )\n    {\n        return katana_token_table[0];\n    }\n    else\n    {\n        char* unicode = malloc(2);\n        unicode[0] = (char)tok;\n        unicode[1] = '\\0';\n        return unicode;\n    }\n}\n#endif // #if KATANA_FELX_DEBUG\n#endif // #ifdef KATANA_FELX_DEBUG\n\ninline bool katana_is_html_space(char c)\n{\n    return c <= ' ' && (c == ' ' || c == '\\n' || c == '\\t' || c == '\\r' || c == '\\f');\n}\n\n//inline int katana_to_ascii_hex_value(char c)\n//{\n//    //    ASSERT(isASCIIHexDigit(c));\n//    return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF;\n//}\n\n//inline bool katana_is_ascii_hex_digit(char c)\n//{\n//    return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f');\n//}\n"
  },
  {
    "path": "compiler/compiler/README.md",
    "content": "# Valdi\n\nValdi is a language, framework, and view abstraction layer that lets you declaratively build complex UIs.\n\n## Build for macOS\n\nOpen `client/src/open_source/compiler/compiler/Compiler/Package.swift` in Xcode and allow it to resolve the dependencies, and then it should build successfully.\n\n## Build for Ubuntu 18.04\n\nRun client/src/dev_setup.sh. This should download and install Swift, clone and build watchman from source and install all the necessary apt-get dependencies.\n\n## Building the compiler locally\n\nTo build and use the compiler from source (instead of the prebuilt binary):\n\n```sh\ncompiler/compiler/scripts/update_compiler.sh -s -o compiler/compiler/out\n```\n\n- `-s` skips analytics upload (recommended for local builds)\n- `-o compiler/compiler/out` writes the binary to `out/macos/valdi_compiler` (or `out/linux/valdi_compiler` on Linux)\n\nThe `out/` directory is gitignored.\n\nTo use your local build with Bazel, pass `--//bzl/valdi:use_local_compiler=true`:\n\n```sh\nbazel build //src/valdi_modules/src/valdi/jasmine --//bzl/valdi:use_local_compiler=true\n```\n\nOr via the CLI hotreload command:\n\n```sh\nvaldi hotreload --local\n```\n\nSee [docs/docs/workflow-bazel.md](../../docs/docs/workflow-bazel.md) for more details.\n\n## Updating the prebuilt compiler binary in the repo\n\nTo update the prebuilt binary that gets downloaded by other developers (SnapCI job):\n\n```sh\n./scripts/update_compiler.sh\n```\n\n## Debugging C++ JNI crashes\n\n- Copy paste the native crash from adb logcat into a txt file. It should have the **\\* \\*** etc... at the beginning\n- Run this:\n\n```\n$ANDROID_NDK/ndk-stack -sym \"{PATH_TO_CLIENT_REPO}/src/buck-out/gen/client-jni#android-armv7,shared/\"\n```\n\nIt will show you the files and lines of the stacktrace.\n\n## Troubleshooting\n\nMy breakpoints are not activating in Xcode.\n\n1. Close Xcode\n2. Delete Xcode cache\n\n   - `rm -rf ~/Library/Developer/Xcode/DerivedData/*`\n   - `rm -rf ~/Library/Caches/com.apple.dt.Xcode`\n\n3. Delete ~/.lldbinit-Xcode\n\n   - `rm -rf ~/.lldbinit-Xcode`\n   - Optionally `rm -rf ~/.lldbinit-*`\n\n4. Kill lldb-rpc-server process (may not be active if Xcode was previously closed\n\n   - `pkill -9 \"lldb-rpc-server\"`\n\n5. Open Xcode, build and run the project again.\n"
  },
  {
    "path": "compiler/compiler/generate_proto.py",
    "content": "#!/usr/bin/python\n\nfrom subprocess import check_call\nimport os\n\nPROTO_PATH = '.'\nINPUT_DIR = os.path.join(PROTO_PATH, '.')\nINPUT_FILES = ['valdi', 'valdi-daemon-registry']\nSWIFT_FILES = INPUT_FILES + ['valdi-artifact-management']\nOUTPUT_SWIFT = 'Compiler/Sources/Models'\nOUTPUT_CPP = '../client/src/valdi/protogen-lite/valdi/'\n\nfor filename in INPUT_FILES:\n    # cpp uses protobuf 3.5.1\n    check_call([\n        '../client/tools/protoc',\n        '--proto_path={}'.format(PROTO_PATH),\n        '--cpp_out=lite:{}'.format(OUTPUT_CPP),\n        '{}/{}.proto'.format(INPUT_DIR, filename),\n    ])\n\nfor filename in SWIFT_FILES:\n    check_call(['protoc',\n        '--swift_out={}'.format(OUTPUT_SWIFT),\n        '--proto_path={}'.format(INPUT_DIR),\n        '{}/{}.proto'.format(INPUT_DIR, filename)]\n    )\n"
  },
  {
    "path": "compiler/compiler/generate_proto.sh",
    "content": "#!/usr/bin/env bash\n\nset -eu\n\nscript_root=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\nrepo_root=\"$(cd \"$script_root\"/../../../.. && pwd)\"\n\nprotoc=\"${repo_root}/tools/protoc\"\nvaldi_root=\"${repo_root}/src/open_source/valdi\"\ncompiler_root=\"${repo_root}/src/open_source/compiler\"\n\ngenerate_protos() {\n  local proto_path=\"${compiler_root}/compiler/\"\n\n  local cpp_out=\"${valdi_root}/protogen-lite/valdi\"\n  local valdi_cpp_proto_files=(\n    valdi.proto\n  )\n\n  mkdir -p \"${cpp_out}\"\n\n  ${protoc} --proto_path=\"${proto_path}\" \\\n    --cpp_out=\"lite:${cpp_out}\" \\\n    $valdi_cpp_proto_files\n\n\n  local swift_out=\"${compiler_root}/compiler/Compiler/Sources/Models\"\n  local valdi_swift_proto_files=(\n    valdi-artifact-management.proto\n    valdi-daemon-registry.proto\n  )\n  ${protoc} --proto_path=\"${proto_path}\" \\\n    --swift_out=\"${swift_out}\" \\\n    $valdi_swift_proto_files\n}\n\n(\n  cd ${repo_root}\n  generate_protos\n)\n"
  },
  {
    "path": "compiler/compiler/scripts/README_local_compiler.md",
    "content": "# Using a local Valdi compiler for testing\n\nWhen you change the code generator (ObjC, Swift, Kotlin), Bazel must use your built compiler instead of the prebuilt one.\n\n## One-time setup\n\nFrom the **client repo root** (directory that contains `src/open_source`):\n\n```bash\ncd src/open_source/compiler/compiler\n./scripts/use_local_compiler.sh\n```\n\nThis will:\n1. Build the compiler (`update_compiler.sh -o bin/macos`)\n2. Package it as `bin/macos.tar.gz`\n3. Update `src/open_source/bzl/open_source_archives.bzl` to point `valdi_compiler_macos` at that file (and set the correct hash)\n\nThen clear Bazel’s cache so it re-fetches the compiler:\n\n```bash\n# From client repo root\nrm -rf ~/.cache/bazel/*/external/valdi_compiler_macos\n# or\nbzl clean --expunge\n```\n\n## Reverting to the prebuilt compiler\n\nIn `src/open_source/bzl/open_source_archives.bzl`, set the `valdi_compiler_macos` entry back to the `gs://` URL and the original hash (or simply revert the local change with git).\n"
  },
  {
    "path": "compiler/compiler/scripts/entitlements.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\"\n  \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n<key>com.apple.security.get-task-allow</key>\n<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "compiler/compiler/scripts/update_compiler.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\nset -x\n\necho \"Updating Valdi compiler...\"\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" >/dev/null 2>&1 && pwd)\"\nBASE_PATH=\"${SCRIPT_DIR}/../Compiler\"\n\n# Compute the repo/client root now (before any cd) so we can resolve relative paths correctly\n# regardless of the caller's working directory.\n# - Mobile repo (SnapCI): SCRIPT_DIR contains \"open_source\", root is client/\n# - Public/mirrored repo (post-Copybara): root is the open_source repo root\nif [[ \"$SCRIPT_DIR\" == *\"open_source\"* ]]; then\n    COPY_DEST_ROOT=\"$(cd \"$SCRIPT_DIR/../../../../../\" && pwd)\"\nelse\n    COPY_DEST_ROOT=\"$(cd \"$SCRIPT_DIR/../../../\" && pwd)\"\nfi\nOUTPUT_FILENAME=\"Compiler\"\nENTITLEMENTS_PATH=\"$SCRIPT_DIR/entitlements.plist\"\n\n# previous version 5.9 for XCode 15\n# current version 6.0 for XCode 16\nSWIFT_CURRENT_VERSION=\"6.0\"\nSWIFT_ALLOWED_VERSIONS=\"$SWIFT_CURRENT_VERSION\\|5.7\\|5.8\\|5.9\\|6.1\\|6.2\"\n\nskip_analytics=false\nbin_output_path=\"\"\n\nusage() {\n  echo \"Usage: $0 [-o bin_output_path] [-s] [skip_analytics]\"\n  exit 1\n}\n\n# Parse simple command line options\nwhile getopts \":o:s\" opt; do\n  case \"$opt\" in\n    s)\n      skip_analytics=true\n      ;;\n    o)\n      bin_output_path=$OPTARG\n      ;;\n    \\? )\n      echo \"Invalid option: $OPTARG\" 1>&2\n      usage\n      ;;\n    : )\n      echo \"Invalid option: $OPTARG requires an argument\" 1>&2\n      usage\n      ;;\n  esac\ndone\n\nshift $((OPTIND -1))\n\nif [[ ! -z $ENV_SKIP_ANALYTICS ]] && [ \"$ENV_SKIP_ANALYTICS\" = true ]; then\n    skip_analytics=true\nfi\n\n# Assign positional arguments if options were not provided\nif [ -z \"$bin_output_path\" ] && [ $# -ge 1 ]; then\n  bin_output_path=$1\n  shift\nfi\n\nif [ -z \"$bin_output_path\" ]; then\n  usage\nfi\n\n# Resolve bin_output_path relative to COPY_DEST_ROOT (not the caller's CWD),\n# so the output location is correct regardless of where the script is invoked from.\nif [[ \"$bin_output_path\" != /* ]]; then\n  bin_output_path=\"$COPY_DEST_ROOT/$bin_output_path\"\nfi\n\n# Main\ncd \"$BASE_PATH\"\nVARIANT=\"release\"\n\nif [[ $1 ]]; then\n    VARIANT=\"$1\"\nfi\n\nSWIFT_BIN=\"/usr/bin/swift\"\n\n# For debugging purposes\necho $($SWIFT_BIN --version)\n\n# Check if the current swift version is the expected version\nSWIFT_VERSION_OUTPUT=$($SWIFT_BIN --version | grep -e \"$SWIFT_ALLOWED_VERSIONS\") || true\n\nCURRENT_SYSTEM=$(uname)\nIS_LINUX=false\nif [[ \"$CURRENT_SYSTEM\" == \"Linux\" ]]; then\n    IS_LINUX=true\nfi\n\nif [[ \"$IS_LINUX\" = true ]]; then\n    if [[ -z $SWIFT_VERSION_OUTPUT ]]; then\n        echo \"Need to build using Swift $SWIFT_CURRENT_VERSION. Please run the linux_dev_setup.sh script.\"\n        exit 1\n    fi\n\n    # Run tests\n    # $SWIFT_BIN test\n    # Can't run tests on Linux because of https://github.com/apple/swift-corelibs-xctest/issues/438\n\n    # Passing -Xswiftc -g ensures we output debug information even for release builds\n    $SWIFT_BIN build $SWIFT_BUILD_ADDITIONAL_ARGS -c \"$VARIANT\" -Xswiftc -g --static-swift-stdlib\n    OUTPUT_FILE_PATH=$($SWIFT_BIN build $SWIFT_BUILD_ADDITIONAL_ARGS -c \"$VARIANT\" -Xswiftc -g --show-bin-path)/$OUTPUT_FILENAME\nelse\n    # If PATH `swift` is not the expected version, we try to use the latest known expected version toolchain\n    if [[ -z $SWIFT_VERSION_OUTPUT ]]; then\n        SWIFT_BIN=\"/Library/Developer/Toolchains/swift-$SWIFT_CURRENT_VERSION-RELEASE.xctoolchain/usr/bin/swift\"\n        SWIFT_VERSION_OUTPUT=$($SWIFT_BIN --version | grep -e \"$SWIFT_CURRENT_VERSION\") || true\n\n        echo \"Swift $SWIFT_CURRENT_VERSION not found, falling back to $SWIFT_PREVIOUS_VERSION\"\n\n        if [[ -z $SWIFT_VERSION_OUTPUT ]]; then\n            SWIFT_BIN=\"/Library/Developer/Toolchains/swift-$SWIFT_PREVIOUS_VERSION-RELEASE.xctoolchain/usr/bin/swift\"\n            SWIFT_VERSION_OUTPUT=$($SWIFT_BIN --version | grep -e \"$SWIFT_PREVIOUS_VERSION\") || true\n        fi\n    fi\n\n    if [[ -z $SWIFT_VERSION_OUTPUT ]]; then\n        echo \"Need to build using Swift $SWIFT_CURRENT_VERSION. Please download and install the toolchain from https://swift.org/builds/swift-$SWIFT_CURRENT_VERSION-release/xcode/swift-$SWIFT_CURRENT_VERSION-RELEASE/swift-$SWIFT_CURRENT_VERSION-RELEASE-osx.pkg\"\n        exit 1\n    fi\n\n    # Run tests\n    $SWIFT_BIN test\n\n    OUTPUT_PATH=$($SWIFT_BIN build $SWIFT_BUILD_ADDITIONAL_ARGS -c \"$VARIANT\" --arch arm64 --arch x86_64 -Xswiftc -g --show-bin-path)\n    OUTPUT_FILE_PATH=$OUTPUT_PATH/$OUTPUT_FILENAME\n    $SWIFT_BIN build $SWIFT_BUILD_ADDITIONAL_ARGS -c \"$VARIANT\" --arch arm64 --arch x86_64 -Xswiftc -g\n    codesign --force --sign - --entitlements \"$ENTITLEMENTS_PATH\" \"$OUTPUT_FILE_PATH\"\n\n    if $skip_analytics; then\n        echo \"Analytic uploading for this run will be skipped...\"\n    fi\nfi\n\nif [[ \"$IS_LINUX\" = true ]]; then\n    OUT_DIR=\"$bin_output_path/linux\"\n    SHA256_VAR_NAME=\"VALDI_COMPILER_LINUX_SHA256\"\nelse\n    OUT_DIR=\"$bin_output_path/macos\"\n    SHA256_VAR_NAME=\"VALDI_COMPILER_MACOS_SHA256\"\nfi\n\n(\ncd \"$COPY_DEST_ROOT\"\nif [[ -f \"src/composer/jenkins/jenkins_helpers.sh\" ]]; then\n    source src/composer/jenkins/jenkins_helpers.sh\nfi\n\nmkdir -p \"$OUT_DIR\"\nrm -f \"$OUT_DIR/valdi_compiler\"\ncp \"$OUTPUT_FILE_PATH\" \"$OUT_DIR/valdi_compiler\"\n)\n"
  },
  {
    "path": "compiler/compiler/scripts/use_local_compiler.sh",
    "content": "#!/usr/bin/env bash\n# Build the Valdi compiler, package it as macos.tar.gz, and point the repo at it\n# so Bazel uses your local compiler instead of the prebuilt one.\n#\n# Run from the client repo root (the directory containing src/open_source).\n# After running:\n#   - Clear Bazel cache if you had a previous compiler: bzl clean --expunge (or rm -rf ~/.cache/bazel/.../external/valdi_compiler_macos)\n#   - Run tests (see below)\n#\n# Usage: ./scripts/use_local_compiler.sh\n#   or:  CLIENT_ROOT=/path/to/client ./scripts/use_local_compiler.sh\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nCOMPILER_DIR=\"$(cd \"$SCRIPT_DIR/..\" && pwd)\"\n# Client root: directory that contains src/open_source (compiler/compiler -> open_source -> src -> client)\nCLIENT_ROOT=\"${CLIENT_ROOT:-$(cd \"$COMPILER_DIR/../../../..\" && pwd)}\"\nOPEN_SOURCE=\"$CLIENT_ROOT/src/open_source\"\nBIN_DIR=\"$COMPILER_DIR/bin\"\nARCHIVE=\"$BIN_DIR/macos.tar.gz\"\nARCHIVES_BZL=\"$OPEN_SOURCE/bzl/open_source_archives.bzl\"\n\necho \"Compiler dir: $COMPILER_DIR\"\necho \"Client root:  $CLIENT_ROOT\"\necho \"Archives:     $ARCHIVES_BZL\"\n\n# 1) Build compiler (output goes to $CLIENT_ROOT/bin/macos/macos/valdi_compiler)\necho \"Building compiler...\"\n\"$SCRIPT_DIR/update_compiler.sh\" -o bin/macos\n\n# 2) Package: copy binary into compiler bin and create tar.gz\necho \"Packaging...\"\nmkdir -p \"$BIN_DIR\"\ncp \"$CLIENT_ROOT/bin/macos/macos/valdi_compiler\" \"$BIN_DIR/valdi_compiler\"\nrm -f \"$ARCHIVE\"\ntar -czf \"$ARCHIVE\" -C \"$BIN_DIR\" valdi_compiler\n\n# 3) Hash\nHASH=$(shasum -a 256 \"$ARCHIVE\" | awk '{print $1}')\necho \"New hash: $HASH\"\n\n# 4) Point archives at local file (absolute file:// URL)\nLOCAL_URL=\"file://$ARCHIVE\"\n\n# 5) Update open_source_archives.bzl for valdi_compiler_macos (hash + url)\nUPDATED=0\nif [[ -f \"$ARCHIVES_BZL\" ]]; then\n  awk -v hash=\"$HASH\" -v url=\"$LOCAL_URL\" '\n    /\"src\\/open_source\\/bin\\/compiler\\/macos\":/ { in_block=1 }\n    in_block && /\"hash\":/ { sub(/\"hash\": \"[^\"]+\"/, \"\\\"hash\\\": \\\"\" hash \"\\\"\") }\n    in_block && /\"url\":/  { gsub(/\"url\": \"[^\"]+\"/, \"\\\"url\\\": \\\"\" url \"\\\"\") }\n    in_block && /},/      { in_block=0 }\n    { print }\n  ' \"$ARCHIVES_BZL\" > \"$ARCHIVES_BZL.tmp\" && mv \"$ARCHIVES_BZL.tmp\" \"$ARCHIVES_BZL\" && UPDATED=1\nfi\n\nif [[ \"$UPDATED\" -eq 0 ]]; then\n  echo \"Update $ARCHIVES_BZL manually: set hash to $HASH and url to $LOCAL_URL for valdi_compiler_macos.\"\nfi\n\necho \"\"\necho \"Done. Next steps:\"\necho \"  Clear Bazel cache (so it re-fetches the compiler):\"\necho \"     rm -rf ~/.cache/bazel/*/external/valdi_compiler_macos\"\necho \"     # or from repo root: bzl clean --expunge\"\n"
  },
  {
    "path": "compiler/compiler/valdi-artifact-management.proto",
    "content": "syntax = \"proto3\";\npackage ValdiArtifactManagement;\n\noption java_package = \"snapchat.valdi.artifactmanagement\";\noption java_multiple_files = true;\n\n////////////////////////////////////////////////////////////////\n// Messages described here are used by a developer-only service,\n// currently running on `content-platform`.\n// See /contentplatform/valdi-artifact-management.proto\n////////////////////////////////////////////////////////////////\n\n// Endpoint suffix: /uploadArtifact\nmessage UploadArtifactRequest {\n  // A unique key generated by the client.\n  // If an item already exists at this key, it should\n  // be replaced\n  string key = 1;\n  // The human-readable name of the artifact. It doesn't need to be unique\n  string name = 2;\n  // The bytes contents of the artifact\n  bytes data = 3;\n}\n\nmessage UploadArtifactResponse {\n  bool success = 1;\n  string error_message = 2;\n  string url = 3;\n}\n\n// Endpoint suffix: /getArtifact\nmessage GetArtifactRequest { \n    string key = 1;\n}\n\nmessage GetArtifactResponse {\n  bool success = 1;\n  string error_message = 2;\n  string url = 3;\n  string name = 4;\n}\n\nmessage ManagedArtifact {\n    string key = 1;\n    string url = 2;\n    string name = 3;\n}"
  },
  {
    "path": "compiler/compiler/valdi-daemon-registry.proto",
    "content": "syntax = \"proto3\";\npackage ValdiDaemonRegistry;\n\noption objc_class_prefix = \"SCCDaemonRegistry\";\noption java_package = \"snapchat.valdi.daemon.registry\";\noption java_multiple_files = true;\n\n////////////////////////////////////////////////////////////////\n// Messages described here are used by a developer-only service,\n// currently running on `content-platform`. \n// See /contentplatform/valdi-daemon-registry-service.proto\n////////////////////////////////////////////////////////////////\n\n// Describes a Valdi daemon service and the devices it's targeting\nmessage DaemonService {\n  string key = 1;\n  repeated string service_addresses = 2;\n  int32 service_port = 3;\n  string process_id = 4;\n\n  repeated string device_ids = 5;\n  repeated string usernames = 6;\n}\n\nmessage ListServicesRequest {\n  ListServicesFilters filters = 1;\n}\n\nmessage ListServicesFilters {\n  string device_id = 1;\n  string username = 2;\n}\n\nmessage ListServicesResponse { \n  repeated DaemonService services = 1;\n}\n\nmessage RegisterServiceRequest {\n  DaemonService service = 1;\n}\n\nmessage RegisterServiceResponse {\n  bool success = 1;\n}\n\nmessage UnregisterServiceRequest {\n  string service_key = 1;\n}\n\nmessage UnregisterServiceResponse { \n  bool success = 1;\n}"
  },
  {
    "path": "compiler/compiler/valdi.proto",
    "content": "syntax = \"proto3\";\n\npackage Valdi;\n\noption objc_class_prefix = \"SCValdi\";\noption java_package = \"snapchat.valdi\";\noption cc_enable_arenas = true;\noption optimize_for = CODE_SIZE;\n\n// Defines a static attribute name\n// and its value.\nmessage NodeAttribute {\n  enum Type {\n    NODE_ATTRIBUTE_TYPE_STRING = 0;\n    NODE_ATTRIBUTE_TYPE_INT = 1;\n    NODE_ATTRIBUTE_TYPE_DOUBLE = 2;\n  }\n\n  Type type = 1;\n  string name = 2;\n  // Set if the type is STRING\n  string str_value = 3;\n  // Set if type is INT\n  int64 int_value = 4;\n  // Set if double is INT\n  double double_value = 5;\n}\n\n////////////////////////\n// Downloadable module\n//\n\nmessage DownloadableModuleArtifact {\n  // The url on which the artifact can be downloaded.\n  string url = 1;\n  // The sha256 digest of the artifact data that can be used for verification.\n  bytes sha256Digest = 2;\n}\n\nmessage DownloadableModuleAssets {\n  DownloadableModuleArtifact artifact = 1;\n\n  // The device density for which the assets contained\n  // in this artifact are optimized for.\n  // List of known density:\n  // iPhone @2x: 2\n  // iPhone @3x: 3\n  // Android mdpi: 1\n  // Android hdpi: 1.5\n  // Android xhdpi: 2\n  // Android xxhdpi: 3\n  // Android xxxhdpi: 4\n  double device_density = 3;\n}\n\n// Manifest stored in a .valdimodule when the module\n// is downloadable. Contains all the dependencies and all\n// the urls in which the artifact can be downloaded from.\nmessage DownloadableModuleManifest {\n  // The name which uniquely identifies the module\n  string name = 1;\n  // Where to download the .valdimodule containing the compiled sources\n  // Can be unset if this module only contains assets\n  DownloadableModuleArtifact artifact = 2;\n  // The list of available artifacts containing the assets.\n  repeated DownloadableModuleAssets assets = 3;\n  // The list of module dependencies on this module.\n  // This can be used to ensure that they are available before\n  // attempting to use the module.\n  repeated string dependencies = 4;\n  // Whether the downloadable assets are also available locally\n  bool has_local_assets = 5;\n}\n\n////////////////////////\n// Discovery protocol\n//\n\nmessage DaemonAwakeMessage {\n  // The list of device ids that should connect to the announced service\n  repeated string device_ids = 16;\n  // The list of usernames that should connect to the announced service\n  repeated string usernames = 17;\n\n  // addresses at which the daemon service is listening\n  repeated string service_addresses = 1;\n  // port at which the daemon service is listening\n  int32 service_port = 2;\n  // The id of the daemon process\n  string process_id = 3;\n}\n\nmessage ClientAwakeMessage {\n  string device_id = 1;\n  string username = 2;\n}\n\nmessage DaemonServiceDiscoveryPayload {\n  oneof message {\n    DaemonAwakeMessage daemon_awake_message = 1;\n    ClientAwakeMessage client_awake_message = 2;\n  }\n}\n\n////////////////////////\n// CSS\n//\n\n// A tree, generated bottom-up from all CSS styles in the document, for\n// efficient selector matching.\n\nmessage StyleNode {\n  repeated StyleDeclaration styles = 1;\n  CSSRuleIndex ruleIndex = 2;\n}\n\nmessage StyleDeclaration {\n  NodeAttribute attribute = 1;\n  int32 priority = 2; // value corresponding to CSS specificity\n  int32 order = 3;\n  int32 id = 4;\n}\n\nmessage NamedStyleNode {\n  string name = 1;\n  StyleNode node = 2;\n}\n\nmessage CSSRuleIndex {\n  // To determine the rules that match an element, elements should start with\n  // the current element and the document's root CSSRuleIndex, and recur up\n  // through matching ruleIndexes and the element's ancestry. For a particular\n  // element and ruleIndex, the ruleIndex's properties should be checked in the\n  // order they appear in this proto, and the current ruleIndex should be\n  // reassigned if a match is found.\n  repeated NamedStyleNode id_rules = 1;\n  repeated NamedStyleNode class_rules = 2;\n  repeated NamedStyleNode tag_rules =\n      3; // the universal selector is implemented as a tagRule with tag '*'\n  repeated AttributeRule attribute_rules = 4;\n  StyleNode first_child_rule = 5;\n  StyleNode last_child_rule = 6;\n  repeated NthChildRule nth_child_rules = 7;\n  CSSRuleIndex ancestor_rules = 8;\n  CSSRuleIndex direct_parent_rules = 9;\n\n  message AttributeRule {\n    enum Type {\n      EQUALS = 0;                // [title=\"flower\"]\n      CONTAINS_WORD = 1;         // [title~=\"flower\"]\n      STARTS_WITH_WORD = 2;      // [title|=\"flower\"]\n      STARTS_WITH_SUBSTRING = 3; // [title^=\"flower\"]\n      ENDS_WITH_SUBSTRING = 4;   // [title$=\"flower\"]\n      CONTAINS_SUBSTRING = 5;    // [title*=\"flower\"]\n      HAS_ATTRIBUTE = 6;         // [title]\n    }\n    Type type = 1;\n    NodeAttribute attribute = 2;\n    StyleNode node = 3;\n  }\n\n  message NthChildRule {\n    int32 n = 1;\n    int32 offset = 2;\n    StyleNode node = 3;\n  }\n}\n\n////////////////////////\n// Configs\n//\n\nmessage TsnConfig {\n  // List of tsn enabled modules; all TSN-built modules if empty\n  repeated string enabled_modules = 1;\n}\n"
  },
  {
    "path": "docs/DEV_SETUP.md",
    "content": "# Getting set up to contribute to Valdi\n\n> **Most users:** Install the CLI from npm and use `valdi dev_setup` — see [INSTALL.md](INSTALL.md). This page is for contributors who are developing Valdi itself (the framework), not just building Valdi apps.\n\nFollow all instructions in [INSTALL.md](INSTALL.md).\n\nRun `dev_setup.sh`\n\n```sh\n../scripts/dev_setup.sh\n```\n"
  },
  {
    "path": "docs/INSTALL.md",
    "content": "# Getting Started with Valdi\n\n> **Install the Valdi CLI from npm.** This guide assumes you install the CLI with `npm install -g @snap/valdi`. If you are contributing to Valdi itself, see [DEV_SETUP.md](DEV_SETUP.md) instead.\n\nThis guide will help you set up your development environment and get started with your first project.\n\n## Prerequisites\n\n### macOS\n**Install Xcode** from the [App Store](https://apps.apple.com/us/app/xcode/id497799835) - this is required for iOS development.\n\n### Linux\nNo prerequisites! The Valdi CLI will install everything you need.\n\n### All Platforms\nThat's it! The `valdi dev_setup` command handles all other dependencies automatically, including:\n- Homebrew (macOS)\n- Bazelisk\n- Java JDK 17\n- Android SDK command-line tools\n- Git LFS\n- Watchman\n- Shell autocomplete, JDK symlink (macOS), Android env vars, and platform-specific extras (e.g. ios-webkit-debug-proxy on macOS; adb, zlib/fontconfig dev libs on Linux)\n\n> [!TIP]\n> For manual installation details, see the [macOS](./setup/macos_setup.md) or [Linux](./setup/linux_setup.md) reference guides.\n\n## Installation\n\n### 1. Install the Valdi CLI\n\n```bash\nnpm install -g @snap/valdi\n```\n\n### 2. Set Up Your Development Environment\n\n```bash\n# Set up your development environment (installs all dependencies)\nvaldi dev_setup\n\n# Verify everything is working\nvaldi doctor\n```\n\n> [!NOTE]\n> The first time you run `valdi dev_setup`, it will download and install several gigabytes of dependencies. This may take 10-20 minutes depending on your internet connection.\n\n> [!TIP]\n> **Contributing to Valdi?** If you're developing Valdi itself (not just using it), clone the repository and install from source:\n> ```bash\n> git clone git@github.com:Snapchat/Valdi.git\n> cd Valdi/npm_modules/cli/\n> npm run cli:install\n> ```\n\n## Creating Your First Project\n\nThe best way to start a new project is to bootstrap it using the Valdi CLI. The bootstrap command will create all of the necessary directories, source, and configuration files.\n\n### 1. Bootstrap a New Project\n\n```bash\n# Create and enter your project directory\nmkdir my_project\ncd my_project\n\n# Initialize a new Valdi project\nvaldi bootstrap\n```\n\nThis will create all necessary files for a new Valdi project in your current directory.\n\n### 2. Run Your Project\n\nChoose your target platform and install dependencies:\n\n```bash\n# For iOS\nvaldi install ios\n\n# For Android\nvaldi install android\n```\n\n> [!NOTE]\n> The first build may take several minutes as it sets up the bazel WORKSPACE.\n\n### 3. Enable Hot Reloading\n\nOnce your app is running in a simulator or emulator, start the hot reloader to see your changes in real-time:\n\n```bash\nvaldi hotreload\n```\n\n## VSCode/Cursor Setup (Optional but Recommended)\n\nValdi provides editor extensions for syntax highlighting, debugging, and device logs during hot reload.\n\n### 1. Install VSCode or Cursor\n\n- **VSCode**: Download from [code.visualstudio.com](https://code.visualstudio.com/download)\n- **Cursor**: Download from [cursor.com](https://cursor.com)\n\n### 2. Add Shell Command to PATH\n\nFor **VSCode**:\n- Launch VSCode\n- Open Command Palette (Cmd+Shift+P or Ctrl+Shift+P)\n- Type `shell command` and select `> Install 'code' command in PATH`\n- Restart your terminal\n\nFor **Cursor**:\n- Launch Cursor\n- Open Command Palette (Cmd+Shift+P or Ctrl+Shift+P)\n- Type `shell command` and select `> Install 'cursor' command in PATH`\n- Restart your terminal\n\n### 3. Install Valdi Extensions\n\nDownload the extension files from the [latest release](https://github.com/Snapchat/Valdi/releases/latest):\n- `valdi-vivaldi.vsix` - Device logs and Valdi language support\n- `valdi-debug.vsix` - JavaScript debugger for Valdi apps\n\n**Install the extensions:**\n```bash\n# For VSCode\ncode --install-extension /path/to/valdi-vivaldi.vsix\ncode --install-extension /path/to/valdi-debug.vsix\n\n# For Cursor\ncursor --install-extension /path/to/valdi-vivaldi.vsix\ncursor --install-extension /path/to/valdi-debug.vsix\n```\n\n### 4. Configure TypeScript\n\nAfter creating your first Valdi project:\n- Open any TypeScript file (.tsx) in your project\n- Press `Cmd+Shift+P` (or Ctrl+Shift+P)\n- Select \"TypeScript: Select TypeScript Version...\"\n- Choose `Use Workspace Version`\n\n> [!IMPORTANT]\n> Selecting the workspace TypeScript version is crucial for proper development and cannot be automated.\n\n## Project Synchronization\n\nWhen you make changes to any of the following:\n\n- Dependencies\n- Localization files\n- Resource files\n\nRun this command to update your project configuration:\n\n```bash\nvaldi projectsync\n```\n\n## Troubleshooting\n\nIf you encounter any issues during setup:\n\n1. **Run diagnostics:**\n   ```bash\n   valdi doctor\n   ```\n   This will check your environment and provide specific fix suggestions.\n\n2. **Check prerequisites:**\n   - **macOS:** Ensure Xcode is installed and configured (`sudo xcode-select -s /Applications/Xcode.app`)\n   - **All platforms:** Ensure you have a stable internet connection for downloading dependencies\n\n3. **Review detailed setup guides:**\n   - [macOS Setup Reference](./setup/macos_setup.md)\n   - [Linux Setup Reference](./setup/linux_setup.md)\n\n4. **Get help:**\n   - Join our [Discord community](https://discord.gg/uJyNEeYX2U)\n   - Check [Troubleshooting Guide](./TROUBLESHOOTING.md)\n\n## Next Steps\n\nReady to start building? Check out:\n\n- [Getting Started Codelab](https://github.com/Snapchat/Valdi/blob/main/docs/codelabs/getting_started/1-introduction.md)\n- [Documentation](https://github.com/Snapchat/Valdi/tree/main/docs#the-basics)\n- [API Reference](https://github.com/Snapchat/Valdi/tree/main/docs/api)\n- [Command Line Reference](./docs/command-line-references.md)\n"
  },
  {
    "path": "docs/README.md",
    "content": "# Valdi Docs\n\n - [What is Valdi?](./docs/start-about.md)\n - [Getting Started with Valdi](./docs/start-install.md)\n - [Valdi Code Labs](./docs/start-code-lab.md)\n - [Valdi Command Line References](./docs/command-line-references.md)\n\n## Coming From Another Framework\n\n - [Migrating from React](./docs/start-from-react.md)\n - [Migrating from Flutter](./docs/migrate-from-flutter.md)\n - [Migrating from Jetpack Compose](./docs/migrate-from-compose.md)\n\n## API Reference\n\n - [API Reference](./api/api-reference-elements.md) - Comprehensive API documentation for all native elements\n - [Style Attributes Reference](./api/api-style-attributes.md) - Complete guide to all style attributes for each element type\n - [Quick Reference Guide](./api/api-quick-reference.md) - Quick lookup for commonly used properties\n\n## The Basics\n\n - [Valdi Module](./docs/core-module.md)\n - [The Mighty Component](./docs/core-component.md)\n - [Component States](./docs/core-states.md)\n - [Component Events](./docs/core-events.md)\n - [Control Flow](./docs/control-flow.md)\n - [FlexBox Layout](./docs/core-flexbox.md)\n - [`<layout>` and `<view>`](./docs/core-views.md)\n - [`<label>` and Text](./docs/core-text.md)\n - [`<image>`](./docs/core-images.md)\n - [`<video>`](./docs/core-video.md)\n - [`<scroll>`](./docs/core-scrolls.md)\n - [`<slot>`](./docs/core-slots.md)\n - [`Style<>`](./docs/core-styling.md)\n - [Touches and Gestures](./docs/core-touches.md)\n - [Navigation](./docs/navigation.md)\n \n ## Internals\n \n  - [Runtime Internals](./docs/internals-runtime.md) - Deep dive into `Valdi::Value`, memory management, and the binary protocol\n  - [Renderer Internals](./docs/internals-renderer.md) - Detailed explanation of the diffing algorithm and slot optimizations\n  - [Compiler Internals](./docs/internals-compiler.md) - Pipeline architecture and TSX transformation details\n  - [Native Integration Internals](./docs/internals-native-integration.md) - View factories, pooling, and attribute binding\n  - [API Design & Extensibility](./docs/internals-api-design.md) - Philosophy, bridge modules, and layered architecture\n \n ## Native Integration\n\n - [Annotations](./docs/native-annotations.md)\n - [Native Bindings](./docs/native-bindings.md)\n - [Polyglot Modules](./docs/native-polyglot.md)\n - [Component Context](./docs/native-context.md)\n - [View Model](./docs/native-view-model.md)\n - [Type Conversions](./docs/native-types.md)\n - [The `<custom-view>`](./docs/native-customviews.md)\n - [Native CollectionViews](./docs/native-collectionview.md)\n\n## Client Libraries\n - [Protobuf](./docs/advanced-protobuf.md)\n - [RxJS](./docs/client-libraries-rxjs.md)\n\n## Standard Library\n - [Core Utilities](./docs/stdlib-coreutils.md) - Array utilities, Base64, LRU Cache, MD5, UUID, and more\n - [HTTP Client](./docs/stdlib-http.md) - Promise-based HTTP client for network requests\n - [Persistent Storage](./docs/stdlib-persistence.md) - Key-value storage with encryption and TTL support\n - [File System](./docs/stdlib-filesystem.md) - Low-level file I/O operations (internal use)\n - [Glossary](./docs/glossary.md) - Comprehensive guide to Valdi terminology\n\n## Debugging Tools\n - [Hermes Debugger](./docs/workflow-hermes-debugger.md)\n - [Valdi Inspector](./docs/workflow-inspector.md)\n\n## Advanced Topics\n - [Animations](./docs/advanced-animations.md)\n - [Custom Image Loader](./docs/advanced-images.md)\n - [Localization](./docs/advanced-localization.md)\n - [Element References](./docs/advanced-element-references.md)\n - [Provider](./docs/advanced-provider.md)\n - [Native References](./docs/advanced-native-references.md)\n - [Worker Service](./docs/advanced-worker-service.md)\n - [Full stack Valdi](./docs/advanced-full-stack.md)\n\n## Performance\n - [Optimization](./docs/performance-optimization.md)\n - [Tracing](./docs/performance-tracing.md)\n - [Memory Leaks](./docs/performance-memory-leaks.md)\n - [View Recycling](./docs/performance-view-recycling.md)\n\n## Workflow\n - [SwiftPM, CocoaPods, Xcode and Gradle integration](./docs/workflow-external-build-system.md)\n - [Releasing to app stores](./docs/workflow-appstore-release.md)\n - [Building a CLI application](./docs/workflow-cli-application.md)\n - [Valdi rules for Bazel](./docs/workflow-bazel.md)\n - [Valdi Style Guide](./docs/workflow-style-guide.md)\n - [Valdi Inspector](./docs/workflow-inspector.md)\n - [Testing](./docs/workflow-testing.md)\n - [Hermes Debugger](./docs/workflow-hermes-debugger.md)\n - [Disk Management](./docs/workflow-disk.md)\n\n ## Misc\n - [Third party dependencies](./docs/third-party-dependencies.md)\n - [Frequently Asked Questions](./docs/faq.md)\n\n## Help\n - [Support](./docs/help-support.md)\n - [Troubleshooting](./docs/help-troubleshooting.md)\n"
  },
  {
    "path": "docs/TROUBLESHOOTING.md",
    "content": "# Troubleshooting\n\n## Installation\n\nA good first step is to search the web for the exact error output you see from the command.\n\nThese are common errors and how to resolve them.\n\n<details>\n    <summary><code>nvm not found</code></summary>\n\nIt's very likely either:\n\n- The post install instructions for `nvm` were missed, use `brew info nvm` and follow the instructions for updating your shell environment (e.g. `.zshrc`, `.bashrc`)\n\n```\nYou should create NVM's working directory if it doesn't exist:\nmkdir ~/.nvm\n\nAdd the following to your shell profile e.g. ~/.profile or ~/.zshrc:\nexport NVM_DIR=\"$HOME/.nvm\"\n[ -s \"/opt/homebrew/opt/nvm/nvm.sh\" ] && \\. \"/opt/homebrew/opt/nvm/nvm.sh\"  # This loads nvm\n[ -s \"/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm\" ] && \\. \"/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm\"  # This loads nvm bash_completion\n```\n\n- The shell you are currently using has not loaded the updated profile, eihter - close the terminal shell and open a new one - `source` the updated profile (e.g. `source ~/.zshrc`)\n</details>\n\n<details>\n    <summary><code>Swap Space</code></summary>\n\nBazel eats a lot of memory, if you see Java memory errors, you don't have enough swap space.\n\n8GB should be enough for an Android build of the hello world app.\n\n</details>\n"
  },
  {
    "path": "docs/api/api-quick-reference.md",
    "content": "# Native Template Elements - Quick Reference\n\nThis is a quick reference guide for the most commonly used properties of native template elements. For complete API documentation, see the [API Reference](api-reference-elements.md).\n\n## Common to All Elements\n\n```tsx\n// Layout & Sizing\nwidth={200}              // or \"50%\" or \"auto\"\nheight={100}             // or \"50%\" or \"auto\"\nminWidth={50}\nmaxWidth={500}\naspectRatio={1.5}        // width/height ratio\n\n// Positioning\nposition=\"absolute\"      // or \"relative\" (default)\ntop={10}\nleft={10}\nright={10}\nbottom={10}\n\n// Spacing\nmargin={10}              // or \"10 20 10 20\" or \"10\"\npadding={10}\nmarginTop={5}\npaddingLeft={10}\n\n// Flexbox\nflexDirection=\"row\"      // or \"column\" (default), \"row-reverse\", \"column-reverse\"\njustifyContent=\"center\"  // or \"flex-start\", \"flex-end\", \"space-between\", \"space-around\"\nalignItems=\"center\"      // or \"stretch\" (default), \"flex-start\", \"flex-end\", \"baseline\"\nflexGrow={1}\nflexShrink={1}\nflexWrap=\"wrap\"\n\n// Lifecycle\nonLayout={this.handleLayout}\nonVisibilityChanged={this.handleVisibilityChanged}\nref={myElementRef}\nkey=\"unique-key\"\nid=\"global-id\"\n\n// Performance\nlazy={true}              // Shorthand for lazyLayout + limitToViewport\nlazyLayout={true}\nlimitToViewport={true}\n\n// Accessibility\naccessibilityLabel=\"Tap to continue\"\naccessibilityHint=\"Opens the next screen\"\naccessibilityCategory=\"button\"\n```\n\n---\n\n## `<layout>`\n\n**Use for:** Invisible containers that don't need native views (best performance).\n\n```tsx\n<layout\n  width=\"100%\"\n  height={200}\n  flexDirection=\"row\"\n  justifyContent=\"space-between\"\n  padding={10}\n>\n  {/* children */}\n</layout>\n```\n\n---\n\n## `<view>`\n\n**Use for:** Visible containers that need background, borders, or gesture handling.\n\n```tsx\n<view\n  backgroundColor=\"#ffffff\"\n  borderRadius={8}\n  borderWidth={1}\n  borderColor=\"#dddddd\"\n  opacity={0.9}\n  boxShadow=\"0 2 10 rgba(0,0,0,0.1)\"\n  \n  // Gestures\n  onTap={this.handleTap}\n  onLongPress={this.handleLongPress}\n  onDrag={this.handleDrag}\n  touchEnabled={true}\n  \n  // Transform\n  scaleX={1.2}\n  scaleY={1.2}\n  rotation={0.5}  // radians\n  translationX={10}\n  translationY={10}\n>\n  {/* children */}\n</view>\n```\n\n---\n\n## `<scroll>`\n\n**Use for:** Scrollable containers.\n\n```tsx\n<scroll\n  horizontal={false}     // true for horizontal scrolling\n  height={400}\n  width=\"100%\"\n  \n  // Scroll events\n  onScroll={this.handleScroll}\n  onScrollEnd={this.handleScrollEnd}\n  onDragStart={this.handleDragStart}\n  \n  // Behavior\n  bounces={true}\n  pagingEnabled={false}\n  scrollEnabled={true}\n  showsVerticalScrollIndicator={true}\n  dismissKeyboardOnDrag={false}\n  \n  // Viewport extensions (for preloading)\n  viewportExtensionTop={100}\n  viewportExtensionBottom={100}\n>\n  {/* scrollable children */}\n</scroll>\n\n// Programmatic scrolling (via ref):\nmyScrollRef.setAttribute('contentOffsetY', 500);\nmyScrollRef.setAttribute('contentOffsetAnimated', true);\n```\n\n---\n\n## `<image>`\n\n**Use for:** Displaying images from assets or URLs.\n\n```tsx\n<image\n  src={res.myImage}      // or \"https://example.com/image.png\"\n  width={200}\n  height={200}\n  \n  // Display\n  objectFit=\"cover\"      // or \"fill\", \"contain\", \"none\"\n  tint=\"#ff0000\"\n  flipOnRtl={false}\n  \n  // Transform\n  contentScaleX={1}\n  contentScaleY={1}\n  contentRotation={0}    // radians\n  \n  // Callbacks\n  onAssetLoad={this.handleAssetLoad}\n  onImageDecoded={this.handleImageDecoded}\n  \n  // Filters\n  filter={myImageFilter}\n/>\n```\n\n---\n\n## `<video>`\n\n**Use for:** Video playback.\n\n```tsx\n<video\n  src=\"https://example.com/video.mp4\"\n  width={400}\n  height={300}\n  \n  // Playback control\n  volume={0.8}           // 0.0 to 1.0\n  playbackRate={1}       // 0=paused, 1=playing\n  seekToTime={5000}      // milliseconds\n  \n  // Callbacks\n  onVideoLoaded={this.handleVideoLoaded}\n  onBeginPlaying={this.handleBeginPlaying}\n  onError={this.handleError}\n  onCompleted={this.handleCompleted}\n  onProgressUpdated={this.handleProgressUpdated}\n/>\n```\n\n---\n\n## `<label>`\n\n**Use for:** Displaying text.\n\n```tsx\n<label\n  value=\"Hello World\"    // or attributedText\n  \n  // Text styling\n  font=\"AvenirNext-Bold 16 unscaled 16\"\n  color=\"#000000\"\n  textGradient=\"linear-gradient(#ff0000, #0000ff)\"\n  textShadow=\"rgba(0,0,0,0.1) 1 1 1 1\"\n  \n  // Layout\n  numberOfLines={2}      // 0 = unlimited\n  textAlign=\"left\"       // or \"center\", \"right\", \"justified\"\n  textDecoration=\"none\"  // or \"underline\", \"strikethrough\"\n  lineHeight={1.2}       // ratio of font height\n  letterSpacing={0}      // points\n  textOverflow=\"ellipsis\" // or \"clip\"\n  \n  // Auto-sizing\n  adjustsFontSizeToFitWidth={false}\n  minimumScaleFactor={0.5}\n/>\n```\n\n---\n\n## `<textfield>`\n\n**Use for:** Single-line text input.\n\n```tsx\n<textfield\n  value={this.state.text}\n  placeholder=\"Enter text...\"\n  placeholderColor=\"#999999\"\n  \n  // Keyboard\n  contentType=\"default\"  // or \"email\", \"phoneNumber\", \"password\", \"number\"\n  returnKeyText=\"done\"   // or \"go\", \"join\", \"next\", \"search\", \"send\"\n  autocapitalization=\"sentences\"\n  autocorrection=\"default\"\n  keyboardAppearance=\"default\"\n  \n  // Behavior\n  enabled={true}\n  textAlign=\"left\"\n  characterLimit={50}\n  selectTextOnFocus={false}\n  closesWhenReturnKeyPressed={true}\n  \n  // Callbacks\n  onChange={this.handleChange}\n  onEditBegin={this.handleEditBegin}\n  onEditEnd={this.handleEditEnd}\n  onReturn={this.handleReturn}\n  onWillDelete={this.handleWillDelete}\n  onSelectionChange={this.handleSelectionChange}\n/>\n\n// Programmatic focus (via ref):\nmyTextFieldRef.setAttribute('focused', true);\n```\n\n---\n\n## `<textview>`\n\n**Use for:** Multi-line text input.\n\n```tsx\n<textview\n  value={this.state.text}\n  placeholder=\"Enter text...\"\n  \n  // Similar to textfield, plus:\n  returnType=\"linereturn\" // or any TextFieldReturnKeyText\n  textGravity=\"top\"       // or \"center\", \"bottom\"\n  closesWhenReturnKeyPressed={false}\n  \n  // Background effect\n  backgroundEffectColor=\"#ffffff\"\n  backgroundEffectBorderRadius={4}\n  backgroundEffectPadding={2}\n  \n  onChange={this.handleChange}\n/>\n```\n\n---\n\n## `<blur>`\n\n**Use for:** Blur effects (iOS primarily).\n\n```tsx\n<blur\n  blurStyle=\"systemMaterial\"  // Many options available\n  width={300}\n  height={300}\n>\n  {/* children rendered on top of blur */}\n</blur>\n```\n\n---\n\n## `<spinner>`\n\n**Use for:** Loading indicators.\n\n```tsx\n<spinner\n  color=\"#007AFF\"\n  width={40}\n  height={40}\n/>\n```\n\n---\n\n## `<shape>`\n\n**Use for:** Custom vector shapes.\n\n```tsx\n<shape\n  path={myGeometricPath}\n  width={100}\n  height={100}\n  \n  // Stroke\n  strokeWidth={2}\n  strokeColor=\"#000000\"\n  strokeCap=\"round\"      // or \"butt\", \"square\"\n  strokeJoin=\"round\"     // or \"bevel\", \"miter\"\n  strokeStart={0}        // 0 to 1, animatable\n  strokeEnd={1}          // 0 to 1, animatable\n  \n  // Fill\n  fillColor=\"#ff0000\"\n/>\n```\n\n---\n\n## `<animatedimage>`\n\n**Use for:** Lottie animations and animated images.\n\n```tsx\n<animatedimage\n  src={res.myLottie}\n  width={200}\n  height={200}\n  \n  // Animation control\n  loop={true}\n  advanceRate={1}        // 0=paused, 1=normal, -1=reverse\n  currentTime={0}        // seconds\n  animationStartTime={0} // seconds\n  animationEndTime={5}   // seconds\n  \n  // Display\n  objectFit=\"contain\"    // or \"fill\", \"cover\", \"none\"\n  \n  // Fonts\n  fontProvider={myFontProvider}\n  \n  // Callbacks\n  onAssetLoad={this.handleAssetLoad}\n  onImageDecoded={this.handleImageDecoded}\n  onProgress={this.handleProgress}\n/>\n```\n\n---\n\n## `<slot>`\n\n**Use for:** Content projection in components.\n\n```tsx\n// In component:\n<layout>\n  <slot name=\"header\" />\n  <slot /> {/* default slot */}\n  <slot name=\"footer\" />\n</layout>\n\n// When using component:\n<MyComponent>\n  <layout slot=\"header\">Header content</layout>\n  <layout>Default content</layout>\n  <layout slot=\"footer\">Footer content</layout>\n</MyComponent>\n```\n\n---\n\n## ⚠️ Important: Event Handlers\n\n**Never use inline anonymous functions in TSX.** Always define event handlers as component methods.\n\n**❌ DON'T do this:**\n\n```tsx\nclass MyComponent extends Component {\n  onRender() {\n    <view onTap={() => {\n      // This creates a new function on every render!\n      console.log('tapped');\n    }} />\n  }\n}\n```\n\n**✅ DO this instead:**\n\n```tsx\nclass MyComponent extends Component {\n  onRender() {\n    <view onTap={this.handleTap} />\n  }\n\n  private handleTap = () => {\n    console.log('tapped');\n  }\n}\n```\n\n**Why?** Inline functions create a new function instance on every render, which:\n- Causes unnecessary re-renders and performance issues\n- Breaks the diff algorithm's ability to detect unchanged callbacks\n- Triggers updates to the backing native view on every render\n\n> **See also:** [Performance Optimization](../docs/performance-optimization.md#using-callbacks-in-elements) for more details.\n\n---\n\n## Common Patterns\n\n### Centered Content\n\n```tsx\n<layout width=\"100%\" height=\"100%\" justifyContent=\"center\" alignItems=\"center\">\n  <label value=\"Centered!\" />\n</layout>\n```\n\n### Card with Shadow\n\n```tsx\n<view\n  backgroundColor=\"#ffffff\"\n  borderRadius={12}\n  boxShadow=\"0 4 20 rgba(0,0,0,0.15)\"\n  padding={16}\n  margin={16}\n>\n  {/* card content */}\n</view>\n```\n\n### Horizontal Scroll\n\n```tsx\n<scroll horizontal={true} height={200} width=\"100%\">\n  <layout flexDirection=\"row\">\n    {items.map(item => (\n      <view key={item.id} width={150} height={150} margin={10}>\n        {/* item content */}\n      </view>\n    ))}\n  </layout>\n</scroll>\n```\n\n### Form Input\n\n```tsx\nclass EmailForm extends Component {\n  onRender() {\n    <layout padding={20}>\n      <label value=\"Email\" marginBottom={8} />\n      <textfield\n        contentType=\"email\"\n        placeholder=\"your@email.com\"\n        backgroundColor=\"#f5f5f5\"\n        borderRadius={8}\n        padding={12}\n        onChange={this.handleEmailChange}\n      />\n    </layout>\n  }\n\n  private handleEmailChange = (event) => {\n    this.setState({ email: event.text });\n  }\n}\n```\n\n---\n\n## TypeScript Types\n\n### Events\n\n```typescript\nimport { TouchEvent, DragEvent, ScrollEvent } from 'valdi_tsx/src/GestureEvents';\nimport { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { EditTextEvent, EditTextEndEvent } from 'valdi_tsx/src/NativeTemplateElements';\n```\n\n### Refs\n\n```typescript\nimport { IRenderedElementHolder } from 'valdi_tsx/src/IRenderedElementHolder';\n\nprivate myViewRef = new IRenderedElementHolder<View>();\n\n// In render:\n<view ref={this.myViewRef} />\n\n// Later:\nconst element = this.myViewRef.getElement();\nif (element) {\n  element.setAttribute('backgroundColor', '#ff0000');\n}\n```\n\n---\n\n## See Also\n\n- [Complete API Reference](api-reference-elements.md) - Full documentation with all properties\n- [Core Views Guide](../docs/core-views.md) - Layout and view best practices\n- [Core Flexbox](../docs/core-flexbox.md) - Understanding flexbox layout\n- [Core Images](../docs/core-images.md) - Working with images\n- [Core Scrolls](../docs/core-scrolls.md) - ScrollView patterns\n- [Core Text](../docs/core-text.md) - Text and input components\n\n"
  },
  {
    "path": "docs/api/api-reference-elements.md",
    "content": "# API Reference\n\nThis document provides a comprehensive reference for all native template elements and their properties, methods, and types.\n\n## Table of Contents\n\n- [Layout](#layout)\n- [View](#view)\n- [ScrollView](#scrollview)\n- [ImageView](#imageview)\n- [VideoView](#videoview)\n- [Label](#label)\n- [TextField](#textfield)\n- [TextView](#textview)\n- [BlurView](#blurview)\n- [SpinnerView](#spinnerview)\n- [ShapeView](#shapeview)\n- [AnimatedImage](#animatedimage)\n- [Slot](#slot)\n- [Common Types](#common-types)\n\n> **Note:** Layout and positioning attributes are powered by [Yoga](https://github.com/facebook/yoga) (commit [`0be0e9fc`](https://github.com/facebook/yoga/commit/0be0e9fc0148aa609afdc31cb9670524f07050cb)). See [Style Attributes Reference](api-style-attributes.md#yoga-layout-engine) for Yoga version details and flexbox behavior.\n\n---\n\n## Layout\n\n**JSX Element:** `<layout>`\n\nRepresents a node in the layout tree. Use a `<layout>` instead of `<view>` whenever possible, since these nodes will not be backed by a platform view when rendering, making them more performant.\n\n### Properties\n\n#### Layout Attributes\n\n##### Lifecycle Callbacks\n\n**`onLayout`**: `(frame: ElementFrame) => void`\n- Called whenever the calculated frame for the element has changed.\n\n**`onVisibilityChanged`**: `(isVisible: boolean, eventTime: EventTime) => void`\n- Called whenever the visibility for the element has changed.\n\n**`onViewportChanged`**: `(viewport: ElementFrame, frame: ElementFrame, eventTime: EventTime) => void`\n- Called whenever the calculated viewport for the element has changed.\n- The viewport represents the rectangle area within the element's frame that is visible.\n\n**`onLayoutComplete`**: `() => void`\n- Called after a layout pass has completed, if this node or any of its children were updated.\n\n**`onMeasure`**: `OnMeasureFunc`\n- If set, the node will be set as a lazyLayout, and the given measure callback will be called whenever the node needs to be measured.\n- The callback should return a MeasuredSize tuple representing how big the node should be.\n- Type: `(width: number, widthMode: MeasureMode, height: number, heightMode: MeasureMode) => MeasuredSize`\n\n##### Performance Optimization\n\n**`lazyLayout`**: `boolean`\n- Whether the layout starting from this element should be lazy.\n- A lazy layout is disconnected from its parent layout; its children cannot impact the layout of the parent.\n- Setting this to true will defer layout calculation for all the children until this layout is determined to be visible.\n- This can help with performance when the layout is within a ScrollView.\n- Default: `false`\n\n**`limitToViewport`**: `boolean`\n- Whether the backing native View instance should only be created if the element is visible within the viewport.\n- Setting this to true can help with performance when the view is within a ScrollView.\n- Default: `true`\n\n**`lazy`**: `boolean`\n- Shorthand for lazyComponent, lazyLayout and limitToViewport.\n- Default: `false`\n\n**`estimatedWidth`**: `number`\n- If set, the node will use this value as the base width that the node should measure at before the children are inserted.\n- This is typically used on nodes that represent an empty placeholder that are later rendered with children.\n\n**`estimatedHeight`**: `number`\n- If set, the node will use this value as the base height that the node should measure at before the children are inserted.\n\n##### Identity & References\n\n**`id`**: `string`\n- Used to uniquely identify an element in the global valdi context.\n\n**`key`**: `string`\n- A key to uniquely identify the element.\n- If it is not provided, the framework will generate one based on the index in which the element is being rendered.\n\n**`ref`**: `IRenderedElementHolder<this>`\n- Sets an element reference holder, which will keep track of the rendered elements.\n\n##### Visual Properties\n\n**`animationsEnabled`**: `boolean`\n- Can be used to disable animations for this element and its children.\n- Default: `true`\n\n**`zIndex`**: `number`\n- Loosely, zIndex specifies the order in which siblings are layered on top of each other.\n- Higher zIndex will mean that an element will be rendered \"on top\" of its siblings.\n- Specifying a zIndex will make the framework sort this element and its siblings before rendering the view tree.\n\n**`class`**: `string`\n- Sets a CSS class to use from the associated CSS document.\n- You typically would use the style property directly instead.\n\n**`ignoreParentViewport`**: `boolean`\n- Whether the calculated viewport for this element should not be intersected with the viewport of the parent.\n- This allows a child to have a viewport bigger than its parent.\n\n#### Size Properties\n\n**`width`**: `CSSValue` (string | number)\n- Specifies the width of an element's content area.\n- `auto` (default): width for the element based on its content.\n- points: Defines the width in absolute points.\n- percentage: Defines the width in percentage of its parent's width.\n\n**`height`**: `CSSValue`\n- Specifies the height of an element's content area.\n- `auto` (default): height for the element based on its content.\n- points: Defines the height in absolute points.\n- percentage: Defines the height in percentage of its parent's height.\n\n**`minWidth`**: `CSSValue`\n- Specifies the minimum width of an element's content area.\n\n**`minHeight`**: `CSSValue`\n- Specifies the minimum height of an element's content area.\n\n**`maxWidth`**: `CSSValue`\n- Specifies the maximum width of an element's content area.\n\n**`maxHeight`**: `CSSValue`\n- Specifies the maximum height of an element's content area.\n\n**`aspectRatio`**: `number`\n- Specifies the aspect ratio of an element's content area.\n- Defined as the ratio between the width and the height of a node.\n- e.g. if a node has an aspect ratio of 2 then its width is twice the size of its height.\n\n#### Position Properties\n\n**`position`**: `'relative' | 'absolute'`\n- The position type of an element defines how it is positioned within its parent.\n- `relative` (default): positioned according to the normal flow of the layout, then offset relative to that position based on the values of top, right, bottom, and left.\n- `absolute`: doesn't take part in the normal layout flow. Position is determined based on the top, right, bottom, and left values.\n\n**`top`**: `CSSValue`\n- Used with `position` to offset the element from its normal position or parent.\n\n**`right`**: `CSSValue`\n- Used with `position` to offset the element from its normal position or parent.\n\n**`bottom`**: `CSSValue`\n- Used with `position` to offset the element from its normal position or parent.\n\n**`left`**: `CSSValue`\n- Used with `position` to offset the element from its normal position or parent.\n\n#### Spacing Properties\n\n**`margin`**: `string | number`\n- Margin affects the spacing around the outside of a node.\n- A node with margin will offset itself from the bounds of its parent but also offset the location of any siblings.\n\n**`marginTop`**: `CSSValue`\n\n**`marginRight`**: `CSSValue`\n\n**`marginBottom`**: `CSSValue`\n\n**`marginLeft`**: `CSSValue`\n\n**`padding`**: `string | number`\n- Padding affects the size of the node it is applied to.\n- Padding will not add to the total size of an element if it has an explicit size set.\n\n**`paddingTop`**: `CSSValue`\n\n**`paddingRight`**: `CSSValue`\n\n**`paddingBottom`**: `CSSValue`\n\n**`paddingLeft`**: `CSSValue`\n\n#### Flexbox Properties\n\n**`display`**: `'flex' | 'none'`\n- Choose the display mode.\n- `flex`: use flexbox layout system\n- `none`: do not display this element\n- Default: `'flex'`\n\n**`overflow`**: `'visible' | 'scroll'`\n- Specifies how the parent will react to its children overflowing its boundaries.\n- `visible`: overflowing children elements will stretch the parent container\n- `scroll`: the parent container's size will not be affected by the children element's bounds\n- Default for layout elements: `'visible'`\n- Default for scroll elements: `'scroll'`\n\n**`direction`**: `'inherit' | 'ltr' | 'rtl'`\n- Layout direction specifies the direction in which children and text in a hierarchy should be laid out.\n- `inherit` (default): Use the parent's direction value\n- `ltr`: Text and children laid out from left to right\n- `rtl`: Text and children laid out from right to left\n- Default: `'inherit'`\n\n**`flexDirection`**: `'column' | 'column-reverse' | 'row' | 'row-reverse'`\n- Controls the direction in which children of a node are laid out.\n- `column` (default): Align children from top to bottom\n- `column-reverse`: Align children from bottom to top\n- `row`: Align children from left to right\n- `row-reverse`: Align children from right to left\n- Default: `'column'`\n\n**`flexWrap`**: `'no-wrap' | 'wrap' | 'wrap-reverse'`\n- Set on containers and controls what happens when children overflow the size of the container along the main axis.\n- Default: children are forced into a single line\n- `wrap`: items are wrapped into multiple lines along the main axis if needed\n- `wrap-reverse`: same as wrap but the order of the lines is reversed\n\n**`justifyContent`**: `'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly'`\n- Describes how to align children within the main axis of their container.\n- `flex-start` (default): Align children to the start of the container's main axis\n- `flex-end`: Align children to the end\n- `center`: Align children in the center\n- `space-between`: Evenly space children, distributing remaining space between them\n- `space-around`: Evenly space children, distributing remaining space around them\n- `space-evenly`: Evenly distributed with equal spacing\n- Default: `'flex-start'`\n\n**`alignContent`**: `'flex-start' | 'flex-end' | 'stretch' | 'center' | 'space-between' | 'space-around'`\n- Defines the distribution of lines along the cross-axis.\n- Only has effect when items are wrapped to multiple lines using `flexWrap`.\n- Default: `'flex-start'`\n\n**`alignItems`**: `'stretch' | 'flex-start' | 'flex-end' | 'center' | 'baseline'`\n- Describes how to align children along the cross axis of their container.\n- `stretch` (default): Stretch children to match the height of the container's cross axis\n- `flex-start`: Align children to the start of the container's cross axis\n- `flex-end`: Align children to the end\n- `center`: Align children in the center\n- `baseline`: Align children along a common baseline\n- Default: `'stretch'`\n\n**`alignSelf`**: `'auto' | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'`\n- Overrides the parent's `alignItems` for this specific child.\n\n**`flexGrow`**: `number`\n- Describes how any space within a container should be distributed among its children along the main axis.\n- Accepts any floating point value >= 0\n- Default: `0`\n\n**`flexShrink`**: `number`\n- Describes how to shrink children along the main axis when the total size of the children overflow the size of the container.\n- Accepts any floating point value >= 0\n- Default: `0`\n\n**`flexBasis`**: `CSSValue`\n- Provides the default size of an item along the main axis.\n- Similar to setting width (for row) or height (for column).\n\n**`extendViewportWithChildren`**: `boolean`\n- Whether the calculated viewport for the element should be potentially extended by taking into account the space of all the children.\n- By default, a child element outside the bounds of the parent element is considered invisible.\n- When this flag is true, the bounds of the parent will be extended such that the children are always visible.\n- This flag should be used rarely and in very specific circumstances.\n- Default: `false`\n\n#### Accessibility Properties\n\n**`accessibilityCategory`**: `'auto' | 'view' | 'text' | 'button' | 'image' | 'image-button' | 'input' | 'header' | 'link' | 'checkbox' | 'radio' | 'keyboard-key'`\n- Specify meta information that can then be used by accessibility technologies.\n- Default: `'auto'`\n\n**`accessibilityNavigation`**: `'auto' | 'passthrough' | 'leaf' | 'cover' | 'group' | 'ignored'`\n- Specify the way the element should behave during navigation by accessibility technologies.\n- `auto`: automatically chosen depending on the element\n- `passthrough`: element is not focusable, but its children may be accessed\n- `leaf`: element is fully focusable and interactive but none of its children are navigatable\n- `cover`: element is first fully focusable and interactive and afterward its children can also be accessed\n- `group`: element may be announced but not focused and its children may also be accessed\n- `ignored`: element and all its children will be ignored, unnavigatable and unfocusable\n- Default: `'auto'`\n\n**`accessibilityPriority`**: `number | AccessibilityPriority`\n- Specify the local priority of the element (compared to its direct sibling) for accessibility navigation sequential ordering.\n- All sibling elements are sorted by descending priority during accessibility navigation.\n- Default: `0`\n\n**`accessibilityLabel`**: `string`\n- Defines the information being displayed.\n- When an element is accessed by accessibility technologies, VoiceOver/TalkBack will read this string.\n\n**`accessibilityHint`**: `string`\n- Defines the purpose of this element.\n- Additional hint that helps users understand what will happen when they perform an action on the accessibility element.\n\n**`accessibilityValue`**: `string`\n- For elements that intrinsically contain information (such as textinputs or sliders).\n- Especially when it may be dynamic, we need to provide its current value.\n\n**`accessibilityStateDisabled`**: `boolean`\n- For dynamic and interactive elements, indicate that the element is temporarily disabled.\n- Default: `false`\n\n**`accessibilityStateSelected`**: `boolean`\n- For dynamic and interactive elements, set the current selection status.\n- Default: `false`\n\n**`accessibilityStateLiveRegion`**: `boolean`\n- For dynamic and interactive elements, indicate that the element frequently updates its label, value or children.\n- Default: `false`\n\n#### Styling\n\n**`style`**: `IStyle<Layout>`\n- Styling object allows setting multiple attributes at once.\n- See [Layout Style Attributes](api-style-attributes.md#layout-styles) for a complete list of attributes that can be used in `Style<Layout>`.\n\n---\n\n## View\n\n**JSX Element:** `<view>`\n\n**iOS Native:** `SCValdiView`  \n**Android Native:** `com.snap.valdi.views.ValdiView`\n\nRepresents a node in the layout tree backed by a native platform view. Use a `<layout>` instead of `<view>` whenever possible for better performance.\n\n### Properties\n\nAll properties from [Layout](#layout), plus:\n\n#### Lifecycle Callbacks\n\n**`onViewCreate`**: `() => void`\n- Called whenever the backing native view is created.\n\n**`onViewDestroy`**: `() => void`\n- Called whenever the backing native view is destroyed.\n\n**`onViewChange`**: `(nativeView: NativeView | undefined) => void`\n- Called whenever the backing native view is created or destroyed.\n- @deprecated use `IRenderedElement.getNativeNode`\n\n**`allowReuse`**: `boolean`\n- Whether the backing native View instance can be re-used.\n- By default, View instances are re-used across screens.\n- By setting this to false, the view instance will be guaranteed to be new and not re-used from the view pool.\n- Default: `true`\n\n#### Appearance\n\n**`background`**: `string`\n- Sets the background of the view.\n- Use `\"color1\"` to set a color.\n- Use `\"linear-gradient(color1, color2, color3...)\"` to set a gradient with evenly-spaced stops.\n- Use `\"linear-gradient(color1 stop1, color2 stop2, color3 stop3...)\"` to set a gradient with custom stops.\n\n**`backgroundColor`**: `Color` (string)\n- Sets the background color of the view.\n- `undefined` sets a clear color.\n\n**`opacity`**: `number`\n- Sets the opacity of the view.\n- Accepts values: [0.0 - 1.0]\n- Note: Making a view non-opaque will require layer blending.\n\n**`slowClipping`**: `boolean`\n- Enables clipping of the view's contents based on the view's borders.\n- Warning: degrades performance, avoid using if possible.\n- Default: `false`\n\n#### Border Properties\n\n**`border`**: `string`\n- Short-hand for all the borderXXX attributes.\n\n**`borderWidth`**: `CSSValue`\n- Sets the width of an element's border.\n- Note: make sure to set the borderColor\n- Default: `0`\n\n**`borderColor`**: `Color`\n- Sets the color of an element's four borders.\n- Note: make sure to set the borderWidth for the border to be visible\n- Default: `black`\n\n**`borderRadius`**: `CSSValue`\n- Defines the radius of the element's corners.\n- Can specify radius on a per-corner basis: `\"5 10 0 20\"` (top/left/right/bottom)\n- Or set all corners at once: `\"10\"`\n- Default: `0`\n\n**`boxShadow`**: `string`\n- Add a shadow to the view.\n- Syntax: `'{xOffset} {yOffset} {shadowOverflow} {color}'`\n- All number values are interpreted as points.\n- Example: `\"0 2 10 rgba(0, 0, 0, 0.1)\"`\n\n#### Gesture Properties\n\n**`touchEnabled`**: `boolean`\n- Set this to `false` to disable any user interactions on this view and its children.\n- Default: `true`\n\n**`hitTest`**: `(event: TouchEvent) => boolean`\n- Determines if a given view can capture any touches.\n\n**`onTouch`**: `(event: TouchEvent) => void`\n- Event handler called on every touch event captured by this view (started, changed, ended).\n\n**`onTouchStart`**: `(event: TouchEvent) => void`\n- Event handler called on the 'started' touch events captured by this view.\n\n**`onTouchEnd`**: `(event: TouchEvent) => void`\n- Event handler called on the 'ended' touch events captured by this view.\n\n**`onTouchDelayDuration`**: `number`\n- Specifies the minimum duration, in seconds, for an onTouch event to trigger.\n- When not set, will be zero.\n\n##### Tap Gestures\n\n**`onTapDisabled`**: `boolean`\n- Set to `true` to disable tap completely.\n- Default: `false`\n\n**`onTap`**: `(event: TouchEvent) => void`\n- The handler that will be called when the user performs a tap gesture on this view.\n\n**`onTapPredicate`**: `(event: TouchEvent) => boolean`\n- The predicate used to decide whether the tap gesture should be recognized.\n- Prefer using `onTapDisabled` if the decision can be made without TouchEvent data.\n\n##### Double Tap Gestures\n\n**`onDoubleTapDisabled`**: `boolean`\n- Set to `true` to disable double tap completely.\n- Default: `false`\n\n**`onDoubleTap`**: `(event: TouchEvent) => void`\n- Handler called when the user performs a double tap gesture.\n\n**`onDoubleTapPredicate`**: `(event: TouchEvent) => boolean`\n- Predicate to decide whether the double tap gesture should be recognized.\n\n##### Long Press Gestures\n\n**`longPressDuration`**: `number`\n- Specifies the minimum duration, in seconds, for a long press to trigger.\n- When not set, will use a platform provided default.\n\n**`onLongPressDisabled`**: `boolean`\n- Set to `true` to disable long press completely.\n- Default: `false`\n\n**`onLongPress`**: `(event: TouchEvent) => void`\n- Handler called when the user performs a long press gesture.\n\n**`onLongPressPredicate`**: `(event: TouchEvent) => boolean`\n- Predicate to decide whether the long press gesture should be recognized.\n\n##### Drag Gestures\n\n**`onDragDisabled`**: `boolean`\n- Set to `true` to disable drag completely.\n- Default: `false`\n\n**`onDrag`**: `(event: DragEvent) => void`\n- Handler called when the user performs a dragging gesture that started on this view.\n\n**`onDragPredicate`**: `(event: DragEvent) => boolean`\n- Predicate to decide whether the drag gesture should be recognized.\n\n##### Pinch Gestures\n\n**`onPinchDisabled`**: `boolean`\n- Set to `true` to disable pinch completely.\n- Default: `false`\n\n**`onPinch`**: `(event: PinchEvent) => void`\n- Handler called when the user performs a pinch gesture on this view.\n\n**`onPinchPredicate`**: `(event: PinchEvent) => boolean`\n- Predicate to decide whether the pinch gesture should be recognized.\n\n##### Rotate Gestures\n\n**`onRotateDisabled`**: `boolean`\n- Set to `true` to disable rotate completely.\n- Default: `false`\n\n**`onRotate`**: `(event: RotateEvent) => void`\n- Handler called when the user performs a rotate gesture on this view.\n\n**`onRotatePredicate`**: `(event: RotateEvent) => boolean`\n- Predicate to decide whether the rotate gesture should be recognized.\n\n#### Touch Area Extension\n\n**`touchAreaExtension`**: `number`\n- Can be used to increase the view's touch target area.\n\n**`touchAreaExtensionTop`**: `number`\n\n**`touchAreaExtensionRight`**: `number`\n\n**`touchAreaExtensionBottom`**: `number`\n\n**`touchAreaExtensionLeft`**: `number`\n\n#### Transform Properties\n\n**`scaleX`**: `number`\n- Specifies the horizontal scale component of the affine transformation to be applied to the view.\n\n**`scaleY`**: `number`\n- Specifies the vertical scale component of the affine transformation to be applied to the view.\n\n**`rotation`**: `number`\n- Specifies the rotation component in angle radians of the affine transformation to be applied to the view.\n\n**`translationX`**: `number`\n- Specifies the horizontal translation component of the affine transformation to be applied to the view.\n- Note: When the device is in RTL mode, the applied translationX value will be flipped.\n\n**`translationY`**: `number`\n- Specifies the vertical translation component of the affine transformation to be applied to the view.\n\n#### Mask Properties\n\n**`maskOpacity`**: `number`\n- Set an opacity to use on mask.\n- The opacity defines how much the mask should \"erase\" pixels that match the maskPath.\n- Opacity of 1 will make all the pixels matching the path transparent.\n- Default: `1`\n\n**`maskPath`**: `GeometricPath`\n- Set a geometric path to use as a mask on the given view.\n- Pixels that are within the given path will be turned transparent relative to the maskOpacity.\n\n#### Platform-Specific\n\n**`accessibilityId`**: `string`\n- Sets the view's accessibility identifier.\n- Commonly used to identify UI elements in UI tests.\n\n**`canAlwaysScrollHorizontal`**: `boolean`\n- Forces the platform surface method canScroll to always return true for horizontal touch events.\n- This property can be used to ensure that any platform-specific gesture handlers can be ignored when a valdi module would capture the event.\n\n**`canAlwaysScrollVertical`**: `boolean`\n- Forces the platform surface method canScroll to always return true for vertical touch events.\n\n**`filterTouchesWhenObscured`**: `boolean`\n- Optionally set filterTouchesWhenObscured for payment sensitive button on Android.\n- Not used for iOS.\n\n#### Styling\n\n**`style`**: `IStyle<View | Layout>`\n- Styling object allows setting multiple attributes at once.\n- See [View Style Attributes](api-style-attributes.md#view-styles) for a complete list of attributes that can be used in `Style<View>`.\n\n---\n\n## ScrollView\n\n**JSX Element:** `<scroll>`\n\n**iOS Native:** `SCValdiScrollView`  \n**Android Native:** `com.snap.valdi.views.ValdiScrollView`\n\nA view that provides scrolling functionality for its children.\n\n### Properties\n\nAll properties from [View](#view), except `flexDirection` (which is replaced by `horizontal`), plus:\n\n#### Scroll Event Callbacks\n\n**`onScroll`**: `(event: ScrollEvent) => void`\n- Called when the content offset of the scrollview changed.\n\n**`onScrollEnd`**: `(event: ScrollEndEvent) => void`\n- Called when the content offset of the scrollview has settled.\n\n**`onDragStart`**: `(event: ScrollEvent) => void`\n- Called when the user starts dragging the scroll content.\n\n**`onDragEnding`**: `(event: ScrollDragEndingEvent) => ScrollOffset | undefined`\n- Called synchronously when the ScrollView will end dragging.\n- The called function can return a scroll offset that should be used to replace the content offset where the scroll view should settle.\n\n**`onDragEnd`**: `(event: ScrollDragEndEvent) => void`\n- Called when the ScrollView ended dragging.\n- This will be called right after onDragEnding() is called, and will be called asynchronously.\n- The scroll view might still be animating its scroll at this point.\n\n**`onContentSizeChange`**: `(event: ContentSizeChangeEvent) => void`\n- Called whenever the content size of the scroll view has changed.\n\n#### Scroll Behavior\n\n**`horizontal`**: `boolean`\n- When enabled, the scroll view will allow horizontal scrolling instead of vertical.\n- Note: this attribute replaces flexDirection.\n- When enabled, children will be laid out as if flexDirection=\"row\" was set.\n- When disabled, children will be laid out as if flexDirection=\"column\" was set.\n- Default: `false`\n\n**`flexDirection`**: `never`\n- FlexDirection is not available on scroll views.\n- It can be set through the \"horizontal\" attribute.\n\n**`scrollEnabled`**: `boolean`\n- When enabled, the scroll view can be scrolled by the user.\n- Default: `true`\n\n**`pagingEnabled`**: `boolean`\n- When enabled, the scroll content offset will always settle on a multiple of the scrollview's size.\n- Default: `false`\n\n#### Bounce/Overscroll\n\n**`bounces`**: `boolean`\n- Configure whether or not there should be a visual effect when the user tries to scroll past the scroll boundaries.\n- On iOS: this visually looks like letting the user \"bounce\" on the edge of the scroll view.\n- On Android: this looks like a glow or squish effect that follows the finger or a bounce if using skia.\n- Default: `true`\n\n**`bouncesFromDragAtStart`**: `boolean`\n- Allow bouncing by dragging even when the content offset is already at the minimum.\n- Default: `true`\n\n**`bouncesFromDragAtEnd`**: `boolean`\n- Allow bouncing by dragging even when the content offset is already at the maximum.\n- Default: `true`\n\n**`bouncesVerticalWithSmallContent`**: `boolean`\n- Allow bouncing even when the vertical content size is smaller than the scroll itself.\n- Default: `false`\n\n**`bouncesHorizontalWithSmallContent`**: `boolean`\n- Allow bouncing even when the horizontal content size is smaller than the scroll itself.\n- Default: `false`\n\n#### Touch/Gesture Behavior\n\n**`cancelsTouchesOnScroll`**: `boolean`\n- Cancels all active touch gestures (from onTouch) of the scroll view's children when dragging the scroll view content.\n- Default: `true`\n\n**`dismissKeyboardOnDrag`**: `boolean`\n- If the keyboard is open, close it when we start scrolling.\n- Default: `false`\n\n**`dismissKeyboardOnDragMode`**: `'immediate' | 'touch-exit-below'`\n- When dismissKeyboardOnDrag is `true`, this changes the behavior of when the keyboard is dismissed.\n- `immediate`: keyboard is dismissed as soon as scrolling begins\n- `touch-exit-below`: keyboard is dismissed when the scroll drag gesture touches leave the lower boundary of the scroll bounds\n- Default: `'immediate'`\n\n#### Visual Indicators\n\n**`showsVerticalScrollIndicator`**: `boolean`\n- Shows the scroll indicator when scrolling vertically.\n- Default: `true`\n\n**`showsHorizontalScrollIndicator`**: `boolean`\n- Shows the scroll indicator when scrolling horizontally.\n- Default: `true`\n\n**`fadingEdgeLength`**: `number`\n- Create a fade effect on the content of the scroll view when scrolling is possible.\n- This attribute can control the size of the effect.\n- Default: `0`\n\n#### Viewport Extensions\n\n**`viewportExtensionTop`**: `number`\n- Can be used to extend the visible viewport of the scroll element.\n- When scrolling, this will cause child elements to be rendered potentially earlier (if positive) or later (if negative).\n- Default: `0`\n\n**`viewportExtensionRight`**: `number`\n- Extends the visible viewport on the right side.\n- Default: `0`\n\n**`viewportExtensionBottom`**: `number`\n- Extends the visible viewport on the bottom side.\n- Default: `0`\n\n**`viewportExtensionLeft`**: `number`\n- Extends the visible viewport on the left side.\n- Default: `0`\n\n#### Advanced Features\n\n**`circularRatio`**: `number`\n- Enables circular scroll by specifying the ratio between the calculated content size of the scroll element to the size of a single scrollable page.\n- For circular scroll to work properly, the children elements must be re-rendered at least twice, in which case `circularRatio` should be set to 2.\n- Default: `0` (scroll is not circular)\n\n**`decelerationRate`**: `'normal' | 'fast'`\n- [iOS-Only] Defines the rate at which the scroll view decelerates after a fling gesture.\n- Default: `'normal'`\n\n**`scrollPerfLoggerBridge`**: `IScrollPerfLoggerBridge`\n- Set this to enable scroll performance logging with given attribution parameters.\n- To get a value of this type, see `AttributedCallsite.forScrollPerfLogging`\n\n#### Interactive Properties (Programmatic Only)\n\nThese properties should not be used in TSX tags, only for programmatic attribute manipulation:\n\n**`contentOffsetX`**: `number`\n- Can be programmatically set to change the current horizontal scroll offset.\n\n**`contentOffsetY`**: `number`\n- Can be programmatically set to change the current vertical scroll offset.\n\n**`contentOffsetAnimated`**: `boolean`\n- When set to true, any programmatic change to the contentOffset will be animated.\n\n**`staticContentWidth`**: `number`\n- When set, the scrollable content width will be based on this value for operations like snapping and scrolling.\n- This will bypass the automatic measurement.\n\n**`staticContentHeight`**: `number`\n- When set, the scrollable content height will be based on this value for operations like snapping and scrolling.\n- This will bypass the automatic measurement.\n\n#### Styling\n\n**`style`**: `IStyle<ScrollView | View | Layout>`\n- See [ScrollView Style Attributes](api-style-attributes.md#scrollview-styles) for a complete list of attributes that can be used in `Style<ScrollView>`.\n\n---\n\n## ImageView\n\n**JSX Element:** `<image>`\n\n**iOS Native:** `SCValdiImageView`  \n**Android Native:** `com.snap.valdi.views.ValdiImageView`\n\nA view for displaying images from local assets or remote URLs.\n\n### Properties\n\nAll properties from [Layout Attributes](#layout), plus:\n\n#### Image Source\n\n**`src`**: `string | Asset`\n- Specify the image asset or url to be rendered within the image's bounds.\n- Can be a URL string or an Asset object.\n- Default: `undefined`\n\n#### Image Display\n\n**`objectFit`**: `'fill' | 'contain' | 'cover' | 'none'`\n- Define how the image should be resized within the image view's bounds.\n- Useful when the aspect ratio of the image bounds may be different than the image asset content's aspect ratio.\n- `fill`: stretch the image to fill the image view's bounds\n- `contain`: conserve aspect ratio and scale to fit within bounds (can leave blank space)\n- `cover`: conserve aspect ratio and scale to fill bounds (can crop parts of the image)\n- `none`: conserve aspect ratio and don't scale to fit (just rendered in center)\n- Default: `'fill'`\n\n**`tint`**: `Color`\n- Apply a color tint on every pixel of the image.\n- Default: `undefined`\n\n**`flipOnRtl`**: `boolean`\n- When the current layout is in RTL, horizontally-mirror-flip the image's content.\n- Default: `false`\n\n#### Content Transform\n\n**`contentScaleX`**: `number`\n- Scale horizontally the content of the image within the image's bounds.\n- Default: `1`\n\n**`contentScaleY`**: `number`\n- Scale vertically the content of the image within the image's bounds.\n- Default: `1`\n\n**`contentRotation`**: `number`\n- Rotate the content of the image in radians.\n- Default: `0`\n\n#### Filters\n\n**`filter`**: `ImageFilter`\n- A post processing filter to apply on the image.\n\n#### Callbacks\n\n**`onAssetLoad`**: `(success: boolean, errorMessage?: string) => void`\n- Called when the loaded image asset has either successfully loaded or failed to load.\n\n**`onImageDecoded`**: `(width: number, height: number) => void`\n- Called when the image has been loaded and we have the dimensions.\n- Note: dimensions returned are of the raw image which may be different than the view.\n\n#### View Properties\n\nAll view properties from [View](#view) including:\n- Lifecycle callbacks (`onViewCreate`, `onViewDestroy`)\n- Appearance properties (`backgroundColor`, `opacity`, `border`, etc.)\n- Gesture handlers (tap, drag, etc.)\n- Transform properties\n\n#### Styling\n\n**`style`**: `IStyle<ImageView | View | Layout>`\n- See [ImageView Style Attributes](api-style-attributes.md#imageview-styles) for a complete list of attributes that can be used in `Style<ImageView>`.\n\n---\n\n## VideoView\n\n**JSX Element:** `<video>`\n\n**iOS Native:** `SCValdiVideoView`  \n**Android Native:** `com.snap.valdi.views.ValdiVideoView`\n\nA view for displaying and controlling video playback.\n\n### Properties\n\nAll properties from [Layout Attributes](#layout), plus:\n\n#### Video Source\n\n**`src`**: `string | Asset`\n- Specify the video asset or url to be rendered within the view's bounds.\n- Default: `undefined`\n\n#### Playback Control\n\n**`volume`**: `number`\n- Float between 0 and 1.\n\n**`playbackRate`**: `number`\n- `0` is paused\n- `1` is playing\n- Default: paused\n\n**`seekToTime`**: `number`\n- In milliseconds.\n\n#### Callbacks\n\n**`onVideoLoaded`**: `(duration: number) => void`\n- A callback to be called when the video is loaded.\n- Hands back the length of the video in milliseconds.\n\n**`onBeginPlaying`**: `() => void`\n- Callback for when the video begins playing.\n\n**`onError`**: `(error: string) => void`\n- Callback to be called when there's an error.\n\n**`onCompleted`**: `() => void`\n- Callback to be called when the video completes.\n\n**`onProgressUpdated`**: `(time: number, duration: number) => void`\n- Callback called when the video progress updates.\n- `time` is in milliseconds\n- `duration` is in milliseconds\n- Frequency may differ from platform to platform.\n\n#### View Properties\n\nAll view properties from [View](#view).\n\n#### Styling\n\n**`style`**: `IStyle<VideoView | View | Layout>`\n- See [VideoView Style Attributes](api-style-attributes.md#videoview-styles) for a complete list of attributes that can be used in `Style<VideoView>`.\n\n---\n\n## Label\n\n**JSX Element:** `<label>`\n\n**iOS Native:** `SCValdiLabel`  \n**Android Native:** `android.widget.TextView`\n\nA view for displaying text.\n\n### Properties\n\nAll properties from [Layout Attributes](#layout), plus:\n\n#### Text Content\n\n**`value`**: `string | AttributedText`\n- The text value of the label.\n- Use the `AttributedTextBuilder` class to set a value composed of multiple strings with different text attributes.\n\n#### Text Styling\n\n**`font`**: `string`\n- Set the font used to render the text characters.\n- This attribute must be a string with 4 parts separated by space:\n  1. required: the name of the font (including the font's weight)\n  2. required: the size of the font\n  3. optional: the scaling type (or 'unscaled' for no scaling)\n  4. optional: the maximum size of the font after scaling\n- Example: `'AvenirNext-Bold 16 unscaled 16'`\n- Default: `'system 12'`\n\n**`color`**: `Color`\n- Set the rendering color for the text characters.\n- Default: `black`\n\n**`textGradient`**: `string`\n- Set the Gradient color for the text string. Overrides color setting.\n- Use `\"linear-gradient(color1, color2, color3...)\"` for evenly-spaced stops.\n- Use `\"linear-gradient(color1 stop1, color2 stop2, color3 stop3...)\"` for custom stops.\n\n**`textShadow`**: `string`\n- Add a shadow to the text.\n- Syntax: `'{color} {radius} {opacity} {offsetX} {offsetY}'`\n- All number values are interpreted as points.\n- Note: TextShadow and BoxShadow are mutually exclusive.\n- Example: `'rgba(0, 0, 0, 0.1) 1 1 1 1'`\n\n#### Text Layout\n\n**`numberOfLines`**: `number`\n- This property controls the maximum number of lines to use to fit the label's text into its bounding rectangle.\n- To remove any maximum limit, and use as many lines as needed, set the value to 0.\n- Default: `1`\n\n**`textAlign`**: `'left' | 'right' | 'center' | 'justified'`\n- Set the horizontal alignment behavior for the label's text.\n- Note: it will automatically invert in RTL locales:\n  - In RTL locales, \"left\" will align text to the right of the label's bounds\n  - In RTL locales, \"right\" will align text to the left of the label's bounds\n- Default: `'left'`\n\n**`textDecoration`**: `'none' | 'strikethrough' | 'underline'`\n- Optionally adds a visual decoration effect to the label's text.\n- Default: `undefined`\n\n**`lineHeight`**: `number`\n- Rendering size of each line of the label, this value is a ratio of the font height.\n- If the lineHeight ratio is above 1, spacing is added on top of each line of the text.\n- Example: A value of 2 will double the height of each line.\n- Default: `1`\n\n**`letterSpacing`**: `number`\n- Extra spacing added at the end of each character, in points.\n- Note: negative values will shrink the space between characters.\n- Default: `0`\n\n**`textOverflow`**: `'ellipsis' | 'clip'`\n- Controls how hidden text overflow content is signaled to users.\n- Default: `'ellipsis'`\n\n#### Auto-sizing\n\n**`adjustsFontSizeToFitWidth`**: `boolean`\n- If this property is `true`, and the text exceeds the label's bounding rectangle, the label reduces the font size until the text fits or it has scaled down to the minimum font size.\n- If you set this to `true`, be sure to also set an appropriate minimum font scale with `minimumScaleFactor`.\n- Notes:\n  - This autoshrinking behavior is mostly intended for use with a single-line label when numberOfLines == 1.\n  - This will also work when for multiline using numberOfLines > 0 but the behavior will be much less predictable.\n  - Specifying the label's width/height/minHeight will make the auto-shrink behavior much more predictable.\n- Default: `false`\n\n**`minimumScaleFactor`**: `number`\n- If `adjustsFontSizeToFitWidth` is `true`, use this property to specify the smallest multiplier for the current font size that yields an acceptable font size for the label's text.\n- Default: `0`\n\n#### View Properties\n\nAll view properties from [View](#view).\n\n#### Styling\n\n**`style`**: `IStyle<Label | View | Layout>`\n- See [Label Style Attributes](api-style-attributes.md#label-styles) for a complete list of attributes that can be used in `Style<Label>`.\n\n---\n\n## TextField\n\n**JSX Element:** `<textfield>`\n\n**iOS Native:** `SCValdiTextField`  \n**Android Native:** `com.snap.valdi.views.ValditText`\n\nA single-line text input field.\n\n### Properties\n\nAll properties from [Layout Attributes](#layout), plus:\n\n#### Text Content & Styling\n\nAll text properties from [Label](#label) including `value`, `font`, `color`, `textGradient`, `textShadow`.\n\n#### Text Input Configuration\n\n**`placeholder`**: `string`\n- The string that is displayed when there is no other text in the text field.\n\n**`placeholderColor`**: `Color`\n- Sets the foreground color of the placeholder text.\n\n**`tintColor`**: `Color`\n- [iOS-Only] Setting the tintColor will change the color of the editing caret and drag handles of the text field.\n\n**`textAlign`**: `'left' | 'center' | 'right'`\n- Set the text alignment within the typing box of the text input.\n- Default: `'left'`\n\n**`enabled`**: `boolean`\n- Set whether the text input is editable or not.\n- Default: `true`\n\n#### Keyboard Configuration\n\n**`contentType`**: `'default' | 'phoneNumber' | 'email' | 'password' | 'url' | 'number' | 'numberDecimal' | 'numberDecimalSigned' | 'passwordNumber' | 'passwordVisible' | 'noSuggestions'`\n- The content type identifies what keyboard keys and capabilities are available on the input and which ones appear by default.\n- Default: `'default'`\n\n**`returnKeyText`**: `'done' | 'go' | 'join' | 'next' | 'search' | 'send' | 'continue'`\n- Setting this property changes the visible title of the Return key.\n- Note: This might not actually be text, e.g. on Android 10 setting this to 'search' will make the return key display a search glass icon.\n- Default: `'done'`\n\n**`autocapitalization`**: `'sentences' | 'words' | 'characters' | 'none'`\n- Determines at what times the Shift key is automatically pressed, thereby making the typed character a capital letter.\n- Default: `'sentences'`\n\n**`autocorrection`**: `'default' | 'none'`\n- Determines whether autocorrection is enabled or disabled during typing.\n- Default: `'default'`\n\n**`keyboardAppearance`**: `'default' | 'dark' | 'light'`\n- [iOS-Only] Force keyboard appearance to dark/light (ignoring the current system appearance).\n\n**`enableInlinePredictions`**: `boolean`\n- Whether to enable inline predictions for the text input.\n- Note: This is only relevant on iOS. No-op if used on Android.\n- Default: `false`\n\n#### Text Editing Behavior\n\n**`characterLimit`**: `number`\n- Determines the maximum number of characters allowed to be entered into the text field.\n- Note: an undefined or negative value means there is no limit.\n- Default: `undefined`\n\n**`selectTextOnFocus`**: `boolean`\n- Whether to select the contents of the textfield when it becomes focused.\n- Default: `false`\n\n**`closesWhenReturnKeyPressed`**: `boolean`\n- Dismiss keyboard when the return key is pressed.\n- Is enabled by default.\n- Default for textfield elements: `true`\n- Default for textview elements: `false`\n\n#### Selection\n\n**`selection`**: `[number, number]`\n- Selection for the text field.\n- First index for start of selection\n- Second index for end of selection\n- Set both to the same to select at a single position\n\n#### Callbacks\n\n**`onChange`**: `(event: EditTextEvent) => void`\n- Callback that will get called whenever the user changes the text value of the text field.\n- The event parameter contains the current text value of the text field.\n\n**`onWillChange`**: `(event: EditTextEvent) => EditTextEvent | undefined`\n- Callback called when the text value is about to change.\n- The event parameter contains the current text value before any change.\n- Must return the new text value expected to replace the last text value.\n\n**`onEditBegin`**: `(event: EditTextBeginEvent) => void`\n- Callback called when the user starts editing the textfield (i.e. when the text field becomes focused).\n- The event parameter contains the current text value of the text field.\n\n**`onEditEnd`**: `(event: EditTextEndEvent) => void`\n- Callback called when the user stops editing the textfield (i.e. when the text field stops being focused).\n- The event parameter contains the current text value and the reason for ending.\n\n**`onReturn`**: `(event: EditTextEvent) => void`\n- Callback called when the user taps the return key.\n- The event parameter contains the current text value of the text field.\n\n**`onWillDelete`**: `(event: EditTextEvent) => void`\n- Callback called when the user presses the delete key on the keyboard.\n- The event parameter contains the current text value before characters are deleted.\n- Note: on android some soft-keyboard may only send this when pressing delete on an empty textfield.\n\n**`onSelectionChange`**: `(event: EditTextEvent) => void`\n- Callback called when the selection is changed.\n- The event parameter contains the current text value and the selected indexes.\n\n#### Interactive Properties (Programmatic Only)\n\n**`focused`**: `boolean`\n- Can be programmatically set to change the current focus state of the textfield.\n- Changing this to true will make this textfield become the currently edited one.\n- Example:\n  - On iOS this will make the view request/resign the first responder\n  - On Android this will make the view become focused/unfocused and open/close the keyboard\n\n#### View Properties\n\nAll view properties from [View](#view).\n\n#### Styling\n\n**`style`**: `IStyle<TextField | View | Layout>`\n- See [TextField Style Attributes](api-style-attributes.md#textfield-styles) for a complete list of attributes that can be used in `Style<TextField>`.\n\n---\n\n## TextView\n\n**JSX Element:** `<textview>`\n\n**iOS Native:** `SCValdiTextView`  \n**Android Native:** `com.snap.valdi.views.ValditTextMultiline`\n\nA multi-line text input field.\n\n### Properties\n\nAll properties from [TextField](#textfield), except `returnKeyText` is replaced with `returnType`, plus:\n\n#### Return Key Configuration\n\n**`returnType`**: `'linereturn' | 'done' | 'go' | 'join' | 'next' | 'search' | 'send' | 'continue'`\n- Setting this property changes the visible title of the Return key.\n- Setting this property will also impact the behavior of the return key.\n- `linereturn` will let users add line returns, but any other value will be constrained to single line text.\n- Consider using this attribute in combination with `closesWhenReturnKeyPressed`.\n- Default: `'linereturn'`\n\n#### Text Gravity\n\n**`textGravity`**: `'top' | 'center' | 'bottom'`\n- Set the text gravity/alignment vertically within the text view.\n- Default: `'center'`\n\n#### Background Effect\n\n**`backgroundEffectColor`**: `Color`\n- Set the color for the background effect of the text view.\n- This background is drawn behind each line fragment of the text, wrapping each line together making a cohesive background that follows the text shape.\n- Default: `clear`\n\n**`backgroundEffectBorderRadius`**: `number`\n- Set the background effect border radius.\n- Default: `0`\n\n**`backgroundEffectPadding`**: `number`\n- Set the background effect padding.\n- This padding is applied only around the exterior edge of the text as a whole (it does not apply to the space between lines of text).\n- Default: `0`\n\n#### Interactive Properties (Programmatic Only)\n\n**`focused`**: `boolean`\n- Can be programmatically set to change the current focus state of the textview.\n\n#### Styling\n\n**`style`**: `IStyle<TextView | View | Layout>`\n- See [TextView Style Attributes](api-style-attributes.md#textview-styles) for a complete list of attributes that can be used in `Style<TextView>`.\n\n---\n\n## BlurView\n\n**JSX Element:** `<blur>`\n\n**iOS Native:** `SCValdiBlurView`  \n**Android Native:** `com.snap.valdi.views.ValdiView`\n\nA view that applies a blur effect to content behind it.\n\n### Properties\n\nAll properties from [Layout Attributes](#layout) and [View Attributes](#view) (appearance and gestures), plus:\n\n#### Blur Configuration\n\n**`blurStyle`**: `BlurStyle`\n- The style of blur effect to apply.\n- Possible values:\n  - `'light'`\n  - `'dark'`\n  - `'extraLight'`\n  - `'regular'`\n  - `'prominent'`\n  - `'systemUltraThinMaterial'`\n  - `'systemThinMaterial'`\n  - `'systemMaterial'`\n  - `'systemThickMaterial'`\n  - `'systemChromeMaterial'`\n  - `'systemUltraThinMaterialLight'`\n  - `'systemThinMaterialLight'`\n  - `'systemMaterialLight'`\n  - `'systemThickMaterialLight'`\n  - `'systemChromeMaterialLight'`\n  - `'systemUltraThinMaterialDark'`\n  - `'systemThinMaterialDark'`\n  - `'systemMaterialDark'`\n  - `'systemThickMaterialDark'`\n  - `'systemChromeMaterialDark'`\n\n#### Container Properties\n\nBlurView extends ContainerTemplateElement, so it can have children.\n\n#### Styling\n\n**`style`**: `IStyle<BlurView | View | Layout>`\n- See [BlurView Style Attributes](api-style-attributes.md#blurview-styles) for a complete list of attributes that can be used in `Style<BlurView>`.\n\n---\n\n## SpinnerView\n\n**JSX Element:** `<spinner>`\n\n**iOS Native:** `SCValdiSpinnerView`  \n**Android Native:** `com.snap.valdi.views.ValdiSpinnerView`\n\nA view that displays a loading spinner.\n\n### Properties\n\nAll properties from [Layout Attributes](#layout) and [View](#view), plus:\n\n#### Spinner Configuration\n\n**`color`**: `Color`\n- Color of the spinning shape.\n\n#### Styling\n\n**`style`**: `IStyle<SpinnerView | View | Layout>`\n- See [SpinnerView Style Attributes](api-style-attributes.md#spinnerview-styles) for a complete list of attributes that can be used in `Style<SpinnerView>`.\n\n---\n\n## ShapeView\n\n**JSX Element:** `<shape>`\n\n**iOS Native:** `SCValdiShapeView`  \n**Android Native:** `com.snap.valdi.views.ShapeView`\n\nA view for drawing custom shapes using geometric paths.\n\n### Properties\n\nAll properties from [Layout Attributes](#layout) and [View](#view), plus:\n\n#### Shape Configuration\n\n**`path`**: `GeometricPath`\n- The GeometricPath object representing the path to draw.\n\n#### Stroke Properties\n\n**`strokeWidth`**: `number`\n- Defines the thickness of the shape's stroked path.\n\n**`strokeColor`**: `Color`\n- The color that the stroked path is drawn with.\n\n**`strokeCap`**: `'butt' | 'round' | 'square'`\n- The stroke cap specifies the shape of the endpoints of an open path when stroked.\n\n**`strokeJoin`**: `'bevel' | 'miter' | 'round'`\n- The stroke join specifies the shape of the joints between connected segments of a stroked path.\n\n**`strokeStart`**: `number`\n- The relative location at which to begin stroking the path.\n- Default value is 0. Animatable.\n\n**`strokeEnd`**: `number`\n- The relative location at which to stop stroking the path.\n- Default value is 1. Animatable.\n\n#### Fill Properties\n\n**`fillColor`**: `Color`\n- The color that the shape's enclosed area is filled with.\n\n#### Styling\n\n**`style`**: `IStyle<ShapeView | View | Layout>`\n- See [ShapeView Style Attributes](api-style-attributes.md#shapeview-styles) for a complete list of attributes that can be used in `Style<ShapeView>`.\n\n---\n\n## AnimatedImage\n\n**JSX Element:** `<animatedimage>`\n\n**iOS Native:** `SCValdiAnimatedContentView`  \n**Android Native:** `com.snap.valdi.views.AnimatedImageView`\n\nA view for displaying animated images including Lottie animations, animated WebP, and other formats.\n\n### Properties\n\nAll properties from [Layout Attributes](#layout) and [View](#view), plus:\n\n#### Image Source\n\n**`src`**: `string | Asset`\n- Specify the image asset or url to be rendered within the view's bounds.\n- Default: `undefined` (nothing rendered by default)\n\n#### Animation Control\n\n**`loop`**: `boolean`\n- Specify whether the image animation should loop back to the beginning when reaching the end.\n\n**`advanceRate`**: `number`\n- Sets the speed ratio at which the image animation should run.\n- `0` is paused\n- `1` means the animation runs at normal speed\n- `0.5` at half speed\n- `-1` the animation will run in reverse\n- Default: `0`\n\n**`currentTime`**: `number`\n- Set the current time in seconds for the image animation as an offset from animationStartTime.\n\n**`animationStartTime`**: `number`\n- Set the start time in seconds for the image animation.\n- Animation will be clamped between start and end time.\n- Default: `0`\n\n**`animationEndTime`**: `number`\n- Set the end time in seconds for the image animation.\n- Animation will be clamped between start and end time.\n- Default: animation duration\n\n#### Display Configuration\n\n**`objectFit`**: `'fill' | 'contain' | 'cover' | 'none'`\n- Define how the animatedimage should be resized within the view's bounds.\n- Note that the default is different from the image element.\n- `fill`: stretch the image to fill the view's bounds\n- `contain`: conserve aspect ratio and scale to fit within bounds (can leave blank space)\n- `cover`: conserve aspect ratio and scale to fill bounds (can crop parts)\n- `none`: conserve aspect ratio and don't scale to fit (just rendered in center)\n- Default: `'contain'`\n\n#### Font Provider\n\n**`fontProvider`**: `IFontProvider`\n- Set a font provider that the lottie element will use to resolve fonts within its scenes.\n\n#### Callbacks\n\n**`onAssetLoad`**: `(success: boolean, errorMessage?: string) => void`\n- Called when the loaded animatedimage asset has either successfully loaded or failed to load.\n\n**`onImageDecoded`**: `(width: number, height: number) => void`\n- Called when the animatedimage has been loaded and we have the dimensions.\n- Note: dimensions returned are of the raw image which may be different than the view.\n\n**`onProgress`**: `(event: AnimatedImageOnProgressEvent) => void`\n- Called when the animation progresses.\n- Event contains:\n  - `time`: number (current time in seconds)\n  - `duration`: number (duration of the animation in seconds)\n\n#### Styling\n\n**`style`**: `IStyle<AnimatedImage | View | Layout>`\n- See [AnimatedImage Style Attributes](api-style-attributes.md#animatedimage-styles) for a complete list of attributes that can be used in `Style<AnimatedImage>`.\n\n---\n\n## Slot\n\n**JSX Element:** `<slot>`\n\nSlots are used for content projection, allowing a component to define placeholders that can be filled with content.\n\n### Properties\n\n**`key`**: `string`\n- A key to uniquely identify the element.\n- If not provided, the framework will generate one based on the index.\n\n**`name`**: `string`\n- The unique name of the Slot.\n- If not provided, it would be considered to be named 'default'.\n\n**`ref`**: `IRenderedElementHolder<unknown>`\n- Sets an element reference holder, which will keep track of the elements rendered at the root of this slot.\n\n---\n\n## Common Types\n\n### EditTextEvent\n\nInterface for text editing events.\n\n```typescript\ninterface EditTextEvent {\n  text: string;\n  selectionStart: number;\n  selectionEnd: number;\n}\n```\n\n### EditTextBeginEvent\n\nExtends `EditTextEvent` with no additional properties.\n\n### EditTextEndEvent\n\n```typescript\ninterface EditTextEndEvent extends EditTextEvent {\n  reason: EditTextUnfocusReason;\n}\n```\n\n### EditTextUnfocusReason\n\n```typescript\nenum EditTextUnfocusReason {\n  Unknown = 0,\n  ReturnKeyPress = 1,\n  DismissKeyPress = 2,\n}\n```\n\n### MeasureMode\n\n```typescript\nenum MeasureMode {\n  Unspecified = 0,\n  Exactly = 1,\n  AtMost = 2,\n}\n```\n\n### MeasuredSize\n\n```typescript\ntype MeasuredSize = [number, number];\n```\n\n### OnMeasureFunc\n\n```typescript\ntype OnMeasureFunc = (\n  width: number,\n  widthMode: MeasureMode,\n  height: number,\n  heightMode: MeasureMode,\n) => MeasuredSize;\n```\n\n### CSSValue\n\n```typescript\ntype CSSValue = string | number;\n```\n\n### Color\n\n```typescript\ntype Color = string;\n```\n\n### LabelValue\n\n```typescript\ntype LabelValue = string | AttributedText;\n```\n\n### Gesture Types\n\n#### GestureHandler\n\n```typescript\ntype GestureHandler<Event> = (event: Event) => void;\n```\n\n#### GesturePredicate\n\n```typescript\ntype GesturePredicate<Event> = (event: Event) => boolean;\n```\n\n### Callback Types\n\n#### ImageOnAssetLoadCallback\n\n```typescript\ntype ImageOnAssetLoadCallback = (success: boolean, errorMessage?: string) => void;\n```\n\n#### ImageOnImageDecodedCallback\n\n```typescript\ntype ImageOnImageDecodedCallback = (width: number, height: number) => void;\n```\n\n#### AnimatedImageOnProgressCallback\n\n```typescript\ntype AnimatedImageOnProgressCallback = (event: AnimatedImageOnProgressEvent) => void;\n```\n\n### Layout Enums\n\n#### LayoutAccessibilityCategory\n\n```typescript\ntype LayoutAccessibilityCategory =\n  | 'auto'\n  | 'view'\n  | 'text'\n  | 'button'\n  | 'image'\n  | 'image-button'\n  | 'input'\n  | 'header'\n  | 'link'\n  | 'checkbox'\n  | 'radio'\n  | 'keyboard-key';\n```\n\n#### LayoutAccessibilityNavigation\n\n```typescript\ntype LayoutAccessibilityNavigation = \n  | 'auto' \n  | 'passthrough' \n  | 'leaf' \n  | 'cover' \n  | 'group' \n  | 'ignored';\n```\n\n#### Label Enums\n\n```typescript\ntype LabelTextDecoration = 'none' | 'strikethrough' | 'underline';\ntype LabelTextAlign = 'left' | 'right' | 'center' | 'justified';\ntype LabelFontWeight = 'light' | 'normal' | 'medium' | 'demi-bold' | 'bold' | 'black';\ntype LabelFontStyle = 'normal' | 'italic';\n```\n\n#### Image Enums\n\n```typescript\ntype ImageObjectFit = 'fill' | 'contain' | 'cover' | 'none';\n```\n\n#### TextField Enums\n\n```typescript\ntype TextFieldAutocapitalization = 'sentences' | 'words' | 'characters' | 'none';\ntype TextFieldAutocorrection = 'default' | 'none';\ntype TextFieldTextAlign = 'left' | 'center' | 'right';\ntype TextFieldReturnKeyText = 'done' | 'go' | 'join' | 'next' | 'search' | 'send' | 'continue';\ntype TextFieldKeyboardAppearance = 'default' | 'dark' | 'light';\ntype TextFieldContentType =\n  | 'default'\n  | 'phoneNumber'\n  | 'email'\n  | 'password'\n  | 'url'\n  | 'number'\n  | 'numberDecimal'\n  | 'numberDecimalSigned'\n  | 'passwordNumber'\n  | 'passwordVisible'\n  | 'noSuggestions';\n```\n\n#### TextView Enums\n\n```typescript\ntype TextViewReturnType = 'linereturn' | TextFieldReturnKeyText;\ntype TextViewTextGravity = 'top' | 'center' | 'bottom';\n```\n\n#### Shape Enums\n\n```typescript\ntype ShapeStrokeCap = 'butt' | 'round' | 'square';\ntype ShapeStrokeJoin = 'bevel' | 'miter' | 'round';\n```\n\n#### BlurStyle\n\n```typescript\ntype BlurStyle =\n  | 'light'\n  | 'dark'\n  | 'extraLight'\n  | 'regular'\n  | 'prominent'\n  | 'systemUltraThinMaterial'\n  | 'systemThinMaterial'\n  | 'systemMaterial'\n  | 'systemThickMaterial'\n  | 'systemChromeMaterial'\n  | 'systemUltraThinMaterialLight'\n  | 'systemThinMaterialLight'\n  | 'systemMaterialLight'\n  | 'systemThickMaterialLight'\n  | 'systemChromeMaterialLight'\n  | 'systemUltraThinMaterialDark'\n  | 'systemThinMaterialDark'\n  | 'systemMaterialDark'\n  | 'systemThickMaterialDark'\n  | 'systemChromeMaterialDark';\n```\n\n---\n\n## Usage Examples\n\n### Basic Layout\n\n```tsx\n<layout width=\"100%\" height={200} padding={10} flexDirection=\"row\">\n  <view backgroundColor=\"red\" flex={1} margin={5} />\n  <view backgroundColor=\"blue\" flex={1} margin={5} />\n</layout>\n```\n\n### ScrollView with Images\n\n```tsx\n<scroll height={300} width=\"100%\" horizontal={false}>\n  <layout padding={10}>\n    <image src={res.myImage} width={200} height={200} margin={10} />\n    <label value=\"My Image\" textAlign=\"center\" />\n  </layout>\n</scroll>\n```\n\n### TextField with Callbacks\n\n```tsx\n<textfield\n  value={this.state.text}\n  placeholder=\"Enter your name\"\n  placeholderColor=\"#888\"\n  contentType=\"default\"\n  returnKeyText=\"done\"\n  onChange={(event) => {\n    this.setState({ text: event.text });\n  }}\n  onEditEnd={(event) => {\n    console.log('Editing ended:', event.text);\n  }}\n/>\n```\n\n### Shape Drawing\n\n```tsx\n<shape\n  path={myGeometricPath}\n  strokeWidth={2}\n  strokeColor=\"blue\"\n  fillColor=\"lightblue\"\n  strokeCap=\"round\"\n  strokeJoin=\"round\"\n  width={100}\n  height={100}\n/>\n```\n\n### AnimatedImage (Lottie)\n\n```tsx\n<animatedimage\n  src={res.myLottieAnimation}\n  loop={true}\n  advanceRate={1}\n  width={200}\n  height={200}\n  objectFit=\"contain\"\n  onProgress={(event) => {\n    console.log(`Progress: ${event.time}/${event.duration}`);\n  }}\n/>\n```\n\n---\n\n## See Also\n\n- [Core Views Guide](../docs/core-views.md) - Practical guide to using layouts and views\n- [Core Images Guide](../docs/core-images.md) - Image handling and assets\n- [Core Scrolls Guide](../docs/core-scrolls.md) - ScrollView usage patterns\n- [Core Text Guide](../docs/core-text.md) - Working with text and inputs\n- [Core Flexbox](../docs/core-flexbox.md) - Understanding flexbox layout\n- [Advanced Animations](../docs/advanced-animations.md) - Animating properties\n\n"
  },
  {
    "path": "docs/api/api-style-attributes.md",
    "content": "# Style Attributes Reference\n\nThis document provides a comprehensive reference for all style attributes that can be used with the `Style<T>` object in Valdi. For usage patterns and best practices, see [The Style<> Guide](../docs/core-styling.md).\n\n## Yoga Layout Engine\n\nValdi's layout system is powered by [Yoga](https://github.com/facebook/yoga), Facebook's cross-platform flexbox layout engine. The available flexbox attributes and their behavior are determined by the Yoga version used.\n\n**Current Yoga Version:**\n- **Source Commit:** [`0be0e9fc0148aa609afdc31cb9670524f07050cb`](https://github.com/facebook/yoga/commit/0be0e9fc0148aa609afdc31cb9670524f07050cb)\n- **Version Details:** See [`third-party/yoga/README.snap`](../../third-party/yoga/README.snap)\n- **Local Source:** [`third-party/yoga/`](../../third-party/yoga/)\n- **Modifications:** Custom modifications for Valdi integration (see README.snap for details)\n\n**Key Yoga Files:**\n- Enums/Types: [`third-party/yoga/src/yoga/YGEnums.h`](../../third-party/yoga/src/yoga/YGEnums.h)\n- Style Properties: [`third-party/yoga/src/yoga/YGStyle.h`](../../third-party/yoga/src/yoga/YGStyle.h)\n- Core API: [`third-party/yoga/src/yoga/Yoga.h`](../../third-party/yoga/src/yoga/Yoga.h)\n\n> **Important:** When debugging layout issues or understanding flexbox behavior, refer to this specific Yoga version as behavior may differ from other Yoga versions or standard CSS flexbox implementations.\n\n## Table of Contents\n\n- [Yoga Layout Engine](#yoga-layout-engine)\n- [Understanding Styles](#understanding-styles)\n- [Common Layout Attributes](#common-layout-attributes)\n  - [Using Percentages](#practical-examples-using-percentages)\n- [Common View Attributes](#common-view-attributes)\n- [Element-Specific Styles](#element-specific-styles)\n  - [Layout Styles](#layout-styles)\n  - [View Styles](#view-styles)\n  - [ScrollView Styles](#scrollview-styles)\n  - [ImageView Styles](#imageview-styles)\n  - [VideoView Styles](#videoview-styles)\n  - [Label Styles](#label-styles)\n  - [TextField Styles](#textfield-styles)\n  - [TextView Styles](#textview-styles)\n  - [BlurView Styles](#blurview-styles)\n  - [SpinnerView Styles](#spinnerview-styles)\n  - [ShapeView Styles](#shapeview-styles)\n  - [AnimatedImage Styles](#animatedimage-styles)\n- [Style Composition](#style-composition)\n- [Performance Notes](#performance-notes)\n- [Practical Examples: Using Percentages](#practical-examples-using-percentages)\n\n---\n\n## Understanding Styles\n\nThe `Style<T>` object allows you to group multiple attributes together for reuse and cleaner code. A style can contain any attribute that the element supports, except for the `style` property itself.\n\n```typescript\nimport { Style } from 'valdi_core/src/Style';\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst myStyle = new Style<View>({\n  backgroundColor: '#ffffff',\n  padding: 16,\n  borderRadius: 8,\n});\n\n// Use in JSX:\n<view style={myStyle} />\n```\n\n**Key Points:**\n- Styles are **typed** - `Style<View>` can only be used on `<view>` elements\n- Styles can be **merged** using `Style.merge()`\n- Styles can be **extended** using `.extend()`\n- Styles are **overridden** by inline attributes\n- Styles should be created **at initialization**, not during render\n\n---\n\n## Common Layout Attributes\n\nThese attributes are available on **all elements** (Layout, View, ScrollView, etc.) as they control layout and positioning.\n\n### Size Attributes\n\n```typescript\nnew Style<Layout>({\n  // Dimensions - support points, percentages, or 'auto'\n  width: 200,              // number (points)\n  width: '50%',            // string (percentage of parent width)\n  width: 'auto',           // string (automatic sizing)\n  height: 100,             // number (points)\n  height: '75%',           // string (percentage of parent height)\n  height: 'auto',          // string (automatic sizing)\n  \n  // Size constraints - support points or percentages\n  minWidth: 50,            // number (points)\n  minWidth: '20%',         // string (percentage of parent width)\n  maxWidth: 500,           // number (points)\n  maxWidth: '90%',         // string (percentage of parent width)\n  minHeight: 50,           // number (points)\n  minHeight: '10%',        // string (percentage of parent height)\n  maxHeight: 500,          // number (points)\n  maxHeight: '80%',        // string (percentage of parent height)\n  \n  // Aspect ratio - numeric ratio only (NOT a percentage)\n  aspectRatio: 1.5,        // width/height ratio (1.5 means width is 1.5x height)\n  aspectRatio: 16/9,       // common video aspect ratio\n})\n```\n\n**Percentage Calculation Examples:**\n```typescript\n// Parent container is 400pt wide x 600pt tall\n\n// Child with width: '50%' will be 200pt wide (50% of 400pt)\n// Child with height: '25%' will be 150pt tall (25% of 600pt)\n// Child with margin: '10%' gets 10% of parent's width for horizontal margins (40pt)\n//                    and 10% of parent's height for vertical margins (60pt)\n```\n\n### Position Attributes\n\n```typescript\nnew Style<Layout>({\n  // Position type\n  position: 'relative',    // 'relative' | 'absolute'\n  \n  // Position offsets - support points or percentages\n  top: 10,                 // number (points)\n  top: '5%',               // string (percentage of parent height)\n  right: 10,               // number (points)\n  right: '5%',             // string (percentage of parent width)\n  bottom: 10,              // number (points)\n  bottom: '5%',            // string (percentage of parent height)\n  left: 10,                // number (points)\n  left: '5%',              // string (percentage of parent width)\n})\n```\n\n**Position Percentage Behavior:**\n- **Horizontal offsets** (`left`, `right`): Percentage is relative to parent's **width**\n- **Vertical offsets** (`top`, `bottom`): Percentage is relative to parent's **height**\n\n### Spacing Attributes\n\n```typescript\nnew Style<Layout>({\n  // Margin (outside spacing) - supports points or percentages\n  margin: 10,              // number (points, all sides)\n  margin: '5%',            // string (percentage, all sides)\n  margin: '10 20',         // string (top/bottom 10pt, left/right 20pt)\n  marginTop: 5,            // number (points)\n  marginTop: '2%',         // string (percentage of parent height)\n  marginRight: 5,          // number (points)\n  marginRight: '3%',       // string (percentage of parent width)\n  marginBottom: 5,         // number (points)\n  marginBottom: '2%',      // string (percentage of parent height)\n  marginLeft: 5,           // number (points)\n  marginLeft: '3%',        // string (percentage of parent width)\n  \n  // Padding (inside spacing) - supports points or percentages\n  padding: 10,             // number (points, all sides)\n  padding: '5%',           // string (percentage, all sides)\n  padding: '10 20',        // string (top/bottom 10pt, left/right 20pt)\n  paddingTop: 5,           // number (points)\n  paddingTop: '2%',        // string (percentage of parent height)\n  paddingRight: 5,         // number (points)\n  paddingRight: '3%',      // string (percentage of parent width)\n  paddingBottom: 5,        // number (points)\n  paddingBottom: '2%',     // string (percentage of parent height)\n  paddingLeft: 5,          // number (points)\n  paddingLeft: '3%',       // string (percentage of parent width)\n})\n```\n\n**Spacing Percentage Behavior:**\n- **Horizontal spacing** (`marginLeft`, `marginRight`, `paddingLeft`, `paddingRight`): Percentage is relative to parent's **width**\n- **Vertical spacing** (`marginTop`, `marginBottom`, `paddingTop`, `paddingBottom`): Percentage is relative to parent's **height**\n- **Shorthand with percentage**: `margin: '5%'` applies 5% to all sides (horizontal uses parent width, vertical uses parent height)\n\n### Flexbox Layout Attributes\n\nThese attributes are implemented using [Yoga](https://github.com/facebook/yoga), which provides a flexbox layout engine that closely follows the [CSS Flexible Box Layout](https://www.w3.org/TR/css-flexbox-1/) specification with some additions.\n\n```typescript\nnew Style<Layout>({\n  // Display mode\n  display: 'flex',         // 'flex' | 'none'\n  overflow: 'visible',     // 'visible' | 'scroll' (Yoga also supports 'hidden')\n  \n  // Direction and orientation\n  direction: 'inherit',    // 'inherit' | 'ltr' | 'rtl'\n  flexDirection: 'column', // 'column' | 'column-reverse' | 'row' | 'row-reverse'\n  \n  // Flex properties for this element\n  flexGrow: 1,             // number >= 0 (dimensionless, NOT a percentage)\n  flexShrink: 0,           // number >= 0 (dimensionless, NOT a percentage)\n  flexBasis: 'auto',       // string (automatic)\n  flexBasis: 100,          // number (points)\n  flexBasis: '50%',        // string (percentage of parent's main axis dimension)\n  flexWrap: 'no-wrap',     // 'no-wrap' | 'wrap' | 'wrap-reverse'\n  \n  // Alignment (for children)\n  justifyContent: 'flex-start', // 'flex-start' | 'center' | 'flex-end' | \n                                 // 'space-between' | 'space-around' | 'space-evenly'\n  alignItems: 'stretch',        // 'stretch' | 'flex-start' | 'flex-end' | \n                                 // 'center' | 'baseline'\n  alignContent: 'flex-start',   // Same options as justifyContent plus 'stretch'\n  \n  // Self alignment (override parent's alignItems)\n  alignSelf: 'auto',       // 'auto' | 'flex-start' | 'flex-end' | 'center' | \n                           // 'stretch' | 'baseline' | 'space-between' | 'space-around'\n})\n```\n\n#### Yoga-Specific Flexbox Behaviors\n\n**Aspect Ratio (Yoga Extension):**\n```typescript\nnew Style<Layout>({\n  aspectRatio: 1.5,        // number (width/height ratio)\n                          // This is a Yoga-specific property, not in standard flexbox\n})\n```\n\n**Value Units:**\nYoga supports three types of values for dimensions and edges:\n- **Points**: Absolute values (e.g., `100`)\n- **Percent**: Relative to parent (e.g., `'50%'`)\n- **Auto**: Automatic sizing (e.g., `'auto'`)\n\n**Where Percentages Are Supported:**\nPercentage values are calculated relative to the parent element's corresponding dimension and are supported for:\n- ✅ **Size dimensions**: `width`, `height`, `minWidth`, `maxWidth`, `minHeight`, `maxHeight`\n- ✅ **Spacing**: `margin*`, `padding*` (all directional variants)\n- ✅ **Positioning**: `top`, `right`, `bottom`, `left`\n- ✅ **Flex basis**: `flexBasis`\n\n**Where Percentages Are NOT Supported:**\n- ❌ **Border properties**: `borderWidth`, `borderRadius` (points only)\n- ❌ **Flex factors**: `flexGrow`, `flexShrink` (dimensionless numbers)\n- ❌ **Aspect ratio**: `aspectRatio` (numeric ratio, not percentage)\n- ❌ **Transform properties**: `scaleX`, `scaleY`, `rotation`, `translationX`, `translationY` (specific units)\n- ❌ **Touch area**: `touchAreaExtension*` (points only)\n- ❌ **Opacity and colors**: Always specific formats\n- ❌ **Font sizes**: Use point values or scaling options in font string\n\n**Alignment Extensions:**\nYoga extends the standard flexbox `alignContent` and `alignSelf` to support `space-between` and `space-around`, which are not in the CSS flexbox spec for these properties.\n\n**Default Values:**\nSome Yoga defaults differ from CSS flexbox:\n- `alignItems`: `stretch` (same as CSS)\n- `justifyContent`: `flex-start` (same as CSS)\n- `flexDirection`: `column` (CSS default is `row`)\n- `position`: `relative` (same as CSS)\n\n### Visibility & Performance Attributes\n\n```typescript\nnew Style<Layout>({\n  // Rendering control\n  zIndex: 1,               // number (higher = on top)\n  animationsEnabled: true, // boolean\n  \n  // Performance optimization\n  lazy: false,             // boolean (shorthand for below)\n  lazyLayout: false,       // boolean\n  limitToViewport: true,   // boolean\n  \n  // Viewport behavior\n  ignoreParentViewport: false,        // boolean\n  extendViewportWithChildren: false,  // boolean\n  \n  // Estimated dimensions (for lazy layout)\n  estimatedWidth: 100,     // number\n  estimatedHeight: 100,    // number\n})\n```\n\n### Accessibility Attributes\n\n```typescript\nnew Style<Layout>({\n  // Accessibility category\n  accessibilityCategory: 'auto', // 'auto' | 'view' | 'text' | 'button' | \n                                  // 'image' | 'image-button' | 'input' | \n                                  // 'header' | 'link' | 'checkbox' | 'radio' | \n                                  // 'keyboard-key'\n  \n  // Navigation behavior\n  accessibilityNavigation: 'auto', // 'auto' | 'passthrough' | 'leaf' | \n                                    // 'cover' | 'group' | 'ignored'\n  \n  // Priority\n  accessibilityPriority: 0,  // number\n  \n  // Labels and hints\n  accessibilityLabel: 'Tap here',      // string\n  accessibilityHint: 'Opens menu',     // string\n  accessibilityValue: '50%',           // string\n  \n  // States\n  accessibilityStateDisabled: false,   // boolean\n  accessibilityStateSelected: false,   // boolean\n  accessibilityStateLiveRegion: false, // boolean\n})\n```\n\n---\n\n## Common View Attributes\n\nThese attributes are available on all **visible elements** (View, ScrollView, ImageView, Label, etc.) as they control rendering and interaction.\n\n### Appearance Attributes\n\n```typescript\nnew Style<View>({\n  // Background\n  background: 'linear-gradient(#ff0000, #0000ff)', // gradient string\n  backgroundColor: '#ffffff',  // color string\n  opacity: 1.0,                // number 0.0-1.0\n  \n  // Border\n  border: '2 solid #000000',   // shorthand string\n  borderWidth: 2,              // number or string\n  borderColor: '#000000',      // color string\n  borderRadius: 8,             // number or string ('8 8 0 0' for corners)\n  \n  // Shadow\n  boxShadow: '0 2 10 rgba(0,0,0,0.1)', // string: 'x y blur color'\n  \n  // Clipping\n  slowClipping: false,         // boolean (degrades performance)\n})\n```\n\n### Gesture Attributes\n\n```typescript\nnew Style<View>({\n  // Touch control\n  touchEnabled: true,          // boolean\n  \n  // Gesture states (disabled flags)\n  onTapDisabled: false,        // boolean\n  onDoubleTapDisabled: false,  // boolean\n  onLongPressDisabled: false,  // boolean\n  onDragDisabled: false,       // boolean\n  onPinchDisabled: false,      // boolean\n  onRotateDisabled: false,     // boolean\n  \n  // Gesture timing\n  onTouchDelayDuration: 0,     // number (seconds)\n  longPressDuration: 0.5,      // number (seconds)\n  \n  // Touch area extension\n  touchAreaExtension: 10,      // number (all sides)\n  touchAreaExtensionTop: 10,   // number\n  touchAreaExtensionRight: 10, // number\n  touchAreaExtensionBottom: 10,// number\n  touchAreaExtensionLeft: 10,  // number\n})\n```\n\n### Transform Attributes\n\n```typescript\nnew Style<View>({\n  // Scale\n  scaleX: 1.0,                 // number\n  scaleY: 1.0,                 // number\n  \n  // Rotation\n  rotation: 0,                 // number (radians)\n  \n  // Translation\n  translationX: 0,             // number (points, flipped in RTL)\n  translationY: 0,             // number (points)\n})\n```\n\n### Mask Attributes\n\n```typescript\nnew Style<View>({\n  maskOpacity: 1.0,            // number 0.0-1.0\n  // Note: maskPath is GeometricPath, not styleable\n})\n```\n\n### Platform-Specific Attributes\n\n```typescript\nnew Style<View>({\n  // Accessibility\n  accessibilityId: 'my-button',  // string (for testing)\n  \n  // Scroll behavior\n  canAlwaysScrollHorizontal: false,  // boolean\n  canAlwaysScrollVertical: false,    // boolean\n  \n  // Android-specific\n  filterTouchesWhenObscured: false,  // boolean\n})\n```\n\n### View Lifecycle & Behavior\n\n```typescript\nnew Style<View>({\n  // View reuse\n  allowReuse: true,            // boolean\n})\n```\n\n---\n\n## Element-Specific Styles\n\n### Layout Styles\n\n`Style<Layout>` can contain **only layout-related attributes** (size, position, spacing, flexbox, accessibility, lifecycle).\n\n```typescript\nimport { Layout } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst layoutStyle = new Style<Layout>({\n  width: '100%',\n  height: 'auto',\n  flexDirection: 'row',\n  justifyContent: 'space-between',\n  alignItems: 'center',\n  padding: 16,\n  // Cannot use: backgroundColor, borderRadius, etc. (View-only)\n});\n```\n\n**Available Attribute Groups:**\n- ✅ Size Attributes\n- ✅ Position Attributes\n- ✅ Spacing Attributes\n- ✅ Flexbox Layout Attributes\n- ✅ Visibility & Performance Attributes\n- ✅ Accessibility Attributes\n- ❌ Appearance Attributes (View only)\n- ❌ Gesture Attributes (View only)\n- ❌ Transform Attributes (View only)\n\n---\n\n### View Styles\n\n`Style<View>` can contain **all Layout attributes plus View-specific attributes** (appearance, gestures, transforms).\n\n```typescript\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst viewStyle = new Style<View>({\n  // All Layout attributes\n  width: 200,\n  height: 200,\n  padding: 16,\n  flexDirection: 'column',\n  \n  // View-specific attributes\n  backgroundColor: '#ffffff',\n  borderRadius: 8,\n  borderWidth: 1,\n  borderColor: '#dddddd',\n  boxShadow: '0 2 10 rgba(0,0,0,0.1)',\n  opacity: 0.9,\n  \n  // Gestures\n  touchEnabled: true,\n  onTapDisabled: false,\n  \n  // Transforms\n  scaleX: 1.0,\n  scaleY: 1.0,\n  rotation: 0,\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ Appearance Attributes\n- ✅ Gesture Attributes\n- ✅ Transform Attributes\n- ✅ Mask Attributes\n- ✅ Platform-Specific Attributes\n\n---\n\n### ScrollView Styles\n\n`Style<ScrollView>` can contain **all View attributes plus ScrollView-specific attributes**.\n\n```typescript\nimport { ScrollView } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst scrollStyle = new Style<ScrollView>({\n  // All View attributes\n  backgroundColor: '#f5f5f5',\n  padding: 16,\n  \n  // ScrollView-specific attributes\n  horizontal: false,\n  bounces: true,\n  bouncesFromDragAtStart: true,\n  bouncesFromDragAtEnd: true,\n  bouncesVerticalWithSmallContent: false,\n  bouncesHorizontalWithSmallContent: false,\n  \n  pagingEnabled: false,\n  scrollEnabled: true,\n  \n  showsVerticalScrollIndicator: true,\n  showsHorizontalScrollIndicator: true,\n  \n  cancelsTouchesOnScroll: true,\n  dismissKeyboardOnDrag: false,\n  dismissKeyboardOnDragMode: 'immediate',\n  \n  fadingEdgeLength: 0,\n  decelerationRate: 'normal',\n  \n  viewportExtensionTop: 0,\n  viewportExtensionRight: 0,\n  viewportExtensionBottom: 0,\n  viewportExtensionLeft: 0,\n  \n  circularRatio: 0,\n  \n  // Note: flexDirection is NOT available (use horizontal instead)\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All View attributes\n- ✅ Scroll Behavior Attributes\n- ✅ Bounce/Overscroll Attributes\n- ✅ Touch/Gesture Behavior Attributes\n- ✅ Visual Indicators Attributes\n- ✅ Viewport Extensions Attributes\n- ❌ `flexDirection` (use `horizontal` instead)\n\n**Note:** Programmatic properties like `contentOffsetX`, `contentOffsetY`, `contentOffsetAnimated` cannot be used in styles.\n\n---\n\n### ImageView Styles\n\n`Style<ImageView>` can contain **all Layout and View attributes plus ImageView-specific attributes**.\n\n```typescript\nimport { ImageView } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst imageStyle = new Style<ImageView>({\n  // Layout attributes\n  width: 200,\n  height: 200,\n  \n  // View attributes\n  backgroundColor: '#f5f5f5',\n  borderRadius: 8,\n  \n  // ImageView-specific attributes\n  objectFit: 'cover',      // 'fill' | 'contain' | 'cover' | 'none'\n  tint: '#007AFF',         // color string\n  flipOnRtl: false,        // boolean\n  \n  // Content transform\n  contentScaleX: 1.0,      // number\n  contentScaleY: 1.0,      // number\n  contentRotation: 0,      // number (radians)\n  \n  // Note: src, filter, callbacks cannot be used in styles\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ All View attributes\n- ✅ Image Display Attributes\n- ✅ Content Transform Attributes\n- ❌ `src` (dynamic, use inline)\n- ❌ `filter` (complex object)\n- ❌ Callbacks (functions)\n\n---\n\n### VideoView Styles\n\n`Style<VideoView>` can contain **all Layout and View attributes plus VideoView-specific attributes**.\n\n```typescript\nimport { VideoView } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst videoStyle = new Style<VideoView>({\n  // Layout attributes\n  width: 400,\n  height: 300,\n  \n  // View attributes\n  backgroundColor: '#000000',\n  borderRadius: 8,\n  \n  // VideoView-specific attributes\n  volume: 1.0,             // number 0.0-1.0\n  playbackRate: 1,         // 0=paused, 1=playing\n  \n  // Note: src, seekToTime, callbacks cannot be used in styles\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ All View attributes\n- ✅ Volume and playback rate\n- ❌ `src` (dynamic, use inline)\n- ❌ `seekToTime` (dynamic control)\n- ❌ Callbacks (functions)\n\n---\n\n### Label Styles\n\n`Style<Label>` can contain **all Layout and View attributes plus Label-specific text attributes**.\n\n```typescript\nimport { Label } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst labelStyle = new Style<Label>({\n  // Layout attributes\n  width: 200,\n  padding: 8,\n  \n  // View attributes\n  backgroundColor: '#ffffff',\n  borderRadius: 4,\n  \n  // Text styling\n  font: 'AvenirNext-Bold 16 unscaled 20',\n  color: '#000000',\n  textGradient: 'linear-gradient(#ff0000, #0000ff)',\n  textShadow: 'rgba(0,0,0,0.1) 1 1 1 1',\n  \n  // Text layout\n  numberOfLines: 2,        // number (0=unlimited)\n  textAlign: 'left',       // 'left' | 'right' | 'center' | 'justified'\n  textDecoration: 'none',  // 'none' | 'strikethrough' | 'underline'\n  lineHeight: 1.2,         // number (ratio)\n  letterSpacing: 0,        // number (points)\n  textOverflow: 'ellipsis',// 'ellipsis' | 'clip'\n  \n  // Auto-sizing\n  adjustsFontSizeToFitWidth: false,  // boolean\n  minimumScaleFactor: 0.5,           // number\n  \n  // Note: value cannot be used in styles (dynamic)\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ All View attributes\n- ✅ Text Styling Attributes\n- ✅ Text Layout Attributes\n- ✅ Auto-sizing Attributes\n- ❌ `value` (dynamic content, use inline)\n- ❌ Callbacks (functions)\n\n---\n\n### TextField Styles\n\n`Style<TextField>` can contain **all Label attributes plus TextField-specific input attributes**.\n\n```typescript\nimport { TextField } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst textFieldStyle = new Style<TextField>({\n  // All Label attributes\n  font: 'system 16',\n  color: '#000000',\n  padding: 12,\n  backgroundColor: '#f5f5f5',\n  borderRadius: 8,\n  borderWidth: 1,\n  borderColor: '#dddddd',\n  \n  // TextField-specific attributes\n  placeholderColor: '#999999',\n  tintColor: '#007AFF',    // iOS caret color\n  \n  // Keyboard configuration\n  contentType: 'default',  // 'default' | 'phoneNumber' | 'email' | 'password' | \n                           // 'url' | 'number' | 'numberDecimal' | etc.\n  returnKeyText: 'done',   // 'done' | 'go' | 'join' | 'next' | 'search' | 'send'\n  autocapitalization: 'sentences',  // 'sentences' | 'words' | 'characters' | 'none'\n  autocorrection: 'default',        // 'default' | 'none'\n  keyboardAppearance: 'default',    // 'default' | 'dark' | 'light'\n  \n  // Text editing behavior\n  textAlign: 'left',       // 'left' | 'center' | 'right'\n  enabled: true,           // boolean\n  characterLimit: 100,     // number\n  selectTextOnFocus: false,// boolean\n  closesWhenReturnKeyPressed: true,  // boolean\n  enableInlinePredictions: false,    // boolean (iOS)\n  \n  // Note: value, placeholder, selection, callbacks cannot be used in styles\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ All View attributes\n- ✅ Text Styling Attributes\n- ✅ Keyboard Configuration Attributes\n- ✅ Text Editing Behavior Attributes\n- ❌ `value`, `placeholder` (dynamic, use inline)\n- ❌ `selection` (dynamic state)\n- ❌ `focused` (programmatic only)\n- ❌ Callbacks (functions)\n\n---\n\n### TextView Styles\n\n`Style<TextView>` can contain **all TextField attributes plus TextView-specific attributes**.\n\n```typescript\nimport { TextView } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst textViewStyle = new Style<TextView>({\n  // All TextField attributes\n  font: 'system 16',\n  color: '#000000',\n  padding: 12,\n  backgroundColor: '#f5f5f5',\n  borderRadius: 8,\n  \n  // TextView-specific attributes\n  returnType: 'linereturn',  // 'linereturn' | TextFieldReturnKeyText\n  textGravity: 'top',        // 'top' | 'center' | 'bottom'\n  closesWhenReturnKeyPressed: false,  // typically false for multiline\n  \n  // Background effect\n  backgroundEffectColor: '#ffffff',\n  backgroundEffectBorderRadius: 4,\n  backgroundEffectPadding: 2,\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All TextField attributes\n- ✅ Return Type Configuration\n- ✅ Text Gravity Attributes\n- ✅ Background Effect Attributes\n- ❌ `value`, `placeholder` (dynamic, use inline)\n- ❌ `focused` (programmatic only)\n- ❌ Callbacks (functions)\n\n---\n\n### BlurView Styles\n\n`Style<BlurView>` can contain **all Layout and View attributes plus BlurView-specific attributes**.\n\n```typescript\nimport { BlurView } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst blurStyle = new Style<BlurView>({\n  // Layout attributes\n  width: 300,\n  height: 300,\n  \n  // View attributes (limited)\n  opacity: 0.9,\n  borderRadius: 12,\n  \n  // BlurView-specific attributes\n  blurStyle: 'systemMaterial',  // Many options:\n                                 // 'light', 'dark', 'extraLight', 'regular', 'prominent'\n                                 // 'systemUltraThinMaterial', 'systemThinMaterial',\n                                 // 'systemMaterial', 'systemThickMaterial',\n                                 // 'systemChromeMaterial', 'systemUltraThinMaterialLight',\n                                 // etc.\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ Limited View attributes (positioning, some appearance)\n- ✅ Blur Style Attribute\n- ❌ Most View appearance attributes (blur style controls appearance)\n\n---\n\n### SpinnerView Styles\n\n`Style<SpinnerView>` can contain **all Layout and View attributes plus SpinnerView-specific attributes**.\n\n```typescript\nimport { SpinnerView } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst spinnerStyle = new Style<SpinnerView>({\n  // Layout attributes\n  width: 40,\n  height: 40,\n  \n  // View attributes\n  opacity: 1.0,\n  \n  // SpinnerView-specific attributes\n  color: '#007AFF',        // color string\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ All View attributes\n- ✅ Spinner Color Attribute\n\n---\n\n### ShapeView Styles\n\n`Style<ShapeView>` can contain **all Layout and View attributes plus ShapeView-specific attributes**.\n\n```typescript\nimport { ShapeView } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst shapeStyle = new Style<ShapeView>({\n  // Layout attributes\n  width: 100,\n  height: 100,\n  \n  // View attributes\n  backgroundColor: 'transparent',\n  \n  // ShapeView-specific attributes\n  strokeWidth: 2,          // number\n  strokeColor: '#000000',  // color string\n  strokeCap: 'round',      // 'butt' | 'round' | 'square'\n  strokeJoin: 'round',     // 'bevel' | 'miter' | 'round'\n  strokeStart: 0,          // number 0-1 (animatable)\n  strokeEnd: 1,            // number 0-1 (animatable)\n  fillColor: '#ff0000',    // color string\n  \n  // Note: path is GeometricPath, cannot be used in styles (use inline)\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ All View attributes\n- ✅ Stroke Attributes\n- ✅ Fill Attributes\n- ❌ `path` (complex object, use inline)\n\n---\n\n### AnimatedImage Styles\n\n`Style<AnimatedImage>` can contain **all Layout and View attributes plus AnimatedImage-specific attributes**.\n\n```typescript\nimport { AnimatedImage } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst animatedImageStyle = new Style<AnimatedImage>({\n  // Layout attributes\n  width: 200,\n  height: 200,\n  \n  // View attributes\n  backgroundColor: 'transparent',\n  \n  // AnimatedImage-specific attributes\n  loop: true,              // boolean\n  advanceRate: 1,          // number (0=paused, 1=normal, -1=reverse)\n  objectFit: 'contain',    // 'fill' | 'contain' | 'cover' | 'none'\n  \n  // Animation timing\n  currentTime: 0,          // number (seconds)\n  animationStartTime: 0,   // number (seconds)\n  animationEndTime: 5,     // number (seconds)\n  \n  // Note: src, fontProvider, callbacks cannot be used in styles\n});\n```\n\n**Available Attribute Groups:**\n- ✅ All Layout attributes\n- ✅ All View attributes\n- ✅ Animation Control Attributes\n- ✅ Display Configuration Attributes\n- ❌ `src` (dynamic, use inline)\n- ❌ `fontProvider` (complex object)\n- ❌ Callbacks (functions)\n\n---\n\n## Style Composition\n\n### Merging Styles\n\nCombine multiple styles into one. Later styles override earlier ones.\n\n```typescript\nconst baseStyle = new Style<View>({\n  width: 100,\n  height: 100,\n  backgroundColor: 'red',\n});\n\nconst roundedStyle = new Style<View>({\n  borderRadius: 8,\n});\n\nconst shadowStyle = new Style<View>({\n  boxShadow: '0 2 10 rgba(0,0,0,0.1)',\n});\n\n// Merge all three\nconst cardStyle = Style.merge(baseStyle, roundedStyle, shadowStyle);\n// Result: width: 100, height: 100, backgroundColor: 'red', \n//         borderRadius: 8, boxShadow: '0 2 10 rgba(0,0,0,0.1)'\n```\n\n### Extending Styles\n\nCreate a new style based on an existing one with modifications.\n\n```typescript\nconst baseStyle = new Style<View>({\n  width: 100,\n  height: 100,\n  backgroundColor: 'red',\n});\n\nconst blueStyle = baseStyle.extend({\n  backgroundColor: 'blue',  // Override\n  borderRadius: 8,          // Add new\n});\n// Result: width: 100, height: 100, backgroundColor: 'blue', borderRadius: 8\n```\n\n### Style Inheritance\n\nStyles follow TypeScript's type system. A `Style<View>` can be used where a `Style<Layout>` is expected because View extends Layout.\n\n```typescript\nconst viewStyle = new Style<View>({\n  backgroundColor: 'red',\n  width: 100,\n});\n\n// ✅ Works - View extends Layout\n<view style={viewStyle} />\n\n// ✅ Works - can use on layout (but backgroundColor won't apply)\n<layout style={viewStyle} />  \n\n// ❌ Type error - Label doesn't extend View directly\nconst labelStyle = new Style<Label>({ /* ... */ });\n<view style={labelStyle} />\n```\n\n### Conditional Styles\n\nPre-create styles and switch between them based on state.\n\n```typescript\nconst styles = {\n  normal: new Style<View>({\n    backgroundColor: '#ffffff',\n    borderColor: '#dddddd',\n  }),\n  selected: new Style<View>({\n    backgroundColor: '#007AFF',\n    borderColor: '#0051D5',\n  }),\n  disabled: new Style<View>({\n    backgroundColor: '#f5f5f5',\n    borderColor: '#cccccc',\n    opacity: 0.5,\n  }),\n};\n\n// In render:\n<view style={\n  this.state.disabled ? styles.disabled :\n  this.state.selected ? styles.selected :\n  styles.normal\n} />\n```\n\n---\n\n## Performance Notes\n\n### ✅ DO: Create Styles at Initialization\n\n```typescript\n// At module or component class level\nconst goodStyle = new Style<View>({\n  width: 100,\n  height: 100,\n  backgroundColor: 'red',\n});\n\nclass MyComponent extends Component {\n  // Or as class property\n  private buttonStyle = new Style<View>({\n    padding: 12,\n    borderRadius: 8,\n  });\n  \n  onRender() {\n    <view style={goodStyle} />\n    <view style={this.buttonStyle} />\n  }\n}\n```\n\n### ❌ DON'T: Create Styles During Render\n\n```typescript\nclass MyComponent extends Component {\n  onRender() {\n    // BAD - Creates new object every render\n    const badStyle = new Style<View>({\n      width: 100,\n      height: 100,\n    });\n    \n    // BAD - Expensive operations during render\n    const merged = Style.merge(style1, style2);\n    const extended = style1.extend({ backgroundColor: 'red' });\n    \n    <view style={badStyle} />\n  }\n}\n```\n\n### ✅ DO: Use Inline Attributes for Dynamic Values\n\n```typescript\nconst staticStyle = new Style<View>({\n  width: 100,\n  height: 100,\n  borderRadius: 8,\n});\n\nclass MyComponent extends Component {\n  onRender() {\n    // Good - Style is static, dynamic value is inline\n    <view \n      style={staticStyle} \n      backgroundColor={this.state.isActive ? 'blue' : 'gray'} \n    />\n  }\n}\n```\n\n### ✅ DO: Pre-create Variant Styles\n\n```typescript\nconst baseButton = new Style<View>({\n  padding: 12,\n  borderRadius: 8,\n});\n\nconst styles = {\n  primary: baseButton.extend({ backgroundColor: '#007AFF' }),\n  secondary: baseButton.extend({ backgroundColor: '#5856D6' }),\n  danger: baseButton.extend({ backgroundColor: '#FF3B30' }),\n};\n\n// Use in render - no style creation happens\n<view style={this.props.variant === 'primary' ? styles.primary : styles.secondary} />\n```\n\n### Style vs Inline Attribute Priority\n\nInline attributes **always override** style attributes.\n\n```typescript\nconst myStyle = new Style<View>({\n  backgroundColor: 'red',\n  width: 100,\n});\n\n// backgroundColor will be 'blue', width will be 100\n<view style={myStyle} backgroundColor='blue' />\n```\n\n### What Can't Be Styled\n\nThese properties cannot be included in styles and must be used inline:\n\n- **Callbacks/Functions**: `onChange`, `onTap`, `onLayout`, etc.\n- **Complex Objects**: `path`, `filter`, `fontProvider`, etc.\n- **Dynamic Content**: `value`, `src`, `placeholder` (in most cases)\n- **Refs**: `ref` property\n- **Programmatic Properties**: `focused`, `contentOffsetX`, etc.\n\n---\n\n## Quick Reference by Category\n\n### Layout & Positioning\n- Size: `width`, `height`, `minWidth`, `maxWidth`, `minHeight`, `maxHeight`, `aspectRatio`\n- Position: `position`, `top`, `right`, `bottom`, `left`\n- Spacing: `margin*`, `padding*`\n- Flexbox: `flexDirection`, `justifyContent`, `alignItems`, `alignContent`, `alignSelf`, `flexGrow`, `flexShrink`, `flexBasis`, `flexWrap`\n- Display: `display`, `overflow`, `zIndex`\n\n### Appearance\n- Background: `background`, `backgroundColor`, `opacity`\n- Border: `border`, `borderWidth`, `borderColor`, `borderRadius`\n- Shadow: `boxShadow`\n- Clipping: `slowClipping`\n\n### Text (Label, TextField, TextView)\n- Font: `font`, `color`, `textGradient`, `textShadow`\n- Layout: `numberOfLines`, `textAlign`, `textDecoration`, `lineHeight`, `letterSpacing`, `textOverflow`\n- Auto-size: `adjustsFontSizeToFitWidth`, `minimumScaleFactor`\n- Input: `placeholderColor`, `tintColor`, `contentType`, `returnKeyText`, `autocapitalization`, `autocorrection`\n\n### Gestures\n- Control: `touchEnabled`, `touchAreaExtension*`\n- Disabled: `onTapDisabled`, `onDoubleTapDisabled`, `onLongPressDisabled`, `onDragDisabled`, `onPinchDisabled`, `onRotateDisabled`\n- Timing: `onTouchDelayDuration`, `longPressDuration`\n\n### Transforms\n- Scale: `scaleX`, `scaleY`\n- Rotate: `rotation`\n- Translate: `translationX`, `translationY`\n\n### Accessibility\n- Category: `accessibilityCategory`, `accessibilityNavigation`, `accessibilityPriority`\n- Labels: `accessibilityLabel`, `accessibilityHint`, `accessibilityValue`\n- States: `accessibilityStateDisabled`, `accessibilityStateSelected`, `accessibilityStateLiveRegion`\n- Testing: `accessibilityId`\n\n### Performance\n- Lazy: `lazy`, `lazyLayout`, `limitToViewport`\n- Viewport: `ignoreParentViewport`, `extendViewportWithChildren`\n- Estimates: `estimatedWidth`, `estimatedHeight`\n- Animation: `animationsEnabled`\n\n---\n\n## Practical Examples: Using Percentages\n\n### Responsive Layout with Percentages\n\n```typescript\nconst styles = {\n  // Full-width container\n  container: new Style<View>({\n    width: '100%',           // Takes full width of parent\n    padding: '5%',           // 5% padding on all sides\n    backgroundColor: '#f5f5f5',\n  }),\n  \n  // Two-column layout (side by side)\n  column: new Style<View>({\n    width: '48%',            // Just under 50% to allow for gap\n    margin: '1%',            // Creates spacing between columns\n    backgroundColor: '#ffffff',\n  }),\n  \n  // Centered content with max width\n  content: new Style<Layout>({\n    width: '90%',            // 90% of parent width\n    maxWidth: 600,           // But never more than 600pt\n    marginLeft: '5%',        // Center with left margin\n    marginRight: '5%',       // Center with right margin\n  }),\n  \n  // Card with percentage padding\n  card: new Style<View>({\n    width: '100%',\n    padding: '4%',           // Responsive padding\n    borderRadius: 8,\n    boxShadow: '0 2 10 rgba(0,0,0,0.1)',\n  }),\n  \n  // Absolutely positioned overlay\n  overlay: new Style<View>({\n    position: 'absolute',\n    top: '10%',              // 10% from top\n    left: '10%',             // 10% from left\n    width: '80%',            // 80% of parent width\n    height: '80%',           // 80% of parent height\n    backgroundColor: 'rgba(0,0,0,0.5)',\n  }),\n};\n```\n\n### Flexbox with Percentage Basis\n\n```typescript\nconst flexStyles = {\n  container: new Style<Layout>({\n    width: '100%',\n    flexDirection: 'row',\n    justifyContent: 'space-between',\n  }),\n  \n  // Flexible items with percentage basis\n  sidebar: new Style<Layout>({\n    flexBasis: '30%',        // Takes 30% of container width\n    flexGrow: 0,             // Won't grow\n    flexShrink: 1,           // Can shrink if needed\n  }),\n  \n  mainContent: new Style<Layout>({\n    flexBasis: '65%',        // Takes 65% of container width\n    flexGrow: 1,             // Can grow to fill space\n    flexShrink: 1,           // Can shrink if needed\n  }),\n};\n```\n\n### Avoiding Common Percentage Mistakes\n\n```typescript\n// ❌ WRONG - These don't support percentages\nconst wrongStyles = new Style<View>({\n  borderRadius: '50%',     // ❌ borderRadius only accepts points\n  opacity: '50%',          // ❌ opacity is 0.0-1.0, not percentage\n  scaleX: '150%',          // ❌ scale is a number ratio, not percentage\n  rotation: '90%',         // ❌ rotation is in radians\n  aspectRatio: '16/9',     // ❌ aspectRatio is a number (16/9), not a string\n});\n\n// ✅ CORRECT - Proper usage\nconst correctStyles = new Style<View>({\n  borderRadius: 8,         // ✅ Points only\n  opacity: 0.5,            // ✅ 0.0-1.0 scale\n  scaleX: 1.5,             // ✅ Numeric ratio (150% = 1.5)\n  rotation: Math.PI / 2,   // ✅ Radians (90° = π/2)\n  aspectRatio: 16/9,       // ✅ Numeric ratio\n});\n```\n\n### Mixing Percentages and Fixed Values\n\n```typescript\nconst mixedStyles = {\n  // Fixed header with percentage width\n  header: new Style<View>({\n    width: '100%',           // Full width\n    height: 60,              // Fixed height in points\n    paddingLeft: 20,         // Fixed padding\n    paddingRight: 20,        // Fixed padding\n    backgroundColor: '#ffffff',\n  }),\n  \n  // Responsive grid items\n  gridItem: new Style<View>({\n    width: '31%',            // Percentage width for 3 columns\n    height: 150,             // Fixed height\n    margin: '1%',            // Percentage margin for spacing\n    borderRadius: 8,         // Fixed border radius\n  }),\n  \n  // Combination for centering\n  centered: new Style<Layout>({\n    width: '80%',            // Percentage width\n    maxWidth: 400,           // Fixed maximum\n    marginLeft: '10%',       // Percentage to center\n    marginRight: '10%',      // Percentage to center\n  }),\n};\n```\n\n---\n\n## See Also\n\n- [Complete API Reference](api-reference-elements.md) - Full element documentation\n- [The Style<> Guide](../docs/core-styling.md) - Usage patterns and best practices\n- [Quick Reference](api-quick-reference.md) - Common properties lookup\n- [Core Flexbox](../docs/core-flexbox.md) - Understanding flexbox layout\n\n"
  },
  {
    "path": "docs/codelabs/advanced_ui/1-setup.md",
    "content": "# Advanced UI\n\nIn this codelab you will learn a handful of advanced UI topics.\n\nThis example relies on components from the [Valdi_Widgets][Valdi_Widgets setup] library. You will need to update your `WORKSPACE` to use this library:\n\n```starlark\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"git_repository\")\n\ngit_repository(\n    name = \"valdi_widgets\",\n    branch = \"main\",\n    remote = \"git@github.com:Snapchat/Valdi_Widgets.git\",\n)\n```\n\n## Setup `HelloWorld.tsx`\n\nLet's clear out [`HelloWorld.tsx`](../../../apps/helloworld/src/valdi/hello_world/src/HelloWorldApp.tsx) so we have a clean slate to work with.\n\n\nIt should look like\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nimport { onRootComponentCreated } from './CppModule';\n\n/**\n * @ViewModel\n * @ExportModel\n */\nexport interface ViewModel {}\n\n/**\n * @Context\n * @ExportModel\n */\nexport interface ComponentContext {}\n\n/**\n * @Component\n * @ExportModel\n */\nexport class App extends Component<ViewModel, ComponentContext> {\n  onCreate(): void {\n    onRootComponentCreated(this.renderer.contextId);\n  }\n\n  onRender(): void {\n    <view backgroundColor=\"white\">\n    </view>;\n  }\n}\n\n```\n\n## Make sure it loads\n\nConnect a device or open an Android Emulator or iOS Simulator.\n\nStart up the hotreloader.\n\n```\ncd apps/helloworld\nvaldi hotreload\n```\n\nChoose the `//apps/helloworld:hello_world_hotreload` target.\n\n```\n❯ valdi hotreload\n✔ Running Bazel command: bazel query \"attr(\\\"tags\\\", \\\"valdi_application\\\", //...)\"\n? Please choose a target to hot reload: (Use arrow keys)\n❯ 1. //apps/helloworld:hello_world_hotreload \n  2. //apps/navigation_example:navigation_example_app_hotreload \n  3. //apps/valdi_gpt:valdi_gpt_hotreload \n```\n\nYou should see a blank screen. If you don't, check the hotreloader for errors.\n\nIf you do see errors, check out the [**Getting help**](../how_to_get_help.md) section.\n\n\n## Advanced UI topics\n- [SectionList](./2-section_list.md)\n- [FlexBox Layout](./3-flexbox.md)\n\n\n[Valdi_Widgets setup]: https://github.com/Snapchat/Valdi_Widgets?tab=readme-ov-file#setup-valdi_widgets\n"
  },
  {
    "path": "docs/codelabs/advanced_ui/2-section_list.md",
    "content": "# SectionList\nSectionList is a [Valdi_Widgets][] component that is used by many features to display complex lists with headers.\n\n## Render the list\n\nImport the `SectionList` component from the `valdi_widgets` library.\n\n```tsx\nimport { SectionList } from 'valdi_widgets/src/components/section/SectionList';\n```\n\nUpdate `onRender` to include a `SectionList`.\n\n```tsx\nonRender() {\n    <view backgroundColor=\"white\">\n        <scroll>\n            <SectionList />\n        </scroll>\n    </view>;\n}\n```\n\nVSCode is going to give you some angry squiggles because `SectionList` is missing some parameters.\n\n## ScrollViewHandler\n\nThe `SectionList` needs to share a `ScrollViewHandler` with it's parent `<scroll>` to subscribe to various scroll events.\n\nImport `ScrollViewHandler` from `valdi_widgets`\n\n```tsx\nimport { ScrollViewHandler } from 'valdi_widgets/src/components/scroll/ScrollViewHandler';\n```\n\nCreate a `ScrollViewHandler` instance as a property on the .\n\n```tsx\nexport class App extends Component<ViewModel, ComponentContext> {\n    state: PlaygroundState = {};\n\n    private scrollViewHandler = new ScrollViewHandler();\n```\n\nPass it to the parent `<scroll>` and the `SectionList`.\n\n```tsx\n<view padding='60 20' backgroundColor={SemanticColor.Background.SUBSCREEN}>\n    <scroll ref={this.scrollViewHandler}>\n        <SectionList scrollViewHandler={this.scrollViewHandler} />\n    </scroll>\n</view>;\n```\n\nWe're getting closer, but VSCode is still unhappy.\n\n## Sections\n\nSections in the `<SectionList>` are specified as [`SectionModel`s](https://github.com/Snapchat/Valdi_Widgets/blob/465111c7ae19a6da5bd610139f873e730052b042/valdi_modules/widgets/src/components/section/SectionModel.d.ts#L8).\n\n```typescript\nexport interface SectionModel {\n    /**\n    * A unique key which identifies this Section.\n    */\n    key: string;\n    /**\n    * Render function for injecting anchors right above the section header\n    * (used for anchors because it will not be translated by the sticky headers)\n    */\n    onRenderAnchor?: RenderFunctionAnchor;\n    /**\n    * Render function for rendering the visual content of the header of the section.\n    * (do not use this for anchor because it may get translated by the sticky headers)\n    */\n    onRenderHeader?: RenderFunctionHeader;\n    /**\n    * Render function for rendering the body of the section.\n    */\n    onRenderBody: RenderFunctionBody;\n    /**\n    * When created, this will make the section roll-in fading\n    */\n    animated?: boolean;\n}\n```\n\nThe only required variables in this object are the `key` and `onRenderBody`. `key` is a unique identifier, and `onRenderBody` is a render function (like `onRender`) that creates the views in the section.\n\nLet’s create a `SectionModel` for our `SectionList`.\n\nDefine a class variable to hold onto our models.\n\n```typescript\nexport class Playground extends Component<ViewModel, ComponentContext> {\n    private sections: SectionModel[] = [];\n    \n    ...\n```\n\nThen implement `onCreate` and use it to create a section.\n\n```typescript\nonCreate() {\n    this.sections.push({\n        key: 'one',\n        onRenderBody: () => {\n            <label value={'One'}></label>;\n        },\n    });\n}\n```\n\n`key` can be whatever you want as long as it’s unique, but `onRenderBody` functions in a similar manner to the Component's `onRender`. This is where you render the UI for this particular section.\n\nNow let’s hook it up to the `SectionList`\n\n```typescript\n<SectionList scrollViewHandler={this.scrollViewHandler} sections={this.sections} />\n```\n\n## Render a list\n`SectionList`s are usually used to render lists so let's create one.\n\nCreate a list of `captains` in `onCreate` and then iterate through it.\n\n```typescript\nonCreate() {\n    const captains = ['Picard', 'Janeway', 'Sisko'];\n\n    this.sections.push({\n    key: 'one',\n    onRenderBody: () => {\n        captains.forEach(captain => {\n            <label value={captain}></label>;\n            });\n        },\n    });\n}\n```\n\n## Lists of lists\n\nIf we want to render multiple sections, things are going to get complicated so let’s do some refactoring.\n\nFirst let’s separate the data from the rendering.\n\nAbove the `Playground` component definition, create a new interface to hold on to your data. \n\n```typescript\ninterface OfficersData {\n  officers: string[];\n  title: string;\n  id: string;\n}\n```\n\nWhen you are working with your own data this might be SnapDoc or some data format from native. Each object will need a unique `id` to identify it to the `SectionList`.\n\nNow let's implement a `getData()` function to create our data structure.\n\n```typescript\nprivate getData(): OfficersData[] {\n    return [\n        {\n            officers: ['Picard', 'Janeway', 'Sisko'],\n            title: 'Captains',\n            id: 'starTrekCaptains',\n        },\n        {\n            officers: ['Riker', 'Chakotay', 'Kira'],\n            title: 'First officers',\n            id: 'starTrekFirstOfficers',\n        },\n    ];\n}\n```\n\nWith your own feature, `getData()` will be a call to native or to the server.\n\nNow our `onCreate()` function becomes: \n\n```typescript\nonCreate() {\n    const data = this.getData();\n\n    data.forEach(section => {\n        this.sections.push({\n            key: section.id,\n            onRenderBody: () => {\n                section.officers.forEach(officer => {\n                    <label value={officer}></label>;\n                });\n            },\n        });\n    });\n}\n```\n\nFetch the data, iterate through all of the objects, and create a section for each.\n\nWe have titles now so let's add those in. Add an `onRenderHeader` function into the sections.\n\n```typescript\nimport { systemFont } from 'valdi_core/src/SystemFont';\n```\n\n```typescript\nonRenderHeader: () => {\n    <label value={section.title} font={systemFont(20)} />;\n},\n```\n\n## Fancy rendering\n\n`onRenderBody` and `onRenderHeader` are plain old render functions and you can do the same things with them that you can with a component's `onRender`, but there are a few custom components built to work specifically with the `SectionList`.\n\n### SectionBody\n\n[`<SectionBody>`](https://github.com/Snapchat/Valdi_Widgets/blob/main/valdi_modules/widgets/src/components/section/SectionBody.tsx#L13) is a utility component that applies default padding with a flag to make the section the full width of the parent view.\n\nLet's wrap our `officer` label in a view with a background color so we can see what's up and then put the whole thing in a `<SectionBody>`.\n\n```typescript\nsection.officers.forEach(officer => {\n    <SectionBody>\n        <view backgroundColor='lightblue'>\n            <label value={officer} />\n        </view>\n    </SectionBody>;\n});\n```\n\nTake a look at how your officers are rendering. Then set `fullBleed={true}` on the `<SectionBody>` to see how it changes.\n\n### SectionHeader\n\n[`SectionHeader`](https://github.com/Snapchat/Valdi_Widgets/blob/465111c7ae19a6da5bd610139f873e730052b042/valdi_modules/widgets/src/components/section/SectionHeader.tsx#L46) has a bunch of fancy rendering options.\n\nLet's swap out our `onRenderHeader` implementation with a `<SectionHeader>`.\n\n```typescript\nonRenderHeader: () => {\n    <SectionHeader title={section.title} />;\n},\n```\n\nThe only required parameter is **`title`** but you can add a **`subTitle`**, **`description`**, and additional config as well.\n\nWhat’s most interesting, however, is the built in **`actionButton`**. Let’s add one.\n\nFor this, let’s add an **`action`** function pointer to our data model.\n\n```typescript\ninterface OfficersData {\n  officers: string[];\n  title: string;\n  id: string;\n  action: () => void;\n}\n```\n\nThen update our `getData()` function.\n\n```typescript\nprivate getData(): OfficersData[] {\n    return [\n        {\n            officers: ['Picard', 'Janeway', 'Sisko'],\n            title: 'Captains',\n            id: 'starTrekCaptains',\n            action: () => {\n                console.log('tap captains');\n            },\n        },\n        {\n            officers: ['Riker', 'Chakotay', 'Kira'],\n            title: 'First officers',\n            id: 'starTrekFirstOfficers',\n            action: () => {\n                console.log('tap first officers');\n            },\n        },\n    ];\n}\n```\n\nFor now we’re just logging some debug information.\n\nNow we can hook this up to our section header.\n\n```typescript\n<SectionHeader\n    title={section.title}\n    actionButton={{ label: 'Learn more', onTap: section.action, type: 'navigation' }}\n/>;\n```\n\nCheck out the UI, see how it renders, play with the other parameters.\n\n## Full solution\n\nHere's the full solution if you need it.\n\n```tsx\nimport { StatefulComponent } from 'valdi_core/src/Component';\nimport { ScrollViewHandler } from 'valdi_widgets/src/components/scroll/ScrollViewHandler';\nimport { SectionBody } from 'valdi_widgets/src/components/section/SectionBody';\nimport { SectionHeader } from 'valdi_widgets/src/components/section/SectionHeader';\nimport { SectionList } from 'valdi_widgets/src/components/section/SectionList';\nimport { SectionModel } from 'valdi_widgets/src/components/section/SectionModel';\n\n\ninterface OfficersData {\n  officers: string[];\n  title: string;\n  id: string;\n  action: () => void;\n}\n\n/**\n * @Context\n * @ExportModel\n */\nexport interface ComponentContext {}\n\n/**\n * @Component\n * @ExportModel\n */\nexport class App extends Component<ViewModel, ComponentContext> {\n  private sections: SectionModel[] = [];\n\n  private scrollViewHandler = new ScrollViewHandler();\n\n  onCreate() {\n    const data = this.getData();\n\n    data.forEach(section => {\n      this.sections.push({\n        key: section.id,\n        onRenderBody: () => {\n          section.officers.forEach(officer => {\n            <SectionBody>\n              <view backgroundColor='lightblue'>\n                <label value={officer}></label>\n              </view>\n            </SectionBody>;\n          });\n        },\n        onRenderHeader: () => {\n          <SectionHeader\n            title={section.title}\n            actionButton={{ label: 'Learn more', onTap: section.action, type: 'navigation' }}\n          />;\n        },\n      });\n    });\n  }\n\n  private getData(): OfficersData[] {\n    return [\n      {\n        officers: ['Picard', 'Janeway', 'Sisko'],\n        title: 'Captains',\n        id: 'starTrekCaptains',\n        action: () => {\n          console.log('tap captains');\n        },\n      },\n      {\n        officers: ['Riker', 'Chakotay', 'Kira'],\n        title: 'First officers',\n        id: 'starTrekFirstOfficers',\n        action: () => {\n          console.log('tap first officers');\n        },\n      },\n    ];\n  }\n\n  onRender() {\n    <view padding='60 20' backgroundColor=\"white\">\n      <scroll>\n        <scroll ref={this.scrollViewHandler}>\n          <SectionList scrollViewHandler={this.scrollViewHandler} sections={this.sections} />\n        </scroll>\n      </scroll>\n    </view>;\n  }\n}\n\n```\n\n[Valdi_Widgets]: https://github.com/Snapchat/Valdi_Widgets\n"
  },
  {
    "path": "docs/codelabs/advanced_ui/3-flexbox.md",
    "content": "# FlexBox Layout\nIf you've never done any web programming, `FlexBox` may be unfamiliar. Even if you have worked with the web before, you may need a refresher.\n\n## FlexBox\n`FlexBox` is a concept borrowed from CSS. It is an efficient way to layout children within a parent container even when their size is unknown or dynamic.\n\nValdi uses [Yoga](https://github.com/facebook/yoga), Facebook's cross-platform flexbox layout engine, to implement flexbox layout. The behavior closely follows the CSS Flexible Box Layout specification with some extensions.\n\n> **For more details:** See [Core Flexbox](../../docs/core-flexbox.md) for an introduction and [Style Attributes Reference](../../api/api-style-attributes.md#flexbox-layout-attributes) for the complete API reference including Yoga-specific behaviors.\n\n### Important terms\n- **main axis**: in row mode this is horizontal, in column, it is vertical.\n- **cross axis**: the axis perpendicular to the **main axis**. \n\n### FlexBox parent attributes\nThis is a selection of the most commonly used **FlexBox** attributes. You can find the complete list in the [Style Attributes API Reference](../../api/api-style-attributes.md#flexbox-layout-attributes).\n- **`flexDirection`**: how the children should be arranged.\n    - DEFAULT **`column`**: top to bottom\n    - **`column-reverse`**: bottom to top\n    - **`row`**: left to right\n    - **`row-reverse`**: right to left\n- **`justifyContent`**: alignment along the **main axis**.\n    - DEFAULT **`flex-start`**: at the start\n    - **`flex-end`**: at the end\n    - **`center`**: at the center\n    - **`space-between`**: evenly spaced\n    - **`space-around`**: evenly space children. Children are centered with extra space on the left and right\n    - **`space-evenly`**: evenly distributed. Space between each pair of items; the start edge and the first item; the end edge and the last item; are all the same.\n- **`alignItems`**: alignment along the **cross axis**.\n    - DEFAULT **`stretch`**: strtech children to to match height of the container\n    - **`flex-start`**: at the start\n    - **`flex-end`**: at the end\n    - **`center`**: at the center\n    - **`baseline`**: align children along a common baseline. An individual child can be set to be the reference baseline for the parent container.\n- **`flexWrap`**: how to handle children that overflow the parent container.\n    - DEFAULT **`no-wrap`**: no wrapping. Overflowing children will be hidden.\n    - **`wrap`**: overflow the children into the next row or column based on **`flexDirection`**.\n    - **`wrap-reverse`**: the same as **`wrap`** except the rows or columns are reversed.\n\n### FlexBox child attributes\n- **`flexGrow`**: how space should be distributed among the children along the main axis. After laying out the children, the parent will distribute any remaining space according to the **`flexGrow`** values specified by the children.\n    - DEFAULT **`0`** \n    - float value `>= 0`: A greater value than other children, will give that child more of the extra space\n- **`flexShrink`**: how the parent should constrain the children if they overflow the parent container. The opposite of **`flexGrow`**. **`flexGrow`** and **`flexShrink`** can work together within the same parent.\n    - DEFAULT **`0`**\n    - float value `>= 0`\n\n## Display some dogs\nLet's display a list of dogs so we can see how these attributes impact layout.\n\nLet's render our dogs in a separate function to make it eaiser to update them.\n\n```typescript\nonRenderItems() {\n    for (let i = 0; i < 3; i++) {\n        const dog = 'https://placedog.net/50' + i;\n        <image src={dog} height={64} width={64} border='1 solid red' />;\n    }\n}\n```\n\nThe slightly different URLs will give us different dog images.\n\nNow we can call this function from `onRender`.\n\n```typescript\nonRender() {\n    <view padding='60 20' backgroundColor='green'>\n        <view backgroundColor='lightblue' width={250} height={250}>\n            {this.onRenderItems()}\n        </view>\n    </view>;\n}\n```\n\nThe outer `<view>` is the white background that you see. The inner `<view>` is the parent container that we're going to be playing with.\n\nThis layout is using all of the defaults. Checkout the UI, you should see a column of dogs.\n\n## `flexDirection`\n**`flexDirection`** defaults to column, let's see what this looks like as a row.\n\n```typescript\n<view backgroundColor='lightblue' width={250} height={250} flexDirection='row'>\n    {this.onRenderItems()}\n</view>\n```\n\nNow we have a row of dogs.\n\nIf we specify **`row-reverse`**, we can get them in the opposite order and lined up on the right.\n\n```typescript\n<view backgroundColor='lightblue' width={250} height={250} flexDirection='row-reverse'>\n    {this.onRenderItems()}\n</view>\n```\n\n## Combining multiple attributes\nGoing component by component is boring, let's do something more fun.\n\nDuplicate the list of dogs so we have three of them and give the views a border so we can tell them apart.\n\n```typescript\n<view backgroundColor='lightblue' width={250} height={250} flexDirection='row-reverse' border='1 solid green'>\n    {this.onRenderItems()}\n</view>\n<view backgroundColor='lightblue' width={250} height={250} flexDirection='row-reverse' border='1 solid green'>\n    {this.onRenderItems()}\n</view>\n<view backgroundColor='lightblue' width={250} height={250} flexDirection='row-reverse' border='1 solid green'>\n    {this.onRenderItems()}\n</view>\n```\n\nGive 'em all different **`justifyContent`** values. \n\n```typescript\n<view\n    backgroundColor='lightblue'\n    width={250}\n    height={250}\n    flexDirection='row-reverse'\n    border='1 solid green'\n    justifyContent='center'\n>\n    {this.onRenderItems()}\n</view>\n<view\n    backgroundColor='lightblue'\n    width={250}\n    height={250}\n    flexDirection='row-reverse'\n    border='1 solid green'\n    justifyContent='space-between'\n>\n    {this.onRenderItems()}\n</view>\n<view\n    backgroundColor='lightblue'\n    width={250}\n    height={250}\n    flexDirection='row-reverse'\n    border='1 solid green'\n    justifyContent='space-evenly'\n>\n    {this.onRenderItems()}\n</view>\n```\n\nCheck out the subtle difference between **`space-between`** and **`space-evenly`**.\n\nLet's do the same with **`alignItems`** to place dogs on the cross axis.\n\n```typescript\n<view\n    backgroundColor='lightblue'\n    width={250}\n    height={250}\n    flexDirection='row-reverse'\n    border='1 solid green'\n    justifyContent='center'\n    alignItems='flex-end'\n>\n    {this.onRenderItems()}\n</view>\n<view\n    backgroundColor='lightblue'\n    width={250}\n    height={250}\n    flexDirection='row-reverse'\n    border='1 solid green'\n    justifyContent='space-between'\n    alignItems='center'\n>\n    {this.onRenderItems()}\n</view>\n<view\n    backgroundColor='lightblue'\n    width={250}\n    height={250}\n    flexDirection='row-reverse'\n    border='1 solid green'\n    justifyContent='space-evenly'\n    alignItems='flex-start'\n>\n    {this.onRenderItems()}\n</view>\n```\n\nLook at the UI, see that these values do something, go back and read the documentation above and make sure you understand why.\n\n## Child spacing\nSetting child attributes can create some interesting results.\n\nLet's update our dog rendering so that we can specify an attribute on only one child.\n\n```typescript\nonRenderItems() {\n    for (let i = 0; i < 3; i++) {\n        const dog = 'https://placedog.net/50' + i;\n        if (i == 1) {\n            <image src={dog} height={64} width={64} border='1 solid blue' />;\n        } else {\n            <image src={dog} height={64} width={64} border='1 solid red' />;\n        }\n    }\n}\n```\n\nNow we can do something different with the middle dog. Let's give him some grow.\n\n```typescript\n<image src={dog} height={64} width={64} border='1 solid blue' flexGrow={2} />;\n```\n\nCheck out the UI, the middle dog is now taking up extra space relative to his siblings.\n\nNow let's change that to shrink.\n\n```typescript\n<image src={dog} height={64} width={64} border='1 solid blue' flexShrink={2} />;\n```\n\nThis looks the same as before. Why did nothing happen? **`flexShrink`** only has an impact when the children overflow the parent container and in our example, they all fit neatly in the parent.\n\nLet's change that by making the dogs bigger.\n\n```typescript\nif (i == 1) {\n    <image src={dog} height={100} width={100} border='1 solid blue' flexShrink={2} />;\n} else {\n    <image src={dog} height={100} width={100} border='1 solid red' />;\n}\n```\n\nNow you should be able to see the impact of **`flexShrink`**. \n\n**`flexShrink`** and **`flexGrow`** can be used together in the same UI to create layouts that behave well in different sized parent containers.\n\n## Final solution\nParking it here in case you need it.\n\n```typescript\nimport { StatefulComponent } from 'valdi_core/src/Component';\nimport { ScrollViewHandler } from 'coreui/src/components/scroll/ScrollViewHandler';\nimport { SectionList } from 'coreui/src/components/section/SectionList';\nimport { RenderFunctionBody, RenderFunctionHeader, SectionModel } from 'coreui/src/components/section/SectionModel';\nimport { SemanticColor } from 'coreui/src/styles/semanticColors';\n\n/**\n * Internal state of the component\n */\ninterface PlaygroundState {}\n\n/**\n * @Component\n */\nexport class Playground extends StatefulComponent<{}, PlaygroundState> {\n    onRender() {\n        <view padding='60 20' backgroundColor={SemanticColor.Background.SUBSCREEN}>\n        <view\n            backgroundColor='lightblue'\n            width={250}\n            height={250}\n            flexDirection='row-reverse'\n            border='1 solid green'\n            justifyContent='center'\n            alignItems='flex-end'\n        >\n            {this.onRenderItems()}\n        </view>\n        <view\n            backgroundColor='lightblue'\n            width={250}\n            height={250}\n            flexDirection='row-reverse'\n            border='1 solid green'\n            justifyContent='space-between'\n            alignItems='center'\n        >\n            {this.onRenderItems()}\n        </view>\n        <view\n            backgroundColor='lightblue'\n            width={250}\n            height={250}\n            flexDirection='row-reverse'\n            border='1 solid green'\n            justifyContent='space-evenly'\n            alignItems='flex-start'\n        >\n            {this.onRenderItems()}\n        </view>\n        </view>;\n    }\n    onRenderItems() {\n        for (let i = 0; i < 3; i++) {\n            const dog = 'https://placedog.net/50' + i;\n            if (i == 1) {\n                <image src={dog} height={100} width={100} border='1 solid blue' flexShrink={2} />;\n            } else {\n                <image src={dog} height={100} width={100} border='1 solid red' />;\n            }\n        }\n    }\n}\n```\n"
  },
  {
    "path": "docs/codelabs/getting_started/1-introduction.md",
    "content": "# Getting started with Valdi from scratch\n\n## What is Valdi?\n\nValdi is a framework that allows you to build performant, cross platform, declarative UI in TypeScript.\n\nThe Valdi hotreloader lets you iterate quickly by live updating the UI on a connected device or emulator while you're developing.\n\nYou can easily hook into native code.\n\n## What Valdi is not\n\nValdi is not TypeScript rendered in a WebView.\n\nThe Valdi compiler takes TypeScript source and compiles it down to **valdimodule** files that are read by the Valdi runtime to render natively on each platform.\n\n## Why use Valdi?\n\nOnce you're ramped up, Valdi development is faster than native; you can write UI and business logic once and use it on multiple platforms and the hotreloader lets you iterate faster during development.\n\nWe handle performance optimization for you so you don't need to understand the nuances of each platform's UI to create a good user experience.\n\n# What is this code lab?\n\nThis is your Valdi starting point. If you've never worked with Valdi before and you want to, you're in the right place.\n\nIn this code lab, we will walk you through getting the code, configuring your development environment, and the basics of building a Valdi UI.\n\n## Prerequisites\n\nYou should already be familiar with your native platform of choice. That means you can build and install either an Android or iOS app and have a basic understanding of how their respective development environments work.\n\nFollow the instructions in [INSTALL.md](../../INSTALL.md) to get your machine prepared for building apps with Valdi.\n\n### [Next >](./2-start_coding.md)\n"
  },
  {
    "path": "docs/codelabs/getting_started/2-start_coding.md",
    "content": "# Start coding\n\nNow that you have the code and tools installed, you can jump right in. The quickest way to start playing with Valdi code is through the `helloworld` app.\n\n## Valdi \"Hello World\"\n\nThe source for the `helloworld` app is located in `./apps/helloworld` of the [github.com/Snapchat/Valdi](https://github.com/Snapchat/Valdi) repository.\n\nIf you followed the INSTALL.md instructions you can build the `helloworld` Valdi app. Start an emulator/simulator/development device of your choice and use the correct install script for iOS and Android\n\nFor Android:\n\n```\nvaldi install android\n```\n\nSelect the `//apps/helloworld:hello_world_android` target.\n\nFor iOS:\n\n```\nvaldi install ios\n```\n\nSelect the `//apps/helloworld:hello_world_ios` target.\n\nOnce the build is complete it will launch the `helloworld` app.\n\n## Start the hotreloader\n\nThe hotreloader tool will watch for changes to the Valdi source code, recompile, and re-render the application UI with the changed Valdi modules.\n\n```\nvaldi hotreload --module hello_world\n```\n\n> **CLI Reference:** For more details on available Valdi CLI commands, see [Command Line References](../../docs/command-line-references.md).\n\nThe hotreloader process will print to the console when it is ready to build your changes:\n\n```\n[3.203] [INFO] Recompilation pass finished, waiting for file changes...\n[3.203] [INFO] --------------------------------------------------------\n```\n\n## Make Some Changes\n\nOpen [HelloWorldApp.tsx](../../../apps/helloworld/src/valdi/hello_world/src/HelloWorldApp.tsx) in VS Code.\n\n```\ncode apps/helloworld/src/valdi/hello_world/src/HelloWorldApp.tsx\n```\n\nFind the `<view>` that describes the background ([source](../../../apps/helloworld/src/valdi/hello_world/src/HelloWorldApp.tsx#L34)):\n\n```tsx\n    <view backgroundColor='white'>\n```\n\nChange the `backgroundColor` to `blue` (or any other supported CSS color value):\n\n```tsx\n    <view backgroundColor='blue'>\n```\n\nThe hotreloader process will begin rebuilding the changed module and will update the running application.\n\n```\n[387.506] [INFO] --- Files changed - starting recompilation pass\n# ... additional logs\n[387.823] [INFO] [Hot reloader] sending 2 updated resources to 1 connected client(s)...\n[387.823] [INFO] Saving files\n[387.823] [INFO] Compilation took 316ms\n```\n\nThe `helloworld` application running on your development device/emulator/simulator will now reflect the changes you've made to the `<view>`.\n\n## Find the codelab code\n\nThis is where the codelab starts in earnest.\n\nWe've created a separate component for you to play with. Open [`GettingStartedCodelab.tsx`](../../../apps/helloworld/src/valdi/hello_world/src/GettingStartedCodelab.tsx) in your editor.\n\nIt should look something like this:\n\n```tsx\nimport { Component } from \"valdi_core/src/Component\";\nimport { systemBoldFont, systemFont } from \"valdi_core/src/SystemFont\";\n\nexport class GettingStartedCodelab extends Component {\n    onRender(){\n        <layout padding={24} paddingTop={128}>\n            <label value='Getting started codelab!' font={systemBoldFont(16)} />\n            <label value='github.com/Snapchat/Valdi' font={systemFont(12)} />\n        </layout>\n    }\n}\n```\n\nInside of `HelloWorldApp.tsx` import `GettingStartedCodelab` then update the `onRender` method to render the `GettingStartedCodelab` component:\n\n```tsx\nimport { GettingStartedCodelab } from './GettingStartedCodelab';\n```\n\n```tsx\n  onRender(): void {\n    console.log('Hello World onRender!!!');\n    <view backgroundColor='white'>\n      <GettingStartedCodelab />\n    </view>\n  }\n```\n\nThe hotreloader will rebuild the app and the `GettingStartedCodelab` component will be visible on the screen.\n\nIf you see your change, you're ready to move on to the next step.\n\n## Finding help\nIf your UI isn't updating or you're seeing other issues, check out the [How to get help](../how_to_get_help.md) section.\n\n\n### [Next >](./3-declarative_rendering.md)\n"
  },
  {
    "path": "docs/codelabs/getting_started/3-declarative_rendering.md",
    "content": "# Declarative rendering\nIn an imperative UI (traditional Android and iOS), you create the UI once. If you want to make changes to the UI, you modify the views that are already there.\n\nValdi is a declarative UI framework. In declarative UIs, you don't manage the UI yourself, you create a declaration of what the UI should look like based on some current state and the framework handles the changes to get the UI there from its previous layout.\n\nValdi components override the **`onRender`** function. This function runs every time the UI needs to update.\n\nIn our example **`GettingStartedComponent`**, update the **`value`** of the first **`<label>`** to `'Declarative codelab'` in the `onRender` function.\n\n```typescript\nonRender() {\n    <layout padding={24} paddingTop={80}>\n        <label value='DeclarativeCodelab!' font={systemBoldFont(16)} />\n        <label value='github.com/Snapchat/Valdi' font={systemFont(12)} />\n    </layout>;\n}\n```\n\nWhen you save the file, the hotreloader does its thing, compiles the TypeScript, and rebuilds the page.\n\nValdi does a lot of work under the hood to optimize UIs and changes in UIs, but you should avoid doing any significant work in the **`onRender`** function.\n\n## TSX/JSX\nThese `<layout>` and `<label>` tags may look like HTML, but they are actually TSX.\n\nTSX is an embeddable XML shaped syntax that is transformed into valid TypeScript by our toolchain. In Valdi, you can only use TSX within the call stack of **`onRender`**; that means inside of **`onRender`** or functions called from inside **`onRender`**.\n\nYou can read more about TSX and the JavaScript counterpart, JSX, in the official [TypeScript documentation](https://www.typescriptlang.org/docs/handbook/jsx.html)\n\n## Valdi native elements\nValdi provides a handful of native elements that map to a native implementation. These can be thought of as the primitives of a UI.\n\n`<layout>` doesn't do any rendering on its own, instead it is used to group child elements together and specify how they should be laid out.\n\n`<label>` is a text label that displays text.\n\n`<view>` is a simple rectangular container that can have a background color, border, and respond to gesture events. It's not used much on its own.\n\n`<image>`, `<spinner>`, and `<scroll>` should be self-explanatory.\n\nYou can even define your own native views, but that's a subject for a different codelab.\n\n> **Want more details?** See the [API Reference](../../api/api-reference-elements.md) for a complete list of all available elements and their properties.\n\n## Properties\nWe're not restricted to strings and constants in UI rendering, you can also define your own properties.\n\nDefine a new `msg` property inside your component.\n\n```typescript\nexport class GettingStartedCodelab extends Component {\n    private msg?: string;  \n```\n\nIf you're not familiar with TypeScript or you need a refresher, this is a new private property called **`msg`** of type **`string`**. The question mark `?` indicates that this is an [**optional** property](https://www.typescriptlang.org/docs/handbook/2/objects.html#optional-properties) and may be **`undefined`**.\n\nNow implement the `onCreate` function inside the component and assign a value to the `msg` property.\n\n```typescript\nonCreate() {\n    this.msg = 'Hello Valdi on ' + new Date().toLocaleString();\n}\n```\n\n`onCreate` is part of a Component's lifecycle and is called once when the component is created.\n\nUpdate `<label>` in the `onRender` function to consume your new variable.\n\n```typescript\nonRender() {\n    <layout>\n        <label value='Declarative codelab' font={systemBoldFont(16)} />\n        <label value={this.msg} font={systemFont(12)} />\n    </layout>;\n}\n```\n\nThe curly braces are required to access the variable within the TSX.\n\n## Local variables\nYou can also define local variables.\n\nUpdate **msg** in the `onCreate` function to only contain the first part of your message.\n\n```typescript\nonCreate() {\n    this.msg = 'Hello Valdi on ';\n}\n```\n\nCreate a local variable in the `onRender` function to build your full message string.\n\n```typescript\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleString();\n    // ...\n```\n\nThen update the label value to use the new variable.\n\n```typescript\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value='Declarative codelab' font={systemBoldFont(16)} />\n        <label value={fullMsg} font={systemFont(12)} />\n    </layout>;\n}\n```\n\n**fullMsg** will be created every time `onRender` runs and will update the date.\n\n### [Next >](./4-control_flow_loops.md)"
  },
  {
    "path": "docs/codelabs/getting_started/3-setup_code_tools.md",
    "content": "# Install everything\nThese steps should be completed in order, each step assumes you have successfully completed the previous steps.\n\n## VS Code setup\nValdi tooling is built around the VS Code IDE. You can use other editors but using VS Code will make your life easier.\n\n- Install [VS Code](https://code.visualstudio.com/sha/download?build=stable&os=darwin)\n- Launch VS Code\n- Add VS Code do your `PATH`\n    - Open the Command Palette (**cmd+shift+P**)\n    - Type `shell command`\n    - Select `> Install 'code' command in PATH`\nFor these changes to take effect, restart your terminal or `source` your terminal's config file.\n\nTODO: add public facing instructions\n\n### [Next >](./4-start_coding.md)\n"
  },
  {
    "path": "docs/codelabs/getting_started/4-control_flow_loops.md",
    "content": "# Control flow and loops\nBefore we start, your component should look something like this.\n\n```typescript\nimport { Component } from \"valdi_core/src/Component\";\nimport { systemBoldFont, systemFont } from \"valdi_core/src/SystemFont\";\n\nexport class GettingStartedCodelab extends Component {\n    private msg?: string;\n    onCreate() {\n        this.msg = 'Hello valdi on ';\n    }\n    onRender() {\n        const fullMsg = this.msg + new Date().toLocaleTimeString();\n        <layout padding={24} paddingTop={80}>\n            <label value='Declarative codelab' font={systemBoldFont(16)} />\n            <label value={fullMsg} font={systemFont(12)} />\n        </layout>;\n    }\n}\n```\n\n## **`if`** statements\nYou can conditionally render parts of your UI using if statements.\n\nAdd a new **boolean** class variable.\n\n```typescript\nexport class GettingStartedCodelab extends Component {\n    private msg?: string;\n    private kitten?: boolean;\n    ...\n```\n\nNow add an **`if`** statement checking that variable.\n\n```typescript\nonRender() {\n    if (this.kitten) {\n        <image height={50} width={50} src='https://placecats.com/300/300' />\n    } else {\n        const fullMsg = this.msg + new Date().toLocaleTimeString();\n        <layout>\n            <label value='Declarative codelab' font={systemBoldFont(16)} />\n            <label value={fullMsg} font={systemFont(12)} />\n        </layout>;\n    }\n}\n```\n\nYou won't see any changes yet. Because **`kitten`** is an optional variable and it is still `undefined`, it evaluates to **`false`**.\n\nSet the value of your boolean in `onCreate`.\n\n```tsx\nonCreate() {\n    this.msg = 'Hello valdi on ';\n    this.kitten = true;\n}\n```\n\nNow you should see a kitten!\n\n## Inline loops\nYou can iterate through lists in the middle of the TSX.\n\nStart by removing the **`kitten`** variable we added for the if statement.\n\nCreate a list of kittens.\n\n```tsx\nexport class GettingStartedCodelab extends Component {\n    private msg?: string;\n    private kittens = [\n        'https://placecats.com/300/300',\n        'https://placecats.com/300/301',\n        'https://placecats.com/300/302',\n    ];\n    ...\n```\n\nThe slightly different sizes will give you different kittens.\n\nThen iterate through the **`kittens`** with a **`forEach`**.\n\n```tsx\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value='Declarative codelab' font={systemBoldFont(16)} />\n        <label value={fullMsg} font={systemFont(12)} />\n        {this.kittens.forEach(kitten => {\n            <image height={50} width={50} src={kitten} />;\n        })}\n    </layout>;\n}\n```\n\n## Inline **`if`** and **`for`** caveat\nYou might think, having seen the examples above, that you can do something similar with inline **`if`** and **`for`** loops.\n\nWell, you can't.\n\nThe contents of a curly brace block inside of the TSX need to be an expression. In the current TypeScript standard, **`if`** and **`for`** are not expressions.\n\nIf you want to do something similar, you have a few options discussed below.\n\n## **`when`** expressions\nGoing back to our **`if`** implementation.\n\n```tsx\nonRender() {\n    if (this.kitten) {\n        <image height={50} width={50} src='https://placecats.com/300/300' />\n    } else {\n        const fullMsg = this.msg + new Date().toLocaleTimeString();\n        <layout>\n            <label value='Declarative codelab' font={systemBoldFont(16)} />\n            <label value={fullMsg} font={systemFont(12)} />\n        </layout>;\n    }\n}\n```\n\nIf you decide you want to keep the **\"Declarative codelab\"** title and just swap out the contents of the second line, you can do that with a **`when`** expression.\n\nFirst, import the `when` utility:\n\n```tsx\nimport { when } from 'valdi_core/src/utils/When';\n```\n\nThen use it to conditionally render a component:\n\n```tsx\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value='Declarative codelab' font={systemBoldFont(16)} />\n        {when(this.kitten, () => {\n            <image height={50} width={50} src='https://placecats.com/300/300' />;\n        })}\n        <label value={fullMsg} font={systemFont(12)} />\n    </layout>;\n}\n```\n\nThe first parameter in **`when`** is the conditional, this can be an expression that evaluates to a **`boolean`** or just a variable. The second parameter is a lambda that executes when your conditional evaluates to **`true`**.\n\n**`when`** has no **`else`** clause, so if you want that kind of thing, you need to implement a `when(!conditional)`.\n\n```typescript\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value='Declarative codelab' font={systemBoldFont(16)} />\n        {when(this.kitten, () => {\n            <image height={50} width={50} src='https://placecats.com/300/300' />;\n        })}\n        {when(!this.kitten, () => {\n            <label value={fullMsg} font={systemFont(12)} />;\n        })}\n    </layout>;\n}\n```\n\nTry changing the value of **`this.kitten`** and watch what happens.\n\n## Nested render functions\nYou can call out to another function from `onRender`.\n\nCreate a new function, `onRenderMessage`, and call it from `onRender`.\n\n```typescript\nonRenderMessage(message: string) {\n    // Render message\n}\n\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value='Declarative codelab' font={systemFont(12)} />\n        {this.onRenderMessage(fullMsg)}\n    </layout>;\n}\n```\n\nNow we can put whatever we want in that `onRenderMessage` function.\n\nAdd an **`if`** statement to swap out the kitten.\n\n```typescript\nonRenderMessage(message: string) {\n    if (this.kitten) {\n        <image height={50} width={50} src='https://placecats.com/300/300' />;\n    } else {\n        <label value={message} font={systemFont(12)} />;\n    }\n}\n```\n\nThis isn't just useful for conditionals that are not expressions, it can make your code more readable and reusable.\n\n### [Next >](./5-component_state.md)\n"
  },
  {
    "path": "docs/codelabs/getting_started/5-component_state.md",
    "content": "# Component state\nUp until now, we've been playing with local variables and relying on the hotreloader to rerender our components. But when you've got a component running in production, how does the view update?\n\nValdi will automatically rerender a component when specific kinds of state change. Components have two main kinds of state: the **ViewModel**, and the appropriately named **State**.\n\n## ViewModel and unidirectional data flow\nIn Valdi, data propagates down the tree; from parent to child. The way that parents pass data down to children is through the **ViewModel**.\n\nTo the child, the **ViewModel** is immutable; you can't modify it, only read the variables. When the parent updates the child's **ViewModel**, the child can get the new values in the next `onRender` or in a lifecycle callback `onViewModelUpdate`.\n\nLet's build a **ViewModel** for our component.\n\n**ViewModels** are defined as interfaces and specify a generic type on the `Component`.\n\nDefine your **ViewModel** just below the imports, outside of the `GettingStartedCodelab` component definition.\n\n```typescript\nexport interface GettingStartedCodeLabViewModel {\n    header: string;\n}\n```\n\nThe recommended naming convention for these objects is **`NameOfComponentViewModel`**.\n\nThen specify the **ViewModel** type on the **Component**.\n\n```typescript\nexport class GettingStartedCodelab extends Component<GettingStartedCodeLabViewModel> {\n```\n\nThen in our `onRender` function, we can consume the new **ViewModel**.\n\n```typescript\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value={this.viewModel.header} font={systemBoldFont(16)} />\n        {this.onRenderMessage(fullMsg)}\n    </layout>;\n}\n```\n\nWhen the hotreloader refreshes, you'll either see an error or a missing header. This is because we didn't define the **`header`** parameter where the `GettingStartedCodelab` component was added in its parent.\n\nOpen [`HelloWorldApp.tsx`](../../../apps/helloworld/src/valdi/hello_world/src/HelloWorldApp.tsx) and find where the `<GettingStartedCodelab>` component is included in the `onRender` function.\n\nVSCode should give you some angry red lines and when you hover over the error it'll tell you `\"Property 'header' is missing in type '{}' but required in type 'Readonly<GettingStartedCodeLabViewModel>'\"`\n\nThis is happening because the parent is not passing the **`header`** value to the **ViewModel** of the child.\n\nWe can fix this by adding a value to the **`header`** tag.\n\n```typescript\n<GettingStartedCodelab header='State codelab'></GettingStartedCodelab>\n```\n\nWhen the hotreloader refreshes the UI, your new header should be there.\n\nIf you want **ViewModel** variables that aren't always required, make them optional in the **ViewModel** interface definition.\n\n```typescript\nexport interface GettingStartedCodeLabViewModel {\n    header: string;\n    numKittens?: number;\n}\n```\n\n## State\n**State** objects are used to track a **Component**'s internal state. Like **ViewModels**, **State** objects are immutable. But unlike **ViewModels**, they can be modified with the component's `setState()` function, which will trigger the component to re-render.\n\nDefine a **State** interface for your component just after the **ViewModel**.\n\n```typescript\ninterface GettingStartedCodeLabState {\n    elapsed: number;\n    kitten: boolean;\n}\n```\n\nThe **State** interface does not need to be **exported** because it's not going to be used outside of this file.\n\nWe have a special component that handles **State**. Update your component to extend the **StatefulComponent** and specify the **State** interface as a generic.\n\n```typescript\nimport { StatefulComponent } from \"valdi_core/src/Component\";\n\n/**\n * @Component\n */\nexport class GettingStartedCodelab extends StatefulComponent<\n    GettingStartedCodeLabViewModel,\n    GettingStartedCodeLabState\n> {\n```\n\nThen we can initialize the **state** variable.\n\n```typescript\n/**\n * @Component\n */\nexport class GettingStartedCodelab extends StatefulComponent<\n    GettingStartedCodeLabViewModel,\n    GettingStartedCodeLabState\n> {\n    state = {\n        elapsed: 0,\n        kitten: false,\n    };\n```\n\nNow, let's do something with this **`elapsed`** state property. Set up a timer in `onCreate` and an `interval` property to hold on to a reference to it.\n\n```typescript\nprivate interval?: number;\nonCreate() {\n    this.msg = 'Hello valdi on ';\n    this.kitten = true;\n\n    this.interval = setInterval(() => {\n        this.setState({ elapsed: this.state.elapsed + 1 });\n    }, 1000);\n}\n```\n\n`setInterval` is a JavaScript utility that calls a function, repeatedly, after a set delay.\n\nThe first parameter is the function to be called, we're creating a lambda that calls `setState` to increment **`elapsed`**. `setState` does a partial update, so we're not replacing the whole object here, we're just updating **elapsed**, the value of **kitten** will remain the same.\n\nThe second parameter is a length of time, specified in milliseconds.\n\n`setInterval` will run forever, so we need to clean it up when the component gets destroyed.\n\n```typescript\nonDestroy() {\n    if (this.interval) {\n        clearInterval(this.interval);\n    }\n}\n```\n\n`clearInterval` clears the interval set in `setInterval`, and `onDestroy` is a **Component** lifecycle function that will be called as the **Component** is being destroyed.\n\nNow, let's read this new **State** variable that we've created and are updating. Add another `<label>` in `onRender`.\n\n```typescript\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value={this.viewModel.header} font={systemBoldFont(16)} />\n        <label value={`Time Elapsed: ${this.state.elapsed} seconds`} />\n        {this.onRenderMessage(fullMsg)}\n    </layout>;\n}\n```\n\nThe value of our new `<label>` is a template literal string: a formatted string. Pay attention to the quotes here, they're not quotes, they're back ticks.\n\nLet the hotreloader do its thing and then watch the timer tick up.\n\nLet's play with that other **State** variable we created. Update the `setInterval` function to update the value of **state.kitten** based on `elapsed % 5`.\n\n```typescript\nthis.interval = setInterval(() => {\n    this.setState({\n        elapsed: this.state.elapsed + 1,\n        kitten: this.state.elapsed % 5 == 0,\n    });\n}, 1000);\n```\n\nThis sets **kitten** to **true** when a multiple of 5 seconds have elapsed.\n\nThen we can consume **state.kitten** in `onRenderMessage` and clean up the kitten local variable.\n\n```typescript\nonRenderMessage(message: string) {\n    if (this.state.kitten) {\n        <image height={50} width={50} src='https://placecats.com/300/300' />;\n    } else {\n        <label value={message} font={systemFont(12)} />;\n    }\n}\n```\n\nTake a look at the UI, you should see the hello message some of the time and a kitten every 5 seconds.\n\n### [Next >](./6-component_lifecycle.md)\n"
  },
  {
    "path": "docs/codelabs/getting_started/6-component_lifecycle.md",
    "content": "# Component lifecycle\nLet's take a break from the code for a minute and talk about the **Component** lifecycle.\n\nWe touched on this a bit when the previous examples overrode `onCreate` and `onRender`. These functions, and a few others, are called by the **Valdi** runtime to indicate specific parts of the component lifecycle. You can override them in your **Component** to take advantage of that state of the lifecycle.\n\n## onCreate\n`onCreate` is called once when the component is first created after the **ViewModel** and **State** have been set but rendering hasn't started yet. This is a good place to setup local variables and kick off any work.\n\n## `onViewModelUpdate(previousViewModel?: ViewModelType)`\nThis is called when the **ViewModel** is set and when the parent has updated it since the last `onRender` call. It is also called directly after `onCreate` if the parent provided a **ViewModel** at initialization. `onRender` is always called right after this.\n\n## onRender\n`onRender` is called when the component needs to be rendered. TSX tags will only have any effect if they are inside the call stack of this function.\n\nThere are three scenarios in which onRender is called:\n- Right after `onCreate` during setup.\n- Right after `onViewModelUpdate` is called.\n- In a **StatefulComponent**, right after `setState` is called.\n\n## onDestroy\nThis is called once when the component is destroyed. A component gets destroyed if it's parent no longer renders it in the parent's `onRender`.\n\n`onDestroy` is a good place to cleanup long running tasks and resources.\n\n### [Next >](./7-component_events.md)\n"
  },
  {
    "path": "docs/codelabs/getting_started/7-component_events.md",
    "content": "# Component events\nBefore we get started, your `GettingStartedComponent` should look a little something like this.\n\n```tsx\nimport { StatefulComponent } from 'valdi_core/src/Component';\nimport { systemBoldFont, systemFont } from 'valdi_core/src/SystemFont';\n\nexport interface GettingStartedCodeLabViewModel {\n    header: string;\n    numKittens?: number;\n}\n\ninterface GettingStartedCodeLabState {\n    elapsed: number;\n    kitten: boolean;\n}\n\nexport class GettingStartedCodelab extends StatefulComponent<\n    GettingStartedCodeLabViewModel,\n    GettingStartedCodeLabState\n    > {\n    state = {\n        elapsed: 0,\n        kitten: false,\n    };\n    private msg?: string;\n    private kitten?: boolean;\n    private kittens = [\n        'https://placecats.com/300/300',\n        'https://placecats.com/300/301',\n        'https://placecats.com/300/302',\n    ];\n\n    private interval?: number;\n    onCreate() {\n        this.msg = 'Hello valdi on ';\n        this.kitten = true;\n\n        this.interval = setInterval(() => {\n        this.setState({\n            elapsed: this.state.elapsed + 1,\n            kitten: this.state.elapsed % 5 == 0,\n        });\n        }, 1000);\n    }\n\n    onDestroy() {\n        if (this.interval) {\n            clearInterval(this.interval);\n        }\n    }\n\n    onRenderMessage(message: string) {\n        if (this.state.kitten) {\n            <image height={50} width={50} src='https://placecats.com/300/300' />;\n        } else {\n            <label value={message} font={systemFont(12)} />;\n        }\n    }\n\n    onRender() {\n        const fullMsg = this.msg + new Date().toLocaleTimeString();\n        <layout>\n            <label value={this.viewModel.header} font={systemBoldFont(16)} />\n            <label value={`Time Elapsed: ${this.state.elapsed} seconds`} />\n            {this.onRenderMessage(fullMsg)}\n        </layout>;\n    }\n}\n```\n\n## Touch event callbacks\nSome elements expose handlers for working with touch events. You can register callbacks for specific events on the element.\n\nLet's create a button that adds kittens.\n\nFirst, add a variable to your component's **State** to keep track of the number of **kittens**.\n\n```typescript\ninterface GettingStartedCodeLabState {\n    elapsed: number;\n    kitten: boolean;\n    numKittens: number;\n}\n```\n\nThen initialize it to something reasonable.\n\n```typescript\nstate = {\n    elapsed: 0,\n    kitten: false,\n    numKittens: 1,\n};\n```\n\nNow, let's consume that variable inside `onRenderMessage`.\n\n```tsx\nonRenderMessage(message: string) {\n    if (this.state.kitten) {\n        for (let i = 0; i < this.state.numKittens; i++) {\n            <image height={50} width={50} src='https://placecats.com/300/300' />;\n        }\n    } else {\n        <label value={message} font={TextStyleFont.BODY} />;\n    }\n}\n```\n\nThe for loop will create **numKittens** kitten images.\n\nTo update **numKittens**, let's add a button in our `onRender` function.\n\n```tsx\n<layout>\n    <label value={this.viewModel.header} font={TextStyleFont.TITLE_1} />\n    <label value={`Time Elapsed: ${this.state.elapsed} seconds`} />\n    <view margin={20} backgroundColor='grey' borderRadius={8} padding={16}>\n        <label value='Add kitten' />\n    </view>\n    {this.onRenderMessage(fullMsg)}\n</layout>;\n```\n\nYes, the button is a `<view>` but it has all of the callbacks that we need to implement button behavior. There is a whole catalog of **CoreUI** components that contains a stylized button but that's a subject for another code lab.\n\nIf you click the button now, nothing happens. That's because we need to register an `onTap` handler.\n\nLet's start by creating the callback function.\n\n```tsx\nprivate buttonTapped = () => {\n    this.setState({ numKittens: this.state.numKittens + 1 });\n};\n```\n\nInteraction callbacks should be implemented as [lambdas](https://www.typescriptlang.org/docs/handbook/2/classes.html#arrow-functions) to make sure that the callback is not recreated every render. Don't worry, the linter will yell at you if you forget.\n\nNow we can hook it up to `onTap`.\n\n```tsx\n<view margin={20} backgroundColor='grey' borderRadius={8} padding={16} onTap={this.buttonTapped}>\n    <label value='Add kitten' />\n</view>\n```\n\nTap the button a few times and see how the UI updates.\n\n## Full solution\nParking the full solution here if you need it.\n\n```tsx\nimport { StatefulComponent } from 'valdi_core/src/Component';\nimport { systemBoldFont, systemFont } from 'valdi_core/src/SystemFont';\n\nexport interface GettingStartedCodeLabViewModel {\n    header: string;\n    numKittens?: number;\n}\n\ninterface GettingStartedCodeLabState {\n    elapsed: number;\n    kitten: boolean;\n    numKittens: number;\n}\n\nexport class GettingStartedCodelab extends StatefulComponent<\n    GettingStartedCodeLabViewModel,\n    GettingStartedCodeLabState\n    > {\nstate = {\n    elapsed: 0,\n    kitten: false,\n    numKittens: 1,\n};\nprivate msg?: string;\nprivate kitten?: boolean;\nprivate kittens = [\n    'https://placecats.com/300/300',\n    'https://placecats.com/300/301',\n    'https://placecats.com/300/302',\n];\n\nprivate interval?: number;\nonCreate() {\n    this.msg = 'Hello valdi on ';\n    this.kitten = true;\n\n    this.interval = setInterval(() => {\n        this.setState({\n            elapsed: this.state.elapsed + 1,\n            kitten: this.state.elapsed % 5 == 0,\n        });\n    }, 1000);\n}\n\nonDestroy() {\n    if (this.interval) {\n        clearInterval(this.interval);\n    }\n}\n\nonRenderMessage(message: string) {\n    if (this.state.kitten) {\n        for (let i = 0; i < this.state.numKittens; i++) {\n            <image height={50} width={50} src='https://placecats.com/300/300' />;\n        }\n    } else {\n        <label value={message} font={systemFont(12)} />;\n    }\n}\n\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n    <label value={this.viewModel.header} font={systemBoldFont(16)} />\n    <label value={`Time Elapsed: ${this.state.elapsed} seconds`} />\n    <view margin={20} backgroundColor='grey' borderRadius={8} padding={16} onTap={this.buttonTapped}>\n        <label value='Add kitten' />\n    </view>\n    {this.onRenderMessage(fullMsg)}\n    </layout>;\n}\n\nprivate buttonTapped = () => {\n        this.setState({ numKittens: this.state.numKittens + 1 });\n    };\n}\n```\n\n### [Next >](./8-unittest.md)\n"
  },
  {
    "path": "docs/codelabs/getting_started/8-unittest.md",
    "content": "# Unit testing\nNow that we have some UI, let's make sure that it does what it's supposed to do.\n\nValdi uses the [Jasmine](https://jasmine.github.io/) testing framework.\n\n## Where tests live\nTests generally live in your module but in their own test directory.\n\nThe tests for this codelab will live in `./apps/helloworld/src/valdi/hello_world/test`\n\nCreate a test file for our **GettingStarted** Component.\n\n```\ncd apps/helloworld/src/valdi/hello_world\nmkdir test\ntouch test/GettingStartedCodelab.spec.tsx\n```\n\nThis just sets up the structure and creates a file. Open your new file.\n\n## Test structure\nLet's create a barebones test file.\n\nReplace the contents of `GettingStartedCodelabTest.tsx` with one test.\n\n```typescript\nimport 'jasmine/src/jasmine';\nimport { valdiIt } from 'valdi_test/test/JSXTestUtils';\n\ndescribe('GettingStartedCodelab', () => {\n    valdiIt('creates component', async driver => {\n        // Test logic goes here.\n        throw new Error('not implemented');\n    });\n});\n```\n\nThis imports the framework, sets up a new group of tests called **GettingStartedCodelab** and creates one test called **creates component**. **valdiIt** is a Valdi utility that provides some functionality for rendering components.\n\nIt's good practice to keep unit tests small and the names descriptive.\n\n## Update `BUILD.bazel`\n\nRunning tests requires the test files to be added to the module. Open `apps/helloworld/src/valdi/hello_world/BUILD.bazel`.\n\nUpdate the `srcs` to include `test` files:\n\n```bazel\nvaldi_module(\n    name = \"hello_world\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n```\n\nUpate the `deps` to include the `valdi_test` dependency:\n\n```bazel\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n        \"//src/valdi_modules/src/valdi/valdi_test\",\n        \"//src/valdi_modules/src/valdi/foundation\",\n    ],\n```\n\n## Run the tests\nLet's make sure you can run these new tests. \n\n```\nbazel build //apps/helloworld/src/valdi/hello_world:test\n```\n\nThe initial build may take some time to pull in the test dependencies.\n\n\n```\n//apps/helloworld/src/valdi/hello_world:test                             FAILED in 0.2s\nExecuting tests from //apps/helloworld/src/valdi/hello_world:test\n-----------------------------------------------------------------------------\nRandomized with seed 40852\nStarted\n[0.065: INFO] [JS] - Jasmine execution started (1 specs)\n[0.065: INFO] [JS] -------------------------------------\n[0.065: INFO] [JS] -- Suite started: GettingStartedCodelab\n[0.065: INFO] [JS] ---- Spec started: creates component\nF[0.072: INFO] [JS] -- Suite passed: GettingStartedCodelab\n[0.072: INFO] [JS] -------------------------------------\n\n\n-------------------- Failures start:\n1) GettingStartedCodelab creates component\n  Message:\n    Error: Not implemented\n```\n\n\n## Render a layout\nNow that we can run these tests, we need to get our test subject loaded up.\n\nInside of that **creates component** test, load up your Component.\n\n```tsx\ndescribe('GettingStartedCodelab', () => {\n    valdiIt('creates component', async driver => {\n        const nodes = driver.render(() => {\n            <GettingStartedCodelab header='Stuff and things' />;\n        });\n    });\n});\n```\n\nThis will render your component and give you back a reference to the output. You can use **driver.render** to render any arbitrary TSX similar to `onRender`. This is useful if you want to test how your component layout behaves when inside various sized containers.\n\nNow we can check on that output and make sure it is what we think it is.\n\n```typescript\nexpect(nodes.length).toBe(1);\n\nexpect(nodes[0].component instanceof GettingStartedCodelab).toBeTruthy();\n```\n\nHere we're checking that there was only one thing rendered and that that one thing was a **GettingStarteCodelab**.\n\nSave the file and watch the hotreloader script rerun your tests.\n\n## Render a single component and check the header\nWe only care about our component so there are easier ways to create it for testing.\n\nCreate another test and load up a component with **createComponent**.\n\n```typescript\nvaldiIt('sets header', async driver => {\n    const instrumentedComponent = createComponent(GettingStartedCodelab, { header: 'Something' });\n    const component = instrumentedComponent.getComponent();\n});\n```\n\n**createComponent** is another utility that creates an instrumented component and we can get a reference to our component from there.\n\nLet's fetch the `<label>`s so we can make sure they are what we think they are.\n\n```typescript\nconst labels = elementTypeFind(componentGetElements(component), IRenderedElementViewClass.Label);\n```\n\nVSCode might struggle to find the imports for this one, so here they are if you need them.\n\n```typescript\nimport { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\nimport { componentGetElements } from 'foundation/test/util/componentGetElements';\nimport { elementTypeFind } from 'foundation/test/util/elementTypeFind';\n```\n\n**elementTypeFind** finds all of the elements of a particular type. Remember, elements are the natively supported types in Valdi. There is a similar function for Components: **componentTypeFind**. \n\nSo we're filtering through all of the child elements of the **GettingStartedCodelab** component and getting back any that match **IRenderedElementViewClass.Label** which is the native type of `<label>`.\n\nWe know, from our implementation of the **GettingStartedCodelab** that we want the first `<label>` so let's check it.\n\n```typescript\nconst header = labels[0].getAttribute('value');\nexpect(header).toBe('Something');\n```\n\nWe grab the first element in the array of labels and check to verify that its label is what we set when we created the object.\n\nLet's change the value and check it again.\n\n```typescript\ninstrumentedComponent.setViewModel({ header: 'Something else' });\nconst header2 = labels[0].getAttribute('value');\nexpect(header2).toBe('Something else');\n```\n\nWe set a new **ViewModel** on the instrumentedComponent then checked the label again to make sure it is what we think it should be.\n\n## Test button logic\nLet's make sure that clicking on the button gives us more kittens.\n\nThe setup for this test starts the same way.\n\n```typescript\nvaldiIt('adds kittens', async driver => {\n    const instrumentedComponent = createComponent(GettingStartedCodelab, { header: 'Kittens' });\n    const component = instrumentedComponent.getComponent();\n});\n```\n\nLet's double check that we start out with the right number of kittens.\n\n```typescript\nexpect(component.state.numKittens).toBe(1);\n```\n\nOur button is a view so we want to fetch all of them and then grab the first one.\n\n```typescript\nconst button = elementTypeFind(componentGetElements(component), IRenderedElementViewClass.View)[0];\n```\n\n**onTap** is just another attribute on the element so we can fetch it and then, because it's a function pointer, we can execute it.\n\n```typescript    \nbutton.getAttribute('onTap')?.();\n```\n\nThe question mark (?) is a null check and that final set of parentheses is the function call.\n\nNow we can check and make sure we have the right number of kittens.\n\n```typescript\nexpect(component.state.numKittens).toBe(2);\n```\n\nSave the file and let the hotreloader run the tests.\n\n## Full solution\nHere's the full testing solution if you need it.\n\n```typescript\nimport 'jasmine/src/jasmine';\nimport { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\nimport { valdiIt, createComponent } from 'valdi_test/test/JSXTestUtils';\nimport { componentGetElements } from 'foundation/test/util/componentGetElements';\nimport { elementTypeFind } from 'foundation/test/util/elementTypeFind';\nimport { GettingStartedCodelab } from 'playground/src/GettingStartedCodelab';\n\ndescribe('GettingStartedCodelab', () => {\n    valdiIt('creates component', async driver => {\n        const nodes = driver.render(() => {\n        <GettingStartedCodelab header='Stuff and things' />;\n        });\n\n        expect(nodes.length).toBe(1);\n\n        expect(nodes[0].component instanceof GettingStartedCodelab).toBeTruthy();\n    });\n\n    valdiIt('sets header', async driver => {\n        const instrumentedComponent = createComponent(GettingStartedCodelab, { header: 'Something' });\n        const component = instrumentedComponent.getComponent();\n\n        const labels = elementTypeFind(componentGetElements(component), IRenderedElementViewClass.Label);\n\n        const header = labels[0].getAttribute('value');\n        expect(header).toBe('Something');\n\n        instrumentedComponent.setViewModel({ header: 'Something else' });\n        const header2 = labels[0].getAttribute('value');\n        expect(header2).toBe('Something else');\n    });\n\n    valdiIt('adds kittens', async driver => {\n        const instrumentedComponent = createComponent(GettingStartedCodelab, { header: 'Kittens' });\n        const component = instrumentedComponent.getComponent();\n\n        expect(component.state.numKittens).toBe(1);\n\n        const button = elementTypeFind(componentGetElements(component), IRenderedElementViewClass.View)[0];\n\n        button.getAttribute('onTap')?.();\n\n        expect(component.state.numKittens).toBe(2);\n    });\n});\n```\n\n# Next \n\nDive in to the [documentation](https://github.com/Snapchat/Valdi/tree/main/docs#the-basics) to learn more about how to build your own app."
  },
  {
    "path": "docs/codelabs/how_to_get_help.md",
    "content": "# How to get help\n\n## Valdi on Discord\n\nJoin the [Valdi Discord Server](https://discord.gg/uJyNEeYX2U) to get help.\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/1-introduction.md",
    "content": "# What is this codelab?\nIn this code lab, you will learn how to use Valdi to communicate with native and native to communicate with Valdi.\n\nBefore diving in, you should be comfortable building your platform of choice and have a basic understanding of how to build a Valdi UI. If you're not there yet, check out the [**Getting Started Codelab**](../getting_started/1-introduction.md).\n\n<!-- TODO: will there be any pre-work style documentation for the public? -->\nThis code lab starts by building a common UI and then splits off in to **Android** and **iOS** specific paths. We recommend going all the way through one platform first and then coming back for the other.\n\n# Pre-work\nLet's make sure you're setup to develop.\n\nIn the [**Getting Started Codelab**](../getting_started) you were only modifying typescript which meant that the hotreloader could do all of the work of updating the UI. \n\nIn this codelab, we're going to be modifying native interfaces which means that we need a module linked build.\n\n<!--\n\nTODO: workflow-overview is in Snapchat/Valdi\n\nYou can find the [full documentation](../workflow-overview#iterating-locally) on the Valdi docs site but we'll walk you through it here. -->\n\n**TODO**: Publicly available documentation. This described building the private apps from source.\n\n### [Next >](./2-setup_ui.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/2-setup_ui.md",
    "content": "# Setup your UI\nThe time has come to create your own unit of Valdi. Features are separated into modules.\n\n## What is a module\n\n**TODO**: creating and adding a module to pubicly available native app source code\n\n### [Next >](./3-context_view_model.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/3-context_view_model.md",
    "content": "# Context and ViewModel\n\n**TODO**: Example of using native apis to provide ViewModel properties in publicly available source code.\n\n### [Next >](./4-get_friends.md)"
  },
  {
    "path": "docs/codelabs/integration_with_native/4-get_friends.md",
    "content": "**TODO**: Example of using ViewModel properties provided by native apis in a Valdi component\n\n### [Next >](./5-get_ready_for_testing.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/5-get_ready_for_testing.md",
    "content": "**TODO**: Adapt previous exercise view code for testing\n\n# Get ready for testing\nBefore we move on to the actual integration, let's make sure that we're set up for testing.\n\n## Identifier files\nIdentifier files, or `ids.yaml` are config files that we used to generate unique string identifiers that can be referenced to from TypeScript and native. They can be used for accessiblity but we're going to use them here to make it easier to find views for tests.\n\nCreate an `ids.yaml` file in the top level of your `hello_world` folder.\n\n`touch src/valdi/hello_world/ids.yaml`\n\nLet's add some ids to this file.\n\n```yaml\nids:\n  title:\n    description: The title of the hello world page\n```\n\n## Native testing\nIf you're just here for the testing, you can jump straight to the codelab for native testing.\n\n### [iOS native testing](./ios/5-ios_testing.md)\n### [Android native testing](./android/5-android_testing.md)\n\n### [Next >](./6-native_build_module.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/6-native_build_module.md",
    "content": "# Build a new Valdi module\nIf we were working with pure TypeScript, the hotreloader would handle our new module but we want to work with native code so we need to compile our code to generate the native classes and createa a **valdimodule**.\n\nFirst, specify what native class names you want to use in the `@ExportModel` annotation for your component.\n\n```typescript\n/**\n * @Component\n * @ExportModel({\n *  ios: 'SCCHelloWorldView',\n *  android: 'com.snap.playground.HelloWorldView'\n * })\n */\nexport class HelloWorldComponent extends StatefulComponent<ViewModel, State, Context> { \n```\n\nDo the same for the **Context**, **ViewModel**, and **Friend** objects.\n\n```typescript\n/**\n * @ViewModel\n * @ExportModel({\n *  ios: 'SCCHelloWorldViewModel',\n *  android: 'com.snap.playground.HelloWorldViewModel'\n * })\n *\n * Represents the input parameters for your Component\n */\ninterface ViewModel {\n  // ... define interface\n}\n\n/**\n * @Context\n * @ExportModel({\n *  ios: 'SCCHelloWorldContext',\n *  android: 'com.snap.playground.HelloWorldContext'\n * })\n *\n * Represents the shared Context for your Component and all its child Components.\n * Typically used to provide any bridging methods that native code will implement.\n */\ninterface Context {\n  // define interface\n}\n\n/**\n * @ExportModel({\n *  ios: 'SCCHelloWorldFriend',\n *  android: 'com.snap.playground.HelloWorldFriend'\n * })\n */\nexport interface Friend {\n  // define interface\n}\n```\n\nResynchronize your project.\n\n```\nvaldi projectsync\n```\n\n## Configuring a module\nIn this codelab, we're working with the `tsconfig.json` and `module.yaml` defaults, but you may need custom configuration in your own projects.\n\n### tsconfig.json\n`tsconfig.json` specifies the TypeScript compiler options. This is a standard config file, you can read more about it in the [official TypeScript documentation](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).\n\n### module.yaml\n`module.yaml` is specific to Valdi. This config file controls the compiled module output. We'll cover a few common options here but the full set of options is available in the [Core Module documentation](../../docs/core-module.md#moduleyaml).\n\nCommon options:\n- **`output_target`**: this can be specified globally or on a per platform basis\n    - **`debug`**: for local testing and development, won't become part of release builds\n    - **`release`**: ready for production\n- **`dependencies`**: the other modules that this module depends on\n- **`strings_dir`**: The location of your strings files\n- **`ios`**: this separates iOS specific configuration\n    - **`module_name`**: used for specifying build targets and naming directories\n    - **`class_prefix`**: used as a prefix for generated native code (usually the same as **`module_name`**)\n    - **`output_target`**: the same as discussed above but specific to iOS\n- **`android`**: Android specific configuration\n    - **`class_path`**: a Kotlin class path for the generated native code\n    - **`output_target`**: as discussed above\n- **`downloadable_assets`**: Valdi will upload your assets to BOLT and replace all references with appropriate BOLT urls. This will reduce binary size.\n- **`disable_precompilation`**: This only impacts Android and refers to compiling javascript into bytecode that the Android JS engine quickly run. Disabling precompilation will reduce binary size but lead to slower cold starts because the JS engine needs to parse the raw JS file.\n\n## `valdimodule` troubleshooting\nAny time you update the annotations or the definitions of the **Context**, **ViewModel**, or **Friend** objects, you will need to run the `valdi projectsync` script to regenerate the native code.\n\n## Choose your own adventure\nThis is the last step that applies to both Android and iOS. From here, pick one platform and follow the path to the end before coming back to do the other one (if you want).\n\n### [iOS (Objective-C)>](../integration_with_native/ios/1-ios_setup_for_development.md)\n### [iOS (Swift)>](../integration_with_native/ios_swift/1-ios_setup_for_development.md)\n### [Android >](../integration_with_native/android/1-android_setup_for_devleopment.md)\n\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/android/1-android_setup_for_development.md",
    "content": "# Setup for development\nIn the last section, we generated a new `valdimodule`. Now, let's hook it all up to Android.\n\n**TODO**: Example of integrating into an Android build (e.g bazel)\n\n### [Next >](./2-android_hook_up_module.md)"
  },
  {
    "path": "docs/codelabs/integration_with_native/android/2-android_hook_up_module.md",
    "content": "# Hook up the module\nNow that we have the module bundled up and the code in the right place, we can actually hook up our UI.\n\n**TODO**: Example using publicly available source code\n\nIf you are having trouble with the imports, they were specified in the @GenerateNativeClass annotation during a [previous step](./6-native_build_module.md). If you're working with Android studio, it may not pick up the newly generated files, run a Bazel sync to pick up the new changes.\n\nRebuild and install the Android app. Navigate to the playground and load up your new UI.\n\n### [Next >](./3-android_hook_up_snapchatter_service.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/android/3-android_hook_up_snapchatter_service.md",
    "content": "# Hook up the ExistingNativeApi\n\n**TODO**: An example of integrating a native API with a Valdi Context\n\n\n### [Next >](./4-android_recommendFriendsCallback.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/android/4-android_recommendFriendsCallback.md",
    "content": "# Implement nativeApiWithCallback\n\n**TODO**: Example of using a Valdi Context from a Valdi component using a callback API\n\n### [Next >](./5-android_testing.md)"
  },
  {
    "path": "docs/codelabs/integration_with_native/android/5-android_testing.md",
    "content": "# Testing\nRemember when we added all of those ids? It's time to put them to use. \n\nIn this section we'll be working entirely within the Android code base.\n\nBecause Valdi is it's own special rendering engine, we won't be able to create Robolectric tests, we need to load up the whole runtime so these are going to be [instrumentation tests](https://source.android.com/docs/core/tests/development/instrumentation).\n\nOn Android, Valdi may render your UI with native Android Views or with SnapDrawing. Android Views are nice and stable and well known, SnapDrawing is the new hotness that's fast but still in A/B.\n\nYou don't have to worry about the implementation details though because Valdi has a library that makes all Valdi UI compatible with [Espresso](https://developer.android.com/training/testing/espresso/basics). \n\n## Compspresso mappings\n\n**TODO**: Update links when source is moved to publicly available locations.\n\nThe full libraries are available [here](#todo) but let's go through how the Espresso functions that you know and love map to the Valdi versions.\n\n| Espresso | Compspresso | Description |\n| --- | --- | --- |\n| `onView` | `onValdiElement` | Find a view so you can do things with it. |\n| `withId` | `withAccessibilityId` | Identify a view. |\n\nThat's it. The rest of it is going to behave as expected. \n\n### Overlap\nIf you are testing traditional Android views in the same tests as Valdi views, you're going to have trouble with import overlap. Conveniently, Kotlin allows you to [alias](https://kotlinlang.org/docs/packages.html#imports) imports to get around this problem.\n\n## Set up the test files\nSetup is the most painful part of this, after that, the testing is easy.\n\nWe need a few files to get started.\n\nCreate the files.\n\n`mkdir -p components/valdi/settings/core/src/androidTest/java/com/snap/valdi/settings/core/`\n\n`touch components/valdi/settings/core/src/androidTest/java/com/snap/valdi/settings/core/HelloWorldTests.kt`\n\n`touch components/valdi/settings/core/src/androidTest/BUILD.bazel`\n\n`touch components/valdi/settings/core/src/androidTest/AndroidManifest.xml`\n\nIntegration tests conventionally go in a parallel `androidTest` directory so that's what we're doing here. \n\nIn `HelloWorldTests.kt`, create a bare bones test.\n\n```kotlin\npackage com.snap.valdi.settings.core\n\nimport androidx.test.runner.AndroidJUnit4\nimport org.assertj.core.api.Assertions.assertThat\nimport org.junit.runner.RunWith\nimport org.junit.Test\n\n@RunWith(AndroidJUnit4::class)\nclass HelloWorldTests {\n\n    @Test\n    fun dummy() {\n        assertThat(\"things\").isEqualTo(\"things\")\n    }\n}\n```\n\nWe also need a barebones `AndroidManifest.xml`\n\n```xml\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.snap.valdi.sample.test\"\n    >\n\n    <uses-sdk android:minSdkVersion=\"19\"\n        android:targetSdkVersion=\"30\"/>\n\n    <instrumentation\n        android:name=\"com.snap.test.instrumentation.runner.SnapAndroidJUnitRunner\"\n        android:targetPackage=\"com.snap.valdi.sample\" />\n\n</manifest>\n```\n\nThe `BUILD` file is where it gets complicated.\n\nAdd the imports at the top.\n\n```bazel\nload(\n    \"//bzl:sdk_variables.bzl\",\n    \"SAMPLE_MIN_SDK_VERSION\",\n    \"SAMPLE_TARGET_SDK_VERSION\",\n)\nload(\"//bzl/instrumentation:build_instrumentation_test.bzl\", \"instrumentation_test_library\")\nload(\"//bzl/instrumentation/spoon_instrumentation_rule:defs.bzl\", \"spoon_instrumentation_test\")\n```\n\nThen we setup the test library.\n\n```bazel\ninstrumentation_test_library(\n    name = \"valdi-playground-test-lib\",\n    srcs = glob([\n        \"java/**/*.java\",\n        \"java/**/*.kt\",\n    ]),\n    manifest = \"AndroidManifest.xml\",\n    deps = [\n        \"//platform/valdi/core\",\n        \"//platform/valdi/test-support:lib\",\n        \"//platform/test-attribution:lib\",\n        \"//platform/test-instrumentation-support:lib\",\n        \"@valdi_modules//:hello_world\",\n        \"@test_mvn//:androidx_test_espresso_espresso_core\",\n        \"@test_mvn//:androidx_test_runner\",\n        \"@test_mvn//:junit_junit\",\n        \"@test_mvn//:org_assertj_assertj_core\",\n        \"@test_mvn//:org_hamcrest_hamcrest_core\",\n        \"@test_mvn//:org_hamcrest_hamcrest_library\",\n    ],\n)\n```\n\nThis is where we pull in our test files and their dependencies.\n\nThen we build our lib into an Android test binary.\n\n```bazel\nandroid_binary(\n    name = \"valdi-playground-test-app\",\n    testonly = True,\n    debug_key = \"//scripts/keystore:andy-keystore\",\n    instruments = \"//platform/valdi/sample:valdi-sample-apk\",\n    manifest = \"AndroidManifest.xml\",\n    manifest_values = {\n        \"minSdkVersion\": SAMPLE_MIN_SDK_VERSION,\n        \"applicationId\": \"com.snap.valdi.sample.test\",\n        \"targetSdkVersion\": SAMPLE_TARGET_SDK_VERSION,\n    },\n    tags = [\"no-remote-cache\"],\n    deps = [\":valdi-playground-test-lib\"],\n)\n```\n\nHere we're piggybacking off of the `valdi-sample-apk` because we don't have a sample app specifically for the playground.\n\nOnly now can we setup the integration tests.\n\n```bazel\nspoon_instrumentation_test(\n    name = \"valdi-playground-instrumentation-test\",\n    # Size must be medium to accommodate for 60s average test execution time\n    # (avoids risk of exceeding the limit by a hair)\n    size = \"medium\",\n    test_app = \":valdi-playground-test-app\",\n)\n```\n\nThis is the bare minimum setup to run some tests on a Valdi UI.\n\nAt this point, stop and make sure everything works.\n\n`./bazelw test //components/valdi/settings/core/src/androidTest:valdi-playground-instrumentation-test`\n\nYou should see one passing test.\n\n## Interlude: real world testing\nIn this codelab, we're going to test an individual Component. It's unlikely that you'll do this in the real world but the concepts around accessing Valdi components and interacting with them will be valuable when testing UIs that contain both traditional and Valdi UI.\n\n## Test setup\nWe're going to use the ValdiViewTestRule to create our component and make sure it behaves the way we expect it to. \n\n```kotlin\n@Rule\n@JvmField\nval viewTestRule = ValdiViewTestRule {\n    val context = HelloWorldContext(\n        title = \"Hello world\",\n        recommendFriendsCallback = {\n            \"success\"\n        }\n    )\n    HelloWorldView.create(it, HelloWorldViewModel(), context)\n}\n```\n\nWe need to create a context with some defaults but we can use the ViewModel as is. \n\nThen we need to handle startup and teardown.\n\n```kotlin\n@Before\nfun prepare() {\n    viewTestRule.waitForNextRender()\n}\n\n@After\nfun tearDown() {\n    viewTestRule.destroyView()\n}\n```\n\nWe are `waitForNextRender`ing to make sure that the component is displayed before we start trying to test it.\n\n## First test\nLet's double check that the UI has rendered. We have one element that we know is going to render no matter what.\n\n```kotlin\n@Test\nfun rendersRecommendFriendsButton() {\n    onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommend_friends_button))\n        .check(matchesAnyDescendant(withValdiAttribute(\"value\", \"Recommend friends\")))\n}\n```\n\nHere we're using the Valdispresso `onValdiElement` to access the UI. Then we're using our id, full qualified here as `com.snap.valdi.modules.R.id.hello_world__recommend_friends_button` to find the button.\n\n`recommend_friends_button` refers to a `CoreButton` but we know that to display the text, it has to contain a `<label>` with a `value` that is \"Recommend friends\". So we `check` that there is some descendant `withValdiAttribute`.\n\nRun your tests and make sure they pass.\n\n`./bazelw test //components/valdi/settings/core/src/androidTest:valdi-playground-instrumentation-test`\n\n## Updating the ViewModel\nThis is something that we didn't do in our UI but we can still test the behavior any way.\n\nIf you update the `ViewModel` from native, it has the same effect as if you update the component's parameters from TypeScript.\n\nLet's make sure that the starting value is what we think it is. \n\n```kotlin \nfun resetSubtitleThroughViewModel() {\n    onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__subtitle))\n        .check(matches(withValdiAttribute(\"value\", null)))\n}\n```\n\nWe never set the value of the **subtitle** in the `ViewModel` on setup so it should be null.\n\nNow let's give the view a new `ViewModel`. In the same function:\n\n```kotlin\nvar helloWorldViewModel = HelloWorldViewModel()\nhelloWorldViewModel.subtitle = \"subtitle\"\n\nviewTestRule.view.viewModel = helloWorldViewModel\n\nviewTestRule.waitForNextRender()\n```\n\nWe need to `waitForNextRender` because the values won't update until the next render.\n\nNow we can check the new value.\n\n```kotlin\nonValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__subtitle))\n    .check(matches(withValdiAttribute(\"value\", \"subtitle\")))\n```\n\nLet's try this one more time to make sure it really works.\n\n```kotlin\nviewTestRule.view.viewModel = helloWorldViewModel\nhelloWorldViewModel.subtitle = \"new subtitle\"\nviewTestRule.waitForNextRender()\n\nonValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__subtitle))\n    .check(matches(withValdiAttribute(\"value\", \"new subtitle\")))\n```\n\nRun your tests and make sure they pass.\n\n## Test the `recommendFriendsCallback`\nLet's make sure that the UI responds correctly when you tap on the **Recommend friends** button.\n\nFirst lets return some friends from the callback in the `ValdiViewTestRule`.\n\n```kotlin\nval context = HelloWorldContext(\n    title = \"Hello world test\",\n    recommendFriendsCallback = {\n        it(listOf(HelloWorldFriend(\"Steve Rogers\"),\n                    HelloWorldFriend(\"Tony Stark\"),\n                    HelloWorldFriend(\"Thor Odinson\")))\n        \"success\"\n    }\n)\n```\n\nThen we need to interact with the with button that triggers the callback.\n\n```kotlin\n@Test\nfun recommendsFriends() {\n    onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommend_friends_button))\n        .perform(click())\n\n    viewTestRule.waitForNextRender()\n}\n```\n\n**TODO**: Update link when source is publicy available.\nYou can find the full set of interactions in [ValdiElementActions](#todo).\n\nAgain, we're waiting for the next render so that the UI will update.\n\nThen we can check and make sure our friends are displayed as expected.\n\n```kotlin\nonValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommended_friends_container))\n    .check(matchesAnyDescendant(withValdiAttribute(\"value\", \"Steve Rogers\")))\n\nonValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommended_friends_container))\n    .check(matchesAnyDescendant(withValdiAttribute(\"value\", \"Tony Stark\")))\n\nonValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommended_friends_container))\n    .check(matchesAnyDescendant(withValdiAttribute(\"value\", \"Thor Odinson\")))\n```\n\nMake sure your tests are all passing.\n\n`./bazelw test //components/valdi/settings/core/src/androidTest:valdi-playground-instrumentation-test`\n\n## Full solution\nHere's the full test file if you need it.\n\n```kotlin\npackage com.snap.valdi.settings.core\n\nimport androidx.test.runner.AndroidJUnit4\nimport com.snap.valdi.test.ValdiViewTestRule\nimport com.snap.playground.HelloWorldContext\nimport com.snap.playground.HelloWorldFriend\nimport com.snap.valdi.test.ValdiElementActions.click\nimport com.snap.valdi.test.ValdiElementAssertions.matchesAnyDescendant\nimport com.snap.valdi.test.ValdiElementMatchers.withAccessibilityId\nimport com.snap.valdi.test.ValdiElementAssertions.matches\nimport com.snap.valdi.test.ValdiElementMatchers.withValdiAttribute\nimport com.snap.valdi.test.ValdiEspresso.onValdiElement\nimport com.snap.playground.HelloWorldView\nimport com.snap.playground.HelloWorldViewModel\nimport org.assertj.core.api.Assertions.assertThat\nimport org.junit.runner.RunWith\nimport org.junit.Test\nimport org.junit.Rule\nimport org.junit.After\nimport org.junit.Before\n\n\n@RunWith(AndroidJUnit4::class)\nclass HelloWorldTests {\n\n    @Rule\n    @JvmField\n    val viewTestRule = ValdiViewTestRule {\n        val context = HelloWorldContext(\n            title = \"Hello world test\",\n            recommendFriendsCallback = {\n                it(listOf(HelloWorldFriend(\"Steve Rogers\"),\n                          HelloWorldFriend(\"Tony Stark\"),\n                          HelloWorldFriend(\"Thor Odinson\")))\n                \"success\"\n            }\n        )\n        HelloWorldView.create(it, HelloWorldViewModel(), context)\n    }\n\n    @Before\n    fun prepare() {\n        viewTestRule.waitForNextRender()\n    }\n\n    @After\n    fun tearDown() {\n        viewTestRule.destroyView()\n    }\n\n    @Test\n    fun dummy() {\n        assertThat(\"things\").isEqualTo(\"things\")\n    }\n\n    @Test\n    fun rendersRecommendFriendsButton() {\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommend_friends_button))\n            .check(matchesAnyDescendant(withValdiAttribute(\"value\", \"Recommend friends\")))\n    }\n\n    @Test\n    fun contextSetsTitle() {\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__title))\n            .check(matches(withValdiAttribute(\"value\", \"Hello world test\")))\n    }\n\n    @Test\n    fun resetSubtitleThroughViewModel() {\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__subtitle))\n            .check(matches(withValdiAttribute(\"value\", null)))\n\n        var helloWorldViewModel = HelloWorldViewModel()\n        helloWorldViewModel.subtitle = \"subtitle\"\n\n        viewTestRule.view.viewModel = helloWorldViewModel\n\n        viewTestRule.waitForNextRender()\n\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__subtitle))\n            .check(matches(withValdiAttribute(\"value\", \"subtitle\")))\n\n        viewTestRule.view.viewModel = helloWorldViewModel\n        helloWorldViewModel.subtitle = \"new subtitle\"\n        viewTestRule.waitForNextRender()\n\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__subtitle))\n            .check(matches(withValdiAttribute(\"value\", \"new subtitle\")))\n    }\n\n    @Test\n    fun recommendsFriends() {\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommend_friends_button))\n            .perform(click())\n\n        viewTestRule.waitForNextRender()\n\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommended_friends_container))\n            .check(matchesAnyDescendant(withValdiAttribute(\"value\", \"Steve Rogers\")))\n\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommended_friends_container))\n            .check(matchesAnyDescendant(withValdiAttribute(\"value\", \"Tony Stark\")))\n\n        onValdiElement(withAccessibilityId(com.snap.valdi.modules.R.id.hello_world__recommended_friends_container))\n            .check(matchesAnyDescendant(withValdiAttribute(\"value\", \"Thor Odinson\")))\n    }\n}\n```\n\n### [Check out the iOS version >](https://github.com/Snapchat/Valdi/blob/main/docs/codelabs/integration_with_native/ios/1-ios_setup_for_development.md)"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios/1-ios_setup_for_development.md",
    "content": "# Setup for development\nIn the last section, we generated a new `valdimodule`. Now, let's hook it all up to (**TODO**: pubicly available sample app source code).\n\n**TODO**: Example integrating `valdimodule` into a build\n\n### [Next >](./2-ios_hook_up_module.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios/2-ios_hook_up_module.md",
    "content": "# Hook up the module\nNow that we have the module bundled up and the code in the right place, we can actually hook up our UI.\n\n**TODO**: Example of instantiating Valdi and adding it to an existing UI\n\n### [Next >](./3-ios_hook_up_snapchatter_service.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios/3-ios_hook_up_snapchatter_service.md",
    "content": "# Hook up the GenericService\n\n**TODO**: Example of integrating with an existing custom native API.\n\n\n### [Next >](./4-ios_recommendfriendscallback.md)"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios/4-ios_recommendfriendscallback.md",
    "content": "# Implement valdiToNativeApi\n\n**TODO**: Example of calling native code from a Valdi component\n\n### [Next >](./5-ios_testing.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios/5-ios_testing.md",
    "content": "# Testing\nRemember when we added all of those ids? It's time to put them to use. \n\nOn iOS, Valdi renders UI as native Views so we can work with them the same way you'd work with pure native UI with one big caveat: Valdi is its own special rendering engine. We need the whole runtime for tests so we'll be creating UI tests.\n\n**TODO**: Unit Tests with publicly available iOS testing environments\n\n\n### [Check out the Android version >](../android/1-android_setup_for_devleopment.md)"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios_swift/1-ios_setup_for_development.md",
    "content": "# Setup for development\nIn the last section, we generated a new valdimodule. Now, let's hook it all up to iOS.\nWe will create a new option in the Settings menu from scratch and will load a new view when it is clicked.\n\nIf you're continuing directly from the last section. You'll need to reset the Playground.tsx file back to the original to prevent compilation errors. We won't be using the Playground module in this part.\n\n## Building your component for Swift\nIn the module.yaml of the module, add `language: swift` to the `ios` section. The module.yaml should contain the following:\n\n```bazel\nios:\n  class_prefix: SCCHelloWorld\n  module_name: SCCHelloWorld\n  language: swift\n\n```\n\n**TODO**: Update this for open source\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios_swift/2-ios_hook_up_module.md",
    "content": "# Hook up the module\nNow that we have the settings row, lets hook up our module to the UI.\n\n## Create ValdiSwiftDemoViewController.swift\n\nCreate the file `ValdiSwiftDemoViewController.swift` (`Features/Valdi/EntryPoints/ValdiSettingsSwiftEntryPoint/Sources/ValdiSwiftDemoViewController.swift`)\nand add the following to it:\n```swift\nimport valdi_core\nimport SCValdiServices\nimport SCCHelloWorld\nimport UIKit\n\nenum ValdiSwiftDemoViewControllerError: Error {\n    case runtimeUnavailable\n}\n\nclass ValdiSwiftDemoViewController: UIViewController {\n    init(valdiServices: SCValdiServices) throws {\n        super.init(nibName: nil, bundle: nil)\n    }\n\n    override func viewDidLoad() {\n    }\n\n    override func viewWillLayoutSubviews() {\n    }\n\n    @available(*, unavailable)\n    required init?(coder: NSCoder) {\n        fatalError(\"init(coder:) is not a valid initializer for this view controller\")\n    }\n}\n```\n\n\n## Instantiating the Valdi view\n\nFirst we want to create a variable to hold our Valdi view. The name of the type of the valdi view is defined in the .tsx file with the `@ExportModule` annotation\nAdd the following property to the class:\n\n```swift\nprivate let contentView: SCCHelloWorldView\n```\n\nNow let's initialize the view in the `init()` function. Insert all of the following before the super.init() call, since contentView needs to be initialized before it's called.\n\nFirst we want to make sure we have a `runtime` which we need to create our view.\n```swift\nguard let valdiRuntime = valdiServices.valdiRuntimeProvider.target()?.runtime else {\n    throw ValdiSwiftDemoViewControllerError.runtimeUnavailable\n}\n```\n\nThen we create our ViewModel and Context. Any non-optional parameters must be provided in the constructor on the object.\n```swift\nlet viewModel = SCCHelloWorldViewModel()\nviewModel.subtitle = \"MySubtitle\"\n\nlet dummyRecommendFriendsCallback: ((@escaping ([SCCHelloWorldFriend]) throws -> Void) throws -> String) = { completion in\n    // Dummy implementation of the callback\n    let dummyFriends = [SCCHelloWorldFriend(name: \"John Doe\"), SCCHelloWorldFriend(name: \"Jane Doe\")]\n    try completion(dummyFriends)\n    return \"Callback executed\"\n}\nlet context = SCCHelloWorldContext(title: \"HelloWorld\", recommendFriendsCallback: dummyRecommendFriendsCallback)\n```\n\nAnd finally let's create our view\n```swift\nself.contentView = try SCCHelloWorldView(viewModel: viewModel, context: context, runtime: valdiRuntime)\n```\n\n## Hook up Valdi View\n\nIn the `viewDidLoad` function add the following to load our Valdi view as a subview:\n```swift\ncontentView.valdiContext.traitCollection = traitCollection\nview.addSubview(contentView)\n```\n\nAnd in `viewWillLayoutSubviews`, add the following:\n```swift\ncontentView.frame = view.bounds\n```\n\n## Load our view controller when Settings row is clicked\n\nFinally, we want to load our ViewController when the Settings row is clicked.\nBack in\n`ValdiSwiftDemoViewController.swift` (`Features/Valdi/EntryPoints/ValdiSettingsSwiftEntryPoint/Sources/ValdiSwiftDemoViewController.swift`) add the following in `onSettingsRowHandleContext` in the `do` block:\n\n```swift\nlet settingsPageViewController = try ValdiSwiftDemoViewController(\n    valdiServices: valdiServices\n)\nnavigationController.pushViewController(settingsPageViewController, animated: true)\n```\n\nNow rebuild iOS, navigate to the settings, and load up your new UI.\n\n### [Next >](https://github.com/Snapchat/Valdi/blob/main/docs/codelabs/integration_with_native/ios/3-ios_hook_up_snapchatter_service.md)\n"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios_swift/3-ios_hook_up_snapchatter_service.md",
    "content": "# Hook up the GenericService\n\n**TODO**: Example of integrating with an existing custom native API.\n\n\n### [Next >](./4-ios_recommendfriendscallback.md)"
  },
  {
    "path": "docs/codelabs/integration_with_native/ios_swift/4-ios_recommendfriendscallback.md",
    "content": "# Implement recommendFriendsCallback\nIt is time to actually do the thing we came here to do!\nLets replace our `dummyRecommendFriendsCallback` callback with a real callback:\n\n```swift\nlet friendsCallback: ((@escaping ([SCCHelloWorldFriend]) throws -> Void) throws -> String) = { completion in\n    snapchatterServices.snapchattersDataFetcher.target()?.suggestedSnapchatters(for: .addFriends, completionQueue: DispatchQueue.main) { snapchatters, error in\n        var friends = [SCCHelloWorldFriend]()\n        if error == nil, let snapchatters = snapchatters, !snapchatters.isEmpty {\n            for snapchatter in snapchatters {\n                guard let displayName = snapchatter.displayName else { continue }\n                let friend = SCCHelloWorldFriend(name: displayName)\n                friends.append(friend)\n            }\n        }\n        do {\n            try completion(friends)\n        } catch {\n            // Handle error\n        }\n    }\n    return \"Success\"\n}\n```\n\nThen use this as the `recommendFriendsCallback` when creating `SCCHelloWorldContext`:\n```swift\nlet context = SCCHelloWorldContext(title: \"HelloWorld\", recommendFriendsCallback: friendsCallback)\n```\n\nThat's it. That's the last step.\n\nWe request some suggested friends from the **snapchattersDataFetcher** and then when we get them, we iterate through, format the friends into **Friends**, and put them in an array. Then call the completion with the list.\n\nRebuild your app, load up the page, make some friends.\n\n### [Next >](https://github.com/Snapchat/Valdi/blob/main/docs/codelabs/integration_with_native/ios/4-ios_recommendfriendscallback.md)\n"
  },
  {
    "path": "docs/codelabs/shared_business_logic/1-introduction.md",
    "content": "# What is this codelab?\nValdi is not just a UI framework, it also includes a javascript runtime. In this codelab you will learn how to implement business logic in typescript and use it from Android and iOS.\n\nBefore diving in, you should be comfortable building your platform of choice and have a basic understanding of Valdi. If you're not there yet, check out the [**Getting Started Codelab**](../getting_started).\n\nThis code lab starts by building common typescript logic and then splits off in to **Android** and **iOS** specific paths. We recommend going all the way through one platform first and then coming back for the other.\n\n# Pre-work\nLet's make sure you're setup to develop.\n\nIn the [**Getting Started Codelab**](../getting_started) you were only modifying TypeScript which meant that the hotreloader could do all of the work of updating the UI. \n\nIn this codelab, we're going to be modifying native interfaces which means that we need a module linked build.\n\nFor more details on native bindings and annotations, see the [Native Annotations documentation](../../docs/native-annotations.md) and [Native Bindings documentation](../../docs/native-bindings.md).\n\n### [Next >](./2-setup_module.md)"
  },
  {
    "path": "docs/codelabs/shared_business_logic/2-setup_module.md",
    "content": "# Setup your Module\nThe time has come to create your own unit of Valdi. Features are separated into modules.\n\n## What is a module\nModules live in `src/valdi_modules/src/valdi/<component_name>` (relative to the Valdi root directory).\n\nA module is a set of typescript classes, components, and functions. Modules may, but do not have to, contain image assets, localized strings, and TypeScript tests.\n\nModules can depend on other modules.\n\nAll of these things get compiled down into **valdimodule** files that get read by the **Valdi Runtime** and render natively on each platform.\n\n## Create a new module\nWe have a convenient script to create a new module for you that sets up the basic structure and creates a few important files.\n\n**TODO**: Provide correct parent directory/instructions to the valdi cli\n\n`./scripts/new_module.py hello_world`\n\nThis creates a new module called `hello_world`.\n\nOpen VSCode and navigate to your code.\n\nYour new code will be at `src/valdi/hello_world`\n\nYou should see a handful of files and folders:\n\n- `module.yaml` - Dependencies and generated output files\n- `tsconfig.json` - Typescript compilation options\n- `strings.yaml` - Localized strings\n- `res/` - Image assets\n- `src/` - Typescript code\n    - `HelloWorld.tsx` - Main entry component\n\nThe defaults in `module.yaml` and `tsconfig.json` will work fine for our purposes but feel free to check them out. \n\nThis `HelloWorld.tsx` is the default starting point for UI Components but we won't need it. Go ahead and delete it.\n\nInstead, create a new TypeScript file `Calculator.ts`. This should be a TypeScript file not a TSX file. Learn more about TSX in the [**Getting Started codelab**](../getting_started/5-declarative_rendering.md#tsxjsx).\n\n### [Next >](./3-business_logic.md)\n"
  },
  {
    "path": "docs/codelabs/shared_business_logic/3-business_logic.md",
    "content": "# Business logic\nLet's implement our business logic for this new module we've created.\n\n## Calculator \nWe're going to create a basic calculator in typescript.\n\nIn `Calculator.ts`, create the basic interface.\n\n```typescript\nexport interface ICalculator {\n  add(value: number): void;\n  sub(value: number): void;\n  mul(value: number): void;\n  div(value: number): void;\n\n  total(): number;\n}\n```\n\nThe `export` makes this interface available outside of the file.\n\nThen, in the same file, we'll create a simple implementation.\n\n```typescript\nclass SampleCalculator implements ICalculator {\n  private current = 0;\n\n  constructor(startingValue: number) {\n    this.current = startingValue;\n  }\n\n  add(value: number): void {\n    this.current += value;\n  }\n\n  sub(value: number): void {\n    this.current -= value;\n  }\n\n  mul(value: number): void {\n    this.current *= value;\n  }\n\n  div(value: number): void {\n    this.current /= value;\n  }\n\n  total(): number {\n    return this.current;\n  }\n}\n```\n\nThen we need some utility functions so we can use this implementation.\n\n```typescript\nexport function createCalculator(startingValue: number): ICalculator {\n  return new SampleCalculator(startingValue);\n}\n\nexport function calculatorToString(calculator: ICalculator): string {\n  const classType = calculator.constructor?.name ?? '<unknown class>';\n  const isJsStringConvertible = calculator instanceof SampleCalculator;\n\n  return `Class: ${classType} (is js: ${isJsStringConvertible}): ${calculator.total()}`;\n}\n```\n\n## Magic\nA persistent calculator is all fine and good but what if you need a one-off cross-platform function to access some magic numbers?\n\nCreate another typescript file, `Magic.ts`.\n\nIn this file, we'll implement another function that returns a magic string.\n\n```typescript\nexport function showMeTheMagic(): string {\n  return '42andThings';\n}\n```\n\n### [Next >](./4-native_annotations.md)\n"
  },
  {
    "path": "docs/codelabs/shared_business_logic/4-native_annotations.md",
    "content": "# Native annotations\nNow that we have our calculator, we need to make it accessible from native code. In Valdi, this is done with annotations.\n\nYou can find a full list in the [Native Annotations documentation](../../docs/native-annotations.md).\n\n## GenerateNativeInterface\nWe'll need the calculator interface.\n\n```typescript\n// @GenerateNativeInterface\nexport interface ICalculator {\n  add(value: number): void;\n  sub(value: number): void;\n  mul(value: number): void;\n  div(value: number): void;\n\n  total(): number;\n}\n```\n\n## GenerateNativeFunction\nWe also need the utility methods.\n\n```typescript\n// @GenerateNativeFunction\nexport function createCalculator(startingValue: number): ICalculator {\n  return new SampleCalculator(startingValue);\n}\n\n// @GenerateNativeFunction\nexport function calculatorToString(calculator: ICalculator): string {\n  const classType = calculator.constructor?.name ?? '<unknown class>';\n  const isJsStringConvertible = calculator instanceof SampleCalculator;\n\n  return `Class: ${classType} (is js: ${isJsStringConvertible}): ${calculator.total()}`;\n}\n```\n\nThese will create native files with the paths and prefixes specified in this module's `module.yaml`.\n\n### Extra configuration options\nThere are more options available for the `@GenerateNativeFunction` annotation.\n\nLet's play with them in `Magic.ts`.\n\n```typescript\n// @GenerateNativeFunction({ios: 'SCTotesIsMagic', android: 'com.valdi.hello.world.TotesIsMagic'})\nexport function showMeTheMagic(): string {\n  return '42andThings';\n}\n```\n\nHere we're specifying the iOS name and Android path for the function.\n\n\n## Generate the native files\nBecause we've added `GenerateNative` annotations, we need to recompile and synchronize the project.\n\nIf you're only working on one module, you can specify it with the `--target` option to speed up the process. Keep in mind that the first compile you do after creating a new branch and linking modules needs to compile all of the modules. Only after you start iterating on one module can you speed up the process.\n\n```\nvaldi projectsync\n```\n\n> **Note:** The `projectsync` command regenerates native bindings and updates VS Code project files. See [Command Line References](../../docs/command-line-references.md) for more details.\n\n## The full solution if you need it\n### Calculator.ts\n```typescript\n// @GenerateNativeInterface\nexport interface ICalculator {\n  add(value: number): void;\n  sub(value: number): void;\n  mul(value: number): void;\n  div(value: number): void;\n\n  total(): number;\n}\n\nclass SampleCalculator implements ICalculator {\n  private current = 0;\n\n  constructor(startingValue: number) {\n    this.current = startingValue;\n  }\n\n  add(value: number): void {\n    this.current += value;\n  }\n\n  sub(value: number): void {\n    this.current -= value;\n  }\n\n  mul(value: number): void {\n    this.current *= value;\n  }\n\n  div(value: number): void {\n    this.current /= value;\n  }\n\n  total(): number {\n    return this.current;\n  }\n}\n\n// @GenerateNativeFunction\nexport function createCalculator(startingValue: number): ICalculator {\n  return new SampleCalculator(startingValue);\n}\n\n// @GenerateNativeFunction\nexport function calculatorToString(calculator: ICalculator): string {\n  const classType = calculator.constructor?.name ?? '<unknown class>';\n  const isJsStringConvertible = calculator instanceof SampleCalculator;\n\n  return `Class: ${classType} (is js: ${isJsStringConvertible}): ${calculator.total()}`;\n}\n```\n\n### Magic.ts\n```typescript\n// @GenerateNativeFunction({ios: 'SCTotesIsMagic', android: 'com.valdi.hello.world.TotesIsMagic'})\nexport function showMeTheMagic(): string {\n  return '42andThings';\n}\n```\n\n## Choose your own adventure\nThis is the last step that applies to both Android and iOS. From here, pick one platform and follow the path to the end before coming back to do the other one (if you want).\n\n### [iOS >](./ios/1-ios_setup_for_development.md)\n### [Android >](./android/1-android_setup_for_development.md)\n\n"
  },
  {
    "path": "docs/codelabs/shared_business_logic/android/1-android_setup_for_development.md",
    "content": "# Setup for development\nIn the last section, we generated a new Valdi module. Now, let's hook it all up to Android.\n\n## Dependencies\n\n**TODO**: is this relevant to `open_source`?\n\nIn order to use the TypeScript business logic, we need to build a reference to the functions we just generated. For Valdi with no UI, we need a reference to the `ValdiJSRuntime`. We can get the `ValdiJSRuntime` through the `IValdiRuntime`. **TODO**: Wo we actually have `IValdiRuntime` now?\n\nIn Android, the `IValdiRuntime` is injected by Dagger. We're building this example in part of the code base where the dependencies have already been setup. When you're building your own code, you'll need to set up Dagger.\n\n\n**TODO**: Example of providing \"headless\" `valdimodule` APIs to other parts of Android.\n\n### [Next >](./2-android_hook_up_module.md)\n"
  },
  {
    "path": "docs/codelabs/shared_business_logic/android/2-android_hook_up_module.md",
    "content": "# Hook up the module\nNow that we have the module bundled up and the code in the right place, we can start using our calculator.\n\n**TODO**: Use publicly available source code example\n\n### [Check out the iOS version >](../ios/1-ios_setup_for_development.md)\n"
  },
  {
    "path": "docs/codelabs/shared_business_logic/ios/1-ios_setup_for_development.md",
    "content": "# Setup for development\nIn the last section, we generated a new valdimodule. Now, let's hook it all up to iOS. We're going to be working within the existing Playground files.\n\n**TODO**: Example for iOS using pubicly available source code.\n\n### [Next >](./2-ios_hook_up_module.md)\n"
  },
  {
    "path": "docs/codelabs/shared_business_logic/ios/2-ios_hook_up_module.md",
    "content": "# Hook up the module\nNow that we have the module bundled up and the code in the right place, we can start using our calculator.\n\n## Set up for the calculator\n\n*TODO*: Use pubicly available source code for intergration point.\n\nWe're going to leave the playground setup as is and create our calculator alongside it. The calculator doesn't have any UI so we will add logging to understand what's going on.\n\nIn `SCValdiPlaygroundViewController.m` (**TODO**: path to pubicly available source), import the native functions.\n\n```objectivec\n#import <SCCHelloWorld/SCCHelloWorldCalculatorToString.h>\n#import <SCCHelloWorld/SCCHelloWorldCreateCalculator.h>\n#import <SCCHelloWorld/SCTotesIsMagic.h>\n```\n\nIf Xcode is unhappy about these imports, recompile.\n\nWe need to hold onto a reference to the `SCValdiRuntime` so add a local variable to keep track of it.\n\n```objectivec\n@implementation SCValdiPlaygroundViewController {\n    SCCPlaygroundView *_contentView;\n    id<SCValdiRuntimeProtocol> _runtime;\n}\n```\n\nThen inside of `initWithValdiServices`, intialize the `_runtime`.\n\n```objectivec\nif (self = [super init]) {\n    ...\n        \n    _runtime = valdiServices.valdiRuntimeProvider.target.runtime;\n}\n```\n\nNow let's create a function where we will create and use our calculator.\n\n```objectivec\n- (void)calculate:(id<SCValdiJSRuntime>)runtime\n{\n    NSLog(@\"Calculator setup!\");\n}\n```\n\nThis is just a stub for now, we'll need the `SCValdiJSRuntime` soon.\n\nAnd then in `viewDidLoad`, we'll call the new function.\n\n```objectivec\n- (void)viewDidLoad\n{\n    [self.view addSubview:_contentView];    \n    [self calculate:_runtime.jsRuntime];\n}\n\n```\n\nWhen you load up the Playground, your function will be called. Check out the logs in XCode and make sure you can find the `Calculator setup!` message.\n\n## JavaScript execution primer\n\nBefore we get started, let's walk through how JavaScript function execution works with Valdi.\n\nFunction calls are always executed on the JavaScript thread. Valdi abstracts all of that away for you so you don't have to worry about it but it's helpful to understand what's going on.\n\nIf you need to get the result of your function back \"synchronously\" for use in native code, you can. Valdi will dispatch the work to run on the JS thread and then wait for the result before continuing on.\n\nIf async execution is fine, you can use the `getJSRuntimeWithBlock` API.\n\n## Calculate \"synchronously\"\nNow that you have the basics setup, let's actually use our typescript functions.\n\nInside the `calculate` function, create a reference to the typescript `createCalculator` helper function.\n\n```objectivec\nSCCHelloWorldCreateCalculator *createCalculatorFn = [SCCHelloWorldCreateCalculator functionWithJSRuntime:runtime];\n```\n\nThen we can call our function and get a reference to the calculator.\n\n```objectivec\nid<SCCHelloWorldICalculator> calculator = [createCalculatorFn createCalculatorWithStartingValue:1];\n```\n\nDo some math and then log the result.\n\n```objectivec\n[calculator addWithValue:2];\n[calculator mulWithValue:4];\n\nNSLog(@\"Calculator value after ((1 + 2) * 4): %f\", [calculator total]);\n```\n\nStop at this point, recompile the app and navigate to the Playground. Make sure you see the output of your logging in Xcode.\n\nLet's play with that other utility function.\n\n```objectivec\nSCCHelloWorldCalculatorToString *calculatorToString = [SCCHelloWorldCalculatorToString functionWithJSRuntime:runtime];\n    \nNSLog(@\"TypeScript calculator to string: %@\", [calculatorToString calculatorToStringWithCalculator:calculator]);\n```\n\nRecompile and check your logs.\n\n## Get the magic asynchronously\nIf you don't need your functions to return a value synchronously to platform code, you can execute them asynchronously.\n\nLet's execute the magic function with `getJSRuntimeWithBlock` inside of `viewDidLoad`\n\n```objectivec\n[_runtime getJSRuntimeWithBlock:^(id<SCValdiJSRuntime> runtime) {\n    SCTotesIsMagic *magicFn = [SCTotesIsMagic functionWithJSRuntime:runtime];\n    NSLog(@\"Result is: %@\", [magicFn showMeTheMagic]);\n}];\n    \n```\n\nRebuild iOS, navigate to the playground, and check your logs.\n\n### [Check out the Android version >](../android/1-android_setup_for_development.md)\n"
  },
  {
    "path": "docs/docs/advanced-animations.md",
    "content": "# Advanced animations\n\nValdi exposes an imperative way to animate attributes. Almost all attributes can be animated in Valdi. \n\n## `animate` and `animatePromise`\n\nTo support animations `Valdi` class provies `animate` and `animatePromise` functions. Use `animatePromise` to observe the animation finish event.\n\n```ts\ndeclare class Component {\n  //...\n  /* \n   * Associate a set of changes with an animation\n   * @param animations a block which will be executed in a render. All element mutations\n   * belong to this renderer will be animated.\n   * To get notified on animation complete, use `animatePromise` instead.\n   */\n  animate(options: AnimationOptions, animations: () => void): void;\n  \n  /*\n   * Associate a set of changes with an animation\n   * @param animations a block which will be executed in a render. All element mutations\n   * belong to this renderer will be animated.\n   * @return A promise which will be resolved when the animation finishes.\n   */\n  animatePromise(options: AnimationOptions, animations: () => void): Promise<void>;\n}\n```\n\nThis API is inspired by iOS's `animateWithDuration:animations:`. Your can pass an `AnimationOptions` object, which will define how long the animation should be and what curve or control points to use. Your provided `animations` function will then be called, and you will be able to make any mutation to your Component's state, or to the element's attributes directly. All mutations will be applied with an animation automatically.\n\n## `AnimationOptions`\n\nBoth functions [accept](./generated-docs/valdi_core/AnimationOptions/valdi-generated.md) `AnimationOptions`:\n\n```ts\nexport enum AnimationCurve {\n  Linear = 'linear',\n  EaseIn = 'easeIn',\n  EaseOut = 'easeOut',\n  EaseInOut = 'easeInOut',\n}\n\nexport type AnimationOptions = SpringAnimationOptions | PresetCurveAnimationOptions | CustomCurveAnimationOptions;\n\nexport interface BasicAnimationOptions {\n  /**\n   * The duration of the animation in seconds.\n   */\n  duration: number;\n\n  /**\n   * Whether the animation should start from the current layer state.\n   * Corresponds to CoreAnimation's beginFromCurrentState.\n   */\n  beginFromCurrentState?: boolean;\n\n  /**\n   * Whether the animation should crossfade with an alpha transition between the\n   *  previous state of the tree to the new state.\n   */\n  crossfade?: boolean;\n\n  /**\n   * A completion to call when the transition has completed\n   */\n  completion?: (wasCancelled: boolean) => void;\n}\n\nexport interface PresetCurveAnimationOptions extends BasicAnimationOptions {\n  /**\n   * The curve to use for the animation, defaults\n   * to easeInOut. Ignored when controlPoints is set.\n   */\n  curve?: AnimationCurve;\n}\n\nexport interface CustomCurveAnimationOptions extends BasicAnimationOptions {\n  /**\n   * 4 control points to control the curve.\n   * If set, curve will be ignored to use those\n   * control points instead.\n   */\n  controlPoints: Array<number>;\n}\n\nexport interface SpringAnimationOptions {\n  /**\n   * The spring stiffness coefficient. Higher values correspond to a stiffer spring that yields a greater amount of force for moving objects.\n   * Corresponds to the \"spring constant\" in the spring equation.\n   *\n   * Must be greater than 0.\n   */\n  stiffness: SpringStiffnessValue;\n\n  /**\n   * The damping force to apply to the spring’s motion. This is the damping coefficient in the spring equation.\n   *\n   * Must be greater than 0.\n   */\n  damping: SpringDampingValue;\n\n  /**\n   * Whether the animation should start from the current layer state.\n   * Corresponds to CoreAnimation's beginFromCurrentState.\n   */\n  beginFromCurrentState?: boolean;\n\n  /**\n   * A completion to call when the transition has completed\n   */\n  completion?: (wasCanceled: boolean) => void;\n}\n```\n\n## Example\n```tsx\nexport class YourComponent extends Component {\n\n  titleLabel = new ElementRef();\n  titleContainer = new ElementRef();\n\n  onRender() {\n    <layout>\n      <view ref={this.titleContainer}>\n        <label value='This is a title' ref={this.titleLabe}/>\n      </view>\n    </layout>\n  }\n\n  somethingHappened() {\n    this.animate({ duration: 0.3 }, () => {\n      // This change of font will make the label crossfade to the new size\n      this.titleLabel.setAttribute('font', 'title');\n      // The titleContainer will be resized to that given size, any resulting\n      // change of the layout will be animated.\n      this.titleContainer.setAttribute('width', 200);\n    });\n  }\n}\n```\n\nYou can also animate state changes, which will render your component with the new state and automatically animate any mutations:\n```tsx\ninterface State {\n  text: string;\n}\nexport class YourComponent extends StatefulComponent<object, State> {\n\n  state = {text: 'This is a title'};\n\n  onRender() {\n    <layout>\n      <view>\n        <label value={this.state.text}/>\n      </view>\n    </layout>\n  }\n\n  somethingHappened() {\n    // This will mutate the state, the new text will be applied to the label through a crossfade animation\n    this.setStateAnimated({text: 'This is the new text'}, {duration: 0.3});\n  }\n}\n```\n"
  },
  {
    "path": "docs/docs/advanced-element-references.md",
    "content": "# Element References\n\n## IRenderedElement\n\nThe `IRenderedElement` interface is an abstraction over a rendered element. It allows you to see which attributes were applied, set new attributes, get the children elements, get the parent element, get a reference to the component responsible for rendering it. One could get an `IRenderedElement` instance for the root node and introspect/traverse the entire element tree at runtime.\n\nNote the `ref` attribute. This attribute allows you to pass an `ElementRef` instance to a TSX object. The rendered node will be inserted inside the given ElementRef. \n\n## ElementRef\n\nAn instance of this class can be passed through the ref attribute to capture rendered elements. It also has a `setAttribute()` method, which can be used to set attributes on all held elements at once, as well as to any new elements which might be rendered later on. Example of use:\n\n```tsx\ninterface ViewModel {\n  elementSize: number\n}\nexport class MySlotComponent extends Component<ViewModel> {\n elementsInSlot = new ElementRef();\n \n onCreate() {\n  // This will set the backgroundColor to orange for any elements\n  // which renders in our slot.\n  this.slotRef.setAttribute('backgroundColor', 'orange');\n }\n \n onRender() {\n  <view height={'100%'} alignItems='center'>\n    <slot ref={this.elementsInSlot} />;\n  </view>\n\n  // This will update the size of every elements in our slot\n  // based on a view model property\n  this.elementsInSlot.setAttribute('width', this.viewModel.elementSize);\n  this.elementsInSlot.setAttribute('height', this.viewModel.elementSize);\n }\n}\n```\n"
  },
  {
    "path": "docs/docs/advanced-full-stack.md",
    "content": "# Full stack Valdi\n\nValdi is often used to build cross-platform UI, achieving the same look-and-feel across Android and iOS, built from a common codebase and using advanced capabilities like Hot Reload. But client-side features are more than just their UI, requiring data and other services and APIs to build something useful.\n\nThis document outlines the two main models to building a Valdi feature end-to-end: A \"bridged\" approach, where data and services are provided via common APIs with per-platform implementations, and a \"full-stack\" approach, where a majority of feature code (including its data/service layer) are written almost purely in Valdi.\n\n\n\n## Bridged Architecture\n\nA \"bridged\" feature architecture is one in which its UI is built using cross-platform Valdi, while its data and services are provided via a \"bridge\" from Android and iOS. The bridge is a set of data objects and APIs defined using Valdi's [native annotations](./native-annotations.md), passed from Android/iOS to Valdi via a [Component Context](./native-context.md). Android/iOS implementations populate these data objects or implement these interfaces, and pass them in when [instantiating their Component](./native-bindings.md#using-the-context-most-common-recommended).\n\n![Diagram showing a bridged platform](./img/docs/arch-bridged.png)\n\n\n### When to use Bridging\nBridging is a good solution for features that have existing complex data and APIs in Android/iOS that power the UI experience. Additionally, sometimes a feature needs to make heavy use of OS-specific APIs, perhaps to access physical resources like Bluetooth or camera frames that aren't otherwise directly available in Valdi.\n\nIf the data and services are already available in Android/iOS, but with needs that aren't very complicated, consider adopting a [Full-Stack Valdi](#full-stack-valdi) architecture which will simplify ongoing development with key benefits discussed in detail below.\n\n### Shortcomings of Bridging\nA bridge-based approach for Valdi development has a few shortcomings. First and foremost, each bridged api must be implemented in each supported platform (eg Android/iOS). This adds development overhead, first by requiring more code be written in more languages, but also modifying this code requires each platform to be built entirely, instead of leveraging hot reload or, at worst, recompiling Valdi modules.\n\nAnother challenge with bridged APIs is that sometimes the platform-specific implementations are not the same. This forces a developer to write a \"least common denominator\" api, one that can be handled by each platform, or alternatively accept deviations across platforms. These least common denominator apis may incur performance penalties, for example bulk-loading a data set to create a common representation, which could otherwise be queried on-demand.\n\nLastly, while Valdi's bridging APIs are quite efficient, passing data from platform to Valdi will always incur some amount of overhead. Keeping data purely within Valdi can eliminate this concern.\n\n\n## Full-Stack Valdi\nFull-Stack Valdi is an alternative to a bridge-based feature architecture where the majority of a feature's data and services are built directly in Valdi. We'll outline how to build a scalable feature with a distinct data and UI layers, but the key patterns can work with other background services as well (perhaps processing video frames or running AI inference tasks). A full-stack architecture does not necessarily mean there is no platform-specific bridging, but that the majority of the feature is built purely within Valdi.\n\n!['Diagram of Full Stack architecture'](./img/docs/arch-fullstack.png)\n\nThere are a few key components that work together for a highly performant full-stack design:\n* [RxJs](https://rxjs.dev/) for reactive programming\n* [Worker Services](./advanced-worker-service.md) for running expensive computation on a background thread\n\n\n### Reactive Data for Reactive UI\n\nValdi's UI is designed to be _reactive_. This means that state changes in a component's data model automatically trigger re-renderings of the UI, which keep your UI up-to-date with its underlying state seamlessly. \n\nReactive UI works especially well with a [Unidirectional Data Flow](https://medium.com/@lizdenhup/understanding-unidirectional-data-flow-in-react-3e3524c09d8e) architecture powered by a reactive data store. Similar to reactive UI, a reactive data store automatically updates computed state whenever its underlying data changes. This is generally done by observing data changes and mapping those changes to the desired state.\n\n### Reactive Stores and Worker Threads\nValdi guarantees that all I/O operations (namely network calls and disk reads/writes) run asynchronously and will not block Typescript threads. As a result, a feature can be built with medium complexity while still running in one thread. But as the complexity grows, it's helpful to have a guarantee that data processing and other expensive non-UI operations cannot block UI operations.\n\nFor complex features built with Full-Stack Valdi, we leverage an additional property of our data store: multi-threaded observability. This means that changes to the data store can occur in one thread, while notifications of those changes and subsequent reads from the store may occur in another. This means we can issue our sql write transactions in a worker thread, and on our main thread we observe changes and read data via reactive queries.\n\n![Diagram of a worker and ui accessing a database](./img/docs/arch-worker.png)\n\nWe can set up a service to run as a worker thread as follows:\n```typescript\n\n  export interface IFriendStoriesDataSyncer {\n    sync(trigger: StoriesRequest.Trigger): Promise<MetaSyncToken>;\n  }\n\n  @workerService(WorkerServiceExecutors.CONTENT, module)\nexport class FriendStoriesDataSyncerWorker extends WorkerServiceEntryPoint<\n  IFriendStoriesDataSyncer,\n  [INetworkingClient, IContentRequestInfoProvider | undefined, INativeStoriesResponseProcessor]\n> {\n  start(\n    networkingClient: INetworkingClient,\n    contentRequestInfoProvider: IContentRequestInfoProvider | undefined,\n    nativeStoriesResponseProcessor: INativeStoriesResponseProcessor,\n  ): IWorkerService<IFriendStoriesDataSyncer> {\n    const service = new FriendStoriesDataSyncer(\n      networkingClient,\n      new ContentRequestInfoProvider(contentRequestInfoProvider),\n      nativeStoriesResponseProcessor,\n    );\n\n    return {\n      api: service,\n      dispose: () => {\n        service.dispose();\n      },\n    };\n  }\n}\n```\n\nWe can run this worker service from our feature's data layer:\n```typescript\n  private async useFriendStoryDataSyncer(\n    fn: (friendStoryDataSyncer: IFriendStoriesDataSyncer) => Promise<void>,\n  ): Promise<void> {\n    const worker: IWorkerServiceClient<IFriendStoriesDataSyncer> = useOrStartWorkerService(\n      FriendStoriesDataSyncerWorker,\n      [this.networkClient, this.contentRequestInfoProvider, this.nativeStoriesResponseProcessor],\n    );\n    try {\n      await fn(worker.api);\n    } finally {\n      worker.dispose();\n    }\n  }\n\n  async syncFriendStories(trigger: StoriesRequest.Trigger): Promise<void> {\n    await this.useFriendStoryDataSyncer(async friendStoryDataSyncer => {\n      try {\n        console.log(`${TAG}: syncing friend stories`);\n        await friendStoryDataSyncer.sync(trigger);\n      } catch (e) {\n        console.error(`${TAG}: failed to fetch friend stories. err: ${e}`);\n        throw e;\n      } finally {\n        runtime.performGC();\n      }\n    });\n  }\n```\n\nWhich can be called from our UI:\n```typescript\n  private onPullToRefresh = async (): Promise<void> => {\n    this.setState({ isLoading: true });\n    await this.contentDataService.syncFriendStories(StoriesRequest.Trigger.TRIGGER_PULL_TO_REFRESH);\n    this.resetScroll(false);\n  };\n````\n\n### Debugging Full-Stack Valdi\n\nValdi has a great local development experience for building UI, and these capabilities extend to Full-Stack Valdi as well.\n\nValdi's support for [tracing](./performance-tracing.md) works well with worker threads, giving visibility into the operations and their performance while iterating.\n\n"
  },
  {
    "path": "docs/docs/advanced-images.md",
    "content": "# Custom image loaders\n\nValdi supports loading and displaying `https` and `res` images by default with the `<image>` tag. If you need additional formats or custom image loading behavior, you can build a native custom image loader.\n\nYou will need a custom loader for each platform where you intend to load images.\n\n[iOS SCValdiImageLoader]: ../../valdi/src/valdi/ios/SCValdiDefaultImageLoader.m\n[Android ValdiImageLoader]: ../../valdi/src/java/com/snap/valdi/imageloading/DefaultValdiImageLoader.kt\n\nBefore you create your custom loader, take a look at the existing custom loaders to determine if your functionality has already been implemented: See [iOS][iOS SCValdiImageLoader] and [Android][Android ValdiImageLoader].\n\n## How custom loaders work\n\nThe `src` attribute specifies the target of an `<image>`. This is often thought of as a URL but it is just a string. Anything that can be encoded as a string can be used as a `src`: a URL, a b64 encoded blob of something, a db key.\n\nCustom loaders specify `supportedURLSchemes` these are not strictly URL schemes but again just strings. If the prefix of the specified `src` matches a custom loader's `supportedURLSchemes` then Valdi will use that loader to load that image.\n\n`supportedURLSchemes => returns ['my-image-loader']`\n\nMatches: `my-image-loader://url.shaped.thing` `my-image-loader://bG9sd3V0`\n\n`supportedURLSchemes` should be unique to your loader; if there are conflicting strings, the first one registered will be used.\n\nYour custom loader should live in a folder that you own, not Valdi's codebase.\n\n## iOS\n\nOn iOS, the loader must conform to the [`SCValdiImageLoader`](../../valdi_core/src/valdi_core/ios/valdi_core/SCValdiImageLoader.h) protocol and implement the following methods (including at least one of the optional methods):\n\n```objc\n\n/**\n Returns the URL schemes that this VideoLoader knows how to load.\n */\n- (NSArray<NSString*>*)supportedURLSchemes;\n\n/**\n Returns the request payload object which will be provided to the loadVideoWithRequestPayload:\n method for the given imageURL. The payload can be any Objective-C object. The payload might\n be cached internally by the framework.\n */\n- (id)requestPayloadWithURL:(NSURL*)imageURL error:(NSError**)error;\n\n@optional\n\n/**\n Load the image with the given request payload and call the completion when done.\n This method should only be implemented if this SCValdiImageLoader instance supports loading\n URLs into SCValdiImage instances.\n */\n- (id<SCValdiCancelable>)loadImageWithRequestPayload:(id)requestPayload\n                                             parameters:(SCValdiAssetRequestParameters)parameters\n                                             completion:(SCValdiImageLoaderCompletion)completion;\n\n/**\n Load the bytes with the given request payload and call the completion when done.\n This method should only be implemented if this SCValdiImageLoader instance supports loading\n URLs into raw bytes.\n */\n- (id<SCValdiCancelable>)loadBytesWithRequestPayload:(id)requestPayload\n                                             completion:(SCValdiImageLoaderBytesCompletion)completion;\n\n```\n\n> [!WARNING]\n> The returned implementation for `SCValdiCancelable` must be thread-safe as `cancel()` can be called on any thread.\n\n## Android\n\nThe loader must conform to [ValdiImageLoader](../../valdi/src/java/com/snap/valdi/utils/ValdiImageLoader.kt) and implement the following methods:\n\n```kotlin\n\n    /**\n    Returns the URL schemes supported by this ImageLoader\n     */\n    fun getSupportedURLSchemes(): List<String>\n\n    /**\n     * Returns a RequestPayload that will be provided to the load function of the implementation.\n     * The request payload might be cached by the runtime to avoid processing\n     * it again. This method can throw a ValdiException if Uri cannot be parsed.\n     */\n    @Throws(ValdiException::class)\n    fun getRequestPayload(url: Uri): Any\n\n    /**\n     * Returns the output types that this ValdiAssetLoader supports.\n     */\n    fun getSupportedOutputTypes(): Int\n\n    /**\n    Load the bitmap for the given URL and call the completion when done.\n     */\n    fun loadImage(requestPayload: Any,\n                  options: ValdiImageLoadOptions,\n                  completion: ValdiImageLoadCompletion): Disposable?\n\n```\n\nThe `getSupportedOutputTypes` method should return a list of [ValdiAssetLoadOutputTypes](../../valdi/src/java/com/snap/valdi/utils/ValdiAssetLoadOptions.kt#L3).\n"
  },
  {
    "path": "docs/docs/advanced-localization.md",
    "content": "# Localization\n\n## How to introduce new localizable strings?\n\n### 1. Create a strings file\nFirst, you need to declare your strings by creating a `strings-en.json` file in your module. For example:\n```json\n{\n  \"hello_world\": {\n    \"defaultMessage\": \"Hello, world!\"\n  },\n  \"here_missed_call\": {\n    \"defaultMessage\": \"{person} tried to call you\",\n    \"example\": \"Bob tried to call you\"\n  },\n  \"minutes_ago\": {\n    \"defaultMessage\": \"{minutes%d} minutes ago\",\n    \"example\": \"42 minutes ago\"\n  },\n  \"person_gave_a_gift_to_person\": {\n    \"defaultMessage\": \"{friend1} gave {friend2} a gift. How nice!\",\n    \"example\": \"Alice gave Bob a gift. How nice!\"\n  },\n}\n```\n\nEach entry within the `strings-en.json` file has a unique key and must be lower camelCased (or snake_cased, though we're likely to migrate from that for easier greppability).\n* `defaultMessage`: Required. The base language (en) value for the key.\n* `example`: Optional. An example string used to help translate the message.\n\nMessages can contain uniquely named placeholders. By default, a placeholder is of type `string` but you may add `sprintf` style formatting such as `%s` and `%d` as a suffix to your named placeholder.\n\n### 2. Add the strings directory to your module.yaml\n```yaml\n# Where to find your strings directory\nstrings_dir: strings\n```\n\n### 3. Generate `Strings.d.ts`\n\nRun `valdi projectsync` to generate/update `Strings.d.ts` file for your module.\n\n### 4. Use strings from TypeScript code:\n\nGenerated strings can be used directly in TypeScript code, e.g.:\n\n```tsx\nimport Strings from 'mymodule/src/Strings';\n\n// ...\n\nonRender() {\n  <view>\n    <label value={ Strings.helloWorld() }/>\n  </view>\n}\n\n// ...\n```\nNote that the `Strings` module exported property names are camelCased based on the snake_case localizable key provided in `strings.yaml`. E.g. in the above example the snake_case `hello_world` string is referred to using camelCase `helloWorld`.\n\n### 5. Use strings from Kotlin code:\n\nGenerated strings can be used directly in Kotlin code as normal android resouces:\n\n```kt\nval helloWorld = getResources().getString(com.snap.valdi.modules.valdi_example.R.string.valdi_example_hello_world)\n```\n\n### 6. That's it!\n\nValdi tooling processes the input strings .json files for both the Base (English) localization and the translations. The tooling generates .strings files for iOS and strings .xml files for Android, which are included in the published Valdi modules artifacts.\n\n> [!Note]\n> The Valdi compiler automatically generates a TypeScript file exposing individual localizable strings, similar to the Asset Catalog. This ensures that using localized strings in TypeScript is type-safe and enables autocompletion in your IDE.\n\n\n## Template Strings\n\nIn many instances, developers may require the utilization of strings that incorporate variables or placeholders - such as `\"[5 unread notifications]\"`. Normally in English, we could easily implement this via `numNotifications + \" unread notifications\"`. However, localization challenges arise with variations in languages, and spacing, ordering, and punctuation can all be different. For [5 unread notifications], the Korean translation is [읽지 않은 알림 5개]; simply `numNotifications + {localizedString}` would not suffice.\n\nAs such, we strongly recommend that no localized strings are constructed in code. Using longer strings allow our translations have the full context for each sentence, and we should not be worried about duplicate words and phrases as they are easily compressible. Instead, we can use variable interpolation into variables within template strings, so that they can be natually localized.\n\nThe variables have the following format: `{NAME%FORMAT}`.\n\nThese can be used as follows:\n```tsx\n// strings-en.json:\n\"notification_count\": {\n  \"defaultMessage\": \"{num%d} unread notifications\",\n  \"example\": \"5 unread notifications\",\n}\n\n// calling code\nconst notificationCount = 5;\nconst localizedString = Strings.unreadNotifications(notificationCount);\n\n// result - \"5 unread notifications\"\n```\n\nFormats that are currently accepted are:\n- `%s` - the default format, the raw string is used\n- `%d` - integer format\n\nWhen multiple variables are used, they must be uniquely named. The ordering in the English (default) locale will be used to align passed in variables to variable names, and they will be matched to the correct position in localized strings. \n"
  },
  {
    "path": "docs/docs/advanced-native-references.md",
    "content": "# Native References\n\n## Introduction\n\nValdi allows you to pass callbacks and objects from platform (iOS/Android) to TypeScript and vice versa. The runtime maintains a mapping between those references, so that calling a TypeScript function that is backed by an Objective-C method ends up calling the underlying Objective-C method, and so that calling an Objective-C method or block that is backed by a TypeScript function ends up calling the underlying TypeScript function. The runtime automatically creates the references during the lifetime of your TypeScript component as it interacts with the platform bindings.\n\nA C++, Objective-C or Kotlin object or function exposed to TypeScript is called a `Native Reference` within the runtime. A TypeScript function exposed to C++, Objective-C or Kotlin is called a `JS Value Reference`.\n\n## Example\n\nHere is a scenario where two kind of references would end up being created by the runtime:\n```ts\n\n// @ViewModel\n// @ExportModel\ninterface ViewModel {\n  fetchUserIds(cb: (userIds: string[]) => void): void;\n}\n\n// @ExportModel\nexport class MyComponent extends Component<ViewModel> {\n\n  onCreate() {\n    // By the time onCreate() is called, we have our view model provided\n    // by platform. The ViewModel contains a callback called \"fetchUserIds\".\n    // If the component was created from Kotlin, the \"fetchUserIds\" callback\n    // inside the view model would be a reference to a Kotlin Function.\n    const fetchUserIds = this.viewModel.fetchUserIds;\n\n    // the \"fetchUserIds\" takes a callback as its parameter. If we call it from\n    // TypeScript, we will pass it an arrow function. The runtime will create\n    // a reference to the arrow function and put it inside a Kotlin Function.\n    fetchUserIds((userIds) => {\n\n    });\n  }\n\n}\n```\n\nThe example above shows that when the component is created, it already has one `Native Reference` alive since the view model is natively generated and has a `fetchUserIds` function provided by platform. The `fetchUserIds` function takes a callback as its parameter, so when TypeScript calls it and provides a callback, the runtime creates a new `JS Value Reference` between TypeScript to platform to expose the TypeScript callback to platform.\n\n## Lifecycle of references\n\nThe native and JS value references stay alive until either the receiving platform garbage collects the platform representation of the reference, or until the root component is destroyed.\n\nFor example, if `fetchUserIds` is implemented by Kotlin and that TypeScript calls that function and passes it a callback, on the Kotlin side the `fetchUserIds` will see the callback as a Kotlin Function object. Whenever the Kotlin Function object is garbage collected by the JVM, the `JS Value Reference` holding the TypeScript callback will be removed. If `fetchUserIds` is implemented by Objective-C, the callback for its parameter would be exposed as an Objective-C block, and the `JS Value Reference` for the callback would be removed as soon as Objective-C stops referencing the Objective-C block. The runtime tries to eliminate the emitted references as soon as it knows for sure that they are unused, to reduce memory usage during the lifetime of the component.\n\nIn order to reduce memory usage earlier whenever a root component is destroyed, the runtime also eagerly removes all the emitted references for that component. There could still be at that time some C++, Kotlin or Objective-C code that hold onto some TypeScript callbacks that were associated with the component. If C++, Kotlin or Objective-C calls into those disposed TypeScript callbacks, the runtime will emit a runtime error to notify about the issue.\n\n## Debugging reference errors\n\nAs seen earlier in the `Lifecycle of references` section, references get eagerly disposed whenever the root component is destroyed, which could cause C++, Kotlin or Objective-C to hold into disposed `JS Value References`. When the runtime emits a reference, it also stores some debug information to help understanding what the reference is. The debug information gets shown in the runtime error message whenever something attempted to unwrap that disposed reference, which could happen if C++, Kotlin or Objective-C attempted to call a TypeScript function which was disposed. The debug information contains up to two string identifiers and up to 4 property chains. In the example from the `Example` section, the `fetchUserIds` callback would have a debug information like so:\n```\ncontext.fetchUserIds()\n```\nWhen TypeScript calls the `fetchUserIds` function and passes it a callback, the `JS Value Reference` emitted would have the following debug information:\n```\ncontext.fetchUserIds() -> <parameter 0>()\n```\nTo make it human readable, we would read it from right to left. This could be read as `The reference is a callback which was the first parameter given to the context.fetchUserIds function`. If the `context.fetchUserIds` implementation was calling the TypeScript callback after the root component was destroyed, the error would look like:\n```\nCannot unwrap JS value reference 'context.fetchUserIds() -> <parameter 0>()' as it was disposed\n```\nThe fix to this issue could be to ensure that the `fetchUserIds` implementation does not call any given callback after the root component is destroyed. In Kotlin, this could be done by having the `fetchUserIds` implementation leverages some kind of disposable that would be disposed right before `rootView.destroy()` is called.\n\nHere is an example of a more complex debug information error:\n```\nmakeInterruptibleCallback -> <parameter 0>().getSamples() -> <parameter 1>()'\n```\nThis could be read as `The reference is a function and the second parameter given to a call to getSamples(), which is a property of the first parameter given to makeInterruptibleCallback`\n\n## Extending reference lifeycle\n\n**If** your component needs to have some code that interacts with some bindings and absolutely needs to run even after the root component is is destroyed, you can temporarily extend the lifecycle of the references by calling `protectNativeRefs` from the `NativeReferences` module. The function returns a dispose callback which should be called once you no longer need the refs to be protected. Calling that function will prevent the references to be disposed until the returned value from  `protectNativeRefs` has been called. Here is an example of usage:\n```ts\nimport { protectNativeRefs } from 'valdi_core/src/NativeReferences';\n\ninterface Context {\n  userPreferences: UserPreferences;\n  networkManager: NetworkManager;\n}\n\nexport class MyComponent extends Component<{}, Context> {\n\n  onDestroy() {\n    this.doSave();\n  }\n\n  async doSave(): Promise<void> {\n    // We need to be able to interact with our bindings for a bit longer after\n    // we are destroyed, so we protect the native refs here\n    const disposable = protectNativeRefs(this);\n    try {\n      const preferences = await this.context.userPreferences.save();\n      await this.context.networkManager.saveUserPreferences(preferences);\n    } finally {\n      // We are done with our async calls, we can safely release the native refs\n      disposable();\n    }\n  }\n}\n```\n\nIn this example, our component needs to interact asynchronously with some bindings in `onDestroy`. If we did not call `protectNativeRefs`, any callback/promise passed from TypeScript to the bindings would be not callable by the bindings after `onDestroy()` had finished executing. The first `await this.context.userPreferences.save()` would result in a `Cannot unwrap JS value reference` error as soon as the bindings implementation would call the callback. `protectNativeRefs` temporarily prevents the references to be eagerly destroyed while the `doSave()` asynchronous procedure is being done.\n\nPlease note that `protectNativeRefs` is inherently a bit of a dangerous API: you need to make sure that you call the returned disposable at some point otherwise the native references will leak, and you need to make sure the bindings will end up calling any callbacks your TypeScript code expects so that the disposable ends up being called. In the example above, if the promise returned by `this.context.userPreferences.save()` never got resolved by the `UserPreferences`, the `finally` block will never be reached so the disposable will never be called. As such, we recommend you only use this API if you absolutely need to perform a chain of asynchronous operations when your component is destroyed, similar to how an iOS developer might use Apple's `-[UIApplication beginBackgroundTaskWithExpirationHandler:]` API to perform a bit of work after an application is closed by the user.\n"
  },
  {
    "path": "docs/docs/advanced-protobuf.md",
    "content": "## Protobuf\n\nProtobuf is a message serialization library written by Google and is widely used at Snap. Valdi has a complete integration of Protobuf provided as a built-in module. It leverages the Protobuf C++ library to perform most operations, and exposes type safe TypeScript APIs which are generated from a Protobuf definition file (`.proto`).\n\n> [!Note]\n> The Valdi runtime provides built-in support for Protobuf serialization. This allows TypeScript components to efficiently serialize and deserialize structured data for network requests, disk storage, and cross-language communication.\n\n### Protobuf config file\n\nThe Valdi Protobuf generation script can take a `proto_config.yaml` and generate API definitions for the messages which the config file includes. This file needs to be added inside the root of a Valdi module directory, same location where the `module.yaml` lives.\n\nThe proto config file lists all the proto files which should be included from one of the repositories declared in the `repositories` section, or from files that are in the `proto` directory.\n\n### Generating message APIs\nOnce the `proto_config.yaml` was setup in the module, we can generate the TypeScript bindings by running the `scripts/generate_protos.py` script (Pls. run  `tools/build_pre.sh` once from the client root directory to fetch all necessary prerequirements for `generate_protos` script). We provide it the Valdi module name where the `proto_config.yaml` is stored.\n```bash\n# Typical Valdi development path\ncd ~/Path/to/repo/src/valdi_modules\n# Generate protos\n./scripts/generate_protos.py --module my_module\n```\nThis will parse the `proto_config.yaml` file, resolve all the protobuf messages from the repositories declared in the `proto_config.yaml` files as well as files within `<module>/proto` and generate a TypeScript definition file as well as a binary which will be used to allow the Protobuf C++ library to parse the new message.\n\nIf you have not installed Protobuf on your machine, you can use Homebrew to install it:\n```\nbrew install protobuf\n```\nor in Linux\n```\napt install -y protobuf-compiler\n```\n\nAfter running `generate_protos.py`, the file structure from `my_module` will then look like this:\n```\nmodule.yaml\nproto_config.yaml\nsrc/proto.d.ts\nsrc/proto.js\nsrc/proto.protodecl\n```\n\n- `proto.d.ts` contains the TypeScript definitions for tall the messages.\n- `proto.js` contains instructions to lazily load the messages implementation whenever `proto` is imported.\n- `proto.protodecl` is a binary file containing the message definitions that the Protobuf C++ will be able to read.\n\nMessages are exposed in namespaces to avoid conflicts. The namespace is based off the package name in protobuf.\n\n## Using generated messages in TypeScript\n\n### Setting up valdi_protobuf dependency\n\nThe generated messages will try to import utility classes from the `valdi_protobuf` module. We need to make sure we add a dependency to it in our `module.yaml`:\n```\n- dependencies:\n  - valdi_core\n  - valdi_protobuf\n```\n\n### Decoding a message\n\nMessages can be decoded from a `Uint8Array` instance. We can decode a message by importing the Protobuf package from our `proto.d.ts` and calling `decode()` on the Message type we want to deserialize\n```ts\nimport { snapchat } from './proto';\nimport { Arena } from 'valdi_protobuf/src/Arena';\n\nconst bytes: UInt8Array = getBytesFromSomewhere();\nconst story = snapchat.Story.decode(new Arena(), bytes);\n// We can now use our decoded Story object!\n```\n\n### Encoding a message\n\nMessages can be encoded in two ways: either by calling `MessageType.encode()` and passing a JavaScript object representing the message properties, or by calling `encode()` on a message instance which was previously created or decoded.\n\n```ts\nimport { snapchat } from './proto';\nimport { Arena } from 'valdi_protobuf/src/Arena';\n\n// Option 1\nconst storyBytes = snapchat.Story.encode({storyId: '42', user: {userId: '84', displayName: 'Bob'}});\n\n// Option 2\nconst story = getStoryMessageObjectFromSomewhere();\nconst storyBytes = story.encode();\n```\n\nYou can therefore easily decode an object, modify it and re-encode it:\n```ts\nconst bytes: UInt8Array = getBytesFromSomewhere();\n// Decode our Story message\nconst story = snapchat.Story.decode(new Arena(), bytes);\n// Modify one of the field\nstory.storyId = '84';\n// Encode the result\nconst newBytes = story.encode();\n```\n\nYou can also create a Message instance from a JavaScript object if you absolutely need the Protobuf message representation before going into bytes:\n```ts\nconst story = snapchat.Story.create(new Arena(), {storyId: '42', user: {userId: '84', displayName: 'Bob'}});\n```\n\n### Arena\n\nSome of the message APIs, like `decode()` and `create()` take an `Arena` instance as their first parameter. The `Arena` is what holds all the native allocations for the Protobuf messages. Whenever setting a protobuf message instance into another protobuf message instance, the runtime will have to make a deep copy if both messages are not from the same `Arena` which can be expensive.\nFor instance:\n```ts\nconst story = snapchat.Story.create(new Arena(), {storyId: '42'});\nconst user = snapchat.User.create(new Arena(), {userId: '84', displayName: 'Bob'});\n// This will force the runtime to copy the User message inside Story, since the User message is from a different Arena than Story\nstory.user = user;\n```\n\nWe can easily fix this as follow:\n```ts\nconst arena = new Arena();\nconst story = snapchat.Story.create(arena, {storyId: '42'});\nconst user = snapchat.User.create(arena, {userId: '84', displayName: 'Bob'});\n// No copies will happen, the User message is from the same Arena as Story.\nstory.user = user;\n```\nNote that this can also be written as follow:\n```ts\nconst story = snapchat.Story.create(new Arena(), {storyId: '42', user: {userId: '84', displayName: 'Bob'}});\n// We created a Story object with a User object inside in this single call. The objects will be from the same Arena.\n```\n\nIdeally you should use a single `Arena` instance when creating a complete Message tree. For instance, when serializing a request to a server, you'd use a dedicated Arena instance for representing the whole request.\n`Arena` objects are designed to be used an thrown away. Don't re-use them as they will keep growing in memory.\n"
  },
  {
    "path": "docs/docs/advanced-provider.md",
    "content": "# Provider\n\n## Introduction\n\nProvider API provides a way to pass dependencies from parent component to children without manually declaring them\nat each level of component tree.\n\nThis API is very similar to [React Context](https://reactjs.org/docs/context.html) and others examples like:\n - [Flutter Provider](https://pub.dev/documentation/provider)\n - [Swift Environment Object](https://developer.apple.com/documentation/swiftui/environmentobject)\n - [Android Composition Local](https://developer.android.com/jetpack/compose/compositionlocal)\n\nThis API should be useful when you need to pass the instance of your service or any other readonly data into components tree.\n\nYou may notice that this API has similarity with Valdi Component Context. \n\nProvider doesn't have any platform related logic and focused on work in TypeScript platform only.\n\n>[!NOTE]\n>This API could not be helpful for passing data which you plan to change frequently in the application.\n>\n> View Model mechanism still should be a source of truth for such updates. \n>\n> Provider API is designed for provide an ability to build share mechanism for sharing data, not store data itself.\n\n\n### Using Provider API\nFor example, we have `MyService` and we would like to pass it through the components tree\n```typescript jsx\nclass MyService {\n  public sayHello() {\n    return 'sayHello';\n  }\n}\n```\n\nTo create a new Provider you need to call `createProviderComponent` with a unique provider name and specify the type of needed dependency using the generic type parameter.\n\n```typescript jsx\nconst MyServiceProvider = createProviderComponentWithKeyName<MyService>('MyServiceProvider');\n```\n\n`createProviderComponent` returns a special Provider component which you can use within your component tree. \nWhen you use the returned Provider component, you need to pass the initial `value` that it exposes to any component within its subtree of the component tree. The type of `value` has to be compatible with the type you specified when calling `createProviderComponent`.\n\n```typescript jsx\nclass AppRoot extends Component {\n    private readonly myService = new MyService(); // the service could also have been injected by the native component context\n\n    onRender(): void {\n        <MyServiceProvider value={this.myService}>\n            <App />\n        </MyServiceProvider>;\n    }\n}\n```\n\n>[!NOTE]\n> If you decide to change the value of your Provider, it will trigger a rerender for all of the children that you have inside Provider Component.\n>\n>In our example it will be `<App />`.\n\n\nAfter initialization step you can consume `Provider.value` in any place under the `MyServiceProvider` component tree.\n\nTo get the instance of our `MyService` somewhere in children we need at first \nto extend an original view model of children component from `ProvidersValuesViewModel` interface.\n\n```typescript jsx\ninterface MyConsumerComponentViewModel extends ProvidersValuesViewModel<[MyService]> {\n    myUnrelatedOtherProperty: boolean;\n}\n```\n\nIn this example we're planning to add the Provider value to an existing component which\nalready has a view model property `myUnrelatedOtherProperty: boolean`;\n\nAfter extending component view model, we can consume provider values from the view model. \n`ProvidersValuesViewModel` interface adds a special property which is called `providersValues`\nand contains an array of all resolved providers values from parent providers.\n\n```typescript jsx\nclass MyConsumerComponent extends Component<MyConsumerComponentViewModel> {\n    onRender() {\n        const [myService] = this.viewModel.providersValues;\n        <label value={myService.sayHello()} />;\n    }\n}\n```\n\nIn our example we expect to consume only `MyServiceProvider`. \nTo learn how to consume multiple providers, please read below. \n\nThe last step to make this example work we need to define which Provider and component \nwe would like to use. For this step we need to use `withProviders` function. We need to pass \ninto this function the Provider component which we created before at step one. \n\n```typescript jsx\nconst createComponentWithMyServiceProvider = withProviders(MyServiceProvider)\n```\n\n`withProviders` function returns a function which allows you to inject the providers values\ninto your component without modification. \n\n```typescript jsx\nconst MyConsumerComponentWithMyService = createComponentWithMyServiceProvider(MyConsumerComponent)\n```\n\nThis pattern is called [Higher Order Component](https://blog.jakoblind.no/simple-explanation-of-higher-order-components-hoc/) which can be familiar for web devs. \n\nTo simplify our last steps we can do the following which more nature\n```typescript jsx\nconst MyNewComponent = withProviders(\n    MyServiceProvider\n)(MyConsumerComponent);\n```\n\nand then finally we can use our new component with injected dependency in the app\n\n```typescript jsx\nclass App extends Component {\n    onRender(): void {\n        <view>\n            <MyNewComponent myUnrelatedOtherProperty={true} />\n        </view>;\n    }\n}\n```\n\nAs you may notice the `<App />` component doesn't know anything about `MyService` which this is the key point of usage Provider API.\n\nIn this case intermediate components don't know about needed dependencies, and they can be passed implicitly.\n\nIf you need to consumer several providers, you can use the same API.\n\n```typescript jsx\nconst MyConsumerComponentWithProviderValue = withProviders(\n    Provider1,\n    Provider2,\n    Provider3\n)(MyConsumerComponent);\n```\n\nAs a result, you can get all resolved values the same view model from array `providersValues`.\nPlease note, that this array is strong typed and used typescript feature which is called a [tuple](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types).\n\n```typescript jsx\nclass MyConsumerComponent extends Component<MyConsumerComponentViewModel> {\n    onRender() {\n        // \n        const [providerValue1, providerValue2, providerValue3] = this.viewModel.providersValues;\n        ...\n    }\n}\n```\n\nThe full implementation can be viewed [here](../../src/valdi_modules/src/valdi/valdi_core/src/provider).\n"
  },
  {
    "path": "docs/docs/advanced-worker-service.md",
    "content": "# Worker Service\n\n### Introduction\n\nCompiled TypeScript code runs in a JavaScript Virtual Machine using a single threaded event loop.\n\nExpensive operations, like IO and parsing, are typically implemented by native code and run in a separate background thread, exposed to TypeScript as promise or callback based APIs. This allows for a fairly high level of concurrency even if the TypeScript code itself is single threaded.\n\nSometimes, that single thread might not be enough if there are some inherently expensive operations that are written in TypeScript which might compete with the Valdi components rendering the UI. To solve this problem, you can move parts or all of your business logic as a Worker Service, which will run in a background thread.\n\n### Design\n\nA Worker Service is a service that is started and registered from the TypeScript Main thread, but executes in a separate TypeScript Worker thread.\n\nThroughout this page, we will refer to the code running in the TypeScript Main thread as the `host`, and the code running in the TypeScript Worker Thread as the `worker`.\n\nThe service exposes a promise based API, which can be used from the host. All the calls from host to the worker and vice versa are asynchronous. The service can be provided a set of dependencies. Each created service needs to be disposed at some point by calling the `dispose()` method from the host.\n\nThe service that executes in the worker uses an entirely separate memory heap than the host, passing objects from the host to the worker and vice versa will thus make the runtime to create a deep copy of those objects. There is therefore a cost to using a worker, and one must design their api carefully to limit \"chattiness\" between host and worker.\n\nA Worker Service is declared with an entry point, which is a subclass of the `WorkerServiceEntryPoint` abstract class annotated with the `@workerService(module)` annotation. The entry point is responsible for creating the service and exposing its API by overriding the method `start()`, which will be called with the initialization arguments when the host requests to create the service. The returned object from the `start()` method will contain an `api` object, as well as a `dispose()` implementation which will be called when the service is requested to be torn down.\n\nThe host can start a worker service by using the `startWorkerService()` method, and pass as an argument the `WorkerServiceEntryPoint` subclass, as well as a tuple representing the initialization arguments, which will be forwarded to the `start()` method in the worker. The method returns a `IWorkerServiceClient` instance, containing the `api` that the worker service exposes so that the host can interact with the worker, a `serviceId` which uniquely identifies the service instance, and a `dispose()` method which should be called when the worker service is no longer needed. Failure to call `dispose()` will result in the service staying in memory forever.\n\n### Usage\n\n#### Declaration\n\nTo declare a worker service, one must first write a TypeScript interface representing its API. The API can contain any number of methods, but each method must return a promise, even if the result is void (in which case it'd return `Promise<void>`). Here is an example for a calculator:\n\n```typescript\nexport interface ICalculator {\n  value(): Promise<number>;\n\n  add(value: number): Promise<void>;\n  sub(value: number): Promise<void>;\n  mul(value: number): Promise<void>;\n  div(value: number): Promise<void>;\n}\n```\n\nWe then need an implementation for this interface, which will run in the worker. Here is an example:\n```typescript\nclass CalculatorImpl implements ICalculator {\n  private currentValue: number;\n\n  constructor(initialValue: number) {\n    this.currentValue = initialValue;\n  }\n\n  async add(value: number): Promise<void> {\n    this.currentValue += value;\n  }\n\n  async sub(value: number): Promise<void> {\n    this.currentValue -= value;\n  }\n\n  async mul(value: number): Promise<void> {\n    this.currentValue *= value;\n  }\n\n  async div(value: number): Promise<void> {\n    if (value === 0) {\n      throw new Error('Division by zero is not allowed');\n    }\n\n    this.currentValue /= value;\n  }\n\n  async value(): Promise<number> {\n    return this.currentValue;\n  }\n}\n```\n\nLastly, we need to declare an entry point for this service by declaring a `WorkerServiceEntryPoint` subclass annotated with the `@workerService(module)` annotation:\n```typescript\n@workerService(module)\nexport class CalculatorServiceEntryPoint extends WorkerServiceEntryPoint<ICalculator, [number]> {\n  start(startingValue: number): IWorkerService<ICalculator> {\n    return {\n      api: new CalculatorImpl(startingValue),\n      dispose() {},\n    };\n  }\n}\n```\n\nThe first generic argument of `WorkerServiceEntryPoint` is the API type exposed, the second argument is a tuple representing the initialization arguments which will be passed to the `start()` method. An empty tuple can be used if starting the worker service requires no dependencies. In the example above, we pass a single dependency representing the `startingValue` of our calculator implementation.\n\n#### Integration\n\nTo start using the worker service, we use the `startWorkerService()` to create it, which asynchronously creates the worker service in the worker, and synchromnously returns a client to that worker in the host. The host can immediately interact with the worker service through the `api` property. Once the host is done with the worker, the host should call `dispose()` on the client object.\n\nHere is an example:\n```typescript\n// Start the worker service for our calculator, passing an initial value of 0\nconst client: IWorkerServiceClient<ICalculator> = startWorkerService(CalculatorServiceEntryPoint, [0]);\n\ntry {\n  // Interact with the created worker service\n  await client.api.add(2);\n  await client.api.mul(3);\n  await client.api.sub(1);\n  await client.api.div(2);\n  const result = await client.api.value();\n\n  expect(result).toBe(2.5);\n} finally {\n  // Dispose the service when we're done\n  client.dispose();\n}\n```\n\nNote that in a real life situation, it is far more likely that a worker service would have a much longer lifecycle than the example shown above. A more typical integration might start the worker service from a root Valdi component and tear it down when the root component is destroyed.\n\n### Limitations\n\nAs already mentioned, the worker uses a completely separate heap from the host, and objects are therefore copied.\n\nWhen the host passes a function to the worker, that function is bridged, and a call to that function from the worker will be made asynchronously. As such, bridged TypeScript functions cannot return values synchronously. \n\nWe recommend that you avoid passing TypeScript functions in general between host to worker and vice versa. You can however safely pass instances of `@ExportProxy` that are implemented by native Objective-C, Kotlin/Java or C++ code.\n\nWhen passing an instance of a TypeScript class, only the own properties of the object will be copied, so methods implemented by the class won't be passed in. For example:\n```typescript\nclass User {\n  constructor(readonly firstName: string, readonly lastName: string) {}\n\n  getName(): string {\n      return `${this.firstName} ${this.lastName}`;\n  }\n}\n```\nIf the host or worker passes an instance of `new User('John', 'Smith')`, the receiving side will get a plain object like:\n```typescript\n{\n    firstName: 'John',\n    lastName: 'Smith'\n}\n```\nThe `getName()` method won't be exported because it is not an own property of the `User` instance, and even if it were exported, calling it would not work as intended as the call would be made asynchronously, whereas the method expects to return a string synchronously.\n\nLastly, please note that by default, worker services run in a single shared thread. As such, code running in a worker service should avoid using the thread for too long and avoid processing unbounded tasks, as it will prevent other worker services to work properly.\n"
  },
  {
    "path": "docs/docs/ai-tooling.md",
    "content": "# Working with AI Assistants\n\nThis guide helps developers use AI coding assistants effectively with Valdi.\n\n## 🚨 Critical: Valdi is NOT React\n\nThe most important thing to know when using AI assistants with Valdi: **despite using TSX/JSX syntax, Valdi is fundamentally different from React**.\n\nAI models are heavily trained on React and will often suggest React patterns that **don't exist in Valdi**. This guide will help you recognize and correct these suggestions.\n\n## Common AI Hallucinations\n\n### 1. useState Hook (Doesn't Exist)\n\n**AI might suggest:**\n```typescript\n// ❌ WRONG - useState doesn't exist in Valdi\nconst [count, setCount] = useState(0);\n```\n\n**Correct Valdi pattern:**\n```typescript\n// ✅ CORRECT - Use StatefulComponent with setState()\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\nclass Counter extends StatefulComponent<ViewModel, State> {\n  state = { count: 0 };\n  \n  incrementCount() {\n    this.setState({ count: this.state.count + 1 }); // setState auto re-renders\n  }\n  \n  onRender() {\n    <button \n      title={`Count: ${this.state.count}`}\n      onPress={this.incrementCount}\n    />;\n  }\n}\n```\n\n### 2. useEffect Hook (Doesn't Exist)\n\n**AI might suggest:**\n```typescript\n// ❌ WRONG - useEffect doesn't exist in Valdi\nuseEffect(() => {\n  fetchData();\n}, []);\n```\n\n**Correct Valdi pattern:**\n```typescript\n// ✅ CORRECT - Use lifecycle methods\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\nclass DataComponent extends StatefulComponent<ViewModel, State> {\n  state = { data: null };\n  \n  onCreate() {\n    this.fetchData();\n  }\n  \n  onViewModelUpdate(prevViewModel: ViewModel) {\n    if (this.viewModel.id !== prevViewModel.id) {\n      this.fetchData();\n    }\n  }\n  \n  async fetchData() {\n    const data = await fetch(...);\n    this.setState({ data });\n  }\n}\n```\n\n### 3. Functional Components (Don't Exist)\n\n**AI might suggest:**\n```typescript\n// ❌ WRONG - Functional components don't exist in Valdi\nconst Button = ({ title, onPress }) => {\n  return <button title={title} onPress={onPress} />;\n};\n```\n\n**Correct Valdi pattern:**\n```typescript\n// ✅ CORRECT - Use class-based components\nimport { Component } from 'valdi_core/src/Component';\n\ninterface ButtonViewModel {\n  title: string;\n  onPress: () => void;\n}\n\nclass Button extends Component<ButtonViewModel> {\n  onRender() {\n    <button \n      title={this.viewModel.title} \n      onPress={this.viewModel.onPress} \n    />;\n  }\n}\n```\n\n### 4. Returning JSX from onRender()\n\n**AI might suggest:**\n```typescript\n// ❌ WRONG - onRender returns void, not JSX\nclass MyComponent extends Component {\n  onRender() {\n    return <view />; // Compiler error!\n  }\n}\n```\n\n**Correct Valdi pattern:**\n```typescript\n// ✅ CORRECT - JSX is a statement, onRender returns void\nclass MyComponent extends Component {\n  onRender() {\n    <view />; // No return statement\n  }\n}\n```\n\n### 5. useContext Hook (Doesn't Exist)\n\n**AI might suggest:**\n```typescript\n// ❌ WRONG - useContext doesn't exist in Valdi\nconst theme = useContext(ThemeContext);\n```\n\n**Correct Valdi pattern:**\n```typescript\n// ✅ CORRECT - Use Provider pattern with HOC\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nimport { withProviders } from 'valdi_core/src/provider/withProviders';\nimport { ProvidersValuesViewModel } from 'valdi_core/src/provider/withProviders';\nimport { Component } from 'valdi_core/src/Component';\n\n// Define theme service\nclass Theme {\n  primary = '#FFFC00';\n}\n\n// Create provider\nconst ThemeProvider = createProviderComponentWithKeyName<Theme>('ThemeProvider');\n\n// Provide value\nclass AppRoot extends Component {\n  private theme = new Theme();\n  \n  onRender() {\n    <ThemeProvider value={this.theme}>\n      <ThemedComponentWithProvider />\n    </ThemeProvider>;\n  }\n}\n\n// Consume with HOC\ninterface ThemedViewModel extends ProvidersValuesViewModel<[Theme]> {}\n\nclass ThemedComponent extends Component<ThemedViewModel> {\n  onRender() {\n    const [theme] = this.viewModel.providersValues;\n    <view backgroundColor={theme.primary} />;\n  }\n}\n\nconst ThemedComponentWithProvider = withProviders(ThemeProvider)(ThemedComponent);\n```\n\n## How to Prompt AI Assistants\n\n### Good Prompts\n\nWhen asking AI for help, be explicit that you're using Valdi:\n\n✅ \"In Valdi (not React), how do I add state to a component?\"  \n✅ \"Using Valdi's class-based component model, how do I fetch data on mount?\"  \n✅ \"How do I trigger a re-render in Valdi after updating state?\"\n\n### Prompts to Avoid\n\n❌ \"How do I add a counter?\" (AI will assume React)  \n❌ \"Create a functional component\" (Doesn't exist in Valdi)  \n❌ \"Use hooks to manage state\" (Hooks don't exist in Valdi)\n\n## Quick Reference: React vs Valdi\n\n| Concept | React Pattern | Valdi Pattern |\n|---------|---------------|---------------|\n| **Component** | `const C = () => {}` | `class C extends StatefulComponent {}` |\n| **State** | `useState(0)` | `state = { count: 0 }` |\n| **Update State** | `setCount(1)` | `this.setState({ count: 1 })` |\n| **Props** | `props.title` | `this.viewModel.title` |\n| **Mount effect** | `useEffect(() => {}, [])` | `onCreate() {}` |\n| **Update effect** | `useEffect(() => {}, [dep])` | `onViewModelUpdate(prev) {}` |\n| **Unmount effect** | `useEffect(() => () => {}, [])` | `onDestroy() {}` |\n| **Context** | `useContext(Ctx)` | `withProviders(Provider)(Component) + this.viewModel.providersValues` |\n| **Render** | `return <view />` | `<view />; // statement, returns void` |\n\n## Setting Up AI Tools\n\n### Quick Setup with `valdi skills`\n\nThe fastest way to configure any AI tool for Valdi development is the `valdi skills` command. It installs Valdi-specific context files (bundled in the npm package) into whichever AI tools you have:\n\n```sh\n# Auto-detects Claude Code, Cursor, and Copilot — installs all skills for each\nvaldi skills install\n\n# See what's available and what's already installed\nvaldi skills list\n\n# Keep skills up to date\nvaldi skills update\n```\n\nSkills cover TSX patterns, Bazel, iOS/Android integration, async lifecycle, performance, testing, and more. See [ai-skills/CONTRIBUTING_SKILLS.md](../../ai-skills/CONTRIBUTING_SKILLS.md) to contribute a new skill.\n\n### Cursor\n\nUse `valdi skills install --for=cursor` to install skills to `~/.cursor/rules/`. Skills activate automatically based on file type when you work on Valdi projects.\n\n### GitHub Copilot\n\nAdd this to your workspace settings:\n\n```json\n{\n  \"github.copilot.chat.codeGeneration.instructions\": [\n    {\n      \"text\": \"This is a Valdi project, not React. Use class-based components extending StatefulComponent (with state) or Component (stateless). State is managed via StatefulComponent with this.setState(). Lifecycle methods are onCreate(), onViewModelUpdate(previousViewModel), onDestroy(). Props are accessed via this.viewModel. The onRender() method returns void.\"\n    }\n  ]\n}\n```\n\n### Claude Code\n\nRun `valdi skills install --for=claude` to install Valdi skills globally into Claude Code (`~/.claude/plugins/valdi/skills/`). Skills activate automatically when you work on Valdi projects in any directory.\n\nFor one-off conversations without skills installed, include this in your first message:\n\n> \"I'm working with Valdi, a cross-platform UI framework that uses TSX syntax but is NOT React. Valdi uses class-based components (StatefulComponent with setState() for state, or Component for stateless), not functional components or hooks. Props are accessed via this.viewModel. Lifecycle methods are onCreate(), onViewModelUpdate(), and onDestroy(). The onRender() method returns void, with JSX written as statements.\"\n\n### ChatGPT\n\nWhen starting a conversation, include the same context as the Claude one-off prompt above.\n\n## Reviewing AI Suggestions\n\nAlways check AI-generated code for these red flags:\n\n🚩 **Imports from 'react'** - Valdi imports from 'valdi_core'  \n🚩 **Hooks (useState, useEffect, etc.)** - Don't exist in Valdi  \n🚩 **Functional components** - Must be class-based  \n🚩 **Return statements in onRender()** - Should return void  \n🚩 **Using `this.props`** - Should be `this.viewModel`  \n🚩 **Using `markNeedsRender()`** - Doesn't exist, use `setState()` instead  \n🚩 **Lifecycle methods like `onMount/onUnmount`** - Should be `onCreate/onDestroy`  \n🚩 **`this.context.get()`** - Doesn't exist, use `withProviders()` HOC pattern\n\n## Resources\n\n- **[AGENTS.md](../../AGENTS.md)** - Comprehensive guide for AI assistants\n- **[Getting Started](./getting-started.md)** - Learn Valdi basics\n- **[API Reference](./api/)** - Complete API documentation\n\n## Getting Help\n\nIf AI tools are consistently giving incorrect suggestions:\n\n1. **Install skills**: Run `valdi skills install` to give your AI tool Valdi context\n2. **Be explicit**: Mention \"Valdi (not React)\" in your prompts\n3. **Report issues**: [Open an issue](https://github.com/Snapchat/Valdi/issues) if patterns are consistently wrong\n4. **Join Discord**: [Ask the community](https://discord.gg/uJyNEeYX2U) for help\n\n---\n\nRemember: AI assistants are trained primarily on React code. When working with Valdi, you're the domain expert guiding the AI, not the other way around!\n"
  },
  {
    "path": "docs/docs/choosing-valdi.md",
    "content": "# Choosing Valdi\n\nValdi is a cross-platform native UI framework built around TypeScript and Bazel. It is designed for teams that want to write UI code once and ship true native views on iOS and Android — without a JavaScript bridge at runtime.\n\nThis page is a decision guide. It covers what Valdi is good at and honest gaps in the current release.\n\n## Framework Comparison\n\n| | **Valdi** | **React Native** | **Flutter** | **Native iOS/Android** |\n|---|---|---|---|---|\n| **Language** | TypeScript | JavaScript / TypeScript | Dart | Swift / Kotlin |\n| **Renders to** | True native views (no WebView, no JS bridge) | True native views (new arch: JSI, no bridge) | Native views via Skia/Impeller | Platform native |\n| **UI model** | Class-based components, side-effect JSX | Function/class components, virtual DOM | Widget tree | UIKit / Jetpack Compose |\n| **Hot reload** | `valdi hotreload` — sub-second on-device | Metro bundler — fast | Flutter hot reload — fast | Previews / simulators |\n| **Build system** | Bazel (`BUILD.bazel`) | npm / Metro | `pubspec.yaml` + `flutter` CLI | Xcode / Gradle |\n| **Typing** | Strong (TypeScript, no `any` in generated APIs) | Optional (TypeScript overlay) | Strong (Dart) | Strong |\n| **Ecosystem** | Early-stage; Bazel-first | Large (npm) | Growing (pub.dev) | Platform SDKs |\n| **Dev platform** | macOS Apple Silicon (iOS + Android); Linux (Android only) | macOS, Windows, Linux | macOS, Windows, Linux | macOS (iOS); macOS/Windows/Linux (Android) |\n| **Target platforms** | iOS, Android, macOS desktop, Web (alpha) | iOS, Android, Web | iOS, Android, Web, Desktop | iOS or Android only |\n| **Open source** | Yes (MIT) | Yes (MIT) | Yes (BSD) | Yes |\n| **Bazel integration** | First-class | Third-party rules only | Not supported | Via `rules_apple` / `rules_android` |\n\n## When Valdi is a good fit\n\n**You need a strong TypeScript contract between UI and native.** Valdi generates type-safe ObjC/Kotlin bindings directly from TypeScript interface definitions. Every native binding is defined in TypeScript; there is no `NativeModules.MyMethod()` string dispatch.\n\n**You want true native rendering without a JS bridge at runtime.** Valdi compiles TypeScript to bytecode and renders directly to native views — there is no WebView and no JS-to-native bridge like React Native's JSI.\n\n\n**You are building features for iOS and Android simultaneously.** Valdi modules compile to a single `.valdimodule` archive that runs on both platforms. Platform-specific behavior is isolated to native bindings.\n\n## When another framework is a better fit\n\n**You need Windows or Intel Mac development machines.** The Valdi compiler binary currently ships only for Apple Silicon macOS. Intel Mac and Windows development are not supported yet. Linux is supported for Android-only work. If your engineers are on Windows or Intel Macs and need iOS support, choose React Native or Flutter.\n\n## Current gaps (as of beta-0.0.x)\n\nThese are known limitations the Valdi team is actively working on or tracking:\n\n| Gap | Status | Workaround |\n|-----|--------|-----------|\n| Windows dev support | Not supported | macOS or Linux required |\n| WebSocket API | Not available | Use native bindings via Valdi's TypeScript bridge |\n| CMake / non-Bazel build | Not available | Bazel required |\n| Bazel Central Registry | Not registered | Use `http_archive` with the GitHub release |\n| Linux native target | Not available | — |\n\n## Quick decision guide\n\n```\nNeed iOS support on non-Apple-Silicon Mac? ── Yes ─────────▶ React Native or Flutter\n        │\n       No\n        │\nAre you willing to use Bazel? ───────────── No ─────────────▶ React Native or Flutter\n        │\n       Yes\n        │\n        ▼\n   Valdi is likely a good fit.\n   Start with: valdi bootstrap\n```\n\n## Further reading\n\n- [Getting Started](./start-install.md) — install and run your first module\n- [Valdi for React Developers](./start-from-react.md) — side-by-side React ↔ Valdi reference\n- [Migrating from Flutter](./migrate-from-flutter.md) — Flutter concept mapping\n- [Migrating from Jetpack Compose](./migrate-from-compose.md) — Compose concept mapping\n- [Internals: Renderer](./internals-renderer.md) — how Valdi renders to native views\n- [Troubleshooting](./help-troubleshooting.md) — setup and common issues\n"
  },
  {
    "path": "docs/docs/client-libraries-rxjs.md",
    "content": "# RxJS\n\n## Introduction\n\n[RxJS](https://rxjs.dev/) is a widely used in the industry library to work with async code use reactive paradigm.\n\nFrom the official website:\n\n> RxJS is a library for composing asynchronous and event-based programs by using observable sequences.\n\nRxJS is used extensively at Snap and supported by Valdi. RxJS library is available under `valdi_rxjs` module.\n\n## Linters\n\nTo further enforce some of the best practices, Valdi enables the following RxJS linter rules (click the URL to see the up to date linter description):\n\n### [rxjs/no-sharereplay](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-sharereplay.md)\n\n### [rxjs/no-async-subscribe](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-async-subscribe.md)\n\n### [rxjs/no-ignored-observable](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-ignored-observable.md)\n\n### [rxjs/no-ignored-subscription](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-ignored-subscription.md)\n\nTo avoid memory leaks and unexpected crashes all created subscriptions must be unsubscribed using the `unsubscribe` call or using one of the helpers below.\n\nThere are two ways to ease to manage subscriptions in Valdi:\n\n1. Use [Subscription#add](https://rxjs.dev/api/index/class/Subscription#add) method and invoke [Subscription#unsubscribe](https://rxjs.dev/api/index/class/Subscription#unsubscribe) inside `onDestroy`\n2. Use [Component#registerDisposable](./core-component.md#lifecycle) method which would invoke `unsubscribe` method for you during `onDestroy`\n\n#### Use Component#registerDisposable\n\nUse `Component#registerDisposable` to automatically call `unsubscribe`/`dispose` during `onDestroy` for created subscriptions/disposables if your class is a child of `Component`:\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nimport { Observable } from 'valdi_rxjs/src/Observable';\n\nexport class MyComponent extends Component {\n private myObservable: Observable<boolean> = new Observable<boolean>();\n onCreate() {\n   const sub = this.myObservable.subscribe(data => {\n     // Handle data\n   });\n   this.registerDisposable(sub);\n }\n}\n```\n\n#### Use [Subscription#add](https://rxjs.dev/api/index/class/Subscription#add)\n\nUse `Subscription#add` to keep track of created subscription and manually control when `unsubscribe` method is called:\n\n```tsx\nimport { Subscription } from 'valdi_rxjs/src/Subscription';\n\nexport class MyComponent {\n private subscription: Subscription = new Subscription();\n constructor() {\n   const sub = this.myObservable.subscribe(data => {\n     // Handle data\n   });\n   this.subscription.add(sub);\n }\n\n cleanup() {\n   this.subscription.unsubscribe();\n }\n}\n```\n\n### [rxjs/no-nested-subscribe](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-nested-subscribe.md)\n\n### [rxjs/no-unbound-methods](https://github.com/cartant/eslint-plugin-rxjs/blob/main/docs/rules/no-unbound-methods.md)\n"
  },
  {
    "path": "docs/docs/command-line-references.md",
    "content": "# Valdi Command Line References\n\nThe Valdi command line tools serve as the primary interface for setting up your environment, creating projects, building applications, and managing your Valdi workflow.\n\n## Installation\n\n```bash\nnpm install -g @snap/valdi\nvaldi dev_setup  # Sets up your entire development environment\n```\n\nFor detailed installation instructions, see the [Installation Guide](../INSTALL.md).\n\n> [!TIP]\n> If you're contributing to Valdi itself, install from source instead:\n> ```bash\n> git clone git@github.com:Snapchat/Valdi.git\n> cd Valdi/npm_modules/cli/\n> npm run cli:install\n> ```\n\n## Basic Usage\n\nA list of available commands can be displayed with `valdi --help`.\n\nThe `--help` option is also available within each individual command to display additional details.\n\n```sh\nvaldi <command>\n\nCommands:\n  valdi completion                                             Generates completion script\n  valdi bootstrap                                              Prepares and initializes a project to build and run in Valdi\n  valdi dev_setup                                              Sets up the development environment for Valdi\n  valdi projectsync [--target target]                          Synchronize VSCode project for the given targets\n  valdi new_module [module-name]                               Create a new Valdi module with boilerplate structure\n  valdi build <platform>                                       Build the application\n  valdi install <platform>                                     Build and install the application to the connected device\n  valdi package <platform>                                     Build and package a Valdi application\n  valdi export <platform>                                      Build and export a Valdi library\n  valdi hotreload [--module module_name] [--target             Starts the hotreloader for the application\n  target_name]\n  valdi test [--module module_name] [--target target_name]     Runs tests for given module(s) or target(s). Runs all\n                                                               tests if no module or target is specified.\n  valdi lint <command>                                         Checks and formats the code\n  valdi skills <command>                                       Manage AI assistant skills for Valdi development\n  valdi doctor                                                 Check your Valdi development environment for common issues\n  valdi log                                                    Streams Valdi logs from the connected device to console\n\nOptions:\n  --debug    Run with debug logging                            [boolean] [default: false]\n  --version  Show version number                               [boolean]\n  --help     Show help                                         [boolean]\n```\n\n## Available CLI Commands\n\nThis section aims to cover each command more in-depth and will only provide some barebones usage patterns and descriptions since they are already available via the `--help` option.<br></br>\n\n`valdi completion`\\\nPrints a code snippet and instructions to enable auto completion of available Valdi CLI commands. Optional and not required to use the CLI.<br></br>\n\n`valdi bootstrap [-y --confirm-bootstrap] [-n --project-name]`\\\nSets up a basic Valdi project in the current path by creating all required files to initially build and run the project.\n\nOptions:\n- `-y, --confirm-bootstrap`: Skip confirmation prompt and start bootstrap process\n- `-n, --project-name`: Name of the project\n- `-t, --application-type`: Type of application to create\n- `-l, --valdi-import`: Full path to a local checkout of the Valdi repo\n- `-c, --with-cleanup`: Deletes all existing files in the current directory before initiating bootstrap<br></br>\n\n`valdi dev_setup`\\\nRuns the automated environment setup script to install dependencies and configure the development environment. This command is typically run once during initial setup.<br></br>\n\n`valdi projectsync [--target target]`\\\nRun this command to enable VS Code syntax highlighting for the current workspace project. This regenerates native bindings and updates VS Code project files.\n\n- If `--target` is specified, synchronizes only the specified Bazel target.<br></br>\n\n`valdi new_module [module-name]`\\\nCreate a new Valdi module with boilerplate structure including BUILD.bazel, module.yaml, and basic source files.\n\nOptions:\n- `module-name` (positional): Name of the Valdi module\n- `--template`: Module template to use, will skip the prompt\n- `--skip-checks`: Skips confirmation prompts\n\n**Module naming requirements:**\n- May contain: A-Z, a-z, 0-9, '-', '_', '.'\n- Must start with a letter\n\nExample:\n```sh\n# Interactive mode\nvaldi new_module\n\n# Create module with options\nvaldi new_module my_module --skip-checks\n```\n<br></br>\n\n`valdi build <platform> [--application] [--bazel_args]`\\\nBuild the application without installing it to a device. Useful for CI/CD pipelines or when you just want to verify the build succeeds.\n\n- Supported platforms: `android`, `ios`, `macos`, `cli`\n- If no `--application` is specified, command will query for valid targets in the current workspace.\n- Additional Bazel arguments can be passed in via `--bazel_args` option.<br></br>\n\n`valdi install <platform> [--application] [--bazel_args]`\\\nBuild and install a Valdi application on the given platform to a connected device or emulator.\n\n- Supported platforms: `android`, `ios`, `macos`\n- If no `--application` is specified, command will query for valid targets in the current workspace.\n- Additional Bazel arguments can be passed in via `--bazel_args` option.<br></br>\n\n`valdi package <platform> [--application] --output_path <path>`\\\nBuild and package a Valdi application into a distributable format.\n\n- Supported platforms: `android`, `ios`, `macos`\n- `--output_path` (required): The path where to store the built application package\n- `--application`: Name of the application to build\n\nExample:\n```sh\nvaldi package android --output_path ./dist/app.apk\nvaldi package ios --output_path ./dist/app.ipa\n```\n<br></br>\n\n`valdi export <platform> [--library] --output_path <path>`\\\nBuild and export a Valdi library for integration into native applications. Creates platform-specific library packages.\n\n- Supported platforms: `android`, `ios`\n- `--output_path` (required): The path where to store the exported library\n  - iOS: Must end with `.xcframework`\n  - Android: Must end with `.aar`\n- `--library`: Name of the library to export (will query if not specified)\n\nExample:\n```sh\nvaldi export ios --output_path ./output/MyLibrary.xcframework\nvaldi export android --output_path ./output/mylibrary.aar\n```\n<br></br>\n\n`valdi hotreload [--module module_name] [--target target_name]`\\\nStarts the Valdi [hotreloader](./start-about.md#prototype-quickly-with-hot-reload) for the application target.\n\n- When `--module` and `--target` is omitted, it will attempt to run the application target of the current workspace. If there is more than one defined application, the specific target will need to be specified.\n- The `--target` option should be a valid Bazel target (ex: `//:hello_world_hotreload`).\n- The `--module` option will query and run targets in the current workspace which match the module_name.<br></br>\n\n`valdi test [--module module_name] [--target target_name]`\\\nExecutes the test(s) for the provided targets. Note that multiple modules OR targets can be provided to execute all tests simultaneously. If no modules or targets are provided, ALL tests within the current workspace will be ran.<br></br>\n\n`valdi lint check [files...]`\\\n`valdi lint format [files...]`\\\nRuns the prettier linter on the provided files. The files given can be passed via wildcards. If a prettier config does not exist, a basic one will be created. Further customizations can be done via manually editing the created `.prettierrc.json`.<br></br>\n\n`valdi skills list [--category=framework|client]`\\\n`valdi skills install [name] [--for=claude|cursor|copilot|all] [--category=framework|client]`\\\n`valdi skills update`\\\n`valdi skills remove <name>`\\\n`valdi skills create`\\\nManage Valdi AI skills — context files that teach AI coding assistants (Claude Code, Cursor, GitHub Copilot) about Valdi-specific patterns so they generate correct code instead of React patterns. Skills are bundled in the npm package and work offline.\n\n- `list`: Shows all available skills with per-agent install status. Use `--category` to filter by `framework` (Valdi repo internals) or `client` (module development)\n- `install [name]`: Installs one skill or all skills. Without `--for`, auto-detects which AI tools are installed. Use `--category` to install only framework or client skills\n- `update`: Re-installs all already-installed skills from the bundled package\n- `remove <name>`: Removes a skill from all agents where it is installed\n- `create`: Interactive scaffold — must be run from within a Valdi framework checkout. Prompts for name, description, and category; creates `skill.md` in the correct location and registers it in `registry.json`\n\nExample:\n```sh\n# See all available skills and which are installed\nvaldi skills list\n\n# Install all skills for all detected AI tools\nvaldi skills install\n\n# Install only module-development skills for Cursor\nvaldi skills install --category=client --for=cursor\n\n# Contribute a new skill (run from Valdi repo root)\nvaldi skills create\n```\n\nSkills are stored in `ai-skills/` in the Valdi repository. See [Working with AI Assistants](./ai-tooling.md) for more information.<br></br>\n\n`valdi doctor [--verbose] [--fix] [--json] [--framework] [--project]`\\\nCheck your Valdi development environment for common issues. Performs comprehensive health checks on system requirements, tool installations, and workspace configuration.\n\nOptions:\n- `--verbose, -v`: Show detailed diagnostic information\n- `--fix, -f`: Attempt to automatically fix issues where possible\n- `--json, -j`: Output results in JSON format (useful for CI/CD)\n- `--framework, -F`: Include framework development checks (git-lfs, temurin, etc.)\n- `--project, -p`: Include project-specific checks (workspace structure, etc.)\n\nExample:\n```sh\n# Basic health check\nvaldi doctor\n\n# With verbose output and automatic fixes\nvaldi doctor --verbose --fix\n\n# Include all checks with JSON output\nvaldi doctor --project --framework --json\n```\n\n> [!TIP]\n> Run `valdi doctor` if you encounter setup issues or build failures. It will identify common problems and suggest solutions.<br></br>\n\n`valdi log`\\\nDisplays and streams the Valdi logs. Will prompt user for selection if multiple logs are detected. The list of logs are ordered by descending modification time, with newest entries on the top.\n\n> [!NOTE]\n> Valdi logs are additionally printed to Logcat as well as the XCode console.\n"
  },
  {
    "path": "docs/docs/control-flow.md",
    "content": "# Summary\nThis guide offers a comprehensive introduction to implementing control flow and loops within Valdi. It provides developers with the tools to manage conditional rendering and iterate through lists effectively in their UI designs.\n\n\n# Control Flow and Loops in Valdi Components\n\n## Component Setup\nBegin with a basic Valdi component, initializing necessary variables in onCreate and handling logic in onRender\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nexport class GettingStartedCodelab extends Component {\n    private msg?: string;\n\n    onCreate() {\n        this.msg = 'Hello Valdi on ';\n    }\n\n    onRender() {\n        const fullMsg = this.msg + new Date().toLocaleTimeString();\n        <layout>\n            <label value='Declarative codelab' font=\"system-bold 24\"  />\n            <label value={fullMsg} font=\"system 16\" />\n        </layout>;\n    }\n}\n```\n\n## Conditional Rendering\n### Using if Statements\nEasily manage conditional rendering in your component with if statements:\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nexport class GettingStartedCodelab extends Component {\n    private msg?: string;\n    private kitten?: boolean;\n\n    onRender() {\n        if (this.kitten) {\n            <image height={50} width={50} src='https://placecats.com/300/300' />\n        } else {\n            const fullMsg = this.msg + new Date().toLocaleTimeString();\n            <layout>\n                <label value='Declarative codelab' font=\"system-bold 24\" />\n                <label value={fullMsg} font=\"system 16\" />\n            </layout>;\n        }\n    }\n}\n```\n\n### Nested Functions for Reusability\nImprove readability and reusability by using nested functions for complex render logic:\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nonRenderMessage(message: string): Component {\n    if (this.kitten) {\n        return <image height={50} width={50} src='https://placecats.com/300/300' />;\n    }\n    return <label value={message} font=\"system 16\" />;\n}\n\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value='Declarative codelab' font=\"system-bold 24\" />\n        {this.onRenderMessage(fullMsg)}\n    </layout>;\n}\n```\n\n## Inline **`if`** and **`for`** caveat\nYou might think, having seen the examples above, that you can do something similar with inline **`if`** and **`for`** loops.\n\nWell, you can't.\n\nThe contents of a curly brace block inside of the TSX need to be an expression. In the current tsx standard, **`if`** and **`for`** are not expressions.\nThe alternatives are when and .forEach.\n\n\n## **`when`** expressions\nwhen is a replacement for if for inline rendering.\n\nGoing back to our **`if`** implementation.\n\n```tsx\nonRender() {\n    if (this.kitten) {\n        <image height={50} width={50} src='https://placecats.com/300/300' />\n    } else {\n        const fullMsg = this.msg + new Date().toLocaleTimeString();\n        <layout>\n            <label value='Declarative codelab' font=\"system-bold 24\" />\n            <label value={fullMsg} font=\"system 16\" />\n        </layout>;\n    }\n}\n```\n\nThe first parameter in **`when`** is the conditional, this can be an expression that evaluates to a **`boolean`** or just a variable. The second parameter is a lambda that executes when your conditional evaluates to **`true`**.\n\n**`when`** has no **`else`** clause so if you want that kind of thing, you need to implement a `when(!conditional)`.\n\n```tsx\nonRender() {\n    const fullMsg = this.msg + new Date().toLocaleTimeString();\n    <layout>\n        <label value='Declarative codelab' font=\"system-bold 24\" />\n        {when(this.kitten, () => {\n            <image height={50} width={50} src='https://placecats.com/300/300' />;\n        })}\n        {when(!this.kitten, () => {\n            <label value={fullMsg} font=\"system 16\" />;\n        })}\n    </layout>;\n}\n```\n\n## Inline Loops\nYou can iterate through lists directly within the TSX using map :\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nexport class GettingStartedCodelab extends Component {\n    private kittens = [\n        'https://placecats.com/300/300',\n        'https://placecats.com/300/301',\n        'https://placecats.com/300/302',\n    ];\n\n    onRender() {\n        <layout>\n            <label value='Declarative codelab' font=\"system-bold 24\" />\n            {this.kittens.map(kitten => (\n                <image height={50} width={50} src={kitten} />\n            ))}\n        </layout>;\n    }\n}\n```\n\n## Accessing a specific element in an array\nUsing a key to access a specific element in an array\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nexport class SampleApps extends Component<StartComponentViewModel, StartComponentContext> {\n    private kittens = [\n        { id: 0, url: 'https://picsum.photos/300/300?random=1' },\n        { id: 1, url: 'https://picsum.photos/300/301?random=2' },\n        { id: 2, url: 'https://picsum.photos/300/302?random=3' }\n    ];\n\n    onCreate(): void {\n        console.log('Hello World onCreate!');\n    }\n\n    onRender() {\n        <layout padding={10}>\n            {this.kittens\n                .filter(kitten => kitten.id === 2)\n                .map(kitten => (\n                    <image key={kitten.id.toString()} height={50} width={50} src={kitten.url} />\n                ))}\n        </layout>;\n    }\n}\n```\n\n"
  },
  {
    "path": "docs/docs/core-component.md",
    "content": "# The Mighty Component\n\n## Why Component?\n\n\"Component\" is the basic building block for all valdi UIs.\n\nThere are two basic entities used by Valdi:\n- Valdi `elements` which are basic native elements such as `<image>` or `<view>`\n- Valdi `components` which are implemented in TypeScript and contain business logic.\n\nValdi elements have lowercase naming and are always included by the valdi runtime.\n\nAdditionally, it is possible to directly include a native view using the [`<custom-view>`](./native-customviews.md) tag.\n\nTo simplify:\n- Valdi `elements` are implemented by the native code\n- Valdi `components` are implemented in TypeScript (cross-platform)\n\nWe can define TypeScript components that use both elements and other sub-components. A typical Valdi feature has a root component which calls sub-components who themselves use native elements.\n\n## Native Elements\n\n| Element | Android View | iOS View | Description |\n| ------- | ------------ | ---------|-------------|\n| `<view>` | `ViewGroup`       | `UIView`      | A simple view that can have layout properties (ie: flexbox) and view properties (ie: background color, touch events, etc.)  |\n| `<layout>` | N/A       | N/A      | Supports layout properties such as flexbox but does not support view properties. Use a `<layout>` instead of `<view>` whenever possible, since these nodes will not be backed by a platform view when rendering |\n| `<label>` | `TextView`       | `UITextView`      | For displaying text |\n| `<textfield>` | `EditText`       | `UITextField`      | For editing single line text |\n| `<textview>` | `EditText`       | `UITextView`      | For editing multi-line text |\n| `<image>` | `ValdiImageView`       | `UIImageView`      | Renders an image |\n| `<video>` | `ValdiVideoView`       | `SCValdiVideoView`      | Renders a video |\n| `<scroll>` | `ValdiScrollView`       | `SCValdiScrollView`      | A container of views that can scroll either vertically or horizontally  |\n| `<blur>` | N/A       |    `UIVisualEffectView`   | (iOS only) A container that blurs the background  |\n| `<shape>` | `View`       |   `UIView`    | Supports drawing shapes in a view |\n\n## Example Component\n\n```tsx\n/**\n * Make sure to import the component parent class\n */\nimport { Component } from 'valdi_core/src/Component';\n/**\n * We can (optionally) define an interface that declares all the components parameters\n * Any parent component that uses this component will be able to modify those values\n * Any change in those values will trigger a render of the component\n */\nexport interface ReusableComponentViewModel {\n  myParam: string;\n  myOtherParam: number;\n}\n/**\n * This is a typical class that defines the component logic\n * Note that it has an optional generic type for its view model\n */\nexport class ReusableComponent extends Component<ReusableComponentViewModel> {\n  onCreate() {\n    // Called when the component is created in the render-tree\n    // Used to prepare some resources, precomputed values or subscribe to observables\n  }\n  onDestroy() {\n    // Called when the component is no longer in the render-tree\n    // Used to dispose of resources and observables\n  }\n  onViewModelUpdate(previous?: ReusableComponentViewModel) {\n    // Called every time the view model changes\n    // Used to trigger some computations, typically used for asynchronous operations,\n    // that would then impact the internal component state\n  }\n  onRender() {\n    // Called every time the component needs to be rendered\n    // Used to define child components and child render-tree\n    // Can access \"this.viewModel\" that contains the current component parameters values\n    const myVariable = 20;\n    <view backgroundColor='lightblue' padding={myVariable}>\n      <label value={'myParam: ' + this.viewModel.myParam} />\n      <label value={'myOtherParam: ' + this.viewModel.myOtherParam.toString()} />\n    </view>;\n  }\n}\n```\n\nAn example how to use the above component would be:\n\n```tsx\nexport class HelloWorld extends Component {\n  onRender() {\n    <ReusableComponent myParam='Hello this the parameter' myOtherParam={42} />;\n  }\n}\n```\n\n![''](./assets/core-component/IMG_1448.jpg)\n\n\n> [!Note]\n>  We are using the component **from** within a component.\n\n\n## Lifecycle\nEach component has several lifecycle methods that can be overridden to run code at particular times in the application process.\n\n```ts\nonCreate()\n```\nCalled when the component is first created and its attributes, view model, and state have been set, but it has not yet been rendered. The component will be rendered right after the call.\n\n```ts\nonViewModelUpdate(previousViewModel?: ViewModelType)\n```\nCalled when the `viewModel` of the component is set and updated. Also called directly after `onCreate()` if a view model was provided at initialization. The component will be rendered right after the call.\n\nNote: if you need to update your state as part of a view model change call `setState()` with the new partial state directly.\n\n```ts\nonRender()\n```\nCalled when the component is rendering.\nTSX tags will only have an effect INSIDE of the call stack of an onRender() function\n\n```ts\nonDestroy()\n```\nCalled when the component was destroyed\n\n```ts\nonError(error: Error)\n```\nCalled when a render error occurs in a child component. This allows the component to act as an **Error Boundary**, catching exceptions and potentially rendering a fallback UI instead of crashing the entire tree.\n\n```ts\nregisterDisposable(disposable: (() => void) | Unsubscribable)\n```\nRegisters a function or unsubscribable (like an RxJS Subscription) which will be called automatically when the component is destroyed. This is useful for cleaning up subscriptions, timers, or other resources.\n\n**Example with RxJS:**\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nimport { interval } from 'valdi_rxjs/src/interval';\n\nexport class MyComponent extends Component {\n  onCreate() {\n    const subscription = interval(1000).subscribe(() => {\n      console.log('Tick');\n    });\n    \n    // Subscription will be automatically cleaned up when component is destroyed\n    this.registerDisposable(subscription);\n  }\n}\n```\n\n**Example with custom cleanup:**\n```tsx\nexport class MyComponent extends Component {\n  onCreate() {\n    const timerId = setInterval(() => {\n      console.log('Timer fired');\n    }, 1000);\n    \n    // Clear timer when component is destroyed\n    this.registerDisposable(() => {\n      clearInterval(timerId);\n    });\n  }\n}\n```\n\n> **See also:** [RxJS Integration](./client-libraries-rxjs.md) for more examples of subscription management\n"
  },
  {
    "path": "docs/docs/core-events.md",
    "content": "# Component Events\n\nTo support the ability to listen to and respond to native-side and user interactions as well as a component's lifecycle, Valdi emit events that can be listened to inside pure TypeScript. These events can be handled by registering a listener function via the proper callback.\n\n## View and Layout Events\n\nIn Valdi the `<view>` or `<layout>` elements exposes some lifecycle events such as `onLayout`, `onViewPortChanged`, `onLayoutComplete`, `onVisible`, `onMeasure`, etc., which can be called with a `Frame` that describes the actual components.\n\nThese view and layout based events will also receive information regarding its position and dimensions with the defined interface of an `ElementFrame`.\n\nThese `Frame` or `Size` type events usually have the following:\n\n```js\ninterface ElementFrame extends Point, Size {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n}\n```\n\n> [!NOTE]  \n> In Valdi, positional data such as a view's (`x`, `y`) locations refer to an offset from the top left relative to its parent view. Whereas (`absoluteX`, `absoluteY`) refer to its offset from the root Valdi view.\n\nValdi's geometry based events will implement the following interface(s):\n\n```js\ninterface Point {\n  x: number;\n  y: number;\n}\n\ninterface Size {\n  width: number; // floating point representation of size, point based\n  height: number;\n}\n\ninterface Vector {\n  dx: number; // floating point representation of velocity\n  dy: number;\n}\n```\n\n## Touch and Gesture Events\n\nFor touches and gestures, the `<view>` exposes interaction based events and callbacks such as `on[Touch/Tap/Drag/Scroll/Pinch]`. Each of those callbacks will contain information about the `TouchEvent` whenever the corresponding gesture is performed on a view.\n\nA `TouchEvent` contains the following information for all other gesture event types to extend from.\n\n```js\ninterface TouchEvent {\n  x: number;\n  y: number;\n  absoluteX: number; // X position from within the root element\n  absoluteY: number; // Y position from within the root element\n  pointerCount: number; // count of active pointers\n  pointerLocations: Pointer[]; // all pointer locations, which contain individual point data\n}\n```\n\n> [!NOTE]  \n> For a comprehensive list of all gesture events, refer to [`valdi_tsx/src/GestureEvents.d.ts`](../../src/valdi_modules/src/valdi/valdi_tsx/src/GestureEvents.d.ts)\n\nFor advanced usage of gestures and managing their events, refer to the [Touches and Gestures](./core-touches.md) page.\n\n## Text Editing Events\n\nFor events based on text editing, Valdi exposes `onChange`, `onWillChange`, `onSelectionChange`, and so on which that receive `EditTextEvent` as part of the callback.\n\n## Layout Lifecycle Events\n\nValdi provides specialized events to track the layout process:\n\n- **`onLayoutComplete`**: This callback is triggered when the layout pass for the entire tree has completed. It's useful for performing actions that depend on the final positions and sizes of all elements.\n\nAn `EditTextEvent` has the following:\n\n```js\ninterface EditTextEvent {\n  text: string; // string value of any text that's entered into a text field, ignoring any styling and annotations from attributed text\n  selectionStart: number; // beginning of selection\n  selectionEnd: number; // end of selection, can be equal to selectionStart\n}\n```\n\nFor more information regarding text and text editing, refer to the [Text and Label](./core-text.md) page.\n\n## Callbacks\n\nWithin Valdi, we translate TypeScript-based callbacks so that our native runtime and native code can execute the calls directly. Due to the TypeScript context system, we enforce that all callbacks must properly refer to the correct value of `this`, and so we expect all callbacks to be passed in via TypeScript lambda functions, which do not create modify any references to `this`.\n\nFurthermore, due to how rendering is performed, where `onRender` or an future render functions are called, we recreate all references and variables within the render function. Developers should avoid creating inline functions, and instead use [`createReusableCallback`](../../src/valdi_modules/src/valdi/valdi_core/src/utils/Callback.ts) to ensure functions references are correct.\n\n## Example\n\nWe can create a custom button which increments a counter when it's tapped as follow:\n\n```tsx\ninterface MyButtonState {\n  counter: number;\n}\nexport class MyButton extends StatefulComponent<object, MyButtonState> {\n  state = {\n    counter: 0,\n  };\n  onRender() {\n    const buttonText = `Button tapped ${this.state.counter} times`;\n    // Render our button, with a label\n    // which displays how many times the button was tapped\n    <view\n      margin={20}\n      backgroundColor='gray'\n      borderRadius='50%'\n      padding={16}\n      onTap={this.buttonTapped} // Register a callback for when the view is tapped\n    >\n      <label value={buttonText} />\n    </view>;\n  }\n  // Notice that we declared the function as a lambda instead of a method.\n  // This allows to ensure the onTap callback is not created at every render.\n  private buttonTapped = () => {\n    // Increment our counter in our state\n    // which will trigger a new render and update the UI\n    this.setState({ counter: this.state.counter + 1 });\n  };\n}\n```\n\nand voila:\n\n```tsx\nexport class HelloWorld extends Component {\n  onRender() {\n    <MyButton />;\n  }\n}\n```\n\n![Screenshot of MyButton showing it has been tapped 8 times](./assets/core-events/IMG_1451.jpg)\n"
  },
  {
    "path": "docs/docs/core-flexbox.md",
    "content": "# FlexBox Layout\n\n## What is FlexBox Layout\n\nValdi uses [FlexBox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_flexible_box_layout/Basic_concepts_of_flexbox) for layout. This should be familiar if you have done any web development.\n\n> [!Note]\n> The Valdi runtime integrates a cross-platform layout engine that follows the **Web Flexbox specification**. This engine calculates the positions and sizes of each element on the screen based on the properties provided in TypeScript, ensuring consistent layout across iOS, Android, and Desktop.\n\nYou can find examples and documentation on the different attributes for laying out views on the screen on the following references:\n- https://css-tricks.com/snippets/css/a-guide-to-flexbox/\n- https://jonibologna.com/flexbox-cheatsheet\n\nYou can also practice on a real-time flexbox sandbox here:\n- https://yogalayout.com/playground/\n\n## FlexBox attributes in 30 seconds\n\n> [!Note]\n>**Keep the following in mind:**\n>- `main axis`: in **row mode** it is the **horizontal axis**, in **column mode** it is the **vertical axis**\n>- `cross axis`: in **row mode** it is the **vertical axis**, in **column mode** it is the **horizontal axis**\n\n**FlexBox mainly uses the following attributes:**\n- `flexDirection` used to describe if children should be arranged in rows or columns\n- `justifyContent` used to describe alignment of items along the **main axis**\n- `alignItems` used to describe alignment of items along the **cross axis**\n\n**Less often you might want to use other secondary attributes:**\n- `flexShrink` used to describe how the parent container should constrain item size\n- `flexGrow` used to describe how item should occupy empty space in parent container\n- `flexWrap` used to describe how wrapping is done\n\n## FlexBox examples in 30 seconds\n\n#### Example 1 Requirements\n\n- A row of elements ➜ `flexDirection=row`\n- Horizontally centered ➜ `justifyContent=center` (in row mode, main axis is horizontal)\n- Vertically aligned to the bottom ➜ `alignItems=flex-end` (in row mode, cross axis is vertical)\n\ngo! 🎉\n\n```tsx\nexport class HelloWorld extends Component {\n  onRender() {\n    <view\n      flexDirection='row' // Row mode\n      justifyContent='center' // Main axis centered (row mode: main axis is horizontal)\n      alignItems='flex-end' // Cross axis toward end (row mode: cross axis is vertical)\n      backgroundColor='lightblue'\n      height={100}\n    >\n      {this.onRenderItems()}\n    </view>;\n  }\n  onRenderItems() {\n    for (let i = 0; i < 3; i++) {\n      <image src='https://placedog.net/500' height={64} width={64} border='1 solid red' />;\n    }\n  }\n}\n```\n\n![Screenshot of Flexbox](./assets/core-flexbox/IMG_1466.jpg)\n\n#### Example 2 Requirements\n\n- A column of elements ➜ `flexDirection=column`\n- Vertically centered ➜ `justifyContent=center` (in column mode, main axis is vertical)\n- Horizontally aligned to the right ➜ `alignItems=flex-end` (in column mode, cross axis is horizontal)\n\ngo! 🎉\n\n```tsx\nexport class HelloWorld extends Component {\n  onRender() {\n    <view\n      flexDirection='column' // column mode\n      justifyContent='center' // Main axis centered (column mode: main axis is vertical)\n      alignItems='flex-end' // Cross axis toward end (column mode: cross axis is horizontal)\n      backgroundColor='lightblue'\n      height={100}\n    >\n      {this.onRenderItems()}\n    </view>;\n  }\n  onRenderItems() {\n    for (let i = 0; i < 3; i++) {\n      <label value='Hello World' border='1 solid red' backgroundColor='lightgrey' font={TextStyleFont.BODY}/>;\n    }\n  }\n}\n```\n\n![Screenshot of example 2](./assets/core-flexbox/IMG_1465.jpg)\n\n## Things to keep in mind\n\n- `flexDirection` will impact every other flex attribute's behavior!\n- `justifyContent`/`alignItems` are equivalent, but apply to the main-axis/cross-axis\n- `alignSelf` is equivalent to `alignItems`, but apply only on one child\n\n\n### Default behaviors\n\n- `flexDirection` = \"column\" (top to bottom)\n- `justifyContent` = \"flex-start\" (start of the main-axis)\n- `alignItems` = \"stretch\" (take all space in cross-axis)\n- `flexShrink` = \"0\" (do not shrink content size when constrained by parent size)\n- `flexGrow` = \"0\" (do not grow content size when space is available in parent)\n- `flexWrap` = \"no-wrap\" (do not wrap around the cross-axis)\n"
  },
  {
    "path": "docs/docs/core-images.md",
    "content": "# The `<image>`\n\n## Introduction\n\nValdi supports displaying local and remote image assets through the `<image>` element in TSX, and animated images using the `<animatedimage>` element.\n\nThe Valdi compiler will automatically generate image variants at the right size for both iOS and Android if there is a variant missing. Bundled images should be added to the `res/` folder in the correct Valdi module. The names of the images should follow the iOS or Android naming conventions (`@2x`/`@3x` for iOS or `drawable-hdpi/` `drawable-mdpi/` etc.. for Android) so that the compiler can know what variant the images represent.\n\nYou can specify remote assets with a URL.\n\n## Using images\n\nFor local assets in the `res/` folder, the module will expose properties to all the assets available in this directory. Resources should autocomplete in VSCode.\n\n> [!Note]\n> The Valdi compiler generates an **Asset Catalog** which includes the dimensions (in pixel-independent units) for each image asset. This allows the runtime to \"measure\" images during the layout pass without having to actually load the image data, improving performance and reducing memory usage.\n\nYou specify the asset a url in the `src` attribute of `<image>` in TSX.\n\n```tsx\n// Import the asset catalog in the res folder of the valdi_example module\nimport res from 'valdi_example/res';\nimport { contentObjectImageLoaderUrl, NativeContentTypeKey } from 'media/src/util/encryption';\n// Out lovely component\nexport class HelloWorld extends Component {\n  onRender() {\n    /**\n     * We are gonna render our images in a container, so let's make sure our images has:\n     *  - a source \"src\", this can be an URL or an asset\n     *  - sizes, make sure height and width are defined, otherwise they might be set to 0!\n     *  - optionally, we can \"tint\" our image by an arbitrary color\n     */\n    <view padding={10} backgroundColor='lightblue' flexDirection='row' justifyContent='center'>\n      {/* You can pass the \"emoji\" asset to the src of our image */}\n      <image src={res.emoji} tint='black' height={48} width={48} margin={10} />\n      {/* You can Pass an arbitrary url to the src of our image */}\n      <image src='https://placedog.net/500' height={48} width={48} margin={10} />\n      {/* Urls are sometimes used for loading BOLT assets */}\n      <image src='https://placecats.com/500/500' height={48} width={48} margin={10} />\n      {/* BOLT Urls can also be obtained from contentObjects using contentObjectImageLoaderUrl */}\n      <image\n        src={contentObjectImageLoaderUrl({\n            contentObject, nativeContentTypeKey:\n            NativeContentTypeKey.COMMUNITIES,\n        })}\n        height={48}\n        width={48}\n        margin={10}\n      />\n    </view>;\n  }\n}\n\n```\n\n![Screenshot of image components rendering images](./assets/core-images/IMG_1453.jpg)\n\n> Make sure to run `valdi projectsync [--target target]` before trying to import an image that was just added\n\n## Adding an image asset\n\nLet's consider we want to add an image `my_banner@3x.png` in a `onboarding` module. We'd add it to the `res` folder as follows:\n```\nonboarding/res/my_banner@3x.png\n```\n\nIf we also had an Android specific variant like `drawable-mdpi/my_banner.webp`, we'd also add it in the `res` folder as follow:\n```\nonboarding/res/my_banner@3x.png\nonboarding/res/drawable-mdpi/my_banner.webp\n```\n\nFor the image to be useable at runtime, we need run the compiler again which will generate any missing variants. In our example, the compiler will generate a `my_banner@2x.png`, `drawable-hdpi/my_banner.web`, `drawable-xhdpi/my_banner.webp`, `drawable-xxhdpi/my_banner.webp` and `drawable-xxxhdpi/my_banner.webp`.\n\nMake sure the `res` folder is referenced in your module's `BUILD` file.\n\n```bazel\n\nvaldi_module(\n    name = \"onboarding\",\n    ...\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    ...\n)\n\n```\n\n```bash\n# Typical valdi development path\ncd /Path/To/Your/App/src/valdi/app_name/src\n\n# Need to regenerate the BUILD.bazel files if adding in a /res folder\nbazel build //src/onboarding/onboarding:onboarding\n\n# Compile the typescript code into the native repo\nvaldi install ios\n# or\nvaldi install android\n```\n\nThis can then be used like before:\n\n```tsx\nimport res from 'valdi_example/res';\n// Translate to rendering: onboarding/res/my_banner@[*].png\n<image src={res.myBanner} />\n```\n\n## Animated images\nThe `<animatedimage>` element supports several types of animated images and can display static images as well. Supported formats include [Lottie](https://airbnb.design/lottie) and animated/static WebP, as well as static JPG and PNG.\n\n[factory method]: #todo-factory-method-link\n[LottieDemo app]: #todo-lottie-demo-link\n\nUnder the hood, `<animatedimage>` uses the AnimatedImage [factory method][] to find the right decoder to use for the given media. Valdi uses a custom Lottie renderer, and then relies on [SkCodec](https://github.com/google/skia/blob/main/include/codec/SkCodec.h) to handle a variety of image formats. This means that other formats supported by SkCodec (such as gif) could be supported by compiling SkCodec with additional codecs.\n\nSee the [LottieDemo app][] for examples of how to use `<animatedimage>`.\n\n## Custom image loading\n\nIf you need a different data format or additional functionality, you can do that with a [custom image loader](./advanced-images.md).\n\n## Preloading images\n\nThe runtime will automatically take care of loading assets represented from the `src` attribute of a `<image>` or `<animatedimage>` element whenever the element is visible within the viewport. You can also trigger the load explicitly from the TypeScript code, which can be used to preload images or retrieve the bytes content of an asset:\n```ts\n\nimport { Component } from 'valdi_core/src/Component';\nimport { addAssetLoadObserver, AssetType, AssetOutputType, AssetSubscription, resolveAssetOutputType } from 'valdi_core/src/Asset';\n\nexport class ImagePreloader extends Component {\n  private loadSubscription?: AssetSubscription;\n\n  onCreate() {\n      // Resolve the outputType that the runtime will use for loading images into our current contextId\n      // set within the renderer. This will detect whenever the context is using the iOS, Android or SnapDrawing\n      // render backend and get us the right AssetOutputType.\n      const assetOutputType = resolveAssetOutputType(this.renderer.contextId, AssetType.IMAGE);\n      // Eagerly load our image whenever our ImagePreloader is created, without waiting for the runtime to do it for us.\n      this.loadSubscription = addAssetLoadObserver('https://mydomain.com/myimage.jpg', (loadedAsset, error) => {\n        console.log(`Finished preloading image with error: ${error}`)\n      }, assetOutputType);\n  }\n\n  onDestroy() {\n    this.loadSubscription?.unsubscribe();\n    this.loadSubscription = undefined;\n  }\n}\n```\n\n> [!WARNING]\n> Please note that the asset load observer must be unsubscribed at some point after it has been added, otherwise the loaded image will stay in the in-memory cache forever. The runtime relies on the presence of observers to detect whether or not an asset is actually used.\n\n\n## ImageView Callbacks\n\nYou can attach `ImageView` specific callbacks (in addition to normal callbacks available on a `View`) to perform logic when an image has been loaded or decoded. There are two available callbacks:\n\n```typescript\ntype ImageOnAssetLoadCallback = (success: boolean, errorMessage?: string) => void;\ntype ImageOnImageDecodedCallback = (width: number, height: number) => void;\n\nonAssetLoad?: ImageOnAssetLoadCallback;\nonImageDecoded?: ImageOnImageDecodedCallback;\n```\n\nA key difference between these two callbacks is that `onAssetLoad` is triggered when the image finishes loading but does not necessarily know its dimensions yet. Conversely, `onImageDecoded` is called after the layout has been calculated, which is reflected in their callback parameters.\n\n> [!NOTE]\n> Due to rendering optimizations, views that are too far outside of the parents viewport are not rendered or loaded by default. In such cases, if an image is not preloaded, the `onAssetLoad` and `onImageDecoded` callbacks will not be triggered. This behavior can be bypassed with `limitToViewPort={false}` attribute on a view.\n> This may be relevant when an image is in a scroll view or animating images that begins outside of the parent view's viewport.\n\n## Complete API Reference\n\nFor a comprehensive list of all properties and methods available on `<image>` and `<animatedimage>` elements, including all callbacks, transforms, and display options, see the [API Reference](../api/api-reference-elements.md#imageview).\n"
  },
  {
    "path": "docs/docs/core-module.md",
    "content": "# Valdi Module\n\nA Valdi Module is a logical building block in a Valdi-based application. A typical Valdi module consists of TypeScript code and optional resources and localization data. The Valdi Compiler takes a module and produces a `.valdimodule` artifact used by the final application.\n\n## Creating a new module\n\nValdi provides a convenient script to create a new module that sets up the basic structure and creates a few important files.\n\n```sh\n$ valdi new_module --help\nvaldi new_module [module-name]\n\n\n******************************************\nValdi Module Creation Guide\n******************************************\n\nRequirements for Valdi module names:\n- May contain: A-Z, a-z, 0-9, '-', '_', '.'\n- Must start with a letter.\n\nRecommended Directory Structure:\nmy_application/          # Root directory of your application\n├── WORKSPACE            # Bazel Workspace\n├── BUILD.bazel          # Bazel build\n└── modules/\n    ├── module_a/\n    │   ├── BUILD.bazel\n    │   ├── android/     # Native Android sources\n    │   ├── ios/         # Native iOS sources\n    │   ├── cpp/         # Native C++ sources\n    │   └── src/         # Valdi sources\n    │       └── ModuleAComponent.tsx\n    ├── module_b/\n        ├── BUILD.bazel\n    │   ├── res/         # Image and font resources\n    │   ├── strings/     # Localizable strings\n        └── src/\n            └── ModuleBComponent.tsx\n```\n\n## Project Structure\n\nA Valdi project is defined by:\n- **`WORKSPACE`**: The Bazel workspace file that defines external dependencies. Created automatically by `valdi bootstrap`.\n- **`.bazelrc`**: Bazel configuration file with build settings.\n- **User Config** (`~/.valdi/config.yaml`): Per-user CLI settings (created by `valdi bootstrap`).\n- **Modules**: A list of directories, each containing a `BUILD.bazel` file defining a Valdi module.\n\nRun `valdi bootstrap` to initialize a new project with the correct structure.\n\n### Module Archives\nThe compiler outputs a `.valdimodule` file for each module, which is a bundled archive of compiled TypeScript and metadata. Modules can reference each other as dependencies using standard Bazel target syntax (e.g., `//src/valdi/other_module`).\n\n## Module directory layout\n\n### `res`\n\nThe folder with resources (eg: images).\n\n### `src`\n\nThe folder with TypeScript sources.\n\n### `strings`\n\nThe folder with localized strings.\n\n## `BUILD.bazel`\n\nThe main configuration file of a Valdi module.\n\n> **Note:** Older Valdi projects may have `module.yaml` files. These are deprecated in favor of `BUILD.bazel` configuration. All module configuration should now be done in the `valdi_module()` rule in `BUILD.bazel`.\n\n```python\nload(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"hello_world\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]),\n    android_class_path = \"com.snap.valdi.modules.hello_world\",\n    android_deps = [\"//src/android:native_module_android\"],\n    ios_deps = [\"//src/ios:native_module_ios\"],\n    ios_module_name = \"SCCHelloWorld\",\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_tsx\",\n        \"@valdi_widgets//valdi_modules/widgets\",\n        \"//src/valdi/some_other_valdi_module\",\n    ]\n)\n```\n\n#### `name`\n\nThe name of the Valdi module.\n\n#### `srcs`\n\nglob of the sources to include in the build.\n\n#### `ios_deps`\n\nbazel path of iOS sources this module depends on.\n\n#### `ios_module_name`\n\nClass prefix to use for the generated Objective-C classes.\n\n#### `ios_output_target` (Default: `debug`)\n\nOne of: `debug` or `release`.\nChange the output_target to `release` if you'd like your module to be available in non-debug builds. Defaults to `debug` to avoid accidentally leaking in-development features.\n\n#### `android_class_path`\n\nPackage prefix to use for generated Kotlin classes.\n\n#### `android_output_target` (Default: `debug`)\n\nOne of: `debug` or `release`.\nChange the output_target to `release` if you'd like your module to be available in non-debug builds. Defaults to `debug` to avoid accidentally leaking in-development features.\n\n#### `res`\n\nglob of the resources to include in the build.\n\n#### `visibility`\n\nSee [Bazel Visibility](https://bazel.build/concepts/visibility).\n\n#### `deps` (Default: `[]`)\n\nA list of Valdi modules this module depends on.\n\n#### `strings_dir` (Default: `None`)\n\nThe directory containing the strings files. See [Localization](./advanced-localization.md) for details on string file format.\n\n#### `android_deps` (Default: `[]`)\n\nList of native Android dependencies (Bazel targets) that this module requires.\n\n#### `native_deps` (Default: `[]`)\n\nList of native code dependencies (C++) that this module requires.\n\n#### `web_deps` (Default: `[]`)\n\nList of web-specific dependencies that this module requires.\n\n#### `compilation_mode` (Default: `js_bytecode`)\n\nThe JavaScript compilation mode for the module. Options:\n- `js_bytecode` - Compile to bytecode (default, best performance)\n- `js` - Keep as JavaScript (easier debugging)\n- `native` - Native compilation\n\n#### `downloadable_assets` (Default: `True`)\n\nWhether module resources can be downloaded remotely at runtime (`True`) or must be bundled with the app (`False`).\n\n#### `inline_assets` (Default: `False`)\n\nWhether to inline assets directly into the module instead of as separate resource files.\n\n#### `disable_annotation_processing` (Default: `False`)\n\nDisable processing of TypeScript annotations (e.g., `@ExportModel`). Use when module doesn't need native code generation.\n\n#### `disable_dependency_verification` (Default: `False`)\n\nSkip verification of module dependencies. Generally not recommended.\n\n#### `disable_code_coverage` (Default: `False`)\n\nDisable code coverage instrumentation for this module.\n\n#### `disable_hotreload` (Default: `False`)\n\nDisable hot reload support for this module. Use for performance-critical modules.\n\n#### `single_file_codegen` (Default: `True`)\n\nUse single-file code generation mode. When `True`, generates one file per module instead of multiple files.\n\n#### `ios_language` (Default: `objc`)\n\nLanguage for generated iOS code. Options:\n- `objc` - Objective-C\n- `swift` - Swift  \n- `both` - Both Objective-C and Swift\n\n#### `sql_db_names` (Default: `None`)\n\nList of SQL database names if this module uses SQL databases.\n\n#### `sql_srcs` (Default: `[]`)\n\nSQL source files to include in the module.\n\n## Module Loading & Execution\n\n### `JsEvaluator`\nThe Valdi C++ runtime uses a `JsEvaluator` to load and execute modules. When a module is requested, the evaluator:\n1. Locates the file within the `.valdimodule` archive.\n2. Evaluates the code within the JavaScript engine (QuickJS or JavaScriptCore).\n3. Returns a module function that encapsulates the module's scope.\n\n### Lazy Loading\nTo optimize application startup time, Valdi uses **Lazy Module Loading**. When you `import` or `require()` a module, Valdi returns an ES6 Proxy instead of the actual exports. The module's code is only evaluated the first time you access a property on that proxy.\n\nThis ensures that a large Valdi project doesn't slow down the \"cold start\" of your application, as only the code path required for the initial screen is executed.\n\nFor more details on the runtime implementation, see [Runtime Internals](./internals-runtime.md).\n\n## `ids_yaml`\n\nFile with accessibility ids. Refer to the [testing](./workflow-testing.md) documentation on how it can be used to implement UI tests.\n\nSee also: ([iOS](../codelabs/integration_with_native/ios/5-ios_testing.md), [Android](../codelabs/integration_with_native/android/5-android_testing.md)) on how it can be used to implement UI tests.\n\n## `protodecl_srcs`\n\nIf protobuf is used, refer to [Protobuf Integration](./advanced-protobuf.md#protobuf-config-file).\n"
  },
  {
    "path": "docs/docs/core-scrolls.md",
    "content": "# The `<scroll>`\n\n## Introduction\n\nValdi provides a very easy way to implement a scrollable container through the `<scroll>` element in TSX.\n\nIf any of the children of this `<scroll>` element are laid out outside the bounds of the `<scroll>` element itself, the region will be scrollable. The content size for the `<scroll>` element is determined automatically by the runtime.\n\nIn most cases, this actually removes the need for a ListView equivalent of the native code, you simply add components inside of a scroll view instead!\n\n## Simple Example\n\nLet's implement a simple list of scrollable elements as follow:\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nexport class HelloWorld extends Component {\n  onRender() {\n    <scroll height={200} width='100%' backgroundColor='lightblue'>\n      <view flexDirection='column' width='100%' alignItems='center'>\n        <label value='Cute doggy:' />\n        <image src='https://placedog.net/600' width={200} height={200} />\n        <label value='Another cute doggy:' />\n        <image src='https://placedog.net/500' width={200} height={200} />\n        <label value=\"This time it's cute kitty:\" />\n        <image src='http://placecats.com/200/200' width={200} height={200} />\n      </view>\n    </scroll>;\n  }\n}\n```\n\n![Screenshot of a scrollview with content](./assets/core-scrolls/IMG_1460.jpg)\n\n## Dynamic list of data (ListView equivalent)\n\nThis is great and all, but what if I have dynamic data!?\nWell unlike native view patterns, in this case we simply need to loop over our data and render on element for each!\nValdi will know which one to display and which one to hide.\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\n// Some arbitrary list of elements we want to render, this data can be dynamic!\nconst items = ['Sophie', 'Christophe', 'Pierre', 'Monique', 'Jean-Claude'];\n\n// Let's make a scrollable component\nexport class HelloWorld extends Component {\n  onRender() {\n    // Make a scroll view\n    <view>\n      <scroll width='100%' horizontal={true} backgroundColor='lightblue'>\n        {items.forEach(item => {\n          // For Each Item: Render one box with a label for each item in our list\n          <view padding={10} border='2 solid blue' margin={10}>\n            <label value={item} margin={10} adjustsFontSizeToFitWidth={true} />\n          </view>;\n        })}\n      </scroll>\n    </view>;\n  }\n}\n```\n\n![Screenshot of listview rendering a list of views horizontally](./assets/core-scrolls/IMG_1458.jpg)\n\nThe page will be made automatically scrollable whenever the content of `scroll` is bigger than the `scroll` element itself.\n\n## Horizontal vs Vertical\n\nA `<scroll />` can be displayed in horizontal mode by setting the `horizontal` attribute to `true`:\n\n```tsx\nonRender() {\n  <scroll horizontal={true}>\n    {items.forEach(() => {\n      // add children\n    })}\n  </scroll>\n}\n```\n\n## What about UITableView, UICollectionView, ListView or RecyclerView?\n\nThose view classes are designed to efficiently implement a scrollable region on iOS and Android. Valdi has its own internal mechanism to make scrolling efficient without forcing users to adhere to a strict API.\n\nIn Valdi you don't have to think or deal with view recycling/re-use, the framework handles everything under the hood for you and it has similar performance to those view classes.\n\n> [!Note]\n> The Valdi runtime automatically calculates the viewport of elements when scrolling. It determines which UI elements are actually visible on the screen and only renders those, ensuring high performance even for very long lists.\n\nUsing [flexbox properties](./core-flexbox.md) to layout your child views provides a simple and flexible way to provide a large list of scrollable components. For this reason, Valdi does not currently provide APIs for those view classes.\n\n## Complete API Reference\n\nFor a comprehensive list of all properties and methods available on `<scroll>` elements, including scroll events, bounce behavior, viewport extensions, and programmatic scroll control, see the [API Reference](../api/api-reference-elements.md#scrollview).\n"
  },
  {
    "path": "docs/docs/core-slots.md",
    "content": "# The `<slot>`\n\n## Slots\nValdi implements a content distribution API that’s modeled after the current [Web Components spec draft](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Slots-Proposal.md), using the `<slot>` element to serve as distribution outlets for content.\n\n> Slot provides a component the ability to allow content to be \"injected\" into its render-tree\n\nSlots, when unused or unspecified, are discarded.\n\n## Slotting contents into another Component\n\nIt's often useful to create Components that work as containers for contents that are provided externally. Let's imagine a hypothetical `HorizontalStack` component that takes its children and arranges them on a horizontal line:\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nexport class HorizontalStack extends Component {\n  onRender() {\n    <view\n      flexDirection='row'\n      justifyContent='center'\n      padding={20}\n      backgroundColor='lightblue'>\n      <slot />\n    </view>;\n  }\n}\n```\n\nThe special `<slot/>` element denotes a placeholder in the UI hierarchy that `HorizontalStack`'s children should be _slotted into_. Here's how you can now use the `HorizontalStack` Component:\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nimport { HorizontalStack } from 'horizontal_stack/src/HorizontalStack';\n\nexport class HelloWorld extends Component {\n  onRender() {\n    <HorizontalStack>\n      <label margin={5} value='red' color='red' backgroundColor='white' />\n      <label margin={5} value='green' color='green' backgroundColor='white' />\n      <label margin={5} value='blue' color='blue' backgroundColor='white' />\n    </HorizontalStack>;\n  }\n}\n```\n\n![Screenshot of the HelloWorld component](./assets/core-slots/IMG_1455.jpg)\n\n## Multiple slots\n\nA Component can have multiple slots. To distinguish between them, a `<slot>` element has a `name` attribute. When a name is not provided, `'default'` is assumed\n\n```tsx\n<slot name='good' />\n```\n\nAt the point of use, the children that are being _slotted into_ the Component should be wrapped in a `<slotted>` element specifying the name of the target `<slot>` in the `slot` attribute. When a `slot` name is not provided, `'default'` is assumed. When \n\n```tsx\n<slotted slot='good'>\n  <image width={88} height={88} margin={8} src='https://placecats.com/88/88' />\n</slotted>\n```\n\nPutting this all together, let's imagine a Component that exposes three slots with different colored backgrounds:\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nimport { HorizontalStack } from 'horizontal_stack/src/HorizontalStack';\n\nexport class GoodGreatBetterContainer extends Component {\n  onRender() {\n    <HorizontalStack>\n      <view backgroundColor='lightyellow'>\n        <label value='good:' />\n        <slot name='good' />\n      </view>\n      <view backgroundColor='lightgreen'>\n        <label value='great:' />\n        <slot name='great' />\n      </view>\n      <view backgroundColor='green'>\n        <label value='better:' />\n        <slot name='better' />\n      </view>\n    </HorizontalStack>;\n  }\n}\n```\n\nAnd now, we can use that Component to slot in three different images.\n\n> [!Note]\n> The order in which we're declaring the `<slotted>` doesn't matter\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nimport { GoodGreatBetterContainer } from 'goodgreatbetter_container/src/GoodGreatBetterContainer';\n\nexport class HelloWorld extends Component {\n  onRender() {\n    <GoodGreatBetterContainer>\n      <slotted slot='better'>\n        <image width={88} height={88} margin={8} src='https://placecats.com/200/200' />\n      </slotted>\n      <slotted slot='good'>\n        <image width={88} height={88} margin={8} src='https://placecats.com/210/210' />\n      </slotted>\n      <slotted slot='great'>\n        <image width={88} height={88} margin={8} src='https://placecats.com/220/220' />\n      </slotted>\n    </GoodGreatBetterContainer>;\n  }\n}\n```\n\n![Screenshot of component rendering named slots](./assets/core-slots/IMG_1457.jpg)\n\n## Performance Benefits\n\nSlots are not just a convenience; they are a key performance optimization in Valdi.\n\n### Slot Re-rendering\nWhen a parent component passes children to a child component via a slot, Valdi's Renderer can re-render those children independently. If the parent re-renders but the child component's own ViewModel hasn't changed, Valdi will:\n1. Re-render the content of the slot.\n2. Skip re-rendering the child component itself.\n\nThis \"surgical\" update significantly reduces the amount of TypeScript code that needs to execute and minimizes the blast radius of UI updates.\n\nFor a deeper look at how this works, see [Renderer Internals](./internals-renderer.md).\n"
  },
  {
    "path": "docs/docs/core-states.md",
    "content": "# Component State\n\nComponents have a unidirectional data flow model, similar to React. \n\nData flows from the parent component down to the children and changes are tracked to prevent unnecessary render thrashing. This is handled by passing view models \nand attributes down to children, which can then respond to the changes.\n\n\n## Unidirectional Data Flow\n\nConsumers can send a view model to a child using the view model shorthand syntax and the receiving component uses the view model to configure the view tree.\n\nThe view model is an [immutable](https://en.wikipedia.org/wiki/Immutable_object) object, so you can't modify it in a component or programmatically, it can only be provided in the `onRender()` function of the parent component.\n\nIf we need a component to update it's own visual state itself we'll need to use the \"State\" API.\n([more info below on how to use the setState API](#state)).\n\nLet's build a contrived label that takes a color and text property as its view model.\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nexport interface ColoredLabelViewModel {\n  text: string;\n  color: string;\n}\n\nexport class ColoredLabel extends Component<ColoredLabelViewModel> {\n  onRender() {\n    <label color={this.viewModel.color} value={this.viewModel.text} />;\n  }\n}\n```\n\nTo update or render the label, the parent simply specify the view-model for this label.\n\n```tsx\nexport class HelloWorld extends Component {\n  onRender() {\n    <layout padding={30}>\n      <ColoredLabel color='#FF0000' text='HelloWorld' />;\n    </layout>;\n  }\n}\n\n```\n\n![Screeshot of a component rendering a value provided to its view model](./assets/core-states/IMG_1449.jpg)\n\n## State\n\n**As a best effort rule of thumb, only views that have semantically changed are re-rendered. Components are re-rendered if any top-level properties in their view model changed since the last render from a parent.**\n\nOften times, Components need to track their own state that generally causes a re-render.\n\nTo do this, there is state management built into each Component as a special object called `state`.\n\nIn other words, state is similar to a view model, except it's private to the Component while view models are [immutable](https://en.wikipedia.org/wiki/Immutable_object) data models known to external users of a given component.\n\nState is also an [immutable](https://en.wikipedia.org/wiki/Immutable_object) object, but you can modify it by using `this.setState({ .. })` API which will cause your component to be re-rendered with that new state. \n\n> [!Note]\n> Under the hood, `setState()` uses the `Renderer.renderComponent()` API. This allows Valdi to re-render only the specific component that changed, rather than the entire tree, ensuring high performance for state updates.\n\n\n```tsx\n// Import the StatefulComponent\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\n// ViewModel + State interfaces for component\nexport interface TimerViewModel {\n  loop: number;\n}\ninterface TimerState {\n  elapsed: number;\n}\n// Component class\nexport class Timer extends StatefulComponent<TimerViewModel, TimerState> {\n  // Initialize the state\n  state = {\n    elapsed: 0,\n  };\n  // When creating the component, start a periodic logic\n  private interval?: number;\n\n  // Initialize the setInterval that will update state once a second incrementing\n  // the `elapsed` state value.\n  onCreate() {\n    this.interval = setInterval(() => {\n      // Increment the state to trigger a re-render periodically\n      this.setState({\n        elapsed: (this.state.elapsed + 1) % this.viewModel.loop,\n      });\n    }, 1000);\n  }\n\n  // When component is removed, make sure to cleanup interval logic\n  onDestroy() {\n    if (this.interval) {\n      clearInterval(this.interval);\n    }\n  }\n  // Render visuals will depend both on the state and the view model\n  onRender() {\n    <view padding={30} backgroundColor='lightblue'>\n      <label value={`Time Elapsed: ${this.state.elapsed} seconds`} />;\n      <label value={`Time Looping every: ${this.viewModel.loop} seconds`} />;\n    </view>;\n  }\n}\n```\n\nThis component can then be used like any other component:\n\n```tsx\nexport class HelloWorld extends Component {\n  onRender() {\n    <Timer loop={10} />;\n  }\n}\n```\n\n![Component rendering a value provided by its state](./assets/core-states/IMG_1450.jpg)\n"
  },
  {
    "path": "docs/docs/core-styling.md",
    "content": "# The Style<>\n\n## What is styling?\n\nYou may have noticed that most other examples we are using attributes to impact the rendering of specific components:\n\n```tsx\n<label\n  color='black' // We are using the attribute color to change the rendering of the label\n  value=\"HelloWorld\"\n/>\n```\n\nAny attribute applied on a native view is effectively styling that native view.\n\n## The Problem\n\nAs the complexity of our feature grow we might encounter things like this:\n\n```tsx\n<view\n  backgroundColor=\"white\"\n  flexDirection=\"row\"\n  justifyContent=\"center\"\n  alignItems=\"center\"\n  padding={10}\n  margin={10}\n  borderRadius={10}\n  boxShadow=\"0 8 11 rgba(0, 0, 0, 0.1)\"\n  // That's a lot of attributes\n  // ... There can even be more\n>\n</view>\n```\n\nOr obvious duplication of attributes group is also very common\n\n```tsx\n<view\n  // This view has a few attributes\n  backgroundColor=\"lightblue\"\n  boxShadow=\"0 8 11 rgba(0, 0, 0, 0.1)\"\n  padding={10}\n  margin={10}\n  borderRadius={10}\n>\n  <image /* ... *//>\n</view>\n<view\n  // This view is part of a different branch of the render tree\n  // It has different contents\n  // so we have to re-declare all our attributes\n  backgroundColor=\"lightred\"\n  // Even tho this view shares a lot of attributes\n  boxShadow=\"0 8 11 rgba(0, 0, 0, 0.1)\"\n  padding={10}\n  margin={10}\n  borderRadius={10}\n>\n  <label /* ... *//>\n</view>\n```\n\n## The `Style<>` Object to the rescue\n\nFortunately we have access to the `Style<T>` object the style object allows applying many attributes at once on a single view.\n\nSo:\n\n```tsx\nconst myStyle = new Style<View>({\n  backgroundColor: \"lightblue\",\n  width: 100,\n  height: 100,\n});\n<view style={myStyle}/>\n```\n\nIs equivalent to:\n```tsx\n<view\n  backgroundColor=\"lightblue\"\n  width={100}\n  height={100}\n/>\n```\n\nSo this will be useful for styling large amount of elements and improve reuseability\n\n## The `Style<>` In Example\n\n```tsx\n// Let's import the attribute interfaces for each type of\nimport { Layout, View } from 'NativeTemplateElements';\nimport { Style } from 'valdi_core/src/Style';\n// Let's declare our groups of attributes that we know will be used together\nconst styles = {\n  // This is a Style<View> so it can only be applied on <view>\n  container: new Style<View>({\n    backgroundColor: 'lightgrey',\n    flexDirection: 'row',\n    flexWrap: 'wrap',\n  }),\n  // This is a Style<Layout> so it can only be applied on <layout>\n  // (note that a <view> is also a <layout>)\n  square: new Style<Layout>({\n    height: 100,\n    width: 100,\n  }),\n  // We can make simple styles that we can combine later\n  withMargin: new Style<Layout>({\n    margin: 10,\n  }),\n  withPadding: new Style<Layout>({\n    padding: 10,\n  }),\n  withRounded: new Style<View>({\n    borderRadius: 10,\n  }),\n};\n\n// Note that Styles<> can be combined!\n\n// Using Style.merge\nconst itemStyle = Style.merge(styles.square, styles.withMargin, styles.withPadding, styles.withRounded);\n// Using Style.extend\nconst imageStyle = styles.withRounded.extend({\n  height: '100%',\n  width: '100%',\n});\n\n// We can then build a component that can uses those group of attributes (called Style(s))\nexport class HelloWorld extends Component {\n  onRender() {\n    // And now we can re-use those styles on many different elements in the same template!\n    <view style={styles.container}>\n      <view style={itemStyle} backgroundColor='lightgreen'>\n        <image style={imageStyle} src='https://placedog.net/500' />\n      </view>\n      <view style={itemStyle} backgroundColor='lightpink'>\n        <image style={imageStyle} src='https://placedog.net/500' />\n      </view>\n      <view style={itemStyle} backgroundColor='lightblue'>\n        <image style={imageStyle} src='https://placedog.net/500' />\n      </view>\n    </view>;\n  }\n}\n```\n<img src=\"assets/core-styling/IMG_1469.jpg\" align=\"right\" width=\"250\" border=\"5\" />\n\n## The Good, the Style and the Attribute\n\nAn important property of the Style object is that it will always be overrwritten by any attributes set on the element:\n\n```tsx\nconst myStyle = new Style<View>({\n  height: 100,\n  width: 100,\n  backgroundColor: 'red',\n});\n// height: 100, width: 100, backgroundColor: red\n<view style={myStyle}/>;\n// height: 100, width: 100, backgroundColor: blue\n<view style={myStyle} backgroundColor='blue'>;\n```\n\nThat way you can define any immutable values in your style and then dynamically override any dynamic value using a regular attribute.\n\n## Performance considerations\n\nNote that styles are the perfect usecase for static and invariant attributes but should generally be avoided to be instantiated during rendering, for example:\n\n```tsx\n// GOOD (at init-time)\nconst myCheapStyle = new Style<View>({\n  width: 100,\n  height: 100,\n  backgroundColor: 'red',\n});\n// GOOD also (at init-time)\nconst myCheapStyle2 = myCheapStyle.extend({})\nconst myCheapStyle3 = Style.merge(myCheapStyle, myCheapStyle2);\n\n/**\n * Here is what to avoid\n */\nclass MySlowComponent {\n  onRender() {\n    // BAD - this will be an expensive call (with memory allocation and everything)\n    const myExpensiveStyle = new Style<View>({\n      width: 100,\n      height: 100,\n      backgroundColor: 'blue',\n    });\n    // BAD - merging or extending styles is also equivalent to instantiating a new Style\n    const myExpensiveStyle2 = myExpensiveStyle.extend({})\n    const myExpensiveStyle3 = Style.merge(myExpensiveStyle, myExpensiveStyle2);\n    // height: 100, width: 100, backgroundColor: red\n    <view style={myCheapStyle}/>;\n    // height: 100, width: 100, backgroundColor: blue\n    <view style={myExpensiveStyle}/>;\n  }\n}\n\n/**\n * Here is what to do instead\n */\nclass MyFastComponent {\n  onRender() {\n    // height: 100, width: 100, backgroundColor: red\n    <view style={myCheapStyle}/>;\n    // height: 100, width: 100, backgroundColor: blue\n    <view style={myCheapStyle} backgroundColor='blue'/>;\n  }\n}\n```\n\nNote that managing and manipulating styles is fine as long as we're not creating any new one:\n\n```tsx\n// Statically, we'll create all the styles we need at initialization\nconst item = new Style<View>({\n  width: 100,\n  height: 100,\n});\nconst styles = {\n  itemSelected: item.extend<View>({\n    backgroundColor: 'blue'\n  }),\n  itemDeselected: item.extend<View>({\n    backgroundColor: 'white'\n  }),\n}\n// Dynamically we'll use our existing styles\ninterface State {\n  selected: boolean;\n}\nclass MyFastComponentWithLogic extends StatefulComponent<State> {\n  onRender() {\n    // this is fast, no style creation here\n    <view style={this.state.selected ? styles.itemSelected : styles.itemDeselected}/>\n  }\n}\n```\n\n## TLDR\n\n- DO use Style for batches of static attributes\n- using Style is extremely fast (faster than attributes)\n- **Style Interning**: The first time a style instance is sent to the native runtime, it is assigned a unique integer identifier. Subsequent uses of the same style object only require passing this ID, drastically reducing marshalling overhead. This is why you should reuse style objects instead of creating them on the fly.\n- instantiating/merging/extending Style is costly, don't do it at render-time\n- instantiating/merging/extending Style should be done once, at initialization or lazy loaded\n- use attributes for any dynamic value\n- you can also swap styles for dynamic values with limited granularity\n\n## Complete Style Attributes Reference\n\nFor a comprehensive list of all attributes that can be used in styles for each element type, including Yoga flexbox properties, see the [Style Attributes Reference](../api/api-style-attributes.md).\n"
  },
  {
    "path": "docs/docs/core-text.md",
    "content": "# The `<label>` and Text\n\n## Components\n\nFor text rendering and editing, we have a few core components able to display text and to accept end user input.\n\nFor translations, look at [Localization](./advanced-localization.md). \n\n#### Label\nThe `<label />` is the default for displaying text - this component supports displaying either a single line or multiple lines of text. It offers various styling options, including adjustments to the font, text color, alignment, and autoscaling.\n\n> [!Note]\n> The layout engine relies on the UI backend for measuring labels. This means that the dimensions of a `<label>` are calculated by the native platform (iOS/Android) based on the provided font and text content, ensuring accurate layout across different devices.\n\n#### TextField\nThe `<textfield />` is the default for editing text in one line - this component only supports editable text in a single line. This and textview support options like placeholder, text editing configurations, and keyboard and selection settings.\n\n#### TextView\nThe `<textview />` is the component for editing text in multiline.\n## Common Properties\n\n#### value\nThis is how we set the text to be displayed, and can accept a string (directly or through localization) or [`AttributedText`](../../src/valdi_modules/src/valdi/valdi_tsx/src/AttributedText.d.ts).\n\n#### Styling\n\nText components can be directly styled via `style`, or via specific text attributes:\n\n- [Common attributes for all text][../../src/valdi_modules/src/valdi/valdi_tsx/src/NativeTemplateElements.d.ts#L1385]\n- [Label attributes][../../src/valdi_modules/src/valdi/valdi_tsx/src/NativeTemplateElements.d.ts#L1438]\n- [Text editor attributes][../../src/valdi_modules/src/valdi/valdi_tsx/src/NativeTemplateElements.d.ts#L1013]\n\n### EditTextEvents\n\nText editing is done via a callback on `onChange`, and associated callbacks `onWillChange`, `onSelectionChange`, and so on. [These receive an EditTextEvent](./core-events.md#Events).\n\n## Attributed Text \n\nAttributed text allows end users to style individual pieces of text within a larger paragraph/block, building complex attributed text objects by supplying different styling attributes. This does not support Android-like spannables merging multiple spans, instead an user must individually construct all chunks with the applicable styles applied.\n\nThis uses [`AttributedTextBuilder`](../../src/valdi_modules/src/valdi/valdi_core/src/utils/AttributedTextBuilder.ts) to build a set of text chunks with the following methods:\n\n`AttributedTextBuilder` - base constructor method, exposes an `AttributedTextBuilder` instance for the following operations\n\n`append`: `(text: string, attributes: AttributedTextAttributes) => AttributedTextBuilder` - standard text chunk addition method, which supports appending a text string and its styles simultaneously \n\n`appendText`: `(text: string) => AttributedTextBuilder` - adds only text, keeping the styling from the base component\n\n`appendStyled`: `(styled: AttributedTextStyled) => AttributedTextBuilder` - functionally the same as `append`, with `{ content: string (text), attributes: AttributedTextStyle }` as a single parameter\n\n`withStyle`: `(attributes: AttributedTextAttributes, callback: (textBuilder: AttributedTextBuilder) => void) => AttributedTextBuilder` - decorator function for all nested calls to `AttributedTextBuilder` within a callback, to apply the same styles within\n\n`build`: `() => AttributedText` - must be called to create an `AttributedText` to pass into `value`\n\nAttributed text can take the following [`AttributedTextAttributes`](../../src/valdi_modules/src/valdi/valdi_tsx/src/AttributedText.d.ts#L6) options per chunk:\n```\nfont?: string;\ncolor?: string;\ntextDecoration?: LabelTextDecoration;\nonTap?: AttributedTextOnTap;\nonLayout?: AttributedTextOnLayout; // receives the full size of the attributed text chunk\noutlineColor?: string; // note that both width and color are required for outline\noutlineWidth?: number;\n```\n\n### Examples\n\n```js\nimport { AttributedTextAttributes } from 'valdi_tsx/src/AttributedText';\nimport { AttributedTextBuilder } from 'valdi_core/src/utils/AttributedTextBuilder';\nimport { TextStyleFont } from 'widgets/src/styles/TextStyleFont';\nimport { Spacing } from 'widgets/src/styles/spacing';\n\nconst attributedTextBuilder = new AttributedTextBuilder();\nattributedTextBuilder.pushFont(TextStyleFont.BODY);\n\nconst title1: AttributedTextAttributes = {\n  color: 'red',\n  textDecoration: 'underline',\n  font: TextStyleFont.TITLE_4,\n};\nconst title2: AttributedTextAttributes = {\n  color: 'blue',\n  font: TextStyleFont.BODY_EMPHASIS,\n};\nconst body: AttributedTextAttributes = {\n  color: 'green',\n};\n\nattributedTextBuilder.append('attributed', title1);\nattributedTextBuilder.append(' text:', title2);\nattributedTextBuilder.append('\\n');\n\nattributedTextBuilder.append(loremIpsum, body);\n\nattributedTextBuilder.pop();\n```\n```tsx\n<layout padding={Spacing.XS}>\n  <label value={attributedTextBuilder.build()} numberOfLines={3} />\n</layout>;\n```\n![Screenshot of attributed text rendering styled text](./img/docs/core-attributed-text-example.png)\n\n## Complete API Reference\n\nFor a comprehensive list of all properties and methods available on `<label>`, `<textfield>`, and `<textview>` elements, including all text styling, keyboard configuration, callbacks, and editing behaviors, see the [API Reference](../api/api-reference-elements.md):\n- [Label API](../api/api-reference-elements.md#label)\n- [TextField API](../api/api-reference-elements.md#textfield)\n- [TextView API](../api/api-reference-elements.md#textview)\n"
  },
  {
    "path": "docs/docs/core-touches.md",
    "content": "# Touches and Gestures\n\n## Background\nCurrently, Valdi owns three primary rendering engines - iOS, Android, and SnapDrawing (Android primarily, but also desktop macOS), and each of them has a different implementation of gestures.\n\niOS relies on the default UIGestureRecognizer system, where we extend the existing listeners to allow us to call marshaled JS functions directly based on the events emitted from UIKit.\n\nAndroid and SnapDrawing rely on our custom implementation in Kotlin and C++, respectively, where we take Android-level events and pass them onto our own TouchDispatcher system, where we locate potential touch candidates and execute any recognizers we find. We attempt to mimic iOS as the primary source of truth. \n\nWe’ve taken this approach historically to fit with Valdi’s model of integrating seamlessly with native. \n\n[The `TouchEvent` forms the basis of any touch actions.](./core-events.md#Events)\n\n## Gesture Recognizers \n\nIn general, each of the gestures other than onTouch consist of a `on<Gesture>` function, an `<Gesture>Enabled` boolean, and a `on<Gesture>Predicate` function. The enabled and predicates determine whether a gesture should or should not run.\n\nWe first gather a list of potential candidates for gesture recognizers. When determining what element/node’s gestures should be run - the top most in the visible plane is the first one selected. If it’s enabled and the predicate (if it exists) returns true, that action will be fired, and we prevent conflicting gestures on additional elements after.\n\nWe support the following actions:\n\n#### onTouch\nCalled whenever a view is touched.\n\nThis can always be run, hitting all parents/siblings in the view hierarchy - note that for a continuous gesture the initial start point of a pointer determines the `onTouch`,\n\nWe use `onTouchDelayDuration` specifically for `onTouch`, to ensure onTouches are only fired after a short time during say, a scroll event inside a ScrollView,\n\n#### onTap\nCalled whenever a view is tapped, and only when we know it is not receiving a double tap or long press.\n\n#### onDoubleTap\nCalled whenever a view is double (or more) tapped.\n\n#### onLongPress\nCalled whenever a view is pressed and held.\n\nWe use `longPressDuration` to configure the time until the callback is triggered.\n\n#### onDrag\nCalled whenever a view is dragged continuously, by one or more pointers.\n\nThis can be run simultaneously with onRotate and onPinch\n\n#### onRotate\nCalled whenever a view is rotated continuously, by two or more pointers.\n\nThis can be run simultaneously with onDrag and onPinch\n\n#### onPinch\nCalled whenever a view is pinched continuously, by two or more pointers.\n\nThis can be run simultaneously with onDrag and onRotate\n\n#### Additional Configuration\n`touchAreaExtension`\nUsed to expand the touchable surface area to recogize gestures from\n\n\n## Technical Documentation\n\n- [First party docs on the iOS responder chain](https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/using_responders_and_the_responder_chain_to_handle_events?language=objc)\n\n- [First party docs on the iOS recognizer state machine](https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/implementing_a_custom_gesture_recognizer/about_the_gesture_recognizer_state_machine)\n\n- [TouchDispatcher on Android](../../valdi/src/java/com/snap/valdi/views/touches/TouchDispatcher.kt)\n"
  },
  {
    "path": "docs/docs/core-video.md",
    "content": "# The `<video>`\n\n## Introduction\n\nValdi supports video playback through the `<video>` element in TSX.\n\n> [!Note]\n> The `<video>` element is implemented as a **Custom View Class**. Because implementing a video player from scratch in TypeScript would be slow and impractical, Valdi leverages the native video player implementations on iOS and Android. TypeScript provides the configuration (source, volume, seek time), while the native platform handles the high-performance rendering and decoding.\n\nUnlike with images, Valdi does not support videos in the `res/` folder. We recommend you do not bundle videos for app size reasons.\n\nBy default the tag supports `https` and local `file` objects.\n\n## Using `<video>`\n\n\n```tsx\nimport { StatefulComponent } from 'valdi_core/src/Component';\nimport { CoreButton, CoreButtonColoring, CoreButtonSizing } from 'widgets/src/components/button/CoreButton';\n\nexport class VideoExample extends StatefulComponent<{}, State> {\n  state: State = { volume: 0, playbackRate: 1, playbackPct: 0 };\n\n  private videoLength?: number;\n\n  onRender(): void {\n    <view style={styles.root}>\n      <view style={styles.container} width={`100%`}>\n        <view width={200} height={200}>\n          <video\n            style={videoStyle}\n            volume={this.state.volume}\n            seekToTime={this.state.seekToTime}\n            playbackRate={this.state.playbackRate}\n            onVideoLoaded={this.onVideoLoaded}\n            onBeginPlaying={this.onBeginPlaying}\n            onError={this.onVideoError}\n            onCompleted={this.onCompleted}\n            onProgressUpdated={this.onProgressUpdated}\n            src='https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4'\n          ></video>\n          <view style={controlsStyle}>\n            <CoreButton\n              sizing={CoreButtonSizing.SMALL}\n              coloring={CoreButtonColoring.SECONDARY}\n              onTap={this.onPlayTapped}\n              icon={res.play}\n            />\n            <layout width='140' alignItems='center' flexDirection='row' padding='10'>\n              <Slider onChange={this.onSeek} initialValue={this.state.playbackPct} />\n            </layout>\n          </view>\n        </view>\n        <layout width={200}>\n          <label value='Volume'></label>\n          <Slider onChange={this.onVolumeChanged} initialValue={0} />\n        </layout>\n      </view>\n    </view>;\n  }\n\n  private onVideoLoaded = (duration: number): void => {\n    this.videoLength = duration;\n  };\n\n  private onSeek = (value: number): void => {\n    if (this.videoLength) {\n      this.setState({ seekToTime: this.videoLength * value });\n    }\n  };\n\n  private onVolumeChanged = (value: number): void => {\n    this.setState({ volume: value });\n  };\n\n  private onPlayTapped = (): void => {\n    this.setState({ playbackRate: this.state.playbackRate < 1 ? 1 : 0 });\n  };\n\n  private onBeginPlaying = (): void => {\n    console.log('onBeginPlaying');\n  };\n\n  private onVideoError = (error: string): void => {\n    console.log('onError ' + error);\n  };\n\n  private onCompleted = (): void => {\n    console.log('onCompleted');\n  };\n\n  private onProgressUpdated = (time: number, duration: number): void => {\n    let progress = 0;\n    if (this.videoLength) {\n      progress = time / this.videoLength;\n    }\n    this.setState({ playbackPct: progress });\n  };\n}\n```\n\n> [!NOTE]\n> URLs must be HTTPS, HTTP is unsecured and typically automatically blocked\n\n## Custom video loading\n\nIf you need a different data format for more functionality from the video player, you can do that by building a \ncustom video loader.\n\n## Complete API Reference\n\nFor a comprehensive list of all properties and methods available on `<video>` elements, including playback control, volume, seeking, and all callbacks, see the [API Reference](../api/api-reference-elements.md#videoview).\n"
  },
  {
    "path": "docs/docs/core-views.md",
    "content": "# The `<layout>` and `<view>`\n\n## Understanding `<layout>` and `<view>`\n\nLayout and Views are the basic building blocks of any Valdi feature.\n\n`<layout>` is an invisible rectangular container that is used to configure the layout of the elements within it. It does not emit a resulting platform view (UIView/android.View) instance.\n\n`<view>` is the main element for building a UI which emits an actual native platform view (`UIView`/`android.View`) instance that can be rendered.\n\n![Sketch of layout and view dimensions](./img/docs/core-views-example.png)\n\n\nHere is a quick comparison of their feature set.\n\n**What are they:**\n- `<layout>` is a simple invisible rectangular container\n- `<view>` is a simple rendered rectangular container\n\n**What they can do:**\n- a `<layout>` can only apply the flex layout\n- a `<view>` can: render a background color, render a border, receive tap events\n\n**What do they do:**\n- each `<layout>` is invisible and lives only in memory of the Valdi runtime\n- each `<view>` generates a native view (depending on the platform)\n\n**Advanced Attributes:**\n- `extendViewportWithChildren`: Impacts how the runtime treats the node in a specific update pass.\n- `zIndex`: Controls the rendering order of overlapping elements.\n\n**What they feel like:**\n- a `<layout>` is the most basic building block\n- a `<view>` is a `<layout>` that also generate a native view in its frame\n\n**Also useful to know:**\n- a `<label>` is a `<view>` that also renders text\n- a `<image>` is a `<view>` that also renders images\n- a `<spinner>` is a `<view>` that also renders a loading indicator\n- a `<scroll>` is a `<view>` whose children will be scrollable inside of it\n\nYou will be able to learn how to use `<scroll>`, `<image>` and `<slot>` in following dedicated pages\n\n## Performances considerations\n\n### Real views\n\nWhen using `<view>`/`<image>`/`<label>`/`<scroll>`, it will translate to an actual:\n\n- `UIView` (and proper subclass) on iOS\n- `View` (and proper subclass) on Android\n\nThis is necessary to render pixels on the screen.\n\nHowever those are the most costly elements in the Valdi framework.\n\nIt is then important to always try to minimize the number of total \"Real views\" being rendered on a screen\n\n### Faster in-memory only element: the `<layout>`\n\nThat's where the `<layout>` comes to the rescue,\nsometimes when manipulating the layout of a page or feature,\nit is useful to use wrapping elements and container elements to manipulate the flexbox layout.\n\nIn this case it would be preferable to use `<layout>` instead\nbecause those are extremely cheap:\n\n- they will be taken into account when computing the flexbox layout\n- they will NOT generate any view/layer/drawable\n- they will NOT even be sent to the android/iOS code\n\n### Key Takeaways\n\n- 1) Always try to use layout over views when possible.\n- 2) For visible elements, views are necessary, and that's ok.\n\n## Complete API Reference\n\nFor a comprehensive list of all properties and methods available on `<layout>` and `<view>` elements, see the [API Reference](../api/api-reference-elements.md).\n"
  },
  {
    "path": "docs/docs/export-model-vs-export-proxy-marshalling.md",
    "content": "# @ExportModel vs @ExportProxy: Marshalling Guide\n\nThis document explains the difference between `@ExportModel` and `@ExportProxy` in the Valdi compiler, with emphasis on **marshalling** (passing values across the TypeScript–native boundary). Using the wrong marshalling API for a type can cause subtle runtime bugs.\n\n## Summary\n\n| Aspect | @ExportModel | @ExportProxy |\n|--------|--------------|--------------|\n| **TypeScript** | Class or interface (bag of properties) | Interface only (callable contract) |\n| **Native semantics** | Generated **concrete class** with fields | Generated **protocol/interface**; native **implements** it |\n| **Marshalling** | Serialize **field values** so the other side can reconstruct an equivalent object | Register a **proxy** so the other side can **call methods** on this instance |\n| **Wrong marshalling** | N/A | Passing a proxy to model marshalling serializes the wrong thing and breaks behavior |\n\n---\n\n## @ExportModel: Data Objects\n\n- **Purpose**: Represent a **data shape**—a container of properties (and optional callbacks) that can be copied across the boundary.\n- **Generated native code**: A **concrete class** (e.g. `SCMyContext`) that extends `SCValdiMarshallableObject` (iOS) or equivalent on Android. The class has storage for each property and a descriptor that describes its fields.\n- **Marshalling**: The object is marshalled by **serializing its fields** (and function references) into the marshaller. On the other side, an equivalent object can be **reconstructed** from that data.\n\n**When to use**: View models, context objects, configs, DTOs—anything that is conceptually “a bag of data” that can be copied.\n\n---\n\n## @ExportProxy: Callable Interfaces\n\n- **Purpose**: Represent a **contract** that native code implements—an interface with methods (and optionally properties) that TypeScript can call. The “value” passed across the boundary is not copied; it is a **handle** to the implementation so the other side can invoke methods.\n- **Generated native code**:\n  - **Protocol** (iOS) / **interface** (Android) that native must implement.\n  - A **proxy class** (e.g. `SCMyService`) used by the runtime to represent the TypeScript side of the proxy.\n  - A **free function** (ObjC only) to marshal an implementation instance, e.g. `NSInteger SCMyServiceMarshall(SCValdiMarshallerRef marshaller, id<SCMyService> instance)`.\n- **Marshalling**: The implementation instance is **not** serialized field-by-field. Instead, marshalling **registers a proxy** in the marshaller so that when the other side receives it, they get a handle that forwards method calls back to this instance.\n\n**When to use**: Services, fetchers, delegates, launchers—anything that is “something you call” rather than “something you copy.”\n\n---\n\n## Marshalling APIs by Platform\n\n### Swift and Kotlin\n\nBoth **models** and **proxies** conform to the same marshalling protocol (`ValdiMarshallable` / `push(to:)` / `pushToMarshaller`). The generated code internally does the right thing:\n\n- **Model**: `push` serializes the object’s fields.\n- **Proxy**: `push` registers the instance as a proxy (e.g. via `marshaller.pushProxy(object: self)` or equivalent).\n\nSo in Swift/Kotlin you do **not** need to choose a different API; calling `push(to: marshaller)` (or the Kotlin equivalent) is correct for both.\n\n### Objective-C\n\nObjective-C does **not** have protocol extensions that can provide a single `pushToValdiMarshaller:` implementation for both cases. So:\n\n- **@ExportModel**: The generated **class** extends `SCValdiMarshallableObject` and implements `pushToValdiMarshaller:`. You marshal by calling:\n  ```objc\n  SCValdiMarshallableObjectMarshall(marshaller, modelInstance);\n  ```\n  This is correct for **data objects only**.\n\n- **@ExportProxy**: There is **no** single method on the protocol that marshals “as a proxy.” The compiler emits a **free function** per proxy type, e.g.:\n  ```objc\n  NSInteger SCMyServiceMarshall(SCValdiMarshallerRef marshaller, id<SCMyService> instance);\n  ```\n  You **must** use this generated function to marshal a proxy. Under the hood it calls `SCValdiMarshallableObjectMarshallInterface(marshaller, instance, [SCMyService class])`, which registers the instance as a proxy by **interface**, not by copying fields.\n\n---\n\n## The Bug: Using Model Marshalling for a Proxy\n\n**Wrong (and dangerous):**\n\n```objc\n// productFetcher is an id<SCCPlusIapProductFetcher> (an @ExportProxy type)\nSCValdiMarshallableObjectMarshall(marshaller, productFetcher);\n```\n\n- `SCValdiMarshallableObjectMarshall` expects an `SCValdiMarshallableObject *`. It marshals the object by **field layout** (using the object’s class descriptor). So it only makes sense for **@ExportModel** types.\n- If the native implementation class (e.g. `ProductFetcher`) is made to **subclass** `SCValdiMarshallableObject` so that the call compiles, then:\n  - The compiler accepts the code.\n  - At runtime, the object is marshalled as if it were a **model** (field-by-field). For a proxy, the “fields” are not the intended representation; the other side expects a **proxy handle**, not a reconstructed data object.\n  - Result: incorrect behavior, missing calls, or subtle bugs on the TypeScript or other side.\n\n**Correct:**\n\n```objc\nSCCPlusIapProductFetcherMarshall(marshaller, productFetcher);\n```\n\nSo for **any** `@ExportProxy` type, always use the **generated** `SC<Name>Marshall(marshaller, instance)` function, and **never** use `SCValdiMarshallableObjectMarshall` for proxy instances.\n\n---\n\n## Rule of Thumb\n\n- **Data object (model)** → use `SCValdiMarshallableObjectMarshall(marshaller, object)` (or the object’s `pushToValdiMarshaller:` in ObjC, or `push(to:)` in Swift).\n- **Proxy (interface implementation)** → use the **generated** `SC<ProxyName>Marshall(marshaller, instance)` in Objective-C; in Swift/Kotlin, use the normal `push(to:)` / `pushToMarshaller` and the generated code will choose the right path.\n\n---\n\n## Native Implementation Guidelines for @ExportProxy (iOS)\n\n1. **Do not** make your implementation class extend `SCValdiMarshallableObject` (or `SCValdiProxyMarshallableObject`) just to satisfy a call to `SCValdiMarshallableObjectMarshall`. That is a sign you are using the wrong API.\n2. **Do** implement only the generated protocol (e.g. `<SCCPlusIapProductFetcher>`).\n3. **Do** marshal your implementation using the generated free function, e.g. `SCCPlusIapProductFetcherMarshall(marshaller, self)` (or the appropriate type name for your proxy).\n\n---\n\n\n## Related\n\n- [Annotations (native-annotations.md)](native-annotations.md) – Full list of `@ExportModel` and `@ExportProxy` and other annotations.\n- [Native bindings (native-bindings.md)](native-bindings.md) – How generated types are used across the boundary.\n"
  },
  {
    "path": "docs/docs/faq.md",
    "content": "# Frequently Asked Questions\n\n## Why did Snap create this?\n\nThe Snapchat iOS and Android applications are meant to be basically exactly the same, with identical designs. This is a trend in that has become very common in the industry. Whereas initially many applications had different designs and user experience on each application, over time these differences faded, and nowadays for many companies, difference of application behaviors between iOS and Android are merely just a result of the codebase being implemented by different engineers and technologies rather than conscious design choices. This observation is why code sharing for both business logic and UI is so attractive on paper for many companies, including Snap.\n\nIt is often thought that cross-platform UI frameworks come with many trade-offs, and that cross-platform applications tend to perform worse or offer a less polished experience than platform native codebases. This is an unacceptable trade-off for Snap. Any use of cross-platform had to come with minimal or no trade-offs on application quality and performance.\n\nWe created Valdi because we believed there was an opportunity to increase developer velocity for mobile developers at Snap without reducing application quality, and that we didn't find, especially at the time, any other open source solutions that could check all our boxes. Some of these boxes were:\n\n- Performance comparable to a native UI in most scenarios.\n- Strong consistency between iOS and Android.\n- Scalable by design, startup latency doesn't increase as codebase grows.\n- Low application size impact, both initially and incrementally as codebase grows.\n- Low bar to entry for mobile developers (easy to learn, easy to onboard, hard to use inefficiently).\n- Can be efficiently adopted to render full page components as well as tiny components inside an existing native UI.\n- Platform native and type safe API generation.\n\n## How much is Snap using Valdi?\n\nValdi is used on almost every Snapchat screen: sometimes to render some smaller components as part of an otherwise UI implemented in Swift or Objective-C, sometimes to render the entire screen. Some features are just service layers written using Valdi and don't have any UI. Teams at Snap can choose to adopt Valdi or not based on their use cases and whether they believe Valdi is the right solution for them. Throughout the years, the team working on Valdi has worked with its customers to make this technology useable in more and more use cases. There are close to 2 million lines of TypeScript written by Snap engineers using Valdi.\n\n## Why use Valdi instead of React Native?\n\nWhen we started Valdi, we actually had no intention of making it a React Native competitor. It was initially a small framework, with a clear set of use cases it was meant to help with. We wanted the framework to be really good at solving these use cases knowing that developers would have to initially resort to a large amount of platform native code. Over time, as we kept adding more and more features, Valdi became similar to React Native, although with a different development vision and implementation.\n\nReact Native and Valdi are quite similar in how they work, at their core they are each development platforms allowing users to write their UI in TypeScript, with the backing UI system ultimately using platform native UI components. React Native is more web centric and more compatible with web technologies in general. Valdi breaks with web standards when that enables optimizations that can improve performance on mobile, or when it lowers the bar to entry to mobile engineers. For example, the module loader in Valdi is lazy by default, where dependency module files only actually get imported when they get used for the first time, rather than when their dependent modules get loaded. This solves a common pain point that many companies had where as codebase grew, so did the load time for the main application bundle. In Valdi, each module is independant, there is not a `main.jsbundle`. In Valdi, modules build with Bazel, and native code is an integral part of applications that are built using it. The list of differences is very long, and it'd take many pages to list them all out. The sum of these differences all add up to a technology that was ultimately possible to integrate in so many surfaces on Snapchat.\n\nReact Native is a fantastic technology and we don't claim Valdi is strictly superior to it. We chose a different set of trade-offs for Valdi to make it work at Snap, and other projects might also find these trade-offs desirable. The main target audience for Valdi are developers that have strong requirements for performance and scalability and/or have an existing native application and want to efficiently use some cross-platform business logic or UI.\n\n## Why using TypeScript instead of my favorite language?\n\nIn its early days, the Valdi team experimented with a few different user-facing languages, including Kotlin and Swift. TypeScript was eventually chosen for the following reasons:\n\n- it was easy to integrate at runtime on both iOS and Android, since there are many integrable open source JS engines.\n- it was decently easy to implement a responsive hot reloader on top of it. Hot reloading was a killer feature for us that we were not willing to part way with.\n- it was easy to learn by mobile developers.\n- it was supported equally well by tooling on macOS and Linux.\n- it didn't require the use of a massive IDE to edit source code effectively.\n- it compiled into modules that use very little app size.\n- It is widely adopted, and its adoption kept growing.\n\nWe thought that TypeScript provided the best trade-offs for what we were aiming for. We still believe today it was the right choice.\n\n## What are the trade-offs?\n\nYou will find below a non exhaustive list of trade-offs.\n\nCompared to platform native (native iOS and Android application):\n\n- Incomplete access to some platform specific features, which will require to write and integrate platform native code\n- Harder to make use of the best that each individual platform has to offer\n- Not officially supported by Apple and Google\n- Potentially harder to hire experienced engineers\n- Mobile engineers sometimes prefer Swift/Kotlin\n- Debuggability worse in some scenarios\n- Lower performance ceiling (how fast the application can run if you have unlimited budget for optimizing the application code)\n\nCompared to React Native:\n\n- While APIs look similar, it's not React\n- Not compatible with the vast set of already published libraries\n- Not as mature\n- Supported by a smaller company than Meta\n- Much smaller community\n\n## How does it work?\n\nAt build time, the Valdi compiler packages a Valdi module into .valdimodule file, which contains the compiled TS code. An application can contain many .valdimodule files, Snapchat had around 600 in late 2025. Code can be packaged in 3 different ways:\n\n- JS source: TS code compiled with the TS compiler, then minified.\n- JS bytecode: TS code compiled with the TS compiler, minified, then compiled as bytecode ahead of time. This is the default output mode.\n- Native: TS code compiled to C, then compiled to native with clang. When this mode is used, the .valdimodule doesn't contain the compiled code, the native code is compiled within the application binary itself (or within the main .so dynamic library bundled in the application on Android).\n\nJS source and bytecode gets interpreted by a JS engine at runtime. Supported engines are JavaScriptCore, QuickJS and Hermes. When compiled as native, the code integrates within the QuickJS engine (arrays end up using JS engine arrays). There is complete and \"toll-free\" interop between modules compiled as JS source, JS bytecode and native.\n\nTSX code gets transformed into TS by a special compiler step. The XML statements (like `<view>`, `<MyComponent>` etc...) get converted into Valdi renderer statements like `jsx.beginElement(__viewNodePrototype)`, `jsx.beginComponent(__myComponentPrototype)`. Unlike in React, XML expressions return `void` in Valdi. This is because they mutate the renderer stack when invoked, as opposed to creating objects that need to be diffed. This difference allows Valdi to better control the render flow which made it possible to implement several optimizations that would have been difficult to do in React, and it also reduces how much work happen during render in the first place especially on incremental renders.\n\nThe Valdi runtime is able to process the render output and emit native backing views for each element that need one, that means creating `UIView`, `UILabel` instances on iOS or `ViewGroup`, `TextView` on Android for example. The interaction between the TS code and the runtime is thus highly dynamic, the runtime tries to populate the view hierarchy in the most efficient way based on the TS output. There was extensive work to make this interaction as efficient as possible.\n"
  },
  {
    "path": "docs/docs/glossary.md",
    "content": "# Glossary\n\nA comprehensive guide to Valdi terminology and concepts.\n\n## A\n\n### Annotation\nTypeScript decorator used by the Valdi compiler to generate native code. Examples: `@ExportModel`, `@Context`, `@ViewModel`. See [Native Annotations](./native-annotations.md).\n\n### Asset\nA resource file (image, font, video, etc.) bundled with a Valdi module. Can be referenced using the `Asset` type. See [Images](./core-images.md).\n\n## B\n\n### Bridge / Bridging\nThe mechanism for passing data and invoking methods between TypeScript/JavaScript and native (iOS/Android) code. A \"bridged\" architecture uses native implementations for data/services. See [Native Bindings](./native-bindings.md) and [Full Stack Valdi](./advanced-full-stack.md).\n\n### BUILD.bazel\nThe Bazel build configuration file for a Valdi module. Replaces the deprecated `module.yaml`. See [Valdi Module](./core-module.md).\n\n## C\n\n### Component\nA reusable UI building block implemented in TypeScript. Components have lifecycle methods and can contain other components or elements. See [The Mighty Component](./core-component.md).\n\n### Component Context\nData and services passed from native code to a Valdi component at instantiation time. Used to provide platform-specific functionality. See [Component Context](./native-context.md).\n\n### ComponentDisposable\nA function or RxJS Subscription that can be registered with `registerDisposable()` to be automatically cleaned up when a component is destroyed.\n\n### Custom View\nA native iOS or Android view wrapped for use in Valdi templates using the `<custom-view>` element. See [Custom Views](./native-customviews.md).\n\n## D\n\n### Declarative Rendering\nA programming paradigm where you describe *what* the UI should look like based on state, rather than *how* to update it. Valdi uses TSX to declaratively define UI.\n\n### Diff Algorithm\nThe process Valdi uses to compare the previous and current render output to determine what changed and needs to be updated in the native UI.\n\n## E\n\n### Element\nA native UI primitive provided by Valdi, such as `<view>`, `<label>`, `<image>`. Elements are lowercase and backed by native views. See [API Reference](../api/api-reference-elements.md).\n\n### Element Reference\nA way to get direct access to a native element instance from TypeScript. See [Element References](./advanced-element-references.md).\n\n### ExportModel\nAn annotation that marks a TypeScript interface or class to be exported to native code. See [Native Annotations](./native-annotations.md).\n\n### ExportProxy\nAn annotation that marks a TypeScript interface to generate a native protocol/interface that can be implemented in native code. See [Native Annotations](./native-annotations.md).\n\n## F\n\n### FlexBox\nA layout system borrowed from CSS that allows efficient arrangement of elements. Valdi uses Facebook's Yoga engine for flexbox. See [FlexBox Layout](./core-flexbox.md).\n\n### Full-Stack Valdi\nAn architecture where the majority of a feature (including data/services) is implemented in Valdi/TypeScript rather than native code. See [Full Stack Valdi](./advanced-full-stack.md).\n\n## H\n\n### Hot Reload\nThe ability to update running code without restarting the application. Valdi supports hot reloading of TypeScript code. See [Getting Started](./start-install.md).\n\n### Host (Worker Service)\nThe TypeScript main thread that creates and communicates with worker services.\n\n## I\n\n### IStyle\nThe TypeScript interface that defines style properties for elements. See [Style Attributes](../api/api-style-attributes.md).\n\n## J\n\n### JSX / TSX\nTypeScript extension syntax for writing declarative UI. Valdi uses TSX in `onRender()` methods. Example: `<view><label value=\"Hello\" /></view>`\n\n## L\n\n### Layout Node\nA `<layout>` element that performs layout calculations but doesn't create a native view. More efficient than `<view>` when you don't need view properties. See [Optimization](./performance-optimization.md).\n\n### Lifecycle Methods\nMethods on a Component that are called at specific times: `onCreate()`, `onViewModelUpdate()`, `onRender()`, `onDestroy()`. See [Component Lifecycle](./core-component.md#lifecycle).\n\n## M\n\n### Marshalling\nThe process of converting data between TypeScript and native representations when crossing the bridge. Has a performance cost for complex objects.\n\n### Module\nA logical unit of Valdi code that can include TypeScript sources, resources, native code, and configuration. Compiled into a `.valdimodule` file. See [Valdi Module](./core-module.md).\n\n### module.yaml\n**Deprecated.** Old configuration format for Valdi modules, replaced by `BUILD.bazel`.\n\n## N\n\n### Native Annotations\nTypeScript decorators that instruct the Valdi compiler to generate native code. See [Native Annotations](./native-annotations.md).\n\n### Native Reference\nA way to pass references to native objects (that aren't data) to Valdi. See [Native References](./advanced-native-references.md).\n\n### Native Template Element\nAn element like `<view>` or `<label>` that is backed by native code. Different from components which are TypeScript.\n\n## O\n\n### Observable\nAn RxJS primitive for handling asynchronous data streams. Valdi has special support for bridging Observables to native code. See [RxJS](./client-libraries-rxjs.md).\n\n## P\n\n### Polyglot Module\nA Valdi module that includes native code (iOS/Android/C++) in addition to TypeScript. See [Polyglot Modules](./native-polyglot.md).\n\n### Promise\nAn asynchronous operation that can be passed across the native bridge. Valdi automatically handles Promise conversion. See [Native Types](./native-types.md).\n\n### Props\nReact terminology for component parameters. In Valdi, these are called \"ViewModel\".\n\n### Provider\nA pattern for dependency injection in Valdi, allowing services to be accessed by components. See [Provider](./advanced-provider.md).\n\n## R\n\n### Reactive Programming\nA programming paradigm based on data streams and change propagation. Valdi's UI automatically updates when state changes.\n\n### Render Tree\nThe hierarchy of components and elements that make up the UI at any given time.\n\n### Runtime\nThe Valdi engine that executes TypeScript code and manages the native UI. Each application needs a `ValdiRuntime` instance.\n\n## S\n\n### Slot\nA pattern for passing child elements to a component. Similar to React's `children` prop. See [Slots](./core-slots.md).\n\n### State\nInternal data within a component that triggers re-renders when updated via `setState()`. See [Component States](./core-states.md).\n\n### Style<T>\nAn object containing style properties for an element. The type parameter specifies which element it's for. See [Styling](./core-styling.md).\n\n### StatefulComponent\nA component class that has internal state managed via `this.state` and `setState()`. See [Component States](./core-states.md).\n\n## T\n\n### Type Converter\nA mechanism for converting custom types between TypeScript and native code. See [Native Types](./native-types.md).\n\n### Type Marshalling\nSee **Marshalling**.\n\n## U\n\n### Unsubscribable\nAn object with an `unsubscribe()` method, typically an RxJS Subscription. Can be registered with `registerDisposable()`.\n\n## V\n\n### Valdi Module\nSee **Module**.\n\n### valdimodule File\nThe compiled output of a Valdi module, containing bytecode, resources, and metadata. Used at runtime.\n\n### View\nIn Valdi context, usually refers to the `<view>` element. In native context, refers to iOS `UIView` or Android `View`.\n\n### ViewModel\nThe parameters/props passed to a component from its parent. Changing the ViewModel triggers a re-render. See [View Model](./native-view-model.md).\n\n### View Recycling\nAn optimization technique where native views are reused rather than destroyed and recreated. See [View Recycling](./performance-view-recycling.md).\n\n## W\n\n### Worker Service\nA service that runs in a background TypeScript thread to avoid blocking UI operations. See [Worker Service](./advanced-worker-service.md).\n\n### Worker (Worker Service)\nThe background thread that executes worker service code.\n\n### WORKSPACE\nThe root Bazel configuration file that defines external dependencies and workspace settings.\n\n## Y\n\n### Yoga\nFacebook's cross-platform flexbox layout engine used by Valdi for layout calculations. See [Style Attributes - Yoga](../api/api-style-attributes.md#yoga-layout-engine).\n\n---\n\n## Related Documentation\n\n- [Native Annotations](./native-annotations.md) - Full list of available annotations\n- [Native Bindings](./native-bindings.md) - Complete type system reference\n- [API Reference](../api/api-reference-elements.md) - All native elements\n- [Component Lifecycle](./core-component.md#lifecycle) - Lifecycle methods detail\n\n## Contributing to the Glossary\n\nIf you encounter a term that should be added to this glossary, please consider contributing. See the main README for contribution guidelines.\n\n"
  },
  {
    "path": "docs/docs/help-support.md",
    "content": "# Support\n\n## Questions\n\nWe have a [Discord](https://discord.gg/uJyNEeYX2U)\n\n## Bug Reports\n\nFile 'em on in Github issues. (We will eventually need to set this up and build a guide)\n"
  },
  {
    "path": "docs/docs/help-troubleshooting.md",
    "content": "# Troubleshooting\n\nThis document will list the common issues that you can run into when using Valdi, hopefully creating a searchable self-service knowledge base over time.\n\n## Common Issues\n\n### Module fails to compile with `TypeScript error: '>' expected`\n\n```\n[ERROR] << TypeScript file venue_editor/src/VenueEditor.tsx failed to check: :rotating_light: TypeScript error: '>' expected. at line 79\n          /* Let's create a starting point for a typical screen hierarchy */\n        }\n        <Subscreen>\n   :point_right:      <slotted slot='header'>\n```\n\n**Make sure your module has at least one .ts file.** If not, you can add an empty one yourself (e.g. an empty `dummy.ts`).\n\nThis is a bug in our compilation pipeline, the process that we use to interface with typescript (`tsserver`) seems to not configure itself correctly without having a .ts file in a TypeScript project. A future compiler release will have this fixed.\n\n### Res not found\n\nAfter loading the valdi_modules workspace & setting the TypeScript version VSCode may not find res files. The image assets are not real-time updated by the hotreloader yet and are only re-uploaded after a full compile. Try `valdi projectsync` or restart of the hotreloader.\n\n!['Screenshot of VSCode complaining about a missing import'](./assets/help-troubleshooting/missingres.png)\n\n### I'm using build from source and made native related changes in the client. How do I see them reflected in IDE (Xcode, Android Studio)?\n\nNative code is generated during the build step and later imported by the IDE. In order to see the newly generated/updated native code, invoke build once.\n\n### Hotreloader not working\n\n#### Android\n\nMake sure your device is connected through USB with a properly working cable. You should be able to see your device using this `adb` command:\n\n```sh\n% adb devices\nList of devices attached\n31171JEHN02897\tdevice\n```\n\nAdditionally, you should be able to see your device logs using `adb logcat`, and the logs should keep showing in your terminal. If the `adb logcat` randomly interrupts, this might be an indication that the connection between your host machine and your Android device is unstable. If you notice such problems, try using a different USB cable, or try rebooting your host machine and Android device.\n\n#### iOS\n\nMake sure that you don't have multiple applications running Valdi at the same time. There is a known issue with the iOS Simulator running on M1/M2 machines that can cause zombie processes that hold onto the hotreloader socket forever. If this is suspected to be the case, you can try the following steps:\n\n1. `lsof -i :13592` (13592 is the default hotreloader port)\n2. If the output is empty then this is likely not the issue.\n3. Otherwise, take note of the displayed `PID` the proceed with the next steps.\n4. Run `ps -xo pid,ppid,stat,command | awk '$2 == <PID>'` replacing `<PID>` with the actual PID from step 3.\n5. Kill those processes with `kill -9 <PID>` or manually with Activity Monitor or its equivalent.\n\nIf the above steps do not work - you can try to kill the top level zombie processes (usually just the name of your project) directly via Activity Monitor or command line. Occasionally this will require a system restart.\n\n#### All platforms\n\n##### Delete hotreloader cache\n\nSometimes hotreloader cache can get stale and cause problems. While this is usually fixed by restarting the hotreloader, in the cases where restarting does not resolve the issue, the last resort solution is to manually delete the cache.\n\n```\nrm src/valdi_modules/.valdi_build/hotreload/caches/companion/compilecache.db\n```\n\n##### Watchman Configuration\n\nThe hotreloader leverages the [Watchman](https://facebook.github.io/watchman/) server to monitor for file changes. Issues with Watchman might cause the hotreloader to fail to start or pick up updated files.\n\nMake sure that you are trying to hotreload a file that is used in a module that is currently displayed in the application (A hotreload banner should show up in the application when it receives new files that triggered a reload of a component).\n\nMake sure that you don't have multiple instances of the hotreloader running at the same time.\n\nMake sure that you are not running the Valdi compiler at the same time as a hotreloader instance is running.\n\nMake sure you are on a recent version of `watchman`\n\n```sh\n% watchman --version\n2024.07.01.00\n```\n\nYou can upgrade watchman using `brew upgrade watchman`.\n\nCheck that your `watchman` instance is not currently watching directories that might contain a massive amount of files:\n\n```sh\n% watchman watch-list\n{\n    \"version\": \"2023.08.07.00\",\n    \"roots\": [\n        \"/Path/to/my/project\",\n        \"/Path/to/valdi/src/valdi_modules\"\n    ]\n}\n```\n\nIf you find that `watchman` is observing too many directories or directories that might contain a lot of files like your entire user directory for instance, you can delete a specific watched directory using `watchman watch-del /path/to/dir`. You can also use `watchman watch-del-all` to clear all the entries:\n\n```sh\n% watchman watch-del-all\n{\n    \"version\": \"2023.08.07.00\",\n    \"roots\": [\n        \"/Path/to/my/project\",\n        \"/Path/to/valdi/src/valdi_modules\"\n    ]\n}\n% watchman watch-list\n{\n    \"version\": \"2023.08.07.00\",\n    \"roots\": []\n}\n```\n\nTry restarting the hotreloader after the watch list have been cleared. The hotreloader will re-add the watch list to the `valdi_modules` directory automatically.\n\n## Setup issues\n\n### Intel Mac: `valdi: Bad CPU type in executable` or `cannot execute binary file`\n\nThe Valdi compiler binary is built for Apple Silicon (arm64). It will not run on Intel Macs (x86_64), even under Rosetta 2.\n\n**Intel Mac is not a supported development platform.** You need an Apple Silicon Mac (M1 or later) for iOS + Android development. If you only need Android, Linux is an alternative — see the [Linux setup guide](../setup/linux_setup.md).\n\nIf you're on an Apple Silicon Mac and still see this error, verify Rosetta is not interfering:\n\n```sh\n# Confirm your shell is running natively (should print \"arm64\")\nuname -m\n```\n\nIf `uname -m` returns `x86_64` on an Apple Silicon Mac, your terminal is running under Rosetta. Open a new terminal without Rosetta, or run:\n\n```sh\narch -arm64 /bin/zsh\n```\n\n### Git LFS: 429 rate limit or `Repository or object not found`\n\nValdi distributes compiler binaries via Git LFS. If LFS quota is exceeded you will see errors like:\n\n```\nerror: failed to fetch some objects from 'https://github.com/Snapchat/Valdi.git/info/lfs/objects/batch'\nLFS: Repository or object not found: ... Error 429\n```\n\n**Workarounds:**\n\nOption 1 — Skip LFS on clone and download only what you need:\n```sh\nGIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/Snapchat/Valdi.git\ncd Valdi\ngit lfs pull --include=\"compiler/**\"\n```\n\nOption 2 — Download the compiler binary directly from the [GitHub Release assets](https://github.com/Snapchat/Valdi/releases) for your version, and place it at the path `valdi` expects (check `valdi --help` for the expected location).\n\nIf none of the above work, ping us in the [Valdi Discord](https://discord.gg/uJyNEeYX2U) or [file a GitHub issue](https://github.com/Snapchat/Valdi/issues) and we can help get you unblocked.\n\n### `valdi install android` fails: `JAVA_HOME` not set or wrong Java version\n\n`valdi install android` requires **Java 17**. Other versions (8, 11, 21) are not supported.\n\nCheck your current Java version:\n```sh\njava -version\n# Should print: openjdk version \"17.x.x\"\n```\n\n**macOS:** Install Java 17 and point `JAVA_HOME` at it:\n```sh\nbrew install openjdk@17\nexport JAVA_HOME=$(/usr/libexec/java_home -v 17)\n```\n\nAdd the `export` line to your `~/.zshrc` (or `~/.bashrc`) so it persists across sessions.\n\n**Linux:** Install `openjdk-17-jdk` (Debian/Ubuntu) or `java-17-openjdk-devel` (Fedora/RHEL), then:\n```sh\nexport JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))\n```\n\n### `res.ts` not found / missing generated resource file\n\n`res.ts` is generated during a full compile step, not by the hotreloader. If VSCode reports it as missing:\n\n1. Run a full build to generate `res.ts`:\n   ```sh\n   valdi build   # or: bazel build //your_module\n   ```\n2. If the file still doesn't appear, run `valdi projectsync` to sync the workspace.\n3. Restart the TypeScript language server in VSCode: open the Command Palette (`Cmd+Shift+P`) → `TypeScript: Restart TS Server`.\n\nIf the file is generated but TypeScript still can't find it, check that the `res` directory is included in your `tsconfig.json` paths.\n\n### Fedora / RHEL / non-Debian Linux: `apt-get: command not found`\n\n`valdi dev_setup` detects your distro and uses the appropriate package manager. If auto-detection fails, install dependencies manually:\n\n```sh\n# Fedora / RHEL\nsudo dnf install java-17-openjdk-devel android-tools watchman fontconfig-devel zlib-devel git-lfs npm\n```\n\nThen continue with the [Linux setup guide](../setup/linux_setup.md) for Bazel and Android SDK setup.\n\nIf you're still stuck, ping us in the [Valdi Discord](https://discord.gg/uJyNEeYX2U) or [file a GitHub issue](https://github.com/Snapchat/Valdi/issues).\n\n## Valdi tooling development issues\n\n### Trying to debug Compiler in Xcode but getting `debugserver is x86_64 binary running in translation`\n\nMake sure Xcode doesn't run under Rosetta\n"
  },
  {
    "path": "docs/docs/internals-api-design.md",
    "content": "# Valdi API Design & Extensibility\n\nValdi is designed as a flexible, high-performance platform that balances developer control with framework-level optimizations.\n\n## Design Philosophy\n\nThe core ideology behind Valdi is to **decouple the framework team from feature teams**. By providing a flexible, non-opinionated API, Valdi ensures that feature teams are never blocked by framework limitations.\n\n### The \"Highest Level API\" Motto\n> *\"What is the highest level API we can expose that's easy and safe to use while allowing us to achieve a high level of performance?\"*\n\nValdi aims to:\n- **Minimize API Surface**: A smaller API surface is easier to learn and maintain.\n- **Avoid Domain-Specific APIs**: Instead of solving one specific problem, Valdi designs powerful, flexible APIs that can solve multiple problems.\n- **Maintain Under-the-Hood Control**: Valdi provides a sense of control to the user while allowing the framework to make performance improvements without changing the public APIs.\n\n## Extensibility Mechanisms\n\nValdi provides three primary mechanisms for extending its core functionality:\n\n### 1. Bridge Modules (Global)\nBridge modules expose functionality globally to all TypeScript code. They are best suited for services that are available across the entire application regardless of state (e.g., logging, analytics, global configuration).\n\n### 2. Component Context (Scoped)\nThe `ComponentContext` exposes host app functionality locally to a particular component and its subtree. This is ideal for services scoped to a specific session or feature (e.g., user profile data, feature-specific data stores).\n\n### 3. Custom View Classes (UI)\nCustom view classes allow developers to reuse existing native UI elements (iOS/Android) that would be impractical or non-performant to reimplement in TypeScript (e.g., complex video players, maps, or system-provided pickers).\n\n## Layered Architecture\n\nValdi is organized into distinct layers to ensure separation of concerns:\n\n| Layer | Language | Responsibility |\n| :--- | :--- | :--- |\n| **Feature Layer** | TypeScript | Feature-specific business logic and UI. |\n| **SIG/CoreUI** | TypeScript | High-level, reusable UI components following design guidelines. |\n| **Service Layer** | TS / C++ / Native | Exposes application-specific services (e.g., authentication, data stores) to Valdi. |\n| **Framework Layer** | TS / C++ | Manages component lifecycles and the element tree. |\n| **Core Runtime** | C++ | JS engine integration, Yoga layout engine, and UI synchronization. |\n| **Integration Layer** | C++ / Native | Platform-specific implementation of native elements (e.g., `SCValdiLabel`). |\n"
  },
  {
    "path": "docs/docs/internals-compiler.md",
    "content": "# Valdi Compiler Internals\n\nThe Valdi Compiler is a sophisticated toolchain that transforms TypeScript source code, resources, and configuration into optimized `.valdimodule` artifacts and native bindings.\n\n## Compiler Architecture\n\nThe compiler uses a **Pipeline-based Architecture** where inputs are transformed through a series of specialized processors.\n\n### Compilation Items\nEvery input to the compiler is represented as a `CompilationItem`. Items are immutable objects that can represent:\n- Source files (TypeScript, JavaScript, TSX)\n- Resources (Images, SVG, Fonts)\n- Metadata (OWNERS files, `strings.yaml`)\n- Intermediate states (Exported types, processed assets)\n- Final artifacts (Minified JS, bytecode, native headers)\n\n### Compilation Processors\nA `CompilationProcessor` handles specific item types and emits zero or more new items. \n- **Example**: The Image Processor takes an SVG `CompilationItem` and emits multiple PNG and WebP items for different display densities.\n- **Example**: The Save Processor takes \"Final File\" items and writes them to the output directory.\n\n## TypeScript XML (TSX) Compilation\n\nValdi uses a custom TSX transformer built on top of the TypeScript compiler. Unlike React, which transforms TSX into `createElement` calls, Valdi transforms them into a high-performance stack-based API.\n\n### Transformation Example\n\n**Input Code:**\n```tsx\nfunction render() {\n  <view>\n    <layout />\n  </view>\n}\n```\n\n**Generated Output:**\n```ts\nconst __Renderer = require('valdi_core/jsx/JSX').jsx;\nconst __nodeView1 = __Renderer.makeNodePrototype('view');\nconst __nodeLayout1 = __Renderer.makeNodePrototype('layout');\n\nfunction render() {\n  __Renderer.beginRender(__nodeView1);\n  __Renderer.beginRender(__nodeLayout1);\n  __Renderer.endRender();\n  __Renderer.endRender();\n}\n```\n\n### Key Optimizations\n- **Prototypes**: `makeNodePrototype` is called once at the module level. This blueprint is reused across all render passes.\n- **Specialized Setters**: The compiler detects attribute types and uses specialized functions (e.g., `setAttributeNumber`, `setAttributeString`) to avoid type introspection at runtime.\n- **Static Properties**: Attributes that never change are passed directly into the prototype, removing them from the per-render execution path.\n\n## Transformation Nuances\n\n### Elements vs. Components\n- **Elements**: Defined by lowercase tags (e.g., `<view>`). Transformed into `beginRender` / `endRender` calls using a `NodePrototype`.\n- **Components**: Defined by PascalCase tags (e.g., `<Header>`). Transformed into `beginComponent` / `endComponent` calls using a `ComponentPrototype`.\n\n### Slots\nChildren passed to a component are automatically wrapped in a render function and passed via `setSlot`. The component then uses `renderSlot` to evaluate that function at the desired location in its tree.\n\n## Compiler Pipeline Responsibilities\n\nThe compiler performs several critical tasks beyond simple code transformation:\n\n1. **Asset Generation**: Automatically generates missing image variants (densities) and compresses them.\n2. **Asset Catalog**: Generates a type-safe TypeScript accessor for all assets. It also pre-calculates image dimensions so the runtime can perform layout without loading the image data.\n3. **Localization**: Transforms `strings.yaml` into TypeScript accessors and native platform string files (`Localizable.strings` for iOS, `strings.xml` for Android).\n4. **TSX to TS Transformation**: Our custom transformer converts TSX expressions into high-performance stack-based API calls.\n5. **Minification**: Uses Terser to reduce JavaScript code size.\n6. **Bytecode Compilation**: On Android, the compiler produces QuickJS-compatible bytecode for even faster execution.\n7. **Native Bindings**: Generates Objective-C, Swift, and Kotlin models and view classes from TypeScript code annotations (`@ExportModel`, `@Component`).\n8. **Build System Integration**: Generates Bazel `BUILD.bazel` files so each module can be referenced in the main build.\n9. **Source Maps**: Generates source maps to enable symbolic stack traces in the runtime.\n\n## Compiler Companion\n\nThe compiler utilizes a \"Companion\" binary implemented in TypeScript. The main compiler (written in Swift) makes the following requests to the companion via a JSON protocol:\n- **Minify JS**: Invokes Terser.\n- **Compile TS/TSX**: Invokes the custom TypeScript transformer.\n- **Extract Symbols**: Finds TypeScript symbols with comments for code annotation processing.\n- **Dump AST**: Provides AST information (interfaces, enums, function signatures) for native binding generation.\n- **Debug Proxy**: Sets up a proxy socket for VSCode's JS debugger.\n"
  },
  {
    "path": "docs/docs/internals-native-integration.md",
    "content": "# Native Integration Internals\n\nValdi provides a robust abstraction layer for managing native UI hierarchies across iOS, Android, and Skia. This document explores the internal mechanisms that enable high-performance native view management.\n\n## View Abstraction\n\nThe C++ runtime interacts with native views through the `View` and `ViewFactory` abstract classes. This allows the core logic to remain platform-agnostic while the actual UI is rendered using UIKit (iOS), Android Views, or Skia.\n\n### `View` Class\nA `View` represents a single piece of the user interface. It wraps a platform-specific view (e.g., `UIView` or `android.view.View`) and provides a uniform interface for:\n- **Hierarchy Management**: Inserting, removing, and reordering child views.\n- **Geometry**: Setting the frame (position and size) relative to the parent.\n- **Measurement**: Calculating the view's intrinsic size (e.g., for labels or images).\n- **Attributes**: Applying and resetting key-value properties.\n\n### `ViewFactory` Class\nThe `ViewFactory` is responsible for creating and recycling `View` instances.\n- **Pooling**: To minimize the overhead of view inflation, `ViewFactory` maintains a pool of reusable view instances.\n- **Measurer Placeholder**: Each factory provides a specialized view instance used exclusively for measuring elements that are not currently visible.\n- **Attribute Binding**: A factory is associated with a set of `BoundAttributes` that it supports.\n\n## `IViewManager` Interface\n\nThe `IViewManager` is the primary interface implemented by a UI backend. It serves as a registry and resolver for the runtime.\n\n### Key Responsibilities\n1. **View Class Resolution**: Resolves a `ViewFactory` for a given view class name (e.g., \"label\", \"image\", or a custom class).\n2. **Attribute Discovery**: When a view class is first used, the runtime queries the `IViewManager` for all attributes supported by that class and its hierarchy.\n3. **Hierarchy Introspection**: Provides the class hierarchy for a view class, allowing Valdi to merge attributes from parent classes (e.g., a `Label` inherits attributes from `View`).\n\n## Attribute Binding System\n\nAttribute binding is the process of registering and applying properties to native views. This system is designed to be efficient and type-safe.\n\n### Binding Declaration\nWhen a view class registers an attribute, it specifies:\n- **Expected Type**: (e.g., Int, Double, String, Style). This allows the runtime to pass values directly without expensive boxing/unboxing.\n- **Apply Callback**: The logic that mutates the native view to reflect the new attribute value.\n- **Reset Callback**: The logic that restores the view to its default state when an attribute is removed.\n- **Layout Impact**: Whether changing the attribute should mark the layout as dirty (e.g., changing a label's font size).\n\n### Cross-Platform Consistency\nValdi ensures that attributes behave identically across all supported platforms. The core layout attributes (Flexbox) are handled by the Yoga engine, while view-specific attributes (colors, opacity, etc.) are implemented by each platform's integration layer.\n\n## Custom View Integration\n\nThe `<custom-view>` element allows developers to inject arbitrary native views into a Valdi tree.\n\n1. **Class Mapping**: Valdi can instantiate views by their platform-specific class names using reflection (Android) or class lookup (iOS).\n2. **Factory Injection**: For more control, a `ViewFactory` can be passed via the `ComponentContext`, allowing for custom initialization and dependency injection.\n3. **Lazy Registration**: Attribute binding for custom views happens lazily—only when the view class is first encountered at runtime.\n"
  },
  {
    "path": "docs/docs/internals-renderer.md",
    "content": "# Valdi Renderer Internals\n\nThe Valdi Renderer is responsible for managing the lifecycle of elements and components, performing efficient diffing, and synchronizing the UI state with the native runtime.\n\n## Core Concepts\n\n### VirtualNode Tree vs. Element Tree\n- **VirtualNode Tree**: A TypeScript-only hierarchy containing both **Components** (logic) and **Elements** (UI primitives).\n- **Element Tree**: A filtered version of the VirtualNode tree containing only native elements. This tree is synchronized with the C++ runtime.\n\n### Node Prototypes\nThe Valdi compiler generates a **Prototype** for every TSX expression. Prototypes act as blueprints, allowing the Renderer to identify nodes across render passes without expensive lookups.\n\n## The Diffing Algorithm\n\nValdi uses a stack-based, incremental diffing algorithm that runs *during* the render pass. This minimizes object churn and allows for early exits.\n\n### Stack-Based Rendering\nPush operations can be nested. The Renderer keeps a stack to know what is the node being rendered and their ancestors.\n\n### Key Resolution\nValdi generates stable keys for nodes based on their Prototype and position. \n- **Automatic Keys**: O(1) in most cases. If a conflict occurs (e.g., multiple identical prototypes), an incrementing sequence is used.\n- **Explicit Keys**: Recommended for loops (e.g., `<label key={item.id} />`) to ensure nodes are correctly moved rather than mutated when the list order changes.\n\n### Bypassing Rendering\nTo maximize performance, the Renderer implements a **Stop Gap Rule**:\n- If a component's **ViewModel** (props) has not changed since the last render, the `onRender()` call is bypassed entirely.\n- This prevents a change at the root from cascading through the entire application tree.\n\n## Algorithm Complexity\n\nThe Renderer is optimized for fast incremental renders. Almost all operations are constant time unless changes are detected:\n\n| Operation | Complexity |\n| :--- | :--- |\n| **Generating Key** | O(1) in most cases (up to O(n) on key conflict) |\n| **Diffing ViewModels** | O(1) |\n| **Resolving Children** | O(n) initial, O(1) incremental (no change), O(n+k) incremental (with change) |\n\n## Advanced Optimization: Slot Re-rendering\n\nOne of Valdi's most powerful optimizations is the ability to re-render **Slots** independently of their parent component.\n\n### The Problem\nIn traditional frameworks, if a parent passes new children to a child component, the child component must re-render to incorporate them.\n\n### The Valdi Solution\nThe Renderer tracks the exact location where a slot was evaluated in the element tree. When the parent re-renders:\n\n1. The Renderer identifies the slot's parent node and its siblings.\n2. It \"replays\" the slot's render function at that specific location.\n3. The child component itself is **not** re-rendered, preserving its internal state and avoiding unnecessary work.\n\n## Element Synchronization\n\nThe `RendererDelegate` (specifically `JSXRendererDelegate`) translates VirtualNode changes into native commands.\n\n### Efficient Updates\nThe Renderer computes the minimal set of operations to sync the native tree:\n- **Insert/Remove**: Standard O(n) operations.\n- **Move**: Detected by comparing the current children array with the previous one.\n- **Attribute Updates**: Constant time O(1) updates. Valdi does not detect \"removed\" attributes; they must be explicitly set to `undefined`.\n\n### Marshalling Optimizations\n- **Interned Attributes**: Common attribute names (e.g., \"backgroundColor\") are interned as integers to avoid string conversion overhead.\n- **Style Interning**: `Style<>` objects are interned lazily. Reusing style objects in TypeScript allows the bridge to pass a single integer ID instead of the full style dictionary.\n\n## Error Handling & Boundaries\n\nThe Renderer wraps all component lifecycle methods in `try-catch` blocks to ensure UI stability.\n\n### Error Recovery\nIf a render fails:\n1. The Renderer unwinds the stack to the failing component.\n2. It searches for the nearest ancestor implementing `onError()`.\n3. In debug mode, the `DefaultErrorBoundary` catches these errors and displays a full-screen error report.\n"
  },
  {
    "path": "docs/docs/internals-runtime.md",
    "content": "# Valdi Runtime Internals\n\nThis document provides a deep dive into the Valdi C++ Runtime, its data representation, and the communication protocol between TypeScript and native code.\n\n## Architecture Overview\n\nThe Valdi C++ runtime provides a high-performance environment for executing Valdi components. It integrates a JavaScript engine (QuickJS on Android/Desktop, JavaScriptCore on iOS) and a cross-platform layout engine (Yoga).\n\n![Architecture Diagram](./assets/internals/architecture.png)\n\n### Key Responsibilities\n- **JS Engine Integration**: Managing the lifecycle of the JavaScript environment.\n- **Layout Engine**: Calculating element positions and sizes using the Web Flexbox specification.\n- **Element Synchronization**: Processing update commands from the TypeScript framework.\n- **Platform Integration**: Bridging to iOS (UIKit), Android (Views/Skia), and Desktop (Skia).\n\n## Data Representation: `Valdi::Value`\n\n`Valdi::Value` is the core data container used to pass information across the bridge between C++, JavaScript, Objective-C, and Java.\n\n### Characteristics\n- **128-bit Container**: Uses 64 bits for data storage (or a pointer) and 64 bits for type metadata.\n- **Thread-Safe & Immutable**: Can be safely passed across threads without explicit synchronization.\n- **Reference Counted**: Complex types like Maps and Arrays are heap-allocated and ref-counted.\n- **Zero-Copy Marshalling**: Designed to minimize heap allocations when passing data across the bridge.\n\n### Supported Types\n- Null / Undefined\n- Boolean\n- 32-bit Integer / 64-bit Long\n- 64-bit Double\n- String (Interned via `StringBox`)\n- Map (`ValueMap`) / Array (`ValueArray`)\n- Function / Error\n- TypedArray\n- `ValdiObject` (Abstract base for native objects)\n\n## Optimization: Interned Strings\n\nTo optimize memory and performance, Valdi uses **Interned Strings**. Every unique string value is stored once in a global `StringCache`.\n\n- **`StringBox`**: A value type that holds a reference to an interned string.\n- **Fast Comparison**: String equality is a simple pointer comparison.\n- **Efficient Maps**: Map lookups use pre-calculated hashes stored with the interned string.\n\n## Communication Protocol: `RenderRequest`\n\nWhen the TypeScript `Renderer` completes a render pass, it submits a `RenderRequest` to the C++ runtime.\n\n### `RenderRequest` Structure\n1. **`treeId`**: Identifies the specific element tree being updated.\n2. **`descriptor`**: An `ArrayBuffer` containing a serialized binary protocol of commands.\n3. **`values`**: An array of non-serializable TypeScript values (e.g., functions, native object references).\n\n### Binary Protocol (`RenderRequestDescriptor`)\nThe protocol is optimized for minimal marshalling overhead. Each command starts with a 4-byte header:\n- **1 byte**: `CommandType` (Enum)\n- **3 bytes**: `ElementId` (The target element)\n\n#### Common Commands\n| Command | Size | Description |\n| :--- | :--- | :--- |\n| `CreateElement` | 8 bytes | Creates a new native view of a specific class. |\n| `DestroyElement` | 4 bytes | Recursively destroys an element subtree. |\n| `MoveElementToParent` | 12 bytes | Inserts or moves an element within a parent. |\n| `SetAttributeInt` | 12 bytes | Sets a numeric attribute on an element. |\n| `SetAttributeStyle` | 12 bytes | Applies a pre-interned style object. |\n| `SetAttributeAttachedValue` | 12 bytes | References a value from the `values` array. |\n\n## Module System & Loading\n\nValdi implements a custom module loader inspired by Node.js but optimized for mobile.\n\n### Lazy Loading\nBy default, Valdi modules are **lazy-loaded**. When a module is `require()`'d, the loader returns an **ES6 Proxy**. The actual evaluation of the module code only happens when a property of the proxy is accessed.\n- **Benefit**: Significantly reduces cold start time by avoiding the evaluation of unused code.\n- **Trade-off**: Slightly less deterministic runtime performance during the first access.\n\n### `JsEvaluator`\nThe `JsEvaluator` is a C++ function that:\n1. Resolves the absolute path to a file within a `.valdimodule` archive.\n2. Evaluates the JavaScript code within the engine.\n3. Returns the module function and optional source maps for debugging.\n\n> [!Note]\n> Valdi cannot evaluate raw `.js` files directly. It must evaluate files from `.valdimodule` archives produced by the Valdi compiler. This allows Valdi to run in a standalone mode (without UI) for scripts and unit tests, similar to Node.js.\n\n## Component Instantiation & Management\n\n### `ComponentPath`\nA `ComponentPath` is a string that tells the runtime how to locate and instantiate a component class. It is primarily used for the root component of a feature.\n- **Format**: `<symbol_name>@<module_name>/<file_path>`\n- **Example**: `RootComponent@my_module/src/Root`\n\n### `RootComponentsManager`\nThe `RootComponentsManager` is the primary interface between the C++ runtime and the TypeScript framework.\n- **Lifecycle**: It manages the creation, update, and destruction of all root components in the application.\n- **Hot Reloading**: It registers observers on the TypeScript modules. When a module or its dependency is swapped, the manager resolves the new constructor and triggers a re-render of the affected component hierarchy.\n"
  },
  {
    "path": "docs/docs/migrate-from-compose.md",
    "content": "# Migrating from Jetpack Compose to Valdi\n\nJetpack Compose and Valdi both use a declarative, component-based model for building native UI. If you're coming from Compose, many concepts translate directly — but Valdi uses TypeScript instead of Kotlin, a class-based component model instead of composable functions, and Bazel instead of Gradle.\n\n## Mental Model\n\n| | Jetpack Compose | Valdi |\n|---|---|---|\n| **Language** | Kotlin | TypeScript |\n| **Build system** | Gradle + `build.gradle` | Bazel + `BUILD.bazel` |\n| **UI primitive** | `@Composable` function | Class extending `Component` |\n| **Platforms** | Android (+ multiplatform beta) | iOS, Android, macOS |\n| **Hot reload** | Android Studio Live Edit | `valdi hotreload` |\n| **State** | `remember { mutableStateOf() }` | `StatefulComponent` + `this.setState()` |\n\n## Component Model\n\nThe biggest structural difference: Compose uses annotated functions, Valdi uses classes.\n\n```kotlin\n// Compose — function component\n@Composable\nfun Greeting(name: String) {\n    Text(\"Hello, $name\")\n}\n```\n\n```tsx\n// Valdi — class component\nimport { Component } from 'valdi_core/src/Component';\n\ninterface GreetingViewModel {\n  name: string;\n}\n\nclass Greeting extends Component<GreetingViewModel> {\n  onRender() {\n    <label value={`Hello, ${this.viewModel.name}`} />;\n  }\n}\n```\n\n### Stateful components\n\nCompose's `remember { mutableStateOf() }` maps to `StatefulComponent` with `this.setState()`:\n\n```kotlin\n// Compose\n@Composable\nfun Counter(label: String) {\n    var count by remember { mutableStateOf(0) }\n    Button(onClick = { count++ }) {\n        Text(\"$label: $count\")\n    }\n}\n```\n\n```tsx\n// Valdi\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\ninterface CounterViewModel { label: string; }\ninterface CounterState { count: number; }\n\nclass Counter extends StatefulComponent<CounterViewModel, CounterState> {\n  state = { count: 0 };\n\n  // Class arrow function — never inline lambda in JSX props\n  private increment = () => {\n    this.setState({ count: this.state.count + 1 });\n  };\n\n  onRender() {\n    <view onTap={this.increment}>\n      <label value={`${this.viewModel.label}: ${this.state.count}`} />;\n    </view>;\n  }\n}\n```\n\n> [!Important]\n> Valdi does not have hooks. There is no `remember`, `mutableStateOf`, `derivedStateOf`, or `collectAsState`. All state lives in the class via `this.setState()`.\n\n## Lifecycle\n\n| Compose | Valdi |\n|---|---|\n| `LaunchedEffect(Unit) { ... }` | `onCreate()` |\n| `DisposableEffect { onDispose { ... } }` | `onDestroy()` |\n| `LaunchedEffect(key) { ... }` | `onViewModelUpdate(previous?)` with key comparison |\n| Recomposition triggered by state/remember | `onRender()` triggered by `setState()` or viewModel change |\n| `SideEffect { ... }` | Logic inside `onViewModelUpdate` or `onCreate` |\n\n```tsx\nclass DataComponent extends StatefulComponent<{ userId: string }, { data: Data | null }> {\n  state = { data: null };\n\n  onCreate() {\n    // Like LaunchedEffect(Unit) — runs once on mount\n    this.loadData(this.viewModel.userId);\n  }\n\n  onViewModelUpdate(previous?: { userId: string }) {\n    // Like LaunchedEffect(userId) — re-runs when userId changes\n    if (this.viewModel.userId !== previous?.userId) {\n      this.loadData(this.viewModel.userId);\n    }\n  }\n\n  onDestroy() {\n    // Like DisposableEffect onDispose — clean up\n  }\n\n  private async loadData(id: string) {\n    const data = await fetchData(id);\n    this.setState({ data });\n  }\n\n  onRender() {\n    if (!this.state.data) {\n      <spinner />;\n      return;\n    }\n    <label value={this.state.data.title} />;\n  }\n}\n```\n\n## Layout\n\nCompose's `Column`, `Row`, and `Box` map to Valdi's flexbox-based `<view>` and `<layout>` elements.\n\n| Compose | Valdi |\n|---|---|\n| `Column` | `<view flexDirection=\"column\">` (default) |\n| `Row` | `<view flexDirection=\"row\">` |\n| `Box` | `<view>` with children using `position=\"absolute\"` |\n| `Spacer(Modifier.weight(1f))` | `<layout flexGrow={1} />` |\n| `Modifier.fillMaxWidth()` | `width=\"100%\"` |\n| `Modifier.fillMaxHeight()` | `height=\"100%\"` |\n| `Modifier.padding(16.dp)` | `padding={16}` (on any element) |\n| `Modifier.background(Color.White)` | `backgroundColor=\"#ffffff\"` |\n| `Modifier.clip(RoundedCornerShape(8.dp))` | `borderRadius={8} clipToBounds={true}` |\n| `Modifier.clickable { }` | `onTap={this.handler}` on `<view>` |\n| `Arrangement.Center` / `Alignment.Center` | `justifyContent=\"center\" alignItems=\"center\"` |\n\n```kotlin\n// Compose\nColumn(\n    modifier = Modifier.fillMaxWidth().padding(16.dp),\n    verticalArrangement = Arrangement.spacedBy(8.dp)\n) {\n    Text(\"Title\", style = MaterialTheme.typography.h5)\n    Text(\"Subtitle\")\n}\n```\n\n```tsx\n// Valdi\n// import { systemFont } from 'valdi_core/src/SystemFont';\nonRender() {\n  <view flexDirection=\"column\" width=\"100%\" padding={16}>\n    <label value=\"Title\" font={systemFont(20)} />;\n    <layout height={8} />;\n    <label value=\"Subtitle\" />;\n  </view>;\n}\n```\n\n> [!Note]\n> Valdi doesn't have `Arrangement.spacedBy`. Use margin/padding on children or a `<layout height={gap} />` spacer.\n\n## Native Elements\n\n| Compose | Valdi |\n|---|---|\n| `Text(text)` | `<label value={text}>` |\n| `TextField` / `OutlinedTextField` | `<textfield>` (single-line) |\n| `BasicTextField` | `<textfield>` |\n| `Image(painter)` | `<image src={url}>` |\n| `AsyncImage` (Coil) | `<image src={url}>` (built-in async loading) |\n| `LazyColumn` / `LazyRow` | `<scroll>` + `forEach` (see [Lists](#lists)) |\n| `CircularProgressIndicator` | `<spinner>` |\n| `LottieAnimation` | `<animatedimage>` |\n| `AndroidView` | `<custom-view androidClass=\"...\">` |\n| `VideoPlayer` | `<video>` |\n\n## Lists\n\nCompose's `LazyColumn` / `LazyRow` with `items { }` maps to `<scroll>` with `forEach`. Valdi handles viewport-aware rendering automatically.\n\n```kotlin\n// Compose\nLazyColumn {\n    items(users, key = { it.id }) { user ->\n        UserRow(user = user)\n    }\n}\n```\n\n```tsx\n// Valdi\nonRender() {\n  <scroll>\n    {this.viewModel.users.forEach(user => {\n      <UserRow key={user.id} data={user} />;\n    })}\n  </scroll>;\n}\n```\n\n> [!Important]\n> Do not use `map()`. In Valdi, `onRender()` emits JSX as side-effects — `map()` returns an array that is silently discarded. Use `forEach` or `for...of`.\n\nFor horizontal lists:\n```tsx\n<scroll horizontal={true}>\n  {this.viewModel.items.forEach(item => {\n    <Card key={item.id} data={item} />;\n  })}\n</scroll>\n```\n\n## State Hoisting & CompositionLocal → Provider\n\nCompose's `CompositionLocalProvider` and state hoisting pattern map to Valdi's Provider pattern.\n\n```kotlin\n// Compose — CompositionLocal\nval LocalTheme = compositionLocalOf { LightTheme }\n\nCompositionLocalProvider(LocalTheme provides DarkTheme) {\n    MyScreen()\n}\n\n// Consumer\nval theme = LocalTheme.current\n```\n\n```tsx\n// Valdi — Provider\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nimport { ProvidersValuesViewModel, withProviders } from 'valdi_core/src/provider/withProviders';\n\nclass ThemeService { primary = '#FFFC00'; }\nconst ThemeProvider = createProviderComponentWithKeyName<ThemeService>('ThemeProvider');\n\n// Root\nclass AppRoot extends Component {\n  private theme = new ThemeService();\n  onRender() {\n    <ThemeProvider value={this.theme}><App /></ThemeProvider>;\n  }\n}\n\n// Consumer\ninterface ThemedViewModel extends ProvidersValuesViewModel<[ThemeService]> {}\nclass ThemedButton extends Component<ThemedViewModel> {\n  onRender() {\n    const [theme] = this.viewModel.providersValues;\n    <view backgroundColor={theme.primary}><label value=\"Click\" /></view>;\n  }\n}\nconst ThemedButtonWithProvider = withProviders(ThemeProvider)(ThemedButton);\n```\n\nSee [Provider documentation](./advanced-provider.md).\n\n## Navigation\n\n| Compose (Navigation component) | Valdi |\n|---|---|\n| `NavHost` | `<NavigationRoot>` |\n| `navController.navigate(\"detail\")` | `this.navigationController.push(DetailPage, viewModel)` |\n| `navController.popBackStack()` | `this.navigationController.pop()` |\n| `ModalBottomSheet` / `Dialog` | `this.navigationController.present(Page, viewModel)` |\n| `rememberNavController()` | `this.navigationController` (available on `NavigationPageComponent`) |\n\n## Networking\n\n```kotlin\n// Compose / Kotlin coroutines\nviewModelScope.launch {\n    val response = api.getUsers()\n    _users.value = response\n}\n```\n\n```tsx\n// Valdi\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\n\nclass UserList extends StatefulComponent<{}, { users: User[] }> {\n  state = { users: [] };\n  private client = new HTTPClient('https://api.example.com');\n  private request?: { cancel(): void };\n\n  onCreate() {\n    this.request = this.client.get('/users');\n    this.request.then(response => {\n      const users = JSON.parse(new TextDecoder().decode(response.body));\n      this.setState({ users });\n    });\n  }\n\n  onDestroy() {\n    this.request?.cancel();\n  }\n\n  onRender() {\n    <scroll>\n      {this.state.users.forEach(u => {\n        <label key={u.id} value={u.name} />;\n      })}\n    </scroll>;\n  }\n}\n```\n\n## Styling\n\nCompose's `Modifier` chain and `MaterialTheme` map to Valdi's `Style<T>` objects and Provider-based theming.\n\n```kotlin\n// Compose\nBox(\n    modifier = Modifier\n        .background(Color.White, RoundedCornerShape(12.dp))\n        .shadow(elevation = 4.dp)\n        .padding(16.dp)\n)\n```\n\n```tsx\n// Valdi — Style at module level, not inside onRender()\nimport { Style } from 'valdi_core/src/Style';\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst cardStyle = new Style<View>({\n  backgroundColor: '#ffffff',\n  borderRadius: 12,\n  boxShadow: '0 2 8 rgba(0,0,0,0.15)',\n  padding: 16,\n});\n\nclass Card extends Component<{ title: string }> {\n  onRender() {\n    <view style={cardStyle}>\n      <label value={this.viewModel.title} />;\n    </view>;\n  }\n}\n```\n\n## Storage\n\n| Kotlin / Android | Valdi |\n|---|---|\n| `SharedPreferences` | `PersistentStore` |\n| `DataStore<Preferences>` | `PersistentStore` |\n| `EncryptedSharedPreferences` | `new PersistentStore(name, { enableEncryption: true })` |\n\n## Key Differences to Watch\n\n| Compose | Valdi |\n|---|---|\n| `@Composable` function annotation | No annotation — class extends `Component` |\n| `remember { }` for local state | `state = {}` field on `StatefulComponent` |\n| `mutableStateOf` / `collectAsState` | `this.setState({})` |\n| `Modifier` chain for styling/layout | Direct attributes on elements (`padding={16}`, `backgroundColor=\"#fff\"`) |\n| `LaunchedEffect(key)` for side effects | `onViewModelUpdate(prev)` with key comparison |\n| `items { }` in `LazyColumn` | `forEach` inside `<scroll>` — no `map()` |\n| `LocalContext.current` | No direct equivalent — use Provider pattern |\n| `stringResource(R.string.title)` | Valdi localization module — see [Localization](./advanced-localization.md) |\n| `rememberCoroutineScope()` | `onCreate()` / async class methods |\n\n## See Also\n\n- [The Mighty Component](./core-component.md)\n- [Component States](./core-states.md)\n- [FlexBox Layout](./core-flexbox.md)\n- [Navigation](./navigation.md)\n- [Provider](./advanced-provider.md)\n- [Working with AI Assistants](./ai-tooling.md)\n"
  },
  {
    "path": "docs/docs/migrate-from-flutter.md",
    "content": "# Migrating from Flutter to Valdi\n\nValdi and Flutter share the same high-level goal: write UI once, run natively on iOS and Android without web views. If you're coming from Flutter, many concepts will feel familiar—but the implementation language, build system, and component model are different.\n\nThis guide walks through how Flutter concepts map to Valdi equivalents.\n\n## Mental Model\n\n| | Flutter | Valdi |\n|---|---|---|\n| **Language** | Dart | TypeScript |\n| **Build system** | `pubspec.yaml` + `flutter` CLI | `BUILD.bazel` + `valdi` CLI |\n| **UI primitive** | Widget | Component (class-based) |\n| **Renders to** | Native views via Skia/Impeller | Native views directly |\n| **Hot reload** | `flutter run` | `valdi hotreload` |\n| **Package manager** | `pub.dev` | npm + Bazel deps |\n\nBoth frameworks compile declarative UI code to true native views—no WebView, no JS bridge at runtime.\n\n## Project Setup\n\n### Creating a new project\n\n```bash\n# Flutter\nflutter create my_app\ncd my_app\nflutter run\n\n# Valdi\nmkdir my_app && cd my_app\nvaldi bootstrap\nvaldi install ios    # or android\nvaldi hotreload\n```\n\n### Build configuration\n\nFlutter uses `pubspec.yaml` to declare dependencies. Valdi uses a `BUILD.bazel` file with the `valdi_module()` rule:\n\n```python\n# Flutter: pubspec.yaml\n# dependencies:\n#   http: ^1.0.0\n\n# Valdi: BUILD.bazel\nload(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"my_module\",\n    srcs = glob([\"src/**/*.ts\", \"src/**/*.tsx\"]),\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_http\",\n    ],\n)\n```\n\n## Component Model\n\n### StatelessWidget → Component\n\n```dart\n// Flutter\nclass Greeting extends StatelessWidget {\n  final String name;\n  const Greeting({required this.name});\n\n  @override\n  Widget build(BuildContext context) {\n    return Text('Hello, $name');\n  }\n}\n```\n\n```tsx\n// Valdi\nimport { Component } from 'valdi_core/src/Component';\n\ninterface GreetingViewModel {\n  name: string;\n}\n\nclass Greeting extends Component<GreetingViewModel> {\n  onRender() {\n    <label value={`Hello, ${this.viewModel.name}`} />;\n  }\n}\n```\n\nKey differences:\n- Props are declared as a `ViewModel` interface, accessed via `this.viewModel` (not `this.widget` or constructor params)\n- `build(BuildContext context)` → `onRender(): void` — **no return statement**, JSX is emitted as a side-effect\n- No `BuildContext` parameter — context injection uses the [Provider pattern](#provider-pattern) instead\n\n### StatefulWidget → StatefulComponent\n\nFlutter's `StatefulWidget` + `State<T>` pair becomes a single `StatefulComponent<ViewModel, State>` class in Valdi. The `setState()` API is nearly identical.\n\n```dart\n// Flutter\nclass Counter extends StatefulWidget {\n  final String label;\n  const Counter({required this.label});\n  @override\n  State<Counter> createState() => _CounterState();\n}\n\nclass _CounterState extends State<Counter> {\n  int _count = 0;\n\n  void _increment() {\n    setState(() { _count++; });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return GestureDetector(\n      onTap: _increment,\n      child: Text('${widget.label}: $_count'),\n    );\n  }\n}\n```\n\n```tsx\n// Valdi\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\ninterface CounterViewModel {\n  label: string;\n}\n\ninterface CounterState {\n  count: number;\n}\n\nclass Counter extends StatefulComponent<CounterViewModel, CounterState> {\n  state = { count: 0 };\n\n  // Class arrow function — never use inline lambdas in JSX\n  private increment = () => {\n    this.setState({ count: this.state.count + 1 });\n  };\n\n  onRender() {\n    <view onTap={this.increment}>\n      <label value={`${this.viewModel.label}: ${this.state.count}`} />;\n    </view>;\n  }\n}\n```\n\n> [!Important]\n> Event handlers must be class arrow functions (e.g. `private increment = () => {}`), not inline lambdas in JSX. Inline lambdas create a new function reference on every render, causing unnecessary re-renders of child components.\n\n## Lifecycle Methods\n\n| Flutter (`State<T>`) | Valdi |\n|---|---|\n| `initState()` | `onCreate()` |\n| `dispose()` | `onDestroy()` |\n| `didUpdateWidget(oldWidget)` | `onViewModelUpdate(previous?)` |\n| `build(context)` | `onRender(): void` |\n| `didChangeDependencies()` | `onViewModelUpdate(previous?)` (for Provider changes) |\n\n```tsx\nclass MyComponent extends StatefulComponent<MyViewModel, MyState> {\n  state = { data: null };\n\n  onCreate() {\n    // Like initState() — runs once after component mounts\n    this.loadData();\n  }\n\n  onViewModelUpdate(previous?: MyViewModel) {\n    // Like didUpdateWidget — runs when viewModel changes\n    if (this.viewModel.id !== previous?.id) {\n      this.loadData();\n    }\n  }\n\n  onDestroy() {\n    // Like dispose() — clean up subscriptions, timers, etc.\n  }\n\n  private async loadData() {\n    const data = await fetchData(this.viewModel.id);\n    this.setState({ data });\n  }\n\n  onRender() {\n    if (!this.state.data) {\n      <spinner />;\n      return;\n    }\n    <label value={this.state.data.title} />;\n  }\n}\n```\n\n## Layout\n\nFlutter uses `Row`, `Column`, and `Stack` widgets. Valdi uses flexbox (the CSS Web Flexbox spec, via Facebook's Yoga engine), applied directly to `<view>` and `<layout>` elements.\n\n| Flutter | Valdi |\n|---|---|\n| `Column` | `<view flexDirection=\"column\">` (default) |\n| `Row` | `<view flexDirection=\"row\">` |\n| `Stack` | `<view>` with children using `position=\"absolute\"` |\n| `Container` (visual) | `<view>` |\n| `SizedBox` / `Padding` (layout only) | `<layout>` — no native view, use when no visual styling needed |\n| `Expanded` | `flexGrow={1}` on child |\n| `Flexible` | `flexShrink={1}` on child |\n| `Spacer` | `<layout flexGrow={1} />` |\n| `Center` | `<view justifyContent=\"center\" alignItems=\"center\">` |\n| `Padding(padding: EdgeInsets.all(8))` | `<view padding={8}>` |\n| `AspectRatio` | `<view aspectRatio={16/9}>` |\n\n```tsx\n// Flutter Column with two centered items:\n// Column(\n//   mainAxisAlignment: MainAxisAlignment.center,\n//   children: [Text('Hello'), Text('World')],\n// )\n\n// Valdi:\nonRender() {\n  <view flexDirection=\"column\" justifyContent=\"center\" alignItems=\"center\">\n    <label value=\"Hello\" />;\n    <label value=\"World\" />;\n  </view>;\n}\n```\n\n```tsx\n// Flutter Stack with positioned overlay:\n// Stack(children: [\n//   Image.network(url),\n//   Positioned(bottom: 8, right: 8, child: Text('Caption')),\n// ])\n\n// Valdi:\nonRender() {\n  <view>\n    <image src={this.viewModel.imageUrl} width=\"100%\" height=\"100%\" objectFit=\"cover\" />;\n    <label\n      value=\"Caption\"\n      position=\"absolute\"\n      bottom={8}\n      right={8}\n    />;\n  </view>;\n}\n```\n\n## Native Elements\n\n| Flutter Widget | Valdi Element | Notes |\n|---|---|---|\n| `Text` | `<label>` | `value` prop for string content |\n| `TextField` | `<textfield>` | Single-line input |\n| `TextFormField` | `<textview>` | Multi-line input |\n| `Image.network` / `Image.asset` | `<image>` | `src` accepts URL string or resource |\n| `VideoPlayer` | `<video>` | |\n| `ListView` / `GridView` | `<scroll>` + `forEach` | See [Lists](#lists) |\n| `SingleChildScrollView` | `<scroll>` | |\n| `PageView` | `<scroll pagingEnabled={true}>` | |\n| `CircularProgressIndicator` | `<spinner>` | |\n| `Lottie` | `<animatedimage>` | |\n| `ClipRRect` / `ClipOval` | `<view clipToBounds={true} borderRadius={...}>` | |\n| `BackdropFilter` | `<blur>` | iOS only |\n| `UiKitView` / `AndroidView` | `<custom-view iosClass=\"...\" androidClass=\"...\">` | |\n\n## Lists\n\nFlutter's `ListView.builder` uses index-based construction. Valdi uses `forEach` inside a `<scroll>` element. Viewport-aware rendering is automatic — only visible elements are inflated.\n\n```dart\n// Flutter\nListView.builder(\n  itemCount: items.length,\n  itemBuilder: (context, index) {\n    return ListTile(title: Text(items[index].name));\n  },\n)\n```\n\n```tsx\n// Valdi\nonRender() {\n  <scroll>\n    {this.viewModel.items.forEach(item => {\n      <ListItem key={item.id} data={item} />;\n    })}\n  </scroll>;\n}\n```\n\n> [!Important]\n> Do **not** use `map()` — Valdi JSX is emitted as side-effects, not return values. `map()` returns an array that is silently discarded. Use `forEach` or `for...of` loops instead.\n\nFor performance with very large lists, use `lazy={true}` on children to enable viewport-limited rendering:\n\n```tsx\n<scroll>\n  {this.viewModel.items.forEach(item => {\n    <ExpensiveRow key={item.id} data={item} lazy={true} />;\n  })}\n</scroll>\n```\n\n## Navigation\n\n| Flutter | Valdi |\n|---|---|\n| `MaterialApp` / `CupertinoApp` | `NavigationRoot` |\n| `Navigator.push(context, route)` | `navigationController.push(Page, viewModel, context)` |\n| `Navigator.pop(context)` | `navigationController.pop()` |\n| `Navigator.pushReplacement` | `navigationController.push` + `pop` |\n| `showModalBottomSheet` | `navigationController.present(Page, viewModel, context)` |\n| `Navigator.of(context).pop()` from modal | `navigationController.dismiss()` |\n\n```tsx\nimport { NavigationRoot } from 'valdi_navigation/src/NavigationRoot';\nimport { NavigationPageComponent } from 'valdi_navigation/src/NavigationPageComponent';\n\n// App root\nclass App extends Component {\n  onRender() {\n    <NavigationRoot>\n      {$slot(navigationController => {\n        <HomePage navigationController={navigationController} />;\n      })}\n    </NavigationRoot>;\n  }\n}\n\n// Page — annotate with @NavigationPage\n@NavigationPage(module)\nclass HomePage extends NavigationPageComponent<HomeViewModel> {\n  private goToDetail = () => {\n    this.navigationController.push(DetailPage, { id: '123' });\n  };\n\n  onRender() {\n    <view onTap={this.goToDetail}>\n      <label value=\"Go to detail\" />;\n    </view>;\n  }\n}\n```\n\n## Networking\n\n| Flutter | Valdi |\n|---|---|\n| `http.get(uri)` | `client.get('/path')` |\n| `http.post(uri, body: body)` | `client.post('/path', body)` |\n| `dio.get(url)` | `client.get('/path')` |\n| `Future<T>` | `Promise<T>` / `CancelablePromise<T>` |\n| `CancelToken` (dio) | `.cancel()` on the returned promise |\n\n```tsx\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\n\nclass UserList extends StatefulComponent<{}, { users: User[] }> {\n  state = { users: [] };\n\n  private client = new HTTPClient('https://api.example.com');\n  private request?: { cancel(): void };\n\n  onCreate() {\n    this.request = this.client.get('/users');\n    this.request.then(response => {\n      const users = JSON.parse(new TextDecoder().decode(response.body));\n      this.setState({ users });\n    });\n  }\n\n  onDestroy() {\n    // Cancel in-flight request like Flutter's CancelToken\n    this.request?.cancel();\n  }\n\n  onRender() {\n    <scroll>\n      {this.state.users.forEach(user => {\n        <label key={user.id} value={user.name} />;\n      })}\n    </scroll>;\n  }\n}\n```\n\nAdd `valdi_http` to your `BUILD.bazel` deps:\n```python\ndeps = [\"@valdi//src/valdi_modules/src/valdi/valdi_http\"]\n```\n\n## Storage\n\n| Flutter | Valdi |\n|---|---|\n| `SharedPreferences.getString(key)` | `await store.fetchString(key)` |\n| `SharedPreferences.setString(key, value)` | `await store.storeString(key, value)` |\n| `FlutterSecureStorage` | `new PersistentStore(name, { enableEncryption: true })` |\n\n```tsx\nimport { PersistentStore } from 'persistence/src/PersistentStore';\n\nconst store = new PersistentStore('my_store', { enableEncryption: true });\n\n// Store\nawait store.storeString('user_token', token);\n\n// Fetch\nconst token = await store.fetchString('user_token');\n\n// Remove\nawait store.remove('user_token');\n```\n\nAdd to deps: `@valdi//src/valdi_modules/src/valdi/persistence`\n\n## Styling\n\nFlutter uses `ThemeData` and decoration objects. Valdi uses `Style<T>` — typed objects created at module initialization time (never inside `onRender()`).\n\n```dart\n// Flutter\nContainer(\n  decoration: BoxDecoration(\n    color: Colors.white,\n    borderRadius: BorderRadius.circular(12),\n    boxShadow: [BoxShadow(blurRadius: 8, color: Colors.black12)],\n  ),\n  padding: EdgeInsets.all(16),\n  child: Text('Card'),\n)\n```\n\n```tsx\n// Valdi — Style defined at module level, not inside onRender()\nimport { Style } from 'valdi_core/src/Style';\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst cardStyle = new Style<View>({\n  backgroundColor: '#ffffff',\n  borderRadius: 12,\n  boxShadow: '0 2 8 rgba(0,0,0,0.12)',\n  padding: 16,\n});\n\nclass Card extends Component<{ title: string }> {\n  onRender() {\n    <view style={cardStyle}>\n      <label value={this.viewModel.title} />;\n    </view>;\n  }\n}\n```\n\n> [!Important]\n> Always create `Style` objects at the module level or as class properties — **never** inside `onRender()`. Valdi interns styles by assigning an integer ID on first use; creating new instances each render defeats this optimization.\n\nFor theming (equivalent to Flutter's `ThemeData`), use the [Provider pattern](./advanced-provider.md):\n\n```tsx\nconst ThemeProvider = createProviderComponentWithKeyName<ThemeService>('ThemeProvider');\n```\n\n## Provider Pattern\n\nFlutter's `InheritedWidget` / `provider` package maps to Valdi's `createProviderComponentWithKeyName` + `withProviders` HOC.\n\n```dart\n// Flutter\nclass ThemeNotifier extends ChangeNotifier { ... }\nChangeNotifierProvider(create: (_) => ThemeNotifier(), child: MyApp())\n// Consumer: context.watch<ThemeNotifier>()\n```\n\n```tsx\n// Valdi\nimport { createProviderComponentWithKeyName } from 'valdi_core/src/provider/createProvider';\nimport { ProvidersValuesViewModel, withProviders } from 'valdi_core/src/provider/withProviders';\n\nclass ThemeService { primary = '#FFFC00'; }\n\nconst ThemeProvider = createProviderComponentWithKeyName<ThemeService>('ThemeProvider');\n\n// Root provides value\nclass AppRoot extends Component {\n  private theme = new ThemeService();\n  onRender() {\n    <ThemeProvider value={this.theme}><App /></ThemeProvider>;\n  }\n}\n\n// Consumer\ninterface ThemedViewModel extends ProvidersValuesViewModel<[ThemeService]> {}\nclass ThemedButton extends Component<ThemedViewModel> {\n  onRender() {\n    const [theme] = this.viewModel.providersValues;\n    <view backgroundColor={theme.primary}><label value=\"Click me\" /></view>;\n  }\n}\nconst ThemedButtonWithProvider = withProviders(ThemeProvider)(ThemedButton);\n```\n\nSee [Provider documentation](./advanced-provider.md) for full details.\n\n## Key Differences to Watch\n\n| Flutter behavior | Valdi behavior |\n|---|---|\n| `build(BuildContext context)` receives context | `onRender()` takes no parameters — use Provider for DI |\n| `const` constructor for widget optimization | No `const` constructors — style interning handles optimization |\n| `Widget` is immutable; `State` is mutable | `viewModel` is `ReadOnly<VM>`; `state` is `ReadOnly<State>` |\n| `map()` works naturally in `build()` (returns Widget list) | `map()` is **silent no-op** in `onRender()` — use `forEach` |\n| Render props via `WidgetBuilder` (`(ctx) => Widget`) | Render props via `() => void` callback called inside `onRender()` |\n| `children: [Widget, Widget]` in constructor | Children projected via `<slot />` — see [Slots](./core-slots.md) |\n| `GlobalKey` for cross-widget communication | `ElementRef` / `IRenderedElementHolder<T>` |\n\n## See Also\n\n- [The Mighty Component](./core-component.md)\n- [Component States](./core-states.md)\n- [FlexBox Layout](./core-flexbox.md)\n- [Navigation](./navigation.md)\n- [Provider](./advanced-provider.md)\n- [Working with AI Assistants](./ai-tooling.md)\n"
  },
  {
    "path": "docs/docs/native-annotations.md",
    "content": "# Annotations\n\n## Concept\n\nThe Valdi compiler integrates tightly with the TypeScript compiler. It supports a few annotations, that can be used to associate TypeScript types with some Valdi concepts.\n\nThe annotations are declared in comments, because TypeScript does not support compile time annotations.\n\n> [!Warning]\n> When composing multiple classes with `@Export*`, e.g. having an `@ExportModel` `Component` which exposes a `@ExportModel` on a `Context`, ensure that they are all in the same file. This restriction does not apply for pure TS/JS usages, only for when where generated native code need to depend on other generated native code.\n\n\n## Example\n\n### TypeScript annotated code\n\n```ts\ninterface MyComponentViewModel {}\n/**\n * @Context\n * @ExportModel({\n *   ios: 'SCMyComponentContext',\n *   android: 'com.snap.myfeature.MyComponentContext'\n * })\n */\ninterface MyComponentContext {\n    // IMPORTANT NOTE: using optional fields will allow mutating fields\n    // without breaking the consuming native android and iOS code:\n    // - optional fields will not be initialized in the constructor\n    // - non-optional fields will require to be initialized in the constructor\n    str?: string;\n    callback?: () => void;\n}\n/**\n * @Component\n * @ExportModel({\n *   ios: 'SCMyComponentView',\n *   android: 'com.snap.myfeature.MyComponentView'\n * })\n */\nclass MyComponent extends Component<MyComponentViewModel, MyComponentContext> {\n    onRender() {\n        <view onTap={this.onTap}>\n            <label str={\"context.str:\" + this.context.str ?? \"\"}/>;\n        </view>\n    }\n    onTap = () => {\n        if (this.context.callback) {\n            this.context.callback()\n        }\n    }\n}\n```\n\n### Usage in Obj-c\n\n```objectivec\n// Init context\nSCMyComponentContext *context = [[SCMyComponentContext alloc] init];\ncontext.str = @\"Hello!\"; // NOTE: since the field is declared optional in typescript, it can be initialized independently of the constructor\ncontext.callback = ˆ{\n    NSLog(\"the context's callback was called from typescript!\");\n}\n// Init view\nUIView *view = [[SCMyComponentView alloc]\n    initWithViewModel:nil\n     componentContext:context];\n```\n\n> [!Note]\n> The TypeScript component associated to the root view will be destroyed once the Objective-C root view instance is deallocated. Please make sure that there are no retain cycles between the dependencies passed to the root view through the view model and component context otherwise the root view might leak and the TypeScript component won't be destroyed.\n\n### Usage in Kotlin\n\n```java (works better than kotlin syntax highlighting)\n@Inject lateinit var runtime: IValdiRuntime\n// Init context\nval context = MyComponentContext()\ncontext.str = \"Hello!\"; // NOTE: since the field is declared optional in typescript, it can be initialized independently of the constructor\ncontext.callback = {\n    println(\"the context's callback was called from typescript!\");\n}\n// Init view\nval view: View = MyComponentView.create(\n    runtime = runtime,\n    viewModel = null,\n    componentContext = context\n)\n\n// Destroy the view once we're done with it, which will call onDestroy()\n// and release the associated resources\nview.destroy()\n```\n\n> [!Note]\n> Unlike regular Android views, Valdi views need to be explicitly destroyed by calling `destroy()`. Failure to call destroy will result in leaks and will prevent the TypeScript component's destructure!\n\n## Exhaustive list\n\nThis is the list of available annotations:\n\n### Export Annotations\n\nThese annotations control what gets exported to native code.\n\n```ts\n/**\n * Parameters that can be passed to generate native annotations\n */\ninterface NativeClass {\n    ios?: string;\n    android?: string;\n}\n\n/**\n * Can be set on a Component class or any TypeScript interface\n * Asks the compiler to emit a native class representing the Component/Type.\n */\n@ExportModel(class: NativeClass);\n\n/**\n * Can be set on a TypeScript interface.\n * Asks the compiler to emit an interface representing the Component/Type.\n * Native code will have to implement the interface.\n */\n@ExportProxy(class: NativeClass);\n\n/**\n * Can be set on an exported TypeScript function.\n * Asks the compiler to emit Objective-C/Swift/Kotlin functions which can call\n * this function.\n */\n@ExportFunction(class: NativeClass);\n\n/**\n * Can be set on a TypeScript enum.\n * Asks the compiler to emit Objective-C/Swift/Kotlin enums.\n * Only string and int enums are supported.\n */\n@ExportEnum(class: NativeClass);\n\n/**\n * Can be set on a TypeScript definition file (.d.ts).\n * Tells the compiler to generate Objective-C/Swift/Kotlin modules\n * that must implement the API for the file itself.\n * See documentation about polyglot modules for more details.\n */\n@ExportModule(class: NativeClass);\n```\n\n> [!Important]\n> **Marshalling:** `@ExportModel` and `@ExportProxy` use **different marshalling APIs** on Objective-C. Using `SCValdiMarshallableObjectMarshall` for a proxy type is incorrect and can cause subtle bugs. See [ExportModel vs ExportProxy: Marshalling](export-model-vs-export-proxy-marshalling.md) for details and how to marshal each type correctly.\n\n### Component Annotations\n\nThese annotations mark component-related interfaces and classes.\n\n```ts\n/**\n * Notifies that the class is the exported component class for the TSX file.\n * must be used: alongside @ExportModel\n * must be used: on a class extending Component<>\n */\n@Component();\n\n/**\n * Can be set on a TypeScript interface\n * Notifies that the interface is the view model for the matching @Component.\n * This is used whenever generating a native view class, so that\n * the viewModel parameter will be typed with this interface.\n * must be used: alongside @ExportModel\n * must be used: on an interface\n * must be used: in the same file as the matching @Component\n */\n@ViewModel();\n\n/**\n * Can be set on a TypeScript interface\n * Notifies that the interface is the context for the matching @Component.\n * This is used whenever generating a native view class, so that\n * the context parameter will be typed with this interface.\n * must be used: alongside @ExportModel\n * must be used: on an interface\n * must be used: in the same file as the matching @Component\n */\n@Context();\n```\n\n### Property and Function Modifiers\n\nThese annotations modify the behavior of properties and functions in exported types.\n\n```ts\n/**\n * Marks a property in a Context or ViewModel to be injected from native\n * dependency injection (Dagger for Android).\n * \n * Options:\n *   iosOnly: true - Only inject on iOS platform\n *   androidOnly: true - Only inject on Android platform\n * \n * must be used: on non-optional properties only\n * must be used: in a Context or ViewModel interface\n * \n * Example:\n *   // @Injectable\n *   configurationProvider: ConfigurationProvider;\n * \n *   // @Injectable({androidOnly: true})\n *   androidService: SomeService;\n */\n@Injectable(options?: {iosOnly?: boolean, androidOnly?: boolean});\n\n/**\n * Marks a function/callback that should only be callable once.\n * After the first call, subsequent calls will be no-ops.\n * \n * Use cases:\n *   - One-time initialization callbacks\n *   - Preventing multiple form submissions\n *   - Event handlers that should only fire once\n * \n * must be used: on function properties\n * \n * Example:\n *   // @SingleCall\n *   callback: () => void;\n */\n@SingleCall();\n\n/**\n * Indicates that a function should be executed on a worker/background thread\n * instead of the main thread.\n * \n * must be used: on functions returning Promise<T> or void only\n * must be used: on function properties or methods\n * \n * Example:\n *   // @WorkerThread\n *   heavyComputation: (data: string) => Promise<Result>;\n * \n *   // @WorkerThread\n *   backgroundTask: () => void;\n */\n@WorkerThread();\n\n/**\n * (LEGACY) Marks optional properties that should NOT be included in the\n * generated native constructor. These properties can be set after construction.\n * \n * must be used: on optional properties only (marked with ?)\n * cannot be used: with @ExportProxy\n * deprecated: when not using legacy constructors\n * \n * Example:\n *   requiredParam: string;\n *   \n *   // @ConstructorOmitted\n *   optionalParam?: string; // Can be set after construction\n */\n@ConstructorOmitted();\n```\n\n### Type Conversion Annotations\n\nThese annotations handle type conversion and marshalling between TypeScript and native code.\n\n```ts\n/**\n * Marks an unrecognized TypeScript type to be marshalled as an untyped/any\n * value in native code.\n * \n * Use cases:\n *   - Working with third-party types not registered with Valdi\n *   - Dynamic data structures\n *   - Gradual migration of code\n * \n * must be used: on property types\n * \n * Example:\n *   // @Untyped\n *   dynamicData: SomeUnrecognizedType;\n */\n@Untyped();\n\n/**\n * Marks an unrecognized TypeScript type to be marshalled as a string-keyed\n * map with untyped values (Map<string, any> in native code).\n * \n * must be used: on property types\n * \n * Example:\n *   // @UntypedMap\n *   metadata: SomeMapLikeType;\n */\n@UntypedMap();\n\n/**\n * Defines a custom type converter function for transforming TypeScript types\n * to/from native types.\n * \n * must be used: on exported functions\n * must return: a generic type with two type parameters\n * \n * Example:\n *   // @NativeTypeConverter\n *   export function convertMyType<From, To>(value: From): To {\n *     // Conversion logic\n *     return converted as To;\n *   }\n */\n@NativeTypeConverter();\n```\n\n### Advanced/Internal Annotations\n\nThese annotations are typically used internally by the framework or for advanced use cases.\n\n```ts\n/**\n * Marks a method in a Component class as an \"action\" that can be tracked.\n * \n * must be used: on class member functions\n * must be used: within a @Component class\n * must be used: in .vue, .ts, or .tsx files\n */\n@Action();\n\n/**\n * (INTERNAL) Registers a native type that is implemented natively but used\n * from TypeScript. User code should generally use @ExportModel or @ExportProxy.\n */\n@NativeClass(class: NativeClass);\n\n/**\n * (INTERNAL) Similar to @NativeClass but for interface types.\n */\n@NativeInterface(class: NativeClass);\n\n/**\n * (INTERNAL) Marks an interface as a native template element (UI component)\n * definition. Used internally by Valdi for defining native UI elements.\n */\n@NativeTemplateElement();\n```\n\n### Deprecated Annotations\n\nThese annotations have been superseded by newer alternatives but may still be supported for backwards compatibility.\n\n```ts\n/**\n * @deprecated Use @ExportModel instead\n */\n@GenerateNativeClass(class: NativeClass);\n\n/**\n * @deprecated Use @ExportProxy instead\n */\n@GenerateNativeInterface(class: NativeClass);\n\n/**\n * @deprecated Use @ExportEnum instead\n */\n@GenerateNativeEnum(class: NativeClass);\n\n/**\n * @deprecated Use @ExportFunction instead\n */\n@GenerateNativeFunction(class: NativeClass);\n```\n"
  },
  {
    "path": "docs/docs/native-bindings.md",
    "content": "# Native Bindings\n\n## Communicating between native and JS\n\nValdi is designed with a clear performance motto: *\"What is the highest level API we can expose that's easy and safe to use while allowing us to achieve a high level of performance?\"*\n\nTo achieve this, Valdi uses a unified data container called `Valdi::Value` in C++ to represent data as it crosses the bridge between TypeScript, Objective-C, and Java. This minimizes the overhead of data conversion and enables features like interned strings and styles.\n\nThere are two main ways you can communicate between native and JS.\n\nChoose which one to use based on your use case.\n\n### Using the Context (most common, recommended)\n\nFor interaction between your view's TypeScript and native code, the Context object will probably be the best solution for you.\n\nUsing the [annotations](native-annotations.md) API, the Valdi compiler can generate strongly typed native interfaces/classes which do the conversions in and out between TypeScript and native code.\n\nThis is an example of an interaction between both platforms with them:\n\nYou can call native logic from TypeScript valdi code:\n\n```ts\n/**\n * @Context\n * @ExportModel({\n *   ios: 'SCYourComponentContext',\n *   android: 'com.snap.myfeature.YourComponentContext'\n * })\n */\ninterface YourComponentContext {\n  callMeFromTS?();\n}\n/**\n * @Component\n * [...]\n */\nclass YourComponent extends Component<YourComponentViewModel, YourComponentContext> {\n  onMyButtonWasTapped() {\n    // Calls callMeFromTS: on the SCYourComponentContext (if it has been configured)\n    this.context.callMeFromTS?.();\n  }\n}\n```\n\nThis is what the generated Obj-C counterpart looks like:\n\n```objectivec\n@interface SCYourComponentContext: SCValdiMarshallableObject\n\n@property (copy, nonatomic) SCYourComponentContextOnDoneBlock _Nullable callMeFromTS;\n\n- (instancetype _Nonnull)init;\n\n// ...\n\n@end\n\n//////////\n\n// So you can instantiate SCYourComponentContext and configure it with the callMeFromTS block:\nSCYourComponentContext *componentContext = [[SCYourComponentContext alloc] init];\ncomponentContext.callMeFromTS = ^{\n  // Will be called when this.context.callMeFromTS() is called in TS.\n  NSLog(@\"Hello from Objective-C\");\n}\n```\n\nand Kotlin:\n```kotlin\npackage com.snap.myfeature.YourComponentContext\n\nclass SCYourComponentContextImpl {\n    val onDone: (() -> Unit)?\n    // ...\n}\n\n//////////\n\n// So you can instantiate YourComponentContext and configure it with the callMeFromTS block:\nval componentContext = YourComponentContext()\ncomponentContext.callMeFromTS = {\n  // Will be called when this.context.callMeFromTS() is called in TS.\n  print(\"Hello from Kotlin\")\n}\n```\n\n\nYou can also pass callbacks from JS to native:\n\nTypeScript:\n```ts\ninterface YourComponentContext {\n  callMeFromTS?(completion: (arg: string) => void);\n}\nclass YourComponent extends Component<any, YourComponentContext> {\n  onMyButtonWasTapped() {\n    this.context.callMeFromTS((arg) => {\n      console.log('the native code called the completion function with arg:', arg);\n    });\n  }\n}\n```\n\nObjective-C:\n```objectivec\ncomponentContext.callMeFromTSWithCompletion = ^(YourComponentContextCallMeFromTSCompletionBlock completion) {\n  // This will call the TS callback and provide the given value.\n  completion(@\"I got you loud and clear\");\n}\n```\n\nKotlin:\n```kotlin\ncomponentContext.callMeFromTSWithCompletion = { completion ->\n  // This will call the TS callback and provide the given value.\n  completion(@\"I got you loud and clear\");\n}\n```\n\nThis will print 'the native code called the completion function with arg: I got you loud and clear'.\n\n### ExportFunction\n\nIf you need to use TypeScript code outside of a Valdi component, you can use the `@ExportFunction` annotation:\n```ts\n// @ExportFunction({ios: 'SCMultiplier', android: 'com.valdi.example.Multiplier'})\nexport function multiply(left: number, right: number): number {\n  return left * right;\n}\n```\nThis will generate Objective-C/Swift/Kotlin files which can call this function, and will handle parameter serialization/deserialization automatically:\n```objectivec\n#import <ModuleName/SCMultiplier.h>\n\n- (void)viewDidLoad\n{\n  /// inject the id<SCValdiRuntimeProtocol> dependency\n  [valdiRuntime getJSRuntimeWithBlock:^(id<SCValdiJSRuntime> runtime) {\n    double result = SCMultiplierMultiply(runtime, 2, 4);\n    NSLog(@\"Result is: %fs\", result);\n  }];\n}\n```\n\n```java (works better than kotlin syntax highlighting)\n@Inject lateinit var runtime: IValdiRuntime\n\nfun onCreate() {\n  runtime.createScopedJSRuntime {\n    val result = Multiplier.multiply(it, 2, 4)\n    println(\"Result is: ${result}\")\n  }\n}\n```\n\nThis API supports the whole range of the Valdi [annotations](native-annotations.md). As such it can be used to pass in/return complex objects:\n```ts\n// @ExportModel({ios: 'SCValdiUser', android: 'com.valdi.example.User'})\ninterface User {\n  name: string;\n}\n\n// @ExportModel({ios: 'SCValdiSearchEngine', android: 'com.valdi.example.SearchEngine'})\ninterface SearchEngine {\n  search(term: string, completion: (results: User[]) => void);\n}\n\n// @ExportFunction({ios: 'SCValdiSearchEngineFactory', android: 'com.valdi.example.SearchEngineFactory'})\nexport function makeSearchEngine(users: User[]): SearchEngine {\n  // Note: in a near future, you will be able to make the class itself\n  // implements the interface and return it.\n  const engine = new ConcreteSearchEngine(users);\n\n  return {\n    search(term: string, completion: (results: User[]) => void) {\n      const results = engine.performSearch(term);\n      completion(results);\n    }\n  };\n}\n\n```\n\niOS:\n```objectivec\n- (void)viewDidLoad\n{\n  [UIView.valdiRuntime getJSRuntimeWithBlock:^(id<SCValdiJSRuntime> runtime) {\n    NSArray<SCValdiUser *> *allUsers = fetchAllUsers();\n    SCValdiSearchEngine *searchEngine = SCValdiSearchEngineFactoryMakeSearchEngine(runtime, allUsers);\n    self.searchEngine = searchEngine;\n  }];\n}\n\n// Later on...\n- (void)updateUsers\n{\n  [self.searchEngine searchWithTerm:@\"Simon\" withCompletion:^(NSArray<SCValdiUser *> *results) {\n    NSLog(@\"Found those users: %@\", results);\n  }];\n}\n```\n\nAndroid:\n```java (works better than kotlin syntax highlighting)\n@Inject lateinit var runtime: IValdiRuntime\nvar searchEngine: SearchEngine? = null\n\nfun onCreate() {\n  runtime.createScopedJSRuntime {\n    val allUsers = fetchAllUsers()\n    val searchEngine = SearchEngineFactory.makeSearchEngine(it, allUsers)\n    this.searchEngine = searchEngine\n  }\n}\n\n// Later on...\nfun updateUsers() {\n  searchEngine?.search(\"Simon\") {\n    println(\"Found those users: ${it}\")\n  }\n}\n```\n\nNote that calling a JS function will automatically asynchronously dispatch to the JS thread if needed. If your function need to return a value synchronously to platform code, make sure you call this function within a createScopedJSRuntime scope. If you use asynchronous completion functions this will never be a problem.\n\n### Using a Polyglot Module\n\nIf you want to be able to write a reuseable module using a separate language like Kotlin, Java, Objective-C, C++ or Swift, with an exposed TS API, you can make a polyglot module. See documentation about [polyglot modules](./native-polyglot.md) for more details.\n\n---\n\n## Type System Reference\n\nThis section documents all TypeScript types that can be marshalled between TypeScript and native code.\n\n### Supported Primitive Types\n\n| TypeScript Type | iOS (Obj-C) | iOS (Swift) | Android (Kotlin) | C++ | Notes |\n|----------------|-------------|-------------|------------------|-----|-------|\n| `string` | `NSString *` | `String` | `String` | `std::string` | UTF-8 encoded |\n| `number` | `double` | `Double` | `Double` | `double` | 64-bit floating point |\n| `boolean` | `BOOL` | `Bool` | `Boolean` | `bool` | |\n| `void` | `void` | `Void` | `Unit` | `void` | For return types |\n| `any` | `id` | `Any` | `Any` | `Value` | Dynamic/untyped value |\n| `object` | `id` | `Any` | `Any` | `Value` | Untyped object |\n\n### Supported Complex Types\n\n| TypeScript Type | Native Equivalent | Notes |\n|----------------|------------------|-------|\n| `T[]` | Array/NSArray/List | Arrays of any supported type |\n| `Promise<T>` | Async operation | Mapped to platform async patterns |\n| `CancelablePromise<T>` | Cancelable async | Extended Promise with cancellation |\n| `Map<string, any>` | Dictionary/Map | Currently only supports string keys and any values |\n| `(arg: T) => R` | Block/Closure/Lambda | Function/callback types |\n| `T \\| null \\| undefined` | Optional/nullable | Nullable types |\n| `T?` | Optional/nullable | TypeScript optional syntax |\n\n### Special Types\n\n| TypeScript Type | Purpose | Native Equivalent |\n|----------------|---------|------------------|\n| `Uint8Array` | Binary data | `Data` (iOS) / `ByteArray` (Android) |\n| `Long` | 64-bit integers | `int64_t` / `Long` |\n| `Number` | Explicit double | Same as `number` but explicit |\n\n### Generated Types\n\nTypes defined with annotations can be passed between TypeScript and native:\n\n- **`@ExportModel`** interfaces/classes → Generated native classes\n- **`@ExportProxy`** interfaces → Native must implement\n- **`@ExportEnum`** enums → Generated native enums\n\n**Example:**\n```typescript\n// @ExportModel({ios: 'SCUser', android: 'com.example.User'})\ninterface User {\n  name: string;\n  age: number;\n  friends?: User[];  // Optional array of User\n}\n```\n\n### Generic Types\n\nGenerics are supported on generated types:\n\n```typescript\n// @ExportModel({ios: 'SCContainer', android: 'com.example.Container'})\ninterface Container<T> {\n  value: T;\n}\n\n// Usage\ninterface MyContext {\n  userContainer: Container<User>;\n  stringContainer: Container<string>;\n}\n```\n\n> **Note:** Generics only work on types annotated with `@ExportModel`. Generic parameters must be resolved to concrete types at the interface boundary.\n\n---\n\n## Type Limitations and Constraints\n\n### Union Types\n\n**✅ SUPPORTED:** Union with null/undefined\n```typescript\nproperty: string | null;\nproperty: string | undefined;\nproperty?: string;  // Equivalent to: string | undefined\n```\n\n**❌ NOT SUPPORTED:** Other union types\n```typescript\nproperty: string | number;  // ERROR: Only null/undefined unions supported\nproperty: 'red' | 'blue' | 'green';  // ERROR: Use enum instead\n```\n\n**Solution:** Use enums for multiple value choices:\n```typescript\n// @ExportEnum({ios: 'Color', android: 'com.example.Color'})\nenum Color {\n  Red = 'red',\n  Blue = 'blue',\n  Green = 'green'\n}\n\ninterface Config {\n  color: Color;  // ✅ Works\n}\n```\n\n### Map Type Limitations\n\n**⚠️ PARTIAL SUPPORT:**\n```typescript\n// ✅ SUPPORTED: Map with string keys and any values\nmetadata: Map<string, any>;\n\n// ❌ NOT FULLY SUPPORTED: Typed maps\ntypedMap: Map<string, User>;  // Limited - treated as Map<string, any>\n\n// ❌ NOT SUPPORTED: Non-string keys\nnumberMap: Map<number, string>;  // Not supported\n```\n\n**Workaround:** Use objects with `@ExportModel` for typed dictionaries:\n```typescript\n// @ExportModel\ninterface UserMap {\n  [key: string]: User;  // Use index signature\n}\n```\n\n### Array Nesting\n\nArrays can be nested to any depth:\n```typescript\nmatrix: number[][];  // ✅ 2D array\ncube: number[][][];  // ✅ 3D array\n```\n\n---\n\n## Type Conversion Behavior\n\n### Number Precision\n\nTypeScript `number` always maps to native `double` (64-bit floating point):\n\n```typescript\ninterface Data {\n  count: number;  // Native: double (not int!)\n}\n```\n\n**For 64-bit integers:**\n```typescript\ninterface Data {\n  timestamp: Long;  // Use Long type for precise 64-bit integers\n}\n```\n\n> **Warning:** JavaScript numbers can only precisely represent integers up to 2^53 - 1. For larger integers, use `Long` type or string representation.\n\n### Array Conversion\n\nArrays are **copied** when crossing the native/TypeScript boundary:\n\n```typescript\ninterface DataProcessor {\n  // Array is copied from native to TS\n  processData(items: string[]): void;\n  \n  // Array is copied from TS to native\n  getData(): string[];\n}\n```\n\n**Implications:**\n- Modifications in one environment don't affect the other\n- Large arrays have serialization overhead\n- Consider using `Uint8Array` for binary data to reduce overhead\n\n### Object Marshalling\n\nOnly objects with annotations can be marshalled:\n\n```typescript\n// ✅ Can be passed - has @ExportModel\n// @ExportModel\ninterface User {\n  name: string;\n}\n\n// ❌ Cannot be passed - plain object\ninterface Config {\n  data: { key: string, value: number };  // ERROR\n}\n```\n\n**Solution:** Use `any` with `@Untyped` annotation:\n```typescript\ninterface Config {\n  // @Untyped\n  data: any;  // Dynamic object, no type safety\n}\n```\n\nOr define a proper interface:\n```typescript\n// @ExportModel\ninterface KeyValue {\n  key: string;\n  value: number;\n}\n\ninterface Config {\n  data: KeyValue;  // ✅ Works\n}\n```\n\n### Callback Lifecycle\n\nCallbacks are reference-counted:\n\n```typescript\ninterface Context {\n  callback: () => void;\n}\n```\n\n**Memory Management:**\n- Native holds a strong reference to the callback\n- Callback is released when native object is destroyed\n- Use `@SingleCall` to automatically release after first invocation\n\n```typescript\ninterface Context {\n  // @SingleCall\n  onComplete: () => void;  // Automatically released after first call\n}\n```\n\n---\n\n## Performance Considerations\n\n### Thread Safety\n\nAll TypeScript function calls are dispatched to the JavaScript thread:\n\n```typescript\ninterface DataFetcher {\n  // Automatically dispatches to JS thread\n  fetchData(): Promise<Data>;\n}\n```\n\n**For synchronous calls:**\n```objectivec\n// iOS: Use scoped runtime\n[valdiRuntime getJSRuntimeWithBlock:^(id<SCValdiJSRuntime> runtime) {\n  // Synchronous calls work here\n  double result = MyFunction(runtime, arg);\n}];\n```\n\n```kotlin\n// Android: Use scoped runtime\nruntime.createScopedJSRuntime { jsRuntime ->\n  // Synchronous calls work here\n  val result = MyFunction.call(jsRuntime, arg)\n}\n```\n\n**For heavy operations:**\n```typescript\ninterface Processor {\n  // @WorkerThread\n  processLargeDataset(data: Uint8Array): Promise<Result>;\n}\n```\n\n### Data Serialization Overhead\n\nEach parameter is serialized/deserialized when crossing the boundary:\n\n```typescript\n// ❌ BAD: Many small calls\nfor (let i = 0; i < 1000; i++) {\n  context.updateProgress(i);  // 1000 boundary crossings!\n}\n\n// ✅ GOOD: Batch operations\ncontext.updateProgressBatch(progressArray);  // 1 boundary crossing\n```\n\n### Callback Overhead\n\nMinimize chatty APIs:\n\n```typescript\n// ❌ BAD: Callback for each item\ninterface ItemProcessor {\n  processItems(items: Item[], onEachItem: (item: Item) => void): void;\n}\n\n// ✅ GOOD: Single completion callback\ninterface ItemProcessor {\n  processItems(items: Item[]): Promise<Item[]>;\n}\n```\n\n---\n\n## Best Practices\n\n### Do's ✅\n\n1. **Keep interfaces simple** - Use primitive types when possible\n2. **Use `@ExportModel` for complex types** - Don't rely on `any`\n3. **Document null behavior** - Be explicit about optional properties\n4. **Use `@SingleCall` for one-time callbacks** - Prevents memory leaks\n5. **Batch operations** - Reduce boundary crossings\n6. **Use `Promise` for async operations** - More ergonomic than callbacks\n7. **Use `Uint8Array` for binary data** - More efficient than arrays\n\n### Don'ts ❌\n\n1. **Don't use union types** (except with null/undefined)\n2. **Don't pass large objects frequently** - High serialization cost\n3. **Don't assume synchronous execution** - Use scoped runtime if needed\n4. **Don't hold strong references to callbacks indefinitely**\n5. **Don't pass plain JavaScript objects** - Use `@ExportModel` instead\n6. **Don't use `Map` with non-string keys**\n\n### Common Patterns\n\n**Async Operations:**\n```typescript\ninterface DataFetcher {\n  // ✅ PREFERRED: Promise-based\n  fetchData(): Promise<Data>;\n}\n```\n\n**Bidirectional Communication:**\n```typescript\ninterface Chat {\n  sendMessage(text: string): void;\n  \n  // Native → TS callbacks\n  onMessageReceived?: (text: string) => void;\n  onError?: (error: string) => void;\n}\n```\n\n**Resource Management:**\n```typescript\ninterface FileReader {\n  open(path: string): void;\n  read(): Uint8Array;\n  close(): void;  // Important: Always provide cleanup\n}\n```\n\n---\n\n## See Also\n\n- [Native Annotations](./native-annotations.md) - Complete annotation reference\n- [Native Context](./native-context.md) - Context patterns and dependency injection\n- [Polyglot Modules](./native-polyglot.md) - Writing native modules\n- [Integration Codelabs](../codelabs/integration_with_native/1-introduction.md) - Step-by-step integration guides\n"
  },
  {
    "path": "docs/docs/native-collectionview.md",
    "content": "# Native CollectionViews\n\n## Introduction\n\nWhen using the `@ExportModel` on a component, Valdi generates Objective-C, Swift, and Kotlin View classes that act as entry points from iOS/Android into your Valdi component in TypeScript. Your component can represent an entire screen, or it can represent a smaller UI component as part of an existing iOS/Android view hierarchy. For instance, it can represent a cell inside a `UITableView` or `RecyclerView` scrollable list.\n\nCreating an entry point view can be an expensive operation depending on the complexity of your TypeScript component. It is thus best to avoid creating root views when scrolling, for example when integrating a Valdi view inside an iOS's `UITableViewCell` or inside an Android's `RecyclerView` item view. We will look at two options that you can use to efficiently integrate a Valdi view inside an existing iOS/Android view hierarchy that uses `UITableView`, `UICollectionView` or `RecyclerView`.\n\n### Update view models on scroll\n\nThe first option is to create your entry point view inside the view instance representing your cell or item, and provide it the right view model for the item it represents. You might have something like `SCMyTableViewCell`, meant to represent a cell inside the `UITableView`. Inside `SCMyTableViewCell`, you can create an instance of your Valdi view with no view models initially, and whenever `SCMyTableViewCell` is being displayed, you can pass the view model that contains the data that your Valdi component should display. When scrolling, `UITableView`/`RecyclerView` will ask you to populate the UI, and you can implement those calls by resolving the view model to display and pass it to the Valdi view. The number of root components alive in this approach will be equal to the number of visible cells, as the components are re-used during scrolling.\n\nThis option is probably natural for many developers, as it is a common pattern on iOS and Android. It is however not necessarily efficient performance wise, as every time the view model is passed to the component, the framework will have to:\n- Convert the view model to TypeScript.\n- Trigger a render pass.\n- Evaluate your render function and apply all the changes.\n- Calculate the layout.\n- Populate the UI.\n\n### Attach root view of an existing component on scroll\n\nThe second option is to create your components ahead of time, before your `UITableView`/`RecyclerView` is even displayed, and attach a root view to your component whenever it becomes visible. When `UITableView`/`RecyclerView` is asking to populate the UI, instead of resolving the view model for your cell, you'd resolve the _component_ and provide it a view on which the UI should be displayed on. Instead of holding an array of data that represents what you want to display, you'd hold an array of Valdi components. You pass the data once to the components, when you are creating them, and those components will hold the data instead of holding it in native code (Objective-C/Swift/Kotlin). This approach allows the framework to cache more things under the hood, like the layout calculation, and will reduce work that needs to happen during scrolling. The trade-off is that the number of root components alive will be equivalent to the number of total cells in the whole scrollable area. This is often not a problem unless each cell has a complex hierarchy and you have multiple thousands of cells to display.\n\n#### Creating a component without UI\n\nYou can create a component without UI by creating a `ValdiContext` instance directly, without a root view. To do this, you can use `-[SCValdiRuntime createContextWithViewClass:viewModel:componentContext:]` on iOS or `Runtime.createValdiContext` on Android.\n\nLet's consider this component:\n```ts\n// @ViewModel\n// @ExportModel({ios: 'SCMyCellItemViewModel', android: 'com.snap.valdi.MyCellItemViewModel'})\ninterface ViewModel {\n  label: string;\n}\n\n// @ExportModel({ios: 'SCMyCellItemView', android: 'com.snap.valdi.MyCellItemView'})\nexport class MyCellItem extends Component<ViewModel> {\n  // Render code...\n}\n```\n\nYou can create a `ValdiContext` for this component as follow:\n\niOS:\n```objectivec\n// Get the runtime instance\nid<SCValdiRuntime> runtime = /* ...*/;\n\n// Create view model\nSCMyCellItemViewModel *viewModel = [SCMyCellItemViewModel new];\nviewModel.label = @\"MyLabel\";\n\n// Create the component\nid<SCValdiContextProtocol> valdiContext = [runtime createContextWithViewClass:[SCMyCellItemView class] viewModel:viewModel componentContext:nil];\n// Store the context\n```\n\nAndroid:\n```java (works better than kotlin syntax highlighting)\n// Get the runtime instance\nval runtime: ICValdiRuntime\n\n// Create the view model\nval viewModel = MyCellItemViewModel()\nviewModel.label = \"MyLabel\"\n\n// Create the component\nruntime.createValdiContext(MyCellItemView.componentPath, viewModel, null, null) { valdiContext ->\n  // Store the context\n}\n```\n\nThis will asynchronously trigger the creation of your TypeScript component. There won't be any UI displayed yet, but the framework will still respond to the render calls and will store the render output. All those functions are thread safe and can be called in a background thread. On iOS, the component will be destroyed when the `ValdiContext` is deallocated. On Android, it will be destroyed when `destroy()` is explicitly called on the `ValdiContext` instance.\n\n#### Populating the UI\n\nTo populate the UI on your component, you need to provide a root view to the `ValdiContext` instance. You can create an empty `ValdiView` or `SCValdiView` in your `SCMyTableViewCell`, and set it as the root view to the context:\n\niOS:\n```objectivec\n- (void)populateUIForCell:(SCMyTableViewCell *)cell atRow:(NSUInteger)row\n{\n  // Resolve the ValdiContext\n  id<SCValdiContextProtocol> valdiContext = _valdiContexts[row];\n  // Attach the UI\n  valdiContext.rootView = cell.valdiViewHost;\n}\n```\n\nAndroid:\n```java (works better than kotlin syntax highlighting)\nfun populateUI(cell: MyRecyclerViewItem, row: Int) {\n  // Resolve the ValdiContext\n  val valdiContext = valdiContexts[row]\n  // Attach the UI\n  valdiContext.rootView = cell.valdiViewHost\n}\n```\n\nWith this approach, we completely dissociate the UI from the Valdi components. We use our components as objects that process their view models and internally resolve the elements. Whenever the UI is actually needed, we attach a view host to display it.\n\n#### Measuring the cell\n\n`UITableView`/`RecyclerView` requires the consumer to provide the size for the cells before it can layout the elements. Once you've created the `ValdiContext` instance, you can measure it by using `-[SCValdiContext measureLayoutWithMaxSize:direction:]` or `ValdiContext.measureLayout()`:\n\niOS:\n```objectivec\n- (CGSize)sizeForItemAtRow:(NSUInteger)row\n{\n  // Resolve the ValdiContext\n  id<SCValdiContextProtocol> valdiContext = _valdiContexts[row];\n  // Measure the layout\n  CGSize maxSize = CGSizeMake(self.view.bounds.size.width, CGFLOAT_MAX)\n  return [valdiView measureLayoutWithMaxSize:maxSize direction:SCValdiLayoutDirectionLTR];\n}\n```\n\nAndroid:\n```java (works better than kotlin syntax highlighting)\n- (Double)heightForItew(row: Int) {\n  // Resolve the ValdiContext\n  val valdiContext = valdiContexts[row]\n  // Measure the layout\n  val maxWidth = View.MeasureSpec.makeMeasureSpec(view.width, View.MeasureSpec.AT_MOST)\n  val maxHeight = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)\n  return valdiContext.measureLayout(maxWidth, maxHeight).height\n}\n```\n\nNote that since Valdi components render asynchronously, you might have to wait until the render completes before being able to return a size. For this you can use the `waitUntilAllUpdatesCompleted` method:\n\niOS:\n```objectivec\n  // Resolve the ValdiContext\n  id<SCValdiContextProtocol> valdiContext = _valdiContexts[row];\n\n  [valdiContext waitUntilRenderCompletedWithCompletion:^{\n    // Updates have completed\n  }];\n```\n\nAndroid:\n```java (works better than kotlin syntax highlighting)\n  // Resolve the ValdiContext\n  val valdiContext = valdiContexts[row]\n  valdiContext.waitUntilAllUpdatesCompleted {\n    // Updates have completed\n  }\n```\n"
  },
  {
    "path": "docs/docs/native-context.md",
    "content": "# Component Context\n\n## Basics\nThe context object can be used to provide services, static immutable data and bridge methods to all Components in your Component tree.\nIt can be accessed through `this.context` inside your Component. It is initially created from native code and passed to the root Component, which automatically forwards it by default to all children:\n\nTypeScript:\n```ts\n// @Context\n// @ExportModel({ios: 'SCMyComponentContext'})\ninterface Context {\n  serverURL: string;\n}\n\n// @Component\n// @ExportModel({ios: 'SCMyComponentView'})\nclass MyComponent extends Component<any, Context> {\n  onCreate() {\n    // Will print http://api.server.com in the console\n    console.log(this.context.serverURL);\n  }\n}\n```\n\nNative code:\n```objectivec\n// Instantiate the context data structure\nSCMyComponentContext *context = [[SCMyComponentContext alloc]\n    initWithServerURL:@\"http://api.server.com\"];\n// Instantiate the view with the context passed as parameter\nSCMyComponentView *view = [[SCMyComponentView alloc]\n    initWithViewModel:viewModel\n     componentContext:context];\n```\n\nIf one of your child uses a different Context type, you can translate it to a type it understands through the `context` attribute:\n```tsx\nimport { ChildComponent, ChildContext } from './ChildComponent';\n\ninterface MyContext {\n  currentUser: User;\n}\n\nclass MyComponent extends Component<object, Context> {\n\n  onRender(): void {\n    <layout>\n      <ChildComponent context={this.getChildComponentContext()}/>\n    </layout>\n  }\n\n  getChildComponentContext(): ChildContext {\n    return {user: this.context.currentUser};\n  }\n}\n```\n\n## Context or ViewModel?\n\nUnlike ViewModel, the Context object cannot be changed once it's set. It should therefore not impact the rendering of your tree. Context is the best place to provide services, may they be implemented by native code or TypeScript. We recommend using the Context object for your root Component only, as a way to provide native services to TypeScript.\n\n## Factories\n\nValdi objects do not leverage dependency injection and objects (whether that be contexts, view models, etc.) are instantiated with regular constructors, not inject constructors, which requires more boilerplate to write.\nIn order to inject certain parameters, the Valdi compiler now generates two different native classes: the  class that it was emitting before and a factory with a create function that returns that first class. The factory will leverage our existing native dependency graphs.\n\nAll injected parameters will be passed into the factory’s constructor, requiring that they be provided by the native DI graph. All non injected parameters will be parameters in the create function.\n\n\nTypeScript:\n```ts\n// @Context\n// @ExportModel({android: 'com.snap.mymodule.MyDataSyncerContext'})\ninterface MyDataSyncerContext {\n   // @Injectable \n   configurationProvider: ConfigurationProvider,\n   key: string;\n}\n```\n\nNative:\n```kotlin\nclass MyDataSyncerContextFactory @Inject(\n    val configurationProvider: ConfigurationProvider\n) {\n   fun create(key: String): MyDataSyncerContext {\n       return MyDataSyncerContext(configurationProvider, key)\n   }\n}\n```\n\nTo use Factories, you will need to make changes in both the client repo and in native.\n\nIn the client repo:\n* Mark any parameters on the interface that you want to be provided from the dagger graph with an `@Injectable` annotation. If you want the parameter to only be injected in one client, you have the option of passing `androidOnly: true` or `iOSOnly: true` to the annotation to indicate that.\n\n<!-- TODO: is DI in scope for Open Source? -->\n\n[contributes-valdi-context]: #todo-link-to-source\n\nIn native:\n* Wherever you need access to the Valdi object, inject the factory. Instead of manually instantiating the object with all the dependencies, call the factory’s create method with the non-injectable parameters.\n* On Android, you will be responsible for telling Dagger how to provide the injected parameters. You can use the Anvil plugin [`@ContributesValdiContext`][contributes-valdi-context] to auto-generate some of the boilerplate.\n\n```kotlin\nclass MyAndroidClass @Inject(\n    private val myDataSynceContextFactory: MyDataSyncerContextFactory\n) {\n   fun doSomething() {\n    ...\n    val key = \"myKey\"\n    val context = myDataSyncerContextFactory.create(myKey)\n    ...\n   }\n}\n```"
  },
  {
    "path": "docs/docs/native-customviews.md",
    "content": "# The `<custom-view>`\n\n## Introduction\n\nValdi supports injecting regular `UIView` (iOS) and `View` (Android) inside of an existing valdi feature through the `<custom-view>` element in TSX.\n\nThis type of integration is useful when a very complex view (such as a system view) is already implemented in Android/iOS and we want to re-use both iOS and Android code instead of writing a new cross-platform component.\n\n## Using a `<custom-view>`\n\nHere we find a simple example on how to inject custom views inside of a Valdi rendered feature.\n\n### TypeScript\n\n```tsx\nexport interface MyContext {\n  myCustomViewFactory: ViewFactory; // This will tell valdi which native view to use\n}\nexport class MyComponent extends Component<{}, MyContext> {\n  onRender() {\n    <view backgroundColor='lightblue'>\n      <custom-view viewFactory={this.context.myCustomViewFactory} myAttribute={42}/>\n    </view>\n  }\n}\n```\n\n### Android\n\n```kotlin\n// Create a ViewFactory, that will instantiate a MyCustomView under the hood.\nval myCustomViewFactory = runtime.createViewFactory(MyCustomView::class.java, {\n  context -> MyCustomView(context, this.myViewDependencies)\n}, MyCustomViewAttributesBinder(context))\n\n// Pass the viewFactory to the context\nval context = MyContext()\ncontext.myCustomViewFactory = myCustomViewFactory\n\n// Create the view with the context\nval view = MyComponent.create(runtime, null, context)\n```\n\n### iOS\n\n```objectivec\n// Create a ViewFactory, that will instantiate a MyCustomView under the hood.\nid<SCValdiViewFactory> myCustomViewFactory =\n  [runtime makeViewFactoryWithBlock:^UIView *{\n    return [[MyCustomView alloc] initWithMyDependencies:self.myViewDependencies];\n  } attributesBinder:nil forClass:[MyCustomView class]];\n\n// Pass the viewFactory to the context\nMyContext *context = [MyContext new];\ncontext.myCustomViewFactory = myCustomViewFactory;\n\n// Create the view with the context\nMyComponent *view = [[MyComponent alloc] initWithRuntime:runtime\n                                                  viewModel:nil\n                                           componentContext:context];\n```\n\n## How to define `MyCustomView`\n\nIn the above snippet we injected the view MyCustomView, but we'd need to make sure that View is defined properly to be passed to Valdi.\n\nDeclaring a view class is usually not enough. Your custom view class will probably need to be configurable in order to be useful. Configuration of elements is done through attributes. For example a `Label` will expose attributes like `value` to set the text, `font` to change the font etc... If you were creating a `SliderView` element, you may want to expose an attribute like `progress` which could be used to change the slide position.\n\nThe process in which iOS/Android will declare the available attributes on a View class is called the _Attributes Binding_. At runtime, whenever Valdi has to inflate a view of a given class for the very first time, it will give an opportunity to iOS/Android code to register the attributes it knows how to handle. This process is lazy and happens only once per view class, regardless of which component is responsible for the inflation of that class.\n\nIn some cases, you might want to make a view automatically size itself based on its attributes. If we take the `Label` example again, we want the view representing the `Label` to have a size that changes based on its font, text etc...\n\nTo do this, you need to declare a measurer placeholder view instance or explicitly return a size via `setPlaceholderViewMeasureDelegate` or `setViewMeasureDelegate` respectively (see examples below) inside the `bindAttributes` function. Whenever a view of that class needs to be measured, the respective methods defined on the view will be used, preferring `setViewMeasureDelegate` if both are defined, the attributes will be applied to it, and `sizeThatFits:` will be called on iOS or `onMeasure()` on Android.\n\n> [!NOTE]\n> The view only needs to be measured if the dimensions of the view cannot be inferred from the view's layout attributes on the TypeScript side. For example the following view does not need to be measured as its width is defined relative to its parent (which would already be measured and known) and the height is set statically to 100.\n> ```tsx\n>   <view width={'100%'} height={100} />\n> ```\n>\n> In this case, the native measure methods defined above would _not_ be called.\n\n### Android\n\nTo register attributes on Android, you need to make a class implementing `com.snap.valdi.attributes.AttributesBinder`. You then register an instance of that class to the `ViewFactory` being created.\n\nMake sure your view also properly implements the `onMeasure()` method.\n\n```kotlin\nimport com.snap.valdi.attributes.RegisterAttributesBinder\nimport com.snap.valdi.attributes.AttributesBinder\n\n\nclass MyCustomView(context: Context) : FrameLayout(context) {}\n\n// Make sure to add the @RegisterAttributesBinder annotation so that\n// the Valdi runtime can find it.\n@RegisterAttributesBinder\nclass MyCustomViewAttributesBinder(context: Context): AttributesBinder<MyCustomView> {\n\n  override val viewClass: Class<MyCustomView>\n    get() = MyCustomView::class.java\n\n    private fun applyMyAttribute(\n      view: MyCustomView,\n      attributeValue: Double,\n      animator: ValdiAnimator?\n    ) {\n      view.myAttribute = attributeValue\n    }\n\n    private fun resetMyAttribute(\n      view: MyCustomView,\n      animator: ValdiAnimator?\n    ) {\n      view.myAttribute = 0\n    }\n\n    override fun bindAttributes(\n      attributesBindingContext: AttributesBindingContext<MyCustomView>\n    ) {\n      // Define an attribute\n      attributesBindingContext.bindDoubleAttribute(\n        \"myAttribute\",\n        false, // this attribute will not invalidate the layout of the view\n        this::applyMyAttribute, // called when a new attribute value is set on the view\n        this::resetMyAttribute // called when the attribute becomes undefined\n      )\n\n      // This is optional and will make the view measureable\n      attributesBindingContext.setPlaceholderViewMeasureDelegate(lazy {\n          ValdiDatePicker(context).apply {\n              layoutParams = ViewGroup.LayoutParams(\n                      ViewGroup.LayoutParams.WRAP_CONTENT,\n                      ViewGroup.LayoutParams.WRAP_CONTENT\n              )\n          }\n      })\n\n      // This is optional and will make the view measureable\n      attributesBindingContext.setMeasureDelegate(object : MeasureDelegate {\n          override fun onMeasure(\n              attributes: ViewLayoutAttributes,\n              widthMeasureSpec: Int,\n              heightMeasureSpec: Int,\n              isRightToLeft: Boolean\n          ): MeasuredSize {\n              return MeasuredSize(1000, 1000)\n          }\n      })\n    }\n}\n```\n\nThe semantics are the same as for iOS. We declared to Valdi that we know how to handle the attribute `myAttribute`, we are expecting it to be a double, and we provided callbacks to apply and reset the attribute on the view.\n\nThe second parameter of `bindDoubleAttribute` is used to tell Valdi whether the intrinsic size of your view might change if the attribute changes. This is useful for attributes like `font` on a `Label`, because changing the `font` means the `Label` could end up being bigger. Whenever an attribute changes with `invalidateLayoutOnChange` set to true, a layout calculation will always be triggered at some point.\n\n### iOS\n\nTo register attributes on iOS, you can override this class method `+(void)bindAttributes:(SCValdiAttributesBindingContext *)` in your custom view class. The given attributes binding context provides convenience methods to register the attributes and get a callback when the attribute needs to be applied or removed from a view instance.\n\nMake sure your view also properly implements the `sizeThatFits:` method.\n\n```objectivec\n@implementation MyCustomView {}\n\n- (void)valdi_applyMyAttribute:(double)attributeValue\n{\n  self.myAttribute = attributeValue;\n}\n\n+ (void)bindAttributes:(SCValdiAttributesBindingContext *)bindingContext\n{\n  // Define an attribute\n  [bindingContext bindAttribute:@\"myAttribute\"\n       invalidateLayoutOnChange:NO\n                withDoubleBlock:^(MyCustomView *myCustomView,\n                                  double attributeValue,\n                                  SCValdiAnimator *animator) {\n    // called when a new attribute value is set on the view\n    [myCustomView valdi_applyMyAttribute:attributeValue];\n  }\n                  resetBlock:^(MyCustomView *myCustomView,\n                               SCValdiAnimator *animator) {\n    // called when the attribute becomes undefined\n    [myCustomView valdi_applyMyAttribute:0];\n  }];\n\n  // This is optional and will make the view measureable\n  [attributesBinder setPlaceholderViewMeasureDelegate:^UIView *{\n      return [MyCustomView new];\n  }];\n\n  // This is optional and will make the view measureable (will be prioritized if setPlaceholderViewMeasureDelegate is also defined)\n  [attributesBinder setMeasureDelegate:^CGSize(id<SCValdiViewLayoutAttributes> attributes, CGSize maxSize,\n                                                           UITraitCollection *traitCollection) {\n      CGSize newSize = CGSizeMake(1000, 1000);\n      return newSize;\n  }];\n\n}\n\n@end\n```\n\nIn this example we declared to Valdi that we know how to handle the attribute `myAttribute`, we are expecting it to be a double, and we provided callbacks to apply and reset the attribute on the view.\n\nThe `animator` parameter is passed whenever the attribute change is expected to be animated. `SCValdiAnimator` provides methods to animate a change using `CoreAnimation`. If your attribute is not animatable, it is fine to ignore it.\n\nThe `invalidateLayoutOnChange` parameter is used to tell Valdi whether the intrinsic size of your view might change if the attribute changes. This is useful for attributes like `font` on a `Label`, because changing the `font` means the `Label` could end up being bigger. Whenever an attribute changes with `invalidateLayoutOnChange` set to true, a layout calculation will always be triggered at some point.\n\n#### How to bind `Observable` to iOS view:\n\n<!-- TODO: Link to widget source code -->\n\n[observable]: #replace-with-public-url\n\nLet's say your attribute is called `observable`.\n- At the TSX level, pass the `observable` attribute like `observable={convertObservableToBridgeObservable(yourObservable)}` ([see the method][observable])\n- At the iOS level, use the `bindAttribute withUntypedBlock:` for name `observable`:\n  ```objectivec\n  SCObservable<NSString *>observable;\n  SCValdiMarshallerScoped(marshaller, {\n    NSInteger objectIndex = SCValdiMarshallerPushUntyped  (marshaller, untypedInstance);\n    SCValdiBridgeObservable *bridgeObservable =   [SCValdiMarshallableObjectRegistryGetSharedInstance()   unmarshallObjectOfClass:[SCValdiBridgeObservable class]   fromMarshaller:marshaller atIndex:objectIndex];\n    observable = [bridgeObservable toSCObservable];\n  });\n  ```\n\n## Native View or Component?\n\nIn some cases, you might be able to implement a view class as a Valdi component itself. For example a `SliderView`.\n\nIt is very likely than writing the slider as a component would have been easier and allowed the same level of functionality. Here are some reasons which you might want to use a native view class instead:\n\n- The functionality you want to provide is difficult to do in Valdi.\n\n  For example if you wanted to actually draw an image buffer on the screen or draw the glyphs from a text, it will have to use the platform specific APIs on iOS/Android. As such an `Image` or `Label` native view class will do the job better than a Valdi component.\n- There already exist a view class which provides the level of functionality you need.\n- The view class has performance heavy logic that would be slow to evaluate in a JavaScript engine.\n\n## Using a class mapping\n\n> [!NOTE]\n> In most cases it is easier and safer to use a `ViewFactory` instead\n\nAlternatively in TSX, you can use an arbitrary view class in your render template by using the `<custom-view>` element and pass it the iOS and Android class names.\n\nIn order for the view class to be instantiable by Valdi, it needs to have a working `initWithFrame:` initializer in iOS, and `init(context: Context)` in Android. If the view class does not have those constructors, you can create your own view class that wraps the native view class you want to use. If the view class ultimately needs additional native dependencies to be constructed, the Valdi way to provide them is to use attributes.\n\nIf a view class is designed to be re-usable across multiple features, consider abstracting out the native view class inside a component.\n\n### TypeScript\n\n```tsx\nexport interface SliderViewModel {\n  progress: number;\n}\nexport class Slider extends Component<SliderViewModel> {\n  onRender() {\n    <custom-view\n      iosClass='SliderView'\n      androidClass='com.snap.valdi.SliderView'\n      progress={this.viewModel.progress}\n    />\n  }\n}\n```\n\n### Android\n\n```java (works better than kotlin syntax highlighting)\n// We can then create the view\nval view = MyFeature.create(runtime, null, null)\n```\n\n> [!Warning]\n> The Valdi runtime will use the JVM's reflection APIs to resolve the view class name. The given Android class name needs to be stable and not change on release builds for this mechanism to work. On Android Snapchat's release builds, the R8 optimizer is used to mangle and rename classes, which can break custom views referred by their class names in Valdi. You can use the `@Keep` annotation in Kotlin or a configured `proguard-rules.pro` file to enforce that the view class is not renamed and removed from the apk.\n\n### iOS\n\n```objectivec\n// When we create the slider-view, we'd need to define the attribute binding\n@implementation SliderView {}\n+ (void)bindAttributes:(SCValdiAttributesBindingContext *)bindingContext\n{\n  // Define my slider's attributes\n}\n@end\n\n// We can then create the view\nMyFeature *view = [[MyFeature alloc] initWithRuntime:runtime\n                                              viewModel:nil\n                                       componentContext:nil];\n```\n"
  },
  {
    "path": "docs/docs/native-polyglot.md",
    "content": "# Polyglot Modules\n\n## Introduction\n\nPolyglot modules are a special kind of Valdi modules that expose a TypeScript API backed by a foreign language implementation, like Objective-C, Swift, C++, Java or Kotlin. When a regular Valdi module depends on a polyglot module, it will also depend on its implementation in the separate language. Some example of usecases for polyglot modules include:\n\n- Exposing a third party library written in another language like C into TypeScript.\n- Providing a more optimized implementation of a function or module in another language.\n- Implementing some functionality that requires access to dependencies that are not currently visible by TypeScript.\n\n## Implementing a polyglot module\n\nA polyglot module has two key components:\n\n- It has some part of the TypeScript type definition implemented in a separate language.\n- Its `valdi_module()` Bazel target in the `BUILD.bazel` depends on user defined Android, iOS or native dependencies.\n\nA regular Valdi module can be turned into a polyglot module at any time. We will look at an example where we implement a `join(components: string[], delimiter: string)` function in Objective-C, Kotlin and then C++, that gets exposed to TypeScript. The rest of this document expects that we have a Valdi module where we can add files and modify its `BUILD.bazel` file.\n\n### TypeScript definition\n\nWe start by declaring the TypeScript API of the module for which we want an implementation in a foreign language:\n\n```ts\n/* @ExportModule */\n\nexport const DEFAULT_DELIMITER: string;\n\nexport function join(components: string[], delimiter: string): string;\n```\n\nThe `@ExportModule` annotation tells the Valdi compiler to generate Objective-C, Swift, and Kotlin bindings that will help with implementing the module. Note that the file needs to be a TypeScript definition (`.d.ts` file), at `my_module/src/Joiner.d.ts` for instance.\n\n### Bazel file\n\nThe `valdi_module` Bazel rule that is used for defining Valdi modules exports three properties that can be used to help writing a polyglot modules:\n\n- `android_deps`: Defines a list of `android_library` dependencies, implemented in a JVM language, that will be built and included on an Android build. This can be used to add a JVM based implementation when targeting Android.\n- `ios_deps`: Defines a list of `apple_library` or `cc_library` dependencies, implemented in a native language like Objective-C, Swift, and will be built and included on an iOS build. This can be used to add a native implementation when targeting iOS.\n- `native_deps`: Defines a list of `cc_library` dependencies, implemented in a native cross-platform language like C++, and will be built and included on all platforms like iOS, Android or Desktop. This can be used to add a native and cross-platform implementation.\n\nIn a typical implementation, either `native_deps` is used, or `android_deps` and `ios_deps` are used. If the implementation is native cross-platform, like when writing bindings for a native library like `zstd`, `native_deps` would be used. If the implementation is platform dependent, like when writing bindings for a Camera API, `android_deps` and `ios_deps` would be used.\n\n### iOS implementation\n\nWe start by adding a `objc_library` target in the `BUILD.bazel` file of the module, which will contain the iOS specific implementation of the polyglot module:\n\n```python\nobjc_library(\n    name = \"my_module_ios_impl\",\n    srcs = glob([\n        \"ios/**/*.m\",\n    ]),\n    hdrs = [],\n    copts = [\"-I.\"],\n    deps = [\n        # Depend on the generated Objective-C API of the module\n        \":my_module_api_objc\",\n        # Depend on the Valdi runtime\n        \"//valdi\",\n    ],\n)\n\n```\n\nThe implementation target will need to be referenced as `ios_deps` on the `valdi_module` target of the `BUILD.bazel` representing the module:\n\n```python\nvaldi_module(\n    name = \"my_module\",\n    ios_deps = [\":my_module_ios_impl\"],\n    ios_module_name = \"SCCMyModule\",\n    ios_output_target = \"release\",\n    # Etc...\n)\n```\n\nWe then write an Objective-C implementation file:\n\n```objc\n#import \"valdi_core/SCValdiModuleFactoryRegistry.h\"\n#import <SCCMyModuleTypes/SCCMyModuleTypes.h>\n#import <Foundation/Foundation.h>\n\n@interface SCCMyModuleJoinerModuleImpl: NSObject<SCCMyModuleJoinerModule>\n\n@end\n\n@implementation SCCMyModuleJoinerModuleImpl\n\n- (NSString *)DEFAULT_DELIMITER\n{\n    return @\" \";\n}\n\n- (void)setDEFAULT_DELIMITER:(NSString *)defaultDelimiter\n{\n\n}\n\n- (NSString *)joinWithComponents:(NSArray<NSString *> *)components delimiter:(NSString *)delimiter\n{\n  return [components componentsJoinedByString:delimiter];\n}\n\n@end\n\n@interface SCCMyModuleJoinerModuleFactoryImpl : SCCMyModuleJoinerModuleFactory\n\n@end\n\n@implementation SCCMyModuleJoinerModuleFactoryImpl\n\n// Registers the module into the Valdi runtime\nVALDI_REGISTER_MODULE()\n\n- (id<SCCMyModuleJoinerModule>)onLoadModule\n{\n    // Return the module implementation. Will be called lazily when the module\n    // is imported for the first time.\n    return [SCCMyModuleJoinerModuleImpl new];\n}\n\n@end\n```\n\nThat's it! When TypeScript imports the `.d.ts` file, on iOS the `onLoadModule` of `SCCMyModuleJoinerModuleFactoryImpl` will be called, which will return the module instance that backs the implementation of the module.\n\n### Android implementation\n\nWe start by adding a `valdi_android_library` target in the `BUILD.bazel` file of the module, which will contain the Android specific implementation of the polyglot module:\n\n```python\nload(\"//bzl/valdi:valdi_android_library.bzl\", \"valdi_android_library\")\n\nvaldi_android_library(\n    name = \"my_module_android_impl\",\n    srcs = glob([\n        \"android/**/*.kt\",\n    ]),\n    deps = [\n        # Depend on the generated Kotlin API of the module\n        \":my_module_api_kt\",\n        # Depend on the Valdi runtime\n        \"//valdi:valdi_java\",\n    ],\n)\n\n```\n\nThe implementation target will need to be referenced as `android_deps` on the `valdi_module` target of the `BUILD.bazel` representing the module:\n\n```python\nvaldi_module(\n    name = \"my_module\",\n    android_class_path = \"com.snap.valdi.modules.my_module\",\n    android_deps = [\":my_module_android_impl\"],\n    android_output_target = \"release\",\n    # Etc...\n)\n```\n\nWe then write a Kotlin implementation file:\n\n```kotlin\npackage com.snap.valdi.modules.my_module\n\nimport com.snapchat.client.valdi_core.ModuleFactory\nimport com.snap.valdi.modules.RegisterValdiModule\nimport com.snap.valdi.modules.my_module.MyJoinerModule\nimport com.snap.valdi.modules.my_module.MyJoinerModuleFactory\nimport com.snap.valdi.modules.hello_world.NativeModuleModule\n\n// Registers the module into the Valdi runtime\n@RegisterValdiModule\nclass MyJoinerModuleFactoryImpl: MyJoinerModuleFactory() {\n\n    override fun onLoadModule(): NativeModuleModule {\n          // Return the module implementation. Will be called lazily when the module\n          // is imported for the first time. We use an anonymous class here, but a\n          // proper subclass can also be used of course.\n          return object: MyJoinerModule {\n            override val DEFAULT_DELIMITER = \" \"\n            override fun join(components: List<String>, delimiter: String) -> String {\n              return components.joinToString(delimiter)\n            }\n        }\n    }\n}\n```\n\nThat's it! When TypeScript imports the `.d.ts` file, on Android the `onLoadModule` of `MyJoinerModuleFactoryImpl` will be called, which will return the module instance that backs the implementation of the module. Please note that for the `@RegisterValdiModule` annotation to work, the Kotlin file needs to be compiled through a `valdi_android_library` rule and that rule processes the annotations at build time to add some required information at runtime that is used to register the module.\n\n### C++ implementation\n\nWe start by adding a `cc_library` target in the `BUILD.bazel` file of the module, which will contain the native implementation of the polyglot module:\n\n```python\ncc_library(\n    name = \"my_module_native_impl\",\n    srcs = glob([\n        \"native/**/*.cpp\",\n    ]),\n    # Required for automatic registration of the module into the Valdi runtime\n    alwayslink = 1,\n    deps = [\n        # Depend on the generated C++ API of the module\n        \":my_module_cpp\",\n    ],\n)\n\n```\n\nThe implementation target will need to be referenced as `native_deps` on the `valdi_module` target of the `BUILD.bazel` representing the module:\n\n```python\nvaldi_module(\n    name = \"my_module\",\n    native_deps = [\":my_module_native_impl\"],\n    # Etc...\n)\n```\n\nWe then write a C++ implementation file. The Valdi compiler does not yet support C++ codegen, so unfortunately the bindings currently have to be hand written in C++:\n\n```c++\n#include \"valdi_modules/my_module/my_module.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::valdi_modules::my_module {\n\nclass JoinerModuleFactoryImpl: public JoinerModuleFactory {\npublic:\n    JoinerModuleFactoryImpl() = default;\n    ~JoinerModuleFactoryImpl() override = default;\n\n    Ref<JoinerModule> onLoadModule() final {\n        class JoinerModuleImpl: public JoinerModule {\n        public:\n            JoinerModuleImpl() = default;\n            ~JoinerModuleImpl() override = default;\n\n            StringBox DEFAULT_DELIMITER() final {\n                return StringBox::fromCString(\" \");\n            }\n\n            StringBox join(const std::vector<StringBox> &components, const StringBox &delimiter) final {\n                return StringBox::join(components, delimiter);\n            }\n        };\n\n        return makeShared<JoinerModuleImpl>();\n    }\n};\n\n// Register our module to the Valdi runtime\nauto kRegisterModule = RegisterModuleFactory::registerTyped<MyJoinerModule>();\n\n}\n```\n\nThat's it! When TypeScript imports the `.d.ts` file, on all platforms the `loadModule()` of `MyJoinerModule` will be called, which will return the module instance that backs the implementation of the module.\n"
  },
  {
    "path": "docs/docs/native-types.md",
    "content": "# Type Conversions\n\n# Native Type Conversions\n\nValdi supports extensible type conversions between TypeScript and Android/iOS environments, including built-in support for several key types. Custom type converters are registered at runtime in Android/iOS and can handle any non-primitive TypeScript types.\n\n## Available Types\n\nThe following type conversions are available in Valdi:\n\n## The `Valdi::Value` Container\n\nUnder the hood, all data passed between TypeScript and native environments is encapsulated in a unified C++ container called `Valdi::Value`.\n\n### Characteristics of `Valdi::Value`\n- **128-bit Variant**: It uses 64 bits for data (or a pointer) and 64 bits for type information.\n- **Zero-Copy Marshalling**: Designed to minimize heap allocations when passing data across the bridge.\n- **Reference Counted**: Complex types like maps and arrays are ref-counted to ensure memory safety across threads.\n- **Immutable**: Once created, a `Valdi::Value` is immutable and thread-safe.\n\nThis unified representation allows Valdi to handle complex data structures efficiently without repeated conversions as they move between JavaScript, Objective-C, and Java.\n\n| TypeScript  | Android (Kotlin) | iOS (Objective-C)  |\n| ------------- | ------------- | ------------- |\n| `boolean` | `Boolean` | `BOOL`, or `NSNumber*` if optional |\n| `number` |  `Double`  |  `double`, or `NSNumber*` if optional |\n| `string` | `String`   | `NSString*` |\n| `Uint8Array` | `ByteArray` | `NSData*` |\n| `Long` |  `Long`  |  `int64_t`, or `NSNumber*` if optional |\n| `T[]` or `Array<T>` | `Array<T>` | `NSArray<T *>*` |\n| arrow function or regular function |  lambda  | block |\n| [Annotated type](native-annotations.md) | Generated type | Generated type |\n| `Promise<T>`  | [`Promise<T>`][Promise-android] or [`CancelableResolvablePromise<T>`][Cancelable-Promise-android]  | [`SCValdiPromise`][Promise-ios] or [`SCValdiResolvablePromise`][Cancelable-Promise-ios]\n| `Observable<T>`  | [`BridgeObservable<T>`][Observable-ts]  | [`SCBridgeObservable`][Observable-ts]\n| `Subject<T>` | [`BridgeSubject`][BridgeSubject] | [`SCBridgeSubject`][BridgeSubject]\n| [`Asset`][Asset] | `com.snapchat.client.valdi_core.Asset` | `SCNValdiCoreAsset` use in combination with `SCValdiAssetFromImage` to pass `UIImage` to Valdi |\n\n[Promise-android]: ../../valdi/src/java/com/snap/valdi/promise/Promise.kt\n[Cancelable-Promise-android]: ../../valdi/src/java/com/snap/valdi/promise/CancelableResolvablePromise.kt\n[Promise-ios]: ../../valdi_core/src/valdi_core/ios/valdi_core/SCValdiPromise.m\n[Cancelable-Promise-ios]: ../../valdi_core/src/valdi_core/ios/valdi_core/SCValdiResolvablePromise.mm\n[Observable-ts]: ../../src/valdi_modules/src/valdi/bridge_observables/src/types/BridgeObservable.ts\n[BridgeSubject]: ../../src/valdi_modules/src/valdi/bridge_observables/src/types/BridgeSubject.d.ts\n[Asset]: ../../src/valdi_modules/src/valdi_modules/src/valdi/valdi_tsx/src/Asset.d.ts\n\n\n\n\n## Custom Type Converters\nCustom type converters can be registered at the platform-level and made available to all Valdi features. Type converters are registered at runtime to provide a mapping between a platform-specific type and its TypeScript counterpart using a factory method that creates a `TypeConverter`.\n\nFor example, the following method converts to and from RxJS Observables:\n\n```typescript\nimport { TypeConverter } from 'valdi_core/src/TypeConverter';\nimport { Observable } from 'rxjs/src/Observable';\nimport { BridgeObservable } from '../types/BridgeObservable';\nimport { convertBridgeObservableToObservable } from './convertBridgeObservableToObservable';\nimport { convertObservableToBridgeObservable } from './convertObservableToBridgeObservable';\n\n// @NativeTypeConverter\nexport function makeTypeConverter<T>(): TypeConverter<Observable<T>, BridgeObservable<T>> {\n  return {\n    toIntermediate: convertObservableToBridgeObservable,\n    toTypeScript: convertBridgeObservableToObservable,\n  };\n}\n```\n\n<!-- TODO: publicly available instructions on how to register converters -->\n"
  },
  {
    "path": "docs/docs/native-view-model.md",
    "content": "# View Model\n\n## Passing view model from native code\n\nView models can be passed from native code. To do so, you first need to generate a strong typed interface for the view model.\nTo leverage the compiler's ability to generate Objective-C, Swift, and Kotlin view model classes, add `@ExportModel` and `@ViewModel` annotations, as follow:\n\n```ts\n// @ExportModel({ios: 'SCMyViewModel', android: 'com.snap.valdi.MyViewModel'})\n// @ViewModel\ninterface ViewModel {\n  title?: string;\n  subtitle?: string;\n}\n```\n\nIn iOS you will get a generated view model like:\n```objectivec\n@interface SCMyViewModel: NSObject\n\n@property (readonly, copy, nonatomic) NSString *title;\n@property (readonly, copy, nonatomic) NSString *subtitle;\n\n- (instancetype)initWithTitle:(NSString *)title subtitle:(NSString *)subtitle;\n\n@end\n```\n\nOn Android, you would get this:\n```java (works better than kotlin syntax highlighting)\npackage com.snap.valdi\n\nclass MyViewModel(val title: String, val subtitle: String): ValdiViewModel\n```\n"
  },
  {
    "path": "docs/docs/navigation.md",
    "content": "# Navigation\n\n## Introduction\n\nThe `valdi_navigation` module makes it possible to show and dismiss pages in an application. It supports presentation using horizontal and vertical animations. It follows the iOS model. The module is a work in progress.\n\n## Usage\n\nTo use the navigation module, an application or a page should render a `NavigationRoot` component, which will expose a `NavigationController` allowing consumer to perform various navigation operations. The `NavigationRoot` passes the `NavigationController` instance as part of its slot:\n\n```tsx\nonRender(): void {\n<NavigationRoot>\n    {$slot(navigationController => {\n        // Render the root page with the navigationController\n    })}\n</NavigationRoot>;\n}\n```\n\nThe navigation controller exposes the following key methods:\n\n- `push()`: takes as parameter the component constructor, the view model and component context, and renders the component as a page with a horizontal animation\n- `pop()`: Inverse operation of `push()`, will remove the last page from the stack with a horizontal animation\n- `present()`: Takes as parameter the component constructor, the view model and component context, and renders the component as a page with a vertical animation\n- `dismiss()`: Inverse operation of `present()`, will remove all the pages up to and include the last page that was presented.\n\nEach sub pages in an application should inherit the `NavigationPageComponent` or `NavigationPageStatefulComponent` to get access to a `NavigationController` so that they can perform navigation operations on their own. Only pages rendered inside a `NavigationRoot` should inherit `NavigationPageComponent` or `NavigationPageStatefulComponent`. For example:\n\n```tsx\n@NavigationPage(module)\nexport class Page1 extends NavigationPageComponent<{}> {\n  onRender(): void {\n    <label font={systemBoldFont(17)} value=\"This is Page1\" />;\n  }\n}\n```\n\nThe `Page1` component can be opened as a page shown vertically or horizontally from any component that has access to a `navigationController`, which includes the component rendering the `NavigationRoot` as well as all `NavigationPageComponent` and `NavigationPageStatefulComponent` subclasses:\n\n```tsx\n// Push Page1 with a horizontal animation\nnavigationController.push({\n    Page1,\n    {}, // Specify the view model to pass to Page1\n    {}, // Specify the component context to pass  to Page1\n})\n\n// Push Page1 with a vertical animation\nnavigationController.present({\n    Page1,\n    {}, // Specify the view model to pass to Page1\n    {}, // Specify the component context to pass  to Page1\n})\n```\n\n## Complete example\n\n```tsx\nexport class App extends Component {\n  private navigationController?: NavigationController;\n\n  onRender(): void {\n    <NavigationRoot>\n      {$slot(navigationController => {\n        this.navigationController = navigationController;\n        <view backgroundColor=\"white\" width=\"100%\" height=\"100%\" alignItems=\"center\" justifyContent=\"center\">\n          {this.renderButtons()}\n        </view>;\n      })}\n    </NavigationRoot>;\n  }\n\n  private renderButtons() {\n    <CoreButton text=\"Page 1\" onTap={this.handleOpenPage1} />;\n    <CoreButton text=\"Page 2\" onTap={this.handleOpenPage2} />;\n  }\n\n  private handleOpenPage1 = () => {\n    this.navigationController?.push(Page1, {}, {});\n  };\n\n  private handleOpenPage2 = () => {\n    this.navigationController?.push(Page2, {}, {});\n  };\n}\n\n@NavigationPage(module)\nexport class Page1 extends NavigationPageComponent<{}> {\n  onRender() {\n    <CoreButton text=\"Back\" onTap={this.handleBack} />;\n  }\n\n  private handleBack = () => {\n    this.navigationController.pop();\n  };\n}\n\n@NavigationPage(module)\nexport class Page2 extends NavigationPageComponent<{}> {\n  onRender() {\n    <CoreButton text=\"Back\" onTap={this.handleBack} />;\n  }\n\n  private handleBack = () => {\n    this.navigationController.pop();\n  };\n}\n```\n"
  },
  {
    "path": "docs/docs/on-render.md",
    "content": "# How `onRender()` Works\n\nEvery Valdi component implements `onRender(): void`. The return type is `void` — not `JSX.Element`, not `null`, not anything. This is one of the most fundamental differences between Valdi and React, and it shapes how you write every component.\n\n## JSX as side-effects, not return values\n\nIn React, JSX is an expression that produces a value. `render()` returns a tree of `React.Element` objects and React's reconciler compares new trees to old ones to compute a minimal diff.\n\nIn Valdi, JSX tags are **imperative calls to the native renderer**. When the Valdi runtime calls your `onRender()`, it opens a render transaction. Each JSX tag — `<view>`, `<label>`, `<MyComponent />` — immediately emits a native instruction into that transaction. When `onRender()` returns, the transaction is committed.\n\nThere is no virtual DOM. There is no tree to diff. There is no return value because the output has already been emitted.\n\n```tsx\n// React — JSX produces a value that is returned\nrender(): JSX.Element {\n  return (\n    <view>\n      <label value=\"hello\" />\n    </view>\n  );\n}\n\n// Valdi — JSX emits native calls; nothing is returned\nonRender(): void {\n  <view>\n    <label value=\"hello\" />\n  </view>;\n}\n```\n\n## Common mistakes\n\n### ❌ Using `return`\n\n```tsx\n// WRONG — nothing is returned, this is silently discarded\nonRender(): void {\n  return <view><label value=\"hello\" /></view>;\n}\n```\n\nTypeScript will catch this if your return type annotation is `void`, but the real problem is that `return` exits `onRender()` before the JSX is evaluated. The native renderer never receives the instruction.\n\n```tsx\n// CORRECT\nonRender(): void {\n  <view><label value=\"hello\" /></view>;\n}\n```\n\n### ❌ Storing JSX in a variable\n\n```tsx\n// WRONG — the <label> is emitted into the tree when the variable is assigned,\n// not when it's \"used\" — it ends up in the wrong place\nonRender(): void {\n  const title = <label value={this.viewModel.title} />;\n  <view>\n    {title}  // this does NOT insert the label here\n  </view>;\n}\n```\n\nBecause JSX emits at the point it is evaluated, storing a JSX expression in a variable and using it later does not work the way it does in React. The `<label>` is emitted at the assignment site, not at the usage site.\n\n```tsx\n// CORRECT — call a method that emits at the right time\nonRender(): void {\n  <view>\n    {this.renderTitle()}\n  </view>;\n}\n\nprivate renderTitle(): void {\n  <label value={this.viewModel.title} />;\n}\n```\n\n### ❌ Passing JSX as a prop\n\n```tsx\n// WRONG — the <label> is emitted into the wrong location in the tree\n<MyComponent header={<label value=\"Title\" />} />\n```\n\nJSX cannot be passed as a value. Instead, pass a function (sometimes called a \"render prop\") that the child calls at the correct time:\n\n```tsx\n// CORRECT — write children as inline JSX; the compiler wraps them in a render function\ninterface MyComponentViewModel {\n  children?: () => void;\n}\n\n// Parent\nclass ParentComponent extends Component<ParentViewModel> {\n  onRender(): void {\n    <MyComponent>\n      <label value=\"Title\" />;\n    </MyComponent>;\n  }\n}\n\n// Child — call this.viewModel.children() to render the slot\nclass MyComponent extends Component<MyComponentViewModel> {\n  onRender(): void {\n    <view>\n      {this.viewModel.children?.()}\n    </view>;\n  }\n}\n```\n\nWhen the child component needs to pass a value back into the render function (for example, a measured size), use `$slot()` to pass a parametric callback:\n\n```tsx\nimport { $slot } from 'valdi_core/src/CompilerIntrinsics';\n\ninterface MeasuredViewModel {\n  children?: (frame: { width: number; height: number }) => void;\n}\n\nclass ParentComponent extends Component<ParentViewModel> {\n  onRender(): void {\n    <MeasuredView>\n      {$slot(({ width, height }) => {\n        <view height={Math.min(width, height)} width={Math.min(width, height)} />;\n      })}\n    </MeasuredView>;\n  }\n}\n```\n\n### ❌ Using `Array.map()` to render lists\n\n```tsx\n// WRONG — map() returns an array; the return value is discarded\nonRender(): void {\n  <scroll>\n    {this.viewModel.items.map(item => <Row data={item} />)}\n  </scroll>;\n}\n```\n\n`map()` collects return values into an array. But JSX in Valdi doesn't return — it emits. The `<Row>` elements are emitted immediately, then `map()` returns an array of `void`s which is silently discarded, leaving the `<scroll>` empty.\n\n```tsx\n// CORRECT — forEach emits at the right time\nonRender(): void {\n  <scroll>\n    {this.viewModel.items.forEach(item => {\n      <Row data={item} />;\n    })}\n  </scroll>;\n}\n```\n\n## Why there is no `export default`\n\nA common source of confusion when starting with Valdi: components are not exported as default exports.\n\nIn React, a component file typically ends with `export default MyComponent`. In Valdi, components are referenced by class identity — the host app loads modules by their compiled `.valdimodule` archive, and the Valdi runtime instantiates the root component class directly. There is no module registry that needs a default export.\n\n```tsx\n// React\nexport default class MyComponent extends React.Component<Props> { ... }\n\n// Valdi — no default export needed; class identity is the reference\nexport class MyComponent extends Component<ViewModel> { ... }\n```\n\nIf you're using `EntryPointComponent` to register a component as a module entry point, class identity is sufficient — no default export required.\n\n## Performance implications\n\nBecause there is no virtual DOM, Valdi's render path is direct:\n\n- `onRender()` is called\n- Native view instructions are serialized into a `RenderRequest` buffer as side-effects\n- At the end of the render pass, the `RenderRequest` is submitted to the C++ runtime in one batch\n\nValdi uses a **fine-grained reactivity model**: only the components whose `ViewModel` or `State` changed are re-rendered. A component re-render does not trigger its subtree unless child components also receive updated `ViewModel`s.\n\nThis means:\n- Creating inline lambdas or new objects inside `onRender()` can cause unnecessary child re-renders (changed prop identity even if the value is semantically the same)\n- `new Style({...})` inside `onRender()` defeats style interning — define styles at module level\n- Methods like `renderTitle()` are fine since they emit, not return\n\n> **See also:** [Performance Optimization](./performance-optimization.md), [Component States](./core-states.md), [The Mighty Component](./core-component.md)\n"
  },
  {
    "path": "docs/docs/performance-memory-leaks.md",
    "content": "# Debugging Memory Leaks\n\nValdi supports exporting the heap of the VM in the V8 format, which is supported by the Chrome DevTools and Meta's [Memlab](https://facebook.github.io/memlab/). The heap dump gives a complete report of all of the objects and functions that are currently live within the VM, and the relationships between them.\n\n## Prerequisite\n\nThe heap dump is currently only supported with the Hermes engine. See information about [enabling Hermes](../workflow-hermes-debugger.md).\n\n## Requesting a heap dump\n\nThe heap dump can be requested by connecting the VSCode debugger to a Valdi application, and requesting a Heap Snapshot. See [VSCode documentation](https://code.visualstudio.com/docs/nodejs/profiling) for more informations about how to collect a heap snapshot.\n\n## Analyzing heap dumps\n\nThe `heapsnapshot` file can be opened in the Google Chrome dev tools: navigate to `View` (menu bar at the top) -> `Developer` -> `Developer Tools`.\nNext up, you can load the `heapsnapshot` file in `Memory` -> `Load`:\n\n![Screenshot of using the Memory tool in Chrome's developer tools](./assets/debugging-leaks/load-heapsnapshot.png)\n\nThe `Memory` view shows all of the objects that were part of the dump, with their constructor names. On the right side, `shallow size` tells how much memory each object directly consumes, while `retained size` shows how much memory is indirectly consumed by this object through references to other objects.\nWhen expanding an object, the tool shows all of the references that the object is holding. When the reference is gray, like `<shape>` in the example below, the reference is an implicit hidden reference that the VM holds. Other types of references are propertiess or array elements. Only reference types are currently exported in the dump, numbers or booleans will not show up.\n\n![Screenshot of navigating the Memory developer tool](./assets/debugging-leaks/object-fields.png)\n\nAt the bottom of the window, the tool shows a `Retainers` section, which contains all of the objects that reference the object selected object. This helps understanding at why the object is currently alive.\n\n!['Screeshot showing more of items expanded in the Memory developer tool sidebar'](./assets/debugging-leaks/object-retainers.png)\n\nSome objects might be retained due to existing references between them and native (C++, Objective-C or Kotlin) code. These references are marked inside an array called `System / ExportedReferences`. When a TypeScript object or function gets exported to native code, the Valdi runtime creates a reference to it with an associated native object. When the associated native object gets deallocated or garbage collected, the exported reference gets torn down.\n"
  },
  {
    "path": "docs/docs/performance-optimization.md",
    "content": "# Optimization\n\nValdi was designed for high performance from the ground up. There are a few key points that makes it fast:\n- It avoids allocations on render when possible.\n- It avoids marshalling between JS and native code as much as possible.\n- Component's rendering are local, a component can re-render without triggering a render from its parent. Additionally, in cascading renders between parent to a nested child, the renderer can skip ancestors in between them in many cases. This allows for quick incremental updates.\n- Child Components are only re-rendered whenever their view model changed.\n- Native views are re-used across all components.\n- Logic which runs in the iOS/Android main thread is all C++ code.\n\nThis document covers some additional features that can be used to keep the view inflation fast.\n\n## Layout nodes\n\nSometimes, you may use a `view` to center or align elements. In that case, you can use a `layout` node instead. It works like a `view`, but won't be backed by a native view. As such it cannot display anything on screen and cannot receive touches, it is just used for laying out its children. `layout` nodes are cheaper than `view` to create, destroy and render.\n\n> **See also:** [`<layout>` and `<view>`](./core-views.md) for complete documentation on layout and view elements.\n\n```tsx\n<view>\n   <layout>\n      <label />\n      <label />\n   </layout>\n</view>\n```\n\n## Optimizing rendering\n\nValdi will render your Component in the following cases:\n- Your Component's state changed\n- Your Component's view model instance changed\n- You explicitly called `render()` or `animate()`\n\nRenders in Valdi are a lot cheaper than React, but they still have a cost that can add up if many components need to be rendered. As such, you should try to make sure the framework only render when something actually changed. Here are a few common pitfalls and how to fix them.\n\n### View model always changing\n\n```tsx\nclass Parent extends Component {\n  onRender() {\n    <Child items={['Item1', 'Item2']}/>\n  }\n}\n```\nThis code creates a new view model for `Child`, every time `Parent` renders. This is because the `items` view model property in this example is an array that gets created on every render. This means that the child will always re-render whenever the parent renders. You can solve this by creating the array once and passing it to the child component:\n\n```tsx\nclass Parent extends Component {\n  items = ['Item1', 'Item2'];\n\n  onRender() {\n    <Child items={this.items}/>\n  }\n}\n```\n\nIf the view model property you need to pass to your child component depends on a property passed from a parent, you can leverage the `onViewModelUpdate()` callback to compute and store the fields to pass down to your child components once:\n\n> **See also:** [Component Lifecycle](./core-component.md#lifecycle) for details on `onViewModelUpdate()` and other lifecycle methods.\n\n```tsx\ninterface ViewModel {\n  numberOfItems: number;\n}\n\nclass Parent extends Component<ViewModel> {\n  items = [];\n\n  onViewModelUpdate() {\n    if (this.items.length !== this.viewModel.numberOfItems) {\n      this.items = [];\n      for (let i = 0; i < this.viewModel.numberOfItems; i++) {\n        this.items.push(`Item${i + 1}`);\n      }\n    }\n  }\n\n  onRender() {\n    <Child items={this.items}/>\n  }\n}\n```\n\nThis solution will ensure that `Child` will re-render only when necessary, making incremental updates faster.\n\n### Using callbacks in elements\n\n> **See also:** [Component Events](./core-events.md) for more on handling touch events and callbacks.\n\n**❌ BAD - Don't do this:**\n\n```tsx\nclass MyComponent extends Component {\n  onRender() {\n    <view onTap={() => {\n      // Handle click\n    }}/>\n  }\n}\n```\nThis code sets the `onTap` attribute to an inline lambda. The issue with that code is that whenever the Component renders, a callback function will be created for the `onTap` every time. Functions in TypeScript cannot be compared by value, they are just compared by reference. As such, the framework cannot know if the function has actually changed or not, unless the reference stays the same. This means that for every render, the diff algorithm will detect a change for the `onTap` attribute which triggers an update of the tap handler to the backing view element. The solution is to store the callback as a lambda on the component itself, and pass down the created lambda:\n\n**✅ GOOD - Do this instead:**\n\n```tsx\nclass MyComponent extends Component {\n  onRender() {\n    <view onTap={this.onTap}/>\n  }\n\n  private onTap = () => {\n    // Handle click\n  }\n}\n```\n\n\n### Component Keys\n\nTo correctly identify which elements have been been removed/added/moved between renders the framework has a concept of _keys_. In cases where there are multiple siblings of the same node type the `key` attribute is used to determine the identity of an element. If you don't provide a key manually, the framework assigns one automatically. This works fine for shorter lists of views that, but it's a good idea to provide the `key` yourself, especially since it's trivial as the data backing the elements in your list usually has some sort of unique identifier. For cases such as rearranging arrays or drag and drop, the items can remain consistently rendered instead of destroyed and recreated.\n\n```tsx\nclass MyComponent extends Component {\n  onRender() {\n    <view>\n      <view key=\"1\" />\n      <view key=\"2\" />\n    </view>\n  }\n}\n```\n\n## Advanced Optimizations\n\n### Bypassed Rendering\nValdi avoids unnecessary work by skipping the `onRender` call of any component whose `viewModel` hasn't changed. This prevents updates from cascading through the entire tree.\n\n### Slot Re-rendering\nValdi can re-render a slot's content without re-rendering the component that contains the slot. This is particularly useful for high-level layout components. See [Renderer Internals](./internals-renderer.md) for details.\n\n### Lazy Module Loading\nValdi modules are loaded lazily using ES6 Proxies. Code is only evaluated when it's actually used, which keeps cold start times fast even as your codebase grows.\n\n### Interned Strings and Styles\nThe bridge between TypeScript and C++ is optimized using interning:\n- **Strings**: Common strings (attribute names, view classes) are interned as integers.\n- **Styles**: `Style<>` objects are interned on first use. Reusing style objects in your code allows Valdi to pass a single ID across the bridge instead of a full dictionary of properties.\n"
  },
  {
    "path": "docs/docs/performance-tracing.md",
    "content": "# Debugging Performance\n\n## Tracing\n\nTo help you debug performance issues, Valdi provides a cross-platform tracing API. You can insert your own traces in your TypeScript code to understand how long your call is taking. The framework also traces some key events by default, which are covered in the section below `Framework events`.\n\n### Recording traces\n\n> [!NOTE]\n> Please make sure to add `benchmarking` under `dependencies` and `allowed_debug_dependencies` in the module's `module.yaml` file.\n> Also add `//src/valdi_modules/src/valdi/benchmarking` to the module's `BUILD.bazel` file.\n\n#### `recordTracesWithTimeout()`\n\nThis method works on iOS, Android and Desktop, and requires the hot reloader to be connected. You will need to insert a call to `recordTracesWithTimeout()` from `TraceRecorder.ts` at the appropriate time, which depends on what you are trying to debug. This call will make the runtime starts collecting traces, and store the result as a Chrome Trace file on your local machine that you can open using Perfetto UI.\n\nFor instance, if you wanted to understand what is happening during the creation of your root component, you could insert a `recordTracesWithTimeout()` as follow:\n```tsx\nexport class MyRootComponent extends Component {\n  onCreate() {\n    recordTracesWithTimeout(10000, '~/mytrace');\n  }\n}\n```\n\nAfter 10 seconds, you should see a message in the console like `Saved traces to ~/mytrace.trace`. You can then open the file using [Perfetto UI](https://ui.perfetto.dev/).\n\n#### Using Android Systrace\n\nThis method works on Android only, and does not require the hot reloader to be connected. Valdi traces on Android are also emitted as Android systraces, which means you can use Android's scripts to start recording traces. You can find this script On Snapchat Android at `snapchat/scripts/trace/start_trace.sh`. The script will store the result as a html file on your local machine, which you can open using Perfetto.\n\n### Adding your own traces\n\nAll the following functions are from `Trace.ts` in the `valdi_core` module.\n\n#### trace()\n\nThis function allows to trace a specific section of your code and pass an arbitrary string to identify it.\nExample:\n```ts\nfunction fn() {\n  trace('BuildSection', () => {\n    // Do some expensive work there\n  });\n}\n```\n\n#### `@Trace` annotation\n\nThis annotation can be put on a TypeScript class, and will make all its methods automatically traced. Traced methods using the annotation have lower overhead than the `trace()` function, and they can be thus put on hot code paths.\nExample:\n```ts\n@Trace\nclass MyClass {\n // This method will be traced automatically as MyClass.aMethod when called\n aMethod() {\n   // Do some work here\n }\n}\n```\n\n#### `@TraceMethod` annotation\n\nThis annotation can be put on a single method in a TypeScript class. It is similar to `@Trace`, but is meant to trace a single function instead of all the functions of a class.\nExample:\n```ts\nclass MyClass {\n // This method will be traced as MyClass.aMethod when called\n @TraceMethod\n aMethod() { }\n}\n```\n\n#### `installTraceProxy()`\n\nThe function takes a TypeScript class as its parameter, and will make all its methods automatically traced. It is used by the `@Trace` annotation under the hood. You can use this to inject traces in classes that already exist or are defined in files on which you don't have control on. If you wanted to trace the Renderer calls, as to see what is happening during rendering, you could do this:\n```ts\n// Will make all the methods of Renderer to be be shown in tracing\ninstallTraceProxy(Renderer);\n```\n\n### Framework events\n\nThe Valdi runtime traces some default important events that happens during the lifecycle of your component. This section explains some of them:\n\n- `Valdi.processRenderRequest`: TypeScript rendering has completed, and the framework is now processing the request to update the nodes. Every time a render happens at the TypeScript level, if the render has made any changes, a render request will be emitted that will end up being processed by the runtime. This is where the Valdi C++ runtime syncs its internal state with the state of the nodes in TypeScript.\n\n> [!Note]\n> The Valdi runtime uses **Source Maps** to symbolicate stack traces in the JavaScript engine. This ensures that performance traces and error reports provide meaningful information about your TypeScript code, even when running minified or compiled bytecode.\n\n- `Valdi.updateViewTree`: The framework is going through the nodes and updating the view hierarchy to reflect the changes. This is where the backing views of the nodes are created/destroyed/recycled. This pass might happen after processing a render request, or when scrolling.\n- `Valdi.setUserDefinedViewport`: The framework is reacting to a scroll change.\n- `Valdi.updateVisibility`: The framework is resolving the viewports for the nodes. It is finding out which nodes are visible and which nodes are not visible on the screen.\n- `Valdi.calculateLayout`: The framework is calculating the frames (rectangles) for the nodes. This can happen because nodes have been inserted/removed, because a layout attribute has changed (like `padding`), or because the available space for the root component has changed (for instance if the window has been resized). This can be an expensive operation. Because of this, you should avoid triggering changes in the elements that will cause a layout pass to happen when scrolling. If you need to move elements or show/hide them when scrolling, prefer using the `translationX`/`translationY` attributes or `opacity` which are not layout attributes and don't trigger layout passes when they change.\n\n"
  },
  {
    "path": "docs/docs/performance-view-recycling.md",
    "content": "# View Recycling\n\n## Introduction\n\nTo achieve fast inflation and fast scrolling performance, Valdi recycles all the native views (`UIView` and `android.view.View` and its subclasses). Whenever a view needs to be destroyed, either because a `render-if` toggled to false, or it was part of `for-each` branch which needs to be removed, or the whole component simply needs to be destroyed, Valdi will perform the following actions:\n- The view will be cleared out of all its attributes, this means that all the attributes's reset methods get called on it. This will make the view back to a neutral state. In order to have consistent rendering, it is important that any attributes applied to a View at the platform level can be reverted.\n- On Android, if the View implements `ValdiRecyclableView`, `prepareForRecycling()` will be called and if the view returns false, the view will be simply discarded instead of recycled.\n- On iOS, if the View overrides `willEnqueueIntoValdiPool`, it will be called and if the view returns false, the view will also be discarded.\n- If the methods above returned true, the View will be placed into a dedicated view pool keyed by its class name.\n\n> [!Note]\n> The recycling logic is managed by **View Factories**. Each view class has a corresponding `ViewFactory` that maintains its own pool of reusable view instances. This ensures that view inflation is as efficient as possible across the entire application.\n\nLater on, whenever Valdi needs to create a view of a certain view class, it will first look up in the view pool if there is one pooled view available. If there is it will use it, otherwise a new instance will be created.\n\nThe view pool is _global_, meaning that if there was a previously destroyed Valdi screen, any subsequent opening Valdi screen will inflate faster, as long as they have a fair amount of common views. Because Valdi is designed around composition, most native view trees should have very few different kind of view classes, and as such the number of underlying dedicated view pools should be low and the hit rates on those pools should be high.\n\n## Impact on performance\n\nThis approach aims to make inflation latency as low as possible. It allows patterns that are easy to understand like `for-each`, `render-if` to function in an efficient way. Without it, toggling a `render-if` could mean creating/destroying a lot of views potentially. Thanks to the pooling, once the view pool is cached most of the work being done from Valdi is about reconfiguring views.\n\n## Scrolling\n\nAn additional major benefit is its relationship to the `limitToViewport` attribute (set to `true` by default).\n\nViews that are not visible on screen and have this attribute enabled won't be inflated. When the views become visible they become automatically inflated. This is a common operation when displaying a list of items in a `ScrollView`. With the view pools, doing this is quickly becomes a cheap process.\n\nThe combination of `limitToViewport` with the internal automatic view recycling and `for-each` is how Valdi allows you to display gigantic list of items in a `ScrollView`. Other frameworks, including `UIKit` and the `Android SDK` typically require you to use a `UICollectionView` or `RecyclerView` and implement a bunch of specific interfaces. They handle the recycling at the cell level for you, but they require you to properly cleanup the cell yourself before it gets to the pool. It is a very common source of bugs when cleanup is not handled correctly. \n\nMaking complex layouts with those APIs is also often non trivial. Valdi solves those problems by managing the cleanup of the views automatically, and by not having to use a dedicated component for managing scrollable content that should be using cell recycling. You just use Flexbox to layout your view tree, even for infinitely scrollable content.\n\n## Implementing view recycling on your custom View\n\n- On Android, implement `ValdiRecyclableView` and return `true` in `prepareForRecycling()`. You can do any necessary cleanup in that method as well. Most of the time you shouldn't have anything to do in this method. Don't reset the attributes yourself, this will be done automatically by calling the reset methods.\n- On iOS, override `willEnqueueIntoValdiPool` and return `true`. Same comments apply from Android above.\n- That's it, your view is now recyclable for every consumers of it!\n\n### Note on custom attributes\n\nMake sure that for any attributes you declare in your view, you implement the reset methods and you are able to rollback the attribute exactly as it was before. Failing to do this means that the view might be enqueued in the pool dirty, and this could have side effects like indeterministic rendering if the view ends up being used somewhere else, on a different component or screens.\n\nAdditionally, try to make your attributes apply and reset methods fast. if the view is recycled and re-used when scrolling, it will have to call your attribute handlers to configure your view and thus will have an impact on performance if those methods are slow.\n"
  },
  {
    "path": "docs/docs/start-about.md",
    "content": "# What is Valdi?\n\n## Build native, cross-platform and performant UIs\nValdi is a framework and view abstraction layer that lets you declaratively express complex views. It strikes a balance between performance and flexibility by optimizing declarative views and allowing for event-based business logic in TypeScript.\n\nPractically speaking, the Valdi Compiler can take TypeScript source files and compile them into .valdimodule files that are read by the Valdi Runtime to render natively. There are no web views.\n\n## Benefits\n### Use TypeScript to create views\nValdi uses React-like syntax to create a [tsx](https://www.typescriptlang.org/docs/handbook/jsx.html) view tree, flexbox for layout, and TypeScript for event-handling and business logic.\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nclass HelloWorld extends Component {\n  onRender() {\n    const message = 'Hello World! 👻';\n    <view backgroundColor='#FFFC00' padding={30}>\n      <label color='black' value={message} />\n    </view>;\n  }\n}\n```\n\n<p align=\"center\">\n  <img src=\"./assets//start-about/IMG_1445.jpg\" width=\"500\" />\n</p>\n\n### Integrate with native\n\nWith Valdi, you can easily integrate with platform native code in many ways.\n\n#### Native views in Valdi\n\nNative views can be embedded in Valdi layouts via the [`custom-view`](./native-customviews.md) tag:\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\nclass HelloWorld extends Component {\n  onRender() {\n    const myParamPassedToNativeView = 'hello';\n    <custom-view\n      iosClass=\"MyNativeView\"\n      androidClass=\"com.snap.myfeature.MyNativeView\"\n      paramForNativeView={myParamPassedToNativeView}\n    />\n  }\n}\n```\n\n#### Valdi views in native\n\nValdi views can be easily embedded in [native view](./native-bindings.md) hierarchies.\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\n\n/**\n * @Component\n * @ExportModel({\n *  ios: 'SCValdiHelloWorldView',\n *  android: 'com.snap.hello_world.HelloWorldView'\n * })\n */\nclass HelloWorld extends Component {\n\n  ...\n}\n```\n\n```objectivec\n// In iOS\n#import \"valdi/ios/SCValdiRuntimeManager.h\"\n#import <SCValdiModule/SCValdiHelloWorldView.h>\n\nSCValdiRuntimeManager* runtimeManager = [[SCValdiRuntimeManager alloc] init];\nUIView *view = [[SCValdiHelloWorldView alloc]\n    initWithViewModel:nil\n     componentContext:nil\n     runtime:runtimeManager.mainRuntime];\n```\n\n```java (works better than kotlin syntax highlighting)\n// In Android\nimport com.snap.valdi.support.SupportValdiRuntimeManager\nimport com.valdimodule.HelloWorldView\n\nval runtimeManager = SupportValdiRuntimeManager.createWithSupportLibs(this.applicationContext)\nval view: View = HelloWorldView.create(\n  runtime = runtimeManager.mainRuntime\n)\n```\n\n### Prototype quickly with hot reload\nValdi lets you iterate quickly with hot-reload on all platforms, including on device. Don't waste time re-compiling to get that view feeling just right and to spec.\n\n<p align=\"center\">\n  <img src=\"./assets/start-about/hotreload.gif\" alt=\"Animated image showing how content re-renders with hotreloader\" width=\"500\" />\n</p>\n\n## Advantages over native\n* Build cross-platform UI with a single codebase\n* Writing views with native technology is a slow, manual, and error-prone process\n* UI iteration is generally slow\n* Optimizing layout and view inflation is difficult with native APIs\n\n## Valdi design principles\n* Valdi should be significantly faster to develop with than traditional native code\n* Performance should be equal to, or better than, traditional native code\n* Your UI should never crash\n* What you see on iOS should be the same as what you see on Android\n* It should be possible to build any UI or animation with Valdi\n\n## Layered Architecture\n\nValdi is built as a series of layers, each with a specific responsibility:\n\n*   **Feature Layer (TypeScript)**: Feature-specific business logic and UI built using high-level TypeScript APIs.\n*   **Framework Layer (TypeScript/C++)**: A generic rendering framework that manages component and element lifecycles.\n*   **Core Layer (C++)**: The Valdi Runtime, which integrates the JavaScript engine, the Yoga layout engine, and processes UI updates.\n*   **Integration Layer (C++/Obj-C/Swift/Kotlin)**: Platform-specific implementations of native elements (e.g., `<label>` becoming `SCValdiLabel` on iOS).\n\nFor a deeper dive into the architecture, see [Runtime Internals](./internals-runtime.md).\n"
  },
  {
    "path": "docs/docs/start-code-lab.md",
    "content": "# Valdi Code Labs\n\n## Let's start coding!\n\nWe have a set of codelabs to help you get started with Valdi. They are listed in the recommended order and are meant to be self-paced. \n\n1. [(External) Intro to TypeScript](https://www.typescriptlang.org/docs/handbook/intro.html#get-started)\n2. [Getting started with Valdi from scratch](../codelabs/getting_started/1-introduction.md)\n3. [Valdi integration with native](../codelabs/integration_with_native/1-introduction.md)\n4. [Advanced UI](../codelabs/advanced_ui/1-setup.md)\n\n"
  },
  {
    "path": "docs/docs/start-from-react.md",
    "content": "# Valdi for React Developers\n\nValdi and React are both inspired by Functional Reactive Programming UI patterns.\n\nThe \"state\" of the application is fed into root of the render tree, and components use this state to produce rendered elements. Events emitted by the user interface are then used to change the state of the application in order to produce an updated render tree.\n\nA process compares the new output to the old output and updates the runtime to change the running application.\n\n## Components: Valdi vs React\n\nIn React there are two flavors of components: `function` components and `class` components.\n\nValdi does not have an API equivalent to React’s `function` components.\n\n### React `class` Components\n\nReact’s _`class` components_ inherit from `class React.Component<P, S>` and _at least_ implement an `onRender(): JSX.Element`\n\nProps (`P`) are stored as a property (`this.props`) of the `Component` instance and and are provided by the parent of the component via JSX attribute syntax:\n\n```tsx\n<Heading title=\"Hello World\" />\n```\n\nA component is rendered when:\n\n- It is given new props\n- It calls `this.setState({...})` with new state\n\n### Valdi’s `class Component<ViewModel, State>`\n\nValdi provides a `Component<ViewModel, State, Context>` class similar to React’s `React.Component<P, S>` with the same runtime characteristics for rendering:\n\n- Changes to a component’s props from a parent component will trigger a render pass\n- Calling `this.setState({...})` with changed state values will trigger a render pass\n\nIn Valdi the concept of `Props` are called `ViewModel`s but are otherwise treated identically. In both Valdi and React, the internal/private set of properties that can trigger a render are called `State`.\n\n> **See also:** [The Mighty Component](./core-component.md) for complete documentation on Valdi components and [Component States](./core-states.md) for state management details.\n\n#### Example React Component ported to Valdi\n\nThe following is a trivial React `Component` that uses `Props` and `State`.\n\n```tsx\nimport { Component } from \"react\";\n\ninterface Props {\n  label: string;\n  onDoThing: (count: number) => void;\n}\n\ninterface State {\n  counter: number;\n}\n\nclass MyComponent extends Component<Props, State> {\n  state = {\n    counter: 0,\n  };\n\n  handleTap = () => {\n    const counter = this.state.counter + 1;\n    this.setState({ counter });\n    this.props.onDoThing(counter);\n  };\n\n  onRender(): JSX.Element {\n    return (\n      <view onTap={this.handleTap}>\n        <label\n          value={`${this.props.label} (click count ${this.state.counter})`}\n        />\n      </view>\n    );\n  }\n}\n```\n\nThis component can be used **almost** as is in Valdi:\n\n```tsx\nimport { StatefulComponent } from \"valdi_core/src/Component\";\n\ninterface ViewModel {\n  label: string;\n  onDoThing: (count: number) => void;\n}\n\ninterface State {\n  counter: number;\n}\n\nclass MyComponent extends StatefulComponent<ViewModel, State> {\n  state = {\n    counter: 0,\n  };\n\n  handleTap = () => {\n    const counter = this.state.counter + 1;\n    this.setState({ counter });\n    this.viewModel.onDoThing(counter);\n  };\n\n  onRender(): void {\n    <view onTap={this.handleTap}>\n      <label\n        value={$`{this.viewModel.label} (click count ${this.state.counter})`}\n      />\n    </view>;\n  }\n}\n```\n\nValdi provides a \"stateless\" component: `Component` which has no `State` type or `setState` method. Both `Component` and `StatefulComponent` have a third generic parameter: `Context`.\n\nThis is not the same as React's `Context` API. It is part of Valdi's native API integration. See _[Component Context](./native-context.md)_ to learn more about Valdi's `Context` API.\n\n### Component `key` in React and Valdi\n\nEach Component can be given a `key` property and it functions the same way as React so the same best practices apply.\n\nIf you have a list of items and each item has some intrinsic way of identifying it, using a stable key to reference it will maintain its lifecycle during render passes.\n\n```tsx\n    renderListElements() {\n        for (const item of STUFF) {\n            <ListItem key={item}><label value={item} /></ListItem>\n        }\n    }\n```\n\n## Differences from React\n\nThere are some additional differences, like [life-cycle methods](./core-component.md#lifecycle) but the same best practices remain:\n\n- Do not mutate `this.state`, call `this.setState()`. Valdi sets it to `ReadOnly<State>`\n- Do not mutate `this.viewModel`, the `viewModel`’s value is defined by the parent. Valdi sets it to `ReadOnly<ViewModel>`\n- Inline/lambda functions and non-literal values should be stored as properties of the `class` instance to keep from changing props unintentionally during render. For callback props there is a utility to help with this: [`createReusableCallback`](../../src/valdi_modules/src/valdi/valdi_core/src/utils/Callback.ts#L34)\n\n### Render Output of Valdi vs React.\n\nThere is one significant difference to call out between Valdi and React as it pertains to the `onRender()` method and constructing the output tree.\n\nIn React, the method is `onRender(): JSX.Element | null`. In Valdi, the method is `onRender(): void`. It returns `void`, nothing is returned from `onRender()`.\n\nValdi components **do not return rendered elements**.\n\nWhen `onRender` is called by the Valdi runtime, JSX tags emit the render operations as a side-effect. This means _when_ JSX tags are used is critical to where they end up in the tree.\n\nIn React it is common to store a reference to the `JSX.Element` output of a component and then eventually use it in your component’s output.\n\nFor example, instead of just allowing a `label: string`, in React it can be specified as `label: JSX.Element | null` and the parent can use any other valid React component.\n\n```tsx\n<MyComponent label={<label style={{ color: 'red' }} value=\"Button label text\">}>\n```\n\nThis cannot be done in Valdi. Not only would this fail to pass TypeScript satic analysis, the `<label>` would be emitted into the render tree at a different location in the tree, not where `MyComponent` uses its `this.viewModel.label` property.\n\nTo achieve something similar in Valdi you can use what in the React are sometimes called \"render props\". It would then be up to `MyComponent` to call the function at the correct time.\n\n```tsx\ninterface ViewModel {\n   label: () => void\n}\n\nonRender() {\n   <view margin={20}>{this.viewModel.label()}</view>\n}\n```\n\nDue to the nature of JSX elements being emitted instead of returned, you can also use `for`/`while` loop iterators to generate lists of components.\n\n```tsx\nconst STUFF = [\"beacon\", \"shovel\", \"probe\", \"straps\", \"harness\"];\n\nclass SomeComponent extends Component {\n  onRender() {\n    <List>{this.renderListElements()}</List>;\n  }\n\n  renderListElements() {\n    for (const item of STUFF) {\n      <ListItem>\n        <label value={item} />\n      </ListItem>;\n    }\n  }\n}\n```\n\nIn React, this would produce a `<List />` with nothing in it because the `<ListItem />` components are never returned and placed in the component’s output.\n\n```tsx\n// Example output of <SomeComponent /> using React\n<List />\n```\n\nIn Valdi, because the `renderListElements()` method is emitting `<ListItem>...</ListItem>` elements after the opening of a `<List>` is emitted, but _before_ the closing `</List>` is emitted, the `<ListItem></ListItem>` elements will be placed inside the `<List />` in the component’s rendered representation:\n\n```tsx\n// Example ouptut of <SomeComponent /> using Valdi.\n<List>\n  <ListItem>\n    <label value=\"beacon\" />\n  </ListItem>\n  <ListItem>\n    <label value=\"shovel\" />\n  </ListItem>\n  <ListItem>\n    <label value=\"probes\" />\n  </ListItem>\n</List>\n```\n\nTo reiterate, this is because of _when_ the elements were emitted during a render pass which starts when a component’s `onRender` is called and finishes when all leaves are done rendering.\n\n### Component `ref`\n\nSimilar to `React`, a `Component`’s `ref` provides a way to access the API of the underlying instance of a child component and interact with it beyond using a `Component`’s `viewModel`.\n\nIdeally the contract between a `Component` and its owner is implemented purely in the component’s `ViewModel` but there are instances where it is less complex to interact with the child’s state with imperative code.\n\nVald uses the `interface IRenderedElementHolder<T>` and a `ref` is generally assigned to an implementation stored on the instance of the `Component` rendering it.\n\nAn example of this is [`ScrollViewHandler`](https://github.com/Snapchat/Valdi_Widgets/blob/main/valdi_modules/widgets/src/components/scroll/ScrollViewHandler.ts#L33) which provides a means of interacting with the view underlying a `<scroll>` component.\n\nThis is a trivial example assigns a `ref` to a `<scroll>` native element, and provides a button that scrolls the view down by `10` pixels when pressed.\n\n```tsx\n\ninterface ViewModel {\n    list: {name: string}[]\n}\n\nclass SomeComponent<ViewModel> {\n\n    private currentPosition: {x : number, y: number};\n\n    private readonly scrollHandler = new ScrollViewHandler();\n\n    private scrollDownByTen = () => {\n        this.scrollHandler.scrollTo(\n            this.scrollHandler.scrollX,\n            this.scrollHandler.scrollY + 10\n        );\n    }\n\n    onRender() {\n        <layout>\n            <view onTap={this.scrollDownByTen}>\n                <>\n            </view>\n            <scroll ref={scrollHandler}>\n                {this.viewModel.list.forEach((item) => {\n                    <ListItem data={item} />\n                })}\n            </scroll>\n        </layout>\n    }\n}\n```\n\n### Component `children` and the `<slot />` API\n\nIn React, a component’s `children` prop is used by a component like any other prop.\n\nIn Valdi, a component uses the [`<slot />`](./core-slots.md) API to declare where its children will be rendered.\n\nA Valdi component can specify a different type for its `children` `ViewModel` property. For example the [`MeasuredView` component specifies a function for its children](https://github.com/Snapchat/Valdi_Widgets/blob/main/valdi_modules/widgets/src/components/util/MeasuredView.tsx#L6-L8):\n\n```tsx\nexport interface MeasuredViewModel extends View {\n  children?: (frame: ElementFrame) => void;\n}\n```\n\nTo opt into rendering optimizations, parent componets should use the `$slot` and `$namedSlots` utilities that signal to the rendering system that the children for a component are being changed.\n\nUsing `MeasuredView` as an example, the `children` callback is wrapped in `$slot`:\n\n```tsx\nimport { $slot } from 'valdi_core/src/CompilerIntrinsics';\nimport { MeasuredView } from 'valdi_widgets/src/components/util/MeasuredView';\n\nonRender() {\n    <MeasuredView>\n        {$slot(({ widgth, height }) => {\n            <view>\n            </view>\n        })}\n    </MeasuredView>\n}\n```\n\n## Project Setup\n\nA React project built with `create-react-app` or Vite maps to a Valdi project bootstrapped with `valdi bootstrap`.\n\n| React | Valdi |\n|---|---|\n| `npx create-react-app my-app` | `mkdir my-app && cd my-app && valdi bootstrap` |\n| `package.json` deps | `BUILD.bazel` + `valdi_module()` deps |\n| `npm start` / `vite dev` | `valdi hotreload` |\n| Single `src/index.tsx` entrypoint | Per-module `BUILD.bazel` — modules load lazily |\n| `npm run build` | `bazel build //my_module` |\n\nA Valdi module's `BUILD.bazel`:\n\n```python\nload(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"my_module\",\n    srcs = glob([\"src/**/*.ts\", \"src/**/*.tsx\"]),\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_http\",\n    ],\n)\n```\n\nUnlike a React app's single `main.jsbundle`, each Valdi module compiles to an independent `.valdimodule` archive that is lazy-loaded by the host app.\n\n## Navigation\n\nReact Router and React Navigation both map to Valdi's `NavigationController`, accessed through `NavigationRoot`.\n\n```tsx\n// React Router\nimport { BrowserRouter, Route, Link, useNavigate } from 'react-router-dom';\n\nfunction App() {\n  return (\n    <BrowserRouter>\n      <Route path=\"/detail/:id\" element={<DetailPage />} />\n    </BrowserRouter>\n  );\n}\n\nfunction HomePage() {\n  const navigate = useNavigate();\n  return <button onClick={() => navigate('/detail/123')}>Go</button>;\n}\n```\n\n```tsx\n// Valdi\nimport { NavigationRoot } from 'valdi_navigation/src/NavigationRoot';\nimport { NavigationPageComponent } from 'valdi_navigation/src/NavigationPageComponent';\nimport { $slot } from 'valdi_core/src/CompilerIntrinsics';\n\nclass App extends Component {\n  onRender() {\n    <NavigationRoot>\n      {$slot(navigationController => {\n        <HomePage navigationController={navigationController} />;\n      })}\n    </NavigationRoot>;\n  }\n}\n\n@NavigationPage(module)\nclass HomePage extends NavigationPageComponent<{}> {\n  private goToDetail = () => {\n    // push = horizontal slide; present = vertical modal\n    this.navigationController.push(DetailPage, { id: '123' });\n  };\n\n  onRender() {\n    <view onTap={this.goToDetail}>\n      <label value=\"Go to detail\" />;\n    </view>;\n  }\n}\n```\n\n| React Router / React Navigation | Valdi |\n|---|---|\n| `<BrowserRouter>` / `<NavigationContainer>` | `<NavigationRoot>` |\n| `navigate('/path')` / `navigation.navigate('Screen')` | `this.navigationController.push(Page, viewModel)` |\n| `navigation.goBack()` | `this.navigationController.pop()` |\n| `<Modal>` / bottom sheet | `this.navigationController.present(Page, viewModel)` |\n| Dismiss modal | `this.navigationController.dismiss()` |\n| `useNavigation()` hook | `this.navigationController` (available on all `NavigationPageComponent`) |\n\n## Lists\n\nReact's `Array.map()` and `FlatList` map to a `forEach` loop inside `<scroll>`. The key difference: React's `map()` works because `render()` returns a value. In Valdi, `onRender()` emits JSX as side-effects — `map()` returns an array that is **silently discarded**.\n\n```tsx\n// React — map() works because render() returns JSX\nfunction UserList({ users }) {\n  return (\n    <FlatList\n      data={users}\n      keyExtractor={u => u.id}\n      renderItem={({ item }) => <UserRow user={item} />}\n    />\n  );\n}\n```\n\n```tsx\n// Valdi — use forEach, not map()\nclass UserList extends Component<{ users: User[] }> {\n  onRender() {\n    <scroll>\n      {this.viewModel.users.forEach(user => {\n        <UserRow key={user.id} data={user} />;\n      })}\n    </scroll>;\n  }\n}\n```\n\nValdi's `<scroll>` automatically handles viewport-aware rendering — elements outside the visible area are not inflated. For expensive items, add `lazy={true}` to further limit rendering to the visible viewport.\n\n## Networking\n\n`fetch` and `axios` map to Valdi's `HTTPClient` from the `valdi_http` module. All requests return a `CancelablePromise`.\n\n```tsx\n// React\nuseEffect(() => {\n  const controller = new AbortController();\n  fetch('/api/users', { signal: controller.signal })\n    .then(r => r.json())\n    .then(data => setUsers(data));\n  return () => controller.abort();\n}, []);\n```\n\n```tsx\n// Valdi\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\n\nclass UserList extends StatefulComponent<{}, { users: User[] }> {\n  state = { users: [] };\n  private client = new HTTPClient('https://api.example.com');\n  private request?: { cancel(): void };\n\n  onCreate() {\n    this.request = this.client.get('/users');\n    this.request.then(response => {\n      const users = JSON.parse(new TextDecoder().decode(response.body));\n      this.setState({ users });\n    });\n  }\n\n  onDestroy() {\n    this.request?.cancel(); // Equivalent to AbortController.abort()\n  }\n\n  onRender() {\n    <scroll>\n      {this.state.users.forEach(u => {\n        <label key={u.id} value={u.name} />;\n      })}\n    </scroll>;\n  }\n}\n```\n\nAdd to `BUILD.bazel` deps: `@valdi//src/valdi_modules/src/valdi/valdi_http`\n\n## Styling\n\n`styled-components`, CSS modules, and React Native's `StyleSheet` all map to Valdi's `Style<T>` objects.\n\n```tsx\n// React — styled-components\nconst Card = styled.div`\n  background: white;\n  border-radius: 8px;\n  padding: 16px;\n  box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n`;\n\n// React Native — StyleSheet\nconst styles = StyleSheet.create({\n  card: { backgroundColor: 'white', borderRadius: 8, padding: 16 },\n});\n```\n\n```tsx\n// Valdi — Style<T> at module level (never inside onRender)\nimport { Style } from 'valdi_core/src/Style';\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\nconst cardStyle = new Style<View>({\n  backgroundColor: '#ffffff',\n  borderRadius: 8,\n  padding: 16,\n  boxShadow: '0 2 8 rgba(0,0,0,0.1)',\n});\n\nclass Card extends Component<{ title: string }> {\n  onRender() {\n    <view style={cardStyle}>\n      <label value={this.viewModel.title} />;\n    </view>;\n  }\n}\n```\n\n> [!Important]\n> Never create `new Style()` inside `onRender()`. Valdi assigns each `Style` instance a unique integer ID on first use; creating new instances every render defeats this optimization. Define styles at module level or as class properties.\n\nCombine styles with `Style.merge()` or `.extend()`:\n\n```tsx\nconst activeCardStyle = cardStyle.extend({ borderColor: '#FFFC00', borderWidth: 2 });\nconst combinedStyle = Style.merge(baseStyle, overrideStyle);\n```\n\nFor theming (equivalent to React's `ThemeContext`), use the [Provider pattern](./advanced-provider.md).\n\n## Storage\n\n`localStorage` and `AsyncStorage` (React Native) map to `PersistentStore`.\n\n```tsx\n// React / React Native\nlocalStorage.setItem('token', value);\nconst token = localStorage.getItem('token');\n// or AsyncStorage.setItem / getItem\n```\n\n```tsx\n// Valdi\nimport { PersistentStore } from 'persistence/src/PersistentStore';\n\nconst store = new PersistentStore('my_store', {\n  enableEncryption: true, // for sensitive data like tokens\n});\n\nawait store.storeString('token', value);\nconst token = await store.fetchString('token');\nawait store.remove('token');\n```\n\nAdd to deps: `@valdi//src/valdi_modules/src/valdi/persistence`\n\n## Testing\n\nJest and React Testing Library map to Valdi's jasmine-based test framework with `valdiIt` and `IComponentTestDriver`.\n\n```tsx\n// React Testing Library\ntest('renders counter', () => {\n  render(<Counter label=\"Clicks\" />);\n  expect(screen.getByText('Clicks: 0')).toBeInTheDocument();\n  fireEvent.click(screen.getByRole('button'));\n  expect(screen.getByText('Clicks: 1')).toBeInTheDocument();\n});\n```\n\n```tsx\n// Valdi — test/Counter.spec.tsx\nimport 'jasmine/src/jasmine';\nimport { valdiIt } from 'valdi_core/src/testing';\n\ndescribe('Counter', () => {\n  valdiIt('renders initial count', async driver => {\n    await driver.render(Counter, { label: 'Clicks' });\n    const label = driver.findFirst('label');\n    expect(label?.getAttribute('value')).toBe('Clicks: 0');\n  });\n});\n```\n\nRun tests:\n```sh\nbazel test //my_module:test\n```\n\nSee [Testing documentation](./workflow-testing.md) for full details on `IComponentTestDriver` and hot-reload iteration.\n\n## Common Pitfalls\n\n| React pattern | Valdi equivalent | Why it matters |\n|---|---|---|\n| Inline lambda: `onTap={() => fn()}` | Class arrow fn: `private fn = () => {}` | Inline lambdas create new references each render, causing unnecessary child re-renders |\n| `items.map(i => <Item />)` | `items.forEach(i => { <Item />; })` | `map()` returns are discarded; `forEach` emits as side-effects |\n| `new Style({...})` inside `onRender()` | Module-level `const s = new Style({...})` | Style interning requires stable object identity |\n| `label: JSX.Element` prop | `label: () => void` render prop | JSX can't be passed as a value — it must be called at the right time |\n| `import { x } from 'react'` | `import { x } from 'valdi_core/src/...'` | No React dependency in Valdi |\n| `createReusableCallback` not needed (React) | Use when callback identity must be stable across renders | Prevents spurious viewModel updates in children |\n"
  },
  {
    "path": "docs/docs/start-install.md",
    "content": "# Getting Started with Valdi\n\n> **Get the Valdi CLI from npm.** Run `npm install -g @snap/valdi` and use the commands below. If you're contributing to Valdi itself, see [DEV_SETUP.md](../DEV_SETUP.md).\n\n## Prerequisites\n\n**macOS only:** Install [Xcode from the App Store](https://apps.apple.com/us/app/xcode/id497799835)\n\nEverything else is handled automatically by `valdi dev_setup`!\n\n## Quick Start\n\n```bash\n# 1. Install the Valdi CLI\nnpm install -g @snap/valdi\n\n# 2. Set up your development environment\nvaldi dev_setup\n\n# 3. Verify everything works\nvaldi doctor\n\n# 4. Create your first project\nmkdir my_project && cd my_project\nvaldi bootstrap\nvaldi install ios  # or android\n```\n\n## Full Installation Guide\n\nFor detailed setup instructions, VSCode configuration, and troubleshooting, see the [Installation Guide](../INSTALL.md).\n\n## Help!\n\n- Run `valdi doctor` to diagnose issues\n- Check the [Troubleshooting Guide](../TROUBLESHOOTING.md)\n- Reach out on [Discord](https://discord.gg/uJyNEeYX2U) if you get stuck\n"
  },
  {
    "path": "docs/docs/start-introduction.md",
    "content": "# Introduction\n\nThis guide will introduce many of the core concepts of Valdi, and provide you with a high-level\nunderstanding of what development looks like using Valdi. Further guides will dive deeper into the concepts \nshown here.\n\n> [!Note]\n> These guides assume an intermediate level knowledge of JavaScript/TypeScript. If this is your first exposure to these\n> languages, it might be best to go learn the basics and come back.\n\n## Declarative Rendering\n\nValdi allows developers to declaratively render data into native UIs using a React-like syntax:\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nclass HelloWorld extends Component {\n  private msg?: string;\n  onCreate() {\n    this.msg = 'Hello Valdi on ' + new Date().toLocaleString();\n  }\n  onRender() {\n    <view backgroundColor='lightblue' padding={10}>\n      <label value={this.msg}/>;\n    </view>\n  }\n}\n```\n\n![Screenshot of the HelloWorld component rendering](./assets/start-introduction/IMG_1433.jpg)\n\nWe just created our first Valdi component! \n`onCreate` and `onRender` are Valdi lifecycle events that the Valdi runtime executes to evaluate `this.msg` and then map the value of the `label` on to native views.\n\n> [!Note]\n> Valdi supports **Hot Reloading**, which allows you to see changes in your code immediately without rebuilding the entire application. The compiler works in tandem with the runtime to hot-swap modules and reload components on the fly, significantly increasing developer velocity.\n\n## Inline Variables\n\nBesides just text, we can bind variables to element attributes:\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nclass HelloWorld extends Component {\n  private readonly color = '#' + Math.floor(Math.random()*16777215).toString(16);\n  onRender() {\n    const padding = 5 + 5;\n    <view backgroundColor='lightblue' padding={padding}>\n      <label color={this.color} value='Hello World!'/>\n    </view>\n  }\n}\n```\n\n!['Screenshot of the updated HelloWrold component'](./assets/start-introduction/IMG_1435.jpg)\n\n\n## Inline Conditionals\n\nIt is easy to conditionally render part of the UI based on dynamic variables, as shown here:\n\nUsing `if`\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nclass HelloWorld extends Component {\n  onRender() {\n    if (false) {\n      <label value='This is crazy!' backgroundColor='red' />;\n    } else {\n      <label value='All is well...' backgroundColor='lightblue' margin={10} />;\n    }\n  }\n}\n```\n\n![Screeshot of updated HelloWorld component rendering \"All is well…\"](./assets/start-introduction/IMG_1436.jpg)\n\nIt is also possible to embed conditions inside of xml nodes:\n\nUsing `when`\n\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nimport { when } from 'valdi_core/src/utils/When';\nclass HelloWorld extends Component {\n  onRender() {\n    <view backgroundColor='lightblue' padding={10}>\n      {when(42 === 42, () => {\n        <label value='\"When\" is useful to add a conditional block' />;\n      })}\n    </view>;\n  }\n}\n```\n\n![Screenshot showing updated HelloWorld component](./assets/start-introduction/IMG_1437.jpg)\n\n## Inline Loops\n\nUsing `array.forEach`\n\n```tsx\nclass HelloWorld extends Component {\n  onRender() {\n    const myList = [\"Hello\", \"World\", \"!\"];\n    <view backgroundColor='lightblue' padding={10}>\n      {myList.forEach(str => {\n        <label value={str}/>\n      })}\n    </view>\n  }\n}\n```\n\n![Screenshot showing HelloWorld rendering the text across multiple lines.](./assets/start-introduction/IMG_1438.jpg)\n\nUsing `for`\n\n```tsx\nclass HelloWorld extends Component {\n  onRender() {\n    const myList = [\"Hello\", \"World\", \"!\"];\n    for (const myElement of myList) {\n      <view backgroundColor='lightblue' padding={10}>\n        <label value={myElement} />\n      </view>\n    }\n  }\n}\n```\n\n\n![Screenshot of HelloWorld rendering views with additional paddding](./assets/start-introduction/IMG_1439.jpg)\n\n## Nested Render Functions\n\n```tsx\nclass HelloWorld extends Component {\n  onRender() {\n    <view backgroundColor='lightblue' padding={10}>\n      {this.onRenderContent()}\n    </view>;\n  }\n  onRenderContent() {\n    const variable = 'this is a new scope';\n    if (variable) {\n      <label value='just a regular TypeScript condition' />;\n    } else if (!variable) {\n    } else {\n    }\n    for (let i = 0; i < 10; i++) {\n      <label value='just a regular TypeScript loop' />;\n    }\n    while (false) {}\n  }\n}\n```\n\n![Screenshot of HelloWorld rendering a list of elements based on the updated loop logic](./assets/start-introduction/IMG_1440.jpg)\n\n## Interactive elements\n\nTo respond to user input, such as tapping a button, Valdi `<view>` provides callbacks such as `onTap`:\n\n```tsx\nimport { StatefulComponent } from 'valdi_core/src/Component';\ninterface HelloWorldState {\n  message: string;\n}\nclass HelloWorld extends StatefulComponent<{}, HelloWorldState> {\n  state = {\n    message: 'Hello World',\n  };\n  onRender() {\n    <label value={this.state.message} textAlign='center' margin={10} />;\n    <view onTap={this.onButtonTapped} padding={10} backgroundColor='pink'>\n      <label value='Tap here to wiggle letters around' />\n    </view>;\n  }\n  onButtonTapped = () => {\n    this.setState({\n      message: this.state.message\n        .split('')\n        .reverse()\n        .join(''),\n    });\n  };\n}\n```\n\n![Sreenshot of HelloWorld rendering the view with the onTap callback](./assets/start-introduction/IMG_1441.jpg)\n\nNote that this introduces the concept of Component [state](./core-states.md), as defined by `interface HelloWorldState`.  As opposed to our other examples, we \nwant the UI to respond to changes to our message variable.  In order to do this, we move our `message` variable into the\ncomponent state, and any changes to the state, as shown by called `this.setState`, will automatically update the UI.\nNotice that we access the value of the variable using `this.state.message` within the onRender function.\n\n## Composing Components\n\nIt is good practice to build small components with a single focus for both re-use and ease of development. We encourage you to build small components that can be combined together to create your UI. Valdi makes\nit easy to embed components within components:\n```tsx\nimport { Component } from 'valdi_core/src/Component';\nclass MyOtherComponent extends Component {\n  onRender() {\n    <view backgroundColor='yellow'>\n      <label value='hello!' />;\n    </view>;\n  }\n}\nclass HelloWorld extends Component {\n  onRender() {\n    <view backgroundColor='lightblue' padding={10}>\n      <MyOtherComponent />\n    </view>;\n  }\n}\n```\n\n![Screenshot of HelloWorld rendering MyOtherComponent](./assets/start-introduction/IMG_1442.jpg)\n\nThe parent can pass data down to the child through the child's `ViewModel`:\n\n```tsx\ninterface MyOtherComponentViewModel {\n  message: string;\n}\nclass MyOtherComponent extends Component<MyOtherComponentViewModel> {\n  onRender() {\n    <label value={'Message: ' + this.viewModel.message} />;\n  }\n}\nclass HelloWorld extends Component {\n  onRender() {\n    <view backgroundColor='lightblue' padding={10}>\n      <MyOtherComponent message='Hello World' />;\n    </view>;\n  }\n}\n```\n\n![Screenshot of the HelloWorld component rendering the updated MyOtherComponent](./assets/start-introduction/IMG_1443.jpg)\n\nIn this example, we define `message` to be part of the `interface MyOtherComponentViewModel` of the `<MyOtherComponent>` component. Notice\nthat we access the value of the variable using `viewModel.message` within the template.\n\nThen we use `message='Hello World'` to pass the value of `message` from the parent component down to the child.\n"
  },
  {
    "path": "docs/docs/stdlib-coreutils.md",
    "content": "# Core Utilities (coreutils)\n\nThe `coreutils` module provides a collection of essential utility functions and data structures for Valdi applications.\n\n## Overview\n\nCore utilities are foundational tools extracted from `valdi_core` to be available for modules that `valdi_core` depends on. These utilities cover common programming tasks like array manipulation, encoding, caching, and text processing.\n\n## Installation\n\nThe `coreutils` module is a standard Valdi module. Add it to your `BUILD.bazel` dependencies:\n\n```python\nvaldi_module(\n    name = \"my_module\",\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/coreutils\",\n    ],\n)\n```\n\n## Array Utilities\n\nFunctions for working with arrays efficiently.\n\n### `arrayEquals<T>(left: T[], right: T[]): boolean`\n\nChecks whether two arrays contain the same items in the same order.\n\n```typescript\nimport { arrayEquals } from 'coreutils/src/ArrayUtils';\n\nconst arr1 = [1, 2, 3];\nconst arr2 = [1, 2, 3];\nconst arr3 = [1, 3, 2];\n\nconsole.log(arrayEquals(arr1, arr2)); // true\nconsole.log(arrayEquals(arr1, arr3)); // false\n```\n\n### `lazyMap<T>(array: T[] | undefined, visitor: (item: T) => T): T[]`\n\nLike `Array.map()` but lazy - allocates a new array only when the visitor function returns a different item. Useful for optimization.\n\n```typescript\nimport { lazyMap } from 'coreutils/src/ArrayUtils';\n\nconst numbers = [1, 2, 3, 4, 5];\nconst result = lazyMap(numbers, n => n); // Returns original array, no allocation\nconst doubled = lazyMap(numbers, n => n * 2); // Returns new array\n```\n\n### `binarySearch<T>(array: T[], compareFn: (item: T) => number): number`\n\nSearches for an exact match in a sorted array using binary search.\n\n**Parameters:**\n- `array`: A sorted array to search\n- `compareFn`: Function that returns:\n  - `>0` if the given item is \"higher\" than the searched index\n  - `<0` if the given item is \"lower\"\n  - `0` for a perfect match\n\n**Returns:** Index of the found item, or `-1` if not found.\n\n```typescript\nimport { binarySearch } from 'coreutils/src/ArrayUtils';\n\nconst sortedNumbers = [1, 3, 5, 7, 9, 11, 13];\nconst index = binarySearch(sortedNumbers, item => {\n    return item - 7; // Looking for 7\n});\nconsole.log(index); // 3\n```\n\n### `binarySearchRange<T>(array: T[], compareFn: (item: T) => number, result?: Range): Range`\n\nSearches for a range that would be a suitable match within a sorted array. Returns a `Range` object with `min` and `max` properties.\n\n```typescript\nimport { binarySearchRange } from 'coreutils/src/ArrayUtils';\n\nconst items = [1, 3, 3, 3, 5, 7, 9];\nconst range = binarySearchRange(items, item => item - 3);\n// Returns range of all items matching 3\n```\n\n### Other Array Functions\n\n- `arrayGroupBy<T, K>(array: T[], keyFn: (item: T) => K): StringMap<T[]>` - Groups array items by a key\n- `arrayUniqueBy<T, K>(array: T[], keyFn: (item: T) => K): T[]` - Returns unique items based on a key function\n- `arrayIntersection<T>(left: T[], right: T[]): T[]` - Returns items present in both arrays\n- `arrayDifference<T>(left: T[], right: T[]` - Returns items in left but not in right\n\n## Base64 Encoding\n\nEncode and decode Base64 strings, including URL-safe variants.\n\n```typescript\nimport { fromByteArray, toByteArray } from 'coreutils/src/Base64';\n\n// Encode\nconst data = new Uint8Array([72, 101, 108, 108, 111]);\nconst encoded = fromByteArray(data);\nconsole.log(encoded); // \"SGVsbG8=\"\n\n// Decode\nconst decoded = toByteArray(encoded);\nconsole.log(decoded); // Uint8Array [72, 101, 108, 108, 111]\n```\n\n**Functions:**\n- `byteLength(b64: string): number` - Get byte length of a Base64 string\n- `toByteArray(b64: string): Uint8Array` - Decode Base64 to bytes\n- `fromByteArray(uint8: Uint8Array): string` - Encode bytes to Base64\n\n## LRU Cache\n\nA Least Recently Used (LRU) cache that automatically evicts old items when capacity is reached.\n\n```typescript\nimport { LRUCache } from 'coreutils/src/LRUCache';\n\n// Create a cache that holds up to 100 items\nconst cache = new LRUCache<string>(100);\n\n// Insert items\ncache.insert('user:1', 'Alice');\ncache.insert('user:2', 'Bob');\n\n// Get items (marks as recently used)\nconst user = cache.get('user:1'); // 'Alice'\n\n// Set max size (evicts old items if needed)\ncache.setMaxSize(50);\n\n// Clear all items\ncache.clear();\n\n// Listen to evictions\ncache.listener = {\n    onItemEvicted(key: string, item: string) {\n        console.log(`Evicted ${key}: ${item}`);\n    }\n};\n```\n\n**Methods:**\n- `get(key: string): T | undefined` - Get an item, marking it as recently used\n- `insert(key: string, item: T): void` - Insert or update an item\n- `remove(key: string): T | undefined` - Remove and return an item\n- `setMaxSize(maxSize: number): void` - Change cache capacity\n- `clear(): void` - Remove all items\n- `size: number` - Current number of items\n\n## MD5 Hashing\n\nCompute MD5 hashes of strings.\n\n```typescript\nimport { md5 } from 'coreutils/src/md5';\n\nconst hash = md5('Hello, World!');\nconsole.log(hash); // \"65a8e27d8879283831b664bd8b7f0ad4\"\n```\n\n## UUID Utilities\n\nConvert between UUID string and byte representations.\n\n```typescript\nimport { \n    uuidStringToBytes, \n    uuidBytesToString,\n    uuidStringToBytesList,\n    uuidBytesToStringList\n} from 'coreutils/src/uuidUtils';\n\n// String to bytes\nconst uuid = '550e8400-e29b-41d4-a716-446655440000';\nconst bytes = uuidStringToBytes(uuid);\n\n// Bytes to string\nconst uuidString = uuidBytesToString(bytes);\nconsole.log(uuidString); // \"550e8400-e29b-41d4-a716-446655440000\"\n\n// Batch conversions\nconst uuids = ['550e8400-e29b-41d4-a716-446655440000', 'another-uuid-here'];\nconst bytesList = uuidStringToBytesList(uuids);\nconst stringList = uuidBytesToStringList(bytesList);\n```\n\n## URL Utilities\n\nParse and manipulate URLs.\n\n```typescript\nimport { parseURL, URLComponents } from 'coreutils/src/url';\n\nconst url = 'https://example.com:8080/path?query=value#fragment';\nconst components: URLComponents = parseURL(url);\n\nconsole.log(components.scheme);    // \"https\"\nconsole.log(components.host);      // \"example.com\"\nconsole.log(components.port);      // 8080\nconsole.log(components.path);      // \"/path\"\nconsole.log(components.query);     // \"query=value\"\nconsole.log(components.fragment);  // \"fragment\"\n```\n\n## Unicode Text Processing\n\nUtilities for working with Unicode text, including encoding and decoding.\n\n```typescript\nimport { UnicodeString } from 'coreutils/src/unicode/UnicodeString';\nimport { TextEncoder, TextDecoder } from 'coreutils/src/unicode/TextCoding';\n\n// Unicode string manipulation\nconst str = new UnicodeString('Hello 👋 World');\nconsole.log(str.length); // Character count including emoji\n\n// Text encoding/decoding\nconst encoder = new TextEncoder();\nconst bytes = encoder.encode('Hello');\n\nconst decoder = new TextDecoder();\nconst text = decoder.decode(bytes);\n```\n\n## Serial Task Queue\n\nExecute asynchronous tasks serially, one at a time.\n\n```typescript\nimport { SerialTaskQueue } from 'coreutils/src/SerialTaskQueue';\n\nconst queue = new SerialTaskQueue();\n\n// Add tasks\nqueue.enqueue(async () => {\n    console.log('Task 1');\n    await someAsyncOperation();\n});\n\nqueue.enqueue(async () => {\n    console.log('Task 2');\n    await anotherAsyncOperation();\n});\n\n// Tasks execute serially: Task 1 completes before Task 2 starts\n```\n\n## String Map and String Set\n\nEfficient map and set implementations optimized for string keys.\n\n```typescript\nimport { StringMap } from 'coreutils/src/StringMap';\nimport { StringSet } from 'coreutils/src/StringSet';\n\n// StringMap - object-based map for better performance with string keys\nconst map: StringMap<number> = {};\nmap['key1'] = 42;\nmap['key2'] = 100;\n\n// StringSet - object-based set for string membership testing\nconst set: StringSet = {};\nset['apple'] = true;\nset['banana'] = true;\n\nif (set['apple']) {\n    console.log('Has apple');\n}\n```\n\n## Uint8Array Utilities\n\nHelper functions for working with `Uint8Array`.\n\n```typescript\nimport { \n    areUint8ArraysEqual,\n    concatUint8Arrays \n} from 'coreutils/src/Uint8ArrayUtils';\n\nconst arr1 = new Uint8Array([1, 2, 3]);\nconst arr2 = new Uint8Array([1, 2, 3]);\nconst arr3 = new Uint8Array([4, 5, 6]);\n\nconsole.log(areUint8ArraysEqual(arr1, arr2)); // true\nconsole.log(areUint8ArraysEqual(arr1, arr3)); // false\n\nconst combined = concatUint8Arrays([arr1, arr3]);\nconsole.log(combined); // Uint8Array [1, 2, 3, 4, 5, 6]\n```\n\n## Range Type\n\nSimple interface for representing a numeric range.\n\n```typescript\nimport { Range } from 'coreutils/src/Range';\n\nconst range: Range = { min: 0, max: 100 };\n```\n\n## Best Practices\n\n1. **Use LRU Cache for bounded caches**: When you need a cache with automatic eviction, prefer `LRUCache` over unbounded `Map`.\n\n2. **Prefer lazyMap for conditional transformations**: When mapping an array where many items might not change, `lazyMap` avoids unnecessary allocations.\n\n3. **Use binary search for sorted data**: If you maintain sorted arrays, `binarySearch` is much faster than linear search for large datasets.\n\n4. **StringMap for performance**: For maps with string keys, `StringMap` (plain objects) can be faster than `Map<string, T>` in some JavaScript engines.\n\n## See Also\n\n- [Foundation](./stdlib-foundation.md) - Extended utility functions\n- [File System](./stdlib-filesystem.md) - File I/O operations\n- [Performance Optimization](./performance-optimization.md) - Tips for efficient code\n\n## Testing\n\nThe `coreutils` module includes comprehensive unit tests. To run them:\n\n```bash\nbazel test //src/valdi_modules/src/valdi/coreutils/test/...\n```\n\n"
  },
  {
    "path": "docs/docs/stdlib-filesystem.md",
    "content": "# File System (file_system)\n\nThe `file_system` module provides synchronous file system operations for Valdi applications.\n\n> **⚠️ Internal Use Only**: This module is primarily for internal Valdi infrastructure usage. For most application needs, consider using [Persistent Storage](./stdlib-persistence.md) instead, which provides a higher-level, safer API for data persistence.\n\n## Overview\n\nThe file system module exposes low-level synchronous file operations through a native C++ API. Operations are performed synchronously and may block the JavaScript thread, so use with caution.\n\n## Installation\n\nAdd the `file_system` module to your `BUILD.bazel` dependencies:\n\n```python\nvaldi_module(\n    name = \"my_module\",\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/file_system\",\n    ],\n)\n```\n\n## Basic Usage\n\n```typescript\nimport { fs, VALDI_MODULES_ROOT } from 'file_system/src/FileSystem';\n\n// Get current working directory\nconst cwd = fs.currentWorkingDirectory();\nconsole.log('Working directory:', cwd);\n\n// Read a file as string\nconst content = fs.readFileSync('/path/to/file.txt', { encoding: 'utf8' }) as string;\nconsole.log(content);\n\n// Read a file as binary\nconst buffer = fs.readFileSync('/path/to/file.dat') as ArrayBuffer;\nconsole.log(new Uint8Array(buffer));\n\n// Write a string to file\nfs.writeFileSync('/path/to/output.txt', 'Hello, World!');\n\n// Write binary data to file\nconst data = new Uint8Array([1, 2, 3, 4, 5]);\nfs.writeFileSync('/path/to/output.dat', data.buffer);\n\n// Create a directory\nfs.createDirectorySync('/path/to/new/directory', true); // true = create intermediates\n\n// Remove a file or directory\nfs.removeSync('/path/to/file.txt');\n```\n\n## API Reference\n\n### FileSystemModule\n\nThe main file system interface, accessed via the `fs` export.\n\n#### `currentWorkingDirectory(): string`\n\nReturns the current working directory path.\n\n```typescript\nconst cwd = fs.currentWorkingDirectory();\nconsole.log(cwd); // e.g., \"/Users/username/project\"\n```\n\n#### `readFileSync(path: string, options?: ReadFileOptions): string | ArrayBuffer`\n\nSynchronously reads a file and returns its contents.\n\n**Parameters:**\n- `path` - Absolute or relative file path\n- `options` - Optional encoding specification\n\n**Returns:**\n- If `encoding` is specified: returns `string`\n- If `encoding` is omitted: returns `ArrayBuffer`\n\n```typescript\n// Read as UTF-8 string\nconst text = fs.readFileSync('config.json', { encoding: 'utf8' }) as string;\nconst config = JSON.parse(text);\n\n// Read as UTF-16 string\nconst utf16Text = fs.readFileSync('data.txt', { encoding: 'utf16' }) as string;\n\n// Read as binary\nconst binary = fs.readFileSync('image.png') as ArrayBuffer;\nconst bytes = new Uint8Array(binary);\n```\n\n#### `writeFileSync(path: string, data: ArrayBuffer | string): void`\n\nSynchronously writes data to a file, creating it if it doesn't exist or overwriting if it does.\n\n**Parameters:**\n- `path` - Absolute or relative file path\n- `data` - String or binary data to write\n\n```typescript\n// Write string\nfs.writeFileSync('output.txt', 'Hello, World!');\n\n// Write binary\nconst imageData = new Uint8Array([...]); // image bytes\nfs.writeFileSync('output.png', imageData.buffer);\n\n// Write JSON\nconst config = { setting1: true, setting2: 'value' };\nfs.writeFileSync('config.json', JSON.stringify(config, null, 2));\n```\n\n#### `createDirectorySync(path: string, createIntermediates: boolean): boolean`\n\nSynchronously creates a directory.\n\n**Parameters:**\n- `path` - Directory path to create\n- `createIntermediates` - If `true`, creates parent directories as needed (like `mkdir -p`)\n\n**Returns:** `true` if successful, `false` otherwise\n\n```typescript\n// Create a single directory (fails if parent doesn't exist)\nfs.createDirectorySync('/path/to/dir', false);\n\n// Create directory with intermediates (like mkdir -p)\nfs.createDirectorySync('/path/to/nested/dir', true);\n```\n\n#### `removeSync(path: string): boolean`\n\nSynchronously removes a file or directory.\n\n**Parameters:**\n- `path` - File or directory path to remove\n\n**Returns:** `true` if successful, `false` otherwise\n\n**Warning:** Be careful with this operation - it's permanent!\n\n```typescript\n// Remove a file\nfs.removeSync('/path/to/file.txt');\n\n// Remove a directory\nfs.removeSync('/path/to/directory');\n```\n\n### Types\n\n#### `FileEncoding`\n\n```typescript\ntype FileEncoding = 'utf8' | 'utf16';\n```\n\nSupported text encodings for reading files.\n\n#### `ReadFileOptions`\n\n```typescript\ninterface ReadFileOptions {\n    encoding?: FileEncoding | undefined | null;\n}\n```\n\nOptions for reading files.\n\n### Constants\n\n#### `VALDI_MODULES_ROOT`\n\n```typescript\nconst VALDI_MODULES_ROOT = './valdi_modules/src/valdi';\n```\n\nPath to the Valdi modules root directory.\n\n## Use Cases\n\n### Reading Configuration Files\n\n```typescript\nfunction loadConfig<T>(filename: string): T {\n    try {\n        const content = fs.readFileSync(filename, { encoding: 'utf8' }) as string;\n        return JSON.parse(content);\n    } catch (error) {\n        console.error(`Failed to load config from ${filename}:`, error);\n        throw error;\n    }\n}\n\nconst config = loadConfig<{ apiUrl: string; timeout: number }>('config.json');\n```\n\n### Writing Log Files\n\n```typescript\nfunction appendLog(message: string) {\n    const timestamp = new Date().toISOString();\n    const logEntry = `[${timestamp}] ${message}\\n`;\n    \n    const logPath = `${fs.currentWorkingDirectory()}/app.log`;\n    \n    try {\n        // Read existing log\n        let existingLog = '';\n        try {\n            existingLog = fs.readFileSync(logPath, { encoding: 'utf8' }) as string;\n        } catch {\n            // File doesn't exist yet\n        }\n        \n        // Append new entry\n        fs.writeFileSync(logPath, existingLog + logEntry);\n    } catch (error) {\n        console.error('Failed to write log:', error);\n    }\n}\n```\n\n### Creating Build Artifacts\n\n```typescript\nfunction saveBuildArtifact(data: Uint8Array, filename: string) {\n    const buildDir = `${fs.currentWorkingDirectory()}/build`;\n    \n    // Create build directory if it doesn't exist\n    fs.createDirectorySync(buildDir, true);\n    \n    // Write artifact\n    fs.writeFileSync(`${buildDir}/${filename}`, data.buffer);\n}\n```\n\n## Important Warnings\n\n### ⚠️ Synchronous Operations\n\nAll operations in this module are **synchronous** and **will block** the JavaScript thread. This can cause UI freezes if used with large files or slow storage.\n\n```typescript\n// ❌ BAD: Blocks UI thread\nconst largeFile = fs.readFileSync('large_video.mp4') as ArrayBuffer;\n\n// ✅ BETTER: Use PersistentStore or async APIs for large data\n```\n\n### ⚠️ Platform Limitations\n\nFile system access may be restricted on iOS and Android:\n- iOS: Limited to app sandbox\n- Android: Limited to app private storage and external storage (with permissions)\n- Web: Not available (use IndexedDB or similar instead)\n\n### ⚠️ Security Considerations\n\nDirect file system access can be dangerous:\n- Be careful with user-provided paths (path traversal attacks)\n- Don't store sensitive data without encryption\n- Be aware of file permissions on different platforms\n\n## Best Practices\n\n1. **Prefer PersistentStore**: For most application data needs, use [PersistentStore](./stdlib-persistence.md) instead of direct file I/O.\n\n2. **Use for build tools only**: This module is best suited for build scripts, code generation, and development tools.\n\n3. **Handle errors**: Wrap all file operations in try-catch blocks.\n\n4. **Check file existence**: Before reading, consider checking if files exist (though there's no direct exists() method).\n\n5. **Use absolute paths**: When possible, use absolute paths to avoid ambiguity.\n\n6. **Avoid in production UI**: Don't use synchronous file I/O in production UI code - it will freeze the interface.\n\n## Error Handling\n\nAll methods can throw exceptions on failure. Always wrap in try-catch:\n\n```typescript\nfunction safeReadFile(path: string): string | null {\n    try {\n        return fs.readFileSync(path, { encoding: 'utf8' }) as string;\n    } catch (error) {\n        console.error(`Failed to read ${path}:`, error);\n        return null;\n    }\n}\n\nfunction safeWriteFile(path: string, data: string): boolean {\n    try {\n        fs.writeFileSync(path, data);\n        return true;\n    } catch (error) {\n        console.error(`Failed to write ${path}:`, error);\n        return false;\n    }\n}\n```\n\n## Alternative: Persistent Storage\n\nFor most application needs, **use PersistentStore instead**:\n\n```typescript\n// ❌ Using file_system for app data\nimport { fs } from 'file_system/src/FileSystem';\nfs.writeFileSync('user_prefs.json', JSON.stringify(prefs));\n\n// ✅ Better: Use PersistentStore\nimport { PersistentStore } from 'persistence/src/PersistentStore';\nconst store = new PersistentStore('user_prefs');\nawait store.storeString('preferences', JSON.stringify(prefs));\n```\n\n**Advantages of PersistentStore:**\n- ✅ Asynchronous (doesn't block UI)\n- ✅ Automatic encryption support\n- ✅ TTL and LRU caching\n- ✅ Batch writes for performance\n- ✅ Cross-platform (including web)\n\n## See Also\n\n- [Persistent Storage](./stdlib-persistence.md) - **Recommended** higher-level storage API\n- [Core Utilities](./stdlib-coreutils.md) - Additional utility functions\n- [Advanced Worker Service](./advanced-worker-service.md) - For running file I/O in background threads\n\n## Platform Support\n\n- ✅ iOS (limited to app sandbox)\n- ✅ Android (limited to app storage)\n- ❌ Web (not available)\n\n## Testing\n\nWhen using file_system in tests, you may need to mock the native module:\n\n```typescript\n// In test setup\nconst mockFs = {\n    readFileSync: jest.fn(),\n    writeFileSync: jest.fn(),\n    createDirectorySync: jest.fn(),\n    removeSync: jest.fn(),\n    currentWorkingDirectory: jest.fn(() => '/mock/path')\n};\n```\n\n"
  },
  {
    "path": "docs/docs/stdlib-http.md",
    "content": "# HTTP Client (valdi_http)\n\nThe `valdi_http` module provides a promise-based HTTP client for making network requests from Valdi applications.\n\n## Overview\n\nThe HTTP client supports all standard HTTP methods (GET, POST, PUT, DELETE, HEAD) and returns cancelable promises, allowing you to abort in-flight requests.\n\n## Installation\n\nAdd the `valdi_http` module to your `BUILD.bazel` dependencies:\n\n```python\nvaldi_module(\n    name = \"my_module\",\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/valdi_http\",\n    ],\n)\n```\n\n## Basic Usage\n\n```typescript\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\n\nconst client = new HTTPClient('https://api.example.com');\n\n// GET request\nconst response = await client.get('/users');\nconsole.log(response.statusCode); // 200\nconsole.log(response.body); // Uint8Array\n\n// POST request with body\nconst postData = new TextEncoder().encode(JSON.stringify({ name: 'Alice' }));\nconst postResponse = await client.post('/users', postData, {\n    'Content-Type': 'application/json'\n});\n```\n\n## API Reference\n\n### HTTPClient\n\nThe main HTTP client class.\n\n#### Constructor\n\n```typescript\nconstructor(baseURL?: string)\n```\n\nCreates a new HTTP client with an optional base URL. If provided, all requests will be relative to this base URL.\n\n```typescript\n// With base URL\nconst client = new HTTPClient('https://api.example.com');\nawait client.get('/users'); // Requests https://api.example.com/users\n\n// Without base URL (must use full URLs)\nconst client = new HTTPClient();\nawait client.get('https://api.example.com/users');\n```\n\n#### Methods\n\n##### `get(pathOrUrl: string, headers?: StringMap<string>): CancelablePromise<HTTPResponse>`\n\nPerforms an HTTP GET request.\n\n```typescript\nconst response = await client.get('/api/data', {\n    'Authorization': 'Bearer token123',\n    'Accept': 'application/json'\n});\n```\n\n##### `post(pathOrUrl: string, body?: ArrayBuffer | Uint8Array, headers?: StringMap<string>): CancelablePromise<HTTPResponse>`\n\nPerforms an HTTP POST request with optional body.\n\n```typescript\nconst jsonData = JSON.stringify({ username: 'alice', email: 'alice@example.com' });\nconst body = new TextEncoder().encode(jsonData);\n\nconst response = await client.post('/api/users', body, {\n    'Content-Type': 'application/json'\n});\n```\n\n##### `put(pathOrUrl: string, body?: ArrayBuffer | Uint8Array, headers?: StringMap<string>): CancelablePromise<HTTPResponse>`\n\nPerforms an HTTP PUT request with optional body.\n\n```typescript\nconst updateData = new TextEncoder().encode(JSON.stringify({ name: 'Alice Updated' }));\nconst response = await client.put('/api/users/123', updateData, {\n    'Content-Type': 'application/json'\n});\n```\n\n##### `delete(pathOrUrl: string, headers?: StringMap<string>): CancelablePromise<HTTPResponse>`\n\nPerforms an HTTP DELETE request.\n\n```typescript\nconst response = await client.delete('/api/users/123', {\n    'Authorization': 'Bearer token123'\n});\n```\n\n##### `head(pathOrUrl: string, headers?: StringMap<string>): CancelablePromise<HTTPResponse>`\n\nPerforms an HTTP HEAD request (returns only headers, no body).\n\n```typescript\nconst response = await client.head('/api/resource');\nconsole.log(response.headers['Content-Length']);\n```\n\n## Types\n\n### HTTPRequest\n\n```typescript\ninterface HTTPRequest {\n    url: string;\n    method: HTTPMethod;\n    headers?: StringMap<string>;\n    body?: ArrayBuffer | Uint8Array;\n    priority?: number;\n}\n```\n\n### HTTPResponse\n\n```typescript\ninterface HTTPResponse {\n    headers: StringMap<string>;\n    statusCode: number;\n    body?: Uint8Array;\n}\n```\n\nResponse from an HTTP request.\n\n**Properties:**\n- `statusCode` - HTTP status code (200, 404, 500, etc.)\n- `headers` - Response headers as a string map\n- `body` - Response body as `Uint8Array` (optional)\n\n```typescript\nconst response = await client.get('/api/data');\n\nif (response.statusCode === 200) {\n    // Decode response body\n    const text = new TextDecoder().decode(response.body);\n    const data = JSON.parse(text);\n    console.log(data);\n}\n```\n\n### HTTPMethod\n\n```typescript\nenum HTTPMethod {\n    GET = 'GET',\n    POST = 'POST',\n    DELETE = 'DELETE',\n    PUT = 'PUT',\n    HEAD = 'HEAD',\n}\n```\n\n## Canceling Requests\n\nAll HTTP methods return `CancelablePromise`, which allows you to cancel in-flight requests:\n\n```typescript\nconst request = client.get('/api/large-file');\n\n// Cancel the request after 5 seconds\nsetTimeout(() => {\n    request.cancel();\n}, 5000);\n\ntry {\n    const response = await request;\n    console.log('Request completed');\n} catch (error) {\n    console.log('Request was canceled or failed');\n}\n```\n\n## Working with JSON\n\n### Sending JSON\n\n```typescript\nfunction sendJSON(client: HTTPClient, path: string, data: any): Promise<HTTPResponse> {\n    const jsonString = JSON.stringify(data);\n    const body = new TextEncoder().encode(jsonString);\n    \n    return client.post(path, body, {\n        'Content-Type': 'application/json'\n    });\n}\n\nconst response = await sendJSON(client, '/api/users', {\n    name: 'Bob',\n    email: 'bob@example.com'\n});\n```\n\n### Receiving JSON\n\n```typescript\nasync function getJSON<T>(client: HTTPClient, path: string): Promise<T> {\n    const response = await client.get(path, {\n        'Accept': 'application/json'\n    });\n    \n    if (response.statusCode !== 200) {\n        throw new Error(`HTTP ${response.statusCode}`);\n    }\n    \n    const text = new TextDecoder().decode(response.body);\n    return JSON.parse(text);\n}\n\ninterface User {\n    id: number;\n    name: string;\n    email: string;\n}\n\nconst user = await getJSON<User>(client, '/api/users/123');\nconsole.log(user.name);\n```\n\n## Error Handling\n\n```typescript\nasync function fetchData() {\n    try {\n        const response = await client.get('/api/data');\n        \n        if (response.statusCode >= 200 && response.statusCode < 300) {\n            // Success\n            const text = new TextDecoder().decode(response.body);\n            return JSON.parse(text);\n        } else {\n            // HTTP error\n            throw new Error(`HTTP error: ${response.statusCode}`);\n        }\n    } catch (error) {\n        // Network error or request canceled\n        console.error('Request failed:', error);\n        throw error;\n    }\n}\n```\n\n## Advanced Usage\n\n### Custom Headers\n\n```typescript\nconst client = new HTTPClient('https://api.example.com');\n\nconst commonHeaders = {\n    'Authorization': 'Bearer my-token',\n    'X-App-Version': '1.0.0',\n    'User-Agent': 'MyApp/1.0'\n};\n\nconst response = await client.get('/api/data', commonHeaders);\n```\n\n### Uploading Binary Data\n\n```typescript\nasync function uploadFile(client: HTTPClient, file: Uint8Array) {\n    const response = await client.post('/api/upload', file, {\n        'Content-Type': 'application/octet-stream'\n    });\n    \n    return response;\n}\n```\n\n### Request Priority\n\nSome implementations support request prioritization:\n\n```typescript\nconst request: HTTPRequest = {\n    url: '/api/critical-data',\n    method: HTTPMethod.GET,\n    headers: { 'Authorization': 'Bearer token' },\n    priority: 10 // Higher priority\n};\n```\n\n## Best Practices\n\n1. **Reuse HTTP client instances**: Create one client per base URL and reuse it across your application.\n\n2. **Cancel unnecessary requests**: Use the cancelable promise to abort requests when components unmount or data is no longer needed.\n\n3. **Handle errors gracefully**: Always check status codes and handle network errors.\n\n4. **Use appropriate timeouts**: Cancel long-running requests that exceed expected timeouts.\n\n5. **Decode response bodies**: Remember that `body` is always `Uint8Array` - decode appropriately for text/JSON.\n\n## Integration with Components\n\n```typescript\nimport { Component } from 'valdi_core/src/Component';\nimport { HTTPClient } from 'valdi_http/src/HTTPClient';\n\nexport class UserListComponent extends Component {\n    private httpClient = new HTTPClient('https://api.example.com');\n    private currentRequest?: CancelablePromise<HTTPResponse>;\n    \n    onCreate() {\n        this.loadUsers();\n    }\n    \n    private async loadUsers() {\n        try {\n            this.currentRequest = this.httpClient.get('/api/users');\n            const response = await this.currentRequest;\n            \n            const text = new TextDecoder().decode(response.body);\n            const users = JSON.parse(text);\n            \n            this.setState({ users });\n        } catch (error) {\n            console.error('Failed to load users:', error);\n        }\n    }\n    \n    onDestroy() {\n        // Cancel any in-flight requests when component is destroyed\n        if (this.currentRequest) {\n            this.currentRequest.cancel();\n        }\n    }\n    \n    onRender() {\n        // Render users...\n    }\n}\n```\n\n## See Also\n\n- [Protobuf](./advanced-protobuf.md) - For structured binary protocols\n- [RxJS](./client-libraries-rxjs.md) - For reactive HTTP patterns\n- [Native Bindings](./native-bindings.md) - Type conversion details\n- [Cancelable Promise](./stdlib-coreutils.md) - Promise cancellation patterns\n\n## Platform Support\n\nThe `valdi_http` module works on:\n- ✅ iOS\n- ✅ Android\n- ✅ Web (via polyfill)\n\nNetwork requests are always performed asynchronously and will not block the JavaScript thread.\n\n"
  },
  {
    "path": "docs/docs/stdlib-persistence.md",
    "content": "# Persistent Storage (persistence)\n\nThe `persistence` module provides a simple key-value store that persists data across app sessions, with optional encryption and LRU caching.\n\n> [!Note]\n> The Valdi runtime provides a built-in **Disk Store** mechanism. This allows TypeScript components to persist data locally on the device, ensuring that user preferences, session tokens, and cached assets are available even after the application is restarted.\n\n## Overview\n\n`PersistentStore` allows you to store binary data or strings that survive app restarts. It supports:\n- User-scoped or device-global storage\n- Optional encryption for sensitive data\n- TTL (time-to-live) for automatic expiration\n- LRU cache behavior with maximum weight limits\n- Batch writes for performance\n\n## Installation\n\nAdd the `persistence` module to your `BUILD.bazel` dependencies:\n\n```python\nvaldi_module(\n    name = \"my_module\",\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/persistence\",\n    ],\n)\n```\n\n## Basic Usage\n\n```typescript\nimport { PersistentStore } from 'persistence/src/PersistentStore';\n\n// Create a persistent store\nconst store = new PersistentStore('my_app_data');\n\n// Store a string\nawait store.storeString('username', 'alice');\n\n// Fetch a string\nconst username = await store.fetchString('username');\nconsole.log(username); // 'alice'\n\n// Store binary data\nconst binaryData = new Uint8Array([1, 2, 3, 4, 5]);\nawait store.store('binary_key', binaryData.buffer);\n\n// Fetch binary data\nconst data = await store.fetch('binary_key');\nconsole.log(new Uint8Array(data)); // [1, 2, 3, 4, 5]\n\n// Remove data\nawait store.remove('username');\n```\n\n## API Reference\n\n### PersistentStore\n\n#### Constructor\n\n```typescript\nconstructor(name: string, options?: PersistentStoreOptions)\n```\n\nCreates a new persistent store with the given name.\n\n**Parameters:**\n- `name` - Unique identifier for this store\n- `options` - Optional configuration (see PersistentStoreOptions below)\n\n```typescript\nconst store = new PersistentStore('user_preferences', {\n    enableEncryption: true,\n    maxWeight: 1024 * 1024 // 1MB cache\n});\n```\n\n#### Methods\n\n##### `store(key: string, value: ArrayBuffer, ttlSeconds?: number, weight?: number): Promise<void>`\n\nStore binary data with the given key.\n\n**Parameters:**\n- `key` - Unique key for this data\n- `value` - Binary data to store\n- `ttlSeconds` - Optional time-to-live in seconds (data auto-expires)\n- `weight` - Optional weight for LRU eviction (when maxWeight is set)\n\n```typescript\nconst data = new Uint8Array([1, 2, 3, 4]);\nawait store.store('my_data', data.buffer);\n\n// With TTL (expires in 1 hour)\nawait store.store('temporary', data.buffer, 3600);\n\n// With weight for LRU cache\nawait store.store('cached_image', imageBuffer, undefined, 512 * 1024); // 512KB\n```\n\n##### `storeString(key: string, value: string, ttlSeconds?: number, weight?: number): Promise<void>`\n\nStore a string with the given key.\n\n```typescript\nawait store.storeString('user_name', 'Alice');\n\n// With TTL (expires in 24 hours)\nawait store.storeString('session_token', 'abc123', 86400);\n```\n\n##### `fetch(key: string): Promise<ArrayBuffer>`\n\nFetch binary data for the given key. Throws if key doesn't exist.\n\n```typescript\ntry {\n    const data = await store.fetch('my_data');\n    console.log(new Uint8Array(data));\n} catch (error) {\n    console.log('Key not found or expired');\n}\n```\n\n##### `fetchString(key: string): Promise<string>`\n\nFetch a string for the given key. Throws if key doesn't exist.\n\n```typescript\ntry {\n    const username = await store.fetchString('user_name');\n    console.log(username);\n} catch (error) {\n    console.log('Key not found or expired');\n}\n```\n\n##### `exists(key: string): Promise<boolean>`\n\nTest whether data for the given key exists (and hasn't expired).\n\n```typescript\nif (await store.exists('user_name')) {\n    const username = await store.fetchString('user_name');\n    console.log(username);\n}\n```\n\n##### `remove(key: string): Promise<void>`\n\nRemove data for the given key.\n\n```typescript\nawait store.remove('user_name');\n```\n\n##### `removeAll(): Promise<void>`\n\nRemove all data from this persistent store.\n\n```typescript\n// Clear all stored data\nawait store.removeAll();\n```\n\n##### `fetchAll(): Promise<PropertyList>`\n\nFetch all items as a PropertyList (map of key-value pairs).\n\n```typescript\nconst allData = await store.fetchAll();\nconsole.log(allData);\n```\n\n### PersistentStoreOptions\n\nConfiguration options for creating a persistent store.\n\n```typescript\ninterface PersistentStoreOptions {\n    disableBatchWrites?: boolean;\n    deviceGlobal?: boolean;\n    maxWeight?: number;\n    enableEncryption?: boolean;\n}\n```\n\n#### `disableBatchWrites?: boolean`\n\nBy default, save operations are batched to minimize disk I/O. Set to `true` to write immediately on every `store()` or `remove()` call.\n\n```typescript\nconst store = new PersistentStore('immediate_writes', {\n    disableBatchWrites: true // Writes happen immediately\n});\n```\n\n**Default:** `false` (batching enabled for better performance)\n\n#### `deviceGlobal?: boolean`\n\nWhether the store should be available globally across all user sessions, instead of being scoped to the current user. Data will not be encrypted when this flag is set.\n\n```typescript\n// Device-global store (shared across all users)\nconst deviceStore = new PersistentStore('device_settings', {\n    deviceGlobal: true\n});\n\n// User-scoped store (default)\nconst userStore = new PersistentStore('user_preferences');\n```\n\n**Default:** `false` (user-scoped)\n\n#### `maxWeight?: number`\n\nIf set, the store acts like an LRU cache where items are removed as needed to keep total weight below this value. When using this, provide weight when calling `store()`.\n\n```typescript\nconst imageCache = new PersistentStore('image_cache', {\n    maxWeight: 10 * 1024 * 1024 // 10MB max\n});\n\n// Store with weight\nconst imageData = await loadImage();\nawait imageCache.store('image_123', imageData, undefined, 2 * 1024 * 1024); // 2MB\n```\n\n**Default:** `0` (no weight limit)\n\n#### `enableEncryption?: boolean`\n\nSet to `true` when storing sensitive data (credit cards, secret keys, authentication cookies). \n\n**Performance Note:** Encryption has some performance overhead. Use `false` for non-sensitive data.\n\n```typescript\nconst secureStore = new PersistentStore('credentials', {\n    enableEncryption: true\n});\n\nawait secureStore.storeString('api_key', 'secret_key_123');\n```\n\n**Default:** `false` (no encryption)\n\n## Common Use Cases\n\n### User Preferences\n\n```typescript\nclass UserPreferences {\n    private store = new PersistentStore('user_prefs');\n    \n    async saveTheme(theme: 'light' | 'dark') {\n        await this.store.storeString('theme', theme);\n    }\n    \n    async getTheme(): Promise<'light' | 'dark'> {\n        try {\n            return await this.store.fetchString('theme') as 'light' | 'dark';\n        } catch {\n            return 'light'; // Default\n        }\n    }\n}\n```\n\n### Session Management\n\n```typescript\nclass SessionManager {\n    private store = new PersistentStore('sessions', {\n        enableEncryption: true\n    });\n    \n    async saveSession(token: string) {\n        // Expire after 7 days\n        const ttl = 7 * 24 * 60 * 60;\n        await this.store.storeString('auth_token', token, ttl);\n    }\n    \n    async getSession(): Promise<string | null> {\n        if (await this.store.exists('auth_token')) {\n            return await this.store.fetchString('auth_token');\n        }\n        return null;\n    }\n    \n    async clearSession() {\n        await this.store.remove('auth_token');\n    }\n}\n```\n\n### Image Cache\n\n```typescript\nclass ImageCache {\n    private store = new PersistentStore('images', {\n        maxWeight: 50 * 1024 * 1024 // 50MB cache\n    });\n    \n    async cacheImage(url: string, imageData: ArrayBuffer) {\n        const weight = imageData.byteLength;\n        // Cache for 24 hours\n        await this.store.store(url, imageData, 86400, weight);\n    }\n    \n    async getImage(url: string): Promise<ArrayBuffer | null> {\n        if (await this.store.exists(url)) {\n            return await this.store.fetch(url);\n        }\n        return null;\n    }\n}\n```\n\n### Storing JSON\n\n```typescript\nasync function storeJSON(store: PersistentStore, key: string, data: any) {\n    const jsonString = JSON.stringify(data);\n    await store.storeString(key, jsonString);\n}\n\nasync function fetchJSON<T>(store: PersistentStore, key: string): Promise<T | null> {\n    try {\n        const jsonString = await store.fetchString(key);\n        return JSON.parse(jsonString);\n    } catch {\n        return null;\n    }\n}\n\n// Usage\nconst store = new PersistentStore('app_data');\nawait storeJSON(store, 'user', { name: 'Alice', age: 30 });\nconst user = await fetchJSON<{ name: string; age: number }>(store, 'user');\n```\n\n## Best Practices\n\n1. **Use encryption for sensitive data**: Always set `enableEncryption: true` for passwords, tokens, and personal information.\n\n2. **Choose appropriate TTL**: Set reasonable expiration times to avoid stale data and save storage space.\n\n3. **User-scoped by default**: Unless you explicitly need device-global storage, keep the default user-scoped behavior.\n\n4. **Batch writes for performance**: Keep the default batch write behavior unless you need guaranteed immediate persistence.\n\n5. **Handle missing keys**: Always wrap `fetch()` and `fetchString()` in try-catch blocks or check with `exists()` first.\n\n6. **Use weights for caches**: When using `maxWeight`, always provide meaningful weights to `store()` for proper LRU behavior.\n\n7. **Store name uniqueness**: Use unique store names to avoid conflicts between different parts of your application.\n\n## Error Handling\n\n```typescript\nasync function safeGetString(store: PersistentStore, key: string, defaultValue: string): Promise<string> {\n    try {\n        return await store.fetchString(key);\n    } catch (error) {\n        console.warn(`Failed to fetch ${key}:`, error);\n        return defaultValue;\n    }\n}\n\nasync function safeStore(store: PersistentStore, key: string, value: string): Promise<boolean> {\n    try {\n        await store.storeString(key, value);\n        return true;\n    } catch (error) {\n        console.error(`Failed to store ${key}:`, error);\n        return false;\n    }\n}\n```\n\n## Component Integration\n\n```typescript\nimport { Component } from 'valdi_core/src/Component';\nimport { PersistentStore } from 'persistence/src/PersistentStore';\n\nexport class SettingsComponent extends Component {\n    private store = new PersistentStore('settings');\n    \n    async onCreate() {\n        // Load saved settings\n        const theme = await this.loadTheme();\n        this.setState({ theme });\n    }\n    \n    private async loadTheme(): Promise<string> {\n        try {\n            return await this.store.fetchString('theme');\n        } catch {\n            return 'light'; // Default\n        }\n    }\n    \n    private async saveTheme(theme: string) {\n        await this.store.storeString('theme', theme);\n        this.setState({ theme });\n    }\n    \n    onRender() {\n        // Render settings UI...\n    }\n}\n```\n\n## Platform Support\n\nThe `persistence` module works on:\n- ✅ iOS (uses file system storage)\n- ✅ Android (uses file system storage)\n- ⚠️ Web (requires polyfill or alternative implementation)\n\n## See Also\n\n- [Core Utilities](./stdlib-coreutils.md) - LRU Cache and other utilities\n- [File System](./stdlib-filesystem.md) - Lower-level file operations\n- [Component Lifecycle](./core-component.md) - Loading data in components\n- [RxJS](./client-libraries-rxjs.md) - Reactive data patterns\n\n## Performance Considerations\n\n- **Batch writes are enabled by default** for better performance\n- **Encryption has overhead** - only use for sensitive data\n- **LRU caching helps** - use maxWeight to limit storage usage\n- **TTL prevents bloat** - set reasonable expiration times\n\n"
  },
  {
    "path": "docs/docs/third-party-dependencies.md",
    "content": "# Third Party dependencies\n\n## Introduction\n\nValdi modules can be published so that other users can leverage them. This process is currently a bit more complicated that we'd like, and we are working on making it better.\n\n## Consuming a third-party dependency\n\nAdding a dependency is usually done in three steps:\n- Make the dependency available within the Bazel Workspace.\n- Configure the dependency (optional, depends on whether the dependency requires additional configuration or dependencies)\n- Reference the dependency in one of your Valdi module so that you can make use of it.\n\nYou make a dependency available in Bazel by adding a `git_repository()` or `http_archive()` rule that points to the dependency within your `WORKSPACE` file. The library owner should provide instructions on what to add in your `WORKSPACE`. Here is an example on how it can look like:\n```python\n# Make valdi_widgets available through @valdi_widgets in Bazel build files\ngit_repository(\n    name = \"valdi_widgets\",\n    commit = \"465111c7ae19a6da5bd610139f873e730052b042\",\n    remote = \"git@github.com:Snapchat/Valdi_Widgets.git\",\n)\n```\nIf the dependency requires some additional configuration, you might need to add some additional instructions in your `WORKSPACE` file. Here is an example:\n```python\n# Load the setup function from our Valdi widgets repository\nload(\"@valdi_widgets//:setup.bzl\", \"setup_valdi_widgets\")\n# Invoke it\nsetup_valdi_widgets()\n```\n\nLastly, add a dependency in the Valdi module which wants to access that library:\n```python\nvaldi_module(\n    name = \"my_module\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]),\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_tsx\",\n        # We now depend on valdi_modules/widgets from the valdi_widgets repository\n        \"@valdi_widgets//valdi_modules/widgets\",\n    ]\n)\n```\nPlease note that the target (`@valdi_widgets//valdi_modules/widgets` in this example) must be a `valdi_module()`.\nYou can consume Android specific targets using `android_deps`, iOS specific targets using `ios_deps`, C++ targets using `native_deps`.\n\n> **See also:** [Valdi Module](./core-module.md) for complete BUILD.bazel configuration options.\n\nOnce the dependency is added in your `valdi_module()`, run `valdi projectsync` to fetch it and get autocompletion in VSCode.\n\n## Publishing a library\n\nValdi libraries made available to external developers should have the following:\n- A `WORKSPACE` copy-pastable content that developers can use to reference your library.\n- The list of Valdi module targets exported as part of your library. They should have `visibility = [\"//visibility:public\"]` so that the targets are visible.\n\nPlease use a workspace name that is unique and is unlikely to conflict with other workspaces.\nPublished libraries can be backed by native code, or be pure TypeScript code. If they are backed by native code, the native code should be built automatically when the module is included. Please follow the instructions on [Polyglot Modules](./native-polyglot.md) if you need further instructions about embedding native code in your module.\n\n## See Also\n\n- [Valdi Module](./core-module.md) - Module configuration and BUILD.bazel options\n- [Polyglot Modules](./native-polyglot.md) - Embedding native code in modules\n- [Valdi rules for Bazel](./workflow-bazel.md) - Bazel build system integration\n"
  },
  {
    "path": "docs/docs/workflow-appstore-release.md",
    "content": "# Releasing to iOS App Store and Google Play Store\n\n## Introduction\n\nThis document explains how to build a Valdi application and submit it to the iOS App Store and Google Play Store.\n\n## Prequisites\n\nYou should have a `valdi_application()` target that represents your Valdi application in a `BUILD.bazel`. For example:\n```py\nvaldi_application(\n    name = \"hello_world\",\n    ios_bundle_id = \"com.snap.valdi.helloworld\",\n    root_component_path = \"SampleApps@hello_world/src/HelloWorldApp\",\n    title = \"Valdi Hello World\",\n    deps = [\"//apps/helloworld/src/valdi/hello_world\"],\n    version = \"1.0.5\"\n)\n```\n\nFor iOS, you should have a distribution certificate and an App Store provisioning profile associated with the App ID you want to use.\n\nFor Android, TODO.\n\n## Submitting to iOS App Store\n\nIn your `valdi_application()` target, specify the production provisioning profile using the `ios_provisioning_profile` attribute, and the app icons that your application should use using the `ios_app_icons` attribute. You should also specify if your app targets iPhone, iPad or both using the `ios_families` attribute. Lastly, you should specify the `ios_bundle_id` that your app will use, which should match the bundle id of your provisioning profile.\n\n```py\nvaldi_application(\n    name = \"hello_world\",\n    ios_bundle_id = \"com.snap.valdi.helloworld\",\n    ios_provisioning_profile = \"prod.mobileprovision\",\n    ios_app_icons = glob([\"app_icons/ios/**\"]),\n    ios_families = [\"iphone\"], # Can also be \"ipad\"\n)\n```\nIn the example above, it expects a `prod.mobileprovision` file to be in the same directory where the `BUILD.bazel` file containing the `valdi_application()` lives. The `ios_app_icons` must references an `xcassets` folder containing a `.appiconset` folder with all the icons in it. For example:\n```sh\nls app_icons/ios/Assets.xcassets/AppIcon.appiconset\n1024.png\t120.png\t\t152.png\t\t167.png\t\t180.png\t\t20.png\t\t29.png\t\t40.png\t\t58.png\t\t60.png\t\t80.png\t\t87.png\t\tContents.json\n```\n\nBuild your app in release mode using the `valdi package` command:\n```sh\nvaldi package ios --build_config release --output_path hello_world.ipa\n```\n\nOnce the build is done, you can upload the .ipa file to the App Store. You can follow the instructions by [Apple here](https://developer.apple.com/help/app-store-connect/manage-builds/upload-builds/), but please note that since we are building the application without Xcode, we will have to use a different tool than Xcode for uploading the ipa. The [Transporter app](https://apps.apple.com/us/app/transporter/id1450874784?mt=12), which is an official application from Apple, works well. You can drag and drop the ipa into Transporter, upload it, and you're done!\n\n## Submitting to Google Play Store\n\nIn your `valdi_application()` target, specify the list of Android resource files to include in your application using the `android_resource_files` attribute. These should contain the app icons, and potentially a theme for the main activity so that a splash background is shown when the application starts. You can then specify which app icon or activity theme to use using the `android_app_icon_name`, `android_app_round_icon_name` and `android_activity_theme_name` attributes.\n\n```py\nvaldi_application(\n    name = \"hello_world\",\n    android_app_icon_name = \"app_icon\",\n    android_resource_files = glob([\"app_assets/android/**\"]),\n    android_activity_theme_name = \"Theme.MyApp.Launch\",\n)\n```\n\nHere is the contents of `app_assets/android` for this example:\n```sh\nls -R app_assets/android\ndrawable-nodpi\tmipmap-hdpi\tmipmap-mdpi\tmipmap-xhdpi\tmipmap-xxhdpi\tmipmap-xxxhdpi\tvalues\n\napp_assets/android/drawable-nodpi:\nsplash.png\n\napp_assets/android/mipmap-hdpi:\napp_icon.png\n\napp_assets/android/mipmap-mdpi:\napp_icon.png\n\napp_assets/android/mipmap-xhdpi:\napp_icon.png\n\napp_assets/android/mipmap-xxhdpi:\napp_icon.png\n\napp_assets/android/mipmap-xxxhdpi:\napp_icon.png\n\napp_assets/android/values:\ncolors.xml\tthemes.xml\n```\n\nThe `valdi_application()` rule will generate the `AndroidManifest.xml` file depending on the attributes that arae being passed in. If you want complete control over the Android manifest, you can use the `android_app_manifest` attribute and pass a target or a file name that contains the manifest. Your provided manifest should set as its main activity `<package>.StartActivity`, where package is the value passed from the `android_package` attribute (which defaults to `com.snap.valdi` is not passed). If your package is `com.company.product`, then main activity should be `com.company.product.StartActivty`.\n\nOnce you have setup your resources, build your app in release mode using the `valdi package` command:\n```sh\nvaldi package android --build_config release --output_path hello_world.apk\n```\n\nIf the `valdi` CLI asks you to choose between an unsigned and a signed apk, choose the unsigned one.\nYou can then submit the `apk` to the Google Play Store."
  },
  {
    "path": "docs/docs/workflow-bazel.md",
    "content": "# Valdi rules for Bazel\n\nEach [valdi module](../../valdi_modules/src/valdi) contains a `BUILD.bazel` file which has a single call to `valdi_module` macros. The macro setups a few targets and aliases to build the module from source using the Valdi Toolchain.\n\nThe list of targets created by the `valdi_module` macro includes:\n\n* `module_name:module_name` target which builds just the `.valdimodule` file. It is the default target and can be referenced as `module_name` for example `//src/valdi_modules/src/valdi/jasmine`.\n* `module_name:module_name_kt` target which builds the `android_library` and packages the Valdi generated Kotlin code, if any. It depends on the Valdi module target above and adds the `.valdimodule` and other resources to the `data` attribute.\n* `module_name:module_name_objc` target which builds the `objc_library` and packages the Valdi generated Objective-C code, if any. It depends on the Valdi module target above and adds the `.valdimodule` and other resources to the `data` attribute.\n* `module_name:module_name_objc_api` target which builds the `objc_library` and wraps the generated Objective-C API code, if any. It also depends on the `module_name_objc` target above.\n* `module_name:{ModuleName}` an alias pointing at `module_name:module_name_objc` to keep the compatibility with iOS\n* `module_name:{ModuleName}Types` an alias pointing at `module_name:module_name_objc_api` to keep the compatibility with iOS\n\n## Building\n\nTo build a single module using the default, macOS toolchain:\n\n```sh\nbazel build //src/valdi_modules/src/valdi/jasmine\n```\n\n### Android\n\nTo build the Android target:\n\n```sh\nbazel build //src/valdi_modules/src/valdi/jasmine --platforms=@snap_platforms//os:android_arm64\n```\n\n### iOS\n\nTo build the iOS target:\n```sh\nbazel build //src/valdi_modules/src/valdi/jasmine --platforms=//bzl/platforms:ios_x64\n```\n\n## Maintaining `BUILD.bazel` files\n\nTo ease the burden of writing and maintainting `BUILD.bazel` Valdi provides a script to automatically generate/update/format `BUILD.bazel` files based on `module.yaml` content. In addition to that, the CI infrastructure includes a pre-cool hook to validate `BUILD.bazel` files.\n\nTo add a new dependency:\n\n1. Update `module.yaml`\n2. Run the script:\n\n```sh\n./scripts/regenerate_valdi_modules_build_bazel_files.sh\n```\n\n## Testing\n\nYou can run your tests using `bazel test` directly. See documentation about it here: [Testing](./workflow-testing.md).\n\n## Linting\n\nOnce implemented, users will be able to run linting for a single module using Bazel.\n\n## Rebuilding the compiler and companion\n\nBy default, Bazel uses the **prebuilt compiler** and builds the **companion from source** (the companion is the JS/TS app in `compiler/companion`). To use your own builds so they are not overwritten by prebuilts:\n\n### Using a locally built compiler\n\n\n1. Build the Valdi compiler and place the binary where the toolchain can find it:\n   ```sh\n   compiler/compiler/scripts/update_compiler.sh -s -o compiler/compiler/out\n   ```\n   This produces `compiler/compiler/out/macos/valdi_compiler` (or `out/linux/valdi_compiler` on Linux). The `-s` flag skips analytics upload. The script works in both the mirrored public repo and the mobile monorepo.\n\n2. Build Valdi modules with the local compiler:\n   ```sh\n   bazel build //src/valdi_modules/src/valdi/jasmine --//bzl/valdi:use_local_compiler=true\n   ```\n\nThe `out/` directory is gitignored so your local binary is never committed.\n\n> [!TIP]\n> To confirm the local binary is being picked up, check the Bazel worker log after the first build:\n> ```sh\n> cat \"$(ls ~/.cache/bazel/*/bazel-workers/worker-*-ValdiCompile.log 2>/dev/null | head -1)\"\n> ```\n> The first line should read `[local-compiler] valdi compiler (local build) starting` (or whatever marker you added). The worker log path is also printed by Bazel when `--worker_verbose` is passed.\n\n### Using a locally built companion\n\nThe toolchain already uses the **source-built companion** by default (`use_prebuilt_companion` is false), so the companion is built from `compiler/companion` (e.g. webpack output). To avoid Bazel overwriting your npm-built companion output:\n\n1. Build the companion in dev mode (writes to `dist_dev/` instead of `dist/`):\n   ```sh\n   cd compiler/companion && npm run build-dev\n   ```\n\n2. Build or run Valdi with the dev-mode companion:\n   ```sh\n   bazel build //src/valdi_modules/src/valdi/jasmine --//compiler/companion:dev_mode=true\n   ```\n\nBazel will use `dist_dev/bundle.js` and will not overwrite your `dist/` folder.\n\n## Known issues and limitations\n\n* Updating proto config doesn't trigger a valdi module rebuild\n"
  },
  {
    "path": "docs/docs/workflow-cli-application.md",
    "content": "# Building a CLI application\n\nWith Valdi, you can build CLI applications using TypeScript, running under the Valdi runtime, into a single binary. The built binary is self contained and will have all the dependencies required for the CLI application to run, including any native dependencies that you might bring into the build.\n\n## Getting started\n\nYou can define a CLI application using the `valdi_cli_application()` rule. The rule takes a list of Valdi modules dependencies to include in the build, and `script_path`, which is the path to the script that should be evaluated as the entry point to the application. The script path is in the format `<module_name>/<path_to_file_without_extension>`, for example `my_module/src/my_file`.\n\nHere is an example of a `BUILD.bazel` of a Valdi CLI application:\n```python\nload(\"//bzl/valdi:valdi_cli_application.bzl\", \"valdi_cli_application\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"cli_example\",\n    srcs = glob([\n        \"**/*.ts\",\n        \"**/*.tsx\",\n    ]),\n    deps = [],\n)\n\nvaldi_cli_application(\n    name = \"cli_example_app\",\n    script_path = \"cli_example/index\",\n    deps = [\":cli_example\"],\n)\n```\n\nYou can then run your application using `valdi install cli`.\nYou can package your application into a single binary using `valdi package cli`."
  },
  {
    "path": "docs/docs/workflow-disk.md",
    "content": "# Disk Management\n\n<!--TODO: Validate the build artificat paths relative to a boot strapped Valdi project -->\n\nBazel stores intermediate/final build artifacts locally and may not always clean them up properly. As a result, you may occasionally find it filling up your local disk. If this occurs, the below steps can help reclaim some disk space.\n\nYou may also choose to install a tool like `ncdu` to clean up your local disk, deleting IDE caches and older versions.\n\n## Cleanup Steps\n\n#### Bazel & Valdi\n\nIn your top level project folder (containing a `WORKSPACE` file):\n\n```bash\ncd path/to/your/project\nwatchman shutdown-server;\nbazel clean --expunge;\nbazel shutdown;\nrm -rf ../.cache/;\n```\n\n#### Valdi Modules\n\nWe store additional build caches that are module specific, and are worth clearing for any local hot reloader or valdi module build issues. You can do that via the following commands:\n\n```bash\ncd path/to/your/project\nrm -rf ./.valdi_build\n```\n"
  },
  {
    "path": "docs/docs/workflow-external-build-system.md",
    "content": "# CocoaPods, SwiftPM, Xcode and Gradle integration\n\n## Introduction\n\nValdi can be integrated inside a separate build system. This document covers how to integrate a set of Valdi modules into CocoaPods, SwiftPM, Xcode and Gradle. The main trick behind these integrations is that you can build Valdi modules into a shared iOS and Android framework, that can be added into an iOS and Android project. The built framework is self contained: it has the compiled Valdi modules including compiled TS sources, as well as the Valdi runtime itself.\n\n## Prequisites\n\nTo export a set of Valdi modules, you need to define a `valdi_exported_library()` target that depends on all of the Valdi modules you wish to include in this library.\n\n```python\nload(\"@valdi//bzl/valdi:valdi_exported_library.bzl\", \"valdi_exported_library\")\n\nvaldi_exported_library(\n    name = \"hello_world_export\",\n    ios_bundle_id = \"com.snap.hello_world.lib\",\n    ios_bundle_name = \"HelloWorld\",\n    deps = [\"//apps/helloworld/src/valdi/hello_world\"],\n)\n\n```\n\n`deps` can contain a single Valdi module, or multiple.\n\n## iOS\n\nYou can export your project as a xcframework for iOS using the `valdi export ios` command:\n\n```sh\nvaldi export ios --output_path my_framework.xcframework\n```\n\nThis will build your Valdi modules defined from the `valdi_exported_library()` target, as well as the Valdi runtime, and package it into a universal framework that works for iOS simulator and real devices.\nNote that by default, the library is compiled in debug module. You use the `--build_config release` to build in release mode:\n\n```sh\nvaldi export ios --build_config release --output_path my_framework.xcframework\n```\n\n### Xcode\n\nTo use your `.xcframework` in your Xcode project, just drag and drop the built `.xcframework` file into Xcode. You should be able to import it and use the generated classes from it.\n\n- The **module name** you `import` is the **`ios_bundle_name`** of your `valdi_exported_library()` (e.g. `HelloWorld`).\n- The **root view class** is the Valdi module’s **`ios_module_name`** (or class prefix) plus the root component name (e.g. `SCCHelloWorldApp` for module name `SCCHelloWorld` and root component `App`). If your module does not set `ios_module_name`, the class is **`<module_name><ComponentName>`** where `module_name` is the Valdi module's `name` in BUILD (snake_case, e.g. `test_test` → `test_testApp`). Set your view controller’s view to this class in `loadView()`.\n\n```swift\nimport UIKit\nimport HelloWorld\n\nclass ViewController: UIViewController {\n\n    private var runtimeManager: SCValdiRuntimeManager?\n\n    override func loadView() {\n        // For best performance, your app should maintain a singleton\n        // of the Valdi runtime manager.\n        let runtimeManager = SCValdiRuntimeManager()\n        self.runtimeManager = runtimeManager\n\n        self.view = SCCHelloWorldApp(viewModel: nil, componentContext: nil, runtime: runtimeManager.mainRuntime)\n    }\n}\n```\n\n**Troubleshooting (iOS):** If the host app fails to build with **\"SCValdiDrawingModule.h file not found\"**, the exported xcframework may omit this header. Add a stub header in both slices of your `.xcframework` (e.g. `YourName.xcframework/ios-arm64/YourBundleName.framework/Headers/` and `.../ios-arm64_x86_64-simulator/.../Headers/`): create `SCValdiDrawingModule.h` with:\n\n```objc\n#import <Foundation/Foundation.h>\nNS_ASSUME_NONNULL_BEGIN\n@protocol SCValdiDrawingModule <NSObject>\n@end\nNS_ASSUME_NONNULL_END\n```\n\n### SwiftPM\n\nTo use your `.xcframework` in SwiftPM, you can define a `Package.swift` that exposes your `.xcframework`. Here is an example of such a file:\n\n```swift\n// swift-tools-version:5.6\n\nimport PackageDescription\n\nlet package = Package(\n    name: \"HelloWorld\",\n    platforms: [\n        .iOS(.v12)\n    ],\n    products: [\n        .library(name: \"HelloWorld\", targets: [\"HelloWorldFramework\"])\n    ],\n    targets: [\n        .binaryTarget(\n            name: \"HelloWorldFramework\",\n            // This is relative to the Package.swift file. This should point to the output from\n            // \"valdi export ios\"\n            path: \"HelloWorldFramework.xcframework\"\n        ),\n    ]\n)\n```\n\nThis file can be added as a local dependency using `File` -> `Add Package Dependencies` -> `Add Local`.\nIf you have a `Project.swift` file representing your app, you can add a dependency to the framework by adding the path to the `Package.swift` file in the `packages` array, and add a dependency to the package:\n\n```swift\nlet project = Project(\n    name: \"MyApp\",\n    packages: [\n        .package(path: \"path/to/HelloWorld\"),\n    ],\n    targets: [\n        .target(\n            dependencies: [\n                .package(product: \"HelloWorld\"),\n            ],\n        ),\n    ]\n)\n```\n\nYou can use `.xcframework` directly and avoid having to create a `Package.swift` file entirely:\n\n```swift\nlet project = Project(\n    name: \"MyApp\",\n    packages: [\n    ],\n    targets: [\n        .target(\n            dependencies: [\n                .xcframework(path: \"path/to/HelloWorld.xcframework\"),\n            ],\n        ),\n    ]\n)\n```\n\n### CocoaPods\n\nCocoaPods does not have great support for local `.xcframework` files. We recommend you add your `.xcframework` into Xcode directly (see Xcode instructions), which will edit the `.xcodeproj` file and leave the CocoaPods's managed `.xcworkspace` alone. If you really want to expose the `.xcframework` as a Pod, please look at this [CocoaPods GitHub thread](https://github.com/CocoaPods/CocoaPods/issues/10288). Some people there have reported having some successes with getting it work.\n\n## Android\n\nYou can export your project as a `aar` library for Android using the `valdi export android` command:\n\n```sh\nvaldi export android --output_path my_library.aar\n```\n\nThis will build your Valdi modules defined from the `valdi_exported_library()` target, as well as the Valdi runtime, and package it into an Android library that works for x86_64, arm64 and armv7 architectures.\nNote that by default, the library is compiled in debug module. You use the `--build_config release` to build in release mode:\n\n```sh\nvaldi export android --build_config release --output_path my_library.aar\n```\n\n### Gradle\n\nYou can add a dependency to your built `.aar` using the `implementation files()` in the `dependencies` section as follow:\n\n```groovy\ndependencies {\n    implementation files('libs/my_library.aar')\n    // Rest of your deps...\n}\n```\n\nThis assumes that the output of `valdi export android` is set to `libs/my_library.aar`, relative to the `build.gradle` file.\nPlease note that the built `.aar` file might embed some dependencies that you are already using in your project. If you are seeing build errors with duplicated classes between your project and what is inside the `.aar`, you can use the `android_excluded_class_path_patterns` attribute to exclude some specific class paths.\nFor example if your project already uses AndroidX lifecycle, you might want to it strip out:\n```python\nvaldi_exported_library(\n    name = \"hello_world_export\",\n    android_excluded_class_path_patterns = [\n        'androidx/lifecycle/.*',\n    ],\n)\n```\n`valdi_exported_library()` by default strips out Kotlin runtime files, so it expects that the project importing the `.aar` already bundles Kotlin.\n\nYou should now be able to import the Valdi runtime classes and instantiate your component. Generated view classes (your root component and other exported components) use the package **`com.snap.modules.<module_name>`**, not `com.snap.valdi.modules`:\n\n```kotlin\nimport com.snap.valdi.ValdiRuntimeManager\nimport com.snap.valdi.support.SupportValdiRuntimeManager\nimport com.snap.modules.hello_world.App\n\nclass MainActivity : Activity() {\n    var runtimeManager: ValdiRuntimeManager? = null\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        // This needs to execute at least once\n        // The name of the library will match the name of\n        // your valdi_exported_library() target.\n        System.loadLibrary(\"hello_world_export\")\n\n        // For best performance, your app should maintain a singleton\n        // of the Valdi runtime manager.\n        val runtimeManager = SupportValdiRuntimeManager.createWithSupportLibs(this.applicationContext)\n        this.runtimeManager = runtimeManager\n\n        setContentView(App.create(runtimeManager.mainRuntime))\n    }\n}\n```\n"
  },
  {
    "path": "docs/docs/workflow-hermes-debugger.md",
    "content": "# Hermes Debugger\n\n![Debugging demo](./assets/debugging-hermes/debug-demo.gif)\n\nValdi supports a new debugging environment to provide developers working with Valdi a stable, reliable and consistent debugging experience that can be used across the different platforms that Valdi supports. Live debugging within VSCode should be enabled, as long as Hermes is enabled, your application is running in debug mode and the hot reloader is running.\n\nThe debugger supports:\n- Inspect and modify variables\n- Single Step / Step In / Step Out\n- Set Breakpoints\n- Pause on Exceptions\n- View current call stack\n- Debug JS Worker Threads\n- Debug console to Run commands in a paused JS Context\n\n## Enabling Hermes\n\nThe Hermes engine integration is compiled in on debug builds for iOS and Android, and on all build types for macOS. Projects generated through `valdi bootstrap` will use Hermes by default whenever available. For other projects, you can set `build --valdi_js_engine=hermes` in the `.bazelrc` file.\n\n## Attaching the Debugger\n\nWhen the hot reloader is connected to an instance of the app, you are now able to attach a debugging session to the app right within VSCode. Select \"Valdi attach\" configuration and click the green triangle, or press F5:\n\n![Screenshot of attaching the debugger in VSCode](./assets/debugging-hermes/debug-attach.png)\n\nThe `Valdi attach` option is configured automatically after running `valdi projectsync`.\n\nThe bottom status bar in VSCode will turn orange-ish when the debugger is attached successfully:\n\n![Screenshot of VSCode showing Hermes attached to the debugger](./assets/debugging-hermes/debug-bottom-bar.png)\n\nPlease note that the hot reloader needs to be started for the debugger to work.\n\n## Breakpoints\n\nOnce attached, you can add breakpoints in the editor gutter:\n\n!['Screenshot of VSCode setting a breakpoint in a component'](./assets/debugging-hermes/breakpoints.png)\n\nVSCode will show that the breakpoint was successfully set by displaying a filled red dot on the left side of the editor.\n\nWhen execution is paused on a breakpoint you should be able to inspect the state of any expressions available in the current scope by mousing over them:\n\n!['Screenshot of VSCode hitting a breakpoint'](./assets/debugging-hermes/breakpoints-topdown.png)\n\nFor breakpoints to work properly, the VSCode debugger needs a source mapping information that gets generated through `valdi projectsync`. You will need to re-run `valdi projectsync` when new modules are added so that the debugger is able to map the files on disk to the files that run within the engine on the device.\n\n## Debug Console\n\nWhen execution is paused on a breakpoint, you use the Debug Console to evaluate JS expressions and statements directly:\n\n!['Screenshot of the VSCode debug console'](./assets/debugging-hermes/console.png)\n\n## Pause on Exceptions\n\nYou can also tell the runtime to pause execution on caught and uncaught errors by toggling the checkboxes in the bottom left corner:\n\n!['Screesnhot of VSCode breakpoint settings for breaking on exceptions'](./assets/debugging-hermes/exceptions.png)\n\nThis is what that would look like once an exception is caught:\n\n!['Screenshot of VSCode breaking on an exception'](./assets/debugging-hermes/caught-exception.png)\n\n## Profiling and memory heap dumps\n\nYou can gather profiling data and memory heap dumps when the Hermes engine is enabled. See [VSCode documentation](https://code.visualstudio.com/docs/nodejs/profiling) for more information about how to use these features.\n\n## Troubleshooting\n\nHere are some things you can try if your breakpoints aren't working or you are not able to attach:\n- Make sure that the Valdi hot reloader is running, is connected to your device, and is configured to hot reload targets that you are trying to debug.\n- Run `valdi projectsync` to get an updated `.vscode/launch.json` file, which contains the Valdi attach information necessary for the VSCode JS debugger.\n- Make sure that the Hermes engine is enabled. You should have `build --valdi_js_engine=hermes` in the `.bazelrc` file. You can only use the debugger on debug builds."
  },
  {
    "path": "docs/docs/workflow-inspector.md",
    "content": "# Valdi Inspector\n\nValdi Inspector is a desktop application, written in Valdi itself, which can be used to help debugging a Valdi VirtualNode tree.\n\n> [!Note]\n> Valdi provides a suite of development tools to assist engineers, including a live TypeScript debugger integrated into VSCode, the Valdi Inspector for UI debugging, and a logs viewer for application logs. These tools work in tandem with the hot reloader to provide a responsive development experience.\n\n![Screenshot of Valdi Inspector](./assets/advanced-inspector/Inspector.png)\n\n## Features\n* Inspect the node tree remotely\n  * Can highlight components, elements, and views independently\n* Display accessibilityIds\n  * A toggle lets you display accessibilityId values right next to the views that have it set on them. Should make adding karma tests much easier\n* Inspect element attributes\n  * Selecting an element will display the currently-applied attribute values\n* Preview Valdi Components\n  * The app can display a **preview of any Component, without requiring you to build iOS/android**\n\n## How do I use this?\n<!-- TODO: do these ./scripts work as-is for Open Source? -->\n* Check out fresh client/master\n* Run the hot reloader: \n    ```\n    valdi hotreload\n    ```\n* To just launch the inspector: \n    ```\n    ./scripts/start_inspector.sh\n    ```\n    You should now be able to inspect other instances of Valdi UI that are connected to the hot reloader\n* To preview a Component: \n    ```\n    ./scripts/preview_component.sh --root_component ValdiCatalog@valdi_catalog/src/ValdiCatalog\n    ```\n    You should now be able see and interact with the component from the provided component path in a window on your desktop\n\n## Brief implementation details\n\n[the implementation]: #todo-implementation-link\n\n* Standalone View tree implementation using Skia.\n* Inspector app is a small AppKit+Metal shell exposing the Skia implementation\n* Inspector UI itself is written in Valdi!\n    * Take a peek at [the implementation][]\n    * Feel free to play around with the code if you want to improve the tool. You can hot reload the inspector the same way you can hot reload your components on iOS and Android.\n\n### Hot Reloader Communication\n\nThe hot reloader establishes a TCP connection between the device/simulator and the developer's machine running the `valdi hotreload` daemon. This bidirectional communication enables:\n- **Live code reloading**: The runtime detects module changes and triggers re-renders via `RootComponentsManager`\n- **Inspector debugging**: Remote tree inspection and attribute viewing through `DaemonClientManager`\n- **File transfer**: Reading/writing files on the host machine using `DaemonClientFileManager` (useful for debug data export/import)\n- **Custom messages**: Development tools can send custom requests between device and host\n\n> **Note**: The connection uses a native TCP implementation with a custom packet protocol (not the `TCPSocket` TypeScript module). A low-level `TCPSocket` module exists for specialized internal tooling and is only available in dev/gold builds.\n\n## Limitations\n* Currently only supported on macOS\n    * Implementing the Linux shell around Skia will take some work (sorry Robert)\n* Inaccurate attribute inspection from CSS documents on .vue components\n* Of course, since the Component preview runs outside of iOS/android, any custom native view will not actually render anything\n\n\n\n\n"
  },
  {
    "path": "docs/docs/workflow-style-guide.md",
    "content": "# Valdi Style Guide\n\n### Overview\n\n[ESLint]: https://eslint.org\n[Prettier]: https://prettier.io\n[valdi-eslint-rules]: ../../../../src/valdi_modules/scripts/style-guide/ESLintRules.js\n[eslint-rc]: ../../../../src/valdi_modules/.eslintrc.js\n\nIn this section we would like to share the details about why and how we can use `Valdi Style Guide`.\n`Valdi Style Guide` helps to achieve the following:\n\n- Improve code quality, making code more consistent, avoiding bugs, errors, and suspicious constructs\n- Improve TypeScript learning curve\n- API depreciation\n\n`Valdi Style Guide` is a set of two main tools - language linter and formatting tool.\nWe use for that the most popular and industry approved libraries:\n\n- for code linter we use [ESLint][]\n- for formatting we use [Prettier][]\n\n[Prettier][] allows us to have standard, simple, and opinionated code formatting\nrules. All code can be formatted via IDE or CLI so you can easily integrate this step into your development workflow.\n\n[ESLint][] allows us to use the community-recomended set of JavaScript and TypeScript rules.\nof rules. Also, we introduced more specific rules for our codebase that can be helpful for us. The up-to-date list of rules you can find\n[here][valdi-eslint-rules].\n\nWe have less strict rules for existing codebase and for new modules we use more strict rules.\nEventually we have a plan to help and migrate all Valdi modules to one strict set of rules.\n\n[Prettier][] and [ESLint][] work perfectly with VSCode or WebStorm.\n\nIf you need some modifications you can read more about vscode settings [here](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)\nand [here](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint), and about WebStorm settings\n[here](https://www.jetbrains.com/help/webstorm/eslint.html) and [here](https://www.jetbrains.com/help/webstorm/prettier.html)\n\n#### Valdi Style Guide CLI commands\n\nIf you don't like use the style guide configuration, the Valdi CLI allows you to run all helpful style guide commands. Below are a set of available commands commands that provides a quick way of checking/fixing your code according to our defined standards:\n\n```bash\n# Uses eslint and prettier to check the list of files for errors.\nvaldi lint check [files...]\n\n# Same as check but also attempts to automatically fix errors.\nvaldi lint format [files...]\n```\n\nUnder the hood, the CLI tool uses `prettier` and `eslint` to check and format files. Most if not all formatting rules can be fixed automatically via prettier, whereas\n[ESLint][] will have more cases that will have to be resolved manually.\n\n#### How to fix your linter error\n\nIf you encounter a linter error that can not be fixed automatically. The next step is to google this error or go to the [ESLint][] or [ESLint TypeScript](https://typescript-eslint.io) and follow the steps to resolve it.\n\nFor example, you can observe error `explicit-function-return-type`, then you can go to [website](https://typescript-eslint.io/rules/explicit-function-return-type) to see the examples of usage,\ndetails about the error, and how to fix it.\n\n#### Add specific rules per module\n\nIt is possible to define a specific rules on a per module basis. The official documentation for defining custom rules can be found at [ESLint documentation](https://eslint.org/docs/user-guide/configuring/configuration-files#how-do-overrides-work).\n\nThis [`.eslintrc.js`][eslint-rc] is an existing example of using a custom configuration with ESLint.\n"
  },
  {
    "path": "docs/docs/workflow-testing.md",
    "content": "# Testing\n\n## TypeScript testing\n\nValdi provides a standalone runtime that can execute Valdi code without requiring integration with a host iOS/Android app. Adding new tests is easy and lightweight; they run very fast and can use the hot reloader for rapid iteration. The runtime leverages the [jasmine](https://jasmine.github.io/) testing framework which is probably already familiar to you.\n\n> [!Note]\n> In **Standalone Mode**, Valdi can run on Linux and macOS without any UI, similar to Node.js. This mode is used for running unit tests and scripts, and it evaluates code from `.valdimodule` archives produced by the Valdi compiler.\n\n### How to add new tests?\n\nYou can add .ts/.tsx files to the `test/` directory of your Valdi module. All .ts/.tsx files within the `test/` directory are included when running tests. The convention is to have test files be named `FileToTest.spec.ts`.\nIf you'd like to reference some code from a different module that you don't want to be a dependency of your Valdi module, create a new Valdi module just for your tests.\n\nIf using the [jasmine](https://jasmine.github.io/) framework, ensure you import it in your test file `import 'jasmine/src/jasmine';`.\n\n### How do I run my tests?\n\nYou can use the `bazel test` Bazel command to test your module. It will compile your files and execute all the tests that were found. All the Valdi modules have an implicit Bazel target named `test`.\n\n```sh\nbazel test //src/valdi_modules/src/valdi/your_module_name:test\n```\n\n### How to iterate on my tests using the hot reloader?\n\nYou can run your unit tests with both the VSCode debugger and the hot reloader. This enables you to iterate on your tests as well as debug them. To enable the debugger and hot reloader service, you need to pass the `--//src/valdi_modules/bzl:hot_reload_enabled` flag to the Bazel invocation. Tests running with the hot reloader should be run using `bazel run` instead of `bazel test`, so that you can get your logs in the console.\n\n- Start the hot reloader (using `valdi hotreload`)\n- Run `bazel run //src/valdi_modules/src/valdi/your_module_name:test --//src/valdi_modules/bzl:hot_reload_enabled` to run the standalone test runtime in hot reload mode\n\nNow, whenever you edit the test files in `your_module_name/test` and hit save, the hot reloader will compile and send\nthe updated tests to the standalone runtime, which will then re-run the tests and show you the results.\n\n### How do I see/get code coverage data?\n\nRefer to `./coverage/lcov-report/index.html`.\n\nIn addition to that, code coverage data can be generated using `./scripts/test_module_hotreload_with_code_coverage.sh`\n\n### Example jasmine test\n\nHere's an example test file that tests the `Style` object implementation: [valdi_test/test/Style.spec.ts](https://github.com/Snapchat/Valdi/blob/main/src/valdi_modules/src/valdi/valdi_test/test/Style.spec.ts).\n\n`describe` is used to group test cases. You can add any variables, `beforeEach`, and `beforeAll` calls in this block.\n`it` signifies a specific test case. Write your test case code in this block.\n`expect` matchers are used to assert expected state at the end of the test case.\n\nYou can learn more about jasmine at https://jasmine.github.io/\n\n### How to test Component logic?\n\nWe provide test utility APIs to help you drive your Component in your test cases. If you use the `valdiIt` function instead `it` to specify your test case, you'll get access to an `IComponentTestDriver` instance. Here's an example of a test that uses the driver to render a component and verify the resulting virtual node tree:\n\nFrom [valdi_test/test/ComponentTestExample.tsx](../../src/valdi_modules/src/valdi/valdi_test/test/ComponentTestExample.tsx#L7):\n\n```tsx\nvaldiIt('can create component', async driver => {\n  class MyComponent extends Component {}\n\n  const nodes = driver.render(() => {\n    <MyComponent />;\n  });\n\n  expect(nodes.length).toBe(1);\n\n  expect(nodes[0].component instanceof MyComponent).toBeTruthy();\n});\n```\n\nFurther down you can see an example of a test that uses the driver to lay out some elements and verifies the resulting frames:\n\n```tsx\nvaldiIt('can perform layout', async driver => {\n  const rootRef = new ElementRef();\n  const childRef = new ElementRef();\n\n  driver.render(() => {\n    <layout ref={rootRef} width='100%' height='100%' justifyContent='center' alignItems='center'>\n      <layout ref={childRef} width={25} height={25} />\n    </layout>;\n  });\n\n  await driver.performLayout({ width: 100, height: 100 });\n\n  expect(rootRef.single()!.frame).toEqual({\n    x: 0,\n    y: 0,\n    width: 100,\n    height: 100,\n  });\n  expect(childRef.single()!.frame).toEqual({\n    x: 37.5,\n    y: 37.5,\n    width: 25,\n    height: 25,\n  });\n});\n```\n\n### UI Tests - How to identify views in tests?\n\nOn the TypeScript side you can configure the `accessibiltyId` attribute on any view/label/image element. On iOS this `accessibiltyId` value is applied to the underlying `UIView` and can be retrieved using the usual XCTest APIs. On Android Valdi provides view matcher utilities for finding a reference to a View with a particular accessibilty id.\n\n```xml\n<view accessibilityId={this.state.name} />;\n```\n\nIds can also be provided by writing the accessibility ids into an `ids.yaml` file. The ids files will be generated into TypeScript, Kotlin, Swift and Objective-C. Make sure to update [module.yaml](./core-module.md#moduleyaml) to include the new file.\n\nFor example, given the following `ids.yaml`:\n\n```yaml:\nids:\n  open_page:\n    description: Button in the starting demo app page to open sub pages\n```\n\nTypeScript definitions:\n\n```ts\nexport class Ids {\n  /**\n   * Button in the starting demo app page to open sub pages\n   */\n  static openPage(): string;\n}\n```\n\nAndroid resource file:\n\n```xml\n<resources>\n  <item type=\"id\" name=\"yolo:open_page\"/>\n</resources>\n```\n\nObjective-C header and implementation:\n\n```objective-c\n#import <Foundation/Foundation.h>\n\n/**\n* Button in the starting demo app page to open sub pages\n*/\nextern NSString *SCValdiIdYoloOpenPage();\n```\n\n#### iOS example\n\n<!-- TODO: example for iOS -->\n\niOS [accessibiltyId example](#todo-example-ios)\n\n#### Android example\n\n<!-- TODO: example for Android -->\n\n[`withAccessibilityId` example](#todo-example-android)\n\nThe id itself can be imported using:\n\n```java\nimport com.snap.valdi.modules.<your_module>.R\n```\n\n<!-- TODO: espresso matchers in open source -->\n\n> [!Note]\n> Use the Espresso matchers we've provided for working with Valdi _elements_ instead of Android _views_. They're implemented in [`//platform/valdi/test-support`](#todo-espresso-matchers)\n\nFor automator performance tests on Android, only `accessibilityId` values that are set through an `ids.yaml` will work\n\n### How to get the Valdi dependencies for tests?\n\nIf you're writing a test that requires you to get a reference to a working `SCValdiRuntime`/`ValdiRuntime` to create a view:\n\n- on iOS you can use the `SCValdiServicesForTests()` test utility function available in the `//Features/Valdi/Utilities/SCValdiTestUtilities:SCValdiTestUtilities` module.\n- on Android you can use the [`ValdiViewTestRule`](#todo-android-valdiviewtestrule) test utility function\n"
  },
  {
    "path": "docs/setup/linux_setup.md",
    "content": "# Linux Setup Reference Guide\n\n> **Get the CLI from npm:** `npm install -g @snap/valdi`. Then run `valdi dev_setup` for automated setup. This guide is a reference for manual installation or troubleshooting only.\n\n## About\n\nThis guide documents the dependencies Valdi needs on Linux and how to install them manually. For the quickest setup, use [`valdi dev_setup`](../INSTALL.md) which automates all of these steps.\n\nThis guide assumes you're using the default shell (bash). Setup is possible for other shells, but you'll need to adapt the configuration file paths.\n\n## Setup git-lfs deb\n\n```\ncurl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash\n```\n\n## apt-get install dependencies\n\nOn Debian/Ubuntu, install the same dependencies that `valdi dev_setup` would use:\n\n```\napt-get install npm openjdk-17-jdk git-lfs watchman adb libfontconfig1-dev zlib1g-dev\n```\n\n(On other distros, use the equivalent packages: e.g. RHEL/Fedora use `java-17-openjdk-devel`, `android-tools`, `fontconfig-devel`, `zlib-devel`. The CLI detects your distro and installs the right packages.)\n\n## Install bazel\n\n> [!NOTE]\n> **`valdi dev_setup` installs Bazelisk automatically.** It downloads the bazelisk binary to `~/.valdi/bin/` and adds it to your PATH.\n\nFor manual installation, follow the [Bazelisk installation guide](https://github.com/bazelbuild/bazelisk/blob/master/README.md) or install via npm:\n\n```bash\nnpm install -g @bazel/bazelisk\n```\n\n## Install git-lfs\n\nGit Large File Storage (LFS) manages the binaries that we need for Valdi.\n\n```\ngit lfs install\n```\n\n# Install Android SDK\n\n> [!NOTE]\n> **`valdi dev_setup` installs Android SDK command-line tools automatically.** You only need Android Studio if you prefer using its GUI or need Android emulator management.\n\n### Option 1: Automated (Recommended)\nRun `valdi dev_setup` - it will download and install Android SDK command-line tools, including:\n- Platform tools (API level 35)\n- Build tools (version 34.0.0)\n- NDK (version 25.2.9519653)\n\n### Option 2: Manual via Android Studio\nIf you prefer using Android Studio's GUI:\n\n1. Download and install Android Studio from [developer.android.com/studio](https://developer.android.com/studio)\n2. Open any project, navigate to `Tools` -> `SDK Manager`\n3. Under **SDK Platforms**, install **API level 35**\n4. Under **SDK Tools**, uncheck `Hide obsolete packages`, check `Show Package Details`\n5. Install build tools **version 34.0.0**\n6. Install NDK version **25.2.9519653**\n\nAdd the following to your `.bashrc`\n\n```\necho \"export ANDROID_HOME=$HOME/Android/Sdk\" >> ~/.bashrc\necho \"export ANDROID_NDK_HOME=\\$ANDROID_HOME/ndk-bundle\" >> ~/.bashrc\necho \"export PATH=\\$ANDROID_HOME/platform-tools:\\$PATH\" >> ~/.bashrc\nsource ~/.bashrc\n```\n\n# Next steps\n\n[Installation guide](../INSTALL.md#installation)\n\n## Troubleshooting\n\n### Warning: swap space\n\nBazel eats a lot of memory, if you see Java memory errors, you don't have enough swap space.\n\n8GB should be enough for an Android build of the hello world app.\n"
  },
  {
    "path": "docs/setup/macos_setup.md",
    "content": "# macOS Setup Reference Guide\n\n> **Get the CLI from npm:** `npm install -g @snap/valdi`. Then run `valdi dev_setup` for automated setup. This guide is a reference for manual installation or troubleshooting only.\n\n## About\n\nThis guide documents the dependencies Valdi needs on macOS and how to install them manually. For the quickest setup, use [`valdi dev_setup`](../INSTALL.md) which automates most of these steps.\n\nThis guide assumes you're using the default shell (zsh). Setup is possible for other shells, but you'll need to adapt the configuration file paths.\n\n## Setting up XCode\n\nMake sure you have the latest version of XCode installed in addition to iPhone Simulator packages for iOS development. Latest versions of [XCode](https://apps.apple.com/us/app/xcode/id497799835) can be found on Apple's App Store.\n\nMake sure XCode tools are in your path:\n\n```\nsudo xcode-select -s /Applications/Xcode.app\n```\n\n## Homebrew\n\nMost of Valdi's required dependencies can be installed via Homebrew.\n\nFollow these instructions to install: https://brew.sh/\n\nAdd Homebrew to your path:\n\n```\necho >> ~/.zprofile\necho 'eval \"$(/opt/homebrew/bin/brew shellenv)\"' >> /Users/$USER/.zprofile\neval \"$(/opt/homebrew/bin/brew shellenv)\"\n```\n\n## Autoload compinit\n\nAdd the following to the top of your `.zshrc` to setup for autocomplete.\n\n```\nautoload -U compinit && compinit\nautoload -U bashcompinit && bashcompinit\n```\n\nMake sure to load your changes via `source ~/.zshrc`.\n\n## Brew install dependencies\n\n```\nbrew install npm bazelisk openjdk@17 temurin git-lfs watchman ios-webkit-debug-proxy\n```\n\n## Setup JDK path\n\n```\nsudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk\necho 'export PATH=\"/opt/homebrew/opt/openjdk@17/bin:$PATH\"' >> ~/.zshrc\necho 'export JAVA_HOME=`/usr/libexec/java_home -v 17`' >> ~/.zshrc\n```\n\n## Install git-lfs\n\nGit Large File Storage (LFS) manages the binaries that we need for Valdi.\n\n```\ngit lfs install\n```\n\n## Install Android SDK (only required for Android development)\n\n> [!NOTE]\n> **`valdi dev_setup` installs Android SDK command-line tools automatically.** You only need Android Studio if you prefer using its GUI or need Android emulator management.\n\n### Option 1: Automated (Recommended)\nRun `valdi dev_setup` - it will download and install Android SDK command-line tools, including:\n- Platform tools (API level 35)\n- Build tools (version 34.0.0)\n- NDK (version 25.2.9519653)\n\n### Option 2: Manual via Android Studio\nIf you prefer using Android Studio's GUI:\n\n1. Download and install Android Studio from [developer.android.com/studio](https://developer.android.com/studio)\n2. Open any project, navigate to `Tools` -> `SDK Manager`\n3. Under **SDK Platforms**, install **API level 35**\n4. Under **SDK Tools**, uncheck `Hide obsolete packages`, check `Show Package Details`\n5. Install build tools **version 34.0.0**\n6. Install NDK version **25.2.9519653**\n\nUpdate `.zshrc` with the following:\n\n```\necho \"export ANDROID_HOME=$HOME/Library/Android/sdk\" >> ~/.zshrc\necho \"export ANDROID_NDK_HOME=\\$ANDROID_HOME/ndk-bundle\" >> ~/.zshrc\necho \"export PATH=\\$ANDROID_HOME/platform-tools:\\$PATH\" >> ~/.zshrc\nsource ~/.zshrc\n```\n\n# Next steps\n\n[Installation guide](../INSTALL.md#installation)\n"
  },
  {
    "path": "fossa-deps.yml",
    "content": "server: https://app.fossa.com\n\nremote-dependencies: \n- name: toolchains_llvm\n  version: 1.3.0\n  url: https://github.com/bazel-contrib/toolchains_llvm/releases/download/v1.3.0/toolchains_llvm-v1.3.0.tar.gz\n- name: com_google_protobuf\n  version: 27.0\n  url: https://github.com/protocolbuffers/protobuf/releases/download/v27.0/protobuf-27.0.tar.gz\n- name: rules_cc\n  version: 0.0.17\n  url: https://github.com/bazelbuild/rules_cc/releases/download/0.0.17/rules_cc-0.0.17.tar.gz\n- name: rules_android_ndk\n  version: 0.1.3\n  url: https://github.com/bazelbuild/rules_android_ndk/releases/download/v0.1.3/rules_android_ndk-v0.1.3.tar.gz\n- name: bazel_skylib\n  version: 1.2.0\n  url: https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.0/bazel-skylib-1.2.0.tar.gz\n- name: rules_android\n  version: 0.0.0\n  url: https://github.com/bazelbuild/rules_android/archive/5e74650496dff30e97b8eee5a8b12968de3bdec3.zip\n- name: rules_kotlin\n  version: 1.9.0\n  url: https://github.com/bazelbuild/rules_kotlin/releases/download/v1.9.0/rules_kotlin-v1.9.0.tar.gz\n- name: rules_java\n  version: 7.4.0\n  url: https://github.com/bazelbuild/rules_java/releases/download/7.4.0/rules_java-7.4.0.tar.gz\n- name: rules_jvm_external\n  version: 6.2\n  url: https://github.com/bazelbuild/rules_jvm_external/releases/download/6.2/rules_jvm_external-6.2.tar.gz\n- name: rules_xcodeproj\n  version: 3.2.0\n  url: https://github.com/MobileNativeFoundation/rules_xcodeproj/releases/download/3.2.0/release.tar.gz\n- name: build_bazel_rules_swift\n  version: 3.1.2\n  url: https://github.com/bazelbuild/rules_swift/releases/download/3.1.2/rules_swift.3.1.2.tar.gz\n- name: rules_shell\n  version: 0.3.0\n  url: https://github.com/bazelbuild/rules_shell/releases/download/v0.3.0/rules_shell-v0.3.0.tar.gz\n- name: build_bazel_rules_apple\n  version: 4.0.0\n  url: https://github.com/bazelbuild/rules_apple/releases/download/4.0.0/rules_apple.4.0.0.tar.gz\n- name: build_bazel_apple_support\n  version: 1.21.0\n  url: https://github.com/bazelbuild/apple_support/releases/download/1.21.0/apple_support.1.21.0.tar.gz\n- name: bazel_features\n  version: 1.10.0\n  url: https://github.com/bazel-contrib/bazel_features/releases/download/v1.10.0/bazel_features-v1.10.0.tar.gz\n- name: zoo\n  version: 0.0.0\n  url: https://github.com/thecppzoo/zoo/archive/33b868300145773d8c433b6b3d6643eba6334f7d.zip\n- name: hermes\n  version: 0.0.0\n  url: https://github.com/facebook/hermes/archive/880b1645b5dca974f4329dc4108692d301abee0d.zip\n- name: gtest\n  version: 1.13.0\n  url: https://github.com/google/googletest/archive/refs/tags/v1.13.0.tar.gz\n- name: boringssl\n  version: 0.0.0\n  url: https://boringssl.googlesource.com/boringssl/+archive/82f9853fc7d7360ae44f1e1357a6422c5244bbd8.tar.gz\n- name: boost\n  version: 1.78.0\n  url: https://archives.boost.io/release/1.78.0/source/boost_1_78_0.tar.bz2\n- name: phmap\n  version: 1.3.12\n  url: https://github.com/greg7mdp/parallel-hashmap/archive/refs/tags/v1.3.12.tar.gz\n- name: fmt\n  version: 7.1.3\n  url: https://github.com/fmtlib/fmt/releases/download/7.1.3/fmt-7.1.3.zip\n- name: jsoncpp\n  version: 1.8.0\n  url: https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/1.8.0.zip\n- name: harfbuzz\n  version: 12.2.0\n  url: https://github.com/harfbuzz/harfbuzz/releases/download/12.2.0/harfbuzz-12.2.0.tar.xz\n- name: protobuf_cpp\n  version: 3.20.0\n  url: https://github.com/protocolbuffers/protobuf/releases/download/v3.20.0/protobuf-all-3.20.0.tar.gz\n- name: backward-cpp\n  version: 1.6\n  url: https://github.com/bombela/backward-cpp/archive/refs/tags/v1.6.tar.gz\n- name: xxhash\n  version: 0.8.2\n  url: https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.2.tar.gz\n- name: zlib_chromium\n  version: 0.0.0\n  url: https://github.com/simonis/zlib-chromium/archive/93867c6db67801f74c2d0840a271c7aa7fd6716c.zip\n- name: zstd\n  version: 1.5.6\n  url: https://github.com/facebook/zstd/releases/download/v1.5.6/zstd-1.5.6.tar.gz\n- name: icu\n  version: 68-1\n  url: https://github.com/unicode-org/icu/releases/download/release-68-1/icu4c-68_1-src.tgz\n- name: websocketpp\n  version: 0.8.2\n  url: https://github.com/zaphoyd/websocketpp/archive/refs/tags/0.8.2.tar.gz\n- name: test262\n  version: 0.0.0\n  url: https://github.com/tc39/test262/archive/refs/heads/main.zip\n- name: rules_pkg\n  version: 0.9.1\n  url: https://github.com/bazelbuild/rules_pkg/releases/download/0.9.1/rules_pkg-0.9.1.tar.gz\n- name: rules_nodejs\n  version: 5.8.4\n  url: https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.4/rules_nodejs-core-5.8.4.tar.gz\n- name: build_bazel_rules_nodejs\n  version: 5.8.4\n  url: https://github.com/bazelbuild/rules_nodejs/releases/download/5.8.4/rules_nodejs-5.8.4.tar.gz\n- name: aspect_rules_js\n  version: 2.0.0\n  url: https://github.com/aspect-build/rules_js/releases/download/v2.0.0/rules_js-v2.0.0.tar.gz\n- name: aspect_rules_ts\n  version: 3.7.0\n  url: https://github.com/aspect-build/rules_ts/releases/download/v3.7.0/rules_ts-v3.7.0.tar.gz\n- name: aspect_rules_esbuild\n  version: 0.22.1\n  url: https://github.com/aspect-build/rules_esbuild/releases/download/v0.22.1/rules_esbuild-v0.22.1.tar.gz\n- name: aspect_bazel_lib\n  version: 2.21.2\n  url: https://github.com/bazel-contrib/bazel-lib/releases/download/v2.21.2/bazel-lib-v2.21.2.tar.gz\n- name: rules_fuzzing\n  version: 0.5.2\n  url: https://github.com/bazelbuild/rules_fuzzing/archive/v0.5.2.zip\n- name: rules_python\n  version: 0.20.0\n  url: https://github.com/bazelbuild/rules_python/releases/download/0.20.0/rules_python-0.20.0.tar.gz\n- name: resvg\n  version: 0.0.0\n  url: https://github.com/RazrFalcon/resvg/archive/a739aef5d01360ec238c886bc50674f31458df00.zip\n- name: skia\n  version: 0.0.0\n  url: https://github.com/google/skia/archive/8d5c6efb04514a31f09a2e865940f99cdf60ce21.zip\n- name: libjpeg_turbo\n  version: 0.0.0\n  url: https://chromium.googlesource.com/chromium/deps/libjpeg_turbo/+archive/e14cbfaa85529d47f9f55b0f104a579c1061f9ad.tar.gz\n- name: libpng\n  version: 0.0.0\n  url: https://skia.googlesource.com/third_party/libpng.git/+archive/ed217e3e601d8e462f7fd1e04bed43ac42212429.tar.gz\n- name: libwebp\n  version: 0.0.0\n  url: https://chromium.googlesource.com/webm/libwebp.git/+archive/845d5476a866141ba35ac133f856fa62f0b7445f.tar.gz\n- name: zlib_skia\n  version: 0.0.0\n  url: https://chromium.googlesource.com/chromium/src/third_party/zlib/+archive/646b7f569718921d7d4b5b8e22572ff6c76f2596.tar.gz\n- name: freetype\n  version: 0.0.0\n  url: https://chromium.googlesource.com/chromium/src/third_party/freetype2.git/+archive/5d4e649f740c675426fbe4cdaffc53ee2a4cb954.tar.gz\n- name: expat\n  version: 0.0.0\n  url: https://chromium.googlesource.com/external/github.com/libexpat/libexpat.git/+archive/624da0f593bb8d7e146b9f42b06d8e6c80d032a3.tar.gz\n- name: ocmock\n  version: 3.9.4\n  url: https://github.com/erikdoe/ocmock/archive/refs/tags/v3.9.4.tar.gz\n\nvendored-dependencies:\n- name: djinni-support-lib\n  path: third-party/djinni-support-lib\n- name: quickjs\n  path: third-party/quickjs\n- name: v8\n  path: third-party/v8\n- name: yoga\n  path: third-party/yoga\n"
  },
  {
    "path": "libs/dummy/BUILD.bazel",
    "content": "cc_binary(\n    name = \"dummy\",\n    testonly = 1,\n    srcs = glob([\n        \"src/dummy/**/*.cpp\",\n    ]),\n    linkstatic = True,\n    deps = [\n        \"//libs/utils:utils_cc\",\n        \"//libs/utils:utils_oss_cc\",\n        \"//third-party/djinni-support-lib:djinni_support_lib\",\n        \"//third-party/jscore\",\n        \"@backward-cpp\",\n        \"@boringssl//:ssl\",\n        \"@fmt\",\n        \"@gtest\",\n        \"@harfbuzz\",\n        \"@hermes\",\n        \"@jsoncpp\",\n        \"@phmap\",\n        \"@protobuf_cpp//:protobuf\",\n        \"@skia//:core\",\n        \"@xxhash\",\n        \"@zlib_chromium\",\n        \"@zstd\",\n    ],\n)\n\ncc_test(\n    name = \"test\",\n    srcs = glob([\n        \"test/**/*.cpp\",\n    ]),\n    linkstatic = 1,\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//libs/utils:utils_cc\",\n        \"//libs/utils:utils_oss_cc\",\n        \"@gtest//:gtest_main\",\n    ],\n)\n\nandroid_library(\n    name = \"dummy_android\",\n    custom_package = \"com.snapchat.client\",\n    manifest = \"src/manifest/AndroidManifest.xml\",\n    resource_files = glob([\"res/**\"]),\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "libs/dummy/src/dummy/main.cpp",
    "content": "#include <iostream>\n#include <sstream>\n#include <string>\n#include <vector>\n\n#include \"utils/base/Function.hpp\"\n#include \"utils/base/NonCopyable.hpp\"\n#include \"utils/debugging/Assert.hpp\"\n#include \"utils/platform/TargetPlatform.hpp\"\n\n#include \"hermes/VM/Runtime.h\"\n\n#include <fmt/format.h>\n#include <json/reader.h>\n#include <phmap/phmap.h>\n\nstatic std::string getPlatformString() {\n    switch (snap::kPlatform) {\n        case snap::Platform::Android:\n            return \"android\";\n        case snap::Platform::Ios:\n            return \"ios\";\n        case snap::Platform::MacOs:\n            return \"macos\";\n        case snap::Platform::DesktopLinux:\n            return \"linux\";\n        case snap::Platform::Wasm:\n            return \"macos\";\n    }\n}\n\nint main(int argc, const char** argv) {\n    SC_ASSERT(true);\n\n    std::ostringstream ss;\n    ss << getPlatformString() << \" [\";\n\n    std::vector<std::string> options;\n    if constexpr (snap::kAssertsCompiledIn) {\n        options.emplace_back(\"asserts\");\n    }\n    if constexpr (snap::kLoggingCompiledIn) {\n        options.emplace_back(\"logging\");\n    }\n    if constexpr (snap::kTracingEnabled) {\n        options.emplace_back(\"tracing\");\n    }\n\n    std::copy(options.begin(), options.end(), std::ostream_iterator<std::string>(ss, \",\"));\n\n    ss << \"]\";\n\n    std::cout << ss.str() << std::endl;\n\n    return 0;\n}\n"
  },
  {
    "path": "libs/dummy/src/manifest/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.snapchat.client\">\n</manifest>"
  },
  {
    "path": "libs/dummy/test/Test.cpp",
    "content": "#include \"utils/platform/BuildOptions.hpp\"\n#include <gtest/gtest.h>\n\nnamespace {\n\nTEST(Dummy, canRunTest) {\n    ASSERT_TRUE(snap::kAssertsCompiledIn);\n    ASSERT_TRUE(snap::kLoggingCompiledIn);\n    ASSERT_TRUE(snap::kTracingEnabled);\n}\n\n} // namespace\n"
  },
  {
    "path": "libs/image_toolbox/BUILD.bazel",
    "content": "cc_library(\n    name = \"lib\",\n    srcs = glob([\n        \"src/image_toolbox/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/image_toolbox/**/*.hpp\",\n    ]),\n    strip_include_prefix = \"src\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@resvg\",\n        \"@valdi//snap_drawing:snap_drawing_cc\",\n        \"@valdi//valdi_core:valdi_core_cc\",\n    ],\n)\n\ncc_library(\n    name = \"image_toolbox_c\",\n    srcs = glob([\"src/image_toolbox_c/**/*.cpp\"]),\n    hdrs = glob([\"src/image_toolbox_c/**/*.h\"]),\n    strip_include_prefix = \"src\",\n    tags = [\"swift_module=ImageToolbox\"],\n    visibility = [\"//visibility:public\"],\n    deps = [\":lib\"],\n)\n"
  },
  {
    "path": "libs/image_toolbox/README.md",
    "content": "# ImageToolbox\n\nA high level utility library to perform various tasks on images\n"
  },
  {
    "path": "libs/image_toolbox/src/image_toolbox/ImageToolbox.cpp",
    "content": "#include \"ImageToolbox.hpp\"\n#include \"SVGRenderer.hpp\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n#include \"valdi_core/cpp/Utils/DiskUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n#include \"valdi_core/cpp/Utils/Value.hpp\"\n#include \"valdi_core/cpp/Utils/ValueUtils.hpp\"\n#include <unistd.h>\n\nnamespace snap::imagetoolbox {\n\nusing namespace snap::drawing;\n\ntemplate<typename R>\nusing ProcessImageFn = Valdi::Function<Valdi::Result<R>(Valdi::BytesView)>;\n\ntemplate<typename R>\nstatic Valdi::Result<R> processImage(const Valdi::StringBox& imageFilePath,\n                                     ProcessImageFn<R>&& defaultHandler,\n                                     ProcessImageFn<R>&& svgHandler) {\n    Valdi::Path path(imageFilePath.toStringView());\n    auto loadResult = Valdi::DiskUtils::load(path);\n    if (!loadResult) {\n        return loadResult.moveError();\n    }\n\n    auto fileBytes = loadResult.moveValue();\n\n    if (path.getFileExtension() == \"svg\") {\n        return svgHandler(fileBytes);\n    } else {\n        return defaultHandler(fileBytes);\n    }\n}\n\nstatic Valdi::Result<Ref<Image>> loadImage(const Valdi::StringBox& imageFilePath,\n                                           const std::optional<int>& widthHint,\n                                           const std::optional<int>& heightHint) {\n    return processImage<Valdi::Ref<snap::drawing::Image>>(\n        imageFilePath,\n        [&](auto bytes) { return Image::make(bytes); },\n        [&](auto bytes) {\n            auto outputWidth = widthHint ? widthHint.value() : 0;\n            auto outputHeight = heightHint ? heightHint.value() : 0;\n\n            return SVGRenderer::render(bytes.data(), bytes.size(), outputWidth, outputHeight);\n        });\n}\n\nValdi::Result<ImageInfo> getImageInfo(const Valdi::StringBox& imageFilePath) {\n    auto imageSize = processImage<std::pair<int, int>>(\n        imageFilePath,\n        [&](auto bytes) -> Valdi::Result<std::pair<int, int>> {\n            auto image = Image::make(bytes);\n            if (!image) {\n                return image.moveError();\n            }\n\n            return std::make_pair(image.value()->width(), image.value()->height());\n        },\n        [&](auto bytes) { return SVGRenderer::getSize(bytes.data(), bytes.size()); });\n\n    if (!imageSize) {\n        return imageSize.moveError();\n    }\n\n    ImageInfo info;\n    info.width = static_cast<uint32_t>(imageSize.value().first);\n    info.height = static_cast<uint32_t>(imageSize.value().second);\n\n    return info;\n}\n\nValdi::Result<Valdi::BytesView> outputImageInfo(const Valdi::StringBox& imageFilePath) {\n    auto imageInfo = getImageInfo(imageFilePath);\n    if (!imageInfo) {\n        return imageInfo.moveError();\n    }\n\n    Valdi::Value json;\n    json.setMapValue(\"width\", Valdi::Value(static_cast<int32_t>(imageInfo.value().width)));\n    json.setMapValue(\"height\", Valdi::Value(static_cast<int32_t>(imageInfo.value().height)));\n\n    return Valdi::valueToJson(json)->toBytesView();\n}\n\nValdi::Result<Valdi::BytesView> convertImage(const Valdi::StringBox& inputImageFilePath,\n                                             const Valdi::StringBox& outputImageFilePath,\n                                             const std::optional<int>& outputWidth,\n                                             const std::optional<int>& outputHeight,\n                                             double qualityRatio) {\n    Valdi::Path outputPath(outputImageFilePath.toStringView());\n\n    snap::drawing::EncodedImageFormat outputFormat;\n\n    auto outputFileExtension = outputPath.getFileExtension();\n\n    if (outputFileExtension == \"png\") {\n        outputFormat = snap::drawing::EncodedImageFormatPNG;\n    } else if (outputFileExtension == \"webp\") {\n        outputFormat = snap::drawing::EncodedImageFormatWebP;\n    } else if (outputFileExtension == \"jpg\" || outputFileExtension == \"jpeg\") {\n        outputFormat = snap::drawing::EncodedImageFormatJPG;\n    } else {\n        return Valdi::Error(STRING_FORMAT(\n            \"Unsupported file extension '{}' for output file '{}'\", outputFileExtension, outputImageFilePath));\n    }\n\n    auto imageResult = loadImage(inputImageFilePath, outputWidth, outputHeight);\n    if (!imageResult) {\n        return imageResult.moveError();\n    }\n    auto image = imageResult.moveValue();\n\n    int newWidth = image->width();\n    int newHeight = image->height();\n    auto ratio = static_cast<double>(newWidth) / static_cast<double>(newHeight);\n\n    if (outputWidth && outputHeight) {\n        newWidth = outputWidth.value();\n        newHeight = outputHeight.value();\n    } else if (outputWidth) {\n        newWidth = outputWidth.value();\n        newHeight = static_cast<int>(round(newWidth / ratio));\n    } else if (outputHeight) {\n        newHeight = outputHeight.value();\n        newWidth = static_cast<int>(round(newHeight * ratio));\n    }\n\n    if (newWidth != image->width() && newHeight != image->height()) {\n        image = image->resized(newWidth, newHeight);\n    }\n\n    auto encodeResult = image->encode(outputFormat, qualityRatio);\n    if (!encodeResult) {\n        return encodeResult.moveError();\n    }\n\n    auto storeResult = Valdi::DiskUtils::store(outputPath, encodeResult.value());\n    if (!storeResult) {\n        return storeResult.moveError();\n    }\n\n    return Valdi::BytesView();\n}\n\n} // namespace snap::imagetoolbox\n"
  },
  {
    "path": "libs/image_toolbox/src/image_toolbox/ImageToolbox.hpp",
    "content": "#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include \"valdi_core/cpp/Utils/StringBox.hpp\"\n\n#include <optional>\n\nnamespace snap::imagetoolbox {\n\nstruct ImageInfo {\n    uint32_t width;\n    uint32_t height;\n};\n\nValdi::Result<ImageInfo> getImageInfo(const Valdi::StringBox& imageFilePath);\nValdi::Result<Valdi::BytesView> outputImageInfo(const Valdi::StringBox& imageFilePath);\n\nValdi::Result<Valdi::BytesView> outputImageInfo(const Valdi::StringBox& imageFilePath);\nValdi::Result<Valdi::BytesView> convertImage(const Valdi::StringBox& inputImageFilePath,\n                                             const Valdi::StringBox& outputImageFilePath,\n                                             const std::optional<int>& outputWidth,\n                                             const std::optional<int>& outputHeight,\n                                             double qualityRatio);\n\n} // namespace snap::imagetoolbox\n"
  },
  {
    "path": "libs/image_toolbox/src/image_toolbox/SVGRenderer.cpp",
    "content": "#include \"SVGRenderer.hpp\"\n#include \"resvg/c-api/resvg.h\"\n#include \"snap_drawing/cpp/Utils/Bitmap.hpp\"\n#include \"utils/base/NonCopyable.hpp\"\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\nnamespace snap::imagetoolbox {\n\nstatic Valdi::Error svgErrorFromResult(int32_t result) {\n    switch (static_cast<resvg_error>(result)) {\n        case RESVG_OK:\n            return Valdi::Error(\"Everything is ok\");\n        case RESVG_ERROR_NOT_AN_UTF8_STR:\n            return Valdi::Error(\"Only UTF-8 content are supported\");\n        case RESVG_ERROR_FILE_OPEN_FAILED:\n            return Valdi::Error(\"Failed to open the provided file\");\n        case RESVG_ERROR_MALFORMED_GZIP:\n            return Valdi::Error(\"Compressed SVG must use the GZip algorithm\");\n        case RESVG_ERROR_ELEMENTS_LIMIT_REACHED:\n            return Valdi::Error(\"We do not allow SVG with more than 1_000_000 elements for security reasons\");\n        case RESVG_ERROR_INVALID_SIZE:\n            return Valdi::Error(\"SVG doesn't have a valid size\");\n        case RESVG_ERROR_PARSING_FAILED:\n            return Valdi::Error(\"Failed to parse an SVG data\");\n    }\n}\n\nclass ReSVGHandle : public Valdi::SimpleRefCountable {\npublic:\n    ReSVGHandle(resvg_render_tree* tree) : _tree(tree) {}\n\n    ~ReSVGHandle() override {\n        resvg_tree_destroy(_tree);\n    }\n\n    std::pair<int, int> getSize() const {\n        auto size = resvg_get_image_size(_tree);\n        return std::make_pair(static_cast<int>(size.width), static_cast<int>(size.height));\n    }\n\n    resvg_render_tree* tree() const {\n        return _tree;\n    }\n\nprivate:\n    resvg_render_tree* _tree;\n};\n\nclass ReSVG {\npublic:\n    ReSVG() {\n        static std::once_flag flag;\n        std::call_once(flag, []() { resvg_init_log(); });\n\n        _options = resvg_options_create();\n    }\n\n    ~ReSVG() {\n        resvg_options_destroy(_options);\n    }\n\n    Valdi::Result<Valdi::Ref<ReSVGHandle>> parse(const Valdi::Byte* data, size_t length) {\n        resvg_render_tree* tree = nullptr;\n        auto loadResult = resvg_parse_tree_from_data(reinterpret_cast<const char*>(data), length, _options, &tree);\n        if (loadResult != RESVG_OK) {\n            return svgErrorFromResult(loadResult);\n        }\n\n        return Valdi::makeShared<ReSVGHandle>(tree);\n    }\n\nprivate:\n    resvg_options* _options = nullptr;\n};\n\nValdi::Result<std::pair<int, int>> SVGRenderer::getSize(const Valdi::Byte* data, size_t length) {\n    ReSVG reSVG;\n    auto result = reSVG.parse(data, length);\n    if (!result) {\n        return result.moveError();\n    }\n\n    return result.value()->getSize();\n}\n\nValdi::Result<snap::drawing::Ref<snap::drawing::Image>> SVGRenderer::render(const Valdi::Byte* data,\n                                                                            size_t length,\n                                                                            int outputWidth,\n                                                                            int outputHeight) {\n    ReSVG reSVG;\n    auto result = reSVG.parse(data, length);\n    if (!result) {\n        return result.moveError();\n    }\n\n    auto svgSize = result.value()->getSize();\n\n    int surfaceWidth;\n    if (outputWidth > 0) {\n        surfaceWidth = outputWidth;\n    } else {\n        surfaceWidth = svgSize.first;\n    }\n\n    int surfaceHeight;\n    if (outputHeight > 0) {\n        surfaceHeight = outputHeight;\n    } else {\n        surfaceHeight = svgSize.second;\n    }\n\n    auto outputBitmapResult = snap::drawing::Bitmap::make(Valdi::BitmapInfo(\n        surfaceWidth, surfaceHeight, Valdi::ColorType::ColorTypeRGBA8888, Valdi::AlphaType::AlphaTypePremul, 0));\n    if (!outputBitmapResult) {\n        return outputBitmapResult.error().rethrow(\"Failed to create output bitmap: \");\n    }\n\n    auto outputBitmap = outputBitmapResult.moveValue();\n\n    auto* outputBytes = outputBitmap->lockBytes();\n\n    resvg_fit_to fitTo;\n    fitTo.type = RESVG_FIT_TO_TYPE_ZOOM;\n    fitTo.value = std::max(static_cast<float>(surfaceWidth) / static_cast<float>(svgSize.first),\n                           static_cast<float>(surfaceHeight) / static_cast<float>(svgSize.second));\n\n    resvg_render(result.value()->tree(),\n                 fitTo,\n                 resvg_transform_identity(),\n                 static_cast<uint32_t>(surfaceWidth),\n                 static_cast<uint32_t>(surfaceHeight),\n                 reinterpret_cast<char*>(outputBytes));\n    outputBitmap->unlockBytes();\n\n    return snap::drawing::Image::makeFromBitmap(outputBitmap, false);\n}\n\n} // namespace snap::imagetoolbox\n"
  },
  {
    "path": "libs/image_toolbox/src/image_toolbox/SVGRenderer.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n#include <utility>\n\nnamespace snap::imagetoolbox {\n\nclass SVGRenderer {\npublic:\n    static Valdi::Result<std::pair<int, int>> getSize(const Valdi::Byte* data, size_t length);\n\n    static Valdi::Result<snap::drawing::Ref<snap::drawing::Image>> render(const Valdi::Byte* data,\n                                                                          size_t length,\n                                                                          int outputWidth,\n                                                                          int outputHeight);\n};\n\n} // namespace snap::imagetoolbox\n"
  },
  {
    "path": "libs/image_toolbox/src/image_toolbox_c/image_toolbox.cpp",
    "content": "#include \"image_toolbox.h\"\n#include \"image_toolbox/ImageToolbox.hpp\"\n#include \"valdi_core/cpp/Utils/StringBox.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\nextern \"C\" {\n\nstatic void setAsError(char** error, const Valdi::StringBox& errorMessage) {\n    char* allocatedError = reinterpret_cast<char*>(malloc(sizeof(char) * (errorMessage.length() + 1)));\n    std::memcpy(allocatedError, errorMessage.getCStr(), errorMessage.length());\n    allocatedError[errorMessage.length()] = 0;\n\n    *error = allocatedError;\n}\n\nimage_toolbox_size imagetoolbox_get_size(const char* input_path, char** error) {\n    image_toolbox_size size;\n    size.width = 0;\n    size.height = 0;\n\n    auto imageInfo =\n        snap::imagetoolbox::getImageInfo(Valdi::StringCache::getGlobal().makeStringFromLiteral(input_path));\n    if (imageInfo) {\n        size.width = imageInfo.value().width;\n        size.height = imageInfo.value().height;\n    } else {\n        setAsError(error, imageInfo.error().getMessage());\n    }\n\n    return size;\n}\n\nint imagetoolbox_convert(\n    const char* input_path, const char* output_path, int outputWidth, int outputHeight, char** error) {\n    auto result = snap::imagetoolbox::convertImage(Valdi::StringCache::getGlobal().makeStringFromLiteral(input_path),\n                                                   Valdi::StringCache::getGlobal().makeStringFromLiteral(output_path),\n                                                   {outputWidth},\n                                                   {outputHeight},\n                                                   1.0);\n\n    if (result) {\n        return 0;\n    }\n\n    setAsError(error, result.error().getMessage());\n    return -1;\n}\n\nvoid imagetoolbox_free_error(char* error) {\n    free(error);\n}\n}\n"
  },
  {
    "path": "libs/image_toolbox/src/image_toolbox_c/image_toolbox.h",
    "content": "#pragma once\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct {\n    int width;\n    int height;\n} image_toolbox_size;\n\nimage_toolbox_size imagetoolbox_get_size(const char* input_path, char** error);\nint imagetoolbox_convert(\n    const char* input_path, const char* output_path, int outputWidth, int outputHeight, char** error);\nvoid imagetoolbox_free_error(char* error);\n\n#ifdef __cplusplus\n}\n#endif\n"
  },
  {
    "path": "libs/utils/BUILD.bazel",
    "content": "load(\"//bzl:expand_template.bzl\", \"expand_template\")\nload(\"//bzl:valdi_library.bzl\", \"COMMON_COMPILE_FLAGS\")\n\nENABLE_ASSERT = {\n    \"@snap_client_toolchains//:sc_build_flag_assert\": [\"true\"],\n    \"//conditions:default\": [\"false\"],\n}\n\nENABLE_LOGGING = {\n    \"@snap_client_toolchains//:sc_build_flag_logging\": [\"true\"],\n    \"//conditions:default\": [\"false\"],\n}\n\nENABLE_TRACING = {\n    \"@snap_client_toolchains//:sc_build_flag_tracing\": [\"true\"],\n    \"//conditions:default\": [\"false\"],\n}\n\nDEV_BUILD = {\n    \"@snap_platforms//flavors:client_development\": [\"true\"],\n    \"@snap_platforms//flavors:platform_development\": [\"true\"],\n    \"//conditions:default\": [\"false\"],\n}\n\n# Map master and gold to gold for legacy compatibility\nGOLD_BUILD = {\n    \"@snap_platforms//flavors:gold\": [\"true\"],\n    \"@snap_platforms//flavors:master\": [\"true\"],\n    \"//conditions:default\": [\"false\"],\n}\n\nAPPSTORE_BUILD = {\n    \"@snap_platforms//flavors:production\": [\"true\"],\n    \"@snap_platforms//flavors:production_snapos\": [\"true\"],\n    \"//conditions:default\": [\"false\"],\n}\n\nALPHA_BUILD = {\n    \"@snap_platforms//flavors:alpha\": [\"true\"],\n    \"//conditions:default\": [\"false\"],\n}\n\nexpand_template(\n    name = \"generate_build_options\",\n    src = \":src/utils/platform/BuildOptionsGenerated.hpp.in\",\n    output = \"BuildOptionsGenerated.hpp\",\n    select_based_substitutions = {\n        \"@SC_BUILD_FLAG_ASSERT@\": ENABLE_ASSERT,\n        \"@SC_BUILD_FLAG_LOGGING@\": ENABLE_LOGGING,\n        \"@SC_BUILD_FLAG_TRACING@\": ENABLE_TRACING,\n        \"@SC_BUILD_FLAG_DEV@\": DEV_BUILD,\n        \"@SC_BUILD_FLAG_GOLD@\": GOLD_BUILD,\n        \"@SC_BUILD_FLAG_APPSTORE@\": APPSTORE_BUILD,\n        \"@SC_BUILD_FLAG_ALPHA@\": ALPHA_BUILD,\n    },\n)\n\ncc_library(\n    name = \"build_options\",\n    hdrs = [\":generate_build_options\"],\n    include_prefix = \"build_options\",\n    linkstatic = 1,\n)\n\ncc_library(\n    name = \"utils_cc\",\n    linkstatic = 1,\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":utils_base_cc\",\n        \":utils_core_cc\",\n    ],\n)\n\ncc_library(\n    name = \"utils_core_cc\",\n    srcs = glob([\n        \"src/utils/platform/**/*.cpp\",\n        \"src/utils/debugging/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/utils/platform/**/*.hpp\",\n        \"src/utils/debugging/**/*.hpp\",\n    ]),\n    copts = COMMON_COMPILE_FLAGS,\n    includes = [\"src\"],\n    tags = [\"exported\"],\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":build_options\",\n        \":utils_base_cc\",\n        \":utils_kitchensink_cc\",\n        \":utils_time_cc\",\n        \"//third-party/djinni-support-lib:djinni_support_lib\",  # needed for JvmUtils\n        \"@fmt\",\n        \"@jsoncpp\",  # needed for KeyValueStore\n    ] + select({\n        \"@platforms//os:ios\": [\":utils_core_objc\"],\n        \"//conditions:default\": [],\n    }),\n)\n\nobjc_library(\n    name = \"utils_core_objc\",\n    srcs = glob([\n        \"src/utils/debugging/**/*.mm\",\n    ]),\n)\n\n# Everything else\ncc_library(\n    name = \"utils_time_cc\",\n    srcs = glob([\n        \"src/utils/time/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/utils/time/**/*.hpp\",\n        \"src/utils/platform/**/*.hpp\",\n    ]),\n    copts = [\"-fvisibility=default\"],\n    includes = [\"src\"],\n    tags = [\"exported\"],\n    visibility = [\"//visibility:public\"],\n    deps = [],\n)\n\ncc_library(\n    name = \"utils_encoding_cc\",\n    srcs = glob([\n        \"src/utils/encoding/**/*.cpp\",\n        \"src/utils/crypto/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/utils/encoding/**/*.hpp\",\n        \"src/utils/crypto/**/*.hpp\",\n    ]),\n    copts = COMMON_COMPILE_FLAGS,\n    includes = [\"src\"],\n    tags = [\"exported\"],\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":utils_core_cc\",\n        \":utils_logging_cc\",\n        \"@boost\",\n        \"@protobuf_cpp//:protobuf\",\n    ],\n)\n\ncc_library(\n    name = \"utils_logging_cc\",\n    srcs = glob([\n        \"src/utils/logging/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/utils/logging/**/*.hpp\",\n        \"src/utils/platform/**/*.hpp\",\n    ]),\n    copts = COMMON_COMPILE_FLAGS,\n    includes = [\"src\"],\n    tags = [\"exported\"],\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":build_options\",\n        \"@fmt\",\n    ],\n)\n\ncc_library(\n    name = \"utils_base_cc\",\n    srcs = glob([\n        \"src/utils/base/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/utils/base/**/*.hpp\",\n    ]),\n    includes = [\"src\"],\n    linkopts = [\n        \"-lm\",\n    ],\n    tags = [\"exported\"],\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@boost\",\n        \"@fmt\",\n        \"@zoo\",\n    ],\n)\n\ncc_library(\n    name = \"utils_kitchensink_cc\",\n    srcs = glob([\n        \"src/utils/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/utils/*.hpp\",\n    ]),\n    copts = COMMON_COMPILE_FLAGS + [\"-fvisibility=default\"],\n    includes = [\"src\"],\n    tags = [\"exported\"],\n    visibility = [\"//visibility:public\"],\n    deps = [],\n)\n\ncc_library(\n    name = \"utils_oss_cc\",\n    srcs = glob([\n        \"src/utils_oss/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/utils_oss/**/*.hpp\",\n    ]),\n    linkstatic = 1,\n    strip_include_prefix = \"src\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":utils_cc\",\n    ],\n)\n\ncc_library(\n    name = \"utils_obj_cpp_ptr_wrapper\",\n    hdrs = [\n        \"src/utils/ObjCppPtrWrapper.hpp\",\n    ],\n    includes = [\"src\"],\n    tags = [\"exported\"],\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "libs/utils/src/utils/NoDestructor.hpp",
    "content": "#pragma once\n// copied from https://chromium.googlesource.com/chromium/src/base/+/refs/heads/master/no_destructor.h\n// Copyright 2018 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n#include <new>\n#include <utility>\n\nnamespace snap::utils {\n\n// A wrapper that makes it easy to create an object of type T with static\n// storage duration that:\n// - is only constructed on first access\n// - never invokes the destructor\n// in order to satisfy the styleguide ban on global constructors and\n// destructors.\n//\n// Runtime constant example:\n// const std::string& GetLineSeparator() {\n//  // Forwards to std::string(size_t, char, const Allocator&) constructor.\n//   static const base::NoDestructor<std::string> s(5, '-');\n//   return *s;\n// }\n//\n// More complex initialization with a lambda:\n// const std::string& GetSessionNonce() {\n//   static const base::NoDestructor<std::string> nonce([] {\n//     std::string s(16);\n//     crypto::RandString(s.data(), s.size());\n//     return s;\n//   }());\n//   return *nonce;\n// }\n//\n// NoDestructor<T> stores the object inline, so it also avoids a pointer\n// indirection and a malloc. Also note that since C++11 static local variable\n// initialization is thread-safe and so is this pattern. Code should prefer to\n// use NoDestructor<T> over:\n// - A function scoped static T* or T& that is dynamically initialized.\n// - A global base::LazyInstance<T>.\n//\n// Note that since the destructor is never run, this *will* leak memory if used\n// as a stack or member variable. Furthermore, a NoDestructor<T> should never\n// have global scope as that may require a static initializer.\ntemplate<typename T>\nclass NoDestructor {\npublic:\n    // Not constexpr; just write static constexpr T x = ...; if the value should\n    // be a constexpr.\n    template<typename... Args>\n    explicit NoDestructor(Args&&... args) {\n        new (_storage) T(std::forward<Args>(args)...);\n    }\n\n    // Allows copy and move construction of the contained type, to allow\n    // construction from an initializer list, e.g. for std::vector.\n    explicit NoDestructor(const T& x) {\n        new (_storage) T(x);\n    }\n    explicit NoDestructor(T&& x) {\n        new (_storage) T(std::move(x));\n    }\n\n    NoDestructor(const NoDestructor&) = delete;\n    NoDestructor& operator=(const NoDestructor&) = delete;\n\n    ~NoDestructor() = default;\n\n    const T& operator*() const {\n        return *get();\n    }\n    T& operator*() {\n        return *get();\n    }\n\n    const T* operator->() const {\n        return get();\n    }\n    T* operator->() {\n        return get();\n    }\n\n    const T* get() const {\n        return reinterpret_cast<const T*>(_storage);\n    }\n    T* get() {\n        return reinterpret_cast<T*>(_storage);\n    }\n\nprivate:\n    alignas(T) char _storage[sizeof(T)];\n\n#if defined(LEAK_SANITIZER)\n    // TODO(https://crbug.com/812277): This is a hack to work around the fact\n    // that LSan doesn't seem to treat NoDestructor as a root for reachability\n    // analysis. This means that code like this:\n    //   static base::NoDestructor<std::vector<int>> v({1, 2, 3});\n    // is considered a leak. Using the standard leak sanitizer annotations to\n    // suppress leaks doesn't work: std::vector is implicitly constructed before\n    // calling the base::NoDestructor constructor.\n    //\n    // Unfortunately, I haven't been able to demonstrate this issue in simpler\n    // reproductions: until that's resolved, hold an explicit pointer to the\n    // placement-new'd object in leak sanitizer mode to help LSan realize that\n    // objects allocated by the contained type are still reachable.\n    T* _storagePtr = reinterpret_cast<T*>(_storage);\n#endif // defined(LEAK_SANITIZER)\n};\n\n} // namespace snap::utils\n"
  },
  {
    "path": "libs/utils/src/utils/ObjCppPtrWrapper.hpp",
    "content": "/**\n  Used to wrap another type. ObjC type encoding can be very large for complex\n  C++ types, so when an ObjC method/field has a C++ type, wrap it in this to\n  avoid the type encoding. If you do this, confirm it worked by checking the\n  length of the type encoding before and after with: \"objdump -macho\n  -objc-meta-data YourObjectFile.o\"\n  **/\ntemplate<class T>\nclass ObjCppPtrWrapper {\npublic:\n    T* o;\n    ObjCppPtrWrapper(T* t) : o(t) {}\n    ObjCppPtrWrapper() {\n        o = nullptr;\n    }\n};\n"
  },
  {
    "path": "libs/utils/src/utils/base/Function.hpp",
    "content": "#pragma once\n\n// Synopsis:\n// This header introduces snap::Function, a move-only equivalent to std::function\n// and snap::CopyableFunction.\n// These components should track very closely std::function, see the documentation\n// for std::function, differences not listed below are probably a bug to be reported\n// These are the differences:\n// - the only valid operations on a \"moved-from\" state are destruction and assignment (quasi-destructive move)\n// - snap::Function accepts move-only targets (for example lambdas that capture unique_ptr) and is itself move-only\n// - RTTI will be removed in the future, do not rely on .type()\n// - the internal trampolining does not convert the arguments into references\n\n// clang-format off\n\n// The zoo library does not detect whether or not exceptions are disabled.\n// This file should be included before any zoo headers.\n#if !defined(ZOO_DISABLE_EXCEPTIONS) && !defined(__cpp_exceptions)\n  // This C++ feature test macro is supported by both clang and gcc,\n  // but not MSVC.\n  #define ZOO_DISABLE_EXCEPTIONS 1\n#endif\n\n#include \"zoo/Any/VTablePolicy.h\"\n#include \"zoo/AnyContainer.h\"\n#include \"zoo/FunctionPolicy.h\"\n\n// clang-format on\n\n#include <typeinfo>\n\nnamespace snap {\n\nnamespace callable::affordance {\n\n// clang-format off\n\nstruct ICFSafeDestroy: zoo::Destroy {\n    struct VTableEntry: zoo::Destroy::VTableEntry {\n        bool default_; // NOLINT\n    };\n\n    template<typename Container>\n    constexpr static inline VTableEntry\n        Default = { zoo::Destroy::Default<Container>, true }; // NOLINT\n\n    template<typename Container>\n    constexpr static inline VTableEntry\n        Operation = { zoo::Destroy::Operation<Container>, false }; // NOLINT\n\n    template<typename UserContainer>\n    struct UserAffordance: zoo::Destroy::UserAffordance<UserContainer> {\n        bool isDefault() const noexcept {\n            return\n                static_cast<const UserContainer *>(this)->\n                    container()->template vTable<ICFSafeDestroy>()->default_;\n        }\n    };\n};\n\n}  // namespace callable::affordance\n\n/// \\brief restricts the public API of zoo::AnyContainer\n///\n/// zoo::Function offers access to all of the public interface of its\n/// given type erasure container, this might be confusing with regards to\n/// AnyContainer::swap, reset and emplace that only make changes to\n/// the type-erased value but not the internal trampoline in zoo::Function\n// NOLINTNEXTLINE(readability-identifier-naming)\ntemplate<typename Policy_>\nstruct SaferTypeErasureContainer: protected zoo::AnyContainer<Policy_>\n{\n    using Base = zoo::AnyContainer<Policy_>;\n    using Base::Base;\n    using Policy = typename Base::Policy;\n};\n\ntemplate<typename T>\nusing MoveOnlyTypeErasurePolicy =\n    zoo::Policy<\n        T, callable::affordance::ICFSafeDestroy, zoo::Move\n    >;\n\ntemplate<typename T>\nusing CopyableTypeErasurePolicy =\n    zoo::Policy<\n        T, callable::affordance::ICFSafeDestroy, zoo::Move, zoo::Copy\n    >;\n\ntemplate<typename OptimizeFor, typename Signature>\nusing OptimizedMoveOnlyFunction =\n    zoo::Function<\n        SaferTypeErasureContainer<MoveOnlyTypeErasurePolicy<OptimizeFor>>,\n        Signature\n    >;\n\ntemplate<typename OptimizeFor, typename Signature>\nusing OptimizedCopyableFunction =\n    zoo::Function<\n        SaferTypeErasureContainer<CopyableTypeErasurePolicy<OptimizeFor>>,\n        Signature\n    >;\n\n// clang-format on\n\ntemplate<typename Signature>\nusing Function = OptimizedMoveOnlyFunction<void* [4], Signature>;\n\ntemplate<typename Signature>\nusing CopyableFunction = OptimizedCopyableFunction<void* [4], Signature>;\n\n} // namespace snap\n"
  },
  {
    "path": "libs/utils/src/utils/base/NonCopyable.hpp",
    "content": "#pragma once\n\nnamespace snap {\n\nclass NonCopyable {\npublic:\n    NonCopyable(const NonCopyable&) = delete;\n    NonCopyable& operator=(const NonCopyable&) = delete;\n\nprotected:\n    NonCopyable() = default;\n};\n\n} // namespace snap\n"
  },
  {
    "path": "libs/utils/src/utils/crypto/AesEncryptor.cpp",
    "content": "#include \"utils/crypto/AesEncryptor.hpp\"\n\n#include \"utils/crypto/CryptoHelpers.hpp\"\n#include \"utils/debugging/Assert.hpp\"\n#include \"utils/logging/Log.hpp\"\n\n#include <openssl/aead.h>\n#include <openssl/span.h>\n\nnamespace snap::utils::crypto {\n\nconstexpr auto kTag = \"[utils][AesEncryptor]\";\n\nAesEncryptor::AesEncryptor(const AesEncryptor::Key& key, const AesEncryptor::Iv& iv)\n    : _cipher(EVP_aead_aes_128_gcm()), _key(key), _iv(iv) {\n    SC_ASSERT(_key.size() == EVP_AEAD_key_length(_cipher));\n    SC_ASSERT(_iv.size() == EVP_AEAD_nonce_length(_cipher));\n}\n\nAesEncryptor::AesEncryptor(const bssl::Span<uint8_t>& key, const bssl::Span<uint8_t>& iv)\n    : _cipher(EVP_aead_aes_128_gcm()) {\n    SC_ASSERT(_key.size() == EVP_AEAD_key_length(_cipher));\n    SC_ASSERT(_iv.size() == EVP_AEAD_nonce_length(_cipher));\n    std::copy(key.begin(), key.end(), _key.begin());\n    std::copy(iv.begin(), iv.end(), _iv.begin());\n}\n\nAesEncryptor::AesEncryptor(const std::vector<uint8_t>& key, const std::vector<uint8_t>& iv)\n    : _cipher(EVP_aead_aes_128_gcm()) {\n    SC_ASSERT(_key.size() == EVP_AEAD_key_length(_cipher));\n    SC_ASSERT(_iv.size() == EVP_AEAD_nonce_length(_cipher));\n    std::copy(key.begin(), key.end(), _key.begin());\n    std::copy(iv.begin(), iv.end(), _iv.begin());\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::encrypt(const uint8_t* plainText, size_t len) {\n    return encryptWithAd(plainText, len, nullptr, 0);\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::decrypt(const uint8_t* cipherText, size_t len) {\n    return decryptWithAd(cipherText, len, nullptr, 0);\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::encryptWithAd(const uint8_t* plainText,\n                                                                size_t len,\n                                                                const uint8_t* additionalData,\n                                                                size_t adLen) {\n    SC_ASSERT_NOTNULL(plainText);\n    SC_ASSERT(len > 0);\n    EVP_AEAD_CTX ctx;\n    if (EVP_AEAD_CTX_init(&ctx, _cipher, _key.data(), _key.size(), EVP_AEAD_max_tag_len(_cipher), nullptr) == 0) {\n        SCLOGE(kTag, \"Failed to initialize encryption key\");\n        logCryptoErrors();\n        SC_ASSERT(false, \"Bad key\");\n        return {};\n    }\n    std::vector<uint8_t> cipherText(len + EVP_AEAD_max_overhead(_cipher), 0);\n    size_t outLen;\n    if (EVP_AEAD_CTX_seal(&ctx,\n                          cipherText.data(),\n                          &outLen,\n                          cipherText.capacity(),\n                          _iv.data(),\n                          _iv.size(),\n                          plainText,\n                          len,\n                          additionalData,\n                          adLen) == 0) {\n        SCLOGE(kTag, \"Failed encryption\");\n        logCryptoErrors();\n        return {};\n    }\n    SC_ASSERT(outLen == cipherText.size());\n    EVP_AEAD_CTX_cleanup(&ctx);\n    return {cipherText};\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::decryptWithAd(const uint8_t* cipherText,\n                                                                size_t len,\n                                                                const uint8_t* additionalData,\n                                                                size_t adLen) {\n    SC_ASSERT_NOTNULL(cipherText);\n    EVP_AEAD_CTX ctx;\n    if (EVP_AEAD_CTX_init(&ctx, _cipher, _key.data(), _key.size(), EVP_AEAD_max_tag_len(_cipher), nullptr) == 0) {\n        SCLOGE(kTag, \"Failed to initialize decryption key\");\n        logCryptoErrors();\n        SC_ASSERT(false, \"Bad key\");\n        return std::nullopt;\n    }\n    const auto maxOverheadLen = EVP_AEAD_max_overhead(_cipher);\n    if (len < maxOverheadLen) {\n        SCLOGW(kTag, \"Invalid cipherText length {}. Min expected: {}\", len, maxOverheadLen);\n        return std::nullopt;\n    }\n    std::vector<uint8_t> plainText(len - maxOverheadLen, 0);\n    size_t outLen;\n    if (EVP_AEAD_CTX_open(&ctx,\n                          plainText.data(),\n                          &outLen,\n                          plainText.capacity(),\n                          _iv.data(),\n                          _iv.size(),\n                          cipherText,\n                          len,\n                          additionalData,\n                          adLen) == 0) {\n        SCLOGE(kTag, \"Failed decryption\");\n        logCryptoErrors();\n        return {};\n    }\n    SC_ASSERT(outLen == plainText.size());\n    EVP_AEAD_CTX_cleanup(&ctx);\n    return {plainText};\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::encrypt(const std::vector<uint8_t>& plainText) {\n    return encrypt(plainText.data(), plainText.size());\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::encrypt(const std::string& plainText) {\n    return encrypt(reinterpret_cast<const uint8_t*>(plainText.data()), plainText.size());\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::decrypt(const std::vector<uint8_t>& cipherText) {\n    return decrypt(cipherText.data(), cipherText.size());\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::decrypt(const std::string& cipherText) {\n    return decrypt(reinterpret_cast<const uint8_t*>(cipherText.data()), cipherText.size());\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::encrypt(const bssl::Span<uint8_t>& plainText) {\n    return encrypt(plainText.data(), plainText.size());\n}\nstd::optional<std::vector<uint8_t>> AesEncryptor::decrypt(const bssl::Span<uint8_t>& cipherText) {\n    return decrypt(cipherText.data(), cipherText.size());\n}\n\nstd::optional<std::vector<uint8_t>> AesEncryptor::encrypt(const bssl::Span<uint8_t>& plainText,\n                                                          const bssl::Span<uint8_t>& addData) {\n    return encryptWithAd(plainText.data(), plainText.size(), addData.data(), addData.size());\n}\nstd::optional<std::vector<uint8_t>> AesEncryptor::decrypt(const bssl::Span<uint8_t>& cipherText,\n                                                          const bssl::Span<uint8_t>& addData) {\n    return decryptWithAd(cipherText.data(), cipherText.size(), addData.data(), addData.size());\n}\n\n} // namespace snap::utils::crypto\n"
  },
  {
    "path": "libs/utils/src/utils/crypto/AesEncryptor.hpp",
    "content": "#pragma once\n\n#include <array>\n#include <cstdint>\n#include <optional>\n#include <string>\n#include <vector>\n\nusing EVP_AEAD = struct evp_aead_st;\n\nnamespace bssl {\ntemplate<typename T>\nclass Span;\n}\n\nnamespace snap::utils::crypto {\n\n/**\n * Convenience class for encrypting/decrypting bytes using AES-128-GCM (128-bit keys and 96-bit nonce/iv).\n * Once initialized with a key, this class should only be used for one round of encryption.\n * Keys and IVs MUST be generated with secure randomness. See utils::generateSecureRandomBytes.\n * DO NOT encrypt more than once with the same key and IV.\n *\n * The optional results of encrypt/decrypt are used to indicate success and failure. If the value is present,\n * the operation was successful. If the value is not present, the operation failed.\n *\n * For encrypt, the output is cipher text. This will always be the size of the input plus a 16-byte authentication tag.\n * The tag is opaque--just consider it part of the cipher text.\n *\n * For decrypt, the output is the original plain text. This will be the size of the cipher text minus the 16-byte\n * authentication tag.\n */\nclass AesEncryptor {\npublic:\n    using Key = std::array<uint8_t, 16>;\n    using Iv = std::array<uint8_t, 12>;\n\n    // TODO: Allow re-use of keys and setting the IV.\n    AesEncryptor(const Key& key, const Iv& iv);\n    AesEncryptor(const std::vector<uint8_t>& key, const std::vector<uint8_t>& iv);\n    AesEncryptor(const bssl::Span<uint8_t>& key, const bssl::Span<uint8_t>& iv);\n    virtual ~AesEncryptor() = default;\n\n    // Standard encrypt/decrypt for a vector of bytes.\n    std::optional<std::vector<uint8_t>> encrypt(const std::vector<uint8_t>& plainText);\n    std::optional<std::vector<uint8_t>> decrypt(const std::vector<uint8_t>& cipherText);\n\n    // Protobuf-friendly encrypt/decrypt. Protobuf uses std::string for byte buffers.\n    std::optional<std::vector<uint8_t>> encrypt(const std::string& plainText);\n    std::optional<std::vector<uint8_t>> decrypt(const std::string& cipherText);\n\n    // bssl::Span verions to avoid copies.\n    std::optional<std::vector<uint8_t>> encrypt(const bssl::Span<uint8_t>& plainText);\n    std::optional<std::vector<uint8_t>> decrypt(const bssl::Span<uint8_t>& cipherText);\n\n    // Authentically encrypt/decrypt with additional data.\n    std::optional<std::vector<uint8_t>> encrypt(const bssl::Span<uint8_t>& plainText,\n                                                const bssl::Span<uint8_t>& addData);\n    std::optional<std::vector<uint8_t>> decrypt(const bssl::Span<uint8_t>& cipherText,\n                                                const bssl::Span<uint8_t>& addData);\n\nprivate:\n    std::optional<std::vector<uint8_t>> encrypt(const uint8_t* plainText, size_t len);\n    std::optional<std::vector<uint8_t>> decrypt(const uint8_t* cipherText, size_t len);\n    std::optional<std::vector<uint8_t>> encryptWithAd(const uint8_t* plainText,\n                                                      size_t len,\n                                                      const uint8_t* additionalData,\n                                                      size_t adLen);\n    std::optional<std::vector<uint8_t>> decryptWithAd(const uint8_t* cipherText,\n                                                      size_t len,\n                                                      const uint8_t* additionalData,\n                                                      size_t adLen);\n\nprivate:\n    const EVP_AEAD* _cipher;\n    Key _key;\n    Iv _iv;\n};\n\n} // namespace snap::utils::crypto\n"
  },
  {
    "path": "libs/utils/src/utils/crypto/CryptoHelpers.cpp",
    "content": "#include \"utils/crypto/CryptoHelpers.hpp\"\n\n#include \"utils/logging/Log.hpp\"\n\n#include <array>\n#include <cstdint>\n#include <fmt/format.h>\n#include <openssl/err.h>\n\nnamespace snap::utils::crypto {\n\nvoid logCryptoErrors() {\n#ifdef NDEBUG\n    while (ERR_get_error() != 0u) {\n    }\n#else\n    while (uint32_t error = ERR_get_error()) {\n        std::array<char, 120> buf;\n        ERR_error_string_n(error, buf.data(), buf.size());\n        SCLOGE(\"[utils][CryptoHelpers]\", \"OpenSSL error: {}\", buf.data());\n    }\n#endif\n}\n\n} // namespace snap::utils::crypto\n"
  },
  {
    "path": "libs/utils/src/utils/crypto/CryptoHelpers.hpp",
    "content": "#pragma once\n\nnamespace snap::utils::crypto {\n\n/**\n * Logs the open SSL error stack for debug builds.\n * In release builds will clear the stack but not log anything.\n */\nvoid logCryptoErrors();\n\n} // namespace snap::utils::crypto\n"
  },
  {
    "path": "libs/utils/src/utils/debugging/Assert.cpp",
    "content": "#include \"utils/debugging/Assert.hpp\"\n\n#include <atomic>\n#include <chrono>\n#include <cstdio>\n\nnamespace snap {\nnamespace {\n// Global variable that we set by setEnableReleaseAsserts(). Enabled by default for development builds.\nstd::atomic_bool gReleaseAssertsEnabled{kAssertsCompiledIn};\n// Global variable indicating whether fused assertions are enabled. Disabled by\n// default. Should be enabled when running in Snapchat app.\nstd::atomic_bool gFusedAssertionEnabled{false};\n} // namespace\n\nbool releaseAssertsEnabled() {\n    return gReleaseAssertsEnabled.load(std::memory_order_relaxed);\n}\n\nvoid setEnableReleaseAsserts(bool enable) {\n    gReleaseAssertsEnabled.store(enable, std::memory_order_relaxed);\n}\n\nbool fusedAssertsEnabled() {\n    return gFusedAssertionEnabled.load(std::memory_order_relaxed);\n}\n\nvoid setEnableFusedAsserts(bool enable) {\n    gFusedAssertionEnabled.store(enable, std::memory_order_relaxed);\n}\n\n} // namespace snap\n"
  },
  {
    "path": "libs/utils/src/utils/debugging/Assert.hpp",
    "content": "#pragma once\n\n// This header adds assertion macros that can be used to validate conditions.\n//\n// SC_ASSERT(expression, \"optional message here\");\n// SC_ASSERT(expression);\n//\n// Asserts are enabled in all internal builds (Debug, Master, Alpha) and disabled for all\n// AppStore builds (Beta and Production).\n//\n// Fused Asserts:\n//    In non-debug builds (Master and Alpha) asserts may be fusible which\n//    helps to prevent crash loops.  Once an assertion is hit and the app aborts,\n//    future assertions will be disabled on that line for 30 minutes.\n//\n// Aborts will crash the app for all builds, including AppStore builds.  Be extremely\n// careful with their usage and use them only when the app is in an unrecoverable state.\n\n#include \"utils/debugging/detail/AssertInternals.hpp\"\n#include \"utils/platform/BuildOptions.hpp\"\n\n#include <cstdlib>\n#include <string>\n#include <string_view>\n\n// Aborts the application when releaseAssertsEnabled is true and the expression\n// evaluates to false.\n//\n// Usage:\n//   SC_ASSERT(expression)\n//   SC_ASSERT(expression, message)\n#define SC_ASSERT(...) _SC_PICK_ASSERTION_ARGS(__VA_ARGS__, _SC_WITH_MESSAGE, _SC_WITHOUT_MESSAGE)(__VA_ARGS__)\n\n// Prints the passed message and crashes the process when releaseAssertsEnabled is true.\n// Same as SC_ASSERT(false, message)\n//\n// Usage:\n//   SC_ASSERT_FAIL(message)\n#define SC_ASSERT_FAIL(message)                                                                                        \\\n    do {                                                                                                               \\\n        if constexpr (::snap::kAssertsCompiledIn) {                                                                    \\\n            if (::snap::releaseAssertsEnabled()) {                                                                     \\\n                _SC_SYSTEM_ASSERT_MAYBE_FUSED(__FILE__, __LINE__, ::snap::detail::messageToCString(message));          \\\n            }                                                                                                          \\\n        }                                                                                                              \\\n    } while (false)\n\n// Shortcut for nullptr check.\n//\n// This macro works will all pointer types including std::unique_ptr and std::shared_ptr.\n//\n// Usage:\n//   std::shared_ptr<T> myPtr = getSharedT();\n//   SC_ASSERT_NOTNULL(myPtr);\n#define SC_ASSERT_NOTNULL(expr) SC_ASSERT((expr) != nullptr)\n\n// Production assertion macro.\n//\n// ** BE EXTREMELY CAREFUL AND READ THIS DOCUMENTATION BEFORE USING **\n//\n// This will always abort the app when the condition evalutes to false, even in release builds.\n// Only use this for fatal, unrecoverable states that require us to crash at the site where the\n// unrecoverable state is found.\n//\n// For example, programming and logic errors which would leave the app in a broken and/or invalid\n// state.  In general, do not use this unless you are ready to treat the occurrence of this in a\n// release build as UBN.\n//\n// WARNING: The stringified expression and assert message will be embedded into the binary. Make\n//          sure you don't leak any private info!\n//\n// Usage:\n//   SC_ABORT(message)\n//   SC_ABORT_UNLESS(expression, message)\n#define SC_ABORT_UNLESS(expr, msg)                                                                                     \\\n    do {                                                                                                               \\\n        if (!(expr)) {                                                                                                 \\\n            if constexpr (::snap::kAssertsCompiledIn) {                                                                \\\n                _SC_CALL_SYSTEM_ASSERT(msg, #expr, __FILE__, __LINE__);                                                \\\n            } else {                                                                                                   \\\n                _SC_CALL_SYSTEM_ASSERT(msg, #expr, \"unknown\", __LINE__);                                               \\\n            }                                                                                                          \\\n        }                                                                                                              \\\n    } while (false)\n\n#define SC_ABORT(msg) SC_ABORT_UNLESS(false, msg)\n\nnamespace snap {\n\n// Returns true if SC_ASSERT is enabled. Used for disabling asserts in runtime.\nbool releaseAssertsEnabled();\n\n// Enables/disables SC_ASSERT\nvoid setEnableReleaseAsserts(bool enable);\n\n// Fuse the assertion. Returns true if assertion is fused by this call. Returns\n// false if assertion was already fused. In any case, when this call returns,\n// the assertion is in fused state.\nbool fuseAssertion(std::string_view key);\n\n// == FOR TESTING ONLY==\n// Clear all fused assertions. Next SC_ASSERT will trigger.\nvoid resetFusedAssertions();\n// == FOR TESTING ONLY==\n// Re-read fused assertions from persist storage.\nvoid reloadFusedAssertions();\n\n// Returns true if fused assertions are enabled\nbool fusedAssertsEnabled();\n\n// Enables/disables fused assertions\nvoid setEnableFusedAsserts(bool enable);\n\n} // namespace snap\n"
  },
  {
    "path": "libs/utils/src/utils/debugging/DjinniPrologue.hpp",
    "content": "#pragma once\n\n// Define DJINNI_FUNCTION_PROLOGUE to insert logging or tracing to Djinni calls.\n// For example: profiling::SCTrace<profiling::OsTraceEmitter> djinniTrace{\"Djinni:\" method};\n// Be careful not to use anything that depends on Djinni calls themselves,\n// otherwise it will form an infinite recursion.\n#define DJINNI_FUNCTION_PROLOGUE(method)\n"
  },
  {
    "path": "libs/utils/src/utils/debugging/Trace.cpp",
    "content": "#include \"utils/debugging/Trace.hpp\"\n\n#include <atomic>\n\n// for trace functions\n#if defined(SC_ANDROID)\n#include <android/trace.h>\n#include <dlfcn.h>\n#elif defined(SC_IOS)\n#include <os/signpost.h>\n#endif\n\nnamespace snap::profiling {\n\nstd::atomic<int> gTraceLevel = 0;\n\n// ------------------------------------------------------\n\n#if defined(SC_ANDROID)\nstruct TraceFunctions {\n    using TraceBeginSection = void (*)(const char* sectionName);\n    using TraceEndSection = void (*)();\n    using TraceBeginAsyncSection = void (*)(const char* sectionName, int32_t cookie);\n    using TraceEndAsyncSection = void (*)(const char* sectionName, int32_t cookie);\n\n    TraceBeginSection beginSection = [](const char* sectionName) {};\n    TraceEndSection endSection = [] {};\n    TraceBeginAsyncSection beginAsyncSection = [](const char* sectionName, int32_t cookie) {};\n    TraceEndAsyncSection endAsyncSection = [](const char* sectionName, int32_t cookie) {};\n\n    TraceFunctions() {\n        // TODO: remove dlopen() hacks when minAPI is bumped up to 23\n        void* lib = dlopen(\"libandroid.so\", RTLD_NOW | RTLD_LOCAL);\n        if (lib != nullptr) {\n            auto pBeginSection = reinterpret_cast<TraceBeginSection>(dlsym(lib, \"ATrace_beginSection\"));\n            auto pEndSection = reinterpret_cast<TraceEndSection>(dlsym(lib, \"ATrace_endSection\"));\n            auto pBeginAsyncSection = reinterpret_cast<TraceBeginAsyncSection>(dlsym(lib, \"ATrace_beginAsyncSection\"));\n            auto pEndAsyncSection = reinterpret_cast<TraceEndAsyncSection>(dlsym(lib, \"ATrace_endAsyncSection\"));\n            if (pBeginSection && pEndSection) {\n                beginSection = pBeginSection;\n                endSection = pEndSection;\n            }\n            if (pBeginAsyncSection && pEndAsyncSection) {\n                beginAsyncSection = pBeginAsyncSection;\n                endAsyncSection = pEndAsyncSection;\n            }\n        }\n    }\n\n    static TraceFunctions& get() {\n        static TraceFunctions traceFunctions;\n        return traceFunctions;\n    }\n};\n\nstatic std::atomic<int32_t> gCookie{1};\n\n// ------------------------------------------------------\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static, readability-make-member-function-const)\nvoid ATraceSectionEmitter::begin(const TraceBegin& traceBegin) {\n    TraceFunctions::get().beginSection(traceBegin.name.data());\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static, readability-make-member-function-const)\nvoid ATraceSectionEmitter::end(const TraceEnd& /*traceEnd*/) {\n    TraceFunctions::get().endSection();\n}\n\n// ------------------------------------------------------\n\nATraceAsyncSectionEmitter::ATraceAsyncSectionEmitter() {\n    _cookie = gCookie.fetch_add(1, std::memory_order_relaxed);\n}\n\n// NOLINTNEXTLINE(readability-make-member-function-const)\nvoid ATraceAsyncSectionEmitter::begin(const TraceBegin& traceBegin) {\n    TraceFunctions::get().beginAsyncSection(traceBegin.name.data(), _cookie);\n}\n\n// NOLINTNEXTLINE(readability-make-member-function-const)\nvoid ATraceAsyncSectionEmitter::end(const TraceEnd& traceEnd) {\n    TraceFunctions::get().endAsyncSection(traceEnd.name.data(), _cookie);\n}\n\n// ------------------------------------------------------\n\n#elif defined(SC_IOS)\n\nstatic os_log_t nativeSignpostLogger() {\n    if (__builtin_available(iOS 12.0, *)) {\n        static os_log_t logger = os_log_create(\"com.snap.native.signpost\", \"SCClient\");\n        return logger;\n    } else {\n        return nullptr;\n    }\n}\n\nIosSignpostEmitter::IosSignpostEmitter() {\n    if (__builtin_available(iOS 12.0, *)) {\n        _signpostId = os_signpost_id_generate(nativeSignpostLogger());\n    }\n}\n\nvoid IosSignpostEmitter::begin(const TraceBegin& traceBegin) {\n    if (__builtin_available(iOS 12.0, *)) {\n        os_signpost_interval_begin(\n            nativeSignpostLogger(), _signpostId, \"AsyncTrace\", \"%{public}s\", traceBegin.name.data());\n    }\n}\n\nvoid IosSignpostEmitter::step(const TraceStep<std::string_view>& traceStep) {\n    if (__builtin_available(iOS 12.0, *)) {\n        os_signpost_event_emit(nativeSignpostLogger(),\n                               _signpostId,\n                               \"AsyncTrace\",\n                               \"%{public}s:%{public}s\",\n                               traceStep.name.data(),\n                               traceStep.step.data());\n    }\n}\n\nvoid IosSignpostEmitter::end(const TraceEnd& traceEnd) {\n    if (__builtin_available(iOS 12.0, *)) {\n        os_signpost_interval_end(nativeSignpostLogger(), _signpostId, \"AsyncTrace\", \"%{public}s\", traceEnd.name.data());\n    }\n}\n\n#endif\n\nstd::atomic<detail::TraceSdkScopedTraceSupport*> scopedTraceSupportInstance = nullptr;\n\nvoid TraceSdkScopedTrace::initialize(detail::TraceSdkScopedTraceSupport* scopedTraceSupport) {\n    std::atomic_store_explicit(&scopedTraceSupportInstance, scopedTraceSupport, std::memory_order_relaxed);\n}\n\nTraceSdkScopedTrace::TraceSdkScopedTrace(const char* name) noexcept\n    : _scopedTraceSupport(std::atomic_load_explicit(&scopedTraceSupportInstance, std::memory_order_relaxed)) {\n    if (_scopedTraceSupport) {\n        _cookie = _scopedTraceSupport->beginSync(name);\n    }\n}\n\nTraceSdkScopedTrace::~TraceSdkScopedTrace() {\n    if (_scopedTraceSupport) {\n        _scopedTraceSupport->endSync(_cookie);\n    }\n}\n\nvoid TraceSdkScopedTrace::end() noexcept {\n    if (_scopedTraceSupport) {\n        _scopedTraceSupport->endSync(_cookie);\n        _scopedTraceSupport = nullptr;\n    }\n}\n\n} // namespace snap::profiling\n"
  },
  {
    "path": "libs/utils/src/utils/debugging/Trace.hpp",
    "content": "#pragma once\n\n#include \"utils/debugging/Assert.hpp\"\n#include \"utils/platform/TargetPlatform.hpp\"\n#include \"utils/time/BoottimeClock.hpp\"\n#include \"utils/time/UptimeClock.hpp\"\n\n#include <atomic>\n#include <chrono>\n#include <string>\n#include <type_traits>\n\nnamespace snap::profiling {\n\n#if defined(__APPLE__) || defined(SC_WASM)\n// align with iOS mach_absolute_time. Also use uptime for wasm, as boot-time is not supported in browsers.\nusing TraceClock = utils::time::UptimeClock;\n#else\n// match Android for elapsedRealtime.\nusing TraceClock = utils::time::BoottimeClock;\n#endif\n\n// Raise this above the default 0 to allow only traces initialized with greater\n// levels to pass\nextern std::atomic<int> gTraceLevel;\n\n// -------- Parameter types\n\nstruct TraceBegin { // used by the begin() method of emitters\n    std::string_view name;\n    TraceClock::time_point startTs;\n};\n\nstruct TraceEnd { // used by the end() method of emitters\n    std::string_view name;\n    TraceClock::time_point startTs;\n    TraceClock::time_point endTs;\n};\n\ntemplate<typename T>\nstruct TraceStep {\n    std::string_view name;\n    T step;\n    TraceClock::time_point ts;\n};\n\n// -------- Enum trace types/steps to string\n// Client code to overload with custom enum types\n// By default enums are converted to integers\ntemplate<typename T>\nstd::enable_if_t<std::is_enum_v<T>, std::string> toString(const T& e) {\n    return std::to_string(static_cast<int>(e));\n}\n\n// -------- Emitter classes\n\ntemplate<typename EnumT, size_t kSteps>\nclass LatencyRecorder {\npublic:\n    void begin(const TraceBegin& traceBegin) {\n        _steps[0] = traceBegin.startTs;\n    }\n    void step(const TraceStep<EnumT>& traceStep) {\n        SC_ASSERT(static_cast<size_t>(traceStep.step) < kSteps);\n        _steps[static_cast<size_t>(traceStep.step) + 1] = traceStep.ts;\n    }\n    void end(const TraceEnd& traceEnd) {\n        _steps[kSteps + 1] = traceEnd.endTs;\n    }\n    TraceClock::duration stepLatency(EnumT step) const {\n        SC_ASSERT(static_cast<size_t>(step) < kSteps);\n        auto tsBegin = _steps[static_cast<size_t>(step)];\n        auto tsEnd = _steps[static_cast<size_t>(step) + 1];\n        return tsEnd - tsBegin;\n    }\n\nprivate:\n    TraceClock::time_point _steps[kSteps + 2]; // add begin/end steps\n};\n\nclass NullEmitter {\npublic:\n    void begin(const TraceBegin& /*traceBegin*/) {}\n    void end(const TraceEnd& /*traceEnd*/) {}\n};\n\n#if defined(SC_ANDROID)\n// Wraps ATrace_beginSection\nclass ATraceSectionEmitter {\npublic:\n    ATraceSectionEmitter() = default;\n    ATraceSectionEmitter(ATraceSectionEmitter&&) = delete;\n\n    void begin(const TraceBegin& traceBegin);\n    void end(const TraceEnd& traceEnd);\n};\n\n// Wraps ATrace_beginAsyncSection\nclass ATraceAsyncSectionEmitter {\npublic:\n    ATraceAsyncSectionEmitter();\n\n    void begin(const TraceBegin& traceBegin);\n    void end(const TraceEnd& traceEnd);\n\nprotected:\n    int32_t _cookie = 0;\n};\n#endif\n\n#if defined(SC_IOS)\n// Wraps os_signpost_interval_begin\nclass IosSignpostEmitter {\npublic:\n    IosSignpostEmitter();\n\n    void begin(const TraceBegin& traceBegin);\n    void step(const TraceStep<std::string_view>& traceStep);\n    // if called with types other than string_view, expect a toString overload\n    // that converts it to string.\n    template<typename T>\n    void step(const TraceStep<T>& traceStep) {\n        step({traceStep.name, toString(traceStep.step), traceStep.ts});\n    }\n    void end(const TraceEnd& traceEnd);\n\nprotected:\n    uint64_t _signpostId = 0;\n};\n#endif\n\n// -------- Trace driver class\n\ntemplate<typename... T>\nclass TraceDriver : private T... {\n    using Expander = int[];\n\n    // Check if emitter has a step() method callable with `TraceStep<StepType>`\n    template<typename U, typename StepType, typename = void>\n    struct HasSteps : std::false_type {};\n\n    template<typename U, typename StepType>\n    struct HasSteps<U, StepType, decltype(std::declval<U>().step(std::declval<TraceStep<StepType>>()))>\n        : std::true_type {};\n\n    // Call the emitter's step() method when it's available\n    template<typename U, typename StepType>\n    void emitStep(const TraceStep<StepType>& traceStep) {\n        if constexpr (HasSteps<U, StepType>::value) {\n            U::step(traceStep);\n        }\n    }\n\npublic:\n    // The goal is to avoid allocation and copying when the parameter is a\n    // string literal. This is done by matching a char array with static\n    // size. It's probably not 100% bullet proof, but at least prevents most\n    // const char* and std::string.\n    template<size_t kSize>\n    explicit TraceDriver(const char (&name)[kSize], int level = 0) noexcept : _name(name, kSize - 1), _level(level) {\n        begin();\n    }\n\n    template<size_t kSize>\n    explicit TraceDriver(char (&name)[kSize], int level = 0) = delete;\n\n    // If the caller passes a dynamic string, then we have no choice but copy\n    // the string. We have to support this use case because it's quite common in\n    // Snap codebase.\n    explicit TraceDriver(std::string name, int level = 0) noexcept\n        : _nameStorage(std::move(name)), _name(_nameStorage), _level(level) {\n        begin();\n    }\n\n    TraceDriver(const TraceDriver&) = delete; // no copy\n\n    TraceDriver(TraceDriver&& other) noexcept // support move\n        : T(std::move(other))...,\n          _ended(other._ended),\n          _startTs(other._startTs),\n          _endTs(other._endTs),\n          _level(other._level) {\n        other._ended = true;\n        if (other._name.data() == other._nameStorage.data()) {\n            _nameStorage = std::move(other._nameStorage);\n            _name = _nameStorage;\n        } else {\n            _name = other._name;\n        }\n    }\n\n    ~TraceDriver() {\n        end();\n    }\n\n    // Forward to `end()` methods on emitters\n    void end() noexcept {\n        if constexpr (sizeof...(T) > 0) {\n            if (!_ended) {\n                _ended = true;\n                _endTs = TraceClock::now();\n                (void)Expander{(T::end({_name, _startTs, _endTs}), 0)...};\n            }\n        }\n    }\n\n    // Forward to `step()` methods on emitters\n    template<typename StepType>\n    void step(StepType step) {\n        if constexpr (sizeof...(T) > 0) {\n            if (!_ended) {\n                auto ts = TraceClock::now();\n                (void)Expander{(emitStep<T, StepType>({_name, step, ts}), 0)...};\n            }\n        }\n    }\n\n    TraceClock::duration latency() const {\n        SC_ASSERT(_ended);\n        return _endTs - _startTs;\n    }\n\n    // Return the result from the first emitter that implements a `stepLatency()` method\n    template<typename StepType>\n    auto stepLatency(StepType step) const {\n        return stepLatencyImpl<StepType, T...>(step, 0);\n    }\n\nprivate:\n    bool _ended = false;\n    std::string _nameStorage;\n    std::string_view _name;\n    TraceClock::time_point _startTs;\n    TraceClock::time_point _endTs;\n    const int _level;\n\n    // Forward to `begin()` methods on emitters\n    void begin() noexcept {\n        if constexpr (sizeof...(T) > 0) {\n            if (_level >= gTraceLevel.load(std::memory_order_relaxed)) {\n                _startTs = TraceClock::now();\n                (void)Expander{(T::begin({_name, _startTs}), 0)...};\n            } else {\n                _ended = true;\n            }\n        }\n    }\n\n    // Iterate through the emitter list and return the first `steps()` method\n    template<typename StepType, typename U, typename... Rest>\n    auto stepLatencyImpl(StepType step, ...) const {\n        return stepLatencyImpl<StepType, Rest...>(step, 0);\n    }\n    template<typename StepType, typename U, typename...>\n    decltype(U::stepLatency(std::declval<StepType>())) stepLatencyImpl(StepType step, int /*unused*/) const {\n        return U::stepLatency(step);\n    }\n};\n\n// Specialize for the empty emitter list case for a NO-OP trace driver\ntemplate<>\nclass TraceDriver<> {\npublic:\n    template<size_t kSize>\n    explicit constexpr TraceDriver(const char (& /*name*/)[kSize]) noexcept {}\n    explicit constexpr TraceDriver(const std::string& /*name*/) noexcept {}\n    TraceDriver(const TraceDriver&) = delete;\n    TraceDriver(TraceDriver&& other) noexcept {}\n    // If we change the next line to '~TraceDriver() = default;',\n    // we need to add '[[maybe_unused]]' in each use of TraceDriver<>,\n    // which is uglier than this NOLINT.\n    ~TraceDriver() noexcept {} // NOLINT(modernize-use-equals-default)\n    void end() noexcept {}\n    template<typename StepType>\n    void step(StepType /*step*/) noexcept {}\n    // NOLINTNEXTLINE(readability-convert-member-functions-to-static)\n    TraceClock::duration latency() const {\n        return {};\n    }\n    template<typename StepType>\n    auto stepLatency(StepType /*step*/) const {\n        return TraceClock::duration();\n    }\n};\n\ntemplate<typename... T>\nusing SCTrace = typename std::conditional<snap::kTracingEnabled, TraceDriver<T...>, TraceDriver<>>::type;\n\n// Do not include OS Trace Emitters in production-like builds as they incur significant overhead.\n#if defined(SC_ANDROID)\nusing OsTraceEmitter =\n    typename std::conditional<snap::kIsDevBuild, profiling::ATraceSectionEmitter, profiling::NullEmitter>::type;\nusing OsAsyncTraceEmitter =\n    typename std::conditional<snap::kIsDevBuild, profiling::ATraceAsyncSectionEmitter, profiling::NullEmitter>::type;\n#elif defined(SC_IOS)\nusing OsTraceEmitter = profiling::NullEmitter;\nusing OsAsyncTraceEmitter =\n    typename std::conditional<snap::kIsDevBuild, profiling::IosSignpostEmitter, profiling::NullEmitter>::type;\n#else\nusing OsTraceEmitter = profiling::NullEmitter;\nusing OsAsyncTraceEmitter = profiling::NullEmitter;\n#endif\n\nnamespace detail {\n// An internal interface for the Profiling module to inject an object that\n// provides TraceSDK based begin()/end() calls.\nstruct TraceSdkScopedTraceSupport {\n    virtual ~TraceSdkScopedTraceSupport() = default;\n    virtual int64_t beginSync(std::string_view label) = 0;\n    virtual void endSync(int64_t cookie) = 0;\n    virtual int64_t beginAsync(std::string_view label) = 0;\n    virtual void endAsync(int64_t cookie) = 0;\n    virtual void traceCounter(const std::string& name, int64_t count) = 0;\n};\n} // namespace detail\n\nextern std::atomic<detail::TraceSdkScopedTraceSupport*> scopedTraceSupportInstance;\n\n// Implement the SCTrace methods by forwarding to TraceSdkScopedTraceSupport.\nclass TraceSdkScopedTrace {\npublic:\n    explicit TraceSdkScopedTrace(const char* name) noexcept;\n    explicit TraceSdkScopedTrace(const std::string& name) noexcept : TraceSdkScopedTrace(name.data()) {}\n    TraceSdkScopedTrace(const TraceSdkScopedTrace&) = delete;\n\n    virtual ~TraceSdkScopedTrace();\n\n    void end() noexcept;\n\n    static void initialize(detail::TraceSdkScopedTraceSupport* scopedTraceSupport);\n\nprivate:\n    detail::TraceSdkScopedTraceSupport* _scopedTraceSupport;\n    int64_t _cookie;\n};\n\n} // namespace snap::profiling\n\n// Alias to utils::debugging namespace for compatibility\nnamespace snap::utils::debugging {\nusing ScopedTrace = typename std::\n    conditional<snap::kTracingEnabled, profiling::TraceSdkScopedTrace, ::snap::profiling::TraceDriver<>>::type;\n\n} // namespace snap::utils::debugging\n"
  },
  {
    "path": "libs/utils/src/utils/debugging/detail/AssertInternals.cpp",
    "content": "#include \"utils/debugging/detail/AssertInternals.hpp\"\n\n#include <atomic>\n#include <chrono>\n#include <cstdio>\n\nnamespace snap::detail {\n\nstd::string combineString(std::string_view msg, const char* expressionStr) {\n    if (!msg.empty()) {\n        std::string_view expr(expressionStr);\n        std::string out;\n        out.reserve(msg.length() + 2 + expr.length());\n        out += msg;\n        out += \": \";\n        out += expr;\n\n        return out;\n    }\n\n    return expressionStr;\n}\n\n} // namespace snap::detail\n\n#if defined(__APPLE__)\n\n#include <cstring>\n\nconst size_t __sc_assert_rtn_message_size = 1024;\nextern \"C\" char __sc_assert_rtn_message[1024] __attribute__((weak)) = {0};\n\n#if defined(NDEBUG)\nextern \"C\" __attribute__((noreturn)) __attribute__((noinline)) void __assert_rtn(const char*,\n                                                                                 const char*,\n                                                                                 int,\n                                                                                 const char*);\n#endif\n\n// Throwing function\n__attribute__((noreturn)) void __sc_apple_system_assert(const char* expr, const char* path, int line) {\n    std::strncpy(__sc_assert_rtn_message, expr, __sc_assert_rtn_message_size);\n    __sc_assert_rtn_message[__sc_assert_rtn_message_size - 1] = '\\0';\n    __assert_rtn(reinterpret_cast<const char*>(-1L), path, line, expr);\n}\n\n#endif\n"
  },
  {
    "path": "libs/utils/src/utils/debugging/detail/AssertInternals.hpp",
    "content": "#pragma once\n\n#include <cassert>\n#include <cstdlib>\n#include <string>\n#include <string_view>\n\n#if defined(__ANDROID__)\n#define _SC_SYSTEM_ASSERT(path, line, message) __assert(path, line, message)\n#elif defined(__APPLE__)\n__attribute__((noreturn)) void __sc_apple_system_assert(const char* expr, const char* path, int line);\n#define _SC_SYSTEM_ASSERT(path, line, message) __sc_apple_system_assert(message, path, line)\n#elif defined(__GLIBC__)\n// Declaring a function from assert.h. It's hidden if NDEBUG is defined\n// NOLINTNEXTLINE(readability-identifier-naming)\n__attribute__((noinline)) extern \"C\" void __assert(const char* assertion, const char* file, int line);\n#define _SC_SYSTEM_ASSERT(path, line, message) __assert(message, path, line)\n#elif defined(EMSCRIPTEN)\n#if defined(NDEBUG)\n// Declaring a function from assert.h. It's hidden if NDEBUG is defined\nvoid __assert_fail(const char*, const char*, int, const char*);\n#endif\n#define _SC_SYSTEM_ASSERT(path, line, message) __assert_fail(message, path, line, \"unknown_func\")\n#else\n#define _SC_SYSTEM_ASSERT(...) [&] { ::abort(); }()\n#endif\n\n// Release assertions are fused by default\n// Debug assertions are not fused by default\n// This can be overriden by defining _SC_ENABLE_FUSED_ASSERTION\n#if !defined(_SC_ENABLE_FUSED_ASSERTION)\n#if defined(NDEBUG) && !defined(EMSCRIPTEN)\n#define _SC_ENABLE_FUSED_ASSERTION 1\n#else\n#define _SC_ENABLE_FUSED_ASSERTION 0\n#endif\n#endif\n\n#if _SC_ENABLE_FUSED_ASSERTION\n#define _SC_SYSTEM_ASSERT_MAYBE_FUSED(path, line, message)                                                             \\\n    if (::snap::fuseAssertion(path \":\" #line)) {                                                                       \\\n        _SC_SYSTEM_ASSERT(path, line, message);                                                                        \\\n    } else {                                                                                                           \\\n        ::snap::detail::reportNonFatalAssert(path, line, message);                                                     \\\n    }\n#else\n#define _SC_SYSTEM_ASSERT_MAYBE_FUSED(path, line, message) _SC_SYSTEM_ASSERT(path, line, message)\n#endif\n\n// Helper macro, don't use in user code\n#define _SC_CALL_SYSTEM_ASSERT(msg, expressionStr, file, line)                                                         \\\n    _SC_SYSTEM_ASSERT(file, line, ::snap::detail::combineString(msg, expressionStr).c_str());\n#define _SC_CALL_SYSTEM_ASSERT_MAYBE_FUSED(msg, expressionStr, file, line)                                             \\\n    _SC_SYSTEM_ASSERT_MAYBE_FUSED(file, line, ::snap::detail::combineString(msg, expressionStr).c_str());\n\n// Helper macro, don't use in user code\n#define _SC_WITH_MESSAGE(expr, msg)                                                                                    \\\n    do {                                                                                                               \\\n        if constexpr (::snap::kAssertsCompiledIn) {                                                                    \\\n            if (::snap::releaseAssertsEnabled() && !(expr)) {                                                          \\\n                _SC_CALL_SYSTEM_ASSERT_MAYBE_FUSED(msg, #expr, __FILE__, __LINE__);                                    \\\n            }                                                                                                          \\\n        }                                                                                                              \\\n    } while (false)\n\n#define _SC_WITHOUT_MESSAGE(expr)                                                                                      \\\n    do {                                                                                                               \\\n        if constexpr (::snap::kAssertsCompiledIn) {                                                                    \\\n            if (::snap::releaseAssertsEnabled() && !(expr)) {                                                          \\\n                _SC_CALL_SYSTEM_ASSERT_MAYBE_FUSED(\"\", #expr, __FILE__, __LINE__);                                     \\\n            }                                                                                                          \\\n        }                                                                                                              \\\n    } while (false)\n\n#define _SC_PICK_ASSERTION_ARGS(_1, _2, SC_WHICH, ...) SC_WHICH\n\nnamespace snap::detail {\n\n// Helper function to combine expression string and user message\nstd::string combineString(std::string_view msg, const char* expressionStr);\n\ninline const char* messageToCString(const char* s) {\n    return s;\n}\ninline const char* messageToCString(const std::string& s) {\n    return s.c_str();\n}\n\nvoid reportNonFatalAssert(std::string_view path, int64_t line, std::string_view message);\n\n} // namespace snap::detail\n"
  },
  {
    "path": "libs/utils/src/utils/encoding/Base64Utils.cpp",
    "content": "#include \"utils/encoding/Base64Utils.hpp\"\n\n#include <boost/algorithm/string.hpp>\n#include <openssl/base64.h>\n\n#include <algorithm>\n#include <cstring>\n#include <string>\n#include <vector>\n\n// We wrap the BoringSSL Base64 encoding/decoding functions\nnamespace snap::utils::encoding {\n\nstd::string binaryToBase64(const uint8_t* data, size_t size) {\n    size_t maxOutSize = 0;\n    if (size == 0 || EVP_EncodedLength(&maxOutSize, size) != 1 || maxOutSize == 0) {\n        return \"\";\n    }\n\n    std::string result(maxOutSize, '\\0');\n    EVP_EncodeBlock(reinterpret_cast<uint8_t*>(result.data()), data, size);\n    result.resize(result.size() - 1); // remove the trailing \\0 that EVP_EncodeBlock always writes\n    return result;\n}\n\nstd::string binaryToBase64(const std::vector<uint8_t>& binary) {\n    return binaryToBase64(binary.data(), binary.size());\n}\n\nstd::string binaryToBase64(const std::string& binary) {\n    return binaryToBase64(reinterpret_cast<const uint8_t*>(binary.data()), binary.size());\n}\n\nstd::string uint64ToBase64(uint64_t data) {\n    std::array<uint8_t, sizeof(data)> bytes;\n    for (size_t i = 0; i < 8; i++) {\n        bytes.at(i) = (data >> (i * 8)) & 0xFF;\n    }\n    return binaryToBase64(bytes.data(), bytes.size());\n}\n\nbool base64ToBinaryInternal(const char* encodedString, size_t inSize, std::vector<uint8_t>* ret) {\n    // Strip out newlines since the decoder returns an error code (0) if it finds them within the encoded string.\n    std::string noNewlines(encodedString, inSize);\n    boost::algorithm::replace_all(noNewlines, \"\\n\", \"\");\n    boost::algorithm::replace_all(noNewlines, \"\\r\", \"\");\n\n    // Determine the max array length we'll need given the string length\n    size_t maxOutSize = 0;\n    if (EVP_DecodedLength(&maxOutSize, noNewlines.length()) != 1 || maxOutSize == 0) {\n        return false;\n    }\n\n    ret->resize(maxOutSize);\n    size_t outSize = 0;\n    if (EVP_DecodeBase64(reinterpret_cast<uint8_t*>(ret->data()),\n                         &outSize,\n                         maxOutSize,\n                         reinterpret_cast<const uint8_t*>(noNewlines.c_str()),\n                         noNewlines.length()) != 1) {\n        // make it empty to indicate error\n        ret->resize(0);\n        return false;\n    }\n\n    ret->resize(outSize);\n    return true;\n}\n\nstd::vector<uint8_t> base64ToBinary(std::string_view base64) {\n    std::vector<uint8_t> decodedData;\n    base64ToBinaryInternal(base64.data(), base64.size(), &decodedData);\n    return decodedData;\n}\n\nbool base64ToBinary(std::string_view base64, std::vector<uint8_t>& decodedData) {\n    return base64ToBinaryInternal(base64.data(), base64.size(), &decodedData);\n}\n\nuint64_t base64ToUInt64(const std::string& base64) {\n    std::vector<uint8_t> bytes = base64ToBinary(base64);\n    uint64_t retVal = 0;\n\n    for (int i = std::min(static_cast<int>(bytes.size()), 8) - 1; i >= 0; i--) {\n        retVal <<= 8;\n        retVal |= bytes[i];\n    }\n\n    return retVal;\n}\n\nstd::string base64UrlToBase64(const std::string& base64url) {\n    std::string temp;\n    temp.reserve(base64url.size() + 4);\n\n    // change Base64 alphabet from urlsafe version to standard\n    for (const auto& c : base64url) {\n        if (c == '-') {\n            temp += '+';\n        } else if (c == '_') {\n            temp += '/';\n        } else {\n            temp += c;\n        }\n    }\n\n    // add padding\n    if ((base64url.size() % 4) != 0u) {\n        int toAppend = 4 - static_cast<int>(base64url.size() % 4);\n        for (int i = 0; i < toAppend; i++) {\n            temp += '=';\n        }\n    }\n\n    return temp;\n}\n\nstd::string base64ToBase64Url(const std::string& base64) {\n    std::string temp(base64);\n\n    // remove padding\n    size_t found = temp.find_last_not_of('=');\n    if (found == std::string::npos)\n        return \"\";\n\n    // change Base64 alphabet from standard version to urlsafe\n    boost::algorithm::replace_all(temp, \"+\", \"-\");\n    boost::algorithm::replace_all(temp, \"/\", \"_\");\n\n    return temp.substr(0, found + 1);\n}\n\n} // namespace snap::utils::encoding\n"
  },
  {
    "path": "libs/utils/src/utils/encoding/Base64Utils.hpp",
    "content": "#pragma once\n\n#include <string>\n#include <vector>\n\nnamespace snap::utils::encoding {\n\n/**\n * @brief Base64 encode the uint8_t buffer and return the result as a string.\n * No newlines are inserted into the result.\n */\nstd::string binaryToBase64(const uint8_t* data, size_t size);\n\n/**\n * @brief Base64 encode the uint8_t vector and return the result as a string.\n * No newlines are inserted into the result.\n */\nstd::string binaryToBase64(const std::vector<uint8_t>& binary);\n\n/**\n * @brief Base64 encode the bytes in the string and return the result as a string.\n * No newlines are inserted into the result.\n */\nstd::string binaryToBase64(const std::string& binary);\n\n/**\n * @brief Interpret the uint64_t as an 8-byte binary value, Base64 encode it and\n * return the result as a string. No newlines are inserted into the result.\n */\nstd::string uint64ToBase64(uint64_t data);\n\n/**\n * @brief Base64 decode the string and store the resulting bytes in the returned vector.\n * Newlines are stripped from the string before decoding.\n * Returns empty vector if failed to decode.\n */\nstd::vector<uint8_t> base64ToBinary(std::string_view base64);\n\n/**\n * @brief Base64 decode the string and store the resulting bytes in the |decoded| vector.\n * Newlines are stripped from the string before decoding.\n * Returns false if failed to decode.\n */\nbool base64ToBinary(std::string_view base64, std::vector<uint8_t>& decoded);\n\n/**\n * @brief Base64 decode the string and store the first 8-bytes of the result in the\n * returned uint64_t. If the result is more than 8-bytes then it will be truncated.\n * If the result is less than 8-bytes then the remaining bytes in the uint64_t will\n * be 0x00.\n */\nuint64_t base64ToUInt64(const std::string& base64);\n\n/**\n * @brief Convert the Base64 URL string to standard Base64.\n * See RFC 4648 'Table 2: The \"URL and Filename safe\" Base 64 Alphabet'\n */\nstd::string base64UrlToBase64(const std::string& base64url);\n\n/**\n * @brief Convert the Base64 string to a Base64 URL string.\n * See RFC 4648 'Table 2: The \"URL and Filename safe\" Base 64 Alphabet'\n */\nstd::string base64ToBase64Url(const std::string& base64);\n\n} // namespace snap::utils::encoding\n"
  },
  {
    "path": "libs/utils/src/utils/logging/Log.hpp",
    "content": "#pragma once\n\n#include \"utils/logging/Logger.hpp\"\n#include \"utils/platform/BuildOptions.hpp\"\n#include \"utils/platform/TargetPlatform.hpp\"\n\n#include <fmt/format.h>\n\nnamespace snap {\nnamespace utils::logging {\n\n// TODO: Move this logic out to build scripts and just plumb in the enum value\nconstexpr auto kMinAllowedLogLevel = []() constexpr {\n    if constexpr (!kLoggingCompiledIn) {\n        return LogLevel::None;\n    }\n\n    if constexpr (isWasm()) {\n        if constexpr (kIsDevBuild) {\n            // Verbose logs can be very noisy, let's try debug for now.\n            return LogLevel::Debug;\n        } else {\n            // Logs are compiled out in prod currently, so this level is mainly for gold/alpha.\n            return LogLevel::Info;\n        }\n    }\n\n    // TODO: Drive off of build flavors not libc macros!\n    if constexpr (isSystemDebug()) {\n        return LogLevel::Verbose;\n    }\n\n    if constexpr (isDesktop()) {\n        // Mac and linux disable noisy debug logs.\n        return LogLevel::Info;\n    } else {\n        return LogLevel::Debug;\n    }\n}();\n\ntemplate<LogLevel logLevel, typename FmtString, typename... Args>\nvoid log(LogContext context, const std::string& tag, FmtString&& formatStr, Args&&... args) {\n    static_assert(logLevel != LogLevel::None, \"NONE cannot be used for actual logging\");\n\n    if constexpr (logLevel >= kMinAllowedLogLevel) {\n        // logging allowed for this level, forwarding into fmtlib\n        logToExternalLogger(\n            logLevel, context, tag, fmt::format(std::forward<FmtString>(formatStr), std::forward<Args>(args)...));\n    }\n}\n} // namespace utils::logging\n\n///\n/// Set of helper functions for every log level, put directly in ::snap namespace to avoid unnecessary typing of full\n/// namespace in user code.\n///\n\ntemplate<typename FmtString, typename... Args>\nvoid logVerbose(utils::logging::LogContext context, const std::string& tag, FmtString&& formatStr, Args&&... args) {\n    utils::logging::log<utils::logging::LogLevel::Verbose>(\n        context, tag, std::forward<FmtString>(formatStr), std::forward<Args>(args)...);\n}\n\ntemplate<typename FmtString, typename... Args>\nvoid logDebug(utils::logging::LogContext context, const std::string& tag, FmtString&& formatStr, Args&&... args) {\n    utils::logging::log<utils::logging::LogLevel::Debug>(\n        context, tag, std::forward<FmtString>(formatStr), std::forward<Args>(args)...);\n}\n\ntemplate<typename FmtString, typename... Args>\nvoid logInfo(utils::logging::LogContext context, const std::string& tag, FmtString&& formatStr, Args&&... args) {\n    utils::logging::log<utils::logging::LogLevel::Info>(\n        context, tag, std::forward<FmtString>(formatStr), std::forward<Args>(args)...);\n}\n\ntemplate<typename FmtString, typename... Args>\nvoid logWarn(utils::logging::LogContext context, const std::string& tag, FmtString&& formatStr, Args&&... args) {\n    utils::logging::log<utils::logging::LogLevel::Warn>(\n        context, tag, std::forward<FmtString>(formatStr), std::forward<Args>(args)...);\n}\n\ntemplate<typename FmtString, typename... Args>\nvoid logError(utils::logging::LogContext context, const std::string& tag, FmtString&& formatStr, Args&&... args) {\n    utils::logging::log<utils::logging::LogLevel::Error>(\n        context, tag, std::forward<FmtString>(formatStr), std::forward<Args>(args)...);\n}\n} // namespace snap\n\n#if SC_LOGGING_COMPILED_IN()\n// Used when logging from another data source where file/log line is not useful.\n#define SCLOG_GENERIC_NO_FILE(context, level, tag, fmtString, ...)                                                     \\\n    ::snap::utils::logging::log<level>(context, tag, FMT_STRING(fmtString), ##__VA_ARGS__)\n#define SC_STRINGIZE(x) SC_STRINGIZE2(x)\n#define SC_STRINGIZE2(x) #x\n#define SCLOG_GENERIC(context, level, tag, fmtString, ...)                                                             \\\n    ::snap::utils::logging::log<level>(                                                                                \\\n        context, tag, FMT_STRING(\"[\" __FILE_NAME__ \":\" SC_STRINGIZE(__LINE__) \"] \" fmtString), ##__VA_ARGS__)\n#else\n#define SCLOG_GENERIC_NO_FILE(context, level, tag, fmtString, ...)                                                     \\\n    {                                                                                                                  \\\n        (void)tag;                                                                                                     \\\n    }\n#define SCLOG_GENERIC(context, level, tag, fmtString, ...)                                                             \\\n    {                                                                                                                  \\\n        (void)tag;                                                                                                     \\\n    }\n#endif\n\n///\n/// Set of macros that check formatting string against the supplied arguments and fail to compile if they don't match.\n/// NOTE: formatting string must be supplied directly as a string literal. Passing std::string or a pointer to the\n/// existing string won't work.\n/// For example:\n/// SCLOG_I(kTag, \"Result of operation is {} for {}\", arg1, arg2); // GOOD\n///\n/// std::string fmtString = \"Result of operation is {} for {}\";\n/// SCLOG_I(kTag, fmtString, arg1, arg2); // BAD, reports some obscure compilation error\n/// logVerbose(kTag, fmtString, arg1, arg2); // GOOD, but no compile-time check for the formatting string\n///\n\n#define SCLOGV(tag, fmtString, ...)                                                                                    \\\n    SCLOG_GENERIC(::snap::utils::logging::LogContext::General,                                                         \\\n                  ::snap::utils::logging::LogLevel::Verbose,                                                           \\\n                  tag,                                                                                                 \\\n                  fmtString,                                                                                           \\\n                  ##__VA_ARGS__)\n#define SCLOGD(tag, fmtString, ...)                                                                                    \\\n    SCLOG_GENERIC(::snap::utils::logging::LogContext::General,                                                         \\\n                  ::snap::utils::logging::LogLevel::Debug,                                                             \\\n                  tag,                                                                                                 \\\n                  fmtString,                                                                                           \\\n                  ##__VA_ARGS__)\n#define SCLOGI(tag, fmtString, ...)                                                                                    \\\n    SCLOG_GENERIC(::snap::utils::logging::LogContext::General,                                                         \\\n                  ::snap::utils::logging::LogLevel::Info,                                                              \\\n                  tag,                                                                                                 \\\n                  fmtString,                                                                                           \\\n                  ##__VA_ARGS__)\n#define SCLOGW(tag, fmtString, ...)                                                                                    \\\n    SCLOG_GENERIC(::snap::utils::logging::LogContext::General,                                                         \\\n                  ::snap::utils::logging::LogLevel::Warn,                                                              \\\n                  tag,                                                                                                 \\\n                  fmtString,                                                                                           \\\n                  ##__VA_ARGS__)\n#define SCLOGE(tag, fmtString, ...)                                                                                    \\\n    SCLOG_GENERIC(::snap::utils::logging::LogContext::General,                                                         \\\n                  ::snap::utils::logging::LogLevel::Error,                                                             \\\n                  tag,                                                                                                 \\\n                  fmtString,                                                                                           \\\n                  ##__VA_ARGS__)\n\n#define SCLOGCONTEXTV(tag, logContext, fmtString, ...)                                                                 \\\n    SCLOG_GENERIC(logContext, ::snap::utils::logging::LogLevel::Verbose, tag, fmtString, ##__VA_ARGS__)\n#define SCLOGCONTEXTD(tag, logContext, fmtString, ...)                                                                 \\\n    SCLOG_GENERIC(logContext, ::snap::utils::logging::LogLevel::Debug, tag, fmtString, ##__VA_ARGS__)\n#define SCLOGCONTEXTI(tag, logContext, fmtString, ...)                                                                 \\\n    SCLOG_GENERIC(logContext, ::snap::utils::logging::LogLevel::Info, tag, fmtString, ##__VA_ARGS__)\n#define SCLOGCONTEXTW(tag, logContext, fmtString, ...)                                                                 \\\n    SCLOG_GENERIC(logContext, ::snap::utils::logging::LogLevel::Warn, tag, fmtString, ##__VA_ARGS__)\n#define SCLOGCONTEXTE(tag, logContext, fmtString, ...)                                                                 \\\n    SCLOG_GENERIC(logContext, ::snap::utils::logging::LogLevel::Error, tag, fmtString, ##__VA_ARGS__)\n"
  },
  {
    "path": "libs/utils/src/utils/logging/Logger.cpp",
    "content": "#include \"utils/logging/Logger.hpp\"\n#include \"utils/platform/TargetPlatform.hpp\"\n\n#include <atomic>\n#include <fmt/chrono.h>\n#include <fmt/format.h>\n\n// a bunch of headrs only needed on desktop\n#if defined(SC_DESKTOP) || defined(EMSCRIPTEN)\n#include <cstdio>\n#include <fmt/color.h>\n#include <fmt/ostream.h>\n#include <sys/time.h>\n#include <thread>\n#endif\n\nnamespace snap::utils::logging {\nnamespace {\n// Global variable for logging facility\n// Intentionally using a raw pointer and allocating this on the heap to make sure the logger is not destroyed\n// on app exit.\n// std::atomic is trivallly destructible and hence is not cleaned up on program shutdown and are safe to access\n// from other code running during shutdown.\n// https://github.com/abseil/abseil-cpp/blob/389ec3f906f018661a5308458d623d01f96d7b23/absl/base/const_init.h#L42\n// NOLINTNEXTLINE(fuchsia-statically-constructed-objects)\nstd::atomic<Logger*> gExternalLogger;\n\n// Maximum allowed log level when no external logger is specified\nLogLevel gMaxInternalLogLevel = LogLevel::Verbose;\n\n} // namespace\n\nvoid logToExternalLogger(LogLevel logLevel, LogContext logContext, const std::string& tag, const std::string& message) {\n    if (auto* logger = gExternalLogger.load()) {\n        try {\n            logger->log(logLevel, logContext, tag, message);\n        } catch (std::range_error&) {\n            logger->log(logLevel, logContext, tag, \"[INVALID LOG MESSAGE]\");\n        }\n    } else {\n        if (logLevel < gMaxInternalLogLevel) {\n            return;\n        }\n\n#if defined(SC_DESKTOP) || defined(EMSCRIPTEN)\n        auto logLevelToStr = [](LogLevel level) {\n            switch (level) {\n                case LogLevel::Verbose:\n                    return \"VERBOSE\";\n                case LogLevel::Debug:\n                    return \"DEBUG\";\n                case LogLevel::Info:\n                    return \"INFO\";\n                case LogLevel::Warn:\n                    return \"WARN\";\n                case LogLevel::Error:\n                    return \"ERROR\";\n                case LogLevel::None:\n                    return \"NONE\";\n            }\n        };\n\n        auto logContextToStr = [](LogContext context) {\n            switch (context) {\n                case LogContext::Chat:\n                    return \"Chat\";\n                case LogContext::ContentManager:\n                    return \"ContentManager\";\n                case LogContext::General:\n                    return \"General\";\n                case LogContext::GRPC:\n                    return \"GRPC\";\n                case LogContext::GRPCTrace:\n                    return \"GRPCTrace\";\n                case LogContext::Map:\n                    return \"Map\";\n                case LogContext::Network:\n                    return \"Network\";\n                case LogContext::Duplex:\n                    return \"Duplex\";\n                case LogContext::Talk:\n                    return \"Talk\";\n                case LogContext::Core:\n                    return \"Core\";\n                case LogContext::CUPS:\n                    return \"CUPS\";\n                case LogContext::Ad:\n                    return \"Ad\";\n                case LogContext::TIV:\n                    return \"TIV\";\n                case LogContext::OnDeviceML:\n                    return \"OnDeviceML\";\n                case LogContext::DeepLinkResolution:\n                    return \"DeepLinkResolution\";\n                case LogContext::Notifications:\n                    return \"Notifications\";\n                case LogContext::S2REvent:\n                    return \"S2REvent\";\n                case LogContext::Atlas:\n                    return \"Atlas\";\n                case LogContext::NeoPlayer:\n                    return \"NeoPlayer\";\n                case LogContext::MediaStrategyCenter:\n                    return \"MediaStrategyCenter\";\n            }\n        };\n\n#if defined(EMSCRIPTEN)\n\n        fmt::print(\"[{}] {} {} {}\\n\", logLevelToStr(logLevel), logContextToStr(logContext), tag, message);\n\n#else // defined(EMSCRIPTEN)\n\n        timeval curTime;\n        gettimeofday(&curTime, nullptr);\n        int64_t milliseconds = curTime.tv_sec * 1000 + curTime.tv_usec / 1000;\n        auto getStyle = [&] {\n            static bool useColor = getenv(\"TERM\") != nullptr;\n            if (!useColor) {\n                return fmt::text_style();\n            }\n            switch (logLevel) {\n                case LogLevel::Warn:\n                    return fmt::fg(fmt::terminal_color::yellow);\n                case LogLevel::Error:\n                    return fmt::fg(fmt::terminal_color::red);\n                default:\n                    return fmt::fg(fmt::terminal_color::white);\n            }\n        };\n        fmt::print(getStyle(),\n                   \"[{}][{:<14}] [{}] {} {} {}\",\n                   logLevelToStr(logLevel),\n                   std::this_thread::get_id(),\n                   millisecondsToString(milliseconds),\n                   logContextToStr(logContext),\n                   tag,\n                   message);\n        fmt::print(\"\\n\");\n\n#endif // defined(EMSCRIPTEN)\n\n#endif // defined(SC_DESKTOP) || defined(EMSCRIPTEN)\n    }\n}\n\nvoid setExternalLogger(Logger* logger) {\n    gExternalLogger.store(logger);\n}\n\nvoid setInternalLoggerLogLevel(LogLevel maxLogLevel) {\n    gMaxInternalLogLevel = maxLogLevel;\n}\n\nstd::string millisecondsToString(int64_t milliseconds) {\n    return fmt::format(\n        \"{:%Y-%m-%d %H:%M:%S}.{:0>3}\", fmt::localtime(static_cast<time_t>(milliseconds / 1000)), milliseconds % 1000);\n}\n\nstd::string secondsToString(int64_t seconds) {\n    return fmt::format(\"{:%Y-%m-%d %H:%M:%S}\", fmt::localtime(static_cast<time_t>(seconds)));\n}\n\n} // namespace snap::utils::logging\n"
  },
  {
    "path": "libs/utils/src/utils/logging/Logger.hpp",
    "content": "#pragma once\n\n#include <memory>\n#include <string>\n\nnamespace snap::utils::logging {\n\nenum class LogLevel { Verbose, Debug, Info, Warn, Error, None };\n/**\n * When adding a new context, make sure to update shims.djinni.\n */\nenum class LogContext {\n    General,\n    Chat,\n    ContentManager,\n    GRPC,\n    GRPCTrace,\n    Network,\n    Duplex,\n    Talk,\n    Core,\n    CUPS,\n    Ad,\n    TIV,\n    Map,\n    OnDeviceML,\n    DeepLinkResolution,\n    Notifications,\n    S2REvent,\n    Atlas,\n    NeoPlayer,\n    MediaStrategyCenter\n};\n\n/**\n * Callback interface for logger\n */\nclass Logger {\npublic:\n    virtual ~Logger() = default;\n    virtual void log(LogLevel logLevel, LogContext logContext, const std::string& tag, const std::string& message) = 0;\n};\n\n/**\n * @brief Sets global logger instance. Keeps reference to the logger instance.\n * Call with empty shared pointer if you want to fall back to console/file logger.\n */\nvoid setExternalLogger(Logger* logger);\n\n/**\n * @brief Logs to log set by setExternalLogger. If logger is not set, logging is redirected to console/file.\n */\nvoid logToExternalLogger(LogLevel logLevel, LogContext logContext, const std::string& tag, const std::string& message);\n\n/**\n * @brief Sets max log level for cases when external logger is not specified\n */\nvoid setInternalLoggerLogLevel(LogLevel maxLogLevel);\n\n/**\n * @brief Formats milliseconds since epoch into a local time string for logging\n */\nstd::string millisecondsToString(int64_t milliseconds);\n\n/**\n * @brief Formats seconds since epoch into a local time string for logging\n */\nstd::string secondsToString(int64_t seconds);\n} // namespace snap::utils::logging\n"
  },
  {
    "path": "libs/utils/src/utils/platform/BuildOptions.hpp",
    "content": "#pragma once\n\n#if __has_include(\"build_options/BuildOptionsGenerated.hpp\")\n#include \"build_options/BuildOptionsGenerated.hpp\"\n#else\n// Fallback for cmake based builds, we keep all flags enabled\n// by default in this scenario.\n#include \"utils/platform/BuildOptionsDefault.hpp\"\n#endif\n"
  },
  {
    "path": "libs/utils/src/utils/platform/BuildOptionsDefault.hpp",
    "content": "#pragma once\n\nnamespace snap {\n\n// Controls the way SC_ASSERT is embedded into the final binary. Asserts are compiled out if set to false.\nconstexpr bool kAssertsCompiledIn = true;\n\nconstexpr bool kLoggingCompiledIn = true;\n// Macros version that can be used in #if expressions\n#define SC_LOGGING_COMPILED_IN() true\n\n// Controls tracing being compiled in. Not enabled if set to false.\nconstexpr bool kTracingEnabled = true;\n#define SC_TRACING_COMPILED_IN() true\n\n// If this build is a development build\nconstexpr bool kIsDevBuild = true;\n\nconstexpr bool kIsGoldBuild = false;\n\nconstexpr bool kIsAppstoreBuild = false;\n\nconstexpr bool kIsAlphaBuild = false;\n\n} // namespace snap\n"
  },
  {
    "path": "libs/utils/src/utils/platform/BuildOptionsGenerated.hpp.in",
    "content": "#pragma once\n\n// NOTE: This header is auto-generated. Don't use it directly. Do #include \"utils/platform/BuildFlags.hpp\" instead\n\nnamespace snap {\n\n// Controls the way SC_ASSERT is embedded into the final binary. Asserts are compiled out if set to false.\nconstexpr bool kAssertsCompiledIn = @SC_BUILD_FLAG_ASSERT@;\n\n// Controls the way log insructions are embedded into the final binary. Logging is compiled out if set to false.\nconstexpr bool kLoggingCompiledIn = @SC_BUILD_FLAG_LOGGING@;\n// Macros version that can be used in #if expressions\n#define SC_LOGGING_COMPILED_IN() @SC_BUILD_FLAG_LOGGING@\n\n// Controls tracing being compiled in. Not enabled if set to false.\nconstexpr bool kTracingEnabled = @SC_BUILD_FLAG_TRACING@;\n#define SC_TRACING_COMPILED_IN() @SC_BUILD_FLAG_TRACING@\n\n// If this build is a development build\nconstexpr bool kIsDevBuild = @SC_BUILD_FLAG_DEV@;\n\nconstexpr bool kIsGoldBuild = @SC_BUILD_FLAG_GOLD@;\n\nconstexpr bool kIsAppstoreBuild = @SC_BUILD_FLAG_APPSTORE@;\n\nconstexpr bool kIsAlphaBuild = @SC_BUILD_FLAG_ALPHA@;\n\n} // namespace snap\n"
  },
  {
    "path": "libs/utils/src/utils/platform/JNITypeStubs.hpp",
    "content": "#pragma once\n\n// You can include this on any platform (android/ios/pc) and it'll replace the\n// JNI types with dummy types on non-android.\n\n#ifdef __ANDROID__\n#include <jni.h> // for JNINativeMethod; it's a typedef of an anonymous struct so we can't forward declare it\n\nstruct _JavaVM;\nstruct _JNIEnv;\nusing JavaVM = _JavaVM;\nusing JNIEnv = _JNIEnv;\n#else\nstruct JNINativeMethod {};\n\nstruct JavaVM_;\nstruct JNIEnv_;\nclass _jobject {};\n\nusing JavaVM = JavaVM_;\nusing JNIEnv = JNIEnv_;\nusing jobject = _jobject*;\n#endif\n"
  },
  {
    "path": "libs/utils/src/utils/platform/JvmOnLoad.cpp",
    "content": "#include \"utils/platform/JvmOnLoad.hpp\"\n\n#include \"utils/platform/TargetPlatform.hpp\"\n\n#if defined(SC_ANDROID)\n\nnamespace snap::utils::platform::jni {\n\nstd::vector<JniInitializer>& getInitializersVector() {\n    static std::vector<JniInitializer> initializers;\n    return initializers;\n}\nvoid runOnLoadInitializers(JNIEnv* env) {\n    auto& initializers = getInitializersVector();\n    for (auto& initializer : initializers) {\n        initializer(env);\n    }\n    initializers.clear();\n}\n\n} // namespace snap::utils::platform::jni\n\n#endif\n"
  },
  {
    "path": "libs/utils/src/utils/platform/JvmOnLoad.hpp",
    "content": "#include \"utils/platform/TargetPlatform.hpp\"\n\n#if defined(SC_ANDROID)\n\n#include <jni.h>\n#include <vector>\n\n// Provides a way for you to run your own code during JNI_OnLoad. Typically\n// this would be used to register JNI methods.\n\nnamespace snap::utils::platform::jni {\nvoid runOnLoadInitializers(JNIEnv* env);\nusing JniInitializer = void (*)(JNIEnv*);\nstd::vector<JniInitializer>& getInitializersVector();\n} // namespace snap::utils::platform::jni\n\n#define SNAP_JNI_DEFINE_INITIALIZER(initializer)                                                                       \\\n    static __attribute__((constructor)) void registerOnLoadInitializer(void) {                                         \\\n        snap::utils::platform::jni::getInitializersVector().push_back(initializer);                                    \\\n    }\n\n#endif\n"
  },
  {
    "path": "libs/utils/src/utils/platform/JvmUtils.cpp",
    "content": "#ifdef ANDROID_WITH_JNI\n\n#include \"utils/platform/JvmUtils.hpp\"\n\n#include \"utils/debugging/Assert.hpp\"\n#include \"utils/debugging/Trace.hpp\"\n#include \"utils/platform/JvmOnLoad.hpp\"\n\n#include <fmt/format.h>\n\n#include <android/log.h>\n#include <cassert>\n#include <djinni/jni/djinni_support.hpp>\n#include <jni.h>\n#include <pthread.h>\n\n// This implementation is based on code from\n// https://chromium.googlesource.com/external/webrtc/+/HEAD/sdk/android/src/jni/jvm.cc\n\nnamespace snap::utils::platform {\n\nnamespace {\n// Global JVM reference that was passed by the app\nJavaVM* gJvm = nullptr;\n\n// Key for per-thread JNIEnv* data.  Non-NULL in threads attached to |gJvm| by\n// AttachCurrentThreadIfNeeded(), NULL in unattached threads and threads that\n// were attached by the JVM because of a Java->native call.\npthread_key_t gJniPtr;\n\nvoid threadDestructor([[maybe_unused]] void* prevJniPtr) {\n    // This function only runs on threads where gJniPtr is non-null, meaning\n    // we were responsible for originally attaching the thread, so are responsible\n    // for detaching it now.  However, because some JVM implementations (notably\n    // Oracle's http://goo.gl/eHApYT) also use the pthread_key_create mechanism,\n    // the JVMs accounting info for this thread may already be wiped out by the\n    // time this is called. Thus it may appear we are already detached even though\n    // it was our responsibility to detach!  Oh well.\n    if (getEnv() == nullptr)\n        return;\n\n    assert(getEnv() == prevJniPtr);\n    [[maybe_unused]] jint status = gJvm->DetachCurrentThread();\n    SC_ASSERT(status == JNI_OK);\n}\n} // namespace\n\n// Called when library is loaded by the first class which uses it.\nextern \"C\" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* jvm, void* reserved) // NOLINT naming\n{\n    debugging::ScopedTrace trace(\"client::JNI_OnLoad\");\n    gJvm = jvm;\n    djinni::jniInit(jvm);\n\n    [[maybe_unused]] auto result = pthread_key_create(&gJniPtr, &threadDestructor);\n    SC_ASSERT(!result);\n\n    JNIEnv* jni = nullptr;\n    if (jvm->GetEnv(reinterpret_cast<void**>(&jni), JNI_VERSION_1_6) != JNI_OK)\n        return -1;\n\n    jni::runOnLoadInitializers(jni);\n\n    return JNI_VERSION_1_6;\n}\n\n// (Potentially) called when library is about to be unloaded.\nextern \"C\" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* jvm, void* reserved) // NOLINT naming\n{\n    gJvm = nullptr;\n    djinni::jniShutdown();\n}\n\nnamespace {\n\nJNIEnv* attachJniInternal(const char* threadName) {\n    if (gJvm == nullptr) {\n        return nullptr;\n    }\n    JavaVMAttachArgs args{};\n    args.version = JNI_VERSION_1_6;\n    args.name = threadName;\n    args.group = nullptr;\n// Deal with difference in signatures between Oracle's jni.h and Android's.\n#ifdef _JAVASOFT_JNI_H_ // Oracle's jni.h violates the JNI spec\n    void* env = nullptr;\n#else\n    JNIEnv* env = nullptr;\n#endif\n    // this function may fail if JVM is shutting down:\n    [[maybe_unused]] auto result = gJvm->AttachCurrentThread(&env, &args);\n    assert(result == JNI_OK);\n    assert(env != nullptr);\n\n    return static_cast<JNIEnv*>(env);\n}\n} // namespace\n\n// Return a |JNIEnv*| usable on this thread or NULL if this thread is detached.\nJNIEnv* getEnv() {\n    void* env = nullptr;\n    [[maybe_unused]] jint status = gJvm->GetEnv(&env, JNI_VERSION_1_6);\n    assert(((env != nullptr) && (status == JNI_OK)) || ((env == nullptr) && (status == JNI_EDETACHED)));\n    return reinterpret_cast<JNIEnv*>(env);\n}\n\nbool attachThreadIfNeeded(const char* threadName) {\n    // check if already attached\n    if (auto* jni = getEnv(); jni != nullptr)\n        return true;\n\n    SC_ASSERT(!pthread_getspecific(gJniPtr));\n    auto* jni = attachJniInternal(threadName);\n    auto result = pthread_setspecific(gJniPtr, jni);\n    assert(result == 0);\n    return result == 0;\n}\n\nvoid attachJni(const char* threadName) {\n    attachJniInternal(threadName);\n}\n\nvoid detachJni() {\n    if (gJvm != nullptr) {\n        gJvm->DetachCurrentThread();\n    }\n}\n\nJavaVM* getJvm() {\n    return gJvm;\n}\n\n// Register java native methods with JNI C methods. Crashes immediately if errors occur.\nvoid registerNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod methods[], int numMethods) {\n    jclass clazz;\n    clazz = env->FindClass(className);\n    if (clazz == nullptr) {\n        // This will log and immediately abort() which is what we want, because\n        // if we keep going then we'll crash when someone tries to call this\n        // unregistered method.\n        __android_log_assert(nullptr, \"ClientAssert\", \"Native registration unable to find class '%s'\", className);\n    }\n    int res = env->RegisterNatives(clazz, methods, numMethods);\n    if (res < 0) {\n        __android_log_assert(nullptr, \"ClientAssert\", \"RegisterNatives failed for '%s'\", className);\n    }\n}\n\nstd::string getDeviceModel() {\n    JNIEnv* env = getEnv();\n    if (env == nullptr) {\n        return {};\n    }\n    jclass buildClass = env->FindClass(\"android/os/Build\");\n    jfieldID modelId = env->GetStaticFieldID(buildClass, \"MODEL\", \"Ljava/lang/String;\");\n    auto* modelObj = reinterpret_cast<jstring>(env->GetStaticObjectField(buildClass, modelId));\n    const char* deviceModel = env->GetStringUTFChars(modelObj, nullptr);\n    if (env->ExceptionCheck() != 0u) {\n        env->ExceptionClear();\n        return {};\n    }\n    return std::string(deviceModel);\n}\n} // namespace snap::utils::platform\n\nclass UncaughtJavaException : public djinni::jni_exception {\nprivate:\n    std::string _whatMessage;\n\npublic:\n    UncaughtJavaException(JNIEnv* env, jthrowable javaException, std::string whatArg)\n        : jni_exception(env, javaException), _whatMessage(std::move(whatArg)) {};\n\n    const char* what() const noexcept override {\n        return this->_whatMessage.c_str();\n    }\n};\n\nnamespace djinni {\n\n// Overriding the handler that processes exceptions thrown in Java\nDJINNI_NORETURN_DEFINITION void jniThrowCppFromJavaException(JNIEnv* env, jthrowable javaException) {\n    // WARN: This code is called from djinni so don't use Djinni helper functions\n    // here to avoid deadlocks and other issues.\n\n    auto checkJniReturn = [env, javaException](auto o, const char* msg) {\n        auto* e = env->ExceptionOccurred();\n        if (e) {\n            // Nothing we can do if we get an exception in the function that\n            // translates exceptions.\n            env->ExceptionClear();\n        }\n        if (e || o == nullptr) {\n            throw UncaughtJavaException(env, javaException, fmt::format(\"failed to translate java exception: {}\", msg));\n        }\n    };\n    auto getJniString = [env](jstring jstr) {\n        const char* chars = env->GetStringUTFChars(jstr, nullptr);\n        if (chars) {\n            std::string cstr(chars);\n            env->ReleaseStringUTFChars(jstr, chars);\n            return cstr;\n        } else {\n            return std::string(\"[N/A]\");\n        }\n    };\n\n    jclass arraysClass = env->FindClass(\"java/util/Arrays\");\n    checkJniReturn(arraysClass, \"unable to find class java.util.Arrays\");\n\n    jclass throwableClass = env->FindClass(\"java/lang/Throwable\");\n    checkJniReturn(throwableClass, \"unable to find class java.lang.Throwable\");\n\n    jmethodID arraysToStringMethod =\n        env->GetStaticMethodID(arraysClass, \"toString\", \"([Ljava/lang/Object;)Ljava/lang/String;\");\n    checkJniReturn(arraysToStringMethod, \"unable to get method Arrays.toString()\");\n\n    jmethodID throwableToStringMethod = env->GetMethodID(throwableClass, \"toString\", \"()Ljava/lang/String;\");\n    checkJniReturn(throwableToStringMethod, \"unable to get method Throwable.toString()\");\n\n    jmethodID getStackTraceMethod =\n        env->GetMethodID(throwableClass, \"getStackTrace\", \"()[Ljava/lang/StackTraceElement;\");\n    checkJniReturn(getStackTraceMethod, \"unable to get method Throwable.getStackTrace()\");\n\n    auto* msgStr = reinterpret_cast<jstring>(env->CallObjectMethod(javaException, throwableToStringMethod));\n    checkJniReturn(msgStr, \"failed calling Throwable.toString()\");\n\n    jobject stack = env->CallObjectMethod(javaException, getStackTraceMethod);\n    checkJniReturn(stack, \"failed calling Throwable.getStackTrace()\");\n\n    auto* stackStr = reinterpret_cast<jstring>(env->CallStaticObjectMethod(arraysClass, arraysToStringMethod, stack));\n    checkJniReturn(stackStr, \"failed calling Arrays.toString()\");\n\n    std::string exceptionMessage =\n        fmt::format(\"Message: [{}], StackTrace: {}\", getJniString(msgStr), getJniString(stackStr));\n\n    __android_log_print(\n        ANDROID_LOG_ERROR, \"[scclient]\", \"Java exception to propagate to native: %s\", exceptionMessage.data());\n    throw UncaughtJavaException(env, javaException, std::move(exceptionMessage));\n}\n} // namespace djinni\n\n#endif\n"
  },
  {
    "path": "libs/utils/src/utils/platform/JvmUtils.hpp",
    "content": "#pragma once\n\n#include \"utils/platform/JNITypeStubs.hpp\"\n#include <stdexcept>\n\nnamespace snap::utils::platform {\n// Attaches JNI environment to the currrently executing thread if not set.\n// This is necessary when calling from pure C++ thread into Java.\n// Returns true if attached successfully.\nbool attachThreadIfNeeded(const char* threadName);\n\n// Attaches JNI on Android. Does nothing on other platforms.\nvoid attachJni(const char* threadName);\n\n// Detaches JNI on Android. Does nothing on other platforms.\nvoid detachJni();\n\n// Returns pointer to JVM instance\nJavaVM* getJvm();\n\n/**\n * Gets the JNIEnv on Android. Will assert fail on other platforms.\n */\nJNIEnv* getEnv();\n\n// Registers JNI methods so they can be called from Java. Will assert fail on other platforms.\nvoid registerNativeMethods(JNIEnv* env, const char* className, const JNINativeMethod methods[], int numMethods);\n\nstruct ScopedJniAttach final {\n    explicit ScopedJniAttach(const char* threadName) {\n        attachJni(threadName);\n    }\n\n    ~ScopedJniAttach() {\n        detachJni();\n    }\n};\n\n// move to common header if we later need this on iOS\nstd::string getDeviceModel();\n\n} // namespace snap::utils::platform\n"
  },
  {
    "path": "libs/utils/src/utils/platform/TargetPlatform.hpp",
    "content": "#pragma once\n\n/**\n * This header adds a set of macros to detect the platform we're targeting for the build.\n * SC_ANDROID for Android\n * SC_IOS for iOS\n * SC_IPHONE_SIMULATOR for iPhone simulator\n * SC_DESKTOP for macos and desktop/server linux\n * SC_DESKTOP_LINUX for desktop/server linux\n * SC_DESKTOP_MACOS for desktop macos\n * SC_WASM for wasm\n */\n\n#if defined(__APPLE__)\n\n#include \"TargetConditionals.h\"\n#if TARGET_IPHONE_SIMULATOR\n#define SC_IPHONE_SIMULATOR 1\n#define SC_IOS 1\n#elif TARGET_OS_IPHONE\n#define SC_IOS 1\n#else\n#define SC_DESKTOP 1\n#define SC_DESKTOP_MACOS 1\n#endif\n\n#elif defined(ANDROID_WITH_JNI)\n#define SC_ANDROID 1\n#elif defined(EMSCRIPTEN)\n#define SC_WASM 1\n#elif defined(__linux__)\n#define SC_DESKTOP 1\n#define SC_DESKTOP_LINUX 1\n#endif // defined(__APPLE__)\n\n// We need this guard because this file is used in pure Objective-C which doesn't support constexpr.\n#ifdef __cplusplus\n\nnamespace snap {\n\n// Supported operating systems\nenum class Platform { Android, Ios, MacOs, DesktopLinux, Wasm };\n\n#if defined(SC_ANDROID)\nconstexpr Platform kPlatform = Platform::Android;\n#elif defined(SC_IOS)\nconstexpr Platform kPlatform = Platform::Ios;\n#elif defined(SC_DESKTOP_MACOS)\nconstexpr Platform kPlatform = Platform::MacOs;\n#elif defined(SC_WASM)\nconstexpr Platform kPlatform = Platform::Wasm;\n#else\nconstexpr Platform kPlatform = Platform::DesktopLinux;\n#endif\n\n///\n/// Set of helper functions for use in constexpr functions and `if` blocks.\n/// Provides cleaner alternative to #ifdef macros in some cases.\n///\n/// For example:\n/// if constexpr (snap::isIos()) {\n///     callIosSpecificFunction();\n/// else {\n///     callGenericFunction();\n/// }\n///\n\nconstexpr bool isAndroid() {\n    return kPlatform == Platform::Android;\n}\n\nconstexpr bool isIos() {\n    return kPlatform == Platform::Ios;\n}\n\nconstexpr bool isMacOs() {\n    return kPlatform == Platform::MacOs;\n}\n\nconstexpr bool isDesktopLinux() {\n    return kPlatform == Platform::DesktopLinux;\n}\n\nconstexpr bool isApple() {\n    return isIos() || isMacOs();\n}\n\nconstexpr bool isWasm() {\n    return kPlatform == Platform::Wasm;\n}\n\nconstexpr bool isDesktop() {\n    return isMacOs() || isDesktopLinux();\n}\n\n// Based off of the C standard library definition of NDEBUG (not debug).\n// TODO: We should not use this flag and should instead drive off of build flavor!\nconstexpr bool isSystemDebug() {\n#if defined(NDEBUG)\n    return false;\n#else\n    return true;\n#endif\n}\n\n} // namespace snap\n\n#endif\n"
  },
  {
    "path": "libs/utils/src/utils/time/BoottimeClock.cpp",
    "content": "#include \"utils/time/BoottimeClock.hpp\"\n#include \"utils/platform/TargetPlatform.hpp\"\n#include <cerrno>\n#include <chrono>\n#include <ctime>\n#include <system_error>\n\nnamespace snap::utils::time {\n\nusing std::chrono::nanoseconds;\nusing std::chrono::seconds;\n\n// Remove the implementation of this symbol for wasm. We can let code include the header file, but this will ensure\n// nobody tries to reference the symbol. Boot-time is somewhat possible in NodeJS, but specifically in browsers, they\n// don't offer visibility into the OS to know when the machine was booted up. UptimeClock is supported however, and\n// should meet most needs if the only requirement is a monotonic clock.\n#ifndef SC_WASM\nBoottimeClock::time_point BoottimeClock::now() noexcept {\n    // This implementation is copied from the LLVM source.\n    // https://github.com/llvm/llvm-project/blob/master/libcxx/src/chrono.cpp\n    struct timespec tp;\n\n#if __APPLE__\n    // This should align with iOS mach_continuous_time.\n    // https://opensource.apple.com/source/Libc/Libc-1158.1.2/gen/clock_gettime.c.auto.html\n    if (0 != clock_gettime(CLOCK_MONOTONIC_RAW, &tp)) {\n        std::__throw_system_error(errno, \"clock_gettime(CLOCK_MONOTONIC_RAW) failed\");\n    }\n#else\n    // This should match the Android source for elapsedRealtime.\n    // https://cs.android.com/android/platform/superproject/+/master:system/core/libutils/SystemClock.cpp\n    if (0 != clock_gettime(CLOCK_BOOTTIME, &tp)) {\n        std::__throw_system_error(errno, \"clock_gettime(CLOCK_BOOTTIME) failed\");\n    }\n#endif\n\n    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));\n}\n#endif\n\n} // namespace snap::utils::time\n"
  },
  {
    "path": "libs/utils/src/utils/time/BoottimeClock.hpp",
    "content": "#pragma once\n\n#include <chrono>\n#include <ctime>\n\nnamespace snap::utils::time {\n\n// A monotonically increasing clock that will return the time since boot, including\n// time spent while the device is asleep.\n//\n// This clock reads from CLOCK_MONOTONIC_RAW.\n//\n// On iOS, this clock is equivalent to mach_continuous_time.\n// On Android, this clock is equivalent to System.elapsedRealtime().\n//\n// This class conforms to the TrivialClock standard.\nclass BoottimeClock {\npublic:\n    using duration = std::chrono::nanoseconds;\n    using rep = duration::rep;\n    using period = duration::period;\n    using time_point = std::chrono::time_point<BoottimeClock, duration>;\n\n    static constexpr bool is_steady = true; // NOLINT\n\n    static time_point now() noexcept;\n};\n\n} // namespace snap::utils::time\n"
  },
  {
    "path": "libs/utils/src/utils/time/Duration.hpp",
    "content": "#pragma once\n\n#include <array>\n#include <chrono>\n#include <fmt/format.h>\n#include <string>\n\nnamespace snap::utils::time {\n\n/**\n * Helper wrapper class around std::chrono::duration which exposes\n * easy conversion methods as well a human readable fmt/format support.\n *\n * Duration can be divided or multiplied by an amount in integer or double.\n * It can be used for instance to calculate, given a total duration for N\n * iterations, an average duration time by dividing the duration by N.\n *\n */\ntemplate<class Clock>\nclass Duration {\npublic:\n    constexpr explicit Duration(typename Clock::duration duration) : _duration(duration) {}\n    constexpr Duration() : _duration(Clock::duration::zero()) {}\n\n    Duration operator+(const Duration& operand) const {\n        return Duration(_duration + operand._duration);\n    }\n\n    Duration& operator+=(const Duration& operand) {\n        _duration += operand._duration;\n        return *this;\n    }\n\n    Duration operator-(const Duration& operand) const {\n        return Duration(_duration - operand._duration);\n    }\n\n    Duration& operator-=(const Duration& operand) {\n        _duration -= operand._duration;\n        return *this;\n    }\n\n    template<class T>\n    Duration operator/(const T& amount) const {\n        return Duration(_duration / amount);\n    }\n\n    template<class T>\n    Duration operator*(const T& amount) const {\n        return Duration(_duration * amount);\n    }\n\n    template<class T>\n    Duration& operator/=(const T& amount) {\n        _duration /= amount;\n        return *this;\n    }\n\n    template<class T>\n    Duration& operator*=(const T& amount) {\n        _duration *= amount;\n        return *this;\n    }\n\n    constexpr bool operator==(const Duration& rhs) const {\n        return _duration == rhs._duration;\n    }\n    constexpr bool operator!=(const Duration& rhs) const {\n        return _duration != rhs._duration;\n    }\n    constexpr bool operator<(const Duration& rhs) const {\n        return _duration < rhs._duration;\n    }\n    constexpr bool operator<=(const Duration& rhs) const {\n        return _duration <= rhs._duration;\n    }\n    constexpr bool operator>(const Duration& rhs) const {\n        return _duration > rhs._duration;\n    }\n    constexpr bool operator>=(const Duration& rhs) const {\n        return _duration >= rhs._duration;\n    }\n\n    double seconds() const {\n        return convert<double, std::chrono::seconds>();\n    }\n\n    double milliseconds() const {\n        return convert<double, std::chrono::milliseconds>();\n    }\n\n    double microseconds() const {\n        return convert<double, std::chrono::microseconds>();\n    }\n\n    double nanoseconds() const {\n        return convert<double, std::chrono::nanoseconds>();\n    }\n\n    typename Clock::duration chrono() const {\n        return _duration;\n    }\n\n    // automatic cast to any time unit\n    template<class T>\n    constexpr T as() const {\n        return std::chrono::duration_cast<T>(_duration);\n    }\n\n    std::string toString() const {\n        static std::array<std::pair<std::string_view, double>, 4> units = {\n            {{\"ns\", 1.0}, {\"us\", pow(1000, 1)}, {\"ms\", pow(1000, 2)}, {\"s\", pow(1000, 3)}}};\n        static auto log1000 = log(1000);\n\n        auto ns = nanoseconds();\n\n        auto unitIndex = ns != 0.0 ? std::min(static_cast<size_t>(log(ns) / log1000), units.size() - 1) : 0;\n\n        const auto& unit = units.at(unitIndex);\n        auto remain = ns / unit.second;\n        return fmt::format(\"{:.1f} {}\", remain, unit.first);\n    }\n\nprivate:\n    typename Clock::duration _duration;\n\n    template<typename Rep, typename Ratio>\n    Rep convert() const {\n        using TargetTimeUnit = std::chrono::duration<Rep, typename Ratio::period>;\n        return std::chrono::duration_cast<TargetTimeUnit>(_duration).count();\n    }\n};\n\n} // namespace snap::utils::time\n\n// Formatter for snap::utils::time::Duration\ntemplate<typename T>\nstruct fmt::formatter<snap::utils::time::Duration<T>> : fmt::formatter<std::string> {\n    template<typename FormatContext>\n    auto format(const snap::utils::time::Duration<T>& duration, FormatContext& ctx) {\n        return fmt::formatter<std::string>::format(duration.toString(), ctx);\n    }\n};\n"
  },
  {
    "path": "libs/utils/src/utils/time/StopWatch.hpp",
    "content": "#pragma once\n\n#include <array>\n#include <chrono>\n#include <fmt/format.h>\n#include <string>\n\n#include \"utils/time/Duration.hpp\"\n\nnamespace snap::utils::time {\n\n// Helper class to measure time intervals. Use the StopWatch alias for monotonic\n// clocks by default.\n//\n// Basic usage:\n//\n//   StopWatch sw(StopWatch::STARTED);\n//   doSomething();\n//   LOG(\"Operation took {}ms\", sw.elapsedMs());\n//\n// If you need more manual control of your stop watch you can explicitly call\n// start() and stop().  A stopwatch will by default start in a stopped state,\n// requiring you to call start() to initiate timing.\n//\n//   StopWatch sw;\n//   sw.start();\n//   doSomething();\n//   sw.stop();\n//   LOG(\"Operation took {}ms\", sw.elapsedMs());\n//\n// This class is NOT thread-safe for changes to the running state. If you\n// intend to share this object across threads, such as an async callback,\n// to update the StopWatch running state then you must ensure that only\n// one thread updates the class at a time, including readers.  Concurrent\n// reads to the StopWatch are always thread-safe.\ntemplate<class Clock>\nclass StopWatchGeneric {\npublic:\n    enum Mode {\n        STOPPED = 0,\n        STARTED = 1,\n    };\n\n    // Messaging test code relies on implicit constructor below for shorter code.\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    constexpr StopWatchGeneric(const Mode startMode = StopWatchGeneric::STOPPED) {\n        if (startMode == STARTED) {\n            _startingTime = now();\n            _running = true;\n        }\n    }\n\n    // Starts or resumes measuring time. If it has been started/stopped before,\n    // the newly measured elapsed time will be summed with the previous elapsed value.\n    // Trying to start if it's already started will do nothing.\n    void start() {\n        if (_running) {\n            return;\n        }\n\n        _startingTime = now();\n        _running = true;\n    }\n\n    // Stops measuring elapsed time. It does not reset already accumulated elapsed time.\n    void stop() {\n        if (!_running) {\n            return;\n        }\n        _elapsedTotal += fromStart();\n        _running = false;\n    }\n\n    // Stops time interval measurement and resets the elapsed time to zero.\n    void reset() {\n        _elapsedTotal = {};\n        _running = false;\n    }\n\n    // Helper method that does reset() and then start()\n    void restart() {\n        _elapsedTotal = {};\n        _startingTime = now();\n        _running = true;\n    }\n\n    int64_t elapsedSeconds() const {\n        return static_cast<int64_t>(elapsed().seconds());\n    }\n\n    int64_t elapsedMs() const {\n        return static_cast<int64_t>(elapsed().milliseconds());\n    }\n\n    int64_t elapsedUs() const {\n        return static_cast<int64_t>(elapsed().microseconds());\n    }\n\n    // Total elapsed time while this stopwatch was running.\n    Duration<Clock> elapsed() const {\n        auto elapsed = _elapsedTotal;\n\n        if (_running)\n            elapsed += fromStart();\n\n        return Duration<Clock>(elapsed);\n    }\n\n    const typename Clock::time_point& getStartTime() const {\n        return _startingTime;\n    }\n\nprivate:\n    typename Clock::duration fromStart() const {\n        return now() - _startingTime;\n    }\n\n    static typename Clock::time_point now() noexcept {\n        return Clock::now();\n    }\n\n    typename Clock::duration _elapsedTotal{};\n    typename Clock::time_point _startingTime{};\n    bool _running = false;\n};\n\n// StopWatch for monotonic clock. Guarantees that elapsed time is never negative.\nusing StopWatch = StopWatchGeneric<std::chrono::steady_clock>;\n\n} // namespace snap::utils::time\n"
  },
  {
    "path": "libs/utils/src/utils/time/UptimeClock.cpp",
    "content": "#include \"utils/time/UptimeClock.hpp\"\n\n#include <chrono>\n#include <ctime>\n#include <system_error>\n\n#include <time.h>\n\nnamespace snap::utils::time {\n\nusing std::chrono::nanoseconds;\nusing std::chrono::seconds;\n\nUptimeClock::time_point UptimeClock::now() noexcept {\n    // This implementation is copied from the LLVM source.\n    // https://github.com/llvm/llvm-project/blob/master/libcxx/src/chrono.cpp\n    struct timespec tp;\n#ifdef __APPLE__\n    // This should align with iOS mach_absolute_time.\n    // https://opensource.apple.com/source/Libc/Libc-1158.1.2/gen/clock_gettime.c.auto.html\n    if (0 != clock_gettime(CLOCK_UPTIME_RAW, &tp)) {\n        std::__throw_system_error(errno, \"clock_gettime(CLOCK_UPTIME_RAW) failed\");\n    }\n#else\n    // This should match the Android source for uptimeMillis.\n    // https://cs.android.com/android/platform/superproject/+/master:system/core/libutils/SystemClock.cpp\n    if (0 != clock_gettime(CLOCK_MONOTONIC, &tp)) {\n        std::__throw_system_error(errno, \"clock_gettime(CLOCK_MONOTONIC) failed\");\n    }\n#endif\n    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));\n}\n\n} // namespace snap::utils::time\n"
  },
  {
    "path": "libs/utils/src/utils/time/UptimeClock.hpp",
    "content": "#pragma once\n\n#include <chrono>\n#include <ctime>\n\nnamespace snap::utils::time {\n\n// A monotonically increasing clock that will return the time since boot, excluding\n// time spent while the device is asleep.\n//\n// This clock reads from CLOCK_UPTIME_RAW.\n//\n// On iOS, this clock is equivalent to mach_absolute_time and CACurrentMediaTime.\n// On Android, this clock is equivalent to System.uptimeMillis().\n//\n// This class conforms to the TrivialClock standard.\nclass UptimeClock {\npublic:\n    using duration = std::chrono::nanoseconds;\n    using rep = duration::rep;\n    using period = duration::period;\n    using time_point = std::chrono::time_point<UptimeClock, duration>;\n\n    static constexpr bool is_steady = true; // NOLINT\n\n    static time_point now() noexcept;\n};\n\n} // namespace snap::utils::time\n"
  },
  {
    "path": "libs/utils/src/utils_oss/utils_oss.cpp",
    "content": "#include \"utils/debugging/detail/AssertInternals.hpp\"\n\nnamespace snap {\n\nnamespace detail {\nvoid reportNonFatalAssert(std::string_view path, int64_t line, std::string_view message) {\n    // no-op\n}\n} // namespace detail\n\nbool fuseAssertion(std::string_view key) {\n    // no-op\n    return true;\n}\n\n} // namespace snap\n"
  },
  {
    "path": "modules/.terserrc.json",
    "content": "{\n  \"ecma\": \"ES2016\",\n  \"safari10\": true,\n  \"mangle\": {\n    \"toplevel\": true,\n    \"keep_classnames\": true\n  },\n  \"compress\": {\n    \"keep_classnames\": true\n  },\n  \"sourceMap\": {\n    \"content\": \"inline\",\n    \"url\": \"inline\"\n  }\n}\n"
  },
  {
    "path": "modules/BUILD.bazel",
    "content": "filegroup(\n    name = \"valdi_base\",\n    srcs = glob([\n        \"types/*.ts\",\n        \"_configs/*.json\",\n    ]) + [\"tsconfig.json\"],\n    visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n    name = \"minify_config\",\n    srcs = [\".terserrc.json\"],\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "modules/_configs/base.tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"target\": \"ES2016\",\n    \"module\": \"commonjs\",\n    \"lib\": [\"dom\", \"ES2019\"],\n    \"noImplicitReturns\": true,\n    \"noImplicitAny\": true,\n    \"importHelpers\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"jsx\": \"preserve\",\n    \"paths\": {\n      \"Valdi\": [\n        \"./valdi_core/src/Valdi\",\n        \"../src/valdi_modules/src/valdi/valdi_core/src/Valdi\"\n      ],\n      \"tslib\": [\n        \"./valdi_core/src/tslib.d.ts\",\n        \"../src/valdi_modules/src/valdi/valdi_core/src/tslib.d.ts\"\n      ],\n      \"jasmine\": [\n        \"./jasmine/src/jasmine.d.ts\",\n        \"../src/valdi_modules/src/valdi/jasmine/src/jasmine.d.ts\"\n      ]\n    },\n    \"types\": [\"../types/Long\", \"../types/globals\"]\n  }\n}\n"
  },
  {
    "path": "modules/_configs/eslint.tsconfig.json",
    "content": "{\n  \"extends\": \"./base.tsconfig.json\",\n  \"include\": [\"../**/*.ts\", \"../**/*.tsx\"]\n}\n"
  },
  {
    "path": "modules/hello_world/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nvaldi_module(\n    name = \"hello_world\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCHelloWorld\",\n    ios_output_target = \"release\",\n    module_yaml = \"module.yaml\",\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "modules/hello_world/module.yaml",
    "content": "output_target: release\n\ndependencies:\n  - valdi_core\n  - valdi_tsx\n\ncompilation_mode: js\n"
  },
  {
    "path": "modules/hello_world/src/HelloWorldApp.tsx",
    "content": "import { Asset } from 'valdi_core/src/Asset';\nimport { Component } from 'valdi_core/src/Component';\nimport { Label, ScrollView } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Style } from 'valdi_core/src/Style';\nimport { systemFont } from \"valdi_core/src/SystemFont\";\n\nimport res from '../res';\n\n/**\n * @ViewModel\n * @ExportModel({ ios: 'ValdiStartViewComponentViewModel', android: 'com.snap.valdi.helloworld.StartViewComponentViewModel'})\n */\nexport interface StartComponentViewModel {}\n\n/**\n * @Context\n * @ExportModel({ios: 'ValdiStartViewComponentContext', android: 'com.snap.valdi.helloworld.StartViewComponentContext'})\n */\nexport interface StartComponentContext {\n  iconImage?: Asset;\n}\n\n/**\n * @Component\n * @ExportModel({ios: 'ValdiStartView', android: 'com.snap.valdi.helloworld.StartView'})\n */\nexport class SampleApps extends Component<\n  StartComponentViewModel,\n  StartComponentContext\n> {\n  onCreate(): void {\n    console.log('Hello World onCreate!');\n  }\n\n  onRender(): void {\n    console.log('Hello World onRender!');\n    <view backgroundColor='white'>\n      <image src={this.context.iconImage as Asset} alignSelf='center' />\n      <scroll style={styles.scroll} padding={16}>\n        <layout marginTop={100} flexDirection='row' width='100%' minHeight={10}>\n          <image src={res.emoji} height='100%' tint='gray' marginRight={10} />\n          <label style={styles.title} value='Welcome to Valdi!' font={systemFont(20)}/>\n        </layout>\n      </scroll>\n    </view>;\n  }\n}\n\nconst styles = {\n  scroll: new Style<ScrollView>({\n    alignItems: 'center',\n    height: '100%',\n  }),\n\n  title: new Style<Label>({\n    color: 'black',\n    accessibilityCategory: 'header',\n    width: '100%',\n  }),\n};\n"
  },
  {
    "path": "modules/hello_world/src/index.ts",
    "content": "console.log('Hello World!');\n"
  },
  {
    "path": "modules/hello_world/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\"\n}\n"
  },
  {
    "path": "modules/tsconfig.json",
    "content": "{\n    \"extends\": \"./_configs/base.tsconfig.json\",\n}\n"
  },
  {
    "path": "modules/types/Long.d.ts",
    "content": "/* eslint-disable */\n// Type definitions for long.js 4.0.0\n// Project: https://github.com/dcodeIO/long.js\n// Definitions by: Peter Kooijmans <https://github.com/peterkooijmans>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// Definitions by: Denis Cappellin <https://github.com/cappellin>\n\ndeclare global {\n  class Long {\n    /**\n     * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as signed integers. See the from* functions below for more convenient ways of constructing Longs.\n     */\n    constructor(low: number, high?: number, unsigned?: boolean);\n\n    /**\n     * Maximum unsigned value.\n     */\n    static MAX_UNSIGNED_VALUE: Long;\n\n    /**\n     * Maximum signed value.\n     */\n    static MAX_VALUE: Long;\n\n    /**\n     * Minimum signed value.\n     */\n    static MIN_VALUE: Long;\n\n    /**\n     * Signed negative one.\n     */\n    static NEG_ONE: Long;\n\n    /**\n     * Signed one.\n     */\n    static ONE: Long;\n\n    /**\n     * Unsigned one.\n     */\n    static UONE: Long;\n\n    /**\n     * Unsigned zero.\n     */\n    static UZERO: Long;\n\n    /**\n     * Signed zero\n     */\n    static ZERO: Long;\n\n    /**\n     * The high 32 bits as a signed value.\n     */\n    high: number;\n\n    /**\n     * The low 32 bits as a signed value.\n     */\n    low: number;\n\n    /**\n     * Whether unsigned or not.\n     */\n    unsigned: boolean;\n\n    /**\n     * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is assumed to use 32 bits.\n     */\n    static fromBits(lowBits: number, highBits: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representing the given 32 bit integer value.\n     */\n    static fromInt(value: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.\n     */\n    static fromNumber(value: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representation of the given string, written using the specified radix.\n     */\n    static fromString(str: string, unsigned?: boolean | number, radix?: number): Long;\n\n    /**\n     * Creates a Long from its byte representation.\n     */\n    static fromBytes(bytes: number[], unsigned?: boolean, le?: boolean): Long;\n\n    /**\n     * Creates a Long from its little endian byte representation.\n     */\n    static fromBytesLE(bytes: number[], unsigned?: boolean): Long;\n\n    /**\n     * Creates a Long from its little endian byte representation.\n     */\n    static fromBytesBE(bytes: number[], unsigned?: boolean): Long;\n\n    /**\n     * Tests if the specified object is a Long.\n     */\n    static isLong(obj: any): boolean;\n\n    /**\n     * Converts the specified value to a Long.\n     */\n    static fromValue(val: Long | number | string | { low: number; high: number; unsigned: boolean }): Long;\n\n    /**\n     * Returns the sum of this and the specified Long.\n     */\n    add(addend: number | Long | string): Long;\n\n    /**\n     * Returns the bitwise AND of this Long and the specified.\n     */\n    and(other: Long | number | string): Long;\n\n    /**\n     * Compares this Long's value with the specified's.\n     */\n    compare(other: Long | number | string): number;\n\n    /**\n     * Compares this Long's value with the specified's.\n     */\n    comp(other: Long | number | string): number;\n\n    /**\n     * Returns this Long divided by the specified.\n     */\n    divide(divisor: Long | number | string): Long;\n\n    /**\n     * Returns this Long divided by the specified.\n     */\n    div(divisor: Long | number | string): Long;\n\n    /**\n     * Tests if this Long's value equals the specified's.\n     */\n    equals(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value equals the specified's.\n     */\n    eq(other: Long | number | string): boolean;\n\n    /**\n     * Gets the high 32 bits as a signed integer.\n     */\n    getHighBits(): number;\n\n    /**\n     * Gets the high 32 bits as an unsigned integer.\n     */\n    getHighBitsUnsigned(): number;\n\n    /**\n     * Gets the low 32 bits as a signed integer.\n     */\n    getLowBits(): number;\n\n    /**\n     * Gets the low 32 bits as an unsigned integer.\n     */\n    getLowBitsUnsigned(): number;\n\n    /**\n     * Gets the number of bits needed to represent the absolute value of this Long.\n     */\n    getNumBitsAbs(): number;\n\n    /**\n     * Tests if this Long's value is greater than the specified's.\n     */\n    greaterThan(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than the specified's.\n     */\n    gt(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than or equal the specified's.\n     */\n    greaterThanOrEqual(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than or equal the specified's.\n     */\n    gte(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is even.\n     */\n    isEven(): boolean;\n\n    /**\n     * Tests if this Long's value is negative.\n     */\n    isNegative(): boolean;\n\n    /**\n     * Tests if this Long's value is odd.\n     */\n    isOdd(): boolean;\n\n    /**\n     * Tests if this Long's value is positive.\n     */\n    isPositive(): boolean;\n\n    /**\n     * Tests if this Long's value equals zero.\n     */\n    isZero(): boolean;\n\n    /**\n     * Tests if this Long's value is less than the specified's.\n     */\n    lessThan(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than the specified's.\n     */\n    lt(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than or equal the specified's.\n     */\n    lessThanOrEqual(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than or equal the specified's.\n     */\n    lte(other: Long | number | string): boolean;\n\n    /**\n     * Returns this Long modulo the specified.\n     */\n    modulo(other: Long | number | string): Long;\n\n    /**\n     * Returns this Long modulo the specified.\n     */\n    mod(other: Long | number | string): Long;\n\n    /**\n     * Returns the product of this and the specified Long.\n     */\n    multiply(multiplier: Long | number | string): Long;\n\n    /**\n     * Returns the product of this and the specified Long.\n     */\n    mul(multiplier: Long | number | string): Long;\n\n    /**\n     * Negates this Long's value.\n     */\n    negate(): Long;\n\n    /**\n     * Negates this Long's value.\n     */\n    neg(): Long;\n\n    /**\n     * Returns the bitwise NOT of this Long.\n     */\n    not(): Long;\n\n    /**\n     * Tests if this Long's value differs from the specified's.\n     */\n    notEquals(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value differs from the specified's.\n     */\n    neq(other: Long | number | string): boolean;\n\n    /**\n     * Returns the bitwise OR of this Long and the specified.\n     */\n    or(other: Long | number | string): Long;\n\n    /**\n     * Returns this Long with bits shifted to the left by the given amount.\n     */\n    shiftLeft(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits shifted to the left by the given amount.\n     */\n    shl(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits arithmetically shifted to the right by the given amount.\n     */\n    shiftRight(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits arithmetically shifted to the right by the given amount.\n     */\n    shr(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits logically shifted to the right by the given amount.\n     */\n    shiftRightUnsigned(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits logically shifted to the right by the given amount.\n     */\n    shru(numBits: number | Long): Long;\n\n    /**\n     * Returns the difference of this and the specified Long.\n     */\n    subtract(subtrahend: number | Long | string): Long;\n\n    /**\n     * Returns the difference of this and the specified Long.\n     */\n    sub(subtrahend: number | Long | string): Long;\n\n    /**\n     * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.\n     */\n    toInt(): number;\n\n    /**\n     * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).\n     */\n    toNumber(): number;\n\n    /**\n     * Converts this Long to its byte representation.\n     */\n\n    toBytes(le?: boolean): number[];\n\n    /**\n     * Converts this Long to its little endian byte representation.\n     */\n\n    toBytesLE(): number[];\n\n    /**\n     * Converts this Long to its big endian byte representation.\n     */\n\n    toBytesBE(): number[];\n\n    /**\n     * Converts this Long to signed.\n     */\n    toSigned(): Long;\n\n    /**\n     * Converts the Long to a string written in the specified radix.\n     */\n    toString(radix?: number): string;\n\n    /**\n     * Converts this Long to unsigned.\n     */\n    toUnsigned(): Long;\n\n    /**\n     * Returns the bitwise XOR of this Long and the given one.\n     */\n    xor(other: Long | number | string): Long;\n  }\n}\n\nexport {};\n"
  },
  {
    "path": "modules/types/globals.d.ts",
    "content": "// This is a global declarations file that's referenced by valdi_core/src/Valdi.ts\n\ndeclare const module: { path: string; exports: unknown };\n"
  },
  {
    "path": "npm_modules/cli/.bazelignore",
    "content": ".metadata\n.bootstrap"
  },
  {
    "path": "npm_modules/cli/.bootstrap/apps/cli_application/BUILD.bazel.template",
    "content": "load(\"@valdi//bzl/valdi:valdi_cli_application.bzl\", \"valdi_cli_application\")\n\nvaldi_cli_application(\n    name = \"{{MODULE_NAME}}_app\",\n    script_path = \"{{MODULE_NAME}}/src/index\",\n    deps = [\"//modules/{{MODULE_NAME}}\"],\n)\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/apps/cli_application/modules/{{MODULE_NAME}}/BUILD.bazel.template",
    "content": "load(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"{{MODULE_NAME}}\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [],\n)\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/apps/cli_application/modules/{{MODULE_NAME}}/src/index.ts",
    "content": "console.log('Hello world!');\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/apps/ui_application/.eslint.rc",
    "content": "\nmodule.exports = {\n  root: true,\n  parser: '@typescript-eslint/parser',\n  parserOptions: {\n    tsconfigRootDir: __dirname,\n    project: ['./src/valdi/_configs/eslint.tsconfig.json'],\n  },\n  plugins: ['@typescript-eslint', 'unused-imports', 'rxjs', 'prettier', '@snapchat/eslint-plugin-valdi'],\n  extends: [\n    'eslint:recommended',\n    'plugin:@typescript-eslint/recommended',\n    'plugin:import/recommended',\n    'plugin:import/typescript',\n    'prettier',\n  ],\n  rules: { \n    '@snapchat/valdi/attributed-text-no-array-assignment': 'error',\n    '@snapchat/valdi/jsx-no-lambda': 'error',\n    '@snapchat/valdi/assign-timer-id': 'error',\n    '@snapchat/valdi/only-const-enum': 'off',\n    '@snapchat/valdi/no-implicit-index-import': 'error',\n    '@snapchat/valdi/mutate-state-without-set-state': 'error',\n    '@snapchat/valdi/no-import-from-test-outside-test-dir': 'error',\n    '@snapchat/valdi/no-declare-test-without-describe': 'error', \n  },\n};\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/apps/ui_application/BUILD.bazel.template",
    "content": "load(\"@valdi//bzl/valdi:valdi_application.bzl\", \"valdi_application\")\nload(\"@valdi//bzl/valdi:valdi_exported_library.bzl\", \"valdi_exported_library\")\n\nvaldi_application(\n    name = \"{{MODULE_NAME}}_app\",\n    ios_bundle_id = \"com.website.{{MODULE_NAME}}\",\n    ios_families = [\"iphone\"],\n    root_component_path = \"App@{{MODULE_NAME}}/src/App\",\n    title = \"{{MODULE_NAME}}\",\n    version = \"1.0.0\",\n    deps = [\"//modules/{{MODULE_NAME}}\"],\n)\n\nvaldi_exported_library(\n    name = \"{{MODULE_NAME}}_export\",\n    ios_bundle_id = \"com.website.{{MODULE_NAME}}.lib\",\n    ios_bundle_name = \"{{MODULE_NAME_PASCAL_CASED}}\",\n    deps = [\"//modules/{{MODULE_NAME}}\"],\n)\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/apps/ui_application/modules/{{MODULE_NAME}}/BUILD.bazel.template",
    "content": "load(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"{{MODULE_NAME}}\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]),\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/apps/ui_application/modules/{{MODULE_NAME}}/src/App.tsx",
    "content": "import { StatefulComponent } from 'valdi_core/src/Component';\nimport { ImageView, Label, View } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Style } from 'valdi_core/src/Style';\nimport { systemBoldFont, systemFont } from 'valdi_core/src/SystemFont';\nimport { AttributedText } from 'valdi_tsx/src/AttributedText';\nimport { AttributedTextBuilder } from 'valdi_core/src/utils/AttributedTextBuilder';\nimport { Device } from 'valdi_core/src/Device';\nimport { getDaemonClientManager } from 'valdi_core/src/debugging/DaemonClientManagerResolver';\nimport { IDaemonClientManagerListener } from 'valdi_core/src/debugging/DaemonClientManager';\nimport res from '../res';\n\n/**\n * @ViewModel\n * @ExportModel\n */\nexport interface AppViewModel {}\n\n/**\n * @Context\n * @ExportModel\n */\nexport interface AppComponentContext {}\n\ninterface State {\n  hotReloaderConnected: boolean;\n}\n\n/**\n * @Component\n * @ExportModel\n */\nexport class App extends StatefulComponent<AppViewModel, AppComponentContext> implements IDaemonClientManagerListener {\n  state: State = { hotReloaderConnected: false };\n\n  onCreate(): void {\n    console.log('On App create!');\n    getDaemonClientManager().addListener(this);\n  }\n\n  onDestroy(): void {\n    console.log('On App destroy!');\n    getDaemonClientManager().removeListener(this);\n  }\n\n  onAvailabilityChanged(available: boolean): void {\n    this.setState({ hotReloaderConnected: available });\n  }\n\n  onRender(): void {\n    console.log('On App render!');\n    <view style={styles.main}>\n      <image style={styles.logo} src={res.valdi} />\n      <layout padding={20}>\n        <label style={styles.title} value={`Welcome to Valdi!`} />\n      </layout>\n      <label style={styles.subtitle} value={this.renderLabel()} />\n    </view>;\n  }\n\n  private renderLabel(): AttributedText {\n    const textBuilder = new AttributedTextBuilder();\n\n    textBuilder.appendText('This is currently running on ');\n    textBuilder.appendStyled({\n      content: this.getPlatformString(),\n      attributes: {\n        color: 'red',\n        font: systemBoldFont(20),\n      },\n    });\n\n    textBuilder.appendText('\\nHot reloader ');\n    if (this.state.hotReloaderConnected) {\n      textBuilder.appendStyled({\n        content: 'connected',\n        attributes: {\n          color: 'green',\n          font: systemBoldFont(20),\n        },\n      });\n    } else {\n      textBuilder.appendStyled({\n        content: 'disconnected',\n        attributes: {\n          color: 'red',\n          font: systemBoldFont(20),\n        },\n      });\n    }\n\n    return textBuilder.build();\n  }\n\n  private getPlatformString(): string {\n    if (Device.isDesktop()) {\n      return 'Desktop';\n    } else if (Device.isIOS()) {\n      return 'iOS';\n    } else if (Device.isAndroid()) {\n      return 'Android';\n    } else {\n      return 'Unknown';\n    }\n  }\n}\n\nconst styles = {\n  main: new Style<View>({\n    backgroundColor: 'white',\n    justifyContent: 'center',\n  }),\n  logo: new Style<ImageView>({\n    width: 80,\n    height: 80,\n    alignSelf: 'center',\n    borderRadius: 16,\n    boxShadow: '0 0 3 rgba(0, 0, 0, 0.15)',\n  }),\n  title: new Style<Label>({\n    color: 'black',\n    font: systemBoldFont(24),\n    accessibilityCategory: 'header',\n    alignSelf: 'center',\n  }),\n\n  subtitle: new Style<Label>({\n    alignSelf: 'center',\n    color: 'black',\n    font: systemFont(20),\n    numberOfLines: 0,\n    textAlign: 'center',\n  }),\n};\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/apps/ui_application/package.json",
    "content": "{\n    \"name\": \"hello_world\",\n    \"version\": \"1.0.0\",\n    \"description\": \"Valdi Helloworld app\",\n    \"license\": \"ISC\",\n    \"devDependencies\": {\n      \"@snap/eslint-plugin-valdi\": \"1.0.2\",\n      \"@types/eslint\": \"^9.6.1\",\n      \"@types/jasmine\": \"^5.1.7\",\n      \"@typescript-eslint/eslint-plugin\": \"^6.21.0\",\n      \"@typescript-eslint/parser\": \"^6.21.0\",\n      \"@typescript-eslint/utils\": \"^6.21.0\",\n      \"eslint\": \"^8.27.0\",\n      \"eslint-config-prettier\": \"^8.5.0\",\n      \"eslint-plugin-import\": \"^2.26.0\",\n      \"eslint-plugin-prettier\": \"^4.2.1\",\n      \"eslint-plugin-rxjs\": \"^5.0.2\",\n      \"eslint-plugin-unused-imports\": \"^3.2.0\",\n      \"jasmine\": \"^5.6.0\",\n      \"ts-node\": \"^10.9.2\",\n      \"typescript\": \"5.3.3\"\n    }\n  }\n  "
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_bridge_module/BUILD.bazel.template",
    "content": "load(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"@valdi//bzl/valdi:valdi_android_library.bzl\", \"valdi_android_library\")\nload(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_android_library(\n    name = \"android_impl\",\n    srcs = glob([\n        \"android/**/*.kt\",\n    ]),\n    deps = [\n        \":{{MODULE_NAME}}_api_kt\",\n    ],\n)\n\nobjc_library(\n    name = \"ios_impl\",\n    srcs = glob([\n        \"ios/**/*.m\",\n    ]),\n    hdrs = glob([\n        \"ios/**/*.h\",\n    ]),\n    copts = [\"-I.\"],\n    deps = [\n        \":{{MODULE_NAME}}_api_objc\",\n    ],\n)\n\nts_project(\n    name = \"{{MODULE_NAME}}_web\",\n    srcs = glob([\n        \"web/**/*.ts\",\n        \"web/**/*.d.ts\",\n    ]),\n    allow_js = True,\n    composite = False,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n    visibility = [\"//visibility:public\"],\n)\n\nvaldi_module(\n    name = \"{{MODULE_NAME}}\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]),\n    android_deps = [\":android_impl\"],\n    ios_deps = [\":ios_impl\"],\n    ios_module_name = \"{{MODULE_NAME_PASCAL_CASED}}\",\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":{{MODULE_NAME}}_web\"],\n    deps = [],\n)\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_bridge_module/android/CalculatorModuleFactory.kt.template",
    "content": "package com.snap.modules.{{MODULE_NAME}}\n\nimport com.snapchat.client.valdi_core.ModuleFactory\nimport com.snap.valdi.modules.RegisterValdiModule\nimport com.snap.modules.{{MODULE_NAME}}.CalculatorModuleFactory\nimport com.snap.modules.{{MODULE_NAME}}.CalculatorModule\n\n@RegisterValdiModule\nclass CalculatorModuleFactoryImpl: CalculatorModuleFactory() {\n\n    override fun onLoadModule(): CalculatorModule {\n        return object: CalculatorModule {\n            override fun multiply(left: Double, right: Double): Double {\n                return left * right\n            }\n        }\n    }\n}"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_bridge_module/ios/SCCCalculatorModuleFactory.m.template",
    "content": "#import \"valdi_core/SCValdiModuleFactoryRegistry.h\"\n#import <{{MODULE_NAME_PASCAL_CASED}}Types/{{MODULE_NAME_PASCAL_CASED}}Types.h>\n#import <Foundation/Foundation.h>\n\n@interface SCCCalculatorModule: NSObject<{{MODULE_NAME_PASCAL_CASED}}CalculatorModule>\n\n@end\n\n@implementation SCCCalculatorModule\n\n- (double)multiplyWithLeft:(double)left right:(double)right\n{\n    return left * right;\n}\n\n@end\n\n@interface SCCCalculatorModuleFactoryImpl : {{MODULE_NAME_PASCAL_CASED}}CalculatorModuleFactory\n\n@end\n\n@implementation SCCCalculatorModuleFactoryImpl\n\nVALDI_REGISTER_MODULE()\n\n- (id<{{MODULE_NAME_PASCAL_CASED}}CalculatorModule>)onLoadModule\n{\n    return [SCCCalculatorModule new];\n}\n\n@end"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_bridge_module/src/Calculator.d.ts",
    "content": "/**\n * @ExportModule\n */\nexport declare function multiply(left: number, right: number): number;\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_bridge_module/web/Calculator.ts",
    "content": "/**\n * Web implementation of the Calculator bridge module.\n *\n * Registered automatically by RegisterNativeModules.js via moduleLoader.\n */\n\nfunction multiply(left: number, right: number): number {\n  return left * right;\n}\n\nexport = { multiply };\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_bridge_module/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"lib\": [\"DOM\", \"ES2020\"],\n    \"module\": \"commonjs\",\n    \"moduleResolution\": \"node\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": false,\n    \"allowJs\": true\n  },\n  \"include\": [\n    \"./**/*.ts\",\n    \"./**/*.d.ts\"\n  ]\n}\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/BUILD.bazel.template",
    "content": "load(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"@valdi//bzl/valdi:valdi_android_library.bzl\", \"valdi_android_library\")\nload(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_android_library(\n    name = \"android_impl\",\n    srcs = glob([\n        \"android/**/*.kt\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":{{MODULE_NAME}}_api_kt\",\n        \"@valdi//valdi:valdi_java\",\n    ],\n)\n\nobjc_library(\n    name = \"ios_impl\",\n    srcs = glob([\n        \"ios/**/*.m\",\n    ]),\n    hdrs = glob([\n        \"ios/**/*.h\",\n    ]),\n    copts = [\"-I.\"],\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":{{MODULE_NAME}}_api_objc\",\n    ],\n)\n\nobjc_library(\n    name = \"macos_impl\",\n    srcs = glob([\n        \"macos/**/*.m\",\n    ]),\n    hdrs = glob([\n        \"macos/**/*.h\",\n    ]),\n    copts = [\"-I.\"],\n    sdk_frameworks = [\"AppKit\"],\n    visibility = [\"//visibility:public\"],\n)\n\nts_project(\n    name = \"{{MODULE_NAME}}_web\",\n    srcs = glob([\n        \"web/**/*.ts\",\n        \"web/**/*.d.ts\",\n    ]),\n    allow_js = True,\n    composite = False,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n    visibility = [\"//visibility:public\"],\n)\n\nvaldi_module(\n    name = \"{{MODULE_NAME}}\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]),\n    android_deps = [\":android_impl\"],\n    ios_deps = [\":ios_impl\"],\n    ios_module_name = \"SCC{{MODULE_NAME_PASCAL_CASED}}\",\n    macos_deps = [\":macos_impl\"],\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":{{MODULE_NAME}}_web\"],\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/foundation\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/android/PolyglotNativeView.kt.template",
    "content": "package com.snap.modules.{{MODULE_NAME}}\n\nimport android.content.Context\nimport android.graphics.Color\nimport android.view.MotionEvent\nimport android.view.ViewGroup\nimport android.widget.LinearLayout\nimport android.widget.TextView\nimport com.snap.valdi.views.ValdiTouchEventResult\nimport com.snap.valdi.views.ValdiTouchTarget\n\n/**\n * Android native view for the {{MODULE_NAME}} polyglot module.\n * ReflectionViewFactory requires a single-arg (Context) constructor.\n */\nclass PolyglotNativeView(context: Context) : LinearLayout(context), ValdiTouchTarget {\n\n    init {\n        orientation = VERTICAL\n        layoutParams = ViewGroup.LayoutParams(\n            ViewGroup.LayoutParams.MATCH_PARENT,\n            ViewGroup.LayoutParams.MATCH_PARENT\n        )\n        setBackgroundColor(Color.parseColor(\"#E8E8E8\"))\n\n        val label = TextView(context).apply {\n            text = \"Hello from Android ({{MODULE_NAME}})\"\n            setPadding(32, 32, 32, 16)\n        }\n        addView(label)\n    }\n\n    override fun processTouchEvent(event: MotionEvent): ValdiTouchEventResult {\n        val consumed = dispatchTouchEvent(event)\n        return if (consumed) {\n            ValdiTouchEventResult.ConsumeEventAndCancelOtherGestures\n        } else {\n            ValdiTouchEventResult.IgnoreEvent\n        }\n    }\n}\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/android/PolyglotNativeViewAttributesBinder.kt.template",
    "content": "package com.snap.modules.{{MODULE_NAME}}\n\nimport android.content.Context\nimport com.snap.valdi.attributes.AttributesBinder\nimport com.snap.valdi.attributes.AttributesBindingContext\nimport com.snap.valdi.attributes.RegisterAttributesBinder\n\n@RegisterAttributesBinder\nclass PolyglotNativeViewAttributesBinder constructor(private val context: Context) : AttributesBinder<PolyglotNativeView> {\n\n    override val viewClass: Class<PolyglotNativeView>\n        get() = PolyglotNativeView::class.java\n\n    override fun bindAttributes(attributesBindingContext: AttributesBindingContext<PolyglotNativeView>) {\n        // Add custom attribute bindings here.\n    }\n}\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/ios/SCPolyglotView.h",
    "content": "#import <UIKit/UIKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SCPolyglotView : UIView\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/ios/SCPolyglotView.m",
    "content": "#import \"SCPolyglotView.h\"\n\n@implementation SCPolyglotView\n\n- (instancetype)initWithFrame:(CGRect)frame {\n    self = [super initWithFrame:frame];\n    if (self) {\n        self.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1];\n\n        UILabel *label = [[UILabel alloc] init];\n        label.text = @\"Hello from iOS\";\n        label.translatesAutoresizingMaskIntoConstraints = NO;\n        [self addSubview:label];\n\n        [NSLayoutConstraint activateConstraints:@[\n            [label.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],\n            [label.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],\n        ]];\n    }\n    return self;\n}\n\n@end\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/macos/SCPolyglotView.h",
    "content": "#import <AppKit/AppKit.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface SCPolyglotView : NSView\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/macos/SCPolyglotView.m",
    "content": "#import \"SCPolyglotView.h\"\n\n@implementation SCPolyglotView\n\n- (instancetype)initWithFrame:(NSRect)frameRect {\n    self = [super initWithFrame:frameRect];\n    if (self) {\n        self.wantsLayer = YES;\n        self.layer.backgroundColor = [[NSColor colorWithWhite:0.93 alpha:1] CGColor];\n\n        NSTextField *label = [NSTextField labelWithString:@\"Hello from macOS\"];\n        label.translatesAutoresizingMaskIntoConstraints = NO;\n        [self addSubview:label];\n\n        [NSLayoutConstraint activateConstraints:@[\n            [label.centerXAnchor constraintEqualToAnchor:self.centerXAnchor],\n            [label.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],\n        ]];\n    }\n    return self;\n}\n\n@end\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/src/PolyglotCustomView.tsx.template",
    "content": "import 'valdi_tsx/src/JSX';\nimport { View } from 'valdi_tsx/src/NativeTemplateElements';\n\nexport interface PolyglotCustomViewModel extends View {}\n\n/**\n * Polyglot custom-view wrapper.\n *\n * Each platform resolves the view by class name:\n *  - Android: ReflectionViewFactory creates PolyglotNativeView(context)\n *  - iOS:     ObjC class linked via ios_deps\n *  - macOS:   NSClassFromString() linked via macos_deps\n *  - Web:     webPolyglotViews factory in web/ auto-registered at bundle time\n */\nexport function PolyglotCustomView(viewModel: PolyglotCustomViewModel) {\n  <custom-view\n    androidClass={'com.snap.modules.{{MODULE_NAME}}.PolyglotNativeView'}\n    iosClass={'SCPolyglotView'}\n    macosClass={'SCPolyglotView'}\n    webClass={'{{MODULE_NAME_PASCAL_CASED}}WebView'}\n    {...viewModel}\n  />;\n}\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/web/PolyglotWeb.ts.template",
    "content": "/**\n * Web polyglot entry for {{MODULE_NAME}}.\n *\n * Exports view factories that are auto-registered with the WebViewClassRegistry\n * by the build-generated RegisterNativeModules.js.\n */\n\nfunction createWebViewFactory(): (container: HTMLElement) => void {\n  return (container: HTMLElement) => {\n    container.style.display = 'flex';\n    container.style.alignItems = 'center';\n    container.style.justifyContent = 'center';\n    container.style.padding = '12px';\n    container.style.backgroundColor = '#f8f9fa';\n    container.style.borderRadius = '8px';\n    container.style.border = '1px solid #ccc';\n    container.style.minHeight = '80px';\n\n    const label = document.createElement('span');\n    label.textContent = 'Hello from Web ({{MODULE_NAME}})';\n    label.style.fontSize = '14px';\n    label.style.fontWeight = '500';\n    container.appendChild(label);\n  };\n}\n\nexport const webPolyglotViews: Record<string, (container: HTMLElement) => void> = {\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  {{MODULE_NAME_PASCAL_CASED}}WebView: createWebViewFactory(),\n};\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/polyglot_view_module/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"lib\": [\"DOM\", \"ES2020\"],\n    \"module\": \"commonjs\",\n    \"moduleResolution\": \"node\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": false,\n    \"allowJs\": true\n  },\n  \"include\": [\n    \"./**/*.ts\",\n    \"./**/*.d.ts\"\n  ]\n}\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/ui_component/BUILD.bazel.template",
    "content": "# Usage Instructions for This Module\n#\n# Step 1: Add this module to your `BUILD.bazel` file dependencies:\n#         `//src/valdi/{{MODULE_NAME}}`\n#\n# Step 2: Import the module in your `.tsx` file:\n#         `import { NewModuleComponent } from '{{MODULE_NAME}}/src/NewModuleComponent';`\n#\n# Step 3: Render the component in your `onRender()` function:\n#         `<NewModuleComponent title={'Valdi'}/>`\n\nload(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"{{MODULE_NAME}}\",\n    srcs = glob(\n        [\n            \"src/**/*.ts\",\n            \"src/**/*.tsx\",\n        ],\n    ),\n    res = glob([\n        \"res/**/*.jpeg\",\n        \"res/**/*.jpg\",\n        \"res/**/*.png\",\n        \"res/**/*.svg\",\n        \"res/**/*.webp\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "npm_modules/cli/.bootstrap/modules/ui_component/src/NewModuleComponent.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { Label, View } from 'valdi_tsx/src/NativeTemplateElements';\nimport { systemFont } from 'valdi_core/src/SystemFont';\nimport { Style } from 'valdi_core/src/Style';\n\nexport interface NewModuleViewModel {\n  title: string;\n}\n\nexport class NewModuleComponent extends Component<NewModuleViewModel> {\n  onCreate() {\n    // Called when the component is created in the render-tree\n    // Used to prepare some resources, precomputed values or subscribe to observables\n  }\n  onDestroy() {\n    // Called the component is not longer in the render-tree\n    // Used to dispose of resources and observables\n  }\n  onViewModelUpdate(previous?: NewModuleViewModel) {\n    // Called every time the view model changes\n    // Used to trigger some computations, typically used for asynchronous operations,\n    // that would then impact the internal component state\n  }\n\n  onRender(): void {\n    // Called every time the component needs to be rendered\n    // Used to define child components and child render-tree\n    // Can access \"this.viewModel\" that contains the current component parameters values\n    <view style={styles.root}>\n      <label style={styles.label} value={this.viewModel.title} />\n    </view>;\n  }\n}\n\nconst styles = {\n  root: new Style<View>({\n    backgroundColor: 'red',\n    width: '100%',\n    height: '100%',\n  }),\n  label: new Style<Label>({\n    font: systemFont(20),\n    color: 'white',\n  }),\n};\n"
  },
  {
    "path": "npm_modules/cli/.config/copyconfig.json",
    "content": "{\n  \"blacklist\": [\n    \"open_source/\\\\.aswb\",\n    \"open_source/bazel-.*\",\n    \"open_source/cli\",\n    \"open_source/docs\",\n    \"open_source/\\\\.git.*\",\n    \"\\\\.DS_Store\"\n  ]\n}\n"
  },
  {
    "path": "npm_modules/cli/.editorconfig",
    "content": "# EditorConfig is awesome: http://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n[*]\n# Unix-style newlines with a newline ending every file\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n# 4 spaces for indentation\nindent_size = 4\nindent_style = space\n\n# 120 characters max per line\nmax_line_length = 120\n\n# some files use 2 spaces for indentation\n[*.{json,yml,yaml}]\nindent_size = 2\n"
  },
  {
    "path": "npm_modules/cli/.eslintignore",
    "content": "/**/*.js\n"
  },
  {
    "path": "npm_modules/cli/.eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  parser: '@typescript-eslint/parser',\n  parserOptions: {\n    tsconfigRootDir: __dirname,\n    project: ['./tsconfig.json'],\n  },\n  plugins: ['@typescript-eslint', 'import'],\n  extends: [\n    'eslint:recommended',\n    'plugin:@typescript-eslint/recommended',\n    'plugin:@typescript-eslint/recommended-requiring-type-checking',\n    'plugin:import/recommended',\n    'plugin:import/typescript',\n    'plugin:unicorn/recommended',\n    'prettier',\n  ],\n  rules: {\n    eqeqeq: 'error',\n    '@typescript-eslint/consistent-type-assertions': [\n      'warn',\n      {\n        assertionStyle: 'as',\n        objectLiteralTypeAssertions: 'never',\n      },\n    ],\n    '@typescript-eslint/consistent-type-imports': [\n      'error',\n      {\n        prefer: 'type-imports',\n      },\n    ],\n    '@typescript-eslint/member-ordering': 'warn',\n    '@typescript-eslint/no-inferrable-types': ['error', { ignoreParameters: true }],\n    '@typescript-eslint/prefer-ts-expect-error': 'error',\n    '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],\n    '@typescript-eslint/no-misused-promises': [\n      'error',\n      {\n        checksVoidReturn: false,\n      },\n    ],\n    '@typescript-eslint/no-empty-function': 'off',\n    'import/default': 'off',\n    'import/namespace': 'off',\n    'import/no-unresolved': 'off',\n    'import/no-duplicates': 'error',\n    'import/no-named-as-default': 'error',\n    'import/order': ['warn', { alphabetize: { order: 'asc' } }],\n    'unicorn/filename-case': [\n      'error',\n      {\n        cases: {\n          camelCase: true,\n          pascalCase: true,\n        },\n        ignore: ['^.*CLI.*'],\n      },\n    ],\n    'unicorn/no-array-for-each': 'off',\n    'unicorn/no-array-reduce': 'off',\n    'unicorn/no-for-loop': 'off',\n    'unicorn/no-null': 'off',\n    'unicorn/prefer-node-protocol': 'off',\n    'unicorn/prefer-query-selector': 'off',\n    'unicorn/prefer-ternary': 'off',\n    'unicorn/prefer-top-level-await': 'off',\n    'unicorn/prefer-spread': 'off',\n    'unicorn/prevent-abbreviations': 'off',\n    'sort-imports': ['error', { allowSeparatedGroups: true, ignoreDeclarationSort: true }],\n  },\n};\n"
  },
  {
    "path": "npm_modules/cli/.github/README.md",
    "content": "# GitHub Actions CI for Valdi CLI\n\n## Workflows\n\n### 1. `test-cli-linux.yml` - Linux Distribution Testing\n\nTests the CLI on multiple Linux distributions to ensure proper distribution detection and package management.\n\n**Triggers:**\n- Pull requests touching CLI source files\n- Pushes to main branch\n- Manual workflow dispatch\n\n**Test Matrix:**\n- Ubuntu 22.04\n- Ubuntu 24.04\n- Fedora 39\n- Fedora 40\n\n**Tests:**\n1. **Distribution Detection**\n   - Verifies correct detection of distribution type (Debian, RedHat)\n   - Validates package manager identification (apt, dnf)\n   - Checks distribution name parsing\n\n2. **Package Name Mappings**\n   - Tests all common package mappings (git, npm, Java, etc.)\n   - Ensures correct package names for each distribution\n   - Validates fallback behavior\n\n3. **Install Command Generation**\n   - Tests single and multiple package installation commands\n   - Verifies correct package manager usage\n   - Validates sudo requirement handling\n\n4. **Git-LFS Setup Detection**\n   - Tests whether repository setup is needed\n   - Validates setup command generation\n   - Checks Debian vs RPM script selection\n\n5. **`valdi doctor` Integration**\n   - Runs the doctor command on each distribution\n   - Verifies it executes without errors\n   - Checks distribution-specific fix commands\n\n6. **Unit Tests**\n   - Runs Jasmine unit tests for `linuxDistro` utilities\n   - Validates ESLint compliance\n\n**Example Run:**\n\n```bash\n# Locally test distribution detection (requires Docker)\ndocker run -it ubuntu:22.04 bash\n# Install Node.js, clone repo, run tests\n\n# Or use act to run GitHub Actions locally\nact -j test-distribution-detection -P ubuntu-22.04=ubuntu:22.04\n```\n\n### 2. `bzl-changes.yml` - Main CI Pipeline (Updated)\n\n**Changes:**\n- Added `test-cli-linux` job to test CLI on Linux containers\n- Updated path triggers to include `npm_modules/cli/src/**`\n- Tests run alongside existing Bazel validation\n\n**Linux Job:**\n- Tests CLI on Ubuntu and Fedora\n- Validates distribution detection\n- Ensures package mappings work correctly\n\n### 3. `publish-npm.yml` - NPM Publishing\n\n**No changes needed** - builds and publishes on Ubuntu, which now benefits from the improved Linux support.\n\n## Running Tests Locally\n\n### Test Distribution Detection\n\n```bash\n# On your Linux machine\ncd npm_modules/cli\nnpm install\nnpm run build\n\n# Test distribution detection\nnode -e \"\n  const distro = require('./dist/utils/linuxDistro');\n  const detected = distro.detectLinuxDistro();\n  console.log('Detected:', detected);\n\"\n\n# Run unit tests\nnpx jasmine dist/utils/linuxDistro.spec.js\n```\n\n### Test on Multiple Distributions (Docker)\n\n```bash\n# Ubuntu 22.04\ndocker run --rm -v $(pwd):/workspace -w /workspace node:22-slim bash -c \"\n  apt-get update && apt-get install -y git\n  cd npm_modules/cli\n  npm install && npm run build\n  node -e \\\"const d = require('./dist/utils/linuxDistro'); console.log(d.detectLinuxDistro())\\\"\n\"\n\n# Fedora 39\ndocker run --rm -v $(pwd):/workspace -w /workspace node:22-slim bash -c \"\n  dnf install -y git\n  cd npm_modules/cli\n  npm install && npm run build\n  node -e \\\"const d = require('./dist/utils/linuxDistro'); console.log(d.detectLinuxDistro())\\\"\n\"\n```\n\n## CI Badge\n\nAdd this to your README to show CI status:\n\n```markdown\n![Test CLI on Linux](https://github.com/Snapchat/Valdi/actions/workflows/test-cli-linux.yml/badge.svg)\n```\n\n## Troubleshooting CI Failures\n\n### Distribution detection fails\n- Check `/etc/os-release` file exists in container\n- Verify `ID` and `ID_LIKE` fields are present\n- Check package manager is in PATH\n\n### Package mappings incorrect\n- Update `getCommonPackageMappings()` in `src/utils/linuxDistro.ts`\n- Add distribution-specific package names\n- Update unit tests to match\n\n### `valdi doctor` fails\n- Check if missing dependencies are expected for CI\n- Verify error handling works correctly\n- Ensure fix commands use correct distribution detection\n\n## Adding New Distributions to CI\n\nTo add a new distribution to the test matrix:\n\n1. Edit `.github/workflows/test-cli-linux.yml`\n2. Add to the matrix:\n   ```yaml\n   - distro: new-distro-name\n     container: distro:version\n     expected_type: debian|redhat|arch|suse\n     expected_pm: apt|dnf|pacman|zypper\n     expected_name_pattern: \"Distro Name\"\n   ```\n3. Ensure the distribution has Node.js 22+ support\n4. Test locally with Docker first\n\n## Notes\n\n- **Arch Linux** and **openSUSE** are not in CI due to container availability/complexity\n- CI uses Docker containers for isolation\n- Tests are read-only - we don't actually install packages in CI\n- Manual testing on physical distributions is still recommended for full coverage\n"
  },
  {
    "path": "npm_modules/cli/.gitignore",
    "content": ".DS_Store\n/node_modules\n/coverage\n/.idea\n/.eslintcache\n/dist\n/bundled-skills\n"
  },
  {
    "path": "npm_modules/cli/.metadata/.bazelrc.template",
    "content": "# No bzlmod yet\ncommon --noenable_bzlmod\n\ncommon --bes_instance_name=client\ncommon --enable_platform_specific_config\n\n# Disable workers for repo fetching to prevent OOM\ncommon --experimental_worker_for_repo_fetching=off\n\n# android configuration\n# Expose AndroidResourceInfo provider to Kotlin rules\ncommon --experimental_google_legacy_api=true\ncommon --experimental_enable_android_migration_apis=true\ncommon --incompatible_java_common_parameters=false\n\n# Flags for compilation\ncommon --define enable_web=true\n\nbuild --tool_java_language_version=11\nbuild --java_language_version=11\n\n## Disable sandboxing for macs, both laptops and in CI; the performance hit is much too high.\nbuild:macos --spawn_strategy=local\nbuild:linux --sandbox_writable_path=/var/tmp\n\n# common cc configuration\nbuild --cxxopt=-std=c++20\nbuild --cxxopt=-Wno-ambiguous-reversed-operator\nbuild --cxxopt=-D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS\nbuild --host_cxxopt=-std=c++20\n\n## we need to disable this due to a bug in bazel\n## see https://github.com/bazelbuild/bazel/issues/12381\nbuild --incompatible_use_specific_tool_files=false\nbuild --incompatible_enable_cc_toolchain_resolution\n\n# iOS and Apple cc changes and hacks\n## For Objective-C source files\nbuild --per_file_copt=.*\\.mm\\$@-std=c++20\nbuild --host_per_file_copt=.*\\.mm\\$@-std=c++20\nbuild --ios_minimum_os=12.0\n\n## TODO: (dchapp) this is currently needed otherwise -O0 and -DDEBUG=1 get passed to compilations of .mm/.m for production flavor builds\nbuild --experimental_objc_fastbuild_options=\"\"\n## HACK inject this in the default toolchain which is only used on macos until we switch to bazel_toolchains\nbuild:macos --copt=-fvisibility=hidden\n\n# java configuration\n## Disable some java checks for now, djinni generates code that errors out\nbuild --javacopt=-XepDisableAllChecks\nbuild --java_runtime_version=11\nbuild --tool_java_runtime_version=17\n\nbuild --flag_alias=snap_flavor=@snap_platforms//flavors:snap_flavor\nbuild --snap_flavor=platform_development\n\nbuild --android_crosstool_top=@androidndk//:toolchain\nbuild --define=android_dexmerger_tool=d8_dexmerger\nbuild --define=android_incremental_dexing_tool=d8_dexbuilder\nbuild --define=android_standalone_dexing_tool=d8_compat_dx\nbuild --incremental_dexing\n\n# Disable 3rd party libs warnings\nbuild --per_file_copt=external/com_github_grpc_grpc/.*\\$@-Wno-everything\nbuild --per_file_copt=external/snap_protobuf/.*\\$@-Wno-everything\nbuild --per_file_copt=external/boringssl/.*\\$@-Wno-everything\nbuild --per_file_copt=external/com_github_google_flatbuffers/.*\\$@-Wno-everything\n\n# Enable persistent worker for Valdi compilation\nbuild --strategy=ValdiCompile=worker\n\n## Disable sandboxing for macs, both laptops and in CI; the performance hit is much too high.\nbuild:macos --spawn_strategy=local\nbuild:linux --sandbox_writable_path=/var/tmp\n\n# Disable disk cache to save disk space\n# https://docs.google.com/document/d/1N8W_M83n9jhMi7pgUhXuEuxypb3dmlHBu_CG_eXipXI/edit?usp=sharing\nbuild --disk_cache=\"\"\n\n# common build configuration\nbuild --experimental_generate_json_trace_profile\n# enable grpc log\nbuild --remote_grpc_log=/tmp/snap_client_grpc.log\nbuild --experimental_reuse_sandbox_directories\n\n# Default JS engine\nbuild --flag_alias=valdi_js_engine=@valdi//bzl/valdi:js_engine\nbuild --valdi_js_engine=hermes\n\n# Valdi Open Source Flags\nbuild --define=open_source_build=true\n"
  },
  {
    "path": "npm_modules/cli/.metadata/.bazelversion.template",
    "content": "7.2.1\n"
  },
  {
    "path": "npm_modules/cli/.metadata/.editorconfig.template",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{ts,tsx,js,jsx}]\nindent_style = space\nindent_size = 2\n\n[*.{cpp,hpp,h,cc}]\nindent_style = space\nindent_size = 4\n\n[*.{swift,kt,java}]\nindent_style = space\nindent_size = 4\n\n[*.{yml,yaml,json}]\nindent_style = space\nindent_size = 2\n\n[*.{bzl,bazel,BUILD}]\nindent_style = space\nindent_size = 4\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[*.{mm,m}]\nindent_style = space\nindent_size = 4\n\n[Makefile]\nindent_style = tab\n"
  },
  {
    "path": "npm_modules/cli/.metadata/.eslintrc.js.template",
    "content": "\nmodule.exports = {\n  root: true,\n  parser: '@typescript-eslint/parser',\n  parserOptions: {\n    tsconfigRootDir: __dirname,\n    project: ['./src/valdi/_configs/eslint.tsconfig.json'],\n  },\n  plugins: ['@typescript-eslint', 'unused-imports', 'rxjs', 'prettier', '@snapchat/eslint-plugin-valdi'],\n  extends: [\n    'eslint:recommended',\n    'plugin:@typescript-eslint/recommended',\n    'plugin:import/recommended',\n    'plugin:import/typescript',\n    'prettier',\n  ],\n  rules: { \n    '@snapchat/valdi/attributed-text-no-array-assignment': 'error',\n    '@snapchat/valdi/jsx-no-lambda': 'error',\n    '@snapchat/valdi/assign-timer-id': 'error',\n    '@snapchat/valdi/only-const-enum': 'off',\n    '@snapchat/valdi/no-implicit-index-import': 'error',\n    '@snapchat/valdi/mutate-state-without-set-state': 'error',\n    '@snapchat/valdi/no-import-from-test-outside-test-dir': 'error',\n    '@snapchat/valdi/no-declare-test-without-describe': 'error', \n  },\n};\n"
  },
  {
    "path": "npm_modules/cli/.metadata/.gitignore.template",
    "content": "*.DS_Store\n\nbazel-*\nnode_modules\n"
  },
  {
    "path": "npm_modules/cli/.metadata/.prettierrc.json.template",
    "content": "{\n  \"printWidth\": 120,\n  \"singleQuote\": true,\n  \"jsxSingleQuote\": true,\n  \"arrowParens\": \"avoid\",\n  \"trailingComma\": \"all\"\n}\n"
  },
  {
    "path": "npm_modules/cli/.metadata/.watchmanconfig.template",
    "content": "{\n    \"root_files\": [\".watchmanconfig\"],\n    \"ignore_dirs\": [\n        \"bazel-out\",\n        \"bazel-bin\",\n        \"bazel-testlogs\"\n    ]\n}\n"
  },
  {
    "path": "npm_modules/cli/.metadata/AGENTS.md.template",
    "content": "# AI Assistant Context\n\nThis is a Valdi application. Valdi compiles TypeScript/TSX to native iOS, Android, and macOS views — it is **not React**.\n\n## Get AI Skills\n\nInstall context files so your AI tool generates correct Valdi code instead of React patterns:\n\n```bash\nnpm install -g @snap/valdi\nvaldi skills install          # installs skills for Claude Code, Cursor, or Copilot\n```\n\nSkills are bundled in the npm package and work offline. They cover component patterns, lifecycle, async handling, build rules, testing, and platform bridging.\n\nFor documentation and support: https://github.com/Snapchat/Valdi\n"
  },
  {
    "path": "npm_modules/cli/.metadata/README.md.template",
    "content": "# valdi_demo\nDemo of a hello world app using Valdi open source\n\n## Usage\n\nAll commands requires `valdi` to be available on PATH.\n\nGet auto completion in VSCode\n```sh\nvaldi projectsync\n```\n\nBuild and install iOS:\n```sh\nvaldi install ios\n```\n\nBuild and install Android:\n```sh\nvaldi install android\n```\n\nBuild and install MacOS:\n```sh\nvaldi install macos\n```\n\nStart hot reloader:\n```sh\nvaldi hotreload\n```\n"
  },
  {
    "path": "npm_modules/cli/.metadata/WORKSPACE.template",
    "content": "workspace(name = \"{{WORKSPACE_NAME}}\")\n\nload(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"git_repository\")\nload(\"@bazel_tools//tools/build_defs/repo:http.bzl\", \"http_archive\")\n\n{{VALDI_IMPORT}}\n\n{{VALDI_WIDGETS_IMPORT}}\n\nload(\"@valdi//bzl:workspace_prepare.bzl\", \"valdi_prepare_workspace\")\n\nvaldi_prepare_workspace()\n\nload(\"@valdi//bzl:workspace_preinit.bzl\", \"valdi_preinitialize_workspace\")\n\nvaldi_preinitialize_workspace()\n\nload(\"@aspect_bazel_lib//lib:repositories.bzl\", \"aspect_bazel_lib_dependencies\", \"aspect_bazel_lib_register_toolchains\", \"register_yq_toolchains\")\n\nregister_yq_toolchains()\n\n# Required bazel-lib dependencies\n\naspect_bazel_lib_dependencies()\n\n# Required rules_shell dependencies\nload(\"@rules_shell//shell:repositories.bzl\", \"rules_shell_dependencies\", \"rules_shell_toolchains\")\n\nrules_shell_dependencies()\n\nrules_shell_toolchains()\n\n# Register bazel-lib toolchains\n\naspect_bazel_lib_register_toolchains()\n\n# Create the host platform repository transitively required by bazel-lib\n\nload(\"@bazel_tools//tools/build_defs/repo:utils.bzl\", \"maybe\")\nload(\"@platforms//host:extension.bzl\", \"host_platform_repo\")\n\nmaybe(\n    host_platform_repo,\n    name = \"host_platform\",\n)\n\nload(\"@valdi//bzl:workspace_init.bzl\", \"valdi_initialize_workspace\")\n\nvaldi_initialize_workspace()\n\nload(\"@valdi_npm//:repositories.bzl\", \"npm_repositories\")\n\nnpm_repositories()\n\nload(\"@valdi//bzl:workspace_postinit.bzl\", \"valdi_post_initialize_workspace\")\n\nvaldi_post_initialize_workspace()\n"
  },
  {
    "path": "npm_modules/cli/.metadata/config.yaml.template",
    "content": "logs_output_dir: ~/.valdi/logs\n"
  },
  {
    "path": "npm_modules/cli/.metadata/package.json.template",
    "content": "{\n  \"name\": \"hello_world\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Valdi Helloworld app\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@snap/eslint-plugin-valdi\": \"1.0.2\",\n    \"@types/eslint\": \"^9.6.1\",\n    \"@types/jasmine\": \"^5.1.7\",\n    \"@typescript-eslint/eslint-plugin\": \"^6.21.0\",\n    \"@typescript-eslint/parser\": \"^6.21.0\",\n    \"@typescript-eslint/utils\": \"^6.21.0\",\n    \"eslint\": \"^8.27.0\",\n    \"eslint-config-prettier\": \"^8.5.0\",\n    \"eslint-plugin-import\": \"^2.26.0\",\n    \"eslint-plugin-prettier\": \"^4.2.1\",\n    \"eslint-plugin-rxjs\": \"^5.0.2\",\n    \"eslint-plugin-unused-imports\": \"^3.2.0\",\n    \"jasmine\": \"^5.6.0\",\n    \"ts-node\": \"^10.9.2\",\n    \"typescript\": \"5.3.3\"\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/.metadata/skill-reference.tsx.template",
    "content": "// SKILL_NAME skill reference — compile check for patterns in ../skill.md.\n// Add code that exercises every import path and API shown in the skill.\n// Run: bazel build //ai-skills/skills/SKILL_NAME/tests:tests\n\nimport { Component } from 'valdi_core/src/Component';\n\n// TODO: add reference examples here\nvoid Component;\n"
  },
  {
    "path": "npm_modules/cli/.metadata/skill-tests-BUILD.bazel.template",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"tests\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SKILL_IOS_MODULE_NAME\",\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        # Add deps for the imports used in src/reference.tsx\n        # Common options: valdi_core, valdi_tsx, valdi_http, foundation, valdi_test, jasmine\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "npm_modules/cli/.metadata/skill-tests-README.md.template",
    "content": "# SKILL_NAME skill tests\n\nCompile check for the patterns taught in `../skill.md`.\n\n## Compile check\n\n```bash\ncd client/src/open_source\nbazel build //ai-skills/skills/SKILL_NAME/tests:tests\n```\n\nExpected: `Build completed successfully`\n\n## Updating\n\nWhen Valdi APIs change (import paths, type signatures), update `src/reference.tsx` to match.\nAlso update `../skill.md` with any corrected patterns.\n"
  },
  {
    "path": "npm_modules/cli/.metadata/skill.md.template",
    "content": "# SKILL_NAME\n\nSKILL_DESCRIPTION\n\n## When to use\n\nDescribe the scenarios or file types where this skill applies.\n\n## Key concepts\n\nExplain the important concepts for this area of Valdi.\n\n## Correct patterns\n\n```typescript\n// ✅ Correct example\n```\n\n## Common mistakes\n\n```typescript\n// ❌ Wrong example — explain why\n```\n\n## More information\n\n- Valdi docs: https://github.com/Snapchat/Valdi\n"
  },
  {
    "path": "npm_modules/cli/.prettierignore",
    "content": "node_modules\n.vscode\n"
  },
  {
    "path": "npm_modules/cli/.prettierrc.json",
    "content": "{\n  \"printWidth\": 120,\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"arrowParens\": \"avoid\",\n  \"tabWidth\": 2\n}\n"
  },
  {
    "path": "npm_modules/cli/LINUX_COMPATIBILITY.md",
    "content": "# Linux Distribution Compatibility\n\nThis document describes how the Valdi CLI handles different Linux distributions.\n\n## Overview\n\nThe Valdi CLI (`valdi doctor` and `valdi dev_setup` commands) now supports multiple Linux distributions beyond just Debian/Ubuntu. The CLI automatically detects your distribution and uses the appropriate package manager and package names.\n\n## Supported Distributions\n\n### Tier 1 Support (Fully Tested)\n- **Debian-based**: Debian, Ubuntu, Linux Mint, Pop!_OS, etc.\n  - Package manager: `apt`\n  - Tested on: Ubuntu 22.04, Debian 12\n\n### Tier 2 Support (Community Tested)\n- **Red Hat-based**: Fedora, RHEL, CentOS, Rocky Linux, AlmaLinux\n  - Package manager: `dnf` or `yum`\n  - Notes: Some packages (like watchman) may require EPEL repository\n\n- **Arch-based**: Arch Linux, Manjaro, EndeavourOS\n  - Package manager: `pacman`\n  - Notes: Some packages may be in AUR\n\n- **SUSE-based**: openSUSE, SLES\n  - Package manager: `zypper`\n\n## How Distribution Detection Works\n\nThe CLI detects your distribution using the following methods (in order):\n\n1. **`/etc/os-release`**: Reads the standard Linux distribution information file\n   - Uses `ID` and `ID_LIKE` fields to determine distribution family\n   - Extracts distribution name and version\n\n2. **Package Manager Detection**: Falls back to detecting available package managers\n   - Checks for `apt-get`, `dnf`, `yum`, `pacman`, or `zypper`\n\n3. **Unknown Distributions**: If detection fails, provides manual installation instructions\n\n## Package Mappings\n\nDifferent distributions use different package names for the same software. The CLI includes mappings for common dependencies:\n\n| Dependency | Debian/Ubuntu | Red Hat/Fedora | Arch Linux | openSUSE |\n|------------|---------------|----------------|------------|----------|\n| Java 17 JDK | `openjdk-17-jdk` | `java-17-openjdk-devel` | `jdk17-openjdk` | `java-17-openjdk-devel` |\n| Android Debug Bridge | `adb` | `android-tools` | `android-tools` | `android-tools` |\n| Fontconfig Dev | `libfontconfig1-dev` | `fontconfig-devel` | `fontconfig` | `fontconfig-devel` |\n| Zlib Dev | `zlib1g-dev` | `zlib-devel` | `zlib` | `zlib-devel` |\n| Git LFS | `git-lfs` | `git-lfs` | `git-lfs` | `git-lfs` |\n| Watchman | `watchman` | `watchman` | `watchman` | `watchman` |\n\n## Commands\n\n### `valdi dev_setup`\n\nThe `dev_setup` command automatically installs required dependencies for your distribution:\n\n```bash\nvaldi dev_setup\n```\n\n**What it does:**\n1. Detects your Linux distribution\n2. Installs the following dependencies:\n   - Node.js/npm (if not installed)\n   - Java 17 JDK\n   - Git LFS\n   - Watchman (for hot reload)\n   - Android Debug Bridge (adb)\n   - Development libraries (fontconfig, zlib)\n   - Additional distribution-specific packages\n3. Downloads and installs Bazelisk\n4. Sets up Android SDK with command-line tools\n5. Configures environment variables in your shell RC file\n\n**Distribution-specific behavior:**\n\n- **Debian/Ubuntu**: \n  - Sets up packagecloud repository for git-lfs\n  - Installs `libtinfo5` for Android command-line tools compatibility\n\n- **Red Hat/Fedora**:\n  - Sets up packagecloud RPM repository for git-lfs\n  - Installs `ncurses-compat-libs` for Android tools\n  - Shows warning if EPEL repository is needed for watchman\n\n- **Arch Linux**:\n  - Uses standard repositories (most packages available)\n  - May require AUR helper for some packages\n\n- **openSUSE**:\n  - Uses zypper to install packages\n\n### `valdi doctor`\n\nThe `doctor` command checks your development environment and provides distribution-specific fix commands:\n\n```bash\nvaldi doctor\n```\n\n**Features:**\n- Detects your distribution automatically\n- Provides correct package manager commands for your distribution\n- Shows distribution-specific warnings (e.g., EPEL repository for RHEL)\n- Validates all required tools are installed\n\n**Example output on Fedora:**\n\n```\nRunning Valdi environment diagnostics...\nDetected distribution: Fedora Linux (dnf)\n\n✓ Node.js installation\n✗ Java installation\n  • Java not found in PATH\n  Fix: sudo dnf install java-17-openjdk-devel\n```\n\n## Troubleshooting\n\n### Watchman on Red Hat/Fedora\n\nWatchman may not be available in the default repositories. Enable EPEL:\n\n```bash\n# Fedora\nsudo dnf install epel-release\n\n# RHEL/CentOS\nsudo yum install epel-release\n```\n\nThen install watchman:\n\n```bash\nsudo dnf install watchman\n# or\nsudo yum install watchman\n```\n\n### Packages in AUR (Arch Linux)\n\nSome packages may only be available in the AUR. Use an AUR helper like `yay` or `paru`:\n\n```bash\nyay -S watchman\n```\n\n### Unknown Distribution\n\nIf your distribution is not automatically detected, you'll see:\n\n```\nUnable to detect Linux distribution.\nPlease manually install the following dependencies and re-run this command:\n  - git\n  - git-lfs\n  - npm (Node.js)\n  - openjdk-17-jdk (or equivalent Java 17 JDK)\n  - watchman\n  - adb (Android Debug Bridge)\n  - fontconfig development libraries\n  - zlib development libraries\n```\n\nConsult your distribution's package manager documentation for the correct package names.\n\n### Distribution Detection Issues\n\nIf distribution detection fails or provides incorrect results:\n\n1. Check that `/etc/os-release` exists and is readable:\n   ```bash\n   cat /etc/os-release\n   ```\n\n2. Verify your package manager is in PATH:\n   ```bash\n   which apt-get  # or dnf, yum, pacman, zypper\n   ```\n\n3. Report the issue with your distribution details:\n   - Distribution name and version\n   - Output of `cat /etc/os-release`\n   - Available package manager\n\n## Contributing\n\nTo add support for a new distribution:\n\n1. Add package mappings in `src/utils/linuxDistro.ts`:\n   ```typescript\n   // In getCommonPackageMappings()\n   'your-package': {\n     debian: 'debian-package-name',\n     redhat: 'redhat-package-name',\n     arch: 'arch-package-name',\n     suse: 'suse-package-name',\n     fallback: 'generic-package-name',\n   }\n   ```\n\n2. Add distribution detection logic in `detectLinuxDistro()` if needed\n\n3. Test on the target distribution:\n   ```bash\n   valdi dev_setup\n   valdi doctor\n   ```\n\n4. Update this documentation with your findings\n\n## Technical Details\n\n### Files Modified\n- `src/utils/linuxDistro.ts` - Distribution detection and package mapping utilities\n- `src/setup/linuxSetup.ts` - Linux-specific dev_setup implementation\n- `src/commands/doctor.ts` - Environment diagnostics with distribution-aware fix commands\n\n### Distribution Detection API\n\n```typescript\nimport { detectLinuxDistro, buildInstallCommand, getPackageName } from './utils/linuxDistro';\n\n// Detect distribution\nconst distro = detectLinuxDistro();\nconsole.log(distro.name); // e.g., \"Ubuntu\"\nconsole.log(distro.type); // e.g., LinuxDistroType.DEBIAN\nconsole.log(distro.packageManager.name); // e.g., \"apt\"\n\n// Build install command\nconst cmd = buildInstallCommand(['git', 'npm', 'watchman'], distro);\nconsole.log(cmd); // e.g., \"sudo apt-get install git npm watchman\"\n\n// Get package name for current distribution\nconst packageMappings = getCommonPackageMappings();\nconst javaPackage = getPackageName(packageMappings['openjdk-17'], distro);\nconsole.log(javaPackage); // e.g., \"openjdk-17-jdk\" on Ubuntu\n```\n\n## See Also\n\n- [Valdi Installation Guide](https://github.com/Snapchat/Valdi/blob/main/docs/INSTALL.md)\n- [Development Setup Guide](https://github.com/Snapchat/Valdi/blob/main/docs/DEV_SETUP.md)\n- [Contributing Guidelines](https://github.com/Snapchat/Valdi/blob/main/CONTRIBUTING.md)\n"
  },
  {
    "path": "npm_modules/cli/README.md",
    "content": "# Valdi CLI\n\nThe Valdi CLI tool provides helpful commands for setting up your environment, creating projects, building applications, and managing your Valdi workflow.\n\n## For Users\n\nThe CLI is published to npm as `@snap/valdi`:\n\n```bash\n# Install globally\nnpm install -g @snap/valdi\n\n# Set up your development environment\nvaldi dev_setup\n\n# Verify your setup\nvaldi doctor\n\n# Get help\nvaldi --help\n```\n\n### Create Your First App\n\nAfter setting up your environment, create a new Valdi project:\n\n```bash\n# Create a new directory for your project\nmkdir my_valdi_app\ncd my_valdi_app\n\n# Initialize the project\nvaldi bootstrap\n\n# Build and install on iOS\nvaldi install ios\n\n# Or build and install on Android\nvaldi install android\n\n# Start hot reload for development\nvaldi hotreload\n```\n\nNow you can edit your TypeScript files and see changes instantly on your device!\n\nFor complete documentation, see:\n- [Command Line Reference](https://github.com/Snapchat/Valdi/blob/main/docs/docs/command-line-references.md)\n- [Installation Guide](https://github.com/Snapchat/Valdi/blob/main/docs/INSTALL.md)\n- [Troubleshooting](https://github.com/Snapchat/Valdi/blob/main/docs/TROUBLESHOOTING.md) — run `valdi doctor` to diagnose issues, or ask on [Discord](https://discord.gg/uJyNEeYX2U)\n\n### Key Commands\n\n**`valdi dev_setup`** - Automated environment setup\n- Installs all required dependencies (Bazel, Node.js, Java JDK 17, Android SDK, etc.)\n- Configures environment variables and PATH\n- Initializes Git LFS\n- Sets up shell autocomplete\n- Platform-specific: macOS (Homebrew, Xcode) or Linux (apt packages)\n\n**`valdi doctor`** - Environment diagnostics\n- Validates Node.js, Bazel, Java, Android SDK installations\n- Checks Git LFS initialization\n- Verifies shell autocomplete configuration\n- Checks VSCode/Cursor extensions (warns if missing)\n- macOS: Validates Xcode installation\n- Supports `--framework` mode for additional checks\n- Supports `--fix` to auto-repair issues\n- Supports `--json` for CI/CD integration\n\n**`valdi bootstrap`** - Project initialization\n- Creates a new Valdi project in the current directory\n- Sets up BUILD.bazel, WORKSPACE, package.json, and source files\n- Supports multiple application templates (Hello World, Counter, etc.)\n- Options: `-y` (skip confirmation), `-n` (project name), `-t` (application type), `-l` (local Valdi path), `-c` (clean directory first). Run `valdi bootstrap --help` for all options.\n\n**`valdi install <platform>`** - Build and install\n- Builds and installs app to connected device/simulator\n- Platforms: `ios`, `android`, `macos`\n\n**`valdi hotreload`** - Development server\n- Enables instant hot reload during development\n- Watches for file changes and updates app in milliseconds\n\n**`valdi skills`** - AI assistant skills\n- Installs Valdi context files into Claude Code, Cursor, or GitHub Copilot so AI tools generate correct Valdi code instead of React patterns\n- `valdi skills install` — auto-detects installed AI tools and installs all skills\n- `valdi skills list` — show available skills and install status per agent\n- `valdi skills update` — re-install already-installed skills from the bundled package\n- `valdi skills create` — scaffold a new skill (run from within the Valdi repo)\n\n**Other commands:** `valdi build <platform>` (build without installing), `valdi package <platform>` (create distributable app), `valdi export <platform>` (export library for native apps), `valdi test` (run tests), `valdi lint check` / `valdi lint format` (lint and format code), `valdi log` (stream device logs), `valdi projectsync` (sync VS Code project and native bindings), `valdi completion` (shell autocomplete setup). Use `valdi <command> --help` for options.\n\nFor complete command documentation, see [Command Line Reference](https://github.com/Snapchat/Valdi/blob/main/docs/docs/command-line-references.md).\n\n### Creating New Modules\n\n```sh\nvaldi new_module\n\n# Create module without prompts (specify template to skip the prompt)\nvaldi new_module my_new_module --skip-checks --template=ui_component\n\n# Help\n$ valdi new_module --help\nvaldi new_module [module-name]\n\n\n******************************************\nValdi Module Creation Guide\n******************************************\n\nRequirements for Valdi module names:\n- May contain: A-Z, a-z, 0-9, '-', '_', '.'\n- Must start with a letter.\n\nRecommended Directory Structure:\nmy_application/          # Root directory of your application\n├── WORKSPACE            # Bazel Workspace\n├── BUILD.bazel          # Bazel build\n└── modules/\n    ├── module_a/\n    │   ├── BUILD.bazel\n    │   ├── android/     # Native Android sources (Kotlin)\n    │   ├── ios/         # Native iOS sources (Objective-C)\n    │   ├── macos/       # Native macOS sources (Objective-C)\n    │   ├── web/         # Web sources (TypeScript, compiled by tsc)\n    │   ├── cpp/         # Native C++ sources\n    │   └── src/         # Valdi sources\n    │       └── ModuleAComponent.tsx\n    ├── module_b/\n        ├── BUILD.bazel\n    │   ├── res/         # Image and font resources\n    │   ├── strings/     # Localizable strings\n        └── src/\n            └── ModuleBComponent.tsx\n\nFor more comprehensive details, refer to the core-module documentation:\nhttps://github.com/Snapchat/Valdi/blob/main/docs/docs/core-module.md\n\n******************************************\n\n\nPositionals:\n  module-name  Name of the Valdi module.\n\nOptions:\n  --debug        Run with debug logging                    [boolean] [default: false]\n  --version      Show version number                       [boolean]\n  --help         Show help                                 [boolean]\n  --skip-checks  Skips confirmation prompts.               [boolean]\n  --template     Module template to use (skips the prompt). One of: ui_component, polyglot_bridge_module, polyglot_view_module  [string]\n```\n\n## For Contributors\n\nThis section is for developers working on the Valdi CLI itself.\n\n### Prerequisites\n\nSet your npm registry when working on this module:\n\n```sh\nnpm config set registry https://registry.npmjs.org/\n```\n\n### Development Setup\n\nInstall dependencies:\n\n```sh\nnpm install\n```\n\n### Development\n\nRun the CLI:\n\n```sh\nnpm run main\n```\n\n# Pass in command line arguments\n\n```sh\nnpm run main bootstrap -- --confirm-bootstrap\n```\n\nBuild JavaScript output to `./dist`:\n\n```sh\nnpm run build\n```\n\nDevelop with hot reload:\n\n```sh\nnpm run watch\nnode ./dist/index.js\nnode ./dist/index.js bootstrap --confirm-bootstrap\n```\n\nShow the help menu:\n\n```sh\nnode ./dist/index.js new_module --help\n```\n\nRun unit tests:\n\n```sh\nnpm test\n```\n\nInstall the `valdi` command locally:\n\n```sh\nnpm run cli:install\n```\n"
  },
  {
    "path": "npm_modules/cli/package.json",
    "content": "{\n  \"name\": \"@snap/valdi\",\n  \"version\": \"1.0.8\",\n  \"description\": \"Valdi CLI tools for developers\",\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Snapchat/Valdi.git\",\n    \"directory\": \"npm_modules/cli\"\n  },\n  \"publishConfig\": { \"access\": \"public\" },\n  \"bin\": {\n    \"valdi\": \"dist/index.js\"\n  },\n  \"files\": [\n    \"dist\",\n    \"bundled-skills\"\n  ],\n  \"scripts\": {\n    \"prepare\": \"npm run build\",\n    \"prebuild\": \"node scripts/bundle-skills.js\",\n    \"build\": \"npm exec --package=typescript@5.9.2 tsc -- --project ./tsconfig.dist.json\",\n    \"test\": \"ts-node node_modules/jasmine/bin/jasmine\",\n    \"watch\": \"tsc --watch\",\n    \"main\": \"ts-node ./src/index.ts\",\n    \"format\": \"prettier --ignore-path .gitignore --write \\\"**/*.+(js|ts|json)\\\"\",\n    \"eslint\": \"eslint './{src,test}/**/*.{ts,tsx}'\",\n    \"eslint:fix\": \"npm run eslint -- --fix\",\n    \"cli:install\": \"npm ci && npm link\",\n    \"cli:uninstall\": \"PKG_NAME=$(npm pkg get name | tr -d '\\\"') && npm uninstall $PKG_NAME -g\",\n    \"cli:uninstall_all\": \"PKG_NAME=$(npm pkg get name | tr -d '\\\"') && npm uninstall $PKG_NAME && npm uninstall -g $PKG_NAME\",\n    \"update-agents-templates\": \"ts-node scripts/update-agents-templates.ts\",\n    \"validate-agents\": \"bash scripts/sync-agents-md.sh\"\n  },\n  \"dependencies\": {\n    \"@bazel/bazelisk\": \"^1.19.0\",\n    \"@types/inquirer\": \"^9.0.7\",\n    \"@types/yargs\": \"^17.0.32\",\n    \"@typescript-eslint/eslint-plugin\": \"^5.59.9\",\n    \"eslint\": \"^8.42.0\",\n    \"eslint-config-prettier\": \"^8.8.0\",\n    \"eslint-plugin-import\": \"^2.27.5\",\n    \"eslint-plugin-unicorn\": \"^47.0.0\",\n    \"extract-zip\": \"^2.0.1\",\n    \"glob\": \"^11.0.1\",\n    \"inquirer\": \"^8.0.0\",\n    \"jsonc-parser\": \"^3.3.1\",\n    \"ora\": \"^8.2.0\",\n    \"prettier\": \"^3.3.1\",\n    \"tslib\": \"^2.5.3\",\n    \"typescript\": \"^5.3.3\",\n    \"yaml\": \"^2.4.5\",\n    \"yargs\": \"^17.7.2\"\n  },\n  \"devDependencies\": {\n    \"@types/eslint\": \"^9.6.1\",\n    \"@types/jasmine\": \"^5.1.7\",\n    \"jasmine\": \"^5.6.0\",\n    \"ts-node\": \"^10.9.2\"\n  },\n  \"overrides\": {\n    \"brace-expansion\": \"2.0.2\"\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/prettier.config.js",
    "content": "module.exports = {\n  trailingComma: 'all',\n  arrowParens: 'avoid',\n};\n"
  },
  {
    "path": "npm_modules/cli/scripts/bundle-skills.js",
    "content": "#!/usr/bin/env node\n// Copies ai-skills/ into bundled-skills/ inside the CLI package so skills are\n// available at runtime without any network requests.\n'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\n\nconst src = path.resolve(__dirname, '..', '..', '..', 'ai-skills');\nconst dest = path.resolve(__dirname, '..', 'bundled-skills');\n\nif (!fs.existsSync(src)) {\n  console.log(`bundle-skills: ${src} not found, skipping`);\n  process.exit(0);\n}\n\nif (fs.existsSync(dest)) {\n  fs.rmSync(dest, { recursive: true });\n}\n\nfs.cpSync(src, dest, { recursive: true });\nconsole.log(`bundle-skills: copied ai-skills/ → bundled-skills/`);\n"
  },
  {
    "path": "npm_modules/cli/scripts/sync-agents-md.sh",
    "content": "#!/bin/bash\n# Sync AGENTS.md content between root and bootstrap templates\n# This script extracts common sections from the root AGENTS.md and updates bootstrap templates\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nCLI_ROOT=\"$(cd \"$SCRIPT_DIR/..\" && pwd)\"\nOPEN_SOURCE_ROOT=\"$(cd \"$CLI_ROOT/../..\" && pwd)\"\n\nROOT_AGENTS=\"$OPEN_SOURCE_ROOT/AGENTS.md\"\nUI_AGENTS_TEMPLATE=\"$CLI_ROOT/.bootstrap/apps/ui_application/AGENTS.md.template\"\nCLI_AGENTS_TEMPLATE=\"$CLI_ROOT/.bootstrap/apps/cli_application/AGENTS.md.template\"\n\necho \"Syncing AGENTS.md patterns from root to bootstrap templates...\"\necho \"Root AGENTS.md: $ROOT_AGENTS\"\necho \"UI Template: $UI_AGENTS_TEMPLATE\"\necho \"CLI Template: $CLI_AGENTS_TEMPLATE\"\n\n# Extract the Anti-Hallucination section from root AGENTS.md\n# This ensures patterns stay consistent\nANTI_HALLUCINATION_START=\"## 🚨 AI Anti-Hallucination: This is NOT React!\"\nANTI_HALLUCINATION_END=\"## Directory Structure\"\n\n# For now, just validate that the files exist\nif [ ! -f \"$ROOT_AGENTS\" ]; then\n    echo \"Error: Root AGENTS.md not found at $ROOT_AGENTS\"\n    exit 1\nfi\n\nif [ ! -f \"$UI_AGENTS_TEMPLATE\" ]; then\n    echo \"Error: UI AGENTS.md template not found at $UI_AGENTS_TEMPLATE\"\n    exit 1\nfi\n\nif [ ! -f \"$CLI_AGENTS_TEMPLATE\" ]; then\n    echo \"Error: CLI AGENTS.md template not found at $CLI_AGENTS_TEMPLATE\"\n    exit 1\nfi\n\necho \"✅ All AGENTS.md files found\"\necho \"\"\necho \"Note: This script currently validates file existence.\"\necho \"To fully implement sync, run: npm run update-agents-templates\"\n"
  },
  {
    "path": "npm_modules/cli/scripts/update-agents-templates.ts",
    "content": "#!/usr/bin/env ts-node\n/**\n * Updates AGENTS.md templates in bootstrap directory with correct Valdi patterns\n * Ensures consistency with root AGENTS.md anti-hallucination guidelines\n */\n\nimport fs from 'fs';\nimport path from 'path';\n\nconst CLI_ROOT = path.join(__dirname, '..');\nconst OPEN_SOURCE_ROOT = path.join(CLI_ROOT, '../..');\n\n// Common Valdi patterns section that should be consistent across all AGENTS.md files\nconst VALDI_PATTERNS_SECTION = `\n## 🚨 CRITICAL: Valdi is NOT React!\n\n**AI assistants often suggest React patterns that DON'T EXIST in Valdi.** This is because TSX/JSX syntax looks like React, but Valdi compiles to native code.\n\n### ❌ FORBIDDEN Patterns (Don't exist in Valdi)\n\n\\`\\`\\`typescript\n// ❌ WRONG - React hooks don't exist\nconst [count, setCount] = useState(0);\nuseEffect(() => { ... }, []);\n\n// ❌ WRONG - Functional components don't exist\nconst MyComponent = () => <view />;\n\n// ❌ WRONG - Common AI mistakes\nthis.markNeedsRender();  // Doesn't exist!\nthis.props.title;        // Should be: this.viewModel.title\nonMount() { }            // Should be: onCreate()\nonUpdate() { }           // Should be: onViewModelUpdate()\nonUnmount() { }          // Should be: onDestroy()\nthis.context.get(Service);  // Wrong pattern, use withProviders()\n\\`\\`\\`\n\n### ✅ CORRECT Valdi Patterns\n\n\\`\\`\\`typescript\n// ✅ Stateful component with state\nimport { StatefulComponent } from 'valdi_core/src/Component';\n\nclass MyComponent extends StatefulComponent<ViewModel, State> {\n  state = { count: 0 };\n  \n  // Lifecycle methods\n  onCreate() { }                           // Component created\n  onViewModelUpdate(prev: ViewModel) { }  // Props changed\n  onDestroy() { }                          // Before removal\n  \n  // State updates\n  handleClick() {\n    this.setState({ count: this.state.count + 1 }); // Auto re-renders\n  }\n  \n  // Render (returns void, JSX is statement)\n  onRender() {\n    <button \n      title={\\`Count: \\${this.state.count}\\`}\n      onPress={this.handleClick}\n    />;\n  }\n}\n\n// ✅ Stateless component (props only)\nimport { Component } from 'valdi_core/src/Component';\n\nclass SimpleComponent extends Component<ViewModel> {\n  onRender() {\n    <label value={this.viewModel.title} />;  // viewModel, not props!\n  }\n}\n\\`\\`\\`\n\n### Key Differences from React\n\n| Concept | React | Valdi |\n|---------|-------|-------|\n| **Components** | Functions or classes | Classes only (Component or StatefulComponent) |\n| **State** | \\`useState\\` hook | \\`state = { }\\` + \\`setState()\\` |\n| **Props** | \\`this.props\\` | \\`this.viewModel\\` |\n| **Lifecycle** | \\`useEffect\\` | \\`onCreate\\`, \\`onViewModelUpdate\\`, \\`onDestroy\\` |\n| **Re-render** | \\`setCount(...)\\` | \\`this.setState(...)\\` |\n| **Return** | \\`return <view />\\` | \\`<view />;\\` (statement, returns void) |\n\nFor complete framework documentation, see: https://github.com/Snapchat/Valdi\n`;\n\nfunction updateAgentsTemplate(templatePath: string, _isCliApp: boolean) {\n  console.log(`\\nUpdating: ${path.relative(CLI_ROOT, templatePath)}`);\n  \n  let content = fs.readFileSync(templatePath, 'utf-8');\n  \n  // Fix incorrect lifecycle method comments\n  content = content.replace(\n    /\\/\\/ onMount\\(\\) - Called when component is first mounted/g,\n    '// onCreate() - Called when component is first created'\n  );\n  content = content.replace(\n    /\\/\\/ onUnmount\\(\\) - Called before component is removed/g,\n    '// onDestroy() - Called before component is removed'\n  );\n  content = content.replace(\n    /\\/\\/ onUpdate\\(prevProps\\) - Called when component updates/g,\n    '// onViewModelUpdate(previousViewModel) - Called when viewModel updates'\n  );\n  \n  // Find where to insert the patterns section (after Overview, before Project Structure or Development Workflow)\n  const insertAfter = '## Overview';\n  const insertIndex = content.indexOf(insertAfter);\n  \n  if (insertIndex === -1) {\n    console.warn('  ⚠️  Could not find Overview section, skipping pattern insertion');\n  } else {\n    // Find the end of the Overview section (next ## heading)\n    const nextHeadingMatch = content.substring(insertIndex + insertAfter.length).match(/\\n## /);\n    if (nextHeadingMatch) {\n      const insertPosition = insertIndex + insertAfter.length + nextHeadingMatch.index!;\n      \n      // Check if patterns section already exists\n      if (!content.includes('🚨 CRITICAL: Valdi is NOT React!')) {\n        content = \n          content.substring(0, insertPosition) + \n          '\\n' + \n          VALDI_PATTERNS_SECTION + \n          '\\n' + \n          content.substring(insertPosition);\n        console.log('  ✅ Added Valdi patterns section');\n      } else {\n        console.log('  ℹ️  Patterns section already exists, preserving custom content');\n      }\n    }\n  }\n  \n  // Update Provider pattern example if it exists\n  if (content.includes('import { Provider }')) {\n    console.log('  ⚠️  Found old Provider pattern, consider updating to withProviders() HOC');\n  }\n  \n  fs.writeFileSync(templatePath, content, 'utf-8');\n  console.log('  ✅ Template updated');\n}\n\nfunction main() {\n  console.log('Updating AGENTS.md bootstrap templates with correct Valdi patterns...\\n');\n  \n  const uiTemplate = path.join(CLI_ROOT, '.bootstrap/apps/ui_application/AGENTS.md.template');\n  const cliTemplate = path.join(CLI_ROOT, '.bootstrap/apps/cli_application/AGENTS.md.template');\n  \n  if (fs.existsSync(uiTemplate)) {\n    updateAgentsTemplate(uiTemplate, false);\n  } else {\n    console.warn(`UI template not found: ${uiTemplate}`);\n  }\n  \n  if (fs.existsSync(cliTemplate)) {\n    updateAgentsTemplate(cliTemplate, true);\n  } else {\n    console.warn(`CLI template not found: ${cliTemplate}`);\n  }\n  \n  console.log('\\n✅ All templates updated!');\n  console.log('\\nNext steps:');\n  console.log('  1. Review the changes in the templates');\n  console.log('  2. Test with: valdi bootstrap (in a test directory)');\n  console.log('  3. Commit the updated templates');\n}\n\nmain();\n"
  },
  {
    "path": "npm_modules/cli/spec/support/jasmine.json",
    "content": "{\n    \"spec_dir\": \".\",\n    \"spec_files\": [\n      \"**/*.spec.ts\"\n    ]\n}"
  },
  {
    "path": "npm_modules/cli/src/commands/bootstrap.ts",
    "content": "import path from 'path';\nimport inquirer from 'inquirer';\nimport type { Argv } from 'yargs';\nimport { ANSI_COLORS, BOOTSTRAP_DIR_PATH, META_DIR_PATH, TEMPLATE_BASE_PATHS, VALDI_CONFIG_PATHS } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport type { CliChoice } from '../utils/cliUtils';\nimport { getUserChoice, getUserConfirmation } from '../utils/cliUtils';\nimport { copyBootstrapFiles } from '../utils/copyBootstrapFiles';\nimport { makeCommandHandler } from '../utils/errorUtils';\nimport type { Replacements } from '../utils/fileUtils';\nimport {\n  TemplateFile,\n  deleteAll,\n  fileExists,\n  isDirectoryEmpty,\n  processReplacements,\n  resolveFilePath,\n} from '../utils/fileUtils';\nimport { wrapInColor } from '../utils/logUtils';\nimport { toPascalCase, sanitizeProjectName, validateProjectName } from '../utils/stringUtils';\nimport { getAllProjectSyncTargets, runProjectSync } from './projectsync';\nimport { getLatestReleaseTag } from '../utils/githubUtils';\n\ninterface CommandParameters {\n  confirmBootstrap: boolean;\n  projectName: string;\n  applicationType: string;\n  valdiImport: string;\n  valdiWidgetsImport: string;\n  valdiVersion: string;\n  valdiWidgetsVersion: string;\n  skipProjectsync: boolean;\n  withCleanup: boolean;\n}\n\ninterface ApplicationTemplate {\n  name: string;\n  path: string;\n  description: string;\n}\n\nconst ALL_APPLICATION_TEMPLATES: readonly ApplicationTemplate[] = [\n  {\n    name: 'UI Application',\n    path: 'ui_application',\n    description: `An application rendering UI in a window on iOS, Android and macOS.`,\n  },\n  {\n    name: 'CLI Application',\n    path: 'cli_application',\n    description: `A command line application that runs in a terminal`,\n  },\n];\n\nconst VALDI_GIT_URL = 'https://github.com/Snapchat/Valdi';\nconst VALDI_WIDGETS_GIT_URL = 'https://github.com/Snapchat/Valdi_Widgets';\n\n/** Pinned Valdi release used by default for reproducible bootstraps. Bump when cutting a new Valdi release. */\nconst DEFAULT_VALDI_RELEASE_TAG = 'beta-0.0.3';\n/** Pinned Valdi_Widgets release used by default. Should match the Valdi release cycle. */\nconst DEFAULT_VALDI_WIDGETS_RELEASE_TAG = 'beta-0.0.3';\n\nconst DEFAULT_VALDI_IMPORT = `\nhttp_archive(\n    name = \"valdi\",\n    strip_prefix = \"Valdi-{{VALDI_RELEASE_TAG}}\",\n    url = \"${VALDI_GIT_URL}/archive/{{VALDI_RELEASE_REF}}.tar.gz\",\n)`;\n\nconst DEFAULT_VALDI_WIDGETS_IMPORT = `\nhttp_archive(\n    name = \"valdi_widgets\",\n    strip_prefix = \"Valdi_Widgets-{{VALDI_WIDGETS_RELEASE_TAG}}\",\n    url = \"${VALDI_WIDGETS_GIT_URL}/archive/{{VALDI_WIDGETS_RELEASE_REF}}.tar.gz\",\n)`;\n\nconst LOCAL_VALDI_IMPORT_TEMPLATE = `\nlocal_repository(\n    name = \"valdi\",\n    path = \"{{PATH}}\",\n)\n`;\n\nconst LOCAL_VALDI_WIDGETS_IMPORT_TEMPLATE = `\nlocal_repository(\n    name = \"valdi_widgets\",\n    path = \"{{PATH}}\",\n)\n`;\n\nfunction isAlreadyInitialized(): boolean {\n  return fileExists(path.join(process.cwd(), 'WORKSPACE'));\n}\n\nasync function getShouldBootstrap(argv: ArgumentsResolver<CommandParameters>): Promise<boolean> {\n  // Get confirmation on directory path\n  return argv.getArgumentOrResolve('confirmBootstrap', () => {\n    return getUserConfirmation('Do you want to create a new project in the current directory?', true);\n  });\n}\n\nconst defaultProjectName = path.basename(process.cwd());\n\nasync function getApplicationType(argv: ArgumentsResolver<CommandParameters>): Promise<ApplicationTemplate> {\n  const applicationType = argv.getArgument('applicationType');\n\n  if (applicationType) {\n    const target = ALL_APPLICATION_TEMPLATES.find(target => target.path === applicationType);\n\n    if (target) {\n      return target;\n    } else {\n      throw new CliError(`Unknown application type: ${applicationType}`);\n    }\n  }\n\n  const choices: CliChoice<ApplicationTemplate>[] = ALL_APPLICATION_TEMPLATES.map(target => ({\n    name: `${wrapInColor(target.name, ANSI_COLORS.GREEN_COLOR)} . ${target.description}`,\n    value: target,\n  }));\n\n  return await getUserChoice(choices, `Please choose the application type:`);\n}\n\nasync function getProjectName(argv: ArgumentsResolver<CommandParameters>): Promise<string> {\n  return argv.getArgumentOrResolve('projectName', async () => {\n    let projectName = '';\n    let isValid = false;\n\n    while (!isValid) {\n      const result = await inquirer.prompt<{ projectName: string }>([\n        {\n          type: 'input',\n          name: 'projectName',\n          message: 'Please provide a name for this project:',\n          default: defaultProjectName,\n        },\n      ]);\n\n      projectName = result.projectName;\n      const validationError = validateProjectName(projectName);\n\n      if (validationError) {\n        console.log(wrapInColor(`\\n❌ ${validationError}\\n`, ANSI_COLORS.RED_COLOR));\n        continue;\n      }\n\n      const sanitized = sanitizeProjectName(projectName);\n      if (sanitized !== projectName) {\n        console.log(\n          wrapInColor(\n            `\\n⚠️  Project name will be sanitized from \"${projectName}\" to \"${sanitized}\"`,\n            ANSI_COLORS.YELLOW_COLOR,\n          ),\n        );\n        const confirm = await getUserConfirmation('Do you want to continue with this name?', true);\n        if (!confirm) {\n          continue;\n        }\n      }\n\n      isValid = true;\n    }\n\n    return sanitizeProjectName(projectName);\n  });\n}\n\nfunction resolveValdiReleaseTag(\n  argv: ArgumentsResolver<CommandParameters>,\n  gitUrl: string,\n  defaultTag: string,\n  versionOption: 'valdiVersion' | 'valdiWidgetsVersion' = 'valdiVersion',\n): Promise<string> {\n  const override = argv.getArgument(versionOption);\n  if (!override) {\n    return Promise.resolve(defaultTag);\n  }\n  if (override === 'latest') {\n    return getLatestReleaseTag(gitUrl);\n  }\n  return Promise.resolve(override);\n}\n\nfunction getValdiImport(argv: ArgumentsResolver<CommandParameters>, valdiReleaseRef: string): string {\n  const valdiImport = argv.getArgument('valdiImport');\n  if (valdiImport) {\n    return processReplacements(LOCAL_VALDI_IMPORT_TEMPLATE, { PATH: valdiImport });\n  } else {\n    const valdiReleaseTag = valdiReleaseRef.split('/').pop()!;\n    return processReplacements(DEFAULT_VALDI_IMPORT, {\n      VALDI_RELEASE_REF: valdiReleaseRef,\n      VALDI_RELEASE_TAG: valdiReleaseTag,\n    });\n  }\n}\n\nfunction getValdiWidgetsImport(argv: ArgumentsResolver<CommandParameters>, valdiWidgetsReleaseRef: string): string {\n  const valdiWidgetsImport = argv.getArgument('valdiWidgetsImport');\n  if (valdiWidgetsImport) {\n    return processReplacements(LOCAL_VALDI_WIDGETS_IMPORT_TEMPLATE, { PATH: valdiWidgetsImport });\n  } else {\n    const valdiWidgetsReleaseTag = valdiWidgetsReleaseRef.split('/').pop()!;\n    return processReplacements(DEFAULT_VALDI_WIDGETS_IMPORT, {\n      VALDI_WIDGETS_RELEASE_REF: valdiWidgetsReleaseRef,\n      VALDI_WIDGETS_RELEASE_TAG: valdiWidgetsReleaseTag,\n    });\n  }\n}\n\n// Create files from templates\nfunction initializeConfigFiles(\n  projectName: string,\n  template: ApplicationTemplate,\n  valdiImport: string,\n  valdiWidgetsImport: string,\n) {\n\n  const TEMPLATE_FILES = [\n    TemplateFile.init(TEMPLATE_BASE_PATHS.USER_CONFIG).withOutputPath(resolveFilePath(VALDI_CONFIG_PATHS[0] ?? '')),\n    TemplateFile.init(TEMPLATE_BASE_PATHS.BAZEL_VERSION),\n    TemplateFile.init(TEMPLATE_BASE_PATHS.WORKSPACE).withReplacements({\n      WORKSPACE_NAME: projectName,\n      VALDI_IMPORT: valdiImport,\n      VALDI_WIDGETS_IMPORT: valdiWidgetsImport,\n    }),\n    TemplateFile.init(TEMPLATE_BASE_PATHS.BAZEL_RC),\n    TemplateFile.init(TEMPLATE_BASE_PATHS.README),\n    TemplateFile.init(TEMPLATE_BASE_PATHS.GIT_IGNORE),\n    TemplateFile.init(TEMPLATE_BASE_PATHS.WATCHMAN_CONFIG),\n    TemplateFile.init(TEMPLATE_BASE_PATHS.EDITOR_CONFIG),\n    TemplateFile.init(TEMPLATE_BASE_PATHS.AGENTS).withReplacements({ MODULE_NAME: projectName }),\n  ];\n\n  TEMPLATE_FILES.forEach(templateFile => {\n    console.log(\n      wrapInColor(`Creating ${templateFile.baseName} in ${templateFile.outputPath}...`, ANSI_COLORS.YELLOW_COLOR),\n    );\n    templateFile.expandTemplate();\n  });\n\n  // Copy GitHub templates directory (if it exists)\n  const replacements: Replacements = {\n    MODULE_NAME: projectName,\n    MODULE_NAME_PASCAL_CASED: toPascalCase(projectName),\n  };\n  const githubSourcePath = path.join(BOOTSTRAP_DIR_PATH, '.github');\n  if (fileExists(githubSourcePath)) {\n    console.log(wrapInColor('Creating GitHub templates...', ANSI_COLORS.YELLOW_COLOR));\n    const githubDestPath = path.join(process.cwd(), '.github');\n    copyBootstrapFiles(githubSourcePath, githubDestPath, replacements);\n  }\n\n  // Setup hello world application\n  console.log(wrapInColor(`Initializing ${template.name} application...`, ANSI_COLORS.YELLOW_COLOR));\n  const sourcePath = path.join(BOOTSTRAP_DIR_PATH, 'apps', template.path);\n  const destPath = process.cwd();\n\n  copyBootstrapFiles(sourcePath, destPath, replacements);\n}\n\nasync function valdiBootstrap(argv: ArgumentsResolver<CommandParameters>) {\n  // Set up a Valdi project in the current directory. Will go through a flow to ask some questions to the user like the name of the application. This will create the following files:\n  // user_config.yaml: User configuration file\n  // application_names.bzl: Bazel macro file with application names\n  const curDir = process.cwd();\n\n  console.log(`\\nCurrent directory: ${wrapInColor(curDir, ANSI_COLORS.GREEN_COLOR)}`);\n\n  if (isAlreadyInitialized()) {\n    // Check for existing project files\n    // If the directory already contains a project, prompt the user to re-run command with explicit --with-cleanup flag\n    if (argv.getArgument('withCleanup')) {\n      console.log(wrapInColor('Deleting all files in current directory...', ANSI_COLORS.YELLOW_COLOR));\n      deleteAll(curDir);\n    } else {\n      throw new CliError(\n        `Detected existing project files. Please remove them before re-running 'valdi bootstrap'.\\nYou can run '${wrapInColor('valdi bootstrap --with-cleanup', ANSI_COLORS.YELLOW_COLOR, ANSI_COLORS.RED_COLOR)}' to remove ALL FILES in the current directory.`,\n      );\n    }\n  } else if (!isDirectoryEmpty(curDir)) {\n    // Folder contains non project files\n    // Prompt for manual clean up to prevent accidental deletion of important files\n    throw new CliError(\n      \"Current directory is not empty. Please run 'valdi bootstrap' in an empty directory or manually clean up existing files.\",\n    );\n  }\n\n  if (!(await getShouldBootstrap(argv))) {\n    throw new CliError('Bootstrap process aborted.');\n  }\n\n  const applicationType = await getApplicationType(argv);\n\n  // Prompt user for input\n  // - Application Name\n  let projectName = await getProjectName(argv);\n  \n  // Validate project name if provided via command line argument\n  if (argv.getArgument('projectName')) {\n    const validationError = validateProjectName(projectName);\n    if (validationError) {\n      throw new CliError(validationError);\n    }\n    projectName = sanitizeProjectName(projectName);\n  }\n  \n  if (!projectName) {\n    throw new CliError('Project name cannot be empty.');\n  }\n\n  const valdiReleaseTag = await resolveValdiReleaseTag(argv, VALDI_GIT_URL, DEFAULT_VALDI_RELEASE_TAG);\n  const valdiWidgetsReleaseTag = await resolveValdiReleaseTag(\n    argv,\n    VALDI_WIDGETS_GIT_URL,\n    DEFAULT_VALDI_WIDGETS_RELEASE_TAG,\n    'valdiWidgetsVersion',\n  );\n\n  const valdiImport = getValdiImport(argv, valdiReleaseTag);\n  const valdiWidgetsImport = getValdiWidgetsImport(argv, valdiWidgetsReleaseTag);\n\n  // Creating basic config files and Hello World application\n  console.log(wrapInColor('Initializing config files...', ANSI_COLORS.BLUE_COLOR));\n  initializeConfigFiles(projectName, applicationType, valdiImport, valdiWidgetsImport);\n\n  // Check bazel version matches .bazelversion\n  console.log(wrapInColor('Verifying Bazel installation...', ANSI_COLORS.BLUE_COLOR));\n  const bazel = new BazelClient();\n  const [returnCode, versionInfo, errors] = await bazel.getVersion();\n\n  if (returnCode !== 0) {\n    throw new CliError(`Bazel installation failed to verify with errors: ${errors.toString()}`);\n  }\n\n  console.log(versionInfo);\n\n  if (argv.getArgument('skipProjectsync')) {\n    console.log(wrapInColor('Skipping projectsync', ANSI_COLORS.YELLOW_COLOR));\n  } else {\n    console.log(wrapInColor('Running projectsync...', ANSI_COLORS.BLUE_COLOR));\n    // eslint-disable-next-line unicorn/no-useless-undefined\n    await runProjectSync(bazel, await getAllProjectSyncTargets(bazel), undefined, true);\n  }\n\n  // Finalize message\n  console.log(wrapInColor('Bootstrap complete!', ANSI_COLORS.GREEN_COLOR));\n}\n\nexport const command = 'bootstrap';\nexport const describe = 'Prepares and initializes a project to build and run in Valdi';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs\n    .option('confirmBootstrap', {\n      describe: 'Skip confirmation prompt and start bootstrap process',\n      type: 'boolean',\n      alias: 'y',\n    })\n    .option('applicationType', {\n      describe: 'Type of application to create',\n      alias: 't',\n    })\n    .option('projectName', {\n      describe: 'Name of the project',\n      type: 'string',\n      alias: 'n',\n    })\n    .option('valdiImport', {\n      describe:\n        'Path to a local checkout of the Valdi repo. If not specified, uses the pinned release (see valdiVersion).',\n      type: 'string',\n      alias: 'l',\n    })\n    .option('valdiWidgetsImport', {\n      describe:\n        'Path to a local checkout of the Valdi_Widgets repo. If not specified, uses the pinned release (see valdiWidgetsVersion).',\n      type: 'string',\n      alias: 'w',\n    })\n    .option('valdiVersion', {\n      describe: `Valdi release tag to use (e.g. v1.0.0). Use \"latest\" to fetch the GitHub latest release. Default: ${DEFAULT_VALDI_RELEASE_TAG}`,\n      type: 'string',\n    })\n    .option('valdiWidgetsVersion', {\n      describe: `Valdi_Widgets release tag to use. Use \"latest\" to fetch the GitHub latest release. Default: ${DEFAULT_VALDI_WIDGETS_RELEASE_TAG}`,\n      type: 'string',\n    })\n    .option('skipProjectsync', {\n      describe: 'Skip projectsync for testing purposes',\n      type: 'boolean',\n      alias: 'p',\n    })\n    .option('withCleanup', {\n      describe: 'Deletes all existing files in the current directory before initiating bootstrap',\n      type: 'boolean',\n      alias: 'c',\n    });\n};\nexport const handler = makeCommandHandler(valdiBootstrap);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/build.ts",
    "content": "import { type Argv } from 'yargs';\nimport { ANSI_COLORS, PLATFORM } from '../core/constants';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport {\n  applicationExtensionForPlatform,\n  getOutputFilePath,\n  makeArgsBuilder,\n} from '../utils/applicationUtils';\nimport type { CommandParameters} from '../utils/buildInfo';\nimport { getBuildInfo } from '../utils/buildInfo';\nimport { installAndroidApk } from '../utils/deviceUtils';\nimport { logReproduceThisCommandIfNeeded, makeCommandHandler } from '../utils/errorUtils';\nimport { wrapInColor } from '../utils/logUtils';\n\n\nasync function valdiBuild(argv: ArgumentsResolver<CommandParameters>) {\n  const bazel = new BazelClient();\n\n  const buildInfo = await getBuildInfo(argv, bazel, false);  \n\n  // Output Selection\n  // ----------------\n\n  // Perform build and install\n  // -------------------------\n  console.log(`Building: ${wrapInColor(buildInfo.application, ANSI_COLORS.GREEN_COLOR)}`);\n\n  switch (buildInfo.platform) {\n    case PLATFORM.ANDROID: {\n      const outputFilePath = await argv.getArgumentOrResolve('target_output_path', () => {\n        console.log('Resolving output paths...');\n        return getOutputFilePath(bazel, applicationExtensionForPlatform(buildInfo.platform), buildInfo.application, buildInfo.bazelArgs);\n      });\n      await bazel.buildTarget(buildInfo.application, buildInfo.bazelArgs);\n      break;\n    }\n    case PLATFORM.IOS: {\n      console.log('Building iOS application...');\n      await bazel.buildTarget(buildInfo.application, buildInfo.bazelArgs);\n      logReproduceThisCommandIfNeeded(argv);\n      break;\n    }\n    case PLATFORM.MACOS: {\n      logReproduceThisCommandIfNeeded(argv);\n      console.log('Building MacOS application...');\n      await bazel.buildTarget(buildInfo.application, buildInfo.bazelArgs);\n      break;\n    }\n    case PLATFORM.CLI: {\n      logReproduceThisCommandIfNeeded(argv);\n      console.log('Build CLI application...');\n      await bazel.buildTarget(buildInfo.application, buildInfo.bazelArgs);\n      break;\n    }\n  }\n}\n\nexport const command = 'build <platform>';\nexport const describe = 'Build the application';\nexport const builder = makeArgsBuilder((yargs: Argv<CommandParameters>) => {\n  yargs\n    .option('application', {\n      describe: 'Name of the application to install',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('device_id', {\n      describe: 'Device ID that will receive the application',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('target_output_path', {\n      describe: 'The output path for the Bazel target',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('simulator', {\n      describe: 'Whether to build for simulator or for device',\n      type: 'boolean',\n    });\n});\nexport const handler = makeCommandHandler(valdiBuild);\n\n// TODOs:\n// - Cached bazel query results\n\n// Extract 'custom_package' from android_binary\n// Extract 'bundle_id' from ios_application target\n"
  },
  {
    "path": "npm_modules/cli/src/commands/devSetup.ts",
    "content": "import { ANSI_COLORS } from '../core/constants';\nimport { beginEnvironmentSetup } from '../setup/setupEntryPoint';\nimport { makeCommandHandler } from '../utils/errorUtils';\nimport { wrapInColor } from '../utils/logUtils';\n\nasync function valdiSetup() {\n  const returnCode = await beginEnvironmentSetup();\n\n  if (returnCode !== 0) {\n    console.log(wrapInColor('Environment setup did not complete successfully.', ANSI_COLORS.YELLOW_COLOR));\n  }\n}\n\nexport const command = 'dev_setup';\nexport const describe = 'Sets up the development environment for Valdi';\nexport const builder = () => {};\nexport const handler = makeCommandHandler(valdiSetup);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/doctor.ts",
    "content": "/**\n * @fileoverview Valdi CLI Doctor Command - Environment Health Diagnostics\n *\n * This module implements the `valdi doctor` command, which performs comprehensive\n * health checks on the Valdi development environment. It validates system requirements,\n * tool installations, workspace configuration, and provides actionable feedback\n * for resolving issues.\n *\n * @author rohanjsh\n *\n * @example\n * ```bash\n * # Basic health check (dev environment only)\n * valdi doctor\n *\n * # Include project-specific checks\n * valdi doctor --project\n *\n * # Include framework development checks\n * valdi doctor --framework\n *\n * # Detailed diagnostics with verbose output\n * valdi doctor --verbose\n *\n * # Machine-readable JSON output for CI/CD\n * valdi doctor --json\n *\n * # Attempt automatic fixes where possible\n * valdi doctor --fix\n * ```\n\n * @see {@link https://bazel.build/install} Bazel Installation Guide\n * @see {@link https://nodejs.org} Node.js Installation\n */\n\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport path from 'path';\nimport type { Argv } from 'yargs';\nimport { ANSI_COLORS } from '../core/constants';\n\nimport { ANDROID_NDK_VERSION, ANDROID_PLATFORM_VERSION } from '../setup/versions';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport { checkCommandExists, runCliCommand } from '../utils/cliUtils';\nimport { makeCommandHandler } from '../utils/errorUtils';\nimport {\n  type LinuxDistroInfo,\n  buildInstallCommand,\n  detectLinuxDistro,\n  getCommonPackageMappings,\n  getPackageName,\n} from '../utils/linuxDistro';\nimport { wrapInColor } from '../utils/logUtils';\n\n/** Discord support link for troubleshooting */\nconst DISCORD_SUPPORT_URL = 'https://discord.gg/uJyNEeYX2U';\n\n/**\n * Command line parameters for the doctor command.\n *\n * @interface CommandParameters\n */\ninterface CommandParameters {\n  /** Enable detailed diagnostic information output */\n  verbose: boolean;\n  /** Attempt to automatically fix issues where possible */\n  fix: boolean;\n  /** Output results in JSON format for machine processing */\n  json: boolean;\n  /** Include framework development checks (git-lfs, temurin, etc.) */\n  framework: boolean;\n  /** Include project-specific checks (workspace structure, etc.) */\n  project: boolean;\n}\n\n/**\n * Represents the result of a single diagnostic check.\n *\n * @interface DiagnosticResult\n */\ninterface DiagnosticResult {\n  /** Human-readable name of the diagnostic check */\n  name: string;\n  /** Status of the check: pass (✓), warn (⚠), or fail (✗) */\n  status: 'pass' | 'warn' | 'fail';\n  /** Primary message describing the check result */\n  message: string;\n  /** Optional detailed information about the check */\n  details?: string;\n  /** Whether this issue can potentially be auto-fixed */\n  fixable?: boolean;\n  /** Command or instruction to fix the issue */\n  fixCommand?: string;\n  /** Category for grouping related checks */\n  category?: string;\n}\n\n/**\n * Represents a group of related diagnostic checks with their overall status.\n *\n * @interface GroupedDiagnosticResult\n */\ninterface GroupedDiagnosticResult {\n  /** Category name for the group */\n  category: string;\n  /** Overall status of the group (worst status among all checks) */\n  status: 'pass' | 'warn' | 'fail';\n  /** Summary message for the group */\n  message: string;\n  /** Individual check results within this group */\n  checks: DiagnosticResult[];\n  /** Issues found in this group (only checks with warn/fail status) */\n  issues: DiagnosticResult[];\n}\n\n/**\n * Main class responsible for performing Valdi environment health diagnostics.\n *\n * This class orchestrates various system checks to ensure the development environment\n * is properly configured for Valdi development. It validates:\n * - Node.js version compatibility (≥18.0.0)\n * - Bazel build system installation and functionality (with version validation)\n * - Java JDK installation (Java 17+ required)\n * - Platform-specific development tools (Android SDK, Xcode)\n * - Required development dependencies (git, npm, watchman, ios-webkit-debug-proxy)\n * - Optional project-specific checks (workspace structure)\n * - Optional framework development tools (git-lfs, temurin)\n *\n * @class ValdiDoctor\n */\nclass ValdiDoctor {\n  /** Collection of diagnostic check results */\n  private readonly results: DiagnosticResult[] = [];\n\n  /** Whether to show detailed diagnostic information */\n  private readonly verbose: boolean;\n\n  /** Whether to attempt automatic fixes for detected issues */\n  private readonly autoFix: boolean;\n\n  /** Whether to output results in JSON format */\n  private readonly jsonOutput: boolean;\n\n  /** Whether to include framework development checks */\n  private readonly frameworkMode: boolean;\n\n  /** Whether to include project-specific checks */\n  private readonly projectMode: boolean;\n\n  /** Cached Linux distribution info (only on Linux) */\n  private readonly linuxDistro?: LinuxDistroInfo;\n\n  /**\n   * Creates a new ValdiDoctor instance.\n   *\n   * @param verbose - Enable detailed diagnostic output\n   * @param autoFix - Attempt to automatically fix issues where possible\n   * @param jsonOutput - Output results in JSON format for machine processing\n   * @param frameworkMode - Include framework development checks\n   * @param projectMode - Include project-specific checks\n   */\n  constructor(verbose: boolean, autoFix: boolean, jsonOutput: boolean, frameworkMode: boolean, projectMode: boolean) {\n    this.verbose = verbose;\n    this.autoFix = autoFix;\n    this.jsonOutput = jsonOutput;\n    this.frameworkMode = frameworkMode;\n    this.projectMode = projectMode;\n\n    // Detect Linux distribution if on Linux\n    if (os.platform() === 'linux') {\n      this.linuxDistro = detectLinuxDistro();\n    }\n  }\n\n  /**\n   * Executes diagnostic checks based on the target audience.\n   *\n   * **App Development Mode (default):**\n   * - Essential tools for building Valdi applications\n   * - Node.js, Bazel (with version validation)\n   * - Basic Android SDK and Java setup (Java 17+ required)\n   * - Core development tools (git, npm, watchman, ios-webkit-debug-proxy)\n   *\n   * **Project Mode (--project flag):**\n   * - All app development checks plus\n   * - Workspace structure validation (WORKSPACE file, .bazelrc)\n   *\n   * **Framework Development Mode (--framework flag):**\n   * - All app development checks plus\n   * - Advanced development tools (git-lfs, temurin)\n   * - Detailed environment variable validation\n   * - Platform-specific development packages\n   *\n   * @returns Promise that resolves when all diagnostics are complete\n   *\n   * @example\n   * ```typescript\n   * // App development checks only\n   * await doctor.runDiagnostics();\n   *\n   * // App development + project checks\n   * await doctor.runDiagnostics(); // with projectMode = true\n   *\n   * // App development + framework checks\n   * await doctor.runDiagnostics(); // with frameworkMode = true\n   * ```\n   */\n  async runDiagnostics(): Promise<DiagnosticResult['status']> {\n    if (!this.jsonOutput) {\n      let mode = 'app development';\n      if (this.frameworkMode) mode = 'framework development';\n      if (this.projectMode) mode += ' + project';\n      console.log(wrapInColor(`Running Valdi environment diagnostics (${mode} mode)...`, ANSI_COLORS.BLUE_COLOR));\n      console.log();\n    }\n\n    // Core checks for all users\n    await this.checkNodeVersion();\n    await this.checkBazelInstallation();\n\n    // Project-specific checks (only if requested)\n    if (this.projectMode) {\n      this.checkWorkspaceStructure();\n    }\n\n    // Essential platform tools\n    await this.checkEssentialPlatformTools();\n\n    // Java for Android development\n    await this.checkJavaInstallation();\n\n    // Android SDK basics\n    this.checkAndroidSDKBasics();\n\n    // Core development dependencies\n    await this.checkCoreDependencies();\n\n    // Git LFS initialization check\n    await this.checkGitLfsInitialization();\n\n    // Shell autocomplete configuration\n    this.checkShellAutoComplete();\n\n    // VSCode/Cursor extensions check\n    await this.checkEditorExtensions();\n\n    // Framework-specific checks (only if requested)\n    if (this.frameworkMode) {\n      this.checkFrameworkDependencies();\n      this.checkAdvancedAndroidSDK();\n      this.checkEnvironmentVariables();\n    }\n\n    return this.results.some(r => r.status === 'fail') ? 'fail' : 'pass';\n  }\n\n  /**\n   * Outputs the diagnostic results in the appropriate format.\n   *\n   * Depending on the configuration, this method will either:\n   * - Output structured JSON for machine processing (--json flag)\n   * - Display formatted, colored output for human consumption\n   *\n   \n   *\n   * @example\n   * ```typescript\n   * doctor.printResults(); // Human-readable output\n   * ```\n   */\n  printResults(): void {\n    if (this.jsonOutput) {\n      this.printJsonResults();\n    } else {\n      this.printFormattedResults();\n    }\n  }\n\n  /**\n   * Adds a diagnostic result to the internal collection.\n   *\n   * @param result - The diagnostic result to add\n   * @private\n\n   */\n  private addResult(result: DiagnosticResult): void {\n    this.results.push(result);\n  }\n\n  /**\n   * Groups diagnostic results by category for more concise output.\n   *\n   * @returns Array of grouped diagnostic results\n   * @private\n   */\n  private groupResultsByCategory(): GroupedDiagnosticResult[] {\n    const groups = new Map<string, DiagnosticResult[]>();\n\n    // Group results by category, with fallback for uncategorized results\n    for (const result of this.results) {\n      const category = result.category || result.name;\n      if (!groups.has(category)) {\n        groups.set(category, []);\n      }\n      const categoryGroup = groups.get(category);\n      if (categoryGroup) {\n        categoryGroup.push(result);\n      }\n    }\n\n    // Convert to grouped results with overall status\n    const groupedResults: GroupedDiagnosticResult[] = [];\n    for (const [category, checks] of groups.entries()) {\n      // Determine overall status (worst status wins)\n      let overallStatus: 'pass' | 'warn' | 'fail' = 'pass';\n      for (const check of checks) {\n        if (check.status === 'fail') {\n          overallStatus = 'fail';\n          break;\n        } else if (check.status === 'warn' && overallStatus === 'pass') {\n          overallStatus = 'warn';\n        }\n      }\n\n      // Create summary message\n      const warnCount = checks.filter(c => c.status === 'warn').length;\n      const failCount = checks.filter(c => c.status === 'fail').length;\n\n      let message: string;\n      if (overallStatus === 'pass') {\n        const firstCheck = checks[0];\n        message = checks.length === 1 && firstCheck ? firstCheck.message : `All ${checks.length} checks passed`;\n      } else {\n        const issues = failCount + warnCount;\n        message = `${issues} issue${issues > 1 ? 's' : ''} found`;\n      }\n\n      groupedResults.push({\n        category,\n        status: overallStatus,\n        message,\n        checks,\n        issues: checks.filter(c => c.status !== 'pass'),\n      });\n    }\n\n    return groupedResults;\n  }\n\n  /**\n   * Attempts to automatically fix a detected issue.\n   *\n   * This method executes the provided fix command and reports the outcome.\n   * It only runs when auto-fix mode is enabled and provides user feedback\n   * about the success or failure of the fix attempt.\n   *\n   * @param tool - Name of the tool being fixed (for user feedback)\n   * @param command - Shell command to execute for the fix\n   * @returns Promise that resolves when the fix attempt is complete\n   */\n  private async attemptAutoFix(tool: string, command: string): Promise<void> {\n    if (!this.autoFix) {\n      return;\n    }\n\n    try {\n      console.log(wrapInColor(`Attempting to fix ${tool}...`, ANSI_COLORS.YELLOW_COLOR));\n      const { returnCode } = await runCliCommand(command);\n\n      if (returnCode === 0) {\n        console.log(wrapInColor(`✓ Successfully fixed ${tool}`, ANSI_COLORS.GREEN_COLOR));\n      } else {\n        console.log(wrapInColor(`✗ Failed to fix ${tool}`, ANSI_COLORS.RED_COLOR));\n      }\n    } catch (error) {\n      console.log(wrapInColor(`✗ Failed to fix ${tool}: ${error instanceof Error ? error.message : 'Unknown error'}`, ANSI_COLORS.RED_COLOR));\n    }\n  }\n\n  /**\n   * Validates Node.js installation and version compatibility.\n   *\n   * Valdi requires Node.js version 18.0.0 or higher for optimal compatibility.\n   * This method:\n   * 1. Checks if Node.js is installed and accessible via PATH\n   * 2. Validates the version meets minimum requirements (≥18.0.0)\n   * 3. Optionally attempts to upgrade to Node.js 20 if auto-fix is enabled\n   * 4. Provides specific installation/upgrade instructions\n   *\n   * @returns Promise that resolves when the check is complete\n   */\n  private async checkNodeVersion(): Promise<void> {\n    try {\n      const { stdout } = await runCliCommand('node --version');\n      const version = stdout.trim();\n      const versionParts = version.replace('v', '').split('.');\n      const majorVersionStr = versionParts[0];\n\n      if (!majorVersionStr) {\n        throw new Error('Invalid version format');\n      }\n\n      const majorVersion = Number.parseInt(majorVersionStr, 10);\n\n      if (majorVersion >= 18) {\n        this.addResult({\n          name: 'Node.js version',\n          status: 'pass',\n          message: `Node.js ${version} is installed`,\n          category: 'Node.js installation',\n        });\n\n        // Suggest upgrading to Node.js 20 for better performance\n        if (this.autoFix && majorVersion < 20) {\n          await this.attemptAutoFix('node', 'nvm install 20 && nvm use 20');\n        }\n      } else {\n        this.addResult({\n          name: 'Node.js version',\n          status: 'fail',\n          message: `Node.js ${version} is outdated. Valdi requires Node.js 18 or higher`,\n          fixable: true,\n          fixCommand: 'nvm install 18 && nvm use 18',\n          category: 'Node.js installation',\n        });\n\n        if (this.autoFix) {\n          await this.attemptAutoFix('node', 'nvm install 18 && nvm use 18');\n        }\n      }\n    } catch {\n      this.addResult({\n        name: 'Node.js version',\n        status: 'fail',\n        message: 'Node.js is not installed or not in PATH',\n        fixable: true,\n        fixCommand: 'Install Node.js from https://nodejs.org or use nvm',\n        category: 'Node.js installation',\n      });\n    }\n  }\n\n  /**\n   * Validates Bazel build system installation and functionality.\n   *\n   * Bazel is the core build system for Valdi projects. This method:\n   * 1. Attempts to create a BazelClient instance\n   * 2. Executes `bazel version` to verify installation and functionality\n   * 3. Validates version against .bazelversion file if available\n   * 4. Provides installation guidance if Bazel is missing or broken\n   *\n   * @returns Promise that resolves when the check is complete\n   * @see {@link https://bazel.build/install} Bazel Installation Guide\n   */\n  private async checkBazelInstallation(): Promise<void> {\n    try {\n      const bazel = new BazelClient();\n      const [returnCode, versionInfo, errorInfo] = await bazel.getVersion();\n\n      if (returnCode === 0 && versionInfo) {\n        const versionLine = versionInfo.split('\\n')[0] || 'Unknown version';\n\n        // Extract version number for comparison\n        const versionMatch = versionLine.match(/(\\d+\\.\\d+\\.\\d+)/);\n        const installedVersion = versionMatch?.[1];\n\n        // Check against .bazelversion file\n        const bazelVersionFile = path.join(process.cwd(), '.bazelversion');\n        let expectedVersion: string | undefined;\n\n        try {\n          if (fs.existsSync(bazelVersionFile)) {\n            expectedVersion = fs.readFileSync(bazelVersionFile, 'utf8').trim();\n          }\n        } catch {\n          // Ignore file read errors\n        }\n\n        if (expectedVersion && installedVersion && installedVersion !== expectedVersion) {\n          this.addResult({\n            name: 'Bazel version',\n            status: 'warn',\n            message: `Bazel version mismatch: installed ${installedVersion}, expected ${expectedVersion}`,\n            details: 'Version mismatch may cause build issues. Consider updating Bazel.',\n            fixable: true,\n            fixCommand: `Install Bazel ${expectedVersion} or run a trial bazel command to verify compatibility`,\n            category: 'Bazel installation',\n          });\n        } else {\n          this.addResult({\n            name: 'Bazel installation',\n            status: 'pass',\n            message: `Bazel is installed: ${versionLine}${expectedVersion ? ` (matches expected ${expectedVersion})` : ''}`,\n            category: 'Bazel installation',\n          });\n        }\n      } else {\n        this.addResult({\n          name: 'Bazel installation',\n          status: 'fail',\n          message: 'Bazel is installed but not working correctly',\n          details: errorInfo || versionInfo || 'Unknown error',\n          category: 'Bazel installation',\n        });\n      }\n    } catch {\n      this.addResult({\n        name: 'Bazel installation',\n        status: 'fail',\n        message: 'Bazel is not installed or not in PATH',\n        fixable: true,\n        fixCommand: 'Install Bazel from https://bazel.build/install',\n        category: 'Bazel installation',\n      });\n    }\n  }\n\n  /**\n   * Validates Valdi workspace structure and configuration files.\n   *\n   * **WORKSPACE File Requirement:**\n   * Every Valdi application requires a WORKSPACE file at the project root. This file:\n   * - Defines the Bazel workspace name\n   * - Imports the Valdi framework as an external dependency\n   * - Configures build rules and toolchains for Valdi development\n   * - Is automatically created by `valdi bootstrap` when starting a new project\n   *\n   * **Configuration Files:**\n   * - WORKSPACE file (required for all Valdi apps)\n   * - .bazelrc file (recommended for build optimization and consistency)\n   *\n   * This method checks the current working directory for these essential files\n   * and provides guidance if they're missing.\n   *\n   * @private\n   *\n   * @see {@link https://bazel.build/concepts/build-ref#workspace} Bazel Workspace Documentation\n   *\n   * @example\n   * ```typescript\n   * this.checkWorkspaceStructure();\n   * // Results in diagnostic output like:\n   * // ✓ Valid Valdi workspace detected\n   * // ✗ Not in a Valdi workspace directory\n   * ```\n   */\n  private checkWorkspaceStructure(): void {\n    const workspaceFile = path.join(process.cwd(), 'WORKSPACE');\n    const bazelrcFile = path.join(process.cwd(), '.bazelrc');\n\n    if (fs.existsSync(workspaceFile)) {\n      this.addResult({\n        name: 'Valdi workspace',\n        status: 'pass',\n        message: 'Valid Valdi workspace detected',\n        category: 'Workspace configuration',\n      });\n    } else {\n      this.addResult({\n        name: 'Valdi workspace',\n        status: 'fail',\n        message: 'Not in a Valdi workspace directory',\n        details: 'WORKSPACE file is required for all Valdi applications. Run `valdi bootstrap` to create a new project or navigate to an existing Valdi project root.',\n        fixable: true,\n        fixCommand: 'valdi bootstrap',\n        category: 'Workspace configuration',\n      });\n    }\n\n    if (fs.existsSync(bazelrcFile)) {\n      this.addResult({\n        name: 'Bazel configuration',\n        status: 'pass',\n        message: '.bazelrc file found',\n        category: 'Workspace configuration',\n      });\n    } else {\n      this.addResult({\n        name: 'Bazel configuration',\n        status: 'warn',\n        message: '.bazelrc file not found',\n        details: 'A .bazelrc file provides build optimization and consistency. Consider creating one or use `valdi bootstrap` for new projects.',\n        fixable: true,\n        fixCommand: 'Create .bazelrc file with Valdi-specific build configurations',\n        category: 'Workspace configuration',\n      });\n    }\n  }\n\n  /**\n   * Validates essential platform tools needed for app development.\n   *\n   * Focuses on core tools that app developers need:\n   * - Android SDK (basic check)\n   * - Xcode (macOS only, for iOS apps)\n   *\n   * @returns Promise that resolves when essential platform checks are complete\n   * @private\n   */\n  private async checkEssentialPlatformTools(): Promise<void> {\n    // Check Android SDK (essential for mobile app development)\n    const androidHome = process.env['ANDROID_HOME'] || process.env['ANDROID_SDK_ROOT'];\n    if (androidHome && fs.existsSync(androidHome)) {\n      this.addResult({\n        name: 'Android SDK',\n        status: 'pass',\n        message: `Android SDK found at ${androidHome}`,\n        category: 'Android installation',\n      });\n    } else {\n      this.addResult({\n        name: 'Android SDK',\n        status: 'warn',\n        message: 'Android SDK not found',\n        details: 'Required for Android app development. Set ANDROID_HOME environment variable.',\n        fixable: true,\n        fixCommand: 'Install Android Studio and set ANDROID_HOME',\n        category: 'Android installation',\n      });\n    }\n\n    // Check Xcode (macOS only, essential for iOS app development)\n    if (os.platform() === 'darwin') {\n      await this.checkXcodeInstallation();\n    }\n  }\n\n  /**\n   * Validates comprehensive Xcode installation and configuration.\n   *\n   * Performs thorough checks matching dev_setup requirements:\n   * - xcode-select command exists\n   * - xcode-select path is configured and valid\n   * - /Applications/Xcode.app exists\n   *\n   * @returns Promise that resolves when Xcode checks are complete\n   * @private\n   */\n  private async checkXcodeInstallation(): Promise<void> {\n    // Check if xcode-select command exists\n    if (!checkCommandExists('xcode-select')) {\n      this.addResult({\n        name: 'Xcode',\n        status: 'fail',\n        message: 'Xcode command line tools not installed',\n        details: 'Required for iOS app development',\n        fixable: true,\n        fixCommand: 'Install Xcode from App Store (https://apps.apple.com/us/app/xcode/id497799835)',\n        category: 'iOS development',\n      });\n      return;\n    }\n\n    // Check if Xcode is properly configured\n    try {\n      const { stdout } = await runCliCommand('xcode-select -p');\n      const xcodePath = stdout.trim();\n\n      if (!xcodePath || !fs.existsSync(xcodePath)) {\n        this.addResult({\n          name: 'Xcode configuration',\n          status: 'fail',\n          message: 'Xcode command line tools path is not configured correctly',\n          fixable: true,\n          fixCommand: 'Run: sudo xcode-select -s /Applications/Xcode.app (or your Xcode path)',\n          category: 'iOS development',\n        });\n        return;\n      }\n\n      // Extract Xcode.app path from the Developer path\n      // xcode-select -p typically returns: /Applications/Xcode.app/Contents/Developer\n      const xcodeAppPath = xcodePath.replace(/\\/Contents\\/Developer\\/?$/, '');\n      \n      if (fs.existsSync(xcodeAppPath) && xcodeAppPath.includes('Xcode')) {\n        // Xcode is installed and configured\n        this.addResult({\n          name: 'Xcode',\n          status: 'pass',\n          message: `Xcode found at ${xcodeAppPath}`,\n          category: 'iOS development',\n        });\n      } else {\n        // Path doesn't point to an Xcode installation\n        this.addResult({\n          name: 'Xcode',\n          status: 'fail',\n          message: 'Xcode installation not found',\n          details: `xcode-select points to ${xcodePath}, but Xcode app not found at ${xcodeAppPath}`,\n          fixable: true,\n          fixCommand: 'Install Xcode from App Store (https://apps.apple.com/us/app/xcode/id497799835)',\n          category: 'iOS development',\n        });\n      }\n    } catch {\n      this.addResult({\n        name: 'Xcode',\n        status: 'fail',\n        message: 'Xcode not properly configured',\n        fixable: true,\n        fixCommand: 'Run: sudo xcode-select -s /Applications/Xcode.app (or your Xcode path)',\n        category: 'iOS development',\n      });\n    }\n  }\n\n  /**\n   * Validates Java JDK installation and configuration as set up by dev_setup.\n   *\n   * Checks for Java installation and configuration that dev_setup manages:\n   * - Java JDK availability and version (Java 17+)\n   * - JAVA_HOME environment variable\n   * - Java symlink configuration (macOS)\n   * - Java runtime availability (Linux)\n   *\n   * @returns Promise that resolves when Java checks are complete\n   * @private\n   */\n  private async checkJavaInstallation(): Promise<void> {\n    // Check if Java is available\n    if (checkCommandExists('java')) {\n      try {\n        const { stdout, stderr } = await runCliCommand('java -version');\n        // java -version typically outputs to stderr, but check both\n        const versionInfo = stderr || stdout || '';\n        \n        // Try multiple version string formats:\n        // 1. version \"17.0.16\" (older format)\n        // 2. openjdk 17.0.16 (OpenJDK format)\n        // 3. java version \"17.0.16\" (alternative format)\n        let versionMatch = versionInfo.match(/version \"([^\"]+)\"/);\n        if (!versionMatch) {\n          versionMatch = versionInfo.match(/openjdk\\s+(\\d+\\.\\d+\\.\\d+)/i);\n        }\n        if (!versionMatch) {\n          versionMatch = versionInfo.match(/java\\s+(\\d+\\.\\d+\\.\\d+)/i);\n        }\n        \n        const version = versionMatch?.[1] ?? 'Unknown version';\n\n        // Check if Java version is 17 or higher\n        const majorVersionMatch = version.match(/^(\\d+)/);\n        const majorVersion = majorVersionMatch?.[1] ? Number.parseInt(majorVersionMatch[1], 10) : 0;\n\n        if (majorVersion >= 17) {\n          this.addResult({\n            name: 'Java Runtime',\n            status: 'pass',\n            message: `Java is installed: ${version}`,\n            category: 'Java installation',\n          });\n        } else if (majorVersion > 0) {\n          this.addResult({\n            name: 'Java Runtime',\n            status: 'fail',\n            message: `Java ${version} is outdated. Java 17+ is required`,\n            details: 'dev_setup installs Java 17 for Android development',\n            fixable: true,\n            fixCommand: this.getJavaInstallCommand(),\n            category: 'Java installation',\n          });\n        } else {\n          // Could detect java but not parse version\n          this.addResult({\n            name: 'Java Runtime',\n            status: 'pass',\n            message: 'Java is installed',\n            details: `Version info: ${versionInfo.split('\\n')[0] || 'Unable to parse version'}`,\n            category: 'Java installation',\n          });\n        }\n      } catch {\n        this.addResult({\n          name: 'Java Runtime',\n          status: 'pass',\n          message: 'Java is installed',\n          category: 'Java installation',\n        });\n      }\n    } else {\n      this.addResult({\n        name: 'Java Runtime',\n        status: 'fail',\n        message: 'Java not found in PATH',\n        details: 'dev_setup installs Java JDK for Android development',\n        fixable: true,\n        fixCommand: this.getJavaInstallCommand(),\n        category: 'Java installation',\n      });\n    }\n\n    // Check JAVA_HOME environment variable\n    const javaHome = process.env['JAVA_HOME'];\n    if (javaHome && fs.existsSync(javaHome)) {\n      this.addResult({\n        name: 'JAVA_HOME',\n        status: 'pass',\n        message: `JAVA_HOME set to ${javaHome}`,\n        category: 'Java installation',\n      });\n    } else {\n      this.addResult({\n        name: 'JAVA_HOME',\n        status: 'warn',\n        message: 'JAVA_HOME not set or invalid',\n        details: 'dev_setup configures JAVA_HOME for Android development',\n        fixable: true,\n        fixCommand: os.platform() === 'darwin' ? 'export JAVA_HOME=`/usr/libexec/java_home -v 17`' : 'Set JAVA_HOME environment variable',\n        category: 'Java installation',\n      });\n    }\n\n    // Check Java tools in PATH\n    const pathEnv = process.env['PATH'] || '';\n    if (os.platform() === 'darwin') {\n      if (pathEnv.includes('/opt/homebrew/opt/openjdk@17/bin')) {\n        this.addResult({\n          name: 'Java PATH',\n          status: 'pass',\n          message: 'Java tools in PATH',\n          category: 'Java installation',\n        });\n      } else if (pathEnv.includes('/opt/homebrew/opt/openjdk@11/bin')) {\n        this.addResult({\n          name: 'Java PATH',\n          status: 'fail',\n          message: 'Java 11 in PATH, but Java 17 is required',\n          details: 'dev_setup installs Java 17 for Android development',\n          fixable: true,\n          fixCommand: 'export PATH=\"/opt/homebrew/opt/openjdk@17/bin:$PATH\"',\n          category: 'Java installation',\n        });\n      } else {\n        this.addResult({\n          name: 'Java PATH',\n          status: 'warn',\n          message: 'Java tools not in PATH',\n          details: 'dev_setup adds Java tools to PATH',\n          fixable: true,\n          fixCommand: 'export PATH=\"/opt/homebrew/opt/openjdk@17/bin:$PATH\"',\n          category: 'Java installation',\n        });\n      }\n    }\n\n    // macOS-specific Java JDK symlink check\n    if (os.platform() === 'darwin') {\n      const jdk17Symlink = '/Library/Java/JavaVirtualMachines/openjdk-17.jdk';\n      const jdk11Symlink = '/Library/Java/JavaVirtualMachines/openjdk-11.jdk';\n\n      if (fs.existsSync(jdk17Symlink)) {\n        this.addResult({\n          name: 'Java JDK symlink',\n          status: 'pass',\n          message: 'OpenJDK 17 symlink configured',\n          category: 'Java installation',\n        });\n      } else if (fs.existsSync(jdk11Symlink)) {\n        this.addResult({\n          name: 'Java JDK symlink',\n          status: 'warn',\n          message: 'OpenJDK 11 symlink found, but Java 17 is required',\n          details: 'dev_setup installs Java 17',\n          fixable: true,\n          fixCommand: 'sudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk',\n          category: 'Java installation',\n        });\n      } else {\n        this.addResult({\n          name: 'Java JDK symlink',\n          status: 'warn',\n          message: 'OpenJDK symlink not found',\n          details: 'dev_setup creates symlink for system-wide Java access',\n          fixable: true,\n          fixCommand: 'sudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk',\n          category: 'Java installation',\n        });\n      }\n    }\n  }\n\n\n\n  /**\n   * Validates basic Android SDK components needed for app development.\n   *\n   * Checks essential Android SDK components without overwhelming users:\n   * - Android Platform (latest)\n   * - Build Tools (basic check)\n   *\n   * @private\n   */\n  private checkAndroidSDKBasics(): void {\n    const androidHome = process.env['ANDROID_HOME'] || process.env['ANDROID_SDK_ROOT'];\n\n    if (!androidHome || !fs.existsSync(androidHome)) {\n      this.addResult({\n        name: 'Android SDK Components',\n        status: 'warn',\n        message: 'Cannot check Android SDK components - ANDROID_HOME not set',\n        details: 'Set ANDROID_HOME environment variable for Android development',\n        fixable: true,\n        fixCommand: 'Install Android Studio and set ANDROID_HOME',\n        category: 'Android installation',\n      });\n      return;\n    }\n\n    // Check for any Android Platform (not specific version)\n    const platformsDir = path.join(androidHome, 'platforms');\n    if (fs.existsSync(platformsDir)) {\n      const platforms = fs.readdirSync(platformsDir).filter(dir => dir.startsWith('android-'));\n      if (platforms.length > 0) {\n        this.addResult({\n          name: 'Android Platform',\n          status: 'pass',\n          message: `Android Platform installed (${platforms.length} version${platforms.length > 1 ? 's' : ''})`,\n          category: 'Android installation',\n        });\n      } else {\n        this.addResult({\n          name: 'Android Platform',\n          status: 'warn',\n          message: 'No Android Platform found',\n          details: 'Install an Android Platform via Android Studio SDK Manager',\n          fixable: true,\n          fixCommand: 'Open Android Studio > SDK Manager > Install an Android Platform',\n          category: 'Android installation',\n        });\n      }\n    } else {\n      this.addResult({\n        name: 'Android Platform',\n        status: 'warn',\n        message: 'Android platforms directory not found',\n        fixable: true,\n        fixCommand: 'Install Android Studio and configure SDK',\n        category: 'Android installation',\n      });\n    }\n\n    // Check for any Build Tools (not specific version)\n    const buildToolsDir = path.join(androidHome, 'build-tools');\n    if (fs.existsSync(buildToolsDir)) {\n      const buildTools = fs.readdirSync(buildToolsDir);\n      if (buildTools.length > 0) {\n        this.addResult({\n          name: 'Android Build Tools',\n          status: 'pass',\n          message: `Android Build Tools installed (${buildTools.length} version${buildTools.length > 1 ? 's' : ''})`,\n          category: 'Android installation',\n        });\n      } else {\n        this.addResult({\n          name: 'Android Build Tools',\n          status: 'warn',\n          message: 'No Android Build Tools found',\n          fixable: true,\n          fixCommand: 'Install Build Tools via Android Studio SDK Manager',\n          category: 'Android installation',\n        });\n      }\n    } else {\n      this.addResult({\n        name: 'Android Build Tools',\n        status: 'warn',\n        message: 'Build tools directory not found',\n        fixable: true,\n        fixCommand: 'Install Android Studio and configure SDK',\n        category: 'Android installation',\n      });\n    }\n  }\n\n  /**\n   * Validates core development dependencies needed for app development.\n   *\n   * Focuses on essential tools that app developers need:\n   * - git: Version control (essential)\n   * - npm: Package management (essential)\n   * - watchman: File watching for hot reloader (essential)\n   * - ios-webkit-debug-proxy: iOS debugging for hot reloader (macOS only, essential)\n   *\n   * @returns Promise that resolves when core dependency checks are complete\n   * @private\n   */\n  private async checkCoreDependencies(): Promise<void> {\n    const coreDeps = ['git', 'npm', 'watchman'];\n\n    for (const dep of coreDeps) {\n      await this.checkSingleDependency(dep, 'fail'); // Core deps are critical\n    }\n\n    // Platform-specific core dependencies\n    if (os.platform() === 'darwin') {\n      await this.checkSingleDependency('ios_webkit_debug_proxy', 'fail'); // Essential for hot reloader\n    }\n  }\n\n  /**\n   * Validates Git LFS initialization status.\n   *\n   * Checks if git-lfs is installed and properly initialized.\n   * dev_setup runs `git lfs install` to configure Git LFS hooks.\n   *\n   * @returns Promise that resolves when Git LFS check is complete\n   * @private\n   */\n  private async checkGitLfsInitialization(): Promise<void> {\n    // First check if git-lfs command exists\n    if (!checkCommandExists('git-lfs')) {\n      const fixCommand = this.getFixCommandForDependency('git-lfs');\n      this.addResult({\n        name: 'Git LFS',\n        status: 'warn',\n        message: 'git-lfs not installed',\n        details: 'Required for working with large files in the repository',\n        fixable: true,\n        fixCommand,\n        category: 'Development tools',\n      });\n      return;\n    }\n\n    // Check if git lfs is initialized by checking the config\n    try {\n      const { stdout, returnCode } = await runCliCommand('git config --global --get filter.lfs.process');\n      \n      if (returnCode === 0 && stdout.trim()) {\n        this.addResult({\n          name: 'Git LFS initialization',\n          status: 'pass',\n          message: 'git-lfs is initialized',\n          category: 'Development tools',\n        });\n      } else {\n        this.addResult({\n          name: 'Git LFS initialization',\n          status: 'warn',\n          message: 'git-lfs is installed but not initialized',\n          details: 'Run git lfs install to configure Git LFS hooks',\n          fixable: true,\n          fixCommand: 'git lfs install',\n          category: 'Development tools',\n        });\n\n        if (this.autoFix) {\n          await this.attemptAutoFix('git-lfs', 'git lfs install');\n        }\n      }\n    } catch {\n      this.addResult({\n        name: 'Git LFS initialization',\n        status: 'warn',\n        message: 'git-lfs is installed but not initialized',\n        details: 'Run git lfs install to configure Git LFS hooks',\n        fixable: true,\n        fixCommand: 'git lfs install',\n        category: 'Development tools',\n      });\n\n      if (this.autoFix) {\n        await this.attemptAutoFix('git-lfs', 'git lfs install');\n      }\n    }\n  }\n\n  /**\n   * Validates shell autocomplete configuration.\n   *\n   * Checks if shell autocomplete (compinit/bashcompinit) is configured.\n   * dev_setup adds these to shell RC files for better CLI experience.\n   *\n   * @private\n   */\n  private checkShellAutoComplete(): void {\n    const homeDir = process.env['HOME'] ?? '';\n    const shell = process.env['SHELL'] ?? '';\n    \n    let rcFile: string | undefined;\n    let requiredLines: string[] = [];\n\n    // Determine shell and required configuration\n    if (shell.endsWith('/zsh')) {\n      rcFile = path.join(homeDir, '.zshrc');\n      requiredLines = ['autoload -U compinit && compinit', 'autoload -U bashcompinit && bashcompinit'];\n    } else if (shell.endsWith('/bash')) {\n      rcFile = path.join(homeDir, '.bashrc');\n      // Bash typically auto-loads completion, so we're more lenient\n      requiredLines = [];\n    } else {\n      // Unknown shell, skip check\n      return;\n    }\n\n    if (!rcFile || !fs.existsSync(rcFile)) {\n      this.addResult({\n        name: 'Shell autocomplete',\n        status: 'warn',\n        message: `Shell configuration file not found (${rcFile || 'unknown'})`,\n        details: 'Shell autocomplete improves CLI experience',\n        category: 'Development tools',\n      });\n      return;\n    }\n\n    // For bash, we just report success since it typically handles completion automatically\n    if (requiredLines.length === 0) {\n      this.addResult({\n        name: 'Shell autocomplete',\n        status: 'pass',\n        message: 'Shell autocomplete configured (bash)',\n        category: 'Development tools',\n      });\n      return;\n    }\n\n    // Read RC file and check for required lines\n    try {\n      const rcContent = fs.readFileSync(rcFile, 'utf8');\n      const rcLines = rcContent.split('\\n');\n      \n      const missingLines: string[] = [];\n      for (const required of requiredLines) {\n        if (!rcLines.includes(required)) {\n          missingLines.push(required);\n        }\n      }\n\n      if (missingLines.length === 0) {\n        this.addResult({\n          name: 'Shell autocomplete',\n          status: 'pass',\n          message: 'Shell autocomplete configured',\n          category: 'Development tools',\n        });\n      } else {\n        this.addResult({\n          name: 'Shell autocomplete',\n          status: 'warn',\n          message: 'Shell autocomplete not fully configured',\n          details: `Missing in ${rcFile}: ${missingLines.join(', ')}`,\n          fixable: true,\n          fixCommand: `Add to ${rcFile}: ${missingLines.join(' && ')}`,\n          category: 'Development tools',\n        });\n      }\n    } catch {\n      this.addResult({\n        name: 'Shell autocomplete',\n        status: 'warn',\n        message: 'Could not verify shell autocomplete configuration',\n        category: 'Development tools',\n      });\n    }\n  }\n\n  /**\n   * Validates VSCode/Cursor extensions installation.\n   *\n   * Checks if Valdi extensions are installed in VSCode or Cursor:\n   * - valdi-vivaldi: Device logs and language support\n   * - valdi-debug: JavaScript debugger\n   *\n   * @returns Promise that resolves when extension checks are complete\n   * @private\n   */\n  private async checkEditorExtensions(): Promise<void> {\n    const hasCode = checkCommandExists('code');\n    const hasCursor = checkCommandExists('cursor');\n\n    if (!hasCode && !hasCursor) {\n      // No editor installed, skip check\n      return;\n    }\n\n    let extensionsInstalled = false;\n\n    // Check VSCode extensions\n    if (hasCode) {\n      try {\n        const { stdout } = await runCliCommand('code --list-extensions');\n        const installedExtensions = stdout.toLowerCase();\n        \n        const hasVivaldi = installedExtensions.includes('valdi-vivaldi');\n        const hasDebug = installedExtensions.includes('valdi-debug');\n\n        if (hasVivaldi && hasDebug) {\n          extensionsInstalled = true;\n          this.addResult({\n            name: 'VSCode Extensions',\n            status: 'pass',\n            message: 'Valdi extensions installed in VSCode',\n            category: 'Development tools',\n          });\n        }\n      } catch {\n        // Could not check VSCode extensions\n      }\n    }\n\n    // Check Cursor extensions\n    if (hasCursor) {\n      try {\n        const { stdout } = await runCliCommand('cursor --list-extensions');\n        const installedExtensions = stdout.toLowerCase();\n        \n        const hasVivaldi = installedExtensions.includes('valdi-vivaldi');\n        const hasDebug = installedExtensions.includes('valdi-debug');\n\n        if (hasVivaldi && hasDebug) {\n          extensionsInstalled = true;\n          this.addResult({\n            name: 'Cursor Extensions',\n            status: 'pass',\n            message: 'Valdi extensions installed in Cursor',\n            category: 'Development tools',\n          });\n        }\n      } catch {\n        // Could not check Cursor extensions\n      }\n    }\n\n    // If neither editor has extensions, show info\n    if (!extensionsInstalled && (hasCode || hasCursor)) {\n      const editor = hasCode ? 'VSCode' : 'Cursor';\n      this.addResult({\n        name: `${editor} Extensions`,\n        status: 'warn',\n        message: 'Valdi editor extensions not installed',\n        details: 'Extensions provide syntax highlighting, debugging, and device logs',\n        fixable: true,\n        fixCommand: 'See installation instructions: https://github.com/Snapchat/Valdi/blob/main/docs/INSTALL.md#vscodecursor-setup-optional-but-recommended',\n        category: 'Development tools',\n      });\n    }\n  }\n\n  /**\n   * Validates framework development dependencies.\n   *\n   * Additional tools needed for framework development:\n   * - temurin: Alternative JDK (macOS)\n   *\n   * Note: git-lfs is now checked in core dependencies with initialization verification\n   *\n   * @private\n   */\n  private checkFrameworkDependencies(): void {\n    // git-lfs is now checked in core with initialization verification\n\n    // Platform-specific framework dependencies\n    if (os.platform() === 'darwin') {\n      // Check for temurin package\n      const temurinPath = '/opt/homebrew/opt/temurin';\n      if (fs.existsSync(temurinPath)) {\n        this.addResult({\n          name: 'temurin package',\n          status: 'pass',\n          message: 'temurin installed via Homebrew',\n          category: 'Framework tools',\n        });\n      } else {\n        this.addResult({\n          name: 'temurin package',\n          status: 'warn',\n          message: 'temurin not found',\n          details: 'Alternative JDK for framework development',\n          fixable: true,\n          fixCommand: 'brew install temurin',\n          category: 'Framework tools',\n        });\n      }\n    }\n  }\n\n  /**\n   * Validates advanced Android SDK components for framework development.\n   *\n   * Detailed Android SDK validation including:\n   * - Specific platform versions\n   * - NDK installation\n   * - Command line tools\n   *\n   * @private\n   */\n  private checkAdvancedAndroidSDK(): void {\n    const androidHome = process.env['ANDROID_HOME'] || process.env['ANDROID_SDK_ROOT'];\n\n    if (!androidHome || !fs.existsSync(androidHome)) {\n      return; // Already checked in basics\n    }\n\n    // Check specific Android Platform version\n    const platformPath = path.join(androidHome, 'platforms', ANDROID_PLATFORM_VERSION);\n    if (fs.existsSync(platformPath)) {\n      this.addResult({\n        name: `Android Platform ${ANDROID_PLATFORM_VERSION}`,\n        status: 'pass',\n        message: `Android Platform ${ANDROID_PLATFORM_VERSION} installed`,\n        category: 'Android installation',\n      });\n    } else {\n      this.addResult({\n        name: `Android Platform ${ANDROID_PLATFORM_VERSION}`,\n        status: 'warn',\n        message: `Android Platform ${ANDROID_PLATFORM_VERSION} not found`,\n        details: 'Specific platform version for framework development',\n        fixable: true,\n        fixCommand: `sdkmanager --install 'platforms;${ANDROID_PLATFORM_VERSION}'`,\n        category: 'Android installation',\n      });\n    }\n\n    // Check Android NDK\n    const ndkPath = path.join(androidHome, 'ndk', ANDROID_NDK_VERSION);\n    if (fs.existsSync(ndkPath)) {\n      this.addResult({\n        name: 'Android NDK',\n        status: 'pass',\n        message: `Android NDK ${ANDROID_NDK_VERSION} installed`,\n        category: 'Android installation',\n      });\n    } else {\n      this.addResult({\n        name: 'Android NDK',\n        status: 'warn',\n        message: `Android NDK ${ANDROID_NDK_VERSION} not found`,\n        details: 'Required for native development in framework',\n        fixable: true,\n        fixCommand: `sdkmanager --install 'ndk;${ANDROID_NDK_VERSION}'`,\n        category: 'Android installation',\n      });\n    }\n  }\n\n\n\n\n\n  /**\n   * Checks a single dependency and reports its status.\n   * @private\n   */\n  private async checkSingleDependency(dep: string, failureLevel: 'warn' | 'fail'): Promise<void> {\n    // Determine category based on dependency type\n    let category: string;\n    if (['git', 'npm', 'watchman', 'ios_webkit_debug_proxy'].includes(dep)) {\n      category = 'Development tools';\n    } else if (['git-lfs', 'temurin'].includes(dep)) {\n      category = 'Framework tools';\n    } else {\n      category = 'Development tools';\n    }\n\n    if (checkCommandExists(dep)) {\n      try {\n        const { stdout } = await runCliCommand(`${dep} --version`);\n        const versionLine = stdout.split('\\n')[0] || 'Unknown version';\n        this.addResult({\n          name: `${dep} installation`,\n          status: 'pass',\n          message: `${dep} is installed: ${versionLine}`,\n          category,\n        });\n      } catch {\n        this.addResult({\n          name: `${dep} installation`,\n          status: 'pass',\n          message: `${dep} is installed`,\n          category,\n        });\n      }\n    } else {\n      const fixCommand = this.getFixCommandForDependency(dep);\n      this.addResult({\n        name: `${dep} installation`,\n        status: failureLevel,\n        message: `${dep} is not installed or not in PATH`,\n        fixable: true,\n        fixCommand,\n        category,\n      });\n\n      if (this.autoFix && failureLevel === 'fail') {\n        await this.attemptAutoFix(dep, fixCommand);\n      }\n    }\n  }\n\n  /**\n   * Validates environment variables as configured by dev_setup.\n   *\n   * Checks for essential environment variables that dev_setup configures:\n   * - ANDROID_HOME: Android SDK location\n   * - ANDROID_NDK_HOME: Android NDK location\n   * - JAVA_HOME: Java JDK location\n   * - PATH modifications: Java, Android tools, Bazelisk\n   *\n   * @private\n   */\n  private checkEnvironmentVariables(): void {\n    // Check ANDROID_HOME\n    const androidHome = process.env['ANDROID_HOME'];\n    if (androidHome && fs.existsSync(androidHome)) {\n      this.addResult({\n        name: 'ANDROID_HOME',\n        status: 'pass',\n        message: `ANDROID_HOME set to ${androidHome}`,\n        category: 'Android installation',\n      });\n    } else {\n      this.addResult({\n        name: 'ANDROID_HOME',\n        status: 'fail',\n        message: 'ANDROID_HOME not set or invalid',\n        details: 'dev_setup configures ANDROID_HOME for Android development',\n        fixable: true,\n        fixCommand: 'valdi dev_setup',\n        category: 'Android installation',\n      });\n    }\n\n    // Check ANDROID_NDK_HOME\n    const androidNdkHome = process.env['ANDROID_NDK_HOME'];\n    if (androidNdkHome && fs.existsSync(androidNdkHome)) {\n      this.addResult({\n        name: 'ANDROID_NDK_HOME',\n        status: 'pass',\n        message: `ANDROID_NDK_HOME set to ${androidNdkHome}`,\n        category: 'Android installation',\n      });\n    } else {\n      this.addResult({\n        name: 'ANDROID_NDK_HOME',\n        status: 'warn',\n        message: 'ANDROID_NDK_HOME not set or invalid',\n        details: 'dev_setup configures ANDROID_NDK_HOME for native development',\n        fixable: true,\n        fixCommand: 'valdi dev_setup',\n        category: 'Android installation',\n      });\n    }\n\n    // Check platform-tools in PATH\n    const pathEnvAndroid = process.env['PATH'] || '';\n    const androidHomeForPath = process.env['ANDROID_HOME'];\n    if (androidHomeForPath) {\n      const platformToolsInPath = pathEnvAndroid.includes(`${androidHomeForPath}/platform-tools`) || \n                                   pathEnvAndroid.includes('platform-tools');\n      if (platformToolsInPath) {\n        this.addResult({\n          name: 'Android platform-tools PATH',\n          status: 'pass',\n          message: 'Android platform-tools in PATH',\n          category: 'Android installation',\n        });\n      } else {\n        this.addResult({\n          name: 'Android platform-tools PATH',\n          status: 'warn',\n          message: 'Android platform-tools not in PATH',\n          details: 'dev_setup adds platform-tools (containing adb) to PATH',\n          fixable: true,\n          fixCommand: 'export PATH=\"$ANDROID_HOME/platform-tools:$PATH\"',\n          category: 'Android installation',\n        });\n      }\n    }\n\n    // JAVA_HOME is checked in Java installation section to avoid duplication\n\n    // Check PATH modifications\n    const pathEnv = process.env['PATH'] || '';\n\n    // Check for Bazelisk in PATH (Linux only - Java PATH checked in Java section)\n    if (os.platform() === 'linux') {\n      if (pathEnv.includes('/.valdi/bin')) {\n        this.addResult({\n          name: 'Bazelisk PATH',\n          status: 'pass',\n          message: 'Bazelisk directory in PATH',\n          category: 'Bazel installation',\n        });\n      } else {\n        this.addResult({\n          name: 'Bazelisk PATH',\n          status: 'warn',\n          message: 'Bazelisk directory not in PATH',\n          details: 'dev_setup adds ~/.valdi/bin to PATH for Bazelisk',\n          fixable: true,\n          fixCommand: 'export PATH=\"$HOME/.valdi/bin:$PATH\"',\n          category: 'Bazel installation',\n        });\n      }\n    }\n  }\n\n  /**\n   * Gets the appropriate Java installation command for the current platform\n   * @private\n   */\n  private getJavaInstallCommand(): string {\n    if (os.platform() === 'darwin') {\n      return 'brew install openjdk@17';\n    } else if (os.platform() === 'linux' && this.linuxDistro) {\n      const packageMappings = getCommonPackageMappings();\n      const javaPackage = getPackageName(packageMappings['openjdk-17']!, this.linuxDistro);\n      return buildInstallCommand([javaPackage], this.linuxDistro);\n    } else {\n      return 'Install Java 17 JDK for your distribution';\n    }\n  }\n\n  /**\n   * Generates platform-specific fix commands for missing dependencies.\n   *\n   * Provides appropriate installation commands based on the current platform\n   * and the specific dependency that's missing. Enhanced to support all\n   * dependencies that dev_setup installs.\n   *\n   * @param dep - The name of the missing dependency\n   * @returns Platform-appropriate installation command or instruction\n   * @private\n   */\n  private getFixCommandForDependency(dep: string): string {\n    // macOS-specific dependencies\n    if (os.platform() === 'darwin') {\n      switch (dep) {\n        case 'git': {\n          return 'brew install git';\n        }\n        case 'npm': {\n          return 'Install Node.js from https://nodejs.org (includes npm)';\n        }\n        case 'watchman': {\n          return 'brew install watchman';\n        }\n        case 'git-lfs': {\n          return 'brew install git-lfs';\n        }\n        case 'bazelisk': {\n          return 'brew install bazelisk';\n        }\n        case 'ios_webkit_debug_proxy': {\n          return 'brew install ios-webkit-debug-proxy';\n        }\n        default: {\n          return `brew install ${dep}`;\n        }\n      }\n    }\n\n    // Linux dependencies with distribution detection\n    if (os.platform() === 'linux' && this.linuxDistro) {\n      const packageMappings = getCommonPackageMappings();\n\n      switch (dep) {\n        case 'git': {\n          return buildInstallCommand(['git'], this.linuxDistro);\n        }\n        case 'npm': {\n          return buildInstallCommand([getPackageName(packageMappings['npm']!, this.linuxDistro)], this.linuxDistro);\n        }\n        case 'watchman': {\n          const watchmanPkg = getPackageName(packageMappings['watchman']!, this.linuxDistro);\n          const cmd = buildInstallCommand([watchmanPkg], this.linuxDistro);\n          // Add note for RHEL-based systems\n          if (this.linuxDistro.packageManager.name === 'yum' || this.linuxDistro.packageManager.name === 'dnf') {\n            return `${cmd} (may require EPEL repository)`;\n          }\n          return cmd;\n        }\n        case 'git-lfs': {\n          return buildInstallCommand([getPackageName(packageMappings['git-lfs']!, this.linuxDistro)], this.linuxDistro);\n        }\n        case 'bazelisk': {\n          return 'valdi dev_setup';\n        }\n        case 'adb': {\n          return buildInstallCommand([getPackageName(packageMappings['adb']!, this.linuxDistro)], this.linuxDistro);\n        }\n        default: {\n          return buildInstallCommand([dep], this.linuxDistro);\n        }\n      }\n    }\n\n    // Fallback for unknown platforms or when distro detection fails\n    switch (dep) {\n      case 'npm': {\n        return 'Install Node.js from https://nodejs.org (includes npm)';\n      }\n      case 'bazelisk': {\n        return 'valdi dev_setup';\n      }\n      default: {\n        return `Install ${dep} using your system's package manager`;\n      }\n    }\n  }\n\n  /**\n   * Outputs diagnostic results in JSON format for machine processing.\n   *\n   * Generates a structured JSON report containing:\n   * - ISO timestamp of the diagnostic run\n   * - Summary statistics (passed, warnings, failed, total)\n   * - Complete array of diagnostic results with all details\n   *\n   * This format is ideal for:\n   * - CI/CD pipeline integration\n   * - Automated monitoring and alerting\n   * - Programmatic analysis of environment health\n   * @example\n   * ```json\n   * {\n   *   \"timestamp\": \"2024-01-15T10:30:00.000Z\",\n   *   \"summary\": { \"passed\": 8, \"warnings\": 0, \"failed\": 1, \"total\": 9 },\n   *   \"results\": [...]\n   * }\n   * ```\n   */\n  private printJsonResults(): void {\n    const passCount = this.results.filter(r => r.status === 'pass').length;\n    const warnCount = this.results.filter(r => r.status === 'warn').length;\n    const failCount = this.results.filter(r => r.status === 'fail').length;\n\n    const output = {\n      timestamp: new Date().toISOString(),\n      summary: {\n        passed: passCount,\n        warnings: warnCount,\n        failed: failCount,\n        total: this.results.length,\n      },\n      results: this.results,\n    };\n\n    console.log(JSON.stringify(output, null, 2));\n  }\n\n  /**\n   * Outputs diagnostic results in human-readable format with colors and icons.\n   *\n   * Generates a formatted report with:\n   * - Grouped categories for better readability\n   * - Colored status icons (✓ ⚠ ✗) for visual clarity\n   * - Detailed issue information only when problems exist\n   * - Optional verbose details when requested\n   * - Actionable fix commands for failed checks\n   * - Summary statistics and overall health assessment\n   *\n   * The output uses ANSI color codes for enhanced readability:\n   * - Green (✓): Successful checks\n   * - Yellow (⚠): Warnings that don't block development\n   * - Red (✗): Critical failures requiring attention\n   * @example\n   * ```\n   * Valdi Doctor Report\n   * ==================================================\n   * ✓ Node.js installation\n   * ✗ Java installation\n   *   • JAVA_HOME not set or invalid\n   *   • Java tools not in PATH\n   * ==================================================\n   * Summary: 1 passed, 0 warnings, 1 failed\n   * ```\n   */\n  private printFormattedResults(): void {\n    console.log(wrapInColor('Valdi Doctor Report', ANSI_COLORS.BLUE_COLOR));\n    console.log('='.repeat(50));\n    console.log();\n\n    const groupedResults = this.groupResultsByCategory();\n    let totalPassCount = 0;\n    let totalWarnCount = 0;\n    let totalFailCount = 0;\n\n    for (const group of groupedResults) {\n      const statusIcon = group.status === 'pass' ? '✓' : group.status === 'warn' ? '⚠' : '✗';\n      const statusColor = group.status === 'pass' ? ANSI_COLORS.GREEN_COLOR :\n                         group.status === 'warn' ? ANSI_COLORS.YELLOW_COLOR : ANSI_COLORS.RED_COLOR;\n\n      console.log(`${wrapInColor(statusIcon, statusColor)} ${group.category}`);\n\n      // Show issues when there are problems\n      if (group.issues.length > 0) {\n        for (const issue of group.issues) {\n          console.log(`   • ${issue.message}`);\n\n          if (this.verbose && issue.details) {\n            console.log(`     ${wrapInColor('Details:', ANSI_COLORS.GRAY_COLOR)} ${issue.details}`);\n          }\n\n          if (issue.fixable && issue.fixCommand) {\n            console.log(`     ${wrapInColor('Fix:', ANSI_COLORS.BLUE_COLOR)} ${issue.fixCommand}`);\n          }\n        }\n      }\n\n      console.log();\n\n      // Count individual check results for summary\n      for (const check of group.checks) {\n        if (check.status === 'pass') totalPassCount++;\n        else if (check.status === 'warn') totalWarnCount++;\n        else totalFailCount++;\n      }\n    }\n\n    console.log('='.repeat(50));\n    console.log(`${wrapInColor('Summary:', ANSI_COLORS.BLUE_COLOR)} ${totalPassCount} passed, ${totalWarnCount} warnings, ${totalFailCount} failed`);\n\n    if (totalFailCount > 0) {\n      console.log();\n      console.log(wrapInColor('Some issues need to be resolved before Valdi can work properly.', ANSI_COLORS.RED_COLOR));\n      console.log();\n      console.log(wrapInColor('Still having trouble? Come get help on Discord:', ANSI_COLORS.BLUE_COLOR));\n      console.log(wrapInColor(DISCORD_SUPPORT_URL, ANSI_COLORS.BLUE_COLOR));\n      console.log(wrapInColor('Please paste the entire output of this command when asking for help.', ANSI_COLORS.YELLOW_COLOR));\n    } else if (totalWarnCount > 0) {\n      console.log();\n      console.log(wrapInColor('Your environment is mostly ready, but some optional tools are missing.', ANSI_COLORS.YELLOW_COLOR));\n    } else {\n      console.log();\n      console.log(wrapInColor('Your Valdi development environment is ready! 🎉', ANSI_COLORS.GREEN_COLOR));\n    }\n  }\n}\n\n/**\n * Main entry point for the Valdi doctor command.\n *\n * This function serves as the command handler that:\n * 1. Extracts command line arguments (verbose, fix, json)\n * 2. Creates a new ValdiDoctor instance with the specified configuration\n * 3. Executes the complete diagnostic suite\n * 4. Outputs results in the requested format\n *\n * @param argv - Resolved command line arguments\n * @returns Promise that resolves when the doctor command completes\n * \n * @example\n * ```bash\n * valdi doctor --verbose --fix --json\n * ```\n */\nasync function valdiDoctor(argv: ArgumentsResolver<CommandParameters>): Promise<void> {\n  const verbose = argv.getArgument('verbose');\n  const autoFix = argv.getArgument('fix');\n  const jsonOutput = argv.getArgument('json');\n  const frameworkMode = argv.getArgument('framework');\n  const projectMode = argv.getArgument('project');\n\n  const doctor = new ValdiDoctor(verbose, autoFix, jsonOutput, frameworkMode, projectMode);\n  const status = await doctor.runDiagnostics();\n  doctor.printResults();\n\n  if (status === 'fail') {\n    throw new Error('valdi doctor failed');\n  }\n}\n\n// ============================================================================\n// YARGS COMMAND CONFIGURATION\n// ============================================================================\n\n/**\n * The command name as it appears in the CLI.\n \n */\nexport const command = 'doctor';\n\n/**\n * Human-readable description of the command for help output.\n \n */\nexport const describe = 'Check your Valdi development environment for common issues';\n\n/**\n * Configures command line options and their validation.\n *\n * Defines three main options:\n * - `--verbose` (-v): Enable detailed diagnostic output\n * - `--fix` (-f): Attempt automatic fixes where possible\n * - `--json` (-j): Output results in JSON format for automation\n *\n * @param yargs - The yargs instance to configure\n \n */\nexport const builder = (yargs: Argv<CommandParameters>): void => {\n  yargs\n    .option('verbose', {\n      describe: 'Show detailed diagnostic information',\n      type: 'boolean',\n      default: false,\n      alias: 'v',\n    })\n    .option('fix', {\n      describe: 'Attempt to automatically fix issues where possible',\n      type: 'boolean',\n      default: false,\n      alias: 'f',\n    })\n    .option('json', {\n      describe: 'Output results in JSON format',\n      type: 'boolean',\n      default: false,\n      alias: 'j',\n    })\n    .option('framework', {\n      describe: 'Include framework development checks (git-lfs, temurin, etc.)',\n      type: 'boolean',\n      default: false,\n      alias: 'F',\n    })\n    .option('project', {\n      describe: 'Include project-specific checks (workspace structure, etc.)',\n      type: 'boolean',\n      default: false,\n      alias: 'p',\n    });\n};\n\n/**\n * The command handler wrapped with error handling and logging.\n \n */\nexport const handler = makeCommandHandler(valdiDoctor);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/export.ts",
    "content": "import * as fs from 'fs';\nimport path from 'path';\nimport type { Argv } from 'yargs';\nimport { ALL_ARCHITECTURES, ANSI_COLORS, PLATFORM } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport type { SharedCommandParameters } from '../utils/applicationUtils';\nimport {\n  exportedLibraryExtensionForPlatform,\n  getExportedLibraryTargetTagForPlatform,\n  getOutputFilePath,\n  makeArgsBuilder,\n  resolveBazelBuildArgs,\n  selectBazelTarget,\n} from '../utils/applicationUtils';\nimport { logReproduceThisCommandIfNeeded, makeCommandHandler } from '../utils/errorUtils';\nimport { removeFileOrDirAtPath } from '../utils/fileUtils';\nimport { wrapInColor } from '../utils/logUtils';\nimport { withTempDir } from '../utils/tempDir';\nimport { decompressTo } from '../utils/zipUtils';\n\ninterface CommandParameters extends SharedCommandParameters {\n  library: string | undefined;\n  target_output_path: string | undefined;\n  output_path: string;\n}\n\nasync function decompressAndMoveXCFrameworkIntoDestination(\n  bazelOutputFilePath: string,\n  resolvedOutputPath: string,\n): Promise<void> {\n  await withTempDir(async tempDir => {\n    await decompressTo(bazelOutputFilePath, tempDir);\n\n    const decompressedOutputs = fs.readdirSync(tempDir);\n    if (decompressedOutputs.length !== 1) {\n      throw new Error(\n        `Expected 1 unzipped output, got ${decompressedOutputs.length} (${decompressedOutputs.join(', ')})`,\n      );\n    }\n\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    const inputDir = path.join(tempDir, decompressedOutputs[0]!);\n\n    await fs.promises.rename(inputDir, resolvedOutputPath);\n  });\n}\n\nasync function valdiExport(argv: ArgumentsResolver<CommandParameters>): Promise<void> {\n  const bazel = new BazelClient();\n  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n  const platform = argv.getArgument('platform') as PLATFORM;\n  const bazelArgs = resolveBazelBuildArgs(\n    platform,\n    argv.getArgument('build_config'),\n    ALL_ARCHITECTURES,\n    /* forDevice */ false,\n    argv.getArgument('enable_runtime_logs'),\n    argv.getArgument('enable_runtime_traces'),\n    argv.getArgument('bazel_args'),\n  );\n\n  const resolvedOutputPath = path.resolve(argv.getArgument('output_path'));\n  const expectedExtension = exportedLibraryExtensionForPlatform(platform);\n  if (!resolvedOutputPath.endsWith(expectedExtension)) {\n    throw new CliError(`Output path for platform '${platform}' must have ${expectedExtension} file extension`);\n  }\n\n  removeFileOrDirAtPath(resolvedOutputPath);\n  const directoryPath = path.dirname(resolvedOutputPath);\n  if (!fs.existsSync(directoryPath)) {\n    fs.mkdirSync(directoryPath, { recursive: true });\n  }\n\n  const library = await argv.getArgumentOrResolve('library', () => {\n    console.log('No library specified querying available targets...');\n    return selectBazelTarget(\n      bazel,\n      getExportedLibraryTargetTagForPlatform(platform),\n      'valdi_exported_library',\n      'Please select a library to export:',\n    );\n  });\n\n  console.log('Resolving output paths...');\n\n  const bazelOutputExtension = platform === PLATFORM.IOS ? '.zip' : expectedExtension;\n  const bazelOutputFilePath = await argv.getArgumentOrResolve('target_output_path', () => {\n    console.log('Resolving output paths...');\n    return getOutputFilePath(bazel, bazelOutputExtension, library, bazelArgs);\n  });\n\n  console.log(`Building: ${wrapInColor(library, ANSI_COLORS.GREEN_COLOR)}`);\n\n  await bazel.buildTarget(library, bazelArgs);\n\n  console.log(`Copying built target to ${resolvedOutputPath}...`);\n  if (platform === PLATFORM.IOS) {\n    await decompressAndMoveXCFrameworkIntoDestination(bazelOutputFilePath, resolvedOutputPath);\n  } else {\n    await fs.promises.copyFile(bazelOutputFilePath, resolvedOutputPath);\n  }\n\n  logReproduceThisCommandIfNeeded(argv);\n\n  console.log('All done!');\n}\n\nexport const command = 'export <platform>';\nexport const describe = 'Build and export a Valdi library';\nexport const builder = makeArgsBuilder((yargs: Argv<CommandParameters>) => {\n  yargs\n    .option('library', {\n      describe: 'Name of the library to build',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('target_output_path', {\n      describe: 'The output path for the Bazel target',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('output_path', {\n      describe: 'The path where to store the built application package',\n      type: 'string',\n      requiresArg: true,\n    })\n    .demandOption('output_path');\n});\nexport const handler = makeCommandHandler(valdiExport);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/hotreload.ts",
    "content": "import type { Argv } from 'yargs';\nimport { ANSI_COLORS } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport type { CliChoice } from '../utils/cliUtils';\nimport { getUserChoice, spawnCliCommand } from '../utils/cliUtils';\nimport { logReproduceThisCommandIfNeeded, makeCommandHandler } from '../utils/errorUtils';\nimport { wrapInColor } from '../utils/logUtils';\n\ninterface CommandParameters {\n  module: string | undefined;\n  target: string | undefined;\n}\n\nasync function hotreloadResolvedTarget(client: BazelClient, resolvedTarget: string) {\n  await client.buildTarget(resolvedTarget);\n  const workspaceRoot = await client.getWorkspaceRoot();\n  const buildOutputs = await client.queryBuildOutputs([resolvedTarget]);\n\n  if (buildOutputs.length === 0) {\n    throw new CliError(`No build outputs found for target: ${resolvedTarget}`);\n  }\n\n  const hotreloadCommand = buildOutputs[0] ?? '';\n\n  await spawnCliCommand(hotreloadCommand, workspaceRoot, 'inherit', true, false);\n}\n\nasync function hotreloadTarget(client: BazelClient, target: string) {\n  const resolvedLabel = await client.resolveLabel(target);\n  let resolvedTarget: string;\n  if (resolvedLabel.name) {\n    resolvedTarget = resolvedLabel.toString();\n  } else {\n    const targets = await client.query(`kind('valdi_hotreload', ${resolvedLabel.toString()}/...)`);\n    if (targets.length === 0) {\n      throw new Error(`Could not resolve hot reload target for label ${resolvedLabel.toString()}`);\n    }\n    if (targets.length !== 1) {\n      throw new Error(`Resolved more than 1 hot reload target for ${resolvedLabel.toString()}: ${targets.join(',')}`);\n    }\n    resolvedTarget = targets[0] as string;\n  }\n\n  await hotreloadResolvedTarget(client, resolvedTarget);\n}\n\nasync function getHotreloadTargetByModuleName(client: BazelClient, moduleName: string): Promise<string> {\n  const targets = await client.query(`filter(${moduleName}_hotreload, kind('valdi_hotreload rule', //...))`);\n  if (targets.length === 0) {\n    throw new CliError(`No hotreload target found for module: ${moduleName}`);\n  }\n\n  return targets[0]?.trim() ?? '';\n}\n\nasync function valdiHotreload(argv: ArgumentsResolver<CommandParameters>) {\n  const client = new BazelClient();\n\n  // TODO(3136): Try discovering and building with default path to modules first\n  const target = await argv.getArgumentOrResolve('target', async () => {\n    const module = argv.getArgument('module');\n    if (module) {\n      console.log('Finding target for module:', wrapInColor(module, ANSI_COLORS.GREEN_COLOR));\n      const target = await getHotreloadTargetByModuleName(client, module);\n      console.log('Found target:', wrapInColor(target, ANSI_COLORS.GREEN_COLOR));\n      return target;\n    }\n    const targets = await client.query('attr(\"tags\", \"valdi_application\", //...)');\n    if (targets.length === 0) {\n      throw new CliError(`Could not resolve Valdi application Bazel target`);\n    }\n\n    if (targets.length === 1) {\n      return targets[0] as string;\n    } else {\n      const choices: Array<CliChoice<string>> = targets.map((target, index) => ({\n        name: `${index + 1}. ${target}`,\n        value: target,\n      }));\n\n      return await getUserChoice(choices, 'Please choose a target to hot reload:');\n    }\n  });\n\n  logReproduceThisCommandIfNeeded(argv);\n\n  await hotreloadResolvedTarget(client, target);\n}\n\nexport const command = 'hotreload [--module module_name] [--target target_name]';\nexport const describe = 'Starts the hotreloader for the application';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs\n    .option('module', {\n      describe: 'Name of the module to hotreload',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('target', {\n      describe: 'Bazel target path to hotreload',\n      type: 'string',\n      requiresArg: true,\n    });\n};\n\nexport const handler = makeCommandHandler(valdiHotreload);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/install.ts",
    "content": "import { type Argv } from 'yargs';\nimport { ANSI_COLORS, PLATFORM } from '../core/constants';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport {\n  applicationExtensionForPlatform,\n  getOutputFilePath,\n  makeArgsBuilder,\n} from '../utils/applicationUtils';\nimport type { CommandParameters} from '../utils/buildInfo';\nimport { getBuildInfo } from '../utils/buildInfo';\nimport { installAndroidApk } from '../utils/deviceUtils';\nimport { logReproduceThisCommandIfNeeded, makeCommandHandler } from '../utils/errorUtils';\nimport { wrapInColor } from '../utils/logUtils';\n\n\nasync function valdiInstall(argv: ArgumentsResolver<CommandParameters>) {\n  const bazel = new BazelClient();\n\n  const buildInfo = await getBuildInfo(argv, bazel, true);  \n\n  // Output Selection\n  // ----------------\n\n  // Perform build and install\n  // -------------------------\n  console.log(`Building: ${wrapInColor(buildInfo.application, ANSI_COLORS.GREEN_COLOR)}`);\n\n  switch (buildInfo.platform) {\n    case PLATFORM.ANDROID: {\n      const outputFilePath = await argv.getArgumentOrResolve('target_output_path', () => {\n        console.log('Resolving output paths...');\n        return getOutputFilePath(bazel, applicationExtensionForPlatform(buildInfo.platform), buildInfo.application, buildInfo.bazelArgs);\n      });\n      await bazel.buildTarget(buildInfo.application, buildInfo.bazelArgs);\n\n      console.log('Installing Android application...');\n      await installAndroidApk(outputFilePath, buildInfo.selectedDevice);\n      logReproduceThisCommandIfNeeded(argv);\n      break;\n    }\n    case PLATFORM.IOS: {\n      console.log('Installing iOS application...');\n      await bazel.runTarget(buildInfo.application, buildInfo.bazelArgs);\n      logReproduceThisCommandIfNeeded(argv);\n      break;\n    }\n    case PLATFORM.MACOS: {\n      logReproduceThisCommandIfNeeded(argv);\n      console.log('Installing MacOS application...');\n      await bazel.runTarget(buildInfo.application, buildInfo.bazelArgs);\n      break;\n    }\n    case PLATFORM.CLI: {\n      logReproduceThisCommandIfNeeded(argv);\n      console.log('Running CLI application...');\n      await bazel.runTarget(buildInfo.application, buildInfo.bazelArgs);\n      break;\n    }\n  }\n}\n\nexport const command = 'install <platform>';\nexport const describe = 'Build and install the application to the connected device';\nexport const builder = makeArgsBuilder((yargs: Argv<CommandParameters>) => {\n  yargs\n    .option('application', {\n      describe: 'Name of the application to install',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('device_id', {\n      describe: 'Device ID that will receive the application',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('target_output_path', {\n      describe: 'The output path for the Bazel target',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('simulator', {\n      describe: 'Whether to build for simulator or for device',\n      type: 'boolean',\n    });\n});\nexport const handler = makeCommandHandler(valdiInstall);\n\n// TODOs:\n// - Cached bazel query results\n\n// Extract 'custom_package' from android_binary\n// Extract 'bundle_id' from ios_application target\n"
  },
  {
    "path": "npm_modules/cli/src/commands/lint.ts",
    "content": "import type { Argv } from 'yargs';\n\nexport const command = 'lint <command>';\nexport const describe = 'Checks and formats the code';\nexport const builder = (yargs: Argv) => {\n  return yargs\n    .commandDir('lint_commands', {\n      extensions: ['js', 'ts'],\n    })\n    .demandCommand(1, 'Use \"check\" or \"format\" to execute prettier')\n    .recommendCommands()\n    .wrap(yargs.terminalWidth())\n    .help();\n};\nexport const handler = () => {};\n"
  },
  {
    "path": "npm_modules/cli/src/commands/lint_commands/lintCheck.ts",
    "content": "import type { Argv } from 'yargs';\nimport { ANSI_COLORS } from '../../core/constants';\nimport type { ArgumentsResolver } from '../../utils/ArgumentsResolver';\nimport { makeCommandHandler } from '../../utils/errorUtils';\nimport type { FileLintStatus } from '../../utils/lintUtils';\nimport {\n  checkAndFormatFiles,\n  getPrettierConfig,\n  maybeSetupEslint,\n  maybeSetupPrettier,\n  printStatus,\n} from '../../utils/lintUtils';\nimport { wrapInColor } from '../../utils/logUtils';\n\ninterface CommandParameters {\n  files: string[] | undefined;\n  showSkipped: boolean;\n}\n\nasync function lintCheck(argv: ArgumentsResolver<CommandParameters>) {\n  const configPath = await maybeSetupPrettier();\n  const prettierConfig = await getPrettierConfig(configPath);\n  await maybeSetupEslint();\n\n  console.log(`Using config at: ${wrapInColor(configPath, ANSI_COLORS.GREEN_COLOR)}\\n`);\n\n  const filePaths = argv.getArgument('files');\n\n  if (filePaths === undefined || prettierConfig === null) {\n    return;\n  }\n\n  const results: FileLintStatus[] = await checkAndFormatFiles(filePaths, prettierConfig);\n\n  // Output list of files and their status\n  printStatus(results, argv.getArgument('showSkipped'));\n\n  // TODO (yhuang6): Implement the following\n  // Default checks changed files based on git\n  // Default checks the current directory otherwise\n}\n\nexport const command = 'check [files..]';\nexport const describe = 'Checks the file formatting and lint rules';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs.option('show-skipped', {\n    describe: 'Shows files skipped during linting (e.g. no format parsers)',\n    type: 'boolean',\n    alias: 's',\n    default: false,\n  });\n};\nexport const handler = makeCommandHandler(lintCheck);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/lint_commands/lintFormat.ts",
    "content": "import type { Argv } from 'yargs';\nimport { ANSI_COLORS } from '../../core/constants';\nimport type { ArgumentsResolver } from '../../utils/ArgumentsResolver';\nimport { makeCommandHandler } from '../../utils/errorUtils';\nimport type { FileLintStatus } from '../../utils/lintUtils';\nimport {\n  checkAndFormatFiles,\n  getPrettierConfig,\n  maybeSetupEslint,\n  maybeSetupPrettier,\n  printStatus,\n} from '../../utils/lintUtils';\nimport { wrapInColor } from '../../utils/logUtils';\n\ninterface CommandParameters {\n  files: [string] | undefined;\n  showSkipped: boolean;\n}\n\nasync function lintFormat(argv: ArgumentsResolver<CommandParameters>) {\n  const configPath = await maybeSetupPrettier();\n  const prettierConfig = await getPrettierConfig(configPath);\n  await maybeSetupEslint();\n\n  console.log(`Using config at: ${wrapInColor(configPath, ANSI_COLORS.GREEN_COLOR)}\\n`);\n\n  const filePaths = argv.getArgument('files');\n\n  if (filePaths === undefined || prettierConfig === null) {\n    return;\n  }\n\n  const results: FileLintStatus[] = await checkAndFormatFiles(filePaths, prettierConfig, true);\n\n  // Output list of files and their status\n  printStatus(results, argv.getArgument('showSkipped'));\n}\n\nexport const command = 'format [files..]';\nexport const describe = 'Apply prettier formatting to files';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs.option('show-skipped', {\n    describe: 'Shows files skipped during linting (e.g. no format parsers)',\n    type: 'boolean',\n    alias: 's',\n    default: false,\n  });\n};\nexport const handler = makeCommandHandler(lintFormat);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/log.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport { CliError } from '../core/errors';\nimport { getUserChoice } from '../utils/cliUtils';\nimport { makeCommandHandler } from '../utils/errorUtils';\nimport * as fileUtils from '../utils/fileUtils';\n\nfunction readAndWatchFile(filePath: string) {\n  filePath = fileUtils.resolveFilePath(filePath);\n\n  let fileSize = 0;\n  let isWatching = false;\n  const abortController = new AbortController();\n\n  const readInitialContent = () => {\n    const fileStream = fs.createReadStream(filePath, { encoding: 'utf8', start: 0 });\n\n    fileStream.on('data', chunk => {\n      process.stdout.write(chunk);\n    });\n\n    fileStream.on('end', () => {\n      fileSize = fs.statSync(filePath).size;\n\n      if (!isWatching) {\n        startWatching();\n      }\n    });\n  };\n\n  const startWatching = () => {\n    isWatching = true;\n    fs.watch(filePath, { signal: abortController.signal }, eventType => {\n      if (eventType === 'change') {\n        const newFileSize = fs.statSync(filePath).size;\n        if (newFileSize > fileSize) {\n          const readStream = fs.createReadStream(filePath, { encoding: 'utf8', start: fileSize });\n          readStream.on('data', chunk => {\n            process.stdout.write(chunk);\n          });\n          fileSize = newFileSize;\n        }\n      } else if (eventType === 'rename') {\n        isWatching = false;\n        if (fs.existsSync(filePath)) {\n          // When files is written, sometimes the first reported event\n          // occurs when the write is incomplete, so verifying the file exists\n          // before reading and restarting the watch\n          readInitialContent();\n        }\n      }\n    });\n  };\n\n  readInitialContent();\n\n  // Liten for (Ctrl+D) to exit as otherwise it would not do anything\n  process.stdin.on('end', () => {\n    abortController.abort();\n  });\n\n  // Keep the process running\n  process.stdin.resume();\n}\n\nasync function showValdiLogs() {\n  const userConfig = fileUtils.getUserConfig();\n\n  if (userConfig.logs_output_dir === undefined) {\n    throw new CliError(\"Missing 'logs_output_dir' config value in config.yaml\");\n  }\n\n  const allFilePaths = fileUtils.getFilesSortedByUpdatedTime(userConfig.logs_output_dir).filter(path => {\n    return path.endsWith('.log');\n  });\n\n  if (allFilePaths.length <= 0) {\n    throw new CliError(\n      'No logs available. Please start up hot reloader and the app first to make sure there are logs available',\n    );\n  }\n\n  let logPath = '';\n\n  if (allFilePaths.length === 1) {\n    logPath = allFilePaths[0] as string;\n  } else {\n    const choices = allFilePaths.map((filePath, index) => ({\n      name: `${index + 1}. ${path.basename(filePath)}`,\n      value: filePath,\n    }));\n\n    logPath = await getUserChoice(\n      choices,\n      'Please select the log file to use (this list is ordered by modification time, the most updated log will be displayed first):',\n    );\n\n    console.log(logPath);\n  }\n\n  // Read and show log file content\n  readAndWatchFile(logPath);\n}\n\nexport const command = 'log';\nexport const describe = 'Streams Valdi logs from the connected device to console';\nexport const builder = () => {};\nexport const handler = makeCommandHandler(showValdiLogs);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/newModule.ts",
    "content": "import fs from 'fs';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport type { Argv } from 'yargs';\nimport { ANSI_COLORS, BOOTSTRAP_DIR_PATH } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport type { CliChoice } from '../utils/cliUtils';\nimport { getUserChoice } from '../utils/cliUtils';\nimport { copyBootstrapFiles } from '../utils/copyBootstrapFiles';\nimport { makeCommandHandler } from '../utils/errorUtils';\nimport type { Replacements } from '../utils/fileUtils';\nimport { fileExists } from '../utils/fileUtils';\nimport { wrapInColor } from '../utils/logUtils';\nimport { toPascalCase, toSnakeCase, sanitizeProjectName, validateProjectName } from '../utils/stringUtils';\n\nconst referenceString = `\n******************************************\n        Valdi Module Creation Guide\n******************************************\n\nRequirements for Valdi module names:\n- May contain: A-Z, a-z, 0-9, '-', '_', '.'\n- Must start with a letter.\n\nRecommended Directory Structure:\nmy_application/          # Root directory of your application\n├── WORKSPACE            # Bazel Workspace\n├── BUILD.bazel          # Bazel build\n└── modules/\n    ├── module_a/\n    │   ├── BUILD.bazel\n    │   ├── android/     # Native Android sources (Kotlin)\n    │   ├── ios/         # Native iOS sources (Objective-C)\n    │   ├── macos/       # Native macOS sources (Objective-C)\n    │   ├── web/         # Web sources (TypeScript, compiled by tsc)\n    │   └── src/         # Valdi sources\n    │       └── ModuleAComponent.tsx\n    ├── module_b/\n        ├── BUILD.bazel\n    │   ├── res/         # Image and font resources\n    │   ├── strings/     # Localizable strings\n        └── src/\n            └── ModuleBComponent.tsx\n\nFor more comprehensive details, refer to the core-module documentation:\nhttps://github.com/Snapchat/Valdi/blob/main/docs/docs/core-module.md\n\n******************************************\n`;\n\nconst ALL_MODULE_TEMPLATES: readonly ModuleTemplate[] = [\n  {\n    name: 'UI Component',\n    path: 'ui_component',\n    description: `Exports a Valdi component, which can render UI elements`,\n  },\n  {\n    name: 'Polyglot Bridge module',\n    path: 'polyglot_bridge_module',\n    description: `Bridge module with a TypeScript API backed by Kotlin (Android), Objective-C (iOS), and TypeScript (Web/macOS)`,\n  },\n  {\n    name: 'Polyglot View module',\n    path: 'polyglot_view_module',\n    description: `Native view with <custom-view> implementations for all platforms: Android, iOS, macOS, and Web`,\n  },\n];\n\ninterface CommandParameters {\n  debug: boolean;\n  skipChecks: boolean;\n  moduleName: string;\n  template?: string\n}\n\ninterface Checks {\n  confirmBazelWorkspace?: boolean;\n  confirmValdiPath?: boolean;\n  valdiModulePath?: string;\n}\n\ninterface ModuleTemplate {\n  name: string;\n  path: string;\n  description: string;\n}\n\nasync function promptChecks(): Promise<Checks> {\n  let answers: Checks = {};\n\n  /**\n   * Verify Bazel Workspace\n   */\n  const bazelWorkspacePath = await getBazelWorkspaceRoot();\n\n  answers = await inquirer.prompt<Checks>(\n    [\n      {\n        type: 'confirm',\n        name: 'confirmBazelWorkspace',\n        message: 'Bazel WORKSPACE not found (did you run `valdi bootstrap` first?). Continue anyway?',\n        default: true,\n        when() {\n          return !bazelWorkspacePath;\n        },\n      },\n    ],\n    answers,\n  );\n\n  if (!bazelWorkspacePath && !answers.confirmBazelWorkspace) {\n    throw new CliError('Aborting.');\n  }\n\n  /**\n   * Verify directory structure\n   */\n  answers = await inquirer.prompt<Checks>(\n    {\n      type: 'confirm',\n      name: 'confirmValdiPath',\n      message:\n        '/modules directory not found (did you run `valdi bootstrap` first?). Create module in current directory?',\n      default: true,\n      when(answers) {\n        const curDir = process.cwd();\n        const parsedPath = path.parse(curDir);\n        if (parsedPath.base === 'modules') {\n          // Create the new module in the current directory\n          answers.valdiModulePath = curDir;\n        } else if (curDir === bazelWorkspacePath) {\n          // Create the new module in ./modules\n          const valdiPath = path.join(curDir, 'modules');\n          if (fs.existsSync(valdiPath)) {\n            answers.valdiModulePath = valdiPath;\n          }\n        }\n\n        return !answers.valdiModulePath;\n      },\n    },\n    answers,\n  );\n\n  if (!answers.valdiModulePath && !answers.confirmValdiPath) {\n    throw new CliError('Aborting.');\n  }\n\n  return answers;\n}\n\nasync function getModuleName(argv: ArgumentsResolver<CommandParameters>): Promise<string> {\n  return argv.getArgumentOrResolve('moduleName', async () => {\n    const result = await inquirer.prompt<{ moduleName?: string }>(\n      [\n        {\n          type: 'input',\n          name: 'moduleName',\n          message: 'Please provide a name for this module:',\n          validate: (input: string) => {\n            const validationError = validateProjectName(input);\n            if (validationError) {\n              return validationError;\n            }\n\n            const sanitized = sanitizeProjectName(input);\n            const destPath = path.join(process.cwd(), sanitized);\n            if (fileExists(destPath)) {\n              return `Path ${destPath} already exists. Choose a different name or delete the folder and try again.`;\n            }\n\n            return true;\n          },\n        },\n      ],\n      {},\n    );\n\n    return sanitizeProjectName(result.moduleName ?? '');\n  });\n}\n\nasync function finalConfirmation(destPath: string, argv: ArgumentsResolver<CommandParameters>): Promise<boolean> {\n  return argv.getArgumentOrResolve('skipChecks', async () => {\n    const confirmMessage = `\nCreate module?\n  Path:               ${wrapInColor(destPath, ANSI_COLORS.GREEN_COLOR)}\n`;\n    const answers = await inquirer.prompt<{ confirm?: boolean }>(\n      [\n        {\n          type: 'confirm',\n          name: 'confirm',\n          message: confirmMessage,\n          default: true,\n        },\n      ],\n      {},\n    );\n\n    return answers.confirm ?? false;\n  });\n}\n\nfunction getBazelWorkspaceRoot() {\n  return new BazelClient().getWorkspaceRoot();\n}\n\nasync function valdiNewModule(argv: ArgumentsResolver<CommandParameters>) {\n  console.log(referenceString);\n  const skipChecks = argv.getArgument('skipChecks');\n\n  const checks: Checks = skipChecks ? {} : await promptChecks();\n  const valdiModulePath = checks.valdiModulePath ?? path.join(await getBazelWorkspaceRoot(), 'modules');\n\n  let moduleName = await getModuleName(argv);\n  \n  // Validate module name if provided via command line argument\n  if (argv.getArgument('moduleName')) {\n    const validationError = validateProjectName(moduleName);\n    if (validationError) {\n      throw new CliError(validationError);\n    }\n    moduleName = sanitizeProjectName(moduleName);\n  }\n\n  const destPath = path.join(valdiModulePath, moduleName);\n  const didConfirm = skipChecks || (await finalConfirmation(destPath, argv));\n  if (!didConfirm) {\n    throw new CliError('Cancelled new module creation.');\n  }\n\n  /**\n   * Do not overwrite existing files\n   */\n  if (fs.existsSync(destPath)) {\n    throw new CliError(`Path already exists ${destPath}`);\n  }\n\n  const choices: CliChoice<ModuleTemplate>[] = ALL_MODULE_TEMPLATES.map(target => ({\n    name: `${wrapInColor(target.name, ANSI_COLORS.GREEN_COLOR)} . ${target.description}`,\n    value: target,\n  }));\n\n  const templateOption = argv.getArgument('template');\n  const template = templateOption ? ALL_MODULE_TEMPLATES.find(template => template.path === templateOption) : undefined;\n  const moduleTemplate = template ?? await getUserChoice(choices, `Please choose the module type:`);\n\n  /**\n   * Copy bootstrap files\n   */\n  const sourcePath = path.join(BOOTSTRAP_DIR_PATH, 'modules', moduleTemplate.path);\n  const replacements: Replacements = {\n    MODULE_NAME: moduleName,\n    MODULE_NAME_PASCAL_CASED: toPascalCase(moduleName),\n  };\n\n  copyBootstrapFiles(sourcePath, destPath, replacements);\n\n  // Finalize message\n  console.log(`Success! New module directory: ${wrapInColor(destPath, ANSI_COLORS.GREEN_COLOR)}`);\n}\n\nexport const command = `new_module [module-name]`;\nexport const describe = referenceString;\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs\n    .positional('module-name', {\n      describe: 'Name of the Valdi module.',\n    })\n    .option('template', {\n      describe: 'module template to use, will skip the prompt',\n      choices: ALL_MODULE_TEMPLATES.map(template => template.path),\n    })\n    .option('skip-checks', {\n      describe: 'Skips confirmation prompts.',\n      type: 'boolean',\n    });\n};\nexport const handler = makeCommandHandler(valdiNewModule);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/package.ts",
    "content": "import * as fs from 'fs';\nimport path from 'path';\nimport type { Argv } from 'yargs';\nimport type { PLATFORM } from '../core/constants';\nimport { ALL_ARCHITECTURES, ANSI_COLORS } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport type { SharedCommandParameters } from '../utils/applicationUtils';\nimport {\n  applicationExtensionForPlatform,\n  getApplicationTargetTagForPlatform,\n  getOutputFilePath,\n  makeArgsBuilder,\n  resolveBazelBuildArgs,\n  selectBazelTarget,\n} from '../utils/applicationUtils';\nimport { logReproduceThisCommandIfNeeded, makeCommandHandler } from '../utils/errorUtils';\nimport { wrapInColor } from '../utils/logUtils';\n\ninterface CommandParameters extends SharedCommandParameters {\n  application: string | undefined;\n  target_output_path: string | undefined;\n  output_path: string;\n}\n\nasync function valdiPackage(argv: ArgumentsResolver<CommandParameters>): Promise<void> {\n  const bazel = new BazelClient();\n  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n  const platform = argv.getArgument('platform') as PLATFORM;\n  const bazelArgs = resolveBazelBuildArgs(\n    platform,\n    argv.getArgument('build_config'),\n    ALL_ARCHITECTURES,\n    /* forDevice */ true,\n    argv.getArgument('enable_runtime_logs'),\n    argv.getArgument('enable_runtime_traces'),\n    argv.getArgument('bazel_args'),\n  );\n\n  const resolvedOutputPath = path.resolve(argv.getArgument('output_path'));\n  const expectedExtension = applicationExtensionForPlatform(platform);\n  if (expectedExtension.length > 0 && !resolvedOutputPath.endsWith(expectedExtension)) {\n    throw new CliError(`Output path for platform '${platform}' must have ${expectedExtension} file extension`);\n  }\n\n  if (fs.existsSync(resolvedOutputPath)) {\n    fs.rmSync(resolvedOutputPath);\n  }\n  const directoryPath = path.dirname(resolvedOutputPath);\n  if (!fs.existsSync(directoryPath)) {\n    fs.mkdirSync(directoryPath, { recursive: true });\n  }\n\n  const application = await argv.getArgumentOrResolve('application', () => {\n    console.log('No application specified querying available targets...');\n    return selectBazelTarget(\n      bazel,\n      getApplicationTargetTagForPlatform(platform),\n      'valdi_application',\n      'Please select an application target to package:',\n    );\n  });\n  console.log('Resolving output paths...');\n\n  const bazelOutputFilePath = await argv.getArgumentOrResolve('target_output_path', () => {\n    console.log('Resolving output paths...');\n    return getOutputFilePath(bazel, expectedExtension, application, bazelArgs);\n  });\n  console.log(`Building: ${wrapInColor(application, ANSI_COLORS.GREEN_COLOR)}`);\n\n  await bazel.buildTarget(application, bazelArgs);\n\n  console.log(`Copying built target to ${resolvedOutputPath}...`);\n  await fs.promises.copyFile(bazelOutputFilePath, resolvedOutputPath);\n\n  logReproduceThisCommandIfNeeded(argv);\n  console.log('All done!');\n}\n\nexport const command = 'package <platform>';\nexport const describe = 'Build and package a Valdi application';\nexport const builder = makeArgsBuilder((yargs: Argv<CommandParameters>) => {\n  yargs\n    .option('application', {\n      describe: 'Name of the application to build',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('target_output_path', {\n      describe: 'The output path for the Bazel target',\n      type: 'string',\n      requiresArg: true,\n    })\n    .option('output_path', {\n      describe: 'The path where to store the built application package',\n      type: 'string',\n      requiresArg: true,\n    })\n    .demandOption('output_path');\n});\nexport const handler = makeCommandHandler(valdiPackage);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/projectsync.ts",
    "content": "/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\nimport fsSync from 'fs';\nimport fs from 'fs/promises';\nimport type { JSONPath } from 'jsonc-parser';\nimport path from 'path';\nimport type { Argv } from 'yargs';\nimport { CliError } from '../core/errors';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient, BazelLabel } from '../utils/BazelClient';\nimport { byString } from '../utils/byString';\nimport { logReproduceThisCommandIfNeeded, makeCommandHandler } from '../utils/errorUtils';\nimport { JSONCFile } from '../utils/jsonUtils';\nimport { relativePathTo } from '../utils/pathUtils';\n\nconst VALDI_BASE_TARGET = BazelLabel.fromString('@valdi//modules:valdi_base');\nconst VALDI_CORE_TARGET = BazelLabel.fromString('@valdi//src/valdi_modules/valdi_core:valdi_core');\n\ninterface VSCodeLaunchConfiguration {\n  name: string;\n  type: string;\n  request: string;\n  websocketAddress: string;\n  sourceMapPathOverrides: { [key: string]: string };\n  sourceMaps: boolean;\n  restart: boolean;\n  resolveSourceMapLocations: unknown[];\n}\n\ninterface VSCodeLaunchInfo {\n  version?: string;\n  configurations?: VSCodeLaunchConfiguration[];\n}\n\nconst VSCODE_VALDI_LAUNCH_CONFIGURATION: VSCodeLaunchConfiguration = {\n  name: 'Valdi attach',\n  type: 'node',\n  request: 'attach',\n  websocketAddress: 'ws://localhost:13595',\n  sourceMapPathOverrides: {},\n  sourceMaps: true,\n  restart: false,\n  //This empty value is important so that vscode-js-debug just uses the inline source maps\n  resolveSourceMapLocations: [],\n};\n\nconst DEFAULT_VSCODE_LAUNCH_JSON: VSCodeLaunchInfo = {\n  version: '0.2.0',\n  configurations: [VSCODE_VALDI_LAUNCH_CONFIGURATION],\n};\n\ninterface CommandParameters {\n  target: string[] | undefined;\n  vscode_launch_path: string | undefined;\n}\n\ninterface TargetDescription {\n  label: BazelLabel;\n  paths: readonly string[];\n}\n\ninterface TsConfigMatchedTarget {\n  target: TargetDescription;\n  dependencies: TargetDescription[];\n}\n\ninterface TsConfigDir {\n  dir: string;\n  matchedTargets: TsConfigMatchedTarget[];\n}\n\ninterface BazelWorkspaceInfo {\n  workspaceName: string;\n  workspaceRoot: string;\n  executionRoot: string;\n}\n\ninterface ProjectSyncOutput {\n  target: BazelLabel;\n  dependencies: BazelLabel[];\n  tsGeneratedDir: string | undefined;\n}\n\ninterface ProjectSyncOutputJSON {\n  target: string;\n  dependencies: string[];\n  ts_generated_dir: string | undefined;\n}\n\nasync function parseProjectSyncJSON(jsonFilePath: string): Promise<ProjectSyncOutput> {\n  const jsonFilePathContent = await fs.readFile(jsonFilePath);\n  const json = JSON.parse(jsonFilePathContent.toString('utf8')) as ProjectSyncOutputJSON;\n  let tsGeneratedDir: string | undefined;\n\n  if (json.ts_generated_dir) {\n    const dir = path.dirname(jsonFilePath);\n\n    tsGeneratedDir = path.resolve(dir, json.ts_generated_dir);\n  }\n\n  return {\n    target: BazelLabel.fromString(json.target),\n    dependencies: json.dependencies.map(d => BazelLabel.fromString(d)),\n    tsGeneratedDir,\n  };\n}\n\nfunction isExternalLabel(workspaceInfo: BazelWorkspaceInfo, label: BazelLabel): boolean {\n  return !!label.repo && label.repo !== workspaceInfo.workspaceName;\n}\n\nfunction getSymlinkedBazelExecutionRoot(workspaceInfo: BazelWorkspaceInfo): string {\n  return path.join(workspaceInfo.workspaceRoot, `bazel-${workspaceInfo.workspaceName}`);\n}\n\nfunction bazelLabelToAbsolutePath(workspaceInfo: BazelWorkspaceInfo, label: BazelLabel): string {\n  const targetPath = label.target.slice(2);\n  if (isExternalLabel(workspaceInfo, label)) {\n    return path.join(getSymlinkedBazelExecutionRoot(workspaceInfo), 'external', label.repo!, targetPath);\n  } else {\n    return path.join(workspaceInfo.workspaceRoot, targetPath);\n  }\n}\n\nasync function buildProjectSyncs(bazel: BazelClient, workspaceRoot: string, projectSyncTargets: readonly string[]) {\n  await bazel.buildTargets(projectSyncTargets);\n  const buildOutputs = await bazel.queryBuildOutputs(projectSyncTargets);\n  const filteredBuildOutputs = buildOutputs.filter(c => c.endsWith('/projectsync.json')).sort(byString(v => v));\n\n  return await Promise.all(filteredBuildOutputs.map(b => parseProjectSyncJSON(path.resolve(workspaceRoot, b))));\n}\n\nasync function syncPathsByLabel(\n  client: BazelClient,\n  workspaceInfo: BazelWorkspaceInfo,\n  pathsByLabel: Map<string, string[]>,\n  projectSyncOutputs: readonly ProjectSyncOutput[],\n) {\n  for (const projectSyncOutput of projectSyncOutputs) {\n    const paths: string[] = [];\n    paths.push(bazelLabelToAbsolutePath(workspaceInfo, projectSyncOutput.target));\n\n    if (projectSyncOutput.tsGeneratedDir) {\n      paths.push(projectSyncOutput.tsGeneratedDir);\n    }\n\n    pathsByLabel.set(projectSyncOutput.target.toString(), paths);\n  }\n\n  // TODO(simon): Refactor projectsync bzl rule so that it recursively resolves\n  // all of these without us having to take care of it.\n  const missingTargets = new Set<string>();\n\n  for (const projectSyncOutput of projectSyncOutputs) {\n    for (const dependency of projectSyncOutput.dependencies) {\n      const target = dependency.toString();\n      if (!pathsByLabel.has(target)) {\n        missingTargets.add(target);\n      }\n    }\n  }\n\n  if (missingTargets.size > 0) {\n    const targets = [...missingTargets.values()].sort().map(f => `${f}_projectsync`);\n    const newProjectSyncOutputs = await buildProjectSyncs(client, workspaceInfo.workspaceRoot, targets);\n    await syncPathsByLabel(client, workspaceInfo, pathsByLabel, newProjectSyncOutputs);\n  }\n}\n\nasync function collectTsConfigDirs(\n  bazel: BazelClient,\n  workspaceInfo: BazelWorkspaceInfo,\n  projectSyncOutputs: readonly ProjectSyncOutput[],\n): Promise<TsConfigDir[]> {\n  const pathsByLabel = new Map<string, string[]>();\n\n  await syncPathsByLabel(bazel, workspaceInfo, pathsByLabel, projectSyncOutputs);\n\n  const makeTargetDescription = (label: BazelLabel): TargetDescription => {\n    const target = label.toString();\n    const paths = pathsByLabel.get(target);\n\n    if (!paths) {\n      throw new CliError(`Could not resolve TypeScript import paths for target ${target}`);\n    }\n    return {\n      label,\n      paths,\n    };\n  };\n\n  const tsConfigDirs = new Map<string, TsConfigDir>();\n\n  for (const projectSyncOutput of projectSyncOutputs) {\n    if (projectSyncOutput.target.repo) {\n      // Ignore external repo deps\n      continue;\n    }\n\n    const tsConfigDirPath = bazelLabelToAbsolutePath(workspaceInfo, projectSyncOutput.target);\n    let tsConfigDir = tsConfigDirs.get(tsConfigDirPath);\n    if (!tsConfigDir) {\n      tsConfigDir = { dir: tsConfigDirPath, matchedTargets: [] };\n      tsConfigDirs.set(tsConfigDirPath, tsConfigDir);\n    }\n\n    const dependencies = projectSyncOutput.dependencies.map(d => makeTargetDescription(d));\n\n    tsConfigDir.matchedTargets.push({\n      target: makeTargetDescription(projectSyncOutput.target),\n      dependencies: dependencies,\n    });\n  }\n\n  return [...tsConfigDirs.values()].sort(byString(v => v.dir));\n}\n\nfunction removeTsFileExtension(path: string): string {\n  if (path.endsWith('.d.ts')) {\n    return path.slice(0, -5);\n  } else if (path.endsWith('.ts')) {\n    return path.slice(0, -3);\n  }\n  return path;\n}\n\nfunction computeTsCompilerOptions(\n  existingTsConfigFile: any,\n  tsConfigDir: string,\n  matchedTargets: readonly TsConfigMatchedTarget[],\n  baseTsFiles: readonly string[],\n): unknown {\n  let compilerOptions: any;\n  if (existingTsConfigFile) {\n    compilerOptions = { ...existingTsConfigFile };\n  } else {\n    compilerOptions = {};\n  }\n\n  compilerOptions.paths = {};\n  const rootDirs: string[] = [];\n  let valdiCoreTarget: TargetDescription | undefined;\n  for (const matchedTarget of matchedTargets) {\n    const targetRootDirs = matchedTarget.target.paths.map(p => relativePathTo(tsConfigDir, path.dirname(p)));\n\n    for (const targetRootDir of targetRootDirs) {\n      if (!rootDirs.includes(targetRootDir)) {\n        rootDirs.push(targetRootDir);\n      }\n    }\n\n    const selfName = matchedTarget.target.label.name ?? '';\n    const selfInclude = `${selfName}/*`;\n\n    const selfImportPaths = matchedTarget.target.paths.map(p => `${relativePathTo(tsConfigDir, p)}/*`);\n\n    compilerOptions.paths[selfInclude] = selfImportPaths;\n\n    for (const dependency of matchedTarget.dependencies) {\n      if (!dependency.label.name || compilerOptions.paths[dependency.label.name]) {\n        // Already present\n        continue;\n      }\n\n      if (dependency.label.name === 'valdi_core') {\n        valdiCoreTarget = dependency;\n      }\n\n      const importPaths = dependency.paths.map(p => `${relativePathTo(tsConfigDir, p)}/*`);\n\n      const key = `${dependency.label.name}/*`;\n      compilerOptions.paths[key] = importPaths;\n    }\n  }\n\n  if (valdiCoreTarget) {\n    // Add tslib dep\n    compilerOptions.paths['tslib'] = valdiCoreTarget.paths.map(p =>\n      relativePathTo(tsConfigDir, path.join(p, 'src/tslib')),\n    );\n  }\n\n  compilerOptions.types = baseTsFiles.map(p => relativePathTo(tsConfigDir, removeTsFileExtension(p)));\n\n  compilerOptions.rootDirs = rootDirs;\n\n  return compilerOptions;\n}\n\nfunction getBaseTsConfigFile(valdiBaseAbsoluteFilePaths: string[]): string | undefined {\n  return valdiBaseAbsoluteFilePaths.find(p => path.basename(p) === 'base.tsconfig.json');\n}\n\nfunction updateTsConfigFile(file: JSONCFile<any>, path: JSONPath, value: any): JSONCFile<any> {\n  return file.updating(path, value, {\n    formattingOptions: {\n      insertSpaces: true,\n    },\n  });\n}\n\nasync function processTsConfigDir(\n  tsConfigDir: TsConfigDir,\n  baseTsConfigFilePath: string | undefined,\n  baseTsFiles: readonly string[],\n): Promise<void> {\n  const tsConfigPath = path.join(tsConfigDir.dir, 'tsconfig.json');\n\n  let tsConfigFile: JSONCFile<any>;\n  if (fsSync.existsSync(tsConfigPath)) {\n    const fileContent = await fs.readFile(tsConfigPath);\n    tsConfigFile = JSONCFile.parse(fileContent.toString('utf8'));\n  } else {\n    tsConfigFile = JSONCFile.fromObject({});\n  }\n\n  const tsCompilerOptions = computeTsCompilerOptions(\n    tsConfigFile?.value?.compilerOptions,\n    tsConfigDir.dir,\n    tsConfigDir.matchedTargets,\n    baseTsFiles,\n  );\n\n  if (baseTsConfigFilePath) {\n    const resolvedBaseTsConfigFilePath = relativePathTo(tsConfigDir.dir, baseTsConfigFilePath);\n    if (tsConfigFile?.value?.extends !== resolvedBaseTsConfigFilePath) {\n      tsConfigFile = updateTsConfigFile(tsConfigFile, ['extends'], resolvedBaseTsConfigFilePath);\n    }\n  }\n\n  tsConfigFile = updateTsConfigFile(tsConfigFile, ['compilerOptions'], tsCompilerOptions);\n\n  await fs.writeFile(tsConfigPath, tsConfigFile.toJSONString());\n}\n\nfunction computeSourceMapPathOverrides(\n  bazelWorkspaceRoot: string,\n  tsConfigDirs: readonly TsConfigDir[],\n): { [key: string]: string } {\n  const output: { [key: string]: string } = {};\n\n  for (const tsConfigDir of tsConfigDirs) {\n    for (const matchedTarget of tsConfigDir.matchedTargets) {\n      if (matchedTarget.target.label.name) {\n        const key = `/${matchedTarget.target.label.name}/*`;\n        const relativePath = relativePathTo(bazelWorkspaceRoot, tsConfigDir.dir);\n        const expected = `\\${workspaceRoot}/${relativePath}/*`;\n\n        const existing = output[key];\n        if (existing && existing !== expected) {\n          console.error(`Conflicting target name ${matchedTarget.target.label.name}: '${expected}' vs ${existing}`);\n        } else {\n          output[key] = expected;\n        }\n      }\n    }\n  }\n\n  return output;\n}\n\nasync function processLaunchJSONFile(\n  launchJsonFilePath: string | undefined,\n  bazel: BazelClient,\n  tsConfigDirs: readonly TsConfigDir[],\n): Promise<void> {\n  const workspaceRoot = await bazel.getWorkspaceRoot();\n  if (!launchJsonFilePath) {\n    launchJsonFilePath = path.join(workspaceRoot, '.vscode/launch.json');\n  }\n\n  let launchJsonFile: JSONCFile<VSCodeLaunchInfo>;\n  if (fsSync.existsSync(launchJsonFilePath)) {\n    const launchJsonFileContent = await fs.readFile(launchJsonFilePath, 'utf8');\n    launchJsonFile = JSONCFile.parse(launchJsonFileContent);\n  } else {\n    launchJsonFile = JSONCFile.fromObject(DEFAULT_VSCODE_LAUNCH_JSON);\n  }\n\n  const valdiLaunchConfigurationIndex =\n    launchJsonFile.value.configurations?.findIndex(c => c.name === VSCODE_VALDI_LAUNCH_CONFIGURATION.name) ?? -1;\n  let valdiLaunchConfiguration =\n    valdiLaunchConfigurationIndex >= 0\n      ? launchJsonFile.value.configurations![valdiLaunchConfigurationIndex]!\n      : VSCODE_VALDI_LAUNCH_CONFIGURATION;\n  valdiLaunchConfiguration = { ...valdiLaunchConfiguration };\n  valdiLaunchConfiguration.sourceMapPathOverrides = computeSourceMapPathOverrides(workspaceRoot, tsConfigDirs);\n\n  if (valdiLaunchConfigurationIndex >= 0) {\n    launchJsonFile = launchJsonFile.updating(\n      ['configurations', valdiLaunchConfigurationIndex],\n      valdiLaunchConfiguration,\n      {\n        formattingOptions: { insertSpaces: true },\n      },\n    );\n  } else if (launchJsonFile.value.configurations) {\n    launchJsonFile = launchJsonFile.updating(\n      ['configurations', launchJsonFile.value.configurations.length],\n      valdiLaunchConfiguration,\n      {\n        formattingOptions: { insertSpaces: true },\n        isArrayInsertion: true,\n      },\n    );\n  } else {\n    launchJsonFile = launchJsonFile.updating(['configurations'], [valdiLaunchConfiguration], {\n      formattingOptions: { insertSpaces: true },\n    });\n  }\n\n  const launchJsonFileDir = path.dirname(launchJsonFilePath);\n  if (!fsSync.existsSync(launchJsonFileDir)) {\n    await fs.mkdir(launchJsonFileDir, { recursive: true });\n  }\n  await fs.writeFile(launchJsonFilePath, launchJsonFile.toJSONString());\n}\n\nexport async function getAllProjectSyncTargets(bazel: BazelClient): Promise<string[]> {\n  console.log('Searching for Valdi targets in current workspace...');\n  return await bazel.query(`kind('valdi_projectsync', //...)`);\n}\n\nexport async function runProjectSync(\n  bazel: BazelClient,\n  inputTargets: string[],\n  vscodeLaunchPath: string | undefined,\n  generateLaunchJSONFile: boolean,\n): Promise<void> {\n  console.log('Resolving dependencies of resolved Valdi targets...');\n  const workspaceRoot = await bazel.getWorkspaceRoot();\n  const executionRoot = await bazel.getExecutionRoot();\n\n  const allProjectSyncOutputs = await buildProjectSyncs(bazel, workspaceRoot, inputTargets);\n\n  console.log('Generating tsconfig.json files...');\n\n  const workspaceName = path.basename(executionRoot);\n  const workspaceInfo: BazelWorkspaceInfo = { workspaceName, workspaceRoot, executionRoot };\n\n  const valdiBaseRelativeFilePaths = await bazel.queryBuildOutputs([VALDI_BASE_TARGET.toString()]);\n  const valdiBaseAbsoluteFilePaths = valdiBaseRelativeFilePaths.map(v => {\n    if (isExternalLabel(workspaceInfo, VALDI_BASE_TARGET)) {\n      return path.resolve(getSymlinkedBazelExecutionRoot(workspaceInfo), v);\n    } else {\n      return path.resolve(workspaceRoot, v);\n    }\n  });\n  const baseTsConfigFilePath = getBaseTsConfigFile(valdiBaseAbsoluteFilePaths);\n  const baseTsFiles = valdiBaseAbsoluteFilePaths.filter(v => v.endsWith('.ts'));\n\n  const tsConfigDirs = await collectTsConfigDirs(bazel, workspaceInfo, allProjectSyncOutputs);\n\n  await Promise.all(tsConfigDirs.map(v => processTsConfigDir(v, baseTsConfigFilePath, baseTsFiles)));\n\n  if (generateLaunchJSONFile) {\n    console.log('Generating VSCode launch.json file...');\n    await processLaunchJSONFile(vscodeLaunchPath, bazel, tsConfigDirs);\n  }\n}\n\nasync function projectSync(args: ArgumentsResolver<CommandParameters>): Promise<void> {\n  const bazel = new BazelClient();\n  const inputTargets = await args.getArgumentOrResolve('target', () => getAllProjectSyncTargets(bazel));\n  await runProjectSync(bazel, inputTargets, args.getArgument('vscode_launch_path'), true);\n\n  logReproduceThisCommandIfNeeded(args);\n}\n\nexport const command = 'projectsync [--target target]';\nexport const describe = 'Synchronize VSCode project for the given targets';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs.option('target', {\n    describe: 'targets for which to synchronize the VSCode project for',\n    type: 'string',\n    array: true,\n    requiresArg: false,\n  });\n  yargs.option('vscode_launch_path', {\n    describe:\n      'A the path to there launch.json file used by VSCode. Will be inferred as .vscode/launch.json from the Bazel workspace root if not specified',\n    type: 'string',\n  });\n};\n\nexport const handler = makeCommandHandler(projectSync);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/skills.ts",
    "content": "import type { Argv } from 'yargs';\n\nexport const command = 'skills <command>';\nexport const describe = 'Manage AI assistant skills for Valdi development';\nexport const builder = (yargs: Argv) => {\n  return yargs\n    .commandDir('skills_commands', { extensions: ['js', 'ts'] })\n    .demandCommand(1, 'Use list, install, update, remove, or add')\n    .recommendCommands()\n    .wrap(yargs.terminalWidth())\n    .help();\n};\nexport const handler = () => {};\n"
  },
  {
    "path": "npm_modules/cli/src/commands/skills_commands/create.ts",
    "content": "import type { Argv } from 'yargs';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport inquirer from 'inquirer';\nimport { makeCommandHandler } from '../../utils/errorUtils';\nimport type { ArgumentsResolver } from '../../utils/ArgumentsResolver';\nimport type { SkillRegistry, SkillMeta } from '../../utils/skillsRegistry';\nimport { ANSI_COLORS, META_DIR_PATH } from '../../core/constants';\nimport { wrapInColor } from '../../utils/logUtils';\n\n// ─── Template loading ────────────────────────────────────────────────────────\n\nfunction loadTemplate(filename: string, replacements: Record<string, string>): string {\n  const raw = fs.readFileSync(path.join(META_DIR_PATH, filename), 'utf8');\n  return Object.entries(replacements).reduce(\n    (content, [key, value]) => content.replaceAll(key, value),\n    raw,\n  );\n}\n\nfunction toIosModuleName(skillName: string): string {\n  const pascal = skillName\n    .split('-')\n    .map((w: string) => w.charAt(0).toUpperCase() + w.slice(1))\n    .join('');\n  return `SCCValdi${pascal}Ref`;\n}\n\n// ─── Valdi root detection ────────────────────────────────────────────────────\n\nfunction findValdiRoot(dir: string): string | null {\n  let current = path.resolve(dir);\n  while (true) {\n    if (fs.existsSync(path.join(current, 'ai-skills', 'registry.json'))) {\n      return current;\n    }\n    const parent = path.dirname(current);\n    if (parent === current) return null; // filesystem root\n    current = parent;\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\ninterface CommandParameters {}\n\nasync function skillsCreate(_argv: ArgumentsResolver<CommandParameters>) {\n  const valdiRoot = findValdiRoot(process.cwd());\n  if (valdiRoot == null) {\n    console.log(\n      wrapInColor(\n        'Not inside a Valdi framework checkout. Run this command from within the Valdi repo.',\n        ANSI_COLORS.RED_COLOR,\n      ),\n    );\n    console.log('Expected to find ai-skills/registry.json in the current directory or a parent.');\n    return;\n  }\n\n  const skillsDir = path.join(valdiRoot, 'ai-skills', 'skills');\n  const registryPath = path.join(valdiRoot, 'ai-skills', 'registry.json');\n\n  console.log(wrapInColor(`Valdi root: ${valdiRoot}\\n`, ANSI_COLORS.GRAY_COLOR));\n  console.log(wrapInColor('Create a new Valdi skill\\n', ANSI_COLORS.BLUE_COLOR));\n\n  const answers = await inquirer.prompt<{\n    name: string;\n    description: string;\n    category: ('framework' | 'client')[];\n    tags: string;\n  }>([\n    {\n      type: 'input',\n      name: 'name',\n      message: 'Skill name (e.g. valdi-animations):',\n      validate: (input: string) => {\n        if (!input.trim()) return 'Name is required';\n        if (!/^[\\w-]+$/u.test(input.trim())) return 'Name must be alphanumeric with hyphens only';\n        const existing = fs.existsSync(path.join(skillsDir, input.trim()));\n        if (existing) return `Skill \"${input.trim()}\" already exists`;\n        return true;\n      },\n      filter: (input: string) => input.trim(),\n    },\n    {\n      type: 'input',\n      name: 'description',\n      message: 'Short description (one sentence):',\n      validate: (input: string) => (input.trim() ? true : 'Description is required'),\n      filter: (input: string) => input.trim(),\n    },\n    {\n      type: 'checkbox',\n      name: 'category',\n      message: 'Category (select all that apply):',\n      choices: [\n        { name: 'client  — creating / updating / testing Valdi modules', value: 'client', checked: true },\n        { name: 'framework — working on the Valdi repo itself', value: 'framework' },\n      ],\n      validate: (input: string[]) => (input.length > 0 ? true : 'Select at least one category'),\n    },\n    {\n      type: 'input',\n      name: 'tags',\n      message: 'Tags (comma-separated, e.g. tsx,components):',\n      filter: (input: string) =>\n        input\n          .split(',')\n          .map((t) => t.trim())\n          .filter(Boolean)\n          .join(','),\n    },\n  ]);\n\n  const { name, description, category, tags } = answers;\n  const tagList = tags ? tags.split(',') : [];\n\n  const skillDir = path.join(skillsDir, name);\n  const skillFile = path.join(skillDir, 'skill.md');\n  const skillPath = `skills/${name}/skill.md`;\n  const testsDir = path.join(skillDir, 'tests');\n  const testsSrcDir = path.join(testsDir, 'src');\n\n  // Create skill.md from template\n  fs.mkdirSync(skillDir, { recursive: true });\n  fs.writeFileSync(\n    skillFile,\n    loadTemplate('skill.md.template', { SKILL_NAME: name, SKILL_DESCRIPTION: description }),\n    'utf8',\n  );\n\n  // Scaffold tests/ directory from templates\n  fs.mkdirSync(testsSrcDir, { recursive: true });\n  fs.writeFileSync(\n    path.join(testsSrcDir, 'reference.tsx'),\n    loadTemplate('skill-reference.tsx.template', { SKILL_NAME: name }),\n    'utf8',\n  );\n  fs.writeFileSync(\n    path.join(testsDir, 'BUILD.bazel'),\n    loadTemplate('skill-tests-BUILD.bazel.template', {\n      SKILL_NAME: name,\n      SKILL_IOS_MODULE_NAME: toIosModuleName(name),\n    }),\n    'utf8',\n  );\n  fs.writeFileSync(\n    path.join(testsDir, 'tsconfig.json'),\n    '{\"extends\": \"../../../../src/valdi_modules/src/valdi/_configs/base.tsconfig.json\"}\\n',\n    'utf8',\n  );\n  fs.writeFileSync(\n    path.join(testsDir, 'README.md'),\n    loadTemplate('skill-tests-README.md.template', { SKILL_NAME: name }),\n    'utf8',\n  );\n\n  // Register in registry.json\n  const registry = JSON.parse(fs.readFileSync(registryPath, 'utf8')) as SkillRegistry;\n  const entry: SkillMeta = { name, description, tags: tagList, path: skillPath, category };\n  registry.skills.push(entry);\n  fs.writeFileSync(registryPath, JSON.stringify(registry, null, 2) + '\\n', 'utf8');\n\n  console.log(`\\n${wrapInColor('Created:', ANSI_COLORS.GREEN_COLOR)} ${skillFile}`);\n  console.log(`${wrapInColor('Created:', ANSI_COLORS.GREEN_COLOR)} ${testsDir}/`);\n  console.log(`${wrapInColor('Registered:', ANSI_COLORS.GREEN_COLOR)} ${registryPath}`);\n  console.log(`\\nNext steps:`);\n  console.log(`  1. Edit ${wrapInColor(skillFile, ANSI_COLORS.BLUE_COLOR)} — fill in the skill content`);\n  console.log(`  2. Edit ${wrapInColor(path.join(testsDir, 'src', 'reference.tsx'), ANSI_COLORS.BLUE_COLOR)} — add compile-check examples`);\n  console.log(`  3. Run ${wrapInColor(`bazel build //ai-skills/skills/${name}/tests:tests`, ANSI_COLORS.BLUE_COLOR)} to verify the reference compiles`);\n  console.log(`  4. Run ${wrapInColor('valdi skills install', ANSI_COLORS.BLUE_COLOR)} to test the skill locally`);\n  console.log(`  5. Open a PR against the Valdi repo to share it with the community`);\n}\n\nexport const command = 'create';\nexport const describe = 'Scaffold a new skill in the Valdi framework checkout';\nexport const builder = (_yargs: Argv<CommandParameters>) => {};\nexport const handler = makeCommandHandler(skillsCreate);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/skills_commands/install.ts",
    "content": "import type { Argv } from 'yargs';\nimport ora from 'ora';\nimport { makeCommandHandler } from '../../utils/errorUtils';\nimport type { ArgumentsResolver } from '../../utils/ArgumentsResolver';\nimport { fetchRegistry, fetchSkillContent } from '../../utils/skillsRegistry';\nimport { detectAdapters, getAdapterByName } from '../../utils/skillsAdapters';\nimport { ANSI_COLORS } from '../../core/constants';\nimport { wrapInColor } from '../../utils/logUtils';\n\ninterface CommandParameters {\n  name: string | undefined;\n  for: string | undefined;\n  category: string | undefined;\n}\n\nasync function skillsInstall(argv: ArgumentsResolver<CommandParameters>) {\n  const skillName = argv.getArgument('name');\n  const forAgent = argv.getArgument('for');\n  const categoryFilter = argv.getArgument('category') as string | undefined;\n\n  let registry;\n  try {\n    registry = await fetchRegistry();\n  } catch (error) {\n    console.log(wrapInColor(\n      `Could not load skills: ${error instanceof Error ? error.message : String(error)}`,\n      ANSI_COLORS.RED_COLOR,\n    ));\n    return;\n  }\n\n  // Determine which skills to install\n  let skillsToInstall = skillName\n    ? registry.skills.filter((s) => s.name === skillName)\n    : registry.skills;\n\n  if (skillName && skillsToInstall.length === 0) {\n    console.log(wrapInColor(`Skill \"${skillName}\" not found in registry.`, ANSI_COLORS.RED_COLOR));\n    console.log(`Run ${wrapInColor('valdi skills list', ANSI_COLORS.BLUE_COLOR)} to see available skills.`);\n    return;\n  }\n\n  if (categoryFilter) {\n    skillsToInstall = skillsToInstall.filter((s) => s.category.includes(categoryFilter as 'framework' | 'client'));\n    if (skillsToInstall.length === 0) {\n      console.log(wrapInColor(`No skills found for category \"${categoryFilter}\".`, ANSI_COLORS.YELLOW_COLOR));\n      return;\n    }\n  }\n\n  // Determine which adapters to use\n  let adapters = detectAdapters().filter((a) => a.name !== 'generic');\n  if (forAgent) {\n    if (forAgent === 'all') {\n      // keep all detected adapters\n    } else {\n      const specific = getAdapterByName(forAgent);\n      if (!specific) {\n        console.log(wrapInColor(`Unknown agent \"${forAgent}\". Valid options: claude, cursor, copilot, all`, ANSI_COLORS.RED_COLOR));\n        return;\n      }\n      adapters = [specific];\n    }\n  }\n\n  if (adapters.length === 0) {\n    console.log(wrapInColor('No supported AI agents detected.', ANSI_COLORS.YELLOW_COLOR));\n    console.log('Use --for=claude, --for=cursor, or --for=copilot to install for a specific agent.');\n    return;\n  }\n\n  console.log(\n    `Installing ${wrapInColor(String(skillsToInstall.length), ANSI_COLORS.GREEN_COLOR)} skill(s) for: ${wrapInColor(adapters.map((a) => a.name).join(', '), ANSI_COLORS.BLUE_COLOR)}\\n`,\n  );\n\n  for (const skill of skillsToInstall) {\n    const installSpinner = ora(`Installing ${skill.name}…`).start();\n    try {\n      const content = await fetchSkillContent(skill.path);\n      for (const adapter of adapters) {\n        adapter.install(skill.name, content, skill);\n      }\n      installSpinner.succeed(`Installed ${wrapInColor(skill.name, ANSI_COLORS.GREEN_COLOR)}`);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      installSpinner.fail(`Failed to install ${skill.name}: ${message}`);\n    }\n  }\n\n  console.log(`\\nDone. Run ${wrapInColor('valdi skills list', ANSI_COLORS.BLUE_COLOR)} to see installed skills.`);\n  if (!categoryFilter) {\n    console.log(\n      `Tip: install only module-development skills with ${wrapInColor('valdi skills install --category=client', ANSI_COLORS.BLUE_COLOR)}`,\n    );\n  }\n}\n\nexport const command = 'install [name]';\nexport const describe = 'Install skills for detected AI agents (--category=framework|client to filter)';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs\n    .positional('name', {\n      describe: 'Skill name to install (omit to install all)',\n      type: 'string',\n    })\n    .option('for', {\n      describe: 'Target agent to install for',\n      type: 'string',\n      choices: ['claude', 'cursor', 'copilot', 'all'],\n    })\n    .option('category', {\n      describe: 'Only install skills in this category',\n      type: 'string',\n      choices: ['framework', 'client'],\n    });\n};\nexport const handler = makeCommandHandler(skillsInstall);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/skills_commands/list.ts",
    "content": "import type { Argv } from 'yargs';\nimport { makeCommandHandler } from '../../utils/errorUtils';\nimport type { ArgumentsResolver } from '../../utils/ArgumentsResolver';\nimport { fetchRegistry } from '../../utils/skillsRegistry';\nimport { detectAdapters } from '../../utils/skillsAdapters';\nimport { ANSI_COLORS } from '../../core/constants';\nimport { wrapInColor } from '../../utils/logUtils';\n\ninterface CommandParameters {\n  category: string | undefined;\n}\n\nasync function skillsList(argv: ArgumentsResolver<CommandParameters>) {\n  const categoryFilter = argv.getArgument('category') as string | undefined;\n\n  let registry;\n  try {\n    registry = await fetchRegistry();\n  } catch (error) {\n    console.log(wrapInColor(\n      `Could not load skills: ${error instanceof Error ? error.message : String(error)}`,\n      ANSI_COLORS.RED_COLOR,\n    ));\n    return;\n  }\n\n  const adapters = detectAdapters();\n  const adapterNames = adapters.map((a) => a.name);\n\n  // Build installed sets per adapter\n  const installedByAdapter = new Map<string, Set<string>>();\n  for (const adapter of adapters) {\n    installedByAdapter.set(adapter.name, new Set(adapter.listInstalled()));\n  }\n\n  const skills = categoryFilter\n    ? registry.skills.filter((s) => s.category.includes(categoryFilter as 'framework' | 'client'))\n    : registry.skills;\n\n  if (categoryFilter && skills.length === 0) {\n    console.log(wrapInColor(`No skills found for category \"${categoryFilter}\".`, ANSI_COLORS.YELLOW_COLOR));\n    return;\n  }\n\n  // Header\n  const nameWidth = 28;\n  const catWidth = 18;\n  const descWidth = 44;\n  const colWidth = 8;\n\n  const headerParts = [\n    'NAME'.padEnd(nameWidth),\n    'CATEGORY'.padEnd(catWidth),\n    'DESCRIPTION'.padEnd(descWidth),\n    ...adapterNames.map((n) => n.toUpperCase().padEnd(colWidth)),\n  ];\n  console.log(wrapInColor(headerParts.join('  '), ANSI_COLORS.GRAY_COLOR));\n  console.log(wrapInColor('-'.repeat(nameWidth + catWidth + descWidth + adapterNames.length * (colWidth + 2) + 4), ANSI_COLORS.GRAY_COLOR));\n\n  // Group by category for cleaner display (skills in multiple categories appear in each group)\n  const categories = [...new Set(skills.flatMap((s) => s.category))];\n  for (const cat of categories) {\n    const group = skills.filter((s) => s.category.includes(cat as 'framework' | 'client'));\n    if (categories.length > 1) {\n      console.log(wrapInColor(`\\n[${cat}]`, ANSI_COLORS.BLUE_COLOR));\n    }\n    for (const skill of group) {\n      const name = skill.name.padEnd(nameWidth);\n      const category = skill.category.join(', ').padEnd(catWidth);\n      const desc = skill.description.length > descWidth - 1\n        ? skill.description.slice(0, descWidth - 1) + '…'\n        : skill.description.padEnd(descWidth);\n\n      const statusCols = adapterNames.map((adapterName) => {\n        const installed = installedByAdapter.get(adapterName)?.has(skill.name) ?? false;\n        const mark = installed\n          ? wrapInColor('✓', ANSI_COLORS.GREEN_COLOR)\n          : wrapInColor('-', ANSI_COLORS.GRAY_COLOR);\n        return mark.padEnd(colWidth);\n      });\n\n      console.log([name, category, desc, ...statusCols].join('  '));\n    }\n  }\n\n  console.log(\n    `\\n${wrapInColor(`${skills.length} skill(s) available`, ANSI_COLORS.GRAY_COLOR)}` +\n    `  Detected agents: ${wrapInColor(adapterNames.join(', '), ANSI_COLORS.GREEN_COLOR)}`,\n  );\n  console.log(\n    `\\nInstall a skill: ${wrapInColor('valdi skills install <name>', ANSI_COLORS.BLUE_COLOR)}`,\n  );\n  if (!categoryFilter) {\n    console.log(\n      `Filter by category: ${wrapInColor('valdi skills list --category=framework', ANSI_COLORS.BLUE_COLOR)}`,\n    );\n  }\n}\n\nexport const command = 'list';\nexport const describe = 'List available skills and their installation status';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs.option('category', {\n    describe: 'Filter by category (framework, client)',\n    type: 'string',\n    choices: ['framework', 'client'],\n  });\n};\nexport const handler = makeCommandHandler(skillsList);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/skills_commands/remove.ts",
    "content": "import type { Argv } from 'yargs';\nimport { makeCommandHandler } from '../../utils/errorUtils';\nimport type { ArgumentsResolver } from '../../utils/ArgumentsResolver';\nimport { detectAdapters } from '../../utils/skillsAdapters';\nimport { ANSI_COLORS } from '../../core/constants';\nimport { wrapInColor } from '../../utils/logUtils';\n\ninterface CommandParameters {\n  name: string;\n}\n\nasync function skillsRemove(argv: ArgumentsResolver<CommandParameters>) {\n  const skillName = argv.getArgument('name');\n  const adapters = detectAdapters();\n\n  let removedFromAny = false;\n\n  for (const adapter of adapters) {\n    const installed = adapter.listInstalled();\n    if (installed.includes(skillName)) {\n      try {\n        adapter.remove(skillName);\n        console.log(\n          `Removed ${wrapInColor(skillName, ANSI_COLORS.GREEN_COLOR)} from ${wrapInColor(adapter.name, ANSI_COLORS.BLUE_COLOR)}`,\n        );\n        removedFromAny = true;\n      } catch (error) {\n        const message = error instanceof Error ? error.message : String(error);\n        console.log(\n          wrapInColor(`Failed to remove ${skillName} from ${adapter.name}: ${message}`, ANSI_COLORS.RED_COLOR),\n        );\n      }\n    }\n  }\n\n  if (!removedFromAny) {\n    console.log(\n      wrapInColor(`Skill \"${skillName}\" is not installed for any detected agent.`, ANSI_COLORS.YELLOW_COLOR),\n    );\n    console.log(`Run ${wrapInColor('valdi skills list', ANSI_COLORS.BLUE_COLOR)} to see installed skills.`);\n  }\n}\n\nexport const command = 'remove <name>';\nexport const describe = 'Remove a skill from all detected AI agents';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs.positional('name', {\n    describe: 'Name of the skill to remove',\n    type: 'string',\n    demandOption: true,\n  });\n};\nexport const handler = makeCommandHandler(skillsRemove);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/skills_commands/update.ts",
    "content": "import type { Argv } from 'yargs';\nimport ora from 'ora';\nimport { makeCommandHandler } from '../../utils/errorUtils';\nimport type { ArgumentsResolver } from '../../utils/ArgumentsResolver';\nimport { fetchRegistry, fetchSkillContent } from '../../utils/skillsRegistry';\nimport { detectAdapters } from '../../utils/skillsAdapters';\nimport { ANSI_COLORS } from '../../core/constants';\nimport { wrapInColor } from '../../utils/logUtils';\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\ninterface CommandParameters {}\n\nasync function skillsUpdate(_argv: ArgumentsResolver<CommandParameters>) {\n  const adapters = detectAdapters().filter((a) => a.name !== 'generic');\n  if (adapters.length === 0) {\n    console.log(\n      wrapInColor('No supported AI agents detected. Nothing to update.', ANSI_COLORS.YELLOW_COLOR),\n    );\n    return;\n  }\n\n  let registry;\n  try {\n    registry = await fetchRegistry();\n  } catch (error) {\n    console.log(wrapInColor(\n      `Could not load skills: ${error instanceof Error ? error.message : String(error)}`,\n      ANSI_COLORS.RED_COLOR,\n    ));\n    return;\n  }\n\n  // Only update skills that are already installed somewhere.\n  const installedSkillNames = new Set<string>();\n  for (const adapter of adapters) {\n    for (const skillName of adapter.listInstalled()) {\n      installedSkillNames.add(skillName);\n    }\n  }\n\n  const skillsToUpdate = registry.skills.filter((s) => installedSkillNames.has(s.name));\n\n  if (skillsToUpdate.length === 0) {\n    console.log('No installed skills found to update.');\n    console.log(\n      `Run ${wrapInColor('valdi skills install', ANSI_COLORS.BLUE_COLOR)} to install skills.`,\n    );\n    return;\n  }\n\n  console.log(\n    `\\nUpdating ${wrapInColor(String(skillsToUpdate.length), ANSI_COLORS.GREEN_COLOR)} installed skill(s) for: ${wrapInColor(adapters.map((a) => a.name).join(', '), ANSI_COLORS.BLUE_COLOR)}\\n`,\n  );\n\n  for (const skill of skillsToUpdate) {\n    const updateSpinner = ora(`Updating ${skill.name}…`).start();\n    try {\n      const content = await fetchSkillContent(skill.path);\n      for (const adapter of adapters) {\n        if (adapter.listInstalled().includes(skill.name)) {\n          adapter.install(skill.name, content, skill);\n        }\n      }\n      updateSpinner.succeed(`Updated ${wrapInColor(skill.name, ANSI_COLORS.GREEN_COLOR)}`);\n    } catch (error) {\n      updateSpinner.fail(\n        `Failed to update ${skill.name}: ${error instanceof Error ? error.message : String(error)}`,\n      );\n    }\n  }\n\n  console.log(`\\nAll installed skills updated.`);\n}\n\nexport const command = 'update';\nexport const describe = 'Re-install all currently installed skills from the bundled package';\nexport const builder = (_yargs: Argv<CommandParameters>) => {};\nexport const handler = makeCommandHandler(skillsUpdate);\n"
  },
  {
    "path": "npm_modules/cli/src/commands/test.ts",
    "content": "import type { Argv } from 'yargs';\nimport { ANSI_COLORS } from '../core/constants';\nimport type { ArgumentsResolver } from '../utils/ArgumentsResolver';\nimport { BazelClient } from '../utils/BazelClient';\nimport { LoadingIndicator } from '../utils/LoadingIndicator';\nimport { makeCommandHandler } from '../utils/errorUtils';\nimport { wrapInColor } from '../utils/logUtils';\n\ninterface CommandParameters {\n  module: string[] | undefined;\n  target: string[] | undefined;\n  bazel_args: string | undefined;\n}\n\nasync function getTestTargetsByModuleNames(client: BazelClient, modules?: string[]): Promise<string[]> {\n  return await client.queryTargetsByKindWithFilter('test', modules ?? [], 'pipe');\n}\n\nasync function valdiTest(argv: ArgumentsResolver<CommandParameters>) {\n  const bazelClient = new BazelClient();\n\n  const targets = await argv.getArgumentOrResolve('target', () => {\n    return LoadingIndicator.fromTask(getTestTargetsByModuleNames(bazelClient, argv.getArgument('module') ?? []))\n      .setText(wrapInColor('Collecting targets for tests...', ANSI_COLORS.YELLOW_COLOR))\n      .setSuccessText(wrapInColor('Finished collecting test targets.', ANSI_COLORS.GREEN_COLOR))\n      .setFailureText(wrapInColor('Failed to collect targets.', ANSI_COLORS.RED_COLOR))\n      .show();\n  });\n\n  if (targets === undefined || targets.length === 0) {\n    console.log('No test targets found.');\n    return;\n  }\n\n  console.log('Starting tests for targets:');\n  console.log(\n    targets\n      .map(target => {\n        return `  ${wrapInColor(target, ANSI_COLORS.GREEN_COLOR)}`;\n      })\n      .join('\\n'),\n  );\n\n  await bazelClient.testTargets(targets, argv.getArgument('bazel_args'));\n}\n\nexport const command = 'test [--module module_name] [--target target_name]';\nexport const describe =\n  'Runs tests for given module(s) or target(s). Runs all tests if no module or target is specified.';\nexport const builder = (yargs: Argv<CommandParameters>) => {\n  yargs\n    .option('module', {\n      describe: 'name of the module to test',\n      type: 'array',\n      requiresArg: true,\n    })\n    .option('target', {\n      describe: 'Bazel target path to test',\n      type: 'array',\n      requiresArg: true,\n    })\n    .option('bazel_args', {\n      describe: `Additional arguments to pass to bazel build. Use format ${wrapInColor('--bazel_args=\"<args>\"', ANSI_COLORS.YELLOW_COLOR)}.`,\n      type: 'string',\n      requiresArg: true,\n    });\n};\nexport const handler = makeCommandHandler(valdiTest);\n"
  },
  {
    "path": "npm_modules/cli/src/core/constants.ts",
    "content": "import path from 'path';\n\nexport const VALDI_CONFIG_PATHS: string[] = ['~/.valdi/config.yaml', '~/.valdi/config.yml'];\nexport const BAZEL_BIN_ENV = 'BAZEL_BIN';\nexport const BAZEL_EXECUTABLES: string[] = ['bazel', 'bzl', 'bazelisk'];\n\n// Console color ANSI escape sequences\nexport enum ANSI_COLORS {\n  RESET_COLOR = '\\u001B[0m',\n  RED_COLOR = '\\u001B[31m',\n  GREEN_COLOR = '\\u001B[32m',\n  YELLOW_COLOR = '\\u001B[33m',\n  BLUE_COLOR = '\\u001B[34m',\n  GRAY_COLOR = '\\u001B[90m',\n}\n\nexport enum PLATFORM {\n  IOS = 'ios',\n  ANDROID = 'android',\n  MACOS = 'macos',\n  CLI = 'cli',\n}\n\nexport enum Architecture {\n  ARM64,\n  ARMV7,\n  X86_64,\n}\n\nexport const ALL_ARCHITECTURES: Architecture[] = [Architecture.ARMV7, Architecture.ARM64, Architecture.X86_64];\n\n// Relative path starts at .metadata\nexport enum TEMPLATE_BASE_PATHS {\n  WORKSPACE = 'WORKSPACE.template',\n  BAZEL_RC = '.bazelrc.template',\n  BAZEL_VERSION = '.bazelversion.template',\n  USER_CONFIG = 'config.yaml.template',\n  PRETTIER_CONFIG = '.prettierrc.json.template',\n  ESLINT_CONFIG = '.eslintrc.js.template',\n  ESLINT_PACKAGE_JSON_CONFIG = 'package.json.template',\n  README = 'README.md.template',\n  WATCHMAN_CONFIG = '.watchmanconfig.template',\n  GIT_IGNORE = '.gitignore.template',\n  EDITOR_CONFIG = '.editorconfig.template',\n  AGENTS = 'AGENTS.md.template',\n}\n\nexport const VALID_PLATFORMS: string[] = [PLATFORM.ANDROID, PLATFORM.IOS, PLATFORM.MACOS, PLATFORM.CLI];\n\nexport interface UserConfig {\n  logs_output_dir: string | undefined;\n}\n\n// TODO: Replace with Valdi defined bazel rule targets\nexport const IOS_BAZEL_APPLICATION_TAG = 'valdi_ios_application';\nexport const ANDROID_BAZEL_APPLICATION_TAG = 'valdi_android_application';\nexport const MACOS_BAZEL_APPLICATION_TAG = 'valdi_macos_application';\nexport const CLI_BAZEL_APPLICATION_TAG = 'valdi_cli_application';\n\nexport const IOS_EXPORTED_LIBRARY_TAG = 'valdi_ios_exported_library';\nexport const ANDROID_EXPORTED_LIBRARY_TAG = 'valdi_android_exported_library';\n\n// Paths\n// eslint-disable-next-line unicorn/prefer-module\nexport const CLI_ROOT = path.join(__dirname, '../..');\nexport const CONFIG_DIR_PATH = path.join(CLI_ROOT, '.config');\nexport const META_DIR_PATH = path.join(CLI_ROOT, '.metadata');\nexport const BOOTSTRAP_DIR_PATH = path.join(CLI_ROOT, '.bootstrap');\nexport const SETUP_SCRIPT_DIR_PATH = path.join(CLI_ROOT, 'src/setup');\nexport const MACOS_SETUP_SCRIPT_DIR_PATH = path.join(SETUP_SCRIPT_DIR_PATH, 'macos');\nexport const LINUX_SETUP_SCRIPT_DIR_PATH = path.join(SETUP_SCRIPT_DIR_PATH, 'linux');\n\nexport const COPY_CONFIG_PATH = path.join(CONFIG_DIR_PATH, 'copyconfig.json');\n\nexport const ANDROID_BUILD_FLAGS = ['--copt=-DANDROID_WITH_JNI', '--repo_env=VALDI_PLATFORM_DEPENDENCIES=android'];\n\nfunction androidCpuFlags(cpu: string): readonly string[] {\n  return [`--fat_apk_cpu=${cpu}`, `--android_cpu=${cpu}`];\n}\n\nexport const ANDROID_ARM64_BUILD_FLAGS = ['--define', 'client_repo_arm64=true', ...androidCpuFlags('arm64-v8a')];\nexport const ANDROID_ARMV7_BUILD_FLAGS = ['--define', 'client_repo_arm32=true', ...androidCpuFlags('armeabi-v7a')];\nexport const ANDROID_X86_64_BUILD_FLAGS = ['--define', 'client_repo_x86_64=true', ...androidCpuFlags('x86_64')];\n\nexport const ENABLE_RUNTIME_LOGS_BUILD_FLAGS = ['--@valdi//bzl/runtime_flags:enable_logging'];\nexport const ENABLE_RUNTIME_TRACES_BUILD_FLAGS = ['--@valdi//bzl/runtime_flags:enable_tracing'];\nexport const DEBUG_BUILD_FLAGS = ['--snap_flavor=platform_development'];\nexport const RELEASE_BUILD_FLAGS = ['--snap_flavor=production', '-c opt'];\n\nexport const IOS_DEVICE_BUILD_FLAGS = '--ios_multi_cpus=arm64';\nexport const IOS_BUILD_FLAGS = '--repo_env=VALDI_PLATFORM_DEPENDENCIES=ios';\n\nconst INLINE_ASSETS_BUILD_FLAGS = ['--@valdi//bzl/valdi:assets_mode=inline'];\n\nexport const MACOS_BUILD_FLAGS = [...INLINE_ASSETS_BUILD_FLAGS, '--repo_env=VALDI_PLATFORM_DEPENDENCIES=macos'];\nexport const CLI_BUILD_FLAGS = [...INLINE_ASSETS_BUILD_FLAGS, '--repo_env=VALDI_PLATFORM_DEPENDENCIES=cli'];\nexport const TEST_BUILD_FLAGS = INLINE_ASSETS_BUILD_FLAGS;\n"
  },
  {
    "path": "npm_modules/cli/src/core/errors.ts",
    "content": "import { ANSI_COLORS } from './constants';\n\nexport class CliError extends Error {\n  textColor: ANSI_COLORS;\n\n  constructor(message: string, textColor: ANSI_COLORS = ANSI_COLORS.RED_COLOR) {\n    super(message);\n    this.textColor = textColor;\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/index.ts",
    "content": "#!/usr/bin/env node\n\nimport yargs from 'yargs';\nimport { hideBin } from 'yargs/helpers';\nimport { version } from '../package.json';\n\nfunction main() {\n  void yargs(hideBin(process.argv))\n    .completion()\n    .commandDir('commands', {\n      extensions: ['js', 'ts'],\n    })\n    .demandCommand(1, 'Need at least one command to execute')\n    .recommendCommands()\n    .strict()\n    .option('debug', {\n      describe: 'Run with debug logging',\n      type: 'boolean',\n      default: false,\n    })\n    .version('version', 'Show version number', version)\n    .scriptName('valdi')\n    .wrap(yargs.terminalWidth())\n    .help().argv;\n}\n\nmain();\n"
  },
  {
    "path": "npm_modules/cli/src/setup/DevSetupHelper.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport { ANSI_COLORS } from '../core/constants';\nimport { LoadingIndicator } from '../utils/LoadingIndicator';\nimport { spawnCliCommand } from '../utils/cliUtils';\nimport { wrapInColor } from '../utils/logUtils';\nimport { withTempDir } from '../utils/tempDir';\nimport { decompressTo } from '../utils/zipUtils';\nimport { ANDROID_BUILD_TOOLS_VERSION, ANDROID_NDK_VERSION, ANDROID_PLATFORM_VERSION } from './versions';\n\nexport const HOME_DIR = process.env['HOME'] ?? '';\n\n// Platform-specific Android SDK locations matching documentation\nfunction getAndroidHomeDir(): string {\n  const platform = process.platform;\n  if (platform === 'darwin') {\n    return path.join(HOME_DIR, 'Library', 'Android', 'sdk');\n  } else {\n    // Linux and others\n    return path.join(HOME_DIR, 'Android', 'Sdk');\n  }\n}\n\nconst ANDROID_HOME_TARGET_DIR = getAndroidHomeDir();\n\nexport interface EnvVariable {\n  name: string;\n  value: string;\n}\n\nexport class DevSetupHelper {\n  async download(url: string): Promise<ArrayBuffer> {\n    return new LoadingIndicator(async () => {\n      const response = await fetch(url);\n\n      return response.arrayBuffer();\n    })\n      .setText(`${wrapInColor('Downloading', ANSI_COLORS.YELLOW_COLOR)} ${url}...`)\n      .show();\n  }\n\n  async downloadToPath(url: string, dest: string): Promise<void> {\n    const body = await this.download(url);\n\n    const dir = path.dirname(dest);\n    if (!fs.existsSync(dir)) {\n      fs.mkdirSync(dir, { recursive: true });\n    }\n\n    await fs.promises.writeFile(dest, new Uint8Array(body));\n  }\n\n  async runShell(\n    guide: string,\n    commands: string[],\n    additionalEnvVariables: { [key: string]: string } = {},\n  ): Promise<string> {\n    let command = '';\n    for (const key in additionalEnvVariables) {\n      command += `export ${key}=\"${additionalEnvVariables[key] as string}\"\\n`;\n    }\n    command += commands.join(' && ');\n    console.log(`${wrapInColor(guide, ANSI_COLORS.YELLOW_COLOR)}...`);\n    for (const command of commands) {\n      console.log(`- ${command}`);\n    }\n\n    const result = await spawnCliCommand(command, undefined, 'inherit', false, true);\n    return result.stdout;\n  }\n\n  async writeEnvVariablesToRcFile(envVariables: readonly EnvVariable[]): Promise<void> {\n    const expectedEnvVariable = envVariables.map(e => `export ${e.name}=${e.value}`);\n    const rcFile = this.getRcFile();\n    if (!rcFile) {\n      console.log();\n      console.log(\n        `${wrapInColor(`Unrecognized shell ${process.env['SHELL'] ?? ''}. Please add the following env variables to your shell configuration file manually:`, ANSI_COLORS.RED_COLOR)}`,\n      );\n      for (const l of expectedEnvVariable) {\n        console.log(l);\n      }\n      console.log();\n      return;\n    }\n\n    return new LoadingIndicator(async () => {\n      let originalRcLines: readonly string[] = [];\n      let rcLines: string[] = [];\n      if (fs.existsSync(rcFile)) {\n        const fileBody = await fs.promises.readFile(rcFile, 'utf8');\n        originalRcLines = fileBody.split('\\n');\n        rcLines = [...originalRcLines];\n      }\n\n      const valdiConfHeader = `# Valdi configuration end`;\n      let insertionIndex = rcLines.indexOf(valdiConfHeader);\n\n      if (insertionIndex < 0) {\n        rcLines.push(`# Valdi configuration begin`, valdiConfHeader);\n        insertionIndex = rcLines.length - 1;\n      }\n\n      for (const envVariable of expectedEnvVariable) {\n        if (!rcLines.includes(envVariable)) {\n          rcLines.splice(insertionIndex++, 0, envVariable);\n        }\n      }\n\n      if (rcLines.length !== originalRcLines.length) {\n        const content = rcLines.join('\\n');\n        await fs.promises.writeFile(rcFile, content, 'utf8');\n      }\n    })\n      .setText(\n        wrapInColor(\n          `Updating ${rcFile} to include ${envVariables.map(e => e.name).join(', ')}...`,\n          ANSI_COLORS.YELLOW_COLOR,\n        ),\n      )\n      .show();\n  }\n\n  onComplete(): void {\n    let suffix = '';\n    const rcFile = this.getRcFile();\n\n    if (rcFile) {\n      suffix += ` Please run ${wrapInColor(`source ${rcFile}`, ANSI_COLORS.YELLOW_COLOR)} or restart your terminal.`;\n    }\n    console.log(`${wrapInColor('Dev setup completed!', ANSI_COLORS.GREEN_COLOR)}.${suffix}`);\n    console.log();\n    console.log(wrapInColor('📝 Next steps:', ANSI_COLORS.BLUE_COLOR));\n    console.log('  1. Restart your terminal or source your shell configuration');\n    console.log('  2. Install VSCode/Cursor extensions for the best development experience:');\n    console.log(`     ${wrapInColor('https://github.com/Snapchat/Valdi/blob/main/docs/INSTALL.md#vscodecursor-setup-optional-but-recommended', ANSI_COLORS.BLUE_COLOR)}`);\n    console.log('  3. Run `valdi doctor` to verify your setup');\n    console.log('  4. Create your first project with `valdi bootstrap`');\n  }\n\n  async setupGitLfs(): Promise<void> {\n    await this.runShell('Initializing git-lfs', ['git lfs install']);\n  }\n\n  async setupShellAutoComplete(): Promise<void> {\n    const rcFile = this.getRcFile();\n    if (!rcFile) {\n      console.log(\n        wrapInColor(\n          'Could not determine shell configuration file, skipping autocomplete setup...',\n          ANSI_COLORS.YELLOW_COLOR,\n        ),\n      );\n      return;\n    }\n\n    const shell = process.env['SHELL'] ?? '';\n    let autoCompleteLines: string[] = [];\n\n    if (shell.endsWith('/zsh')) {\n      autoCompleteLines = ['autoload -U compinit && compinit', 'autoload -U bashcompinit && bashcompinit'];\n    } else if (shell.endsWith('/bash')) {\n      // Bash completion is typically handled by bash-completion package\n      // We'll check if it's already enabled\n      autoCompleteLines = ['# Bash completion is enabled'];\n    }\n\n    if (autoCompleteLines.length === 0 || autoCompleteLines[0] === '# Bash completion is enabled') {\n      // For bash, we don't need to add anything as it's usually auto-loaded\n      if (shell.endsWith('/bash')) {\n        console.log(wrapInColor('Shell autocomplete setup complete (bash)', ANSI_COLORS.GREEN_COLOR));\n      }\n      return;\n    }\n\n    return new LoadingIndicator(async () => {\n      let originalRcLines: readonly string[] = [];\n      let rcLines: string[] = [];\n      if (fs.existsSync(rcFile)) {\n        const fileBody = await fs.promises.readFile(rcFile, 'utf8');\n        originalRcLines = fileBody.split('\\n');\n        rcLines = [...originalRcLines];\n      }\n\n      // Check if autocomplete is already configured\n      let needsUpdate = false;\n      for (const line of autoCompleteLines) {\n        if (!rcLines.includes(line)) {\n          needsUpdate = true;\n          break;\n        }\n      }\n\n      if (needsUpdate) {\n        // Find the Valdi configuration section or add to the top\n        const valdiConfBegin = rcLines.indexOf('# Valdi configuration begin');\n        const insertIndex = valdiConfBegin >= 0 ? valdiConfBegin : 0;\n\n        // Insert autocomplete lines at the beginning (before Valdi config or at top)\n        for (let i = autoCompleteLines.length - 1; i >= 0; i--) {\n          const line = autoCompleteLines[i];\n          if (line && !rcLines.includes(line)) {\n            rcLines.splice(insertIndex, 0, line);\n          }\n        }\n\n        const content = rcLines.join('\\n');\n        await fs.promises.writeFile(rcFile, content, 'utf8');\n      }\n    })\n      .setText(wrapInColor('Setting up shell autocomplete...', ANSI_COLORS.YELLOW_COLOR))\n      .show();\n  }\n\n  async setupAndroidSDK(commandLineToolsURL: string, javaHomeOverride?: string | undefined): Promise<void> {\n    console.log(wrapInColor('Setting up Android SDK...', ANSI_COLORS.YELLOW_COLOR));\n    if (!process.env['ANDROID_HOME']) {\n      await withTempDir(async tempDir => {\n        const filename = path.join(tempDir, path.basename(commandLineToolsURL));\n        await this.downloadToPath(commandLineToolsURL, filename);\n        const targetDir = path.join(ANDROID_HOME_TARGET_DIR, 'cmdline-tools');\n        await decompressTo(filename, targetDir);\n\n        const target = path.join(targetDir, 'latest');\n        if (fs.existsSync(target)) {\n          await fs.promises.rm(target, { recursive: true, force: true });\n        }\n        fs.renameSync(path.join(targetDir, 'cmdline-tools'), target);\n      });\n      process.env['ANDROID_HOME'] = ANDROID_HOME_TARGET_DIR;\n      \n      // Set ANDROID_HOME with platform-specific path\n      const androidHomeValue = process.platform === 'darwin' \n        ? '\"$HOME/Library/Android/sdk\"'\n        : '\"$HOME/Android/Sdk\"';\n      await this.writeEnvVariablesToRcFile([{ name: 'ANDROID_HOME', value: androidHomeValue }]);\n    }\n\n    const androidHome = process.env['ANDROID_HOME'] ?? '';\n    const sdkManagerBin = path.join(androidHome, 'cmdline-tools/latest/bin/sdkmanager');\n\n    const sdkManagerEnvVariables: { [key: string]: string } = {};\n    if (javaHomeOverride) {\n      sdkManagerEnvVariables['JAVA_HOME'] = javaHomeOverride;\n    }\n\n    await this.runShell(\n      'Installing Android platform',\n      [`${sdkManagerBin} --install 'platforms;${ANDROID_PLATFORM_VERSION}'`],\n      sdkManagerEnvVariables,\n    );\n    await this.runShell(\n      'Installing Android NDK',\n      [`${sdkManagerBin} --install 'ndk;${ANDROID_NDK_VERSION}'`],\n      sdkManagerEnvVariables,\n    );\n    await this.runShell(\n      'Installing Android build-tools',\n      [`${sdkManagerBin} --install 'build-tools;${ANDROID_BUILD_TOOLS_VERSION}'`],\n      sdkManagerEnvVariables,\n    );\n\n    const ndkBundle = path.join(androidHome, 'ndk-bundle');\n    if (!fs.existsSync(ndkBundle)) {\n      fs.symlinkSync(`ndk/${ANDROID_NDK_VERSION}`, ndkBundle);\n    }\n    \n    // Set up Android environment variables including platform-tools in PATH\n    await this.writeEnvVariablesToRcFile([\n      { name: 'ANDROID_NDK_HOME', value: `\"$ANDROID_HOME/ndk-bundle\"` },\n      { name: 'PATH', value: `\"$ANDROID_HOME/platform-tools:$PATH\"` },\n    ]);\n  }\n\n  private getRcFile(): string | undefined {\n    const homeDir = process.env['HOME'] ?? '';\n    const shell = process.env['SHELL'] ?? '';\n    if (shell.endsWith('/zsh')) {\n      return path.join(homeDir, '.zshrc');\n    } else if (shell.endsWith('/bash')) {\n      return path.join(homeDir, '.bashrc');\n    } else if (shell.endsWith('/ksh')) {\n      return path.join(homeDir, '.kshrc');\n    } else if (shell.endsWith('/tcsh')) {\n      return path.join(homeDir, '.tcshrc');\n    } else {\n      return undefined;\n    }\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/setup/linuxSetup.ts",
    "content": "import { execSync } from 'child_process';\nimport fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport { ANSI_COLORS } from '../core/constants';\nimport { checkCommandExists } from '../utils/cliUtils';\nimport {\n  LinuxDistroType,\n  buildInstallCommand,\n  detectLinuxDistro,\n  getCommonPackageMappings,\n  getGitLfsRepoSetupCommand,\n  getPackageName,\n  needsGitLfsRepoSetup,\n} from '../utils/linuxDistro';\nimport { wrapInColor } from '../utils/logUtils';\nimport { DevSetupHelper, HOME_DIR } from './DevSetupHelper';\nimport { ANDROID_LINUX_COMMANDLINE_TOOLS } from './versions';\n\nconst BAZELISK_URL = 'https://github.com/bazelbuild/bazelisk/releases/download/v1.26.0/bazelisk-linux-amd64';\n\n/**\n * Maps Node.js architecture names to Debian package architecture names.\n * @returns Debian package architecture string (e.g., 'amd64', 'arm64', 'armhf')\n */\nfunction getDebianArchitecture(): string {\n  const nodeArch = os.arch();\n  \n  // Map Node.js arch names to Debian package arch names\n  switch (nodeArch) {\n    case 'x64': {\n      return 'amd64';\n    }\n    case 'arm64': {\n      return 'arm64';\n    }\n    case 'arm': {\n      return 'armhf';\n    }\n    case 'ia32': {\n      return 'i386';\n    }\n    default: {\n      // Fallback to amd64 for unknown architectures\n      console.log(\n        wrapInColor(\n          `Warning: Unknown architecture '${nodeArch}', defaulting to amd64`,\n          ANSI_COLORS.YELLOW_COLOR,\n        ),\n      );\n      return 'amd64';\n    }\n  }\n}\n\nexport async function linuxSetup(): Promise<void> {\n  const devSetup = new DevSetupHelper();\n\n  // Detect Linux distribution\n  const distro = detectLinuxDistro();\n  console.log(\n    wrapInColor(\n      `Detected distribution: ${distro.name} (${distro.packageManager.name})`,\n      ANSI_COLORS.BLUE_COLOR,\n    ),\n  );\n\n  if (distro.type === LinuxDistroType.UNKNOWN) {\n    console.log();\n    console.log(wrapInColor('Unable to detect Linux distribution.', ANSI_COLORS.YELLOW_COLOR));\n    console.log(\n      wrapInColor(\n        'Please manually install the following dependencies and re-run this command:',\n        ANSI_COLORS.YELLOW_COLOR,\n      ),\n    );\n    console.log('  - git');\n    console.log('  - git-lfs');\n    console.log('  - npm (Node.js)');\n    console.log('  - openjdk-17-jdk (or equivalent Java 17 JDK)');\n    console.log('  - watchman');\n    console.log('  - adb (Android Debug Bridge)');\n    console.log('  - fontconfig development libraries');\n    console.log('  - zlib development libraries');\n    console.log();\n    console.log(\n      wrapInColor(\n        'For manual installation instructions, see: https://github.com/Snapchat/Valdi/blob/main/docs/INSTALL.md',\n        ANSI_COLORS.BLUE_COLOR,\n      ),\n    );\n    throw new Error('Unable to proceed with automatic setup on unknown Linux distribution');\n  }\n\n  const packageMappings = getCommonPackageMappings();\n\n  // Setup git-lfs repository if needed (only for Debian/Ubuntu and RHEL-based)\n  const repoSetupCommand = getGitLfsRepoSetupCommand(distro);\n  if (repoSetupCommand && needsGitLfsRepoSetup(distro)) {\n    try {\n      await devSetup.runShell('Setting up git-lfs repository', [repoSetupCommand]);\n    } catch {\n      console.log(\n        wrapInColor(\n          `Warning: git-lfs repository setup failed. Will try to install git-lfs from standard repositories.`,\n          ANSI_COLORS.YELLOW_COLOR,\n        ),\n      );\n    }\n  }\n\n  // Build list of packages to install\n  const packagesToInstall: string[] = [];\n\n  // Always needed packages\n  if (!checkCommandExists('npm')) {\n    packagesToInstall.push(getPackageName(packageMappings['npm']!, distro));\n  }\n  if (!checkCommandExists('java')) {\n    packagesToInstall.push(getPackageName(packageMappings['openjdk-17']!, distro));\n  }\n  if (!checkCommandExists('git-lfs')) {\n    packagesToInstall.push(getPackageName(packageMappings['git-lfs']!, distro));\n  }\n  if (!checkCommandExists('watchman')) {\n    packagesToInstall.push(getPackageName(packageMappings['watchman']!, distro));\n  }\n  if (!checkCommandExists('adb')) {\n    packagesToInstall.push(getPackageName(packageMappings['adb']!, distro));\n  }\n\n  // Development libraries\n  packagesToInstall.push(\n    getPackageName(packageMappings['fontconfig']!, distro),\n    getPackageName(packageMappings['zlib']!, distro),\n  );\n\n  // Install all packages\n  if (packagesToInstall.length > 0) {\n    const installCommand = buildInstallCommand(packagesToInstall, distro);\n    \n    try {\n      await devSetup.runShell(`Installing dependencies via ${distro.packageManager.name}`, [installCommand]);\n    } catch {\n      console.log();\n      console.log(wrapInColor('Some packages failed to install.', ANSI_COLORS.YELLOW_COLOR));\n      console.log(wrapInColor('Common issues:', ANSI_COLORS.YELLOW_COLOR));\n      \n      if (distro.type === LinuxDistroType.REDHAT) {\n        console.log('  - watchman may require EPEL repository on RHEL-based systems');\n        console.log('    Run: sudo dnf install epel-release (or sudo yum install epel-release)');\n      } else if (distro.type === LinuxDistroType.ARCH) {\n        console.log('  - Some packages may be in the AUR');\n        console.log('    Consider using an AUR helper like yay or paru');\n      }\n      \n      console.log();\n      console.log(wrapInColor('Continuing with setup...', ANSI_COLORS.YELLOW_COLOR));\n    }\n  } else {\n    console.log(wrapInColor('All required packages are already installed.', ANSI_COLORS.GREEN_COLOR));\n  }\n\n  await devSetup.setupGitLfs();\n\n  await devSetup.setupShellAutoComplete();\n\n  // Install libtinfo5 for Debian-based systems (needed for some Android tools)\n  if (distro.type === LinuxDistroType.DEBIAN) {\n    const libtinfoInstalled = checkCommandExists('dpkg') && \n      (() => {\n        try {\n          execSync('dpkg -l libtinfo5', { stdio: 'ignore' });\n          return true;\n        } catch {\n          return false;\n        }\n      })();\n\n    if (!libtinfoInstalled) {\n      try {\n        const arch = getDebianArchitecture();\n        const version = '6.3-2ubuntu0.1';\n        const packageName = `libtinfo5_${version}_${arch}.deb`;\n        const packageUrl = `https://security.ubuntu.com/ubuntu/pool/universe/n/ncurses/${packageName}`;\n        const tempPath = path.join(HOME_DIR, `.valdi/tmp/${packageName}`);\n        \n        // Ensure temp directory exists\n        const tempDir = path.dirname(tempPath);\n        if (!fs.existsSync(tempDir)) {\n          fs.mkdirSync(tempDir, { recursive: true });\n        }\n        \n        console.log(\n          wrapInColor(\n            `Downloading libtinfo5 for ${arch} architecture...`,\n            ANSI_COLORS.BLUE_COLOR,\n          ),\n        );\n        \n        // Download using DevSetupHelper (more robust than wget)\n        await devSetup.downloadToPath(packageUrl, tempPath);\n        \n        // Install the package\n        await devSetup.runShell('Installing libtinfo5 (required for Android tools)', [\n          `sudo apt install -y ${tempPath}`,\n        ]);\n        \n        // Clean up\n        fs.unlinkSync(tempPath);\n      } catch (error) {\n        console.log(\n          wrapInColor(\n            'Warning: libtinfo5 installation failed. Some Android command-line tools may not work.',\n            ANSI_COLORS.YELLOW_COLOR,\n          ),\n        );\n        console.log(\n          wrapInColor(\n            `Details: ${error instanceof Error ? error.message : 'Unknown error'}`,\n            ANSI_COLORS.YELLOW_COLOR,\n          ),\n        );\n        console.log(wrapInColor('You may need to install it manually if you encounter issues.', ANSI_COLORS.YELLOW_COLOR));\n      }\n    }\n  } else if (distro.type === LinuxDistroType.REDHAT) {\n    // For RHEL-based systems, try to install ncurses-compat-libs if available\n    try {\n      await devSetup.runShell('Installing ncurses compatibility libraries (for Android tools)', [\n        buildInstallCommand(['ncurses-compat-libs'], distro),\n      ]);\n    } catch {\n      console.log(\n        wrapInColor(\n          'Warning: ncurses-compat-libs installation failed. Some Android command-line tools may not work.',\n          ANSI_COLORS.YELLOW_COLOR,\n        ),\n      );\n    }\n  }\n\n  const bazeliskPathSuffix = '.valdi/bin/bazelisk';\n  const bazeliskTargetPath = path.join(HOME_DIR, bazeliskPathSuffix);\n  \n  if (fs.existsSync(bazeliskTargetPath)) {\n    console.log(wrapInColor('Bazelisk already installed.', ANSI_COLORS.GREEN_COLOR));\n  } else {\n    await devSetup.downloadToPath(BAZELISK_URL, bazeliskTargetPath);\n\n    // Add executable permission to the downloaded binary\n    const stats = fs.statSync(bazeliskTargetPath);\n    fs.chmodSync(bazeliskTargetPath, stats.mode | 0o111);\n  }\n\n  await devSetup.writeEnvVariablesToRcFile([{ name: 'PATH', value: `\"$HOME/.valdi/bin:$PATH\"` }]);\n\n  await devSetup.setupAndroidSDK(ANDROID_LINUX_COMMANDLINE_TOOLS);\n\n  devSetup.onComplete();\n}\n"
  },
  {
    "path": "npm_modules/cli/src/setup/macOSSetup.ts",
    "content": "import fs from 'fs';\nimport { CliError } from '../core/errors';\nimport { checkCommandExists, runCliCommand } from '../utils/cliUtils';\nimport { DevSetupHelper } from './DevSetupHelper';\nimport { ANDROID_MACOS_COMMANDLINE_TOOLS } from './versions';\n\nexport async function macOSSetup(): Promise<void> {\n  const devSetup = new DevSetupHelper();\n\n  // Check if xcode-select command exists\n  if (!checkCommandExists('xcode-select')) {\n    throw new CliError(\n      'Xcode command line tools are not installed.\\n\\n' +\n        'Please install Xcode from the App Store, then run:\\n' +\n        '  sudo xcode-select -s /Applications/Xcode.app\\n\\n' +\n        'After installation, run valdi dev_setup again.',\n    );\n  }\n\n  // Verify Xcode is properly configured\n  try {\n    const xcodePathResult = await runCliCommand('xcode-select -p');\n    const xcodePath = xcodePathResult.stdout.trim();\n\n    if (!xcodePath || !fs.existsSync(xcodePath)) {\n      throw new CliError(\n        'Xcode command line tools path is not configured correctly.\\n\\n' +\n          'Please run:\\n' +\n          '  sudo xcode-select -s /Applications/Xcode.app\\n\\n' +\n          'Or if you have Xcode with a different name (e.g., beta versions):\\n' +\n          '  sudo xcode-select -s /Applications/YourXcode.app\\n\\n' +\n          'After configuration, run valdi dev_setup again.',\n      );\n    }\n\n    // Extract Xcode.app path from the Developer path\n    const xcodeAppPath = xcodePath.replace(/\\/Contents\\/Developer\\/?$/, '');\n    \n    // Verify the Xcode app exists\n    if (!fs.existsSync(xcodeAppPath) || !xcodeAppPath.includes('Xcode')) {\n      throw new CliError(\n        'Xcode installation not found.\\n\\n' +\n          `xcode-select points to ${xcodePath}\\n` +\n          `but Xcode app not found at ${xcodeAppPath}\\n\\n` +\n          'Please install Xcode from the App Store:\\n' +\n          '  https://apps.apple.com/us/app/xcode/id497799835\\n\\n' +\n          'Then configure it with:\\n' +\n          '  sudo xcode-select -s /Applications/Xcode.app\\n\\n' +\n          'After installation, run valdi dev_setup again.',\n      );\n    }\n  } catch (error) {\n    if (error instanceof CliError) {\n      throw error;\n    }\n    throw new CliError(\n      'Failed to verify Xcode installation.\\n\\n' +\n        'Please ensure Xcode is installed from the App Store and properly configured:\\n' +\n        '  sudo xcode-select -s /Applications/Xcode.app\\n\\n' +\n        'After setup, run valdi dev_setup again.',\n    );\n  }\n\n  if (!checkCommandExists('brew')) {\n    await devSetup.runShell('Homebrew not found. Installing', [\n      '/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"',\n    ]);\n\n    // Configure Homebrew PATH in .zprofile\n    const homeDir = process.env['HOME'] ?? '';\n    const zprofilePath = `${homeDir}/.zprofile`;\n    const brewShellenvLine = 'eval \"$(/opt/homebrew/bin/brew shellenv)\"';\n    \n    try {\n      let zprofileContent = '';\n      if (fs.existsSync(zprofilePath)) {\n        zprofileContent = fs.readFileSync(zprofilePath, 'utf8');\n      }\n      \n      if (!zprofileContent.includes(brewShellenvLine)) {\n        const newContent = zprofileContent + '\\n' + brewShellenvLine + '\\n';\n        fs.writeFileSync(zprofilePath, newContent, 'utf8');\n        console.log('Added Homebrew to PATH in .zprofile');\n      }\n    } catch {\n      console.log('Note: Could not automatically configure Homebrew PATH in .zprofile');\n    }\n  }\n\n  // Install dependencies, skipping already installed ones\n  const packages = ['npm', 'bazelisk', 'openjdk@17', 'temurin', 'git-lfs', 'watchman', 'ios-webkit-debug-proxy'];\n  const packagesToInstall: string[] = [];\n  \n  for (const pkg of packages) {\n    try {\n      // Check if package is already installed (from any tap)\n      const result = await runCliCommand(`brew list ${pkg}`);\n      if (result.returnCode !== 0) {\n        packagesToInstall.push(pkg);\n      }\n    } catch {\n      // Package not installed, add to list\n      packagesToInstall.push(pkg);\n    }\n  }\n  \n  if (packagesToInstall.length > 0) {\n    await devSetup.runShell(\n      `Installing dependencies from Homebrew (${packagesToInstall.length}/${packages.length})`,\n      [`brew install ${packagesToInstall.join(' ')}`]\n    );\n  } else {\n    console.log('All Homebrew dependencies are already installed');\n  }\n\n  await devSetup.setupGitLfs();\n\n  await devSetup.setupShellAutoComplete();\n\n  // Check if JDK symlink exists and points to the correct location\n  const jdkSymlinkPath = '/Library/Java/JavaVirtualMachines/openjdk-17.jdk';\n  const jdkSourcePath = '/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk';\n  \n  let needsJdkSymlink = false;\n  if (fs.existsSync(jdkSymlinkPath)) {\n    try {\n      const linkTarget = fs.readlinkSync(jdkSymlinkPath);\n      if (linkTarget !== jdkSourcePath) {\n        needsJdkSymlink = true;\n      }\n    } catch {\n      // Not a symlink or can't read it, needs to be set up\n      needsJdkSymlink = true;\n    }\n  } else {\n    needsJdkSymlink = true;\n  }\n  \n  if (needsJdkSymlink) {\n    console.log('\\nSetting up JDK symlink (requires admin password)...');\n    await devSetup.runShell('Setting up JDK', [\n      'sudo ln -sfn /opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-17.jdk',\n    ]);\n  }\n\n  await devSetup.writeEnvVariablesToRcFile([\n    { name: 'PATH', value: '\"/opt/homebrew/opt/openjdk@17/bin:$PATH\"' },\n    { name: 'JAVA_HOME', value: '`/usr/libexec/java_home -v 17`' },\n  ]);\n\n  const javaHome = await runCliCommand('/usr/libexec/java_home');\n\n  await devSetup.setupAndroidSDK(ANDROID_MACOS_COMMANDLINE_TOOLS, javaHome.stdout.trim());\n\n  devSetup.onComplete();\n}\n"
  },
  {
    "path": "npm_modules/cli/src/setup/setupEntryPoint.ts",
    "content": "import { ANSI_COLORS } from '../core/constants';\nimport { wrapInColor } from '../utils/logUtils';\nimport { linuxSetup } from './linuxSetup';\nimport { macOSSetup } from './macOSSetup';\n\nenum OSType {\n  MACOS = 'macos',\n  WINDOWS = 'windows',\n  LINUX = 'linux',\n  UNKNOWN = 'unknown',\n}\n\nfunction getOSType(): OSType {\n  switch (process.platform) {\n    case 'darwin': {\n      return OSType.MACOS;\n    }\n    case 'win32': {\n      return OSType.WINDOWS;\n    }\n    case 'linux': {\n      return OSType.LINUX;\n    }\n    default: {\n      return OSType.UNKNOWN;\n    }\n  }\n}\n\nexport async function beginEnvironmentSetup(): Promise<number> {\n  const os = getOSType();\n  const returnCode = 0;\n\n  switch (os) {\n    case OSType.MACOS: {\n      console.log(wrapInColor('Setting up development environment for MacOS...', ANSI_COLORS.BLUE_COLOR));\n      await macOSSetup();\n      break;\n    }\n    case OSType.WINDOWS: {\n      console.log(wrapInColor('Windows is not a supported operating system...aborting...', ANSI_COLORS.RED_COLOR));\n      return 1;\n    }\n    case OSType.LINUX: {\n      console.log(wrapInColor('Setting up development environment for Linux...', ANSI_COLORS.BLUE_COLOR));\n      await linuxSetup();\n      break;\n    }\n    default: {\n      console.log(\n        wrapInColor(\n          'Could not determine current operating system, skipping automated environment setup...',\n          ANSI_COLORS.RED_COLOR,\n        ),\n      );\n      console.log(\n        'Please see https://github.com/Snapchat/Valdi/blob/main/docs/INSTALL.md for manual setup instructions.',\n      );\n      return 1;\n    }\n  }\n\n  return returnCode;\n}\n"
  },
  {
    "path": "npm_modules/cli/src/setup/versions.ts",
    "content": "export const ANDROID_BUILD_TOOLS_VERSION = '34.0.0';\nexport const ANDROID_NDK_VERSION = '25.2.9519653';\nexport const ANDROID_PLATFORM_VERSION = 'android-36';\n\nexport const ANDROID_MACOS_COMMANDLINE_TOOLS =\n  'https://dl.google.com/android/repository/commandlinetools-mac-13114758_latest.zip';\nexport const ANDROID_LINUX_COMMANDLINE_TOOLS =\n  'https://dl.google.com/android/repository/commandlinetools-linux-13114758_latest.zip';\n"
  },
  {
    "path": "npm_modules/cli/src/utils/ArgumentsResolver.ts",
    "content": "export class ArgumentsResolver<Args> {\n  additionalResolvedArguments: Partial<Args> = {};\n\n  constructor(readonly args: Args) {}\n\n  getArgument<K extends keyof Args>(key: K): Args[K] {\n    return this.args[key];\n  }\n\n  async getArgumentOrResolve<K extends keyof Args>(\n    key: K,\n    resolve: () => Promise<NonNullable<Args[K]>>,\n  ): Promise<NonNullable<Args[K]>> {\n    const value = this.args[key];\n    if (value) {\n      return value;\n    }\n\n    const resolved = await resolve();\n    this.additionalResolvedArguments[key] = resolved;\n    return resolved;\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/BazelClient.ts",
    "content": "import type { StdioOptions } from 'child_process';\nimport path from 'path';\nimport { ANSI_COLORS, BAZEL_BIN_ENV, BAZEL_EXECUTABLES } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport { Digraph } from './Digraph';\nimport { LoadingIndicator } from './LoadingIndicator';\nimport type { CommandResult } from './cliUtils';\nimport { checkCommandExists, runCliCommand, spawnCliCommand } from './cliUtils';\nimport { wrapInColor } from './logUtils';\n\nconst BAZEL_QUIET_OPTIONS = '--noshow_progress --noshow_loading_progress --ui_event_filters=-info,-progress';\nconst BAZEL_PREFIXED_OPTIONS = '--max_idle_secs=5';\nconst BAZEL_POSTFIXED_OPTIONS = '--color=yes';\nconst DEFAULT_STDIO_MODE: StdioOptions = ['pipe', 'pipe', 'inherit'];\n\nlet cached_bazel_executable: string | undefined;\n\nfunction getBazelCli(): string {\n  if (!cached_bazel_executable) {\n    const bazelBinEnv = process.env[BAZEL_BIN_ENV];\n    if (bazelBinEnv) {\n      cached_bazel_executable = bazelBinEnv;\n      return bazelBinEnv;\n    }\n\n    const found = BAZEL_EXECUTABLES.find(element => checkCommandExists(element));\n    if (!found) {\n      throw new Error('Could not find bazel executable (bzl or bazel)');\n    }\n    cached_bazel_executable = found;\n  }\n\n  return cached_bazel_executable;\n}\n\nfunction getBazelCommandString(baseCommand: string, extraArgs: string, quiet: boolean): string {\n  return `${getBazelCli()} ${BAZEL_PREFIXED_OPTIONS} ${baseCommand} ${extraArgs} ${quiet ? BAZEL_QUIET_OPTIONS : ''} ${BAZEL_POSTFIXED_OPTIONS}`.trim();\n}\n\nfunction escapeQuery(str: string): string {\n  return str.replaceAll('\"', '\\\\\"');\n}\n\nexport class BazelLabel {\n  constructor(\n    readonly repo: string | undefined,\n    readonly target: string,\n    readonly name: string | undefined,\n  ) {}\n\n  static fromString(str: string): BazelLabel {\n    let repo: string | undefined;\n    if (str.startsWith('@')) {\n      const slashSlashIndex = str.indexOf('//');\n      if (slashSlashIndex <= 0) {\n        throw new Error(`Expected // after repo name (got ${str})`);\n      }\n\n      repo = str.slice(1, slashSlashIndex);\n      str = str.slice(slashSlashIndex);\n    }\n    if (str.endsWith('/')) {\n      str = str.slice(0, -1);\n    }\n\n    const separatorIndex = str.indexOf(':');\n    if (separatorIndex >= 0) {\n      const target = str.slice(0, separatorIndex);\n      const name = str.slice(separatorIndex + 1);\n      return new BazelLabel(repo, target, name);\n    } else {\n      return new BazelLabel(repo, str, undefined);\n    }\n  }\n\n  toString(): string {\n    const repoPrefix = this.repo ? `@${this.repo}` : '';\n    if (this.name) {\n      return `${repoPrefix}${this.target}:${this.name}`;\n    } else {\n      return repoPrefix + this.target;\n    }\n  }\n}\n\nclass BazelCommandCache {\n  private cache = new Map<string, Promise<string>>();\n\n  constructor(readonly execute: (arg: string) => Promise<string>) {}\n\n  get(args: string): Promise<string> {\n    const existingPromise = this.cache.get(args);\n    if (existingPromise) {\n      return existingPromise;\n    }\n\n    const ret = this.execute(args);\n    this.cache.set(args, ret);\n\n    return ret;\n  }\n}\n\nexport class BazelClient {\n  private workspaceRootCache: BazelCommandCache;\n  private executionRootCache: BazelCommandCache;\n\n  constructor() {\n    this.workspaceRootCache = new BazelCommandCache(async () => {\n      return this.runCommandAndGetTrimmedStdOut('info workspace');\n    });\n\n    this.executionRootCache = new BazelCommandCache(async () => {\n      return this.runCommandAndGetTrimmedStdOut('info execution_root');\n    });\n  }\n\n  async resolveLabel(str: string): Promise<BazelLabel> {\n    const unresolvedLabel = BazelLabel.fromString(str);\n\n    const requiresResolve = unresolvedLabel.target.split('/').includes('..');\n    if (!requiresResolve) {\n      return unresolvedLabel;\n    }\n\n    const resolvedTarget = await this.resolveTarget(unresolvedLabel.target);\n    return new BazelLabel(unresolvedLabel.repo, resolvedTarget, unresolvedLabel.name);\n  }\n\n  async getWorkspaceRoot(): Promise<string> {\n    return this.workspaceRootCache.get(process.cwd());\n  }\n\n  async getExecutionRoot(): Promise<string> {\n    return this.executionRootCache.get(process.cwd());\n  }\n\n  async queryTargetsForKinds(kinds: string[]): Promise<string[]> {\n    const command = `query \"kind(${kinds.join('|')}, //...)\"`;\n\n    const { stdout: targetStrings } = await this.spawnCommand(command);\n    const targets = targetStrings.split('\\n').filter(target => target.length > 0);\n\n    return targets;\n  }\n\n  async queryTargetsForTag(kind: string): Promise<string[]> {\n    const command = `query 'attr(\"tags\", \"${kind}\", //...)'`;\n\n    const { stdout: targetStrings } = await this.spawnCommand(command);\n    const targets = targetStrings.split('\\n').filter(target => target.length > 0);\n\n    return targets;\n  }\n\n  async query(queryStr: string): Promise<string[]> {\n    const command = `query \"${escapeQuery(queryStr)}\"`;\n    return await this.runCommandWithLinesOutput(command);\n  }\n\n  async graphQuery(queryStr: string): Promise<Digraph> {\n    const command = `query \"${escapeQuery(queryStr)}\"  --output=graph`;\n    const { stdout } = await this.runCommand(command);\n\n    return Digraph.parse(stdout.trim());\n  }\n\n  async queryBuildOutputs(targets: readonly string[], extraArgs: string = ''): Promise<string[]> {\n    const command = `cquery 'set(${targets.join(' ')})' --output files ${extraArgs}`;\n    const lines = await this.runCommandWithLinesOutput(command);\n    return lines.sort();\n  }\n\n  async buildTarget(target: string, extraArgs: string = ''): Promise<CommandResult> {\n    // Use 'inherit' as the stdio mode by default as usually the output irrelevant\n    // and only the success/failure matters\n    const commandBuildTarget = `build ${target} ${extraArgs}`;\n\n    return await this.spawnCommand(commandBuildTarget, 'inherit').catch(() => {\n      throw new CliError(`Failed to build target: ${target}`);\n    });\n  }\n\n  async buildTargets(targets: readonly string[]): Promise<CommandResult> {\n    // Use 'inherit' as the stdio mode by default as usually the output irrelevant\n    // and only the success/failure matters\n\n    const allTargets = targets.join(' ');\n    const commandBuildTarget = `build ${allTargets} --show_result=${targets.length}`;\n\n    return await this.spawnCommand(commandBuildTarget, 'inherit').catch(() => {\n      throw new CliError(`Failed to build targets: ${targets.join(' ')}`);\n    });\n  }\n\n  async runTarget(target: string, extraArgs: string = ''): Promise<CommandResult> {\n    const commandBuildTarget = `run ${target} ${extraArgs}`;\n\n    return await this.spawnCommand(commandBuildTarget, 'inherit').catch(() => {\n      throw new CliError(`Failed to run target: ${target}`);\n    });\n  }\n\n  // Run bazel query for targets matching queryKind and filtered to match any of the specified\n  // filters.\n  async queryTargetsByKindWithFilter(\n    queryKind: string,\n    filters?: string[],\n    stdioMode = DEFAULT_STDIO_MODE,\n  ): Promise<string[]> {\n    let command = `query \"kind(${queryKind}, //...)\"`;\n\n    if (filters !== undefined && filters.length > 0) {\n      const filtersString = filters.join('|');\n      command = `query 'filter(\"${filtersString}\", kind(\"${queryKind}\", //...))'`;\n    }\n\n    return await this.spawnCommand(command, stdioMode).then(result => {\n      const targets = result.stdout.split('\\n').filter(target => target.length > 0);\n      return targets;\n    });\n  }\n\n  async testTargets(targets: string[], extraArgs: string = ''): Promise<CommandResult> {\n    const targetsString = targets.join(' ');\n    const commandTestTarget = `test ${targetsString} ${extraArgs}`;\n\n    return await this.spawnCommand(commandTestTarget, 'inherit', extraArgs).catch(() => {\n      throw new CliError(`Failed to test targets: ${targetsString}`);\n    });\n  }\n\n  async getVersion(): Promise<[number, string, string]> {\n    const commandBazelInfoVersion = `version --gnu_format`;\n    const {\n      returnCode: returnCode,\n      stdout: versionInfo,\n      stderr: error,\n    } = await this.runCommand(commandBazelInfoVersion);\n\n    return [returnCode, versionInfo.trim(), String(error)];\n  }\n\n  private async runCommandWithLinesOutput(command: string): Promise<string[]> {\n    const { stdout: outputStrings } = await this.runCommand(command);\n    return outputStrings.split('\\n').filter(output => output.length > 0);\n  }\n\n  private async runCommandAndGetTrimmedStdOut(command: string): Promise<string> {\n    const { stdout: root } = await this.runCommand(command);\n\n    return root.trim();\n  }\n\n  private runCommand(command: string): Promise<CommandResult> {\n    const commandWithOptions = getBazelCommandString(command, '', false);\n    return LoadingIndicator.fromTask(runCliCommand(commandWithOptions, undefined, true))\n      .setText(`${wrapInColor('Running Bazel command:', ANSI_COLORS.YELLOW_COLOR)} ${getBazelCli()} ${command}`)\n      .show();\n  }\n\n  private async spawnCommand(\n    command: string,\n    stdioMode: StdioOptions = DEFAULT_STDIO_MODE,\n    extraArgs: string = '',\n  ): Promise<CommandResult> {\n    const commandWithOptions = getBazelCommandString(command, extraArgs, false);\n    console.log(\n      `${wrapInColor('Running Bazel command:', ANSI_COLORS.YELLOW_COLOR)} ${getBazelCli()} ${command} ${extraArgs}`,\n    );\n    return await spawnCliCommand(commandWithOptions, undefined, stdioMode, true, true);\n  }\n\n  private async resolveTarget(pathStr: string): Promise<string> {\n    const absolutePath = path.resolve(pathStr);\n    const root = await this.getWorkspaceRoot();\n    if (!absolutePath.startsWith(root)) {\n      throw new Error(\n        `Could not resolve target at relative path, found Bazel workspace root at '${root}', resolved target path at ${absolutePath}`,\n      );\n    }\n\n    return '/' + absolutePath.slice(root.length);\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/Digraph.ts",
    "content": "export interface DigraphNode {\n  name: string;\n  edges: DigraphNode[];\n}\n\nfunction unquote(str: string): string {\n  return str.slice(1, -1);\n}\n\nexport class Digraph {\n  private nodeByName = new Map<string, DigraphNode>();\n  private _allNodes: DigraphNode[] = [];\n\n  constructor() {}\n\n  get nodes(): readonly DigraphNode[] {\n    return this._allNodes;\n  }\n\n  static parse(str: string): Digraph {\n    const lines = str.split('\\n');\n    const graph = new Digraph();\n\n    let index = 0;\n    for (const line of lines) {\n      const trimmedLine = line.trim();\n      if (trimmedLine.startsWith('digraph ')) {\n        if (index !== 0) {\n          this.throwInvalidGraph();\n        }\n      } else if (trimmedLine === '}') {\n        if (index !== lines.length - 1) {\n          this.throwInvalidGraph();\n        }\n      } else if (trimmedLine.startsWith('node ')) {\n          // no-op\n      } else if (trimmedLine.startsWith('\"')) {\n          const edgeIndex = trimmedLine.indexOf('->');\n          if (edgeIndex >= 0) {\n            const fromEdge = unquote(trimmedLine.slice(0, edgeIndex).trim());\n            const toEdge = unquote(trimmedLine.slice(edgeIndex + 2).trim());\n            graph.addEdge(fromEdge, toEdge);\n          } else {\n            graph.getOrCreateNode(unquote(trimmedLine))\n          }\n      } else {\n        this.throwInvalidGraph();\n      }\n\n      index++;\n    }\n\n    return graph;\n  }\n\n  private static throwInvalidGraph(): never {\n    throw new Error('Could not parse digraph');\n  }\n\n  getNode(name: string): DigraphNode | undefined {\n    return this.nodeByName.get(name);\n  }\n\n  getOrCreateNode(name: string): DigraphNode {\n    let node = this.nodeByName.get(name);\n    if (!node) {\n      node = { name, edges: [] };\n      this.nodeByName.set(name, node);\n      this._allNodes.push(node);\n    }\n\n    return node;\n  }\n\n  addEdge(from: string, to: string): void {\n    const fromNode = this.getOrCreateNode(from);\n    const toNode = this.getOrCreateNode(to);\n\n    fromNode.edges.push(toNode);\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/LoadingIndicator.ts",
    "content": "// We use dynamic imports here because ora uses\n// the ES6 import syntax, which cannot be fixed\n// with require() style imports on older node js versions.\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports, @typescript-eslint/no-implied-eval\nconst ora = new Function(\"return import('ora')\") as () => Promise<typeof import('ora')>;\n\nexport class LoadingIndicator<T> {\n  private text = '';\n  private successText: string | undefined;\n  private failureText: string | undefined;\n\n  constructor(private readonly runnable: () => PromiseLike<T>) {}\n\n  static fromTask<T>(task: PromiseLike<T>): LoadingIndicator<T> {\n    return new LoadingIndicator<T>(() => task);\n  }\n\n  setText(text: string): LoadingIndicator<T> {\n    this.text = text;\n    return this;\n  }\n\n  setSuccessText(successText: string): LoadingIndicator<T> {\n    this.successText = successText;\n    return this;\n  }\n\n  setFailureText(failureText: string): LoadingIndicator<T> {\n    this.failureText = failureText;\n    return this;\n  }\n\n  show(): Promise<T> {\n    return ora().then(ora => {\n      return ora.oraPromise(this.runnable(), {\n        text: this.text,\n        successText: this.successText,\n        failText: this.failureText,\n      });\n    });\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/applicationUtils.ts",
    "content": "import path from 'path';\nimport type { Argv } from 'yargs';\nimport {\n  ANDROID_ARM64_BUILD_FLAGS,\n  ANDROID_ARMV7_BUILD_FLAGS,\n  ANDROID_BAZEL_APPLICATION_TAG,\n  ANDROID_BUILD_FLAGS,\n  ANDROID_EXPORTED_LIBRARY_TAG,\n  ANDROID_X86_64_BUILD_FLAGS,\n  ANSI_COLORS,\n  Architecture,\n  CLI_BAZEL_APPLICATION_TAG,\n  CLI_BUILD_FLAGS,\n  DEBUG_BUILD_FLAGS,\n  ENABLE_RUNTIME_LOGS_BUILD_FLAGS,\n  ENABLE_RUNTIME_TRACES_BUILD_FLAGS,\n  IOS_BAZEL_APPLICATION_TAG,\n  IOS_BUILD_FLAGS,\n  IOS_DEVICE_BUILD_FLAGS,\n  IOS_EXPORTED_LIBRARY_TAG,\n  MACOS_BAZEL_APPLICATION_TAG,\n  MACOS_BUILD_FLAGS,\n  PLATFORM,\n  RELEASE_BUILD_FLAGS,\n  VALID_PLATFORMS,\n} from '../core/constants';\nimport { CliError } from '../core/errors';\nimport type { BazelClient } from './BazelClient';\nimport type { CliChoice } from './cliUtils';\nimport { getUserChoice } from './cliUtils';\nimport { wrapInColor } from './logUtils';\n\nexport interface SharedCommandParameters {\n  platform: string | undefined;\n  bazel_args: string | undefined;\n  build_config: 'debug' | 'release';\n  enable_runtime_logs: boolean | undefined;\n  enable_runtime_traces: boolean | undefined;\n}\n\nexport function makeArgsBuilder<T extends SharedCommandParameters>(\n  nestedBuilder: (yargs: Argv<T>) => void,\n): (yargs: Argv<T>) => void {\n  return yargs => {\n    yargs\n      .positional('platform', {\n        describe: 'Platform to build the library or application for: <ios|android>',\n        type: 'string',\n        choices: VALID_PLATFORMS,\n        coerce: arg => {\n          return arg === undefined ? undefined : String(arg).toLowerCase();\n        },\n      })\n      .option('build_config', {\n        describe: 'Specifiy whether the application or library should be built in release or debug mode',\n        type: 'string',\n        choices: ['debug', 'release'],\n        default: 'debug',\n        requiresArg: true,\n      })\n      .option('enable_runtime_logs', {\n        describe: 'Specifiy Valdi runtime logs should be enabled',\n        type: 'boolean',\n        default: false,\n      })\n      .option('enable_runtime_traces', {\n        describe: 'Specifiy Valdi runtime traces should be enabled',\n        type: 'boolean',\n        default: false,\n      })\n      .option('bazel_args', {\n        describe: `Additional arguments to pass to bazel build. Use format ${wrapInColor('--bazel_args=\"<args>\"', ANSI_COLORS.YELLOW_COLOR)}.`,\n        type: 'string',\n        requiresArg: true,\n      });\n\n    nestedBuilder(yargs);\n  };\n}\n\nexport async function selectBazelTarget(\n  bazel: BazelClient,\n  tag: string,\n  targetTypeName: string,\n  promptText: string,\n): Promise<string> {\n  const unfilteredAvailableTargets = await bazel.queryTargetsForTag(tag);\n  const availableTargets = unfilteredAvailableTargets.filter(c => !c.endsWith('_DO_NOT_USE'));\n\n  if (availableTargets.length === 0) {\n    throw new CliError(`No ${targetTypeName} targets found...`);\n  } else if (availableTargets.length === 1) {\n    console.log(\n      `Only one ${targetTypeName} target found, using it:`,\n      wrapInColor(availableTargets[0], ANSI_COLORS.GREEN_COLOR),\n    );\n\n    return availableTargets[0] ?? '';\n  }\n\n  // Prompt user to select an application target\n  const choices: Array<CliChoice<string>> = availableTargets.map((target, index) => ({\n    name: `${index + 1}. ${target}`,\n    value: target,\n  }));\n\n  return await getUserChoice(choices, promptText);\n}\n\nexport function getApplicationTargetTagForPlatform(platform: PLATFORM): string {\n  switch (platform) {\n    case PLATFORM.IOS: {\n      return IOS_BAZEL_APPLICATION_TAG;\n    }\n    case PLATFORM.ANDROID: {\n      return ANDROID_BAZEL_APPLICATION_TAG;\n    }\n    case PLATFORM.MACOS: {\n      return MACOS_BAZEL_APPLICATION_TAG;\n    }\n    case PLATFORM.CLI: {\n      return CLI_BAZEL_APPLICATION_TAG;\n    }\n  }\n}\n\nexport function getExportedLibraryTargetTagForPlatform(platform: PLATFORM): string {\n  switch (platform) {\n    case PLATFORM.IOS: {\n      return IOS_EXPORTED_LIBRARY_TAG;\n    }\n    case PLATFORM.ANDROID: {\n      return ANDROID_EXPORTED_LIBRARY_TAG;\n    }\n    case PLATFORM.MACOS: {\n      throw new CliError('Exported library is not yet supported for macOS platform');\n    }\n    case PLATFORM.CLI: {\n      throw new CliError('Exported library is not supported for CLI platform');\n    }\n  }\n}\n\nexport function applicationExtensionForPlatform(platform: PLATFORM): string {\n  switch (platform) {\n    case PLATFORM.IOS: {\n      return '.ipa';\n    }\n    case PLATFORM.ANDROID: {\n      return '.apk';\n    }\n    case PLATFORM.MACOS: {\n      return '.zip';\n    }\n    case PLATFORM.CLI: {\n      return '';\n    }\n  }\n}\n\nexport function exportedLibraryExtensionForPlatform(platform: PLATFORM): string {\n  switch (platform) {\n    case PLATFORM.IOS: {\n      return '.xcframework';\n    }\n    case PLATFORM.ANDROID: {\n      return '.aar';\n    }\n    case PLATFORM.MACOS: {\n      return '.zip';\n    }\n    case PLATFORM.CLI: {\n      return '.zip';\n    }\n  }\n}\n\n// Reads and selects the output path for the build & install\nexport async function getOutputFilePath(\n  bazel: BazelClient,\n  expectedExtension: string,\n  target: string,\n  bazelArgs: string = '',\n): Promise<string> {\n  const workspaceRootResult = await bazel.getWorkspaceRoot();\n  const buildOutputsResult = await bazel.queryBuildOutputs([target], bazelArgs);\n\n  // TODO(yhuang6): Have a way to prompt for selection and memorize it and/or\n  //  add an option to specify name of apk.\n  let appChoices = buildOutputsResult;\n  if (expectedExtension.length > 0) {\n    appChoices = buildOutputsResult.filter(\n      output => output.endsWith(expectedExtension) && !output.includes('_unsigned'),\n    );\n  }\n\n  let outputPath;\n  if (appChoices.length === 0) {\n    throw new CliError('No outputs are found...');\n  } else if (appChoices.length === 1) {\n    outputPath = appChoices[0];\n  } else {\n    outputPath = await getUserChoice(\n      appChoices.map((output, index) => ({ name: `${index + 1}. ${output}`, value: output })),\n      'Please select the app to install:',\n    );\n  }\n\n  return outputPath === undefined ? '' : path.join(workspaceRootResult, outputPath);\n}\n\nfunction androidBuildFlagsForArchitecture(architecture: Architecture): readonly string[] {\n  switch (architecture) {\n    case Architecture.ARM64: {\n      return ANDROID_ARM64_BUILD_FLAGS;\n    }\n    case Architecture.ARMV7: {\n      return ANDROID_ARMV7_BUILD_FLAGS;\n    }\n    case Architecture.X86_64: {\n      return ANDROID_X86_64_BUILD_FLAGS;\n    }\n  }\n}\n\nexport function resolveBazelBuildArgs(\n  platform: PLATFORM,\n  buildConfig: 'debug' | 'release' | undefined,\n  architectures: Architecture[],\n  forDevice: boolean,\n  enableRuntimeLogs: boolean | undefined,\n  enableRuntimeTracing: boolean | undefined,\n  additionalBazelArgs: string | undefined,\n): string {\n  const allArgs: string[] = [];\n\n  if (buildConfig === 'release') {\n    allArgs.push(...RELEASE_BUILD_FLAGS);\n  } else {\n    allArgs.push(...DEBUG_BUILD_FLAGS);\n  }\n\n  if (enableRuntimeLogs) {\n    allArgs.push(...ENABLE_RUNTIME_LOGS_BUILD_FLAGS);\n  }\n  if (enableRuntimeTracing) {\n    allArgs.push(...ENABLE_RUNTIME_TRACES_BUILD_FLAGS);\n  }\n\n  if (platform === PLATFORM.IOS) {\n    allArgs.push(IOS_BUILD_FLAGS);\n\n    if (forDevice) {\n      allArgs.push(IOS_DEVICE_BUILD_FLAGS);\n    }\n  }\n\n  if (platform === PLATFORM.CLI) {\n    allArgs.push(...CLI_BUILD_FLAGS);\n  } else if (platform === PLATFORM.MACOS) {\n    allArgs.push(...MACOS_BUILD_FLAGS);\n  }\n\n  if (platform === PLATFORM.ANDROID) {\n    allArgs.push(...ANDROID_BUILD_FLAGS);\n\n    for (const architecture of architectures) {\n      allArgs.push(...androidBuildFlagsForArchitecture(architecture));\n    }\n  }\n\n  if (additionalBazelArgs) {\n    allArgs.push(additionalBazelArgs);\n  }\n  return allArgs.join(' ');\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/buildInfo.ts",
    "content": "import Separator from \"inquirer/lib/objects/separator\";\nimport { ALL_ARCHITECTURES, ANSI_COLORS, Architecture, PLATFORM } from \"../core/constants\";\nimport { CliError } from \"../core/errors\";\nimport { getApplicationTargetTagForPlatform, resolveBazelBuildArgs, selectBazelTarget, SharedCommandParameters } from \"./applicationUtils\";\nimport { ArgumentsResolver } from \"./ArgumentsResolver\";\nimport { CliChoice, getUserChoice } from \"./cliUtils\";\nimport { getAllArchitecturesForAndroid, getArchitectureForAndroidDevice, getConnectedDevices } from \"./deviceUtils\";\nimport { wrapInColor } from \"./logUtils\";\nimport { BazelClient } from \"./BazelClient\";\n\nexport interface BuildInfo {\n    platform: PLATFORM;\n    application: string;\n    bazelArgs: string; \n    selectedDevice: string | undefined\n}\n\nexport interface CommandParameters extends SharedCommandParameters {\n  application: string | undefined;\n  device_id: string | undefined;\n  target_output_path: string | undefined;\n  simulator: boolean | undefined;\n}\n\n// Prompts User to choose from the list of available devices\n// No prompt if only one device is available\nasync function getDeviceChoice(platform: string): Promise<string> {\n  const availableDevices = await getConnectedDevices(platform);\n\n  if (availableDevices.length === 0) {\n    throw new CliError('No devices connected...');\n  } else if (availableDevices.length === 1) {\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    const selectedDevice: string = availableDevices[0]!;\n    console.log('Only one device connected, using it:', wrapInColor(selectedDevice, ANSI_COLORS.GREEN_COLOR));\n    return selectedDevice;\n  }\n\n  // Prompt user to select a device\n  const choices: Array<CliChoice<string> | Separator> = [];\n\n  if (platform === PLATFORM.ANDROID) {\n    choices.push(new Separator('-----Android Devices-----'));\n  } else if (platform === PLATFORM.IOS) {\n    choices.push(new Separator('-----iOS Devices-----'));\n  }\n  choices.push(...availableDevices.map(device => ({ name: device, value: device })));\n\n  return await getUserChoice(choices, 'Please select a device to perform the install:');\n}\n\nexport async function getBuildInfo(argv: ArgumentsResolver<CommandParameters>, bazel: BazelClient, checkDevice: boolean): Promise<BuildInfo> {\n  const platform = argv.getArgument('platform') as PLATFORM;\n  const forDevice = !!argv.getArgument('simulator');\n\n  let selectedDevice: string | undefined;\n  let architectures: Architecture[] = ALL_ARCHITECTURES;\n\n  if (platform === PLATFORM.ANDROID) {\n    if (checkDevice) {\n        selectedDevice = await argv.getArgumentOrResolve('device_id', () => {\n        console.log('Detecting Connected Devices...');\n        return getDeviceChoice(platform);\n        });\n        architectures = [await getArchitectureForAndroidDevice(selectedDevice)];\n    } else {\n        architectures = getAllArchitecturesForAndroid();\n    }\n  }\n\n  const bazelArgs = resolveBazelBuildArgs(\n    platform,\n    argv.getArgument('build_config'),\n    architectures,\n    forDevice,\n    argv.getArgument('enable_runtime_logs'),\n    argv.getArgument('enable_runtime_traces'),\n    argv.getArgument('bazel_args'),\n  );\n\n  // Application Selection\n  // ---------------------\n  const application = await argv.getArgumentOrResolve('application', () => {\n    console.log('No application specified querying available targets...');\n    return selectBazelTarget(\n      bazel,\n      getApplicationTargetTagForPlatform(platform),\n      'valdi_application',\n      'Please select an application target to install:',\n    );\n  });\n\n  return {\n    platform: platform,\n    application: application,\n    bazelArgs: bazelArgs,\n    selectedDevice: selectedDevice,\n  };\n}"
  },
  {
    "path": "npm_modules/cli/src/utils/byString.ts",
    "content": "export function byString<T>(selector: (v: T) => string): (l: T, r: T) => number {\n  return (l, r) => selector(l).localeCompare(selector(r));\n}"
  },
  {
    "path": "npm_modules/cli/src/utils/cliUtils.ts",
    "content": "import type { StdioOptions } from 'child_process';\nimport { exec, execSync, spawn } from 'child_process';\nimport inquirer from 'inquirer';\nimport type Separator from 'inquirer/lib/objects/separator';\n\nexport type CommandResult = { returnCode: number; stdout: string; stderr: string };\nexport type CliChoice<T> = { name: string; value: T };\n\nexport function runCliCommand(command: string, cwd?: string, rejectOnFailure?: boolean): Promise<CommandResult> {\n  return new Promise((resolve, reject) => {\n    exec(command, { cwd: cwd, shell: getShell() }, (error, stdout, stderr) => {\n      const returnCode = error ? (error.code ?? 1) : 0;\n      if (returnCode !== 0 && rejectOnFailure) {\n        reject(new Error(stderr.trim()));\n      } else {\n        resolve({ returnCode, stdout, stderr });\n      }\n    });\n  });\n}\n\nexport function spawnCliCommand(\n  command: string,\n  cwd: string | undefined,\n  stdioMode: StdioOptions,\n  quiet: boolean,\n  rejectOnFailure: boolean,\n): Promise<CommandResult> {\n  return new Promise((resolve, reject) => {\n    const child = spawn(command, {\n      stdio: stdioMode,\n      shell: getShell(),\n      cwd: cwd,\n      env: { ...process.env, FORCE_COLOR: '1' },\n    });\n\n    // When using mode = 'inherit', the following output and error capture is a no-op\n\n    let stdout = '';\n    let stderr = '';\n\n    child.stdout?.on('data', (data: Buffer) => {\n      stdout += data.toString();\n      if (!quiet) {\n        process.stdout.write(stdout);\n      }\n    });\n\n    child.stderr?.on('data', (data: Buffer) => {\n      stderr += data.toString();\n      if (!quiet) {\n        process.stderr.write(stderr);\n      }\n    });\n\n    child.on('close', code => {\n      if (code !== 0 && rejectOnFailure) {\n        reject(new Error(stderr.trim()));\n      } else {\n        resolve({ returnCode: code ?? 0, stdout, stderr });\n      }\n    });\n\n    child.on('error', err => {\n      reject(err);\n    });\n  });\n}\n\nexport async function getUserChoice<T>(\n  choices: Array<CliChoice<T> | Separator>,\n  promptMessage?: string,\n  maxChoices?: number,\n): Promise<T> {\n  const answers = await inquirer.prompt<{ selectedChoice: T }>([\n    {\n      type: 'list',\n      name: 'selectedChoice',\n      message: promptMessage ?? 'Please select an option:',\n      choices: choices,\n      loop: false,\n      pageSize: maxChoices ?? 10,\n    },\n  ]);\n\n  return answers.selectedChoice;\n}\n\nexport async function getUserConfirmation(promptMessage?: string, defaultConfirm: boolean = false): Promise<boolean> {\n  const answer = await inquirer.prompt<{ confirm: boolean }>([\n    { type: 'confirm', name: 'confirm', message: promptMessage ?? 'Are you sure?', default: defaultConfirm },\n  ]);\n\n  return answer.confirm;\n}\n\nexport function getScriptDirectory(): string {\n  return '';\n}\n\nfunction getShell(): string {\n  return process.env['SHELL'] ?? '/bin/bash';\n}\n\nexport function checkCommandExists(command: string): boolean {\n  try {\n    execSync(`command -v ${command}`, { stdio: 'ignore' });\n    return true;\n  } catch {\n    return false;\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/copyBootstrapFiles.ts",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport { globSync } from 'glob';\nimport { ANSI_COLORS } from '../core/constants';\nimport type { Replacements } from './fileUtils';\nimport { copyFileWithReplacement, copyFiles, processReplacements } from './fileUtils';\nimport { wrapInColor } from './logUtils';\n\nexport function copyBootstrapFiles(from: string, to: string, replacements: Replacements) {\n  copyFiles(from, to);\n\n  const keys = Object.keys(replacements);\n\n  const filenamesToReplace = globSync(keys.map(key => `**/{{${key}}}`));\n\n  for (const filename of filenamesToReplace) {\n    fs.renameSync(filename, processReplacements(filename, replacements));\n  }\n\n  const templateFiles = globSync(`${to}/**/*.template`);\n  templateFiles.forEach(templateFile => {\n    const parsedPath = path.parse(templateFile);\n    console.log(\n      wrapInColor(`Updating template file ${parsedPath.name} in ${parsedPath.dir}...`, ANSI_COLORS.YELLOW_COLOR),\n    );\n    const templateFileWithoutSuffix = templateFile.replace(/.template$/, '');\n    fs.renameSync(templateFile, templateFileWithoutSuffix);\n    copyFileWithReplacement(templateFileWithoutSuffix, templateFileWithoutSuffix, replacements);\n  });\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/deviceUtils.ts",
    "content": "import { Architecture, PLATFORM } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport { runCliCommand, spawnCliCommand } from './cliUtils';\n\nfunction parseAndroidDevices(devicesString: string): string[] {\n  const deviceIDs: string[] = devicesString\n    .split('\\n')\n    .filter(line => line.trim().endsWith('device') && !line.startsWith('List of devices'))\n    .map(line => line.split('\\t')?.[0]?.trim() ?? ''); // Extract the device ID\n\n  return deviceIDs ?? [];\n}\n\nexport async function getArchitectureForAndroidDevice(deviceId: string): Promise<Architecture> {\n  const { stdout } = await runCliCommand(`adb -s ${deviceId} shell getprop ro.product.cpu.abi`, undefined, true);\n\n  const architectureString = stdout.trim();\n\n  switch (architectureString) {\n    case 'arm64-v8a': {\n      return Architecture.ARM64;\n    }\n    case 'armeabi-v7a': {\n      return Architecture.ARMV7;\n    }\n    case 'armeabi': {\n      return Architecture.ARMV7;\n    }\n    case 'x86_64': {\n      return Architecture.X86_64;\n    }\n    default: {\n      throw new CliError(`Unsupported device architecture: ${architectureString}`);\n    }\n  }\n}\n\nexport function getAllArchitecturesForAndroid() {\n  return [Architecture.ARM64, Architecture.ARMV7, Architecture.X86_64];\n}\n\nexport async function getConnectedAndroidDevices(): Promise<string[]> {\n  const commandListDevices = 'adb devices';\n  const { stdout: devicesString } = await runCliCommand(commandListDevices, undefined, true);\n  const androidDevices = parseAndroidDevices(devicesString);\n\n  return androidDevices;\n}\n\nexport async function getConnectedIOSDevices(): Promise<string[]> {\n  // eslint-disable-next-line unicorn/no-useless-promise-resolve-reject\n  return Promise.resolve(['-1']);\n}\n\nexport async function getConnectedDevices(platform: string): Promise<string[]> {\n  if (platform === PLATFORM.ANDROID) {\n    const androidDevices = await getConnectedAndroidDevices();\n    return androidDevices;\n  } else if (platform === PLATFORM.IOS) {\n    const iosDevices = await getConnectedIOSDevices();\n    return iosDevices;\n  }\n\n  return [];\n}\n\nexport async function installAndroidApk(apkPath: string, emulatorId?: string) {\n  const idString = emulatorId ? ` -s ${emulatorId} ` : ' ';\n  const commandInstallApk = `adb${idString}install -r ${apkPath}`;\n  await spawnCliCommand(commandInstallApk, undefined, 'pipe', false, true);\n}\n\nexport async function startAndroidActivity(activityName: string) {\n  const commandStartActivity = `adb shell am start -n ${activityName}`;\n  await spawnCliCommand(commandStartActivity, undefined, 'pipe', false, true);\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/errorUtils.ts",
    "content": "/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\nimport { ANSI_COLORS } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport { ArgumentsResolver } from './ArgumentsResolver';\nimport { wrapInColor } from './logUtils';\n\nfunction logReproduceWith(keys: string[], additionalResolvedArguments: any) {\n  const allArguments = ['valdi', ...process.argv.slice(2)];\n  keys.sort();\n\n  for (const key of keys.sort()) {\n    const value = additionalResolvedArguments[key];\n    if (Array.isArray(value)) {\n      for (const item of value) {\n        allArguments.push(`--${key}`, item.toString());\n      }\n    } else {\n      allArguments.push(`--${key}`, value.toString());\n    }\n  }\n\n  console.log(\n    `\\n${wrapInColor('Note: Use the following command next time to reproduce without prompts', ANSI_COLORS.GREEN_COLOR)}\\n${allArguments.join(' ')}\\n`,\n  );\n}\n\nexport function logReproduceThisCommandIfNeeded<T>(argumentsResolver: ArgumentsResolver<T>) {\n  const keys = Object.keys(argumentsResolver.additionalResolvedArguments);\n  if (keys.length > 0) {\n    logReproduceWith(keys, argumentsResolver.additionalResolvedArguments);\n  }\n}\n\nexport function makeCommandHandler<T>(cb: (argv: ArgumentsResolver<T>) => Promise<void>): (argv: T) => void {\n  const command = async (argv: T) => {\n    const argumentsResolver = new ArgumentsResolver(argv);\n    try {\n      await cb(argumentsResolver);\n      process.exitCode = 0;\n    } catch (error) {\n      process.exitCode = 1;\n\n      if (error instanceof CliError) {\n        // Managed Error\n        console.log(wrapInColor(error.message, error.textColor));\n      } else if (error instanceof Error) {\n        // Unmanaged Error\n        console.log(error.stack);\n        console.log(wrapInColor(error.message, ANSI_COLORS.RED_COLOR));\n      } else {\n        // Something went really wrong\n        throw error;\n      }\n    }\n  };\n\n  return (argv: T) => {\n    void command(argv);\n  };\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/fileUtils.ts",
    "content": "import fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport yaml from 'yaml';\nimport * as Constants from '../core/constants';\nimport { CliError } from '../core/errors';\n\nexport type Replacements = { [key: string]: string };\n\nexport class TemplateFile {\n  readonly templatePath: string;\n  readonly metaTemplatePath: string;\n\n  // Defaults to cwd\n  readonly outputPath: string;\n  readonly replacements: Replacements;\n\n  // Name/Path without .template suffix\n  readonly baseName: string;\n  readonly basePath: string;\n\n  private constructor(templatePath: string, outputPath?: string, replacements: Replacements = {}) {\n    this.templatePath = path.normalize(templatePath);\n    this.metaTemplatePath = path.join(Constants.META_DIR_PATH, this.templatePath);\n\n    if (!fileExists(this.metaTemplatePath)) {\n      throw new CliError(`Template file not found: ${this.metaTemplatePath}`);\n    }\n\n    const parsedPath = path.parse(this.templatePath);\n    this.baseName = parsedPath.name;\n    this.basePath = path.join(parsedPath.dir, parsedPath.name);\n\n    this.outputPath = outputPath ?? path.join(process.cwd(), this.basePath);\n    this.outputPath = path.normalize(this.outputPath);\n\n    this.replacements = replacements;\n  }\n\n  static init(templatePath: string): TemplateFile {\n    return new TemplateFile(templatePath);\n  }\n\n  withReplacements(replacements: Replacements): TemplateFile {\n    return new TemplateFile(this.templatePath, this.outputPath, replacements);\n  }\n\n  withOutputPath(outputPath: string): TemplateFile {\n    const newOutputPath = isDirectory(outputPath) ? path.join(outputPath, this.baseName) : outputPath;\n    return new TemplateFile(this.templatePath, newOutputPath, this.replacements);\n  }\n\n  expandTemplate(): string {\n    const metaTemplatePath = path.join(Constants.META_DIR_PATH, this.templatePath);\n    return copyFileWithReplacement(metaTemplatePath, this.outputPath, this.replacements);\n  }\n}\n\nexport function resolveFilePath(pathString: string): string {\n  if (pathString.startsWith('~')) {\n    const tildeResolvedPath = path.join(os.homedir(), pathString.slice(1));\n    return path.resolve(tildeResolvedPath);\n  }\n  return path.resolve(pathString);\n}\n\nexport function fileExists(filePath: string): boolean {\n  return fs.existsSync(filePath);\n}\n\nexport function getUserConfig(): Constants.UserConfig {\n  let resolvedPath: string | undefined;\n\n  for (const filePath of Constants.VALDI_CONFIG_PATHS) {\n    const unrolledPath = resolveFilePath(filePath);\n    if (fs.existsSync(unrolledPath)) {\n      resolvedPath = unrolledPath;\n      break;\n    }\n  }\n\n  if (resolvedPath === undefined) {\n    throw new CliError(\n      `Please create a Valdi config file in ${Constants.VALDI_CONFIG_PATHS[0] ?? ''} (Running 'valdi bootstrap' takes care of that for you)`,\n    );\n  }\n\n  const configContents = fs.readFileSync(resolvedPath, 'utf8');\n  const parsedYaml = yaml.parse(configContents) as Constants.UserConfig;\n\n  return parsedYaml;\n}\n\nexport function getAllFilePaths(directoryPath: string): string[] {\n  directoryPath = resolveFilePath(directoryPath);\n\n  const files: string[] = [];\n  function traverseDirectories(dir: string) {\n    fs.readdirSync(dir, { withFileTypes: true }).forEach(file => {\n      const fullPath = path.join(dir, file.name);\n      if (file.isDirectory()) {\n        traverseDirectories(fullPath);\n        return;\n      }\n\n      files.push(fullPath);\n    });\n  }\n\n  traverseDirectories(directoryPath);\n\n  return files;\n}\n\nexport function isDirectoryEmpty(directoryPath: string): boolean {\n  const absPath = resolveFilePath(directoryPath);\n  const dir = fs.opendirSync(absPath);\n  const firstEntry = dir.readSync();\n  dir.closeSync();\n  return firstEntry === null;\n}\n\nexport function getFilesSortedByUpdatedTime(directoryPath: string): string[] {\n  directoryPath = resolveFilePath(directoryPath);\n  const files = getAllFilePaths(directoryPath);\n\n  const fileStats = files.map(file => {\n    const stats = fs.statSync(file);\n    return { file, mtime: stats.mtime };\n  });\n\n  const sortedFiles = fileStats.sort((a, b) => b.mtime.getTime() - a.mtime.getTime()).map(fileStat => fileStat.file);\n\n  return sortedFiles;\n}\n\nexport function isDirectory(filePath: string): boolean {\n  return fs.existsSync(filePath) && fs.statSync(filePath).isDirectory();\n}\n\nexport function hasExtension(filePath: string, extension: string): boolean {\n  return fs.existsSync(filePath) && path.extname(filePath) === extension;\n}\n\nexport function processReplacements(input: string, replacements: Replacements): string {\n  let outputContent = input;\n  for (const [key, value] of Object.entries(replacements)) {\n    const placeholder = `{{${key}}}`;\n    const regex = new RegExp(placeholder, 'g'); // Global replace for all occurrences\n    outputContent = outputContent.replace(regex, value);\n  }\n\n  return outputContent;\n}\n\n// Returns outputFilePath\nexport function copyFileWithReplacement(\n  inputFilePath: string,\n  outputFilePath: string,\n  replacements: Replacements,\n): string {\n  // Read the input file content\n  const inputContent = fs.readFileSync(inputFilePath, 'utf8');\n\n  // Replace the keys in the input content with the corresponding values\n  const outputContent = processReplacements(inputContent, replacements);\n\n  // Ensure the output directory exists\n  const outputDir = path.dirname(outputFilePath);\n  if (!fs.existsSync(outputDir)) {\n    fs.mkdirSync(outputDir, { recursive: true });\n  }\n\n  // Write the replaced content to the output file\n  fs.writeFileSync(outputFilePath, outputContent);\n\n  return outputFilePath;\n}\n\nexport function deleteAll(destPath: string) {\n  if (!isDirectory(destPath)) {\n    return;\n  }\n\n  fs.readdirSync(destPath, { withFileTypes: true }).forEach(item => {\n    const fullPath = path.join(destPath, item.name);\n    fs.rmSync(fullPath, { recursive: true });\n  });\n}\n\n// Util functions for copying files\nexport interface CopyConfig {\n  whitelist?: string[];\n  blacklist?: string[];\n}\n\nexport function loadConfig(configPath: string): CopyConfig {\n  const ext = path.extname(configPath).toLowerCase();\n  const rawConfig = fs.readFileSync(configPath, 'utf8');\n\n  if (ext === '.json') {\n    return JSON.parse(rawConfig) as CopyConfig;\n  } else {\n    throw new Error(`Unsupported config file format: ${ext}`);\n  }\n}\n\nfunction precompilePatterns(patterns?: string[]): RegExp[] {\n  return patterns?.map(pattern => new RegExp(pattern)) ?? [];\n}\n\nfunction matchesCompiledPatterns(compiledPatterns: RegExp[], filePath: string): boolean {\n  return compiledPatterns.some(regex => regex.test(filePath));\n}\n\nfunction isPathAllowed(filePath: string, blacklist: RegExp[], whitelist: RegExp[]): boolean {\n  const normalizedPath = resolveFilePath(filePath);\n\n  if (blacklist.length > 0 && matchesCompiledPatterns(blacklist, normalizedPath)) {\n    return false;\n  }\n\n  if (whitelist.length > 0) {\n    return matchesCompiledPatterns(whitelist, normalizedPath);\n  }\n\n  return true;\n}\n\nexport function copyFiles(sourceDir: string, destDir: string, config: CopyConfig = {}) {\n  // Precompile patterns for efficiency.\n  const blacklist = precompilePatterns(config.blacklist);\n  const whitelist = precompilePatterns(config.whitelist);\n\n  fs.cpSync(sourceDir, destDir, {\n    recursive: true,\n    filter: (src): boolean => {\n      return isPathAllowed(src, blacklist, whitelist);\n    },\n  });\n}\n\nexport function removeFileOrDirAtPath(path: string): boolean {\n  if (!fs.existsSync(path)) {\n    return false;\n  }\n\n  const outputStat = fs.lstatSync(path);\n  if (outputStat.isFile()) {\n    fs.rmSync(path);\n    return true;\n  } else if (outputStat.isDirectory()) {\n    fs.rmSync(path, { recursive: true });\n    return true;\n  }\n  return false;\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/githubUtils.ts",
    "content": "import { runCliCommand } from './cliUtils';\n\n/**\n * Parses a GitHub repo URL (e.g. https://github.com/Snapchat/Valdi or .git variant)\n * into \"owner/repo\" for the GitHub API.\n */\nfunction parseGitHubRepoSlug(repoUrl: string): string {\n  const normalized = repoUrl.replace(/\\.git$/u, '').trim();\n  const match = normalized.match(/github\\.com[/:]([^/]+)\\/([^/]+?)(?:[/]?$)/u);\n  if (!match) {\n    throw new Error(`Invalid GitHub URL: ${repoUrl}`);\n  }\n  return `${match[1]}/${match[2]}`;\n}\n\nconst LATEST_RELEASE_HINT =\n  'Use --valdiVersion=latest to retry, or --valdiVersion=<tag> (e.g. main or v1.0.0) to pin a version.';\n\n/**\n * Returns the tag name of the release marked as \"Latest\" on GitHub (releases UI).\n * Uses only the GitHub Releases API so the result matches what GitHub shows.\n * Falls back to git ls-remote only when the repo has no releases (404).\n */\nexport async function getLatestReleaseTag(repoUrl: string): Promise<string> {\n  const slug = parseGitHubRepoSlug(repoUrl);\n  let response: Response;\n  try {\n    response = await fetch(`https://api.github.com/repos/${slug}/releases/latest`, {\n      headers: { 'User-Agent': 'Valdi-CLI' },\n    });\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error);\n    throw new Error(\n      `Could not fetch latest release from GitHub (${message}). ${LATEST_RELEASE_HINT}`,\n    );\n  }\n  if (!response.ok) {\n    if (response.status === 404) {\n      // No releases or no \"latest\" release – fall back to git ls-remote\n      return getLatestReleaseTagFromGit(repoUrl);\n    }\n    throw new Error(\n      `GitHub API returned ${response.status} (rate limit or server error). ${LATEST_RELEASE_HINT}`,\n    );\n  }\n  const data = (await response.json()) as { tag_name?: string };\n  if (typeof data?.tag_name !== 'string') {\n    throw new Error(`Invalid response: missing tag_name. ${LATEST_RELEASE_HINT}`);\n  }\n  return data.tag_name;\n}\n\n/** Matches semver-like tags (e.g. v1.0.0, 2.3.1, beta-0.0.1). Captures major, minor, patch. */\nconst SEMVER_TAG_REGEX = /^(?:\\w+-)?v?(\\d+)\\.(\\d+)\\.(\\d+)(?:[-.]\\S+)?$/u;\n\nfunction parseSemverTag(tag: string): [number, number, number] | null {\n  const m = tag.match(SEMVER_TAG_REGEX);\n  if (!m) return null;\n  return [Number.parseInt(m[1]!, 10), Number.parseInt(m[2]!, 10), Number.parseInt(m[3]!, 10)];\n}\n\nfunction compareSemverTags(a: string, b: string): number {\n  const va = parseSemverTag(a);\n  const vb = parseSemverTag(b);\n  if (va && vb) {\n    return va[0] - vb[0] || va[1] - vb[1] || va[2] - vb[2];\n  }\n  if (va) return 1;   // non-semver (b) sorts before semver (a)\n  if (vb) return -1;  // non-semver (a) sorts before semver (b)\n  return a.localeCompare(b, undefined, { numeric: true });\n}\n\n/**\n * Fallback: resolve tag refs via git ls-remote and return the latest tag by semver.\n * git ls-remote returns refs sorted by refname (alphabetically), so we parse all tags\n * and pick the highest semantic version.\n */\nasync function getLatestReleaseTagFromGit(repoUrl: string): Promise<string> {\n  const gitUrl = repoUrl.includes('.git') ? repoUrl : `${repoUrl}.git`;\n  const result = await runCliCommand(`git ls-remote --tags --refs ${gitUrl}`, undefined, true);\n  const lines = result.stdout.trim().split('\\n').filter(Boolean);\n  const tags: string[] = [];\n  for (const line of lines) {\n    const ref = line.split(/\\s+/)[1];\n    if (ref?.startsWith('refs/tags/')) {\n      const tag = ref.slice('refs/tags/'.length);\n      if (tag) tags.push(tag);\n    }\n  }\n  if (tags.length === 0) {\n    throw new Error('No tags found in repository');\n  }\n  tags.sort(compareSemverTags);\n  return tags[tags.length - 1]!;\n}\n\n/** @deprecated Use getLatestReleaseTag for the GitHub \"Latest\" release; this returns an arbitrary tag from git ls-remote. */\nexport async function resolveLatestReleaseRef(repoUrl: string): Promise<string> {\n  const tag = await getLatestReleaseTagFromGit(repoUrl);\n  // Template expects either ref (refs/tags/X) or tag name for archive URL; we use tag name.\n  return tag;\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/jsonUtils.ts",
    "content": "import type { JSONPath, ModificationOptions } from 'jsonc-parser';\nimport { applyEdits, modify, parse } from 'jsonc-parser';\n\nexport class JSONCFile<T> {\n  constructor(\n    private content: string,\n    readonly value: T,\n  ) {}\n\n  static parse<T>(content: string): JSONCFile<T> {\n    const parsed = parse(content) as T;\n\n    return new JSONCFile(content, parsed);\n  }\n\n  static fromObject<T>(object: T): JSONCFile<T> {\n    const content = JSON.stringify(object, null, 2);\n    return JSONCFile.parse<T>(content);\n  }\n\n  toJSONString(): string {\n    return this.content;\n  }\n\n  updating(path: JSONPath, value: unknown, options: ModificationOptions): JSONCFile<T> {\n    const edits = modify(this.content, path, value, options);\n\n    return new JSONCFile(applyEdits(this.content, edits), this.value);\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/lintUtils.ts",
    "content": "/**\n * Common functions shared between the linting commands\n */\nimport fs from 'fs';\nimport path from 'path';\nimport eslint, { ESLint } from 'eslint';\nimport prettier from 'prettier';\nimport { ANSI_COLORS, TEMPLATE_BASE_PATHS } from '../core/constants';\nimport { CliError } from '../core/errors';\nimport { getUserConfirmation } from './cliUtils';\nimport { TemplateFile, fileExists, hasExtension, isDirectory } from './fileUtils';\nimport { wrapInColor } from './logUtils';\n\nexport enum RESULT_STATUS {\n  SKIPPED = 'skipped',\n  DIRECTORY = 'directory',\n  NEEDS_FORMAT = 'needs format',\n  VALID = 'valid',\n  CHANGED = 'changed',\n}\n\nexport type FileLintStatus = [string, RESULT_STATUS];\n\n// Returns the config path if it exists, otherwise prompts the user to create one\nexport async function maybeSetupPrettier(): Promise<string> {\n  let prettierConfigPath = await getPrettierConfigPath();\n\n  if (prettierConfigPath === null) {\n    const initMessage = `No prettier config found. Would you like to create one here? ${wrapInColor(process.cwd(), ANSI_COLORS.GREEN_COLOR)}`;\n    const shouldInitPrettier = await getUserConfirmation(initMessage, true);\n\n    if (!shouldInitPrettier) {\n      throw new CliError('Prettier config is required, aborting...');\n    }\n\n    prettierConfigPath = createPrettierConfig();\n\n    // Need to clear the cache so the newly created config can be resolved\n    // in the same execution cycle\n    await prettier.clearConfigCache();\n  }\n\n  return prettierConfigPath;\n}\n\nexport async function getPrettierConfigPath(): Promise<string | null> {\n  // Starts searching at process.cwd() by default\n  // Note that VALIDing in process.cwd() as a parameter will NOT work\n  const prettierConfigPath = await prettier.resolveConfigFile();\n\n  return prettierConfigPath;\n}\n\nexport function createPrettierConfig(): string {\n  const prettierTemplateFile = TemplateFile.init(TEMPLATE_BASE_PATHS.PRETTIER_CONFIG);\n  return prettierTemplateFile.expandTemplate();\n}\n\n// Prompts user to create eslint config files if they don't exist.\nexport async function maybeSetupEslint() {\n  if (!fileExists('.eslintrc.js')) {\n    const initMessage = `No eslintrc found. Would you like to create one here? ${wrapInColor(process.cwd(), ANSI_COLORS.GREEN_COLOR)}`;\n    const shouldInitEslintrc = await getUserConfirmation(initMessage, true);\n\n    if (!shouldInitEslintrc) {\n      throw new CliError('eslintrc config is required, aborting...');\n    }\n\n    createEslintConfig();\n  }\n\n  if (!fileExists('package.json')) {\n    const initMessage = `No package.json found. Would you like to create one here? ${wrapInColor(process.cwd(), ANSI_COLORS.GREEN_COLOR)}`;\n    const shouldInitEslintrc = await getUserConfirmation(initMessage, true);\n\n    if (!shouldInitEslintrc) {\n      throw new CliError('package.json config is required, aborting...');\n    }\n\n    createPackageConfig();\n\n    throw new CliError('New package.json created, run `npm install` before trying again.');\n  }\n}\n\nexport function createEslintConfig(): string {\n  const eslintConfigFile = TemplateFile.init(TEMPLATE_BASE_PATHS.ESLINT_CONFIG);\n  return eslintConfigFile.expandTemplate();\n}\n\nexport function createPackageConfig(): string {\n  const packageConfigFile = TemplateFile.init(TEMPLATE_BASE_PATHS.ESLINT_PACKAGE_JSON_CONFIG);\n  return packageConfigFile.expandTemplate();\n}\n\nexport async function getPrettierConfig(configPath: string): Promise<prettier.Options | null> {\n  return await prettier.resolveConfig(configPath);\n}\n\nexport async function checkAndFormatFiles(\n  filePaths: string[],\n  prettierOptions: prettier.Options,\n  shouldFormat: boolean = false,\n): Promise<FileLintStatus[]> {\n  const linter = new eslint.ESLint({fix: true});\n  const results: FileLintStatus[] = await Promise.all(\n    filePaths.map(async fp => {\n      const filePath = path.resolve(fp);\n\n      if (isDirectory(filePath)) {\n        return [fp, RESULT_STATUS.DIRECTORY];\n      }\n\n      if (hasExtension(filePath, '.json')) {\n        return [fp, RESULT_STATUS.SKIPPED];\n      }\n\n      const fileContent = fs.readFileSync(filePath, 'utf8');\n      const prettierFileInfo = await prettier.getFileInfo(filePath);\n\n      if (prettierFileInfo.inferredParser === null) {\n        return [fp, RESULT_STATUS.SKIPPED];\n      }\n\n      const lintResults = await linter.lintFiles([filePath]);\n      const needsLint = lintResults.length > 0;\n      let isLintFormatted = false;\n\n      if (shouldFormat && needsLint) {\n        console.log(lintResults[0]?.messages[0]?.message);\n        await ESLint.outputFixes(lintResults);\n        isLintFormatted = true;\n      }\n\n      const needsPrettier = await prettier.check(fileContent, { ...prettierOptions, filepath: filePath });\n      let isPrettierFormatted = false;\n\n      if (shouldFormat && !needsPrettier) {\n        const formattedContent = await prettier.format(fileContent, { ...prettierOptions, filepath: filePath });\n        fs.writeFileSync(filePath, formattedContent, 'utf8');\n\n        isPrettierFormatted = true;\n\n      }\n\n      if (isPrettierFormatted || isLintFormatted) {\n        return [fp, RESULT_STATUS.CHANGED];\n      }\n\n      const formattedStatus = isPrettierFormatted && isLintFormatted ? RESULT_STATUS.VALID : RESULT_STATUS.NEEDS_FORMAT;\n      return [fp, formattedStatus];\n    }),\n  );\n\n  return results;\n}\n\nexport function printStatus(lintResults: FileLintStatus[], showSkipped: boolean = false) {\n  let textColor = ANSI_COLORS.RESET_COLOR;\n\n  for (const [shortPath, status] of lintResults) {\n    switch (status) {\n      case RESULT_STATUS.DIRECTORY: {\n        continue;\n      }\n      case RESULT_STATUS.SKIPPED: {\n        if (!showSkipped) {\n          continue;\n        }\n\n        textColor = ANSI_COLORS.GRAY_COLOR;\n        break;\n      }\n      case RESULT_STATUS.VALID: {\n        textColor = ANSI_COLORS.GRAY_COLOR;\n        break;\n      }\n      case RESULT_STATUS.NEEDS_FORMAT: {\n        textColor = ANSI_COLORS.YELLOW_COLOR;\n        break;\n      }\n      case RESULT_STATUS.CHANGED: {\n        textColor = ANSI_COLORS.YELLOW_COLOR;\n        break;\n      }\n    }\n\n    console.log(`${wrapInColor(shortPath, textColor)} - ${status}`);\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/linuxDistro.spec.ts",
    "content": "import 'jasmine';\nimport {\n  type LinuxDistroInfo,\n  LinuxDistroType,\n  buildInstallCommand,\n  getCommonPackageMappings,\n  getGitLfsRepoSetupCommand,\n  getPackageName,\n  needsGitLfsRepoSetup,\n} from './linuxDistro';\n\ndescribe('linuxDistro', () => {\n  describe('getPackageName', () => {\n    it('returns Debian package name for Debian distribution', () => {\n      const packageMap = {\n        debian: 'openjdk-17-jdk',\n        redhat: 'java-17-openjdk-devel',\n        unknown: 'openjdk-17',\n      };\n\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.DEBIAN,\n        name: 'Ubuntu',\n        packageManager: { name: 'apt', installCommand: 'apt-get install', requiresSudo: true },\n      };\n\n      const result = getPackageName(packageMap, distro);\n\n      expect(result).toBe('openjdk-17-jdk');\n    });\n\n    it('returns RedHat package name for RedHat distribution', () => {\n      const packageMap = {\n        debian: 'openjdk-17-jdk',\n        redhat: 'java-17-openjdk-devel',\n        unknown: 'openjdk-17',\n      };\n\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.REDHAT,\n        name: 'Fedora',\n        packageManager: { name: 'dnf', installCommand: 'dnf install', requiresSudo: true },\n      };\n\n      const result = getPackageName(packageMap, distro);\n\n      expect(result).toBe('java-17-openjdk-devel');\n    });\n\n    it('returns unknown fallback for distributions without specific mapping', () => {\n      const packageMap = {\n        debian: 'openjdk-17-jdk',\n        unknown: 'openjdk-17',\n      };\n\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.ARCH,\n        name: 'Arch Linux',\n        packageManager: { name: 'pacman', installCommand: 'pacman -S', requiresSudo: true },\n      };\n\n      const result = getPackageName(packageMap, distro);\n\n      expect(result).toBe('openjdk-17');\n    });\n  });\n\n  describe('buildInstallCommand', () => {\n    it('builds install command for Debian', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.DEBIAN,\n        name: 'Ubuntu',\n        packageManager: { name: 'apt', installCommand: 'apt-get install', requiresSudo: true },\n      };\n\n      const result = buildInstallCommand(['git', 'npm', 'watchman'], distro);\n\n      expect(result).toBe('sudo apt-get install git npm watchman');\n    });\n\n    it('builds install command for RedHat', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.REDHAT,\n        name: 'Fedora',\n        packageManager: { name: 'dnf', installCommand: 'dnf install', requiresSudo: true },\n      };\n\n      const result = buildInstallCommand(['git', 'npm'], distro);\n\n      expect(result).toBe('sudo dnf install git npm');\n    });\n\n    it('builds install command for Arch', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.ARCH,\n        name: 'Arch Linux',\n        packageManager: { name: 'pacman', installCommand: 'pacman -S', requiresSudo: true },\n      };\n\n      const result = buildInstallCommand(['git', 'npm'], distro);\n\n      expect(result).toBe('sudo pacman -S git npm');\n    });\n\n    it('returns comment for unknown distribution', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.UNKNOWN,\n        name: 'Unknown',\n        packageManager: { name: 'unknown', installCommand: '', requiresSudo: true },\n      };\n\n      const result = buildInstallCommand(['git', 'npm'], distro);\n\n      expect(result).toContain('Unable to determine package manager');\n      expect(result).toContain('git, npm');\n    });\n  });\n\n  describe('needsGitLfsRepoSetup', () => {\n    it('returns true for Debian distributions', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.DEBIAN,\n        name: 'Ubuntu',\n        packageManager: { name: 'apt', installCommand: 'apt-get install', requiresSudo: true },\n      };\n\n      expect(needsGitLfsRepoSetup(distro)).toBe(true);\n    });\n\n    it('returns false for Arch distributions', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.ARCH,\n        name: 'Arch Linux',\n        packageManager: { name: 'pacman', installCommand: 'pacman -S', requiresSudo: true },\n      };\n\n      expect(needsGitLfsRepoSetup(distro)).toBe(false);\n    });\n  });\n\n  describe('getGitLfsRepoSetupCommand', () => {\n    it('returns Debian script for Debian distributions', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.DEBIAN,\n        name: 'Ubuntu',\n        packageManager: { name: 'apt', installCommand: 'apt-get install', requiresSudo: true },\n      };\n\n      const result = getGitLfsRepoSetupCommand(distro);\n\n      expect(result).toContain('script.deb.sh');\n    });\n\n    it('returns RPM script for RedHat distributions', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.REDHAT,\n        name: 'Fedora',\n        packageManager: { name: 'dnf', installCommand: 'dnf install', requiresSudo: true },\n      };\n\n      const result = getGitLfsRepoSetupCommand(distro);\n\n      expect(result).toContain('script.rpm.sh');\n    });\n\n    it('returns null for distributions with git-lfs in standard repos', () => {\n      const distro: LinuxDistroInfo = {\n        type: LinuxDistroType.ARCH,\n        name: 'Arch Linux',\n        packageManager: { name: 'pacman', installCommand: 'pacman -S', requiresSudo: true },\n      };\n\n      const result = getGitLfsRepoSetupCommand(distro);\n\n      expect(result).toBeNull();\n    });\n  });\n\n  describe('getCommonPackageMappings', () => {\n    it('returns package mappings for common dependencies', () => {\n      const mappings = getCommonPackageMappings();\n\n      expect(mappings['git']).toBeDefined();\n      expect(mappings['git-lfs']).toBeDefined();\n      expect(mappings['npm']).toBeDefined();\n      expect(mappings['openjdk-17']).toBeDefined();\n      expect(mappings['watchman']).toBeDefined();\n      expect(mappings['adb']).toBeDefined();\n      expect(mappings['fontconfig']).toBeDefined();\n      expect(mappings['zlib']).toBeDefined();\n    });\n\n    it('has platform-specific mappings for Java', () => {\n      const mappings = getCommonPackageMappings();\n      const javaMappings = mappings['openjdk-17'];\n\n      expect(javaMappings).toBeDefined();\n      if (javaMappings) {\n        expect(javaMappings.debian).toBe('openjdk-17-jdk');\n        expect(javaMappings.redhat).toBe('java-17-openjdk-devel');\n        expect(javaMappings.arch).toBe('jdk17-openjdk');\n        expect(javaMappings.suse).toBe('java-17-openjdk-devel');\n      }\n    });\n\n    it('has platform-specific mappings for adb', () => {\n      const mappings = getCommonPackageMappings();\n      const adbMappings = mappings['adb'];\n\n      expect(adbMappings).toBeDefined();\n      if (adbMappings) {\n        expect(adbMappings.debian).toBe('adb');\n        expect(adbMappings.redhat).toBe('android-tools');\n        expect(adbMappings.arch).toBe('android-tools');\n        expect(adbMappings.suse).toBe('android-tools');\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "npm_modules/cli/src/utils/linuxDistro.ts",
    "content": "import fs from 'fs';\nimport { checkCommandExists } from './cliUtils';\n\n/**\n * Detected Linux distribution type\n */\nexport enum LinuxDistroType {\n  DEBIAN = 'debian', // Debian, Ubuntu, Mint, Pop!_OS, etc.\n  REDHAT = 'redhat', // RHEL, Fedora, CentOS, Rocky Linux, etc.\n  ARCH = 'arch', // Arch Linux, Manjaro, EndeavourOS, etc.\n  SUSE = 'suse', // openSUSE, SLES, etc.\n  UNKNOWN = 'unknown',\n}\n\n/**\n * Package manager information for a Linux distribution\n */\nexport interface PackageManager {\n  /** Name of the package manager */\n  name: string;\n  /** Command to install packages (without sudo) */\n  installCommand: string;\n  /** Whether this package manager requires sudo */\n  requiresSudo: boolean;\n  /** Command to update package database */\n  updateCommand?: string;\n}\n\n/**\n * Linux distribution information\n */\nexport interface LinuxDistroInfo {\n  /** Distribution type */\n  type: LinuxDistroType;\n  /** Distribution name (e.g., \"Ubuntu\", \"Fedora\") */\n  name: string;\n  /** Distribution version (if available) */\n  version?: string;\n  /** Package manager information */\n  packageManager: PackageManager;\n}\n\n/**\n * Infer distribution keys from the enum, excluding 'unknown'\n */\ntype Distros = Exclude<`${LinuxDistroType}`, 'unknown'>;\n\n/**\n * Package name mappings for different distributions\n * Keys are automatically inferred from LinuxDistroType enum\n */\nexport type PackageNameMap = {\n  [K in Distros]?: string;\n} & {\n  unknown: string; // Fallback for unknown distributions\n};\n\n/**\n * Detects the current Linux distribution and package manager\n */\nexport function detectLinuxDistro(): LinuxDistroInfo {\n  // Try to read /etc/os-release (most modern distributions)\n  if (fs.existsSync('/etc/os-release')) {\n    try {\n      const osRelease = fs.readFileSync('/etc/os-release', 'utf8');\n      const lines = osRelease.split('\\n');\n      const info: { [key: string]: string } = {};\n\n      for (const line of lines) {\n        const match = line.match(/^([^=]+)=(.*)$/);\n        if (match && match[1] && match[2]) {\n          // Remove quotes from value\n          info[match[1]] = match[2].replaceAll(/^[\"']|[\"']$/g, '');\n        }\n      }\n\n      const id = info['ID']?.toLowerCase() ?? '';\n      const idLike = info['ID_LIKE']?.toLowerCase() ?? '';\n      const name = info['NAME'] ?? 'Linux';\n      const version = info['VERSION_ID'];\n\n      // Detect distribution type based on ID and ID_LIKE\n      if (id.includes('debian') || id.includes('ubuntu') || idLike.includes('debian') || idLike.includes('ubuntu')) {\n        const result: LinuxDistroInfo = {\n          type: LinuxDistroType.DEBIAN,\n          name,\n          packageManager: getPackageManager(LinuxDistroType.DEBIAN),\n        };\n        if (version) result.version = version;\n        return result;\n      } else if (\n        id.includes('fedora') ||\n        id.includes('rhel') ||\n        id.includes('centos') ||\n        id.includes('rocky') ||\n        idLike.includes('fedora') ||\n        idLike.includes('rhel')\n      ) {\n        const result: LinuxDistroInfo = {\n          type: LinuxDistroType.REDHAT,\n          name,\n          packageManager: getPackageManager(LinuxDistroType.REDHAT),\n        };\n        if (version) result.version = version;\n        return result;\n      } else if (id.includes('arch') || id.includes('manjaro') || idLike.includes('arch')) {\n        const result: LinuxDistroInfo = {\n          type: LinuxDistroType.ARCH,\n          name,\n          packageManager: getPackageManager(LinuxDistroType.ARCH),\n        };\n        if (version) result.version = version;\n        return result;\n      } else if (id.includes('suse') || idLike.includes('suse')) {\n        const result: LinuxDistroInfo = {\n          type: LinuxDistroType.SUSE,\n          name,\n          packageManager: getPackageManager(LinuxDistroType.SUSE),\n        };\n        if (version) result.version = version;\n        return result;\n      }\n    } catch {\n      // Fall through to legacy detection\n    }\n  }\n\n  // Legacy detection methods\n  if (checkCommandExists('apt-get')) {\n    return {\n      type: LinuxDistroType.DEBIAN,\n      name: 'Debian/Ubuntu',\n      packageManager: getPackageManager(LinuxDistroType.DEBIAN),\n    };\n  } else if (checkCommandExists('dnf')) {\n    return {\n      type: LinuxDistroType.REDHAT,\n      name: 'Fedora/RHEL',\n      packageManager: getPackageManager(LinuxDistroType.REDHAT),\n    };\n  } else if (checkCommandExists('yum')) {\n    return {\n      type: LinuxDistroType.REDHAT,\n      name: 'RHEL/CentOS',\n      packageManager: getPackageManager(LinuxDistroType.REDHAT),\n    };\n  } else if (checkCommandExists('pacman')) {\n    return {\n      type: LinuxDistroType.ARCH,\n      name: 'Arch Linux',\n      packageManager: getPackageManager(LinuxDistroType.ARCH),\n    };\n  } else if (checkCommandExists('zypper')) {\n    return {\n      type: LinuxDistroType.SUSE,\n      name: 'openSUSE/SLES',\n      packageManager: getPackageManager(LinuxDistroType.SUSE),\n    };\n  }\n\n  // Unknown distribution\n  return {\n    type: LinuxDistroType.UNKNOWN,\n    name: 'Unknown Linux',\n    packageManager: {\n      name: 'unknown',\n      installCommand: '',\n      requiresSudo: true,\n    },\n  };\n}\n\n/**\n * Gets the package manager for a specific distribution type\n */\nfunction getPackageManager(distroType: LinuxDistroType): PackageManager {\n  switch (distroType) {\n    case LinuxDistroType.DEBIAN: {\n      return {\n        name: 'apt',\n        installCommand: 'apt-get install',\n        requiresSudo: true,\n        updateCommand: 'apt-get update',\n      };\n    }\n    case LinuxDistroType.REDHAT: {\n      // Prefer dnf over yum\n      if (checkCommandExists('dnf')) {\n        return {\n          name: 'dnf',\n          installCommand: 'dnf install',\n          requiresSudo: true,\n        };\n      } else {\n        return {\n          name: 'yum',\n          installCommand: 'yum install',\n          requiresSudo: true,\n        };\n      }\n    }\n    case LinuxDistroType.ARCH: {\n      return {\n        name: 'pacman',\n        installCommand: 'pacman -S',\n        requiresSudo: true,\n        updateCommand: 'pacman -Sy',\n      };\n    }\n    case LinuxDistroType.SUSE: {\n      return {\n        name: 'zypper',\n        installCommand: 'zypper install',\n        requiresSudo: true,\n      };\n    }\n    default: {\n      return {\n        name: 'unknown',\n        installCommand: '',\n        requiresSudo: true,\n      };\n    }\n  }\n}\n\n/**\n * Gets the appropriate package name for the current distribution\n * Uses type-safe indexing based on the LinuxDistroType enum\n */\nexport function getPackageName(packageMap: PackageNameMap, distro = detectLinuxDistro()): string {\n  return packageMap[distro.type] ?? packageMap.unknown;\n}\n\n/**\n * Builds an install command for packages on the current distribution\n */\nexport function buildInstallCommand(packages: string[], distro = detectLinuxDistro()): string {\n  if (distro.type === LinuxDistroType.UNKNOWN) {\n    return `# Unable to determine package manager. Please install manually: ${packages.join(', ')}`;\n  }\n\n  const { packageManager } = distro;\n  const sudo = packageManager.requiresSudo ? 'sudo ' : '';\n\n  return `${sudo}${packageManager.installCommand} ${packages.join(' ')}`;\n}\n\n/**\n * Gets the package name mappings for common dependencies\n */\nexport function getCommonPackageMappings(): { [key: string]: PackageNameMap } {\n  return {\n    git: {\n      unknown: 'git',\n    },\n    'git-lfs': {\n      unknown: 'git-lfs',\n    },\n    npm: {\n      unknown: 'npm',\n    },\n    'openjdk-17': {\n      debian: 'openjdk-17-jdk',\n      redhat: 'java-17-openjdk-devel',\n      arch: 'jdk17-openjdk',\n      suse: 'java-17-openjdk-devel',\n      unknown: 'openjdk-17-jdk',\n    },\n    watchman: {\n      debian: 'watchman',\n      redhat: 'watchman', // May need EPEL repository\n      arch: 'watchman',\n      suse: 'watchman',\n      unknown: 'watchman',\n    },\n    adb: {\n      debian: 'adb',\n      redhat: 'android-tools',\n      arch: 'android-tools',\n      suse: 'android-tools',\n      unknown: 'adb',\n    },\n    fontconfig: {\n      debian: 'libfontconfig1-dev',\n      redhat: 'fontconfig-devel',\n      arch: 'fontconfig',\n      suse: 'fontconfig-devel',\n      unknown: 'fontconfig',\n    },\n    zlib: {\n      debian: 'zlib1g-dev',\n      redhat: 'zlib-devel',\n      arch: 'zlib',\n      suse: 'zlib-devel',\n      unknown: 'zlib',\n    },\n  };\n}\n\n/**\n * Checks if git-lfs can be installed directly or needs repository setup\n */\nexport function needsGitLfsRepoSetup(distro = detectLinuxDistro()): boolean {\n  // Only Debian/Ubuntu-based systems need the packagecloud repository setup\n  // Other distributions usually have git-lfs in their standard repos\n  return distro.type === LinuxDistroType.DEBIAN;\n}\n\n/**\n * Gets the shell command to setup git-lfs repository for the current distribution\n */\nexport function getGitLfsRepoSetupCommand(distro = detectLinuxDistro()): string | null {\n  switch (distro.type) {\n    case LinuxDistroType.DEBIAN: {\n      return 'curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash';\n    }\n    case LinuxDistroType.REDHAT: {\n      return 'curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.rpm.sh | sudo bash';\n    }\n    default: {\n      // Most other distributions have git-lfs in their standard repositories\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/logUtils.ts",
    "content": "import * as Constants from '../core/constants';\n\nexport function wrapInColor(\n  s: string | undefined,\n  color: Constants.ANSI_COLORS,\n  reset_color: Constants.ANSI_COLORS = Constants.ANSI_COLORS.RESET_COLOR,\n): string {\n  return `${color}${s ?? ''}${reset_color}`;\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/pathUtils.ts",
    "content": "import path from 'path';\n\n/**\n * Version of path.relative() that resolves equal paths to .\n */\nexport function relativePathTo(from: string, to: string): string {\n  const output = path.relative(from, to);\n  if (!output) {\n    return '.';\n  }\n  return output;\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/skillsAdapters.ts",
    "content": "import * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport type { SkillMeta } from './skillsRegistry';\n\nexport interface SkillAdapter {\n  name: string;\n  detect(): boolean;\n  install(skillName: string, content: string, meta: SkillMeta): void;\n  remove(skillName: string): void;\n  listInstalled(): string[];\n}\n\n// ClaudeCodeAdapter: installs to ~/.claude/plugins/valdi/skills/<name>/SKILL.md\nconst ClaudeCodeAdapter: SkillAdapter = {\n  name: 'claude',\n  detect() {\n    const claudeDir = path.join(os.homedir(), '.claude');\n    return fs.existsSync(claudeDir);\n  },\n  install(skillName: string, content: string, meta: SkillMeta) {\n    const skillDir = path.join(os.homedir(), '.claude', 'plugins', 'valdi', 'skills', skillName);\n    fs.mkdirSync(skillDir, { recursive: true });\n    const frontmatter = `---\\nname: ${meta.name}\\ndescription: ${meta.description}\\n---\\n\\n`;\n    fs.writeFileSync(path.join(skillDir, 'SKILL.md'), frontmatter + content, 'utf8');\n  },\n  remove(skillName: string) {\n    const skillDir = path.join(os.homedir(), '.claude', 'plugins', 'valdi', 'skills', skillName);\n    if (fs.existsSync(skillDir)) {\n      fs.rmSync(skillDir, { recursive: true, force: true });\n    }\n  },\n  listInstalled() {\n    const skillsDir = path.join(os.homedir(), '.claude', 'plugins', 'valdi', 'skills');\n    if (!fs.existsSync(skillsDir)) return [];\n    return fs\n      .readdirSync(skillsDir)\n      .filter((entry) => fs.statSync(path.join(skillsDir, entry)).isDirectory());\n  },\n};\n\n// CursorAdapter: installs to ~/.cursor/rules/valdi-<name>.mdc (global)\nconst CursorAdapter: SkillAdapter = {\n  name: 'cursor',\n  detect() {\n    const cursorDir = path.join(os.homedir(), '.cursor');\n    return fs.existsSync(cursorDir);\n  },\n  install(skillName: string, content: string, meta: SkillMeta) {\n    const rulesDir = path.join(os.homedir(), '.cursor', 'rules');\n    fs.mkdirSync(rulesDir, { recursive: true });\n    const frontmatter = `---\\ndescription: ${meta.description}\\nalwaysApply: false\\n---\\n\\n`;\n    fs.writeFileSync(path.join(rulesDir, `valdi-${skillName}.mdc`), frontmatter + content, 'utf8');\n  },\n  remove(skillName: string) {\n    const filePath = path.join(os.homedir(), '.cursor', 'rules', `valdi-${skillName}.mdc`);\n    if (fs.existsSync(filePath)) {\n      fs.unlinkSync(filePath);\n    }\n  },\n  listInstalled() {\n    const rulesDir = path.join(os.homedir(), '.cursor', 'rules');\n    if (!fs.existsSync(rulesDir)) return [];\n    return fs\n      .readdirSync(rulesDir)\n      .filter((f) => f.startsWith('valdi-') && f.endsWith('.mdc'))\n      .map((f) => f.replace(/^valdi-/u, '').replace(/\\.mdc$/u, ''));\n  },\n};\n\n// CopilotAdapter: appends to ./.github/copilot-instructions.md in CWD (project-scoped)\nconst CopilotAdapter: SkillAdapter = {\n  name: 'copilot',\n  detect() {\n    const githubDir = path.join(process.cwd(), '.github');\n    return fs.existsSync(githubDir);\n  },\n  install(skillName: string, content: string, _meta: SkillMeta) {\n    const githubDir = path.join(process.cwd(), '.github');\n    fs.mkdirSync(githubDir, { recursive: true });\n    const instructionsFile = path.join(githubDir, 'copilot-instructions.md');\n    const section = `\\n\\n## ${skillName}\\n\\n${content}`;\n    if (fs.existsSync(instructionsFile)) {\n      fs.appendFileSync(instructionsFile, section, 'utf8');\n    } else {\n      fs.writeFileSync(instructionsFile, `# Copilot Instructions${section}`, 'utf8');\n    }\n  },\n  remove(skillName: string) {\n    const instructionsFile = path.join(process.cwd(), '.github', 'copilot-instructions.md');\n    if (!fs.existsSync(instructionsFile)) return;\n    const contents = fs.readFileSync(instructionsFile, 'utf8');\n    // Remove section starting with ## <skillName> up to next ## or end of file\n    const sectionRegex = new RegExp(\n      `\\\\n\\\\n## ${skillName}\\\\n[\\\\s\\\\S]*?(?=\\\\n\\\\n## |$)`,\n      'u',\n    );\n    const updated = contents.replace(sectionRegex, '');\n    fs.writeFileSync(instructionsFile, updated, 'utf8');\n  },\n  listInstalled() {\n    const instructionsFile = path.join(process.cwd(), '.github', 'copilot-instructions.md');\n    if (!fs.existsSync(instructionsFile)) return [];\n    const contents = fs.readFileSync(instructionsFile, 'utf8');\n    const matches = contents.match(/^## (valdi-\\S+)/gmu);\n    if (!matches) return [];\n    return matches.map((m) => m.replace(/^## /u, ''));\n  },\n};\n\n// GenericAdapter: installs to ~/.valdi/skills/<name>.md\nconst GenericAdapter: SkillAdapter = {\n  name: 'generic',\n  detect() {\n    // Always available as a fallback\n    return true;\n  },\n  install(skillName: string, content: string, _meta: SkillMeta) {\n    const skillsDir = path.join(os.homedir(), '.valdi', 'skills');\n    fs.mkdirSync(skillsDir, { recursive: true });\n    fs.writeFileSync(path.join(skillsDir, `${skillName}.md`), content, 'utf8');\n  },\n  remove(skillName: string) {\n    const filePath = path.join(os.homedir(), '.valdi', 'skills', `${skillName}.md`);\n    if (fs.existsSync(filePath)) {\n      fs.unlinkSync(filePath);\n    }\n  },\n  listInstalled() {\n    const skillsDir = path.join(os.homedir(), '.valdi', 'skills');\n    if (!fs.existsSync(skillsDir)) return [];\n    return fs\n      .readdirSync(skillsDir)\n      .filter((f) => f.endsWith('.md'))\n      .map((f) => f.replace(/\\.md$/u, ''));\n  },\n};\n\nexport const ALL_ADAPTERS: SkillAdapter[] = [\n  ClaudeCodeAdapter,\n  CursorAdapter,\n  CopilotAdapter,\n  GenericAdapter,\n];\n\nexport function detectAdapters(): SkillAdapter[] {\n  return ALL_ADAPTERS.filter((a) => a.detect());\n}\n\nexport function getAdapterByName(name: string): SkillAdapter | undefined {\n  return ALL_ADAPTERS.find((a) => a.name === name);\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/skillsRegistry.ts",
    "content": "import * as path from 'path';\nimport * as fs from 'fs';\n\nexport interface SkillMeta {\n  name: string;\n  description: string;\n  tags: string[];\n  path: string;\n  /** 'framework' = for working on the Valdi repo itself (runtime, compiler, build rules)\n   *  'client'    = for creating / updating / testing Valdi modules\n   *  A skill may belong to both categories. */\n  category: ('framework' | 'client')[];\n}\n\nexport interface SkillRegistry {\n  version: string;\n  skills: SkillMeta[];\n}\n\n// Returns the bundled-skills/ directory shipped inside the npm package\n// (sits next to dist/ after build).\nfunction findBundledSkillsDir(): string | null {\n  const candidate = path.resolve(__dirname, '..', '..', 'bundled-skills');\n  return fs.existsSync(path.join(candidate, 'registry.json')) ? candidate : null;\n}\n\n// --- Public API ---\n\n// Load registry from the bundled skills shipped in the npm package.\nexport function loadLocalRegistry(): SkillRegistry | null {\n  const bundledDir = findBundledSkillsDir();\n  if (bundledDir == null) return null;\n  try {\n    return JSON.parse(\n      fs.readFileSync(path.join(bundledDir, 'registry.json'), 'utf8'),\n    ) as SkillRegistry;\n  } catch {\n    return null;\n  }\n}\n\n// Used by list/install/update — reads from the bundled skills, no network.\nexport async function fetchRegistry(): Promise<SkillRegistry> {\n  const local = loadLocalRegistry();\n  if (local != null) {\n    return local;\n  }\n  throw new Error(\n    'No bundled skills found. Re-install @snap/valdi to get the latest bundle.',\n  );\n}\n\n// Read skill content from the bundled skills shipped in the npm package.\nexport async function fetchSkillContent(skillPath: string): Promise<string> {\n  const bundledDir = findBundledSkillsDir();\n  if (bundledDir != null) {\n    const candidate = path.join(bundledDir, skillPath);\n    if (fs.existsSync(candidate)) {\n      return fs.readFileSync(candidate, 'utf8');\n    }\n  }\n  throw new Error(\n    `Skill content not found for \"${skillPath}\". Re-install @snap/valdi to get the latest bundle.`,\n  );\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/stringUtils.spec.ts",
    "content": "import 'jasmine';\nimport { sanitizeProjectName, toPascalCase, toSnakeCase, validateProjectName } from './stringUtils';\n\ndescribe('stringUtils', () => {\n    it('converts strings to pascal case', () => {\n      const testCases: [string, string][] = [['hello', 'Hello'], ['hello world', 'HelloWorld'], ['My New Module', 'MyNewModule'], ['my_new_module', 'MyNewModule']];\n      testCases.forEach(([input, expected]) => {\n        expect(toPascalCase(input)).toBe(expected);\n      });\n    });\n\n    it('converts strings to snake case', () => {\n      const testCases: [string, string][] = [['hello', 'hello'], ['hello world', 'hello_world']];\n      testCases.forEach(([input, expected]) => {\n        expect(toSnakeCase(input)).toBe(expected);\n      });\n    });\n\n    describe('sanitizeProjectName', () => {\n      it('replaces dashes with underscores', () => {\n        expect(sanitizeProjectName('my-project')).toBe('my_project');\n        expect(sanitizeProjectName('my-cool-app')).toBe('my_cool_app');\n      });\n\n      it('preserves original case', () => {\n        expect(sanitizeProjectName('MyProject')).toBe('MyProject');\n        expect(sanitizeProjectName('MY_PROJECT')).toBe('MY_PROJECT');\n        expect(sanitizeProjectName('testNewModule')).toBe('testNewModule');\n      });\n\n      it('removes invalid characters', () => {\n        expect(sanitizeProjectName('my project!')).toBe('myproject');\n        expect(sanitizeProjectName('my@project#')).toBe('myproject');\n        expect(sanitizeProjectName('my.project')).toBe('myproject');\n      });\n\n      it('prefixes with underscore if starts with number', () => {\n        expect(sanitizeProjectName('123project')).toBe('_123project');\n        expect(sanitizeProjectName('7-eleven')).toBe('_7_eleven');\n      });\n\n      it('handles mixed cases', () => {\n        expect(sanitizeProjectName('My-Cool_Project123')).toBe('My_Cool_Project123');\n      });\n\n      it('handles already valid names', () => {\n        expect(sanitizeProjectName('my_project')).toBe('my_project');\n        expect(sanitizeProjectName('myproject')).toBe('myproject');\n        expect(sanitizeProjectName('my_project_123')).toBe('my_project_123');\n      });\n    });\n\n    describe('validateProjectName', () => {\n      it('rejects empty names', () => {\n        expect(validateProjectName('')).toBeTruthy();\n        expect(validateProjectName('   ')).toBeTruthy();\n      });\n\n      it('rejects reserved words (case-insensitive)', () => {\n        expect(validateProjectName('test')).toContain('reserved word');\n        expect(validateProjectName('Test')).toContain('reserved word');\n        expect(validateProjectName('TEST')).toContain('reserved word');\n        expect(validateProjectName('build')).toContain('reserved word');\n        expect(validateProjectName('workspace')).toContain('reserved word');\n        expect(validateProjectName('native')).toContain('reserved word');\n        expect(validateProjectName('package')).toContain('reserved word');\n      });\n\n      it('accepts valid names with mixed case', () => {\n        expect(validateProjectName('my_project')).toBeNull();\n        expect(validateProjectName('myproject')).toBeNull();\n        expect(validateProjectName('my_cool_app')).toBeNull();\n        expect(validateProjectName('project123')).toBeNull();\n        expect(validateProjectName('MyProject')).toBeNull();\n        expect(validateProjectName('testNewModule')).toBeNull();\n      });\n\n      it('accepts names with dashes (they will be sanitized)', () => {\n        expect(validateProjectName('my-project')).toBeNull();\n        expect(validateProjectName('my-cool-app')).toBeNull();\n      });\n\n      it('rejects names with only invalid characters', () => {\n        expect(validateProjectName('!!!')).toBeTruthy();\n        expect(validateProjectName('...')).toBeTruthy();\n        expect(validateProjectName('@#$')).toBeTruthy();\n      });\n\n      it('handles names that start with numbers', () => {\n        // These are valid because sanitization will prefix with underscore\n        expect(validateProjectName('123project')).toBeNull();\n      });\n    });\n});\n\n"
  },
  {
    "path": "npm_modules/cli/src/utils/stringUtils.ts",
    "content": "const wordSplitRegex = /[\\W_]/;\n\n// Bazel and common programming language reserved words that should not be used as project names\nconst RESERVED_PROJECT_NAMES = new Set([\n  // Bazel reserved words\n  'test',\n  'tests',\n  'build',\n  'workspace',\n  'native',\n  'rule',\n  'package',\n  'glob',\n  'select',\n  'repository',\n  'external',\n  'bazel',\n  // Common programming language keywords that might cause issues\n  'class',\n  'function',\n  'var',\n  'let',\n  'const',\n  'if',\n  'else',\n  'for',\n  'while',\n  'return',\n  'import',\n  'export',\n  'module',\n  'require',\n  // Other problematic names\n  'main',\n  'lib',\n  'src',\n  'bin',\n  'data',\n  'config',\n]);\n\n/**\n * Sanitizes a project name to be safe for use in Bazel rules and generated code.\n * - Replaces dashes with underscores\n * - Removes any characters that are not alphanumeric or underscore\n * - Ensures the name starts with a letter or underscore\n * - Preserves original case (Bazel target names are case-sensitive)\n */\nexport function sanitizeProjectName(name: string): string {\n  // Replace dashes with underscores\n  let sanitized = name.replace(/-/g, '_');\n  \n  // Remove any characters that are not alphanumeric or underscore\n  sanitized = sanitized.replace(/[^a-zA-Z0-9_]/g, '');\n  \n  // Ensure it starts with a letter or underscore\n  if (sanitized.length > 0 && /^[0-9]/.test(sanitized)) {\n    sanitized = '_' + sanitized;\n  }\n  \n  return sanitized;\n}\n\n/**\n * Validates a project name and returns an error message if invalid, or null if valid.\n */\nexport function validateProjectName(name: string): string | null {\n  if (!name || name.trim().length === 0) {\n    return 'Project name cannot be empty.';\n  }\n  \n  const sanitized = sanitizeProjectName(name);\n  \n  if (sanitized.length === 0) {\n    return 'Project name must contain at least one alphanumeric character.';\n  }\n  \n  // Check if the sanitized name (case-insensitive) is a reserved word\n  if (RESERVED_PROJECT_NAMES.has(sanitized.toLowerCase())) {\n    return `Project name \"${name}\" (sanitized to \"${sanitized}\") is a reserved word and cannot be used. Please choose a different name.`;\n  }\n  \n  // Warn if the name was significantly changed during sanitization\n  if (sanitized !== name.replace(/-/g, '_')) {\n    return `Project name \"${name}\" contains invalid characters. It will be sanitized to \"${sanitized}\". Please use only letters, numbers, underscores, and dashes.`;\n  }\n  \n  return null;\n}\n\nexport function toPascalCase(str: string): string {\n    const words = str.trim().toLowerCase().split(wordSplitRegex);\n    return words.reduce((acc, curr) => {\n        const [firstChar, ...rest] = curr;\n        const pascalCaseWord = firstChar?.toUpperCase()?.concat(rest.join('')) ?? '';\n        return acc + pascalCaseWord;\n    }, '');\n}\n\nexport function toSnakeCase(str: string): string {\n    const words = str.trim().toLowerCase().split(wordSplitRegex);\n    return words.join('_');\n}"
  },
  {
    "path": "npm_modules/cli/src/utils/tempDir.ts",
    "content": "import crypto from 'crypto';\nimport * as fs from 'node:fs';\nimport os from 'os';\nimport path from 'path';\n\nexport function makeTempDir(): string {\n  return path.join(os.tmpdir(), crypto.randomUUID());\n}\n\nexport async function withTempDir<T>(receiveTempDir: (tempDir: string) => Promise<T>): Promise<T> {\n  const tempDir = makeTempDir();\n\n  fs.mkdirSync(tempDir);\n\n  try {\n    return await receiveTempDir(tempDir);\n  } finally {\n    try {\n      fs.rmdirSync(tempDir);\n    } catch {\n      // no-op\n    }\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/src/utils/zipUtils.ts",
    "content": "import path from 'node:path';\n\nimport extract from 'extract-zip';\n\nexport async function decompressTo(inputFilePath: string, outputFilePath: string): Promise<void> {\n  const archive = path.resolve(inputFilePath);\n  const destination = path.resolve(outputFilePath);\n\n  try {\n    await extract(archive, { dir: destination });\n  } catch (error: unknown) {\n    throw new Error(`Failed to extract “${archive}” → “${destination}”: ${(error as Error).message}`);\n  }\n}\n"
  },
  {
    "path": "npm_modules/cli/test/ValdiSmokeTest.ts",
    "content": "/* eslint-disable @typescript-eslint/no-non-null-assertion */\nimport assert from 'node:assert';\nimport { mkdir, rm } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport { afterEach, beforeEach, describe, it } from 'node:test';\nimport { lookForOutput } from './helpers/AsyncHelpers';\nimport { run } from './helpers/CommandHelpers';\nimport {\n  atBeginning,\n  createProject,\n  findDefinitionForTokenInFile,\n  insertLineAfter,\n  insertLineBefore,\n  lineMatches,\n} from './helpers/ProjectHelpers';\nimport { type ProjectConfig } from './helpers/ProjectHelpers';\nimport { type TSServerClient, createClient, lineAndOffset } from './helpers/TypeScriptClient';\nimport { error } from 'node:console';\n\n\nconst PROJECT_ROOT = process.env['PROJECT_ROOT']!;\nconst PROJECT_NAME = process.env['PROJECT_NAME'] ?? basename(PROJECT_ROOT);\n\n// eslint-disable-next-line unicorn/prefer-module\nconst runtimeDir = __dirname;\n\nconst OPEN_SOURCE_DIR = process.env['OPEN_SOURCE_DIR']!;\n\nvoid describe('valdi ui app', () => {\n  let client: TSServerClient;\n  let project: ProjectConfig;\n\n  beforeEach(async () => {\n    await bootstrap(PROJECT_ROOT, PROJECT_NAME, 'ui_application');\n    // Create a tsserver client to interact with tsserver\n    client = createClient(runtimeDir);\n    // Create the project instance which is a wrapper to find and modify files in valdi modules\n    project = createProject(PROJECT_NAME, PROJECT_ROOT);\n  });\n\n  afterEach(async () => {\n    // Shuts down the tsserver instance for this test\n    await client.disconnect();\n  });\n\n  void describe('cli', () => {\n    void it('build ios', async () => {\n      const task = run('valdi', ['build', 'ios']);\n      await lookForOutput({ stderr: [/Build completed successfully, \\d+ total actions?/] }, task);\n    });\n\n    void it('build macos', async () => {\n      const task = run('valdi', ['build', 'macos']);\n      await lookForOutput({ stderr: [/Build completed successfully, \\d+ total actions?/] }, task);\n    });\n\n    void it('build android', { skip: true }, async () => {\n      const task = run('valdi', ['build', 'android']);\n      await lookForOutput({ stderr: [/Build completed successfully, \\d+ total actions?/] }, task);\n    });\n\n    void it('valdi doctor', async () => {\n      const task = run('valdi', ['doctor']);\n      await lookForOutput({ stdout: [\n        'Valdi Doctor Report',\n        'Node.js installation',\n        'Bazel installation',\n        'Android installation',\n        'iOS development',\n        'Java installation',\n        'Development tools'\n      ]}, task)\n    });\n\n    /**\n     * Runs `valdi new_module`\n     * Updates `App.tsx` to import the module and use it\n     * Checks that the tsserver discovers the reference can be found\n     */\n    void it('new_module ui_component', async () => {\n      const moduleName = 'testNewModule';\n      const task = run('valdi', ['new_module', '--skip-checks', '--template', 'ui_component', moduleName]);\n\n      await lookForOutput({ stdout: ['Success! New module directory:'] }, task);\n\n      // Add testNewModule bazel dependency for valdi_app\n      await project.updateFile(\n        'BUILD.bazel',\n        'valdi_app',\n        insertLineAfter(lineMatches('deps = ['), `\\t\\t\"//modules/${moduleName}\",\\n`),\n      );\n\n      // Insert new import statement for the new module at the top of the file\n      await project.updateFile(\n        'App.tsx',\n        'valdi_app',\n        insertLineBefore(() => true, `import { NewModuleComponent } from '${moduleName}/src/NewModuleComponent';\\n`),\n      );\n      // Try to use the component in onRender\n      await project.updateFile(\n        'App.tsx',\n        'valdi_app',\n        insertLineBefore(lineMatches('</view>;'), '<NewModuleComponent />\\n'),\n      );\n\n      await run('valdi', ['projectsync'], { pipeOutput: true }).wait();\n\n      // We updated the file on the filesystem, the ts client needs to know to refresh the file\n      const file = await project.findFile('App.tsx', 'valdi_app');\n      await client.command('open', { file });\n\n      // Throws if it cannot find a valid TypeScript code reference\n      await findDefinitionForTokenInFile({ project, client }, 'NewModuleComponent />', 'App.tsx', 'valdi_app');\n\n      await client.command('close', { file });\n    });\n  });\n\n  void describe('typescript', () => {\n    void it('finds project references', async () => {\n      await client.command('open', { file: await project.findFile('App.tsx', 'valdi_app') });\n\n      await Promise.all(\n        ['StatefulComponent', 'Label', 'Device', 'view>', 'style='].map(token =>\n          findDefinitionForTokenInFile({ client, project }, token, 'App.tsx', 'valdi_app'),\n        ),\n      );\n\n      await client.command('close', { file: await project.findFile('App.tsx', 'valdi_app') });\n    });\n\n    /**\n     * Check for VSCode completions when typing \"<l\" inside the App `onRender` method.\n     *\n     * It should offer `<label` and `<layout`.\n     */\n    void it('finds code completions', async () => {\n      const file = await project.findFile('App.tsx', 'valdi_app');\n      await client.command('open', { file });\n      await client.command('reload', { file });\n\n      const appSource = await project.findFile('App.tsx');\n\n      // Look for the whole definition block of onRender by asking tsserver for the definition\n      const view = await lineAndOffset('onRender', appSource);\n      const onRenderDef = (await client.command('definition', { file: appSource, ...view })) as {\n        body?: { contextEnd: { line: number; offset: number } }[];\n      };\n\n      const defInfo = onRenderDef.body![0]!;\n\n      // Insert the '<' character before the ending \"}\" of onRender\n      const insertionLocation = {\n        file: appSource,\n        line: defInfo.contextEnd.line,\n        endLine: defInfo.contextEnd.line,\n        offset: defInfo.contextEnd.offset - 2,\n        endOffset: defInfo.contextEnd.offset,\n      };\n\n      // Tell tsserver to update its representatin of the file\n      await client.command('change', { insertString: '<l', ...insertionLocation });\n\n      // Ask for the completion info at the place the '<l' was inserted\n      const info = (await client.command('completionInfo', {\n        file: appSource,\n        ...defInfo.contextEnd,\n        offset: defInfo.contextEnd.offset,\n        prefix: 'l',\n      })) as { body?: { entries: { name: string }[] } };\n\n      // We expect certain items to be available as completions\n      const completionsExpected = ['label', 'layout'];\n      const missing = completionsExpected.filter(\n        item => info.body!.entries.some(({ name }) => name === item) === undefined,\n      );\n\n      if (missing.length > 0) {\n        throw new Error('missing completions: ' + missing.join(', '));\n      }\n\n      await client.command('close', { file });\n    });\n\n    void it('has localized strings', async () => {\n      await project.updateFile(\n        'BUILD.bazel',\n        'valdi_app',\n        insertLineBefore(lineMatches('visibility = [\"//visibility:public\"],'), '    strings_dir = \"strings\",\\n'),\n      );\n\n      const strings = {\n        l10nsvc: 'sourcefile',\n        welcome: {\n          defaultMessage: 'Hello World',\n        },\n      };\n\n      await project.createFile('strings/strings-en.json', 'valdi_app', JSON.stringify(strings, null, '  '));\n      await run('valdi', ['projectsync'], { pipeOutput: true }).wait();\n\n      await project.updateFile(\n        'App.tsx',\n        'valdi_app',\n        insertLineBefore(atBeginning, \"import strings from './Strings'\\n\"),\n      );\n\n      const appFile = await project.findFile('App.tsx', 'valdi_app');\n      await client.command('open', { file: appFile });\n      const [pathDescriptor] = await findDefinitionForTokenInFile(\n        { project, client },\n        'strings',\n        'App.tsx',\n        'valdi_app',\n      );\n\n      assert.match(pathDescriptor, /\\/generated_ts\\/valdi_app\\/src\\/Strings\\.d\\.ts:\\d+:\\d+/);\n\n      await client.command('close', { file: appFile });\n    });\n  });\n});\n\nvoid describe('valdi cli app', () => {\n  const CLI_PROJECT_ROOT = join(PROJECT_ROOT, 'valdi_cli_app');\n  const CLI_PROJECT_NAME = basename(CLI_PROJECT_ROOT);\n\n  beforeEach(async () => {\n    await bootstrap(CLI_PROJECT_ROOT, CLI_PROJECT_NAME, 'cli_application');\n  });\n\n  void it('install cli', async () => {\n    const task = run('valdi', ['install', 'cli'], { pipeOutput: true });\n    await lookForOutput(\n      {\n        // means the bazel build was succesful\n        stderr: [/Build completed successfully, \\d+ total actions?/],\n        // The default bootstrapped app logs \"Hello world!\"\n        stdout: ['Hello world!'],\n      },\n      task,\n    );\n  });\n});\n\n/**\n * Sets up a valdi project for tests\n *\n *  - Delete's the existing directory (if any)\n *  - Re-creates the directory\n *  - Changes the currenty working directory to the new directory\n *  - Runs `valdi bootstrap` linked to the OPEN_SOURCE_DIR for `@@valdi`\n *  - Runs `valdi projectsync`\n */\nasync function bootstrap(\n  projectRootPath: string,\n  projectName: string,\n  applicationType: 'ui_application' | 'cli_application',\n) {\n  // Delete and recreate the bootstrapped project\n  await rm(projectRootPath, { recursive: true, force: true }).catch((error) => {\n    // Logging the failure; if it doesn't exist the force flag will handle it \n    console.error('Failed to remove', projectRootPath, ':', error);\n  });\n  await mkdir(projectRootPath, { recursive: true });\n\n  // Run all commands from within the projectRootPath\n  process.chdir(projectRootPath);\n\n  await run(\n    'valdi',\n    ['bootstrap', '-y', `-n=${projectName}`, `-t=${applicationType}`, `-l=${OPEN_SOURCE_DIR}`, '-p', '--with-cleanup'],\n    {\n      pipeOutput: true,\n    },\n  ).wait();\n\n  await run('valdi', ['projectsync'], { pipeOutput: true }).wait();\n}\n"
  },
  {
    "path": "npm_modules/cli/test/helpers/AsyncHelpers.ts",
    "content": "import type { SubCommand } from './CommandHelpers';\nimport { onEachLine } from './StreamHelpers';\n\n/**\n * Create a Promise that rejects after ms milliseconds from the last time it is \"touched\".\n *\n * Returns a promise, a function to reset the timeout, and a function to clear the timeout.\n *\n * The returned promise will never resolve.\n */\nexport function timeoutOnIdle(ms = 30_000): [timeout: Promise<never>, touch: () => void, clear: () => void] {\n  let timer: NodeJS.Timeout;\n  let resetTimer: () => void;\n  let clearTimer: () => void;\n  let complete = false;\n\n  const timeout = new Promise<never>((_resolve, reject) => {\n    clearTimer = () => {\n      complete = true;\n      clearTimeout(timer);\n    };\n\n    resetTimer = () => {\n      clearTimeout(timer);\n      if (complete) {\n        return;\n      }\n      timer = setTimeout(() => {\n        complete = true;\n        reject(new Error('timeout'));\n      }, ms);\n    };\n\n    resetTimer();\n  });\n\n  return [timeout, () => resetTimer(), () => clearTimer()];\n}\n\n/**\n * Given a task created with CommandHelpers.run, watches the STDOUT and/or STDERR\n * for the given strings or expressions.\n *\n * Will timeeout if there's no output after 30 seconds.\n *\n * Rejects if there are queries remaning after the\n */\nexport function lookForOutput(\n  { stdout = [], stderr = [] }: { stdout?: (string | RegExp)[]; stderr?: (string | RegExp)[] },\n  subcommand: SubCommand,\n): Promise<true> {\n  const [idleTimer, touch, complete] = timeoutOnIdle();\n\n  const monitor = (requiredQueries: (string | RegExp)[]) => {\n    let queries = requiredQueries.slice();\n    let onDone: (value: true) => void, onError: (error: Error) => void;\n\n    const promise = new Promise((resolve, reject) => {\n      onDone = resolve;\n      onError = reject;\n\n      // If queries are empty to start with resolve immediately\n      if (queries.length === 0) {\n        resolve(true);\n      }\n    });\n\n    const isDone = () => queries.length === 0;\n\n    return {\n      promise,\n      isDone,\n      onEachLine: onEachLine(line => {\n        touch();\n        queries = queries.filter((query): boolean => {\n          if (typeof query === 'string') {\n            return !line.toString().includes(query);\n          }\n          if (query instanceof RegExp) {\n            return !query.test(line.toString('utf8'));\n          }\n          onError(new Error('invalid query'));\n          return false;\n        });\n\n        if (isDone()) {\n          onDone(true);\n          return;\n        }\n      }),\n    };\n  };\n\n  const stdoutMonitor = monitor(stdout);\n  const stderrMonitor = monitor(stderr);\n\n  subcommand.process.stdout.compose(stdoutMonitor.onEachLine).pipe(process.stdout);\n  subcommand.process.stderr.compose(stderrMonitor.onEachLine).pipe(process.stderr);\n\n  return Promise.race([\n    idleTimer,\n    subcommand\n      .wait()\n      .then((): true => {\n        const allFound = [stderrMonitor, stderrMonitor].every(monitor => monitor.isDone());\n        if (allFound) {\n          return true;\n        }\n        throw new Error('Not all queries found: ' + [stdout, stderr].map(q => q.toString()).join('\\n - '));\n      })\n      .finally(() => complete()),\n  ]);\n}\n"
  },
  {
    "path": "npm_modules/cli/test/helpers/CommandHelpers.ts",
    "content": "import { type ChildProcessWithoutNullStreams, spawn } from 'child_process';\n\nexport interface SubCommand {\n  process: ChildProcessWithoutNullStreams;\n  /**\n   * Resolvess when the command exits\n   */\n  wait: () => Promise<number>;\n}\n\nexport const run = (\n  command: string,\n  args: string[] = [],\n  { pipeOutput = false, cwd }: { pipeOutput?: boolean; cwd?: string } = {},\n): SubCommand => {\n  const child = spawn(command, args, { detached: true, stdio: 'pipe', cwd });\n\n  if (pipeOutput) {\n    child.stderr.pipe(process.stderr);\n    child.stdout.pipe(process.stdout);\n  }\n\n  const complete = new Promise<number>((resolve, reject) => {\n    child.on('close', exitCode => {\n      if (exitCode !== null && exitCode !== 0) {\n        reject(new Error(command + ' ' + args.join(' ') + ' failed with code ' + exitCode.toString()));\n        return;\n      }\n      resolve(exitCode ?? 0);\n    });\n  });\n\n  return {\n    process: child,\n    wait: () => complete,\n  };\n};\n"
  },
  {
    "path": "npm_modules/cli/test/helpers/ProjectHelpers.ts",
    "content": "import { spawn } from 'child_process';\nimport { mkdir, readFile, writeFile } from 'fs/promises';\nimport path from 'path';\nimport { eachLine } from './StreamHelpers';\nimport type { FilePosition, TSServerClient } from './TypeScriptClient';\nimport { lineAndOffset } from './TypeScriptClient';\n\ntype FileUpdater = (contents: Buffer) => Promise<Buffer>;\n\nexport interface ProjectConfig {\n  rootPath: string;\n  name: string;\n  findFile: (fileName: string, withinModule?: string) => Promise<string>;\n  updateFile: (fileName: string, withinModule: string | undefined, change: FileUpdater) => Promise<void>;\n  createFile: (\n    fileName: string,\n    withinModule: string | undefined,\n    source: Parameters<typeof writeFile>[1],\n  ) => Promise<string>;\n}\n\ninterface TaskContext {\n  project: ProjectConfig;\n  client: TSServerClient;\n}\n\nexport function createProject(name: string, rootPath: string): ProjectConfig {\n  const findFile: ProjectConfig['findFile'] = (fileName, withinModule) => {\n    return new Promise((resolve, reject) => {\n      const buffers: Buffer[] = [];\n\n      const errorBuffers: Buffer[] = [];\n      const directory = path.join(...['.', 'modules'].concat(withinModule ?? []));\n\n      const child = spawn('find', [directory]);\n      child.stdout.on('data', (chunk: Buffer) => {\n        buffers.push(chunk);\n      });\n\n      child.stderr.on('data', (chunk: Buffer) => {\n        errorBuffers.push(chunk);\n      });\n\n      child.on('close', code => {\n        if (!!code && code > 0) {\n          reject(new Error('exited with error code: ' + code.toString()));\n        }\n\n        const output = Buffer.concat(buffers).toString('utf8');\n\n        const files = output.trim().split('\\n');\n\n        const found = files.find(file => file.endsWith(`/${fileName}`));\n\n        if (!found) {\n          reject(new Error('File not found: ' + fileName));\n          return;\n        }\n\n        resolve(path.join(rootPath, found));\n      });\n    });\n  };\n  return {\n    name,\n    rootPath,\n    findFile,\n    updateFile: async (file, withinModule, updater) => {\n      const path = await findFile(file, withinModule);\n      const contents = await readFile(path);\n      const updated = await updater(contents);\n      await writeFile(path, updated);\n    },\n    createFile: async (filePath, withinModule, source) => {\n      const fullPath = path.resolve(path.join(rootPath, withinModule ? `modules/${withinModule}` : '.', filePath));\n      await mkdir(path.dirname(fullPath), { recursive: true });\n      await writeFile(fullPath, source);\n      return fullPath;\n    },\n  };\n}\n\ntype LineMatcher = (line: string) => boolean;\n\nexport function lineMatches(search: string | RegExp): LineMatcher {\n  return line => {\n    if (typeof search === 'string') {\n      return line.toString().includes(search);\n    }\n    return search.test(line);\n  };\n}\n\nexport const atBeginning: LineMatcher = () => true;\n\nexport function insertLine(position: 'before' | 'after', search: LineMatcher, content: string | Buffer): FileUpdater {\n  const match = (content: Buffer | string): boolean => search(content.toString());\n  return contents => {\n    let found = false;\n    let buffer = Buffer.from([]);\n    for (const line of eachLine(contents)) {\n      const bufferLine = typeof line === 'string' ? Buffer.from(line) : line;\n      if (position === 'after') {\n        buffer = Buffer.concat([buffer, bufferLine]);\n      }\n      if (!found && match(line)) {\n        found = true;\n        buffer = Buffer.concat([buffer, typeof content === 'string' ? Buffer.from(content) : content]);\n      }\n      if (position === 'before') {\n        buffer = Buffer.concat([buffer, bufferLine]);\n      }\n    }\n    return Promise.resolve(buffer);\n  };\n}\n\nexport function insertLineBefore(search: LineMatcher, content: string | Buffer): FileUpdater {\n  return insertLine('before', search, content);\n}\n\nexport function insertLineAfter(search: LineMatcher, content: string | Buffer): FileUpdater {\n  return insertLine('after', search, content);\n}\n\nexport async function findDefinitionForTokenInFile(\n  context: TaskContext,\n  token: string,\n  file: string,\n  valdiModuleName?: string,\n): Promise<[pathDescriptor: string, position: FilePosition, location: { file: string }, token: string]> {\n  const appSource = await context.project.findFile(file, valdiModuleName);\n  const position = await lineAndOffset(token, appSource);\n  const definition = await context.client.command('definition', {\n    file: appSource,\n    line: position.line,\n    offset: position.offset + 1,\n  });\n\n  if ('success' in definition && !definition['success']) {\n    console.error(definition['message']);\n    throw new Error('failed to get typeDefinition');\n  }\n\n  const body = definition['body'] as { file: string; start: { line: number; offset: number } }[];\n  const location = body.at(0);\n\n  if (!location) {\n    throw new Error('No library definitions found for: ' + token + ' at ' + JSON.stringify(position));\n  }\n\n  return [`${location.file}:${location.start.line}:${location.start.offset}`, position, location, token];\n}\n"
  },
  {
    "path": "npm_modules/cli/test/helpers/StreamHelpers.ts",
    "content": "export function* eachLine(chunkOrString: Buffer | string): Generator<Buffer | string> {\n  let position = 0;\n  const chunk = typeof chunkOrString === 'string' ? Buffer.from(chunkOrString) : chunkOrString;\n  while (position < chunk.length) {\n    const newline = chunk.indexOf('\\n', position);\n    if (newline === -1) {\n      yield chunk.subarray(position).toString('utf8') + '\\n';\n      break;\n    }\n    yield chunk.subarray(position, newline).toString('utf8') + `\\n`;\n    position = newline + 1;\n  }\n}\n\nexport async function* pipeEachLine(source: AsyncGenerator<Buffer | string>): AsyncGenerator<Buffer | string> {\n  for await (const chunk of source) {\n    for (const line of eachLine(chunk)) {\n      yield line;\n    }\n  }\n}\n\n/**\n * Reads the input of source and calls `fn` for each line as a side-effect.\n *\n * The input/output is not changed and cannot be mutated by the callback.\n */\nexport function onEachLine(\n  fn: (line: Buffer) => void,\n): (source: AsyncGenerator<Buffer | string>) => AsyncGenerator<string | Buffer> {\n  return async function* (source) {\n    for await (const line of pipeEachLine(source)) {\n      fn(typeof line === 'string' ? Buffer.from(line) : line);\n      yield line;\n    }\n  };\n}\n"
  },
  {
    "path": "npm_modules/cli/test/helpers/TypeScriptClient.ts",
    "content": "import { EventEmitter } from 'node:events';\nimport { readFile } from 'node:fs/promises';\nimport { run } from './CommandHelpers';\n\nconst HEADER_END = '\\r\\n\\r\\n';\n\nexport interface TSServerClient {\n  command: (command: string, args?: Record<string, unknown>) => Promise<Record<string, unknown>>;\n  disconnect: () => Promise<number>;\n}\n\nexport function createClient(workingDir: string): TSServerClient {\n  const reserveSequence = createNonceService();\n  const read = createMessageBuffer();\n\n  // eslint-disable-next-line unicorn/prefer-event-target\n  const queue = new EventEmitter<{\n    response: [Record<string, unknown>];\n    message: [Record<string, unknown>];\n  }>();\n\n  const service = run('npx', ['tsserver'], {cwd: workingDir});\n\n  service.process.stdout?.on('data', (chunk: Buffer) => {\n    for (const [message] of read(chunk)) {\n      if ('type' in message && message['type'] === 'response') {\n        queue.emit('response', message);\n      }\n      queue.emit('message', message);\n    }\n  });\n\n  service.process.stderr?.pipe(process.stderr)\n\n  const send = (\n    request: Record<string, unknown>,\n    { timeout = 300000 }: { timeout?: number } = {},\n  ): Promise<Record<string, unknown>> => {\n    const seq = reserveSequence();\n    const body = JSON.stringify({\n      seq,\n      ...request,\n    });\n    const payload = body + '\\r\\n';\n    service.process.stdin.write(payload);\n\n    return withTimeout(\n      new Promise(resolve => {\n        const listener = (message: Record<string, unknown>) => {\n          if ('request_seq' in message && message['request_seq'] !== seq) {\n            return;\n          }\n          queue.removeListener('response', listener);\n          resolve(message);\n        };\n        queue.addListener('response', listener);\n      }),\n      timeout,\n    );\n  };\n\n  return {\n    command: (command: string, args?: Record<string, unknown>) =>\n      send({\n        command,\n        ...(args ? { arguments: args } : null),\n      }),\n    disconnect: () => {\n      service.process.stdin.end();\n      service.process.kill('SIGINT');\n      return service.wait();\n    },\n  };\n}\n\nexport interface FilePosition {\n  /**\n   * 1 indexed line number (first line is line 1)\n   */\n  line: number;\n  /**\n   * 1 indexed column number (first column is column 1)\n   */\n  offset: number;\n  /**\n   * 0-index within the file content, the nth character\n   */\n  position: number;\n}\n\nexport async function lineAndOffset(searchToken: string, file: string): Promise<FilePosition> {\n  const buffer = await readFile(file);\n  const position = buffer.indexOf(searchToken);\n\n  if (position === -1) {\n    throw new Error('searchToken not found in file');\n  }\n\n  let line = 1;\n  let index = 0;\n  let offset = -1;\n  while (index <= position) {\n    const nextLine = buffer.indexOf('\\n', index);\n    if (nextLine < position) {\n      line += 1;\n      index = nextLine + 1;\n      continue;\n    } else {\n      offset = position - index;\n      break;\n    }\n  }\n  return { line, offset: Math.max(0, offset), position };\n}\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number | false = 300000): Promise<T> {\n  if (ms === false) {\n    return promise;\n  }\n  let timer: NodeJS.Timeout;\n  return Promise.race([\n    new Promise<never>((_resolve, reject) => {\n      timer = setTimeout(() => reject(new Error('timeout')), ms);\n    }),\n    promise.then(value => {\n      clearTimeout(timer);\n      return value;\n    }),\n  ]);\n}\n\nfunction* eachLine(buffer: Buffer) {\n  let index = 0;\n  while (index > -1 && index < buffer.length) {\n    const endIndex = buffer.indexOf('\\n', index);\n    if (endIndex === -1) {\n      yield buffer.subarray(index);\n      break;\n    }\n    yield buffer.subarray(index, endIndex);\n    index = endIndex;\n  }\n}\n\nfunction* parseHeaders(chunk: Buffer): Generator<[name: string, value: string]> {\n  for (const line of eachLine(chunk)) {\n    const sep = line.indexOf(':');\n    const name = line.subarray(0, sep);\n    const value = line.subarray(sep + 1);\n    yield [name.toString('utf8'), value.toString('utf8').trim()];\n  }\n}\n\n/**\n * Create a statefull message buffer that parses TSServer messages.\n *\n * @returns {(chunk: Buffer) => Generator<[body: Record<string, unknown>, headers: Array<[name: string, value: string]>]>}\n */\nfunction createMessageBuffer(): (\n  chunk: Buffer,\n) => Generator<[body: Record<string, unknown>, headers: Array<[name: string, value: string]>]> {\n  let buffer = Buffer.from([]);\n  /**\n   *\n   * @param {Buffer} chunk\n   * @return {Generator<[body: Record<string, unknown>, headers: Array<[name: string, value: string]>]>}\n   */\n  return function* read(chunk) {\n    buffer = Buffer.concat([buffer, chunk]);\n\n    let position = 0;\n\n    while (position < buffer.length) {\n      const headerSuffix = buffer.indexOf(HEADER_END, position);\n\n      if (headerSuffix === -1) {\n        throw new Error('no headers ' + buffer.toString('utf8'));\n      }\n\n      const headers: [string, string][] = Array.from(parseHeaders(buffer.subarray(position, headerSuffix)));\n\n      // Content length\n      const contentLength = Number.parseInt(\n        headers.find(([name]) => name === 'Content-Length')?.[1] ?? Number.NaN.toString(),\n      );\n      if (Number.isNaN(contentLength)) {\n        throw new TypeError('invalid message, no Content-Length');\n      }\n\n      const bodyStart = headerSuffix + HEADER_END.length;\n      const bodyEnd = bodyStart + contentLength;\n\n      if (bodyEnd > buffer.length) {\n        buffer = buffer.subarray(position);\n        return;\n      }\n\n      yield [JSON.parse(buffer.subarray(bodyStart, bodyEnd).toString('utf8')), headers];\n\n      position = bodyEnd;\n    }\n  };\n}\n\n/**\n * Every time the returned function is called it will return a new sequenc.\n *\n * @returns {() => number}\n */\nfunction createNonceService() {\n  let sequence = 1;\n  return () => {\n    const seq = sequence;\n    sequence += 1;\n    return seq;\n  };\n}\n"
  },
  {
    "path": "npm_modules/cli/tsconfig.dist.json",
    "content": "{\n    \"extends\": \"./tsconfig.json\",\n    \"compilerOptions\": {\n        \"rootDirs\": [],\n        \"rootDir\": \"./src\",\n    },\n    \"include\": [\"./src/**/*.ts\"]\n}"
  },
  {
    "path": "npm_modules/cli/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    // Main settings\n    \"rootDirs\": [\"./src\", \"./test\"],\n    \"outDir\": \"./dist\",\n\n    // Modules\n    \"module\": \"CommonJS\",\n    \"moduleResolution\": \"node\",\n    \"esModuleInterop\": true,\n    \"resolveJsonModule\": true,\n\n    // Type Checking\n    \"exactOptionalPropertyTypes\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitOverride\": true,\n    \"noImplicitReturns\": true,\n    \"noPropertyAccessFromIndexSignature\": true,\n    \"noUncheckedIndexedAccess\": true,\n    \"noUnusedLocals\": false,\n    \"noUnusedParameters\": true,\n    \"strict\": true,\n\n    // Emit\n    \"importHelpers\": true,\n    \"noEmitHelpers\": true,\n    \"noEmitOnError\": true,\n    \"removeComments\": true,\n\n    // Interop Constraints\n    \"allowSyntheticDefaultImports\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"isolatedModules\": true,\n\n    // Language and Environment\n    \"experimentalDecorators\": true,\n    \"lib\": [\"ESNext\"],\n    \"target\": \"ESNext\",\n    \"useDefineForClassFields\": true\n  },\n  \"include\": [\"./src/**/*.ts\", \"./test/**/*.ts\"]\n}\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/.gitignore",
    "content": "dist\nnode_modules"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/package.json",
    "content": "{\n  \"name\": \"@snap/eslint-plugin-valdi\",\n  \"version\": \"1.0.3\",\n  \"description\": \"ESLint rules for the Valdi project\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/Snapchat/Valdi.git\",\n    \"directory\": \"npm_modules/eslint-plugin-valdi\"\n  },\n  \"publishConfig\": { \"access\": \"public\" },\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"build\": \"npm exec --package=typescript@5.7.2 tsc\",\n    \"watch\": \"tsc --watch\",\n    \"test\": \"npm run build && mocha --require tests/mocha-setup.mjs -R progress -c dist/tests/**/*.js\",\n    \"prepare\": \"npm run build\",\n    \"preinstall\": \"npm run build\"\n  },\n  \"author\": \"elee2@snapchat.com\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@typescript-eslint/eslint-plugin\": \"^6.21.0\",\n    \"@typescript-eslint/parser\": \"^6.21.0\",\n    \"@typescript-eslint/utils\": \"^6.21.0\",\n    \"eslint\": \"^8.27.0\",\n    \"typescript\": \"^5.3.3\"\n  }\n}\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/index.ts",
    "content": "import assignTimerIdRule from './rules/assign-timer-id';\nimport attributedTextNoArrayAssignmentRule from './rules/attributed-text-no-array-assignment';\nimport jsxNoLambdaRule from './rules/jsx-no-lambda';\nimport noImplicitIndexImport from './rules/no-implicit-index-import';\nimport mutateStateWithoutSetState from './rules/mutate-state-without-set-state';\nimport noImportFromTestOutsideTestDir from './rules/no-import-from-test-outside-test-dir';\nimport onlyConstEnum from './rules/only-const-enum';\nimport noDeclareTestWithoutDescribe from './rules/no-declare-test-without-describe';\nimport noReactPatterns from './rules/no-react-patterns';\n\nexport = {\n  rules: {\n    'attributed-text-no-array-assignment': attributedTextNoArrayAssignmentRule,\n    'jsx-no-lambda': jsxNoLambdaRule,\n    'only-const-enum': onlyConstEnum,\n    'assign-timer-id': assignTimerIdRule,\n    'no-implicit-index-import': noImplicitIndexImport,\n    'mutate-state-without-set-state': mutateStateWithoutSetState,\n    'no-import-from-test-outside-test-dir': noImportFromTestOutsideTestDir,\n    'no-declare-test-without-describe': noDeclareTestWithoutDescribe,\n    'no-react-patterns': noReactPatterns,\n  },\n};\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/assign-timer-id.ts",
    "content": "import { TSESTree, ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport { TypeFormatFlags } from 'typescript';\n\nconst createRule = ESLintUtils.RuleCreator(name => `assign-timer-id`);\n\nconst rule = createRule({\n  name: 'assign-timer-id',\n  meta: {\n    type: 'problem',\n    docs: {\n      description: 'Ensures that timer IDs are assigned to an identifier or member so they can be cleaned up.',\n      recommended: 'strict',\n    },\n    messages: {\n      assignTimerId: 'Timer id should assign to an identifier or member for cleaning up.',\n    },\n    schema: [], // no options\n  },\n  defaultOptions: [],\n  create(context) {\n    function isZeroDelay(delayValue: TSESTree.CallExpressionArgument) {\n      return (\n        delayValue === undefined || (delayValue && delayValue.type === 'Literal' && Number(delayValue.value) === 0)\n      );\n    }\n\n    return {\n      CallExpression(node: TSESTree.CallExpression) {\n        let calleeName: string | undefined;\n        if (node.callee.type === 'Identifier') {\n          calleeName = node.callee.name;\n        } else if (node.callee.type === 'MemberExpression' && node.callee.property.type === 'Identifier') {\n          calleeName = node.callee.property.name;\n        }\n        if (!calleeName) {\n          return;\n        }\n\n        const timeoutExpressions = [\n          'setTimeout',\n          'setTimeoutInterruptible',\n          'setTimeoutConfigurable',\n          'setTimeoutUninterruptible',\n        ];\n        const isTimeout = timeoutExpressions.includes(calleeName);\n        const isInterval = calleeName === 'setInterval';\n        const delayValue = node.arguments[1];\n\n        if (isTimeout && isZeroDelay(delayValue)) {\n          return;\n        }\n\n        if (isTimeout || isInterval) {\n          const parent = node.parent;\n          if (parent.type === 'AssignmentExpression' && parent.right === node) {\n            return;\n          }\n          if (parent.type === 'VariableDeclarator' && parent.init === node) {\n            return;\n          }\n          if (parent.type === 'ReturnStatement' && parent.argument === node) {\n            return;\n          }\n          context.report({\n            node,\n            messageId: 'assignTimerId',\n          });\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/attributed-text-no-array-assignment.ts",
    "content": "import { TSESTree, ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport { TypeFormatFlags } from 'typescript';\n\nconst createRule = ESLintUtils.RuleCreator(\n  name =>\n    `https://github.com/Snapchat/Valdi/blob/main/src/valdi_modules/src/valdi/valdi_core/src/utils/AttributedTextBuilder.ts`,\n);\n\nconst rule = createRule({\n  name: 'attributed-text-no-array-assignment',\n  meta: {\n    type: 'problem',\n    docs: {\n      description: \"Ensures that the AttributedText type doesn't get directly assigned to an array.\",\n      recommended: 'strict',\n    },\n    messages: {\n      incorrectInitializer:\n        'Variable that resolves to AttributedText should not be initialized as an array. Use AttributedTextBuilder instead.',\n      incorrectAssignment:\n        'Variable that resolves to AttributedText should not be assigned to an array. Use AttributedTextBuilder instead.',\n      incorrectJSXAttribute:\n        'JSX attribute that resolves to AttributedText should not be assigned to an array. Use AttributedTextBuilder instead.',\n    },\n    schema: [], // no options\n  },\n  defaultOptions: [],\n  create(context) {\n    const parserServices = ESLintUtils.getParserServices(context);\n    const checker = parserServices?.program?.getTypeChecker();\n\n    function getTypesOfNode(node: TSESTree.Node): string[] {\n      const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n      const type = checker.getTypeAtLocation(tsNode);\n      if (type.isUnion()) {\n        return type.types.map(type => checker.typeToString(type));\n      }\n      return [checker.typeToString(type)];\n    }\n\n    function getTypesOfJSXAttribute(node: TSESTree.JSXOpeningElement, attributeName: string): string[] {\n      const className = node.name;\n      if (className.type !== AST_NODE_TYPES.JSXIdentifier) {\n        return [];\n      }\n\n      const classSymbol = checker.getSymbolAtLocation(parserServices?.esTreeNodeToTSNodeMap.get(className));\n      if (!classSymbol) {\n        return [];\n      }\n\n      const attribute = checker.getDeclaredTypeOfSymbol(classSymbol)?.getProperty(attributeName);\n      if (!attribute) {\n        return [];\n      }\n\n      const attributeType = checker.getDeclaredTypeOfSymbol(attribute);\n      if (attributeType.isUnion()) {\n        return attributeType.types.map(type => checker.typeToString(type));\n      }\n      return [checker.typeToString(attributeType)];\n    }\n\n    function checkRule(lhsTypes: string[], rhsExpressionType: AST_NODE_TYPES): boolean {\n      return lhsTypes.includes('AttributedText') && rhsExpressionType == AST_NODE_TYPES.ArrayExpression;\n    }\n\n    return {\n      VariableDeclarator(node: TSESTree.VariableDeclarator) {\n        if (!node.init) {\n          return;\n        }\n\n        if (checkRule(getTypesOfNode(node.id), node.init.type)) {\n          context.report({\n            node,\n            messageId: 'incorrectInitializer',\n          });\n        }\n      },\n\n      AssignmentExpression(node: TSESTree.AssignmentExpression) {\n        if (checkRule(getTypesOfNode(node.left), node.right.type)) {\n          context.report({\n            node,\n            messageId: 'incorrectAssignment',\n          });\n        }\n      },\n\n      JSXOpeningElement(node: TSESTree.JSXOpeningElement) {\n        for (const attribute of node.attributes) {\n          if (\n            attribute.type !== AST_NODE_TYPES.JSXAttribute ||\n            attribute.name.type !== AST_NODE_TYPES.JSXIdentifier ||\n            attribute.value?.type !== AST_NODE_TYPES.JSXExpressionContainer\n          ) {\n            continue;\n          }\n          if (checkRule(getTypesOfJSXAttribute(node, attribute.name.name), attribute.value.expression.type)) {\n            context.report({\n              node: attribute,\n              messageId: 'incorrectJSXAttribute',\n            });\n          }\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/jsx-no-lambda.ts",
    "content": "import { TSESTree, ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport { TypeFormatFlags } from 'typescript';\n\nconst createRule = ESLintUtils.RuleCreator(\n  name =>\n    `https://github.com/Snapchat/Valdi/blob/main/docs/docs/performance-optimization.md#using-callbacks-in-elements`,\n);\n\nconst rule = createRule({\n  name: 'jsx-no-lambda',\n  meta: {\n    type: 'problem',\n    docs: {\n      description: \"Ensures that lambda functions and arrays aren't rendered directly in JSX\",\n      recommended: 'strict',\n    },\n    messages: {\n      incorrectLambda: \"Avoid assigning a lambda function directly to the '{{attributeName}}' JSX attribute.\",\n      incorrectArray:\n        \"Avoid assigning an array directly to the '{{attributeName}}' JSX attribute . Consider storing the array as a member of this component.\",\n    },\n    schema: [], // no options\n  },\n  defaultOptions: [],\n  create(context) {\n    return {\n      JSXAttribute(node: TSESTree.JSXAttribute) {\n        if (node.value?.type !== AST_NODE_TYPES.JSXExpressionContainer) {\n          return;\n        }\n        switch (node.value.expression.type) {\n          case AST_NODE_TYPES.ArrowFunctionExpression:\n          case AST_NODE_TYPES.FunctionExpression:\n            context.report({\n              node: node.value,\n              messageId: 'incorrectLambda',\n              data: {\n                attributeName: node.name.name,\n              },\n            });\n            break;\n          case AST_NODE_TYPES.ArrayExpression:\n            context.report({\n              node: node.value,\n              messageId: 'incorrectArray',\n              data: {\n                attributeName: node.name.name,\n              },\n            });\n            break;\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/mutate-state-without-set-state.ts",
    "content": "import { ESLintUtils } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(name => `https://github.com/Snapchat/Valdi/blob/main/docs/docs/workflow-style-guide.md`);\n\nconst rule = createRule({\n  name: 'mutate-state-without-set-state',\n  meta: {\n    type: 'problem',\n    docs: {\n      description: 'Ensures that clients do not mutate state without calling setState.',\n      recommended: 'strict',\n    },\n    messages: {\n      stateAssignment: 'Assignment to this.state will not update the UI. Use setState() instead.',\n    },\n    schema: [], // no options\n    hasSuggestions: true,\n  },\n  defaultOptions: [],\n  create(context) {\n    return {\n      AssignmentExpression(node) {\n        if (node.left != null && node.operator == '=') {\n          let range = node.left.range;\n          let leftText = context.sourceCode.getText().slice(range[0], range[1]);\n          if (/^this\\.state\\./.test(leftText.toString())) {\n            context.report({\n              messageId: 'stateAssignment',\n              node: node,\n              data: {\n                message: leftText,\n              },\n            });\n          }\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/no-declare-test-without-describe.ts",
    "content": "import { ESLintUtils, TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n  name => `https://github.com/Snapchat/Valdi/blob/main/docs/docs/workflow-style-guide.md`,\n);\n\nconst rule = createRule({\n  name: 'no-declare-test-without-describe',\n  meta: {\n    type: 'problem',\n    docs: {\n      description: 'Ensures that tests are not declared without using describe.',\n      recommended: 'strict',\n    },\n    messages: {\n      declaredTestWithoutDescribe:\n        'Declaration of test cases without using describe will break CI. Please wrap test cases in a describe block.',\n    },\n    schema: [], // no options\n  },\n  defaultOptions: [],\n  create(context) {\n    const filePath = context.filename;\n    const isInTestFolder = filePath.includes('/test/');\n    const isTestExtension = filePath.endsWith('.spec.ts') || filePath.endsWith('.spec.tsx');\n\n    if (!(isInTestFolder && isTestExtension)) return {};\n\n    return {\n      CallExpression(node: TSESTree.CallExpression) {\n        let calleeName: string | undefined;\n        if (node.callee.type === 'Identifier') {\n          calleeName = node.callee.name;\n        } else if (node.callee.type === 'MemberExpression' && node.callee.property.type === 'Identifier') {\n          calleeName = node.callee.property.name;\n        }\n\n        // Ignore non test case declarations\n        if (calleeName !== 'it' && calleeName !== 'valdiIt') {\n          return;\n        }\n\n        const ancestors = context.sourceCode.getAncestors?.(node);\n        const hasDescribe = ancestors\n          ? ancestors.some(ancestor => {\n              if (ancestor.type === 'CallExpression') {\n                // Check if any ancestor of `it` or `valdiIt` is a `describe` call\n                const callee = ancestor.callee;\n                return callee.type === 'Identifier' && callee.name === 'describe';\n              } else if (ancestor.type === 'FunctionDeclaration') {\n                return true;\n              }\n\n              return false;\n            })\n          : false;\n\n        if (!hasDescribe) {\n          context.report({\n            node,\n            messageId: 'declaredTestWithoutDescribe',\n          });\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/no-implicit-index-import.ts",
    "content": "import { TSESTree, ESLintUtils } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(name => `https://github.com/Snapchat/Valdi/blob/main/docs/docs/workflow-style-guide.md`);\n\nconst rule = createRule({\n  name: 'no-implicit-index-import',\n  meta: {\n    type: 'problem',\n    docs: {\n      description:\n        \"Ensures that imports of index files are explicit. Valdi module loader doesn't resolve implicit index so we disallow them to prevent errors at runtime.\",\n      recommended: 'strict',\n    },\n    messages: {\n      implicitIndexImport: \"Import of '{{importPath}}' should be explicit, not implicit, append /index\",\n      changeToExplicitImport: \"Change to explicit import '{{importPath}}/index'\",\n    },\n    schema: [], // no options\n    hasSuggestions: true,\n  },\n  defaultOptions: [],\n  create(context) {\n    return {\n      ImportDeclaration(node: TSESTree.ImportDeclaration) {\n        if (node.source.value.endsWith('/src')) {\n          context.report({\n            node: node,\n            messageId: 'implicitIndexImport',\n            data: {\n              importPath: node.source.value,\n            },\n            suggest: [\n              {\n                messageId: 'changeToExplicitImport',\n                data: {\n                  importPath: node.source.value,\n                },\n                fix: fixer => {\n                  return fixer.replaceText(node.source, `'${node.source.value}/index'`);\n                },\n              },\n            ],\n          });\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/no-import-from-test-outside-test-dir.ts",
    "content": "import { ESLintUtils, TSESTree } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(name => `https://github.com/Snapchat/Valdi/blob/main/docs/docs/workflow-style-guide.md`);\n\nconst rule = createRule({\n  name: 'no-import-from-test-outside-test-dir',\n  meta: {\n    type: 'problem',\n    docs: {\n      description: 'Ensures that non-test files do not import from tests directory.',\n      recommended: 'strict',\n    },\n    messages: {\n      importTestFromOutside:\n        \"Import of '{{importPath}}' from non-test directory could result in unexpected behavior between development and production environments. Consider refactoring to avoid.\",\n    },\n    schema: [], // no options\n  },\n  defaultOptions: [],\n  create(context) {\n    const isTestFile = context.filename.includes('/test/');\n\n    return {\n      ImportDeclaration(node: TSESTree.ImportDeclaration) {\n        if (isTestFile) return;\n\n        if (node.source.value.includes('/test/')) {\n          context.report({\n            node: node,\n            messageId: 'importTestFromOutside',\n            data: {\n              importPath: node.source.value,\n            },\n          });\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/no-react-patterns.ts",
    "content": "import { TSESTree, ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\n\nconst createRule = ESLintUtils.RuleCreator(\n  name => `https://github.com/Snapchat/Valdi/blob/main/docs/docs/ai-tooling.md`,\n);\n\nconst REACT_HOOKS = [\n  'useState',\n  'useEffect',\n  'useContext',\n  'useReducer',\n  'useCallback',\n  'useMemo',\n  'useRef',\n  'useImperativeHandle',\n  'useLayoutEffect',\n  'useDebugValue',\n  'useDeferredValue',\n  'useTransition',\n  'useId',\n  'useSyncExternalStore',\n  'useInsertionEffect',\n];\n\n/**\n * Helper function to recursively check if an expression contains JSX.\n * Handles direct JSX, ternaries, logical expressions, and nested combinations.\n */\nfunction containsJSX(node: TSESTree.Expression | TSESTree.SpreadElement | null | undefined): boolean {\n  if (!node) return false;\n\n  // Direct JSX\n  if (node.type === AST_NODE_TYPES.JSXElement || node.type === AST_NODE_TYPES.JSXFragment) {\n    return true;\n  }\n\n  // Ternary: condition ? <view /> : <text />\n  if (node.type === AST_NODE_TYPES.ConditionalExpression) {\n    return containsJSX(node.consequent) || containsJSX(node.alternate);\n  }\n\n  // Logical: condition && <view /> or condition || <view />\n  if (node.type === AST_NODE_TYPES.LogicalExpression) {\n    return containsJSX(node.left) || containsJSX(node.right);\n  }\n\n  // Parenthesized expressions: (<view />)\n  if (node.type === AST_NODE_TYPES.TSAsExpression || node.type === AST_NODE_TYPES.TSNonNullExpression) {\n    return containsJSX(node.expression);\n  }\n\n  return false;\n}\n\nconst rule = createRule({\n  name: 'no-react-patterns',\n  meta: {\n    type: 'problem',\n    docs: {\n      description: 'Prevents React patterns that do not exist in Valdi',\n      recommended: 'error',\n    },\n    messages: {\n      reactImport: 'Do not import from \"react\". Valdi is not React. Use \"valdi_core\" instead.',\n      reactHook:\n        'React hook \"{{hookName}}\" does not exist in Valdi. Use class properties and lifecycle methods instead. See https://github.com/Snapchat/Valdi/blob/main/docs/docs/ai-tooling.md',\n      functionalComponent:\n        'Functional components do not exist in Valdi. Use class-based components that extend Component. See https://github.com/Snapchat/Valdi/blob/main/docs/docs/ai-tooling.md',\n      returnInRender:\n        'onRender() should return void, not JSX. Write JSX as a statement, not a return value. See https://github.com/Snapchat/Valdi/blob/main/docs/docs/ai-tooling.md',\n      reactComponent:\n        'Do not extend React.Component. Extend Component from \"valdi_core/src/Component\" instead.',\n    },\n    schema: [], // no options\n  },\n  defaultOptions: [],\n  create(context) {\n    return {\n      // Detect imports from 'react'\n      ImportDeclaration(node: TSESTree.ImportDeclaration) {\n        if (node.source.value === 'react') {\n          context.report({\n            node,\n            messageId: 'reactImport',\n          });\n        }\n      },\n\n      // Detect React hooks being called\n      CallExpression(node: TSESTree.CallExpression) {\n        if (node.callee.type === AST_NODE_TYPES.Identifier && REACT_HOOKS.includes(node.callee.name)) {\n          context.report({\n            node,\n            messageId: 'reactHook',\n            data: {\n              hookName: node.callee.name,\n            },\n          });\n        }\n      },\n\n      // Detect functional components (arrow functions returning JSX)\n      'VariableDeclarator > ArrowFunctionExpression'(node: TSESTree.ArrowFunctionExpression) {\n        // Check if the arrow function returns JSX (including ternaries, logical expressions)\n        if (containsJSX(node.body as TSESTree.Expression)) {\n          context.report({\n            node,\n            messageId: 'functionalComponent',\n          });\n          return;\n        }\n        \n        // Check if the arrow function has a block body that returns JSX\n        if (node.body.type === AST_NODE_TYPES.BlockStatement) {\n          const returnStatements = node.body.body.filter(\n            stmt => stmt.type === AST_NODE_TYPES.ReturnStatement,\n          ) as TSESTree.ReturnStatement[];\n          \n          for (const returnStmt of returnStatements) {\n            if (containsJSX(returnStmt.argument)) {\n              context.report({\n                node,\n                messageId: 'functionalComponent',\n              });\n              break;\n            }\n          }\n        }\n      },\n\n      // Detect return statements in onRender() method\n      'MethodDefinition[key.name=\"onRender\"] ReturnStatement'(node: TSESTree.ReturnStatement) {\n        // onRender() should return void, not JSX (including ternaries, logical expressions)\n        if (containsJSX(node.argument)) {\n          context.report({\n            node,\n            messageId: 'returnInRender',\n          });\n        }\n      },\n\n      // Detect extending React.Component\n      ClassDeclaration(node: TSESTree.ClassDeclaration) {\n        if (node.superClass?.type === AST_NODE_TYPES.MemberExpression) {\n          const superClass = node.superClass;\n          if (\n            superClass.object.type === AST_NODE_TYPES.Identifier &&\n            superClass.object.name === 'React' &&\n            superClass.property.type === AST_NODE_TYPES.Identifier &&\n            superClass.property.property.name === 'Component'\n          ) {\n            context.report({\n              node: node.superClass,\n              messageId: 'reactComponent',\n            });\n          }\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/src/rules/only-const-enum.ts",
    "content": "import { TSESTree, ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';\nimport { TypeFormatFlags } from 'typescript';\n\nconst createRule = ESLintUtils.RuleCreator(name => `https://github.com/Snapchat/Valdi/blob/main/docs/docs/workflow-style-guide.md`);\n\nconst rule = createRule({\n  name: 'only-const-enum',\n  meta: {\n    type: 'problem',\n    docs: {\n      description: 'Ensures that enums are only declared as const enums. Only applies to d.ts or d.tsx files.',\n      recommended: 'strict',\n    },\n    messages: {\n      incorrectQualifier:\n        \"Enum '{{enumName}}' must be declared as a const enum in a d.ts or d.tsx file. If you are seeing this error outside of these files, please contact the Valdi team.\",\n    },\n    schema: [], // no options\n  },\n  defaultOptions: [],\n  create(context) {\n    return {\n      TSEnumDeclaration(node: TSESTree.TSEnumDeclaration) {\n        if (!node.const) {\n          context.report({\n            node: node,\n            messageId: 'incorrectQualifier',\n            data: {\n              enumName: node.id.name,\n            },\n          });\n        }\n      },\n    };\n  },\n});\n\nexport default rule;\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/tests/mocha-setup.mjs",
    "content": "import * as mocha from 'mocha';\nimport { RuleTester } from '@typescript-eslint/rule-tester';\nRuleTester.afterAll = mocha.after;\nexport async function mochaGlobalSetup() {}\n"
  },
  {
    "path": "npm_modules/eslint-plugin-valdi/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"nodenext\",\n    \"target\": \"ES2016\",\n    \"outDir\": \"./dist\",\n    \"strict\": true,\n    \"moduleResolution\": \"nodenext\",\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true\n  },\n  \"include\": [\"src/**/*.ts\", \"tests/**/*.ts\"],\n  \"exclude\": [\"node_modules\", \"**/*.spec.ts\"]\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"devDependencies\": {\n    \"@typescript-eslint/eslint-plugin\": \"^8.30.1\",\n    \"@typescript-eslint/parser\": \"^8.30.1\",\n    \"eslint\": \"^9.24.0\"\n  }\n}\n"
  },
  {
    "path": "scripts/config_setup.sh",
    "content": "#!/usr/bin/env bash\n\n# Fail on errors\nset -e\n\nUSER_VALDI_DIR=\"$HOME/.valdi\"\nUSER_VALDI_CONFIG_PATH=\"$USER_VALDI_DIR/config.yaml\"\n\necho\necho \"********************************************************************************\"\necho \"Checking Valdi config exists at $USER_VALDI_CONFIG_PATH...\"\nif [[ -f \"$USER_VALDI_CONFIG_PATH\" ]]; then\n    echo \"$USER_VALDI_CONFIG_PATH already exists!\"\nelse\n    echo \"$USER_VALDI_CONFIG_PATH doesn't exist, creating...\"\n    mkdir -p \"$USER_VALDI_DIR\"\n    echo \"logs_output_dir: ~/.valdi/logs\" > \"$USER_VALDI_CONFIG_PATH\"\nfi"
  },
  {
    "path": "scripts/dev_setup.sh",
    "content": "#!/usr/bin/env bash\n\n# Fail on errors\nset -e\n\nSCRIPT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" >/dev/null && pwd )\"\n\nCURRENT_SYSTEM=`uname`\n\npushd \"$SCRIPT_DIR\"\n\n./verify_not_rosetta.sh\n\n./config_setup.sh\n\n./npm_setup.sh\n\nif [[ $CURRENT_SYSTEM == \"Linux\" ]]\nthen\n    ./linux_dev_setup.sh\nelse\n    ./macos_dev_setup.sh\nfi\n\npopd\n\necho\necho\necho \"-> All done.\"\n\necho \"================================================================================================\"\necho \"Your ~/.bashrc or ~/.zshrc may have been updated, make sure to open a new shell or source it now yourself:\"\necho \"source ~/.bashrc\"\necho \"source ~/.zshrc\"\necho \"================================================================================================\"\n"
  },
  {
    "path": "scripts/linux_deps_setup.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" >/dev/null && pwd)\"\n\nRC_FILE=\"$HOME/.bashrc\"\nif [ -n \"$($SHELL -c 'echo $ZSH_VERSION')\" ]; then\n    RC_FILE=\"$HOME/.zshrc\"\nfi\n\npushd \"$SCRIPT_DIR\"\n\necho\necho \"********************************************************************************\"\necho \"Updating apt-get...\"\nsudo apt-get --quiet update\n\necho\necho \"********************************************************************************\"\necho \"Installing Swift dependencies...\"\nsudo apt-get --quiet --assume-yes install \\\n    curl \\\n    clang \\\n    libicu-dev \\\n    binutils \\\n    git \\\n    gnupg2 \\\n    libc6-dev \\\n    libcurl4-openssl-dev \\\n    libedit2 \\\n    libgcc-9-dev \\\n    libpython3.8 \\\n    libsqlite3-0 \\\n    libstdc++-9-dev \\\n    libxml2-dev \\\n    libz3-dev \\\n    pkg-config \\\n    tzdata \\\n    unzip \\\n    zlib1g-dev\n\nSWIFT_VERSION=swift-5.9.2-RELEASE\necho\necho \"********************************************************************************\"\necho \"Installing Swift: $SWIFT_VERSION\"\nif [ -z \"$SWIFT_TOOLCHAIN_ROOT\" ]\nthen\n    SWIFT_TOOLCHAIN_ROOT=\"$SCRIPT_DIR/valdi-swift-toolchain\"\nfi\n\nmkdir -p \"$SWIFT_TOOLCHAIN_ROOT\"\npushd $SWIFT_TOOLCHAIN_ROOT\n\nSWIFT_PLATFORM=ubuntu18.04\nSWIFT_TOOLCHAIN_NAME=\"$SWIFT_VERSION-$SWIFT_PLATFORM\"\nSWIFT_TOOLCHAIN_DIR=\"$SWIFT_TOOLCHAIN_ROOT/$SWIFT_TOOLCHAIN_NAME\"\nSWIFT_BIN_DIR=\"$SWIFT_TOOLCHAIN_DIR/usr/bin\"\nSWIFT_LIBS_DIR=\"$SWIFT_TOOLCHAIN_DIR/usr/lib/swift/linux\"\n\nif [[ -d \"$SWIFT_TOOLCHAIN_DIR\" ]]; then\n    echo \"$SWIFT_TOOLCHAIN_DIR already exists!\"\nelse\n    SWIFT_WEBROOT=https://download.swift.org\n    SWIFT_BRANCH=swift-5.9.2-release\n    SWIFT_WEBDIR=\"$SWIFT_WEBROOT/$SWIFT_BRANCH/$(echo $SWIFT_PLATFORM | tr -d .)\"\n    SWIFT_BIN_URL=\"$SWIFT_WEBDIR/$SWIFT_VERSION/$SWIFT_VERSION-$SWIFT_PLATFORM.tar.gz\"\n    SWIFT_SIG_URL=\"$SWIFT_BIN_URL.sig\"\n    SWIFT_SIGNING_KEY=A62AE125BBBFBB96A6E042EC925CC1CCED3D1561\n\n    # Download the toolchain and signature\n    curl --progress-bar -fSL \"$SWIFT_BIN_URL\" -o swift.tar.gz \"$SWIFT_SIG_URL\" -o swift.tar.gz.sig\n\n    # Verify the signature\n    gpg --batch --quiet --keyserver keyserver.ubuntu.com --recv-keys \"$SWIFT_SIGNING_KEY\" && gpg --batch --verify swift.tar.gz.sig swift.tar.gz\n\n    # Unpack the toolchain, set libs permissions, and clean up.\n    mkdir -p \"$SWIFT_TOOLCHAIN_DIR\" && tar -xzf swift.tar.gz --directory \"$SWIFT_TOOLCHAIN_DIR\" --strip-components=1 && chmod -R o+r $SWIFT_TOOLCHAIN_DIR/usr/lib/swift && rm -rf swift.tar.gz.sig swift.tar.gz\nfi\n\necho\necho \"********************************************************************************\"\necho \"Updating PATH to contain the Swift toolchain binaries...\"\nif [[ $PATH == *\"$SWIFT_BIN_DIR\"* ]]; then\n    echo \"PATH already contains $SWIFT_BIN_DIR!\"\nelse\n    echo \"\" >>\"$RC_FILE\"\n    echo \"export PATH=\\\"$SWIFT_BIN_DIR:\\${PATH}\\\"\" >>\"$RC_FILE\"\nfi\n\necho\necho \"********************************************************************************\"\necho \"Updating LD_LIBRARY_PATH to contain the Swift toolchain libraries...\"\nif [[ $LD_LIBRARY_PATH == *\"$SWIFT_LIBS_DIR\"* ]]; then\n    echo \"LD_LIBRARY_PATH already contains $SWIFT_LIBS_DIR!\"\nelse\n    echo \"\" >>\"$RC_FILE\"\n    echo \"export LD_LIBRARY_PATH=\\\"$SWIFT_LIBS_DIR:\\${LD_LIBRARY_PATH}\\\"\" >>\"$RC_FILE\"\nfi\npopd\n\necho\necho \"********************************************************************************\"\necho \"Updating LD_LIBRARY_PATH to contain the path to the JavaScriptCore dynamic library...\"\nJSCORE_LIB_DIR=\"$SCRIPT_DIR/../../third-party/jscore/libs/linux/x86_64\"\nif [[ $LD_LIBRARY_PATH == *\"$JSCORE_LIB_DIR\"* ]]; then\n    echo \"LD_LIBRARY_PATH already contains $JSCORE_LIB_DIR!\"\nelse\n    echo \"\" >>\"$RC_FILE\"\n    echo \"export LD_LIBRARY_PATH=\\\"$JSCORE_LIB_DIR:\\${LD_LIBRARY_PATH}\\\"\" >>\"$RC_FILE\"\nfi\npopd\n\nsource \"$RC_FILE\"\n\necho\necho \"********************************************************************************\"\necho \"Installing usbmuxd, adb...\"\nsudo apt-get --assume-yes --quiet install usbmuxd adb\n\necho\necho \"********************************************************************************\"\necho \"Installing Valdi image processing dependencies...\"\nsudo apt-get --assume-yes --quiet install pngquant\n"
  },
  {
    "path": "scripts/linux_dev_setup.sh",
    "content": "#!/bin/bash\n\nset -e\n\nSCRIPT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" >/dev/null && pwd )\"\n\npushd \"$SCRIPT_DIR\"\n\n./linux_deps_setup.sh\n\necho\necho \"********************************************************************************\"\necho \"Installing bazel\"\n\n# Bazel setup from https://bazel.build/install/ubuntu\nsudo apt install apt-transport-https curl gnupg -y\ncurl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor >bazel-archive-keyring.gpg\nsudo mv bazel-archive-keyring.gpg /usr/share/keyrings\necho \"deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8\" | sudo tee /etc/apt/sources.list.d/bazel.list\n\nsudo apt update && sudo apt install bazel\n\nsudo apt update && sudo apt full-upgrade\n\npopd\n"
  },
  {
    "path": "scripts/mac_deps_setup.sh",
    "content": "#!/bin/bash\n\nset -e\n\n# Avoid causing Homebrew to run 'brew cleanup' automatically\nexport HOMEBREW_NO_INSTALL_CLEANUP=1\n\ninstall_or_upgrade() {\n    echo \"Checking $1\"\n    if brew ls --versions \"$1\" >/dev/null; then\n        if (brew outdated | grep \"$1\" >/dev/null); then\n            echo \"Upgrading $1\"\n            brew upgrade \"$1\"\n        fi\n    else\n        echo \"Installing $1\"\n        HOMEBREW_NO_AUTO_UPDATE=1 brew install \"$1\"\n    fi\n}\n\necho\necho \"********************************************************************************\"\necho \"Updating Homebrew...\"\nbrew update\n\necho\necho \"********************************************************************************\"\necho \"Installing/upgrading Homebrew dependencies...\"\ninstall_or_upgrade \"watchman\"\ninstall_or_upgrade \"git-lfs\"\ninstall_or_upgrade \"jq\"\ninstall_or_upgrade \"libimobiledevice\"\ninstall_or_upgrade \"libusbmuxd\"\ninstall_or_upgrade \"libplist\"\n"
  },
  {
    "path": "scripts/macos_dev_setup.sh",
    "content": "#!/bin/bash\n\nset -e\n\nSCRIPT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" >/dev/null && pwd )\"\n\npushd \"$SCRIPT_DIR\"\n\n./mac_deps_setup.sh\n\necho\necho \"********************************************************************************\"\necho \"Will install ios-webkit-debug-proxy\"\nbrew install ios-webkit-debug-proxy\n\npopd\n"
  },
  {
    "path": "scripts/npm_setup.sh",
    "content": "#!/usr/bin/env bash\n\n# Fail on errors\nset -e\n\nCURRENT_SYSTEM=`uname`\n\nif [[ $CURRENT_SYSTEM == \"Linux\" ]]\nthen\n    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash\n    export NVM_DIR=\"$([ -z \"${XDG_CONFIG_HOME-}\" ] && printf %s \"${HOME}/.nvm\" || printf %s \"${XDG_CONFIG_HOME}/nvm\")\"\nelse\n    brew install nvm\n    export NVM_DIR=\"$HOME/.nvm\"\nfi\n\n# Load NVM\n[ -s \"$NVM_DIR/nvm.sh\" ] && \\. \"$NVM_DIR/nvm.sh\"\n\nnvm install v22\nnvm use v22\nnvm alias default v22\n\nnpm install -g npm@8\n"
  },
  {
    "path": "scripts/premerge_check.sh",
    "content": "#!/bin/bash\n\nset -e\n\nSCRIPT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" >/dev/null && pwd )\"\ncd $SCRIPT_DIR/..\n\n# Run dummy tests\nbzl test  --bzl_arch=native //libs/dummy:test --@valdi//bzl/runtime_flags:enable_asserts --@valdi//bzl/runtime_flags:enable_tracing  --@valdi//bzl/runtime_flags:enable_logging\n\n# Build with no asserts,tracing and logging\nbzl run  --bzl_arch=native //libs/dummy:dummy\n\n# Build with everything enabled\nbzl run --bzl_arch=native //libs/dummy:dummy --@valdi//bzl/runtime_flags:enable_asserts --@valdi//bzl/runtime_flags:enable_tracing  --@valdi//bzl/runtime_flags:enable_logging -c opt\n"
  },
  {
    "path": "scripts/verify_not_rosetta.sh",
    "content": "#!/usr/bin/env bash\n\n# Fail on errors\nset -e\n\nCURRENT_SYSTEM=`uname`\n\nif [ \"$CURRENT_SYSTEM\" == \"Darwin\" ] && [ \"$(arch)\" == \"i386\" ] && [ \"$(sysctl sysctl.proc_translated)\" == \"sysctl.proc_translated: 1\" ];\nthen\n    MSG=\"terminal is currently running under rosetta and dev_setup.sh does not support installation in this mode\"\n    PREFIX=\"\"\n    HELPFUL=$'IMPORTANT:\\n\\t1 - With Terminal closed (Important) Go to finder -> /Applications/Utilities/\\n\\t2 - Right Click on Terminal and select \"Get Info\"\\n\\t3 - On the info panel uncheck \"Open using Rosetta\"'\n    if [ $TERM_PROGRAM == \"vscode\" ]\n    then\n        PREFIX=\"VSCode \"\n        HELPFUL=$'IMPORTANT:\\n\\tRerun the script outside of VSCode using the system terminal'\n    fi\n    echo \"$PREFIX$MSG\"\n    echo \"$HELPFUL\"\n    exit 1\nfi"
  },
  {
    "path": "scripts/vscode/install_extensions.sh",
    "content": "#!/bin/bash\n\nSCRIPT_DIR=$(dirname \"$0\")\n\necho\necho \"********************************************************************************\"\necho \"Checking if the 'code' command is installed...\"\ncode --version > /dev/null 2>&1\nCODE_AVAILABLE=$?\n\necho \"Checking if the 'cursor' command is installed...\"\ncursor --version > /dev/null 2>&1\nCURSOR_AVAILABLE=$?\n\nif [ $CODE_AVAILABLE -eq 0 ]; then\n    echo \"'code' command exists!\"\nfi\n\nif [ $CURSOR_AVAILABLE -eq 0 ]; then\n    echo \"'cursor' command exists!\"\nfi\n\nif [ $CODE_AVAILABLE -ne 0 ]; then\n    echo\n    echo \"⚠️ !!!!!!!!!!!! Warning !!!!!!!!!!!!!\"\n    echo \"⚠️ VS Code 'code' command is not installed.\"\n    echo \"⚠️ This is required for the standard Valdi development workflow.\"\n    echo \"⚠️ \"\n    echo \"⚠️ Please do the following:\"\n    echo \"⚠️ * Launch VS Code\"\n    echo \"⚠️ * Open the Command Palette (either F1 or cmd+shift+P)\"\n    echo \"⚠️ * Type 'shell command' and select > Install 'code' command in PATH\"\n    echo \"⚠️ * Restart the terminal for the new PATH to take effect\"\n    echo \"⚠️ * Run open_source/scripts/vscode/install_extensions.sh (or just scripts/dev_setup.sh)\"\n    echo \"⚠️ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\"\n    echo\nfi\n\nif [ $CURSOR_AVAILABLE -ne 0 ]; then\n    echo\n    echo \"⚠️ !!!!!!!!!!!! Warning !!!!!!!!!!!!!\"\n    echo \"⚠️ Cursor 'cursor' command is not installed.\"\n    echo \"⚠️ \"\n    echo \"⚠️ If you want to use cursor, please do the following:\"\n    echo \"⚠️ * Launch Cursor\"\n    echo \"⚠️ * Open the Command Palette (either F1 or cmd+shift+P)\"\n    echo \"⚠️ * Type 'shell command' and select > Install 'cursor' command in PATH\"\n    echo \"⚠️ * Restart the terminal for the new PATH to take effect\"\n    echo \"⚠️ * Run open_source/scripts/vscode/install_extensions.sh (or just scripts/dev_setup.sh)\"\n    echo \"⚠️ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\"\n    echo\nfi\n\nif [ $CODE_AVAILABLE -ne 0 ] && [ $CURSOR_AVAILABLE -ne 0 ]; then\n    exit 1\nfi\n\nif [ $CODE_AVAILABLE -eq 0 ]; then\n    echo\n    echo \"********************************************************************************\"\n    echo \"Installing VS Code extensions...\"\n    echo\n    echo \"Installing valdi-vivaldi...\"\n    code --install-extension \"$SCRIPT_DIR\"/valdi-vivaldi.vsix\n    echo\n    echo \"Installing valdi-debug...\"\n    code --install-extension \"$SCRIPT_DIR\"/valdi-debug.vsix\n    echo\n    echo \"Installing Prettier JS...\"\n    code --install-extension \"esbenp.prettier-vscode\"\n    echo\n    echo \"Installing Vetur\"\n    code --install-extension \"octref.vetur\"\n    echo\n    echo \"Installing ESLint\"\n    code --install-extension \"dbaeumer.vscode-eslint\"\nfi\n\nif [ $CURSOR_AVAILABLE -eq 0 ]; then\n    echo\n    echo \"********************************************************************************\"\n    echo \"Installing Cursor extensions...\"\n    echo\n    echo \"Installing valdi-vivaldi...\"\n    cursor --install-extension \"$SCRIPT_DIR\"/valdi-vivaldi.vsix\n    echo\n    echo \"Installing valdi-debug...\"\n    cursor --install-extension \"$SCRIPT_DIR\"/valdi-debug.vsix\n    echo\n    echo \"Installing Prettier JS...\"\n    cursor --install-extension \"esbenp.prettier-vscode\"\n    echo\n    echo \"Installing Vetur\"\n    cursor --install-extension \"octref.vetur\"\n    echo\n    echo \"Installing ESLint\"\n    cursor --install-extension \"dbaeumer.vscode-eslint\"\nfi\n"
  },
  {
    "path": "snap_drawing/BUILD.bazel",
    "content": "load(\"@bazel_skylib//lib:selects.bzl\", \"selects\")\nload(\"@build_bazel_rules_swift//swift:swift.bzl\", \"swift_interop_hint\")\nload(\"@rules_kotlin//kotlin:android.bzl\", \"kt_android_library\")\nload(\"//bzl:valdi_library.bzl\", \"COMMON_COMPILE_FLAGS\", \"OBJC_ONLY_FLAGS\")\nload(\"//bzl/conditions:custom_selects.bzl\", \"custom_selects\")\n\nCOMPILER_FLAGS = [\n    \"-fno-exceptions\",\n    \"-Wno-deprecated-this-capture\",\n]\n\ncustom_selects.config_setting_inverse(\n    name = \"not_linux\",\n    inverse_of = \"//bzl/conditions:linux\",\n)\n\nselects.config_setting_group(\n    \"lottie_enabled\",\n    match_all = [\n        \":not_linux\",\n    ],\n)\n\ncc_library(\n    name = \"snap_drawing\",\n    copts = COMMON_COMPILE_FLAGS,\n    visibility = [\"//visibility:public\"],\n    deps = selects.with_or({\n        (\"//bzl/conditions:ios\", \"//bzl/conditions:macos\"): [\":snap_drawing_apple\"],\n        \"//bzl/conditions:android_with_jni\": [\":snap_drawing_android\"],\n        \"//conditions:default\": [\":snap_drawing_cc\"],\n    }),\n)\n\ncc_library(\n    name = \"snap_drawing_cc\",\n    srcs = glob(\n        [\n            \"src/snap_drawing/cpp/**/*.cpp\",\n        ],\n        exclude = [\n            \"src/snap_drawing/android/**/*.cpp\",\n            \"src/snap_drawing/apple/**/*.cpp\",\n        ],\n    ),\n    hdrs = glob(\n        [\n            \"src/snap_drawing/cpp/**/*.hpp\",\n        ],\n        exclude = [\n            \"src/snap_drawing/android/**/*.hpp\",\n            \"src/snap_drawing/apple/**/*.hpp\",\n        ],\n    ),\n    copts = COMPILER_FLAGS + COMMON_COMPILE_FLAGS,\n    defines = select({\n        \":lottie_enabled\": [\"SNAP_DRAWING_LOTTIE_ENABLED\"],\n        \"//conditions:default\": [],\n    }),\n    linkstatic = False,\n    strip_include_prefix = \"src\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//third-party/yoga\",\n        \"//valdi_core:valdi_core_cc\",\n        \"@harfbuzz\",\n        \"@icu\",\n        \"@skia//:core\",\n        \"@skia//:jpeg_decode_codec\",\n        \"@skia//:jpeg_encode_codec\",\n        \"@skia//:png_decode_codec\",\n        \"@skia//:png_encode_codec\",\n        \"@skia//:skottie\",\n        \"@skia//:webp_decode_codec\",\n        \"@skia//:webp_encode_codec\",\n    ] + select({\n        \"//bzl/conditions:ios\": [\n            \"@skia//:fontmgr_coretext\",\n            \"@skia//:ganesh_metal\",\n        ],\n        \"//bzl/conditions:macos\": [\n            \"@skia//:fontmgr_coretext\",\n            \"@skia//:ganesh_metal\",\n        ],\n        \"//bzl/conditions:android_with_jni\": [\n            \"@skia//:fontmgr_android_freetype\",\n            \"@skia//:ganesh_egl_factory\",\n            \"@skia//:ganesh_gl\",\n        ],\n        \"@snap_platforms//conditions:android\": [\n            \"@skia//:fontmgr_android_freetype\",\n            \"@skia//:ganesh_egl_factory\",\n            \"@skia//:ganesh_gl\",\n        ],\n        \"//conditions:default\": [\n            \"@skia//:fontmgr_empty_freetype\",\n        ],\n    }),\n    alwayslink = False,\n)\n\ncc_library(\n    name = \"test_utils\",\n    testonly = 1,\n    srcs = glob([\"test/utils/**/*.cpp\"]),\n    hdrs = glob([\"test/utils/**/*.hpp\"]),\n    copts = COMMON_COMPILE_FLAGS,\n    strip_include_prefix = \"test/utils\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":snap_drawing\",\n        \"@gtest\",\n    ],\n)\n\nLINUX_TEST_EXCLUSIONS = [\"test/src/TextLayout_Tests.cpp\"]\n\nLOTTIE_TEST_EXCLUSIONS = [\"test/src/LottieLayer_tests.cpp\"]\n\ncc_test(\n    name = \"test\",\n    srcs = select({\n        \":lottie_enabled\": glob(\n            [\"test/src/**/*.cpp\"],\n        ),\n        \"//bzl/conditions:linux\": glob(\n            [\"test/src/**/*.cpp\"],\n            exclude = (LINUX_TEST_EXCLUSIONS + LOTTIE_TEST_EXCLUSIONS),\n        ),\n        \"//conditions:default\": glob(\n            [\"test/src/**/*.cpp\"],\n            exclude = LOTTIE_TEST_EXCLUSIONS,\n        ),\n    }),\n    copts = COMPILER_FLAGS,\n    data = glob([\"testdata/**\"]),\n    linkstatic = True,\n    deps = [\n        \":snap_drawing\",\n        \":test_utils\",\n        \"@gtest//:gtest_main\",\n    ],\n)\n\ncc_binary(\n    name = \"benchmark\",\n    srcs = glob([\"src/benchmark/**/*.cpp\"]),\n    linkstatic = True,\n    deps = [\n        \":snap_drawing\",\n        \"@com_github_google_benchmark//:benchmark\",\n    ],\n)\n\ncc_library(\n    name = \"snap_drawing_android\",\n    srcs = glob([\n        \"src/snap_drawing/android/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/snap_drawing/android/**/*.hpp\",\n    ]),\n    copts = COMPILER_FLAGS + COMMON_COMPILE_FLAGS,\n    defines = select({\n        \"//conditions:default\": [],\n    }),\n    linkopts = [\n        \"-landroid\",\n        \"-lEGL\",\n        \"-lGLESv3\",\n        \"-llog\",\n        \"-ljnigraphics\",\n    ],\n    strip_include_prefix = \"src\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":snap_drawing_cc\",\n        \"//valdi_core:valdi_core_android\",\n    ],\n    alwayslink = True,\n)\n\nkt_android_library(\n    name = \"snap_drawing_java\",\n    srcs = glob([\n        \"src/java/**/*.kt\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    exports = [\n    ],\n    deps = [\n        \"//valdi_core:valdi_core_java\",\n    ],\n)\n\nswift_interop_hint(\n    name = \"snap_drawing_apple_swift_interop\",\n    suppressed = True,\n    tags = [\"manual\"],\n)\n\nobjc_library(\n    name = \"snap_drawing_apple\",\n    srcs = glob([\n        \"src/snap_drawing/apple/**/*.m\",\n        \"src/snap_drawing/apple/**/*.mm\",\n        \"src/snap_drawing/apple/**/*.cpp\",\n    ]),\n    hdrs = glob([\n        \"src/snap_drawing/apple/**/*.h\",\n        \"src/snap_drawing/apple/**/*.hpp\",\n    ]),\n    aspect_hints = [\":snap_drawing_apple_swift_interop\"],\n    copts = OBJC_ONLY_FLAGS,\n    includes = [\n        \"src\",\n    ],\n    sdk_frameworks = [\n        \"Metal\",\n        \"CoreGraphics\",\n        \"CoreText\",\n        \"CoreVideo\",\n    ],\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \":snap_drawing_cc\",\n        \"//valdi_core:valdi_core_objc\",\n    ],\n)\n\nobjc_library(\n    name = \"snap_drawing_src-demo\",\n    srcs = glob([\n        \"src/demo/**/*.m\",\n        \"src/demo/**/*.mm\",\n    ]),\n    copts = COMPILER_FLAGS + [\n        \"-ObjC++\",\n        \"-std=c++20\",\n    ],\n    sdk_frameworks = [\n        \"AVFoundation\",\n        \"CoreMedia\",\n        \"CoreVideo\",\n    ],\n    deps = [\n        \":snap_drawing\",\n        \"@valdi//valdi:valdi_standalone_runtime\",\n    ],\n)\n\ncc_binary(\n    name = \"snap_drawing-demo\",\n    deps = [\n        \":snap_drawing_src-demo\",\n    ],\n)\n"
  },
  {
    "path": "snap_drawing/README.md",
    "content": "# SnapDrawing\n\nA fast, native and cross-platform drawing and UI system leveraging the Skia library.\n\n## When should you use SnapDrawing?\n\nIn most cases, you should use Valdi for building a cross-platform UI. Valdi is built on top of SnapDrawing for Android.\nThere are some cases however where using SnapDrawing directly might make sense:\n- You need to render some form of UI into a bitmap or a texture that you control\n- You want to control the draw loop yourself, or even draw a one-off UI without a loop\n\n## Demo app\n\nThe src/demo folder contains a demo CLI desktop app that leverages SnapDrawing to setup a scene using layers with a given image or video, and generates an output as a PNG or MP4 file. The image demo renders the scene once and exports the result. The video demo creates the scene and updates it on every decoded video buffer with its timestamp. It includes a fade-out animation which shows how a SnapDrawing layer scene can be updated through a video timeline.\n\nTo process an image:\n```sh\nbzl run //src/snap_drawing:snap_drawing-demo -- image -i <path_to_input_image> -o <path_to_output_image>\n```\nTo process a video:\n```sh\nbzl run //src/snap_drawing:snap_drawing-demo -- video -i <path_to_input_video> -o <path_to_output_video>\n```\n"
  },
  {
    "path": "snap_drawing/scripts/run_benchmark.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSCRIPT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" >/dev/null && pwd )\"\nCLIENT_ROOT=\"$SCRIPT_DIR/../../\"\npushd \"$CLIENT_ROOT\"\n\nbzl run snap_drawing:benchmark --snap_flavor=production -c opt\n"
  },
  {
    "path": "snap_drawing/src/benchmark/main.cpp",
    "content": "#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n#include \"snap_drawing/cpp/Text/TextLayoutBuilder.hpp\"\n\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n\n#include \"benchmark/benchmark.h\"\n\nusing namespace snap::drawing;\n\nstatic void doBenchmark(benchmark::State& state, Valdi::Function<void(const Ref<FontManager>&)>&& benchmarkFn) {\n    auto disableCache = state.range(0) == 0;\n    auto fontManager = Valdi::makeShared<FontManager>(Valdi::ConsoleLogger::getLogger(), !disableCache);\n    fontManager->load();\n\n    auto shouldClearCacheAfterEachIteration = state.range(0) == 1;\n    for (auto _ : state) {\n        benchmarkFn(fontManager);\n\n        if (shouldClearCacheAfterEachIteration) {\n            fontManager->getTextShaper()->clearCache();\n        }\n    }\n}\n\nstatic void TextLayoutSimpleTextSingleLine(benchmark::State& state) {\n    doBenchmark(state, [&](const auto& fontManager) {\n        auto font = fontManager->getDefaultFont().moveValue();\n\n        TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, Size::make(5000, 5000), 1, fontManager, false);\n\n        builder.append(\"Hello World!\", font, 1.0f, 0.0f, TextDecorationNone);\n\n        benchmark::DoNotOptimize(builder.build());\n    });\n}\n\nstatic void TextLayoutLongTextSingleLine(benchmark::State& state) {\n    doBenchmark(state, [&](const auto& fontManager) {\n        auto font = fontManager->getDefaultFont().moveValue();\n\n        TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, Size::make(50000, 5000), 0, fontManager, false);\n\n        builder.append(\"Hello World! This string might be pretty long, and because of that we will have to lay it out \"\n                       \"on multiple lines\",\n                       font,\n                       1.0f,\n                       0.0f,\n                       TextDecorationNone);\n\n        benchmark::DoNotOptimize(builder.build());\n    });\n}\n\nstatic void TextLayoutLongTextMultiLine(benchmark::State& state) {\n    doBenchmark(state, [&](const auto& fontManager) {\n        auto font = fontManager->getDefaultFont().moveValue();\n\n        TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, Size::make(100, 5000), 0, fontManager, false);\n\n        builder.append(\"Hello World! This string might be pretty long, and because of that we will have to lay it out \"\n                       \"on multiple lines\",\n                       font,\n                       1.0f,\n                       0.0f,\n                       TextDecorationNone);\n\n        benchmark::DoNotOptimize(builder.build());\n    });\n}\n\nstatic void TextLayoutEmojiText(benchmark::State& state) {\n    doBenchmark(state, [&](const auto& fontManager) {\n        auto font = fontManager->getDefaultFont().moveValue();\n\n        TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, Size::make(5000, 5000), 1, fontManager, false);\n\n        builder.append(\"Hello World 😀😃😄! We like emojis here 😍😍😍.\", font, 1.0f, 0.0f, TextDecorationNone);\n\n        benchmark::DoNotOptimize(builder.build());\n    });\n}\n\nstatic void TextLayoutArabicText(benchmark::State& state) {\n    doBenchmark(state, [&](const auto& fontManager) {\n        auto font = fontManager->getDefaultFont().moveValue();\n\n        TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, Size::make(5000, 5000), 1, fontManager, false);\n\n        builder.append(\"قرأ Wikipedia™ طوال اليوم.\", font, 1.0, 0.0, TextDecorationNone);\n\n        benchmark::DoNotOptimize(builder.build());\n    });\n}\n\nBENCHMARK(TextLayoutSimpleTextSingleLine)->Arg(0)->Arg(1)->Arg(2);\nBENCHMARK(TextLayoutLongTextSingleLine)->Arg(0)->Arg(1)->Arg(2);\nBENCHMARK(TextLayoutLongTextMultiLine)->Arg(0)->Arg(1)->Arg(2);\nBENCHMARK(TextLayoutEmojiText)->Arg(0)->Arg(1)->Arg(2);\nBENCHMARK(TextLayoutArabicText)->Arg(0)->Arg(1)->Arg(2);\nBENCHMARK_MAIN();\n"
  },
  {
    "path": "snap_drawing/src/demo/SnapDrawingDemo.mm",
    "content": "#include <unistd.h>\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include \"valdi_core/cpp/Utils/DiskUtils.hpp\"\n\n#include \"valdi/standalone_runtime/Arguments.hpp\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Layers/ImageLayer.hpp\"\n#include \"snap_drawing/cpp/Layers/TextLayer.hpp\"\n#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/BitmapGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n\n#import \"SnapDrawingVideoEncoder.h\"\n\nusing namespace Valdi;\n\nint exitWithError(const Error &error) {\n    VALDI_ERROR(ConsoleLogger::getLogger(), \"{}\", error.getMessage());\n    return EXIT_FAILURE;\n}\n\nint printUsage(const char **argv) {\n    VALDI_ERROR(ConsoleLogger::getLogger(), \"Usage: {} image|video -i input -o output\", argv[0]);\n    return EXIT_FAILURE;\n}\n\nnamespace snap::drawing {\n\nstatic Valdi::Ref<Resources> initializeSnapDrawingResources() {\n    auto &logger = ConsoleLogger::getLogger();\n    auto fontManager = makeShared<FontManager>(logger);\n\n    fontManager->load();\n\n    return makeShared<Resources>(fontManager, 1.0f, logger);\n}\n\nstruct Scene: public snap::drawing::LayerRoot {\n    static constexpr Scalar VIGNETTE_OFFSET = 40;\n//    static constexpr ColorType COLOR_TYPE =  ColorTypeRGBA8888;\n    static constexpr ColorType COLOR_TYPE =  ColorTypeBGRA8888;\n\n    Size vignetteSize;\n\n    Ref<Layer> contentLayer;\n    Ref<Layer> vignetteLayer;\n    Ref<Layer> overlayLayer;\n    Ref<ImageLayer> imageLayer;\n    Ref<TextLayer> textLayer;\n\n    Scene(const Valdi::Ref<Resources> &resources, Size vignetteSize): LayerRoot(resources), vignetteSize(vignetteSize) {}\n\n    void onInitialize() override {\n        // Create the layers from our scene\n        contentLayer = makeLayer<Layer>(getResources());\n        vignetteLayer = makeLayer<Layer>(getResources());\n        overlayLayer = makeLayer<Layer>(getResources());\n        imageLayer = makeLayer<ImageLayer>(getResources());\n        textLayer = makeLayer<TextLayer>(getResources());\n\n        contentLayer->addChild(vignetteLayer);\n        vignetteLayer->addChild(imageLayer);\n        vignetteLayer->addChild(overlayLayer);\n        overlayLayer->addChild(textLayer);\n\n        // Setup main content\n        contentLayer->setBackgroundColor(Color::white());\n\n        // Setup inside vignette\n        vignetteLayer->setBorderColor(Color::black());\n        vignetteLayer->setBorderWidth(4.0);\n        vignetteLayer->setBorderRadius(BorderRadius::makeOval(VIGNETTE_OFFSET / 2, false));\n        vignetteLayer->setClipsToBounds(true);\n        vignetteLayer->setBoxShadow(2.0, 2.0, 5.0, Color::black().withAlphaRatio(0.5f));\n\n        // Setup the text layer\n        textLayer->setTextAlign(TextAlignCenter);\n        textLayer->setText(STRING_LITERAL(\"SnapDrawing is pretty cool\"));\n        textLayer->setTextColor(Color::white());\n\n        auto font = getResources()->getFontManager()->getFontForName(STRING_LITERAL(\"system-bold 24\"), 1.0);\n        if (font) {\n            textLayer->setTextFont(font.value());\n        } else {\n            VALDI_ERROR(getResources()->getLogger(), \"Failed to load Font: {}\", font.error().getMessage());\n        }\n\n        // Setup the image layer\n        imageLayer->setFittingSizeMode(FittingSizeModeFill);\n\n        // Setup the overlay\n        overlayLayer->setBackgroundLinearGradient({0.0, 1.0}, {Color::black().withAlphaRatio(0.0f), Color::black()}, LinearGradientOrientationTopBottom);\n\n        // Layout the scene\n        auto sceneSize = Size::make(vignetteSize.width + VIGNETTE_OFFSET * 2, vignetteSize.height + VIGNETTE_OFFSET * 2);\n\n        contentLayer->setFrame(Rect::makeXYWH(0, 0, sceneSize.width, sceneSize.height));\n        vignetteLayer->setFrame(contentLayer->getFrame().withInsets(VIGNETTE_OFFSET, VIGNETTE_OFFSET));\n        imageLayer->setFrame(Rect::makeXYWH(0, 0, vignetteLayer->getFrame().width(), vignetteLayer->getFrame().height()));\n        overlayLayer->setFrame(Rect::makeLTRB(0, vignetteLayer->getFrame().height() / 2.0, vignetteLayer->getFrame().width(), vignetteLayer->getFrame().height()));\n        textLayer->setFrame(Rect::makeXYWH(0, 0, overlayLayer->getFrame().width(), overlayLayer->getFrame().height()));\n\n        // Create the root, which host the whole scene\n        setContentLayer(contentLayer, ContentLayerSizingModeMatchSize);\n        setSize(sceneSize, 1.0);\n    }\n\n};\n\nstatic Valdi::BitmapInfo bitmapInfoFromBufferData(BufferData &bufferData) {\n    return  Valdi::BitmapInfo((int)bufferData.width, (int)bufferData.height, Scene::COLOR_TYPE, AlphaTypeOpaque, bufferData.bytesPerRow);\n}\n\nValdi::Ref<DisplayList> updateSceneWithBufferData(const Ref<Scene> &scene, BufferData *bufferData, double timestamp) {\n    VALDI_INFO(scene->getResources()->getLogger(), \"Processing scene at {}s\", timestamp);\n    Valdi::Result<Ref<Image>> image;\n\n    if (bufferData != nullptr) {\n        auto bitmapInfo = bitmapInfoFromBufferData(*bufferData);\n        Valdi::BytesView bytesView(nullptr, reinterpret_cast<const Valdi::Byte *>(bufferData->bytes), bufferData->bytesPerRow * bufferData->height);\n\n        image = Image::makeFromPixelsData(bitmapInfo, bytesView, false);\n    } else {\n        image = Error(\"Failed to read input buffer data\");\n    }\n\n    if (image) {\n        scene->imageLayer->setImage(image.value());\n    } else {\n        scene->imageLayer->setImage(nullptr);\n        VALDI_ERROR(scene->getResources()->getLogger(), \"Failed to read image: {}\", image.error().getMessage());\n    }\n\n    scene->processFrame(TimePoint(timestamp));\n    return scene->getLastDrawnFrame();\n}\n\nValdi::Result<Valdi::Void> rasterFrameIntoBuffer(const Valdi::Ref<DisplayList> &frame, BufferData &bufferData) {\n    auto bitmapInfo = bitmapInfoFromBufferData(bufferData);\n    BitmapGraphicsContext bitmapContext;\n    auto drawableSurface = bitmapContext.createBitmapSurface(bitmapInfo, bufferData.bytes);\n\n    auto canvas = drawableSurface->prepareCanvas();\n    if (!canvas) {\n        return canvas.moveError();\n    }\n\n    frame->draw(canvas.value(), 0, /* shouldClearCanvas */ true);\n\n    drawableSurface->flush();\n\n    return Valdi::Void();\n}\n\nSnapDrawingSampleBuffer *processVideoFrame(const Ref<Scene> &scene, SnapDrawingSampleBuffer *inputVideoBuffer, SnapDrawingSampleBuffer *outputVideoBuffer) {\n    BufferData inputBufferData;\n    BOOL inputLocked = [inputVideoBuffer lockBytes:&inputBufferData];\n\n    auto frame = updateSceneWithBufferData(scene, inputLocked ? &inputBufferData : nullptr, [inputVideoBuffer timestamp]);\n\n    BufferData outputBufferData;\n    BOOL outputLocked = [outputVideoBuffer lockBytes:&outputBufferData];\n\n    if (outputLocked) {\n        auto rasterResult = rasterFrameIntoBuffer(frame, outputBufferData);\n        if (!rasterResult) {\n            VALDI_ERROR(scene->getResources()->getLogger(), \"Failed to raster scene: {}\", rasterResult.error().getMessage());\n        }\n    } else {\n        VALDI_ERROR(scene->getResources()->getLogger(), \"Failed to lock bytes on output buffer\");\n    }\n\n    if (inputLocked) {\n        [inputVideoBuffer unlockBytes:&inputBufferData];\n    }\n\n    if (outputLocked) {\n        [outputVideoBuffer unlockBytes:&outputBufferData];\n    }\n\n    return inputVideoBuffer;\n}\n\nstatic void openOutput(const StringBox &output) {\n    NSString *objcOutput = [NSString stringWithUTF8String:output.getCStr()];\n    @try {\n        [NSTask launchedTaskWithLaunchPath:@\"/usr/bin/open\" arguments:@[objcOutput]];\n    } @catch (NSException *exception) {\n        NSLog(@\"Failed to open output file '%@': %@\", objcOutput, exception.reason);\n    }\n}\n\nint processVideo(StringBox input, StringBox output) {\n    SnapDrawingVideoDecoder *decoder = [[SnapDrawingVideoDecoder alloc] initWithPath:[NSString stringWithUTF8String:input.getCStr()]];\n\n    NSError *error = nil;\n\n    if (![decoder prepareWithError:&error]) {\n        return exitWithError(Valdi::Error(error.localizedDescription.UTF8String));\n    }\n\n    auto resources = initializeSnapDrawingResources();\n\n    auto scene = makeLayer<Scene>(resources, Size::make(decoder.videoWidth, decoder.videoHeight));\n\n    double fadeOutDuration = std::min(decoder.durationSeconds / 2.0, 5.0);\n\n    scene->overlayLayer->addAnimation(STRING_LITERAL(\"opacity\"), makeShared<Animation>(Duration(fadeOutDuration),\n                                                                                        InterpolationFunctions::easeOut(),\n                                                                                        [](Layer &layer, double ratio) {\n        layer.setOpacity(1.0 - static_cast<Scalar>(ratio));\n    }));\n\n    SnapDrawingVideoEncoder *encoder = [[SnapDrawingVideoEncoder alloc] initWithPath:[NSString stringWithUTF8String:output.getCStr()]\n                                                        videoWidth:scene->getContentLayer()->getFrame().width()\n                                                       videoHeight:scene->getContentLayer()->getFrame().height()];\n\n    if (![encoder prepareWithError:&error]) {\n        return exitWithError(Valdi::Error(error.localizedDescription.UTF8String));\n    }\n\n    error = SnapDrawingTranscodeVideo(encoder, decoder, ^void (SnapDrawingSampleBuffer * _Nonnull inputBuffer, SnapDrawingSampleBuffer * _Nonnull outputBuffer) {\n        processVideoFrame(scene, inputBuffer, outputBuffer);\n    });\n\n    if (error) {\n        return exitWithError(Valdi::Error(error.localizedDescription.UTF8String));\n    }\n    openOutput(output);\n\n    return EXIT_SUCCESS;\n}\n\nint processImage(StringBox input, StringBox output) {\n    auto imageBytes = DiskUtils::load(Valdi::Path(input.toStringView()));\n    if (!imageBytes) {\n        return exitWithError(imageBytes.error().prepending(\"Failed to open image input: \"));\n    }\n\n    auto imageResult = Image::make(imageBytes.value());\n    if (!imageResult) {\n        return exitWithError(imageResult.error().prepending(\"Failed to load image: \"));\n    }\n\n    auto image = imageResult.moveValue();\n\n    auto resources = initializeSnapDrawingResources();\n\n    auto scene = makeLayer<Scene>(resources, Size::make(image->width(), image->height()));\n    // Set the image to display on the scene\n    scene->imageLayer->setImage(image);\n\n    scene->processFrame(TimePoint(0.0));\n\n    auto frame = scene->getLastDrawnFrame();\n\n    BitmapGraphicsContext bitmapContext;\n    auto drawableSurface = bitmapContext.createBitmapSurface(Valdi::BitmapInfo(static_cast<int>(frame->getSize().width), static_cast<int>(frame->getSize().height), Scene::COLOR_TYPE, AlphaTypePremul, 0));\n\n    auto canvas = drawableSurface->prepareCanvas();\n    if (!canvas) {\n        return exitWithError(canvas.error());\n    }\n\n    frame->draw(canvas.value(), 0, /* shouldClearCanvas */ true);\n\n    auto canvasSnapshot = canvas.value().snapshot();\n    if (!canvasSnapshot) {\n        return exitWithError(canvasSnapshot.error());\n    }\n\n    auto pngBytes = canvasSnapshot.value()->toPNG();\n    if (!pngBytes) {\n        return exitWithError(pngBytes.error());\n    }\n\n    auto writeResult = DiskUtils::store(Valdi::Path(output.toStringView()), pngBytes.value());\n    if (!writeResult) {\n        return exitWithError(writeResult.error().prepending(\"Failed to write PNG output: \"));\n    }\n\n    openOutput(output);\n\n    return EXIT_SUCCESS;\n}\n\n}\n\nint main(int argc, const char **argv) {\n    @autoreleasepool {\n        Arguments arguments(argc, argv);\n\n        arguments.next();\n\n        if (!arguments.hasNext()) {\n            return printUsage(argv);\n        }\n\n        auto command = arguments.next();\n        StringBox input;\n        StringBox output;\n\n        while (arguments.hasNext()) {\n            auto arg = arguments.next();\n\n            if (arg == \"-i\") {\n                if (!arguments.hasNext()) {\n                    return printUsage(argv);\n                }\n                input = arguments.next();\n            } else if (arg == \"-o\") {\n                if (!arguments.hasNext()) {\n                    return printUsage(argv);\n                }\n                output = arguments.next();\n            } else {\n                return printUsage(argv);\n            }\n        }\n\n        if (command == \"video\") {\n            return snap::drawing::processVideo(input, output);\n        } else if (command == \"image\") {\n            return snap::drawing::processImage(input, output);\n        } else {\n            return printUsage(argv);\n        }\n    }\n}\n"
  },
  {
    "path": "snap_drawing/src/demo/SnapDrawingVideoEncoder.h",
    "content": "//\n//  SnapDrawingVideoEncoder.h\n//  snap_drawing-demo\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class SnapDrawingSampleBuffer;\n\nstruct BufferData {\n    void* bytes;\n    size_t bytesPerRow;\n    size_t width;\n    size_t height;\n};\n\n@interface SnapDrawingSampleBuffer : NSObject\n\n@property (readonly, nonatomic) double timestamp;\n\n- (BOOL)lockBytes:(BufferData*)bufferData;\n- (void)unlockBytes:(BufferData*)bufferData;\n\n@end\n\n@interface SnapDrawingVideoDecoder : NSObject\n\n@property (readonly, nonatomic) double durationSeconds;\n@property (readonly, nonatomic) NSInteger videoWidth;\n@property (readonly, nonatomic) NSInteger videoHeight;\n\n- (instancetype)initWithPath:(NSString*)path;\n\n- (BOOL)prepareWithError:(NSError**)error;\n\n- (SnapDrawingSampleBuffer*)copyNextSampleBufferWithError:(NSError**)error;\n\n@end\n\n@interface SnapDrawingVideoEncoder : NSObject\n\n- (instancetype)initWithPath:(NSString*)path videoWidth:(NSInteger)videoWidth videoHeight:(NSInteger)videoHeight;\n\n- (BOOL)prepareWithError:(NSError**)error;\n\n- (BOOL)writeSampleBuffer:(SnapDrawingSampleBuffer*)sampleBuffer error:(NSError**)error;\n\n- (void)finishWriting;\n\n@end\n\ntypedef void (^SnapDrawingVideoTranscodeBlock)(SnapDrawingSampleBuffer* inputBuffer,\n                                               SnapDrawingSampleBuffer* outputBuffer);\n\nNSError* SnapDrawingTranscodeVideo(SnapDrawingVideoEncoder* encoder,\n                                   SnapDrawingVideoDecoder* decoder,\n                                   SnapDrawingVideoTranscodeBlock transcodeBlock);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "snap_drawing/src/demo/SnapDrawingVideoEncoder.mm",
    "content": "//\n//  SnapDrawingVideoEncoder.m\n//  snap_drawing-demo\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#import \"SnapDrawingVideoEncoder.h\"\n#import <AVFoundation/AVFoundation.h>\n\n#define PIXEL_FORMAT kCVPixelFormatType_32BGRA\n\n@implementation SnapDrawingSampleBuffer {\n    CMTime _presentationTimestamp;\n    CMSampleBufferRef _sampleBufferRef;\n    CVPixelBufferRef _pixelBufferRef;\n}\n\n- (instancetype)initWithSampleBufferRef:(CMSampleBufferRef)sampleBufferRef\n{\n    self = [super init];\n\n    if (self) {\n        _sampleBufferRef = sampleBufferRef;\n        CFRetain(_sampleBufferRef);\n        _pixelBufferRef = CMSampleBufferGetImageBuffer(_sampleBufferRef);\n        if (_pixelBufferRef) {\n            CVPixelBufferRetain(_pixelBufferRef);\n        }\n\n        _presentationTimestamp = CMSampleBufferGetPresentationTimeStamp(_sampleBufferRef);\n    }\n\n    return self;\n}\n\n- (instancetype)initWithPixelBufferRef:(CVPixelBufferRef)pixelBufferRef\n                 presentationTimestamp:(CMTime)presentationTimestamp\n{\n    self = [super init];\n\n    if (self) {\n        _pixelBufferRef = pixelBufferRef;\n        CVPixelBufferRetain(_pixelBufferRef);\n        _presentationTimestamp = presentationTimestamp;\n    }\n\n    return self;\n}\n\n- (void)dealloc\n{\n    if (_pixelBufferRef) {\n        CVPixelBufferRelease(_pixelBufferRef);\n    }\n\n    if (_sampleBufferRef) {\n        CFRelease(_sampleBufferRef);\n    }\n}\n\n- (BOOL)lockBytes:(BufferData *)bufferData\n{\n    if (!_pixelBufferRef) {\n        return NO;\n    }\n\n    CVPixelBufferLockBaseAddress(_pixelBufferRef, 0);\n\n    bufferData->bytes = CVPixelBufferGetBaseAddress(_pixelBufferRef);\n    bufferData->bytesPerRow = CVPixelBufferGetBytesPerRow(_pixelBufferRef);\n    bufferData->width = CVPixelBufferGetWidth(_pixelBufferRef);\n    bufferData->height = CVPixelBufferGetHeight(_pixelBufferRef);\n\n    return YES;\n}\n\n- (void)unlockBytes:(BufferData *)bufferData\n{\n    bufferData->bytes = nil;\n    bufferData->bytesPerRow = 0;\n    bufferData->width = 0;\n    bufferData->height = 0;\n\n    CVPixelBufferUnlockBaseAddress(_pixelBufferRef, 0);\n}\n\n- (CMSampleBufferRef)sampleBufferRef\n{\n    return _sampleBufferRef;\n}\n\n- (CVPixelBufferRef)pixelBufferREf\n{\n    return _pixelBufferRef;\n}\n\n- (double)timestamp\n{\n    return CMTimeGetSeconds(_presentationTimestamp);\n}\n\n- (CMTime)presentationTimestamp\n{\n    return _presentationTimestamp;\n}\n\n@end\n\n@implementation SnapDrawingVideoDecoder {\n    AVAsset *_asset;\n    AVAssetReader *_assetReader;\n    AVAssetReaderTrackOutput *_videoOutput;\n    AVAssetTrack *_videoTrack;\n}\n\n- (instancetype)initWithPath:(NSString *)path\n{\n    self = [super init];\n\n    if (self) {\n        NSURL *url = [NSURL fileURLWithPath:path];\n        _asset = [AVAsset assetWithURL:url];\n    }\n\n    return self;\n}\n\n- (void)dealloc\n{\n    [_assetReader cancelReading];\n}\n\n- (double)durationSeconds\n{\n    return CMTimeGetSeconds(_asset.duration);\n}\n\n- (NSInteger)videoWidth\n{\n    CGSize size = [_videoTrack naturalSize];\n    return (NSInteger)size.width;\n}\n\n- (NSInteger)videoHeight\n{\n    CGSize size = [_videoTrack naturalSize];\n    return (NSInteger)size.height;\n}\n\n- (BOOL)prepareWithError:(NSError * _Nullable *)error\n{\n    NSArray<AVAssetTrack *> *videoTracks = [_asset tracksWithMediaType:AVMediaTypeVideo];\n    if (!videoTracks.count) {\n        *error = [NSError errorWithDomain:@\"\" code:0 userInfo:@{NSLocalizedDescriptionKey: @\"No Video track in media\"}];\n        return NO;\n    }\n\n    _videoTrack = videoTracks.firstObject;\n\n    AVAssetReader *reader = [AVAssetReader assetReaderWithAsset:_asset error:error];\n    if (!reader) {\n        return NO;\n    }\n\n    AVAssetReaderTrackOutput *output = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:_videoTrack outputSettings:@{\n        (id)kCVPixelBufferPixelFormatTypeKey     : @(PIXEL_FORMAT),\n        (id)kCVPixelBufferIOSurfacePropertiesKey : @{}\n    }];\n\n    if (![reader canAddOutput:output]) {\n        *error = [NSError errorWithDomain:@\"\" code:0 userInfo:@{NSLocalizedDescriptionKey: @\"Cannot add output\"}];\n        return NO;\n    }\n    [reader addOutput:output];\n\n    if (![reader startReading]) {\n        *error = reader.error;\n        return NO;\n    }\n\n    _assetReader = reader;\n    _videoOutput = output;\n\n    return YES;\n}\n\n- (SnapDrawingSampleBuffer *)copyNextSampleBufferWithError:(NSError * _Nullable *)error\n{\n    CMSampleBufferRef sampleBufferRef = nil;\n\n    while (!sampleBufferRef) {\n        switch (_assetReader.status) {\n            case AVAssetReaderStatusUnknown:\n            case AVAssetReaderStatusReading: {\n                sampleBufferRef = [_videoOutput copyNextSampleBuffer];\n                break;\n            case AVAssetReaderStatusCompleted:\n                return nil;\n            case AVAssetReaderStatusFailed:\n            case AVAssetReaderStatusCancelled:\n                *error = _assetReader.error;\n                return nil;\n            }\n        }\n    }\n\n    SnapDrawingSampleBuffer *buffer = [[SnapDrawingSampleBuffer alloc] initWithSampleBufferRef:sampleBufferRef];\n    CFRelease(sampleBufferRef);\n\n    return buffer;\n}\n\n@end\n\n@implementation SnapDrawingVideoEncoder {\n    NSURL *_url;\n    AVAssetWriter *_assetWriter;\n    AVAssetWriterInput *_videoInput;\n    NSInteger _videoWidth;\n    NSInteger _videoHeight;\n    AVAssetWriterInputPixelBufferAdaptor *_pixelBufferAdaptor;\n}\n\n- (instancetype)initWithPath:(NSString *)path\n                  videoWidth:(NSInteger)videoWidth\n                 videoHeight:(NSInteger)videoHeight\n{\n    self = [super init];\n\n    if (self) {\n        _url = [NSURL fileURLWithPath:path];\n        _videoWidth = videoWidth;\n        _videoHeight = videoHeight;\n\n        if ([[NSFileManager defaultManager] fileExistsAtPath:_url.path]) {\n            [[NSFileManager defaultManager] removeItemAtPath:_url.path error:nil];\n        }\n    }\n\n    return self;\n}\n\n- (void)dealloc\n{\n}\n\n- (BOOL)prepareWithError:(NSError *__autoreleasing  _Nullable *)error\n{\n    AVAssetWriter *writer = [AVAssetWriter assetWriterWithURL:_url fileType:AVFileTypeMPEG4 error:error];\n    if (!writer) {\n        return NO;\n    }\n\n    AVAssetWriterInput *videoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:@{\n        AVVideoCodecKey : AVVideoCodecTypeH264,\n        AVVideoScalingModeKey : AVVideoScalingModeResizeAspectFill,\n        AVVideoWidthKey : @(_videoWidth),\n        AVVideoHeightKey : @(_videoHeight),\n        AVVideoCompressionPropertiesKey : @{\n            AVVideoAverageBitRateKey: @(6000000),\n        }\n    }];\n\n    if (![writer canAddInput:videoInput]) {\n        *error = [NSError errorWithDomain:@\"\" code:0 userInfo:@{NSLocalizedDescriptionKey: @\"Cannot add video output\"}];\n        return NO;\n    }\n    [writer addInput:videoInput];\n\n    _pixelBufferAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoInput sourcePixelBufferAttributes:@{\n        (id)kCVPixelBufferPixelFormatTypeKey : @(PIXEL_FORMAT),\n        (id)kCVPixelBufferWidthKey : @(_videoWidth),\n        (id)kCVPixelBufferHeightKey : @(_videoHeight),\n    }];\n\n    if (![writer startWriting]) {\n        *error = writer.error;\n        return NO;\n    }\n\n    [writer startSessionAtSourceTime:kCMTimeZero];\n\n    _assetWriter = writer;\n    _videoInput = videoInput;\n\n    return YES;\n}\n\n- (BOOL)writeSampleBuffer:(SnapDrawingSampleBuffer *)sampleBuffer error:(NSError *__autoreleasing  _Nullable *)error\n{\n    while (!_videoInput.isReadyForMoreMediaData && _assetWriter.status == AVAssetWriterStatusWriting) {\n        // Dirty hack to simplify implementation\n        [NSThread sleepForTimeInterval:0.01];\n    }\n\n    if ([sampleBuffer sampleBufferRef]) {\n        if (![_videoInput appendSampleBuffer:[sampleBuffer sampleBufferRef]]) {\n            *error = _assetWriter.error;\n            return NO;\n        }\n    } else {\n        if (![_pixelBufferAdaptor appendPixelBuffer:[sampleBuffer pixelBufferREf] withPresentationTime:[sampleBuffer presentationTimestamp]]) {\n            *error = _assetWriter.error;\n            return NO;\n        }\n    }\n\n    return YES;\n}\n\n- (void)finishWriting\n{\n    __block BOOL done = NO;\n    [_assetWriter finishWritingWithCompletionHandler:^{\n        done = YES;\n    }];\n\n    while (!done) {\n        [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];\n    }\n}\n\n- (SnapDrawingSampleBuffer *)dequeueOutputSampleBufferForTimestamp:(CMTime)timestamp error:(NSError **)error\n{\n    CVPixelBufferRef outputPixelBuffer = nil;\n    CVReturn ret = CVPixelBufferPoolCreatePixelBuffer(NULL, [_pixelBufferAdaptor pixelBufferPool], &outputPixelBuffer);\n\n    if (ret != kCVReturnSuccess) {\n        *error = [NSError errorWithDomain:@\"\" code:0 userInfo:@{NSLocalizedDescriptionKey: @\"Cannot dequeue output sample buffer\"}];\n        return nil;\n    }\n\n    SnapDrawingSampleBuffer *sampleBuffer = [[SnapDrawingSampleBuffer alloc] initWithPixelBufferRef:outputPixelBuffer presentationTimestamp:timestamp];\n    CVPixelBufferRelease(outputPixelBuffer);\n\n    return sampleBuffer;\n}\n\n@end\n\nNSError *SnapDrawingTranscodeVideo(SnapDrawingVideoEncoder *encoder,\n                          SnapDrawingVideoDecoder *decoder,\n                          SnapDrawingVideoTranscodeBlock transcodeBlock) {\n    NSError *error = nil;\n    BOOL reachedEnd = NO;\n    double lastTimestamp = NAN;\n\n    while (!error && !reachedEnd) {\n        @autoreleasepool {\n            SnapDrawingSampleBuffer *inputBuffer = [decoder copyNextSampleBufferWithError:&error];\n\n            if (!inputBuffer) {\n                reachedEnd = YES;\n            }\n\n            double timestamp = inputBuffer.timestamp;\n\n            if (isnan(lastTimestamp) || timestamp > lastTimestamp) {\n                lastTimestamp = timestamp;\n\n                SnapDrawingSampleBuffer *outputBuffer = [encoder dequeueOutputSampleBufferForTimestamp:[inputBuffer presentationTimestamp] error:&error];\n                if (!outputBuffer) {\n                    break;\n                }\n\n                transcodeBlock(inputBuffer, outputBuffer);\n\n                if (![encoder writeSampleBuffer:outputBuffer error:&error]) {\n                    break;\n                }\n            }\n        }\n    }\n\n    if (!error) {\n        [encoder finishWriting];\n    }\n\n    return error;\n\n}\n\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/android/AndroidFrameScheduler.cpp",
    "content": "//\n//  AndroidFrameScheduler.cpp\n//  snap_drawing-android\n//\n//  Created by Simon Corsin on 1/25/22.\n//\n\n#if __ANDROID__\n\n#include \"snap_drawing/android/AndroidFrameScheduler.hpp\"\n\nnamespace snap::drawing {\n\nAndroidFrameScheduler::AndroidFrameScheduler(const ValdiAndroid::GlobalRefJavaObjectBase& frameSchedulerJava)\n    : _frameSchedulerJava(frameSchedulerJava) {\n    auto frameSchedulerJavaObject = _frameSchedulerJava.toObject();\n    auto cls = frameSchedulerJavaObject.getClass();\n    cls.getMethod(\"onNextVSync\", _onNextVSyncMethod);\n    cls.getMethod(\"onMainThread\", _onMainThreadMethod);\n    cls.getMethod(\"stop\", _stopMethod);\n}\n\nAndroidFrameScheduler::~AndroidFrameScheduler() {\n    _stopMethod.call(_frameSchedulerJava.toObject());\n}\n\nvoid AndroidFrameScheduler::onNextVSync(const Ref<IFrameCallback>& callback) {\n    auto ptr = reinterpret_cast<int64_t>(Valdi::unsafeBridgeRetain(callback.get()));\n    _onNextVSyncMethod.call(_frameSchedulerJava.toObject(), ptr);\n}\n\nvoid AndroidFrameScheduler::onMainThread(const Ref<IFrameCallback>& callback) {\n    auto ptr = reinterpret_cast<int64_t>(Valdi::unsafeBridgeRetain(callback.get()));\n    _onMainThreadMethod.call(_frameSchedulerJava.toObject(), ptr);\n}\n\nvoid AndroidFrameScheduler::performCallback(int64_t callbackHandle, int64_t frameTimeNanos) {\n    auto ref = Valdi::unsafeBridge<IFrameCallback>(reinterpret_cast<void*>(callbackHandle));\n\n    if (ref == nullptr) {\n        return;\n    }\n\n    ref->onFrame(TimePoint::fromNanoSeconds(frameTimeNanos));\n}\n\n} // namespace snap::drawing\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/android/AndroidFrameScheduler.hpp",
    "content": "//\n//  AndroidFrameScheduler.hpp\n//  snap_drawing-android\n//\n//  Created by Simon Corsin on 1/25/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/IFrameScheduler.hpp\"\n#include \"valdi_core/jni/GlobalRefJavaObject.hpp\"\n#include \"valdi_core/jni/JavaMethod.hpp\"\n\nnamespace snap::drawing {\n\nclass AndroidFrameScheduler : public IFrameScheduler {\npublic:\n    explicit AndroidFrameScheduler(const ValdiAndroid::GlobalRefJavaObjectBase& frameSchedulerJava);\n    ~AndroidFrameScheduler() override;\n\n    void onNextVSync(const Ref<IFrameCallback>& callback) override;\n\n    void onMainThread(const Ref<IFrameCallback>& callback) override;\n\n    static void performCallback(int64_t callbackHandle, int64_t frameTimeNanos);\n\nprivate:\n    ValdiAndroid::GlobalRefJavaObjectBase _frameSchedulerJava;\n    ValdiAndroid::JavaMethod<ValdiAndroid::VoidType, int64_t> _onNextVSyncMethod;\n    ValdiAndroid::JavaMethod<ValdiAndroid::VoidType, int64_t> _onMainThreadMethod;\n    ValdiAndroid::JavaMethod<ValdiAndroid::VoidType> _stopMethod;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/CoreGraphicsUtils.cpp",
    "content": "//\n//  CoreGraphicsUtils.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/14/22.\n//\n\n#include \"snap_drawing/apple/CoreGraphicsUtils.hpp\"\n#include <optional>\n\nnamespace snap::drawing {\n\nstruct PathToCGPathVisitor : public PathVisitor {\n    CGMutablePathRef pathRef;\n\n    PathToCGPathVisitor(CGMutablePathRef pathRef) : pathRef(pathRef) {}\n\n    bool shouldConvertConicToQuad() const override {\n        return true;\n    }\n\n    void move(const Point& point) override {\n        CGPathMoveToPoint(pathRef, nil, point.x, point.y);\n    }\n\n    void line(const Point& from, const Point& to) override {\n        CGPathAddLineToPoint(pathRef, nil, to.x, to.y);\n    }\n\n    void quad(const Point& p1, const Point& p2, const Point& p3) override {\n        CGPathAddQuadCurveToPoint(pathRef, nil, p2.x, p2.y, p3.x, p3.y);\n    }\n\n    void conic(const Point& p1, const Point& p2, const Point& p3, Scalar weight) override {}\n\n    void cubic(const Point& p1, const Point& p2, const Point& p3, const Point& p4) override {\n        // TODO(simon): This is untested\n        CGPathAddCurveToPoint(pathRef, nil, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y);\n    }\n\n    void close() override {}\n};\n\nCGPathRef cgPathFromPath(const Path& path) {\n    CGMutablePathRef clipPathRef = CGPathCreateMutable();\n\n    PathToCGPathVisitor visitor(clipPathRef);\n    path.visit(visitor);\n\n    return static_cast<CGPathRef>(clipPathRef);\n}\n\nCGAffineTransform cgAffineTransformFromMatrix(const Matrix& matrix) {\n    Scalar affines[6];\n    if (!matrix.toAffine(affines)) {\n        return CGAffineTransformIdentity;\n    }\n\n    return CGAffineTransformMake(affines[0], affines[1], affines[2], affines[3], affines[4], affines[5]);\n}\n\nCATransform3D caTransform3DFromMatrix(const Matrix& matrix) {\n    CGAffineTransform affineTransform = cgAffineTransformFromMatrix(matrix);\n    return CATransform3DMakeAffineTransform(affineTransform);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/CoreGraphicsUtils.hpp",
    "content": "//\n//  CoreGraphicsUtils.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/14/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include <CoreGraphics/CGPath.h>\n#include <QuartzCore/CATransform3D.h>\n\nnamespace snap::drawing {\n\nCGPathRef cgPathFromPath(const Path& path);\nCATransform3D caTransform3DFromMatrix(const Matrix& matrix);\nCGAffineTransform cgAffineTransformFromMatrix(const Matrix& matrix);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/Drawing/BaseDisplayLinkFrameScheduler.cpp",
    "content": "//\n//  BaseDisplayLinkFrameScheduler.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#include \"utils/platform/TargetPlatform.hpp\"\n\n#if __APPLE__\n#include \"dispatch/dispatch.h\"\n#include \"snap_drawing/apple/Drawing/BaseDisplayLinkFrameScheduler.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n\nnamespace snap::drawing {\n\n/**\n Delay in seconds after which the display link will be set to pause\n if the scheduler did not receive any tasks in that time frame.\n */\nconstexpr snap::drawing::TimeInterval kDisplayLinkTimeout = 1.0;\n\nstruct MainQueueFlushTask {\n    TimePoint time;\n    Ref<BaseDisplayLinkFrameScheduler> frameScheduler;\n\n    MainQueueFlushTask(TimePoint time, Ref<BaseDisplayLinkFrameScheduler>&& frameScheduler)\n        : time(time), frameScheduler(std::move(frameScheduler)) {}\n};\n\nBaseDisplayLinkFrameScheduler::BaseDisplayLinkFrameScheduler(Valdi::ILogger& logger) : _logger(logger) {}\n\nBaseDisplayLinkFrameScheduler::~BaseDisplayLinkFrameScheduler() {}\n\nstd::unique_lock<Valdi::Mutex> BaseDisplayLinkFrameScheduler::lock() const {\n    return std::unique_lock<Valdi::Mutex>(_mutex);\n}\n\nvoid BaseDisplayLinkFrameScheduler::onNextVSync(const Ref<IFrameCallback>& callback) {\n    auto guard = lock();\n    _vsyncCallbacks.emplace_back(callback);\n    updateDisplayLink(guard);\n}\n\nvoid BaseDisplayLinkFrameScheduler::onMainThread(const Ref<IFrameCallback>& callback) {\n    auto guard = lock();\n    _mainThreadCallbacks.emplace_back(callback);\n    updateDisplayLink(guard);\n}\n\nvoid BaseDisplayLinkFrameScheduler::flushMainThreadCallbacks(TimePoint time) {\n    auto flushedCallbacksCount = flushCallbacks(_mainThreadCallbacks, time);\n\n    auto guard = lock();\n\n    if (flushedCallbacksCount > 0) {\n        _displayLinkTimeout = snap::drawing::TimePoint::now() + snap::drawing::Duration(kDisplayLinkTimeout);\n    }\n\n    updateDisplayLink(guard);\n}\n\nvoid BaseDisplayLinkFrameScheduler::flushVSyncCallbacks(TimePoint time) {\n    flushCallbacks(_vsyncCallbacks, time);\n}\n\nsize_t BaseDisplayLinkFrameScheduler::flushCallbacks(CallbackQueue& queue, TimePoint time) {\n    CallbackQueue callbacksToFlush;\n    {\n        std::lock_guard<Valdi::Mutex> lock(_mutex);\n\n        callbacksToFlush = std::move(queue);\n        queue.clear();\n    }\n\n    for (const auto& callback : callbacksToFlush) {\n        callback->onFrame(time);\n    }\n\n    return callbacksToFlush.size();\n}\n\nvoid BaseDisplayLinkFrameScheduler::onDisplayLinkChanged(std::unique_lock<Valdi::Mutex>& lock) {\n    _displayLinkRunning = false;\n    updateDisplayLink(lock);\n}\n\nvoid BaseDisplayLinkFrameScheduler::updateDisplayLink(std::unique_lock<Valdi::Mutex>& lock) {\n    auto running = _displayLinkRunning;\n\n    if (_vsyncCallbacks.empty() && _mainThreadCallbacks.empty()) {\n        if (running && snap::drawing::TimePoint::now() > _displayLinkTimeout) {\n            _displayLinkRunning = false;\n            onPause(lock);\n        }\n    } else {\n        if (!running) {\n            _displayLinkRunning = true;\n            onResume(lock);\n        }\n    }\n}\n\nvoid BaseDisplayLinkFrameScheduler::onVSync() {\n    auto time = TimePoint::now();\n\n    auto flushTask = new MainQueueFlushTask(time, Valdi::strongSmallRef(this));\n\n    dispatch_async_f(dispatch_get_main_queue(), flushTask, &BaseDisplayLinkFrameScheduler::mainQueueCallback);\n\n    flushVSyncCallbacks(time);\n}\n\nValdi::ILogger& BaseDisplayLinkFrameScheduler::getLogger() const {\n    return _logger;\n}\n\nvoid BaseDisplayLinkFrameScheduler::mainQueueCallback(void* context) {\n    auto task = reinterpret_cast<MainQueueFlushTask*>(context);\n    task->frameScheduler->flushMainThreadCallbacks(task->time);\n    delete task;\n}\n\n} // namespace snap::drawing\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/Drawing/BaseDisplayLinkFrameScheduler.hpp",
    "content": "//\n//  BaseDisplayLinkFrameScheduler.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/IFrameScheduler.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"valdi_core/cpp/Interfaces/ILogger.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\n#include <deque>\n\nnamespace snap::drawing {\n\nusing CallbackQueue = Valdi::SmallVector<Ref<IFrameCallback>, 2>;\n\n/**\n Abstract class for an implementation of IFrameScheduler on Apple platforms\n meant to use a DisplayLink (like CADisplayLink or CVDisplayLink).\n */\nclass BaseDisplayLinkFrameScheduler : public IFrameScheduler {\npublic:\n    explicit BaseDisplayLinkFrameScheduler(Valdi::ILogger& logger);\n    ~BaseDisplayLinkFrameScheduler() override;\n\n    void onNextVSync(const Ref<IFrameCallback>& callback) override;\n\n    void onMainThread(const Ref<IFrameCallback>& callback) override;\n\n    void onVSync();\n\n    Valdi::ILogger& getLogger() const;\n\nprotected:\n    virtual void onResume(std::unique_lock<Valdi::Mutex>& lock) = 0;\n    virtual void onPause(std::unique_lock<Valdi::Mutex>& lock) = 0;\n\n    std::unique_lock<Valdi::Mutex> lock() const;\n\n    void onDisplayLinkChanged(std::unique_lock<Valdi::Mutex>& lock);\n\nprivate:\n    [[maybe_unused]] Valdi::ILogger& _logger;\n    snap::drawing::TimePoint _displayLinkTimeout = snap::drawing::TimePoint::now();\n    CallbackQueue _vsyncCallbacks;\n    CallbackQueue _mainThreadCallbacks;\n    mutable Valdi::Mutex _mutex;\n    bool _displayLinkRunning = false;\n\n    void updateDisplayLink(std::unique_lock<Valdi::Mutex>& lock);\n\n    size_t flushCallbacks(CallbackQueue& queue, TimePoint time);\n    void flushMainThreadCallbacks(TimePoint time);\n    void flushVSyncCallbacks(TimePoint time);\n\n    static void mainQueueCallback(void* context);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/Drawing/CADisplayLinkFrameScheduler.h",
    "content": "//\n//  CVDisplayLinkFrameScheduler.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/apple/Drawing/BaseDisplayLinkFrameScheduler.hpp\"\n\n#include <QuartzCore/CADisplayLink.h>\n\n@class SCSnapDrawingDisplayLinkTarget;\n\nnamespace snap::drawing {\n\nusing CallbackQueue = Valdi::SmallVector<Ref<IFrameCallback>, 2>;\n\nclass CADisplayLinkFrameScheduler : public BaseDisplayLinkFrameScheduler {\npublic:\n    explicit CADisplayLinkFrameScheduler(Valdi::ILogger& logger);\n    ~CADisplayLinkFrameScheduler() override;\n\nprotected:\n    void onResume(std::unique_lock<Valdi::Mutex>& lock) override;\n    void onPause(std::unique_lock<Valdi::Mutex>& lock) override;\n\nprivate:\n    CADisplayLink* _displayLink;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/Drawing/CADisplayLinkFrameScheduler.mm",
    "content": "//\n//  CADisplayLinkFrameScheduler.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#include \"utils/platform/TargetPlatform.hpp\"\n\n#if __APPLE__ && SC_IOS\n#include \"snap_drawing/apple/Drawing/CADisplayLinkFrameScheduler.h\"\n#import <Foundation/Foundation.h>\n\n@interface SCSnapDrawingDisplayLinkTarget: NSObject\n\n@end\n\n@implementation SCSnapDrawingDisplayLinkTarget {\n    snap::drawing::CADisplayLinkFrameScheduler *_frameScheduler;\n}\n\n- (instancetype)initWithScheduler:(snap::drawing::CADisplayLinkFrameScheduler *)frameScheduler\n{\n    self = [super init];\n\n    if (self) {\n        _frameScheduler = frameScheduler;\n    }\n\n    return self;\n}\n\n- (void)vsync\n{\n    _frameScheduler->onVSync();\n}\n\n@end\n\nnamespace snap::drawing {\n\nCADisplayLinkFrameScheduler::CADisplayLinkFrameScheduler(Valdi::ILogger& logger) : BaseDisplayLinkFrameScheduler(logger) {\n    SCSnapDrawingDisplayLinkTarget *target = [[SCSnapDrawingDisplayLinkTarget alloc] initWithScheduler:this];\n    _displayLink = [CADisplayLink displayLinkWithTarget:target selector:@selector(vsync)];\n}\n\nCADisplayLinkFrameScheduler::~CADisplayLinkFrameScheduler() {\n    [_displayLink invalidate];\n    _displayLink = nil;\n}\n\nvoid CADisplayLinkFrameScheduler::onResume(std::unique_lock<Valdi::Mutex>& lock) {\n    lock.unlock();\n    [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];\n}\n\nvoid CADisplayLinkFrameScheduler::onPause(std::unique_lock<Valdi::Mutex>& lock) {\n    lock.unlock();\n    [_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];\n}\n\n} // namespace snap::drawing\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/Drawing/CVDisplayLinkFrameScheduler.cpp",
    "content": "//\n//  CVDisplayLinkFrameScheduler.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#include \"utils/platform/TargetPlatform.hpp\"\n\n#if __APPLE__ && !SC_IOS\n#include \"snap_drawing/apple/Drawing/CVDisplayLinkFrameScheduler.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n\nextern \"C\" {\nvoid* objc_autoreleasePoolPush(void);\nvoid objc_autoreleasePoolPop(void* pool);\n}\n\nnamespace snap::drawing {\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n\nCVDisplayLinkFrameScheduler::CVDisplayLinkFrameScheduler(Valdi::ILogger& logger)\n    : BaseDisplayLinkFrameScheduler(logger) {}\n\nCVDisplayLinkFrameScheduler::~CVDisplayLinkFrameScheduler() {\n    auto guard = lock();\n    destroyDisplayLink();\n}\n\nvoid CVDisplayLinkFrameScheduler::setActiveDisplay(CGDirectDisplayID displayId) {\n    auto guard = lock();\n\n    if (displayId != _activeDisplay) {\n        destroyDisplayLink();\n        _activeDisplay = displayId;\n        createDisplayLink(guard);\n        onDisplayLinkChanged(guard);\n    }\n}\n\nvoid CVDisplayLinkFrameScheduler::destroyDisplayLink() {\n    if (_activeDisplay != kCGNullDirectDisplay) {\n        if (_displayLink) {\n            CVDisplayLinkStop(_displayLink);\n            CVDisplayLinkRelease(_displayLink);\n            _displayLink = nil;\n        }\n\n        _activeDisplay = kCGNullDirectDisplay;\n    }\n}\n\nvoid CVDisplayLinkFrameScheduler::createDisplayLink(std::unique_lock<Valdi::Mutex>& lock) {\n    if (_activeDisplay == kCGNullDirectDisplay) {\n        return;\n    }\n\n    auto code = CVDisplayLinkCreateWithCGDisplay(_activeDisplay, &_displayLink);\n    if (code != kCVReturnSuccess) {\n        VALDI_ERROR(getLogger(), \"Failed to create DisplayLink: {}\", code);\n        return;\n    }\n\n    CVDisplayLinkSetOutputCallback(_displayLink, &CVDisplayLinkFrameScheduler::displayLinkCallback, this);\n}\n\nvoid CVDisplayLinkFrameScheduler::onResume(std::unique_lock<Valdi::Mutex>& lock) {\n    auto displayLink = _displayLink;\n\n    if (displayLink) {\n        lock.unlock();\n        CVDisplayLinkStart(displayLink);\n    }\n}\n\nvoid CVDisplayLinkFrameScheduler::onPause(std::unique_lock<Valdi::Mutex>& lock) {\n    auto displayLink = _displayLink;\n\n    if (displayLink) {\n        lock.unlock();\n        CVDisplayLinkStop(displayLink);\n    }\n}\n\nCVReturn CVDisplayLinkFrameScheduler::displayLinkCallback(CVDisplayLinkRef displayLink,\n                                                          const CVTimeStamp* inNow,\n                                                          const CVTimeStamp* inOutputTime,\n                                                          CVOptionFlags flagsIn,\n                                                          CVOptionFlags* flagsOut,\n                                                          void* displayLinkContext) {\n    auto pool = objc_autoreleasePoolPush();\n\n    auto frameScheduler = Valdi::strongSmallRef(reinterpret_cast<CVDisplayLinkFrameScheduler*>(displayLinkContext));\n\n    frameScheduler->onVSync();\n\n    objc_autoreleasePoolPop(pool);\n\n    return kCVReturnSuccess;\n}\n\n#pragma clang diagnostic pop\n\n} // namespace snap::drawing\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/Drawing/CVDisplayLinkFrameScheduler.hpp",
    "content": "//\n//  CVDisplayLinkFrameScheduler.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/apple/Drawing/BaseDisplayLinkFrameScheduler.hpp\"\n\n#include <CoreVideo/CVDisplayLink.h>\n\nnamespace snap::drawing {\n\nclass CVDisplayLinkFrameScheduler : public BaseDisplayLinkFrameScheduler {\npublic:\n    explicit CVDisplayLinkFrameScheduler(Valdi::ILogger& logger);\n    ~CVDisplayLinkFrameScheduler() override;\n\n    void setActiveDisplay(CGDirectDisplayID displayId);\n\nprotected:\n    void onResume(std::unique_lock<Valdi::Mutex>& lock) override;\n    void onPause(std::unique_lock<Valdi::Mutex>& lock) override;\n\nprivate:\n    CGDirectDisplayID _activeDisplay = kCGNullDirectDisplay;\n    CVDisplayLinkRef _displayLink = nullptr;\n\n    void destroyDisplayLink();\n    void createDisplayLink(std::unique_lock<Valdi::Mutex>& lock);\n\n    static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink,\n                                        const CVTimeStamp* inNow,\n                                        const CVTimeStamp* inOutputTime,\n                                        CVOptionFlags flagsIn,\n                                        CVOptionFlags* flagsOut,\n                                        void* displayLinkContext);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/MetalGraphicsContext.mm",
    "content": "#import <Metal/Metal.h>\n#import <QuartzCore/CAMetalLayer.h>\n\n#import \"snap_drawing/cpp/Drawing/GraphicsContext/MetalGraphicsContext.hpp\"\n\n#include \"include/gpu/ganesh/GrDirectContext.h\"\n#include \"include/gpu/ganesh/mtl/SkSurfaceMetal.h\"\n#include \"include/gpu/ganesh/mtl/GrMtlDirectContext.h\"\n#include \"include/gpu/ganesh/mtl/GrMtlBackendContext.h\"\n#include \"include/core/SkSurface.h\"\n#include \"include/core/SkColorSpace.h\"\n\nnamespace snap::drawing {\n\nvoid MetalGraphicsContext::presentMetalDrawable(CFTypeRef mtlCommandBuffer, CFTypeRef mtlDrawableHandle) {\n    id<CAMetalDrawable> currentDrawable = (__bridge id<CAMetalDrawable>)mtlDrawableHandle;\n    id<MTLCommandBuffer> commandBuffer = (__bridge id<MTLCommandBuffer>)mtlCommandBuffer;\n\n    if (currentDrawable) {\n        [commandBuffer presentDrawable:currentDrawable];\n    }\n}\n\nCFTypeRef MetalGraphicsContext::createCommandBuffer(CFTypeRef mtlCommandQueue) {\n    id<MTLCommandBuffer> commandBuffer = [(__bridge id<MTLCommandQueue>)mtlCommandQueue commandBuffer];\n    CFTypeRef rawCommandBuffer = (__bridge CFTypeRef)(commandBuffer);\n\n    CFRetain(rawCommandBuffer);\n    return rawCommandBuffer;\n}\n\nvoid MetalGraphicsContext::commitCommandBuffer(CFTypeRef mtlCommandBuffer) {\n    id<MTLCommandBuffer> commandBuffer = (__bridge id<MTLCommandBuffer>)mtlCommandBuffer;\n    [commandBuffer commit];\n}\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wunguarded-availability-new\"\n\nsnap::drawing::MetalLayerSize MetalGraphicsContext::getMetalLayerSize(CFTypeRef mtlLayer) {\n    CAMetalLayer *metalLayer = (__bridge CAMetalLayer *)mtlLayer;\n\n    CGSize drawableSize = metalLayer.drawableSize;\n\n    return snap::drawing::MetalLayerSize(drawableSize.width, drawableSize.height);\n}\n\n#pragma clang diagnostic pop\n\nsk_sp<GrDirectContext> MetalGraphicsContext::makeContext(void *mtlDevice, void *mtlCommandQueue, const GrContextOptions &options) {\n    GrMtlBackendContext mtlBackendContext;\n    mtlBackendContext.fDevice.retain(mtlDevice);\n    mtlBackendContext.fQueue.retain(mtlCommandQueue);\n\n    return GrDirectContexts::MakeMetal(mtlBackendContext, options);\n}\n\nsk_sp<SkSurface> MetalGraphicsContext::makeSurface(GrDirectContext *grContext, const void *mtlLayer, int sampleCount, SkColorType colorType, const void **mtlDrawableHandle) {\n    return SkSurfaces::WrapCAMetalLayer(grContext, mtlLayer, kTopLeft_GrSurfaceOrigin, sampleCount, colorType, nullptr, nullptr, mtlDrawableHandle);\n}\n\n}\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/MetalSurfacePresenterManager.h",
    "content": "//\n//  SCValdiMacOSSurfacePresenterManager.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 2/22/22.\n//\n\n#pragma once\n\n#import \"Foundation/Foundation.h\"\n\n#include \"snap_drawing/apple/CoreGraphicsUtils.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/MetalGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenterManager.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n\n@class CAMetalLayer;\n\n@protocol SCSnapDrawingMetalSurfacePresenterManagerDelegate <NSObject>\n\n- (id)createMetalPresenter:(inout CAMetalLayer**)metalLayer API_AVAILABLE(ios(13.0));\n\n- (id)createEmbeddedPresenterForView:(id)view;\n\n- (void)removePresenter:(id)presenter;\n\n- (void)setZIndex:(NSUInteger)zIndex forPresenter:(id)presenter;\n\n- (void)setFrame:(CGRect)frame\n               transform:(CATransform3D)transform\n                 opacity:(CGFloat)opacity\n                clipPath:(CGPathRef)clipPath\n          clipHasChanged:(BOOL)clipHasChanged\n    forEmbeddedPresenter:(id)presenter;\n\n@end\n\nnamespace snap::drawing {\n\nclass ExternalSurface;\n\nclass MetalSurfacePresenterManager : public SurfacePresenterManager {\npublic:\n    MetalSurfacePresenterManager(id<SCSnapDrawingMetalSurfacePresenterManagerDelegate> delegate,\n                                 const Ref<MetalGraphicsContext>& graphicsContext);\n\n    ~MetalSurfacePresenterManager() override;\n\n    Ref<DrawableSurface> createPresenterWithDrawableSurface(SurfacePresenterId presenterId, size_t zIndex) override;\n\n    void createPresenterForExternalSurface(SurfacePresenterId presenterId,\n                                           size_t zIndex,\n                                           ExternalSurface& externalSurface) override;\n\n    void setSurfacePresenterZIndex(SurfacePresenterId presenterId, size_t zIndex) override;\n\n    void setExternalSurfacePresenterState(SurfacePresenterId presenterId,\n                                          const ExternalSurfacePresenterState& presenterState,\n                                          const ExternalSurfacePresenterState* previousPresenterState) override;\n\n    void removeSurfacePresenter(SurfacePresenterId presenterId) override;\n\nprotected:\n    virtual id getEmbeddedViewForExternalSurface(ExternalSurface& externalSurface) = 0;\n\nprivate:\n    __weak id<SCSnapDrawingMetalSurfacePresenterManagerDelegate> _delegate;\n    Ref<MetalGraphicsContext> _graphicsContext;\n    Valdi::FlatMap<SurfacePresenterId, CFTypeRef> _presenters;\n\n    id presenterForDisplayId(SurfacePresenterId presenterId) const;\n};\n\n}; // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/apple/MetalSurfacePresenterManager.mm",
    "content": "//\n//  SCValdiMetalSurfacePresenterManager.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 2/22/22.\n//\n\n#include \"snap_drawing/apple/MetalSurfacePresenterManager.h\"\n#include \"snap_drawing/apple/CoreGraphicsUtils.hpp\"\n#include \"utils/platform/TargetPlatform.hpp\"\n\n#import <QuartzCore/CAMetalLayer.h>\n\nnamespace snap::drawing {\n\nMetalSurfacePresenterManager::MetalSurfacePresenterManager(id<SCSnapDrawingMetalSurfacePresenterManagerDelegate> delegate,\n                                                           const Ref<MetalGraphicsContext> &graphicsContext): _delegate(delegate), _graphicsContext(graphicsContext) {\n    \n}\n\nMetalSurfacePresenterManager::~MetalSurfacePresenterManager() {\n    _delegate = nil;\n    for (const auto &it: _presenters) {\n        CFRelease(it.second);\n    }\n}\n\nRef<DrawableSurface> MetalSurfacePresenterManager::createPresenterWithDrawableSurface(SurfacePresenterId presenterId, size_t zIndex) {\n    if (@available(iOS 13.0, macOS 10.11, *)) {\n        CAMetalLayer *metalLayer;\n        id presenter = [_delegate createMetalPresenter:&metalLayer];\n        if (!presenter) {\n            return nullptr;\n        }\n\n        metalLayer.device = (__bridge  id)_graphicsContext->getMTLDevice();\n        metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;\n#if __APPLE__ && !SC_IOS\n        metalLayer.displaySyncEnabled = YES;\n#endif\n        metalLayer.framebufferOnly = YES;\n        metalLayer.opaque = NO;\n\n        auto surface = _graphicsContext->createSurfaceForMetalLayer((__bridge CFTypeRef)metalLayer, 1);\n\n        _presenters[presenterId] = CFBridgingRetain(presenter);\n\n        setSurfacePresenterZIndex(presenterId, zIndex);\n\n        return surface;\n    } else {\n        return nullptr;\n    }\n}\n\nvoid MetalSurfacePresenterManager::createPresenterForExternalSurface(SurfacePresenterId presenterId, size_t zIndex, ExternalSurface& externalSurface) {\n    id embeddedView = getEmbeddedViewForExternalSurface(externalSurface);\n    id presenter = [_delegate createEmbeddedPresenterForView:embeddedView];\n    if (!presenter) {\n        return;\n    }\n\n    _presenters[presenterId] = CFBridgingRetain(presenter);\n    \n    setSurfacePresenterZIndex(presenterId, zIndex);\n}\n\nvoid MetalSurfacePresenterManager::setSurfacePresenterZIndex(SurfacePresenterId presenterId, size_t zIndex) {\n    id presenter = presenterForDisplayId(presenterId);\n    [_delegate setZIndex:zIndex forPresenter:presenter];\n}\n\nvoid MetalSurfacePresenterManager::setExternalSurfacePresenterState(SurfacePresenterId presenterId,\n                                                                    const ExternalSurfacePresenterState& presenterState,\n                                                                    const ExternalSurfacePresenterState* previousPresenterState) {\n    id presenter = presenterForDisplayId(presenterId);\n    CGRect frame = CGRectMake(presenterState.frame.x(), presenterState.frame.y(), presenterState.frame.width(), presenterState.frame.height());\n    auto transform = snap::drawing::caTransform3DFromMatrix(presenterState.transform);\n    \n    BOOL clipHasChanged = NO;\n    CGPathRef clipPathRef = nil;\n    \n    if (previousPresenterState == nullptr || presenterState.clipPath != previousPresenterState->clipPath) {\n        clipHasChanged = YES;\n        \n        if (!presenterState.clipPath.isEmpty()) {\n            clipPathRef = snap::drawing::cgPathFromPath(presenterState.clipPath);\n        }\n    }\n\n    [_delegate setFrame:frame\n              transform:transform\n                opacity:presenterState.opacity\n               clipPath:clipPathRef\n         clipHasChanged:clipHasChanged\n   forEmbeddedPresenter:presenter];\n\n    if (clipPathRef) {\n        CGPathRelease(clipPathRef);\n    }\n}\n\nvoid MetalSurfacePresenterManager::removeSurfacePresenter(SurfacePresenterId presenterId) {\n    auto it = _presenters.find(presenterId);\n    if (it == _presenters.end()) {\n        return;\n    }\n\n    id presenter = CFBridgingRelease(it->second);\n\n    _presenters.erase(it);\n\n    [_delegate removePresenter:presenter];\n}\n\nid MetalSurfacePresenterManager::presenterForDisplayId(SurfacePresenterId presenterId) const {\n    const auto &it = _presenters.find(presenterId);\n    if (it == _presenters.end()) {\n        return nil;\n    }\n\n    return (__bridge  id)it->second;\n}\n\n}\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/Animation.cpp",
    "content": "//\n//  Animation.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 7/3/20.\n//\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n\nnamespace snap::drawing {\n\nAnimation::Animation(Duration duration, InterpolationFunction&& interpolationFunction, AnimationApplier&& applier)\n    : _duration(duration),\n      _remainingDuration(duration),\n      _interpolationFunction(std::move(interpolationFunction)),\n      _applier(std::move(applier)) {}\n\nAnimation::~Animation() = default;\n\nbool Animation::run(Layer& layer, Duration delta) {\n    if (!_started) {\n        _applier(layer, 0.0);\n        _started = true;\n        return false;\n    }\n\n    _remainingDuration -= delta;\n\n    if (_remainingDuration.seconds() <= 0) {\n        _remainingDuration = Duration();\n        _applier(layer, 1.0);\n\n        return true;\n    } else {\n        auto ratio = _interpolationFunction(1.0 - (_remainingDuration.seconds() / _duration.seconds()));\n        _applier(layer, ratio);\n\n        return false;\n    }\n}\n\nvoid Animation::cancel(Layer& layer) {\n    finish(layer, false);\n}\n\nvoid Animation::complete(Layer& layer) {\n    finish(layer, true);\n}\n\nvoid Animation::finish(Layer& layer, bool didComplete) {\n    auto applier = std::move(_applier);\n    _applier = nullptr;\n    if (applier) {\n        applier(layer, 1.0);\n    }\n\n    auto completions = std::move(_completions);\n    for (const auto& completion : completions) {\n        completion(didComplete);\n    }\n}\n\nvoid Animation::addCompletion(AnimationCompletion&& completion) {\n    _completions.emplace_back(std::move(completion));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/Animation.hpp",
    "content": "//\n//  Animation.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 7/3/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\n#include \"snap_drawing/cpp/Animations/InterpolationFunction.hpp\"\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n\n#include <vector>\n\nnamespace snap::drawing {\n\nclass Layer;\n\nusing AnimationCompletion = Valdi::Function<void(bool)>;\nusing AnimationApplier = Valdi::Function<void(Layer&, double)>;\n\nclass IAnimation : public Valdi::SimpleRefCountable {\npublic:\n    /**\n     Run the animation on the given layer with the delta duration from the last run call.\n     Returns whether the animation has completed.\n     */\n    virtual bool run(Layer& layer, Duration delta) = 0;\n\n    /**\n     Cancel the animation, which will clear the animation object and call the completion handler\n     */\n    virtual void cancel(Layer& layer) = 0;\n\n    /**\n     Complete the animation, which will clear the animation object and call the completion handler.\n     This should be called after the run() function returns true.\n     */\n    virtual void complete(Layer& layer) = 0;\n\n    /**\n     A set of completion handlers to call when the animation completes or is cancelled\n     */\n    virtual void addCompletion(AnimationCompletion&& completion) = 0;\n};\n\nclass Animation : public IAnimation {\npublic:\n    Animation(Duration duration, InterpolationFunction&& interpolationFunction, AnimationApplier&& applier);\n    ~Animation() override;\n\n    bool run(Layer& layer, Duration delta) override;\n\n    void cancel(Layer& layer) override;\n\n    void complete(Layer& layer) override;\n\n    void addCompletion(AnimationCompletion&& completion) override;\n\nprivate:\n    Duration _duration;\n    Duration _remainingDuration;\n    InterpolationFunction _interpolationFunction;\n    AnimationApplier _applier;\n    std::vector<snap::drawing::AnimationCompletion> _completions;\n    bool _started = false;\n\n    void finish(Layer& layer, bool didComplete);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/InterpolationFunction.cpp",
    "content": "//\n//  InterpolationFunction.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 7/3/20.\n//\n\n#include \"snap_drawing/cpp/Animations/InterpolationFunction.hpp\"\n#include \"snap_drawing/cpp/Animations/ViscousFluidInterpolator.hpp\"\n#include \"snap_drawing/cpp/Animations/bezier.hpp\"\n#include <cmath>\n#include <cstdio>\n\nnamespace snap::drawing {\n\nstatic Bezier::Bezier<3> makeTimingCurve(float p1x, float p1y, float p2x, float p2y) {\n    Bezier::Bezier<3> curve({{0.0, 0.0}, {p1x, p1y}, {p2x, p2y}, {1.0, 1.0}});\n    return curve;\n}\n\nstatic InterpolationFunction makeInterpolationFunction(const Bezier::Bezier<3>& curve) {\n    return [curve](double t) -> double {\n        double mappedX = curve.valueAt(static_cast<float>(t), 0);\n        double mappedY = curve.valueAt(static_cast<float>(mappedX), 1);\n        return mappedY;\n    };\n}\n\n// matches https://developer.apple.com/documentation/quartzcore/camediatimingfunctionname/1521854-default\nBezier::Bezier<3> defaultBezier = makeTimingCurve(0.25, 0.1, 0.25, 1.0);\n// matches https://developer.apple.com/documentation/quartzcore/camediatimingfunctionname/1522173-easeineaseout\nBezier::Bezier<3> easeInOutBezier = makeTimingCurve(0.42, 0.0, 0.58, 1.0);\n// matches https://developer.apple.com/documentation/quartzcore/camediatimingfunctionname/1521971-easein\nBezier::Bezier<3> easeInBezier = makeTimingCurve(0.42, 0.0, 1.0, 1.0);\n// matches https://developer.apple.com/documentation/quartzcore/camediatimingfunctionname/1522178-easeout\nBezier::Bezier<3> easeOutBezier = makeTimingCurve(0.0, 0.0, 0.58, 1.0);\n\nBezier::Bezier<3> strongEaseOutBezier = makeTimingCurve(0.9, 0.90, 0.95, 1.0);\n\nstatic const ViscousFluidInterpolator& getViscousFluidInterpolator() {\n    static ViscousFluidInterpolator kInstance;\n    return kInstance;\n}\n\nInterpolationFunction InterpolationFunctions::linear() {\n    return [](double ratio) -> double { return ratio; };\n}\n\nInterpolationFunction InterpolationFunctions::systemDefault() {\n    return makeInterpolationFunction(defaultBezier);\n}\n\nInterpolationFunction InterpolationFunctions::easeInOut() {\n    return makeInterpolationFunction(easeInOutBezier);\n}\n\nInterpolationFunction InterpolationFunctions::easeIn() {\n    return makeInterpolationFunction(easeInBezier);\n}\n\nInterpolationFunction InterpolationFunctions::easeOut() {\n    return makeInterpolationFunction(easeOutBezier);\n}\n\nInterpolationFunction InterpolationFunctions::strongEaseOut() {\n    return makeInterpolationFunction(strongEaseOutBezier);\n}\n\nInterpolationFunction InterpolationFunctions::viscousFluid() {\n    return [](double ratio) -> double { return getViscousFluidInterpolator().interpolate(ratio); };\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/InterpolationFunction.hpp",
    "content": "//\n//  InterpolationFunction.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 7/3/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n\nnamespace snap::drawing {\n\nusing InterpolationFunction = Valdi::Function<double(double)>;\n\nclass InterpolationFunctions {\npublic:\n    static InterpolationFunction linear();\n    static InterpolationFunction systemDefault();\n    static InterpolationFunction easeInOut();\n    static InterpolationFunction easeIn();\n    static InterpolationFunction easeOut();\n    static InterpolationFunction strongEaseOut();\n    static InterpolationFunction viscousFluid();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/SpringAnimation.cpp",
    "content": "//\n// Created by Carson Holgate on 8/4/22.\n//\n\n#include \"SpringAnimation.hpp\"\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\n#include <float.h>\n\nstatic constexpr double kMax = std::numeric_limits<double>::max();\nstatic constexpr double kMin = std::numeric_limits<double>::min();\n\nnamespace snap::drawing {\n\nSpringAnimation::SpringAnimation(double stiffness, double damping, double minVisibleChange, AnimationApplier&& applier)\n    : _applier(applier), _spring(damping, stiffness, minVisibleChange) {}\n\nSpringAnimation::~SpringAnimation() = default;\n\nbool SpringAnimation::run(Layer& layer, Duration delta) {\n    if (!_started) {\n        _applier(layer, 0.0);\n        _started = true;\n        return false;\n    }\n\n    if (_endRequested) {\n        if (_pendingPosition != kMax) {\n            _spring.setFinalPosition(_pendingPosition);\n            _pendingPosition = kMax;\n        }\n        _value = _spring.getFinalPosition();\n        _velocity = 0;\n        _endRequested = false;\n        return true;\n    }\n    if (_pendingPosition != kMax) {\n        // Approximate by considering half of the time spring position stayed at the old\n        // position, half of the time it's at the new position.\n        MassState massState = _spring.updateValues(_value, _velocity, delta.milliseconds() / 2);\n        _spring.setFinalPosition(_pendingPosition);\n        _pendingPosition = kMax;\n        massState = _spring.updateValues(massState.value, massState.velocity, delta.milliseconds() / 2);\n        _value = massState.value;\n        _velocity = massState.velocity;\n    } else {\n        MassState massState = _spring.updateValues(_value, _velocity, delta.milliseconds());\n        _value = massState.value;\n        _velocity = massState.velocity;\n    }\n    _value = fmax(_value, kMin);\n    _value = fmin(_value, kMax);\n    if (_spring.isAtEquilibrium(_value, _velocity)) {\n        _value = _spring.getFinalPosition();\n        _velocity = 0;\n        _applier(layer, _value);\n        return true;\n    }\n\n    _applier(layer, _value);\n    return false;\n}\n\nvoid SpringAnimation::cancel(Layer& layer) {\n    finish(layer, false);\n}\n\nvoid SpringAnimation::complete(Layer& layer) {\n    finish(layer, true);\n}\n\nvoid SpringAnimation::finish(Layer& layer, bool didComplete) {\n    auto applier = std::move(_applier);\n    _applier = nullptr;\n    if (applier) {\n        applier(layer, 1.0);\n    }\n\n    for (const auto& completion : _completions) {\n        completion(didComplete);\n    }\n    _completions.clear();\n}\n\nvoid SpringAnimation::addCompletion(AnimationCompletion&& completion) {\n    _completions.emplace_back(std::move(completion));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/SpringAnimation.hpp",
    "content": "//\n// Created by Carson Holgate on 8/4/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n#include \"snap_drawing/cpp/Animations/SpringForce.hpp\"\n\nnamespace snap::drawing {\n\nclass SpringAnimation : public IAnimation {\npublic:\n    SpringAnimation(double stiffness, double damping, double minVisibleChange, AnimationApplier&& applier);\n    ~SpringAnimation() override;\n\n    bool run(Layer& layer, Duration delta) override;\n\n    void cancel(Layer& layer) override;\n\n    void complete(Layer& layer) override;\n\n    void addCompletion(AnimationCompletion&& completion) override;\n\nprivate:\n    AnimationApplier _applier;\n    std::vector<snap::drawing::AnimationCompletion> _completions;\n    bool _started = false;\n    SpringForce _spring;\n    double _value = 0;\n    double _velocity = 0;\n    double _pendingPosition = 1;\n    bool _endRequested = false;\n\n    void finish(Layer& layer, bool didComplete);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/SpringForce.cpp",
    "content": "//\n// Created by Carson Holgate on 8/4/22.\n//\n\n#include \"SpringForce.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n#include <cstdlib>\n#include <float.h>\n#include <math.h>\n\n// This was borrowed from Android's spring force implementation\n// https://android.googlesource.com/platform/frameworks/support/+/300475fc42431cefb0d8f1bfc70de1a7a052a501/dynamic-animation/src/main/java/android/support/animation/SpringForce.java#77\nstatic constexpr double kVelocityThresholdMultiplier = 1000.0 / 16.0;\n\nnamespace snap::drawing {\nSpringForce::SpringForce(double damping, double stiffness, double valueThreshold)\n    : _valueThreshold(abs(valueThreshold)) {\n    // This is borrowed from the Android implementation\n    // //valdi/src/java/com/snap/valdi/attributes/impl/animations/ValdiSpringAnimator.kt#L31\n    _dampingRatio = damping / (2 * sqrt(stiffness));\n    if (_dampingRatio < 0) {\n        SC_ASSERT_FAIL(\"SpringForce damping ratio must be greater than 0\");\n    }\n    _frequency = sqrt(stiffness);\n\n    if (_dampingRatio > 1) {\n        // Over damping\n        _gammaPlus = -_dampingRatio * _frequency + _frequency * sqrt(_dampingRatio * _dampingRatio - 1);\n        _gammaMinus = -_dampingRatio * _frequency - _frequency * sqrt(_dampingRatio * _dampingRatio - 1);\n    } else if (_dampingRatio >= 0 && _dampingRatio < 1) {\n        // Under damping\n        _dampedFreq = _frequency * sqrt(1 - _dampingRatio * _dampingRatio);\n    }\n\n    _velocityThreshold = _valueThreshold * kVelocityThresholdMultiplier;\n}\n\nvoid SpringForce::setFinalPosition(double finalPosition) {\n    _finalPosition = finalPosition;\n}\n\ndouble SpringForce::getFinalPosition() const {\n    return _finalPosition;\n}\n\nMassState SpringForce::updateValues(double lastDisplacement, double lastVelocity, long timeElapsed) {\n    double deltaT = timeElapsed / 1000.0;\n    lastDisplacement -= _finalPosition;\n    double displacement;\n    double currentVelocity;\n    double e = M_E;\n\n    if (_dampingRatio > 1) {\n        // Overdamped\n        double coeffA = lastDisplacement - (_gammaMinus * lastDisplacement - lastVelocity) / (_gammaMinus - _gammaPlus);\n        double coeffB = (_gammaMinus * lastDisplacement - lastVelocity) / (_gammaMinus - _gammaPlus);\n        displacement = coeffA * pow(e, _gammaMinus * deltaT) + coeffB * pow(e, _gammaPlus * deltaT);\n        currentVelocity =\n            coeffA * _gammaMinus * pow(e, _gammaMinus * deltaT) + coeffB * _gammaPlus * pow(e, _gammaPlus * deltaT);\n    } else if (_dampingRatio == 1) {\n        // Critically damped\n        double coeffA = lastDisplacement;\n        double coeffB = lastVelocity + _frequency * lastDisplacement;\n        displacement = (coeffA + coeffB * deltaT) * pow(e, -_frequency * deltaT);\n        currentVelocity = (coeffA + coeffB * deltaT) * pow(e, -_frequency * deltaT) * (-_frequency) +\n                          coeffB * pow(e, -_frequency * deltaT);\n    } else {\n        // Underdamped\n        double cosCoeff = lastDisplacement;\n        double sinCoeff = (1 / _dampedFreq) * (_dampingRatio * _frequency * lastDisplacement + lastVelocity);\n        displacement = pow(e, -_dampingRatio * _frequency * deltaT) *\n                       (cosCoeff * cos(_dampedFreq * deltaT) + sinCoeff * sin(_dampedFreq * deltaT));\n        currentVelocity =\n            displacement * (-_frequency) * _dampingRatio +\n            pow(e, -_dampingRatio * _frequency * deltaT) * (-_dampedFreq * cosCoeff * sin(_dampedFreq * deltaT) +\n                                                            _dampedFreq * sinCoeff * cos(_dampedFreq * deltaT));\n    }\n    _massState.value = displacement + _finalPosition;\n    _massState.velocity = currentVelocity;\n    return _massState;\n}\n\ndouble SpringForce::getAcceleration(double lastDisplacement, double lastVelocity) const {\n    lastDisplacement -= getFinalPosition();\n    double k = _frequency * _frequency;\n    double c = 2 * _frequency * _dampingRatio;\n    return -k * lastDisplacement - c * lastVelocity;\n}\n\nbool SpringForce::isAtEquilibrium(double value, double velocity) const {\n    return abs(velocity) < _velocityThreshold && abs(value - _finalPosition) < _valueThreshold;\n}\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/SpringForce.hpp",
    "content": "//\n// Created by Carson Holgate on 8/4/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n\nnamespace snap::drawing {\n\nclass MassState {\npublic:\n    float value;\n    float velocity;\n};\n\nclass SpringForce {\npublic:\n    SpringForce(double damping, double stiffness, double valueThreshold);\n    ~SpringForce() = default;\n\n    void setValueThreshold(double threshold);\n\n    void setFinalPosition(double finalPosition);\n\n    double getFinalPosition() const;\n\n    MassState updateValues(double lastDisplacement, double lastVelocity, long timeElapsed);\n\n    double getAcceleration(double lastDisplacement, double lastVelocity) const;\n\n    bool isAtEquilibrium(double value, double velocity) const;\n\nprivate:\n    double _dampingRatio;\n    double _frequency;\n    double _valueThreshold;\n    double _velocityThreshold;\n    double _gammaPlus;\n    double _gammaMinus;\n    double _dampedFreq;\n    double _finalPosition = 1;\n    MassState _massState;\n\n    void init();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/ValueInterpolators.cpp",
    "content": "//\n//  ValueInterpolators.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/3/20.\n//\n\n#include \"snap_drawing/cpp/Animations/ValueInterpolators.hpp\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nRect interpolateValue(const Rect& from, const Rect& to, double ratio) {\n    auto l = interpolateValue(from.left, to.left, ratio);\n    auto t = interpolateValue(from.top, to.top, ratio);\n    auto r = interpolateValue(from.right, to.right, ratio);\n    auto b = interpolateValue(from.bottom, to.bottom, ratio);\n    return Rect::makeLTRB(l, t, r, b);\n}\n\nSize interpolateValue(const Size& from, const Size& to, double ratio) {\n    auto width = interpolateValue(from.width, to.width, ratio);\n    auto height = interpolateValue(from.height, to.height, ratio);\n    return Size::make(width, height);\n}\n\nPoint interpolateValue(const Point& from, const Point& to, double ratio) {\n    auto x = interpolateValue(from.x, to.x, ratio);\n    auto y = interpolateValue(from.y, to.y, ratio);\n    return Point::make(x, y);\n}\n\nScalar interpolateValue(Scalar from, Scalar to, double ratio) {\n    return from + ((to - from) * ratio);\n}\n\nstatic ColorComponent blendColorAlpha(ColorComponent from, ColorComponent to, double ratio) {\n    auto alpha = (1.0 - ratio) * static_cast<double>(from) + (ratio * static_cast<double>(to));\n    return static_cast<ColorComponent>(alpha);\n}\n\nstatic ColorComponent blendColorComponent(ColorComponent from, ColorComponent to, double ratio) {\n    auto component = sqrt((1.0 - ratio) * pow(static_cast<double>(from), 2) + ratio * pow(static_cast<double>(to), 2));\n\n    return static_cast<ColorComponent>(component);\n}\n\nColor interpolateValue(Color from, Color to, double ratio) {\n    double clampedRatio = std::clamp(ratio, 0.0, 1.0);\n    auto alpha = blendColorAlpha(from.getAlpha(), to.getAlpha(), clampedRatio);\n    auto red = blendColorComponent(from.getRed(), to.getRed(), clampedRatio);\n    auto green = blendColorComponent(from.getGreen(), to.getGreen(), clampedRatio);\n    auto blue = blendColorComponent(from.getBlue(), to.getBlue(), clampedRatio);\n\n    return Color::makeARGB(alpha, red, green, blue);\n}\n\nstatic inline Scalar interpolateCorner(\n    Scalar from, Scalar to, bool fromIsPercent, bool toIsPercent, double progress, Scalar sideLength) {\n    if (fromIsPercent == toIsPercent) {\n        return interpolateValue(from, to, progress);\n    } else if (fromIsPercent) {\n        auto fromPoints = from * sideLength / 100;\n        return interpolateValue(fromPoints, to, progress);\n    } else {\n        auto fromPercent = from / sideLength * 100;\n        return interpolateValue(fromPercent, to, progress);\n    }\n}\n\nBorderRadius interpolateBorderRadius(BorderRadius from, BorderRadius to, const Rect& bounds, double ratio) {\n    Scalar sideLength = BorderRadius::sideLengthForPercentages(bounds);\n    return BorderRadius(\n        interpolateCorner(\n            from.topLeft(), to.topLeft(), from.topLeftIsPercent(), to.topLeftIsPercent(), ratio, sideLength),\n        interpolateCorner(\n            from.topRight(), to.topRight(), from.topRightIsPercent(), to.topRightIsPercent(), ratio, sideLength),\n        interpolateCorner(from.bottomRight(),\n                          to.bottomRight(),\n                          from.bottomRightIsPercent(),\n                          to.bottomRightIsPercent(),\n                          ratio,\n                          sideLength),\n        interpolateCorner(from.bottomLeft(),\n                          to.bottomLeft(),\n                          from.bottomLeftIsPercent(),\n                          to.bottomLeftIsPercent(),\n                          ratio,\n                          sideLength),\n        to.topLeftIsPercent(),\n        to.topRightIsPercent(),\n        to.bottomRightIsPercent(),\n        to.bottomLeftIsPercent());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/ValueInterpolators.hpp",
    "content": "//\n//  ValueInterpolators.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/3/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\nnamespace snap::drawing {\n\nRect interpolateValue(const Rect& from, const Rect& to, double ratio);\nSize interpolateValue(const Size& from, const Size& to, double ratio);\nPoint interpolateValue(const Point& from, const Point& to, double ratio);\nScalar interpolateValue(Scalar from, Scalar to, double ratio);\nColor interpolateValue(Color from, Color to, double ratio);\n\nBorderRadius interpolateBorderRadius(BorderRadius from, BorderRadius to, const Rect& bounds, double ratio);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/ViscousFluidInterpolator.cpp",
    "content": "//\n//  ViscousFluidInterpolator.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 11/21/22.\n//\n\n#include \"snap_drawing/cpp/Animations/ViscousFluidInterpolator.hpp\"\n\nnamespace snap::drawing {\n\nViscousFluidInterpolator::ViscousFluidInterpolator() {\n    // must be set to 1.0 (used in viscousFluid())\n    _normalize = 1.0f / viscousFluid(1.0f);\n    // account for very small floating-point error\n    _offset = 1.0f - _normalize * viscousFluid(1.0f);\n}\n\ndouble ViscousFluidInterpolator::viscousFluid(double x) const {\n    x *= _scale;\n    if (x < 1.0) {\n        x -= (1.0 - std::exp(-x));\n    } else {\n        double start = 0.36787944117; // 1/e == exp(-1)\n        x = 1.0 - std::exp(1.0 - x);\n        x = start + x * (1.0 - start);\n    }\n    return x;\n}\n\ndouble ViscousFluidInterpolator::interpolate(double i) const {\n    auto interpolated = _normalize * viscousFluid(i);\n    if (interpolated > 0) {\n        return interpolated + _offset;\n    }\n    return interpolated;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/ViscousFluidInterpolator.hpp",
    "content": "//\n//  ViscousFluidInterpolator.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 11/21/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n\nnamespace snap::drawing {\n\n/**\n An interpolator implementing the \"viscous fluid\" effect\n from the Android's scroll animation implementation.\n */\nclass ViscousFluidInterpolator {\npublic:\n    ViscousFluidInterpolator();\n\n    double interpolate(double i) const;\n\nprivate:\n    double _scale = 8.0f;\n    double _normalize;\n    double _offset;\n\n    double viscousFluid(double x) const;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Animations/bezier.hpp",
    "content": "#ifndef bezier_h\n#define bezier_h\n\n/* Copyright © 2018 Øystein Myrmo (oystein.myrmo@gmail.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n#pragma once\n#include <assert.h> // NOLINT\n#include <limits>\n#include <math.h> // NOLINT\n#include <vector>\n\n// Cross platform define for printing size_t variables\n#ifdef __WIN32__\n#define BEZIER_SIZE_T_FORMAT \"%ld\"\n#else\n#define BEZIER_SIZE_T_FORMAT \"%zd\"\n#endif\n\n#define BEZIER_FUZZY_EPSILON 0.0001\n#define BEZIER_DEFAULT_INTERVALS 10\n#define BEZIER_DEFAULT_MAX_ITERATIONS 15\n\nnamespace Bezier {\nnamespace Math {\ninline double faculty(size_t n) {\n    double d = 1.0;\n    if (n == 0 || n == 1)\n        return d;\n    for (size_t i = 2; i <= n; i++)\n        d *= (double)i; // NOLINT\n    return d;\n}\n\n// Note: Using faculty function seems to be way faster than the recursive one\n// given at https://en.wikipedia.org/wiki/Binomial_coefficient\ninline double binomial(size_t n, size_t k) {\n    assert(k <= n);\n    return faculty(n) / (faculty(k) * faculty(n - k));\n}\n\ninline bool isWithinZeroAndOne(float x) {\n    return x >= -BEZIER_FUZZY_EPSILON && x <= (1.0 + BEZIER_FUZZY_EPSILON);\n}\n} // namespace Math\n\ntemplate<size_t N> // NOLINT\nclass BinomialCoefficients {\npublic:\n    BinomialCoefficients() {\n        size_t center = N / 2;\n        size_t k = 0;\n\n        while (k <= center) {\n            mCoefficients[k] = Math::binomial(N, k); // NOLINT\n            k++;\n        }\n\n        // Utilize the symmetrical nature of the binomial coefficients.\n        while (k <= N) {\n            mCoefficients[k] = mCoefficients[N - k]; // NOLINT\n            k++;\n        }\n    }\n\n    static constexpr size_t size() {\n        return N + 1;\n    }\n\n    size_t operator[](size_t idx) const {\n        assert(idx < size());\n        return mCoefficients[idx]; // NOLINT\n    }\n\nprivate:\n    float mCoefficients[size()]; // NOLINT\n};\n\nstruct PolynomialPair {\n    size_t t = 0;\n    size_t one_minus_t = 0; // NOLINT\n\n    double valueAt(float t) const {\n        return pow(1 - t, one_minus_t) * pow(t, this->t);\n    }\n};\n\ntemplate<size_t N> // NOLINT\nclass PolynomialCoefficients {\npublic:\n    PolynomialCoefficients() {\n        for (size_t i = 0; i <= N; i++) {\n            mPolynomialPairs[i].t = i;               // NOLINT\n            mPolynomialPairs[i].one_minus_t = N - i; // NOLINT\n            assert(mPolynomialPairs[i].t + mPolynomialPairs[i].one_minus_t == N);\n        }\n    }\n\n    double valueAt(size_t pos, float t) const {\n        assert(pos < size());\n        return mPolynomialPairs[pos].valueAt(t);\n    }\n\n    static constexpr size_t size() {\n        return N + 1;\n    }\n\n    const PolynomialPair& operator[](size_t idx) const {\n        assert(idx < size());\n        return mPolynomialPairs[idx]; // NOLINT\n    }\n\nprivate:\n    PolynomialPair mPolynomialPairs[size()]; // NOLINT\n};\n\nclass Vec2 {\npublic:\n    Vec2() : x(0), y(0) {}\n\n    Vec2(float x, float y) : x(x), y(y) {}\n\n    Vec2(float x, float y, bool normalize) : x(x), y(y) {\n        if (normalize)\n            this->normalize();\n    }\n\n    Vec2(const Vec2& other) : x(other.x), y(other.y) {} // NOLINT\n\n    Vec2(const Vec2& other, bool normalize) : Vec2(other.x, other.y, normalize) {}\n\n    Vec2& operator=(const Vec2& other) = default;\n\n    void set(float x, float y) {\n        this->x = x;\n        this->y = y;\n    }\n\n    void set(const Vec2& other) {\n        this->x = other.x;\n        this->y = other.y;\n    }\n\n    double length() const {\n        return sqrt(x * x + y * y);\n    }\n\n    void normalize() {\n        double len = length();\n        x /= len; // NOLINT\n        y /= len; // NOLINT\n    }\n\n    void translate(float dx, float dy) {\n        x += dx;\n        y += dy;\n    }\n\n    void translate(const Vec2& distance) {\n        x += distance.x;\n        y += distance.y;\n    }\n\n    void rotate(double angle, const Vec2& pivot = Vec2(0, 0)) {\n        double s = sin(angle);\n        double c = cos(angle);\n\n        x -= pivot.x;\n        y -= pivot.y;\n\n        double xnew = x * c - y * s;\n        double ynew = x * s + y * c;\n\n        x = xnew + pivot.x; // NOLINT\n        y = ynew + pivot.y; // NOLINT\n    }\n\n    float angle() const {\n        return atan2(y, x);\n    }\n\n    float angleDeg() const {\n        return angle() * 180.0 / M_PI; // NOLINT\n    }\n\n    float operator[](size_t axis) const {\n        assert(axis < Vec2::size);\n        switch (axis) {\n            case 0:\n                return x;\n            case 1:\n                return y;\n            default:\n                return 0;\n        }\n    }\n\n    float& operator[](size_t axis) {\n        assert(axis < Vec2::size);\n        switch (axis) {\n            case 0:\n                return x;\n            case 1:\n                return y;\n            default:\n                return x;\n        }\n    }\n\n    Vec2 operator+(const Vec2& other) const {\n        return Vec2(x + other.x, y + other.y);\n    }\n\n    Vec2 operator-(const Vec2& other) const {\n        return Vec2(x - other.x, y - other.y);\n    }\n\n    Vec2 operator-() const {\n        return Vec2(-x, -y);\n    }\n\n    Vec2 operator*(double scale) const {\n        return Vec2(x * scale, y * scale); // NOLINT\n    }\n\n    Vec2 operator/(double scale) const {\n        return Vec2(x / scale, y / scale); // NOLINT\n    }\n\n    Vec2 operator/(const Vec2& other) const {\n        return Vec2(x / other.x, y / other.y);\n    }\n\n    bool fuzzyEquals(const Vec2& other) const {\n        bool equals = true;\n        for (size_t axis = 0; axis < Vec2::size; axis++) {\n            if (fabs((*this)[axis] - other[axis]) >= BEZIER_FUZZY_EPSILON) {\n                equals = false;\n                break;\n            }\n        }\n        return equals;\n    }\n\n    bool isWithinZeroAndOne() const {\n        return Math::isWithinZeroAndOne(x) && Math::isWithinZeroAndOne(y);\n    }\n\n    float x;                          // NOLINT\n    float y;                          // NOLINT\n    static constexpr size_t size = 2; // NOLINT\n};\n\ntypedef Vec2 Point;   // NOLINT\ntypedef Vec2 Normal;  // NOLINT\ntypedef Vec2 Tangent; // NOLINT\n\nstruct ExtremeValue {\n    ExtremeValue(float t, size_t axis) : t(t), axis(axis) {}\n\n    bool fuzzyEquals(const ExtremeValue& other) const {\n        return axis == other.axis && fabs(t - other.t) < BEZIER_FUZZY_EPSILON;\n    }\n\n    const float t;\n    const size_t axis;\n};\n\nclass ExtremeValues {\npublic:\n    bool add(float t, size_t axis) {\n        return add(ExtremeValue(t, axis));\n    }\n\n    bool add(const ExtremeValue& val) {\n        assert(Math::isWithinZeroAndOne(val.t));\n        for (auto const& v : values) {\n            if (val.fuzzyEquals(v))\n                return false;\n        }\n        values.push_back(val);\n        return true;\n    }\n\n    size_t size() const {\n        return values.size();\n    }\n\n    ExtremeValue& operator[](size_t idx) {\n        assert(idx < values.size());\n        return values[idx];\n    }\n\n    ExtremeValue operator[](size_t idx) const {\n        assert(idx < values.size());\n        return values[idx];\n    }\n\nprivate:\n    std::vector<ExtremeValue> values; // NOLINT\n};\n\nclass ExtremePoints {\npublic:\n    bool add(float x, float y) {\n        return add(Point(x, y));\n    }\n\n    bool add(const Point& extremePoint) {\n        for (auto const& ep : points) {\n            if (extremePoint.fuzzyEquals(ep))\n                return false;\n        }\n        points.push_back(extremePoint);\n        return true;\n    }\n\n    size_t size() const {\n        return points.size();\n    }\n\n    bool empty() const {\n        return !size(); // NOLINT\n    }\n\n    Point& operator[](size_t idx) {\n        assert(idx < size());\n        return points[idx];\n    }\n\n    Point operator[](size_t idx) const {\n        assert(idx < size());\n        return points[idx];\n    }\n\nprivate:\n    std::vector<Point> points; // NOLINT\n};\n\nclass AxisAlignedBoundingBox {\npublic:\n    AxisAlignedBoundingBox(const Point& p0, const Point& p1, const Point& p2, const Point& p3)\n        : points{{p0}, {p1}, {p2}, {p3}} {}\n\n    AxisAlignedBoundingBox(const ExtremePoints& xPoints) { // NOLINT\n        float minX = std::numeric_limits<float>::max();\n        float maxX = -std::numeric_limits<float>::max();\n        float minY = std::numeric_limits<float>::max();\n        float maxY = -std::numeric_limits<float>::max();\n\n        for (size_t i = 0; i < xPoints.size(); i++) {\n            if (xPoints[i].x > maxX)\n                maxX = xPoints[i].x;\n            if (xPoints[i].x < minX)\n                minX = xPoints[i].x;\n            if (xPoints[i].y > maxY)\n                maxY = xPoints[i].y;\n            if (xPoints[i].y < minY)\n                minY = xPoints[i].y;\n        }\n\n        points[0].set(minX, minY);\n        points[1].set(minX, maxY);\n        points[2].set(maxX, maxY);\n        points[3].set(maxX, minY);\n    }\n\n    static constexpr size_t size() {\n        return 4;\n    }\n\n    float minX() const {\n        return points[0].x;\n    }\n\n    float maxX() const {\n        return points[2].x;\n    }\n\n    float minY() const {\n        return points[0].y;\n    }\n\n    float maxY() const {\n        return points[2].y;\n    }\n\n    float width() const {\n        return maxX() - minX();\n    }\n\n    float height() const {\n        return maxY() - minY();\n    }\n\n    float area() const {\n        return ((double)width() * (double)height()); // NOLINT\n    }\n\n    Point& operator[](size_t idx) {\n        assert(idx < size());\n        return points[idx]; // NOLINT\n    }\n\n    Point operator[](size_t idx) const {\n        assert(idx < size());\n        return points[idx]; // NOLINT\n    }\n\nprivate:\n    // NOLINTNEXTLINE\n    Point points[4]; // Starting in lower left corner, going clock-wise.\n};\n\ntypedef AxisAlignedBoundingBox AABB; // NOLINT\n\nclass TightBoundingBox {\npublic:\n    // Takes the ExtremePoints of the Bezier curve moved to origo and rotated to align the x-axis\n    // as arguments as well as the translation/rotation used to calculate it.\n    TightBoundingBox(const ExtremePoints& xPoints, const Vec2& translation, double rotation) {\n        float minX = std::numeric_limits<float>::max();\n        float maxX = -std::numeric_limits<float>::max();\n        float minY = std::numeric_limits<float>::max();\n        float maxY = -std::numeric_limits<float>::max();\n\n        for (size_t i = 0; i < xPoints.size(); i++) {\n            if (xPoints[i].x > maxX)\n                maxX = xPoints[i].x;\n            if (xPoints[i].x < minX)\n                minX = xPoints[i].x;\n            if (xPoints[i].y > maxY)\n                maxY = xPoints[i].y;\n            if (xPoints[i].y < minY)\n                minY = xPoints[i].y;\n        }\n\n        points[0].set(minX, minY);\n        points[1].set(minX, maxY);\n        points[2].set(maxX, maxY);\n        points[3].set(maxX, minY);\n\n        if (xPoints.empty())\n            return;\n\n        for (size_t i = 0; i < 4; i++) {       // NOLINT\n            points[i].rotate(-rotation);       // NOLINT\n            points[i].translate(-translation); // NOLINT\n        }\n    }\n\n    static constexpr size_t size() {\n        return 4;\n    }\n\n    float minX() const {\n        return std::min({points[0].x, points[1].x, points[2].x, points[3].x});\n    }\n\n    float maxX() const {\n        return std::max({points[0].x, points[1].x, points[2].x, points[3].x});\n    }\n\n    float minY() const {\n        return std::min({points[0].y, points[1].y, points[2].y, points[3].y});\n    }\n\n    float maxY() const {\n        return std::max({points[0].y, points[1].y, points[2].y, points[3].y});\n    }\n\n    float area() const {\n        return width() * height();\n    }\n\n    // Uses the two first points to calculate the \"width\".\n    float width() const {\n        double x = points[1].x - points[0].x;\n        double y = points[1].y - points[0].y;\n        return sqrt(x * x + y * y); // NOLINT\n    }\n\n    // Uses the second and third points to calculate the \"height\".\n    float height() const {\n        double x = points[2].x - points[1].x;\n        double y = points[2].y - points[1].y;\n        return sqrt(x * x + y * y); // NOLINT\n    }\n\n    Point& operator[](size_t idx) {\n        assert(idx < size());\n        return points[idx]; // NOLINT\n    }\n\n    Point operator[](size_t idx) const {\n        assert(idx < size());\n        return points[idx]; // NOLINT\n    }\n\nprivate:\n    // NOLINTNEXTLINE\n    Point points[4]; // The points are ordered in a clockwise manner.\n};\n\ntypedef TightBoundingBox TBB; // NOLINT\n\ntemplate<size_t N> // NOLINT\nclass Bezier {\npublic:\n    Bezier() {\n        for (size_t i = 0; i < N + 1; i++)\n            mControlPoints[i].set(0, 0);\n    }\n\n    Bezier(const std::vector<Point>& controlPoints) { // NOLINT\n        assert(controlPoints.size() ==\n               size()); // The Bezier curve must be initialized with the expected number og points\n        for (size_t i = 0; i < controlPoints.size(); i++)\n            mControlPoints[i] = Point(controlPoints[i]); // NOLINT\n    }\n\n    Bezier(const Bezier<N>& other) {\n        for (size_t i = 0; i < other.size(); i++)\n            mControlPoints[i] = Point(other[i]); // NOLINT\n    }\n\n    // The order of the bezier curve.\n    size_t order() const {\n        return N;\n    }\n\n    // Number of control points.\n    size_t size() const {\n        return N + 1;\n    }\n\n    Bezier<N - 1> derivative() const {\n        assert(N != 0);\n\n        // Note: derivative weights/control points are not actual control points.\n        std::vector<Point> derivativeWeights(N);\n        for (size_t i = 0; i < N; i++)\n            derivativeWeights[i].set(Point((mControlPoints[i + 1] - mControlPoints[i]) * N));\n\n        return Bezier<N - 1>(derivativeWeights);\n    }\n\npublic:\n    double valueAt(float t, size_t axis) const {\n        assert(axis < Vec2::size); // Currently only support 2D\n        double sum = 0;\n        for (size_t n = 0; n < N + 1; n++) {\n            sum += binomialCoefficients[n] * polynomialCoefficients[n].valueAt(t) * mControlPoints[n][axis]; // NOLINT\n        }\n        return sum;\n    }\n\n    Point valueAt(float t) const {\n        Point p;\n        for (size_t i = 0; i < Point::size; i++) {\n            p[i] = (float)valueAt(t, i); // NOLINT\n        }\n        return p;\n    }\n\n    Tangent tangentAt(float t, bool normalize = true) const {\n        Point p;\n        Bezier<N - 1> derivative = this->derivative();\n        p.set(derivative.valueAt(t));\n        if (normalize)\n            p.normalize();\n        return p;\n    }\n\n    Normal normalAt(float t, bool normalize = true) const {\n        Point tangent = tangentAt(t, normalize);\n        return Normal(-tangent.y, tangent.x, normalize);\n    }\n\n    void translate(const Vec2& distance) {\n        for (size_t i = 0; i < N + 1; i++) {\n            mControlPoints[i].translate(distance);\n        }\n    }\n\n    void translate(float dx, float dy) {\n        for (size_t i = 0; i < N + 1; i++) {\n            mControlPoints[i].translate(dx, dy);\n        }\n    }\n\n    void rotate(double angle, Vec2 pivot = Vec2(0, 0)) {\n        for (size_t i = 0; i < N + 1; i++) {\n            mControlPoints[i].rotate(angle, pivot);\n        }\n    }\n\n    ExtremeValues derivativeZero(size_t intervals = BEZIER_DEFAULT_INTERVALS,\n                                 double epsilon = BEZIER_FUZZY_EPSILON,\n                                 size_t maxIterations = BEZIER_DEFAULT_MAX_ITERATIONS) const {\n        switch (N) {\n            case 1:\n                return derivativeZero1();\n            case 2:\n                return derivativeZero2();\n            case 3:\n                //                    return derivativeZero3();\n                return newtonRhapson(intervals, epsilon, maxIterations);\n            default:\n                return newtonRhapson(intervals, epsilon, maxIterations);\n        }\n    }\n\n    ExtremePoints extremePoints() const {\n        ExtremeValues xVals = derivativeZero();\n        xVals.add(0.0f, 0);\n        xVals.add(1.0f, 0);\n\n        ExtremePoints xPoints;\n        for (size_t i = 0; i < xVals.size(); i++)\n            xPoints.add(valueAt(xVals[i].t));\n\n        return xPoints;\n    }\n\n    AxisAlignedBoundingBox aabb() const {\n        return AxisAlignedBoundingBox(extremePoints());\n    }\n\n    AxisAlignedBoundingBox aabb(const ExtremePoints& xPoints) const {\n        return AxisAlignedBoundingBox(xPoints);\n    }\n\n    TightBoundingBox tbb() const {\n        Bezier<N> bezier = *this;\n\n        // Translate last control point (highest order) to origo.\n        Vec2 translation(-bezier[N]);\n        bezier.translate(translation);\n\n        // Rotate bezier to align the first control point (lowest order) with the x-axis\n        double angle = -bezier[0].angle();\n        bezier.rotate(angle);\n\n        return TightBoundingBox(bezier.extremePoints(), translation, angle);\n    }\n\npublic:\n    Point& operator[](size_t idx) {\n        assert(idx < size());\n        return mControlPoints[idx];\n    }\n\n    Point operator[](size_t idx) const {\n        assert(idx < size());\n        return mControlPoints[idx]; // NOLINT\n    }\n\nprivate:\n    ExtremeValues derivativeZero1() const {\n        assert(N == 1);\n        return ExtremeValues();\n    }\n\n    ExtremeValues derivativeZero2() const {\n        assert(N == 2);\n        ExtremeValues xVals;\n        Point roots =\n            (mControlPoints[0] - mControlPoints[1]) / (mControlPoints[0] - mControlPoints[1] * 2 + mControlPoints[2]);\n        if (Math::isWithinZeroAndOne(roots[0]))\n            xVals.add(roots[0], 0);\n        if (Math::isWithinZeroAndOne(roots[1]))\n            xVals.add(roots[1], 1);\n        return xVals;\n    }\n\n    ExtremeValues derivativeZero3() const {\n        // Note: NOT IMPLMENTED YET\n        assert(N == 3);\n        return ExtremeValues();\n    }\n\n    ExtremeValues newtonRhapson(size_t intervals = BEZIER_DEFAULT_INTERVALS,\n                                double epsilon = BEZIER_FUZZY_EPSILON,\n                                size_t maxIterations = BEZIER_DEFAULT_MAX_ITERATIONS) const {\n        assert(N >= 2);\n        ExtremeValues xVals;\n        const double dt = 1.0 / (double)intervals; // NOLINT\n        const double absEpsilon = fabs(epsilon);\n        const Bezier<N - 1> db = derivative();\n        const Bezier<N - 2> ddb = db.derivative();\n\n        for (size_t i = 0; i < Point::size; i++) {\n            double t = 0;\n\n            while (t <= 1.0) {\n                double zeroVal = t;\n                size_t current_iter = 0; // NOLINT\n\n                while (current_iter < maxIterations) {\n                    double dbVal = db.valueAt(zeroVal, i);\n                    double ddbVal = ddb.valueAt(zeroVal, i);\n                    double nextZeroVal = zeroVal - (dbVal / ddbVal);\n\n                    if (fabs(nextZeroVal - zeroVal) < absEpsilon) {\n                        if (Math::isWithinZeroAndOne(nextZeroVal)) { // NOLINT\n                            xVals.add(nextZeroVal, i);               // NOLINT\n                            break;\n                        }\n                    }\n\n                    zeroVal = nextZeroVal;\n                    current_iter++;\n                }\n\n                t += dt;\n            }\n        }\n\n        return xVals;\n    }\n\npublic:\n    static const BinomialCoefficients<N> binomialCoefficients;     // NOLINT\n    static const PolynomialCoefficients<N> polynomialCoefficients; // NOLINT\n\nprivate:\n    Point mControlPoints[N + 1]; // NOLINT\n};\n\ntemplate<size_t N>                                                                         // NOLINT\nconst BinomialCoefficients<N> Bezier<N>::binomialCoefficients = BinomialCoefficients<N>(); // NOLINT\n\ntemplate<size_t N>                                                                               // NOLINT\nconst PolynomialCoefficients<N> Bezier<N>::polynomialCoefficients = PolynomialCoefficients<N>(); // NOLINT\n\n} // namespace Bezier\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/BlendMode.cpp",
    "content": "//\n//  BlendMode.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/25/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/BlendMode.hpp\"\n#include \"include/core/SkBlendMode.h\"\n\nnamespace snap::drawing {\n\nSkBlendMode toSkBlendMode(BlendMode blendMode) {\n    switch (blendMode) {\n        case BlendModeClear:\n            return SkBlendMode::kClear;\n        case BlendModeSrc:\n            return SkBlendMode::kSrc;\n        case BlendModeDst:\n            return SkBlendMode::kDst;\n        case BlendModeSrcOver:\n            return SkBlendMode::kSrcOver;\n        case BlendModeDstOver:\n            return SkBlendMode::kDstOver;\n        case BlendModeSrcIn:\n            return SkBlendMode::kSrcIn;\n        case BlendModeDstIn:\n            return SkBlendMode::kDstIn;\n        case BlendModeSrcOut:\n            return SkBlendMode::kSrcOut;\n        case BlendModeDstOut:\n            return SkBlendMode::kDstOut;\n        case BlendModeSrcATop:\n            return SkBlendMode::kSrcATop;\n        case BlendModeDstATop:\n            return SkBlendMode::kDstATop;\n        case BlendModeXor:\n            return SkBlendMode::kXor;\n        case BlendModePlus:\n            return SkBlendMode::kPlus;\n        case BlendModeModulate:\n            return SkBlendMode::kModulate;\n        case BlendModeScreen:\n            return SkBlendMode::kScreen;\n        case BlendModeLastCoeffMode:\n            return SkBlendMode::kLastCoeffMode;\n        case BlendModeOverlay:\n            return SkBlendMode::kOverlay;\n        case BlendModeDarken:\n            return SkBlendMode::kDarken;\n        case BlendModeLighten:\n            return SkBlendMode::kLighten;\n        case BlendModeColorDodge:\n            return SkBlendMode::kColorDodge;\n        case BlendModeColorBurn:\n            return SkBlendMode::kColorBurn;\n        case BlendModeHardLight:\n            return SkBlendMode::kHardLight;\n        case BlendModeSoftLight:\n            return SkBlendMode::kSoftLight;\n        case BlendModeDifference:\n            return SkBlendMode::kDifference;\n        case BlendModeExclusion:\n            return SkBlendMode::kExclusion;\n        case BlendModeMultiply:\n            return SkBlendMode::kMultiply;\n        case BlendModeLastSeparableMode:\n            return SkBlendMode::kLastSeparableMode;\n        case BlendModeHue:\n            return SkBlendMode::kHue;\n        case BlendModeSaturation:\n            return SkBlendMode::kSaturation;\n        case BlendModeColor:\n            return SkBlendMode::kColor;\n        case BlendModeLuminosity:\n            return SkBlendMode::kLuminosity;\n    }\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/BlendMode.hpp",
    "content": "//\n//  BlendMode.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/25/22.\n//\n\n#pragma once\n\n#include \"include/core/SkBlendMode.h\"\n\nnamespace snap::drawing {\n\nenum BlendMode {\n    BlendModeClear,             //!< replaces destination with zero: fully transparent\n    BlendModeSrc,               //!< replaces destination\n    BlendModeDst,               //!< preserves destination\n    BlendModeSrcOver,           //!< source over destination\n    BlendModeDstOver,           //!< destination over source\n    BlendModeSrcIn,             //!< source trimmed inside destination\n    BlendModeDstIn,             //!< destination trimmed by source\n    BlendModeSrcOut,            //!< source trimmed outside destination\n    BlendModeDstOut,            //!< destination trimmed outside source\n    BlendModeSrcATop,           //!< source inside destination blended with destination\n    BlendModeDstATop,           //!< destination inside source blended with source\n    BlendModeXor,               //!< each of source and destination trimmed outside the other\n    BlendModePlus,              //!< sum of colors\n    BlendModeModulate,          //!< product of premultiplied colors; darkens destination\n    BlendModeScreen,            //!< multiply inverse of pixels, inverting result; brightens destination\n    BlendModeLastCoeffMode,     //!< last porter duff blend mode\n    BlendModeOverlay,           //!< multiply or screen, depending on destination\n    BlendModeDarken,            //!< darker of source and destination\n    BlendModeLighten,           //!< lighter of source and destination\n    BlendModeColorDodge,        //!< brighten destination to reflect source\n    BlendModeColorBurn,         //!< darken destination to reflect source\n    BlendModeHardLight,         //!< multiply or screen, depending on source\n    BlendModeSoftLight,         //!< lighten or darken, depending on source\n    BlendModeDifference,        //!< subtract darker from lighter with higher contrast\n    BlendModeExclusion,         //!< subtract darker from lighter with lower contrast\n    BlendModeMultiply,          //!< multiply source with destination, darkening image\n    BlendModeLastSeparableMode, //!< last blend mode operating separately on components\n    BlendModeHue,               //!< hue of source with saturation and luminosity of destination\n    BlendModeSaturation,        //!< saturation of source with hue and luminosity of destination\n    BlendModeColor,             //!< hue and saturation of source with luminosity of destination\n    BlendModeLuminosity,        //!< luminosity of source with hue and saturation of destination\n};\n\nSkBlendMode toSkBlendMode(BlendMode blendMode);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/BoxShadow.cpp",
    "content": "//\n//  BoxShadow.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/8/20.\n//\n\n#include \"snap_drawing/cpp/Drawing/BoxShadow.hpp\"\n\n#include \"include/core/SkBlurTypes.h\"\n#include \"include/core/SkMaskFilter.h\"\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n\nnamespace snap::drawing {\n\nBoxShadow::BoxShadow() = default;\n\nBoxShadow::~BoxShadow() = default;\n\nvoid BoxShadow::setOffset(Size offset) {\n    _offset = offset;\n}\n\nvoid BoxShadow::setBlurAmount(Scalar blurAmount) {\n    if (_blurAmount != blurAmount) {\n        _blurAmount = blurAmount;\n        if (blurAmount == 0) {\n            _paint.getSkValue().setMaskFilter(nullptr);\n        } else {\n            _paint.getSkValue().setMaskFilter(SkMaskFilter::MakeBlur(SkBlurStyle::kNormal_SkBlurStyle, blurAmount * 2));\n        }\n    }\n}\n\nvoid BoxShadow::setColor(Color color) {\n    _color = color;\n\n    _paint.setColor(color);\n}\n\nvoid BoxShadow::draw(DrawingContext& drawingContext, const BorderRadius& borderRadius) {\n    auto drawBounds = drawingContext.drawBounds().makeOffset(_offset.width, _offset.height);\n\n    drawingContext.drawPaint(_paint, borderRadius, drawBounds, _lazyPath);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/BoxShadow.hpp",
    "content": "//\n//  BoxShadow.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/8/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/LazyPath.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n\nnamespace snap::drawing {\n\nclass BorderRadius;\n\nclass BoxShadow : public Valdi::SimpleRefCountable {\npublic:\n    BoxShadow();\n    ~BoxShadow() override;\n\n    void setOffset(Size offset);\n    void setColor(Color color);\n    void setBlurAmount(Scalar blurAmount);\n\n    void draw(DrawingContext& drawingContext, const BorderRadius& borderRadius);\n\nprivate:\n    Size _offset = Size::makeEmpty();\n    Color _color = Color::transparent();\n    Scalar _blurAmount = 0;\n    Paint _paint;\n    LazyPath _lazyPath;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/CompositionState.cpp",
    "content": "#include \"CompositionState.hpp\"\n\nnamespace snap::drawing {\n\nCompositionState::CompositionState() = default;\n\nCompositionState::CompositionState(const Path& clipPath, const Matrix& resolvedMatrix, Scalar resolvedOpacity)\n    : _absoluteClipPath(clipPath), _absoluteMatrix(resolvedMatrix), _absoluteOpacity(resolvedOpacity) {}\n\nCompositionState::~CompositionState() = default;\n\nCompositionState CompositionState::pushContext(Scalar opacity, const Matrix& matrix) {\n    auto newOpacity = _absoluteOpacity * opacity;\n    auto newMatrix = _absoluteMatrix;\n    newMatrix.preConcat(matrix);\n\n    return CompositionState(_absoluteClipPath, newMatrix, newOpacity);\n}\n\nvoid CompositionState::clipRect(Scalar width, Scalar height) {\n    Path clipPath;\n    clipPath.addRect(Rect::makeLTRB(0, 0, width, height), true);\n    updateClip(clipPath);\n}\n\nvoid CompositionState::clipRound(const BorderRadius& borderRadius, Scalar width, Scalar height) {\n    auto clipPath = borderRadius.getPath(Rect::makeLTRB(0, 0, width, height));\n    updateClip(clipPath);\n}\n\nvoid CompositionState::updateClip(Path& path) {\n    path.transform(_absoluteMatrix);\n\n    if (_absoluteClipPath.isEmpty()) {\n        _absoluteClipPath = std::move(path);\n    } else {\n        _absoluteClipPath = _absoluteClipPath.intersection(path);\n    }\n}\n\nSkScalar CompositionState::getAbsoluteOpacity() const {\n    return _absoluteOpacity;\n}\n\nconst Matrix& CompositionState::getAbsoluteMatrix() const {\n    return _absoluteMatrix;\n}\n\nconst Path& CompositionState::getAbsoluteClipPath() const {\n    return _absoluteClipPath;\n}\n\nRect CompositionState::getAbsoluteRect(const Rect& localRect) const {\n    return _absoluteMatrix.mapRect(localRect);\n}\n\nRect CompositionState::getAbsoluteClippedRect(const Rect& localRect) const {\n    auto absoluteRect = getAbsoluteRect(localRect);\n    auto clipBounds = _absoluteClipPath.getBounds();\n\n    if (clipBounds) {\n        return clipBounds.value().intersection(absoluteRect);\n    } else {\n        return absoluteRect;\n    }\n}\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/CompositionState.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n\nnamespace snap::drawing {\n\n/**\nCompositionState helps with resolving absolute opacity, transform matrix and clip path inside a DisplayList.\nSince each pushContext operation within the DisplayList is relative to the parent context, CompositionState helps\nwith resolving the absolute values for properties that are relevant for composition.\n */\nclass CompositionState {\npublic:\n    CompositionState();\n    CompositionState(const Path& clipPath, const Matrix& resolvedMatrix, Scalar resolvedOpacity);\n    ~CompositionState();\n\n    CompositionState pushContext(Scalar opacity, const Matrix& matrix);\n\n    void clipRect(Scalar width, Scalar height);\n    void clipRound(const BorderRadius& borderRadius, Scalar width, Scalar height);\n\n    SkScalar getAbsoluteOpacity() const;\n    const Matrix& getAbsoluteMatrix() const;\n    const Path& getAbsoluteClipPath() const;\n\n    Rect getAbsoluteRect(const Rect& localRect) const;\n    Rect getAbsoluteClippedRect(const Rect& localRect) const;\n\nprivate:\n    // The absolute clip path in this context\n    Path _absoluteClipPath;\n    // The absolute matrix which can be used to transform from relative coordinates\n    // from within this context into absolute.\n    Matrix _absoluteMatrix;\n    // The absolute opacity, taking in account the opacity of this context and\n    // all contexts above it.\n    Scalar _absoluteOpacity = 1.0;\n\n    void updateClip(Path& path);\n};\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/Compositor.cpp",
    "content": "//\n//  Compositor.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/1/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Composition/Compositor.hpp\"\n#include \"CompositionState.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlane.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlaneList.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/ResolvedPlane.hpp\"\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"utils/debugging/Assert.hpp\"\n\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n\nnamespace snap::drawing {\n\n// Since we use a bitmask for the presence field in order to remain efficient,\n// we support a maximum of 64 composited planes.\nconstexpr size_t kMaxSurfacesCount = sizeof(uint64_t) * 8;\n\n// Represents a pushContext operation inside a DisplayList on which\n// the clipRect, matrix and opacity have been resolved\nstruct VisitedContext {\n    // Bitmask that tells which planes have this pushContext\n    // operation been inserted into.\n    uint64_t planePresenceField = 0;\n    CompositionState compositionState;\n    // The original pushContext operation from which this VisitedContext comes from\n    const Operations::PushContext* pushContext;\n    // The last clipping operation that has been set\n    const Operations::ClipOperation* clipOperation = nullptr;\n\n    inline VisitedContext(CompositionState&& compositionState, const Operations::PushContext* pushContext)\n        : compositionState(std::move(compositionState)), pushContext(pushContext) {}\n\n    template<typename F>\n    inline void forEachPlaneIndex(F&& fn) {\n        auto planePresenceField = this->planePresenceField;\n\n        while (planePresenceField != 0) {\n            // ctzl counts the number of zeroes before the first non zero bit,\n            // which here tells us the planeIndex.\n            // Can be replaced by std::countr_one once we compile using C++20\n            auto planeIndex = static_cast<uint64_t>(__builtin_ctzll(planePresenceField));\n            uint64_t t = planePresenceField & -planePresenceField;\n            planePresenceField ^= t;\n            fn(planeIndex);\n        }\n    }\n};\n\nstruct SubmittedPrepareMask {\n    IMask* mask;\n    uint64_t planeIndex;\n\n    SubmittedPrepareMask(IMask* mask, uint64_t planeIndex) : mask(mask), planeIndex(planeIndex) {}\n};\n\nclass PopulatePlanesVisitor {\npublic:\n    PopulatePlanesVisitor(DisplayList& displayList, Valdi::ILogger& logger)\n        : _displayList(displayList),\n          _displayListFrame(0, 0, displayList.getSize().width, displayList.getSize().height),\n          _logger(logger) {\n        appendContext(CompositionState(), nullptr);\n    }\n\n    void visit(const Operations::PushContext& pushContext) {\n        auto& topContext = getCurrentContext();\n\n        appendContext(topContext.compositionState.pushContext(pushContext.opacity, pushContext.matrix), &pushContext);\n    }\n\n    void visit(const Operations::PopContext& /*popContext*/) {\n        auto& topContext = getCurrentContext();\n\n        topContext.forEachPlaneIndex([&](uint64_t planeIndex) {\n            setCurrentPlaneIndex(planeIndex);\n            _displayList.popContext();\n        });\n\n        _visitedContexts.pop_back();\n    }\n\n    void visit(const Operations::ClipRect& clipRect) {\n        auto& currentContext = getCurrentContext();\n\n        currentContext.compositionState.clipRect(clipRect.width, clipRect.height);\n\n        onClipUpdated(currentContext, clipRect);\n    }\n\n    void visit(const Operations::ClipRound& clipRound) {\n        auto& currentContext = getCurrentContext();\n\n        currentContext.compositionState.clipRound(clipRound.borderRadius, clipRound.width, clipRound.height);\n\n        onClipUpdated(currentContext, clipRound);\n    }\n\n    void visit(const Operations::DrawPicture& drawPicture) {\n        auto absoluteClippedPictureRect =\n            resolveAbsoluteClippedRect(fromSkValue<Rect>(drawPicture.picture->cullRect()));\n\n        auto& resolvedPlane = resolveRegularPlane(absoluteClippedPictureRect);\n        appendDrawPictureToPlane(drawPicture, absoluteClippedPictureRect, resolvedPlane);\n    }\n\n    void visit(const Operations::DrawExternalSurface& drawExternalSurface) {\n        auto& current = getCurrentContext();\n\n        auto& externalSurface = drawExternalSurface.externalSurfaceSnapshot->getExternalSurface();\n\n        auto externalSurfaceRect =\n            Rect::makeXYWH(0, 0, externalSurface->getRelativeSize().width, externalSurface->getRelativeSize().height);\n\n        auto absoluteOpacity = drawExternalSurface.opacity * current.compositionState.getAbsoluteOpacity();\n        auto absoluteSurfaceRect = current.compositionState.getAbsoluteRect(externalSurfaceRect);\n\n        appendExternalPlane(drawExternalSurface.externalSurfaceSnapshot,\n                            current.compositionState.getAbsoluteMatrix(),\n                            current.compositionState.getAbsoluteClipPath(),\n                            absoluteOpacity,\n                            absoluteSurfaceRect);\n    }\n\n    void visit(const Operations::PrepareMask& prepareMask) {\n        auto absoluteClippedRect = resolveAbsoluteClippedRect(prepareMask.mask->getBounds());\n\n        auto& resolvedPlane = resolveRegularPlane(absoluteClippedRect);\n\n        resolvedPlane.bbox->insert(absoluteClippedRect);\n\n        syncDisplayListWithPlaneIfNeeded(resolvedPlane);\n        _displayList.appendPrepareMask(prepareMask.mask);\n\n        _submittedPrepareMasks.emplace_back(prepareMask.mask, resolvedPlane.planeIndex);\n    }\n\n    void visit(const Operations::ApplyMask& applyMask) {\n        auto index = _submittedPrepareMasks.size();\n        while (index > 0) {\n            index--;\n            auto& it = _submittedPrepareMasks[index];\n\n            if (it.mask == applyMask.mask) {\n                setCurrentPlaneIndex(it.planeIndex);\n                _displayList.appendApplyMask(applyMask.mask);\n                _submittedPrepareMasks.erase(_submittedPrepareMasks.begin() + index);\n                return;\n            }\n        }\n    }\n\n    const Valdi::SmallVector<ResolvedPlane, 2>& getResolvedPlanes() const {\n        return _resolvedPlanes;\n    }\n\nprivate:\n    [[maybe_unused]] DisplayList& _displayList;\n    Rect _displayListFrame;\n    [[maybe_unused]] Valdi::ILogger& _logger;\n    Valdi::SmallVector<VisitedContext, 8> _visitedContexts;\n    Valdi::SmallVector<ResolvedPlane, 2> _resolvedPlanes;\n    Valdi::SmallVector<SubmittedPrepareMask, 2> _submittedPrepareMasks;\n    std::vector<int> _bboxSearchResult;\n    uint64_t _planeIndexSequence = 0;\n    uint64_t _currentDisplayListPlaneIndex = 0;\n\n    Rect resolveAbsoluteClippedRect(const Rect& relativeRect) {\n        return getCurrentContext().compositionState.getAbsoluteClippedRect(relativeRect);\n    }\n\n    void onClipUpdated(VisitedContext& currentContext, const Operations::ClipOperation& clipOperation) {\n        currentContext.clipOperation = &clipOperation;\n\n        if (currentContext.planePresenceField != 0) {\n            // If our context was already inserted into a plane,\n            // we need to update the new clip for those planes\n            syncClipWithPlanes(currentContext);\n        }\n    }\n\n    VisitedContext& getCurrentContext() {\n        return _visitedContexts[_visitedContexts.size() - 1];\n    }\n\n    void appendContext(CompositionState&& compositionState, const Operations::PushContext* pushContext) {\n        _visitedContexts.emplace_back(std::move(compositionState), pushContext);\n    }\n\n    void appendDrawPictureToPlane(const Operations::DrawPicture& drawPicture,\n                                  const Rect& frame,\n                                  ResolvedRegularPlane& plane) {\n        plane.bbox->insert(frame);\n\n        syncDisplayListWithPlaneIfNeeded(plane);\n        _displayList.appendPicture(drawPicture.picture, drawPicture.opacity);\n    }\n\n    void setCurrentPlaneIndex(uint64_t planeIndex) {\n        if (_currentDisplayListPlaneIndex != planeIndex) {\n            _displayList.setCurrentPlane(static_cast<size_t>(planeIndex));\n            _currentDisplayListPlaneIndex = planeIndex;\n        }\n    }\n\n    std::pair<VisitedContext*, VisitedContext*> findContextsToPush(ResolvedRegularPlane& plane) {\n        auto planeBit = static_cast<uint64_t>(1) << plane.planeIndex;\n\n        auto visitedContextsSize = _visitedContexts.size();\n\n        VisitedContext* begin = _visitedContexts.data() + visitedContextsSize;\n        VisitedContext* end = begin;\n\n        auto i = visitedContextsSize;\n\n        while (i > 1 /* The index at 0 is a placeholder */) {\n            i--;\n\n            auto& pushContext = _visitedContexts[i];\n\n            if ((pushContext.planePresenceField & planeBit) == 0) {\n                // Push operation has not been recorded in the DisplayList for that plane\n                pushContext.planePresenceField |= planeBit;\n                begin = &pushContext;\n            } else {\n                break;\n            }\n        }\n\n        return std::make_pair(begin, end);\n    }\n\n    void syncClipWithPlanes(VisitedContext& pushContext) {\n        pushContext.forEachPlaneIndex([&](uint64_t planeIndex) {\n            setCurrentPlaneIndex(planeIndex);\n            appendClipOperation(pushContext);\n        });\n    }\n\n    void appendClipOperation(VisitedContext& pushContext) {\n        if (pushContext.clipOperation->type == Operations::ClipRound::kId) {\n            const auto& borderRadius =\n                reinterpret_cast<const Operations::ClipRound*>(pushContext.clipOperation)->borderRadius;\n            _displayList.appendClipRound(\n                borderRadius, pushContext.clipOperation->width, pushContext.clipOperation->height);\n        } else {\n            _displayList.appendClipRect(pushContext.clipOperation->width, pushContext.clipOperation->height);\n        }\n    }\n\n    void syncDisplayListWithPlaneIfNeeded(ResolvedRegularPlane& plane) {\n        setCurrentPlaneIndex(plane.planeIndex);\n\n        auto iterator = findContextsToPush(plane);\n\n        auto* it = iterator.first;\n        while (it != iterator.second) {\n            auto& pushContext = *it;\n\n            _displayList.pushContext(pushContext.pushContext->matrix,\n                                     pushContext.pushContext->opacity,\n                                     pushContext.pushContext->layerId,\n                                     pushContext.pushContext->hasUpdates);\n\n            if (pushContext.clipOperation != nullptr) {\n                appendClipOperation(pushContext);\n            }\n\n            it++;\n        }\n    }\n\n    ResolvedPlane& getTopPlane() {\n        return _resolvedPlanes[_resolvedPlanes.size() - 1];\n    }\n\n    ResolvedRegularPlane& appendRegularPlane() {\n        auto planeIndex = _planeIndexSequence++;\n\n        while (static_cast<size_t>(planeIndex) >= _displayList.getPlanesCount()) {\n            _displayList.appendPlane();\n            _currentDisplayListPlaneIndex = planeIndex;\n        }\n\n        auto& plane = _resolvedPlanes.emplace_back(planeIndex, Valdi::makeShared<BoundingBoxHierarchy>());\n        return *plane.getRegular();\n    }\n\n    size_t resolveExternalPlaneInsertionIndex(const Rect& absoluteFrame) {\n        auto planesCount = _resolvedPlanes.size();\n        auto bestInsertionIndex = planesCount;\n\n        size_t i = planesCount;\n        while (i > 0) {\n            i--;\n            auto& plane = _resolvedPlanes[i];\n\n            auto* regularPlane = plane.getRegular();\n            if (regularPlane != nullptr) {\n                if (regularPlane->bbox->contains(absoluteFrame)) {\n                    break;\n                } else {\n                    bestInsertionIndex = i;\n                }\n            } else {\n                break;\n            }\n        }\n\n        return bestInsertionIndex;\n    }\n\n    ResolvedExternalPlane& appendExternalPlane(ExternalSurfaceSnapshot* externalSurfaceSnapshot,\n                                               const Matrix& transform,\n                                               const Path& clipPath,\n                                               Scalar opacity,\n                                               const Rect& absoluteFrame) {\n        auto insertionIndex = resolveExternalPlaneInsertionIndex(absoluteFrame);\n        auto it = _resolvedPlanes.emplace(_resolvedPlanes.begin() + insertionIndex,\n                                          externalSurfaceSnapshot,\n                                          transform,\n                                          clipPath,\n                                          opacity,\n                                          absoluteFrame);\n        return *it->getExternal();\n    }\n\n    ResolvedRegularPlane* getTopRegularPlane() {\n        size_t index = _resolvedPlanes.size();\n        while (index > 0) {\n            index--;\n\n            auto& plane = _resolvedPlanes[index];\n            auto* regularPlane = plane.getRegular();\n            if (regularPlane != nullptr) {\n                return regularPlane;\n            }\n        }\n\n        return nullptr;\n    }\n\n    ResolvedRegularPlane& resolveRegularPlane(const Rect& absoluteFrame) {\n        ResolvedRegularPlane* bestPlane = nullptr;\n\n        // The algorithm goes from top plane to bottom, and finds the lowest plane\n        // that is not an external plane and can host the given frame.\n\n        size_t index = _resolvedPlanes.size();\n        while (index > 0) {\n            index--;\n\n            auto& plane = _resolvedPlanes[index];\n\n            auto* externalSurface = plane.getExternal();\n\n            if (externalSurface != nullptr) {\n                if (externalSurface->absoluteFrame.intersects(absoluteFrame)) {\n                    // We are intersecting with an external plane.\n                    // Stop the search to decide whether to use a plane\n                    // above us or append a new one\n                    break;\n                }\n            } else {\n                if (bestPlane != nullptr && bestPlane->bbox->contains(absoluteFrame)) {\n                    // A plane has already some things that intersects with our frame.\n                    // We can't use a lower plane than this one\n                    break;\n                }\n                bestPlane = plane.getRegular();\n            }\n        }\n\n        if (bestPlane != nullptr) {\n            return *bestPlane;\n        }\n\n        if (_planeIndexSequence < kMaxSurfacesCount) {\n            return appendRegularPlane();\n        }\n\n        // Cannot create more planes, we fallback on re-using the top one\n        auto* topPlane = getTopRegularPlane();\n        SC_ASSERT_NOTNULL(topPlane);\n        return *topPlane;\n    }\n};\n\nCompositor::Compositor(Valdi::ILogger& logger) : _logger(logger) {}\n\nRef<DisplayList> Compositor::performComposition(DisplayList& sourceDisplayList, CompositorPlaneList& planeList) {\n    if (!sourceDisplayList.hasExternalSurfaces()) {\n        planeList.appendDrawableSurface();\n        return Ref<DisplayList>(&sourceDisplayList);\n    }\n\n    VALDI_TRACE(\"SnapDrawing.performComposition\");\n\n    auto outputDisplayList =\n        Valdi::makeShared<DisplayList>(sourceDisplayList.getSize(), sourceDisplayList.getFrameTime());\n\n    PopulatePlanesVisitor visitor(*outputDisplayList, _logger);\n    sourceDisplayList.visitOperations(kDisplayListAllPlaneIndexes, visitor);\n\n    for (const auto& plane : visitor.getResolvedPlanes()) {\n        const auto* resolvedExternalSurface = plane.getExternal();\n        if (resolvedExternalSurface != nullptr) {\n            planeList.appendPlane(\n                CompositorPlane(Ref<ExternalSurfaceSnapshot>(resolvedExternalSurface->externalSurface),\n                                resolvedExternalSurface->resolveDisplayState()));\n        } else {\n            planeList.appendDrawableSurface();\n        }\n    }\n\n    return outputDisplayList;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/Compositor.hpp",
    "content": "//\n//  Compositor.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/1/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\nnamespace Valdi {\nclass ILogger;\n}\n\nnamespace snap::drawing {\n\nclass CompositorPlaneList;\n\n/**\n The Compositor finds how many surfaces need to be used in order to draw a DisplayList.\n If the DisplayList has 1 or more external surfaces, it will split up the DisplayList\n into surfaces such that the external surfaces can be drawn at the right location and opacity\n by an external system. Regular surfaces are then laid out above or below the external\n surfaces depending on what they should drawn. The Compositor tries to limit the number\n of regular surfaces to use as much as possible. It does this by calculating the intersections\n of the draw commands to see if they intersects with external surfaces.\n */\nclass Compositor {\npublic:\n    explicit Compositor(Valdi::ILogger& logger);\n\n    Ref<DisplayList> performComposition(DisplayList& sourceDisplayList, CompositorPlaneList& planeList);\n\nprivate:\n    [[maybe_unused]] Valdi::ILogger& _logger;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/CompositorPlane.cpp",
    "content": "//\n//  CompositorPlane.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlane.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n\nnamespace snap::drawing {\n\nCompositorPlane::CompositorPlane(const Ref<ExternalSurfaceSnapshot>& externalSurfaceSnapshot,\n                                 const ExternalSurfacePresenterState& presenterState)\n    : _externalSurfaceSnapshot(externalSurfaceSnapshot), _externalSurfacePresenterState(presenterState) {}\nCompositorPlane::CompositorPlane(const Ref<DrawableSurface>& drawableSurface) : _drawableSurface(drawableSurface) {}\n\nCompositorPlane::CompositorPlane(CompositorPlane&& other)\n    : _drawableSurface(std::move(other._drawableSurface)),\n      _externalSurfaceSnapshot(std::move(other._externalSurfaceSnapshot)),\n      _externalSurfacePresenterState(std::move(other._externalSurfacePresenterState)) {}\n\nCompositorPlane::CompositorPlane(const CompositorPlane& other)\n    : _drawableSurface(other._drawableSurface),\n      _externalSurfaceSnapshot(other._externalSurfaceSnapshot),\n      _externalSurfacePresenterState(other._externalSurfacePresenterState) {}\n\nCompositorPlane::~CompositorPlane() = default;\n\nCompositorPlaneType CompositorPlane::getType() const {\n    if (getExternalSurfaceSnapshot() == nullptr) {\n        return CompositorPlaneTypeDrawable;\n    } else {\n        return CompositorPlaneTypeExternal;\n    }\n}\n\nDrawableSurface* CompositorPlane::getDrawableSurface() const {\n    return _drawableSurface.get();\n}\n\nExternalSurfaceSnapshot* CompositorPlane::getExternalSurfaceSnapshot() const {\n    return _externalSurfaceSnapshot.get();\n}\n\nExternalSurface* CompositorPlane::getExternalSurface() const {\n    if (_externalSurfaceSnapshot == nullptr) {\n        return nullptr;\n    }\n    return _externalSurfaceSnapshot->getExternalSurface().get();\n}\n\nconst ExternalSurfacePresenterState* CompositorPlane::getExternalSurfacePresenterState() const {\n    if (getExternalSurfaceSnapshot() == nullptr) {\n        return nullptr;\n    }\n    return &_externalSurfacePresenterState;\n}\n\nExternalSurfacePresenterState* CompositorPlane::getExternalSurfacePresenterState() {\n    if (getExternalSurfaceSnapshot() == nullptr) {\n        return nullptr;\n    }\n    return &_externalSurfacePresenterState;\n}\n\nCompositorPlane& CompositorPlane::operator=(CompositorPlane&& other) {\n    _externalSurfaceSnapshot = std::move(other._externalSurfaceSnapshot);\n    _drawableSurface = std::move(other._drawableSurface);\n    _externalSurfacePresenterState = std::move(other._externalSurfacePresenterState);\n    return *this;\n}\n\nCompositorPlane& CompositorPlane::operator=(const CompositorPlane& other) {\n    _externalSurfaceSnapshot = other._externalSurfaceSnapshot;\n    _drawableSurface = other._drawableSurface;\n    _externalSurfacePresenterState = other._externalSurfacePresenterState;\n    return *this;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/CompositorPlane.hpp",
    "content": "//\n//  CompositorPlane.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp\"\n\nnamespace snap::drawing {\n\nclass ExternalSurfaceSnapshot;\nclass DrawableSurface;\nclass ExternalSurface;\n\nenum CompositorPlaneType { CompositorPlaneTypeDrawable, CompositorPlaneTypeExternal };\n\nclass CompositorPlane {\npublic:\n    CompositorPlane(const Ref<ExternalSurfaceSnapshot>& externalSurface,\n                    const ExternalSurfacePresenterState& presenterState);\n    explicit CompositorPlane(const Ref<DrawableSurface>& drawableSurface);\n    CompositorPlane(CompositorPlane&& other);\n    CompositorPlane(const CompositorPlane& other);\n    ~CompositorPlane();\n\n    CompositorPlaneType getType() const;\n\n    DrawableSurface* getDrawableSurface() const;\n    ExternalSurfaceSnapshot* getExternalSurfaceSnapshot() const;\n    ExternalSurface* getExternalSurface() const;\n\n    const ExternalSurfacePresenterState* getExternalSurfacePresenterState() const;\n    ExternalSurfacePresenterState* getExternalSurfacePresenterState();\n\n    CompositorPlane& operator=(CompositorPlane&& other);\n    CompositorPlane& operator=(const CompositorPlane& other);\n\nprivate:\n    Ref<DrawableSurface> _drawableSurface;\n    Ref<ExternalSurfaceSnapshot> _externalSurfaceSnapshot;\n    ExternalSurfacePresenterState _externalSurfacePresenterState;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/CompositorPlaneList.cpp",
    "content": "//\n//  CompositorPlaneList.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlaneList.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n\nnamespace snap::drawing {\n\nCompositorPlaneList::CompositorPlaneList() = default;\n\nCompositorPlaneList::~CompositorPlaneList() = default;\n\nsize_t CompositorPlaneList::getPlanesCount() const {\n    return _planes.size();\n}\n\nconst CompositorPlane& CompositorPlaneList::getPlaneAtIndex(size_t index) const {\n    return _planes[index];\n}\n\nCompositorPlane& CompositorPlaneList::getPlaneAtIndex(size_t index) {\n    return _planes[index];\n}\n\nvoid CompositorPlaneList::appendPlane(CompositorPlane&& plane) {\n    _planes.emplace_back(plane);\n}\n\nvoid CompositorPlaneList::appendDrawableSurface() {\n    appendPlane(CompositorPlane(nullptr));\n}\n\nvoid CompositorPlaneList::insertPlane(CompositorPlane&& plane, size_t index) {\n    _planes.insert(_planes.begin() + index, std::move(plane));\n}\n\nvoid CompositorPlaneList::removePlaneAtIndex(size_t index) {\n    _planes.erase(_planes.begin() + index);\n}\n\nvoid CompositorPlaneList::clear() {\n    _planes.clear();\n}\n\nconst CompositorPlane* CompositorPlaneList::begin() const {\n    return _planes.data();\n}\n\nconst CompositorPlane* CompositorPlaneList::end() const {\n    return _planes.data() + _planes.size();\n}\n\nCompositorPlane* CompositorPlaneList::begin() {\n    return _planes.data();\n}\n\nCompositorPlane* CompositorPlaneList::end() {\n    return _planes.data() + _planes.size();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/CompositorPlaneList.hpp",
    "content": "//\n//  CompositorPlaneList.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlane.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\nnamespace snap::drawing {\n\nclass CompositorPlaneList {\npublic:\n    CompositorPlaneList();\n    ~CompositorPlaneList();\n\n    size_t getPlanesCount() const;\n    const CompositorPlane& getPlaneAtIndex(size_t index) const;\n    CompositorPlane& getPlaneAtIndex(size_t index);\n\n    void appendPlane(CompositorPlane&& plane);\n    void appendDrawableSurface();\n    void insertPlane(CompositorPlane&& plane, size_t index);\n    void removePlaneAtIndex(size_t index);\n\n    void clear();\n\n    const CompositorPlane* begin() const;\n    const CompositorPlane* end() const;\n    CompositorPlane* begin();\n    CompositorPlane* end();\n\nprivate:\n    Valdi::SmallVector<CompositorPlane, 2> _planes;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/ResolvedPlane.cpp",
    "content": "//\n//  ResolvedPlane.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Composition/ResolvedPlane.hpp\"\n\nnamespace snap::drawing {\n\nExternalSurfacePresenterState ResolvedExternalPlane::resolveDisplayState() const {\n    auto relativeSize = externalSurface->getExternalSurface()->getRelativeSize();\n\n    Matrix resolvedTransform;\n    Rect displayFrame;\n    if (transform.isIdentityOrTranslate()) {\n        // If we have just a translation transform, we put the translation in the display frame\n        // and pass in an identity transform. This makes the rendering more compatible with platforms\n        // that expect a proper frame position on their view elements.\n        displayFrame = Rect::makeXYWH(\n            transform.getTranslateX(), transform.getTranslateY(), relativeSize.width, relativeSize.height);\n    } else {\n        // If we have a more complex transform, the view will have to be positioned using the transform\n        // starting at 0,0 .\n        resolvedTransform = transform;\n        displayFrame = Rect::makeXYWH(0, 0, relativeSize.width, relativeSize.height);\n    }\n\n    return ExternalSurfacePresenterState(displayFrame, resolvedTransform, clipPath, opacity);\n}\n\nResolvedPlane::ResolvedPlane(uint64_t planeIndex, const Ref<BoundingBoxHierarchy>& bbox)\n    : _data(ResolvedRegularPlane(planeIndex, bbox)) {}\n\nResolvedPlane::ResolvedPlane(ExternalSurfaceSnapshot* externalSurface,\n                             const Matrix& transform,\n                             const Path& clipPath,\n                             Scalar opacity,\n                             const Rect& absoluteFrame)\n    : _data(ResolvedExternalPlane(externalSurface, transform, clipPath, opacity, absoluteFrame)) {}\n\nResolvedRegularPlane* ResolvedPlane::getRegular() {\n    return std::get_if<ResolvedRegularPlane>(&_data);\n}\n\nResolvedExternalPlane* ResolvedPlane::getExternal() {\n    return std::get_if<ResolvedExternalPlane>(&_data);\n}\n\nconst ResolvedRegularPlane* ResolvedPlane::getRegular() const {\n    return std::get_if<ResolvedRegularPlane>(&_data);\n}\n\nconst ResolvedExternalPlane* ResolvedPlane::getExternal() const {\n    return std::get_if<ResolvedExternalPlane>(&_data);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Composition/ResolvedPlane.hpp",
    "content": "//\n//  ResolvedPlane.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp\"\n#include \"snap_drawing/cpp/Utils/BoundingBoxHierarchy.hpp\"\n\n#include <variant>\n\nnamespace snap::drawing {\n\nstruct ResolvedRegularPlane {\n    // Index of the surface inside the DisplayList\n    uint64_t planeIndex;\n    // Bounding box calculator, set if the surface is not external\n    Ref<BoundingBoxHierarchy> bbox;\n\n    inline ResolvedRegularPlane(uint64_t planeIndex, const Ref<BoundingBoxHierarchy>& bbox)\n        : planeIndex(planeIndex), bbox(bbox) {}\n};\n\nstruct ResolvedExternalPlane {\n    ExternalSurfaceSnapshot* externalSurface;\n    Matrix transform;\n    Path clipPath;\n    Scalar opacity;\n    Rect absoluteFrame;\n\n    inline ResolvedExternalPlane(ExternalSurfaceSnapshot* externalSurface,\n                                 const Matrix& transform,\n                                 const Path& clipPath,\n                                 Scalar opacity,\n                                 const Rect& absoluteFrame)\n        : externalSurface(externalSurface),\n          transform(transform),\n          clipPath(clipPath),\n          opacity(opacity),\n          absoluteFrame(absoluteFrame) {}\n\n    ExternalSurfacePresenterState resolveDisplayState() const;\n};\n\n// Represents a surface which can be either external or regular.\n// Regular surfaces are appended into the output display list,\n// whereas\nclass ResolvedPlane {\npublic:\n    ResolvedPlane(uint64_t planeIndex, const Ref<BoundingBoxHierarchy>& bbox);\n\n    ResolvedPlane(ExternalSurfaceSnapshot* externalSurface,\n                  const Matrix& transform,\n                  const Path& clipPath,\n                  Scalar opacity,\n                  const Rect& absoluteFrame);\n\n    ResolvedRegularPlane* getRegular();\n\n    ResolvedExternalPlane* getExternal();\n\n    const ResolvedRegularPlane* getRegular() const;\n\n    const ResolvedExternalPlane* getExternal() const;\n\nprivate:\n    std::variant<ResolvedExternalPlane, ResolvedRegularPlane> _data;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/CleanUpDisplayListVisitor.cpp",
    "content": "//\n//  CleanUpDisplayListVisitor.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/CleanUpDisplayListVisitor.hpp\"\n#include \"include/core/SkPicture.h\"\n\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n\nnamespace snap::drawing {\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nvoid CleanUpDisplayListVisitor::visit(const Operations::PushContext& /*pushContext*/) {}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nvoid CleanUpDisplayListVisitor::visit(const Operations::PopContext& /*popContext*/) {}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nvoid CleanUpDisplayListVisitor::visit(const Operations::DrawPicture& drawPicture) {\n    drawPicture.picture->unref();\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nvoid CleanUpDisplayListVisitor::visit(const Operations::ClipRect& /*clipRect*/) {}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nvoid CleanUpDisplayListVisitor::visit(const Operations::ClipRound& /*clipRound*/) {}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nvoid CleanUpDisplayListVisitor::visit(const Operations::DrawExternalSurface& drawExternalSurface) {\n    drawExternalSurface.externalSurfaceSnapshot->unsafeReleaseInner();\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nvoid CleanUpDisplayListVisitor::visit(const Operations::PrepareMask& prepareMask) {\n    prepareMask.mask->unsafeReleaseInner();\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nvoid CleanUpDisplayListVisitor::visit(const Operations::ApplyMask& applyMask) {\n    applyMask.mask->unsafeReleaseInner();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/CleanUpDisplayListVisitor.hpp",
    "content": "//\n//  CleanUpDisplayListVisitor.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayListOperations.hpp\"\n\nnamespace snap::drawing {\n\n/**\n DisplayList visitor which cleans up the operations by releasing any\n retained refs.\n */\nclass CleanUpDisplayListVisitor {\npublic:\n    void visit(const Operations::PushContext& pushContext);\n\n    void visit(const Operations::PopContext& popContext);\n\n    void visit(const Operations::DrawPicture& drawPicture);\n\n    void visit(const Operations::ClipRect& clipRect);\n\n    void visit(const Operations::ClipRound& clipRound);\n\n    void visit(const Operations::DrawExternalSurface& drawExternalSurface);\n\n    void visit(const Operations::PrepareMask& prepareMask);\n\n    void visit(const Operations::ApplyMask& applyMask);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/DebugJSONDisplayListVisitor.cpp",
    "content": "//\n//  DebugJSONDisplayListVisitor.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DebugJSONDisplayListVisitor.hpp\"\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n\nnamespace snap::drawing {\n\nDebugJSONDisplayListVisitor::DebugJSONDisplayListVisitor(std::vector<Valdi::Value>& output) : _output(output) {}\n\nvoid DebugJSONDisplayListVisitor::visit(const Operations::PushContext& pushContext) {\n    auto& op = append(\"push\");\n    op.setMapValue(\"matrix\", Valdi::Value(pushContext.matrix.toString()));\n    op.setMapValue(\"opacity\", Valdi::Value(pushContext.opacity));\n}\n\nvoid DebugJSONDisplayListVisitor::visit(const Operations::PopContext& /*popContext*/) {\n    append(\"pop\");\n}\n\nvoid DebugJSONDisplayListVisitor::visit(const Operations::DrawPicture& drawPicture) {\n    auto& op = append(\"draw\");\n    op.setMapValue(\"opacity\", Valdi::Value(drawPicture.opacity));\n    op.setMapValue(\"picturePtr\", Valdi::Value(reinterpret_cast<int64_t>(drawPicture.picture)));\n}\n\nvoid DebugJSONDisplayListVisitor::visit(const Operations::ClipRect& clipRect) {\n    auto& op = append(\"clipRect\");\n    op.setMapValue(\"width\", Valdi::Value(clipRect.width));\n    op.setMapValue(\"height\", Valdi::Value(clipRect.height));\n}\n\nvoid DebugJSONDisplayListVisitor::visit(const Operations::ClipRound& clipRound) {\n    auto& op = append(\"clipRound\");\n    op.setMapValue(\"width\", Valdi::Value(clipRound.width));\n    op.setMapValue(\"height\", Valdi::Value(clipRound.height));\n    op.setMapValue(\"borderRadius\", Valdi::Value(clipRound.borderRadius.toString()));\n}\n\nvoid DebugJSONDisplayListVisitor::visit(const Operations::DrawExternalSurface& drawExternalSurface) {\n    auto& op = append(\"clipRound\");\n    op.setMapValue(\"opacity\", Valdi::Value(drawExternalSurface.opacity));\n    op.setMapValue(\"externalSurfaceSnapshotPtr\",\n                   Valdi::Value(reinterpret_cast<int64_t>(drawExternalSurface.externalSurfaceSnapshot)));\n}\n\nvoid DebugJSONDisplayListVisitor::visit(const Operations::PrepareMask& prepareMask) {\n    auto& op = append(\"prepareMask\");\n    op.setMapValue(\"description\", Valdi::Value(prepareMask.mask->getDescription()));\n}\n\nvoid DebugJSONDisplayListVisitor::visit(const Operations::ApplyMask& applyMask) {\n    auto& op = append(\"applyMask\");\n    op.setMapValue(\"description\", Valdi::Value(applyMask.mask->getDescription()));\n}\n\nValdi::Value& DebugJSONDisplayListVisitor::append(std::string_view type) {\n    auto& value = _output.emplace_back();\n    value.setMapValue(\"type\", Valdi::Value(std::move(type)));\n    return value;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/DebugJSONDisplayListVisitor.hpp",
    "content": "//\n//  DebugJSONDisplayListVisitor.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayListOperations.hpp\"\n#include \"valdi_core/cpp/Utils/Value.hpp\"\n\n#include <vector>\n\nnamespace snap::drawing {\n\nclass DebugJSONDisplayListVisitor {\npublic:\n    explicit DebugJSONDisplayListVisitor(std::vector<Valdi::Value>& output);\n\n    void visit(const Operations::PushContext& pushContext);\n\n    void visit(const Operations::PopContext& popContext);\n\n    void visit(const Operations::DrawPicture& drawPicture);\n\n    void visit(const Operations::ClipRect& clipRect);\n\n    void visit(const Operations::ClipRound& clipRound);\n\n    void visit(const Operations::DrawExternalSurface& drawExternalSurface);\n\n    void visit(const Operations::PrepareMask& prepareMask);\n\n    void visit(const Operations::ApplyMask& applyMask);\n\nprivate:\n    std::vector<Valdi::Value>& _output;\n\n    Valdi::Value& append(std::string_view type);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/DisplayList.cpp",
    "content": "//\n//  DisplayList.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 9/15/20.\n//\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/CleanUpDisplayListVisitor.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DebugJSONDisplayListVisitor.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DrawDisplayListVisitor.hpp\"\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.hpp\"\n\n#include \"include/core/SkCanvas.h\"\n#include \"include/core/SkPicture.h\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include <cstdint>\n\nnamespace snap::drawing {\n\nstatic void cleanUpByteBuffer(Valdi::ByteBuffer& byteBuffer) {\n    byteBuffer.clear();\n}\n\nDisplayListPlane::DisplayListPlane(PooledByteBuffer&& operations) : operations(std::move(operations)) {}\n\nsize_t kDisplayListAllPlaneIndexes = std::numeric_limits<size_t>::max();\n\nDisplayList::DisplayList(Size size, TimePoint frameTime) : _size(size), _frameTime(frameTime) {\n    appendPlane();\n}\n\nDisplayList::~DisplayList() {\n    removeAllPlanes();\n}\n\nSize DisplayList::getSize() const {\n    return _size;\n}\n\nTimePoint DisplayList::getFrameTime() const {\n    return _frameTime;\n}\n\nvoid DisplayList::pushContext(const Matrix& matrix, Scalar opacity, uint64_t layerId, bool hasUpdates) {\n    auto* op = appendOperation<Operations::PushContext>();\n    op->matrix = matrix;\n    op->opacity = opacity;\n    op->layerId = layerId;\n    op->hasUpdates = hasUpdates;\n}\n\nvoid DisplayList::popContext() {\n    appendOperation<Operations::PopContext>();\n}\n\nvoid DisplayList::appendLayerContent(const LayerContent& layerContent, Scalar opacity) {\n    if (layerContent.picture != nullptr) {\n        appendPicture(layerContent.picture.get(), opacity);\n    }\n\n    if (layerContent.externalSurface != nullptr) {\n        auto* op = appendOperation<Operations::DrawExternalSurface>();\n        op->externalSurfaceSnapshot = layerContent.externalSurface.get();\n        op->opacity = opacity;\n\n        op->externalSurfaceSnapshot->unsafeRetainInner();\n        _hasExternalSurfaces = true;\n    }\n}\n\nvoid DisplayList::appendPicture(SkPicture* picture, Scalar opacity) {\n    auto* op = appendOperation<Operations::DrawPicture>();\n    op->picture = picture;\n    op->opacity = opacity;\n\n    op->picture->ref();\n}\n\nvoid DisplayList::appendClipRound(const BorderRadius& borderRadius, Scalar width, Scalar height) {\n    if (borderRadius.isEmpty()) {\n        appendClipRect(width, height);\n    } else {\n        auto* op = appendOperation<Operations::ClipRound>();\n        op->width = width;\n        op->height = height;\n        op->borderRadius = borderRadius;\n    }\n}\n\nvoid DisplayList::appendClipRect(Scalar width, Scalar height) {\n    auto* op = appendOperation<Operations::ClipRect>();\n    op->width = width;\n    op->height = height;\n}\n\nvoid DisplayList::appendPrepareMask(IMask* mask) {\n    auto* op = appendOperation<Operations::PrepareMask>();\n    op->mask = mask;\n    op->mask->unsafeRetainInner();\n\n    _hasMask = true;\n}\n\nvoid DisplayList::appendApplyMask(IMask* mask) {\n    auto* op = appendOperation<Operations::ApplyMask>();\n    op->mask = mask;\n    op->mask->unsafeRetainInner();\n}\n\nsize_t DisplayList::getBytesUsed(size_t planeIndex) const {\n    auto ptrs = getBeginEndPtrs(planeIndex);\n\n    return ptrs.second - ptrs.first;\n}\n\nsize_t DisplayList::getPlanesCount() const {\n    return _planes.size();\n}\n\nvoid DisplayList::appendPlane() {\n    _currentPlane = &_planes.emplace_back(Valdi::ObjectPool<Valdi::ByteBuffer>::get().getOrCreate(&cleanUpByteBuffer));\n}\n\nvoid DisplayList::setCurrentPlane(size_t planeIndex) {\n    _currentPlane = &_planes[planeIndex];\n}\n\nvoid DisplayList::removePlane(size_t planeIndex) {\n    if (&_planes[planeIndex] == _currentPlane) {\n        _currentPlane = nullptr;\n    }\n\n    CleanUpDisplayListVisitor visitor;\n    visitOperations(planeIndex, visitor);\n\n    _planes.erase(_planes.begin() + planeIndex);\n}\n\nvoid DisplayList::removeEmptyPlanes() {\n    auto index = getPlanesCount();\n\n    while (index > 0) {\n        index--;\n\n        if (getBytesUsed(index) == 0) {\n            removePlane(index);\n        }\n    }\n}\n\nvoid DisplayList::removeAllPlanes() {\n    auto size = getPlanesCount();\n    while (size > 0) {\n        auto planeIndex = --size;\n        removePlane(planeIndex);\n    }\n}\n\nbool DisplayList::hasExternalSurfaces() const {\n    return _hasExternalSurfaces;\n}\n\nValdi::Value DisplayList::toDebugJSON() const {\n    Valdi::Value json;\n    json.setMapValue(\"frameTime\", Valdi::Value(_frameTime.getTime()));\n    json.setMapValue(\"width\", Valdi::Value(_size.width));\n    json.setMapValue(\"height\", Valdi::Value(_size.height));\n\n    std::vector<Valdi::Value> surfaces;\n    for (size_t i = 0; i < getPlanesCount(); i++) {\n        std::vector<Valdi::Value> jsonOperations;\n        DebugJSONDisplayListVisitor visitor(jsonOperations);\n\n        visitOperations(i, visitor);\n\n        surfaces.emplace_back(Valdi::ValueArray::make(std::move(jsonOperations)));\n    }\n\n    json.setMapValue(\"surfaces\", Valdi::Value(Valdi::ValueArray::make(std::move(surfaces))));\n\n    return json;\n}\n\nstd::pair<Valdi::Byte*, Valdi::Byte*> DisplayList::getBeginEndPtrs(size_t planeIndex) const {\n    const auto& operations = *_planes[planeIndex].operations;\n    auto* beginPtr = operations.data();\n    auto* endPtr = beginPtr + operations.size();\n\n    return std::make_pair(beginPtr, endPtr);\n}\n\nstatic void prepareCanvas(SkCanvas* canvas, Scalar scaleX, Scalar scaleY, bool shouldClearCanvas) {\n    canvas->scale(scaleX, scaleY);\n\n    if (shouldClearCanvas) {\n        Paint paint;\n        paint.setColor(Color::transparent());\n        paint.setBlendMode(SkBlendMode::kSrc);\n        canvas->drawPaint(paint.getSkValue());\n    }\n}\n\nvoid DisplayList::draw(\n    DrawableSurfaceCanvas& canvas, size_t planeIndex, Scalar scaleX, Scalar scaleY, bool shouldClearCanvas) const {\n    auto* skiaCanvas = canvas.getSkiaCanvas();\n\n    auto saveCount = skiaCanvas->save();\n\n    prepareCanvas(skiaCanvas, scaleX, scaleY, shouldClearCanvas);\n\n    if (_hasMask) {\n        // We need a dedicated layer texture to implement masking\n        skiaCanvas->saveLayer(nullptr, nullptr);\n    }\n\n    DrawDisplayListVisitor visitor(skiaCanvas, scaleX, scaleY);\n    visitOperations(planeIndex, visitor);\n\n    skiaCanvas->restoreToCount(saveCount);\n}\n\nvoid DisplayList::draw(DrawableSurfaceCanvas& canvas, size_t planeIndex, bool shouldClearCanvas) const {\n    auto canvasWidth = canvas.getWidth();\n    auto canvasHeight = canvas.getHeight();\n\n    auto scaleX = static_cast<Scalar>(canvasWidth) / _size.width;\n    auto scaleY = static_cast<Scalar>(canvasHeight) / _size.height;\n\n    draw(canvas, planeIndex, scaleX, scaleY, shouldClearCanvas);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp",
    "content": "//\n//  DisplayList.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 9/15/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/ByteBuffer.hpp\"\n#include \"valdi_core/cpp/Utils/ObjectPool.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayListOperations.hpp\"\n#include \"snap_drawing/cpp/Drawing/LayerContent.hpp\"\n\n#include \"valdi_core/cpp/Utils/Value.hpp\"\n\n#include \"include/core/SkPicture.h\"\n\n#include <vector>\n\nnamespace snap::drawing {\n\nclass DrawableSurfaceCanvas;\nclass IMask;\n\nextern size_t kDisplayListAllPlaneIndexes;\n\nusing PooledByteBuffer = Valdi::ObjectPoolEntry<Valdi::ByteBuffer, void (*)(Valdi::ByteBuffer&)>;\n\nstruct DisplayListPlane {\n    PooledByteBuffer operations;\n\n    explicit DisplayListPlane(PooledByteBuffer&& operations);\n};\n\nclass DisplayList : public Valdi::SimpleRefCountable {\npublic:\n    DisplayList(Size size, TimePoint frameTime);\n    ~DisplayList() override;\n\n    Size getSize() const;\n    TimePoint getFrameTime() const;\n\n    void pushContext(const Matrix& matrix, Scalar opacity, uint64_t layerId, bool hasUpdates);\n    void popContext();\n\n    void appendLayerContent(const LayerContent& layerContent, Scalar opacity);\n    void appendPicture(SkPicture* picture, Scalar opacity);\n    void appendClipRound(const BorderRadius& borderRadius, Scalar width, Scalar height);\n    void appendClipRect(Scalar width, Scalar height);\n\n    void appendPrepareMask(IMask* mask);\n    void appendApplyMask(IMask* mask);\n\n    size_t getPlanesCount() const;\n    bool hasExternalSurfaces() const;\n\n    size_t getBytesUsed(size_t planeIndex) const;\n\n    void appendPlane();\n    void removePlane(size_t planeIndex);\n\n    void setCurrentPlane(size_t planeIndex);\n\n    void removeEmptyPlanes();\n    void removeAllPlanes();\n\n    Valdi::Value toDebugJSON() const;\n\n    void draw(\n        DrawableSurfaceCanvas& canvas, size_t planeIndex, Scalar scaleX, Scalar scaleY, bool shouldClearCanvas) const;\n\n    void draw(DrawableSurfaceCanvas& canvas, size_t planeIndex, bool shouldClearCanvas = true) const;\n\n    template<typename Visitor>\n    void visitOperations(size_t planeIndex, Visitor& visitor) const {\n        if (planeIndex == kDisplayListAllPlaneIndexes) {\n            auto surfacesCount = getPlanesCount();\n            for (size_t i = 0; i < surfacesCount; i++) {\n                doVisitOperations(i, visitor);\n            }\n        } else {\n            doVisitOperations(planeIndex, visitor);\n        }\n    }\n\nprivate:\n    Valdi::SmallVector<DisplayListPlane, 1> _planes;\n    DisplayListPlane* _currentPlane = nullptr;\n    Size _size;\n    TimePoint _frameTime;\n    bool _hasExternalSurfaces = false;\n    bool _hasMask = false;\n\n    std::pair<Valdi::Byte*, Valdi::Byte*> getBeginEndPtrs(size_t planeIndex) const;\n\n    template<typename T>\n    T* appendOperation() {\n        auto* operation =\n            reinterpret_cast<Operations::Operation*>(_currentPlane->operations->appendWritable(sizeof(T)));\n        operation->type = T::kId;\n\n        return reinterpret_cast<T*>(operation);\n    }\n\n    template<typename Visitor>\n    struct BytesVisitor {\n        Visitor& visitor;\n\n        inline explicit BytesVisitor(Visitor& visitor) : visitor(visitor) {}\n\n        template<typename Operation>\n        inline const Valdi::Byte* visit(const Operation& operation) {\n            visitor.visit(operation);\n            return reinterpret_cast<const Valdi::Byte*>(&operation) + sizeof(Operation);\n        }\n    };\n\n    template<typename Visitor>\n    void doVisitOperations(size_t planeIndex, Visitor& visitor) const {\n        auto ptrs = getBeginEndPtrs(planeIndex);\n        BytesVisitor<Visitor> bytesVisitor(visitor);\n\n        const auto* current = ptrs.first;\n        const auto* end = ptrs.second;\n\n        while (current != end) {\n            current = snap::drawing::Operations::visitOperation(\n                *reinterpret_cast<const Operations::Operation*>(current), bytesVisitor);\n        }\n    }\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/DisplayListOperations.cpp",
    "content": "//\n//  DisplayListOperations.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayListOperations.hpp\"\n\nnamespace snap::drawing::Operations {};\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/DisplayListOperations.hpp",
    "content": "//\n//  DisplayListOperations.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n\nclass SkPicture;\n\nnamespace snap::drawing {\n\nclass ExternalSurfaceSnapshot;\nclass IMask;\n\nnamespace Operations {\n\nstruct Operation {\n    size_t type;\n};\n\nstruct PushContext : public Operation {\n    constexpr static size_t kId = 1;\n\n    Matrix matrix;\n    Scalar opacity;\n    uint64_t layerId;\n    bool hasUpdates;\n};\n\nstruct PopContext : public Operation {\n    constexpr static size_t kId = 2;\n};\n\nstruct DrawPicture : public Operation {\n    constexpr static size_t kId = 3;\n\n    SkPicture* picture;\n    Scalar opacity;\n};\n\nstruct ClipOperation : public Operation {\n    Scalar width;\n    Scalar height;\n};\n\nstruct ClipRect : public ClipOperation {\n    constexpr static size_t kId = 4;\n};\n\nstruct ClipRound : public ClipOperation {\n    constexpr static size_t kId = 5;\n\n    BorderRadius borderRadius;\n};\n\nstruct DrawExternalSurface : public Operation {\n    constexpr static size_t kId = 6;\n\n    ExternalSurfaceSnapshot* externalSurfaceSnapshot;\n    Scalar opacity;\n};\n\nstruct PrepareMask : public Operation {\n    constexpr static size_t kId = 7;\n\n    IMask* mask;\n};\n\nstruct ApplyMask : public Operation {\n    constexpr static size_t kId = 8;\n\n    IMask* mask;\n};\n\ntemplate<typename Visitor>\ninline auto visitOperation(const Operations::Operation& operation, Visitor& visitor) {\n    switch (operation.type) {\n        case Operations::PushContext::kId:\n            return visitor.visit(reinterpret_cast<const Operations::PushContext&>(operation));\n        case Operations::PopContext::kId:\n            return visitor.visit(reinterpret_cast<const Operations::PopContext&>(operation));\n        case Operations::DrawPicture::kId:\n            return visitor.visit(reinterpret_cast<const Operations::DrawPicture&>(operation));\n        case Operations::ClipRect::kId:\n            return visitor.visit(reinterpret_cast<const Operations::ClipRect&>(operation));\n        case Operations::ClipRound::kId:\n            return visitor.visit(reinterpret_cast<const Operations::ClipRound&>(operation));\n        case Operations::DrawExternalSurface::kId:\n            return visitor.visit(reinterpret_cast<const Operations::DrawExternalSurface&>(operation));\n        case Operations::PrepareMask::kId:\n            return visitor.visit(reinterpret_cast<const Operations::PrepareMask&>(operation));\n        case Operations::ApplyMask::kId:\n            return visitor.visit(reinterpret_cast<const Operations::ApplyMask&>(operation));\n        default:\n            std::abort();\n            break;\n    }\n}\n\n}; // namespace Operations\n\n}; // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/DrawDisplayListVisitor.cpp",
    "content": "//\n//  DrawDisplayListVisitor.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DrawDisplayListVisitor.hpp\"\n\n#include \"include/core/SkCanvas.h\"\n\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n\nnamespace snap::drawing {\n\nDrawDisplayListVisitor::DrawDisplayListVisitor(SkCanvas* canvas, Scalar scaleX, Scalar scaleY)\n    : _canvas(canvas), _scaleX(scaleX), _scaleY(scaleY), _tempRect(Rect::makeEmpty()) {}\n\nvoid DrawDisplayListVisitor::visit(const Operations::PushContext& pushContext) {\n    if (pushContext.opacity == 1.0f) {\n        _canvas->save();\n    } else {\n        Paint paint;\n        paint.setAlpha(pushContext.opacity);\n        _canvas->saveLayer(nullptr, &paint.getSkValue());\n    }\n\n    auto matrix = pushContext.matrix;\n\n    matrix.setTranslateX(sanitizeScalarFromScale(matrix.getTranslateX(), _scaleX));\n    matrix.setTranslateY(sanitizeScalarFromScale(matrix.getTranslateY(), _scaleY));\n\n    _canvas->concat(matrix.getSkValue());\n}\n\nvoid DrawDisplayListVisitor::visit(const Operations::PopContext& /*popContext*/) {\n    _canvas->restore();\n}\n\nvoid DrawDisplayListVisitor::visit(const Operations::DrawPicture& drawPicture) {\n    if (drawPicture.opacity == 1.0f) {\n        _canvas->drawPicture(drawPicture.picture);\n    } else {\n        Paint paint;\n        paint.setAlpha(drawPicture.opacity);\n        _canvas->drawPicture(drawPicture.picture, nullptr, &paint.getSkValue());\n    }\n}\n\nvoid DrawDisplayListVisitor::visit(const Operations::ClipRect& clipRect) {\n    _tempRect.right = clipRect.width;\n    _tempRect.bottom = clipRect.height;\n\n    _canvas->clipRect(_tempRect.getSkValue());\n}\n\nvoid DrawDisplayListVisitor::visit(const Operations::ClipRound& clipRound) {\n    _tempRect.right = clipRound.width;\n    _tempRect.bottom = clipRound.height;\n\n    auto path = clipRound.borderRadius.getPath(_tempRect);\n\n    if (!path.isEmpty()) {\n        _canvas->clipPath(path.getSkValue());\n    }\n}\n\nvoid DrawDisplayListVisitor::visit(const Operations::DrawExternalSurface& /*drawExternalSurface*/) {}\n\nvoid DrawDisplayListVisitor::visit(const Operations::PrepareMask& prepareMask) {\n    prepareMask.mask->prepare(_canvas);\n}\n\nvoid DrawDisplayListVisitor::visit(const Operations::ApplyMask& applyMask) {\n    applyMask.mask->apply(_canvas);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DisplayList/DrawDisplayListVisitor.hpp",
    "content": "//\n//  DrawDisplayListVisitor.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayListOperations.hpp\"\n\nclass SkCanvas;\n\nnamespace snap::drawing {\n\n/**\n DisplayList visitor which draws into a canvas\n */\nclass DrawDisplayListVisitor {\npublic:\n    DrawDisplayListVisitor(SkCanvas* canvas, Scalar scaleX, Scalar scaleY);\n\n    void visit(const Operations::PushContext& pushContext);\n\n    void visit(const Operations::PopContext& popContext);\n\n    void visit(const Operations::DrawPicture& drawPicture);\n\n    void visit(const Operations::ClipRect& clipRect);\n\n    void visit(const Operations::ClipRound& clipRound);\n\n    void visit(const Operations::DrawExternalSurface& drawExternalSurface);\n\n    void visit(const Operations::PrepareMask& prepareMask);\n\n    void visit(const Operations::ApplyMask& applyMask);\n\nprivate:\n    SkCanvas* _canvas;\n    Scalar _scaleX;\n    Scalar _scaleY;\n    Rect _tempRect;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DrawLooper.cpp",
    "content": "//\n//  DrawLooper.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/DrawLooper.hpp\"\n#include \"snap_drawing/cpp/Drawing/DrawOperation.hpp\"\n#include \"utils/debugging/Assert.hpp\"\n\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n\nnamespace snap::drawing {\n\n/**\n Max GPU cache size used by Skia.\n Skia uses a default of 256MB.\n Android computes the size based on the device screen size,\n for a Pixel XL the cache is 168MB.\n We use a hardcoded 128MB, which is lower than the default, while\n remaining fairly large already.\n */\nstatic constexpr size_t kMaxGpuCacheSize = 128 * 1024 * 1024;\nstatic constexpr size_t kMaxGpuCacheSizeInBackground = kMaxGpuCacheSize / 4;\nstatic constexpr std::chrono::seconds kCacheExpirationSeconds = std::chrono::seconds(10);\n\nclass DrawLooperFrameCallback : public IFrameCallback {\npublic:\n    explicit DrawLooperFrameCallback(DrawLooper* looper) : _drawLooper(Valdi::strongSmallRef(looper)) {}\n    ~DrawLooperFrameCallback() override = default;\n\nprotected:\n    Ref<DrawLooper> _drawLooper;\n};\n\nclass DrawFramesCallback : public DrawLooperFrameCallback {\npublic:\n    explicit DrawFramesCallback(DrawLooper* looper) : DrawLooperFrameCallback(looper) {}\n\n    void onFrame(TimePoint time) override {\n        _drawLooper->drawFrames(time);\n    }\n};\n\nclass ProcessFramesCallback : public DrawLooperFrameCallback {\npublic:\n    explicit ProcessFramesCallback(DrawLooper* looper) : DrawLooperFrameCallback(looper) {}\n\n    void onFrame(TimePoint time) override {\n        _drawLooper->processFrames(time);\n    }\n};\n\nclass PerformCleanupCallback : public DrawLooperFrameCallback {\npublic:\n    PerformCleanupCallback(DrawLooper* looper, DrawLooper::CleanUpMode cleanUpMode)\n        : DrawLooperFrameCallback(looper), _cleanUpMode(cleanUpMode) {}\n\n    void onFrame(TimePoint /*time*/) override {\n        auto drawLock = _drawLooper->getDrawLock();\n        _drawLooper->performCleanup(_cleanUpMode);\n    }\n\nprivate:\n    DrawLooper::CleanUpMode _cleanUpMode;\n};\n\nclass ConfigureCacheSizeCallback : public DrawLooperFrameCallback {\npublic:\n    ConfigureCacheSizeCallback(DrawLooper* looper, const Ref<GraphicsContext>& graphicsContext)\n        : DrawLooperFrameCallback(looper), _graphicsContext(graphicsContext) {}\n    ~ConfigureCacheSizeCallback() override = default;\n\n    void onFrame(TimePoint /*time*/) override {\n        auto drawLock = _drawLooper->getDrawLock();\n        _graphicsContext->setResourceCacheLimit(kMaxGpuCacheSize);\n    }\n\nprivate:\n    Ref<GraphicsContext> _graphicsContext;\n};\n\nDrawLooper::DrawLooper(const Ref<IFrameScheduler>& frameScheduler, Valdi::ILogger& logger)\n    : _frameScheduler(frameScheduler), _logger(logger) {}\n\nDrawLooper::~DrawLooper() = default;\n\nvoid DrawLooper::addLayerRoot(const Ref<LayerRoot>& layerRoot,\n                              const Ref<SurfacePresenterManager>& surfacePresenterManager,\n                              bool disallowSynchronousDraw) {\n    DrawLooperEntryListener* listener = this;\n    auto entry = Valdi::makeShared<DrawLooperEntry>(layerRoot, surfacePresenterManager, listener);\n    entry->setDisallowSynchronousDraw(disallowSynchronousDraw);\n\n    {\n        auto lock = getEntriesLock();\n        SC_ASSERT(getEntryForLayer(*layerRoot) == nullptr);\n\n        _entries.emplace_back(entry);\n        layerRoot->setListener(entry.get());\n        scheduleProcessFrame(lock);\n    }\n\n    layerRoot->setChildNeedsDisplay();\n}\n\nvoid DrawLooper::removeLayerRoot(const Ref<LayerRoot>& layerRoot) {\n    Ref<DrawLooperEntry> entry;\n    auto drawLock = getDrawLock();\n    auto lock = getEntriesLock();\n\n    auto it = _entries.begin();\n    while (it != _entries.end()) {\n        if (it->get()->getLayerRoot() == layerRoot) {\n            layerRoot->setListener(nullptr);\n            entry = *it;\n            _entries.erase(it);\n\n            entry->removeSurfacePresenters();\n\n            if (!_managedGraphicsContexts.empty()) {\n                schedulePerformCleanup(DrawLooper::CleanUpMode::PostDraw);\n            }\n\n            return;\n        }\n        it++;\n    }\n}\n\nvoid DrawLooper::setDrawableSurfaceOfLayerRootForPresenterId(LayerRoot& layerRoot,\n                                                             SurfacePresenterId surfacePresenterId,\n                                                             const Ref<DrawableSurface>& drawableSurface) {\n    auto drawLock = getDrawLock();\n    auto lock = getEntriesLock();\n    auto entry = getEntryForLayer(layerRoot);\n    if (entry == nullptr) {\n        return;\n    }\n\n    entry->setDrawableSurfaceForPresenterId(surfacePresenterId, drawableSurface);\n\n    auto drawState = entry->getDrawState();\n    if (drawState.needsDraw) {\n        if (drawState.prefersSynchronousDraw) {\n            drawEntry(*entry);\n        } else {\n            scheduleDraw(lock);\n        }\n    }\n}\n\nbool DrawLooper::drawPlaneOfLayerRootForPresenterId(LayerRoot& layerRoot,\n                                                    SurfacePresenterId surfacePresenterId,\n                                                    DrawableSurfaceCanvas& canvas) {\n    auto lock = getEntriesLock();\n    auto entry = getEntryForLayer(layerRoot);\n    if (entry == nullptr) {\n        return false;\n    }\n\n    auto drawOperation = entry->makeDrawOperation(false);\n\n    lock.unlock();\n\n    return drawOperation->drawForPresenterId(surfacePresenterId, canvas);\n}\n\nvoid DrawLooper::setPresenterOfLayerRootNeedsRedraw(LayerRoot& layerRoot, SurfacePresenterId surfacePresenterId) {\n    auto entriesLock = getEntriesLock();\n    auto entry = mustGetEntryForLayer(layerRoot);\n    entry->setPresenterNeedsDraw(surfacePresenterId);\n    scheduleDraw(entriesLock);\n}\n\nvoid DrawLooper::appendManagedGraphicsContext(const Ref<GraphicsContext>& graphicsContext) {\n    auto drawLock = getDrawLock();\n    _managedGraphicsContexts.emplace_back(graphicsContext);\n    _frameScheduler->onNextVSync(Valdi::makeShared<ConfigureCacheSizeCallback>(this, graphicsContext));\n}\n\nvoid DrawLooper::removeManagedGraphicsContext(const GraphicsContext* graphicsContext) {\n    auto drawLock = getDrawLock();\n    auto it = _managedGraphicsContexts.begin();\n    while (it != _managedGraphicsContexts.end()) {\n        if (it->get() == graphicsContext) {\n            it = _managedGraphicsContexts.erase(it);\n        } else {\n            it++;\n        }\n    }\n}\n\nvoid DrawLooper::onApplicationEnteringBackground() {\n    {\n        auto entriesLock = getEntriesLock();\n        _inBackground = true;\n    }\n    schedulePerformCleanup(CleanUpMode::EnteringBackground);\n}\n\nvoid DrawLooper::onApplicationEnteringForeground() {\n    auto entriesLock = getEntriesLock();\n    _inBackground = false;\n    scheduleProcessFrame(entriesLock);\n}\n\nvoid DrawLooper::onApplicationIsInLowMemory() {\n    schedulePerformCleanup(CleanUpMode::TrimMemory);\n}\n\nvoid DrawLooper::onNeedsProcessFrame(DrawLooperEntry& /*entry*/) {\n    auto entriesLock = getEntriesLock();\n    scheduleProcessFrame(entriesLock);\n}\n\nSurfacePresenterId DrawLooper::createSurfacePresenterId() {\n    return ++_surfacePresenterIdSequence;\n}\n\nvoid DrawLooper::onDidDraw(DrawLooperEntry& entry,\n                           const Ref<DisplayList>& displayList,\n                           const CompositorPlaneList* planeList) {\n    auto entriesLock = getEntriesLock();\n\n    if (planeList != nullptr) {\n        if (entry.surfacePresentersNeedUpdate(*planeList)) {\n            // Release the lock before taking the draw lock, to follow the same\n            // locking ordering used in drawFrames\n            entriesLock.unlock();\n            auto drawLock = getDrawLock();\n            entriesLock.lock();\n\n            {\n                VALDI_TRACE(\"SnapDrawing.updateSurfacePresenters\");\n                entry.updateSurfacePresenters(*planeList);\n            }\n            entry.enqueueDisplayList(displayList);\n\n            if (entry.getDrawState().needsSynchronousDraw()) {\n                drawEntry(entry);\n\n                if (!_managedGraphicsContexts.empty()) {\n                    schedulePerformCleanup(CleanUpMode::PostDraw);\n                }\n            }\n\n            return;\n        }\n    }\n\n    entry.enqueueDisplayList(displayList);\n}\n\nvoid DrawLooper::drawEntry(DrawLooperEntry& entry) {\n    DrawOperationsBatch batch;\n    batch.emplace_back(entry.makeDrawOperation(true));\n\n    drawOperationsBatch(batch);\n}\n\nDrawOperationsBatch DrawLooper::collectDrawOperations() {\n    DrawOperationsBatch drawOperations;\n    auto entriesLock = getEntriesLock();\n\n    for (const auto& it : _entries) {\n        if (it->getDrawState().needsDraw) {\n            drawOperations.emplace_back(it->makeDrawOperation(true));\n        }\n    }\n\n    return drawOperations;\n}\n\nvoid DrawLooper::drawOperationsBatch(const DrawOperationsBatch& drawOperations) {\n    Valdi::SmallVector<GraphicsContext*, 2> graphicsContexts;\n\n    for (const auto& drawOperation : drawOperations) {\n        while (drawOperation->hasNext()) {\n            auto result = drawOperation->drawNext();\n\n            if (!result) {\n                VALDI_ERROR(_logger, \"Failed to draw Surface: {}\", result.error());\n            } else {\n                auto* graphicsContext = result.value();\n                if (graphicsContext != nullptr &&\n                    std::find(graphicsContexts.begin(), graphicsContexts.end(), graphicsContext) ==\n                        graphicsContexts.end()) {\n                    graphicsContexts.emplace_back(graphicsContext);\n                }\n            }\n        }\n    }\n\n    for (auto* graphicsContext : graphicsContexts) {\n        graphicsContext->commit();\n    }\n}\n\nvoid DrawLooper::drawFrames(TimePoint /*time*/) {\n    auto drawLock = getDrawLock();\n    auto drawOperations = collectDrawOperations();\n    drawOperationsBatch(drawOperations);\n    performCleanup(DrawLooper::CleanUpMode::PostDraw);\n\n    auto entriesLock = getEntriesLock();\n    _drawScheduled = false;\n\n    for (const auto& it : _entries) {\n        if (it->getDrawState().needsDraw) {\n            scheduleDraw(entriesLock);\n            return;\n        }\n    }\n}\n\nvoid DrawLooper::processFrames(TimePoint time) {\n    _processingFrames = true;\n\n    while (processFrameForNextLayer(time)) {\n    }\n\n    bool needScheduleDraw = false;\n    bool needScheduleProcessFrame = false;\n    auto entriesLock = getEntriesLock();\n\n    for (const auto& it : _entries) {\n        if (it->getLayerRoot()->needsProcessFrame()) {\n            needScheduleProcessFrame = true;\n        }\n        if (it->getDrawState().needsDraw) {\n            needScheduleDraw = true;\n        }\n    }\n\n    _processingFrames = false;\n    _processFrameScheduled = false;\n\n    if (needScheduleProcessFrame) {\n        doScheduleProcessFrame();\n    }\n\n    if (needScheduleDraw && !_drawScheduled && !_inBackground) {\n        doScheduleDraw();\n    }\n}\n\nvoid DrawLooper::performCleanup(DrawLooper::CleanUpMode cleanUpMode) {\n    for (const auto& managedGraphicsContext : _managedGraphicsContexts) {\n        switch (cleanUpMode) {\n            case CleanUpMode::PostDraw:\n                managedGraphicsContext->performCleanup(false, kCacheExpirationSeconds);\n                break;\n            case CleanUpMode::EnteringBackground:\n                managedGraphicsContext->setResourceCacheLimit(kMaxGpuCacheSizeInBackground);\n                managedGraphicsContext->performCleanup(true, std::chrono::seconds(0));\n                managedGraphicsContext->setResourceCacheLimit(kMaxGpuCacheSize);\n                break;\n            case CleanUpMode::TrimMemory:\n                managedGraphicsContext->setResourceCacheLimit(0);\n                managedGraphicsContext->performCleanup(true, std::chrono::seconds(0));\n                managedGraphicsContext->setResourceCacheLimit(kMaxGpuCacheSize);\n                break;\n        }\n    }\n}\n\nbool DrawLooper::processFrameForNextLayer(TimePoint currentFrameTime) {\n    auto entriesLock = getEntriesLock();\n    for (const auto& it : _entries) {\n        if (it->needsProcessFrameAtTime(currentFrameTime)) {\n            auto layerRoot = it->getLayerRoot();\n            entriesLock.unlock();\n\n            layerRoot->processFrame(currentFrameTime);\n            return true;\n        }\n    }\n    return false;\n}\n\nvoid DrawLooper::scheduleProcessFrame(EntriesLock& entriesLock) {\n    if (_processingFrames || _processFrameScheduled) {\n        return;\n    }\n    doScheduleProcessFrame();\n    entriesLock.unlock();\n}\n\nvoid DrawLooper::scheduleDraw(EntriesLock& entriesLock) {\n    if (_drawScheduled) {\n        return;\n    }\n    doScheduleDraw();\n    entriesLock.unlock();\n}\n\nvoid DrawLooper::schedulePerformCleanup(CleanUpMode cleanUpMode) {\n    _frameScheduler->onNextVSync(Valdi::makeShared<PerformCleanupCallback>(this, cleanUpMode));\n}\n\nvoid DrawLooper::doScheduleProcessFrame() {\n    _processFrameScheduled = true;\n    _frameScheduler->onMainThread(Valdi::makeShared<ProcessFramesCallback>(this));\n}\n\nvoid DrawLooper::doScheduleDraw() {\n    _drawScheduled = true;\n    _frameScheduler->onNextVSync(Valdi::makeShared<DrawFramesCallback>(this));\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nRef<DrawLooperEntry> DrawLooper::getEntryForLayer(LayerRoot& layerRoot) const {\n    auto* entry = dynamic_cast<DrawLooperEntry*>(layerRoot.getListener());\n    return Valdi::strongSmallRef(entry);\n}\n\nRef<DrawLooperEntry> DrawLooper::mustGetEntryForLayer(LayerRoot& layerRoot) const {\n    auto entry = getEntryForLayer(layerRoot);\n    SC_ASSERT(entry != nullptr);\n    return entry;\n}\n\nEntriesLock DrawLooper::getEntriesLock() const {\n    return EntriesLock(_mainThreadMutex);\n}\n\nDrawLock DrawLooper::getDrawLock() const {\n    return DrawLock(_drawMutex);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DrawLooper.hpp",
    "content": "//\n//  DrawLooper.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/DrawLooperEntry.hpp\"\n#include \"snap_drawing/cpp/Drawing/IFrameScheduler.hpp\"\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"valdi_core/cpp/Interfaces/ILogger.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\n#include <vector>\n\nnamespace snap::drawing {\n\nusing EntriesLock = std::unique_lock<std::recursive_mutex>;\nusing DrawLock = std::unique_lock<std::recursive_mutex>;\nusing DrawOperationsBatch = Valdi::SmallVector<Ref<DrawOperation>, 8>;\n\nclass PerformCleanupCallback;\nclass ConfigureCacheSizeCallback;\n\n/**\n The DrawLooper is a class that manages frame processing and drawing on LayerRoot objects.\n Frame processing is done in the main thread, while drawing is done on a background thread.\n It relies on a FrameScheduler instance to schedule VSync and main thread callbacks.\n\n The DrawLooper will keep enqueueing callbacks into the main thread as long as there\n are LayerRoot that needs frame processing, which can happen if they have running animations,\n gestures, or any external updates to the Layer tree. The FrameScheduler can dequeue those\n callbacks as fast it wants.\n\n Similarly, the DrawLooper will keep enqueueing callbacks into the draw thread on VSync as long\n as there are pending frames to be dequeued.\n\n Every added LayerRoot is associated an Entry, which holds the last and next frame to draw and\n the GraphicsContext associated to that LayerRoot. As such the looper is double buffered, as it\n can hold one pending frame to draw while another frame might be drawing. Whenever a frame is\n emitted during frame processing on the main thread, it is enqueued and later\n dequeued when drawing in the VSync thread. When the VSync callback is called, the looper goes\n its entries, extracts the pending frames that should be drawn, and then draw them.\n\n It uses 2 mutexes: a draw mutex and an entries mutex. The entries mutex is the main mutex for\n which a lock is acquired whenever doing any reading or writing on the entries that the looper holds.\n Most calls into the looper ends up acquiring the entries mutex. The draw mutex is locked at the\n beginning of vsync and released after draw. This ensures that mutations on the GraphicsContext\n of a LayerRoot can be done synchronously with the VSync thread.\n */\nclass DrawLooper : public Valdi::SimpleRefCountable, protected DrawLooperEntryListener {\npublic:\n    DrawLooper(const Ref<IFrameScheduler>& frameScheduler, Valdi::ILogger& logger);\n    ~DrawLooper() override;\n\n    /**\n     Append a LayerRoot into the looper and associate it with a SurfacePresenterManager.\n     The looper will begin calling LayerRoot::processFrame() on the main thread whenever the LayerRoot\n     needs to be updated.\n     When the LayerRoot emits new DisplayList, the DrawLooper will use the given SurfacePresenterManager\n     to create drawable or external surface presenters to draw the content of the DisplayList as needed.\n     `disallowSynchronousDraw` controls whether native views are drawn synchronously.\n     */\n    void addLayerRoot(const Ref<LayerRoot>& layerRoot,\n                      const Ref<SurfacePresenterManager>& surfacePresenterManager,\n                      bool disallowSynchronousDraw);\n\n    /**\n     Remove a LayerRoot from the looper, which will stop the looper from calling LayerRoot::processFrame()\n     and will remove all previously created presenters.\n     */\n    void removeLayerRoot(const Ref<LayerRoot>& layerRoot);\n\n    /**\n     Draw the DisplayList plane content from the given drawable presenter id and LayerRoot\n     into the given canvas. This can be used to dump the content of the presenter into a separate canvas.\n     */\n    bool drawPlaneOfLayerRootForPresenterId(LayerRoot& layerRoot,\n                                            SurfacePresenterId surfacePresenterId,\n                                            DrawableSurfaceCanvas& canvas);\n\n    /**\n     Set the DrawableSurface instance of the drawable presenter id and LayerRoot.\n     If the SurfacePresenterManager implementation cannot synchronously return a DrawableSurface\n     when calling SurfacePresenterManager::createPresenterWithDrawableSurface(), like on Android for instance,\n     the DrawableSurface should be provided later on when it becomes available so that the DrawLooper\n     can draw into it.\n     */\n    void setDrawableSurfaceOfLayerRootForPresenterId(LayerRoot& layerRoot,\n                                                     SurfacePresenterId surfacePresenterId,\n                                                     const Ref<DrawableSurface>& drawableSurface);\n\n    /**\n     Marks that a SurfacePresenter with the given id and LayerRoot needs to be redrawn.\n     The DrawLooper will forcefully trigger a draw on that presenter to draw the last DisplayList\n     plane that was drawn into it.\n     */\n    void setPresenterOfLayerRootNeedsRedraw(LayerRoot& layerRoot, SurfacePresenterId surfacePresenterId);\n\n    /**\n     Append a GraphicsContext to the list of managed GraphicsContexts.\n     The GraphicsContext will be periodically purged to reduce its memory usage,\n     Its resource cache limit will be updated depending on the application state.\n     */\n    void appendManagedGraphicsContext(const Ref<GraphicsContext>& graphicsContext);\n\n    /**\n     Remove a GraphicsContext from the list of managed GraphicsContext.\n     */\n    void removeManagedGraphicsContext(const GraphicsContext* graphicsContext);\n\n    /**\n     Notifies the DrawLooper that the application is entering background\n     */\n    void onApplicationEnteringBackground();\n\n    /**\n     Notifies the DrawLooper that the application is entering foreground\n     */\n    void onApplicationEnteringForeground();\n\n    /**\n     Notifies the DrawLooper that the application has low memory.\n     This will free up as much resources as possible from the managed\n     GraphicsContexts.\n     */\n    void onApplicationIsInLowMemory();\n\n    /**\n     Call LayerRoot::processFrame() for all registered LayerRoot that needs to be processed.\n     The processed LayerRoot might then emit new DisplayList if the processFrame() call ended up\n     triggering a draw. If new DisplayLists were emitted, a DrawLooper::drawFrames() pass is then scheduled in the\n     VSync thread.\n\n     This is called from the IFrameScheduler::onMainThread callback, which should be called in the main thread.\n     */\n    void processFrames(TimePoint time);\n\n    /**\n     Draw the frames for all the registered LayerRoot that emitted new DisplayLists in the last processFrames()\n     pass. This is called from the IFrameScheduler::onNextVsync callback, which should be called in a background thread.\n     */\n    void drawFrames(TimePoint time);\n\n    DrawLock getDrawLock() const;\n\nprotected:\n    void onNeedsProcessFrame(DrawLooperEntry& entry) override;\n\n    void onDidDraw(DrawLooperEntry& entry,\n                   const Ref<DisplayList>& displayList,\n                   const CompositorPlaneList* planeList) override;\n\n    SurfacePresenterId createSurfacePresenterId() override;\n\nprivate:\n    friend PerformCleanupCallback;\n    friend ConfigureCacheSizeCallback;\n\n    enum class CleanUpMode {\n        PostDraw,\n        EnteringBackground,\n        TrimMemory,\n    };\n\n    Ref<IFrameScheduler> _frameScheduler;\n    [[maybe_unused]] Valdi::ILogger& _logger;\n    std::vector<Ref<DrawLooperEntry>> _entries;\n    std::vector<Ref<GraphicsContext>> _managedGraphicsContexts;\n    mutable std::recursive_mutex _mainThreadMutex;\n    mutable std::recursive_mutex _drawMutex;\n    SurfacePresenterId _surfacePresenterIdSequence = 0;\n    bool _processingFrames = false;\n    bool _processFrameScheduled = false;\n    bool _drawScheduled = false;\n    bool _inBackground = false;\n\n    Ref<DrawLooperEntry> getEntryForLayer(LayerRoot& layerRoot) const;\n    Ref<DrawLooperEntry> mustGetEntryForLayer(LayerRoot& layerRoot) const;\n\n    EntriesLock getEntriesLock() const;\n\n    void scheduleDraw(EntriesLock& entriesLock);\n    void scheduleProcessFrame(EntriesLock& entriesLock);\n    void schedulePerformCleanup(CleanUpMode cleanUpMode);\n\n    void doScheduleDraw();\n    void doScheduleProcessFrame();\n    void drawEntry(DrawLooperEntry& entry);\n\n    bool processFrameForNextLayer(TimePoint currentFrameTime);\n\n    DrawOperationsBatch collectDrawOperations();\n    void drawOperationsBatch(const DrawOperationsBatch& drawOperations);\n    bool needsDraw() const;\n    void performCleanup(CleanUpMode cleanUpMode);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DrawLooperEntry.cpp",
    "content": "//\n//  DrawLooperEntry.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/25/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/DrawLooperEntry.hpp\"\n#include \"snap_drawing/cpp/Drawing/DrawOperation.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n#include <bitset>\n\nnamespace snap::drawing {\n\nDrawLooperEntry::DrawLooperEntry(const Ref<LayerRoot>& layerRoot,\n                                 const Ref<SurfacePresenterManager>& surfacePresenterManager,\n                                 DrawLooperEntryListener* listener)\n    : _layerRoot(layerRoot), _surfacePresenterManager(surfacePresenterManager), _listener(listener) {}\n\nDrawLooperEntry::~DrawLooperEntry() = default;\n\nDrawLooperEntryDrawState DrawLooperEntry::getDrawState() const {\n    DrawLooperEntryDrawState drawState;\n    if (_displayList == nullptr) {\n        return drawState;\n    }\n\n    auto frameTime = _displayList->getFrameTime();\n\n    for (const auto& surfacePresenter : _surfacePresenters) {\n        if (surfacePresenter.needsDrawForFrameTime(frameTime)) {\n            drawState.needsDraw = true;\n            if (surfacePresenter.needsSynchronousDraw()) {\n                drawState.prefersSynchronousDraw = true;\n            }\n        }\n    }\n\n    return drawState;\n}\n\nbool DrawLooperEntry::needsProcessFrameAtTime(TimePoint frameTime) const {\n    return _layerRoot->needsProcessFrame() &&\n           (!_layerRoot->getLastAbsoluteFrameTime() || _layerRoot->getLastAbsoluteFrameTime().value() != frameTime);\n}\n\nvoid DrawLooperEntry::enqueueDisplayList(const Ref<DisplayList>& displayList) {\n    _displayList = displayList;\n}\n\nRef<DrawOperation> DrawLooperEntry::makeDrawOperation(bool shouldSwapToNextFrame) {\n    SurfacePresenterList surfacePresenters;\n\n    if (shouldSwapToNextFrame) {\n        if (_displayList != nullptr) {\n            auto frameTime = _displayList->getFrameTime();\n            for (auto& presenter : _surfacePresenters) {\n                if (presenter.needsDrawForFrameTime(frameTime)) {\n                    presenter.setLastDrawnFrameTime({frameTime});\n                    presenter.setNeedsSynchronousDraw(false);\n\n                    auto& presenterToDraw = surfacePresenters.append(presenter.getId());\n                    presenterToDraw = presenter;\n                }\n            }\n        }\n    } else {\n        surfacePresenters = _surfacePresenters;\n    }\n\n    return Valdi::makeShared<DrawOperation>(_displayList, _surfacePresenterManager, std::move(surfacePresenters));\n}\n\nconst Ref<LayerRoot>& DrawLooperEntry::getLayerRoot() const {\n    return _layerRoot;\n}\n\nbool DrawLooperEntry::surfacePresentersNeedUpdate(const CompositorPlaneList& planeList) const {\n    if (_surfacePresenters.size() != planeList.getPlanesCount()) {\n        return true;\n    }\n\n    size_t i = 0;\n    for (const auto& surfacePresenter : _surfacePresenters) {\n        const auto& plane = planeList.getPlaneAtIndex(i);\n\n        switch (plane.getType()) {\n            case CompositorPlaneTypeDrawable: {\n                if (!surfacePresenter.isDrawable()) {\n                    return true;\n                }\n            } break;\n            case CompositorPlaneTypeExternal: {\n                if (surfacePresenter.getExternalSurface() !=\n                    plane.getExternalSurfaceSnapshot()->getExternalSurface().get()) {\n                    return true;\n                }\n                if (*surfacePresenter.getExternalSurfacePresenterState() != *plane.getExternalSurfacePresenterState()) {\n                    return true;\n                }\n            } break;\n        }\n\n        i++;\n    }\n\n    return false;\n}\n\nbool DrawLooperEntry::setPresenterNeedsDraw(SurfacePresenterId id) {\n    auto* presenter = _surfacePresenters.getForId(id);\n    if (presenter == nullptr) {\n        return false;\n    }\n\n    presenter->setLastDrawnFrameTime(std::nullopt);\n\n    return true;\n}\n\nvoid DrawLooperEntry::setDisallowSynchronousDraw(bool disallowSynchronousDraw) {\n    _disallowSynchronousDraw = disallowSynchronousDraw;\n}\n\nvoid DrawLooperEntry::removeSurfacePresenters() {\n    updateSurfacePresenters(CompositorPlaneList());\n}\n\nvoid DrawLooperEntry::updateSurfacePresenters(const CompositorPlaneList& planeList) {\n    auto newPlanesCount = planeList.getPlanesCount();\n    size_t displayListPlaneIndex = 0;\n    bool needSynchronousDraw = false;\n\n    for (size_t i = 0; i < newPlanesCount; i++) {\n        const auto& plane = planeList.getPlaneAtIndex(i);\n        updateSurfaceForPlane(plane, i, &needSynchronousDraw, &displayListPlaneIndex);\n    }\n\n    while (_surfacePresenters.size() > newPlanesCount) {\n        auto indexToRemove = _surfacePresenters.size() - 1;\n        auto surfacePresenter = std::move(_surfacePresenters[indexToRemove]);\n        _surfacePresenters.remove(indexToRemove);\n\n        {\n            VALDI_TRACE(\"SnapDrawing.removeSurfacePresenter\");\n            _surfacePresenterManager->removeSurfacePresenter(surfacePresenter.getId());\n        }\n\n        needSynchronousDraw = true;\n    }\n\n    if (needSynchronousDraw && !_disallowSynchronousDraw) {\n        for (auto& presenter : _surfacePresenters) {\n            if (presenter.isDrawable()) {\n                presenter.setNeedsSynchronousDraw(true);\n            }\n        }\n    }\n}\n\nbool DrawLooperEntry::setDrawableSurfaceForPresenterId(SurfacePresenterId id,\n                                                       const Ref<DrawableSurface>& drawableSurface) {\n    auto* surfacePresenter = _surfacePresenters.getForId(id);\n    if (surfacePresenter == nullptr) {\n        return false;\n    }\n    if (surfacePresenter->getDrawableSurface() != drawableSurface.get()) {\n        surfacePresenter->setSurface(drawableSurface.get());\n        surfacePresenter->setLastDrawnFrameTime(std::nullopt);\n    }\n\n    return true;\n}\n\nvoid DrawLooperEntry::createSurfaceForPlane(const CompositorPlane& plane,\n                                            size_t zIndex,\n                                            bool* needSynchronousDraw,\n                                            size_t* displayListPlaneIndex) {\n    auto surfacePresenterId = _listener->createSurfacePresenterId();\n\n    SurfacePresenter& surfacePresenter = _surfacePresenters.insert(zIndex, surfacePresenterId);\n\n    switch (plane.getType()) {\n        case CompositorPlaneTypeDrawable: {\n            surfacePresenter.setDisplayListPlaneIndex((*displayListPlaneIndex)++);\n            surfacePresenter.setAsDrawable();\n            VALDI_TRACE(\"SnapDrawing.createDrawablePresenter\");\n            auto drawableSurface =\n                _surfacePresenterManager->createPresenterWithDrawableSurface(surfacePresenterId, zIndex);\n            if (drawableSurface != nullptr) {\n                surfacePresenter.setSurface(drawableSurface.get());\n            }\n            if (_surfacePresenters.size() > 1 && drawableSurface == nullptr) {\n                // If we already had a presenter before creating this one and that the new presenter\n                // doesn't have a surface readily available, we will need a synchronous draw once\n                // the surface comes in to synchronize the surfaces together\n                *needSynchronousDraw = true;\n            }\n        } break;\n        case CompositorPlaneTypeExternal: {\n            surfacePresenter.setDisplayListPlaneIndex(*displayListPlaneIndex);\n            auto* externalSurfaceSnapshot = plane.getExternalSurfaceSnapshot();\n            const auto& presenterState = *plane.getExternalSurfacePresenterState();\n            surfacePresenter.setAsExternal(*externalSurfaceSnapshot->getExternalSurface(), presenterState);\n\n            VALDI_TRACE(\"SnapDrawing.createExternalPresenter\");\n            _surfacePresenterManager->createPresenterForExternalSurface(\n                surfacePresenterId, zIndex, *externalSurfaceSnapshot->getExternalSurface());\n            _surfacePresenterManager->setExternalSurfacePresenterState(surfacePresenterId, presenterState, nullptr);\n            *needSynchronousDraw = true;\n        } break;\n    }\n}\n\nvoid DrawLooperEntry::moveSurfacePresenter(SurfacePresenterId id,\n                                           size_t fromIndex,\n                                           size_t toIndex,\n                                           bool* needSynchronousDraw) {\n    _surfacePresenters.move(fromIndex, toIndex);\n    _surfacePresenterManager->setSurfacePresenterZIndex(id, toIndex);\n    *needSynchronousDraw = true;\n}\n\nbool DrawLooperEntry::tryReuseDrawableSurface(const CompositorPlane& /*plane*/,\n                                              size_t zIndex,\n                                              size_t planesCount,\n                                              bool* needSynchronousDraw,\n                                              size_t* displayListPlaneIndex) {\n    for (size_t i = zIndex; i < planesCount; i++) {\n        auto& existingSurfacePresenter = _surfacePresenters[i];\n        if (existingSurfacePresenter.isDrawable()) {\n            // We found a surface we can use\n            existingSurfacePresenter.setDisplayListPlaneIndex((*displayListPlaneIndex)++);\n\n            if (i != zIndex) {\n                // zIndex has changed\n                auto surfacePresenterId = existingSurfacePresenter.getId();\n                moveSurfacePresenter(surfacePresenterId, i, zIndex, needSynchronousDraw);\n            }\n            return true;\n        }\n    }\n\n    return false;\n}\n\nbool DrawLooperEntry::tryReuseExternalSurface(\n    const CompositorPlane& plane,\n    size_t zIndex,\n    size_t planesCount,\n    bool* needSynchronousDraw,\n    size_t* displayListPlaneIndex) { // NOLINT(readability-non-const-parameter)\n    auto* externalSurface = plane.getExternalSurfaceSnapshot()->getExternalSurface().get();\n    const auto& presenterState = *plane.getExternalSurfacePresenterState();\n\n    for (size_t i = zIndex; i < planesCount; i++) {\n        auto& existingSurfacePresenter = _surfacePresenters[i];\n        if (existingSurfacePresenter.getExternalSurface() == externalSurface) {\n            existingSurfacePresenter.setDisplayListPlaneIndex((*displayListPlaneIndex));\n\n            auto* externalSurfacePresenterPtr = existingSurfacePresenter.getExternalSurfacePresenterState();\n\n            if (*externalSurfacePresenterPtr != presenterState) {\n                // DisplayState has changed, update it and notify the SurfacePresenterManager\n                auto oldExternalSurfacePresenterState = std::move(*externalSurfacePresenterPtr);\n                *externalSurfacePresenterPtr = presenterState;\n\n                _surfacePresenterManager->setExternalSurfacePresenterState(\n                    existingSurfacePresenter.getId(), presenterState, &oldExternalSurfacePresenterState);\n                *needSynchronousDraw = true;\n            }\n\n            if (i != zIndex) {\n                // zIndex has changed\n                moveSurfacePresenter(existingSurfacePresenter.getId(), i, zIndex, needSynchronousDraw);\n            }\n\n            return true;\n        }\n    }\n\n    return false;\n}\n\nconst SurfacePresenterList& DrawLooperEntry::getSurfacePresenters() const {\n    return _surfacePresenters;\n}\n\nvoid DrawLooperEntry::updateSurfaceForPlane(const CompositorPlane& plane,\n                                            size_t zIndex,\n                                            bool* needSynchronousDraw,\n                                            size_t* displayListPlaneIndex) {\n    auto existingPlanesCount = _surfacePresenters.size();\n\n    if (zIndex >= existingPlanesCount) {\n        createSurfaceForPlane(plane, zIndex, needSynchronousDraw, displayListPlaneIndex);\n        return;\n    }\n\n    switch (plane.getType()) {\n        case CompositorPlaneTypeDrawable:\n            if (!tryReuseDrawableSurface(\n                    plane, zIndex, existingPlanesCount, needSynchronousDraw, displayListPlaneIndex)) {\n                createSurfaceForPlane(plane, zIndex, needSynchronousDraw, displayListPlaneIndex);\n            }\n            break;\n        case CompositorPlaneTypeExternal:\n            if (!tryReuseExternalSurface(\n                    plane, zIndex, existingPlanesCount, needSynchronousDraw, displayListPlaneIndex)) {\n                createSurfaceForPlane(plane, zIndex, needSynchronousDraw, displayListPlaneIndex);\n            }\n            break;\n    }\n}\n\nvoid DrawLooperEntry::onNeedsProcessFrame(LayerRoot& /*root*/) {\n    _listener->onNeedsProcessFrame(*this);\n}\n\nvoid DrawLooperEntry::onDidDraw(LayerRoot& /*root*/,\n                                const Ref<DisplayList>& displayList,\n                                const CompositorPlaneList* planeList) {\n    _listener->onDidDraw(*this, displayList, planeList);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DrawLooperEntry.hpp",
    "content": "//\n//  DrawLooperEntry.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/25/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlaneList.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenterList.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenterManager.hpp\"\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\nnamespace snap::drawing {\n\nclass DrawLooperEntry;\n\nclass DrawLooperEntryListener {\npublic:\n    virtual ~DrawLooperEntryListener() = default;\n\n    virtual SurfacePresenterId createSurfacePresenterId() = 0;\n\n    virtual void onNeedsProcessFrame(DrawLooperEntry& entry) = 0;\n\n    virtual void onDidDraw(DrawLooperEntry& entry,\n                           const Ref<DisplayList>& displayList,\n                           const CompositorPlaneList* planeList) = 0;\n};\n\nclass DrawOperation;\n\nstruct DrawLooperEntryDrawState {\n    bool needsDraw = false;\n    bool prefersSynchronousDraw = false;\n\n    constexpr bool needsSynchronousDraw() const {\n        return needsDraw && prefersSynchronousDraw;\n    }\n};\n\n/**\n The DrawLooperEntry represents a LayerRoot that was added to a DrawLooper.\n It contains a SurfacePresenterManager, which is used to create presenters\n that will display the drawn content of the LayerRoot.\n The entry manages the presenters for the LayerRoot. It will call into the\n SurfacePresenterManager to create or update presenters when needed.\n The entry holds the display list that should be drawn next into the presenter.\n */\nclass DrawLooperEntry : public Valdi::SimpleRefCountable, public LayerRootListener {\npublic:\n    DrawLooperEntry(const Ref<LayerRoot>& layerRoot,\n                    const Ref<SurfacePresenterManager>& surfacePresenterManager,\n                    DrawLooperEntryListener* listener);\n    ~DrawLooperEntry() override;\n\n    bool needsProcessFrameAtTime(TimePoint frameTime) const;\n    DrawLooperEntryDrawState getDrawState() const;\n    bool setPresenterNeedsDraw(SurfacePresenterId id);\n\n    void setDisallowSynchronousDraw(bool disallowSynchronousDraw);\n\n    void enqueueDisplayList(const Ref<DisplayList>& displayList);\n\n    Ref<DrawOperation> makeDrawOperation(bool shouldSwapToNextFrame);\n\n    const Ref<LayerRoot>& getLayerRoot() const;\n\n    bool surfacePresentersNeedUpdate(const CompositorPlaneList& planeList) const;\n    void updateSurfacePresenters(const CompositorPlaneList& planeList);\n    void removeSurfacePresenters();\n\n    bool setDrawableSurfaceForPresenterId(SurfacePresenterId id, const Ref<DrawableSurface>& drawableSurface);\n\n    const SurfacePresenterList& getSurfacePresenters() const;\n\n    void onNeedsProcessFrame(LayerRoot& root) override;\n\n    void onDidDraw(LayerRoot& root, const Ref<DisplayList>& displayList, const CompositorPlaneList* planeList) override;\n\nprivate:\n    Ref<LayerRoot> _layerRoot;\n    Ref<SurfacePresenterManager> _surfacePresenterManager;\n    DrawLooperEntryListener* _listener;\n    SurfacePresenterList _surfacePresenters;\n    Ref<DisplayList> _displayList;\n    bool _disallowSynchronousDraw = false;\n\n    void updateSurfaceForPlane(const CompositorPlane& plane,\n                               size_t zIndex,\n                               bool* needSynchronousDraw,\n                               size_t* displayListPlaneIndex);\n    void createSurfaceForPlane(const CompositorPlane& plane,\n                               size_t zIndex,\n                               bool* needSynchronousDraw,\n                               size_t* displayListPlaneIndex);\n\n    bool tryReuseExternalSurface(const CompositorPlane& plane,\n                                 size_t zIndex,\n                                 size_t planesCount,\n                                 bool* needSynchronousDraw,\n                                 size_t* displayListPlaneIndex);\n    bool tryReuseDrawableSurface(const CompositorPlane& plane,\n                                 size_t zIndex,\n                                 size_t planesCount,\n                                 bool* needSynchronousDraw,\n                                 size_t* displayListPlaneIndex);\n\n    void moveSurfacePresenter(SurfacePresenterId id, size_t fromIndex, size_t toIndex, bool* needSynchronousDraw);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DrawOperation.cpp",
    "content": "//\n//  DrawOperation.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 2/16/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/DrawOperation.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenterManager.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n\nnamespace snap::drawing {\n\nDrawOperation::DrawOperation(const Ref<DisplayList>& displayList,\n                             const Ref<SurfacePresenterManager>& surfacePresenterManager,\n                             SurfacePresenterList&& surfacePresenters)\n    : _displayList(displayList),\n      _surfacePresenterManager(surfacePresenterManager),\n      _surfacePresenters(std::move(surfacePresenters)),\n      _current(_surfacePresenters.begin()) {\n    advance();\n}\n\nDrawOperation::~DrawOperation() = default;\n\nbool DrawOperation::drawForPresenterId(SurfacePresenterId presenterId, DrawableSurfaceCanvas& canvas) {\n    auto* presenter = _surfacePresenters.getForId(presenterId);\n    if (_displayList == nullptr || presenter == nullptr) {\n        return false;\n    }\n\n    _displayList->draw(canvas, presenter->getDisplayListPlaneIndex(), /* shouldClearCanvas */ true);\n\n    return true;\n}\n\nValdi::Result<snap::drawing::GraphicsContext*> DrawOperation::drawNext() {\n    const auto& surfacePresenter = *_current;\n    _current++;\n\n    advance();\n\n    auto drawableSurface = Ref<DrawableSurface>(surfacePresenter.getDrawableSurface());\n\n    if (drawableSurface == nullptr) {\n        return nullptr;\n    }\n\n    VALDI_TRACE(\"SnapDrawing.drawSurface\");\n\n    auto canvasResult = drawableSurface->prepareCanvas();\n\n    if (!canvasResult) {\n        return canvasResult.error().rethrow(\"Failed to prepare canvas on GraphicsContext\");\n    }\n\n    auto displayListSize = _displayList->getSize();\n    auto scaleX = static_cast<Scalar>(canvasResult.value().getWidth()) / displayListSize.width;\n    auto scaleY = static_cast<Scalar>(canvasResult.value().getHeight()) / displayListSize.height;\n\n    _displayList->draw(canvasResult.value(),\n                       surfacePresenter.getDisplayListPlaneIndex(),\n                       scaleX,\n                       scaleY,\n                       /* shouldClearCanvas */ true);\n\n    drawableSurface->flush();\n\n    _surfacePresenterManager->onDrawableSurfacePresenterUpdated(surfacePresenter.getId());\n\n    return drawableSurface->getGraphicsContext();\n}\n\nbool DrawOperation::hasNext() {\n    return _current != _surfacePresenters.end();\n}\n\nvoid DrawOperation::advance() {\n    while (_current != _surfacePresenters.end() && !_current->isDrawable()) {\n        _current++;\n    }\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DrawOperation.hpp",
    "content": "//\n//  DrawOperation.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 2/16/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenterList.hpp\"\n\nnamespace snap::drawing {\n\nclass SurfacePresenterManager;\n\nclass DrawOperation : public Valdi::SimpleRefCountable {\npublic:\n    DrawOperation(const Ref<DisplayList>& displayList,\n                  const Ref<SurfacePresenterManager>& presenterManager,\n                  SurfacePresenterList&& surfacePresenters);\n    ~DrawOperation() override;\n\n    bool drawForPresenterId(SurfacePresenterId presenterId, DrawableSurfaceCanvas& canvas);\n\n    Valdi::Result<snap::drawing::GraphicsContext*> drawNext();\n    bool hasNext();\n\nprivate:\n    Ref<DisplayList> _displayList;\n    Ref<SurfacePresenterManager> _surfacePresenterManager;\n    SurfacePresenterList _surfacePresenters;\n    const SurfacePresenter* _current;\n\n    void advance();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DrawingContext.cpp",
    "content": "//\n//  DrawingContext.cpp\n//  valdi-skia-app\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"snap_drawing/cpp/Utils/BitmapUtils.hpp\"\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/LazyPath.hpp\"\n\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n\nnamespace snap::drawing {\n\nDrawingContext::DrawingContext(Scalar width, Scalar height) : _drawBounds(Rect::makeXYWH(0, 0, width, height)) {}\n\nDrawingContext::~DrawingContext() = default;\n\nLayerContent DrawingContext::finish() {\n    LayerContent content;\n    if (_externalSurface != nullptr) {\n        content.externalSurface = Valdi::makeShared<ExternalSurfaceSnapshot>(std::move(_externalSurface));\n    }\n\n    if (_canvas != nullptr) {\n        content.picture = _recorder.finishRecordingAsPicture();\n    }\n\n    return content;\n}\n\nvoid DrawingContext::drawPaint(const Paint& paint, const BorderRadius& borderRadius, LazyPath& lazyPath) {\n    drawPaint(paint, borderRadius, drawBounds(), lazyPath);\n}\n\nvoid DrawingContext::drawPaint(const Paint& paint,\n                               const BorderRadius& borderRadius,\n                               const Rect& targetRect,\n                               LazyPath& lazyPath) {\n    if (borderRadius.isEmpty()) {\n        drawPaint(paint, targetRect);\n    } else {\n        if (lazyPath.update(targetRect.size())) {\n            borderRadius.applyToPath(targetRect, lazyPath.path());\n        }\n\n        drawPaint(paint, lazyPath.path());\n    }\n}\n\nvoid DrawingContext::drawPaint(const Paint& paint, const Path& path) {\n    if (!path.isEmpty()) {\n        canvas()->drawPath(path.getSkValue(), paint.getSkValue());\n    }\n}\n\nvoid DrawingContext::drawPaint(const Paint& paint, const Rect& targetRect) {\n    canvas()->drawRect(targetRect.getSkValue(), paint.getSkValue());\n}\n\nvoid DrawingContext::drawBitmap(const Valdi::Ref<Valdi::IBitmap>& bitmap, FittingSizeMode fittingSizeMode) {\n    auto imageResult = Image::makeFromBitmap(bitmap, false);\n    if (!imageResult) {\n        return;\n    }\n    auto image = imageResult.moveValue();\n\n    auto imageRect = Rect::makeLTRB(0, 0, static_cast<Scalar>(image->width()), static_cast<Scalar>(image->height()));\n    auto targetRect = drawBounds().makeFittingSize(imageRect.size(), fittingSizeMode);\n\n    drawImage(*image, imageRect, targetRect, nullptr);\n}\n\nvoid DrawingContext::drawImage(const Image& image, const Rect& imageRect, const Rect& targetRect, const Paint* paint) {\n    canvas()->drawImageRect(image.getSkValue(),\n                            imageRect.getSkValue(),\n                            targetRect.getSkValue(),\n                            SkSamplingOptions(),\n                            paint != nullptr ? &paint->getSkValue() : nullptr,\n                            SkCanvas::kStrict_SrcRectConstraint);\n}\n\nvoid DrawingContext::clipPath(const Path& path) {\n    canvas()->clipPath(path.getSkValue(), true);\n}\n\nvoid DrawingContext::clipRect(const Rect& rect) {\n    canvas()->clipRect(rect.getSkValue(), true);\n}\n\nvoid DrawingContext::concat(const Matrix& matrix) {\n    canvas()->concat(matrix.getSkValue());\n}\n\nconst Rect& DrawingContext::drawBounds() const {\n    return _drawBounds;\n}\n\nvoid DrawingContext::drawExternalSurface(const Ref<ExternalSurface>& externalSurface) {\n    SC_ASSERT(_externalSurface == nullptr);\n    _externalSurface = externalSurface;\n}\n\nint DrawingContext::save() {\n    return canvas()->save();\n}\n\nvoid DrawingContext::restore(int count) {\n    canvas()->restoreToCount(count);\n}\n\nSkCanvas* DrawingContext::canvas() {\n    if (_canvas == nullptr) {\n        _canvas = _recorder.beginRecording(_drawBounds.getSkValue());\n    }\n\n    return _canvas;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/DrawingContext.hpp",
    "content": "//\n//  DrawingContext.hpp\n//  valdi-skia-app\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#pragma once\n\n#include \"utils/base/NonCopyable.hpp\"\n\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/LayerContent.hpp\"\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n\n#include \"include/core/SkCanvas.h\"\n#include \"include/core/SkPictureRecorder.h\"\n\n#include <optional>\n\nnamespace snap::drawing {\n\nclass BorderRadius;\nclass LazyPath;\nclass ExternalSurface;\n\nclass DrawingContext : public snap::NonCopyable {\npublic:\n    DrawingContext(Scalar width, Scalar height);\n    ~DrawingContext();\n\n    /**\n     Complete the rendering. This must be called after prepare() has been called.\n     */\n    LayerContent finish();\n\n    /**\n     Draw the paint to the context with the given border radius.\n     */\n    void drawPaint(const Paint& paint, const BorderRadius& borderRadius, LazyPath& lazyPath);\n\n    /**\n     Draw the paint to the context with the given border radius at the given targetRect.\n     */\n    void drawPaint(const Paint& paint, const BorderRadius& borderRadius, const Rect& targetRect, LazyPath& lazyPath);\n\n    /**\n     Draw the paint as a rect to the context at the given targetRect.\n     */\n    void drawPaint(const Paint& paint, const Rect& targetRect);\n\n    /**\n     Draw the paint with the given path\n     */\n    void drawPaint(const Paint& paint, const Path& path);\n\n    /**\n     Draw the bitmap into the current draw bounds, scaling the bitmap with the given FittingSizeMode\n     */\n    void drawBitmap(const Valdi::Ref<Valdi::IBitmap>& bitmap, FittingSizeMode fittingSizeMode);\n\n    /**\n     Draw the image into the given target rect\n     */\n    void drawImage(const Image& image, const Rect& imageRect, const Rect& targetRect, const Paint* paint);\n\n    void drawExternalSurface(const Ref<ExternalSurface>& externalSurface);\n\n    void clipPath(const Path& path);\n\n    void clipRect(const Rect& rect);\n\n    void concat(const Matrix& matrix);\n\n    int save();\n\n    void restore(int count);\n\n    const Rect& drawBounds() const;\n\n    SkCanvas* canvas();\n\nprivate:\n    Rect _drawBounds;\n    SkPictureRecorder _recorder;\n    Ref<ExternalSurface> _externalSurface;\n    SkCanvas* _canvas = nullptr;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/ANativeWindowGraphicsContext.cpp",
    "content": "//\n//  ANativeWindowGraphicsContext.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#if __ANDROID__\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/ANativeWindowGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/EGLUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n#include <GLES/glext.h>\n\n#include \"include/core/SkColorSpace.h\"\n#include \"include/core/SkSurface.h\"\n#include \"include/gpu/ganesh/SkSurfaceGanesh.h\"\n#include \"include/gpu/ganesh/gl/GrGLBackendSurface.h\"\n#include \"include/gpu/ganesh/gl/GrGLDirectContext.h\"\n#include \"include/gpu/ganesh/gl/GrGLInterface.h\"\n#include \"include/gpu/ganesh/gl/egl/GrGLMakeEGLInterface.h\"\n\nnamespace snap::drawing {\n\nclass ANativeWindowDrawableSurface : public DrawableSurface {\npublic:\n    ANativeWindowDrawableSurface(const Ref<ANativeWindowGraphicsContext>& context, ANativeWindow* nativeWindow)\n        : _context(context), _nativeWindow(nativeWindow) {\n        ANativeWindow_acquire(nativeWindow);\n        _width = ANativeWindow_getWidth(nativeWindow);\n        _height = ANativeWindow_getHeight(nativeWindow);\n    }\n\n    ~ANativeWindowDrawableSurface() override {\n        if (_eglContext.getDrawSurface() != EGL_NO_SURFACE) {\n            eglDestroySurface(_eglContext.getDisplay(), _eglContext.getDrawSurface());\n\n            _eglContext.setReadSurface(EGL_NO_SURFACE);\n            _eglContext.setDrawSurface(EGL_NO_SURFACE);\n        }\n\n        if (_nativeWindow) {\n            ANativeWindow_release(_nativeWindow);\n            _nativeWindow = nullptr;\n        }\n    }\n\n    GraphicsContext* getGraphicsContext() override {\n        return _context.get();\n    }\n\n    Valdi::Result<DrawableSurfaceCanvas> prepareCanvas() override {\n        auto glObjectsResult = _context->getGLObjects();\n        if (!glObjectsResult) {\n            SC_ASSERT_FAIL(glObjectsResult.error().toString().c_str());\n            return glObjectsResult.moveError();\n        }\n\n        auto glObjects = glObjectsResult.moveValue();\n\n        _eglContext.setDisplay(glObjects.eGLDisplay);\n        _eglContext.setContext(glObjects.eGLContext);\n\n        if (_eglContext.getDrawSurface() == EGL_NO_SURFACE) {\n            auto* surfaceAndroid =\n                eglCreateWindowSurface(_eglContext.getDisplay(), glObjects.eGLConfig, _nativeWindow, nullptr);\n\n            if (surfaceAndroid == EGL_NO_SURFACE) {\n                return EGLContextWrapper::getLastError(\"Could not create GL surface\");\n            }\n\n            _eglContext.setDrawSurface(surfaceAndroid);\n            _eglContext.setReadSurface(surfaceAndroid);\n        }\n\n        auto result = makeCurrent();\n        if (!result) {\n            return result.moveError();\n        }\n\n        if (_surface == nullptr) {\n            int fbBOID;\n            glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &fbBOID);\n\n            GrGLFramebufferInfo fbInfo;\n            fbInfo.fFBOID = static_cast<GrGLint>(fbBOID);\n            fbInfo.fFormat = GL_RGBA8_OES;\n\n            auto backendRT =\n                GrBackendRenderTargets::MakeGL(_width, _height, glObjects.sampleCount, glObjects.stencilBits, fbInfo);\n\n            SkSurfaceProps surfaceProps;\n\n            _surface = SkSurfaces::WrapBackendRenderTarget(glObjects.grContext.get(),\n                                                           backendRT,\n                                                           kBottomLeft_GrSurfaceOrigin,\n                                                           kRGBA_8888_SkColorType,\n                                                           nullptr,\n                                                           &surfaceProps);\n        }\n\n        return DrawableSurfaceCanvas(_surface.get(), _width, _height);\n    }\n\n    void flush() override {\n        if (_surface != nullptr) {\n            GLDrawableSurface::flushSurface(_surface.get());\n        }\n\n        swapBuffers();\n\n        releaseCurrent();\n    }\n\n    Valdi::Result<Valdi::Void> makeCurrent() {\n        if (!_eglContext.makeCurrent()) {\n            return EGLContextWrapper::getLastError(\"Failed to make EGL context current\");\n        }\n        return Valdi::Void();\n    }\n\n    bool releaseCurrent() {\n        return _eglContext.releaseCurrent();\n    }\n\n    void swapBuffers() {\n        if (_eglContext.getDrawSurface() != EGL_NO_SURFACE) {\n            eglSwapBuffers(_eglContext.getDisplay(), _eglContext.getDrawSurface());\n        }\n    }\n\nprivate:\n    Ref<ANativeWindowGraphicsContext> _context;\n    ANativeWindow* _nativeWindow;\n    EGLContextWrapper _eglContext;\n    sk_sp<SkSurface> _surface;\n\n    int _width;\n    int _height;\n};\n\nANativeWindowGraphicsContext::ANativeWindowGraphicsContext(const DisplayParams& displayParams,\n                                                           const Ref<GrGraphicsContextOptions>& options)\n    : GraphicsContext(), _displayParams(displayParams), _options(options) {}\n\nANativeWindowGraphicsContext::~ANativeWindowGraphicsContext() {\n    std::lock_guard<Valdi::Mutex> guard(_mutex);\n\n    if (_glObjects) {\n        auto& glObjects = _glObjects.value();\n\n        if (glObjects.grContext != nullptr) {\n            glObjects.grContext->abandonContext();\n            glObjects.grContext = nullptr;\n        }\n\n        if (glObjects.eGLContext != EGL_NO_CONTEXT) {\n            eglDestroyContext(glObjects.eGLDisplay, glObjects.eGLContext);\n            glObjects.eGLContext = EGL_NO_CONTEXT;\n        }\n\n        if (glObjects.eGLDefaultSurface != EGL_NO_SURFACE) {\n            eglDestroySurface(glObjects.eGLDisplay, glObjects.eGLDefaultSurface);\n            glObjects.eGLDefaultSurface = EGL_NO_SURFACE;\n        }\n\n        if (glObjects.eGLDisplay != EGL_NO_DISPLAY) {\n            eglTerminate(glObjects.eGLDisplay);\n            glObjects.eGLDisplay = EGL_NO_DISPLAY;\n        }\n    }\n}\n\nvoid ANativeWindowGraphicsContext::setResourceCacheLimit(size_t resourceCacheLimitBytes) {\n    auto currentContext = makeContextCurrent();\n    if (currentContext) {\n        GrGraphicsContext::setGrResourceCacheLimit(_glObjects->grContext, resourceCacheLimitBytes);\n        currentContext->releaseCurrent();\n    }\n}\n\nvoid ANativeWindowGraphicsContext::performCleanup(bool shouldPurgeScratchResources,\n                                                  std::chrono::seconds secondsNotUsed) {\n    auto currentContext = makeContextCurrent();\n    if (currentContext) {\n        GrGraphicsContext::performGrCleanup(_glObjects->grContext, shouldPurgeScratchResources, secondsNotUsed);\n        currentContext->releaseCurrent();\n    }\n}\n\nstd::optional<EGLContextWrapper> ANativeWindowGraphicsContext::makeContextCurrent() {\n    auto glObjectsResult = getGLObjects();\n    if (!glObjectsResult) {\n        return std::nullopt;\n    }\n\n    auto newGLContext = EGLContextWrapper(\n        glObjectsResult.value().eGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, glObjectsResult.value().eGLContext);\n\n    if (!newGLContext.makeCurrent()) {\n        return std::nullopt;\n    }\n\n    return {newGLContext};\n}\n\nValdi::Error ANativeWindowGraphicsContext::onGLObjectsError(GLObjects& glObjects, const char* message) {\n    auto error = EGLContextWrapper::getLastError(message);\n\n    if (glObjects.eGLContext != EGL_NO_CONTEXT) {\n        eglDestroyContext(glObjects.eGLDisplay, glObjects.eGLContext);\n        glObjects.eGLContext = EGL_NO_CONTEXT;\n    }\n\n    if (glObjects.eGLDefaultSurface != EGL_NO_SURFACE) {\n        eglDestroySurface(glObjects.eGLDisplay, glObjects.eGLDefaultSurface);\n        glObjects.eGLDefaultSurface = EGL_NO_SURFACE;\n    }\n\n    if (glObjects.eGLDisplay != EGL_NO_DISPLAY) {\n        eglTerminate(glObjects.eGLDisplay);\n        glObjects.eGLDisplay = EGL_NO_DISPLAY;\n    }\n\n    return error;\n}\n\nValdi::Error ANativeWindowGraphicsContext::onBindAPIError(GLObjects& glObjects) {\n    return onGLObjectsError(glObjects, \"Failed to bind GL API\");\n}\n\nValdi::Error ANativeWindowGraphicsContext::onGetDefaultDisplayError(GLObjects& glObjects) {\n    return onGLObjectsError(glObjects, \"Failed to retrieve default display\");\n}\n\nValdi::Error ANativeWindowGraphicsContext::onInitializeError(GLObjects& glObjects) {\n    return onGLObjectsError(glObjects, \"Failed to initialize eGLDisplay\");\n}\n\nValdi::Error ANativeWindowGraphicsContext::onChooseConfigError(GLObjects& glObjects) {\n    return onGLObjectsError(glObjects, \"Could not resolve GL config\");\n}\n\nValdi::Error ANativeWindowGraphicsContext::onCreateContextError(GLObjects& glObjects) {\n    return onGLObjectsError(glObjects, \"Could not create GL context\");\n}\n\nValdi::Error ANativeWindowGraphicsContext::onCreateDefaultSurfaceError(GLObjects& glObjects) {\n    return onGLObjectsError(glObjects, \"Could not create default surface during initialization\");\n}\n\nValdi::Error ANativeWindowGraphicsContext::onMakeCurrentError(GLObjects& glObjects) {\n    return onGLObjectsError(glObjects, \"Could not make GL current during initialization\");\n}\n\nValdi::Error ANativeWindowGraphicsContext::onGrContextError(GLObjects& glObjects) {\n    return onGLObjectsError(glObjects, \"Failed to create GrContext\");\n}\n\nValdi::Result<ANativeWindowGraphicsContext::GLObjects> ANativeWindowGraphicsContext::getGLObjects() {\n    std::lock_guard<Valdi::Mutex> guard(_mutex);\n\n    if (_glObjects) {\n        return _glObjects.value();\n    }\n\n    GLObjects glObjects;\n\n    if (eglBindAPI(EGL_OPENGL_ES_API) == 0) {\n        return onBindAPIError(glObjects);\n    }\n\n    glObjects.eGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);\n\n    if (glObjects.eGLDisplay == EGL_NO_DISPLAY) {\n        return onGetDefaultDisplayError(glObjects);\n    }\n\n    EGLint majorVersion;\n    EGLint minorVersion;\n    if (eglInitialize(glObjects.eGLDisplay, &majorVersion, &minorVersion) != EGL_TRUE) {\n        return onInitializeError(glObjects);\n    }\n\n    EGLint numConfigs = 0;\n    EGLint eglSampleCnt = _displayParams.mSAASampleCount > 1 ? static_cast<EGLint>(_displayParams.mSAASampleCount) : 0;\n\n    const EGLint configAttribs[] = {EGL_SURFACE_TYPE,\n                                    EGL_WINDOW_BIT,\n                                    EGL_RENDERABLE_TYPE,\n                                    EGL_OPENGL_ES2_BIT,\n                                    EGL_RED_SIZE,\n                                    8,\n                                    EGL_GREEN_SIZE,\n                                    8,\n                                    EGL_BLUE_SIZE,\n                                    8,\n                                    EGL_ALPHA_SIZE,\n                                    8,\n                                    EGL_STENCIL_SIZE,\n                                    8,\n                                    EGL_SAMPLE_BUFFERS,\n                                    (eglSampleCnt > 1) ? 1 : 0,\n                                    EGL_SAMPLES,\n                                    eglSampleCnt,\n                                    EGL_NONE};\n\n    eglChooseConfig(glObjects.eGLDisplay, configAttribs, &glObjects.eGLConfig, 1, &numConfigs);\n    if (numConfigs == 0) {\n        return onChooseConfigError(glObjects);\n    }\n\n    static const EGLint kEGLContextAttribsForOpenGLES[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};\n    glObjects.eGLContext =\n        eglCreateContext(glObjects.eGLDisplay, glObjects.eGLConfig, EGL_NO_CONTEXT, kEGLContextAttribsForOpenGLES);\n    if (glObjects.eGLContext == EGL_NO_CONTEXT) {\n        return onCreateContextError(glObjects);\n    }\n\n    eglGetConfigAttrib(glObjects.eGLDisplay, glObjects.eGLConfig, EGL_STENCIL_SIZE, &glObjects.stencilBits);\n    eglGetConfigAttrib(glObjects.eGLDisplay, glObjects.eGLConfig, EGL_SAMPLES, &glObjects.sampleCount);\n    glObjects.sampleCount = std::max(glObjects.sampleCount, 1);\n\n    static const EGLint kEGLPBufferAttributes[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};\n    glObjects.eGLDefaultSurface =\n        eglCreatePbufferSurface(glObjects.eGLDisplay, glObjects.eGLConfig, kEGLPBufferAttributes);\n    if (glObjects.eGLDefaultSurface == EGL_NO_SURFACE) {\n        return onCreateDefaultSurfaceError(glObjects);\n    }\n\n    eglSwapInterval(glObjects.eGLDisplay, _displayParams.disableVsync ? 0 : 1);\n\n    if (eglMakeCurrent(\n            glObjects.eGLDisplay, glObjects.eGLDefaultSurface, glObjects.eGLDefaultSurface, glObjects.eGLContext) ==\n        EGL_FALSE) {\n        return onMakeCurrentError(glObjects);\n    }\n\n    sk_sp<const GrGLInterface> glInterface = GrGLInterfaces::MakeEGL();\n    if (!glInterface) {\n        eglMakeCurrent(glObjects.eGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);\n        return Valdi::Error(\"Failed to create EGL interface\");\n    }\n\n    glObjects.grContext = GrDirectContexts::MakeGL(std::move(glInterface), _options->getGrContextOptions());\n\n    eglMakeCurrent(glObjects.eGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);\n\n    if (glObjects.grContext == nullptr) {\n        return onGrContextError(glObjects);\n    }\n\n    _glObjects = std::move(glObjects);\n\n    return _glObjects.value();\n}\n\nRef<ANativeWindowGraphicsContext> ANativeWindowGraphicsContext::create(const DisplayParams& displayParams,\n                                                                       const Ref<GrGraphicsContextOptions>& options) {\n    return Valdi::makeShared<ANativeWindowGraphicsContext>(displayParams, options);\n}\n\nRef<DrawableSurface> ANativeWindowGraphicsContext::createSurfaceForNativeWindow(ANativeWindow* nativeWindow) {\n    return Valdi::makeShared<ANativeWindowDrawableSurface>(Valdi::strongSmallRef(this), nativeWindow);\n}\n\nint64_t ANativeWindowGraphicsContext::getMaxRenderTargetSize() {\n    auto glObjectsResult = getGLObjects();\n    if (!glObjectsResult) {\n        return -1;\n    }\n    return glObjectsResult.value().grContext->maxRenderTargetSize();\n}\n\nANativeWindowGraphicsContext::GLObjects::GLObjects() : eGLDisplay(EGL_NO_DISPLAY), eGLContext(EGL_NO_CONTEXT) {}\n\n} // namespace snap::drawing\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/ANativeWindowGraphicsContext.hpp",
    "content": "//\n//  ANativeWindowGraphicsContext.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#pragma once\n\n#include <android/native_window_jni.h>\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GLGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GrGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include <optional>\n\nnamespace snap::drawing {\n\nstruct DisplayParams {\n    DisplayParams() = default;\n\n    int mSAASampleCount = 1;\n    bool disableVsync = false;\n};\n\nclass EGLContextWrapper;\n\nclass ANativeWindowDrawableSurface;\n\nclass ANativeWindowGraphicsContext : public GraphicsContext {\npublic:\n    ANativeWindowGraphicsContext(const DisplayParams& displayParams, const Ref<GrGraphicsContextOptions>& options);\n    ~ANativeWindowGraphicsContext() override;\n\n    void setResourceCacheLimit(size_t resourceCacheLimitBytes) override;\n\n    void performCleanup(bool shouldPurgeScratchResources, std::chrono::seconds secondsNotUsed) override;\n\n    Ref<DrawableSurface> createSurfaceForNativeWindow(ANativeWindow* nativeWindow);\n\n    int64_t getMaxRenderTargetSize();\n\n    static Ref<ANativeWindowGraphicsContext> create(const DisplayParams& displayParams,\n                                                    const Ref<GrGraphicsContextOptions>& options);\n\nprivate:\n    struct GLObjects {\n        EGLDisplay eGLDisplay;\n        EGLContext eGLContext;\n        EGLSurface eGLDefaultSurface = EGL_NO_SURFACE;\n        EGLConfig eGLConfig = nullptr;\n        int sampleCount = 0;\n        int stencilBits = 0;\n        sk_sp<GrDirectContext> grContext;\n\n        GLObjects();\n    };\n\n    Valdi::Mutex _mutex;\n    DisplayParams _displayParams;\n    Ref<GrGraphicsContextOptions> _options;\n    std::optional<GLObjects> _glObjects;\n\n    Valdi::Result<GLObjects> getGLObjects();\n    static Valdi::Error onGLObjectsError(GLObjects& glObjects, const char* message);\n    static Valdi::Error onBindAPIError(GLObjects& glObjects);\n    static Valdi::Error onGetDefaultDisplayError(GLObjects& glObjects);\n    static Valdi::Error onInitializeError(GLObjects& glObjects);\n    static Valdi::Error onChooseConfigError(GLObjects& glObjects);\n    static Valdi::Error onCreateContextError(GLObjects& glObjects);\n    static Valdi::Error onCreateDefaultSurfaceError(GLObjects& glObjects);\n    static Valdi::Error onMakeCurrentError(GLObjects& glObjects);\n    static Valdi::Error onGrContextError(GLObjects& glObjects);\n\n    friend ANativeWindowDrawableSurface;\n\n    std::optional<EGLContextWrapper> makeContextCurrent();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/BitmapGraphicsContext.cpp",
    "content": "//\n//  BitmapGraphicsContext.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/BitmapGraphicsContext.hpp\"\n#include \"include/core/SkSurface.h\"\n#include \"snap_drawing/cpp/Utils/BitmapUtils.hpp\"\n\nnamespace snap::drawing {\n\nclass BitmapDrawableSurface : public DrawableSurface {\npublic:\n    BitmapDrawableSurface(const Valdi::Ref<Valdi::IBitmap>& bitmap,\n                          const Valdi::BitmapInfo& bitmapInfo,\n                          void* bitmapBytes)\n        : _bitmap(bitmap),\n          _bitmapInfo(bitmapInfo),\n          _imageInfo(toSkiaImageInfo(_bitmapInfo)),\n          _bitmapBytes(bitmapBytes) {}\n\n    ~BitmapDrawableSurface() override {\n        releaseSurface();\n    }\n\n    GraphicsContext* getGraphicsContext() override {\n        return nullptr;\n    }\n\n    Valdi::Result<DrawableSurfaceCanvas> prepareCanvas() override {\n        if (_surface == nullptr) {\n            if (_bitmap != nullptr) {\n                auto* bytes = _bitmap->lockBytes();\n\n                if (bytes == nullptr) {\n                    return Valdi::Error(\"Failed to lock bytes from Bitmap\");\n                }\n\n                _surface = SkSurfaces::WrapPixels(_imageInfo, bytes, _bitmapInfo.rowBytes);\n\n                if (_surface == nullptr) {\n                    _bitmap->unlockBytes();\n                    return Valdi::Error(\"Failed to create Surface\");\n                }\n            } else if (_bitmapBytes != nullptr) {\n                _surface = SkSurfaces::WrapPixels(_imageInfo, _bitmapBytes, _bitmapInfo.rowBytes);\n\n                if (_surface == nullptr) {\n                    return Valdi::Error(\"Failed to create Surface\");\n                }\n            } else {\n                _surface = SkSurfaces::Raster(_imageInfo);\n\n                if (_surface == nullptr) {\n                    return Valdi::Error(\"Failed to create Surface\");\n                }\n            }\n        }\n\n        return DrawableSurfaceCanvas(_surface.get(), _bitmapInfo.width, _bitmapInfo.height);\n    }\n\n    void flush() override {\n        releaseSurface();\n    }\n\n    void releaseSurface() {\n        if (_surface != nullptr) {\n            _surface = nullptr;\n\n            if (_bitmap != nullptr) {\n                _bitmap->unlockBytes();\n            }\n        }\n    }\n\nprivate:\n    Valdi::Ref<Valdi::IBitmap> _bitmap;\n    Valdi::BitmapInfo _bitmapInfo;\n    SkImageInfo _imageInfo;\n    sk_sp<SkSurface> _surface;\n    void* _bitmapBytes = nullptr;\n};\n\nBitmapGraphicsContext::BitmapGraphicsContext() = default;\n\nvoid BitmapGraphicsContext::setResourceCacheLimit(size_t /*resourceCacheLimitBytes*/) {}\n\nvoid BitmapGraphicsContext::performCleanup(bool /*shouldPurgeScratchResources*/,\n                                           std::chrono::seconds /*secondsNotUsed*/) {}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nRef<DrawableSurface> BitmapGraphicsContext::createBitmapSurface(const Valdi::Ref<Valdi::IBitmap>& bitmap) {\n    return Valdi::makeShared<BitmapDrawableSurface>(bitmap, bitmap->getInfo(), nullptr);\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nRef<DrawableSurface> BitmapGraphicsContext::createBitmapSurface(const Valdi::BitmapInfo& bitmapInfo) {\n    return Valdi::makeShared<BitmapDrawableSurface>(nullptr, bitmapInfo, nullptr);\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nRef<DrawableSurface> BitmapGraphicsContext::createBitmapSurface(const Valdi::BitmapInfo& bitmapInfo,\n                                                                void* bitmapBytes) {\n    return Valdi::makeShared<BitmapDrawableSurface>(nullptr, bitmapInfo, bitmapBytes);\n}\n\nValdi::Result<Valdi::BytesView> BitmapGraphicsContext::bitmapToPNG(const Valdi::Ref<Valdi::IBitmap>& bitmap) {\n    BitmapGraphicsContext bitmapContext;\n    auto surface = bitmapContext.createBitmapSurface(bitmap);\n\n    auto canvasResult = surface->prepareCanvas();\n    if (!canvasResult) {\n        return canvasResult.moveError();\n    }\n\n    auto image = canvasResult.value().snapshot();\n    if (!image) {\n        return image.moveError();\n    }\n\n    return image.value()->toPNG();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/BitmapGraphicsContext.hpp",
    "content": "//\n//  BitmapGraphicsContext.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n\nnamespace snap::drawing {\n\nclass BitmapGraphicsContext : public GraphicsContext {\npublic:\n    BitmapGraphicsContext();\n\n    void setResourceCacheLimit(size_t resourceCacheLimitBytes) override;\n\n    void performCleanup(bool shouldPurgeScratchResources, std::chrono::seconds secondsNotUsed) override;\n\n    /**\n     Creates a surface that will draw directly into the given bitmap.\n     */\n    Ref<DrawableSurface> createBitmapSurface(const Valdi::Ref<Valdi::IBitmap>& bitmap);\n\n    /**\n     Creates a BitmapGraphicsContext that will allocate a bitmap from the given BitmapInfo\n     and draw into it.\n     */\n    Ref<DrawableSurface> createBitmapSurface(const Valdi::BitmapInfo& bitmapInfo);\n\n    /**\n     Creates a BitmapGraphicsContext that will draw directly into the given bitmap bytes.\n     */\n    Ref<DrawableSurface> createBitmapSurface(const Valdi::BitmapInfo& bitmapInfo, void* bitmapBytes);\n\n    /**\n     Convenience method to create a PNG from a Bitmap\n     */\n    static Valdi::Result<Valdi::BytesView> bitmapToPNG(const Valdi::Ref<Valdi::IBitmap>& bitmap);\n\nprivate:\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/EGLUtils.cpp",
    "content": "//\n//  EGLUtils.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 6/2/22.\n//\n\n#if __ANDROID__\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/EGLUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\nnamespace snap::drawing {\n\nEGLContextWrapper::EGLContextWrapper(EGLDisplay display,\n                                     EGLSurface drawSurface,\n                                     EGLSurface readSurface,\n                                     EGLContext context)\n    : _display(display), _drawSurface(drawSurface), _readSurface(readSurface), _context(context) {}\n\nEGLContextWrapper::EGLContextWrapper()\n    : _display(EGL_NO_DISPLAY), _drawSurface(EGL_NO_SURFACE), _readSurface(EGL_NO_SURFACE), _context(EGL_NO_CONTEXT) {}\n\nValdi::Error EGLContextWrapper::getLastError(const char* errorMessagePrefix) {\n    auto errorCode = eglGetError();\n    // TODO(simon): Translate error code to string?\n    return Valdi::Error(STRING_FORMAT(\"{}: EGL error code {}\", errorMessagePrefix, static_cast<int>(errorCode)));\n}\n\nbool EGLContextWrapper::makeCurrent() {\n    return eglMakeCurrent(_display, _drawSurface, _readSurface, _context) != EGL_FALSE;\n}\n\nbool EGLContextWrapper::releaseCurrent() {\n    return EGLContextWrapper(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT).makeCurrent();\n}\n\nEGLDisplay EGLContextWrapper::getDisplay() const {\n    return _display;\n}\n\nvoid EGLContextWrapper::setDisplay(EGLDisplay display) {\n    _display = display;\n}\n\nEGLSurface EGLContextWrapper::getDrawSurface() const {\n    return _drawSurface;\n}\n\nvoid EGLContextWrapper::setDrawSurface(EGLSurface drawSurface) {\n    _drawSurface = drawSurface;\n}\n\nEGLSurface EGLContextWrapper::getReadSurface() const {\n    return _readSurface;\n}\n\nvoid EGLContextWrapper::setReadSurface(EGLSurface readSurface) {\n    _readSurface = readSurface;\n}\n\nEGLContext EGLContextWrapper::getContext() const {\n    return _context;\n}\n\nvoid EGLContextWrapper::setContext(EGLContext context) {\n    _context = context;\n}\n\nEGLContextWrapper EGLContextWrapper::current() {\n    return EGLContextWrapper(\n        eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW), eglGetCurrentSurface(EGL_READ), eglGetCurrentContext());\n}\n\nstd::ostream& operator<<(std::ostream& os, const EGLContextWrapper& ctx) {\n    return os << \"EGLDisplay: \" << reinterpret_cast<void*>(ctx.getDisplay())\n              << \", DrawSurface: \" << reinterpret_cast<void*>(ctx.getDrawSurface())\n              << \", ReadSurface: \" << reinterpret_cast<void*>(ctx.getReadSurface())\n              << \", Context: \" << reinterpret_cast<void*>(ctx.getContext());\n}\n\nEGLContextScope::EGLContextScope() = default;\nEGLContextScope::EGLContextScope(EGLContextScope&& other) noexcept\n    : _oldContext(other._oldContext), _valid(other._valid) {\n    other._oldContext = EGLContextWrapper();\n    other._valid = false;\n}\nEGLContextScope::EGLContextScope(EGLContextWrapper context) : EGLContextScope(EGLContextWrapper::current(), context) {}\n\nEGLContextScope::EGLContextScope(EGLContextWrapper oldContext, EGLContextWrapper context)\n    : _oldContext(oldContext), _valid(context.makeCurrent()) {}\n\nEGLContextScope::~EGLContextScope() {\n    if (_valid) {\n        _oldContext.makeCurrent();\n    }\n}\n\nEGLContextScope& EGLContextScope::operator=(EGLContextScope&& other) noexcept {\n    if (this != &other) {\n        _oldContext = other._oldContext;\n        _valid = other._valid;\n\n        other._oldContext = EGLContextWrapper();\n        other._valid = false;\n    }\n\n    return *this;\n}\n\nEGLContextScope::operator bool() const noexcept {\n    return _valid;\n}\n\n} // namespace snap::drawing\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/EGLUtils.hpp",
    "content": "//\n//  EGLUtils.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 6/2/22.\n//\n\n#pragma once\n\n#include <EGL/egl.h>\n#include <GLES/gl.h>\n\n#include \"utils/base/NonCopyable.hpp\"\n#include \"valdi_core/cpp/Utils/Error.hpp\"\n\n#include <iostream>\n\nnamespace snap::drawing {\n\nclass EGLContextWrapper {\npublic:\n    EGLContextWrapper(EGLDisplay display, EGLSurface drawSurface, EGLSurface readSurface, EGLContext context);\n    EGLContextWrapper();\n\n    bool makeCurrent();\n    bool releaseCurrent();\n\n    EGLDisplay getDisplay() const;\n    void setDisplay(EGLDisplay display);\n\n    EGLSurface getDrawSurface() const;\n    void setDrawSurface(EGLSurface drawSurface);\n\n    EGLSurface getReadSurface() const;\n    void setReadSurface(EGLSurface readSurface);\n\n    EGLContext getContext() const;\n    void setContext(EGLContext context);\n\n    static EGLContextWrapper current();\n\n    static Valdi::Error getLastError(const char* errorMessagePrefix);\n\nprivate:\n    EGLDisplay _display;\n    EGLSurface _drawSurface;\n    EGLSurface _readSurface;\n    EGLContext _context;\n};\n\nstd::ostream& operator<<(std::ostream& os, const EGLContextWrapper& ctx);\n\nclass EGLContextScope : public snap::NonCopyable {\npublic:\n    EGLContextScope();\n    EGLContextScope(EGLContextScope&& other) noexcept;\n    explicit EGLContextScope(EGLContextWrapper context);\n    EGLContextScope(EGLContextWrapper oldContext, EGLContextWrapper newContext);\n\n    ~EGLContextScope();\n\n    EGLContextScope& operator=(EGLContextScope&& other) noexcept;\n\n    explicit operator bool() const noexcept;\n\nprivate:\n    EGLContextWrapper _oldContext;\n    bool _valid = false;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/GLGraphicsContext.cpp",
    "content": "//\n//  GLGraphicsContext.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 5/27/22.\n//\n\n#ifdef SK_GL\n\n#include \"include/core/SkColorSpace.h\"\n#include \"include/core/SkSurface.h\"\n#include \"include/gpu/ganesh/SkSurfaceGanesh.h\"\n#include \"include/gpu/ganesh/gl/GrGLBackendSurface.h\"\n#include \"include/gpu/ganesh/gl/GrGLDirectContext.h\"\n#include \"include/gpu/ganesh/gl/GrGLInterface.h\"\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/EGLUtils.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GLGraphicsContext.hpp\"\n\n#include \"snap_drawing/cpp/Utils/BitmapUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n\n#include <GLES/glext.h>\n\n#include <EGL/egl.h>\n#include <EGL/eglext.h>\n#include <GLES/gl.h>\n#include <GLES/glext.h>\n\nnamespace snap::drawing {\n\nGLDrawableSurface::GLDrawableSurface(const Ref<GLGraphicsContext>& context,\n                                     const GrBackendTexture& backendTexture,\n                                     int sampleCount,\n                                     Valdi::ColorType colorType,\n                                     bool isOwned)\n    : _context(context),\n      _backendTexture(backendTexture),\n      _sampleCount(sampleCount),\n      _colorType(toSkiaColorType(colorType)),\n      _owned(isOwned) {}\n\nGLDrawableSurface::~GLDrawableSurface() {\n    if (_owned) {\n        _context->getGrContext().deleteBackendTexture(_backendTexture);\n    }\n}\n\nGraphicsContext* GLDrawableSurface::getGraphicsContext() {\n    return _context.get();\n}\n\nValdi::Result<DrawableSurfaceCanvas> GLDrawableSurface::prepareCanvas() {\n    _context->getGrContext().resetContext(kTextureBinding_GrGLBackendState);\n\n    if (_surface == nullptr) {\n        SkSurfaceProps surfaceProps;\n\n        _surface = SkSurfaces::WrapBackendTexture(&_context->getGrContext(),\n                                                  _backendTexture,\n                                                  kBottomLeft_GrSurfaceOrigin,\n                                                  _sampleCount,\n                                                  _colorType,\n                                                  nullptr,\n                                                  &surfaceProps);\n\n        if (_surface == nullptr) {\n            return Valdi::Error(\"Failed to create Surface from Backend Texture\");\n        }\n    }\n\n    return DrawableSurfaceCanvas(_surface.get(), getTextureWidth(), getTextureHeight());\n}\n\nvoid GLDrawableSurface::flush() {\n    if (_surface != nullptr) {\n        GLDrawableSurface::flushSurface(_surface.get());\n        _surface = nullptr;\n    }\n}\n\nvoid GLDrawableSurface::flushSurface(SkSurface* surface) {\n    auto direct = surface->recordingContext() ? surface->recordingContext()->asDirectContext() : nullptr;\n    if (!direct) {\n        return;\n    }\n\n    direct->flushAndSubmit();\n}\n\nGrGLuint GLDrawableSurface::getTextureId() const {\n    GrGLTextureInfo textureInfo;\n    GrBackendTextures::GetGLTextureInfo(_backendTexture, &textureInfo);\n    return textureInfo.fID;\n}\n\nint GLDrawableSurface::getTextureWidth() const {\n    return _backendTexture.width();\n}\n\nint GLDrawableSurface::getTextureHeight() const {\n    return _backendTexture.height();\n}\n\nGLGraphicsContext::GLGraphicsContext(const sk_sp<GrDirectContext>& grContext,\n                                     const Ref<GrGraphicsContextOptions>& options)\n    : GrGraphicsContext(grContext, options) {}\n\nGLGraphicsContext::~GLGraphicsContext() = default;\n\nValdi::Result<Ref<GLGraphicsContext>> GLGraphicsContext::create(const Ref<GrGraphicsContextOptions>& options) {\n    auto grContext = GrDirectContexts::MakeGL(nullptr, options->getGrContextOptions());\n    if (grContext == nullptr) {\n        return Valdi::Error(\"Failed to create GLGraphicsContext\");\n    }\n\n    return Valdi::makeShared<GLGraphicsContext>(grContext, options);\n}\n\nRef<GLDrawableSurface> GLGraphicsContext::createSurface(int width,\n                                                        int height,\n                                                        Valdi::ColorType colorType,\n                                                        int sampleCount) {\n    auto backendTexture = getGrContext().createBackendTexture(\n        width, height, toSkiaColorType(colorType), skgpu::Mipmapped::kYes, GrRenderable::kYes);\n\n    return Valdi::makeShared<GLDrawableSurface>(\n        Valdi::strongSmallRef(this), backendTexture, sampleCount, colorType, true);\n}\n\nRef<GLDrawableSurface> GLGraphicsContext::createSurfaceWrappingTexture(GrGLuint textureId,\n                                                                       int width,\n                                                                       int height,\n                                                                       Valdi::ColorType colorType,\n                                                                       int sampleCount,\n                                                                       GrGLenum format,\n                                                                       GrGLenum target) {\n    GrGLTextureInfo textureInfo;\n    textureInfo.fFormat = format;\n    textureInfo.fTarget = target;\n    textureInfo.fID = textureId;\n\n    auto backendTexture = GrBackendTextures::MakeGL(width, height, skgpu::Mipmapped::kNo, textureInfo);\n\n    return Valdi::makeShared<GLDrawableSurface>(\n        Valdi::strongSmallRef(this), backendTexture, sampleCount, colorType, false);\n}\n\n} // namespace snap::drawing\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/GLGraphicsContext.hpp",
    "content": "//\n//  GLGraphicsContext.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 5/27/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GrGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n\n#include \"include/gpu/ganesh/GrBackendSurface.h\"\n#include \"include/gpu/ganesh/gl/GrGLTypes.h\"\n\n#include <EGL/egl.h>\n#include <GLES/gl.h>\n\nnamespace snap::drawing {\n\nclass GLGraphicsContext;\n\nclass GLDrawableSurface : public DrawableSurface {\npublic:\n    GLDrawableSurface(const Ref<GLGraphicsContext>& context,\n                      const GrBackendTexture& backendTexture,\n                      int sampleCount,\n                      Valdi::ColorType colorType,\n                      bool isOwned);\n    ~GLDrawableSurface() override;\n\n    GraphicsContext* getGraphicsContext() override;\n\n    Valdi::Result<DrawableSurfaceCanvas> prepareCanvas() override;\n\n    void flush() override;\n\n    GrGLuint getTextureId() const;\n    int getTextureWidth() const;\n    int getTextureHeight() const;\n\n    static void flushSurface(SkSurface* surface);\n\nprivate:\n    Ref<GLGraphicsContext> _context;\n    sk_sp<SkSurface> _surface;\n    GrBackendTexture _backendTexture;\n    int _sampleCount;\n    SkColorType _colorType;\n    bool _owned;\n};\n\nclass GLGraphicsContext : public GrGraphicsContext {\npublic:\n    GLGraphicsContext(const sk_sp<GrDirectContext>& grContext, const Ref<GrGraphicsContextOptions>& options);\n    ~GLGraphicsContext() override;\n\n    Ref<GLDrawableSurface> createSurface(int width, int height, Valdi::ColorType colorType, int sampleCount);\n\n    Ref<GLDrawableSurface> createSurfaceWrappingTexture(GrGLuint textureId,\n                                                        int width,\n                                                        int height,\n                                                        Valdi::ColorType colorType,\n                                                        int sampleCount,\n                                                        GrGLenum format,\n                                                        GrGLenum target);\n\n    static Valdi::Result<Ref<GLGraphicsContext>> create(const Ref<GrGraphicsContextOptions>& options);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/GrGraphicsContext.cpp",
    "content": "//\n//  GrGraphicsContext.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#ifdef SK_GANESH\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GrGraphicsContext.hpp\"\n#include \"include/core/SkExecutor.h\"\n#include <iostream>\n\nnamespace snap::drawing {\n\nGrGraphicsContextOptions::GrGraphicsContextOptions() : GrGraphicsContextOptions(nullptr) {};\n\nGrGraphicsContextOptions::~GrGraphicsContextOptions() = default;\n\nGrGraphicsContextOptions::GrGraphicsContextOptions(const Valdi::Ref<IShaderCache>& cache)\n    : _executor(SkExecutor::MakeFIFOThreadPool(1, true)), _cache(cache) {};\n\nGrContextOptions GrGraphicsContextOptions::getGrContextOptions() const {\n    GrContextOptions options;\n\n    options.fExecutor = _executor.get();\n\n    if (_cache != nullptr) {\n        options.fPersistentCache = _cache.get();\n        options.fShaderCacheStrategy = GrContextOptions::ShaderCacheStrategy::kBackendBinary;\n    }\n    return options;\n}\n\nGrGraphicsContext::GrGraphicsContext(const sk_sp<GrDirectContext>& grContext,\n                                     const Ref<GrGraphicsContextOptions>& options)\n    : _grContext(grContext), _options(options) {}\n\nGrGraphicsContext::~GrGraphicsContext() {\n    if (_grContext != nullptr) {\n        _grContext->abandonContext();\n        _grContext = nullptr;\n    }\n\n    _options = nullptr;\n}\n\nvoid GrGraphicsContext::setResourceCacheLimit(size_t resourceCacheLimitBytes) {\n    setGrResourceCacheLimit(_grContext, resourceCacheLimitBytes);\n}\n\nvoid GrGraphicsContext::performCleanup(bool shouldPurgeScratchResources, std::chrono::seconds secondsNotUsed) {\n    performGrCleanup(_grContext, shouldPurgeScratchResources, secondsNotUsed);\n}\n\nvoid GrGraphicsContext::setGrResourceCacheLimit(const sk_sp<GrDirectContext>& grContext,\n                                                size_t resourceCacheLimitBytes) {\n    if (grContext == nullptr) {\n        return;\n    }\n\n    grContext->setResourceCacheLimit(resourceCacheLimitBytes);\n}\n\nvoid GrGraphicsContext::performGrCleanup(const sk_sp<GrDirectContext>& grContext,\n                                         bool shouldPurgeScratchResources,\n                                         std::chrono::seconds secondsNotUsed) {\n    if (grContext == nullptr) {\n        return;\n    }\n\n    if (shouldPurgeScratchResources) {\n        grContext->purgeUnlockedResources(GrPurgeResourceOptions::kScratchResourcesOnly);\n    }\n    grContext->performDeferredCleanup(secondsNotUsed);\n}\n\nGrDirectContext& GrGraphicsContext::getGrContext() const {\n    return *_grContext;\n}\n\n} // namespace snap::drawing\n\n#endif"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/GrGraphicsContext.hpp",
    "content": "//\n//  GrGraphicsContext.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/IShaderCache.hpp\"\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wimport-preprocessor-directive-pedantic\"\n\n#include \"include/gpu/ganesh/GrDirectContext.h\"\n\n#pragma clang diagnostic pop\n\nclass SkExecutor;\n\nnamespace snap::drawing {\n\nclass GrGraphicsContextOptions : public Valdi::SimpleRefCountable {\npublic:\n    explicit GrGraphicsContextOptions();\n    explicit GrGraphicsContextOptions(const Valdi::Ref<IShaderCache>& cache);\n\n    ~GrGraphicsContextOptions() override;\n\n    GrContextOptions getGrContextOptions() const;\n\nprivate:\n    std::unique_ptr<SkExecutor> _executor;\n    Valdi::Ref<IShaderCache> _cache;\n};\n\nclass GrGraphicsContext : public GraphicsContext {\npublic:\n    GrGraphicsContext(const sk_sp<GrDirectContext>& grContext, const Ref<GrGraphicsContextOptions>& options);\n    ~GrGraphicsContext() override;\n\n    void setResourceCacheLimit(size_t resourceCacheLimitBytes) override;\n\n    void performCleanup(bool shouldPurgeScratchResources, std::chrono::seconds secondsNotUsed) override;\n\n    GrDirectContext& getGrContext() const;\n\n    static void setGrResourceCacheLimit(const sk_sp<GrDirectContext>& grContext, size_t resourceCacheLimitBytes);\n    static void performGrCleanup(const sk_sp<GrDirectContext>& grContext,\n                                 bool shouldPurgeScratchResources,\n                                 std::chrono::seconds secondsNotUsed);\n\nprivate:\n    sk_sp<GrDirectContext> _grContext;\n    Ref<GrGraphicsContextOptions> _options;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/GraphicsContext.cpp",
    "content": "//\n//  GraphicsContext.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GraphicsContext.hpp\"\n\nnamespace snap::drawing {\n\nvoid GraphicsContext::commit() {}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/GraphicsContext.hpp",
    "content": "//\n//  GraphicsContext.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include <chrono>\n\nnamespace snap::drawing {\n\nclass GraphicsContext : public Valdi::SimpleRefCountable {\npublic:\n    virtual void setResourceCacheLimit(size_t resourceCacheLimitBytes) = 0;\n\n    virtual void performCleanup(bool shouldPurgeScratchResources, std::chrono::seconds secondsNotUsed) = 0;\n\n    virtual void commit();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/IShaderCache.hpp",
    "content": "#pragma once\n\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\n#ifdef SK_GANESH\n\n#include \"include/gpu/ganesh/GrDirectContext.h\"\n\nnamespace snap::drawing {\n\nclass IShaderCache : public GrContextOptions::PersistentCache, public Valdi::SharedPtrRefCountable {};\n\n} // namespace snap::drawing\n\n#else\n\n#include \"include/core/SkData.h\"\n\nnamespace snap::drawing {\n\nclass IShaderCache : public Valdi::SharedPtrRefCountable {\npublic:\n    virtual sk_sp<SkData> load(const SkData& key) = 0;\n    virtual void store(const SkData& key, const SkData& data) = 0;\n};\n\n} // namespace snap::drawing\n\n#endif"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/MetalGraphicsContext.cpp",
    "content": "//\n//  MetalGraphicsContext.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#ifdef SK_METAL\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/MetalGraphicsContext.hpp\"\n\n#include \"include/core/SkSurface.h\"\n#include \"include/gpu/ganesh/SkSurfaceGanesh.h\"\n\nnamespace snap::drawing {\n\nMetalDrawableSurface::MetalDrawableSurface(const Ref<MetalGraphicsContext>& context,\n                                           CFTypeRef mtlLayer,\n                                           int sampleCount)\n    : _context(context), _mtlLayer(CFRetain(mtlLayer)), _sampleCount(sampleCount) {}\n\nMetalDrawableSurface::~MetalDrawableSurface() {\n    if (_mtlDrawableHandle != nullptr) {\n        CFRelease(_mtlDrawableHandle);\n    }\n\n    CFRelease(_mtlLayer);\n}\n\nGraphicsContext* MetalDrawableSurface::getGraphicsContext() {\n    return _context.get();\n}\n\nValdi::Result<DrawableSurfaceCanvas> MetalDrawableSurface::prepareCanvas() {\n    if (_surface == nullptr) {\n        _surface = MetalGraphicsContext::makeSurface(&_context->getGrContext(),\n                                                     const_cast<void*>(_mtlLayer),\n                                                     _sampleCount,\n                                                     kBGRA_8888_SkColorType,\n                                                     &_mtlDrawableHandle);\n\n        if (_surface == nullptr) {\n            return Valdi::Error(\"Failed to create Metal surface\");\n        }\n    }\n\n    auto size = MetalGraphicsContext::getMetalLayerSize(_mtlLayer);\n\n    auto width = static_cast<int>(size.width);\n    auto height = static_cast<int>(size.height);\n\n    return DrawableSurfaceCanvas(_surface.get(), width, height);\n}\n\nvoid MetalDrawableSurface::flush() {\n    if (_surface == nullptr) {\n        return;\n    }\n\n    skgpu::ganesh::FlushAndSubmit(_surface);\n    _surface = nullptr;\n\n    CFTypeRef mtlDrawableHandle = _mtlDrawableHandle;\n\n    _mtlDrawableHandle = nullptr;\n\n    if (mtlDrawableHandle != nullptr) {\n        _context->presentMetalDrawable(mtlDrawableHandle);\n        CFRelease(mtlDrawableHandle);\n    }\n}\n\nMetalGraphicsContext::MetalGraphicsContext(CFTypeRef mtlDevice,\n                                           CFTypeRef mtlCommandQueue,\n                                           const Ref<GrGraphicsContextOptions>& options)\n    : GrGraphicsContext(MetalGraphicsContext::makeContext(const_cast<void*>(mtlDevice),\n                                                          const_cast<void*>(mtlCommandQueue),\n                                                          options->getGrContextOptions()),\n                        options),\n      _mtlDevice(CFRetain(mtlDevice)),\n      _mtlCommandQueue(CFRetain(mtlCommandQueue)) {}\n\nMetalGraphicsContext::~MetalGraphicsContext() {\n    if (_mtlCommandBuffer != nullptr) {\n        CFRelease(_mtlCommandBuffer);\n    }\n\n    CFRelease(_mtlCommandQueue);\n    CFRelease(_mtlDevice);\n}\n\nvoid MetalGraphicsContext::commit() {\n    CFTypeRef mtlCommandBuffer = _mtlCommandBuffer;\n    if (mtlCommandBuffer != nullptr) {\n        _mtlCommandBuffer = nullptr;\n        MetalGraphicsContext::commitCommandBuffer(mtlCommandBuffer);\n        CFRelease(mtlCommandBuffer);\n    }\n}\n\nvoid MetalGraphicsContext::presentMetalDrawable(CFTypeRef mtlDrawableHandle) {\n    if (_mtlCommandBuffer == nullptr) {\n        _mtlCommandBuffer = MetalGraphicsContext::createCommandBuffer(_mtlCommandQueue);\n    }\n\n    MetalGraphicsContext::presentMetalDrawable(_mtlCommandBuffer, mtlDrawableHandle);\n}\n\nRef<DrawableSurface> MetalGraphicsContext::createSurfaceForMetalLayer(CFTypeRef mtlLayer, int sampleCount) {\n    return Valdi::makeShared<MetalDrawableSurface>(Valdi::strongSmallRef(this), mtlLayer, sampleCount);\n}\n\nCFTypeRef MetalGraphicsContext::getMTLDevice() const {\n    return _mtlDevice;\n}\n\nCFTypeRef MetalGraphicsContext::getMTLCommandQueue() const {\n    return _mtlCommandQueue;\n}\n\n} // namespace snap::drawing\n\n#endif\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/GraphicsContext/MetalGraphicsContext.hpp",
    "content": "//\n//  MetalGraphicsContext.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GrGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n\n#include \"CoreFoundation/CoreFoundation.h\"\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n\nnamespace snap::drawing {\n\nstruct MetalLayerSize {\n    double width;\n    double height;\n\n    constexpr MetalLayerSize(double width, double height) : width(width), height(height) {}\n};\n\nclass MetalGraphicsContext;\n\nclass MetalDrawableSurface : public DrawableSurface {\npublic:\n    MetalDrawableSurface(const Ref<MetalGraphicsContext>& context, CFTypeRef mtlLayer, int sampleCount);\n    ~MetalDrawableSurface() override;\n\n    GraphicsContext* getGraphicsContext() override;\n\n    Valdi::Result<DrawableSurfaceCanvas> prepareCanvas() override;\n\n    void flush() override;\n\n    CFTypeRef getMTLLayer() const;\n\nprivate:\n    Ref<MetalGraphicsContext> _context;\n    sk_sp<SkSurface> _surface;\n    CFTypeRef _mtlLayer;\n    CFTypeRef _mtlDrawableHandle = nullptr;\n    int _sampleCount;\n};\n\nclass MetalGraphicsContext : public GrGraphicsContext {\npublic:\n    MetalGraphicsContext(CFTypeRef mtlDevice, CFTypeRef mtlCommandQueue, const Ref<GrGraphicsContextOptions>& options);\n    ~MetalGraphicsContext() override;\n\n    Ref<DrawableSurface> createSurfaceForMetalLayer(CFTypeRef mtlLayer, int sampleCount);\n\n    void commit() override;\n\n    CFTypeRef getMTLDevice() const;\n    CFTypeRef getMTLCommandQueue() const;\n\nprivate:\n    CFTypeRef _mtlDevice;\n    CFTypeRef _mtlCommandQueue;\n    CFTypeRef _mtlCommandBuffer = nullptr;\n\n    friend MetalDrawableSurface;\n\n    void presentMetalDrawable(CFTypeRef mtlDrawableHandle);\n\n    // These methods are not directly implemented in the cpp files, the implementation should live in a .mm file\n    static CFTypeRef createCommandBuffer(CFTypeRef mtlCommandQueue);\n    static void presentMetalDrawable(CFTypeRef mtlCommandBuffer, CFTypeRef mtlDrawableHandle);\n    static void commitCommandBuffer(CFTypeRef mtlCommandBuffer);\n    static MetalLayerSize getMetalLayerSize(CFTypeRef mtlLayer);\n\n    static sk_sp<GrDirectContext> makeContext(void* mtlDevice, void* mtlCommandQueue, const GrContextOptions& options);\n    static sk_sp<SkSurface> makeSurface(GrDirectContext* grContext,\n                                        const void* mtlLayer,\n                                        int sampleCount,\n                                        SkColorType colorType,\n                                        const void** mtlDrawableHandle);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/IFrameScheduler.hpp",
    "content": "//\n//  IFrameScheduler.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/21/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\nnamespace snap::drawing {\n\nclass IFrameCallback : public Valdi::SimpleRefCountable {\npublic:\n    virtual void onFrame(TimePoint time) = 0;\n};\n\nclass IFrameScheduler : public Valdi::SimpleRefCountable {\npublic:\n    /**\n     Schedule a function to be executed on the next VSYNC of the display.\n     */\n    virtual void onNextVSync(const Ref<IFrameCallback>& callback) = 0;\n\n    virtual void onMainThread(const Ref<IFrameCallback>& callback) = 0;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/LayerContent.cpp",
    "content": "//\n//  LayerContent.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 2/1/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/LayerContent.hpp\"\n\nnamespace snap::drawing {\n\nLayerContent::LayerContent(const sk_sp<SkPicture>& picture, const Ref<ExternalSurfaceSnapshot>& externalSurface)\n    : picture(picture), externalSurface(externalSurface) {}\nLayerContent::LayerContent() = default;\nLayerContent::~LayerContent() = default;\n\nbool LayerContent::isEmpty() const {\n    return picture == nullptr && externalSurface == nullptr;\n}\n\nvoid LayerContent::clear() {\n    picture = nullptr;\n    externalSurface = nullptr;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/LayerContent.hpp",
    "content": "//\n//  LayerContent.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 2/1/22.\n//\n\n#pragma once\n\n#include \"include/core/SkPicture.h\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\nnamespace snap::drawing {\n\n/**\n LayerContent is a wrapper around a recorded list of draw commands through SkPicture,\n or a ExternalSurface reference. The LayerContent might hold the picture representing the\n background and result of the onDraw() call, or the foreground picture.\n It is created by the DrawingContext.\n */\nstruct LayerContent {\n    sk_sp<SkPicture> picture;\n    Ref<ExternalSurfaceSnapshot> externalSurface;\n\n    LayerContent(const sk_sp<SkPicture>& picture, const Ref<ExternalSurfaceSnapshot>& externalSurface);\n    LayerContent();\n    ~LayerContent();\n\n    bool isEmpty() const;\n    void clear();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/LinearGradient.cpp",
    "content": "//\n//  LinearGradient.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/8/20.\n//\n\n#include \"snap_drawing/cpp/Drawing/LinearGradient.hpp\"\n#include \"include/effects/SkGradientShader.h\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nLinearGradient::LinearGradient() = default;\n\nLinearGradient::~LinearGradient() = default;\n\nbool LinearGradient::isDirty() const {\n    return _dirty;\n}\n\nbool LinearGradient::isEmpty() const {\n    return _colors.empty();\n}\n\nvoid LinearGradient::setLocations(std::vector<Scalar>&& locations) {\n    if (_locations != locations) {\n        _locations = std::move(locations);\n        _dirty = true;\n    }\n}\n\nvoid LinearGradient::setColors(std::vector<Color>&& colors) {\n    if (_colors != colors) {\n        _colors = std::move(colors);\n        _dirty = true;\n    }\n}\n\nvoid LinearGradient::setOrientation(LinearGradientOrientation orientation) {\n    if (_orientation != orientation) {\n        _orientation = orientation;\n        _dirty = true;\n    }\n}\n\nvoid LinearGradient::updateShader(const Rect& bounds) {\n    if (isEmpty()) {\n        _shader = nullptr;\n    } else {\n        auto halfWidth = bounds.x() + (bounds.width() / 2);\n        auto halfHeight = bounds.y() + (bounds.height() / 2);\n\n        Point points[2];\n\n        switch (_orientation) {\n            case LinearGradientOrientationTopBottom:\n                points[0] = Point::make(halfWidth, bounds.top);\n                points[1] = Point::make(halfWidth, bounds.bottom);\n                break;\n            case LinearGradientOrientationTopRightBottomLeft:\n                points[0] = Point::make(bounds.right, bounds.top);\n                points[1] = Point::make(bounds.left, bounds.bottom);\n                break;\n            case LinearGradientOrientationRightLeft:\n                points[0] = Point::make(bounds.right, halfHeight);\n                points[1] = Point::make(bounds.left, halfHeight);\n                break;\n            case LinearGradientOrientationBottomRightTopLeft:\n                points[0] = Point::make(bounds.right, bounds.bottom);\n                points[1] = Point::make(bounds.left, bounds.top);\n                break;\n            case LinearGradientOrientationBottomTop:\n                points[0] = Point::make(halfWidth, bounds.bottom);\n                points[1] = Point::make(halfWidth, bounds.top);\n                break;\n            case LinearGradientOrientationBottomLeftTopRight:\n                points[0] = Point::make(bounds.left, bounds.bottom);\n                points[1] = Point::make(bounds.right, bounds.top);\n                break;\n            case LinearGradientOrientationLeftRight:\n                points[0] = Point::make(bounds.left, halfHeight);\n                points[1] = Point::make(bounds.right, halfHeight);\n                break;\n            case LinearGradientOrientationTopLeftBottomRight:\n                points[0] = Point::make(bounds.left, bounds.top);\n                points[1] = Point::make(bounds.right, bounds.bottom);\n                break;\n            default:\n                points[0] = Point::make(halfWidth, bounds.top);\n                points[1] = Point::make(halfWidth, bounds.bottom);\n        }\n\n        const auto* colorsData = reinterpret_cast<const SkColor*>(_colors.data());\n\n        sk_sp<SkShader> shader;\n        if (_colors.size() == _locations.size()) {\n            // User provided color distribution\n\n            _shader = SkGradientShader::MakeLinear(&points[0].getSkValue(),\n                                                   colorsData,\n                                                   _locations.data(),\n                                                   static_cast<int>(_colors.size()),\n                                                   SkTileMode::kClamp);\n        } else {\n            // Distribute colors evenly\n            _shader = SkGradientShader::MakeLinear(\n                &points[0].getSkValue(), colorsData, nullptr, static_cast<int>(_colors.size()), SkTileMode::kClamp);\n        }\n    }\n}\n\nvoid LinearGradient::applyToPaint(Paint& paint) const {\n    paint.getSkValue().setShader(_shader);\n}\n\nvoid LinearGradient::update(const Rect& bounds) {\n    if (_dirty || _lastDrawBounds != bounds) {\n        updateShader(bounds);\n\n        _lastDrawBounds = bounds;\n        _dirty = false;\n    }\n}\n\nvoid LinearGradient::draw(DrawingContext& drawingContext, const BorderRadius& borderRadius) {\n    update(drawingContext.drawBounds());\n\n    if (isEmpty()) {\n        return;\n    }\n\n    Paint paint;\n    applyToPaint(paint);\n\n    drawingContext.drawPaint(paint, borderRadius, _lazyPath);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/LinearGradient.hpp",
    "content": "//\n//  LinearGradient.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/8/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/LazyPath.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n\n#include <vector>\n\nnamespace snap::drawing {\n\nclass BorderRadius;\n\nenum LinearGradientOrientation {\n    /** draw the gradient from the top to the bottom */\n    LinearGradientOrientationTopBottom,\n    /** draw the gradient from the top-right to the bottom-left */\n    LinearGradientOrientationTopRightBottomLeft,\n    /** draw the gradient from the right to the left */\n    LinearGradientOrientationRightLeft,\n    /** draw the gradient from the bottom-right to the top-left */\n    LinearGradientOrientationBottomRightTopLeft,\n    /** draw the gradient from the bottom to the top */\n    LinearGradientOrientationBottomTop,\n    /** draw the gradient from the bottom-left to the top-right */\n    LinearGradientOrientationBottomLeftTopRight,\n    /** draw the gradient from the left to the right */\n    LinearGradientOrientationLeftRight,\n    /** draw the gradient from the top-left to the bottom-right */\n    LinearGradientOrientationTopLeftBottomRight,\n};\n\nclass LinearGradient : public Valdi::SimpleRefCountable {\npublic:\n    LinearGradient();\n    ~LinearGradient() override;\n\n    bool isDirty() const;\n    bool isEmpty() const;\n\n    void setLocations(std::vector<Scalar>&& locations);\n    void setColors(std::vector<Color>&& colors);\n    void setOrientation(LinearGradientOrientation orientation);\n\n    void update(const Rect& bounds);\n\n    void applyToPaint(Paint& paint) const;\n\n    void draw(DrawingContext& drawingContext, const BorderRadius& borderRadius);\n\nprivate:\n    sk_sp<SkShader> _shader;\n    std::vector<Scalar> _locations;\n    std::vector<Color> _colors;\n    LinearGradientOrientation _orientation = LinearGradientOrientationTopBottom;\n    Rect _lastDrawBounds = Rect::makeEmpty();\n    LazyPath _lazyPath;\n    bool _dirty = true;\n\n    void updateShader(const Rect& bounds);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Mask/CompositeMask.cpp",
    "content": "#include \"snap_drawing/cpp/Drawing/Mask/CompositeMask.hpp\"\n\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\nnamespace snap::drawing {\n\nCompositeMask::CompositeMask(std::vector<Valdi::Ref<IMask>>&& masks) : _masks(std::move(masks)) {\n    for (const auto& mask : _masks) {\n        _bounds.join(mask->getBounds());\n    }\n}\n\nCompositeMask::~CompositeMask() = default;\n\nRect CompositeMask::getBounds() const {\n    return _bounds;\n}\n\nvoid CompositeMask::prepare(SkCanvas* canvas) {\n    for (const auto& mask : _masks) {\n        mask->prepare(canvas);\n    }\n}\n\nvoid CompositeMask::apply(SkCanvas* canvas) {\n    // Need to reverse the order of the `prepare` operations because the flow is stack based.\n    for (size_t i = _masks.size(); i-- > 0;) {\n        const auto& mask = _masks[i];\n        mask->apply(canvas);\n    }\n}\n\nString CompositeMask::getDescription() {\n    String output = STRING_FORMAT(\"Composite bounds is {}\\n\", _bounds);\n    for (const auto& mask : _masks) {\n        output += STRING_FORMAT(\" - {}\\n\", mask->getDescription());\n    }\n    return output;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Mask/CompositeMask.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n\nnamespace snap::drawing {\n\nclass CompositeMask : public IMask {\npublic:\n    explicit CompositeMask(std::vector<Valdi::Ref<IMask>>&& masks);\n    ~CompositeMask() override;\n\n    Rect getBounds() const override;\n\n    void prepare(SkCanvas* canvas) override;\n\n    void apply(SkCanvas* canvas) override;\n\n    String getDescription() override;\n\nprivate:\n    std::vector<Valdi::Ref<IMask>> _masks;\n    Rect _bounds;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Mask/IMask.hpp",
    "content": "//\n//  IMask.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 10/20/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\nclass SkCanvas;\n\nnamespace snap::drawing {\n\n/**\n An IMask represents a single masking operation emitted at draw time.\n It can be created from an IMaskLayer instance.\n */\nclass IMask : public Valdi::SimpleRefCountable {\npublic:\n    /**\n     Returns the bounds covering the entire range of the mask.\n     The bounds is used to know what area might be altered by the mask.\n     */\n    virtual Rect getBounds() const = 0;\n\n    /**\n     Prepare the canvas for applying the mask.\n     */\n    virtual void prepare(SkCanvas* canvas) = 0;\n\n    /**\n     Apply the mask, which should have been previously prepared through the prepare() call.\n     The content drawn between the prepare and apply call should be masked after\n     the apply call is made.\n     */\n    virtual void apply(SkCanvas* canvas) = 0;\n\n    /**\n     Return a description best matching the mask and its configured values.\n     */\n    virtual String getDescription() = 0;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Mask/PaintMask.cpp",
    "content": "//\n//  PaintMask.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 10/20/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Mask/PaintMask.hpp\"\n\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\n#include \"include/core/SkCanvas.h\"\n\n// This is a private header in Skia.\n// This allows us to leverage the saveBehind API\n\nclass SkCanvasPriv {\npublic:\n    // NOLINTNEXTLINE\n    static int SaveBehind(SkCanvas* canvas, const SkRect* subset) {\n        return canvas->only_axis_aligned_saveBehind(subset);\n    }\n};\n\nnamespace snap::drawing {\n\nPaintMask::PaintMask(const Paint& paint, const Path& path, const Rect& rect)\n    : _paint(paint), _path(path), _rect(rect) {}\n\nPaintMask::~PaintMask() = default;\n\nRect PaintMask::getBounds() const {\n    auto bounds = _path.getBounds();\n    return bounds ? bounds.value() : _rect;\n}\n\nvoid PaintMask::prepare(SkCanvas* canvas) {\n    auto bounds = getBounds();\n    SkCanvasPriv::SaveBehind(canvas, &bounds.getSkValue());\n}\n\nvoid PaintMask::apply(SkCanvas* canvas) {\n    if (_path.isEmpty()) {\n        canvas->drawRect(_rect.getSkValue(), _paint.getSkValue());\n    } else {\n        canvas->drawPath(_path.getSkValue(), _paint.getSkValue());\n    }\n\n    canvas->restore();\n}\n\nString PaintMask::getDescription() {\n    if (_path.isEmpty()) {\n        return STRING_FORMAT(\"PaintMask with rect {}\", _rect);\n    } else {\n        return STRING_FORMAT(\"PaintMask with path {}\", _path);\n    }\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Mask/PaintMask.hpp",
    "content": "//\n//  PaintMask.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 10/20/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n\nnamespace snap::drawing {\n\n/**\n A PaintMask is an implementation of IMask that prepares the canvas\n using SkCanvas::saveBehind and draws a region from a given rect or path\n with a given paint.\n */\nclass PaintMask : public IMask {\npublic:\n    PaintMask(const Paint& paint, const Path& path, const Rect& rect);\n    ~PaintMask() override;\n\n    Rect getBounds() const override;\n\n    void prepare(SkCanvas* canvas) override;\n\n    void apply(SkCanvas* canvas) override;\n\n    String getDescription() override;\n\nprivate:\n    Paint _paint;\n    Path _path;\n    Rect _rect;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/MaskFilter.cpp",
    "content": "#include \"snap_drawing/cpp/Drawing/MaskFilter.hpp\"\n\nnamespace snap::drawing {\n\nMaskFilter::MaskFilter() : MaskFilter(nullptr) {}\n\nMaskFilter::MaskFilter(sk_sp<SkMaskFilter> skValue) : WrappedSkValue<sk_sp<SkMaskFilter>>(std::move(skValue)) {}\nMaskFilter::~MaskFilter() = default;\n\nMaskFilter MaskFilter::makeBlur(BlurStyle blurStyle, Scalar sigma) {\n    return MaskFilter(SkMaskFilter::MakeBlur(static_cast<SkBlurStyle>(blurStyle), sigma));\n}\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/MaskFilter.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n#include \"snap_drawing/cpp/Utils/SkiaBridge.hpp\"\n\n#include \"include/core/SkBlurTypes.h\"\n#include \"include/core/SkMaskFilter.h\"\n\nnamespace snap::drawing {\n\nenum BlurStyle {\n    BlurStyleNormal = kNormal_SkBlurStyle, //!< fuzzy inside and outside\n    BlurStyleSolid = kSolid_SkBlurStyle,   //!< solid inside, fuzzy outside\n    BlurStyleOuter = kOuter_SkBlurStyle,   //!< nothing inside, fuzzy outside\n    BlurStyleInner = kInner_SkBlurStyle,   //!< fuzzy inside, nothing outside\n};\n\nclass MaskFilter : public WrappedSkValue<sk_sp<SkMaskFilter>> {\npublic:\n    MaskFilter();\n    ~MaskFilter();\n\n    static MaskFilter makeBlur(BlurStyle blurStyle, Scalar sigma);\n\nprivate:\n    explicit MaskFilter(sk_sp<SkMaskFilter> skValue);\n};\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Paint.cpp",
    "content": "//\n//  Paint.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n#include \"snap_drawing/cpp/Drawing/MaskFilter.hpp\"\n#include \"snap_drawing/cpp/Drawing/Shader.hpp\"\n\n#include \"include/core/SkColorFilter.h\"\n\nnamespace snap::drawing {\n\nPaint::Paint() = default;\n\nPaint::Paint(const Paint& other) : Paint() {\n    *this = other;\n}\n\nPaint::~Paint() = default;\n\nPaint& Paint::operator=(const Paint& other) {\n    if (&other != this) {\n        getSkValue() = other.getSkValue();\n    }\n\n    return *this;\n}\n\nvoid Paint::setColor(Color color) {\n    getSkValue().setColor(color.getSkValue());\n}\n\nColor Paint::getColor() const {\n    return fromSkValue<Color>(getSkValue().getColor());\n}\n\nvoid Paint::setAlpha(float alpha) {\n    getSkValue().setAlphaf(alpha);\n}\n\nvoid Paint::setBlendColorFilter(Color color) {\n    if (color == Color::transparent()) {\n        getSkValue().setColorFilter(nullptr);\n    } else {\n        getSkValue().setColorFilter(SkColorFilters::Blend(color.getSkValue(), SkBlendMode::kSrcATop));\n    }\n}\n\nvoid Paint::setStroke(bool stroke) {\n    getSkValue().setStroke(stroke);\n}\n\nvoid Paint::setStrokeWidth(Scalar strokeWidth) {\n    getSkValue().setStrokeWidth(strokeWidth);\n}\n\nScalar Paint::getStrokeWidth() const {\n    return getSkValue().getStrokeWidth();\n}\n\nvoid Paint::setStrokeJoin(PaintStrokeJoin strokeJoin) {\n    getSkValue().setStrokeJoin(static_cast<SkPaint::Join>(strokeJoin));\n}\n\nvoid Paint::setStrokeCap(PaintStrokeCap strokeCap) {\n    getSkValue().setStrokeCap(static_cast<SkPaint::Cap>(strokeCap));\n}\n\nvoid Paint::setBlendMode(SkBlendMode blendMode) {\n    getSkValue().setBlendMode(blendMode);\n}\n\nvoid Paint::setAntiAlias(bool antialias) {\n    getSkValue().setAntiAlias(antialias);\n}\n\nvoid Paint::setShader(const Shader& shader) {\n    getSkValue().setShader(shader.getSkValue());\n}\n\nvoid Paint::setMaskFilter(const MaskFilter& maskFilter) {\n    getSkValue().setMaskFilter(maskFilter.getSkValue());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Paint.hpp",
    "content": "//\n//  Paint.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n#include \"snap_drawing/cpp/Utils/SkiaBridge.hpp\"\n\n#include \"include/core/SkPaint.h\"\n\nnamespace snap::drawing {\n\nenum PaintStrokeCap {\n    PaintStrokeCapButt = SkPaint::Cap::kButt_Cap,\n    PaintStrokeCapRound = SkPaint::Cap::kRound_Cap,\n    PaintStrokeCapSquare = SkPaint::Cap::kSquare_Cap,\n};\n\nenum PaintStrokeJoin {\n    PaintStrokeJoinMiter = SkPaint::Join::kMiter_Join,\n    PaintStrokeJoinRound = SkPaint::Join::kRound_Join,\n    PaintStrokeJoinBevel = SkPaint::Join::kBevel_Join,\n};\n\nclass Shader;\nclass MaskFilter;\n\nclass Paint : public WrappedSkValue<SkPaint> {\npublic:\n    Paint();\n    Paint(const Paint& other);\n\n    ~Paint();\n\n    Paint& operator=(const Paint& other);\n\n    Color getColor() const;\n    void setColor(Color color);\n    void setAlpha(float alpha);\n    void setBlendColorFilter(Color color);\n    void setStroke(bool stroke);\n\n    void setStrokeWidth(Scalar strokeWidth);\n    Scalar getStrokeWidth() const;\n\n    void setStrokeCap(PaintStrokeCap strokeCap);\n    void setStrokeJoin(PaintStrokeJoin strokeJoin);\n    void setBlendMode(SkBlendMode blendMode);\n    void setAntiAlias(bool antialias);\n\n    void setShader(const Shader& shader);\n    void setMaskFilter(const MaskFilter& maskFilter);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/RadialGradient.cpp",
    "content": "//\n//  RadialGradient.cpp\n//  snap_drawing\n//\n//  Created by Brandon Francis on 3/7/23.\n//\n\n#include \"snap_drawing/cpp/Drawing/RadialGradient.hpp\"\n#include \"include/effects/SkGradientShader.h\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nRadialGradient::RadialGradient() = default;\n\nRadialGradient::~RadialGradient() = default;\n\nbool RadialGradient::isDirty() const {\n    return _dirty;\n}\n\nbool RadialGradient::isEmpty() const {\n    return _colors.empty();\n}\n\nvoid RadialGradient::setLocations(std::vector<Scalar>&& locations) {\n    if (_locations != locations) {\n        _locations = std::move(locations);\n        _dirty = true;\n    }\n}\n\nvoid RadialGradient::setColors(std::vector<Color>&& colors) {\n    if (_colors != colors) {\n        _colors = std::move(colors);\n        _dirty = true;\n    }\n}\n\nvoid RadialGradient::updateShader(const Rect& bounds) {\n    if (isEmpty()) {\n        _shader = nullptr;\n    } else {\n        auto width = bounds.width();\n        auto height = bounds.height();\n        auto radius = std::min(width / 2, height / 2);\n\n        const auto* colorsData = reinterpret_cast<const SkColor*>(_colors.data());\n\n        SkMatrix localMatrix;\n        if (width != height) {\n            localMatrix.postScale(width / height, 1);\n        }\n        localMatrix.postTranslate(bounds.x() + (width / 2), bounds.y() + (height / 2));\n\n        sk_sp<SkShader> shader;\n        if (_colors.size() == _locations.size()) {\n            // User provided color distribution\n\n            _shader = SkGradientShader::MakeRadial(Point::make(0, 0).getSkValue(),\n                                                   radius,\n                                                   colorsData,\n                                                   _locations.data(),\n                                                   static_cast<int>(_colors.size()),\n                                                   SkTileMode::kClamp,\n                                                   0,\n                                                   &localMatrix);\n        } else {\n            // Distribute colors evenly\n            _shader = SkGradientShader::MakeRadial(Point::make(0, 0).getSkValue(),\n                                                   radius,\n                                                   colorsData,\n                                                   nullptr,\n                                                   static_cast<int>(_colors.size()),\n                                                   SkTileMode::kClamp,\n                                                   0,\n                                                   &localMatrix);\n        }\n    }\n}\n\nvoid RadialGradient::applyToPaint(Paint& paint) const {\n    paint.getSkValue().setShader(_shader);\n}\n\nvoid RadialGradient::update(const Rect& bounds) {\n    if (_dirty || _lastDrawBounds != bounds) {\n        updateShader(bounds);\n\n        _lastDrawBounds = bounds;\n        _dirty = false;\n    }\n}\n\nvoid RadialGradient::draw(DrawingContext& drawingContext, const BorderRadius& borderRadius) {\n    update(drawingContext.drawBounds());\n\n    if (isEmpty()) {\n        return;\n    }\n\n    Paint paint;\n    applyToPaint(paint);\n\n    drawingContext.drawPaint(paint, borderRadius, _lazyPath);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/RadialGradient.hpp",
    "content": "//\n//  RadialGradient.hpp\n//  snap_drawing\n//\n//  Created by Brandon Francis on 3/7/23.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/LazyPath.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n\n#include <vector>\n\nnamespace snap::drawing {\n\nclass BorderRadius;\n\nclass RadialGradient : public Valdi::SimpleRefCountable {\npublic:\n    RadialGradient();\n    ~RadialGradient() override;\n\n    bool isDirty() const;\n    bool isEmpty() const;\n\n    void setLocations(std::vector<Scalar>&& locations);\n    void setColors(std::vector<Color>&& colors);\n\n    void update(const Rect& bounds);\n\n    void applyToPaint(Paint& paint) const;\n\n    void draw(DrawingContext& drawingContext, const BorderRadius& borderRadius);\n\nprivate:\n    sk_sp<SkShader> _shader;\n    std::vector<Scalar> _locations;\n    std::vector<Color> _colors;\n    Rect _lastDrawBounds = Rect::makeEmpty();\n    LazyPath _lazyPath;\n    bool _dirty = true;\n\n    void updateShader(const Rect& bounds);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Raster/BitmapCache.cpp",
    "content": "#include \"BitmapCache.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmapFactory.hpp\"\n\nnamespace snap::drawing {\n\nBitmapCache::Entry::Entry(const Ref<Valdi::IBitmapFactory>& bitmapFactory,\n                          const Ref<Valdi::IBitmap>& bitmap,\n                          int width,\n                          int height)\n    : _bitmapFactory(bitmapFactory), _bitmap(bitmap), _width(width), _height(height) {}\n\nBitmapCache::Entry::~Entry() = default;\n\nbool BitmapCache::Entry::isCompatibleWith(const Ref<Valdi::IBitmapFactory>& bitmapFactory,\n                                          int width,\n                                          int height) const {\n    return _bitmapFactory == bitmapFactory && _width == width && _height == height;\n}\n\nbool BitmapCache::Entry::isUsed() const {\n    return _bitmap.use_count() > 1;\n}\n\nconst Ref<Valdi::IBitmap>& BitmapCache::Entry::getBitmap() const {\n    return _bitmap;\n}\n\nBitmapCache::BitmapCache() = default;\nBitmapCache::~BitmapCache() = default;\n\nValdi::Result<Ref<Valdi::IBitmap>> BitmapCache::allocateBitmap(const Ref<Valdi::IBitmapFactory>& bitmapFactory,\n                                                               int width,\n                                                               int height) {\n    for (const auto& entry : _entries) {\n        if (!entry.isUsed() && entry.isCompatibleWith(bitmapFactory, width, height)) {\n            return entry.getBitmap();\n        }\n    }\n\n    auto bitmap = bitmapFactory->createBitmap(width, height);\n    if (!bitmap) {\n        return bitmap;\n    }\n\n    _entries.emplace_back(bitmapFactory, bitmap.value(), width, height);\n\n    return bitmap;\n}\n\nvoid BitmapCache::clearUnused() {\n    _entries.erase(std::remove_if(_entries.begin(), _entries.end(), [](const auto& entry) { return !entry.isUsed(); }),\n                   _entries.end());\n}\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Raster/BitmapCache.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmapFactory.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include <vector>\n\nnamespace Valdi {\nclass IBitmapFactory;\n}\n\nnamespace snap::drawing {\n\n/**\nBitmapCache helps with creating bitmaps and re-using them when they are not already in-use.\n */\nclass BitmapCache {\npublic:\n    BitmapCache();\n    ~BitmapCache();\n\n    Valdi::Result<Ref<Valdi::IBitmap>> allocateBitmap(const Ref<Valdi::IBitmapFactory>& bitmapFactory,\n                                                      int width,\n                                                      int height);\n\n    void clearUnused();\n\nprivate:\n    class Entry {\n    public:\n        Entry(const Ref<Valdi::IBitmapFactory>& bitmapFactory,\n              const Ref<Valdi::IBitmap>& bitmap,\n              int width,\n              int height);\n        ~Entry();\n\n        bool isCompatibleWith(const Ref<Valdi::IBitmapFactory>& bitmapFactory, int width, int height) const;\n\n        bool isUsed() const;\n\n        const Ref<Valdi::IBitmap>& getBitmap() const;\n\n    private:\n        Ref<Valdi::IBitmapFactory> _bitmapFactory;\n        Ref<Valdi::IBitmap> _bitmap;\n        int _width;\n        int _height;\n    };\n\n    std::vector<Entry> _entries;\n};\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Raster/RasterContext.cpp",
    "content": "#include \"RasterContext.hpp\"\n#include \"include/core/SkCanvas.h\"\n#include \"snap_drawing/cpp/Drawing/Composition/CompositionState.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/Compositor.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlaneList.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/BitmapGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n#include \"snap_drawing/cpp/Drawing/Raster/RasterDamageResolver.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp\"\n#include \"snap_drawing/cpp/Utils/Bitmap.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmapFactory.hpp\"\n#include \"valdi_core/cpp/Interfaces/ILogger.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n#include <cstddef>\n#include <cstdint>\n\n// These come from Skia SkBlitRow.h .\n// We use them for blending rows. They are highly optimized under the hood,\n// so it's best to re-use instead of rolling out our own.\nclass SkBlitRow {\npublic:\n    // NOLINTNEXTLINE(readability-identifier-naming)\n    enum Flags32 { kGlobalAlpha_Flag32 = 1 << 0, kSrcPixelAlpha_Flag32 = 1 << 1 };\n\n    // NOLINTNEXTLINE(readability-identifier-naming)\n    using Proc32 = void (*)(uint32_t dst[], const SkPMColor src[], int count, U8CPU alpha);\n\n    // NOLINTNEXTLINE(readability-identifier-naming)\n    static Proc32 Factory32(unsigned flags32);\n};\n\nnamespace snap::drawing {\n\nstruct RasterContext::CompositionResult {\n    CompositorPlaneList planeList;\n    Ref<DisplayList> displayList;\n};\n\nRasterContext::RasterContext(Valdi::ILogger& logger,\n                             ExternalSurfaceRasterizationMethod externalSurfaceRasterizationMethod,\n                             bool enableDeltaRasterization)\n    : _logger(logger),\n      _externalSurfaceRasterizationMethod(externalSurfaceRasterizationMethod),\n      _deltaRasterizationEnabled(enableDeltaRasterization) {}\nRasterContext::~RasterContext() = default;\n\nRasterContext::CompositionResult RasterContext::performCompositionIfNeeded(const Ref<DisplayList>& displayList) const {\n    CompositionResult result;\n\n    if (_externalSurfaceRasterizationMethod == ExternalSurfaceRasterizationMethod::ACCURATE &&\n        displayList->hasExternalSurfaces()) {\n        Compositor compositor(_logger);\n        result.displayList = compositor.performComposition(*displayList, result.planeList);\n    } else {\n        result.planeList.appendDrawableSurface();\n        result.displayList = displayList;\n    }\n\n    return result;\n}\n\nValdi::Result<RasterContext::RasterResult> RasterContext::raster(const Ref<DisplayList>& displayList,\n                                                                 const Ref<Valdi::IBitmap>& bitmap,\n                                                                 bool shouldClearBitmapBeforeDrawing) {\n    VALDI_TRACE(\"SnapDrawing.rasterContext.raster\");\n    auto rasterId = ++_rasterSequence;\n\n    auto inputBitmapInfo = bitmap->getInfo();\n    auto composition = performCompositionIfNeeded(displayList);\n\n    RasterResult output;\n    output.renderedPixelsCount = inputBitmapInfo.width * inputBitmapInfo.height;\n\n    if (_deltaRasterizationEnabled) {\n        std::lock_guard<std::recursive_mutex> lock(_mutex);\n\n        output.damageRects = computeDamageRects(displayList, inputBitmapInfo);\n\n        if (needsNewBitmap(inputBitmapInfo)) {\n            // Cannot do a delta raster if the input bitmap info has changed\n            _lastBitmap = nullptr;\n\n            {\n                VALDI_TRACE(\"SnapDrawing.rasterContext.allocateDeltaBitmap\");\n                auto newBitmap = Bitmap::make(inputBitmapInfo);\n                if (!newBitmap) {\n                    return newBitmap.moveError();\n                }\n\n                _lastBitmap = newBitmap.value();\n            }\n\n            auto result = rasterNonDelta(_lastBitmap,\n                                         *composition.displayList,\n                                         composition.planeList,\n                                         inputBitmapInfo,\n                                         shouldClearBitmapBeforeDrawing,\n                                         rasterId);\n            if (!result) {\n                return result.moveError();\n            }\n\n            // Calculate rendered pixel count from damage rects for consistency\n            output.renderedPixelsCount = 0;\n            for (const auto& damageRect : output.damageRects) {\n                output.renderedPixelsCount +=\n                    static_cast<size_t>(damageRect.width()) * static_cast<size_t>(damageRect.height());\n            }\n        } else {\n            auto result = doRasterDelta(composition, _lastBitmap, inputBitmapInfo, output.damageRects, rasterId);\n            if (!result) {\n                return result.moveError();\n            }\n\n            output.renderedPixelsCount = result.value().renderedPixelsCount;\n        }\n\n        auto result =\n            blitDeltaBitmapToOutputBitmap(_lastBitmap, bitmap, inputBitmapInfo, shouldClearBitmapBeforeDrawing);\n        if (!result) {\n            return result.moveError();\n        }\n    } else {\n        auto result = rasterNonDelta(bitmap,\n                                     *composition.displayList,\n                                     composition.planeList,\n                                     inputBitmapInfo,\n                                     shouldClearBitmapBeforeDrawing,\n                                     rasterId);\n        if (!result) {\n            return result.moveError();\n        }\n    }\n\n    removeUnusedCachedRasterizedExternalSurfaces(rasterId);\n\n    return output;\n}\n\nValdi::Result<Valdi::Void> RasterContext::blitDeltaBitmapToOutputBitmap(const Ref<Valdi::IBitmap>& deltaBitmap,\n                                                                        const Ref<Valdi::IBitmap>& outputBitmap,\n                                                                        const Valdi::BitmapInfo& bitmapInfo,\n                                                                        bool fullReplace) {\n    if (!fullReplace) {\n        if (bitmapInfo.alphaType != Valdi::AlphaType::AlphaTypePremul) {\n            return Valdi::Error(\"Delta rasterization is currently only supported for premultiplied alpha bitmaps\");\n        }\n\n        if (bitmapInfo.colorType != Valdi::ColorType::ColorTypeRGBA8888 &&\n            bitmapInfo.colorType != Valdi::ColorType::ColorTypeBGRA8888) {\n            return Valdi::Error(\"Delta rasterization is currently only supported for RGBA or BGRA bitmaps\");\n        }\n    }\n\n    auto deltaBitmapInfo = deltaBitmap->getInfo();\n\n    // Copy bytes from our bitmap to the input bitmap\n    auto inputBytes = deltaBitmap->lockBytes();\n    if (inputBytes == nullptr) {\n        return Valdi::Error(\"Failed to lock bytes\");\n    }\n\n    auto outputBytes = outputBitmap->lockBytes();\n    if (outputBytes == nullptr) {\n        deltaBitmap->unlockBytes();\n        return Valdi::Error(\"Failed to lock bytes\");\n    }\n\n    if (fullReplace) {\n        if (deltaBitmapInfo.bytesLength() == bitmapInfo.bytesLength()) {\n            std::memcpy(outputBytes, inputBytes, bitmapInfo.bytesLength());\n        } else {\n            auto minRowBytes = std::min(deltaBitmapInfo.rowBytes, bitmapInfo.rowBytes);\n            auto* outputPtr = reinterpret_cast<uint8_t*>(outputBytes);\n            const auto* inputPtr = reinterpret_cast<const uint8_t*>(inputBytes);\n            for (int y = 0; y < bitmapInfo.height; y++) {\n                std::memcpy(outputPtr, inputPtr, minRowBytes);\n\n                inputPtr += deltaBitmapInfo.rowBytes;\n                outputPtr += bitmapInfo.rowBytes;\n            }\n        }\n    } else {\n        auto processProc = SkBlitRow::Factory32(SkBlitRow::kSrcPixelAlpha_Flag32);\n\n        auto* outputPtr = reinterpret_cast<uint8_t*>(outputBytes);\n        const auto* inputPtr = reinterpret_cast<const uint8_t*>(inputBytes);\n\n        for (int y = 0; y < bitmapInfo.height; y++) {\n            processProc(reinterpret_cast<uint32_t*>(outputPtr),\n                        reinterpret_cast<const uint32_t*>(inputPtr),\n                        bitmapInfo.width,\n                        255);\n\n            inputPtr += deltaBitmapInfo.rowBytes;\n            outputPtr += bitmapInfo.rowBytes;\n        }\n    }\n\n    deltaBitmap->unlockBytes();\n    outputBitmap->unlockBytes();\n    return Valdi::Void();\n}\n\nstd::vector<Rect> RasterContext::computeDamageRects(const Ref<DisplayList>& displayList,\n                                                    const Valdi::BitmapInfo& bitmapInfo) {\n    VALDI_TRACE(\"SnapDrawing.rasterContext.computeDamageRects\");\n    _rasterDamageResolver.beginUpdates(bitmapInfo.width, bitmapInfo.height);\n    _rasterDamageResolver.addDamageFromDisplayListUpdates(*displayList);\n\n    return _rasterDamageResolver.endUpdates();\n}\n\nValdi::Result<RasterContext::RasterResult> RasterContext::rasterDelta(const Ref<DisplayList>& displayList,\n                                                                      const Ref<Valdi::IBitmap>& bitmap) {\n    VALDI_TRACE(\"SnapDrawing.rasterContext.rasterDelta\");\n    auto inputBitmapInfo = bitmap->getInfo();\n    auto rasterId = ++_rasterSequence;\n\n    std::lock_guard<std::recursive_mutex> lock(_mutex);\n    auto damageRects = computeDamageRects(displayList, inputBitmapInfo);\n\n    auto composition = performCompositionIfNeeded(displayList);\n    auto result = doRasterDelta(composition, bitmap, bitmap->getInfo(), damageRects, rasterId);\n\n    removeUnusedCachedRasterizedExternalSurfaces(rasterId);\n\n    if (result) {\n        result.value().damageRects = std::move(damageRects);\n    }\n\n    return result;\n}\n\nValdi::Result<RasterContext::RasterResult> RasterContext::doRasterDelta(const CompositionResult& compositionResult,\n                                                                        const Ref<Valdi::IBitmap>& bitmap,\n                                                                        const Valdi::BitmapInfo& bitmapInfo,\n                                                                        const std::vector<Rect>& damageRects,\n                                                                        size_t rasterId) {\n    BitmapGraphicsContext graphicsContext;\n    auto surface = graphicsContext.createBitmapSurface(bitmap);\n\n    auto canvas = surface->prepareCanvas();\n    if (!canvas) {\n        return canvas.moveError();\n    }\n\n    RasterResult output;\n    output.renderedPixelsCount = 0;\n\n    for (const auto& damageRect : damageRects) {\n        VALDI_TRACE(\"SnapDrawing.rasterContext.rasterDeltaInRect\");\n        auto* skiaCanvas = canvas.value().getSkiaCanvas();\n        auto saveCount = skiaCanvas->save();\n        skiaCanvas->clipRect(damageRect.getSkValue());\n\n        auto doRasterResult = doRaster(\n            canvas.value(), *compositionResult.displayList, compositionResult.planeList, bitmapInfo, true, rasterId);\n\n        skiaCanvas->restoreToCount(saveCount);\n\n        if (!doRasterResult) {\n            return doRasterResult.moveError();\n        }\n\n        output.renderedPixelsCount +=\n            static_cast<size_t>(damageRect.width()) * static_cast<size_t>(damageRect.height());\n    }\n\n    surface->flush();\n\n    return output;\n}\n\nValdi::Result<Valdi::Void> RasterContext::rasterNonDelta(const Ref<Valdi::IBitmap>& bitmap,\n                                                         const DisplayList& displayList,\n                                                         const CompositorPlaneList& planeList,\n                                                         const Valdi::BitmapInfo& bitmapInfo,\n                                                         bool shouldClearBitmapBeforeDrawing,\n                                                         size_t rasterId) {\n    VALDI_TRACE(\"SnapDrawing.rasterContext.rasterNonDelta\");\n    BitmapGraphicsContext graphicsContext;\n    auto surface = graphicsContext.createBitmapSurface(bitmap);\n\n    auto canvas = surface->prepareCanvas();\n    if (!canvas) {\n        return canvas.moveError();\n    }\n\n    auto doRasterResult =\n        doRaster(canvas.value(), displayList, planeList, bitmapInfo, shouldClearBitmapBeforeDrawing, rasterId);\n\n    surface->flush();\n\n    return doRasterResult;\n}\n\nValdi::Result<Valdi::Void> RasterContext::doRaster(DrawableSurfaceCanvas& canvas,\n                                                   const DisplayList& displayList,\n                                                   const CompositorPlaneList& planeList,\n                                                   const Valdi::BitmapInfo& bitmapInfo,\n                                                   bool shouldClearBitmapBeforeDrawing,\n                                                   size_t rasterId) {\n    if (shouldClearBitmapBeforeDrawing) {\n        Paint paint;\n        paint.setColor(Color::transparent());\n        paint.setBlendMode(SkBlendMode::kSrc);\n        canvas.getSkiaCanvas()->drawPaint(paint.getSkValue());\n    }\n\n    size_t drawablePlaneIndex = 0;\n    for (const auto& plane : planeList) {\n        switch (plane.getType()) {\n            case CompositorPlaneTypeDrawable:\n                displayList.draw(canvas, drawablePlaneIndex, false);\n                drawablePlaneIndex++;\n                break;\n            case CompositorPlaneTypeExternal: {\n                auto rasterScaleX = bitmapInfo.width / displayList.getSize().width;\n                auto rasterScaleY = bitmapInfo.height / displayList.getSize().height;\n                const auto& presenterState = *plane.getExternalSurfacePresenterState();\n\n                auto rasterImage = getOrCreateRasterImageForExternalSurfaceSnapshot(plane.getExternalSurfaceSnapshot(),\n                                                                                    presenterState.frame,\n                                                                                    presenterState.transform,\n                                                                                    bitmapInfo,\n                                                                                    rasterScaleX,\n                                                                                    rasterScaleY,\n                                                                                    rasterId);\n                if (!rasterImage) {\n                    return rasterImage.moveError();\n                }\n\n                auto* skiaCanvas = canvas.getSkiaCanvas();\n                auto saveCount = skiaCanvas->save();\n\n                if (!presenterState.clipPath.isEmpty()) {\n                    auto clipPath = presenterState.clipPath;\n                    clipPath.transform(Matrix::makeScale(rasterScaleX, rasterScaleY));\n                    skiaCanvas->clipPath(clipPath.getSkValue(), true);\n                }\n\n                Paint paint;\n                paint.setAntiAlias(true);\n                paint.setAlpha(presenterState.opacity);\n                skiaCanvas->drawImage(\n                    rasterImage.value()->getSkValue(), 0, 0, SkSamplingOptions(), &paint.getSkValue());\n                skiaCanvas->restoreToCount(saveCount);\n            } break;\n        }\n    }\n\n    return Valdi::Void();\n}\n\nvoid RasterContext::removeUnusedCachedRasterizedExternalSurfaces(size_t rasterId) {\n    std::lock_guard<std::recursive_mutex> lock(_mutex);\n    _cachedRasterizedExternalSurfaces.erase(std::remove_if(_cachedRasterizedExternalSurfaces.begin(),\n                                                           _cachedRasterizedExternalSurfaces.end(),\n                                                           [rasterId](const auto& cachedRasterizedExternalSurface) {\n                                                               return cachedRasterizedExternalSurface.lastRasterId <\n                                                                      rasterId;\n                                                           }),\n                                            _cachedRasterizedExternalSurfaces.end());\n}\n\nValdi::Result<Ref<Image>> RasterContext::getOrCreateRasterImageForExternalSurfaceSnapshot(\n    ExternalSurfaceSnapshot* externalSurfaceSnapshot,\n    const Rect& frame,\n    const Matrix& transform,\n    const Valdi::BitmapInfo& bitmapInfo,\n    Scalar rasterScaleX,\n    Scalar rasterScaleY,\n    size_t rasterId) {\n    std::lock_guard<std::recursive_mutex> lock(_mutex);\n\n    for (auto& cachedRasterizedExternalSurface : _cachedRasterizedExternalSurfaces) {\n        if (cachedRasterizedExternalSurface.externalSurfaceSnapshot.get() == externalSurfaceSnapshot &&\n            cachedRasterizedExternalSurface.frame == frame && cachedRasterizedExternalSurface.transform == transform &&\n            cachedRasterizedExternalSurface.rasterScaleX == rasterScaleX &&\n            cachedRasterizedExternalSurface.rasterScaleY == rasterScaleY) {\n            cachedRasterizedExternalSurface.lastRasterId = rasterId;\n            return cachedRasterizedExternalSurface.image;\n        }\n    }\n\n    VALDI_TRACE(\"SnapDrawing.rasterExternalSurface\");\n    auto bitmapFactory = externalSurfaceSnapshot->getExternalSurface()->getRasterBitmapFactory();\n\n    if (bitmapFactory == nullptr) {\n        return Valdi::Error(\"Cannot rasterize external surface without a bitmap factory\");\n    }\n\n    auto bitmap = _bitmapCache.allocateBitmap(bitmapFactory, bitmapInfo.width, bitmapInfo.height);\n    if (!bitmap) {\n        return bitmap.moveError();\n    }\n\n    void* pixels = bitmap.value()->lockBytes();\n    if (pixels != nullptr) {\n        std::memset(pixels, 0, bitmapInfo.bytesLength());\n        bitmap.value()->unlockBytes();\n    }\n\n    auto rasterIntoResult = externalSurfaceSnapshot->getExternalSurface()->rasterInto(\n        bitmap.value(), frame, transform, rasterScaleX, rasterScaleY);\n    if (!rasterIntoResult) {\n        return rasterIntoResult.error().rethrow(\"Failed to rasterize external surface\");\n    }\n\n    auto image = Image::makeFromBitmap(bitmap.value(), false);\n    if (!image) {\n        return image.moveError();\n    }\n\n    auto& cachedEntry = _cachedRasterizedExternalSurfaces.emplace_back();\n    cachedEntry.externalSurfaceSnapshot = externalSurfaceSnapshot;\n    cachedEntry.frame = frame;\n    cachedEntry.transform = transform;\n    cachedEntry.rasterScaleX = rasterScaleX;\n    cachedEntry.rasterScaleY = rasterScaleY;\n    cachedEntry.lastRasterId = rasterId;\n    cachedEntry.image = image.value();\n\n    return image;\n}\n\nbool RasterContext::needsNewBitmap(const Valdi::BitmapInfo& inputBitmapInfo) const {\n    if (_lastBitmap == nullptr) {\n        return true;\n    }\n\n    auto lastBitmapInfo = _lastBitmap->getInfo();\n    return lastBitmapInfo.width != inputBitmapInfo.width || lastBitmapInfo.height != inputBitmapInfo.height ||\n           lastBitmapInfo.colorType != inputBitmapInfo.colorType ||\n           lastBitmapInfo.alphaType != inputBitmapInfo.alphaType;\n}\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Raster/RasterContext.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Raster/BitmapCache.hpp\"\n#include \"snap_drawing/cpp/Drawing/Raster/RasterDamageResolver.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include <mutex>\n#include <vector>\n\nnamespace Valdi {\n\nclass IBitmap;\nclass IBitmapFactory;\nclass ILogger;\nstruct BitmapInfo;\n} // namespace Valdi\n\nnamespace snap::drawing {\n\nclass DisplayList;\nclass CompositorPlaneList;\nclass ExternalSurfaceSnapshot;\nclass Image;\nstruct ExternalSurfacePresenterState;\nclass DrawableSurfaceCanvas;\n\nenum class ExternalSurfaceRasterizationMethod {\n    /**\n     * The native view will be rasterized using its frame size. If it has a transform (scale, rotation)\n     * set on the view or one of its ancestors, the transform will be applied post rasterization.\n     * The native view is only redrawn when one of its properties changes. This system results in high\n     * draw cache hit rate, but will result in a potentially lower quality image when using transformation.\n     */\n    FAST = 0,\n\n    /**\n     * The native view will be rasterized into the final output buffer with its final transform (scale, rotation)\n     * applied. It will be rasterized again every time scale, rotation, translation or frame changes, or if\n     * one of its properties changes. This system results in a highly accurate rasterization of the native view,\n     * but will result in a potentially lower draw cache hit rate and more expensive rasterization.\n     */\n    ACCURATE = 1,\n};\n\n/**\nRasterContext helps with rasterizing a display list into a target bitmap.\nIf the ExternalSurfaceRasterizationMethod is set to ACCURATE, the RasterContext will perform\ncomposition internally before rasterizing. The given plane list can reference external surfaces\n(like embedded iOS or Android views), in which case the RasterContext will take care of rasterizing\nthem into bitmaps and compositing them into the final bitmap. The raster context holds caches to\navoid re-rasterizing external surfaces for each frame if they don't change.\n\nIf \"enableDeltaRasterization\" is true, all the raster operations will be delta rasterized, with the\nRasterContext keeping a bitmap cache of the last raster pass.\n */\nclass RasterContext : public Valdi::SimpleRefCountable {\npublic:\n    explicit RasterContext(Valdi::ILogger& logger,\n                           ExternalSurfaceRasterizationMethod externalSurfaceRasterizationMethod,\n                           bool enableDeltaRasterization);\n    ~RasterContext() override;\n\n    struct RasterResult {\n        size_t renderedPixelsCount = 0;\n        std::vector<Rect> damageRects;\n    };\n\n    Valdi::Result<RasterResult> raster(const Ref<DisplayList>& displayList,\n                                       const Ref<Valdi::IBitmap>& bitmap,\n                                       bool shouldClearBitmapBeforeDrawing);\n\n    /**\n    Raster the region of the display list that changed since the last draw into the given bitmap.\n     */\n    Valdi::Result<RasterResult> rasterDelta(const Ref<DisplayList>& displayList, const Ref<Valdi::IBitmap>& bitmap);\n\nprivate:\n    struct CachedRasterizedExternalSurface {\n        Ref<Image> image;\n        Ref<ExternalSurfaceSnapshot> externalSurfaceSnapshot;\n        Rect frame;\n        Matrix transform;\n        Scalar rasterScaleX = 0;\n        Scalar rasterScaleY = 0;\n        size_t lastRasterId = 0;\n    };\n\n    struct CompositionResult;\n\n    mutable std::recursive_mutex _mutex;\n    Valdi::ILogger& _logger;\n    ExternalSurfaceRasterizationMethod _externalSurfaceRasterizationMethod;\n    std::vector<CachedRasterizedExternalSurface> _cachedRasterizedExternalSurfaces;\n    BitmapCache _bitmapCache;\n    std::atomic<size_t> _rasterSequence = 0;\n    Ref<Valdi::IBitmap> _lastBitmap;\n    RasterDamageResolver _rasterDamageResolver;\n    bool _deltaRasterizationEnabled;\n\n    CompositionResult performCompositionIfNeeded(const Ref<DisplayList>& displayList) const;\n\n    Valdi::Result<Valdi::Void> doRaster(DrawableSurfaceCanvas& canvas,\n                                        const DisplayList& displayList,\n                                        const CompositorPlaneList& planeList,\n                                        const Valdi::BitmapInfo& bitmapInfo,\n                                        bool shouldClearBitmapBeforeDrawing,\n                                        size_t rasterId);\n\n    Valdi::Result<RasterResult> doRasterDelta(const CompositionResult& compositionResult,\n                                              const Ref<Valdi::IBitmap>& bitmap,\n                                              const Valdi::BitmapInfo& bitmapInfo,\n                                              const std::vector<Rect>& damageRects,\n                                              size_t rasterId);\n\n    Valdi::Result<Valdi::Void> rasterNonDelta(const Ref<Valdi::IBitmap>& bitmap,\n                                              const DisplayList& displayList,\n                                              const CompositorPlaneList& planeList,\n                                              const Valdi::BitmapInfo& bitmapInfo,\n                                              bool shouldClearBitmapBeforeDrawing,\n                                              size_t rasterId);\n\n    Valdi::Result<Ref<Image>> getOrCreateRasterImageForExternalSurfaceSnapshot(\n        ExternalSurfaceSnapshot* externalSurfaceSnapshot,\n        const Rect& frame,\n        const Matrix& transform,\n        const Valdi::BitmapInfo& bitmapInfo,\n        Scalar rasterScaleX,\n        Scalar rasterScaleY,\n        size_t rasterId);\n\n    void removeUnusedCachedRasterizedExternalSurfaces(size_t rasterId);\n\n    bool needsNewBitmap(const Valdi::BitmapInfo& inputBitmapInfo) const;\n\n    std::vector<Rect> computeDamageRects(const Ref<DisplayList>& displayList, const Valdi::BitmapInfo& bitmapInfo);\n\n    Valdi::Result<Valdi::Void> blitDeltaBitmapToOutputBitmap(const Ref<Valdi::IBitmap>& deltaBitmap,\n                                                             const Ref<Valdi::IBitmap>& outputBitmap,\n                                                             const Valdi::BitmapInfo& bitmapInfo,\n                                                             bool fullReplace);\n};\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Raster/RasterDamageResolver.cpp",
    "content": "#include \"snap_drawing/cpp/Drawing/Raster/RasterDamageResolver.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/CompositionState.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\nnamespace snap::drawing {\n\nstruct ComputeDamageVisitor {\n    explicit ComputeDamageVisitor(RasterDamageResolver& rasterDamageResolver, Scalar scaleX, Scalar scaleY)\n        : _rasterDamageResolver(rasterDamageResolver) {\n        Matrix baseMatrix;\n        baseMatrix.setScaleX(scaleX);\n        baseMatrix.setScaleY(scaleY);\n        _contextStack.emplace_back(CompositionState(Path(), baseMatrix, 1.0), 0, false);\n    }\n\n    void visit(const Operations::PushContext& pushContext) {\n        auto& topContext = getCurrentContext();\n\n        _contextStack.emplace_back(topContext.compositionState.pushContext(pushContext.opacity, pushContext.matrix),\n                                   pushContext.layerId,\n                                   pushContext.hasUpdates);\n    }\n\n    void visit(const Operations::PopContext& /*popContext*/) {\n        _contextStack.pop_back();\n    }\n\n    void visit(const Operations::ClipRect& clipRect) {\n        auto& currentContext = getCurrentContext();\n\n        currentContext.compositionState.clipRect(clipRect.width, clipRect.height);\n    }\n\n    void visit(const Operations::ClipRound& clipRound) {\n        auto& currentContext = getCurrentContext();\n\n        currentContext.compositionState.clipRound(clipRound.borderRadius, clipRound.width, clipRound.height);\n    }\n\n    void visit(const Operations::DrawPicture& drawPicture) {\n        addDamageIfNeeded(fromSkValue<Rect>(drawPicture.picture->cullRect()));\n    }\n\n    void visit(const Operations::DrawExternalSurface& drawExternalSurface) {\n        auto size = drawExternalSurface.externalSurfaceSnapshot->getExternalSurface()->getRelativeSize();\n\n        addDamageIfNeeded(Rect::makeXYWH(0, 0, size.width, size.height));\n    }\n\n    void visit(const Operations::PrepareMask& prepareMask) {\n        addDamageIfNeeded(prepareMask.mask->getBounds());\n    }\n\n    void visit(const Operations::ApplyMask& applyMask) {}\n\nprivate:\n    struct Context {\n        CompositionState compositionState;\n        uint64_t layerId = 0;\n        bool hasUpdates = false;\n\n        Context(CompositionState&& compositionState, uint64_t layerId, bool hasUpdates)\n            : compositionState(std::move(compositionState)), layerId(layerId), hasUpdates(hasUpdates) {}\n    };\n\n    RasterDamageResolver& _rasterDamageResolver;\n    Valdi::SmallVector<Context, 8> _contextStack;\n\n    Context& getCurrentContext() {\n        return _contextStack[_contextStack.size() - 1];\n    }\n\n    void addDamageIfNeeded(const Rect& bounds) {\n        const auto& context = getCurrentContext();\n        auto absoluteRect = context.compositionState.getAbsoluteClippedRect(bounds);\n\n        // Apply damage rect expansion:\n        // 1. Round outward to pixel boundaries (floor/ceil) to handle sub-pixel coordinates\n        absoluteRect = absoluteRect.makeOutset();\n\n        // 2. Expand by 1px for anti-aliasing bleed\n        // When rendering, anti-aliasing can affect pixels OUTSIDE the geometric bounds.\n        // The damage rect is used as a clip rect (RasterContext.cpp:251), so if we don't\n        // account for AA bleed, pixels at edges won't be updated, causing trailing artifacts.\n        absoluteRect.left -= 1.0f;\n        absoluteRect.top -= 1.0f;\n        absoluteRect.right += 1.0f;\n        absoluteRect.bottom += 1.0f;\n\n        _rasterDamageResolver.addNonTransparentLayerInRect(context.layerId,\n                                                           absoluteRect,\n                                                           context.compositionState.getAbsoluteMatrix(),\n                                                           context.compositionState.getAbsoluteClipPath(),\n                                                           context.compositionState.getAbsoluteOpacity(),\n                                                           context.hasUpdates);\n    }\n};\n\nRasterDamageResolver::RasterDamageResolver() = default;\nRasterDamageResolver::~RasterDamageResolver() = default;\n\nvoid RasterDamageResolver::beginUpdates(Scalar surfaceWidth, Scalar surfaceHeight) {\n    auto changed = _width != surfaceWidth || _height != surfaceHeight;\n    _width = surfaceWidth;\n    _height = surfaceHeight;\n\n    if (changed) {\n        // Apply same expansion as other damage rects: rounding + 1px margin for anti-aliasing\n        auto damageRect = Rect::makeXYWH(0, 0, surfaceWidth, surfaceHeight).makeOutset();\n        damageRect.left -= 1.0f;\n        damageRect.top -= 1.0f;\n        damageRect.right += 1.0f;\n        damageRect.bottom += 1.0f;\n        addDamageInRect(damageRect);\n    }\n}\n\nstd::vector<Rect> RasterDamageResolver::endUpdates() {\n    resolveDamage();\n\n    std::swap(_previousLayerContents, _layerContents);\n    _layerContents.clear();\n    auto damageRects = std::move(_damageRects);\n    _damageRects = std::vector<Rect>();\n\n    return damageRects;\n}\n\nvoid RasterDamageResolver::resolveDamage() {\n    // Iterate over all previous layer contents, and add damage if the layer was removed, or has updates of any kind.\n    for (const auto& [layerId, layerContent] : _previousLayerContents) {\n        const auto& it = _layerContents.find(layerId);\n        if (it == _layerContents.end()) {\n            // Layer no longer exists, add damage for the entire previous rect\n            addDamageInRect(layerContent.absoluteRect);\n            continue;\n        }\n\n        auto& newLayerContent = it->second;\n\n        if (newLayerContent.hasUpdates || newLayerContent.absoluteMatrix != layerContent.absoluteMatrix ||\n            newLayerContent.clipPath != layerContent.clipPath ||\n            newLayerContent.absoluteRect != layerContent.absoluteRect ||\n            newLayerContent.absoluteOpacity != layerContent.absoluteOpacity) {\n            newLayerContent.hasUpdates = false;\n\n            addDamageInRect(layerContent.absoluteRect);\n            addDamageInRect(newLayerContent.absoluteRect);\n        }\n    }\n\n    // Iterate over new layer contents, add damage for the new layer that were not processed in the previous loop.\n    for (auto& [layerId, layerContent] : _layerContents) {\n        if (layerContent.hasUpdates) {\n            layerContent.hasUpdates = false;\n            addDamageInRect(layerContent.absoluteRect);\n        }\n    }\n}\n\nvoid RasterDamageResolver::addDamageFromDisplayListUpdates(const DisplayList& displayList) {\n    auto scaleX = _width / displayList.getSize().width;\n    auto scaleY = _height / displayList.getSize().height;\n    ComputeDamageVisitor computeDamageVisitor(*this, scaleX, scaleY);\n    for (size_t i = 0; i < displayList.getPlanesCount(); i++) {\n        displayList.visitOperations(i, computeDamageVisitor);\n    }\n}\n\nvoid RasterDamageResolver::addDamageInRect(const Rect& rect) {\n    auto damageToAdd = rect;\n\n    /**\n    TODO(simon): This is a simple and inefficient implementation which removes the\n    intersected damage rects and adds a new damage rect that is the union of all\n    the intersected damage rects.\n     */\n    auto it = _damageRects.begin();\n    while (it != _damageRects.end()) {\n        // Use epsilon-tolerant intersection check for damage rect merging to handle\n        // floating-point precision issues from scaling/transformation\n        if (it->intersectsWithTolerance(damageToAdd)) {\n            damageToAdd.join(*it);\n            _damageRects.erase(it);\n            it = _damageRects.begin();\n            break;\n        } else {\n            it++;\n        }\n    }\n\n    _damageRects.emplace_back(damageToAdd);\n}\n\nvoid RasterDamageResolver::addNonTransparentLayerInRect(uint64_t layerId,\n                                                        const Rect& rect,\n                                                        const Matrix& absoluteMatrix,\n                                                        const Path& clipPath,\n                                                        Scalar absoluteOpacity,\n                                                        bool hasUpdates) {\n    auto& layerContent = _layerContents[layerId];\n    layerContent.absoluteRect = rect;\n    layerContent.absoluteMatrix = absoluteMatrix;\n    layerContent.clipPath = clipPath;\n    layerContent.absoluteOpacity = absoluteOpacity;\n    layerContent.hasUpdates = hasUpdates;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Raster/RasterDamageResolver.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n#include <vector>\n\nnamespace snap::drawing {\n\nclass DisplayList;\nstruct ComputeDamageVisitor;\n\n/**\nRasterDamageResolver helps with resolving dirty rects from a display list. It is used to\nimplement delta rasterization, so that only the areas that have changed since the last\ndrawn frame are rasterized.\n */\nclass RasterDamageResolver {\npublic:\n    RasterDamageResolver();\n    ~RasterDamageResolver();\n\n    void beginUpdates(Scalar surfaceWidth, Scalar surfaceHeight);\n    std::vector<Rect> endUpdates();\n\n    void addDamageFromDisplayListUpdates(const DisplayList& displayList);\n\n    void addDamageInRect(const Rect& rect);\n\nprivate:\n    friend ComputeDamageVisitor;\n    struct LayerContent {\n        Rect absoluteRect;\n        Matrix absoluteMatrix;\n        Scalar absoluteOpacity;\n        Path clipPath;\n        bool hasUpdates;\n    };\n\n    Scalar _width = 0;\n    Scalar _height = 0;\n    std::vector<Rect> _damageRects;\n    Valdi::FlatMap<uint64_t, LayerContent> _previousLayerContents;\n    Valdi::FlatMap<uint64_t, LayerContent> _layerContents;\n\n    void resolveDamage();\n\n    void addNonTransparentLayerInRect(uint64_t layerId,\n                                      const Rect& rect,\n                                      const Matrix& absoluteMatrix,\n                                      const Path& clipPath,\n                                      Scalar absoluteOpacity,\n                                      bool hasUpdates);\n};\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Shader.cpp",
    "content": "//\n//  Shader.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/25/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Shader.hpp\"\n#include \"include/core/SkSamplingOptions.h\"\n#include \"include/core/SkTileMode.h\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n\nnamespace snap::drawing {\n\nstatic SkSamplingOptions makeSmaplingOptions(FilterQuality quality) {\n    switch (quality) {\n        case FilterQualityNone:\n            return SkSamplingOptions();\n        case FilterQualityLow:\n            return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);\n        case FilterQualityMedium:\n            return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);\n        case FilterQualityHigh:\n            return SkSamplingOptions(SkCubicResampler::Mitchell());\n    }\n}\n\nShader::Shader() : Shader(nullptr) {}\n\nShader::Shader(sk_sp<SkShader> skValue) : WrappedSkValue<sk_sp<SkShader>>(std::move(skValue)) {}\nShader::~Shader() = default;\n\nShader Shader::withLocalMatrix(const Matrix& localMatrix) const {\n    return Shader(getSkValue()->makeWithLocalMatrix(localMatrix.getSkValue()));\n}\n\nShader Shader::makeEmpty() {\n    return Shader(SkShaders::Empty());\n}\n\nShader Shader::makeColor(Color color) {\n    return Shader(SkShaders::Color(color.getSkValue()));\n}\n\nShader Shader::makeBlend(BlendMode mode, Shader dst, Shader src) {\n    return Shader(SkShaders::Blend(toSkBlendMode(mode), dst.getSkValue(), src.getSkValue()));\n}\n\nShader Shader::makeImage(const Ref<Image>& image, const Matrix* localMatrix, FilterQuality filterQuality) {\n    auto samplingOptions = makeSmaplingOptions(filterQuality);\n    const auto* skMatrix = localMatrix != nullptr ? &localMatrix->getSkValue() : nullptr;\n    return Shader(image->getSkValue()->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, samplingOptions, skMatrix));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Shader.hpp",
    "content": "//\n//  Shader.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/25/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/BlendMode.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/SkiaBridge.hpp\"\n\n#include \"include/core/SkShader.h\"\n\nnamespace snap::drawing {\n\nclass Image;\n\nenum FilterQuality {\n    FilterQualityNone,   //!< fastest but lowest quality, typically nearest-neighbor\n    FilterQualityLow,    //!< typically bilerp\n    FilterQualityMedium, //!< typically bilerp + mipmaps for down-scaling\n    FilterQualityHigh,   //!< slowest but highest quality, typically bicubic or better\n};\n\nclass Shader : public WrappedSkValue<sk_sp<SkShader>> {\npublic:\n    Shader();\n    ~Shader();\n\n    Shader withLocalMatrix(const Matrix& localMatrix) const;\n\n    static Shader makeEmpty();\n    static Shader makeColor(Color color);\n    static Shader makeBlend(BlendMode mode, Shader dst, Shader src);\n    static Shader makeImage(const Ref<Image>& image, const Matrix* localMatrix, FilterQuality filterQuality);\n\nprivate:\n    explicit Shader(sk_sp<SkShader> skValue);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/DrawableSurface.cpp",
    "content": "//\n//  DrawableSurface.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n\nnamespace snap::drawing {} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp",
    "content": "//\n//  DrawableSurface.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/GraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/Surface.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\nnamespace snap::drawing {\n\nclass DrawableSurface : public Surface {\npublic:\n    virtual GraphicsContext* getGraphicsContext() = 0;\n\n    virtual Valdi::Result<DrawableSurfaceCanvas> prepareCanvas() = 0;\n    virtual void flush() = 0;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.cpp",
    "content": "//\n//  DrawableSurfaceCanvas.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.hpp\"\n#include \"include/core/SkSurface.h\"\n#include \"snap_drawing/cpp/Utils/BytesUtils.hpp\"\n\nnamespace snap::drawing {\n\nDrawableSurfaceCanvas::DrawableSurfaceCanvas(SkSurface* surface, int width, int height)\n    : _surface(surface), _canvas(surface->getCanvas()), _width(width), _height(height) {}\n\nSkCanvas* DrawableSurfaceCanvas::getSkiaCanvas() const {\n    return _canvas;\n}\n\nSkSurface* DrawableSurfaceCanvas::getSkiaSurface() const {\n    return _surface;\n}\n\nint DrawableSurfaceCanvas::getWidth() const {\n    return _width;\n}\n\nint DrawableSurfaceCanvas::getHeight() const {\n    return _height;\n}\n\nValdi::Result<Ref<Image>> DrawableSurfaceCanvas::snapshot() const {\n    auto snapshot = getSkiaSurface()->makeImageSnapshot();\n    if (snapshot == nullptr) {\n        return Valdi::Error(\"Failed to create snapshot\");\n    }\n\n    return Ref<Image>(Valdi::makeShared<Image>(snapshot));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.hpp",
    "content": "//\n//  DrawableSurfaceCanvas.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n\nclass SkSurface;\nclass SkCanvas;\n\nnamespace snap::drawing {\n\nclass DrawableSurfaceCanvas {\npublic:\n    DrawableSurfaceCanvas(SkSurface* surface, int width, int height);\n\n    SkCanvas* getSkiaCanvas() const;\n    SkSurface* getSkiaSurface() const;\n\n    int getWidth() const;\n    int getHeight() const;\n\n    Valdi::Result<Ref<Image>> snapshot() const;\n\nprivate:\n    SkSurface* _surface;\n    SkCanvas* _canvas;\n    int _width;\n    int _height;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/ExternalSurface.cpp",
    "content": "//\n//  ExternalSurface.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/1/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmapFactory.hpp\"\n\nnamespace snap::drawing {\n\nExternalSurface::ExternalSurface() = default;\nExternalSurface::~ExternalSurface() = default;\n\nRef<Valdi::IBitmapFactory> ExternalSurface::getRasterBitmapFactory() const {\n    return nullptr;\n}\n\nValdi::Result<Valdi::Void> ExternalSurface::rasterInto(const Ref<Valdi::IBitmap>& bitmap,\n                                                       const Rect& frame,\n                                                       const Matrix& transform,\n                                                       float rasterScaleX,\n                                                       float rasterScaleY) {\n    return Valdi::Error(\"rasterInto() not implemented\");\n}\n\nconst Size& ExternalSurface::getRelativeSize() const {\n    return _relativeSize;\n}\n\nvoid ExternalSurface::setRelativeSize(const Size& relativeSize) {\n    _relativeSize = relativeSize;\n}\n\nExternalSurfaceSnapshot::ExternalSurfaceSnapshot(Ref<ExternalSurface> externalSurface)\n    : _externalSurface(std::move(externalSurface)) {}\n\nExternalSurfaceSnapshot::~ExternalSurfaceSnapshot() = default;\n\nconst Ref<ExternalSurface>& ExternalSurfaceSnapshot::getExternalSurface() const {\n    return _externalSurface;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp",
    "content": "//\n//  ExternalSurface.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/1/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/Surface/Surface.hpp\"\n\nnamespace Valdi {\nclass IBitmap;\nclass IBitmapFactory;\n} // namespace Valdi\n\nnamespace snap::drawing {\n\nstruct ExternalSurfacePresenterState;\n\n/**\nAn external surface is a surface that is not drawn directly by SnapDrawing.\nIt is typically used to represent embedded platform views like UIView on iOS\nor View on Android.\n */\nclass ExternalSurface : public Surface {\npublic:\n    ExternalSurface();\n    ~ExternalSurface() override;\n\n    virtual Ref<Valdi::IBitmapFactory> getRasterBitmapFactory() const;\n\n    virtual Valdi::Result<Valdi::Void> rasterInto(const Ref<Valdi::IBitmap>& bitmap,\n                                                  const Rect& frame,\n                                                  const Matrix& transform,\n                                                  float rasterScaleX,\n                                                  float rasterScaleY);\n\n    const Size& getRelativeSize() const;\n    void setRelativeSize(const Size& relativeSize);\n\nprivate:\n    Size _relativeSize;\n};\n\n/**\nAn external surface snapshot holds an external surface, and is created every time\nthe ExternalLayer is re-drawn. The ExternalSurface is inherently mutated, whereas the\nExternalSurfaceSnapshot is not. A snapshot gets created whenever the ExternalSurface\nhas been mutated.\n */\nclass ExternalSurfaceSnapshot : public Valdi::SimpleRefCountable {\npublic:\n    explicit ExternalSurfaceSnapshot(Ref<ExternalSurface> externalSurface);\n    ~ExternalSurfaceSnapshot() override;\n\n    const Ref<ExternalSurface>& getExternalSurface() const;\n\nprivate:\n    Ref<ExternalSurface> _externalSurface;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.cpp",
    "content": "//\n//  ExternalSurfacePresenterState.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp\"\n\nnamespace snap::drawing {\n\nExternalSurfacePresenterState::ExternalSurfacePresenterState() = default;\nExternalSurfacePresenterState::ExternalSurfacePresenterState(const Rect& frame,\n                                                             const Matrix& transform,\n                                                             const Path& clipPath,\n                                                             Scalar opacity)\n    : frame(frame), transform(transform), clipPath(clipPath), opacity(opacity) {}\n\nbool ExternalSurfacePresenterState::operator==(const ExternalSurfacePresenterState& other) const {\n    return frame == other.frame && transform == other.transform && clipPath == other.clipPath &&\n           opacity == other.opacity;\n}\n\nbool ExternalSurfacePresenterState::operator!=(const ExternalSurfacePresenterState& other) const {\n    return !(*this == other);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp",
    "content": "//\n//  ExternalSurfacePresenterState.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n\nnamespace snap::drawing {\n\nstruct ExternalSurfacePresenterState {\n    Rect frame;\n    Matrix transform;\n    Path clipPath;\n    Scalar opacity = 0;\n\n    ExternalSurfacePresenterState();\n    ExternalSurfacePresenterState(const Rect& frame, const Matrix& transform, const Path& clipPath, Scalar opacity);\n\n    bool operator==(const ExternalSurfacePresenterState& other) const;\n    bool operator!=(const ExternalSurfacePresenterState& other) const;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/Surface.cpp",
    "content": "//\n//  Surface.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Surface/Surface.hpp\"\n\nnamespace snap::drawing {} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/Surface.hpp",
    "content": "//\n//  Surface.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\nnamespace snap::drawing {\n\nclass Surface : public Valdi::SimpleRefCountable {\npublic:\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/SurfacePresenter.cpp",
    "content": "//\n//  SurfacePresenter.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/16/22.\n//\n\n#include \"SurfacePresenter.hpp\"\n\nnamespace snap::drawing {\n\nSurfacePresenter::SurfacePresenter(SurfacePresenterId id) : _id(id) {}\nSurfacePresenter::~SurfacePresenter() = default;\n\nSurfacePresenterId SurfacePresenter::getId() const {\n    return _id;\n}\n\nbool SurfacePresenter::isExternal() const {\n    return _externalSurfacePresenterState.has_value();\n}\n\nbool SurfacePresenter::isDrawable() const {\n    return !isExternal();\n}\n\nExternalSurface* SurfacePresenter::getExternalSurface() const {\n    return dynamic_cast<ExternalSurface*>(_surface.get());\n}\n\nDrawableSurface* SurfacePresenter::getDrawableSurface() const {\n    return dynamic_cast<DrawableSurface*>(_surface.get());\n}\n\nvoid SurfacePresenter::setAsExternal(ExternalSurface& externalSurface,\n                                     const ExternalSurfacePresenterState& presenterState) {\n    _surface = &externalSurface;\n    _externalSurfacePresenterState = {presenterState};\n}\n\nvoid SurfacePresenter::setAsDrawable() {\n    _externalSurfacePresenterState = std::nullopt;\n}\n\nvoid SurfacePresenter::setSurface(Surface* surface) {\n    _surface = surface;\n}\n\nvoid SurfacePresenter::setDisplayListPlaneIndex(size_t displayListPlaneIndex) {\n    _displayListPlaneIndex = displayListPlaneIndex;\n}\n\nsize_t SurfacePresenter::getDisplayListPlaneIndex() const {\n    return _displayListPlaneIndex;\n}\n\nconst ExternalSurfacePresenterState* SurfacePresenter::getExternalSurfacePresenterState() const {\n    return _externalSurfacePresenterState.has_value() ? &_externalSurfacePresenterState.value() : nullptr;\n}\n\nExternalSurfacePresenterState* SurfacePresenter::getExternalSurfacePresenterState() {\n    return _externalSurfacePresenterState.has_value() ? &_externalSurfacePresenterState.value() : nullptr;\n}\n\nconst std::optional<TimePoint>& SurfacePresenter::getLastDrawnFrameTime() const {\n    return _lastDrawnFrameTime;\n}\n\nvoid SurfacePresenter::setLastDrawnFrameTime(const std::optional<TimePoint>& lastDrawnFrameTime) {\n    _lastDrawnFrameTime = lastDrawnFrameTime;\n}\n\nbool SurfacePresenter::needsDrawForFrameTime(const TimePoint& time) const {\n    return getDrawableSurface() != nullptr && (!_lastDrawnFrameTime || _lastDrawnFrameTime.value() != time);\n}\n\nbool SurfacePresenter::needsSynchronousDraw() const {\n    return _needsSynchronousDraw;\n}\n\nvoid SurfacePresenter::setNeedsSynchronousDraw(bool needsSynchronousDraw) {\n    _needsSynchronousDraw = needsSynchronousDraw;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/SurfacePresenter.hpp",
    "content": "//\n//  SurfacePresenter.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/16/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp\"\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n\n#include <optional>\n\nnamespace snap::drawing {\n\nusing SurfacePresenterId = size_t;\n\n/**\n A SurfacePresenter is an object that can display a drawable surface\n or external surface. It has a id, which is used to identify it\n across the SurfaceManagerPresenter API. When the presenter is drawable,\n it should eventually have a DrawableSurface attached so that the DrawLooper\n can draw into it.\n */\nclass SurfacePresenter {\npublic:\n    explicit SurfacePresenter(SurfacePresenterId id);\n    ~SurfacePresenter();\n\n    SurfacePresenterId getId() const;\n\n    bool isExternal() const;\n    bool isDrawable() const;\n\n    ExternalSurface* getExternalSurface() const;\n    DrawableSurface* getDrawableSurface() const;\n\n    const std::optional<TimePoint>& getLastDrawnFrameTime() const;\n    void setLastDrawnFrameTime(const std::optional<TimePoint>& lastDrawnFrameTime);\n\n    bool needsDrawForFrameTime(const TimePoint& time) const;\n\n    void setAsExternal(ExternalSurface& externalSurface, const ExternalSurfacePresenterState& presenterState);\n    void setAsDrawable();\n\n    void setSurface(Surface* surface);\n\n    bool needsSynchronousDraw() const;\n    void setNeedsSynchronousDraw(bool needsSynchronousDraw);\n\n    void setDisplayListPlaneIndex(size_t displayListPlaneIndex);\n    size_t getDisplayListPlaneIndex() const;\n\n    const ExternalSurfacePresenterState* getExternalSurfacePresenterState() const;\n    ExternalSurfacePresenterState* getExternalSurfacePresenterState();\n\nprivate:\n    SurfacePresenterId _id;\n    Ref<Surface> _surface;\n    size_t _displayListPlaneIndex = 0;\n    std::optional<TimePoint> _lastDrawnFrameTime;\n    std::optional<ExternalSurfacePresenterState> _externalSurfacePresenterState;\n    bool _needsSynchronousDraw = false;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/SurfacePresenterList.cpp",
    "content": "//\n//  SurfacePresenterList.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/16/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenterList.hpp\"\n#include <algorithm>\n\nnamespace snap::drawing {\n\nSurfacePresenterList::SurfacePresenterList() = default;\nSurfacePresenterList::~SurfacePresenterList() = default;\n\nsize_t SurfacePresenterList::size() const {\n    return _surfacePresenters.size();\n}\n\nconst SurfacePresenter* SurfacePresenterList::begin() const {\n    return _surfacePresenters.data();\n}\n\nconst SurfacePresenter* SurfacePresenterList::end() const {\n    return _surfacePresenters.data() + _surfacePresenters.size();\n}\n\nSurfacePresenter* SurfacePresenterList::begin() {\n    return _surfacePresenters.data();\n}\n\nSurfacePresenter* SurfacePresenterList::end() {\n    return _surfacePresenters.data() + _surfacePresenters.size();\n}\n\nconst SurfacePresenter& SurfacePresenterList::operator[](size_t i) const {\n    return _surfacePresenters[i];\n}\n\nSurfacePresenter& SurfacePresenterList::operator[](size_t i) {\n    return _surfacePresenters[i];\n}\n\nconst SurfacePresenter* SurfacePresenterList::getForId(SurfacePresenterId id) const {\n    // Could later also introduce a map if we want fast look up for the surface presenters.\n    // In practice this call should be not frequent, and the number of presenters should be\n    // very low, so this might not be necessary.\n    for (const auto& surfacePresenter : _surfacePresenters) {\n        if (surfacePresenter.getId() == id) {\n            return &surfacePresenter;\n        }\n    }\n    return nullptr;\n}\n\nSurfacePresenter* SurfacePresenterList::getForId(SurfacePresenterId id) {\n    for (auto& surfacePresenter : _surfacePresenters) {\n        if (surfacePresenter.getId() == id) {\n            return &surfacePresenter;\n        }\n    }\n    return nullptr;\n}\n\nSurfacePresenter& SurfacePresenterList::append(SurfacePresenterId id) {\n    return insert(size(), id);\n}\n\nSurfacePresenter& SurfacePresenterList::insert(size_t index, SurfacePresenterId id) {\n    return *_surfacePresenters.insert(_surfacePresenters.begin() + index, SurfacePresenter(id));\n}\n\nvoid SurfacePresenterList::move(size_t fromIndex, size_t toIndex) {\n    if (fromIndex > toIndex) {\n        std::rotate(_surfacePresenters.rend() - fromIndex - 1,\n                    _surfacePresenters.rend() - fromIndex,\n                    _surfacePresenters.rend() - toIndex);\n    } else {\n        std::rotate(_surfacePresenters.begin() + fromIndex,\n                    _surfacePresenters.begin() + fromIndex + 1,\n                    _surfacePresenters.begin() + toIndex + 1);\n    }\n}\n\nvoid SurfacePresenterList::remove(size_t i) {\n    _surfacePresenters.erase(_surfacePresenters.begin() + i);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/SurfacePresenterList.hpp",
    "content": "//\n//  SurfacePresenterList.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/16/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenter.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n#include <optional>\n\nnamespace snap::drawing {\n\nclass SurfacePresenterList {\npublic:\n    SurfacePresenterList();\n    ~SurfacePresenterList();\n\n    size_t size() const;\n\n    const SurfacePresenter* begin() const;\n    const SurfacePresenter* end() const;\n    SurfacePresenter* begin();\n    SurfacePresenter* end();\n\n    const SurfacePresenter& operator[](size_t i) const;\n    SurfacePresenter& operator[](size_t i);\n\n    const SurfacePresenter* getForId(SurfacePresenterId id) const;\n    SurfacePresenter* getForId(SurfacePresenterId id);\n\n    SurfacePresenter& insert(size_t index, SurfacePresenterId id);\n\n    SurfacePresenter& append(SurfacePresenterId id);\n\n    void move(size_t fromIndex, size_t toIndex);\n\n    void remove(size_t i);\n\nprivate:\n    Valdi::SmallVector<SurfacePresenter, 2> _surfacePresenters;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/SurfacePresenterManager.cpp",
    "content": "//\n//  SurfacePresenterManager.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenterManager.hpp\"\n\nnamespace snap::drawing {\n\nvoid SurfacePresenterManager::onDrawableSurfacePresenterUpdated(SurfacePresenterId presenterId) {}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Drawing/Surface/SurfacePresenterManager.hpp",
    "content": "//\n//  SurfacePresenterManager.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/7/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/Surface.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenter.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\nnamespace snap::drawing {\n\n/**\n The SurfacePresenterManager is responsible for displaying surfaces,\n which can be either DrawableSurface's or ExternalSurface's, while respecting their zIndex.\n */\nclass SurfacePresenterManager : public Valdi::SimpleRefCountable {\npublic:\n    /**\n     Create a presenter backed with a DrawableSurface for the given id, inserted at the given zIndex.\n     If the backing DrawableSurface of the presenter can be created synchronously, it can be returned\n     from this function. If returning null, the DrawableSurface for the given presenterId will have to\n     be later set on the DrawLooper so that the looper can draw the content into the surface.\n     */\n    virtual Ref<DrawableSurface> createPresenterWithDrawableSurface(SurfacePresenterId presenterId, size_t zIndex) = 0;\n\n    /**\n     Create a presenter wrapping an ExternalSurface for the given id, inserted at the given zIndex.\n     */\n    virtual void createPresenterForExternalSurface(SurfacePresenterId presenterId,\n                                                   size_t zIndex,\n                                                   ExternalSurface& externalSurface) = 0;\n\n    /**\n     Update the zIndex for the presenter at the given id.\n     */\n    virtual void setSurfacePresenterZIndex(SurfacePresenterId presenterId, size_t zIndex) = 0;\n\n    /**\n     Update the presenter state for a presenter wrapping an ExternalSurface at the given id.\n     */\n    virtual void setExternalSurfacePresenterState(SurfacePresenterId presenterId,\n                                                  const ExternalSurfacePresenterState& presenterState,\n                                                  const ExternalSurfacePresenterState* previousPresenterState) = 0;\n\n    /**\n     Remove the presenter at the given id.\n     */\n    virtual void removeSurfacePresenter(SurfacePresenterId presenterId) = 0;\n\n    /**\n     Called whenever the DrawableSurface attached to the SurfacePresenter has been drawn into.\n     */\n    virtual void onDrawableSurfacePresenterUpdated(SurfacePresenterId presenterId);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Events/Event.cpp",
    "content": "//\n//  Event.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/19/22.\n//\n\n#include \"snap_drawing/cpp/Events/Event.hpp\"\n\nnamespace snap::drawing {\n\nEvent::Event(EventId id, snap::drawing::TimePoint time, EventCallback&& callback) noexcept\n    : id(id), time(time), callback(std::move(callback)) {}\n\nEvent::Event(Event&& other) noexcept : id(other.id), time(other.time), callback(std::move(other.callback)) {\n    other.id = EventId();\n}\n\nEvent& Event::operator=(Event&& other) noexcept {\n    id = other.id;\n    time = other.time;\n    callback = std::move(other.callback);\n\n    other.id = EventId();\n\n    return *this;\n}\n\nbool Event::cancel() {\n    if (!callback) {\n        return false;\n    }\n    callback = EventCallback();\n    return true;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Events/Event.hpp",
    "content": "//\n//  Event.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/19/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Events/EventCallback.hpp\"\n#include \"snap_drawing/cpp/Events/EventId.hpp\"\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n\nnamespace snap::drawing {\n\nstruct Event {\n    EventId id;\n    TimePoint time;\n    EventCallback callback;\n\n    Event(EventId id, TimePoint time, EventCallback&& callback) noexcept;\n    Event(Event&& other) noexcept;\n\n    Event& operator=(Event&& other) noexcept;\n\n    bool cancel();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Events/EventCallback.hpp",
    "content": "//\n//  EventCallback.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/19/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n\nnamespace snap::drawing {\n\nusing EventCallback = Valdi::Function<void(TimePoint, Duration)>;\n\n}\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Events/EventId.hpp",
    "content": "//\n//  EventId.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/19/22.\n//\n\n#pragma once\n\n#include <cstdint>\n\nnamespace snap::drawing {\n\nstruct EventId {\n    uint32_t index = 0;\n    uint32_t sequence = 0;\n\n    constexpr EventId() = default;\n    constexpr EventId(uint32_t index, uint32_t sequence) : index(index), sequence(sequence) {}\n\n    constexpr bool operator==(const EventId& other) const {\n        return index == other.index && sequence == other.sequence;\n    }\n\n    constexpr bool operator!=(const EventId& other) const {\n        return !(*this == other);\n    }\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Events/EventQueue.cpp",
    "content": "//\n//  EventQueue.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/7/20.\n//\n\n#include \"snap_drawing/cpp/Events/EventQueue.hpp\"\n#include <algorithm>\n\n#include \"utils/debugging/Assert.hpp\"\n\nnamespace snap::drawing {\n\nEventQueue::EventQueue(TimePoint initialTime) : _lastTime(initialTime) {}\n\nvoid EventQueue::flush(TimePoint currentTime) {\n    auto delta = currentTime - _lastTime;\n    SC_ASSERT(delta.seconds() >= 0);\n    _lastTime = currentTime;\n\n    collectNextEvents(currentTime);\n\n    for (const auto& event : _nextEvents) {\n        if (event.callback) {\n            event.callback(currentTime, delta);\n        }\n    }\n\n    _nextEvents.clear();\n}\n\nEventId EventQueue::enqueue(Duration delay, EventCallback&& callback) {\n    return enqueue(_lastTime + delay, std::move(callback));\n}\n\nEventId EventQueue::enqueue(TimePoint time, EventCallback&& callback) {\n    auto sequence = ++_sequence;\n    Event event(EventId(), time, std::move(callback));\n\n    auto it =\n        std::upper_bound(_pendingEvents.begin(), _pendingEvents.end(), event, [=](const Event& a, const Event& b) {\n            return a.time < b.time;\n        });\n    auto index = it - _pendingEvents.begin();\n    auto enqueuedEvent = _pendingEvents.emplace(it, std::move(event));\n\n    auto eventId = EventId(static_cast<uint32_t>(index), sequence);\n    enqueuedEvent->id = eventId;\n\n    return eventId;\n}\n\nbool EventQueue::cancel(EventId eventId) {\n    return cancelFromPendingEvents(eventId) || cancelFromProcessingEvents(eventId);\n}\n\nbool EventQueue::cancelFromPendingEvents(EventId eventId) {\n    auto index = static_cast<size_t>(eventId.index);\n    if (index >= _pendingEvents.size()) {\n        return false;\n    }\n\n    auto& event = _pendingEvents[index];\n    if (event.id != eventId) {\n        return false;\n    }\n\n    return event.cancel();\n}\n\nbool EventQueue::cancelFromProcessingEvents(EventId eventId) {\n    for (auto& nextEvent : _nextEvents) {\n        if (nextEvent.id == eventId) {\n            return nextEvent.cancel();\n        }\n    }\n\n    return false;\n}\n\nvoid EventQueue::collectNextEvents(TimePoint currentTime) {\n    while (!_pendingEvents.empty() && currentTime >= _pendingEvents.front().time) {\n        _nextEvents.emplace_back(std::move(_pendingEvents.front()));\n        _pendingEvents.pop_front();\n    }\n}\n\nvoid EventQueue::clear() {\n    _nextEvents.clear();\n    _pendingEvents.clear();\n}\n\nbool EventQueue::isEmpty() const {\n    return _pendingEvents.empty();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Events/EventQueue.hpp",
    "content": "//\n//  EventQueue.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/7/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Events/Event.hpp\"\n\n#include <deque>\n#include <vector>\n\nnamespace snap::drawing {\n\nclass EventQueue {\npublic:\n    explicit EventQueue(TimePoint initialTime);\n\n    void flush(TimePoint currentTime);\n\n    EventId enqueue(Duration delay, EventCallback&& callback);\n    EventId enqueue(TimePoint time, EventCallback&& callback);\n    bool cancel(EventId eventId);\n\n    void clear();\n\n    bool isEmpty() const;\n\nprivate:\n    std::vector<Event> _nextEvents;\n    std::deque<Event> _pendingEvents;\n    TimePoint _lastTime;\n    uint32_t _sequence = 0;\n\n    void collectNextEvents(TimePoint currentTime);\n\n    bool cancelFromPendingEvents(EventId eventId);\n    bool cancelFromProcessingEvents(EventId eventId);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/AnimatedImageLayer.cpp",
    "content": "//\n//  AnimatedImageLayer.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 7/15/22.\n//\n\n#include \"snap_drawing/cpp/Layers/AnimatedImageLayer.hpp\"\n#include \"snap_drawing/cpp/Utils/AnimatedImage.hpp\"\n\nnamespace snap::drawing {\n\nImageAnimation::ImageAnimation() = default;\nImageAnimation::~ImageAnimation() = default;\n\nbool ImageAnimation::run(Layer& layer, Duration delta) {\n    return dynamic_cast<AnimatedImageLayer&>(layer).advanceTime(delta);\n}\n\nvoid ImageAnimation::cancel(Layer& /*layer*/) {}\n\nvoid ImageAnimation::complete(Layer& /*layer*/) {}\n\nvoid ImageAnimation::addCompletion(AnimationCompletion&& /*completion*/) {\n    // no-op\n}\n\nAnimatedImageLayer::AnimatedImageLayer(const Ref<Resources>& resources) : Layer(resources) {}\nAnimatedImageLayer::~AnimatedImageLayer() = default;\n\nvoid AnimatedImageLayer::onInitialize() {\n    Layer::onInitialize();\n\n    _animation = Valdi::makeShared<ImageAnimation>();\n}\n\nvoid AnimatedImageLayer::onDraw(DrawingContext& drawingContext) {\n    if (_image == nullptr) {\n        return;\n    }\n\n    auto drawBounds = drawingContext.drawBounds();\n\n    auto imageWidth = static_cast<Scalar>(_image->getSize().width);\n    auto imageHeight = static_cast<Scalar>(_image->getSize().height);\n    auto imageRect = Rect::makeLTRB(0, 0, imageWidth, imageHeight);\n\n    auto imageDrawBounds = drawBounds.makeFittingSize(imageRect.size(), _fittingSizeMode);\n\n    // Clip to view bounds. Applied before matrix transform\n    auto drawRect = imageDrawBounds.intersection(drawBounds);\n    drawingContext.clipRect(drawRect);\n\n    if (_shouldFlip) {\n        drawingContext.concat(Matrix::makeScaleTranslate(-1, 1, imageDrawBounds.width(), 0));\n    }\n\n    _image->draw(drawingContext.canvas(), imageDrawBounds, _currentTime, _fittingSizeMode);\n}\n\nvoid AnimatedImageLayer::onLoadedAssetChanged(const Ref<Valdi::LoadedAsset>& loadedAsset, bool shouldDrawFlipped) {\n    setImage(Valdi::castOrNull<AnimatedImage>(loadedAsset));\n    setShouldFlip(shouldDrawFlipped);\n}\n\nvoid AnimatedImageLayer::setFittingSizeMode(FittingSizeMode fittingSizeMode) {\n    if (_fittingSizeMode != fittingSizeMode) {\n        _fittingSizeMode = fittingSizeMode;\n        setNeedsDisplay();\n    }\n}\n\nvoid AnimatedImageLayer::setImage(const Ref<AnimatedImage>& image) {\n    if (_image != image) {\n        auto hadImage = _image != nullptr;\n        _image = image;\n\n        updateAnimationTimeWindow();\n        updateActiveAnimation();\n        if (!hadImage) {\n            setCurrentTime(_currentTime, false, true);\n        } else {\n            setCurrentTime(Duration(), false, true);\n        }\n        setNeedsDisplay();\n    }\n}\n\nconst Ref<AnimatedImage>& AnimatedImageLayer::getImage() const {\n    return _image;\n}\n\nvoid AnimatedImageLayer::setAdvanceRate(double advanceRate) {\n    if (_advanceRate != advanceRate) {\n        _advanceRate = advanceRate;\n        updateActiveAnimation();\n    }\n}\n\nvoid AnimatedImageLayer::setShouldLoop(bool shouldLoop) {\n    _shouldLoop = shouldLoop;\n}\n\nvoid AnimatedImageLayer::setShouldFlip(bool shouldFlip) {\n    if (_shouldFlip != shouldFlip) {\n        _shouldFlip = shouldFlip;\n        setNeedsDisplay();\n    }\n}\n\nvoid AnimatedImageLayer::setCurrentTime(const Duration& currentTime) {\n    setCurrentTime(currentTime, true, false);\n}\n\nvoid AnimatedImageLayer::setCurrentTime(const Duration& currentTime, bool relative, bool forceNotify) {\n    bool shouldNotify = forceNotify;\n\n    Duration newTime;\n    if (_image == nullptr) {\n        newTime = currentTime;\n    } else if (relative) {\n        if (_shouldLoop) {\n            auto duration = _clampedEndTime - _clampedStartTime;\n            newTime = currentTime % duration + _clampedStartTime;\n        } else {\n            newTime = std::clamp(_clampedStartTime + currentTime, _clampedStartTime, _clampedEndTime);\n        }\n    } else {\n        if (_shouldLoop) {\n            auto duration = getDuration();\n            newTime = std::clamp(currentTime % duration, _clampedStartTime, _clampedEndTime);\n            ;\n        } else {\n            newTime = std::clamp(currentTime, _clampedStartTime, _clampedEndTime);\n        }\n    }\n\n    if (_currentTime != newTime) {\n        _currentTime = newTime;\n        shouldNotify = true;\n        setNeedsDisplay();\n    }\n    if (_listener != nullptr && shouldNotify) {\n        _listener->onProgress(*this, _currentTime, getDuration());\n    }\n}\n\nbool AnimatedImageLayer::advanceTime(Duration delta) {\n    auto duration = _clampedEndTime - _clampedStartTime;\n    auto newTime = _currentTime + Duration(delta.seconds() * _advanceRate) - _clampedStartTime;\n    bool reachedEnd = false;\n\n    if (duration <= Duration()) {\n        newTime = Duration();\n        reachedEnd = !_shouldLoop;\n    } else if (newTime > duration) {\n        if (_shouldLoop) {\n            newTime = newTime % duration;\n        } else {\n            newTime = duration;\n            reachedEnd = true;\n        }\n    } else if (newTime < Duration()) {\n        if (_shouldLoop) {\n            newTime = duration + (newTime % duration);\n        } else {\n            newTime = Duration();\n            reachedEnd = true;\n        }\n    }\n\n    newTime += _clampedStartTime;\n    setCurrentTime(newTime, false, false);\n\n    return reachedEnd;\n}\n\nvoid AnimatedImageLayer::setAnimationStartTime(const Duration& startTime) {\n    _animationStartTime = startTime;\n    updateAnimationTimeWindow();\n}\n\nvoid AnimatedImageLayer::setAnimationEndTime(const Duration& endTime) {\n    _animationEndTime = endTime;\n    updateAnimationTimeWindow();\n}\n\nvoid AnimatedImageLayer::onRootChanged(ILayerRoot* root) {\n    Layer::onRootChanged(root);\n\n    updateActiveAnimation();\n}\n\nvoid AnimatedImageLayer::updateActiveAnimation() {\n    static auto kAnimationKey = STRING_LITERAL(\"imgAnim\");\n\n    if (getRoot() == nullptr || _image == nullptr || _advanceRate == 0.0) {\n        removeAnimation(kAnimationKey);\n    } else if (!hasAnimation(kAnimationKey)) {\n        addAnimation(kAnimationKey, _animation);\n    }\n}\n\nvoid AnimatedImageLayer::setListener(const Ref<AnimatedImageLayerListener>& listener) {\n    _listener = listener;\n}\n\nconst Ref<AnimatedImageLayerListener>& AnimatedImageLayer::getListener() const {\n    return _listener;\n}\n\nvoid AnimatedImageLayer::updateAnimationTimeWindow() {\n    if (_image == nullptr) {\n        _clampedStartTime = Duration();\n        _clampedEndTime = Duration();\n        return;\n    }\n\n    auto duration = getDuration();\n    _clampedStartTime = std::clamp(_animationStartTime, Duration(), duration);\n    _clampedEndTime = _animationEndTime > Duration() ? std::clamp(_animationEndTime, Duration(), duration) : duration;\n\n    if (_clampedEndTime < _clampedStartTime) {\n        _clampedEndTime = _clampedStartTime;\n    }\n}\n\nDuration AnimatedImageLayer::getDuration() const {\n    return _image != nullptr ? _image->getDuration() : Duration();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/AnimatedImageLayer.hpp",
    "content": "//\n//  AnimatedImageLayer.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 7/15/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n#include \"snap_drawing/cpp/Layers/Interfaces/ILoadedAssetLayer.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Utils/AnimatedImage.hpp\"\n#include \"valdi_core/Cancelable.hpp\"\n\nnamespace snap::drawing {\n\nclass ImageAnimation : public IAnimation {\npublic:\n    ImageAnimation();\n    ~ImageAnimation() override;\n\n    bool run(Layer& layer, Duration delta) override;\n\n    void cancel(Layer& layer) override;\n\n    void complete(Layer& layer) override;\n\n    void addCompletion(AnimationCompletion&& completion) override;\n};\n\nclass AnimatedImageLayer;\n\nclass AnimatedImageLayerListener : public Valdi::SimpleRefCountable {\npublic:\n    virtual void onProgress(AnimatedImageLayer& AnimatedImageLayer, const Duration& time, const Duration& duration) = 0;\n};\n\nclass AnimatedImageLayer : public Layer, public ILoadedAssetLayer {\npublic:\n    explicit AnimatedImageLayer(const Ref<Resources>& resources);\n    ~AnimatedImageLayer() override;\n\n    void onInitialize() override;\n\n    void setImage(const Ref<AnimatedImage>& image);\n    const Ref<AnimatedImage>& getImage() const;\n\n    void setShouldFlip(bool shouldFlip);\n\n    void setAdvanceRate(double advanceRate);\n    void setShouldLoop(bool shouldLoop);\n    void setCurrentTime(const Duration& currentTime);\n    void setAnimationStartTime(const Duration& startTime);\n    void setAnimationEndTime(const Duration& endTime);\n\n    bool advanceTime(Duration delta);\n\n    void setListener(const Ref<AnimatedImageLayerListener>& listener);\n    const Ref<AnimatedImageLayerListener>& getListener() const;\n\n    void onLoadedAssetChanged(const Ref<Valdi::LoadedAsset>& loadedAsset, bool shouldDrawFlipped) override;\n\n    void setFittingSizeMode(FittingSizeMode fittingSizeMode);\n\nprotected:\n    void onDraw(DrawingContext& drawingContext) override;\n    void onRootChanged(ILayerRoot* root) override;\n\nprivate:\n    Ref<AnimatedImage> _image;\n    Ref<ImageAnimation> _animation;\n    Ref<AnimatedImageLayerListener> _listener;\n    Duration _currentTime;\n    Duration _animationStartTime;\n    Duration _animationEndTime;\n    Duration _clampedStartTime;\n    Duration _clampedEndTime;\n    bool _shouldLoop = false;\n    bool _shouldFlip = false;\n    double _advanceRate = 0.0;\n    FittingSizeMode _fittingSizeMode = FittingSizeModeCenterScaleFit;\n\n    void updateActiveAnimation();\n    void setCurrentTime(const Duration& currentTime, bool relative, bool forceNotify);\n\n    Duration getDuration() const;\n    void updateAnimationTimeWindow();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ButtonLayer.cpp",
    "content": "//\n//  ButtonLayer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#include \"snap_drawing/cpp/Layers/ButtonLayer.hpp\"\n\nnamespace snap::drawing {\n\nButtonLayer::ButtonLayer(const Ref<Resources>& resources) : TextLayer(resources) {\n    setTextAlign(TextAlignCenter);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ButtonLayer.hpp",
    "content": "//\n//  ButtonLayer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/TextLayer.hpp\"\n\nnamespace snap::drawing {\n\nclass ButtonLayer : public TextLayer {\npublic:\n    explicit ButtonLayer(const Ref<Resources>& resources);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ExternalLayer.cpp",
    "content": "//\n//  ExternalLayer.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/1/22.\n//\n\n#include \"snap_drawing/cpp/Layers/ExternalLayer.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurfacePresenterState.hpp\"\n#include \"snap_drawing/cpp/Layers/Interfaces/ILayerRoot.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmapFactory.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n\nnamespace snap::drawing {\n\nExternalLayer::ExternalLayer(const Ref<Resources>& resources) : Layer(resources) {}\nExternalLayer::~ExternalLayer() = default;\n\nvoid ExternalLayer::setExternalSurface(const Ref<ExternalSurface>& externalSurface) {\n    if (_externalSurface != externalSurface) {\n        _externalSurface = externalSurface;\n        setNeedsDisplay();\n    }\n}\n\nconst Ref<ExternalSurface>& ExternalLayer::getExternalSurface() const {\n    return _externalSurface;\n}\n\nbool ExternalLayer::shouldRasterizeExternalSurface() const {\n    auto* root = getRoot();\n    if (root == nullptr) {\n        return true;\n    }\n    return root->shouldRasterizeExternalSurface();\n}\n\nValdi::Result<Ref<Image>> ExternalLayer::rasterExternalSurface(int width, int height) const {\n    VALDI_TRACE(\"SnapDrawing.rasterExternalSurface\");\n    auto bitmapFactory = _externalSurface->getRasterBitmapFactory();\n    if (bitmapFactory == nullptr) {\n        return Valdi::Error(\"No bitmap factory\");\n    }\n    // When rasterizing to off-screen buffer, use 1:1 scale. This is because\n    // unlike the display, the off-screen rasterization buffer is not high\n    // density.\n    auto displayScale = shouldRasterizeExternalSurface() ? 1 : getResources()->getDisplayScale();\n    auto widthInPixels = static_cast<int>(width * displayScale);\n    auto heightInPixels = static_cast<int>(height * displayScale);\n    auto bitmap = bitmapFactory->createBitmap(widthInPixels, heightInPixels);\n    if (!bitmap) {\n        return bitmap.moveError();\n    }\n\n    auto rasterIntoResult = _externalSurface->rasterInto(\n        bitmap.value(), Rect::makeXYWH(0, 0, width, height), Matrix(), displayScale, displayScale);\n    if (!rasterIntoResult) {\n        return rasterIntoResult.error().rethrow(\"Failed to rasterize external surface\");\n    }\n\n    return Image::makeFromBitmap(bitmap.value(), false);\n}\n\nvoid ExternalLayer::onDraw(DrawingContext& drawingContext) {\n    if (_externalSurface != nullptr) {\n        auto frameSize = getFrame().size();\n        _externalSurface->setRelativeSize(frameSize);\n\n        if (shouldRasterizeExternalSurface()) {\n            auto imageResult = rasterExternalSurface(frameSize.width, frameSize.height);\n\n            if (imageResult) {\n                auto image = imageResult.moveValue();\n                auto imageRect =\n                    Rect::makeLTRB(0, 0, static_cast<Scalar>(image->width()), static_cast<Scalar>(image->height()));\n                auto bounds = Rect::makeXYWH(0, 0, frameSize.width, frameSize.height);\n                drawingContext.drawImage(*image, imageRect, bounds, nullptr);\n            } else {\n                VALDI_ERROR(getLogger(), \"Failed to draw ExternalLayer: {}\", imageResult.error());\n            }\n        } else {\n            drawingContext.drawExternalSurface(_externalSurface);\n        }\n    }\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ExternalLayer.hpp",
    "content": "//\n//  ExternalLayer.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 2/1/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\nnamespace snap::drawing {\n\n/**\n An ExternalLayer is a special Layer that draws an ExternalSurface instance.\n The ExternalSurface represents an external rendering source that SnapDrawing\n does not directly manage.\n */\nclass ExternalLayer : public Layer {\npublic:\n    explicit ExternalLayer(const Ref<Resources>& resources);\n    ~ExternalLayer() override;\n\n    void setExternalSurface(const Ref<ExternalSurface>& externalSurface);\n    const Ref<ExternalSurface>& getExternalSurface() const;\n\n    bool shouldRasterizeExternalSurface() const;\n\nprotected:\n    void onDraw(DrawingContext& drawingContext) override;\n\nprivate:\n    Ref<ExternalSurface> _externalSurface;\n\n    Valdi::Result<Ref<Image>> rasterExternalSurface(int width, int height) const;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/FlexboxLayer.cpp",
    "content": "//\n//  FlexboxLayer.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 3/10/23.\n//\n\n#include \"snap_drawing/cpp/Layers/FlexboxLayer.hpp\"\n#include <yoga/YGNode.h>\n\nnamespace snap::drawing {\n\nstatic YGConfigRef makeYogaConfig() {\n    auto* config = YGConfigNew();\n    YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureWebFlexBasis, true);\n    return config;\n}\n\nstatic YGConfigRef getYogaConfig() {\n    static auto* kYogaConfig = makeYogaConfig();\n\n    return kYogaConfig;\n}\n\nstruct FlexboxNode : public Valdi::SimpleRefCountable {\n    YGNodeRef yogaNode;\n\n    FlexboxNode() : yogaNode(YGNodeNewWithConfig(getYogaConfig())) {}\n\n    ~FlexboxNode() override {\n        YGNodeFree(yogaNode);\n    }\n\n    void calculateLayout(Size size, bool isRightToLeft) const {\n        auto ownerWidth =\n            (size.width == std::numeric_limits<Scalar>::max() || std::isnan(size.width)) ? YGUndefined : size.width;\n        auto ownerHeight =\n            (size.height == std::numeric_limits<Scalar>::max() || std::isnan(size.height)) ? YGUndefined : size.height;\n\n        YGNodeCalculateLayout(yogaNode, ownerWidth, ownerHeight, isRightToLeft ? YGDirectionRTL : YGDirectionLTR);\n    }\n\n    void setLayoutDirty() const {\n        if (yogaNode->hasMeasureFunc()) {\n            YGNodeMarkDirty(yogaNode);\n        }\n    }\n\n    Rect getFrame() const {\n        return Rect::makeXYWH(sanitizeYogaValue(YGNodeLayoutGetLeft(yogaNode)),\n                              sanitizeYogaValue(YGNodeLayoutGetTop(yogaNode)),\n                              sanitizeYogaValue(YGNodeLayoutGetWidth(yogaNode)),\n                              sanitizeYogaValue(YGNodeLayoutGetHeight(yogaNode)));\n    }\n\nprivate:\n    static inline float sanitizeYogaValue(float yogaValue) {\n        if (std::isnan(yogaValue)) {\n            return 0.0;\n        }\n\n        return yogaValue;\n    }\n};\n\nstatic YGFloatOptional toOptional(const std::optional<Scalar>& value) {\n    if (value) {\n        return YGFloatOptional(value.value());\n    } else {\n        return YGFloatOptional();\n    }\n}\n\nFlexboxAttributes::FlexboxAttributes(YGStyle* style) : _style(style) {}\n\nFlexboxAttributes& FlexboxAttributes::setDirection(YGDirection value) {\n    _style->direction() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setFlexDirection(YGFlexDirection value) {\n    _style->flexDirection() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setJustifyContent(YGJustify value) {\n    _style->justifyContent() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setAlignItems(YGAlign value) {\n    _style->alignItems() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setAlignContent(YGAlign value) {\n    _style->alignContent() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setAlignSelf(YGAlign value) {\n    _style->alignSelf() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setPadding(YGEdge edge, FlexValue value) {\n    _style->padding()[edge] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setMargin(YGEdge edge, FlexValue value) {\n    _style->margin()[edge] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setBorder(YGEdge edge, FlexValue value) {\n    _style->border()[edge] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setPosition(YGEdge edge, FlexValue value) {\n    _style->position()[edge] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setPositionType(YGPositionType value) {\n    _style->positionType() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setFlexWrap(YGWrap value) {\n    _style->flexWrap() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setOverflow(YGOverflow value) {\n    _style->overflow() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setDisplay(YGDisplay value) {\n    _style->display() = value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setFlex(std::optional<Scalar> value) {\n    _style->flex() = toOptional(value);\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setFlexGrow(std::optional<Scalar> value) {\n    _style->flexGrow() = toOptional(value);\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setFlexShrink(std::optional<Scalar> value) {\n    _style->flexShrink() = toOptional(value);\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setFlexBasis(FlexValue value) {\n    _style->flexBasis() = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setWidth(FlexValue value) {\n    _style->dimensions()[YGDimensionWidth] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setHeight(FlexValue value) {\n    _style->dimensions()[YGDimensionHeight] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setMinWidth(FlexValue value) {\n    _style->minDimensions()[YGDimensionWidth] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setMinHeight(FlexValue value) {\n    _style->minDimensions()[YGDimensionHeight] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setMaxWidth(FlexValue value) {\n    _style->maxDimensions()[YGDimensionWidth] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setMaxHeight(FlexValue value) {\n    _style->maxDimensions()[YGDimensionHeight] = value.value;\n    return *this;\n}\n\nFlexboxAttributes& FlexboxAttributes::setAspectRatio(std::optional<Scalar> value) {\n    _style->aspectRatio() = toOptional(value);\n    return *this;\n}\n\nvoid onYogaNodeDirty(YGNodeRef node) {\n    auto* layer = reinterpret_cast<snap::drawing::Layer*>(node->getContext());\n    if (layer == nullptr) {\n        return;\n    }\n\n    layer->setNeedsLayout();\n}\n\nYGSize onYogaMeasure(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) {\n    auto* layer = reinterpret_cast<snap::drawing::Layer*>(node->getContext());\n    if (layer == nullptr) {\n        return {.width = 0, .height = 0};\n    }\n\n    auto outputSize = layer->sizeThatFits(\n        Size::make(widthMode == YGMeasureModeUndefined ? std::numeric_limits<Scalar>::max() : width,\n                   heightMode == YGMeasureModeUndefined ? std::numeric_limits<Scalar>::max() : height));\n\n    return {.width = outputSize.width, .height = outputSize.height};\n}\n\nstatic Ref<FlexboxNode> createAndAssociateFlexboxNode(Layer* layer, bool isOwner) {\n    auto flexboxNode = Valdi::makeShared<FlexboxNode>();\n    layer->setAttachedData(flexboxNode);\n\n    flexboxNode->yogaNode->setContext(static_cast<snap::drawing::Layer*>(layer));\n    flexboxNode->yogaNode->setDirtiedFunc(&onYogaNodeDirty);\n\n    if (!isOwner) {\n        flexboxNode->yogaNode->setMeasureFunc(&onYogaMeasure);\n    }\n\n    return flexboxNode;\n}\n\nstatic Ref<FlexboxNode> getFlexboxNode(const Layer* layer) {\n    return Valdi::castOrNull<FlexboxNode>(layer->getAttachedData());\n}\n\nstatic Ref<FlexboxNode> mustGetFlexboxNode(const Layer* layer) {\n    auto node = getFlexboxNode(layer);\n    SC_ASSERT_NOTNULL(node);\n    return node;\n}\n\nstatic Ref<FlexboxNode> getOrCreateFlexboxNode(Layer* layer) {\n    auto flexboxNode = getFlexboxNode(layer);\n    if (flexboxNode == nullptr) {\n        flexboxNode = createAndAssociateFlexboxNode(layer, false);\n    }\n\n    return flexboxNode;\n}\n\nFlexboxLayer::FlexboxLayer(const Ref<Resources>& resources) : Layer(resources) {}\nFlexboxLayer::~FlexboxLayer() = default;\n\nvoid FlexboxLayer::onInitialize() {\n    createAndAssociateFlexboxNode(this, true);\n}\n\nSize FlexboxLayer::sizeThatFits(Size maxSize) {\n    auto node = getOrCreateFlexboxNode(this);\n\n    node->calculateLayout(maxSize, isRightToLeft());\n    return node->getFrame().size();\n}\n\nvoid FlexboxLayer::onBoundsChanged() {\n    Layer::onBoundsChanged();\n\n    setNeedsLayout();\n}\n\nvoid FlexboxLayer::onLayout() {\n    Layer::onLayout();\n\n    auto node = mustGetFlexboxNode(this);\n    if (YGNodeGetOwner(node->yogaNode) == nullptr) {\n        // we are the root node, calculate the layout starting from us\n        node->calculateLayout(getFrame().size(), isRightToLeft());\n    }\n\n    auto childrenSize = getChildrenSize();\n    for (size_t i = 0; i < childrenSize; i++) {\n        auto child = getChild(i);\n        auto childNode = mustGetFlexboxNode(child.get());\n\n        child->setFrame(childNode->getFrame());\n    }\n}\n\nFlexboxAttributes FlexboxLayer::updateLayoutAttributes() {\n    return updateLayoutAttributesForLayer(this);\n}\n\nFlexboxAttributes FlexboxLayer::updateLayoutAttributesForLayer(const Ref<Layer>& layer) {\n    return updateLayoutAttributesForLayer(layer.get());\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nFlexboxAttributes FlexboxLayer::updateLayoutAttributesForLayer(Layer* layer) {\n    auto flexboxNode = mustGetFlexboxNode(layer);\n    auto& style = flexboxNode->yogaNode->getStyle();\n\n    flexboxNode->setLayoutDirty();\n\n    return FlexboxAttributes(&style);\n}\n\nvoid FlexboxLayer::requestLayout(ILayer* layer) {\n    Layer::requestLayout(layer);\n\n    auto* childLayer = dynamic_cast<Layer*>(layer);\n    if (childLayer != nullptr && childLayer != this && childLayer->getParent().get() == this) {\n        mustGetFlexboxNode(childLayer)->setLayoutDirty();\n    }\n}\n\nvoid FlexboxLayer::onChildRemoved(Layer* childLayer) {\n    auto ownerNode = mustGetFlexboxNode(this);\n    auto childNode = mustGetFlexboxNode(childLayer);\n\n    YGNodeRemoveChild(ownerNode->yogaNode, childNode->yogaNode);\n}\n\nvoid FlexboxLayer::onChildInserted(Layer* childLayer, size_t index) {\n    auto ownerNode = mustGetFlexboxNode(this);\n    auto childNode = getOrCreateFlexboxNode(childLayer);\n\n    auto* previousParent = YGNodeGetParent(childNode->yogaNode);\n    if (previousParent != nullptr) {\n        YGNodeRemoveChild(previousParent, childNode->yogaNode);\n    }\n    YGNodeInsertChild(ownerNode->yogaNode, childNode->yogaNode, static_cast<uint32_t>(index));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/FlexboxLayer.hpp",
    "content": "//\n//  FlexboxLayer.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 3/10/23.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n\n#include <yoga/YGStyle.h>\n\nstruct YGNode;\n\nnamespace snap::drawing {\n\nstruct FlexValue {\n    facebook::yoga::detail::CompactValue value;\n\n    constexpr FlexValue(facebook::yoga::detail::CompactValue value) : value(value) {}\n\n    inline static FlexValue point(Scalar value) {\n        return facebook::yoga::detail::CompactValue::of<YGUnitPoint>(value);\n    }\n\n    inline static FlexValue percent(Scalar value) {\n        return facebook::yoga::detail::CompactValue::of<YGUnitPercent>(value);\n    }\n\n    inline static FlexValue undefined() {\n        return facebook::yoga::detail::CompactValue::ofUndefined();\n    }\n};\n\nclass FlexboxAttributes {\npublic:\n    FlexboxAttributes(YGStyle* _style);\n\n    FlexboxAttributes& setDirection(YGDirection value);\n\n    FlexboxAttributes& setFlexDirection(YGFlexDirection value);\n\n    FlexboxAttributes& setJustifyContent(YGJustify value);\n    FlexboxAttributes& setAlignItems(YGAlign value);\n    FlexboxAttributes& setAlignContent(YGAlign value);\n    FlexboxAttributes& setAlignSelf(YGAlign value);\n\n    FlexboxAttributes& setPadding(YGEdge edge, FlexValue value);\n    FlexboxAttributes& setMargin(YGEdge edge, FlexValue value);\n    FlexboxAttributes& setBorder(YGEdge edge, FlexValue value);\n    FlexboxAttributes& setPosition(YGEdge edge, FlexValue value);\n\n    FlexboxAttributes& setPositionType(YGPositionType value);\n    FlexboxAttributes& setFlexWrap(YGWrap value);\n    FlexboxAttributes& setOverflow(YGOverflow value);\n    FlexboxAttributes& setDisplay(YGDisplay value);\n    FlexboxAttributes& setFlex(std::optional<Scalar> value);\n    FlexboxAttributes& setFlexGrow(std::optional<Scalar> value);\n    FlexboxAttributes& setFlexShrink(std::optional<Scalar> value);\n\n    FlexboxAttributes& setFlexBasis(FlexValue value);\n\n    FlexboxAttributes& setWidth(FlexValue value);\n    FlexboxAttributes& setHeight(FlexValue value);\n    FlexboxAttributes& setMinWidth(FlexValue value);\n    FlexboxAttributes& setMinHeight(FlexValue value);\n\n    FlexboxAttributes& setMaxWidth(FlexValue value);\n    FlexboxAttributes& setMaxHeight(FlexValue value);\n\n    FlexboxAttributes& setAspectRatio(std::optional<Scalar> value);\n\nprivate:\n    YGStyle* _style;\n};\n\n/**\n A Layer subclass that can layout its children with the Flexbox layout\n algorithm implemented by Yoga. The FlexboxLayer will associate Flexbox node\n for each children added to the layer. Each children can be a regular Layer\n or a FlexboxLayer as well.\n */\nclass FlexboxLayer : public Layer {\npublic:\n    explicit FlexboxLayer(const Ref<Resources>& resources);\n    ~FlexboxLayer() override;\n\n    void onInitialize() override;\n\n    Size sizeThatFits(Size maxSize) override;\n\n    /**\n     Get the flexbox attributes for the Flexbox node of this layer.\n     */\n    FlexboxAttributes updateLayoutAttributes();\n\n    /**\n     Get the flexbox attributes for the Flexbox node of the given layer.\n     The layer needs to be a FlexboxLayer or has a FlexboxLayer as its parent.\n     */\n    FlexboxAttributes updateLayoutAttributesForLayer(const Ref<Layer>& layer);\n\n    /**\n     Get the flexbox attributes for the Flexbox node of the given layer.\n     The layer needs to be a FlexboxLayer or has a FlexboxLayer as its parent.\n     */\n    FlexboxAttributes updateLayoutAttributesForLayer(Layer* layer);\n\n    void requestLayout(ILayer* layer) override;\n\nprotected:\n    void onBoundsChanged() override;\n    void onLayout() override;\n\n    void onChildRemoved(Layer* childLayer) override;\n    void onChildInserted(Layer* childLayer, size_t index) override;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ImageLayer.cpp",
    "content": "//\n//  ImageLayer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#include \"snap_drawing/cpp/Layers/ImageLayer.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/Shader.hpp\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n\n#include \"valdi_core/cpp/Resources/Asset.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Marshaller.hpp\"\n\n#include \"valdi_core/AssetLoadObserver.hpp\"\n#include \"valdi_core/Platform.hpp\"\n\n#include \"include/core/SkColorFilter.h\"\n#include \"include/effects/SkImageFilters.h\"\n\nnamespace snap::drawing {\n\nconstexpr Scalar kUIKitToSkiaBlurRatio = 2.0f;\n\nImageLayer::ImageLayer(const Ref<Resources>& resources) : Layer(resources), _tintColor(Color::transparent()) {\n    _imagePaint.setAntiAlias(true);\n}\n\nImageLayer::~ImageLayer() = default;\n\n// From https://github.com/servo/skia/blob/master/src/effects/SkBlurMask.cpp#L23\nstatic const SkScalar kBlurSigmaScale = 0.57735f;\n\nstatic Scalar radiusToSigma(Scalar radius) {\n    return radius > 0 ? kBlurSigmaScale * radius + 0.5f : 0.0f;\n}\n\nvoid ImageLayer::onDraw(DrawingContext& drawingContext) {\n    Layer::onDraw(drawingContext);\n\n    if (_image == nullptr) {\n        return;\n    }\n\n    auto drawBounds = drawingContext.drawBounds();\n\n    auto imageWidth = static_cast<Scalar>(_image->width());\n    auto imageHeight = static_cast<Scalar>(_image->height());\n\n    if (imageWidth == 0 || imageHeight == 0) {\n        return;\n    }\n\n    auto imageRect = Rect::makeLTRB(0, 0, imageWidth, imageHeight);\n    auto imageDrawBounds = drawBounds.makeFittingSize(imageRect.size(), _fittingSizeMode);\n\n    if (_contentScaleX != 1.0) {\n        auto previousWidth = imageDrawBounds.width();\n        auto offsetX = (previousWidth - previousWidth * _contentScaleX) / 2.0;\n        imageDrawBounds.left += offsetX;\n        imageDrawBounds.right -= offsetX;\n    }\n\n    if (_contentScaleY != 1.0) {\n        auto previousHeight = imageDrawBounds.height();\n        auto offsetY = (previousHeight - previousHeight * _contentScaleY) / 2.0;\n        imageDrawBounds.top += offsetY;\n        imageDrawBounds.bottom -= offsetY;\n    }\n\n    auto drawRect = imageDrawBounds.intersection(drawBounds);\n\n    auto drawWidth = imageDrawBounds.width();\n    auto drawHeight = imageDrawBounds.height();\n\n    Scalar matrixScaleX = drawWidth / imageWidth;\n    Scalar matrixScaleY = drawHeight / imageHeight;\n    Scalar matrixTranslateX = imageDrawBounds.left;\n    Scalar matrixTranslateY = imageDrawBounds.top;\n\n    if (_shouldFlip) {\n        matrixScaleX *= -1.0;\n        matrixTranslateX += drawWidth;\n    }\n\n    auto localMatrix = Matrix::makeScaleTranslate(matrixScaleX, matrixScaleY, matrixTranslateX, matrixTranslateY);\n\n    if (_contentRotation != 0.0) {\n        Scalar centerX = localMatrix.getTranslateX() + drawWidth / 2.0f;\n        Scalar centerY = localMatrix.getTranslateY() + drawHeight / 2.0f;\n        localMatrix.postRotate(_contentRotation, centerX, centerY);\n    }\n\n    auto imagePaint = _imagePaint;\n\n    const auto& filter = _image->getFilter();\n\n    if (filter != nullptr) {\n        auto& skPaint = imagePaint.getSkValue();\n        if (!filter->isIdentityColorMatrix()) {\n            auto colorMatrixFilter = SkColorFilters::Matrix(filter->getColorMatrix());\n            if (skPaint.getColorFilter() == nullptr) {\n                skPaint.setColorFilter(std::move(colorMatrixFilter));\n            } else {\n                skPaint.setColorFilter(SkColorFilters::Compose(std::move(colorMatrixFilter), skPaint.refColorFilter()));\n            }\n        }\n\n        if (filter->getBlurRadius() != 0.0f) {\n            auto blurSigma = radiusToSigma(filter->getBlurRadius()) * kUIKitToSkiaBlurRatio;\n            auto xScaleRatio = drawRect.width() / imageWidth;\n            auto yScaleRatio = drawRect.height() / imageHeight;\n            skPaint.setImageFilter(\n                SkImageFilters::Blur(blurSigma * xScaleRatio, blurSigma * yScaleRatio, SkTileMode::kClamp, nullptr));\n            drawingContext.clipRect(drawRect);\n        }\n    }\n\n    if (_optimizeRenderingForFrequentUpdates) {\n        if (!getBorderRadius().isEmpty()) {\n            drawingContext.clipPath(getBorderRadius().getPath(drawBounds));\n        } else {\n            drawingContext.clipRect(drawBounds);\n        }\n        drawingContext.drawImage(*_image, imageRect, imageDrawBounds, &imagePaint);\n    } else {\n        imagePaint.setShader(Shader::makeImage(_image, &localMatrix, FilterQualityLow));\n\n        if (!getBorderRadius().isEmpty()) {\n            auto drawPath = getBorderRadius().getPath(drawBounds);\n            if (drawRect != drawBounds) {\n                drawingContext.clipRect(drawRect);\n            }\n\n            drawingContext.drawPaint(imagePaint, drawPath);\n        } else {\n            drawingContext.drawPaint(imagePaint, drawRect);\n        }\n    }\n}\n\nvoid ImageLayer::onLoadedAssetChanged(const Ref<Valdi::LoadedAsset>& loadedAsset, bool shouldDrawFlipped) {\n    setImage(Valdi::castOrNull<Image>(loadedAsset));\n    setShouldFlip(shouldDrawFlipped);\n}\n\nvoid ImageLayer::setFittingSizeMode(FittingSizeMode fittingSizeMode) {\n    if (_fittingSizeMode != fittingSizeMode) {\n        _fittingSizeMode = fittingSizeMode;\n        setNeedsDisplay();\n    }\n}\n\nvoid ImageLayer::setImage(const Ref<Image>& image) {\n    if (_image != image) {\n        _image = image;\n        setNeedsDisplay();\n    }\n}\n\nvoid ImageLayer::setShouldFlip(bool shouldFlip) {\n    if (_shouldFlip != shouldFlip) {\n        _shouldFlip = shouldFlip;\n        setNeedsDisplay();\n    }\n}\n\nvoid ImageLayer::setTintColor(Color tintColor) {\n    if (_tintColor != tintColor) {\n        _tintColor = tintColor;\n        _imagePaint.setBlendColorFilter(tintColor);\n        setNeedsDisplay();\n    }\n}\n\nvoid ImageLayer::setContentScaleX(Scalar contentScaleX) {\n    if (_contentScaleX != contentScaleX) {\n        _contentScaleX = contentScaleX;\n        setNeedsDisplay();\n    }\n}\n\nvoid ImageLayer::setContentScaleY(Scalar contentScaleY) {\n    if (_contentScaleY != contentScaleY) {\n        _contentScaleY = contentScaleY;\n        setNeedsDisplay();\n    }\n}\n\nvoid ImageLayer::setContentRotation(Scalar contentRotation) {\n    if (_contentRotation != contentRotation) {\n        _contentRotation = contentRotation;\n        setNeedsDisplay();\n    }\n}\n\nvoid ImageLayer::setOptimizeRenderingForFrequentUpdates(bool optimizeRenderingForFrequentUpdates) {\n    _optimizeRenderingForFrequentUpdates = optimizeRenderingForFrequentUpdates;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ImageLayer.hpp",
    "content": "//\n//  ImageLayer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Interfaces/ILoadedAssetLayer.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n\nnamespace Valdi {\nclass Asset;\n}\n\nnamespace snap::drawing {\n\nclass Image;\nclass ValdiAnimator;\n\nclass ImageLayer : public Layer, public ILoadedAssetLayer {\npublic:\n    explicit ImageLayer(const Ref<Resources>& resources);\n    ~ImageLayer() override;\n\n    void setImage(const Ref<Image>& image);\n    void setTintColor(Color tintColor);\n    void setShouldFlip(bool shouldFlip);\n\n    void setContentScaleX(Scalar contentScaleX);\n    void setContentScaleY(Scalar contentScaleY);\n    void setContentRotation(Scalar contentRotation);\n\n    void setFittingSizeMode(FittingSizeMode fittingSizeMode);\n\n    void setOptimizeRenderingForFrequentUpdates(bool optimizeRenderingForFrequentUpdates);\n\n    void onLoadedAssetChanged(const Ref<Valdi::LoadedAsset>& loadedAsset, bool shouldDrawFlipped) override;\n\nprotected:\n    void onDraw(DrawingContext& drawingContext) override;\n\nprivate:\n    Ref<Image> _image;\n    Color _tintColor;\n    Paint _imagePaint;\n    FittingSizeMode _fittingSizeMode = FittingSizeModeFill;\n    bool _shouldFlip = false;\n    bool _optimizeRenderingForFrequentUpdates = false;\n\n    Scalar _contentScaleX = 1;\n    Scalar _contentScaleY = 1;\n    Scalar _contentRotation = 0;\n\n    void handleAssetLoaded(const Ref<Valdi::Asset>& asset, const Valdi::Result<Ref<Image>>& result);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Interfaces/ILayer.hpp",
    "content": "//\n//  ILayer.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\nnamespace snap::drawing {\n\nusing LayerId = uint64_t;\nconstexpr LayerId kLayerIdNone = 0;\n\nclass ILayer : public Valdi::SharedPtrRefCountable {\npublic:\n    /**\n     Will be called right after the constructor when using the makeLayer factory function.\n     */\n    virtual void onInitialize() = 0;\n    virtual void setChildNeedsDisplay() = 0;\n    virtual void requestLayout(ILayer* layer) = 0;\n    virtual void requestFocus(ILayer* layer) = 0;\n    virtual Ref<ILayer> getParent() const = 0;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Interfaces/ILayerRoot.hpp",
    "content": "//\n//  ILayerRoot.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/19/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Events/EventCallback.hpp\"\n#include \"snap_drawing/cpp/Events/EventId.hpp\"\n#include \"snap_drawing/cpp/Layers/Interfaces/ILayer.hpp\"\n#include \"snap_drawing/cpp/Utils/Duration.hpp\"\n\nnamespace snap::drawing {\n\nclass ILayerRoot : public ILayer {\npublic:\n    virtual EventId enqueueEvent(EventCallback&& eventCallback, Duration after) = 0;\n    virtual bool cancelEvent(EventId eventId) = 0;\n\n    virtual LayerId allocateLayerId() = 0;\n\n    Ref<ILayer> getParent() const final {\n        return nullptr;\n    }\n\n    virtual bool shouldRasterizeExternalSurface() const = 0;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Interfaces/ILoadedAssetLayer.hpp",
    "content": "//\n//  ILoadedAssetLayer.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 7/22/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\nnamespace Valdi {\nclass LoadedAsset;\n}\n\nnamespace snap::drawing {\n\nclass ILoadedAssetLayer {\npublic:\n    virtual ~ILoadedAssetLayer() = default;\n\n    virtual void onLoadedAssetChanged(const Ref<Valdi::LoadedAsset>& loadedAsset, bool shouldDrawFlipped) = 0;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Layer.cpp",
    "content": "//\n//  Layer.cpp\n//  valdi-skia-apple\n//\n//  Created by Simon Corsin on 6/27/20.\n//\n\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"Interfaces/ILayer.hpp\"\n#include \"snap_drawing/cpp/Layers/Interfaces/ILayerRoot.hpp\"\n#include \"snap_drawing/cpp/Layers/Mask/IMaskLayer.hpp\"\n\n#include \"utils/debugging/Assert.hpp\"\n\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/BoxShadow.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Drawing/LinearGradient.hpp\"\n#include \"snap_drawing/cpp/Utils/GradientWrapper.hpp\"\n\n#include <iostream>\n\nnamespace snap::drawing {\n\nLayer::Layer(const Ref<Resources>& resources)\n    : _resources(resources),\n      _frame(Rect::makeEmpty()),\n      _backgroundColor(Color::transparent()),\n      _translation(Size::makeEmpty()) {}\n\nLayer::~Layer() {\n    for (const auto& gestureRecognizer : _gestureRecognizers.readAccess()) {\n        gestureRecognizer->setLayer(nullptr);\n    }\n}\n\nvoid Layer::onInitialize() {}\n\nvoid Layer::draw(DisplayList& displayList, DrawMetrics& metrics) {\n    if (!isVisible()) {\n        return;\n    }\n\n    metrics.visitedLayers++;\n\n    auto width = _frame.width();\n    auto height = _frame.height();\n\n    if (_matrixDirty) {\n        _matrixDirty = false;\n        updateMatrix(width, height);\n\n        metrics.matrixCacheMiss++;\n    }\n\n    _isDrawing = true;\n\n    Scalar resolvedContextOpacity;\n    Scalar resolvedPictureOpacity;\n\n    if (_opacity == 1.0f || !hasOverlappingRendering()) {\n        resolvedContextOpacity = 1.0f;\n        resolvedPictureOpacity = _opacity;\n    } else {\n        resolvedContextOpacity = _opacity;\n        resolvedPictureOpacity = 1.0f;\n    }\n\n    if (_layerId == kLayerIdNone && _root != nullptr) {\n        _layerId = _root->allocateLayerId();\n    }\n\n    displayList.pushContext(_matrix, resolvedContextOpacity, _layerId, _needsDisplay);\n\n    if (_needsDisplay) {\n        drawBackground(width, height);\n        drawContent(width, height);\n        drawForeground(width, height);\n    }\n\n    MaskLayerPositioning maskPositioning = MaskLayerPositioning::BelowBackground;\n    Ref<IMask> mask;\n    if (_maskLayer != nullptr) {\n        maskPositioning = _maskLayer->getPositioning();\n        mask = _maskLayer->createMask(Rect::makeLTRB(0, 0, width, height));\n    }\n\n    if (mask != nullptr && maskPositioning == MaskLayerPositioning::BelowBackground) {\n        displayList.appendPrepareMask(mask.get());\n    }\n\n    if (!_cachedBackground.isEmpty()) {\n        displayList.appendLayerContent(_cachedBackground, resolvedPictureOpacity);\n    }\n\n    if (mask != nullptr && maskPositioning == MaskLayerPositioning::AboveBackground) {\n        displayList.appendPrepareMask(mask.get());\n    }\n\n    if (!_cachedContent.isEmpty()) {\n        displayList.appendLayerContent(_cachedContent, resolvedPictureOpacity);\n    }\n\n    if (_clipsToBounds) {\n        displayList.appendClipRound(_borderRadius, width, height);\n    }\n\n    {\n        auto children = _children.readAccess();\n        for (const auto& child : *children) {\n            child->draw(displayList, metrics);\n        }\n    }\n\n    if (mask != nullptr) {\n        displayList.appendApplyMask(mask.get());\n    }\n\n    if (!_cachedForeground.isEmpty()) {\n        displayList.appendLayerContent(_cachedForeground, resolvedPictureOpacity);\n    }\n\n    if (_needsDisplay) {\n        _needsDisplay = false;\n        metrics.drawCacheMiss++;\n    }\n\n    _childNeedsDisplay = false;\n    _isDrawing = false;\n\n    displayList.popContext();\n}\n\nvoid Layer::onDraw(DrawingContext& drawingContext) {}\n\nvoid Layer::drawContent(Scalar width, Scalar height) {\n    DrawingContext drawingContext(width, height);\n\n    onDraw(drawingContext);\n\n    _cachedContent = drawingContext.finish();\n}\n\nvoid Layer::drawBackground(Scalar width, Scalar height) {\n    DrawingContext drawingContext(width, height);\n\n    if (_boxShadow != nullptr) {\n        _boxShadow->draw(drawingContext, _borderRadius);\n    }\n\n    if (_gradientWrapper.hasGradient()) {\n        _gradientWrapper.draw(drawingContext, _borderRadius);\n    } else if (_backgroundColor != Color::transparent()) {\n        Paint paint;\n        paint.setColor(_backgroundColor);\n        paint.setAntiAlias(true);\n\n        drawingContext.drawPaint(paint, _borderRadius, _lazyPath);\n    }\n\n    _cachedBackground = drawingContext.finish();\n}\n\nvoid Layer::drawForeground(Scalar width, Scalar height) {\n    DrawingContext drawingContext(width, height);\n\n    if (_borderWidth != 0) {\n        Paint paint;\n        paint.setStroke(true);\n        paint.setColor(_borderColor);\n        paint.setStrokeWidth(_borderWidth);\n        paint.setAntiAlias(true);\n\n        drawingContext.drawPaint(paint, _borderRadius, _lazyPath);\n    }\n\n    _cachedForeground = drawingContext.finish();\n}\n\nbool Layer::hasOverlappingRendering() const {\n    return getChildrenSize() > 0;\n}\n\nSize Layer::sizeThatFits(Size /*maxSize*/) {\n    return Size::make(0, 0);\n}\n\nvoid Layer::addChild(const Valdi::Ref<Layer>& childLayer) {\n    insertChild(childLayer, getChildrenSize());\n}\n\nvoid Layer::insertChild(const Valdi::Ref<Layer>& childLayer, size_t index) {\n    SC_ASSERT(this != childLayer.get());\n\n    if (childLayer->_hasParent) {\n        bool shouldNotify = childLayer->getParent().get() != this;\n        childLayer->removeFromParent(shouldNotify);\n    }\n\n    {\n        auto children = _children.writeAccess();\n        SC_ASSERT(index <= children->size());\n        if (index == children->size()) {\n            children->emplace_back(childLayer);\n        } else {\n            children->emplace(children->begin() + index, childLayer);\n        }\n    }\n\n    childLayer->onParentChanged(Valdi::strongSmallRef(this));\n\n    setChildNeedsDisplay();\n\n    onChildInserted(childLayer.get(), index);\n\n    if (childLayer->_needsLayout) {\n        setNeedsLayout();\n    }\n    childLayer->setNeedsDisplay();\n}\n\nvoid Layer::onChildInserted(Layer* /*childLayer*/, size_t /*index*/) {}\n\nvoid Layer::onChildRemoved(Layer* /*childLayer*/) {}\n\nvoid Layer::removeChild(Layer* childLayer, bool shouldNotify) {\n    auto erased = false;\n    {\n        auto children = _children.writeAccess();\n        auto it = children->begin();\n        while (it != children->end()) {\n            if (it->get() == childLayer) {\n                it = children->erase(it);\n                erased = true;\n            } else {\n                it++;\n            }\n        }\n    }\n\n    if (erased) {\n        if (shouldNotify) {\n            onChildRemoved(childLayer);\n        }\n        setChildNeedsDisplay();\n    }\n}\n\nvoid Layer::removeFromParent() {\n    removeFromParent(true);\n}\n\nvoid Layer::removeFromParent(bool shouldNotify) {\n    if (!_hasParent) {\n        return;\n    }\n\n    auto parentLayer = Valdi::castOrNull<Layer>(getParent());\n    if (parentLayer != nullptr) {\n        parentLayer->removeChild(this, shouldNotify);\n    }\n\n    onParentChanged(nullptr);\n}\n\nRef<Layer> Layer::getChild(size_t index) const {\n    return (*_children.readAccess())[index];\n}\n\nsize_t Layer::getChildrenSize() const {\n    return _children.size();\n}\n\nbool Layer::hitTest(const Point& point) const {\n    if (!isTouchEnabled() || !isVisible()) {\n        return false;\n    }\n\n    if (point.x < -_touchAreaExtensionLeft) {\n        return false;\n    }\n\n    if (point.y < -_touchAreaExtensionTop) {\n        return false;\n    }\n\n    if (point.x > (_frame.width() + _touchAreaExtensionRight)) {\n        return false;\n    }\n\n    if (point.y > (_frame.height() + _touchAreaExtensionBottom)) {\n        return false;\n    }\n\n    return true;\n}\n\nRef<Layer> Layer::getLayerAtPoint(const Point& point) {\n    if (!hitTest(point)) {\n        return nullptr;\n    }\n\n    // Dispatch touches to children, starting from the last child.\n    auto children = _children.readAccess();\n    auto i = children->size();\n    while (i > 0) {\n        i--;\n\n        const auto& child = (*children)[i];\n        auto childPoint = child->convertPointFromParent(point);\n\n        auto hitChild = child->getLayerAtPoint(childPoint);\n        if (hitChild != nullptr) {\n            return hitChild;\n        }\n    }\n\n    return Valdi::strongSmallRef(this);\n}\n\nvoid Layer::updateMatrix(Scalar width, Scalar height) {\n    _matrix.setIdentity();\n\n    auto scaledWidth = width;\n    auto scaledHeight = height;\n    auto translationX = _translation.width;\n    auto translationY = _translation.height;\n\n    // Compensate for the change of size so that it appears as if we are scaling from the center\n    if (_scaleX != 1.0f) {\n        scaledWidth *= _scaleX;\n\n        translationX += (width - scaledWidth) / 2.0f;\n        _matrix.setScaleX(_scaleX);\n    }\n\n    if (_scaleY != 1.0f) {\n        scaledHeight *= _scaleY;\n\n        translationY += (height - scaledHeight) / 2.0f;\n        _matrix.setScaleY(_scaleY);\n    }\n\n    _matrix.setTranslateX(_frame.left + translationX);\n    _matrix.setTranslateY(_frame.top + translationY);\n\n    if (_rotation != 0.0f) {\n        Scalar centerX = _matrix.getTranslateX() + scaledWidth / 2.0f;\n        Scalar centerY = _matrix.getTranslateY() + scaledHeight / 2.0f;\n        _matrix.postRotate(_rotation, centerX, centerY);\n    }\n}\n\nvoid Layer::setTouchAreaExtension(Scalar left, Scalar right, Scalar top, Scalar bottom) {\n    _touchAreaExtensionLeft = left;\n    _touchAreaExtensionRight = right;\n    _touchAreaExtensionTop = top;\n    _touchAreaExtensionBottom = bottom;\n}\n\nvoid Layer::setBackgroundColor(Color backgroundColor) {\n    if (_backgroundColor != backgroundColor) {\n        _backgroundColor = backgroundColor;\n        setNeedsDisplay();\n    }\n}\n\nvoid Layer::setBackgroundLinearGradient(std::vector<Scalar>&& locations,\n                                        std::vector<Color>&& colors,\n                                        LinearGradientOrientation orientation) {\n    if (_gradientWrapper.clearIfNeeded(GradientWrapper::GradientType::RADIAL)) {\n        setNeedsDisplay();\n    }\n\n    if (colors.empty()) {\n        if (_gradientWrapper.clearIfNeeded(GradientWrapper::GradientType::LINEAR)) {\n            setNeedsDisplay();\n        }\n        return;\n    }\n\n    _gradientWrapper.setAsLinear(std::move(locations), std::move(colors), orientation);\n\n    if (_gradientWrapper.isDirty()) {\n        setNeedsDisplay();\n    }\n}\n\nvoid Layer::setBackgroundRadialGradient(std::vector<Scalar>&& locations, std::vector<Color>&& colors) {\n    if (_gradientWrapper.clearIfNeeded(GradientWrapper::GradientType::LINEAR)) {\n        setNeedsDisplay();\n    }\n\n    if (colors.empty()) {\n        if (_gradientWrapper.clearIfNeeded(GradientWrapper::GradientType::RADIAL)) {\n            setNeedsDisplay();\n        }\n        return;\n    }\n\n    _gradientWrapper.setAsRadial(std::move(locations), std::move(colors));\n\n    if (_gradientWrapper.isDirty()) {\n        setNeedsDisplay();\n    }\n}\n\nColor Layer::getBackgroundColor() const {\n    return _backgroundColor;\n}\n\nvoid Layer::setTouchEnabled(bool touchEnabled) {\n    _touchEnabled = touchEnabled;\n}\n\nbool Layer::isTouchEnabled() const {\n    return _touchEnabled;\n}\n\nvoid Layer::setBorderRadius(BorderRadius borderRadius) {\n    _borderRadius = borderRadius;\n    // Path needs to be recomputed when the border radius changes\n    _lazyPath.setNeedsUpdate();\n    setNeedsDisplay();\n}\n\nBorderRadius Layer::getBorderRadius() const {\n    return _borderRadius;\n}\n\nvoid Layer::setOpacity(Scalar opacity) {\n    if (_opacity != opacity) {\n        auto wasVisible = isVisible();\n        _opacity = opacity;\n\n        if (isVisible() != wasVisible) {\n            // If we are switching from visible to non-visible or vice versa,\n            // we need to redraw completely as the visibility state is used\n            // to determine whether we should even emit the draw operations\n            // for the layer or not\n            setNeedsDisplay();\n            // We also should force notify our parent since our needsDisplay/childNeedsDisplay\n            // flags might be out of sync, since we are not visited when not visible.\n            notifyParentSetChildNeedsDisplay();\n        } else {\n            setChildNeedsDisplay();\n        }\n    }\n}\n\nScalar Layer::getOpacity() const {\n    return _opacity;\n}\n\nbool Layer::isVisible() const {\n    return _opacity > 0;\n}\n\nvoid Layer::setBorderWidth(Scalar borderWidth) {\n    if (_borderWidth != borderWidth) {\n        _borderWidth = borderWidth;\n        setNeedsDisplay();\n    }\n}\n\nScalar Layer::getBorderWidth() const {\n    return _borderWidth;\n}\n\nvoid Layer::setBorderColor(Color borderColor) {\n    if (_borderColor != borderColor) {\n        _borderColor = borderColor;\n        setNeedsDisplay();\n    }\n}\n\nColor Layer::getBorderColor() const {\n    return _borderColor;\n}\n\nvoid Layer::setMaskLayer(const Ref<IMaskLayer>& maskLayer) {\n    if (_maskLayer != maskLayer) {\n        _maskLayer = maskLayer;\n        setNeedsDisplay();\n    }\n}\n\nconst Ref<IMaskLayer>& Layer::getMaskLayer() const {\n    return _maskLayer;\n}\n\nvoid Layer::setClipsToBounds(bool clipToBounds) {\n    if (_clipsToBounds != clipToBounds) {\n        _clipsToBounds = clipToBounds;\n        setNeedsDisplay();\n    }\n}\n\nbool Layer::clipsToBounds() const {\n    return _clipsToBounds;\n}\n\nvoid Layer::onBoundsChanged() {}\n\nvoid Layer::onLayout() {}\n\nvoid Layer::onRightToLeftChanged() {}\n\nvoid Layer::setFrame(const Rect& frame) {\n    if (_frame != frame) {\n        auto boundsChanged = (_frame.width() != frame.width()) || (_frame.height() != frame.height());\n        _frame = frame;\n\n        setVisualFrameDirty();\n\n        if (boundsChanged) {\n            setNeedsDisplay();\n            onBoundsChanged();\n        } else {\n            setChildNeedsDisplay();\n        }\n    }\n}\n\nconst Rect& Layer::getFrame() const {\n    return _frame;\n}\n\nvoid Layer::setNeedsDisplay() {\n    if (_isDrawing) {\n        return;\n    }\n\n    if (!_needsDisplay) {\n        _needsDisplay = true;\n\n        _cachedForeground.clear();\n        _cachedContent.clear();\n\n        setChildNeedsDisplay();\n    }\n}\n\nbool Layer::needsDisplay() const {\n    return _needsDisplay;\n}\n\nbool Layer::childNeedsDisplay() const {\n    return _childNeedsDisplay;\n}\n\nvoid Layer::setChildNeedsDisplay() {\n    if (!_childNeedsDisplay) {\n        _childNeedsDisplay = true;\n\n        notifyParentSetChildNeedsDisplay();\n    }\n}\n\nvoid Layer::requestFocus(ILayer* layer) {\n    auto parent = getParent();\n    if (parent != nullptr) {\n        parent->requestFocus(layer);\n    }\n}\n\nvoid Layer::notifyParentSetChildNeedsDisplay() {\n    auto parent = _parent.lock();\n    if (parent != nullptr) {\n        parent->setChildNeedsDisplay();\n    }\n}\n\nvoid Layer::setNeedsLayout() {\n    requestLayout(this);\n}\n\nvoid Layer::requestLayout(ILayer* /*layer*/) {\n    if (_needsLayout) {\n        return;\n    }\n    _needsLayout = true;\n\n    auto parent = _parent.lock();\n    if (parent != nullptr) {\n        parent->requestLayout(this);\n    }\n}\n\nvoid Layer::layoutIfNeeded() {\n    if (_needsLayout) {\n        onLayout();\n\n        for (const auto& child : _children.readAccess()) {\n            child->layoutIfNeeded();\n        }\n\n        _needsLayout = false;\n    }\n}\n\nvoid Layer::addAnimation(const String& key, const Ref<IAnimation>& animation) {\n    removeAnimation(key);\n    {\n        (*_animations.writeAccess())[key] = animation;\n    }\n    scheduleProcessAnimationsIfNeeded();\n}\n\nvoid Layer::removeAnimation(const String& key) {\n    Ref<IAnimation> animation;\n    {\n        auto animations = _animations.writeAccess();\n        const auto& it = animations->find(key);\n        if (it != animations->end()) {\n            animation = std::move(it->second);\n            animations->erase(it);\n        }\n    }\n\n    if (animation != nullptr) {\n        animation->cancel(*this);\n    }\n}\n\nvoid Layer::removeAllAnimations() {\n    while (!_animations.empty()) {\n        String key;\n        {\n            key = _animations.readAccess()->begin()->first;\n        }\n        removeAnimation(key);\n    }\n}\n\nbool Layer::hasAnimation(const String& key) const {\n    auto animations = _animations.readAccess();\n    return animations->find(key) != animations->end();\n}\n\nRef<IAnimation> Layer::getAnimation(const String& key) const {\n    auto animations = _animations.readAccess();\n    auto it = animations->find(key);\n    if (it == animations->end()) {\n        return nullptr;\n    }\n\n    return it->second;\n}\n\nstd::vector<String> Layer::getAnimationKeys() const {\n    std::vector<String> out;\n\n    auto animations = _animations.readAccess();\n    out.reserve(animations->size());\n\n    for (const auto& it : animations) {\n        out.emplace_back(it.first);\n    }\n\n    return out;\n}\n\nbool Layer::needsProcessAnimations() const {\n    return _enqueuedFrame.has_value();\n}\n\nvoid Layer::scheduleProcessAnimationsIfNeeded() {\n    if (_enqueuedFrame || _animations.empty() || _root == nullptr) {\n        return;\n    }\n\n    auto weakSelf = Valdi::weakRef(this);\n    auto eventId = onNextFrame([weakSelf](auto /*timePoint*/, auto delta) {\n        auto strongSelf = weakSelf.lock();\n        if (strongSelf != nullptr) {\n            strongSelf->processAnimations(delta);\n        }\n    });\n\n    _enqueuedFrame = {eventId};\n}\n\nbool Layer::cancelProcessAnimations() {\n    if (!_enqueuedFrame || _root == nullptr) {\n        return false;\n    }\n    auto eventId = _enqueuedFrame.value();\n    _enqueuedFrame = std::nullopt;\n    return _root->cancelEvent(eventId);\n}\n\nEventId Layer::onNextFrame(EventCallback&& eventCallback) {\n    if (_root == nullptr) {\n        return EventId();\n    }\n\n    return _root->enqueueEvent(std::move(eventCallback), Duration(0));\n}\n\nstruct AnimationToProcess {\n    String key;\n    Ref<IAnimation> animation;\n\n    inline AnimationToProcess(const String& key, const Ref<IAnimation>& animation) : key(key), animation(animation) {}\n};\n\nvoid Layer::processAnimations(Duration delta) {\n    _enqueuedFrame = std::nullopt;\n\n    if (_animations.empty()) {\n        return;\n    }\n\n    Valdi::SmallVector<AnimationToProcess, 4> collectedAnimations;\n\n    // Collect all the animations to process\n    {\n        auto animations = _animations.readAccess();\n        for (const auto& it : animations) {\n            collectedAnimations.emplace_back(it.first, it.second);\n        }\n    }\n\n    // Process all our animations with the delta.\n    // We remove the ones that have completed\n    for (const auto& animationToProcess : collectedAnimations) {\n        auto completed = animationToProcess.animation->run(*this, delta);\n        if (completed) {\n            {\n                auto animations = _animations.writeAccess();\n                const auto& it = animations->find(animationToProcess.key);\n                if (it != animations->end() && it->second == animationToProcess.animation) {\n                    animations->erase(it);\n                }\n            }\n            animationToProcess.animation->complete(*this);\n        }\n    }\n\n    scheduleProcessAnimationsIfNeeded();\n}\n\nstd::optional<Point> Layer::convertPointToLayer(Point point, const Valdi::Ref<Layer>& childLayer) const {\n    thread_local std::vector<Ref<Layer>> kDescendants;\n\n    auto& descendants = kDescendants;\n    auto current = childLayer;\n\n    for (;;) {\n        if (current.get() == this) {\n            break;\n        }\n\n        if (current == nullptr) {\n            return std::nullopt;\n        }\n\n        descendants.emplace_back(current);\n        current = Valdi::castOrNull<Layer>(current->getParent());\n    }\n\n    for (size_t i = descendants.size(); i > 0;) {\n        i--;\n        point = descendants[i]->convertPointFromParent(point);\n    }\n\n    descendants.clear();\n\n    return point;\n}\n\nPoint Layer::convertPointFromParent(const Point& point) {\n    // TODO(simon): Take in account rotation\n\n    if (_hasScale) {\n        auto offset = getOffsetInParent();\n\n        auto convertedPoint = point.makeOffset(-offset.x, -offset.y);\n\n        if (_scaleX != 0.0f) {\n            convertedPoint.x /= _scaleX;\n        } else {\n            convertedPoint.x = 0.0f;\n        }\n\n        if (_scaleY != 0.0f) {\n            convertedPoint.y /= _scaleY;\n        } else {\n            convertedPoint.y = 0.0f;\n        }\n\n        return convertedPoint;\n    } else {\n        return point.makeOffset(-(_frame.left + _translation.width), -(_frame.top + _translation.height));\n    }\n}\n\nconst Rect& Layer::getVisualFrame() {\n    if (_visualFrameDirty) {\n        _visualFrameDirty = false;\n        _visualFrame = convertRectToParent(Rect::makeLTRB(0, 0, _frame.width(), _frame.height()));\n    }\n\n    return _visualFrame;\n}\n\nPoint Layer::getOffsetInParent() const {\n    auto frameWidth = _frame.width();\n    auto frameHeight = _frame.height();\n\n    auto scaledWidth = frameWidth * _scaleX;\n    auto scaledHeight = frameHeight * _scaleY;\n\n    auto x = (_frame.left + frameWidth / 2.0f) + _translation.width - scaledWidth / 2.0f;\n    auto y = (_frame.top + frameHeight / 2.0f) + _translation.height - scaledHeight / 2.0f;\n\n    return Point::make(x, y);\n}\n\nRect Layer::convertRectToParent(const Rect& rect) {\n    // TODO(simon): Take in account rotation\n\n    if (_hasScale) {\n        auto convertedRect =\n            Rect::makeXYWH(rect.left * _scaleX, rect.top * _scaleY, rect.width() * _scaleX, rect.height() * _scaleY);\n\n        auto offset = getOffsetInParent();\n        return convertedRect.makeOffset(offset.x, offset.y);\n    } else {\n        return rect.makeOffset(_frame.left + _translation.width, _frame.top + _translation.height);\n    }\n}\n\nPoint Layer::convertPointToParent(const Point& point) {\n    // TODO(simon): Take in account rotation\n\n    if (_hasScale) {\n        auto convertedPoint = Point::make(point.x * _scaleX, point.y * _scaleY);\n\n        auto offset = getOffsetInParent();\n        return convertedPoint.makeOffset(offset.x, offset.y);\n    } else {\n        return point.makeOffset(_frame.left + _translation.width, _frame.top + _translation.height);\n    }\n}\n\nvoid Layer::setVisualFrameDirty() {\n    _visualFrameDirty = true;\n    _matrixDirty = true;\n}\n\nRect Layer::getAbsoluteVisualFrame() {\n    auto frame = Rect::makeXYWH(0, 0, _frame.width(), _frame.height());\n    auto current = Valdi::strongSmallRef(this);\n\n    for (;;) {\n        if (current == nullptr) {\n            return frame;\n        }\n\n        frame = current->convertRectToParent(frame);\n\n        current = Valdi::castOrNull<Layer>(current->getParent());\n    }\n}\n\nvoid Layer::setBoxShadow(Scalar widthOffset, Scalar heightOffset, Scalar blurAmount, Color color) {\n    if (color == Color::transparent()) {\n        if (_boxShadow != nullptr) {\n            _boxShadow = nullptr;\n            setNeedsDisplay();\n        }\n    } else {\n        if (_boxShadow == nullptr) {\n            _boxShadow = Valdi::makeShared<BoxShadow>();\n        }\n        _boxShadow->setOffset(Size::make(widthOffset, heightOffset));\n        _boxShadow->setBlurAmount(blurAmount);\n        _boxShadow->setColor(color);\n    }\n}\n\nScalar Layer::getTranslationX() const {\n    return _translation.width;\n}\n\nvoid Layer::setTranslationX(Scalar translationX) {\n    if (_translation.width != translationX) {\n        _translation.width = translationX;\n        setChildNeedsDisplay();\n        setVisualFrameDirty();\n    }\n}\n\nScalar Layer::getTranslationY() const {\n    return _translation.height;\n}\n\nvoid Layer::setTranslationY(Scalar translationY) {\n    if (_translation.height != translationY) {\n        _translation.height = translationY;\n        setChildNeedsDisplay();\n        setVisualFrameDirty();\n    }\n}\n\nScalar Layer::getScaleX() const {\n    return _scaleX;\n}\n\nvoid Layer::setScaleX(Scalar scaleX) {\n    if (_scaleX != scaleX) {\n        _scaleX = scaleX;\n        _hasScale = (_scaleX != 1) || (_scaleY != 1);\n        setChildNeedsDisplay();\n        setVisualFrameDirty();\n    }\n}\n\nScalar Layer::getScaleY() const {\n    return _scaleY;\n}\n\nvoid Layer::setScaleY(Scalar scaleY) {\n    if (_scaleY != scaleY) {\n        _scaleY = scaleY;\n        _hasScale = (_scaleX != 1) || (_scaleY != 1);\n        setChildNeedsDisplay();\n        setVisualFrameDirty();\n    }\n}\n\nScalar Layer::getRotation() const {\n    return _rotation;\n}\n\nvoid Layer::setRotation(Scalar rotation) {\n    if (_rotation != rotation) {\n        _rotation = rotation;\n        setChildNeedsDisplay();\n        setVisualFrameDirty();\n    }\n}\n\nvoid Layer::onParentChanged(const Valdi::Ref<ILayer>& parent) {\n    _parent = parent;\n    _hasParent = parent != nullptr;\n\n    if (_hasParent) {\n        auto parentAsLayer = Valdi::castOrNull<Layer>(parent);\n        if (parentAsLayer != nullptr) {\n            if (parentAsLayer->_root != _root) {\n                onRootChanged(parentAsLayer->_root);\n            }\n        } else {\n            auto parentAsRoot = Valdi::castOrNull<ILayerRoot>(parent);\n            if (parentAsRoot.get() != _root) {\n                onRootChanged(parentAsRoot.get());\n            }\n        }\n    } else {\n        if (_root != nullptr) {\n            onRootChanged(nullptr);\n        }\n    }\n}\n\nValdi::Ref<ILayer> Layer::getParent() const {\n    return _parent.lock();\n}\n\nbool Layer::hasParent() const {\n    return _hasParent;\n}\n\nvoid Layer::onRootChanged(ILayerRoot* root) {\n    if (root == nullptr) {\n        cancelProcessAnimations();\n    }\n\n    _root = root;\n    _layerId = kLayerIdNone;\n    {\n        for (const auto& child : _children.readAccess()) {\n            child->onRootChanged(root);\n        }\n    }\n\n    if (_root != nullptr) {\n        scheduleProcessAnimationsIfNeeded();\n    } else {\n        removeAllAnimations();\n        setNeedsDisplay();\n    }\n}\n\nvoid Layer::addGestureRecognizer(const Valdi::Ref<GestureRecognizer>& gestureRecognizer) {\n    auto layer = Valdi::castOrNull<Layer>(gestureRecognizer->getLayer());\n    if (layer != nullptr) {\n        layer->removeGestureRecognizer(gestureRecognizer);\n    }\n\n    _gestureRecognizers.writeAccess()->emplace_back(gestureRecognizer);\n    gestureRecognizer->setLayer(this);\n}\n\nvoid Layer::removeGestureRecognizer(const Valdi::Ref<GestureRecognizer>& gestureRecognizer) {\n    auto gestureRecognizers = _gestureRecognizers.writeAccess();\n    auto it = gestureRecognizers->begin();\n    while (it != gestureRecognizers->end()) {\n        if (*it == gestureRecognizer) {\n            gestureRecognizers->erase(it);\n            gestureRecognizer->setLayer(nullptr);\n            return;\n        }\n        it++;\n    }\n}\n\nstd::optional<size_t> Layer::indexOfGestureRecognizerOfType(const std::type_info& type) const {\n    size_t i = 0;\n\n    for (const auto& gestureRecognizer : _gestureRecognizers.readAccess()) {\n        const auto* ptr = gestureRecognizer.get();\n        if (typeid(*ptr) == type) {\n            return {i};\n        }\n\n        i++;\n    }\n\n    return std::nullopt;\n}\n\nvoid Layer::removeGestureRecognizerOfType(const std::type_info& type) {\n    auto index = indexOfGestureRecognizerOfType(type);\n    if (index) {\n        auto gestureRecognizers = _gestureRecognizers.writeAccess();\n        (*gestureRecognizers)[index.value()]->setLayer(nullptr);\n        gestureRecognizers->erase(gestureRecognizers->begin() + index.value());\n    }\n}\n\nsize_t Layer::getGestureRecognizersSize() const {\n    return _gestureRecognizers.size();\n}\n\nRef<GestureRecognizer> Layer::getGestureRecognizer(size_t index) const {\n    return (*_gestureRecognizers.readAccess())[index];\n}\n\nconst Ref<Valdi::RefCountable>& Layer::getAttachedData() const {\n    return _attachedData;\n}\n\nvoid Layer::setAttachedData(const Ref<Valdi::RefCountable>& attachedData) {\n    _attachedData = attachedData;\n}\n\nbool Layer::getClipsToBoundsDefaultValue() const {\n    return false;\n}\n\nValdi::StringBox Layer::getDebugDescription(bool recursive) const {\n    std::string out;\n\n    outputDebugDescription(out, 0, recursive);\n\n    return Valdi::StringCache::getGlobal().makeString(std::move(out));\n}\n\nvoid Layer::printDebugDescription(bool recursive) const {\n    auto debugDescription = getDebugDescription(recursive);\n    std::cout << debugDescription.toStringView() << std::endl;\n}\n\nstd::string_view Layer::getClassName() const {\n    return \"Layer\";\n}\n\nvoid Layer::outputDebugDescription(std::string& out, int indent, bool recursive) const {\n    for (int i = 0; i < indent; i++) {\n        out += \"  \";\n    }\n\n    out += getClassName();\n    out += \" (ID: \" + getAccessibilityId().slowToString() + \")\";\n    out += \" \";\n    out += \"x:\" + std::to_string(_frame.x());\n    out += \", y:\" + std::to_string(_frame.y());\n    out += \", w:\" + std::to_string(_frame.width());\n    out += \", h:\" + std::to_string(_frame.height());\n\n    if (recursive) {\n        for (const auto& child : _children.readAccess()) {\n            out += \"\\n\";\n            child->outputDebugDescription(out, indent + 1, recursive);\n        }\n    }\n}\n\nbool Layer::prepareForReuse() {\n    return true;\n}\n\nILayerRoot* Layer::getRoot() const {\n    return _root;\n}\n\nValdi::ILogger& Layer::getLogger() const {\n    return _resources->getLogger();\n}\n\nconst Ref<Resources>& Layer::getResources() const {\n    return _resources;\n}\n\nvoid Layer::setRightToLeft(bool isRightToLeft) {\n    if (_isRightToLeft != isRightToLeft) {\n        _isRightToLeft = isRightToLeft;\n        onRightToLeftChanged();\n    }\n}\n\nbool Layer::isRightToLeft() const {\n    return _isRightToLeft;\n}\n\nvoid Layer::setAccessibilityId(const Valdi::StringBox& accessibilityId) {\n    if (_accessibilityId != accessibilityId) {\n        _accessibilityId = accessibilityId;\n    }\n}\n\nconst Valdi::StringBox& Layer::getAccessibilityId() const {\n    return _accessibilityId;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Layer.hpp",
    "content": "//\n//  Layer.hpp\n//  valdi-skia-apple\n//\n//  Created by Simon Corsin on 6/27/20.\n//\n\n#pragma once\n\n#include \"Interfaces/ILayer.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\n#include \"snap_drawing/cpp/Resources.hpp\"\n\n#include \"snap_drawing/cpp/Layers/Interfaces/ILayer.hpp\"\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/LayerContent.hpp\"\n#include \"snap_drawing/cpp/Drawing/LinearGradient.hpp\"\n#include \"snap_drawing/cpp/Drawing/RadialGradient.hpp\"\n#include \"snap_drawing/cpp/Events/EventCallback.hpp\"\n#include \"snap_drawing/cpp/Events/EventId.hpp\"\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/GradientWrapper.hpp\"\n#include \"snap_drawing/cpp/Utils/LazyPath.hpp\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include \"snap_drawing/cpp/Utils/SafeContainer.hpp\"\n\n#include <optional>\n#include <string>\n#include <string_view>\n#include <type_traits>\n#include <typeinfo>\n#include <utility>\n#include <vector>\n\n#include \"valdi_core/cpp/Utils/PlatformResult.hpp\"\n\n#include \"utils/base/NonCopyable.hpp\"\n\nnamespace Valdi {\nclass DispatchQueue;\nclass ValueFunction;\nclass ILogger;\n}; // namespace Valdi\n\nnamespace snap::drawing {\n\nclass Layer;\nclass ILayerRoot;\nclass IAnimation;\nclass IMaskLayer;\n\nclass BoxShadow;\nclass LinearGradient;\nclass RadialGradient;\nstruct AttributeContext;\n\nclass DisplayList;\n\nstruct DrawMetrics {\n    int drawCacheMiss = 0;\n    int matrixCacheMiss = 0;\n    int visitedLayers = 0;\n};\n\ntemplate<typename T, typename std::enable_if<std::is_convertible<T*, ILayer*>::value, int>::type = 0, typename... Args>\nRef<T> makeLayer(Args&&... args) {\n    auto ref = Valdi::makeShared<T>(std::forward<Args>(args)...);\n    ref->onInitialize();\n    return ref;\n}\n\nclass Layer : public ILayer, public snap::NonCopyable {\npublic:\n    explicit Layer(const Ref<Resources>& resources);\n    ~Layer() override;\n\n    void onInitialize() override;\n    void draw(DisplayList& displayList, DrawMetrics& metrics);\n\n    virtual Size sizeThatFits(Size maxSize);\n\n    void setFrame(const Rect& frame);\n    const Rect& getFrame() const;\n\n    void setBackgroundColor(Color backgroundColor);\n    Color getBackgroundColor() const;\n\n    void setBackgroundLinearGradient(std::vector<Scalar>&& locations,\n                                     std::vector<Color>&& colors,\n                                     LinearGradientOrientation orientation);\n    void setBackgroundRadialGradient(std::vector<Scalar>&& locations, std::vector<Color>&& colors);\n\n    void setTouchEnabled(bool touchEnabled);\n    bool isTouchEnabled() const;\n\n    void setBorderRadius(BorderRadius borderRadius);\n    BorderRadius getBorderRadius() const;\n\n    void setOpacity(Scalar opacity);\n    Scalar getOpacity() const;\n\n    void setBorderWidth(Scalar borderWidth);\n    Scalar getBorderWidth() const;\n\n    void setBorderColor(Color borderColor);\n    Color getBorderColor() const;\n\n    void setMaskLayer(const Ref<IMaskLayer>& maskLayer);\n    const Ref<IMaskLayer>& getMaskLayer() const;\n\n    void setClipsToBounds(bool clipToBounds);\n    bool clipsToBounds() const;\n    bool isVisible() const;\n\n    virtual bool getClipsToBoundsDefaultValue() const;\n\n    void setTouchAreaExtension(Scalar left, Scalar right, Scalar top, Scalar bottom);\n\n    void setBoxShadow(Scalar widthOffset, Scalar heightOffset, Scalar blurAmount, Color color);\n\n    void setTranslationX(Scalar translationX);\n    Scalar getTranslationX() const;\n\n    void setTranslationY(Scalar translationY);\n    Scalar getTranslationY() const;\n\n    void setScaleX(Scalar scaleX);\n    Scalar getScaleX() const;\n\n    void setScaleY(Scalar scaleY);\n    Scalar getScaleY() const;\n\n    void setRotation(Scalar rotation);\n    Scalar getRotation() const;\n\n    void setAccessibilityId(const Valdi::StringBox& accessibilityId);\n    const Valdi::StringBox& getAccessibilityId() const;\n\n    virtual bool hitTest(const Point& point) const;\n    Ref<Layer> getLayerAtPoint(const Point& point);\n\n    void layoutIfNeeded();\n\n    bool needsDisplay() const;\n    bool childNeedsDisplay() const;\n    void setNeedsDisplay();\n    void setNeedsLayout();\n    void requestLayout(ILayer* layer) override;\n    void setChildNeedsDisplay() override;\n\n    void requestFocus(ILayer* layer) override;\n\n    bool needsProcessAnimations() const;\n\n    bool isRightToLeft() const;\n    void setRightToLeft(bool isRightToLeft);\n\n    virtual bool prepareForReuse();\n\n    std::optional<Point> convertPointToLayer(Point point, const Valdi::Ref<Layer>& childLayer) const;\n\n    /**\n     Convert the given point in the parent's coordinates to this layer's coordinates.\n     */\n    Point convertPointFromParent(const Point& point);\n\n    /**\n     Convert a rect from this layer's coordinates to the parent's coordinates\n     */\n    Rect convertRectToParent(const Rect& rect);\n\n    /**\n     Convert a point from this layer's coordinates to the parent's coordinates\n     */\n    Point convertPointToParent(const Point& point);\n\n    /**\n     Returns the actual frame that this layer represents, taking in account\n     scaling, translation and rotation.\n     */\n    const Rect& getVisualFrame();\n\n    Rect getAbsoluteVisualFrame();\n\n    void addChild(const Valdi::Ref<Layer>& childLayer);\n    void insertChild(const Valdi::Ref<Layer>& childLayer, size_t index);\n    void removeFromParent();\n\n    Valdi::Ref<Layer> getChild(size_t index) const;\n    size_t getChildrenSize() const;\n\n    Valdi::Ref<ILayer> getParent() const override;\n    bool hasParent() const;\n\n    Valdi::StringBox getDebugDescription(bool recursive) const;\n    void printDebugDescription(bool recursive) const;\n\n    void addAnimation(const String& key, const Ref<IAnimation>& animation);\n    void removeAnimation(const String& key);\n    void removeAllAnimations();\n    bool hasAnimation(const String& key) const;\n    Ref<IAnimation> getAnimation(const String& key) const;\n    std::vector<String> getAnimationKeys() const;\n\n    void addGestureRecognizer(const Valdi::Ref<GestureRecognizer>& gestureRecognizer);\n    void removeGestureRecognizer(const Valdi::Ref<GestureRecognizer>& gestureRecognizer);\n    size_t getGestureRecognizersSize() const;\n    Valdi::Ref<GestureRecognizer> getGestureRecognizer(size_t index) const;\n\n    void removeGestureRecognizerOfType(const std::type_info& type);\n    std::optional<size_t> indexOfGestureRecognizerOfType(const std::type_info& type) const;\n\n    const Ref<RefCountable>& getAttachedData() const;\n    virtual void setAttachedData(const Ref<RefCountable>& attachedData);\n\n    Valdi::ILogger& getLogger() const;\n\n    ILayerRoot* getRoot() const;\n\n    const Ref<Resources>& getResources() const;\n\n    // Will be called automatically when inserting/removing children, this should only be called\n    // explicitly by the root layer.\n    void onParentChanged(const Valdi::Ref<ILayer>& parent);\n\nprotected:\n    virtual void onDraw(DrawingContext& drawingContext);\n    virtual void onBoundsChanged();\n    virtual void onLayout();\n    virtual void onRootChanged(ILayerRoot* root);\n    virtual void onRightToLeftChanged();\n\n    virtual void onChildRemoved(Layer* childLayer);\n    virtual void onChildInserted(Layer* childLayer, size_t index);\n\n    virtual std::string_view getClassName() const;\n\nprivate:\n    Ref<Resources> _resources;\n    SafeContainer<std::vector<Valdi::Ref<Layer>>> _children;\n    SafeContainer<std::vector<Valdi::Ref<GestureRecognizer>>> _gestureRecognizers;\n    SafeContainer<Valdi::FlatMap<String, Ref<IAnimation>>> _animations;\n    Valdi::Weak<ILayer> _parent;\n    ILayerRoot* _root = nullptr;\n    Ref<RefCountable> _attachedData;\n    LayerId _layerId = kLayerIdNone;\n    Rect _frame;\n    Rect _visualFrame;\n    Scalar _touchAreaExtensionLeft = 0;\n    Scalar _touchAreaExtensionRight = 0;\n    Scalar _touchAreaExtensionTop = 0;\n    Scalar _touchAreaExtensionBottom = 0;\n    Color _backgroundColor;\n    Size _translation;\n    Scalar _scaleX = 1;\n    Scalar _scaleY = 1;\n    Scalar _opacity = 1;\n    Scalar _rotation = 0;\n    Scalar _borderWidth = 0;\n    Color _borderColor = Color::transparent();\n    BorderRadius _borderRadius;\n    GradientWrapper _gradientWrapper;\n    Ref<BoxShadow> _boxShadow;\n    Ref<IMaskLayer> _maskLayer;\n    LayerContent _cachedBackground;\n    LayerContent _cachedContent;\n    LayerContent _cachedForeground;\n    LazyPath _lazyPath;\n    Matrix _matrix;\n    bool _needsDisplay = true;\n    bool _childNeedsDisplay = true;\n    bool _touchEnabled = true;\n    bool _clipsToBounds = false;\n    bool _hasParent = false;\n    bool _needsLayout = false;\n    bool _hasScale = false;\n    bool _isDrawing = false;\n    bool _visualFrameDirty = true;\n    bool _matrixDirty = true;\n    bool _isRightToLeft = false;\n    std::optional<EventId> _enqueuedFrame;\n    Valdi::StringBox _accessibilityId;\n\n    EventId onNextFrame(EventCallback&& eventCallback);\n\n    Point getOffsetInParent() const;\n\n    void removeFromParent(bool shouldNotify);\n    void removeChild(Layer* childLayer, bool shouldNotify);\n\n    void drawBackground(Scalar width, Scalar height);\n    void drawContent(Scalar width, Scalar height);\n    void drawForeground(Scalar width, Scalar height);\n\n    void setVisualFrameDirty();\n\n    void notifyParentSetChildNeedsDisplay();\n\n    void updateMatrix(Scalar width, Scalar height);\n\n    void scheduleProcessAnimationsIfNeeded();\n    bool cancelProcessAnimations();\n    void processAnimations(Duration delta);\n\n    bool hasOverlappingRendering() const;\n\n    void outputDebugDescription(std::string& out, int indent, bool recursive) const;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/LayerRoot.cpp",
    "content": "//\n//  LayerRoot.cpp\n//  valdi-skia-apple\n//\n//  Created by Simon Corsin on 6/27/20.\n//\n\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n\n#include \"LayerRoot.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/Composition/Compositor.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlaneList.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.hpp\"\n\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/ScrollGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\n#include \"utils/time/StopWatch.hpp\"\n#include <cstdint>\n\nnamespace snap::drawing {\n\nconstexpr double kFrameWarningThresholdMs = 100;\nconstexpr double kTouchRefreshMs = 10;\n\nLayerRoot::LayerRoot(const Ref<Resources>& resources)\n    : _resources(resources),\n      _touchDispatcher(resources->getLogger(), resources->getGesturesConfiguration().debugGestures),\n      _eventQueue(TimePoint(0.0)) {}\n\nLayerRoot::~LayerRoot() = default;\n\nvoid LayerRoot::onInitialize() {}\n\nvoid LayerRoot::setListener(LayerRootListener* listener) {\n    _listener = listener;\n}\n\nLayerRootListener* LayerRoot::getListener() const {\n    return _listener;\n}\n\nvoid LayerRoot::setContentLayer(const Valdi::Ref<Layer>& contentLayer, ContentLayerSizingMode sizingMode) {\n    if (_contentLayer != contentLayer || _sizingMode != sizingMode) {\n        _touchDispatcher.cancelAllGestures();\n\n        if (_contentLayer != nullptr) {\n            _contentLayer->onParentChanged(nullptr);\n        }\n\n        _contentLayer = contentLayer;\n        _sizingMode = sizingMode;\n\n        if (_contentLayer != nullptr) {\n            _contentLayer->onParentChanged(Valdi::strongSmallRef(this));\n        }\n\n        setChildNeedsDisplay();\n        requestLayout(this);\n    }\n}\n\nconst Valdi::Ref<Layer>& LayerRoot::getContentLayer() const {\n    return _contentLayer;\n}\n\nvoid LayerRoot::destroy() {\n    _listener = nullptr;\n    _destroyed = true;\n    setContentLayer(nullptr, _sizingMode);\n    _eventQueue.clear();\n}\n\nvoid LayerRoot::setSize(Size size, Scalar scale) {\n    if (_size != size) {\n        _size = size;\n        _needsLayout = true;\n    }\n\n    if (_scale != scale) {\n        _scale = scale;\n        setChildNeedsDisplay();\n    }\n\n    layoutIfNeeded();\n}\n\nvoid LayerRoot::drawInCanvas(DrawableSurfaceCanvas& canvas) {\n    if (_size.width == 0 || _size.height == 0) {\n        return;\n    }\n\n    auto displayList = draw();\n\n    auto scaleWidth = static_cast<Scalar>(canvas.getWidth()) / _size.width;\n    auto scaleHeight = static_cast<Scalar>(canvas.getHeight()) / _size.height;\n\n    displayList->draw(canvas, kDisplayListAllPlaneIndexes, scaleWidth, scaleHeight, /* shouldClearCanvas */ true);\n}\n\nRef<DisplayList> LayerRoot::draw() {\n    VALDI_TRACE(\"SnapDrawing.draw\");\n\n    snap::utils::time::StopWatch sw;\n    sw.start();\n\n    DrawMetrics metrics;\n    auto displayList = doDraw(metrics);\n\n    auto elapsed = sw.elapsed();\n    if (elapsed.milliseconds() >= kFrameWarningThresholdMs) {\n        VALDI_WARN(_resources->getLogger(),\n                   \"Spent {} to render frame (draw cache hit {}, draw cache miss {})\",\n                   elapsed.toString(),\n                   metrics.visitedLayers - metrics.drawCacheMiss,\n                   metrics.drawCacheMiss);\n    }\n\n    return displayList;\n}\n\nRef<DisplayList> LayerRoot::doDraw(DrawMetrics& metrics) {\n    auto displayList =\n        Valdi::makeShared<DisplayList>(_size, _lastAbsoluteFrameTime ? _lastAbsoluteFrameTime.value() : TimePoint(0.0));\n\n    if (_contentLayer != nullptr) {\n        _contentLayer->draw(*displayList, metrics);\n    }\n\n    if (_planeList == nullptr) {\n        _planeList = std::make_unique<CompositorPlaneList>();\n    } else {\n        _planeList->clear();\n    }\n\n    Compositor compositor(_resources->getLogger());\n    return compositor.performComposition(*displayList, *_planeList);\n}\n\nvoid LayerRoot::setChildNeedsDisplay() {\n    if (!_needsDisplay) {\n        _needsDisplay = true;\n        enqueueFrame();\n    }\n}\n\nbool LayerRoot::needsDisplay() const {\n    return _needsDisplay;\n}\n\nvoid LayerRoot::requestLayout(ILayer* /*layer*/) {\n    if (!_needsLayout) {\n        _needsLayout = true;\n        enqueueFrame();\n    }\n}\n\nvoid LayerRoot::requestFocus(ILayer* /*layer*/) {\n    // no-op by default\n}\n\nbool LayerRoot::dispatchTouchEvent(const TouchEvent& event) {\n    if (_contentLayer == nullptr || _touchDispatcher.isDispatchingEvent()) {\n        return false;\n    }\n\n    auto processed = _touchDispatcher.dispatchEvent(event, _contentLayer);\n\n    if (!_touchDispatcher.isEmpty()) {\n        enqueueFrame();\n    }\n\n    return processed;\n}\n\nGestureTypes LayerRoot::getGesturesTypesForTouchEvent(const TouchEvent& event) const {\n    if (_contentLayer == nullptr) {\n        return GestureTypes();\n    }\n\n    auto gestureCandidates = _touchDispatcher.getGestureCandidatesForEvent(event, _contentLayer);\n\n    GestureTypes types;\n\n    for (const auto& gesture : gestureCandidates) {\n        if (Valdi::castOrNull<TapGestureRecognizer>(gesture) != nullptr) {\n            types.hasTap = true;\n        } else if (Valdi::castOrNull<ScrollGestureRecognizer>(gesture) != nullptr) {\n            types.hasScroll = true;\n        } else if (Valdi::castOrNull<DragGestureRecognizer>(gesture) != nullptr) {\n            types.hasDrag = true;\n        }\n    }\n\n    return types;\n}\n\nbool LayerRoot::refreshTouches(const TimePoint& currentTime) {\n    if (_touchDispatcher.isEmpty()) {\n        return false;\n    }\n    if (!_touchDispatcher.getLastEvent()) {\n        return false;\n    }\n\n    const auto& lastEvent = _touchDispatcher.getLastEvent().value();\n\n    auto offsetSinceLastEvent = currentTime - lastEvent.getTime();\n\n    if (offsetSinceLastEvent.milliseconds() < kTouchRefreshMs) {\n        // Only refresh gestures if there wasn't another event that came over 10ms ago\n        return false;\n    }\n\n    const auto wasInteraction =\n        (lastEvent.getType() == TouchEventTypeDown || lastEvent.getType() == TouchEventTypeMoved ||\n         lastEvent.getType() == TouchEventTypeIdle || lastEvent.getType() == TouchEventTypePointerDown ||\n         lastEvent.getType() == TouchEventTypePointerUp);\n    const auto newType = wasInteraction ? TouchEventTypeIdle : TouchEventTypeNone;\n\n    dispatchTouchEvent(TouchEvent(newType,\n                                  lastEvent.getLocationInWindow(),\n                                  lastEvent.getLocation(),\n                                  lastEvent.getDirection(),\n                                  lastEvent.getPointerCount(),\n                                  lastEvent.getActionIndex(),\n                                  lastEvent.getPointerLocations(),\n                                  currentTime,\n                                  lastEvent.getOffsetSinceSource() + offsetSinceLastEvent,\n                                  lastEvent.getSource()));\n    return true;\n}\n\nEventId LayerRoot::enqueueEvent(EventCallback&& eventCallback, Duration after) {\n    auto eventId = _eventQueue.enqueue(after, std::move(eventCallback));\n    enqueueFrame();\n    return eventId;\n}\n\nbool LayerRoot::cancelEvent(EventId eventId) {\n    return _eventQueue.cancel(eventId);\n}\n\nvoid LayerRoot::enqueueFrame() {\n    if (canEnqueueFrame() && _listener != nullptr) {\n        _didEnqueueFrame = true;\n        _listener->onNeedsProcessFrame(*this);\n    }\n}\n\nvoid LayerRoot::layoutIfNeeded() {\n    if (needsLayout()) {\n        VALDI_TRACE(\"SnapDrawing.layout\");\n        _needsLayout = false;\n\n        Size resolvedSize;\n\n        if (_sizingMode == ContentLayerSizingModeMinSize) {\n            resolvedSize = _contentLayer->sizeThatFits(_size);\n        } else {\n            resolvedSize = _size;\n        }\n\n        _contentLayer->setFrame(Rect::makeXYWH(0, 0, resolvedSize.width, resolvedSize.height));\n        _contentLayer->layoutIfNeeded();\n    }\n}\n\nTimePoint LayerRoot::updateFrameTime(TimePoint absoluteFrameTime) {\n    if (!_initialAbsoluteFrameTime) {\n        _initialAbsoluteFrameTime = {absoluteFrameTime};\n    }\n    _lastAbsoluteFrameTime = {absoluteFrameTime};\n\n    return TimePoint((absoluteFrameTime - _initialAbsoluteFrameTime.value()).seconds());\n}\n\nTimePoint LayerRoot::getFrameTimeForAbsoluteFrameTime(TimePoint absoluteFrameTime) const {\n    if (!_initialAbsoluteFrameTime) {\n        return TimePoint(0.0);\n    }\n\n    return TimePoint((absoluteFrameTime - _initialAbsoluteFrameTime.value()).seconds());\n}\n\nuint64_t LayerRoot::allocateLayerId() {\n    return ++_layerIdSequence;\n}\n\nvoid LayerRoot::processFrame(TimePoint absoluteFrameTime) {\n    if (_destroyed) {\n        return;\n    }\n\n    _processingFrame = true;\n\n    VALDI_TRACE(\"SnapDrawing.processFrame\");\n\n    auto frameTime = updateFrameTime(absoluteFrameTime);\n\n    layoutIfNeeded();\n\n    {\n        VALDI_TRACE(\"SnapDrawing.flushEvents\");\n        refreshTouches(frameTime);\n        _eventQueue.flush(frameTime);\n    }\n\n    Ref<DisplayList> displayList;\n\n    if (_needsDisplay) {\n        _needsDisplay = false;\n        displayList = draw();\n        _lastDrawnFrame = displayList;\n    }\n\n    _didEnqueueFrame = false;\n    _processingFrame = false;\n\n    if (displayList != nullptr && _listener != nullptr) {\n        _listener->onDidDraw(*this, displayList, _planeList.get());\n    }\n\n    if (needsProcessFrame()) {\n        enqueueFrame();\n    }\n}\n\nbool LayerRoot::needsProcessFrame() const {\n    return _didEnqueueFrame || _needsDisplay || needsLayout() || !_eventQueue.isEmpty() || !_touchDispatcher.isEmpty();\n}\n\nbool LayerRoot::needsLayout() const {\n    return _needsLayout && _contentLayer != nullptr;\n}\n\nbool LayerRoot::canEnqueueFrame() const {\n    return !_didEnqueueFrame && !_processingFrame && !_destroyed;\n}\n\nconst Ref<DisplayList>& LayerRoot::getLastDrawnFrame() const {\n    return _lastDrawnFrame;\n}\n\nconst std::optional<TimePoint>& LayerRoot::getLastAbsoluteFrameTime() const {\n    return _lastAbsoluteFrameTime;\n}\n\nTouchDispatcher& LayerRoot::getTouchDispatcher() {\n    return _touchDispatcher;\n}\n\nScalar LayerRoot::getScale() const {\n    return _scale;\n}\n\nconst Ref<Resources>& LayerRoot::getResources() const {\n    return _resources;\n}\n\nbool LayerRoot::shouldRasterizeExternalSurface() const {\n    return false;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/LayerRoot.hpp",
    "content": "//\n//  LayerRoot.hpp\n//  valdi-skia-apple\n//\n//  Created by Simon Corsin on 6/27/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n#include \"valdi_core/cpp/Interfaces/IMainThreadDispatcher.hpp\"\n\n#include \"snap_drawing/cpp/Events/EventQueue.hpp\"\n#include \"snap_drawing/cpp/Layers/Interfaces/ILayerRoot.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Touches/TouchDispatcher.hpp\"\n#include \"snap_drawing/cpp/Touches/TouchEvent.hpp\"\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include <cstdint>\n\nnamespace snap::drawing {\n\nclass LayerRoot;\nclass DrawableSurfaceCanvas;\nclass CompositorPlaneList;\n\nclass LayerRootListener {\npublic:\n    virtual ~LayerRootListener() = default;\n\n    /**\n     Called whenever the layer tree requires a call to processFrame().\n     */\n    virtual void onNeedsProcessFrame(LayerRoot& root) = 0;\n\n    /**\n     Called whenever a frame was drawn during a processFrame() call.\n     The given DisplayList contains the draw operations for the whole tree and\n     can be drawn into a RenderTarget.\n     */\n    virtual void onDidDraw(LayerRoot& root,\n                           const Ref<DisplayList>& displayList,\n                           const CompositorPlaneList* planeList) = 0;\n};\n\nenum ContentLayerSizingMode {\n    // ContentLayer will have the minimum size possible\n    // for the given size constraints\n    ContentLayerSizingModeMinSize,\n    // ContentLayer will have the same size as the given\n    // size constraints\n    ContentLayerSizingModeMatchSize,\n};\n\nstruct GestureTypes {\n    bool hasTap = false;\n    bool hasScroll = false;\n    bool hasDrag = false;\n};\n\nclass LayerRoot : public ILayerRoot {\npublic:\n    explicit LayerRoot(const Ref<Resources>& resources);\n    ~LayerRoot() override;\n\n    void onInitialize() override;\n\n    void setContentLayer(const Valdi::Ref<Layer>& contentLayer, ContentLayerSizingMode sizingMode);\n    const Valdi::Ref<Layer>& getContentLayer() const;\n\n    bool dispatchTouchEvent(const TouchEvent& event);\n    GestureTypes getGesturesTypesForTouchEvent(const TouchEvent& event) const;\n    bool refreshTouches(const TimePoint& currentTime);\n\n    void setSize(Size size, Scalar scale);\n\n    void setListener(LayerRootListener* listener);\n    LayerRootListener* getListener() const;\n\n    void setChildNeedsDisplay() override;\n    bool needsDisplay() const;\n\n    void requestLayout(ILayer* layer) override;\n    EventId enqueueEvent(EventCallback&& eventCallback, Duration after) override;\n    bool cancelEvent(EventId eventId) override;\n\n    void requestFocus(ILayer* layer) override;\n\n    uint64_t allocateLayerId() override;\n\n    TouchDispatcher& getTouchDispatcher();\n\n    void destroy();\n\n    Scalar getScale() const;\n\n    void processFrame(TimePoint absoluteFrameTime);\n\n    const std::optional<TimePoint>& getLastAbsoluteFrameTime() const;\n    const Ref<DisplayList>& getLastDrawnFrame() const;\n\n    Ref<DisplayList> draw();\n\n    void drawInCanvas(DrawableSurfaceCanvas& canvas);\n\n    bool needsProcessFrame() const;\n\n    const Ref<Resources>& getResources() const;\n\n    bool shouldRasterizeExternalSurface() const override;\n\n    inline Scalar sanitizeCoordinate(Scalar value) const {\n        return snap::drawing::sanitizeScalarFromScale(value, _scale);\n    }\n\n    TimePoint getFrameTimeForAbsoluteFrameTime(TimePoint absoluteFrameTime) const;\n\nprivate:\n    Ref<Resources> _resources;\n    LayerRootListener* _listener = nullptr;\n    TouchDispatcher _touchDispatcher;\n    Valdi::Ref<Layer> _contentLayer;\n    EventQueue _eventQueue;\n    Size _size = Size::makeEmpty();\n    Scalar _scale = 1;\n    uint64_t _layerIdSequence = 0;\n    bool _needsDisplay = false;\n    bool _needsLayout = true;\n    bool _didEnqueueFrame = false;\n    bool _destroyed = false;\n    bool _processingFrame = false;\n    ContentLayerSizingMode _sizingMode = ContentLayerSizingModeMinSize;\n    std::optional<TimePoint> _initialAbsoluteFrameTime;\n    std::optional<TimePoint> _lastAbsoluteFrameTime;\n    std::unique_ptr<CompositorPlaneList> _planeList;\n    Ref<DisplayList> _lastDrawnFrame;\n\n    bool needsLayout() const;\n\n    void enqueueFrame();\n\n    void layoutIfNeeded();\n\n    bool canEnqueueFrame() const;\n\n    Ref<DisplayList> doDraw(DrawMetrics& metrics);\n\n    TimePoint updateFrameTime(TimePoint absoluteFrameTime);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Mask/GradientMaskLayer.cpp",
    "content": "//\n//  GradientMaskLayer.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 10/20/22.\n//\n\n#include \"snap_drawing/cpp/Layers/Mask/GradientMaskLayer.hpp\"\n\nnamespace snap::drawing {\n\nGradientMaskLayer::GradientMaskLayer() = default;\nGradientMaskLayer::~GradientMaskLayer() = default;\n\nconst LinearGradient& GradientMaskLayer::getGradient() const {\n    return _gradient;\n}\n\nLinearGradient& GradientMaskLayer::getGradient() {\n    return _gradient;\n}\n\nvoid GradientMaskLayer::onConfigurePaint(Paint& paint, const Rect& bounds) {\n    PaintMaskLayer::onConfigurePaint(paint, bounds);\n\n    _gradient.update(bounds);\n    _gradient.applyToPaint(paint);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Mask/GradientMaskLayer.hpp",
    "content": "//\n//  GradientMaskLayer.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 10/20/22.\n//\n\n#include \"snap_drawing/cpp/Drawing/LinearGradient.hpp\"\n#include \"snap_drawing/cpp/Layers/Mask/PaintMaskLayer.hpp\"\n\nnamespace snap::drawing {\n\nclass Paint;\n\n/**\n A GradientMaskLayer is a specialization of PaintMaskLayer which\n draws the region using a given gradient.\n */\nclass GradientMaskLayer : public PaintMaskLayer {\npublic:\n    GradientMaskLayer();\n    ~GradientMaskLayer() override;\n\n    const LinearGradient& getGradient() const;\n    LinearGradient& getGradient();\n\nprotected:\n    void onConfigurePaint(Paint& paint, const Rect& bounds) override;\n\nprivate:\n    LinearGradient _gradient;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Mask/IMaskLayer.hpp",
    "content": "//\n//  IMaskLayer.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 10/20/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"snap_drawing/cpp/Drawing/Mask/IMask.hpp\"\n\nnamespace snap::drawing {\n\n/**\n MaskLayerPositioning defines where a mask should be prepared/applied within the layer.\n */\nenum class MaskLayerPositioning {\n    /**\n     The mask should be prepared before the background, which will cause\n     the masking operation to include the background.\n     */\n    BelowBackground,\n\n    /**\n     The mask should be prepared after the background, which will cause the\n     masking operation to NOT include the background.\n     */\n    AboveBackground\n\n};\n\n/**\n A MaskLayer can set up a mask within a Layer instance. It can be set directly on a Layer, to\n alter how the layer and its children should be drawn.\n */\nclass IMaskLayer : public Valdi::SimpleRefCountable {\npublic:\n    /**\n     Returns the positioning that should be used to prepare the mask within the Layer.\n     */\n    virtual MaskLayerPositioning getPositioning() = 0;\n\n    /**\n     Create the final mask that should be prepared and applied at draw time.\n     This method can return null if no masks should be applied.\n     */\n    virtual Ref<IMask> createMask(const Rect& bounds) = 0;\n};\n\n}; // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Mask/PaintMaskLayer.cpp",
    "content": "//\n//  PaintMaskLayer.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 10/20/22.\n//\n\n#include \"snap_drawing/cpp/Layers/Mask/PaintMaskLayer.hpp\"\n#include \"snap_drawing/cpp/Drawing/Mask/PaintMask.hpp\"\n\nnamespace snap::drawing {\n\nPaintMaskLayer::PaintMaskLayer() = default;\nPaintMaskLayer::~PaintMaskLayer() = default;\n\nvoid PaintMaskLayer::setPath(const Path& path) {\n    _path = path;\n    _rect = Rect::makeEmpty();\n}\n\nvoid PaintMaskLayer::setRect(const Rect& rect) {\n    _rect = rect;\n\n    if (!_path.isEmpty()) {\n        _path.reset();\n    }\n}\n\nvoid PaintMaskLayer::setColor(Color color) {\n    _color = color;\n}\n\nColor PaintMaskLayer::getColor() const {\n    return _color;\n}\n\nvoid PaintMaskLayer::setBlendMode(SkBlendMode blendMode) {\n    _blendMode = blendMode;\n}\n\nRect PaintMaskLayer::getBounds() const {\n    auto bounds = _path.getBounds();\n    return bounds ? bounds.value() : _rect;\n}\n\nRef<IMask> PaintMaskLayer::createMask(const Rect& /*bounds*/) {\n    auto pathBounds = getBounds();\n    if (pathBounds.isEmpty()) {\n        return nullptr;\n    }\n\n    Paint paint;\n    onConfigurePaint(paint, pathBounds);\n\n    return Valdi::makeShared<PaintMask>(paint, _path, _rect);\n}\n\nMaskLayerPositioning PaintMaskLayer::getPositioning() {\n    return _positioning;\n}\n\nvoid PaintMaskLayer::setPositioning(MaskLayerPositioning positioning) {\n    _positioning = positioning;\n}\n\nvoid PaintMaskLayer::onConfigurePaint(Paint& paint, const Rect& /*bounds*/) {\n    paint.setColor(_color);\n    paint.setBlendMode(_blendMode);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Mask/PaintMaskLayer.hpp",
    "content": "//\n//  PaintMaskLayer.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 10/20/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n#include \"snap_drawing/cpp/Layers/Mask/IMaskLayer.hpp\"\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"include/core/SkBlendMode.h\"\n\nnamespace snap::drawing {\n\nclass Paint;\n\n/**\n A PaintMaskLayer is an IMaskLayer implementation that emits PaintMask.\n When using the default DstOut blendMode, this will cause a given region\n provided through a rect or path to be drawn with a different opacity.\n */\nclass PaintMaskLayer : public IMaskLayer {\npublic:\n    PaintMaskLayer();\n    ~PaintMaskLayer() override;\n\n    void setRect(const Rect& rect);\n    void setPath(const Path& path);\n\n    /**\n     Set the color that should be used to draw the region.\n     */\n    void setColor(Color color);\n\n    /**\n     Get the color that should be used to draw the region\n     */\n    Color getColor() const;\n\n    void setPositioning(MaskLayerPositioning positioning);\n\n    /**\n     Set the blend mode that should be used to draw the region.\n     */\n    void setBlendMode(SkBlendMode blendMode);\n\n    /**\n     Returns the bounds that represents the entire region configured\n     through either a rect or path.\n     */\n    Rect getBounds() const;\n\n    MaskLayerPositioning getPositioning() override;\n    Ref<IMask> createMask(const Rect& bounds) override;\n\nprotected:\n    virtual void onConfigurePaint(Paint& paint, const Rect& bounds);\n\nprivate:\n    Rect _rect;\n    Path _path;\n    Color _color = Color::black();\n    SkBlendMode _blendMode = SkBlendMode::kDstOut;\n    MaskLayerPositioning _positioning = MaskLayerPositioning::BelowBackground;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Mask/ScrollLayerFadingEdgesMaskLayer.cpp",
    "content": "#include \"snap_drawing/cpp/Layers/Mask/ScrollLayerFadingEdgesMaskLayer.hpp\"\n#include \"snap_drawing/cpp/Drawing/Mask/CompositeMask.hpp\"\n\nnamespace snap::drawing {\n\nScrollLayerFadingEdgesMaskLayer::ScrollLayerFadingEdgesMaskLayer() = default;\nScrollLayerFadingEdgesMaskLayer::~ScrollLayerFadingEdgesMaskLayer() = default;\n\nbool ScrollLayerFadingEdgesMaskLayer::configure(bool isHorizontal,\n                                                const Rect& scrollRect,\n                                                Scalar leadingEdgeLength,\n                                                Scalar trailingEdgeLength) {\n    auto boundsChanged = _scrollRect != scrollRect;\n    if (!boundsChanged && _isHorizontal == isHorizontal && _leadingEdgeLength == leadingEdgeLength &&\n        _trailingEdgeLength == trailingEdgeLength) {\n        return false;\n    }\n    _isHorizontal = isHorizontal;\n    _scrollRect = scrollRect;\n    LinearGradientOrientation orientation =\n        isHorizontal ? LinearGradientOrientationLeftRight : LinearGradientOrientationTopBottom;\n    if (leadingEdgeLength != _leadingEdgeLength || boundsChanged) {\n        _leadingEdgeLength = leadingEdgeLength;\n        if (leadingEdgeLength > 0 && _leadingEdgeMaskLayer == nullptr) {\n            _leadingEdgeMaskLayer = Valdi::makeShared<GradientMaskLayer>();\n            _leadingEdgeMaskLayer->setPositioning(getPositioning());\n            std::vector<Color> colors{Color::black(), Color::transparent()};\n            _leadingEdgeMaskLayer->getGradient().setColors(std::move(colors));\n        }\n        if (_leadingEdgeMaskLayer.get()) {\n            _leadingEdgeMaskLayer->getGradient().setOrientation(orientation);\n            auto rect = Rect::makeLTRB(0,\n                                       0,\n                                       isHorizontal ? leadingEdgeLength : scrollRect.right,\n                                       isHorizontal ? scrollRect.bottom : leadingEdgeLength);\n            _leadingEdgeMaskLayer->setRect(rect);\n        }\n    }\n    if (trailingEdgeLength != _trailingEdgeLength || boundsChanged) {\n        _trailingEdgeLength = trailingEdgeLength;\n        if (trailingEdgeLength > 0 && _trailingEdgeMaskLayer == nullptr) {\n            _trailingEdgeMaskLayer = Valdi::makeShared<GradientMaskLayer>();\n            _trailingEdgeMaskLayer->setPositioning(getPositioning());\n            std::vector<Color> colors{Color::transparent(), Color::black()};\n            _trailingEdgeMaskLayer->getGradient().setColors(std::move(colors));\n        }\n        if (_trailingEdgeMaskLayer.get()) {\n            _trailingEdgeMaskLayer->getGradient().setOrientation(orientation);\n            auto rect = Rect::makeLTRB(isHorizontal ? scrollRect.right - trailingEdgeLength : 0,\n                                       isHorizontal ? 0 : scrollRect.bottom - trailingEdgeLength,\n                                       scrollRect.right,\n                                       scrollRect.bottom);\n            _trailingEdgeMaskLayer->setRect(rect);\n        }\n    }\n    return true;\n}\n\nMaskLayerPositioning ScrollLayerFadingEdgesMaskLayer::getPositioning() {\n    return MaskLayerPositioning::AboveBackground;\n}\n\nRef<IMask> ScrollLayerFadingEdgesMaskLayer::createMask(const Rect& bounds) {\n    std::vector<Ref<IMask>> masks;\n    if (_leadingEdgeLength > 0) {\n        auto mask = _leadingEdgeMaskLayer->createMask(bounds);\n        if (mask != nullptr) {\n            masks.emplace_back(mask);\n        }\n    }\n    if (_trailingEdgeLength > 0) {\n        auto mask = _trailingEdgeMaskLayer->createMask(bounds);\n        if (mask != nullptr) {\n            masks.emplace_back(mask);\n        }\n    }\n    if (masks.empty()) {\n        return nullptr;\n    }\n    auto composite = Valdi::makeShared<CompositeMask>(std::move(masks));\n    return composite;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Mask/ScrollLayerFadingEdgesMaskLayer.hpp",
    "content": "#include \"snap_drawing/cpp/Layers/Mask/GradientMaskLayer.hpp\"\n\nnamespace snap::drawing {\n\nclass Paint;\n\nclass ScrollLayerFadingEdgesMaskLayer : public IMaskLayer {\npublic:\n    ScrollLayerFadingEdgesMaskLayer();\n    ~ScrollLayerFadingEdgesMaskLayer() override;\n\n    bool configure(bool isHorizontal, const Rect& scrollRect, Scalar leadingEdgeLength, Scalar trailingEdgeLength);\n\n    MaskLayerPositioning getPositioning() override;\n    Ref<IMask> createMask(const Rect& bounds) override;\n\nprotected:\nprivate:\n    bool _isHorizontal = false;\n    Rect _scrollRect;\n    Scalar _leadingEdgeLength = 0;\n    Scalar _trailingEdgeLength = 0;\n\n    Ref<GradientMaskLayer> _leadingEdgeMaskLayer;\n    Ref<GradientMaskLayer> _trailingEdgeMaskLayer;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/AndroidScroller.cpp",
    "content": "//\n//  AndroidScroller.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 11/21/22.\n//\n\n#include \"snap_drawing/cpp/Layers/Scroll/AndroidScroller.hpp\"\n#include \"snap_drawing/cpp/Animations/InterpolationFunction.hpp\"\n#include \"snap_drawing/cpp/Animations/ValueInterpolators.hpp\"\n#include \"snap_drawing/cpp/Layers/Scroll/SplineScrollPhysics.hpp\"\n#include \"snap_drawing/cpp/Layers/Scroll/SpringFlingScrollLayerAnimation.hpp\"\n#include \"snap_drawing/cpp/Layers/ScrollLayer.hpp\"\n#include \"snap_drawing/cpp/Resources.hpp\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nstatic constexpr Duration kSlowDuration = Duration(0.4);\nstatic constexpr Duration kFastDuration = Duration(0.25);\nstatic constexpr Scalar kFlingDecelerationRate = 0.998f;\nstatic Scalar kFlingDecelerationCoefficient = 1000 * std::log(kFlingDecelerationRate);\nstatic Scalar kFlingDecelerationCorrection = 1.0f / -kFlingDecelerationCoefficient;\n\nconstexpr Scalar kSpringMass = 0.35;\nconstexpr Scalar kSpringStiffness = 120;\nconstexpr Scalar kSpringDampingRatio = 0.95;\n\nstatic const SpringScrollPhysicsConfiguration* getSpringScrollPhysicsConfiguration() {\n    static SpringScrollPhysicsConfiguration kInstance =\n        SpringScrollPhysicsConfiguration::make(kSpringMass, kSpringStiffness, kSpringDampingRatio);\n    return &kInstance;\n}\n\nclass AndroidContentOffsetAnimation : public BaseScrollLayerAnimation {\npublic:\n    AndroidContentOffsetAnimation(const Point& sourceContentOffset, const Point& targetContentOffset, bool fast)\n        : _sourceContentOffset(sourceContentOffset),\n          _targetContentOffset(targetContentOffset),\n          _duration(fast ? kFastDuration : kSlowDuration) {}\n\n    ~AndroidContentOffsetAnimation() override = default;\n\n    bool update(ScrollLayer& scrollLayer, Duration delta) override {\n        _elapsed += delta;\n        if (_elapsed >= _duration) {\n            applyContentOffset(scrollLayer, _targetContentOffset);\n            return true;\n        }\n\n        auto ratio = InterpolationFunctions::viscousFluid()(_elapsed.seconds() / _duration.seconds());\n        auto currentContentOffset = interpolateValue(_sourceContentOffset, _targetContentOffset, ratio);\n\n        auto adjustment = applyContentOffset(scrollLayer, currentContentOffset);\n        _sourceContentOffset.x += adjustment.dx;\n        _sourceContentOffset.y += adjustment.dy;\n\n        return false;\n    }\n\nprivate:\n    Point _sourceContentOffset;\n    Point _targetContentOffset;\n    Duration _duration;\n    Duration _elapsed;\n    Vector _contentOffsetAdjustment;\n};\n\nclass AndroidFlingAnimation : public SpringFlingScrollLayerAnimation {\npublic:\n    AndroidFlingAnimation(AndroidScroller* scroller,\n                          Scalar scrollFriction,\n                          const Point& sourceContentOffset,\n                          const Vector& velocity,\n                          bool /*fast*/)\n        : _scroller(scroller), _sourceContentOffset(sourceContentOffset), _physics(scrollFriction, velocity) {}\n\n    ~AndroidFlingAnimation() override = default;\n\nprotected:\n    void updateCarriedVelocity(const Vector& velocity) final {\n        _scroller->updateCarriedVelocity(velocity);\n    }\n\n    bool onDecelerate(ScrollLayer& scrollLayer, Duration elapsed) final {\n        auto result = _physics.compute(elapsed);\n\n        auto contentOffset = _sourceContentOffset.makeOffset(result.distance.dx, result.distance.dy);\n        auto clampedContentOffset = clampContentOffset(scrollLayer, contentOffset);\n\n        if (clampedContentOffset != contentOffset) {\n            return startBouncing(scrollLayer,\n                                 result.velocity,\n                                 contentOffset,\n                                 clampedContentOffset,\n                                 Duration(),\n                                 getSpringScrollPhysicsConfiguration());\n        }\n\n        auto adjustment = applyContentOffset(scrollLayer, contentOffset);\n        _sourceContentOffset.x += adjustment.dx;\n        _sourceContentOffset.y += adjustment.dy;\n\n        updateCarriedVelocity(result.velocity);\n\n        return result.finished;\n    }\n\nprivate:\n    Ref<AndroidScroller> _scroller;\n    Point _sourceContentOffset;\n    SplineScrollPhysics _physics;\n};\n\nAndroidScroller::AndroidScroller(const Ref<Resources>& resources)\n    : _scrollFriction(resources->getGesturesConfiguration().scrollFriction) {}\n\nAndroidScroller::~AndroidScroller() = default;\n\nvoid AndroidScroller::reset() {\n    updateCarriedVelocity(Vector::makeEmpty());\n}\n\nvoid AndroidScroller::onDrag(GestureRecognizerState /*state*/, const DragEvent& event) {\n    if (std::signbit(_carriedVelocity.dx) != std::signbit(event.velocity.dx)) {\n        // Change direction, cancel all the carried velocity\n        _carriedVelocity.dx = 0.0f;\n    }\n\n    if (std::signbit(_carriedVelocity.dy) != std::signbit(event.velocity.dy)) {\n        // Change direction, cancel all the carried velocity\n        _carriedVelocity.dy = 0.0f;\n    }\n}\n\nPoint AndroidScroller::computeDecelerationFinalOffset(const Point& contentOffset,\n                                                      const Vector& velocity,\n                                                      const Size& pageSize,\n                                                      bool /*fast*/) {\n    auto flingRangeX = pageSize.width / 2.0f;\n    auto flingRangeY = pageSize.height / 2.0f;\n    auto flingRawDistanceX = velocity.dx * kFlingDecelerationCorrection;\n    auto flingRawDistanceY = velocity.dy * kFlingDecelerationCorrection;\n    auto flingClampedDistanceX = std::min(std::max(flingRawDistanceX, -flingRangeX), +flingRangeX);\n    auto flingClampedDistanceY = std::min(std::max(flingRawDistanceY, -flingRangeY), +flingRangeY);\n    return Point(contentOffset.x + flingClampedDistanceX, contentOffset.y + flingClampedDistanceY);\n}\n\nvoid AndroidScroller::updateCarriedVelocity(Vector currentVelocity) {\n    _carriedVelocity = currentVelocity;\n}\n\nRef<BaseScrollLayerAnimation> AndroidScroller::fling(const Point& sourceContentOffset,\n                                                     const Vector& velocity,\n                                                     bool fast) {\n    auto resolvedVelocity = Vector::make(velocity.dx + _carriedVelocity.dx, velocity.dy + _carriedVelocity.dy);\n\n    return Valdi::makeShared<AndroidFlingAnimation>(this, _scrollFriction, sourceContentOffset, resolvedVelocity, fast);\n}\n\nRef<BaseScrollLayerAnimation> AndroidScroller::animate(const Point& sourceContentOffset,\n                                                       const Point& targetContentOffset,\n                                                       bool fast) {\n    return Valdi::makeShared<AndroidContentOffsetAnimation>(sourceContentOffset, targetContentOffset, fast);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/AndroidScroller.hpp",
    "content": "//\n//  AndroidScroller.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 11/21/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Scroll/IScroller.hpp\"\n\nnamespace snap::drawing {\n\nclass AndroidFlingAnimation;\nclass AndroidContentOffsetAnimation;\nclass Resources;\n\n/**\n An IScroller implementation that replicates Android's scroll physics.\n */\nclass AndroidScroller : public IScroller {\npublic:\n    explicit AndroidScroller(const Ref<Resources>& resources);\n    ~AndroidScroller() override;\n\n    void reset() override;\n\n    void onDrag(GestureRecognizerState state, const DragEvent& event) override;\n    Point computeDecelerationFinalOffset(const Point& contentOffset,\n                                         const Vector& velocity,\n                                         const Size& pageSize,\n                                         bool fast) override;\n\n    Ref<BaseScrollLayerAnimation> fling(const Point& sourceContentOffset, const Vector& velocity, bool fast) override;\n    Ref<BaseScrollLayerAnimation> animate(const Point& sourceContentOffset,\n                                          const Point& targetContentOffset,\n                                          bool fast) override;\n\nprivate:\n    friend AndroidFlingAnimation;\n    friend AndroidContentOffsetAnimation;\n\n    Vector _carriedVelocity;\n    Scalar _scrollFriction = 0.0f;\n\n    void updateCarriedVelocity(Vector currentVelocity);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/BaseScrollLayerAnimation.cpp",
    "content": "//\n//  BaseScrollLayerAnimation.cpp\n//  snap_drawing-ios\n//\n//  Created by Simon Corsin on 11/18/22.\n//\n\n#include \"snap_drawing/cpp/Layers/Scroll/BaseScrollLayerAnimation.hpp\"\n#include \"snap_drawing/cpp/Layers/ScrollLayer.hpp\"\n\nnamespace snap::drawing {\n\nBaseScrollLayerAnimation::BaseScrollLayerAnimation() = default;\nBaseScrollLayerAnimation::~BaseScrollLayerAnimation() = default;\n\nbool BaseScrollLayerAnimation::run(Layer& layer, Duration delta) {\n    auto& scrollLayer = dynamic_cast<ScrollLayer&>(layer);\n\n    if (!_started) {\n        _started = true;\n        // delta is currently not always correct on the first animation frame\n        // TODO(simon): Fix this inside the FrameScheduler.\n        return false;\n    }\n\n    return update(scrollLayer, delta);\n}\n\nvoid BaseScrollLayerAnimation::cancel(Layer& layer) {\n    auto& scrollLayer = dynamic_cast<ScrollLayer&>(layer);\n    scrollLayer.onScrollAnimationEnded();\n}\n\nvoid BaseScrollLayerAnimation::complete(Layer& layer) {\n    auto& scrollLayer = dynamic_cast<ScrollLayer&>(layer);\n    scrollLayer.onScrollAnimationEnded();\n}\n\nvoid BaseScrollLayerAnimation::addCompletion(AnimationCompletion&& /*completion*/) {\n    // not implemented. Not needed for now\n}\n\nPoint BaseScrollLayerAnimation::clampContentOffset(ScrollLayer& scrollLayer, Point contentOffset) {\n    auto clampedOffsetX = scrollLayer.clampContentOffsetX(contentOffset.x);\n    auto clamedOpffsetY = scrollLayer.clampContentOffsetY(contentOffset.y);\n\n    return Point::make(clampedOffsetX, clamedOpffsetY);\n}\n\nVector BaseScrollLayerAnimation::applyContentOffset(ScrollLayer& scrollLayer, Point contentOffset) {\n    return scrollLayer.applyContentOffset(contentOffset.x, contentOffset.y, Vector::makeEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/BaseScrollLayerAnimation.hpp",
    "content": "//\n//  BaseScrollLayerAnimation.hpp\n//  snap_drawing-ios\n//\n//  Created by Simon Corsin on 11/18/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\nnamespace snap::drawing {\n\nclass ScrollLayer;\n\nclass BaseScrollLayerAnimation : public IAnimation {\npublic:\n    BaseScrollLayerAnimation();\n    ~BaseScrollLayerAnimation() override;\n\n    bool run(Layer& layer, Duration delta) override;\n    void cancel(Layer& layer) override;\n    void complete(Layer& layer) override;\n    void addCompletion(AnimationCompletion&& completion) override;\n\nprotected:\n    virtual bool update(ScrollLayer& scrollLayer, Duration delta) = 0;\n\n    static Point clampContentOffset(ScrollLayer& scrollLayer, Point contentOffset);\n    static Vector applyContentOffset(ScrollLayer& scrollLayer, Point contentOffset);\n\nprivate:\n    bool _started = false;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/IOSScroller.cpp",
    "content": "//\n//  IOSScroller.cpp\n//  snap_drawing-ios\n//\n//  Created by Simon Corsin on 11/18/22.\n//\n\n#include \"snap_drawing/cpp/Layers/Scroll/IOSScroller.hpp\"\n#include \"snap_drawing/cpp/Layers/Scroll/SpringFlingScrollLayerAnimation.hpp\"\n#include \"snap_drawing/cpp/Layers/Scroll/SpringScrollPhysics.hpp\"\n#include \"snap_drawing/cpp/Layers/ScrollLayer.hpp\"\n\n#include <cmath>\n\nnamespace snap::drawing {\n\nconstexpr Scalar kVelocityThreshold = 0.2;\nconstexpr float kTimeThresholdInMilliseconds = 250;\n\nconstexpr Scalar kThreshold = 0.5;\n\nconstexpr Scalar kDecelerationNormalRate = 0.998;\nstatic Scalar const kDecelerationNormalCoef = 1000 * log(kDecelerationNormalRate);\n\nconstexpr Scalar kDecelerationFastRate = 0.99;\nstatic Scalar const kDecelerationFastCoef = 1000 * log(kDecelerationFastRate);\n\nconstexpr Scalar kSpringMass = 0.5;\nconstexpr Scalar kSpringStiffness = 95;\nconstexpr Scalar kSpringDampingRatio = 0.95;\n\nstatic const SpringScrollPhysicsConfiguration* getSpringScrollPhysicsConfiguration() {\n    static SpringScrollPhysicsConfiguration kInstance =\n        SpringScrollPhysicsConfiguration::make(kSpringMass, kSpringStiffness, kSpringDampingRatio);\n    return &kInstance;\n}\n\nstatic Scalar carriedVelocityComputation(Scalar velocity) {\n    static constexpr Scalar kThreshold = 80000.0f;\n    Scalar sign = std::signbit(velocity) ? -1 : 1;\n    Scalar scaledMomentum = 0.000816f * std::pow(std::abs(velocity), 1.967f);\n\n    return sign * std::min(scaledMomentum, kThreshold);\n}\n\nclass IOSContentOffsetAnimation : public BaseScrollLayerAnimation {\npublic:\n    IOSContentOffsetAnimation(const Point& sourceContentOffset, const Point& targetContentOffset, bool fast)\n        : _contentOffset(sourceContentOffset), _targetContentOffset(targetContentOffset), _fast(fast) {\n        _velocity = IOSScroller::computeDecelerationInitialVelocity(sourceContentOffset, targetContentOffset, fast);\n        _duration = IOSScroller::computeDecelerationDuration(_velocity, false);\n    }\n\n    ~IOSContentOffsetAnimation() override = default;\n\n    bool update(ScrollLayer& scrollLayer, Duration delta) override {\n        _elapsed += delta;\n\n        if (_elapsed > _duration) {\n            applyContentOffset(scrollLayer, _targetContentOffset);\n            return true;\n        }\n\n        auto contentOffset = IOSScroller::computeDecelerationOffset(_contentOffset, _velocity, _elapsed, _fast);\n\n        auto adjustment = applyContentOffset(scrollLayer, contentOffset);\n\n        _contentOffset.x += adjustment.dx;\n        _contentOffset.y += adjustment.dy;\n\n        return false;\n    }\n\nprivate:\n    Duration _elapsed;\n    Duration _duration;\n    Point _contentOffset;\n    Point _targetContentOffset;\n    Vector _velocity;\n    bool _fast;\n};\n\nclass IOSFlingAnimation : public SpringFlingScrollLayerAnimation {\npublic:\n    IOSFlingAnimation(IOSScroller* scroller, const Point& sourceContentOffset, const Vector& velocity, bool fast)\n        : _scroller(Valdi::strongSmallRef(scroller)), _offset(sourceContentOffset), _velocity(velocity), _fast(fast) {}\n\n    ~IOSFlingAnimation() override = default;\n\n    void updateCarriedVelocity(const Vector& velocity) final {\n        _scroller->updateCarriedVelocity(velocity);\n    }\n\n    bool onOverscroll(ScrollLayer& scrollLayer,\n                      Duration elapsed,\n                      const Vector& deceleratedVelocity,\n                      const Point& contentOffset,\n                      const Point& clampedContentOffset) {\n        Duration startTime;\n        Vector resolvedVelocity = deceleratedVelocity;\n        Point resolvedSourceContentOffset = contentOffset;\n\n        auto duration =\n            IOSScroller::computeDecelerationTimeAtTargetOffset(_offset, _velocity, clampedContentOffset, _fast);\n\n        if (duration) {\n            startTime = elapsed - duration.value();\n            resolvedVelocity = computeDecelerationVelocity(duration.value());\n            resolvedSourceContentOffset = clampedContentOffset;\n        }\n\n        return startBouncing(scrollLayer,\n                             resolvedVelocity,\n                             resolvedSourceContentOffset,\n                             clampedContentOffset,\n                             startTime,\n                             getSpringScrollPhysicsConfiguration());\n    }\n\n    bool onDecelerate(ScrollLayer& scrollLayer, Duration elapsed) final {\n        auto deceleratedOffset = computeDecelerationOffset(elapsed);\n        auto deceleratedVelocity = computeDecelerationVelocity(elapsed);\n\n        auto clampedOffset = clampContentOffset(scrollLayer, deceleratedOffset);\n\n        const bool overScrolled = clampedOffset.x != deceleratedOffset.x || clampedOffset.y != deceleratedOffset.y;\n\n        if (overScrolled) {\n            return onOverscroll(scrollLayer, elapsed, deceleratedVelocity, deceleratedOffset, clampedOffset);\n        }\n\n        auto lowVelocity = Point::length(deceleratedVelocity.dx, deceleratedVelocity.dy) < kMinScrollVelocity;\n        if (lowVelocity) {\n            _scroller->reset();\n            return true;\n        }\n\n        updateCarriedVelocity(deceleratedVelocity);\n\n        auto adjustment = applyContentOffset(scrollLayer, deceleratedOffset);\n        _offset.x += adjustment.dx;\n        _offset.y += adjustment.dy;\n\n        return false;\n    }\n\nprivate:\n    Ref<IOSScroller> _scroller;\n    Point _offset;\n    Vector _velocity;\n    bool _fast;\n\n    Point computeDecelerationOffset(Duration elapsedTime) const {\n        return IOSScroller::computeDecelerationOffset(_offset, _velocity, elapsedTime, _fast);\n    }\n\n    Vector computeDecelerationVelocity(Duration elapsed) const {\n        auto rate = IOSScroller::getDecelerationRate(_fast);\n        auto ratio = std::pow(rate, elapsed.milliseconds());\n        auto deceleratedVelocityX = _velocity.dx * ratio;\n        auto deceleratedVelocityY = _velocity.dy * ratio;\n        return Vector::make(deceleratedVelocityX, deceleratedVelocityY);\n    }\n};\n\nIOSScroller::IOSScroller() : _dragStartTime(0) {}\nIOSScroller::~IOSScroller() = default;\n\nPoint IOSScroller::computeDecelerationFinalOffset(const Point& contentOffset,\n                                                  const Vector& velocity,\n                                                  const Size& /*pageSize*/,\n                                                  bool fast) {\n    auto coef = IOSScroller::getDecelerationCoef(fast);\n    auto finalOffsetX = contentOffset.x + velocity.dx / -coef;\n    auto finalOffsetY = contentOffset.y + velocity.dy / -coef;\n    return Point::make(finalOffsetX, finalOffsetY);\n}\n\nRef<BaseScrollLayerAnimation> IOSScroller::animate(const Point& sourceContentOffset,\n                                                   const Point& targetContentOffset,\n                                                   bool fast) {\n    reset();\n\n    return Valdi::makeShared<IOSContentOffsetAnimation>(sourceContentOffset, targetContentOffset, fast);\n}\n\nRef<BaseScrollLayerAnimation> IOSScroller::fling(const Point& sourceContentOffset, const Vector& velocity, bool fast) {\n    auto resolvedVelocity = Vector::make(velocity.dx + _carriedVelocity.dx, velocity.dy + _carriedVelocity.dy);\n\n    updateCarriedVelocity(resolvedVelocity);\n\n    return Valdi::makeShared<IOSFlingAnimation>(this, sourceContentOffset, resolvedVelocity, fast);\n}\n\nvoid IOSScroller::onDrag(GestureRecognizerState state, const DragEvent& event) {\n    if (std::signbit(_carriedVelocity.dx) != std::signbit(event.velocity.dx)) {\n        // Change direction, cancel all the carried velocity\n        _carriedVelocity.dx = 0.0f;\n    }\n\n    if (std::signbit(_carriedVelocity.dy) != std::signbit(event.velocity.dy)) {\n        // Change direction, cancel all the carried velocity\n        _carriedVelocity.dy = 0.0f;\n    }\n\n    auto currentTime = event.time;\n\n    if (state == GestureRecognizerStateBegan) {\n        _dragStartTime = currentTime;\n    } else if (state == GestureRecognizerStateEnded) {\n        // Cancel carried velocity if the fling velocity is under our threshold\n        if (std::abs(event.velocity.dx) < (std::abs(_carriedVelocity.dx) * kVelocityThreshold)) {\n            _carriedVelocity.dx = 0;\n        }\n        if (std::abs(event.velocity.dy) < (std::abs(_carriedVelocity.dy) * kVelocityThreshold)) {\n            _carriedVelocity.dy = 0;\n        }\n\n        if ((currentTime - _dragStartTime) > Duration::fromMilliseconds(kTimeThresholdInMilliseconds)) {\n            // Cancel carried velocity if the fling took more than 250ms\n            _carriedVelocity.dx = 0.0f;\n            _carriedVelocity.dy = 0.0f;\n        }\n    }\n}\n\nvoid IOSScroller::reset() {\n    _carriedVelocity.dx = 0.0f;\n    _carriedVelocity.dy = 0.0f;\n}\n\nvoid IOSScroller::updateCarriedVelocity(Vector currentVelocity) {\n    _carriedVelocity.dx = carriedVelocityComputation(currentVelocity.dx);\n    _carriedVelocity.dy = carriedVelocityComputation(currentVelocity.dy);\n}\n\nVector IOSScroller::computeDecelerationInitialVelocity(const Point& initialOffset,\n                                                       const Point& finalOffset,\n                                                       bool fast) {\n    auto coef = getDecelerationCoef(fast);\n    auto initialVelocityX = (finalOffset.x - initialOffset.x) * -coef;\n    auto initialVelocityY = (finalOffset.y - initialOffset.y) * -coef;\n    return Vector::make(initialVelocityX, initialVelocityY);\n}\n\nScalar IOSScroller::getDecelerationCoef(bool fast) {\n    if (fast) {\n        return kDecelerationFastCoef;\n    } else {\n        return kDecelerationNormalCoef;\n    }\n}\n\nScalar IOSScroller::getDecelerationRate(bool fast) {\n    if (fast) {\n        return kDecelerationFastRate;\n    } else {\n        return kDecelerationNormalRate;\n    }\n}\n\nDuration IOSScroller::computeDecelerationDuration(const Vector& velocity, bool fast) {\n    auto velocityLength = Point::length(velocity.dx, velocity.dy);\n    if (velocityLength == 0) {\n        return Duration::fromSeconds(0);\n    }\n    auto coef = IOSScroller::getDecelerationCoef(fast);\n    auto durationSeconds = std::log(-coef * kThreshold / velocityLength) / coef;\n    return Duration::fromSeconds(durationSeconds);\n}\n\nPoint IOSScroller::computeDecelerationOffset(const Point& contentOffset,\n                                             const Vector& velocity,\n                                             Duration elapsedTime,\n                                             bool fast) {\n    auto coef = IOSScroller::getDecelerationCoef(fast);\n    auto rate = IOSScroller::getDecelerationRate(fast);\n    // dx = x + ((((rate ^ ms) - 1) / coef) * vx)\n\n    auto ratio = (std::pow(rate, elapsedTime.milliseconds()) - 1) / coef;\n    auto deceleratedOffsetX = contentOffset.x + ratio * velocity.dx;\n    auto deceleratedOffsetY = contentOffset.y + ratio * velocity.dy;\n    return Point::make(deceleratedOffsetX, deceleratedOffsetY);\n}\n\nstd::optional<Duration> IOSScroller::computeDecelerationTimeAtTargetOffset(Scalar sourceOffset,\n                                                                           Scalar velocity,\n                                                                           Scalar targetOffset,\n                                                                           bool fast) {\n    // Base equation:\n    // dx = x + ((((rate ^ ms) - 1) / coef) * vx)\n    // ((dx - x) / vx * coeff) + 1 = rate ^ ms\n\n    auto distance = targetOffset - sourceOffset;\n\n    if (velocity == 0.0f || std::signbit(distance) != std::signbit(velocity)) {\n        return std::nullopt;\n    }\n\n    auto coef = IOSScroller::getDecelerationCoef(fast);\n    auto rate = IOSScroller::getDecelerationRate(fast);\n    auto base = (distance / velocity * coef) + 1.0f;\n\n    auto timeMs = std::log(base) / std::log(rate);\n\n    return Duration::fromMilliseconds(timeMs);\n}\n\nstd::optional<Duration> IOSScroller::computeDecelerationTimeAtTargetOffset(const Point& contentOffset,\n                                                                           const Vector& velocity,\n                                                                           const Point& targetContentOffset,\n                                                                           bool fast) {\n    auto xDuration = computeDecelerationTimeAtTargetOffset(contentOffset.x, velocity.dx, targetContentOffset.x, fast);\n    auto yDuration = computeDecelerationTimeAtTargetOffset(contentOffset.y, velocity.dy, targetContentOffset.y, fast);\n\n    if (xDuration && yDuration) {\n        return {std::min(xDuration.value(), yDuration.value())};\n    } else if (xDuration) {\n        return xDuration;\n    } else if (yDuration) {\n        return yDuration;\n    } else {\n        return std::nullopt;\n    }\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/IOSScroller.hpp",
    "content": "//\n//  IOSScroller.hpp\n//  snap_drawing-ios\n//\n//  Created by Simon Corsin on 11/18/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Scroll/IScroller.hpp\"\n\nnamespace snap::drawing {\n\nclass IOSFlingAnimation;\nclass IOSContentOffsetAnimation;\n\nclass IOSScroller : public IScroller {\npublic:\n    IOSScroller();\n    ~IOSScroller() override;\n\n    void reset() override;\n\n    void onDrag(GestureRecognizerState state, const DragEvent& event) override;\n    Point computeDecelerationFinalOffset(const Point& contentOffset,\n                                         const Vector& velocity,\n                                         const Size& pageSize,\n                                         bool fast) override;\n\n    Ref<BaseScrollLayerAnimation> fling(const Point& sourceContentOffset, const Vector& velocity, bool fast) override;\n    Ref<BaseScrollLayerAnimation> animate(const Point& sourceContentOffset,\n                                          const Point& targetContentOffset,\n                                          bool fast) override;\n\nprivate:\n    Vector _carriedVelocity;\n    TimePoint _dragStartTime;\n\n    friend IOSFlingAnimation;\n    friend IOSContentOffsetAnimation;\n\n    void updateCarriedVelocity(Vector currentVelocity);\n\n    static Scalar getDecelerationCoef(bool fast);\n    static Scalar getDecelerationRate(bool fast);\n    static Vector computeDecelerationInitialVelocity(const Point& initialOffset, const Point& finalOffset, bool fast);\n    static Duration computeDecelerationDuration(const Vector& velocity, bool fast);\n\n    static Point computeDecelerationOffset(const Point& contentOffset,\n                                           const Vector& velocity,\n                                           Duration elapsedTime,\n                                           bool fast);\n\n    static std::optional<Duration> computeDecelerationTimeAtTargetOffset(const Point& contentOffset,\n                                                                         const Vector& velocity,\n                                                                         const Point& targetContentOffset,\n                                                                         bool fast);\n\n    static std::optional<Duration> computeDecelerationTimeAtTargetOffset(Scalar sourceOffset,\n                                                                         Scalar velocity,\n                                                                         Scalar targetOffset,\n                                                                         bool fast);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/IScroller.hpp",
    "content": "//\n//  IScroller.hpp\n//  snap_drawing-ios\n//\n//  Created by Simon Corsin on 11/18/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Scroll/BaseScrollLayerAnimation.hpp\"\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\nnamespace snap::drawing {\n\n/**\n A Scroller is responsible for implementing the underlying scroll physics of a ScrollLayer.\n */\nclass IScroller : public Valdi::SimpleRefCountable {\npublic:\n    /**\n     Reset the state of the scroller.\n     Called when the ScrollLayer is removed from the hierarchy.\n     */\n    virtual void reset() = 0;\n\n    /**\n     Called on drag events. The scroller can use this to update its underlying\n     carried velocity.\n     */\n    virtual void onDrag(GestureRecognizerState state, const DragEvent& event) = 0;\n\n    /**\n     Computes the target deceleration offset for the given contentOffset at the given velocity.\n     This is used on paginated scrolling to find the target range.\n     */\n    virtual Point computeDecelerationFinalOffset(const Point& contentOffset,\n                                                 const Vector& velocity,\n                                                 const Size& pageSize,\n                                                 bool fast) = 0;\n\n    /**\n     Return an animation that will fling the scroll layer from the given source contentOffset with the given\n     velocity. The scroller should use its the accumulated velocity if it has any for the fling animation.\n     */\n    virtual Ref<BaseScrollLayerAnimation> fling(const Point& sourceContentOffset,\n                                                const Vector& velocity,\n                                                bool fast) = 0;\n\n    /**\n     Animate a scroll between the given source contentOffset to the given target contentOffset.\n     The scroller should not use its accumulated velocity.\n     */\n    virtual Ref<BaseScrollLayerAnimation> animate(const Point& sourceContentOffset,\n                                                  const Point& targetContentOffset,\n                                                  bool fast) = 0;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/SplineScrollPhysics.cpp",
    "content": "//\n//  SplineScrollPhysics.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 11/22/22.\n//\n\n#include \"snap_drawing/cpp/Layers/Scroll/SplineScrollPhysics.hpp\"\n#include <array>\n#include <cmath>\n\nnamespace snap::drawing {\n\n/**\n  These constants were extracted from Android's OverScroller.java\n*/\nstatic constexpr Scalar kDefaultGravity = 2000.0f;\nstatic constexpr Scalar kDefaultInflexion = 0.35f;\nstatic constexpr Scalar kDefaultStartTension = 0.5f;\nstatic constexpr Scalar kDefaultEndTension = 1.0f;\nstatic constexpr Scalar kDefaultPhysicalCoeff = 9.80665f // g (m/s^2)\n                                                * 39.37f // inch/meter\n                                                * 160.0f // pixels per inch\n                                                * 0.84f; // look and feel tuning\nstatic constexpr Scalar kDefaultDecelerationRate = 2.3582017f;\n\nstatic Scalar getOrDefault(Scalar value, Scalar defaultValue) {\n    return value != 0.0f ? value : defaultValue;\n}\n\n/**\n A large part of this file was ported from Android's OverScroller.java\n file.\n */\nstruct SplineOverScrollerConstants {\n    // Constant gravity value, used in the deceleration phase.\n    Scalar gravity;\n    Scalar inflexion; // Tension lines cross at (INFLEXION, 1)\n    Scalar startTension;\n    Scalar endTension;\n    Scalar physicalCoeff;\n    Scalar decelerationRate;\n\n    static constexpr size_t kNBSamples = 100;\n\n    std::array<Scalar, SplineOverScrollerConstants::kNBSamples + 1> splinePosition;\n    std::array<Scalar, SplineOverScrollerConstants::kNBSamples + 1> splineTime;\n\n    static void initialize(Scalar gravity,\n                           Scalar inflexion,\n                           Scalar startTension,\n                           Scalar endTension,\n                           Scalar physicalCoeff,\n                           Scalar decelerationRate) {\n        kInstance.doInitialize(getOrDefault(gravity, kDefaultGravity),\n                               getOrDefault(inflexion, kDefaultInflexion),\n                               getOrDefault(startTension, kDefaultStartTension),\n                               getOrDefault(endTension, kDefaultEndTension),\n                               getOrDefault(physicalCoeff, kDefaultPhysicalCoeff),\n                               getOrDefault(decelerationRate, kDefaultDecelerationRate));\n    }\n\n    static const SplineOverScrollerConstants& get() {\n        if (!kInstance._initialized) {\n            initialize(0, 0, 0, 0, 0, 0);\n        }\n\n        return kInstance;\n    }\n\nprivate:\n    bool _initialized = false;\n    static SplineOverScrollerConstants kInstance;\n\n    void doInitialize(Scalar gravity,\n                      Scalar inflexion,\n                      Scalar startTension,\n                      Scalar endTension,\n                      Scalar physicalCoeff,\n                      Scalar decelerationRate) {\n        this->gravity = gravity;\n        this->inflexion = inflexion;\n        this->startTension = startTension;\n        this->endTension = endTension;\n        this->physicalCoeff = physicalCoeff;\n        this->decelerationRate = decelerationRate;\n        _initialized = true;\n\n        auto p1 = startTension * inflexion;\n        auto p2 = 1.0f - endTension * (1.0f - inflexion);\n        Scalar xMin = 0.0f;\n        Scalar yMin = 0.0f;\n        for (size_t i = 0; i < kNBSamples; i++) {\n            Scalar alpha = static_cast<Scalar>(i) / static_cast<Scalar>(kNBSamples);\n\n            Scalar xMax = 1.0f;\n            Scalar x = 0.0f;\n            Scalar tx = 0.0f;\n            Scalar coef = 0.0f;\n            for (;;) {\n                x = xMin + (xMax - xMin) / 2.0f;\n                coef = 3.0f * x * (1.0f - x);\n                tx = coef * ((1.0f - x) * p1 + x * p2) + x * x * x;\n                if (std::abs(tx - alpha) < 1E-5) {\n                    break;\n                }\n                if (tx > alpha) {\n                    xMax = x;\n                } else {\n                    xMin = x;\n                }\n            }\n            splinePosition[i] = coef * ((1.0f - x) * startTension + x) + x * x * x;\n\n            Scalar yMax = 1.0f;\n            Scalar y = 0.0f;\n            Scalar dy = 0.0f;\n            for (;;) {\n                y = yMin + (yMax - yMin) / 2.0f;\n                coef = 3.0f * y * (1.0f - y);\n                dy = coef * ((1.0f - y) * startTension + y) + y * y * y;\n                if (std::abs(dy - alpha) < 1E-5) {\n                    break;\n                }\n                if (dy > alpha) {\n                    yMax = y;\n                } else {\n                    yMin = y;\n                }\n            }\n            splineTime[i] = coef * ((1.0f - y) * p1 + y * p2) + y * y * y;\n        }\n        splinePosition[kNBSamples] = splineTime[kNBSamples] = 1.0f;\n    }\n};\n\n// NOLINTNEXTLINE(fuchsia-statically-constructed-objects)\nSplineOverScrollerConstants SplineOverScrollerConstants::kInstance;\n\nSplineScrollPhysics::SplineScrollPhysics(Scalar scrollFriction, const Vector& velocity)\n    : _scrollFriction(scrollFriction) {\n    if (velocity.dx != 0.0f) {\n        auto decelerationX = computeDeceleration(velocity.dx);\n        _distance.dx = computeDistance(velocity.dx, decelerationX);\n        _durationX = computeDuration(decelerationX);\n    }\n\n    if (velocity.dy != 0.0f) {\n        auto decelerationY = computeDeceleration(velocity.dy);\n        _distance.dy = computeDistance(velocity.dy, decelerationY);\n        _durationY = computeDuration(decelerationY);\n    }\n}\n\nSplineScrollPhysicsResult SplineScrollPhysics::compute(Duration elapsed) const {\n    SplineScrollPhysicsResult result;\n\n    auto xFinished = doCompute(_durationX, _distance.dx, elapsed, &result.distance.dx, &result.velocity.dx);\n    auto yFinished = doCompute(_durationY, _distance.dy, elapsed, &result.distance.dy, &result.velocity.dy);\n\n    result.finished = xFinished && yFinished;\n\n    return result;\n}\n\nbool SplineScrollPhysics::doCompute(\n    Duration totalDuration, Scalar totalDistance, Duration elapsed, Scalar* outDistance, Scalar* outVelocity) {\n    if (elapsed >= totalDuration) {\n        *outDistance = totalDistance;\n        *outVelocity = 0.0f;\n        return true;\n    }\n\n    const auto& constants = SplineOverScrollerConstants::get();\n\n    auto ratio = static_cast<Scalar>(elapsed.seconds() / totalDuration.seconds());\n    auto index = static_cast<size_t>(SplineOverScrollerConstants::kNBSamples * ratio);\n    Scalar distanceCoef = 1.f;\n    Scalar velocityCoef = 0.f;\n    if (index < SplineOverScrollerConstants::kNBSamples) {\n        auto tInf = static_cast<Scalar>(index) / static_cast<Scalar>(SplineOverScrollerConstants::kNBSamples);\n        auto tSup = static_cast<Scalar>(index + 1) / static_cast<Scalar>(SplineOverScrollerConstants::kNBSamples);\n        auto dInf = constants.splinePosition[index];\n        auto dSup = constants.splinePosition[index + 1];\n        velocityCoef = (dSup - dInf) / (tSup - tInf);\n        distanceCoef = dInf + (ratio - tInf) * velocityCoef;\n    }\n\n    *outDistance = distanceCoef * totalDistance;\n    *outVelocity = velocityCoef * totalDistance / static_cast<Scalar>(totalDuration.seconds());\n\n    return false;\n}\n\nScalar SplineScrollPhysics::computeDeceleration(Scalar velocity) const {\n    const auto& constants = SplineOverScrollerConstants::get();\n    return std::log(constants.inflexion * std::abs(velocity) / (_scrollFriction * constants.physicalCoeff));\n}\n\nScalar SplineScrollPhysics::computeDistance(Scalar velocity, Scalar deceleration) const {\n    const auto& constants = SplineOverScrollerConstants::get();\n    auto decelMinusOne = constants.decelerationRate - 1.0;\n    auto absDistance =\n        _scrollFriction * constants.physicalCoeff * std::exp(constants.decelerationRate / decelMinusOne * deceleration);\n\n    return std::signbit(velocity) ? -absDistance : absDistance;\n}\n\nDuration SplineScrollPhysics::computeDuration(Scalar deceleration) {\n    auto decelMinusOne = SplineOverScrollerConstants::get().decelerationRate - 1.0;\n    return Duration::fromSeconds(std::exp(deceleration / decelMinusOne));\n}\n\nvoid SplineScrollPhysics::initialize(Scalar gravity,\n                                     Scalar inflexion,\n                                     Scalar startTension,\n                                     Scalar endTension,\n                                     Scalar physicalCoeff,\n                                     Scalar decelerationRate) {\n    SplineOverScrollerConstants::initialize(\n        gravity, inflexion, startTension, endTension, physicalCoeff, decelerationRate);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/SplineScrollPhysics.hpp",
    "content": "//\n//  SplineScrollPhysics.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 11/22/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Duration.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\nnamespace snap::drawing {\n\nstruct SplineScrollPhysicsResult {\n    Vector distance;\n    Vector velocity;\n    bool finished = false;\n};\n\nclass SplineScrollPhysics {\npublic:\n    SplineScrollPhysics(Scalar scrollFriction, const Vector& velocity);\n\n    SplineScrollPhysicsResult compute(Duration elapsed) const;\n\n    static void initialize(Scalar gravity,\n                           Scalar inflexion,\n                           Scalar startTension,\n                           Scalar endTension,\n                           Scalar physicalCoeff,\n                           Scalar decelerationRate);\n\nprivate:\n    Scalar _scrollFriction;\n    Vector _distance;\n    Duration _durationX;\n    Duration _durationY;\n\n    Scalar computeDeceleration(Scalar velocity) const;\n    Scalar computeDistance(Scalar velocity, Scalar deceleration) const;\n    static Duration computeDuration(Scalar deceleration);\n\n    static bool doCompute(\n        Duration totalDuration, Scalar totalDistance, Duration elapsed, Scalar* outDistance, Scalar* outVelocity);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/SpringFlingScrollLayerAnimation.cpp",
    "content": "//\n//  SpringFlingScrollLayerAnimation.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/28/22.\n//\n\n#include \"snap_drawing/cpp/Layers/Scroll/SpringFlingScrollLayerAnimation.hpp\"\n\nnamespace snap::drawing {\n\nSpringFlingScrollLayerAnimation::SpringFlingScrollLayerAnimation() = default;\nSpringFlingScrollLayerAnimation::~SpringFlingScrollLayerAnimation() = default;\n\nbool SpringFlingScrollLayerAnimation::update(ScrollLayer& scrollLayer, Duration delta) {\n    _elapsed += delta;\n\n    if (_springScrollPhysics) {\n        return onBounce(scrollLayer);\n    } else {\n        return onDecelerate(scrollLayer, _elapsed);\n    }\n}\n\nbool SpringFlingScrollLayerAnimation::startBouncing(\n    ScrollLayer& scrollLayer,\n    const Vector& velocity,\n    const Point& sourceContentOffset,\n    const Point& targetContentOffset,\n    const Duration& startTime,\n    const SpringScrollPhysicsConfiguration* scrollPhysicsConfiguration) {\n    _targetContentOffset = targetContentOffset;\n\n    auto displacement =\n        Vector::make(sourceContentOffset.x - targetContentOffset.x, sourceContentOffset.y - targetContentOffset.y);\n    _elapsed = startTime;\n    _springScrollPhysics = {SpringScrollPhysics(scrollPhysicsConfiguration, velocity, displacement)};\n\n    return onBounce(scrollLayer);\n}\n\nbool SpringFlingScrollLayerAnimation::onBounce(ScrollLayer& scrollLayer) {\n    auto& springScrollPhysics = _springScrollPhysics.value();\n\n    auto result = springScrollPhysics.compute(_elapsed);\n\n    updateCarriedVelocity(result.velocity);\n\n    auto adjustment = applyContentOffset(\n        scrollLayer,\n        Point::make(_targetContentOffset.x + result.distance.dx, _targetContentOffset.y + result.distance.dy));\n    _targetContentOffset.x += adjustment.dx;\n    _targetContentOffset.y += adjustment.dy;\n\n    return result.finished;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/SpringFlingScrollLayerAnimation.hpp",
    "content": "//\n//  SpringFlingScrollLayerAnimation.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/28/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Scroll/BaseScrollLayerAnimation.hpp\"\n#include \"snap_drawing/cpp/Layers/Scroll/SpringScrollPhysics.hpp\"\n\n#include <optional>\n\nnamespace snap::drawing {\n\nclass SpringFlingScrollLayerAnimation : public BaseScrollLayerAnimation {\npublic:\n    SpringFlingScrollLayerAnimation();\n    ~SpringFlingScrollLayerAnimation() override;\n\nprotected:\n    bool update(ScrollLayer& scrollLayer, Duration delta) final;\n\n    virtual bool onDecelerate(ScrollLayer& scrollLayer, Duration elapsed) = 0;\n    virtual void updateCarriedVelocity(const Vector& velocity) = 0;\n\n    bool startBouncing(ScrollLayer& scrollLayer,\n                       const Vector& velocity,\n                       const Point& sourceContentOffset,\n                       const Point& targetContentOffset,\n                       const Duration& startTime,\n                       const SpringScrollPhysicsConfiguration* scrollPhysicsConfiguration);\n\nprivate:\n    Duration _elapsed;\n    std::optional<SpringScrollPhysics> _springScrollPhysics;\n    Point _targetContentOffset;\n\n    bool onBounce(ScrollLayer& scrollLayer);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/SpringScrollPhysics.cpp",
    "content": "//\n//  SpringScrollPhysics.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/23/22.\n//\n\n#include \"snap_drawing/cpp/Layers/Scroll/SpringScrollPhysics.hpp\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nconstexpr Scalar kThreshold = 0.5;\nconstexpr Duration kVelocityComputationDuration(0.01);\nconstexpr Scalar kMinOverScrollVelocity = kMinScrollVelocity;\nconstexpr Scalar kMaxOverscrollVelocity = 3500;\n\nstatic Scalar computeClampedVelocity(Scalar velocity, Scalar displacement) {\n    if (velocity == 0.0f && displacement == 0.0f) {\n        return 0.0f;\n    }\n\n    auto sign = std::signbit(velocity) ? -1 : 1;\n    return sign * std::clamp(std::abs(velocity), kMinOverScrollVelocity, kMaxOverscrollVelocity);\n}\n\nSpringScrollPhysicsConfiguration SpringScrollPhysicsConfiguration::make(Scalar springMass,\n                                                                        Scalar springStiffness,\n                                                                        Scalar springDampingRatio) {\n    auto naturalFrequency = std::sqrt(springStiffness / springMass) * std::sqrt(1.0f - std::pow(springDampingRatio, 2));\n    auto damping = 2.0f * springDampingRatio * std::sqrt(springMass * springStiffness);\n    auto beta = damping / (2.0f * springMass);\n\n    return SpringScrollPhysicsConfiguration(naturalFrequency, damping, beta);\n}\n\nSpringScrollPhysics::SpringScrollPhysics(const SpringScrollPhysicsConfiguration* configuration,\n                                         const Vector& velocity,\n                                         const Vector& displacement)\n    : _configuration(configuration),\n      _velocity(computeClampedVelocity(velocity.dx, displacement.dx),\n                computeClampedVelocity(velocity.dy, displacement.dy)),\n      _displacement(displacement) {\n    auto springReferenceX =\n        (_velocity.dx + configuration->getBeta() * displacement.dx) / configuration->getNaturalFrequency();\n    auto springReferenceY =\n        (_velocity.dy + configuration->getBeta() * displacement.dy) / configuration->getNaturalFrequency();\n    _springReference = Vector::make(springReferenceX, springReferenceY);\n\n    auto displacementLength = Point::length(displacement.dx, displacement.dy);\n    auto velocityLength = Point::length(_velocity.dx, _velocity.dy);\n\n    if (displacementLength != 0 || velocityLength != 0) {\n        auto referenceLength = Point::length(_springReference.dx, _springReference.dy);\n\n        _duration = Duration::fromSeconds(std::log((displacementLength + referenceLength) / kThreshold) /\n                                          configuration->getBeta());\n    }\n}\n\nSpringScrollPhysicsResult SpringScrollPhysics::compute(Duration elapsed) const {\n    SpringScrollPhysicsResult result;\n\n    if (elapsed < _duration) {\n        result.finished = false;\n        result.distance = computeDistance(elapsed);\n\n        if (elapsed > kVelocityComputationDuration) {\n            auto lastDistance = computeDistance(elapsed - kVelocityComputationDuration);\n            result.velocity.dx = (result.distance.dx - lastDistance.dx) / kVelocityComputationDuration.seconds();\n            result.velocity.dy = (result.distance.dy - lastDistance.dy) / kVelocityComputationDuration.seconds();\n        } else {\n            result.velocity = _velocity;\n        }\n    } else {\n        result.finished = true;\n    }\n\n    return result;\n}\n\nVector SpringScrollPhysics::computeDistance(Duration elapsed) const {\n    auto time = elapsed.seconds();\n    auto wd = _configuration->getNaturalFrequency() * time;\n    auto factor1 = std::exp(-_configuration->getBeta() * time);\n    auto factor2 = std::cos(wd);\n    auto factor3 = std::sin(wd);\n    auto bounceOffsetX = factor1 * (_displacement.dx * factor2 + _springReference.dx * factor3);\n    auto bounceOffsetY = factor1 * (_displacement.dy * factor2 + _springReference.dy * factor3);\n    return Vector::make(bounceOffsetX, bounceOffsetY);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/Scroll/SpringScrollPhysics.hpp",
    "content": "//\n//  SpringScrollPhysics.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/23/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Duration.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\nnamespace snap::drawing {\n\nclass SpringScrollPhysicsConfiguration {\npublic:\n    constexpr SpringScrollPhysicsConfiguration(Scalar naturalFrequency, Scalar damping, Scalar beta)\n        : _naturalFrequency(naturalFrequency), _damping(damping), _beta(beta) {}\n\n    constexpr Scalar getNaturalFrequency() const {\n        return _naturalFrequency;\n    }\n\n    constexpr Scalar getDamping() const {\n        return _damping;\n    }\n\n    constexpr Scalar getBeta() const {\n        return _beta;\n    }\n\n    static SpringScrollPhysicsConfiguration make(Scalar springMass, Scalar springStiffness, Scalar springDampingRatio);\n\nprivate:\n    Scalar _naturalFrequency = 0.0f;\n    Scalar _damping = 0.0f;\n    Scalar _beta = 0.0f;\n};\n\nstruct SpringScrollPhysicsResult {\n    Vector distance;\n    Vector velocity;\n    bool finished = false;\n};\n\nconstexpr Scalar kMinScrollVelocity = 15;\n\nclass SpringScrollPhysics {\npublic:\n    SpringScrollPhysics(const SpringScrollPhysicsConfiguration* configuration,\n                        const Vector& velocity,\n                        const Vector& displacement);\n\n    SpringScrollPhysicsResult compute(Duration elapsed) const;\n\n    const Duration& getDuration() const {\n        return _duration;\n    }\n\nprivate:\n    const SpringScrollPhysicsConfiguration* _configuration;\n    Vector _velocity;\n    Vector _displacement;\n    Vector _springReference;\n    Duration _duration;\n\n    Vector computeDistance(Duration elapsed) const;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ScrollLayer.cpp",
    "content": "//\n//  ScrollLayer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#include \"snap_drawing/cpp/Layers/ScrollLayer.hpp\"\n\n#include \"valdi_core/cpp/Utils/Marshaller.hpp\"\n#include \"valdi_core/cpp/Utils/ValueFunction.hpp\"\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n#include \"snap_drawing/cpp/Animations/ValueInterpolators.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n\n#include \"snap_drawing/cpp/Layers/Scroll/IScroller.hpp\"\n\nnamespace snap::drawing {\n\nVALDI_CLASS_IMPL(ScrollPerfLogger);\n\nconstexpr Scalar kRubberBandCoefficient = 0.55;\n\nString& ScrollLayer::getScrollAnimationKey() {\n    static auto kScrollAnimationKey = STRING_LITERAL(\"scrollAnimation\");\n    return kScrollAnimationKey;\n}\n\nScrollLayer::ScrollLayer(const Ref<Resources>& resources) : Layer(resources) {}\n\nScrollLayer::~ScrollLayer() = default;\n\nvoid ScrollLayer::onInitialize() {\n    Layer::onInitialize();\n    _contentLayer = makeLayer<Layer>(getResources());\n\n    addChild(_contentLayer);\n\n    _scrollGestureRecognizer = Valdi::makeShared<ScrollGestureRecognizer>(getResources()->getGesturesConfiguration());\n    _scrollGestureRecognizer->setListener(\n        [=](const auto& /*gesture*/, auto state, const auto& event) { this->onScrollDrag(state, event); });\n    addGestureRecognizer(_scrollGestureRecognizer);\n\n    _wheelGestureRecognizer = Valdi::makeShared<WheelGestureRecognizer>(\n        [=](const auto& /*gesture*/, auto state, const auto& wheelEvent) { this->onScrollWheel(state, wheelEvent); });\n    addGestureRecognizer(_wheelGestureRecognizer);\n\n    setClipsToBounds(getClipsToBoundsDefaultValue());\n    _scrollGestureRecognizer->setHorizontal(_horizontal);\n    setCancelsOtherGesturesOnScroll(true);\n}\n\nvoid ScrollLayer::setContentOffset(Point contentOffset, const Vector& velocity, bool animated) {\n    if (_contentOffset == contentOffset) {\n        return;\n    }\n\n    cancelScrollAnimation();\n\n    if (animated && _scroller != nullptr) {\n        auto fast = true;\n        auto initialOffset = _contentOffset;\n        auto finalOffset = contentOffset;\n\n        auto scrollAnimation = _scroller->animate(initialOffset, finalOffset, fast);\n        addAnimation(getScrollAnimationKey(), scrollAnimation);\n        _scrollGestureRecognizer->setAnimatingScroll(true);\n    } else {\n        applyContentOffset(contentOffset.x, contentOffset.y, velocity);\n    }\n}\n\nvoid ScrollLayer::setContentSize(Size size) {\n    _contentSize = size;\n\n    updateContentLayerFrame();\n\n    auto currentOffsetX = _contentOffset.x;\n    auto currentOffsetY = _contentOffset.y;\n    auto clampedOffsetX = clampContentOffsetX(currentOffsetX);\n    auto clampedOffsetY = clampContentOffsetY(currentOffsetY);\n    if (currentOffsetX != clampedOffsetX || currentOffsetY != clampedOffsetY) {\n        setContentOffset(Point::make(clampedOffsetX, clampedOffsetY), Vector(0, 0), false);\n    }\n}\n\nVector ScrollLayer::applyContentOffset(Scalar offsetX, Scalar offsetY, Vector velocity) {\n    Vector adjustment = Vector::makeEmpty();\n    auto newOffsetX = offsetX;\n    auto newOffsetY = offsetY;\n\n    if (_listener != nullptr) {\n        auto updatedOffset = _listener->onScroll(*this, Point::make(offsetX, offsetY), velocity);\n        if (updatedOffset) {\n            newOffsetX = updatedOffset.value().x;\n            newOffsetY = updatedOffset.value().y;\n\n            adjustment.dx = newOffsetX - offsetX;\n            adjustment.dy = newOffsetY - offsetY;\n            _scrollGestureOffset.x += adjustment.dx;\n            _scrollGestureOffset.y += adjustment.dy;\n        }\n    }\n\n    applyContentOffsetInternal(newOffsetX, newOffsetY);\n\n    return adjustment;\n}\n\nvoid ScrollLayer::applyContentOffsetInternal(Scalar offsetX, Scalar offsetY) {\n    _contentOffset.x = offsetX;\n    _contentOffset.y = offsetY;\n\n    updateContentLayerFrame();\n    updateEdgeGradient();\n}\n\nvoid ScrollLayer::onBoundsChanged() {\n    updateContentLayerFrame();\n    updateEdgeGradient();\n}\n\nvoid ScrollLayer::updateContentLayerFrame() {\n    _contentLayer->setFrame(\n        Rect::makeXYWH(-_contentOffset.x, -_contentOffset.y, _contentSize.width, _contentSize.height));\n}\n\nScalar ScrollLayer::clampContentOffsetX(Scalar contentOffsetX) const {\n    return std::clamp(contentOffsetX, getMinContentOffsetX(), getMaxContentOffsetX());\n}\n\nScalar ScrollLayer::clampContentOffsetY(Scalar contentOffsetY) const {\n    return std::clamp(contentOffsetY, getMinContentOffsetY(), getMaxContentOffsetY());\n}\n\nvoid ScrollLayer::cancelScrollAnimation() {\n    auto animation = getAnimation(getScrollAnimationKey());\n    if (animation != nullptr) {\n        removeAnimation(getScrollAnimationKey());\n    }\n}\n\nvoid ScrollLayer::onRootChanged(ILayerRoot* root) {\n    Layer::onRootChanged(root);\n\n    if (root == nullptr) {\n        cancelScrollAnimation();\n        if (_scroller != nullptr) {\n            _scroller->reset();\n        }\n    }\n}\n\nvoid ScrollLayer::onScrollDrag(GestureRecognizerState state, const DragEvent& event) {\n    cancelScrollAnimation();\n\n    if (state == GestureRecognizerStateBegan) {\n        _scrollGestureOffset = _contentOffset;\n    }\n\n    if (_scroller != nullptr) {\n        _scroller->onDrag(state, event);\n    }\n\n    auto dragVelocity = Vector::make(_horizontal ? event.velocity.dx : 0.0f, !_horizontal ? event.velocity.dy : 0.0f);\n    auto targetOffset = targetOffsetForInteractiveOffset(\n        Point(_scrollGestureOffset.x - event.offset.width, _scrollGestureOffset.y - event.offset.height));\n\n    if (state == GestureRecognizerStateBegan) {\n        resumeScrollPerfLogger();\n        if (_dismissKeyboardOnDrag) {\n            requestFocus(this);\n        }\n        if (_listener != nullptr) {\n            _listener->onDragStart(*this, _contentOffset, dragVelocity);\n        }\n    } else if (state == GestureRecognizerStateEnded) {\n        onScrollEnded(targetOffset, dragVelocity);\n    } else {\n        setContentOffset(targetOffset, dragVelocity, false);\n    }\n}\n\nvoid ScrollLayer::onScrollWheel(GestureRecognizerState /*state*/, const WheelScrollEvent& scrollEvent) {\n    auto desiredContentOffset = getContentOffset().makeOffset(scrollEvent.direction.dx, scrollEvent.direction.dy);\n    auto finalContentOffset = targetOffsetForInteractiveOffset(desiredContentOffset);\n    onScrollEnded(finalContentOffset, scrollEvent.direction);\n}\n\nPoint ScrollLayer::targetOffsetForInteractiveOffset(const Point& interactiveOffset) {\n    Scalar targetOffsetX = interactiveOffset.x;\n    Scalar targetOffsetY = interactiveOffset.y;\n\n    Scalar clampedOffsetX = clampContentOffsetX(targetOffsetX);\n    Scalar clampedOffsetY = clampContentOffsetY(targetOffsetY);\n\n    if (!_horizontal) {\n        targetOffsetX = clampedOffsetX;\n    } else {\n        targetOffsetY = clampedOffsetY;\n    }\n    if (!_bounces) {\n        if (!_bouncesHorizontalWithSmallContent) {\n            targetOffsetX = clampedOffsetX;\n        }\n        if (!_bouncesVerticalWithSmallContent) {\n            targetOffsetY = clampedOffsetY;\n        }\n    }\n    if (targetOffsetX != clampedOffsetX) {\n        Scalar frameWidth = getFrame().width();\n        targetOffsetX = computeRubberBand(targetOffsetX, clampedOffsetX, frameWidth);\n    }\n    if (targetOffsetY != clampedOffsetY) {\n        Scalar frameHeight = getFrame().height();\n        targetOffsetY = computeRubberBand(targetOffsetY, clampedOffsetY, frameHeight);\n    }\n\n    return Point::make(targetOffsetX, targetOffsetY);\n}\n\nstd::optional<Point> ScrollLayer::computePaginatedTargetContentOffset(const Point& contentOffset,\n                                                                      const std::optional<Point>& contentOffsetOverride,\n                                                                      const Vector& velocity) const {\n    if (_scroller == nullptr) {\n        return contentOffsetOverride;\n    }\n\n    Scalar frameWidth = getFrame().width();\n    Scalar frameHeight = getFrame().height();\n    auto minOffsetX = std::max<Scalar>(0, floor(_contentOffset.x / frameWidth) * frameWidth);\n    auto maxOffsetX =\n        std::min<Scalar>(_contentSize.width - frameWidth, ceil(_contentOffset.x / frameWidth) * frameWidth);\n    auto minOffsetY = std::max<Scalar>(0, floor(_contentOffset.y / frameHeight) * frameHeight);\n    auto maxOffsetY =\n        std::min<Scalar>(_contentSize.height - frameHeight, ceil(_contentOffset.y / frameHeight) * frameHeight);\n\n    Point finalOffset;\n    if (contentOffsetOverride) {\n        finalOffset = contentOffsetOverride.value();\n    } else {\n        finalOffset =\n            _scroller->computeDecelerationFinalOffset(contentOffset, velocity, Size(frameWidth, frameHeight), true);\n    }\n\n    auto paginatedFinalOffsetX = std::clamp(round(finalOffset.x / frameWidth) * frameWidth, minOffsetX, maxOffsetX);\n    auto paginatedFinalOffsetY = std::clamp(round(finalOffset.y / frameHeight) * frameHeight, minOffsetY, maxOffsetY);\n    return Point::make(paginatedFinalOffsetX, paginatedFinalOffsetY);\n}\n\nvoid ScrollLayer::onScrollEnded(const Point& contentOffset, const Vector& velocity) {\n    std::optional<Point> targetContentOffsetOverride;\n    if (_listener != nullptr) {\n        targetContentOffsetOverride = _listener->onDragEnding(*this, contentOffset, velocity);\n    }\n\n    if (_pagingEnabled) {\n        targetContentOffsetOverride =\n            computePaginatedTargetContentOffset(contentOffset, targetContentOffsetOverride, velocity);\n    }\n\n    if (targetContentOffsetOverride) {\n        setContentOffset(targetContentOffsetOverride.value(), velocity, true);\n    } else {\n        setContentOffset(contentOffset, velocity, false);\n\n        if (_scroller != nullptr) {\n            _scrollGestureRecognizer->setAnimatingScroll(true);\n\n            auto animation = _scroller->fling(contentOffset, velocity, false);\n            addAnimation(getScrollAnimationKey(), animation);\n        }\n    }\n}\n\nScalar ScrollLayer::computeRubberBand(Scalar value, Scalar clamped, Scalar dim) {\n    auto coef = kRubberBandCoefficient;\n    auto diff = std::abs(value - clamped);\n    auto sign = clamped > value ? -1 : 1;\n    auto rubber = (1.0 - (1.0 / (diff * coef / dim + 1.0))) * dim;\n    return clamped + sign * rubber;\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nScalar ScrollLayer::getMinContentOffsetX() const {\n    return 0;\n}\n\nScalar ScrollLayer::getMaxContentOffsetX() const {\n    return _horizontal ? std::max(_contentSize.width - getFrame().width(), 0.0f) : 0;\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nScalar ScrollLayer::getMinContentOffsetY() const {\n    return 0;\n}\n\nScalar ScrollLayer::getMaxContentOffsetY() const {\n    return _horizontal ? 0 : std::max(_contentSize.height - getFrame().height(), 0.0f);\n}\n\nconst Point& ScrollLayer::getContentOffset() const {\n    return _contentOffset;\n}\n\nconst Ref<Layer>& ScrollLayer::getContentLayer() const {\n    return _contentLayer;\n}\n\nbool ScrollLayer::getClipsToBoundsDefaultValue() const {\n    return true;\n}\n\nvoid ScrollLayer::setHorizontal(bool horizontal) {\n    _horizontal = horizontal;\n    _scrollGestureRecognizer->setHorizontal(horizontal);\n    updateEdgeGradient();\n}\n\nvoid ScrollLayer::setBounces(bool bounces) {\n    _bounces = bounces;\n}\n\nvoid ScrollLayer::setBouncesVerticalWithSmallContent(bool bouncesVerticalWithSmallContent) {\n    _bouncesVerticalWithSmallContent = bouncesVerticalWithSmallContent;\n}\n\nvoid ScrollLayer::setBouncesHorizontalWithSmallContent(bool bouncesHorizontalWithSmallContent) {\n    _bouncesHorizontalWithSmallContent = bouncesHorizontalWithSmallContent;\n}\n\nvoid ScrollLayer::setPagingEnabled(bool pagingEnabled) {\n    _pagingEnabled = pagingEnabled;\n}\n\nvoid ScrollLayer::setDismissKeyboardOnDrag(bool dismissKeyboardOnDrag) {\n    _dismissKeyboardOnDrag = dismissKeyboardOnDrag;\n}\n\nvoid ScrollLayer::setFadingEdgeLength(Scalar length) {\n    if (length == _fadingEdgeLength) {\n        return;\n    }\n    _fadingEdgeLength = length;\n    if (length <= 0) {\n        _fadingEdgesMaskLayer = nullptr;\n        setMaskLayer(nullptr);\n        return;\n    }\n    if (_fadingEdgesMaskLayer == nullptr) {\n        _fadingEdgesMaskLayer = Valdi::makeShared<ScrollLayerFadingEdgesMaskLayer>();\n        updateEdgeGradient();\n        setMaskLayer(_fadingEdgesMaskLayer);\n    } else {\n        updateEdgeGradient();\n        setNeedsDisplay();\n    }\n}\n\nvoid ScrollLayer::setFadingEdgeStart(bool enabled) {\n    if (_fadingEdgeStartEnabled == enabled) {\n        return;\n    }\n    _fadingEdgeStartEnabled = enabled;\n    updateEdgeGradient();\n}\n\nvoid ScrollLayer::setFadingEdgeEnd(bool enabled) {\n    if (_fadingEdgeEndEnabled == enabled) {\n        return;\n    }\n    _fadingEdgeEndEnabled = enabled;\n    updateEdgeGradient();\n}\n\nvoid ScrollLayer::updateEdgeGradient() {\n    if (_fadingEdgeLength <= 0) {\n        return;\n    }\n    auto offset = getContentOffset();\n    auto frame = getFrame();\n    auto bounds = Rect::makeXYWH(0, 0, frame.width(), frame.height());\n    if (_horizontal) {\n        auto leadingEdgeLength = _fadingEdgeStartEnabled ? std::clamp<Scalar>(offset.x, 0, _fadingEdgeLength) : 0;\n        auto trailingEdgeLength =\n            _fadingEdgeEndEnabled ?\n                std::clamp<Scalar>(_contentSize.width - bounds.width() - offset.x, 0, _fadingEdgeLength) :\n                0;\n        _fadingEdgesMaskLayer->configure(_horizontal, bounds, leadingEdgeLength, trailingEdgeLength);\n    } else {\n        auto leadingEdgeLength = _fadingEdgeStartEnabled ? std::clamp<Scalar>(offset.y, 0, _fadingEdgeLength) : 0;\n        auto trailingEdgeLength =\n            _fadingEdgeEndEnabled ?\n                std::clamp<Scalar>(_contentSize.height - bounds.height() - offset.y, 0, _fadingEdgeLength) :\n                0;\n        _fadingEdgesMaskLayer->configure(_horizontal, bounds, leadingEdgeLength, trailingEdgeLength);\n    }\n}\n\nbool ScrollLayer::prepareForReuse() {\n    auto shouldReuse = Layer::prepareForReuse();\n    cancelScrollAnimation();\n    if (_scroller != nullptr) {\n        _scroller->reset();\n    }\n    applyContentOffsetInternal(0, 0);\n    pauseScrollPerfLogger();\n    return shouldReuse;\n}\n\nvoid ScrollLayer::onScrollAnimationEnded() {\n    _scrollGestureRecognizer->setAnimatingScroll(false);\n    if (_listener != nullptr) {\n        _listener->onScrollEnd(*this, _contentOffset);\n    }\n    pauseScrollPerfLogger();\n}\n\nvoid ScrollLayer::resumeScrollPerfLogger() {\n    if (!_scrollPerfLoggerStarted) {\n        _scrollPerfLoggerStarted = true;\n        if (_scrollPerfLogger != nullptr) {\n            _scrollPerfLogger->resume();\n        }\n    }\n}\n\nvoid ScrollLayer::pauseScrollPerfLogger() {\n    if (_scrollPerfLoggerStarted) {\n        _scrollPerfLoggerStarted = false;\n        if (_scrollPerfLogger != nullptr) {\n            _scrollPerfLogger->pause(false);\n        }\n    }\n}\n\nvoid ScrollLayer::setCancelsOtherGesturesOnScroll(bool cancelsTouchesOnScroll) {\n    _scrollGestureRecognizer->setShouldCancelOtherGesturesOnStart(cancelsTouchesOnScroll);\n}\n\nvoid ScrollLayer::setListener(const Ref<ScrollLayerListener>& listener) {\n    _listener = listener;\n}\n\nconst Ref<ScrollLayerListener>& ScrollLayer::getListener() const {\n    return _listener;\n}\n\nvoid ScrollLayer::setScrollPerfLogger(const Ref<ScrollPerfLogger>& scrollPerfLogger) {\n    if (_scrollPerfLogger != scrollPerfLogger) {\n        pauseScrollPerfLogger();\n        _scrollPerfLogger = scrollPerfLogger;\n    }\n}\n\nconst Ref<ScrollPerfLogger>& ScrollLayer::getScrollPerfLogger() const {\n    return _scrollPerfLogger;\n}\n\nvoid ScrollLayer::setScroller(const Ref<IScroller>& scroller) {\n    _scroller = scroller;\n}\n\nconst Ref<IScroller>& ScrollLayer::getScroller() const {\n    return _scroller;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ScrollLayer.hpp",
    "content": "//\n//  ScrollLayer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Layers/Mask/ScrollLayerFadingEdgesMaskLayer.hpp\"\n#include \"snap_drawing/cpp/Touches/ScrollGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/WheelGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Utils/VelocityTracker.hpp\"\n\n#include \"valdi_core/cpp/Utils/ValueFunction.hpp\"\n\nnamespace snap::drawing {\n\nclass ScrollLayerClass;\nclass ScrollLayerFixture;\nclass ScrollLayer;\nclass IScroller;\n\nclass ScrollLayerListener : public Valdi::SimpleRefCountable {\npublic:\n    virtual std::optional<Point> onScroll(const ScrollLayer& scrollLayer,\n                                          const Point& point,\n                                          const Vector& velocity) = 0;\n\n    virtual void onScrollEnd(const ScrollLayer& scrollLayer, const Point& point) = 0;\n\n    virtual void onDragStart(const ScrollLayer& scrollLayer, const Point& point, const Vector& velocity) = 0;\n\n    virtual std::optional<Point> onDragEnding(const ScrollLayer& scrollLayer,\n                                              const Point& point,\n                                              const Vector& velocity) = 0;\n};\n\nclass ScrollPerfLogger : public Valdi::ValdiObject {\npublic:\n    virtual void resume() = 0;\n    virtual void pause(bool cancelLogging) = 0;\n\n    VALDI_CLASS_HEADER(ScrollPerfLogger)\n};\n\nclass BaseScrollLayerAnimation;\n\nclass ScrollLayer : public Layer {\npublic:\n    explicit ScrollLayer(const Ref<Resources>& resources);\n    ~ScrollLayer() override;\n\n    void onInitialize() override;\n\n    void setContentOffset(Point contentOffset, const Vector& velocity, bool animated);\n    void setContentSize(Size size);\n\n    const Ref<Layer>& getContentLayer() const;\n\n    bool prepareForReuse() override;\n\n    const Point& getContentOffset() const;\n\n    void setHorizontal(bool horizontal);\n\n    void setCancelsOtherGesturesOnScroll(bool cancelsTouchesOnScroll);\n\n    void setBounces(bool bounces);\n    void setBouncesVerticalWithSmallContent(bool bouncesVerticalWithSmallContent);\n    void setBouncesHorizontalWithSmallContent(bool bouncesHorizontalWithSmallContent);\n\n    void setDismissKeyboardOnDrag(bool dismissKeyboardOnDrag);\n\n    void setFadingEdgeLength(Scalar length);\n    void setFadingEdgeStart(bool enabled);\n    void setFadingEdgeEnd(bool enabled);\n\n    void setPagingEnabled(bool pagingEnabled);\n\n    bool getClipsToBoundsDefaultValue() const override;\n\n    void setListener(const Ref<ScrollLayerListener>& listener);\n    const Ref<ScrollLayerListener>& getListener() const;\n\n    void setScrollPerfLogger(const Ref<ScrollPerfLogger>& scrollPerfLogger);\n    const Ref<ScrollPerfLogger>& getScrollPerfLogger() const;\n\n    /**\n     Set a Scroller instance which will be responsible for calculating the scroll physics.\n     */\n    void setScroller(const Ref<IScroller>& scroller);\n    const Ref<IScroller>& getScroller() const;\n\nprotected:\n    void onBoundsChanged() override;\n    void onRootChanged(ILayerRoot* root) override;\n\nprivate:\n    friend ScrollLayerClass;\n    friend ScrollLayerFixture;\n    friend BaseScrollLayerAnimation;\n\n    Ref<Layer> _contentLayer;\n\n    Point _contentOffset = Point::makeEmpty();\n    Size _contentSize = Size::makeEmpty();\n\n    Point _scrollGestureOffset = Point::makeEmpty();\n\n    bool _horizontal = false;\n    bool _bounces = true;\n    bool _bouncesVerticalWithSmallContent = false;\n    bool _bouncesHorizontalWithSmallContent = false;\n    bool _pagingEnabled = false;\n    bool _scrollPerfLoggerStarted = false;\n    bool _dismissKeyboardOnDrag = false;\n\n    Ref<ScrollGestureRecognizer> _scrollGestureRecognizer;\n    Ref<WheelGestureRecognizer> _wheelGestureRecognizer;\n    Ref<ScrollLayerListener> _listener;\n    Ref<ScrollPerfLogger> _scrollPerfLogger;\n    Ref<IScroller> _scroller;\n\n    Ref<ScrollLayerFadingEdgesMaskLayer> _fadingEdgesMaskLayer;\n    Scalar _fadingEdgeLength = 0;\n    bool _fadingEdgeStartEnabled = true;\n    bool _fadingEdgeEndEnabled = true;\n\n    Scalar getMinContentOffsetX() const;\n    Scalar getMinContentOffsetY() const;\n    Scalar getMaxContentOffsetX() const;\n    Scalar getMaxContentOffsetY() const;\n\n    Scalar clampContentOffsetX(Scalar contentOffsetX) const;\n    Scalar clampContentOffsetY(Scalar contentOffsetY) const;\n\n    Vector applyContentOffset(Scalar offsetX, Scalar offsetY, Vector velocity);\n    void applyContentOffsetInternal(Scalar offsetX, Scalar offsetY);\n\n    std::optional<Point> computePaginatedTargetContentOffset(const Point& contentOffset,\n                                                             const std::optional<Point>& contentOffsetOverride,\n                                                             const Vector& velocity) const;\n\n    void cancelScrollAnimation();\n\n    void onScrollAnimationEnded();\n\n    void updateContentLayerFrame();\n    void updateEdgeGradient();\n\n    void onScrollDrag(GestureRecognizerState state, const DragEvent& event);\n    void onScrollWheel(GestureRecognizerState state, const WheelScrollEvent& scrollEvent);\n\n    Point targetOffsetForInteractiveOffset(const Point& interactiveOffset);\n    void onScrollEnded(const Point& contentOffset, const Vector& velocity);\n\n    void resumeScrollPerfLogger();\n    void pauseScrollPerfLogger();\n\n    static Scalar computeRubberBand(Scalar value, Scalar clamped, Scalar dim);\n\n    // For Testing Only\n    static String& getScrollAnimationKey();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ShapeLayer.cpp",
    "content": "//\n//  ShapeLayer.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 3/4/22.\n//\n\n#include \"snap_drawing/cpp/Layers/ShapeLayer.hpp\"\n#include \"snap_drawing/cpp/Utils/PathInterpolator.hpp\"\n\nnamespace snap::drawing {\n\nShapeLayer::ShapeLayer(const Ref<Resources>& resources) : Layer(resources) {}\nShapeLayer::~ShapeLayer() = default;\n\nvoid ShapeLayer::onInitialize() {\n    _strokePaint.setAntiAlias(true);\n    _strokePaint.setStroke(true);\n    _fillPaint.setAntiAlias(true);\n    _fillPaint.setStroke(false);\n\n    setStrokeCap(PaintStrokeCapButt);\n    setStrokeJoin(PaintStrokeJoinMiter);\n    setFillColor(Color::transparent());\n    setStrokeColor(Color::transparent());\n    setStrokeWidth(1);\n}\n\nvoid ShapeLayer::onDraw(DrawingContext& drawingContext) {\n    const auto& path = getActivePath();\n    drawingContext.drawPaint(_fillPaint, path);\n    drawingContext.drawPaint(_strokePaint, path);\n}\n\nconst Path& ShapeLayer::getActivePath() {\n    if (_strokeStart == 0.0f && _strokeEnd == 1.0f) {\n        return _path;\n    }\n\n    if (!_pathInterpolator) {\n        _pathInterpolator.emplace(_path);\n    }\n\n    return _pathInterpolator.value().interpolate(_strokeStart, _strokeEnd);\n}\n\nvoid ShapeLayer::setPath(Path&& path) {\n    _path = std::move(path);\n    _pathInterpolator = std::nullopt;\n    setNeedsDisplay();\n}\n\nScalar ShapeLayer::getStrokeWidth() const {\n    return _strokePaint.getStrokeWidth();\n}\n\nvoid ShapeLayer::setStrokeWidth(Scalar strokeWidth) {\n    _strokePaint.setStrokeWidth(strokeWidth);\n    setNeedsDisplay();\n}\n\nColor ShapeLayer::getStrokeColor() const {\n    return _strokePaint.getColor();\n}\n\nvoid ShapeLayer::setStrokeColor(Color strokeColor) {\n    _strokePaint.setColor(strokeColor);\n    setNeedsDisplay();\n}\n\nColor ShapeLayer::getFillColor() const {\n    return _fillPaint.getColor();\n}\n\nvoid ShapeLayer::setFillColor(Color fillColor) {\n    _fillPaint.setColor(fillColor);\n    setNeedsDisplay();\n}\n\nvoid ShapeLayer::setStrokeCap(PaintStrokeCap strokeCap) {\n    _strokePaint.setStrokeCap(strokeCap);\n    setNeedsDisplay();\n}\n\nvoid ShapeLayer::setStrokeJoin(PaintStrokeJoin strokeJoin) {\n    _strokePaint.setStrokeJoin(strokeJoin);\n    setNeedsDisplay();\n}\n\nScalar ShapeLayer::getStrokeStart() const {\n    return _strokeStart;\n}\n\nvoid ShapeLayer::setStrokeStart(Scalar strokeStart) {\n    if (_strokeStart != strokeStart) {\n        _strokeStart = strokeStart;\n        setNeedsDisplay();\n    }\n}\n\nScalar ShapeLayer::getStrokeEnd() const {\n    return _strokeEnd;\n}\n\nvoid ShapeLayer::setStrokeEnd(Scalar strokeEnd) {\n    if (_strokeEnd != strokeEnd) {\n        _strokeEnd = strokeEnd;\n        setNeedsDisplay();\n    }\n}\n\nvoid ShapeLayer::setMaskFilter(const MaskFilter& maskFilter) {\n    _strokePaint.setMaskFilter(maskFilter);\n    _fillPaint.setMaskFilter(maskFilter);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/ShapeLayer.hpp",
    "content": "//\n//  ShapeLayer.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 3/4/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Drawing/Paint.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n#include \"snap_drawing/cpp/Utils/PathInterpolator.hpp\"\n\nnamespace snap::drawing {\n\nclass MaskFilter;\n\nclass ShapeLayer : public Layer {\npublic:\n    explicit ShapeLayer(const Ref<Resources>& resources);\n    ~ShapeLayer() override;\n\n    void onInitialize() override;\n\n    void setPath(Path&& path);\n\n    void setStrokeWidth(Scalar strokeWidth);\n    Scalar getStrokeWidth() const;\n\n    void setStrokeColor(Color strokeColor);\n    Color getStrokeColor() const;\n\n    void setFillColor(Color fillColor);\n    Color getFillColor() const;\n\n    void setStrokeCap(PaintStrokeCap strokeCap);\n    void setStrokeJoin(PaintStrokeJoin strokeJoin);\n\n    void setStrokeStart(Scalar strokeStart);\n    Scalar getStrokeStart() const;\n\n    void setStrokeEnd(Scalar strokeEnd);\n    Scalar getStrokeEnd() const;\n\n    void setMaskFilter(const MaskFilter& maskFilter);\n\nprotected:\n    void onDraw(DrawingContext& drawingContext) override;\n\nprivate:\n    Path _path;\n    Paint _strokePaint;\n    Paint _fillPaint;\n    Scalar _strokeStart = 0.0f;\n    Scalar _strokeEnd = 1.0f;\n    std::optional<PathInterpolator> _pathInterpolator;\n\n    const Path& getActivePath();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/SpinnerLayer.cpp",
    "content": "//\n//  SpinnerLayer.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 9/15/20.\n//\n\n#include \"snap_drawing/cpp/Layers/SpinnerLayer.hpp\"\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\nnamespace snap::drawing {\n\nconstexpr TimeInterval kLineThicknessAnimation = 0.5;\nconstexpr TimeInterval kRotationAnimation = 1.0;\nconstexpr Scalar kLineThickness = 1.5;\nconstexpr Scalar kLineSweepRatio = 0.6;\nconstexpr Scalar kInnerCircleOffset = 3.0;\nconstexpr Scalar kInnerCircleRotationOffset = 0.5;\n\nclass SpinnerAnimation : public IAnimation {\npublic:\n    SpinnerAnimation() = default;\n    ~SpinnerAnimation() override = default;\n\n    bool run(Layer& layer, Duration delta) override {\n        if (!_started) {\n            _started = true;\n            _animationTime = 0;\n        } else {\n            _animationTime += delta.seconds();\n        }\n\n        auto lineThicknessCompletion = std::min(1.0, _animationTime / kLineThicknessAnimation);\n        auto rotationAnimation = (fmod(_animationTime, kRotationAnimation)) / kRotationAnimation;\n\n        update(layer, lineThicknessCompletion, rotationAnimation);\n\n        // The animation never completes\n        return false;\n    }\n\n    void cancel(Layer& layer) override {\n        _started = false;\n        update(layer, 0.0, 0.0);\n    }\n\n    void complete(Layer& layer) override {\n        _started = false;\n        update(layer, 0.0, 0.0);\n    }\n\n    void addCompletion(AnimationCompletion&& completion) override {}\n\nprivate:\n    bool _started = false;\n    TimeInterval _animationTime = 0;\n\n    static void update(Layer& layer, double lineThicknessRatio, double rotationRatio) {\n        auto& spinnerLayer = dynamic_cast<SpinnerLayer&>(layer);\n\n        spinnerLayer.setLineThicknessRatio(static_cast<Scalar>(lineThicknessRatio));\n        spinnerLayer.setRotationRatio(static_cast<Scalar>(rotationRatio));\n    }\n};\n\nSpinnerLayer::SpinnerLayer(const Ref<Resources>& resources)\n    : Layer(resources),\n      _spinnerAnimation(Valdi::makeShared<SpinnerAnimation>()),\n      _circleBorder(BorderRadius::makeCircle()) {\n    _outerCirclePaint.setStroke(true);\n    _outerCirclePaint.setColor(_color);\n    _outerCirclePaint.setAntiAlias(true);\n\n    _innerCirclePaint.setStroke(true);\n    _innerCirclePaint.setColor(_color);\n    _innerCirclePaint.setAntiAlias(true);\n}\n\nSpinnerLayer::~SpinnerLayer() = default;\n\nstatic void drawArc(\n    DrawingContext& drawingContext, const Rect& arcBounds, const Paint& paint, LazyPath& lazyPath, Scalar rotation) {\n    auto drawWidth = drawingContext.drawBounds().width();\n    auto drawHeight = drawingContext.drawBounds().height();\n\n    auto saveCount = drawingContext.save();\n\n    Matrix matrix;\n    matrix.postRotate(rotation, drawWidth / 2.0f, drawHeight / 2.0f);\n    drawingContext.concat(matrix);\n\n    if (lazyPath.update(drawWidth, drawHeight)) {\n        lazyPath.path().arcTo(arcBounds, 360.0f, 360.0f * kLineSweepRatio);\n    }\n\n    drawingContext.drawPaint(paint, lazyPath.path());\n\n    drawingContext.restore(saveCount);\n}\n\nvoid SpinnerLayer::onDraw(DrawingContext& drawingContext) {\n    Layer::onDraw(drawingContext);\n\n    auto pi2 = M_PI * 2.0f;\n\n    drawArc(drawingContext, drawingContext.drawBounds(), _outerCirclePaint, _outerCirclePath, pi2 * _rotationRatio);\n\n    auto innerCircleBounds = drawingContext.drawBounds();\n\n    innerCircleBounds.offset(kInnerCircleOffset, kInnerCircleOffset);\n    innerCircleBounds.right -= kInnerCircleOffset * 2;\n    innerCircleBounds.bottom -= kInnerCircleOffset * 2;\n\n    if (!innerCircleBounds.isEmpty()) {\n        drawArc(drawingContext,\n                innerCircleBounds,\n                _innerCirclePaint,\n                _innerCirclePath,\n                pi2 - fmod(pi2 * (_rotationRatio + kInnerCircleRotationOffset), pi2));\n    }\n}\n\nvoid SpinnerLayer::onRootChanged(ILayerRoot* root) {\n    Layer::onRootChanged(root);\n\n    static auto kAnimationKey = STRING_LITERAL(\"spinner\");\n\n    if (root != nullptr && !hasAnimation(kAnimationKey)) {\n        addAnimation(kAnimationKey, _spinnerAnimation);\n    }\n}\n\nvoid SpinnerLayer::setLineThicknessRatio(Scalar lineThicknessRatio) {\n    if (_lineThicknessRatio != lineThicknessRatio) {\n        _lineThicknessRatio = lineThicknessRatio;\n\n        _innerCirclePaint.setStrokeWidth(kLineThickness * lineThicknessRatio);\n        _outerCirclePaint.setStrokeWidth(kLineThickness * lineThicknessRatio);\n        setNeedsDisplay();\n    }\n}\n\nvoid SpinnerLayer::setRotationRatio(Scalar rotationRatio) {\n    if (_rotationRatio != rotationRatio) {\n        _rotationRatio = rotationRatio;\n        setNeedsDisplay();\n    }\n}\n\nvoid SpinnerLayer::setColor(Color color) {\n    if (_color != color) {\n        _color = color;\n        _innerCirclePaint.setColor(color);\n        _outerCirclePaint.setColor(color);\n\n        setNeedsDisplay();\n    }\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/SpinnerLayer.hpp",
    "content": "//\n//  SpinnerLayer.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 9/15/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Utils/LazyPath.hpp\"\n\nnamespace snap::drawing {\n\nclass SpinnerAnimation;\n\nclass SpinnerLayer : public Layer {\npublic:\n    explicit SpinnerLayer(const Ref<Resources>& resources);\n    ~SpinnerLayer() override;\n\n    void setColor(Color color);\n    void setLineThicknessRatio(Scalar lineThicknessRatio);\n    void setRotationRatio(Scalar rotationRatio);\n\nprotected:\n    void onRootChanged(ILayerRoot* root) override;\n    void onDraw(DrawingContext& drawingContext) override;\n\nprivate:\n    Ref<SpinnerAnimation> _spinnerAnimation;\n    Scalar _lineThicknessRatio = 0.0f;\n    Scalar _rotationRatio = 0.0f;\n    Color _color = Color::white();\n\n    BorderRadius _circleBorder;\n\n    Paint _outerCirclePaint;\n    Paint _innerCirclePaint;\n    LazyPath _outerCirclePath;\n    LazyPath _innerCirclePath;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/TextLayer.cpp",
    "content": "//\n//  TextLayer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#include \"snap_drawing/cpp/Layers/TextLayer.hpp\"\n\n#include \"valdi_core/cpp/Attributes/TextAttributeValue.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n\n#include \"include/core/SkBlurTypes.h\"\n#include \"include/core/SkMaskFilter.h\"\n#include \"include/effects/SkGradientShader.h\"\n#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n#include \"snap_drawing/cpp/Text/TextLayoutBuilder.hpp\"\n#include \"snap_drawing/cpp/Touches/AttributedTextOnTapGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Utils/GradientWrapper.hpp\"\n\n#include <cmath>\n\nnamespace snap::drawing {\n\nconstexpr double kMaxAdjustsFontSizeToFitWidthAttempt = 8;\n\nTextLayer::TextLayer(const Ref<Resources>& resources) : Layer(resources) {\n    _textPaint.setAntiAlias(true);\n    _gradientWrapper = GradientWrapper();\n}\n\nTextLayer::~TextLayer() = default;\n\nSize TextLayer::sizeThatFits(Size maxSize) {\n    auto respectDynamicType = getResources()->getRespectDynamicType();\n    auto displayScale = getResources()->getDisplayScale();\n    auto dynamicTypeScale = getResources()->getDynamicTypeScale();\n    auto& layout = getTextLayout(maxSize, respectDynamicType, displayScale, dynamicTypeScale);\n\n    return Size::make(layout.getBounds().width() / displayScale, layout.getBounds().height() / displayScale);\n}\n\nvoid TextLayer::onDraw(DrawingContext& drawingContext) {\n    Layer::onDraw(drawingContext);\n\n    auto respectDynamicType = getResources()->getRespectDynamicType();\n    auto displayScale = getResources()->getDisplayScale();\n    auto dynamicTypeScale = getResources()->getDynamicTypeScale();\n    auto& layout = getTextLayout(\n        Size::make(getFrame().width(), getFrame().height()), respectDynamicType, displayScale, dynamicTypeScale);\n    drawingContext.concat(Matrix::makeScaleTranslate(1.0f / displayScale, 1.0f / displayScale, 0.0f, 0.0f));\n\n    if (hasTextShadow()) {\n        // Draw all of the shadows first\n        drawTextDecorationsShadows(drawingContext, layout.getDecorations());\n        for (const auto& entry : layout.getEntries()) {\n            if (entry.textBlob != nullptr) {\n                drawTextShadows(drawingContext, entry.textBlob);\n            }\n        }\n    }\n\n    // Then draw all of the text things\n    drawTextDecorations(drawingContext, layout.getDecorations(), /* predraw */ true);\n\n    for (const auto& entry : layout.getEntries()) {\n        if (entry.textBlob != nullptr) {\n            drawText(drawingContext, entry.textBlob, entry.color);\n        }\n    }\n\n    drawTextDecorations(drawingContext, layout.getDecorations(), /* predraw */ false);\n}\n\nvoid TextLayer::drawTextDecorationsShadows(DrawingContext& drawingContext,\n                                           const std::vector<TextLayoutDecorationEntry>& textDecorations) {\n    for (const auto& decoration : textDecorations) {\n        auto resolvedPaint = _textPaint;\n        resolvedPaint.getSkValue().setMaskFilter(\n            SkMaskFilter::MakeBlur(SkBlurStyle::kNormal_SkBlurStyle, _textShadow.radius, false));\n\n        resolvedPaint.setColor(_textShadow.color);\n        resolvedPaint.setAlpha(_textShadow.opacity);\n\n        auto bounds = decoration.bounds;\n        bounds.offsetX(_textShadow.offsetX);\n        bounds.offsetY(_textShadow.offsetY);\n\n        drawingContext.drawPaint(resolvedPaint, bounds);\n    }\n}\n\nvoid TextLayer::drawTextDecorations(DrawingContext& drawingContext,\n                                    const std::vector<TextLayoutDecorationEntry>& textDecorations,\n                                    bool predraw) {\n    for (const auto& decoration : textDecorations) {\n        if (decoration.predraw != predraw) {\n            continue;\n        }\n\n        auto resolvedPaint = _textPaint;\n\n        if (_gradientWrapper.hasGradient()) {\n            applyGradientToTextPaint(resolvedPaint);\n        } else if (decoration.color) {\n            resolvedPaint.setColor(decoration.color.value());\n        }\n\n        drawingContext.drawPaint(resolvedPaint, decoration.bounds);\n    }\n}\n\nvoid TextLayer::drawText(DrawingContext& drawingContext,\n                         const sk_sp<SkTextBlob>& textBlob,\n                         std::optional<Color> textColor) {\n    auto resolvedPaint = _textPaint;\n    if (_gradientWrapper.hasGradient()) {\n        applyGradientToTextPaint(resolvedPaint);\n    } else {\n        if (textColor) {\n            resolvedPaint.setColor(textColor.value());\n        }\n    }\n\n    drawingContext.canvas()->drawTextBlob(textBlob, 0, 0, resolvedPaint.getSkValue());\n}\n\nvoid TextLayer::applyGradientToTextPaint(Paint& paint) {\n    if (_textLayout != nullptr) {\n        _gradientWrapper.update(_textLayout->getBounds());\n        _gradientWrapper.applyToPaint(paint);\n    }\n}\n\nbool TextLayer::hasTextShadow() const {\n    auto isVisible = _textShadow.opacity > 0;\n    auto hiddenBehindText = _textShadow.radius == 0 && _textShadow.offsetX == 0 && _textShadow.offsetY == 0;\n    return isVisible && !hiddenBehindText;\n}\n\nvoid TextLayer::drawTextShadows(DrawingContext& drawingContext, const sk_sp<SkTextBlob>& textBlob) {\n    auto resolvedPaint = _textPaint;\n\n    resolvedPaint.getSkValue().setMaskFilter(\n        SkMaskFilter::MakeBlur(SkBlurStyle::kNormal_SkBlurStyle, _textShadow.radius, false));\n    resolvedPaint.setColor(_textShadow.color);\n    resolvedPaint.setAlpha(_textShadow.opacity);\n\n    drawingContext.canvas()->drawTextBlob(\n        textBlob.get(), _textShadow.offsetX, _textShadow.offsetY, resolvedPaint.getSkValue());\n}\n\nvoid TextLayer::setText(const Valdi::StringBox& text) {\n    if (_text != text || _attributedText != nullptr) {\n        _text = text;\n        _attributedText = nullptr;\n\n        setNeedsTextLayout();\n    }\n}\n\nconst Valdi::StringBox& TextLayer::getText() const {\n    return _text;\n}\n\nvoid TextLayer::setAttributedText(const Valdi::Ref<AttributedText>& attributedText) {\n    if (_attributedText != attributedText) {\n        _attributedText = attributedText;\n        _text = Valdi::StringBox();\n\n        setNeedsTextLayout();\n    }\n}\n\nconst Valdi::Ref<AttributedText>& TextLayer::getAttributedText() const {\n    return _attributedText;\n}\n\nvoid TextLayer::setTextColor(Color textColor) {\n    if (_textPaint.getColor() != textColor) {\n        _textPaint.setColor(textColor);\n\n        setNeedsDisplay();\n    }\n}\n\nColor TextLayer::getTextColor() const {\n    return _textPaint.getColor();\n}\n\nvoid TextLayer::setTextLinearGradient(std::vector<Scalar>&& locations,\n                                      std::vector<Color>&& colors,\n                                      LinearGradientOrientation orientation) {\n    if (_gradientWrapper.clearIfNeeded(GradientWrapper::GradientType::RADIAL)) {\n        setNeedsDisplay();\n    }\n\n    if (colors.empty()) {\n        if (_gradientWrapper.clearIfNeeded(GradientWrapper::GradientType::LINEAR)) {\n            setNeedsDisplay();\n        }\n        return;\n    }\n    _gradientWrapper.setAsLinear(std::move(locations), std::move(colors), orientation);\n\n    if (_gradientWrapper.isDirty()) {\n        setNeedsDisplay();\n    }\n}\n\nvoid TextLayer::setTextRadialGradient(std::vector<Scalar>&& locations, std::vector<Color>&& colors) {\n    if (_gradientWrapper.clearIfNeeded(GradientWrapper::GradientType::LINEAR)) {\n        setNeedsDisplay();\n    }\n\n    if (colors.empty()) {\n        if (_gradientWrapper.clearIfNeeded(GradientWrapper::GradientType::RADIAL)) {\n            setNeedsDisplay();\n        }\n        return;\n    }\n\n    _gradientWrapper.setAsRadial(std::move(locations), std::move(colors));\n\n    if (_gradientWrapper.isDirty()) {\n        setNeedsDisplay();\n    }\n}\n\nvoid TextLayer::resetTextGradient() {\n    _gradientWrapper.clear();\n    setNeedsDisplay();\n}\n\nvoid TextLayer::setTextAlign(TextAlign textAlign) {\n    if (_textAlign != textAlign) {\n        _textAlign = textAlign;\n\n        setNeedsTextLayout();\n    }\n}\n\nTextAlign TextLayer::getTextAlign() const {\n    return _textAlign;\n}\n\nvoid TextLayer::setTextDecoration(TextDecoration textDecoration) {\n    if (_textDecoration != textDecoration) {\n        _textDecoration = textDecoration;\n        setNeedsTextLayout();\n    }\n}\n\nTextDecoration TextLayer::getTextDecoration() const {\n    return _textDecoration;\n}\n\nvoid TextLayer::setTextOverflow(TextOverflow textOveflow) {\n    if (_textOverflow != textOveflow) {\n        _textOverflow = textOveflow;\n        setNeedsTextLayout();\n    }\n}\n\nTextOverflow TextLayer::getTextOverflow() const {\n    return _textOverflow;\n}\n\nvoid TextLayer::setTextShadow(Color color, Scalar radius, float opacity, Scalar offsetX, Scalar offsetY) {\n    auto textShadow = TextShadow(color, radius, opacity, offsetX, offsetY);\n    if (_textShadow != textShadow) {\n        _textShadow = textShadow;\n        setNeedsDisplay();\n    }\n}\n\nvoid TextLayer::resetTextShadow() {\n    setTextShadow(Color(), 0, 0, 0, 0);\n}\n\nTextShadow TextLayer::getTextShadow() const {\n    return _textShadow;\n}\n\nvoid TextLayer::setTextFont(const Valdi::Ref<Font>& font) {\n    if (_textFont != font) {\n        _textFont = font;\n\n        setNeedsTextLayout();\n    }\n}\n\nconst Valdi::Ref<Font>& TextLayer::getTextFont() const {\n    return _textFont;\n}\n\nvoid TextLayer::setNumberOfLines(int numberOfLines) {\n    if (_numberOfLines != numberOfLines) {\n        _numberOfLines = numberOfLines;\n\n        setNeedsTextLayout();\n    }\n}\n\nint TextLayer::getNumberOfLines() const {\n    return _numberOfLines;\n}\n\nvoid TextLayer::setAdjustsFontSizeToFitWidth(bool adjustsFontSizeToFitWidth) {\n    if (_adjustsFontSizeToFitWidth != adjustsFontSizeToFitWidth) {\n        _adjustsFontSizeToFitWidth = adjustsFontSizeToFitWidth;\n        setNeedsTextLayout();\n    }\n}\n\nbool TextLayer::getAdjustsFontSizeToFitWidth() const {\n    return _adjustsFontSizeToFitWidth;\n}\n\nvoid TextLayer::setMinimumScaleFactor(double minimumScaleFactor) {\n    minimumScaleFactor = std::clamp(minimumScaleFactor, 0.0, 1.0);\n\n    if (_minimumScaleFactor != minimumScaleFactor) {\n        _minimumScaleFactor = minimumScaleFactor;\n        if (_adjustsFontSizeToFitWidth) {\n            setNeedsTextLayout();\n        }\n    }\n}\n\ndouble TextLayer::getMinimumScaleFactor() const {\n    return _minimumScaleFactor;\n}\n\nvoid TextLayer::setLineHeightMultiple(Scalar lineHeightMultiple) {\n    if (_lineHeightMultiple != lineHeightMultiple) {\n        _lineHeightMultiple = lineHeightMultiple;\n        setNeedsTextLayout();\n    }\n}\n\nvoid TextLayer::setLetterSpacing(Scalar letterSpacing) {\n    if (_letterSpacing != letterSpacing) {\n        _letterSpacing = letterSpacing;\n        setNeedsTextLayout();\n    }\n}\n\nScalar TextLayer::getLetterSpacing() const {\n    return _letterSpacing;\n}\n\nScalar TextLayer::getLineHeightMultiple() const {\n    return _lineHeightMultiple;\n}\n\nvoid TextLayer::setNeedsTextLayout() {\n    if (_textLayout != nullptr) {\n        _textLayout = nullptr;\n        if (_attributedTextOnTapGestureRecognizer != nullptr) {\n            _attributedTextOnTapGestureRecognizer->setTextLayout(nullptr);\n        }\n        setNeedsDisplay();\n    }\n}\n\nstatic bool hasOnTapAttributeInTextLayout(const TextLayout& textLayout) {\n    for (const auto& attachment : textLayout.getAttachments()) {\n        if (Valdi::castOrNull<AttributedTextOnTapAttribute>(attachment.attachment) != nullptr) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\nTextLayout& TextLayer::getTextLayout(Size size, bool respectDynamicType, Scalar displayScale, Scalar dynamicTypeScale) {\n    // Align maxSize to pixel grid\n    auto maxSize = Size::make(ceilf(size.width * displayScale), ceilf(size.height * displayScale));\n\n    if (_textLayout != nullptr && (_textLayout->getMaxSize() != maxSize)) {\n        _textLayout = nullptr;\n    }\n\n    if (_textLayout == nullptr) {\n        VALDI_TRACE(\"SnapDrawing.makeTextLayout\");\n        _textLayout = TextLayer::makeTextLayout(maxSize,\n                                                _text,\n                                                _attributedText,\n                                                _textFont,\n                                                _textAlign,\n                                                _textDecoration,\n                                                _textOverflow,\n                                                _numberOfLines,\n                                                _lineHeightMultiple,\n                                                _letterSpacing,\n                                                isRightToLeft(),\n                                                _adjustsFontSizeToFitWidth,\n                                                _minimumScaleFactor,\n                                                respectDynamicType,\n                                                /* includeTextBlob*/ true,\n                                                displayScale,\n                                                dynamicTypeScale,\n                                                getResources()->getFontManager());\n\n        if (hasOnTapAttributeInTextLayout(*_textLayout)) {\n            addOnTapGestureRecognizer();\n        } else {\n            removeOnTapGestureRecognizer();\n        }\n    }\n\n    return *_textLayout;\n}\n\nvoid TextLayer::removeOnTapGestureRecognizer() {\n    if (_attributedTextOnTapGestureRecognizer != nullptr) {\n        removeGestureRecognizer(_attributedTextOnTapGestureRecognizer);\n        _attributedTextOnTapGestureRecognizer = nullptr;\n    }\n}\n\nvoid TextLayer::addOnTapGestureRecognizer() {\n    if (_attributedTextOnTapGestureRecognizer == nullptr) {\n        _attributedTextOnTapGestureRecognizer =\n            Valdi::makeShared<AttributedTextOnTapGestureRecognizer>(getResources()->getGesturesConfiguration());\n        addGestureRecognizer(_attributedTextOnTapGestureRecognizer);\n    }\n\n    _attributedTextOnTapGestureRecognizer->setTextLayout(_textLayout);\n}\n\nvoid TextLayer::onRightToLeftChanged() {\n    Layer::onRightToLeftChanged();\n\n    setNeedsTextLayout();\n}\n\nSize TextLayer::measureText(Size maxSize,\n                            const String& text,\n                            const Ref<AttributedText>& attributedText,\n                            const Ref<Font>& font,\n                            TextAlign textAlign,\n                            TextDecoration textDecoration,\n                            TextOverflow textOverflow,\n                            int numberOfLines,\n                            Scalar lineHeightMultiple,\n                            Scalar letterSpacing,\n                            bool isRightToLeft,\n                            bool adjustsFontSizeToFitWidth,\n                            double minimumScaleFactor,\n                            bool respectDynamicType,\n                            Scalar displayScale,\n                            Scalar dynamicTypeScale,\n                            const Ref<FontManager>& fontManager) {\n    auto textLayout = makeTextLayout(maxSize,\n                                     text,\n                                     attributedText,\n                                     font,\n                                     textAlign,\n                                     textDecoration,\n                                     textOverflow,\n                                     numberOfLines,\n                                     lineHeightMultiple,\n                                     letterSpacing,\n                                     isRightToLeft,\n                                     adjustsFontSizeToFitWidth,\n                                     minimumScaleFactor,\n                                     respectDynamicType,\n                                     /* includeTextBlob*/ false,\n                                     displayScale,\n                                     dynamicTypeScale,\n                                     fontManager);\n\n    return textLayout->getBounds().size();\n}\n\nRef<TextLayout> TextLayer::makeTextLayout(Size maxSize,\n                                          const String& text,\n                                          const Ref<AttributedText>& attributedText,\n                                          const Ref<Font>& font,\n                                          TextAlign textAlign,\n                                          TextDecoration textDecoration,\n                                          TextOverflow textOverflow,\n                                          int numberOfLines,\n                                          Scalar lineHeightMultiple,\n                                          Scalar letterSpacing,\n                                          bool isRightToLeft,\n                                          bool adjustsFontSizeToFitWidth,\n                                          double minimumScaleFactor,\n                                          bool respectDynamicType,\n                                          bool includeTextBlob,\n                                          Scalar displayScale,\n                                          Scalar dynamicTypeScale,\n                                          const Ref<FontManager>& fontManager) {\n    if (!adjustsFontSizeToFitWidth || numberOfLines != 1) {\n        return makeTextLayoutUnscaled(maxSize,\n                                      text,\n                                      attributedText,\n                                      font,\n                                      textAlign,\n                                      textDecoration,\n                                      textOverflow,\n                                      numberOfLines,\n                                      lineHeightMultiple,\n                                      letterSpacing,\n                                      isRightToLeft,\n                                      1.0,\n                                      respectDynamicType,\n                                      includeTextBlob,\n                                      displayScale,\n                                      dynamicTypeScale,\n                                      fontManager);\n    }\n\n    auto currentScale = 1.0;\n    auto scaleIncrement = (1.0 - minimumScaleFactor) / kMaxAdjustsFontSizeToFitWidthAttempt;\n\n    for (;;) {\n        auto layout = makeTextLayoutUnscaled(maxSize,\n                                             text,\n                                             attributedText,\n                                             font,\n                                             textAlign,\n                                             textDecoration,\n                                             textOverflow,\n                                             numberOfLines,\n                                             lineHeightMultiple,\n                                             letterSpacing,\n                                             isRightToLeft,\n                                             currentScale,\n                                             respectDynamicType,\n                                             includeTextBlob,\n                                             displayScale,\n                                             dynamicTypeScale,\n                                             fontManager);\n\n        if (layout->fitsInMaxSize() || currentScale <= minimumScaleFactor) {\n            return layout;\n        } else {\n            currentScale = std::max(minimumScaleFactor, currentScale - scaleIncrement);\n        }\n    }\n}\n\nstatic double resolveFontScale(\n    const Ref<Font>& font, double fontScale, bool respectDynamicType, Scalar displayScale, Scalar dynamicTypeScale) {\n    auto fontScaleRespectingDisplayScale = fontScale * displayScale;\n    if (!respectDynamicType || !font->respectDynamicType()) {\n        return fontScaleRespectingDisplayScale;\n    }\n\n    return fontScaleRespectingDisplayScale * dynamicTypeScale;\n}\n\nRef<TextLayout> TextLayer::makeTextLayoutUnscaled(Size maxSize,\n                                                  const String& text,\n                                                  const Ref<AttributedText>& attributedText,\n                                                  const Ref<Font>& font,\n                                                  TextAlign textAlign,\n                                                  TextDecoration textDecoration,\n                                                  TextOverflow textOverflow,\n                                                  int numberOfLines,\n                                                  Scalar lineHeightMultiple,\n                                                  Scalar letterSpacing,\n                                                  bool isRightToLeft,\n                                                  double fontScale,\n                                                  bool respectDynamicType,\n                                                  bool includeTextBlob,\n                                                  Scalar displayScale,\n                                                  Scalar dynamicTypeScale,\n                                                  const Ref<FontManager>& fontManager) {\n    TextLayoutBuilder builder(textAlign, textOverflow, maxSize, numberOfLines, fontManager, isRightToLeft);\n    builder.setIncludeTextBlob(includeTextBlob);\n\n    auto textFont = font;\n    if (textFont == nullptr && fontManager != nullptr) {\n        auto defaultFont = fontManager->getDefaultFont();\n        if (defaultFont) {\n            textFont = defaultFont.moveValue();\n        }\n    }\n\n    if (attributedText != nullptr) {\n        for (size_t i = 0; i < attributedText->getPartsSize(); i++) {\n            const auto& style = attributedText->getStyleAtIndex(i);\n            const auto& content = attributedText->getContentAtIndex(i);\n\n            Ref<Font> resolvedFont = style.font != nullptr ? style.font : textFont;\n            if (resolvedFont == nullptr) {\n                continue;\n            }\n            auto resolvedFontScale =\n                resolveFontScale(resolvedFont, fontScale, respectDynamicType, displayScale, dynamicTypeScale);\n            auto resolvedTextDecoration = style.textDecoration ? style.textDecoration.value() : textDecoration;\n\n            builder.append(content.toStringView(),\n                           resolvedFont->withScale(resolvedFontScale),\n                           lineHeightMultiple,\n                           letterSpacing,\n                           resolvedTextDecoration,\n                           style.onTap,\n                           style.color);\n        }\n    } else if (!text.isEmpty() && textFont != nullptr) {\n        auto resolvedFontScale =\n            resolveFontScale(textFont, fontScale, respectDynamicType, displayScale, dynamicTypeScale);\n        builder.append(text.toStringView(),\n                       textFont->withScale(resolvedFontScale),\n                       lineHeightMultiple,\n                       letterSpacing,\n                       textDecoration,\n                       nullptr,\n                       std::nullopt);\n    }\n\n    return builder.build();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/TextLayer.hpp",
    "content": "//\n//  TextLayer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Text/AttributedText.hpp\"\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n#include \"snap_drawing/cpp/Text/TextLayout.hpp\"\n\n#include \"valdi_core/cpp/Utils/PlatformResult.hpp\"\n\nnamespace snap::drawing {\n\nclass FontManager;\nclass ValdiAnimator;\nclass AttributedTextOnTapGestureRecognizer;\n\nstruct TextShadow {\n    Color color;\n    Scalar radius;\n    float opacity;\n    Scalar offsetX;\n    Scalar offsetY;\n\n    constexpr TextShadow() : color(Color()), radius(0), opacity(0), offsetX(0), offsetY(0) {};\n    constexpr TextShadow(Color color, Scalar radius, float opacity, Scalar offsetX, Scalar offsetY)\n        : color(color), radius(radius), opacity(opacity), offsetX(offsetX), offsetY(offsetY) {}\n\n    bool operator==(const TextShadow& other) const {\n        return this->color == other.color && this->radius == other.radius && this->opacity == other.opacity &&\n               this->offsetX == other.offsetX && this->offsetY == other.offsetY;\n    }\n};\n\nclass TextLayer : public Layer {\npublic:\n    explicit TextLayer(const Ref<Resources>& resources);\n    ~TextLayer() override;\n\n    Size sizeThatFits(Size maxSize) override;\n\n    void setText(const Valdi::StringBox& text);\n    const Valdi::StringBox& getText() const;\n\n    void setAttributedText(const Valdi::Ref<AttributedText>& attributedText);\n    const Valdi::Ref<AttributedText>& getAttributedText() const;\n\n    void setTextColor(Color textColor);\n    Color getTextColor() const;\n\n    void setTextAlign(TextAlign textAlign);\n    TextAlign getTextAlign() const;\n\n    void setTextDecoration(TextDecoration textDecoration);\n    TextDecoration getTextDecoration() const;\n\n    void setTextShadow(Color color, Scalar radius, float opacity, Scalar offsetX, Scalar offsetY);\n    void resetTextShadow();\n    TextShadow getTextShadow() const;\n\n    void setAdjustsFontSizeToFitWidth(bool adjustsFontSizeToFitWidth);\n    bool getAdjustsFontSizeToFitWidth() const;\n\n    void setMinimumScaleFactor(double minimumScaleFactor);\n    double getMinimumScaleFactor() const;\n\n    void setLineHeightMultiple(Scalar lineHeightMultiple);\n    Scalar getLineHeightMultiple() const;\n\n    void setLetterSpacing(Scalar letterSpacing);\n    Scalar getLetterSpacing() const;\n\n    void setTextFont(const Valdi::Ref<Font>& font);\n    const Valdi::Ref<Font>& getTextFont() const;\n\n    void setNumberOfLines(int numberOfLines);\n    int getNumberOfLines() const;\n\n    void setTextOverflow(TextOverflow textOveflow);\n    TextOverflow getTextOverflow() const;\n\n    void setTextLinearGradient(std::vector<Scalar>&& locations,\n                               std::vector<Color>&& colors,\n                               LinearGradientOrientation orientation);\n    void setTextRadialGradient(std::vector<Scalar>&& locations, std::vector<Color>&& colors);\n    void resetTextGradient();\n\n    static Size measureText(Size maxSize,\n                            const String& text,\n                            const Ref<AttributedText>& attributedText,\n                            const Ref<Font>& font,\n                            TextAlign textAlign,\n                            TextDecoration textDecoration,\n                            TextOverflow textOverflow,\n                            int numberOfLines,\n                            Scalar lineHeightMultiple,\n                            Scalar letterSpacing,\n                            bool isRightToLeft,\n                            bool adjustsFontSizeToFitWidth,\n                            double minimumScaleFactor,\n                            bool respectDynamicType,\n                            Scalar displayScale,\n                            Scalar dynamicTypeScale,\n                            const Ref<FontManager>& fontManager);\n\n    static Ref<TextLayout> makeTextLayout(Size maxSize,\n                                          const String& text,\n                                          const Ref<AttributedText>& attributedText,\n                                          const Ref<Font>& font,\n                                          TextAlign textAlign,\n                                          TextDecoration textDecoration,\n                                          TextOverflow textOverflow,\n                                          int numberOfLines,\n                                          Scalar lineHeightMultiple,\n                                          Scalar letterSpacing,\n                                          bool isRightToLeft,\n                                          bool adjustsFontSizeToFitWidth,\n                                          double minimumScaleFactor,\n                                          bool respectDynamicType,\n                                          bool includeTextBlob,\n                                          Scalar displayScale,\n                                          Scalar dynamicTypeScale,\n                                          const Ref<FontManager>& fontManager);\n\n    static Ref<TextLayout> makeTextLayoutUnscaled(Size maxSize,\n                                                  const String& text,\n                                                  const Ref<AttributedText>& attributedText,\n                                                  const Ref<Font>& font,\n                                                  TextAlign textAlign,\n                                                  TextDecoration textDecoration,\n                                                  TextOverflow textOverflow,\n                                                  int numberOfLines,\n                                                  Scalar lineHeightMultiple,\n                                                  Scalar letterSpacing,\n                                                  bool isRightToLeft,\n                                                  double fontScale,\n                                                  bool respectDynamicType,\n                                                  bool includeTextBlob,\n                                                  Scalar displayScale,\n                                                  Scalar dynamicTypeScale,\n                                                  const Ref<FontManager>& fontManager);\n\nprotected:\n    void onDraw(DrawingContext& drawingContext) override;\n    void onRightToLeftChanged() override;\n\nprivate:\n    Valdi::Ref<Font> _textFont;\n    Paint _textPaint;\n    Valdi::StringBox _text;\n    Valdi::Ref<AttributedText> _attributedText;\n    Ref<AttributedTextOnTapGestureRecognizer> _attributedTextOnTapGestureRecognizer;\n    TextAlign _textAlign = TextAlignLeft;\n    TextDecoration _textDecoration = TextDecorationNone;\n    TextShadow _textShadow;\n    TextOverflow _textOverflow = TextOverflowEllipsis;\n    int _numberOfLines = 1;\n    bool _adjustsFontSizeToFitWidth = false;\n    double _minimumScaleFactor = 0.0;\n    Scalar _lineHeightMultiple = 1.0f;\n    Scalar _letterSpacing = 0.0f;\n\n    Ref<TextLayout> _textLayout;\n    GradientWrapper _gradientWrapper;\n\n    TextLayout& getTextLayout(Size size, bool respectDynamicType, Scalar displayScale, Scalar dynamicTypeScale);\n\n    void setNeedsTextLayout();\n\n    void removeOnTapGestureRecognizer();\n    void addOnTapGestureRecognizer();\n\n    void drawTextDecorationsShadows(DrawingContext& drawingContext,\n                                    const std::vector<TextLayoutDecorationEntry>& textDecorations);\n\n    void drawTextDecorations(DrawingContext& drawingContext,\n                             const std::vector<TextLayoutDecorationEntry>& textDecorations,\n                             bool predraw);\n\n    void applyGradientToTextPaint(Paint& paint);\n\n    void drawText(DrawingContext& DrawingContext, const sk_sp<SkTextBlob>& textBlob, std::optional<Color> textColor);\n\n    bool hasTextShadow() const;\n\n    void drawTextShadows(DrawingContext& drawingContext, const sk_sp<SkTextBlob>& textBlob);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/VideoLayer.cpp",
    "content": "//\n//  VideoLayer.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 6/16/22.\n//\n\n#include \"snap_drawing/cpp/Layers/VideoLayer.hpp\"\n#include \"snap_drawing/cpp/Utils/ImageQueue.hpp\"\n\nnamespace snap::drawing {\n\nVideoPlaybackAnimation::VideoPlaybackAnimation(const Ref<ImageQueue>& imageQueue, const Ref<ImageLayer>& imageLayer)\n    : _imageQueue(imageQueue), _imageLayer(imageLayer) {}\n\nVideoPlaybackAnimation::~VideoPlaybackAnimation() = default;\n\nbool VideoPlaybackAnimation::run(Layer& /*layer*/, Duration /*delta*/) {\n    auto nextImage = _imageQueue->dequeue();\n    if (nextImage) {\n        _imageLayer->setImage(nextImage.value());\n    }\n    return false;\n}\n\nvoid VideoPlaybackAnimation::cancel(Layer& layer) {}\n\nvoid VideoPlaybackAnimation::complete(Layer& layer) {}\n\nvoid VideoPlaybackAnimation::addCompletion(AnimationCompletion&& completion) {}\n\nVideoLayer::VideoLayer(const Ref<Resources>& resources) : Layer(resources) {}\n\nVideoLayer::~VideoLayer() = default;\n\nvoid VideoLayer::onInitialize() {\n    Layer::onInitialize();\n\n    _imageLayer = makeLayer<ImageLayer>(getResources());\n    _imageLayer->setOptimizeRenderingForFrequentUpdates(true);\n    addChild(_imageLayer);\n}\n\nvoid VideoLayer::onRootChanged(ILayerRoot* root) {\n    Layer::onRootChanged(root);\n\n    updatePlaybackAnimation();\n}\n\nvoid VideoLayer::onBoundsChanged() {\n    Layer::onBoundsChanged();\n\n    _imageLayer->setFrame(Rect::makeXYWH(0, 0, getFrame().width(), getFrame().height()));\n}\n\nvoid VideoLayer::setFittingSizeMode(FittingSizeMode fittingSizeMode) {\n    _imageLayer->setFittingSizeMode(fittingSizeMode);\n}\n\nvoid VideoLayer::updatePlaybackAnimation() {\n    static auto kAnimationKey = STRING_LITERAL(\"videoPlayback\");\n\n    if (getRoot() != nullptr && _imageQueue != nullptr) {\n        addAnimation(kAnimationKey, Valdi::makeShared<VideoPlaybackAnimation>(_imageQueue, _imageLayer));\n    } else {\n        removeAnimation(kAnimationKey);\n    }\n}\n\nvoid VideoLayer::setImageQueue(const Ref<ImageQueue>& imageQueue) {\n    if (_imageQueue != imageQueue) {\n        _imageQueue = imageQueue;\n        updatePlaybackAnimation();\n    }\n}\n\nconst Ref<ImageQueue>& VideoLayer::getImageQueue() const {\n    return _imageQueue;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Layers/VideoLayer.hpp",
    "content": "//\n//  VideoLayer.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 6/16/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n#include \"snap_drawing/cpp/Layers/ImageLayer.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n\nnamespace snap::drawing {\n\nclass ImageQueue;\n\nclass VideoPlaybackAnimation : public IAnimation {\npublic:\n    VideoPlaybackAnimation(const Ref<ImageQueue>& imageQueue, const Ref<ImageLayer>& imageLayer);\n    ~VideoPlaybackAnimation() override;\n\n    bool run(Layer& layer, Duration delta) override;\n\n    void cancel(Layer& layer) override;\n\n    void complete(Layer& layer) override;\n\n    void addCompletion(AnimationCompletion&& completion) override;\n\nprivate:\n    Ref<ImageQueue> _imageQueue;\n    Ref<ImageLayer> _imageLayer;\n};\n\nclass VideoLayer : public Layer {\npublic:\n    explicit VideoLayer(const Ref<Resources>& resources);\n    ~VideoLayer() override;\n\n    void onInitialize() override;\n\n    void setFittingSizeMode(FittingSizeMode fittingSizeMode);\n\n    void setImageQueue(const Ref<ImageQueue>& imageQueue);\n    const Ref<ImageQueue>& getImageQueue() const;\n\nprotected:\n    void onRootChanged(ILayerRoot* root) override;\n    void onBoundsChanged() override;\n\nprivate:\n    Ref<ImageLayer> _imageLayer;\n    Ref<ImageQueue> _imageQueue;\n\n    void updatePlaybackAnimation();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Resources.cpp",
    "content": "//\n//  Resources.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/12/22.\n//\n\n#include \"snap_drawing/cpp/Resources.hpp\"\n#include \"include/core/SkGraphics.h\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n#include \"valdi_core/cpp/Interfaces/ILogger.hpp\"\n\nnamespace snap::drawing {\n\nResources::Resources(const Ref<FontManager>& fontManager, Scalar displayScale, Valdi::ILogger& logger)\n    : Resources(fontManager, displayScale, GesturesConfiguration::getDefault(), logger) {}\n\nResources::Resources(const Ref<FontManager>& fontManager,\n                     Scalar displayScale,\n                     const GesturesConfiguration& gesturesConfiguration,\n                     Valdi::ILogger& logger)\n    : _fontManager(fontManager),\n      _respectDynamicType(true),\n      _displayScale(displayScale),\n      _dynamicTypeScale(1.0),\n      _gesturesConfiguration(gesturesConfiguration),\n      _logger(&logger) {\n    // Make sure all Skia features are properly loaded.\n    // This will be a no-op if this call was already done before.\n    SkGraphics::Init();\n    Image::initializeCodecs();\n}\n\nResources::~Resources() = default;\n\nconst Ref<FontManager>& Resources::getFontManager() const {\n    return _fontManager;\n}\n\nbool Resources::getRespectDynamicType() const {\n    return _respectDynamicType;\n}\n\nvoid Resources::setRespectDynamicType(bool respectDynamicType) {\n    _respectDynamicType = respectDynamicType;\n}\n\nScalar Resources::getDisplayScale() const {\n    return _displayScale;\n}\n\nvoid Resources::setDisplayScale(Scalar displayScale) {\n    _displayScale = displayScale;\n}\n\nScalar Resources::getDynamicTypeScale() const {\n    return _dynamicTypeScale;\n}\n\nvoid Resources::setDynamicTypeScale(Scalar dynamicTypeScale) {\n    _dynamicTypeScale = dynamicTypeScale;\n}\n\nconst GesturesConfiguration& Resources::getGesturesConfiguration() const {\n    return _gesturesConfiguration;\n}\n\nValdi::ILogger& Resources::getLogger() const {\n    return *_logger;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Resources.hpp",
    "content": "//\n//  Resources.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/12/22.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n\n#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n\nnamespace Valdi {\nclass ILogger;\n}\n\nnamespace snap::drawing {\n\nclass Resources : public Valdi::SimpleRefCountable {\npublic:\n    Resources(const Ref<FontManager>& fontManager,\n              Scalar displayScale,\n              const GesturesConfiguration& gesturesConfiguration,\n              Valdi::ILogger& logger);\n\n    Resources(const Ref<FontManager>& fontManager, Scalar displayScale, Valdi::ILogger& logger);\n\n    ~Resources() override;\n\n    const Ref<FontManager>& getFontManager() const;\n    Valdi::ILogger& getLogger() const;\n\n    bool getRespectDynamicType() const;\n    void setRespectDynamicType(bool respectDynamicType);\n\n    Scalar getDisplayScale() const;\n    void setDisplayScale(Scalar displayScale);\n\n    Scalar getDynamicTypeScale() const;\n    void setDynamicTypeScale(Scalar dynamicTypeScale);\n\n    const GesturesConfiguration& getGesturesConfiguration() const;\n\nprivate:\n    Ref<FontManager> _fontManager;\n    bool _respectDynamicType;\n    Scalar _displayScale;\n    Scalar _dynamicTypeScale;\n    GesturesConfiguration _gesturesConfiguration;\n    Ref<Valdi::ILogger> _logger;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/AttributedText.cpp",
    "content": "//\n//  AttributedText.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/30/20.\n//\n\n#include \"snap_drawing/cpp/Text/AttributedText.hpp\"\n\nnamespace snap::drawing {\n\nAttributedText::AttributedText(AttributedText::Parts parts)\n    : Valdi::TextAttributeValueBase<AttributedTextPartStyle>(std::move(parts)) {}\n\nAttributedText::~AttributedText() = default;\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/AttributedText.hpp",
    "content": "//\n//  AttributedText.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/30/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Attributes/TextAttributeValue.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n#include \"valdi_core/cpp/Utils/Value.hpp\"\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n#include \"snap_drawing/cpp/Text/TextLayout.hpp\"\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n\n#include <optional>\n#include <vector>\n\nnamespace snap::drawing {\n\nclass AttributedTextOnTapAttribute : public Valdi::SimpleRefCountable {\npublic:\n    virtual void onTap(const GestureRecognizer& gestureRecognizer,\n                       GestureRecognizerState state,\n                       const Point& location) = 0;\n};\n\nstruct AttributedTextPartStyle {\n    Ref<Font> font;\n    std::optional<Color> color;\n    std::optional<TextDecoration> textDecoration;\n    Ref<AttributedTextOnTapAttribute> onTap;\n};\n\nclass AttributedText : public Valdi::SimpleRefCountable, public Valdi::TextAttributeValueBase<AttributedTextPartStyle> {\npublic:\n    explicit AttributedText(AttributedText::Parts parts);\n\n    ~AttributedText() override;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Character.hpp",
    "content": "//\n//  Character.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 11/8/22.\n//\n\n#pragma once\n\n#include <cstdint>\n\nnamespace snap::drawing {\n\nusing Character = uint32_t;\n\n}\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/CharactersIterator.hpp",
    "content": "//\n//  CharactersIterator.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/3/23.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Character.hpp\"\n#include <cstddef>\n\nnamespace snap::drawing {\n\n/**\n A Helper to iterate through characters and process them\n by range.\n */\nclass CharactersIterator {\npublic:\n    constexpr CharactersIterator(const Character* characters, size_t length)\n        : CharactersIterator(characters, 0, length) {}\n    constexpr CharactersIterator(const Character* characters, size_t start, size_t end)\n        : _characters(characters), _end(end), _position(start), _rangeStart(start) {}\n\n    constexpr bool isAtEnd() const {\n        return _position == _end;\n    }\n\n    constexpr Character current() const {\n        return _characters[_position];\n    }\n\n    constexpr void advance() {\n        _position++;\n    }\n\n    constexpr size_t position() const {\n        return _position;\n    }\n\n    constexpr void resetRange() {\n        _rangeStart = _position;\n    }\n\n    constexpr bool hasRange() const {\n        return _rangeStart != _position;\n    }\n\n    constexpr size_t rangeStart() const {\n        return _rangeStart;\n    }\n\n    constexpr size_t rangeEnd() const {\n        return _position;\n    }\n\n    constexpr size_t rangeLength() const {\n        return _position - _rangeStart;\n    }\n\nprivate:\n    const Character* _characters;\n    size_t _end;\n    size_t _position;\n    size_t _rangeStart;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Font.cpp",
    "content": "//\n//  Font.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n\n#include \"include/core/SkFontMetrics.h\"\n#include <fmt/format.h>\n\nnamespace snap::drawing {\n\nFont::Font(\n    Ref<FontResolver>&& fontResolver, Ref<Typeface>&& typeface, Scalar size, double scale, bool respectDynamicType)\n    : _fontResolver(std::move(fontResolver)),\n      _typeface(std::move(typeface)),\n      _font(_typeface->getSkValue(), size * scale),\n      _size(size),\n      _scale(scale),\n      _respectDynamicType(respectDynamicType) {\n    _font.setEdging(SkFont::Edging::kAntiAlias);\n}\n\nFont::~Font() = default;\n\nFontId Font::getFontId() const {\n    auto size = _font.getSize();\n\n    auto sizeId = *reinterpret_cast<uint32_t*>(&size);\n    auto typefaceId = _typeface->getId();\n\n    return (static_cast<FontId>(sizeId) << 32) | static_cast<FontId>(typefaceId);\n}\n\nconst SkFont& Font::getSkValue() const {\n    return _font;\n}\n\nconst FontStyle& Font::style() const {\n    return _typeface->fontStyle();\n}\n\nScalar Font::size() const {\n    return _size;\n}\n\nScalar Font::resolvedSize() const {\n    return _font.getSize();\n}\n\nRef<Font> Font::withScale(double scale) {\n    if (_scale == scale) {\n        return Valdi::strongSmallRef(this);\n    }\n\n    return Valdi::makeShared<Font>(\n        Ref<FontResolver>(_fontResolver), Ref<Typeface>(_typeface), _size, scale, _respectDynamicType);\n}\n\nValdi::Result<Ref<Font>> Font::withStyle(FontStyle style) {\n    return withStyleAndSize(style, _size);\n}\n\nValdi::Result<Ref<Font>> Font::withSize(Scalar size) {\n    return withStyleAndSize(style(), size);\n}\n\nValdi::Result<Ref<Font>> Font::withStyleAndSize(FontStyle style, Scalar size) {\n    if (_typeface->fontStyle() == style && _size == size) {\n        return Valdi::strongSmallRef(this);\n    }\n\n    return _fontResolver->getFont(_typeface, style, size, _scale, _respectDynamicType);\n}\n\ndouble Font::scale() const {\n    return _scale;\n}\n\nconst Ref<Typeface>& Font::typeface() const {\n    return _typeface;\n}\n\nbool Font::respectDynamicType() const {\n    return _respectDynamicType;\n}\n\nstd::string Font::getDescription() const {\n    return fmt::format(\"{} {} x{}\", _typeface->familyName().toStringView(), _size, _scale);\n}\n\nconst FontMetrics& Font::metrics() {\n    if (!_loadedMetrics) {\n        _loadedMetrics = true;\n        _metrics = _typeface->getFontMetrics(_size * _scale);\n    }\n\n    return _metrics;\n}\n\nconst HBFont& Font::getHBFont() {\n    if (!_hasHBFont) {\n        _hasHBFont = true;\n        _hbFont = Harfbuzz::createSubFont(_typeface->getHBFont(), &_font);\n    }\n\n    return _hbFont;\n}\n\nVALDI_CLASS_IMPL(Font)\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Font.hpp",
    "content": "//\n//  Font.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include \"valdi_core/cpp/Utils/ValdiObject.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\n#include \"snap_drawing/cpp/Text/FontMetrics.hpp\"\n#include \"snap_drawing/cpp/Text/FontStyle.hpp\"\n#include \"snap_drawing/cpp/Text/Harfbuzz.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"include/core/SkFont.h\"\n\nnamespace snap::drawing {\n\nclass Font;\n\nclass Typeface;\n\nclass FontResolver : public Valdi::ValdiObject {\npublic:\n    virtual Valdi::Result<Ref<Font>> getFont(\n        const Ref<Typeface>& typeface, FontStyle fontStyle, Scalar fontSize, double scale, bool respectDynamicType) = 0;\n};\n\nusing FontId = uint64_t;\n\nclass Font : public Valdi::ValdiObject {\npublic:\n    Font(\n        Ref<FontResolver>&& fontResolver, Ref<Typeface>&& typeface, Scalar size, double scale, bool respectDynamicType);\n    ~Font() override;\n\n    const SkFont& getSkValue() const;\n    const FontStyle& style() const;\n    const Ref<Typeface>& typeface() const;\n\n    FontId getFontId() const;\n\n    Scalar resolvedSize() const;\n\n    Scalar size() const;\n    double scale() const;\n    bool respectDynamicType() const;\n\n    const FontMetrics& metrics();\n\n    std::string getDescription() const;\n\n    Ref<Font> withScale(double scale);\n    Valdi::Result<Ref<Font>> withStyle(FontStyle style);\n    Valdi::Result<Ref<Font>> withSize(Scalar size);\n    Valdi::Result<Ref<Font>> withStyleAndSize(FontStyle style, Scalar size);\n\n    const HBFont& getHBFont();\n\n    VALDI_CLASS_HEADER(Font)\n\nprivate:\n    Ref<FontResolver> _fontResolver;\n    Ref<Typeface> _typeface;\n    Ref<Valdi::RefCountable> _textShaperRepr;\n    HBFont _hbFont;\n    SkFont _font;\n    Scalar _size;\n    double _scale;\n    bool _respectDynamicType;\n    FontMetrics _metrics;\n    bool _loadedMetrics = false;\n    bool _hasHBFont = false;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontFamily.cpp",
    "content": "//\n//  FontFamily.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 10/19/22.\n//\n\n#include \"snap_drawing/cpp/Text/FontFamily.hpp\"\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n\n#include \"include/core/SkFontMgr.h\"\n\nnamespace snap::drawing {\n\nFontFamily::FontFamily(const String& familyName) : _familyName(familyName) {}\nFontFamily::~FontFamily() = default;\n\nconst String& FontFamily::getFamilyName() const {\n    return _familyName;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontFamily.hpp",
    "content": "//\n//  FontFamily.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 10/19/22.\n//\n\n#pragma once\n\n#include \"include/core/SkTypeface.h\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\n#include \"snap_drawing/cpp/Text/FontStyle.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n\nclass SkFontMgr;\n\nnamespace snap::drawing {\n\nclass Typeface;\n\n/**\n A FontFamily holds a set of related typefaces with different styles.\n */\nclass FontFamily : public Valdi::SimpleRefCountable {\npublic:\n    explicit FontFamily(const String& familyName);\n    ~FontFamily() override;\n\n    const String& getFamilyName() const;\n\n    /**\n     Returns the closest matching Typeface from the given FontStyle.\n     May return null if the FontFamily holds no typefaces.\n     */\n    virtual Ref<Typeface> matchStyle(SkFontMgr& fontMgr, FontStyle fontStyle) = 0;\n\nprivate:\n    String _familyName;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontFamilyWithLoadableTypefaces.cpp",
    "content": "//\n//  FontFamilyWithLoadableTypefaces.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 12/12/22.\n//\n\n#include \"snap_drawing/cpp/Text/FontFamilyWithLoadableTypefaces.hpp\"\n#include \"snap_drawing/cpp/Text/LoadableTypeface.hpp\"\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n\nnamespace snap::drawing {\n\nFontFamilyWithLoadableTypefaces::FontFamilyWithLoadableTypefaces(Valdi::ILogger& logger, const String& familyName)\n    : FontFamily(familyName), _logger(logger) {}\nFontFamilyWithLoadableTypefaces::~FontFamilyWithLoadableTypefaces() = default;\n\nvoid FontFamilyWithLoadableTypefaces::registerLoadableTypeface(FontStyle fontStyle,\n                                                               const Ref<LoadableTypeface>& loadableTypeface) {\n    _typefaces[fontStyle] = loadableTypeface;\n}\n\nvoid FontFamilyWithLoadableTypefaces::unregisterLoadableTypeface(const Ref<LoadableTypeface>& loadableTypeface) {\n    auto it = _typefaces.begin();\n    while (it != _typefaces.end()) {\n        if (it->second == loadableTypeface) {\n            it = _typefaces.erase(it);\n        } else {\n            it++;\n        }\n    }\n}\n\nstatic int computeSelectionScore(FontStyle desiredFontStyle, FontStyle candidateFontStyle) {\n    static constexpr int kMismatchedSlantOffset = static_cast<int>(FontWeightExtraBlack) + 1;\n\n    /**\n     * Taken from Valdi's FontManager.kt:\n     * This will return a score where values closer than 0 are higher matches.\n     * In case of equality, values lower than 0 should be prioritized over values higher than 0.\n     *\n     * Examples:\n     * Desired LIGHT\n     * CANDIDATE: DEMI_BOLD\n     * Score: -3\n     * Score is negative because weight is lower than the desired weight\n     *\n     * Desired: MEDIUM\n     * CANDIDATE: NORMAL\n     * Score: 1\n     * Score is positive because weight is higher than the desired weight\n\n     * Desired: NORMAL\n     * Candidate: NORMAL\n     * Mismatched style\n     * Score: 8\n     * Mismatching styles look very bad, we prioritize matching styles over weights.\n     *\n     */\n\n    auto score = static_cast<int>(candidateFontStyle.getWeight()) - static_cast<int>(desiredFontStyle.getWeight());\n    if (desiredFontStyle.getSlant() != candidateFontStyle.getSlant()) {\n        if (score >= 0) {\n            score += kMismatchedSlantOffset;\n        } else {\n            score -= kMismatchedSlantOffset;\n        }\n    }\n\n    // TODO(simon): Also look at FontWidth.\n\n    return score;\n}\n\nRef<LoadableTypeface> FontFamilyWithLoadableTypefaces::resolveLoadableTypeface(FontStyle fontStyle) const {\n    std::optional<std::pair<FontStyle, Ref<LoadableTypeface>>> bestLoadableTypeface;\n\n    for (const auto& it : _typefaces) {\n        if (!bestLoadableTypeface) {\n            bestLoadableTypeface = {std::make_pair(it.first, it.second)};\n        } else {\n            /**\n             Algorithm taken from Valdi's FontManager.kt\n             */\n            auto previousScore = computeSelectionScore(fontStyle, bestLoadableTypeface.value().first);\n            auto newScore = computeSelectionScore(fontStyle, it.first);\n\n            auto previousScoreAbs = std::abs(previousScore);\n            auto newScoreAbs = std::abs(newScore);\n\n            // We are looking for the closest value to zero\n            if (newScoreAbs < previousScoreAbs) {\n                bestLoadableTypeface = {std::make_pair(it.first, it.second)};\n            } else if (newScoreAbs == previousScoreAbs) {\n                // In case of equality, we choose the lower values, which means we prioritize\n                // weight which are less strong than our requested weight over the ones\n                // which are higher\n                if (newScore < previousScore) {\n                    bestLoadableTypeface = {std::make_pair(it.first, it.second)};\n                }\n            }\n        }\n    }\n\n    if (!bestLoadableTypeface) {\n        return nullptr;\n    }\n\n    return std::move(bestLoadableTypeface.value().second);\n}\n\nRef<Typeface> FontFamilyWithLoadableTypefaces::matchStyle(SkFontMgr& fontMgr, FontStyle fontStyle) {\n    while (!_typefaces.empty()) {\n        auto loadableTypeface = resolveLoadableTypeface(fontStyle);\n        if (loadableTypeface == nullptr) {\n            return nullptr;\n        }\n\n        const auto& result = loadableTypeface->get(fontMgr);\n        if (result) {\n            return result.value();\n        }\n\n        VALDI_ERROR(\n            _logger, \"Failed to load registered Typeface in font family '{}': {}\", getFamilyName(), result.error());\n        unregisterLoadableTypeface(loadableTypeface);\n    }\n\n    return nullptr;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontFamilyWithLoadableTypefaces.hpp",
    "content": "//\n//  FontFamilyWithLoadableTypefaces.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 12/12/22.\n//\n\n#include \"snap_drawing/cpp/Text/FontFamily.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n\nclass SkFontStyleSet;\n\nnamespace Valdi {\nclass ILogger;\n}\n\nnamespace snap::drawing {\n\nclass LoadableTypeface;\n\n/**\n An implementation of FontFamily which holds a list of LoadableTypeface that\n can be externally registered. The LoadableTypeface are loaded lazily when\n they are selected through matchStyle(). If the LoadableTypeface fails to load,\n it will be unregistered from the FontFamily.\n */\nclass FontFamilyWithLoadableTypefaces : public FontFamily {\npublic:\n    FontFamilyWithLoadableTypefaces(Valdi::ILogger& logger, const String& familyName);\n    ~FontFamilyWithLoadableTypefaces() override;\n\n    /**\n     Register a LoadableTypeface associated with the given FontStyle. The LoadableTypeface will\n     become a candidate for matchStyle().\n     */\n    void registerLoadableTypeface(FontStyle fontStyle, const Ref<LoadableTypeface>& loadableTypeface);\n\n    Ref<Typeface> matchStyle(SkFontMgr& fontMgr, FontStyle fontStyle) override;\n\nprivate:\n    [[maybe_unused]] Valdi::ILogger& _logger;\n    Valdi::FlatMap<FontStyle, Ref<LoadableTypeface>> _typefaces;\n\n    Ref<LoadableTypeface> resolveLoadableTypeface(FontStyle fontStyle) const;\n    void unregisterLoadableTypeface(const Ref<LoadableTypeface>& loadableTypeface);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontFamilyWithStyleSet.cpp",
    "content": "//\n//  FontFamilyWithStyleSet.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 12/12/22.\n//\n\n#include \"snap_drawing/cpp/Text/FontFamilyWithStyleSet.hpp\"\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n\n#include \"include/core/SkFontMgr.h\"\n\nnamespace snap::drawing {\n\nFontFamilyWithStyleSet::FontFamilyWithStyleSet(const sk_sp<SkFontStyleSet>& fontStyleSet, const String& familyName)\n    : FontFamily(familyName), _fontStyleSet(fontStyleSet) {}\nFontFamilyWithStyleSet::~FontFamilyWithStyleSet() = default;\n\nRef<Typeface> FontFamilyWithStyleSet::matchStyle(SkFontMgr& fontMgr, FontStyle fontStyle) {\n    const auto& it = _fontIdByStyle.find(fontStyle);\n    if (it != _fontIdByStyle.end()) {\n        if (it->second == 0) {\n            return nullptr;\n        }\n\n        return _typefaces[it->second];\n    }\n\n    sk_sp<SkTypeface> matchedTypeface(_fontStyleSet->matchStyle(fontStyle.getSkValue()));\n    if (matchedTypeface == nullptr) {\n        _fontIdByStyle[fontStyle] = 0;\n        return nullptr;\n    }\n\n    auto id = matchedTypeface->uniqueID();\n    _fontIdByStyle[fontStyle] = id;\n\n    const auto& typefaceId = _typefaces.find(id);\n    if (typefaceId != _typefaces.end()) {\n        return typefaceId->second;\n    }\n\n    auto typeface = Valdi::makeShared<Typeface>(std::move(matchedTypeface), getFamilyName(), false);\n    _typefaces[id] = typeface;\n\n    return typeface;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontFamilyWithStyleSet.hpp",
    "content": "//\n//  FontFamilyWithStyleSet.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 12/12/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/FontFamily.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n\nclass SkFontStyleSet;\n\nnamespace snap::drawing {\n\nclass Typeface;\n\n/**\n A FontFamily implementation that is backed by a Skia SkFontStyleSet instance.\n */\nclass FontFamilyWithStyleSet : public FontFamily {\npublic:\n    FontFamilyWithStyleSet(const sk_sp<SkFontStyleSet>& fontStyleSet, const String& familyName);\n    ~FontFamilyWithStyleSet() override;\n\n    Ref<Typeface> matchStyle(SkFontMgr& fontMgr, FontStyle fontStyle) override;\n\nprivate:\n    sk_sp<SkFontStyleSet> _fontStyleSet;\n    Valdi::FlatMap<SkTypefaceID, Ref<Typeface>> _typefaces;\n    Valdi::FlatMap<FontStyle, SkTypefaceID> _fontIdByStyle;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontManager.cpp",
    "content": "//\n//  FontManager.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n#include \"snap_drawing/cpp/Text/FontFamily.hpp\"\n#include \"snap_drawing/cpp/Text/FontFamilyWithLoadableTypefaces.hpp\"\n#include \"snap_drawing/cpp/Text/FontFamilyWithStyleSet.hpp\"\n#include \"snap_drawing/cpp/Text/SkFontMgrSingleton.hpp\"\n#include \"snap_drawing/cpp/Text/TextShaper.hpp\"\n\n#include \"valdi_core/cpp/Utils/DiskUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n#include \"valdi_core/cpp/Utils/Value.hpp\"\n\nnamespace snap::drawing {\n\nclass ScopedFontManager : public IFontManager {\npublic:\n    ScopedFontManager(SkFontMgr& fontMgr, Valdi::ILogger& logger, const Ref<IFontManager>& parent)\n        : _typefaceRegistry(logger, nullptr), _fontMgr(fontMgr), _parent(parent) {}\n\n    ~ScopedFontManager() override = default;\n\n    void registerTypeface(const String& fontFamilyName,\n                          FontStyle fontStyle,\n                          bool canUseAsFallback,\n                          const Ref<LoadableTypeface>& loadableTypeface) override {\n        std::lock_guard<Valdi::Mutex> guard(_mutex);\n        _typefaceRegistry.registerTypeface(fontFamilyName, fontStyle, canUseAsFallback, loadableTypeface);\n    }\n\n    Ref<IFontManager> makeScoped() override {\n        return Valdi::makeShared<ScopedFontManager>(\n            _fontMgr, _typefaceRegistry.getLogger(), Valdi::strongSmallRef(this));\n    }\n\n    Valdi::Result<Ref<Font>> getFont(const Ref<Typeface>& typeface,\n                                     FontStyle fontStyle,\n                                     Scalar fontSize,\n                                     double scale,\n                                     bool respectDynamicType) override {\n        // Not implemented locally, we don't yet need this functionality\n        return _parent->getFont(typeface, fontStyle, fontSize, scale, respectDynamicType);\n    }\n\n    Valdi::Result<Valdi::Ref<Typeface>> getTypefaceWithName(const String& name) override {\n        {\n            std::lock_guard<Valdi::Mutex> guard(_mutex);\n            auto typeface = _typefaceRegistry.getTypefaceWithName(_fontMgr, name, nullptr);\n            if (typeface) {\n                return typeface.moveValue();\n            }\n        }\n\n        return _parent->getTypefaceWithName(name);\n    }\n\n    Valdi::Result<Valdi::Ref<Typeface>> getTypefaceWithFamilyNameAndStyle(const String& familyName,\n                                                                          FontStyle fontStyle) override {\n        {\n            std::lock_guard<Valdi::Mutex> guard(_mutex);\n            auto typeface = _typefaceRegistry.getTypefaceWithFamilyNameAndStyle(_fontMgr, familyName, fontStyle);\n            if (typeface) {\n                return typeface.moveValue();\n            }\n        }\n\n        return _parent->getTypefaceWithFamilyNameAndStyle(familyName, fontStyle);\n    }\n\nprivate:\n    TypefaceRegistry _typefaceRegistry;\n    SkFontMgr& _fontMgr;\n    Ref<IFontManager> _parent;\n    Valdi::Mutex _mutex;\n};\n\n#if __ANDROID__\nconst char* kFallbackDefaultFontFamilyName = \"helvetica\";\n#else\nconst char* kFallbackDefaultFontFamilyName = \"Helvetica\";\n#endif\n\nstatic Valdi::StringBox getFamilyNameAtIndex(SkFontMgr* mgr, size_t index) {\n    SkString familyName;\n    mgr->getFamilyName(static_cast<int>(index), &familyName);\n\n    return Valdi::StringCache::makeStringFromCLiteral(familyName.c_str());\n}\n\nFontManager::FontManager(Valdi::ILogger& logger, bool enableTextShaperCache)\n    : _logger(logger),\n      _typefaceRegistry(logger, this),\n      _defaultFontStyle(FontWidthNormal, FontWeightNormal, FontSlantUpright),\n      _textShaper(TextShaper::make(enableTextShaperCache)) {}\n\nFontManager::~FontManager() = default;\n\nLoadResult FontManager::load() {\n    // Acquiring the lock will trigger the load if it weren't loaded yet\n    bool activeInit;\n    auto guard = lock(true, &activeInit);\n    return {doGetAvailableFonts(guard), activeInit};\n}\n\nbool FontManager::doLoad(std::unique_lock<Valdi::Mutex>& /*lock*/) {\n    VALDI_TRACE(\"SnapDrawing.loadFontManager\");\n\n    bool isFirst = false;\n    static std::once_flag sOnceFlag;\n    std::call_once(sOnceFlag, [&isFirst] { isFirst = true; });\n    _fontManager = snap_drawing::getSkFontMgrSingleton();\n\n    // Query the system for the default font\n    auto skTypeface = sk_sp<SkTypeface>(_fontManager->matchFamilyStyle(nullptr, _defaultFontStyle.getSkValue()));\n    if (skTypeface == nullptr) {\n        // On Android (at least on some devices) the flow lands here, so use the fallback default\n        _defaultFontFamilyName = Valdi::StringCache::makeStringFromCLiteral(kFallbackDefaultFontFamilyName);\n    } else {\n        SkString familyName;\n        skTypeface->getFamilyName(&familyName);\n        _defaultFontFamilyName = Valdi::StringCache::makeStringFromCLiteral(familyName.c_str());\n    }\n    // This will create a FontFamily object for the default font and cache it\n    _typefaceRegistry.getFontFamilyByFamilyName(_defaultFontFamilyName);\n\n    auto families = static_cast<size_t>(_fontManager->countFamilies());\n    for (size_t i = 0; i < families; i++) {\n        auto familyName = getFamilyNameAtIndex(_fontManager.get(), i);\n        _typefaceRegistry.registerFamilyName(familyName);\n    }\n    return isFirst;\n}\n\nstd::vector<String> FontManager::getAvailableFonts() {\n    auto guard = lock();\n    return doGetAvailableFonts(guard);\n}\n\nstd::vector<String> FontManager::doGetAvailableFonts(std::unique_lock<Valdi::Mutex>& /*lock*/) const {\n    return _typefaceRegistry.getAllAvailableTypefaceNames();\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nValdi::Ref<Font> FontManager::getFontWithTypefaceAndSize(std::unique_lock<Valdi::Mutex>& /*lock*/,\n                                                         const Ref<Typeface>& typeface,\n                                                         Scalar fontSize,\n                                                         double scale,\n                                                         bool respectDynamicType) {\n    // TODO(simon): Caching of Font objects\n    auto font = Valdi::makeShared<Font>(\n        Valdi::strongSmallRef(this), Ref<Typeface>(typeface), fontSize, scale, respectDynamicType);\n    return Valdi::Ref<Font>(std::move(font));\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getDefaultFontWithStyle(std::unique_lock<Valdi::Mutex>& lock,\n                                                                     FontStyle fontStyle,\n                                                                     Scalar fontSize,\n                                                                     double scale) {\n    return getFontWithFamilyNameAndStyle(lock, _defaultFontFamilyName, fontStyle, fontSize, scale, true);\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getFont(\n    const Valdi::Ref<Typeface>& typeface, FontStyle fontStyle, Scalar fontSize, double scale, bool respectDynamicType) {\n    auto guard = lock();\n    if (typeface->isCustom()) {\n        // TODO(simon): Is this still necessary now that we have the font family system?\n        return getFontWithTypefaceAndSize(guard, typeface, fontSize, scale, respectDynamicType);\n    } else {\n        return getFontWithFamilyNameAndStyle(\n            guard, typeface->familyName(), fontStyle, fontSize, scale, respectDynamicType);\n    }\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getFontWithFamilyNameAndStyle(std::unique_lock<Valdi::Mutex>& lock,\n                                                                           const String& familyName,\n                                                                           FontStyle fontStyle,\n                                                                           Scalar fontSize,\n                                                                           double scale,\n                                                                           bool respectDynamicType) {\n    auto typeface = _typefaceRegistry.getTypefaceWithFamilyNameAndStyle(*_fontManager, familyName, fontStyle);\n    if (!typeface) {\n        return typeface.moveError();\n    }\n\n    return getFontWithTypefaceAndSize(lock, typeface.value(), fontSize, scale, respectDynamicType);\n}\n\nValdi::Result<Valdi::Ref<Typeface>> FontManager::getTypefaceWithName(const String& fontName) {\n    static auto kSystemFontKey = STRING_LITERAL(\"system\");\n    static auto kSystemFontBoldKey = STRING_LITERAL(\"system-bold\");\n\n    auto guard = lock();\n    if (fontName == kSystemFontKey) {\n        return _typefaceRegistry.getTypefaceWithFamilyNameAndStyle(\n            *_fontManager, _defaultFontFamilyName, _defaultFontStyle);\n    } else if (fontName == kSystemFontBoldKey) {\n        return _typefaceRegistry.getTypefaceWithFamilyNameAndStyle(\n            *_fontManager, _defaultFontFamilyName, FontStyle(FontWidthNormal, FontWeightBold, FontSlantUpright));\n    }\n    FontStyle fontStyle = _defaultFontStyle;\n\n    auto result = _typefaceRegistry.getTypefaceWithName(*_fontManager, fontName, &fontStyle);\n\n    if (result) {\n        return result;\n    }\n\n    onFontResolveFailed(fontName, Valdi::Error(\"Font is not available\"));\n    return _typefaceRegistry.getTypefaceWithFamilyNameAndStyle(*_fontManager, _defaultFontFamilyName, fontStyle);\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getFontWithNameAndSize(const String& fontName,\n                                                                    Scalar fontSize,\n                                                                    double scale,\n                                                                    bool respectDynamicType) {\n    auto typefaceResult = getTypefaceWithName(fontName);\n    if (!typefaceResult) {\n        return typefaceResult.moveError();\n    }\n\n    auto guard = lock();\n\n    return getFontWithTypefaceAndSize(guard, typefaceResult.value(), fontSize, scale, respectDynamicType);\n}\n\nRef<FontFamily> FontManager::onFontFamilyMissing(const String& familyName) {\n    if (_listener != nullptr) {\n        auto loadableTypeface = _listener->resolveTypefaceWithName(familyName);\n        if (loadableTypeface != nullptr) {\n            auto family = makeShared<FontFamilyWithLoadableTypefaces>(_logger, familyName);\n            // TODO(simon): This is hardcoded to have a single font style per family name, which\n            // is not super flexible. We might need to improve this later.\n            family->registerLoadableTypeface(FontStyle(FontWidthNormal, FontWeightNormal, FontSlantUpright),\n                                             loadableTypeface);\n            return family;\n        }\n    }\n\n    const sk_sp<SkFontStyleSet> styleSet(_fontManager->matchFamily(familyName.getCStr()));\n    if (styleSet == nullptr || styleSet->count() == 0) {\n        return nullptr;\n    }\n\n    return Valdi::makeShared<FontFamilyWithStyleSet>(styleSet, familyName);\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getFontWithFamilyNameAndStyle(\n    const String& familyName, FontStyle fontStyle, Scalar fontSize, double scale, bool respectDynamicType) {\n    auto guard = lock();\n    return getFontWithFamilyNameAndStyle(guard, familyName, fontStyle, fontSize, scale, respectDynamicType);\n}\n\nValdi::Result<Valdi::Ref<Typeface>> FontManager::getTypefaceWithFamilyNameAndStyle(const String& familyName,\n                                                                                   FontStyle fontStyle) {\n    auto guard = lock();\n    return _typefaceRegistry.getTypefaceWithFamilyNameAndStyle(*_fontManager, familyName, fontStyle);\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getCompatibleFont(const Ref<Font>& originalFont,\n                                                               const char** bcp47,\n                                                               size_t bcp47Count,\n                                                               Character character) {\n    return getCompatibleFont(originalFont->typeface()->familyName(),\n                             originalFont->style(),\n                             originalFont->size(),\n                             originalFont->scale(),\n                             bcp47,\n                             bcp47Count,\n                             character);\n}\n\nRef<FontFamily> FontManager::resolveFallbackFontFamilyForCharacter(std::unique_lock<Valdi::Mutex>& /*lock*/,\n                                                                   Character character) {\n    auto fontFamily = _typefaceRegistry.getFontFamilyForCharacterAndStyle(*_fontManager, character, _defaultFontStyle);\n    if (fontFamily != nullptr) {\n        return fontFamily;\n    }\n\n    VALDI_TRACE(\"SnapDrawing.matchFamilyStyleCharacter\");\n    auto skTypeface =\n        sk_sp<SkTypeface>(_fontManager->matchFamilyStyleCharacter(nullptr, SkFontStyle(), nullptr, 0, character));\n    if (skTypeface == nullptr) {\n        return nullptr;\n    }\n\n    SkString skFamilyName;\n    skTypeface->getFamilyName(&skFamilyName);\n    auto resolvedFamilyname = Valdi::StringCache::getGlobal().makeStringFromLiteral(skFamilyName.c_str());\n\n    return _typefaceRegistry.getFontFamilyByFamilyName(resolvedFamilyname);\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getCompatibleFont(const String& /*familyName*/,\n                                                               FontStyle fontStyle,\n                                                               Scalar fontSize,\n                                                               double scale,\n                                                               const char** /*bcp47*/,\n                                                               size_t /*bcp47Count*/,\n                                                               Character character) {\n    auto guard = lock();\n    const auto& it = _fallbackFontFamilies.find(character);\n    if (it != _fallbackFontFamilies.end()) {\n        return getFontFromFamily(guard, it->second, fontStyle, fontSize, scale, true);\n    }\n\n    auto fontFamily = resolveFallbackFontFamilyForCharacter(guard, character);\n    _fallbackFontFamilies[character] = fontFamily;\n\n    return getFontFromFamily(guard, fontFamily, fontStyle, fontSize, scale, true);\n}\n\nValdi::Result<Ref<Font>> FontManager::getEmojiFont(Scalar fontSize, double scale) {\n    Character emoji = 0x270C;\n    return getCompatibleFont(String(), _defaultFontStyle, fontSize, scale, nullptr, 0, emoji);\n}\n\nRef<IFontManager> FontManager::makeScoped() {\n    return Valdi::makeShared<ScopedFontManager>(*getSkValue(), _logger, Valdi::strongSmallRef(this));\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getFontFromFamily(std::unique_lock<Valdi::Mutex>& lock,\n                                                               const Ref<FontFamily>& fontFamily,\n                                                               FontStyle fontStyle,\n                                                               Scalar fontSize,\n                                                               double scale,\n                                                               bool respectDynamicType) {\n    auto typeface = _typefaceRegistry.getTypefaceFromFamily(*_fontManager, fontFamily, fontStyle);\n    if (!typeface) {\n        return typeface.moveError();\n    }\n\n    return getFontWithTypefaceAndSize(lock, typeface.value(), fontSize, scale, respectDynamicType);\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getFontForName(const String& fontName, double scale) {\n    auto components = fontName.split(' ', true);\n\n    if (components.size() == 1) {\n        auto guard = lock();\n        if (components[0] == \"title1\") {\n            return getDefaultFontWithStyle(guard, _defaultFontStyle, 25, scale);\n        } else if (components[0] == \"title2\") {\n            return getDefaultFontWithStyle(guard, _defaultFontStyle, 19, scale);\n        } else if (components[0] == \"title3\") {\n            return getDefaultFontWithStyle(guard, _defaultFontStyle, 17, scale);\n        } else if (components[0] == \"body\") {\n            return getDefaultFontWithStyle(guard, _defaultFontStyle, 14, scale);\n        }\n    }\n\n    double fontSize = 12;\n    bool respectDynamicType = true;\n    auto fontNamePart = components[0];\n\n    if (components.size() >= 2) {\n        fontSize = Valdi::Value(components[1]).toDouble();\n        if (components.size() >= 3 && components[2].lowercased() == \"unscaled\") {\n            respectDynamicType = false;\n        }\n    }\n\n    return getFontWithNameAndSize(fontNamePart, static_cast<Scalar>(fontSize), scale, respectDynamicType);\n}\n\nValdi::Result<Ref<Font>> FontManager::getDefaultFont() {\n    auto guard = lock();\n    return getDefaultFontWithStyle(guard, _defaultFontStyle, 12, 1.0);\n}\n\nValdi::Result<Valdi::Ref<Font>> FontManager::getDefaultFont(Scalar fontSize, double scale) {\n    auto guard = lock();\n    return getDefaultFontWithStyle(guard, _defaultFontStyle, fontSize, scale);\n}\n\nvoid FontManager::registerTypeface(const String& fontFamilyName,\n                                   FontStyle fontStyle,\n                                   bool canUseAsFallback,\n                                   const Valdi::BytesView& fontData) {\n    registerTypeface(\n        fontFamilyName, fontStyle, canUseAsFallback, LoadableTypeface::fromBytes(fontFamilyName, fontData));\n}\n\nvoid FontManager::registerTypeface(const String& fontFamilyName,\n                                   FontStyle fontStyle,\n                                   bool canUseAsFallback,\n                                   const Ref<LoadableTypeface>& loadableTypeface) {\n    auto guard = lock(/* shouldInitIfNeeded */ false, nullptr);\n    _typefaceRegistry.registerTypeface(fontFamilyName, fontStyle, canUseAsFallback, loadableTypeface);\n    // Clear fallback font family cache, so that we can pickup our new typeface\n    _fallbackFontFamilies.clear();\n}\n\nvoid FontManager::onFontResolveFailed(const String& fontName, const Valdi::Error& error) {\n    VALDI_ERROR(_logger, \"Failed to resolve font '{}': {}\", fontName, error);\n}\n\nconst Ref<TextShaper>& FontManager::getTextShaper() const {\n    return _textShaper;\n}\n\nconst sk_sp<SkFontMgr>& FontManager::getSkValue() {\n    auto guard = lock();\n    return _fontManager;\n}\n\nvoid FontManager::setListener(const Ref<IFontManagerListener>& listener) {\n    auto guard = lock(/* shouldInitIfNeeded */ false, nullptr);\n    _listener = listener;\n}\n\nstd::unique_lock<Valdi::Mutex> FontManager::lock() {\n    return lock(true, nullptr);\n}\n\nstd::unique_lock<Valdi::Mutex> FontManager::lock(bool shouldInitIfNeeded, bool* didInit) {\n    auto lock = std::unique_lock<Valdi::Mutex>(_mutex);\n    auto alreadyInitialized = _fontManager != nullptr;\n    if (!alreadyInitialized && shouldInitIfNeeded) {\n        alreadyInitialized = !doLoad(lock);\n    }\n\n    if (didInit != nullptr) {\n        *didInit = !alreadyInitialized;\n    }\n    return lock;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontManager.hpp",
    "content": "//\n//  FontManager.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Character.hpp\"\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n#include \"snap_drawing/cpp/Text/IFontManager.hpp\"\n#include \"snap_drawing/cpp/Text/LoadableTypeface.hpp\"\n#include \"snap_drawing/cpp/Text/TypefaceRegistry.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\n#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include \"valdi_core/cpp/Utils/StringBox.hpp\"\n\n#include \"include/core/SkFontMgr.h\"\n\n#include <optional>\n#include <vector>\n\nnamespace Valdi {\nclass ILogger;\n}\n\nnamespace snap::drawing {\n\nclass TextShaper;\nclass FontFamily;\nclass FontFamilyWithLoadableTypefaces;\n\nstruct LoadResult {\n    std::vector<String> availableFonts;\n    bool activeInitialization;\n};\n\nclass IFontManagerListener : public Valdi::SimpleRefCountable {\npublic:\n    virtual Ref<LoadableTypeface> resolveTypefaceWithName(const String& name) = 0;\n};\n\nclass FontManager : public IFontManager, protected ITypefaceRegistryListener {\npublic:\n    FontManager(Valdi::ILogger& logger, bool enableTextShaperCache = true);\n    ~FontManager() override;\n\n    /**\n     * Calling load() can result with either active or passive initialization of Skia's font manager.\n     * An active initialization is the first initialization which may be computation/io intensive depending on the\n     * underlying platform. A passive initialization is a consecutive initialization that relies on data collected\n     * in the active initialization and is *not* computation intensive.\n     *\n     * @return pair of available font families and whether Skia's initialization was active or not.\n     * The active/passive initialization is used for metrics reporting purposes only.\n     */\n    LoadResult load();\n\n    std::vector<String> getAvailableFonts();\n\n    Valdi::Result<Valdi::Ref<Font>> getFontForName(const String& fontName, double scale);\n    Valdi::Result<Valdi::Ref<Font>> getFontWithNameAndSize(const String& fontName,\n                                                           Scalar fontSize,\n                                                           double scale,\n                                                           bool respectDynamicType);\n    Valdi::Result<Valdi::Ref<Typeface>> getTypefaceWithName(const String& fontName) override;\n    Valdi::Result<Valdi::Ref<Font>> getFontWithFamilyNameAndStyle(\n        const String& familyName, FontStyle fontStyle, Scalar fontSize, double scale, bool respectDynamicType);\n\n    Valdi::Result<Valdi::Ref<Typeface>> getTypefaceWithFamilyNameAndStyle(const String& familyName,\n                                                                          FontStyle fontStyle) override;\n\n    Valdi::Result<Valdi::Ref<Font>> getDefaultFont();\n    Valdi::Result<Valdi::Ref<Font>> getDefaultFont(Scalar fontSize, double scale);\n\n    Valdi::Result<Ref<Font>> getFont(const Ref<Typeface>& typeface,\n                                     FontStyle fontStyle,\n                                     Scalar fontSize,\n                                     double scale,\n                                     bool respectDynamicType) override;\n    Valdi::Result<Ref<Font>> getCompatibleFont(const Ref<Font>& originalFont,\n                                               const char** bcp47,\n                                               size_t bcp47Count,\n                                               Character character);\n    Valdi::Result<Ref<Font>> getCompatibleFont(const String& familyName,\n                                               FontStyle fontStyle,\n                                               Scalar fontSize,\n                                               double scale,\n                                               const char** bcp47,\n                                               size_t bcp47Count,\n                                               Character character);\n\n    Valdi::Result<Ref<Font>> getEmojiFont(Scalar fontSize, double scale);\n\n    Ref<IFontManager> makeScoped() override;\n\n    void registerTypeface(const String& fontFamilyName,\n                          FontStyle fontStyle,\n                          bool canUseAsFallback,\n                          const Valdi::BytesView& fontData);\n\n    void registerTypeface(const String& fontFamilyName,\n                          FontStyle fontStyle,\n                          bool canUseAsFallback,\n                          const Ref<LoadableTypeface>& loadableTypeface) override;\n\n    const Ref<TextShaper>& getTextShaper() const;\n\n    const sk_sp<SkFontMgr>& getSkValue();\n\n    void setListener(const Ref<IFontManagerListener>& listener);\n\nprotected:\n    Ref<FontFamily> onFontFamilyMissing(const String& familyName) override;\n\nprivate:\n    mutable Valdi::Mutex _mutex;\n    [[maybe_unused]] Valdi::ILogger& _logger;\n    sk_sp<SkFontMgr> _fontManager;\n\n    TypefaceRegistry _typefaceRegistry;\n    Valdi::FlatMap<Character, Ref<FontFamily>> _fallbackFontFamilies;\n    FontStyle _defaultFontStyle;\n    Ref<TextShaper> _textShaper;\n    Valdi::StringBox _defaultFontFamilyName;\n    Ref<IFontManagerListener> _listener;\n\n    std::unique_lock<Valdi::Mutex> lock();\n    std::unique_lock<Valdi::Mutex> lock(bool shouldInitIfNeeded, bool* didInit);\n\n    Valdi::Result<Valdi::Ref<Font>> getDefaultFontWithStyle(std::unique_lock<Valdi::Mutex>& lock,\n                                                            FontStyle fontStyle,\n                                                            Scalar fontSize,\n                                                            double scale);\n\n    Ref<FontFamily> resolveFallbackFontFamilyForCharacter(std::unique_lock<Valdi::Mutex>& lock, Character character);\n    Valdi::Result<Valdi::Ref<Font>> getFontFromFamily(std::unique_lock<Valdi::Mutex>& lock,\n                                                      const Ref<FontFamily>& fontFamily,\n                                                      FontStyle fontStyle,\n                                                      Scalar fontSize,\n                                                      double scale,\n                                                      bool respectDynamicType);\n    Valdi::Result<Valdi::Ref<Font>> getFontWithFamilyNameAndStyle(std::unique_lock<Valdi::Mutex>& lock,\n                                                                  const String& familyName,\n                                                                  FontStyle fontStyle,\n                                                                  Scalar fontSize,\n                                                                  double scale,\n                                                                  bool respectDynamicType);\n\n    void onFontResolveFailed(const String& fontName, const Valdi::Error& error);\n    std::vector<String> doGetAvailableFonts(std::unique_lock<Valdi::Mutex>& lock) const;\n\n    bool doLoad(std::unique_lock<Valdi::Mutex>& lock);\n\n    Valdi::Ref<Font> getFontWithTypefaceAndSize(std::unique_lock<Valdi::Mutex>& /*lock*/,\n                                                const Ref<Typeface>& typeface,\n                                                Scalar fontSize,\n                                                double scale,\n                                                bool respectDynamicType);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontMetrics.hpp",
    "content": "//\n//  FontMetrics.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/14/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n\nnamespace snap::drawing {\n\nstruct FontMetrics {\n    Scalar lineSpacing = 0.0f;\n    Scalar ascent = 0.0f;\n    Scalar descent = 0.0f;\n    Scalar underlineThickness = 0.0f; //!< underline thickness\n    Scalar underlinePosition = 0.0f;  //!< distance from baseline to top of stroke, typically positive\n    Scalar strikeoutThickness = 0.0f; //!< strikeout thickness\n    Scalar strikeoutPosition = 0.0f;  //!< distance from baseline to bottom of stroke, typically negative\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontStyle.cpp",
    "content": "//\n//  FontStyle.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"snap_drawing/cpp/Text/FontStyle.hpp\"\n#include \"valdi_core/cpp/Utils/Format.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include \"valdi_core/cpp/Utils/StringBox.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\nnamespace snap::drawing {\n\nstatic inline FontWeight fromSkiaWeight(int weight) {\n    switch (weight) {\n        case SkFontStyle::kInvisible_Weight:\n            return FontWeightInvisible;\n        case SkFontStyle::kThin_Weight:\n            return FontWeightThin;\n        case SkFontStyle::kExtraLight_Weight:\n            return FontWeightExtraLight;\n        case SkFontStyle::kLight_Weight:\n            return FontWeightLight;\n        case SkFontStyle::kNormal_Weight:\n            return FontWeightNormal;\n        case SkFontStyle::kMedium_Weight:\n            return FontWeightMedium;\n        case SkFontStyle::kSemiBold_Weight:\n            return FontWeightSemiBold;\n        case SkFontStyle::kBold_Weight:\n            return FontWeightBold;\n        case SkFontStyle::kExtraBold_Weight:\n            return FontWeightExtraBold;\n        case SkFontStyle::kBlack_Weight:\n            return FontWeightBlack;\n        case SkFontStyle::kExtraBlack_Weight:\n            return FontWeightExtraBlack;\n    }\n    return FontWeightNormal;\n}\n\nstatic inline FontWidth fromSkiaWidth(int width) {\n    switch (width) {\n        case SkFontStyle::kUltraCondensed_Width:\n            return FontWidthUltraCondensed;\n        case SkFontStyle::kExtraCondensed_Width:\n            return FontWidthExtraCondensed;\n        case SkFontStyle::kCondensed_Width:\n            return FontWidthCondensed;\n        case SkFontStyle::kSemiCondensed_Width:\n            return FontWidthSemiCondensed;\n        case SkFontStyle::kNormal_Width:\n            return FontWidthNormal;\n        case SkFontStyle::kSemiExpanded_Width:\n            return FontWidthSemiExpanded;\n        case SkFontStyle::kExpanded_Width:\n            return FontWidthExpanded;\n        case SkFontStyle::kExtraExpanded_Width:\n            return FontWidthExtraExpanded;\n        case SkFontStyle::kUltraExpanded_Width:\n            return FontWidthUltraExpanded;\n    }\n    return FontWidthNormal;\n}\n\nstatic inline FontSlant fromSkiaSlant(SkFontStyle::Slant slant) {\n    switch (slant) {\n        case SkFontStyle::kUpright_Slant:\n            return FontSlantUpright;\n        case SkFontStyle::kItalic_Slant:\n            return FontSlantItalic;\n        case SkFontStyle::kOblique_Slant:\n            return FontSlantOblique;\n    }\n}\n\nstatic inline SkFontStyle::Weight toSkiaWeight(FontWeight weight) {\n    switch (weight) {\n        case FontWeightInvisible:\n            return SkFontStyle::kInvisible_Weight;\n        case FontWeightThin:\n            return SkFontStyle::kThin_Weight;\n        case FontWeightExtraLight:\n            return SkFontStyle::kExtraLight_Weight;\n        case FontWeightLight:\n            return SkFontStyle::kLight_Weight;\n        case FontWeightNormal:\n            return SkFontStyle::kNormal_Weight;\n        case FontWeightMedium:\n            return SkFontStyle::kMedium_Weight;\n        case FontWeightSemiBold:\n            return SkFontStyle::kSemiBold_Weight;\n        case FontWeightBold:\n            return SkFontStyle::kBold_Weight;\n        case FontWeightExtraBold:\n            return SkFontStyle::kExtraBold_Weight;\n        case FontWeightBlack:\n            return SkFontStyle::kBlack_Weight;\n        case FontWeightExtraBlack:\n            return SkFontStyle::kExtraBlack_Weight;\n    }\n}\n\nstatic inline SkFontStyle::Width toSkiaWidth(FontWidth width) {\n    switch (width) {\n        case FontWidthUltraCondensed:\n            return SkFontStyle::kUltraCondensed_Width;\n        case FontWidthExtraCondensed:\n            return SkFontStyle::kExtraCondensed_Width;\n        case FontWidthCondensed:\n            return SkFontStyle::kCondensed_Width;\n        case FontWidthSemiCondensed:\n            return SkFontStyle::kSemiCondensed_Width;\n        case FontWidthNormal:\n            return SkFontStyle::kNormal_Width;\n        case FontWidthSemiExpanded:\n            return SkFontStyle::kSemiExpanded_Width;\n        case FontWidthExpanded:\n            return SkFontStyle::kExpanded_Width;\n        case FontWidthExtraExpanded:\n            return SkFontStyle::kExtraExpanded_Width;\n        case FontWidthUltraExpanded:\n            return SkFontStyle::kUltraExpanded_Width;\n    }\n}\n\nstatic inline SkFontStyle::Slant toSkiaSlant(FontSlant slant) {\n    switch (slant) {\n        case FontSlantUpright:\n            return SkFontStyle::kUpright_Slant;\n        case FontSlantItalic:\n            return SkFontStyle::kItalic_Slant;\n        case FontSlantOblique:\n            return SkFontStyle::kOblique_Slant;\n    }\n}\n\nFontStyle::FontStyle(FontWidth width, FontWeight weight, FontSlant slant)\n    : _width(width), _weight(weight), _slant(slant) {}\n\nFontStyle::FontStyle(SkFontStyle skFontStyle)\n    : _width(fromSkiaWidth(skFontStyle.width())),\n      _weight(fromSkiaWeight(skFontStyle.weight())),\n      _slant(fromSkiaSlant(skFontStyle.slant())) {}\n\nFontWidth FontStyle::getWidth() const {\n    return _width;\n}\n\nvoid FontStyle::setWidth(FontWidth width) {\n    _width = width;\n}\n\nFontWeight FontStyle::getWeight() const {\n    return _weight;\n}\n\nvoid FontStyle::setWeight(FontWeight weight) {\n    _weight = weight;\n}\n\nValdi::StringBox FontStyle::fontWeightToString(FontWeight fontWeight) {\n    static auto kWeightInvisible = STRING_LITERAL(\"invisible\");\n    static auto kWeightThin = STRING_LITERAL(\"thin\");\n    static auto kWeightExtraLight = STRING_LITERAL(\"extralight\");\n    static auto kWeightLight = STRING_LITERAL(\"light\");\n    static auto kWeightNormal = STRING_LITERAL(\"normal\");\n    static auto kWeightMedium = STRING_LITERAL(\"medium\");\n    static auto kWeightSemiBold = STRING_LITERAL(\"semibold\");\n    static auto kWeightBold = STRING_LITERAL(\"bold\");\n    static auto kWeightExtraBold = STRING_LITERAL(\"extrabold\");\n    static auto kWeightBlack = STRING_LITERAL(\"black\");\n    static auto kWeightExtraBlack = STRING_LITERAL(\"extrablack\");\n\n    switch (fontWeight) {\n        case FontWeightInvisible:\n            return kWeightInvisible;\n        case FontWeightThin:\n            return kWeightThin;\n        case FontWeightExtraLight:\n            return kWeightExtraLight;\n        case FontWeightLight:\n            return kWeightLight;\n        case FontWeightNormal:\n            return kWeightNormal;\n        case FontWeightMedium:\n            return kWeightMedium;\n        case FontWeightSemiBold:\n            return kWeightSemiBold;\n        case FontWeightBold:\n            return kWeightBold;\n        case FontWeightExtraBold:\n            return kWeightExtraBold;\n        case FontWeightBlack:\n            return kWeightBlack;\n        case FontWeightExtraBlack:\n            return kWeightExtraBlack;\n    }\n}\n\nValdi::Result<std::pair<Valdi::StringBox, FontWeight>> FontStyle::getFamilyNameAndFontWeight(\n    const Valdi::StringBox& fontName) {\n    auto fontKey = fontName;\n    auto fontWeight = FontWeightNormal;\n    auto separatorIndex = fontName.lastIndexOf('-');\n    if (separatorIndex) {\n        auto components = fontName.split(*separatorIndex);\n        fontKey = components.first;\n\n        auto fontWeightResult = parseWeight(components.second.toStringView());\n        if (!fontWeightResult) {\n            return fontWeightResult.moveError();\n        }\n        fontWeight = fontWeightResult.value();\n    }\n    return std::pair<Valdi::StringBox, FontWeight>(fontKey, fontWeight);\n}\n\nValdi::Result<FontWeight> FontStyle::parseWeight(std::string_view weightStr) {\n    if (weightStr == \"light\") {\n        return FontWeightLight;\n    } else if (weightStr == \"regular\" || weightStr == \"normal\") {\n        return FontWeightNormal;\n    } else if (weightStr == \"medium\") {\n        return FontWeightMedium;\n    } else if (weightStr == \"semibold\" || weightStr == \"demibold\" || weightStr == \"demi-bold\") {\n        return FontWeightSemiBold;\n    } else if (weightStr == \"bold\") {\n        return FontWeightBold;\n    } else if (weightStr == \"black\") {\n        return FontWeightBlack;\n    } else {\n        return Valdi::Error(STRING_FORMAT(\"Could not resolve weight '{}'\", weightStr));\n    }\n}\n\nValdi::Result<FontSlant> FontStyle::parseSlant(std::string_view slantStr) {\n    if (slantStr == \"normal\" || slantStr == \"upright\") {\n        return FontSlantUpright;\n    } else if (slantStr == \"italic\") {\n        return FontSlantItalic;\n    } else if (slantStr == \"oblique\") {\n        return FontSlantOblique;\n    } else {\n        return Valdi::Error(STRING_FORMAT(\"Could not resolve slant '{}'\", slantStr));\n    }\n}\n\nFontSlant FontStyle::getSlant() const {\n    return _slant;\n}\n\nvoid FontStyle::setSlant(FontSlant slant) {\n    _slant = slant;\n}\n\nsize_t FontStyle::hash() const {\n    return static_cast<size_t>(_width) | static_cast<size_t>(_weight) << 8 | static_cast<size_t>(_slant) << 16;\n}\n\nbool FontStyle::operator==(const FontStyle& other) const {\n    return _width == other._width && _weight == other._weight && _slant == other._slant;\n}\n\nbool FontStyle::operator!=(const FontStyle& other) const {\n    return !(*this == other);\n}\n\nSkFontStyle FontStyle::getSkValue() const {\n    return SkFontStyle(toSkiaWeight(_weight), toSkiaWidth(_width), toSkiaSlant(_slant));\n}\n\n} // namespace snap::drawing\n\nnamespace std {\n\nstd::size_t hash<snap::drawing::FontStyle>::operator()(const snap::drawing::FontStyle& k) const noexcept {\n    return k.hash();\n}\n\n} // namespace std\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/FontStyle.hpp",
    "content": "//\n//  FontStyle.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include \"include/core/SkFontStyle.h\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include \"valdi_core/cpp/Utils/StringBox.hpp\"\n#include <functional>\n\nnamespace snap::drawing {\n\nenum FontWidth : uint8_t {\n    FontWidthUltraCondensed,\n    FontWidthExtraCondensed,\n    FontWidthCondensed,\n    FontWidthSemiCondensed,\n    FontWidthNormal,\n    FontWidthSemiExpanded,\n    FontWidthExpanded,\n    FontWidthExtraExpanded,\n    FontWidthUltraExpanded,\n};\n\nenum FontWeight : uint8_t {\n    FontWeightInvisible,\n    FontWeightThin,\n    FontWeightExtraLight,\n    FontWeightLight,\n    FontWeightNormal,\n    FontWeightMedium,\n    FontWeightSemiBold,\n    FontWeightBold,\n    FontWeightExtraBold,\n    FontWeightBlack,\n    FontWeightExtraBlack,\n};\n\nenum FontSlant : uint8_t {\n    FontSlantUpright,\n    FontSlantItalic,\n    FontSlantOblique,\n};\n\nclass FontStyle {\npublic:\n    FontStyle(FontWidth width, FontWeight weight, FontSlant slant);\n    explicit FontStyle(SkFontStyle skFontStyle);\n\n    FontWidth getWidth() const;\n    void setWidth(FontWidth width);\n\n    FontWeight getWeight() const;\n    void setWeight(FontWeight weight);\n\n    static Valdi::StringBox fontWeightToString(FontWeight fontWeight);\n\n    static Valdi::Result<std::pair<Valdi::StringBox, FontWeight>> getFamilyNameAndFontWeight(\n        const Valdi::StringBox& fontName);\n\n    FontSlant getSlant() const;\n    void setSlant(FontSlant slant);\n\n    SkFontStyle getSkValue() const;\n\n    size_t hash() const;\n\n    bool operator==(const FontStyle& other) const;\n    bool operator!=(const FontStyle& other) const;\n\n    static Valdi::Result<FontWeight> parseWeight(std::string_view weightStr);\n    static Valdi::Result<FontSlant> parseSlant(std::string_view slantStr);\n\nprivate:\n    FontWidth _width;\n    FontWeight _weight;\n    FontSlant _slant;\n};\n\n} // namespace snap::drawing\n\nnamespace std {\n\ntemplate<>\nstruct hash<snap::drawing::FontStyle> {\n    std::size_t operator()(const snap::drawing::FontStyle& k) const noexcept;\n};\n\n} // namespace std\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Harfbuzz.cpp",
    "content": "//\n//  Harfbuzz.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 10/18/22.\n//\n\n#include \"snap_drawing/cpp/Text/Harfbuzz.hpp\"\n#include \"valdi_core/cpp/Text/CharacterSet.hpp\"\n\n#include \"include/core/SkData.h\"\n#include \"include/core/SkFont.h\"\n#include \"include/core/SkFontTypes.h\"\n#include \"include/core/SkTypeface.h\"\n#include \"include/private/base/SkTemplates.h\"\n\n#include \"hb-ot.h\"\n#include \"hb.h\"\n\nnamespace snap::drawing {\n\nHBBlob::HBBlob(HBBlob&& other) noexcept : HBResource<hb_blob_t>(other._ptr) {\n    other._ptr = nullptr;\n}\n\nHBBlob::~HBBlob() {\n    if (_ptr) {\n        hb_blob_destroy(_ptr);\n    }\n}\n\nHBBlob& HBBlob::operator=(HBBlob&& other) noexcept {\n    if (_ptr) {\n        hb_blob_destroy(_ptr);\n        _ptr = nullptr;\n    }\n\n    std::swap(_ptr, other._ptr);\n\n    return *this;\n}\n\nHBFace::HBFace(HBFace&& other) noexcept : HBResource<hb_face_t>(other._ptr) {\n    other._ptr = nullptr;\n}\n\nHBFace::~HBFace() {\n    if (_ptr) {\n        hb_face_destroy(_ptr);\n    }\n}\n\nHBFace& HBFace::operator=(HBFace&& other) noexcept {\n    if (_ptr) {\n        hb_face_destroy(_ptr);\n        _ptr = nullptr;\n    }\n\n    std::swap(_ptr, other._ptr);\n\n    return *this;\n}\n\nstatic size_t countRanges(hb_set_t* set) {\n    hb_codepoint_t first = 0;\n    hb_codepoint_t last = HB_SET_VALUE_INVALID;\n    size_t rangesCount = 0;\n\n    while (hb_set_next_range(set, &first, &last) != 0) {\n        rangesCount++;\n    }\n\n    return rangesCount;\n}\n\nRef<Valdi::CharacterSet> HBFace::getCharacters() {\n    auto* set = hb_set_create();\n    hb_face_collect_unicodes(_ptr, set);\n\n    std::vector<Valdi::CharacterRange> ranges;\n    ranges.reserve(countRanges(set));\n\n    hb_codepoint_t first = 0;\n    hb_codepoint_t last = HB_SET_VALUE_INVALID;\n\n    while (hb_set_next_range(set, &first, &last) != 0) {\n        ranges.emplace_back(static_cast<uint32_t>(first), static_cast<uint32_t>(last));\n    }\n\n    hb_set_destroy(set);\n\n    return Valdi::CharacterSet::make(ranges.data(), ranges.size());\n}\n\nHBFont::HBFont(HBFont&& other) noexcept : HBResource<hb_font_t>(other._ptr) {\n    other._ptr = nullptr;\n}\n\nHBFont::~HBFont() {\n    if (_ptr) {\n        hb_font_destroy(_ptr);\n    }\n}\n\nHBFont& HBFont::operator=(HBFont&& other) noexcept {\n    if (_ptr) {\n        hb_font_destroy(_ptr);\n        _ptr = nullptr;\n    }\n\n    std::swap(_ptr, other._ptr);\n\n    return *this;\n}\n\nHBBuffer::HBBuffer(HBBuffer&& other) noexcept : HBResource<hb_buffer_t>(other._ptr) {\n    other._ptr = nullptr;\n}\n\nHBBuffer::~HBBuffer() {\n    if (_ptr) {\n        hb_buffer_destroy(_ptr);\n    }\n}\n\nHBBuffer& HBBuffer::operator=(HBBuffer&& other) noexcept {\n    if (_ptr) {\n        hb_buffer_destroy(_ptr);\n        _ptr = nullptr;\n    }\n\n    std::swap(_ptr, other._ptr);\n\n    return *this;\n}\n\nstatic hb_position_t sskhbPosition(SkScalar value) {\n    // Treat HarfBuzz hb_position_t as 16.16 fixed-point.\n    constexpr int kHbPosition1 = 1 << 16;\n    return SkScalarRoundToInt(value * kHbPosition1);\n}\n\nstatic hb_bool_t skhbGlyph(hb_font_t* /*hbFont*/,\n                           void* fontData,\n                           hb_codepoint_t unicode,\n                           hb_codepoint_t /*variantionSelector*/,\n                           hb_codepoint_t* glyph,\n                           void* /*userData*/) {\n    SkFont& font = *reinterpret_cast<SkFont*>(fontData);\n\n    *glyph = font.unicharToGlyph(unicode);\n    return static_cast<hb_bool_t>(*glyph != 0);\n}\n\nstatic hb_bool_t skhbNominalGlyph(\n    hb_font_t* hbFont, void* fontData, hb_codepoint_t unicode, hb_codepoint_t* glyph, void* userData) {\n    return skhbGlyph(hbFont, fontData, unicode, 0, glyph, userData);\n}\n\nstatic unsigned skhbNominalGlyphs(hb_font_t* /*hbFont*/,\n                                  void* fontData,\n                                  unsigned int count,\n                                  const hb_codepoint_t* unicodes,\n                                  unsigned int unicodeStride,\n                                  hb_codepoint_t* glyphs,\n                                  unsigned int glyphStride,\n                                  void* /*userData*/) {\n    SkFont& font = *reinterpret_cast<SkFont*>(fontData);\n\n    // Batch call textToGlyphs since entry cost is not cheap.\n    // Copy requred because textToGlyphs is dense and hb is strided.\n    skia_private::AutoSTMalloc<256, SkUnichar> unicode(count);\n    for (unsigned i = 0; i < count; i++) {\n        unicode[i] = *unicodes;\n        unicodes = SkTAddOffset<const hb_codepoint_t>(unicodes, unicodeStride);\n    }\n    skia_private::AutoSTMalloc<256, SkGlyphID> glyph(count);\n    font.textToGlyphs(unicode.get(), count * sizeof(SkUnichar), SkTextEncoding::kUTF32, glyph.get(), count);\n\n    // Copy the results back to the sparse array.\n    unsigned int done;\n    for (done = 0; done < count && glyph[done] != 0; done++) {\n        *glyphs = glyph[done];\n        glyphs = SkTAddOffset<hb_codepoint_t>(glyphs, glyphStride);\n    }\n    // return 'done' to allow HarfBuzz to synthesize with NFC and spaces, return 'count' to avoid\n    return done;\n}\n\nstatic hb_position_t skhbGlyphHAdvance(hb_font_t* /*hbFont*/,\n                                       void* fontData,\n                                       hb_codepoint_t hbGlyph,\n                                       void* /*userData*/) {\n    SkFont& font = *reinterpret_cast<SkFont*>(fontData);\n\n    SkScalar advance;\n    auto skGlyph = SkTo<SkGlyphID>(hbGlyph);\n\n    font.getWidths(&skGlyph, 1, &advance);\n    if (!font.isSubpixel()) {\n        advance = SkScalarRoundToInt(advance);\n    }\n    return sskhbPosition(advance);\n}\n\nstatic void skhbGlyphHAdvances(hb_font_t* /*hbFont*/,\n                               void* fontData,\n                               unsigned count,\n                               const hb_codepoint_t* glyphs,\n                               unsigned int glyphStride,\n                               hb_position_t* advances,\n                               unsigned int advanceStride,\n                               void* /*userData*/) {\n    SkFont& font = *reinterpret_cast<SkFont*>(fontData);\n\n    // Batch call getWidths since entry cost is not cheap.\n    // Copy requred because getWidths is dense and hb is strided.\n    skia_private::AutoSTMalloc<256, SkGlyphID> glyph(count);\n    for (unsigned i = 0; i < count; i++) {\n        glyph[i] = *glyphs;\n        glyphs = SkTAddOffset<const hb_codepoint_t>(glyphs, glyphStride);\n    }\n    skia_private::AutoSTMalloc<256, SkScalar> advance(count);\n    font.getWidths(glyph.get(), count, advance.get());\n\n    if (!font.isSubpixel()) {\n        for (unsigned i = 0; i < count; i++) {\n            advance[i] = SkScalarRoundToInt(advance[i]);\n        }\n    }\n\n    // Copy the results back to the sparse array.\n    for (unsigned i = 0; i < count; i++) {\n        *advances = sskhbPosition(advance[i]);\n        advances = SkTAddOffset<hb_position_t>(advances, advanceStride);\n    }\n}\n\n// HarfBuzz callback to retrieve glyph extents, mainly used by HarfBuzz for\n// fallback mark positioning, i.e. the situation when the font does not have\n// mark anchors or other mark positioning rules, but instead HarfBuzz is\n// supposed to heuristically place combining marks around base glyphs. HarfBuzz\n// does this by measuring \"ink boxes\" of glyphs, and placing them according to\n// Unicode mark classes. Above, below, centered or left or right, etc.\nstatic hb_bool_t skhbGlyphExtents(\n    hb_font_t* /*hbFont*/, void* fontData, hb_codepoint_t hbGlyph, hb_glyph_extents_t* extents, void* /*userData*/) {\n    SkFont& font = *reinterpret_cast<SkFont*>(fontData);\n\n    SkRect skBounds;\n    auto skGlyph = SkTo<SkGlyphID>(hbGlyph);\n\n    font.getWidths(&skGlyph, 1, nullptr, &skBounds);\n    if (!font.isSubpixel()) {\n        skBounds.set(skBounds.roundOut());\n    }\n\n    // Skia is y-down but HarfBuzz is y-up.\n    extents->x_bearing = sskhbPosition(skBounds.fLeft);\n    extents->y_bearing = sskhbPosition(-skBounds.fTop);\n    extents->width = sskhbPosition(skBounds.width());\n    extents->height = sskhbPosition(-skBounds.height());\n    return static_cast<hb_bool_t>(true);\n}\n\nstatic hb_font_funcs_t* skhbGetFontFuncs() {\n    static hb_font_funcs_t* const funcs = [] {\n        // HarfBuzz will use the default (parent) implementation if they aren't set.\n        hb_font_funcs_t* const funcs = hb_font_funcs_create();\n        hb_font_funcs_set_variation_glyph_func(funcs, skhbGlyph, nullptr, nullptr);\n        hb_font_funcs_set_nominal_glyph_func(funcs, skhbNominalGlyph, nullptr, nullptr);\n        hb_font_funcs_set_nominal_glyphs_func(funcs, skhbNominalGlyphs, nullptr, nullptr);\n        hb_font_funcs_set_glyph_h_advance_func(funcs, skhbGlyphHAdvance, nullptr, nullptr);\n        hb_font_funcs_set_glyph_h_advances_func(funcs, skhbGlyphHAdvances, nullptr, nullptr);\n        hb_font_funcs_set_glyph_extents_func(funcs, skhbGlyphExtents, nullptr, nullptr);\n        hb_font_funcs_make_immutable(funcs);\n        return funcs;\n    }();\n    return funcs;\n}\n\nstatic hb_blob_t* skhbGetTable(hb_face_t* /*face*/, hb_tag_t tag, void* userData) {\n    SkTypeface& typeface = *reinterpret_cast<SkTypeface*>(userData);\n\n    auto data = typeface.copyTableData(tag);\n    if (!data) {\n        return nullptr;\n    }\n    SkData* rawData = data.release();\n    return hb_blob_create(reinterpret_cast<char*>(rawData->writable_data()),\n                          static_cast<unsigned int>(rawData->size()),\n                          HB_MEMORY_MODE_READONLY,\n                          rawData,\n                          [](void* ctx) { SkSafeUnref(reinterpret_cast<SkData*>(ctx)); });\n}\n\nHBFace Harfbuzz::createFace(SkTypeface* typeface) {\n    HBFace face(hb_face_create_for_tables(\n        skhbGetTable, SkRef(typeface), [](void* userData) { SkSafeUnref(reinterpret_cast<SkTypeface*>(userData)); }));\n\n    if (face.get() == nullptr) {\n        return HBFace(nullptr);\n    }\n\n    hb_face_set_upem(face.get(), typeface->getUnitsPerEm());\n\n    return face;\n}\n\nHBFont Harfbuzz::createMainFont(const SkTypeface& typeface, const HBFace& hbFace) {\n    HBFont hbFont(hb_font_create(hbFace.get()));\n    if (hbFont.get() == nullptr) {\n        return HBFont(nullptr);\n    }\n    hb_ot_font_set_funcs(hbFont.get());\n    int axisCount = typeface.getVariationDesignPosition(nullptr, 0);\n    if (axisCount > 0) {\n        skia_private::AutoSTMalloc<4, SkFontArguments::VariationPosition::Coordinate> axisValues(axisCount);\n        if (typeface.getVariationDesignPosition(axisValues, axisCount) == axisCount) {\n            hb_font_set_variations(hbFont.get(), reinterpret_cast<hb_variation_t*>(axisValues.get()), axisCount);\n        }\n    }\n\n    return hbFont;\n}\n\nHBFont Harfbuzz::createSubFont(const HBFont& mainFont, SkFont* font) {\n    // Creating a sub font means that non-available functions\n    // are found from the parent.\n    HBFont hbFont(hb_font_create_sub_font(mainFont.get()));\n    if (hbFont.get() == nullptr) {\n        return HBFont(nullptr);\n    }\n\n    hb_font_set_funcs(hbFont.get(), skhbGetFontFuncs(), font, nullptr);\n    int scale = sskhbPosition(font->getSize());\n    hb_font_set_scale(hbFont.get(), scale, scale);\n\n    return hbFont;\n}\n\n}; // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Harfbuzz.hpp",
    "content": "//\n//  Harfbuzz.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 10/18/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"utils/base/NonCopyable.hpp\"\n\nstruct hb_blob_t;\nstruct hb_face_t;\nstruct hb_font_t;\nstruct hb_buffer_t;\nclass SkTypeface;\nclass SkFont;\n\nnamespace Valdi {\nclass CharacterSet;\n}\n\nnamespace snap::drawing {\n\ntemplate<typename T>\nclass HBResource : public snap::NonCopyable {\npublic:\n    HBResource() = default;\n    explicit HBResource(T* ptr) : _ptr(ptr) {}\n\n    T* get() const {\n        return _ptr;\n    }\n\nprotected:\n    T* _ptr = nullptr;\n};\n\nclass HBBlob : public HBResource<hb_blob_t> {\npublic:\n    using HBResource<hb_blob_t>::HBResource;\n    ~HBBlob();\n\n    HBBlob(HBBlob&& other) noexcept;\n    HBBlob& operator=(HBBlob&& other) noexcept;\n};\n\nclass HBFace : public HBResource<hb_face_t> {\npublic:\n    using HBResource<hb_face_t>::HBResource;\n    ~HBFace();\n\n    HBFace(HBFace&& other) noexcept;\n    HBFace& operator=(HBFace&& other) noexcept;\n\n    Ref<Valdi::CharacterSet> getCharacters();\n};\n\nclass HBFont : public HBResource<hb_font_t> {\npublic:\n    using HBResource<hb_font_t>::HBResource;\n    ~HBFont();\n\n    HBFont(HBFont&& other) noexcept;\n    HBFont& operator=(HBFont&& other) noexcept;\n};\n\nclass HBBuffer : public HBResource<hb_buffer_t> {\npublic:\n    using HBResource<hb_buffer_t>::HBResource;\n    ~HBBuffer();\n\n    HBBuffer(HBBuffer&& other) noexcept;\n    HBBuffer& operator=(HBBuffer&& other) noexcept;\n};\n\nclass Harfbuzz {\npublic:\n    static HBFace createFace(SkTypeface* typeface);\n    static HBFont createMainFont(const SkTypeface& typeface, const HBFace& hbFace);\n    static HBFont createSubFont(const HBFont& mainFont, SkFont* font);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/IFontManager.cpp",
    "content": "//\n//  IFontManager.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 5/16/24.\n//\n\n#include \"snap_drawing/cpp/Text/IFontManager.hpp\"\n\nnamespace snap::drawing {\n\nVALDI_CLASS_IMPL(IFontManager)\n\n}\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/IFontManager.hpp",
    "content": "//\n//  IFontManager.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 5/16/24.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n\nnamespace snap::drawing {\n\nclass LoadableTypeface;\n\nclass IFontManager : public FontResolver {\npublic:\n    virtual void registerTypeface(const String& fontFamilyName,\n                                  FontStyle fontStyle,\n                                  bool canUseAsFallback,\n                                  const Ref<LoadableTypeface>& loadableTypeface) = 0;\n\n    virtual Valdi::Ref<IFontManager> makeScoped() = 0;\n\n    virtual Valdi::Result<Valdi::Ref<Typeface>> getTypefaceWithName(const String& name) = 0;\n\n    virtual Valdi::Result<Valdi::Ref<Typeface>> getTypefaceWithFamilyNameAndStyle(const String& familyName,\n                                                                                  FontStyle fontStyle) = 0;\n\n    VALDI_CLASS_HEADER(IFontManager)\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/LoadableTypeface.cpp",
    "content": "//\n//  LoadableTypeface.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 9/2/20.\n//\n\n#include \"snap_drawing/cpp/Text/LoadableTypeface.hpp\"\n#include \"include/core/SkData.h\"\n#include \"include/core/SkFontMgr.h\"\n#include \"snap_drawing/cpp/Utils/BytesUtils.hpp\"\n#include \"valdi_core/cpp/Utils/DiskUtils.hpp\"\n\nnamespace snap::drawing {\n\nclass BytesLoadableTypeface : public LoadableTypeface {\npublic:\n    BytesLoadableTypeface(const String& fontName, const Valdi::BytesView& bytes)\n        : LoadableTypeface(fontName), _bytes(bytes) {}\n    ~BytesLoadableTypeface() override = default;\n\nprotected:\n    Valdi::Result<Valdi::BytesView> loadFontData() override {\n        return std::move(_bytes);\n    }\n\nprivate:\n    Valdi::BytesView _bytes;\n};\n\nclass FileLoadableTypeface : public LoadableTypeface {\npublic:\n    FileLoadableTypeface(const String& fontName, const String& path) : LoadableTypeface(fontName), _path(path) {}\n    ~FileLoadableTypeface() override = default;\n\nprotected:\n    Valdi::Result<Valdi::BytesView> loadFontData() override {\n        Valdi::Path path(_path.toStringView());\n        return Valdi::DiskUtils::load(path);\n    }\n\nprivate:\n    Valdi::StringBox _path;\n};\n\nLoadableTypeface::LoadableTypeface(const String& fontName) : _fontName(fontName) {}\nLoadableTypeface::~LoadableTypeface() = default;\n\nconst Valdi::Result<Ref<Typeface>>& LoadableTypeface::get(SkFontMgr& fontMgr) {\n    if (_loadedTypeface.empty()) {\n        _loadedTypeface = loadTypeface(fontMgr);\n    }\n    return _loadedTypeface;\n}\n\nconst String& LoadableTypeface::getName() const {\n    return _fontName;\n}\n\nValdi::Result<Ref<Typeface>> LoadableTypeface::loadTypeface(SkFontMgr& fontMgr) {\n    auto fontDataResult = loadFontData();\n    if (!fontDataResult) {\n        return fontDataResult.error().rethrow(\"Could not load typeface data\");\n    }\n\n    auto fontData = fontDataResult.moveValue();\n    auto skData = skDataFromBytes(fontData, DataConversionModeCopyIfUnsafe);\n    auto skTypeface = fontMgr.makeFromData(skData);\n\n    if (skTypeface == nullptr) {\n        return Valdi::Error(\"Could not load typeface from data\");\n    }\n\n    return Valdi::makeShared<Typeface>(std::move(skTypeface), _fontName, true);\n}\n\nRef<LoadableTypeface> LoadableTypeface::fromBytes(const String& fontName, const Valdi::BytesView& bytes) {\n    return Valdi::makeShared<BytesLoadableTypeface>(fontName, bytes);\n}\n\nRef<LoadableTypeface> LoadableTypeface::fromFile(const String& fontName, const Valdi::StringBox& filePath) {\n    return Valdi::makeShared<FileLoadableTypeface>(fontName, filePath);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/LoadableTypeface.hpp",
    "content": "//\n//  LoadableTypeface.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 9/2/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n\n#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\nclass SkFontMgr;\n\nnamespace Valdi {\nclass Path;\n}\n\nnamespace snap::drawing {\n\nclass LoadableTypeface : public Valdi::SimpleRefCountable {\npublic:\n    explicit LoadableTypeface(const String& fontName);\n    ~LoadableTypeface() override;\n\n    const Valdi::Result<Ref<Typeface>>& get(SkFontMgr& fontMgr);\n\n    const String& getName() const;\n\n    static Ref<LoadableTypeface> fromBytes(const String& fontName, const Valdi::BytesView& bytes);\n    static Ref<LoadableTypeface> fromFile(const String& fontName, const Valdi::StringBox& filePath);\n\nprotected:\n    virtual Valdi::Result<Valdi::BytesView> loadFontData() = 0;\n\nprivate:\n    Valdi::Result<Ref<Typeface>> _loadedTypeface;\n    String _fontName;\n\n    Valdi::Result<Ref<Typeface>> loadTypeface(SkFontMgr& fontMgr);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/SkFontMgrSingleton.cpp",
    "content": "#include \"snap_drawing/cpp/Text/SkFontMgrSingleton.hpp\"\n\n#if defined(SK_FONTMGR_CORETEXT_AVAILABLE)\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wimport-preprocessor-directive-pedantic\"\n#include \"include/ports/SkFontMgr_mac_ct.h\"\n#pragma clang diagnostic pop\n\n#elif defined(SK_FONTMGR_ANDROID_AVAILABLE)\n#include \"include/ports/SkFontMgr_android.h\"\n#include \"include/ports/SkFontScanner_FreeType.h\"\n#elif defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)\n#include \"include/ports/SkFontMgr_fontconfig.h\"\n#include \"include/ports/SkFontScanner_FreeType.h\"\n#else\n#include \"include/ports/SkFontMgr_empty.h\"\n#endif\n\nnamespace snap::snap_drawing {\n\nstatic sk_sp<SkFontMgr> makeSkFontMgr() {\n    // If necessary, clients should use a font manager that would load fonts from the system.\n#if defined(SK_FONTMGR_CORETEXT_AVAILABLE)\n    return SkFontMgr_New_CoreText(nullptr);\n#elif defined(SK_FONTMGR_ANDROID_AVAILABLE)\n    return SkFontMgr_New_Android(nullptr, SkFontScanner_Make_FreeType());\n#elif defined(SK_FONTMGR_FONTCONFIG_AVAILABLE)\n    return SkFontMgr_New_FontConfig(nullptr, SkFontScanner_Make_FreeType());\n#else\n    return SkFontMgr_New_Custom_Empty();\n#endif\n}\n\nsk_sp<SkFontMgr> getSkFontMgrSingleton() {\n    static auto kFontMgr = makeSkFontMgr();\n    return kFontMgr;\n}\n\n} // namespace snap::snap_drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/SkFontMgrSingleton.hpp",
    "content": "#pragma once\n\n#include \"include/core/SkFontMgr.h\"\n\nnamespace snap::snap_drawing {\n\nsk_sp<SkFontMgr> getSkFontMgrSingleton();\n\n}"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextLayout.cpp",
    "content": "//\n//  TextLayout.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/14/20.\n//\n\n#include \"snap_drawing/cpp/Text/TextLayout.hpp\"\n#include \"snap_drawing/cpp/Utils/JSONUtils.hpp\"\n\n#include \"valdi_core/cpp/Utils/ValueArray.hpp\"\n\nnamespace snap::drawing {\n\nTextLayoutEntrySegment::TextLayoutEntrySegment() = default;\nTextLayoutEntrySegment::TextLayoutEntrySegment(const Rect& bounds, const Ref<Font>& font, const std::string& characters)\n    : bounds(bounds), font(font), characters(characters) {}\n\nTextLayoutEntry::TextLayoutEntry() = default;\nTextLayoutEntry::TextLayoutEntry(const Rect& bounds,\n                                 std::optional<Color> color,\n                                 std::vector<TextLayoutEntrySegment> segments)\n    : bounds(bounds), color(color), segments(std::move(segments)) {}\nTextLayoutEntry::~TextLayoutEntry() = default;\n\nTextLayout::TextLayout(Size maxSize,\n                       std::vector<TextLayoutEntry>&& entries,\n                       std::vector<TextLayoutDecorationEntry>&& decorations,\n                       std::vector<TextLayoutAttachment>&& attachments,\n                       bool fitsInMaxSize)\n    : _maxSize(maxSize),\n      _fitsInMaxSize(fitsInMaxSize),\n      _entries(std::move(entries)),\n      _decorations(std::move(decorations)),\n      _attachments(std::move(attachments)) {\n    _bounds = Rect::makeEmpty();\n\n    for (const auto& entry : _entries) {\n        _bounds.join(entry.bounds);\n    }\n}\n\nTextLayout::~TextLayout() = default;\n\nconst std::vector<TextLayoutEntry>& TextLayout::getEntries() const {\n    return _entries;\n}\n\nconst std::vector<TextLayoutDecorationEntry>& TextLayout::getDecorations() const {\n    return _decorations;\n}\n\nconst std::vector<TextLayoutAttachment>& TextLayout::getAttachments() const {\n    return _attachments;\n}\n\nconst Rect& TextLayout::getBounds() const {\n    return _bounds;\n}\n\nconst Size& TextLayout::getMaxSize() const {\n    return _maxSize;\n}\n\nbool TextLayout::fitsInMaxSize() const {\n    return _fitsInMaxSize;\n}\n\nValdi::Value TextLayout::toJSONValue() const {\n    Valdi::Value out;\n    out.setMapValue(\"maxSize\", snap::drawing::toJSONValue(_maxSize));\n\n    auto entries = Valdi::ValueArray::make(_entries.size());\n\n    for (size_t i = 0; i < _entries.size(); i++) {\n        const auto& entry = _entries[i];\n\n        Valdi::Value entryJson;\n        entryJson.setMapValue(\"bounds\", snap::drawing::toJSONValue(entry.bounds));\n\n        if (!entry.segments.empty()) {\n            auto segments = Valdi::ValueArray::make(entry.segments.size());\n            for (size_t j = 0; j < entry.segments.size(); j++) {\n                const auto& segment = entry.segments[j];\n                Valdi::Value segmentJson;\n\n                segmentJson.setMapValue(\"bounds\", snap::drawing::toJSONValue(segment.bounds));\n                segmentJson.setMapValue(\"font\", Valdi::Value(segment.font->getDescription()));\n                segmentJson.setMapValue(\"characters\", Valdi::Value(segment.characters));\n\n                segments->emplace(j, std::move(segmentJson));\n            }\n\n            entryJson.setMapValue(\"segments\", Valdi::Value(segments));\n        }\n\n        if (entry.color) {\n            entryJson.setMapValue(\"color\", Valdi::Value(entry.color.value().toString()));\n        }\n\n        entries->emplace(i, std::move(entryJson));\n    }\n\n    out.setMapValue(\"entries\", Valdi::Value(entries));\n\n    auto decorations = Valdi::ValueArray::make(_decorations.size());\n    for (size_t i = 0; i < _decorations.size(); i++) {\n        const auto& decoration = _decorations[i];\n\n        Valdi::Value decorationJson;\n        decorationJson.setMapValue(\"bounds\", snap::drawing::toJSONValue(decoration.bounds));\n        decorationJson.setMapValue(\"predraw\", Valdi::Value(decoration.predraw));\n\n        if (decoration.color) {\n            decorationJson.setMapValue(\"color\", Valdi::Value(decoration.color.value().toString()));\n        }\n\n        decorations->emplace(i, std::move(decorationJson));\n    }\n\n    out.setMapValue(\"decorations\", Valdi::Value(decorations));\n\n    return out;\n}\n\nRef<Valdi::RefCountable> TextLayout::getAttachmentAtPoint(Point location, Scalar tolerance) const {\n    Ref<Valdi::RefCountable> bestCandidate;\n    Scalar shortestDistance = 0.0f;\n    for (const auto& attachment : _attachments) {\n        if (attachment.bounds.contains(location)) {\n            return attachment.attachment;\n        }\n\n        auto closestPoint = attachment.bounds.closestPoint(location);\n        auto distance = Point::distance(location, closestPoint);\n\n        if (distance <= tolerance && (bestCandidate == nullptr || distance < shortestDistance)) {\n            shortestDistance = distance;\n            bestCandidate = attachment.attachment;\n        }\n    }\n\n    return bestCandidate;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextLayout.hpp",
    "content": "//\n//  TextLayout.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/14/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"include/core/SkTextBlob.h\"\n\n#include \"valdi_core/cpp/Utils/Value.hpp\"\n\n#include <memory>\n#include <optional>\n#include <string>\n\nnamespace snap::drawing {\n\nenum TextAlign {\n    TextAlignLeft,\n    TextAlignRight,\n    TextAlignCenter,\n    TextAlignJustify,\n};\n\nenum TextDecoration {\n    TextDecorationNone,\n    TextDecorationStrikethrough,\n    TextDecorationUnderline,\n};\n\nenum TextOverflow { TextOverflowEllipsis, TextOverflowClip };\n\nstruct TextLayoutDecorationEntry {\n    Rect bounds;\n    /**\n     Whether the entry should be drawn before or after the text blobs\n     */\n    bool predraw;\n    std::optional<Color> color;\n\n    TextLayoutDecorationEntry() = default;\n    constexpr TextLayoutDecorationEntry(const Rect& bounds, bool predraw, std::optional<Color> color)\n        : bounds(bounds), predraw(predraw), color(color) {}\n};\n\nstruct TextLayoutEntrySegment {\n    Rect bounds;\n    Ref<Font> font;\n    std::string characters;\n\n    TextLayoutEntrySegment();\n    TextLayoutEntrySegment(const Rect& bounds, const Ref<Font>& font, const std::string& characters);\n};\n\nstruct TextLayoutEntry {\n    sk_sp<SkTextBlob> textBlob;\n    Rect bounds;\n    std::optional<Color> color;\n    std::vector<TextLayoutEntrySegment> segments;\n\n    TextLayoutEntry();\n    TextLayoutEntry(const Rect& bounds, std::optional<Color> color, std::vector<TextLayoutEntrySegment> segments);\n\n    ~TextLayoutEntry();\n};\n\nstruct TextLayoutAttachment {\n    Rect bounds;\n    Ref<Valdi::RefCountable> attachment;\n\n    inline TextLayoutAttachment(const Rect& bounds, const Ref<Valdi::RefCountable>& attachment)\n        : bounds(bounds), attachment(attachment) {}\n};\n\nclass TextLayout : public Valdi::SimpleRefCountable {\npublic:\n    TextLayout(Size maxSize,\n               std::vector<TextLayoutEntry>&& entries,\n               std::vector<TextLayoutDecorationEntry>&& decorations,\n               std::vector<TextLayoutAttachment>&& attachments,\n               bool fitsInMaxSize);\n    ~TextLayout() override;\n\n    const std::vector<TextLayoutEntry>& getEntries() const;\n    const std::vector<TextLayoutDecorationEntry>& getDecorations() const;\n    const std::vector<TextLayoutAttachment>& getAttachments() const;\n\n    const Size& getMaxSize() const;\n\n    const Rect& getBounds() const;\n\n    bool fitsInMaxSize() const;\n\n    Valdi::Value toJSONValue() const;\n\n    Ref<Valdi::RefCountable> getAttachmentAtPoint(Point location, Scalar tolerance) const;\n\nprivate:\n    Size _maxSize;\n    bool _fitsInMaxSize;\n\n    std::vector<TextLayoutEntry> _entries;\n    std::vector<TextLayoutDecorationEntry> _decorations;\n    std::vector<TextLayoutAttachment> _attachments;\n    Rect _bounds = Rect::makeEmpty();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextLayoutBuilder.cpp",
    "content": "//\n//  TextLayoutBuilder.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 9/21/22.\n//\n\n#include \"snap_drawing/cpp/Text/TextLayoutBuilder.hpp\"\n#include \"snap_drawing/cpp/Text/CharactersIterator.hpp\"\n#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n#include \"snap_drawing/cpp/Text/TextShaper.hpp\"\n#include \"snap_drawing/cpp/Text/Unicode.hpp\"\n\n#include \"snap_drawing/cpp/Utils/UTFUtils.hpp\"\n\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n#include \"valdi_core/cpp/Utils/Trace.hpp\"\n\n#include <iostream>\n\nnamespace snap::drawing {\n\nstruct TextLineOffset {\n    Scalar horizontalOffset = 0;\n    LineMetrics lineMetrics;\n};\n\nstruct TextLineSize {\n    Scalar width = 0;\n    LineMetrics lineMetrics;\n};\n\nusing TextLineOffsetVector = Valdi::SmallVector<TextLineOffset, 2>;\n\nstatic std::string toUTF8(const ShapedGlyph* glyphsBegin, const ShapedGlyph* glyphsEnd) {\n    std::vector<Character> unicode;\n    unicode.resize(glyphsEnd - glyphsBegin);\n\n    auto* unicodePtr = unicode.data();\n\n    const auto* it = glyphsBegin;\n    while (it != glyphsEnd) {\n        *unicodePtr = it->character();\n        it++;\n        unicodePtr++;\n    }\n\n    return unicodeToUtf8(unicode.data(), unicode.size());\n}\n\ntemplate<typename T>\nstatic void forEachSegmentsLine(TextLayoutBuilderSegment* begin, TextLayoutBuilderSegment* end, T&& cb) {\n    size_t lastLineNumber = 0;\n    TextLayoutBuilderSegment* itStartForCurrentLine = nullptr;\n    auto* it = begin;\n    while (it != end) {\n        auto currentLineNumber = it->lineNumber;\n        if (currentLineNumber != lastLineNumber) {\n            if (itStartForCurrentLine != nullptr) {\n                cb(lastLineNumber, itStartForCurrentLine, it);\n            }\n\n            itStartForCurrentLine = it;\n            lastLineNumber = currentLineNumber;\n        }\n\n        it++;\n    }\n\n    if (itStartForCurrentLine != nullptr) {\n        cb(lastLineNumber, itStartForCurrentLine, it);\n    }\n}\n\nstruct LineBreakResult {\n    const ShapedGlyph* end;\n    const ShapedGlyph* next;\n    bool reachedEndLine;\n    bool brokenByNewLineCharacter;\n\n    constexpr LineBreakResult(const ShapedGlyph* end,\n                              const ShapedGlyph* next,\n                              bool reachedEndLine,\n                              bool brokenByNewLineCharacter)\n        : end(end), next(next), reachedEndLine(reachedEndLine), brokenByNewLineCharacter(brokenByNewLineCharacter) {}\n};\n\nstatic LineBreakResult lineBreak(const ShapedGlyph* begin,\n                                 const ShapedGlyph* end,\n                                 LineBreakStrategy strategy,\n                                 Scalar containerWidth,\n                                 Scalar accumulatedWidth) {\n    const auto* it = begin;\n    // The last iterator that we can safely break on\n    const auto* lastSafeBreakIt = it;\n    auto prevWasWhitespace = false;\n\n    while (it < end) {\n        if (Unicode::isNewline(it->character())) {\n            return LineBreakResult(it, it + 1, true, true);\n        }\n\n        accumulatedWidth += it->advanceX;\n\n        auto isWhitespace = Unicode::isBreakingWhitespace(it->character());\n\n        switch (strategy) {\n            case LineBreakStrategy::ByWord:\n                if (isWhitespace && !prevWasWhitespace) {\n                    lastSafeBreakIt = it;\n                }\n                break;\n            case LineBreakStrategy::ByCharacter:\n                if (!it->unsafeToBreak() && !prevWasWhitespace) {\n                    lastSafeBreakIt = it;\n                }\n                break;\n        }\n\n        if (accumulatedWidth > containerWidth) {\n            // Reached the end of our container\n\n            if (!isWhitespace) {\n                // If we are not in a whitespace, we move back the iterator\n                // down to our first safe breaking point in order to consume\n                // all the breaking whitespaces that might be there.\n                // This is to set our next iterator on the first word instead\n                // of having leading whitespaces.\n                it = lastSafeBreakIt;\n            }\n\n            // Eat up all the trailing whitespaces\n            while (it < end && Unicode::isBreakingWhitespace(it->character())) {\n                it++;\n            }\n\n            return LineBreakResult(lastSafeBreakIt, it, true, false);\n        }\n\n        prevWasWhitespace = isWhitespace;\n        it++;\n    }\n\n    return LineBreakResult(it, it, false, false);\n}\n\nstatic Scalar computeAdvance(const ShapedGlyph* shapedGlyphs, size_t length) {\n    auto advance = 0.0f;\n\n    for (size_t i = 0; i < length; i++) {\n        advance += shapedGlyphs[i].advanceX;\n    }\n\n    return advance;\n}\n\nTextLayoutSpecs TextLayoutSpecs::withFont(const Ref<Font>& newFont) const {\n    return TextLayoutSpecs(newFont, attachment, lineHeightMultiple, letterSpacing, textDecoration, colorIndex);\n}\n\nTextLayoutBuilder::TextLayoutBuilder(TextAlign textAlign,\n                                     TextOverflow textOverflow,\n                                     Size maxSize,\n                                     int maxLinesCount,\n                                     const Ref<FontManager>& fontManager,\n                                     bool isRightToLeft,\n                                     bool prioritizeFewerFonts)\n    : _textAlign(textAlign),\n      _textOverflow(textOverflow),\n      _maxSize(maxSize),\n      _position(Point::makeEmpty()),\n      _maxLinesCount(maxLinesCount),\n      _isRightToLeft(isRightToLeft),\n      _prioritizeFewerFonts(prioritizeFewerFonts),\n      _fontManager(fontManager),\n      _shaper(fontManager != nullptr ? fontManager->getTextShaper() : nullptr) {}\n\nTextLayoutBuilder::~TextLayoutBuilder() = default;\n\nvoid TextLayoutBuilder::appendSegment(\n    const TextLayoutSpecs& specs, size_t glyphsStart, size_t glyphsCount, const Rect& bounds, bool isRightToLeft) {\n    auto& segment = _segments.emplace_back();\n    segment.glyphsStart = glyphsStart;\n    segment.glyphsCount = glyphsCount;\n    segment.bounds = bounds;\n    segment.lineNumber = _currentNumberOfLines;\n    segment.drawPosition = _position;\n    segment.lineMetrics = _currentLineMetrics;\n    segment.font = specs.font;\n    segment.attachment = specs.attachment;\n    segment.colorIndex = specs.colorIndex;\n    segment.isRightToLeft = isRightToLeft;\n    segment.textDecoration = specs.textDecoration;\n}\n\n[[maybe_unused]] static void outputDebug(const ShapedGlyph* shapedGlyphs,\n                                         size_t consumedGlyphCount,\n                                         const Point& advance,\n                                         const Rect& bounds) {\n    auto utf8 = toUTF8(shapedGlyphs, shapedGlyphs + consumedGlyphCount);\n\n    std::cout << std::endl;\n    std::cout << \"For text: \\\"\" << utf8 << \"\\\"\" << std::endl;\n    std::cout << \"Advance is \" << advance << std::endl;\n    std::cout << \"Bounds is \" << bounds << std::endl;\n    std::cout << \"Width is \" << bounds.width() << std::endl;\n}\n\nbool TextLayoutBuilder::computeLineMetrics(const TextLayoutSpecs& specs,\n                                           const FontMetrics& fontMetrics,\n                                           LineMetrics& output) {\n    output = _currentLineMetrics;\n    output.join(\n        LineMetrics(fontMetrics.ascent * specs.lineHeightMultiple, fontMetrics.descent * specs.lineHeightMultiple));\n    return _position.y + output.height() <= _maxSize.height;\n}\n\nRect TextLayoutBuilder::computeChunkBounds(const TextLayoutSpecs& specs,\n                                           Scalar advance,\n                                           const FontMetrics& fontMetrics) {\n    auto bounds = Rect::makeLTRB(\n        0, fontMetrics.ascent * specs.lineHeightMultiple, advance, fontMetrics.descent * specs.lineHeightMultiple);\n\n    return bounds;\n}\n\nvoid TextLayoutBuilder::removeLastSegment() {\n    auto lastIndex = _segments.size() - 1;\n    auto& lastSegment = _segments[lastIndex];\n\n    _position = lastSegment.drawPosition;\n    _segments.erase(_segments.begin() + lastIndex);\n\n    if (_segments.empty()) {\n        _currentLineMetrics.ascent = 0;\n        _currentLineMetrics.descent = 0;\n        _currentNumberOfLines = 1;\n    } else {\n        auto& newLastSegment = _segments[_segments.size() - 1];\n        _currentLineMetrics = newLastSegment.lineMetrics;\n        _currentNumberOfLines = newLastSegment.lineNumber;\n    }\n}\n\nbool TextLayoutBuilder::removeCharactersUntilSizeFit(Size size) {\n    for (;;) {\n        if (_position.x + size.width <= _maxSize.width && _position.y + size.height <= _maxSize.height) {\n            // Our size now fits\n            return true;\n        }\n\n        if (_segments.empty()) {\n            // No segment to remove, we can't fit our size\n            return false;\n        }\n\n        auto lastIndex = _segments.size() - 1;\n\n        auto& lastSegment = _segments[lastIndex];\n\n        if (lastSegment.lineNumber != _currentNumberOfLines) {\n            // We are processing a segment that is not on the current line.\n            // Move back to the line of the segment.\n            _currentNumberOfLines = lastSegment.lineNumber;\n            _position = lastSegment.drawPosition;\n            _position.x += lastSegment.bounds.width();\n\n            continue;\n        }\n\n        if (_position.y + std::max(lastSegment.lineMetrics.height(), size.height) > _maxSize.height) {\n            // The whole computed line height doesn't fit our container height.\n            // We can remove the entire segment\n            removeLastSegment();\n\n            continue;\n        }\n\n        const auto* glyphsStart = _glyphs.data() + lastSegment.glyphsStart;\n        const auto* glyphsEnd = glyphsStart + lastSegment.glyphsCount;\n\n        // Do a line break to compute how much characters of this segment we can fit\n        auto lineBreakResult = lineBreak(glyphsStart,\n                                         glyphsEnd,\n                                         LineBreakStrategy::ByCharacter,\n                                         _maxSize.width,\n                                         size.width + lastSegment.drawPosition.x);\n\n        size_t newGlyphsCount = lineBreakResult.end - glyphsStart;\n\n        if (newGlyphsCount == 0) {\n            // No glyphs can fit, remove the entire segment\n            removeLastSegment();\n            continue;\n        }\n\n        lastSegment.glyphsCount = newGlyphsCount;\n\n        // Update the bounds\n        auto advance = computeAdvance(glyphsStart, newGlyphsCount);\n\n        auto newRight = lastSegment.bounds.left + advance;\n        SC_ABORT_UNLESS(newRight < lastSegment.bounds.right, \"Computed advance should be smaller\");\n        lastSegment.bounds.right = newRight;\n\n        // Update current position\n        _position = lastSegment.drawPosition;\n        _position.x += advance;\n    }\n}\n\nvoid TextLayoutBuilder::processEllipsis(const TextLayoutSpecs& specs) {\n    _reachedMaxLines = true;\n\n    if (_textOverflow != TextOverflowEllipsis) {\n        return;\n    }\n\n    Character c = 0x2026; // Code point for character '…'\n\n    TextLayoutSpecs resolvedSpecs = specs;\n\n    if (!specs.font->typeface()->supportsCharacter(c)) {\n        auto result = _fontManager->getCompatibleFont(specs.font, nullptr, 0, c);\n        if (!result) {\n            return;\n        }\n        resolvedSpecs = resolvedSpecs.withFont(result.value());\n    }\n\n    auto shapeResult = shape(resolvedSpecs, &c, 1, TextScript::common(), false);\n\n    const auto& fontMetrics = resolvedSpecs.font->metrics();\n\n    auto advance = computeAdvance(shapeResult.glyphsStart, shapeResult.glyphsEnd - shapeResult.glyphsStart);\n    auto bounds = computeChunkBounds(resolvedSpecs, advance, fontMetrics);\n\n    if (!removeCharactersUntilSizeFit(bounds.size())) {\n        // Cannot fit our ... within the current line\n        return;\n    }\n\n    appendSegment(resolvedSpecs,\n                  shapeResult.glyphsStart - _glyphs.data(),\n                  shapeResult.glyphsEnd - shapeResult.glyphsStart,\n                  bounds,\n                  false);\n\n    _position.x += advance;\n}\n\nTextLayoutBuilder::ShapeResult TextLayoutBuilder::shape(\n    const TextLayoutSpecs& specs, const Character* characters, size_t charactersLength, TextScript script, bool isRTL) {\n    auto glyphsStart = _glyphs.size();\n    auto glyphsLength =\n        _shaper->shape(characters, charactersLength, *specs.font, isRTL, specs.letterSpacing, script, _glyphs);\n\n    if (isRTL) {\n        // Put the glyphs into processing order, so that we process the characters from right to left\n        std::reverse(_glyphs.begin() + glyphsStart, _glyphs.end());\n    }\n\n    auto* shapedGlyphStart = _glyphs.data();\n    auto* shapedGlyphIt = shapedGlyphStart + glyphsStart;\n    auto* shapedGlyphEnd = shapedGlyphIt + glyphsLength;\n\n    // Round advances to pixel grid\n    for (size_t i = 0; i < glyphsLength; i++) {\n        shapedGlyphIt[i].advanceX = roundf(shapedGlyphIt[i].advanceX);\n    }\n\n    return TextLayoutBuilder::ShapeResult(shapedGlyphIt, shapedGlyphEnd);\n}\n\nbool TextLayoutBuilder::shouldProcessEllipsisAfterLineBreak(const ShapedGlyph* begin,\n                                                            const ShapedGlyph* end,\n                                                            const ShapedGlyph* next) const {\n    if (_maxLinesCount != 0 && _currentNumberOfLines + 1 > _maxLinesCount) {\n        // We reached our maximum number of lines\n        return true;\n    }\n\n    if (_position.x == 0 && begin == end && end == next) {\n        // We are at the beginning of the line, and we were not able\n        // to process any characters. We should break now as we will not\n        // be able to fit any more characters.\n        return true;\n    }\n\n    return false;\n}\n\nbool TextLayoutBuilder::shouldProcessEllipsisAfterLineHeightUpdate() const {\n    return _position.y + _currentLineMetrics.height() > _maxSize.height;\n}\n\nvoid TextLayoutBuilder::processUnidirectionalRun(const TextLayoutSpecs& specs,\n                                                 const Ref<Font>& originalFont,\n                                                 const Character* characters,\n                                                 size_t charactersLength,\n                                                 TextScript script,\n                                                 bool isRTL) {\n    if (_reachedMaxLines) {\n        return;\n    }\n\n    auto shapeResult = shape(specs, characters, charactersLength, script, isRTL);\n\n    const auto* shapedGlyphIt = shapeResult.glyphsStart;\n    const auto& fontMetrics = specs.font->metrics();\n    LineMetrics lineMetrics;\n\n    // Resolve all the segments of our blob.\n    // We emit one segment per line.\n\n    while (shapedGlyphIt < shapeResult.glyphsEnd && !_reachedMaxLines) {\n        if (!computeLineMetrics(specs, fontMetrics, lineMetrics)) {\n            // We reached the bottom of our container.\n            processEllipsis(specs.withFont(originalFont));\n            return;\n        }\n\n        // Consume the unicode string until we reach the max size or a new line character\n        auto result = lineBreak(shapedGlyphIt, shapeResult.glyphsEnd, _lineBreakStrategy, _maxSize.width, _position.x);\n\n        auto shouldProcessEllipsis = false;\n        if (result.reachedEndLine && shouldProcessEllipsisAfterLineBreak(shapedGlyphIt, result.end, result.next)) {\n            // We reached en end of our container and we need to append an ellipsis.\n            // In this case we actually want to break by character so that we can remove\n            // the trailing characters to fit the ellipsis.\n            shouldProcessEllipsis = true;\n            result = lineBreak(\n                shapedGlyphIt, shapeResult.glyphsEnd, LineBreakStrategy::ByCharacter, _maxSize.width, _position.x);\n        }\n\n        auto consumedGlyphCount = result.end - shapedGlyphIt;\n\n        if (consumedGlyphCount > 0 || result.brokenByNewLineCharacter) {\n            // Update the lineHeight if we consumed characters or if we added newlines\n            _currentLineMetrics = lineMetrics;\n        }\n\n        if (consumedGlyphCount > 0) {\n            // Measure the space consumed by our chunk.\n            auto advance = computeAdvance(shapedGlyphIt, consumedGlyphCount);\n            auto bounds = computeChunkBounds(specs, advance, fontMetrics);\n            appendSegment(specs, shapedGlyphIt - _glyphs.data(), consumedGlyphCount, bounds, isRTL);\n            _position.x += advance;\n        }\n\n        if (result.reachedEndLine) {\n            if (shouldProcessEllipsis) {\n                processEllipsis(specs.withFont(originalFont));\n                return;\n            }\n\n            _position.x = 0;\n            _position.y += _currentLineMetrics.height();\n            _currentLineMetrics.ascent = 0;\n            _currentLineMetrics.descent = 0;\n            _currentNumberOfLines++;\n\n            if (result.brokenByNewLineCharacter) {\n                if (!computeLineMetrics(specs, fontMetrics, lineMetrics)) {\n                    // We reached the bottom of our container.\n                    processEllipsis(specs.withFont(originalFont));\n                    return;\n                } else {\n                    _currentLineMetrics = lineMetrics;\n                }\n            }\n        }\n\n        shapedGlyphIt = result.next;\n    }\n}\n\nsize_t TextLayoutBuilder::appendColor(const std::optional<Color>& color) {\n    for (size_t i = 0; i < _colors.size(); i++) {\n        if (_colors[i] == color) {\n            return i;\n        }\n    }\n\n    auto previousSize = _colors.size();\n    _colors.emplace_back(color);\n    return previousSize;\n}\n\nsize_t TextLayoutBuilder::append(const std::string_view& text,\n                                 const Ref<Font>& font,\n                                 Scalar lineHeightMultiple,\n                                 Scalar letterSpacing,\n                                 TextDecoration textDecoration,\n                                 Ref<Valdi::RefCountable> attachment,\n                                 std::optional<Color> color) {\n    if (font == nullptr || text.empty()) {\n        return 0;\n    }\n\n    auto unicodeCount = utf8ToUnicode(text, _characters);\n    if (unicodeCount == 0) {\n        return 0;\n    }\n\n    auto charactersStart = _characters.size() - unicodeCount;\n\n    auto& entry = _entries.emplace_back();\n    entry.specs.font = font;\n    entry.specs.lineHeightMultiple = lineHeightMultiple;\n    entry.specs.letterSpacing = letterSpacing;\n    entry.specs.textDecoration = textDecoration;\n    entry.specs.attachment = std::move(attachment);\n    entry.specs.colorIndex = appendColor(color);\n    entry.charactersStart = charactersStart;\n    entry.charactersEnd = charactersStart + unicodeCount;\n\n    return unicodeCount;\n}\n\nstatic void appendLineOffset(TextLineOffsetVector& lineOffsets,\n                             size_t lineNumber,\n                             TextAlign textAlign,\n                             Scalar containerWidth,\n                             Scalar lineWidth,\n                             LineMetrics lineMetrics) {\n    auto index = lineNumber - 1;\n    while (index >= lineOffsets.size()) {\n        lineOffsets.emplace_back();\n    }\n\n    auto& lineOffset = lineOffsets[index];\n    lineOffset.lineMetrics = lineMetrics;\n\n    switch (textAlign) {\n        case TextAlignLeft:\n            lineOffset.horizontalOffset = 0;\n            break;\n        case TextAlignRight:\n            lineOffset.horizontalOffset = containerWidth - lineWidth;\n            break;\n        case TextAlignCenter:\n            lineOffset.horizontalOffset = containerWidth / 2 - lineWidth / 2;\n            break;\n        case TextAlignJustify:\n            lineOffset.horizontalOffset = 0;\n            break;\n    }\n}\n\nstatic TextLineSize getSegmentsLineSize(const TextLayoutBuilderSegment* begin, const TextLayoutBuilderSegment* end) {\n    TextLineSize size;\n    const auto* it = begin;\n    while (it != end) {\n        size.width = std::max(size.width, it->drawPosition.x + it->bounds.width());\n        size.lineMetrics.join(it->lineMetrics);\n        it++;\n    }\n    return size;\n}\n\ntemplate<typename T>\nstatic void forEachSegmentsLineWidth(TextLayoutBuilderSegment* begin, TextLayoutBuilderSegment* end, T&& cb) {\n    forEachSegmentsLine(begin, end, [&](size_t lineNumber, const auto* begin, const auto* end) {\n        TextLineSize lineSize = getSegmentsLineSize(begin, end);\n\n        cb(lineNumber, lineSize.width);\n    });\n}\n\nstatic Scalar calculateMaxLineWidth(TextLayoutBuilderSegment* begin, TextLayoutBuilderSegment* end) {\n    Scalar maxLineWidth = 0;\n\n    forEachSegmentsLineWidth(\n        begin, end, [&](size_t /*lineNumber*/, Scalar lineWidth) { maxLineWidth = std::max(lineWidth, maxLineWidth); });\n\n    return maxLineWidth;\n}\n\nstatic Scalar resolveContainerWidth(TextLayoutBuilderSegment* begin,\n                                    TextLayoutBuilderSegment* end,\n                                    Scalar suggestedContainerWidth) {\n    if (suggestedContainerWidth == std::numeric_limits<Scalar>::max()) {\n        return calculateMaxLineWidth(begin, end);\n    } else {\n        return suggestedContainerWidth;\n    }\n}\n\nstatic void calculateLineOffsets(TextLineOffsetVector& lineOffsets,\n                                 TextLayoutBuilderSegment* begin,\n                                 TextLayoutBuilderSegment* end,\n                                 TextAlign textAlign,\n                                 Scalar containerWidth) {\n    forEachSegmentsLine(begin, end, [&](size_t lineNumber, const auto* begin, const auto* end) {\n        TextLineSize lineSize = getSegmentsLineSize(begin, end);\n\n        appendLineOffset(lineOffsets, lineNumber, textAlign, containerWidth, lineSize.width, lineSize.lineMetrics);\n    });\n}\n\nvoid TextLayoutBuilder::setIncludeSegments(bool includeSegments) {\n    _includeSegments = includeSegments;\n}\n\nvoid TextLayoutBuilder::setIncludeTextBlob(bool includeTextBlob) {\n    _includeTextBlob = includeTextBlob;\n}\n\nvoid TextLayoutBuilder::setLineBreakStrategy(LineBreakStrategy lineBreakStrategy) {\n    _lineBreakStrategy = lineBreakStrategy;\n}\n\nvoid TextLayoutBuilder::outputSegmentToEntry(TextLayoutEntry& entry,\n                                             const ShapedGlyph* glyphsBegin,\n                                             const ShapedGlyph* glyphsEnd,\n                                             const Rect& bounds,\n                                             const Ref<Font>& font) {\n    auto& segment = entry.segments.emplace_back();\n    segment.bounds = bounds;\n    segment.font = font;\n    segment.characters = toUTF8(glyphsBegin, glyphsEnd);\n}\n\nvoid TextLayoutBuilder::reverseSegmentsHorizontally(size_t fromIndex, size_t toIndex) {\n    if (fromIndex >= toIndex) {\n        // fromIndex could be larger than toIndex if there were segments removed to fit a \"...\".\n        return;\n    }\n\n    forEachSegmentsLine(_segments.data() + fromIndex,\n                        _segments.data() + toIndex,\n                        [&](size_t /*lineNumber*/, TextLayoutBuilderSegment* begin, TextLayoutBuilderSegment* end) {\n                            auto drawPositionX = begin->drawPosition.x;\n\n                            std::reverse(begin, end);\n\n                            auto* it = begin;\n                            while (it != end) {\n                                it->drawPosition.x = drawPositionX;\n                                drawPositionX += it->bounds.width();\n                                it++;\n                            }\n                        });\n}\n\nstatic inline bool entryIncludesCharacter(const TextLayoutBuilderEntry& entry, size_t characterIndex) {\n    return characterIndex >= entry.charactersStart && characterIndex < entry.charactersEnd;\n}\n\nconst TextLayoutBuilderEntry* TextLayoutBuilder::resolveEntryAtCharacter(\n    size_t characterIndex, const TextLayoutBuilderEntry* lastEntry) const {\n    if (lastEntry != nullptr && entryIncludesCharacter(*lastEntry, characterIndex)) {\n        return lastEntry;\n    }\n\n    for (const auto& entry : _entries) {\n        if (entryIncludesCharacter(entry, characterIndex)) {\n            return &entry;\n        }\n    }\n\n    SC_ASSERT_FAIL(\"Unable to resolve matching entry for character\");\n    std::abort();\n}\n\nstatic bool fontSupportsCharacter(const Ref<Font>& font, Character c) {\n    return Unicode::isNewline(c) || font->typeface()->supportsCharacter(c);\n}\n\nstatic bool fontSupportsAllCharacters(Ref<Font>& font,\n                                      const Character* charactersStart,\n                                      const Character* charactersEnd) {\n    for (const auto* character = charactersStart; character < charactersEnd; character++) {\n        if (!fontSupportsCharacter(font, *character)) {\n            return false;\n        }\n    }\n    return true;\n}\n\nvoid processFewerFonts(TextLayoutBuilderResolvedShapeableSegments& output, const Character* characters) {\n    Ref<Font> candidateFont = nullptr;\n    auto it = output.shapeableSegments.rbegin();\n    while (it != output.shapeableSegments.rend()) {\n        bool attemptMerge = false;\n        if (candidateFont == nullptr) {\n            candidateFont = it->resolvedFont;\n        } else if (it->resolvedFont == nullptr) {\n            candidateFont = nullptr;\n        } else if (it->resolvedFont != candidateFont) {\n            // Re-evaluate the option to use the candidate font for this shapeable segment\n            if (fontSupportsAllCharacters(\n                    candidateFont, characters + it->charactersStart, characters + it->charactersEnd)) {\n                attemptMerge = true;\n                it->resolvedFont = candidateFont;\n            } else {\n                attemptMerge = false;\n                candidateFont = it->resolvedFont;\n            }\n        } else {\n            attemptMerge = true;\n        }\n\n        if (attemptMerge) {\n            auto& previousShapableSegment = *std::prev(it);\n\n            if (!it->isEndOfParagraphSegment && !it->isEndOfParagraph && it->entry == previousShapableSegment.entry &&\n                it->paragraphSegment == previousShapableSegment.paragraphSegment &&\n                previousShapableSegment.charactersStart == it->charactersEnd) {\n                previousShapableSegment.charactersStart = it->charactersStart;\n\n                // The following erases the item pointed by 'it' while returning an iterator to the next (in reverse\n                // order) item. This is a bit convoluted but required as erase() operates on iterator, not reverse\n                // iterator\n                it = decltype(it)(output.shapeableSegments.erase(std::next(it).base()));\n            } else {\n                ++it;\n            }\n        } else {\n            ++it;\n        }\n    }\n}\n\nstatic bool characterNeedsFontSupport(Character c) {\n    return !(Unicode::isBreakingWhitespace(c) || Unicode::isNewline(c) || Unicode::isUnbreakableMarker(c));\n}\n\nvoid TextLayoutBuilder::resolveShapeableSegmentsInSegmentParagraph(\n    const TextParagraph& paragraph,\n    const TextSegmentProperties& paragraphSegment,\n    const Character* characters,\n    size_t start,\n    size_t end,\n    const TextLayoutBuilderEntry* entry,\n    std::vector<TextLayoutBuilderShapeableSegment>& output) const {\n    Ref<Font> currentFont;\n    Ref<Font> fallbackFont;\n    bool currentFontIsEmoji = entry->specs.font->typeface()->isEmoji();\n    CharactersIterator iterator(characters, start, end);\n\n    while (!iterator.isAtEnd()) {\n        auto c = iterator.current();\n\n        if (characterNeedsFontSupport(c) || (currentFontIsEmoji && Unicode::isBreakingWhitespace(c))) {\n            // We attempt to resolve a new font whenever encountering a character that needs font support,\n            // or our current font is emoji and that we find a space. The latter is to deal with issues\n            // in spaces width in Skia, which end up being very large with emojis.\n            Font* resolvedFont;\n            if (fontSupportsCharacter(entry->specs.font, c)) {\n                resolvedFont = entry->specs.font.get();\n            } else if (fallbackFont != nullptr && fontSupportsCharacter(fallbackFont, c)) {\n                resolvedFont = fallbackFont.get();\n            } else {\n                auto matchedFont = _fontManager->getCompatibleFont(entry->specs.font, nullptr, 0, c);\n                if (matchedFont) {\n                    fallbackFont = matchedFont.moveValue();\n                } else {\n                    fallbackFont = nullptr;\n                }\n                resolvedFont = fallbackFont.get();\n            }\n\n            if (currentFont.get() != resolvedFont) {\n                if (currentFont != nullptr && iterator.hasRange()) {\n                    auto& currentShapeableSegment = output.emplace_back(entry, &paragraph, &paragraphSegment);\n                    currentShapeableSegment.resolvedFont = currentFont;\n                    currentShapeableSegment.charactersStart = iterator.rangeStart();\n                    currentShapeableSegment.charactersEnd = iterator.rangeEnd();\n                    iterator.resetRange();\n                }\n\n                currentFont = resolvedFont;\n                currentFontIsEmoji = resolvedFont != nullptr ? resolvedFont->typeface()->isEmoji() : false;\n            }\n            iterator.advance();\n\n            if (currentFont == nullptr) {\n                iterator.resetRange();\n            }\n        } else {\n            iterator.advance();\n        }\n    }\n\n    if (iterator.hasRange()) {\n        auto& currentShapeableSegment = output.emplace_back(entry, &paragraph, &paragraphSegment);\n        currentShapeableSegment.charactersStart = iterator.rangeStart();\n        currentShapeableSegment.charactersEnd = iterator.rangeEnd();\n        currentShapeableSegment.resolvedFont = currentFont != nullptr ? currentFont : entry->specs.font;\n    }\n}\n\nTextLayoutBuilderResolvedShapeableSegments TextLayoutBuilder::resolveShapeableSegments() const {\n    TextLayoutBuilderResolvedShapeableSegments output;\n\n    /**\n     Directional layout algorithm is as follow:\n     - Resolve the text direction segments using the TextShaper\n     - For each directional segment:\n         - Resolve the shapeable segments, which are parts of the strings that can be processed by a single font.\n         - For each shapeable segment:\n           - Shape the segment\n           - If the segment is RTL, flip the emitted glyphs, to process them in the logical order\n           - Layout the shaped glyphs across lines\n         - If the directional segment is RTL, and that the overall layout is LTR, flip the emitted sentences across\n     lines.\n         - If the directional segment is LTR, and that the overall layout is RTL, flip the emitted sentences across\n     lines.\n     - If the overall layout is RTL, flip all the emitted sentences across lines.\n     - When emitting the final text blob, the glyphs for each emitted RTL segment are added in reverse order, which is\n       the natural display order for those segments.\n\n     Example string: \"123 He Yo 4567 YO 89\"\n     The string above is an example of a bidi string in LTR and RTL.\n     The numbers represent RTL region and the letters represent LTR regions.\n     We make the assumption that \"1\", \"23\", \"He\", \"Yo\", \"456\", \"7\" need different fonts.\n     We also simulate a line breaking in the example.\n\n     Algorithm in LTR:\n     Direction segments: [123], [He Yo], [4567], [YO], [89]\n     Shapeable segments: [1] [23] [He] [Yo] [456] [7] [YO] [89]\n     Shape and layout:       [1][23] [He] [Yo]\n                             [456][7] [YO] [89]\n     Flipping RTL segments:  [23][1] [He] [Yo]\n                             [7][456] [YO] [89]\n     Text blob output:  321 He Yo\n                        7654 YO 98\n\n     Algorithm in RTL:\n     Direction segments: [123] [He Yo] [4567] [YO] [89]\n     Shapeable segments: [1] [23] [He] [Yo] [456] [7] [YO] [89]\n     Shape and layout:       [1][23] [He] [Yo]\n                             [456][7] [YO] [89]\n     Flipping LTR segments:  [1][23] [Yo] [He]\n                             [456][7] [YO] [89]\n     Flipping all segments:  [He] [Yo] [23][1]\n                             [89] [YO] [7]456]\n     Text blob output:       He Yo 321\n                             98 YO 7654\n     */\n\n    const auto* characters = _characters.data();\n    {\n        VALDI_TRACE(\"SnapDrawing.resolveParagraphs\");\n        output.paragraphList = _shaper->resolveParagraphs(characters, _characters.size(), _isRightToLeft);\n    }\n\n    const TextLayoutBuilderEntry* entry = nullptr;\n\n    VALDI_TRACE(\"SnapDrawing.resolveFontCollection\");\n    for (const auto& paragraph : output.paragraphList) {\n        for (const auto& segment : paragraph.segments) {\n            CharactersIterator iterator(characters, segment.start, segment.end);\n            const TextLayoutBuilderEntry* lastEntry = nullptr;\n\n            while (!iterator.isAtEnd()) {\n                entry = resolveEntryAtCharacter(iterator.position(), entry);\n                if (entry != lastEntry) {\n                    if (iterator.hasRange()) {\n                        resolveShapeableSegmentsInSegmentParagraph(paragraph,\n                                                                   segment,\n                                                                   characters,\n                                                                   iterator.rangeStart(),\n                                                                   iterator.rangeEnd(),\n                                                                   lastEntry,\n                                                                   output.shapeableSegments);\n                    }\n\n                    iterator.resetRange();\n\n                    lastEntry = entry;\n                }\n                iterator.advance();\n            }\n\n            if (iterator.hasRange()) {\n                resolveShapeableSegmentsInSegmentParagraph(paragraph,\n                                                           segment,\n                                                           characters,\n                                                           iterator.rangeStart(),\n                                                           iterator.rangeEnd(),\n                                                           lastEntry,\n                                                           output.shapeableSegments);\n            }\n        }\n    }\n\n    if (!output.shapeableSegments.empty()) {\n        // Compute endOfParagraph and endOfParagraphSegment flags\n        const TextParagraph* lastParagraph = nullptr;\n        const TextSegmentProperties* lastSegment = nullptr;\n\n        size_t index = output.shapeableSegments.size();\n        while (index > 0) {\n            index--;\n            auto& shapeableSegment = output.shapeableSegments[index];\n            if (shapeableSegment.paragraph != lastParagraph) {\n                lastParagraph = shapeableSegment.paragraph;\n                shapeableSegment.isEndOfParagraph = true;\n            }\n            if (shapeableSegment.paragraphSegment != lastSegment) {\n                lastSegment = shapeableSegment.paragraphSegment;\n                shapeableSegment.isEndOfParagraphSegment = true;\n            }\n        }\n    }\n\n    if (_prioritizeFewerFonts) {\n        processFewerFonts(output, characters);\n    }\n    return output;\n}\n\nvoid TextLayoutBuilder::buildSegments() {\n    // Preallocate glyphs to reduce chance we will have to allocate during shaping\n    _glyphs.reserve(_characters.size());\n    auto resolvedShapeableSegments = resolveShapeableSegments();\n    auto segmentsStartAtParagraph = _segments.size();\n    auto segmentsStartAtParagraphSegment = _segments.size();\n\n    VALDI_TRACE(\"SnapDrawing.shape\");\n    for (const auto& shapeableSegment : resolvedShapeableSegments.shapeableSegments) {\n        if (shapeableSegment.resolvedFont != nullptr) {\n            const auto* characters = _characters.data() + shapeableSegment.charactersStart;\n            processUnidirectionalRun(shapeableSegment.entry->specs.withFont(shapeableSegment.resolvedFont),\n                                     shapeableSegment.entry->specs.font,\n                                     characters,\n                                     shapeableSegment.charactersEnd - shapeableSegment.charactersStart,\n                                     shapeableSegment.paragraphSegment->script,\n                                     shapeableSegment.paragraphSegment->isRTL);\n        }\n\n        if (shapeableSegment.isEndOfParagraphSegment) {\n            if (shapeableSegment.paragraphSegment->isRTL != shapeableSegment.paragraph->baseDirectionIsRightToLeft) {\n                reverseSegmentsHorizontally(segmentsStartAtParagraphSegment, _segments.size());\n            }\n            segmentsStartAtParagraphSegment = _segments.size();\n        }\n\n        if (shapeableSegment.isEndOfParagraph) {\n            if (shapeableSegment.paragraph->baseDirectionIsRightToLeft) {\n                reverseSegmentsHorizontally(segmentsStartAtParagraph, _segments.size());\n            }\n\n            segmentsStartAtParagraph = _segments.size();\n        }\n    }\n}\n\n/**\n Contains the index for each TextLayoutBuilderSegment that has whitespace\n following it.\n */\nusing TextLayoutBuilderWhitespaceIndexes = Valdi::SmallVector<size_t, 16>;\n\nstatic void appendSegmentWord(const TextLayoutBuilderSegment& segment,\n                              const ShapedGlyph* glyphs,\n                              const ShapedGlyph* glyphsStart,\n                              const ShapedGlyph* glyphsEnd,\n                              Point* drawPosition,\n                              std::vector<TextLayoutBuilderSegment>& out) {\n    auto& newSegment = out.emplace_back(segment);\n    newSegment.glyphsStart = glyphsStart - glyphs;\n    newSegment.glyphsCount = glyphsEnd - glyphsStart;\n    newSegment.drawPosition = *drawPosition;\n\n    auto advance = computeAdvance(glyphsStart, newSegment.glyphsCount);\n    // Update the bounds so that they only contain the word chunk\n    newSegment.bounds =\n        Rect::makeXYWH(newSegment.bounds.x(), newSegment.bounds.y(), advance, newSegment.bounds.height());\n\n    drawPosition->x += advance;\n}\n\nstatic void appendWhitespaceIndexIfNeeded(const TextLayoutBuilderSegment& segment,\n                                          const std::vector<TextLayoutBuilderSegment>& segments,\n                                          TextLayoutBuilderWhitespaceIndexes& whitespaceIndexes) {\n    auto segmentsSize = segments.size();\n    if (segmentsSize == 0) {\n        // Only insert whitespace index once we have at least once segment\n        return;\n    }\n\n    auto lastSegmentIndex = segmentsSize - 1;\n\n    if (segments[lastSegmentIndex].lineNumber != segment.lineNumber) {\n        // Only insert whitespace for a segment on the current line\n        return;\n    }\n\n    if (whitespaceIndexes.empty() || whitespaceIndexes[whitespaceIndexes.size() - 1] != lastSegmentIndex) {\n        // Append the index of the segment that has whitespace following it\n        whitespaceIndexes.emplace_back(lastSegmentIndex);\n    }\n}\n\nstatic void breakDownSegmentByWords(const TextLayoutBuilderSegment& segment,\n                                    const ShapedGlyph* glyphs,\n                                    std::vector<TextLayoutBuilderSegment>& out,\n                                    Point* drawPosition,\n                                    TextLayoutBuilderWhitespaceIndexes& whitespaceIndexes) {\n    /**\n     This algorithm will break down each TextLayoutBuilderSegment into one segment per word.\n     When encountering a whitespace that can be used to justify words, the index of segment\n     following the whitespace is added into the WhitespaceIndexes.\n     */\n    const auto* glyphsIt = glyphs + segment.glyphsStart;\n    const auto* glyphsEnd = glyphsIt + segment.glyphsCount;\n    const ShapedGlyph* wordStart = nullptr;\n\n    while (glyphsIt != glyphsEnd) {\n        auto uni = glyphsIt->character();\n\n        if (Unicode::isBreakingWhitespace(uni)) {\n            if (wordStart != nullptr) {\n                appendSegmentWord(segment, glyphs, wordStart, glyphsIt, drawPosition, out);\n                wordStart = nullptr;\n            }\n\n            appendWhitespaceIndexIfNeeded(segment, out, whitespaceIndexes);\n        } else {\n            if (wordStart == nullptr) {\n                wordStart = glyphsIt;\n            }\n        }\n\n        glyphsIt++;\n    }\n\n    if (wordStart != nullptr) {\n        appendSegmentWord(segment, glyphs, wordStart, glyphsIt, drawPosition, out);\n    }\n}\n\nstatic void justifySegments(TextLayoutBuilderSegment* segments,\n                            size_t segmentsStart,\n                            size_t segmentsEnd,\n                            Scalar lineWidth,\n                            Scalar consumedCharactersWidth,\n                            const TextLayoutBuilderWhitespaceIndexes& whitespaceIndexes) {\n    if (whitespaceIndexes.empty()) {\n        return;\n    }\n\n    auto resolvedWhitespaceIndexesSize = whitespaceIndexes.size();\n    if (whitespaceIndexes[resolvedWhitespaceIndexesSize - 1] == segmentsEnd - 1) {\n        // If the last whitespace index matches the last segment, we have trailing\n        // spaces and we should ignore it\n        resolvedWhitespaceIndexesSize--;\n    }\n\n    // Calculate how much space should be inserted between each segment that has whitespace before it\n    auto widthPerWhitespaceIndex =\n        (lineWidth - consumedCharactersWidth) / static_cast<Scalar>(resolvedWhitespaceIndexesSize);\n\n    Scalar currentOffset = 0;\n    size_t currentWhitespaceIndex = 0;\n    // Go over all the segments on the line and update their drawX position to account for the whitespaces.\n    // Whenever we find a segment that has whitespace after it, we increment the current drawOffset with\n    // our calculated whitespace width.\n\n    for (size_t i = segmentsStart; i < segmentsEnd; i++) {\n        auto& segment = segments[i];\n\n        segment.drawPosition.x += currentOffset;\n\n        if (i == whitespaceIndexes[currentWhitespaceIndex]) {\n            currentOffset += widthPerWhitespaceIndex;\n            if (currentWhitespaceIndex + 1 < whitespaceIndexes.size()) {\n                currentWhitespaceIndex++;\n            }\n        }\n    }\n}\n\nvoid TextLayoutBuilder::doJustify(Scalar containerWidth) {\n    /**\n     The algorithm works as follow:\n     - For each segments in each line\n       - Break down each segment by words, such that there is at least one segment per word\n       - Gather an array containing the indexes of each segment that has whitespace before it.\n         This is because there could be multiple segments representing one word, which would be\n         the case when rendering a word using multiple fonts or colors for instance.\n       - From the whitespaces array and the container width, calculate how much space should be\n         uniformly given to each whitespace\n       - Update drawX of each segment, such that each segment will be offset by the calculated\n         whitespace if needed.\n     */\n\n    // Stash the segments away, we are going to split them into words\n    auto segments = std::move(_segments);\n    // Workaround to fix clang tidy issue\n    _segments = {};\n\n    TextLayoutBuilderWhitespaceIndexes whitespaceIndexes;\n\n    forEachSegmentsLine(\n        segments.data(),\n        segments.data() + segments.size(),\n        [&](size_t /*lineNumber*/, TextLayoutBuilderSegment* begin, TextLayoutBuilderSegment* end) {\n            whitespaceIndexes.clear();\n\n            auto segmentsStart = _segments.size();\n\n            auto drawPosition = begin->drawPosition;\n\n            const auto* it = begin;\n            while (it != end) {\n                breakDownSegmentByWords(*it, _glyphs.data(), _segments, &drawPosition, whitespaceIndexes);\n                it++;\n            }\n\n            auto segmentsEnd = _segments.size();\n\n            justifySegments(\n                _segments.data(), segmentsStart, segmentsEnd, containerWidth, drawPosition.x, whitespaceIndexes);\n        });\n}\n\nvoid TextLayoutBuilder::appendDecorationIfNeeded(std::vector<TextLayoutDecorationEntry>& decorations,\n                                                 const TextLayoutBuilderSegment& segment,\n                                                 const std::optional<Color>& color,\n                                                 Scalar resolvedSegmentX,\n                                                 Scalar resolvedSegmentY) {\n    switch (segment.textDecoration) {\n        case TextDecorationNone:\n            break;\n        case TextDecorationStrikethrough: {\n            const auto& metrics = segment.font->metrics();\n\n            auto& decorationEntry = decorations.emplace_back();\n            decorationEntry.bounds = Rect::makeXYWH(resolvedSegmentX,\n                                                    resolvedSegmentY + metrics.strikeoutPosition,\n                                                    segment.bounds.width(),\n                                                    metrics.strikeoutThickness);\n            decorationEntry.predraw = false;\n            decorationEntry.color = color;\n        } break;\n        case TextDecorationUnderline: {\n            const auto& metrics = segment.font->metrics();\n\n            auto& decorationEntry = decorations.emplace_back();\n            decorationEntry.bounds = Rect::makeXYWH(resolvedSegmentX,\n                                                    resolvedSegmentY + metrics.underlinePosition,\n                                                    segment.bounds.width(),\n                                                    metrics.underlineThickness);\n            decorationEntry.predraw = true;\n            decorationEntry.color = color;\n        } break;\n    }\n}\n\nRef<TextLayout> TextLayoutBuilder::build() {\n    buildSegments();\n\n    auto containerWidth = resolveContainerWidth(_segments.data(), _segments.data() + _segments.size(), _maxSize.width);\n\n    if (_textAlign == TextAlignJustify) {\n        doJustify(containerWidth);\n    }\n\n    std::vector<TextLayoutEntry> entries;\n    entries.reserve(_colors.size());\n\n    std::vector<TextLayoutDecorationEntry> decorations;\n    std::vector<TextLayoutAttachment> attachments;\n\n    /**\n     Step 1: Calculate the offsets to apply on every  line which will respect the given TextAlign parameter\n     and the baseline.\n     */\n    TextLineOffsetVector lineOffsets;\n    lineOffsets.reserve(static_cast<size_t>(_currentNumberOfLines));\n    calculateLineOffsets(\n        lineOffsets, _segments.data(), _segments.data() + _segments.size(), _textAlign, containerWidth);\n\n    /**\n     Step 2: Generate the SkTextBlob from the pending blobs which will be drawn at the correct location.\n     */\n\n    for (size_t colorIndex = 0; colorIndex < _colors.size(); colorIndex++) {\n        auto& layoutEntry = entries.emplace_back();\n        auto entryBounds = Rect::makeEmpty();\n        layoutEntry.bounds = Rect::makeEmpty();\n        layoutEntry.color = _colors[colorIndex];\n\n        SkTextBlobBuilder textBlobBuilder;\n\n        for (const auto& segment : _segments) {\n            if (segment.colorIndex != colorIndex) {\n                continue;\n            }\n\n            auto lineOffset = lineOffsets[segment.lineNumber - 1];\n            auto baseline = std::max(-lineOffset.lineMetrics.ascent, 0.0f);\n\n            auto resolvedSegmentX = segment.drawPosition.x + lineOffset.horizontalOffset;\n            auto resolvedSegmentY = segment.drawPosition.y + baseline;\n\n            appendDecorationIfNeeded(decorations, segment, layoutEntry.color, resolvedSegmentX, resolvedSegmentY);\n\n            auto resolvedBounds = Rect::makeXYWH(\n                resolvedSegmentX, segment.drawPosition.y, segment.bounds.width(), segment.bounds.height());\n            entryBounds.join(resolvedBounds);\n\n            if (segment.attachment != nullptr) {\n                attachments.emplace_back(resolvedBounds, segment.attachment);\n            }\n\n            const auto* glyphsIt = _glyphs.data() + segment.glyphsStart;\n            const auto* glyphsEnd = glyphsIt + segment.glyphsCount;\n\n            if (_includeSegments) {\n                outputSegmentToEntry(layoutEntry, glyphsIt, glyphsEnd, resolvedBounds, segment.font);\n            }\n\n            if (_includeTextBlob) {\n                ptrdiff_t itIncrement;\n\n                if (segment.isRightToLeft) {\n                    const auto* tmp = glyphsIt;\n                    glyphsIt = glyphsEnd - 1;\n                    glyphsEnd = tmp - 1;\n                    itIncrement = -1;\n                } else {\n                    itIncrement = 1;\n                }\n\n                const auto& run = textBlobBuilder.allocRunPos(\n                    segment.font->getSkValue(), static_cast<int>(segment.glyphsCount), &resolvedBounds.getSkValue());\n\n                auto* outPoints = run.points();\n                auto* outGlyphs = run.glyphs;\n\n                Scalar drawX = resolvedSegmentX;\n                Scalar drawY = resolvedSegmentY;\n\n                while (glyphsIt != glyphsEnd) {\n                    *outGlyphs = glyphsIt->glyphID;\n\n                    outPoints->fX = drawX + glyphsIt->offsetX;\n                    outPoints->fY = drawY + glyphsIt->offsetY;\n\n                    drawX += glyphsIt->advanceX;\n\n                    glyphsIt += itIncrement;\n                    outPoints++;\n                    outGlyphs++;\n                }\n            }\n        }\n        // Take in account trailing whitespace at the end, in case if the string ended with a newline character\n        entryBounds.bottom = std::max(entryBounds.bottom, _position.y + _currentLineMetrics.height());\n\n        if (_includeTextBlob) {\n            layoutEntry.textBlob = textBlobBuilder.make();\n        }\n        layoutEntry.bounds = entryBounds;\n    }\n\n    return Valdi::makeShared<TextLayout>(\n        _maxSize, std::move(entries), std::move(decorations), std::move(attachments), !_reachedMaxLines);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextLayoutBuilder.hpp",
    "content": "//\n//  TextLayoutBuilder.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 9/21/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n#include \"snap_drawing/cpp/Text/TextLayout.hpp\"\n#include \"snap_drawing/cpp/Text/TextShaper.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"include/core/SkTextBlob.h\"\n\n#include <memory>\n#include <optional>\n#include <string>\n\nnamespace snap::drawing {\n\nstruct ShapedGlyph;\nclass FontManager;\n\nstruct TextLayoutSpecs {\n    Ref<Font> font;\n    Ref<Valdi::RefCountable> attachment;\n    Scalar lineHeightMultiple;\n    Scalar letterSpacing;\n    TextDecoration textDecoration;\n    size_t colorIndex;\n\n    TextLayoutSpecs() = default;\n    inline TextLayoutSpecs(const Ref<Font>& font,\n                           const Ref<Valdi::RefCountable>& attachment,\n                           Scalar lineHeightMultiple,\n                           Scalar letterSpacing,\n                           TextDecoration textDecoration,\n                           size_t colorIndex)\n        : font(font),\n          attachment(attachment),\n          lineHeightMultiple(lineHeightMultiple),\n          letterSpacing(letterSpacing),\n          textDecoration(textDecoration),\n          colorIndex(colorIndex) {}\n\n    TextLayoutSpecs withFont(const Ref<Font>& newFont) const;\n};\n\nstruct TextLayoutBuilderEntry {\n    TextLayoutSpecs specs;\n    size_t charactersStart;\n    size_t charactersEnd;\n};\n\nstruct LineMetrics {\n    Scalar ascent = 0;\n    Scalar descent = 0;\n\n    constexpr LineMetrics() = default;\n    constexpr LineMetrics(Scalar ascent, Scalar descent) : ascent(ascent), descent(descent) {}\n\n    constexpr Scalar height() const {\n        return descent - ascent;\n    }\n\n    void join(const LineMetrics& other) {\n        ascent = std::min(ascent, other.ascent);\n        descent = std::max(descent, other.descent);\n    }\n};\n\nstruct TextLayoutBuilderSegment {\n    // Where to find the glyphs for this segment\n    size_t glyphsStart;\n\n    // How many glyphs should be displayed from glyphs pointer\n    size_t glyphsCount;\n\n    // The draw position, within the TextLayout, not taking in account\n    // text alignment or vertical offset\n    Point drawPosition;\n\n    // The computed bounds of the glyphs, not taking in\n    // account the drawPosition.\n    Rect bounds;\n\n    // The line number that this segment is drawn into\n    size_t lineNumber;\n\n    // The total line metrics that includes the ascent of this segment within the line\n    // and all prior segments within the same line.\n    LineMetrics lineMetrics;\n\n    // The decoration type to draw on top of the segment\n    TextDecoration textDecoration;\n\n    // The resolved font of the segment\n    Ref<Font> font;\n\n    // The attachment that was passed in through the append() call\n    Ref<Valdi::RefCountable> attachment;\n\n    // The color on which the segment should be drawn\n    size_t colorIndex;\n\n    bool isRightToLeft;\n};\n\n/**\n * TextLayoutBuilderShapeableSegment contains a single resolved font\n * with a resolved text direction.\n */\nstruct TextLayoutBuilderShapeableSegment {\n    // Holds a reference on the TextLayoutBuilderEntry, which was created\n    // by the TextLayoutBuilder::append() call.\n    const TextLayoutBuilderEntry* entry;\n    // Holds a reference on the resolved TextParagraph, which tells what base\n    // direction this segment is part of.\n    const TextParagraph* paragraph;\n    // Holds a reference on the paragraph segment within the paragraph, which tells\n    // what direction this shapeable segment should be shaped in.\n    const TextSegmentProperties* paragraphSegment;\n    // Contains the index where the characters represented by this shapeable segment\n    // start within the unicode characters array.\n    size_t charactersStart = 0;\n    // Contains the index where the characters represented by this shapeable segment\n    // end within the unicode characters array.\n    size_t charactersEnd = 0;\n    // Whether this shapeable segment is the last entry before entering a new paragraph.\n    // This could mean that the base text direction will switch from LTR to RTL or\n    // vice versa after processing this shapeable segment.\n    bool isEndOfParagraph = false;\n    // Whether this shapeable segment is the last entry before entering a new paragraph segment.\n    bool isEndOfParagraphSegment = false;\n\n    // The resolved font that should be used to shape this segment.\n    // Can be null, if no suitable fonts were found for this segment.\n    Ref<Font> resolvedFont;\n\n    inline TextLayoutBuilderShapeableSegment(const TextLayoutBuilderEntry* entry,\n                                             const TextParagraph* paragraph,\n                                             const TextSegmentProperties* paragraphSegment)\n        : entry(entry), paragraph(paragraph), paragraphSegment(paragraphSegment) {}\n};\n\n/**\n * The TextLayoutBuilderResolvedShapeableSegments contains the list of resolved paragraphs,\n * where each paragraph has a single base direction, and can contain a list of segments that\n * can be either LTR or RTL. A paragraph reads in a logical direction, which is defined\n * by the base direction. The TextLayoutBuilderResolvedShapeableSegments contains the list\n * of segments that can be shaped from the paragraph list, where each shapeable segment\n * is associated with a single font, in a single direction.\n */\nstruct TextLayoutBuilderResolvedShapeableSegments {\n    TextParagraphList paragraphList;\n    std::vector<TextLayoutBuilderShapeableSegment> shapeableSegments;\n};\n\n/**\n This defines the strategy to use to break sentences into multiple lines.\n */\nenum class LineBreakStrategy {\n    /**\n     Line break will happen between word boundaries.\n     */\n    ByWord,\n    /**\n     Line break will happen between any safe to break character.\n     */\n    ByCharacter\n\n};\n\nclass TextLayoutBuilder {\npublic:\n    TextLayoutBuilder(TextAlign textAlign,\n                      TextOverflow textOverflow,\n                      Size maxSize,\n                      int maxLinesCount,\n                      const Ref<FontManager>& fontManager,\n                      bool isRightToLeft,\n                      bool prioritizeFewerFonts = false);\n    ~TextLayoutBuilder();\n\n    /**\n     * Append a UTF-8 encoded string to the builder, associated with the given layout specs.\n     * Returns how many UTF-32 Unicode characters have been added to the builder.\n     */\n    size_t append(const std::string_view& text,\n                  const Ref<Font>& font,\n                  Scalar lineHeightMultiple,\n                  Scalar letterSpacing,\n                  TextDecoration textDecoration,\n                  Ref<Valdi::RefCountable> attachment = nullptr,\n                  std::optional<Color> color = std::nullopt);\n\n    void setIncludeSegments(bool includeSegments);\n\n    /**\n     Whether the output TextLayout should include an SkTextBlob.\n     Without an SkTextBlob, the TextLayout will not be drawable, so disabling\n     textBlob output is only suitable when measuring text.\n     */\n    void setIncludeTextBlob(bool includeTextBlob);\n\n    void setLineBreakStrategy(LineBreakStrategy lineBreakStrategy);\n\n    /**\n     * Resolves the Shapeable text segments by processing the entries that were\n     * added to the builder. Each shapeable segment defines a set of characters\n     * associated with a single font in a single direction (LTR or RTL).\n     */\n    TextLayoutBuilderResolvedShapeableSegments resolveShapeableSegments() const;\n\n    Ref<TextLayout> build();\n\nprivate:\n    TextAlign _textAlign;\n    TextOverflow _textOverflow;\n    Size _maxSize;\n    Point _position;\n    LineMetrics _currentLineMetrics;\n    size_t _maxLinesCount;\n    size_t _currentNumberOfLines = 1;\n    bool _reachedMaxLines = false;\n    bool _includeSegments = false;\n    bool _includeTextBlob = false;\n    bool _isRightToLeft;\n    bool _prioritizeFewerFonts;\n\n    Ref<FontManager> _fontManager;\n\n    // The characters from all the append calls converted into utf32\n    std::vector<Character> _characters;\n    // The entries corresponding to each append call\n    std::vector<TextLayoutBuilderEntry> _entries;\n    // The combined shaped glyphs from all the shape calls\n    std::vector<ShapedGlyph> _glyphs;\n    // The resolved segments, there will be one segment per\n    // directional run, resolved font, line number and decoration\n    std::vector<TextLayoutBuilderSegment> _segments;\n    // The list of colors used for the append calls.\n    // There will be one entry per unique color, as each color\n    // needs to be drawn individually.\n    std::vector<std::optional<Color>> _colors;\n    Ref<TextShaper> _shaper;\n    LineBreakStrategy _lineBreakStrategy = LineBreakStrategy::ByWord;\n\n    struct ShapeResult {\n        const ShapedGlyph* glyphsStart;\n        const ShapedGlyph* glyphsEnd;\n\n        constexpr ShapeResult(const ShapedGlyph* glyphsStart, const ShapedGlyph* glyphsEnd)\n            : glyphsStart(glyphsStart), glyphsEnd(glyphsEnd) {}\n    };\n\n    static Rect computeChunkBounds(const TextLayoutSpecs& specs, Scalar advance, const FontMetrics& fontMetrics);\n\n    /**\n     Compute the current line metrics into the given LineMetrics output.\n     Returns whether the computed line height fits within the constraints of our container.\n     */\n    bool computeLineMetrics(const TextLayoutSpecs& specs, const FontMetrics& fontMetrics, LineMetrics& output);\n\n    size_t appendColor(const std::optional<Color>& color);\n\n    void appendSegment(\n        const TextLayoutSpecs& specs, size_t glyphsStart, size_t glyphsCount, const Rect& bounds, bool isRightToLeft);\n\n    void processUnidirectionalRun(const TextLayoutSpecs& specs,\n                                  const Ref<Font>& originalFont,\n                                  const Character* characters,\n                                  size_t charactersLength,\n                                  TextScript script,\n                                  bool isRTL);\n\n    void buildSegments();\n    void doJustify(Scalar containerWidth);\n    void processEllipsis(const TextLayoutSpecs& specs);\n    void removeLastSegment();\n    bool removeCharactersUntilSizeFit(Size size);\n    bool shouldProcessEllipsisAfterLineBreak(const ShapedGlyph* begin,\n                                             const ShapedGlyph* end,\n                                             const ShapedGlyph* next) const;\n    bool shouldProcessEllipsisAfterLineHeightUpdate() const;\n\n    ShapeResult shape(const TextLayoutSpecs& specs,\n                      const Character* characters,\n                      size_t charactersLength,\n                      TextScript script,\n                      bool isRTL);\n\n    const TextLayoutBuilderEntry* resolveEntryAtCharacter(size_t characterIndex,\n                                                          const TextLayoutBuilderEntry* lastEntry) const;\n\n    static void outputSegmentToEntry(TextLayoutEntry& entry,\n                                     const ShapedGlyph* glyphsBegin,\n                                     const ShapedGlyph* glyphsEnd,\n                                     const Rect& bounds,\n                                     const Ref<Font>& font);\n\n    void reverseSegmentsHorizontally(size_t fromIndex, size_t toIndex);\n\n    static void appendDecorationIfNeeded(std::vector<TextLayoutDecorationEntry>& decorations,\n                                         const TextLayoutBuilderSegment& segment,\n                                         const std::optional<Color>& color,\n                                         Scalar resolvedSegmentX,\n                                         Scalar resolvedSegmentY);\n\n    void resolveShapeableSegmentsInSegmentParagraph(const TextParagraph& paragraph,\n                                                    const TextSegmentProperties& paragraphSegment,\n                                                    const Character* characters,\n                                                    size_t start,\n                                                    size_t end,\n                                                    const TextLayoutBuilderEntry* entry,\n                                                    std::vector<TextLayoutBuilderShapeableSegment>& output) const;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextShaper.cpp",
    "content": "//\n//  TextShaper.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 3/8/22.\n//\n\n#include \"snap_drawing/cpp/Text/TextShaper.hpp\"\n#include \"snap_drawing/cpp/Text/TextShaperHarfbuzz.hpp\"\n#include \"snap_drawing/cpp/Text/WordCachingTextShaper.hpp\"\n\nnamespace snap::drawing {\n\nRef<TextShaper> TextShaper::make(bool enableCache) {\n    auto strategy = enableCache ? WordCachingTextShaperStrategy::PrioritizeCorrectness :\n                                  WordCachingTextShaperStrategy::DisableCache;\n    auto harfbuzzShaper = Valdi::makeShared<TextShaperHarfbuzz>();\n    return Valdi::makeShared<WordCachingTextShaper>(harfbuzzShaper, strategy);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextShaper.hpp",
    "content": "//\n//  TextShaper.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 3/8/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Character.hpp\"\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n#include \"snap_drawing/cpp/Text/Unicode.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\nnamespace snap::drawing {\n\nconstexpr uint32_t kUnsafeToBreakMask = 1 << 31;\nconstexpr uint32_t kCharacterMask = ~kUnsafeToBreakMask;\n\nstruct ShapedGlyph {\n    Scalar offsetX;\n    Scalar offsetY;\n    Scalar advanceX;\n    SkGlyphID glyphID;\n\npublic:\n    constexpr Character character() const {\n        return characterAndFlags & kCharacterMask;\n    }\n\n    constexpr void setCharacter(Character character, bool unsafeToBreak) {\n        characterAndFlags = (character & kCharacterMask) | (unsafeToBreak ? kUnsafeToBreakMask : 0);\n    }\n\n    constexpr bool unsafeToBreak() const {\n        return (characterAndFlags & kUnsafeToBreakMask) != 0;\n    }\n\n    constexpr bool operator==(const ShapedGlyph& other) const {\n        return offsetX == other.offsetX && offsetY == other.offsetY && advanceX == other.advanceX &&\n               glyphID == other.glyphID && characterAndFlags == other.characterAndFlags;\n    }\n\n    constexpr bool operator!=(const ShapedGlyph& other) const {\n        return !(*this == other);\n    }\n\nprivate:\n    uint32_t characterAndFlags;\n};\n\nstruct TextSegmentProperties {\n    bool isRTL;\n    size_t start;\n    size_t end;\n    TextScript script;\n\n    constexpr TextSegmentProperties(bool isRTL, size_t start, size_t end, TextScript script)\n        : isRTL(isRTL), start(start), end(end), script(script) {}\n};\n\nstruct TextParagraph {\n    Valdi::SmallVector<TextSegmentProperties, 2> segments;\n    bool baseDirectionIsRightToLeft;\n};\n\nusing TextParagraphList = Valdi::SmallVector<TextParagraph, 2>;\n\nclass TextShaper : public Valdi::SimpleRefCountable {\npublic:\n    virtual void clearCache() {}\n\n    virtual TextParagraphList resolveParagraphs(const Character* unicodeText, size_t length, bool isRightToLeft) = 0;\n\n    virtual size_t shape(const Character* unicodeText,\n                         size_t length,\n                         Font& font,\n                         bool isRightToLeft,\n                         Scalar letterSpacing,\n                         TextScript script,\n                         std::vector<ShapedGlyph>& out) = 0;\n\n    static Ref<TextShaper> make(bool enableCache);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextShaperCache.cpp",
    "content": "//\n//  TextShaperCache.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/15/22.\n//\n\n#include \"snap_drawing/cpp/Text/TextShaperCache.hpp\"\n#include \"valdi_core/cpp/Utils/InlineContainerAllocator.hpp\"\n#include <boost/functional/hash.hpp>\n\nnamespace snap::drawing {\n\nstatic size_t computeHash(FontId fontId,\n                          Scalar letterSpacing,\n                          TextScript script,\n                          bool isRightToLeft,\n                          const Character* characters,\n                          size_t length) {\n    auto stringView = std::u32string_view(reinterpret_cast<const char32_t*>(characters), length);\n\n    auto hash = static_cast<size_t>(fontId);\n    boost::hash_combine(hash, std::hash<float>()(letterSpacing));\n    boost::hash_combine(hash, std::hash<uint32_t>()(script.code));\n    boost::hash_combine(hash, std::hash<bool>()(isRightToLeft));\n    boost::hash_combine(hash, std::hash<std::u32string_view>()(stringView));\n\n    return hash;\n}\n\nTextShaperCacheKey::TextShaperCacheKey(FontId fontId,\n                                       Scalar letterSpacing,\n                                       TextScript script,\n                                       bool isRightToLeft,\n                                       const Character* characters,\n                                       size_t length)\n    : TextShaperCacheKey(fontId,\n                         letterSpacing,\n                         script,\n                         isRightToLeft,\n                         characters,\n                         length,\n                         computeHash(fontId, letterSpacing, script, isRightToLeft, characters, length)) {}\n\nbool TextShaperCacheKey::operator==(const TextShaperCacheKey& other) const {\n    if (fontId != other.fontId || letterSpacing != other.letterSpacing ||\n        script != other.script != isRightToLeft != other.isRightToLeft || length != other.length) {\n        return false;\n    }\n\n    for (size_t i = 0; i < length; i++) {\n        if (characters[i] != other.characters[i]) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nbool TextShaperCacheKey::operator!=(const TextShaperCacheKey& other) const {\n    return !(*this == other);\n}\n\nTextShaperCacheNode::TextShaperCacheNode(std::pair<TextShaperCacheKey, TextShaperCacheValue>&& keyValue)\n    : Valdi::LRUCacheNode<TextShaperCacheKey, TextShaperCacheValue>(std::move(keyValue)) {}\n\nRef<TextShaperCacheNode> TextShaperCacheNode::make(FontId fontId,\n                                                   Scalar letterSpacing,\n                                                   TextScript script,\n                                                   bool isRightToLeft,\n                                                   const Character* characters,\n                                                   size_t charactersLength,\n                                                   const ShapedGlyph* glyphs,\n                                                   size_t glyphsLength,\n                                                   size_t hash) {\n    /**\n     This does a single allocation containing the TextShaperCacheNode structure, the characters array, and the shaped\n     glyphs.\n     */\n\n    auto charactersAllocSize = charactersLength * sizeof(Character);\n    auto glyphsAllocSize = glyphsLength * sizeof(ShapedGlyph);\n\n    auto baseAllocSize = sizeof(TextShaperCacheNode);\n    auto withCharactersAllocSize = Valdi::alignUp(baseAllocSize + charactersAllocSize, alignof(Character));\n    auto withGlyphsAllocSize = Valdi::alignUp(withCharactersAllocSize + glyphsAllocSize, alignof(ShapedGlyph));\n\n    std::allocator<uint8_t> allocator;\n    auto* region = allocator.allocate(withGlyphsAllocSize);\n\n    auto* allocatedCharacters = reinterpret_cast<Character*>(&region[withCharactersAllocSize - charactersAllocSize]);\n    auto* allocatedGlyphs = reinterpret_cast<ShapedGlyph*>(&region[withGlyphsAllocSize - glyphsAllocSize]);\n\n    if (characters != nullptr) {\n        std::memcpy(allocatedCharacters, characters, charactersAllocSize);\n    }\n    if (glyphs != nullptr) {\n        std::memcpy(allocatedGlyphs, glyphs, glyphsAllocSize);\n    }\n\n    auto cacheKey =\n        TextShaperCacheKey(fontId, letterSpacing, script, isRightToLeft, allocatedCharacters, charactersLength, hash);\n    auto cacheValue = TextShaperCacheValue(allocatedGlyphs, glyphsLength);\n\n    new (region)(TextShaperCacheNode)(std::make_pair(cacheKey, cacheValue));\n\n    return Ref<TextShaperCacheNode>(reinterpret_cast<TextShaperCacheNode*>(region));\n}\n\nTextShaperCache::TextShaperCache(size_t capacity) : _cache(capacity) {}\n\nTextShaperCache::~TextShaperCache() = default;\n\nvoid TextShaperCache::clear() {\n    _cache.clear();\n}\n\nbool TextShaperCache::contains(const TextShaperCacheKey& key) const {\n    return _cache.contains(key);\n}\n\nstd::optional<TextShaperCacheValue> TextShaperCache::find(const TextShaperCacheKey& key) {\n    const auto& it = _cache.find(key);\n    if (it == _cache.end()) {\n        return std::nullopt;\n    }\n\n    return {it->value()};\n}\n\nvoid TextShaperCache::insert(const TextShaperCacheKey& key, const ShapedGlyph* glyphs, size_t glyphsLength) {\n    auto node = TextShaperCacheNode::make(key.fontId,\n                                          key.letterSpacing,\n                                          key.script,\n                                          key.isRightToLeft,\n                                          key.characters,\n                                          key.length,\n                                          glyphs,\n                                          glyphsLength,\n                                          key.hash());\n    _cache.insert(node);\n}\n\n} // namespace snap::drawing\n\nnamespace std {\n\nstd::size_t hash<snap::drawing::TextShaperCacheKey>::operator()(\n    const snap::drawing::TextShaperCacheKey& k) const noexcept {\n    return k.hash();\n}\n\n} // namespace std\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextShaperCache.hpp",
    "content": "//\n//  TextShaperCache.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/15/22.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/LRUCache.hpp\"\n\n#include \"snap_drawing/cpp/Text/Character.hpp\"\n#include \"snap_drawing/cpp/Text/Font.hpp\"\n#include \"snap_drawing/cpp/Text/TextShaper.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\n#include <optional>\n\nnamespace snap::drawing {\n\nstruct TextShaperCacheKey {\n    FontId fontId = 0;\n    Scalar letterSpacing = 0.0f;\n    TextScript script;\n    bool isRightToLeft = false;\n    const Character* characters = nullptr;\n    size_t length = 0;\n\n    constexpr TextShaperCacheKey() = default;\n\n    constexpr TextShaperCacheKey(FontId fontId,\n                                 Scalar letterSpacing,\n                                 TextScript script,\n                                 bool isRightToLeft,\n                                 const Character* characters,\n                                 size_t length,\n                                 size_t hash)\n        : fontId(fontId),\n          letterSpacing(letterSpacing),\n          script(script),\n          isRightToLeft(isRightToLeft),\n          characters(characters),\n          length(length),\n          _hash(hash) {}\n\n    TextShaperCacheKey(FontId fontId,\n                       Scalar letterSpacing,\n                       TextScript script,\n                       bool isRightToLeft,\n                       const Character* characters,\n                       size_t length);\n\n    bool operator==(const TextShaperCacheKey& other) const;\n    bool operator!=(const TextShaperCacheKey& other) const;\n\n    constexpr size_t hash() const {\n        return _hash;\n    }\n\nprivate:\n    size_t _hash = 0;\n};\n\nstruct TextShaperCacheValue {\n    const ShapedGlyph* glyphs = nullptr;\n    size_t length = 0;\n\n    constexpr TextShaperCacheValue() = default;\n    constexpr TextShaperCacheValue(const ShapedGlyph* glyphs, size_t length) : glyphs(glyphs), length(length) {}\n};\n\nclass TextShaperCacheNode : public Valdi::LRUCacheNode<TextShaperCacheKey, TextShaperCacheValue> {\npublic:\n    explicit TextShaperCacheNode(std::pair<TextShaperCacheKey, TextShaperCacheValue>&& keyValue);\n\n    static Ref<TextShaperCacheNode> make(FontId fontId,\n                                         Scalar letterSpacing,\n                                         TextScript script,\n                                         bool isRightToLeft,\n                                         const Character* characters,\n                                         size_t charactersLength,\n                                         const ShapedGlyph* glyphs,\n                                         size_t glyphsLength,\n                                         size_t hash);\n};\n\n/**\n * The TextShaperCache can store shape results from a font id and a set of characters.\n * It uses an LRUCache to store the shape results.\n */\nclass TextShaperCache {\npublic:\n    explicit TextShaperCache(size_t capacity);\n    ~TextShaperCache();\n\n    void clear();\n\n    bool contains(const TextShaperCacheKey& key) const;\n    std::optional<TextShaperCacheValue> find(const TextShaperCacheKey& key);\n    void insert(const TextShaperCacheKey& key, const ShapedGlyph* glyphs, size_t glyphsLength);\n\nprivate:\n    Valdi::LRUCache<TextShaperCacheKey, TextShaperCacheValue> _cache;\n};\n\n} // namespace snap::drawing\n\nnamespace std {\n\ntemplate<>\nstruct hash<snap::drawing::TextShaperCacheKey> {\n    std::size_t operator()(const snap::drawing::TextShaperCacheKey& k) const noexcept;\n};\n\n} // namespace std\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextShaperHarfbuzz.cpp",
    "content": "//\n//  TextShaperHarfbuzz.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/9/22.\n//\n\n#include \"snap_drawing/cpp/Text/TextShaperHarfbuzz.hpp\"\n#include \"snap_drawing/cpp/Text/CharactersIterator.hpp\"\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n#include \"snap_drawing/cpp/Text/Unicode.hpp\"\n\n#include \"valdi_core/cpp/Text/UTF16Utils.hpp\"\n#include \"valdi_core/cpp/Utils/AutoMalloc.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n\n#include \"hb-icu.h\"\n#include \"hb-ot.h\"\n#include \"hb.h\"\n\n#include \"include/core/SkStream.h\"\n#include \"unicode/ubidi.h\"\n#include \"unicode/uchar.h\"\n#include <algorithm>\n\nnamespace snap::drawing {\n\nenum class TextDirectionResolutionResult {\n    Complex,\n    LeftToRight,\n    RightToLeft,\n};\n\nTextShaperHarfbuzz::TextShaperHarfbuzz() : _buffer(hb_buffer_create()) {}\nTextShaperHarfbuzz::~TextShaperHarfbuzz() = default;\n\n/**\n * Disable certain scripts (mostly those with cursive connection) from having letterspacing\n * applied. See https://github.com/behdad/harfbuzz/issues/64 for more details.\n */\nstatic bool isScriptOkForLetterspacing(hb_script_t script) {\n    return !(script == HB_SCRIPT_ARABIC || script == HB_SCRIPT_NKO || script == HB_SCRIPT_PSALTER_PAHLAVI ||\n             script == HB_SCRIPT_MANDAIC || script == HB_SCRIPT_MONGOLIAN || script == HB_SCRIPT_PHAGS_PA ||\n             script == HB_SCRIPT_DEVANAGARI || script == HB_SCRIPT_BENGALI || script == HB_SCRIPT_GURMUKHI ||\n             script == HB_SCRIPT_MODI || script == HB_SCRIPT_SHARADA || script == HB_SCRIPT_SYLOTI_NAGRI ||\n             script == HB_SCRIPT_TIRHUTA || script == HB_SCRIPT_OGHAM);\n}\n\nstatic bool isBiDiLevelRightToLeft(UBiDiLevel level) {\n    return (level & 0x1) != 0;\n}\n\nstruct UbiDiWrapper {\n    UBiDi* ptr;\n\n    UbiDiWrapper() : ptr(ubidi_open()) {}\n\n    ~UbiDiWrapper() {\n        ubidi_close(ptr);\n    }\n};\n\nstatic void appendSingleSegment(TextParagraph& paragraph,\n                                const CharactersIterator& iterator,\n                                bool isRightToLeft,\n                                TextScript script) {\n    paragraph.segments.emplace_back(isRightToLeft, iterator.rangeStart(), iterator.rangeEnd(), script);\n}\n\nstatic void doAppendSegment(\n    TextParagraph& paragraph, const Character* unicodeText, size_t start, size_t end, bool isRightToLeft) {\n    /**\n     Remove control chars from the string. We append one separate segment\n     for each uninterrupted sequence of non control characters.\n     */\n\n    CharactersIterator iterator(unicodeText, start, end);\n    auto currentScript = TextScript::common();\n\n    while (!iterator.isAtEnd()) {\n        auto c = iterator.current();\n\n        if (Unicode::isBidiControl(c)) {\n            if (iterator.hasRange()) {\n                appendSingleSegment(paragraph, iterator, isRightToLeft, currentScript);\n            }\n            iterator.advance();\n            iterator.resetRange();\n        } else {\n            auto newScript = TextScript::fromCharacter(c);\n\n            if (newScript.isStrong()) {\n                if (currentScript != newScript && currentScript.isStrong() && iterator.hasRange()) {\n                    // Changing from a strong script to another one, we append a dedicated paragraph segment for it\n                    appendSingleSegment(paragraph, iterator, isRightToLeft, currentScript);\n                    iterator.resetRange();\n                }\n\n                currentScript = newScript;\n            }\n            iterator.advance();\n        }\n    }\n\n    if (iterator.hasRange()) {\n        appendSingleSegment(paragraph, iterator, isRightToLeft, currentScript);\n    }\n}\n\nstatic TextDirectionResolutionResult resolveTextDirection(const Character* unicodeText,\n                                                          size_t length,\n                                                          bool isRightToLeft) {\n    // Use \"complex\" as initial state, when actually detecting that the text has complex or mixed\n    // direction, we will bail out of the function.\n    TextDirectionResolutionResult currentDirection = TextDirectionResolutionResult::Complex; // Use mixed to define\n\n    for (size_t i = 0; i < length; i++) {\n        auto c = unicodeText[i];\n\n        auto charDirection = u_charDirection(c);\n\n        switch (charDirection) {\n            case U_LEFT_TO_RIGHT:\n            case U_EUROPEAN_NUMBER:\n                if (currentDirection == TextDirectionResolutionResult::RightToLeft) {\n                    // mixed LTR/RTL, need full ICU\n                    return TextDirectionResolutionResult::Complex;\n                }\n                currentDirection = TextDirectionResolutionResult::LeftToRight;\n                break;\n            case U_RIGHT_TO_LEFT:\n            case U_RIGHT_TO_LEFT_ARABIC:\n            case U_ARABIC_NUMBER:\n                if (currentDirection == TextDirectionResolutionResult::LeftToRight) {\n                    // mixed LTR/RTL, need full ICU\n                    return TextDirectionResolutionResult::Complex;\n                }\n                currentDirection = TextDirectionResolutionResult::RightToLeft;\n                break;\n            case U_LEFT_TO_RIGHT_EMBEDDING:\n            case U_LEFT_TO_RIGHT_OVERRIDE:\n            case U_RIGHT_TO_LEFT_EMBEDDING:\n            case U_RIGHT_TO_LEFT_OVERRIDE:\n            case U_POP_DIRECTIONAL_FORMAT:\n            case U_FIRST_STRONG_ISOLATE:\n            case U_LEFT_TO_RIGHT_ISOLATE:\n            case U_RIGHT_TO_LEFT_ISOLATE:\n            case U_POP_DIRECTIONAL_ISOLATE:\n                // bidi markers, need full ICU\n                return TextDirectionResolutionResult::Complex;\n            case U_EUROPEAN_NUMBER_SEPARATOR:\n            case U_EUROPEAN_NUMBER_TERMINATOR:\n            case U_COMMON_NUMBER_SEPARATOR:\n            case U_BLOCK_SEPARATOR:\n            case U_SEGMENT_SEPARATOR:\n            case U_WHITE_SPACE_NEUTRAL:\n            case U_OTHER_NEUTRAL:\n            case U_DIR_NON_SPACING_MARK:\n            case U_BOUNDARY_NEUTRAL:\n            case U_CHAR_DIRECTION_COUNT:\n                // neutral characters\n                break;\n        }\n    }\n\n    if (currentDirection == TextDirectionResolutionResult::Complex) {\n        return isRightToLeft ? TextDirectionResolutionResult::RightToLeft : TextDirectionResolutionResult::LeftToRight;\n    } else {\n        return currentDirection;\n    }\n}\n\nTextParagraphList TextShaperHarfbuzz::resolveParagraphs(const Character* unicodeText,\n                                                        size_t length,\n                                                        bool isRightToLeft) {\n    auto textDirection = resolveTextDirection(unicodeText, length, isRightToLeft);\n    switch (textDirection) {\n        case TextDirectionResolutionResult::Complex:\n            return resolveParagraphsICU(unicodeText, length, isRightToLeft);\n        case TextDirectionResolutionResult::LeftToRight:\n            return resolveParagraphsPrimitive(unicodeText, length, false);\n        case TextDirectionResolutionResult::RightToLeft:\n            return resolveParagraphsPrimitive(unicodeText, length, true);\n    }\n}\n\nTextParagraphList TextShaperHarfbuzz::resolveParagraphsPrimitive(const Character* unicodeText,\n                                                                 size_t length,\n                                                                 bool isRightToLeft) {\n    TextParagraphList out;\n\n    if (length > 0) {\n        auto& paragraph = out.emplace_back();\n        paragraph.baseDirectionIsRightToLeft = isRightToLeft;\n        doAppendSegment(paragraph, unicodeText, 0, length, isRightToLeft);\n    }\n\n    return out;\n}\n\nTextParagraphList TextShaperHarfbuzz::resolveParagraphsICU(const Character* unicodeText,\n                                                           size_t length,\n                                                           bool isRightToLeft) {\n    TextParagraphList out;\n\n    Valdi::AutoMalloc<char16_t, 512> utf16Storage;\n\n    auto utf16Length = Valdi::countUtf32ToUtf16(unicodeText, length);\n    utf16Storage.resize(utf16Length);\n    utf16Length = Valdi::utf32ToUtf16(unicodeText, length, utf16Storage.data(), utf16Length);\n    Valdi::UTF16ToUTF32Index utf16Index(utf16Storage.data(), utf16Length, unicodeText, length);\n\n    UbiDiWrapper ubidi;\n\n    UErrorCode status = U_ZERO_ERROR;\n\n    ubidi_setPara(ubidi.ptr,\n                  utf16Storage.data(),\n                  static_cast<int32_t>(utf16Length),\n                  isRightToLeft ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR,\n                  nullptr,\n                  &status);\n\n    if (U_FAILURE(status) != 0) {\n        return out;\n    }\n\n    auto runsCount = ubidi_countRuns(ubidi.ptr, &status);\n\n    if (U_FAILURE(status) != 0) {\n        return out;\n    }\n\n    for (int32_t i = 0; i < runsCount; i++) {\n        int32_t logicalStart = 0;\n        int32_t logicalLength = 0;\n        auto direction = ubidi_getVisualRun(ubidi.ptr, i, &logicalStart, &logicalLength);\n\n        if (logicalLength == 0) {\n            continue;\n        }\n\n        UBiDiLevel paraLevel;\n\n        ubidi_getParagraph(ubidi.ptr, logicalStart, nullptr, nullptr, &paraLevel, &status);\n\n        if (U_FAILURE(status) != 0) {\n            status = U_ZERO_ERROR;\n            continue;\n        }\n\n        auto paragraphIsRightToLeft = isBiDiLevelRightToLeft(paraLevel);\n\n        if (out.empty() || out[out.size() - 1].baseDirectionIsRightToLeft != paragraphIsRightToLeft) {\n            // Append a paragraph if we find our run is in a paragraph that has a different base direction.\n            auto& paragraph = out.emplace_back();\n            paragraph.baseDirectionIsRightToLeft = paragraphIsRightToLeft;\n        }\n\n        auto& paragraph = out[out.size() - 1];\n\n        auto isSegmentRTL = isBiDiLevelRightToLeft(direction);\n\n        auto segmentStart = static_cast<size_t>(logicalStart);\n        auto segmentEnd = static_cast<size_t>(logicalStart + logicalLength);\n\n        doAppendSegment(paragraph,\n                        unicodeText,\n                        utf16Index.getUTF32Index(segmentStart),\n                        utf16Index.getUTF32Index(segmentEnd),\n                        isSegmentRTL);\n    }\n\n    return out;\n}\n\nsize_t TextShaperHarfbuzz::shape(const Character* unicodeText,\n                                 size_t length,\n                                 Font& font,\n                                 bool isRightToLeft,\n                                 Scalar letterSpacing,\n                                 TextScript script,\n                                 std::vector<ShapedGlyph>& out) {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n\n    auto* buffer = _buffer.get();\n    if (buffer == nullptr) {\n        return 0;\n    }\n\n    auto* hbFont = font.getHBFont().get();\n    if (hbFont == nullptr) {\n        return 0;\n    }\n\n    hb_buffer_set_content_type(buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);\n    hb_buffer_add_utf32(buffer, reinterpret_cast<const uint32_t*>(unicodeText), static_cast<int>(length), 0, -1);\n    hb_buffer_set_script(buffer, static_cast<hb_script_t>(script.code));\n    hb_buffer_set_direction(buffer, isRightToLeft ? HB_DIRECTION_RTL : HB_DIRECTION_LTR);\n    hb_buffer_guess_segment_properties(buffer);\n\n    const hb_feature_t* features = nullptr;\n    unsigned int featuresSize = 0;\n    // Disable default-on non-required ligature features if letter-spacing\n    // See http://dev.w3.org/csswg/css-text-3/#letter-spacing-property\n    // \"When the effective spacing between two characters is not zero (due to\n    // either justification or a non-zero value of letter-spacing), user agents\n    // should not apply optional ligatures.\"\n    if (letterSpacing != 0.0) {\n        static hb_feature_t kNoLigaFeatures[] = {{HB_TAG('l', 'i', 'g', 'a'), 0, 0, ~0u},\n                                                 {HB_TAG('c', 'l', 'i', 'g'), 0, 0, ~0u}};\n        features = kNoLigaFeatures;\n        featuresSize = static_cast<unsigned int>(sizeof(kNoLigaFeatures) / sizeof(hb_feature_t));\n    }\n\n    hb_shape(hbFont, buffer, features, featuresSize);\n\n    uint32_t glyphCount = 0;\n    hb_glyph_info_t* glyphInfos = hb_buffer_get_glyph_infos(buffer, &glyphCount);\n    hb_glyph_position_t* glyphPositions = hb_buffer_get_glyph_positions(buffer, &glyphCount);\n\n    int scaleX;\n    int scaleY;\n    hb_font_get_scale(hbFont, &scaleX, &scaleY);\n    auto fontSize = font.getSkValue().getSize();\n    double textSizeY = fontSize / scaleY;\n    double textSizeX = fontSize / scaleX * font.getSkValue().getScaleX();\n    Scalar advanceOffset = isScriptOkForLetterspacing(hb_buffer_get_script(_buffer.get())) ? letterSpacing : 0.0f;\n\n    auto glyphsLength = static_cast<size_t>(glyphCount);\n\n    auto glyphsStart = out.size();\n    out.resize(glyphsStart + glyphsLength);\n    auto* glyphs = out.data() + glyphsStart;\n\n    for (size_t i = 0; i < glyphsLength; i++) {\n        auto& glyph = glyphs[i];\n        auto& info = glyphInfos[i];\n        auto& pos = glyphPositions[i];\n\n        glyph.setCharacter(unicodeText[info.cluster], (info.mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK) != 0);\n        glyph.glyphID = info.codepoint;\n        glyph.offsetX = pos.x_offset * textSizeX;\n        glyph.offsetY = -(pos.y_offset * textSizeY); // HarfBuzz y-up, Skia y-down\n        glyph.advanceX = (pos.x_advance * textSizeX) + advanceOffset;\n    }\n\n    hb_buffer_clear_contents(buffer);\n\n    return glyphsLength;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TextShaperHarfbuzz.hpp",
    "content": "//\n//  TextShaperHarfbuzz.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/9/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Harfbuzz.hpp\"\n#include \"snap_drawing/cpp/Text/TextShaper.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n\nnamespace snap::drawing {\n\nstruct CachedHBFace;\n\nclass TextShaperHarfbuzz : public TextShaper {\npublic:\n    TextShaperHarfbuzz();\n    ~TextShaperHarfbuzz() override;\n\n    TextParagraphList resolveParagraphs(const Character* unicodeText, size_t length, bool isRightToLeft) override;\n\n    size_t shape(const Character* unicodeText,\n                 size_t length,\n                 Font& font,\n                 bool isRightToLeft,\n                 Scalar letterSpacing,\n                 TextScript script,\n                 std::vector<ShapedGlyph>& out) override;\n\nprivate:\n    Valdi::Mutex _mutex;\n    HBBuffer _buffer;\n\n    static TextParagraphList resolveParagraphsPrimitive(const Character* unicodeText,\n                                                        size_t length,\n                                                        bool isRightToLeft);\n    static TextParagraphList resolveParagraphsICU(const Character* unicodeText, size_t length, bool isRightToLeft);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Typeface.cpp",
    "content": "//\n//  Typeface.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n#include \"snap_drawing/cpp/Text/FontStyle.hpp\"\n\n#include \"valdi_core/cpp/Text/CharacterSet.hpp\"\n#include \"valdi_core/cpp/Utils/ByteBuffer.hpp\"\n\n#include \"include/core/SkFont.h\"\n#include \"include/core/SkFontMetrics.h\"\n#include \"include/core/SkStream.h\"\n\nnamespace snap::drawing {\n\nconstexpr Scalar kDefaultLineHeightToUnderlineThicknessRatio = 0.06;\nconstexpr Scalar kDefaultDescentUnderlineToPositionRatio = 0.2;\n\nconstexpr Scalar kDefaultLineHeightToStrikethroughThicknessRatio = 0.06;\nconstexpr Scalar kDefaultAscentToStrikethroughPositionRatio = 0.3;\n\nTypeface::Typeface(sk_sp<SkTypeface>&& typeface, const String& familyName, bool isCustom)\n    : _typeface(std::move(typeface)), _familyName(familyName), _fontStyle(_typeface->fontStyle()), _isCustom(isCustom) {\n    _hbFace = Harfbuzz::createFace(_typeface.get());\n    if (_hbFace.get() != nullptr) {\n        _hbFont = Harfbuzz::createMainFont(*_typeface, _hbFace);\n    }\n\n    _characterSet = _hbFace.getCharacters();\n    // This seems arbitrary, but I'm not sure if there is a better way\n    _isEmoji = supportsCharacter(0x270C);\n}\n\nTypeface::~Typeface() = default;\n\nuint32_t Typeface::getId() const {\n    return _typeface->uniqueID();\n}\n\nconst sk_sp<SkTypeface>& Typeface::getSkValue() const {\n    return _typeface;\n}\n\nconst String& Typeface::familyName() const {\n    return _familyName;\n}\n\nconst FontStyle& Typeface::fontStyle() const {\n    return _fontStyle;\n}\n\nbool Typeface::isCustom() const {\n    return _isCustom;\n}\n\nbool Typeface::supportsCharacter(Character character) {\n    return _characterSet->contains(character);\n}\n\nconst HBFace& Typeface::getHBFace() const {\n    return _hbFace;\n}\n\nconst HBFont& Typeface::getHBFont() const {\n    return _hbFont;\n}\n\nbool Typeface::isEmoji() const {\n    return _isEmoji;\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nbool Typeface::hasSpaceInLigaturesOrKerning() const {\n    // TODO(simon): Implement\n    return false;\n}\n\nValdi::BytesView Typeface::makeFontData() {\n    auto skStreamAsset = _typeface->openStream(nullptr);\n    if (!skStreamAsset) {\n        return Valdi::BytesView();\n    }\n\n    auto streamSize = skStreamAsset->getLength();\n    auto buffer = Valdi::makeShared<Valdi::ByteBuffer>();\n    buffer->reserve(streamSize);\n\n    auto realSize = skStreamAsset->read(buffer->data(), streamSize);\n    buffer->resize(realSize);\n    return buffer->toBytesView();\n}\n\nFontMetrics Typeface::getFontMetrics(double fontSize) {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n\n    const auto& it = _fontMetricsBySize.find(fontSize);\n    if (it != _fontMetricsBySize.end()) {\n        return it->second;\n    }\n\n    SkFont font(_typeface, fontSize);\n    font.setEdging(SkFont::Edging::kAntiAlias);\n\n    SkFontMetrics metrics;\n\n    FontMetrics out;\n    out.lineSpacing = font.getMetrics(&metrics);\n    out.descent = metrics.fDescent;\n    out.ascent = metrics.fAscent;\n\n    auto lineHeight = metrics.fDescent - metrics.fAscent;\n\n    if (!metrics.hasUnderlineThickness(&out.underlineThickness)) {\n        out.underlineThickness = kDefaultLineHeightToUnderlineThicknessRatio * lineHeight;\n    }\n\n    if (!metrics.hasUnderlinePosition(&out.underlinePosition)) {\n        out.underlinePosition = kDefaultDescentUnderlineToPositionRatio * metrics.fDescent;\n    }\n\n    if (!metrics.hasStrikeoutThickness(&out.strikeoutThickness)) {\n        out.strikeoutThickness = kDefaultLineHeightToStrikethroughThicknessRatio * lineHeight;\n    }\n\n    if (!metrics.hasStrikeoutPosition(&out.strikeoutPosition)) {\n        out.strikeoutPosition =\n            (kDefaultAscentToStrikethroughPositionRatio * metrics.fAscent) - out.strikeoutThickness / 2.0f;\n    }\n\n    _fontMetricsBySize[fontSize] = out;\n\n    return out;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Typeface.hpp",
    "content": "//\n//  Typeface.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Character.hpp\"\n#include \"snap_drawing/cpp/Text/FontMetrics.hpp\"\n#include \"snap_drawing/cpp/Text/FontStyle.hpp\"\n#include \"snap_drawing/cpp/Text/Harfbuzz.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\n#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n\n#include \"include/core/SkTypeface.h\"\n\nnamespace Valdi {\nclass CharacterSet;\n}\n\nnamespace snap::drawing {\n\nclass Typeface : public Valdi::SimpleRefCountable {\npublic:\n    Typeface(sk_sp<SkTypeface>&& typeface, const String& familyName, bool isCustom);\n    ~Typeface() override;\n\n    uint32_t getId() const;\n\n    const sk_sp<SkTypeface>& getSkValue() const;\n\n    const String& familyName() const;\n    const FontStyle& fontStyle() const;\n\n    bool isCustom() const;\n\n    bool hasSpaceInLigaturesOrKerning() const;\n\n    bool isEmoji() const;\n\n    bool supportsCharacter(Character character);\n\n    Valdi::BytesView makeFontData();\n\n    const HBFace& getHBFace() const;\n    const HBFont& getHBFont() const;\n\n    FontMetrics getFontMetrics(double fontSize);\n\nprivate:\n    mutable Valdi::Mutex _mutex;\n    sk_sp<SkTypeface> _typeface;\n    Ref<Valdi::CharacterSet> _characterSet;\n    String _familyName;\n    FontStyle _fontStyle;\n    bool _isCustom;\n    bool _isEmoji;\n    HBFace _hbFace;\n    HBFont _hbFont;\n    Valdi::FlatMap<double, FontMetrics> _fontMetricsBySize;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TypefaceRegistry.cpp",
    "content": "//\n//  TypefaceRegistry.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/13/24.\n//\n\n#include \"snap_drawing/cpp/Text/TypefaceRegistry.hpp\"\n#include \"snap_drawing/cpp/Text/FontFamily.hpp\"\n#include \"snap_drawing/cpp/Text/FontFamilyWithLoadableTypefaces.hpp\"\n#include \"snap_drawing/cpp/Text/FontFamilyWithStyleSet.hpp\"\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n#include \"valdi_core/cpp/Utils/StringCache.hpp\"\n\nnamespace snap::drawing {\n\nstatic String toFontKey(const String& fontName) {\n    auto fontKey = fontName.lowercased();\n    if (fontKey.contains(' ')) {\n        auto components = fontKey.split(' ', true);\n        fontKey = Valdi::StringBox::join(components, \"\");\n    }\n\n    return fontKey;\n}\n\nstatic String toFamilyName(const String& fontName) {\n    auto separatorIndex = fontName.lastIndexOf('-');\n    return separatorIndex ? fontName.split(*separatorIndex).first : fontName;\n}\n\nstatic Valdi::Result<std::pair<String, FontStyle>> resolveFontKeyAndStyle(const String& fontName) {\n    auto fontKey = toFontKey(fontName);\n    auto fontWeight = FontWeightNormal;\n\n    auto familyNameAndWeight = FontStyle::getFamilyNameAndFontWeight(fontKey);\n    if (!familyNameAndWeight) {\n        return familyNameAndWeight.error().rethrow(\n            STRING_FORMAT(\"Error resolving family name and weight '{}'\", fontKey));\n    }\n    std::tie(fontKey, fontWeight) = familyNameAndWeight.value();\n\n    return std::make_pair(fontKey, FontStyle(FontWidthNormal, fontWeight, FontSlantUpright));\n}\n\nTypefaceRegistry::TypefaceRegistry(Valdi::ILogger& logger, ITypefaceRegistryListener* listener)\n    : _logger(logger), _listener(listener) {}\nTypefaceRegistry::~TypefaceRegistry() = default;\n\nValdi::Result<Valdi::Ref<Typeface>> TypefaceRegistry::getTypefaceWithName(SkFontMgr& fontMgr,\n                                                                          const String& fontName,\n                                                                          FontStyle* outResolvedFontStyle) {\n    auto fontKeyAndStyleResult = resolveFontKeyAndStyle(fontName);\n    if (!fontKeyAndStyleResult) {\n        return fontKeyAndStyleResult.moveError();\n    }\n\n    auto fontKey = std::move(fontKeyAndStyleResult.value().first);\n    auto fontStyle = fontKeyAndStyleResult.value().second;\n    if (outResolvedFontStyle != nullptr) {\n        *outResolvedFontStyle = fontStyle;\n    }\n\n    auto fontFamilyIt = _fontFamilyByFontKey.find(fontKey);\n\n    if (fontFamilyIt == _fontFamilyByFontKey.end()) {\n        auto familyNameIt = _familyNameByFontKey.find(fontKey);\n        auto familyName = familyNameIt == _familyNameByFontKey.end() ? toFamilyName(fontName) : familyNameIt->second;\n        return getTypefaceWithFamilyNameAndStyle(fontMgr, familyName, fontStyle);\n    }\n\n    return getTypefaceFromFamily(fontMgr, fontFamilyIt->second, fontStyle);\n}\n\n// NOLINTNEXTLINE(readability-convert-member-functions-to-static)\nValdi::Result<Valdi::Ref<Typeface>> TypefaceRegistry::getTypefaceFromFamily(SkFontMgr& fontMgr,\n                                                                            const Ref<FontFamily>& fontFamily,\n                                                                            FontStyle fontStyle) {\n    if (fontFamily == nullptr) {\n        return Valdi::Error(\"Could not resolve Font\");\n    }\n\n    auto typeface = fontFamily->matchStyle(fontMgr, fontStyle);\n    if (typeface == nullptr) {\n        return Valdi::Error(\n            STRING_FORMAT(\"Could not resolve Font with given style in family {}\", fontFamily->getFamilyName()));\n    }\n    return typeface;\n}\n\nValdi::Result<Valdi::Ref<Typeface>> TypefaceRegistry::getTypefaceWithFamilyNameAndStyle(SkFontMgr& fontMgr,\n                                                                                        const String& familyName,\n                                                                                        FontStyle fontStyle) {\n    return getTypefaceFromFamily(fontMgr, getFontFamilyByFamilyName(familyName), fontStyle);\n}\n\nValdi::Ref<FontFamily> TypefaceRegistry::getFontFamilyByFamilyName(const String& familyName) {\n    if (familyName.hasSuffix(\"##fallback\")) {\n        return getFontFamilyByFamilyName(_fontFamilyByFallbackKey, familyName);\n    } else {\n        return getFontFamilyByFamilyName(_fontFamilyByFamilyName, familyName);\n    }\n}\n\nvoid TypefaceRegistry::registerTypeface(const String& fontFamilyName,\n                                        FontStyle fontStyle,\n                                        bool canUseAsFallback,\n                                        const Ref<LoadableTypeface>& loadableTypeface) {\n    auto fontFamily = getOrCreateFontFamilyWithLoadableTypefaces(fontFamilyName);\n    fontFamily->registerLoadableTypeface(fontStyle, loadableTypeface);\n\n    if (canUseAsFallback &&\n        std::find(_registeredFallbackFontFamilies.begin(), _registeredFallbackFontFamilies.end(), fontFamily) ==\n            _registeredFallbackFontFamilies.end()) {\n        _registeredFallbackFontFamilies.emplace_back(fontFamily);\n    }\n}\n\nvoid TypefaceRegistry::registerFamilyName(const String& familyName) {\n    auto fontKey = toFontKey(familyName);\n    _familyNameByFontKey[fontKey] = familyName;\n}\n\nValdi::Ref<FontFamily> TypefaceRegistry::getFontFamilyForCharacterAndStyle(SkFontMgr& fontMgr,\n                                                                           Character character,\n                                                                           FontStyle fontStyle) {\n    for (const auto& fontFamily : _registeredFallbackFontFamilies) {\n        // Attempt to lookup in the registered font families before hitting SkFontMgr::matchFamilyStyleCharacter\n        auto typeface = fontFamily->matchStyle(fontMgr, fontStyle);\n        if (typeface != nullptr && typeface->supportsCharacter(character)) {\n            return fontFamily;\n        }\n    }\n\n    for (const auto& it : _fontFamilyByFallbackKey) {\n        // Attempt to lookup in our cache before hitting SkFontMgr::matchFamilyStyleCharacter if we had\n        // some fallback fonts provided. This would happen only on Android.\n        auto typeface = it.second->matchStyle(fontMgr, fontStyle);\n        if (typeface != nullptr && typeface->supportsCharacter(character)) {\n            return it.second;\n        }\n    }\n\n    return nullptr;\n}\n\nValdi::Ref<FontFamily> TypefaceRegistry::getFontFamilyByFamilyName(\n    Valdi::FlatMap<String, Ref<FontFamily>>& fontFamilyMap, const String& familyName) {\n    Ref<FontFamily> fontFamily;\n\n    const auto& resultByFamilyName = fontFamilyMap.find(familyName);\n    if (resultByFamilyName != fontFamilyMap.end()) {\n        fontFamily = resultByFamilyName->second;\n    } else {\n        auto fontKey = toFontKey(familyName);\n        const auto& resultByFontKey = _fontFamilyByFontKey.find(fontKey);\n        if (resultByFontKey != _fontFamilyByFontKey.end()) {\n            fontFamily = resultByFontKey->second;\n        } else {\n            if (_listener != nullptr) {\n                fontFamily = _listener->onFontFamilyMissing(familyName);\n                fontFamilyMap[familyName] = fontFamily;\n                _fontFamilyByFontKey[fontKey] = fontFamily;\n            }\n        }\n    }\n    return fontFamily;\n}\n\nRef<FontFamilyWithLoadableTypefaces> TypefaceRegistry::getOrCreateFontFamilyWithLoadableTypefaces(\n    const String& fontFamilyName) {\n    auto fontKey = toFontKey(fontFamilyName);\n\n    Ref<FontFamilyWithLoadableTypefaces> fontFamily;\n    const auto& it = _fontFamilyByFontKey.find(fontKey);\n    if (it != _fontFamilyByFontKey.end()) {\n        fontFamily = Valdi::castOrNull<FontFamilyWithLoadableTypefaces>(it->second);\n    }\n\n    if (fontFamily == nullptr) {\n        fontFamily = Valdi::makeShared<FontFamilyWithLoadableTypefaces>(_logger, fontFamilyName);\n        _fontFamilyByFontKey[fontKey] = fontFamily;\n    }\n\n    return fontFamily;\n}\n\nstd::vector<String> TypefaceRegistry::getAllAvailableTypefaceNames() const {\n    std::vector<String> availableFonts;\n    availableFonts.reserve(_fontFamilyByFamilyName.size());\n\n    for (const auto& it : _fontFamilyByFamilyName) {\n        availableFonts.emplace_back(it.first);\n    }\n\n    for (const auto& it : _fontFamilyByFallbackKey) {\n        availableFonts.emplace_back(it.first);\n    }\n\n    return availableFonts;\n}\n\nValdi::ILogger& TypefaceRegistry::getLogger() const {\n    return _logger;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/TypefaceRegistry.hpp",
    "content": "//\n//  TypefaceRegistry.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/13/24.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Character.hpp\"\n#include \"snap_drawing/cpp/Text/FontStyle.hpp\"\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include <vector>\n\nclass SkFontMgr;\n\nnamespace Valdi {\nclass ILogger;\n}\n\nnamespace snap::drawing {\n\nclass TextShaper;\nclass FontFamily;\nclass FontFamilyWithLoadableTypefaces;\nclass LoadableTypeface;\nclass Typeface;\n\nclass ITypefaceRegistryListener {\npublic:\n    virtual ~ITypefaceRegistryListener() = default;\n\n    /**\n     Called whenever a FontFamily was not found within the TypefaceRegistry. It gives an opportunity\n     to the listener to resolve and return the missing FontFamily.\n     */\n    virtual Ref<FontFamily> onFontFamilyMissing(const String& familyName) = 0;\n};\n\nclass TypefaceRegistry {\npublic:\n    TypefaceRegistry(Valdi::ILogger& logger, ITypefaceRegistryListener* listener);\n    ~TypefaceRegistry();\n\n    std::vector<String> getAllAvailableTypefaceNames() const;\n\n    Valdi::Result<Valdi::Ref<Typeface>> getTypefaceWithName(SkFontMgr& fontMgr,\n                                                            const String& fontName,\n                                                            FontStyle* outResolvedFontStyle);\n    Valdi::Result<Valdi::Ref<Typeface>> getTypefaceWithFamilyNameAndStyle(SkFontMgr& fontMgr,\n                                                                          const String& familyName,\n                                                                          FontStyle fontStyle);\n\n    Valdi::Ref<FontFamily> getFontFamilyByFamilyName(const String& familyName);\n\n    Valdi::Ref<FontFamily> getFontFamilyForCharacterAndStyle(SkFontMgr& fontMgr,\n                                                             Character character,\n                                                             FontStyle fontStyle);\n\n    Valdi::Result<Valdi::Ref<Typeface>> getTypefaceFromFamily(SkFontMgr& fontMgr,\n                                                              const Ref<FontFamily>& fontFamily,\n                                                              FontStyle fontStyle);\n\n    void registerFamilyName(const String& familyName);\n\n    /**\n     Registers a Typeface from a loadable typeface. This will make the typeface available through the various\n     getTypeface methods.\n     */\n    void registerTypeface(const String& fontFamilyName,\n                          FontStyle fontStyle,\n                          bool canUseAsFallback,\n                          const Ref<LoadableTypeface>& loadableTypeface);\n\n    Valdi::ILogger& getLogger() const;\n\nprivate:\n    Valdi::ILogger& _logger;\n    ITypefaceRegistryListener* _listener;\n    Valdi::FlatMap<String, String> _familyNameByFontKey;\n    Valdi::FlatMap<String, Ref<FontFamily>> _fontFamilyByFontKey;\n    Valdi::FlatMap<String, Ref<FontFamily>> _fontFamilyByFamilyName;\n    Valdi::FlatMap<String, Ref<FontFamily>> _fontFamilyByFallbackKey;\n    std::vector<Ref<FontFamily>> _registeredFallbackFontFamilies;\n\n    Ref<FontFamilyWithLoadableTypefaces> getOrCreateFontFamilyWithLoadableTypefaces(const String& fontFamilyName);\n\n    Valdi::Ref<FontFamily> getFontFamilyByFamilyName(Valdi::FlatMap<String, Ref<FontFamily>>& fontFamilyMap,\n                                                     const String& familyName);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Unicode.cpp",
    "content": "//\n//  Unicode.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/4/23.\n//\n\n#include \"snap_drawing/cpp/Text/Unicode.hpp\"\n#include \"hb.h\"\n\nnamespace snap::drawing {\n\nconstexpr Character kLREChar = 0x202a;\nconstexpr Character kLRIChar = 0x2066;\n\nconstexpr Character kVariationSelectorStart = 0xFE00;\nconstexpr Character kVariationSelectorEnd = 0xFE0F;\nconstexpr Character kVariationSelectorSupplementStart = 0xE0100;\nconstexpr Character kVariationSelectorSupplementEnd = 0xE01EF;\n\nbool Unicode::isBreakingWhitespace(Character c) {\n    switch (c) {\n        case 0x0020: // SPACE\n        // case 0x00A0: // NO-BREAK SPACE\n        case 0x1680: // OGHAM SPACE MARK\n        case 0x180E: // MONGOLIAN VOWEL SEPARATOR\n        case 0x2000: // EN QUAD\n        case 0x2001: // EM QUAD\n        case 0x2002: // EN SPACE (nut)\n        case 0x2003: // EM SPACE (mutton)\n        case 0x2004: // THREE-PER-EM SPACE (thick space)\n        case 0x2005: // FOUR-PER-EM SPACE (mid space)\n        case 0x2006: // SIX-PER-EM SPACE\n        case 0x2007: // FIGURE SPACE\n        case 0x2008: // PUNCTUATION SPACE\n        case 0x2009: // THIN SPACE\n        case 0x200A: // HAIR SPACE\n        case 0x200B: // ZERO WIDTH SPACE\n        case 0x202F: // NARROW NO-BREAK SPACE\n        case 0x205F: // MEDIUM MATHEMATICAL SPACE\n        case 0x3000: // IDEOGRAPHIC SPACE\n                     // case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE\n            return true;\n        default:\n            return false;\n    }\n}\n\nbool Unicode::isNewline(Character c) {\n    switch (c) {\n        case 0x000A:\n        case 0x0D0A:\n            return true;\n        default:\n            return false;\n    }\n}\n\nbool Unicode::isUnbreakableMarker(Character c) {\n    switch (c) {\n        case 0x034F: // COMBINING GRAPHEME JOINER\n        case 0x061C: // ARABIC LETTER MARK\n        case 0x200C: // ZERO WIDTH NON-JOINER\n        case 0x200D: // ZERO WIDTH JOINER\n        case 0xFEFF: // BYTE-ORDER MARK\n            return true;\n        default:\n            return isVariationSelector(c);\n    }\n}\n\ninline static bool isBMPVariationSelector(Character c) {\n    return c >= kVariationSelectorStart && c <= kVariationSelectorEnd;\n}\n\ninline static bool isVariationSelectorSupplement(Character c) {\n    return c >= kVariationSelectorSupplementStart && c <= kVariationSelectorSupplementEnd;\n}\n\nbool Unicode::isVariationSelector(Character c) {\n    return isBMPVariationSelector(c) || isVariationSelectorSupplement(c);\n}\n\nbool Unicode::isBidiControl(Character c) {\n    return (c - kLREChar) < 5 || (c - kLRIChar) < 4;\n}\n\nstd::string TextScript::toString() const {\n    std::string out;\n    out.resize(4);\n\n    hb_tag_to_string(code, out.data());\n\n    return out;\n}\n\nbool TextScript::isStrong() const {\n    return code != HB_SCRIPT_UNKNOWN && code != HB_SCRIPT_INHERITED && code != HB_SCRIPT_COMMON;\n}\n\nTextScript TextScript::fromCharacter(Character c) {\n    static auto* kUnicodeFont = hb_unicode_funcs_get_default();\n    return TextScript(hb_unicode_script(kUnicodeFont, c));\n}\n\nTextScript TextScript::common() {\n    return TextScript(HB_SCRIPT_COMMON);\n}\n\nstatic_assert(TextScript::invalid().code == HB_SCRIPT_INVALID);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/Unicode.hpp",
    "content": "//\n//  Unicode.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/4/23.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Character.hpp\"\n#include <string>\n\nnamespace snap::drawing {\n\n/**\n Utility functions to deal with Unicode points.\n Could be later migrated to use libicu\n */\nclass Unicode {\npublic:\n    /**\n     Returns whether the Character represents a whitespace that can be used as word break.\n     */\n    static bool isBreakingWhitespace(Character c);\n\n    /**\n     Returns whether the character represents a newline\n     */\n    static bool isNewline(Character c);\n\n    /**\n     Returns whether the character represents a Unicode marker that\n     should be treated alongside surrounding characters, meaning that\n     it would be illegal to break the string on this character.\n     */\n    static bool isUnbreakableMarker(Character c);\n\n    /**\n     Returns whether the character represents a variation selector.\n     */\n    static bool isVariationSelector(Character c);\n\n    /**\n     Returns whether the character represents a bidi control character\n     */\n    static bool isBidiControl(Character c);\n};\n\n/**\n TextScript represents a collection of letters and signs within a writing\n systems, like Latin for example which is used in English, French, Italian...,\n or Arabic which is used in Persian, Punjabi, Sindhi etc...\n */\nstruct TextScript {\n    uint32_t code = 0;\n\n    constexpr TextScript() = default;\n    explicit constexpr TextScript(uint32_t code) : code(code) {}\n\n    std::string toString() const;\n\n    constexpr bool operator==(const TextScript& other) const {\n        return code == other.code;\n    }\n\n    constexpr bool operator!=(const TextScript& other) const {\n        return code != other.code;\n    }\n\n    /**\n     Returns whether the script is a known and not common script,\n     like Latin or Arabic. Script representing punctation letters\n     or whitespaces are considered weak.\n     */\n    bool isStrong() const;\n\n    static TextScript fromCharacter(Character c);\n\n    static constexpr TextScript invalid() {\n        return TextScript(0);\n    }\n\n    static TextScript common();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/WordCachingTextShaper.cpp",
    "content": "//\n//  WordCachingTextShaper.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/15/22.\n//\n\n#include \"snap_drawing/cpp/Text/WordCachingTextShaper.hpp\"\n#include \"snap_drawing/cpp/Text/CharactersIterator.hpp\"\n#include \"snap_drawing/cpp/Text/Typeface.hpp\"\n\nnamespace snap::drawing {\n\nconstexpr size_t kWordCacheSize = 1000;\nconstexpr Scalar kUniformFontSize = 12;\n\nWordCachingTextShaper::WordCachingTextShaper(const Ref<TextShaper>& innerShaper, WordCachingTextShaperStrategy strategy)\n    : _innerShaper(innerShaper), _cache(kWordCacheSize), _strategy(strategy) {}\nWordCachingTextShaper::~WordCachingTextShaper() = default;\n\nvoid WordCachingTextShaper::clearCache() {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    _cache.clear();\n}\n\nTextParagraphList WordCachingTextShaper::resolveParagraphs(const Character* unicodeText,\n                                                           size_t length,\n                                                           bool isRightToLeft) {\n    return _innerShaper->resolveParagraphs(unicodeText, length, isRightToLeft);\n}\n\nsize_t WordCachingTextShaper::shape(const Character* unicodeText,\n                                    size_t length,\n                                    Font& font,\n                                    bool isRightToLeft,\n                                    Scalar letterSpacing,\n                                    TextScript script,\n                                    std::vector<ShapedGlyph>& out) {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n\n    if (font.typeface()->hasSpaceInLigaturesOrKerning()) {\n        return _innerShaper->shape(unicodeText, length, font, isRightToLeft, letterSpacing, script, out);\n    }\n\n    switch (_strategy) {\n        case WordCachingTextShaperStrategy::DisableCache:\n            return _innerShaper->shape(unicodeText, length, font, isRightToLeft, letterSpacing, script, out);\n        case WordCachingTextShaperStrategy::PrioritizeCacheHit:\n            return shapeUsingUniformFont(unicodeText, length, font, isRightToLeft, letterSpacing, script, out);\n        case WordCachingTextShaperStrategy::PrioritizeCorrectness:\n            return breakdownByWordAndShape(unicodeText, length, font, isRightToLeft, letterSpacing, script, out);\n    }\n}\n\nsize_t WordCachingTextShaper::shapeUsingUniformFont(const Character* unicodeText,\n                                                    size_t length,\n                                                    Font& font,\n                                                    bool isRightToLeft,\n                                                    Scalar letterSpacing,\n                                                    TextScript script,\n                                                    std::vector<ShapedGlyph>& out) {\n    auto uniformFont = getUniformFont(font.typeface());\n\n    auto written =\n        breakdownByWordAndShape(unicodeText, length, *uniformFont, isRightToLeft, letterSpacing, script, out);\n\n    auto* glyphsIt = &out[out.size() - written];\n\n    // Scale the written shaped glyph to account for the difference in scale\n    auto ratio = font.resolvedSize() / uniformFont->resolvedSize();\n\n    for (size_t i = 0; i < written; i++) {\n        auto& glyph = glyphsIt[i];\n\n        glyph.advanceX *= ratio;\n        glyph.offsetX *= ratio;\n        glyph.offsetY *= ratio;\n    }\n\n    return written;\n}\n\nsize_t WordCachingTextShaper::breakdownByWordAndShape(const Character* unicodeText,\n                                                      size_t length,\n                                                      Font& font,\n                                                      bool isRightToLeft,\n                                                      Scalar letterSpacing,\n                                                      TextScript script,\n                                                      std::vector<ShapedGlyph>& out) {\n    auto sizeBefore = out.size();\n\n    auto fontId = font.getFontId();\n\n    std::optional<ShapedGlyph> spaceGlyph;\n\n    CharactersIterator iterator(unicodeText, length);\n\n    while (!iterator.isAtEnd()) {\n        auto c = iterator.current();\n\n        if (c == static_cast<Character>(' ')) {\n            if (iterator.hasRange()) {\n                shapeWord(&unicodeText[iterator.rangeStart()],\n                          iterator.rangeLength(),\n                          fontId,\n                          font,\n                          isRightToLeft,\n                          letterSpacing,\n                          script,\n                          out);\n            }\n\n            iterator.advance();\n            iterator.resetRange();\n\n            if (!spaceGlyph) {\n                spaceGlyph = {getSpaceGlyphForFont(fontId, font)};\n            }\n\n            out.emplace_back(spaceGlyph.value());\n        } else {\n            iterator.advance();\n        }\n    }\n\n    if (iterator.hasRange()) {\n        shapeWord(&unicodeText[iterator.rangeStart()],\n                  iterator.rangeLength(),\n                  fontId,\n                  font,\n                  isRightToLeft,\n                  letterSpacing,\n                  script,\n                  out);\n    }\n\n    auto outputSize = out.size();\n\n    if (isRightToLeft) {\n        std::reverse(out.data() + sizeBefore, out.data() + outputSize);\n    }\n\n    return outputSize - sizeBefore;\n}\n\nvoid WordCachingTextShaper::shapeWord(const Character* unicodeText,\n                                      size_t length,\n                                      FontId fontId,\n                                      Font& font,\n                                      bool isRightToLeft,\n                                      Scalar letterSpacing,\n                                      TextScript script,\n                                      std::vector<ShapedGlyph>& out) {\n    auto cacheKey = TextShaperCacheKey(fontId, letterSpacing, script, isRightToLeft, unicodeText, length);\n    auto cacheResult = _cache.find(cacheKey);\n\n    if (cacheResult) {\n        copyGlyphs(cacheResult.value().glyphs, cacheResult.value().length, out);\n        return;\n    }\n\n    auto writtenGlyphsLength =\n        _innerShaper->shape(unicodeText, length, font, isRightToLeft, letterSpacing, script, _tmp);\n\n    auto* writtenGlyphs = _tmp.data();\n\n    if (isRightToLeft) {\n        std::reverse(writtenGlyphs, writtenGlyphs + writtenGlyphsLength);\n    }\n\n    _cache.insert(cacheKey, writtenGlyphs, writtenGlyphsLength);\n    copyGlyphs(writtenGlyphs, writtenGlyphsLength, out);\n    _tmp.clear();\n}\n\nRef<Font> WordCachingTextShaper::getUniformFont(const Ref<Typeface>& typeface) {\n    const auto& it = _uniformFonts.find(typeface->getId());\n    if (it != _uniformFonts.end()) {\n        return it->second;\n    }\n\n    auto font = Valdi::makeShared<Font>(nullptr, Ref<Typeface>(typeface), kUniformFontSize, 1.0, false);\n    _uniformFonts[typeface->getId()] = font;\n\n    return font;\n}\n\nvoid WordCachingTextShaper::copyGlyphs(const ShapedGlyph* glyphs, size_t length, std::vector<ShapedGlyph>& out) {\n    auto beforeSize = out.size();\n    out.resize(beforeSize + length);\n\n    auto* outGlyphs = &out[beforeSize];\n    for (size_t i = 0; i < length; i++) {\n        outGlyphs[i] = glyphs[i];\n    }\n}\n\nShapedGlyph WordCachingTextShaper::getSpaceGlyphForFont(FontId fontId, Font& font) {\n    auto text = static_cast<Character>(' ');\n    auto cacheKey = TextShaperCacheKey(fontId, 0.0f, TextScript::common(), false, &text, 1);\n\n    auto cacheResult = _cache.find(cacheKey);\n    if (cacheResult && cacheResult.value().length == 1) {\n        return cacheResult.value().glyphs[0];\n    }\n\n    auto spaceGlyphId = font.getSkValue().unicharToGlyph(static_cast<SkUnichar>(text));\n    SkScalar width;\n    font.getSkValue().getWidths(&spaceGlyphId, 1, &width);\n\n    ShapedGlyph glyph;\n    glyph.glyphID = spaceGlyphId;\n    glyph.offsetX = 0;\n    glyph.offsetY = 0;\n    glyph.advanceX = width;\n    glyph.setCharacter(text, false);\n\n    _cache.insert(cacheKey, &glyph, 1);\n\n    return glyph;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Text/WordCachingTextShaper.hpp",
    "content": "//\n//  WordCachingTextShaper.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 11/15/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/TextShaper.hpp\"\n#include \"snap_drawing/cpp/Text/TextShaperCache.hpp\"\n#include \"valdi_core/cpp/Utils/FlatMap.hpp\"\n\nnamespace snap::drawing {\n\nenum class WordCachingTextShaperStrategy { DisableCache, PrioritizeCacheHit, PrioritizeCorrectness };\n\n/**\n * A TextShaper implementation that breaks down shaping by words and use a cache.\n * The given innerShaper will be used to shape the individual words on a cache miss.\n */\nclass WordCachingTextShaper : public TextShaper {\npublic:\n    WordCachingTextShaper(const Ref<TextShaper>& innerShaper, WordCachingTextShaperStrategy strategy);\n    ~WordCachingTextShaper() override;\n\n    void clearCache() override;\n\n    TextParagraphList resolveParagraphs(const Character* unicodeText, size_t length, bool isRightToLeft) override;\n\n    size_t shape(const Character* unicodeText,\n                 size_t length,\n                 Font& font,\n                 bool isRightToLeft,\n                 Scalar letterSpacing,\n                 TextScript script,\n                 std::vector<ShapedGlyph>& out) override;\n\nprivate:\n    Valdi::Mutex _mutex;\n    Ref<TextShaper> _innerShaper;\n    TextShaperCache _cache;\n    WordCachingTextShaperStrategy _strategy;\n    Valdi::FlatMap<uint32_t, Ref<Font>> _uniformFonts;\n    std::vector<ShapedGlyph> _tmp;\n\n    size_t shapeUsingUniformFont(const Character* unicodeText,\n                                 size_t length,\n                                 Font& font,\n                                 bool isRightToLeft,\n                                 Scalar letterSpacing,\n                                 TextScript script,\n                                 std::vector<ShapedGlyph>& out);\n\n    size_t breakdownByWordAndShape(const Character* unicodeText,\n                                   size_t length,\n                                   Font& font,\n                                   bool isRightToLeft,\n                                   Scalar letterSpacing,\n                                   TextScript script,\n                                   std::vector<ShapedGlyph>& out);\n\n    void shapeWord(const Character* unicodeText,\n                   size_t length,\n                   FontId fontId,\n                   Font& font,\n                   bool isRightToLeft,\n                   Scalar letterSpacing,\n                   TextScript script,\n                   std::vector<ShapedGlyph>& out);\n\n    ShapedGlyph getSpaceGlyphForFont(FontId fontId, Font& font);\n\n    Ref<Font> getUniformFont(const Ref<Typeface>& typeface);\n\n    static void copyGlyphs(const ShapedGlyph* glyphs, size_t length, std::vector<ShapedGlyph>& out);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/AttributedTextOnTapGestureRecognizer.cpp",
    "content": "//\n//  AttributedTextOnTapGestureRecognizer.cpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 12/22/22.\n//\n\n#include \"snap_drawing/cpp/Touches/AttributedTextOnTapGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Text/AttributedText.hpp\"\n#include \"snap_drawing/cpp/Text/TextLayout.hpp\"\n\nnamespace snap::drawing {\n\nAttributedTextOnTapGestureRecognizer::AttributedTextOnTapGestureRecognizer(\n    const GesturesConfiguration& gesturesConfiguration)\n    : TapGestureRecognizer(1, gesturesConfiguration), _touchTolerance(gesturesConfiguration.touchTolerance) {\n    setListener(AttributedTextOnTapGestureRecognizer::makeOnTapListener());\n}\n\nAttributedTextOnTapGestureRecognizer::~AttributedTextOnTapGestureRecognizer() = default;\n\nvoid AttributedTextOnTapGestureRecognizer::setTextLayout(const Ref<TextLayout>& textLayout) {\n    _textLayout = textLayout;\n}\n\nbool AttributedTextOnTapGestureRecognizer::shouldBegin() {\n    _onTapAttribute = nullptr;\n    if (_textLayout == nullptr) {\n        return false;\n    }\n\n    auto attachment = _textLayout->getAttachmentAtPoint(getLocation(), _touchTolerance);\n    _onTapAttribute = Valdi::castOrNull<AttributedTextOnTapAttribute>(attachment);\n    return _onTapAttribute != nullptr;\n}\n\nvoid AttributedTextOnTapGestureRecognizer::forwardTouchEvent(GestureRecognizerState state,\n                                                             const Point& location) const {\n    if (_onTapAttribute != nullptr) {\n        _onTapAttribute->onTap(*this, state, location);\n    }\n}\n\nvoid AttributedTextOnTapGestureRecognizer::onReset() {\n    _onTapAttribute = nullptr;\n    TapGestureRecognizer::onReset();\n}\n\nTapGestureRecognizer::Listener AttributedTextOnTapGestureRecognizer::makeOnTapListener() {\n    return [](const auto& gesture, auto state, const auto& event) {\n        dynamic_cast<const AttributedTextOnTapGestureRecognizer&>(gesture).forwardTouchEvent(state, event);\n    };\n}\n\nstd::string_view AttributedTextOnTapGestureRecognizer::getTypeName() const {\n    return \"text link\";\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/AttributedTextOnTapGestureRecognizer.hpp",
    "content": "//\n//  AttributedTextOnTapGestureRecognizer.hpp\n//  snap_drawing-macos\n//\n//  Created by Simon Corsin on 12/22/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nclass TextLayout;\nclass AttributedTextOnTapAttribute;\n\nclass AttributedTextOnTapGestureRecognizer : public TapGestureRecognizer {\npublic:\n    AttributedTextOnTapGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~AttributedTextOnTapGestureRecognizer() override;\n\n    void setTextLayout(const Ref<TextLayout>& textLayout);\n\nprotected:\n    bool shouldBegin() override;\n    void onReset() override;\n\n    std::string_view getTypeName() const final;\n\nprivate:\n    Ref<TextLayout> _textLayout;\n    Ref<AttributedTextOnTapAttribute> _onTapAttribute;\n    Scalar _touchTolerance;\n\n    void forwardTouchEvent(GestureRecognizerState state, const Point& location) const;\n\n    static TapGestureRecognizer::Listener makeOnTapListener();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/DoubleTapGestureRecognizer.cpp",
    "content": "//\n//  DoubleTapGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Vincent Brunet on 01/07/21.\n//\n\n#include \"snap_drawing/cpp/Touches/DoubleTapGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nDoubleTapGestureRecognizer::DoubleTapGestureRecognizer(const GesturesConfiguration& gesturesConfiguration)\n    : TapGestureRecognizer(2, gesturesConfiguration) {}\n\nDoubleTapGestureRecognizer::~DoubleTapGestureRecognizer() = default;\n\nstd::string_view DoubleTapGestureRecognizer::getTypeName() const {\n    return \"double tap\";\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/DoubleTapGestureRecognizer.hpp",
    "content": "//\n//  DoubleTapGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Vincent Brunet on 01/07/21.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nclass DoubleTapGestureRecognizer : public TapGestureRecognizer {\npublic:\n    DoubleTapGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~DoubleTapGestureRecognizer() override;\n\nprotected:\n    std::string_view getTypeName() const final;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/DragGestureRecognizer.cpp",
    "content": "//\n//  DragGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/PinchGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/RotateGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\n#include \"utils/debugging/Assert.hpp\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nDragGestureRecognizer::DragGestureRecognizer(const GesturesConfiguration& gesturesConfiguration)\n    : _dragThreshold(gesturesConfiguration.dragTouchSlop) {}\n\nDragGestureRecognizer::~DragGestureRecognizer() = default;\n\nbool DragGestureRecognizer::requiresFailureOf(const GestureRecognizer& other) const {\n    return dynamic_cast<const DragGestureRecognizer*>(&other) != nullptr;\n}\n\nbool DragGestureRecognizer::canRecognizeSimultaneously(const GestureRecognizer& other) const {\n    if (dynamic_cast<const PinchGestureRecognizer*>(&other) != nullptr) {\n        return true;\n    }\n    if (dynamic_cast<const RotateGestureRecognizer*>(&other) != nullptr) {\n        return true;\n    }\n    return false;\n}\n\nDragEvent DragGestureRecognizer::makeMoveEvent() const {\n    return MoveGestureRecognizer<DragEvent>::makeMoveEvent();\n}\n\nbool DragGestureRecognizer::shouldStartMove(const TouchEvent& event) const {\n    auto distance = Point::distance(_moveState->startEvent.getLocationInWindow(), event.getLocationInWindow());\n    auto movedEnough = (distance >= _dragThreshold);\n    auto multipleTouch = event.getPointerCount() > 1;\n    return (movedEnough || multipleTouch);\n}\n\nbool DragGestureRecognizer::shouldContinueMove(const TouchEvent& event) const {\n    // we continue drags even if pointers change, to support multitouch and composing gestures\n    return event.getPointerCount() > 0;\n}\n\nstd::string_view DragGestureRecognizer::getTypeName() const {\n    return \"drag\";\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/DragGestureRecognizer.hpp",
    "content": "//\n//  DragGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n#include \"snap_drawing/cpp/Touches/MoveGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nstruct DragEvent {\n    Point location;\n    Size offset;\n    Vector velocity;\n    TimePoint time;\n    size_t pointerCount;\n\n    DragEvent() : time(0), pointerCount(0) {};\n};\n\nclass DragGestureRecognizer : public MoveGestureRecognizer<DragEvent> {\npublic:\n    explicit DragGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~DragGestureRecognizer() override;\n\n    bool requiresFailureOf(const GestureRecognizer& other) const override;\n    bool canRecognizeSimultaneously(const GestureRecognizer& other) const override;\n\nprotected:\n    bool shouldStartMove(const TouchEvent& event) const override;\n    bool shouldContinueMove(const TouchEvent& event) const override;\n\n    std::string_view getTypeName() const final;\n\nprivate:\n    DragEvent makeMoveEvent() const override;\n\n    Scalar _dragThreshold;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/GestureRecognizer.cpp",
    "content": "//\n//  SkiaGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include <fmt/format.h>\n\nnamespace snap::drawing {\n\nGestureRecognizer::GestureRecognizer() = default;\n\nGestureRecognizer::~GestureRecognizer() = default;\n\nGestureRecognizerState GestureRecognizer::getState() const {\n    return _state;\n}\n\nbool GestureRecognizer::shouldBegin() {\n    return true;\n}\n\nbool GestureRecognizer::requiresFailureOf(const GestureRecognizer& /*other*/) const {\n    return false;\n}\n\nbool GestureRecognizer::canRecognizeSimultaneously(const GestureRecognizer& /*other*/) const {\n    return false;\n}\n\nbool GestureRecognizer::isActive() const {\n    return _state == GestureRecognizerStateBegan || _state == GestureRecognizerStateChanged ||\n           _state == GestureRecognizerStateEnded;\n}\n\nconst TouchEvent* GestureRecognizer::getLastEvent() const {\n    if (!_lastEvent.has_value()) {\n        return nullptr;\n    }\n    return &_lastEvent.value();\n}\n\nPoint GestureRecognizer::getLocation() const {\n    if (!_lastEvent.has_value()) {\n        return Point::make(0, 0);\n    }\n    return _lastEvent.value().getLocation();\n}\n\nPoint GestureRecognizer::getLocationInWindow() const {\n    if (!_lastEvent.has_value()) {\n        return Point::make(0, 0);\n    }\n    return _lastEvent.value().getLocationInWindow();\n}\n\nvoid GestureRecognizer::update(const TouchEvent& event) {\n    auto wasPossible = _state == GestureRecognizerStatePossible;\n    if (_state == GestureRecognizerStateBegan) {\n        _state = GestureRecognizerStateChanged;\n    }\n\n    onUpdate(event);\n\n    if (isActive()) {\n        _lastEvent = event;\n\n        if (wasPossible && !shouldBegin()) {\n            _state = GestureRecognizerStateFailed;\n        }\n    }\n}\n\nvoid GestureRecognizer::transitionToState(GestureRecognizerState newState) {\n    _state = newState;\n}\n\nvoid GestureRecognizer::process() {\n    _wasProcessed = true;\n    onProcess();\n}\n\nvoid GestureRecognizer::cancel() {\n    if (_wasProcessed && _state != GestureRecognizerStateEnded) {\n        // We send an ended event if we were already started (thus acting like a cancel)\n        _state = GestureRecognizerStateEnded;\n        process();\n    }\n\n    _wasProcessed = false;\n    _state = GestureRecognizerStatePossible;\n    _lastEvent = std::nullopt;\n    onReset();\n}\n\nvoid GestureRecognizer::onStarted() {}\n\nvoid GestureRecognizer::onReset() {}\n\nvoid GestureRecognizer::setLayer(ILayer* layer) {\n    if (layer != nullptr) {\n        _layer = Valdi::weakRef(layer);\n    } else {\n        _layer.reset();\n    }\n}\n\nValdi::Ref<ILayer> GestureRecognizer::getLayer() const {\n    return _layer.lock();\n}\n\nvoid GestureRecognizer::setShouldCancelOtherGesturesOnStart(bool shouldCancelOtherGesturesOnStart) {\n    _shouldCancelOtherGesturesOnStart = shouldCancelOtherGesturesOnStart;\n}\n\nbool GestureRecognizer::shouldCancelOtherGesturesOnStart() const {\n    return _shouldCancelOtherGesturesOnStart;\n}\n\nbool GestureRecognizer::shouldProcessBeforeOtherGestures() const {\n    return _shouldProcessBeforeOtherGestures;\n}\n\nvoid GestureRecognizer::setShouldProcessBeforeOtherGestures(bool shouldProcessBeforeOtherGestures) {\n    _shouldProcessBeforeOtherGestures = shouldProcessBeforeOtherGestures;\n}\n\nstatic std::string_view gestureRecognizerStateToString(GestureRecognizerState state) {\n    switch (state) {\n        case GestureRecognizerStatePossible:\n            return \"possible\";\n        case GestureRecognizerStateFailed:\n            return \"failed\";\n        case GestureRecognizerStateBegan:\n            return \"began\";\n        case GestureRecognizerStateChanged:\n            return \"changed\";\n        case GestureRecognizerStateEnded:\n            return \"ended\";\n    }\n}\n\nstd::string GestureRecognizer::toDebugString() const {\n    auto* layer = dynamic_cast<Layer*>(getLayer().get());\n    const char* accessibilityId = \"\";\n    if (layer != nullptr) {\n        accessibilityId = layer->getAccessibilityId().getCStr();\n    }\n\n    return fmt::format(\"Gesture '{}' with ID '{}' and state {}\",\n                       getTypeName(),\n                       accessibilityId,\n                       gestureRecognizerStateToString(_state));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/GestureRecognizer.hpp",
    "content": "//\n//  SkiaGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\n#include \"snap_drawing/cpp/Touches/TouchEvent.hpp\"\n\n#include \"snap_drawing/cpp/Layers/Interfaces/ILayer.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\nnamespace snap::drawing {\n\nenum GestureRecognizerState {\n    GestureRecognizerStatePossible,\n    GestureRecognizerStateFailed,\n    GestureRecognizerStateBegan,\n    GestureRecognizerStateChanged,\n    GestureRecognizerStateEnded\n};\n\ntemplate<typename Gesture, typename Event>\nusing GestureRecognizerListener = Valdi::Function<void(const Gesture&, GestureRecognizerState, const Event&)>;\n\ntemplate<typename Gesture, typename Event>\nusing GestureRecognizerShouldBeginListener = Valdi::Function<bool(const Gesture&, const Event&)>;\n\nclass GestureRecognizer : public Valdi::SimpleRefCountable {\npublic:\n    GestureRecognizer();\n    ~GestureRecognizer() override;\n\n    void setLayer(ILayer* layer);\n    Valdi::Ref<ILayer> getLayer() const;\n\n    const TouchEvent* getLastEvent() const;\n    Point getLocation() const;\n    Point getLocationInWindow() const;\n\n    GestureRecognizerState getState() const;\n\n    virtual bool requiresFailureOf(const GestureRecognizer& other) const;\n    virtual bool canRecognizeSimultaneously(const GestureRecognizer& other) const;\n\n    void update(const TouchEvent& event);\n    void process();\n    void cancel();\n\n    virtual void onStarted();\n    virtual void onReset();\n\n    bool isActive() const;\n\n    bool shouldCancelOtherGesturesOnStart() const;\n    void setShouldCancelOtherGesturesOnStart(bool shouldCancelOtherGesturesOnStart);\n\n    bool shouldProcessBeforeOtherGestures() const;\n    void setShouldProcessBeforeOtherGestures(bool shouldProcessBeforeOtherGestures);\n\n    std::string toDebugString() const;\n\nprotected:\n    virtual bool shouldBegin();\n\n    virtual void onUpdate(const TouchEvent& event) = 0;\n    virtual void onProcess() = 0;\n\n    void transitionToState(GestureRecognizerState newState);\n\n    virtual std::string_view getTypeName() const = 0;\n\nprivate:\n    Valdi::Weak<ILayer> _layer;\n    std::optional<TouchEvent> _lastEvent;\n    GestureRecognizerState _state = GestureRecognizerStatePossible;\n    bool _wasProcessed = false;\n    bool _shouldCancelOtherGesturesOnStart = false;\n    bool _shouldProcessBeforeOtherGestures = false;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/GesturesConfiguration.cpp",
    "content": "//\n//  GesturesConfiguration.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 11/17/22.\n//\n\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n\nnamespace snap::drawing {\n\nconstexpr auto kDefaultLongPressTimeout = Duration(0.25);\nconstexpr auto kDefaultDoubleTapTimeout = Duration(0.25);\nconstexpr Scalar kDefaultDragTouchSlop = 10.0f;\nconstexpr Scalar kDefaultTouchTolerance = 5.0f;\nconstexpr Scalar kDefaultScrollFriction = 0.015f;\n\nGesturesConfiguration GesturesConfiguration::getDefault() {\n    return GesturesConfiguration(kDefaultLongPressTimeout,\n                                 kDefaultDoubleTapTimeout,\n                                 kDefaultDragTouchSlop,\n                                 kDefaultTouchTolerance,\n                                 kDefaultScrollFriction,\n                                 /* debugGestures */ false);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/GesturesConfiguration.hpp",
    "content": "//\n//  GesturesConfiguration.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 11/17/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Duration.hpp\"\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n\nnamespace snap::drawing {\n\nstruct GesturesConfiguration {\n    /**\n     Defines the amount of time before a press is considered a long press.\n     */\n    Duration longPressTimeout;\n\n    /**\n     Defines the maximum amount of time for waiting for a second tap\n     after a single tap.\n     */\n    Duration doubleTapTimeout;\n\n    /**\n     Defines the drag distance before a gesture is considered a drag.\n     Any series of drag events above this value will be considered a drag.\n     */\n    Scalar dragTouchSlop;\n\n    /**\n     The tolerance for a touchable region to be considered touched.\n     Currently only used for hit testing links inside labels, but might be used for hit testing\n     layers in the future.\n     */\n    Scalar touchTolerance;\n\n    /**\n     The amount of friction when scrolling. This is a dimensionless value\n     representing a coefficient applied when scrolling.\n     Equivalent to Android's ViewConfiguration.getScrollFriction()\n     (see https://developer.android.com/reference/android/view/ViewConfiguration#getScrollFriction() )\n     */\n    Scalar scrollFriction;\n\n    /**\n     Whether debug info should be printed when processing gestures\n     */\n    bool debugGestures;\n\n    constexpr GesturesConfiguration(Duration longPressTimeout,\n                                    Duration doubleTapTimeout,\n                                    Scalar dragTouchSlop,\n                                    Scalar touchTolerance,\n                                    Scalar scrollFriction,\n                                    bool debugGestures)\n        : longPressTimeout(longPressTimeout),\n          doubleTapTimeout(doubleTapTimeout),\n          dragTouchSlop(dragTouchSlop),\n          touchTolerance(touchTolerance),\n          scrollFriction(scrollFriction),\n          debugGestures(debugGestures) {}\n\n    static GesturesConfiguration getDefault();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/LongPressGestureRecognizer.cpp",
    "content": "//\n//  LongPressGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#include \"snap_drawing/cpp/Touches/LongPressGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nLongPressGestureRecognizer::LongPressGestureRecognizer(const GesturesConfiguration& gesturesConfiguration)\n    : _longPressTimeout(gesturesConfiguration.longPressTimeout),\n      _longPressShiftTolerance(gesturesConfiguration.dragTouchSlop) {}\n\nLongPressGestureRecognizer::~LongPressGestureRecognizer() = default;\n\nvoid LongPressGestureRecognizer::setLongPressTimeout(Duration longPressTimeout) {\n    _longPressTimeout = longPressTimeout;\n}\n\nvoid LongPressGestureRecognizer::onProcess() {\n    if (_listener) {\n        _listener(*this, getState(), getLocation());\n    }\n}\n\nvoid LongPressGestureRecognizer::onUpdate(const TouchEvent& event) {\n    switch (event.getType()) {\n        case TouchEventTypeDown: {\n            // Cancel the long press if we have a second down event\n            if (_longPressState.has_value()) {\n                transitionToState(GestureRecognizerStateFailed);\n            } else {\n                _longPressState = {LongPressGestureRecognizerState(event)};\n            }\n        } break;\n        case TouchEventTypePointerUp:\n            [[fallthrough]];\n        case TouchEventTypePointerDown:\n            [[fallthrough]];\n        case TouchEventTypeIdle:\n            [[fallthrough]];\n        case TouchEventTypeMoved: {\n            if (isActive()) {\n                transitionToState(GestureRecognizerStateChanged);\n            } else if (_longPressState.has_value()) {\n                auto distance =\n                    Point::distance(_longPressState->startEvent.getLocationInWindow(), event.getLocationInWindow());\n                if (distance > _longPressShiftTolerance) {\n                    transitionToState(GestureRecognizerStateFailed);\n                } else if (event.getTime().durationSince(_longPressState->startEvent.getTime()) >= _longPressTimeout) {\n                    transitionToState(GestureRecognizerStateBegan);\n                }\n            }\n        } break;\n        case TouchEventTypeUp: {\n            if (isActive()) {\n                transitionToState(GestureRecognizerStateEnded);\n            } else {\n                transitionToState(GestureRecognizerStateFailed);\n            }\n        } break;\n        case TouchEventTypeWheel:\n            [[fallthrough]];\n        case TouchEventTypeNone:\n            transitionToState(GestureRecognizerStateFailed);\n            break;\n    }\n}\n\nvoid LongPressGestureRecognizer::onReset() {\n    _longPressState = std::nullopt;\n}\n\nstd::string_view LongPressGestureRecognizer::getTypeName() const {\n    return \"long press\";\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/LongPressGestureRecognizer.hpp",
    "content": "//\n//  LongPressGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n\n#include <optional>\n\nnamespace snap::drawing {\n\nstruct LongPressGestureRecognizerState {\n    TouchEvent startEvent;\n\n    explicit inline LongPressGestureRecognizerState(const TouchEvent& startEvent) : startEvent(startEvent) {}\n};\n\nclass LongPressGestureRecognizer : public GestureRecognizer {\npublic:\n    using ShouldBeginListener = GestureRecognizerShouldBeginListener<LongPressGestureRecognizer, Point>;\n    using Listener = GestureRecognizerListener<LongPressGestureRecognizer, Point>;\n\n    LongPressGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~LongPressGestureRecognizer() override;\n\n    void setShouldBeginListener(ShouldBeginListener&& shouldBeginListener) {\n        _shouldBeginListener = std::move(shouldBeginListener);\n    }\n\n    void setListener(Listener&& listener) {\n        _listener = std::move(listener);\n    }\n\n    bool isEmpty() const {\n        return (!_shouldBeginListener && !_listener);\n    }\n\n    void setLongPressTimeout(Duration longPressTimeout);\n\nprotected:\n    bool shouldBegin() override {\n        if (_shouldBeginListener) {\n            return _shouldBeginListener(*this, getLocation());\n        }\n        return true;\n    }\n\n    void onProcess() override;\n\n    void onUpdate(const TouchEvent& event) override;\n    void onReset() override;\n\n    std::string_view getTypeName() const final;\n\nprivate:\n    ShouldBeginListener _shouldBeginListener;\n\n    Duration _longPressTimeout;\n    Scalar _longPressShiftTolerance;\n    Listener _listener;\n\n    std::optional<LongPressGestureRecognizerState> _longPressState;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/MoveGestureRecognizer.cpp",
    "content": "//\n//  MoveGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Vincent Brunet on 01/17/21.\n//\n\n#include \"snap_drawing/cpp/Touches/MoveGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/PinchGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/RotateGestureRecognizer.hpp\"\n\n#include \"utils/debugging/Assert.hpp\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nMoveGestureState::MoveGestureState(const TouchEvent& startEvent,\n                                   const TouchEvent& lastEvent,\n                                   const TouchEvent& currentEvent)\n    : startEvent(startEvent), lastEvent(lastEvent), currentEvent(currentEvent) {}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/MoveGestureRecognizer.hpp",
    "content": "//\n//  MoveGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Vincent Brunet on 01/17/21.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nstruct MoveGestureState {\n    TouchEvent startEvent;\n    TouchEvent lastEvent;\n    TouchEvent currentEvent;\n\n    MoveGestureState(const TouchEvent& startEvent, const TouchEvent& lastEvent, const TouchEvent& currentEvent);\n};\n\ntemplate<class MoveEvent>\nclass MoveGestureRecognizer : public GestureRecognizer {\npublic:\n    using ShouldBeginListener = GestureRecognizerShouldBeginListener<MoveGestureRecognizer, MoveEvent>;\n\n    using Listener = GestureRecognizerListener<MoveGestureRecognizer, MoveEvent>;\n\n    explicit MoveGestureRecognizer() = default;\n    ~MoveGestureRecognizer() override = default;\n\n    void setShouldBeginListener(ShouldBeginListener&& shouldBeginListener) {\n        _shouldBeginListener = std::move(shouldBeginListener);\n    }\n\n    void setListener(Listener&& listener) {\n        _listener = std::move(listener);\n    }\n\n    bool isEmpty() const {\n        return (!_shouldBeginListener && !_listener);\n    }\n\nprotected:\n    bool shouldBegin() override {\n        if (_shouldBeginListener) {\n            return _shouldBeginListener(*this, makeMoveEvent());\n        }\n        return true;\n    }\n\n    virtual void onEnd(const TouchEvent& event) {\n        transitionToState(GestureRecognizerStateEnded);\n    }\n\n    virtual void onPointerChange(const TouchEvent& event) {}\n\n    void onProcess() override {\n        if (_listener) {\n            if (_moveState && _moveState->currentEvent.getType() == TouchEventTypeIdle) {\n                return;\n            }\n            _listener(*this, getState(), makeMoveEvent());\n        }\n    }\n\n    void onUpdate(const TouchEvent& event) override {\n        if (!_moveState.has_value()) {\n            _moveState = {MoveGestureState(event, event, event)};\n        }\n\n        if (event.getType() == TouchEventTypeNone || event.getType() == TouchEventTypeWheel) {\n            transitionToState(GestureRecognizerStateFailed);\n        } else {\n            if (isActive()) {\n                if (event.getType() == TouchEventTypePointerUp || event.getType() == TouchEventTypePointerDown) {\n                    onPointerChange(event);\n                } else if (event.getType() == TouchEventTypeUp || !shouldContinueMove(event)) {\n                    onEnd(event);\n                } else {\n                    didContinueMove(event);\n                }\n            } else {\n                if (shouldStartMove(event)) {\n                    transitionToState(GestureRecognizerStateBegan);\n                    _moveState = {MoveGestureState(event, event, event)};\n                    didStartMove(event);\n                } else if (event.getType() == TouchEventTypeUp) {\n                    transitionToState(GestureRecognizerStateFailed);\n                }\n            }\n        }\n\n        _moveState.value().lastEvent = _moveState.value().currentEvent;\n        _moveState.value().currentEvent = event;\n    }\n\n    void onReset() override {\n        _moveState = std::nullopt;\n    }\n\n    virtual MoveEvent makeMoveEvent() const {\n        SC_ASSERT(_moveState.has_value());\n\n        auto startEvent = _moveState.value().startEvent;\n        auto lastEvent = _moveState.value().lastEvent;\n        auto currentEvent = _moveState.value().currentEvent;\n\n        auto startLocationInWindow = startEvent.getLocationInWindow();\n        auto currentLocationInWindow = currentEvent.getLocationInWindow();\n\n        MoveEvent moveEvent;\n        moveEvent.location = getLocation();\n        moveEvent.offset.width = currentLocationInWindow.x - startLocationInWindow.x;\n        moveEvent.offset.height = currentLocationInWindow.y - startLocationInWindow.y;\n        moveEvent.velocity = computeVelocity(lastEvent, currentEvent);\n        moveEvent.time = currentEvent.getTime();\n        moveEvent.pointerCount = currentEvent.getPointerCount();\n\n        return moveEvent;\n    }\n\n    virtual bool shouldStartMove(const TouchEvent& event) const = 0;\n    virtual bool shouldContinueMove(const TouchEvent& event) const = 0;\n\n    virtual void didStartMove(const TouchEvent& event) {}\n    virtual void didContinueMove(const TouchEvent& event) {}\n\n    std::optional<MoveGestureState> _moveState;\n\nprivate:\n    ShouldBeginListener _shouldBeginListener;\n\n    Listener _listener;\n\n    static Vector computeVelocity(const TouchEvent& previousEvent, const TouchEvent& newEvent) {\n        auto delta = newEvent.getTime() - previousEvent.getTime();\n\n        auto fSeconds = static_cast<Scalar>(delta.seconds());\n        if (fSeconds == 0) {\n            return Vector::makeEmpty();\n        }\n\n        auto previousLocationInWindow = previousEvent.getLocationInWindow();\n        auto newLocationInWindow = newEvent.getLocationInWindow();\n\n        auto velocityX = (newLocationInWindow.x - previousLocationInWindow.x) / fSeconds;\n        auto velocityY = (newLocationInWindow.y - previousLocationInWindow.y) / fSeconds;\n\n        return Vector::make(velocityX, velocityY);\n    }\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/PinchGestureRecognizer.cpp",
    "content": "//\n//  PinchGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n#include \"snap_drawing/cpp/Touches/PinchGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/RotateGestureRecognizer.hpp\"\n\n#include \"utils/debugging/Assert.hpp\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nPinchGestureRecognizer::PinchGestureRecognizer(const GesturesConfiguration& /*gesturesConfiguration*/) {}\n\nPinchGestureRecognizer::~PinchGestureRecognizer() = default;\n\nbool PinchGestureRecognizer::requiresFailureOf(const GestureRecognizer& other) const {\n    return dynamic_cast<const PinchGestureRecognizer*>(&other) != nullptr;\n}\n\nbool PinchGestureRecognizer::canRecognizeSimultaneously(const GestureRecognizer& other) const {\n    if (dynamic_cast<const RotateGestureRecognizer*>(&other) != nullptr) {\n        return true;\n    }\n    if (dynamic_cast<const DragGestureRecognizer*>(&other) != nullptr) {\n        return true;\n    }\n    return false;\n}\n\nPinchEvent PinchGestureRecognizer::makeMoveEvent() const {\n    PinchEvent pinchEvent = MoveGestureRecognizer<PinchEvent>::makeMoveEvent();\n    if (pinchEvent.pointerCount > 1 && _moveState.value().currentEvent.getType() != TouchEventTypePointerUp &&\n        _moveState.value().currentEvent.getType() != TouchEventTypePointerDown) {\n        // for events with more than one pointer, we use the delta from the cached value\n        pinchEvent.scale = getCurrentScale() * _netScale;\n    } else {\n        // currently, our gesture detection system fires one last event for the finger leaving with a null currentEvent,\n        // and we want to ensure any changes are persisted\n        pinchEvent.scale = _netScale;\n    }\n\n    return pinchEvent;\n}\n\n// (mli6) WARN) - startEvent setting for multitouch does not track perfectly accurately for resumptions -\n// Ticket: 2885\nScalar PinchGestureRecognizer::getCurrentScale() const {\n    auto startDirection = _moveState.value().startEvent.getDirection();\n    auto currentDirection = _moveState.value().currentEvent.getDirection();\n\n    auto startScale = Point::length(startDirection.dx, startDirection.dy);\n    auto currentScale = Point::length(currentDirection.dx, currentDirection.dy);\n\n    return currentScale / startScale;\n}\n\nbool PinchGestureRecognizer::shouldStartMove(const TouchEvent& event) const {\n    return event.getPointerCount() > 1;\n}\n\nbool PinchGestureRecognizer::shouldContinueMove(const TouchEvent& event) const {\n    return event.getPointerCount() > 0;\n}\n\nvoid PinchGestureRecognizer::onPointerChange(const TouchEvent& event) {\n    if (event.getPointerCount() == 2 && event.getType() == TouchEventTypePointerUp) {\n        // if any touches are still present, we allow for a scale to continue\n        // when end users lift all but one finger, we cache the current scale amount such that they can resume the\n        // scale\n\n        // we only cache this when the pointer count decreases, such that multifinger events or duplicate events don't\n        // cause a re-caching\n        _netScale *= getCurrentScale();\n        transitionToState(GestureRecognizerStateChanged);\n    }\n}\n\nvoid PinchGestureRecognizer::onReset() {\n    MoveGestureRecognizer::onReset();\n    _netScale = 1;\n}\n\nstd::string_view PinchGestureRecognizer::getTypeName() const {\n    return \"pinch\";\n}\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/PinchGestureRecognizer.hpp",
    "content": "//\n//  PinchGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n#include \"snap_drawing/cpp/Touches/MoveGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nstruct PinchEvent : DragEvent {\n    Scalar scale;\n};\n\nclass PinchGestureRecognizer : public MoveGestureRecognizer<PinchEvent> {\npublic:\n    explicit PinchGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~PinchGestureRecognizer() override;\n\n    bool requiresFailureOf(const GestureRecognizer& other) const override;\n    bool canRecognizeSimultaneously(const GestureRecognizer& other) const override;\n\nprotected:\n    std::string_view getTypeName() const final;\n\nprivate:\n    // track previous scales - such that multiple single scales can be all multiplied together\n    Scalar _netScale = 1;\n\n    Scalar getCurrentScale() const;\n    bool shouldStartMove(const TouchEvent& event) const override;\n    bool shouldContinueMove(const TouchEvent& event) const override;\n    void onReset() override;\n    void onPointerChange(const TouchEvent& event) override;\n\n    PinchEvent makeMoveEvent() const override;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/RotateGestureRecognizer.cpp",
    "content": "//\n//  RotateGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n#include \"snap_drawing/cpp/Touches/RotateGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/PinchGestureRecognizer.hpp\"\n\n#include \"utils/debugging/Assert.hpp\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nRotateGestureRecognizer::RotateGestureRecognizer(const GesturesConfiguration& /*gesturesConfiguration*/) {}\n\nRotateGestureRecognizer::~RotateGestureRecognizer() = default;\n\nbool RotateGestureRecognizer::requiresFailureOf(const GestureRecognizer& other) const {\n    return dynamic_cast<const RotateGestureRecognizer*>(&other) != nullptr;\n}\n\nbool RotateGestureRecognizer::canRecognizeSimultaneously(const GestureRecognizer& other) const {\n    if (dynamic_cast<const PinchGestureRecognizer*>(&other) != nullptr) {\n        return true;\n    }\n    if (dynamic_cast<const DragGestureRecognizer*>(&other) != nullptr) {\n        return true;\n    }\n    return false;\n}\n\nRotateEvent RotateGestureRecognizer::makeMoveEvent() const {\n    RotateEvent rotateEvent = MoveGestureRecognizer<RotateEvent>::makeMoveEvent();\n\n    if (rotateEvent.pointerCount > 1 && _moveState.value().currentEvent.getType() != TouchEventTypePointerUp &&\n        _moveState.value().currentEvent.getType() != TouchEventTypePointerDown) {\n        // for events with more than one pointer, we use the delta from the cached value\n        rotateEvent.rotation = getCurrentRotation() + _netRotation;\n    } else {\n        // currently, our gesture detection system fires one last event for the finger leaving with a null currentEvent,\n        // and we want to ensure any changes are persisted\n        rotateEvent.rotation = _netRotation;\n    }\n\n    return rotateEvent;\n}\n\n// (mli6) WARN) - startEvent setting for multitouch does not track perfectly accurately for resumptions -\n// Ticket: 2885\nScalar RotateGestureRecognizer::getCurrentRotation() const {\n    auto startDirection = _moveState.value().startEvent.getDirection();\n    auto currentDirection = _moveState.value().currentEvent.getDirection();\n    auto startRotation = -atan2f(startDirection.dx, startDirection.dy);\n    auto currentRotation = -atan2f(currentDirection.dx, currentDirection.dy);\n    return currentRotation - startRotation;\n}\n\nbool RotateGestureRecognizer::shouldStartMove(const TouchEvent& event) const {\n    return event.getPointerCount() > 1;\n}\n\nbool RotateGestureRecognizer::shouldContinueMove(const TouchEvent& event) const {\n    return event.getPointerCount() > 0;\n}\n\nvoid RotateGestureRecognizer::onPointerChange(const TouchEvent& event) {\n    if (event.getPointerCount() == 2 && event.getType() == TouchEventTypePointerUp) {\n        // if any touches are still present, we allow for a rotation to continue\n        // when end users lift all but one finger, we cache the current rotation amount such that they can resume the\n        // rotation\n\n        // we only cache this when the pointer count decreases, such that multifinger events or duplicate events don't\n        // cause a re-caching\n        _netRotation += getCurrentRotation();\n        transitionToState(GestureRecognizerStateChanged);\n    }\n}\n\nvoid RotateGestureRecognizer::onReset() {\n    MoveGestureRecognizer::onReset();\n    _netRotation = 0;\n}\n\nstd::string_view RotateGestureRecognizer::getTypeName() const {\n    return \"rotate\";\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/RotateGestureRecognizer.hpp",
    "content": "//\n//  RotateGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n#include \"snap_drawing/cpp/Touches/MoveGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nstruct RotateEvent : DragEvent {\n    Scalar rotation;\n};\n\nclass RotateGestureRecognizer : public MoveGestureRecognizer<RotateEvent> {\npublic:\n    RotateGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~RotateGestureRecognizer() override;\n\n    bool requiresFailureOf(const GestureRecognizer& other) const override;\n    bool canRecognizeSimultaneously(const GestureRecognizer& other) const override;\n\nprotected:\n    std::string_view getTypeName() const final;\n\nprivate:\n    // track previous rotations - such that multiple single rotations can be all added together\n    Scalar _netRotation = 0;\n\n    Scalar getCurrentRotation() const;\n    bool shouldStartMove(const TouchEvent& event) const override;\n    bool shouldContinueMove(const TouchEvent& event) const override;\n    void onReset() override;\n    void onPointerChange(const TouchEvent& event) override;\n\n    RotateEvent makeMoveEvent() const override;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/ScrollGestureRecognizer.cpp",
    "content": "//\n//  ScrollGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#include \"snap_drawing/cpp/Touches/ScrollGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/LongPressGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/PinchGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/RotateGestureRecognizer.hpp\"\n\n#include \"utils/debugging/Assert.hpp\"\n\n#include <cmath>\n\nnamespace snap::drawing {\n\nconstexpr Scalar kScrollVelocityThreshold = 50;\n\nScrollGestureRecognizer::ScrollGestureRecognizer(const GesturesConfiguration& gesturesConfiguration)\n    : _dragThreshold(gesturesConfiguration.dragTouchSlop) {}\n\nScrollGestureRecognizer::~ScrollGestureRecognizer() = default;\n\nvoid ScrollGestureRecognizer::setHorizontal(bool horizontal) {\n    _isHorizontal = horizontal;\n}\n\nvoid ScrollGestureRecognizer::setAnimatingScroll(bool animatingScroll) {\n    _animatingScroll = animatingScroll;\n}\n\nbool ScrollGestureRecognizer::requiresFailureOf(const GestureRecognizer& /*other*/) const {\n    return false;\n}\n\nDragEvent ScrollGestureRecognizer::makeMoveEvent() const {\n    auto event = MoveGestureRecognizer<DragEvent>::makeMoveEvent();\n    if (_isHorizontal) {\n        event.velocity.dy = 0;\n        event.velocity.dx = -_horizontalVelocityTracker.computeVelocity();\n        if (fabs(event.velocity.dx) < kScrollVelocityThreshold) {\n            event.velocity.dx = 0;\n        }\n    } else {\n        event.velocity.dx = 0;\n        event.velocity.dy = -_verticalVelocityTracker.computeVelocity();\n        if (fabs(event.velocity.dy) < kScrollVelocityThreshold) {\n            event.velocity.dy = 0;\n        }\n    }\n    return event;\n}\n\nbool ScrollGestureRecognizer::shouldStartMove(const TouchEvent& event) const {\n    // Immediately start the scroll on down if we are animating.\n    if (_animatingScroll) {\n        return true;\n    }\n\n    auto startEvent = _moveState.value().startEvent;\n    const auto& testedEvent = event;\n\n    auto startLocationInWindow = startEvent.getLocationInWindow();\n    auto testedLocationInWindow = testedEvent.getLocationInWindow();\n\n    auto distance = Point::distance(startLocationInWindow, testedLocationInWindow);\n    if (distance < _dragThreshold) {\n        return false;\n    }\n\n    auto diffX = testedLocationInWindow.x - startLocationInWindow.x;\n    auto diffY = testedLocationInWindow.y - startLocationInWindow.y;\n\n    if (_isHorizontal) {\n        return std::fabs(diffX) > std::fabs(diffY);\n    } else {\n        return std::fabs(diffY) > std::fabs(diffX);\n    }\n}\n\nbool ScrollGestureRecognizer::shouldContinueMove(const TouchEvent& event) const {\n    return _moveState->startEvent.getPointerCount() == event.getPointerCount();\n}\n\nvoid ScrollGestureRecognizer::didStartMove(const TouchEvent& event) {\n    _horizontalVelocityTracker.clear();\n    _verticalVelocityTracker.clear();\n    didContinueMove(event);\n}\n\nvoid ScrollGestureRecognizer::didContinueMove(const TouchEvent& event) {\n    auto locationInWindow = event.getLocationInWindow();\n    _horizontalVelocityTracker.addSample(event.getTime(), locationInWindow.x);\n    _verticalVelocityTracker.addSample(event.getTime(), locationInWindow.y);\n}\n\nstd::string_view ScrollGestureRecognizer::getTypeName() const {\n    return \"scroll\";\n}\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/ScrollGestureRecognizer.hpp",
    "content": "//\n//  ScrollGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n#include \"snap_drawing/cpp/Touches/MoveGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Utils/VelocityTracker.hpp\"\n\nnamespace snap::drawing {\n\nclass ScrollGestureRecognizer : public MoveGestureRecognizer<DragEvent> {\npublic:\n    explicit ScrollGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~ScrollGestureRecognizer() override;\n\n    bool requiresFailureOf(const GestureRecognizer& other) const override;\n\n    void setHorizontal(bool horizontal);\n    void setAnimatingScroll(bool animatingScroll);\n\nprotected:\n    bool shouldStartMove(const TouchEvent& event) const override;\n    bool shouldContinueMove(const TouchEvent& event) const override;\n\n    void didStartMove(const TouchEvent& event) override;\n    void didContinueMove(const TouchEvent& event) override;\n\n    std::string_view getTypeName() const final;\n\nprivate:\n    DragEvent makeMoveEvent() const override;\n\nprivate:\n    Scalar _dragThreshold;\n    bool _isHorizontal = false;\n    bool _animatingScroll = false;\n\n    VelocityTracker _horizontalVelocityTracker;\n    VelocityTracker _verticalVelocityTracker;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/SingleTapGestureRecognizer.cpp",
    "content": "//\n//  SingleTapGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Vincent Brunet on 01/07/21.\n//\n\n#include \"snap_drawing/cpp/Touches/SingleTapGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nSingleTapGestureRecognizer::SingleTapGestureRecognizer(const GesturesConfiguration& gesturesConfiguration)\n    : TapGestureRecognizer(1, gesturesConfiguration) {}\n\nSingleTapGestureRecognizer::~SingleTapGestureRecognizer() = default;\n\nstd::string_view SingleTapGestureRecognizer::getTypeName() const {\n    return \"single tap\";\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/SingleTapGestureRecognizer.hpp",
    "content": "//\n//  SingleTapGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Vincent Brunet on 01/07/21.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nclass SingleTapGestureRecognizer : public TapGestureRecognizer {\npublic:\n    SingleTapGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~SingleTapGestureRecognizer() override;\n\nprotected:\n    std::string_view getTypeName() const final;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/TapGestureRecognizer.cpp",
    "content": "//\n//  TapGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nTapGestureRecognizer::TapGestureRecognizer(size_t numberOfTapsRequired,\n                                           const GesturesConfiguration& gesturesConfiguration)\n    : _numberOfTapsRequired(numberOfTapsRequired),\n      _pressTimeout(gesturesConfiguration.doubleTapTimeout),\n      _tapShiftTolerance(gesturesConfiguration.dragTouchSlop) {}\n\nTapGestureRecognizer::~TapGestureRecognizer() = default;\n\nbool TapGestureRecognizer::requiresFailureOf(const GestureRecognizer& other) const {\n    return dynamic_cast<const TapGestureRecognizer*>(&other) != nullptr;\n}\n\nvoid TapGestureRecognizer::onProcess() {\n    if (_listener) {\n        _listener(*this, getState(), getLocation());\n    }\n}\n\nvoid TapGestureRecognizer::onUpdate(const TouchEvent& event) {\n    if (!_events.empty()) {\n        auto& firstEvent = _events.front();\n        auto distance = Point::distance(firstEvent.getLocationInWindow(), event.getLocationInWindow());\n        if (distance >= _tapShiftTolerance) {\n            transitionToState(GestureRecognizerStateFailed);\n            return;\n        }\n        auto duration = event.getTime().durationSince(firstEvent.getTime());\n        if (duration >= _pressTimeout) {\n            transitionToState(GestureRecognizerStateFailed);\n            return;\n        }\n    }\n\n    switch (event.getType()) {\n        case TouchEventTypeDown: {\n            _events.emplace_back(event);\n        } break;\n        // adding/removing pointers treated as moving - the touch event is still active\n        case TouchEventTypePointerUp:\n            [[fallthrough]];\n        case TouchEventTypePointerDown:\n            [[fallthrough]];\n        case TouchEventTypeWheel:\n            [[fallthrough]];\n        case TouchEventTypeIdle:\n            [[fallthrough]];\n        case TouchEventTypeMoved: {\n        } break;\n        case TouchEventTypeUp: {\n            if (_events.size() == _numberOfTapsRequired) {\n                transitionToState(GestureRecognizerStateBegan);\n            }\n        } break;\n        case TouchEventTypeNone: {\n            auto counter = _events.size();\n            if (counter == 0 || counter >= _numberOfTapsRequired) {\n                transitionToState(GestureRecognizerStateFailed);\n                return;\n            }\n        } break;\n    }\n\n    if (_events.size() > _numberOfTapsRequired) {\n        transitionToState(GestureRecognizerStateFailed);\n        return;\n    }\n}\n\nvoid TapGestureRecognizer::onStarted() {\n    transitionToState(GestureRecognizerStateEnded);\n}\n\nvoid TapGestureRecognizer::onReset() {\n    _events.clear();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/TapGestureRecognizer.hpp",
    "content": "//\n//  TapGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n\n#include <optional>\n\nnamespace snap::drawing {\n\nclass TapGestureRecognizer : public GestureRecognizer {\npublic:\n    using ShouldBeginListener = GestureRecognizerShouldBeginListener<TapGestureRecognizer, Point>;\n    using Listener = GestureRecognizerListener<TapGestureRecognizer, Point>;\n\n    TapGestureRecognizer(size_t numberOfTapsRequired, const GesturesConfiguration& gesturesConfiguration);\n    ~TapGestureRecognizer() override;\n\n    void setShouldBeginListener(ShouldBeginListener&& shouldBeginListener) {\n        _shouldBeginListener = std::move(shouldBeginListener);\n    }\n\n    void setListener(Listener&& listener) {\n        _listener = std::move(listener);\n    }\n\n    bool isEmpty() const {\n        return (!_shouldBeginListener && !_listener);\n    }\n\n    bool requiresFailureOf(const GestureRecognizer& other) const override;\n\nprotected:\n    bool shouldBegin() override {\n        if (_shouldBeginListener) {\n            return _shouldBeginListener(*this, getLocation());\n        }\n        return true;\n    }\n\n    void onUpdate(const TouchEvent& event) override;\n    void onReset() override;\n\n    void onProcess() override;\n\n    void onStarted() override;\n\nprivate:\n    ShouldBeginListener _shouldBeginListener;\n\n    size_t _numberOfTapsRequired;\n    Duration _pressTimeout;\n    Scalar _tapShiftTolerance;\n\n    Listener _listener;\n\n    std::vector<TouchEvent> _events;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/TouchDispatcher.cpp",
    "content": "//\n//  SkiaTouchDispatcher.cpp\n//  valdi-skia-apple\n//\n//  Created by Simon Corsin on 6/27/20.\n//\n\n#include \"snap_drawing/cpp/Touches/TouchDispatcher.hpp\"\n\n#include \"valdi_core/cpp/Utils/LoggerUtils.hpp\"\n\nnamespace snap::drawing {\n\n#define TOUCHDISPATCHER_DEBUG(____format, ...)                                                                         \\\n    if (_enableLogging) {                                                                                              \\\n        VALDI_INFO(_logger, \"TouchDispatcher - {}\", fmt::format(____format VALDI_LOG_ARGS(__VA_ARGS__)));              \\\n    }\n\nTouchDispatcher::TouchDispatcher(Valdi::ILogger& logger, bool enableLogging)\n    : _logger(logger), _enableLogging(enableLogging) {}\n\nstatic bool removeGestureRecognizer(std::vector<Valdi::Ref<GestureRecognizer>>& gestures,\n                                    const Valdi::Ref<GestureRecognizer>& gestureRecognizer) {\n    auto candidateIt = std::find(gestures.begin(), gestures.end(), gestureRecognizer);\n    if (candidateIt == gestures.end()) {\n        return false;\n    }\n    gestures.erase(candidateIt);\n    return true;\n}\n\nstatic size_t indexOfGestureRecognizer(const std::vector<Valdi::Ref<GestureRecognizer>>& gestures,\n                                       const Valdi::Ref<GestureRecognizer>& gestureRecognizer) {\n    return std::find(gestures.begin(), gestures.end(), gestureRecognizer) - gestures.begin();\n}\n\nvoid TouchDispatcher::cancelAllGestures() {\n    while (!_candidateGestureRecognizers.empty()) {\n        auto gestureRecognizer = _candidateGestureRecognizers[_candidateGestureRecognizers.size() - 1];\n        cancelGestureRecognizer(gestureRecognizer);\n    }\n}\n\nbool TouchDispatcher::dispatchEvent(const TouchEvent& event, const Valdi::Ref<Layer>& rootLayer) {\n    _dispatchingEvent = true;\n    _lastEvent = event;\n    TOUCHDISPATCHER_DEBUG(\"Dispatching event '{}'\", event);\n\n    if (event.getType() == TouchEventTypeDown || event.getType() == TouchEventTypeWheel) {\n        // Step 1, we capture all the layers and their gesture recognizers which are within the event's target.\n        // We only do this on touch down.\n        [[maybe_unused]] auto sizeBefore = _candidateGestureRecognizers.size();\n        captureCandidates(event, rootLayer, _candidateGestureRecognizers);\n\n        if (_enableLogging) {\n            TOUCHDISPATCHER_DEBUG(\"Captured {} new gestures candidates (total {})\",\n                                  _candidateGestureRecognizers.size() - sizeBefore,\n                                  _candidateGestureRecognizers.size());\n            for (size_t i = 0; i < _candidateGestureRecognizers.size(); i++) {\n                TOUCHDISPATCHER_DEBUG(\"Candidate gesture #{}: {}\", i, _candidateGestureRecognizers[i]->toDebugString());\n            }\n        }\n    }\n\n    auto processed = processGestureRecognizers(rootLayer);\n    _dispatchingEvent = false;\n    return processed;\n}\n\nstd::vector<Valdi::Ref<GestureRecognizer>> TouchDispatcher::getGestureCandidatesForEvent(\n    const TouchEvent& event, const Valdi::Ref<Layer>& rootLayer) const {\n    std::vector<Valdi::Ref<GestureRecognizer>> candidateGestures;\n\n    captureCandidates(event, rootLayer, candidateGestures);\n\n    return candidateGestures;\n}\n\nbool TouchDispatcher::containsGestureRecognizer(const Valdi::Ref<GestureRecognizer>& gestureRecognizer,\n                                                const std::vector<Valdi::Ref<GestureRecognizer>>& gestureRecognizers) {\n    return std::find(gestureRecognizers.begin(), gestureRecognizers.end(), gestureRecognizer) !=\n           gestureRecognizers.end();\n}\n\nbool TouchDispatcher::captureCandidates(const TouchEvent& event,\n                                        const Valdi::Ref<Layer>& layer,\n                                        std::vector<Valdi::Ref<GestureRecognizer>>& candidateGestureRecognizers) const {\n    if (!layer->hitTest(event.getLocation())) {\n        return false;\n    }\n\n    size_t gestureRecognizerSize = layer->getGestureRecognizersSize();\n    for (size_t i = 0; i < gestureRecognizerSize; i++) {\n        auto gestureRecognizer = layer->getGestureRecognizer(i);\n        if (!containsGestureRecognizer(gestureRecognizer, candidateGestureRecognizers)) {\n            if (gestureRecognizer->shouldProcessBeforeOtherGestures()) {\n                size_t insertionIndex = 0;\n                while (insertionIndex < candidateGestureRecognizers.size() &&\n                       candidateGestureRecognizers[i]->shouldProcessBeforeOtherGestures()) {\n                    insertionIndex++;\n                }\n                candidateGestureRecognizers.emplace(candidateGestureRecognizers.begin() + insertionIndex,\n                                                    std::move(gestureRecognizer));\n            } else {\n                candidateGestureRecognizers.emplace_back(std::move(gestureRecognizer));\n            }\n        }\n    }\n\n    // Dispatch touches to children, starting from the last child.\n    auto i = layer->getChildrenSize();\n    while (i > 0) {\n        i--;\n\n        auto child = layer->getChild(i);\n\n        auto childPoint = child->convertPointFromParent(event.getLocation());\n\n        if (captureCandidates(event.withLocation(childPoint), child, candidateGestureRecognizers)) {\n            // Among siblings, we only capture the first sibling which is hit.\n            break;\n        }\n    }\n\n    return true;\n}\n\nbool TouchDispatcher::processGestureRecognizers(const Valdi::Ref<Layer>& rootLayer) {\n    if (!_lastEvent) {\n        return false;\n    }\n\n    // Step 2, we update all the active gesture recognizers. They will update their states.\n    updateGestureRecognizers(rootLayer);\n\n    // Step 3, we go over all the gesture recognizers which want to start. We resolve the conflicts.\n    // For each gesture which wants to start, we will ask any other active gestures or gestures which want to\n    // start if they agree that this gesture should be allowed to start. If any one the gesture says no, the\n    // gesture will not start. As such we go from the back, as the gestures which are at the front are deepest\n    // in the hierarchy, they should be prioritized and canceled only as a last resort.\n    startPendingGestureRecognizers();\n\n    // Step 4, we process all active gesture recognizers,\n    processActiveGestureRecognizers();\n\n    return !_candidateGestureRecognizers.empty();\n}\n\nvoid TouchDispatcher::updateGestureRecognizers(const Valdi::Ref<Layer>& rootLayer) {\n    TOUCHDISPATCHER_DEBUG(\"Updating {} gesture candidates\", _candidateGestureRecognizers.size());\n\n    auto candidateIt = _candidateGestureRecognizers.begin();\n    while (candidateIt != _candidateGestureRecognizers.end()) {\n        auto gestureRecognizer = *candidateIt;\n        auto shouldCancel = false;\n\n        if (!isGestureRecognizerDeferred(gestureRecognizer)) {\n            auto childEvent =\n                adjustEventCoordinatesToLayer(rootLayer, gestureRecognizer->getLayer(), _lastEvent.value());\n            if (childEvent) {\n                TOUCHDISPATCHER_DEBUG(\"Calling update() on {}\", gestureRecognizer->toDebugString());\n\n                auto previousState = gestureRecognizer->getState();\n                gestureRecognizer->update(childEvent.value());\n\n                if (gestureRecognizer->getState() == GestureRecognizerStateFailed) {\n                    shouldCancel = true;\n                    TOUCHDISPATCHER_DEBUG(\"failed after update on {}\", gestureRecognizer->toDebugString());\n                } else if (gestureRecognizer->getState() == GestureRecognizerStateBegan ||\n                           (previousState == GestureRecognizerStatePossible &&\n                            gestureRecognizer->getState() == GestureRecognizerStateEnded)) {\n                    _gestureRecognizersToStart.emplace_back(gestureRecognizer);\n                    TOUCHDISPATCHER_DEBUG(\"{} is requesting to start\", gestureRecognizer->toDebugString());\n                }\n            } else {\n                // Cancelling gesture since the layer is not in the layer hierarchy anymore\n                shouldCancel = true;\n                TOUCHDISPATCHER_DEBUG(\"{} is no longer in hierarchy\", gestureRecognizer->toDebugString());\n            }\n        } else {\n            TOUCHDISPATCHER_DEBUG(\"{} is deferred\", gestureRecognizer->toDebugString());\n        }\n\n        if (shouldCancel) {\n            TOUCHDISPATCHER_DEBUG(\"Canceling {}\", gestureRecognizer->toDebugString());\n            gestureRecognizer->cancel();\n            candidateIt = _candidateGestureRecognizers.erase(candidateIt);\n        } else {\n            candidateIt++;\n        }\n    }\n}\n\nvoid TouchDispatcher::cancelGestureRecognizer(const Valdi::Ref<GestureRecognizer>& gestureRecognizer) {\n    TOUCHDISPATCHER_DEBUG(\"Canceling {}\", gestureRecognizer->toDebugString());\n    removeGestureRecognizer(_candidateGestureRecognizers, gestureRecognizer);\n    removeGestureRecognizer(_gestureRecognizersToStart, gestureRecognizer);\n\n    gestureRecognizer->cancel();\n}\n\nvoid TouchDispatcher::cancelGestureRecognizersBeforeIndex(size_t index) {\n    index++;\n    for (; index < _candidateGestureRecognizers.size(); index++) {\n        auto gestureRecognizer = _candidateGestureRecognizers[index];\n        cancelGestureRecognizer(gestureRecognizer);\n    }\n}\n\nvoid TouchDispatcher::startPendingGestureRecognizers() {\n    auto index = _gestureRecognizersToStart.size();\n    while (index > 0) {\n        index--;\n\n        auto gestureRecognizer = _gestureRecognizersToStart[index];\n\n        TOUCHDISPATCHER_DEBUG(\"Processing gesture requesting start on {}\", gestureRecognizer->toDebugString());\n\n        auto shouldStart = true;\n        auto shouldDefer = false;\n\n        auto downIndex = index;\n        while (downIndex > 0) {\n            downIndex--;\n            auto conflictingGestureRecognizer = _gestureRecognizersToStart[downIndex];\n            if (!canRecognizeSimultaneously(gestureRecognizer, conflictingGestureRecognizer)) {\n                if (conflictingGestureRecognizer->requiresFailureOf(*gestureRecognizer)) {\n                    // The conflicting gesture required failure of this gesture but this gesture succeeded, so we cancel\n                    // the conflicting gesture.\n                    TOUCHDISPATCHER_DEBUG(\"Cancelling conflicting gesture {} with {}\",\n                                          conflictingGestureRecognizer->toDebugString(),\n                                          gestureRecognizer->toDebugString());\n\n                    conflictingGestureRecognizer->cancel();\n                    _gestureRecognizersToStart.erase(_gestureRecognizersToStart.begin() + downIndex);\n                    removeGestureRecognizer(_candidateGestureRecognizers, conflictingGestureRecognizer);\n\n                    index--;\n                } else {\n                    shouldStart = false;\n                    TOUCHDISPATCHER_DEBUG(\"{} conflicts with {}, waiting for resolution\",\n                                          conflictingGestureRecognizer->toDebugString(),\n                                          gestureRecognizer->toDebugString());\n                    break;\n                }\n            }\n        }\n\n        if (shouldStart) {\n            // Also look up in the active gesture recognizers\n            for (const auto& activeGestureRecognizer : _candidateGestureRecognizers) {\n                if (activeGestureRecognizer == gestureRecognizer) {\n                    continue;\n                }\n\n                if (activeGestureRecognizer->getState() == GestureRecognizerStateChanged ||\n                    activeGestureRecognizer->getState() == GestureRecognizerStateEnded) {\n                    if (!canRecognizeSimultaneously(gestureRecognizer, activeGestureRecognizer)) {\n                        shouldStart = false;\n                        TOUCHDISPATCHER_DEBUG(\"Cannot start {} due to conflict with active gesture {}\",\n                                              gestureRecognizer->toDebugString(),\n                                              activeGestureRecognizer->toDebugString());\n                        break;\n                    }\n                } else if (activeGestureRecognizer->getState() == GestureRecognizerStatePossible) {\n                    if (gestureRecognizer->requiresFailureOf(*activeGestureRecognizer)) {\n                        shouldDefer = true;\n                        TOUCHDISPATCHER_DEBUG(\"Deferring start of {} due to conflict with candidate {}\",\n                                              gestureRecognizer->toDebugString(),\n                                              activeGestureRecognizer->toDebugString());\n                        break;\n                    }\n                }\n            }\n        }\n\n        if (!shouldDefer) {\n            removeGestureRecognizer(_gestureRecognizersToStart, gestureRecognizer);\n\n            if (shouldStart) {\n                if (gestureRecognizer->shouldCancelOtherGesturesOnStart()) {\n                    cancelGestureRecognizersBeforeIndex(\n                        indexOfGestureRecognizer(_candidateGestureRecognizers, gestureRecognizer));\n                    index = 0;\n                }\n                TOUCHDISPATCHER_DEBUG(\"Starting {}\", gestureRecognizer->toDebugString());\n\n                gestureRecognizer->onStarted();\n            } else {\n                cancelGestureRecognizer(gestureRecognizer);\n            }\n        }\n    }\n}\n\nvoid TouchDispatcher::processActiveGestureRecognizers() {\n    auto it = _candidateGestureRecognizers.begin();\n    while (it != _candidateGestureRecognizers.end()) {\n        const auto& gestureRecognizer = *it;\n\n        if (!isGestureRecognizerDeferred(gestureRecognizer) && gestureRecognizer->isActive()) {\n            TOUCHDISPATCHER_DEBUG(\"Processing active {}\", gestureRecognizer->toDebugString());\n\n            gestureRecognizer->process();\n\n            if (gestureRecognizer->getState() == GestureRecognizerStateEnded) {\n                TOUCHDISPATCHER_DEBUG(\"Gesture completed {}\", gestureRecognizer->toDebugString());\n\n                gestureRecognizer->cancel();\n                it = _candidateGestureRecognizers.erase(it);\n                continue;\n            }\n        } else {\n            TOUCHDISPATCHER_DEBUG(\"Candidate gesture is not active {}\", gestureRecognizer->toDebugString());\n        }\n\n        it++;\n    }\n}\n\nbool TouchDispatcher::isGestureRecognizerDeferred(const Valdi::Ref<GestureRecognizer>& gestureRecognizer) const {\n    return std::find(_gestureRecognizersToStart.begin(), _gestureRecognizersToStart.end(), gestureRecognizer) !=\n           _gestureRecognizersToStart.end();\n}\n\nbool TouchDispatcher::canRecognizeSimultaneously(const Valdi::Ref<GestureRecognizer>& leftGestureRecognizer,\n                                                 const Valdi::Ref<GestureRecognizer>& rightGestureRecognizer) {\n    if (leftGestureRecognizer->canRecognizeSimultaneously(*rightGestureRecognizer)) {\n        return true;\n    }\n    if (rightGestureRecognizer->canRecognizeSimultaneously(*leftGestureRecognizer)) {\n        return true;\n    }\n    return false;\n}\n\nstd::optional<TouchEvent> TouchDispatcher::adjustEventCoordinatesToLayer(const Valdi::Ref<Layer>& rootLayer,\n                                                                         const Valdi::Ref<ILayer>& childLayer,\n                                                                         const TouchEvent& event) {\n    auto typedChildLayer = Valdi::castOrNull<Layer>(childLayer);\n    if (typedChildLayer == nullptr) {\n        return std::nullopt;\n    }\n\n    auto convertedPoint = rootLayer->convertPointToLayer(event.getLocation(), typedChildLayer);\n    if (!convertedPoint) {\n        return std::nullopt;\n    }\n\n    return event.withLocation(convertedPoint.value());\n}\n\nbool TouchDispatcher::isDispatchingEvent() const {\n    return _dispatchingEvent;\n}\n\nbool TouchDispatcher::isEmpty() const {\n    return _candidateGestureRecognizers.empty() && _gestureRecognizersToStart.empty();\n}\n\nconst std::optional<TouchEvent>& TouchDispatcher::getLastEvent() const {\n    return _lastEvent;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/TouchDispatcher.hpp",
    "content": "//\n//  SkiaTouchDispatcher.hpp\n//  valdi-skia-apple\n//\n//  Created by Simon Corsin on 6/27/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/TouchEvent.hpp\"\n\n#include \"valdi_core/cpp/Interfaces/ILogger.hpp\"\n\n#include <optional>\n#include <vector>\n\nnamespace snap::drawing {\n\nclass TouchDispatcher {\npublic:\n    TouchDispatcher(Valdi::ILogger& logger, bool enableLogging);\n\n    void cancelAllGestures();\n\n    bool dispatchEvent(const TouchEvent& event, const Valdi::Ref<Layer>& rootLayer);\n\n    bool isDispatchingEvent() const;\n\n    std::vector<Valdi::Ref<GestureRecognizer>> getGestureCandidatesForEvent(const TouchEvent& event,\n                                                                            const Valdi::Ref<Layer>& rootLayer) const;\n\n    bool isEmpty() const;\n\n    const std::optional<TouchEvent>& getLastEvent() const;\n\nprivate:\n    std::vector<Valdi::Ref<GestureRecognizer>> _candidateGestureRecognizers;\n    std::vector<Valdi::Ref<GestureRecognizer>> _gestureRecognizersToStart;\n    std::optional<TouchEvent> _lastEvent;\n    [[maybe_unused]] Valdi::ILogger& _logger;\n    bool _dispatchingEvent = false;\n    bool _enableLogging = false;\n\n    bool captureCandidates(const TouchEvent& event,\n                           const Valdi::Ref<Layer>& layer,\n                           std::vector<Valdi::Ref<GestureRecognizer>>& candidateGestureRecognizers) const;\n\n    static bool containsGestureRecognizer(const Valdi::Ref<GestureRecognizer>& gestureRecognizer,\n                                          const std::vector<Valdi::Ref<GestureRecognizer>>& gestureRecognizers);\n\n    bool processGestureRecognizers(const Valdi::Ref<Layer>& rootLayer);\n\n    bool isGestureRecognizerDeferred(const Valdi::Ref<GestureRecognizer>& gestureRecognizer) const;\n\n    void cancelGestureRecognizer(const Valdi::Ref<GestureRecognizer>& gestureRecognizer);\n    void cancelGestureRecognizersBeforeIndex(size_t index);\n\n    void updateGestureRecognizers(const Valdi::Ref<Layer>& rootLayer);\n    void startPendingGestureRecognizers();\n    void processActiveGestureRecognizers();\n\n    static bool canRecognizeSimultaneously(const Valdi::Ref<GestureRecognizer>& leftGestureRecognizer,\n                                           const Valdi::Ref<GestureRecognizer>& rightGestureRecognizer);\n\n    static std::optional<TouchEvent> adjustEventCoordinatesToLayer(const Valdi::Ref<Layer>& rootLayer,\n                                                                   const Valdi::Ref<ILayer>& childLayer,\n                                                                   const TouchEvent& event);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/TouchEvent.cpp",
    "content": "//\n//  SkiaTouchEvent.cpp\n//  valdi-skia-apple\n//\n//  Created by Simon Corsin on 6/27/20.\n//\n\n#include \"snap_drawing/cpp/Touches/TouchEvent.hpp\"\n#include \"utils/debugging/Assert.hpp\"\n#include <fmt/format.h>\n#include <fmt/ostream.h>\n\nnamespace snap::drawing {\n\nTouchEvent::TouchEvent(TouchEventType type,\n                       const Point& locationFromWindow,\n                       const Point& location,\n                       const Vector& direction,\n                       size_t pointerCount,\n                       size_t actionIndex,\n                       TouchEvent::PointerLocations pointerLocations,\n                       const TimePoint& timePoint,\n                       Duration offsetSinceSource,\n                       const Ref<Valdi::RefCountable>& source)\n    : _type(type),\n      _locationFromWindow(locationFromWindow),\n      _location(location),\n      _direction(direction),\n      _pointerCount(pointerCount),\n      _actionIndex(actionIndex),\n      _pointerLocations(std::move(pointerLocations)),\n      _time(timePoint),\n      _offsetSinceSource(offsetSinceSource),\n      _source(source) {}\n\nTouchEvent::~TouchEvent() = default;\n\nTouchEventType TouchEvent::getType() const {\n    return _type;\n}\n\nconst Point& TouchEvent::getLocationInWindow() const {\n    return _locationFromWindow;\n}\n\nconst Point& TouchEvent::getLocation() const {\n    return _location;\n}\n\nconst Vector& TouchEvent::getDirection() const {\n    return _direction;\n}\n\nsize_t TouchEvent::getPointerCount() const {\n    return _pointerCount;\n}\n\nsize_t TouchEvent::getActionIndex() const {\n    return _actionIndex;\n}\n\nconst Point& TouchEvent::getLocationByPointer(size_t pointer) const {\n    SC_ASSERT(pointer < _pointerLocations.size());\n    return _pointerLocations[pointer];\n}\n\nconst TouchEvent::PointerLocations& TouchEvent::getPointerLocations() const {\n    return _pointerLocations;\n}\n\nconst TimePoint& TouchEvent::getTime() const {\n    return _time;\n}\n\nconst Ref<Valdi::RefCountable>& TouchEvent::getSource() const {\n    return _source;\n}\n\nDuration TouchEvent::getOffsetSinceSource() const {\n    return _offsetSinceSource;\n}\n\nTouchEvent TouchEvent::withLocation(const Point& newLocation) const {\n    return TouchEvent(_type,\n                      _locationFromWindow,\n                      newLocation,\n                      _direction,\n                      _pointerCount,\n                      _actionIndex,\n                      _pointerLocations,\n                      _time,\n                      _offsetSinceSource,\n                      _source);\n}\n\nstd::string TouchEvent::toString() const {\n    std::string_view type;\n    switch (_type) {\n        case TouchEventTypeDown:\n            type = \"down\";\n            break;\n        case TouchEventTypeMoved:\n            type = \"moved\";\n            break;\n        case TouchEventTypeIdle:\n            type = \"idle\";\n            break;\n        case TouchEventTypeUp:\n            type = \"up\";\n            break;\n        case TouchEventTypeWheel:\n            type = \"wheel\";\n            break;\n        case TouchEventTypeNone:\n            type = \"none\";\n            break;\n        case TouchEventTypePointerDown:\n            type = \"pointerdown\";\n            break;\n        case TouchEventTypePointerUp:\n            type = \"pointerup\";\n            break;\n    }\n\n    return fmt::format(\n        \"touch type {} at window location {}, local location {}, pointerCount {}, actionIndex {}, time {}\",\n        type,\n        _locationFromWindow,\n        _location,\n        _pointerCount,\n        _actionIndex,\n        _time.getTime());\n}\n\nstd::ostream& operator<<(std::ostream& os, const TouchEvent& touchEvent) noexcept {\n    return os << touchEvent.toString();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/TouchEvent.hpp",
    "content": "//\n//  SkiaTouchEvent.hpp\n//  valdi-skia-apple\n//\n//  Created by Simon Corsin on 6/27/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n#include <ostream>\n\nnamespace snap::drawing {\n\nenum TouchEventType {\n    TouchEventTypeDown,        // the user touched down\n    TouchEventTypeMoved,       // the touch moved\n    TouchEventTypeIdle,        // the touch is active but not moving\n    TouchEventTypeUp,          // the user touched up\n    TouchEventTypeWheel,       // the user moved the scrollwheel (or panned with a touchpad)\n    TouchEventTypeNone,        // there are no longer any active touches\n    TouchEventTypePointerUp,   // multitouch, when the user removes a pointer (lifts a finger up)\n    TouchEventTypePointerDown, // multitouch, when the user adds a pointer (places a finger down)\n};\n\nclass TouchEvent {\npublic:\n    using PointerLocations = Valdi::SmallVector<Point, 2>;\n\n    TouchEvent(TouchEventType type,\n               const Point& locationFromWindow,\n               const Point& location,\n               const Vector& direction,\n               size_t pointerCount,\n               size_t actionIndex,\n               const PointerLocations pointerLocations,\n               const TimePoint& time,\n               Duration offsetSinceSource,\n               const Ref<Valdi::RefCountable>& source);\n    ~TouchEvent();\n\n    TouchEventType getType() const;\n\n    const Point& getLocationInWindow() const;\n\n    const Point& getLocation() const;\n\n    const Vector& getDirection() const;\n\n    Duration getOffsetSinceSource() const;\n\n    size_t getPointerCount() const;\n\n    size_t getActionIndex() const;\n\n    const Point& getLocationByPointer(size_t pointer) const;\n\n    const PointerLocations& getPointerLocations() const;\n\n    const TimePoint& getTime() const;\n\n    const Ref<Valdi::RefCountable>& getSource() const;\n\n    std::string toString() const;\n\n    TouchEvent withLocation(const Point& newLocation) const;\n\nprivate:\n    TouchEventType _type;\n    Point _locationFromWindow;\n    Point _location;\n    Vector _direction;\n    size_t _pointerCount;\n    size_t _actionIndex;\n    TouchEvent::PointerLocations _pointerLocations;\n    TimePoint _time;\n    Duration _offsetSinceSource;\n    Ref<Valdi::RefCountable> _source;\n};\n\nstd::ostream& operator<<(std::ostream& os, const TouchEvent& touchEvent) noexcept;\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/TouchGestureRecognizer.cpp",
    "content": "//\n//  TouchGestureRecognizer.cpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#include \"snap_drawing/cpp/Touches/TouchGestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nTouchGestureRecognizer::TouchGestureRecognizer(const GesturesConfiguration& /*gesturesConfiguration*/) {}\n\nTouchGestureRecognizer::~TouchGestureRecognizer() = default;\n\nbool TouchGestureRecognizer::canRecognizeSimultaneously(const GestureRecognizer& /*other*/) const {\n    return true;\n}\n\nvoid TouchGestureRecognizer::onUpdate(const TouchEvent& event) {\n    switch (event.getType()) {\n        case TouchEventTypeDown: {\n            if (_onTouchDelayDuration <= Duration::fromSeconds(0)) {\n                transitionToState(GestureRecognizerStateBegan);\n            } else {\n                _touchGestureState = {TouchGestureRecognizerState(event)};\n            }\n        } break;\n        case TouchEventTypeWheel: {\n        } break;\n        case TouchEventTypeIdle: {\n            if (!isActive() && _touchGestureState.has_value() &&\n                event.getTime().durationSince(_touchGestureState->startEvent.getTime()) >= _onTouchDelayDuration) {\n                transitionToState(GestureRecognizerStateBegan);\n            }\n        } break;\n        // adding/removing pointers treated as moving - the touch event is still active\n        case TouchEventTypePointerUp:\n            [[fallthrough]];\n        case TouchEventTypePointerDown:\n            [[fallthrough]];\n        case TouchEventTypeMoved: {\n            if (isActive()) {\n                transitionToState(GestureRecognizerStateChanged);\n            } else if (_touchGestureState.has_value() &&\n                       event.getTime().durationSince(_touchGestureState->startEvent.getTime()) >=\n                           _onTouchDelayDuration) {\n                transitionToState(GestureRecognizerStateBegan);\n            }\n        } break;\n        case TouchEventTypeUp: {\n            transitionToState(GestureRecognizerStateEnded);\n        } break;\n        case TouchEventTypeNone: {\n            transitionToState(GestureRecognizerStateFailed);\n        } break;\n    }\n}\n\nvoid TouchGestureRecognizer::onProcess() {\n    if (getState() == GestureRecognizerStateBegan) {\n        if (_onStartListener) {\n            _onStartListener(*this, getState(), getLocation());\n        }\n    } else if (getState() == GestureRecognizerStateEnded) {\n        if (_onEndListener) {\n            _onEndListener(*this, getState(), getLocation());\n        }\n    }\n\n    if (getLastEvent()->getType() != TouchEventTypeIdle && _listener) {\n        _listener(*this, getState(), getLocation());\n    }\n}\n\nvoid TouchGestureRecognizer::setListener(TouchGestureRecognizerListener&& listener) {\n    _listener = std::move(listener);\n}\n\nvoid TouchGestureRecognizer::setOnStartListener(TouchGestureRecognizerListener&& onStartListener) {\n    _onStartListener = std::move(onStartListener);\n}\n\nvoid TouchGestureRecognizer::setOnEndListener(TouchGestureRecognizerListener&& onEndListener) {\n    _onEndListener = std::move(onEndListener);\n}\n\nvoid TouchGestureRecognizer::setOnTouchDelayDuration(Duration onTouchDelayDuration) {\n    _onTouchDelayDuration = onTouchDelayDuration;\n}\n\nbool TouchGestureRecognizer::isEmpty() const {\n    return (!_listener && !_onStartListener && !_onEndListener && _onTouchDelayDuration == Duration::fromSeconds(0));\n}\n\nvoid TouchGestureRecognizer::onReset() {\n    _touchGestureState = std::nullopt;\n}\n\nstd::string_view TouchGestureRecognizer::getTypeName() const {\n    return \"touch\";\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/TouchGestureRecognizer.hpp",
    "content": "//\n//  TouchGestureRecognizer.hpp\n//  valdi-skia\n//\n//  Created by Simon Corsin on 6/29/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/GesturesConfiguration.hpp\"\n\nnamespace snap::drawing {\n\nclass TouchGestureRecognizer;\nusing TouchGestureRecognizerListener = GestureRecognizerListener<TouchGestureRecognizer, Point>;\n\nstruct TouchGestureRecognizerState {\n    TouchEvent startEvent;\n\n    explicit inline TouchGestureRecognizerState(const TouchEvent& startEvent) : startEvent(startEvent) {}\n};\n\nclass TouchGestureRecognizer : public GestureRecognizer {\npublic:\n    explicit TouchGestureRecognizer(const GesturesConfiguration& gesturesConfiguration);\n    ~TouchGestureRecognizer() override;\n\n    bool canRecognizeSimultaneously(const GestureRecognizer& other) const override;\n\n    void setListener(TouchGestureRecognizerListener&& listener);\n\n    void setOnStartListener(TouchGestureRecognizerListener&& onStartListener);\n    void setOnEndListener(TouchGestureRecognizerListener&& onEndListener);\n\n    void setOnTouchDelayDuration(Duration onTouchDelayDuration);\n\n    bool isEmpty() const;\n\nprotected:\n    void onUpdate(const TouchEvent& event) override;\n\n    void onProcess() override;\n\n    void onReset() override;\n\n    std::string_view getTypeName() const final;\n\nprivate:\n    TouchGestureRecognizerListener _listener;\n    TouchGestureRecognizerListener _onStartListener;\n    TouchGestureRecognizerListener _onEndListener;\n    Duration _onTouchDelayDuration;\n\n    std::optional<TouchGestureRecognizerState> _touchGestureState;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/WheelGestureRecognizer.cpp",
    "content": "#include \"snap_drawing/cpp/Touches/WheelGestureRecognizer.hpp\"\n\n#include <iostream>\n\nnamespace snap::drawing {\n\nWheelGestureRecognizer::WheelGestureRecognizer(WheelGestureRecognizerListener&& listener)\n    : _listener(std::move(listener)) {}\n\nWheelGestureRecognizer::~WheelGestureRecognizer() = default;\n\nbool WheelGestureRecognizer::canRecognizeSimultaneously(const GestureRecognizer& /*other*/) const {\n    return true;\n}\n\nvoid WheelGestureRecognizer::onProcess() {\n    if (!_listener) {\n        return;\n    }\n\n    const auto* event = getLastEvent();\n    WheelScrollEvent scrollEvent;\n    scrollEvent.direction = event->getDirection();\n    scrollEvent.location = event->getLocation();\n    _listener(*this, getState(), scrollEvent);\n    transitionToState(GestureRecognizerStateEnded);\n}\n\nvoid WheelGestureRecognizer::onUpdate(const TouchEvent& event) {\n    switch (event.getType()) {\n        case TouchEventTypeWheel:\n            transitionToState(GestureRecognizerStateBegan);\n            break;\n        case TouchEventTypeDown:\n        case TouchEventTypeIdle:\n        case TouchEventTypeMoved:\n        case TouchEventTypeUp:\n        case TouchEventTypeNone:\n        case TouchEventTypePointerUp:\n        case TouchEventTypePointerDown: {\n            transitionToState(GestureRecognizerStateFailed);\n        } break;\n    }\n}\n\nstd::string_view WheelGestureRecognizer::getTypeName() const {\n    return \"drag\";\n}\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Touches/WheelGestureRecognizer.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Touches/GestureRecognizer.hpp\"\n\nnamespace snap::drawing {\n\nstruct WheelScrollEvent {\n    Point location;\n    Vector direction;\n};\n\nclass WheelGestureRecognizer;\nusing WheelGestureRecognizerListener = GestureRecognizerListener<WheelGestureRecognizer, WheelScrollEvent>;\n\nclass WheelGestureRecognizer : public GestureRecognizer {\npublic:\n    explicit WheelGestureRecognizer(WheelGestureRecognizerListener&& listener);\n    ~WheelGestureRecognizer() override;\n\n    bool canRecognizeSimultaneously(const GestureRecognizer& other) const override;\n\nprotected:\n    void onUpdate(const TouchEvent& event) override;\n    void onProcess() override;\n\n    std::string_view getTypeName() const final;\n\nprivate:\n    WheelGestureRecognizerListener _listener;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Aliases.hpp",
    "content": "//\n//  Aliases.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/2/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n#include \"valdi_core/cpp/Utils/StringBox.hpp\"\n\nnamespace snap::drawing {\n\ntemplate<typename T>\nusing Ref = Valdi::Ref<T>;\n\nusing String = Valdi::StringBox;\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/AnimatedImage.cpp",
    "content": "#include \"snap_drawing/cpp/Utils/AnimatedImage.hpp\"\n#include \"include/codec/SkCodec.h\"\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.hpp\"\n#include \"snap_drawing/cpp/Utils/BytesUtils.hpp\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n#include \"snap_drawing/cpp/Utils/LottieAnimatedImage.hpp\"\n#include \"snap_drawing/cpp/Utils/SkCodecAnimatedImage.hpp\"\n#include \"valdi_core/cpp/Utils/JSONReader.hpp\"\n\nnamespace snap::drawing {\n\nAnimatedImage::AnimatedImage() = default;\nAnimatedImage::~AnimatedImage() = default;\n\nvoid AnimatedImage::draw(SkCanvas* canvas,\n                         const Rect& drawBounds,\n                         const Duration& time,\n                         FittingSizeMode fittingSizeMode) {\n    doDraw(canvas, drawBounds, time, fittingSizeMode);\n}\n\nvoid AnimatedImage::drawInCanvas(const DrawableSurfaceCanvas& canvas,\n                                 const Rect& drawBounds,\n                                 const Duration& time,\n                                 FittingSizeMode fittingSizeMode) {\n    doDraw(canvas.getSkiaCanvas(), drawBounds, time, fittingSizeMode);\n}\n\nValdi::Result<Ref<AnimatedImage>> AnimatedImage::make(const Ref<IFontManager>& fontManager,\n                                                      const Valdi::Byte* data,\n                                                      size_t length) {\n    Image::initializeCodecs();\n\n    if constexpr (kLottieEnabled) {\n        if (isJsonObject(data, length)) {\n            return LottieAnimatedImage::make(fontManager, data, length).map<Ref<AnimatedImage>>();\n        }\n    }\n\n    const Valdi::BytesView bytesView(nullptr, data, length);\n    auto skData = skDataFromBytes(bytesView, DataConversionModeAlwaysCopy);\n    auto codec = SkCodec::MakeFromData(skData);\n    if (codec == nullptr) {\n        return Valdi::Error(\"Unsupported image format\");\n    }\n    return SkCodecAnimatedImage::make(std::move(codec)).map<Ref<AnimatedImage>>();\n}\n\nbool AnimatedImage::isJsonObject(const Valdi::Byte* data, size_t length) {\n    // Fuzzy but efficient check for JSON, and if so assume Lottie\n    Valdi::JSONReader reader(std::string_view(reinterpret_cast<const char*>(data), length));\n    return reader.parseBeginObject();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/AnimatedImage.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Duration.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"valdi_core/cpp/Resources/LoadedAsset.hpp\"\n\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\nclass SkCanvas;\n\nnamespace snap::drawing {\n\n#ifdef SNAP_DRAWING_LOTTIE_ENABLED\nconstexpr bool kLottieEnabled = true;\n#else\nconstexpr bool kLottieEnabled = false;\n#endif\n\nclass Resources;\nclass DrawableSurfaceCanvas;\nclass DrawingContext;\nclass IFontManager;\n\nclass AnimatedImage : public Valdi::LoadedAsset {\npublic:\n    AnimatedImage();\n    ~AnimatedImage() override;\n\n    void draw(SkCanvas* canvas,\n              const Rect& drawBounds,\n              const Duration& time,\n              FittingSizeMode fittingSizeMode = snap::drawing::FittingSizeModeCenterScaleFit);\n    void drawInCanvas(const DrawableSurfaceCanvas& canvas,\n                      const Rect& drawBounds,\n                      const Duration& time,\n                      FittingSizeMode fittingSizeMode = snap::drawing::FittingSizeModeCenterScaleFit);\n\n    virtual Duration getCurrentTime() const = 0;\n    virtual const Duration& getDuration() const = 0;\n    virtual const Size& getSize() const = 0;\n    virtual double getFrameRate() const = 0;\n\n    static Valdi::Result<Ref<AnimatedImage>> make(const Ref<IFontManager>& fontManager,\n                                                  const Valdi::Byte* data,\n                                                  size_t length);\n\nprotected:\n    virtual void doDraw(SkCanvas* canvas,\n                        const Rect& drawBounds,\n                        const Duration& time,\n                        FittingSizeMode fittingSizeMode) = 0;\n\nprivate:\n    static bool isJsonObject(const Valdi::Byte* data, size_t length);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Bitmap.cpp",
    "content": "//\n//  Bitmap.cpp\n//  snap_drawing\n//\n//  Created by Ramzy Jaber on 3/28/22.\n//\n\n#include \"snap_drawing/cpp/Utils/Bitmap.hpp\"\n#include \"snap_drawing/cpp/Utils/BitmapUtils.hpp\"\n\nnamespace snap::drawing {\n\nBitmap::Bitmap(SkBitmap&& bitmap) : _bitmap(std::move(bitmap)) {}\n\nValdi::BitmapInfo Bitmap::getInfo() const {\n    const auto& pixmap = _bitmap.pixmap();\n    return toBitmapInfo(pixmap.info());\n}\n\nvoid* Bitmap::lockBytes() {\n    const auto& pixmap = _bitmap.pixmap();\n    return pixmap.writable_addr();\n}\n\nvoid Bitmap::unlockBytes() {}\n\nvoid Bitmap::dispose() {\n    _bitmap = SkBitmap();\n}\n\nValdi::Result<Ref<Bitmap>> Bitmap::make(const Valdi::BitmapInfo& info) {\n    SkBitmap skBitmap;\n    auto imageInfo = toSkiaImageInfo(info);\n    if (!skBitmap.tryAllocPixels(imageInfo, std::max(info.rowBytes, imageInfo.minRowBytes()))) {\n        return Valdi::Error(\"Failed to allocate pixels for bitmap\");\n    }\n\n    return Valdi::makeShared<Bitmap>(std::move(skBitmap));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Bitmap.hpp",
    "content": "//\n//  Bitmap.hpp\n//  snap_drawing\n//\n//  Created by Ramzy Jaber on 3/28/22.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include \"include/core/SkBitmap.h\"\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\nnamespace snap::drawing {\n\nclass Bitmap : public Valdi::IBitmap {\npublic:\n    explicit Bitmap(SkBitmap&& bitmap);\n\n    ~Bitmap() override = default;\n\n    void dispose() override;\n\n    Valdi::BitmapInfo getInfo() const override;\n\n    void* lockBytes() override;\n\n    void unlockBytes() override;\n\n    static Valdi::Result<Ref<Bitmap>> make(const Valdi::BitmapInfo& info);\n\nprivate:\n    SkBitmap _bitmap;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BitmapFactory.cpp",
    "content": "#include \"snap_drawing/cpp/Utils/BitmapFactory.hpp\"\n#include \"snap_drawing/cpp/Utils/Bitmap.hpp\"\n\nnamespace snap::drawing {\n\nBitmapFactory::BitmapFactory(Valdi::ColorType colorType) : _colorType(colorType) {}\nBitmapFactory::~BitmapFactory() = default;\n\nValdi::Result<Ref<Valdi::IBitmap>> BitmapFactory::createBitmap(int width, int height) {\n    auto info = Valdi::BitmapInfo(width,\n                                  height,\n                                  _colorType,\n                                  Valdi::AlphaType::AlphaTypePremul,\n                                  width * Valdi::BitmapInfo::bytesPerPixelForColorType(_colorType));\n    auto result = Bitmap::make(info);\n    if (!result) {\n        return result.moveError();\n    }\n    return Ref<Valdi::IBitmap>(result.moveValue());\n}\n\nconst Ref<BitmapFactory>& BitmapFactory::getInstance(Valdi::ColorType colorType) {\n    switch (colorType) {\n        case Valdi::ColorType::ColorTypeUnknown:\n            std::abort();\n        case Valdi::ColorType::ColorTypeRGBA8888: {\n            static auto kInstance = Valdi::makeShared<BitmapFactory>(Valdi::ColorType::ColorTypeRGBA8888);\n            return kInstance;\n        }\n        case Valdi::ColorType::ColorTypeBGRA8888: {\n            static auto kInstance = Valdi::makeShared<BitmapFactory>(Valdi::ColorType::ColorTypeBGRA8888);\n            return kInstance;\n        }\n        case Valdi::ColorType::ColorTypeAlpha8: {\n            static auto kInstance = Valdi::makeShared<BitmapFactory>(Valdi::ColorType::ColorTypeAlpha8);\n            return kInstance;\n        }\n        case Valdi::ColorType::ColorTypeGray8: {\n            static auto kInstance = Valdi::makeShared<BitmapFactory>(Valdi::ColorType::ColorTypeGray8);\n            return kInstance;\n        }\n        case Valdi::ColorType::ColorTypeRGBAF16: {\n            static auto kInstance = Valdi::makeShared<BitmapFactory>(Valdi::ColorType::ColorTypeRGBAF16);\n            return kInstance;\n        }\n        case Valdi::ColorType::ColorTypeRGBAF32: {\n            static auto kInstance = Valdi::makeShared<BitmapFactory>(Valdi::ColorType::ColorTypeRGBAF32);\n            return kInstance;\n        }\n    }\n}\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BitmapFactory.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmapFactory.hpp\"\n\nnamespace snap::drawing {\n\nclass BitmapFactory : public Valdi::IBitmapFactory {\npublic:\n    explicit BitmapFactory(Valdi::ColorType colorType);\n    ~BitmapFactory() override;\n\n    Valdi::Result<Ref<Valdi::IBitmap>> createBitmap(int width, int height) override;\n\n    static const Ref<BitmapFactory>& getInstance(Valdi::ColorType colorType);\n\nprivate:\n    Valdi::ColorType _colorType;\n};\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BitmapUtils.cpp",
    "content": "//\n//  BitmapUtils.cpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/24/22.\n//\n\n#include \"snap_drawing/cpp/Utils/BitmapUtils.hpp\"\n#include \"include/core/SkImageInfo.h\"\n\nnamespace snap::drawing {\n\nstatic Valdi::ColorType toValdiColorType(SkColorType colorType) {\n    switch (colorType) {\n        case SkColorType::kUnknown_SkColorType:\n            return Valdi::ColorTypeUnknown;\n        case SkColorType::kRGBA_8888_SkColorType:\n            return Valdi::ColorTypeRGBA8888;\n        case SkColorType::kBGRA_8888_SkColorType:\n            return Valdi::ColorTypeBGRA8888;\n        case SkColorType::kAlpha_8_SkColorType:\n            return Valdi::ColorTypeAlpha8;\n        case SkColorType::kGray_8_SkColorType:\n            return Valdi::ColorTypeGray8;\n        case SkColorType::kRGBA_F16_SkColorType:\n            return Valdi::ColorTypeRGBAF16;\n        case SkColorType::kRGBA_F32_SkColorType:\n            return Valdi::ColorTypeRGBAF32;\n        default:\n            return Valdi::ColorTypeUnknown;\n    }\n}\n\nstatic Valdi::AlphaType toValdiAlphaType(SkAlphaType alphaType) {\n    switch (alphaType) {\n        case SkAlphaType::kOpaque_SkAlphaType:\n            return Valdi::AlphaTypeOpaque;\n        case SkAlphaType::kPremul_SkAlphaType:\n            return Valdi::AlphaTypePremul;\n        case SkAlphaType::kUnpremul_SkAlphaType:\n            return Valdi::AlphaTypeUnpremul;\n        default:\n            return Valdi::AlphaTypeOpaque;\n    }\n}\n\nValdi::BitmapInfo toBitmapInfo(const SkImageInfo& info) {\n    auto colorType = toValdiColorType(info.colorType());\n    auto alphaType = toValdiAlphaType(info.alphaType());\n    auto rowByteSize = info.minRowBytes();\n\n    return Valdi::BitmapInfo(info.width(), info.height(), colorType, alphaType, rowByteSize);\n}\n\nSkColorType toSkiaColorType(Valdi::ColorType colorType) {\n    switch (colorType) {\n        case Valdi::ColorTypeUnknown:\n            return SkColorType::kUnknown_SkColorType;\n        case Valdi::ColorTypeRGBA8888:\n            return SkColorType::kRGBA_8888_SkColorType;\n        case Valdi::ColorTypeBGRA8888:\n            return SkColorType::kBGRA_8888_SkColorType;\n        case Valdi::ColorTypeAlpha8:\n            return SkColorType::kAlpha_8_SkColorType;\n        case Valdi::ColorTypeGray8:\n            return SkColorType::kGray_8_SkColorType;\n        case Valdi::ColorTypeRGBAF16:\n            return SkColorType::kRGBA_F16_SkColorType;\n        case Valdi::ColorTypeRGBAF32:\n            return SkColorType::kRGBA_F32_SkColorType;\n    }\n\n    return SkColorType::kUnknown_SkColorType;\n}\n\nstatic SkAlphaType toSkiaAlphaType(Valdi::AlphaType alphaType) {\n    switch (alphaType) {\n        case Valdi::AlphaTypeOpaque:\n            return SkAlphaType::kOpaque_SkAlphaType;\n        case Valdi::AlphaTypePremul:\n            return SkAlphaType::kPremul_SkAlphaType;\n        case Valdi::AlphaTypeUnpremul:\n            return SkAlphaType::kUnpremul_SkAlphaType;\n    }\n\n    return SkAlphaType::kOpaque_SkAlphaType;\n}\n\nSkImageInfo toSkiaImageInfo(const Valdi::BitmapInfo& info) {\n    auto colorType = toSkiaColorType(info.colorType);\n    auto alphaType = toSkiaAlphaType(info.alphaType);\n\n    return SkImageInfo::Make(info.width, info.height, colorType, alphaType);\n}\n\nstatic void releaseBitmap(const void* /*ptr*/, void* context) {\n    auto bitmap = Valdi::unsafeBridge<Valdi::IBitmap>(context);\n    bitmap->unlockBytes();\n    Valdi::unsafeBridgeRelease(context);\n}\n\nValdi::Result<sk_sp<SkData>> bitmapToData(const Valdi::Ref<Valdi::IBitmap>& bitmap,\n                                          const Valdi::BitmapInfo& info,\n                                          bool copy) {\n    auto* bytes = bitmap->lockBytes();\n    if (bytes == nullptr) {\n        return Valdi::Error(\"Failed to lock bytes\");\n    }\n\n    auto size = info.rowBytes * static_cast<size_t>(info.height);\n\n    if (copy) {\n        auto data = SkData::MakeWithCopy(bytes, size);\n        bitmap->unlockBytes();\n        return data;\n    } else {\n        return SkData::MakeWithProc(bytes, size, &releaseBitmap, Valdi::unsafeBridgeRetain(bitmap.get()));\n    }\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BitmapUtils.hpp",
    "content": "//\n//  BitmapUtils.hpp\n//  snap_drawing-pc\n//\n//  Created by Simon Corsin on 1/24/22.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include \"include/core/SkData.h\"\n#include \"include/core/SkImageInfo.h\"\n\nnamespace snap::drawing {\n\nValdi::BitmapInfo toBitmapInfo(const SkImageInfo& info);\n\nSkImageInfo toSkiaImageInfo(const Valdi::BitmapInfo& info);\nSkColorType toSkiaColorType(Valdi::ColorType colorType);\n\nValdi::Result<sk_sp<SkData>> bitmapToData(const Valdi::Ref<Valdi::IBitmap>& bitmap,\n                                          const Valdi::BitmapInfo& info,\n                                          bool copy);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BorderRadius.cpp",
    "content": "//\n//  BorderRadius.cpp\n//  valdi-skia-app\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include <algorithm>\n#include <fmt/format.h>\n\nnamespace snap::drawing {\n\nBorderRadius::BorderRadius(Scalar topLeft,\n                           Scalar topRight,\n                           Scalar bottomRight,\n                           Scalar bottomLeft,\n                           bool topLeftIsPercent,\n                           bool topRightIsPercent,\n                           bool bottomRightIsPercent,\n                           bool bottomLeftIsPercent)\n    : _topLeft(topLeft),\n      _topRight(topRight),\n      _bottomRight(bottomRight),\n      _bottomLeft(bottomLeft),\n      _topLeftIsPercent(topLeftIsPercent),\n      _topRightIsPercent(topRightIsPercent),\n      _bottomRightIsPercent(bottomRightIsPercent),\n      _bottomLeftIsPercent(bottomLeftIsPercent) {\n    _isEmpty = topLeft == 0 && topRight == 0 && bottomRight == 0 && bottomLeft == 0;\n}\n\nBorderRadius::BorderRadius() = default;\n\nbool BorderRadius::isEmpty() const {\n    return _isEmpty;\n}\n\nScalar BorderRadius::sideLengthForPercentages(const Rect& bounds) {\n    return std::min(bounds.width(), bounds.height());\n}\n\nBorderRadius BorderRadius::makeCircle() {\n    return BorderRadius::makeOval(50, true);\n}\n\nBorderRadius BorderRadius::makeOval(Scalar corners, bool isPercent) {\n    return BorderRadius(corners, corners, corners, corners, isPercent, isPercent, isPercent, isPercent);\n}\n\nstatic inline void populateBorderRadius(Scalar* radii, Scalar sizeRatio, Scalar value, bool isPercent) {\n    if (isPercent) {\n        value *= sizeRatio;\n    }\n    radii[0] = value;\n    radii[1] = value;\n}\n\nPath BorderRadius::getPath(const Rect& bounds) const {\n    Path path;\n\n    applyToPath(bounds, path);\n\n    return path;\n}\n\nvoid BorderRadius::applyToPath(const Rect& bounds, Path& path) const {\n    Scalar radii[8];\n\n    Scalar sizeRatio = sideLengthForPercentages(bounds) / 100;\n\n    populateBorderRadius(&radii[0], sizeRatio, _topLeft, _topLeftIsPercent);\n    populateBorderRadius(&radii[2], sizeRatio, _topRight, _topRightIsPercent);\n    populateBorderRadius(&radii[4], sizeRatio, _bottomRight, _bottomRightIsPercent);\n    populateBorderRadius(&radii[6], sizeRatio, _bottomLeft, _bottomLeftIsPercent);\n\n    path.addRoundRect(bounds, radii, true);\n}\n\nbool BorderRadius::operator==(const BorderRadius& other) const {\n    return _topLeft == other._topLeft && _topRight == other._topRight && _bottomRight == other._bottomRight &&\n           _bottomLeft == other._bottomLeft && _topLeftIsPercent == other._topLeftIsPercent &&\n           _topRightIsPercent == other._topRightIsPercent && _bottomRightIsPercent == other._bottomRightIsPercent &&\n           _bottomLeftIsPercent == other._bottomLeftIsPercent;\n}\n\nbool BorderRadius::operator!=(const BorderRadius& other) const {\n    return !(*this == other);\n}\n\nstatic std::string borderToString(Scalar value, bool isPercent) {\n    auto strValue = fmt::format(\"{:.1f}\", value);\n    if (isPercent) {\n        strValue += \"%\";\n    }\n    return strValue;\n}\n\nstd::string BorderRadius::toString() const {\n    return fmt::format(\"[{}, {}, {}, {}]\",\n                       borderToString(_topLeft, _topLeftIsPercent),\n                       borderToString(_topRight, _topRightIsPercent),\n                       borderToString(_bottomRight, _bottomRightIsPercent),\n                       borderToString(_bottomLeft, _bottomLeftIsPercent));\n}\n\nstd::ostream& operator<<(std::ostream& os, const BorderRadius& borderRadius) {\n    return os << borderRadius.toString();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BorderRadius.hpp",
    "content": "//\n//  BorderRadius.hpp\n//  valdi-skia-app\n//\n//  Created by Simon Corsin on 6/28/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n\n#include <ostream>\n#include <string>\n\nnamespace snap::drawing {\n\nclass BorderRadius {\npublic:\n    BorderRadius(Scalar topLeft,\n                 Scalar topRight,\n                 Scalar bottomRight,\n                 Scalar bottomLeft,\n                 bool topLeftIsPercent,\n                 bool topRightIsPercent,\n                 bool bottomRightIsPercent,\n                 bool bottomLeftIsPercent);\n    BorderRadius();\n\n    constexpr Scalar topLeft() const {\n        return _topLeft;\n    }\n\n    constexpr Scalar topRight() const {\n        return _topRight;\n    }\n\n    constexpr Scalar bottomLeft() const {\n        return _bottomLeft;\n    }\n\n    constexpr Scalar bottomRight() const {\n        return _bottomRight;\n    }\n\n    constexpr bool topLeftIsPercent() const {\n        return _topLeftIsPercent;\n    }\n\n    constexpr bool topRightIsPercent() const {\n        return _topRightIsPercent;\n    }\n\n    constexpr bool bottomLeftIsPercent() const {\n        return _bottomLeftIsPercent;\n    }\n\n    constexpr bool bottomRightIsPercent() const {\n        return _bottomRightIsPercent;\n    }\n\n    bool isEmpty() const;\n\n    void applyToPath(const Rect& bounds, Path& path) const;\n    Path getPath(const Rect& bounds) const;\n\n    bool operator==(const BorderRadius& other) const;\n    bool operator!=(const BorderRadius& other) const;\n\n    std::string toString() const;\n\n    static Scalar sideLengthForPercentages(const Rect& bounds);\n    static BorderRadius makeCircle();\n    static BorderRadius makeOval(Scalar corners, bool isPercent);\n\nprivate:\n    Scalar _topLeft = 0;\n    Scalar _topRight = 0;\n    Scalar _bottomRight = 0;\n    Scalar _bottomLeft = 0;\n\n    bool _topLeftIsPercent = false;\n    bool _topRightIsPercent = false;\n    bool _bottomRightIsPercent = false;\n    bool _bottomLeftIsPercent = false;\n    bool _isEmpty = true;\n};\n\nstd::ostream& operator<<(std::ostream& os, const BorderRadius& borderRadius);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BoundingBoxHierarchy.cpp",
    "content": "//\n//  BoundingBoxHierarchy.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/22/22.\n//\n\n#include \"snap_drawing/cpp/Utils/BoundingBoxHierarchy.hpp\"\n#include \"include/core/SkBBHFactory.h\"\n\nnamespace snap::drawing {\n\nBoundingBoxHierarchy::BoundingBoxHierarchy() = default;\nBoundingBoxHierarchy::~BoundingBoxHierarchy() = default;\n\nvoid BoundingBoxHierarchy::insert(const Rect& box) {\n    _frames.emplace_back(box.getSkValue());\n    _rTree = nullptr;\n}\n\nbool BoundingBoxHierarchy::contains(const Rect& box) {\n    if (_rTree == nullptr) {\n        SkRTreeFactory factory;\n        _rTree = factory();\n        _rTree->insert(_frames.data(), static_cast<int>(_frames.size()));\n    }\n\n    _rTree->search(box.getSkValue(), &_rTreeOutput);\n    if (_rTreeOutput.empty()) {\n        return false;\n    } else {\n        _rTreeOutput.clear();\n        return true;\n    }\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BoundingBoxHierarchy.hpp",
    "content": "//\n//  BoundingBoxHierarchy.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/22/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"include/core/SkRefCnt.h\"\n\n#include <vector>\n\nclass SkBBoxHierarchy;\n\nnamespace snap::drawing {\n\nclass BoundingBoxHierarchy : public Valdi::SimpleRefCountable {\npublic:\n    BoundingBoxHierarchy();\n    ~BoundingBoxHierarchy() override;\n\n    void insert(const Rect& box);\n    bool contains(const Rect& box);\n\nprivate:\n    std::vector<SkRect> _frames;\n    std::vector<int> _rTreeOutput;\n    sk_sp<SkBBoxHierarchy> _rTree;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BytesUtils.cpp",
    "content": "//\n//  BytesUtils.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#include \"snap_drawing/cpp/Utils/BytesUtils.hpp\"\n\nnamespace snap::drawing {\n\nclass SkiaDataHolder : public Valdi::SimpleRefCountable {\npublic:\n    explicit SkiaDataHolder(const sk_sp<SkData>& data) : _data(data) {}\n\n    ~SkiaDataHolder() override = default;\n\n    const sk_sp<SkData>& getData() const {\n        return _data;\n    }\n\nprivate:\n    sk_sp<SkData> _data;\n};\n\nValdi::BytesView bytesFromSkData(const sk_sp<SkData>& data) {\n    if (data == nullptr) {\n        return Valdi::BytesView();\n    }\n\n    return Valdi::BytesView(\n        Valdi::makeShared<SkiaDataHolder>(data), reinterpret_cast<const Valdi::Byte*>(data->data()), data->size());\n}\n\nstatic void releaseData(const void* /*ptr*/, void* context) {\n    Valdi::unsafeBridgeRelease(context);\n}\n\nsk_sp<SkData> skDataFromBytes(const Valdi::BytesView& bytes, DataConversionMode conversionMode) {\n    auto dataHolder = Valdi::castOrNull<SkiaDataHolder>(bytes.getSource());\n\n    switch (conversionMode) {\n        case DataConversionModeCopyIfUnsafe: {\n            if (dataHolder != nullptr) {\n                return dataHolder->getData();\n            }\n\n            if (bytes.empty()) {\n                return SkData::MakeEmpty();\n            }\n\n            if (bytes.getSource() == nullptr) {\n                return SkData::MakeWithCopy(bytes.data(), bytes.size());\n            } else {\n                auto* source = Valdi::unsafeBridgeRetain(bytes.getSource().get());\n                return SkData::MakeWithProc(bytes.data(), bytes.size(), &releaseData, source);\n            }\n        }\n        case DataConversionModeAlwaysCopy: {\n            return SkData::MakeWithCopy(bytes.data(), bytes.size());\n        }\n        case DataConversionModeNeverCopy: {\n            if (dataHolder != nullptr) {\n                return dataHolder->getData();\n            }\n\n            if (bytes.getSource() == nullptr) {\n                return SkData::MakeWithoutCopy(bytes.data(), bytes.size());\n            } else {\n                auto* source = Valdi::unsafeBridgeRetain(bytes.getSource().get());\n                return SkData::MakeWithProc(bytes.data(), bytes.size(), &releaseData, source);\n            }\n        };\n    }\n\n    return nullptr;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/BytesUtils.hpp",
    "content": "//\n//  BytesUtils.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/20/22.\n//\n\n#pragma once\n\n#include \"include/core/SkData.h\"\n#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n\nnamespace snap::drawing {\n\nenum DataConversionMode {\n    DataConversionModeCopyIfUnsafe,\n    DataConversionModeAlwaysCopy,\n    DataConversionModeNeverCopy,\n};\n\nValdi::BytesView bytesFromSkData(const sk_sp<SkData>& data);\nsk_sp<SkData> skDataFromBytes(const Valdi::BytesView& bytes, DataConversionMode conversionMode);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Color.cpp",
    "content": "//\n//  Color.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n#include <fmt/format.h>\n\nnamespace snap::drawing {\n\nstd::string Color::toString() const {\n    return fmt::format(\"{:#010x}\", value);\n}\n\nstd::ostream& operator<<(std::ostream& os, const Color& color) {\n    return os << color.toString();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Color.hpp",
    "content": "//\n//  Color.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include \"include/core/SkColor.h\"\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n#include \"snap_drawing/cpp/Utils/SkiaBridge.hpp\"\n\n#include <ostream>\n#include <string>\n\nnamespace snap::drawing {\n\nusing ColorComponent = uint8_t;\n\nstruct Color : public BridgedSkValue<Color, SkColor> {\n    uint32_t value = 0;\n\n    constexpr Color() = default;\n    constexpr explicit Color(uint32_t value) : value(value) {}\n\n    std::string toString() const;\n\n    constexpr ColorComponent getAlpha() const {\n        return (value >> 24) & 0xFF;\n    }\n\n    constexpr ColorComponent getRed() const {\n        return (value >> 16) & 0xFF;\n    }\n\n    constexpr ColorComponent getGreen() const {\n        return (value >> 8) & 0xFF;\n    }\n\n    constexpr ColorComponent getBlue() const {\n        return value & 0xFF;\n    }\n\n    constexpr Color withAlpha(ColorComponent a) const {\n        return Color::makeARGB(a, getRed(), getGreen(), getBlue());\n    }\n\n    constexpr Color withAlphaRatio(Scalar alphaRatio) const {\n        return withAlpha(static_cast<ColorComponent>(static_cast<Scalar>(0xFF) * alphaRatio));\n    }\n\n    static constexpr Color make(uint32_t value) {\n        return Color(value);\n    }\n\n    static constexpr Color makeARGB(ColorComponent a, ColorComponent r, ColorComponent g, ColorComponent b) {\n        return make((a << 24) | (r << 16) | (g << 8) | (b << 0));\n    }\n\n    static constexpr Color transparent() {\n        return make(0);\n    }\n\n    static constexpr Color black() {\n        return makeARGB(0xFF, 0, 0, 0);\n    }\n\n    static constexpr Color white() {\n        return makeARGB(0xFF, 0xFF, 0xFF, 0xFF);\n    }\n\n    static constexpr Color red() {\n        return makeARGB(0xFF, 0xFF, 0, 0);\n    }\n\n    static constexpr Color green() {\n        return makeARGB(0xFF, 0, 0xFF, 0);\n    }\n\n    static constexpr Color blue() {\n        return makeARGB(0xFF, 0, 0, 0xFF);\n    }\n\n    constexpr bool operator==(Color other) const {\n        return value == other.value;\n    }\n\n    constexpr bool operator!=(Color other) const {\n        return value != other.value;\n    }\n};\n\nstd::ostream& operator<<(std::ostream& os, const Color& color);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Duration.hpp",
    "content": "//\n//  Duration.hpp\n//  valdi-pc\n//\n//  Created by Simon Corsin on 6/30/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Duration.hpp\"\n\nnamespace snap::drawing {\n\nusing TimeInterval = Valdi::TimeInterval;\nusing Duration = Valdi::Duration;\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Geometry.cpp",
    "content": "//\n//  Geometry.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\nnamespace snap::drawing {\n\nScalar Point::length(Scalar dx, Scalar dy) {\n    Scalar mag2 = dx * dx + dy * dy;\n    return sqrtf(mag2);\n}\n\nvoid Rect::join(const Rect& r) {\n    if (r.isEmpty()) {\n        return;\n    }\n\n    if (this->isEmpty()) {\n        *this = r;\n    } else {\n        left = std::min(left, r.left);\n        top = std::min(top, r.top);\n        right = std::max(right, r.right);\n        bottom = std::max(bottom, r.bottom);\n    }\n}\n\nRect Rect::makeFittingSize(Size size, FittingSizeMode mode) const {\n    auto selfWidth = width();\n    auto selfHeight = height();\n    auto halfWidth = selfWidth / 2.0f;\n    auto halfHeight = selfHeight / 2.0f;\n\n    switch (mode) {\n        case FittingSizeModeFill:\n            return *this;\n        case FittingSizeModeCenter: {\n            return Rect::makeXYWH(\n                left + halfWidth - size.width / 2.0f, top + halfHeight - size.height / 2.0f, size.width, size.height);\n        }\n        case FittingSizeModeCenterScaleFill:\n        case FittingSizeModeCenterScaleFit: {\n            auto wRatio = selfWidth / size.width;\n            auto hRatio = selfHeight / size.height;\n            auto ratio = mode == FittingSizeModeCenterScaleFill ? std::max(wRatio, hRatio) : std::min(wRatio, hRatio);\n\n            auto resolvedTargetWidth = size.width * ratio;\n            auto resolvedTargetHeight = size.height * ratio;\n\n            return Rect::makeXYWH(left + halfWidth - resolvedTargetWidth / 2.0f,\n                                  top + halfHeight - resolvedTargetHeight / 2.0f,\n                                  resolvedTargetWidth,\n                                  resolvedTargetHeight);\n        }\n    }\n}\n\nbool Rect::intersects(const Rect& other) const {\n    // Use Skia's exact floating-point comparison for general intersection checks.\n    // This is important for Compositor plane optimization logic.\n    return getSkValue().intersects(other.getSkValue());\n}\n\nbool Rect::intersectsWithTolerance(const Rect& other) const {\n    // Use epsilon-based comparison for damage rect merging.\n    // This prevents gaps when rects computed through different transformation paths\n    // have tiny numerical differences (e.g., 10.499999 vs 10.500001).\n    constexpr Scalar epsilon = 0.0001f; // ~1/10000th of a pixel\n\n    return !(other.right < left - epsilon || right < other.left - epsilon || other.bottom < top - epsilon ||\n             bottom < other.top - epsilon);\n}\n\nbool Rect::contains(const Point& point) const {\n    return !(point.x < left || point.x > right || point.y < top || point.y > bottom);\n}\n\nPoint Rect::closestPoint(const Point& toPoint) const {\n    auto closestX = std::clamp(toPoint.x, left, right);\n    auto closestY = std::clamp(toPoint.y, top, bottom);\n\n    return Point::make(closestX, closestY);\n}\n\nRect Rect::intersection(const Rect& other) const {\n    auto x = std::max(left, other.left);\n    auto y = std::max(top, other.top);\n    auto width = std::min(right, other.right) - x;\n    auto height = std::min(bottom, other.bottom) - y;\n\n    if (width < 0.0f || height < 0.0f) {\n        // Rectangles don't intersect\n        return Rect::makeEmpty();\n    }\n\n    return Rect::makeXYWH(x, y, width, height);\n}\n\nstd::ostream& operator<<(std::ostream& os, const Vector& vec) {\n    return os << \"dx: \" << vec.dx << \", dy: \" << vec.dy;\n}\n\nstd::ostream& operator<<(std::ostream& os, const Size& size) {\n    return os << \"w: \" << size.width << \", h: \" << size.height;\n}\n\nstd::ostream& operator<<(std::ostream& os, const Point& point) {\n    return os << \"x: \" << point.x << \", y: \" << point.y;\n}\n\nstd::ostream& operator<<(std::ostream& os, const Rect& rect) {\n    return os << \"x: \" << rect.left << \", y: \" << rect.top << \", w: \" << rect.width() << \", h: \" << rect.height();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Geometry.hpp",
    "content": "//\n//  Geometry.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n#include \"snap_drawing/cpp/Utils/SkiaBridge.hpp\"\n\n#include \"include/core/SkPoint.h\"\n#include \"include/core/SkRect.h\"\n\n#include <ostream>\n\nnamespace snap::drawing {\n\nstruct Vector {\n    Scalar dx = 0;\n    Scalar dy = 0;\n\n    constexpr Vector() = default;\n    constexpr Vector(Scalar dx, Scalar dy) : dx(dx), dy(dy) {}\n\n    static constexpr Vector make(Scalar dx, Scalar dy) {\n        return Vector(dx, dy);\n    }\n\n    inline bool operator==(const Vector& other) const {\n        return scalarsEqual<2>(reinterpret_cast<const Scalar*>(this), reinterpret_cast<const Scalar*>(&other));\n    }\n\n    inline bool operator!=(const Vector& other) const {\n        return !scalarsEqual<2>(reinterpret_cast<const Scalar*>(this), reinterpret_cast<const Scalar*>(&other));\n    }\n\n    static constexpr Vector makeEmpty() {\n        return make(0, 0);\n    }\n};\n\nstruct Size {\n    Scalar width = 0;\n    Scalar height = 0;\n\n    constexpr Size() = default;\n    constexpr Size(Scalar width, Scalar height) : width(width), height(height) {}\n\n    static constexpr Size make(Scalar width, Scalar height) {\n        return Size(width, height);\n    }\n\n    inline bool operator==(const Size& other) const {\n        return scalarsEqual<2>(reinterpret_cast<const Scalar*>(this), reinterpret_cast<const Scalar*>(&other));\n    }\n\n    inline bool operator!=(const Size& other) const {\n        return !scalarsEqual<2>(reinterpret_cast<const Scalar*>(this), reinterpret_cast<const Scalar*>(&other));\n    }\n\n    static constexpr Size makeEmpty() {\n        return make(0, 0);\n    }\n};\n\nstruct Point : public BridgedSkValue<Point, SkPoint> {\n    Scalar x = 0;\n    Scalar y = 0;\n\n    constexpr Point() = default;\n    constexpr Point(Scalar x, Scalar y) : x(x), y(y) {}\n\n    static constexpr Point make(Scalar x, Scalar y) {\n        return Point(x, y);\n    }\n\n    static constexpr Point makeEmpty() {\n        return make(0, 0);\n    }\n\n    constexpr void offset(Scalar dx, Scalar dy) {\n        x += dx;\n        y += dy;\n    }\n\n    constexpr Point makeOffset(Scalar dx, Scalar dy) const {\n        return Point::make(x + dx, y + dy);\n    }\n\n    /** Returns the Euclidean distance from origin, computed as:\n\n            sqrt(fX * fX + fY * fY)\n\n        .\n\n        @return  straight-line distance to origin\n     */\n    static Scalar length(Scalar dx, Scalar dy);\n\n    static Scalar distance(const Point& a, const Point& b) {\n        return length(a.x - b.x, a.y - b.y);\n    }\n\n    inline bool operator==(const Point& other) const {\n        return scalarsEqual<2>(reinterpret_cast<const Scalar*>(this), reinterpret_cast<const Scalar*>(&other));\n    }\n\n    inline bool operator!=(const Point& other) const {\n        return !scalarsEqual<2>(reinterpret_cast<const Scalar*>(this), reinterpret_cast<const Scalar*>(&other));\n    }\n};\n\nenum FittingSizeMode {\n    FittingSizeModeFill,\n    FittingSizeModeCenter,\n    FittingSizeModeCenterScaleFill,\n    FittingSizeModeCenterScaleFit,\n};\n\nstruct Rect : public BridgedSkValue<Rect, SkRect> {\n    Scalar left = 0;\n    Scalar top = 0;\n    Scalar right = 0;\n    Scalar bottom = 0;\n\n    constexpr Rect() = default;\n    constexpr Rect(Scalar left, Scalar top, Scalar right, Scalar bottom)\n        : left(left), top(top), right(right), bottom(bottom) {}\n\n    constexpr Scalar x() const {\n        return left;\n    }\n\n    constexpr Scalar y() const {\n        return top;\n    }\n\n    constexpr Scalar width() const {\n        return right - left;\n    }\n\n    constexpr Scalar height() const {\n        return bottom - top;\n    }\n\n    constexpr Size size() const {\n        return Size::make(width(), height());\n    }\n\n    constexpr Point center() const {\n        return Point::make(left + width() / 2.0f, top + height() / 2.0f);\n    }\n\n    inline bool operator==(const Rect& other) const {\n        return scalarsEqual<4>(reinterpret_cast<const Scalar*>(this), reinterpret_cast<const Scalar*>(&other));\n    }\n\n    inline bool operator!=(const Rect& other) const {\n        return !scalarsEqual<4>(reinterpret_cast<const Scalar*>(this), reinterpret_cast<const Scalar*>(&other));\n    }\n\n    static constexpr Rect makeLTRB(Scalar l, Scalar t, Scalar r, Scalar b) {\n        return Rect(l, t, r, b);\n    }\n\n    static constexpr Rect makeXYWH(Scalar x, Scalar y, Scalar w, Scalar h) {\n        return Rect(x, y, x + w, y + h);\n    }\n\n    static constexpr Rect makeEmpty() {\n        return makeLTRB(0, 0, 0, 0);\n    }\n\n    constexpr bool isEmpty() const {\n        return !(left < right && top < bottom);\n    }\n\n    constexpr Rect makeOffset(Scalar dx, Scalar dy) const {\n        return Rect::makeLTRB(left + dx, top + dy, right + dx, bottom + dy);\n    }\n\n    constexpr void offsetX(Scalar dx) {\n        left += dx;\n        right += dx;\n    }\n\n    constexpr void offsetY(Scalar dy) {\n        top += dy;\n        bottom += dy;\n    }\n\n    constexpr void offset(Scalar dx, Scalar dy) {\n        offsetX(dx);\n        offsetY(dy);\n    }\n\n    constexpr Rect withInsets(Scalar horizontalInsets, Scalar verticalInsets) const {\n        return Rect::makeLTRB(\n            left + horizontalInsets, top + verticalInsets, right - horizontalInsets, bottom - verticalInsets);\n    }\n\n    /**\n     Returns a new rect which will scale and position the given size\n     in this rect coordinates using the given mode.\n     */\n    Rect makeFittingSize(Size size, FittingSizeMode mode) const;\n\n    void join(const Rect& other);\n\n    Rect intersection(const Rect& other) const;\n\n    bool intersects(const Rect& other) const;\n\n    /**\n     Returns true if the two rectangles intersect, using a small tolerance for floating-point\n     comparison. This is useful for damage rect merging where rects computed through different\n     transformation paths may have tiny numerical differences but should still be considered\n     as intersecting.\n     */\n    bool intersectsWithTolerance(const Rect& other) const;\n\n    bool contains(const Point& point) const;\n\n    /**\n     Return the closest point to the given point that is within the rectangle bounds.\n     */\n    Point closestPoint(const Point& toPoint) const;\n\n    /**\n     Returns a new rect with outward rounding to ensure all fractional pixels are included.\n     This is useful for damage rect calculations where missing sub-pixels can cause artifacts.\n     */\n    Rect makeOutset() const {\n        return Rect::makeLTRB(std::floor(left), std::floor(top), std::ceil(right), std::ceil(bottom));\n    }\n};\n\nstd::ostream& operator<<(std::ostream& os, const Vector& vec);\nstd::ostream& operator<<(std::ostream& os, const Size& size);\nstd::ostream& operator<<(std::ostream& os, const Point& point);\nstd::ostream& operator<<(std::ostream& os, const Rect& rect);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/GradientWrapper.cpp",
    "content": "#include \"snap_drawing/cpp/Utils/GradientWrapper.hpp\"\n\nnamespace snap::drawing {\n\nGradientWrapper::GradientWrapper() = default;\n\nvoid GradientWrapper::update(const Rect& bounds) {\n    if (_linearGradient != nullptr) {\n        _linearGradient->update(bounds);\n    } else if (_radialGradient != nullptr) {\n        _radialGradient->update(bounds);\n    }\n}\n\nvoid GradientWrapper::applyToPaint(Paint& paint) const {\n    if (_linearGradient != nullptr) {\n        _linearGradient->applyToPaint(paint);\n    } else if (_radialGradient != nullptr) {\n        _radialGradient->applyToPaint(paint);\n    }\n}\n\nvoid GradientWrapper::draw(DrawingContext& drawingContext, const BorderRadius& borderRadius) {\n    if (_linearGradient != nullptr) {\n        _linearGradient->draw(drawingContext, borderRadius);\n    } else if (_radialGradient != nullptr) {\n        _radialGradient->draw(drawingContext, borderRadius);\n    }\n}\n\nvoid GradientWrapper::setAsLinear(std::vector<Scalar>&& locations,\n                                  std::vector<Color>&& colors,\n                                  LinearGradientOrientation orientation) {\n    if (_radialGradient != nullptr) {\n        _radialGradient = nullptr;\n    }\n\n    if (_linearGradient == nullptr) {\n        _linearGradient = Valdi::makeShared<LinearGradient>();\n    }\n\n    _linearGradient->setLocations(std::move(locations));\n    _linearGradient->setColors(std::move(colors));\n    _linearGradient->setOrientation(orientation);\n}\n\nRef<LinearGradient> GradientWrapper::getLinearGradient() {\n    return _linearGradient;\n}\n\nvoid GradientWrapper::setAsRadial(std::vector<Scalar>&& locations, std::vector<Color>&& colors) {\n    if (_linearGradient != nullptr) {\n        _linearGradient = nullptr;\n    }\n\n    if (_radialGradient == nullptr) {\n        _radialGradient = Valdi::makeShared<RadialGradient>();\n    }\n\n    _radialGradient->setLocations(std::move(locations));\n    _radialGradient->setColors(std::move(colors));\n}\n\nRef<RadialGradient> GradientWrapper::getRadialGradient() {\n    return _radialGradient;\n}\n\nvoid GradientWrapper::clear() {\n    _linearGradient = nullptr;\n    _radialGradient = nullptr;\n}\n\n// Returns a boolean value indicating whether there was an existing gradient\n// of the given type that was cleared.\nbool GradientWrapper::clearIfNeeded(GradientType type) {\n    if (type == GradientType::LINEAR && _linearGradient != nullptr) {\n        _linearGradient = nullptr;\n        return true;\n    } else if (type == GradientType::RADIAL && _radialGradient != nullptr) {\n        _radialGradient = nullptr;\n        return true;\n    }\n\n    return false;\n}\n\nbool GradientWrapper::isDirty() {\n    if (_linearGradient != nullptr) {\n        return _linearGradient->isDirty();\n    } else if (_radialGradient != nullptr) {\n        return _radialGradient->isDirty();\n    }\n\n    return false;\n}\n\nbool GradientWrapper::hasGradient() {\n    return _linearGradient != nullptr || _radialGradient != nullptr;\n}\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/GradientWrapper.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/LinearGradient.hpp\"\n#include \"snap_drawing/cpp/Drawing/RadialGradient.hpp\"\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n\n#include <vector>\n\nnamespace snap::drawing {\n\nclass GradientWrapper {\npublic:\n    enum class GradientType { LINEAR, RADIAL };\n\n    GradientWrapper();\n\n    void update(const Rect& bounds);\n\n    void applyToPaint(Paint& paint) const;\n\n    void draw(DrawingContext& drawingContext, const BorderRadius& borderRadius);\n\n    void setAsLinear(std::vector<Scalar>&& locations,\n                     std::vector<Color>&& colors,\n                     LinearGradientOrientation orientation);\n    void setAsRadial(std::vector<Scalar>&& locations, std::vector<Color>&& colors);\n\n    void clear();\n    bool clearIfNeeded(GradientType type);\n\n    bool isDirty();\n    bool hasGradient();\n\n    Ref<LinearGradient> getLinearGradient();\n    Ref<RadialGradient> getRadialGradient();\n\nprivate:\n    Ref<LinearGradient> _linearGradient;\n    Ref<RadialGradient> _radialGradient;\n};\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Image.cpp",
    "content": "//\n//  Image.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/7/20.\n//\n\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n#include \"snap_drawing/cpp/Utils/BytesUtils.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Bitmap.hpp\"\n\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n#include \"valdi_core/cpp/Utils/ValueTypedArray.hpp\"\n\n#include \"snap_drawing/cpp/Utils/BitmapUtils.hpp\"\n\n#include \"include/codec/SkEncodedImageFormat.h\"\n#include \"include/codec/SkJpegDecoder.h\"\n#include \"include/codec/SkPngDecoder.h\"\n#include \"include/codec/SkWebpDecoder.h\"\n#include \"include/core/SkStream.h\"\n#include \"include/encode/SkJpegEncoder.h\"\n#include \"include/encode/SkPngEncoder.h\"\n#include \"include/encode/SkWebpEncoder.h\"\n#include \"src/image/SkImage_Base.h\"\n\nnamespace snap::drawing {\n\nImage::Image(const sk_sp<SkImage>& skImage) : _skImage(skImage) {}\n\nImage::~Image() = default;\n\nvoid Image::initializeCodecs() {\n    static std::once_flag flag;\n    std::call_once(flag, [&]() {\n        SkCodecs::Register(SkJpegDecoder::Decoder());\n        SkCodecs::Register(SkPngDecoder::Decoder());\n        SkCodecs::Register(SkWebpDecoder::Decoder());\n    });\n}\n\nValdi::Value Image::getMetadata() const {\n    return Valdi::Value()\n        .setMapValue(\"type\", Valdi::Value(Valdi::StringBox::fromCString(\"image\")))\n        .setMapValue(\"width\", Valdi::Value(static_cast<int32_t>(_skImage->width())))\n        .setMapValue(\"height\", Valdi::Value(static_cast<int32_t>(_skImage->height())));\n}\n\nconst sk_sp<SkImage>& Image::getSkValue() const {\n    return _skImage;\n}\n\nint Image::width() const {\n    return _skImage->width();\n}\n\nint Image::height() const {\n    return _skImage->height();\n}\n\nValdi::Result<Valdi::BytesView> Image::toPNG() const {\n    return encode(EncodedImageFormatPNG, 1.0);\n}\n\nstatic bool encodeImage(SkWStream* dst, const SkPixmap& src, EncodedImageFormat format, int quality) {\n    switch (format) {\n        case EncodedImageFormatJPG: {\n            SkJpegEncoder::Options opts;\n            opts.fQuality = quality;\n            return SkJpegEncoder::Encode(dst, src, opts);\n        }\n        case EncodedImageFormatPNG: {\n            SkPngEncoder::Options opts;\n            return SkPngEncoder::Encode(dst, src, opts);\n        }\n        case EncodedImageFormatWebP: {\n            SkWebpEncoder::Options opts;\n            if (quality == 100) {\n                opts.fCompression = SkWebpEncoder::Compression::kLossless;\n                // Note: SkEncodeImage treats 0 quality as the lowest quality\n                // (greatest compression) and 100 as the highest quality (least\n                // compression). For kLossy, this matches libwebp's\n                // interpretation, so it is passed directly to libwebp. But\n                // with kLossless, libwebp always creates the highest quality\n                // image. In this case, fQuality is reinterpreted as how much\n                // effort (time) to put into making a smaller file. This API\n                // does not provide a way to specify this value (though it can\n                // be specified by using SkWebpEncoder::Encode) so we have to\n                // pick one arbitrarily. This value matches that chosen by\n                // blink::ImageEncoder::ComputeWebpOptions as well\n                // WebPConfigInit.\n                opts.fQuality = 75;\n            } else {\n                opts.fCompression = SkWebpEncoder::Compression::kLossy;\n                opts.fQuality = quality;\n            }\n            return SkWebpEncoder::Encode(dst, src, opts);\n        }\n    }\n}\n\nsk_sp<SkData> Image::encodeSKImageToSKData(SkImage& image, EncodedImageFormat format, int quality) {\n    Image::initializeCodecs();\n    SkBitmap bm;\n    if (!as_IB(&image)->getROPixels(nullptr, &bm)) {\n        return nullptr;\n    }\n\n    SkPixmap pixmap;\n    if (!bm.peekPixels(&pixmap)) {\n        return nullptr;\n    }\n\n    SkDynamicMemoryWStream stream;\n    if (!encodeImage(&stream, pixmap, format, quality)) {\n        return nullptr;\n    }\n    return stream.detachAsData();\n}\n\nValdi::Result<Valdi::BytesView> Image::encode(EncodedImageFormat format, double qualityRatio) const {\n    auto quality = static_cast<int>(round(100.0 * qualityRatio));\n\n    auto encoded = Image::encodeSKImageToSKData(*_skImage, format, quality);\n    if (encoded == nullptr) {\n        return Valdi::Error(\"Cannot encode image\");\n    }\n\n    return bytesFromSkData(encoded);\n}\n\nRef<Image> Image::resized(int width, int height) const {\n    SkBitmap bitmap;\n\n    SkImageInfo imageInfo = SkImageInfo::Make(width, height, _skImage->colorType(), _skImage->alphaType());\n    bitmap.allocPixels(imageInfo, imageInfo.minRowBytes());\n\n    _skImage->scalePixels(bitmap.pixmap(), SkSamplingOptions(SkCubicResampler::Mitchell()));\n\n    bitmap.setImmutable();\n\n    auto skImage = SkImages::RasterFromBitmap(bitmap);\n    return Ref<Image>(Valdi::makeShared<Image>(skImage));\n}\n\nvoid Image::draw(const Valdi::BitmapInfo& bitmapInfo, void* bytes) {\n    SkPixmap pixmap(toSkiaImageInfo(bitmapInfo), bytes, bitmapInfo.rowBytes);\n    _skImage->scalePixels(pixmap, SkSamplingOptions(SkCubicResampler::Mitchell()));\n}\n\nRef<Image> Image::withFilter(const Ref<Valdi::ImageFilter>& filter) {\n    auto copiedImage = Valdi::makeShared<Image>(_skImage);\n    copiedImage->_filter = filter;\n    copiedImage->_sourceImage = Valdi::strongSmallRef(this);\n    return copiedImage;\n}\n\nconst Ref<Valdi::ImageFilter>& Image::getFilter() const {\n    return _filter;\n}\n\nValdi::Result<Ref<Image>> Image::make(const Valdi::BytesView& data) {\n    Image::initializeCodecs();\n    auto skData = skDataFromBytes(data, DataConversionModeNeverCopy);\n\n    auto skImage = SkImages::DeferredFromEncodedData(skData);\n\n    if (skImage == nullptr) {\n        return Valdi::Error(\"Unable to decode image\");\n    }\n\n    return Ref<Image>(Valdi::makeShared<Image>(skImage));\n}\n\nValdi::Result<Ref<Image>> Image::makeFromPixelsData(const Valdi::BitmapInfo& bitmapInfo,\n                                                    const Valdi::BytesView& pixelsData,\n                                                    bool shouldCopy) {\n    return makeFromPixelsData(\n        bitmapInfo,\n        skDataFromBytes(pixelsData, shouldCopy ? DataConversionModeAlwaysCopy : DataConversionModeNeverCopy));\n}\n\nValdi::Result<Ref<Image>> Image::makeFromPixelsData(const Valdi::BitmapInfo& bitmapInfo,\n                                                    const sk_sp<SkData>& pixelsData) {\n    auto imageInfo = snap::drawing::toSkiaImageInfo(bitmapInfo);\n\n    auto skImage = SkImages::RasterFromData(imageInfo, pixelsData, bitmapInfo.rowBytes);\n\n    if (skImage == nullptr) {\n        return Valdi::Error(\"Unable to create image\");\n    }\n\n    return Ref<Image>(Valdi::makeShared<Image>(skImage));\n}\n\nValdi::Result<Ref<Image>> Image::makeFromBitmap(const Valdi::Ref<Valdi::IBitmap>& bitmap, bool shouldCopy) {\n    auto info = bitmap->getInfo();\n\n    auto data = bitmapToData(bitmap, info, shouldCopy);\n    if (!data) {\n        return data.moveError();\n    }\n\n    return makeFromPixelsData(info, data.value());\n}\n\nValdi::Ref<Valdi::IBitmap> Image::getBitmap() {\n    auto imageInfo = _skImage->imageInfo();\n    if (imageInfo.colorType() == kUnknown_SkColorType) {\n        return nullptr;\n    }\n\n    SkBitmap bitmap;\n    bitmap.allocPixels(_skImage->imageInfo(), imageInfo.minRowBytes());\n    auto pixmap = bitmap.pixmap();\n    _skImage->readPixels(imageInfo, pixmap.writable_addr(), imageInfo.minRowBytes(), 0, 0);\n\n    return Valdi::makeShared<snap::drawing::Bitmap>(std::move(bitmap));\n}\n\nVALDI_CLASS_IMPL(Image)\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Image.hpp",
    "content": "//\n//  Image.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 7/7/20.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Attributes/ImageFilter.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n#include \"valdi_core/cpp/Resources/LoadedAsset.hpp\"\n#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include \"valdi_core/cpp/Utils/ValdiObject.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n\n#include \"include/core/SkImage.h\"\n\nnamespace snap::drawing {\n\nenum EncodedImageFormat { EncodedImageFormatJPG, EncodedImageFormatPNG, EncodedImageFormatWebP };\n\nclass Image : public Valdi::LoadedAsset {\npublic:\n    explicit Image(const sk_sp<SkImage>& skImage);\n\n    ~Image() override;\n\n    int width() const;\n    int height() const;\n\n    Valdi::Value getMetadata() const override;\n\n    static void initializeCodecs();\n\n    /**\n     Resize the image to the given width/height.\n     This will read the entire bitmap of the Image and scale it\n     in software, this is an expensive operation.\n     */\n    Ref<Image> resized(int width, int height) const;\n\n    /**\n     Draw the image into the given bytes buffer conforming to the given bitmap info,\n     scaling pixels if necessary.\n     */\n    void draw(const Valdi::BitmapInfo& bitmapInfo, void* bytes);\n\n    /**\n     Returns a new Image which will be displayed with the given filter when drawn\n     */\n    Ref<Image> withFilter(const Ref<Valdi::ImageFilter>& filter);\n\n    const Ref<Valdi::ImageFilter>& getFilter() const;\n\n    Valdi::Result<Valdi::BytesView> toPNG() const;\n\n    Valdi::Result<Valdi::BytesView> encode(EncodedImageFormat format, double qualityRatio) const;\n\n    const sk_sp<SkImage>& getSkValue() const;\n\n    Valdi::Ref<Valdi::IBitmap> getBitmap();\n\n    /**\n     Make an Image from bytes representing an encoded image, like in PNG or JPG format.\n     */\n    static Valdi::Result<Ref<Image>> make(const Valdi::BytesView& data);\n\n    /**\n     Make an Image with the raw pixels data in the format specified in the BitmapInfo.\n     If shouldCopy is false, the returned Image will use the bytes from the attached BytesView\n     and it will retain its source if it has one.\n     Otherwise, the bytes will be copied.\n     */\n    static Valdi::Result<Ref<Image>> makeFromPixelsData(const Valdi::BitmapInfo& bitmapInfo,\n                                                        const Valdi::BytesView& pixelsData,\n                                                        bool shouldCopy);\n\n    /**\n     Make an Image with the raw pixels data provided from the given Bitmap.\n     If shouldCopy is false, the returned Image will retain the Bitmap and use its underlying\n     buffer directly. Otherwise, the bytes will be copied.\n     */\n    static Valdi::Result<Ref<Image>> makeFromBitmap(const Valdi::Ref<Valdi::IBitmap>& bitmap, bool shouldCopy);\n\n    static sk_sp<SkData> encodeSKImageToSKData(SkImage& image, EncodedImageFormat format, int quality);\n\n    VALDI_CLASS_HEADER(Image)\n\nprivate:\n    sk_sp<SkImage> _skImage;\n    Ref<Image> _sourceImage;\n    Ref<Valdi::ImageFilter> _filter;\n\n    static Valdi::Result<Ref<Image>> makeFromPixelsData(const Valdi::BitmapInfo& bitmapInfo,\n                                                        const sk_sp<SkData>& pixelsData);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/ImageQueue.cpp",
    "content": "//\n//  ImageQueue.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 6/16/22.\n//\n\n#include \"snap_drawing/cpp/Utils/ImageQueue.hpp\"\n#include \"snap_drawing/cpp/Utils/Bitmap.hpp\"\n\nnamespace snap::drawing {\n\nPooledBitmap::PooledBitmap(ImageQueue* queue, Ref<Valdi::IBitmap> sourceBitmap)\n    : _queue(Valdi::weakRef(queue)), _sourceBitmap(std::move(sourceBitmap)) {}\n\nPooledBitmap::~PooledBitmap() {\n    doDispose();\n}\n\nvoid PooledBitmap::doDispose() {\n    auto queue = _queue.lock();\n    if (queue != nullptr && _sourceBitmap != nullptr) {\n        queue->enqueueCachedBitmap(_sourceBitmap);\n        _sourceBitmap = nullptr;\n    }\n}\n\nvoid PooledBitmap::dispose() {\n    doDispose();\n}\n\nValdi::BitmapInfo PooledBitmap::getInfo() const {\n    return _sourceBitmap->getInfo();\n}\n\nvoid* PooledBitmap::lockBytes() {\n    return _sourceBitmap->lockBytes();\n}\n\nvoid PooledBitmap::unlockBytes() {\n    _sourceBitmap->unlockBytes();\n}\n\nImageQueue::ImageQueue(size_t maxQueueSize) : _maxQueueSize(maxQueueSize) {}\n\nImageQueue::~ImageQueue() = default;\n\nvoid ImageQueue::enqueue(const Ref<Image>& image) {\n    std::unique_lock<Valdi::Mutex> lock(_mutex);\n    _queue.emplace_back(image);\n    if (_maxQueueSize != 0) {\n        clearQueueUpToSize(_maxQueueSize, lock);\n    }\n}\n\nvoid ImageQueue::clear() {\n    std::unique_lock<Valdi::Mutex> lock(_mutex);\n    clearQueueUpToSize(0, lock);\n}\n\nstd::optional<Ref<Image>> ImageQueue::dequeue() {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    if (_queue.empty()) {\n        return std::nullopt;\n    }\n\n    auto image = std::move(_queue.front());\n    _queue.pop_front();\n\n    return {std::move(image)};\n}\n\nvoid ImageQueue::clearQueueUpToSize(size_t maxSize, std::unique_lock<Valdi::Mutex>& lock) {\n    while (_queue.size() > maxSize) {\n        auto image = std::move(_queue.front());\n        _queue.pop_front();\n\n        lock.unlock();\n        image = nullptr;\n        lock.lock();\n    }\n}\n\nbool ImageQueue::isCacheCompatibleWithBitmapInfo(const Valdi::BitmapInfo& bitmapInfo) const {\n    if (!_cacheBitmapInfo) {\n        return false;\n    }\n\n    return _cacheBitmapInfo->width == bitmapInfo.width && _cacheBitmapInfo->height == bitmapInfo.height &&\n           _cacheBitmapInfo->colorType == bitmapInfo.colorType;\n}\n\nValdi::Result<Ref<Valdi::IBitmap>> ImageQueue::allocateBitmap(int width, int height, Valdi::ColorType colorType) {\n    auto bitmapInfo = Valdi::BitmapInfo(width, height, colorType, Valdi::AlphaType::AlphaTypePremul, 0);\n\n    {\n        std::lock_guard<Valdi::Mutex> lock(_mutex);\n        if (!isCacheCompatibleWithBitmapInfo(bitmapInfo)) {\n            _cacheBitmapInfo = {bitmapInfo};\n            _cachedBitmaps.clear();\n        }\n\n        if (!_cachedBitmaps.empty()) {\n            auto cachedBitmap = std::move(_cachedBitmaps.back());\n            _cachedBitmaps.pop_back();\n\n            Ref<Valdi::IBitmap> pooledBitmap = Valdi::makeShared<PooledBitmap>(this, std::move(cachedBitmap));\n            return pooledBitmap;\n        }\n    }\n\n    // Cache is empty, allocating the bitmap\n\n    auto bitmap = Bitmap::make(bitmapInfo);\n    if (!bitmap) {\n        return bitmap.moveError();\n    }\n\n    Ref<Valdi::IBitmap> pooledBitmap = Valdi::makeShared<PooledBitmap>(this, bitmap.moveValue());\n    return pooledBitmap;\n}\n\nvoid ImageQueue::enqueueCachedBitmap(const Ref<Valdi::IBitmap>& sourceBitmap) {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    auto bitmapInfo = sourceBitmap->getInfo();\n    if (!isCacheCompatibleWithBitmapInfo(bitmapInfo) || _cachedBitmaps.size() >= kImageQueueMaxPoolSize) {\n        return;\n    }\n    _cachedBitmaps.emplace_back(sourceBitmap);\n}\n\nsize_t ImageQueue::getQueueSize() const {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    return _queue.size();\n}\n\nsize_t ImageQueue::getPoolSize() const {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    return _cachedBitmaps.size();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/ImageQueue.hpp",
    "content": "//\n//  ImageQueue.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 6/16/22.\n//\n\n#pragma once\n\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n#include \"valdi_core/cpp/Utils/Shared.hpp\"\n\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n\n#include <deque>\n#include <optional>\n\nnamespace snap::drawing {\n\nclass ImageQueue;\n\nclass PooledBitmap : public Valdi::IBitmap {\npublic:\n    PooledBitmap(ImageQueue* queue, Ref<Valdi::IBitmap> sourceBitmap);\n    ~PooledBitmap() override;\n\n    void dispose() override;\n    Valdi::BitmapInfo getInfo() const override;\n    void* lockBytes() override;\n    void unlockBytes() override;\n\nprivate:\n    Valdi::Weak<ImageQueue> _queue;\n    Ref<Valdi::IBitmap> _sourceBitmap;\n\n    void doDispose();\n};\n\nconstexpr size_t kImageQueueMaxPoolSize = 3;\n\nclass ImageQueue : public Valdi::SharedPtrRefCountable {\npublic:\n    explicit ImageQueue(size_t maxQueueSize);\n    ~ImageQueue() override;\n\n    void enqueue(const Ref<Image>& image);\n    void clear();\n\n    std::optional<Ref<Image>> dequeue();\n\n    Valdi::Result<Ref<Valdi::IBitmap>> allocateBitmap(int width, int height, Valdi::ColorType colorType);\n\n    size_t getQueueSize() const;\n    size_t getPoolSize() const;\n\nprivate:\n    mutable Valdi::Mutex _mutex;\n    std::deque<Ref<Image>> _queue;\n    std::vector<Ref<Valdi::IBitmap>> _cachedBitmaps;\n    std::optional<Valdi::BitmapInfo> _cacheBitmapInfo;\n    size_t _maxQueueSize;\n\n    friend PooledBitmap;\n\n    void enqueueCachedBitmap(const Ref<Valdi::IBitmap>& sourceBitmap);\n    void clearQueueUpToSize(size_t maxSize, std::unique_lock<Valdi::Mutex>& lock);\n\n    bool isCacheCompatibleWithBitmapInfo(const Valdi::BitmapInfo& bitmapInfo) const;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/JSONUtils.cpp",
    "content": "//\n//  JSONUtils.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/10/22.\n//\n\n#include \"snap_drawing/cpp/Utils/JSONUtils.hpp\"\n\nnamespace snap::drawing {\n\nconstexpr double kJSONPrecision = 1000;\n\nstatic Valdi::Value toJSONValue(Scalar value) {\n    return Valdi::Value(round(static_cast<double>(value) * kJSONPrecision) / kJSONPrecision);\n}\n\nValdi::Value toJSONValue(const Rect& rect) {\n    return Valdi::Value()\n        .setMapValue(\"x\", toJSONValue(rect.x()))\n        .setMapValue(\"y\", toJSONValue(rect.y()))\n        .setMapValue(\"width\", toJSONValue(rect.width()))\n        .setMapValue(\"height\", toJSONValue(rect.height()));\n}\n\nValdi::Value toJSONValue(const Size& size) {\n    return Valdi::Value().setMapValue(\"width\", toJSONValue(size.width)).setMapValue(\"height\", toJSONValue(size.height));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/JSONUtils.hpp",
    "content": "//\n//  JSONUtils.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/10/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"valdi_core/cpp/Utils/Value.hpp\"\n\nnamespace snap::drawing {\n\nValdi::Value toJSONValue(const Rect& rect);\nValdi::Value toJSONValue(const Size& size);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/LazyPath.cpp",
    "content": "//\n//  LazyPath.cpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 9/21/20.\n//\n\n#include \"snap_drawing/cpp/Utils/LazyPath.hpp\"\n\nnamespace snap::drawing {\n\nLazyPath::LazyPath() = default;\n\nLazyPath::~LazyPath() = default;\n\nvoid LazyPath::setNeedsUpdate() {\n    _size = Size();\n}\n\nbool LazyPath::update(const Size& size) {\n    if (size == _size) {\n        return false;\n    }\n    _size = size;\n    _path = Path();\n    return true;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/LazyPath.hpp",
    "content": "//\n//  LazyPath.hpp\n//  valdi-desktop-apple\n//\n//  Created by Simon Corsin on 9/21/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n\nnamespace snap::drawing {\n\n/**\n LazyPath offers a simple caching mecanism to avoid\n recreating Path on every draw. It assumes that the\n Path will only need be to be recreated if the size changes.\n */\nclass LazyPath {\npublic:\n    LazyPath();\n    ~LazyPath();\n\n    constexpr bool update(Scalar width, Scalar height) {\n        return update(Size::make(width, height));\n    }\n\n    void setNeedsUpdate();\n\n    bool update(const Size& size);\n\n    constexpr Path& path() {\n        return _path;\n    }\n\nprivate:\n    Path _path;\n    Size _size = Size::makeEmpty();\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/LottieAnimatedImage.cpp",
    "content": "//\n//  LottieAnimatedImage.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 7/22/22.\n//\n\n#include \"snap_drawing/cpp/Utils/LottieAnimatedImage.hpp\"\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.hpp\"\n#include \"snap_drawing/cpp/Resources.hpp\"\n#include \"snap_drawing/cpp/Utils/AnimatedImage.hpp\"\n\nnamespace skresources {\nclass DelegatedTypefaceResourceProvider : public ResourceProvider {\npublic:\n    using DelegateFn = std::function<sk_sp<SkTypeface>(const char*, const char*)>;\n\n    static sk_sp<DelegatedTypefaceResourceProvider> Make(DelegateFn delegateFn);\n\n    sk_sp<SkTypeface> loadTypeface(const char* name, const char* url) const override;\n\nprivate:\n    explicit DelegatedTypefaceResourceProvider(DelegateFn delegateFn);\n\n    DelegateFn _delegate;\n};\n\nDelegatedTypefaceResourceProvider::DelegatedTypefaceResourceProvider(DelegateFn delegateFn)\n    : _delegate(std::move(delegateFn)) {}\n\nsk_sp<DelegatedTypefaceResourceProvider> DelegatedTypefaceResourceProvider::Make(DelegateFn delegateFn) {\n    return sk_sp<DelegatedTypefaceResourceProvider>(new DelegatedTypefaceResourceProvider(std::move(delegateFn)));\n}\n\nsk_sp<SkTypeface> DelegatedTypefaceResourceProvider::loadTypeface(const char* name, const char* url) const {\n    return _delegate(name, url);\n}\n} // namespace skresources\n\nnamespace snap::drawing {\n\nLottieAnimatedImage::~LottieAnimatedImage() = default;\n\nconst Duration& LottieAnimatedImage::getDuration() const {\n    return _duration;\n}\n\nDuration LottieAnimatedImage::getCurrentTime() const {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    return _currentTime;\n}\n\nconst Size& LottieAnimatedImage::getSize() const {\n    return _size;\n}\n\ndouble LottieAnimatedImage::getFrameRate() const {\n    return _frameRate;\n}\n\nValdi::Value LottieAnimatedImage::getMetadata() const {\n    return Valdi::Value()\n        .setMapValue(\"type\", Valdi::Value(Valdi::StringBox::fromCString(\"lottie\")))\n        .setMapValue(\"width\", Valdi::Value(static_cast<int32_t>(_size.width)))\n        .setMapValue(\"height\", Valdi::Value(static_cast<int32_t>(_size.height)))\n        .setMapValue(\"durationMs\", Valdi::Value(static_cast<int32_t>(_duration.milliseconds())));\n}\n\nValdi::Result<Ref<LottieAnimatedImage>> LottieAnimatedImage::make(const Ref<Resources>& resources,\n                                                                  const Valdi::Byte* data,\n                                                                  size_t length) {\n    return make(resources->getFontManager(), data, length);\n}\n\n#ifdef SNAP_DRAWING_LOTTIE_ENABLED\n\nLottieAnimatedImage::LottieAnimatedImage(const sk_sp<skottie::Animation>& animation)\n    : _animation(animation),\n      _duration(Duration::fromSeconds(animation->duration())),\n      _size(Size(animation->size().width(), animation->size().height())),\n      _frameRate(animation->fps()) {}\n\nvoid LottieAnimatedImage::doDraw(SkCanvas* canvas,\n                                 const Rect& drawBounds,\n                                 const Duration& time,\n                                 FittingSizeMode fittingSizeMode) {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    _currentTime = std::clamp(time, Duration(), _duration);\n    _animation->seekFrameTime(_currentTime.seconds());\n\n    // If fittingSizeMode is fill need to apply transform since\n    // Skottie does not render with 'fill' mode by default\n    if (fittingSizeMode == FittingSizeModeFill) {\n        Scalar scaleX = drawBounds.width() / _size.width;\n        Scalar scaleY = drawBounds.height() / _size.height;\n        auto fillMatrix = Matrix::makeScaleTranslate(scaleX, scaleY, 0, 0);\n        canvas->concat(fillMatrix.getSkValue());\n\n        // nullptr passed as bounds to prevent scaling being applied twice\n        _animation->render(canvas, nullptr, 0);\n    } else {\n        _animation->render(canvas, &drawBounds.getSkValue(), 0);\n    }\n}\n\nstatic sk_sp<SkTypeface> loadTypeface(const Ref<IFontManager>& fontManager, const char* name, const char* /*url*/) {\n    if (name == nullptr) {\n        return nullptr;\n    }\n\n    auto typeface =\n        fontManager->getTypefaceWithName(Valdi::StringCache::getGlobal().makeString(std::string_view(name)));\n    if (typeface) {\n        return typeface.value()->getSkValue();\n    }\n\n    return nullptr;\n}\nValdi::Result<Ref<LottieAnimatedImage>> LottieAnimatedImage::make(const Ref<IFontManager>& fontManager,\n                                                                  const Valdi::Byte* data,\n                                                                  size_t length) {\n    auto resourceProvider = skresources::CachingResourceProvider::Make(\n        skresources::DataURIResourceProviderProxy::Make(skresources::DelegatedTypefaceResourceProvider::Make(\n            [fontManager](const char* name, const char* url) { return loadTypeface(fontManager, name, url); })));\n\n    auto animation = skottie::Animation::Builder()\n                         .setResourceProvider(std::move(resourceProvider))\n                         .make(reinterpret_cast<const char*>(data), length);\n    if (!animation) {\n        return Valdi::Error(\"Failed to parse animation\");\n    }\n\n    return Valdi::makeShared<LottieAnimatedImage>(animation);\n}\n\n#else\n\nValdi::Result<Ref<LottieAnimatedImage>> LottieAnimatedImage::make(const Ref<IFontManager>& /*fontManager*/,\n                                                                  const Valdi::Byte* /*data*/,\n                                                                  size_t /*length*/) {\n    return Valdi::Error(\"Lottie was not enabled in the build\");\n}\n\n#endif\n\nVALDI_CLASS_IMPL(LottieAnimatedImage)\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/LottieAnimatedImage.hpp",
    "content": "//\n//  LottieScene.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 7/22/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/AnimatedImage.hpp\"\n#include \"snap_drawing/cpp/Utils/Duration.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"valdi_core/cpp/Resources/LoadedAsset.hpp\"\n\n#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include \"modules/skottie/include/Skottie.h\"\n\nnamespace snap::drawing {\n\nclass Resources;\nclass DrawingContext;\nclass IFontManager;\n\nclass LottieAnimatedImage : public AnimatedImage {\npublic:\n    explicit LottieAnimatedImage(const sk_sp<skottie::Animation>& animation);\n    ~LottieAnimatedImage() override;\n\n    Duration getCurrentTime() const override;\n    const Duration& getDuration() const override;\n    const Size& getSize() const override;\n    double getFrameRate() const override;\n    Valdi::Value getMetadata() const override;\n\n    static Valdi::Result<Ref<LottieAnimatedImage>> make(const Ref<Resources>& resources,\n                                                        const Valdi::Byte* data,\n                                                        size_t length);\n\n    static Valdi::Result<Ref<LottieAnimatedImage>> make(const Ref<IFontManager>& fontManager,\n                                                        const Valdi::Byte* data,\n                                                        size_t length);\n\n    VALDI_CLASS_HEADER(LottieAnimatedImage)\n\nprotected:\n    void doDraw(SkCanvas* canvas,\n                const Rect& drawBounds,\n                const Duration& time,\n                FittingSizeMode fittingSizeMode) override;\n\nprivate:\n    mutable Valdi::Mutex _mutex;\n#ifdef SNAP_DRAWING_LOTTIE_ENABLED\n    sk_sp<skottie::Animation> _animation;\n#endif\n    Duration _duration;\n    Duration _currentTime;\n    Size _size;\n    double _frameRate;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Matrix.cpp",
    "content": "//\n//  Matrix.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n#include <fmt/format.h>\n\nnamespace snap::drawing {\n\nvoid Matrix::setIdentity() {\n    getSkValue().setIdentity();\n}\n\nScalar Matrix::getTranslateX() const {\n    return getSkValue().getTranslateX();\n}\n\nvoid Matrix::setTranslateX(Scalar translateX) {\n    getSkValue().setTranslateX(translateX);\n}\n\nScalar Matrix::getTranslateY() const {\n    return getSkValue().getTranslateY();\n}\n\nvoid Matrix::setTranslateY(Scalar translateY) {\n    getSkValue().setTranslateY(translateY);\n}\n\nScalar Matrix::getScaleX() const {\n    return getSkValue().getScaleX();\n}\n\nvoid Matrix::setScaleX(Scalar scaleX) {\n    getSkValue().setScaleX(scaleX);\n}\n\nScalar Matrix::getScaleY() const {\n    return getSkValue().getScaleY();\n}\n\nvoid Matrix::setScaleY(Scalar scaleY) {\n    getSkValue().setScaleY(scaleY);\n}\n\nScalar Matrix::getSkewX() const {\n    return getSkValue().getSkewX();\n}\n\nvoid Matrix::setSkewX(Scalar skewX) {\n    getSkValue().setSkewX(skewX);\n}\n\nScalar Matrix::getSkewY() const {\n    return getSkValue().getSkewY();\n}\n\nvoid Matrix::setSkewY(Scalar skewY) {\n    getSkValue().setSkewY(skewY);\n}\n\nvoid Matrix::postRotate(Scalar radians, Scalar px, Scalar py) {\n    postRotateDegrees(SkRadiansToDegrees(radians), px, py);\n}\n\nvoid Matrix::postRotateDegrees(Scalar degrees, Scalar px, Scalar py) {\n    getSkValue().postRotate(degrees, px, py);\n}\n\nvoid Matrix::preConcat(const Matrix& other) {\n    getSkValue().preConcat(other.getSkValue());\n}\n\nvoid Matrix::postConcat(const Matrix& other) {\n    getSkValue().postConcat(other.getSkValue());\n}\n\nvoid Matrix::preScale(Scalar sx, Scalar sy) {\n    getSkValue().preScale(sx, sy);\n}\n\nvoid Matrix::postScale(Scalar sx, Scalar sy) {\n    getSkValue().postScale(sx, sy);\n}\n\nRect Matrix::mapRect(const Rect& rect) const {\n    return fromSkValue<Rect>(getSkValue().mapRect(rect.getSkValue()));\n}\n\nbool Matrix::isIdentity() const {\n    return getSkValue().isIdentity();\n}\n\nbool Matrix::isIdentityOrTranslate() const {\n    return getSkValue().isTranslate();\n}\n\nMatrix Matrix::makeScaleTranslate(Scalar sx, Scalar sy, Scalar tx, Scalar ty) {\n    Matrix matrix;\n    matrix.getSkValue().setScaleTranslate(sx, sy, tx, ty);\n    return matrix;\n}\n\nMatrix Matrix::makeScale(Scalar sx, Scalar sy) {\n    Matrix matrix;\n    matrix.getSkValue().setScale(sx, sy);\n    return matrix;\n}\n\nbool Matrix::operator==(const Matrix& other) const {\n    return getSkValue() == other.getSkValue();\n}\n\nbool Matrix::operator!=(const Matrix& other) const {\n    return getSkValue() != other.getSkValue();\n}\n\nbool Matrix::toAffine(Scalar* affineValues) const {\n    const auto& mat = getSkValue();\n\n    return mat.asAffine(reinterpret_cast<SkScalar*>(affineValues));\n}\n\nvoid Matrix::getAll(Scalar* values) const {\n    getSkValue().get9(reinterpret_cast<SkScalar*>(values));\n}\n\nstd::string Matrix::toString() const {\n    const auto& skMatrix = getSkValue();\n    return fmt::format(\"[{}, {}, {}, {}, {}, {}, {}, {}, {}]\",\n                       skMatrix.get(0),\n                       skMatrix.get(1),\n                       skMatrix.get(2),\n                       skMatrix.get(3),\n                       skMatrix.get(4),\n                       skMatrix.get(5),\n                       skMatrix.get(6),\n                       skMatrix.get(7),\n                       skMatrix.get(8));\n}\n\nstd::ostream& operator<<(std::ostream& os, const Matrix& matrix) {\n    return os << matrix.toString();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Matrix.hpp",
    "content": "//\n//  Matrix.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/SkiaBridge.hpp\"\n\n#include \"include/core/SkMatrix.h\"\n\n#include <ostream>\n#include <string>\n\nnamespace snap::drawing {\n\nclass Matrix : public WrappedSkValue<SkMatrix> {\npublic:\n    void setIdentity();\n\n    Scalar getTranslateX() const;\n    void setTranslateX(Scalar translateX);\n\n    Scalar getTranslateY() const;\n    void setTranslateY(Scalar translateY);\n\n    Scalar getScaleX() const;\n    void setScaleX(Scalar scaleX);\n\n    Scalar getScaleY() const;\n    void setScaleY(Scalar scaleY);\n\n    Scalar getSkewX() const;\n    void setSkewX(Scalar skewX);\n\n    Scalar getSkewY() const;\n    void setSkewY(Scalar skewY);\n\n    void postRotate(Scalar radians, Scalar px, Scalar py);\n    void postRotateDegrees(Scalar degrees, Scalar px, Scalar py);\n\n    void preConcat(const Matrix& other);\n    void postConcat(const Matrix& other);\n\n    void preScale(Scalar sx, Scalar sy);\n    void postScale(Scalar sx, Scalar sy);\n\n    Rect mapRect(const Rect& rect) const;\n\n    /**\n     Append all the Matrix values into the given array.\n     The array must be of length 9.\n     */\n    void getAll(Scalar* values) const;\n\n    std::string toString() const;\n\n    bool isIdentity() const;\n\n    bool isIdentityOrTranslate() const;\n\n    /**\n     Given array must be of length 6\n     */\n    bool toAffine(Scalar* affineValues) const;\n\n    bool operator==(const Matrix& other) const;\n    bool operator!=(const Matrix& other) const;\n\n    static Matrix makeScaleTranslate(Scalar sx, Scalar sy, Scalar tx, Scalar ty);\n    static Matrix makeScale(Scalar sx, Scalar sy);\n};\n\nstd::ostream& operator<<(std::ostream& os, const Matrix& matrix);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Path.cpp",
    "content": "//\n//  Path.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n#include \"include/core/SkStream.h\"\n#include \"include/pathops/SkPathOps.h\"\n#include \"snap_drawing/cpp/Utils/Matrix.hpp\"\n\nnamespace snap::drawing {\n\nPath::Path() = default;\nPath::Path(Path&& other) noexcept : WrappedSkValue<SkPath>(std::move(other.getSkValue())) {}\n\nPath::Path(const Path& other) noexcept : WrappedSkValue<SkPath>(other.getSkValue()) {}\n\nPath::~Path() = default;\n\nstatic SkPathDirection getPathDirection(bool clockwise) {\n    return clockwise ? SkPathDirection::kCW : SkPathDirection::kCCW;\n}\n\nPath& Path::operator=(Path&& other) noexcept {\n    if (&other != this) {\n        getSkValue() = std::move(other.getSkValue());\n    }\n\n    return *this;\n}\n\nPath& Path::operator=(const Path& other) noexcept {\n    getSkValue() = other.getSkValue();\n    return *this;\n}\n\nbool Path::operator==(const Path& other) const {\n    return getSkValue() == other.getSkValue();\n}\n\nbool Path::operator!=(const Path& other) const {\n    return getSkValue() != other.getSkValue();\n}\n\nvoid Path::addRoundRect(const Rect& bounds, Scalar radii[8], bool clockwise) {\n    getSkValue().addRoundRect(bounds.getSkValue(), &radii[0], getPathDirection(clockwise));\n}\n\nvoid Path::addRoundRect(const Rect& bounds, Scalar rx, Scalar ry, bool clockwise) {\n    getSkValue().addRoundRect(bounds.getSkValue(), rx, ry, getPathDirection(clockwise));\n}\n\nbool Path::isEmpty() const {\n    return getSkValue().isEmpty();\n}\n\nvoid Path::reset() {\n    getSkValue().reset();\n}\n\nvoid Path::moveTo(Scalar x, Scalar y) {\n    getSkValue().moveTo(x, y);\n}\n\nvoid Path::lineTo(Scalar x, Scalar y) {\n    getSkValue().lineTo(x, y);\n}\n\nvoid Path::quadTo(Scalar x0, Scalar y0, Scalar x1, Scalar y1) {\n    getSkValue().quadTo(x0, y0, x1, y1);\n}\n\nvoid Path::conicTo(Scalar x0, Scalar y0, Scalar x1, Scalar y1, Scalar weight) {\n    getSkValue().conicTo(x0, y0, x1, y1, weight);\n}\n\nvoid Path::cubicTo(Scalar x0, Scalar y0, Scalar x1, Scalar y1, Scalar x2, Scalar y2) {\n    getSkValue().cubicTo(x0, y0, x1, y1, x2, y2);\n}\n\nvoid Path::close() {\n    getSkValue().close();\n}\n\nvoid Path::addRect(const Rect& bounds, bool clockwise) {\n    getSkValue().addRect(bounds.getSkValue(), getPathDirection(clockwise));\n}\n\nvoid Path::addOval(const Rect& bounds, bool clockwise) {\n    getSkValue().addOval(bounds.getSkValue(), getPathDirection(clockwise));\n}\n\nvoid Path::arcTo(const Rect& oval, Scalar startAngle, Scalar sweepAngle) {\n    getSkValue().addArc(oval.getSkValue(), startAngle, sweepAngle);\n}\n\nvoid Path::addPath(const Path& path) {\n    getSkValue().addPath(path.getSkValue());\n}\n\nvoid Path::transform(const Matrix& matrix) {\n    getSkValue().transform(matrix.getSkValue());\n}\n\nPath Path::intersection(const Path& other) const {\n    Path output;\n    Op(getSkValue(), other.getSkValue(), kIntersect_SkPathOp, &output.getSkValue());\n\n    output.getSkValue().setFillType(getSkValue().getFillType());\n    return output;\n}\n\nstd::optional<Rect> Path::getBounds() const {\n    if (isEmpty()) {\n        return std::nullopt;\n    }\n    return {fromSkValue<Rect>(getSkValue().getBounds())};\n}\n\nstd::string Path::toString() const {\n    SkDynamicMemoryWStream stream;\n    getSkValue().dump(&stream, true);\n\n    auto bytes = stream.bytesWritten();\n\n    std::string output;\n    output.resize(bytes);\n\n    stream.copyTo(output.data());\n\n    return output;\n}\n\nvoid Path::visit(PathVisitor& visitor) const {\n    SkPath::Iter it(getSkValue(), false);\n    SkPoint points[4];\n    SkPoint quads[5];\n\n    for (;;) {\n        auto verb = it.next(points);\n\n        switch (verb) {\n            case SkPath::kMove_Verb:\n                visitor.move(fromSkValue<Point>(points[0]));\n                break;\n            case SkPath::kLine_Verb:\n                visitor.line(fromSkValue<Point>(points[0]), fromSkValue<Point>(points[1]));\n                break;\n            case SkPath::kQuad_Verb:\n                visitor.quad(\n                    fromSkValue<Point>(points[0]), fromSkValue<Point>(points[1]), fromSkValue<Point>(points[2]));\n                break;\n            case SkPath::kConic_Verb: {\n                if (visitor.shouldConvertConicToQuad()) {\n                    SkPath::ConvertConicToQuads(points[0], points[1], points[2], it.conicWeight(), quads, 1);\n\n                    visitor.quad(\n                        fromSkValue<Point>(quads[0]), fromSkValue<Point>(quads[1]), fromSkValue<Point>(quads[2]));\n                    visitor.quad(\n                        fromSkValue<Point>(quads[2]), fromSkValue<Point>(quads[3]), fromSkValue<Point>(quads[4]));\n                } else {\n                    visitor.conic(fromSkValue<Point>(points[0]),\n                                  fromSkValue<Point>(points[1]),\n                                  fromSkValue<Point>(points[2]),\n                                  it.conicWeight());\n                }\n            } break;\n            case SkPath::kCubic_Verb:\n                visitor.cubic(fromSkValue<Point>(points[0]),\n                              fromSkValue<Point>(points[1]),\n                              fromSkValue<Point>(points[2]),\n                              fromSkValue<Point>(points[3]));\n                break;\n            case SkPath::kClose_Verb:\n                visitor.close();\n                break;\n            case SkPath::kDone_Verb:\n                return;\n        }\n    }\n}\n\nstd::ostream& operator<<(std::ostream& os, const Path& path) {\n    return os << path.toString();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Path.hpp",
    "content": "//\n//  Path.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/SkiaBridge.hpp\"\n\n#include \"include/core/SkPath.h\"\n\n#include <optional>\n#include <ostream>\n#include <string>\n\nnamespace snap::drawing {\n\nclass Matrix;\n\nclass PathVisitor;\n\nclass Path : public WrappedSkValue<SkPath> {\npublic:\n    Path();\n    Path(Path&& other) noexcept;\n    Path(const Path& other) noexcept;\n\n    ~Path();\n\n    Path& operator=(Path&& other) noexcept;\n    Path& operator=(const Path& other) noexcept;\n\n    void reset();\n\n    void addRoundRect(const Rect& bounds, Scalar radii[8], bool clockwise);\n\n    void addRoundRect(const Rect& bounds, Scalar rx, Scalar ry, bool clockwise);\n\n    /** Set the beginning of the next contour to the point (x,y). */\n    void moveTo(Scalar x, Scalar y);\n\n    /**\n    Add a line from the last point to the specified point (x,y). If no\n    sk_path_move_to() call has been made for this contour, the first\n    point is automatically set to (0,0).\n    */\n    void lineTo(Scalar x, Scalar y);\n\n    /**\n    Add a quadratic bezier from the last point, approaching control\n    point (x0,y0), and ending at (x1,y1). If no sk_path_move_to() call\n    has been made for this contour, the first point is automatically\n    set to (0,0).\n    */\n    void quadTo(Scalar x0, Scalar y0, Scalar x1, Scalar y1);\n\n    /**\n    Add a conic curve from the last point, approaching control point\n    (x0,y01), and ending at (x1,y1) with weight w.  If no\n    sk_path_move_to() call has been made for this contour, the first\n    point is automatically set to (0,0).\n    */\n    void conicTo(Scalar x0, Scalar y0, Scalar x1, Scalar y1, Scalar weight);\n\n    /**\n    Add a cubic bezier from the last point, approaching control points\n    (x0,y0) and (x1,y1), and ending at (x2,y2). If no\n    sk_path_move_to() call has been made for this contour, the first\n    point is automatically set to (0,0).\n    */\n    void cubicTo(Scalar x0, Scalar y0, Scalar x1, Scalar y1, Scalar x2, Scalar y2);\n\n    /** Appends arc to SkPath, as the start of new contour. Arc added is part of ellipse\n           bounded by oval, from startAngle through sweepAngle. Both startAngle and\n           sweepAngle are measured in degrees, where zero degrees is aligned with the\n           positive x-axis, and positive sweeps extends arc clockwise.\n\n           If sweepAngle <= -360, or sweepAngle >= 360; and startAngle modulo 90 is nearly\n           zero, append oval instead of arc. Otherwise, sweepAngle values are treated\n           modulo 360, and arc may or may not draw depending on numeric rounding.\n\n           @param oval        bounds of ellipse containing arc\n           @param startAngle  starting angle of arc in degrees\n           @param sweepAngle  sweep, in degrees. Positive is clockwise; treated modulo 360\n           @return            reference to SkPath\n\n           example: https://fiddle.skia.org/c/@Path_addArc\n       */\n    void arcTo(const Rect& oval, Scalar startAngle, Scalar sweepAngle);\n\n    /**\n    Close the current contour. If the current point is not equal to the\n    first point of the contour, a line segment is automatically added.\n    */\n    void close();\n\n    /**\n    Add a closed rectangle contour to the path.\n    */\n    void addRect(const Rect& bounds, bool clockwise);\n\n    /**\n    Add a closed oval contour to the path\n    */\n    void addOval(const Rect& bounds, bool clockwise);\n\n    void transform(const Matrix& matrix);\n\n    void addPath(const Path& path);\n\n    /**\n     *  If the path is empty, return false and set the rect parameter to [0, 0, 0, 0].\n     *  else return true and set the rect parameter to the bounds of the control-points\n     *  of the path.\n     */\n    std::optional<Rect> getBounds() const;\n\n    bool isEmpty() const;\n\n    std::string toString() const;\n\n    Path intersection(const Path& other) const;\n\n    void visit(PathVisitor& visitor) const;\n\n    bool operator==(const Path& other) const;\n    bool operator!=(const Path& other) const;\n};\n\nstd::ostream& operator<<(std::ostream& os, const Path& path);\n\nclass PathVisitor {\npublic:\n    virtual ~PathVisitor() = default;\n\n    virtual bool shouldConvertConicToQuad() const = 0;\n\n    virtual void move(const Point& point) = 0;\n    virtual void line(const Point& from, const Point& to) = 0;\n    virtual void quad(const Point& p1, const Point& p2, const Point& p3) = 0;\n    virtual void conic(const Point& p1, const Point& p2, const Point& p3, Scalar weight) = 0;\n    virtual void cubic(const Point& p1, const Point& p2, const Point& p3, const Point& p4) = 0;\n    virtual void close() = 0;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/PathInterpolator.cpp",
    "content": "//\n//  PathInterpolator.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 4/20/22.\n//\n\n#include \"snap_drawing/cpp/Utils/PathInterpolator.hpp\"\n\nnamespace snap::drawing {\n\nPathInterpolator::PathInterpolator(const Path& path) {\n    SkContourMeasureIter iter(path.getSkValue(), false);\n\n    sk_sp<SkContourMeasure> measure;\n    while ((measure = iter.next())) {\n        _totalLength += measure->length();\n        _contours.emplace_back(std::move(measure));\n    }\n}\n\nPathInterpolator::~PathInterpolator() = default;\n\nconst Path& PathInterpolator::interpolate(Scalar start, Scalar end) {\n    _interpolatedPath.reset();\n\n    auto absoluteStart = start * _totalLength;\n    auto absoluteEnd = end * _totalLength;\n\n    Scalar currentStart = 0;\n    for (const auto& contour : _contours) {\n        auto currentLength = contour->length();\n        auto currentEnd = currentStart + currentLength;\n\n        if (currentStart >= absoluteEnd) {\n            break;\n        }\n\n        auto relativeStart = std::min(std::max(absoluteStart - currentStart, 0.0f), currentLength);\n        auto relativeEnd = std::min(absoluteEnd - currentStart, currentLength);\n\n        if (relativeStart != relativeEnd) {\n            if (!contour->getSegment(relativeStart, relativeEnd, &_interpolatedPath.getSkValue(), true)) {\n                break;\n            }\n        }\n\n        currentStart = currentEnd;\n    }\n\n    return _interpolatedPath;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/PathInterpolator.hpp",
    "content": "//\n//  PathInterpolator.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 4/20/22.\n//\n\n#pragma once\n\n#include \"include/core/SkContourMeasure.h\"\n#include \"snap_drawing/cpp/Utils/Path.hpp\"\n#include \"valdi_core/cpp/Utils/SmallVector.hpp\"\n\nnamespace snap::drawing {\n\nclass PathInterpolator {\npublic:\n    explicit PathInterpolator(const Path& path);\n    ~PathInterpolator();\n\n    const Path& interpolate(Scalar start, Scalar end);\n\nprivate:\n    Path _interpolatedPath;\n    Valdi::SmallVector<sk_sp<SkContourMeasure>, 1> _contours;\n    Scalar _totalLength = 0.0f;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/SafeContainer.cpp",
    "content": "//\n//  SafeContainer.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 10/24/22.\n//\n\n#include \"snap_drawing/cpp/Utils/SafeContainer.hpp\"\n#include \"utils/debugging/Assert.hpp\"\n\nnamespace snap::drawing {\n\nSafeContainerBase::Write::Write(SafeContainerBase* wrapper) : _wrapper(wrapper) {\n    wrapper->onWriteBegin();\n}\n\nSafeContainerBase::Write::~Write() {\n    _wrapper->onWriteEnd();\n}\n\nSafeContainerBase::Read::Read(SafeContainerBase* wrapper) : _wrapper(wrapper) {\n    wrapper->onReadBegin();\n}\n\nSafeContainerBase::Read::~Read() {\n    _wrapper->onReadEnd();\n}\n\nvoid SafeContainerBase::onReadBegin() {\n    if (_writeCount > 0) {\n        SC_ASSERT_FAIL(\"Cannot acquire read lock: write lock already acquired\");\n    }\n    _readCount++;\n}\n\nvoid SafeContainerBase::onReadEnd() {\n    _readCount--;\n}\n\nvoid SafeContainerBase::onWriteBegin() {\n    if (_readCount > 0) {\n        SC_ASSERT_FAIL(\"Cannot acquire write lock: read lock already acquired\");\n    }\n    if (_writeCount > 0) {\n        SC_ASSERT_FAIL(\"Cannot acquire write lock: write lock already acquired\");\n    }\n    _writeCount++;\n}\n\nvoid SafeContainerBase::onWriteEnd() {\n    _writeCount--;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/SafeContainer.hpp",
    "content": "//\n//  SafeContainer.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 10/24/22.\n//\n\n#pragma once\n\n#include \"utils/base/NonCopyable.hpp\"\n#include <cstddef>\n\nnamespace snap::drawing {\n\nclass SafeContainerBase {\npublic:\n    class Write : public snap::NonCopyable {\n    public:\n        explicit Write(SafeContainerBase* wrapper);\n        ~Write();\n\n    private:\n        SafeContainerBase* _wrapper;\n    };\n\n    class Read : public snap::NonCopyable {\n    public:\n        explicit Read(SafeContainerBase* wrapper);\n        ~Read();\n\n    private:\n        SafeContainerBase* _wrapper;\n    };\n\nprivate:\n    int _readCount = 0;\n    int _writeCount = 0;\n\n    friend Write;\n    friend Read;\n\n    void onReadBegin();\n    void onReadEnd();\n\n    void onWriteBegin();\n    void onWriteEnd();\n};\n\n/**\n SafeContainer is a general purpose wrapper around a container that exposes\n read and write \"locks\" semantics. It helps ensuring that mutations to the underlying\n container are not happening while a read is in progress and vice versa.\n */\ntemplate<typename T>\nclass SafeContainer : public SafeContainerBase {\npublic:\n    class WriteAccess : public SafeContainerBase::Write {\n    public:\n        WriteAccess(SafeContainerBase* wrapper, T& container)\n            : SafeContainerBase::Write(wrapper), _container(container) {}\n        ~WriteAccess() = default;\n\n        constexpr T* operator->() const {\n            return &_container;\n        }\n\n        constexpr T& operator*() const {\n            return _container;\n        }\n\n        T& get() const {\n            return _container;\n        }\n\n        auto begin() const {\n            return _container.begin();\n        }\n\n        auto end() const {\n            return _container.end();\n        }\n\n    private:\n        T& _container;\n    };\n\n    class ReadAccess : public SafeContainerBase::Read {\n    public:\n        ReadAccess(SafeContainerBase* wrapper, const T& container)\n            : SafeContainerBase::Read(wrapper), _container(container) {}\n        ~ReadAccess() = default;\n\n        constexpr const T* operator->() const {\n            return &_container;\n        }\n\n        constexpr const T& operator*() const {\n            return _container;\n        }\n\n        const T& get() const {\n            return _container;\n        }\n\n        auto begin() const {\n            return _container.begin();\n        }\n\n        auto end() const {\n            return _container.end();\n        }\n\n    private:\n        const T& _container;\n    };\n\n    WriteAccess writeAccess() {\n        return WriteAccess(this, _container);\n    }\n\n    ReadAccess readAccess() const {\n        // Casting to mutable to preserve read-only semantics on the caller, even\n        // if we have to increment/decrement an integer under the hood\n        return ReadAccess(const_cast<SafeContainer<T>*>(this), _container);\n    }\n\n    size_t size() const {\n        return _container.size();\n    }\n\n    bool empty() const {\n        return _container.empty();\n    }\n\nprivate:\n    T _container;\n};\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Scalar.cpp",
    "content": "//\n//  Scalar.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"snap_drawing/cpp/Utils/Scalar.hpp\"\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/Scalar.hpp",
    "content": "//\n//  Scalar.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include \"include/core/SkScalar.h\"\n#include <cmath>\n\nnamespace snap::drawing {\n\nusing Scalar = SkScalar;\n\ninline Scalar pixelsToScalar(int pixels, float pointScale) {\n    return static_cast<Scalar>(pixels) / pointScale;\n}\n\ntemplate<size_t length>\nstatic inline bool scalarsEqual(const Scalar* left, const Scalar* right) {\n    // Use epsilon-based comparison to handle floating-point precision issues.\n    // Without this, tiny differences (e.g., 10.499999 vs 10.500001) from different\n    // transformation paths incorrectly trigger damage detection, requiring larger\n    // damage rect margins to compensate.\n    constexpr Scalar epsilon = 0.0001f; // ~1/10000th of a pixel\n\n    for (size_t i = 0; i < length; i++) {\n        if (std::abs(left[i] - right[i]) > epsilon) {\n            return false;\n        }\n    }\n    return true;\n}\n\nstatic inline Scalar sanitizeScalarFromScale(Scalar value, Scalar scale) {\n    return roundf(value * scale) / scale;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/SkCodecAnimatedImage.cpp",
    "content": "//\n//  SkCodecAnimatedImage.cpp\n//  snap_drawing\n//\n//  Created by Ben Dodson on 06/19/24.\n//\n\n#include \"snap_drawing/cpp/Utils/SkCodecAnimatedImage.hpp\"\n#include \"include/core/SkCanvas.h\"\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/DrawableSurfaceCanvas.hpp\"\n\nnamespace snap::drawing {\n\nSkCodecAnimatedImage::~SkCodecAnimatedImage() = default;\n\nconst Duration& SkCodecAnimatedImage::getDuration() const {\n    return _duration;\n}\n\nDuration SkCodecAnimatedImage::getCurrentTime() const {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    return _currentTime;\n}\n\nconst Size& SkCodecAnimatedImage::getSize() const {\n    return _size;\n}\n\ndouble SkCodecAnimatedImage::getFrameRate() const {\n    return _frameRate;\n}\n\nSkCodecAnimatedImage::SkCodecAnimatedImage(std::unique_ptr<SkCodec> codec)\n    : _size(Size(codec->dimensions().width(), codec->dimensions().height())) {\n    SkImageInfo imageInfo = codec->getInfo().makeColorType(kN32_SkColorType);\n    std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo();\n    const auto totalFrames = frameInfos.size();\n    long totalAnimationDurationMs = 0u;\n    for (size_t i = 0; i < totalFrames; i++) {\n        totalAnimationDurationMs += frameInfos[i].fDuration;\n    }\n    _numberOfFrames = totalFrames;\n    _duration = Duration::fromMilliseconds(totalAnimationDurationMs);\n    _frameRate = _frameRate = codec->getFrameCount() / _duration.seconds();\n    _player = std::make_unique<SkAnimCodecPlayer>(std::move(codec));\n}\n\nValdi::Value SkCodecAnimatedImage::getMetadata() const {\n    return Valdi::Value()\n        .setMapValue(\"type\", Valdi::Value(Valdi::StringBox::fromCString(\"skcodec\")))\n        .setMapValue(\"width\", Valdi::Value(static_cast<int32_t>(_size.width)))\n        .setMapValue(\"height\", Valdi::Value(static_cast<int32_t>(_size.height)))\n        .setMapValue(\"numberOfFrames\", Valdi::Value(static_cast<int32_t>(_numberOfFrames)))\n        .setMapValue(\"durationMs\", Valdi::Value(static_cast<int32_t>(_duration.milliseconds())));\n}\n\nvoid SkCodecAnimatedImage::doDraw(SkCanvas* canvas,\n                                  const Rect& drawBounds,\n                                  const Duration& time,\n                                  FittingSizeMode fittingSizeMode) {\n    std::lock_guard<Valdi::Mutex> lock(_mutex);\n    _currentTime = std::clamp(time, Duration(), _duration);\n\n    _player->seek(_currentTime.milliseconds());\n    const auto& image = _player->getFrame();\n    const SkRect srcR = SkRect::MakeWH(_size.width, _size.height);\n    canvas->drawImageRect(\n        image, srcR, drawBounds.getSkValue(), SkSamplingOptions(), nullptr, SkCanvas::kStrict_SrcRectConstraint);\n}\n\nValdi::Result<Ref<SkCodecAnimatedImage>> SkCodecAnimatedImage::make(std::unique_ptr<SkCodec> codec) {\n    return Valdi::makeShared<SkCodecAnimatedImage>(std::move(codec));\n}\n\nVALDI_CLASS_IMPL(SkCodecAnimatedImage)\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/SkCodecAnimatedImage.hpp",
    "content": "//\n//  SkCodecAnimatedImage.hpp\n//  snap_drawing\n//\n//  Created by Ben Dodson on 6/20/24.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Aliases.hpp\"\n#include \"snap_drawing/cpp/Utils/AnimatedImage.hpp\"\n#include \"snap_drawing/cpp/Utils/Duration.hpp\"\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n\n#include \"valdi_core/cpp/Resources/LoadedAsset.hpp\"\n\n#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/Mutex.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\n#include \"include/codec/SkCodec.h\"\n#include \"modules/skottie/include/Skottie.h\"\n#include \"modules/skresources/src/SkAnimCodecPlayer.h\"\n\nnamespace snap::drawing {\n\nclass Resources;\nclass DrawingContext;\nclass IFontManager;\n\nclass SkCodecAnimatedImage : public AnimatedImage {\npublic:\n    explicit SkCodecAnimatedImage(std::unique_ptr<SkCodec> codec);\n    ~SkCodecAnimatedImage() override;\n\n    Duration getCurrentTime() const override;\n    const Duration& getDuration() const override;\n    const Size& getSize() const override;\n    double getFrameRate() const override;\n    Valdi::Value getMetadata() const override;\n\n    static Valdi::Result<Ref<SkCodecAnimatedImage>> make(std::unique_ptr<SkCodec> codec);\n\n    VALDI_CLASS_HEADER(SkCodecAnimatedImage)\n\nprotected:\n    void doDraw(SkCanvas* canvas,\n                const Rect& drawBounds,\n                const Duration& time,\n                FittingSizeMode fittingSizeMode) override;\n\nprivate:\n    mutable Valdi::Mutex _mutex;\n    std::unique_ptr<SkAnimCodecPlayer> _player;\n    Duration _duration;\n    Duration _currentTime;\n    Size _size;\n    size_t _numberOfFrames = 0;\n    double _frameRate;\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/SkiaBridge.cpp",
    "content": "//\n//  SkiaBridge.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#include \"SkiaBridge.hpp\"\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/SkiaBridge.hpp",
    "content": "//\n//  SkiaBridge.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 1/28/22.\n//\n\n#pragma once\n\n#include <utility>\n\nnamespace snap::drawing {\n\n/**\n A BridgedSkValue is a data class which has a memory layout\n 100% compatible with a Skia representation.\n Subclasses of BridgedSkValue should expose methods to interact\n with itself without mutating the SkValue. BridgedSkValue\n can be converted into an equivalent Skia value with no\n performance penalty.\n */\ntemplate<typename T, typename SkType>\nstruct BridgedSkValue {\n    constexpr SkType& getSkValue() {\n        static_assert(sizeof(T) == sizeof(SkType));\n        return *reinterpret_cast<SkType*>(this);\n    }\n\n    constexpr const SkType& getSkValue() const {\n        static_assert(sizeof(T) == sizeof(SkType));\n        return *reinterpret_cast<const SkType*>(this);\n    }\n};\n\n/**\n A WrappedSkValue is an abstraction over a Skia object.\n The Skia object is held internally and can be accessed\n through getSkValue(). Subclasses of WrapedSkValue should\n expose methods to interact with the SKValue, without exposing\n the SkValue itself, thus abstracting it.\n */\ntemplate<typename SkType>\nclass WrappedSkValue {\npublic:\n    template<typename... Args>\n    explicit WrappedSkValue(Args&&... args) : _value(std::forward<Args>(args)...) {}\n\n    constexpr SkType& getSkValue() {\n        return _value;\n    }\n\n    constexpr const SkType& getSkValue() const {\n        return _value;\n    }\n\nprivate:\n    SkType _value;\n};\n\ntemplate<typename T,\n         typename SkType,\n         typename std::enable_if<std::is_convertible<T*, BridgedSkValue<T, SkType>*>::value, int>::type = 0>\nconstexpr const T& fromSkValue(const SkType& skValue) {\n    return reinterpret_cast<const T&>(skValue);\n}\n\ntemplate<typename T,\n         typename SkType,\n         typename std::enable_if<std::is_convertible<T*, WrappedSkValue<SkType>*>::value, int>::type = 0>\nconstexpr T fromSkValue(const SkType& skValue) {\n    return T(skValue);\n}\n\ntemplate<typename T,\n         typename SkType,\n         typename std::enable_if<std::is_convertible<T*, WrappedSkValue<SkType>*>::value, int>::type = 0>\nconstexpr T fromSkValue(SkType&& skValue) {\n    return T(std::forward<SkType>(skValue));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/TimePoint.hpp",
    "content": "//\n//  TimePoint.hpp\n//  valdi-pc\n//\n//  Created by Simon Corsin on 6/30/20.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Duration.hpp\"\n#include \"valdi_core/cpp/Utils/TimePoint.hpp\"\n\nnamespace snap::drawing {\n\nusing TimePoint = Valdi::TimePoint;\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/UTFUtils.cpp",
    "content": "//\n//  UTFUtils.cpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/16/22.\n//\n\n#include \"snap_drawing/cpp/Utils/UTFUtils.hpp\"\n#include \"include/core/SkTypes.h\"\n\nnamespace SkUTF {\n\n// Those APIs exist in Skia but not in the public headers\nSK_SPI int CountUTF8(const char* utf8, size_t byteLength);    // NOLINT\nSK_SPI SkUnichar NextUTF8(const char** ptr, const char* end); // NOLINT\nSK_SPI size_t ToUTF8(SkUnichar uni, char* utf8);              // NOLINT\n\n} // namespace SkUTF\n\nnamespace snap::drawing {\n\nstd::vector<Character> utf8ToUnicode(std::string_view utf8) {\n    std::vector<Character> out;\n    utf8ToUnicode(utf8, out);\n    return out;\n}\n\nsize_t utf8ToUnicode(std::string_view utf8, std::vector<Character>& output) {\n    const auto* utf8Start = utf8.data();\n\n    auto unicodeCount = SkUTF::CountUTF8(utf8Start, utf8.size());\n    if (unicodeCount <= 0) {\n        return 0;\n    }\n\n    auto previousSize = output.size();\n    output.resize(previousSize + unicodeCount);\n\n    auto* unicodePtr = reinterpret_cast<SkUnichar*>(output.data() + previousSize);\n\n    const auto* utf8End = utf8Start + utf8.size();\n\n    while (utf8Start < utf8End) {\n        (*unicodePtr) = SkUTF::NextUTF8(&utf8Start, utf8End);\n        unicodePtr++;\n    }\n\n    return unicodeCount;\n}\n\nstd::string unicodeToUtf8(const Character* unicode, size_t length) {\n    std::string characters;\n    char buffer[4];\n\n    const auto* skCharactersPtr = reinterpret_cast<const SkUnichar*>(unicode);\n\n    for (size_t i = 0; i < length; i++) {\n        size_t written = SkUTF::ToUTF8(skCharactersPtr[i], buffer);\n        characters.append(buffer, written);\n    }\n\n    return characters;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/UTFUtils.hpp",
    "content": "//\n//  UTFUtils.hpp\n//  snap_drawing\n//\n//  Created by Simon Corsin on 3/16/22.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Text/Character.hpp\"\n#include <string>\n#include <vector>\n\nnamespace snap::drawing {\n\nstd::vector<Character> utf8ToUnicode(std::string_view utf8);\nsize_t utf8ToUnicode(std::string_view utf8, std::vector<Character>& output);\nstd::string unicodeToUtf8(const Character* unicode, size_t length);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/VelocityTracker.cpp",
    "content": "//\n//  VelocityTracker.cpp\n//  valdi-skia\n//\n//  Created by Vincent Brunet on 02/16/21.\n//\n\n#include \"snap_drawing/cpp/Utils/VelocityTracker.hpp\"\n\n#include <cmath>\n\nnamespace snap::drawing {\n\nconst Scalar kApproxSqrt2 = 1.41421356237f;\nconst size_t kMomentHistory = 10;\n\nVelocityTracker::VelocityTracker() = default;\n\nVelocityTracker::Moment::Moment(const TimePoint& time, Scalar sample) : time(time), sample(sample) {}\n\nvoid VelocityTracker::addSample(const TimePoint& time, Scalar sample) {\n    // First element in the list is the most recent event\n    _moments.emplace_front(time, sample);\n    while (_moments.size() > kMomentHistory) {\n        _moments.pop_back();\n    }\n}\n\nScalar VelocityTracker::computeVelocity() const {\n    return computeImpulseVelocity();\n}\n\nvoid VelocityTracker::clear() {\n    _moments.clear();\n}\n\nScalar VelocityTracker::computeImpulseVelocity() const {\n    auto count = _moments.size();\n    // If 0 or 1 points, velocity is zero\n    if (count < 2) {\n        return 0;\n    }\n    // If 2 points, basic linear calculation\n    if (count == 2) {\n        auto moment0 = _moments[0];\n        auto moment1 = _moments[1];\n        Scalar timeDiff = (moment1.time - moment0.time).seconds();\n        if (timeDiff == 0) {\n            return 0;\n        }\n        return (moment1.sample - moment0.sample) / timeDiff;\n    }\n    // Guaranteed to have at least 3 points here\n    Scalar work = 0;\n    // Start with the oldest sample and go forward in time\n    for (size_t i = count - 1; i > 0; i--) {\n        auto momentCurrent = _moments[i];\n        auto momentNext = _moments[i - 1];\n        // Events have identical time stamps, skipping sample\n        if (momentCurrent.time == momentNext.time) {\n            continue;\n        }\n        Scalar timeDiff = (momentCurrent.time - momentNext.time).seconds();\n        Scalar velocityPrev = VelocityTracker::kineticEnergyToVelocity(work);\n        Scalar velocityCurrent = (momentCurrent.sample - momentNext.sample) / timeDiff;\n        work += (velocityCurrent - velocityPrev) * fabsf(velocityCurrent);\n        if (i == count - 1) {\n            work *= 0.5f; // initial condition\n        }\n    }\n    return kineticEnergyToVelocity(work);\n}\n\nScalar VelocityTracker::kineticEnergyToVelocity(Scalar work) {\n    return (work < 0 ? -1.0f : 1.0f) * sqrtf(fabsf(work)) * kApproxSqrt2;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/src/snap_drawing/cpp/Utils/VelocityTracker.hpp",
    "content": "//\n//  VelocityTracker.hpp\n//  valdi-skia\n//\n//  Created by Vincent Brunet on 02/16/21.\n//\n\n#pragma once\n\n#include \"snap_drawing/cpp/Utils/Geometry.hpp\"\n#include \"snap_drawing/cpp/Utils/TimePoint.hpp\"\n\n#include <deque>\n#include <optional>\n\nnamespace snap::drawing {\n\nclass VelocityTracker {\npublic:\n    VelocityTracker();\n\n    void addSample(const TimePoint& time, Scalar sample);\n    Scalar computeVelocity() const;\n    void clear();\n\nprivate:\n    struct Moment {\n        TimePoint time;\n        Scalar sample;\n\n        Moment(const TimePoint& time, Scalar sample);\n    };\n\n    std::deque<Moment> _moments;\n\n    Scalar computeImpulseVelocity() const;\n\n    static Scalar kineticEnergyToVelocity(Scalar work);\n};\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/Compositor_Tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"DisplayListBuilder.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/Compositor.hpp\"\n#include \"snap_drawing/cpp/Drawing/Composition/CompositorPlaneList.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"src/base/SkFloatBits.h\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nstatic CompositorPlaneList performComposition(DisplayListBuilder& builder,\n                                              Ref<DisplayList>* outputDisplayList = nullptr) {\n    CompositorPlaneList planeList;\n    Compositor compositor(ConsoleLogger::getLogger());\n    auto displayList = compositor.performComposition(*builder.displayList, planeList);\n    if (outputDisplayList != nullptr) {\n        *outputDisplayList = displayList;\n    }\n    return planeList;\n}\n\nTEST(Compositor, doesNothingWhenNoExternalSurfacesArePresent) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.rectangle(Size(50, 50), 1.0);\n\n        builder.context(Vector(25, 25), 1.0, [&]() { builder.rectangle(Size(10, 10), 1.0); });\n\n        builder.context(Vector(35, 35), 1.0, [&]() { builder.rectangle(Size(50, 50), 1.0); });\n\n        builder.rectangle(Size(25, 25), 1.0);\n    });\n\n    Ref<DisplayList> outputDisplayList;\n    auto planeList = performComposition(builder, &outputDisplayList);\n\n    ASSERT_EQ(static_cast<size_t>(1), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_TRUE(planeList.getPlaneAtIndex(0).getExternalSurface() == nullptr);\n\n    ASSERT_EQ(builder.displayList, outputDisplayList);\n}\n\nTEST(Compositor, emitsDedicatedLayerWhenAnExternalSurfaceIsPresent) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.rectangle(Size(50, 50), 1.0);\n\n        builder.context(Vector(25, 25), 1.0, [&]() { builder.rectangle(Size(10, 10), 1.0); });\n\n        builder.context(Vector(35, 35), 1.0, [&]() { builder.rectangle(Size(50, 50), 1.0); });\n\n        builder.rectangle(Size(25, 25), 1.0);\n\n        builder.externalSurface(Size(50, 50), 1.0);\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_TRUE(planeList.getPlaneAtIndex(1).getExternalSurface() != nullptr);\n}\n\nTEST(Compositor, resolvesDisplayStateOfExternalSurface) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.context(Vector(10, 20), 0.75, [&]() {\n            builder.context(Vector(0, 0), 1.0, [&]() {\n                builder.context(Vector(30, 40), 0.5, [&]() { builder.externalSurface(Size(50, 50), 0.25); });\n            });\n        });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(1), planeList.getPlanesCount());\n\n    const auto& plane = planeList.getPlaneAtIndex(0);\n    ASSERT_EQ(CompositorPlaneTypeExternal, plane.getType());\n    ASSERT_TRUE(plane.getExternalSurface() != nullptr);\n\n    Matrix expectedTransform;\n\n    ASSERT_EQ(Rect::makeXYWH(40, 60, 50, 50), plane.getExternalSurfacePresenterState()->frame);\n    ASSERT_EQ(expectedTransform, plane.getExternalSurfacePresenterState()->transform);\n    ASSERT_EQ(0.09375, plane.getExternalSurfacePresenterState()->opacity);\n}\n\nTEST(Compositor, resolvesDisplayStateOfExternalSurfaceWithComplexTransforms) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        Matrix outerMatrix;\n        outerMatrix.setTranslateX(10);\n        outerMatrix.setTranslateY(20);\n        outerMatrix.setScaleX(2.0);\n        outerMatrix.setScaleY(4.0);\n\n        builder.context(outerMatrix, 1.0, [&]() {\n            builder.context(Vector(0, 0), 1.0, [&]() {\n                Matrix innerMatrix;\n                innerMatrix.postRotateDegrees(90.0, 25.0, 25.0);\n                builder.context(innerMatrix, 1.0, [&]() { builder.externalSurface(Size(50, 50), 1.0); });\n            });\n        });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(1), planeList.getPlanesCount());\n\n    const auto& plane = planeList.getPlaneAtIndex(0);\n    ASSERT_EQ(CompositorPlaneTypeExternal, plane.getType());\n    ASSERT_TRUE(plane.getExternalSurface() != nullptr);\n\n    Matrix expectedTransform;\n    expectedTransform.setScaleX(0);\n    expectedTransform.setScaleY(0);\n    expectedTransform.setTranslateX(110);\n    expectedTransform.setTranslateY(20);\n    expectedTransform.setSkewX(-2);\n    expectedTransform.setSkewY(4);\n\n    ASSERT_EQ(Rect::makeXYWH(0, 0, 50, 50), plane.getExternalSurfacePresenterState()->frame);\n    ASSERT_EQ(\n        Rect::makeXYWH(10, 20, 100, 200),\n        plane.getExternalSurfacePresenterState()->transform.mapRect(plane.getExternalSurfacePresenterState()->frame));\n    ASSERT_EQ(expectedTransform, plane.getExternalSurfacePresenterState()->transform);\n}\n\nTEST(Compositor, resolvesSimpleClipOfExternalSurface) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.clip(Size(100, 100));\n        builder.context(Vector(10, 20), 0.75, [&]() {\n            builder.context(Vector(0, 0), 1.0, [&]() {\n                builder.context(Vector(30, 40), 0.5, [&]() {\n                    builder.clip(Size(20, 13));\n                    builder.externalSurface(Size(50, 50), 0.25);\n                });\n            });\n        });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(1), planeList.getPlanesCount());\n\n    const auto& plane = planeList.getPlaneAtIndex(0);\n    ASSERT_EQ(CompositorPlaneTypeExternal, plane.getType());\n    ASSERT_TRUE(plane.getExternalSurface() != nullptr);\n\n    Path expectedClip;\n    expectedClip.addRect(Rect::makeXYWH(40, 60, 20, 13), true);\n\n    ASSERT_EQ(expectedClip, plane.getExternalSurfacePresenterState()->clipPath);\n}\n\nTEST(Compositor, resolvesComplexClipOfExternalSurface) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.clip(BorderRadius::makeCircle(), Size(100, 100));\n        builder.context(Vector(50, 50), 1.0, [&]() {\n            builder.clip(Size(50, 25));\n            builder.externalSurface(Size(50, 50), 0.25);\n        });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(1), planeList.getPlanesCount());\n\n    const auto& plane = planeList.getPlaneAtIndex(0);\n    ASSERT_EQ(CompositorPlaneTypeExternal, plane.getType());\n    ASSERT_TRUE(plane.getExternalSurface() != nullptr);\n\n    Path expectedClip;\n    expectedClip.moveTo(SkBits2Float(0x42ba9a40), 75); // 93.3013f, 75\n    expectedClip.lineTo(50, 75);\n    expectedClip.lineTo(50, 50);\n    expectedClip.lineTo(100, 50);\n    expectedClip.conicTo(100,\n                         SkBits2Float(0x427d9700),\n                         SkBits2Float(0x42ba9a40),\n                         75,\n                         SkBits2Float(0x3f7746ea)); // 100, 63.3975f, 93.3013f, 75, 0.965926f\n    expectedClip.close();\n\n    ASSERT_EQ(expectedClip, plane.getExternalSurfacePresenterState()->clipPath);\n}\n\nTEST(Compositor, usesOneLayerPerExternalSurface) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.externalSurface(Size(10, 10), 1.0);\n\n        builder.context(Vector(25, 25), 1.0, [&]() { builder.externalSurface(Size(20, 20), 1.0); });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_TRUE(planeList.getPlaneAtIndex(0).getExternalSurface() != nullptr);\n    ASSERT_TRUE(planeList.getPlaneAtIndex(1).getExternalSurface() != nullptr);\n}\n\nTEST(Compositor, supportsExternalSurfaceOnTopOfRegularLayer) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.rectangle(Size(25, 25), 1.0);\n        builder.context(Vector(100, 100), 1.0, [&]() { builder.rectangle(Size(1, 1), 1.0); });\n\n        builder.externalSurface(Size(10, 10), 1.0);\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_FALSE(planeList.getPlaneAtIndex(0).getExternalSurface() != nullptr);\n    ASSERT_TRUE(planeList.getPlaneAtIndex(1).getExternalSurface() != nullptr);\n}\n\nTEST(Compositor, supportsRegularLayerOnTopOfExternalSurface) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.externalSurface(Size(10, 10), 1.0);\n\n        builder.rectangle(Size(25, 25), 1.0);\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_TRUE(planeList.getPlaneAtIndex(0).getExternalSurface() != nullptr);\n    ASSERT_FALSE(planeList.getPlaneAtIndex(1).getExternalSurface() != nullptr);\n}\n\nTEST(Compositor, supportsExternalSurfaceInBetweenRegularLayers) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.rectangle(Size(25, 25), 1.0);\n\n        builder.context(Vector(0.0, 0.0), 1.0, [&]() { builder.externalSurface(Size(10, 10), 1.0); });\n\n        builder.rectangle(Size(15, 15), 1.0);\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(3), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(2).getType());\n    ASSERT_FALSE(planeList.getPlaneAtIndex(0).getExternalSurface() != nullptr);\n    ASSERT_TRUE(planeList.getPlaneAtIndex(1).getExternalSurface() != nullptr);\n    ASSERT_FALSE(planeList.getPlaneAtIndex(2).getExternalSurface() != nullptr);\n}\n\nTEST(Compositor, avoidsCreatingRegularLayerIfItemFitsInALowerRegularLayer) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.rectangle(Size(25, 25), 1.0);\n\n        builder.context(Vector(15, 15), 1.0, [&]() { builder.externalSurface(Size(10, 10), 1.0); });\n\n        builder.rectangle(Size(15, 15), 1.0);\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_FALSE(planeList.getPlaneAtIndex(0).getExternalSurface() != nullptr);\n    ASSERT_TRUE(planeList.getPlaneAtIndex(1).getExternalSurface() != nullptr);\n}\n\nTEST(Compositor, takesInAccountClippingWhenCalculatingRegularLayerFit) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.rectangle(Size(25, 25), 1.0);\n\n        builder.context(Vector(15, 15), 1.0, [&]() { builder.externalSurface(Size(10, 10), 1.0); });\n\n        builder.context(Vector(0, 0), 1.0, [&]() {\n            builder.clip(Size(15, 15));\n            builder.rectangle(Size(100, 100), 1.0);\n        });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_FALSE(planeList.getPlaneAtIndex(0).getExternalSurface() != nullptr);\n    ASSERT_TRUE(planeList.getPlaneAtIndex(1).getExternalSurface() != nullptr);\n}\n\nTEST(Compositor, handlesClipThatDoesntImpactLayerFit) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.rectangle(Size(25, 25), 1.0);\n\n        builder.context(Vector(15, 15), 1.0, [&]() { builder.externalSurface(Size(10, 10), 1.0); });\n\n        builder.context(Vector(0, 0), 1.0, [&]() {\n            builder.clip(Size(50, 16));\n            builder.rectangle(Size(100, 100), 1.0);\n        });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(3), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(2).getType());\n}\n\nTEST(Compositor, mergesClips) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.rectangle(Size(25, 25), 1.0);\n\n        builder.context(Vector(15, 15), 1.0, [&]() { builder.externalSurface(Size(10, 10), 1.0); });\n\n        builder.context(Vector(0, 0), 1.0, [&]() {\n            builder.clip(Size(15, 100));\n\n            builder.context(Vector(0, 0), 1.0, [&]() {\n                builder.clip(Size(50, 50));\n\n                builder.rectangle(Size(100, 100), 1.0);\n            });\n        });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_FALSE(planeList.getPlaneAtIndex(0).getExternalSurface() != nullptr);\n    ASSERT_TRUE(planeList.getPlaneAtIndex(1).getExternalSurface() != nullptr);\n}\n\nTEST(Compositor, handlesComplexCompositions) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.context(Vector(0.0, 0.0), 1.0, [&]() { builder.rectangle(Size(25, 25), 1.0); });\n\n        builder.context(Vector(10.0, 10.0), 1.0, [&]() { builder.externalSurface(Size(25, 25), 1.0); });\n\n        builder.context(Vector(20.0, 20.0), 1.0, [&]() { builder.rectangle(Size(25, 25), 1.0); });\n\n        builder.context(Vector(30.0, 30.0), 1.0, [&]() { builder.externalSurface(Size(25, 25), 1.0); });\n\n        builder.context(Vector(40.0, 40.0), 1.0, [&]() { builder.rectangle(Size(25, 25), 1.0); });\n\n        builder.context(Vector(50.0, 50.0), 1.0, [&]() { builder.externalSurface(Size(25, 25), 1.0); });\n\n        // This one specifically does not overlap with all external planes\n        // and should be thus added to an existing layer instead of creating one\n        builder.context(Vector(0.0, 0.0), 1.0, [&]() { builder.rectangle(Size(25, 25), 1.0); });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(6), planeList.getPlanesCount());\n\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(2).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(3).getType());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(4).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(5).getType());\n}\n\nTEST(Compositor, keepsExternalSurfaceBelowOverlayWhenPossible) {\n    DisplayListBuilder builder(100, 100);\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.context(Vector(0.0, 0.0), 1.0, [&]() { builder.rectangle(Size(25, 25), 1.0); });\n\n        builder.context(Vector(10.0, 10.0), 1.0, [&]() { builder.externalSurface(Size(25, 25), 1.0); });\n\n        builder.context(Vector(10.0, 25.0), 1.0, [&]() { builder.rectangle(Size(25, 2), 1.0); });\n\n        builder.context(Vector(5.0, 50.0), 1.0, [&]() { builder.externalSurface(Size(25, 25), 1.0); });\n\n        builder.context(Vector(0.0, 65.0), 1.0, [&]() { builder.rectangle(Size(25, 2), 1.0); });\n    });\n\n    auto planeList = performComposition(builder);\n\n    ASSERT_EQ(static_cast<size_t>(4), planeList.getPlanesCount());\n\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(0).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(1).getType());\n    ASSERT_EQ(CompositorPlaneTypeExternal, planeList.getPlaneAtIndex(2).getType());\n    ASSERT_EQ(CompositorPlaneTypeDrawable, planeList.getPlaneAtIndex(3).getType());\n}\n\nTEST(Compositor, buildsOutputDisplayList) {\n    DisplayListBuilder builder(100, 100);\n\n    LayerContent firstRectangle;\n    LayerContent secondRectangle;\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.context(Vector(1, 1), 1.0, [&]() {\n            builder.clip(Size(100, 100));\n\n            builder.context(Vector(-1, -1), 1.0, [&]() { firstRectangle = builder.rectangle(Size(25, 25), 1.0); });\n\n            builder.context(Vector(0.0, 0.0), 1.0, [&]() {\n                builder.clip(Size(10, 10));\n                builder.externalSurface(Size(10, 10), 1.0);\n            });\n\n            builder.context(Vector(0, 0), 1.0, [&]() { secondRectangle = builder.rectangle(Size(15, 15), 1.0); });\n        });\n    });\n\n    Ref<DisplayList> outputDisplayList;\n    auto planeList = performComposition(builder, &outputDisplayList);\n    ASSERT_EQ(static_cast<size_t>(3), planeList.getPlanesCount());\n\n    DisplayListBuilder expectedBuilder(100, 100);\n    expectedBuilder.displayList->removePlane(0);\n\n    expectedBuilder.plane([&]() {\n        expectedBuilder.context(Vector(0, 0), 1.0, [&]() {\n            expectedBuilder.context(Vector(1, 1), 1.0, [&]() {\n                expectedBuilder.clip(Size(100, 100));\n                expectedBuilder.context(\n                    Vector(-1, -1), 1.0, [&]() { expectedBuilder.layerContent(firstRectangle, 1.0); });\n            });\n        });\n    });\n\n    expectedBuilder.plane([&]() {\n        expectedBuilder.context(Vector(0, 0), 1.0, [&]() {\n            expectedBuilder.context(Vector(1, 1), 1.0, [&]() {\n                expectedBuilder.clip(Size(100, 100));\n                expectedBuilder.context(\n                    Vector(0, 0), 1.0, [&]() { expectedBuilder.layerContent(secondRectangle, 1.0); });\n            });\n        });\n    });\n\n    ASSERT_EQ(*expectedBuilder.displayList, *outputDisplayList);\n}\n\nTEST(Compositor, canHandleMultipleClipsInContext) {\n    DisplayListBuilder builder(100, 100);\n\n    LayerContent firstRectangle;\n    LayerContent secondRectangle;\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.context(Vector(1, 1), 1.0, [&]() {\n            builder.clip(Size(100, 100));\n\n            builder.context(Vector(-1, -1), 1.0, [&]() { firstRectangle = builder.rectangle(Size(25, 25), 1.0); });\n\n            builder.clip(Size(50, 50));\n\n            secondRectangle = builder.rectangle(Size(25, 25), 1.0);\n\n            builder.context(Vector(0.0, 0.0), 1.0, [&]() {\n                builder.clip(Size(10, 10));\n                builder.externalSurface(Size(10, 10), 1.0);\n            });\n        });\n    });\n\n    Ref<DisplayList> outputDisplayList;\n    auto planeList = performComposition(builder, &outputDisplayList);\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n\n    DisplayListBuilder expectedBuilder(100, 100);\n    expectedBuilder.displayList->removePlane(0);\n\n    expectedBuilder.plane([&]() {\n        expectedBuilder.context(Vector(0, 0), 1.0, [&]() {\n            expectedBuilder.context(Vector(1, 1), 1.0, [&]() {\n                expectedBuilder.clip(Size(100, 100));\n                expectedBuilder.context(\n                    Vector(-1, -1), 1.0, [&]() { expectedBuilder.layerContent(firstRectangle, 1.0); });\n                expectedBuilder.clip(Size(50, 50));\n                expectedBuilder.layerContent(secondRectangle, 1.0);\n            });\n        });\n    });\n\n    ASSERT_EQ(*expectedBuilder.displayList, *outputDisplayList);\n}\n\nTEST(Compositor, appliesMaskToActivePlane) {\n    DisplayListBuilder builder(100, 100);\n\n    LayerContent firstRectangle;\n    LayerContent secondRectangle;\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.context(Vector(0, 0), 1.0, [&]() {\n            builder.mask(Rect::makeXYWH(10, 10, 10, 10), [&]() {\n                firstRectangle = builder.rectangle(Size(25, 25), 1.0);\n\n                builder.context(Vector(0.0, 0.0), 1.0, [&]() {\n                    builder.externalSurface(Size(30, 30), 1.0);\n\n                    builder.mask(Rect::makeXYWH(15, 15, 30, 30),\n                                 [&]() { secondRectangle = builder.rectangle(Size(25, 25), 1.0); });\n                });\n            });\n        });\n    });\n\n    Ref<DisplayList> outputDisplayList;\n    auto planeList = performComposition(builder, &outputDisplayList);\n    ASSERT_EQ(static_cast<size_t>(3), planeList.getPlanesCount());\n\n    DisplayListBuilder expectedBuilder(100, 100);\n    expectedBuilder.displayList->removePlane(0);\n\n    expectedBuilder.plane([&]() {\n        expectedBuilder.context(Vector(0, 0), 1.0, [&]() {\n            expectedBuilder.context(Vector(0, 0), 1.0, [&]() {\n                expectedBuilder.mask(Rect::makeXYWH(10, 10, 10, 10),\n                                     [&]() { expectedBuilder.layerContent(firstRectangle, 1.0); });\n            });\n        });\n    });\n\n    expectedBuilder.plane([&]() {\n        expectedBuilder.context(Vector(0, 0), 1.0, [&]() {\n            expectedBuilder.context(Vector(0, 0), 1.0, [&]() {\n                expectedBuilder.context(Vector(0.0, 0.0), 1.0, [&]() {\n                    expectedBuilder.mask(Rect::makeXYWH(15, 15, 30, 30),\n                                         [&]() { expectedBuilder.layerContent(secondRectangle, 1.0); });\n                });\n            });\n        });\n    });\n\n    ASSERT_EQ(*expectedBuilder.displayList, *outputDisplayList);\n}\n\nTEST(Compositor, optimizesOutUnusedCommands) {\n    DisplayListBuilder builder(100, 100);\n\n    LayerContent rectangle;\n\n    builder.context(Vector(0, 0), 1.0, [&]() {\n        builder.context(\n            Vector(5, 5), 1.0, [&]() { builder.context(Vector(0, 0), 0.5, [&]() { builder.clip(Size(100, 100)); }); });\n\n        rectangle = builder.rectangle(Size(25, 25), 1.0);\n\n        builder.context(Vector(5, 5), 1.0, [&]() { builder.clip(Size(100, 100)); });\n\n        builder.externalSurface(Size(10, 10), 1.0);\n    });\n\n    Ref<DisplayList> outputDisplayList;\n    auto planeList = performComposition(builder, &outputDisplayList);\n\n    ASSERT_EQ(static_cast<size_t>(2), planeList.getPlanesCount());\n\n    DisplayListBuilder expectedBuilder(100, 100);\n\n    expectedBuilder.context(Vector(0, 0), 1.0, [&]() { expectedBuilder.layerContent(rectangle, 1.0); });\n\n    ASSERT_EQ(*expectedBuilder.displayList, *outputDisplayList);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/DisplayList_Tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"DisplayListBuilder.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include <vector>\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nstatic LayerContent makeRectangle(Size size) {\n    DrawingContext ctx(size.width, size.height);\n\n    Paint paint;\n    paint.setColor(Color::blue());\n\n    ctx.drawPaint(paint, ctx.drawBounds());\n\n    return ctx.finish();\n}\n\nTEST(DisplayList, canRecordAndVisitCommands) {\n    auto displayList = makeShared<DisplayList>(Size(100, 100), TimePoint(0));\n\n    auto layerContent = makeRectangle(Size(50, 500));\n    auto borderRadius = BorderRadius::makeOval(25, true);\n\n    Matrix matrix;\n    matrix.setTranslateX(42);\n    matrix.setScaleY(2);\n\n    displayList->pushContext(matrix, 0.5, 0, true);\n    displayList->appendLayerContent(layerContent, 0.25);\n    displayList->appendClipRound(borderRadius, 25, 30);\n    displayList->appendClipRect(40, 70);\n    displayList->popContext();\n\n    ASSERT_EQ(static_cast<size_t>(1), displayList->getPlanesCount());\n\n    auto operations = getOperationsFromDisplayList(displayList, 0);\n\n    ASSERT_EQ(static_cast<size_t>(5), operations.size());\n\n    ASSERT_EQ(Operations::PushContext::kId, operations[0]->type);\n    ASSERT_EQ(Operations::DrawPicture::kId, operations[1]->type);\n    ASSERT_EQ(Operations::ClipRound::kId, operations[2]->type);\n    ASSERT_EQ(Operations::ClipRect::kId, operations[3]->type);\n    ASSERT_EQ(Operations::PopContext::kId, operations[4]->type);\n\n    const auto* pushContext = reinterpret_cast<const Operations::PushContext*>(operations[0]);\n    const auto* drawPicture = reinterpret_cast<const Operations::DrawPicture*>(operations[1]);\n    const auto* clipRound = reinterpret_cast<const Operations::ClipRound*>(operations[2]);\n    const auto* clipRect = reinterpret_cast<const Operations::ClipRect*>(operations[3]);\n\n    ASSERT_EQ(matrix, pushContext->matrix);\n    ASSERT_EQ(0.5, pushContext->opacity);\n\n    ASSERT_EQ(layerContent.picture.get(), drawPicture->picture);\n    ASSERT_EQ(0.25, drawPicture->opacity);\n\n    ASSERT_EQ(borderRadius, clipRound->borderRadius);\n    ASSERT_EQ(25, clipRound->width);\n    ASSERT_EQ(30, clipRound->height);\n\n    ASSERT_EQ(40, clipRect->width);\n    ASSERT_EQ(70, clipRect->height);\n}\n\nTEST(DisplayList, retainAndReleaseRetainableObjects) {\n    auto displayList = makeShared<DisplayList>(Size(100, 100), TimePoint(0));\n\n    auto rectanglePicture = makeRectangle(Size(50, 500)).picture;\n    auto externalSurface = makeShared<ExternalSurface>();\n\n    ASSERT_EQ(1, externalSurface.use_count());\n\n    displayList->appendLayerContent(\n        LayerContent(rectanglePicture, makeShared<ExternalSurfaceSnapshot>(externalSurface)), 1.0);\n\n    ASSERT_EQ(2, externalSurface.use_count());\n\n    // We can't explicitly check for ref count of SkPicture, but we can check that we can make calls to it\n    // after we release our own ref\n    auto* rectanglePicturePtr = rectanglePicture.get();\n\n    ASSERT_EQ(Rect(0, 0, 50, 500), fromSkValue<Rect>(rectanglePicturePtr->cullRect()));\n    rectanglePicture = nullptr;\n    ASSERT_EQ(Rect(0, 0, 50, 500), fromSkValue<Rect>(rectanglePicturePtr->cullRect()));\n\n    displayList = nullptr;\n\n    ASSERT_EQ(1, externalSurface.use_count());\n}\n\nTEST(DisplayList, releaseRetainableObjectsWhenRemovingPlane) {\n    auto displayList = makeShared<DisplayList>(Size(100, 100), TimePoint(0));\n\n    displayList->appendPlane();\n    displayList->appendPlane();\n\n    displayList->setCurrentPlane(1);\n\n    auto externalSurface = makeShared<ExternalSurface>();\n\n    ASSERT_EQ(1, externalSurface.use_count());\n\n    displayList->appendLayerContent(LayerContent(nullptr, makeShared<ExternalSurfaceSnapshot>(externalSurface)), 1.0);\n\n    ASSERT_EQ(2, externalSurface.use_count());\n\n    displayList->removePlane(2);\n\n    ASSERT_EQ(2, externalSurface.use_count());\n\n    displayList->removePlane(1);\n\n    ASSERT_EQ(1, externalSurface.use_count());\n\n    displayList->removePlane(0);\n\n    ASSERT_EQ(1, externalSurface.use_count());\n}\n\nTEST(DisplayList, canHoldMultipleSurfaces) {\n    auto displayList = makeShared<DisplayList>(Size(100, 100), TimePoint(0));\n\n    auto layerContent = makeRectangle(Size(50, 500));\n    auto borderRadius = BorderRadius::makeOval(25, true);\n\n    Matrix matrix;\n    matrix.setTranslateX(42);\n    matrix.setScaleY(2);\n\n    displayList->pushContext(matrix, 0.5, 0, true);\n\n    displayList->appendPlane();\n    displayList->appendLayerContent(layerContent, 0.25);\n\n    displayList->appendPlane();\n    displayList->appendClipRound(borderRadius, 25, 30);\n    displayList->appendClipRect(40, 70);\n\n    ASSERT_EQ(static_cast<size_t>(3), displayList->getPlanesCount());\n\n    auto operations1 = getOperationsFromDisplayList(displayList, 0);\n    auto operations2 = getOperationsFromDisplayList(displayList, 1);\n    auto operations3 = getOperationsFromDisplayList(displayList, 2);\n\n    ASSERT_EQ(static_cast<size_t>(1), operations1.size());\n    ASSERT_EQ(static_cast<size_t>(1), operations2.size());\n    ASSERT_EQ(static_cast<size_t>(2), operations3.size());\n\n    ASSERT_EQ(Operations::PushContext::kId, operations1[0]->type);\n    ASSERT_EQ(Operations::DrawPicture::kId, operations2[0]->type);\n    ASSERT_EQ(Operations::ClipRound::kId, operations3[0]->type);\n    ASSERT_EQ(Operations::ClipRect::kId, operations3[1]->type);\n\n    const auto* pushContext = reinterpret_cast<const Operations::PushContext*>(operations1[0]);\n    const auto* drawPicture = reinterpret_cast<const Operations::DrawPicture*>(operations2[0]);\n    const auto* clipRound = reinterpret_cast<const Operations::ClipRound*>(operations3[0]);\n    const auto* clipRect = reinterpret_cast<const Operations::ClipRect*>(operations3[1]);\n\n    ASSERT_EQ(matrix, pushContext->matrix);\n    ASSERT_EQ(0.5, pushContext->opacity);\n\n    ASSERT_EQ(layerContent.picture.get(), drawPicture->picture);\n    ASSERT_EQ(0.25, drawPicture->opacity);\n\n    ASSERT_EQ(borderRadius, clipRound->borderRadius);\n    ASSERT_EQ(25, clipRound->width);\n    ASSERT_EQ(30, clipRound->height);\n\n    ASSERT_EQ(40, clipRect->width);\n    ASSERT_EQ(70, clipRect->height);\n\n    // We should also be able to visit them all at once\n    auto allOperations = getOperationsFromDisplayList(displayList, kDisplayListAllPlaneIndexes);\n\n    ASSERT_EQ(static_cast<size_t>(4), allOperations.size());\n\n    ASSERT_EQ(pushContext, allOperations[0]);\n    ASSERT_EQ(drawPicture, allOperations[1]);\n    ASSERT_EQ(clipRound, allOperations[2]);\n    ASSERT_EQ(clipRect, allOperations[3]);\n}\n\nTEST(DisplayList, canRemoveEmptySurfaces) {\n    auto displayList = makeShared<DisplayList>(Size(100, 100), TimePoint(0));\n\n    Matrix matrix;\n    matrix.setTranslateX(42);\n    matrix.setScaleY(2);\n\n    displayList->appendPlane();\n\n    displayList->pushContext(matrix, 0.5, 0, true);\n\n    displayList->appendPlane();\n\n    displayList->appendPlane();\n    displayList->appendClipRect(40, 70);\n\n    displayList->appendPlane();\n\n    ASSERT_EQ(static_cast<size_t>(5), displayList->getPlanesCount());\n\n    displayList->removeEmptyPlanes();\n\n    ASSERT_EQ(static_cast<size_t>(2), displayList->getPlanesCount());\n\n    auto operations1 = getOperationsFromDisplayList(displayList, 0);\n    auto operations2 = getOperationsFromDisplayList(displayList, 1);\n\n    ASSERT_EQ(static_cast<size_t>(1), operations1.size());\n    ASSERT_EQ(static_cast<size_t>(1), operations2.size());\n\n    ASSERT_EQ(Operations::PushContext::kId, operations1[0]->type);\n    ASSERT_EQ(Operations::ClipRect::kId, operations2[0]->type);\n\n    const auto* pushContext = reinterpret_cast<const Operations::PushContext*>(operations1[0]);\n    const auto* clipRect = reinterpret_cast<const Operations::ClipRect*>(operations2[0]);\n\n    ASSERT_EQ(matrix, pushContext->matrix);\n    ASSERT_EQ(0.5, pushContext->opacity);\n\n    ASSERT_EQ(40, clipRect->width);\n    ASSERT_EQ(70, clipRect->height);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/DoubleTapGestureRecognizer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(DoubleTapGestureRecognizer, canHandleDoubleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto doubleTapSnapshot = addDoubleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    ASSERT_FALSE(container->root->getTouchDispatcher().isEmpty());\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStateEnded, doubleTapSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(DoubleTapGestureRecognizer, canHandleDoubleTapWithSingleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n    auto doubleTapSnapshot = addDoubleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    ASSERT_FALSE(container->root->getTouchDispatcher().isEmpty());\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, doubleTapSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/DragGestureRecognizer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(DragGestureRecognizer, canHandleDrag) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto dragSnapshot = addDragGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, dragSnapshot->state);\n    ASSERT_EQ(30 + GesturesConfiguration::getDefault().dragTouchSlop - 25, dragSnapshot->location.x);\n    ASSERT_EQ(35 - 25, dragSnapshot->location.y);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35);\n    ASSERT_EQ(GestureRecognizerStateChanged, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, dragSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(DragGestureRecognizer, canHandleDragWithSingleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto dragSnapshot = addDragGesture(childView);\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35);\n    ASSERT_EQ(GestureRecognizerStateChanged, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(DragGestureRecognizer, canHandleDragWithLongPress) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto dragSnapshot = addDragGesture(childView);\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, longPressSnapshot->state);\n\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStateChanged, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(DragGestureRecognizer, canHandleDragWithoutLongPress) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto dragSnapshot = addDragGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(DragGestureRecognizer, canHandleDragDelayed) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto dragSnapshot = addDragGesture(childView);\n\n    auto hold = GesturesConfiguration::getDefault().longPressTimeout;\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 0, 0, 1, hold);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35, 0, 0, 1, hold);\n    ASSERT_EQ(GestureRecognizerStateBegan, dragSnapshot->state);\n\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35, 0, 0, 1, hold);\n    ASSERT_EQ(GestureRecognizerStateChanged, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35, 0, 0, 1, hold);\n    ASSERT_EQ(GestureRecognizerStateEnded, dragSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(DragGestureRecognizer, canHandleDragTwoPointers) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto dragSnapshot = addDragGesture(childView);\n\n    auto hold = GesturesConfiguration::getDefault().longPressTimeout;\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateBegan, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35, 0, 0, 1, hold);\n    ASSERT_EQ(GestureRecognizerStateEnded, dragSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/DrawLooper_Tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"snap_drawing/cpp/Animations/Animation.hpp\"\n#include \"snap_drawing/cpp/Drawing/DrawLooper.hpp\"\n#include \"snap_drawing/cpp/Layers/ExternalLayer.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n\n#include \"valdi_core/cpp/Utils/ByteBuffer.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\n#include \"TestBitmap.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/BitmapGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/SurfacePresenterManager.hpp\"\n\n#include <deque>\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nclass TestFrameScheduler : public IFrameScheduler {\npublic:\n    void advanceTime(TimeInterval duration) {\n        _currentTime += Duration(duration);\n    }\n\n    bool runNextVSyncCallback() {\n        return runNextCallback(_vsyncCallbacks);\n    }\n\n    bool runNextMainThreadCallback() {\n        return runNextCallback(_mainThreadCallbacks);\n    }\n\n    size_t getMainThreadCallbacksSize() const {\n        return _mainThreadCallbacks.size();\n    }\n\n    void onNextVSync(const Ref<IFrameCallback>& callback) override {\n        _vsyncCallbacks.emplace_back(callback);\n    }\n\n    void onMainThread(const Ref<IFrameCallback>& callback) override {\n        _mainThreadCallbacks.emplace_back(callback);\n    }\n\nprivate:\n    std::deque<Ref<IFrameCallback>> _vsyncCallbacks;\n    std::deque<Ref<IFrameCallback>> _mainThreadCallbacks;\n    TimePoint _currentTime = TimePoint(0.0);\n\n    bool runNextCallback(std::deque<Ref<IFrameCallback>>& callbacks) {\n        if (callbacks.empty()) {\n            return false;\n        }\n\n        auto cb = std::move(callbacks.front());\n        callbacks.pop_front();\n\n        cb->onFrame(_currentTime);\n\n        return true;\n    }\n};\n\nstruct TestExternalSurface : public ExternalSurface {\n    std::optional<ExternalSurfacePresenterState> presenterState;\n};\n\nstd::ostream& operator<<(std::ostream& stream, const Surface& surface) {\n    const auto* surfacePtr = &surface;\n\n    if (dynamic_cast<const ExternalSurface*>(surfacePtr) != nullptr) {\n        stream << \"ExternalSurface \";\n    } else if (dynamic_cast<const DrawableSurface*>(surfacePtr) != nullptr) {\n        stream << \"DrawableSurface \";\n    } else {\n        stream << \"Surface \";\n    }\n\n    return stream << reinterpret_cast<const void*>(surfacePtr);\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Ref<Surface>& surface) {\n    return stream << *surface.get();\n}\n\nstd::ostream& operator<<(std::ostream& stream, const Ref<TestExternalSurface>& surface) {\n    return stream << *surface.get();\n}\n\nstruct SurfacePresenterEntry {\n    Ref<Surface> surface;\n    Ref<TestBitmap> bitmap;\n};\n\nstruct PerformCleanupRequest {\n    bool shouldPurgeScratchResources;\n    std::chrono::seconds secondsNotUsed;\n};\n\nclass TestGraphicsContext : public BitmapGraphicsContext {\npublic:\n    void clearRequests() {\n        std::lock_guard<Valdi::Mutex> guard(_mutex);\n        _resourceCacheLimitBytesRequests.clear();\n        _performCleanupRequests.clear();\n    }\n\n    std::vector<size_t> getResourceCacheLimitRequests() const {\n        std::lock_guard<Valdi::Mutex> guard(_mutex);\n        return _resourceCacheLimitBytesRequests;\n    }\n\n    std::vector<PerformCleanupRequest> getPerformCleanupRequests() const {\n        std::lock_guard<Valdi::Mutex> guard(_mutex);\n        return _performCleanupRequests;\n    }\n\n    void setResourceCacheLimit(size_t resourceCacheLimitBytes) override {\n        std::lock_guard<Valdi::Mutex> guard(_mutex);\n        _resourceCacheLimitBytesRequests.emplace_back(resourceCacheLimitBytes);\n    }\n\n    void performCleanup(bool shouldPurgeScratchResources, std::chrono::seconds secondsNotUsed) override {\n        PerformCleanupRequest cleanUpRequest;\n        cleanUpRequest.shouldPurgeScratchResources = shouldPurgeScratchResources;\n        cleanUpRequest.secondsNotUsed = secondsNotUsed;\n\n        std::lock_guard<Valdi::Mutex> guard(_mutex);\n        _performCleanupRequests.emplace_back(cleanUpRequest);\n    }\n\nprivate:\n    mutable Valdi::Mutex _mutex;\n    std::vector<size_t> _resourceCacheLimitBytesRequests;\n    std::vector<PerformCleanupRequest> _performCleanupRequests;\n};\n\nclass TestSurfacePresenterManager : public SurfacePresenterManager {\npublic:\n    TestSurfacePresenterManager() : _graphicsContext(makeShared<TestGraphicsContext>()) {}\n\n    ~TestSurfacePresenterManager() override = default;\n\n    const Ref<TestGraphicsContext>& getGraphicsContext() const {\n        return _graphicsContext;\n    }\n\n    virtual Ref<TestBitmap> createBitmap() {\n        return makeShared<SinglePixelBitmap>();\n    }\n\n    Ref<DrawableSurface> createDrawableSurface(const Ref<TestBitmap>& bitmap) {\n        return _graphicsContext->createBitmapSurface(bitmap);\n    }\n\n    Ref<DrawableSurface> createPresenterWithDrawableSurface(SurfacePresenterId id, size_t zIndex) override {\n        auto bitmap = createBitmap();\n        auto surface = createDrawableSurface(bitmap);\n\n        auto& entry = _surfacePresenters[id];\n        entry.surface = surface;\n        entry.bitmap = bitmap;\n\n        insertSurface(surface, zIndex);\n\n        return surface;\n    }\n\n    void createPresenterForExternalSurface(SurfacePresenterId id,\n                                           size_t zIndex,\n                                           ExternalSurface& externalSurface) override {\n        auto surface = Ref<Surface>(&externalSurface);\n        _surfacePresenters[id].surface = surface;\n\n        insertSurface(surface, zIndex);\n    }\n\n    void setSurfacePresenterZIndex(SurfacePresenterId id, size_t zIndex) override {\n        auto surface = _surfacePresenters[id].surface;\n        SC_ASSERT(surface != nullptr);\n\n        tryRemoveSurface(*surface);\n        insertSurface(surface, zIndex);\n    }\n\n    void setExternalSurfacePresenterState(SurfacePresenterId id,\n                                          const ExternalSurfacePresenterState& presenterState,\n                                          const ExternalSurfacePresenterState* previousPresenterState) override {\n        auto surface = Valdi::castOrNull<TestExternalSurface>(_surfacePresenters[id].surface);\n        SC_ASSERT(surface != nullptr);\n\n        surface->presenterState = presenterState;\n    }\n\n    void removeSurfacePresenter(SurfacePresenterId id) override {\n        auto surface = _surfacePresenters[id].surface;\n        SC_ASSERT(surface != nullptr);\n\n        _surfacePresenters.erase(id);\n\n        removeSurface(*surface);\n    }\n\n    std::optional<SurfacePresenterEntry> getPresenter(size_t zIndex) const {\n        if (zIndex >= _surfaces.size()) {\n            return std::nullopt;\n        }\n\n        const auto& surface = _surfaces[zIndex];\n\n        for (const auto& it : _surfacePresenters) {\n            if (it.second.surface == surface) {\n                return {it.second};\n            }\n        }\n\n        return std::nullopt;\n    }\n\n    Ref<TestBitmap> getSurfaceBitmap(size_t zIndex) {\n        auto presenter = getPresenter(zIndex);\n        if (!presenter) {\n            return nullptr;\n        }\n        return presenter.value().bitmap;\n    }\n\n    Ref<SinglePixelBitmap> getSurfaceSinglePixelBitmap(size_t zIndex) {\n        return Valdi::castOrNull<SinglePixelBitmap>(getSurfaceBitmap(zIndex));\n    }\n\n    void removeSurface(Surface& surface) {\n        auto removed = tryRemoveSurface(surface);\n        SC_ASSERT(removed);\n    }\n\n    const std::vector<Ref<Surface>>& getSurfaces() const {\n        return _surfaces;\n    }\n\nprivate:\n    Ref<TestGraphicsContext> _graphicsContext;\n    Valdi::FlatMap<SurfacePresenterId, SurfacePresenterEntry> _surfacePresenters;\n    std::vector<Ref<Surface>> _surfaces;\n\n    bool tryRemoveSurface(Surface& surface) {\n        auto it = _surfaces.begin();\n        while (it != _surfaces.end()) {\n            if (it->get() == &surface) {\n                _surfaces.erase(it);\n                return true;\n            }\n            it++;\n        }\n\n        return false;\n    }\n\n    void insertSurface(const Ref<Surface>& surface, size_t zIndex) {\n        SC_ASSERT(zIndex <= _surfaces.size());\n        SC_ASSERT(!tryRemoveSurface(*surface));\n        _surfaces.insert(_surfaces.begin() + zIndex, surface);\n    }\n};\n\nclass TestDelayedSurfacePresenterManager : public TestSurfacePresenterManager {\n    Ref<DrawableSurface> createPresenterWithDrawableSurface(SurfacePresenterId id, size_t zIndex) override {\n        TestSurfacePresenterManager::createPresenterWithDrawableSurface(id, zIndex);\n        return nullptr;\n    }\n};\n\nclass Test4PixelsBitmapSurfacePresenterManager : public TestSurfacePresenterManager {\npublic:\n    Ref<TestBitmap> createBitmap() override {\n        return makeShared<TestBitmap>(4, 4);\n    }\n};\n\nstruct TestDrawLooperEntryListener : public DrawLooperEntryListener {\n    SurfacePresenterId presenterIdSequence = 0;\n\n    SurfacePresenterId createSurfacePresenterId() override {\n        return ++presenterIdSequence;\n    }\n\n    void onNeedsProcessFrame(DrawLooperEntry& entry) override {}\n\n    void onDidDraw(DrawLooperEntry& entry,\n                   const Ref<DisplayList>& displayList,\n                   const CompositorPlaneList* planeList) override {}\n};\n\nstruct DrawLooperTestContainer {\n    Ref<Resources> resources;\n    Ref<TestFrameScheduler> frameScheduler;\n    Ref<DrawLooper> drawLooper;\n    Ref<LayerRoot> layerRoot;\n\n    DrawLooperTestContainer() {\n        resources = makeShared<Resources>(nullptr, 1.0f, ConsoleLogger::getLogger());\n\n        frameScheduler = makeShared<TestFrameScheduler>();\n        drawLooper = makeShared<DrawLooper>(frameScheduler, resources->getLogger());\n\n        layerRoot = makeLayerRoot();\n    }\n\n    Ref<TestSurfacePresenterManager> addLayerRootToLooper(const Ref<LayerRoot>& layerRoot) {\n        auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n        drawLooper->addLayerRoot(layerRoot, surfacePresenterManager, false);\n        return surfacePresenterManager;\n    }\n\n    Ref<LayerRoot> makeLayerRoot() const {\n        auto contentLayer = makeShared<Layer>(resources);\n        contentLayer->setBackgroundColor(Color::black());\n        auto layerRoot = makeShared<LayerRoot>(resources);\n        layerRoot->setContentLayer(contentLayer, ContentLayerSizingModeMatchSize);\n        layerRoot->setSize(Size::make(1.0f, 1.0f), 1.0);\n        return layerRoot;\n    }\n};\n\nTEST(DrawLooper, addRemoveListenerOnLayerRoot) {\n    DrawLooperTestContainer container;\n\n    ASSERT_FALSE(container.layerRoot->getListener() != nullptr);\n\n    container.addLayerRootToLooper(container.layerRoot);\n\n    ASSERT_TRUE(container.layerRoot->getListener() != nullptr);\n\n    container.drawLooper->removeLayerRoot(container.layerRoot);\n\n    ASSERT_FALSE(container.layerRoot->getListener() != nullptr);\n}\n\nTEST(DrawLooper, schedulesProcessFramesOnLayerUpdates) {\n    DrawLooperTestContainer container;\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n\n    container.addLayerRootToLooper(container.layerRoot);\n\n    ASSERT_TRUE(container.layerRoot->needsProcessFrame());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_FALSE(container.layerRoot->needsProcessFrame());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::white());\n    container.frameScheduler->advanceTime(1.0);\n\n    ASSERT_TRUE(container.layerRoot->needsProcessFrame());\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_FALSE(container.layerRoot->needsProcessFrame());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n}\n\nTEST(DrawLooper, processesFrameAgainWhenSwitchingContentLayer) {\n    DrawLooperTestContainer container;\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n\n    container.addLayerRootToLooper(container.layerRoot);\n\n    ASSERT_TRUE(container.layerRoot->needsProcessFrame());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_FALSE(container.layerRoot->needsProcessFrame());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n\n    auto contentLayer = container.layerRoot->getContentLayer();\n    container.layerRoot->setContentLayer(nullptr, ContentLayerSizingModeMatchSize);\n\n    ASSERT_TRUE(container.layerRoot->needsProcessFrame());\n\n    container.frameScheduler->advanceTime(1.0);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_FALSE(container.layerRoot->needsProcessFrame());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n\n    container.layerRoot->setContentLayer(contentLayer, ContentLayerSizingModeMatchSize);\n    container.frameScheduler->advanceTime(1.0);\n\n    ASSERT_TRUE(container.layerRoot->needsProcessFrame());\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_FALSE(container.layerRoot->needsProcessFrame());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n}\n\nTEST(DrawLooper, scheduleProcessFramesOnceForAllLayers) {\n    DrawLooperTestContainer container;\n\n    ASSERT_EQ(static_cast<size_t>(0), container.frameScheduler->getMainThreadCallbacksSize());\n\n    container.addLayerRootToLooper(container.layerRoot);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::white());\n\n    auto newLayerRoot = container.makeLayerRoot();\n    container.addLayerRootToLooper(newLayerRoot);\n\n    ASSERT_EQ(static_cast<size_t>(1), container.frameScheduler->getMainThreadCallbacksSize());\n\n    ASSERT_TRUE(container.layerRoot->needsProcessFrame());\n    ASSERT_TRUE(newLayerRoot->needsProcessFrame());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_FALSE(container.layerRoot->needsProcessFrame());\n    ASSERT_FALSE(newLayerRoot->needsProcessFrame());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n}\n\nTEST(DrawLooper, repeatedlyProcessesFramesWhenLayerNeedsProcessFrame) {\n    DrawLooperTestContainer container;\n\n    container.addLayerRootToLooper(container.layerRoot);\n\n    auto animation =\n        Valdi::makeShared<Animation>(Duration(1.0), InterpolationFunctions::linear(), [](Layer& view, double ratio) {\n            view.setScaleX(static_cast<Scalar>(ratio));\n            view.setScaleY(static_cast<Scalar>(ratio));\n        });\n\n    container.layerRoot->getContentLayer()->addAnimation(STRING_LITERAL(\"scale\"), animation);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_EQ(static_cast<Scalar>(0.0f), container.layerRoot->getContentLayer()->getScaleX());\n    ASSERT_EQ(static_cast<Scalar>(0.0f), container.layerRoot->getContentLayer()->getScaleY());\n\n    container.frameScheduler->advanceTime(0.5);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_EQ(static_cast<Scalar>(0.5f), container.layerRoot->getContentLayer()->getScaleX());\n    ASSERT_EQ(static_cast<Scalar>(0.5f), container.layerRoot->getContentLayer()->getScaleY());\n\n    container.frameScheduler->advanceTime(0.5);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_EQ(static_cast<Scalar>(1.0f), container.layerRoot->getContentLayer()->getScaleX());\n    ASSERT_EQ(static_cast<Scalar>(1.0f), container.layerRoot->getContentLayer()->getScaleY());\n\n    container.frameScheduler->advanceTime(0.5);\n\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n};\n\nTEST(DrawLooper, schedulesDraw) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = container.addLayerRootToLooper(container.layerRoot);\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    auto pixelBitmap = surfacePresenterManager->getSurfaceSinglePixelBitmap(0);\n\n    ASSERT_TRUE(pixelBitmap != nullptr);\n\n    ASSERT_EQ(Color::black(), pixelBitmap->getPixel());\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    container.frameScheduler->advanceTime(1.0);\n\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::red());\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(Color::red(), pixelBitmap->getPixel());\n\n    container.frameScheduler->advanceTime(1.0);\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n}\n\nTEST(DrawLooper, redrawsOnDrawableSurfaceChange) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestDelayedSurfacePresenterManager>();\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, false);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    auto pixelBitmap = surfacePresenterManager->getSurfaceSinglePixelBitmap(0);\n\n    ASSERT_TRUE(pixelBitmap != nullptr);\n\n    ASSERT_EQ(Color::white(), pixelBitmap->getPixel());\n\n    container.drawLooper->setDrawableSurfaceOfLayerRootForPresenterId(\n        *container.layerRoot, 1, surfacePresenterManager->createDrawableSurface(pixelBitmap));\n\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(Color::black(), pixelBitmap->getPixel());\n\n    pixelBitmap->setPixel(Color::red());\n    auto newPixelBitmap = Valdi::makeShared<SinglePixelBitmap>();\n\n    container.drawLooper->setDrawableSurfaceOfLayerRootForPresenterId(\n        *container.layerRoot, 1, surfacePresenterManager->createDrawableSurface(newPixelBitmap));\n\n    ASSERT_EQ(Color::white(), newPixelBitmap->getPixel());\n\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(Color::red(), pixelBitmap->getPixel());\n    ASSERT_EQ(Color::black(), newPixelBitmap->getPixel());\n\n    container.drawLooper->setDrawableSurfaceOfLayerRootForPresenterId(*container.layerRoot, 1, nullptr);\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n}\n\nTEST(DrawLooper, redrawsWhenFrameReceivedDuringDraw) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = container.addLayerRootToLooper(container.layerRoot);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::blue());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    auto pixelBitmap = surfacePresenterManager->getSurfaceSinglePixelBitmap(0);\n\n    ASSERT_TRUE(pixelBitmap != nullptr);\n\n    bool didUpdate = false;\n\n    pixelBitmap->setOnLockCallback([&]() {\n        if (didUpdate) {\n            return;\n        }\n        didUpdate = true;\n        // Update the tree while drawing to simulate a UI thread update while the drawer is drawing\n        container.layerRoot->getContentLayer()->setBackgroundColor(Color::red());\n        container.frameScheduler->advanceTime(1.0);\n        ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    });\n\n    ASSERT_EQ(Color::blue(), pixelBitmap->getPixel());\n\n    container.frameScheduler->advanceTime(1.0);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::black());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(Color::black(), pixelBitmap->getPixel());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(Color::red(), pixelBitmap->getPixel());\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n}\n\nTEST(DrawLooper, redrawsWhenRemovingAndReaddingLayerRoot) {\n    DrawLooperTestContainer container;\n\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::blue());\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, true);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(1), surfacePresenterManager->getSurfaces().size());\n\n    container.frameScheduler->advanceTime(1.0);\n    container.drawLooper->removeLayerRoot(container.layerRoot);\n\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(0), surfacePresenterManager->getSurfaces().size());\n\n    container.frameScheduler->advanceTime(1.0);\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, false);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(1), surfacePresenterManager->getSurfaces().size());\n}\n\nTEST(DrawLooper, canSplitDrawingWhenUsingExternalSurface) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<Test4PixelsBitmapSurfacePresenterManager>();\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, false);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::blue());\n\n    auto beforeSiblingLayer = makeLayer<Layer>(container.resources);\n    beforeSiblingLayer->setBackgroundColor(Color::green());\n    beforeSiblingLayer->setFrame(Rect::makeXYWH(1, 1, 1, 1));\n\n    auto externalLayer = makeLayer<ExternalLayer>(container.resources);\n    externalLayer->setFrame(Rect::makeXYWH(1, 1, 2, 2));\n\n    auto afterSiblingLayer = makeLayer<Layer>(container.resources);\n    afterSiblingLayer->setBackgroundColor(Color::red());\n    afterSiblingLayer->setFrame(Rect::makeXYWH(2, 2, 1, 1));\n\n    container.layerRoot->getContentLayer()->addChild(beforeSiblingLayer);\n    container.layerRoot->getContentLayer()->addChild(externalLayer);\n    container.layerRoot->getContentLayer()->addChild(afterSiblingLayer);\n\n    container.layerRoot->setSize(Size::make(4, 4), 1);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    auto backgroundBitmap = surfacePresenterManager->getSurfaceBitmap(0);\n    SC_ASSERT(backgroundBitmap != nullptr);\n\n    // Since no surfaces are set, the background bitmap should have all the content in it\n\n    ASSERT_EQ(*BitmapBuilder(4, 4)\n                   .row({Color::blue(), Color::blue(), Color::blue(), Color::blue()})\n                   .row({\n                       Color::blue(),\n                       Color::green(),\n                       Color::blue(),\n                       Color::blue(),\n                   })\n                   .row({\n\n                       Color::blue(),\n                       Color::blue(),\n                       Color::red(),\n                       Color::blue(),\n                   })\n                   .row({\n                       Color::blue(),\n                       Color::blue(),\n                       Color::blue(),\n                       Color::blue(),\n                   })\n                   .build(),\n              *backgroundBitmap);\n\n    auto foregroundBitmap = surfacePresenterManager->getSurfaceBitmap(1);\n    ASSERT_TRUE(foregroundBitmap == nullptr);\n\n    auto externalSurface = makeShared<TestExternalSurface>();\n    externalLayer->setExternalSurface(externalSurface);\n\n    container.frameScheduler->advanceTime(1.0);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    // Drawing should be synchronous when an external surface is being updated\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(3), surfacePresenterManager->getSurfaces().size());\n    ASSERT_EQ(externalSurface, surfacePresenterManager->getSurfaces()[1]);\n\n    foregroundBitmap = surfacePresenterManager->getSurfaceBitmap(2);\n    ASSERT_TRUE(foregroundBitmap != nullptr);\n\n    // background should not have the red color from the sibling after the surface\n    ASSERT_EQ(*BitmapBuilder(4, 4)\n                   .row({\n                       Color::blue(),\n                       Color::blue(),\n                       Color::blue(),\n                       Color::blue(),\n                   })\n                   .row({\n                       Color::blue(),\n                       Color::green(),\n                       Color::blue(),\n                       Color::blue(),\n                   })\n                   .row({\n                       Color::blue(),\n                       Color::blue(),\n                       Color::blue(),\n                       Color::blue(),\n                   })\n                   .row({\n                       Color::blue(),\n                       Color::blue(),\n                       Color::blue(),\n                       Color::blue(),\n                   })\n                   .build(),\n              *backgroundBitmap);\n\n    // red color should be set\n    ASSERT_EQ(*BitmapBuilder(4, 4)\n                   .row({\n                       Color::transparent(),\n                       Color::transparent(),\n                       Color::transparent(),\n                       Color::transparent(),\n                   })\n                   .row({\n                       Color::transparent(),\n                       Color::transparent(),\n                       Color::transparent(),\n                       Color::transparent(),\n                   })\n                   .row({\n                       Color::transparent(),\n                       Color::transparent(),\n                       Color::red(),\n                       Color::transparent(),\n                   })\n                   .row({\n                       Color::transparent(),\n                       Color::transparent(),\n                       Color::transparent(),\n                       Color::transparent(),\n                   })\n                   .build(),\n              *foregroundBitmap);\n\n    ASSERT_TRUE(externalSurface->presenterState);\n\n    Matrix expectedTransform;\n\n    ASSERT_EQ(Rect::makeXYWH(1, 1, 2, 2), externalSurface->presenterState.value().frame);\n    ASSERT_EQ(expectedTransform, externalSurface->presenterState.value().transform);\n    ASSERT_EQ(1.0, externalSurface->presenterState.value().opacity);\n}\n\nTEST(DrawLooper, drawsSynchronouslyWhenUpdatingPresenters) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, false);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::blue());\n\n    auto externalLayer = makeLayer<ExternalLayer>(container.resources);\n    auto externalSurface = makeShared<TestExternalSurface>();\n    externalLayer->setExternalSurface(externalSurface);\n    externalLayer->setFrame(Rect::makeXYWH(0, 0, 1, 1));\n\n    container.layerRoot->getContentLayer()->addChild(externalLayer);\n\n    container.layerRoot->setSize(Size::make(1, 1), 1);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_EQ(static_cast<size_t>(2), surfacePresenterManager->getSurfaces().size());\n    auto pixelBitmap = surfacePresenterManager->getSurfaceSinglePixelBitmap(0);\n    ASSERT_TRUE(pixelBitmap != nullptr);\n    ASSERT_EQ(externalSurface, surfacePresenterManager->getSurfaces()[1]);\n\n    // Color should have been applied immediately given that we have an external surface\n    ASSERT_EQ(Color::blue(), pixelBitmap->getPixel());\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    container.frameScheduler->advanceTime(1.0);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::red());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    // Since we are not updating presenters, the update should be async\n    ASSERT_EQ(Color::blue(), pixelBitmap->getPixel());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(Color::red(), pixelBitmap->getPixel());\n\n    container.frameScheduler->advanceTime(1.0);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::white());\n    externalLayer->setOpacity(0.5);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    // Color should have been applied immediately, as the external layer was updated\n    ASSERT_EQ(Color::white(), pixelBitmap->getPixel());\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    auto foregroundLayer = makeLayer<Layer>(container.resources);\n    foregroundLayer->setBackgroundColor(Color::green());\n    foregroundLayer->setFrame(Rect::makeXYWH(0, 0, 1, 1));\n\n    container.frameScheduler->advanceTime(1.0);\n    container.layerRoot->getContentLayer()->addChild(foregroundLayer);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::blue());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    // When just adding a Drawable presenter, drawing should stay async\n    ASSERT_EQ(Color::white(), pixelBitmap->getPixel());\n\n    ASSERT_EQ(static_cast<size_t>(3), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(Color::blue(), pixelBitmap->getPixel());\n\n    container.frameScheduler->advanceTime(1.0);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::red());\n    foregroundLayer->removeFromParent();\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    // When removing a Drawable presenter, drawing should be sync\n    ASSERT_EQ(Color::red(), pixelBitmap->getPixel());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(2), surfacePresenterManager->getSurfaces().size());\n\n    container.frameScheduler->advanceTime(1.0);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::blue());\n    externalLayer->removeFromParent();\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    // When removing an external layer, drawing should be sync\n    ASSERT_EQ(Color::blue(), pixelBitmap->getPixel());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(1), surfacePresenterManager->getSurfaces().size());\n}\n\nTEST(DrawLooper, drawsAsynchronouslyWhenUpdatingPresenters) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    // Specify to disallow sync drawing here.\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, true);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::blue());\n\n    auto externalLayer = makeLayer<ExternalLayer>(container.resources);\n    auto externalSurface = makeShared<TestExternalSurface>();\n    externalLayer->setExternalSurface(externalSurface);\n    externalLayer->setFrame(Rect::makeXYWH(0, 0, 1, 1));\n\n    container.layerRoot->getContentLayer()->addChild(externalLayer);\n\n    container.layerRoot->setSize(Size::make(1, 1), 1);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_EQ(static_cast<size_t>(2), surfacePresenterManager->getSurfaces().size());\n    auto pixelBitmap = surfacePresenterManager->getSurfaceSinglePixelBitmap(0);\n    ASSERT_TRUE(pixelBitmap != nullptr);\n    ASSERT_EQ(externalSurface, surfacePresenterManager->getSurfaces()[1]);\n\n    // Color should NOT have been applied immediately given that we specified to disallow sync drawing\n    ASSERT_EQ(Color::white(), pixelBitmap->getPixel());\n\n    // Run a vsync which should then update the surface\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n    pixelBitmap = surfacePresenterManager->getSurfaceSinglePixelBitmap(0);\n    ASSERT_EQ(Color::blue(), pixelBitmap->getPixel());\n}\n\nTEST(DrawLooper, drawsSynchronouslyWhenReceivingDrawableSurfaceAfterUpdatingPresenters) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, false);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::blue());\n\n    auto externalLayer = makeLayer<ExternalLayer>(container.resources);\n    externalLayer->setExternalSurface(makeShared<TestExternalSurface>());\n    externalLayer->setFrame(Rect::makeXYWH(0, 0, 1, 1));\n\n    container.layerRoot->getContentLayer()->addChild(externalLayer);\n\n    container.layerRoot->setSize(Size::make(1, 1), 1);\n\n    auto foregroundLayer = makeLayer<Layer>(container.resources);\n    foregroundLayer->setBackgroundColor(Color::green());\n    foregroundLayer->setFrame(Rect::makeXYWH(0, 0, 1, 1));\n\n    container.layerRoot->getContentLayer()->addChild(foregroundLayer);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    // Drawing should have been synchronous\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(3), surfacePresenterManager->getSurfaces().size());\n    auto presenter = surfacePresenterManager->getPresenter(0);\n    ASSERT_TRUE(presenter.has_value());\n    auto pixelBitmap = surfacePresenterManager->getSurfaceSinglePixelBitmap(0);\n    ASSERT_TRUE(pixelBitmap != nullptr);\n\n    ASSERT_EQ(Color::blue(), pixelBitmap->getPixel());\n\n    container.frameScheduler->advanceTime(1.0);\n\n    externalLayer->setExternalSurface(nullptr);\n\n    // Explicitly remove the DrawableSurface attached to the background presenter\n    container.drawLooper->setDrawableSurfaceOfLayerRootForPresenterId(*container.layerRoot, 1, nullptr);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    // No VSync should have happened since none of the drawable presenters have a surface\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    // Since the external surface was removed from the ExternalLayer, it should have resolved to 1 drawable presenter.\n    ASSERT_EQ(static_cast<size_t>(1), surfacePresenterManager->getSurfaces().size());\n\n    // Surface should not have been updated\n    ASSERT_EQ(Color::blue(), pixelBitmap->getPixel());\n\n    auto surface = Valdi::castOrNull<DrawableSurface>(presenter.value().surface);\n    ASSERT_TRUE(surface != nullptr);\n    container.drawLooper->setDrawableSurfaceOfLayerRootForPresenterId(*container.layerRoot, 1, surface);\n\n    ASSERT_FALSE(container.frameScheduler->runNextMainThreadCallback());\n    // It should have drawn synchronously, without scheduling a vsync\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    // Color should have been updated by setting the DrawableSurface\n    // The green comes from the foreground layer covering the background layer\n    ASSERT_EQ(Color::green(), pixelBitmap->getPixel());\n}\n\nTEST(DrawLooper, canConfigureManagedGraphicsContext) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    auto graphicsContext = surfacePresenterManager->getGraphicsContext();\n\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(0), graphicsContext->getResourceCacheLimitRequests().size());\n    ASSERT_EQ(static_cast<size_t>(0), graphicsContext->getPerformCleanupRequests().size());\n\n    container.drawLooper->appendManagedGraphicsContext(surfacePresenterManager->getGraphicsContext());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(1), graphicsContext->getResourceCacheLimitRequests().size());\n    ASSERT_EQ(static_cast<size_t>(0), graphicsContext->getPerformCleanupRequests().size());\n\n    ASSERT_EQ(static_cast<size_t>(134217728), graphicsContext->getResourceCacheLimitRequests()[0]);\n}\n\nTEST(DrawLooper, performCleanUpOnGraphicsContextWhenEnteringBackground) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    auto graphicsContext = surfacePresenterManager->getGraphicsContext();\n\n    container.drawLooper->appendManagedGraphicsContext(surfacePresenterManager->getGraphicsContext());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n    graphicsContext->clearRequests();\n\n    container.drawLooper->onApplicationEnteringBackground();\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(2), graphicsContext->getResourceCacheLimitRequests().size());\n    ASSERT_EQ(static_cast<size_t>(1), graphicsContext->getPerformCleanupRequests().size());\n\n    ASSERT_EQ(static_cast<size_t>(33554432), graphicsContext->getResourceCacheLimitRequests()[0]);\n    ASSERT_EQ(static_cast<size_t>(134217728), graphicsContext->getResourceCacheLimitRequests()[1]);\n    ASSERT_TRUE(graphicsContext->getPerformCleanupRequests()[0].shouldPurgeScratchResources);\n    ASSERT_EQ(std::chrono::seconds(0), graphicsContext->getPerformCleanupRequests()[0].secondsNotUsed);\n}\n\nTEST(DrawLooper, performCleanUpOnGraphicsContextOnLowMemory) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    auto graphicsContext = surfacePresenterManager->getGraphicsContext();\n\n    container.drawLooper->appendManagedGraphicsContext(surfacePresenterManager->getGraphicsContext());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n    graphicsContext->clearRequests();\n\n    container.drawLooper->onApplicationIsInLowMemory();\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(2), graphicsContext->getResourceCacheLimitRequests().size());\n    ASSERT_EQ(static_cast<size_t>(1), graphicsContext->getPerformCleanupRequests().size());\n\n    ASSERT_EQ(static_cast<size_t>(0), graphicsContext->getResourceCacheLimitRequests()[0]);\n    ASSERT_EQ(static_cast<size_t>(134217728), graphicsContext->getResourceCacheLimitRequests()[1]);\n    ASSERT_TRUE(graphicsContext->getPerformCleanupRequests()[0].shouldPurgeScratchResources);\n    ASSERT_EQ(std::chrono::seconds(0), graphicsContext->getPerformCleanupRequests()[0].secondsNotUsed);\n}\n\nTEST(DrawLooper, performCleanUpOnGraphicsContextAfterDraw) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    auto graphicsContext = surfacePresenterManager->getGraphicsContext();\n\n    container.drawLooper->appendManagedGraphicsContext(surfacePresenterManager->getGraphicsContext());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n    graphicsContext->clearRequests();\n\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, false);\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(0), graphicsContext->getResourceCacheLimitRequests().size());\n    ASSERT_EQ(static_cast<size_t>(1), graphicsContext->getPerformCleanupRequests().size());\n\n    ASSERT_FALSE(graphicsContext->getPerformCleanupRequests()[0].shouldPurgeScratchResources);\n    ASSERT_EQ(std::chrono::seconds(10), graphicsContext->getPerformCleanupRequests()[0].secondsNotUsed);\n\n    container.frameScheduler->advanceTime(1.0);\n\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::red());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    ASSERT_EQ(static_cast<size_t>(0), graphicsContext->getResourceCacheLimitRequests().size());\n    ASSERT_EQ(static_cast<size_t>(2), graphicsContext->getPerformCleanupRequests().size());\n\n    ASSERT_FALSE(graphicsContext->getPerformCleanupRequests()[1].shouldPurgeScratchResources);\n    ASSERT_EQ(std::chrono::seconds(10), graphicsContext->getPerformCleanupRequests()[1].secondsNotUsed);\n}\n\nTEST(DrawLooper, destroysPresentersOnRemove) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = container.addLayerRootToLooper(container.layerRoot);\n\n    ASSERT_TRUE(container.layerRoot->needsProcessFrame());\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n\n    ASSERT_EQ(static_cast<size_t>(1), surfacePresenterManager->getSurfaces().size());\n\n    container.drawLooper->removeLayerRoot(container.layerRoot);\n\n    ASSERT_EQ(static_cast<size_t>(0), surfacePresenterManager->getSurfaces().size());\n}\n\nTEST(DrawLooper, doesNotDrawWhenInBackground) {\n    DrawLooperTestContainer container;\n\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    auto graphicsContext = surfacePresenterManager->getGraphicsContext();\n\n    container.drawLooper->appendManagedGraphicsContext(surfacePresenterManager->getGraphicsContext());\n\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n    graphicsContext->clearRequests();\n\n    container.drawLooper->addLayerRoot(container.layerRoot, surfacePresenterManager, false);\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    container.drawLooper->onApplicationEnteringBackground();\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    container.frameScheduler->advanceTime(1.0);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::red());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    // No VSync callbacks should be attempted when we are in background\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    container.frameScheduler->advanceTime(2.0);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::green());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_FALSE(container.frameScheduler->runNextVSyncCallback());\n\n    container.drawLooper->onApplicationEnteringForeground();\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    // Should redraw after enterering foreground if we had a pending draw\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n\n    container.frameScheduler->advanceTime(3.0);\n    container.layerRoot->getContentLayer()->setBackgroundColor(Color::red());\n\n    ASSERT_TRUE(container.frameScheduler->runNextMainThreadCallback());\n    ASSERT_TRUE(container.frameScheduler->runNextVSyncCallback());\n}\n\nvoid updateSurfacePresenters(const Ref<DrawLooperEntry>& entry, const CompositorPlaneList& planeList) {\n    entry->updateSurfacePresenters(planeList);\n    // Check that the presenter states are correct\n\n    const auto& surfacePresenters = entry->getSurfacePresenters();\n\n    ASSERT_EQ(planeList.getPlanesCount(), surfacePresenters.size());\n\n    size_t displayListPlaneIndex = 0;\n    for (const auto& surfacePresenter : surfacePresenters) {\n        ASSERT_EQ(displayListPlaneIndex, surfacePresenter.getDisplayListPlaneIndex());\n        if (surfacePresenter.isDrawable()) {\n            displayListPlaneIndex++;\n        }\n    }\n}\n\nTEST(DrawLooperEntry, canCreateDrawableSurfaces) {\n    DrawLooperTestContainer container;\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n    TestDrawLooperEntryListener listener;\n    auto entry = makeShared<DrawLooperEntry>(container.layerRoot, surfacePresenterManager, &listener);\n\n    CompositorPlaneList planeList;\n\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    planeList.appendDrawableSurface();\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n\n    updateSurfacePresenters(entry, planeList);\n\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(1), surfacePresenterManager->getSurfaces().size());\n\n    auto firstSurface = surfacePresenterManager->getSurfaces()[0];\n\n    planeList.appendDrawableSurface();\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n\n    updateSurfacePresenters(entry, planeList);\n\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(2), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_EQ(firstSurface, surfacePresenterManager->getSurfaces()[0]);\n    ASSERT_NE(firstSurface, surfacePresenterManager->getSurfaces()[1]);\n}\n\nTEST(DrawLooperEntry, destroysDanglingSurfaces) {\n    DrawLooperTestContainer container;\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n\n    TestDrawLooperEntryListener listener;\n    auto entry = makeShared<DrawLooperEntry>(container.layerRoot, surfacePresenterManager, &listener);\n\n    CompositorPlaneList planeList;\n\n    planeList.appendDrawableSurface();\n    planeList.appendDrawableSurface();\n    planeList.appendDrawableSurface();\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n\n    updateSurfacePresenters(entry, planeList);\n\n    ASSERT_EQ(static_cast<size_t>(3), surfacePresenterManager->getSurfaces().size());\n\n    auto firstSurface = surfacePresenterManager->getSurfaces()[0];\n    auto secondSurface = surfacePresenterManager->getSurfaces()[1];\n\n    planeList.removePlaneAtIndex(2);\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n\n    updateSurfacePresenters(entry, planeList);\n\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(2), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_EQ(firstSurface, surfacePresenterManager->getSurfaces()[0]);\n    ASSERT_EQ(secondSurface, surfacePresenterManager->getSurfaces()[1]);\n}\n\nTEST(DrawLooperEntry, canReuseSurfaces) {\n    DrawLooperTestContainer container;\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n\n    TestDrawLooperEntryListener listener;\n    auto entry = makeShared<DrawLooperEntry>(container.layerRoot, surfacePresenterManager, &listener);\n\n    auto externalSurface1 = makeShared<TestExternalSurface>();\n    auto externalSurface2 = makeShared<TestExternalSurface>();\n    auto externalSurfaceSnapshot1 = makeShared<ExternalSurfaceSnapshot>(externalSurface1);\n    auto externalSurfaceSnapshot2 = makeShared<ExternalSurfaceSnapshot>(externalSurface2);\n\n    CompositorPlaneList planeList;\n\n    planeList.appendDrawableSurface();\n    planeList.appendPlane(CompositorPlane(externalSurfaceSnapshot1, ExternalSurfacePresenterState()));\n    planeList.appendDrawableSurface();\n    planeList.appendPlane(CompositorPlane(externalSurfaceSnapshot2, ExternalSurfacePresenterState()));\n    planeList.appendDrawableSurface();\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n    updateSurfacePresenters(entry, planeList);\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(5), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_TRUE(castOrNull<DrawableSurface>(surfacePresenterManager->getSurfaces()[0]) != nullptr);\n    ASSERT_EQ(externalSurface1, surfacePresenterManager->getSurfaces()[1]);\n    ASSERT_TRUE(castOrNull<DrawableSurface>((surfacePresenterManager->getSurfaces()[2])) != nullptr);\n    ASSERT_EQ(externalSurface2, surfacePresenterManager->getSurfaces()[3]);\n    ASSERT_TRUE(castOrNull<DrawableSurface>((surfacePresenterManager->getSurfaces()[4])) != nullptr);\n\n    auto firstDrawableSurface = surfacePresenterManager->getSurfaces()[0];\n    auto secondDrawableSurface = surfacePresenterManager->getSurfaces()[2];\n    auto thirdDrawableSurface = surfacePresenterManager->getSurfaces()[4];\n\n    planeList.clear();\n\n    planeList.appendPlane(CompositorPlane(externalSurfaceSnapshot2, ExternalSurfacePresenterState()));\n    planeList.appendPlane(CompositorPlane(externalSurfaceSnapshot1, ExternalSurfacePresenterState()));\n    planeList.appendDrawableSurface();\n    planeList.appendDrawableSurface();\n    planeList.appendDrawableSurface();\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n    updateSurfacePresenters(entry, planeList);\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(5), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_EQ(externalSurface2, surfacePresenterManager->getSurfaces()[0]);\n    ASSERT_EQ(externalSurface1, surfacePresenterManager->getSurfaces()[1]);\n    ASSERT_EQ(firstDrawableSurface, surfacePresenterManager->getSurfaces()[2]);\n    ASSERT_EQ(secondDrawableSurface, surfacePresenterManager->getSurfaces()[3]);\n    ASSERT_EQ(thirdDrawableSurface, surfacePresenterManager->getSurfaces()[4]);\n\n    planeList.clear();\n\n    planeList.appendPlane(CompositorPlane(externalSurfaceSnapshot2, ExternalSurfacePresenterState()));\n    planeList.appendDrawableSurface();\n    planeList.appendDrawableSurface();\n    planeList.appendPlane(CompositorPlane(externalSurfaceSnapshot1, ExternalSurfacePresenterState()));\n    planeList.appendDrawableSurface();\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n    updateSurfacePresenters(entry, planeList);\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(5), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_EQ(externalSurface2, surfacePresenterManager->getSurfaces()[0]);\n    ASSERT_EQ(firstDrawableSurface, surfacePresenterManager->getSurfaces()[1]);\n    ASSERT_EQ(secondDrawableSurface, surfacePresenterManager->getSurfaces()[2]);\n    ASSERT_EQ(externalSurface1, surfacePresenterManager->getSurfaces()[3]);\n    ASSERT_EQ(thirdDrawableSurface, surfacePresenterManager->getSurfaces()[4]);\n\n    planeList.clear();\n\n    planeList.appendDrawableSurface();\n    planeList.appendDrawableSurface();\n    planeList.appendDrawableSurface();\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n    updateSurfacePresenters(entry, planeList);\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(3), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_EQ(firstDrawableSurface, surfacePresenterManager->getSurfaces()[0]);\n    ASSERT_EQ(secondDrawableSurface, surfacePresenterManager->getSurfaces()[1]);\n    ASSERT_EQ(thirdDrawableSurface, surfacePresenterManager->getSurfaces()[2]);\n\n    planeList.appendPlane(CompositorPlane(externalSurfaceSnapshot1, ExternalSurfacePresenterState()));\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n\n    updateSurfacePresenters(entry, planeList);\n\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(4), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_EQ(firstDrawableSurface, surfacePresenterManager->getSurfaces()[0]);\n    ASSERT_EQ(secondDrawableSurface, surfacePresenterManager->getSurfaces()[1]);\n    ASSERT_EQ(thirdDrawableSurface, surfacePresenterManager->getSurfaces()[2]);\n    ASSERT_EQ(externalSurface1, surfacePresenterManager->getSurfaces()[3]);\n\n    planeList.insertPlane(CompositorPlane(externalSurfaceSnapshot2, ExternalSurfacePresenterState()), 1);\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n    updateSurfacePresenters(entry, planeList);\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_EQ(static_cast<size_t>(5), surfacePresenterManager->getSurfaces().size());\n\n    ASSERT_EQ(firstDrawableSurface, surfacePresenterManager->getSurfaces()[0]);\n    ASSERT_EQ(externalSurface2, surfacePresenterManager->getSurfaces()[1]);\n    ASSERT_EQ(secondDrawableSurface, surfacePresenterManager->getSurfaces()[2]);\n    ASSERT_EQ(thirdDrawableSurface, surfacePresenterManager->getSurfaces()[3]);\n    ASSERT_EQ(externalSurface1, surfacePresenterManager->getSurfaces()[4]);\n}\n\nTEST(DrawLooperEntry, detectsExternalSurfacePresenterStateChange) {\n    DrawLooperTestContainer container;\n    auto surfacePresenterManager = makeShared<TestSurfacePresenterManager>();\n\n    TestDrawLooperEntryListener listener;\n    auto entry = makeShared<DrawLooperEntry>(container.layerRoot, surfacePresenterManager, &listener);\n\n    auto externalSurface = makeShared<TestExternalSurface>();\n    auto externalSurfaceSnapshot = makeShared<ExternalSurfaceSnapshot>(externalSurface);\n\n    CompositorPlaneList planeList;\n\n    ExternalSurfacePresenterState presenterState;\n\n    planeList.appendDrawableSurface();\n    planeList.appendPlane(CompositorPlane(externalSurfaceSnapshot, presenterState));\n    planeList.appendDrawableSurface();\n\n    ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n    updateSurfacePresenters(entry, planeList);\n    ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n    ASSERT_TRUE(externalSurface->presenterState);\n    ASSERT_EQ(presenterState, externalSurface->presenterState.value());\n\n    auto updateAndCheck = [&]() {\n        ASSERT_NE(presenterState, externalSurface->presenterState.value());\n\n        planeList.getPlaneAtIndex(1) = CompositorPlane(externalSurfaceSnapshot, presenterState);\n\n        ASSERT_TRUE(entry->surfacePresentersNeedUpdate(planeList));\n        updateSurfacePresenters(entry, planeList);\n        ASSERT_FALSE(entry->surfacePresentersNeedUpdate(planeList));\n\n        ASSERT_EQ(presenterState, externalSurface->presenterState.value());\n    };\n\n    // Updating frame\n    presenterState.frame = Rect::makeXYWH(0, 0, 40, 40);\n\n    updateAndCheck();\n\n    // Updating transform\n    presenterState.transform.setScaleX(2.0);\n\n    updateAndCheck();\n\n    // Updating clipPath\n    presenterState.clipPath.addRect(Rect::makeXYWH(0, 0, 40, 40), true);\n\n    updateAndCheck();\n\n    // Updating opacity\n    presenterState.opacity = 0.5;\n    updateAndCheck();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/FlexboxLayer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"snap_drawing/cpp/Layers/FlexboxLayer.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nclass FlexboxLayerTests : public ::testing::Test {\nprotected:\n    void SetUp() override {\n        _resources = makeShared<Resources>(nullptr, 1.0f, ConsoleLogger::getLogger());\n\n        _layer = makeLayer<FlexboxLayer>(_resources);\n    }\n\n    void TearDown() override {\n        _layer = nullptr;\n    }\n\n    Ref<Resources> _resources;\n    Ref<FlexboxLayer> _layer;\n};\n\nTEST_F(FlexboxLayerTests, canLayoutNonFlexLayers) {\n    auto child1 = makeLayer<Layer>(_resources);\n    auto child2 = makeLayer<Layer>(_resources);\n    auto child3 = makeLayer<Layer>(_resources);\n\n    _layer->addChild(child1);\n    _layer->addChild(child2);\n    _layer->addChild(child3);\n\n    _layer->updateLayoutAttributes()\n        .setFlexDirection(YGFlexDirectionRow)\n        .setJustifyContent(YGJustifyCenter)\n        .setAlignItems(YGAlignCenter);\n\n    _layer->updateLayoutAttributesForLayer(child1)\n        .setWidth(FlexValue::point(16))\n        .setHeight(FlexValue::point(16))\n        .setMargin(YGEdgeRight, FlexValue::point(8));\n\n    _layer->updateLayoutAttributesForLayer(child2).setWidth(FlexValue::point(10)).setHeight(FlexValue::point(10));\n\n    _layer->updateLayoutAttributesForLayer(child3)\n        .setWidth(FlexValue::point(8))\n        .setHeight(FlexValue::point(8))\n        .setMargin(YGEdgeLeft, FlexValue::point(8));\n\n    _layer->setFrame(Rect::makeXYWH(0, 0, 50, 16));\n    _layer->layoutIfNeeded();\n\n    ASSERT_EQ(Rect::makeXYWH(0, 0, 16, 16), child1->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(24, 3, 10, 10), child2->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(42, 4, 8, 8), child3->getFrame());\n\n    _layer->updateLayoutAttributesForLayer(child1).setMargin(YGEdgeRight, FlexValue::point(4));\n\n    _layer->updateLayoutAttributesForLayer(child3)\n        .setMargin(YGEdgeLeft, FlexValue::point(6))\n        .setMargin(YGEdgeRight, FlexValue::point(6));\n\n    ASSERT_EQ(Rect::makeXYWH(0, 0, 16, 16), child1->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(24, 3, 10, 10), child2->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(42, 4, 8, 8), child3->getFrame());\n\n    _layer->layoutIfNeeded();\n\n    ASSERT_EQ(Rect::makeXYWH(0, 0, 16, 16), child1->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(20, 3, 10, 10), child2->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(36, 4, 8, 8), child3->getFrame());\n}\n\nTEST_F(FlexboxLayerTests, canLayoutFlexLayers) {\n    auto child1 = makeLayer<Layer>(_resources);\n    auto childLayout = makeLayer<FlexboxLayer>(_resources);\n\n    _layer->addChild(child1);\n    _layer->addChild(childLayout);\n\n    auto innerChild = makeLayer<Layer>(_resources);\n\n    childLayout->addChild(innerChild);\n\n    _layer->updateLayoutAttributes()\n        .setFlexDirection(YGFlexDirectionRow)\n        .setJustifyContent(YGJustifyCenter)\n        .setAlignItems(YGAlignCenter);\n\n    _layer->updateLayoutAttributesForLayer(child1)\n        .setWidth(FlexValue::point(10))\n        .setHeight(FlexValue::point(10))\n        .setMargin(YGEdgeRight, FlexValue::point(8));\n\n    _layer->updateLayoutAttributesForLayer(childLayout).setPadding(YGEdgeAll, FlexValue::point(4));\n\n    _layer->updateLayoutAttributesForLayer(innerChild).setWidth(FlexValue::point(8)).setHeight(FlexValue::point(8));\n\n    _layer->setFrame(Rect::makeXYWH(0, 0, 34, 16));\n    _layer->layoutIfNeeded();\n\n    ASSERT_EQ(Rect::makeXYWH(0, 3, 10, 10), child1->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(18, 0, 16, 16), childLayout->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(4, 4, 8, 8), innerChild->getFrame());\n\n    _layer->updateLayoutAttributesForLayer(innerChild).setWidth(FlexValue::point(1));\n\n    _layer->layoutIfNeeded();\n\n    ASSERT_EQ(Rect::makeXYWH(3, 3, 10, 10), child1->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(22, 0, 9, 16), childLayout->getFrame());\n    ASSERT_EQ(Rect::makeXYWH(4, 4, 1, 8), innerChild->getFrame());\n}\n\nTEST_F(FlexboxLayerTests, implementsSizeThatFits) {\n    auto child1 = makeLayer<Layer>(_resources);\n\n    _layer->addChild(child1);\n\n    _layer->updateLayoutAttributes().setFlexDirection(YGFlexDirectionRow);\n    ;\n\n    _layer->updateLayoutAttributesForLayer(child1).setWidth(FlexValue::point(16)).setHeight(FlexValue::point(8));\n\n    _layer->updateLayoutAttributesForLayer(_layer).setPadding(YGEdgeAll, FlexValue::point(8));\n\n    auto size =\n        _layer->sizeThatFits(Size::make(std::numeric_limits<Scalar>::max(), std::numeric_limits<Scalar>::max()));\n\n    ASSERT_EQ(Size::make(32, 24), size);\n}\n\nclass TestLayerWithSize : public Layer {\npublic:\n    explicit TestLayerWithSize(const Ref<Resources>& resources) : Layer(resources) {}\n\n    Size sizeThatFits(Size maxSize) override {\n        return _intrinsicContentSize;\n    }\n\n    void setIntrinsicContentSize(Size value) {\n        _intrinsicContentSize = value;\n    }\n\nprivate:\n    Size _intrinsicContentSize;\n};\n\nTEST_F(FlexboxLayerTests, respectsSizeThatFitsOnChildLayer) {\n    auto child = makeLayer<TestLayerWithSize>(_resources);\n\n    _layer->addChild(child);\n\n    _layer->updateLayoutAttributes().setFlexDirection(YGFlexDirectionRow);\n    ;\n\n    child->setIntrinsicContentSize(Size::make(4, 16));\n\n    _layer->updateLayoutAttributesForLayer(_layer).setPadding(YGEdgeAll, FlexValue::point(8));\n\n    auto size =\n        _layer->sizeThatFits(Size::make(std::numeric_limits<Scalar>::max(), std::numeric_limits<Scalar>::max()));\n\n    ASSERT_EQ(Size::make(20, 32), size);\n}\n\nTEST_F(FlexboxLayerTests, respectsSetNeedsLayout) {\n    auto child = makeLayer<TestLayerWithSize>(_resources);\n\n    _layer->addChild(child);\n\n    _layer->updateLayoutAttributes().setFlexDirection(YGFlexDirectionRow);\n    ;\n\n    child->setIntrinsicContentSize(Size::make(4, 16));\n\n    _layer->updateLayoutAttributesForLayer(_layer).setPadding(YGEdgeAll, FlexValue::point(8));\n\n    auto size =\n        _layer->sizeThatFits(Size::make(std::numeric_limits<Scalar>::max(), std::numeric_limits<Scalar>::max()));\n\n    ASSERT_EQ(Size::make(20, 32), size);\n\n    child->setIntrinsicContentSize(Size::make(6, 20));\n\n    size = _layer->sizeThatFits(Size::make(std::numeric_limits<Scalar>::max(), std::numeric_limits<Scalar>::max()));\n\n    // Shouldn't change until setNeedsLayout() is called\n    ASSERT_EQ(Size::make(20, 32), size);\n\n    child->setNeedsLayout();\n\n    size = _layer->sizeThatFits(Size::make(std::numeric_limits<Scalar>::max(), std::numeric_limits<Scalar>::max()));\n\n    ASSERT_EQ(Size::make(22, 36), size);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/ImageBitmap_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestBitmap.hpp\"\n#include \"snap_drawing/cpp/Utils/Image.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(ImageBitmap, testBitmapFullConversion) {\n    auto bitmap = createTestBitmap();\n    auto imageResult = Image::makeFromBitmap(bitmap, true);\n    ASSERT_FALSE(imageResult.failure()) << imageResult.error().getMessage();\n\n    auto image = imageResult.value();\n    auto returnedBitmap = image->getBitmap();\n    auto returnedInfo = returnedBitmap->getInfo();\n    ASSERT_TRUE(returnedInfo == bitmap->getInfo());\n\n    const auto pixelDataSize = returnedInfo.height * returnedInfo.rowBytes;\n    auto bitmapData = static_cast<uint8_t*>(bitmap->lockBytes());\n    auto returnedBitmapData = static_cast<uint8_t*>(returnedBitmap->lockBytes());\n\n    ASSERT_EQ(BytesView(nullptr, bitmapData, pixelDataSize), BytesView(nullptr, returnedBitmapData, pixelDataSize));\n}\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/ImageQueue_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestBitmap.hpp\"\n\n#include \"snap_drawing/cpp/Utils/ImageQueue.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nclass ImageQueueTests : public ::testing::Test {\nprotected:\n    void SetUp() override {\n        _imageQueue = makeShared<ImageQueue>(2);\n    }\n\n    Ref<IBitmap> allocateAndEnqueue(int width, int height, ColorType colorType) {\n        auto result = _imageQueue->allocateBitmap(width, height, colorType);\n\n        auto bitmap = result.moveValue();\n        _imageQueue->enqueue(Image::makeFromBitmap(bitmap, false).value());\n\n        return bitmap;\n    }\n\n    Ref<ImageQueue> _imageQueue;\n};\n\nTEST_F(ImageQueueTests, canEnqueueAndDequeue) {\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getQueueSize());\n\n    auto bitmap1 = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n\n    ASSERT_EQ(static_cast<size_t>(1), _imageQueue->getQueueSize());\n\n    auto image = _imageQueue->dequeue();\n\n    ASSERT_TRUE(image.has_value());\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getQueueSize());\n\n    auto image2 = _imageQueue->dequeue();\n    ASSERT_FALSE(image2.has_value());\n}\n\nTEST_F(ImageQueueTests, clearOutQueueWhenReachingLimit) {\n    auto bitmap1 = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n\n    ASSERT_EQ(static_cast<size_t>(1), _imageQueue->getQueueSize());\n    ASSERT_EQ(static_cast<long>(2), bitmap1.use_count());\n\n    auto bitmap2 = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n\n    ASSERT_EQ(static_cast<size_t>(2), _imageQueue->getQueueSize());\n    ASSERT_EQ(static_cast<long>(2), bitmap1.use_count());\n\n    auto bitmap3 = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n\n    ASSERT_EQ(static_cast<size_t>(2), _imageQueue->getQueueSize());\n    ASSERT_EQ(static_cast<long>(1), bitmap1.use_count());\n}\n\nTEST_F(ImageQueueTests, canClear) {\n    allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n    allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n    ASSERT_EQ(static_cast<size_t>(2), _imageQueue->getQueueSize());\n\n    _imageQueue->clear();\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getQueueSize());\n\n    auto image = _imageQueue->dequeue();\n    ASSERT_FALSE(image.has_value());\n}\n\nTEST_F(ImageQueueTests, canReuseBitmaps) {\n    auto bitmap = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n    void* bytes = bitmap->lockBytes();\n\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getPoolSize());\n    _imageQueue->dequeue();\n\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getPoolSize());\n    bitmap = nullptr;\n\n    ASSERT_EQ(static_cast<size_t>(1), _imageQueue->getPoolSize());\n\n    bitmap = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getPoolSize());\n\n    ASSERT_EQ(bytes, bitmap->lockBytes());\n}\n\nTEST_F(ImageQueueTests, maintainsPoolSizeBelowThreshold) {\n    auto bitmap = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n    auto bitmap2 = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n    auto bitmap3 = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n    auto bitmap4 = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getPoolSize());\n\n    _imageQueue->clear();\n\n    bitmap = nullptr;\n    ASSERT_EQ(static_cast<size_t>(1), _imageQueue->getPoolSize());\n\n    bitmap2 = nullptr;\n    ASSERT_EQ(static_cast<size_t>(2), _imageQueue->getPoolSize());\n\n    bitmap3 = nullptr;\n    ASSERT_EQ(static_cast<size_t>(3), _imageQueue->getPoolSize());\n\n    bitmap4 = nullptr;\n    ASSERT_EQ(static_cast<size_t>(3), _imageQueue->getPoolSize());\n}\n\nTEST_F(ImageQueueTests, clearsPoolWhenSwitchingSizeOrColorType) {\n    auto bitmap = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n    auto bitmap2 = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n\n    _imageQueue->clear();\n\n    bitmap = nullptr;\n    bitmap2 = nullptr;\n\n    ASSERT_EQ(static_cast<size_t>(2), _imageQueue->getPoolSize());\n\n    auto bitmap3 = allocateAndEnqueue(2, 2, ColorType::ColorTypeRGBA8888);\n\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getPoolSize());\n\n    auto bitmap4 = allocateAndEnqueue(2, 2, ColorType::ColorTypeRGBA8888);\n\n    _imageQueue->clear();\n    bitmap3 = nullptr;\n    bitmap4 = nullptr;\n\n    ASSERT_EQ(static_cast<size_t>(2), _imageQueue->getPoolSize());\n\n    auto bitmap5 = allocateAndEnqueue(2, 2, ColorType::ColorTypeAlpha8);\n\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getPoolSize());\n}\n\nTEST_F(ImageQueueTests, doesntEnqueueToPoolWhenSwitchingSizeOrColorType) {\n    auto bitmap = allocateAndEnqueue(1, 1, ColorType::ColorTypeRGBA8888);\n    auto bitmap2 = allocateAndEnqueue(2, 2, ColorType::ColorTypeRGBA8888);\n\n    _imageQueue->clear();\n\n    bitmap = nullptr;\n    ASSERT_EQ(static_cast<size_t>(0), _imageQueue->getPoolSize());\n\n    bitmap2 = nullptr;\n    ASSERT_EQ(static_cast<size_t>(1), _imageQueue->getPoolSize());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/Interpolator_Tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"snap_drawing/cpp/Animations/ValueInterpolators.hpp\"\n#include \"snap_drawing/cpp/Utils/BorderRadius.hpp\"\n\nnamespace snap::drawing {\n\nTEST(InterpolatorTest, canInterpolatePercentBorderRadius) {\n    auto fromBorderRadius = BorderRadius(10, 20, 30, 40, true, true, true, true);\n\n    auto toBorderRadius = BorderRadius(14, 24, 34, 44, true, true, true, true);\n\n    auto bounds = Rect::makeXYWH(0.f, 0.f, 100.f, 100.f);\n    auto halfProgressInterpolated = interpolateBorderRadius(fromBorderRadius, toBorderRadius, bounds, 0.5f);\n\n    ASSERT_EQ(\"[12.0%, 22.0%, 32.0%, 42.0%]\", halfProgressInterpolated.toString());\n\n    auto threeQuartersProgressInterpolated = interpolateBorderRadius(fromBorderRadius, toBorderRadius, bounds, 0.75f);\n\n    ASSERT_EQ(\"[13.0%, 23.0%, 33.0%, 43.0%]\", threeQuartersProgressInterpolated.toString());\n}\n\nTEST(InterpolatorTest, canInterpolatePointBorderRadius) {\n    auto fromBorderRadius = BorderRadius(10, 20, 30, 40, false, false, false, false);\n\n    auto toBorderRadius = BorderRadius(14, 24, 34, 44, false, false, false, false);\n\n    auto bounds = Rect::makeXYWH(0.f, 0.f, 100.f, 100.f);\n    auto halfProgressInterpolated = interpolateBorderRadius(fromBorderRadius, toBorderRadius, bounds, 0.5f);\n\n    ASSERT_EQ(\"[12.0, 22.0, 32.0, 42.0]\", halfProgressInterpolated.toString());\n\n    auto threeQuartersProgressInterpolated = interpolateBorderRadius(fromBorderRadius, toBorderRadius, bounds, 0.75f);\n\n    ASSERT_EQ(\"[13.0, 23.0, 33.0, 43.0]\", threeQuartersProgressInterpolated.toString());\n}\n\nTEST(InterpolatorTest, canInterpolatePercentToPointBorderRadius) {\n    auto fromBorderRadius = BorderRadius(20, 30, 40, 50, true, true, true, true);\n\n    auto toBorderRadius = BorderRadius(20, 30, 40, 50, false, false, false, false);\n\n    auto bounds = Rect::makeXYWH(0.f, 0.f, 200.f, 200.f);\n    auto halfProgressInterpolated = interpolateBorderRadius(fromBorderRadius, toBorderRadius, bounds, 0.5f);\n\n    ASSERT_EQ(\"[30.0, 45.0, 60.0, 75.0]\", halfProgressInterpolated.toString());\n\n    auto threeQuartersProgressInterpolated = interpolateBorderRadius(fromBorderRadius, toBorderRadius, bounds, 0.75f);\n\n    ASSERT_EQ(\"[25.0, 37.5, 50.0, 62.5]\", threeQuartersProgressInterpolated.toString());\n}\n\nTEST(InterpolatorTest, canInterpolatePointToPercentBorderRadius) {\n    auto fromBorderRadius = BorderRadius(20, 30, 40, 50, false, false, false, false);\n\n    auto toBorderRadius = BorderRadius(20, 30, 40, 50, true, true, true, true);\n\n    auto bounds = Rect::makeXYWH(0.f, 0.f, 200.f, 200.f);\n    auto halfProgressInterpolated = interpolateBorderRadius(fromBorderRadius, toBorderRadius, bounds, 0.5f);\n\n    ASSERT_EQ(\"[15.0%, 22.5%, 30.0%, 37.5%]\", halfProgressInterpolated.toString());\n\n    auto threeQuartersProgressInterpolated = interpolateBorderRadius(fromBorderRadius, toBorderRadius, bounds, 0.75f);\n\n    ASSERT_EQ(\"[17.5%, 26.2%, 35.0%, 43.8%]\", threeQuartersProgressInterpolated.toString());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/Layer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"DisplayListBuilder.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Layers/Mask/PaintMaskLayer.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nclass LayerTests : public ::testing::Test {\nprotected:\n    void SetUp() override {\n        _resources = makeShared<Resources>(nullptr, 1.0f, ConsoleLogger::getLogger());\n\n        _root = createLayer();\n    }\n\n    void TearDown() override {\n        _resources = nullptr;\n        _root = nullptr;\n    }\n\n    Ref<Layer> createLayer() {\n        return makeLayer<Layer>(_resources);\n    }\n\n    DrawMetrics draw() {\n        DrawMetrics metrics;\n\n        if (_root->childNeedsDisplay()) {\n            auto displayList = makeShared<DisplayList>(Size(), TimePoint::fromSeconds(0.0));\n\n            _root->draw(*displayList, metrics);\n        }\n\n        return metrics;\n    }\n\n    Ref<Resources> _resources;\n    Ref<Layer> _root;\n};\n\nTEST_F(LayerTests, visitsChildrenOnDraw) {\n    auto metrics = draw();\n    ASSERT_EQ(1, metrics.drawCacheMiss);\n    ASSERT_EQ(1, metrics.visitedLayers);\n\n    auto container = createLayer();\n    auto child1 = createLayer();\n    auto child2 = createLayer();\n\n    _root->addChild(container);\n    container->addChild(child1);\n    container->addChild(child2);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_TRUE(_root->childNeedsDisplay());\n    ASSERT_TRUE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_TRUE(child1->needsDisplay());\n    ASSERT_TRUE(child1->childNeedsDisplay());\n    ASSERT_TRUE(child2->needsDisplay());\n    ASSERT_TRUE(child2->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(3, metrics.drawCacheMiss);\n    ASSERT_EQ(4, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(0, metrics.drawCacheMiss);\n    ASSERT_EQ(0, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n}\n\nTEST_F(LayerTests, visitsChildAgainAfterReinsertion) {\n    auto container = createLayer();\n    auto child1 = createLayer();\n    auto child2 = createLayer();\n\n    _root->addChild(container);\n    container->addChild(child1);\n    container->addChild(child2);\n\n    auto metrics = draw();\n    ASSERT_EQ(4, metrics.drawCacheMiss);\n    ASSERT_EQ(4, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    child2->removeFromParent();\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_TRUE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(0, metrics.drawCacheMiss);\n    ASSERT_EQ(3, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    container->addChild(child2);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_TRUE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_TRUE(child2->needsDisplay());\n    ASSERT_TRUE(child2->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(1, metrics.drawCacheMiss);\n    ASSERT_EQ(4, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(0, metrics.drawCacheMiss);\n    ASSERT_EQ(0, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n}\n\nTEST_F(LayerTests, propagatesNeedsDisplay) {\n    auto container = createLayer();\n    auto child1 = createLayer();\n    auto child2 = createLayer();\n\n    _root->addChild(container);\n    container->addChild(child1);\n    container->addChild(child2);\n\n    auto metrics = draw();\n    ASSERT_EQ(4, metrics.drawCacheMiss);\n    ASSERT_EQ(4, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    child2->setNeedsDisplay();\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_TRUE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_TRUE(child2->needsDisplay());\n    ASSERT_TRUE(child2->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(1, metrics.drawCacheMiss);\n    ASSERT_EQ(4, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    container->setNeedsDisplay();\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_TRUE(_root->childNeedsDisplay());\n    ASSERT_TRUE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(1, metrics.drawCacheMiss);\n    ASSERT_EQ(4, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n\n    container->setNeedsDisplay();\n    child2->setNeedsDisplay();\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_TRUE(_root->childNeedsDisplay());\n    ASSERT_TRUE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_TRUE(child2->needsDisplay());\n    ASSERT_TRUE(child2->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(2, metrics.drawCacheMiss);\n    ASSERT_EQ(4, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n    ASSERT_FALSE(child2->needsDisplay());\n    ASSERT_FALSE(child2->childNeedsDisplay());\n}\n\nTEST_F(LayerTests, doesntVisitInvisibleChild) {\n    auto container = createLayer();\n    auto child1 = createLayer();\n\n    _root->addChild(container);\n    container->addChild(child1);\n\n    auto metrics = draw();\n    ASSERT_EQ(3, metrics.drawCacheMiss);\n    ASSERT_EQ(3, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_FALSE(container->needsDisplay());\n    ASSERT_FALSE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n\n    ASSERT_TRUE(container->isVisible());\n    container->setOpacity(0);\n    ASSERT_FALSE(container->isVisible());\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_TRUE(_root->childNeedsDisplay());\n    ASSERT_TRUE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(0, metrics.drawCacheMiss);\n    ASSERT_EQ(1, metrics.visitedLayers);\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_FALSE(_root->childNeedsDisplay());\n    ASSERT_TRUE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n\n    container->setOpacity(0.5);\n    ASSERT_TRUE(container->isVisible());\n\n    ASSERT_FALSE(_root->needsDisplay());\n    ASSERT_TRUE(_root->childNeedsDisplay());\n    ASSERT_TRUE(container->needsDisplay());\n    ASSERT_TRUE(container->childNeedsDisplay());\n    ASSERT_FALSE(child1->needsDisplay());\n    ASSERT_FALSE(child1->childNeedsDisplay());\n\n    metrics = draw();\n    ASSERT_EQ(1, metrics.drawCacheMiss);\n    ASSERT_EQ(3, metrics.visitedLayers);\n}\n\nTEST_F(LayerTests, canDrawMask) {\n    auto maskLayer = Valdi::makeShared<PaintMaskLayer>();\n    maskLayer->setRect(Rect::makeXYWH(5, 5, 10, 10));\n\n    _root->setMaskLayer(maskLayer);\n    _root->setFrame(Rect::makeXYWH(0, 0, 20, 20));\n\n    auto displayList = makeShared<DisplayList>(Size(), TimePoint::fromSeconds(0.0));\n\n    DrawMetrics metrics;\n    _root->draw(*displayList, metrics);\n\n    auto operations = getOperationsFromDisplayList(displayList, 0);\n\n    ASSERT_EQ(static_cast<size_t>(4), operations.size());\n\n    ASSERT_EQ(Operations::PrepareMask::kId, operations[1]->type);\n    ASSERT_EQ(Operations::ApplyMask::kId, operations[2]->type);\n\n    auto* expectedMask = reinterpret_cast<const Operations::PrepareMask*>(operations[1])->mask;\n    ASSERT_TRUE(expectedMask != nullptr);\n\n    ASSERT_EQ(expectedMask, reinterpret_cast<const Operations::ApplyMask*>(operations[2])->mask);\n    ASSERT_EQ(Rect::makeXYWH(5, 5, 10, 10), expectedMask->getBounds());\n}\n\nTEST_F(LayerTests, canDrawMaskBelowBackground) {\n    auto maskLayer = Valdi::makeShared<PaintMaskLayer>();\n    maskLayer->setRect(Rect::makeXYWH(5, 5, 10, 10));\n    maskLayer->setPositioning(MaskLayerPositioning::BelowBackground);\n\n    _root->setMaskLayer(maskLayer);\n    _root->setBackgroundColor(Color::red());\n    _root->setFrame(Rect::makeXYWH(0, 0, 20, 20));\n\n    auto displayList = makeShared<DisplayList>(Size(), TimePoint::fromSeconds(0.0));\n\n    DrawMetrics metrics;\n    _root->draw(*displayList, metrics);\n\n    auto operations = getOperationsFromDisplayList(displayList, 0);\n\n    ASSERT_EQ(static_cast<size_t>(5), operations.size());\n\n    ASSERT_EQ(Operations::PrepareMask::kId, operations[1]->type);\n    ASSERT_EQ(Operations::DrawPicture::kId, operations[2]->type);\n    ASSERT_EQ(Operations::ApplyMask::kId, operations[3]->type);\n}\n\nTEST_F(LayerTests, canDrawMaskAboveBackground) {\n    auto maskLayer = Valdi::makeShared<PaintMaskLayer>();\n    maskLayer->setRect(Rect::makeXYWH(5, 5, 10, 10));\n    maskLayer->setPositioning(MaskLayerPositioning::AboveBackground);\n\n    _root->setMaskLayer(maskLayer);\n    _root->setBackgroundColor(Color::red());\n    _root->setFrame(Rect::makeXYWH(0, 0, 20, 20));\n\n    auto displayList = makeShared<DisplayList>(Size(), TimePoint::fromSeconds(0.0));\n\n    DrawMetrics metrics;\n    _root->draw(*displayList, metrics);\n\n    auto operations = getOperationsFromDisplayList(displayList, 0);\n\n    ASSERT_EQ(static_cast<size_t>(5), operations.size());\n\n    ASSERT_EQ(Operations::DrawPicture::kId, operations[1]->type);\n    ASSERT_EQ(Operations::PrepareMask::kId, operations[2]->type);\n    ASSERT_EQ(Operations::ApplyMask::kId, operations[3]->type);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/LongPressGestureRecognizer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(LongPressGestureRecognizer, canHandleLongPress) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(LongPressGestureRecognizer, canHandleLongPressWithDoubleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto doubleTapSnapshot = addDoubleTapGesture(childView);\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(LongPressGestureRecognizer, canHandleLongPressWithSingleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(LongPressGestureRecognizer, triggersLongPressWithoutWaitingForTapFailure) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    Valdi::castOrNull<LongPressGestureRecognizer>(longPressSnapshot->parent)\n        ->setLongPressTimeout(Duration::fromSeconds(0.1));\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 0, 0, 1, Duration::fromSeconds(0.15));\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(LongPressGestureRecognizer, canHandleLongPressWithSingleTapWithDoubleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n    auto doubleTapSnapshot = addDoubleTapGesture(childView);\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(LongPressGestureRecognizer, canHandleLongPressQuickTwo) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_EQ(4, longPressSnapshot->counter);\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(LongPressGestureRecognizer, canHandleLongPressWithDrag) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto dragSnapshot = addDragGesture(childView);\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, longPressSnapshot->state);\n\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateChanged, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(LongPressGestureRecognizer, canHandleLongPressWithoutDrag) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto dragSnapshot = addDragGesture(childView);\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, longPressSnapshot->state);\n\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35);\n    ASSERT_EQ(GestureRecognizerStateChanged, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/LottieLayer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestBitmap.hpp\"\n#include \"snap_drawing/cpp/Layers/AnimatedImageLayer.hpp\"\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n#include \"snap_drawing/cpp/Utils/AnimatedImage.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\n#include \"TestDataUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nconstexpr int kExpectedAnimationDurationMs = 3903;\n\nclass TestLayerRootListener : public LayerRootListener {\npublic:\n    bool didDraw = false;\n    void onNeedsProcessFrame(LayerRoot& /*root*/) override {}\n\n    void onDidDraw(LayerRoot& root,\n                   const Ref<DisplayList>& displayList,\n                   const CompositorPlaneList* planeList) override {\n        didDraw = true;\n    }\n};\n\nclass AnimatedImageLayerTests : public ::testing::Test {\nprotected:\n    void SetUp() override {\n        auto fontManager = makeShared<FontManager>(ConsoleLogger::getLogger());\n        auto resources = makeShared<Resources>(fontManager, 1.0f, ConsoleLogger::getLogger());\n\n        _layerRoot = makeLayer<LayerRoot>(resources);\n        _animatedImageLayer = makeLayer<AnimatedImageLayer>(resources);\n        _layerRoot->setContentLayer(_animatedImageLayer, ContentLayerSizingModeMatchSize);\n        _layerRoot->setSize(Size(1.0f, 1.0f), 1.0f);\n        _layerRoot->setListener(&_layerRootListener);\n\n        auto testData = getTestData(\"lottie_loading.json\");\n        SC_ASSERT(testData.success(), testData.description());\n\n        auto animatedImage = AnimatedImage::make(fontManager, testData.value().data(), testData.value().size());\n        SC_ASSERT(animatedImage.success(), animatedImage.description());\n        _animatedImage = animatedImage.moveValue();\n\n        ASSERT_EQ(kExpectedAnimationDurationMs, static_cast<int>(_animatedImage->getDuration().milliseconds()));\n    }\n\n    void TearDown() override {\n        _animatedImageLayer = nullptr;\n        _layerRoot = nullptr;\n        _animatedImage = nullptr;\n    }\n\n    bool update(double delta) {\n        _layerRootListener.didDraw = false;\n        _layerRoot->processFrame(TimePoint::fromSeconds(_currentTime));\n\n        _currentTime += delta;\n\n        return _layerRootListener.didDraw;\n    }\n\n    Ref<LayerRoot> _layerRoot;\n    Ref<AnimatedImageLayer> _animatedImageLayer;\n    Ref<AnimatedImage> _animatedImage;\n    TimeInterval _currentTime = 0.0;\n    TestLayerRootListener _layerRootListener;\n};\n\nTEST_F(AnimatedImageLayerTests, setsAnimationWhenSceneIsSetWithAdvanceRate) {\n    update(0.5);\n\n    ASSERT_FALSE(_animatedImageLayer->needsProcessAnimations());\n\n    _animatedImageLayer->setImage(_animatedImage);\n\n    ASSERT_EQ(static_cast<size_t>(0), _animatedImageLayer->getAnimationKeys().size());\n    ASSERT_FALSE(_animatedImageLayer->needsProcessAnimations());\n\n    _animatedImageLayer->setAdvanceRate(1.0);\n\n    ASSERT_EQ(static_cast<size_t>(1), _animatedImageLayer->getAnimationKeys().size());\n    ASSERT_TRUE(_animatedImageLayer->needsProcessAnimations());\n\n    ASSERT_TRUE(update(0.5));\n\n    ASSERT_EQ(static_cast<size_t>(1), _animatedImageLayer->getAnimationKeys().size());\n    ASSERT_TRUE(_animatedImageLayer->needsProcessAnimations());\n\n    _animatedImageLayer->setImage(nullptr);\n\n    ASSERT_EQ(static_cast<size_t>(0), _animatedImageLayer->getAnimationKeys().size());\n    ASSERT_TRUE(_animatedImageLayer->needsProcessAnimations());\n\n    ASSERT_TRUE(update(0.5));\n\n    ASSERT_EQ(static_cast<size_t>(0), _animatedImageLayer->getAnimationKeys().size());\n    ASSERT_FALSE(_animatedImageLayer->needsProcessAnimations());\n\n    _animatedImageLayer->setImage(_animatedImage);\n\n    ASSERT_EQ(static_cast<size_t>(1), _animatedImageLayer->getAnimationKeys().size());\n    ASSERT_TRUE(_animatedImageLayer->needsProcessAnimations());\n}\n\nTEST_F(AnimatedImageLayerTests, canSeek) {\n    _animatedImageLayer->setImage(_animatedImage);\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(0, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    _animatedImageLayer->setCurrentTime(Duration::fromMilliseconds(250));\n    // Should only be impacted on draw\n    ASSERT_EQ(0, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(250, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    _animatedImageLayer->setCurrentTime(Duration::fromMilliseconds(750));\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(750, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    _animatedImageLayer->setCurrentTime(Duration::fromMilliseconds(100));\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(100, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n}\n\nTEST_F(AnimatedImageLayerTests, canMoveForward) {\n    _animatedImageLayer->setImage(_animatedImage);\n    _animatedImageLayer->setAdvanceRate(1.0);\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(0, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.25));\n    ASSERT_EQ(500, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(750, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    _animatedImageLayer->setAdvanceRate(3.0);\n\n    ASSERT_TRUE(update(0.1));\n    ASSERT_EQ(2250, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(1.0));\n    ASSERT_EQ(2550, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n}\n\nTEST_F(AnimatedImageLayerTests, canMoveBackward) {\n    _animatedImageLayer->setImage(_animatedImage);\n    _animatedImageLayer->setAdvanceRate(-1.0);\n    _animatedImageLayer->setCurrentTime(Duration::fromMilliseconds(3500));\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(3500, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.25));\n    ASSERT_EQ(3000, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(2750, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    _animatedImageLayer->setAdvanceRate(-3.0);\n\n    ASSERT_TRUE(update(0.1));\n    ASSERT_EQ(1250, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n}\n\nTEST_F(AnimatedImageLayerTests, staysAtLastFrameWhenReachingEndForward) {\n    _animatedImageLayer->setImage(_animatedImage);\n    _animatedImageLayer->setAdvanceRate(1.0);\n\n    ASSERT_TRUE(update(3.0));\n    ASSERT_EQ(0, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(2.0));\n    ASSERT_EQ(3000, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(3903, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_FALSE(update(0.5));\n    ASSERT_EQ(3903, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_FALSE(update(0.5));\n    ASSERT_EQ(3903, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n}\n\nTEST_F(AnimatedImageLayerTests, staysAtFirstFrameWhenReachingEndForward) {\n    _animatedImageLayer->setImage(_animatedImage);\n    _animatedImageLayer->setAdvanceRate(-1.0);\n    _animatedImageLayer->setCurrentTime(Duration::fromMilliseconds(3500));\n\n    ASSERT_TRUE(update(3.0));\n    ASSERT_EQ(3500, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(2.0));\n    ASSERT_EQ(500, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(0, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_FALSE(update(0.5));\n    ASSERT_EQ(0, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_FALSE(update(0.5));\n    ASSERT_EQ(0, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n}\n\nTEST_F(AnimatedImageLayerTests, canLoopForward) {\n    _animatedImageLayer->setImage(_animatedImage);\n    _animatedImageLayer->setAdvanceRate(1.0);\n    _animatedImageLayer->setShouldLoop(true);\n\n    ASSERT_TRUE(update(2.0));\n    ASSERT_EQ(0, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(1.0));\n    ASSERT_EQ(2000, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(2));\n    ASSERT_EQ(3000, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.1));\n    ASSERT_EQ(1096, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n}\n\nTEST_F(AnimatedImageLayerTests, canLoopBackward) {\n    _animatedImageLayer->setImage(_animatedImage);\n    _animatedImageLayer->setAdvanceRate(-1.0);\n    _animatedImageLayer->setShouldLoop(true);\n    _animatedImageLayer->setCurrentTime(Duration::fromMilliseconds(1000));\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(1000, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.75));\n    ASSERT_EQ(500, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n\n    ASSERT_TRUE(update(0.5));\n    ASSERT_EQ(3653, static_cast<int>(_animatedImage->getCurrentTime().milliseconds()));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/PinchGestureRecognizer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(PinchGestureRecognizer, canHandlePinchTwoPointers) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto pinchSnapshot = addPinchGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateBegan, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeMoved, 35, 40, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypePointerUp, 35, 40, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeUp, 35, 40, 1, 2, 1);\n    ASSERT_EQ(GestureRecognizerStateEnded, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(PinchGestureRecognizer, canHandlePinchTwoPointersInterrupted) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto pinchSnapshot = addPinchGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateBegan, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeMoved, 40, 35, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypePointerUp, 40, 35, 0, 0, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeMoved, 40, 35, 0, 0, 1);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeUp, 40, 35, 0, 0, 1);\n    ASSERT_EQ(GestureRecognizerStateEnded, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(PinchGestureRecognizer, canHandlePinchOneThenTwoPointers) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto pinchSnapshot = addPinchGesture(childView);\n\n    auto holdDuration = Duration::fromSeconds(GesturesConfiguration::getDefault().dragTouchSlop);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, pinchSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, pinchSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 0, 0, 1, holdDuration);\n    ASSERT_EQ(GestureRecognizerStatePossible, pinchSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 1, 1, 2, holdDuration);\n    ASSERT_EQ(GestureRecognizerStateBegan, pinchSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 1, 2, 2, holdDuration);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, pinchSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(PinchGestureRecognizer, canHandlePinchResumption) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto pinchSnapshot = addPinchGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateBegan, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeMoved, 40, 35, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypePointerUp, 40, 35, 0, 0, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeMoved, 60, 35, 0, 0, 1);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypePointerDown, 60, 35, 0, 0, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(1.5811388, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeMoved, 40, 35, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(2.5, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypePointerUp, 40, 35, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(2.5, pinchSnapshot->pinchEvent.scale);\n\n    container->dispatchEvent(TouchEventTypeUp, 40, 35, 0, 0, 1);\n    ASSERT_EQ(GestureRecognizerStateEnded, pinchSnapshot->state);\n    ASSERT_FLOAT_EQ(2.5, pinchSnapshot->pinchEvent.scale);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/RasterContext_tests.cpp",
    "content": "#include \"gtest/gtest.h\"\n#include <cstdint>\n#include <gtest/gtest.h>\n\n#include \"TestBitmap.hpp\"\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/BitmapGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Raster/RasterContext.hpp\"\n#include \"snap_drawing/cpp/Layers/ExternalLayer.hpp\"\n#include \"snap_drawing/cpp/Layers/Interfaces/ILayerRoot.hpp\"\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Utils/Bitmap.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmapFactory.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nclass TestBitmapFactory : public IBitmapFactory {\npublic:\n    size_t createdBitmapCount = 0;\n\n    TestBitmapFactory() = default;\n    ~TestBitmapFactory() override = default;\n\n    Result<Ref<IBitmap>> createBitmap(int width, int height) override {\n        createdBitmapCount++;\n\n        Ref<IBitmap> bitmap = makeShared<TestBitmap>(width, height);\n        return bitmap;\n    }\n};\n\nclass TestLayerRoot : public ILayerRoot {\npublic:\n    TestLayerRoot() = default;\n    ~TestLayerRoot() override = default;\n\n    EventId enqueueEvent(EventCallback&& eventCallback, Duration after) final {\n        return EventId();\n    }\n\n    bool cancelEvent(EventId eventId) final {\n        return false;\n    }\n\n    bool shouldRasterizeExternalSurface() const final {\n        return false;\n    }\n\n    void onInitialize() final {}\n    void setChildNeedsDisplay() final {}\n    void requestLayout(ILayer* layer) final {}\n    void requestFocus(ILayer* layer) final {}\n\n    LayerId allocateLayerId() override {\n        return ++_layerIdSequence;\n    }\n\nprivate:\n    uint64_t _layerIdSequence = 0;\n};\n\nclass RasterContextTestExternalSurface : public ExternalSurface {\npublic:\n    size_t rasterCount = 0;\n    RasterContextTestExternalSurface(const Ref<Valdi::IBitmapFactory>& bitmapFactory, Color color)\n        : _bitmapFactory(bitmapFactory), _color(color) {}\n    ~RasterContextTestExternalSurface() override = default;\n\n    Ref<Valdi::IBitmapFactory> getRasterBitmapFactory() const override {\n        return _bitmapFactory;\n    }\n\n    Valdi::Result<Valdi::Void> rasterInto(const Ref<Valdi::IBitmap>& bitmap,\n                                          const Rect& frame,\n                                          const Matrix& transform,\n                                          float rasterScaleX,\n                                          float rasterScaleY) override {\n        rasterCount++;\n        BitmapGraphicsContext bitmapContext;\n        auto surface = bitmapContext.createBitmapSurface(bitmap);\n        auto canvas = surface->prepareCanvas();\n        if (!canvas) {\n            return canvas.moveError();\n        }\n\n        auto* skCanvas = canvas.value().getSkiaCanvas();\n\n        skCanvas->concat(transform.getSkValue());\n        skCanvas->scale(rasterScaleX, rasterScaleY);\n        SkPaint paint;\n        paint.setColor(_color.getSkValue());\n        skCanvas->drawRect(frame.getSkValue(), paint);\n\n        surface->flush();\n\n        return Valdi::Void();\n    }\n\nprivate:\n    Ref<Valdi::IBitmapFactory> _bitmapFactory;\n    Color _color;\n};\n\nclass RasterContextTests : public ::testing::Test {\nprotected:\n    void SetUp() override {\n        _resources = makeShared<Resources>(nullptr, 1.0f, ConsoleLogger::getLogger());\n        _rasterContext =\n            makeShared<RasterContext>(_resources->getLogger(), ExternalSurfaceRasterizationMethod::ACCURATE, false);\n        _layerRoot = makeShared<TestLayerRoot>();\n        _contentLayer = makeLayer<Layer>(_resources);\n        _contentLayer->onParentChanged(_layerRoot);\n        _bitmapFactory = makeShared<TestBitmapFactory>();\n    }\n\n    Result<Ref<TestBitmap>> raster() {\n        auto outputBitmap = makeShared<TestBitmap>(4, 4);\n        auto result = rasterInto(outputBitmap);\n        if (!result) {\n            return result.moveError();\n        }\n\n        return outputBitmap;\n    }\n\n    Result<RasterContext::RasterResult> rasterInto(const Ref<Valdi::IBitmap>& outputBitmap,\n                                                   bool shouldClearBitmapBeforeDrawing = true) {\n        auto displayList = Valdi::makeShared<DisplayList>(_contentLayer->getFrame().size(), TimePoint(0.0));\n        DrawMetrics metrics;\n        _contentLayer->draw(*displayList, metrics);\n\n        return _rasterContext->raster(displayList, outputBitmap, shouldClearBitmapBeforeDrawing);\n    }\n\n    Result<RasterContext::RasterResult> rasterDelta(const Ref<TestBitmap>& inputBitmap) {\n        auto displayList = Valdi::makeShared<DisplayList>(_contentLayer->getFrame().size(), TimePoint(0.0));\n        DrawMetrics metrics;\n        _contentLayer->draw(*displayList, metrics);\n\n        return _rasterContext->rasterDelta(displayList, inputBitmap);\n    }\n\n    Ref<Resources> _resources;\n    Ref<RasterContext> _rasterContext;\n    Ref<TestLayerRoot> _layerRoot;\n    Ref<Layer> _contentLayer;\n    Ref<TestBitmapFactory> _bitmapFactory;\n};\n\nTEST_F(RasterContextTests, canRasterSimpleScene) {\n    _contentLayer->setBackgroundColor(Color::red());\n\n    auto centerLayer = makeLayer<Layer>(_resources);\n    centerLayer->setBackgroundColor(Color::blue());\n    centerLayer->setFrame(Rect::makeXYWH(1, 1, 2, 2));\n    _contentLayer->addChild(centerLayer);\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 4, 4));\n\n    auto result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::blue(), Color::blue(), Color::red(),\n                Color::red(), Color::blue(), Color::blue(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(0, _bitmapFactory->createdBitmapCount);\n}\n\nTEST_F(RasterContextTests, scalesSceneToBitmap) {\n    _contentLayer->setBackgroundColor(Color::red());\n\n    auto centerLayer = makeLayer<Layer>(_resources);\n    centerLayer->setBackgroundColor(Color::blue());\n    centerLayer->setFrame(Rect::makeXYWH(0, 0, 1, 1));\n    _contentLayer->addChild(centerLayer);\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 2, 2));\n\n    auto result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::blue(), Color::blue(), Color::red(), Color::red(),\n                Color::blue(), Color::blue(), Color::red(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(0, _bitmapFactory->createdBitmapCount);\n}\n\nTEST_F(RasterContextTests, canRasterDelta) {\n    _contentLayer->setBackgroundColor(Color::red());\n\n    auto centerLayer = makeLayer<Layer>(_resources);\n    centerLayer->setBackgroundColor(Color::blue());\n    centerLayer->setFrame(Rect::makeXYWH(1, 1, 2, 2));\n    _contentLayer->addChild(centerLayer);\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 4, 4));\n\n    auto outputBitmap = makeShared<TestBitmap>(4, 4);\n\n    auto result = rasterDelta(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                  Color::red(), Color::red(), Color::red(), Color::red(),\n                  Color::red(), Color::blue(), Color::blue(), Color::red(),\n                  Color::red(), Color::blue(), Color::blue(), Color::red(),\n                  Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    // With 1px AA margin, 4x4 rect becomes 6x6 = 36 pixels\n    ASSERT_EQ(36, result.value().renderedPixelsCount);\n\n    outputBitmap->setPixels(std::initializer_list<Color>({\n        // clang-format off\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n        // clang-format on\n    }));\n\n    result = rasterDelta(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                  Color::black(), Color::black(), Color::black(), Color::black(),\n                  Color::black(), Color::black(), Color::black(), Color::black(),\n                  Color::black(), Color::black(), Color::black(), Color::black(),\n                  Color::black(), Color::black(), Color::black(), Color::black(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(0, result.value().renderedPixelsCount);\n    centerLayer->setBackgroundColor(Color::green());\n\n    result = rasterDelta(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    // With 1px AA margin, the damage rect extends beyond the changed 2x2 area,\n    // causing the red background to be re-rendered in the margin area\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                            Color::red(), Color::red(), Color::red(), Color::red(),\n                            Color::red(), Color::green(), Color::green(), Color::red(),\n                            Color::red(), Color::green(), Color::green(), Color::red(),\n                            Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    // With 1px AA margin, 2x2 rect becomes 4x4 = 16 pixels\n    ASSERT_EQ(16, result.value().renderedPixelsCount);\n}\n\nTEST_F(RasterContextTests, canRasterDeltaWithScale) {\n    _contentLayer->setBackgroundColor(Color::red());\n\n    auto centerLayer = makeLayer<Layer>(_resources);\n    centerLayer->setBackgroundColor(Color::blue());\n    centerLayer->setFrame(Rect::makeXYWH(0, 0, 1, 1));\n    _contentLayer->addChild(centerLayer);\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 2, 2));\n\n    auto outputBitmap = makeShared<TestBitmap>(4, 4);\n\n    auto result = rasterDelta(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                  Color::blue(), Color::blue(), Color::red(), Color::red(),\n                  Color::blue(), Color::blue(), Color::red(), Color::red(),\n                  Color::red(), Color::red(), Color::red(), Color::red(),\n                  Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    outputBitmap->setPixels(std::initializer_list<Color>({\n        // clang-format off\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n        // clang-format on\n    }));\n\n    centerLayer->setBackgroundColor(Color::green());\n\n    result = rasterDelta(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    // With 1px AA margin, the 2x2 green layer's damage extends to adjacent red pixels\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                            Color::green(), Color::green(), Color::red(), Color::black(),\n                            Color::green(), Color::green(), Color::red(), Color::black(),\n                            Color::red(), Color::red(), Color::red(), Color::black(),\n                            Color::black(), Color::black(), Color::black(), Color::black(),\n                  // clang-format on\n              }));\n}\n\nTEST_F(RasterContextTests, canRasterDeltaWitMovedSurfaces) {\n    _contentLayer->setBackgroundColor(Color::red());\n\n    auto centerLayer = makeLayer<Layer>(_resources);\n    centerLayer->setBackgroundColor(Color::blue());\n    centerLayer->setFrame(Rect::makeXYWH(1, 1, 2, 2));\n    _contentLayer->addChild(centerLayer);\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 4, 4));\n\n    auto outputBitmap = makeShared<TestBitmap>(4, 4);\n\n    auto result = rasterDelta(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    outputBitmap->setPixels(std::initializer_list<Color>({\n        // clang-format off\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n            Color::black(), Color::black(), Color::black(), Color::black(),\n        // clang-format on\n    }));\n\n    centerLayer->setFrame(Rect::makeXYWH(0, 1, 2, 2));\n\n    result = rasterDelta(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    // With 1px AA margin, moving the layer causes both old and new positions to\n    // re-render with their margins, exposing the red background\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                            Color::red(), Color::red(), Color::red(), Color::red(),\n                            Color::blue(), Color::blue(), Color::red(), Color::red(),\n                            Color::blue(), Color::blue(), Color::red(), Color::red(),\n                            Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n}\n\nTEST_F(RasterContextTests, canRasterSceneWithExternalSurface) {\n    _contentLayer->setBackgroundColor(Color::red());\n\n    auto centerLayer = makeLayer<ExternalLayer>(_resources);\n    auto externalSurface = makeShared<RasterContextTestExternalSurface>(_bitmapFactory, Color::green());\n    centerLayer->setExternalSurface(externalSurface);\n\n    _contentLayer->addChild(centerLayer);\n\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 4, 4));\n    centerLayer->setFrame(Rect::makeXYWH(1, 1, 2, 2));\n\n    auto result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::green(), Color::green(), Color::red(),\n                Color::red(), Color::green(), Color::green(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(1, _bitmapFactory->createdBitmapCount);\n    ASSERT_EQ(1, externalSurface->rasterCount);\n}\n\nTEST_F(RasterContextTests, appliesClipToExternalSurface) {\n    _contentLayer->setBackgroundColor(Color::red());\n\n    auto clipLayer = makeLayer<Layer>(_resources);\n\n    auto centerLayer = makeLayer<ExternalLayer>(_resources);\n    auto externalSurface = makeShared<RasterContextTestExternalSurface>(_bitmapFactory, Color::green());\n    centerLayer->setExternalSurface(externalSurface);\n\n    _contentLayer->addChild(clipLayer);\n    clipLayer->addChild(centerLayer);\n\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 4, 4));\n    clipLayer->setFrame(Rect::makeXYWH(1, 1, 1, 2));\n    centerLayer->setFrame(Rect::makeXYWH(0, 0, 2, 2));\n\n    auto result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    // Try first without clipping\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::green(), Color::green(), Color::red(),\n                Color::red(), Color::green(), Color::green(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(1, _bitmapFactory->createdBitmapCount);\n    ASSERT_EQ(1, externalSurface->rasterCount);\n\n    // Now raster with clipping. Only the left side of the external surface should be visible.\n\n    clipLayer->setClipsToBounds(true);\n    result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::green(), Color::red(), Color::red(),\n                Color::red(), Color::green(), Color::red(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(1, _bitmapFactory->createdBitmapCount);\n    ASSERT_EQ(1, externalSurface->rasterCount);\n}\n\nTEST_F(RasterContextTests, redrawsExternalSurfaceOnlyWhenNeeded) {\n    _contentLayer->setBackgroundColor(Color::red());\n\n    auto centerLayer = makeLayer<ExternalLayer>(_resources);\n    auto externalSurface = makeShared<RasterContextTestExternalSurface>(_bitmapFactory, Color::green());\n    centerLayer->setExternalSurface(externalSurface);\n\n    _contentLayer->addChild(centerLayer);\n\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 4, 4));\n    centerLayer->setFrame(Rect::makeXYWH(1, 1, 2, 2));\n\n    auto result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::green(), Color::green(), Color::red(),\n                Color::red(), Color::green(), Color::green(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(1, _bitmapFactory->createdBitmapCount);\n    ASSERT_EQ(1, externalSurface->rasterCount);\n\n    // Now raster again without changing the external surface.\n\n    result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::green(), Color::green(), Color::red(),\n                Color::red(), Color::green(), Color::green(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(1, _bitmapFactory->createdBitmapCount);\n    ASSERT_EQ(1, externalSurface->rasterCount);\n\n    // Change position of the external surface.\n    centerLayer->setFrame(Rect::makeXYWH(0, 1, 2, 2));\n\n    result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::green(), Color::green(), Color::red(), Color::red(),\n                Color::green(), Color::green(), Color::red(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(2, _bitmapFactory->createdBitmapCount);\n    ASSERT_EQ(2, externalSurface->rasterCount);\n\n    // Change transform. It should reuse a bitmap from the cache, but raster should occur again.\n\n    centerLayer->setScaleX(0.5f);\n    centerLayer->setTranslationX(-1.0f);\n\n    result = raster();\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*result.value(),\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::green(), Color::red(), Color::red(), Color::red(),\n                Color::green(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(2, _bitmapFactory->createdBitmapCount);\n    ASSERT_EQ(3, externalSurface->rasterCount);\n}\n\nTEST_F(RasterContextTests, canRasterWithInternalDeltaMode) {\n    _rasterContext =\n        makeShared<RasterContext>(_resources->getLogger(), ExternalSurfaceRasterizationMethod::ACCURATE, true);\n\n    auto outputBitmap = makeShared<TestBitmap>(4, 4);\n\n    _contentLayer->setBackgroundColor(Color::red());\n    auto innerLayer = makeLayer<Layer>(_resources);\n    innerLayer->setBackgroundColor(Color::blue());\n    innerLayer->setFrame(Rect::makeXYWH(0, 0, 1, 1));\n    _contentLayer->addChild(innerLayer);\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 2, 2));\n\n    auto result = rasterInto(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                Color::blue(), Color::blue(), Color::red(), Color::red(),\n                Color::blue(), Color::blue(), Color::red(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    // Initially it should rasterize the entire bitmap (4x4 + margin = 6x6 = 36 pixels).\n    ASSERT_EQ(36, result.value().renderedPixelsCount);\n\n    // Raster again with no changes, it should not draw anything.\n\n    result = rasterInto(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n          Color::blue(), Color::blue(), Color::red(), Color::red(),\n          Color::blue(), Color::blue(), Color::red(), Color::red(),\n          Color::red(), Color::red(), Color::red(), Color::red(),\n          Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    ASSERT_EQ(0, result.value().renderedPixelsCount);\n\n    innerLayer->setFrame(Rect::makeXYWH(1, 0, 1, 1));\n\n    result = rasterInto(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                    Color::red(), Color::red(), Color::blue(), Color::blue(),\n                    Color::red(), Color::red(), Color::blue(), Color::blue(),\n                    Color::red(), Color::red(), Color::red(), Color::red(),\n                    Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    // With 1px AA margin, old (2x2) + new (2x2) positions overlap to ~24 pixels\n    ASSERT_EQ(24, result.value().renderedPixelsCount);\n\n    innerLayer->setBackgroundColor(Color::green());\n\n    result = rasterInto(outputBitmap);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                    Color::red(), Color::red(), Color::green(), Color::green(),\n                    Color::red(), Color::red(), Color::green(), Color::green(),\n                    Color::red(), Color::red(), Color::red(), Color::red(),\n                    Color::red(), Color::red(), Color::red(), Color::red(),\n                  // clang-format on\n              }));\n\n    // With 1px AA margin, 2x2 rect becomes 4x4 = 16 pixels\n    ASSERT_EQ(16, result.value().renderedPixelsCount);\n}\n\nTEST_F(RasterContextTests, canRasterWithInternalDeltaModeAndNoClear) {\n    _rasterContext =\n        makeShared<RasterContext>(_resources->getLogger(), ExternalSurfaceRasterizationMethod::ACCURATE, true);\n\n    auto outputBitmap = makeShared<TestBitmap>(4, 4);\n\n    outputBitmap->setPixels(std::initializer_list<Color>({\n        // clang-format off\n        Color::green(), Color::green(), Color::green(), Color::green(),\n        Color::green(), Color::green(), Color::green(), Color::green(),\n        Color::green(), Color::green(), Color::green(), Color::green(),\n        Color::green(), Color::green(), Color::green(), Color::green(),\n        // clang-format on\n    }));\n\n    _contentLayer->setBackgroundColor(Color::transparent());\n    auto innerLayer = makeLayer<Layer>(_resources);\n    innerLayer->setBackgroundColor(Color::blue());\n    innerLayer->setFrame(Rect::makeXYWH(1, 1, 2, 2));\n    _contentLayer->addChild(innerLayer);\n    _contentLayer->setFrame(Rect::makeXYWH(0, 0, 4, 4));\n\n    auto result = rasterInto(outputBitmap, false);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                  Color::green(), Color::green(), Color::green(), Color::green(),\n                  Color::green(), Color::blue(), Color::blue(), Color::green(),\n                  Color::green(), Color::blue(), Color::blue(), Color::green(),\n                  Color::green(), Color::green(), Color::green(), Color::green(),\n                  // clang-format on\n              }));\n\n    // With 1px AA margin, 4x4 rect becomes 6x6 = 36 pixels\n    ASSERT_EQ(36, result.value().renderedPixelsCount);\n\n    outputBitmap->setPixels(std::initializer_list<Color>({\n        // clang-format off\n        Color::green(), Color::green(), Color::green(), Color::green(),\n        Color::green(), Color::green(), Color::green(), Color::green(),\n        Color::green(), Color::green(), Color::green(), Color::green(),\n        Color::green(), Color::green(), Color::green(), Color::green(),\n        // clang-format on\n    }));\n\n    innerLayer->setFrame(Rect::makeXYWH(2, 2, 2, 2));\n\n    result = rasterInto(outputBitmap, false);\n    ASSERT_TRUE(result) << result.description();\n\n    ASSERT_EQ(*outputBitmap,\n              std::initializer_list<Color>({\n                  // clang-format off\n                  Color::green(), Color::green(), Color::green(), Color::green(),\n                  Color::green(), Color::green(), Color::green(), Color::green(),\n                  Color::green(), Color::green(), Color::blue(), Color::blue(),\n                  Color::green(), Color::green(), Color::blue(), Color::blue(),\n                  // clang-format on\n              }));\n\n    // With 1px AA margin, old (2x2) and new (2x2) positions with overlap = 25 pixels\n    ASSERT_EQ(25, result.value().renderedPixelsCount);\n}\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/test/src/RasterDamageResolver_tests.cpp",
    "content": "#include \"DisplayListBuilder.hpp\"\n#include \"snap_drawing/cpp/Drawing/Raster/RasterDamageResolver.hpp\"\n#include <gtest/gtest.h>\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nclass RasterDamageResolverTests : public ::testing::Test {\nprotected:\n    DisplayListBuilder _builder = DisplayListBuilder(100, 100);\n    RasterDamageResolver _damageResolver;\n\n    void SetUp() override {\n        _builder = DisplayListBuilder(100, 100);\n        _damageResolver = RasterDamageResolver();\n    }\n\n    std::vector<Rect> resolveDamage() {\n        _damageResolver.beginUpdates(100, 100);\n        _damageResolver.addDamageFromDisplayListUpdates(*_builder.displayList);\n        return _damageResolver.endUpdates();\n    }\n};\n\nTEST_F(RasterDamageResolverTests, returnsFullRectOnInInitialDraw) {\n    _builder.context(Vector(0, 0), 1.0, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n    });\n    auto damageRects = resolveDamage();\n\n    ASSERT_EQ(static_cast<size_t>(1), damageRects.size());\n    // Damage rects include 1px margin for anti-aliasing\n    ASSERT_EQ(Rect::makeXYWH(-1, -1, 102, 102), damageRects[0]);\n}\n\nTEST_F(RasterDamageResolverTests, returnsPartialDamageRect) {\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, true, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n    });\n\n    // First pass to populate the previous layer contents\n    resolveDamage();\n    auto damageRects = resolveDamage();\n\n    ASSERT_EQ(static_cast<size_t>(1), damageRects.size());\n    // Damage rects include 1px margin for anti-aliasing: (50-1, 50-1, 10+2, 10+2)\n    ASSERT_EQ(Rect::makeXYWH(49, 49, 12, 12), damageRects[0]);\n}\n\nTEST_F(RasterDamageResolverTests, returnsMultipleDamageRects) {\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, true, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n        _builder.context(Vector(20, 20), 1.0, 3, true, [&]() { _builder.rectangle(Size(15, 15), 1.0); });\n    });\n\n    // First pass to populate the previous layer contents\n    resolveDamage();\n    auto damageRects = resolveDamage();\n\n    ASSERT_EQ(static_cast<size_t>(2), damageRects.size());\n    // Damage rects include 1px margin for anti-aliasing\n    ASSERT_EQ(Rect::makeXYWH(49, 49, 12, 12), damageRects[0]);\n    ASSERT_EQ(Rect::makeXYWH(19, 19, 17, 17), damageRects[1]);\n}\n\nTEST_F(RasterDamageResolverTests, mergesMultipleDamageRectsWhenPossible) {\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, true, [&]() { _builder.rectangle(Size(20, 20), 1.0); });\n        _builder.context(Vector(20, 20), 1.0, 3, true, [&]() { _builder.rectangle(Size(40, 40), 1.0); });\n    });\n\n    // First pass to populate the previous layer contents\n    resolveDamage();\n    auto damageRects = resolveDamage();\n\n    ASSERT_EQ(static_cast<size_t>(1), damageRects.size());\n    // Rects (50,50,20,20) and (20,20,40,40) with 1px margin merge into (19,19,52,52)\n    ASSERT_EQ(Rect::makeXYWH(19, 19, 52, 52), damageRects[0]);\n}\n\nTEST_F(RasterDamageResolverTests, returnsEmptyDamageRectsWhenNoDamage) {\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, false, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n        _builder.context(Vector(20, 20), 1.0, 3, false, [&]() { _builder.rectangle(Size(50, 50), 1.0); });\n    });\n\n    // First pass to populate the previous layer contents\n    resolveDamage();\n    auto damageRects = resolveDamage();\n\n    ASSERT_EQ(static_cast<size_t>(0), damageRects.size());\n}\n\nTEST_F(RasterDamageResolverTests, returnsDamageOnInsertedLayer) {\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, false, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n        _builder.context(Vector(20, 20), 1.0, 3, false, [&]() { _builder.rectangle(Size(50, 50), 1.0); });\n    });\n\n    // First pass to populate the previous layer contents\n    resolveDamage();\n\n    _builder = DisplayListBuilder(100, 100);\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, false, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n        _builder.context(Vector(20, 20), 1.0, 3, false, [&]() { _builder.rectangle(Size(50, 50), 1.0); });\n        _builder.context(Vector(10, 10), 1.0, 4, true, [&]() { _builder.rectangle(Size(15, 15), 1.0); });\n    });\n\n    auto damageRects = resolveDamage();\n\n    ASSERT_EQ(static_cast<size_t>(1), damageRects.size());\n    // Damage rects include 1px margin for anti-aliasing: (10-1, 10-1, 15+2, 15+2)\n    ASSERT_EQ(Rect::makeXYWH(9, 9, 17, 17), damageRects[0]);\n}\n\nTEST_F(RasterDamageResolverTests, returnsDamageOnRemovedLayer) {\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, false, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n        _builder.context(Vector(20, 20), 1.0, 3, false, [&]() { _builder.rectangle(Size(50, 50), 1.0); });\n    });\n\n    // First pass to populate the previous layer contents\n    resolveDamage();\n\n    _builder = DisplayListBuilder(100, 100);\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, false, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n    });\n\n    auto damageRects = resolveDamage();\n\n    ASSERT_EQ(static_cast<size_t>(1), damageRects.size());\n    // Damage rects include 1px margin for anti-aliasing: (20-1, 20-1, 50+2, 50+2)\n    ASSERT_EQ(Rect::makeXYWH(19, 19, 52, 52), damageRects[0]);\n}\n\nTEST_F(RasterDamageResolverTests, returnsDamageOnMovedLayer) {\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(50, 50), 1.0, 2, false, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n        _builder.context(Vector(20, 20), 1.0, 3, false, [&]() { _builder.rectangle(Size(50, 50), 1.0); });\n    });\n\n    // First pass to populate the previous layer contents\n    resolveDamage();\n\n    _builder = DisplayListBuilder(100, 100);\n    _builder.context(Vector(0, 0), 1.0, 1, false, [&]() {\n        _builder.rectangle(Size(100, 100), 1.0);\n        _builder.context(Vector(10, 10), 1.0, 2, false, [&]() { _builder.rectangle(Size(10, 10), 1.0); });\n        _builder.context(Vector(20, 20), 1.0, 3, false, [&]() { _builder.rectangle(Size(50, 50), 1.0); });\n    });\n\n    auto damageRects = resolveDamage();\n\n    ASSERT_EQ(static_cast<size_t>(2), damageRects.size());\n    // Damage rects include 1px margin for anti-aliasing\n    ASSERT_EQ(Rect::makeXYWH(49, 49, 12, 12), damageRects[0]);\n    ASSERT_EQ(Rect::makeXYWH(9, 9, 12, 12), damageRects[1]);\n}\n\n} // namespace snap::drawing"
  },
  {
    "path": "snap_drawing/test/src/RotateGestureRecognizer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(RotateGestureRecognizer, canHandleRotateTwoPointers) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto rotateSnapshot = addRotateGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateBegan, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeMoved, 35, 40, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypePointerUp, 35, 40, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeUp, 35, 40, 1, 2, 1);\n    ASSERT_EQ(GestureRecognizerStateEnded, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(RotateGestureRecognizer, canHandleRotateTwoPointersInterrupted) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto rotateSnapshot = addRotateGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateBegan, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeMoved, 35, 40, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypePointerUp, 35, 40, 0, 0, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeMoved, 35, 40, 0, 0, 1);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeUp, 35, 40, 0, 0, 1);\n    ASSERT_EQ(GestureRecognizerStateEnded, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(RotateGestureRecognizer, canHandleRotateOneThenTwoPointers) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto rotateSnapshot = addRotateGesture(childView);\n\n    auto holdDuration = Duration::fromSeconds(GesturesConfiguration::getDefault().dragTouchSlop);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, rotateSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, rotateSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 0, 0, 1, holdDuration);\n    ASSERT_EQ(GestureRecognizerStatePossible, rotateSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 1, 1, 2, holdDuration);\n    ASSERT_EQ(GestureRecognizerStateBegan, rotateSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35, 1, 2, 2, holdDuration);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, rotateSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(RotateGestureRecognizer, canHandleRotateResumption) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto rotateSnapshot = addRotateGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35, 1, 1, 2);\n    ASSERT_EQ(GestureRecognizerStateBegan, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeMoved, 35, 40, 1, 2, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypePointerUp, 35, 40, 0, 0, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeMoved, 55, 60, 0, 0, 1);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypePointerDown, 55, 60, 0, 0, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(0.32175058, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeMoved, 60, 65, 0, 0, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(1.1071488, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypePointerUp, 60, 65, 0, 0, 2);\n    ASSERT_EQ(GestureRecognizerStateChanged, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(1.1071488, rotateSnapshot->rotateEvent.rotation);\n\n    container->dispatchEvent(TouchEventTypeUp, 60, 65, 0, 0, 1);\n    ASSERT_EQ(GestureRecognizerStateEnded, rotateSnapshot->state);\n    ASSERT_FLOAT_EQ(1.1071488, rotateSnapshot->rotateEvent.rotation);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/ScrollLayer_test.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n#include \"snap_drawing/cpp/Layers/Scroll/IOSScroller.hpp\"\n#include \"snap_drawing/cpp/Layers/ScrollLayer.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nenum class Velocity { low = 1000, med = 10000, high = 100000, shigh = 1000000 };\n\nclass TestScrollPerfLogger : public ScrollPerfLogger {\npublic:\n    int resumeCount = 0;\n    int pauseCount = 0;\n\n    void resume() override {\n        resumeCount++;\n    }\n\n    void pause(bool cancelLogging) override {\n        pauseCount++;\n    }\n};\n\nclass ScrollLayerRoot : public LayerRoot {\npublic:\n    int requestFocusCount = 0;\n\n    explicit ScrollLayerRoot(const Ref<Resources>& resources) : LayerRoot(resources) {}\n\n    void requestFocus(ILayer* layer) override {\n        requestFocusCount++;\n    }\n};\n\nclass TestScrollLayerListener : public ScrollLayerListener {\npublic:\n    Valdi::Function<std::optional<Point>(Point, Vector)> onScrollCallback;\n    Valdi::Function<void(Point)> onScrollEndCallback;\n    Valdi::Function<void(Point, Vector)> onDragStartCallback;\n    Valdi::Function<std::optional<Point>(Point, Vector)> onDragEndingCallback;\n\n    std::optional<Point> onScroll(const ScrollLayer& scrollLayer, const Point& point, const Vector& velocity) override {\n        if (onScrollCallback) {\n            return onScrollCallback(point, velocity);\n        }\n\n        return std::nullopt;\n    }\n\n    void onScrollEnd(const ScrollLayer& scrollLayer, const Point& point) override {\n        if (onScrollEndCallback) {\n            onScrollEndCallback(point);\n        }\n    }\n\n    void onDragStart(const ScrollLayer& scrollLayer, const Point& point, const Vector& velocity) override {\n        if (onDragStartCallback) {\n            onDragStartCallback(point, velocity);\n        }\n    }\n\n    std::optional<Point> onDragEnding(const ScrollLayer& scrollLayer,\n                                      const Point& point,\n                                      const Vector& velocity) override {\n        if (onDragEndingCallback) {\n            return onDragEndingCallback(point, velocity);\n        }\n\n        return std::nullopt;\n    }\n};\n\nclass ScrollLayerFixture : public ::testing::TestWithParam<Velocity> {\nprotected:\n    void SetUp() override {\n        auto resources = makeShared<Resources>(nullptr, 1.0f, ConsoleLogger::getLogger());\n\n        _listener = Valdi::makeShared<TestScrollLayerListener>();\n\n        _scrollLayer = makeLayer<ScrollLayer>(resources);\n        _scrollLayer->setScroller(Valdi::makeShared<IOSScroller>());\n        _scrollLayer->setListener(_listener);\n        _scrollLayer->setContentSize(Size(400, 2 * 800));\n        _velocity = static_cast<float>(GetParam());\n\n        _layerRoot = makeLayer<ScrollLayerRoot>(resources);\n        _layerRoot->setContentLayer(_scrollLayer, ContentLayerSizingModeMatchSize);\n        _layerRoot->setSize(Size(400.0f, 800.0f), 1.0f);\n    }\n\n    Scalar getMaxContentOffsetYWrapper() {\n        return _scrollLayer->getMaxContentOffsetY();\n    }\n\n    Scalar getMinContentOffsetYWrapper() {\n        return _scrollLayer->getMinContentOffsetY();\n    }\n\n    void setAtTop() {\n        _scrollLayer->applyContentOffset(0, 0, Vector(0, 0));\n    }\n\n    void setAtBottom() {\n        _scrollLayer->applyContentOffset(0, _scrollLayer->getMaxContentOffsetY(), Vector(0, 0));\n    }\n\n    void scrollAndFlushAnimations(GestureRecognizerState state,\n                                  const Point location,\n                                  const Size offset,\n                                  const Vector velocity) {\n        DragEvent event;\n        event.location = location;\n        event.offset = offset;\n        event.velocity = velocity;\n        _scrollLayer->onScrollDrag(state, event);\n\n        flushAnimations();\n    }\n\n    size_t flushAnimations() {\n        size_t frames = 0;\n        while (_layerRoot->needsProcessFrame()) {\n            _layerRoot->processFrame(TimePoint::fromSeconds(_currentTime));\n            _currentTime += 1.0 / 60.0;\n            frames++;\n        }\n\n        return frames;\n    }\n\n    void TearDown() override {}\n\n    Valdi::Ref<ScrollLayer> _scrollLayer;\n    Valdi::Ref<TestScrollLayerListener> _listener;\n    Ref<ScrollLayerRoot> _layerRoot;\n    float _velocity;\n    TimeInterval _currentTime = 0.0;\n};\n\nTEST_P(ScrollLayerFixture, testScrollDownStopsAtMaxOffset) {\n    setAtTop();\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 600), Size(0, 0), Vector(0, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, -200), Vector(0, _velocity));\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 200), Size(0, -400), Vector(0, _velocity));\n\n    auto test = _scrollLayer->getContentOffset().y;\n    auto limit = getMaxContentOffsetYWrapper();\n    ASSERT_EQ(test, limit);\n}\n\nTEST_P(ScrollLayerFixture, testScrollUpStopsAtMinOffset) {\n    setAtBottom();\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 200), Size(0, 0), Vector(0, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, 200), Vector(0, -_velocity));\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 600), Size(0, 400), Vector(0, -_velocity));\n\n    auto test = _scrollLayer->getContentOffset().y;\n    auto limit = getMinContentOffsetYWrapper();\n    ASSERT_EQ(test, limit);\n}\n\nTEST_P(ScrollLayerFixture, notifiesRequestFocusWhenDismissKeyboardOnDragIsEnabled) {\n    setAtTop();\n\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 200), Size(0, 0), Vector(0, 0));\n    ASSERT_EQ(0, _layerRoot->requestFocusCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, 200), Vector(0, -_velocity));\n    ASSERT_EQ(0, _layerRoot->requestFocusCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 600), Size(0, 400), Vector(0, -_velocity));\n    ASSERT_EQ(0, _layerRoot->requestFocusCount);\n\n    setAtTop();\n\n    _scrollLayer->setDismissKeyboardOnDrag(true);\n\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 200), Size(0, 0), Vector(0, 0));\n    ASSERT_EQ(1, _layerRoot->requestFocusCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, 200), Vector(0, -_velocity));\n    ASSERT_EQ(1, _layerRoot->requestFocusCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 600), Size(0, 400), Vector(0, -_velocity));\n    ASSERT_EQ(1, _layerRoot->requestFocusCount);\n\n    setAtTop();\n    ASSERT_EQ(1, _layerRoot->requestFocusCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 200), Size(0, 0), Vector(0, 0));\n    ASSERT_EQ(2, _layerRoot->requestFocusCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, 200), Vector(0, -_velocity));\n    ASSERT_EQ(2, _layerRoot->requestFocusCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 600), Size(0, 400), Vector(0, -_velocity));\n    ASSERT_EQ(2, _layerRoot->requestFocusCount);\n}\n\nTEST_P(ScrollLayerFixture, callsIntoScrollPerfLogger) {\n    auto scrollPerfLogger = Valdi::makeShared<TestScrollPerfLogger>();\n\n    _scrollLayer->setScrollPerfLogger(scrollPerfLogger);\n\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 600), Size(0, 0), Vector(0, 0));\n\n    ASSERT_EQ(1, scrollPerfLogger->resumeCount);\n    ASSERT_EQ(0, scrollPerfLogger->pauseCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, -200), Vector(0, _velocity));\n\n    ASSERT_EQ(1, scrollPerfLogger->resumeCount);\n    ASSERT_EQ(0, scrollPerfLogger->pauseCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 200), Size(0, -400), Vector(0, _velocity));\n\n    ASSERT_EQ(1, scrollPerfLogger->resumeCount);\n    ASSERT_EQ(1, scrollPerfLogger->pauseCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 600), Size(0, 0), Vector(0, 0));\n\n    ASSERT_EQ(2, scrollPerfLogger->resumeCount);\n    ASSERT_EQ(1, scrollPerfLogger->pauseCount);\n\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 200), Size(0, -400), Vector(0, _velocity));\n\n    ASSERT_EQ(2, scrollPerfLogger->resumeCount);\n    ASSERT_EQ(2, scrollPerfLogger->pauseCount);\n}\n\nTEST_P(ScrollLayerFixture, canCancelScrollWhileAnimatingScroll) {\n    setAtBottom();\n    _scrollLayer->setContentOffset(Point::make(0, 0), Vector::makeEmpty(), true);\n\n    _listener->onScrollCallback = [&](auto point, auto velocity) -> std::optional<Point> {\n        if (point != Point::make(0, 0)) {\n            _scrollLayer->setContentOffset(Point::make(0, 0), Vector::makeEmpty(), false);\n        }\n        return std::nullopt;\n    };\n\n    auto processedFrames = flushAnimations();\n\n    ASSERT_EQ(2, processedFrames);\n}\n\nTEST_P(ScrollLayerFixture, onlyPagesToNeighboringHorizontalScreens) {\n    _scrollLayer->setContentSize(Size(400 * 5, 800));\n    _scrollLayer->setPagingEnabled(true);\n    _scrollLayer->setHorizontal(true);\n    setAtTop();\n\n    // Standard velocity swipe, one page right\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(0, 200), Size(0, 0), Vector(0, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 200), Size(-200, 0), Vector(400, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(300, 200), Size(-400, 0), Vector(400, 0));\n\n    auto xLoc1 = _scrollLayer->getContentOffset().x;\n    ASSERT_EQ(xLoc1, 400);\n\n    // High velocity swipe, one page right\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(0, 200), Size(0, 0), Vector(0, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 200), Size(-200, 0), Vector(400, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(300, 200), Size(-400, 0), Vector(8000, 0));\n\n    auto xLoc2 = _scrollLayer->getContentOffset().x;\n    ASSERT_EQ(xLoc2, 800);\n\n    // Uncertain swipe, same page\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(300, 200), Size(0, 0), Vector(0, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 200), Size(-200, 0), Vector(-400, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(300, 200), Size(100, 0), Vector(50, 0));\n\n    auto xLoc3 = _scrollLayer->getContentOffset().x;\n    ASSERT_EQ(static_cast<int>(xLoc3), 800);\n}\n\nTEST_P(ScrollLayerFixture, onlyPagesToNeighboringVerticalScreens) {\n    _scrollLayer->setContentSize(Size(400, 5 * 800));\n    _scrollLayer->setPagingEnabled(true);\n    setAtTop();\n\n    // Standard velocity swipe, one page down\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 200), Size(0, 0), Vector(0, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, -200), Vector(0, 800));\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 600), Size(0, -400), Vector(0, 800));\n\n    auto yLoc1 = _scrollLayer->getContentOffset().y;\n    ASSERT_EQ(static_cast<int>(yLoc1), 800);\n\n    // High velocity swipe, one page down\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 200), Size(0, 0), Vector(0, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, -200), Vector(0, 800));\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 600), Size(0, -400), Vector(0, 8000));\n\n    auto yLoc2 = _scrollLayer->getContentOffset().y;\n    ASSERT_EQ(static_cast<int>(yLoc2), 1600);\n\n    // Uncertain swipe, same page\n    scrollAndFlushAnimations(GestureRecognizerStateBegan, Point(200, 200), Size(0, 0), Vector(0, 0));\n    scrollAndFlushAnimations(GestureRecognizerStateChanged, Point(200, 400), Size(0, -200), Vector(0, 800));\n    scrollAndFlushAnimations(GestureRecognizerStateEnded, Point(200, 200), Size(0, 200), Vector(0, -50));\n\n    auto yLoc3 = _scrollLayer->getContentOffset().y;\n    ASSERT_EQ(static_cast<int>(yLoc3), 1600);\n}\n\nINSTANTIATE_TEST_SUITE_P(ScrollLayerTests,\n                         ScrollLayerFixture,\n                         ::testing::Values(Velocity::low, Velocity::med, Velocity::high, Velocity::shigh));\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/SingleTapGestureRecognizer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(SingleTapGestureRecognizer, canHandleSingleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStateEnded, singleTapSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(SingleTapGestureRecognizer, canHandleSingleTapWithDoubleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n    auto doubleTapSnapshot = addDoubleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    ASSERT_FALSE(container->root->getTouchDispatcher().isEmpty());\n\n    container->dispatchEvent(TouchEventTypeIdle, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n\n    ASSERT_EQ(GestureRecognizerStateEnded, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(SingleTapGestureRecognizer, canHandleSingleTapQuickTwo) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStateEnded, singleTapSnapshot->state);\n    ASSERT_EQ(1, singleTapSnapshot->counter);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStateEnded, singleTapSnapshot->state);\n    ASSERT_EQ(2, singleTapSnapshot->counter);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(SingleTapGestureRecognizer, canHandleSingleTapWithDrag) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n    auto dragSnapshot = addDragGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, dragSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(SingleTapGestureRecognizer, canHandleSingleTapWithFailedDoubleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n    auto doubleTapSnapshot = addDoubleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStateEnded, singleTapSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/TextLayout_Tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n#include \"snap_drawing/cpp/Text/TextLayout.hpp\"\n#include \"snap_drawing/cpp/Text/TextLayoutBuilder.hpp\"\n#include \"snap_drawing/cpp/Text/TextShaper.hpp\"\n#include \"snap_drawing/cpp/Utils/JSONUtils.hpp\"\n#include \"snap_drawing/cpp/Utils/UTFUtils.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\n#include \"TestDataUtils.hpp\"\n#include \"hb.h\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nstruct TextLayoutTestContainer {\n    Ref<FontManager> fontManager;\n\n    Ref<Font> avenirNext;\n    Ref<Font> arabicFont;\n\n    TextLayoutTestContainer() {\n        fontManager = makeShared<FontManager>(ConsoleLogger::getLogger());\n        fontManager->load();\n\n        avenirNext = registerFont(\"Avenir Next\",\n                                  FontStyle(FontWidthNormal, FontWeightNormal, FontSlantUpright),\n                                  \"AvenirNext-Regular\",\n                                  \"avenir_next_regular\",\n                                  false);\n\n        auto arabicText = utf8ToUnicode(\"ر\");\n        SC_ASSERT(arabicText.size() == 1);\n\n        auto arabicFont = fontManager->getCompatibleFont(avenirNext, nullptr, 0, arabicText[0]);\n        SC_ASSERT(arabicFont.success(), arabicFont.description());\n        this->arabicFont = arabicFont.moveValue();\n        SC_ASSERT(this->avenirNext->getDescription() != this->arabicFont->getDescription());\n    }\n\n    Ref<Font> getFontWithName(std::string_view fontName) {\n        auto font =\n            fontManager->getFontWithNameAndSize(Valdi::StringCache::getGlobal().makeString(fontName), 17, 1.0, true);\n        SC_ASSERT(font.success(), font.description());\n\n        return font.moveValue();\n    }\n\n    Ref<Font> registerFont(std::string_view fontFamilyName,\n                           FontStyle fontStyle,\n                           std::string_view fontName,\n                           const std::string& filename,\n                           bool canUseAsFallback) {\n        auto testData = getTestData(filename + \".ttf\");\n        SC_ASSERT(testData.success(), testData.description());\n\n        fontManager->registerTypeface(\n            Valdi::StringCache::getGlobal().makeString(fontFamilyName), fontStyle, canUseAsFallback, testData.value());\n\n        return getFontWithName(fontName);\n    }\n\n    Ref<Font> getAppleEmojiFont() {\n        return getFontWithName(\"Apple Color Emoji\");\n    }\n\n    Ref<Font> getDevanagariFont() {\n        return getFontWithName(\"Kohinoor Devanagari\");\n    }\n\n    Ref<Font> getSinhalaFont() {\n        return getFontWithName(\"Sinhala Sangam MN\");\n    }\n};\n\nValdi::Value makeTextLayoutJSON(Size maxSize,\n                                std::initializer_list<TextLayoutEntry> entries,\n                                std::initializer_list<TextLayoutDecorationEntry> decorations = {}) {\n    return TextLayout(maxSize,\n                      std::vector<TextLayoutEntry>(entries),\n                      std::vector<TextLayoutDecorationEntry>(decorations),\n                      {},\n                      true)\n        .toJSONValue();\n}\n\nstruct TextShaperTestContainer {\n    Ref<TextShaper> textShaper;\n    TextSegmentProperties segment;\n    std::vector<TextSegmentProperties> segments;\n\n    TextShaperTestContainer() : segment(false, 0, 0, TextScript::invalid()) {\n        textShaper = TextShaper::make(true);\n    }\n\n    void resolveSingleSegmentTextProperties(std::string str, bool isRightToLeft, bool expectsResolvedAsRightToLeft) {\n        resolveMultipleSegmentsTextProperties(str, isRightToLeft, expectsResolvedAsRightToLeft);\n        ASSERT_EQ(static_cast<size_t>(1), segments.size());\n\n        segment = segments[0];\n    }\n\n    void resolveMultipleSegmentsTextProperties(std::string str, bool isRightToLeft, bool expectsResolvedAsRightToLeft) {\n        segments.clear();\n\n        auto unicode = utf8ToUnicode(str);\n        auto paragraphList = textShaper->resolveParagraphs(unicode.data(), unicode.size(), isRightToLeft);\n\n        ASSERT_EQ(static_cast<size_t>(1), paragraphList.size());\n        ASSERT_EQ(expectsResolvedAsRightToLeft, paragraphList[0].baseDirectionIsRightToLeft);\n\n        for (const auto& segment : paragraphList[0].segments) {\n            segments.emplace_back(segment);\n        }\n    }\n};\n\nTEST(TextShaper, resolvesLTRInLTRContext) {\n    TextShaperTestContainer testContainer;\n    auto& segment = testContainer.segment;\n\n    testContainer.resolveSingleSegmentTextProperties(\"hello\", false, false);\n\n    ASSERT_FALSE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(5), segment.end);\n\n    testContainer.resolveSingleSegmentTextProperties(\"hello word\", false, false);\n\n    ASSERT_FALSE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(10), segment.end);\n\n    testContainer.resolveSingleSegmentTextProperties(\"  hello world  \", false, false);\n\n    ASSERT_FALSE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(15), segment.end);\n}\n\nTEST(TextShaper, resolvesRTLInLTRContext) {\n    TextShaperTestContainer testContainer;\n    auto& segment = testContainer.segment;\n\n    testContainer.resolveSingleSegmentTextProperties(\"مصر\", false, true);\n\n    ASSERT_TRUE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(3), segment.end);\n\n    testContainer.resolveSingleSegmentTextProperties(\"مصر مصر\", false, true);\n\n    ASSERT_TRUE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(7), segment.end);\n\n    testContainer.resolveSingleSegmentTextProperties(\"  مصر مصر  \", false, true);\n\n    ASSERT_TRUE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(11), segment.end);\n}\n\nTEST(TextShaper, resolvesLTRinRTLContext) {\n    TextShaperTestContainer testContainer;\n    auto& segment = testContainer.segment;\n\n    testContainer.resolveSingleSegmentTextProperties(\"hello\", true, false);\n\n    ASSERT_FALSE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(5), segment.end);\n\n    testContainer.resolveSingleSegmentTextProperties(\"hello world\", true, false);\n\n    ASSERT_FALSE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(11), segment.end);\n\n    testContainer.resolveSingleSegmentTextProperties(\"  hello world  \", true, false);\n\n    ASSERT_FALSE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(15), segment.end);\n}\n\nTEST(TextShaper, resolvesRTLInRTLContext) {\n    TextShaperTestContainer testContainer;\n    auto& segment = testContainer.segment;\n\n    testContainer.resolveSingleSegmentTextProperties(\"مصر\", true, true);\n\n    ASSERT_TRUE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(3), segment.end);\n\n    testContainer.resolveSingleSegmentTextProperties(\"مصر مصر\", true, true);\n\n    ASSERT_TRUE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(7), segment.end);\n\n    testContainer.resolveSingleSegmentTextProperties(\"  مصر مصر  \", true, true);\n\n    ASSERT_TRUE(segment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), segment.start);\n    ASSERT_EQ(static_cast<size_t>(11), segment.end);\n}\n\nTEST(TextShaper, resolvesBidiInLTRContext) {\n    TextShaperTestContainer testContainer;\n\n    testContainer.resolveMultipleSegmentsTextProperties(\"bahrain مصر kuwait\", false, false);\n\n    ASSERT_EQ(static_cast<size_t>(3), testContainer.segments.size());\n\n    auto firstSegment = testContainer.segments[0];\n    auto secondSegment = testContainer.segments[1];\n    auto thirdSegment = testContainer.segments[2];\n\n    ASSERT_FALSE(firstSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), firstSegment.start);\n    ASSERT_EQ(static_cast<size_t>(8), firstSegment.end);\n\n    ASSERT_TRUE(secondSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(8), secondSegment.start);\n    ASSERT_EQ(static_cast<size_t>(11), secondSegment.end);\n\n    ASSERT_FALSE(thirdSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(11), thirdSegment.start);\n    ASSERT_EQ(static_cast<size_t>(18), thirdSegment.end);\n\n    testContainer.resolveMultipleSegmentsTextProperties(\"  bahrain مصر kuwait  \", false, false);\n\n    ASSERT_EQ(static_cast<size_t>(3), testContainer.segments.size());\n\n    firstSegment = testContainer.segments[0];\n    secondSegment = testContainer.segments[1];\n    thirdSegment = testContainer.segments[2];\n\n    ASSERT_FALSE(firstSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), firstSegment.start);\n    ASSERT_EQ(static_cast<size_t>(10), firstSegment.end);\n\n    ASSERT_TRUE(secondSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(10), secondSegment.start);\n    ASSERT_EQ(static_cast<size_t>(13), secondSegment.end);\n\n    ASSERT_FALSE(thirdSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(13), thirdSegment.start);\n    ASSERT_EQ(static_cast<size_t>(22), thirdSegment.end);\n}\n\nTEST(TextShaper, resolvesBidiInRTLContext) {\n    TextShaperTestContainer testContainer;\n\n    testContainer.resolveMultipleSegmentsTextProperties(\"bahrain مصر kuwait\", true, false);\n\n    ASSERT_EQ(static_cast<size_t>(3), testContainer.segments.size());\n\n    auto firstSegment = testContainer.segments[0];\n    auto secondSegment = testContainer.segments[1];\n    auto thirdSegment = testContainer.segments[2];\n\n    ASSERT_FALSE(firstSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), firstSegment.start);\n    ASSERT_EQ(static_cast<size_t>(8), firstSegment.end);\n\n    ASSERT_TRUE(secondSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(8), secondSegment.start);\n    ASSERT_EQ(static_cast<size_t>(11), secondSegment.end);\n\n    ASSERT_FALSE(thirdSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(11), thirdSegment.start);\n    ASSERT_EQ(static_cast<size_t>(18), thirdSegment.end);\n\n    testContainer.resolveMultipleSegmentsTextProperties(\"  bahrain مصر kuwait  \", true, false);\n\n    ASSERT_EQ(static_cast<size_t>(3), testContainer.segments.size());\n\n    firstSegment = testContainer.segments[0];\n    secondSegment = testContainer.segments[1];\n    thirdSegment = testContainer.segments[2];\n\n    ASSERT_FALSE(firstSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(0), firstSegment.start);\n    ASSERT_EQ(static_cast<size_t>(10), firstSegment.end);\n\n    ASSERT_TRUE(secondSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(10), secondSegment.start);\n    ASSERT_EQ(static_cast<size_t>(13), secondSegment.end);\n\n    ASSERT_FALSE(thirdSegment.isRTL);\n    ASSERT_EQ(static_cast<size_t>(13), thirdSegment.start);\n    ASSERT_EQ(static_cast<size_t>(22), thirdSegment.end);\n}\n\nTEST(TestShaper, resolvesParagraphs) {\n    TextShaperTestContainer testContainer;\n    auto singleLine = utf8ToUnicode(\"This is a single line\");\n\n    auto paragraphs = testContainer.textShaper->resolveParagraphs(singleLine.data(), singleLine.size(), false);\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs.size());\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs[0].segments.size());\n    ASSERT_EQ(static_cast<size_t>(0), paragraphs[0].segments[0].start);\n    ASSERT_EQ(static_cast<size_t>(21), paragraphs[0].segments[0].end);\n\n    auto twoLines = utf8ToUnicode(\"Line1\\nLineTwo\");\n    paragraphs = testContainer.textShaper->resolveParagraphs(twoLines.data(), twoLines.size(), false);\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs.size());\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs[0].segments.size());\n    ASSERT_EQ(static_cast<size_t>(0), paragraphs[0].segments[0].start);\n    ASSERT_EQ(static_cast<size_t>(13), paragraphs[0].segments[0].end);\n\n    auto groupedLines = utf8ToUnicode(\"\\n\\n\\nLine1\\n\\nLineTwo\\n\\n\\n\\n\");\n    paragraphs = testContainer.textShaper->resolveParagraphs(groupedLines.data(), groupedLines.size(), false);\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs.size());\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs[0].segments.size());\n    ASSERT_EQ(static_cast<size_t>(0), paragraphs[0].segments[0].start);\n    ASSERT_EQ(static_cast<size_t>(21), paragraphs[0].segments[0].end);\n\n    auto differentDirectionParagraphs = utf8ToUnicode(\"\\n\\n\\nLine1\\n\\nقرأ Wikipedia™ طوال اليوم\\n\\n\\n\\n\");\n    paragraphs = testContainer.textShaper->resolveParagraphs(\n        differentDirectionParagraphs.data(), differentDirectionParagraphs.size(), false);\n    ASSERT_EQ(static_cast<size_t>(3), paragraphs.size());\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs[0].segments.size());\n    ASSERT_EQ(static_cast<size_t>(0), paragraphs[0].segments[0].start);\n    ASSERT_EQ(static_cast<size_t>(10), paragraphs[0].segments[0].end);\n\n    ASSERT_EQ(static_cast<size_t>(3), paragraphs[1].segments.size());\n    ASSERT_EQ(static_cast<size_t>(23), paragraphs[1].segments[0].start);\n    ASSERT_EQ(static_cast<size_t>(36), paragraphs[1].segments[0].end);\n    ASSERT_EQ(static_cast<size_t>(14), paragraphs[1].segments[1].start);\n    ASSERT_EQ(static_cast<size_t>(23), paragraphs[1].segments[1].end);\n    ASSERT_EQ(static_cast<size_t>(10), paragraphs[1].segments[2].start);\n    ASSERT_EQ(static_cast<size_t>(14), paragraphs[1].segments[2].end);\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs[2].segments.size());\n    ASSERT_EQ(static_cast<size_t>(36), paragraphs[2].segments[0].start);\n    ASSERT_EQ(static_cast<size_t>(39), paragraphs[2].segments[0].end);\n}\n\nTEST(TestShaper, separatesParagraphSegmentsByScript) {\n    TextShaperTestContainer testContainer;\n\n    auto singleLine = utf8ToUnicode(\"123 Hello 456 क्‍ष ශ්‍ර\");\n\n    auto paragraphs = testContainer.textShaper->resolveParagraphs(singleLine.data(), singleLine.size(), false);\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs.size());\n\n    ASSERT_EQ(static_cast<size_t>(3), paragraphs[0].segments.size());\n    ASSERT_EQ(HB_SCRIPT_LATIN, paragraphs[0].segments[0].script.code);\n    ASSERT_EQ(static_cast<size_t>(0), paragraphs[0].segments[0].start);\n    ASSERT_EQ(static_cast<size_t>(14), paragraphs[0].segments[0].end);\n    ASSERT_EQ(HB_SCRIPT_DEVANAGARI, paragraphs[0].segments[1].script.code);\n    ASSERT_EQ(static_cast<size_t>(14), paragraphs[0].segments[1].start);\n    ASSERT_EQ(static_cast<size_t>(19), paragraphs[0].segments[1].end);\n    ASSERT_EQ(HB_SCRIPT_SINHALA, paragraphs[0].segments[2].script.code);\n    ASSERT_EQ(static_cast<size_t>(19), paragraphs[0].segments[2].start);\n    ASSERT_EQ(static_cast<size_t>(23), paragraphs[0].segments[2].end);\n}\n\nTEST(TestShaper, associatesWeakScriptWithCommon) {\n    TextShaperTestContainer testContainer;\n\n    auto singleLine = utf8ToUnicode(\"123 456 \");\n\n    auto paragraphs = testContainer.textShaper->resolveParagraphs(singleLine.data(), singleLine.size(), false);\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs.size());\n\n    ASSERT_EQ(static_cast<size_t>(1), paragraphs[0].segments.size());\n    ASSERT_EQ(HB_SCRIPT_COMMON, paragraphs[0].segments[0].script.code);\n    ASSERT_EQ(static_cast<size_t>(0), paragraphs[0].segments[0].start);\n    ASSERT_EQ(static_cast<size_t>(8), paragraphs[0].segments[0].end);\n}\n\n// Since we rely on the toJSON to simplify checks, we do this test upfront to confirm that the json conversions work\nTEST(TextLayout, canBeConvertedToJSON) {\n    TextLayoutTestContainer testContainer;\n\n    auto size = Size::make(13, 24);\n    auto bounds = Rect::makeXYWH(1, 2, 3, 4);\n    auto segmentsBounds = Rect::makeXYWH(4, 3, 2, 1);\n    auto decorationBounds = Rect::makeXYWH(9, 8, 7, 6);\n\n    auto segments = ValueArray::make(1);\n    segments->emplace(0,\n                      Value()\n                          .setMapValue(\"bounds\", toJSONValue(segmentsBounds))\n                          .setMapValue(\"characters\", Value(\"Hello world\"))\n                          .setMapValue(\"font\", Value(\"Avenir Next 17 x1\")));\n\n    auto decorations = ValueArray::make(1);\n    decorations->emplace(\n        0, Value().setMapValue(\"bounds\", toJSONValue(decorationBounds)).setMapValue(\"predraw\", Value(true)));\n\n    auto entries = ValueArray::make(1);\n\n    entries->emplace(0, Value().setMapValue(\"bounds\", toJSONValue(bounds)).setMapValue(\"segments\", Value(segments)));\n\n    auto expectedJSON = Value()\n                            .setMapValue(\"maxSize\", toJSONValue(size))\n                            .setMapValue(\"entries\", Value(entries))\n                            .setMapValue(\"decorations\", Value(decorations));\n\n    ASSERT_EQ(expectedJSON,\n              makeTextLayoutJSON(\n                  size,\n                  {TextLayoutEntry(bounds,\n                                   std::nullopt,\n                                   {TextLayoutEntrySegment(segmentsBounds, testContainer.avenirNext, \"Hello world\")})},\n                  {TextLayoutDecorationEntry(decorationBounds, true, std::nullopt)}));\n\n    ASSERT_NE(\n        expectedJSON,\n        makeTextLayoutJSON(\n            size,\n            {TextLayoutEntry(\n                bounds, std::nullopt, {TextLayoutEntrySegment(segmentsBounds, testContainer.avenirNext, \"Not good\")})},\n            {TextLayoutDecorationEntry(decorationBounds, true, std::nullopt)}));\n\n    ASSERT_NE(\n        expectedJSON,\n        makeTextLayoutJSON(\n            size,\n            {TextLayoutEntry(bounds,\n                             std::nullopt,\n                             {TextLayoutEntrySegment(segmentsBounds, testContainer.avenirNext, \"Hello world\")})}));\n\n    ASSERT_NE(\n        expectedJSON,\n        makeTextLayoutJSON(\n            size,\n            {TextLayoutEntry(bounds,\n                             std::nullopt,\n                             {TextLayoutEntrySegment(segmentsBounds, testContainer.avenirNext, \"Hello world\")})}));\n\n    ASSERT_NE(expectedJSON,\n              makeTextLayoutJSON(size,\n                                 {TextLayoutEntry(bounds, std::nullopt, {})},\n                                 {TextLayoutDecorationEntry(decorationBounds, true, std::nullopt)}));\n\n    ASSERT_NE(expectedJSON,\n              makeTextLayoutJSON(\n                  size,\n                  {TextLayoutEntry(Rect::makeXYWH(0, 0, 0, 0),\n                                   std::nullopt,\n                                   {TextLayoutEntrySegment(segmentsBounds, testContainer.avenirNext, \"Hello world\")})},\n                  {TextLayoutDecorationEntry(decorationBounds, true, std::nullopt)}));\n}\n\nTEST(TextLayout, canLayoutSingleLine) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(10000, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 1, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello World!\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    auto expectedBounds = Rect::makeXYWH(0, 0, 97.0, 23.222000);\n    auto segmentBounds = expectedBounds;\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(expectedBounds,\n                                   std::nullopt,\n                                   {TextLayoutEntrySegment(segmentBounds, testContainer.avenirNext, \"Hello World!\")})}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, canLayoutMultipleLinesWithExplicitNewLines) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(10000, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello world\\nand welcome!\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0, 0, 111.000000, 46.444000),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 0.0, 88.000000, 23.222), testContainer.avenirNext, \"Hello world\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 23.222000, 111.000000, 23.222), testContainer.avenirNext, \"and welcome!\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, canLayoutWithExplicitTrailingNewLines) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(10000, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello world\\n\\n\\n\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(maxSize,\n                                 {TextLayoutEntry(Rect::makeXYWH(0, 0, 88.000000, 92.888000),\n                                                  std::nullopt,\n                                                  {\n                                                      TextLayoutEntrySegment(Rect::makeXYWH(0, 0.0, 88.000000, 23.222),\n                                                                             testContainer.avenirNext,\n                                                                             \"Hello world\"),\n                                                  })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, canLayoutMultipleLinesByWordBreak) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello world and welcome!\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0, 0.000000, 111.000000, 46.444000),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 0.0, 88.000000, 23.222), testContainer.avenirNext, \"Hello world\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 23.222000, 111.000000, 23.222), testContainer.avenirNext, \"and welcome!\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, canLayoutMultipleLinesByCharacterBreak) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\n        \"Thisisaverylongtextthatcannotfitinasingleline\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    builder.setLineBreakStrategy(LineBreakStrategy::ByCharacter);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0, 0.000000, 120.0, 69.666000),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 0.0, 120, 23.222000), testContainer.avenirNext, \"Thisisaverylong\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 23.222, 119, 23.222),\n                        testContainer.avenirNext,\n                        \"textthatcannotf\"), /* Note: the 'i' after the 'f' should have been merged as fi */\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 46.444000, 103.000000, 23.222), testContainer.avenirNext, \"tinasingleline\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, addsEllipsisWhenDoesntFit) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(80, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 1, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"This text will not fit\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_FALSE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0, 0.000000, 76.000, 23.222),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 0.0, 59.000, 23.222), testContainer.avenirNext, \"This tex\"),\n                    TextLayoutEntrySegment(Rect::makeXYWH(59.000, 0.0, 17.0, 23.222), testContainer.avenirNext, \"…\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, breaksWordByCharacterWhenDoesntFit) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(80, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 1, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\n        \"Thisisaverylongtextthatcannotfitinasingleline\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_FALSE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0, 0.000000, 78.000, 23.222),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0, 0.0, 61.000, 23.222), testContainer.avenirNext, \"Thisisav\"),\n                    TextLayoutEntrySegment(Rect::makeXYWH(61.000, 0.0, 17.0, 23.222), testContainer.avenirNext, \"…\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsMultipleAppendWithDifferentFonts) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(10000, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    auto scaledFont = testContainer.avenirNext->withScale(0.5);\n    builder.append(\"Hello \", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n    builder.append(\"World\", scaledFont, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {\n                TextLayoutEntry(\n                    Rect::makeXYWH(0, 0.000000, 67.000, 23.222),\n                    std::nullopt,\n                    {\n                        TextLayoutEntrySegment(\n                            Rect::makeXYWH(0, 0.0, 44.000000, 23.222000), testContainer.avenirNext, \"Hello \"),\n                        TextLayoutEntrySegment(Rect::makeXYWH(44.000000, 0.0, 23.000, 11.611000), scaledFont, \"World\"),\n                    }),\n            }),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsRightTextAlignment) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignRight, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello world and welcome!\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(Rect::makeXYWH(9.000000, 0.000000, 111.000000, 46.444000),\n                                   std::nullopt,\n                                   {\n                                       TextLayoutEntrySegment(Rect::makeXYWH(32.000000, 0.000000, 88.000000, 23.222),\n                                                              testContainer.avenirNext,\n                                                              \"Hello world\"),\n                                       TextLayoutEntrySegment(Rect::makeXYWH(9.000000, 23.222000, 111.000000, 23.222),\n                                                              testContainer.avenirNext,\n                                                              \"and welcome!\"),\n                                   })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsCenteredTextAlignment) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignCenter, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello world and welcome!\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(Rect::makeXYWH(4.500000, 0.000000, 111.000000, 46.444000),\n                                   std::nullopt,\n                                   {\n                                       TextLayoutEntrySegment(Rect::makeXYWH(16.000000, 0.000000, 88.000000, 23.222),\n                                                              testContainer.avenirNext,\n                                                              \"Hello world\"),\n                                       TextLayoutEntrySegment(Rect::makeXYWH(4.500000, 23.222, 111.0000, 23.222),\n                                                              testContainer.avenirNext,\n                                                              \"and welcome!\"),\n                                   })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsJustifiedTextAlignment) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignJustify, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello world and welcome!\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0.000000, 0.000000, 120.000000, 46.444000),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0.000000, 0.000000, 40.00000, 23.222), testContainer.avenirNext, \"Hello\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(76.000000, 0.000000, 44.000000, 23.222), testContainer.avenirNext, \"world\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0.00000, 23.222, 30.0000, 23.222), testContainer.avenirNext, \"and\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(43.000000, 23.222, 77.0000, 23.222), testContainer.avenirNext, \"welcome!\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsLineHeightMultiple) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignCenter, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello world and welcome!\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(4.500000, 0.0, 111.000000, 69.666),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(16.000000, 0, 88.000000, 34.8333), testContainer.avenirNext, \"Hello world\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(4.500000, 34.8333, 111.000, 34.8333), testContainer.avenirNext, \"and welcome!\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsMaxHeight) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 50);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello world and welcome!\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n    auto layout = builder.build();\n\n    ASSERT_FALSE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(\n                      Rect::makeXYWH(0.000000, 0.0, 105.000000, 34.833000),\n                      std::nullopt,\n                      {\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(0.000000, 0, 88.000000, 34.8333), testContainer.avenirNext, \"Hello world\"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(88.000000, 0, 17.000, 34.8333), testContainer.avenirNext, \"…\"),\n                      })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsFontFallback) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignCenter, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"مصر\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(Rect::makeXYWH(45.000000, 0.0, 30.000000, 31.264),\n                                   std::nullopt,\n                                   {\n                                       TextLayoutEntrySegment(Rect::makeXYWH(45.000000, 0.00, 30.000000, 31.264),\n                                                              testContainer.arabicFont,\n                                                              \"مصر\"),\n                                   })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsFontFallbackFromRegisteredFont) {\n    TextLayoutTestContainer testContainer;\n\n    auto appleColorEmoji = testContainer.getAppleEmojiFont();\n\n    auto maxSize = Size::make(120, 10000);\n\n    Ref<TextLayout> layout;\n    {\n        TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n        builder.setIncludeSegments(true);\n\n        builder.append(\"😊\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n\n        layout = builder.build();\n    }\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    // Should initially use Apple Color Emoji\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(Rect::makeXYWH(0.000000, 0.0, 21.0, 40.359000),\n                                   std::nullopt,\n                                   {\n                                       TextLayoutEntrySegment(\n                                           Rect::makeXYWH(0.000000, 0.00, 21.0, 40.359000), appleColorEmoji, \"😊\"),\n                                   })}),\n              layout->toJSONValue());\n\n    // We now regsiter our custom emoji font and retry\n    auto androidEmojiFont = testContainer.registerFont(\"Noto Color Emoji\",\n                                                       FontStyle(FontWidthNormal, FontWeightNormal, FontSlantUpright),\n                                                       \"NotoColorEmoji-Regular\",\n                                                       \"NotoColorEmoji-Regular\",\n                                                       /* canUseAsFallback */ true);\n\n    {\n        TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n        builder.setIncludeSegments(true);\n\n        builder.append(\"😊\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n\n        layout = builder.build();\n    }\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    // We should have used the Noto Color Emoji font\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(\n                      Rect::makeXYWH(0.000000, 0.0, 21.0, 29.883),\n                      std::nullopt,\n                      {\n                          TextLayoutEntrySegment(Rect::makeXYWH(0.000000, 0.00, 21.0, 29.883), androidEmojiFont, \"😊\"),\n                      })}),\n              layout->toJSONValue());\n}\n\n// Text incorrect for appleColorEmojiFont\n// Expected: 🏳🏳👨👨👨👨\n// Actual: 🏳👨👨\nTEST(TextLayout, DISABLED_supportsZeroWidthJoiner) {\n    TextLayoutTestContainer testContainer;\n\n    auto appleColorEmojiFont = testContainer.getAppleEmojiFont();\n    auto devanagariFont = testContainer.getDevanagariFont();\n    auto sinhalaFont = testContainer.getSinhalaFont();\n\n    auto maxSize = Size::make(2000, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"🏳️‍🌈👨‍🌾👨‍🦰 क्‍ष ශ්‍ර\",\n                   testContainer.avenirNext,\n                   1.5,\n                   0.0,\n                   TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0.000, 0.0, 104.000, 40.359),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0.000, 0.00, 63.000000, 40.359000), appleColorEmojiFont, \"🏳🏳👨👨👨👨\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(63.000000, 0.00, 4.000000, 34.833), testContainer.avenirNext, \" \"),\n                    TextLayoutEntrySegment(Rect::makeXYWH(67.000000, 0.00, 25.000000, 35.700), devanagariFont, \"ककष \"),\n                    TextLayoutEntrySegment(Rect::makeXYWH(92.000000, 0.00, 12.000000, 34.216000), sinhalaFont, \"ශ\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, useProvidedFontForSpacesBetweenEmojis) {\n    TextLayoutTestContainer testContainer;\n\n    auto appleColorEmojiFont = testContainer.getAppleEmojiFont();\n\n    auto maxSize = Size::make(2000, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"🦊 🦊 🦊 3 foxes \", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0.000, 0.0, 134.000, 26.906),\n                std::nullopt,\n                {TextLayoutEntrySegment(Rect::makeXYWH(0.000, 0.00, 21.000000, 26.906), appleColorEmojiFont, \"🦊\"),\n                 TextLayoutEntrySegment(\n                     Rect::makeXYWH(21.000000, 0.00, 4.000000, 23.222), testContainer.avenirNext, \" \"),\n                 TextLayoutEntrySegment(Rect::makeXYWH(25.000, 0.00, 21.000000, 26.906), appleColorEmojiFont, \"🦊\"),\n                 TextLayoutEntrySegment(\n                     Rect::makeXYWH(46.000000, 0.00, 4.000000, 23.222), testContainer.avenirNext, \" \"),\n                 TextLayoutEntrySegment(Rect::makeXYWH(50.000, 0.00, 21.000000, 26.906), appleColorEmojiFont, \"🦊\"),\n                 TextLayoutEntrySegment(\n                     Rect::makeXYWH(71.000000, 0.00, 63.000000, 23.222), testContainer.avenirNext, \" 3 foxes \")})}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsZeroWidthNonJoiner) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(2000, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"می‌خواهم\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(maxSize,\n                           {TextLayoutEntry(Rect::makeXYWH(0.000, 0.0, 56.000, 31.264),\n                                            std::nullopt,\n                                            {\n                                                TextLayoutEntrySegment(Rect::makeXYWH(0.000, 0.00, 56.000000, 31.264),\n                                                                       testContainer.arabicFont,\n                                                                       \"می‌خواهم\"),\n                                            })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsLineBreakingInRightToLeft) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(80, 10000);\n    TextLayoutBuilder builder(TextAlignRight, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"مرحبا كيف حالك\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(15.000, 0.0, 65.000, 62.527000),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(15.000, 0.00, 65.000, 31.264000), testContainer.arabicFont, \"مرحبا كيف\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(52.000000, 31.264000, 28.000000, 31.264000), testContainer.arabicFont, \"حالك\"),\n                })}),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsBidirectionalTextWithLeftToRightBaseDirection) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(200, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"bahrain مصر kuwait\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(\n                      Rect::makeXYWH(0.0, 0.0, 147.000, 23.222000),\n                      std::nullopt,\n                      {\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(0.0, 0.00, 63.000, 23.222000), testContainer.avenirNext, \"bahrain \"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(63.000, 0.0, 30.000000, 20.842000), testContainer.arabicFont, \"مصر\"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(93.000, 0.00, 54.000, 23.222000), testContainer.avenirNext, \" kuwait\"),\n                      })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsBidirectionalTextWithRightToLeftBaseDirection) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(200, 10000);\n    TextLayoutBuilder builder(TextAlignRight, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, true);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"bahrain مصر kuwait\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(\n                      Rect::makeXYWH(53.000, 0.0, 147.000, 23.222000),\n                      std::nullopt,\n                      {\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(53.000, 0.00, 63.000, 23.222000), testContainer.avenirNext, \"bahrain \"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(116.000, 0.0, 30.000000, 20.842000), testContainer.arabicFont, \"مصر\"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(146.000, 0.00, 54.000, 23.222000), testContainer.avenirNext, \" kuwait\"),\n                      })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsBidirectionalLineBreakingWithLeftToRightBaseDirection) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"قرأ Wikipedia™ طوال اليوم.\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(\n                      Rect::makeXYWH(0.0, 0.0, 102.000, 46.444000),\n                      std::nullopt,\n                      {\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(0.000, 0.0, 4.000000, 23.222000), testContainer.avenirNext, \".\"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(4.0, 0.0, 63.000, 20.842000), testContainer.arabicFont, \"طوال اليوم\"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(67.000, 0.00, 21.000000, 23.222000), testContainer.avenirNext, \"™ \"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(0.0, 23.222, 23.000, 20.842000), testContainer.arabicFont, \"قرأ \"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(23.000, 23.222, 79.000, 23.222000), testContainer.avenirNext, \"Wikipedia\"),\n                      })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsBidirectionalLineBreakingWithRightToLeftBaseDirection) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignRight, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, true);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"قرأ Wikipedia™ طوال اليوم.\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(\n                      Rect::makeXYWH(18.0, 0.0, 102.000, 46.444000),\n                      std::nullopt,\n                      {\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(32.000, 0.0, 4.000000, 23.222000), testContainer.avenirNext, \".\"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(36.0, 0.0, 63.000, 20.842000), testContainer.arabicFont, \"طوال اليوم\"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(99.000, 0.00, 21.000000, 23.222000), testContainer.avenirNext, \"™ \"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(18.0, 23.222, 23.000, 20.842000), testContainer.arabicFont, \"قرأ \"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(41.000, 23.222, 79.000, 23.222000), testContainer.avenirNext, \"Wikipedia\"),\n                      })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, emitsSeparateEntriesForEachColor) {\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(500, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n\n    builder.append(\"Hello \", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n    builder.append(\"world\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone, nullptr, {Color::red()});\n    builder.append(\" and \", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n    builder.append(\"welcome\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone, nullptr, {Color::blue()});\n    builder.append(\"!\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {\n                TextLayoutEntry(\n                    Rect::makeXYWH(0.0, 0.0, 203.000000, 23.222000),\n                    std::nullopt,\n                    {\n                        TextLayoutEntrySegment(\n                            Rect::makeXYWH(0.000000, 0, 44.000000, 23.222000), testContainer.avenirNext, \"Hello \"),\n                        TextLayoutEntrySegment(\n                            Rect::makeXYWH(88.000000, 0.0, 38.000000, 23.222000), testContainer.avenirNext, \" and \"),\n                        TextLayoutEntrySegment(\n                            Rect::makeXYWH(197.000000, 0, 6.000000, 23.222000), testContainer.avenirNext, \"!\"),\n                    }),\n                TextLayoutEntry(Rect::makeXYWH(44.000000, 0.0, 44.000000, 23.222000),\n                                Color::red(),\n                                {\n                                    TextLayoutEntrySegment(Rect::makeXYWH(44.000000, 0, 44.000000, 23.222000),\n                                                           testContainer.avenirNext,\n                                                           \"world\"),\n                                }),\n                TextLayoutEntry(Rect::makeXYWH(126.000000, 0.0, 71.000000, 23.222000),\n                                Color::blue(),\n                                {\n                                    TextLayoutEntrySegment(Rect::makeXYWH(126.000000, 0, 71.000000, 23.222000),\n                                                           testContainer.avenirNext,\n                                                           \"welcome\"),\n                                }),\n            }),\n        layout->toJSONValue());\n}\n\nTEST(TextLayout, dontPrioritizeFewerFonts) {\n    TextLayoutTestContainer testContainer;\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignCenter,\n                              TextOverflowEllipsis,\n                              maxSize,\n                              0,\n                              testContainer.fontManager,\n                              false /*isRightToLeft*/,\n                              false /*prioritizeLowerFontCount*/);\n    builder.setIncludeSegments(true);\n    builder.append(\" مصر\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(Rect::makeXYWH(42.500000, 0.0, 35.000000, 31.264),\n                                   std::nullopt,\n                                   {\n                                       TextLayoutEntrySegment(Rect::makeXYWH(42.500000, 0.00, 35.000000, 31.264),\n                                                              testContainer.arabicFont,\n                                                              \" مصر\"),\n                                   })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, prioritizeFewerFontsTwoSegmentsMerging) {\n    TextLayoutTestContainer testContainer;\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignCenter,\n                              TextOverflowEllipsis,\n                              maxSize,\n                              0,\n                              testContainer.fontManager,\n                              true /*isRightToLeft*/,\n                              true /*prioritizeLowerFontCount*/);\n    builder.setIncludeSegments(true);\n    builder.append(\" مصر\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(Rect::makeXYWH(42.500000, 0.0, 35.000000, 31.264),\n                                   std::nullopt,\n                                   {\n                                       TextLayoutEntrySegment(Rect::makeXYWH(42.500000, 0.00, 35.000000, 31.264),\n                                                              testContainer.arabicFont,\n                                                              \" مصر\"),\n                                   })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, prioritizeFewerFontsFiveSegmentsDifferentParagraphs) {\n    TextLayoutTestContainer testContainer;\n    auto maxSize = Size::make(120, 10000);\n    TextLayoutBuilder builder(TextAlignCenter,\n                              TextOverflowEllipsis,\n                              maxSize,\n                              0,\n                              testContainer.fontManager,\n                              false /*isRightToLeft*/,\n                              true /*prioritizeLowerFontCount*/);\n    builder.setIncludeSegments(true);\n    builder.append(\" مصر \\n سيريا\", testContainer.avenirNext, 1.5, 0.0, TextDecorationNone);\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(\n                      Rect::makeXYWH(40.000000, 0.0, 40.00000, 62.527),\n                      std::nullopt,\n                      {\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(40.000000, 0.00, 40.000000, 31.264), testContainer.arabicFont, \" مصر \"),\n                          TextLayoutEntrySegment(\n                              Rect::makeXYWH(40.000000, 31.264, 40.000000, 31.264), testContainer.arabicFont, \" سيريا\"),\n                      })}),\n              layout->toJSONValue());\n}\n\nTEST(TextLayout, supportsBidiMarker) {\n    TextLayoutTestContainer testContainer;\n    auto maxSize = Size::make(10000, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n    builder.append(\"the title is \\\"\\u2067مقدمة إلى \\u2066C++\\u2069\\u2069\\\" in Arabic.\",\n                   testContainer.avenirNext,\n                   1.0,\n                   0.0,\n                   TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(\n        makeTextLayoutJSON(\n            maxSize,\n            {TextLayoutEntry(\n                Rect::makeXYWH(0.000000, 0.0, 264.00000, 23.222),\n                std::nullopt,\n                {\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(0.000000, 0.00, 84.0, 23.222000), testContainer.avenirNext, \"the title is \\\"\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(84.000000, 0.00, 34.000000, 23.222), testContainer.avenirNext, \"C++\"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(118.000000, 0.00, 62.000000, 20.842), testContainer.arabicFont, \"مقدمة إلى \"),\n                    TextLayoutEntrySegment(\n                        Rect::makeXYWH(180.000000, 0.00, 84.000000, 23.222), testContainer.avenirNext, \"\\\" in Arabic.\"),\n                })}),\n        layout->toJSONValue());\n}\n\nstruct Attachment : public SimpleRefCountable {};\n\nTEST(TextLayut, supportsAttachments) {\n    auto attachment1 = Valdi::makeShared<Attachment>();\n    auto attachment2 = Valdi::makeShared<Attachment>();\n\n    TextLayoutTestContainer testContainer;\n\n    auto maxSize = Size::make(300, 10000);\n    TextLayoutBuilder builder(TextAlignLeft, TextOverflowEllipsis, maxSize, 0, testContainer.fontManager, false);\n    builder.setIncludeSegments(true);\n    builder.append(\"the URL is \", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n    builder.append(\"https://www.snapchat.com\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone, attachment1);\n    builder.append(\" and you can also search on \", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n    builder.append(\"https://google.com\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone, attachment2);\n\n    builder.append(\" if you so wish.\", testContainer.avenirNext, 1.0, 0.0, TextDecorationNone);\n\n    auto layout = builder.build();\n\n    ASSERT_TRUE(layout->fitsInMaxSize());\n\n    ASSERT_EQ(makeTextLayoutJSON(\n                  maxSize,\n                  {TextLayoutEntry(Rect::makeXYWH(0.000000, 0.0, 287.00000, 69.666),\n                                   std::nullopt,\n                                   {\n                                       TextLayoutEntrySegment(Rect::makeXYWH(0.000000, 0.00, 80.0, 23.222000),\n                                                              testContainer.avenirNext,\n                                                              \"the URL is \"),\n                                       TextLayoutEntrySegment(Rect::makeXYWH(80.000000, 0.00, 207.000000, 23.222),\n                                                              testContainer.avenirNext,\n                                                              \"https://www.snapchat.com\"),\n                                       TextLayoutEntrySegment(Rect::makeXYWH(0.000000, 23.222, 213.000000, 23.222),\n                                                              testContainer.avenirNext,\n                                                              \"and you can also search on \"),\n                                       TextLayoutEntrySegment(Rect::makeXYWH(0.00000, 46.444, 150.000000, 23.222),\n                                                              testContainer.avenirNext,\n                                                              \"https://google.com\"),\n                                       TextLayoutEntrySegment(Rect::makeXYWH(150.00000, 46.444, 110.000000, 23.222),\n                                                              testContainer.avenirNext,\n                                                              \" if you so wish.\"),\n                                   })}),\n              layout->toJSONValue());\n\n    ASSERT_EQ(static_cast<size_t>(2), layout->getAttachments().size());\n\n    ASSERT_EQ(toJSONValue(Rect::makeXYWH(80.000000, 0.00, 207.000000, 23.222)),\n              toJSONValue(layout->getAttachments()[0].bounds));\n    ASSERT_EQ(attachment1, layout->getAttachments()[0].attachment);\n\n    ASSERT_EQ(toJSONValue(Rect::makeXYWH(0.00000, 46.444, 150.000000, 23.222)),\n              toJSONValue(layout->getAttachments()[1].bounds));\n    ASSERT_EQ(attachment2, layout->getAttachments()[1].attachment);\n}\n\nTEST(TextLayut, canQueryAttachmentByPoint) {\n    auto attachment1 = Valdi::makeShared<Attachment>();\n    auto attachment2 = Valdi::makeShared<Attachment>();\n\n    auto bounds1 = Rect::makeXYWH(80.000000, 0.00, 207.000000, 23.222);\n    auto bounds2 = Rect::makeXYWH(0.00000, 46.444, 150.000000, 23.222);\n\n    std::vector<TextLayoutAttachment> attachments;\n    attachments.emplace_back(bounds1, attachment1);\n    attachments.emplace_back(bounds2, attachment2);\n\n    auto maxSize = Size::make(300, 10000);\n    TextLayout textLayout(maxSize, {}, {}, std::move(attachments), true);\n\n    auto attachment = textLayout.getAttachmentAtPoint(Point::make(0.0f, 0.0f), 0.0f);\n    ASSERT_EQ(nullptr, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(79.0f, 0.0f), 0.0f);\n    ASSERT_EQ(nullptr, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(80.0f, 0.0f), 0.0f);\n    ASSERT_EQ(attachment1, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(183.0f, 0.0f), 0.0f);\n    ASSERT_EQ(attachment1, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(287.0f, 0.0f), 0.0f);\n    ASSERT_EQ(attachment1, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(288.0f, 0.0f), 0.0f);\n    ASSERT_EQ(nullptr, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(200.0f, 10.0f), 0.0f);\n    ASSERT_EQ(attachment1, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(0.0f, 45.0f), 0.0f);\n    ASSERT_EQ(nullptr, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(0.0f, 47.0f), 0.0f);\n    ASSERT_EQ(attachment2, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(75.0f, 55.0f), 0.0f);\n    ASSERT_EQ(attachment2, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(150.0f, 69.0f), 0.0f);\n    ASSERT_EQ(attachment2, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(151.0f, 69.0f), 0.0f);\n    ASSERT_EQ(nullptr, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(150.0f, 70.0f), 0.0f);\n    ASSERT_EQ(nullptr, attachment);\n}\n\nTEST(TextLayut, canQueryAttachmentByPointWithTolerance) {\n    auto attachment1 = Valdi::makeShared<Attachment>();\n    auto attachment2 = Valdi::makeShared<Attachment>();\n\n    auto bounds1 = Rect::makeXYWH(80.000000, 0.00, 207.000000, 23.222);\n    auto bounds2 = Rect::makeXYWH(0.00000, 46.444, 150.000000, 23.222);\n\n    std::vector<TextLayoutAttachment> attachments;\n    attachments.emplace_back(bounds1, attachment1);\n    attachments.emplace_back(bounds2, attachment2);\n\n    auto maxSize = Size::make(300, 10000);\n    TextLayout textLayout(maxSize, {}, {}, std::move(attachments), true);\n\n    auto attachment = textLayout.getAttachmentAtPoint(Point::make(79.0f, 0.0f), 0.0f);\n    ASSERT_EQ(nullptr, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(79.0f, 0.0f), 2.0f);\n    ASSERT_EQ(attachment1, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(0.0f, 45.0f), 0.0f);\n    ASSERT_EQ(nullptr, attachment);\n\n    attachment = textLayout.getAttachmentAtPoint(Point::make(0.0f, 45.0f), 2.0f);\n    ASSERT_EQ(attachment2, attachment);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/TextShaperCache_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"snap_drawing/cpp/Text/TextShaperCache.hpp\"\n#include \"snap_drawing/cpp/Utils/UTFUtils.hpp\"\n\nnamespace snap::drawing {\n\nstatic std::vector<ShapedGlyph> toGlyphVec(const ShapedGlyph* glyphs, size_t length) {\n    std::vector<ShapedGlyph> out;\n    out.reserve(length);\n\n    for (size_t i = 0; i < length; i++) {\n        out.emplace_back() = glyphs[i];\n    }\n\n    return out;\n}\n\nstatic std::vector<ShapedGlyph> generateGlyphVec(const Character* characters, size_t length) {\n    std::vector<ShapedGlyph> out;\n    out.resize(length);\n\n    auto* data = out.data();\n    for (size_t i = 0; i < length; i++) {\n        auto& glyph = data[i];\n        glyph.offsetX = static_cast<Scalar>(i);\n        glyph.offsetY = -static_cast<Scalar>(i);\n        glyph.advanceX = static_cast<Scalar>(i) * 2.0f;\n        glyph.glyphID = static_cast<uint32_t>(i);\n\n        glyph.setCharacter(characters[i], false);\n    }\n\n    return out;\n}\n\nstatic TextShaperCacheKey makeCacheKey(FontId fontId, const std::vector<Character>& characters) {\n    return TextShaperCacheKey(fontId, 0.0f, TextScript::invalid(), false, characters.data(), characters.size());\n}\n\nTEST(TextShaperCache, canInsertAndGet) {\n    TextShaperCache cache(8);\n\n    auto characters = utf8ToUnicode(\"Hello World what is going on!\");\n\n    auto result = cache.find(makeCacheKey(1, characters));\n\n    ASSERT_FALSE(result);\n\n    auto shapedGlyphs = generateGlyphVec(characters.data(), characters.size());\n\n    cache.insert(makeCacheKey(1, characters), shapedGlyphs.data(), shapedGlyphs.size());\n\n    result = cache.find(makeCacheKey(1, characters));\n\n    ASSERT_TRUE(result);\n\n    ASSERT_EQ(shapedGlyphs, toGlyphVec(result.value().glyphs, result.value().length));\n}\n\nTEST(TextShaperCache, useFontIdAsKey) {\n    TextShaperCache cache(8);\n\n    auto characters = utf8ToUnicode(\"Hello World what is going on!\");\n    auto shapedGlyphs = generateGlyphVec(characters.data(), characters.size());\n\n    cache.insert(makeCacheKey(1, characters), shapedGlyphs.data(), shapedGlyphs.size());\n    cache.insert(makeCacheKey(2, characters), shapedGlyphs.data(), shapedGlyphs.size());\n    cache.insert(makeCacheKey(3, characters), shapedGlyphs.data(), shapedGlyphs.size());\n\n    auto result = cache.find(makeCacheKey(1, characters));\n\n    ASSERT_TRUE(result);\n\n    result = cache.find(makeCacheKey(2, characters));\n\n    ASSERT_TRUE(result);\n\n    result = cache.find(makeCacheKey(3, characters));\n\n    ASSERT_TRUE(result);\n\n    result = cache.find(makeCacheKey(4, characters));\n\n    ASSERT_FALSE(result);\n\n    result = cache.find(makeCacheKey(0, characters));\n\n    ASSERT_FALSE(result);\n}\n\nTEST(TextShaperCache, useCharactersAsKey) {\n    TextShaperCache cache(8);\n\n    auto characters = utf8ToUnicode(\"Hello World what is going on!\");\n    auto characters2 = utf8ToUnicode(\"Hello World what is going on.\");\n    auto characters3 = utf8ToUnicode(\"I'm way different.\");\n    auto characters4 = utf8ToUnicode(\"I dont exist\");\n\n    auto shapedGlyphs = generateGlyphVec(characters.data(), characters.size());\n    auto shapedGlyphs2 = generateGlyphVec(characters2.data(), characters2.size());\n    auto shapedGlyphs3 = generateGlyphVec(characters3.data(), characters3.size());\n\n    cache.insert(makeCacheKey(1, characters), shapedGlyphs.data(), shapedGlyphs.size());\n    cache.insert(makeCacheKey(1, characters2), shapedGlyphs2.data(), shapedGlyphs2.size());\n    cache.insert(makeCacheKey(1, characters3), shapedGlyphs3.data(), shapedGlyphs3.size());\n\n    auto result = cache.find(makeCacheKey(1, characters));\n\n    ASSERT_TRUE(result);\n\n    ASSERT_EQ(shapedGlyphs, toGlyphVec(result.value().glyphs, result.value().length));\n    ASSERT_NE(shapedGlyphs2, toGlyphVec(result.value().glyphs, result.value().length));\n    ASSERT_NE(shapedGlyphs3, toGlyphVec(result.value().glyphs, result.value().length));\n\n    result = cache.find(makeCacheKey(1, characters2));\n\n    ASSERT_TRUE(result);\n\n    ASSERT_NE(shapedGlyphs, toGlyphVec(result.value().glyphs, result.value().length));\n    ASSERT_EQ(shapedGlyphs2, toGlyphVec(result.value().glyphs, result.value().length));\n    ASSERT_NE(shapedGlyphs3, toGlyphVec(result.value().glyphs, result.value().length));\n\n    result = cache.find(makeCacheKey(1, characters3));\n\n    ASSERT_TRUE(result);\n\n    ASSERT_NE(shapedGlyphs, toGlyphVec(result.value().glyphs, result.value().length));\n    ASSERT_NE(shapedGlyphs2, toGlyphVec(result.value().glyphs, result.value().length));\n    ASSERT_EQ(shapedGlyphs3, toGlyphVec(result.value().glyphs, result.value().length));\n\n    result = cache.find(makeCacheKey(1, characters4));\n\n    ASSERT_FALSE(result);\n}\n\nTEST(TextShaperCache, canClear) {\n    TextShaperCache cache(8);\n\n    auto characters = utf8ToUnicode(\"Hello World what is going on!\");\n    auto characters2 = utf8ToUnicode(\"Hello World what is going on.\");\n\n    auto shapedGlyphs = generateGlyphVec(characters.data(), characters.size());\n    auto shapedGlyphs2 = generateGlyphVec(characters2.data(), characters2.size());\n\n    cache.insert(makeCacheKey(1, characters), shapedGlyphs.data(), shapedGlyphs.size());\n    cache.insert(makeCacheKey(1, characters2), shapedGlyphs2.data(), shapedGlyphs2.size());\n\n    cache.clear();\n\n    auto result = cache.find(makeCacheKey(1, characters));\n\n    ASSERT_FALSE(result);\n\n    result = cache.find(makeCacheKey(1, characters2));\n\n    ASSERT_FALSE(result);\n}\n\nTEST(TextShaperCache, removesLeastRecentlyUsedWhenFull) {\n    TextShaperCache cache(3);\n\n    auto characters = utf8ToUnicode(\"Hello World what is going on!\");\n    auto characters2 = utf8ToUnicode(\"Hello World what is going on.\");\n    auto characters3 = utf8ToUnicode(\"I'm way different.\");\n    auto characters4 = utf8ToUnicode(\"I dont exist\");\n\n    auto shapedGlyphs = generateGlyphVec(characters.data(), characters.size());\n    auto shapedGlyphs2 = generateGlyphVec(characters2.data(), characters2.size());\n    auto shapedGlyphs3 = generateGlyphVec(characters3.data(), characters3.size());\n    auto shapedGlyphs4 = generateGlyphVec(characters4.data(), characters4.size());\n\n    cache.insert(makeCacheKey(1, characters), shapedGlyphs.data(), shapedGlyphs.size());\n    cache.insert(makeCacheKey(1, characters2), shapedGlyphs2.data(), shapedGlyphs2.size());\n    cache.insert(makeCacheKey(1, characters3), shapedGlyphs3.data(), shapedGlyphs3.size());\n    cache.insert(makeCacheKey(1, characters4), shapedGlyphs4.data(), shapedGlyphs4.size());\n\n    ASSERT_FALSE(cache.contains(makeCacheKey(1, characters)));\n    ASSERT_TRUE(cache.contains(makeCacheKey(1, characters2)));\n    ASSERT_TRUE(cache.contains(makeCacheKey(1, characters3)));\n    ASSERT_TRUE(cache.contains(makeCacheKey(1, characters4)));\n\n    // Use characters2 so that it becomes the most recently used, this way the oldest\n    // item becomes characters3\n    ASSERT_TRUE(cache.find(makeCacheKey(1, characters2)));\n\n    // Insert the first one so that the cache needs to remove an item\n    cache.insert(makeCacheKey(1, characters), shapedGlyphs.data(), shapedGlyphs.size());\n\n    ASSERT_TRUE(cache.contains(makeCacheKey(1, characters)));\n    ASSERT_TRUE(cache.contains(makeCacheKey(1, characters2)));\n    ASSERT_FALSE(cache.contains(makeCacheKey(1, characters3)));\n    ASSERT_TRUE(cache.contains(makeCacheKey(1, characters4)));\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/TouchDispatcher_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(Layer, canResolveCoordinates) {\n    auto rootView = createView(25, 25, 100, 100);\n    auto middleView = createView(5, 5, 50, 50);\n    auto leafView = createView(7, 9, 10, 10);\n\n    rootView->addChild(middleView);\n    middleView->addChild(leafView);\n\n    ASSERT_EQ(Rect::makeXYWH(25, 25, 100, 100), rootView->getVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(5, 5, 50, 50), middleView->getVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(7, 9, 10, 10), leafView->getVisualFrame());\n\n    ASSERT_EQ(Rect::makeXYWH(25, 25, 100, 100), rootView->getAbsoluteVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(30, 30, 50, 50), middleView->getAbsoluteVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(37, 39, 10, 10), leafView->getAbsoluteVisualFrame());\n\n    // 7, 9\n    // 12, 14\n    //\n\n    auto result = rootView->convertPointToLayer(Point::make(2, 15), rootView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(2, 15), result.value());\n\n    result = rootView->convertPointToLayer(Point::make(2, 15), middleView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(-3, 10), result.value());\n\n    result = rootView->convertPointToLayer(Point::make(2, 15), leafView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(-10, 1), result.value());\n\n    result = middleView->convertPointToLayer(Point::make(-3, 10), leafView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(-10, 1), result.value());\n}\n\nTEST(Layer, canResolveCoordinatesWithTranslate) {\n    auto rootView = createView(25, 25, 100, 100);\n    auto middleView = createView(5, 5, 50, 50);\n    auto leafView = createView(7, 9, 10, 10);\n\n    rootView->addChild(middleView);\n    middleView->addChild(leafView);\n\n    middleView->setTranslationX(4);\n    middleView->setTranslationY(-3);\n\n    ASSERT_EQ(Rect::makeXYWH(25, 25, 100, 100), rootView->getVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(9, 2, 50, 50), middleView->getVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(7, 9, 10, 10), leafView->getVisualFrame());\n\n    ASSERT_EQ(Rect::makeXYWH(25, 25, 100, 100), rootView->getAbsoluteVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(34, 27, 50, 50), middleView->getAbsoluteVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(41, 36, 10, 10), leafView->getAbsoluteVisualFrame());\n\n    auto result = rootView->convertPointToLayer(Point::make(2, 15), rootView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(2, 15), result.value());\n\n    result = rootView->convertPointToLayer(Point::make(2, 15), middleView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(-7, 13), result.value());\n\n    result = rootView->convertPointToLayer(Point::make(2, 15), leafView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(-14, 4), result.value());\n\n    result = middleView->convertPointToLayer(Point::make(-7, 13), leafView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(-14, 4), result.value());\n}\n\nTEST(Layer, canResolveCoordinatesWithScale) {\n    auto rootView = createView(25, 25, 100, 100);\n    auto middleView = createView(5, 5, 50, 50);\n    auto leafView = createView(7, 9, 10, 10);\n\n    rootView->addChild(middleView);\n    middleView->addChild(leafView);\n\n    middleView->setScaleX(2);\n    middleView->setScaleY(4);\n\n    ASSERT_EQ(Rect::makeXYWH(25, 25, 100, 100), rootView->getVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(-20, -70, 100, 200), middleView->getVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(7, 9, 10, 10), leafView->getVisualFrame());\n\n    ASSERT_EQ(Rect::makeXYWH(25, 25, 100, 100), rootView->getAbsoluteVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(5, -45, 100, 200), middleView->getAbsoluteVisualFrame());\n    ASSERT_EQ(Rect::makeXYWH(19, -9, 20, 40), leafView->getAbsoluteVisualFrame());\n\n    auto result = rootView->convertPointToLayer(Point::make(2, 15), rootView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(2, 15), result.value());\n\n    result = rootView->convertPointToLayer(Point::make(2, 15), middleView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(11, 21.25), result.value());\n\n    result = rootView->convertPointToLayer(Point::make(2, 15), leafView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(4, 12.25), result.value());\n\n    result = middleView->convertPointToLayer(Point::make(11, 21.25), leafView);\n    ASSERT_TRUE(result.has_value());\n    ASSERT_EQ(Point::make(4, 12.25), result.value());\n}\n\n//\n// TEST(Layer, canResolveCoordinatesWithScaleTranslate) {\n//\n//}\n\nTEST(TouchDispatcher, transitionFromStates) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n\n    container->view->addChild(childView);\n\n    auto snapshot = addCustomTouchGesture(childView);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, snapshot->state);\n    ASSERT_EQ(Point::makeEmpty(), snapshot->location);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStateBegan, snapshot->state);\n    ASSERT_EQ(5, snapshot->location.x);\n    ASSERT_EQ(10, snapshot->location.y);\n\n    container->dispatchEvent(TouchEventTypeMoved, 40, 40);\n\n    ASSERT_EQ(GestureRecognizerStateChanged, snapshot->state);\n    ASSERT_EQ(15, snapshot->location.x);\n    ASSERT_EQ(15, snapshot->location.y);\n\n    container->dispatchEvent(TouchEventTypeMoved, 1000, 1000);\n\n    ASSERT_EQ(GestureRecognizerStateChanged, snapshot->state);\n    ASSERT_EQ(975, snapshot->location.x);\n    ASSERT_EQ(975, snapshot->location.y);\n\n    container->dispatchEvent(TouchEventTypeUp, 5, 5);\n\n    ASSERT_EQ(GestureRecognizerStateEnded, snapshot->state);\n    ASSERT_EQ(-20, snapshot->location.x);\n    ASSERT_EQ(-20, snapshot->location.y);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, canHandleSimpleGesture) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n\n    container->view->addChild(childView);\n\n    auto snapshot = addCustomTapGesture(childView, 1);\n\n    // Touch outside\n    container->dispatchEvent(TouchEventTypeDown, 20, 20);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, snapshot->state);\n    ASSERT_EQ(Point::makeEmpty(), snapshot->location);\n\n    // Touch inside\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n\n    // This is a tap, so it should still be null at this point\n    ASSERT_EQ(GestureRecognizerStatePossible, snapshot->state);\n    ASSERT_EQ(Point::makeEmpty(), snapshot->location);\n\n    // Lift finger\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n\n    ASSERT_EQ(GestureRecognizerStateEnded, snapshot->state);\n    ASSERT_EQ(5, snapshot->location.x);\n    ASSERT_EQ(10, snapshot->location.y);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, canCalculateRelativeCoordinates) {\n    auto root = makeRoot();\n\n    auto rootView = createView(10, 10, 100, 100);\n    auto childView = createView(15, 15, 50, 50);\n    auto childView2 = createView(17, 17, 25, 25);\n\n    rootView->addChild(childView);\n    childView->addChild(childView2);\n\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto snapshot = addCustomTouchGesture(childView2);\n\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeDown, 49, 48));\n\n    ASSERT_EQ(GestureRecognizerStateBegan, snapshot->state);\n    ASSERT_EQ(17, snapshot->location.x);\n    ASSERT_EQ(16, snapshot->location.y);\n\n    ASSERT_FALSE(root->getTouchDispatcher().isEmpty());\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeUp, 0, 0));\n\n    ASSERT_TRUE(root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, onlyRecognizeOnHit) {\n    auto container = makeContainer(10, 10, 100, 100);\n\n    auto childView = createView(15, 15, 50, 50);\n    auto childView2 = createView(17, 17, 25, 25);\n\n    container->view->addChild(childView);\n    childView->addChild(childView2);\n\n    auto snapshot = addCustomTouchGesture(childView2);\n\n    container->dispatchEvent(TouchEventTypeDown, 67, 48);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, snapshot->state);\n    ASSERT_EQ(Point::makeEmpty(), snapshot->location);\n\n    container->dispatchEvent(TouchEventTypeUp, 67, 48);\n\n    container->dispatchEvent(TouchEventTypeDown, 49, 67);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, snapshot->state);\n    ASSERT_EQ(Point::makeEmpty(), snapshot->location);\n\n    container->dispatchEvent(TouchEventTypeUp, 49, 67);\n    container->dispatchEvent(TouchEventTypeDown, 67, 67);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, snapshot->state);\n    ASSERT_EQ(Point::makeEmpty(), snapshot->location);\n\n    container->dispatchEvent(TouchEventTypeUp, 67, 48);\n\n    // This time we should hit\n    container->dispatchEvent(TouchEventTypeDown, 50, 50);\n\n    ASSERT_NE(GestureRecognizerStatePossible, snapshot->state);\n    ASSERT_NE(Point::makeEmpty(), snapshot->location);\n\n    ASSERT_FALSE(container->root->getTouchDispatcher().isEmpty());\n\n    container->dispatchEvent(TouchEventTypeUp, 0, 0);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, siblingsCanPreventHitTest) {\n    auto root = makeRoot();\n    auto rootView = createView(0, 0, 100, 100);\n    auto childView = createView(15, 15, 50, 50);\n    auto childView2 = createView(15, 15, 50, 50);\n\n    rootView->addChild(childView);\n    rootView->addChild(childView2);\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto snapshot = addCustomTouchGesture(childView);\n\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeDown, 20, 20));\n\n    ASSERT_EQ(GestureRecognizerStatePossible, snapshot->state);\n\n    ASSERT_TRUE(root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, siblingsDontPreventHitTestWithTouchDisabled) {\n    auto root = makeRoot();\n    auto rootView = createView(0, 0, 100, 100);\n    auto childView = createView(15, 15, 50, 50);\n    auto childView2 = createView(15, 15, 50, 50);\n\n    rootView->addChild(childView);\n    rootView->addChild(childView2);\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto snapshot = addCustomTouchGesture(childView);\n    childView2->setTouchEnabled(false);\n\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeDown, 20, 20));\n\n    ASSERT_EQ(GestureRecognizerStateBegan, snapshot->state);\n\n    ASSERT_FALSE(root->getTouchDispatcher().isEmpty());\n\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeUp, 0, 0));\n\n    ASSERT_TRUE(root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, onlyConsiderTopSiblings) {\n    auto root = makeRoot();\n    auto rootView = createView(0, 0, 100, 100);\n    auto childView = createView(15, 15, 50, 50);\n    auto childView2 = createView(15, 15, 50, 50);\n\n    rootView->addChild(childView);\n    rootView->addChild(childView2);\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto stateChild = addCustomTouchGesture(childView);\n    auto stateChild2 = addCustomTouchGesture(childView2);\n\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeDown, 20, 20));\n\n    ASSERT_EQ(GestureRecognizerStatePossible, stateChild->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, stateChild2->state);\n\n    ASSERT_FALSE(root->getTouchDispatcher().isEmpty());\n\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeUp, 0, 0));\n\n    ASSERT_TRUE(root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, canHandleSimulatenousGesture) {\n    auto root = makeRoot();\n\n    auto rootView = createView(0, 0, 100, 100);\n    auto childView = createView(25, 25, 25, 25);\n    auto childView2 = createView(5, 5, 25, 25);\n    rootView->addChild(childView);\n    childView->addChild(childView2);\n\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto tap1 = addCustomTapGesture(childView, 1, true);\n    auto tap2 = addCustomTapGesture(childView2, 1, true);\n\n    // Touch inside\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeDown, 30, 35));\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeUp, 30, 35));\n\n    ASSERT_EQ(GestureRecognizerStateEnded, tap1->state);\n    ASSERT_EQ(5, tap1->location.x);\n    ASSERT_EQ(10, tap1->location.y);\n\n    ASSERT_EQ(GestureRecognizerStateEnded, tap2->state);\n    ASSERT_EQ(0, tap2->location.x);\n    ASSERT_EQ(5, tap2->location.y);\n\n    ASSERT_TRUE(root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, canHandleSimulatenousDelayedGesture) {\n    auto root = makeRoot();\n\n    auto rootView = createView(0, 0, 100, 100);\n    auto childView = createView(25, 25, 25, 25);\n    auto childView2 = createView(5, 5, 25, 25);\n\n    rootView->addChild(childView);\n    childView->addChild(childView2);\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto touch = addCustomTouchGesture(childView);\n    auto tap = addCustomTapGesture(childView2, 1);\n\n    // Touch inside\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeDown, 30, 35));\n\n    ASSERT_EQ(GestureRecognizerStateBegan, touch->state);\n    ASSERT_EQ(5, touch->location.x);\n    ASSERT_EQ(10, touch->location.y);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, tap->state);\n    ASSERT_EQ(0, tap->location.x);\n    ASSERT_EQ(0, tap->location.y);\n\n    // We move very slightly\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeMoved, 31, 35));\n\n    ASSERT_EQ(GestureRecognizerStateChanged, touch->state);\n    ASSERT_EQ(6, touch->location.x);\n    ASSERT_EQ(10, touch->location.y);\n\n    // Tap should still be off\n    ASSERT_EQ(GestureRecognizerStatePossible, tap->state);\n    ASSERT_EQ(0, tap->location.x);\n    ASSERT_EQ(0, tap->location.y);\n\n    // We then release\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeUp, 31, 35));\n\n    ASSERT_EQ(GestureRecognizerStateEnded, touch->state);\n    ASSERT_EQ(6, touch->location.x);\n    ASSERT_EQ(10, touch->location.y);\n\n    // The tap gesture should have triggered, because we barely moved\n    ASSERT_EQ(GestureRecognizerStateEnded, tap->state);\n    ASSERT_EQ(1, tap->location.x);\n    ASSERT_EQ(5, tap->location.y);\n\n    ASSERT_TRUE(root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, canHandleConflicts) {\n    auto root = makeRoot();\n\n    auto rootView = createView(0, 0, 100, 100);\n    auto childView = createView(25, 25, 25, 25);\n    auto childView2 = createView(30, 30, 25, 25);\n\n    rootView->addChild(childView);\n    rootView->addChild(childView2);\n\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto tap1 = addCustomTapGesture(childView, 1, false);\n\n    auto tap2 = addCustomTapGesture(childView2, 1, false);\n\n    // Touch inside\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeDown, 30, 35));\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeUp, 30, 35));\n\n    // Only tap2 should be called, since it's the highest child.\n    ASSERT_EQ(GestureRecognizerStateEnded, tap2->state);\n    ASSERT_EQ(0, tap2->location.x);\n    ASSERT_EQ(5, tap2->location.y);\n\n    ASSERT_EQ(GestureRecognizerStatePossible, tap1->state);\n    ASSERT_EQ(0, tap1->location.x);\n    ASSERT_EQ(0, tap1->location.y);\n\n    ASSERT_TRUE(root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, canCancelOtherGesturesOnStart) {\n    auto root = makeRoot();\n\n    auto rootView = createView(0, 0, 100, 100);\n    auto childView = createView(25, 25, 25, 25);\n    auto childView2 = createView(5, 5, 25, 25);\n    rootView->addChild(childView);\n    childView->addChild(childView2);\n\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto drag = addDragGesture(childView, /*shouldCancelOtherGesturesOnStart*/ true);\n    auto touch = addCustomTouchGesture(childView2);\n\n    // Touch inside\n    root->dispatchTouchEvent(createTouchEvent(TouchEventTypeDown, 30, 35));\n\n    ASSERT_EQ(GestureRecognizerStatePossible, drag->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, touch->state);\n\n    root->dispatchTouchEvent(\n        createTouchEvent(TouchEventTypeMoved, 30 + (GesturesConfiguration::getDefault().dragTouchSlop / 2), 35));\n\n    ASSERT_EQ(GestureRecognizerStatePossible, drag->state);\n    ASSERT_EQ(GestureRecognizerStateChanged, touch->state);\n\n    root->dispatchTouchEvent(\n        createTouchEvent(TouchEventTypeMoved, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35));\n\n    ASSERT_EQ(GestureRecognizerStateBegan, drag->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, touch->state);\n\n    root->dispatchTouchEvent(\n        createTouchEvent(TouchEventTypeUp, 30 + GesturesConfiguration::getDefault().dragTouchSlop, 35));\n\n    ASSERT_EQ(GestureRecognizerStateEnded, drag->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, touch->state);\n\n    ASSERT_TRUE(root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchDispatcher, canRefreshTouchGestures) {\n    auto root = makeRoot();\n\n    auto rootView = createView(10, 10, 100, 100);\n    auto childView = createView(15, 15, 50, 50);\n\n    rootView->addChild(childView);\n\n    root->setContentLayer(rootView, ContentLayerSizingModeMatchSize);\n\n    auto snapshot = addCustomTouchGesture(childView);\n\n    auto event = createTouchEvent(TouchEventTypeDown, 17, 16);\n\n    root->dispatchTouchEvent(event);\n\n    ASSERT_EQ(GestureRecognizerStateBegan, snapshot->state);\n    ASSERT_EQ(2, snapshot->location.x);\n    ASSERT_EQ(1, snapshot->location.y);\n    ASSERT_EQ(1, snapshot->counter);\n\n    ASSERT_FALSE(root->getTouchDispatcher().isEmpty());\n\n    // No refreshes when called in under 10ms.\n    ASSERT_FALSE(root->refreshTouches(event.getTime()));\n    ASSERT_FALSE(root->refreshTouches(event.getTime() + Duration::fromMilliseconds(5)));\n\n    // Refresh for >10ms succeeds.\n    ASSERT_TRUE(root->refreshTouches(event.getTime() + Duration::fromMilliseconds(15)));\n\n    // No state change because it didn't move.\n    ASSERT_EQ(GestureRecognizerStateBegan, snapshot->state);\n    ASSERT_EQ(1, snapshot->counter);\n\n    // Ensure state changes after a move.\n    event = createTouchEvent(TouchEventTypeMoved, 18, 17);\n    root->dispatchTouchEvent(event);\n\n    ASSERT_EQ(GestureRecognizerStateChanged, snapshot->state);\n    ASSERT_EQ(3, snapshot->location.x);\n    ASSERT_EQ(2, snapshot->location.y);\n    ASSERT_EQ(2, snapshot->counter);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/TouchGestureRecognizer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(TouchGestureRecognizer, canHandleTouch) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto gestureRecognizer = makeTouchGestureRecognizer(childView);\n\n    auto touchSnapshot = addTouchGesture(gestureRecognizer);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateChanged, touchSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, touchSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchGestureRecognizer, canHandleTouchWithSingleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto gestureRecognizer = makeTouchGestureRecognizer(childView);\n\n    auto touchSnapshot = addTouchGesture(gestureRecognizer);\n    auto singleTapSnapshot = addSingleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateChanged, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, singleTapSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchGestureRecognizer, canHandleTouchWithDoubleTap) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto gestureRecognizer = makeTouchGestureRecognizer(childView);\n\n    auto touchSnapshot = addTouchGesture(gestureRecognizer);\n    auto doubleTapSnapshot = addDoubleTapGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateChanged, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    ASSERT_FALSE(container->root->getTouchDispatcher().isEmpty());\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateChanged, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, doubleTapSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, doubleTapSnapshot->state);\n\n    ASSERT_EQ(6, touchSnapshot->counter);\n    ASSERT_EQ(1, doubleTapSnapshot->counter);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchGestureRecognizer, canHandleTouchWithLongPress) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto gestureRecognizer = makeTouchGestureRecognizer(childView);\n\n    auto touchSnapshot = addTouchGesture(gestureRecognizer);\n    auto longPressSnapshot = addLongPressGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, longPressSnapshot->state);\n\n    container->dispatchEvent(\n        TouchEventTypeMoved, 30, 35, 0, 0, 1, GesturesConfiguration::getDefault().longPressTimeout);\n    ASSERT_EQ(GestureRecognizerStateChanged, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, longPressSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, longPressSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchGestureRecognizer, canHandleTouchStart) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto gestureRecognizer = makeTouchGestureRecognizer(childView);\n\n    auto touchStartSnapshot = addTouchStartGesture(gestureRecognizer);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchStartSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchStartSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchStartSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchGestureRecognizer, canHandleTouchEnd) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto gestureRecognizer = makeTouchGestureRecognizer(childView);\n\n    auto touchEndSnapshot = addTouchEndGesture(gestureRecognizer);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, touchEndSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, touchEndSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, touchEndSnapshot->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchGestureRecognizer, canHandleTouchCombined) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto gestureRecognizer = makeTouchGestureRecognizer(childView);\n\n    auto touchSnapshot = addTouchGesture(gestureRecognizer);\n    auto touchStartSnapshot = addTouchStartGesture(gestureRecognizer);\n    auto touchEndSnapshot = addTouchEndGesture(gestureRecognizer);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchStartSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, touchEndSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeMoved, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateChanged, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchStartSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, touchEndSnapshot->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStateEnded, touchSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateBegan, touchStartSnapshot->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, touchEndSnapshot->state);\n\n    ASSERT_EQ(3, touchSnapshot->counter);\n    ASSERT_EQ(1, touchStartSnapshot->counter);\n    ASSERT_EQ(1, touchEndSnapshot->counter);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\nTEST(TouchGestureRecognizer, canHandleOverlappingTapGestures) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView1 = createView(25, 25, 25, 25);\n    container->view->addChild(childView1);\n    auto singleTapSnapshot1 = addSingleTapGesture(childView1);\n\n    auto childView2 = createView(0, 0, 25, 25);\n    childView1->addChild(childView2);\n    auto singleTapSnapshot2 = addSingleTapGesture(childView2);\n\n    container->dispatchEvent(TouchEventTypeDown, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot1->state);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot2->state);\n\n    container->dispatchEvent(TouchEventTypeUp, 30, 35);\n    ASSERT_EQ(GestureRecognizerStatePossible, singleTapSnapshot1->state);\n    ASSERT_EQ(GestureRecognizerStateEnded, singleTapSnapshot2->state);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/VideoLayer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestBitmap.hpp\"\n#include \"snap_drawing/cpp/Drawing/GraphicsContext/BitmapGraphicsContext.hpp\"\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n#include \"snap_drawing/cpp/Layers/VideoLayer.hpp\"\n#include \"snap_drawing/cpp/Utils/ImageQueue.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nclass VideoLayerTests : public ::testing::Test {\nprotected:\n    void SetUp() override {\n        auto resources = makeShared<Resources>(nullptr, 1.0f, ConsoleLogger::getLogger());\n\n        _layerRoot = makeLayer<LayerRoot>(resources);\n        _videoLayer = makeLayer<VideoLayer>(resources);\n        _layerRoot->setContentLayer(_videoLayer, ContentLayerSizingModeMatchSize);\n        _layerRoot->setSize(Size(1.0f, 1.0f), 1.0f);\n    }\n\n    void TearDown() override {\n        _videoLayer = nullptr;\n        _layerRoot = nullptr;\n    }\n\n    Color updateAndDraw() {\n        _layerRoot->processFrame(TimePoint::fromSeconds(_currentTime));\n\n        BitmapGraphicsContext context;\n\n        auto bitmap = makeShared<TestBitmap>(1, 1);\n        auto surface = context.createBitmapSurface(bitmap);\n        _layerRoot->drawInCanvas(surface->prepareCanvas().value());\n\n        _currentTime += 1.0;\n\n        return bitmap->getPixel(0, 0);\n    }\n\n    void enqueueColorToQueue(const Ref<ImageQueue>& queue, Color color) const {\n        auto coloredBitmap = makeShared<TestBitmap>(1, 1);\n        coloredBitmap->setPixel(0, 0, color);\n\n        queue->enqueue(Image::makeFromBitmap(coloredBitmap, false).value());\n    }\n\n    Ref<LayerRoot> _layerRoot;\n    Ref<VideoLayer> _videoLayer;\n    TimeInterval _currentTime = 0.0;\n};\n\nTEST_F(VideoLayerTests, displaysNothingWhenQueueIsEmpty) {\n    ASSERT_TRUE(_layerRoot->needsProcessFrame());\n    auto color = updateAndDraw();\n    ASSERT_FALSE(_layerRoot->needsProcessFrame());\n    ASSERT_EQ(Color::transparent(), color);\n}\n\nTEST_F(VideoLayerTests, alwaysNeedsProcessFrameWhenQueueIsSet) {\n    auto queue = makeShared<ImageQueue>(1);\n    _videoLayer->setImageQueue(queue);\n\n    ASSERT_TRUE(_layerRoot->needsProcessFrame());\n    auto color = updateAndDraw();\n    ASSERT_TRUE(_layerRoot->needsProcessFrame());\n    ASSERT_EQ(Color::transparent(), color);\n\n    color = updateAndDraw();\n    ASSERT_TRUE(_layerRoot->needsProcessFrame());\n    ASSERT_EQ(Color::transparent(), color);\n}\n\nTEST_F(VideoLayerTests, canDrawFromImageQueue) {\n    auto queue = makeShared<ImageQueue>(1);\n    _videoLayer->setImageQueue(queue);\n\n    auto color = updateAndDraw();\n    ASSERT_EQ(Color::transparent(), color);\n\n    ASSERT_EQ(static_cast<size_t>(0), queue->getQueueSize());\n\n    enqueueColorToQueue(queue, Color::red());\n\n    ASSERT_EQ(static_cast<size_t>(1), queue->getQueueSize());\n\n    color = updateAndDraw();\n    ASSERT_EQ(Color::red(), color);\n\n    ASSERT_EQ(static_cast<size_t>(0), queue->getQueueSize());\n\n    ASSERT_TRUE(_layerRoot->needsProcessFrame());\n\n    color = updateAndDraw();\n    // Should remain the same\n    ASSERT_EQ(Color::red(), color);\n}\n\nTEST_F(VideoLayerTests, dequeuesFromImageQueueRepeatedly) {\n    auto queue = makeShared<ImageQueue>(3);\n    _videoLayer->setImageQueue(queue);\n\n    enqueueColorToQueue(queue, Color::red());\n    enqueueColorToQueue(queue, Color::green());\n    enqueueColorToQueue(queue, Color::blue());\n\n    ASSERT_EQ(static_cast<size_t>(3), queue->getQueueSize());\n\n    auto color = updateAndDraw();\n    ASSERT_EQ(Color::red(), color);\n    ASSERT_EQ(static_cast<size_t>(2), queue->getQueueSize());\n\n    color = updateAndDraw();\n    ASSERT_EQ(Color::green(), color);\n    ASSERT_EQ(static_cast<size_t>(1), queue->getQueueSize());\n\n    color = updateAndDraw();\n    ASSERT_EQ(Color::blue(), color);\n    ASSERT_EQ(static_cast<size_t>(0), queue->getQueueSize());\n\n    color = updateAndDraw();\n    ASSERT_EQ(Color::blue(), color);\n}\n\nTEST_F(VideoLayerTests, stopsProcessingWhenQueueIsRemoved) {\n    auto queue = makeShared<ImageQueue>(1);\n    _videoLayer->setImageQueue(queue);\n\n    ASSERT_TRUE(_layerRoot->needsProcessFrame());\n    updateAndDraw();\n\n    ASSERT_TRUE(_layerRoot->needsProcessFrame());\n    updateAndDraw();\n\n    _videoLayer->setImageQueue(nullptr);\n    updateAndDraw();\n\n    ASSERT_FALSE(_layerRoot->needsProcessFrame());\n\n    _videoLayer->setImageQueue(queue);\n    ASSERT_TRUE(_layerRoot->needsProcessFrame());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/WheelGestureRecognizer_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nTEST(DragGestureRecognizer, doesHandleWheel) {\n    auto container = makeContainer(0, 0, 100, 100);\n\n    auto childView = createView(25, 25, 25, 25);\n    container->view->addChild(childView);\n\n    auto wheelSnapshot = addWheelGesture(childView);\n\n    container->dispatchEvent(TouchEventTypeWheel, 30, 35, 0, 10);\n    ASSERT_EQ(GestureRecognizerStateBegan, wheelSnapshot->state);\n    ASSERT_EQ(5, wheelSnapshot->location.x);\n    ASSERT_EQ(10, wheelSnapshot->location.y);\n    ASSERT_EQ(0, wheelSnapshot->direction.dx);\n    ASSERT_EQ(10, wheelSnapshot->direction.dy);\n\n    container->dispatchEvent(TouchEventTypeWheel, 35, 40, 5, 5);\n    ASSERT_EQ(GestureRecognizerStateBegan, wheelSnapshot->state);\n    ASSERT_EQ(10, wheelSnapshot->location.x);\n    ASSERT_EQ(15, wheelSnapshot->location.y);\n    ASSERT_EQ(5, wheelSnapshot->direction.dx);\n    ASSERT_EQ(5, wheelSnapshot->direction.dy);\n\n    ASSERT_TRUE(container->root->getTouchDispatcher().isEmpty());\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/src/WordCachingTextShaper_tests.cpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"TestDataUtils.hpp\"\n#include \"snap_drawing/cpp/Text/FontManager.hpp\"\n#include \"snap_drawing/cpp/Text/WordCachingTextShaper.hpp\"\n#include \"snap_drawing/cpp/Utils/UTFUtils.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\nnamespace snap::drawing {\n\nstruct TextShaperRequest {\n    std::string characters;\n    Ref<Font> font;\n    bool isRightToLeft;\n    Scalar letterSpacing;\n    TextScript script;\n};\n\nstruct TestTextShaper : public TextShaper {\n    std::vector<TextShaperRequest> shapeRequests;\n\n    TextParagraphList resolveParagraphs(const Character* unicodeText, size_t length, bool isRightToLeft) override {\n        return TextParagraphList();\n    }\n\n    size_t shape(const Character* unicodeText,\n                 size_t length,\n                 Font& font,\n                 bool isRightToLeft,\n                 Scalar letterSpacing,\n                 TextScript script,\n                 std::vector<ShapedGlyph>& out) override {\n        TextShaperRequest request;\n        request.characters = unicodeToUtf8(unicodeText, length);\n        request.font = Valdi::strongSmallRef(&font);\n        request.isRightToLeft = isRightToLeft;\n        request.letterSpacing = letterSpacing;\n        request.script = script;\n\n        shapeRequests.emplace_back(request);\n\n        auto glyphsStart = out.size();\n        out.resize(glyphsStart + length);\n        auto* outGlyphs = out.data() + glyphsStart;\n\n        for (size_t i = 0; i < length; i++) {\n            auto& glyph = outGlyphs[i];\n\n            glyph.setCharacter(unicodeText[i], false);\n            glyph.glyphID = 0;\n            glyph.offsetX = 0;\n            glyph.offsetY = 0;\n            glyph.advanceX = font.resolvedSize();\n        }\n\n        return length;\n    }\n};\n\nclass WordCachingTextShaperTest : public ::testing::Test {\nprotected:\n    void SetUp() override {\n        fontManager = Valdi::makeShared<FontManager>(Valdi::ConsoleLogger::getLogger());\n        fontManager->load();\n\n        avenirNext = registerFont(\"Avenir Next\",\n                                  FontStyle(FontWidthNormal, FontWeightNormal, FontSlantUpright),\n                                  \"AvenirNext-Regular\",\n                                  \"avenir_next_regular\");\n        testTextShaper = Valdi::makeShared<TestTextShaper>();\n    }\n\n    void TearDown() override {\n        avenirNext = nullptr;\n        fontManager = nullptr;\n    }\n\n    Ref<FontManager> fontManager;\n    Ref<Font> avenirNext;\n    Ref<TestTextShaper> testTextShaper;\n\nprivate:\n    Ref<Font> registerFont(std::string_view fontFamilyName,\n                           FontStyle fontStyle,\n                           std::string_view fontName,\n                           const std::string& filename) {\n        auto testData = getTestData(filename + \".ttf\");\n        SC_ASSERT(testData.success(), testData.description());\n\n        fontManager->registerTypeface(\n            Valdi::StringCache::getGlobal().makeString(fontFamilyName), fontStyle, false, testData.value());\n        auto font =\n            fontManager->getFontWithNameAndSize(Valdi::StringCache::getGlobal().makeString(fontName), 17, 1.0, true);\n        SC_ASSERT(font.success(), font.description());\n\n        return font.moveValue();\n    }\n};\n\nTEST_F(WordCachingTextShaperTest, canShapeByWord) {\n    WordCachingTextShaper textShaper(testTextShaper, WordCachingTextShaperStrategy::PrioritizeCorrectness);\n\n    auto unicode = utf8ToUnicode(\"This is a sentence\");\n\n    std::vector<ShapedGlyph> glyphs;\n\n    textShaper.shape(unicode.data(), unicode.size(), *avenirNext, false, 1.0f, TextScript::invalid(), glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(4), testTextShaper->shapeRequests.size());\n\n    ASSERT_EQ(\"This\", testTextShaper->shapeRequests[0].characters);\n    ASSERT_EQ(\"is\", testTextShaper->shapeRequests[1].characters);\n    ASSERT_EQ(\"a\", testTextShaper->shapeRequests[2].characters);\n    ASSERT_EQ(\"sentence\", testTextShaper->shapeRequests[3].characters);\n\n    for (const auto& shapeRequest : testTextShaper->shapeRequests) {\n        ASSERT_EQ(avenirNext, shapeRequest.font);\n        ASSERT_FALSE(shapeRequest.isRightToLeft);\n        ASSERT_EQ(1.0f, shapeRequest.letterSpacing);\n    }\n}\n\nTEST_F(WordCachingTextShaperTest, avoidShapingWhenHittingKnownWords) {\n    WordCachingTextShaper textShaper(testTextShaper, WordCachingTextShaperStrategy::PrioritizeCorrectness);\n\n    auto unicode = utf8ToUnicode(\"word word    word  \");\n\n    std::vector<ShapedGlyph> glyphs;\n\n    textShaper.shape(unicode.data(), unicode.size(), *avenirNext, false, 1.0f, TextScript::invalid(), glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(1), testTextShaper->shapeRequests.size());\n\n    ASSERT_EQ(\"word\", testTextShaper->shapeRequests[0].characters);\n\n    for (const auto& shapeRequest : testTextShaper->shapeRequests) {\n        ASSERT_EQ(avenirNext, shapeRequest.font);\n        ASSERT_FALSE(shapeRequest.isRightToLeft);\n        ASSERT_EQ(1.0f, shapeRequest.letterSpacing);\n    }\n\n    glyphs.clear();\n\n    testTextShaper->shapeRequests.clear();\n    textShaper.shape(unicode.data(), unicode.size(), *avenirNext, false, 1.0f, TextScript::invalid(), glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(0), testTextShaper->shapeRequests.size());\n\n    // If we change the direction, it should not hit the cache\n\n    textShaper.shape(unicode.data(), unicode.size(), *avenirNext, true, 1.0f, TextScript::invalid(), glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(1), testTextShaper->shapeRequests.size());\n    testTextShaper->shapeRequests.clear();\n\n    textShaper.shape(unicode.data(), unicode.size(), *avenirNext, true, 1.0f, TextScript::invalid(), glyphs);\n    ASSERT_EQ(static_cast<size_t>(0), testTextShaper->shapeRequests.size());\n\n    // If we change the letter spacing, it should also not hit the cache\n\n    textShaper.shape(unicode.data(), unicode.size(), *avenirNext, true, 2.0f, TextScript::invalid(), glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(1), testTextShaper->shapeRequests.size());\n    testTextShaper->shapeRequests.clear();\n\n    textShaper.shape(unicode.data(), unicode.size(), *avenirNext, true, 2.0f, TextScript::invalid(), glyphs);\n    ASSERT_EQ(static_cast<size_t>(0), testTextShaper->shapeRequests.size());\n\n    // Using a different font size should also not hit the cache\n    textShaper.shape(unicode.data(),\n                     unicode.size(),\n                     *avenirNext->withSize(12.0f).value(),\n                     true,\n                     2.0f,\n                     TextScript::invalid(),\n                     glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(1), testTextShaper->shapeRequests.size());\n    testTextShaper->shapeRequests.clear();\n\n    textShaper.shape(unicode.data(),\n                     unicode.size(),\n                     *avenirNext->withSize(12.0f).value(),\n                     true,\n                     2.0f,\n                     TextScript::invalid(),\n                     glyphs);\n    ASSERT_EQ(static_cast<size_t>(0), testTextShaper->shapeRequests.size());\n\n    // Using a different script should also not hit the cache\n\n    textShaper.shape(\n        unicode.data(), unicode.size(), *avenirNext->withSize(12.0f).value(), true, 2.0f, TextScript::common(), glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(1), testTextShaper->shapeRequests.size());\n    testTextShaper->shapeRequests.clear();\n\n    textShaper.shape(\n        unicode.data(), unicode.size(), *avenirNext->withSize(12.0f).value(), true, 2.0f, TextScript::common(), glyphs);\n    ASSERT_EQ(static_cast<size_t>(0), testTextShaper->shapeRequests.size());\n}\n\nTEST_F(WordCachingTextShaperTest, canPrioritizeCacheHit) {\n    WordCachingTextShaper textShaper(testTextShaper, WordCachingTextShaperStrategy::PrioritizeCacheHit);\n\n    auto unicode = utf8ToUnicode(\"word word    word  \");\n\n    std::vector<ShapedGlyph> glyphs;\n\n    textShaper.shape(unicode.data(), unicode.size(), *avenirNext, false, 1.0f, TextScript::invalid(), glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(1), testTextShaper->shapeRequests.size());\n\n    ASSERT_EQ(\"word\", testTextShaper->shapeRequests[0].characters);\n\n    for (const auto& shapeRequest : testTextShaper->shapeRequests) {\n        ASSERT_NE(avenirNext, shapeRequest.font);\n        ASSERT_EQ(avenirNext->typeface(), shapeRequest.font->typeface());\n        ASSERT_EQ(12.0f, shapeRequest.font->size());\n        ASSERT_FALSE(shapeRequest.isRightToLeft);\n        ASSERT_EQ(1.0f, shapeRequest.letterSpacing);\n    }\n\n    ASSERT_EQ(static_cast<size_t>(19), glyphs.size());\n    ASSERT_EQ(17.0f, glyphs[0].advanceX);\n    glyphs.clear();\n\n    testTextShaper->shapeRequests.clear();\n\n    textShaper.shape(unicode.data(),\n                     unicode.size(),\n                     *avenirNext->withSize(9.0f).value(),\n                     false,\n                     1.0f,\n                     TextScript::invalid(),\n                     glyphs);\n\n    // We should get a cache hit even with a font of different size\n    ASSERT_EQ(static_cast<size_t>(0), testTextShaper->shapeRequests.size());\n\n    ASSERT_EQ(static_cast<size_t>(19), glyphs.size());\n    ASSERT_EQ(9.0f, glyphs[0].advanceX);\n    glyphs.clear();\n\n    textShaper.shape(unicode.data(),\n                     unicode.size(),\n                     *avenirNext->withSize(12.0f).value(),\n                     false,\n                     1.0f,\n                     TextScript::invalid(),\n                     glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(0), testTextShaper->shapeRequests.size());\n\n    ASSERT_EQ(static_cast<size_t>(19), glyphs.size());\n    ASSERT_EQ(12.0f, glyphs[0].advanceX);\n    glyphs.clear();\n\n    textShaper.shape(unicode.data(),\n                     unicode.size(),\n                     *avenirNext->withSize(20.0f).value(),\n                     false,\n                     1.0f,\n                     TextScript::invalid(),\n                     glyphs);\n\n    ASSERT_EQ(static_cast<size_t>(0), testTextShaper->shapeRequests.size());\n\n    ASSERT_EQ(static_cast<size_t>(19), glyphs.size());\n    ASSERT_EQ(20.0f, glyphs[0].advanceX);\n    glyphs.clear();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/utils/DisplayListBuilder.cpp",
    "content": "#include \"DisplayListBuilder.hpp\"\n#include \"snap_drawing/cpp/Drawing/Mask/PaintMask.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n\nnamespace snap::drawing {\n\nDisplayListBuilder::DisplayListBuilder(Scalar width, Scalar height)\n    : displayList(Valdi::makeShared<DisplayList>(Size(width, height), TimePoint(0.0))) {}\n\nvoid DisplayListBuilder::context(Vector translation, Scalar opacity, BuilderCb&& cb) {\n    context(translation, opacity, 0, true, std::move(cb));\n}\n\nvoid DisplayListBuilder::context(const Matrix& matrix, Scalar opacity, BuilderCb&& cb) {\n    context(matrix, opacity, 0, true, std::move(cb));\n}\n\nvoid DisplayListBuilder::context(\n    Vector translation, Scalar opacity, uint64_t layerId, bool hasUpdates, BuilderCb&& cb) {\n    Matrix matrix;\n    matrix.setTranslateX(translation.dx);\n    matrix.setTranslateY(translation.dy);\n\n    context(matrix, opacity, layerId, hasUpdates, std::move(cb));\n}\n\nvoid DisplayListBuilder::context(\n    const Matrix& matrix, Scalar opacity, uint64_t layerId, bool hasUpdates, BuilderCb&& cb) {\n    displayList->pushContext(matrix, opacity, layerId, hasUpdates);\n\n    cb();\n\n    displayList->popContext();\n}\n\nvoid DisplayListBuilder::layerContent(const LayerContent& layerContent, Scalar opacity) {\n    displayList->appendLayerContent(layerContent, opacity);\n}\n\nLayerContent DisplayListBuilder::draw(Size size, Scalar opacity, Valdi::Function<void(DrawingContext&)>&& cb) {\n    DrawingContext ctx(size.width, size.height);\n\n    cb(ctx);\n\n    auto content = ctx.finish();\n\n    layerContent(content, opacity);\n\n    return content;\n}\n\nLayerContent DisplayListBuilder::rectangle(Size size, Scalar opacity) {\n    return draw(size, opacity, [](DrawingContext& drawingContext) {\n        Paint paint;\n        paint.setColor(Color::blue());\n\n        drawingContext.drawPaint(paint, drawingContext.drawBounds());\n    });\n}\n\nLayerContent DisplayListBuilder::externalSurface(Size size, Scalar opacity) {\n    return draw(size, opacity, [&](DrawingContext& drawingContext) {\n        auto externalSurface = Valdi::makeShared<ExternalSurface>();\n        externalSurface->setRelativeSize(size);\n\n        drawingContext.drawExternalSurface(externalSurface);\n    });\n}\n\nvoid DisplayListBuilder::clip(Size size) {\n    displayList->appendClipRect(size.width, size.height);\n}\n\nvoid DisplayListBuilder::clip(const BorderRadius& borderRadius, Size size) {\n    displayList->appendClipRound(borderRadius, size.width, size.height);\n}\n\nvoid DisplayListBuilder::plane(BuilderCb&& cb) {\n    displayList->appendPlane();\n    cb();\n}\n\nvoid DisplayListBuilder::mask(const Rect& rect, BuilderCb&& cb) {\n    Paint paint;\n    auto mask = Valdi::makeShared<PaintMask>(paint, Path(), rect);\n    displayList->appendPrepareMask(mask.get());\n    cb();\n    displayList->appendApplyMask(mask.get());\n}\n\nstruct ToArrayVisitor {\n    std::vector<const Operations::Operation*> operations;\n\n    template<typename T>\n    void visit(const T& operation) {\n        operations.emplace_back(&static_cast<const Operations::Operation&>(operation));\n    }\n};\n\nstd::vector<const Operations::Operation*> getOperationsFromDisplayList(const DisplayList& displayList,\n                                                                       size_t planeIndex) {\n    ToArrayVisitor visitor;\n    displayList.visitOperations(planeIndex, visitor);\n\n    return std::move(visitor.operations);\n}\n\nstd::vector<const Operations::Operation*> getOperationsFromDisplayList(const Ref<DisplayList>& displayList,\n                                                                       size_t planeIndex) {\n    return getOperationsFromDisplayList(*displayList, planeIndex);\n}\n\nbool operator==(const DisplayList& left, const DisplayList& right) {\n    return left.toDebugJSON() == right.toDebugJSON();\n}\n\nbool operator!=(const DisplayList& left, const DisplayList& right) {\n    return !(left == right);\n}\n\nstd::ostream& operator<<(std::ostream& os, const DisplayList& displayList) {\n    return os << displayList.toDebugJSON().toString(true);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/utils/DisplayListBuilder.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Drawing/DisplayList/DisplayList.hpp\"\n#include \"snap_drawing/cpp/Drawing/DrawingContext.hpp\"\n#include \"snap_drawing/cpp/Drawing/Surface/ExternalSurface.hpp\"\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n#include <vector>\n\nnamespace snap::drawing {\n\nusing BuilderCb = Valdi::Function<void()>;\n\nstruct DisplayListBuilder {\n    Ref<DisplayList> displayList;\n\n    DisplayListBuilder(Scalar width, Scalar height);\n\n    void context(Vector translation, Scalar opacity, BuilderCb&& cb);\n\n    void context(const Matrix& matrix, Scalar opacity, BuilderCb&& cb);\n\n    void context(Vector translation, Scalar opacity, uint64_t layerId, bool hasUpdates, BuilderCb&& cb);\n\n    void context(const Matrix& matrix, Scalar opacity, uint64_t layerId, bool hasUpdates, BuilderCb&& cb);\n\n    LayerContent draw(Size size, Scalar opacity, Valdi::Function<void(DrawingContext&)>&& cb);\n\n    LayerContent rectangle(Size size, Scalar opacity);\n\n    LayerContent externalSurface(Size size, Scalar opacity);\n\n    void mask(const Rect& rect, BuilderCb&& cb);\n\n    void layerContent(const LayerContent& layerContent, Scalar opacity);\n\n    void clip(Size size);\n    void clip(const BorderRadius& borderRadius, Size size);\n\n    void plane(BuilderCb&& cb);\n};\n\nstd::vector<const Operations::Operation*> getOperationsFromDisplayList(const Ref<DisplayList>& displayList,\n                                                                       size_t planeIndex);\n\nbool operator==(const DisplayList& left, const DisplayList& right);\nbool operator!=(const DisplayList& left, const DisplayList& right);\nstd::ostream& operator<<(std::ostream& os, const DisplayList& displayList);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/utils/TestBitmap.cpp",
    "content": "#include \"TestBitmap.hpp\"\n#include \"utils/debugging/Assert.hpp\"\n\nnamespace snap::drawing {\n\nTestBitmap::TestBitmap(int width, int height) : _width(width), _height(height) {\n    auto offset = getPixelOffset(0, height);\n    _pixels.resize(offset);\n\n    for (int y = 0; y < height; y++) {\n        for (int x = 0; x < width; x++) {\n            setPixel(x, y, Color::white());\n        }\n    }\n}\n\nTestBitmap::~TestBitmap() = default;\n\nvoid TestBitmap::dispose() {}\n\nValdi::BitmapInfo TestBitmap::getInfo() const {\n    return Valdi::BitmapInfo(\n        _width, _height, Valdi::ColorTypeBGRA8888, Valdi::AlphaTypePremul, static_cast<size_t>(_width) * sizeof(Color));\n}\n\nvoid* TestBitmap::lockBytes() {\n    if (_onLock) {\n        _onLock();\n    }\n\n    return _pixels.data();\n}\n\nvoid TestBitmap::unlockBytes() {}\n\nColor TestBitmap::getPixel(int x, int y) const {\n    return *getPixelPtr(x, y);\n}\n\nvoid TestBitmap::setPixel(int x, int y, Color pixel) {\n    *getPixelPtr(x, y) = pixel;\n}\n\nvoid TestBitmap::setPixelsRow(int y, const Color* pixels) {\n    auto* ptr = getPixelPtr(0, y);\n\n    std::memcpy(ptr, pixels, static_cast<size_t>(_width) * sizeof(Color));\n}\n\nvoid TestBitmap::setOnLockCallback(Valdi::Function<void()>&& onLock) {\n    _onLock = std::move(onLock);\n}\n\nvoid TestBitmap::setPixels(const std::initializer_list<Color>& pixels) {\n    SC_ASSERT(pixels.size() == static_cast<size_t>(_width) * _height);\n    std::memcpy(_pixels.data(), pixels.begin(), pixels.size() * sizeof(Color));\n}\n\nbool TestBitmap::operator==(const TestBitmap& other) const {\n    if (_width != other._width || _height != other._height) {\n        return false;\n    }\n\n    return _pixels == other._pixels;\n}\n\nbool TestBitmap::operator!=(const TestBitmap& other) const {\n    return !(*this == other);\n}\n\nbool TestBitmap::operator==(const std::initializer_list<Color>& pixels) const {\n    if (pixels.size() != (_pixels.size() / sizeof(Color))) {\n        return false;\n    }\n\n    const auto* pixelsPtr = getPixelPtr(0, 0);\n    for (size_t i = 0; i < pixels.size(); i++) {\n        if (pixelsPtr[i] != pixels.begin()[i]) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nbool TestBitmap::operator!=(const std::initializer_list<Color>& pixels) const {\n    return !(*this == pixels);\n}\n\ninline size_t TestBitmap::getPixelOffset(int x, int y) const {\n    return ((y * _width) + x) * sizeof(Color);\n}\n\ninline Color* TestBitmap::getPixelPtr(int x, int y) const {\n    auto offset = getPixelOffset(x, y);\n    return reinterpret_cast<Color*>(_pixels[offset]);\n}\n\nSinglePixelBitmap::SinglePixelBitmap() : TestBitmap(1, 1) {}\n\nColor SinglePixelBitmap::getPixel() const {\n    return TestBitmap::getPixel(0, 0);\n}\n\nvoid SinglePixelBitmap::setPixel(Color pixel) {\n    TestBitmap::setPixel(0, 0, pixel);\n}\n\nBitmapBuilder::BitmapBuilder(int width, int height)\n    : _height(height), _bitmap(Valdi::makeShared<TestBitmap>(width, height)) {}\n\nint BitmapBuilder::incrementRow() {\n    auto row = ++_currentRow;\n    SC_ASSERT(row < _height);\n    return row;\n}\n\nBitmapBuilder& BitmapBuilder::row(std::initializer_list<Color> pixels) {\n    _bitmap->setPixelsRow(incrementRow(), pixels.begin());\n    return *this;\n}\n\nBitmapBuilder& BitmapBuilder::row(const std::vector<Color>& pixels) {\n    _bitmap->setPixelsRow(incrementRow(), pixels.data());\n    return *this;\n}\n\nValdi::Ref<TestBitmap> BitmapBuilder::build() {\n    SC_ASSERT(_currentRow + 1 == _height);\n    return _bitmap;\n}\n\nstd::ostream& operator<<(std::ostream& os, const TestBitmap& bitmap) {\n    auto info = bitmap.getInfo();\n\n    for (int y = 0; y < info.height; y++) {\n        os << \"\\n[\";\n        for (int x = 0; x < info.width; x++) {\n            auto pixel = bitmap.getPixel(x, y);\n            if (x > 0) {\n                os << \", \";\n            }\n            os << pixel;\n        }\n        os << \"]\";\n    }\n\n    return os;\n}\n\nValdi::Ref<TestBitmap> createTestBitmap() {\n    const int height = 6;\n    BitmapBuilder builder(8, height);\n    for (int i = 0; i < height; i++) {\n        builder.row({Color(0xFF000000),\n                     Color(0x00FF0000),\n                     Color(0x0000FF00),\n                     Color(0x000000FF),\n                     Color(0xFF000000),\n                     Color(0x00FF0000),\n                     Color(0x0000FF00),\n                     Color(0x000000FF)});\n    }\n    return builder.build();\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/utils/TestBitmap.hpp",
    "content": "#pragma once\n\n#include \"snap_drawing/cpp/Utils/Color.hpp\"\n#include \"valdi_core/cpp/Interfaces/IBitmap.hpp\"\n#include \"valdi_core/cpp/Utils/ByteBuffer.hpp\"\n#include \"valdi_core/cpp/Utils/Function.hpp\"\n\n#include <ostream>\n#include <vector>\n\nnamespace snap::drawing {\n\nclass TestBitmap : public Valdi::IBitmap {\npublic:\n    TestBitmap(int width, int height);\n\n    ~TestBitmap() override;\n\n    void dispose() override;\n\n    Valdi::BitmapInfo getInfo() const override;\n\n    void* lockBytes() override;\n\n    void unlockBytes() override;\n\n    Color getPixel(int x, int y) const;\n\n    void setPixel(int x, int y, Color pixel);\n\n    void setPixels(const std::initializer_list<Color>& pixels);\n\n    void setPixelsRow(int y, const Color* pixels);\n\n    void setOnLockCallback(Valdi::Function<void()>&& onLock);\n\n    bool operator==(const TestBitmap& other) const;\n    bool operator!=(const TestBitmap& other) const;\n    bool operator==(const std::initializer_list<Color>& pixels) const;\n    bool operator!=(const std::initializer_list<Color>& pixels) const;\n\nprivate:\n    Valdi::ByteBuffer _pixels;\n    int _width;\n    int _height;\n    Valdi::Function<void()> _onLock;\n\n    inline size_t getPixelOffset(int x, int y) const;\n\n    inline Color* getPixelPtr(int x, int y) const;\n};\n\nclass SinglePixelBitmap : public TestBitmap {\npublic:\n    SinglePixelBitmap();\n\n    Color getPixel() const;\n\n    void setPixel(Color pixel);\n};\n\nclass BitmapBuilder {\npublic:\n    BitmapBuilder(int width, int height);\n\n    BitmapBuilder& row(std::initializer_list<Color> pixels);\n    BitmapBuilder& row(const std::vector<Color>& pixels);\n\n    Valdi::Ref<TestBitmap> build();\n\nprivate:\n    int incrementRow();\n\n    int _height;\n    int _currentRow = -1;\n    Valdi::Ref<TestBitmap> _bitmap;\n};\n\nValdi::Ref<TestBitmap> createTestBitmap();\n\nstd::ostream& operator<<(std::ostream& os, const TestBitmap& bitmap);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/utils/TestDataUtils.cpp",
    "content": "#include \"TestDataUtils.hpp\"\n#include \"valdi_core/cpp/Utils/DiskUtils.hpp\"\n#include <unistd.h>\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nPath resolveTestPath(const std::string& path) {\n    char cwdBuffer[PATH_MAX];\n    (void)::getcwd(cwdBuffer, PATH_MAX);\n\n    auto basePath = Path(cwdBuffer);\n\n    basePath.append(\"external/_main~local_repos~valdi/snap_drawing/testdata\");\n    basePath.append(path);\n    basePath.normalize();\n\n    return basePath;\n}\n\nValdi::Result<Valdi::BytesView> getTestData(const std::string& filename) {\n    auto path = resolveTestPath(filename);\n    return DiskUtils::load(path);\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/utils/TestDataUtils.hpp",
    "content": "#include \"valdi_core/cpp/Utils/Bytes.hpp\"\n#include \"valdi_core/cpp/Utils/PathUtils.hpp\"\n#include \"valdi_core/cpp/Utils/Result.hpp\"\n\nnamespace snap::drawing {\n\nValdi::Path resolveTestPath(const std::string& path);\nValdi::Result<Valdi::BytesView> getTestData(const std::string& filename);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/utils/TestGestureUtils.cpp",
    "content": "\n#include \"TestGestureUtils.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nRef<Resources> createResources() {\n    return makeShared<Resources>(nullptr, 1.0f, ConsoleLogger::getLogger());\n}\n\nRef<LayerRoot> makeRoot() {\n    return makeShared<LayerRoot>(createResources());\n}\n\nRef<Layer> createView(Scalar x, Scalar y, Scalar width, Scalar height) {\n    auto view = makeShared<Layer>(createResources());\n    view->setFrame(Rect::makeXYWH(x, y, width, height));\n    return view;\n}\n\nTouchEvent createTouchEvent(\n    TouchEventType type, Scalar x, Scalar y, Scalar dx, Scalar dy, int pointerCount, Duration delay) {\n    static auto referencePoint = TimePoint::now();\n\n    // TODO(2835) - add support for these when they're used\n    TouchEvent::PointerLocations pointerLocations;\n    pointerLocations.push_back(Point::make(x, y));\n    return TouchEvent(type,\n                      Point::make(x, y),\n                      Point::make(x, y),\n                      Vector::make(dx, dy),\n                      pointerCount,\n                      0,\n                      std::move(pointerLocations),\n                      referencePoint + delay,\n                      Duration(),\n                      nullptr);\n}\n\nTestContainer::TestContainer(Rect size) {\n    root = makeRoot();\n    view = createView(size.left, size.top, size.width(), size.height());\n    root->setContentLayer(view, ContentLayerSizingModeMatchSize);\n}\n\nvoid TestContainer::dispatchEvent(\n    TouchEventType type, Scalar x, Scalar y, Scalar dx, Scalar dy, int pointerCount, Duration delay) {\n    root->dispatchTouchEvent(createTouchEvent(type, x, y, dx, dy, pointerCount, delay));\n}\n\nRef<TestContainer> makeContainer(Scalar x, Scalar y, Scalar width, Scalar height) {\n    return makeShared<TestContainer>(Rect::makeXYWH(x, y, width, height));\n}\n\nCustomTapGestureRecognizer::CustomTapGestureRecognizer(size_t taps)\n    : TapGestureRecognizer(taps, GesturesConfiguration::getDefault()) {}\n\nbool CustomTapGestureRecognizer::canRecognizeSimultaneously(const GestureRecognizer& other) const {\n    return shouldRecognizeSimulatenously;\n}\n\nbool CustomTapGestureRecognizer::requiresFailureOf(const GestureRecognizer& other) const {\n    return shouldRequiresFailureOf;\n}\n\nstd::string_view CustomTapGestureRecognizer::getTypeName() const {\n    return \"custom\";\n}\n\nCustomTouchGestureRecognizer::CustomTouchGestureRecognizer()\n    : TouchGestureRecognizer(GesturesConfiguration::getDefault()) {}\n\nbool CustomTouchGestureRecognizer::canRecognizeSimultaneously(const GestureRecognizer& other) const {\n    return shouldRecognizeSimulatenously;\n}\n\nbool CustomTouchGestureRecognizer::requiresFailureOf(const GestureRecognizer& other) const {\n    return shouldRequiresFailureOf;\n}\n\nRef<GestureRecognizerSnapshot> addCustomTouchGesture(const Ref<Layer>& view,\n                                                     bool shouldRecognizeSimulatenously,\n                                                     bool shouldRequiresFailureOf) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    auto gestureRecognizer = makeShared<CustomTouchGestureRecognizer>();\n    gestureRecognizer->setListener(([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point;\n        snapshot->counter++;\n    }));\n    snapshot->parent = gestureRecognizer;\n    gestureRecognizer->shouldRecognizeSimulatenously = shouldRecognizeSimulatenously;\n    gestureRecognizer->shouldRequiresFailureOf = shouldRequiresFailureOf;\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\nRef<GestureRecognizerSnapshot> addCustomTapGesture(const Ref<Layer>& view,\n                                                   size_t taps,\n                                                   bool shouldRecognizeSimulatenously,\n                                                   bool shouldRequiresFailureOf) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    auto gestureRecognizer = makeShared<CustomTapGestureRecognizer>(taps);\n    gestureRecognizer->setListener(([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point;\n        snapshot->counter++;\n    }));\n    snapshot->parent = gestureRecognizer;\n    gestureRecognizer->shouldRecognizeSimulatenously = shouldRecognizeSimulatenously;\n    gestureRecognizer->shouldRequiresFailureOf = shouldRequiresFailureOf;\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\nRef<GestureRecognizerSnapshot> addSingleTapGesture(const Ref<Layer>& view) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    auto gestureRecognizer = makeShared<SingleTapGestureRecognizer>(GesturesConfiguration::getDefault());\n    gestureRecognizer->setListener(([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point;\n        snapshot->counter++;\n    }));\n    snapshot->parent = gestureRecognizer;\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\nRef<GestureRecognizerSnapshot> addDoubleTapGesture(const Ref<Layer>& view) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    auto gestureRecognizer = makeShared<DoubleTapGestureRecognizer>(GesturesConfiguration::getDefault());\n    gestureRecognizer->setListener(([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point;\n        snapshot->counter++;\n    }));\n    snapshot->parent = gestureRecognizer;\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\nRef<GestureRecognizerSnapshot> addLongPressGesture(const Ref<Layer>& view) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    auto gestureRecognizer = makeShared<LongPressGestureRecognizer>(GesturesConfiguration::getDefault());\n    gestureRecognizer->setListener(([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point;\n        snapshot->counter++;\n    }));\n    snapshot->parent = gestureRecognizer;\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\nRef<TouchGestureRecognizer> makeTouchGestureRecognizer(const Ref<Layer>& view) {\n    auto gestureRecognizer = makeShared<TouchGestureRecognizer>(GesturesConfiguration::getDefault());\n    view->addGestureRecognizer(gestureRecognizer);\n    return gestureRecognizer;\n}\n\nRef<GestureRecognizerSnapshot> addTouchGesture(const Ref<TouchGestureRecognizer>& gestureRecognizer) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    gestureRecognizer->setListener(([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point;\n        snapshot->counter++;\n    }));\n    snapshot->parent = gestureRecognizer;\n    return snapshot;\n}\n\nRef<GestureRecognizerSnapshot> addTouchStartGesture(const Ref<TouchGestureRecognizer>& gestureRecognizer) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    gestureRecognizer->setOnStartListener(([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point;\n        snapshot->counter++;\n    }));\n    snapshot->parent = gestureRecognizer;\n    return snapshot;\n}\n\nRef<GestureRecognizerSnapshot> addTouchEndGesture(const Ref<TouchGestureRecognizer>& gestureRecognizer) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    gestureRecognizer->setOnEndListener(([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point;\n        snapshot->counter++;\n    }));\n    snapshot->parent = gestureRecognizer;\n    return snapshot;\n}\n\nRef<GestureRecognizerSnapshot> addDragGesture(const Ref<Layer>& view, bool shouldCancelOtherGesturesOnStart) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    auto gestureRecognizer = makeShared<DragGestureRecognizer>(GesturesConfiguration::getDefault());\n    gestureRecognizer->setListener([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point.location;\n        snapshot->counter++;\n    });\n    snapshot->parent = gestureRecognizer;\n    gestureRecognizer->setShouldCancelOtherGesturesOnStart(shouldCancelOtherGesturesOnStart);\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\nRef<RotateGestureRecognizerSnapshot> addRotateGesture(const Ref<Layer>& view) {\n    auto snapshot = makeShared<RotateGestureRecognizerSnapshot>();\n    auto gestureRecognizer = makeShared<RotateGestureRecognizer>(GesturesConfiguration::getDefault());\n    gestureRecognizer->setListener([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point.location;\n        snapshot->rotateEvent = point;\n        snapshot->counter++;\n    });\n    snapshot->parent = gestureRecognizer;\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\nRef<PinchGestureRecognizerSnapshot> addPinchGesture(const Ref<Layer>& view) {\n    auto snapshot = makeShared<PinchGestureRecognizerSnapshot>();\n    auto gestureRecognizer = makeShared<PinchGestureRecognizer>(GesturesConfiguration::getDefault());\n    gestureRecognizer->setListener([=](const auto& gesture, auto state, const auto& point) {\n        snapshot->state = state;\n        snapshot->location = point.location;\n        snapshot->pinchEvent = point;\n        snapshot->counter++;\n    });\n    snapshot->parent = gestureRecognizer;\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\nRef<GestureRecognizerSnapshot> addWheelGesture(const Ref<Layer>& view) {\n    auto snapshot = makeShared<GestureRecognizerSnapshot>();\n    auto gestureRecognizer =\n        makeShared<WheelGestureRecognizer>([=](const auto& gesture, auto state, const auto& scrollEvent) {\n            snapshot->state = state;\n            snapshot->location = scrollEvent.location;\n            snapshot->direction = scrollEvent.direction;\n            snapshot->counter++;\n        });\n    snapshot->parent = gestureRecognizer;\n    view->addGestureRecognizer(gestureRecognizer);\n    return snapshot;\n}\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/test/utils/TestGestureUtils.hpp",
    "content": "#include <gtest/gtest.h>\n\n#include \"snap_drawing/cpp/Layers/Layer.hpp\"\n#include \"snap_drawing/cpp/Layers/LayerRoot.hpp\"\n#include \"valdi_core/cpp/Utils/ConsoleLogger.hpp\"\n\n#include \"snap_drawing/cpp/Touches/DoubleTapGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/DragGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/LongPressGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/PinchGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/RotateGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/SingleTapGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/TapGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/TouchGestureRecognizer.hpp\"\n#include \"snap_drawing/cpp/Touches/WheelGestureRecognizer.hpp\"\n\nusing namespace Valdi;\n\nnamespace snap::drawing {\n\nRef<LayerRoot> makeRoot();\n\nRef<Layer> createView(Scalar x, Scalar y, Scalar width, Scalar height);\n\nTouchEvent createTouchEvent(TouchEventType type,\n                            Scalar x,\n                            Scalar y,\n                            Scalar dx = 0,\n                            Scalar dy = 0,\n                            int pointerCount = 1,\n                            Duration after = Duration::fromSeconds(0));\n\nclass TestContainer : public SimpleRefCountable {\npublic:\n    TestContainer(Rect size);\n\n    Ref<LayerRoot> root;\n    Ref<Layer> view;\n\n    void dispatchEvent(TouchEventType type,\n                       Scalar x,\n                       Scalar y,\n                       Scalar dx = 0,\n                       Scalar dy = 0,\n                       int pointerCount = 1,\n                       Duration after = Duration::fromSeconds(0));\n};\n\nstruct GestureRecognizerSnapshot : public SimpleRefCountable {\n    GestureRecognizerState state = GestureRecognizerStatePossible;\n    Point location = Point::makeEmpty();\n    Vector direction = Vector::makeEmpty();\n    int counter = 0;\n    Ref<GestureRecognizer> parent;\n};\n\nstruct RotateGestureRecognizerSnapshot : public GestureRecognizerSnapshot {\n    RotateEvent rotateEvent;\n};\nstruct PinchGestureRecognizerSnapshot : public GestureRecognizerSnapshot {\n    PinchEvent pinchEvent;\n};\n\nclass CustomTapGestureRecognizer : public TapGestureRecognizer {\npublic:\n    using TapGestureRecognizer::TapGestureRecognizer;\n\n    CustomTapGestureRecognizer(size_t taps);\n\n    bool canRecognizeSimultaneously(const GestureRecognizer& other) const override;\n    bool requiresFailureOf(const GestureRecognizer& other) const override;\n    std::string_view getTypeName() const final;\n\n    bool shouldRecognizeSimulatenously = false;\n    bool shouldRequiresFailureOf = false;\n};\n\nclass CustomTouchGestureRecognizer : public TouchGestureRecognizer {\npublic:\n    using TouchGestureRecognizer::TouchGestureRecognizer;\n\n    CustomTouchGestureRecognizer();\n\n    bool canRecognizeSimultaneously(const GestureRecognizer& other) const override;\n    bool requiresFailureOf(const GestureRecognizer& other) const override;\n\n    bool shouldRecognizeSimulatenously = false;\n    bool shouldRequiresFailureOf = false;\n};\n\nRef<TestContainer> makeContainer(Scalar x, Scalar y, Scalar width, Scalar height);\n\nRef<GestureRecognizerSnapshot> addCustomTouchGesture(const Ref<Layer>& view,\n                                                     bool shouldRecognizeSimulatenously = true,\n                                                     bool shouldRequiresFailureOf = false);\n\nRef<GestureRecognizerSnapshot> addCustomTapGesture(const Ref<Layer>& view,\n                                                   size_t taps,\n                                                   bool shouldRecognizeSimulatenously = true,\n                                                   bool shouldRequiresFailureOf = false);\n\nRef<GestureRecognizerSnapshot> addSingleTapGesture(const Ref<Layer>& view);\nRef<GestureRecognizerSnapshot> addDoubleTapGesture(const Ref<Layer>& view);\nRef<GestureRecognizerSnapshot> addLongPressGesture(const Ref<Layer>& view);\n\nRef<TouchGestureRecognizer> makeTouchGestureRecognizer(const Ref<Layer>& view);\n\nRef<GestureRecognizerSnapshot> addTouchGesture(const Ref<TouchGestureRecognizer>& gestureRecognizer);\nRef<GestureRecognizerSnapshot> addTouchStartGesture(const Ref<TouchGestureRecognizer>& gestureRecognizer);\nRef<GestureRecognizerSnapshot> addTouchEndGesture(const Ref<TouchGestureRecognizer>& gestureRecognizer);\n\nRef<GestureRecognizerSnapshot> addDragGesture(const Ref<Layer>& view, bool shouldCancelOtherGesturesOnStart = false);\nRef<RotateGestureRecognizerSnapshot> addRotateGesture(const Ref<Layer>& view);\nRef<PinchGestureRecognizerSnapshot> addPinchGesture(const Ref<Layer>& view);\nRef<GestureRecognizerSnapshot> addWheelGesture(const Ref<Layer>& view);\n\n} // namespace snap::drawing\n"
  },
  {
    "path": "snap_drawing/testdata/lottie_loading.json",
    "content": "{\"v\":\"4.5.7\",\"fr\":30,\"ip\":0,\"op\":97,\"w\":512,\"h\":512,\"ddd\":0,\"assets\":[{\"id\":\"comp_0\",\"layers\":[{\"ddd\":0,\"ind\":0,\"ty\":4,\"nm\":\"Layer 2/loader Outlines\",\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[{\"i\":{\"x\":0.667,\"y\":1},\"o\":{\"x\":0.167,\"y\":0.167},\"n\":\"0p667_1_0p167_0p167\",\"t\":15,\"s\":[400,337,0],\"e\":[396,335.04,0],\"to\":[0,-0.57204169034958,0],\"ti\":[2.25,3.28968811035156,0]},{\"i\":{\"x\":0.833,\"y\":0.833},\"o\":{\"x\":0.31,\"y\":0},\"n\":\"0p833_0p833_0p31_0\",\"t\":26,\"s\":[396,335.04,0],\"e\":[400,230,0],\"to\":[-1.89180493354797,-2.76597690582275,0],\"ti\":[32.75,5.75,0]},{\"i\":{\"x\":0.658,\"y\":0.366},\"o\":{\"x\":0.322,\"y\":0},\"n\":\"0p658_0p366_0p322_0\",\"t\":37,\"s\":[400,230,0],\"e\":[397.463,229.697,0],\"to\":[-0.8968859910965,-0.13742607831955,0],\"ti\":[0.79534405469894,0.06496899574995,0]},{\"i\":{\"x\":0.749,\"y\":0.753},\"o\":{\"x\":0.356,\"y\":0.179},\"n\":\"0p749_0p753_0p356_0p179\",\"t\":38,\"s\":[397.463,229.697,0],\"e\":[400,265,0],\"to\":[-26.6949577331543,-2.18062162399292,0],\"ti\":[0,0,0]},{\"i\":{\"x\":0.811,\"y\":0},\"o\":{\"x\":0.167,\"y\":0},\"n\":\"0p811_0_0p167_0\",\"t\":43,\"s\":[400,265,0],\"e\":[470.35,266.825,0],\"to\":[0,0,0],\"ti\":[0,0,0]},{\"t\":83.0000033806593}]},\"a\":{\"k\":[106,105.5,0]},\"s\":{\"k\":[{\"i\":{\"x\":[0.207,0.207,0.667],\"y\":[0.954,0.954,0.667]},\"o\":{\"x\":[0.167,0.167,0.167],\"y\":[0,0,0.167]},\"n\":[\"0p207_0p954_0p167_0\",\"0p207_0p954_0p167_0\",\"0p667_0p667_0p167_0p167\"],\"t\":0,\"s\":[0,0,100],\"e\":[33,33,100]},{\"t\":15.0000006109625}]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,57.99],[57.99,0],[0,-57.99],[-57.99,0]],\"o\":[[0,-57.99],[-57.99,0],[0,57.99],[57.99,0]],\"v\":[[105,0],[0,-105],[-105,0],[0,105]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.08,0.08,0.08,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"},{\"ty\":\"tr\",\"p\":{\"k\":[106,105.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[100,100],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 1\",\"np\":2,\"mn\":\"ADBE Vector Group\"}],\"ip\":0,\"op\":43.0000017514259,\"st\":-3.00000012219251,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":1,\"ty\":4,\"nm\":\"Layer 1/loader Outlines\",\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":[{\"i\":{\"x\":[0.428],\"y\":[1]},\"o\":{\"x\":[0.167],\"y\":[0.167]},\"n\":[\"0p428_1_0p167_0p167\"],\"t\":43,\"s\":[0],\"e\":[90]},{\"i\":{\"x\":[0.517],\"y\":[1]},\"o\":{\"x\":[0.359],\"y\":[0]},\"n\":[\"0p517_1_0p359_0\"],\"t\":58,\"s\":[90],\"e\":[480]},{\"i\":{\"x\":[0.128],\"y\":[0.158]},\"o\":{\"x\":[0.249],\"y\":[0]},\"n\":[\"0p128_0p158_0p249_0\"],\"t\":83,\"s\":[480],\"e\":[500]},{\"i\":{\"x\":[0.762],\"y\":[-9.662]},\"o\":{\"x\":[0.958],\"y\":[1.387]},\"n\":[\"0p762_-9p662_0p958_1p387\"],\"t\":87,\"s\":[500],\"e\":[510]},{\"i\":{\"x\":[0.833],\"y\":[1]},\"o\":{\"x\":[0],\"y\":[0]},\"n\":[\"0p833_1_0_0\"],\"t\":90,\"s\":[510],\"e\":[900]},{\"t\":106.000004317469}]},\"p\":{\"k\":[400,337.175,0]},\"a\":{\"k\":[105.5,105.5,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"shapes\":[{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,19.33],[19.33,0],[0,-19.33],[-19.33,0]],\"o\":[[0,-19.33],[-19.33,0],[0,19.33],[19.33,0]],\"v\":[[35,0],[0,-35],[-35,0],[0,35]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.08,0.08,0.08,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"},{\"ty\":\"tr\",\"p\":{\"k\":[105.5,175.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":45,\"s\":[0,0],\"e\":[100,100]},{\"i\":{\"x\":[0.833,0.833],\"y\":[0.833,0.833]},\"o\":{\"x\":[0.167,0.167],\"y\":[0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":51,\"s\":[100,100],\"e\":[100,100]},{\"i\":{\"x\":[0.833,0.833],\"y\":[1,1]},\"o\":{\"x\":[0.167,0.167],\"y\":[0,0]},\"n\":[\"0p833_1_0p167_0\",\"0p833_1_0p167_0\"],\"t\":98,\"s\":[100,100],\"e\":[0,0]},{\"t\":104.000004236007}],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 1\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,19.33],[19.33,0],[0,-19.33],[-19.33,0]],\"o\":[[0,-19.33],[-19.33,0],[0,19.33],[19.33,0]],\"v\":[[35,0],[0,-35],[-35,0],[0,35]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.08,0.08,0.08,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"},{\"ty\":\"tr\",\"p\":{\"k\":[105.5,35.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[{\"i\":{\"x\":[0.833,0.833],\"y\":[0.833,0.833]},\"o\":{\"x\":[0.167,0.167],\"y\":[0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":43,\"s\":[100,100],\"e\":[100,100]},{\"i\":{\"x\":[0.833,0.833],\"y\":[1,1]},\"o\":{\"x\":[0.167,0.167],\"y\":[0,0]},\"n\":[\"0p833_1_0p167_0\",\"0p833_1_0p167_0\"],\"t\":94,\"s\":[100,100],\"e\":[0,0]},{\"t\":100.000004073084}],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 2\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,19.33],[19.33,0],[0,-19.33],[-19.33,0]],\"o\":[[0,-19.33],[-19.33,0],[0,19.33],[19.33,0]],\"v\":[[35,0],[0,-35],[-35,0],[0,35]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.08,0.08,0.08,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"},{\"ty\":\"tr\",\"p\":{\"k\":[35.5,105.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":47,\"s\":[0,0],\"e\":[100,100]},{\"i\":{\"x\":[0.833,0.833],\"y\":[0.833,0.833]},\"o\":{\"x\":[0.167,0.167],\"y\":[0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":53,\"s\":[100,100],\"e\":[100,100]},{\"i\":{\"x\":[0.833,0.833],\"y\":[1,1]},\"o\":{\"x\":[0.167,0.167],\"y\":[0,0]},\"n\":[\"0p833_1_0p167_0\",\"0p833_1_0p167_0\"],\"t\":100,\"s\":[100,100],\"e\":[0,0]},{\"t\":106.000004317469}],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 3\",\"np\":2,\"mn\":\"ADBE Vector Group\"},{\"ty\":\"gr\",\"it\":[{\"ind\":0,\"ty\":\"sh\",\"ks\":{\"k\":{\"i\":[[0,19.33],[19.33,0],[0,-19.33],[-19.33,0]],\"o\":[[0,-19.33],[-19.33,0],[0,19.33],[19.33,0]],\"v\":[[35,0],[0,-35],[-35,0],[0,35]],\"c\":true}},\"nm\":\"Path 1\",\"mn\":\"ADBE Vector Shape - Group\"},{\"ty\":\"fl\",\"fillEnabled\":true,\"c\":{\"k\":[0.08,0.08,0.08,1]},\"o\":{\"k\":100},\"nm\":\"Fill 1\",\"mn\":\"ADBE Vector Graphic - Fill\"},{\"ty\":\"tr\",\"p\":{\"k\":[175.5,105.5],\"ix\":2},\"a\":{\"k\":[0,0],\"ix\":1},\"s\":{\"k\":[{\"i\":{\"x\":[0.667,0.667],\"y\":[1,1]},\"o\":{\"x\":[0.333,0.333],\"y\":[0,0]},\"n\":[\"0p667_1_0p333_0\",\"0p667_1_0p333_0\"],\"t\":43,\"s\":[0,0],\"e\":[100,100]},{\"i\":{\"x\":[0.833,0.833],\"y\":[0.833,0.833]},\"o\":{\"x\":[0.167,0.167],\"y\":[0.167,0.167]},\"n\":[\"0p833_0p833_0p167_0p167\",\"0p833_0p833_0p167_0p167\"],\"t\":49,\"s\":[100,100],\"e\":[100,100]},{\"i\":{\"x\":[0.833,0.833],\"y\":[1,1]},\"o\":{\"x\":[0.167,0.167],\"y\":[0,0]},\"n\":[\"0p833_1_0p167_0\",\"0p833_1_0p167_0\"],\"t\":96,\"s\":[100,100],\"e\":[0,0]},{\"t\":102.000004154545}],\"ix\":3},\"r\":{\"k\":0,\"ix\":6},\"o\":{\"k\":100,\"ix\":7},\"sk\":{\"k\":0,\"ix\":4},\"sa\":{\"k\":0,\"ix\":5},\"nm\":\"Transform\"}],\"nm\":\"Group 4\",\"np\":2,\"mn\":\"ADBE Vector Group\"}],\"ip\":43.0000017514259,\"op\":117.000004765508,\"st\":-1.00000004073083,\"bm\":0,\"sr\":1}]}],\"layers\":[{\"ddd\":0,\"ind\":0,\"ty\":0,\"nm\":\"loader-source\",\"refId\":\"comp_0\",\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[400,263.5,0]},\"a\":{\"k\":[400,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"w\":800,\"h\":600,\"ip\":0,\"op\":117.000004765508,\"st\":0,\"bm\":0,\"sr\":1},{\"ddd\":0,\"ind\":1,\"ty\":1,\"nm\":\"Medium Red Solid 1\",\"ks\":{\"o\":{\"k\":100},\"r\":{\"k\":0},\"p\":{\"k\":[400,300,0]},\"a\":{\"k\":[400,300,0]},\"s\":{\"k\":[100,100,100]}},\"ao\":0,\"sw\":800,\"sh\":600,\"sc\":\"#ea6262\",\"ip\":0,\"op\":117.000004765508,\"st\":0,\"bm\":0,\"sr\":1}],\"v\":\"4.5.3\",\"ddd\":0,\"ip\":0,\"op\":117.000004765508,\"fr\":29.9700012207031,\"w\":800,\"h\":600}\n"
  },
  {
    "path": "src/BUILD.bazel",
    "content": "load(\"@rules_android//rules:rules.bzl\", \"android_library\")\n\n# Note don't add any c++ deps to this target as it doesn't work\n# Add C++ deps to the package_aar rule below\nandroid_library(\n    name = \"dummy_android\",\n    manifest = \"platform-projects/android/dummy/src/main/AndroidManifest.xml\",\n    visibility = [\"//visibility:public\"],\n    exports = [],\n)\n\ngenrule(\n    name = \"client_proguard-rules\",\n    srcs = [\n        \"platform-projects/android/client/proguard-rules.pro\",\n        \"//valdi:proguard-rules\",\n    ],\n    outs = [\"proguard.txt\"],\n    cmd = \"\"\"\n      : > $@\n      for f in $(SRCS); do\n        cat \"$$f\" >> $@\n        printf '\\\\n\\\\n' >> $@\n      done\n    \"\"\",\n    visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n    name = \"build_id_note_symbols.ld\",\n    srcs = [\"platform-projects/android/build_id_note_symbols.ld\"],\n    visibility = [\"//visibility:public\"],\n)\n\nfilegroup(\n    name = \"android_exports.lst\",\n    srcs = [\"platform-projects/android/android_exports.lst\"],\n    visibility = [\"//visibility:public\"],\n)\n\ncc_binary(\n    name = \"libdummy.so\",\n    additional_linker_inputs = select({\n        \"@snap_platforms//conditions:android\": [\n            \":android_exports.lst\",\n            \":build_id_note_symbols.ld\",\n        ],\n        \"//conditions:default\": [],\n    }),\n    linkopts = [\n        \"-fuse-ld=lld\",\n        \"--no-undefined\",\n        \"-landroid\",\n        \"-ldl\",\n        \"-llog\",\n        \"-lm\",\n        \"-lz\",\n    ] + select({\n        \"@snap_platforms//conditions:android\": [\"-Wl,--version-script=$(location :android_exports.lst) $(location :build_id_note_symbols.ld)\"],\n        \"//conditions:default\": [],\n    }),\n    linkshared = True,\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/utils:utils_logging_cc\",\n    ],\n)\n"
  },
  {
    "path": "src/platform-projects/android/android_exports.lst",
    "content": "{\n  global:\n    JNI_*;\n    Java_com_*;\n    GamesClient_*;\n    MapsClient_*;\n    VoiceMLClient_*;\n  local: *;\n};\n"
  },
  {
    "path": "src/platform-projects/android/build_id_note_symbols.ld",
    "content": "HIDDEN(sc_libclient_build_id_section_start = ADDR(.note.gnu.build-id));\nHIDDEN(sc_libclient_build_id_section_end = ADDR(.note.gnu.build-id) + SIZEOF(.note.gnu.build-id));\n"
  },
  {
    "path": "src/platform-projects/android/client/.gitignore",
    "content": "/build\n/.externalNativeBuild\nclient.iml\n/.cxx\n\n"
  },
  {
    "path": "src/platform-projects/android/client/proguard-rules.pro",
    "content": "# Client wraper libs\n-keep public enum com.snapchat.client.** {\n    **[] $VALUES;\n    public *;\n}\n\n-keep class com.snapchat.djinni.** { *; }\n\n# For serializing Djinni protos\n-keep class com.google.protobuf.nano.MessageNano { *; }"
  },
  {
    "path": "src/platform-projects/android/client/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.snapchat.client\">\n\n</manifest>"
  },
  {
    "path": "src/platform-projects/android/client/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!--\n        we need this string to have at least one resource in each aar\n        because of bug in new Android gradle 3.1 plugin that\n        does not create res folder if there are no resources\n        https://issuetracker.google.com/issues/77591523\n    -->\n    <string name=\"place_holder\"></string>\n</resources>\n"
  },
  {
    "path": "src/platform-projects/android/dummy/.gitignore",
    "content": "/build\n/.cxx\n"
  },
  {
    "path": "src/platform-projects/android/dummy/prepare_compressed_library.sh",
    "content": "#!/bin/bash\n\nset -euo pipefail\n\n# import monorepo utils\n. \"$(dirname ${BASH_SOURCE:-$0})/../../../../utils/monorepo.sh\"\n\nREPO_ROOT_DIR=\"$(get_dev_root)\"\n\nexport ZSTD=\"$REPO_ROOT_DIR/src/open_source/tools/zstd/zstdw\"\n\nUNPACKED_PATH=$1\npushd $UNPACKED_PATH\n\n# Note: This is renaming XYZ.so to XYZ.zst.so when the file gets\n# compressed. This is kind of clowny, but this is prototype code and\n# this approach will be revised once functional behavior is verified\n# in mushroom.\n#\n# But why?\n#\n# The default \"XYZ.so.zst\" filename used by the zstd tool will get\n# ignored by the android gradle MergeNativeLibsTask when it's\n# assembling native libs into the final apk, because the filename does\n# not end in \".so\"\n#\n# Reference (\"predicate\" is used to filter only files that match that pattern):\n# https://android.googlesource.com/platform/tools/base/+/studio-master-dev/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/tasks/MergeNativeLibsTask.kt#200\n#\n# One more note is that using this approach will cause some (benign --\n# does not fail the build) error messages to show up in the android\n# build logs. The build tries to strip symbols from XYZ.zst.so, but\n# it's not a format the symbol stripper is expecting.\nfind jni -name \"*.so\" -exec \\\n     bash -c 'set -euo pipefail; export TGT=$(echo $0 | sed \"s|.so$|.zst.so|\"); ${ZSTD} -f --ultra -22 -o $TGT --rm $0' {} \\;\n"
  },
  {
    "path": "src/platform-projects/android/dummy/proguard-rules.pro",
    "content": "# This file is intentionally empty. There is no Java code in this AAR.\n"
  },
  {
    "path": "src/platform-projects/android/dummy/src/main/AndroidManifest.xml",
    "content": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.snapchat.dummy\">\n\n</manifest>\n"
  },
  {
    "path": "src/platform-projects/android/dummy/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <!--\n        we need this string to have at least one resource in each aar\n        because of bug in new Android gradle 3.1 plugin that\n        does not create res folder if there are no resources\n        https://issuetracker.google.com/issues/77591523\n    -->\n    <string name=\"place_holder\"></string>\n</resources>\n"
  },
  {
    "path": "src/valdi_modules/.prettierrc.json",
    "content": "{\n  \"printWidth\": 120,\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"arrowParens\": \"avoid\",\n  \"tabWidth\": 2\n}\n"
  },
  {
    "path": "src/valdi_modules/src/cpp/valdi_http/BUILD.bazel",
    "content": "cc_library(\n    name = \"valdi_http_cpp\",\n    srcs = glob([\"**/*.cpp\"]),\n    hdrs = glob([\"**/*.hpp\"]),\n    includes = [],\n    visibility = [\"//visibility:public\"],\n    deps = [\"@valdi//valdi:valdi_runtime\"],\n    alwayslink = 1,\n)\n"
  },
  {
    "path": "src/valdi_modules/src/cpp/valdi_http/HTTPRequestManagerModuleFactory.cpp",
    "content": "//\n//  HTTPRequestManagerModuleFactory.cpp\n//  valdi-pc\n//\n//  Created by Simon Corsin on 10/14/20.\n//\n\n#include \"HTTPRequestManagerModuleFactory.hpp\"\n#include \"valdi/runtime/Runtime.hpp\"\n#include \"valdi/runtime/Utils/HTTPRequestManagerUtils.hpp\"\n#include \"valdi_core/Cancelable.hpp\"\n#include \"valdi_core/HTTPRequest.hpp\"\n#include \"valdi_core/HTTPResponse.hpp\"\n#include \"valdi_core/cpp/JavaScript/ModuleFactoryRegistry.hpp\"\n#include \"valdi_core/cpp/Utils/ValueFunctionWithCallable.hpp\"\n#include \"valdi_core/cpp/Utils/ValueTypedArray.hpp\"\n\nnamespace Valdi {\n\nHTTPRequestManagerModuleFactory::HTTPRequestManagerModuleFactory() = default;\nHTTPRequestManagerModuleFactory::~HTTPRequestManagerModuleFactory() = default;\n\nStringBox HTTPRequestManagerModuleFactory::getModulePath() {\n    return STRING_LITERAL(\"valdi_http/src/NativeHTTPClient\");\n}\n\nstatic Shared<snap::valdi_core::HTTPRequestManager> getRequestManager() {\n    auto runtime = Runtime::currentRuntime();\n    if (runtime == nullptr) {\n        return nullptr;\n    }\n\n    return runtime->getRequestManager();\n}\n\nValue HTTPRequestManagerModuleFactory::loadModule() {\n    Value out;\n\n    auto strongSelf = strongSmallRef(this);\n\n    out.setMapValue(\n        \"performRequest\",\n        Value(makeShared<ValueFunctionWithCallable>([strongSelf](const ValueFunctionCallContext& callContext) -> Value {\n            auto requestManager = getRequestManager();\n            if (requestManager == nullptr) {\n                callContext.getExceptionTracker().onError(Error(\"No RequestManager set\"));\n                return Value::undefined();\n            }\n\n            const auto& requestObject = callContext.getParameter(0);\n            auto url = requestObject.getMapValue(\"url\").toStringBox();\n            auto method = requestObject.getMapValue(\"method\").toStringBox();\n            auto headers = requestObject.getMapValue(\"headers\");\n            auto body = requestObject.getMapValue(\"body\").getTypedArrayRef();\n            auto priority = requestObject.getMapValue(\"priority\").toInt();\n\n            std::optional<BytesView> convertedBody;\n            if (body != nullptr) {\n                convertedBody = {body->getBuffer()};\n            }\n\n            auto completion =\n                callContext.getParameter(1).checkedTo<Ref<ValueFunction>>(callContext.getExceptionTracker());\n            if (!callContext.getExceptionTracker()) {\n                return Value::undefined();\n            }\n\n            auto requestCompletion = HTTPRequestManagerUtils::makeRequestCompletion(\n                [completion = std::move(completion)](const Result<snap::valdi_core::HTTPResponse>& result) {\n                    std::array<Value, 2> parameters;\n                    if (result) {\n                        const auto& response = result.value();\n\n                        Value convertedResponse;\n                        convertedResponse.setMapValue(\"headers\", response.headers);\n                        convertedResponse.setMapValue(\"statusCode\", Value(response.statusCode));\n\n                        if (response.body) {\n                            convertedResponse.setMapValue(\n                                \"body\",\n                                Value(makeShared<ValueTypedArray>(TypedArrayType::Uint8Array, response.body.value())));\n                        }\n\n                        parameters[0] = std::move(convertedResponse);\n                        parameters[1] = Value::undefined();\n                    } else {\n                        parameters[0] = Value::undefined();\n                        parameters[1] = Value(result.error());\n                    }\n\n                    (*completion)(parameters.data(), parameters.size());\n                });\n\n            auto cancellable = requestManager->performRequest(\n                snap::valdi_core::HTTPRequest(\n                    std::move(url), std::move(method), std::move(headers), std::move(convertedBody), priority),\n                requestCompletion);\n\n            Value out;\n            out.setMapValue(\"cancel\",\n                            Value(makeShared<ValueFunctionWithCallable>(\n                                [cancellable](const ValueFunctionCallContext& /*callContext*/) -> Value {\n                                    cancellable->cancel();\n                                    return Value::undefined();\n                                })));\n\n            return out;\n        })));\n\n    return out;\n}\n\nstatic auto kRegisterModule = Valdi::RegisterModuleFactory::registerTyped<HTTPRequestManagerModuleFactory>();\n\n} // namespace Valdi\n"
  },
  {
    "path": "src/valdi_modules/src/cpp/valdi_http/HTTPRequestManagerModuleFactory.hpp",
    "content": "//\n//  HTTPRequestManagerModuleFactory.hpp\n//  valdi-pc\n//\n//  Created by Simon Corsin on 10/14/20.\n//\n\n#pragma once\n\n#include \"valdi_core/HTTPRequestManager.hpp\"\n#include \"valdi_core/ModuleFactory.hpp\"\n\nnamespace Valdi {\n\nclass HTTPRequestManagerModuleFactory : public Valdi::SharedPtrRefCountable, public snap::valdi_core::ModuleFactory {\npublic:\n    HTTPRequestManagerModuleFactory();\n    ~HTTPRequestManagerModuleFactory() override;\n\n    StringBox getModulePath() override;\n    Value loadModule() override;\n};\n\n} // namespace Valdi\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/_configs/BUILD.bazel",
    "content": "load(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_config\")\n\nts_config(\n    name = \"base\",\n    src = \"base.tsconfig.json\",\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/_configs/base.tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"experimentalDecorators\": true,\n    \"composite\": true,\n    \"target\": \"ES2016\",\n    \"module\": \"commonjs\",\n    \"baseUrl\": \"..\",\n    \"paths\": {\n      \"Valdi\": [\n        \"./valdi_core/src/Valdi\",\n        \"../src/valdi_modules/src/valdi/valdi_core/src/Valdi\"\n      ],\n      \"tslib\": [\n        \"./valdi_core/src/tslib.d.ts\",\n        \"../src/valdi_modules/src/valdi/valdi_core/src/tslib.d.ts\"\n      ],\n      \"jasmine\": [\n        \"./jasmine/src/jasmine.d.ts\",\n        \"../src/valdi_modules/src/valdi/jasmine/src/jasmine.d.ts\"\n      ],\n      \"*\": [\n        \"*\",\n        \"../src/valdi_modules/src/valdi/*\",\n        \"../../.valdi_build/hotreload/generated_ts/*\",\n        \"../../.valdi_build/compile/generated_ts/*\"\n      ]\n    },\n    \"lib\": [\"dom\", \"ES2019\"],\n    \"noImplicitReturns\": true,\n    \"noImplicitAny\": true,\n    \"importHelpers\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"jsx\": \"preserve\",\n    \"rootDirs\": [\n      \"..\",\n      \"../../../.valdi_build/hotreload/generated_ts\",\n      \"../../../.valdi_build/compile/generated_ts\"\n    ],\n    \"types\": [\"../types/Long\", \"../types/globals\"],\n    \"typeRoots\": [\".\"]\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/_configs/eslint.tsconfig.json",
    "content": "{\n  \"extends\": \"./base.tsconfig.json\",\n  \"include\": [\"../**/*.ts\", \"../**/*.tsx\"]\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nvaldi_module(\n    name = \"bridge_observables\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_language = [\n        \"objc\",\n        \"swift\",\n    ],\n    ios_module_name = \"SCCBridgeObservables\",\n    ios_output_target = \"release\",\n    module_yaml = \"module.yaml\",\n    single_file_codegen = False,\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/valdi_rxjs\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/README.md",
    "content": "# Bridge Observables\n\nProvide bridging types and conversion functions for observable types.\n\n# Example\n\n**Cheat sheet:**\nhttps://drive.google.com/file/d/1es4pbaHdJE8uGfMxi1sgSd8lfyjz5eUF/view?usp=sharing\n\n**Declaration:**\n```ts\nexport interface MyFeatureContext {\n    myDataStream?: BridgeObservable<string>\n}\n```\n\n**Valdi / Usage:**\n```ts\nconst bridgeObservable = context.myDataStream ?? [...];\nconst rxObservable = convertBridgeObservableToObservable(bridgeObservable);\nrxObservable.subscribe() // as usual\n```\n\n**Android / Kotlin:**\n```kotlin\nval context = MyFeatureContext();\ncontext.myDataStream = Observable.just(\"hello world!\").toBridgeObservable();\n```\n\n**iOS / Obj-C:**\n```obj-c\nMyFeatureContext *context = [MyFeatureContext new];\ncontext.myDataStream = [[SCObservable just:@\"hello world!\"] toBridgeObservable];\n```\n\n# iOS\n\n### iOS -> Valdi (RxJS):\n\n**Available conversions:**\n\nTODO: consider moving iOS implementation into open source\n\n### Valdi (RxJS) -> iOS:\n\n**Available conversions:**\n\nTODO: consider moving iOS implementatino into open source\n\n# Android\n\n### Android (RxJava) -> Valdi (RxJS):\n\n**Available conversions:**\n\nObservable(RxJava) -> toBridgeObservable -> BridgeObservable -> convertBridgeObservableToObservable -> Observable(RxJS)\nObserver(RxJava) -> toBridgeObserver -> BridgeObserver -> convertBridgeObserverToObserver -> Observer(RxJS)\n\nSubject(RxJava) -> toBridgeSubject -> BridgeSubject -> convertBridgeSubjectToObservable -> Observable(RxJS)\nSubject(RxJava) -> toBridgeSubject -> BridgeSubject -> convertBridgeSubjectToObserver -> Observer(RxJS)\n\n### Valdi (RxJS) -> Android (RxJava):\n\n**Available conversions:**\n\nObservable(RxJs) -> convertObservableToBridgeObservable -> BridgeObservable -> toObservable -> Observable(RxJava)\nObserver(RxJs) -> convertObserverToBridgeObserver -> BridgeObserver -> toObserver -> Observer(RxJava)\n\nSubject(RxJs) -> convertSubjectToBridgeSubject -> BridgeSubject -> toObservable -> Observable(RxJava)\nSubject(RxJs) -> convertSubjectToBridgeSubject -> BridgeSubject -> toObserver -> Observer(RxJava)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/module.yaml",
    "content": "ios:\n  language: objc, swift\n\noutput_target: release\n\ndependencies:\n  - valdi_core\n  - valdi_rxjs\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/types/BridgeError.d.ts",
    "content": "/**\n * @ExportModel({\n *  ios: 'SCBridgeError',\n *  swift: 'BridgeError',\n *  android: 'com.snap.valdi.bridge_observables.BridgeError'\n * })\n */\nexport interface BridgeError {\n  message: string;\n  stack?: string;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/types/BridgeObservable.ts",
    "content": "import { BridgeError } from './BridgeError';\nimport { BridgeObserverEvent } from './BridgeObserverEvent';\n\n/**\n * @ExportModel({\n *  ios: 'SCBridgeObservable',\n *  swift: 'BridgeObservable',\n *  android: 'com.snap.valdi.bridge_observables.BridgeObservable'\n * })\n */\nexport interface BridgeObservable<T> {\n  subscribe: (\n    onEvent: (\n      type: BridgeObserverEvent,\n      subscription: (() => void) | undefined,\n      value: T | undefined,\n      error: BridgeError | undefined,\n    ) => void,\n  ) => void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/types/BridgeObserver.d.ts",
    "content": "import { BridgeError } from './BridgeError';\nimport { BridgeObserverEvent } from './BridgeObserverEvent';\n\n/**\n * @ExportModel({\n *  ios: 'SCBridgeObserver',\n *  swift: 'BridgeObserver',\n *  android: 'com.snap.valdi.bridge_observables.BridgeObserver'\n * })\n */\nexport interface BridgeObserver<T> {\n  // @WorkerThread\n  onEvent: (\n    type: BridgeObserverEvent,\n    subscription: (() => void) | undefined,\n    value: T | undefined,\n    error: BridgeError | undefined,\n  ) => void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/types/BridgeObserverEvent.d.ts",
    "content": "/**\n * @ExportEnum({\n *  ios: 'SCBridgeObserverEvent',\n *  swift: 'BridgeObserverEvent',\n *  android: 'com.snap.valdi.bridge_observables.BridgeObserverEvent'\n * })\n */\nexport const enum BridgeObserverEvent {\n  RECEIVE_SUBSCRIPTION,\n  NEXT,\n  ERROR,\n  COMPLETE,\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/types/BridgeSubject.d.ts",
    "content": "import { BridgeError } from './BridgeError';\nimport { BridgeObserverEvent } from './BridgeObserverEvent';\n\n/**\n * @ExportModel({\n *  ios: 'SCBridgeSubject',\n *  swift: 'BridgeSubject',\n *  android: 'com.snap.valdi.bridge_observables.BridgeSubject'\n * })\n */\nexport interface BridgeSubject<T> {\n  onEvent: (\n    type: BridgeObserverEvent,\n    subscription: (() => void) | undefined,\n    value: T | undefined,\n    error: BridgeError | undefined,\n  ) => void;\n\n  subscribe: (\n    onEvent: (\n      type: BridgeObserverEvent,\n      subscription: (() => void) | undefined,\n      value: T | undefined,\n      error: BridgeError | undefined,\n    ) => void,\n  ) => void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/convertBridgeObservableToObservable.ts",
    "content": "import { Observable } from 'valdi_rxjs/src/Observable';\nimport { Subscriber } from 'valdi_rxjs/src/Subscriber';\nimport { BridgeObservable } from '../types/BridgeObservable';\nimport { BridgeObserverEvent } from '../types/BridgeObserverEvent';\n\nexport function convertBridgeObservableToObservable<T>(observable: BridgeObservable<T>): Observable<T> {\n  return new Observable<T>((subscriber: Subscriber<T>) => {\n    let storedSubscription: (() => void) | undefined;\n    let disposed = false;\n\n    observable.subscribe((type, subscription, value, error) => {\n      switch (type) {\n        case BridgeObserverEvent.RECEIVE_SUBSCRIPTION:\n          if (disposed) {\n            subscription?.();\n          } else {\n            storedSubscription = subscription;\n          }\n          break;\n        case BridgeObserverEvent.NEXT:\n          subscriber.next(value);\n          break;\n        case BridgeObserverEvent.ERROR:\n          const jsErr = new Error(error?.message)\n          jsErr.stack = error?.stack;\n          subscriber.error(jsErr);\n          break;\n        case BridgeObserverEvent.COMPLETE:\n          subscriber.complete();\n          break;\n      }\n    });\n\n    return () => {\n      disposed = true;\n      storedSubscription?.();\n      storedSubscription = undefined;\n    };\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/convertBridgeObserverToObserver.ts",
    "content": "import { Observer } from 'valdi_rxjs/src/types';\nimport { BridgeObserver } from '../types/BridgeObserver';\nimport { BridgeObserverEvent } from '../types/BridgeObserverEvent';\n\nexport function convertBridgeObserverToObserver<T>(observer: BridgeObserver<T>): Observer<T> {\n  return {\n    next: value => {\n      observer.onEvent(BridgeObserverEvent.NEXT, undefined, value, undefined);\n    },\n    error: err => {\n      observer.onEvent(BridgeObserverEvent.ERROR, undefined, undefined, err);\n    },\n    complete: () => {\n      observer.onEvent(BridgeObserverEvent.COMPLETE, undefined, undefined, undefined);\n    },\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/convertBridgeSubjectToObservable.ts",
    "content": "import { Observable } from 'valdi_rxjs/src/Observable';\nimport { BridgeSubject } from '../types/BridgeSubject';\nimport { convertBridgeObservableToObservable } from './convertBridgeObservableToObservable';\n\nexport function convertBridgeSubjectToObservable<T>(subject: BridgeSubject<T>): Observable<T> {\n  return convertBridgeObservableToObservable(subject);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/convertBridgeSubjectToObserver.ts",
    "content": "import { Observer } from 'valdi_rxjs/src/types';\nimport { BridgeSubject } from '../types/BridgeSubject';\nimport { convertBridgeObserverToObserver } from './convertBridgeObserverToObserver';\n\nexport function convertBridgeSubjectToObserver<T>(subject: BridgeSubject<T>): Observer<T> {\n  return convertBridgeObserverToObserver(subject);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/convertBridgeSubjectToSubject.ts",
    "content": "import { AnonymousSubject, Subject } from 'valdi_rxjs/src/Subject';\nimport { BridgeSubject } from '../types/BridgeSubject';\nimport { convertBridgeObservableToObservable } from './convertBridgeObservableToObservable';\nimport { convertBridgeSubjectToObserver } from './convertBridgeSubjectToObserver';\n\nexport function convertBridgeSubjectToSubject<T>(subject: BridgeSubject<T>): Subject<T> {\n  return new AnonymousSubject<T>(convertBridgeSubjectToObserver(subject), convertBridgeObservableToObservable(subject));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/convertObservableToBridgeObservable.ts",
    "content": "import { Observable } from 'valdi_rxjs/src/Observable';\nimport { BridgeError } from '../types/BridgeError';\nimport { BridgeObservable } from '../types/BridgeObservable';\nimport { BridgeObserverEvent } from '../types/BridgeObserverEvent';\n\nexport function createBridgeSubscribeFn<T>(\n  observable: Observable<T>,\n): (\n  onEvent: (\n    type: BridgeObserverEvent,\n    subscription: (() => void) | undefined,\n    value: T | undefined,\n    error: BridgeError | undefined,\n  ) => void,\n) => void {\n  return (\n    onEvent: (\n      type: BridgeObserverEvent,\n      subscription: (() => void) | undefined,\n      value: T | undefined,\n      error: BridgeError | undefined,\n    ) => void,\n  ) => {\n    const subscription = observable.subscribe(\n      (value: T) => {\n        onEvent(BridgeObserverEvent.NEXT, undefined, value, undefined);\n      },\n      (error: BridgeError) => {\n        onEvent(BridgeObserverEvent.ERROR, undefined, undefined, error);\n      },\n      () => {\n        onEvent(BridgeObserverEvent.COMPLETE, undefined, undefined, undefined);\n      },\n    );\n\n    onEvent(BridgeObserverEvent.RECEIVE_SUBSCRIPTION, () => subscription.unsubscribe(), undefined, undefined);\n  };\n}\n\nexport function convertObservableToBridgeObservable<T>(observable: Observable<T>): BridgeObservable<T> {\n  return {\n    subscribe: createBridgeSubscribeFn(observable),\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/convertObserverToBridgeObserver.ts",
    "content": "import { Observer } from 'valdi_rxjs/src/types';\nimport { BridgeError } from '../types/BridgeError';\nimport { BridgeObserver } from '../types/BridgeObserver';\nimport { BridgeObserverEvent } from '../types/BridgeObserverEvent';\n\nexport function createBridgeOnEventFn<T>(\n  observer: Observer<T>,\n): (\n  type: BridgeObserverEvent,\n  subscription: (() => void) | undefined,\n  value: T | undefined,\n  error: BridgeError | undefined,\n) => void {\n  return (type, subscription, value, error) => {\n    switch (type) {\n      case BridgeObserverEvent.RECEIVE_SUBSCRIPTION:\n        // nothing to do\n        break;\n      case BridgeObserverEvent.NEXT:\n        observer.next(value!);\n        break;\n      case BridgeObserverEvent.ERROR:\n        observer.error(error);\n        break;\n      case BridgeObserverEvent.COMPLETE:\n        observer.complete();\n        break;\n    }\n  };\n}\n\nexport function convertObserverToBridgeObserver<T>(observer: Observer<T>): BridgeObserver<T> {\n  return {\n    onEvent: createBridgeOnEventFn(observer),\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/convertSubjectToBridgeSubject.ts",
    "content": "import { Subject } from 'valdi_rxjs/src/Subject';\nimport { BridgeSubject } from '../types/BridgeSubject';\nimport { createBridgeSubscribeFn } from './convertObservableToBridgeObservable';\nimport { createBridgeOnEventFn } from './convertObserverToBridgeObserver';\n\nexport function convertSubjectToBridgeSubject<T>(subject: Subject<T>): BridgeSubject<T> {\n  return {\n    onEvent: createBridgeOnEventFn(subject),\n    subscribe: createBridgeSubscribeFn(subject),\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/converter.ts",
    "content": "import { TypeConverter } from 'valdi_core/src/TypeConverter';\nimport { Observable } from 'valdi_rxjs/src/Observable';\nimport { Subject } from 'valdi_rxjs/src/Subject';\nimport { BridgeObservable } from '../types/BridgeObservable';\nimport { BridgeSubject } from '../types/BridgeSubject';\nimport { convertBridgeObservableToObservable } from './convertBridgeObservableToObservable';\nimport { convertBridgeSubjectToSubject } from './convertBridgeSubjectToSubject';\nimport { convertObservableToBridgeObservable } from './convertObservableToBridgeObservable';\nimport { convertSubjectToBridgeSubject } from './convertSubjectToBridgeSubject';\n\n// @NativeTypeConverter\nexport function makeTypeConverter<T>(): TypeConverter<Observable<T>, BridgeObservable<T>> {\n  return {\n    toIntermediate: convertObservableToBridgeObservable,\n    toTypeScript: convertBridgeObservableToObservable,\n  };\n}\n\n// @NativeTypeConverter\nexport function makeSubjectTypeConverter<T>(): TypeConverter<Subject<T>, BridgeSubject<T>> {\n  return {\n    toIntermediate: convertSubjectToBridgeSubject,\n    toTypeScript: convertBridgeSubjectToSubject,\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/optional/convertOptionalBridgeObservableToObservable.ts",
    "content": "import { Observable } from 'valdi_rxjs/src/Observable';\nimport { EMPTY } from 'valdi_rxjs/src/observable/empty';\nimport { BridgeObservable } from '../../types/BridgeObservable';\nimport { convertBridgeObservableToObservable } from '../convertBridgeObservableToObservable';\n\nexport function convertOptionalBridgeObservableToObservable<T>(\n  observable?: BridgeObservable<T>,\n  fallback?: Observable<T>,\n): Observable<T> {\n  if (!observable) {\n    return fallback ?? EMPTY;\n  }\n  return convertBridgeObservableToObservable(observable);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/src/utils/optional/convertOptionalBridgeSubjectToObservable.ts",
    "content": "import { Observable } from 'valdi_rxjs/src/Observable';\nimport { BridgeSubject } from '../../types/BridgeSubject';\nimport { convertOptionalBridgeObservableToObservable } from './convertOptionalBridgeObservableToObservable';\n\nexport function convertOptionalBridgeSubjectToObservable<T>(\n  subject?: BridgeSubject<T>,\n  fallback?: Observable<T>,\n): Observable<T> {\n  return convertOptionalBridgeObservableToObservable(subject, fallback);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/bridge_observables/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\",\n    \"compilerOptions\": {\n        \"noImplicitReturns\": true,\n        \"noImplicitAny\": true,\n        \"strict\": true,\n    }\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/BUILD.bazel",
    "content": "load(\"@aspect_bazel_lib//lib:copy_to_bin.bzl\", \"copy_to_bin\")\nload(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\ncopy_to_bin(\n    name = \"coreutils_dts\",\n    srcs = glob([\n        \"src/**/*.d.ts\",\n    ]),\n    visibility = [\"//visibility:public\"],\n)\n\nts_project(\n    name = \"coreutils_web\",\n    srcs = glob([\n        \"web/**/*.ts\",\n        \"src/**/*.d.ts\",\n    ]),\n    allow_js = True,\n    composite = True,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n)\n\nvaldi_module(\n    name = \"coreutils\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCCoreutils\",\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":coreutils_web\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/jasmine\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/README.md",
    "content": "# coreutils\n\nUtility modules extracted from valdi_core to make available for modules that valdi_core needs to depend on.\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/module.yaml",
    "content": "output_target: release\n\nallowed_debug_dependencies:\n  - jasmine\n\nexclude_patterns:\n  - .*\\/web\\/.*\nexclude_globs:\n  - \"**/web/**\"\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/ArrayUtils.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { Range } from './Range';\n\n/**\n * Check whether two arrays contains the same items. *\n */\nexport function arrayEquals<T>(left: T[], right: T[]): boolean {\n  const length = left.length;\n  if (length !== right.length) {\n    return false;\n  }\n\n  for (let i = 0; i < length; i++) {\n    if (left[i] !== right[i]) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n/**\n * Like Array.map() but lazy. It will allocate a new array\n * only when the visitor function returns a different item.\n * @param array\n * @param visitor\n */\nexport function lazyMap<T>(array: T[] | undefined, visitor: (item: T) => T): T[] {\n  if (!array) {\n    return [];\n  }\n\n  let outputArray = array;\n\n  let index = 0;\n  for (const item of array) {\n    const newItem = visitor(item);\n\n    if (newItem !== item) {\n      if (outputArray === array) {\n        outputArray = array.slice(0, array.length);\n      }\n\n      outputArray[index] = newItem;\n    }\n\n    index++;\n  }\n\n  return outputArray;\n}\n\n/**\n * Search an exact match item in a sorted array.\n *\n * the compareFn should return >0 to indicate that the given item is \"higher\"\n * than the searched index, <0 to indicate that the given item is \"lower\",\n * 0 to indicate a perfect match.\n */\nconst binarySearchRangeResult: Range = { min: 0, max: 0 };\nexport function binarySearch<T>(array: T[], compareFn: (item: T) => number): number {\n  const range = binarySearchRange(array, compareFn, binarySearchRangeResult);\n  if (range.min === range.max) {\n    return range.min;\n  }\n  return -1;\n}\n\n/**\n * Search the range that would be a suitable match within an array\n *\n * the compareFn should return >0 to indicate that the given item is \"higher\"\n * than the searched index, <0 to indicate that the given item is \"lower\",\n * 0 to indicate a perfect match.\n */\nexport function binarySearchRange<T>(array: T[], compareFn: (item: T) => number, result?: Range): Range {\n  let start = 0;\n  let end = array.length - 1;\n\n  // Iterate while start not meets end\n  while (start <= end) {\n    // Find the mid index\n    const mid = Math.floor((start + end) / 2);\n\n    const diff = compareFn(array[mid]);\n    if (diff === 0) {\n      return {\n        min: mid,\n        max: mid,\n      };\n    } else if (diff > 0) {\n      end = mid - 1;\n    } else {\n      start = mid + 1;\n    }\n  }\n\n  const min = Math.min(start, end);\n  const max = Math.max(start, end);\n  if (result) {\n    result.min = min;\n    result.max = max;\n    return result;\n  } else {\n    return {\n      min: min,\n      max: max,\n    };\n  }\n}\n\n/**\n * Given an array, group the items by the given keySelector into a map.\n */\nexport function groupBy<T>(array: T[], keySelector: (item: T) => string): StringMap<T[]> {\n  const output: StringMap<T[]> = {};\n\n  for (const item of array) {\n    const key = keySelector(item);\n    let itemsForKey = output[key];\n    if (!itemsForKey) {\n      itemsForKey = [];\n      output[key] = itemsForKey;\n    }\n    itemsForKey.push(item);\n  }\n\n  return output;\n}\n\n/**\n * Remove an item from the given array.\n * Return whether the item was succesfully removed.\n */\nexport function remove<T>(array: T[], item: T): boolean {\n  const index = array.indexOf(item);\n  if (index < 0) {\n    return false;\n  }\n  array.splice(index, 1);\n  return true;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/Base64.ts",
    "content": "/**\n * Ported from https://github.com/beatgammit/base64-js/blob/master/index.js\n */\n\nconst lookup: string[] = [];\nconst revLookup: { [key: string]: number } = {};\n\nconst code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nfor (let i = 0, len = code.length; i < len; ++i) {\n  lookup[i] = code[i];\n  revLookup[code.charCodeAt(i)] = i;\n}\n\n// Support decoding URL-safe base64 strings, as Node.js does.\n// See: https://en.wikipedia.org/wiki/Base64#URL_applications\nrevLookup['-'.charCodeAt(0)] = 62;\nrevLookup['_'.charCodeAt(0)] = 63;\n\nfunction getLens(b64: string): [number, number] {\n  const len = b64.length;\n\n  if (len % 4 > 0) {\n    throw new Error('Invalid string. Length must be a multiple of 4');\n  }\n\n  // Trim off extra bytes after placeholder bytes are found\n  // See: https://github.com/beatgammit/base64-js/issues/42\n  let validLen = b64.indexOf('=');\n  if (validLen === -1) validLen = len;\n\n  const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4);\n\n  return [validLen, placeHoldersLen];\n}\n\nfunction _byteLength(b64: string, validLen: number, placeHoldersLen: number): number {\n  return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;\n}\n\nfunction tripletToBase64(num: number): string {\n  return lookup[(num >> 18) & 0x3f] + lookup[(num >> 12) & 0x3f] + lookup[(num >> 6) & 0x3f] + lookup[num & 0x3f];\n}\n\nfunction encodeChunk(uint8: Uint8Array, start: number, end: number): string {\n  let tmp: number;\n  const output: string[] = [];\n  for (let i = start; i < end; i += 3) {\n    tmp = ((uint8[i] << 16) & 0xff0000) + ((uint8[i + 1] << 8) & 0xff00) + (uint8[i + 2] & 0xff);\n    output.push(tripletToBase64(tmp));\n  }\n  return output.join('');\n}\n\nexport namespace Base64 {\n  interface Base64Options {\n    urlSafe?: boolean;\n  }\n\n  export function fromByteArray(uint8: Uint8Array, { urlSafe }: Base64Options = {}): string {\n    let tmp: number;\n    const len = uint8.length;\n    const extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes\n    const parts: string[] = [];\n    const maxChunkLength = 16383; // must be multiple of 3\n\n    // go through the array every three bytes, we'll deal with trailing stuff later\n    for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n      parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength));\n    }\n\n    // pad the end with zeros, but make sure to not forget the extra bytes\n    if (extraBytes === 1) {\n      tmp = uint8[len - 1];\n      parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==');\n    } else if (extraBytes === 2) {\n      tmp = (uint8[len - 2] << 8) + uint8[len - 1];\n      parts.push(lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3f] + lookup[(tmp << 2) & 0x3f] + '=');\n    }\n\n    const base64String = parts.join('');\n\n    if (urlSafe) {\n      // Convert to URL-safe base64\n      return base64String.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n    } else {\n      return base64String;\n    }\n  }\n\n  export function toByteArray(b64: string): Uint8Array {\n    let tmp = 0;\n\n    // Add padding to make length multiple of 4, if necessary\n    const originalLen = b64.length;\n    if (originalLen % 4 > 0) {\n      const paddingCount = 4 - (originalLen % 4);\n      b64 += '='.repeat(paddingCount);\n    }\n\n    const lens = getLens(b64);\n    const validLen = lens[0];\n    const placeHoldersLen = lens[1];\n\n    const arr = new Uint8Array(_byteLength(b64, validLen, placeHoldersLen));\n\n    let curByte = 0;\n\n    // if there are placeholders, only get up to the last complete 4 chars\n    const len = placeHoldersLen > 0 ? validLen - 4 : validLen;\n\n    let i = 0;\n    for (i = 0; i < len; i += 4) {\n      tmp =\n        (revLookup[b64.charCodeAt(i)] << 18) |\n        (revLookup[b64.charCodeAt(i + 1)] << 12) |\n        (revLookup[b64.charCodeAt(i + 2)] << 6) |\n        revLookup[b64.charCodeAt(i + 3)];\n      arr[curByte++] = (tmp >> 16) & 0xff;\n      arr[curByte++] = (tmp >> 8) & 0xff;\n      arr[curByte++] = tmp & 0xff;\n    }\n\n    if (placeHoldersLen === 2) {\n      tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4);\n      arr[curByte++] = tmp & 0xff;\n    }\n\n    if (placeHoldersLen === 1) {\n      tmp =\n        (revLookup[b64.charCodeAt(i)] << 10) |\n        (revLookup[b64.charCodeAt(i + 1)] << 4) |\n        (revLookup[b64.charCodeAt(i + 2)] >> 2);\n      arr[curByte++] = (tmp >> 8) & 0xff;\n      arr[curByte++] = tmp & 0xff;\n    }\n\n    return arr;\n  }\n\n  // base64 is 4/3 + up to two characters of the original data\n  export function byteLength(b64: string): number {\n    const lens = getLens(b64);\n    const validLen = lens[0];\n    const placeHoldersLen = lens[1];\n    return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/LRUCache.ts",
    "content": "interface LRUCacheEntry<T> {\n  key: string;\n  item: T;\n  previous: LRUCacheEntry<T> | undefined;\n  next: LRUCacheEntry<T> | undefined;\n}\n\nfunction checkMaxSize(maxSize: number) {\n  if (maxSize < 0) {\n    throw new Error(`Invalid maxSize ${maxSize}`);\n  }\n}\n\nexport interface LRUCacheListener<T> {\n  onItemEvicted(key: string, item: T): void;\n}\n\n/**\n * A simple LRU cache that holds up to N items and will\n * evict the least recently used ones.\n */\nexport class LRUCache<T> {\n  listener?: LRUCacheListener<T>;\n\n  get size(): number {\n    return this.entryById.size;\n  }\n\n  private entryById = new Map<string, LRUCacheEntry<T>>();\n  private maxSize: number;\n  private head?: LRUCacheEntry<T>;\n  private tail?: LRUCacheEntry<T>;\n\n  constructor(maxSize: number) {\n    checkMaxSize(maxSize);\n    this.maxSize = maxSize;\n  }\n\n  /**\n   * Set the maximum number of items that the LRU cache can hold.\n   */\n  setMaxSize(maxSize: number) {\n    checkMaxSize(maxSize);\n\n    if (this.maxSize !== maxSize) {\n      this.maxSize = maxSize;\n      this.trimToMaxSize(maxSize);\n    }\n  }\n\n  /**\n   * Return the item for the given key.\n   */\n  get(key: string): T | undefined {\n    const entry = this.entryById.get(key);\n    if (!entry) {\n      return undefined;\n    }\n\n    this.removeEntryFromList(entry);\n    this.pushEntryInList(entry);\n\n    return entry.item;\n  }\n\n  /**\n   * Insert an item with the given key.\n   */\n  insert(key: string, item: T): void {\n    let shouldTrim = false;\n    let entry = this.entryById.get(key);\n    if (!entry) {\n      entry = {\n        key,\n        item,\n        previous: undefined,\n        next: undefined,\n      };\n      this.entryById.set(key, entry);\n      shouldTrim = this.entryById.size > this.maxSize;\n\n      this.pushEntryInList(entry);\n    } else {\n      entry.item = item;\n\n      this.removeEntryFromList(entry);\n      this.pushEntryInList(entry);\n    }\n\n    if (shouldTrim) {\n      this.trimToMaxSize(this.maxSize);\n    }\n  }\n\n  /**\n   * Returns whether the cache holds an item for the given key\n   * @param key\n   * @returns\n   */\n  has(key: string): boolean {\n    return this.entryById.has(key);\n  }\n\n  /**\n   * Remove the item with the given key. Return true if the item was found\n   * and removed, or false otherwise.\n   */\n  remove(key: string): boolean {\n    const entry = this.entryById.get(key);\n    if (!entry) {\n      return false;\n    }\n\n    this.removeEntry(entry);\n    return true;\n  }\n\n  /**\n   * Remove all of the items within the cache.\n   */\n  clear(): void {\n    this.trimToMaxSize(0);\n  }\n\n  /**\n   * Returns all the items that the LRUCache holds.\n   */\n  all(): T[] {\n    const output: T[] = [];\n    let current = this.head;\n\n    while (current) {\n      output.push(current.item);\n      current = current.next;\n    }\n\n    return output;\n  }\n\n  private trimToMaxSize(maxSize: number) {\n    while (this.entryById.size > maxSize) {\n      const tail = this.tail!;\n      this.removeEntry(tail);\n    }\n  }\n\n  private removeEntry(entry: LRUCacheEntry<T>) {\n    this.entryById.delete(entry.key);\n    this.removeEntryFromList(entry);\n\n    if (this.listener) {\n      this.listener.onItemEvicted(entry.key, entry.item);\n    }\n  }\n\n  private removeEntryFromList(entry: LRUCacheEntry<T>) {\n    const previous = entry.previous;\n    const next = entry.next;\n\n    if (previous) {\n      previous.next = next;\n    }\n    if (next) {\n      next.previous = previous;\n    }\n\n    if (this.head === entry) {\n      this.head = next;\n    }\n\n    if (this.tail === entry) {\n      this.tail = previous;\n    }\n\n    entry.previous = undefined;\n    entry.next = undefined;\n  }\n\n  private pushEntryInList(entry: LRUCacheEntry<T>) {\n    const next = this.head;\n\n    if (next) {\n      next.previous = entry;\n    }\n\n    entry.next = next;\n\n    this.head = entry;\n\n    if (!this.tail) {\n      this.tail = entry;\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/Range.ts",
    "content": "export interface Range {\n  min: number;\n  max: number;\n}\n\n// @ExportModel({ios: 'SCCCoreUtilsMediaTimeRange', android: 'com.snap.valdi.coreutils.MediaTimeRange'})\nexport interface MediaTimeRange {\n  startMs: number;\n  durationMs: number;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/RuntimeBase.d.ts",
    "content": "export interface RuntimeBase {\n  bytesToString(bytes: Uint8Array | ArrayBuffer): string;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/SerialTaskQueue.ts",
    "content": "export type Task = (done: () => void) => void;\n\nexport class SerialTaskQueue {\n  private ready: boolean = true;\n  private pendingTasks: Task[] = [];\n\n  enqueueTask(operation: Task) {\n    this.pendingTasks.push(operation);\n    this.flushTasks();\n  }\n\n  private flushTasks() {\n    if (this.ready && this.pendingTasks.length) {\n      const operation = this.pendingTasks.shift()!;\n      this.ready = false;\n      operation(() => {\n        this.ready = true;\n        this.flushTasks();\n      });\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/StringMap.d.ts",
    "content": "// Deprecated: Use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map\n\n/**\n * @NativeClass({\n *   marshallAsUntypedMap: true\n * })\n */\nexport interface StringMap<T> {\n  [key: string]: T | undefined;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/StringSet.d.ts",
    "content": "import { StringMap } from './StringMap';\n\n// Deprecated: Use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set\nexport type StringSet = StringMap<boolean | undefined>;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/Uint8ArrayUtils.ts",
    "content": "import { RuntimeBase } from './RuntimeBase';\n\ndeclare const runtime: RuntimeBase;\n\nexport function arrayToString(buf: Uint8Array): string {\n  if (runtime.bytesToString) {\n    return runtime.bytesToString(buf);\n  }\n\n  return String.fromCharCode.apply(null, buf as any);\n}\n\nexport function stringToArray(str: string): Uint8Array {\n  const buf = new ArrayBuffer(str.length);\n  const bufView = new Uint8Array(buf);\n  for (let i = 0, strLen = str.length; i < strLen; i++) {\n    bufView[i] = str.charCodeAt(i);\n  }\n  return bufView;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/dummy.ts",
    "content": ""
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/md5.ts",
    "content": "export namespace md5 {\n  export function hash(s: string): string {\n    return hex(md51(s));\n  }\n}\n\n/* Ported from http://www.myersdaily.org/joseph/javascript/md5-text.html */\nfunction md5cycle(x: any, k: any) {\n  let a = x[0],\n    b = x[1],\n    c = x[2],\n    d = x[3];\n\n  a = ff(a, b, c, d, k[0], 7, -680876936);\n  d = ff(d, a, b, c, k[1], 12, -389564586);\n  c = ff(c, d, a, b, k[2], 17, 606105819);\n  b = ff(b, c, d, a, k[3], 22, -1044525330);\n  a = ff(a, b, c, d, k[4], 7, -176418897);\n  d = ff(d, a, b, c, k[5], 12, 1200080426);\n  c = ff(c, d, a, b, k[6], 17, -1473231341);\n  b = ff(b, c, d, a, k[7], 22, -45705983);\n  a = ff(a, b, c, d, k[8], 7, 1770035416);\n  d = ff(d, a, b, c, k[9], 12, -1958414417);\n  c = ff(c, d, a, b, k[10], 17, -42063);\n  b = ff(b, c, d, a, k[11], 22, -1990404162);\n  a = ff(a, b, c, d, k[12], 7, 1804603682);\n  d = ff(d, a, b, c, k[13], 12, -40341101);\n  c = ff(c, d, a, b, k[14], 17, -1502002290);\n  b = ff(b, c, d, a, k[15], 22, 1236535329);\n\n  a = gg(a, b, c, d, k[1], 5, -165796510);\n  d = gg(d, a, b, c, k[6], 9, -1069501632);\n  c = gg(c, d, a, b, k[11], 14, 643717713);\n  b = gg(b, c, d, a, k[0], 20, -373897302);\n  a = gg(a, b, c, d, k[5], 5, -701558691);\n  d = gg(d, a, b, c, k[10], 9, 38016083);\n  c = gg(c, d, a, b, k[15], 14, -660478335);\n  b = gg(b, c, d, a, k[4], 20, -405537848);\n  a = gg(a, b, c, d, k[9], 5, 568446438);\n  d = gg(d, a, b, c, k[14], 9, -1019803690);\n  c = gg(c, d, a, b, k[3], 14, -187363961);\n  b = gg(b, c, d, a, k[8], 20, 1163531501);\n  a = gg(a, b, c, d, k[13], 5, -1444681467);\n  d = gg(d, a, b, c, k[2], 9, -51403784);\n  c = gg(c, d, a, b, k[7], 14, 1735328473);\n  b = gg(b, c, d, a, k[12], 20, -1926607734);\n\n  a = hh(a, b, c, d, k[5], 4, -378558);\n  d = hh(d, a, b, c, k[8], 11, -2022574463);\n  c = hh(c, d, a, b, k[11], 16, 1839030562);\n  b = hh(b, c, d, a, k[14], 23, -35309556);\n  a = hh(a, b, c, d, k[1], 4, -1530992060);\n  d = hh(d, a, b, c, k[4], 11, 1272893353);\n  c = hh(c, d, a, b, k[7], 16, -155497632);\n  b = hh(b, c, d, a, k[10], 23, -1094730640);\n  a = hh(a, b, c, d, k[13], 4, 681279174);\n  d = hh(d, a, b, c, k[0], 11, -358537222);\n  c = hh(c, d, a, b, k[3], 16, -722521979);\n  b = hh(b, c, d, a, k[6], 23, 76029189);\n  a = hh(a, b, c, d, k[9], 4, -640364487);\n  d = hh(d, a, b, c, k[12], 11, -421815835);\n  c = hh(c, d, a, b, k[15], 16, 530742520);\n  b = hh(b, c, d, a, k[2], 23, -995338651);\n\n  a = ii(a, b, c, d, k[0], 6, -198630844);\n  d = ii(d, a, b, c, k[7], 10, 1126891415);\n  c = ii(c, d, a, b, k[14], 15, -1416354905);\n  b = ii(b, c, d, a, k[5], 21, -57434055);\n  a = ii(a, b, c, d, k[12], 6, 1700485571);\n  d = ii(d, a, b, c, k[3], 10, -1894986606);\n  c = ii(c, d, a, b, k[10], 15, -1051523);\n  b = ii(b, c, d, a, k[1], 21, -2054922799);\n  a = ii(a, b, c, d, k[8], 6, 1873313359);\n  d = ii(d, a, b, c, k[15], 10, -30611744);\n  c = ii(c, d, a, b, k[6], 15, -1560198380);\n  b = ii(b, c, d, a, k[13], 21, 1309151649);\n  a = ii(a, b, c, d, k[4], 6, -145523070);\n  d = ii(d, a, b, c, k[11], 10, -1120210379);\n  c = ii(c, d, a, b, k[2], 15, 718787259);\n  b = ii(b, c, d, a, k[9], 21, -343485551);\n\n  x[0] = add32(a, x[0]);\n  x[1] = add32(b, x[1]);\n  x[2] = add32(c, x[2]);\n  x[3] = add32(d, x[3]);\n}\n\nfunction cmn(q: number, a: number, b: any, x: any, s: number, t: any) {\n  a = add32(add32(a, q), add32(x, t));\n  return add32((a << s) | (a >>> (32 - s)), b);\n}\n\nfunction ff(a: any, b: number, c: number, d: number, x: any, s: number, t: number) {\n  return cmn((b & c) | (~b & d), a, b, x, s, t);\n}\n\nfunction gg(a: any, b: number, c: number, d: number, x: any, s: number, t: number) {\n  return cmn((b & d) | (c & ~d), a, b, x, s, t);\n}\n\nfunction hh(a: any, b: number, c: number, d: number, x: any, s: number, t: number) {\n  return cmn(b ^ c ^ d, a, b, x, s, t);\n}\n\nfunction ii(a: any, b: number, c: number, d: number, x: any, s: number, t: number) {\n  return cmn(c ^ (b | ~d), a, b, x, s, t);\n}\n\nfunction md51(s: string) {\n  const n = s.length;\n  const state = [1732584193, -271733879, -1732584194, 271733878];\n  let i = 0;\n  for (i = 64; i <= s.length; i += 64) {\n    md5cycle(state, md5blk(s.substring(i - 64, i)));\n  }\n  s = s.substring(i - 64);\n  const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n  for (i = 0; i < s.length; i++) tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);\n  tail[i >> 2] |= 0x80 << (i % 4 << 3);\n  if (i > 55) {\n    md5cycle(state, tail);\n    for (i = 0; i < 16; i++) tail[i] = 0;\n  }\n  tail[14] = n * 8;\n  md5cycle(state, tail);\n  return state;\n}\n\nfunction md5blk(s: string): number[] {\n  const md5blks: number[] = [];\n  for (let i = 0; i < 64; i += 4) {\n    md5blks[i >> 2] =\n      s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);\n  }\n  return md5blks;\n}\n\nconst hex_chr = '0123456789abcdef'.split('');\n\nfunction rhex(n: number) {\n  let s = '',\n    j = 0;\n  for (; j < 4; j++) s += hex_chr[(n >> (j * 8 + 4)) & 0x0f] + hex_chr[(n >> (j * 8)) & 0x0f];\n  return s;\n}\n\nfunction hex(x: any[]) {\n  for (let i = 0; i < x.length; i++) x[i] = rhex(x[i]);\n  return x.join('');\n}\n\nfunction add32(a: number, b: number) {\n  return (a + b) & 0xffffffff;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/unicode/TextCoding.ts",
    "content": "import { decodeIntoString, encodeString, Encoding } from './UnicodeNative';\n\nexport type TextEncoding = 'utf8' | 'utf16' | 'utf32' | 'utf-8' | 'utf-16' | 'utf-32';\n\nfunction resolveEncoding(textEncoding: TextEncoding): Encoding {\n  if (textEncoding === 'utf-8' || textEncoding == 'utf8') {\n    return Encoding.utf8;\n  } else if (textEncoding === 'utf-16' || textEncoding == 'utf16') {\n    return Encoding.utf16;\n  } else if (textEncoding === 'utf-32' || textEncoding == 'utf32') {\n    return Encoding.utf32;\n  }\n  throw new Error(`Unsupported text encoding '${textEncoding}'`);\n}\n\nfunction encodingToString(encoding: Encoding): string {\n  switch (encoding) {\n    case Encoding.utf8:\n      return 'utf-8';\n    case Encoding.utf16:\n      return 'utf-16';\n    case Encoding.utf32:\n      return 'utf-32';\n  }\n}\n\nexport class TextDecoder {\n  get encoding(): string {\n    return encodingToString(this._encoding);\n  }\n\n  get fatal(): boolean {\n    return false;\n  }\n\n  get ignoreBOM(): boolean {\n    return false;\n  }\n\n  private readonly _encoding: Encoding;\n\n  constructor(encoding?: TextEncoding) {\n    this._encoding = encoding ? resolveEncoding(encoding) : Encoding.utf8;\n  }\n\n  decode(buffer: ArrayBufferLike): string {\n    return decodeIntoString(buffer, this._encoding);\n  }\n}\n\nexport class TextEncoder {\n  get encoding(): string {\n    return encodingToString(this._encoding);\n  }\n\n  private readonly _encoding: Encoding;\n\n  constructor(encoding?: TextEncoding) {\n    this._encoding = encoding ? resolveEncoding(encoding) : Encoding.utf8;\n  }\n\n  encode(str: string): Uint8Array {\n    return new Uint8Array(encodeString(str, this._encoding));\n  }\n\n  encodeInto(str: string, buffer: ArrayBufferLike): TextEncoderEncodeIntoResult {\n    throw new Error('encodeInto() is not yet implemented in Valdi');\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/unicode/UnicodeNative.d.ts",
    "content": "export const enum Encoding {\n  utf8 = 1,\n  utf16 = 2,\n  utf32 = 3,\n}\n\nexport interface FromCodepointsOutput {\n  str: string;\n  buffer: ArrayBuffer;\n}\n\nexport function strToCodepoints(input: string, normalize: boolean, disableCategorization: boolean): ArrayBuffer;\n\nexport function codepointsToStr(\n  codepoints: number[],\n  normalize: boolean,\n  disableCategorization: boolean,\n): FromCodepointsOutput;\n\nexport function encodeString(str: string, encoding: Encoding): ArrayBuffer;\n\nexport function decodeIntoString(buffer: ArrayBufferLike, encoding: Encoding): string;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/unicode/UnicodeString.ts",
    "content": "import { codepointsToStr, strToCodepoints } from './UnicodeNative';\n\nexport const enum UnicodeFlags {\n  NONE = 0,\n  CONTROL = 1 << 0,\n  FORMAT = 1 << 1,\n  UNASSIGNED = 1 << 2,\n  PRIVATE_USE = 1 << 3,\n  SURROGATE = 1 << 4,\n  LOWERCASE_LETTER = 1 << 5,\n  MODIFIER_LETTER = 1 << 6,\n  OTHER_LETTER = 1 << 7,\n  TITLECASE_LETTER = 1 << 8,\n  UPPERCASE_LETTER = 1 << 9,\n  SPACING_MARK = 1 << 10,\n  ENCLOSING_MARK = 1 << 11,\n  NON_SPACING_MARK = 1 << 12,\n  DECIMAL_NUMBER = 1 << 13,\n  LETTER_NUMBER = 1 << 14,\n  OTHER_NUMBER = 1 << 15,\n  CONNECT_PUNCTUATION = 1 << 16,\n  DASH_PUNCTUATION = 1 << 17,\n  CLOSE_PUNCTUATION = 1 << 18,\n  FINAL_PUNCTUATION = 1 << 19,\n  INITIAL_PUNCTUATION = 1 << 20,\n  OTHER_PUNCTUATION = 1 << 21,\n  OPEN_PUNCTUATION = 1 << 22,\n  CURRENCY_SYMBOL = 1 << 23,\n  MODIFIER_SYMOL = 1 << 24,\n  MATH_SYMBOL = 1 << 25,\n  OTHER_SYMBOL = 1 << 26,\n  LINE_SEPARATOR = 1 << 27,\n  PARAGRAPH_SEPARATOR = 1 << 28,\n  SPACE_SEPARATOR = 1 << 29,\n  EMOJI = 1 << 30,\n  FROM_GRAPHEME_CLUSTER = 1 << 31,\n}\n\nexport const enum UnicodeFlagsMask {\n  LETTER = UnicodeFlags.LOWERCASE_LETTER |\n    UnicodeFlags.MODIFIER_LETTER |\n    UnicodeFlags.OTHER_LETTER |\n    UnicodeFlags.TITLECASE_LETTER |\n    UnicodeFlags.UPPERCASE_LETTER,\n\n  NUMBER = UnicodeFlags.DECIMAL_NUMBER | UnicodeFlags.LETTER_NUMBER | UnicodeFlags.OTHER_NUMBER,\n\n  PUNCTUATION = UnicodeFlags.CONNECT_PUNCTUATION |\n    UnicodeFlags.DASH_PUNCTUATION |\n    UnicodeFlags.CLOSE_PUNCTUATION |\n    UnicodeFlags.FINAL_PUNCTUATION |\n    UnicodeFlags.INITIAL_PUNCTUATION |\n    UnicodeFlags.OTHER_PUNCTUATION |\n    UnicodeFlags.OPEN_PUNCTUATION,\n\n  SEPARATOR = UnicodeFlags.LINE_SEPARATOR | UnicodeFlags.PARAGRAPH_SEPARATOR | UnicodeFlags.SPACE_SEPARATOR,\n\n  SYMBOL = UnicodeFlags.CURRENCY_SYMBOL |\n    UnicodeFlags.MODIFIER_SYMOL |\n    UnicodeFlags.MATH_SYMBOL |\n    UnicodeFlags.OTHER_SYMBOL,\n\n  /**\n   * Mask to check whether the unicode point will result in a visible glyph\n   */\n  VISIBLE_GLYPH = LETTER | NUMBER | PUNCTUATION | SEPARATOR | SYMBOL,\n}\n\nexport const enum UnicodeStringOptions {\n  NONE = 0,\n\n  /**\n   * Whether unicode points should be combined if possible.\n   */\n  NORMALIZE = 1 << 0,\n\n  /**\n   * Whether to disable categorization of each character.\n   * This will speed up processing of the string but will\n   * be missing all the flags information.\n   */\n  NO_CATEGORIZATION = 1 << 1,\n}\n\nabstract class UnicodeStringBase {\n  abstract readonly length: number;\n\n  abstract getCodepointAt(index: number): number;\n  abstract getFlagsAt(index: number): UnicodeFlags;\n\n  isEmojiAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlags.EMOJI) != 0;\n  }\n\n  isLetterAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlagsMask.LETTER) != 0;\n  }\n\n  isNumber(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlagsMask.NUMBER) != 0;\n  }\n\n  isPunctuationAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlagsMask.PUNCTUATION) != 0;\n  }\n\n  isSeparatorAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlagsMask.SEPARATOR) != 0;\n  }\n\n  isSurrogateAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlags.SURROGATE) != 0;\n  }\n\n  isModifierSymbolAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlags.MODIFIER_SYMOL) != 0;\n  }\n\n  isFormatAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlags.FORMAT) != 0;\n  }\n\n  isControlAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlags.CONTROL) != 0;\n  }\n\n  isNewlineAt(index: number): boolean {\n    return this.getCodepointAt(index) == 0x000a;\n  }\n\n  isWhitespaceAt(index: number): boolean {\n    return this.isSeparatorAt(index) || this.isNewlineAt(index);\n  }\n\n  isFromGraphemeClusterAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlags.FROM_GRAPHEME_CLUSTER) != 0;\n  }\n\n  isVisibleAt(index: number): boolean {\n    return (this.getFlagsAt(index) & UnicodeFlagsMask.VISIBLE_GLYPH) != 0;\n  }\n\n  /**\n   * Counts the number of grapheme clusters within the string\n   */\n  countGraphemeClusters(): number {\n    const length = this.length;\n    let count = 0;\n    for (let i = 0; i < length; i++) {\n      if (!this.isFromGraphemeClusterAt(i)) {\n        count++;\n      }\n    }\n\n    return count;\n  }\n}\n\nlet spaceConstant: UnicodeString | undefined;\n\n/**\n * UnicodeString is a wrapper around a UTF32 string, with methods to help\n * querying about unicode information for each character.\n */\nexport class UnicodeString extends UnicodeStringBase {\n  /**\n   * Returns the number of UTF32 codepoints in the string.\n   */\n  readonly length: number;\n\n  /**\n   * Returns a JS string representing the UnicodeString.\n   */\n  readonly str: string;\n\n  private buffer: Uint32Array;\n\n  private constructor(str: string, buffer: Uint32Array) {\n    super();\n    this.str = str;\n    this.length = buffer.length / 2;\n    this.buffer = buffer;\n  }\n\n  getCodepointAt(index: number): number {\n    return this.buffer[index];\n  }\n\n  getFlagsAt(index: number): UnicodeFlags {\n    return this.buffer[this.length + index];\n  }\n\n  toMutable(): MutableUnicodeString {\n    const codepoints: number[] = [];\n    const flags: number[] = [];\n    for (let i = 0, length = this.length; i < length; i++) {\n      codepoints.push(this.getCodepointAt(i));\n      flags.push(this.getFlagsAt(i));\n    }\n    return new MutableUnicodeString(codepoints, flags);\n  }\n\n  /**\n   * Create a UnicodeString from a JS string.\n   * if \"includeCategorization\" is false, flags for each symbol won't be resolved.\n   */\n  static fromString(str: string, options: UnicodeStringOptions = UnicodeStringOptions.NONE): UnicodeString {\n    const normalize = (options & UnicodeStringOptions.NORMALIZE) != 0;\n    const disableCategorization = (options & UnicodeStringOptions.NO_CATEGORIZATION) != 0;\n    const uni = strToCodepoints(str, normalize, disableCategorization);\n    return new UnicodeString(str, new Uint32Array(uni));\n  }\n\n  /**\n   * Create a UnicodeString from an array of UTF32 codepoints.\n   * if \"includeCategorization\" is false, flags for each symbol won't be resolved.\n   */\n  static fromCodepoints(\n    codepoints: number[],\n    options: UnicodeStringOptions = UnicodeStringOptions.NONE,\n  ): UnicodeString {\n    const normalize = (options & UnicodeStringOptions.NORMALIZE) != 0;\n    const disableCategorization = (options & UnicodeStringOptions.NO_CATEGORIZATION) != 0;\n    const uni = codepointsToStr(codepoints, normalize, disableCategorization);\n    return new UnicodeString(uni.str, new Uint32Array(uni.buffer));\n  }\n\n  /**\n   * Returns a UnicodeString constant containing a single space\n   */\n  static space(): UnicodeString {\n    if (!spaceConstant) {\n      spaceConstant = UnicodeString.fromString(' ');\n    }\n    return spaceConstant;\n  }\n}\n\n/**\n * MutableUnicodeString is a class that helps with manipulating UnicodeStrings.\n */\nexport class MutableUnicodeString extends UnicodeStringBase {\n  get length(): number {\n    return this.codepoints.length;\n  }\n\n  private codepoints: number[];\n  private flags: number[];\n\n  constructor(codepoints: number[], flags: number[]) {\n    super();\n    this.codepoints = codepoints;\n    this.flags = flags;\n  }\n\n  getCodepointAt(index: number): number {\n    return this.codepoints[index];\n  }\n\n  getFlagsAt(index: number): UnicodeFlags {\n    return this.flags[index];\n  }\n\n  trim(): MutableUnicodeString {\n    return this.trimRight().trimLeft();\n  }\n\n  trimLeft(): MutableUnicodeString {\n    while (this.length > 0 && this.isWhitespaceAt(0)) {\n      this.codepoints.shift();\n      this.flags.shift();\n    }\n\n    return this;\n  }\n\n  trimRight(): MutableUnicodeString {\n    for (;;) {\n      const endIndex = this.length - 1;\n      if (endIndex < 0 || !this.isWhitespaceAt(endIndex)) {\n        break;\n      }\n\n      this.codepoints.pop();\n      this.flags.pop();\n    }\n    return this;\n  }\n\n  removeAt(index: number): MutableUnicodeString {\n    return this.removeCount(index, 1);\n  }\n\n  /**\n   * Remove the codepoints from the given inclusive startIndex to the given exclusive endIndex.\n   */\n  removeRange(startIndex: number, endIndex: number): MutableUnicodeString {\n    if (endIndex < startIndex) {\n      throw new Error(`Invalid range ${startIndex} to ${endIndex}`);\n    }\n    return this.removeCount(startIndex, endIndex - startIndex);\n  }\n\n  /**\n   * Remove a number of codepoints from the given startIndex\n   */\n  removeCount(startIndex: number, count: number): MutableUnicodeString {\n    this.codepoints.splice(startIndex, count);\n    this.flags.splice(startIndex, count);\n    return this;\n  }\n\n  /**\n   * Insert the given codepoint and flags at the given index\n   */\n  insertAt(index: number, codepoint: number, flags: UnicodeFlags): MutableUnicodeString {\n    this.codepoints.splice(index, 0, codepoint);\n    this.flags.splice(index, 0, flags);\n\n    return this;\n  }\n\n  /**\n   * Only keep the grapheme clusters for which the include function returns true.\n   * The include function will be called for each grapheme cluster, providing the startIndex\n   * of the graphem cluster within the UnicodeString and its exclusive endIndex.\n   */\n  filterGraphemeClusters(\n    include: (self: MutableUnicodeString, startIndex: number, endIndex: number) => boolean,\n  ): MutableUnicodeString {\n    return this.replaceGraphemeClusters(\n      (self, startIndex, endIndex) => !include(self, startIndex, endIndex),\n      undefined,\n    );\n  }\n\n  /**\n   *\n   * Replace the grapheme clusters for which include returns true by the given replacement UnicodeString.\n   * The include function will be called for each grapheme cluster, providing the startIndex\n   * of the graphem cluster within the UnicodeString and its exclusive endIndex.\n   * If \"replacement\" is undefined, it will be replaced by empty string.\n   * @returns\n   */\n  replaceGraphemeClusters(\n    include: (self: MutableUnicodeString, startIndex: number, endIndex: number) => boolean,\n    replacement: UnicodeString | undefined,\n  ): MutableUnicodeString {\n    let graphemeClusterStart = -1;\n    let current = 0;\n    while (current < this.length) {\n      if (!this.isFromGraphemeClusterAt(current)) {\n        // New grapheme cluster\n        if (graphemeClusterStart >= 0) {\n          const graphemeClusterEnd = current;\n          if (include(this, graphemeClusterStart, graphemeClusterEnd)) {\n            const toRemoveCount = graphemeClusterEnd - graphemeClusterStart;\n            this.removeCount(graphemeClusterStart, toRemoveCount);\n            current -= toRemoveCount;\n\n            if (replacement) {\n              for (let i = 0; i < replacement.length; i++) {\n                this.insertAt(current, replacement.getCodepointAt(i), replacement.getFlagsAt(i));\n                current++;\n              }\n            }\n          }\n        }\n        graphemeClusterStart = current;\n      }\n\n      current++;\n    }\n\n    if (graphemeClusterStart >= 0) {\n      if (include(this, graphemeClusterStart, current)) {\n        const toRemoveCount = current - graphemeClusterStart;\n        this.removeCount(graphemeClusterStart, toRemoveCount);\n\n        if (replacement) {\n          for (let i = 0; i < replacement.length; i++) {\n            this.insertAt(current, replacement.getCodepointAt(i), replacement.getFlagsAt(i));\n            current++;\n          }\n        }\n      }\n    }\n\n    return this;\n  }\n\n  /**\n   * Split the UnicodeString for each unicode point on which the predicate function\n   * returns true.\n   */\n  splitBy(predicate: (self: MutableUnicodeString, index: number) => boolean): MutableUnicodeString[] {\n    const output: MutableUnicodeString[] = [];\n\n    let currentCodepoints: number[] = [];\n    let currentFlags: number[] = [];\n\n    for (let i = 0; i < this.length; i++) {\n      if (predicate(this, i)) {\n        output.push(new MutableUnicodeString(currentCodepoints, currentFlags));\n        currentCodepoints = [];\n        currentFlags = [];\n      } else {\n        if (!currentCodepoints) {\n          currentCodepoints = [];\n        }\n        if (!currentFlags) {\n          currentFlags = [];\n        }\n        currentCodepoints.push(this.getCodepointAt(i));\n        currentFlags.push(this.getFlagsAt(i));\n      }\n    }\n\n    output.push(new MutableUnicodeString(currentCodepoints, currentFlags));\n\n    return output;\n  }\n\n  /**\n   * Split the UnicodeString by whitespaces, which includes newlines and separators\n   */\n  splitByWhitespace(): MutableUnicodeString[] {\n    return this.splitBy((self, index) => self.isWhitespaceAt(index));\n  }\n\n  copy(): MutableUnicodeString {\n    return new MutableUnicodeString([...this.codepoints], [...this.flags]);\n  }\n\n  toUnicodeString(): UnicodeString {\n    return UnicodeString.fromCodepoints(this.codepoints);\n  }\n\n  toString(): string {\n    return codepointsToStr(this.codepoints, false, true).str;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/url.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\n\ntype EncodableParams = StringMap<string | number>;\ntype DecodedParams = StringMap<string>;\n\n/**\n * String-encode a query param mapping.\n */\nexport function encodeQueryParams(params: EncodableParams): string {\n  return Object.keys(params)\n    .filter(k => params[k] !== undefined)\n    .map(k => [k, params[k]!].map(encodeURIComponent).join('='))\n    .join('&');\n}\n\n/**\n * Retrieve a map of from a querystring formatted string\n */\nexport function decodeQueryParams(paramString: string): DecodedParams {\n  return paramString\n    .split('&')\n    .filter(pair => pair) // remove empty strings\n    .map(pair => pair.split('=').map(decodeURIComponent))\n    .reduce((acc: DecodedParams, pairParts: string[]) => {\n      acc[pairParts[0]] = pairParts.length > 1 ? pairParts[1] : undefined;\n      return acc;\n    }, {});\n}\n\n/**\n * Generate a path string with query params.\n */\nexport function pathWithParams(path: string, params: EncodableParams): string {\n  return [path, encodeQueryParams(params)].join('?');\n}\n\n/**\n * Parse key/value pairs from a URL's query string\n */\nexport function paramsFromUrl(url: string): DecodedParams {\n  if (!url) return {};\n  const parts = url.split('?');\n  if (parts.length <= 1) return {};\n  return decodeQueryParams(parts[1]);\n}\n\n/**\n * Validate if string matches url pattern and return results of the search\n */\nfunction isUrl(url: string): RegExpMatchArray | null {\n  return url.match(/^https?\\:\\/\\/([^\\/?#]+)(?:[\\/?#]|$)/i);\n}\n\n/**\n * Parse hostname from URL\n */\nexport function hostnameFromUrl(url: string): string {\n  const matches = isUrl(url);\n  const host = matches && matches[1];\n  return host || '';\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/src/uuidUtils.ts",
    "content": "// Code in this file is adapted from uuid-tool:\n// https://github.com/domske/uuid-tool/blob/master/src/uuid.ts\n\nexport function uuidStringToBytes(uuid: string): Uint8Array {\n  const bytes = (uuid.trim().replace(/-/g, '').match(/.{2}/g) || []).map(b => parseInt(b, 16));\n  return Uint8Array.of(...bytes);\n}\n\nexport function uuidStringToBytesList(uuids: string[]): Uint8Array[] {\n  return uuids.map(uuidStringToBytes);\n}\n\nexport function uuidBytesToString(uuid: Uint8Array): string {\n  return Array.from(uuid)\n    .map(b => ('00' + b.toString(16)).slice(-2))\n    .join('')\n    .replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, '$1-$2-$3-$4-$5');\n}\n\nexport function uuidBytesToStringList(uuids: readonly Uint8Array[]): string[] {\n  return uuids.map(uuidBytesToString);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/test/Base64.spec.ts",
    "content": "import { Base64 } from 'coreutils/src/Base64';\nimport 'jasmine/src/jasmine';\n\ndescribe('coreutils > Base64', () => {\n  // Byte array for '<<???>>'\n  const byteArray = new Uint8Array([60, 60, 63, 63, 63, 62, 62]);\n  it('should Base64 encode correctly', () => {\n    expect(Base64.fromByteArray(byteArray)).toEqual('PDw/Pz8+Pg==');\n  });\n  it('should url-safe Base64 encode correctly', () => {\n    expect(Base64.fromByteArray(byteArray, { urlSafe: true })).toEqual('PDw_Pz8-Pg');\n  });\n  it('should Base64 decode correctly with padding', () => {\n    expect(Base64.toByteArray('PDw/Pz8+Pg==')).toEqual(byteArray);\n  });\n  it('should Base64 decode correctly without padding', () => {\n    expect(Base64.toByteArray('PDw/Pz8+Pg')).toEqual(byteArray);\n  });\n  it('should url-safe Base64 decode correctly without padding', () => {\n    expect(Base64.toByteArray('PDw_Pz8-Pg')).toEqual(byteArray);\n  });\n  it('should url-safe Base64 decode correctly with padding', () => {\n    expect(Base64.toByteArray('PDw_Pz8-Pg=')).toEqual(byteArray);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/test/LRUCache.spec.ts",
    "content": "import { LRUCache } from 'coreutils/src/LRUCache';\nimport 'jasmine/src/jasmine';\n\ndescribe('LRUCache', () => {\n  it('should update items order on get', () => {\n    const cache = new LRUCache<string>(8);\n    cache.insert('1', 'Hello');\n    cache.insert('2', 'Bonjour');\n    cache.insert('3', 'Dzien dobry');\n\n    expect(cache.all()).toEqual(['Dzien dobry', 'Bonjour', 'Hello']);\n\n    let fetchedItem = cache.get('2');\n    expect(fetchedItem).toBe('Bonjour');\n\n    expect(cache.all()).toEqual(['Bonjour', 'Dzien dobry', 'Hello']);\n\n    // No change expected if we fetch the item at the front\n    fetchedItem = cache.get('2');\n    expect(fetchedItem).toBe('Bonjour');\n\n    expect(cache.all()).toEqual(['Bonjour', 'Dzien dobry', 'Hello']);\n\n    // Fetching last item should re-order\n\n    fetchedItem = cache.get('1');\n    expect(fetchedItem).toBe('Hello');\n\n    expect(cache.all()).toEqual(['Hello', 'Bonjour', 'Dzien dobry']);\n  });\n\n  it('should trim items on out of bounds', () => {\n    const cache = new LRUCache<string>(2);\n    cache.insert('1', 'Hello');\n    cache.insert('2', 'Bonjour');\n    cache.insert('3', 'Dzien dobry');\n\n    expect(cache.all()).toEqual(['Dzien dobry', 'Bonjour']);\n\n    cache.insert('4', 'Hola');\n\n    expect(cache.all()).toEqual(['Hola', 'Dzien dobry']);\n  });\n\n  it('should replace item on re-insert', () => {\n    const cache = new LRUCache<string>(8);\n    cache.insert('1', 'Hello');\n    cache.insert('2', 'Bonjour');\n    cache.insert('3', 'Dzien dobry');\n\n    expect(cache.all()).toEqual(['Dzien dobry', 'Bonjour', 'Hello']);\n\n    // Replace Hello by Hola\n    cache.insert('1', 'Hola');\n\n    expect(cache.all()).toEqual(['Hola', 'Dzien dobry', 'Bonjour']);\n  });\n\n  it('can erase item', () => {\n    const cache = new LRUCache<string>(8);\n    cache.insert('1', 'Hello');\n    cache.insert('2', 'Bonjour');\n    cache.insert('3', 'Dzien dobry');\n\n    expect(cache.all()).toEqual(['Dzien dobry', 'Bonjour', 'Hello']);\n\n    cache.remove('2');\n\n    expect(cache.all()).toEqual(['Dzien dobry', 'Hello']);\n\n    cache.remove('1');\n\n    expect(cache.all()).toEqual(['Dzien dobry']);\n\n    cache.remove('3');\n\n    expect(cache.all()).toEqual([]);\n  });\n\n  it('can be cleared', () => {\n    const cache = new LRUCache<string>(8);\n    cache.insert('1', 'Hello');\n    cache.insert('2', 'Bonjour');\n    cache.insert('3', 'Dzien dobry');\n\n    expect(cache.all()).toEqual(['Dzien dobry', 'Bonjour', 'Hello']);\n\n    cache.clear();\n\n    expect(cache.all()).toEqual([]);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/test/TextCoding.spec.ts",
    "content": "import { TextDecoder, TextEncoder } from 'coreutils/src/unicode/TextCoding';\nimport 'jasmine/src/jasmine';\n\ndeclare const global: any;\n\ndescribe('TextDecoder', () => {\n  it('can decode utf8', () => {\n    const textDecoder = new TextDecoder('utf-8');\n    const str = textDecoder.decode(new Uint8Array([0xf0, 0x9f, 0x91, 0x8d, 0xf0, 0x9f, 0x8f, 0xbb]));\n    expect(str).toBe('👍🏻');\n  });\n\n  it('can decode utf16', () => {\n    const textDecoder = new TextDecoder('utf-16');\n    const str = textDecoder.decode(new Uint16Array([0xd83d, 0xdc4d, 0xd83c, 0xdffb]));\n    expect(str).toBe('👍🏻');\n  });\n\n  it('can decode utf32', () => {\n    const textDecoder = new TextDecoder('utf-32');\n    const str = textDecoder.decode(new Uint32Array([0x1f44d, 0x1f3fb]));\n    expect(str).toBe('👍🏻');\n  });\n\n  it('is assigned in global', () => {\n    expect(global.TextDecoder).toBeDefined();\n  });\n});\n\ndescribe('TextEncoder', () => {\n  it('can encode utf8', () => {\n    const textEncoder = new TextEncoder('utf-8');\n\n    const result = textEncoder.encode('👍🏻');\n\n    expect(result).toEqual(new Uint8Array([0xf0, 0x9f, 0x91, 0x8d, 0xf0, 0x9f, 0x8f, 0xbb]));\n  });\n\n  it('can encode utf16', () => {\n    const textEncoder = new TextEncoder('utf-16');\n\n    const result = textEncoder.encode('👍🏻');\n\n    expect(new Uint16Array(result.buffer)).toEqual(new Uint16Array([0xd83d, 0xdc4d, 0xd83c, 0xdffb]));\n  });\n\n  it('can encode utf32', () => {\n    const textEncoder = new TextEncoder('utf-32');\n\n    const result = textEncoder.encode('👍🏻');\n\n    expect(new Uint32Array(result.buffer)).toEqual(new Uint32Array([0x1f44d, 0x1f3fb]));\n  });\n\n  it('is assigned in global', () => {\n    expect(global.TextDecoder).toBeDefined();\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/test/UnicodeString.spec.ts",
    "content": "import { UnicodeString, UnicodeStringOptions } from 'coreutils/src/unicode/UnicodeString';\nimport 'jasmine/src/jasmine';\n\ndescribe('UnicodeString', () => {\n  it('detects letters', () => {\n    const str = UnicodeString.fromString('Hello, World!');\n\n    expect(str.length).toEqual(13);\n    expect(str.isLetterAt(0)).toBeTrue();\n    expect(str.isLetterAt(1)).toBeTrue();\n    expect(str.isLetterAt(2)).toBeTrue();\n    expect(str.isLetterAt(3)).toBeTrue();\n    expect(str.isLetterAt(4)).toBeTrue();\n    expect(str.isLetterAt(5)).toBeFalse();\n    expect(str.isLetterAt(6)).toBeFalse();\n    expect(str.isLetterAt(7)).toBeTrue();\n    expect(str.isLetterAt(8)).toBeTrue();\n    expect(str.isLetterAt(9)).toBeTrue();\n    expect(str.isLetterAt(10)).toBeTrue();\n    expect(str.isLetterAt(11)).toBeTrue();\n    expect(str.isLetterAt(12)).toBeFalse();\n  });\n\n  it('detects numbers', () => {\n    const str = UnicodeString.fromString('H3ll0 W0rld');\n\n    expect(str.length).toEqual(11);\n    expect(str.isNumber(0)).toBeFalse();\n    expect(str.isNumber(1)).toBeTrue();\n    expect(str.isNumber(2)).toBeFalse();\n    expect(str.isNumber(3)).toBeFalse();\n    expect(str.isNumber(4)).toBeTrue();\n    expect(str.isNumber(5)).toBeFalse();\n    expect(str.isNumber(6)).toBeFalse();\n    expect(str.isNumber(7)).toBeTrue();\n    expect(str.isNumber(8)).toBeFalse();\n    expect(str.isNumber(9)).toBeFalse();\n    expect(str.isNumber(10)).toBeFalse();\n  });\n\n  it('detects punctuations', () => {\n    const str = UnicodeString.fromString('Ok,wow! (great...)');\n\n    expect(str.length).toEqual(18);\n\n    expect(str.isPunctuationAt(0)).toBeFalse();\n    expect(str.isPunctuationAt(1)).toBeFalse();\n    expect(str.isPunctuationAt(2)).toBeTrue();\n    expect(str.isPunctuationAt(3)).toBeFalse();\n    expect(str.isPunctuationAt(4)).toBeFalse();\n    expect(str.isPunctuationAt(5)).toBeFalse();\n    expect(str.isPunctuationAt(6)).toBeTrue();\n    expect(str.isPunctuationAt(7)).toBeFalse();\n    expect(str.isPunctuationAt(8)).toBeTrue();\n    expect(str.isPunctuationAt(9)).toBeFalse();\n    expect(str.isPunctuationAt(10)).toBeFalse();\n    expect(str.isPunctuationAt(11)).toBeFalse();\n    expect(str.isPunctuationAt(12)).toBeFalse();\n    expect(str.isPunctuationAt(13)).toBeFalse();\n    expect(str.isPunctuationAt(14)).toBeTrue();\n    expect(str.isPunctuationAt(15)).toBeTrue();\n    expect(str.isPunctuationAt(16)).toBeTrue();\n    expect(str.isPunctuationAt(17)).toBeTrue();\n  });\n\n  it('detects separators', () => {\n    const str = UnicodeString.fromString('Nice boy\\n');\n\n    expect(str.length).toEqual(9);\n\n    expect(str.isSeparatorAt(0)).toBeFalse();\n    expect(str.isSeparatorAt(1)).toBeFalse();\n    expect(str.isSeparatorAt(2)).toBeFalse();\n    expect(str.isSeparatorAt(3)).toBeFalse();\n    expect(str.isSeparatorAt(4)).toBeTrue();\n    expect(str.isSeparatorAt(5)).toBeFalse();\n    expect(str.isSeparatorAt(6)).toBeFalse();\n    expect(str.isSeparatorAt(7)).toBeFalse();\n    expect(str.isSeparatorAt(8)).toBeFalse();\n    expect(str.isControlAt(8)).toBeTrue();\n    expect(str.isNewlineAt(8)).toBeTrue();\n  });\n\n  it('detects emoji', () => {\n    const str = UnicodeString.fromString('Wow 😀');\n\n    expect(str.length).toBe(5);\n\n    expect(str.isEmojiAt(0)).toBeFalse();\n    expect(str.isEmojiAt(1)).toBeFalse();\n    expect(str.isEmojiAt(2)).toBeFalse();\n    expect(str.isEmojiAt(3)).toBeFalse();\n    expect(str.isEmojiAt(4)).toBeTrue();\n  });\n\n  it('can normalize', () => {\n    const str = UnicodeString.fromCodepoints([0x41, 0x0301], UnicodeStringOptions.NORMALIZE);\n    expect(str.length).toEqual(1);\n  });\n\n  it('detects modifiers', () => {\n    const str = UnicodeString.fromString('👍🏻👍🏼👍🏽👍🏾👍🏿');\n\n    expect(str.length).toEqual(10);\n\n    expect(str.isEmojiAt(0)).toBeTrue();\n    expect(str.isModifierSymbolAt(0)).toBeFalse();\n    expect(str.isEmojiAt(1)).toBeTrue();\n    expect(str.isModifierSymbolAt(1)).toBeTrue();\n    expect(str.isEmojiAt(2)).toBeTrue();\n    expect(str.isModifierSymbolAt(2)).toBeFalse();\n    expect(str.isEmojiAt(3)).toBeTrue();\n    expect(str.isModifierSymbolAt(3)).toBeTrue();\n    expect(str.isEmojiAt(4)).toBeTrue();\n    expect(str.isModifierSymbolAt(4)).toBeFalse();\n    expect(str.isEmojiAt(5)).toBeTrue();\n    expect(str.isModifierSymbolAt(5)).toBeTrue();\n    expect(str.isEmojiAt(6)).toBeTrue();\n    expect(str.isModifierSymbolAt(6)).toBeFalse();\n    expect(str.isEmojiAt(7)).toBeTrue();\n    expect(str.isModifierSymbolAt(7)).toBeTrue();\n    expect(str.isEmojiAt(8)).toBeTrue();\n    expect(str.isModifierSymbolAt(8)).toBeFalse();\n    expect(str.isEmojiAt(9)).toBeTrue();\n    expect(str.isModifierSymbolAt(9)).toBeTrue();\n  });\n\n  it('can count grapheme clusters', () => {\n    let str = UnicodeString.fromString('👍🏻👍🏼👍🏽👍🏾👍🏿');\n\n    expect(str.countGraphemeClusters()).toBe(5);\n\n    str = UnicodeString.fromString('👨‍❤️‍👨');\n\n    expect(str.countGraphemeClusters()).toBe(1);\n    expect(str.length).toBe(6);\n  });\n\n  it('can create unicode from codepoints', () => {\n    const str = UnicodeString.fromCodepoints([78, 105, 99, 101, 33]);\n\n    expect(str.length).toBe(5);\n    expect(str.str).toBe('Nice!');\n\n    expect(str.isLetterAt(0)).toBeTrue();\n    expect(str.isLetterAt(1)).toBeTrue();\n    expect(str.isLetterAt(2)).toBeTrue();\n    expect(str.isLetterAt(3)).toBeTrue();\n    expect(str.isPunctuationAt(4)).toBeTrue();\n  });\n});\n\ndescribe('MutableUnicodeString', () => {\n  it('can trimLeft', () => {\n    expect(UnicodeString.fromString('    Hello World    ').toMutable().trimLeft().toString()).toBe('Hello World    ');\n  });\n\n  it('can trimRight', () => {\n    expect(UnicodeString.fromString('    Hello World    ').toMutable().trimRight().toString()).toBe('    Hello World');\n  });\n\n  it('can trim', () => {\n    expect(UnicodeString.fromString('    Hello World    ').toMutable().trim().toString()).toBe('Hello World');\n  });\n\n  it('can removeAt', () => {\n    const str = UnicodeString.fromString('Hello World').toMutable();\n    str.removeAt(0);\n    expect(str.toString()).toBe('ello World');\n    str.removeAt(4);\n    expect(str.toString()).toBe('elloWorld');\n  });\n\n  it('can removeRange', () => {\n    const str = UnicodeString.fromString('Hello World').toMutable();\n    str.removeRange(0, 6);\n\n    expect(str.toString()).toBe('World');\n\n    str.removeRange(1, 2);\n\n    expect(str.toString()).toBe('Wrld');\n  });\n\n  it('can removeCount', () => {\n    const str = UnicodeString.fromString('Hello World').toMutable();\n    str.removeCount(6, 5);\n\n    expect(str.toString()).toBe('Hello ');\n  });\n\n  it('can filter by grapheme cluster', () => {\n    const str = UnicodeString.fromString('Wow 😀, this is great 👍🏻!').toMutable();\n\n    str.filterGraphemeClusters((s, startIndex) => !s.isEmojiAt(startIndex));\n\n    expect(str.toString()).toBe('Wow , this is great !');\n\n    expect(\n      UnicodeString.fromString('...\\n')\n        .toMutable()\n        .filterGraphemeClusters((s, startIndex) => !s.isNewlineAt(startIndex))\n        .toString(),\n    ).toBe('...');\n  });\n\n  it('can replace grapheme clusters', () => {\n    const replacement = UnicodeString.fromString('<redacted>');\n    const str = UnicodeString.fromString('Wow 😀, this is great 👍🏻!').toMutable();\n\n    str.replaceGraphemeClusters((s, startIndex) => s.isEmojiAt(startIndex), replacement);\n\n    expect(str.toString()).toBe('Wow <redacted>, this is great <redacted>!');\n  });\n\n  it('can split', () => {\n    expect(\n      UnicodeString.fromString('Hello\\nBonjour\\nDzień dobry\\n')\n        .toMutable()\n        .splitBy((s, index) => s.isNewlineAt(index))\n        .map(f => f.toString()),\n    ).toEqual(['Hello', 'Bonjour', 'Dzień dobry', '']);\n  });\n\n  it('can split by whitespace', () => {\n    expect(\n      UnicodeString.fromString('Hello\\nBonjour\\nDzień dobry')\n        .toMutable()\n        .splitByWhitespace()\n        .map(f => f.toString()),\n    ).toEqual(['Hello', 'Bonjour', 'Dzień', 'dobry']);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/test/md5.spec.ts",
    "content": "import { md5 } from 'coreutils/src/md5';\nimport 'jasmine/src/jasmine';\n\ndescribe('coreutils > md5', () => {\n  it('should md5 hash correctly', () => {\n    expect(md5.hash('hello')).toEqual('5d41402abc4b2a76b9719d911017c592');\n    expect(md5.hash('W7_EDlXWTBiXAEEniNoMPwAAYZXVhZ2NqcGt6AYFPU_XMAYFPU_WKAAAAAA')).toEqual(\n      '15b244225a3207159403fdc623aa4991',\n    );\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/test/urls.spec.ts",
    "content": "import * as urls from 'coreutils/src/url';\nimport 'jasmine/src/jasmine';\n\ndescribe('coreutils > url', () => {\n  it('should encode query params', () => {\n    expect(urls.encodeQueryParams({})).toEqual('');\n    expect(urls.encodeQueryParams({ foo: 'bar' })).toEqual('foo=bar');\n    expect(urls.encodeQueryParams({ foo: 'bar bar' })).toEqual('foo=bar%20bar');\n    expect(urls.encodeQueryParams({ foo: 'bar', bar: 'baz' })).toEqual('foo=bar&bar=baz');\n    expect(urls.encodeQueryParams({ foo: undefined })).toEqual('');\n    expect(urls.encodeQueryParams({ foo: 200 })).toEqual('foo=200');\n    expect(urls.encodeQueryParams({ 'foo bar': 'baz' })).toEqual('foo%20bar=baz');\n  });\n\n  it('should decode query params', () => {\n    expect(urls.decodeQueryParams('')).toEqual({});\n    expect(urls.decodeQueryParams('foo=bar')).toEqual({ foo: 'bar' });\n    expect(urls.decodeQueryParams('foo=bar%20bar')).toEqual({ foo: 'bar bar' });\n    expect(urls.decodeQueryParams('foo=bar&bar=baz')).toEqual({ foo: 'bar', bar: 'baz' });\n    expect(urls.decodeQueryParams('foo=200')).toEqual({ foo: '200' });\n    expect(urls.decodeQueryParams('foo=bar&foo=baz')).toEqual({ foo: 'baz' });\n  });\n\n  it('should create a url with params', () => {\n    expect(urls.pathWithParams('', { foo: 'bar', bar: 'baz' })).toEqual('?foo=bar&bar=baz');\n    expect(urls.pathWithParams('http://foo', { foo: 'bar', bar: 'baz' })).toEqual('http://foo?foo=bar&bar=baz');\n    expect(urls.pathWithParams('http://foo', {})).toEqual('http://foo?');\n  });\n\n  it('should return params from a url', () => {\n    expect(urls.paramsFromUrl('')).toEqual({});\n    expect(urls.paramsFromUrl('http://foo')).toEqual({});\n    expect(urls.paramsFromUrl('http://foo?')).toEqual({});\n    expect(urls.paramsFromUrl('http://foo?foo=bar')).toEqual({ foo: 'bar' });\n    expect(urls.paramsFromUrl('http://foo?foo=bar%20bar&bar=baz')).toEqual({ foo: 'bar bar', bar: 'baz' });\n  });\n\n  it('should return hostname from a url', () => {\n    expect(urls.hostnameFromUrl('')).toEqual('');\n    expect(urls.hostnameFromUrl('foo')).toEqual('');\n    expect(urls.hostnameFromUrl('https://foo')).toEqual('foo');\n    expect(urls.hostnameFromUrl('https://foo?')).toEqual('foo');\n    expect(urls.hostnameFromUrl('https://foo?foo=bar')).toEqual('foo');\n    expect(urls.hostnameFromUrl('https://foo?foo=bar%20bar&bar=baz')).toEqual('foo');\n    expect(urls.hostnameFromUrl('https://foo.foo')).toEqual('foo.foo');\n    expect(urls.hostnameFromUrl('http://foo')).toEqual('foo');\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/test/uuidUtils.spec.ts",
    "content": "import { uuidStringToBytes, uuidBytesToString } from '../src/uuidUtils';\nimport 'jasmine/src/jasmine';\n\nconst UUIDS: { uuidString: string; uuidBytes: Uint8Array }[] = [\n  {\n    uuidString: 'f64ea4e0-bc3b-42c2-ad34-29698bafef09',\n    uuidBytes: Uint8Array.from([246, 78, 164, 224, 188, 59, 66, 194, 173, 52, 41, 105, 139, 175, 239, 9]),\n  },\n  {\n    uuidString: 'f47ac10b-58cc-0372-8567-0e02b2c3d479',\n    uuidBytes: Uint8Array.from([244, 122, 193, 11, 88, 204, 3, 114, 133, 103, 14, 2, 178, 195, 212, 121]),\n  },\n];\n\ndescribe('uuidStringToBytes', () => {\n  it('should convert a uuid string to correct bytes', () => {\n    for (const uuid of UUIDS) {\n      const { uuidString, uuidBytes } = uuid;\n      expect(uuidStringToBytes(uuidString)).toEqual(uuidBytes);\n    }\n  });\n\n  it('should convert to and from a string', () => {\n    for (const uuid of UUIDS) {\n      const { uuidString } = uuid;\n      expect(uuidStringToBytes(uuidString)).toEqual(\n        uuidStringToBytes(uuidBytesToString(uuidStringToBytes(uuidString))),\n      );\n    }\n  });\n});\n\ndescribe('uuidBytesToString', () => {\n  it('should convert uuid bytes to string', () => {\n    for (const uuid of UUIDS) {\n      const { uuidString, uuidBytes } = uuid;\n      expect(uuidBytesToString(uuidBytes)).toEqual(uuidString);\n    }\n  });\n\n  it('should convert to and from bytes', () => {\n    for (const uuid of UUIDS) {\n      const { uuidBytes } = uuid;\n      expect(uuidBytesToString(uuidBytes)).toEqual(uuidBytesToString(uuidStringToBytes(uuidBytesToString(uuidBytes))));\n    }\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/tsconfig.json",
    "content": "{\n  \"extends\": \"../_configs/base.tsconfig.json\",\n  \"compilerOptions\": {\n    \"noImplicitReturns\": true,\n    \"noImplicitAny\": true,\n    \"strict\": true,\n    \"jsx\": \"preserve\"\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/web/UnicodeNative.ts",
    "content": "import { FromCodepointsOutput, Encoding } from '../src/unicode/UnicodeNative';\n\nexport function strToCodepoints(\n  input: string,\n  normalize: boolean,\n  _disableCategorization: boolean\n): ArrayBuffer {\n  const s = normalize ? input.normalize(\"NFC\") : input;\n  const cps = toCodePoints(s);\n  const out = new ArrayBuffer(cps.length * 4);\n  const view = new DataView(out);\n  for (let i = 0; i < cps.length; i++) view.setUint32(i * 4, cps[i], true);\n  return out;\n}\n\nexport function codepointsToStr(\n  codepoints: number[],\n  normalize: boolean,\n  _disableCategorization: boolean\n): FromCodepointsOutput {\n  const sanitized = codepoints.map(sanitizeCodePoint);\n  const str = String.fromCodePoint(...sanitized);\n  const s = normalize ? str.normalize(\"NFC\") : str;\n\n  // Return a Uint32-per-codepoint buffer (LE) mirroring the input array\n  const buf = new ArrayBuffer(sanitized.length * 4);\n  const dv = new DataView(buf);\n  for (let i = 0; i < sanitized.length; i++) dv.setUint32(i * 4, sanitized[i], true);\n  return { str: s, buffer: buf };\n}\n\nexport function encodeString(str: string, encoding: Encoding): ArrayBuffer {\n  switch (encoding) {\n    case Encoding.utf8:  return encodeUtf8(str).buffer;\n    case Encoding.utf16: return encodeUtf16LE(str).buffer;               // no BOM\n    case Encoding.utf32: return encodeUtf32LE(str).buffer;               // no BOM\n    default: throw new TypeError(\"Unknown encoding\");\n  }\n}\n\nexport function decodeIntoString(buffer: ArrayBufferLike, encoding: Encoding): string {\n  switch (encoding) {\n    case Encoding.utf8:  return decodeUtf8(new Uint8Array(buffer));\n    case Encoding.utf16: return decodeUtf16(new Uint8Array(buffer));     // BOM aware\n    case Encoding.utf32: return decodeUtf32(new Uint8Array(buffer));     // BOM aware\n    default: throw new TypeError(\"Unknown encoding\");\n  }\n}\n\n/* ===== Helpers ===== */\n\nconst REPLACEMENT = 0xFFFD;\n\nfunction forEachCodePoint(s: string, fn: (cp: number, i: number) => void) {\n  for (let i = 0; i < s.length; ) {\n    const cp = s.codePointAt(i)!;\n    fn(cp, i);\n    i += cp > 0xFFFF ? 2 : 1;\n  }\n}\n\n/** Turn a JS string into Unicode scalar values (code points). */\nfunction toCodePoints(s: string): number[] {\n  const cps: number[] = [];\n  forEachCodePoint(s, (cp) => {\n    const ch = String.fromCodePoint(cp);\n    // ...\n  });\n  return cps;\n}\n\nfunction sanitizeCodePoint(cp: number): number {\n  // valid ranges: 0..0xD7FF, 0xE000..0x10FFFF\n  if (cp >= 0 && cp <= 0x10FFFF && !(cp >= 0xD800 && cp <= 0xDFFF)) return cp >>> 0;\n  return REPLACEMENT;\n}\n\n/* ===== UTF-8 ===== */\n\nfunction encodeUtf8(str: string): Uint8Array {\n  if (typeof TextEncoder !== \"undefined\") {\n    return new TextEncoder().encode(str);\n  }\n  // Manual fallback (sufficient for BMP + astral)\n  const cps = toCodePoints(str);\n  // worst case 4 bytes/code point\n  const out: number[] = [];\n  for (const cp of cps) {\n    if (cp <= 0x7F) {\n      out.push(cp);\n    } else if (cp <= 0x7FF) {\n      out.push(\n        0b11000000 | (cp >> 6),\n        0b10000000 | (cp & 0b00111111),\n      );\n    } else if (cp <= 0xFFFF) {\n      out.push(\n        0b11100000 | (cp >> 12),\n        0b10000000 | ((cp >> 6) & 0b00111111),\n        0b10000000 | (cp & 0b00111111),\n      );\n    } else {\n      out.push(\n        0b11110000 | (cp >> 18),\n        0b10000000 | ((cp >> 12) & 0b00111111),\n        0b10000000 | ((cp >> 6) & 0b00111111),\n        0b10000000 | (cp & 0b00111111),\n      );\n    }\n  }\n  return Uint8Array.from(out);\n}\n\nfunction decodeUtf8(bytes: Uint8Array): string {\n  if (typeof TextDecoder !== \"undefined\") {\n    try {\n      return new TextDecoder(\"utf-8\", { fatal: false }).decode(bytes);\n    } catch {\n      // fall through to manual\n    }\n  }\n  const cps: number[] = [];\n  for (let i = 0; i < bytes.length;) {\n    const b0 = bytes[i++];\n    if (b0 < 0x80) { cps.push(b0); continue; }\n    let needed = 0, cp = 0;\n    if ((b0 & 0b11100000) === 0b11000000) { needed = 1; cp = b0 & 0b00011111; }\n    else if ((b0 & 0b11110000) === 0b11100000) { needed = 2; cp = b0 & 0b00001111; }\n    else if ((b0 & 0b11111000) === 0b11110000) { needed = 3; cp = b0 & 0b00000111; }\n    else { cps.push(REPLACEMENT); continue; }\n\n    if (i + needed > bytes.length) { cps.push(REPLACEMENT); break; }\n    let valid = true;\n    for (let k = 0; k < needed; k++) {\n      const bx = bytes[i++];\n      if ((bx & 0b11000000) !== 0b10000000) { valid = false; break; }\n      cp = (cp << 6) | (bx & 0b00111111);\n    }\n    // overlong & range checks (simple)\n    if (!valid ||\n        (needed === 1 && cp < 0x80) ||\n        (needed === 2 && cp < 0x800) ||\n        (needed === 3 && cp < 0x10000) ||\n        cp > 0x10FFFF ||\n        (cp >= 0xD800 && cp <= 0xDFFF)) {\n      cps.push(REPLACEMENT);\n    } else {\n      cps.push(cp);\n    }\n  }\n  return String.fromCodePoint(...cps);\n}\n\n/* ===== UTF-16 (LE on encode; BOM-aware on decode) ===== */\n\nfunction encodeUtf16LE(str: string): Uint8Array {\n  // Use UTF-16 code units directly (JS internal)\n  const out = new Uint8Array(str.length * 2);\n  const dv = new DataView(out.buffer);\n  for (let i = 0; i < str.length; i++) {\n    dv.setUint16(i * 2, str.charCodeAt(i), true); // little-endian\n  }\n  return out;\n}\n\nfunction decodeUtf16(bytes: Uint8Array): string {\n  if (bytes.length === 0) return \"\";\n  // Detect BOM\n  let be = false, offset = 0;\n  if (bytes.length >= 2) {\n    const b0 = bytes[0], b1 = bytes[1];\n    if (b0 === 0xFE && b1 === 0xFF) { be = true; offset = 2; }\n    else if (b0 === 0xFF && b1 === 0xFE) { be = false; offset = 2; }\n  }\n  const dv = new DataView(bytes.buffer, bytes.byteOffset + offset, bytes.byteLength - offset);\n  const len = dv.byteLength & ~1;\n  const codeUnits: number[] = new Array(len / 2);\n  for (let i = 0; i < len; i += 2) {\n    codeUnits[i >> 1] = dv.getUint16(i, !be);\n  }\n  // Construct string in chunks to avoid argument limits\n  let out = \"\";\n  const CHUNK = 0x8000;\n  for (let i = 0; i < codeUnits.length; i += CHUNK) {\n    out += String.fromCharCode(...codeUnits.slice(i, i + CHUNK));\n  }\n  return out;\n}\n\n/* ===== UTF-32 (LE on encode; BOM-aware on decode) ===== */\n\nfunction encodeUtf32LE(str: string): Uint8Array {\n  const cps = toCodePoints(str);\n  const out = new Uint8Array(cps.length * 4);\n  const dv = new DataView(out.buffer);\n  for (let i = 0; i < cps.length; i++) {\n    dv.setUint32(i * 4, cps[i], true);\n  }\n  return out;\n}\n\nfunction decodeUtf32(bytes: Uint8Array): string {\n  if (bytes.length === 0) return \"\";\n  // Detect BOM\n  let be = false, offset = 0;\n  if (bytes.length >= 4) {\n    const b0 = bytes[0], b1 = bytes[1], b2 = bytes[2], b3 = bytes[3];\n    // UTF-32BE BOM: 00 00 FE FF\n    if (b0 === 0x00 && b1 === 0x00 && b2 === 0xFE && b3 === 0xFF) { be = true; offset = 4; }\n    // UTF-32LE BOM: FF FE 00 00\n    else if (b0 === 0xFF && b1 === 0xFE && b2 === 0x00 && b3 === 0x00) { be = false; offset = 4; }\n  }\n  if (((bytes.length - offset) & 3) !== 0) {\n    // truncate to a multiple of 4\n    bytes = bytes.slice(0, bytes.length - ((bytes.length - offset) & 3));\n  }\n  const dv = new DataView(bytes.buffer, bytes.byteOffset + offset, bytes.byteLength - offset);\n  const cps: number[] = [];\n  for (let i = 0; i < dv.byteLength; i += 4) {\n    const cp = dv.getUint32(i, !be);\n    cps.push(sanitizeCodePoint(cp));\n  }\n  return String.fromCodePoint(...cps);\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/coreutils/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n     \"lib\": [\"DOM\", \"ES2020\"],\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": true,\n    \"allowJs\": true\n  },\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/BUILD.bazel",
    "content": "load(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nts_project(\n    name = \"drawing_web\",\n    srcs = glob([\n        \"web/**/*.ts\",\n        \"src/**/*.d.ts\",\n    ]),\n    allow_js = True,\n    composite = True,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n    deps = [\n        \"//:valdi_core_link\",\n        \"//:valdi_tsx_link\",\n    ],\n)\n\nvaldi_module(\n    name = \"drawing\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCDrawing\",\n    ios_output_target = \"release\",\n    module_yaml = \"module.yaml\",\n    single_file_codegen = False,\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":drawing_web\"],\n    web_register_native_module_id_overrides = {\n        # drawing/src/Drawing.ts does require('Drawing') to get the native provider\n        \"drawing/web/DrawingModuleProvider.js\": \"drawing/src/Drawing,Drawing\",\n    },\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/jasmine\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_test\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/module.yaml",
    "content": "output_target: release\n\nbazel_build_file_generation_disabled: true\n\ndependencies:\n  - valdi_core\n\nallowed_debug_dependencies:\n  - valdi_test\n  - jasmine\n\nexclude_patterns:\n  - .*\\/web\\/.*\nexclude_globs:\n  - \"**/web/**\"\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/AttributedTextNative.d.ts",
    "content": "import { AttributedText } from 'valdi_tsx/src/AttributedText';\n\n/**\n * @NativeClass({\n *   marshallAsUntyped: true,\n *   ios: 'SCValdiWrappedValue', iosImportPrefix: 'valdi_core',\n *   android: 'com.snapchat.client.valdi.utils.CppObjectWrapper'\n * })\n */\nexport interface AttributedTextNative {\n  __brand?: 'AttributedTextNative';\n}\n\nexport function makeNativeAttributedText(attributedText: AttributedText): AttributedTextNative;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/BitmapFactory.ts",
    "content": "import * as BitmapNative from './BitmapNative';\nimport { BitmapInfo, IBitmap, ImageEncoding } from './IBitmap';\nimport { INativeBitmap } from './INativeBitmap';\n\nclass BitmapImpl implements IBitmap {\n  constructor(readonly native: INativeBitmap) {}\n\n  getInfo(): BitmapInfo {\n    return BitmapNative.getNativeBitmapInfo(this.native);\n  }\n\n  dispose(): void {\n    BitmapNative.disposeNativeBitmap(this.native);\n  }\n\n  lockPixels(): ArrayBuffer {\n    return BitmapNative.lockNativeBitmap(this.native);\n  }\n\n  unlockPixels(): void {\n    BitmapNative.unlockNativeBitmap(this.native);\n  }\n\n  accessPixels<T>(cb: (view: DataView) => T): T {\n    const pixels = this.lockPixels();\n    try {\n      return cb(new DataView(pixels));\n    } finally {\n      this.unlockPixels();\n    }\n  }\n\n  encode(encoding: ImageEncoding, quality: number): ArrayBuffer {\n    return BitmapNative.encodeNativeBitmap(this.native, encoding, quality);\n  }\n}\n\n/**\n * Create a new blank writable bitmap with the given bitmap info.\n * This will allocate the underlying bitmap buffer.\n */\nexport function createBitmap(info: BitmapInfo): IBitmap {\n  return new BitmapImpl(\n    BitmapNative.createNativeBitmap(info.width, info.height, info.colorType, info.alphaType, info.rowBytes, undefined),\n  );\n}\n\n/**\n * Create a new bitmap which will write into the given buffer.\n */\nexport function createBitmapWithBuffer(info: BitmapInfo, buffer: ArrayBuffer): IBitmap {\n  return new BitmapImpl(\n    BitmapNative.createNativeBitmap(info.width, info.height, info.colorType, info.alphaType, info.rowBytes, buffer),\n  );\n}\n\nexport function wrapBitmap(native: INativeBitmap): IBitmap {\n  return new BitmapImpl(native);\n}\n\n/**\n * Returns a new bitmap by decoding the given image data provided as a base64 string\n * or as a buffer.\n */\nexport function decodeBitmap(data: string | Uint8Array | ArrayBuffer): IBitmap {\n  return new BitmapImpl(BitmapNative.decodeNativeBitmap(data));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/BitmapNative.d.ts",
    "content": "import { BitmapAlphaType, BitmapColorType, BitmapInfo, ImageEncoding } from './IBitmap';\nimport { INativeBitmap } from './INativeBitmap';\n\nexport function createNativeBitmap(\n  width: number,\n  height: number,\n  colorType: BitmapColorType,\n  alphaType: BitmapAlphaType,\n  rowBytes: number,\n  buffer: ArrayBuffer | undefined,\n): INativeBitmap;\n\nexport function decodeNativeBitmap(data: string | Uint8Array | ArrayBuffer): INativeBitmap;\n\nexport function disposeNativeBitmap(bitmap: INativeBitmap): void;\n\nexport function encodeNativeBitmap(bitmap: INativeBitmap, encoding: ImageEncoding, quality: number): ArrayBuffer;\n\nexport function lockNativeBitmap(bitmap: INativeBitmap): ArrayBuffer;\nexport function unlockNativeBitmap(bitmap: INativeBitmap): void;\n\nexport function getNativeBitmapInfo(bitmap: INativeBitmap): BitmapInfo;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/Drawing.ts",
    "content": "import { RequireFunc } from 'valdi_core/src/IModuleLoader';\nimport { DrawingModuleProvider } from './DrawingModuleProvider';\n\n\ndeclare const require: RequireFunc;\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\nexport const Drawing = (require('Drawing') as DrawingModuleProvider).Drawing;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/DrawingModuleProvider.d.ts",
    "content": "import { AttributedTextNative } from './AttributedTextNative';\n\n/**\n * @ExportModel({ios: 'SCValdiDrawingFontSpecs', android: 'com.snap.valdi.modules.drawing.FontSpecs'})\n */\nexport interface FontSpecs {\n  font: string;\n  lineHeight?: number;\n}\n\n/**\n * @ExportModel({ios: 'SCValdiDrawingSize', android: 'com.snap.valdi.modules.drawing.Size'})\n */\nexport interface Size {\n  width: number;\n  height: number;\n}\n\n/**\n * @ExportEnum({ios: 'SCValdiDrawingFontWeight', android: 'com.snap.valdi.modules.drawing.FontWeight'})\n */\nexport const enum FontWeight {\n  LIGHT = 'light',\n  NORMAL = 'normal',\n  MEDIUM = 'medium',\n  DEMI_BOLD = 'demi-bold',\n  BOLD = 'bold',\n  BLACK = 'black',\n}\n\n/**\n * @ExportEnum({ios: 'SCValdiDrawingFontStyle', android: 'com.snap.valdi.modules.drawing.FontStyle'})\n */\nexport const enum FontStyle {\n  NORMAL = 'normal',\n  ITALIC = 'italic',\n}\n\n/**\n * @ExportProxy({ios: 'SCValdiDrawingFont', android: 'com.snap.valdi.modules.drawing.Font'})\n */\nexport interface Font {\n  measureText(text: string, maxWidth?: number, maxHeight?: number, maxLines?: number): Size;\n  measureAttributedText(\n    attributedText: AttributedTextNative,\n    maxWidth?: number,\n    maxHeight?: number,\n    maxLines?: number,\n  ): Size;\n}\n\n/**\n * @ExportProxy({android: 'com.snap.valdi.modules.drawing.DrawingModule', ios: 'SCValdiDrawingModule'})\n */\nexport interface DrawingModule {\n  getFont(specs: FontSpecs): Font;\n  isFontRegistered(fontName: string): boolean;\n  registerFont(fontName: string, weight: FontWeight, style: FontStyle, filename: string): void;\n}\n\nexport interface DrawingModuleProvider {\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  Drawing: DrawingModule;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/FontManager.ts",
    "content": "import { IFontProvider } from 'valdi_tsx/src/IFontProvider';\nimport { FontStyle, FontWeight } from './DrawingModuleProvider';\nimport {\n  IFontManagerNative,\n  getDefaultFontManager,\n  makeScopedFontManager,\n  registerFontFromData,\n  registerFontFromFilePath,\n} from './FontManagerNative';\n\nlet cachedDefault: FontManager | undefined = undefined;\n\nexport class FontManager {\n  private constructor(readonly native: IFontManagerNative) {}\n\n  /**\n   * Return the IFontProvider instance suitable to pass as the `fontProvider`\n   * attribute of the lottie element.\n   */\n  get fontProvider(): IFontProvider {\n    return this.native;\n  }\n\n  /**\n   * Returns the default font manager associated with the runtime\n   */\n  static getDefault(): FontManager {\n    if (!cachedDefault) {\n      cachedDefault = new FontManager(getDefaultFontManager());\n    }\n    return cachedDefault;\n  }\n\n  /**\n   * Creates a scoped font manager from the given font manager instance.\n   * Any registered fonts within the returned scoped font manager will impact\n   * the scoped font manager only. The returned instance will inherit the fonts\n   * from its parent font manager\n   */\n  makeScoped(): FontManager {\n    return new FontManager(makeScopedFontManager(this.native));\n  }\n\n  /**\n   * Registers a font into the font manager from bytes representing the font data\n   */\n  registerFontFromData(fontName: string, weight: FontWeight, style: FontStyle, fontData: Uint8Array): void {\n    registerFontFromData(this.native, fontName, weight, style, fontData);\n  }\n\n  /**\n   * Registers a font into the font manager from bytes from a file path\n   */\n  registerFontFromFilePath(fontName: string, weight: FontWeight, style: FontStyle, filePath: string): void {\n    registerFontFromFilePath(this.native, fontName, weight, style, filePath);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/FontManagerNative.d.ts",
    "content": "import { IFontProvider } from 'valdi_tsx/src/IFontProvider';\nimport { FontStyle, FontWeight } from './DrawingModuleProvider';\n\n/**\n * @NativeClass({\n *   marshallAsUntyped: true,\n *   ios: 'SCValdiSnapDrawingFontManager', iosImportPrefix: 'valdi_core',\n *   android: 'com.snap.valdi.snapdrawing.SnapDrawingFontManager'\n * })\n */\nexport interface IFontManagerNative extends IFontProvider {}\n\nexport function getDefaultFontManager(): IFontManagerNative;\n\nexport function makeScopedFontManager(fontManager: IFontManagerNative): IFontManagerNative;\n\nexport function registerFontFromData(\n  fontManager: IFontManagerNative,\n  fontName: string,\n  weight: FontWeight,\n  style: FontStyle,\n  fontData: Uint8Array,\n): void;\n\nexport function registerFontFromFilePath(\n  fontManager: IFontManagerNative,\n  fontName: string,\n  weight: FontWeight,\n  style: FontStyle,\n  filePath: string,\n): void;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/IBitmap.d.ts",
    "content": "import { INativeBitmap } from './INativeBitmap';\n\nexport const enum BitmapColorType {\n  UNKNOWN = 0,\n  RGBA8888,\n  BGRA8888,\n  Alpha8,\n  Gray8,\n  RGBAF16,\n  RGBAF32,\n}\n\nexport const enum BitmapAlphaType {\n  OPAQUE = 0,\n  Premul,\n  Unpremul,\n}\n\nexport interface BitmapInfo {\n  width: number;\n  height: number;\n  colorType: BitmapColorType;\n  alphaType: BitmapAlphaType;\n  rowBytes: number;\n}\n\nexport const enum ImageEncoding {\n  JPG = 0,\n  PNG = 1,\n  WEB = 2,\n}\n\nexport interface IBitmap {\n  native: INativeBitmap;\n\n  dispose(): void;\n\n  getInfo(): BitmapInfo;\n\n  lockPixels(): ArrayBuffer;\n  unlockPixels(): void;\n\n  accessPixels<T>(cb: (view: DataView) => T): T;\n\n  encode(encoding: ImageEncoding, quality: number): ArrayBuffer;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/IManagedContext.d.ts",
    "content": "import { IRenderer } from 'valdi_core/src/IRenderer';\nimport { Size } from './DrawingModuleProvider';\nimport { IBitmap } from './IBitmap';\nimport type { Rect } from './ManagedContextNative';\n\nexport type { Rect };\n\nexport const enum MeasureMode {\n  UNSPECIFIED = 0,\n  EXACTLY = 1,\n  AT_MOST = 2,\n}\n\nexport interface RasterResult {\n  damageRects: Rect[];\n}\n\nexport interface IManagedContextDrawResult {\n  frame: IManagedContextFrame;\n  mainThreadMs: number;\n}\n\nexport interface IManagedContextAssetsLoadResult {\n  loadedAssetsCount: number;\n  errors: string[] | undefined;\n}\n\nexport interface IManagedContext {\n  /**\n   * Return the underlying Renderer managed by this ManagedContext\n   */\n  renderer: IRenderer;\n\n  /**\n   * Starts a render and evaluate the given render function\n   */\n  render(renderFunc: () => void): void;\n\n  /**\n   * Measure the context with the given max size and return\n   * a size that fits within the size constraint.\n   * When using the async path, measurement is dispatched to the main thread.\n   * If the context is disposed before completion (async path), the promise still resolves with { width: 0, height: 0 }.\n   */\n  measure(maxWidth: number, widthMode: MeasureMode, maxHeight: number, heightMode: MeasureMode, rtl: boolean): Promise<Size>;\n\n  /**\n   * Set the layout specifications of the tree.\n   * When using the async path, layout is dispatched to the main thread.\n   * If the context is disposed before completion (async path), the promise still resolves (no-op).\n   */\n  layout(width: number, height: number, rtl: boolean): Promise<void>;\n\n  /**\n   * Draw the rendered tree with the previously provided layout specs.\n   * Return a frame that contains the instructions that represents the scene.\n   * When using the async path, draw is dispatched to the main thread.\n   * If the context is disposed before completion (async path), the promise still resolves with an empty frame.\n   */\n  draw(): Promise<IManagedContextDrawResult>;\n\n  /**\n   * Schedule a callback to be called when all the assets have been loaded.\n   */\n  onAllAssetsLoaded(): Promise<IManagedContextAssetsLoadResult>;\n\n  /**\n   * Destroy the managed context and its associated resources\n   */\n  dispose(): void;\n}\n\nexport interface IManagedContextFrame {\n  /**\n   * Immediately dispose the frame and its associated resources\n   */\n  dispose(): void;\n\n  /**\n   * Rasterize the frame into a bitmap provided as an array buffer.\n   */\n  rasterInto(bitmap: IBitmap, shouldClearBitmapBeforeDrawing: boolean): RasterResult;\n\n  /**\n   * Rasterize the frame into a bitmap provided as an array buffer.\n   * Only the areas that have changed since the last rasterization will be rasterized.\n   */\n  rasterDeltaInto(bitmap: IBitmap): RasterResult;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/INativeBitmap.d.ts",
    "content": "// @NativeInterface({marshallAsUntyped: true, ios: 'SCValdiBitmap', iosImportPrefix: 'valdi_core', android: 'com.snap.valdi.IBitmap'})\nexport interface INativeBitmap {\n  brand?: 'INativeBitmap';\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/ManagedContextAssetTracker.ts",
    "content": "interface AssetState {\n  next: AssetState | undefined;\n  prev: AssetState | undefined;\n  loaded: boolean;\n  error: string | undefined;\n}\n\nexport class ManagedContextAssetTracker {\n  get assetsCount(): number {\n    return this._assetCount;\n  }\n\n  private assetStateById: { [key: number]: AssetState } = {};\n  private _assetCount = 0;\n  private onAllAssetsLoadedCallbacks: (() => void)[] = [];\n  private assetStateRoot: AssetState | undefined = undefined;\n\n  collectErrors(): string[] | undefined {\n    let errors: string[] | undefined;\n    let current = this.assetStateRoot;\n    while (current) {\n      if (current.error) {\n        if (!errors) {\n          errors = [];\n        }\n        errors.push(current.error);\n      }\n      current = current.next;\n    }\n\n    return errors;\n  }\n\n  onAllAssetsLoaded(cb: () => void): void {\n    this.onAllAssetsLoadedCallbacks.push(cb);\n    this.flushAllAssetsLoadedIfNeeded();\n  }\n\n  private removeAssetState(assetState: AssetState) {\n    const prev = assetState.prev;\n    const next = assetState.next;\n\n    if (prev) {\n      prev.next = next;\n    }\n    if (next) {\n      next.prev = prev;\n    }\n\n    this._assetCount--;\n\n    if (assetState === this.assetStateRoot) {\n      this.assetStateRoot = assetState.next;\n    }\n\n    assetState.prev = undefined;\n    assetState.next = undefined;\n  }\n\n  private appendAssetState(assetState: AssetState) {\n    this._assetCount++;\n\n    if (this.assetStateRoot) {\n      this.assetStateRoot.prev = assetState;\n      assetState.next = this.assetStateRoot;\n    }\n\n    this.assetStateRoot = assetState;\n  }\n\n  private areAllAssetsLoaded(): boolean {\n    let current = this.assetStateRoot;\n    while (current) {\n      if (!current.loaded && !current.error) {\n        return false;\n      }\n      current = current.next;\n    }\n\n    return true;\n  }\n\n  private flushAllAssetsLoadedIfNeeded() {\n    if (this.areAllAssetsLoaded() && this.onAllAssetsLoadedCallbacks.length > 0) {\n      const callbacks = this.onAllAssetsLoadedCallbacks;\n      this.onAllAssetsLoadedCallbacks = [];\n      for (const callback of callbacks) {\n        callback();\n      }\n    }\n  }\n\n  onBeganRequestingLoadedAsset(viewNode: number): void {\n    let existingState = this.assetStateById[viewNode];\n    if (existingState) {\n      this.removeAssetState(existingState);\n    }\n    const newAssetState: AssetState = { prev: undefined, next: undefined, loaded: false, error: undefined };\n    this.assetStateById[viewNode] = newAssetState;\n\n    this.appendAssetState(newAssetState);\n\n    this.flushAllAssetsLoadedIfNeeded();\n  }\n\n  onEndRequestingLoadedAsset(viewNode: number): void {\n    let existingState = this.assetStateById[viewNode];\n    delete this.assetStateById[viewNode];\n\n    if (existingState) {\n      this.removeAssetState(existingState);\n    }\n\n    this.flushAllAssetsLoadedIfNeeded();\n  }\n\n  onLoadedAssetChanged(viewNode: number, error: string | undefined): void {\n    let existingState = this.assetStateById[viewNode];\n\n    if (!existingState) {\n      return;\n    }\n\n    existingState.loaded = !error;\n    existingState.error = error;\n\n    this.flushAllAssetsLoadedIfNeeded();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/ManagedContextFactory.ts",
    "content": "import { ValdiRuntime } from 'valdi_core/src/ValdiRuntime';\nimport { IRenderer } from 'valdi_core/src/IRenderer';\nimport { jsx } from 'valdi_core/src/JSXBootstrap';\nimport { Renderer } from 'valdi_core/src/Renderer';\nimport { Size } from './DrawingModuleProvider';\nimport { IBitmap } from './IBitmap';\nimport { IManagedContext, IManagedContextAssetsLoadResult, IManagedContextDrawResult, IManagedContextFrame, MeasureMode, RasterResult } from './IManagedContext';\nimport { ManagedContextAssetTracker } from './ManagedContextAssetTracker';\nimport {\n  AssetTrackerEventType,\n  SnapDrawingValdiContext,\n  SnapDrawingFrameNative,\n  createValdiContextWithSnapDrawing,\n  destroyValdiContextWithSnapDrawing,\n  disposeFrame,\n  drawFrame,\n  drawFrameSync,\n  layoutAsync,\n  measureAsync,\n  rasterFrame,\n} from './ManagedContextNative';\n\ndeclare const runtime: ValdiRuntime;\n\nclass FrameImpl implements IManagedContextFrame {\n  constructor(readonly native: SnapDrawingFrameNative) {}\n\n  dispose(): void {\n    disposeFrame(this.native);\n  }\n\n  rasterInto(bitmap: IBitmap, shouldClearBitmapBeforeDrawing: boolean): RasterResult {\n    const damageRects = rasterFrame(this.native, bitmap.native, shouldClearBitmapBeforeDrawing, false);\n    return { damageRects };\n  }\n\n  rasterDeltaInto(bitmap: IBitmap): RasterResult {\n    const damageRects = rasterFrame(this.native, bitmap.native, false, true);\n    return { damageRects };\n  }\n}\n\nclass ManagedContextImpl implements IManagedContext {\n  renderer: IRenderer;\n\n  private snapDrawingValdiContext: SnapDrawingValdiContext;\n  private contextId: string;\n  private _renderer: Renderer;\n  private assetTracker: ManagedContextAssetTracker;\n  private readonly useAsyncPath: boolean;\n\n  constructor(\n    useNewExternalSurfaceRasterMethod: boolean,\n    enableDeltaRasterization: boolean,\n    useAsyncPath: boolean,\n  ) {\n    this.useAsyncPath = useAsyncPath;\n    this.snapDrawingValdiContext = createValdiContextWithSnapDrawing(\n      useNewExternalSurfaceRasterMethod,\n      enableDeltaRasterization,\n      (eventType, nodeId, error) => {\n        console.log('Event asset event', eventType, nodeId);\n        this.processAssetEvent(eventType, nodeId, error);\n      },\n    );\n    this.contextId = this.snapDrawingValdiContext.contextId;\n    this._renderer = jsx.makeRenderer(this.contextId);\n    this.renderer = this._renderer;\n    this.assetTracker = new ManagedContextAssetTracker();\n  }\n\n  private processAssetEvent(eventType: AssetTrackerEventType, nodeId: number, error: string | undefined) {\n    switch (eventType) {\n      case AssetTrackerEventType.beganRequestingLoadedAsset:\n        this.assetTracker.onBeganRequestingLoadedAsset(nodeId);\n        break;\n      case AssetTrackerEventType.endRequestingLoadedAsset:\n        this.assetTracker.onEndRequestingLoadedAsset(nodeId);\n        break;\n      case AssetTrackerEventType.loadedAssetChange:\n        this.assetTracker.onLoadedAssetChanged(nodeId, error);\n        break;\n    }\n  }\n\n  render(renderFunc: () => void): void {\n    this._renderer.renderRoot(renderFunc);\n  }\n\n  measure(maxWidth: number, widthMode: MeasureMode, maxHeight: number, heightMode: MeasureMode, rtl: boolean): Promise<Size> {\n    if (this.useAsyncPath) {\n      return new Promise(resolve => {\n        measureAsync(\n          this.snapDrawingValdiContext.native,\n          maxWidth,\n          widthMode,\n          maxHeight,\n          heightMode,\n          rtl,\n          (width: number, height: number) => {\n            resolve({ width, height });\n          },\n        );\n      });\n    }\n    // Sync path: use runtime.measureContext directly (same as original implementation; no native module dispatch).\n    const result = runtime.measureContext(\n      this.contextId,\n      maxWidth,\n      widthMode,\n      maxHeight,\n      heightMode,\n      rtl,\n    );\n    return Promise.resolve({ width: result[0], height: result[1] });\n  }\n\n  layout(width: number, height: number, rtl: boolean): Promise<void> {\n    if (this.useAsyncPath) {\n      return new Promise(resolve => {\n        layoutAsync(this.snapDrawingValdiContext.native, width, height, rtl, () => {\n          resolve();\n        });\n      });\n    }\n    // Sync path: use runtime.setLayoutSpecs directly (same as original implementation).\n    runtime.setLayoutSpecs(this.contextId, width, height, rtl);\n    return Promise.resolve();\n  }\n\n  draw(): Promise<IManagedContextDrawResult> {\n    if (this.useAsyncPath) {\n      return new Promise(resolve => {\n        drawFrame(\n          this.snapDrawingValdiContext.native,\n          (frameNative: SnapDrawingFrameNative, mainThreadMs: number) => {\n            resolve({ frame: new FrameImpl(frameNative), mainThreadMs });\n          },\n        );\n      });\n    }\n    const frameNative = drawFrameSync(this.snapDrawingValdiContext.native);\n    return Promise.resolve({\n      frame: new FrameImpl(frameNative),\n      mainThreadMs: 0,\n    });\n  }\n\n  onAllAssetsLoaded(): Promise<IManagedContextAssetsLoadResult> {\n    return new Promise(resolve => {\n      this.assetTracker.onAllAssetsLoaded(() => {\n        const errors = this.assetTracker.collectErrors();\n        resolve({ loadedAssetsCount: this.assetTracker.assetsCount, errors });\n      });\n    });\n  }\n\n  dispose(): void {\n    this._renderer.delegate.onDestroyed();\n    this._renderer.renderRoot(() => {});\n    destroyValdiContextWithSnapDrawing(this.snapDrawingValdiContext.native);\n  }\n}\n\n/**\n * Defines how embedded platform views are rasterized. Embedded platform views are views\n * that are not natively implemented by SnapDrawing, for example like <textview> or\n * <textfield> or any other native view provided through the <custom-view> element.\n */\nexport const enum EmbeddedPlatformViewRasterMethod {\n  /**\n   * The native view will be rasterized using its frame size. If it has a transform (scale, rotation)\n   * set on the view or one of its ancestors, the transform will be applied post rasterization.\n   * The native view is only redrawn when one of its properties changes. This system results in high\n   * draw cache hit rate, but will result in a potentially lower quality image when using transformation.\n   */\n  FAST = 0,\n\n  /**\n   * The native view will be rasterized into the final output buffer with its final transform (scale, rotation)\n   * applied. It will be rasterized again every time scale, rotation, translation or frame changes,  or if\n   * one of its properties changes. This system results in a highly accurate rasterization of the native view,\n   *  but will result in a potentially lower draw cache hit rate and more expensive rasterization.\n   */\n  ACCURATE = 1,\n}\n\nexport interface IManagedContextOptions {\n  embeddedPlatformViewRasterMethod?: EmbeddedPlatformViewRasterMethod;\n  deltaRasterization?: boolean;\n  /**\n   * When false or unset (default, control), use sync path. When true (treatment), use async path.\n   * AB test: compare deadlock rate and performance; CoF MANAGED_CONTEXT_USE_ASYNC.\n   */\n  useAsyncPath?: boolean;\n}\n\n/**\n * Create a new IManagedContext that can be used to render a detached Valdi tree\n */\nexport function createManagedContext(options?: IManagedContextOptions): IManagedContext {\n  const useNewExternalSurfaceRasterMethod =\n    options?.embeddedPlatformViewRasterMethod === EmbeddedPlatformViewRasterMethod.ACCURATE;\n  const enableDeltaRasterization = options?.deltaRasterization ?? false;\n  const useAsyncPath = options?.useAsyncPath ?? false;\n  return new ManagedContextImpl(useNewExternalSurfaceRasterMethod, enableDeltaRasterization, useAsyncPath);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/src/ManagedContextNative.d.ts",
    "content": "import { INativeBitmap } from './INativeBitmap';\n\nexport interface SnapDrawingValdiContextNative {\n  brand?: 'SnapDrawingValdiContextNative';\n}\n\nexport interface SnapDrawingFrameNative {\n  brand?: 'SnapDrawingFrameNative';\n}\n\nexport interface SnapDrawingValdiContext {\n  contextId: string;\n  native: SnapDrawingValdiContextNative;\n}\n\nexport const enum AssetTrackerEventType {\n  beganRequestingLoadedAsset = 1,\n  endRequestingLoadedAsset = 2,\n  loadedAssetChange = 3,\n}\n\nexport type AssetTrackerCallback = (\n  eventType: AssetTrackerEventType,\n  nodeId: number,\n  error: string | undefined,\n) => void;\n\nexport function createValdiContextWithSnapDrawing(\n  useNewExternalSurfaceRasterMethod: boolean,\n  enableDeltaRasterization: boolean,\n  assetTrackerCallback: AssetTrackerCallback,\n): SnapDrawingValdiContext;\n\nexport function destroyValdiContextWithSnapDrawing(native: SnapDrawingValdiContextNative): void;\n\nexport function measureAsync(\n  native: SnapDrawingValdiContextNative,\n  maxWidth: number,\n  widthMode: number,\n  maxHeight: number,\n  heightMode: number,\n  rtl: boolean,\n  callback: (width: number, height: number) => void,\n): void;\n\nexport function layoutAsync(\n  native: SnapDrawingValdiContextNative,\n  width: number,\n  height: number,\n  rtl: boolean,\n  callback: () => void,\n): void;\n\nexport function drawFrame(\n  native: SnapDrawingValdiContextNative,\n  callback: (frame: SnapDrawingFrameNative, mainThreadMs: number) => void,\n): void;\n\nexport function drawFrameSync(native: SnapDrawingValdiContextNative): SnapDrawingFrameNative;\n\nexport function disposeFrame(native: SnapDrawingFrameNative): void;\n\n/**\n * @ExportModel({\n *   ios: 'SCDrawingRect',\n *   android: 'com.snap.drawing.Rect'\n * })\n */\nexport interface Rect {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n}\n\nexport function rasterFrame(\n  native: SnapDrawingFrameNative,\n  bitmapNative: INativeBitmap,\n  shouldClearBitmapBeforeDrawing: boolean,\n  deltaRasterization: boolean,\n): Rect[];\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/test/ManagedContextAssetTracker.spec.ts",
    "content": "import { ManagedContextAssetTracker } from 'drawing/src/ManagedContextAssetTracker';\n\nimport 'jasmine/src/jasmine';\n\ndescribe('ManagedContextAssetTracker', () => {\n  it('can collect errors', () => {\n    const assetTracker = new ManagedContextAssetTracker();\n\n    assetTracker.onBeganRequestingLoadedAsset(1);\n    assetTracker.onBeganRequestingLoadedAsset(2);\n\n    expect(assetTracker.collectErrors()).toBeUndefined();\n\n    assetTracker.onLoadedAssetChanged(1, 'It failed');\n\n    expect(assetTracker.collectErrors()).toEqual(['It failed']);\n\n    assetTracker.onLoadedAssetChanged(1, 'It failed again');\n\n    expect(assetTracker.collectErrors()).toEqual(['It failed again']);\n\n    assetTracker.onLoadedAssetChanged(2, 'This one also failed');\n\n    expect(assetTracker.collectErrors()).toEqual(['This one also failed', 'It failed again']);\n  });\n\n  it('notifies when all assets are loaded when empty', () => {\n    const assetTracker = new ManagedContextAssetTracker();\n    let called = false;\n\n    assetTracker.onAllAssetsLoaded(() => {\n      called = true;\n    });\n\n    expect(called).toBeTrue();\n  });\n\n  it('notifies when all assets are loaded', () => {\n    const assetTracker = new ManagedContextAssetTracker();\n\n    let called = false;\n\n    assetTracker.onBeganRequestingLoadedAsset(1);\n    assetTracker.onAllAssetsLoaded(() => {\n      called = true;\n    });\n\n    expect(called).toBeFalse();\n\n    assetTracker.onBeganRequestingLoadedAsset(2);\n    assetTracker.onBeganRequestingLoadedAsset(3);\n\n    expect(called).toBeFalse();\n\n    assetTracker.onLoadedAssetChanged(3, undefined);\n\n    expect(called).toBeFalse();\n\n    assetTracker.onLoadedAssetChanged(1, undefined);\n\n    expect(called).toBeFalse();\n\n    assetTracker.onLoadedAssetChanged(2, undefined);\n\n    expect(called).toBeTrue();\n  });\n\n  it('notifies when all assets are loaded after cancelation', () => {\n    const assetTracker = new ManagedContextAssetTracker();\n    let called = false;\n\n    assetTracker.onBeganRequestingLoadedAsset(1);\n    assetTracker.onBeganRequestingLoadedAsset(2);\n    assetTracker.onBeganRequestingLoadedAsset(3);\n\n    assetTracker.onAllAssetsLoaded(() => {\n      called = true;\n    });\n    expect(called).toBeFalse();\n\n    assetTracker.onLoadedAssetChanged(3, undefined);\n    assetTracker.onLoadedAssetChanged(1, undefined);\n\n    expect(called).toBeFalse();\n\n    assetTracker.onEndRequestingLoadedAsset(2);\n\n    expect(called).toBeTrue();\n\n    assetTracker.onEndRequestingLoadedAsset(3);\n    assetTracker.onEndRequestingLoadedAsset(1);\n\n    called = false;\n    assetTracker.onAllAssetsLoaded(() => {\n      called = true;\n    });\n\n    expect(called).toBeTrue();\n\n    assetTracker.onBeganRequestingLoadedAsset(1);\n\n    called = false;\n    assetTracker.onAllAssetsLoaded(() => {\n      called = true;\n    });\n\n    expect(called).toBeFalse();\n\n    assetTracker.onEndRequestingLoadedAsset(1);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/test/ManagedContextFactory.spec.tsx",
    "content": "import { createBitmap } from 'drawing/src/BitmapFactory';\nimport { BitmapAlphaType, BitmapColorType } from 'drawing/src/IBitmap';\nimport { MeasureMode } from 'drawing/src/IManagedContext';\nimport { createManagedContext } from 'drawing/src/ManagedContextFactory';\nimport { ElementRef } from 'valdi_core/src/ElementRef';\nimport { Layout, View } from 'valdi_tsx/src/NativeTemplateElements';\n\nimport 'jasmine/src/jasmine';\nimport 'valdi_tsx/src/JSX';\n\ndescribe('ManagedContextFactory', () => {\n  it('can be created and destroyed', () => {\n    const context = createManagedContext();\n    expect(context.renderer.getRootVirtualNode()).toBeUndefined();\n\n    context.render(() => {\n      <view />;\n    });\n\n    expect(context.renderer.getRootVirtualNode()).not.toBeUndefined();\n    expect(context.renderer.getRootVirtualNode()?.element).not.toBeUndefined();\n    context.dispose();\n    expect(context.renderer.getRootVirtualNode()).toBeUndefined();\n  });\n\n  it('can layout', async () => {\n    const context = createManagedContext();\n\n    const roofRef = new ElementRef<Layout>();\n    const viewRef = new ElementRef<View>();\n    context.render(() => {\n      <layout ref={roofRef} width={'100%'} height={'100%'} padding={16} alignItems=\"stretch\" alignContent=\"stretch\">\n        <view ref={viewRef} flexGrow={1} />\n      </layout>;\n    });\n\n    await context.layout(100, 100, false);\n\n    expect(roofRef.single()?.frame).toEqual({\n      width: 100,\n      height: 100,\n      x: 0,\n      y: 0,\n    });\n\n    expect(viewRef.single()?.frame).toEqual({\n      width: 68,\n      height: 68,\n      x: 16,\n      y: 16,\n    });\n\n    context.dispose();\n  });\n\n  it('can measure', async () => {\n    const context = createManagedContext();\n    context.render(() => {\n      <layout padding={20} alignItems=\"stretch\" alignContent=\"stretch\">\n        <view width={40} height={30} />\n      </layout>;\n    });\n\n    const result = await context.measure(1000, MeasureMode.AT_MOST, 1000, MeasureMode.AT_MOST, false);\n\n    expect(result).toEqual({ width: 80, height: 70 });\n  });\n\n  it('can draw', async () => {\n    const context = createManagedContext();\n    context.render(() => {\n      <view width={2} height={2} flexDirection=\"column\">\n        <layout flexDirection=\"row\">\n          <view width={1} height={1} backgroundColor=\"rgba(255, 0, 0, 1.0)\" />\n          <view width={1} height={1} backgroundColor=\"rgba(0, 255, 0, 1.0)\" />\n        </layout>\n        <layout flexDirection=\"row\">\n          <view width={1} height={1} backgroundColor=\"rgba(0, 0, 255, 1.0)\" />\n          <view width={1} height={1} backgroundColor=\"rgba(255, 255, 255, 1.0)\" />\n        </layout>\n      </view>;\n    });\n\n    await context.layout(2, 2, false);\n\n    const { frame } = await context.draw();\n    const bitmap = createBitmap({\n      width: 2,\n      height: 2,\n      colorType: BitmapColorType.RGBA8888,\n      alphaType: BitmapAlphaType.OPAQUE,\n      rowBytes: 2 * 4,\n    });\n\n    frame.rasterInto(bitmap, true);\n\n    const { byteLength, topLeftPixel, topRightPixel, bottomLeftPixel, bottomRightPixel } = bitmap.accessPixels(\n      pixels => {\n        const byteLength = pixels.byteLength;\n        const topLeftPixel = pixels.getUint32(0);\n        const topRightPixel = pixels.getUint32(4);\n        const bottomLeftPixel = pixels.getUint32(8);\n        const bottomRightPixel = pixels.getUint32(12);\n        return { byteLength, topLeftPixel, topRightPixel, bottomLeftPixel, bottomRightPixel };\n      },\n    );\n\n    expect(byteLength).toBe(16);\n\n    expect(topLeftPixel).toBe(0xff0000ff);\n    expect(topRightPixel).toBe(0x00ff00ff);\n    expect(bottomLeftPixel).toBe(0x0000ffff);\n    expect(bottomRightPixel).toBe(0xffffffff);\n\n    frame.dispose();\n    context.dispose();\n  });\n\n  it('can observe asset load', async () => {\n    const image =\n      'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEkAAAA7CAYAAAA3macWAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAASaADAAQAAAABAAAAOwAAAACp5RezAAAEs0lEQVR4Ae2azY8URRiHGUFBYqIsgp8kBggaL3owJoZE44GokKgXLya4ZEXgICfix1+gRw2iETRGQEk8KDGc96YiiigXkKhwRfCDj6BiTJbnIdPLOtP99uzszNDVu2/yS3XVW11d75Oq6uqamTWr4jY2NrYaHUTHmvqMdMkgu90Y5MMm+yxgLOWefWhOy72nyD/XaDROtJT3JXtNX1rtXaOraKoVkK0vRrubEM331aoOaW4Q/SJ8uwYBquqQvg0g6RoIqEpDYs3ZD4jPOwDV16lX6YVbOEyn2SRvoMfMB/YbvrWAPR7U6cpVeUhGBSgX7zeRC3lkgvKt90tUabK+JCAZFKCuJXkLPWo+sN/xOaJ6BioZSEJpgnqby0fMByYoR9TPQZ2OXUlBMipAXUfyLlppPrCegUoOklAA5f5pO3rIfGCCGmZE/RTUKXUlCcmoADWP5D30oPnA/sDn1OsaVLKQhAKo60neRw+YD2xKoCq9mQyCvuxidPzNxQZ0sKTuEH4/YVaU1Mt1Jw3JiAB1gWQEjZoPTFA7uwGVPCShAOoiyYvoU/OBZaDuDuq0uZJek9qioYCRsoXEKRiZa9Q64B6LKmW+2kEyMECtI3kVRfH9iV9QP5KGFjUS3lh1J6CepI+vo7xDu6z7HYGqLSQpAOphkq3IrUKRlYKqNSSpAOo+kh3oJvMFdoZyd+a5U6/2kIQCqGUkH6BbzReYoFyjjrb6pwUkgwaUgAQlsCLLBVWLfVJRxBPLGSEnyT+LDk8sb7l2SrrhvHdi+fhIwuGh1kLkcWnKNkbn/Vw5D5j/WgMhThdxF3MX9SI7i8Opd8QKDW4SyktIyh5B1MmEdQ6dbyq7/ou8WwRPEopsHJSQNlPLLf2MtRM4TdETrknPtPtmSpoEFpGuEdLQDJKQwGIh9exXhfBR6TqPCMmV3jfCjLUT+Jqi0ctbABZvD9SH0W2oDluAf4gje5P5ZvM6y5vegF5B81GR/YBjhG3AhfF9UlHNupUzINxxl32ifE+d5wVk/E63aWMAup9g96DoG+5/gIQzbSAByF99P0R+ehTZIRzjIyirNC0gAegpAn4HRedKAlqfTbEMkGnt1yQAjRDnyyWxfof/hTxAlNcbEoB8gwkpMgE5gvyey7VajiTguI15DT2dG/WVQn/UdAQVArJq7SAByC/7rciFOrKOANlArSAB6EZi8jzbV31kHQOykdpAAlAnx7PGLCDXIM+aOrJabAEA5C76E2QamX95nhQgG0t+JAHoHuLYiaJNorF+gzZMZgR5k5Y0JAD5V5pdaIHBBNY1INtMFhKAltP/3WjIQAI7gG9jNyMoazNJSABaSgACujkLpCAVkFPMo5OuLbmFG0B3Ea1rUBkgD8ymDIg20ppuAFpCnz9Gt9j5wATkFJvSCMraT2YkAehOOu0UKwO0v5eABJXEmgSg2+nrR+gOOx1YBsi/B/bMKg8JQI4cp5hTLbKvcG5iivUUkA+sNCQA+bP7XlS2k+4bICFVfU16/GoDSgFS2Qj6kiD6MsWEk1n0p8usztVMTwYPzwD9G9Tpiavq020fUf6aE+kXlDmC+g4o59nVK3J/hLahA2gUbUYDnQGXAGz/ceUh+eOJAAAAAElFTkSuQmCC';\n    const context = createManagedContext();\n    context.render(() => {\n      <view width={100} height={100} flexDirection=\"column\">\n        <image width={'100%'} height={'100%'} src={image} />\n      </view>;\n    });\n\n    await context.layout(100, 100, false);\n\n    const result = await context.onAllAssetsLoaded();\n    expect(result.loadedAssetsCount).toBe(1);\n    expect(result.errors).toBeUndefined();\n  });\n\n  it('can observe asset load with error', async () => {\n    const image = 'doesnotexist://whatisup';\n    const context = createManagedContext();\n    context.render(() => {\n      <view width={100} height={100} flexDirection=\"column\">\n        <image width={'100%'} height={'100%'} src={image} />\n      </view>;\n    });\n    await context.layout(100, 100, false);\n\n    const result = await context.onAllAssetsLoaded();\n    expect(result.loadedAssetsCount).toBe(1);\n    expect(result.errors).not.toBeUndefined();\n    expect(result.errors![0]).toBe(\n      \"Cannot resolve AssetLoader for URL scheme 'doesnotexist' and output type 'imageSnapDrawing'\",\n    );\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/tsconfig.json",
    "content": "{\n    \"extends\": \"../../../../../modules/_configs/base.tsconfig.json\",\n    \"compilerOptions\": {\n        \"paths\": {\n            \"drawing/*\": [\n                \"./*\"\n            ],\n            \"jasmine/*\": [\n                \"../jasmine/*\"\n            ],\n            \"coreutils/*\": [\n                \"../coreutils/*\"\n            ],\n            \"source_map/*\": [\n                \"../source_map/*\"\n            ],\n            \"valdi_tsx/*\": [\n                \"../valdi_tsx/*\"\n            ],\n            \"valdi_core/*\": [\n                \"../valdi_core/*\"\n            ],\n            \"file_system/*\": [\n                \"../file_system/*\"\n            ],\n            \"valdi_standalone/*\": [\n                \"../valdi_standalone/*\"\n            ],\n            \"valdi_test/*\": [\n                \"../valdi_test/*\",\n                \"../../../../../bazel-out/darwin_arm64-fastbuild/bin/src/valdi_modules/src/valdi/valdi_test/.valdi_build/projectsync/generated_ts/valdi_test/*\"\n            ],\n            \"tslib\": [\n                \"../valdi_core/src/tslib\"\n            ]\n        },\n        \"types\": [\n            \"../../../../../modules/types/Long\",\n            \"../../../../../modules/types/globals\"\n        ],\n        \"rootDirs\": [\n            \"..\"\n        ]\n    }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/web/BitmapNative.ts",
    "content": "import {\n  BitmapAlphaType,\n  BitmapColorType,\n  BitmapInfo,\n  ImageEncoding,\n} from \"../src/IBitmap\";\nimport { INativeBitmap } from \"../src/INativeBitmap\";\n\ntype Meta = {\n  info: BitmapInfo;\n  pixels: ArrayBuffer;\n  locked: boolean;\n};\n\nconst META = new WeakMap<INativeBitmap, Meta>();\n\nfunction bytesPerPixel(ct: BitmapColorType): number {\n  switch (ct) {\n    case BitmapColorType.RGBA8888:\n    case BitmapColorType.BGRA8888:\n      return 4;\n    case BitmapColorType.Alpha8:\n    case BitmapColorType.Gray8:\n      return 1;\n    case BitmapColorType.RGBAF16:\n      return 8;  // 4 channels * 2 bytes\n    case BitmapColorType.RGBAF32:\n      return 16; // 4 channels * 4 bytes\n    case BitmapColorType.UNKNOWN:\n    default:\n      return 4;\n  }\n}\n\nfunction ensureRowBytes(\n  rowBytes: number,\n  width: number,\n  colorType: BitmapColorType\n): number {\n  if (rowBytes && rowBytes >= width * bytesPerPixel(colorType)) return rowBytes;\n  return width * bytesPerPixel(colorType);\n}\n\nexport function createNativeBitmap(\n  width: number,\n  height: number,\n  colorType: BitmapColorType,\n  alphaType: BitmapAlphaType,\n  rowBytes: number,\n  buffer: ArrayBuffer | undefined,\n): INativeBitmap {\n  const rb = ensureRowBytes(rowBytes, width, colorType);\n  const byteLen = rb * height;\n  const pixels = buffer && buffer.byteLength >= byteLen\n    ? buffer.slice(0, byteLen)\n    : new ArrayBuffer(byteLen);\n\n  const info: BitmapInfo = { width, height, colorType, alphaType, rowBytes: rb };\n\n  const handle: INativeBitmap = { brand: \"INativeBitmap\" };\n  META.set(handle, { info, pixels, locked: false });\n  return handle;\n}\n\nexport function decodeNativeBitmap(\n  _data: string | Uint8Array | ArrayBuffer\n): INativeBitmap {\n  // Stub: return a 1x1 transparent RGBA8\n  const info: BitmapInfo = {\n    width: 1,\n    height: 1,\n    colorType: BitmapColorType.RGBA8888,\n    alphaType: BitmapAlphaType.Premul,\n    rowBytes: 4,\n  };\n  const pixels = new ArrayBuffer(4); // RGBA = 0,0,0,0\n  const handle: INativeBitmap = { brand: \"INativeBitmap\" };\n  META.set(handle, { info, pixels, locked: false });\n  return handle;\n}\n\nexport function disposeNativeBitmap(bitmap: INativeBitmap): void {\n  META.delete(bitmap);\n}\n\nexport function encodeNativeBitmap(\n  bitmap: INativeBitmap,\n  _encoding: ImageEncoding,\n  _quality: number\n): ArrayBuffer {\n  // Stub: return a copy of the pixel buffer\n  const meta = META.get(bitmap);\n  if (!meta) throw new Error(\"Invalid INativeBitmap\");\n  return meta.pixels.slice(0);\n}\n\nexport function lockNativeBitmap(bitmap: INativeBitmap): ArrayBuffer {\n  const meta = META.get(bitmap);\n  if (!meta) throw new Error(\"Invalid INativeBitmap\");\n  meta.locked = true;\n  return meta.pixels;\n}\n\nexport function unlockNativeBitmap(bitmap: INativeBitmap): void {\n  const meta = META.get(bitmap);\n  if (!meta) throw new Error(\"Invalid INativeBitmap\");\n  meta.locked = false;\n}\n\nexport function getNativeBitmapInfo(bitmap: INativeBitmap): BitmapInfo {\n  const meta = META.get(bitmap);\n  if (!meta) throw new Error(\"Invalid INativeBitmap\");\n  return meta.info;\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/web/DrawingModuleProvider.ts",
    "content": "import { FontWeight, DrawingModule, FontSpecs, Font, Size, FontStyle, DrawingModuleProvider } from \"../src/DrawingModuleProvider\";\n\nconst registered = new Set<string>();\n\nfunction getCanvas(): CanvasRenderingContext2D {\n  const canvas = document.createElement('canvas');\n  const ctx = canvas.getContext('2d');\n  if (!ctx) throw new Error('2D canvas not available');\n  return ctx;\n}\n\nfunction cssWeight(w: FontWeight): string {\n  switch (w) {\n    case FontWeight.LIGHT: return '300';\n    case FontWeight.NORMAL: return '400';\n    case FontWeight.MEDIUM: return '500';\n    case FontWeight.DEMI_BOLD: return '600';\n    case FontWeight.BOLD: return '700';\n    case FontWeight.BLACK: return '900';\n    default: return '400';\n  }\n}\n\nconst Drawing: DrawingModule = {\n  getFont(specs: FontSpecs): Font {\n    const ctx = getCanvas();\n    ctx.font = specs.font; // Caller supplies a full CSS font string\n\n    const defaultLineHeight = (() => {\n      // crude estimate if not provided: 1.2 * font-size\n      const m = /(\\d+(?:\\.\\d+)?)px/.exec(specs.font);\n      return m ? Math.ceil(parseFloat(m[1]) * 1.2) : 16;\n    })();\n    const lineHeight = specs.lineHeight ?? defaultLineHeight;\n\n    return {\n      measureText(text: string, maxWidth?: number, maxHeight?: number, maxLines?: number): Size {\n        // naive single-line; clamp to maxWidth/Height if given\n        const metrics = ctx.measureText(text);\n        let width = Math.ceil(metrics.width);\n        let height = lineHeight;\n        if (maxWidth != null) width = Math.min(width, Math.floor(maxWidth));\n        if (maxHeight != null) height = Math.min(height, Math.floor(maxHeight));\n        // ignore wrapping/maxLines in this stub\n        return { width, height };\n      },\n      measureAttributedText(attributedText: any, maxWidth?: number, maxHeight?: number, maxLines?: number): Size {\n        // TODO: Implement this properly. For now just measure the plain text.\n        const plainText = attributedText?.text || '';\n        return this.measureText(plainText, maxWidth, maxHeight, maxLines);\n      },\n    };\n  },\n\n  isFontRegistered(fontName: string): boolean {\n    return registered.has(fontName);\n  },\n\n  registerFont(fontName: string, weight: FontWeight, style: FontStyle, _filename: string): void {\n    // Stub: record the logical registration; real loading is left to the app.\n    // You could add a CSSFontFaceSet load() here if desired.\n    const key = `${fontName}:${cssWeight(weight)}:${style}`;\n    registered.add(key);\n  },\n};\n\nconst provider: DrawingModuleProvider = { Drawing };\nexport = provider;"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/web/FontManagerNative.ts",
    "content": "import { IFontProvider } from 'valdi_tsx/src/IFontProvider';\nimport { FontStyle, FontWeight } from '../src/DrawingModuleProvider';\nimport { IFontManagerNative } from '../src/FontManagerNative';\n\n\ntype FontKey = `${string}|${FontWeight}|${FontStyle}`;\n\nconst defaultManager: IFontManagerNative = { __tag: 'IFontProvider' };\nconst registrations = new Map<FontKey, { source: 'data' | 'file'; payload: Uint8Array | string }>();\n\nexport function getDefaultFontManager(): IFontManagerNative {\n  return defaultManager;\n}\n\nexport function makeScopedFontManager(fontManager: IFontManagerNative): IFontManagerNative {\n  // Stub: return the same instance; scope isolation not modeled here.\n  return fontManager ?? defaultManager;\n}\n\nexport function registerFontFromData(\n  _fontManager: IFontManagerNative,\n  fontName: string,\n  weight: FontWeight,\n  style: FontStyle,\n  fontData: Uint8Array,\n): void {\n  const key: FontKey = `${fontName}|${weight}|${style}`;\n  registrations.set(key, { source: 'data', payload: fontData });\n}\n\nexport function registerFontFromFilePath(\n  _fontManager: IFontManagerNative,\n  fontName: string,\n  weight: FontWeight,\n  style: FontStyle,\n  filePath: string,\n): void {\n  const key: FontKey = `${fontName}|${weight}|${style}`;\n  registrations.set(key, { source: 'file', payload: filePath });\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/web/ManagedContextNative.ts",
    "content": "import { INativeBitmap } from '../src/INativeBitmap';\nimport {\n  SnapDrawingValdiContext,\n  SnapDrawingValdiContextNative,\n  SnapDrawingFrameNative,\n  AssetTrackerCallback,\n  AssetTrackerEventType,\n} from '../src/ManagedContextNative';\nimport type { Rect } from '../src/ManagedContextNative';\n\n/** Internal no-op tracker state */\nlet _nextContextId = 1;\n\n/** Make a brandy placeholder object */\nfunction makeNativeContext(): SnapDrawingValdiContextNative {\n  return { brand: 'SnapDrawingValdiContextNative' };\n}\n\n/** Make a brandy frame placeholder object */\nfunction makeFrame(): SnapDrawingFrameNative {\n  return { brand: 'SnapDrawingFrameNative' };\n}\n\nexport function createValdiContextWithSnapDrawing(\n  useNewExternalSurfaceRasterMethod: boolean,\n  assetTrackerCallback: AssetTrackerCallback,\n): SnapDrawingValdiContext {\n  // Fire a benign \"started\" and \"ended\" sequence to exercise the callback.\n  try {\n    assetTrackerCallback(AssetTrackerEventType.beganRequestingLoadedAsset, 0, undefined);\n    assetTrackerCallback(AssetTrackerEventType.endRequestingLoadedAsset, 0, undefined);\n  } catch {\n    // Intentionally swallow in stub\n  }\n\n  const id = String(_nextContextId++);\n  return {\n    contextId: id,\n    native: makeNativeContext(),\n  };\n}\n\nexport function destroyValdiContextWithSnapDrawing(_native: SnapDrawingValdiContextNative): void {\n  // no-op\n}\n\nexport function drawFrame(_native: SnapDrawingValdiContextNative): SnapDrawingFrameNative {\n  // Return a placeholder frame\n  return makeFrame();\n}\n\nexport function disposeFrame(_native: SnapDrawingFrameNative): void {\n  // no-op\n}\n\nexport function rasterFrame(\n  _native: SnapDrawingFrameNative,\n  _bitmapNative: INativeBitmap,\n  _shouldClearBitmapBeforeDrawing: boolean,\n  _deltaRasterization: boolean,\n): Rect[] {\n  // no-op - return empty damage rects array\n  return [];\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/drawing/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n     \"lib\": [\"DOM\", \"ES2020\"],\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": true,\n    \"allowJs\": true,\n  },\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/BUILD.bazel",
    "content": "load(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nts_project(\n    name = \"file_system_web\",\n    srcs = glob([\n        \"web/**/*.ts\",\n        \"src/**/*.d.ts\",\n    ]),\n    allow_js = True,\n    composite = True,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n)\n\nvaldi_module(\n    name = \"file_system\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"debug\",\n    ios_module_name = \"SCCFileSystem\",\n    ios_output_target = \"debug\",\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":file_system_web\"],\n    web_register_native_module_id_overrides = {\n        # file_system/src/FileSystem.ts does require('FileSystem')\n        \"file_system/web/FileSystem.js\": \"FileSystem\",\n    },\n    deps = [\n        \"//src/valdi_modules/src/valdi/coreutils\",\n        \"//src/valdi_modules/src/valdi/jasmine\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/README.md",
    "content": "### Valdi File System module\n\nThis module exists only for internal Valdi team usage to\nunlock integration with tools which require with file system.\nIt provides an ability to work with file system through the [C++ API](../../../../../valdi/src/valdi/runtime/JavaScript/Modules/FileSystemFactory.cpp) \n\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/module.yaml",
    "content": "output_target: debug\n\nbazel_build_file_generation_disabled: true\n\ndependencies:\n  - valdi_core\n  - coreutils\n  - jasmine\n\nexclude_patterns:\n  - .*\\/web\\/.*\nexclude_globs:\n  - \"**/web/**\"\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/src/FileSystem.ts",
    "content": "import { RequireFunc } from 'valdi_core/src/IModuleLoader';\nimport { FileSystemModule } from './FileSystemModule';\n\ndeclare const require: RequireFunc;\n\nexport const VALDI_MODULES_ROOT = './valdi_modules/src/valdi';\n\nexport const fs = require('FileSystem') as FileSystemModule;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/src/FileSystemModule.d.ts",
    "content": "export type FileEncoding = 'utf8' | 'utf16';\n\nexport interface ReadFileOptions {\n  encoding?: FileEncoding | undefined | null;\n}\n\n/**\n * Valdi File System module\n * This FS API right now is only for internal usage due to some limitations.\n * Inside Valdi, we use it mostly infrastructure things.\n * If you have any questions about the usage this module please ask in the support channel\n */\nexport interface FileSystemModule {\n  removeSync(path: string): boolean;\n\n  createDirectorySync(path: string, createIntermediates: boolean): boolean;\n\n  readFileSync(path: string, options?: ReadFileOptions): string | ArrayBuffer;\n\n  writeFileSync(path: string, data: ArrayBuffer | string): void;\n\n  currentWorkingDirectory(): string;\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/test/FileSystem.spec.ts",
    "content": "import 'jasmine/src/jasmine';\nimport { arrayToString } from 'coreutils/src/Uint8ArrayUtils';\nimport { fs, VALDI_MODULES_ROOT } from '../src/FileSystem';\n\ndescribe('File System Module', () => {\n  const newFSItems = {\n    file: `${VALDI_MODULES_ROOT}/file_system/test/new_test_file.txt`,\n    folder: `${VALDI_MODULES_ROOT}/file_system/test/new_folder`,\n  };\n\n  it('should read file with content inside', () => {\n    const fileName = `${VALDI_MODULES_ROOT}/file_system/test/test_file.txt`;\n    const fileContent = 'test data for file';\n    const result = fs.readFileSync(fileName, { encoding: 'utf8' });\n\n    expect(result).toEqual(fileContent);\n  });\n\n  it('should read file as array buffer', () => {\n    const fileName = `${VALDI_MODULES_ROOT}/file_system/test/test_file.txt`;\n    const fileContent = 'test data for file';\n    const result = fs.readFileSync(fileName);\n\n    expect(result).toBeInstanceOf(ArrayBuffer);\n\n    const stringContent = arrayToString(new Uint8Array(result as ArrayBuffer));\n\n    expect(stringContent).toEqual(fileContent);\n  });\n\n  it('should throw an error for read file operation if file does not exist', () => {\n    const fileName = `${VALDI_MODULES_ROOT}/file_system/test/no_file`;\n\n    expect(() => fs.readFileSync(fileName)).toThrowError(`Could not read the file at path: '${fileName}'`);\n  });\n\n  it('should create, write and remove the new file', () => {\n    const fileContent = 'test data for file';\n    fs.writeFileSync(newFSItems.file, fileContent);\n\n    const result = fs.readFileSync(newFSItems.file, { encoding: 'utf8' });\n\n    expect(result).toEqual(fileContent);\n\n    const resultFromFileRemove = fs.removeSync(newFSItems.file);\n\n    expect(resultFromFileRemove).toBeTrue();\n  });\n\n  it('should get current root directory for client repository', () => {\n    expect(() => fs.currentWorkingDirectory()).not.toThrow();\n  });\n\n  it('should create and remove a new folder', () => {\n    const result = fs.createDirectorySync(newFSItems.folder, false);\n\n    expect(result).toBeTrue();\n\n    const resultFromFolderRemove = fs.removeSync(newFSItems.folder);\n\n    expect(resultFromFolderRemove).toBeTrue();\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/test/test_file.txt",
    "content": "test data for file"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\",\n    \"compilerOptions\": {\n        \"noImplicitReturns\": true,\n        \"noImplicitAny\": true,\n        \"strict\": true,\n    }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/web/FileSystem.ts",
    "content": "import { FileSystemModule, ReadFileOptions } from '../src/FileSystemModule';\n\nconst encUtf8 = new TextEncoder();\nconst decUtf8 = new TextDecoder();\n\n/** UTF-16LE encode/decode (simple, BOM-less) */\nfunction encodeUtf16LE(str: string): Uint8Array {\n  const out = new Uint8Array(str.length * 2);\n  for (let i = 0; i < str.length; i++) {\n    const code = str.charCodeAt(i);\n    out[i * 2] = code & 0xff;\n    out[i * 2 + 1] = code >> 8;\n  }\n  return out;\n}\nfunction decodeUtf16LE(buf: Uint8Array): string {\n  let s = \"\";\n  const len = buf.length & ~1; // even length\n  for (let i = 0; i < len; i += 2) {\n    s += String.fromCharCode(buf[i] | (buf[i + 1] << 8));\n  }\n  return s;\n}\n\nconst ROOT = \"/\";\nfunction norm(p: string): string {\n  // POSIX-like normalization; treat relative as from ROOT\n  const parts = (p.startsWith(\"/\") ? p : ROOT + p).split(\"/\").filter(Boolean);\n  const stack: string[] = [];\n  for (const part of parts) {\n    if (part === \".\") continue;\n    if (part === \"..\") { stack.pop(); continue; }\n    stack.push(part);\n  }\n  return ROOT + stack.join(\"/\");\n}\nfunction parentDir(p: string): string {\n  if (p === ROOT) return ROOT;\n  const idx = p.lastIndexOf(\"/\");\n  return idx > 0 ? p.slice(0, idx) : ROOT;\n}\n\n/* -------- in-memory FS state -------- */\n\nconst dirs = new Set<string>([ROOT]);\nconst files = new Map<string, Uint8Array>();\nlet CWD = ROOT;\n\n/* -------- implementation -------- */\n\nconst fsStub: FileSystemModule = {\n  removeSync(path: string): boolean {\n    const p = norm(path);\n    if (files.delete(p)) return true;\n    if (dirs.has(p)) {\n      // recursive remove directory\n      let removed = false;\n      // remove all nested files/dirs\n      for (const f of Array.from(files.keys())) {\n        if (f === p || f.startsWith(p + \"/\")) {\n          files.delete(f);\n          removed = true;\n        }\n      }\n      for (const d of Array.from(dirs.values())) {\n        if (d !== ROOT && (d === p || d.startsWith(p + \"/\"))) {\n          dirs.delete(d);\n          removed = true;\n        }\n      }\n      // finally remove the dir itself\n      if (p !== ROOT) dirs.delete(p);\n      return removed || true;\n    }\n    return false;\n  },\n\n  createDirectorySync(path: string, createIntermediates: boolean): boolean {\n    const p = norm(path);\n    if (dirs.has(p)) return true;\n    const chain: string[] = [];\n    let cur = p;\n    while (cur !== ROOT && !dirs.has(cur)) {\n      chain.push(cur);\n      cur = parentDir(cur);\n    }\n    if (!dirs.has(cur) && !createIntermediates) return false;\n    if (!createIntermediates && parentDir(p) !== cur) return false;\n\n    // create parents if requested/needed\n    while (chain.length) {\n      const d = chain.pop()!;\n      dirs.add(d);\n    }\n    return true;\n  },\n\n  readFileSync(path: string, options?: ReadFileOptions): string | ArrayBuffer {\n    const p = norm(path);\n    const buf = files.get(p) ?? new Uint8Array(0);\n\n    const enc = options?.encoding;\n    if (enc === \"utf8\") return decUtf8.decode(buf);\n    if (enc === \"utf16\") return decodeUtf16LE(buf);\n    // undefined/null => raw bytes\n    return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);\n  },\n\n  writeFileSync(path: string, data: ArrayBuffer | string): void {\n    const p = norm(path);\n    // ensure parent dir exists (be friendly in the stub)\n    const parent = parentDir(p);\n    if (!dirs.has(parent)) {\n      this.createDirectorySync(parent, true);\n    }\n    const bytes =\n      typeof data === \"string\" ? encUtf8.encode(data) : new Uint8Array(data);\n    files.set(p, bytes);\n  },\n\n  currentWorkingDirectory(): string {\n    return CWD;\n  },\n};\n\n/** Exported instance + setter so you can swap in a real native binding later. */\nexport let fileSystem: FileSystemModule = fsStub;\nexport function setFileSystem(impl: FileSystemModule): void {\n  fileSystem = impl;\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/file_system/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n     \"lib\": [\"DOM\", \"ES2020\"],\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": true,\n    \"allowJs\": true\n  },\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/BUILD.bazel",
    "content": "load(\"@aspect_rules_js//npm:defs.bzl\", \"npm_package\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nnpm_package(\n    name = \"foundation_dts\",\n    srcs = glob([\n        \"src/**/*.d.ts\",\n    ]),\n    package = \"foundation\",\n    visibility = [\"//visibility:public\"],\n)\n\nvaldi_module(\n    name = \"foundation\",\n    srcs = glob([\n        \"src/**/*.js\",\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.js\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCFoundation\",\n    ios_output_target = \"release\",\n    module_yaml = \"module.yaml\",\n    single_file_codegen = False,\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/jasmine\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_test\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/README.md",
    "content": "# Foundation\n\nCommon non-ui bits, e.g. generated interfaces and classes.\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/module.yaml",
    "content": "output_target: release\n\ndependencies:\n  - valdi_core\n  - valdi_tsx\nallowed_debug_dependencies:\n  - valdi_test\n  - jasmine\n\nios:\n  class_prefix: SCCFoundation\n  module_name: SCCFoundation\nandroid:\n  class_path: com.snap.valdi.foundation\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Announcer.ts",
    "content": "import { ICancelable } from 'foundation/src/ICancelable';\nimport CallbackCancelable from 'foundation/src/impl/CallbackCancelable';\n\nexport type Listener<T> = (value: T) => void;\n\ninterface ListenerInstance<T> {\n  readonly listener: Listener<T>;\n}\n\nexport class Announcer<T = void> {\n  private readonly listenerInstances = new Set<ListenerInstance<T>>();\n\n  announce(value: T): void {\n    for (const instance of Array.from(this.listenerInstances)) {\n      instance.listener(value);\n    }\n  }\n\n  addListener(listener: Listener<T>): ICancelable {\n    const instance: ListenerInstance<T> = { listener };\n    this.listenerInstances.add(instance);\n    return new CallbackCancelable(() => {\n      this.listenerInstances.delete(instance);\n    });\n  }\n\n  clear() {\n    this.listenerInstances.clear();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/CachedFunctionCall.ts",
    "content": "/**\n * This class will act like a function call whose output is automatically cached\n * until the input value changes\n *\n * You can use this class as a simple caching object for expensive function calls and computations\n */\nexport class CachedFunctionCall<Input, Output> {\n  private lastInput?: Input;\n  private lastOutput?: Output;\n\n  private fn: (input: Input) => Output;\n\n  constructor(fn: (input: Input) => Output) {\n    this.fn = fn;\n  }\n\n  getOrCall(input: Input): Output | undefined {\n    if (input !== this.lastInput) {\n      this.lastInput = input;\n      this.lastOutput = this.fn(input);\n    }\n    return this.lastOutput;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Debounce.ts",
    "content": "import { setTimeoutConfigurable } from 'valdi_core/src/SetTimeout';\n\nexport class Debounce<T> {\n  private interruptible: boolean;\n  private delayMs: number;\n  private handler: (values: T[]) => void;\n  private closed: boolean;\n\n  private timeout: number | undefined;\n  private queue: T[] = [];\n\n  /**\n   * Create a Debounce object\n   * @param interruptible If true, the debounce handler will not be called after the valdi context is destroyed\n   * @param delayMs how long to wait before calling the handler\n   * @param handler the handler to call with the debounced values\n   */\n  constructor(interruptible: boolean, delayMs: number, handler: (values: T[]) => void) {\n    this.interruptible = interruptible;\n    this.delayMs = delayMs;\n    this.handler = handler;\n    this.closed = false;\n  }\n\n  schedule(value: T) {\n    if (this.closed) {\n      return;\n    }\n    this.queue.push(value);\n    if (this.timeout) {\n      clearTimeout(this.timeout);\n    }\n    this.timeout = setTimeoutConfigurable(\n      this.interruptible,\n      () => {\n        this.flush();\n      },\n      this.delayMs,\n    );\n  }\n\n  private flush() {\n    this.handler(this.queue);\n    this.queue = [];\n  }\n\n  stop() {\n    this.closed = true;\n    this.flush();\n    if (this.timeout) {\n      clearTimeout(this.timeout);\n    }\n    this.timeout = undefined;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/DebounceBatch.ts",
    "content": "import { Debounce } from './Debounce';\n\ninterface Item<T, R> {\n  value: T;\n  completion: (value?: R, error?: any) => void;\n}\n\n/**\n * Allow the batching of multiple async operations\n * by immediately scheduling them\n * and automatically running them all at the same time\n * trough a single logic call after some debounced delay\n */\nexport class DebounceBatch<T, R> {\n  private debouncer: Debounce<Item<T, R>>;\n\n  /**\n   * Create a DebounceBatch object\n   * @param interruptible If true, the debounce handler will not be called after the valdi context is destroyed\n   * @param delayMs how long to wait before calling the handler\n   * @param handler the handler to call with the debounced values\n   */\n  constructor(\n    interruptible: boolean,\n    delayMs: number,\n    handler: (values: T[], completion: (values?: R[], error?: any) => void) => void,\n  ) {\n    this.debouncer = new Debounce(interruptible, delayMs, (items: Item<T, R>[]) => {\n      // Get the items values and handlers\n      const values = items.map((item: Item<T, R>) => {\n        return item.value;\n      });\n      const completions = items.map((item: Item<T, R>) => {\n        return item.completion;\n      });\n      // Run a single handler for all values\n      handler(values, (values?: R[], error?: any) => {\n        // The dispatch result array to items handlers\n        for (let i = 0; i < completions.length; i++) {\n          const completion = completions[i];\n          if (values) {\n            completion(values[i], error);\n          } else {\n            completion(undefined, error);\n          }\n        }\n      });\n    });\n  }\n\n  schedule(value: T, completion: (values?: R, error?: any) => void) {\n    this.debouncer.schedule({\n      value: value,\n      completion: completion,\n    });\n  }\n\n  schedulePromise(value: T): Promise<R> {\n    return new Promise((resolve, reject) => {\n      this.schedule(value, (values, error) => {\n        if (values) {\n          resolve(values);\n        } else {\n          reject(error);\n        }\n      });\n    });\n  }\n\n  stop() {\n    this.debouncer.stop();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/DebounceReorder.ts",
    "content": "import { Debounce } from './Debounce';\n\ninterface Item<T> {\n  priority: number;\n  value: T;\n}\n\n/**\n * Allow the batching of multiple async operations\n * by immediately scheduling them\n * and automatically running them all in a new order\n * after a specific debounced timer\n */\nexport class DebounceReorder<T> {\n  private debouncer: Debounce<Item<T>>;\n\n  /**\n   * Create a DebounceReorder object\n   * @param interruptible If true, the debounce handler will not be called after the valdi context is destroyed\n   * @param delayMs how long to wait before calling the handler\n   * @param handler the handler to call with the debounced values\n   */\n  constructor(interruptible: boolean, delayMs: number, handler: (value: T) => void) {\n    this.debouncer = new Debounce(interruptible, delayMs, (items: Item<T>[]) => {\n      items.sort((a, b) => {\n        return a.priority - b.priority;\n      });\n      return items.forEach(i => handler(i.value));\n    });\n  }\n\n  schedule(priority: number, value: T) {\n    this.debouncer.schedule({\n      priority: priority,\n      value: value,\n    });\n  }\n\n  stop() {\n    this.debouncer.stop();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/DeferredPromise.ts",
    "content": "/**\n * Error thrown when a DeferredPromise exceeds its specified timeoutMs.\n */\nexport class DeferredPromiseTimeoutError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = 'DeferredPromiseTimeoutError';\n    Object.setPrototypeOf(this, DeferredPromiseTimeoutError.prototype);\n  }\n}\n\n/**\n * Creates a Promise that can later be resolved or rejected\n */\nexport class DeferredPromise<T> implements PromiseLike<T> {\n  private resolved = false;\n  private timeoutId?: any;\n\n  readonly promise: Promise<T>;\n  resolve!: (value: T | PromiseLike<T>) => void;\n  reject!: (reason?: unknown) => void;\n\n  constructor(timeoutMs?: number) {\n    let res: (value: T | PromiseLike<T>) => void;\n    let rej: (reason?: unknown) => void;\n\n    this.promise = new Promise<T>((_res, _rej) => {\n      res = _res;\n      rej = _rej;\n    });\n\n    this.resolve = value => this.finalize(res, value);\n    this.reject = reason => this.finalize(rej, reason);\n\n    if (timeoutMs !== undefined) {\n      this.timeoutId = setTimeout(() => {\n        this.reject(new DeferredPromiseTimeoutError(`Promise timed out after ${timeoutMs}ms`));\n      }, timeoutMs);\n    }\n  }\n\n  /**\n   * Prevents multiple resolutions and clears any active timeout.\n   */\n  private finalize(callback: Function, arg: any) {\n    if (this.resolved) return;\n    this.resolved = true;\n\n    if (this.timeoutId) {\n      clearTimeout(this.timeoutId);\n      this.timeoutId = undefined;\n    }\n\n    callback(arg);\n  }\n\n  then<T1 = T, T2 = never>(\n    onfulfilled?: (value: T) => T1 | PromiseLike<T1>,\n    onrejected?: (reason: any) => T2 | PromiseLike<T2>,\n  ): Promise<T1 | T2> {\n    return this.promise.then(onfulfilled, onrejected);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Error.d.ts",
    "content": "/**\n * @ExportModel({ios: 'SCValdiFoundationError', android: 'com.snap.valdi.foundation.Error'})\n */\nexport interface Error {\n  // contains the error message\n  message: string;\n  // contains the optional error code\n  code?: number;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/ICancelable.d.ts",
    "content": "/**\n * @ExportProxy({ios: 'SCValdiFoundationCancelable', android: 'com.snap.valdi.foundation.Cancelable'})\n */\nexport interface ICancelable {\n  cancel(): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/IDisposable.d.ts",
    "content": "export interface IDisposable {\n  dispose(): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/KeyedFunctionCache.ts",
    "content": "export interface KeyedFunctionFactoryProvider<Key, Parameters extends any[] = [], ReturnValue = void> {\n  /**\n   * Creates an instance of {@link KeyedFunctionFactory} that uses the provided function to make keyed versions\n   * @param fn function that accepts a key + parameters, used to generated keyed functions\n   */\n  for(fn: (key: Key, ...params: Parameters) => ReturnValue): KeyedFunctionFactory<Key, Parameters, ReturnValue>;\n}\n\nexport interface KeyedFunctionFactory<Key, Parameters extends any[], ReturnValue> {\n  bindKey(key: Key): (...params: Parameters) => ReturnValue;\n}\n\n/**\n * Provides callback functions for lists of Components such that the callback functions for each Component\n * in the list are reused if the Component's key remains the same. This helps avoid unnecessary re-renders\n * due to view model changes caused by new function instances.\n * @example\n * interface ItemsViewModel {\n *   items: string[];\n *   onItemTap(i: number): void;\n * }\n * class ItemsView extends Component<ItemsViewModel> {\n *   private readonly onItemTapCache = new KeyedFunctionCache<number>();\n *   onRender(): void {\n *     const onItemTapFactory = onItemTapCache.for(this.viewModel.onItemTap);\n *     this.viewModel.items.forEach((item, i) => {\n *       <label value={item} onTap={onItemTapFactory.bindKey(i)} />;\n *     });\n *   }\n * }\n */\nexport class KeyedFunctionCache<Key, Parameters extends any[] = [], ReturnValue = void>\n  implements KeyedFunctionFactoryProvider<Key, Parameters, ReturnValue>\n{\n  private cache = new Map<Key, (...params: Parameters) => ReturnValue>();\n  private lastUsedFn?: (key: Key, ...params: Parameters) => ReturnValue;\n\n  for(fn: (key: Key, ...params: Parameters) => ReturnValue): KeyedFunctionFactory<Key, Parameters, ReturnValue> {\n    let prevCache: ReadonlyMap<Key, (...params: Parameters) => ReturnValue>;\n    if (this.lastUsedFn === fn) {\n      prevCache = this.cache;\n    } else {\n      // The function itself updated so the cached keyed functions are no longer valid\n      prevCache = new Map();\n    }\n    // Clear the current cache to avoid holding stale references\n    this.cache = new Map();\n    this.lastUsedFn = fn;\n    return new CachingKeyedFunctionFactory(prevCache, this.cache, fn);\n  }\n}\n\nclass CachingKeyedFunctionFactory<Key, Parameters extends any[], ReturnValue = void> {\n  constructor(\n    private readonly prevCache: ReadonlyMap<Key, (...params: Parameters) => ReturnValue>,\n    private readonly newCache: Map<Key, (...params: Parameters) => ReturnValue>,\n    private readonly fn: (key: Key, ...params: Parameters) => ReturnValue,\n  ) {}\n\n  /**\n   * Either returns a previously generated keyed function or creates a new one if none exists\n   * for the provided key. Caches any requested keyed functions in the {@link newCache}\n   * @param key the unique key that identifies a Component within a list\n   * @returns a callback function with the key parameter removed\n   */\n  bindKey(key: Key): (...params: Parameters) => ReturnValue {\n    const keyedFn = this.prevCache.get(key) ?? this.fn.bind(null, key);\n    this.newCache.set(key, keyedFn);\n    return keyedFn;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Lazy.ts",
    "content": "export class Lazy<T> {\n  private value?: { value: T };\n  private work?: () => T;\n\n  constructor(work: () => T) {\n    this.work = work;\n  }\n\n  get target(): T {\n    if (!this.value) {\n      this.value = { value: this.work!() };\n      this.work = undefined;\n    }\n    return this.value.value;\n  }\n\n  get isCreated(): boolean {\n    return this.value !== undefined;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Long.ts",
    "content": "/**\n * @ExportModel({ios: 'SCValdiFoundationLong', android: 'com.snap.valdi.foundation.Long'})\n */\nexport interface NativeLong {\n  /** Unsigned int32 */\n  readonly lowBits: number;\n  /** Unsigned int32 */\n  readonly highBits: number;\n}\n\n/** Converts a native long into a js long */\nexport function fromNativeLong(long: NativeLong, unsigned: boolean): Long {\n  // Need to convert the unsigned bits into signed bits for the js long class\n  return Long.fromBits(long.lowBits >> 0, long.highBits >> 0, unsigned);\n}\n\n/** Converts a js long into a native long */\nexport function toNativeLong(long: Long): NativeLong {\n  // Need to convert the signed bits from js long into unsigned bits for native long\n  return { lowBits: long.low >>> 0, highBits: long.high >>> 0 };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/NativeViewUtils.ts",
    "content": "import { ElementRef } from 'valdi_core/src/ElementRef';\nimport { NativeView } from 'valdi_tsx/src/NativeView';\n/**\n * Make a factory for callbacks that will bind the native view of the element ref as the callback argument\n */\nexport function makeFactoryForEventWithNativeView(elementRefGetter: () => ElementRef) {\n  let actualCallback: ((v: NativeView) => void) | undefined = undefined;\n  const wrappedCallback = async () => {\n    if (!actualCallback) {\n      return;\n    }\n    const elementRef = elementRefGetter();\n    const nativeView = await (elementRef.single()?.getNativeView() ?? Promise.resolve(undefined));\n    if (nativeView) {\n      actualCallback(nativeView);\n    }\n  };\n  return (callback?: (v: NativeView) => void) => {\n    actualCallback = callback;\n    if (actualCallback) {\n      return wrappedCallback;\n    }\n    return undefined;\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Provider.ts",
    "content": "import { Lazy } from 'foundation/src/Lazy';\nimport { isUndefined } from 'foundation/src/isUndefined';\n\n/**\n * Used to provide lazy dependencies to valdi context\n * @ExportModel\n */\nexport interface Provider<T> {\n  get(): T;\n}\n\nexport function providerToLazy<T>(provider: Provider<T>): Lazy<T>;\nexport function providerToLazy<T>(provider?: Provider<T>): Lazy<T> | undefined;\nexport function providerToLazy<T>(provider?: Provider<T>): Lazy<T> | undefined {\n  if (isUndefined(provider)) {\n    return;\n  }\n  return new Lazy(() => provider.get());\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Subscribable.ts",
    "content": "import { Subscription } from './Subscription';\n\nexport class Subscribable<T> {\n  private listeners: T[] = [];\n  subscribe(listener: T): Subscription {\n    this.listeners.push(listener);\n    return {\n      unsubscribe: () => {\n        const index = this.listeners.indexOf(listener);\n        if (index != -1) {\n          this.listeners.splice(index, 1);\n        }\n      },\n    };\n  }\n  subscribers(): T[] {\n    return this.listeners;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Subscription.d.ts",
    "content": "export interface Subscription {\n  unsubscribe(): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/Timer.ts",
    "content": "export class Timer {\n  startMs: number;\n  constructor() {\n    this.startMs = this.nowMs();\n  }\n  reset() {\n    this.startMs = this.nowMs();\n  }\n  elapsedMs() {\n    return this.nowMs() - this.startMs;\n  }\n  private nowMs() {\n    return new Date().getTime();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/UnreachableError.ts",
    "content": "export class UnreachableCaseError extends Error {\n  constructor(val?: any) {\n    const message = `Unreachable case` + val ? `:${val}` : '';\n    super(message);\n  }\n}\n\nexport function unreachable(val: any): any {\n  throw new UnreachableCaseError(val);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/array.ts",
    "content": "/**\n * Create an array of arbitrary size that contains x times the same value\n */\nexport function arrayRepeat<T>(size: number, value: T): T[] {\n  return arrayGenerate(size, () => value);\n}\n\n/**\n * Create an array of arbitrary size by calling a function x times and saving its return value in the array\n */\nexport function arrayGenerate<T>(size: number, call: (index: number) => T): T[] {\n  const result: T[] = [];\n  for (let i = 0; i < size; i++) {\n    result.push(call(i));\n  }\n  return result;\n}\n\n/*\n * Immutable insert function\n */\nexport function insert<T>(arr: T[], index: number, newItem: T): T[] {\n  return [...arr.slice(0, index), newItem, ...arr.slice(index)];\n}\n\n/*\n * Immutable multiInsert function that inserts values into an array at given indeces\n */\nexport function multiInsert<T>(arr: T[], values: { [index: number]: T }): T[] {\n  let numInsertions = 0;\n  const clonedArr: T[] = Object.assign([], arr);\n  arr.forEach((_, index) => {\n    if (values[index]) {\n      const clonedIndex = index + numInsertions;\n      clonedArr.splice(clonedIndex, 0, values[index]);\n      numInsertions += 1;\n    }\n  });\n  return clonedArr;\n}\n\n/**\n * Partitions an array based on a predicate, and returns a tuple of two arrays.\n * The first array contains elements that tested positive, the second negative\n */\nexport function partition<T>(arr: readonly T[], predicate: (element: T) => boolean): [T[], T[]] {\n  return arr.reduce<[T[], T[]]>(\n    (splitArrays, currentValue) => {\n      splitArrays[predicate(currentValue) ? 0 : 1].push(currentValue);\n      return splitArrays;\n    },\n    [[], []],\n  );\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/deepClone.ts",
    "content": "/**\n * Deep clone the object.\n *\n * Note that we should use structuredClone(), once valdi upgrade to Node.js 17.\n */\nconst deepClone = <T>(val: T, seen = new WeakMap()): T => {\n  // Handle primitive types\n  if (val === null || typeof val !== 'object') {\n    return val;\n  }\n\n  // Handle circular references\n  if (seen.has(val)) {\n    return seen.get(val) as T;\n  }\n\n  // handle Array\n  if (Array.isArray(val)) {\n    const result = val.slice(0) as T;\n    seen.set(val, result);\n    val.forEach((item: unknown, i) => {\n      // No easy way to type this, so we use any\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n      (result as any)[i] = deepClone(item, seen);\n    });\n    return result;\n  }\n\n  // handle Date\n  if (val instanceof Date) {\n    return new Date(val.valueOf()) as T;\n  }\n  // handle RegExp\n  if (val instanceof RegExp) {\n    return new RegExp(val) as T;\n  }\n  // handle Map\n  if (val instanceof Map) {\n    const result = new Map();\n    seen.set(val, result);\n    val.forEach((value, key) => {\n      result.set(key, deepClone(value, seen));\n    });\n    return result as T;\n  }\n  // handle Set\n  if (val instanceof Set) {\n    const result = new Set();\n    seen.set(val, result);\n    val.forEach(value => {\n      result.add(deepClone(value, seen));\n    });\n    return result as T;\n  }\n  // handle ArrayBuffer\n  if (val instanceof ArrayBuffer) {\n    return val.slice(0) as T;\n  }\n  // handle Long\n  if (val instanceof Long) {\n    return Long.fromValue(val) as T;\n  }\n  // handle plain object\n  if (val.constructor === Object) {\n    return deepClonePlainObject(val, seen) as T;\n  }\n  // handle Uint8Array\n  if (val instanceof Uint8Array) {\n    return new Uint8Array(val) as T;\n  }\n  // handle protobuf Message\n  if (isClonableProtobufMessage(val)) {\n    const cloned = val.clone() as T;\n    seen.set(val, cloned);\n    return cloned;\n  }\n\n  throw new Error(`Unsupported type in deepClone ${typeof val} ${val.constructor.name}`);\n};\n\nconst deepClonePlainObject = <T extends object>(obj: T, seen: WeakMap<object, unknown>): T => {\n  const cloned = {} as T;\n  seen.set(obj, cloned);\n  for (const key in obj) {\n    const val = obj[key];\n    cloned[key] = deepClone(val, seen);\n  }\n  return cloned;\n};\n\nexport default deepClone;\n\n// Object with a clone method (Protobuf Message)\ninterface Cloneable {\n  clone(): unknown;\n}\n\n// Check if value is a protobuf Message (has $arena property and clone method)\nfunction isClonableProtobufMessage(val: object): val is Cloneable {\n  return '$arena' in val && 'clone' in val && typeof val.clone === 'function';\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/emoji.ts",
    "content": "// https://github.com/mathiasbynens/emoji-regex/blob/master/index.js\n// tslint:disable-next-line\n/**\n * @deprecated: Use {@link UnicodeString} , which provides APIs to detect emojis\n */\nexport const emojiRegex =\n  /\\uD83C\\uDFF4\\uDB40\\uDC67\\uDB40\\uDC62(?:\\uDB40\\uDC77\\uDB40\\uDC6C\\uDB40\\uDC73|\\uDB40\\uDC73\\uDB40\\uDC63\\uDB40\\uDC74|\\uDB40\\uDC65\\uDB40\\uDC6E\\uDB40\\uDC67)\\uDB40\\uDC7F|(?:\\uD83E\\uDDD1\\uD83C\\uDFFF\\u200D\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D)?|\\u200D(?:\\uD83D\\uDC8B\\u200D)?)\\uD83E\\uDDD1|\\uD83D\\uDC69\\uD83C\\uDFFF\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83E\\uDEF1\\uD83C\\uDFFF\\u200D\\uD83E\\uDEF2)(?:\\uD83C[\\uDFFB-\\uDFFE])|(?:\\uD83E\\uDDD1\\uD83C\\uDFFE\\u200D\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D)?|\\u200D(?:\\uD83D\\uDC8B\\u200D)?)\\uD83E\\uDDD1|\\uD83D\\uDC69\\uD83C\\uDFFE\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83E\\uDEF1\\uD83C\\uDFFE\\u200D\\uD83E\\uDEF2)(?:\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|(?:\\uD83E\\uDDD1\\uD83C\\uDFFD\\u200D\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D)?|\\u200D(?:\\uD83D\\uDC8B\\u200D)?)\\uD83E\\uDDD1|\\uD83D\\uDC69\\uD83C\\uDFFD\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83E\\uDEF1\\uD83C\\uDFFD\\u200D\\uD83E\\uDEF2)(?:\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|(?:\\uD83E\\uDDD1\\uD83C\\uDFFC\\u200D\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D)?|\\u200D(?:\\uD83D\\uDC8B\\u200D)?)\\uD83E\\uDDD1|\\uD83D\\uDC69\\uD83C\\uDFFC\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83E\\uDEF1\\uD83C\\uDFFC\\u200D\\uD83E\\uDEF2)(?:\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|(?:\\uD83E\\uDDD1\\uD83C\\uDFFB\\u200D\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D)?|\\u200D(?:\\uD83D\\uDC8B\\u200D)?)\\uD83E\\uDDD1|\\uD83D\\uDC69\\uD83C\\uDFFB\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83E\\uDEF1\\uD83C\\uDFFB\\u200D\\uD83E\\uDEF2)(?:\\uD83C[\\uDFFC-\\uDFFF])|\\uD83D\\uDC68(?:\\uD83C\\uDFFB(?:\\u200D(?:\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF]))|\\u200D(?:\\uD83D\\uDC8B\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF])))|\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFC-\\uDFFF])|[\\u2695\\u2696\\u2708]\\uFE0F|[\\u2695\\u2696\\u2708]|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD]))?|(?:\\uD83C[\\uDFFC-\\uDFFF])\\u200D\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF]))|\\u200D(?:\\uD83D\\uDC8B\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF])))|\\u200D(?:\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D)?|\\u200D(?:\\uD83D\\uDC8B\\u200D)?)\\uD83D\\uDC68|(?:\\uD83D[\\uDC68\\uDC69])\\u200D(?:\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67]))|\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67])|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFF\\u200D(?:\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFE])|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFE\\u200D(?:\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFD\\u200D(?:\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFC\\u200D(?:\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|(?:\\uD83C\\uDFFF\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFE\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFD\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFC\\u200D[\\u2695\\u2696\\u2708]|\\u200D[\\u2695\\u2696\\u2708])\\uFE0F|\\u200D(?:(?:\\uD83D[\\uDC68\\uDC69])\\u200D(?:\\uD83D[\\uDC66\\uDC67])|\\uD83D[\\uDC66\\uDC67])|\\uD83C\\uDFFF\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFE\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFD\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFC\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFF|\\uD83C\\uDFFE|\\uD83C\\uDFFD|\\uD83C\\uDFFC|\\u200D[\\u2695\\u2696\\u2708])?|(?:\\uD83D\\uDC69(?:\\uD83C\\uDFFB\\u200D\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83D[\\uDC68\\uDC69])|\\u200D(?:\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83D[\\uDC68\\uDC69]))|(?:\\uD83C[\\uDFFC-\\uDFFF])\\u200D\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83D[\\uDC68\\uDC69])|\\u200D(?:\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83D[\\uDC68\\uDC69])))|\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D\\uD83E\\uDD1D\\u200D\\uD83E\\uDDD1)(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC69\\u200D\\uD83D\\uDC69\\u200D(?:\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67]))|\\uD83D\\uDC69(?:\\u200D(?:\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83D[\\uDC68\\uDC69])|\\u200D(?:\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83D[\\uDC68\\uDC69]))|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFF\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFE\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFD\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFC\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFB\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD]))|\\uD83E\\uDDD1(?:\\u200D(?:\\uD83E\\uDD1D\\u200D\\uD83E\\uDDD1|\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFF\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFE\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFD\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFC\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83C\\uDFFB\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD]))|\\uD83D\\uDC69\\u200D\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC69\\u200D\\uD83D\\uDC69\\u200D(?:\\uD83D[\\uDC66\\uDC67])|\\uD83D\\uDC69\\u200D\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67])|(?:\\uD83D\\uDC41\\uFE0F?\\u200D\\uD83D\\uDDE8|\\uD83E\\uDDD1(?:\\uD83C\\uDFFF\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFE\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFD\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFC\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFB\\u200D[\\u2695\\u2696\\u2708]|\\u200D[\\u2695\\u2696\\u2708])|\\uD83D\\uDC69(?:\\uD83C\\uDFFF\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFE\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFD\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFC\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFB\\u200D[\\u2695\\u2696\\u2708]|\\u200D[\\u2695\\u2696\\u2708])|\\uD83D\\uDE36\\u200D\\uD83C\\uDF2B|\\uD83C\\uDFF3\\uFE0F?\\u200D\\u26A7|\\uD83D\\uDC3B\\u200D\\u2744|(?:(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC70\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDB8\\uDDB9\\uDDCD-\\uDDCF\\uDDD4\\uDDD6-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC6F|\\uD83E[\\uDDDE\\uDDDF])\\u200D[\\u2640\\u2642]|(?:\\u26F9|\\uD83C[\\uDFCB\\uDFCC]|\\uD83D\\uDD75)(?:(?:\\uFE0F|\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2640\\u2642]|\\u200D[\\u2640\\u2642])|\\uD83C\\uDFF4\\u200D\\u2620|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC70\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDB8\\uDDB9\\uDDCD-\\uDDCF\\uDDD4\\uDDD6-\\uDDDD])\\u200D[\\u2640\\u2642]|[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23ED-\\u23EF\\u23F1\\u23F2\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB\\u25FC\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u265F\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267E\\u267F\\u2692\\u2694-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A7\\u26AA\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C8\\u26CF\\u26D1\\u26D3\\u26E9\\u26F0-\\u26F5\\u26F7\\u26F8\\u26FA\\u2702\\u2708\\u2709\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2733\\u2734\\u2744\\u2747\\u2757\\u2763\\u27A1\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B55\\u3030\\u303D\\u3297\\u3299]|\\uD83C[\\uDC04\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDE02\\uDE37\\uDF21\\uDF24-\\uDF2C\\uDF36\\uDF7D\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E\\uDF9F\\uDFCD\\uDFCE\\uDFD4-\\uDFDF\\uDFF5\\uDFF7]|\\uD83D[\\uDC3F\\uDCFD\\uDD49\\uDD4A\\uDD6F\\uDD70\\uDD73\\uDD76-\\uDD79\\uDD87\\uDD8A-\\uDD8D\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA\\uDECB\\uDECD-\\uDECF\\uDEE0-\\uDEE5\\uDEE9\\uDEF0\\uDEF3])\\uFE0F|\\uD83D\\uDC41\\uFE0F?\\u200D\\uD83D\\uDDE8|\\uD83E\\uDDD1(?:\\uD83C\\uDFFF\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFE\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFD\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFC\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFB\\u200D[\\u2695\\u2696\\u2708]|\\u200D[\\u2695\\u2696\\u2708])|\\uD83D\\uDC69(?:\\uD83C\\uDFFF\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFE\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFD\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFC\\u200D[\\u2695\\u2696\\u2708]|\\uD83C\\uDFFB\\u200D[\\u2695\\u2696\\u2708]|\\u200D[\\u2695\\u2696\\u2708])|\\uD83C\\uDFF3\\uFE0F?\\u200D\\uD83C\\uDF08|\\uD83D\\uDC69\\u200D\\uD83D\\uDC67|\\uD83D\\uDC69\\u200D\\uD83D\\uDC66|\\uD83D\\uDE36\\u200D\\uD83C\\uDF2B|\\uD83C\\uDFF3\\uFE0F?\\u200D\\u26A7|\\uD83D\\uDE35\\u200D\\uD83D\\uDCAB|\\uD83D\\uDE2E\\u200D\\uD83D\\uDCA8|\\uD83D\\uDC15\\u200D\\uD83E\\uDDBA|\\uD83E\\uDEF1(?:\\uD83C\\uDFFF|\\uD83C\\uDFFE|\\uD83C\\uDFFD|\\uD83C\\uDFFC|\\uD83C\\uDFFB)?|\\uD83E\\uDDD1(?:\\uD83C\\uDFFF|\\uD83C\\uDFFE|\\uD83C\\uDFFD|\\uD83C\\uDFFC|\\uD83C\\uDFFB)?|\\uD83D\\uDC69(?:\\uD83C\\uDFFF|\\uD83C\\uDFFE|\\uD83C\\uDFFD|\\uD83C\\uDFFC|\\uD83C\\uDFFB)?|\\uD83D\\uDC3B\\u200D\\u2744|(?:(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC70\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDB8\\uDDB9\\uDDCD-\\uDDCF\\uDDD4\\uDDD6-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC6F|\\uD83E[\\uDDDE\\uDDDF])\\u200D[\\u2640\\u2642]|(?:\\u26F9|\\uD83C[\\uDFCB\\uDFCC]|\\uD83D\\uDD75)(?:(?:\\uFE0F|\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2640\\u2642]|\\u200D[\\u2640\\u2642])|\\uD83C\\uDFF4\\u200D\\u2620|\\uD83C\\uDDFD\\uD83C\\uDDF0|\\uD83C\\uDDF6\\uD83C\\uDDE6|\\uD83C\\uDDF4\\uD83C\\uDDF2|\\uD83D\\uDC08\\u200D\\u2B1B|\\u2764(?:\\uFE0F\\u200D(?:\\uD83D\\uDD25|\\uD83E\\uDE79)|\\u200D(?:\\uD83D\\uDD25|\\uD83E\\uDE79))|\\uD83D\\uDC41\\uFE0F?|\\uD83C\\uDFF3\\uFE0F?|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC70\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDB8\\uDDB9\\uDDCD-\\uDDCF\\uDDD4\\uDDD6-\\uDDDD])\\u200D[\\u2640\\u2642]|\\uD83C\\uDDFF(?:\\uD83C[\\uDDE6\\uDDF2\\uDDFC])|\\uD83C\\uDDFE(?:\\uD83C[\\uDDEA\\uDDF9])|\\uD83C\\uDDFC(?:\\uD83C[\\uDDEB\\uDDF8])|\\uD83C\\uDDFB(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDEE\\uDDF3\\uDDFA])|\\uD83C\\uDDFA(?:\\uD83C[\\uDDE6\\uDDEC\\uDDF2\\uDDF3\\uDDF8\\uDDFE\\uDDFF])|\\uD83C\\uDDF9(?:\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDED\\uDDEF-\\uDDF4\\uDDF7\\uDDF9\\uDDFB\\uDDFC\\uDDFF])|\\uD83C\\uDDF8(?:\\uD83C[\\uDDE6-\\uDDEA\\uDDEC-\\uDDF4\\uDDF7-\\uDDF9\\uDDFB\\uDDFD-\\uDDFF])|\\uD83C\\uDDF7(?:\\uD83C[\\uDDEA\\uDDF4\\uDDF8\\uDDFA\\uDDFC])|\\uD83C\\uDDF5(?:\\uD83C[\\uDDE6\\uDDEA-\\uDDED\\uDDF0-\\uDDF3\\uDDF7-\\uDDF9\\uDDFC\\uDDFE])|\\uD83C\\uDDF3(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA-\\uDDEC\\uDDEE\\uDDF1\\uDDF4\\uDDF5\\uDDF7\\uDDFA\\uDDFF])|\\uD83C\\uDDF2(?:\\uD83C[\\uDDE6\\uDDE8-\\uDDED\\uDDF0-\\uDDFF])|\\uD83C\\uDDF1(?:\\uD83C[\\uDDE6-\\uDDE8\\uDDEE\\uDDF0\\uDDF7-\\uDDFB\\uDDFE])|\\uD83C\\uDDF0(?:\\uD83C[\\uDDEA\\uDDEC-\\uDDEE\\uDDF2\\uDDF3\\uDDF5\\uDDF7\\uDDFC\\uDDFE\\uDDFF])|\\uD83C\\uDDEF(?:\\uD83C[\\uDDEA\\uDDF2\\uDDF4\\uDDF5])|\\uD83C\\uDDEE(?:\\uD83C[\\uDDE8-\\uDDEA\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9])|\\uD83C\\uDDED(?:\\uD83C[\\uDDF0\\uDDF2\\uDDF3\\uDDF7\\uDDF9\\uDDFA])|\\uD83C\\uDDEC(?:\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEE\\uDDF1-\\uDDF3\\uDDF5-\\uDDFA\\uDDFC\\uDDFE])|\\uD83C\\uDDEB(?:\\uD83C[\\uDDEE-\\uDDF0\\uDDF2\\uDDF4\\uDDF7])|\\uD83C\\uDDEA(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDED\\uDDF7-\\uDDFA])|\\uD83C\\uDDE9(?:\\uD83C[\\uDDEA\\uDDEC\\uDDEF\\uDDF0\\uDDF2\\uDDF4\\uDDFF])|\\uD83C\\uDDE8(?:\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDEE\\uDDF0-\\uDDF5\\uDDF7\\uDDFA-\\uDDFF])|\\uD83C\\uDDE7(?:\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEF\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9\\uDDFB\\uDDFC\\uDDFE\\uDDFF])|\\uD83C\\uDDE6(?:\\uD83C[\\uDDE8-\\uDDEC\\uDDEE\\uDDF1\\uDDF2\\uDDF4\\uDDF6-\\uDDFA\\uDDFC\\uDDFD\\uDDFF])|[#\\*0-9]\\uFE0F?\\u20E3|\\uD83E\\uDD3C(?:\\uD83C[\\uDFFB-\\uDFFF])|\\u2764\\uFE0F?|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC70\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDB8\\uDDB9\\uDDCD-\\uDDCF\\uDDD4\\uDDD6-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])|(?:\\u26F9|\\uD83C[\\uDFCB\\uDFCC]|\\uD83D\\uDD75)(?:\\uFE0F|\\uD83C[\\uDFFB-\\uDFFF])?|\\uD83C\\uDFF4|(?:[\\u270A\\u270B]|\\uD83C[\\uDF85\\uDFC2\\uDFC7]|\\uD83D[\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66\\uDC67\\uDC6B-\\uDC6D\\uDC72\\uDC74-\\uDC76\\uDC78\\uDC7C\\uDC83\\uDC85\\uDC8F\\uDC91\\uDCAA\\uDD7A\\uDD95\\uDD96\\uDE4C\\uDE4F\\uDEC0\\uDECC]|\\uD83E[\\uDD0C\\uDD0F\\uDD18-\\uDD1F\\uDD30-\\uDD34\\uDD36\\uDD77\\uDDB5\\uDDB6\\uDDBB\\uDDD2\\uDDD3\\uDDD5\\uDEC3-\\uDEC5\\uDEF0\\uDEF2-\\uDEF6])(?:\\uD83C[\\uDFFB-\\uDFFF])|(?:[\\u261D\\u270C\\u270D]|\\uD83D[\\uDD74\\uDD90])(?:\\uFE0F|\\uD83C[\\uDFFB-\\uDFFF])|[\\u261D\\u270A-\\u270D]|\\uD83C[\\uDF85\\uDFC2\\uDFC7]|\\uD83D[\\uDC08\\uDC15\\uDC3B\\uDC42\\uDC43\\uDC46-\\uDC50\\uDC66\\uDC67\\uDC6B-\\uDC6D\\uDC72\\uDC74-\\uDC76\\uDC78\\uDC7C\\uDC83\\uDC85\\uDC8F\\uDC91\\uDCAA\\uDD74\\uDD7A\\uDD90\\uDD95\\uDD96\\uDE2E\\uDE35\\uDE36\\uDE4C\\uDE4F\\uDEC0\\uDECC]|\\uD83E[\\uDD0C\\uDD0F\\uDD18-\\uDD1F\\uDD30-\\uDD34\\uDD36\\uDD3C\\uDD77\\uDDB5\\uDDB6\\uDDBB\\uDDD2\\uDDD3\\uDDD5\\uDEC3-\\uDEC5\\uDEF0\\uDEF2-\\uDEF6]|\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC70\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDB8\\uDDB9\\uDDCD-\\uDDCF\\uDDD4\\uDDD6-\\uDDDD]|\\uD83D\\uDC6F|\\uD83E[\\uDDDE\\uDDDF]|[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23ED-\\u23EF\\u23F1\\u23F2\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB\\u25FC\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u265F\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267E\\u267F\\u2692\\u2694-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A7\\u26AA\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C8\\u26CF\\u26D1\\u26D3\\u26E9\\u26F0-\\u26F5\\u26F7\\u26F8\\u26FA\\u2702\\u2708\\u2709\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2733\\u2734\\u2744\\u2747\\u2757\\u2763\\u27A1\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B55\\u3030\\u303D\\u3297\\u3299]|\\uD83C[\\uDC04\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDE02\\uDE37\\uDF21\\uDF24-\\uDF2C\\uDF36\\uDF7D\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E\\uDF9F\\uDFCD\\uDFCE\\uDFD4-\\uDFDF\\uDFF5\\uDFF7]|\\uD83D[\\uDC3F\\uDCFD\\uDD49\\uDD4A\\uDD6F\\uDD70\\uDD73\\uDD76-\\uDD79\\uDD87\\uDD8A-\\uDD8D\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA\\uDECB\\uDECD-\\uDECF\\uDEE0-\\uDEE5\\uDEE9\\uDEF0\\uDEF3]|[\\u23E9-\\u23EC\\u23F0\\u23F3\\u25FD\\u2693\\u26A1\\u26AB\\u26C5\\u26CE\\u26D4\\u26EA\\u26FD\\u2705\\u2728\\u274C\\u274E\\u2753-\\u2755\\u2795-\\u2797\\u27B0\\u27BF\\u2B50]|\\uD83C[\\uDCCF\\uDD8E\\uDD91-\\uDD9A\\uDE01\\uDE1A\\uDE2F\\uDE32-\\uDE36\\uDE38-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF20\\uDF2D-\\uDF35\\uDF37-\\uDF7C\\uDF7E-\\uDF84\\uDF86-\\uDF93\\uDFA0-\\uDFC1\\uDFC5\\uDFC6\\uDFC8\\uDFC9\\uDFCF-\\uDFD3\\uDFE0-\\uDFF0\\uDFF8-\\uDFFF]|\\uD83D[\\uDC00-\\uDC07\\uDC09-\\uDC14\\uDC16-\\uDC3A\\uDC3C-\\uDC3E\\uDC40\\uDC44\\uDC45\\uDC51-\\uDC65\\uDC6A\\uDC79-\\uDC7B\\uDC7D-\\uDC80\\uDC84\\uDC88-\\uDC8E\\uDC90\\uDC92-\\uDCA9\\uDCAB-\\uDCFC\\uDCFF-\\uDD3D\\uDD4B-\\uDD4E\\uDD50-\\uDD67\\uDDA4\\uDDFB-\\uDE2D\\uDE2F-\\uDE34\\uDE37-\\uDE44\\uDE48-\\uDE4A\\uDE80-\\uDEA2\\uDEA4-\\uDEB3\\uDEB7-\\uDEBF\\uDEC1-\\uDEC5\\uDED0-\\uDED2\\uDED5-\\uDED7\\uDEDD-\\uDEDF\\uDEEB\\uDEEC\\uDEF4-\\uDEFC\\uDFE0-\\uDFEB\\uDFF0]|\\uD83E[\\uDD0D\\uDD0E\\uDD10-\\uDD17\\uDD20-\\uDD25\\uDD27-\\uDD2F\\uDD3A\\uDD3F-\\uDD45\\uDD47-\\uDD76\\uDD78-\\uDDB4\\uDDB7\\uDDBA\\uDDBC-\\uDDCC\\uDDD0\\uDDE0-\\uDDFF\\uDE70-\\uDE74\\uDE78-\\uDE7C\\uDE80-\\uDE86\\uDE90-\\uDEAC\\uDEB0-\\uDEBA\\uDEC0-\\uDEC2\\uDED0-\\uDED9\\uDEE0-\\uDEE7]/g;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/equality.ts",
    "content": "/** Performs a deep equality check between two values */\nexport function deepEqual<T>(a: T, b: T): boolean;\nexport function deepEqual(a: unknown, b: unknown): boolean {\n  if (a === b) {\n    return true;\n  }\n\n  if (a && b && typeof a === 'object' && typeof b === 'object') {\n    if (a.constructor !== b.constructor) {\n      return false;\n    }\n\n    if (Array.isArray(a) && Array.isArray(b)) {\n      if (a.length !== b.length) {\n        return false;\n      }\n      for (let i = 0; i < a.length; i++) {\n        if (!deepEqual(a[i], b[i])) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    if (a instanceof Map && b instanceof Map) {\n      if (a.size !== b.size) {\n        return false;\n      }\n      for (const e of Array.from(a.entries())) {\n        if (!b.has(e[0])) {\n          return false;\n        }\n      }\n      for (const e of Array.from(a.entries())) {\n        if (!deepEqual(e[1], b.get(e[0]))) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    if (a instanceof Set && b instanceof Set) {\n      if (a.size !== b.size) {\n        return false;\n      }\n      for (const e of Array.from(a.entries())) {\n        if (!b.has(e[0])) {\n          return false;\n        }\n      }\n      return true;\n    }\n\n    if (a instanceof RegExp && b instanceof RegExp) {\n      return a.source === b.source && a.flags === b.flags;\n    }\n    if (a instanceof Long && b instanceof Long) {\n      // Handle Long objects before valueOf check, which errors for large values\n      return a.compare(b) === 0; // returns 0 if equal\n    }\n    if (a.valueOf !== Object.prototype.valueOf) {\n      return a.valueOf() === b.valueOf();\n    }\n    if (a.toString !== Object.prototype.toString) {\n      return a.toString() === b.toString();\n    }\n\n    const keys = Object.keys(a);\n    if (keys.length !== Object.keys(b).length) {\n      return false;\n    }\n    for (const key of keys) {\n      if (!Object.prototype.hasOwnProperty.call(b, key)) {\n        return false;\n      }\n    }\n    for (const key of keys) {\n      if (!deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\n        return false;\n      }\n    }\n    return true;\n  }\n\n  // true if both NaN, false otherwise\n  return a !== a && b !== b;\n}\n\n/** Performs a shallow equality check between two values */\nexport function shallowEqual<T>(a: T, b: T): boolean;\nexport function shallowEqual(previous: unknown, current: unknown): boolean {\n  if (previous && current && typeof previous === 'object' && typeof current === 'object') {\n    const previousKeys = Object.keys(previous);\n    const currentKeys = Object.keys(current);\n    if (previousKeys.length !== currentKeys.length) {\n      return false;\n    }\n    return previousKeys.every(\n      key => (previous as Record<string, unknown>)[key] === (current as Record<string, unknown>)[key],\n    );\n  } else {\n    return previous === current;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/foundation.ts",
    "content": "// Empty ts file to force the valdi compiler to generate a valdimodule to make BUCK happy.\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/function.ts",
    "content": "type Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T; // from lodash\n\nexport function noop() {}\n\n/** Used to perform type-correct truthy `.filter` ops. */\nexport function truthy<T>(value: T): value is Truthy<T> {\n  return !!value;\n}\n\n/** Returns passed in `obj` */\nexport function identity<T>(obj: T): T {\n  return obj;\n}\n\n/** Used to perform type-correct nonnull `.filter` ops. */\nexport function nonnull<T>(value: T): value is NonNullable<T> {\n  return value != null;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/functional/README.md",
    "content": "# Higher-order Functions\n\nThis directory contains higher-order functions (functions that in turn return functions) that can be \neasily reused across features. Think rx methods like `map`, `switchMap`, etc. but for general use cases\nbeyond Observables."
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/functional/cacheResolved.ts",
    "content": "type AsyncFunction<Args extends any[], Resolve> = (...args: Args) => Promise<Resolve>;\n\n/**\n * Decorates an async function by internally caching returned Promises by a cache key\n * computed using {@link cacheKeyFn} with the arguments supplied. Only successfully resolved\n * Promises will be remain in cache. Any Promise that rejects is evicted.\n * @param cacheKeyFn generates a cache key using arguments supplied to the async function\n * @returns an async function that caches resolved values\n */\nexport function cacheResolved<Args extends any[], Resolve>(\n  cacheKeyFn: (...args: Args) => string,\n): (fn: AsyncFunction<Args, Resolve>) => AsyncFunction<Args, Resolve> {\n  const cache: Record<string, Promise<Resolve>> = {};\n  return (fn: AsyncFunction<Args, Resolve>) =>\n    async (...args: Args) => {\n      const key = cacheKeyFn(...args);\n      const cached = cache[key];\n      if (cached) {\n        return cached;\n      }\n      const promise = fn(...args);\n      cache[key] = promise;\n\n      try {\n        return await promise;\n      } catch (e) {\n        delete cache[key];\n        throw e;\n      }\n    };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/functional/mapArguments.ts",
    "content": "/**\n * Given a mapping function f(...x) => ...y, returns a method for transforming a function's signature\n * from f(...y) => returnType to f(...x) => returnType.\n *\n * @example\n * const concat = (x: string, y: string): string => x + y;\n * const concatNumbers = mapArguments((i: number, j: number): [string, string] => [i.toString(), j.toString()])(concat);\n * concatNumbers(123, 456); // returns \"123456\"\n *\n * @param mapper maps the desired input arguments to the required arguments\n * @returns a function that updates the arguments of the input function to the desired argument types\n */\nexport function mapArguments<ArgsIn extends unknown[], ArgsOut extends unknown[], ReturnType>(\n  mapper: (...args: ArgsIn) => ArgsOut,\n): (fn: (...args: ArgsOut) => ReturnType) => (...args: ArgsIn) => ReturnType {\n  return fn =>\n    (...args) =>\n      fn(...mapper(...args));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/functional/mapResult.ts",
    "content": "type FunctionWithArgs<Args extends any[], Result> = (...args: Args) => Result;\n\n/**\n * Given a mapping function f(x) => y, returns a method for transforming a function's signature\n * from f(...) => x to f(...) => y.\n *\n * @example\n * const multiply = (x: number, y: number): number => x * y;\n * const multiplyString = mapResult((x: number) => x.toString())(multiply);\n * multiplyString(4, 7); // returns \"28\"\n *\n * @param mapper maps the return value from the provided function to the desired output\n * @returns a function that updates the return value of the input function to the desired value\n */\nexport function mapResult<Args extends any[], ResultIn, ResultOut>(\n  mapper: (result: ResultIn) => ResultOut,\n): (fn: FunctionWithArgs<Args, ResultIn>) => FunctionWithArgs<Args, ResultOut> {\n  return fn =>\n    (...args: Args) =>\n      mapper(fn(...args));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/functional/transformProperties.ts",
    "content": "type KeyedTransforms<T> = { [k in keyof T]?: (input: T[k]) => unknown };\n\n/**\n * Given a type of object T and a set of desired transformations keyed by properties of T,\n * returns a function that applies those transformations to the respective properties of objects of type T\n * @example\n * interface Foo {\n *   count: number;\n *   message: string;\n * }\n * const squareCount = transformProperties<Foo>({\n *   count: (x): number => x * x,\n * });\n *\n * squareCount({ count: 2, message: 'foo' }); // returns { count: 4, message: 'foo' }\n * @param transforms describes how each property should be transformed\n */\nexport function transformProperties<T extends {}, Transforms extends KeyedTransforms<T> = KeyedTransforms<T>>(\n  transforms: Transforms,\n): (input: T) => { [k in keyof T]: Transforms[k] extends (input: T[k]) => infer Out ? Out : T[k] };\n\nexport function transformProperties<T extends {}>(\n  transforms: KeyedTransforms<T>,\n): (input: T) => Record<keyof T, unknown> {\n  return (input: T) => {\n    const transformed: Record<keyof T, unknown> = { ...input };\n    for (const k in input) {\n      const transform = transforms[k];\n      if (transform) {\n        transformed[k] = transform(input[k]);\n      }\n    }\n    return transformed;\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/impl/CallbackCancelable.ts",
    "content": "import { ICancelable } from '../ICancelable';\n\n/**\n * An implementation of cancelable that calls a given callback once when canceled for the first time.\n */\nexport default class CallbackCancelable implements ICancelable {\n  private callback: (() => void) | undefined;\n\n  constructor(callback?: () => void) {\n    this.callback = callback;\n  }\n\n  cancel = () => {\n    const callback = this.callback;\n    this.callback = undefined;\n    callback?.();\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/impl/CallbackDisposable.ts",
    "content": "import { ICancelable } from '../ICancelable';\nimport { IDisposable } from '../IDisposable';\nimport CallbackCancelable from './CallbackCancelable';\n\n/**\n * An implementation of disposable that calls a given callback once when disposed for the first time.\n */\nexport default class CallbackDisposable implements IDisposable {\n  private readonly cancelable: ICancelable;\n\n  constructor(callback: () => void) {\n    // Disposables and cancelables are identical in all but name, so just use\n    // a cancelable under the hood\n    this.cancelable = new CallbackCancelable(callback);\n  }\n\n  dispose(): void {\n    this.cancelable.cancel();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/impl/CancelableGroup.ts",
    "content": "import { CancelablePromise } from 'valdi_core/src/CancelablePromise';\nimport { ICancelable } from '../ICancelable';\nimport CallbackCancelable from './CallbackCancelable';\n\n/**\n * Allows ICancelables to be grouped, so they can be canceled together.\n */\nexport default class CancelableGroup implements ICancelable {\n  private canceled = false;\n  private cancelables: ICancelable[];\n\n  constructor(...cancelables: readonly ICancelable[]) {\n    this.cancelables = [...cancelables];\n  }\n\n  get isCanceled(): boolean {\n    return this.canceled;\n  }\n\n  add = (cancelable: ICancelable) => {\n    if (this.canceled) {\n      cancelable.cancel();\n      return this;\n    }\n    this.cancelables.push(cancelable);\n    return this;\n  };\n\n  addCancelablePromise = <T>(cancelablePromise: CancelablePromise<T>): Promise<T> => {\n    this.add(new CallbackCancelable(cancelablePromise.cancel));\n    return Promise.resolve(cancelablePromise);\n  };\n\n  cancel = () => {\n    this.canceled = true;\n    const cancelables = this.cancelables;\n    this.cancelables = [];\n    for (const cancelable of cancelables) {\n      cancelable.cancel();\n    }\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/isDefined.ts",
    "content": "/**\n * returns true is value is not undefined or null\n * for type narrowing\n *\n * ```ts\n * // 'a', 1\n * const array = ['a', null, 1, undefined].filter(isDefined)\n * ```\n */\nexport function isDefined<T>(value: T): value is NonNullable<T> {\n  return value !== undefined && value !== null;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/isUndefined.ts",
    "content": "export function isUndefined(val: any): val is undefined {\n  return typeof val === 'undefined';\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/makePropertiesOpaque.ts",
    "content": "import { ValdiRuntime } from 'valdi_core/src/ValdiRuntime';\n\ndeclare const runtime: ValdiRuntime;\n\nexport interface WithOpaqueProperties<T> {}\n\n/**\n * Iterate over every entry of the passed-in object and call runtime.makeOpaque on it.\n */\nexport function makePropertiesOpaque<T>(obj: T): WithOpaqueProperties<T> {\n  const result = {} as any;\n  for (const key in obj) {\n    result[key] = runtime.makeOpaque(obj[key]);\n  }\n  return result;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/map.ts",
    "content": "/**\n * Returns the value of `key` in `map`.\n * If `key` does not exist in the map, then set it to `defaultValue` and return it.\n */\nimport { StringMap } from 'coreutils/src/StringMap';\n\nexport function getOrSet<K, V>(key: K, map: Map<K, V>, defaultValue: V): V {\n  const maybeValue = map.get(key);\n  if (!maybeValue) {\n    map.set(key, defaultValue);\n    return defaultValue;\n  }\n  return maybeValue;\n}\n\nexport function getOrLazySet<K, V>(key: K, map: Map<K, V>, defaultValueFn: () => V): V {\n  const maybeValue = map.get(key);\n  if (!maybeValue) {\n    const newValue = defaultValueFn();\n    map.set(key, newValue);\n    return newValue;\n  }\n  return maybeValue;\n}\n\nexport function fromStringMap<T>(strMap: StringMap<T>): Map<string, T> {\n  const m = new Map<string, T>();\n  for (const key of Object.keys(strMap)) {\n    m.set(key, strMap[key]!);\n  }\n  return m;\n}\n\n/**\n * Constructs a Map for an array given a key provider\n */\nexport function arrayToMap<K, T>(arr: T[], key: (item: T) => K): Map<K, T> {\n  const m = new Map<K, T>();\n  for (const item of arr) {\n    m.set(key(item), item);\n  }\n  return m;\n}\n\n/**\n * Provides a function that can be used to map arrays to string maps\n */\nexport function arrayToMapFn<K, T>(key: (item: T) => K): (arr: T[]) => Map<K, T> {\n  return (arr: T[]) => arrayToMap(arr, key);\n}\n\n/**\n * Computes the union of two Maps and returns the result as a new Map\n */\nexport function unionMap<K, V>(m1: Map<K, V>, m2: Map<K, V>) {\n  const result = new Map<K, V>();\n  m1.forEach((v, k) => result.set(k, v));\n  m2.forEach((v, k) => result.set(k, v));\n  return result;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/number.ts",
    "content": "/**\n * Clamps the given value between the given minimum float and maximum float values.\n * Returns the given value if it is within the min and max range.\n */\nexport function clamp(value: number, min: number, max: number): number {\n  if (max < min) {\n    max = min;\n  }\n  return Math.max(Math.min(value, max), min);\n}\n\n/**\n * Linearly interpolates between start and end by ratio.\n * When ratio = 0 returns start.\n * When ratio = 1 return end.\n * When ratio = 0.5 returns the midpoint of start and end.\n */\nexport function lerp(start: number, end: number, ratio: number): number {\n  return start * (1 - ratio) + end * ratio;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/object.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\n\nexport function stringifyKeys(map: StringMap<any>): StringMap<string> {\n  return Object.keys(map).reduce<StringMap<any>>((smap, k) => {\n    smap[k] = String(map[k]);\n    return smap;\n  }, {});\n}\n\nexport function stringifyKeysMap(stringMap: StringMap<any>): Map<string, string> {\n  const map = new Map();\n  Object.keys(stringMap).forEach(k => {\n    map.set(k, String(stringMap[k]));\n  });\n  return map;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/required.ts",
    "content": "/**\n * Requires the value to be not be undefined, otherwise an error is thrown\n * @param value the value that should not be undefined\n * @param message an error message if undefined\n * @returns the defined value\n */\nexport function required<T>(value: T | undefined, message?: string): T {\n  if (value === undefined) {\n    throw new TypeError(message);\n  }\n  return value;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/runWith.ts",
    "content": "/**\n * Convenience method for invoking a function with the specified input. Useful when the input\n * is a computed type, so that the type of the function to run doesn't need to be explicitly defined\n * @param input the input to runnable\n * @param runnable the function to run\n * @returns the output of runnable(input)\n */\nexport function runWith<T, R>(input: T, runnable: (input: T) => R): R {\n  return runnable(input);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/set.ts",
    "content": "export function symmetricDifference<T>(s1: Set<T>, s2: Set<T>): Set<T> {\n  const diff = new Set(s1);\n  for (const item of Array.from(s2)) {\n    if (diff.has(item)) {\n      diff.delete(item);\n    } else {\n      diff.add(item);\n    }\n  }\n  return diff;\n}\n\nexport function setsEquivalent<T>(s1: Set<T>, s2: Set<T>): boolean {\n  if (s1 === s2) return true;\n  if (s1.size !== s2.size) return false;\n\n  for (const item of Array.from(s1)) {\n    if (!s2.has(item)) {\n      return false;\n    }\n  }\n  return true;\n}\n\n/**\n * Computes predicate over a set returning the results in a new Map\n */\nexport function setToMap<T, U>(set: Set<T>, predicate: (item: T) => U): Map<T, U> {\n  const m = new Map<T, U>();\n  set.forEach(k => m.set(k, predicate(k)));\n  return m;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/shuffle.ts",
    "content": "/** Returns a new shuffled array of items given an array */\nexport function shuffleItems<T>(items: readonly T[]): T[] {\n  const shuffled = [...items];\n  for (let i = shuffled.length - 1; i > 0; i--) {\n    const j = Math.floor(Math.random() * (i + 1));\n    [shuffled[i], shuffled[j]] = [shuffled[j]!, shuffled[i]!];\n  }\n  return shuffled;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/staticImplements.ts",
    "content": "/**\n * class decorator.\n *\n * Use this decorator to leverage the type system to guarantee that the class you're annotating\n * statically conforms to a given interface T.\n */\nexport function staticImplements<T>() {\n  return <U extends T>(constructor: U) => {\n    constructor;\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/string.ts",
    "content": "/**\n * Given a URL path returns a slugified path.\n *\n * ie: '/rpc/search' becomes 'rpcsearch'\n *\n * ie:\n * /rpc/snapchat.premiumstories.PremiumStories/GetStory?story_id=577361270638592&profile=1\n * becomes\n * rpcsnapchatpremiumstoriesPremiumStoriesGetStory\n */\nexport function slugifyUrlPath(path: string): string {\n  return path\n    .replace(/\\?.*/g, '') // strip url parameters\n    .replace(/[^a-z0-9 -]/gi, '') // remove invalid chars\n    .replace(/\\s+/g, '-') // collapse whitespace and replace by -\n    .replace(/-+/g, '-'); // collapse dashes\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/time.ts",
    "content": "export enum TimeUnit {\n  HOURS,\n  SECONDS,\n}\n\nexport function convertTimestampMs(timestampMs: number, unit: TimeUnit): number {\n  switch (unit) {\n    case TimeUnit.HOURS:\n      return timestampMs / 1000 / 60 / 60;\n    case TimeUnit.SECONDS:\n      return timestampMs / 1000;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/trace.ts",
    "content": "/**\n * Wraps the Valdi trace function so that we can optionally require it. This is useful so we can run\n * unit tests without requiring Valdi core.\n */\n\ndeclare const require: any;\n\nlet traceFunction: any;\ntry {\n  traceFunction = require('valdi_core/src/utils/Trace').trace;\n} catch (err: any) {\n  console.log(`Could not load Trace module: ${err.message}`);\n}\n\nexport function trace<T>(tag: string, cb: () => T): T {\n  if (traceFunction) {\n    return traceFunction(tag, cb);\n  } else {\n    return cb();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/unicode.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\n\n/* tslint:disable:max-line-length */\nconst defaultDiacriticsRemovalMap: [string, string][] = [\n  [\n    'A',\n    '\\u0041\\u24B6\\uFF21\\u00C0\\u00C1\\u00C2\\u1EA6\\u1EA4\\u1EAA\\u1EA8\\u00C3\\u0100\\u0102\\u1EB0\\u1EAE\\u1EB4\\u1EB2\\u0226\\u01E0\\u00C4\\u01DE\\u1EA2\\u00C5\\u01FA\\u01CD\\u0200\\u0202\\u1EA0\\u1EAC\\u1EB6\\u1E00\\u0104\\u023A\\u2C6F',\n  ],\n  ['AA', '\\uA732'],\n  ['AE', '\\u00C6\\u01FC\\u01E2'],\n  ['AO', '\\uA734'],\n  ['AU', '\\uA736'],\n  ['AV', '\\uA738\\uA73A'],\n  ['AY', '\\uA73C'],\n  ['B', '\\u0042\\u24B7\\uFF22\\u1E02\\u1E04\\u1E06\\u0243\\u0182\\u0181'],\n  ['C', '\\u0043\\u24B8\\uFF23\\u0106\\u0108\\u010A\\u010C\\u00C7\\u1E08\\u0187\\u023B\\uA73E'],\n  ['D', '\\u0044\\u24B9\\uFF24\\u1E0A\\u010E\\u1E0C\\u1E10\\u1E12\\u1E0E\\u0110\\u018B\\u018A\\u0189\\uA779\\u00D0'],\n  ['DZ', '\\u01F1\\u01C4'],\n  ['Dz', '\\u01F2\\u01C5'],\n  [\n    'E',\n    '\\u0045\\u24BA\\uFF25\\u00C8\\u00C9\\u00CA\\u1EC0\\u1EBE\\u1EC4\\u1EC2\\u1EBC\\u0112\\u1E14\\u1E16\\u0114\\u0116\\u00CB\\u1EBA\\u011A\\u0204\\u0206\\u1EB8\\u1EC6\\u0228\\u1E1C\\u0118\\u1E18\\u1E1A\\u0190\\u018E',\n  ],\n  ['F', '\\u0046\\u24BB\\uFF26\\u1E1E\\u0191\\uA77B'],\n  ['G', '\\u0047\\u24BC\\uFF27\\u01F4\\u011C\\u1E20\\u011E\\u0120\\u01E6\\u0122\\u01E4\\u0193\\uA7A0\\uA77D\\uA77E'],\n  ['H', '\\u0048\\u24BD\\uFF28\\u0124\\u1E22\\u1E26\\u021E\\u1E24\\u1E28\\u1E2A\\u0126\\u2C67\\u2C75\\uA78D'],\n  [\n    'I',\n    '\\u0049\\u24BE\\uFF29\\u00CC\\u00CD\\u00CE\\u0128\\u012A\\u012C\\u0130\\u00CF\\u1E2E\\u1EC8\\u01CF\\u0208\\u020A\\u1ECA\\u012E\\u1E2C\\u0197',\n  ],\n  ['J', '\\u004A\\u24BF\\uFF2A\\u0134\\u0248'],\n  ['K', '\\u004B\\u24C0\\uFF2B\\u1E30\\u01E8\\u1E32\\u0136\\u1E34\\u0198\\u2C69\\uA740\\uA742\\uA744\\uA7A2'],\n  ['L', '\\u004C\\u24C1\\uFF2C\\u013F\\u0139\\u013D\\u1E36\\u1E38\\u013B\\u1E3C\\u1E3A\\u0141\\u023D\\u2C62\\u2C60\\uA748\\uA746\\uA780'],\n  ['LJ', '\\u01C7'],\n  ['Lj', '\\u01C8'],\n  ['M', '\\u004D\\u24C2\\uFF2D\\u1E3E\\u1E40\\u1E42\\u2C6E\\u019C'],\n  ['N', '\\u004E\\u24C3\\uFF2E\\u01F8\\u0143\\u00D1\\u1E44\\u0147\\u1E46\\u0145\\u1E4A\\u1E48\\u0220\\u019D\\uA790\\uA7A4'],\n  ['NJ', '\\u01CA'],\n  ['Nj', '\\u01CB'],\n  [\n    'O',\n    '\\u004F\\u24C4\\uFF2F\\u00D2\\u00D3\\u00D4\\u1ED2\\u1ED0\\u1ED6\\u1ED4\\u00D5\\u1E4C\\u022C\\u1E4E\\u014C\\u1E50\\u1E52\\u014E\\u022E\\u0230\\u00D6\\u022A\\u1ECE\\u0150\\u01D1\\u020C\\u020E\\u01A0\\u1EDC\\u1EDA\\u1EE0\\u1EDE\\u1EE2\\u1ECC\\u1ED8\\u01EA\\u01EC\\u00D8\\u01FE\\u0186\\u019F\\uA74A\\uA74C',\n  ],\n  ['OI', '\\u01A2'],\n  ['OO', '\\uA74E'],\n  ['OU', '\\u0222'],\n  ['OE', '\\u008C\\u0152'],\n  ['oe', '\\u009C\\u0153'],\n  ['P', '\\u0050\\u24C5\\uFF30\\u1E54\\u1E56\\u01A4\\u2C63\\uA750\\uA752\\uA754'],\n  ['Q', '\\u0051\\u24C6\\uFF31\\uA756\\uA758\\u024A'],\n  ['R', '\\u0052\\u24C7\\uFF32\\u0154\\u1E58\\u0158\\u0210\\u0212\\u1E5A\\u1E5C\\u0156\\u1E5E\\u024C\\u2C64\\uA75A\\uA7A6\\uA782'],\n  ['S', '\\u0053\\u24C8\\uFF33\\u1E9E\\u015A\\u1E64\\u015C\\u1E60\\u0160\\u1E66\\u1E62\\u1E68\\u0218\\u015E\\u2C7E\\uA7A8\\uA784'],\n  ['T', '\\u0054\\u24C9\\uFF34\\u1E6A\\u0164\\u1E6C\\u021A\\u0162\\u1E70\\u1E6E\\u0166\\u01AC\\u01AE\\u023E\\uA786'],\n  ['TZ', '\\uA728'],\n  [\n    'U',\n    '\\u0055\\u24CA\\uFF35\\u00D9\\u00DA\\u00DB\\u0168\\u1E78\\u016A\\u1E7A\\u016C\\u00DC\\u01DB\\u01D7\\u01D5\\u01D9\\u1EE6\\u016E\\u0170\\u01D3\\u0214\\u0216\\u01AF\\u1EEA\\u1EE8\\u1EEE\\u1EEC\\u1EF0\\u1EE4\\u1E72\\u0172\\u1E76\\u1E74\\u0244',\n  ],\n  ['V', '\\u0056\\u24CB\\uFF36\\u1E7C\\u1E7E\\u01B2\\uA75E\\u0245'],\n  ['VY', '\\uA760'],\n  ['W', '\\u0057\\u24CC\\uFF37\\u1E80\\u1E82\\u0174\\u1E86\\u1E84\\u1E88\\u2C72'],\n  ['X', '\\u0058\\u24CD\\uFF38\\u1E8A\\u1E8C'],\n  ['Y', '\\u0059\\u24CE\\uFF39\\u1EF2\\u00DD\\u0176\\u1EF8\\u0232\\u1E8E\\u0178\\u1EF6\\u1EF4\\u01B3\\u024E\\u1EFE'],\n  ['Z', '\\u005A\\u24CF\\uFF3A\\u0179\\u1E90\\u017B\\u017D\\u1E92\\u1E94\\u01B5\\u0224\\u2C7F\\u2C6B\\uA762'],\n  [\n    'a',\n    '\\u0061\\u24D0\\uFF41\\u1E9A\\u00E0\\u00E1\\u00E2\\u1EA7\\u1EA5\\u1EAB\\u1EA9\\u00E3\\u0101\\u0103\\u1EB1\\u1EAF\\u1EB5\\u1EB3\\u0227\\u01E1\\u00E4\\u01DF\\u1EA3\\u00E5\\u01FB\\u01CE\\u0201\\u0203\\u1EA1\\u1EAD\\u1EB7\\u1E01\\u0105\\u2C65\\u0250',\n  ],\n  ['aa', '\\uA733'],\n  ['ae', '\\u00E6\\u01FD\\u01E3'],\n  ['ao', '\\uA735'],\n  ['au', '\\uA737'],\n  ['av', '\\uA739\\uA73B'],\n  ['ay', '\\uA73D'],\n  ['b', '\\u0062\\u24D1\\uFF42\\u1E03\\u1E05\\u1E07\\u0180\\u0183\\u0253'],\n  ['c', '\\u0063\\u24D2\\uFF43\\u0107\\u0109\\u010B\\u010D\\u00E7\\u1E09\\u0188\\u023C\\uA73F\\u2184'],\n  ['d', '\\u0064\\u24D3\\uFF44\\u1E0B\\u010F\\u1E0D\\u1E11\\u1E13\\u1E0F\\u0111\\u018C\\u0256\\u0257\\uA77A'],\n  ['dz', '\\u01F3\\u01C6'],\n  [\n    'e',\n    '\\u0065\\u24D4\\uFF45\\u00E8\\u00E9\\u00EA\\u1EC1\\u1EBF\\u1EC5\\u1EC3\\u1EBD\\u0113\\u1E15\\u1E17\\u0115\\u0117\\u00EB\\u1EBB\\u011B\\u0205\\u0207\\u1EB9\\u1EC7\\u0229\\u1E1D\\u0119\\u1E19\\u1E1B\\u0247\\u025B\\u01DD',\n  ],\n  ['f', '\\u0066\\u24D5\\uFF46\\u1E1F\\u0192\\uA77C'],\n  ['g', '\\u0067\\u24D6\\uFF47\\u01F5\\u011D\\u1E21\\u011F\\u0121\\u01E7\\u0123\\u01E5\\u0260\\uA7A1\\u1D79\\uA77F'],\n  ['h', '\\u0068\\u24D7\\uFF48\\u0125\\u1E23\\u1E27\\u021F\\u1E25\\u1E29\\u1E2B\\u1E96\\u0127\\u2C68\\u2C76\\u0265'],\n  ['hv', '\\u0195'],\n  [\n    'i',\n    '\\u0069\\u24D8\\uFF49\\u00EC\\u00ED\\u00EE\\u0129\\u012B\\u012D\\u00EF\\u1E2F\\u1EC9\\u01D0\\u0209\\u020B\\u1ECB\\u012F\\u1E2D\\u0268\\u0131',\n  ],\n  ['j', '\\u006A\\u24D9\\uFF4A\\u0135\\u01F0\\u0249'],\n  ['k', '\\u006B\\u24DA\\uFF4B\\u1E31\\u01E9\\u1E33\\u0137\\u1E35\\u0199\\u2C6A\\uA741\\uA743\\uA745\\uA7A3'],\n  [\n    'l',\n    '\\u006C\\u24DB\\uFF4C\\u0140\\u013A\\u013E\\u1E37\\u1E39\\u013C\\u1E3D\\u1E3B\\u017F\\u0142\\u019A\\u026B\\u2C61\\uA749\\uA781\\uA747',\n  ],\n  ['lj', '\\u01C9'],\n  ['m', '\\u006D\\u24DC\\uFF4D\\u1E3F\\u1E41\\u1E43\\u0271\\u026F'],\n  ['n', '\\u006E\\u24DD\\uFF4E\\u01F9\\u0144\\u00F1\\u1E45\\u0148\\u1E47\\u0146\\u1E4B\\u1E49\\u019E\\u0272\\u0149\\uA791\\uA7A5'],\n  ['nj', '\\u01CC'],\n  [\n    'o',\n    '\\u006F\\u24DE\\uFF4F\\u00F2\\u00F3\\u00F4\\u1ED3\\u1ED1\\u1ED7\\u1ED5\\u00F5\\u1E4D\\u022D\\u1E4F\\u014D\\u1E51\\u1E53\\u014F\\u022F\\u0231\\u00F6\\u022B\\u1ECF\\u0151\\u01D2\\u020D\\u020F\\u01A1\\u1EDD\\u1EDB\\u1EE1\\u1EDF\\u1EE3\\u1ECD\\u1ED9\\u01EB\\u01ED\\u00F8\\u01FF\\u0254\\uA74B\\uA74D\\u0275',\n  ],\n  ['oi', '\\u01A3'],\n  ['ou', '\\u0223'],\n  ['oo', '\\uA74F'],\n  ['p', '\\u0070\\u24DF\\uFF50\\u1E55\\u1E57\\u01A5\\u1D7D\\uA751\\uA753\\uA755'],\n  ['q', '\\u0071\\u24E0\\uFF51\\u024B\\uA757\\uA759'],\n  ['r', '\\u0072\\u24E1\\uFF52\\u0155\\u1E59\\u0159\\u0211\\u0213\\u1E5B\\u1E5D\\u0157\\u1E5F\\u024D\\u027D\\uA75B\\uA7A7\\uA783'],\n  ['s', '\\u0073\\u24E2\\uFF53\\u00DF\\u015B\\u1E65\\u015D\\u1E61\\u0161\\u1E67\\u1E63\\u1E69\\u0219\\u015F\\u023F\\uA7A9\\uA785\\u1E9B'],\n  ['t', '\\u0074\\u24E3\\uFF54\\u1E6B\\u1E97\\u0165\\u1E6D\\u021B\\u0163\\u1E71\\u1E6F\\u0167\\u01AD\\u0288\\u2C66\\uA787'],\n  ['tz', '\\uA729'],\n  [\n    'u',\n    '\\u0075\\u24E4\\uFF55\\u00F9\\u00FA\\u00FB\\u0169\\u1E79\\u016B\\u1E7B\\u016D\\u00FC\\u01DC\\u01D8\\u01D6\\u01DA\\u1EE7\\u016F\\u0171\\u01D4\\u0215\\u0217\\u01B0\\u1EEB\\u1EE9\\u1EEF\\u1EED\\u1EF1\\u1EE5\\u1E73\\u0173\\u1E77\\u1E75\\u0289',\n  ],\n  ['v', '\\u0076\\u24E5\\uFF56\\u1E7D\\u1E7F\\u028B\\uA75F\\u028C'],\n  ['vy', '\\uA761'],\n  ['w', '\\u0077\\u24E6\\uFF57\\u1E81\\u1E83\\u0175\\u1E87\\u1E85\\u1E98\\u1E89\\u2C73'],\n  ['x', '\\u0078\\u24E7\\uFF58\\u1E8B\\u1E8D'],\n  ['y', '\\u0079\\u24E8\\uFF59\\u1EF3\\u00FD\\u0177\\u1EF9\\u0233\\u1E8F\\u00FF\\u1EF7\\u1E99\\u1EF5\\u01B4\\u024F\\u1EFF'],\n  ['z', '\\u007A\\u24E9\\uFF5A\\u017A\\u1E91\\u017C\\u017E\\u1E93\\u1E95\\u01B6\\u0225\\u0240\\u2C6C\\uA763'],\n];\n\nconst diacriticsMap = (function () {\n  const m: StringMap<string> = {};\n  for (const [base, letters] of defaultDiacriticsRemovalMap) {\n    for (const l of letters) {\n      m[l] = base;\n    }\n  }\n  return m;\n})();\n\nconst keycapsMap: StringMap<string> = {\n  '\\u0030\\uFE0F\\u20E3': '0',\n  '\\u0030\\u20E3': '0',\n  '\\u0031\\uFE0F\\u20E3': '1',\n  '\\u0031\\u20E3': '1',\n  '\\u0032\\uFE0F\\u20E3': '2',\n  '\\u0032\\u20E3': '2',\n  '\\u0033\\uFE0F\\u20E3': '3',\n  '\\u0033\\u20E3': '3',\n  '\\u0034\\uFE0F\\u20E3': '4',\n  '\\u0034\\u20E3': '4',\n  '\\u0035\\uFE0F\\u20E3': '5',\n  '\\u0035\\u20E3': '5',\n  '\\u0036\\uFE0F\\u20E3': '6',\n  '\\u0036\\u20E3': '6',\n  '\\u0037\\uFE0F\\u20E3': '7',\n  '\\u0037\\u20E3': '7',\n  '\\u0038\\uFE0F\\u20E3': '8',\n  '\\u0038\\u20E3': '8',\n  '\\u0039\\uFE0F\\u20E3': '9',\n  '\\u0039\\u20E3': '9',\n  '\\u0023\\uFE0F\\u20E3': '#',\n  '\\u0023\\u20E3': '#',\n  '\\u002A\\uFE0F\\u20E3': '*',\n  '\\u002A\\u20E3': '*',\n};\n\nconst mathAlphaMap: StringMap<string> = {\n  '\\ud835\\udc00': 'A',\n  '\\ud835\\udc01': 'B',\n  '\\ud835\\udc02': 'C',\n  '\\ud835\\udc03': 'D',\n  '\\ud835\\udc04': 'E',\n  '\\ud835\\udc05': 'F',\n  '\\ud835\\udc06': 'G',\n  '\\ud835\\udc07': 'H',\n  '\\ud835\\udc08': 'I',\n  '\\ud835\\udc09': 'J',\n  '\\ud835\\udc0a': 'K',\n  '\\ud835\\udc0b': 'L',\n  '\\ud835\\udc0c': 'M',\n  '\\ud835\\udc0d': 'N',\n  '\\ud835\\udc0e': 'O',\n  '\\ud835\\udc0f': 'P',\n  '\\ud835\\udc10': 'Q',\n  '\\ud835\\udc11': 'R',\n  '\\ud835\\udc12': 'S',\n  '\\ud835\\udc13': 'T',\n  '\\ud835\\udc14': 'U',\n  '\\ud835\\udc15': 'V',\n  '\\ud835\\udc16': 'W',\n  '\\ud835\\udc17': 'X',\n  '\\ud835\\udc18': 'Y',\n  '\\ud835\\udc19': 'Z',\n  '\\ud835\\udc1a': 'a',\n  '\\ud835\\udc1b': 'b',\n  '\\ud835\\udc1c': 'c',\n  '\\ud835\\udc1d': 'd',\n  '\\ud835\\udc1e': 'e',\n  '\\ud835\\udc1f': 'f',\n  '\\ud835\\udc20': 'g',\n  '\\ud835\\udc21': 'h',\n  '\\ud835\\udc22': 'i',\n  '\\ud835\\udc23': 'j',\n  '\\ud835\\udc24': 'k',\n  '\\ud835\\udc25': 'l',\n  '\\ud835\\udc26': 'm',\n  '\\ud835\\udc27': 'n',\n  '\\ud835\\udc28': 'o',\n  '\\ud835\\udc29': 'p',\n  '\\ud835\\udc2a': 'q',\n  '\\ud835\\udc2b': 'r',\n  '\\ud835\\udc2c': 's',\n  '\\ud835\\udc2d': 't',\n  '\\ud835\\udc2e': 'u',\n  '\\ud835\\udc2f': 'v',\n  '\\ud835\\udc30': 'w',\n  '\\ud835\\udc31': 'x',\n  '\\ud835\\udc32': 'y',\n  '\\ud835\\udc33': 'z',\n  '\\ud835\\udc34': 'A',\n  '\\ud835\\udc35': 'B',\n  '\\ud835\\udc36': 'C',\n  '\\ud835\\udc37': 'D',\n  '\\ud835\\udc38': 'E',\n  '\\ud835\\udc39': 'F',\n  '\\ud835\\udc3a': 'G',\n  '\\ud835\\udc3b': 'H',\n  '\\ud835\\udc3c': 'I',\n  '\\ud835\\udc3d': 'J',\n  '\\ud835\\udc3e': 'K',\n  '\\ud835\\udc3f': 'L',\n  '\\ud835\\udc40': 'M',\n  '\\ud835\\udc41': 'N',\n  '\\ud835\\udc42': 'O',\n  '\\ud835\\udc43': 'P',\n  '\\ud835\\udc44': 'Q',\n  '\\ud835\\udc45': 'R',\n  '\\ud835\\udc46': 'S',\n  '\\ud835\\udc47': 'T',\n  '\\ud835\\udc48': 'U',\n  '\\ud835\\udc49': 'V',\n  '\\ud835\\udc4a': 'W',\n  '\\ud835\\udc4b': 'X',\n  '\\ud835\\udc4c': 'Y',\n  '\\ud835\\udc4d': 'Z',\n  '\\ud835\\udc4e': 'a',\n  '\\ud835\\udc4f': 'b',\n  '\\ud835\\udc50': 'c',\n  '\\ud835\\udc51': 'd',\n  '\\ud835\\udc52': 'e',\n  '\\ud835\\udc53': 'f',\n  '\\ud835\\udc54': 'g',\n  '\\ud835\\udc55': 'h',\n  '\\ud835\\udc56': 'i',\n  '\\ud835\\udc57': 'j',\n  '\\ud835\\udc58': 'k',\n  '\\ud835\\udc59': 'l',\n  '\\ud835\\udc5a': 'm',\n  '\\ud835\\udc5b': 'n',\n  '\\ud835\\udc5c': 'o',\n  '\\ud835\\udc5d': 'p',\n  '\\ud835\\udc5e': 'q',\n  '\\ud835\\udc5f': 'r',\n  '\\ud835\\udc60': 's',\n  '\\ud835\\udc61': 't',\n  '\\ud835\\udc62': 'u',\n  '\\ud835\\udc63': 'v',\n  '\\ud835\\udc64': 'w',\n  '\\ud835\\udc65': 'x',\n  '\\ud835\\udc66': 'y',\n  '\\ud835\\udc67': 'z',\n  '\\ud835\\udc68': 'A',\n  '\\ud835\\udc69': 'B',\n  '\\ud835\\udc6a': 'C',\n  '\\ud835\\udc6b': 'D',\n  '\\ud835\\udc6c': 'E',\n  '\\ud835\\udc6d': 'F',\n  '\\ud835\\udc6e': 'G',\n  '\\ud835\\udc6f': 'H',\n  '\\ud835\\udc70': 'I',\n  '\\ud835\\udc71': 'J',\n  '\\ud835\\udc72': 'K',\n  '\\ud835\\udc73': 'L',\n  '\\ud835\\udc74': 'M',\n  '\\ud835\\udc75': 'N',\n  '\\ud835\\udc76': 'O',\n  '\\ud835\\udc77': 'P',\n  '\\ud835\\udc78': 'Q',\n  '\\ud835\\udc79': 'R',\n  '\\ud835\\udc7a': 'S',\n  '\\ud835\\udc7b': 'T',\n  '\\ud835\\udc7c': 'U',\n  '\\ud835\\udc7d': 'V',\n  '\\ud835\\udc7e': 'W',\n  '\\ud835\\udc7f': 'X',\n  '\\ud835\\udc80': 'Y',\n  '\\ud835\\udc81': 'Z',\n  '\\ud835\\udc82': 'a',\n  '\\ud835\\udc83': 'b',\n  '\\ud835\\udc84': 'c',\n  '\\ud835\\udc85': 'd',\n  '\\ud835\\udc86': 'e',\n  '\\ud835\\udc87': 'f',\n  '\\ud835\\udc88': 'g',\n  '\\ud835\\udc89': 'h',\n  '\\ud835\\udc8a': 'i',\n  '\\ud835\\udc8b': 'j',\n  '\\ud835\\udc8c': 'k',\n  '\\ud835\\udc8d': 'l',\n  '\\ud835\\udc8e': 'm',\n  '\\ud835\\udc8f': 'n',\n  '\\ud835\\udc90': 'o',\n  '\\ud835\\udc91': 'p',\n  '\\ud835\\udc92': 'q',\n  '\\ud835\\udc93': 'r',\n  '\\ud835\\udc94': 's',\n  '\\ud835\\udc95': 't',\n  '\\ud835\\udc96': 'u',\n  '\\ud835\\udc97': 'v',\n  '\\ud835\\udc98': 'w',\n  '\\ud835\\udc99': 'x',\n  '\\ud835\\udc9a': 'y',\n  '\\ud835\\udc9b': 'z',\n  '\\ud835\\udc9c': 'A',\n  '\\ud835\\udc9d': 'B',\n  '\\ud835\\udc9e': 'C',\n  '\\ud835\\udc9f': 'D',\n  '\\ud835\\udca0': 'E',\n  '\\ud835\\udca1': 'F',\n  '\\ud835\\udca2': 'G',\n  '\\ud835\\udca3': 'H',\n  '\\ud835\\udca4': 'I',\n  '\\ud835\\udca5': 'J',\n  '\\ud835\\udca6': 'K',\n  '\\ud835\\udca7': 'L',\n  '\\ud835\\udca8': 'M',\n  '\\ud835\\udca9': 'N',\n  '\\ud835\\udcaa': 'O',\n  '\\ud835\\udcab': 'P',\n  '\\ud835\\udcac': 'Q',\n  '\\ud835\\udcad': 'R',\n  '\\ud835\\udcae': 'S',\n  '\\ud835\\udcaf': 'T',\n  '\\ud835\\udcb0': 'U',\n  '\\ud835\\udcb1': 'V',\n  '\\ud835\\udcb2': 'W',\n  '\\ud835\\udcb3': 'X',\n  '\\ud835\\udcb4': 'Y',\n  '\\ud835\\udcb5': 'Z',\n  '\\ud835\\udcb6': 'a',\n  '\\ud835\\udcb7': 'b',\n  '\\ud835\\udcb8': 'c',\n  '\\ud835\\udcb9': 'd',\n  '\\ud835\\udcba': 'e',\n  '\\ud835\\udcbb': 'f',\n  '\\ud835\\udcbc': 'g',\n  '\\ud835\\udcbd': 'h',\n  '\\ud835\\udcbe': 'i',\n  '\\ud835\\udcbf': 'j',\n  '\\ud835\\udcc0': 'k',\n  '\\ud835\\udcc1': 'l',\n  '\\ud835\\udcc2': 'm',\n  '\\ud835\\udcc3': 'n',\n  '\\ud835\\udcc4': 'o',\n  '\\ud835\\udcc5': 'p',\n  '\\ud835\\udcc6': 'q',\n  '\\ud835\\udcc7': 'r',\n  '\\ud835\\udcc8': 's',\n  '\\ud835\\udcc9': 't',\n  '\\ud835\\udcca': 'u',\n  '\\ud835\\udccb': 'v',\n  '\\ud835\\udccc': 'w',\n  '\\ud835\\udccd': 'x',\n  '\\ud835\\udcce': 'y',\n  '\\ud835\\udccf': 'z',\n  '\\ud835\\udcd0': 'A',\n  '\\ud835\\udcd1': 'B',\n  '\\ud835\\udcd2': 'C',\n  '\\ud835\\udcd3': 'D',\n  '\\ud835\\udcd4': 'E',\n  '\\ud835\\udcd5': 'F',\n  '\\ud835\\udcd6': 'G',\n  '\\ud835\\udcd7': 'H',\n  '\\ud835\\udcd8': 'I',\n  '\\ud835\\udcd9': 'J',\n  '\\ud835\\udcda': 'K',\n  '\\ud835\\udcdb': 'L',\n  '\\ud835\\udcdc': 'M',\n  '\\ud835\\udcdd': 'N',\n  '\\ud835\\udcde': 'O',\n  '\\ud835\\udcdf': 'P',\n  '\\ud835\\udce0': 'Q',\n  '\\ud835\\udce1': 'R',\n  '\\ud835\\udce2': 'S',\n  '\\ud835\\udce3': 'T',\n  '\\ud835\\udce4': 'U',\n  '\\ud835\\udce5': 'V',\n  '\\ud835\\udce6': 'W',\n  '\\ud835\\udce7': 'X',\n  '\\ud835\\udce8': 'Y',\n  '\\ud835\\udce9': 'Z',\n  '\\ud835\\udcea': 'a',\n  '\\ud835\\udceb': 'b',\n  '\\ud835\\udcec': 'c',\n  '\\ud835\\udced': 'd',\n  '\\ud835\\udcee': 'e',\n  '\\ud835\\udcef': 'f',\n  '\\ud835\\udcf0': 'g',\n  '\\ud835\\udcf1': 'h',\n  '\\ud835\\udcf2': 'i',\n  '\\ud835\\udcf3': 'j',\n  '\\ud835\\udcf4': 'k',\n  '\\ud835\\udcf5': 'l',\n  '\\ud835\\udcf6': 'm',\n  '\\ud835\\udcf7': 'n',\n  '\\ud835\\udcf8': 'o',\n  '\\ud835\\udcf9': 'p',\n  '\\ud835\\udcfa': 'q',\n  '\\ud835\\udcfb': 'r',\n  '\\ud835\\udcfc': 's',\n  '\\ud835\\udcfd': 't',\n  '\\ud835\\udcfe': 'u',\n  '\\ud835\\udcff': 'v',\n  '\\ud835\\udd00': 'w',\n  '\\ud835\\udd01': 'x',\n  '\\ud835\\udd02': 'y',\n  '\\ud835\\udd03': 'z',\n  '\\ud835\\udd04': 'A',\n  '\\ud835\\udd05': 'B',\n  '\\ud835\\udd06': 'C',\n  '\\ud835\\udd07': 'D',\n  '\\ud835\\udd08': 'E',\n  '\\ud835\\udd09': 'F',\n  '\\ud835\\udd0a': 'G',\n  '\\ud835\\udd0b': 'H',\n  '\\ud835\\udd0c': 'I',\n  '\\ud835\\udd0d': 'J',\n  '\\ud835\\udd0e': 'K',\n  '\\ud835\\udd0f': 'L',\n  '\\ud835\\udd10': 'M',\n  '\\ud835\\udd11': 'N',\n  '\\ud835\\udd12': 'O',\n  '\\ud835\\udd13': 'P',\n  '\\ud835\\udd14': 'Q',\n  '\\ud835\\udd15': 'R',\n  '\\ud835\\udd16': 'S',\n  '\\ud835\\udd17': 'T',\n  '\\ud835\\udd18': 'U',\n  '\\ud835\\udd19': 'V',\n  '\\ud835\\udd1a': 'W',\n  '\\ud835\\udd1b': 'X',\n  '\\ud835\\udd1c': 'Y',\n  '\\ud835\\udd1d': 'Z',\n  '\\ud835\\udd1e': 'a',\n  '\\ud835\\udd1f': 'b',\n  '\\ud835\\udd20': 'c',\n  '\\ud835\\udd21': 'd',\n  '\\ud835\\udd22': 'e',\n  '\\ud835\\udd23': 'f',\n  '\\ud835\\udd24': 'g',\n  '\\ud835\\udd25': 'h',\n  '\\ud835\\udd26': 'i',\n  '\\ud835\\udd27': 'j',\n  '\\ud835\\udd28': 'k',\n  '\\ud835\\udd29': 'l',\n  '\\ud835\\udd2a': 'm',\n  '\\ud835\\udd2b': 'n',\n  '\\ud835\\udd2c': 'o',\n  '\\ud835\\udd2d': 'p',\n  '\\ud835\\udd2e': 'q',\n  '\\ud835\\udd2f': 'r',\n  '\\ud835\\udd30': 's',\n  '\\ud835\\udd31': 't',\n  '\\ud835\\udd32': 'u',\n  '\\ud835\\udd33': 'v',\n  '\\ud835\\udd34': 'w',\n  '\\ud835\\udd35': 'x',\n  '\\ud835\\udd36': 'y',\n  '\\ud835\\udd37': 'z',\n  '\\ud835\\udd38': 'A',\n  '\\ud835\\udd39': 'B',\n  '\\ud835\\udd3a': 'C',\n  '\\ud835\\udd3b': 'D',\n  '\\ud835\\udd3c': 'E',\n  '\\ud835\\udd3d': 'F',\n  '\\ud835\\udd3e': 'G',\n  '\\ud835\\udd3f': 'H',\n  '\\ud835\\udd40': 'I',\n  '\\ud835\\udd41': 'J',\n  '\\ud835\\udd42': 'K',\n  '\\ud835\\udd43': 'L',\n  '\\ud835\\udd44': 'M',\n  '\\ud835\\udd45': 'N',\n  '\\ud835\\udd46': 'O',\n  '\\ud835\\udd47': 'P',\n  '\\ud835\\udd48': 'Q',\n  '\\ud835\\udd49': 'R',\n  '\\ud835\\udd4a': 'S',\n  '\\ud835\\udd4b': 'T',\n  '\\ud835\\udd4c': 'U',\n  '\\ud835\\udd4d': 'V',\n  '\\ud835\\udd4e': 'W',\n  '\\ud835\\udd4f': 'X',\n  '\\ud835\\udd50': 'Y',\n  '\\ud835\\udd51': 'Z',\n  '\\ud835\\udd52': 'a',\n  '\\ud835\\udd53': 'b',\n  '\\ud835\\udd54': 'c',\n  '\\ud835\\udd55': 'd',\n  '\\ud835\\udd56': 'e',\n  '\\ud835\\udd57': 'f',\n  '\\ud835\\udd58': 'g',\n  '\\ud835\\udd59': 'h',\n  '\\ud835\\udd5a': 'i',\n  '\\ud835\\udd5b': 'j',\n  '\\ud835\\udd5c': 'k',\n  '\\ud835\\udd5d': 'l',\n  '\\ud835\\udd5e': 'm',\n  '\\ud835\\udd5f': 'n',\n  '\\ud835\\udd60': 'o',\n  '\\ud835\\udd61': 'p',\n  '\\ud835\\udd62': 'q',\n  '\\ud835\\udd63': 'r',\n  '\\ud835\\udd64': 's',\n  '\\ud835\\udd65': 't',\n  '\\ud835\\udd66': 'u',\n  '\\ud835\\udd67': 'v',\n  '\\ud835\\udd68': 'w',\n  '\\ud835\\udd69': 'x',\n  '\\ud835\\udd6a': 'y',\n  '\\ud835\\udd6b': 'z',\n  '\\ud835\\udd6c': 'A',\n  '\\ud835\\udd6d': 'B',\n  '\\ud835\\udd6e': 'C',\n  '\\ud835\\udd6f': 'D',\n  '\\ud835\\udd70': 'E',\n  '\\ud835\\udd71': 'F',\n  '\\ud835\\udd72': 'G',\n  '\\ud835\\udd73': 'H',\n  '\\ud835\\udd74': 'I',\n  '\\ud835\\udd75': 'J',\n  '\\ud835\\udd76': 'K',\n  '\\ud835\\udd77': 'L',\n  '\\ud835\\udd78': 'M',\n  '\\ud835\\udd79': 'N',\n  '\\ud835\\udd7a': 'O',\n  '\\ud835\\udd7b': 'P',\n  '\\ud835\\udd7c': 'Q',\n  '\\ud835\\udd7d': 'R',\n  '\\ud835\\udd7e': 'S',\n  '\\ud835\\udd7f': 'T',\n  '\\ud835\\udd80': 'U',\n  '\\ud835\\udd81': 'V',\n  '\\ud835\\udd82': 'W',\n  '\\ud835\\udd83': 'X',\n  '\\ud835\\udd84': 'Y',\n  '\\ud835\\udd85': 'Z',\n  '\\ud835\\udd86': 'a',\n  '\\ud835\\udd87': 'b',\n  '\\ud835\\udd88': 'c',\n  '\\ud835\\udd89': 'd',\n  '\\ud835\\udd8a': 'e',\n  '\\ud835\\udd8b': 'f',\n  '\\ud835\\udd8c': 'g',\n  '\\ud835\\udd8d': 'h',\n  '\\ud835\\udd8e': 'i',\n  '\\ud835\\udd8f': 'j',\n  '\\ud835\\udd90': 'k',\n  '\\ud835\\udd91': 'l',\n  '\\ud835\\udd92': 'm',\n  '\\ud835\\udd93': 'n',\n  '\\ud835\\udd94': 'o',\n  '\\ud835\\udd95': 'p',\n  '\\ud835\\udd96': 'q',\n  '\\ud835\\udd97': 'r',\n  '\\ud835\\udd98': 's',\n  '\\ud835\\udd99': 't',\n  '\\ud835\\udd9a': 'u',\n  '\\ud835\\udd9b': 'v',\n  '\\ud835\\udd9c': 'w',\n  '\\ud835\\udd9d': 'x',\n  '\\ud835\\udd9e': 'y',\n  '\\ud835\\udd9f': 'z',\n  '\\ud835\\udda0': 'A',\n  '\\ud835\\udda1': 'B',\n  '\\ud835\\udda2': 'C',\n  '\\ud835\\udda3': 'D',\n  '\\ud835\\udda4': 'E',\n  '\\ud835\\udda5': 'F',\n  '\\ud835\\udda6': 'G',\n  '\\ud835\\udda7': 'H',\n  '\\ud835\\udda8': 'I',\n  '\\ud835\\udda9': 'J',\n  '\\ud835\\uddaa': 'K',\n  '\\ud835\\uddab': 'L',\n  '\\ud835\\uddac': 'M',\n  '\\ud835\\uddad': 'N',\n  '\\ud835\\uddae': 'O',\n  '\\ud835\\uddaf': 'P',\n  '\\ud835\\uddb0': 'Q',\n  '\\ud835\\uddb1': 'R',\n  '\\ud835\\uddb2': 'S',\n  '\\ud835\\uddb3': 'T',\n  '\\ud835\\uddb4': 'U',\n  '\\ud835\\uddb5': 'V',\n  '\\ud835\\uddb6': 'W',\n  '\\ud835\\uddb7': 'X',\n  '\\ud835\\uddb8': 'Y',\n  '\\ud835\\uddb9': 'Z',\n  '\\ud835\\uddba': 'a',\n  '\\ud835\\uddbb': 'b',\n  '\\ud835\\uddbc': 'c',\n  '\\ud835\\uddbd': 'd',\n  '\\ud835\\uddbe': 'e',\n  '\\ud835\\uddbf': 'f',\n  '\\ud835\\uddc0': 'g',\n  '\\ud835\\uddc1': 'h',\n  '\\ud835\\uddc2': 'i',\n  '\\ud835\\uddc3': 'j',\n  '\\ud835\\uddc4': 'k',\n  '\\ud835\\uddc5': 'l',\n  '\\ud835\\uddc6': 'm',\n  '\\ud835\\uddc7': 'n',\n  '\\ud835\\uddc8': 'o',\n  '\\ud835\\uddc9': 'p',\n  '\\ud835\\uddca': 'q',\n  '\\ud835\\uddcb': 'r',\n  '\\ud835\\uddcc': 's',\n  '\\ud835\\uddcd': 't',\n  '\\ud835\\uddce': 'u',\n  '\\ud835\\uddcf': 'v',\n  '\\ud835\\uddd0': 'w',\n  '\\ud835\\uddd1': 'x',\n  '\\ud835\\uddd2': 'y',\n  '\\ud835\\uddd3': 'z',\n  '\\ud835\\uddd4': 'A',\n  '\\ud835\\uddd5': 'B',\n  '\\ud835\\uddd6': 'C',\n  '\\ud835\\uddd7': 'D',\n  '\\ud835\\uddd8': 'E',\n  '\\ud835\\uddd9': 'F',\n  '\\ud835\\uddda': 'G',\n  '\\ud835\\udddb': 'H',\n  '\\ud835\\udddc': 'I',\n  '\\ud835\\udddd': 'J',\n  '\\ud835\\uddde': 'K',\n  '\\ud835\\udddf': 'L',\n  '\\ud835\\udde0': 'M',\n  '\\ud835\\udde1': 'N',\n  '\\ud835\\udde2': 'O',\n  '\\ud835\\udde3': 'P',\n  '\\ud835\\udde4': 'Q',\n  '\\ud835\\udde5': 'R',\n  '\\ud835\\udde6': 'S',\n  '\\ud835\\udde7': 'T',\n  '\\ud835\\udde8': 'U',\n  '\\ud835\\udde9': 'V',\n  '\\ud835\\uddea': 'W',\n  '\\ud835\\uddeb': 'X',\n  '\\ud835\\uddec': 'Y',\n  '\\ud835\\udded': 'Z',\n  '\\ud835\\uddee': 'a',\n  '\\ud835\\uddef': 'b',\n  '\\ud835\\uddf0': 'c',\n  '\\ud835\\uddf1': 'd',\n  '\\ud835\\uddf2': 'e',\n  '\\ud835\\uddf3': 'f',\n  '\\ud835\\uddf4': 'g',\n  '\\ud835\\uddf5': 'h',\n  '\\ud835\\uddf6': 'i',\n  '\\ud835\\uddf7': 'j',\n  '\\ud835\\uddf8': 'k',\n  '\\ud835\\uddf9': 'l',\n  '\\ud835\\uddfa': 'm',\n  '\\ud835\\uddfb': 'n',\n  '\\ud835\\uddfc': 'o',\n  '\\ud835\\uddfd': 'p',\n  '\\ud835\\uddfe': 'q',\n  '\\ud835\\uddff': 'r',\n  '\\ud835\\ude00': 's',\n  '\\ud835\\ude01': 't',\n  '\\ud835\\ude02': 'u',\n  '\\ud835\\ude03': 'v',\n  '\\ud835\\ude04': 'w',\n  '\\ud835\\ude05': 'x',\n  '\\ud835\\ude06': 'y',\n  '\\ud835\\ude07': 'z',\n  '\\ud835\\ude08': 'A',\n  '\\ud835\\ude09': 'B',\n  '\\ud835\\ude0a': 'C',\n  '\\ud835\\ude0b': 'D',\n  '\\ud835\\ude0c': 'E',\n  '\\ud835\\ude0d': 'F',\n  '\\ud835\\ude0e': 'G',\n  '\\ud835\\ude0f': 'H',\n  '\\ud835\\ude10': 'I',\n  '\\ud835\\ude11': 'J',\n  '\\ud835\\ude12': 'K',\n  '\\ud835\\ude13': 'L',\n  '\\ud835\\ude14': 'M',\n  '\\ud835\\ude15': 'N',\n  '\\ud835\\ude16': 'O',\n  '\\ud835\\ude17': 'P',\n  '\\ud835\\ude18': 'Q',\n  '\\ud835\\ude19': 'R',\n  '\\ud835\\ude1a': 'S',\n  '\\ud835\\ude1b': 'T',\n  '\\ud835\\ude1c': 'U',\n  '\\ud835\\ude1d': 'V',\n  '\\ud835\\ude1e': 'W',\n  '\\ud835\\ude1f': 'X',\n  '\\ud835\\ude20': 'Y',\n  '\\ud835\\ude21': 'Z',\n  '\\ud835\\ude22': 'a',\n  '\\ud835\\ude23': 'b',\n  '\\ud835\\ude24': 'c',\n  '\\ud835\\ude25': 'd',\n  '\\ud835\\ude26': 'e',\n  '\\ud835\\ude27': 'f',\n  '\\ud835\\ude28': 'g',\n  '\\ud835\\ude29': 'h',\n  '\\ud835\\ude2a': 'i',\n  '\\ud835\\ude2b': 'j',\n  '\\ud835\\ude2c': 'k',\n  '\\ud835\\ude2d': 'l',\n  '\\ud835\\ude2e': 'm',\n  '\\ud835\\ude2f': 'n',\n  '\\ud835\\ude30': 'o',\n  '\\ud835\\ude31': 'p',\n  '\\ud835\\ude32': 'q',\n  '\\ud835\\ude33': 'r',\n  '\\ud835\\ude34': 's',\n  '\\ud835\\ude35': 't',\n  '\\ud835\\ude36': 'u',\n  '\\ud835\\ude37': 'v',\n  '\\ud835\\ude38': 'w',\n  '\\ud835\\ude39': 'x',\n  '\\ud835\\ude3a': 'y',\n  '\\ud835\\ude3b': 'z',\n  '\\ud835\\ude3c': 'A',\n  '\\ud835\\ude3d': 'B',\n  '\\ud835\\ude3e': 'C',\n  '\\ud835\\ude3f': 'D',\n  '\\ud835\\ude40': 'E',\n  '\\ud835\\ude41': 'F',\n  '\\ud835\\ude42': 'G',\n  '\\ud835\\ude43': 'H',\n  '\\ud835\\ude44': 'I',\n  '\\ud835\\ude45': 'J',\n  '\\ud835\\ude46': 'K',\n  '\\ud835\\ude47': 'L',\n  '\\ud835\\ude48': 'M',\n  '\\ud835\\ude49': 'N',\n  '\\ud835\\ude4a': 'O',\n  '\\ud835\\ude4b': 'P',\n  '\\ud835\\ude4c': 'Q',\n  '\\ud835\\ude4d': 'R',\n  '\\ud835\\ude4e': 'S',\n  '\\ud835\\ude4f': 'T',\n  '\\ud835\\ude50': 'U',\n  '\\ud835\\ude51': 'V',\n  '\\ud835\\ude52': 'W',\n  '\\ud835\\ude53': 'X',\n  '\\ud835\\ude54': 'Y',\n  '\\ud835\\ude55': 'Z',\n  '\\ud835\\ude56': 'a',\n  '\\ud835\\ude57': 'b',\n  '\\ud835\\ude58': 'c',\n  '\\ud835\\ude59': 'd',\n  '\\ud835\\ude5a': 'e',\n  '\\ud835\\ude5b': 'f',\n  '\\ud835\\ude5c': 'g',\n  '\\ud835\\ude5d': 'h',\n  '\\ud835\\ude5e': 'i',\n  '\\ud835\\ude5f': 'j',\n  '\\ud835\\ude60': 'k',\n  '\\ud835\\ude61': 'l',\n  '\\ud835\\ude62': 'm',\n  '\\ud835\\ude63': 'n',\n  '\\ud835\\ude64': 'o',\n  '\\ud835\\ude65': 'p',\n  '\\ud835\\ude66': 'q',\n  '\\ud835\\ude67': 'r',\n  '\\ud835\\ude68': 's',\n  '\\ud835\\ude69': 't',\n  '\\ud835\\ude6a': 'u',\n  '\\ud835\\ude6b': 'v',\n  '\\ud835\\ude6c': 'w',\n  '\\ud835\\ude6d': 'x',\n  '\\ud835\\ude6e': 'y',\n  '\\ud835\\ude6f': 'z',\n  '\\ud835\\ude70': 'A',\n  '\\ud835\\ude71': 'B',\n  '\\ud835\\ude72': 'C',\n  '\\ud835\\ude73': 'D',\n  '\\ud835\\ude74': 'E',\n  '\\ud835\\ude75': 'F',\n  '\\ud835\\ude76': 'G',\n  '\\ud835\\ude77': 'H',\n  '\\ud835\\ude78': 'I',\n  '\\ud835\\ude79': 'J',\n  '\\ud835\\ude7a': 'K',\n  '\\ud835\\ude7b': 'L',\n  '\\ud835\\ude7c': 'M',\n  '\\ud835\\ude7d': 'N',\n  '\\ud835\\ude7e': 'O',\n  '\\ud835\\ude7f': 'P',\n  '\\ud835\\ude80': 'Q',\n  '\\ud835\\ude81': 'R',\n  '\\ud835\\ude82': 'S',\n  '\\ud835\\ude83': 'T',\n  '\\ud835\\ude84': 'U',\n  '\\ud835\\ude85': 'V',\n  '\\ud835\\ude86': 'W',\n  '\\ud835\\ude87': 'X',\n  '\\ud835\\ude88': 'Y',\n  '\\ud835\\ude89': 'Z',\n  '\\ud835\\ude8a': 'a',\n  '\\ud835\\ude8b': 'b',\n  '\\ud835\\ude8c': 'c',\n  '\\ud835\\ude8d': 'd',\n  '\\ud835\\ude8e': 'e',\n  '\\ud835\\ude8f': 'f',\n  '\\ud835\\ude90': 'g',\n  '\\ud835\\ude91': 'h',\n  '\\ud835\\ude92': 'i',\n  '\\ud835\\ude93': 'j',\n  '\\ud835\\ude94': 'k',\n  '\\ud835\\ude95': 'l',\n  '\\ud835\\ude96': 'm',\n  '\\ud835\\ude97': 'n',\n  '\\ud835\\ude98': 'o',\n  '\\ud835\\ude99': 'p',\n  '\\ud835\\ude9a': 'q',\n  '\\ud835\\ude9b': 'r',\n  '\\ud835\\ude9c': 's',\n  '\\ud835\\ude9d': 't',\n  '\\ud835\\ude9e': 'u',\n  '\\ud835\\ude9f': 'v',\n  '\\ud835\\udea0': 'w',\n  '\\ud835\\udea1': 'x',\n  '\\ud835\\udea2': 'y',\n  '\\ud835\\udea3': 'z',\n  '\\ud835\\udfce': '0',\n  '\\ud835\\udfcf': '1',\n  '\\ud835\\udfd0': '2',\n  '\\ud835\\udfd1': '3',\n  '\\ud835\\udfd2': '4',\n  '\\ud835\\udfd3': '5',\n  '\\ud835\\udfd4': '6',\n  '\\ud835\\udfd5': '7',\n  '\\ud835\\udfd6': '8',\n  '\\ud835\\udfd7': '9',\n  '\\ud835\\udfd8': '0',\n  '\\ud835\\udfd9': '1',\n  '\\ud835\\udfda': '2',\n  '\\ud835\\udfdb': '3',\n  '\\ud835\\udfdc': '4',\n  '\\ud835\\udfdd': '5',\n  '\\ud835\\udfde': '6',\n  '\\ud835\\udfdf': '7',\n  '\\ud835\\udfe0': '8',\n  '\\ud835\\udfe1': '9',\n  '\\ud835\\udfe2': '0',\n  '\\ud835\\udfe3': '1',\n  '\\ud835\\udfe4': '2',\n  '\\ud835\\udfe5': '3',\n  '\\ud835\\udfe6': '4',\n  '\\ud835\\udfe7': '5',\n  '\\ud835\\udfe8': '6',\n  '\\ud835\\udfe9': '7',\n  '\\ud835\\udfea': '8',\n  '\\ud835\\udfeb': '9',\n  '\\ud835\\udfec': '0',\n  '\\ud835\\udfed': '1',\n  '\\ud835\\udfee': '2',\n  '\\ud835\\udfef': '3',\n  '\\ud835\\udff0': '4',\n  '\\ud835\\udff1': '5',\n  '\\ud835\\udff2': '6',\n  '\\ud835\\udff3': '7',\n  '\\ud835\\udff4': '8',\n  '\\ud835\\udff5': '9',\n  '\\ud835\\udff6': '0',\n  '\\ud835\\udff7': '1',\n  '\\ud835\\udff8': '2',\n  '\\ud835\\udff9': '3',\n  '\\ud835\\udffa': '4',\n  '\\ud835\\udffb': '5',\n  '\\ud835\\udffc': '6',\n  '\\ud835\\udffd': '7',\n  '\\ud835\\udffe': '8',\n  '\\ud835\\udfff': '9',\n};\n\n// match emoji keycaps or diacritics\n// <mathematical alphanumeric>|<keycap emojis>|<diacritics>\nconst unicodeExp = new RegExp(/\\uD835[\\uDC00-\\uDFFF]|[\\u0023-\\u0039]\\ufe0f?\\u20e3|[^\\u0000-\\u007E]/g);\n\n/**\n * Return a new string that normalizes unicode characters to ascii.\n * For example:\n * `ézer00️⃣ş` returns `ezer00s`\n * `𝔫𝔞𝔱𝔢 𝔭𝔞𝔯𝔯𝔬𝔱𝔱` returns `nate parrott`\n */\nexport function normalize(str: string): string {\n  return str.replace(unicodeExp, a => mathAlphaMap[a] || keycapsMap[a] || diacriticsMap[a] || a);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/src/uuid.ts",
    "content": "// https://stackoverflow.com/a/2117523\nexport function v4() {\n  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n    const r = (Math.random() * 16) | 0;\n    const v = c === 'x' ? r : (r & 0x3) | 0x8;\n    return v.toString(16);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/DeferredPromise.spec.ts",
    "content": "import { DeferredPromise, DeferredPromiseTimeoutError } from 'foundation/src/DeferredPromise';\n\n// Group 1: Async Logic (Standard)\ndescribe('DeferredPromise', () => {\n  describe('DeferredPromiseTimeoutError', () => {\n    it('checks name, message, and inheritance', () => {\n      const err = new DeferredPromiseTimeoutError('msg');\n      expect(err.name).toBe('DeferredPromiseTimeoutError');\n      expect(err.message).toBe('msg');\n      expect(err).toBeInstanceOf(Error);\n    });\n  });\n\n  describe('Resolution', () => {\n    it('resolves with value', async () => {\n      const def = new DeferredPromise<number>();\n      def.resolve(42);\n      await expectAsync(def.promise).toBeResolvedTo(42);\n    });\n\n    it('resolves with PromiseLike', async () => {\n      const def = new DeferredPromise<string>();\n      def.resolve(Promise.resolve('hi'));\n      await expectAsync(def.promise).toBeResolvedTo('hi');\n    });\n\n    it('handles multiple then() calls', async () => {\n      const def = new DeferredPromise<number>();\n      const res: number[] = [];\n\n      void def.then(v => res.push(v));\n      void def.then(v => res.push(v * 2));\n\n      def.resolve(10);\n      await def.promise;\n      expect(res).toEqual([10, 20]);\n    });\n  });\n\n  describe('Rejection', () => {\n    it('rejects with reason', async () => {\n      const def = new DeferredPromise<number>();\n      def.reject('err');\n      await expectAsync(def.promise).toBeRejectedWith('err');\n    });\n\n    it('rejects without reason', async () => {\n      const def = new DeferredPromise<void>();\n      def.reject();\n      await expectAsync(def.promise).toBeRejected();\n    });\n\n    it('triggers onrejected in then()', async () => {\n      const def = new DeferredPromise<number>();\n      const p = def.then(\n        () => 'ok',\n        (e: unknown) => `caught: ${String(e)}`,\n      );\n      def.reject('oops');\n      await expectAsync(p).toBeResolvedTo('caught: oops');\n    });\n  });\n\n  describe('Chaining', () => {\n    it('chains transformations', async () => {\n      const def = new DeferredPromise<number>();\n      const p = def.then(v => v * 2).then(v => `Res: ${v}`);\n      def.resolve(5);\n      await expectAsync(p).toBeResolvedTo('Res: 10');\n    });\n\n    it('handles exceptions in then()', async () => {\n      const def = new DeferredPromise<number>();\n      const p = def.then(() => {\n        throw new Error('fail');\n      });\n      def.resolve(1);\n      await expectAsync(p).toBeRejectedWith(new Error('fail'));\n    });\n  });\n\n  describe('Types & Properties', () => {\n    it('works with objects', async () => {\n      const def = new DeferredPromise<{ id: number }>();\n      const obj = { id: 1 };\n      def.resolve(obj);\n      await expectAsync(def.promise).toBeResolvedTo(obj);\n    });\n\n    it('works with void', async () => {\n      const def = new DeferredPromise<void>();\n      def.resolve();\n      await expectAsync(def.promise).toBeResolved();\n    });\n\n    it('keeps promise property stable', () => {\n      const def = new DeferredPromise<number>();\n      expect(def.promise).toBe(def.promise);\n    });\n  });\n});\n\n// Group 2: Timing & Idempotency (Mock Clock)\ndescribe('DeferredPromise Timing', () => {\n  beforeEach(() => jasmine.clock().install());\n  afterEach(() => jasmine.clock().uninstall());\n\n  it('timeouts after limit', async () => {\n    const def = new DeferredPromise<number>(50);\n    let err: unknown;\n\n    void def.promise.catch((e: Error) => {\n      err = e;\n    });\n\n    jasmine.clock().tick(51);\n    await Promise.resolve();\n    expect(err).toBeInstanceOf(DeferredPromiseTimeoutError);\n  });\n\n  it('does not timeout if resolved early', async () => {\n    const def = new DeferredPromise<number>(100);\n    let res: number | undefined;\n\n    void def.promise.then(v => {\n      res = v;\n    });\n\n    jasmine.clock().tick(50);\n    def.resolve(42);\n    await Promise.resolve();\n    jasmine.clock().tick(100);\n\n    expect(res).toBe(42);\n  });\n\n  it('does not timeout if rejected early', async () => {\n    const def = new DeferredPromise<number>(100);\n    let err: unknown;\n\n    void def.promise.catch((e: unknown) => {\n      err = e;\n    });\n\n    jasmine.clock().tick(50);\n    def.reject('manual');\n    await Promise.resolve();\n    jasmine.clock().tick(100);\n\n    expect(err).toBe('manual');\n  });\n\n  it('ignores reject after resolve', async () => {\n    const def = new DeferredPromise<number>();\n    let state = 'pending';\n\n    void def.promise.then(\n      () => {\n        state = 'resolved';\n      },\n      () => {\n        state = 'rejected';\n      },\n    );\n\n    def.resolve(1);\n    await Promise.resolve();\n    def.reject('fail');\n    jasmine.clock().tick(1);\n    await Promise.resolve();\n\n    expect(state).toBe('resolved');\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/KeyedFunctionCache.spec.ts",
    "content": "import { KeyedFunctionCache } from 'foundation/src/KeyedFunctionCache';\nimport 'jasmine/src/jasmine';\n\ndescribe('KeyedFunctionCache', () => {\n  it('invokes with provided keys', () => {\n    const fn = jasmine.createSpy();\n    const cache = new KeyedFunctionCache<string, [number]>();\n    const factory = cache.for(fn);\n\n    factory.bindKey('foo')(5);\n    factory.bindKey('bar')(6);\n\n    expect(fn).toHaveBeenCalledWith('foo', 5);\n    expect(fn).toHaveBeenCalledWith('bar', 6);\n  });\n\n  it('returns cached keyed functions', () => {\n    const fn = jasmine.createSpy();\n    const cache = new KeyedFunctionCache<string, [number]>();\n    let factory = cache.for(fn);\n\n    const fooCallback = factory.bindKey('foo');\n    const barCallback = factory.bindKey('bar');\n\n    factory = cache.for(fn);\n\n    expect(factory.bindKey('foo')).toBe(fooCallback);\n    expect(factory.bindKey('bar')).toBe(barCallback);\n  });\n\n  it('returns new keyed functions if provided function changes', () => {\n    const fn = jasmine.createSpy();\n    const cache = new KeyedFunctionCache<string, [number]>();\n    let factory = cache.for(fn);\n\n    const fooCallback = factory.bindKey('foo');\n    const barCallback = factory.bindKey('bar');\n\n    factory = cache.for(() => {});\n\n    expect(factory.bindKey('foo')).not.toBe(fooCallback);\n    expect(factory.bindKey('bar')).not.toBe(barCallback);\n  });\n\n  it('evicts unused keyed functions', () => {\n    const fn = jasmine.createSpy();\n    const cache = new KeyedFunctionCache<string, [number]>();\n    let factory = cache.for(fn);\n\n    const fooCallback = factory.bindKey('foo');\n    const barCallback = factory.bindKey('bar');\n\n    factory = cache.for(fn);\n\n    expect(factory.bindKey('foo')).toBe(fooCallback);\n\n    factory = cache.for(fn);\n\n    expect(factory.bindKey('foo')).toBe(fooCallback);\n    expect(factory.bindKey('bar')).not.toBe(fooCallback);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/deepClone.spec.ts",
    "content": "import deepClone from 'foundation/src/deepClone';\nimport { deepEqual } from 'foundation/src/equality';\n\ndescribe('deepClone', () => {\n  for (const val of primitiveCases) {\n    it(`should handle primitive types: ${val}`, () => {\n      expect(deepClone(val)).toBe(val);\n    });\n  }\n\n  for (const val of nonPrimitiveCases) {\n    it(`should handle non primitive types: ${\n      typeof val === 'object' ? val.constructor.name : typeof val\n    } ${JSON.stringify(val)}`, () => {\n      expect(deepClone(val)).not.toBe(val);\n      expect(deepEqual(deepClone(val), val)).toEqual(true);\n    });\n  }\n\n  it('should handle function', () => {\n    const fn = (): void => {};\n    expect(deepClone(fn)).toBe(fn);\n  });\n\n  it('should handle circular reference', () => {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const obj: any = {};\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n    obj.a = obj;\n    expect(deepClone(obj)).not.toBe(obj);\n    expect(deepClone(obj)).toEqual(obj);\n  });\n});\n\nconst primitiveCases = [0, 1, '', 'a', null, undefined, true, false] as const;\n\nconst nonPrimitiveCases = [\n  new Date(),\n  new RegExp('a'),\n  new Map(),\n  new Set(),\n  new ArrayBuffer(1),\n  Long.fromValue(1),\n  {},\n  { a: new Date(), b: [new Set([1, 2, 3]), 3, 'test', Long.fromValue(123)] },\n];\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/functional/cacheResolved.spec.ts",
    "content": "import { cacheResolved } from 'foundation/src/functional/cacheResolved';\nimport 'jasmine/src/jasmine';\n\ndescribe('cacheResovled', () => {\n  it('returns values', async () => {\n    const squareString = cacheResolved<[number], string>(x => x.toString())(async x => (x * x).toString());\n\n    expect(await squareString(5)).toBe('25');\n    expect(await squareString(7)).toBe('49');\n  });\n\n  it('caches results', async () => {\n    const squareString = jasmine.createSpy('squareString', async x => (x * x).toString());\n    const cached = cacheResolved<[number], string>(x => x.toString())(squareString);\n    squareString.and.callThrough();\n\n    expect(await cached(5)).toBe('25');\n    expect(await cached(7)).toBe('49');\n    expect(await cached(5)).toBe('25');\n    expect(await cached(7)).toBe('49');\n    expect(squareString).toHaveBeenCalledTimes(2);\n  });\n\n  it('does not cache rejects', async () => {\n    const throws = jasmine.createSpy();\n    const cached = cacheResolved<[number], string>(x => x.toString())(throws);\n    throws.and.rejectWith('some error');\n\n    try {\n      await cached(1);\n      fail('unexpected success');\n    } catch {\n      // no-op\n    }\n    try {\n      await cached(1);\n      fail('unexpected success');\n    } catch {\n      // no-op\n    }\n    expect(throws).toHaveBeenCalledTimes(2);\n  });\n\n  it('shares unresolved promise', async () => {\n    const resolvers: Record<number, (result: string) => void> = {};\n    const longOperation = jasmine.createSpy(\n      'longOperation',\n      (arg: number) =>\n        new Promise<string>(resolve => {\n          resolvers[arg] = resolve;\n        }),\n    );\n    const cached = cacheResolved<[number], string>(x => x.toString())(longOperation);\n    longOperation.and.callThrough();\n\n    // eslint-disable-next-line @snap/valdi/assign-timer-id\n    setTimeout(() => Object.entries(resolvers).forEach(([value, resolver]) => resolver(`done ${value}`)), 10);\n\n    expect(await Promise.all([cached(1), cached(2), cached(1)])).toEqual(['done 1', 'done 2', 'done 1']);\n    expect(longOperation).toHaveBeenCalledTimes(2);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/functional/mapArguments.spec.ts",
    "content": "import { mapArguments } from 'foundation/src/functional/mapArguments';\nimport 'jasmine/src/jasmine';\n\ndescribe('mapArguments', () => {\n  it('maps function arguments', () => {\n    const concat = (x: string, y: string): string => x + y;\n    const concatNumbers = mapArguments((i: number, j: number): [string, string] => [i.toString(), j.toString()])(\n      concat,\n    );\n    expect(concatNumbers(123, 456)).toEqual('123456');\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/functional/mapResult.spec.ts",
    "content": "import { mapResult } from 'foundation/src/functional/mapResult';\nimport 'jasmine/src/jasmine';\n\ndescribe('mapResult', () => {\n  it('maps function return values', () => {\n    const multiply = (x: number, y: number): number => x * y;\n    const multiplyString = mapResult((x: number) => x.toString())(multiply);\n    expect(multiplyString(4, 7)).toBe('28');\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/functional/transformProperties.spec.ts",
    "content": "import { transformProperties } from 'foundation/src/functional/transformProperties';\nimport 'jasmine/src/jasmine';\n\ninterface Foo {\n  count: number;\n  message: string;\n}\n\ndescribe('transformProperties', () => {\n  it('applies transformation to specified properties', () => {\n    const squareCount = transformProperties<Foo>({\n      count: (x): number => x * x,\n    });\n    expect(squareCount({ count: 2, message: 'foo' })).toEqual({ count: 4, message: 'foo' });\n    expect(squareCount({ count: 4, message: 'foo' })).toEqual({ count: 16, message: 'foo' });\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/isDefinedTest.ts",
    "content": "import 'jasmine/src/jasmine';\nimport { isDefined } from 'foundation/src/isDefined';\n\ndescribe('optional', () => {\n  it('empty val', () => {\n    let val: boolean | undefined;\n    expect(isDefined(val)).toBe(false);\n  });\n\n  it('true val', () => {\n    const val: boolean | undefined = true;\n    expect(isDefined(val)).toBe(true);\n  });\n\n  it('false val', () => {\n    const val: boolean | undefined = false;\n    expect(isDefined(val)).toBe(true);\n  });\n\n  it('filter', () => {\n    const vals = ['abc', undefined, 1, 2, null, 3];\n    expect(vals.filter(isDefined)).toEqual(['abc', 1, 2, 3]);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/multiInsertTest.ts",
    "content": "import { multiInsert } from 'foundation/src/array';\nimport 'jasmine/src/jasmine';\n\ndescribe('multiInsert', () => {\n  const arr = ['a', 'b', 'c', 'd'];\n  const values = { 0: '1', 1: '2', 2: '3' };\n  it('inserts multiple values', () => {\n    expect(multiInsert(arr, values)).toEqual(['1', 'a', '2', 'b', '3', 'c', 'd']);\n  });\n\n  it('empty values object', () => {\n    expect(multiInsert(arr, {})).toEqual(arr);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/required.spec.ts",
    "content": "import 'jasmine/src/jasmine';\nimport { required } from 'foundation/src/required';\n\ndescribe('required', () => {\n  it('returns defined values', () => {\n    expect(required({})).toEqual({});\n    expect(required({ foo: 'bar' })).toEqual({ foo: 'bar' });\n    expect(required(500)).toBe(500);\n    expect(required(true)).toBe(true);\n    expect(required('blah')).toBe('blah');\n  });\n\n  it('returns falsy defined values', () => {\n    expect(required(0)).toBe(0);\n    expect(required('')).toBe('');\n    expect(required(null)).toBe(null);\n    expect(required(false)).toBe(false);\n  });\n\n  it('throws for undefined', () => {\n    try {\n      expect(required(undefined));\n      fail('unexpected success');\n    } catch (e) {\n      expect(e).toEqual(new TypeError());\n    }\n  });\n\n  it('throws with message', () => {\n    try {\n      expect(required(undefined, 'uh oh!'));\n      fail('unexpected success');\n    } catch (e) {\n      expect(e).toEqual(new TypeError('uh oh!'));\n    }\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/runWith.spec.ts",
    "content": "import { runWith } from 'foundation/src/runWith';\nimport 'jasmine/src/jasmine';\n\ndescribe('runWith', () => {\n  it('runs with input', () => {\n    const fn = jasmine.createSpy();\n    runWith(123, fn);\n    expect(fn).toHaveBeenCalledWith(123);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/stringTest.ts",
    "content": "import 'jasmine/src/jasmine';\nimport { slugifyUrlPath } from '../src/string';\n\ndescribe('slugifyUrlPath', () => {\n  it('returns a slugified URL path', () => {\n    [\n      ['search', 'search'],\n      ['/search', 'search'],\n      ['/some/long/path', 'somelongpath'],\n    ].forEach(([input, expected]) => {\n      expect(slugifyUrlPath(input)).toEqual(expected);\n    });\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/ExplorerVirtualNode.ts",
    "content": "import { IComponent, ComponentConstructor } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { IRenderedVirtualNode } from 'valdi_core/src/IRenderedVirtualNode';\nimport { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\nimport { virtualNodeTreeDump } from './virtualNodeTreeDump';\nimport 'jasmine/src/jasmine';\n\nexport class ExplorerVirtualNode {\n  constructor(private virtualNode: IRenderedVirtualNode) {}\n\n  expectToBeComponent<T extends IComponent>(clazz: ComponentConstructor<T>, viewModel?: any) {\n    const component = this.virtualNode.component;\n    if (!component) {\n      throw new Error('Is not a component');\n    }\n    if (!(component instanceof clazz)) {\n      throw new Error(`Is not a component of type: ${clazz.name}`);\n    }\n    if (viewModel) {\n      for (const key of Object.keys(viewModel)) {\n        const value = viewModel[key];\n        const found = component.viewModel[key];\n        if (found !== value) {\n          throw new Error(`Wrong component attribute: ${clazz.name}.${key} -> ${found} (expected: ${value})`);\n        }\n      }\n    }\n    return this;\n  }\n\n  expectToBeElement(viewClass: IRenderedElementViewClass, attributes?: any) {\n    const element = this.virtualNode.element;\n    if (!element) {\n      throw new Error('Is not an element');\n    }\n    if (element.viewClass != viewClass) {\n      throw new Error(`Is not an element of type: ${viewClass} (found: ${element.viewClass})`);\n    }\n    if (attributes) {\n      for (const key of Object.keys(attributes)) {\n        const value = attributes[key];\n        const found = element.getAttribute(key);\n        if (found !== value) {\n          throw new Error(`Wrong element attribute: ${viewClass}.${key} -> ${found} (expected: ${value})`);\n        }\n      }\n    }\n    return this;\n  }\n\n  expectNumberOfChildren(count: number) {\n    const found = this.virtualNode.children.length;\n    if (found != count) {\n      throw new Error(`Invalid number of children: ${found} (expected: ${count})`);\n    }\n    return this;\n  }\n\n  expectDirectChildComponent<T extends IComponent>(\n    clazz: ComponentConstructor<T>,\n    viewModel?: any,\n  ): ExplorerVirtualNode {\n    for (const child of this.virtualNode.children) {\n      if (child.component instanceof clazz) {\n        const explorer = new ExplorerVirtualNode(child);\n        explorer.expectToBeComponent(clazz, viewModel);\n        return explorer;\n      }\n    }\n    throw new Error(`Could not find the children component: ${clazz.name}`);\n  }\n\n  expectDirectChildElement(viewClass: IRenderedElementViewClass, attributes?: any): ExplorerVirtualNode {\n    for (const child of this.virtualNode.children) {\n      if (child.element?.viewClass === viewClass) {\n        const explorer = new ExplorerVirtualNode(child);\n        explorer.expectToBeElement(viewClass, attributes);\n        return explorer;\n      }\n    }\n    throw new Error(`Could not find the children element: ${viewClass}`);\n  }\n\n  expectExactDirectChildrenElements(params: [IRenderedElementViewClass, any][]): ExplorerVirtualNode[] {\n    this.expectNumberOfChildren(params.length);\n    const results = [];\n    for (let i = 0; i < params.length; i++) {\n      const child = this.virtualNode.children[i];\n      const param = params[i];\n      const explorer = new ExplorerVirtualNode(child);\n      explorer.expectToBeElement(param[0], param[1]);\n      results.push(explorer);\n    }\n    return results;\n  }\n\n  applyOnChild(index: number, cb: (explorer: ExplorerVirtualNode) => void) {\n    const count = this.virtualNode.children.length;\n    if (index >= count) {\n      throw new Error(`Child index is larger than the number of children: ${index} (size: ${count})`);\n    }\n    const child = this.virtualNode.children[index];\n    cb(new ExplorerVirtualNode(child));\n    return this;\n  }\n\n  applyOnElement(cb: (it: IRenderedElement) => void) {\n    const element = this.virtualNode.element;\n    if (!element) {\n      throw new Error('Is not an element');\n    }\n    cb(element);\n    return this;\n  }\n\n  applyOnComponent<T extends IComponent>(clazz: ComponentConstructor<T>, cb: (it: T) => void) {\n    const component = this.virtualNode.component;\n    if (!component) {\n      throw new Error('Is not a component');\n    }\n    if (!(component instanceof clazz)) {\n      throw new Error(`Is not a component of type: ${clazz.name}`);\n    }\n    cb(component);\n    return this;\n  }\n\n  dumpTree() {\n    virtualNodeTreeDump(this.virtualNode);\n    return this;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/ReproducibleGenerator.ts",
    "content": "// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport * as faker from './lib/faker';\n\nexport class ReproducibleGenerator {\n  private faker: any;\n\n  /**\n   * Need to pass a seed to ensure the reproducibility of the generated values\n   */\n  constructor(seed: number) {\n    this.faker = new faker.constructor({ locales: faker.locales });\n    this.faker.seed(seed);\n  }\n  private setLocale(locale?: string) {\n    if (!locale) {\n      this.faker.locale = this.faker.random.locale();\n    } else {\n      this.faker.locale = locale;\n    }\n  }\n\n  nextUniqueId(): string {\n    return this.faker.random.uuid();\n  }\n\n  nextInternetName(locale?: string): string {\n    this.setLocale(locale);\n    return this.faker.internet.userName();\n  }\n  nextFreeformName(locale?: string): string {\n    this.setLocale(locale);\n    return this.faker.name.findName();\n  }\n  nextFreeformWords(locale?: string): string {\n    this.setLocale(locale);\n    return this.faker.name.findName(); // Unfortunately, only names have proper freeform locale support for now\n  }\n  nextPhoneNumber(locale?: string): string {\n    this.setLocale(locale);\n    return this.faker.phone.phoneNumber();\n  }\n  nextAlphaNumericString(size: number): string {\n    return this.faker.random.alphaNumeric(size);\n  }\n\n  /**\n   * returns true/false\n   */\n  nextBoolean() {\n    return this.faker.random.boolean();\n  }\n  /**\n   * returns a number in range [0, 1] included\n   */\n  nextFloat() {\n    return this.faker.random.number({\n      min: 0,\n      max: 1,\n      precision: 0.001,\n    });\n  }\n  /**\n   * returns a number in range [0, 1.000.000.000] included\n   */\n  nextInt() {\n    return this.faker.random.number({\n      min: 0,\n      max: 1000000000,\n      precision: 1,\n    });\n  }\n  /**\n   * returns a number in range [start, end] included\n   */\n  nextRange(start: number, end: number) {\n    return this.faker.random.number(end - start) + start;\n  }\n  /**\n   * returns a timestamp in ms between 2010 and 2020\n   */\n  nextPastTimestampMs(): number {\n    // We need to have a stable date range, otherwise generated value will change over time\n    return this.faker.date.between('2010-01-01', '2020-01-01').getTime();\n  }\n  /**\n   * returns a dummy friendmoji\n   */\n  nextFriendmoji(): string {\n    const options = ['🔥', '🥰', '💚', '❤️', '🎥'];\n    const size = this.nextRange(0, 7);\n    let friendmoji = '';\n    for (let i = 0; i < size; i++) {\n      friendmoji += this.faker.random.arrayElement(options);\n    }\n    return friendmoji;\n  }\n\n  nextLocale(): string {\n    return this.faker.random.locale();\n  }\n  availableLocales() {\n    return Object.keys(this.faker.locales);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/componentGetChildren.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\n\nexport function componentGetChildren(component: IComponent): IComponent[] {\n  return component.renderer.getComponentChildren(component);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/componentGetElements.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\n\nexport function componentGetElements(component: IComponent | IComponent[]): IRenderedElement[] {\n  if (component instanceof Array) {\n    let results: IRenderedElement[] = [];\n    for (const item of component) {\n      results = results.concat(item.renderer.getComponentRootElements(item, false));\n    }\n    return results;\n  } else {\n    return component.renderer.getComponentRootElements(component, false);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/componentGetKey.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\n\nexport function componentGetKey(component: IComponent): string {\n  return component.renderer.getComponentKey(component);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/componentGetVirtualNode.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedVirtualNode } from 'valdi_core/src/IRenderedVirtualNode';\n\nexport function componentGetVirtualNode(component: IComponent): IRenderedVirtualNode {\n  return component.renderer.getComponentVirtualNode(component);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/componentGlobFind.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { componentGetChildren } from './componentGetChildren';\nimport { componentGetKey } from './componentGetKey';\nimport { globToRegex } from './globToRegex';\n\n/**\n * Find components by globbing their relative path\n * Allow search by glob wildcard (like in file system)\n */\nexport function componentGlobFind(component: IComponent | IComponent[], pattern: string): IComponent[] {\n  const possibilities: { path: string; component: IComponent }[] = [];\n\n  const recursor = (current: IComponent, path: string) => {\n    const currentName = componentGetKey(current);\n    const newPath = path + currentName;\n    possibilities.push({ path: newPath, component: current });\n    for (const child of componentGetChildren(current)) {\n      recursor(child, newPath + '/');\n    }\n  };\n\n  if (component instanceof Array) {\n    for (const item of component) {\n      recursor(item, '');\n    }\n  } else {\n    recursor(component, '');\n  }\n\n  const regex = globToRegex(pattern);\n  const results: IComponent[] = [];\n  for (const possibility of possibilities) {\n    if (regex.test(possibility.path)) {\n      results.push(possibility.component);\n    }\n  }\n  return results;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/componentKeyFind.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { componentGetChildren } from './componentGetChildren';\nimport { componentGetKey } from './componentGetKey';\n\n/**\n * Find components with an arbitrary key recursively\n */\nexport function componentKeyFind(component: IComponent | IComponent[], key: string): IComponent[] {\n  const results: IComponent[] = [];\n\n  const recursor = (current: IComponent) => {\n    if (componentGetKey(current) === key) {\n      results.push(current);\n    }\n    for (const child of componentGetChildren(current)) {\n      recursor(child);\n    }\n  };\n\n  if (component instanceof Array) {\n    for (const item of component) {\n      recursor(item);\n    }\n  } else {\n    recursor(component);\n  }\n\n  return results;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/componentTreeDump.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { componentGetChildren } from './componentGetChildren';\nimport { componentGetKey } from './componentGetKey';\nimport { consoleDim, consoleFgRed, consoleFgYellow, consoleReset } from './consoleColor';\n\ninterface Options {\n  maxDepth?: number;\n  noColor?: boolean;\n  maxSpace?: number;\n  maxSpacePerValue?: number;\n  blockKeys?: string[];\n}\n\n/**\n * Print recursively the component tree of the component\n */\nexport function componentTreeDump(component: IComponent | IComponent[], options: Options = {}) {\n  const { maxDepth = 100, noColor = false, maxSpace = 50, maxSpacePerValue = 50, blockKeys = [] } = options;\n  const colorValue = (value: string, color: string) => {\n    if (noColor) {\n      return value;\n    }\n    return color + value + consoleReset;\n  };\n\n  const limit = maxDepth;\n  const recursor = (current: IComponent, depth: number, looping: Map<number, boolean>) => {\n    if (depth > limit) {\n      return;\n    }\n    const key = componentGetKey(current);\n    let prefix = '';\n    for (let i = 0; i < depth; i++) {\n      if (i + 1 == depth) {\n        prefix += ' +';\n      } else {\n        if (looping.get(i)) {\n          prefix += ' |';\n        } else {\n          prefix += '  ';\n        }\n      }\n    }\n\n    const simplifiedViewModel: string[] = [];\n    const keys = Object.keys(current.viewModel);\n    keys.sort((a, b) => {\n      return a.length - b.length;\n    });\n    let usedSpace = 0;\n    for (const key of keys) {\n      if (blockKeys.includes(key)) {\n        continue;\n      }\n      const value = current.viewModel[key];\n      const valueString = stringifyValue(value);\n      if (valueString !== undefined) {\n        const trimmedValueString =\n          valueString.length > maxSpacePerValue ? valueString.slice(0, maxSpacePerValue) + '...\"' : valueString;\n        const itemString = key + ': ' + valueString;\n        if (itemString.length + usedSpace > maxSpace) {\n          simplifiedViewModel.push('...');\n          break;\n        } else {\n          usedSpace += itemString.length;\n          simplifiedViewModel.push(itemString);\n        }\n      }\n    }\n\n    console.log(\n      colorValue(prefix, consoleFgYellow),\n      colorValue(key, consoleFgRed),\n      colorValue('{' + simplifiedViewModel.join(', ') + '}', consoleDim),\n    );\n\n    const children = componentGetChildren(current);\n    for (let i = 0; i < children.length; i++) {\n      const newLooping = new Map(looping);\n      if (i + 1 < children.length) {\n        newLooping.set(depth, true);\n      }\n      recursor(children[i], depth + 1, newLooping);\n    }\n  };\n\n  if (component instanceof Array) {\n    for (const item of component) {\n      recursor(item, 0, new Map());\n    }\n  } else {\n    recursor(component, 0, new Map());\n  }\n}\n\nconst stringifyValue = (value: unknown): string | undefined => {\n  // Primitive types\n  if (value === null || typeof value !== 'object') {\n    return JSON.stringify(value);\n  }\n  if (value instanceof Date) {\n    return value.toISOString();\n  }\n  if (value instanceof Array) {\n    return `[${value.map(stringifyValue).join(', ')}]`;\n  }\n  // Plain object\n  if (value.constructor === Object) {\n    const cache: unknown[] = [];\n    return JSON.stringify(value, (key, value) =>\n      typeof value === 'object' && value !== null\n        ? cache.includes(value)\n          ? undefined // Duplicate reference found, discard key\n          : cache.push(value) && value // Store value in our collection\n        : value,\n    );\n  }\n  return undefined;\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/componentTypeFind.ts",
    "content": "import { ComponentConstructor, IComponent } from 'valdi_core/src/IComponent';\nimport { getChildComponentsOfType } from 'valdi_core/src/utils/ComponentUtils';\n\nexport function componentTypeFind<T extends IComponent>(\n  component: IComponent | IComponent[],\n  clazz: ComponentConstructor<T>,\n): T[] {\n  let results: T[] = [];\n  if (component instanceof Array) {\n    for (const item of component) {\n      results = results.concat(getChildComponentsOfType(item, clazz, true));\n    }\n  } else {\n    results = results.concat(getChildComponentsOfType(component, clazz, true));\n  }\n  return results;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/consoleColor.ts",
    "content": "export const consoleReset = '\\x1b[0m';\nexport const consoleBright = '\\x1b[1m';\nexport const consoleDim = '\\x1b[2m';\nexport const consoleUnderscore = '\\x1b[4m';\nexport const consoleBlink = '\\x1b[5m';\nexport const consoleReverse = '\\x1b[7m';\nexport const consoleHidden = '\\x1b[8m';\n\nexport const consoleFgBlack = '\\x1b[30m';\nexport const consoleFgRed = '\\x1b[31m';\nexport const consoleFgGreen = '\\x1b[32m';\nexport const consoleFgYellow = '\\x1b[33m';\nexport const consoleFgBlue = '\\x1b[34m';\nexport const consoleFgMagenta = '\\x1b[35m';\nexport const consoleFgCyan = '\\x1b[36m';\nexport const consoleFgWhite = '\\x1b[37m';\n\nexport const consoleBgBlack = '\\x1b[40m';\nexport const consoleBgRed = '\\x1b[41m';\nexport const consoleBgGreen = '\\x1b[42m';\nexport const consoleBgYellow = '\\x1b[43m';\nexport const consoleBgBlue = '\\x1b[44m';\nexport const consoleBgMagenta = '\\x1b[45m';\nexport const consoleBgCyan = '\\x1b[46m';\nexport const consoleBgWhite = '\\x1b[47m';\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/elementGlobFind.ts",
    "content": "import { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { globToRegex } from './globToRegex';\n\n/**\n * Find elements by globbing their relative path\n * Allow search by glob wildcard (like in file system)\n */\nexport function elementGlobFind<T = any>(element: IRenderedElement | IRenderedElement[], pattern: string): IRenderedElement<T>[] {\n  const possibilities: { path: string; element: IRenderedElement }[] = [];\n\n  const recursor = (current: IRenderedElement, path: string) => {\n    const currentName = current.viewClass + ':' + current.key;\n    const newPath = path + currentName;\n    possibilities.push({ path: newPath, element: current });\n    for (const child of current.children) {\n      recursor(child, newPath + '/');\n    }\n  };\n\n  if (element instanceof Array) {\n    for (const item of element) {\n      recursor(item, '');\n    }\n  } else {\n    recursor(element, '');\n  }\n\n  const regex = globToRegex(pattern);\n  const results: IRenderedElement<T>[] = [];\n  for (const possibility of possibilities) {\n    if (regex.test(possibility.path)) {\n      results.push(possibility.element);\n    }\n  }\n  return results;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/elementKeyFind.ts",
    "content": "import { IRenderedElement } from 'valdi_core/src/IRenderedElement';\n\n/**\n * Find elements with a specific key recursively\n */\nexport function elementKeyFind<T = any>(element: IRenderedElement | IRenderedElement[], key: string): IRenderedElement<T>[] {\n  const results: IRenderedElement<T>[] = [];\n\n  const recursor = (current: IRenderedElement) => {\n    if (current.key === key) {\n      results.push(current);\n    }\n    for (const child of current.children) {\n      recursor(child);\n    }\n  };\n\n  if (element instanceof Array) {\n    for (const item of element) {\n      recursor(item);\n    }\n  } else {\n    recursor(element);\n  }\n\n  return results;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/elementTreeDump.ts",
    "content": "import { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { consoleDim, consoleFgRed, consoleFgYellow, consoleReset } from './consoleColor';\n\n/**\n * Print recursively the element tree of the element\n */\nexport function elementTreeDump(element: IRenderedElement | IRenderedElement[], maxDepth?: number, noColor?: boolean) {\n  const colorValue = (value: string, color: string) => {\n    if (noColor) {\n      return value;\n    }\n    return color + value + consoleReset;\n  };\n\n  const limit = maxDepth ?? 100;\n  const recursor = (current: IRenderedElement, depth: number, looping: Map<number, boolean>) => {\n    if (depth > limit) {\n      return;\n    }\n    const key = current.viewClass + ':' + current.key;\n    let prefix = '';\n    for (let i = 0; i < depth; i++) {\n      if (i + 1 == depth) {\n        prefix += ' +';\n      } else {\n        if (looping.get(i)) {\n          prefix += ' |';\n        } else {\n          prefix += '  ';\n        }\n      }\n    }\n\n    const simplifiedViewModel: string[] = [];\n    const keys = current.getAttributeNames();\n    keys.sort((a, b) => {\n      return a.length - b.length;\n    });\n    const maxSpace = 50;\n    let usedSpace = 0;\n    for (const key of keys) {\n      const value = current.getAttribute(key);\n      const type = typeof value;\n      if (type == 'number' || type == 'string' || type == 'boolean') {\n        const valueString = value.toString();\n        const itemString = key + ': ' + valueString;\n        if (itemString.length + usedSpace > maxSpace) {\n          simplifiedViewModel.push('...');\n          break;\n        } else {\n          usedSpace += itemString.length;\n          simplifiedViewModel.push(itemString);\n        }\n      }\n    }\n\n    console.log(\n      colorValue(prefix, consoleFgYellow),\n      colorValue(key, consoleFgRed),\n      colorValue('{' + simplifiedViewModel.join(', ') + '}', consoleDim),\n    );\n\n    const children = current.children;\n    for (let i = 0; i < children.length; i++) {\n      const newLooping = new Map(looping);\n      if (i + 1 < children.length) {\n        newLooping.set(depth, true);\n      }\n      recursor(children[i], depth + 1, newLooping);\n    }\n  };\n\n  if (element instanceof Array) {\n    for (const item of element) {\n      recursor(item, 0, new Map());\n    }\n  } else {\n    recursor(element, 0, new Map());\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/elementTypeFind.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\nimport { componentGetElements } from './componentGetElements';\nimport { isRenderedElement } from './isRenderedElement';\nimport { ElementForViewClass } from 'valdi_test/test/ElementForViewClass';\n\ntype Node = IComponent | IRenderedElement;\n\n/**\n * Find elements with an type recursively\n */\nexport function elementTypeFind<T extends IRenderedElementViewClass>(element: Node | Node[], viewClass: T): IRenderedElement<ElementForViewClass<T>>[] {\n  const results: IRenderedElement<ElementForViewClass<T>>[] = [];\n\n  const recursor = (current: Node) => {\n    const isElement = isRenderedElement(current);\n\n    if (isElement && current.viewClass === viewClass) {\n      results.push(current);\n    }\n    const children = isElement ? current.children : componentGetElements(current);\n    children.forEach(child => recursor(child));\n  };\n\n  if (element instanceof Array) {\n    for (const item of element) {\n      recursor(item);\n    }\n  } else {\n    recursor(element);\n  }\n\n  return results;\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/findNodeWithKey.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { componentGetChildren } from './componentGetChildren';\nimport { componentGetElements } from './componentGetElements';\nimport { componentGetKey } from './componentGetKey';\nimport { isRenderedElement } from './isRenderedElement';\n\ntype Node = IComponent | IRenderedElement;\n\n/**\n * Find all components or elements with a specific key recursively.\n * This supports searching in the tree of mixed components and elements.\n */\nexport const findNodeWithKey = (root: Node | Node[] | (() => Node | Node[]), key: string): Node[] => {\n  const results: Node[] = [];\n\n  const recursor = (current: Node) => {\n    const isElement = isRenderedElement(current);\n    const currentkey = isElement ? current.key : componentGetKey(current);\n    if (currentkey === key) {\n      results.push(current);\n    }\n    if (!isElement) {\n      const elements = componentGetElements(current);\n      elements.forEach(recursor);\n    }\n    const children = isElement ? current.children : componentGetChildren(current);\n    for (const child of children) {\n      recursor(child);\n    }\n  };\n\n  const resolvedRoot = typeof root === 'function' ? root() : root;\n  if (resolvedRoot instanceof Array) {\n    for (const item of resolvedRoot) {\n      recursor(item);\n    }\n  } else {\n    recursor(resolvedRoot);\n  }\n\n  return results;\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/getAttributeFromNode.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { isRenderedElement } from './isRenderedElement';\n\nexport const getAttributeFromNode = <T = any>(node: IComponent | IRenderedElement, key: string): T | undefined => {\n  if (isRenderedElement(node)) {\n    return node.getAttribute(key);\n  }\n  return node.viewModel[key];\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/getIsUnderNode.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { componentGetChildren } from './componentGetChildren';\nimport { componentGetElements } from './componentGetElements';\nimport { isRenderedElement } from './isRenderedElement';\n\ntype Node = IComponent | IRenderedElement;\n\n/**\n * Find if the instance of given component exist under another component\n */\nexport const getIsUnderNode = (root: Node, target: Node): boolean => {\n  const isElement = isRenderedElement(root);\n  if (root === target) {\n    return true;\n  }\n  // Check elements under the root\n  if (!isElement && isRenderedElement(target)) {\n    const elements = componentGetElements(root);\n    for (const child of elements) {\n      if (getIsUnderNode(child, target)) {\n        return true;\n      }\n    }\n  }\n  // Check children under the root\n  const children = isElement ? root.children : componentGetChildren(root);\n  for (const child of children) {\n    if (getIsUnderNode(child, target)) {\n      return true;\n    }\n  }\n  return false;\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/globToRegex.ts",
    "content": "const escaped = '/$^+.()=!|';\n\nexport function globToRegex(glob: string) {\n  let regex = '';\n  for (let i = 0; i < glob.length; i++) {\n    const c = glob[i];\n    if (escaped.includes(c)) {\n      regex += '\\\\' + c;\n    } else if (c === '*') {\n      const c1 = glob[i + 1];\n      if (c1 === '*') {\n        regex += '(?:.*)';\n        i++;\n      } else {\n        regex += '([^/]*)';\n      }\n    } else {\n      regex += c;\n    }\n  }\n  regex = '^' + regex + '$';\n  return new RegExp(regex);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/isRenderedElement.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\n\nexport const isRenderedElement = (node: IComponent | IRenderedElement): node is IRenderedElement => {\n  return (node as IRenderedElement).viewClass !== undefined;\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/lib/faker.js",
    "content": "!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.faker=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n// since we are requiring the top level of faker, load all locales by default\nvar Faker = require('./lib');\nvar faker = new Faker({ locales: require('./lib/locales') });\nmodule['exports'] = faker;\n},{\"./lib\":13,\"./lib/locales\":15}],2:[function(require,module,exports){\n/**\n *\n * @namespace faker.address\n */\nfunction Address (faker) {\n  var f = faker.fake,\n      Helpers = faker.helpers;\n\n  /**\n   * Generates random zipcode from format. If format is not specified, the\n   * locale's zip format is used.\n   *\n   * @method faker.address.zipCode\n   * @param {String} format\n   */\n  this.zipCode = function(format) {\n    // if zip format is not specified, use the zip format defined for the locale\n    if (typeof format === 'undefined') {\n      var localeFormat = faker.definitions.address.postcode;\n      if (typeof localeFormat === 'string') {\n        format = localeFormat;\n      } else {\n        format = faker.random.arrayElement(localeFormat);\n      }\n    }\n    return Helpers.replaceSymbols(format);\n  }\n\n  /**\n   * Generates a random localized city name. The format string can contain any\n   * method provided by faker wrapped in `{{}}`, e.g. `{{name.firstName}}` in\n   * order to build the city name.\n   *\n   * If no format string is provided one of the following is randomly used:\n   * \n   * * `{{address.cityPrefix}} {{name.firstName}}{{address.citySuffix}}`\n   * * `{{address.cityPrefix}} {{name.firstName}}`\n   * * `{{name.firstName}}{{address.citySuffix}}`\n   * * `{{name.lastName}}{{address.citySuffix}}`\n   *\n   * @method faker.address.city\n   * @param {String} format\n   */\n  this.city = function (format) {\n    var formats = [\n      '{{address.cityPrefix}} {{name.firstName}}{{address.citySuffix}}',\n      '{{address.cityPrefix}} {{name.firstName}}',\n      '{{name.firstName}}{{address.citySuffix}}',\n      '{{name.lastName}}{{address.citySuffix}}'\n    ];\n\n    if (typeof format !== \"number\") {\n      format = faker.random.number(formats.length - 1);\n    }\n\n    return f(formats[format]);\n\n  }\n\n  /**\n   * Return a random localized city prefix\n   * @method faker.address.cityPrefix\n   */\n  this.cityPrefix = function () {\n    return faker.random.arrayElement(faker.definitions.address.city_prefix);\n  }\n\n  /**\n   * Return a random localized city suffix\n   *\n   * @method faker.address.citySuffix\n   */\n  this.citySuffix = function () {\n    return faker.random.arrayElement(faker.definitions.address.city_suffix);\n  }\n\n  /**\n   * Returns a random localized street name\n   *\n   * @method faker.address.streetName\n   */\n  this.streetName = function () {\n      var result;\n      var suffix = faker.address.streetSuffix();\n      if (suffix !== \"\") {\n          suffix = \" \" + suffix\n      }\n\n      switch (faker.random.number(1)) {\n      case 0:\n          result = faker.name.lastName() + suffix;\n          break;\n      case 1:\n          result = faker.name.firstName() + suffix;\n          break;\n      }\n      return result;\n  }\n\n  //\n  // TODO: change all these methods that accept a boolean to instead accept an options hash.\n  //\n  /**\n   * Returns a random localized street address\n   *\n   * @method faker.address.streetAddress\n   * @param {Boolean} useFullAddress\n   */\n  this.streetAddress = function (useFullAddress) {\n      if (useFullAddress === undefined) { useFullAddress = false; }\n      var address = \"\";\n      switch (faker.random.number(2)) {\n      case 0:\n          address = Helpers.replaceSymbolWithNumber(\"#####\") + \" \" + faker.address.streetName();\n          break;\n      case 1:\n          address = Helpers.replaceSymbolWithNumber(\"####\") +  \" \" + faker.address.streetName();\n          break;\n      case 2:\n          address = Helpers.replaceSymbolWithNumber(\"###\") + \" \" + faker.address.streetName();\n          break;\n      }\n      return useFullAddress ? (address + \" \" + faker.address.secondaryAddress()) : address;\n  }\n\n  /**\n   * streetSuffix\n   *\n   * @method faker.address.streetSuffix\n   */\n  this.streetSuffix = function () {\n      return faker.random.arrayElement(faker.definitions.address.street_suffix);\n  }\n  \n  /**\n   * streetPrefix\n   *\n   * @method faker.address.streetPrefix\n   */\n  this.streetPrefix = function () {\n      return faker.random.arrayElement(faker.definitions.address.street_prefix);\n  }\n\n  /**\n   * secondaryAddress\n   *\n   * @method faker.address.secondaryAddress\n   */\n  this.secondaryAddress = function () {\n      return Helpers.replaceSymbolWithNumber(faker.random.arrayElement(\n          [\n              'Apt. ###',\n              'Suite ###'\n          ]\n      ));\n  }\n\n  /**\n   * county\n   *\n   * @method faker.address.county\n   */\n  this.county = function () {\n    return faker.random.arrayElement(faker.definitions.address.county);\n  }\n\n  /**\n   * country\n   *\n   * @method faker.address.country\n   */\n  this.country = function () {\n    return faker.random.arrayElement(faker.definitions.address.country);\n  }\n\n  /**\n   * countryCode\n   *\n   * @method faker.address.countryCode\n   */\n  this.countryCode = function () {\n    return faker.random.arrayElement(faker.definitions.address.country_code);\n  }\n\n  /**\n   * state\n   *\n   * @method faker.address.state\n   * @param {Boolean} useAbbr\n   */\n  this.state = function (useAbbr) {\n      return faker.random.arrayElement(faker.definitions.address.state);\n  }\n\n  /**\n   * stateAbbr\n   *\n   * @method faker.address.stateAbbr\n   */\n  this.stateAbbr = function () {\n      return faker.random.arrayElement(faker.definitions.address.state_abbr);\n  }\n\n  /**\n   * latitude\n   *\n   * @method faker.address.latitude\n   */\n  this.latitude = function () {\n      return (faker.random.number(180 * 10000) / 10000.0 - 90.0).toFixed(4);\n  }\n\n  /**\n   * longitude\n   *\n   * @method faker.address.longitude\n   */\n  this.longitude = function () {\n      return (faker.random.number(360 * 10000) / 10000.0 - 180.0).toFixed(4);\n  }\n  \n  return this;\n}\n\n\nmodule.exports = Address;\n\n},{}],3:[function(require,module,exports){\n/**\n *\n * @namespace faker.commerce\n */\nvar Commerce = function (faker) {\n  var self = this;\n\n  /**\n   * color\n   *\n   * @method faker.commerce.color\n   */\n  self.color = function() {\n      return faker.random.arrayElement(faker.definitions.commerce.color);\n  };\n\n  /**\n   * department\n   *\n   * @method faker.commerce.department\n   */\n  self.department = function() {\n      return faker.random.arrayElement(faker.definitions.commerce.department);\n  };\n\n  /**\n   * productName\n   *\n   * @method faker.commerce.productName\n   */\n  self.productName = function() {\n      return faker.commerce.productAdjective() + \" \" +\n              faker.commerce.productMaterial() + \" \" +\n              faker.commerce.product();\n  };\n\n  /**\n   * price\n   *\n   * @method faker.commerce.price\n   * @param {number} min\n   * @param {number} max\n   * @param {number} dec\n   * @param {string} symbol\n   *\n   * @return {string}\n   */\n  self.price = function(min, max, dec, symbol) {\n      min = min || 0;\n      max = max || 1000;\n      dec = dec === undefined ? 2 : dec;\n      symbol = symbol || '';\n\n      if (min < 0 || max < 0) {\n          return symbol + 0.00;\n      }\n\n      var randValue = faker.random.number({ max: max, min: min });\n\n      return symbol + (Math.round(randValue * Math.pow(10, dec)) / Math.pow(10, dec)).toFixed(dec);\n  };\n\n  /*\n  self.categories = function(num) {\n      var categories = [];\n\n      do {\n          var category = faker.random.arrayElement(faker.definitions.commerce.department);\n          if(categories.indexOf(category) === -1) {\n              categories.push(category);\n          }\n      } while(categories.length < num);\n\n      return categories;\n  };\n\n  */\n  /*\n  self.mergeCategories = function(categories) {\n      var separator = faker.definitions.separator || \" &\";\n      // TODO: find undefined here\n      categories = categories || faker.definitions.commerce.categories;\n      var commaSeparated = categories.slice(0, -1).join(', ');\n\n      return [commaSeparated, categories[categories.length - 1]].join(separator + \" \");\n  };\n  */\n\n  /**\n   * productAdjective\n   *\n   * @method faker.commerce.productAdjective\n   */\n  self.productAdjective = function() {\n      return faker.random.arrayElement(faker.definitions.commerce.product_name.adjective);\n  };\n\n  /**\n   * productMaterial\n   *\n   * @method faker.commerce.productMaterial\n   */\n  self.productMaterial = function() {\n      return faker.random.arrayElement(faker.definitions.commerce.product_name.material);\n  };\n\n  /**\n   * product\n   *\n   * @method faker.commerce.product\n   */\n  self.product = function() {\n      return faker.random.arrayElement(faker.definitions.commerce.product_name.product);\n  };\n\n  return self;\n};\n\nmodule['exports'] = Commerce;\n\n},{}],4:[function(require,module,exports){\n/**\n *\n * @namespace faker.company\n */\nvar Company = function (faker) {\n  \n  var self = this;\n  var f = faker.fake;\n  \n  /**\n   * suffixes\n   *\n   * @method faker.company.suffixes\n   */\n  this.suffixes = function () {\n    // Don't want the source array exposed to modification, so return a copy\n    return faker.definitions.company.suffix.slice(0);\n  }\n\n  /**\n   * companyName\n   *\n   * @method faker.company.companyName\n   * @param {string} format\n   */\n  this.companyName = function (format) {\n\n    var formats = [\n      '{{name.lastName}} {{company.companySuffix}}',\n      '{{name.lastName}} - {{name.lastName}}',\n      '{{name.lastName}}, {{name.lastName}} and {{name.lastName}}'\n    ];\n\n    if (typeof format !== \"number\") {\n      format = faker.random.number(formats.length - 1);\n    }\n\n    return f(formats[format]);\n  }\n\n  /**\n   * companySuffix\n   *\n   * @method faker.company.companySuffix\n   */\n  this.companySuffix = function () {\n      return faker.random.arrayElement(faker.company.suffixes());\n  }\n\n  /**\n   * catchPhrase\n   *\n   * @method faker.company.catchPhrase\n   */\n  this.catchPhrase = function () {\n    return f('{{company.catchPhraseAdjective}} {{company.catchPhraseDescriptor}} {{company.catchPhraseNoun}}')\n  }\n\n  /**\n   * bs\n   *\n   * @method faker.company.bs\n   */\n  this.bs = function () {\n    return f('{{company.bsAdjective}} {{company.bsBuzz}} {{company.bsNoun}}');\n  }\n\n  /**\n   * catchPhraseAdjective\n   *\n   * @method faker.company.catchPhraseAdjective\n   */\n  this.catchPhraseAdjective = function () {\n      return faker.random.arrayElement(faker.definitions.company.adjective);\n  }\n\n  /**\n   * catchPhraseDescriptor\n   *\n   * @method faker.company.catchPhraseDescriptor\n   */\n  this.catchPhraseDescriptor = function () {\n      return faker.random.arrayElement(faker.definitions.company.descriptor);\n  }\n\n  /**\n   * catchPhraseNoun\n   *\n   * @method faker.company.catchPhraseNoun\n   */\n  this.catchPhraseNoun = function () {\n      return faker.random.arrayElement(faker.definitions.company.noun);\n  }\n\n  /**\n   * bsAdjective\n   *\n   * @method faker.company.bsAdjective\n   */\n  this.bsAdjective = function () {\n      return faker.random.arrayElement(faker.definitions.company.bs_adjective);\n  }\n\n  /**\n   * bsBuzz\n   *\n   * @method faker.company.bsBuzz\n   */\n  this.bsBuzz = function () {\n      return faker.random.arrayElement(faker.definitions.company.bs_verb);\n  }\n\n  /**\n   * bsNoun\n   *\n   * @method faker.company.bsNoun\n   */\n  this.bsNoun = function () {\n      return faker.random.arrayElement(faker.definitions.company.bs_noun);\n  }\n  \n}\n\nmodule['exports'] = Company;\n},{}],5:[function(require,module,exports){\n/**\n *\n * @namespace faker.database\n */\nvar Database = function (faker) {\n  var self = this;\n  /**\n   * column\n   *\n   * @method faker.database.column\n   */\n  self.column = function () {\n      return faker.random.arrayElement(faker.definitions.database.column);\n  };\n\n  self.column.schema = {\n    \"description\": \"Generates a column name.\",\n    \"sampleResults\": [\"id\", \"title\", \"createdAt\"]\n  };\n\n  /**\n   * type\n   *\n   * @method faker.database.type\n   */\n  self.type = function () {\n      return faker.random.arrayElement(faker.definitions.database.type);\n  };\n\n  self.type.schema = {\n    \"description\": \"Generates a column type.\",\n    \"sampleResults\": [\"byte\", \"int\", \"varchar\", \"timestamp\"]\n  };\n\n  /**\n   * collation\n   *\n   * @method faker.database.collation\n   */\n  self.collation = function () {\n      return faker.random.arrayElement(faker.definitions.database.collation);\n  };\n\n  self.collation.schema = {\n    \"description\": \"Generates a collation.\",\n    \"sampleResults\": [\"utf8_unicode_ci\", \"utf8_bin\"]\n  };\n\n  /**\n   * engine\n   *\n   * @method faker.database.engine\n   */\n  self.engine = function () {\n      return faker.random.arrayElement(faker.definitions.database.engine);\n  };\n\n  self.engine.schema = {\n    \"description\": \"Generates a storage engine.\",\n    \"sampleResults\": [\"MyISAM\", \"InnoDB\"]\n  };\n};\n\nmodule[\"exports\"] = Database;\n\n},{}],6:[function(require,module,exports){\n/**\n *\n * @namespace faker.date\n */\nvar _Date = function (faker) {\n  var self = this;\n  /**\n   * past\n   *\n   * @method faker.date.past\n   * @param {number} years\n   * @param {date} refDate\n   */\n  self.past = function (years, refDate) {\n      var date = (refDate) ? new Date(Date.parse(refDate)) : new Date();\n      var range = {\n        min: 1000,\n        max: (years || 1) * 365 * 24 * 3600 * 1000\n      };\n\n      var past = date.getTime();\n      past -= faker.random.number(range); // some time from now to N years ago, in milliseconds\n      date.setTime(past);\n\n      return date;\n  };\n\n  /**\n   * future\n   *\n   * @method faker.date.future\n   * @param {number} years\n   * @param {date} refDate\n   */\n  self.future = function (years, refDate) {\n      var date = (refDate) ? new Date(Date.parse(refDate)) : new Date();\n      var range = {\n        min: 1000,\n        max: (years || 1) * 365 * 24 * 3600 * 1000\n      };\n\n      var future = date.getTime();\n      future += faker.random.number(range); // some time from now to N years later, in milliseconds\n      date.setTime(future);\n\n      return date;\n  };\n\n  /**\n   * between\n   *\n   * @method faker.date.between\n   * @param {date} from\n   * @param {date} to\n   */\n  self.between = function (from, to) {\n      var fromMilli = Date.parse(from);\n      var dateOffset = faker.random.number(Date.parse(to) - fromMilli);\n\n      var newDate = new Date(fromMilli + dateOffset);\n\n      return newDate;\n  };\n\n  /**\n   * recent\n   *\n   * @method faker.date.recent\n   * @param {number} days\n   */\n  self.recent = function (days) {\n      var date = new Date();\n      var range = {\n        min: 1000,\n        max: (days || 1) * 24 * 3600 * 1000\n      };\n\n      var future = date.getTime();\n      future -= faker.random.number(range); // some time from now to N days ago, in milliseconds\n      date.setTime(future);\n\n      return date;\n  };\n\n  /**\n   * month\n   *\n   * @method faker.date.month\n   * @param {object} options\n   */\n  self.month = function (options) {\n      options = options || {};\n\n      var type = 'wide';\n      if (options.abbr) {\n          type = 'abbr';\n      }\n      if (options.context && typeof faker.definitions.date.month[type + '_context'] !== 'undefined') {\n          type += '_context';\n      }\n\n      var source = faker.definitions.date.month[type];\n\n      return faker.random.arrayElement(source);\n  };\n\n  /**\n   * weekday\n   *\n   * @param {object} options\n   * @method faker.date.weekday\n   */\n  self.weekday = function (options) {\n      options = options || {};\n\n      var type = 'wide';\n      if (options.abbr) {\n          type = 'abbr';\n      }\n      if (options.context && typeof faker.definitions.date.weekday[type + '_context'] !== 'undefined') {\n          type += '_context';\n      }\n\n      var source = faker.definitions.date.weekday[type];\n\n      return faker.random.arrayElement(source);\n  };\n  \n  return self;\n  \n};\n\nmodule['exports'] = _Date;\n},{}],7:[function(require,module,exports){\n/*\n  fake.js - generator method for combining faker methods based on string input\n\n*/\n\nfunction Fake (faker) {\n  \n  /**\n   * Generator method for combining faker methods based on string input\n   *\n   * __Example:__\n   *\n   * ```\n   * console.log(faker.fake('{{name.lastName}}, {{name.firstName}} {{name.suffix}}'));\n   * //outputs: \"Marks, Dean Sr.\"\n   * ```\n   *\n   * This will interpolate the format string with the value of methods\n   * [name.lastName]{@link faker.name.lastName}, [name.firstName]{@link faker.name.firstName},\n   * and [name.suffix]{@link faker.name.suffix}\n   *\n   * @method faker.fake\n   * @param {string} str\n   */\n  this.fake = function fake (str) {\n    // setup default response as empty string\n    var res = '';\n\n    // if incoming str parameter is not provided, return error message\n    if (typeof str !== 'string' || str.length === 0) {\n      res = 'string parameter is required!';\n      return res;\n    }\n\n    // find first matching {{ and }}\n    var start = str.search('{{');\n    var end = str.search('}}');\n\n    // if no {{ and }} is found, we are done\n    if (start === -1 && end === -1) {\n      return str;\n    }\n\n    // console.log('attempting to parse', str);\n\n    // extract method name from between the {{ }} that we found\n    // for example: {{name.firstName}}\n    var token = str.substr(start + 2,  end - start - 2);\n    var method = token.replace('}}', '').replace('{{', '');\n\n    // console.log('method', method)\n\n    // extract method parameters\n    var regExp = /\\(([^)]+)\\)/;\n    var matches = regExp.exec(method);\n    var parameters = '';\n    if (matches) {\n      method = method.replace(regExp, '');\n      parameters = matches[1];\n    }\n\n    // split the method into module and function\n    var parts = method.split('.');\n\n    if (typeof faker[parts[0]] === \"undefined\") {\n      throw new Error('Invalid module: ' + parts[0]);\n    }\n\n    if (typeof faker[parts[0]][parts[1]] === \"undefined\") {\n      throw new Error('Invalid method: ' + parts[0] + \".\" + parts[1]);\n    }\n\n    // assign the function from the module.function namespace\n    var fn = faker[parts[0]][parts[1]];\n\n    // If parameters are populated here, they are always going to be of string type\n    // since we might actually be dealing with an object or array,\n    // we always attempt to the parse the incoming parameters into JSON\n    var params;\n    // Note: we experience a small performance hit here due to JSON.parse try / catch\n    // If anyone actually needs to optimize this specific code path, please open a support issue on github\n    try {\n      params = JSON.parse(parameters)\n    } catch (err) {\n      // since JSON.parse threw an error, assume parameters was actually a string\n      params = parameters;\n    }\n\n    var result;\n    if (typeof params === \"string\" && params.length === 0) {\n      result = fn.call(this);\n    } else {\n      result = fn.call(this, params);\n    }\n\n    // replace the found tag with the returned fake value\n    res = str.replace('{{' + token + '}}', result);\n\n    // return the response recursively until we are done finding all tags\n    return fake(res);    \n  }\n  \n  return this;\n  \n  \n}\n\nmodule['exports'] = Fake;\n},{}],8:[function(require,module,exports){\n/**\n * @namespace faker.finance\n */\nvar Finance = function (faker) {\n  var ibanLib = require(\"./iban\");\n  var Helpers = faker.helpers,\n      self = this;\n\n  /**\n   * account\n   *\n   * @method faker.finance.account\n   * @param {number} length\n   */\n  self.account = function (length) {\n\n      length = length || 8;\n\n      var template = '';\n\n      for (var i = 0; i < length; i++) {\n          template = template + '#';\n      }\n      length = null;\n      return Helpers.replaceSymbolWithNumber(template);\n  };\n\n  /**\n   * accountName\n   *\n   * @method faker.finance.accountName\n   */\n  self.accountName = function () {\n\n      return [Helpers.randomize(faker.definitions.finance.account_type), 'Account'].join(' ');\n  };\n\n  /**\n   * mask\n   *\n   * @method faker.finance.mask\n   * @param {number} length\n   * @param {boolean} parens\n   * @param {boolean} ellipsis\n   */\n  self.mask = function (length, parens, ellipsis) {\n\n      //set defaults\n      length = (length == 0 || !length || typeof length == 'undefined') ? 4 : length;\n      parens = (parens === null) ? true : parens;\n      ellipsis = (ellipsis === null) ? true : ellipsis;\n\n      //create a template for length\n      var template = '';\n\n      for (var i = 0; i < length; i++) {\n          template = template + '#';\n      }\n\n      //prefix with ellipsis\n      template = (ellipsis) ? ['...', template].join('') : template;\n\n      template = (parens) ? ['(', template, ')'].join('') : template;\n\n      //generate random numbers\n      template = Helpers.replaceSymbolWithNumber(template);\n\n      return template;\n  };\n\n  //min and max take in minimum and maximum amounts, dec is the decimal place you want rounded to, symbol is $, €, £, etc\n  //NOTE: this returns a string representation of the value, if you want a number use parseFloat and no symbol\n\n  /**\n   * amount\n   *\n   * @method faker.finance.amount\n   * @param {number} min\n   * @param {number} max\n   * @param {number} dec\n   * @param {string} symbol\n   *\n   * @return {string}\n   */\n  self.amount = function (min, max, dec, symbol) {\n\n      min = min || 0;\n      max = max || 1000;\n      dec = dec === undefined ? 2 : dec;\n      symbol = symbol || '';\n      var randValue = faker.random.number({ max: max, min: min, precision: Math.pow(10, -dec) });\n\n      return symbol + randValue.toFixed(dec);\n  };\n\n  /**\n   * transactionType\n   *\n   * @method faker.finance.transactionType\n   */\n  self.transactionType = function () {\n      return Helpers.randomize(faker.definitions.finance.transaction_type);\n  };\n\n  /**\n   * currencyCode\n   *\n   * @method faker.finance.currencyCode\n   */\n  self.currencyCode = function () {\n      return faker.random.objectElement(faker.definitions.finance.currency)['code'];\n  };\n\n  /**\n   * currencyName\n   *\n   * @method faker.finance.currencyName\n   */\n  self.currencyName = function () {\n      return faker.random.objectElement(faker.definitions.finance.currency, 'key');\n  };\n\n  /**\n   * currencySymbol\n   *\n   * @method faker.finance.currencySymbol\n   */\n  self.currencySymbol = function () {\n      var symbol;\n\n      while (!symbol) {\n          symbol = faker.random.objectElement(faker.definitions.finance.currency)['symbol'];\n      }\n      return symbol;\n  };\n\n  /**\n   * bitcoinAddress\n   *\n   * @method  faker.finance.bitcoinAddress\n   */\n  self.bitcoinAddress = function () {\n    var addressLength = faker.random.number({ min: 27, max: 34 });\n\n    var address = faker.random.arrayElement(['1', '3']);\n\n    for (var i = 0; i < addressLength - 1; i++)\n      address += faker.random.alphaNumeric().toUpperCase();\n\n    return address;\n  };\n\n  /**\n   * iban\n   *\n   * @method  faker.finance.iban\n   */\n  self.iban = function (formatted) {\n      var ibanFormat = faker.random.arrayElement(ibanLib.formats);\n      var s = \"\";\n      var count = 0;\n      for (var b = 0; b < ibanFormat.bban.length; b++) {\n          var bban = ibanFormat.bban[b];\n          var c = bban.count;\n          count += bban.count;\n          while (c > 0) {\n              if (bban.type == \"a\") {\n                  s += faker.random.arrayElement(ibanLib.alpha);\n              } else if (bban.type == \"c\") {\n                  if (faker.random.number(100) < 80) {\n                      s += faker.random.number(9);\n                  } else {\n                      s += faker.random.arrayElement(ibanLib.alpha);\n                  }\n              } else {\n                  if (c >= 3 && faker.random.number(100) < 30) {\n                      if (faker.random.boolean()) {\n                          s += faker.random.arrayElement(ibanLib.pattern100);\n                          c -= 2;\n                      } else {\n                          s += faker.random.arrayElement(ibanLib.pattern10);\n                          c--;\n                      }\n                  } else {\n                      s += faker.random.number(9);\n                  }\n              }\n              c--;\n          }\n          s = s.substring(0, count);\n      }\n      var checksum = 98 - ibanLib.mod97(ibanLib.toDigitString(s + ibanFormat.country + \"00\"));\n      if (checksum < 10) {\n          checksum = \"0\" + checksum;\n      }\n      var iban = ibanFormat.country + checksum + s;\n      return formatted ? iban.match(/.{1,4}/g).join(\" \") : iban;\n  };\n\n  /**\n   * bic\n   *\n   * @method  faker.finance.bic\n   */\n  self.bic = function () {\n      var vowels = [\"A\", \"E\", \"I\", \"O\", \"U\"];\n      var prob = faker.random.number(100);\n      return Helpers.replaceSymbols(\"???\") +\n          faker.random.arrayElement(vowels) +\n          faker.random.arrayElement(ibanLib.iso3166) +\n          Helpers.replaceSymbols(\"?\") + \"1\" +\n          (prob < 10 ?\n              Helpers.replaceSymbols(\"?\" + faker.random.arrayElement(vowels) + \"?\") :\n          prob < 40 ?\n              Helpers.replaceSymbols(\"###\") : \"\");\n  };\n};\n\nmodule['exports'] = Finance;\n\n},{\"./iban\":11}],9:[function(require,module,exports){\n/**\n *\n * @namespace faker.hacker\n */\nvar Hacker = function (faker) {\n  var self = this;\n  \n  /**\n   * abbreviation\n   *\n   * @method faker.hacker.abbreviation\n   */\n  self.abbreviation = function () {\n    return faker.random.arrayElement(faker.definitions.hacker.abbreviation);\n  };\n\n  /**\n   * adjective\n   *\n   * @method faker.hacker.adjective\n   */\n  self.adjective = function () {\n    return faker.random.arrayElement(faker.definitions.hacker.adjective);\n  };\n\n  /**\n   * noun\n   *\n   * @method faker.hacker.noun\n   */\n  self.noun = function () {\n    return faker.random.arrayElement(faker.definitions.hacker.noun);\n  };\n\n  /**\n   * verb\n   *\n   * @method faker.hacker.verb\n   */\n  self.verb = function () {\n    return faker.random.arrayElement(faker.definitions.hacker.verb);\n  };\n\n  /**\n   * ingverb\n   *\n   * @method faker.hacker.ingverb\n   */\n  self.ingverb = function () {\n    return faker.random.arrayElement(faker.definitions.hacker.ingverb);\n  };\n\n  /**\n   * phrase\n   *\n   * @method faker.hacker.phrase\n   */\n  self.phrase = function () {\n\n    var data = {\n      abbreviation: self.abbreviation,\n      adjective: self.adjective,\n      ingverb: self.ingverb,\n      noun: self.noun,\n      verb: self.verb\n    };\n\n    var phrase = faker.random.arrayElement([ \"If we {{verb}} the {{noun}}, we can get to the {{abbreviation}} {{noun}} through the {{adjective}} {{abbreviation}} {{noun}}!\",\n      \"We need to {{verb}} the {{adjective}} {{abbreviation}} {{noun}}!\",\n      \"Try to {{verb}} the {{abbreviation}} {{noun}}, maybe it will {{verb}} the {{adjective}} {{noun}}!\",\n      \"You can't {{verb}} the {{noun}} without {{ingverb}} the {{adjective}} {{abbreviation}} {{noun}}!\",\n      \"Use the {{adjective}} {{abbreviation}} {{noun}}, then you can {{verb}} the {{adjective}} {{noun}}!\",\n      \"The {{abbreviation}} {{noun}} is down, {{verb}} the {{adjective}} {{noun}} so we can {{verb}} the {{abbreviation}} {{noun}}!\",\n      \"{{ingverb}} the {{noun}} won't do anything, we need to {{verb}} the {{adjective}} {{abbreviation}} {{noun}}!\",\n      \"I'll {{verb}} the {{adjective}} {{abbreviation}} {{noun}}, that should {{noun}} the {{abbreviation}} {{noun}}!\"\n   ]);\n\n   return faker.helpers.mustache(phrase, data);\n\n  };\n  \n  return self;\n};\n\nmodule['exports'] = Hacker;\n},{}],10:[function(require,module,exports){\n/**\n *\n * @namespace faker.helpers\n */\nvar Helpers = function (faker) {\n\n  var self = this;\n\n  /**\n   * backword-compatibility\n   *\n   * @method faker.helpers.randomize\n   * @param {array} array\n   */\n  self.randomize = function (array) {\n      array = array || [\"a\", \"b\", \"c\"];\n      return faker.random.arrayElement(array);\n  };\n\n  /**\n   * slugifies string\n   *\n   * @method faker.helpers.slugify\n   * @param {string} string\n   */\n  self.slugify = function (string) {\n      string = string || \"\";\n      return string.replace(/ /g, '-').replace(/[^\\w\\.\\-]+/g, '');\n  };\n\n  /**\n   * parses string for a symbol and replace it with a random number from 1-10\n   *\n   * @method faker.helpers.replaceSymbolWithNumber\n   * @param {string} string\n   * @param {string} symbol defaults to `\"#\"`\n   */\n  self.replaceSymbolWithNumber = function (string, symbol) {\n      string = string || \"\";\n      // default symbol is '#'\n      if (symbol === undefined) {\n          symbol = '#';\n      }\n\n      var str = '';\n      for (var i = 0; i < string.length; i++) {\n          if (string.charAt(i) == symbol) {\n              str += faker.random.number(9);\n          } else {\n              str += string.charAt(i);\n          }\n      }\n      return str;\n  };\n\n  /**\n   * parses string for symbols (numbers or letters) and replaces them appropriately\n   *\n   * @method faker.helpers.replaceSymbols\n   * @param {string} string\n   */\n  self.replaceSymbols = function (string) {\n      string = string || \"\";\n      var alpha = ['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']\n      var str = '';\n\n      for (var i = 0; i < string.length; i++) {\n          if (string.charAt(i) == \"#\") {\n              str += faker.random.number(9);\n          } else if (string.charAt(i) == \"?\") {\n              str += faker.random.arrayElement(alpha);\n          } else {\n              str += string.charAt(i);\n          }\n      }\n      return str;\n  };\n\n  /**\n   * takes an array and returns it randomized\n   *\n   * @method faker.helpers.shuffle\n   * @param {array} o\n   */\n  self.shuffle = function (o) {\n      if (typeof o === 'undefined' || o.length === 0) {\n        return [];\n      }\n      o = o || [\"a\", \"b\", \"c\"];\n      for (var j, x, i = o.length-1; i; j = faker.random.number(i), x = o[--i], o[i] = o[j], o[j] = x);\n      return o;\n  };\n\n  /**\n   * mustache\n   *\n   * @method faker.helpers.mustache\n   * @param {string} str\n   * @param {object} data\n   */\n  self.mustache = function (str, data) {\n    if (typeof str === 'undefined') {\n      return '';\n    }\n    for(var p in data) {\n      var re = new RegExp('{{' + p + '}}', 'g')\n      str = str.replace(re, data[p]);\n    }\n    return str;\n  };\n\n  /**\n   * createCard\n   *\n   * @method faker.helpers.createCard\n   */\n  self.createCard = function () {\n      return {\n          \"name\": faker.name.findName(),\n          \"username\": faker.internet.userName(),\n          \"email\": faker.internet.email(),\n          \"address\": {\n              \"streetA\": faker.address.streetName(),\n              \"streetB\": faker.address.streetAddress(),\n              \"streetC\": faker.address.streetAddress(true),\n              \"streetD\": faker.address.secondaryAddress(),\n              \"city\": faker.address.city(),\n              \"state\": faker.address.state(),\n              \"country\": faker.address.country(),\n              \"zipcode\": faker.address.zipCode(),\n              \"geo\": {\n                  \"lat\": faker.address.latitude(),\n                  \"lng\": faker.address.longitude()\n              }\n          },\n          \"phone\": faker.phone.phoneNumber(),\n          \"website\": faker.internet.domainName(),\n          \"company\": {\n              \"name\": faker.company.companyName(),\n              \"catchPhrase\": faker.company.catchPhrase(),\n              \"bs\": faker.company.bs()\n          },\n          \"posts\": [\n              {\n                  \"words\": faker.lorem.words(),\n                  \"sentence\": faker.lorem.sentence(),\n                  \"sentences\": faker.lorem.sentences(),\n                  \"paragraph\": faker.lorem.paragraph()\n              },\n              {\n                  \"words\": faker.lorem.words(),\n                  \"sentence\": faker.lorem.sentence(),\n                  \"sentences\": faker.lorem.sentences(),\n                  \"paragraph\": faker.lorem.paragraph()\n              },\n              {\n                  \"words\": faker.lorem.words(),\n                  \"sentence\": faker.lorem.sentence(),\n                  \"sentences\": faker.lorem.sentences(),\n                  \"paragraph\": faker.lorem.paragraph()\n              }\n          ],\n          \"accountHistory\": [faker.helpers.createTransaction(), faker.helpers.createTransaction(), faker.helpers.createTransaction()]\n      };\n  };\n\n  /**\n   * contextualCard\n   *\n   * @method faker.helpers.contextualCard\n   */\n  self.contextualCard = function () {\n    var name = faker.name.firstName(),\n        userName = faker.internet.userName(name);\n    return {\n        \"name\": name,\n        \"username\": userName,\n        \"avatar\": faker.internet.avatar(),\n        \"email\": faker.internet.email(userName),\n        \"dob\": faker.date.past(50, new Date(\"Sat Sep 20 1992 21:35:02 GMT+0200 (CEST)\")),\n        \"phone\": faker.phone.phoneNumber(),\n        \"address\": {\n            \"street\": faker.address.streetName(true),\n            \"suite\": faker.address.secondaryAddress(),\n            \"city\": faker.address.city(),\n            \"zipcode\": faker.address.zipCode(),\n            \"geo\": {\n                \"lat\": faker.address.latitude(),\n                \"lng\": faker.address.longitude()\n            }\n        },\n        \"website\": faker.internet.domainName(),\n        \"company\": {\n            \"name\": faker.company.companyName(),\n            \"catchPhrase\": faker.company.catchPhrase(),\n            \"bs\": faker.company.bs()\n        }\n    };\n  };\n\n\n  /**\n   * userCard\n   *\n   * @method faker.helpers.userCard\n   */\n  self.userCard = function () {\n      return {\n          \"name\": faker.name.findName(),\n          \"username\": faker.internet.userName(),\n          \"email\": faker.internet.email(),\n          \"address\": {\n              \"street\": faker.address.streetName(true),\n              \"suite\": faker.address.secondaryAddress(),\n              \"city\": faker.address.city(),\n              \"zipcode\": faker.address.zipCode(),\n              \"geo\": {\n                  \"lat\": faker.address.latitude(),\n                  \"lng\": faker.address.longitude()\n              }\n          },\n          \"phone\": faker.phone.phoneNumber(),\n          \"website\": faker.internet.domainName(),\n          \"company\": {\n              \"name\": faker.company.companyName(),\n              \"catchPhrase\": faker.company.catchPhrase(),\n              \"bs\": faker.company.bs()\n          }\n      };\n  };\n\n  /**\n   * createTransaction\n   *\n   * @method faker.helpers.createTransaction\n   */\n  self.createTransaction = function(){\n    return {\n      \"amount\" : faker.finance.amount(),\n      \"date\" : new Date(2012, 1, 2),  //TODO: add a ranged date method\n      \"business\": faker.company.companyName(),\n      \"name\": [faker.finance.accountName(), faker.finance.mask()].join(' '),\n      \"type\" : self.randomize(faker.definitions.finance.transaction_type),\n      \"account\" : faker.finance.account()\n    };\n  };\n\n  return self;\n\n};\n\n\n/*\nString.prototype.capitalize = function () { //v1.0\n    return this.replace(/\\w+/g, function (a) {\n        return a.charAt(0).toUpperCase() + a.substr(1).toLowerCase();\n    });\n};\n*/\n\nmodule['exports'] = Helpers;\n\n},{}],11:[function(require,module,exports){\nmodule[\"exports\"] = {\n  alpha: [\n    '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'\n  ],\n  pattern10: [\n    \"01\", \"02\", \"03\", \"04\", \"05\", \"06\", \"07\", \"08\", \"09\"\n  ],\n  pattern100: [\n    \"001\", \"002\", \"003\", \"004\", \"005\", \"006\", \"007\", \"008\", \"009\"\n  ],\n  toDigitString: function (str) {\n      return str.replace(/[A-Z]/gi, function(match) {\n          return match.toUpperCase().charCodeAt(0) - 55;\n      });\n  },\n  mod97: function (digitStr) {\n      var m = 0;\n      for (var i = 0; i < digitStr.length; i++) {\n          m = ((m * 10) + (digitStr[i] |0)) % 97;\n      }\n      return m;\n  },\n  formats: [\n    {\n      country: \"AL\",\n      total: 28,\n      bban: [\n        {\n          type: \"n\",\n          count: 8\n        },\n        {\n          type: \"c\",\n          count: 16\n        }\n      ],\n      format: \"ALkk bbbs sssx cccc cccc cccc cccc\"\n    },\n    {\n      country: \"AD\",\n      total: 24,\n      bban: [\n        {\n          type: \"n\",\n          count: 8\n        },\n        {\n          type: \"c\",\n          count: 12\n        }\n      ],\n      format: \"ADkk bbbb ssss cccc cccc cccc\"\n    },\n    {\n      country: \"AT\",\n      total: 20,\n      bban: [\n        {\n          type: \"n\",\n          count: 5\n        },\n        {\n          type: \"n\",\n          count: 11\n        }\n      ],\n      format: \"ATkk bbbb bccc cccc cccc\"\n    },\n    {\n      country: \"AZ\",\n      total: 28,\n      bban: [\n        {\n          type: \"c\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 20\n        }\n      ],\n      format: \"AZkk bbbb cccc cccc cccc cccc cccc\"\n    },\n    {\n      country: \"BH\",\n      total: 22,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 14\n        }\n      ],\n      format: \"BHkk bbbb cccc cccc cccc cc\"\n    },\n    {\n      country: \"BE\",\n      total: 16,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"n\",\n          count: 9\n        }\n      ],\n      format: \"BEkk bbbc cccc ccxx\"\n    },\n    {\n      country: \"BA\",\n      total: 20,\n      bban: [\n        {\n          type: \"n\",\n          count: 6\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"BAkk bbbs sscc cccc ccxx\"\n    },\n    {\n      country: \"BR\",\n      total: 29,\n      bban: [\n        {\n          type: \"n\",\n          count: 13\n        },\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"a\",\n          count: 1\n        },\n        {\n          type: \"c\",\n          count: 1\n        }\n      ],\n      format: \"BRkk bbbb bbbb ssss sccc cccc ccct n\"\n    },\n    {\n      country: \"BG\",\n      total: 22,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 6\n        },\n        {\n          type: \"c\",\n          count: 8\n        }\n      ],\n      format: \"BGkk bbbb ssss ddcc cccc cc\"\n    },\n    {\n      country: \"CR\",\n      total: 21,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"n\",\n          count: 14\n        }\n      ],\n      format: \"CRkk bbbc cccc cccc cccc c\"\n    },\n    {\n      country: \"HR\",\n      total: 21,\n      bban: [\n        {\n          type: \"n\",\n          count: 7\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"HRkk bbbb bbbc cccc cccc c\"\n    },\n    {\n      country: \"CY\",\n      total: 28,\n      bban: [\n        {\n          type: \"n\",\n          count: 8\n        },\n        {\n          type: \"c\",\n          count: 16\n        }\n      ],\n      format: \"CYkk bbbs ssss cccc cccc cccc cccc\"\n    },\n    {\n      country: \"CZ\",\n      total: 24,\n      bban: [\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"CZkk bbbb ssss sscc cccc cccc\"\n    },\n    {\n      country: \"DK\",\n      total: 18,\n      bban: [\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"DKkk bbbb cccc cccc cc\"\n    },\n    {\n      country: \"DO\",\n      total: 28,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 20\n        }\n      ],\n      format: \"DOkk bbbb cccc cccc cccc cccc cccc\"\n    },\n    {\n      country: \"TL\",\n      total: 23,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"n\",\n          count: 16\n        }\n      ],\n      format: \"TLkk bbbc cccc cccc cccc cxx\"\n    },\n    {\n      country: \"EE\",\n      total: 20,\n      bban: [\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 12\n        }\n      ],\n      format: \"EEkk bbss cccc cccc cccx\"\n    },\n    {\n      country: \"FO\",\n      total: 18,\n      bban: [\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"FOkk bbbb cccc cccc cx\"\n    },\n    {\n      country: \"FI\",\n      total: 18,\n      bban: [\n        {\n          type: \"n\",\n          count: 6\n        },\n        {\n          type: \"n\",\n          count: 8\n        }\n      ],\n      format: \"FIkk bbbb bbcc cccc cx\"\n    },\n    {\n      country: \"FR\",\n      total: 27,\n      bban: [\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"c\",\n          count: 11\n        },\n        {\n          type: \"n\",\n          count: 2\n        }\n      ],\n      format: \"FRkk bbbb bggg ggcc cccc cccc cxx\"\n    },\n    {\n      country: \"GE\",\n      total: 22,\n      bban: [\n        {\n          type: \"c\",\n          count: 2\n        },\n        {\n          type: \"n\",\n          count: 16\n        }\n      ],\n      format: \"GEkk bbcc cccc cccc cccc cc\"\n    },\n    {\n      country: \"DE\",\n      total: 22,\n      bban: [\n        {\n          type: \"n\",\n          count: 8\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"DEkk bbbb bbbb cccc cccc cc\"\n    },\n    {\n      country: \"GI\",\n      total: 23,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 15\n        }\n      ],\n      format: \"GIkk bbbb cccc cccc cccc ccc\"\n    },\n    {\n      country: \"GR\",\n      total: 27,\n      bban: [\n        {\n          type: \"n\",\n          count: 7\n        },\n        {\n          type: \"c\",\n          count: 16\n        }\n      ],\n      format: \"GRkk bbbs sssc cccc cccc cccc ccc\"\n    },\n    {\n      country: \"GL\",\n      total: 18,\n      bban: [\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"GLkk bbbb cccc cccc cc\"\n    },\n    {\n      country: \"GT\",\n      total: 28,\n      bban: [\n        {\n          type: \"c\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 16\n        }\n      ],\n      format: \"GTkk bbbb mmtt cccc cccc cccc cccc\"\n    },\n    {\n      country: \"HU\",\n      total: 28,\n      bban: [\n        {\n          type: \"n\",\n          count: 8\n        },\n        {\n          type: \"n\",\n          count: 16\n        }\n      ],\n      format: \"HUkk bbbs sssk cccc cccc cccc cccx\"\n    },\n    {\n      country: \"IS\",\n      total: 26,\n      bban: [\n        {\n          type: \"n\",\n          count: 6\n        },\n        {\n          type: \"n\",\n          count: 16\n        }\n      ],\n      format: \"ISkk bbbb sscc cccc iiii iiii ii\"\n    },\n    {\n      country: \"IE\",\n      total: 22,\n      bban: [\n        {\n          type: \"c\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 6\n        },\n        {\n          type: \"n\",\n          count: 8\n        }\n      ],\n      format: \"IEkk aaaa bbbb bbcc cccc cc\"\n    },\n    {\n      country: \"IL\",\n      total: 23,\n      bban: [\n        {\n          type: \"n\",\n          count: 6\n        },\n        {\n          type: \"n\",\n          count: 13\n        }\n      ],\n      format: \"ILkk bbbn nncc cccc cccc ccc\"\n    },\n    {\n      country: \"IT\",\n      total: 27,\n      bban: [\n        {\n          type: \"a\",\n          count: 1\n        },\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"c\",\n          count: 12\n        }\n      ],\n      format: \"ITkk xaaa aabb bbbc cccc cccc ccc\"\n    },\n    {\n      country: \"JO\",\n      total: 30,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 18\n        }\n      ],\n      format: \"JOkk bbbb nnnn cccc cccc cccc cccc cc\"\n    },\n    {\n      country: \"KZ\",\n      total: 20,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"c\",\n          count: 13\n        }\n      ],\n      format: \"KZkk bbbc cccc cccc cccc\"\n    },\n    {\n      country: \"XK\",\n      total: 20,\n      bban: [\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 12\n        }\n      ],\n      format: \"XKkk bbbb cccc cccc cccc\"\n    },\n    {\n      country: \"KW\",\n      total: 30,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 22\n        }\n      ],\n      format: \"KWkk bbbb cccc cccc cccc cccc cccc cc\"\n    },\n    {\n      country: \"LV\",\n      total: 21,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 13\n        }\n      ],\n      format: \"LVkk bbbb cccc cccc cccc c\"\n    },\n    {\n      country: \"LB\",\n      total: 28,\n      bban: [\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 20\n        }\n      ],\n      format: \"LBkk bbbb cccc cccc cccc cccc cccc\"\n    },\n    {\n      country: \"LI\",\n      total: 21,\n      bban: [\n        {\n          type: \"n\",\n          count: 5\n        },\n        {\n          type: \"c\",\n          count: 12\n        }\n      ],\n      format: \"LIkk bbbb bccc cccc cccc c\"\n    },\n    {\n      country: \"LT\",\n      total: 20,\n      bban: [\n        {\n          type: \"n\",\n          count: 5\n        },\n        {\n          type: \"n\",\n          count: 11\n        }\n      ],\n      format: \"LTkk bbbb bccc cccc cccc\"\n    },\n    {\n      country: \"LU\",\n      total: 20,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"c\",\n          count: 13\n        }\n      ],\n      format: \"LUkk bbbc cccc cccc cccc\"\n    },\n    {\n      country: \"MK\",\n      total: 19,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"c\",\n          count: 10\n        },\n        {\n          type: \"n\",\n          count: 2\n        }\n      ],\n      format: \"MKkk bbbc cccc cccc cxx\"\n    },\n    {\n      country: \"MT\",\n      total: 31,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 5\n        },\n        {\n          type: \"c\",\n          count: 18\n        }\n      ],\n      format: \"MTkk bbbb ssss sccc cccc cccc cccc ccc\"\n    },\n    {\n      country: \"MR\",\n      total: 27,\n      bban: [\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"n\",\n          count: 13\n        }\n      ],\n      format: \"MRkk bbbb bsss sscc cccc cccc cxx\"\n    },\n    {\n      country: \"MU\",\n      total: 30,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 15\n        },\n        {\n          type: \"a\",\n          count: 3\n        }\n      ],\n      format: \"MUkk bbbb bbss cccc cccc cccc 000d dd\"\n    },\n    {\n      country: \"MC\",\n      total: 27,\n      bban: [\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"c\",\n          count: 11\n        },\n        {\n          type: \"n\",\n          count: 2\n        }\n      ],\n      format: \"MCkk bbbb bsss sscc cccc cccc cxx\"\n    },\n    {\n      country: \"MD\",\n      total: 24,\n      bban: [\n        {\n          type: \"c\",\n          count: 2\n        },\n        {\n          type: \"c\",\n          count: 18\n        }\n      ],\n      format: \"MDkk bbcc cccc cccc cccc cccc\"\n    },\n    {\n      country: \"ME\",\n      total: 22,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"n\",\n          count: 15\n        }\n      ],\n      format: \"MEkk bbbc cccc cccc cccc xx\"\n    },\n    {\n      country: \"NL\",\n      total: 18,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"NLkk bbbb cccc cccc cc\"\n    },\n    {\n      country: \"NO\",\n      total: 15,\n      bban: [\n        {\n          type: \"n\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 7\n        }\n      ],\n      format: \"NOkk bbbb cccc ccx\"\n    },\n    {\n      country: \"PK\",\n      total: 24,\n      bban: [\n        {\n          type: \"c\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 16\n        }\n      ],\n      format: \"PKkk bbbb cccc cccc cccc cccc\"\n    },\n    {\n      country: \"PS\",\n      total: 29,\n      bban: [\n        {\n          type: \"c\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 9\n        },\n        {\n          type: \"n\",\n          count: 12\n        }\n      ],\n      format: \"PSkk bbbb xxxx xxxx xccc cccc cccc c\"\n    },\n    {\n      country: \"PL\",\n      total: 28,\n      bban: [\n        {\n          type: \"n\",\n          count: 8\n        },\n        {\n          type: \"n\",\n          count: 16\n        }\n      ],\n      format: \"PLkk bbbs sssx cccc cccc cccc cccc\"\n    },\n    {\n      country: \"PT\",\n      total: 25,\n      bban: [\n        {\n          type: \"n\",\n          count: 8\n        },\n        {\n          type: \"n\",\n          count: 13\n        }\n      ],\n      format: \"PTkk bbbb ssss cccc cccc cccx x\"\n    },\n    {\n      country: \"QA\",\n      total: 29,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 21\n        }\n      ],\n      format: \"QAkk bbbb cccc cccc cccc cccc cccc c\"\n    },\n    {\n      country: \"RO\",\n      total: 24,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"c\",\n          count: 16\n        }\n      ],\n      format: \"ROkk bbbb cccc cccc cccc cccc\"\n    },\n    {\n      country: \"SM\",\n      total: 27,\n      bban: [\n        {\n          type: \"a\",\n          count: 1\n        },\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"c\",\n          count: 12\n        }\n      ],\n      format: \"SMkk xaaa aabb bbbc cccc cccc ccc\"\n    },\n    {\n      country: \"SA\",\n      total: 24,\n      bban: [\n        {\n          type: \"n\",\n          count: 2\n        },\n        {\n          type: \"c\",\n          count: 18\n        }\n      ],\n      format: \"SAkk bbcc cccc cccc cccc cccc\"\n    },\n    {\n      country: \"RS\",\n      total: 22,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"n\",\n          count: 15\n        }\n      ],\n      format: \"RSkk bbbc cccc cccc cccc xx\"\n    },\n    {\n      country: \"SK\",\n      total: 24,\n      bban: [\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"SKkk bbbb ssss sscc cccc cccc\"\n    },\n    {\n      country: \"SI\",\n      total: 19,\n      bban: [\n        {\n          type: \"n\",\n          count: 5\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"SIkk bbss sccc cccc cxx\"\n    },\n    {\n      country: \"ES\",\n      total: 24,\n      bban: [\n        {\n          type: \"n\",\n          count: 10\n        },\n        {\n          type: \"n\",\n          count: 10\n        }\n      ],\n      format: \"ESkk bbbb gggg xxcc cccc cccc\"\n    },\n    {\n      country: \"SE\",\n      total: 24,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"n\",\n          count: 17\n        }\n      ],\n      format: \"SEkk bbbc cccc cccc cccc cccc\"\n    },\n    {\n      country: \"CH\",\n      total: 21,\n      bban: [\n        {\n          type: \"n\",\n          count: 5\n        },\n        {\n          type: \"c\",\n          count: 12\n        }\n      ],\n      format: \"CHkk bbbb bccc cccc cccc c\"\n    },\n    {\n      country: \"TN\",\n      total: 24,\n      bban: [\n        {\n          type: \"n\",\n          count: 5\n        },\n        {\n          type: \"n\",\n          count: 15\n        }\n      ],\n      format: \"TNkk bbss sccc cccc cccc cccc\"\n    },\n    {\n      country: \"TR\",\n      total: 26,\n      bban: [\n        {\n          type: \"n\",\n          count: 5\n        },\n        {\n          type: \"c\",\n          count: 1\n        },\n        {\n          type: \"c\",\n          count: 16\n        }\n      ],\n      format: \"TRkk bbbb bxcc cccc cccc cccc cc\"\n    },\n    {\n      country: \"AE\",\n      total: 23,\n      bban: [\n        {\n          type: \"n\",\n          count: 3\n        },\n        {\n          type: \"n\",\n          count: 16\n        }\n      ],\n      format: \"AEkk bbbc cccc cccc cccc ccc\"\n    },\n    {\n      country: \"GB\",\n      total: 22,\n      bban: [\n        {\n          type: \"a\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 6\n        },\n        {\n          type: \"n\",\n          count: 8\n        }\n      ],\n      format: \"GBkk bbbb ssss sscc cccc cc\"\n    },\n    {\n      country: \"VG\",\n      total: 24,\n      bban: [\n        {\n          type: \"c\",\n          count: 4\n        },\n        {\n          type: \"n\",\n          count: 16\n        }\n      ],\n      format: \"VGkk bbbb cccc cccc cccc cccc\"\n    }\n  ],\n  iso3166: [\n    \"AC\", \"AD\", \"AE\", \"AF\", \"AG\", \"AI\", \"AL\", \"AM\", \"AN\", \"AO\", \"AQ\", \"AR\", \"AS\",\n    \"AT\", \"AU\", \"AW\", \"AX\", \"AZ\", \"BA\", \"BB\", \"BD\", \"BE\", \"BF\", \"BG\", \"BH\", \"BI\",\n    \"BJ\", \"BL\", \"BM\", \"BN\", \"BO\", \"BQ\", \"BR\", \"BS\", \"BT\", \"BU\", \"BV\", \"BW\", \"BY\",\n    \"BZ\", \"CA\", \"CC\", \"CD\", \"CE\", \"CF\", \"CG\", \"CH\", \"CI\", \"CK\", \"CL\", \"CM\", \"CN\",\n    \"CO\", \"CP\", \"CR\", \"CS\", \"CS\", \"CU\", \"CV\", \"CW\", \"CX\", \"CY\", \"CZ\", \"DD\", \"DE\",\n    \"DG\", \"DJ\", \"DK\", \"DM\", \"DO\", \"DZ\", \"EA\", \"EC\", \"EE\", \"EG\", \"EH\", \"ER\", \"ES\",\n    \"ET\", \"EU\", \"FI\", \"FJ\", \"FK\", \"FM\", \"FO\", \"FR\", \"FX\", \"GA\", \"GB\", \"GD\", \"GE\",\n    \"GF\", \"GG\", \"GH\", \"GI\", \"GL\", \"GM\", \"GN\", \"GP\", \"GQ\", \"GR\", \"GS\", \"GT\", \"GU\",\n    \"GW\", \"GY\", \"HK\", \"HM\", \"HN\", \"HR\", \"HT\", \"HU\", \"IC\", \"ID\", \"IE\", \"IL\", \"IM\",\n    \"IN\", \"IO\", \"IQ\", \"IR\", \"IS\", \"IT\", \"JE\", \"JM\", \"JO\", \"JP\", \"KE\", \"KG\", \"KH\",\n    \"KI\", \"KM\", \"KN\", \"KP\", \"KR\", \"KW\", \"KY\", \"KZ\", \"LA\", \"LB\", \"LC\", \"LI\", \"LK\",\n    \"LR\", \"LS\", \"LT\", \"LU\", \"LV\", \"LY\", \"MA\", \"MC\", \"MD\", \"ME\", \"MF\", \"MG\", \"MH\",\n    \"MK\", \"ML\", \"MM\", \"MN\", \"MO\", \"MP\", \"MQ\", \"MR\", \"MS\", \"MT\", \"MU\", \"MV\", \"MW\",\n    \"MX\", \"MY\", \"MZ\", \"NA\", \"NC\", \"NE\", \"NF\", \"NG\", \"NI\", \"NL\", \"NO\", \"NP\", \"NR\",\n    \"NT\", \"NU\", \"NZ\", \"OM\", \"PA\", \"PE\", \"PF\", \"PG\", \"PH\", \"PK\", \"PL\", \"PM\", \"PN\",\n    \"PR\", \"PS\", \"PT\", \"PW\", \"PY\", \"QA\", \"RE\", \"RO\", \"RS\", \"RU\", \"RW\", \"SA\", \"SB\",\n    \"SC\", \"SD\", \"SE\", \"SG\", \"SH\", \"SI\", \"SJ\", \"SK\", \"SL\", \"SM\", \"SN\", \"SO\", \"SR\",\n    \"SS\", \"ST\", \"SU\", \"SV\", \"SX\", \"SY\", \"SZ\", \"TA\", \"TC\", \"TD\", \"TF\", \"TG\", \"TH\",\n    \"TJ\", \"TK\", \"TL\", \"TM\", \"TN\", \"TO\", \"TR\", \"TT\", \"TV\", \"TW\", \"TZ\", \"UA\", \"UG\",\n    \"UM\", \"US\", \"UY\", \"UZ\", \"VA\", \"VC\", \"VE\", \"VG\", \"VI\", \"VN\", \"VU\", \"WF\", \"WS\",\n    \"YE\", \"YT\", \"YU\", \"ZA\", \"ZM\", \"ZR\", \"ZW\"\n  ]\n}\n},{}],12:[function(require,module,exports){\n/**\n *\n * @namespace faker.image\n */\nvar Image = function (faker) {\n\n  var self = this;\n\n  /**\n   * image\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.image\n   */\n  self.image = function (width, height, randomize) {\n    var categories = [\"abstract\", \"animals\", \"business\", \"cats\", \"city\", \"food\", \"nightlife\", \"fashion\", \"people\", \"nature\", \"sports\", \"technics\", \"transport\"];\n    return self[faker.random.arrayElement(categories)](width, height, randomize);\n  };\n  /**\n   * avatar\n   *\n   * @method faker.image.avatar\n   */\n  self.avatar = function () {\n    return faker.internet.avatar();\n  };\n  /**\n   * imageUrl\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {string} category\n   * @param {boolean} randomize\n   * @method faker.image.imageUrl\n   */\n  self.imageUrl = function (width, height, category, randomize, https) {\n      var width = width || 640;\n      var height = height || 480;\n      var protocol = 'http://';\n      if (typeof https !== 'undefined' && https === true) {\n        protocol = 'https://';\n      }\n      var url = protocol + 'lorempixel.com/' + width + '/' + height;\n      if (typeof category !== 'undefined') {\n        url += '/' + category;\n      }\n\n      if (randomize) {\n        url += '?' + faker.random.number()\n      }\n\n      return url;\n  };\n  /**\n   * abstract\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.abstract\n   */\n  self.abstract = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'abstract', randomize);\n  };\n  /**\n   * animals\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.animals\n   */\n  self.animals = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'animals', randomize);\n  };\n  /**\n   * business\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.business\n   */\n  self.business = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'business', randomize);\n  };\n  /**\n   * cats\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.cats\n   */\n  self.cats = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'cats', randomize);\n  };\n  /**\n   * city\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.city\n   */\n  self.city = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'city', randomize);\n  };\n  /**\n   * food\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.food\n   */\n  self.food = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'food', randomize);\n  };\n  /**\n   * nightlife\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.nightlife\n   */\n  self.nightlife = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'nightlife', randomize);\n  };\n  /**\n   * fashion\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.fashion\n   */\n  self.fashion = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'fashion', randomize);\n  };\n  /**\n   * people\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.people\n   */\n  self.people = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'people', randomize);\n  };\n  /**\n   * nature\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.nature\n   */\n  self.nature = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'nature', randomize);\n  };\n  /**\n   * sports\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.sports\n   */\n  self.sports = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'sports', randomize);\n  };\n  /**\n   * technics\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.technics\n   */\n  self.technics = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'technics', randomize);\n  };\n  /**\n   * transport\n   *\n   * @param {number} width\n   * @param {number} height\n   * @param {boolean} randomize\n   * @method faker.image.transport\n   */\n  self.transport = function (width, height, randomize) {\n    return faker.image.imageUrl(width, height, 'transport', randomize);\n  };\n  /**\n   * dataUri\n   *\n   * @param {number} width\n   * @param {number} height\n   * @method faker.image.dataurl\n   */\n  self.dataUri = function (width, height) {\n    var rawPrefix = 'data:image/svg+xml;charset=UTF-8,';\n    var svgString = '<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" baseProfile=\"full\" width=\"' + width + '\" height=\"' + height + '\"> <rect width=\"100%\" height=\"100%\" fill=\"grey\"/>  <text x=\"0\" y=\"20\" font-size=\"20\" text-anchor=\"start\" fill=\"white\">' + width + 'x' + height + '</text> </svg>';\n    return rawPrefix + encodeURIComponent(svgString);\n  };\n}\n\nmodule[\"exports\"] = Image;\n},{}],13:[function(require,module,exports){\n/*\n\n   this index.js file is used for including the faker library as a CommonJS module, instead of a bundle\n\n   you can include the faker library into your existing node.js application by requiring the entire /faker directory\n\n    var faker = require(./faker);\n    var randomName = faker.name.findName();\n\n   you can also simply include the \"faker.js\" file which is the auto-generated bundled version of the faker library\n\n    var faker = require(./customAppPath/faker);\n    var randomName = faker.name.findName();\n\n\n  if you plan on modifying the faker library you should be performing your changes in the /lib/ directory\n\n*/\n\n/**\n *\n * @namespace faker\n */\nfunction Faker (opts) {\n\n  var self = this;\n\n  opts = opts || {};\n\n  // assign options\n  var locales = self.locales || opts.locales || {};\n  var locale = self.locale || opts.locale || \"en\";\n  var localeFallback = self.localeFallback || opts.localeFallback || \"en\";\n\n  self.locales = locales;\n  self.locale = locale;\n  self.localeFallback = localeFallback;\n\n  self.definitions = {};\n\n  function bindAll(obj) {\n      Object.keys(obj).forEach(function(meth) {\n          if (typeof obj[meth] === 'function') {\n              obj[meth] = obj[meth].bind(obj);\n          }\n      });\n      return obj;\n  }\n\n  var Fake = require('./fake');\n  self.fake = new Fake(self).fake;\n\n  var Random = require('./random');\n  self.random = bindAll(new Random(self));\n\n  var Helpers = require('./helpers');\n  self.helpers = new Helpers(self);\n\n  var Name = require('./name');\n  self.name = bindAll(new Name(self));\n\n  var Address = require('./address');\n  self.address = bindAll(new Address(self));\n\n  var Company = require('./company');\n  self.company = bindAll(new Company(self));\n\n  var Finance = require('./finance');\n  self.finance = bindAll(new Finance(self));\n\n  var Image = require('./image');\n  self.image = bindAll(new Image(self));\n\n  var Lorem = require('./lorem');\n  self.lorem = bindAll(new Lorem(self));\n\n  var Hacker = require('./hacker');\n  self.hacker = bindAll(new Hacker(self));\n\n  var Internet = require('./internet');\n  self.internet = bindAll(new Internet(self));\n\n  var Database = require('./database');\n  self.database = bindAll(new Database(self));\n\n  var Phone = require('./phone_number');\n  self.phone = bindAll(new Phone(self));\n\n  var _Date = require('./date');\n  self.date = bindAll(new _Date(self));\n\n  var Commerce = require('./commerce');\n  self.commerce = bindAll(new Commerce(self));\n\n  var System = require('./system');\n  self.system = bindAll(new System(self));\n\n  var _definitions = {\n    \"name\": [\"first_name\", \"last_name\", \"prefix\", \"suffix\", \"title\", \"male_first_name\", \"female_first_name\", \"male_middle_name\", \"female_middle_name\", \"male_last_name\", \"female_last_name\"],\n    \"address\": [\"city_prefix\", \"city_suffix\", \"street_suffix\", \"county\", \"country\", \"country_code\", \"state\", \"state_abbr\", \"street_prefix\", \"postcode\"],\n    \"company\": [\"adjective\", \"noun\", \"descriptor\", \"bs_adjective\", \"bs_noun\", \"bs_verb\", \"suffix\"],\n    \"lorem\": [\"words\"],\n    \"hacker\": [\"abbreviation\", \"adjective\", \"noun\", \"verb\", \"ingverb\"],\n    \"phone_number\": [\"formats\"],\n    \"finance\": [\"account_type\", \"transaction_type\", \"currency\", \"iban\"],\n    \"internet\": [\"avatar_uri\", \"domain_suffix\", \"free_email\", \"example_email\", \"password\"],\n    \"commerce\": [\"color\", \"department\", \"product_name\", \"price\", \"categories\"],\n    \"database\": [\"collation\", \"column\", \"engine\", \"type\"],\n    \"system\": [\"mimeTypes\"],\n    \"date\": [\"month\", \"weekday\"],\n    \"title\": \"\",\n    \"separator\": \"\"\n  };\n\n  // Create a Getter for all definitions.foo.bar properties\n  Object.keys(_definitions).forEach(function(d){\n    if (typeof self.definitions[d] === \"undefined\") {\n      self.definitions[d] = {};\n    }\n\n    if (typeof _definitions[d] === \"string\") {\n        self.definitions[d] = _definitions[d];\n      return;\n    }\n\n    _definitions[d].forEach(function(p){\n      Object.defineProperty(self.definitions[d], p, {\n        get: function () {\n          if (typeof self.locales[self.locale][d] === \"undefined\" || typeof self.locales[self.locale][d][p] === \"undefined\") {\n            // certain localization sets contain less data then others.\n            // in the case of a missing definition, use the default localeFallback to substitute the missing set data\n            // throw new Error('unknown property ' + d + p)\n            return self.locales[localeFallback][d][p];\n          } else {\n            // return localized data\n            return self.locales[self.locale][d][p];\n          }\n        }\n      });\n    });\n  });\n\n};\n\nFaker.prototype.seed = function(value) {\n  var Random = require('./random');\n  this.seedValue = value;\n  this.random = new Random(this, this.seedValue);\n}\nmodule['exports'] = Faker;\n\n},{\"./address\":2,\"./commerce\":3,\"./company\":4,\"./database\":5,\"./date\":6,\"./fake\":7,\"./finance\":8,\"./hacker\":9,\"./helpers\":10,\"./image\":12,\"./internet\":14,\"./lorem\":1042,\"./name\":1043,\"./phone_number\":1044,\"./random\":1045,\"./system\":1046}],14:[function(require,module,exports){\nvar random_ua = require('../vendor/user-agent');\n\n/**\n *\n * @namespace faker.internet\n */\nvar Internet = function (faker) {\n  var self = this;\n  /**\n   * avatar\n   *\n   * @method faker.internet.avatar\n   */\n  self.avatar = function () {\n      return faker.random.arrayElement(faker.definitions.internet.avatar_uri);\n  };\n\n  self.avatar.schema = {\n    \"description\": \"Generates a URL for an avatar.\",\n    \"sampleResults\": [\"https://s3.amazonaws.com/uifaces/faces/twitter/igorgarybaldi/128.jpg\"]\n  };\n\n  /**\n   * email\n   *\n   * @method faker.internet.email\n   * @param {string} firstName\n   * @param {string} lastName\n   * @param {string} provider\n   */\n  self.email = function (firstName, lastName, provider) {\n      provider = provider || faker.random.arrayElement(faker.definitions.internet.free_email);\n      return  faker.helpers.slugify(faker.internet.userName(firstName, lastName)) + \"@\" + provider;\n  };\n\n  self.email.schema = {\n    \"description\": \"Generates a valid email address based on optional input criteria\",\n    \"sampleResults\": [\"foo.bar@gmail.com\"],\n    \"properties\": {\n      \"firstName\": {\n        \"type\": \"string\",\n        \"required\": false,\n        \"description\": \"The first name of the user\"\n      },\n      \"lastName\": {\n        \"type\": \"string\",\n        \"required\": false,\n        \"description\": \"The last name of the user\"\n      },\n      \"provider\": {\n        \"type\": \"string\",\n        \"required\": false,\n        \"description\": \"The domain of the user\"\n      }\n    }\n  };\n  /**\n   * exampleEmail\n   *\n   * @method faker.internet.exampleEmail\n   * @param {string} firstName\n   * @param {string} lastName\n   */\n  self.exampleEmail = function (firstName, lastName) {\n      var provider = faker.random.arrayElement(faker.definitions.internet.example_email);\n      return self.email(firstName, lastName, provider);\n  };\n\n  /**\n   * userName\n   *\n   * @method faker.internet.userName\n   * @param {string} firstName\n   * @param {string} lastName\n   */\n  self.userName = function (firstName, lastName) {\n      var result;\n      firstName = firstName || faker.name.firstName();\n      lastName = lastName || faker.name.lastName();\n      switch (faker.random.number(2)) {\n      case 0:\n          result = firstName + faker.random.number(99);\n          break;\n      case 1:\n          result = firstName + faker.random.arrayElement([\".\", \"_\"]) + lastName;\n          break;\n      case 2:\n          result = firstName + faker.random.arrayElement([\".\", \"_\"]) + lastName + faker.random.number(99);\n          break;\n      }\n      result = result.toString().replace(/'/g, \"\");\n      result = result.replace(/ /g, \"\");\n      return result;\n  };\n\n  self.userName.schema = {\n    \"description\": \"Generates a username based on one of several patterns. The pattern is chosen randomly.\",\n    \"sampleResults\": [\n      \"Kirstin39\",\n      \"Kirstin.Smith\",\n      \"Kirstin.Smith39\",\n      \"KirstinSmith\",\n      \"KirstinSmith39\",\n    ],\n    \"properties\": {\n      \"firstName\": {\n        \"type\": \"string\",\n        \"required\": false,\n        \"description\": \"The first name of the user\"\n      },\n      \"lastName\": {\n        \"type\": \"string\",\n        \"required\": false,\n        \"description\": \"The last name of the user\"\n      }\n    }\n  };\n\n  /**\n   * protocol\n   *\n   * @method faker.internet.protocol\n   */\n  self.protocol = function () {\n      var protocols = ['http','https'];\n      return faker.random.arrayElement(protocols);\n  };\n\n  self.protocol.schema = {\n    \"description\": \"Randomly generates http or https\",\n    \"sampleResults\": [\"https\", \"http\"]\n  };\n\n  /**\n   * url\n   *\n   * @method faker.internet.url\n   */\n  self.url = function () {\n      return faker.internet.protocol() + '://' + faker.internet.domainName();\n  };\n\n  self.url.schema = {\n    \"description\": \"Generates a random URL. The URL could be secure or insecure.\",\n    \"sampleResults\": [\n      \"http://rashawn.name\",\n      \"https://rashawn.name\"\n    ]\n  };\n\n  /**\n   * domainName\n   *\n   * @method faker.internet.domainName\n   */\n  self.domainName = function () {\n      return faker.internet.domainWord() + \".\" + faker.internet.domainSuffix();\n  };\n\n  self.domainName.schema = {\n    \"description\": \"Generates a random domain name.\",\n    \"sampleResults\": [\"marvin.org\"]\n  };\n\n  /**\n   * domainSuffix\n   *\n   * @method faker.internet.domainSuffix\n   */\n  self.domainSuffix = function () {\n      return faker.random.arrayElement(faker.definitions.internet.domain_suffix);\n  };\n\n  self.domainSuffix.schema = {\n    \"description\": \"Generates a random domain suffix.\",\n    \"sampleResults\": [\"net\"]\n  };\n\n  /**\n   * domainWord\n   *\n   * @method faker.internet.domainWord\n   */\n  self.domainWord = function () {\n      return faker.name.firstName().replace(/([\\\\~#&*{}/:<>?|\\\"'])/ig, '').toLowerCase();\n  };\n\n  self.domainWord.schema = {\n    \"description\": \"Generates a random domain word.\",\n    \"sampleResults\": [\"alyce\"]\n  };\n\n  /**\n   * ip\n   *\n   * @method faker.internet.ip\n   */\n  self.ip = function () {\n      var randNum = function () {\n          return (faker.random.number(255)).toFixed(0);\n      };\n\n      var result = [];\n      for (var i = 0; i < 4; i++) {\n          result[i] = randNum();\n      }\n\n      return result.join(\".\");\n  };\n\n  self.ip.schema = {\n    \"description\": \"Generates a random IP.\",\n    \"sampleResults\": [\"97.238.241.11\"]\n  };\n\n  /**\n   * ipv6\n   *\n   * @method faker.internet.ipv6\n   */\n  self.ipv6 = function () {\n      var randHash = function () {\n          var result = \"\";\n          for (var i = 0; i < 4; i++) {\n            result += (faker.random.arrayElement([\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\"]));\n          }\n          return result\n      };\n\n      var result = [];\n      for (var i = 0; i < 8; i++) {\n        result[i] = randHash();\n      }\n      return result.join(\":\");\n  };\n\n  self.ipv6.schema = {\n    \"description\": \"Generates a random IPv6 address.\",\n    \"sampleResults\": [\"2001:0db8:6276:b1a7:5213:22f1:25df:c8a0\"]\n  };\n\n  /**\n   * userAgent\n   *\n   * @method faker.internet.userAgent\n   */\n  self.userAgent = function () {\n    return random_ua.generate();\n  };\n\n  self.userAgent.schema = {\n    \"description\": \"Generates a random user agent.\",\n    \"sampleResults\": [\"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10_7_5 rv:6.0; SL) AppleWebKit/532.0.1 (KHTML, like Gecko) Version/7.1.6 Safari/532.0.1\"]\n  };\n\n  /**\n   * color\n   *\n   * @method faker.internet.color\n   * @param {number} baseRed255\n   * @param {number} baseGreen255\n   * @param {number} baseBlue255\n   */\n  self.color = function (baseRed255, baseGreen255, baseBlue255) {\n      baseRed255 = baseRed255 || 0;\n      baseGreen255 = baseGreen255 || 0;\n      baseBlue255 = baseBlue255 || 0;\n      // based on awesome response : http://stackoverflow.com/questions/43044/algorithm-to-randomly-generate-an-aesthetically-pleasing-color-palette\n      var red = Math.floor((faker.random.number(256) + baseRed255) / 2);\n      var green = Math.floor((faker.random.number(256) + baseGreen255) / 2);\n      var blue = Math.floor((faker.random.number(256) + baseBlue255) / 2);\n      var redStr = red.toString(16);\n      var greenStr = green.toString(16);\n      var blueStr = blue.toString(16);\n      return '#' +\n        (redStr.length === 1 ? '0' : '') + redStr +\n        (greenStr.length === 1 ? '0' : '') + greenStr +\n        (blueStr.length === 1 ? '0': '') + blueStr;\n\n  };\n\n  self.color.schema = {\n    \"description\": \"Generates a random hexadecimal color.\",\n    \"sampleResults\": [\"#06267f\"],\n    \"properties\": {\n      \"baseRed255\": {\n        \"type\": \"number\",\n        \"required\": false,\n        \"description\": \"The red value. Valid values are 0 - 255.\"\n      },\n      \"baseGreen255\": {\n        \"type\": \"number\",\n        \"required\": false,\n        \"description\": \"The green value. Valid values are 0 - 255.\"\n      },\n      \"baseBlue255\": {\n        \"type\": \"number\",\n        \"required\": false,\n        \"description\": \"The blue value. Valid values are 0 - 255.\"\n      }\n    }\n  };\n\n  /**\n   * mac\n   *\n   * @method faker.internet.mac\n   */\n  self.mac = function(){\n      var i, mac = \"\";\n      for (i=0; i < 12; i++) {\n          mac+= faker.random.number(15).toString(16);\n          if (i%2==1 && i != 11) {\n              mac+=\":\";\n          }\n      }\n      return mac;\n  };\n\n  self.mac.schema = {\n    \"description\": \"Generates a random mac address.\",\n    \"sampleResults\": [\"78:06:cc:ae:b3:81\"]\n  };\n\n  /**\n   * password\n   *\n   * @method faker.internet.password\n   * @param {number} len\n   * @param {boolean} memorable\n   * @param {string} pattern\n   * @param {string} prefix\n   */\n   self.password = function (len, memorable, pattern, prefix) {\n     len = len || 15;\n     if (typeof memorable === \"undefined\") {\n       memorable = false;\n     }\n     /*\n      * password-generator ( function )\n      * Copyright(c) 2011-2013 Bermi Ferrer <bermi@bermilabs.com>\n      * MIT Licensed\n      */\n     var consonant, letter, password, vowel;\n     letter = /[a-zA-Z]$/;\n     vowel = /[aeiouAEIOU]$/;\n     consonant = /[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ]$/;\n     var _password = function (length, memorable, pattern, prefix) {\n       var char, n;\n       if (length == null) {\n         length = 10;\n       }\n       if (memorable == null) {\n         memorable = true;\n       }\n       if (pattern == null) {\n         pattern = /\\w/;\n       }\n       if (prefix == null) {\n         prefix = '';\n       }\n       if (prefix.length >= length) {\n         return prefix;\n       }\n       if (memorable) {\n         if (prefix.match(consonant)) {\n           pattern = vowel;\n         } else {\n           pattern = consonant;\n         }\n       }\n       n = faker.random.number(94) + 33;\n       char = String.fromCharCode(n);\n       if (memorable) {\n         char = char.toLowerCase();\n       }\n       if (!char.match(pattern)) {\n         return _password(length, memorable, pattern, prefix);\n       }\n       return _password(length, memorable, pattern, \"\" + prefix + char);\n     };\n     return _password(len, memorable, pattern, prefix);\n   }\n\n  self.password.schema = {\n    \"description\": \"Generates a random password.\",\n    \"sampleResults\": [\n      \"AM7zl6Mg\",\n      \"susejofe\"\n    ],\n    \"properties\": {\n      \"length\": {\n        \"type\": \"number\",\n        \"required\": false,\n        \"description\": \"The number of characters in the password.\"\n      },\n      \"memorable\": {\n        \"type\": \"boolean\",\n        \"required\": false,\n        \"description\": \"Whether a password should be easy to remember.\"\n      },\n      \"pattern\": {\n        \"type\": \"regex\",\n        \"required\": false,\n        \"description\": \"A regex to match each character of the password against. This parameter will be negated if the memorable setting is turned on.\"\n      },\n      \"prefix\": {\n        \"type\": \"string\",\n        \"required\": false,\n        \"description\": \"A value to prepend to the generated password. The prefix counts towards the length of the password.\"\n      }\n    }\n  };\n\n};\n\n\nmodule[\"exports\"] = Internet;\n\n},{\"../vendor/user-agent\":1048}],15:[function(require,module,exports){\nexports['az'] = require('./locales/az');\nexports['cz'] = require('./locales/cz');\nexports['de'] = require('./locales/de');\nexports['de_AT'] = require('./locales/de_AT');\nexports['de_CH'] = require('./locales/de_CH');\nexports['en'] = require('./locales/en');\nexports['en_AU'] = require('./locales/en_AU');\nexports['en_BORK'] = require('./locales/en_BORK');\nexports['en_CA'] = require('./locales/en_CA');\nexports['en_GB'] = require('./locales/en_GB');\nexports['en_IE'] = require('./locales/en_IE');\nexports['en_IND'] = require('./locales/en_IND');\nexports['en_US'] = require('./locales/en_US');\nexports['en_au_ocker'] = require('./locales/en_au_ocker');\nexports['es'] = require('./locales/es');\nexports['es_MX'] = require('./locales/es_MX');\nexports['fa'] = require('./locales/fa');\nexports['fr'] = require('./locales/fr');\nexports['fr_CA'] = require('./locales/fr_CA');\nexports['ge'] = require('./locales/ge');\nexports['id_ID'] = require('./locales/id_ID');\nexports['it'] = require('./locales/it');\nexports['ja'] = require('./locales/ja');\nexports['ko'] = require('./locales/ko');\nexports['nb_NO'] = require('./locales/nb_NO');\nexports['nep'] = require('./locales/nep');\nexports['nl'] = require('./locales/nl');\nexports['pl'] = require('./locales/pl');\nexports['pt_BR'] = require('./locales/pt_BR');\nexports['ru'] = require('./locales/ru');\nexports['sk'] = require('./locales/sk');\nexports['sv'] = require('./locales/sv');\nexports['tr'] = require('./locales/tr');\nexports['uk'] = require('./locales/uk');\nexports['vi'] = require('./locales/vi');\nexports['zh_CN'] = require('./locales/zh_CN');\nexports['zh_TW'] = require('./locales/zh_TW');\n\n},{\"./locales/az\":40,\"./locales/cz\":79,\"./locales/de\":117,\"./locales/de_AT\":150,\"./locales/de_CH\":169,\"./locales/en\":249,\"./locales/en_AU\":281,\"./locales/en_BORK\":289,\"./locales/en_CA\":297,\"./locales/en_GB\":310,\"./locales/en_IE\":320,\"./locales/en_IND\":332,\"./locales/en_US\":344,\"./locales/en_au_ocker\":364,\"./locales/es\":396,\"./locales/es_MX\":440,\"./locales/fa\":459,\"./locales/fr\":485,\"./locales/fr_CA\":505,\"./locales/ge\":531,\"./locales/id_ID\":560,\"./locales/it\":597,\"./locales/ja\":619,\"./locales/ko\":640,\"./locales/nb_NO\":670,\"./locales/nep\":690,\"./locales/nl\":714,\"./locales/pl\":754,\"./locales/pt_BR\":783,\"./locales/ru\":820,\"./locales/sk\":860,\"./locales/sv\":907,\"./locales/tr\":933,\"./locales/uk\":966,\"./locales/vi\":993,\"./locales/zh_CN\":1016,\"./locales/zh_TW\":1035}],16:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###\"\n];\n\n},{}],17:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Address.city_name}\"\n];\n\n},{}],18:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ağcabədi\",\n  \"Ağdam\",\n  \"Ağdaş\",\n  \"Ağdərə\",\n  \"Ağstafa\",\n  \"Ağsu\",\n  \"Astara\",\n  \"Bakı\",\n  \"Balakən\",\n  \"Beyləqan\",\n  \"Bərdə\",\n  \"Biləsuvar\",\n  \"Cəbrayıl\",\n  \"Cəlilabad\",\n  \"Culfa\",\n  \"Daşkəsən\",\n  \"Dəliməmmədli\",\n  \"Füzuli\",\n  \"Gədəbəy\",\n  \"Gəncə\",\n  \"Goranboy\",\n  \"Göyçay\",\n  \"Göygöl\",\n  \"Göytəpə\",\n  \"Hacıqabul\",\n  \"Horadiz\",\n  \"Xaçmaz\",\n  \"Xankəndi\",\n  \"Xocalı\",\n  \"Xocavənd\",\n  \"Xırdalan\",\n  \"Xızı\",\n  \"Xudat\",\n  \"İmişli\",\n  \"İsmayıllı\",\n  \"Kəlbəcər\",\n  \"Kürdəmir\",\n  \"Qax\",\n  \"Qazax\",\n  \"Qəbələ\",\n  \"Qobustan\",\n  \"Qovlar\",\n  \"Quba\",\n  \"Qubadlı\",\n  \"Qusar\",\n  \"Laçın\",\n  \"Lerik\",\n  \"Lənkəran\",\n  \"Liman\",\n  \"Masallı\",\n  \"Mingəçevir\",\n  \"Naftalan\",\n  \"Naxçıvan (şəhər)\",\n  \"Neftçala\",\n  \"Oğuz\",\n  \"Ordubad\",\n  \"Saatlı\",\n  \"Sabirabad\",\n  \"Salyan\",\n  \"Samux\",\n  \"Siyəzən\",\n  \"Sumqayıt\",\n  \"Şabran\",\n  \"Şahbuz\",\n  \"Şamaxı\",\n  \"Şəki\",\n  \"Şəmkir\",\n  \"Şərur\",\n  \"Şirvan\",\n  \"Şuşa\",\n  \"Tərtər\",\n  \"Tovuz\",\n  \"Ucar\",\n  \"Yardımlı\",\n  \"Yevlax\",\n  \"Zaqatala\",\n  \"Zəngilan\",\n  \"Zərdab\"\n];\n\n},{}],19:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Akrotiri və Dekeliya\",\n  \"Aland adaları\",\n  \"Albaniya\",\n  \"Almaniya\",\n  \"Amerika Samoası\",\n  \"Andorra\",\n  \"Angilya\",\n  \"Anqola\",\n  \"Antiqua və Barbuda\",\n  \"Argentina\",\n  \"Aruba\",\n  \"Avstraliya\",\n  \"Avstriya\",\n  \"Azərbaycan\",\n  \"Baham adaları\",\n  \"Banqladeş\",\n  \"Barbados\",\n  \"Belçika\",\n  \"Beliz\",\n  \"Belarus\",\n  \"Benin\",\n  \"Bermud adaları\",\n  \"BƏƏ\",\n  \"ABŞ\",\n  \"Boliviya\",\n  \"Bolqarıstan\",\n  \"Bosniya və Herseqovina\",\n  \"Botsvana\",\n  \"Böyük Britaniya\",\n  \"Braziliya\",\n  \"Bruney\",\n  \"Burkina-Faso\",\n  \"Burundi\",\n  \"Butan\",\n  \"Bəhreyn\",\n  \"Cersi\",\n  \"Cəbəli-Tariq\",\n  \"CAR\",\n  \"Cənubi Sudan\",\n  \"Cənubi Koreya\",\n  \"Cibuti\",\n  \"Çad\",\n  \"Çexiya\",\n  \"Monteneqro\",\n  \"Çili\",\n  \"ÇXR\",\n  \"Danimarka\",\n  \"Dominika\",\n  \"Dominikan Respublikası\",\n  \"Efiopiya\",\n  \"Ekvador\",\n  \"Ekvatorial Qvineya\",\n  \"Eritreya\",\n  \"Ermənistan\",\n  \"Estoniya\",\n  \"Əfqanıstan\",\n  \"Əlcəzair\",\n  \"Farer adaları\",\n  \"Fələstin Dövləti\",\n  \"Fici\",\n  \"Kot-d’İvuar\",\n  \"Filippin\",\n  \"Finlandiya\",\n  \"Folklend adaları\",\n  \"Fransa\",\n  \"Fransa Polineziyası\",\n  \"Gernsi\",\n  \"Gürcüstan\",\n  \"Haiti\",\n  \"Hindistan\",\n  \"Honduras\",\n  \"Honkonq\",\n  \"Xorvatiya\",\n  \"İndoneziya\",\n  \"İordaniya\",\n  \"İraq\",\n  \"İran\",\n  \"İrlandiya\",\n  \"İslandiya\",\n  \"İspaniya\",\n  \"İsrail\",\n  \"İsveç\",\n  \"İsveçrə\",\n  \"İtaliya\",\n  \"Kabo-Verde\",\n  \"Kamboca\",\n  \"Kamerun\",\n  \"Kanada\",\n  \"Kayman adaları\",\n  \"Keniya\",\n  \"Kipr\",\n  \"Kiribati\",\n  \"Kokos adaları\",\n  \"Kolumbiya\",\n  \"Komor adaları\",\n  \"Konqo Respublikası\",\n  \"KDR\",\n  \"Kosovo\",\n  \"Kosta-Rika\",\n  \"Kuba\",\n  \"Kuk adaları\",\n  \"Küveyt\",\n  \"Qabon\",\n  \"Qambiya\",\n  \"Qana\",\n  \"Qətər\",\n  \"Qayana\",\n  \"Qazaxıstan\",\n  \"Qərbi Sahara\",\n  \"Qırğızıstan\",\n  \"Qrenada\",\n  \"Qrenlandiya\",\n  \"Quam\",\n  \"Qvatemala\",\n  \"Qvineya\",\n  \"Qvineya-Bisau\",\n  \"Laos\",\n  \"Latviya\",\n  \"Lesoto\",\n  \"Liberiya\",\n  \"Litva\",\n  \"Livan\",\n  \"Liviya\",\n  \"Lixtenşteyn\",\n  \"Lüksemburq\",\n  \"Macarıstan\",\n  \"Madaqaskar\",\n  \"Makao\",\n  \"Makedoniya\",\n  \"Malavi\",\n  \"Malayziya\",\n  \"Maldiv adaları\",\n  \"Mali\",\n  \"Malta\",\n  \"Marşall adaları\",\n  \"Mavriki\",\n  \"Mavritaniya\",\n  \"Mayotta\",\n  \"Meksika\",\n  \"Men adası\",\n  \"Mərakeş\",\n  \"MAR\",\n  \"Mikroneziya\",\n  \"Milad adası\",\n  \"Misir\",\n  \"Myanma\",\n  \"Moldova\",\n  \"Monako\",\n  \"Monqolustan\",\n  \"Montserrat\",\n  \"Mozambik\",\n  \"Müqəddəs Yelena, Askenson və Tristan-da-Kunya adaları\",\n  \"Namibiya\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Niderland\",\n  \"Niderland Antil adaları\",\n  \"Niger\",\n  \"Nigeriya\",\n  \"Nikaraqua\",\n  \"Niue\",\n  \"Norfolk adası\",\n  \"Norveç\",\n  \"Oman\",\n  \"Özbəkistan\",\n  \"Pakistan\",\n  \"Palau\",\n  \"Panama\",\n  \"Papua-Yeni Qvineya\",\n  \"Paraqvay\",\n  \"Peru\",\n  \"Pitkern adaları\",\n  \"Polşa\",\n  \"Portuqaliya\",\n  \"Prednestroviya\",\n  \"Puerto-Riko\",\n  \"Ruanda\",\n  \"Rumıniya\",\n  \"Rusiya\",\n  \"Salvador\",\n  \"Samoa\",\n  \"San-Marino\",\n  \"San-Tome və Prinsipi\",\n  \"Seneqal\",\n  \"Sen-Bartelemi\",\n  \"Sent-Kits və Nevis\",\n  \"Sent-Lüsiya\",\n  \"Sen-Marten\",\n  \"Sen-Pyer və Mikelon\",\n  \"Sent-Vinsent və Qrenadina\",\n  \"Serbiya\",\n  \"Seyşel adaları\",\n  \"Səudiyyə Ərəbistanı\",\n  \"Sinqapur\",\n  \"Slovakiya\",\n  \"Sloveniya\",\n  \"Solomon adaları\",\n  \"Somali\",\n  \"Somalilend\",\n  \"Sudan\",\n  \"Surinam\",\n  \"Suriya\",\n  \"Svazilend\",\n  \"Syerra-Leone\",\n  \"Şərqi Timor\",\n  \"Şimali Marian adaları\",\n  \"Şpisbergen və Yan-Mayen\",\n  \"Şri-Lanka\",\n  \"Tacikistan\",\n  \"Tanzaniya\",\n  \"Tailand\",\n  \"Çin Respublikası\",\n  \"Törks və Kaykos adaları\",\n  \"Tokelau\",\n  \"Tonqa\",\n  \"Toqo\",\n  \"Trinidad və Tobaqo\",\n  \"Tunis\",\n  \"Tuvalu\",\n  \"Türkiyə\",\n  \"Türkmənistan\",\n  \"Ukrayna\",\n  \"Uollis və Futuna\",\n  \"Uqanda\",\n  \"Uruqvay\",\n  \"Vanuatu\",\n  \"Vatikan\",\n  \"Venesuela\",\n  \"Amerika Virgin adaları\",\n  \"Britaniya Virgin adaları\",\n  \"Vyetnam\",\n  \"Yamayka\",\n  \"Yaponiya\",\n  \"Yeni Kaledoniya\",\n  \"Yeni Zelandiya\",\n  \"Yəmən\",\n  \"Yunanıstan\",\n  \"Zambiya\",\n  \"Zimbabve\"\n];\n\n},{}],20:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Azərbaycan\"\n];\n\n},{}],21:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.street_title = require(\"./street_title\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":16,\"./city\":17,\"./city_name\":18,\"./country\":19,\"./default_country\":20,\"./postcode\":22,\"./secondary_address\":23,\"./state\":24,\"./street_address\":25,\"./street_name\":26,\"./street_suffix\":27,\"./street_title\":28}],22:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AZ####\"\n];\n\n},{}],23:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"m. ###\"\n];\n\n},{}],24:[function(require,module,exports){\nmodule[\"exports\"] = [\n\n];\n\n},{}],25:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_name}, #{building_number}\"\n];\n\n},{}],26:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_suffix} #{Address.street_title}\",\n  \"#{Address.street_title} #{street_suffix}\"\n];\n\n},{}],27:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"küç.\",\n  \"küçəsi\",\n  \"prospekti\",\n  \"pr.\",\n  \"sahəsi\",\n  \"sh.\"\n];\n\n},{}],28:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abbas Fətullayev\",\n  \"Abbas Mirzə Şərifzadə\",\n  \"Abbas Səhhət\",\n  \"Abdulla Şaiq\",\n  \"Afiyəddin Cəlilov\",\n  \"Axundov\",\n  \"Ağa Nemətulla\",\n  \"Ağadadaş Qurbanov\",\n  \"Akademik Həsən Əliyev\",\n  \"Akademik Lətif İmanov\",\n  \"Alı Mustafayev\",\n  \"Almas İldırım\",\n  \"Asəf Zeynallı\",\n  \"Asif Əsədullayev\",\n  \"Aşıq Alı\",\n  \"Aşıq Ələsgər\",\n  \"Azadlıq prospekti\",\n  \"Bakıxanov\",\n  \"Balababa Məcidov\",\n  \"Balaəmi Dadaşov\",\n  \"Behbud Şaxtantinski\",\n  \"Bəkir Çobanzadə\",\n  \"Bəsti Bağırova\",\n  \"Bəşir Səfəroğlu\",\n  \"Böyük Qala\",\n  \"Cabir Əliyev\",\n  \"Camal Hacıəliyev\",\n  \"Cavadxan\",\n  \"Cavanşir\",\n  \"Ceyhun Səlimov\",\n  \"Ceyhunbəy Hacıbəyli\",\n  \"Cəbiyev\",\n  \"Cəfər Xəndan\",\n  \"Cəfər Cabbarlı\",\n  \"Cəlal Qurbanov\",\n  \"Cəlil Məmmədquluzadə\",\n  \"Çingiz Mustafayev\",\n  \"Çobanzadə\",\n  \"Dadaş Bünyadzadə\",\n  \"Dağlı Yunus\",\n  \"Dilarə Əliyeva\",\n  \"Elçin Əzimov\",\n  \"Eldar və Abdulla Əlibəyovlar\",\n  \"Elxan Həsənov\",\n  \"Elşən Mehdiyev\",\n  \"Elşən Süleymanov\",\n  \"Etibar Bəkirov\",\n  \"Əbdüləzəl Dəmirçizadə\",\n  \"Əbdülhəsən Anaplı\",\n  \"Əbdülkərim Əlizadə\",\n  \"Əhməd bəy Ağaoğlu\",\n  \"Əhməd Cavad\",\n  \"Əhməd Cəmil\",\n  \"Əhməd Mehbalıyev\",\n  \"Əhməd Rəcəbli\",\n  \"Əjdər Xanbabayev\",\n  \"Əkrəm Cəfərov\",\n  \"Ələsgər Qayıbov\",\n  \"Əliağa Vahid\",\n  \"Əli Bəy Hüseynzadə\",\n  \"Əlimərdan bəy Topçubaşov\",\n  \"Əliyar Əliyev\",\n  \"Əlövsət Abdulrəhimov\",\n  \"Əlövsət Quliyev\",\n  \"Əmir Bağırov\",\n  \"Əsəd Əhmədov\",\n  \"Əşrəf Yunusov\",\n  \"Əzim Əzimzadə\",\n  \"Əziz Əliyev\",\n  \"Heybət Heybətov\",\n  \"Həqiqət Rzayeva\",\n  \"Həmid Araslı\",\n  \"Hənifə Ələsgərova\",\n  \"Hərbçilər\",\n  \"Həsənoğu\",\n  \"Həsən Seyidbəyli\",\n  \"Hətəm Allahverdiyev\",\n  \"Həzi Aslanov\",\n  \"Hüsü Hacıyev\",\n  \"Hüseynqulu Sarabski\",\n  \"Fətəli xan Xoyski\",\n  \"Fəzail Bayramov\",\n  \"Fikrət Əmirov\",\n  \"Fuad İbrahimbəyov\",\n  \"Fuad Yusifov\",\n  \"General Əliağa Şıxlinski\",\n  \"Gülayə Qədirbəyova\",\n  \"Gənclik\",\n  \"Xaqani\",\n  \"Xan Şuşinski\",\n  \"Xanlar\",\n  \"Xudu Məmmədov\",\n  \"İbrahimpaşa Dadaşov\",\n  \"İdris Süleymanov\",\n  \"İlqar Abbasov\",\n  \"İlqar İsmayılov\",\n  \"İmran Qasımov\",\n  \"İnqilab İsmayılov\",\n  \"İsfəndiyar Zülalov\",\n  \"İslam Abışov\",\n  \"İslam Səfərli\",\n  \"İsmayıl bəy Qutqaşınlı\",\n  \"İsmayıl Mirzəgülov\",\n  \"İstiqlaliyyət\",\n  \"28 May\",\n  \"İsgəndərov\",\n  \"İvan Turgenev\",\n  \"İzmir\",\n  \"İzzət Həmidov\",\n  \"İzzət Orucova\",\n  \"Kamal Rəhimov\",\n  \"Kazım Kazımzadə\",\n  \"Kazımağa Kərimov\",\n  \"Kərəm İsmayılov\",\n  \"Kiçik Qala\",\n  \"Koroğlu Rəhimov\",\n  \"Qaçaq Nəbi\",\n  \"Qarabağ\",\n  \"Qədirbəyov\",\n  \"Qəzənfər Musabəyov\",\n  \"Qəzənfər Vəliyev\",\n  \"Leyla Məmmədbəyova\",\n  \"Mahmud İbrahimov\",\n  \"Malik Məmmədov\",\n  \"Mehdi Abbasov\",\n  \"Mehdi Mehdizadə\",\n  \"Məhəmməd Əmin Rəsulzadə\",\n  \"Məhəmməd Hadi\",\n  \"Məhəmməd Xiyabani\",\n  \"Məhəmməd ibn Hinduşah Naxçıvani\",\n  \"Məhsəti Gəncəvi\",\n  \"Məmmədyarov\",\n  \"Mərdanov qardaşları\",\n  \"Mətləb Ağayev\",\n  \"Məşədi Hilal\",\n  \"Məzahir Rüstəmov\",\n  \"Mikayıl Müşviq\",\n  \"Mingəçevir\",\n  \"Mirəli Qaşqay\",\n  \"Mirəli Seyidov\",\n  \"Mirzağa Əliyev\",\n  \"Mirzə İbrahimov\",\n  \"Mirzə Mənsur\",\n  \"Mirzə Mustafayev\",\n  \"Murtuza Muxtarov\",\n  \"Mustafa Topçubaşov\",\n  \"Müqtədir Aydınbəyov\",\n  \"Müslüm Maqomayev\",\n  \"Müzəffər Həsənov\",\n  \"Nabat Aşurbəyova\",\n  \"Naxçıvani\",\n  \"Naximov\",\n  \"Nazim İsmaylov\",\n  \"Neapol\",\n  \"Neftçi Qurban Abbasov\",\n  \"Neftçilər prospekti\",\n  \"Nəcəfbəy Vəzirov\",\n  \"Nəcəfqulu Rəfiyev\",\n  \"Nəriman Nərimanov\",\n  \"Nəsirəddin Tusi\",\n  \"Nigar Rəfibəyli\",\n  \"Niyazi\",\n  \"Nizami\",\n  \"Nizami Abdullayev\",\n  \"Nobel prospekti\",\n  \"Novruz\",\n  \"Novruzov qardaşları\",\n  \"Oqtay Vəliyev\",\n  \"Parlament\",\n  \"Puşkin\",\n  \"Rafiq Ağayev\",\n  \"Ramiz Qəmbərov\",\n  \"Rəşid Behbudov\",\n  \"Rəşid Məcidov\",\n  \"Ruhulla Axundov\",\n  \"Ruslan Allahverdiyev\",\n  \"Rüstəm Rüstəmov\",\n  \"Tahir Bağırov\",\n  \"Tarzan Hacı Məmmədov\",\n  \"Tbilisi prospekti\",\n  \"Təbriz (Bakı)\",\n  \"Təbriz Xəlilbəyli\",\n  \"Tofiq Məmmədov\",\n  \"Tolstoy\",\n  \"Sabit Orucov\",\n  \"Sabit Rəhman\",\n  \"Sahib Hümmətov\",\n  \"Salatın Əsgərova\",\n  \"Sarayevo\",\n  \"Seyid Əzim Şirvani\",\n  \"Seyid Şuşinski\",\n  \"Seyidov\",\n  \"Səməd bəy Mehmandarov\",\n  \"Səməd Vurğun\",\n  \"Səttar Bəhlulzadə\",\n  \"Sona xanım Vəlixanlı\",\n  \"Sübhi Salayev\",\n  \"Süleyman Əhmədov\",\n  \"Süleyman Rəhimov\",\n  \"Süleyman Rüstəm\",\n  \"Süleyman Sani Axundov\",\n  \"Süleyman Vəzirov\",\n  \"Şahin Səmədov\",\n  \"Şamil Əzizbəyov\",\n  \"Şamil Kamilov\",\n  \"Şeyx Şamil\",\n  \"Şəfayət Mehdiyev\",\n  \"Şəmsi Bədəlbəyli\",\n  \"Şirin Mirzəyev\",\n  \"Şıxəli Qurbanov\",\n  \"Şövkət Ələkbərova\",\n  \"Ülvi Bünyadzadə\",\n  \"Üzeyir Hacıbəyov\",\n  \"Vasif Əliyev\",\n  \"Vəli Məmmədov\",\n  \"Vladislav Plotnikov\",\n  \"Vüqar Quliyev\",\n  \"Vunq Tau\",\n  \"Yaqub Əliyev\",\n  \"Yaşar Abdullayev\",\n  \"Yaşar Əliyev\",\n  \"Yavər Əliyev\",\n  \"Yesenin\",\n  \"Yəhya Hüseynov\",\n  \"Yılmaz Axundzadə\",\n  \"Yüsif Eyvazov\",\n  \"Yusif Qasımov\",\n  \"Yusif Məmmədəliyev\",\n  \"Yusif Səfərov\",\n  \"Yusif Vəzir Çəmənzəminli\",\n  \"Zahid Əliyev\",\n  \"Zahid Xəlilov\",\n  \"Zaur Kərimov\",\n  \"Zavod\",\n  \"Zərgərpalan\"\n];\n\n},{}],29:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ala\",\n  \"açıq bənövşəyi\",\n  \"ağ\",\n  \"mavi\",\n  \"boz\",\n  \"bənövşəyi\",\n  \"göy rəng\",\n  \"gümüşü\",\n  \"kardinal\",\n  \"narıncı\",\n  \"qara\",\n  \"qırmızı\",\n  \"qəhvəyi\",\n  \"tünd göy\",\n  \"tünd qırmızı\",\n  \"xlorofil\",\n  \"yaşıl\",\n  \"çəhrayı\"\n];\n\n},{}],30:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Kitablar\",\n  \"Filmlər\",\n  \"musiqi\",\n  \"oyunlar\",\n  \"Elektronika\",\n  \"Kompyuterlər\",\n  \"Ev\",\n  \"садинструмент\",\n  \"Səhiyyə\",\n  \"gözəllik\",\n  \"Oyuncaqlar\",\n  \"uşaq üçün\",\n  \"Geyim\",\n  \"Ayyaqqabı\",\n  \"bəzək\",\n  \"İdman\",\n  \"turizm\",\n  \"Avtomobil\",\n];\n\n},{}],31:[function(require,module,exports){\nvar commerce = {};\nmodule['exports'] = commerce;\ncommerce.color = require(\"./color\");\ncommerce.department = require(\"./department\");\ncommerce.product_name = require(\"./product_name\");\n\n},{\"./color\":29,\"./department\":30,\"./product_name\":32}],32:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"adjective\": [\n    \"Balaca\",\n    \"Ergonomik\",\n    \"Kobud\",\n    \"İntellektual\",\n    \"Möhtəşəm\",\n    \"İnanılmaz\",\n    \"Fantastik\",\n    \"Əlverişli\",\n    \"Parlaq\",\n    \"Mükəmməl\"\n  ],\n  \"material\": [\n    \"Polad\",\n    \"Ağac\",\n    \"Beton\",\n    \"Plastik\",\n    \"Pambıq\",\n    \"Qranit\",\n    \"Rezin\"\n  ],\n  \"product\": [\n    \"Stul\",\n    \"Avtomobil\",\n    \"Kompyuter\",\n    \"Beret\",\n    \"Kulon\",\n    \"Stol\",\n    \"Sviter\",\n    \"Kəmər\",\n  ]\n};\n\n},{}],33:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.prefix = require(\"./prefix\");\ncompany.suffix = require(\"./suffix\");\ncompany.name = require(\"./name\");\n\n},{\"./name\":34,\"./prefix\":35,\"./suffix\":36}],34:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{Name.female_first_name}\",\n  \"#{prefix} #{Name.male_first_name}\",\n  \"#{prefix} #{Name.male_last_name}\",\n  \"#{prefix} #{suffix}#{suffix}\",\n  \"#{prefix} #{suffix}#{suffix}#{suffix}\",\n  \"#{prefix} #{Address.city_name}#{suffix}\",\n  \"#{prefix} #{Address.city_name}#{suffix}#{suffix}\",\n  \"#{prefix} #{Address.city_name}#{suffix}#{suffix}#{suffix}\"\n];\n\n},{}],35:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ASC\",\n  \"MMC\",\n  \"QSC\",\n];\n\n},{}],36:[function(require,module,exports){\nmodule.exports=require(24)\n},{\"/Users/a/dev/faker.js/lib/locales/az/address/state.js\":24}],37:[function(require,module,exports){\nvar date = {};\nmodule[\"exports\"] = date;\ndate.month = require(\"./month\");\ndate.weekday = require(\"./weekday\");\n\n},{\"./month\":38,\"./weekday\":39}],38:[function(require,module,exports){\n// source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/ru.xml#L1734\nmodule[\"exports\"] = {\n  wide: [\n    \"yanvar\",\n    \"fevral\",\n    \"mart\",\n    \"aprel\",\n    \"may\",\n    \"iyun\",\n    \"iyul\",\n    \"avqust\",\n    \"sentyabr\",\n    \"oktyabr\",\n    \"noyabr\",\n    \"dekabr\"\n  ],\n  wide_context: [\n    \"января\",\n    \"февраля\",\n    \"марта\",\n    \"апреля\",\n    \"мая\",\n    \"июня\",\n    \"июля\",\n    \"августа\",\n    \"сентября\",\n    \"октября\",\n    \"ноября\",\n    \"декабря\"\n  ],\n  abbr: [\n    \"янв.\",\n    \"февр.\",\n    \"март\",\n    \"апр.\",\n    \"май\",\n    \"июнь\",\n    \"июль\",\n    \"авг.\",\n    \"сент.\",\n    \"окт.\",\n    \"нояб.\",\n    \"дек.\"\n  ],\n  abbr_context: [\n    \"янв.\",\n    \"февр.\",\n    \"марта\",\n    \"апр.\",\n    \"мая\",\n    \"июня\",\n    \"июля\",\n    \"авг.\",\n    \"сент.\",\n    \"окт.\",\n    \"нояб.\",\n    \"дек.\"\n  ]\n};\n\n},{}],39:[function(require,module,exports){\n// source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/ru.xml#L1825\nmodule[\"exports\"] = {\n  wide: [\n    \"Bazar\",\n    \"Bazar ertəsi\",\n    \"Çərşənbə axşamı\",\n    \"Çərşənbə\",\n    \"Cümə axşamı\",\n    \"Cümə\",\n    \"Şənbə\"\n  ],\n  wide_context: [\n    \"воскресенье\",\n    \"понедельник\",\n    \"вторник\",\n    \"среда\",\n    \"четверг\",\n    \"пятница\",\n    \"суббота\"\n  ],\n  abbr: [\n    \"Ba\",\n    \"BE\",\n    \"ÇA\",\n    \"Çə\",\n    \"CA\",\n    \"Cü\",\n    \"Şə\"\n  ],\n  abbr_context: [\n    \"вс\",\n    \"пн\",\n    \"вт\",\n    \"ср\",\n    \"чт\",\n    \"пт\",\n    \"сб\"\n  ]\n};\n\n},{}],40:[function(require,module,exports){\nvar az = {};\nmodule['exports'] = az;\naz.title = \"Azerbaijani\";\naz.separator = \" və \";\naz.address = require(\"./address\");\naz.internet = require(\"./internet\");\naz.name = require(\"./name\");\naz.phone_number = require(\"./phone_number\");\naz.commerce = require(\"./commerce\");\naz.company = require(\"./company\");\naz.date = require(\"./date\");\n\n},{\"./address\":21,\"./commerce\":31,\"./company\":33,\"./date\":37,\"./internet\":43,\"./name\":46,\"./phone_number\":53}],41:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"az\",\n  \"com.az\",\n  \"info\",\n  \"net\",\n  \"org\"\n];\n\n},{}],42:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"box.az\",\n  \"mail.az\",\n  \"gmail.com\",\n  \"yahoo.com\",\n  \"hotmail.com\"\n];\n\n},{}],43:[function(require,module,exports){\nvar internet = {};\nmodule['exports'] = internet;\ninternet.free_email = require(\"./free_email\");\ninternet.domain_suffix = require(\"./domain_suffix\");\n\n},{\"./domain_suffix\":41,\"./free_email\":42}],44:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Anna\",\n  \"Adeliya\",\n  \"Afaq\",\n  \"Afət\",\n  \"Afərim\",\n  \"Aidə\",\n  \"Aygün\",\n  \"Aynur\",\n  \"Alsu\",\n  \"Ayan\",\n  \"Aytən\",\n  \"Aygül\",\n  \"Aydan\",\n  \"Aylin\",\n  \"Bahar\",\n  \"Banu\",\n  \"Bəyaz\",\n  \"Billurə\",\n  \"Cansu\",\n  \"Ceyla\",\n  \"Damla\",\n  \"Dəniz\",\n  \"Diana\",\n  \"Dilarə\",\n  \"Ella\",\n  \"Elza\",\n  \"Elyanora\",\n  \"Ellada\",\n  \"Elvira\",\n  \"Elnarə\",\n  \"Esmira\",\n  \"Estella\",\n  \"Fatimə\",\n  \"Fəxriyyə\",\n  \"Fərəh\",\n  \"Fərqanə\",\n  \"Fidan\",\n  \"Firuzə\",\n  \"Gövhər\",\n  \"Günay\",\n  \"Gülay\",\n  \"Gülçin\",\n  \"Gülər\",\n  \"Gülsüm\",\n  \"Humay\",\n  \"Hüriyə\",\n  \"Hülya\",\n  \"Jalə\",\n  \"Jasmin\",\n  \"Kübra\",\n  \"Ləman\",\n  \"Lamiyə\",\n  \"Lalə\",\n  \"Liliya\",\n  \"Laura\",\n  \"Leyla\",\n  \"Maya\",\n  \"Mehriban\",\n  \"Mələk\",\n  \"Nuray\",\n  \"Nurgün\",\n  \"Nərgiz\",\n  \"Nigar\",\n  \"Ofelya\",\n  \"Pəri\",\n  \"Röya\",\n  \"Səbinə\",\n  \"Selcan\",\n  \"Tansu\",\n  \"Tuba\",\n  \"Ülviyyə\",\n  \"Ulduz\",\n  \"Ülkər\"\n];\n\n},{}],45:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Qasımova\",\n  \"Əfəndiyeva\",\n  \"Soltanova\",\n  \"Abdullayeva\",\n  \"Rəşidova\",\n  \"Ələkbərova\",\n  \"Əliyeva\",\n  \"Tahirova\",\n  \"Seyidova\",\n  \"Vəsiyeva\"\n];\n\n},{}],46:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.male_first_name = require(\"./male_first_name\");\nname.male_last_name = require(\"./male_last_name\");\nname.female_first_name = require(\"./female_first_name\");\nname.female_last_name = require(\"./female_last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\nname.name = require(\"./name\");\n\n},{\"./female_first_name\":44,\"./female_last_name\":45,\"./male_first_name\":47,\"./male_last_name\":48,\"./name\":49,\"./prefix\":50,\"./suffix\":51}],47:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Anar\",\n  \"Amid\",\n  \"Afəl\",\n  \"Abbas\",\n  \"Abdulla\",\n  \"Adil\",\n  \"Akif\",\n  \"Aqil\",\n  \"Bəhram\",\n  \"Nurlan\",\n  \"Rafiq\",\n  \"Tərlan\",\n  \"Zaur\",\n  \"Emin\",\n  \"Emil\",\n  \"Kamran\",\n  \"Elnur\",\n  \"Natiq\",\n  \"Rəşad\",\n  \"Rəşid\",\n  \"Tahir\",\n  \"Əhməd\",\n  \"Zahir\",\n  \"İlham\",\n  \"İlqar\",\n  \"Nahid\",\n  \"Nihad\",\n  \"Faiq\",\n  \"İxtiyar\",\n  \"Şəhriyar\",\n  \"Şaiq\",\n  \"Bəxtiyar\",\n  \"Bəhruz\",\n  \"Tunar\",\n  \"Nadir\"\n];\n\n},{}],48:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Əhmədov\",\n  \"Ələkbərov\",\n  \"Əliyev\",\n  \"Vəliyev\",\n  \"Soltanov\",\n  \"Quliyev\",\n  \"Məmmədov\",\n  \"Xəlilov\",\n  \"Nəzərov\",\n  \"Rəhimov\"\n];\n\n},{}],49:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{male_first_name}\",\n  \"#{male_last_name} #{male_first_name}\",\n  \"#{male_first_name} #{male_last_name}\",\n  \"#{female_first_name}\",\n  \"#{female_first_name} #{female_last_name}\",\n  \"#{female_last_name} #{female_first_name}\",\n];\n\n},{}],50:[function(require,module,exports){\nmodule[\"exports\"] = [];\n\n},{}],51:[function(require,module,exports){\nmodule.exports=require(50)\n},{\"/Users/a/dev/faker.js/lib/locales/az/name/prefix.js\":50}],52:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"(9##)###-##-##\"\n];\n\n},{}],53:[function(require,module,exports){\nvar phone_number = {};\nmodule['exports'] = phone_number;\nphone_number.formats = require(\"./formats\");\n\n},{\"./formats\":52}],54:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#\",\n  \"##\",\n  \"###\"\n];\n\n},{}],55:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_name}\"\n];\n\n},{}],56:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abertamy\",\n  \"Adamov\",\n  \"Andělská Hora\",\n  \"Aš\",\n  \"Bakov nad Jizerou\",\n  \"Bavorov\",\n  \"Bechyně\",\n  \"Bečov nad Teplou\",\n  \"Bělá nad Radbuzou\",\n  \"Bělá pod Bezdězem\",\n  \"Benátky nad Jizerou\",\n  \"Benešov\",\n  \"Benešov nad Ploučnicí\",\n  \"Beroun\",\n  \"Bezdružice\",\n  \"Bílina\",\n  \"Bílovec\",\n  \"Blansko\",\n  \"Blatná\",\n  \"Blovice\",\n  \"Blšany\",\n  \"Bochov\",\n  \"Bohumín\",\n  \"Bohušovice nad Ohří\",\n  \"Bojkovice\",\n  \"Bor\",\n  \"Borohrádek\",\n  \"Borovany\",\n  \"Boskovice\",\n  \"Boží Dar\",\n  \"Brandýs nad Labem-Stará Boleslav\",\n  \"Brandýs nad Orlicí\",\n  \"Brno\",\n  \"Broumov\",\n  \"Brtnice\",\n  \"Brumov-Bylnice\",\n  \"Bruntál\",\n  \"Brušperk\",\n  \"Břeclav\",\n  \"Březnice\",\n  \"Březová\",\n  \"Březová nad Svitavou\",\n  \"Břidličná\",\n  \"Bučovice\",\n  \"Budišov nad Budišovkou\",\n  \"Budyně nad Ohří\",\n  \"Buštěhrad\",\n  \"Bystré\",\n  \"Bystřice\",\n  \"Bystřice nad Pernštejnem\",\n  \"Bystřice pod Hostýnem\",\n  \"Bzenec\",\n  \"Chabařovice\",\n  \"Cheb\",\n  \"Chlumec\",\n  \"Chlumec nad Cidlinou\",\n  \"Choceň\",\n  \"Chodov\",\n  \"Chomutov\",\n  \"Chotěboř\",\n  \"Chrast\",\n  \"Chrastava\",\n  \"Chropyně\",\n  \"Chrudim\",\n  \"Chřibská\",\n  \"Chvaletice\",\n  \"Chýnov\",\n  \"Chyše\",\n  \"Cvikov\",\n  \"Čáslav\",\n  \"Čelákovice\",\n  \"Černošice\",\n  \"Černošín\",\n  \"Černovice\",\n  \"Červená Řečice\",\n  \"Červený Kostelec\",\n  \"Česká Kamenice\",\n  \"Česká Lípa\",\n  \"Česká Skalice\",\n  \"Česká Třebová\",\n  \"České Budějovice\",\n  \"České Velenice\",\n  \"Český Brod\",\n  \"Český Dub\",\n  \"Český Krumlov\",\n  \"Český Těšín\",\n  \"Dačice\",\n  \"Dašice\",\n  \"Děčín\",\n  \"Desná\",\n  \"Deštná\",\n  \"Dobrovice\",\n  \"Dobruška\",\n  \"Dobřany\",\n  \"Dobřichovice\",\n  \"Dobříš\",\n  \"Doksy\",\n  \"Dolní Benešov\",\n  \"Dolní Bousov\",\n  \"Dolní Kounice\",\n  \"Dolní Poustevna\",\n  \"Domažlice\",\n  \"Dubá\",\n  \"Dubí\",\n  \"Dubňany\",\n  \"Duchcov\",\n  \"Dvůr Králové nad Labem\",\n  \"Františkovy Lázně\",\n  \"Frenštát pod Radhoštěm\",\n  \"Frýdek-Místek\",\n  \"Frýdlant\",\n  \"Frýdlant nad Ostravicí\",\n  \"Fryšták\",\n  \"Fulnek\",\n  \"Golčův Jeníkov\",\n  \"Habartov\",\n  \"Habry\",\n  \"Hanušovice\",\n  \"Harrachov\",\n  \"Hartmanice\",\n  \"Havířov\",\n  \"Havlíčkův Brod\",\n  \"Hejnice\",\n  \"Heřmanův Městec\",\n  \"Hlinsko\",\n  \"Hluboká nad Vltavou\",\n  \"Hlučín\",\n  \"Hluk\",\n  \"Hodkovice nad Mohelkou\",\n  \"Hodonín\",\n  \"Holešov\",\n  \"Holice\",\n  \"Holýšov\",\n  \"Hora Svaté Kateřiny\",\n  \"Horažďovice\",\n  \"Horní Benešov\",\n  \"Horní Blatná\",\n  \"Horní Bříza\",\n  \"Horní Cerekev\",\n  \"Horní Jelení\",\n  \"Horní Jiřetín\",\n  \"Horní Planá\",\n  \"Horní Slavkov\",\n  \"Horšovský Týn\",\n  \"Hořice\",\n  \"Hořovice\",\n  \"Hostinné\",\n  \"Hostivice\",\n  \"Hostomice\",\n  \"Hostouň\",\n  \"Hoštka\",\n  \"Hradec Králové\",\n  \"Hradec nad Moravicí\",\n  \"Hrádek\",\n  \"Hrádek nad Nisou\",\n  \"Hranice (okres Cheb)\",\n  \"Hranice (okres Přerov)\",\n  \"Hrob\",\n  \"Hrochův Týnec\",\n  \"Hronov\",\n  \"Hrotovice\",\n  \"Hroznětín\",\n  \"Hrušovany nad Jevišovkou\",\n  \"Hulín\",\n  \"Humpolec\",\n  \"Husinec\",\n  \"Hustopeče\",\n  \"Ivančice\",\n  \"Ivanovice na Hané\",\n  \"Jablonec nad Jizerou\",\n  \"Jablonec nad Nisou\",\n  \"Jablonné nad Orlicí\",\n  \"Jablonné v Podještědí\",\n  \"Jablunkov\",\n  \"Jáchymov\",\n  \"Janov\",\n  \"Janovice nad Úhlavou\",\n  \"Janské Lázně\",\n  \"Jaroměř\",\n  \"Jaroměřice nad Rokytnou\",\n  \"Javorník\",\n  \"Jemnice\",\n  \"Jesenice (okres Rakovník)\",\n  \"Jeseník\",\n  \"Jevíčko\",\n  \"Jevišovice\",\n  \"Jičín\",\n  \"Jihlava\",\n  \"Jilemnice\",\n  \"Jílové\",\n  \"Jílové u Prahy\",\n  \"Jindřichův Hradec\",\n  \"Jirkov\",\n  \"Jiříkov\",\n  \"Jistebnice\",\n  \"Kadaň\",\n  \"Kamenice nad Lipou\",\n  \"Kamenický Šenov\",\n  \"Kaplice\",\n  \"Kardašova Řečice\",\n  \"Karlovy Vary\",\n  \"Karolinka\",\n  \"Karviná\",\n  \"Kasejovice\",\n  \"Kašperské Hory\",\n  \"Kaznějov\",\n  \"Kdyně\",\n  \"Kelč\",\n  \"Kladno\",\n  \"Kladruby\",\n  \"Klášterec nad Ohří\",\n  \"Klatovy\",\n  \"Klecany\",\n  \"Klimkovice\",\n  \"Klobouky u Brna\",\n  \"Kojetín\",\n  \"Kolín\",\n  \"Konice\",\n  \"Kopidlno\",\n  \"Kopřivnice\",\n  \"Koryčany\",\n  \"Kosmonosy\",\n  \"Kostelec na Hané\",\n  \"Kostelec nad Černými lesy\",\n  \"Kostelec nad Labem\",\n  \"Kostelec nad Orlicí\",\n  \"Košťany\",\n  \"Kouřim\",\n  \"Kožlany\",\n  \"Králíky\",\n  \"Kralovice\",\n  \"Kralupy nad Vltavou\",\n  \"Králův Dvůr\",\n  \"Kraslice\",\n  \"Krásná Hora nad Vltavou\",\n  \"Krásná Lípa\",\n  \"Krásné Údolí\",\n  \"Krásno\",\n  \"Kravaře\",\n  \"Krnov\",\n  \"Kroměříž\",\n  \"Krupka\",\n  \"Kryry\",\n  \"Kunovice\",\n  \"Kunštát\",\n  \"Kuřim\",\n  \"Kutná Hora\",\n  \"Kyjov\",\n  \"Kynšperk nad Ohří\",\n  \"Lanškroun\",\n  \"Lanžhot\",\n  \"Lázně Bělohrad\",\n  \"Lázně Bohdaneč\",\n  \"Lázně Kynžvart\",\n  \"Ledeč nad Sázavou\",\n  \"Ledvice\",\n  \"Letohrad\",\n  \"Letovice\",\n  \"Libáň\",\n  \"Libčice nad Vltavou\",\n  \"Liběchov\",\n  \"Liberec\",\n  \"Libochovice\",\n  \"Libušín\",\n  \"Lipník nad Bečvou\",\n  \"Lišov\",\n  \"Litoměřice\",\n  \"Litomyšl\",\n  \"Litovel\",\n  \"Litvínov\",\n  \"Loket\",\n  \"Lom\",\n  \"Lomnice nad Lužnicí\",\n  \"Lomnice nad Popelkou\",\n  \"Loštice\",\n  \"Loučná pod Klínovcem\",\n  \"Louny\",\n  \"Lovosice\",\n  \"Luby\",\n  \"Lučany nad Nisou\",\n  \"Luhačovice\",\n  \"Luže\",\n  \"Lysá nad Labem\",\n  \"Manětín\",\n  \"Mariánské Lázně\",\n  \"Mašťov\",\n  \"Měčín\",\n  \"Mělník\",\n  \"Městec Králové\",\n  \"Město Albrechtice\",\n  \"Město Touškov\",\n  \"Meziboří\",\n  \"Meziměstí\",\n  \"Mikulášovice\",\n  \"Mikulov\",\n  \"Miletín\",\n  \"Milevsko\",\n  \"Milovice\",\n  \"Mimoň\",\n  \"Miroslav\",\n  \"Mirošov\",\n  \"Mirotice\",\n  \"Mirovice\",\n  \"Mladá Boleslav\",\n  \"Mladá Vožice\",\n  \"Mnichovice\",\n  \"Mnichovo Hradiště\",\n  \"Mníšek pod Brdy\",\n  \"Modřice\",\n  \"Mohelnice\",\n  \"Moravská Třebová\",\n  \"Moravské Budějovice\",\n  \"Moravský Beroun\",\n  \"Moravský Krumlov\",\n  \"Morkovice-Slížany\",\n  \"Most\",\n  \"Mšeno\",\n  \"Mýto\",\n  \"Náchod\",\n  \"Nalžovské Hory\",\n  \"Náměšť nad Oslavou\",\n  \"Napajedla\",\n  \"Nasavrky\",\n  \"Nechanice\",\n  \"Nejdek\",\n  \"Němčice nad Hanou\",\n  \"Nepomuk\",\n  \"Neratovice\",\n  \"Netolice\",\n  \"Neveklov\",\n  \"Nová Bystřice\",\n  \"Nová Paka\",\n  \"Nová Role\",\n  \"Nová Včelnice\",\n  \"Nové Hrady\",\n  \"Nové Město na Moravě\",\n  \"Nové Město nad Metují\",\n  \"Nové Město pod Smrkem\",\n  \"Nové Sedlo\",\n  \"Nové Strašecí\",\n  \"Nový Bor\",\n  \"Nový Bydžov\",\n  \"Nový Jičín\",\n  \"Nový Knín\",\n  \"Nymburk\",\n  \"Nýrsko\",\n  \"Nýřany\",\n  \"Odolena Voda\",\n  \"Odry\",\n  \"Olešnice\",\n  \"Olomouc\",\n  \"Oloví\",\n  \"Opava\",\n  \"Opočno\",\n  \"Orlová\",\n  \"Osečná\",\n  \"Osek\",\n  \"Oslavany\",\n  \"Ostrava\",\n  \"Ostrov\",\n  \"Otrokovice\",\n  \"Pacov\",\n  \"Pardubice\",\n  \"Paskov\",\n  \"Pec pod Sněžkou\",\n  \"Pečky\",\n  \"Pelhřimov\",\n  \"Petřvald\",\n  \"Pilníkov\",\n  \"Písek\",\n  \"Planá\",\n  \"Planá nad Lužnicí\",\n  \"Plánice\",\n  \"Plasy\",\n  \"Plesná\",\n  \"Plumlov\",\n  \"Plzeň\",\n  \"Poběžovice\",\n  \"Počátky\",\n  \"Podbořany\",\n  \"Poděbrady\",\n  \"Podivín\",\n  \"Pohořelice\",\n  \"Police nad Metují\",\n  \"Polička\",\n  \"Polná\",\n  \"Postoloprty\",\n  \"Potštát\",\n  \"Prachatice\",\n  \"Praha\",\n  \"Proseč\",\n  \"Prostějov\",\n  \"Protivín\",\n  \"Přebuz\",\n  \"Přelouč\",\n  \"Přerov\",\n  \"Přeštice\",\n  \"Příbor\",\n  \"Příbram\",\n  \"Přibyslav\",\n  \"Přimda\",\n  \"Pyšely\",\n  \"Rabí\",\n  \"Radnice\",\n  \"Rájec-Jestřebí\",\n  \"Rajhrad\",\n  \"Rakovník\",\n  \"Ralsko\",\n  \"Raspenava\",\n  \"Rejštejn\",\n  \"Rokycany\",\n  \"Rokytnice nad Jizerou\",\n  \"Rokytnice v Orlických horách\",\n  \"Ronov nad Doubravou\",\n  \"Rosice\",\n  \"Rotava\",\n  \"Roudnice nad Labem\",\n  \"Rousínov\",\n  \"Rovensko pod Troskami\",\n  \"Roztoky\",\n  \"Rožďalovice\",\n  \"Rožmberk nad Vltavou\",\n  \"Rožmitál pod Třemšínem\",\n  \"Rožnov pod Radhoštěm\",\n  \"Rtyně v Podkrkonoší\",\n  \"Rudná\",\n  \"Rudolfov\",\n  \"Rumburk\",\n  \"Rychnov nad Kněžnou\",\n  \"Rychnov u Jablonce nad Nisou\",\n  \"Rychvald\",\n  \"Rýmařov\",\n  \"Řevnice\",\n  \"Říčany\",\n  \"Sadská\",\n  \"Sázava\",\n  \"Seč\",\n  \"Sedlčany\",\n  \"Sedlec-Prčice\",\n  \"Sedlice\",\n  \"Semily\",\n  \"Sezemice\",\n  \"Sezimovo Ústí\",\n  \"Skalná\",\n  \"Skuteč\",\n  \"Slaný\",\n  \"Slatiňany\",\n  \"Slavičín\",\n  \"Slavkov u Brna\",\n  \"Slavonice\",\n  \"Slušovice\",\n  \"Smečno\",\n  \"Smiřice\",\n  \"Smržovka\",\n  \"Soběslav\",\n  \"Sobotka\",\n  \"Sokolov\",\n  \"Solnice\",\n  \"Spálené Poříčí\",\n  \"Staňkov\",\n  \"Staré Město (okres Šumperk)\",\n  \"Staré Město (okres Uherské Hradiště)\",\n  \"Stárkov\",\n  \"Starý Plzenec\",\n  \"Stochov\",\n  \"Stod\",\n  \"Strakonice\",\n  \"Stráž nad Nežárkou\",\n  \"Stráž pod Ralskem\",\n  \"Strážnice\",\n  \"Strážov\",\n  \"Strmilov\",\n  \"Stříbro\",\n  \"Studénka\",\n  \"Suchdol nad Lužnicí\",\n  \"Sušice\",\n  \"Světlá nad Sázavou\",\n  \"Svitavy\",\n  \"Svoboda nad Úpou\",\n  \"Svratka\",\n  \"Šenov\",\n  \"Šlapanice\",\n  \"Šluknov\",\n  \"Špindlerův Mlýn\",\n  \"Šternberk\",\n  \"Štětí\",\n  \"Štíty\",\n  \"Štramberk\",\n  \"Šumperk\",\n  \"Švihov\",\n  \"Tábor\",\n  \"Tachov\",\n  \"Tanvald\",\n  \"Telč\",\n  \"Teplá\",\n  \"Teplice\",\n  \"Teplice nad Metují\",\n  \"Terezín\",\n  \"Tišnov\",\n  \"Toužim\",\n  \"Tovačov\",\n  \"Trhové Sviny\",\n  \"Trhový Štěpánov\",\n  \"Trmice\",\n  \"Trutnov\",\n  \"Třebechovice pod Orebem\",\n  \"Třebenice\",\n  \"Třebíč\",\n  \"Třeboň\",\n  \"Třemošná\",\n  \"Třemošnice\",\n  \"Třešť\",\n  \"Třinec\",\n  \"Turnov\",\n  \"Týn nad Vltavou\",\n  \"Týnec nad Labem\",\n  \"Týnec nad Sázavou\",\n  \"Týniště nad Orlicí\",\n  \"Uherské Hradiště\",\n  \"Uherský Brod\",\n  \"Uherský Ostroh\",\n  \"Uhlířské Janovice\",\n  \"Újezd u Brna\",\n  \"Unhošť\",\n  \"Uničov\",\n  \"Úpice\",\n  \"Úsov\",\n  \"Ústí nad Labem\",\n  \"Ústí nad Orlicí\",\n  \"Úštěk\",\n  \"Úterý\",\n  \"Úvaly\",\n  \"Valašské Klobouky\",\n  \"Valašské Meziříčí\",\n  \"Valtice\",\n  \"Vamberk\",\n  \"Varnsdorf\",\n  \"Vejprty\",\n  \"Velešín\",\n  \"Velká Bíteš\",\n  \"Velká Bystřice\",\n  \"Velké Bílovice\",\n  \"Velké Hamry\",\n  \"Velké Meziříčí\",\n  \"Velké Opatovice\",\n  \"Velké Pavlovice\",\n  \"Velký Šenov\",\n  \"Veltrusy\",\n  \"Velvary\",\n  \"Verneřice\",\n  \"Veselí nad Lužnicí\",\n  \"Veselí nad Moravou\",\n  \"Vidnava\",\n  \"Vimperk\",\n  \"Vítkov\",\n  \"Vizovice\",\n  \"Vlachovo Březí\",\n  \"Vlašim\",\n  \"Vodňany\",\n  \"Volary\",\n  \"Volyně\",\n  \"Votice\",\n  \"Vracov\",\n  \"Vratimov\",\n  \"Vrbno pod Pradědem\",\n  \"Vrchlabí\",\n  \"Vroutek\",\n  \"Vsetín\",\n  \"Všeruby\",\n  \"Výsluní\",\n  \"Vysoké Mýto\",\n  \"Vysoké nad Jizerou\",\n  \"Vysoké Veselí\",\n  \"Vyškov\",\n  \"Vyšší Brod\",\n  \"Zábřeh\",\n  \"Zákupy\",\n  \"Zásmuky\",\n  \"Zbiroh\",\n  \"Zbýšov\",\n  \"Zdice\",\n  \"Zlaté Hory\",\n  \"Zlín\",\n  \"Zliv\",\n  \"Znojmo\",\n  \"Zruč nad Sázavou\",\n  \"Zubří\",\n  \"Žacléř\",\n  \"Žamberk\",\n  \"Žandov\",\n  \"Žatec\",\n  \"Ždánice\",\n  \"Žďár nad Sázavou\",\n  \"Ždírec nad Doubravou\",\n  \"Žebrák\",\n  \"Železná Ruda\",\n  \"Železnice\",\n  \"Železný Brod\",\n  \"Židlochovice\",\n  \"Žirovnice\",\n  \"Žlutice\",\n  \"Žulová\",\n];\n\n},{}],57:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afghánistán\",\n  \"Albánie\",\n  \"Alžírsko\",\n  \"Andorra\",\n  \"Angola\",\n  \"Antigua a Barbuda\",\n  \"Argentina\",\n  \"Arménie\",\n  \"Austrálie\",\n  \"Ázerbájdžán\",\n  \"Bahamy\",\n  \"Bahrajn\",\n  \"Bangladéš\",\n  \"Barbados\",\n  \"Belgie\",\n  \"Belize\",\n  \"Benin\",\n  \"Bělorusko\",\n  \"Bhútán\",\n  \"Bolívie\",\n  \"Bosna a Hercegovina\",\n  \"Botswana\",\n  \"Brazílie\",\n  \"Brunej\",\n  \"Bulharsko\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Čad\",\n  \"Černá Hora\",\n  \"Česko\",\n  \"Čína\",\n  \"Dánsko\",\n  \"DR Kongo\",\n  \"Dominika\",\n  \"Dominik\",\n  \"Džibutsko\",\n  \"Egypt\",\n  \"Ekvádor\",\n  \"Eritrea\",\n  \"Estonsko\",\n  \"Etiopie\",\n  \"Fidži\",\n  \"Filipíny\",\n  \"Finsko\",\n  \"Francie\",\n  \"Gabon\",\n  \"Gambie\",\n  \"Gruzie\",\n  \"Německo\",\n  \"Ghana\",\n  \"Grenada\",\n  \"Guatemala\",\n  \"Guinea\",\n  \"Guinea-Bissau\",\n  \"Guyana\",\n  \"Haiti\",\n  \"Honduras\",\n  \"Chile\",\n  \"Chorvatsko\",\n  \"Indie\",\n  \"Indonésie\",\n  \"Irák\",\n  \"Írán\",\n  \"Irsko\",\n  \"Island\",\n  \"Itálie\",\n  \"Izrael\",\n  \"Jamajka\",\n  \"Japonsko\",\n  \"Jemen\",\n  \"Jihoaf\",\n  \"Jižní Korea\",\n  \"Jižní Súdán\",\n  \"Jordánsko\",\n  \"Kambodža\",\n  \"Kamerun\",\n  \"Kanada\",\n  \"Kapverdy\",\n  \"Katar\",\n  \"Kazachstán\",\n  \"Keňa\",\n  \"Kiribati\",\n  \"Kolumbie\",\n  \"Komory\",\n  \"Kongo\",\n  \"Kostarika\",\n  \"Kuba\",\n  \"Kuvajt\",\n  \"Kypr\",\n  \"Kyrgyzstán\",\n  \"Laos\",\n  \"Lesotho\",\n  \"Libanon\",\n  \"Libérie\",\n  \"Libye\",\n  \"Lichtenštejnsko\",\n  \"Litva\",\n  \"Lotyšsko\",\n  \"Lucembursko\",\n  \"Madagaskar\",\n  \"Maďarsko\",\n  \"Makedonie\",\n  \"Malajsie\",\n  \"Malawi\",\n  \"Maledivy\",\n  \"Mali\",\n  \"Malta\",\n  \"Maroko\",\n  \"Marshallovy ostrovy\",\n  \"Mauritánie\",\n  \"Mauricius\",\n  \"Mexiko\",\n  \"Mikronésie\",\n  \"Moldavsko\",\n  \"Monako\",\n  \"Mongolsko\",\n  \"Mosambik\",\n  \"Myanmar (Barma)\",\n  \"Namibie\",\n  \"Nauru\",\n  \"Nepál\",\n  \"Niger\",\n  \"Nigérie\",\n  \"Nikaragua\",\n  \"Nizozemsko\",\n  \"Norsko\",\n  \"Nový Zéland\",\n  \"Omán\",\n  \"Pákistán\",\n  \"Palau\",\n  \"Palestina\",\n  \"Panama\",\n  \"Papua-Nová Guinea\",\n  \"Paraguay\",\n  \"Peru\",\n  \"Pobřeží slonoviny\",\n  \"Polsko\",\n  \"Portugalsko\",\n  \"Rakousko\",\n  \"Rovníková Guinea\",\n  \"Rumunsko\",\n  \"Rusko\",\n  \"Rwanda\",\n  \"Řecko\",\n  \"Salvador\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Saúdská Arábie\",\n  \"Senegal\",\n  \"Severní Korea\",\n  \"Seychely\",\n  \"Sierra Leone\",\n  \"Singapur\",\n  \"Slovensko\",\n  \"Slovinsko\",\n  \"Srbsko\",\n  \"Středo\",\n  \"Somálsko\",\n  \"Surinam\",\n  \"Súdán\",\n  \"Svatá Lucie\",\n  \"Svatý Kryštof a Nevis\",\n  \"Svatý Tomáš a Princův ostrov\",\n  \"Svatý Vincenc a Grenadiny\",\n  \"Svazijsko\",\n  \"Spojené arabské emiráty\",\n  \"Spojené království\",\n  \"Spojené státy americké\",\n  \"Sýrie\",\n  \"Šalamounovy ostrovy\",\n  \"Španělsko\",\n  \"Srí Lanka\",\n  \"Švédsko\",\n  \"Švýcarsko\",\n  \"Tádžikistán\",\n  \"Tanzanie\",\n  \"Thajsko\",\n  \"Togo\",\n  \"Tonga\",\n  \"Trinidad a Tobago\",\n  \"Tunisko\",\n  \"Turecko\",\n  \"Turkmenistán\",\n  \"Tuvalu\",\n  \"Uganda\",\n  \"Ukrajina\",\n  \"Uruguay\",\n  \"Uzbekistán\",\n  \"Vanuatu\",\n  \"Vatikán\",\n  \"Venezuela\",\n  \"Vietnam\",\n  \"Východní Timor\",\n  \"Zambie\",\n  \"Zimbabwe\",\n];\n\n},{}],58:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Česká republika\"\n];\n\n},{}],59:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.time_zone = require(\"./time_zone\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.street = require(\"./street\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":54,\"./city\":55,\"./city_name\":56,\"./country\":57,\"./default_country\":58,\"./postcode\":60,\"./secondary_address\":61,\"./state\":62,\"./state_abbr\":63,\"./street\":64,\"./street_address\":65,\"./street_name\":66,\"./time_zone\":67}],60:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\",\n  \"### ##\",\n  \"###-##\"\n];\n\n},{}],61:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Apt. ###\",\n  \"Suite ###\"\n];\n\n},{}],62:[function(require,module,exports){\nmodule.exports=require(50)\n},{\"/Users/a/dev/faker.js/lib/locales/az/name/prefix.js\":50}],63:[function(require,module,exports){\nmodule.exports=require(50)\n},{\"/Users/a/dev/faker.js/lib/locales/az/name/prefix.js\":50}],64:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"17. Listopadu\",\n  \"17. Listopadu\",\n  \"28. Pluku\",\n  \"28. Října\",\n  \"28. Října\",\n  \"5. Května\",\n  \"5. Května\",\n  \"5. Máje\",\n  \"7. Května\",\n  \"8. Listopadu\",\n  \"9. Května\",\n  \"Achátová\",\n  \"Adamova\",\n  \"Adamovská\",\n  \"Adélčina\",\n  \"Africká\",\n  \"Akademická\",\n  \"Aksamitova\",\n  \"Akátová\",\n  \"Alabastrová\",\n  \"Albertov\",\n  \"Albrechtická\",\n  \"Albánská\",\n  \"Albíny Hochové\",\n  \"Aldašínská\",\n  \"Alej Českých Exulantů\",\n  \"Aleny Santarové\",\n  \"Aloisovská\",\n  \"Aloisovská\",\n  \"Aloisovská\",\n  \"Altajská\",\n  \"Alšovo Nábř.\",\n  \"Alšovo Nábřeží\",\n  \"Alšovy Sady\",\n  \"Alžírská\",\n  \"Ambrožova\",\n  \"Americká\",\n  \"Ametystová\",\n  \"Amforová\",\n  \"Amortova\",\n  \"Ampérova\",\n  \"Amurská\",\n  \"Anastázova\",\n  \"Anderleho\",\n  \"Andersenova\",\n  \"Andrštova\",\n  \"Andělova\",\n  \"Anenská\",\n  \"Anenské Nám.\",\n  \"Anenské Náměstí\",\n  \"Anežky Malé\",\n  \"Anežská\",\n  \"Angelovova\",\n  \"Anglická\",\n  \"Angolská\",\n  \"Anhaltova\",\n  \"Ankarská\",\n  \"Anny Drabíkové\",\n  \"Anny Letenské\",\n  \"Anny Rybníčkové\",\n  \"Anny Čížkové\",\n  \"Anny Čížkové\",\n  \"Antala Staška\",\n  \"Antonína Hodného\",\n  \"Antonína Čermáka\",\n  \"Antonínská\",\n  \"Anýzová\",\n  \"Apolinářská\",\n  \"Arabská\",\n  \"Aranžérská\",\n  \"Arbesovo Nám.\",\n  \"Arbesovo Náměstí\",\n  \"Archangelská\",\n  \"Archeologická\",\n  \"Archimédova\",\n  \"Archivní\",\n  \"Argentinská\",\n  \"Aristotelova\",\n  \"Arkalycká\",\n  \"Armádní\",\n  \"Armádního Sboru\",\n  \"Armády\",\n  \"Arménská\",\n  \"Arnošta Valenty\",\n  \"Astlova\",\n  \"Athénská\",\n  \"Atletická\",\n  \"Aubrechtové\",\n  \"Augustinova\",\n  \"Augustova\",\n  \"Austova\",\n  \"Aviatická\",\n  \"Axmanova\",\n  \"Azalková\",\n  \"Azuritová\",\n  \"Ašská\",\n  \"Baarova\",\n  \"Babická\",\n  \"Babiččina\",\n  \"Babočková\",\n  \"Babská\",\n  \"Babylonská\",\n  \"Babákova\",\n  \"Bachmačské Nám.\",\n  \"Bachmačské Náměstí\",\n  \"Bachova\",\n  \"Bacháčkova\",\n  \"Badeniho\",\n  \"Badeniho\",\n  \"Bajgarova\",\n  \"Bajkalská\",\n  \"Bajkonurská\",\n  \"Bakalářská\",\n  \"Bakovská\",\n  \"Bakurinova\",\n  \"Balabánova\",\n  \"Balbínova\",\n  \"Banskobystrická\",\n  \"Baranova\",\n  \"Barchovická\",\n  \"Barešova\",\n  \"Barrandova\",\n  \"Barrandovská\",\n  \"Bartolomějská\",\n  \"Bartoňkova\",\n  \"Bartoňova\",\n  \"Bartoškova\",\n  \"Bartoškova\",\n  \"Bartoškova\",\n  \"Bartákova\",\n  \"Bartůňkova\",\n  \"Barunčina\",\n  \"Barvířská\",\n  \"Barákova\",\n  \"Basilejské Nám.\",\n  \"Basilejské Náměstí\",\n  \"Bassova\",\n  \"Batelovská\",\n  \"Batličkova\",\n  \"Bavorovská\",\n  \"Bavorská\",\n  \"Bazalková\",\n  \"Bazovského\",\n  \"Bačetínská\",\n  \"Baňská\",\n  \"Baškirská\",\n  \"Bašteckého\",\n  \"Baštýřská\",\n  \"Bažantní\",\n  \"Beaufortova\",\n  \"Bechlínská\",\n  \"Bechyňova\",\n  \"Bechyňská\",\n  \"Beckovská\",\n  \"Bedlová\",\n  \"Bednářská\",\n  \"Bedrnova\",\n  \"Bedřichovská\",\n  \"Beethovenova\",\n  \"Beldova\",\n  \"Belgická\",\n  \"Bellova\",\n  \"Bellušova\",\n  \"Bendlova\",\n  \"Bendova\",\n  \"Benecká\",\n  \"Benediktská\",\n  \"Benešovská\",\n  \"Benická\",\n  \"Benkova\",\n  \"Benákova\",\n  \"Benátská\",\n  \"Benáčanova\",\n  \"Beníškové\",\n  \"Beranových\",\n  \"Bergerova\",\n  \"Bergmanova\",\n  \"Berkovská\",\n  \"Berlínská\",\n  \"Bermanova\",\n  \"Bernartická\",\n  \"Bernolákova\",\n  \"Berounská\",\n  \"Bertrámová\",\n  \"Berylová\",\n  \"Besední\",\n  \"Beskydská\",\n  \"Betlémská\",\n  \"Betlémské Nám.\",\n  \"Betlémské Náměstí\",\n  \"Betáňská\",\n  \"Bezdrevská\",\n  \"Bezděkovská\",\n  \"Bezinková\",\n  \"Bezová\",\n  \"Bezprašná\",\n  \"Bečovská\",\n  \"Bečvářova\",\n  \"Bečvářská\",\n  \"Bečvářská\",\n  \"Beřkovická\",\n  \"Bešťákova\",\n  \"Bieblova\",\n  \"Binarova\",\n  \"Biskupcova\",\n  \"Biskupská\",\n  \"Biskupský Dvůr\",\n  \"Blachutova\",\n  \"Blahníkova\",\n  \"Blahoslavova\",\n  \"Blanická\",\n  \"Blatenská\",\n  \"Blatnická\",\n  \"Blatovská\",\n  \"Blatská\",\n  \"Blattného\",\n  \"Blažimská\",\n  \"Blažkova\",\n  \"Blažíčkova\",\n  \"Blešnovská\",\n  \"Blodkova\",\n  \"Bludovická\",\n  \"Blériotova\",\n  \"Blšanecká\",\n  \"Bobkova\",\n  \"Bochovská\",\n  \"Bodláková\",\n  \"Bohdalec\",\n  \"Bohdalec\",\n  \"Bohdalecká\",\n  \"Bohdalecká\",\n  \"Bohdanečská\",\n  \"Bohdašínská\",\n  \"Bohnická\",\n  \"Bohrova\",\n  \"Bohumínská\",\n  \"Bohuslava Martinů\",\n  \"Bohuslava Martinů\",\n  \"Bohuslava Ze Švamberka\",\n  \"Bohuslavická\",\n  \"Bohušovická\",\n  \"Bohušovická\",\n  \"Boháčova\",\n  \"Bohúňova\",\n  \"Bojanovická\",\n  \"Bojasova\",\n  \"Bojetická\",\n  \"Boješická\",\n  \"Bojkovická\",\n  \"Bojovská\",\n  \"Bojínková\",\n  \"Bojčenkova\",\n  \"Bolebořská\",\n  \"Boleratická\",\n  \"Boleslavova\",\n  \"Boleslavská\",\n  \"Boletická\",\n  \"Bolevecká\",\n  \"Bolinská\",\n  \"Boloňská\",\n  \"Bolzanova\",\n  \"Bolívarova\",\n  \"Borecká\",\n  \"Borečkova\",\n  \"Borodinská\",\n  \"Borotínská\",\n  \"Borovanská\",\n  \"Borovanského\",\n  \"Borovnická\",\n  \"Borovská\",\n  \"Borová\",\n  \"Borošova\",\n  \"Borská\",\n  \"Borského\",\n  \"Boršov\",\n  \"Boršovská\",\n  \"Borůvková\",\n  \"Boseňská\",\n  \"Botevova\",\n  \"Botičská\",\n  \"Botičská\",\n  \"Boudova\",\n  \"Bousovská\",\n  \"Boučkova\",\n  \"Bouřilova\",\n  \"Boušova\",\n  \"Bozděchova\",\n  \"Boční I\",\n  \"Boční Ii\",\n  \"Bořanovická\",\n  \"Bořetická\",\n  \"Bořetínská\",\n  \"Bořivojova\",\n  \"Bořivojova\",\n  \"Boříkova\",\n  \"Bošická\",\n  \"Bošilecká\",\n  \"Bošínská\",\n  \"Božanovská\",\n  \"Božecká\",\n  \"Božejovická\",\n  \"Boženy Hofmeisterové\",\n  \"Boženy Jandlové\",\n  \"Boženy Němcové\",\n  \"Boženy Němcové\",\n  \"Boženy Stárkové\",\n  \"Božetická\",\n  \"Božetěchova\",\n  \"Božkova\",\n  \"Božkovská\",\n  \"Božídarská\",\n  \"Brabcova\",\n  \"Bramboříková\",\n  \"Branaldova\",\n  \"Brandejsova\",\n  \"Brandejsovo Nám.\",\n  \"Brandejsovo Náměstí\",\n  \"Brandlova\",\n  \"Brandýská\",\n  \"Branická\",\n  \"Branická\",\n  \"Branické Nám.\",\n  \"Branické Náměstí\",\n  \"Branislavova\",\n  \"Branišovská\",\n  \"Branská\",\n  \"Bratislavská\",\n  \"Bratranců Veverkových\",\n  \"Bratří Dohalských\",\n  \"Bratří Venclíků\",\n  \"Bratří Čapků\",\n  \"Bratříkovská\",\n  \"Braunerova\",\n  \"Braunova\",\n  \"Braškovská\",\n  \"Brdecká\",\n  \"Brdičkova\",\n  \"Brdlíkova\",\n  \"Brechtova\",\n  \"Brechtova\",\n  \"Brehmova\",\n  \"Breitcetlova\",\n  \"Brichtova\",\n  \"Brigádnická\",\n  \"Brigádníků\",\n  \"Brixiho\",\n  \"Brodecká\",\n  \"Brodecká\",\n  \"Brodského\",\n  \"Bromova\",\n  \"Bronzová\",\n  \"Broskvoňová\",\n  \"Broumarská\",\n  \"Broumovská\",\n  \"Brozánská\",\n  \"Brožíkova\",\n  \"Brtecká\",\n  \"Brtnická\",\n  \"Brumovická\",\n  \"Brunclíkova\",\n  \"Brunelova\",\n  \"Brunnerova\",\n  \"Bruselská\",\n  \"Brusinková\",\n  \"Bruslařská\",\n  \"Bryksova\",\n  \"Brzická\",\n  \"Brzorádových\",\n  \"Brázdimská\",\n  \"Brňovská\",\n  \"Bubenečská\",\n  \"Bubenečská\",\n  \"Bubenská\",\n  \"Bubenské Nábř.\",\n  \"Bubenské Nábřeží\",\n  \"Bubeníčkova\",\n  \"Bublavská\",\n  \"Bublíkova\",\n  \"Bubnova\",\n  \"Bucharova\",\n  \"Buchlovská\",\n  \"Buchovcova\",\n  \"Budapešťská\",\n  \"Budečská\",\n  \"Budilova\",\n  \"Budilovská\",\n  \"Budovatelská\",\n  \"Budyňská\",\n  \"Budyšínská\",\n  \"Budínova\",\n  \"Budčická\",\n  \"Budějovická\",\n  \"Budějovická\",\n  \"Bukolská\",\n  \"Bukovecká\",\n  \"Bukovinská\",\n  \"Buková\",\n  \"Bulharská\",\n  \"Buližníková\",\n  \"Bulovka\",\n  \"Burdova\",\n  \"Burešova\",\n  \"Burianova\",\n  \"Butovická\",\n  \"Butovická\",\n  \"Buzulucká\",\n  \"Buštěhradská\",\n  \"Bydhošťská\",\n  \"Bydžovská\",\n  \"Bydžovského\",\n  \"Bylanská\",\n  \"Bystrá\",\n  \"Bystřická\",\n  \"Bystřičná\",\n  \"Byšická\",\n  \"Byškovická\",\n  \"Bzenecká\",\n  \"Bártlova\",\n  \"Bášťská\",\n  \"Bílenecké Nám.\",\n  \"Bílenecké Náměstí\",\n  \"Bílinská\",\n  \"Bílkova\",\n  \"Bílkova\",\n  \"Bílovská\",\n  \"Bílá\",\n  \"Bílčická\",\n  \"Bínova\",\n  \"Bítovská\",\n  \"Böhmova\",\n  \"Býšovská\",\n  \"Běchorská\",\n  \"Běchovická\",\n  \"Běhounkova\",\n  \"Bělehradská\",\n  \"Bělehradská\",\n  \"Bělehradská\",\n  \"Bělečská\",\n  \"Bělinského\",\n  \"Bělocerkevská\",\n  \"Bělocká\",\n  \"Bělohorská\",\n  \"Bělohorská\",\n  \"Bělomlýnská\",\n  \"Bělomlýnská\",\n  \"Běloveská\",\n  \"Běluňská\",\n  \"Bělušická\",\n  \"Bělásková\",\n  \"Bělčická\",\n  \"Bělčická\",\n  \"Běžecká\",\n  \"Běžná\",\n  \"Břeclavská\",\n  \"Břehová\",\n  \"Břehová\",\n  \"Břetislavova\",\n  \"Břevnovská\",\n  \"Březanova\",\n  \"Březecká\",\n  \"Březenská\",\n  \"Březinova\",\n  \"Březiněveská\",\n  \"Březnická\",\n  \"Březnová\",\n  \"Březovická\",\n  \"Březovského\",\n  \"Březová\",\n  \"Břečťanová\",\n  \"Břežanská\",\n  \"Břežánecká\",\n  \"Břidlicová\",\n  \"Břidličná\",\n  \"Břízova\",\n  \"Bříšťanská\",\n  \"Cafourkova\",\n  \"Cedrová\",\n  \"Celetná\",\n  \"Celniční\",\n  \"Celsiova\",\n  \"Cementářská\",\n  \"Ceplechova\",\n  \"Cerhenická\",\n  \"Cerhýnská\",\n  \"Cetyňská\",\n  \"Chabařovická\",\n  \"Chaberská\",\n  \"Chabeřická\",\n  \"Chabská\",\n  \"Chalabalova\",\n  \"Chaloupeckého\",\n  \"Chaloupky\",\n  \"Chaltická\",\n  \"Chalupkova\",\n  \"Chalupnická\",\n  \"Chaplinovo Nám.\",\n  \"Chaplinovo Náměstí\",\n  \"Charkovská\",\n  \"Charlese De Gaulla\",\n  \"Charvátova\",\n  \"Chatařská\",\n  \"Chatová\",\n  \"Chebská\",\n  \"Chelčického\",\n  \"Chemická\",\n  \"Chilská\",\n  \"Chittussiho\",\n  \"Chladírenská\",\n  \"Chlebovická\",\n  \"Chlumecká\",\n  \"Chlumecká\",\n  \"Chlumecká\",\n  \"Chlumova\",\n  \"Chlumínská\",\n  \"Chlumčanského\",\n  \"Chlupova\",\n  \"Chlupáčova\",\n  \"Chládkova\",\n  \"Chmelařská\",\n  \"Chmelická\",\n  \"Chmelová\",\n  \"Chmelířova\",\n  \"Choceradská\",\n  \"Choceňská\",\n  \"Chocholouškova\",\n  \"Chocholova\",\n  \"Chodecká\",\n  \"Chodovecké Nám.\",\n  \"Chodovecké Náměstí\",\n  \"Chodovická\",\n  \"Chodovská\",\n  \"Chodovská\",\n  \"Chodovská\",\n  \"Chodská\",\n  \"Cholupická\",\n  \"Chomutovická\",\n  \"Chomutovská\",\n  \"Chopinova\",\n  \"Choratická\",\n  \"Chorošová\",\n  \"Chorušická\",\n  \"Chorvatská\",\n  \"Chotečská\",\n  \"Chotkova\",\n  \"Chotouchovská\",\n  \"Chotouňská\",\n  \"Chotovická\",\n  \"Chotutická\",\n  \"Chotěbuzská\",\n  \"Chotěnovská\",\n  \"Chotětovská\",\n  \"Chotěšovská\",\n  \"Chovatelská\",\n  \"Chrastavská\",\n  \"Chrobolská\",\n  \"Chrpová\",\n  \"Chrudimská\",\n  \"Chráněná\",\n  \"Chrášťanská\",\n  \"Chuchelská\",\n  \"Chudenická\",\n  \"Chudoměřická\",\n  \"Churnajevova\",\n  \"Churáňovská\",\n  \"Chvaletická\",\n  \"Chvaletická\",\n  \"Chvalečská\",\n  \"Chvalkovická\",\n  \"Chvalova\",\n  \"Chvalská\",\n  \"Chvalská\",\n  \"Chvalšovická\",\n  \"Chvatěrubská\",\n  \"Chvojenecká\",\n  \"Chyjická\",\n  \"Chýnická\",\n  \"Chýnovská\",\n  \"Chýňská\",\n  \"Chřibská\",\n  \"Cibulka\",\n  \"Cidlinská\",\n  \"Cigánkova\",\n  \"Cihelná\",\n  \"Cihlářova\",\n  \"Cihlářská\",\n  \"Cimburkova\",\n  \"Ciolkovského\",\n  \"Cirkusová\",\n  \"Cisterciácká\",\n  \"Citolibská\",\n  \"Coriových\",\n  \"Ctiborova\",\n  \"Ctiněveská\",\n  \"Ctiradova\",\n  \"Ctěnická\",\n  \"Cukerní\",\n  \"Cukrovarnická\",\n  \"Cukrovarská\",\n  \"Cuřínova\",\n  \"Cvikovská\",\n  \"Cvičebná\",\n  \"Cvrčkova\",\n  \"Cvrčkova\",\n  \"Cvrčkova\",\n  \"Cyprichova\",\n  \"Cíglerova\",\n  \"Cílkova\",\n  \"Cínovecká\",\n  \"Církova\",\n  \"Církvická\",\n  \"Církvičná\",\n  \"Císařská Louka\",\n  \"Císařský Ostrov\",\n  \"Císařský Ostrov\",\n  \"Císařský Ostrov\",\n  \"Cítovská\",\n  \"Daimlerova\",\n  \"Dalejská\",\n  \"Dalejská\",\n  \"Dalešická\",\n  \"Daliborova\",\n  \"Dalimilova\",\n  \"Dalovická\",\n  \"Dandova\",\n  \"Danielova\",\n  \"Dany Medřické\",\n  \"Darwinova\",\n  \"Dasnická\",\n  \"Davelská\",\n  \"Davidovičova\",\n  \"Davídkova\",\n  \"Davídkova\",\n  \"Dačická\",\n  \"Dačického\",\n  \"Daňkova\",\n  \"Dašická\",\n  \"Daškova\",\n  \"Dehtínská\",\n  \"Dejvická\",\n  \"Dejvická\",\n  \"Demlova\",\n  \"Demoliční\",\n  \"Desenská\",\n  \"Destinnové\",\n  \"Destinové\",\n  \"Devonská\",\n  \"Deylova\",\n  \"Deštná\",\n  \"Dešťová\",\n  \"Diabasová\",\n  \"Diamantová\",\n  \"Diblíkova\",\n  \"Diblíkova\",\n  \"Dienzenhoferovy Sady\",\n  \"Dieselova\",\n  \"Diskařská\",\n  \"Diskařská\",\n  \"Dismanova\",\n  \"Dittrichova\",\n  \"Divadelní\",\n  \"Divadelní\",\n  \"Divecká\",\n  \"Diviznová\",\n  \"Divišova\",\n  \"Divišovská\",\n  \"Divoká Šárka\",\n  \"Divoká Šárka\",\n  \"Dlabačov\",\n  \"Dlabačov\",\n  \"Dlouhá\",\n  \"Dlážděná\",\n  \"Do Blatin\",\n  \"Do Borovin\",\n  \"Do Chuchle\",\n  \"Do Dolnic\",\n  \"Do Dubin\",\n  \"Do Dubče\",\n  \"Do Hlinek\",\n  \"Do Klukovic\",\n  \"Do Kopečka\",\n  \"Do Koutů\",\n  \"Do Koutů\",\n  \"Do Lipan\",\n  \"Do Lipin\",\n  \"Do Lipin\",\n  \"Do Luk\",\n  \"Do Panenek\",\n  \"Do Podkovy\",\n  \"Do Polí\",\n  \"Do Potoků\",\n  \"Do Píšovic\",\n  \"Do Roklí\",\n  \"Do Rybníčků\",\n  \"Do Svépravic\",\n  \"Do Vozovny\",\n  \"Do Vrchu\",\n  \"Do Vršku\",\n  \"Do Zahrádek I\",\n  \"Do Zahrádek I\",\n  \"Do Zahrádek I\",\n  \"Do Zahrádek Ii\",\n  \"Do Zahrádek Ii\",\n  \"Do Zátiší\",\n  \"Do Údolí\",\n  \"Do Újezda\",\n  \"Do Čertous\",\n  \"Do Čtvrti\",\n  \"Do Říčan\",\n  \"Dobevská\",\n  \"Dobnerova\",\n  \"Dobratická\",\n  \"Dobronická\",\n  \"Dobronická\",\n  \"Dobropolská\",\n  \"Dobrovická\",\n  \"Dobrovolného\",\n  \"Dobrovolského\",\n  \"Dobrovského\",\n  \"Dobrovízská\",\n  \"Dobročovická\",\n  \"Dobrošovská\",\n  \"Dobrušská\",\n  \"Dobřanská\",\n  \"Dobřejovická\",\n  \"Dobřenická\",\n  \"Dobřichovská\",\n  \"Dobšická\",\n  \"Dobšínská\",\n  \"Dohalická\",\n  \"Doksanská\",\n  \"Dolanská\",\n  \"Dolejškova\",\n  \"Doležalova\",\n  \"Dolina\",\n  \"Dolnobranská\",\n  \"Dolnobřežanská\",\n  \"Dolnocholupická\",\n  \"Dolnojirčanská\",\n  \"Dolnokrčská\",\n  \"Dolnokřeslická\",\n  \"Dolnomlýnská\",\n  \"Dolnoměcholupská\",\n  \"Dolnoměcholupská\",\n  \"Dolnopočernická\",\n  \"Dolnočernošická\",\n  \"Dolní\",\n  \"Dolní\",\n  \"Dolní Chaloupky\",\n  \"Dolomitová\",\n  \"Dolská\",\n  \"Dolákova\",\n  \"Dolínecká\",\n  \"Dolňanská\",\n  \"Domanovická\",\n  \"Domašínská\",\n  \"Domažlická\",\n  \"Dominova\",\n  \"Dominínská\",\n  \"Domkovská\",\n  \"Domkářská\",\n  \"Domousnická\",\n  \"Donatellova\",\n  \"Donovalská\",\n  \"Donská\",\n  \"Donátova\",\n  \"Donínská\",\n  \"Dopplerova\",\n  \"Dopravní\",\n  \"Dopraváků\",\n  \"Dopraváků\",\n  \"Dostihová\",\n  \"Dostojevského\",\n  \"Doubecká\",\n  \"Doubická\",\n  \"Doubravická\",\n  \"Doubravská\",\n  \"Doubravínova\",\n  \"Doubravčická\",\n  \"Doudlebská\",\n  \"Doudova\",\n  \"Doupovská\",\n  \"Dr. Marodyho\",\n  \"Dr. Zikmunda Wintra\",\n  \"Dr.Zikmunda Wintra\",\n  \"Dragounská\",\n  \"Drahanská\",\n  \"Drahanská\",\n  \"Drahelická\",\n  \"Drahelčická\",\n  \"Drahobejlova\",\n  \"Drahorádova\",\n  \"Drahotická\",\n  \"Drahotínská\",\n  \"Drahovská\",\n  \"Drahovská\",\n  \"Drahoňovského\",\n  \"Draženovská\",\n  \"Draženovská\",\n  \"Dražetická\",\n  \"Dražická\",\n  \"Dražického\",\n  \"Dražického Nám.\",\n  \"Dražického Náměstí\",\n  \"Dražkovská\",\n  \"Dreyerova\",\n  \"Drimlova\",\n  \"Drnovská\",\n  \"Drobná\",\n  \"Drtikolova\",\n  \"Drtinova\",\n  \"Druhanická\",\n  \"Druhého Odboje\",\n  \"Družicová\",\n  \"Družnosti\",\n  \"Družná\",\n  \"Družstevní\",\n  \"Družstevní Ochoz\",\n  \"Družstevní Ochoz\",\n  \"Drážní\",\n  \"Drůbežnická\",\n  \"Drůbežářská\",\n  \"Dubanská\",\n  \"Dubenecká\",\n  \"Dubečská\",\n  \"Dubečské Horky\",\n  \"Dubinská\",\n  \"Dubnická\",\n  \"Dubnova\",\n  \"Dubovická\",\n  \"Dubová\",\n  \"Dubrovnická\",\n  \"Dubská\",\n  \"Duchcovská\",\n  \"Duchoslávka\",\n  \"Dudkova\",\n  \"Dudínská\",\n  \"Duhová\",\n  \"Dukelská\",\n  \"Dukelských Hrdinů\",\n  \"Dunajevského\",\n  \"Dunajská\",\n  \"Dunická\",\n  \"Dunovského\",\n  \"Durychova\",\n  \"Durychova\",\n  \"Dusíkova\",\n  \"Duškova\",\n  \"Duškova\",\n  \"Dušní\",\n  \"Dušní\",\n  \"Dvorecká\",\n  \"Dvorecké Nám.\",\n  \"Dvorecké Náměstí\",\n  \"Dvorní\",\n  \"Dvorská\",\n  \"Dvoudílná\",\n  \"Dvouletky\",\n  \"Dvouramenná\",\n  \"Dvořeckého\",\n  \"Dvořišťská\",\n  \"Dvořákova\",\n  \"Dvořákovo Nábř.\",\n  \"Dvořákovo Nábřeží\",\n  \"Dygrýnova\",\n  \"Dyjská\",\n  \"Dykova\",\n  \"Dářská\",\n  \"Dürerova\",\n  \"Dýšinská\",\n  \"Děbolínská\",\n  \"Dědická\",\n  \"Dědinova\",\n  \"Dědinská\",\n  \"Děkanská\",\n  \"Děkanská Vinice I\",\n  \"Děkanská Vinice Ii\",\n  \"Dělená\",\n  \"Dělnická\",\n  \"Dělostřelecká\",\n  \"Dětenická\",\n  \"Dětská\",\n  \"Dětský Ostrov\",\n  \"Děvínská\",\n  \"Děčínská\",\n  \"Děčínská\",\n  \"Dřevařská\",\n  \"Dřevnická\",\n  \"Dřevná\",\n  \"Dřevčická\",\n  \"Dřínovská\",\n  \"Dřínová\",\n  \"Dřítenská\",\n  \"Eberlova\",\n  \"Ebrova\",\n  \"Edisonova\",\n  \"Edvardova\",\n  \"Egyptská\",\n  \"Eichlerova\",\n  \"Einsteinova\",\n  \"Ejpovická\",\n  \"Ekonomická\",\n  \"Eledrova\",\n  \"Elektrárenská\",\n  \"Eliášova\",\n  \"Eliášova\",\n  \"Elišky Junkové\",\n  \"Elišky Krásnohorské\",\n  \"Elišky Krásnohorské\",\n  \"Elišky Peškové\",\n  \"Elišky Přemyslovny\",\n  \"Ellnerové\",\n  \"Elsnicovo Náměstí\",\n  \"Emilie Hyblerové\",\n  \"Emlerova\",\n  \"Engelmüllerova\",\n  \"Engelova\",\n  \"Engelova\",\n  \"Englerova\",\n  \"Erbenova\",\n  \"Erbenova\",\n  \"Estonská\",\n  \"Etiopská\",\n  \"Euklidova\",\n  \"Evropská\",\n  \"Evropská\",\n  \"Evropská\",\n  \"Evropská\",\n  \"Evropská\",\n  \"Evy Olmerové\",\n  \"Exnárova\",\n  \"F.V.Veselého\",\n  \"Fabiánova\",\n  \"Fabiánská\",\n  \"Fadějevova\",\n  \"Fajmanové\",\n  \"Fajtlova\",\n  \"Falcká\",\n  \"Faltysova\",\n  \"Famfulíkova\",\n  \"Fantova\",\n  \"Faradayova\",\n  \"Farkašova\",\n  \"Farní\",\n  \"Farská\",\n  \"Farského\",\n  \"Fastrova\",\n  \"Federova\",\n  \"Fejfarova\",\n  \"Felberova\",\n  \"Fenyklová\",\n  \"Fetrovská\",\n  \"Feřtekova\",\n  \"Fialková\",\n  \"Fibichova\",\n  \"Fikerova\",\n  \"Filipova\",\n  \"Filipovského\",\n  \"Filipíny Welserové\",\n  \"Fillova\",\n  \"Filmařská\",\n  \"Filosofská\",\n  \"Fingerova\",\n  \"Finkovská\",\n  \"Finská\",\n  \"Firkušného\",\n  \"Fischlova\",\n  \"Fišerova\",\n  \"Flemingovo Nám.\",\n  \"Flemingovo Náměstí\",\n  \"Flájská\",\n  \"Flöglova\",\n  \"Foerstrova\",\n  \"Folmavská\",\n  \"Formanská\",\n  \"Formánkova\",\n  \"Fořtova\",\n  \"Fragnerova\",\n  \"Francouzská\",\n  \"Francouzská\",\n  \"Francouzská\",\n  \"Františka Diviše\",\n  \"Františka Jansy\",\n  \"Františka Kadlece\",\n  \"Františka Křížka\",\n  \"Františka Černého\",\n  \"Františka Červeného\",\n  \"Františka Šimáčka\",\n  \"Františkova\",\n  \"Franty Kocourka\",\n  \"Frančíkova\",\n  \"Freiwaldova\",\n  \"Freyova\",\n  \"Frimlova\",\n  \"Fričova\",\n  \"Froncova\",\n  \"Frostova\",\n  \"Froňkova\",\n  \"Frydrychova\",\n  \"Fryčovická\",\n  \"Fráni Šrámka\",\n  \"Frézařská\",\n  \"Frýdecká\",\n  \"Frýdlantská\",\n  \"Fuchsova\",\n  \"Fügnerovo Nám.\",\n  \"Fügnerovo Náměstí\",\n  \"Gabinova\",\n  \"Gabčíkova\",\n  \"Gagarinova\",\n  \"Galandova\",\n  \"Galileova\",\n  \"Gallašova\",\n  \"Galvaniho\",\n  \"Gaussova\",\n  \"Gdaňská\",\n  \"Generála Janouška\",\n  \"Generála Mejstříka\",\n  \"Generála Píky\",\n  \"Generála Šišky\",\n  \"Generála Šišky\",\n  \"Gensovská\",\n  \"Geologická\",\n  \"Gercenova\",\n  \"Gerstnerova\",\n  \"Ginzova\",\n  \"Glazunovova\",\n  \"Glinkova\",\n  \"Glowackého\",\n  \"Goetheho\",\n  \"Gogolova\",\n  \"Golfová\",\n  \"Gollova\",\n  \"Golčova\",\n  \"Gončarenkova\",\n  \"Gončarenkova\",\n  \"Gorazdova\",\n  \"Gotthardská\",\n  \"Goyova\",\n  \"Gočárova\",\n  \"Grafická\",\n  \"Grafitová\",\n  \"Grammova\",\n  \"Granátová\",\n  \"Gregorova\",\n  \"Grussova\",\n  \"Gruzínská\",\n  \"Gutfreundova\",\n  \"Gutova\",\n  \"Gymnasijní\",\n  \"Gymnastická\",\n  \"Habartická\",\n  \"Habartická\",\n  \"Habartovská\",\n  \"Haberfeldova\",\n  \"Habrovská\",\n  \"Habrová\",\n  \"Habřická\",\n  \"Habřická\",\n  \"Hackerova\",\n  \"Hadovitá\",\n  \"Hadravská\",\n  \"Hajní\",\n  \"Hakenova\",\n  \"Halasova\",\n  \"Halenkovská\",\n  \"Halštatská\",\n  \"Hamerská\",\n  \"Hamplova\",\n  \"Hamrová\",\n  \"Hamsíkova\",\n  \"Hankova\",\n  \"Hanouškova\",\n  \"Hanusova\",\n  \"Hanušova\",\n  \"Hanzelkova\",\n  \"Hanzlíkova\",\n  \"Harantova\",\n  \"Harcovská\",\n  \"Harlacherova\",\n  \"Harmonická\",\n  \"Harrachovská\",\n  \"Hartenberská\",\n  \"Hasičská\",\n  \"Hasičů\",\n  \"Hasova\",\n  \"Hastrmanská\",\n  \"Haunerova\",\n  \"Hauptova\",\n  \"Hausmannova\",\n  \"Havanská\",\n  \"Havelská\",\n  \"Havelská Ulička\",\n  \"Havlovického\",\n  \"Havlovického\",\n  \"Havlovská\",\n  \"Havlínova\",\n  \"Havlíčkova\",\n  \"Havlíčkovo Nám.\",\n  \"Havlíčkovo Náměstí\",\n  \"Havlíčkovy Sady\",\n  \"Havlůjové\",\n  \"Havlůjové\",\n  \"Havranická\",\n  \"Havraní\",\n  \"Havránkova\",\n  \"Havířovská\",\n  \"Havířská\",\n  \"Haškova\",\n  \"Hašlerova\",\n  \"Haštalská\",\n  \"Haštalské Nám.\",\n  \"Haštalské Náměstí\",\n  \"Heckelova\",\n  \"Heineho\",\n  \"Heinemannova\",\n  \"Hejnická\",\n  \"Hejnická\",\n  \"Hejplíkova\",\n  \"Hejtmanská\",\n  \"Hejtmánkova\",\n  \"Hekova\",\n  \"Hekrova\",\n  \"Heldova\",\n  \"Heleny Malířové\",\n  \"Hellichova\",\n  \"Helmova\",\n  \"Helsinská\",\n  \"Helénská\",\n  \"Hennerova\",\n  \"Heranova\",\n  \"Herbenova\",\n  \"Herdovská\",\n  \"Herlíkovická\",\n  \"Hermanická\",\n  \"Hermelínská\",\n  \"Hermíny Týrlové\",\n  \"Heroldovy Sady\",\n  \"Herrmannova\",\n  \"Herrova\",\n  \"Hertzova\",\n  \"Herálecká I\",\n  \"Herálecká Ii\",\n  \"Herálecká Iii\",\n  \"Herálecká Iv\",\n  \"Herčíkova\",\n  \"Hevlínská\",\n  \"Heydukova\",\n  \"Heyrovského Nám.\",\n  \"Heyrovského Nám.\",\n  \"Heyrovského Náměstí\",\n  \"Heyrovského Náměstí\",\n  \"Hečkova\",\n  \"Heřmanova\",\n  \"Heřmánková\",\n  \"Hildy Čihákové\",\n  \"Hillebrantova\",\n  \"Hilmarova\",\n  \"Hiršlova\",\n  \"Hlavatého\",\n  \"Hlavenecká\",\n  \"Hlavní\",\n  \"Hlavova\",\n  \"Hlaváčkova\",\n  \"Hlaváčova\",\n  \"Hlaďova\",\n  \"Hledíková\",\n  \"Hlinská\",\n  \"Hlivická\",\n  \"Hlohová\",\n  \"Hloubětínská\",\n  \"Hloubětínská\",\n  \"Hlubocká\",\n  \"Hluboká\",\n  \"Hlubočepská\",\n  \"Hlušičkova\",\n  \"Hládkov\",\n  \"Hládkov\",\n  \"Hlávkova\",\n  \"Hněvkovská\",\n  \"Hněvkovského\",\n  \"Hnězdenská\",\n  \"Hoblířská\",\n  \"Hodkovická\",\n  \"Hodkovská\",\n  \"Hodonínská\",\n  \"Hodčina\",\n  \"Hodějovská\",\n  \"Hodějovská\",\n  \"Hoděšovická\",\n  \"Hofbauerova\",\n  \"Hoffmannova\",\n  \"Hokejová\",\n  \"Hokešovo Nám.\",\n  \"Hokešovo Náměstí\",\n  \"Holandská\",\n  \"Holekova\",\n  \"Holenická\",\n  \"Holenská\",\n  \"Holečkova\",\n  \"Holečkova\",\n  \"Holešovické Nábřeží\",\n  \"Holešovický Přístav\",\n  \"Holická\",\n  \"Hollarovo Nám.\",\n  \"Hollarovo Náměstí\",\n  \"Holohlavská\",\n  \"Holotínská\",\n  \"Holoubkova\",\n  \"Holoubkovská\",\n  \"Holubická\",\n  \"Holubinková\",\n  \"Holubkova\",\n  \"Holubova\",\n  \"Holubí\",\n  \"Holušická\",\n  \"Holyňská\",\n  \"Holátova\",\n  \"Holínská\",\n  \"Holýšovská\",\n  \"Holčovická\",\n  \"Holšická\",\n  \"Homolová\",\n  \"Homérova\",\n  \"Honzíkova\",\n  \"Hornická\",\n  \"Hornocholupická\",\n  \"Hornocholupická\",\n  \"Hornofova\",\n  \"Hornokrčská\",\n  \"Hornokřeslická\",\n  \"Hornomlýnská\",\n  \"Hornoměcholupská\",\n  \"Hornoměcholupská\",\n  \"Hornopočernická\",\n  \"Horní\",\n  \"Horní Chaloupky\",\n  \"Horní Hrdlořezská\",\n  \"Horní Stromky\",\n  \"Horníčkova\",\n  \"Horolezecká\",\n  \"Horoměřická\",\n  \"Horoměřická\",\n  \"Horoušanská\",\n  \"Horoušanská\",\n  \"Horovo Nám.\",\n  \"Horovo Náměstí\",\n  \"Horská\",\n  \"Horusická\",\n  \"Horymírovo Nám.\",\n  \"Horymírovo Náměstí\",\n  \"Horákova\",\n  \"Horáčkova\",\n  \"Horčičkova\",\n  \"Horňátecká\",\n  \"Horšovská\",\n  \"Horšovská\",\n  \"Hospodářská\",\n  \"Hostavická\",\n  \"Hostavická\",\n  \"Hostinského\",\n  \"Hostivařská\",\n  \"Hostivařské Nám.\",\n  \"Hostivařské Náměstí\",\n  \"Hostivická\",\n  \"Hostivítova\",\n  \"Hostišovská\",\n  \"Hostouňská\",\n  \"Hostošova\",\n  \"Hostýnská\",\n  \"Hostýnská\",\n  \"Houbařská\",\n  \"Houdova\",\n  \"Hovorčovická\",\n  \"Hořanská\",\n  \"Hořejší Náb.\",\n  \"Hořejší Nábřeží\",\n  \"Hořejšího\",\n  \"Hořelická\",\n  \"Hořická\",\n  \"Hořovského\",\n  \"Hořínecká\",\n  \"Hoškova\",\n  \"Hoštická\",\n  \"Hošťálkova\",\n  \"Hrabačovská\",\n  \"Hrabákova\",\n  \"Hrachovská\",\n  \"Hrad I. Nádvoří\",\n  \"Hrad Ii. Nádvoří\",\n  \"Hrad Iii. Nádvoří\",\n  \"Hradební\",\n  \"Hradecká\",\n  \"Hradeckých\",\n  \"Hradečkova\",\n  \"Hradešínská\",\n  \"Hradčanské Nám.\",\n  \"Hradčanské Náměstí\",\n  \"Hraniční\",\n  \"Hrazanská\",\n  \"Hrazanská\",\n  \"Hrdinova\",\n  \"Hrdličkova\",\n  \"Hrdlořezská\",\n  \"Hrdoňovická\",\n  \"Hroncova\",\n  \"Hronovská\",\n  \"Hronětická\",\n  \"Hrozenkovská\",\n  \"Hroznová\",\n  \"Hrozného\",\n  \"Hrubého\",\n  \"Hrubínova\",\n  \"Hrudičkova\",\n  \"Hrusická\",\n  \"Hruškovská\",\n  \"Hruškovská\",\n  \"Hrušovanské Nám.\",\n  \"Hrušovanské Náměstí\",\n  \"Hrušovická\",\n  \"Hrušovská\",\n  \"Hrušínského\",\n  \"Hrušňová\",\n  \"Hrušňová\",\n  \"Hrádková\",\n  \"Hráského\",\n  \"Huberova\",\n  \"Hubičkova\",\n  \"Hubáčkova\",\n  \"Hudcova\",\n  \"Hudební\",\n  \"Hudečkova\",\n  \"Hudečkova\",\n  \"Hugo Haase\",\n  \"Hulanova\",\n  \"Hulická\",\n  \"Humenecká\",\n  \"Humpolecká\",\n  \"Huntířovská\",\n  \"Hurbanova\",\n  \"Husařská\",\n  \"Husinecká\",\n  \"Husitská\",\n  \"Husitská\",\n  \"Husníkova\",\n  \"Husova\",\n  \"Husovo Nám.\",\n  \"Husovo Náměstí\",\n  \"Hustopečská\",\n  \"Hutnická\",\n  \"Huťská\",\n  \"Hviezdoslavova\",\n  \"Hviezdoslavova\",\n  \"Hvozdecká\",\n  \"Hvozdnická\",\n  \"Hvozdíková\",\n  \"Hvožďanská\",\n  \"Hvězdonická\",\n  \"Hvězdova\",\n  \"Hvězdářská\",\n  \"Hyacintová\",\n  \"Hybernská\",\n  \"Hybešova\",\n  \"Hynaisova\",\n  \"Hypšmanova\",\n  \"Hábova\",\n  \"Hájecká\",\n  \"Hájenská\",\n  \"Hájkova\",\n  \"Hájovna U Podjezdu\",\n  \"Hájovna V Šárce\",\n  \"Hájová\",\n  \"Hájíčkova\",\n  \"Hájčí\",\n  \"Hákova\",\n  \"Hálkova\",\n  \"Hálova\",\n  \"Hálův Statek\",\n  \"Högerova\",\n  \"Hübnerové\",\n  \"Hřbitovní\",\n  \"Hřebenová\",\n  \"Hřebíkova\",\n  \"Hřenská\",\n  \"Hřibojedská\",\n  \"Hřibská\",\n  \"Hříbková\",\n  \"Hřídelecká\",\n  \"Hůlkova\",\n  \"Hůlkova\",\n  \"Hůrská\",\n  \"Ibsenova\",\n  \"Imrychova\",\n  \"Ingrišova\",\n  \"Internacionální\",\n  \"Irkutská\",\n  \"Irská\",\n  \"Irvingova\",\n  \"Italská\",\n  \"Italská\",\n  \"Italská\",\n  \"Ivančická\",\n  \"Izraelská\",\n  \"Izraelská\",\n  \"Jabkenická\",\n  \"Jablonecká\",\n  \"Jablonecká\",\n  \"Jablonského\",\n  \"Jabloňová\",\n  \"Jablunkovská\",\n  \"Jagellonská\",\n  \"Jagellonská\",\n  \"Jahodnická\",\n  \"Jahodová\",\n  \"Jakobiho\",\n  \"Jakubovská\",\n  \"Jakubská\",\n  \"Jakutská\",\n  \"Jalodvorská\",\n  \"Jalovcová\",\n  \"Jaltská\",\n  \"Jamborova\",\n  \"Jamská\",\n  \"Jana Bílka\",\n  \"Jana Jindřicha\",\n  \"Jana Karafiáta\",\n  \"Jana Kašpara\",\n  \"Jana Marka\",\n  \"Jana Masaryka\",\n  \"Jana Ouřady\",\n  \"Jana Přibíka\",\n  \"Jana Růžičky\",\n  \"Jana Srba\",\n  \"Jana Zajíce\",\n  \"Jana Čerstvého\",\n  \"Jana Želivského\",\n  \"Janderova\",\n  \"Jandova\",\n  \"Janečkova\",\n  \"Jankovcova\",\n  \"Jankovská\",\n  \"Janouchova\",\n  \"Janouškova\",\n  \"Janovická\",\n  \"Janovská\",\n  \"Janovského\",\n  \"Jansenova\",\n  \"Janského\",\n  \"Jansova\",\n  \"Jantarová\",\n  \"Janákova\",\n  \"Janáčkovo Nábř.\",\n  \"Janáčkovo Nábř.\",\n  \"Janáčkovo Nábřeží\",\n  \"Janáčkovo Nábřeží\",\n  \"Janýrova\",\n  \"Jančova\",\n  \"Jarešova\",\n  \"Jarkovská\",\n  \"Jarmily Novotné\",\n  \"Jarní\",\n  \"Jarníkova\",\n  \"Jaromíra Jindry\",\n  \"Jaromíra Vejvody\",\n  \"Jaromírova\",\n  \"Jaroměřská\",\n  \"Jaroslava Foglara\",\n  \"Jaroslava Švehly\",\n  \"Jaroslavická\",\n  \"Jasanová\",\n  \"Jaselská\",\n  \"Jaselská\",\n  \"Jasenická\",\n  \"Jasenná\",\n  \"Jasmínová\",\n  \"Jasná I\",\n  \"Jasná Ii\",\n  \"Jaspisová\",\n  \"Jateční\",\n  \"Jaurisova\",\n  \"Jaurisova\",\n  \"Javorenská\",\n  \"Javornická\",\n  \"Javorová\",\n  \"Javorská\",\n  \"Javořická\",\n  \"Jašíkova\",\n  \"Jažlovická\",\n  \"Jedlová\",\n  \"Jednostranná\",\n  \"Jednostranná\",\n  \"Jednotného Zemědělského Družstva\",\n  \"Jednořadá\",\n  \"Jelenovská\",\n  \"Jelení\",\n  \"Jelínkova\",\n  \"Jemenská\",\n  \"Jemnická\",\n  \"Jenerálka\",\n  \"Jenečská\",\n  \"Jenišovská\",\n  \"Jenská\",\n  \"Jeníkovická\",\n  \"Jenštejnská\",\n  \"Jeremenkova\",\n  \"Jeremenkova\",\n  \"Jeremenkova\",\n  \"Jeremiášova\",\n  \"Jeremiášova\",\n  \"Jerevanská\",\n  \"Jeronýmova\",\n  \"Jeruzalémská\",\n  \"Jesenická\",\n  \"Jeseniova\",\n  \"Jestřebická\",\n  \"Jetelová\",\n  \"Jetřichovická\",\n  \"Jevanská\",\n  \"Jezdecká\",\n  \"Jezdovická\",\n  \"Jezerní\",\n  \"Jezerská\",\n  \"Jezevčí\",\n  \"Ječná\",\n  \"Jeřabinová\",\n  \"Jeřabinová\",\n  \"Jeřická\",\n  \"Jeřábkova\",\n  \"Jeřábnická\",\n  \"Jeřábová\",\n  \"Ješetická\",\n  \"Ještědská\",\n  \"Ježdíkova\",\n  \"Ježkova\",\n  \"Ježovická\",\n  \"Ježovická\",\n  \"Ježovská\",\n  \"Jihlavská\",\n  \"Jihovýchodní I\",\n  \"Jihovýchodní Ii\",\n  \"Jihovýchodní Iii\",\n  \"Jihovýchodní Iv\",\n  \"Jihovýchodní Ix\",\n  \"Jihovýchodní V\",\n  \"Jihovýchodní Vi\",\n  \"Jihovýchodní Vii\",\n  \"Jihovýchodní Viii\",\n  \"Jihozápadní I\",\n  \"Jihozápadní Ii\",\n  \"Jihozápadní Iii\",\n  \"Jihozápadní Iv\",\n  \"Jihozápadní V\",\n  \"Jihozápadní Vi\",\n  \"Jihočeská\",\n  \"Jilemnická\",\n  \"Jilemnická\",\n  \"Jilemnického\",\n  \"Jilmová\",\n  \"Jilská\",\n  \"Jindrova\",\n  \"Jindřicha Jindřicha\",\n  \"Jindřicha Plachty\",\n  \"Jindřichova\",\n  \"Jindřišská\",\n  \"Jinolická\",\n  \"Jinonická\",\n  \"Jinonická\",\n  \"Jinočanská\",\n  \"Jirenská\",\n  \"Jirečkova\",\n  \"Jirkovská\",\n  \"Jirsákova\",\n  \"Jirsíkova\",\n  \"Jiránkova\",\n  \"Jiráskovo Nám.\",\n  \"Jiráskovo Náměstí\",\n  \"Jirčanská\",\n  \"Jiskrova\",\n  \"Jistebnická\",\n  \"Jitkovská\",\n  \"Jitravská\",\n  \"Jitravská\",\n  \"Jitrocelová\",\n  \"Jitřní\",\n  \"Jivenská\",\n  \"Jizerská\",\n  \"Jičínská\",\n  \"Jičínská\",\n  \"Jiřická\",\n  \"Jiřinková\",\n  \"Jiřiny Štěpničkové\",\n  \"Jiřská\",\n  \"Jiřího Jandy\",\n  \"Jiřího Mašína\",\n  \"Jiřího Ze Vtelna\",\n  \"Jiříčkova\",\n  \"Jiříčkové\",\n  \"Jižní I\",\n  \"Jižní Ii\",\n  \"Jižní Iii\",\n  \"Jižní Iv\",\n  \"Jižní Ix\",\n  \"Jižní Nám.\",\n  \"Jižní Náměstí\",\n  \"Jižní Spojka\",\n  \"Jižní Spojka\",\n  \"Jižní Spojka\",\n  \"Jižní Spojka\",\n  \"Jižní V\",\n  \"Jižní Vi\",\n  \"Jižní Vii\",\n  \"Jižní Viii\",\n  \"Jižní Xi\",\n  \"Jižní Xii\",\n  \"Jižní Xiii\",\n  \"Jižní Xiv\",\n  \"Jižní Xv\",\n  \"Jižní Xvi\",\n  \"Jižní Xvii\",\n  \"Johanitská\",\n  \"Jordana Jovkova\",\n  \"Jordánská\",\n  \"Josefa Bíbrdlíka\",\n  \"Josefa Houdka\",\n  \"Josefa Houdka\",\n  \"Josefa Kočího\",\n  \"Josefa Němce\",\n  \"Josefa Vašíčka\",\n  \"Josefa Šimůnka\",\n  \"Josefská\",\n  \"José Martího\",\n  \"Juarézova\",\n  \"Jugoslávská\",\n  \"Jugoslávských Partyzánů\",\n  \"Jugoslávských Partyzánů\",\n  \"Jungmannova\",\n  \"Jungmannova\",\n  \"Jungmannovo Náměstí\",\n  \"Junácká\",\n  \"Jupiterova\",\n  \"Jurkovičova\",\n  \"Juárezova\",\n  \"Jzd\",\n  \"Jáchymova\",\n  \"Jáchymova\",\n  \"Jáchymovská\",\n  \"Jánošíkova\",\n  \"Jánská\",\n  \"Jánský Vršek\",\n  \"Jíchova\",\n  \"Jílkova\",\n  \"Jílovická\",\n  \"Jílovišťská\",\n  \"Jílovská\",\n  \"Jílovská\",\n  \"Jílová\",\n  \"Jírova\",\n  \"Jírovcovo Nám.\",\n  \"Jírovcovo Náměstí\",\n  \"Jívanská\",\n  \"Jívová\",\n  \"K Austisu\",\n  \"K Avii\",\n  \"K Barrandovu\",\n  \"K Bateriím\",\n  \"K Bažantnici\",\n  \"K Belvederu\",\n  \"K Berance\",\n  \"K Beranovu\",\n  \"K Berounce\",\n  \"K Beránku\",\n  \"K Betonárně\",\n  \"K Betáni\",\n  \"K Blatovu\",\n  \"K Bohnicím\",\n  \"K Borovíčku\",\n  \"K Botiči\",\n  \"K Brance\",\n  \"K Brnkám\",\n  \"K Brusce\",\n  \"K Brusce\",\n  \"K Brůdku\",\n  \"K Bílému Vrchu\",\n  \"K Běchovicům\",\n  \"K Březince\",\n  \"K Březiněvsi\",\n  \"K Břečkám\",\n  \"K Celinám\",\n  \"K Cementárně\",\n  \"K Chabům\",\n  \"K Chabům\",\n  \"K Chaloupce\",\n  \"K Chaloupkám\",\n  \"K Chatám\",\n  \"K Chmelnici\",\n  \"K Chumberku\",\n  \"K Cihelně\",\n  \"K Cikánce\",\n  \"K Cíli\",\n  \"K Dalejím\",\n  \"K Dobré Vodě\",\n  \"K Dobré Vodě\",\n  \"K Dolům\",\n  \"K Drahani\",\n  \"K Drahani\",\n  \"K Drazdům\",\n  \"K Drsnici\",\n  \"K Dubinám\",\n  \"K Dubovému Mlýnu\",\n  \"K Dubu\",\n  \"K Dubči\",\n  \"K Dálnici\",\n  \"K Dálnici\",\n  \"K Dýmači\",\n  \"K Děrám\",\n  \"K Fantovu Mlýnu\",\n  \"K Farkám\",\n  \"K Fialce\",\n  \"K Fišpance\",\n  \"K Habrovce\",\n  \"K Habru\",\n  \"K Haltýři\",\n  \"K Havlínu\",\n  \"K Hluboké Cestě\",\n  \"K Hlásku\",\n  \"K Holyni\",\n  \"K Holému Vrchu\",\n  \"K Holému Vrchu\",\n  \"K Homolce\",\n  \"K Horkám\",\n  \"K Horkám\",\n  \"K Horkám\",\n  \"K Horním Počernicím\",\n  \"K Horoměřicům\",\n  \"K Hořavce\",\n  \"K Hradišti\",\n  \"K Hrnčířům\",\n  \"K Hrušovu\",\n  \"K Hrušovu\",\n  \"K Hrázi\",\n  \"K Hutím\",\n  \"K Hutím\",\n  \"K Hutím\",\n  \"K Hádku\",\n  \"K Háječku\",\n  \"K Háji\",\n  \"K Háji\",\n  \"K Hájku\",\n  \"K Hájovně\",\n  \"K Hájovně\",\n  \"K Hájovně\",\n  \"K Hájům\",\n  \"K Hárunce\",\n  \"K Interně\",\n  \"K Jalovce\",\n  \"K Jasánkám\",\n  \"K Jelenu\",\n  \"K Jelenám\",\n  \"K Jezeru\",\n  \"K Jezeru\",\n  \"K Jezu\",\n  \"K Jezírku\",\n  \"K Jihu\",\n  \"K Jihu\",\n  \"K Jinočanům\",\n  \"K Jinočanům\",\n  \"K Jižnímu Městu\",\n  \"K Juliáně\",\n  \"K Jízdárně\",\n  \"K Labeškám\",\n  \"K Ladům\",\n  \"K Lahovičkám\",\n  \"K Lahovské\",\n  \"K Lažance\",\n  \"K Lesoparku\",\n  \"K Lesu\",\n  \"K Lesu\",\n  \"K Lesíku\",\n  \"K Letišti\",\n  \"K Letňanům\",\n  \"K Libuši\",\n  \"K Lindě\",\n  \"K Lipanům\",\n  \"K Lipinám\",\n  \"K Lipám\",\n  \"K Lochkovu\",\n  \"K Lomu\",\n  \"K Louži\",\n  \"K Luhu\",\n  \"K Lukám\",\n  \"K Lučinám\",\n  \"K Lužinám\",\n  \"K Ládví\",\n  \"K Ládví\",\n  \"K Lánu\",\n  \"K Lávce\",\n  \"K Lázním\",\n  \"K Lípě\",\n  \"K Markétě\",\n  \"K Matěji\",\n  \"K Mejtu\",\n  \"K Metru\",\n  \"K Metru\",\n  \"K Milíčovu\",\n  \"K Mlíčníku\",\n  \"K Mlýnu\",\n  \"K Modřanskému Nádraží\",\n  \"K Mohyle\",\n  \"K Moravině\",\n  \"K Moravině\",\n  \"K Mostku\",\n  \"K Mostu\",\n  \"K Motelu\",\n  \"K Motolu\",\n  \"K Mírám\",\n  \"K Měcholupům\",\n  \"K Měchurce\",\n  \"K Nedvězí\",\n  \"K Netlukám\",\n  \"K Noskovně\",\n  \"K Nouzovu\",\n  \"K Nové Vsi\",\n  \"K Nové Vsi\",\n  \"K Nové Škole\",\n  \"K Novému Dvoru\",\n  \"K Novému Hradu\",\n  \"K Novému Sídlišti\",\n  \"K Novým Domkům\",\n  \"K Nádraží\",\n  \"K Nádrži\",\n  \"K Náhonu\",\n  \"K Náměstí\",\n  \"K Náplavce\",\n  \"K Náplavce\",\n  \"K Návrší\",\n  \"K Návrší\",\n  \"K Návsi\",\n  \"K Obci\",\n  \"K Obecním Hájovnám\",\n  \"K Oboře\",\n  \"K Obsinám\",\n  \"K Ochozu\",\n  \"K Ohradě\",\n  \"K Okrouhlíku\",\n  \"K Olympiku\",\n  \"K Opatřilce\",\n  \"K Opatřilce\",\n  \"K Oplocení\",\n  \"K Orionce\",\n  \"K Osmidomkům\",\n  \"K Otočce\",\n  \"K Ovčínu\",\n  \"K Ovčínu\",\n  \"K Padesátníku\",\n  \"K Palečku\",\n  \"K Panenkám\",\n  \"K Parku\",\n  \"K Pastvinám\",\n  \"K Pazderkám\",\n  \"K Pekárně\",\n  \"K Peluňku\",\n  \"K Petrově Komoře\",\n  \"K Pitkovicům\",\n  \"K Podchodu\",\n  \"K Podjezdu\",\n  \"K Podjezdu\",\n  \"K Polím\",\n  \"K Pomníku\",\n  \"K Popelce\",\n  \"K Popelce\",\n  \"K Potoku\",\n  \"K Poště\",\n  \"K Pramenu\",\n  \"K Prelátům\",\n  \"K Prádelně\",\n  \"K Průhonicům\",\n  \"K Průhonu\",\n  \"K Průmstavu\",\n  \"K Pyramidce\",\n  \"K Pérovně\",\n  \"K Pískovně\",\n  \"K Písnici\",\n  \"K Přehradám\",\n  \"K Přejezdu\",\n  \"K Přístavišti\",\n  \"K Přívozu\",\n  \"K Radhošti\",\n  \"K Radonicům\",\n  \"K Radotínu\",\n  \"K Radotínu\",\n  \"K Remízku\",\n  \"K Rokli\",\n  \"K Rokytce\",\n  \"K Rotundě\",\n  \"K Rovinám\",\n  \"K Rozkoši\",\n  \"K Rozmezí\",\n  \"K Roztokům\",\n  \"K Rozvodně\",\n  \"K Rukavičkárně\",\n  \"K Rybníku\",\n  \"K Rybníčku\",\n  \"K Rybníčkům\",\n  \"K Rybárně\",\n  \"K Ryšánce\",\n  \"K Ryšánce\",\n  \"K Sadu\",\n  \"K Safině\",\n  \"K Samoobsluze\",\n  \"K Samotě\",\n  \"K Sedlišti\",\n  \"K Sibřině\",\n  \"K Sokolovně\",\n  \"K Sopce\",\n  \"K Sopce\",\n  \"K Starému Bubenči\",\n  \"K Starému Lomu\",\n  \"K Stavebninám\",\n  \"K Sukovu\",\n  \"K Sádkám\",\n  \"K Sádkám\",\n  \"K Sídlišti\",\n  \"K Sídlišti\",\n  \"K Teplárně\",\n  \"K Topolům\",\n  \"K Topírně\",\n  \"K Transformátoru\",\n  \"K Trati\",\n  \"K Trninám\",\n  \"K Trnkám\",\n  \"K Trníčku\",\n  \"K Truhlářce\",\n  \"K Tržišti\",\n  \"K Tuchoměřicům\",\n  \"K Táboru\",\n  \"K Třebonicům\",\n  \"K Třešňovce\",\n  \"K Tůni\",\n  \"K Ubytovnám\",\n  \"K Uhříněvsi\",\n  \"K Uhříněvsi\",\n  \"K Učilišti\",\n  \"K Valu\",\n  \"K Vejvoďáku\",\n  \"K Velké Ohradě\",\n  \"K Velké Ohradě\",\n  \"K Velkému Dvoru\",\n  \"K Verneráku\",\n  \"K Viaduktu\",\n  \"K Vidouli\",\n  \"K Vilkám\",\n  \"K Vinici\",\n  \"K Vinicím\",\n  \"K Vinoři\",\n  \"K Vizerce\",\n  \"K Višňovce\",\n  \"K Višňovce\",\n  \"K Višňovému Sadu\",\n  \"K Vltavě\",\n  \"K Vlásence\",\n  \"K Vodici\",\n  \"K Vodojemu\",\n  \"K Vodárně\",\n  \"K Vodě\",\n  \"K Vrbičkám\",\n  \"K Vrbě\",\n  \"K Vrcholu\",\n  \"K Vrtilce\",\n  \"K Vršíčku\",\n  \"K Vyhlídce\",\n  \"K Vysoké Cestě\",\n  \"K Vystrkovu\",\n  \"K Václavce\",\n  \"K Vápence\",\n  \"K Váze\",\n  \"K Výboru\",\n  \"K Výtopně\",\n  \"K Výzkumným Ústavům\",\n  \"K Větrolamu\",\n  \"K Zabrkům\",\n  \"K Zadní Kopanině\",\n  \"K Zadní Kopanině\",\n  \"K Zahradnictví\",\n  \"K Zahradám\",\n  \"K Zahrádkám\",\n  \"K Zastávce\",\n  \"K Zatáčce\",\n  \"K Zelené Louce\",\n  \"K Zeleným Domkům\",\n  \"K Zelenči\",\n  \"K Zámku\",\n  \"K Zátiší\",\n  \"K Závodišti\",\n  \"K Závorám\",\n  \"K Závěrce\",\n  \"K Závětinám\",\n  \"K Údolí\",\n  \"K Údolí Hvězd\",\n  \"K Újezdu\",\n  \"K Ústavu\",\n  \"K Úvozu\",\n  \"K Černošicím\",\n  \"K Červenému Dvoru\",\n  \"K Červenému Dvoru\",\n  \"K Červenému Dvoru\",\n  \"K Červenému Vrchu\",\n  \"K Čestlicům\",\n  \"K Čihadlům\",\n  \"K Ďáblicům\",\n  \"K Řece\",\n  \"K Řeporyjím\",\n  \"K Řeporyjím\",\n  \"K Říčanům\",\n  \"K Šafránce\",\n  \"K Šafránce\",\n  \"K Šancím\",\n  \"K Šeberovu\",\n  \"K Šeberáku\",\n  \"K Šedivce\",\n  \"K Šubrtce\",\n  \"K Železnici\",\n  \"K Žižkovu\",\n  \"Kabeláčova\",\n  \"Kabešova\",\n  \"Kabátové\",\n  \"Kadaňská\",\n  \"Kadeřávkovská\",\n  \"Kafkova\",\n  \"Kahovská\",\n  \"Kaizlovy Sady\",\n  \"Kakosova\",\n  \"Kakostová\",\n  \"Kalabisova\",\n  \"Kalašova\",\n  \"Kalinová\",\n  \"Kališnická\",\n  \"Kališťská\",\n  \"Kalská\",\n  \"Kalvodova\",\n  \"Kamelova\",\n  \"Kamencová\",\n  \"Kamenická\",\n  \"Kamenická\",\n  \"Kamenitá\",\n  \"Kamenná\",\n  \"Kameníků\",\n  \"Kamerunská\",\n  \"Kampanova\",\n  \"Kamzíková\",\n  \"Kamýcká\",\n  \"Kamýcká\",\n  \"Kamýcká\",\n  \"Kanadská\",\n  \"Kandertova\",\n  \"Kanovnická\",\n  \"Kapitulská\",\n  \"Kaplanova\",\n  \"Kaplická\",\n  \"Kapraďová\",\n  \"Kaprova\",\n  \"Kaprova\",\n  \"Kapucínská\",\n  \"Karafiátová\",\n  \"Karasova\",\n  \"Karasovská\",\n  \"Kardausova\",\n  \"Kardašovská\",\n  \"Kardašovská\",\n  \"Karenova\",\n  \"Karfíkova\",\n  \"Karla Engliše\",\n  \"Karla Hlaváčka\",\n  \"Karla Kryla\",\n  \"Karla Křížka\",\n  \"Karla Michala\",\n  \"Karla Rachůnka\",\n  \"Karla Tomáše\",\n  \"Karla Zicha\",\n  \"Karla Černého\",\n  \"Karlická\",\n  \"Karlova\",\n  \"Karlovarská\",\n  \"Karlovarská\",\n  \"Karlovická\",\n  \"Karlovo Nám.\",\n  \"Karlovo Nám.\",\n  \"Karlovo Náměstí\",\n  \"Karlovo Náměstí\",\n  \"Karlínské Nám.\",\n  \"Karlínské Náměstí\",\n  \"Karlštejnská\",\n  \"Karmelitská\",\n  \"Karolinská\",\n  \"Karoliny Světlé\",\n  \"Karpatská\",\n  \"Kartounářů\",\n  \"Kartouzská\",\n  \"Kasalická\",\n  \"Kateřinská\",\n  \"Kateřinské Nám.\",\n  \"Kateřinské Náměstí\",\n  \"Katovická\",\n  \"Katusická\",\n  \"Kavkazská\",\n  \"Kazaňská\",\n  \"Kazašská\",\n  \"Kazimírova\",\n  \"Kaznějovská\",\n  \"Kazín\",\n  \"Kazínská\",\n  \"Kačerovská\",\n  \"Kačínská\",\n  \"Kaňkova\",\n  \"Kaňkovského\",\n  \"Kaňovská\",\n  \"Kašeho\",\n  \"Kaškova\",\n  \"Kašovická\",\n  \"Kašparovo Nám.\",\n  \"Kašparovo Náměstí\",\n  \"Kašperská\",\n  \"Kaštanová\",\n  \"Kbelská\",\n  \"Kbelská\",\n  \"Kbelská\",\n  \"Kbelská\",\n  \"Kdoulová\",\n  \"Ke Březině\",\n  \"Ke Břvům\",\n  \"Ke Cvičišti\",\n  \"Ke Dračkám\",\n  \"Ke Dráze\",\n  \"Ke Dvoru\",\n  \"Ke Džbánu\",\n  \"Ke Garážím\",\n  \"Ke Golfu\",\n  \"Ke Goniu\",\n  \"Ke Hlásce\",\n  \"Ke Hrádku\",\n  \"Ke Hrázi\",\n  \"Ke Hrázi\",\n  \"Ke Hřbitovu\",\n  \"Ke Hřišti\",\n  \"Ke Kablu\",\n  \"Ke Kablu\",\n  \"Ke Kalvárii\",\n  \"Ke Kaménce\",\n  \"Ke Kamínce\",\n  \"Ke Kamýku\",\n  \"Ke Kapličce\",\n  \"Ke Kapslovně\",\n  \"Ke Karlovu\",\n  \"Ke Kateřinkám\",\n  \"Ke Kazínu\",\n  \"Ke Kašně\",\n  \"Ke Kinu\",\n  \"Ke Kladivům\",\n  \"Ke Klimentce\",\n  \"Ke Klubovně\",\n  \"Ke Klínku\",\n  \"Ke Klínku\",\n  \"Ke Klíčovu\",\n  \"Ke Koh-I-Nooru\",\n  \"Ke Kolodějskému Zámku\",\n  \"Ke Kolodějům\",\n  \"Ke Kolonii\",\n  \"Ke Konstruktivě\",\n  \"Ke Kopečku\",\n  \"Ke Korunce\",\n  \"Ke Kostelu\",\n  \"Ke Kostelíčku\",\n  \"Ke Kotlářce\",\n  \"Ke Koulce\",\n  \"Ke Koupališti\",\n  \"Ke Kovárně\",\n  \"Ke Kozím Hřbetům\",\n  \"Ke Královicům\",\n  \"Ke Krči\",\n  \"Ke Krčské Stráni\",\n  \"Ke Kulišce\",\n  \"Ke Kulturnímu Domu\",\n  \"Ke Kurtům\",\n  \"Ke Kyjovu\",\n  \"Ke Kálku\",\n  \"Ke Křížku\",\n  \"Ke Křížkám\",\n  \"Ke Lhoteckému Lesu\",\n  \"Ke Mlýnku\",\n  \"Ke Mlýnu\",\n  \"Ke Mlýnu\",\n  \"Ke Schodům\",\n  \"Ke Skalce\",\n  \"Ke Skalkám\",\n  \"Ke Skladům\",\n  \"Ke Sklárně\",\n  \"Ke Skále\",\n  \"Ke Slatinám\",\n  \"Ke Slivenci\",\n  \"Ke Smrčině\",\n  \"Ke Smíchovu\",\n  \"Ke Smíchovu\",\n  \"Ke Splávku\",\n  \"Ke Spofě\",\n  \"Ke Spořilovu\",\n  \"Ke Spálence\",\n  \"Ke Srážku\",\n  \"Ke Stadionu\",\n  \"Ke Stanici\",\n  \"Ke Starému Hřišti\",\n  \"Ke Starým Rybníkům\",\n  \"Ke Stinkovskému Rybníku\",\n  \"Ke Strašnické\",\n  \"Ke Strouze\",\n  \"Ke Stráni\",\n  \"Ke Strži\",\n  \"Ke Studni\",\n  \"Ke Studni\",\n  \"Ke Studánce\",\n  \"Ke Stupicím\",\n  \"Ke Stáčírně\",\n  \"Ke Stírce\",\n  \"Ke Střelnici\",\n  \"Ke Střelnici\",\n  \"Ke Sv. Izidoru\",\n  \"Ke Třem Mostům\",\n  \"Ke Xaverovu\",\n  \"Ke Zbraslavi\",\n  \"Ke Zbrojnici\",\n  \"Ke Zbuzanům\",\n  \"Ke Zdibům\",\n  \"Ke Zdravotnímu Středisku\",\n  \"Ke Zděři\",\n  \"Ke Zlatému Kopci\",\n  \"Ke Zličínu\",\n  \"Ke Znaku\",\n  \"Ke Zvonici\",\n  \"Ke Zvoničce\",\n  \"Ke Školce\",\n  \"Ke Škole\",\n  \"Ke Šmejkalu\",\n  \"Ke Štvanici\",\n  \"Ke Štítu\",\n  \"Ke Štěpcům\",\n  \"Ke Štěrkovně\",\n  \"Ke Švestkovce\",\n  \"Kecova\",\n  \"Kejhova\",\n  \"Kejnická\",\n  \"Kellnerova\",\n  \"Keltská\",\n  \"Keltů\",\n  \"Kelvinova\",\n  \"Kemrova\",\n  \"Keplerova\",\n  \"Keplerova\",\n  \"Keramická\",\n  \"Kesnerka\",\n  \"Kestřanská\",\n  \"Keteňská\",\n  \"Kettnerova\",\n  \"Keřová\",\n  \"Khodlova\",\n  \"Kischova\",\n  \"Kišiněvská\",\n  \"Kladenská\",\n  \"Kladenská\",\n  \"Kladenská\",\n  \"Kladinovská\",\n  \"Kladrubská\",\n  \"Kladská\",\n  \"Klamovka\",\n  \"Klapkova\",\n  \"Klapálkova\",\n  \"Klatovská\",\n  \"Klausova\",\n  \"Klecandova\",\n  \"Klecanská\",\n  \"Klenečská\",\n  \"Klenovická\",\n  \"Klenovská\",\n  \"Klenová\",\n  \"Klečkova\",\n  \"Klečákova\",\n  \"Klešická\",\n  \"Klicperova\",\n  \"Klidná\",\n  \"Klihařská\",\n  \"Klikatá\",\n  \"Klikatá\",\n  \"Klimentská\",\n  \"Klivarova\",\n  \"Kloboukova\",\n  \"Kloboučnická\",\n  \"Kloknerova\",\n  \"Klokotská\",\n  \"Klostermannova\",\n  \"Klouzková\",\n  \"Kludských\",\n  \"Klukovická\",\n  \"Klánova\",\n  \"Klánova\",\n  \"Klánova\",\n  \"Klánovická\",\n  \"Klánovická\",\n  \"Klárov\",\n  \"Klášterecká\",\n  \"Klášterská\",\n  \"Klášterského\",\n  \"Klímova\",\n  \"Klímova\",\n  \"Klínecká\",\n  \"Klínovecká\",\n  \"Klínová\",\n  \"Klírova\",\n  \"Klíčanská\",\n  \"Klíčova\",\n  \"Klíčovská\",\n  \"Klíčovská\",\n  \"Kmochova\",\n  \"Knínická\",\n  \"Kněževeská\",\n  \"Kněžická\",\n  \"Koberkova\",\n  \"Kobrova\",\n  \"Kobyliská\",\n  \"Kobyliské Nám.\",\n  \"Kobyliské Náměstí\",\n  \"Kobylákova\",\n  \"Kochanova\",\n  \"Kocianova\",\n  \"Koclířova\",\n  \"Kocourova\",\n  \"Kodaňská\",\n  \"Kodicilova\",\n  \"Kodymova\",\n  \"Kohoutovská\",\n  \"Kohoutových\",\n  \"Kojetická\",\n  \"Kojická\",\n  \"Kokořínská\",\n  \"Kolbenova\",\n  \"Kolbenova\",\n  \"Kolbenova\",\n  \"Koldínova\",\n  \"Kolejní\",\n  \"Kolektivní\",\n  \"Kolešovská\",\n  \"Kollárova\",\n  \"Kolmistrova\",\n  \"Kolmá\",\n  \"Kolocova\",\n  \"Kolodějská\",\n  \"Kolonie U Obecní Cihelny\",\n  \"Kolonka\",\n  \"Kolovečská\",\n  \"Kolovratská\",\n  \"Kolová\",\n  \"Kolátorova\",\n  \"Koláčkova\",\n  \"Koláře Kaliny\",\n  \"Kolářova\",\n  \"Kolínova\",\n  \"Kolínská\",\n  \"Kolčavka\",\n  \"Komenského Nám.\",\n  \"Komenského Náměstí\",\n  \"Komornická\",\n  \"Komořanská\",\n  \"Komořanská\",\n  \"Komořanská\",\n  \"Komunardů\",\n  \"Komárkova\",\n  \"Komárovská\",\n  \"Koncová\",\n  \"Konecchlumského\",\n  \"Konečná\",\n  \"Kongresová\",\n  \"Konojedská\",\n  \"Konopišťská\",\n  \"Konopova\",\n  \"Konopáskova\",\n  \"Konstantinova\",\n  \"Konvalinková\",\n  \"Konviktská\",\n  \"Konzumní\",\n  \"Konzumní\",\n  \"Koníčkovo Nám.\",\n  \"Koníčkovo Náměstí\",\n  \"Konětopská\",\n  \"Koněvova\",\n  \"Konšelská\",\n  \"Konžská\",\n  \"Kopalova\",\n  \"Kopanina\",\n  \"Kopanská\",\n  \"Kopeckého\",\n  \"Koperníkova\",\n  \"Kopečná\",\n  \"Kopretinová\",\n  \"Kopřivnická\",\n  \"Korandova\",\n  \"Korandova\",\n  \"Korunní\",\n  \"Korunní\",\n  \"Korunní\",\n  \"Korunovační\",\n  \"Korunovační\",\n  \"Korybutova\",\n  \"Korycanská\",\n  \"Korytná\",\n  \"Kosatcová\",\n  \"Kosařova\",\n  \"Kosmická\",\n  \"Kosmonoská\",\n  \"Kosova\",\n  \"Kosořická\",\n  \"Kosořská\",\n  \"Kostelecká\",\n  \"Kostelecká\",\n  \"Kostelní\",\n  \"Kostelní Náměstí\",\n  \"Kostečná\",\n  \"Kostková\",\n  \"Kostlivého\",\n  \"Kostnické Nám.\",\n  \"Kostnické Náměstí\",\n  \"Kostomlatská\",\n  \"Kostrbova\",\n  \"Kostřínská\",\n  \"Kosárkovo Nábř.\",\n  \"Kosárkovo Nábřeží\",\n  \"Kosí\",\n  \"Koterovská\",\n  \"Koterovská\",\n  \"Kotevní\",\n  \"Kotlaska\",\n  \"Kotlářka\",\n  \"Kotorská\",\n  \"Kotovka\",\n  \"Kotrčová\",\n  \"Kotršálova\",\n  \"Kotíkova\",\n  \"Kotěrova\",\n  \"Koubkova\",\n  \"Koubkova\",\n  \"Koubova\",\n  \"Koukolová\",\n  \"Koulka\",\n  \"Koulova\",\n  \"Kounická\",\n  \"Kounovská\",\n  \"Koutská\",\n  \"Kouřimská\",\n  \"Kovanecká\",\n  \"Kovařovicova\",\n  \"Kovriginova\",\n  \"Kováků\",\n  \"Kovárenská\",\n  \"Kovářova\",\n  \"Kovářská\",\n  \"Kováříkova\",\n  \"Kozinova\",\n  \"Kozinovo Náměstí\",\n  \"Kozlova\",\n  \"Kozlovská\",\n  \"Kozmíkova\",\n  \"Kozomínská\",\n  \"Kozácká\",\n  \"Kozákovská\",\n  \"Kozáková\",\n  \"Kozí\",\n  \"Kočova\",\n  \"Kořenského\",\n  \"Košařova\",\n  \"Košická\",\n  \"Koštířova\",\n  \"Košátecká\",\n  \"Košíkářská\",\n  \"Košířské Nám.\",\n  \"Košířské Náměstí\",\n  \"Košťálkova\",\n  \"Koťátkova\",\n  \"Koželužská\",\n  \"Kožlanská\",\n  \"Kožná\",\n  \"Kožíškova\",\n  \"Kpt. Nálepky\",\n  \"Kpt. Stránského\",\n  \"Krabošická\",\n  \"Krahulčí\",\n  \"Krajanská\",\n  \"Krajní\",\n  \"Krajová\",\n  \"Krajánkova\",\n  \"Krakovská\",\n  \"Kralická\",\n  \"Kralupská\",\n  \"Krameriova\",\n  \"Kramlova\",\n  \"Kramolná\",\n  \"Kramolínská\",\n  \"Kramperova\",\n  \"Kraslická\",\n  \"Krasnická\",\n  \"Krasnojarská\",\n  \"Kratochvílova\",\n  \"Krausova\",\n  \"Krbická\",\n  \"Krchlebská\",\n  \"Krejnická\",\n  \"Krejčího\",\n  \"Kremličkova\",\n  \"Kremnická\",\n  \"Kremnická\",\n  \"Krhanická\",\n  \"Krhanická\",\n  \"Kristiánova\",\n  \"Kriváňská\",\n  \"Krkonošská\",\n  \"Krnovská\",\n  \"Krnská\",\n  \"Krocínova\",\n  \"Krocínovská\",\n  \"Kroftova\",\n  \"Krohova\",\n  \"Krokova\",\n  \"Krolmusova\",\n  \"Kropáčkova\",\n  \"Krosenská\",\n  \"Kroupova\",\n  \"Kroupova\",\n  \"Krouzova\",\n  \"Krovova\",\n  \"Krteňská\",\n  \"Kruhová\",\n  \"Krumlovská\",\n  \"Krupkovo Nám.\",\n  \"Krupkovo Náměstí\",\n  \"Krupná\",\n  \"Krupská\",\n  \"Krušovická\",\n  \"Kružberská\",\n  \"Krylovecká\",\n  \"Krylovecká\",\n  \"Krymská\",\n  \"Krynická\",\n  \"Krystalová\",\n  \"Kryšpínova\",\n  \"Kryštofova\",\n  \"Krále Václava Iv.\",\n  \"Králodvorská\",\n  \"Králova\",\n  \"Královická\",\n  \"Královny Žofie\",\n  \"Královská Obora\",\n  \"Královská Obora\",\n  \"Krásnolipská\",\n  \"Krásného\",\n  \"Krásova\",\n  \"Krátká\",\n  \"Krátká\",\n  \"Krátkého\",\n  \"Krátký Lán\",\n  \"Krčmářovská\",\n  \"Krčská\",\n  \"Krčínovo Nám.\",\n  \"Krčínovo Náměstí\",\n  \"Krčínská\",\n  \"Krňovická\",\n  \"Krškova\",\n  \"Kubatova\",\n  \"Kubaštova\",\n  \"Kubelíkova\",\n  \"Kubišova\",\n  \"Kubištova\",\n  \"Kubova\",\n  \"Kubánské Nám.\",\n  \"Kubánské Náměstí\",\n  \"Kubíkova\",\n  \"Kubínova\",\n  \"Kuchařská\",\n  \"Kudeříkové\",\n  \"Kudrnova\",\n  \"Kukelská\",\n  \"Kukelská\",\n  \"Kukulova\",\n  \"Kukulova\",\n  \"Kukučínova\",\n  \"Kulhavého\",\n  \"Kulhánkovská\",\n  \"Kuncova\",\n  \"Kundratka\",\n  \"Kunešova\",\n  \"Kunická\",\n  \"Kunratická\",\n  \"Kunratická Spojka\",\n  \"Kunratická Spojka\",\n  \"Kuní\",\n  \"Kuní\",\n  \"Kunínova\",\n  \"Kunčická\",\n  \"Kunětická\",\n  \"Kupeckého\",\n  \"Kupkova\",\n  \"Kurandové\",\n  \"Kurkova\",\n  \"Kurta Konráda\",\n  \"Kurzova\",\n  \"Kurčatovova\",\n  \"Kusá\",\n  \"Kusého\",\n  \"Kutilova\",\n  \"Kutnauerovo Náměstí\",\n  \"Kutnohorská\",\n  \"Kutnohorská\",\n  \"Kutrovická\",\n  \"Kuttelwascherova\",\n  \"Kutvirtova\",\n  \"Kučerova\",\n  \"Kučerové\",\n  \"Kuťatská\",\n  \"Kuželova\",\n  \"Kvapilova\",\n  \"Kvasinská\",\n  \"Kvestorská\",\n  \"Květinková\",\n  \"Květinářská\",\n  \"Květnická\",\n  \"Květnová\",\n  \"Květnového Povstání\",\n  \"Květnového Povstání\",\n  \"Květnového Vítězství\",\n  \"Květnového Vítězství\",\n  \"Květná\",\n  \"Květoslavova\",\n  \"Květová\",\n  \"Kyjevská\",\n  \"Kyjevská\",\n  \"Kyjovská\",\n  \"Kyjská\",\n  \"Kyjská\",\n  \"Kykalova\",\n  \"Kymrova\",\n  \"Kynická\",\n  \"Kyselova\",\n  \"Kyslíková\",\n  \"Kysucká\",\n  \"Kysúcká\",\n  \"Kytlická\",\n  \"Kytínská\",\n  \"Kácovská\",\n  \"Kádnerova\",\n  \"Kálikova\",\n  \"Kálmánova\",\n  \"Káranská\",\n  \"Křejpského\",\n  \"Křelovická\",\n  \"Křemelná\",\n  \"Křemencova\",\n  \"Křemenná\",\n  \"Křemenáčová\",\n  \"Křemílkova\",\n  \"Křenická\",\n  \"Křenova\",\n  \"Křepelčí\",\n  \"Křepelčí\",\n  \"Křesadlova\",\n  \"Křesanovská\",\n  \"Křeslická\",\n  \"Křesomyslova\",\n  \"Křešínská\",\n  \"Křimická\",\n  \"Křimovská\",\n  \"Křivatcová\",\n  \"Křivenická\",\n  \"Křivoklátská\",\n  \"Křivá\",\n  \"Křičkova\",\n  \"Křišťanova\",\n  \"Křišťálová\",\n  \"Křižovnická\",\n  \"Křižovnické Nám.\",\n  \"Křižovnické Náměstí\",\n  \"Křižíkova\",\n  \"Křižíkova\",\n  \"Křovinovo Nám.\",\n  \"Křovinovo Náměstí\",\n  \"Křtinská\",\n  \"Kříženeckého Nám.\",\n  \"Kříženeckého Náměstí\",\n  \"Křížkovského\",\n  \"Křížová\",\n  \"Křížová\",\n  \"Labská\",\n  \"Labětínská\",\n  \"Ladislava Coňka\",\n  \"Ladova\",\n  \"Laglerové\",\n  \"Lahovská\",\n  \"Lahovská\",\n  \"Lamačova\",\n  \"Langweilova\",\n  \"Lannova\",\n  \"Lanýžová\",\n  \"Lanžhotská\",\n  \"Lanžovská\",\n  \"Laténská\",\n  \"Laubova\",\n  \"Laudonova\",\n  \"Laudova\",\n  \"Laurinova\",\n  \"Lazarská\",\n  \"Lazarská\",\n  \"Lačnovská\",\n  \"Lažanská\",\n  \"Lažanská\",\n  \"Lažanského\",\n  \"Lebeděvova\",\n  \"Ledařská\",\n  \"Ledecká\",\n  \"Ledečská\",\n  \"Ledkovská\",\n  \"Lednická\",\n  \"Lednová\",\n  \"Ledvická\",\n  \"Ledvinova\",\n  \"Ledč\",\n  \"Ledčická\",\n  \"Legerova\",\n  \"Legerova\",\n  \"Legerova\",\n  \"Legerova\",\n  \"Legionářů\",\n  \"Lehárova\",\n  \"Leitzova\",\n  \"Leknínová\",\n  \"Leopoldova\",\n  \"Leskovecká\",\n  \"Lesnická\",\n  \"Lesného\",\n  \"Lesní\",\n  \"Lessnerova\",\n  \"Lesáků\",\n  \"Letců\",\n  \"Letecká\",\n  \"Letenská\",\n  \"Letenské Nám.\",\n  \"Letenské Nám.\",\n  \"Letenské Náměstí\",\n  \"Letenské Náměstí\",\n  \"Letenské Sady\",\n  \"Letní\",\n  \"Letohradská\",\n  \"Letovská\",\n  \"Letňanská\",\n  \"Letňanská\",\n  \"Levandulová\",\n  \"Levobřežní\",\n  \"Levského\",\n  \"Levá\",\n  \"Lexova\",\n  \"Lečkova\",\n  \"Lešanská\",\n  \"Lešenská\",\n  \"Lešetínská\",\n  \"Lešovská\",\n  \"Leštínská\",\n  \"Lhenická\",\n  \"Lhotecká\",\n  \"Lhotecká\",\n  \"Lhotská\",\n  \"Lhotákova\",\n  \"Liberecká\",\n  \"Liberijská\",\n  \"Libečkova\",\n  \"Libeňská\",\n  \"Libeňský Ostrov\",\n  \"Libeňský Ostrov\",\n  \"Libeřská\",\n  \"Libichovská\",\n  \"Libická\",\n  \"Libišanská\",\n  \"Libišská\",\n  \"Libkovská\",\n  \"Liblická\",\n  \"Liblická\",\n  \"Libochovická\",\n  \"Libocká\",\n  \"Liborova\",\n  \"Libotovská\",\n  \"Libovická\",\n  \"Libočanská\",\n  \"Liboňovská\",\n  \"Libošovická\",\n  \"Libuňská\",\n  \"Libušina\",\n  \"Libušská\",\n  \"Libušská\",\n  \"Libušská\",\n  \"Libušská\",\n  \"Libáňská\",\n  \"Libínská\",\n  \"Libčanská\",\n  \"Libčická\",\n  \"Liběchovská\",\n  \"Libědická\",\n  \"Liběšická\",\n  \"Libřická\",\n  \"Lichá\",\n  \"Lidečská\",\n  \"Lidická\",\n  \"Lidického\",\n  \"Lihovarská\",\n  \"Liliová\",\n  \"Lilková\",\n  \"Limuzská\",\n  \"Limuzská\",\n  \"Lindavská\",\n  \"Lindleyova\",\n  \"Lindnerova\",\n  \"Linhartova\",\n  \"Linhartská\",\n  \"Lipanská\",\n  \"Lipecká\",\n  \"Lipenecká\",\n  \"Lipenská\",\n  \"Lipenská\",\n  \"Lipenské Nám.\",\n  \"Lipenské Náměstí\",\n  \"Lipnická\",\n  \"Lipoltická\",\n  \"Lipovická\",\n  \"Lipovská\",\n  \"Lipová Alej\",\n  \"Lipové Náměstí\",\n  \"Lipského\",\n  \"Lipí\",\n  \"Lisabonská\",\n  \"Lisabonská\",\n  \"Listopadová\",\n  \"Lisztova\",\n  \"Litavská\",\n  \"Litevská\",\n  \"Litická\",\n  \"Litochlebská\",\n  \"Litoměřická\",\n  \"Litoměřická\",\n  \"Litovická\",\n  \"Litošická\",\n  \"Litošická\",\n  \"Litožnická\",\n  \"Litvínovská\",\n  \"Litvínovská\",\n  \"Livornská\",\n  \"Lišanská\",\n  \"Lišická\",\n  \"Liškova\",\n  \"Lišovická\",\n  \"Liščí\",\n  \"Liščí\",\n  \"Lnářská\",\n  \"Lobečská\",\n  \"Lochenická\",\n  \"Lochkovská\",\n  \"Lochotínská\",\n  \"Lodecká\",\n  \"Lodní Mlýny\",\n  \"Loděnická\",\n  \"Lodžská\",\n  \"Lodžská\",\n  \"Lohenická\",\n  \"Lohniského\",\n  \"Lojovická\",\n  \"Lojovická\",\n  \"Lojovická\",\n  \"Lolkova\",\n  \"Lomařská\",\n  \"Lomecká\",\n  \"Lomená\",\n  \"Lomnická\",\n  \"Lomnického\",\n  \"Lomová\",\n  \"Londýnská\",\n  \"Loosova\",\n  \"Lopatecká\",\n  \"Lopatecká\",\n  \"Lopuchová\",\n  \"Loretánská\",\n  \"Loretánské Nám.\",\n  \"Loretánské Náměstí\",\n  \"Losinská\",\n  \"Lotyšská\",\n  \"Loucká\",\n  \"Loudova\",\n  \"Lounská\",\n  \"Lounských\",\n  \"Loutkářská\",\n  \"Loučanská\",\n  \"Loučimská\",\n  \"Loučná\",\n  \"Louňovická\",\n  \"Lovecká\",\n  \"Lovosická\",\n  \"Lovosická\",\n  \"Lovosická\",\n  \"Lovčenská\",\n  \"Lovčická\",\n  \"Lozická\",\n  \"Lošetická\",\n  \"Lošáková\",\n  \"Lstibořská\",\n  \"Lubenecká\",\n  \"Lublaňská\",\n  \"Lublaňská\",\n  \"Lublinská\",\n  \"Lubnická\",\n  \"Lucemburská\",\n  \"Lucemburská\",\n  \"Lucinková\",\n  \"Ludmilina\",\n  \"Ludvíkova\",\n  \"Luhovská\",\n  \"Lukavecká\",\n  \"Lukavského\",\n  \"Lukešova\",\n  \"Lukešova\",\n  \"Lukovská\",\n  \"Lukášova\",\n  \"Lumiérů\",\n  \"Lumírova\",\n  \"Lumírova\",\n  \"Luníkovská\",\n  \"Lupenická\",\n  \"Lupáčova\",\n  \"Lutínská\",\n  \"Luční\",\n  \"Luštěnická\",\n  \"Lužanská\",\n  \"Lužecká\",\n  \"Lužická\",\n  \"Lužnická\",\n  \"Lužná\",\n  \"Lužní\",\n  \"Lužská\",\n  \"Lvovská\",\n  \"Lysinská\",\n  \"Lysolajská\",\n  \"Lysolajské Údolí\",\n  \"Lyčkovo Nám.\",\n  \"Lyčkovo Náměstí\",\n  \"Lyžařská\",\n  \"Ládevská\",\n  \"Lánovská\",\n  \"Lánská\",\n  \"Lásenická\",\n  \"Láskova\",\n  \"Lázeňská\",\n  \"Lékařská\",\n  \"Lékořicová\",\n  \"Líbalova\",\n  \"Líbeznická\",\n  \"Lípová\",\n  \"Lískovická\",\n  \"Lísková\",\n  \"Líšnická\",\n  \"Lýskova\",\n  \"M. J. Lermontova\",\n  \"Macešková\",\n  \"Macharovo Nám.\",\n  \"Macharovo Náměstí\",\n  \"Machatého\",\n  \"Machkova\",\n  \"Machnova\",\n  \"Machovcova\",\n  \"Machovická\",\n  \"Machovská\",\n  \"Machuldova\",\n  \"Macháčkova\",\n  \"Madarova\",\n  \"Madaťjanova\",\n  \"Madridská\",\n  \"Magd. Rettigové\",\n  \"Magdalény Rettigové\",\n  \"Magistrů\",\n  \"Magnitogorská\",\n  \"Mahenova\",\n  \"Mahlerovy Sady\",\n  \"Mahulenina\",\n  \"Maiselova\",\n  \"Maiselova\",\n  \"Majerové\",\n  \"Majerského\",\n  \"Makedonská\",\n  \"Makovská\",\n  \"Makovského\",\n  \"Maková\",\n  \"Malachitová\",\n  \"Malebná\",\n  \"Malenická\",\n  \"Malešická\",\n  \"Malešická\",\n  \"Malešická\",\n  \"Malešické Nám.\",\n  \"Malešické Náměstí\",\n  \"Malešovská\",\n  \"Malinová\",\n  \"Maličká\",\n  \"Malkovského\",\n  \"Malletova\",\n  \"Malletova\",\n  \"Malobřevnovská\",\n  \"Malostranské Nábř.\",\n  \"Malostranské Nábřeží\",\n  \"Malostranské Náměstí\",\n  \"Malotická\",\n  \"Malovická\",\n  \"Maltézské Nám.\",\n  \"Maltézské Náměstí\",\n  \"Malá\",\n  \"Malá Bylanská\",\n  \"Malá Houdova\",\n  \"Malá Klášterní\",\n  \"Malá Lada\",\n  \"Malá Michnovka\",\n  \"Malá Plynární\",\n  \"Malá Skloněná\",\n  \"Malá Smidarská\",\n  \"Malá Tyršovka\",\n  \"Malá Xaveriova\",\n  \"Malá Štupartská\",\n  \"Malá Štěpánská\",\n  \"Malátova\",\n  \"Malé Nám.\",\n  \"Malé Náměstí\",\n  \"Malého\",\n  \"Malínská\",\n  \"Malířská\",\n  \"Malý Dvůr\",\n  \"Malý Okrouhlík\",\n  \"Malšovická\",\n  \"Malšovské Nám.\",\n  \"Malšovské Náměstí\",\n  \"Mandloňová\",\n  \"Mandova\",\n  \"Mansfeldova\",\n  \"Manská Zahrada\",\n  \"Mantovská\",\n  \"Manželů Dostálových\",\n  \"Manželů Kotrbových\",\n  \"Manželů Lyčkových\",\n  \"Marciho\",\n  \"Marešova\",\n  \"Marie Cibulkové\",\n  \"Marie Podvalové\",\n  \"Mariánská\",\n  \"Mariánská\",\n  \"Mariánské Hradby\",\n  \"Mariánské Hradby\",\n  \"Mariánské Nám.\",\n  \"Mariánské Náměstí\",\n  \"Markova\",\n  \"Markupova\",\n  \"Markušova\",\n  \"Markvartická\",\n  \"Markyta\",\n  \"Markétská\",\n  \"Maroldova\",\n  \"Martinelliho\",\n  \"Martinická\",\n  \"Martinova\",\n  \"Martinovská\",\n  \"Martinská\",\n  \"Marty Krásové\",\n  \"Marvanova\",\n  \"Maršovská\",\n  \"Masarykovo Nábř.\",\n  \"Masarykovo Nábř.\",\n  \"Masarykovo Nábřeží\",\n  \"Masarykovo Nábřeží\",\n  \"Masná\",\n  \"Matek\",\n  \"Matenská\",\n  \"Maternova\",\n  \"Mateřská\",\n  \"Mateřídoušková\",\n  \"Matjuchinova\",\n  \"Matoušova\",\n  \"Mattioliho\",\n  \"Matúškova\",\n  \"Matěchova\",\n  \"Matějkova\",\n  \"Matějovského\",\n  \"Matějská\",\n  \"Maxovská\",\n  \"Mazancova\",\n  \"Mazovská\",\n  \"Mazurská\",\n  \"Maďarská\",\n  \"Maňákova\",\n  \"Mařatkova\",\n  \"Mařákova\",\n  \"Maříkova\",\n  \"Mašatova\",\n  \"Maškova\",\n  \"Mašovická\",\n  \"Maštěřovského\",\n  \"Mašínova\",\n  \"Mechovka\",\n  \"Mechová\",\n  \"Medinská\",\n  \"Medkova\",\n  \"Medlovská\",\n  \"Medová\",\n  \"Meduňková\",\n  \"Meinlinova\",\n  \"Mejstříkova\",\n  \"Melantrichova\",\n  \"Meliorační\",\n  \"Melodická\",\n  \"Melounová\",\n  \"Menclova\",\n  \"Mendelova\",\n  \"Mendíků\",\n  \"Menšíkova\",\n  \"Menšíkovská\",\n  \"Merhoutova\",\n  \"Merkurova\",\n  \"Meruňková\",\n  \"Meskářova\",\n  \"Meteorologická\",\n  \"Meteorologická\",\n  \"Metodějova\",\n  \"Metujská\",\n  \"Mexická\",\n  \"Mezi Chatami\",\n  \"Mezi Domky\",\n  \"Mezi Domy\",\n  \"Mezi Humny\",\n  \"Mezi Lysinami\",\n  \"Mezi Lány\",\n  \"Mezi Poli\",\n  \"Mezi Potoky\",\n  \"Mezi Rolemi\",\n  \"Mezi Rybníky\",\n  \"Mezi Sklady\",\n  \"Mezi Stráněmi\",\n  \"Mezi Vodami\",\n  \"Mezi Úvozy\",\n  \"Mezi Školami\",\n  \"Mezibranská\",\n  \"Mezihorská\",\n  \"Mezihoří\",\n  \"Mezilehlá\",\n  \"Mezilesní\",\n  \"Mezilesí\",\n  \"Meziluží\",\n  \"Mezipolí\",\n  \"Mezitraťová\",\n  \"Mezitraťová\",\n  \"Mezitraťová\",\n  \"Mezivrší\",\n  \"Meziškolská\",\n  \"Mečislavova\",\n  \"Mečovská\",\n  \"Mečíková\",\n  \"Michalovicova\",\n  \"Michalská\",\n  \"Michelangelova\",\n  \"Michelská\",\n  \"Michelská\",\n  \"Michnova\",\n  \"Michnovka\",\n  \"Mickiewiczova\",\n  \"Mikanova\",\n  \"Mikova\",\n  \"Mikovcova\",\n  \"Mikovická\",\n  \"Mikulandská\",\n  \"Mikuleckého\",\n  \"Mikulova\",\n  \"Mikulovická\",\n  \"Mikuláše Z Husi\",\n  \"Mikulášská\",\n  \"Mikulčická\",\n  \"Mikšovského\",\n  \"Milady Horákové\",\n  \"Milady Horákové\",\n  \"Milady Horákové\",\n  \"Milady Horákové\",\n  \"Milady Horákové\",\n  \"Milana Kadlece\",\n  \"Milenovská\",\n  \"Milerova\",\n  \"Miletická\",\n  \"Miletínská\",\n  \"Milevská\",\n  \"Milevská\",\n  \"Milešovská\",\n  \"Milotická\",\n  \"Milovická\",\n  \"Milovická\",\n  \"Milánská\",\n  \"Milínská\",\n  \"Milíčova\",\n  \"Milíčovská\",\n  \"Mimoňská\",\n  \"Minaříkova\",\n  \"Minerální\",\n  \"Minická\",\n  \"Minská\",\n  \"Miranova\",\n  \"Miroslava Hajna\",\n  \"Miroslava Hamra\",\n  \"Mirotická\",\n  \"Mirotická\",\n  \"Mirovická\",\n  \"Mirošovická\",\n  \"Mirošovská\",\n  \"Mistrovská\",\n  \"Mistřínská\",\n  \"Miřetická\",\n  \"Miškovická\",\n  \"Mladenovova\",\n  \"Mladoboleslavská\",\n  \"Mladoboleslavská\",\n  \"Mladoboleslavská\",\n  \"Mladoboleslavská\",\n  \"Mladoboleslavská\",\n  \"Mladotická\",\n  \"Mladotova\",\n  \"Mladých\",\n  \"Mladých Běchovic\",\n  \"Mladčina\",\n  \"Mladějovská\",\n  \"Mlynářská\",\n  \"Mládeže\",\n  \"Mládežnická\",\n  \"Mládkova\",\n  \"Mládí\",\n  \"Mlázovická\",\n  \"Mlékárenská\",\n  \"Mlýnská\",\n  \"Mlýnská\",\n  \"Mnichovická\",\n  \"Mochovská\",\n  \"Mochovská\",\n  \"Modenská\",\n  \"Modlanská\",\n  \"Modletická\",\n  \"Modletínská\",\n  \"Modravská\",\n  \"Modrá\",\n  \"Modrého\",\n  \"Modřanská\",\n  \"Modřanská\",\n  \"Modřanská\",\n  \"Modřanská\",\n  \"Modřínová\",\n  \"Mohelnická\",\n  \"Mohylová\",\n  \"Mojmírova\",\n  \"Mokrá\",\n  \"Mokřanská\",\n  \"Moldavská\",\n  \"Molitorovská\",\n  \"Molákova\",\n  \"Mongolská\",\n  \"Moravanská\",\n  \"Moravanů\",\n  \"Moravská\",\n  \"Morseova\",\n  \"Morstadtova\",\n  \"Morušová\",\n  \"Morušová\",\n  \"Morávkova\",\n  \"Moskevská\",\n  \"Mostecká\",\n  \"Motolská\",\n  \"Moulíkova\",\n  \"Moysesova\",\n  \"Mozambická\",\n  \"Mozartova\",\n  \"Mošnova\",\n  \"Možného\",\n  \"Mramorová\",\n  \"Mratínská\",\n  \"Mračnická\",\n  \"Mrkosova\",\n  \"Mrkvičkova\",\n  \"Mrákovská\",\n  \"Mrázkova\",\n  \"Mrázovka\",\n  \"Mráčkova\",\n  \"Mrštíkova\",\n  \"Mrštíkova\",\n  \"Muchomůrková\",\n  \"Muchova\",\n  \"Mukařovská\",\n  \"Mukařovského\",\n  \"Murgašova\",\n  \"Murmanská\",\n  \"Musilova\",\n  \"Musorgského\",\n  \"Musílkova\",\n  \"Mutěnínská\",\n  \"Muzejní\",\n  \"Muzikova\",\n  \"Muškova\",\n  \"Mydlářka\",\n  \"Myjavská\",\n  \"Mylnerovka\",\n  \"Myslbekova\",\n  \"Myslbekova\",\n  \"Myslivecká\",\n  \"Myslivečkova\",\n  \"Myslíkova\",\n  \"Myslíkova\",\n  \"Myšlínská\",\n  \"Máchova\",\n  \"Máchova\",\n  \"Mádrova\",\n  \"Májovková\",\n  \"Májová\",\n  \"Málkovská\",\n  \"Mánesova\",\n  \"Márova\",\n  \"Máslova\",\n  \"Máslovická\",\n  \"Mátová\",\n  \"Mílovská\",\n  \"Mílová\",\n  \"Mírová\",\n  \"Mírového Hnutí\",\n  \"Mírového Hnutí\",\n  \"Místecká\",\n  \"Míčova\",\n  \"Míšeňská\",\n  \"Míšovická\",\n  \"Münzbergerových\",\n  \"Mýtní\",\n  \"Měchenická\",\n  \"Měcholupská\",\n  \"Měděnecká\",\n  \"Mělická\",\n  \"Mělnická\",\n  \"Městská\",\n  \"Měsíčková\",\n  \"Měsíční\",\n  \"Měšická\",\n  \"Měšínská\",\n  \"Mšecká\",\n  \"Mšenská\",\n  \"N. A. Někrasova\",\n  \"Na Babách\",\n  \"Na Babě\",\n  \"Na Bahnech\",\n  \"Na Balkáně\",\n  \"Na Balkáně\",\n  \"Na Bambouzku\",\n  \"Na Baních\",\n  \"Na Barikádách\",\n  \"Na Bartoňce\",\n  \"Na Bateriích\",\n  \"Na Bateriích\",\n  \"Na Bačálkách\",\n  \"Na Baště Sv. Jiří\",\n  \"Na Baště Sv. Ludmily\",\n  \"Na Baště Sv. Tomáše\",\n  \"Na Bendovce\",\n  \"Na Benátkách\",\n  \"Na Beránce\",\n  \"Na Betonce\",\n  \"Na Bečvářce\",\n  \"Na Bitevní Pláni\",\n  \"Na Blanici\",\n  \"Na Blanseku\",\n  \"Na Blatech\",\n  \"Na Bluku\",\n  \"Na Bohdalci\",\n  \"Na Bojišti\",\n  \"Na Boleslavce\",\n  \"Na Borovém\",\n  \"Na Botiči\",\n  \"Na Botě\",\n  \"Na Božkovně\",\n  \"Na Brabenci\",\n  \"Na Brázdě\",\n  \"Na Bučance\",\n  \"Na Bělici\",\n  \"Na Bělidle\",\n  \"Na Bělohorské Pláni\",\n  \"Na Břehu\",\n  \"Na Břevnovské Pláni\",\n  \"Na Březince\",\n  \"Na Celné\",\n  \"Na Cestě\",\n  \"Na Chmelnici\",\n  \"Na Chobotě\",\n  \"Na Chodovci\",\n  \"Na Chvalce\",\n  \"Na Chvalské Tvrzi\",\n  \"Na Cihelně\",\n  \"Na Cihlářce\",\n  \"Na Cikorce\",\n  \"Na Cikánce\",\n  \"Na Cimbále\",\n  \"Na Cípu\",\n  \"Na Císařce\",\n  \"Na Dionysce\",\n  \"Na Dlouhé Mezi\",\n  \"Na Dlouhé Mezi\",\n  \"Na Dlouhé Mezi\",\n  \"Na Dlouhé Mezi\",\n  \"Na Dlouhém Lánu\",\n  \"Na Dlážděnce\",\n  \"Na Dlážděnce\",\n  \"Na Dlážděnce\",\n  \"Na Dlážděnce\",\n  \"Na Dobešce\",\n  \"Na Dobré Vodě\",\n  \"Na Dolinách\",\n  \"Na Dolinách\",\n  \"Na Dolnici\",\n  \"Na Dolíku\",\n  \"Na Domovině\",\n  \"Na Doubkové\",\n  \"Na Drahách\",\n  \"Na Dračkách\",\n  \"Na Dračkách\",\n  \"Na Dražkách\",\n  \"Na Dubině\",\n  \"Na Dvorcích\",\n  \"Na Dyrince\",\n  \"Na Dílcích\",\n  \"Na Dílech\",\n  \"Na Dědince\",\n  \"Na Dědinách\",\n  \"Na Děkance\",\n  \"Na Děkance\",\n  \"Na Dělostřílnách\",\n  \"Na Džbánu\",\n  \"Na Fabiánce\",\n  \"Na Farkách\",\n  \"Na Farkáně I\",\n  \"Na Farkáně Ii\",\n  \"Na Farkáně Iii\",\n  \"Na Farkáně Iv\",\n  \"Na Fialce I\",\n  \"Na Fialce Ii\",\n  \"Na Fidlovačce\",\n  \"Na Fišerce\",\n  \"Na Florenci\",\n  \"Na Florenci\",\n  \"Na Floře\",\n  \"Na Folimance\",\n  \"Na Formance\",\n  \"Na Františku\",\n  \"Na Groši\",\n  \"Na Habrovce\",\n  \"Na Habrové\",\n  \"Na Hanspaulce\",\n  \"Na Harfě\",\n  \"Na Havránce\",\n  \"Na Hlavní\",\n  \"Na Hlinách\",\n  \"Na Hloubětínské Vinici\",\n  \"Na Hlídce\",\n  \"Na Holém Vrchu\",\n  \"Na Homolce\",\n  \"Na Homoli\",\n  \"Na Horce\",\n  \"Na Horkách\",\n  \"Na Hradním Vodovodu\",\n  \"Na Hranicích\",\n  \"Na Hranicích\",\n  \"Na Hrobci\",\n  \"Na Hroudě\",\n  \"Na Hroudě\",\n  \"Na Hrádku\",\n  \"Na Hrázi\",\n  \"Na Hubálce\",\n  \"Na Humnech\",\n  \"Na Hupech\",\n  \"Na Hutmance\",\n  \"Na Hutích\",\n  \"Na Hutích\",\n  \"Na Hvížďalce\",\n  \"Na Hvězdárně\",\n  \"Na Hádku\",\n  \"Na Hájku\",\n  \"Na Hřebenech I\",\n  \"Na Hřebenech Ii\",\n  \"Na Hřebenech Ii\",\n  \"Na Hřebenkách\",\n  \"Na Hůrce\",\n  \"Na Jabloňce\",\n  \"Na Jabloňce\",\n  \"Na Jahodách\",\n  \"Na Jarově\",\n  \"Na Jelenách\",\n  \"Na Jelenách\",\n  \"Na Jetelce\",\n  \"Na Jetelce\",\n  \"Na Jezerce\",\n  \"Na Jezerách\",\n  \"Na Jitřence\",\n  \"Na Jivinách\",\n  \"Na Julisce\",\n  \"Na Jílech\",\n  \"Na Jílu\",\n  \"Na Kameni\",\n  \"Na Kampě\",\n  \"Na Kapličce\",\n  \"Na Karlovce\",\n  \"Na Kavčích Horách\",\n  \"Na Kazance\",\n  \"Na Kačence\",\n  \"Na Kačerově\",\n  \"Na Kindlovce\",\n  \"Na Klaudiánce\",\n  \"Na Klaudiánce\",\n  \"Na Kleovce\",\n  \"Na Klikovce\",\n  \"Na Klimentce\",\n  \"Na Klášterním\",\n  \"Na Klínech\",\n  \"Na Klínech\",\n  \"Na Klínku\",\n  \"Na Knížce\",\n  \"Na Kocourkách\",\n  \"Na Kocínce\",\n  \"Na Kodymce\",\n  \"Na Kolejním Statku\",\n  \"Na Komořsku\",\n  \"Na Komořsku\",\n  \"Na Konci\",\n  \"Na Konečné\",\n  \"Na Konvářce\",\n  \"Na Kopanině\",\n  \"Na Kopci\",\n  \"Na Kopečku\",\n  \"Na Kopytářce\",\n  \"Na Korunce\",\n  \"Na Korábě\",\n  \"Na Korálově\",\n  \"Na Kotlářce\",\n  \"Na Koupaliště\",\n  \"Na Kovárně\",\n  \"Na Kozačce\",\n  \"Na Kozinci\",\n  \"Na Košince\",\n  \"Na Košíku\",\n  \"Na Kraji\",\n  \"Na Krocínce\",\n  \"Na Krutci\",\n  \"Na Královce\",\n  \"Na Královně\",\n  \"Na Krčské Stráni\",\n  \"Na Kuthence\",\n  \"Na Kvintusce\",\n  \"Na Květnici\",\n  \"Na Kyjově\",\n  \"Na Křemínku\",\n  \"Na Křenkově\",\n  \"Na Křečku\",\n  \"Na Křivce\",\n  \"Na Křivce\",\n  \"Na Křivce\",\n  \"Na Křivině\",\n  \"Na Křtině\",\n  \"Na Křídle\",\n  \"Na Labuťce\",\n  \"Na Labuťce I\",\n  \"Na Labuťce Ii\",\n  \"Na Labuťce Iii\",\n  \"Na Labuťce Iv\",\n  \"Na Ladách\",\n  \"Na Lahovské\",\n  \"Na Laurové\",\n  \"Na Lepším\",\n  \"Na Lhotech\",\n  \"Na Lhotkách\",\n  \"Na Libušince\",\n  \"Na Losách\",\n  \"Na Louce\",\n  \"Na Loukoti\",\n  \"Na Louži\",\n  \"Na Loužku\",\n  \"Na Luka\",\n  \"Na Lukách\",\n  \"Na Luzích\",\n  \"Na Lučinách\",\n  \"Na Lužci\",\n  \"Na Lysinách\",\n  \"Na Lysině\",\n  \"Na Ládví\",\n  \"Na Lánech\",\n  \"Na Lávce\",\n  \"Na Lázeňce\",\n  \"Na Líše\",\n  \"Na Malovance\",\n  \"Na Malé Šárce\",\n  \"Na Malém Klínu\",\n  \"Na Maninách\",\n  \"Na Manoušce\",\n  \"Na Markvartce\",\n  \"Na Marně\",\n  \"Na Mezi\",\n  \"Na Mlejnku\",\n  \"Na Moklině\",\n  \"Na Mokřině\",\n  \"Na Moráni\",\n  \"Na Močále\",\n  \"Na Mrázovce\",\n  \"Na Musilech\",\n  \"Na Mírách\",\n  \"Na Míčánce\",\n  \"Na Míčánkách\",\n  \"Na Mýtě\",\n  \"Na Můstku\",\n  \"Na Neklance\",\n  \"Na Nežárce\",\n  \"Na Nivách\",\n  \"Na Novině\",\n  \"Na Nové Silnici\",\n  \"Na Náspu\",\n  \"Na Návrati\",\n  \"Na Návrší\",\n  \"Na Návsi\",\n  \"Na Obrátce\",\n  \"Na Obrátce\",\n  \"Na Odbočce\",\n  \"Na Ohradě\",\n  \"Na Okraji\",\n  \"Na Okraji\",\n  \"Na Okrouhlíku\",\n  \"Na Okruhu\",\n  \"Na Opyši\",\n  \"Na Opyši\",\n  \"Na Ostrohu\",\n  \"Na Ostrově\",\n  \"Na Ostrůvku\",\n  \"Na Ovesníku\",\n  \"Na Ovčinách\",\n  \"Na Ovčáckém\",\n  \"Na Ovčíně\",\n  \"Na Ořechovce\",\n  \"Na Padesátníku I\",\n  \"Na Padesátníku Ii\",\n  \"Na Padesátníku Iii\",\n  \"Na Padesátníku Iv\",\n  \"Na Padesátníku V\",\n  \"Na Padesátém\",\n  \"Na Pahorku\",\n  \"Na Pahoubce\",\n  \"Na Palouku\",\n  \"Na Paloučku\",\n  \"Na Pankráci\",\n  \"Na Panorámě\",\n  \"Na Parcelách\",\n  \"Na Parkáně\",\n  \"Na Parukářce\",\n  \"Na Pasece\",\n  \"Na Pasece\",\n  \"Na Pastvinách\",\n  \"Na Pavím Vrchu\",\n  \"Na Pazderce\",\n  \"Na Pecích\",\n  \"Na Pernikářce\",\n  \"Na Perštýně\",\n  \"Na Petynce\",\n  \"Na Petynce\",\n  \"Na Petřinách\",\n  \"Na Petřinách\",\n  \"Na Placích\",\n  \"Na Planině\",\n  \"Na Plužině\",\n  \"Na Plzeňce\",\n  \"Na Plácku\",\n  \"Na Pláni\",\n  \"Na Plískavě\",\n  \"Na Podkovce\",\n  \"Na Pokraji\",\n  \"Na Pokraji\",\n  \"Na Poli\",\n  \"Na Polníku\",\n  \"Na Pomezí\",\n  \"Na Pomezí\",\n  \"Na Popelce\",\n  \"Na Popelce\",\n  \"Na Potůčku\",\n  \"Na Poustkách\",\n  \"Na Pozorce\",\n  \"Na Poříčním Právu\",\n  \"Na Poříčí\",\n  \"Na Poříčí\",\n  \"Na Požáru\",\n  \"Na Požáru\",\n  \"Na Pramenech\",\n  \"Na Pramenech\",\n  \"Na Prosecké Vyhlídce\",\n  \"Na Proseku\",\n  \"Na Prostřední Cestě\",\n  \"Na Proutcích\",\n  \"Na Provaznici\",\n  \"Na Průhonu\",\n  \"Na Průseku\",\n  \"Na Pučálce\",\n  \"Na Pískovně\",\n  \"Na Písku\",\n  \"Na Pískách\",\n  \"Na Pěkné Vyhlídce\",\n  \"Na Pěšinách\",\n  \"Na Pěšinách\",\n  \"Na Pěšině\",\n  \"Na Předevsi\",\n  \"Na Přesypu\",\n  \"Na Přesypu\",\n  \"Na Přídole\",\n  \"Na Příkopě\",\n  \"Na Příkopě\",\n  \"Na Přívozích\",\n  \"Na Příčce\",\n  \"Na Příčné Mezi\",\n  \"Na Radosti\",\n  \"Na Radosti\",\n  \"Na Rampách\",\n  \"Na Rejdišti\",\n  \"Na Roháčku\",\n  \"Na Rokytce\",\n  \"Na Rolích\",\n  \"Na Rovinách\",\n  \"Na Rovině\",\n  \"Na Rovni\",\n  \"Na Rovnosti\",\n  \"Na Rovném\",\n  \"Na Rozcestí\",\n  \"Na Rozdílu\",\n  \"Na Rozdílu\",\n  \"Na Rozhledu\",\n  \"Na Rozhraní\",\n  \"Na Rozhraní\",\n  \"Na Rozvodí\",\n  \"Na Ročkově\",\n  \"Na Rybníčku\",\n  \"Na Rybářce\",\n  \"Na Rybářce\",\n  \"Na Rymáni\",\n  \"Na Rynku\",\n  \"Na Salabce\",\n  \"Na Samotě\",\n  \"Na Schodech\",\n  \"Na Schůdkách\",\n  \"Na Sedlišti\",\n  \"Na Sekyrce\",\n  \"Na Selském\",\n  \"Na Seníku\",\n  \"Na Skalce\",\n  \"Na Skalách\",\n  \"Na Sklonku\",\n  \"Na Skále\",\n  \"Na Slatince\",\n  \"Na Slatinách\",\n  \"Na Slatinách\",\n  \"Na Slatinách\",\n  \"Na Slavíkově\",\n  \"Na Slovance\",\n  \"Na Slupi\",\n  \"Na Slupi\",\n  \"Na Smetance\",\n  \"Na Souvrati\",\n  \"Na Souvrati\",\n  \"Na Spojce\",\n  \"Na Spádu\",\n  \"Na Spáleništi\",\n  \"Na Srpečku\",\n  \"Na Srázu\",\n  \"Na Srážku\",\n  \"Na Staré\",\n  \"Na Staré Cestě\",\n  \"Na Staré Návsi\",\n  \"Na Staré Silnici\",\n  \"Na Staré Vinici\",\n  \"Na Stezce\",\n  \"Na Stezce\",\n  \"Na Struze\",\n  \"Na Stráni\",\n  \"Na Stráňkách\",\n  \"Na Stráži\",\n  \"Na Stráži\",\n  \"Na Strži\",\n  \"Na Strži\",\n  \"Na Stupních\",\n  \"Na Stárce\",\n  \"Na Stírce\",\n  \"Na Střelnici\",\n  \"Na Svahu\",\n  \"Na Svěcence\",\n  \"Na Sychrově\",\n  \"Na Sychrově\",\n  \"Na Sypkém\",\n  \"Na Sypčině\",\n  \"Na Sádce\",\n  \"Na Terase\",\n  \"Na Topolce\",\n  \"Na Topolce\",\n  \"Na Truhlářce\",\n  \"Na Tržišti\",\n  \"Na Tykačce\",\n  \"Na Táboře\",\n  \"Na Třebešíně\",\n  \"Na Třebešíně\",\n  \"Na Universitním Statku\",\n  \"Na Usedlosti\",\n  \"Na Vackově\",\n  \"Na Valech\",\n  \"Na Valentince\",\n  \"Na Vartě\",\n  \"Na Vaňhově\",\n  \"Na Veselí\",\n  \"Na Vidouli\",\n  \"Na Viktorce\",\n  \"Na Vinici\",\n  \"Na Viničce\",\n  \"Na Viničkách\",\n  \"Na Viničních Horách\",\n  \"Na Vinobraní\",\n  \"Na Vinohradu\",\n  \"Na Višňovce\",\n  \"Na Vlasačce\",\n  \"Na Vlastní Půdě\",\n  \"Na Vlastním\",\n  \"Na Vlku\",\n  \"Na Vlčovce\",\n  \"Na Volánové\",\n  \"Na Vrchmezí\",\n  \"Na Vrchmezí\",\n  \"Na Vrchmezí\",\n  \"Na Vrcholu\",\n  \"Na Vrchu\",\n  \"Na Vrchu\",\n  \"Na Vrchách\",\n  \"Na Vrchách\",\n  \"Na Vrstevnici\",\n  \"Na Vrstvách\",\n  \"Na Vršku\",\n  \"Na Vrškách\",\n  \"Na Vrších\",\n  \"Na Vrších\",\n  \"Na Vydrholci\",\n  \"Na Vyhlídce\",\n  \"Na Vypichu\",\n  \"Na Vypichu\",\n  \"Na Vysoké I\",\n  \"Na Vysoké I\",\n  \"Na Vysoké Ii\",\n  \"Na Vysočanských Vinicích\",\n  \"Na Vysočině\",\n  \"Na Václavce\",\n  \"Na Vápence\",\n  \"Na Vápenném\",\n  \"Na Vítězné Pláni\",\n  \"Na Výběžku\",\n  \"Na Výhledech\",\n  \"Na Výhonku\",\n  \"Na Výrovně\",\n  \"Na Výsledku I\",\n  \"Na Výsledku Ii\",\n  \"Na Výsluní\",\n  \"Na Výspě\",\n  \"Na Výspě\",\n  \"Na Výstupu\",\n  \"Na Výtoni\",\n  \"Na Výši\",\n  \"Na Výšince\",\n  \"Na Výšinách\",\n  \"Na Výšině\",\n  \"Na Věnečku\",\n  \"Na Větrníku\",\n  \"Na Větrníku\",\n  \"Na Větrově\",\n  \"Na Větru\",\n  \"Na Zahrádkách\",\n  \"Na Zatlance\",\n  \"Na Zavadilce\",\n  \"Na Zbořenci\",\n  \"Na Zderaze\",\n  \"Na Zedníkové\",\n  \"Na Zelené Louce\",\n  \"Na Zemance\",\n  \"Na Zkratce\",\n  \"Na Zlatnici\",\n  \"Na Zlaté\",\n  \"Na Zlíchově\",\n  \"Na Zlíchově\",\n  \"Na Zmrzlíku\",\n  \"Na Znělci\",\n  \"Na Zvoničce\",\n  \"Na Zábradlí\",\n  \"Na Záhonech\",\n  \"Na Zájezdu\",\n  \"Na Zámecké\",\n  \"Na Zámkách\",\n  \"Na Zámyšli\",\n  \"Na Zástřelu\",\n  \"Na Zástřelu\",\n  \"Na Zátorce\",\n  \"Na Zátorách\",\n  \"Na Závěji\",\n  \"Na Úbočí\",\n  \"Na Úhoru\",\n  \"Na Úlehli\",\n  \"Na Úseku\",\n  \"Na Úspěchu\",\n  \"Na Černé Hoře\",\n  \"Na Černé Strouze\",\n  \"Na Černém Vrchu\",\n  \"Na Července\",\n  \"Na Čečeličce\",\n  \"Na Čihadle\",\n  \"Na Čisté\",\n  \"Na Říháku\",\n  \"Na Šabatce\",\n  \"Na Šachtě\",\n  \"Na Šafránce\",\n  \"Na Šancích\",\n  \"Na Šedivé\",\n  \"Na Šejdru\",\n  \"Na Šejdru\",\n  \"Na Šmukýřce\",\n  \"Na Špejcharu\",\n  \"Na Špitálce\",\n  \"Na Špitálsku\",\n  \"Na Štamberku\",\n  \"Na Štěpnici\",\n  \"Na Šubě\",\n  \"Na Šumavě\",\n  \"Na Šutce\",\n  \"Na Švihance\",\n  \"Na Šťáhlavce\",\n  \"Na Žertvách\",\n  \"Na Žvahově\",\n  \"Naardenská\",\n  \"Nad Akcízem\",\n  \"Nad Akáty\",\n  \"Nad Alejí\",\n  \"Nad Belvederem\",\n  \"Nad Belárií\",\n  \"Nad Berounkou\",\n  \"Nad Bertramkou\",\n  \"Nad Botičem\",\n  \"Nad Bořislavkou\",\n  \"Nad Bořislavkou\",\n  \"Nad Branickým Pivovarem\",\n  \"Nad Brůdkem\",\n  \"Nad Brůdkem\",\n  \"Nad Buďánkami I\",\n  \"Nad Buďánkami Ii\",\n  \"Nad Buďánkami Iii\",\n  \"Nad Cementárnou\",\n  \"Nad Chaloupkami\",\n  \"Nad Chuchlí\",\n  \"Nad Cihelnou\",\n  \"Nad Dalejským Údolím\",\n  \"Nad Doly\",\n  \"Nad Dolíky\",\n  \"Nad Drahou\",\n  \"Nad Dubovým Mlýnem\",\n  \"Nad Dvorem\",\n  \"Nad Dálnicí\",\n  \"Nad Elektrárnou\",\n  \"Nad Elektrárnou\",\n  \"Nad Flajšnerkou\",\n  \"Nad Habrovkou\",\n  \"Nad Havlem\",\n  \"Nad Helmrovkou\",\n  \"Nad Hercovkou\",\n  \"Nad Hercovkou\",\n  \"Nad Hliníkem\",\n  \"Nad Hliníkem\",\n  \"Nad Horizontem\",\n  \"Nad Hradním Potokem\",\n  \"Nad Hradním Vodojemem\",\n  \"Nad Husovými Sady\",\n  \"Nad Hutěmi\",\n  \"Nad Hutěmi\",\n  \"Nad Hájem\",\n  \"Nad Hřištěm\",\n  \"Nad Jenerálkou\",\n  \"Nad Jetelkou\",\n  \"Nad Jezem\",\n  \"Nad Jezerkou\",\n  \"Nad Jordánkem\",\n  \"Nad Kajetánkou\",\n  \"Nad Kamínkou\",\n  \"Nad Kaplankou\",\n  \"Nad Kapličkou\",\n  \"Nad Kavalírkou\",\n  \"Nad Kazankou\",\n  \"Nad Kazínem\",\n  \"Nad Kelerkou\",\n  \"Nad Kesnerkou\",\n  \"Nad Klamovkou\",\n  \"Nad Klikovkou\",\n  \"Nad Klíčovem\",\n  \"Nad Kolonií\",\n  \"Nad Kolčavkou\",\n  \"Nad Komornickou\",\n  \"Nad Konečnou\",\n  \"Nad Konvářkou\",\n  \"Nad Kostelem\",\n  \"Nad Kotlaskou I\",\n  \"Nad Kotlaskou Ii\",\n  \"Nad Kotlaskou Iii\",\n  \"Nad Kotlaskou Iv\",\n  \"Nad Kotlaskou V\",\n  \"Nad Koulkou\",\n  \"Nad Koupadly\",\n  \"Nad Koupalištěm\",\n  \"Nad Košinkou\",\n  \"Nad Košíkem\",\n  \"Nad Krocínkou\",\n  \"Nad Krocínkou\",\n  \"Nad Královskou Oborou\",\n  \"Nad Kuliškou\",\n  \"Nad Kundratkou\",\n  \"Nad Kundratkou\",\n  \"Nad Kundratkou\",\n  \"Nad Křížkem\",\n  \"Nad Laurovou\",\n  \"Nad Lesem\",\n  \"Nad Lesním Divadlem\",\n  \"Nad Lesíkem\",\n  \"Nad Libeňským Nádražím\",\n  \"Nad Libeřským Potokem\",\n  \"Nad Libušským Potokem\",\n  \"Nad Libří\",\n  \"Nad Lomem\",\n  \"Nad Lomy\",\n  \"Nad Lukami\",\n  \"Nad Lávkou\",\n  \"Nad Malým Mýtem\",\n  \"Nad Manovkou\",\n  \"Nad Markytou\",\n  \"Nad Mazankou\",\n  \"Nad Meandry\",\n  \"Nad Mlynářkou\",\n  \"Nad Mlýnem\",\n  \"Nad Mlýnským Potokem\",\n  \"Nad Mohylou\",\n  \"Nad Mokřinou\",\n  \"Nad Mostem\",\n  \"Nad Motolskou Nemocnicí\",\n  \"Nad Motolskou Nemocnicí\",\n  \"Nad Mrázovkou\",\n  \"Nad Mušlovkou\",\n  \"Nad Mušlovkou\",\n  \"Nad Novou Libní\",\n  \"Nad Nuslemi\",\n  \"Nad Nádražím\",\n  \"Nad Nádrží\",\n  \"Nad Náhonem\",\n  \"Nad Náměstím\",\n  \"Nad Návsí\",\n  \"Nad Obcí I\",\n  \"Nad Obcí Ii\",\n  \"Nad Octárnou\",\n  \"Nad Odbočkou\",\n  \"Nad Ohradou\",\n  \"Nad Okrouhlíkem\",\n  \"Nad Olšinami\",\n  \"Nad Olšinami\",\n  \"Nad Ondřejovem\",\n  \"Nad Opatovem\",\n  \"Nad Ostrovem\",\n  \"Nad Pahorkem\",\n  \"Nad Palatou\",\n  \"Nad Panenskou\",\n  \"Nad Parkem\",\n  \"Nad Parkánem\",\n  \"Nad Paťankou\",\n  \"Nad Pentlovkou\",\n  \"Nad Petruskou\",\n  \"Nad Petynkou\",\n  \"Nad Plynovodem\",\n  \"Nad Podbabskou Skálou\",\n  \"Nad Pomníkem\",\n  \"Nad Popelkou\",\n  \"Nad Popelářkou\",\n  \"Nad Potůčkem\",\n  \"Nad Prahou\",\n  \"Nad Pramenem\",\n  \"Nad Primaskou\",\n  \"Nad Primaskou\",\n  \"Nad Propustí\",\n  \"Nad Pruhy\",\n  \"Nad Pískovnou\",\n  \"Nad Přehradou\",\n  \"Nad Přívozem\",\n  \"Nad Radotínem\",\n  \"Nad Rohatci\",\n  \"Nad Roklí\",\n  \"Nad Rokoskou\",\n  \"Nad Rokytkou\",\n  \"Nad Rybníkem\",\n  \"Nad Rybníkem\",\n  \"Nad Rybníčky\",\n  \"Nad Ryšánkou\",\n  \"Nad Rážákem\",\n  \"Nad Sadem\",\n  \"Nad Sady\",\n  \"Nad Santoškou\",\n  \"Nad Schody\",\n  \"Nad Skálou\",\n  \"Nad Slávií\",\n  \"Nad Slávií\",\n  \"Nad Smetankou\",\n  \"Nad Sokolovnou\",\n  \"Nad Soutokem\",\n  \"Nad Soutokem\",\n  \"Nad Splavem\",\n  \"Nad Spádem\",\n  \"Nad Spáleným Mlýnem\",\n  \"Nad Stanicí\",\n  \"Nad Starou Pískovnou\",\n  \"Nad Statkem\",\n  \"Nad Strakovkou\",\n  \"Nad Strouhou\",\n  \"Nad Strání\",\n  \"Nad Strání\",\n  \"Nad Studánkou\",\n  \"Nad Svahem\",\n  \"Nad Sýpkou\",\n  \"Nad Tejnkou\",\n  \"Nad Teplárnou\",\n  \"Nad Topoly\",\n  \"Nad Tratí\",\n  \"Nad Trnkovem\",\n  \"Nad Trojou\",\n  \"Nad Turbovou\",\n  \"Nad Třebešínem I\",\n  \"Nad Třebešínem Ii\",\n  \"Nad Třebešínem Ii\",\n  \"Nad Třebešínem Iii\",\n  \"Nad Třebešínem Iii\",\n  \"Nad Vavrouškou\",\n  \"Nad Vernerákem\",\n  \"Nad Vinicí\",\n  \"Nad Vinným Potokem\",\n  \"Nad Vinným Potokem\",\n  \"Nad Vinným Potokem\",\n  \"Nad Vinohradem\",\n  \"Nad Višňovkou\",\n  \"Nad Vltavou\",\n  \"Nad Vodovodem\",\n  \"Nad Vodovodem\",\n  \"Nad Vojenským Hřbitovem\",\n  \"Nad Vokolky\",\n  \"Nad Volyňkou\",\n  \"Nad Vrbami\",\n  \"Nad Vrstvami\",\n  \"Nad Vršovskou Horou\",\n  \"Nad Vsí\",\n  \"Nad Vysočany\",\n  \"Nad Václavkou\",\n  \"Nad Výpustí\",\n  \"Nad Výšinkou\",\n  \"Nad Zahradnictvím\",\n  \"Nad Zatáčkou\",\n  \"Nad Zavážkou\",\n  \"Nad Zbraslaví\",\n  \"Nad Zbrojnicí\",\n  \"Nad Zemankou\",\n  \"Nad Zemankou\",\n  \"Nad Zlatnicí\",\n  \"Nad Zlíchovem\",\n  \"Nad Záložnou\",\n  \"Nad Zámečkem\",\n  \"Nad Zámečnicí\",\n  \"Nad Zátiším\",\n  \"Nad Závodištěm\",\n  \"Nad Závěrkou\",\n  \"Nad Údolím\",\n  \"Nad Údolím Hvězd\",\n  \"Nad Úpadem\",\n  \"Nad Úvozem\",\n  \"Nad Úžlabinou\",\n  \"Nad Úžlabinou\",\n  \"Nad Šafránkou\",\n  \"Nad Šancemi\",\n  \"Nad Šauerovými Sady\",\n  \"Nad Šeberákem\",\n  \"Nad Šejdrem\",\n  \"Nad Šestikopy\",\n  \"Nad Šetelkou\",\n  \"Nad Štolou\",\n  \"Nad Šutkou\",\n  \"Nad Šálkovnou\",\n  \"Nad Šárkou\",\n  \"Nad Želivkou\",\n  \"Nad Žlábkem\",\n  \"Nademlejnská\",\n  \"Nadějovská\",\n  \"Narcisová\",\n  \"Naskové\",\n  \"Natanaelka\",\n  \"Navarova\",\n  \"Navigátorů\",\n  \"Navrátilova\",\n  \"Načeradecká\",\n  \"Načešická\",\n  \"Neapolská\",\n  \"Nebeského\",\n  \"Nebovidská\",\n  \"Nebozízek-Sady\",\n  \"Nebušická\",\n  \"Nechanická\",\n  \"Nechanského\",\n  \"Nechvalická\",\n  \"Nechvílova\",\n  \"Nechybova\",\n  \"Nedašovská\",\n  \"Nedbalova\",\n  \"Nedokončená\",\n  \"Nedokončená\",\n  \"Nedošínské\",\n  \"Nedražická\",\n  \"Nedvědická\",\n  \"Nedvědovo Nám.\",\n  \"Nedvědovo Náměstí\",\n  \"Nedvězská\",\n  \"Neffova\",\n  \"Nefritová\",\n  \"Neherovská\",\n  \"Nehvizdská\",\n  \"Nehvizdská\",\n  \"Nejdkova\",\n  \"Neklanova\",\n  \"Nekvasilova\",\n  \"Nekázanka\",\n  \"Nemocniční\",\n  \"Nemošická\",\n  \"Nepasické Nám.\",\n  \"Nepasické Náměstí\",\n  \"Nepelova\",\n  \"Nepilova\",\n  \"Nepomucká\",\n  \"Nepomuckých\",\n  \"Nepovolená\",\n  \"Nepravidelná\",\n  \"Neprůjezdná\",\n  \"Nepálská\",\n  \"Neratovická\",\n  \"Nerudova\",\n  \"Nerudova\",\n  \"Nesměřická\",\n  \"Nespecká\",\n  \"Nesvadbova\",\n  \"Netlucká\",\n  \"Netluky\",\n  \"Netolická\",\n  \"Netušilská\",\n  \"Netínská\",\n  \"Netřebická\",\n  \"Netřebská\",\n  \"Neumannova\",\n  \"Neustupného\",\n  \"Neužilova\",\n  \"Nevanova\",\n  \"Neveklovská\",\n  \"Newtonova\",\n  \"Nezamyslova\",\n  \"Nezdova\",\n  \"Nezvalova\",\n  \"Nečova\",\n  \"Nešporova\",\n  \"Nežárská\",\n  \"Nickerleho\",\n  \"Niederleho\",\n  \"Nikodémova\",\n  \"Nikoly Tesly\",\n  \"Nikoly Vapcarova\",\n  \"Niská\",\n  \"Nitranská\",\n  \"Nitranská\",\n  \"Nivnická\",\n  \"Nobelova\",\n  \"Norbertov\",\n  \"Norská\",\n  \"Nosická\",\n  \"Nosticova\",\n  \"Notečská\",\n  \"Noutonická\",\n  \"Nouzov\",\n  \"Nouzovské Nám.\",\n  \"Nouzovské Náměstí\",\n  \"Nouzová\",\n  \"Novgorodská\",\n  \"Novobohdalecká\",\n  \"Novoborská\",\n  \"Novoborská\",\n  \"Novochuchelská\",\n  \"Novodvorská\",\n  \"Novodvorská\",\n  \"Novodvorská\",\n  \"Novodvorská\",\n  \"Novohradská\",\n  \"Novohrádecká\",\n  \"Novohrádecká\",\n  \"Novolhotská\",\n  \"Novolipanská\",\n  \"Novomeského\",\n  \"Novomeského\",\n  \"Novomlýnská\",\n  \"Novopacká\",\n  \"Novopetrovická\",\n  \"Novorossijská\",\n  \"Novosibřinská\",\n  \"Novostrašnická\",\n  \"Novosuchdolská\",\n  \"Novosvětská\",\n  \"Novotného Lávka\",\n  \"Novoveská\",\n  \"Novoveská\",\n  \"Novovysočanská\",\n  \"Novovysočanská\",\n  \"Novovysočanská\",\n  \"Novozámecká\",\n  \"Novozámecká\",\n  \"Novoškolská\",\n  \"Novoštěrboholská\",\n  \"Nová\",\n  \"Nová Cesta\",\n  \"Nová Kolonie\",\n  \"Nová Ves\",\n  \"Nová Ves\",\n  \"Nová Šárka\",\n  \"Novákovo Nám.\",\n  \"Novákovo Náměstí\",\n  \"Novákových\",\n  \"Nové Domy\",\n  \"Nové Dvory\",\n  \"Nové Mlýny\",\n  \"Nové Náměstí\",\n  \"Nového\",\n  \"Nový Lesík\",\n  \"Nový Svět\",\n  \"Nový Zlíchov\",\n  \"Nový Zlíchov\",\n  \"Nupacká\",\n  \"Nuselská\",\n  \"Nuselská\",\n  \"Nučická\",\n  \"Nušlova\",\n  \"Nymburská\",\n  \"Nábř. Edvarda Beneše\",\n  \"Nábř. Edvarda Beneše\",\n  \"Nábř. Edvarda Beneše\",\n  \"Nábř. Kapitána Jaroše\",\n  \"Nábř. Kapitána Jaroše\",\n  \"Nábřežní\",\n  \"Nábřeží Edvarda Beneše\",\n  \"Nábřeží Edvarda Beneše\",\n  \"Nábřeží Edvarda Beneše\",\n  \"Nábřeží Kapitána Jaroše\",\n  \"Nábřeží Ludvíka Svobody\",\n  \"Náchodská\",\n  \"Nádražní\",\n  \"Nádražní\",\n  \"Nádvorní\",\n  \"Náhorní\",\n  \"Nákupní\",\n  \"Nám. 14. Října\",\n  \"Nám. 25. Března\",\n  \"Nám. Antonína Pecáka\",\n  \"Nám. Barikád\",\n  \"Nám. Bořislavka\",\n  \"Nám. Bratří Synků\",\n  \"Nám. Chuchelských Bojovníků\",\n  \"Nám. Chuchleských Bojovníků\",\n  \"Nám. Curieových\",\n  \"Nám. Dr. V. Holého\",\n  \"Nám. Franze Kafky\",\n  \"Nám. Generála Kutlvašra\",\n  \"Nám. Hrdinů\",\n  \"Nám. I. P. Pavlova\",\n  \"Nám. Interbrigády\",\n  \"Nám. Jana Palacha\",\n  \"Nám. Jana Palacha\",\n  \"Nám. Jiřího Berana\",\n  \"Nám. Jiřího Z Lobkovic\",\n  \"Nám. Jiřího Z Poděbrad\",\n  \"Nám. Jiřího Z Poděbrad\",\n  \"Nám. Josefa Machka\",\n  \"Nám. Kinských\",\n  \"Nám. Kinských\",\n  \"Nám. Mezi Zahrádkami\",\n  \"Nám. Na Balabence\",\n  \"Nám. Na Farkáně\",\n  \"Nám. Na Lužinách\",\n  \"Nám. Na Santince\",\n  \"Nám. Na Stráži\",\n  \"Nám. Omladiny\",\n  \"Nám. Osvoboditelů\",\n  \"Nám. Padlých\",\n  \"Nám. Pod Kaštany\",\n  \"Nám. Pod Lípou\",\n  \"Nám. Prezidenta Masaryka\",\n  \"Nám. Před Bateriemi\",\n  \"Nám. Republiky\",\n  \"Nám. Smiřických\",\n  \"Nám. Svatopluka Čecha\",\n  \"Nám. Svobody\",\n  \"Nám. U Lva\",\n  \"Nám. U Lípy Svobody\",\n  \"Nám. U Svatého Jiří\",\n  \"Nám. Winstona Churchilla\",\n  \"Nám. Českého Povstání\",\n  \"Nám.Organizace Spojených Národ\",\n  \"Nám.Plukovníka Vlčka\",\n  \"Náměstí 14. Října\",\n  \"Náměstí 25. Března\",\n  \"Náměstí Antonína Pecáka\",\n  \"Náměstí Barikád\",\n  \"Náměstí Bořislavka\",\n  \"Náměstí Bořislavka\",\n  \"Náměstí Bratří Jandusů\",\n  \"Náměstí Bratří Synků\",\n  \"Náměstí Chuchelských Bojovníků\",\n  \"Náměstí Curieových\",\n  \"Náměstí Dr. Václava Holého\",\n  \"Náměstí Generála Kutlvašra\",\n  \"Náměstí Hrdinů\",\n  \"Náměstí I. P. Pavlova\",\n  \"Náměstí Interbrigády\",\n  \"Náměstí Jana Palacha\",\n  \"Náměstí Jana Palacha\",\n  \"Náměstí Jiřího Berana\",\n  \"Náměstí Jiřího Z Lobkovic\",\n  \"Náměstí Jiřího Z Poděbrad\",\n  \"Náměstí Jiřího Z Poděbrad\",\n  \"Náměstí Josefa Machka\",\n  \"Náměstí Junkových\",\n  \"Náměstí Kinských\",\n  \"Náměstí Kinských\",\n  \"Náměstí Kosmonautů\",\n  \"Náměstí Mezi Zahrádkami\",\n  \"Náměstí Míru\",\n  \"Náměstí Na Balabence\",\n  \"Náměstí Na Farkáně\",\n  \"Náměstí Na Lužinách\",\n  \"Náměstí Na Santince\",\n  \"Náměstí Na Stráži\",\n  \"Náměstí Omladiny\",\n  \"Náměstí Organizace Spojených Národů\",\n  \"Náměstí Osvoboditelů\",\n  \"Náměstí Padlých\",\n  \"Náměstí Plukovníka Vlčka\",\n  \"Náměstí Pod Emauzy\",\n  \"Náměstí Pod Kaštany\",\n  \"Náměstí Pod Lípou\",\n  \"Náměstí Prezidenta Masaryka\",\n  \"Náměstí Protifašistických Bojovníků\",\n  \"Náměstí Před Bateriemi\",\n  \"Náměstí Přátelství\",\n  \"Náměstí Republiky\",\n  \"Náměstí Republiky\",\n  \"Náměstí Smiřických\",\n  \"Náměstí Sv. Petra A Pavla\",\n  \"Náměstí Svatopluka Čecha\",\n  \"Náměstí Svobody\",\n  \"Náměstí U Lva\",\n  \"Náměstí U Lípy Svobody\",\n  \"Náměstí U Svatého Jiří\",\n  \"Náměstí Winstona Churchilla\",\n  \"Náměstí Zdenky Braunerové\",\n  \"Náměstí Českého Povstání\",\n  \"Náplavní\",\n  \"Náprstkova\",\n  \"Národní\",\n  \"Národní\",\n  \"Národní Obrany\",\n  \"Národních Hrdinů\",\n  \"Nárožní\",\n  \"Násirovo Nám.\",\n  \"Násirovo Náměstí\",\n  \"Nástrojářská\",\n  \"Návazná\",\n  \"Návršní\",\n  \"Návětrná\",\n  \"Návětrná\",\n  \"Názovská\",\n  \"Nýdecká\",\n  \"Nýrská\",\n  \"Nýřanská\",\n  \"Němčická\",\n  \"Něvská\",\n  \"Obchodní\",\n  \"Obchodní Nám.\",\n  \"Obchodní Náměstí\",\n  \"Obilní\",\n  \"Objízdná\",\n  \"Oblouková\",\n  \"Obora Hvězda\",\n  \"Oborská\",\n  \"Obrataňská\",\n  \"Obrovského\",\n  \"Obsiny\",\n  \"Obslužná\",\n  \"Obvodová\",\n  \"Obědovická\",\n  \"Obětí 6. Května\",\n  \"Obětí 6.Května\",\n  \"Ocelkova\",\n  \"Ocelářská\",\n  \"Ocelářská\",\n  \"Ocelíkova\",\n  \"Ochozská\",\n  \"Ochranovská\",\n  \"Od Rozcestí\",\n  \"Od Vysoké\",\n  \"Od Školy\",\n  \"Odboje\",\n  \"Odborů\",\n  \"Odbočná\",\n  \"Oddechová\",\n  \"Oddělená\",\n  \"Oderská\",\n  \"Odlehlá\",\n  \"Ohmova\",\n  \"Ohnivcova\",\n  \"Ohnišťanská\",\n  \"Ohradní\",\n  \"Ohradní\",\n  \"Ohradská\",\n  \"Ohradské Nám.\",\n  \"Ohradské Náměstí\",\n  \"Ohrobecká\",\n  \"Okenská\",\n  \"Okořská\",\n  \"Okrajní\",\n  \"Okrajová\",\n  \"Okrajová\",\n  \"Okrasná\",\n  \"Okrouhlická\",\n  \"Okrouhlíkova\",\n  \"Okrová\",\n  \"Okruhová\",\n  \"Okružní\",\n  \"Okružní\",\n  \"Okřínecká\",\n  \"Olbrachtova\",\n  \"Olbramovická\",\n  \"Oldřichova\",\n  \"Olešnická\",\n  \"Olešská\",\n  \"Olgy Havlové\",\n  \"Olivova\",\n  \"Olomoucká\",\n  \"Olympijská\",\n  \"Olšanská\",\n  \"Olšanské Nám.\",\n  \"Olšanské Náměstí\",\n  \"Olšovická\",\n  \"Olšová\",\n  \"Olštýnská\",\n  \"Omladinářů\",\n  \"Omská\",\n  \"Ondřejovská\",\n  \"Ondříčkova\",\n  \"Ondříčkova\",\n  \"Onšovecká\",\n  \"Opata Konráda\",\n  \"Opatovická\",\n  \"Opatovská\",\n  \"Opatovská\",\n  \"Opatřilka\",\n  \"Opatřilka\",\n  \"Opařanská\",\n  \"Oplanská\",\n  \"Opletalova\",\n  \"Opolská\",\n  \"Opočenská\",\n  \"Opočínská\",\n  \"Opravářská\",\n  \"Opuková\",\n  \"Opálkova\",\n  \"Opálová\",\n  \"Oravská\",\n  \"Ordovická\",\n  \"Orebitská\",\n  \"Orelská\",\n  \"Orlická\",\n  \"Ortenovo Náměstí\",\n  \"Osadní\",\n  \"Osamocená\",\n  \"Osecká\",\n  \"Osetá\",\n  \"Osická\",\n  \"Osiková\",\n  \"Osinalická\",\n  \"Osluněná\",\n  \"Osmého Listopadu\",\n  \"Osnická\",\n  \"Osnická\",\n  \"Osnická\",\n  \"Ostravická\",\n  \"Ostravská\",\n  \"Ostromečská\",\n  \"Ostrov Štvanice\",\n  \"Ostrovní\",\n  \"Ostrovského\",\n  \"Ostruženská\",\n  \"Ostružinová\",\n  \"Ostrá\",\n  \"Ostrčilovo Nám.\",\n  \"Ostrčilovo Náměstí\",\n  \"Ostředecká\",\n  \"Ostřicová\",\n  \"Osvobození\",\n  \"Osvětová\",\n  \"Otakara Vrby\",\n  \"Otakarova\",\n  \"Otavova\",\n  \"Otavova\",\n  \"Otavská\",\n  \"Otevřená\",\n  \"Otická\",\n  \"Otlíkovská\",\n  \"Otopašská\",\n  \"Otovická\",\n  \"Otradovická\",\n  \"Ottova\",\n  \"Otvovická\",\n  \"Oty Pavla\",\n  \"Otínská\",\n  \"Otěšínská\",\n  \"Ouholická\",\n  \"Ouhrabkova\",\n  \"Ovenecká\",\n  \"Ovenecká\",\n  \"Ovesná\",\n  \"Ovocná\",\n  \"Ovocnářská\",\n  \"Ovocný Trh\",\n  \"Ovsíková\",\n  \"Oválová\",\n  \"Ovčárská\",\n  \"Ovčí Hájek\",\n  \"Ořechová\",\n  \"Ořešská\",\n  \"Paběnická\",\n  \"Paběnická\",\n  \"Pacajevova\",\n  \"Paceřická\",\n  \"Pacholíkova\",\n  \"Pacovská\",\n  \"Paculova\",\n  \"Padovská\",\n  \"Pajerova\",\n  \"Pakoměřická\",\n  \"Palackého\",\n  \"Palackého Nám.\",\n  \"Palackého Náměstí\",\n  \"Palmetová\",\n  \"Palmovka\",\n  \"Paláskova\",\n  \"Pampelišková\",\n  \"Pancířova\",\n  \"Panelová\",\n  \"Panenky\",\n  \"Panenská\",\n  \"Pankrácké Náměstí\",\n  \"Panská\",\n  \"Panská Zahrada\",\n  \"Panský Dvůr\",\n  \"Panuškova\",\n  \"Paprsková\",\n  \"Papírenská\",\n  \"Papírníkova\",\n  \"Parašutistů\",\n  \"Pardubická\",\n  \"Park Přátelství\",\n  \"Parková\",\n  \"Parléřova\",\n  \"Parléřova\",\n  \"Parmská\",\n  \"Paroplavební\",\n  \"Partyzánská\",\n  \"Pasecká\",\n  \"Pasteurova\",\n  \"Pastevců\",\n  \"Patočkova\",\n  \"Patočkova\",\n  \"Patočkova\",\n  \"Pavelkova\",\n  \"Pavla Beneše\",\n  \"Pavla Švandy Ze Semčic\",\n  \"Pavlická\",\n  \"Pavlišovská\",\n  \"Pavlovická\",\n  \"Pavlovská\",\n  \"Pavlíkova\",\n  \"Pavrovského\",\n  \"Paříkova\",\n  \"Pařízkova\",\n  \"Pařížská\",\n  \"Pařížská\",\n  \"Paškova\",\n  \"Paťanka\",\n  \"Peceradská\",\n  \"Pecharova\",\n  \"Pechlátova\",\n  \"Pechlátova\",\n  \"Pecháčkova\",\n  \"Peckova\",\n  \"Pejevové\",\n  \"Pekařova\",\n  \"Pekařova\",\n  \"Pekařská\",\n  \"Pekárenská\",\n  \"Pekárkova\",\n  \"Pelclova\",\n  \"Pelechovská\",\n  \"Pelhřimovská\",\n  \"Pelikánova\",\n  \"Pelléova\",\n  \"Pelléova\",\n  \"Pelnářova\",\n  \"Pelušková\",\n  \"Pelyňková\",\n  \"Pelzova\",\n  \"Penízovková\",\n  \"Perlitová\",\n  \"Perlitová\",\n  \"Perlová\",\n  \"Pernerova\",\n  \"Pernerova\",\n  \"Peroutkova\",\n  \"Peroutkova\",\n  \"Peroutkova\",\n  \"Peroutkova\",\n  \"Perspektivní\",\n  \"Pertoldova\",\n  \"Perucká\",\n  \"Perunova\",\n  \"Perštejnská\",\n  \"Petra Bezruče\",\n  \"Petra Rezka\",\n  \"Petra Slezáka\",\n  \"Petrbokova\",\n  \"Petrklíčová\",\n  \"Petrohradská\",\n  \"Petrovická\",\n  \"Petrovská\",\n  \"Petrská\",\n  \"Petrské Nám.\",\n  \"Petrské Náměstí\",\n  \"Petráčkova\",\n  \"Petržílkova\",\n  \"Petržílova\",\n  \"Petýrkova\",\n  \"Petříkova\",\n  \"Petříkovská\",\n  \"Petřínská\",\n  \"Petřínská\",\n  \"Petřínské Sady\",\n  \"Petřínské Sady\",\n  \"Pevnostní\",\n  \"Pečárková\",\n  \"Pešinova\",\n  \"Peškova\",\n  \"Pešlova\",\n  \"Pešova\",\n  \"Peštukova\",\n  \"Pešákova\",\n  \"Picassova\",\n  \"Pickova\",\n  \"Pihelská\",\n  \"Pikovická\",\n  \"Pikrtova\",\n  \"Pilařská\",\n  \"Pilníkovská\",\n  \"Pilotů\",\n  \"Pilovská\",\n  \"Pilovská\",\n  \"Pilská\",\n  \"Pirinská\",\n  \"Pirnerova\",\n  \"Pitkovická\",\n  \"Pitterova\",\n  \"Pivcova\",\n  \"Pivovarnická\",\n  \"Pivovarská\",\n  \"Pivoňková\",\n  \"Pištěkova\",\n  \"Placina\",\n  \"Placina\",\n  \"Plajnerova\",\n  \"Plamínkové\",\n  \"Plaská\",\n  \"Platanová\",\n  \"Platnéřská\",\n  \"Platónova\",\n  \"Plavecká\",\n  \"Plavínová\",\n  \"Plačická\",\n  \"Plaňanská\",\n  \"Plevenská\",\n  \"Plečnikova\",\n  \"Plhovská\",\n  \"Plickova\",\n  \"Plkovská\",\n  \"Plojharova\",\n  \"Ploskovická\",\n  \"Ploučnická\",\n  \"Plovdivská\",\n  \"Plošná\",\n  \"Ploštilova\",\n  \"Plukovníka Mráze\",\n  \"Plumlovská\",\n  \"Plutova\",\n  \"Plynární\",\n  \"Plzeňská\",\n  \"Plzeňská\",\n  \"Plzeňská\",\n  \"Plzeňská\",\n  \"Plzeňská\",\n  \"Plánická\",\n  \"Pláničkova\",\n  \"Poberova\",\n  \"Pobočná\",\n  \"Pobořská\",\n  \"Poběžovická\",\n  \"Pobřežní\",\n  \"Pobřežní Cesta\",\n  \"Pod Akáty\",\n  \"Pod Altánem\",\n  \"Pod Altánem\",\n  \"Pod Andělkou\",\n  \"Pod Areálem\",\n  \"Pod Aritmou\",\n  \"Pod Ateliéry\",\n  \"Pod Bahnivkou\",\n  \"Pod Balkánem\",\n  \"Pod Barvířkou\",\n  \"Pod Bateriemi\",\n  \"Pod Baštami\",\n  \"Pod Belvederem\",\n  \"Pod Belárií\",\n  \"Pod Beránkem\",\n  \"Pod Beránkou\",\n  \"Pod Betání\",\n  \"Pod Bohdalcem I\",\n  \"Pod Bohdalcem I\",\n  \"Pod Bohdalcem Ii\",\n  \"Pod Brentovou\",\n  \"Pod Bruskou\",\n  \"Pod Buďánkou\",\n  \"Pod Bání\",\n  \"Pod Březinou\",\n  \"Pod Chaloupkami\",\n  \"Pod Chodovem\",\n  \"Pod Cihelnou\",\n  \"Pod Cihelnou\",\n  \"Pod Cukrákem\",\n  \"Pod Císařkou\",\n  \"Pod Dlážděnkou\",\n  \"Pod Domky\",\n  \"Pod Drinopolem\",\n  \"Pod Dráhou\",\n  \"Pod Duby\",\n  \"Pod Dvorem\",\n  \"Pod Dálnicí\",\n  \"Pod Děkankou\",\n  \"Pod Děkankou\",\n  \"Pod Děvínem\",\n  \"Pod Farou\",\n  \"Pod Fialkou\",\n  \"Pod Formankou\",\n  \"Pod Fořtem\",\n  \"Pod Garážemi\",\n  \"Pod Habrovkou\",\n  \"Pod Habrovou\",\n  \"Pod Haltýřem\",\n  \"Pod Harfou\",\n  \"Pod Havlínem\",\n  \"Pod Havránkou\",\n  \"Pod Havránkou\",\n  \"Pod Hliništěm\",\n  \"Pod Hloubětínskou Zastávkou\",\n  \"Pod Hláskem\",\n  \"Pod Homolkou\",\n  \"Pod Hotelem\",\n  \"Pod Hořavkou\",\n  \"Pod Hrachovkou\",\n  \"Pod Hradbami\",\n  \"Pod Hradem\",\n  \"Pod Hranicí\",\n  \"Pod Hrází\",\n  \"Pod Hvězdou\",\n  \"Pod Hvězdárnou\",\n  \"Pod Hvězdárnou\",\n  \"Pod Hybšmankou\",\n  \"Pod Hájem\",\n  \"Pod Hájkem\",\n  \"Pod Hájovnou\",\n  \"Pod Hřbitovem\",\n  \"Pod Hřištěm\",\n  \"Pod Jalovým Dvorem\",\n  \"Pod Jankovem\",\n  \"Pod Jarovem\",\n  \"Pod Javory\",\n  \"Pod Jiráskovou Čtvrtí\",\n  \"Pod Juliskou\",\n  \"Pod Kamínkou\",\n  \"Pod Kapličkou\",\n  \"Pod Kapličkou\",\n  \"Pod Karlovarskou Silnicí\",\n  \"Pod Karlovem\",\n  \"Pod Kavalírkou\",\n  \"Pod Kaštany\",\n  \"Pod Kaštany\",\n  \"Pod Kesnerkou\",\n  \"Pod Kladenskou Silnicí\",\n  \"Pod Klamovkou\",\n  \"Pod Klapicí\",\n  \"Pod Klaudiánkou\",\n  \"Pod Klikovkou\",\n  \"Pod Kopcem\",\n  \"Pod Kostelem\",\n  \"Pod Kotlaskou\",\n  \"Pod Kotlářkou\",\n  \"Pod Kotlářkou\",\n  \"Pod Kotlářkou\",\n  \"Pod Krejcárkem\",\n  \"Pod Krocínkou\",\n  \"Pod Královkou\",\n  \"Pod Krčským Lesem\",\n  \"Pod Kulturním Domem\",\n  \"Pod Kynclovkou\",\n  \"Pod Křížem\",\n  \"Pod Křížkem\",\n  \"Pod Labuťkou\",\n  \"Pod Lahovskou\",\n  \"Pod Lesem\",\n  \"Pod Lesíkem\",\n  \"Pod Letištěm\",\n  \"Pod Lečí\",\n  \"Pod Lipami\",\n  \"Pod Lipkami\",\n  \"Pod Lisem\",\n  \"Pod Lisem\",\n  \"Pod Lochkovem\",\n  \"Pod Lomem\",\n  \"Pod Lysinami\",\n  \"Pod Lázní\",\n  \"Pod Marjánkou\",\n  \"Pod Markétou\",\n  \"Pod Martinem\",\n  \"Pod Meliškou\",\n  \"Pod Mlýnkem\",\n  \"Pod Mohylou\",\n  \"Pod Mostem\",\n  \"Pod Napětím\",\n  \"Pod Nouzovem\",\n  \"Pod Novou Školou\",\n  \"Pod Novým Lesem\",\n  \"Pod Novým Lesem\",\n  \"Pod Nuselskými Schody\",\n  \"Pod Náměstím\",\n  \"Pod Náplavkou\",\n  \"Pod Náplavkou\",\n  \"Pod Náspem\",\n  \"Pod Návsí\",\n  \"Pod Oborou\",\n  \"Pod Ovčínem\",\n  \"Pod Ořechovkou\",\n  \"Pod Palatou\",\n  \"Pod Palírkou\",\n  \"Pod Parukářkou\",\n  \"Pod Paťankou\",\n  \"Pod Paťankou\",\n  \"Pod Pekařkou\",\n  \"Pod Pekárnami\",\n  \"Pod Petřinami\",\n  \"Pod Plynojemem\",\n  \"Pod Plynojemem\",\n  \"Pod Plynojemem\",\n  \"Pod Plískavou\",\n  \"Pod Poštou\",\n  \"Pod Pramenem\",\n  \"Pod Prodejnou\",\n  \"Pod Průsekem\",\n  \"Pod Písečnou\",\n  \"Pod Přehradou\",\n  \"Pod Přesypem\",\n  \"Pod Radnicí\",\n  \"Pod Rapidem\",\n  \"Pod Rapidem\",\n  \"Pod Rapidem\",\n  \"Pod Remízkem\",\n  \"Pod Rovinou\",\n  \"Pod Rozvodnou\",\n  \"Pod Rybníkem\",\n  \"Pod Rybníčkem\",\n  \"Pod Sady\",\n  \"Pod Salabkou\",\n  \"Pod Sirénou\",\n  \"Pod Skalkou\",\n  \"Pod Skalou\",\n  \"Pod Sklenářkou\",\n  \"Pod Slovany\",\n  \"Pod Smetankou\",\n  \"Pod Sokolovnou\",\n  \"Pod Soutratím\",\n  \"Pod Spalovnou\",\n  \"Pod Spiritkou\",\n  \"Pod Spravedlností\",\n  \"Pod Srázem\",\n  \"Pod Stadiony\",\n  \"Pod Stanicí\",\n  \"Pod Starou Školou\",\n  \"Pod Starákem\",\n  \"Pod Statky\",\n  \"Pod Strašnickou Vinicí\",\n  \"Pod Strojírnami\",\n  \"Pod Strání\",\n  \"Pod Studánkou\",\n  \"Pod Stupni\",\n  \"Pod Stárkou\",\n  \"Pod Stárkou\",\n  \"Pod Stírkou\",\n  \"Pod Svahem\",\n  \"Pod Sychrovem I\",\n  \"Pod Sychrovem I\",\n  \"Pod Sychrovem I\",\n  \"Pod Sychrovem Ii\",\n  \"Pod Sídlištěm\",\n  \"Pod Terasami\",\n  \"Pod Terebkou\",\n  \"Pod Topoly\",\n  \"Pod Tratí\",\n  \"Pod Turnovskou Tratí\",\n  \"Pod Turnovskou Tratí\",\n  \"Pod Táborem\",\n  \"Pod Táborem\",\n  \"Pod Třebešínem\",\n  \"Pod Třešněmi\",\n  \"Pod Třešňovkou\",\n  \"Pod Urnovým Hájem\",\n  \"Pod Valem\",\n  \"Pod Vartou\",\n  \"Pod Vavřincem\",\n  \"Pod Velkým Hájem\",\n  \"Pod Viaduktem\",\n  \"Pod Vidoulí\",\n  \"Pod Viktorkou\",\n  \"Pod Vilami\",\n  \"Pod Vinicemi\",\n  \"Pod Vinicí\",\n  \"Pod Vinohradem\",\n  \"Pod Višňovkou\",\n  \"Pod Vlachovkou\",\n  \"Pod Vlastním Krovem\",\n  \"Pod Vlkem\",\n  \"Pod Vodojemem\",\n  \"Pod Vodovodem\",\n  \"Pod Vodárenskou Věží\",\n  \"Pod Vrchem\",\n  \"Pod Vrcholem\",\n  \"Pod Vrstevnicí\",\n  \"Pod Vrškem\",\n  \"Pod Vrškem\",\n  \"Pod Vršovickou Vodárnou I\",\n  \"Pod Vršovickou Vodárnou Ii\",\n  \"Pod Vršovickou Vodárnou Iii\",\n  \"Pod Vsí\",\n  \"Pod Vyhlídkou\",\n  \"Pod Vysokou\",\n  \"Pod Vysokou Mezí\",\n  \"Pod Vysílačkou\",\n  \"Pod Vyšehradem\",\n  \"Pod Václavem\",\n  \"Pod Vítkovem\",\n  \"Pod Výtopnou\",\n  \"Pod Výšinkou\",\n  \"Pod Větrolamem\",\n  \"Pod Větrovem\",\n  \"Pod Věží\",\n  \"Pod Zahradami\",\n  \"Pod Zahrádkami\",\n  \"Pod Zastávkou\",\n  \"Pod Zatáčkou\",\n  \"Pod Zbuzany\",\n  \"Pod Zemankou\",\n  \"Pod Zličínem\",\n  \"Pod Zvonařkou\",\n  \"Pod Zvoničkou\",\n  \"Pod Zámečkem\",\n  \"Pod Závěrkou\",\n  \"Pod Útesy\",\n  \"Pod Čertovou Skalou\",\n  \"Pod Čihadlem\",\n  \"Pod Čimickým Hájem\",\n  \"Pod Šancemi\",\n  \"Pod Školou\",\n  \"Pod Šmukýřkou\",\n  \"Pod Špejcharem\",\n  \"Pod Špitálem\",\n  \"Pod Štěpem\",\n  \"Pod Žvahovem\",\n  \"Podbabská\",\n  \"Podbabská\",\n  \"Podbělohorská\",\n  \"Podbělová\",\n  \"Podchýšská\",\n  \"Podedvorská\",\n  \"Podhajská Pole\",\n  \"Podholí\",\n  \"Podhorská\",\n  \"Podhořská\",\n  \"Podivínská\",\n  \"Podjavorinské\",\n  \"Podjezd\",\n  \"Podkovářská\",\n  \"Podkrkonošská\",\n  \"Podkrkonošských Tkalců\",\n  \"Podle Kačerova\",\n  \"Podle Lomu\",\n  \"Podle Lomu\",\n  \"Podle Náhonu\",\n  \"Podle Náhonu\",\n  \"Podle Sadů\",\n  \"Podle Trati\",\n  \"Podlesek\",\n  \"Podleská\",\n  \"Podlesní\",\n  \"Podlešínská\",\n  \"Podlibská\",\n  \"Podlipného\",\n  \"Podlišovská\",\n  \"Podlužanská\",\n  \"Podléšková\",\n  \"Podnikatelská\",\n  \"Podnádražní\",\n  \"Podohradská\",\n  \"Podolanská\",\n  \"Podolská\",\n  \"Podolská\",\n  \"Podolské Nábř.\",\n  \"Podolské Nábřeží\",\n  \"Podolské Schody\",\n  \"Podpěrova\",\n  \"Podskalská\",\n  \"Podsychrovská\",\n  \"Podvinný Mlýn\",\n  \"Podvinný Mlýn\",\n  \"Podzámecká\",\n  \"Podéšťova\",\n  \"Poděbradova\",\n  \"Poděbradova\",\n  \"Poděbradská\",\n  \"Poděbradská\",\n  \"Poděbradská\",\n  \"Podůlší\",\n  \"Pohledná\",\n  \"Pohnertova\",\n  \"Pohořelec\",\n  \"Pohořelec\",\n  \"Pokojná\",\n  \"Pokorného\",\n  \"Pokřivená\",\n  \"Polabská\",\n  \"Polabská\",\n  \"Polaneckého\",\n  \"Polední\",\n  \"Polední\",\n  \"Polenská\",\n  \"Polepská\",\n  \"Poleradská\",\n  \"Polesná\",\n  \"Polešovická\",\n  \"Politických Vězňů\",\n  \"Poličanská\",\n  \"Poljanovova\",\n  \"Polní\",\n  \"Polovnická\",\n  \"Polská\",\n  \"Polygrafická\",\n  \"Polákova\",\n  \"Poláčkova\",\n  \"Políkenská\",\n  \"Polívkova\",\n  \"Pomezní\",\n  \"Pomněnková\",\n  \"Pomořanská\",\n  \"Ponrepova\",\n  \"Poplužní\",\n  \"Popovická\",\n  \"Popovova\",\n  \"Poslední\",\n  \"Pospíchalova\",\n  \"Pospíšilova\",\n  \"Postlova\",\n  \"Postranní\",\n  \"Postupická\",\n  \"Postřekovská\",\n  \"Postřižínská\",\n  \"Postřižínská\",\n  \"Potocká\",\n  \"Potoční\",\n  \"Pouchova\",\n  \"Poupětova\",\n  \"Poustka\",\n  \"Povltavská\",\n  \"Povltavská\",\n  \"Povltavská\",\n  \"Povodňová\",\n  \"Pozdeňská\",\n  \"Poznaňská\",\n  \"Počeradská\",\n  \"Počernická\",\n  \"Počernická\",\n  \"Počátecká\",\n  \"Počátecká\",\n  \"Poříčanská\",\n  \"Poříčanská\",\n  \"Poříčská\",\n  \"Pošepného Nám.\",\n  \"Pošepného Náměstí\",\n  \"Poštovská\",\n  \"Požárnická\",\n  \"Pplk. Nováčka\",\n  \"Pplk. Sochora\",\n  \"Prachatická\",\n  \"Prachnerova\",\n  \"Prachovická\",\n  \"Prachovská\",\n  \"Pramenná\",\n  \"Pramenná\",\n  \"Pravoúhlá\",\n  \"Pravská\",\n  \"Pravá\",\n  \"Prašná\",\n  \"Pražská\",\n  \"Pražského\",\n  \"Pražského Povstání\",\n  \"Pražský Okruh\",\n  \"Pražákovská\",\n  \"Prefátova\",\n  \"Preislerova\",\n  \"Preláta\",\n  \"Prelátská\",\n  \"Preslova\",\n  \"Primátorská\",\n  \"Probluzská\",\n  \"Proboštská\",\n  \"Procházkova\",\n  \"Prodloužená\",\n  \"Prokofjevova\",\n  \"Prokopka\",\n  \"Prokopova\",\n  \"Prokopovo Nám.\",\n  \"Prokopovo Náměstí\",\n  \"Prokopových\",\n  \"Prokopská\",\n  \"Prokopské Údolí\",\n  \"Prokopské Údolí\",\n  \"Prorektorská\",\n  \"Prosecká\",\n  \"Prosecká\",\n  \"Prosecká\",\n  \"Prosincová\",\n  \"Prosluněná\",\n  \"Prosná\",\n  \"Prostřední\",\n  \"Proti Proudu\",\n  \"Protilehlá\",\n  \"Protivínská\",\n  \"Proutěná\",\n  \"Prouzova\",\n  \"Provaznická\",\n  \"Provozní\",\n  \"Prunéřovská\",\n  \"Prusická\",\n  \"Prusíkova\",\n  \"Prušánecká\",\n  \"Prvního Pluku\",\n  \"Prvního Pluku\",\n  \"Prvomájová\",\n  \"Prácheňská\",\n  \"Práčská\",\n  \"Průběžná\",\n  \"Průchodní\",\n  \"Průchova\",\n  \"Průhledová\",\n  \"Průhonek\",\n  \"Průhonek\",\n  \"Průhonická\",\n  \"Průhonská\",\n  \"Průjezdná\",\n  \"Průmyslová\",\n  \"Průmyslová\",\n  \"Průmyslová\",\n  \"Průmyslová\",\n  \"Průtažní\",\n  \"Průčelní\",\n  \"Průškova\",\n  \"Psohlavců\",\n  \"Pstružná\",\n  \"Psárská\",\n  \"Ptáčnická\",\n  \"Puchmajerova\",\n  \"Puchmajerova\",\n  \"Pujmanové\",\n  \"Pujmanové\",\n  \"Pujmanové\",\n  \"Purkrabská\",\n  \"Purkyňova\",\n  \"Putimská\",\n  \"Pučova\",\n  \"Puškinovo Nám.\",\n  \"Puškinovo Náměstí\",\n  \"Pyšelská\",\n  \"Pálavská\",\n  \"Pálkařská\",\n  \"Pámelníková\",\n  \"Pánkova\",\n  \"Pátkova\",\n  \"Pávovské Náměstí\",\n  \"Písecká\",\n  \"Píseckého\",\n  \"Písečná\",\n  \"Pískařská\",\n  \"Pískovcová\",\n  \"Pískovna\",\n  \"Písková\",\n  \"Písnická\",\n  \"Písnická\",\n  \"Písnické Zahrady\",\n  \"Písčitá\",\n  \"Píškova\",\n  \"Píšovická\",\n  \"Pöslova\",\n  \"Púchovská\",\n  \"Púchovská\",\n  \"Pýchavková\",\n  \"Pýrová\",\n  \"Pěnkaví\",\n  \"Pěstitelská\",\n  \"Pětidomí\",\n  \"Pětipeského\",\n  \"Pěší\",\n  \"Přecechtělova\",\n  \"Přechodní\",\n  \"Před Cibulkami\",\n  \"Před Dráhou\",\n  \"Před Mosty\",\n  \"Před Nádražím\",\n  \"Před Oborou\",\n  \"Před Rybníkem\",\n  \"Před Skalkami I\",\n  \"Před Skalkami Ii\",\n  \"Před Skálou\",\n  \"Před Sokolovnou\",\n  \"Před Tratí\",\n  \"Před Ústavem\",\n  \"Předbořská\",\n  \"Předměřická\",\n  \"Přední\",\n  \"Předpolní\",\n  \"Předposlední\",\n  \"Předvoje\",\n  \"Předvoje\",\n  \"Předškolní\",\n  \"Přeletová\",\n  \"Přeloučská\",\n  \"Přemyslova\",\n  \"Přemyslovská\",\n  \"Přemyslovská\",\n  \"Přemyšlenská\",\n  \"Přerušená\",\n  \"Přesličková\",\n  \"Přespolní\",\n  \"Přetlucká\",\n  \"Přeučilova\",\n  \"Převoznická\",\n  \"Přezletická\",\n  \"Přeštická\",\n  \"Přeštínská\",\n  \"Přeťatá\",\n  \"Při Hranici\",\n  \"Při Hranici\",\n  \"Při Trati\",\n  \"Přibyslavská\",\n  \"Přibíkova\",\n  \"Přistoupimská\",\n  \"Přádova\",\n  \"Přátelství\",\n  \"Příborská\",\n  \"Příbramská\",\n  \"Příběnická\",\n  \"Příchovická\",\n  \"Přídolská\",\n  \"Příkrá\",\n  \"Přílepská\",\n  \"Přímské Nám.\",\n  \"Přímské Náměstí\",\n  \"Přímá\",\n  \"Přímětická\",\n  \"Přípotoční\",\n  \"Přípřežní\",\n  \"Přírodní\",\n  \"Přístavní\",\n  \"Přívorská\",\n  \"Přívozní\",\n  \"Příčka\",\n  \"Příčná\",\n  \"Pšeničná\",\n  \"Pšenčíkova\",\n  \"Pšovanská\",\n  \"Pštrossova\",\n  \"Půdova\",\n  \"Půlkruhová\",\n  \"Půlnoční\",\n  \"Půtova\",\n  \"R.A. Dvorského\",\n  \"Rabasova\",\n  \"Rabyňská\",\n  \"Rackova\",\n  \"Rackova Zahrada\",\n  \"Radbuzská\",\n  \"Radechovská\",\n  \"Radešovská\",\n  \"Radhošťská\",\n  \"Radhošťská\",\n  \"Radimova\",\n  \"Radimovická\",\n  \"Radimská\",\n  \"Radiová\",\n  \"Radiová\",\n  \"Radistů\",\n  \"Radkovská\",\n  \"Radlická\",\n  \"Radlická\",\n  \"Radlická\",\n  \"Radnické Schody\",\n  \"Radomská\",\n  \"Radonická\",\n  \"Radostavická\",\n  \"Radostná\",\n  \"Radotínská\",\n  \"Radotínská\",\n  \"Radouňova\",\n  \"Radouňova\",\n  \"Radouňova\",\n  \"Radova\",\n  \"Radovská\",\n  \"Radošovická\",\n  \"Radvanická\",\n  \"Radúzova\",\n  \"Radčina\",\n  \"Radějovská\",\n  \"Raffaelova\",\n  \"Raichlova\",\n  \"Raisova\",\n  \"Rajhradská\",\n  \"Rajmonova\",\n  \"Rajská\",\n  \"Rakousova\",\n  \"Rakovnická\",\n  \"Rakovského\",\n  \"Randova\",\n  \"Ranská\",\n  \"Ratajova\",\n  \"Ratajská\",\n  \"Ratbořská\",\n  \"Ratibořická\",\n  \"Ratibořská\",\n  \"Ratibořská\",\n  \"Ravennská\",\n  \"Račická\",\n  \"Račiněveská\",\n  \"Rašilovova\",\n  \"Rašova\",\n  \"Rašovická\",\n  \"Rašovská\",\n  \"Rašínovo Nábř.\",\n  \"Rašínovo Nábř.\",\n  \"Rašínovo Nábřeží\",\n  \"Rašínovo Nábřeží\",\n  \"Rašínská\",\n  \"Ražická\",\n  \"Reinerova\",\n  \"Rejchova\",\n  \"Rejskova\",\n  \"Rekreační\",\n  \"Rektorská\",\n  \"Rembrandtova\",\n  \"Remízková\",\n  \"Renoirova\",\n  \"Resslova\",\n  \"Revoluce\",\n  \"Revoluční\",\n  \"Revoluční\",\n  \"Rezedová\",\n  \"Rezlerova\",\n  \"Rečkova\",\n  \"Richtrova\",\n  \"Riegrova\",\n  \"Riegrovy Sady\",\n  \"Rilská\",\n  \"Ringhofferova\",\n  \"Ringhofferova\",\n  \"Rižská\",\n  \"Roblínská\",\n  \"Rochovská\",\n  \"Rochovská\",\n  \"Rodopská\",\n  \"Rodovská\",\n  \"Rodvinovská\",\n  \"Roentgenova\",\n  \"Rohanovská\",\n  \"Rohanské Nábřeží\",\n  \"Rohanský Ostrov\",\n  \"Rohatecká\",\n  \"Rohenická\",\n  \"Rohlovská\",\n  \"Rohová\",\n  \"Rohozecká\",\n  \"Rohožnická\",\n  \"Roháčova\",\n  \"Roithova\",\n  \"Rojická\",\n  \"Roklova\",\n  \"Rokycanova\",\n  \"Rokycanská\",\n  \"Rokytnická\",\n  \"Rokytná\",\n  \"Rolnická\",\n  \"Rolní\",\n  \"Romaina Rollanda\",\n  \"Romana Blahníka\",\n  \"Ronalda Reagana\",\n  \"Ronešova\",\n  \"Ronkova\",\n  \"Ronovská\",\n  \"Rooseveltova\",\n  \"Rorýsová\",\n  \"Rosečská\",\n  \"Rosická\",\n  \"Rostislavova\",\n  \"Rostoklatská\",\n  \"Rostovská\",\n  \"Rotavská\",\n  \"Rotenská\",\n  \"Roudnická\",\n  \"Rousovická\",\n  \"Rousínovská\",\n  \"Rovenská\",\n  \"Rovnoběžná\",\n  \"Rovná\",\n  \"Rozdělená\",\n  \"Rozdělovská\",\n  \"Rozhovická\",\n  \"Rozkošného\",\n  \"Rozkošská\",\n  \"Rozmarýnová\",\n  \"Rozrazilová\",\n  \"Roztocká\",\n  \"Roztylská\",\n  \"Roztylské Náměstí\",\n  \"Roztylské Sady\",\n  \"Rozvadovská\",\n  \"Rozvodova\",\n  \"Rozvojová\",\n  \"Rozárčina\",\n  \"Rozýnova\",\n  \"Rozšířená\",\n  \"Ročovská\",\n  \"Rošických\",\n  \"Roškotova\",\n  \"Rošovická\",\n  \"Rožmberská\",\n  \"Rožmitálská\",\n  \"Rožnovská\",\n  \"Rožďalovická\",\n  \"Rtyňská\",\n  \"Rubensova\",\n  \"Rubeška\",\n  \"Rubešova\",\n  \"Rubličova\",\n  \"Rubínová\",\n  \"Rudečská\",\n  \"Rudníkovská\",\n  \"Rudolfa Holeky\",\n  \"Rudoltická\",\n  \"Rudoltická\",\n  \"Rujanská\",\n  \"Rumburská\",\n  \"Rumunská\",\n  \"Rumunská\",\n  \"Ruprechtická\",\n  \"Ruská\",\n  \"Ruská\",\n  \"Ruzyňská\",\n  \"Ruzyňská\",\n  \"Ruzyňské Schody\",\n  \"Ružinovská\",\n  \"Rybalkova\",\n  \"Rybalkova\",\n  \"Rybalkova\",\n  \"Rybničná\",\n  \"Rybná\",\n  \"Rybova\",\n  \"Rybářská\",\n  \"Rybízová\",\n  \"Rychnovská\",\n  \"Rychtáře Petříka\",\n  \"Rychtáře Šimona\",\n  \"Rychtářská\",\n  \"Rypkova\",\n  \"Rytířova\",\n  \"Rytířská\",\n  \"Ryzcová\",\n  \"Ryzlinková\",\n  \"Ryšánkova\",\n  \"Rájecká\",\n  \"Rámová\",\n  \"Rápošovská\",\n  \"Rážova\",\n  \"Révová\",\n  \"Rýmařovská\",\n  \"Rýnská\",\n  \"Rýznerova\",\n  \"Růženínová\",\n  \"Růženínská\",\n  \"Růženínská\",\n  \"Růžová\",\n  \"S. K. Neumanna\",\n  \"Sabinova\",\n  \"Sadařská\",\n  \"Sadová\",\n  \"Sadská\",\n  \"Sadská\",\n  \"Sady Bratří Čapků\",\n  \"Safírová\",\n  \"Salabova\",\n  \"Salačova\",\n  \"Salmovská\",\n  \"Salvátorská\",\n  \"Samcova\",\n  \"Samohelova\",\n  \"Samota U Podleského Rybníka\",\n  \"Sarajevská\",\n  \"Saratovská\",\n  \"Sartoriova\",\n  \"Sasanková\",\n  \"Saská\",\n  \"Satalická\",\n  \"Saturnova\",\n  \"Saudkova\",\n  \"Sauerova\",\n  \"Saveljevova\",\n  \"Savojská\",\n  \"Sazečská\",\n  \"Sazečská\",\n  \"Sazovická\",\n  \"Sbíhavá I\",\n  \"Sbíhavá Ii\",\n  \"Schnirchova\",\n  \"Schodišťová\",\n  \"Schodová\",\n  \"Schoellerova\",\n  \"Schoellerova\",\n  \"Schulhoffova\",\n  \"Schwaigerova\",\n  \"Schwarzenberská\",\n  \"Schöfflerova\",\n  \"Sdružení\",\n  \"Sechterova\",\n  \"Sedlecká\",\n  \"Sedlovická\",\n  \"Sedloňovská\",\n  \"Sedlčanská\",\n  \"Sedmidomky\",\n  \"Sedmidomky\",\n  \"Sedmikrásková\",\n  \"Sedmnáctého Listopadu\",\n  \"Seidlova\",\n  \"Seifertova\",\n  \"Sekaninova\",\n  \"Sekeřická\",\n  \"Sekorova\",\n  \"Selmická\",\n  \"Selská\",\n  \"Selských Baterií\",\n  \"Semanského\",\n  \"Semická\",\n  \"Semilská\",\n  \"Semilská\",\n  \"Seminární\",\n  \"Seminářská\",\n  \"Seminářská Zahrada\",\n  \"Semonická\",\n  \"Semtínská\",\n  \"Semčická\",\n  \"Sendražická\",\n  \"Senegalská\",\n  \"Senohrabská\",\n  \"Senovážná\",\n  \"Senovážné Nám.\",\n  \"Senovážné Náměstí\",\n  \"Senožatská\",\n  \"Sestupná\",\n  \"Sestupná\",\n  \"Setbová\",\n  \"Sevastopolská\",\n  \"Severní I\",\n  \"Severní Ii\",\n  \"Severní Iii\",\n  \"Severní Iv\",\n  \"Severní Ix\",\n  \"Severní V\",\n  \"Severní Vi\",\n  \"Severní Vii\",\n  \"Severní Viii\",\n  \"Severní X\",\n  \"Severní Xi\",\n  \"Severovýchodní I\",\n  \"Severovýchodní Ii\",\n  \"Severovýchodní Iii\",\n  \"Severovýchodní Iv\",\n  \"Severovýchodní V\",\n  \"Severovýchodní Vi\",\n  \"Severozápadní I\",\n  \"Severozápadní Ii\",\n  \"Severozápadní Iii\",\n  \"Severozápadní Iv\",\n  \"Severozápadní V\",\n  \"Severozápadní Vi\",\n  \"Severýnova\",\n  \"Sevřená\",\n  \"Seydlerova\",\n  \"Sezemická\",\n  \"Sezemínská\",\n  \"Sezimova\",\n  \"Sečská\",\n  \"Sibeliova\",\n  \"Sibiřské Nám.\",\n  \"Sibiřské Náměstí\",\n  \"Sicherova\",\n  \"Sichrovského\",\n  \"Siemensova\",\n  \"Silurská\",\n  \"Sinkulova\",\n  \"Sinkulova\",\n  \"Sitteho\",\n  \"Siwiecova\",\n  \"Skalecká\",\n  \"Skalnatá\",\n  \"Skalnická\",\n  \"Skalní\",\n  \"Skalská\",\n  \"Skaláků\",\n  \"Skandinávská\",\n  \"Skandinávská\",\n  \"Skautská\",\n  \"Sklenská\",\n  \"Skloněná\",\n  \"Sklářská\",\n  \"Skokanská\",\n  \"Skorkovská\",\n  \"Skorkovská\",\n  \"Skotská\",\n  \"Skořepka\",\n  \"Skořicová\",\n  \"Skryjská\",\n  \"Skupova\",\n  \"Skuteckého\",\n  \"Skálova\",\n  \"Skřivanova\",\n  \"Skřivanská\",\n  \"Skřivánčí\",\n  \"Sladkovského Nám.\",\n  \"Sladkovského Náměstí\",\n  \"Sladovnická\",\n  \"Slancova\",\n  \"Slaná\",\n  \"Slapská\",\n  \"Slatinová\",\n  \"Slatinská\",\n  \"Slatiny\",\n  \"Slatiňanská\",\n  \"Slavatova\",\n  \"Slaviborské Nám.\",\n  \"Slaviborské Náměstí\",\n  \"Slavická\",\n  \"Slavičí\",\n  \"Slavičínská\",\n  \"Slavníkova\",\n  \"Slavojova\",\n  \"Slavonická\",\n  \"Slavíkova\",\n  \"Slavíkova\",\n  \"Slavíkova\",\n  \"Slavínského\",\n  \"Slavíčkova\",\n  \"Slavětínská\",\n  \"Slepá I\",\n  \"Slepá Ii\",\n  \"Slezanů\",\n  \"Slezská\",\n  \"Slezská\",\n  \"Sliačská\",\n  \"Sliačská\",\n  \"Slibná\",\n  \"Slinková\",\n  \"Slivenecká\",\n  \"Slovanský Ostrov\",\n  \"Slovačíkova\",\n  \"Slovenská\",\n  \"Slovenská\",\n  \"Slovinská\",\n  \"Slunečnicová\",\n  \"Slunečná\",\n  \"Sluneční\",\n  \"Sluneční Nám.\",\n  \"Sluneční Náměstí\",\n  \"Slunná\",\n  \"Sluštická\",\n  \"Služeb\",\n  \"Služeb\",\n  \"Služská\",\n  \"Sládkova\",\n  \"Sládkovičova\",\n  \"Slámova\",\n  \"Slánská\",\n  \"Slávy Horníka\",\n  \"Slévačská\",\n  \"Slévačská\",\n  \"Slévačská\",\n  \"Slídová\",\n  \"Slívová\",\n  \"Smaragdová\",\n  \"Smetanovo Nábř.\",\n  \"Smetanovo Nábřeží\",\n  \"Smetáčkova\",\n  \"Smidarská\",\n  \"Smikova\",\n  \"Smiřická\",\n  \"Smiřického\",\n  \"Smolenská\",\n  \"Smolkova\",\n  \"Smolíkova\",\n  \"Smotlachova\",\n  \"Smotlachova\",\n  \"Smrková\",\n  \"Smrčinská\",\n  \"Smržovská\",\n  \"Smržová\",\n  \"Smíchovská\",\n  \"Smíchovská\",\n  \"Smíchovská\",\n  \"Smírná\",\n  \"Snopkova\",\n  \"Sněmovní\",\n  \"Sněženková\",\n  \"Sněžná\",\n  \"Sobolákova\",\n  \"Soborská\",\n  \"Sobotecká\",\n  \"Sobínská\",\n  \"Soběslavova\",\n  \"Soběslavská\",\n  \"Sobětická\",\n  \"Sobětušská\",\n  \"Soběšínská\",\n  \"Sochařská\",\n  \"Socháňova\",\n  \"Sodomkova\",\n  \"Sofijské Nám.\",\n  \"Sofijské Náměstí\",\n  \"Sojkovská\",\n  \"Sojovická\",\n  \"Sojčí\",\n  \"Sojčí\",\n  \"Sokolovská\",\n  \"Sokolovská\",\n  \"Sokolovská\",\n  \"Sokolovská\",\n  \"Sokolská\",\n  \"Sokratova\",\n  \"Solidarity\",\n  \"Solnická\",\n  \"Solná\",\n  \"Sopotská\",\n  \"Sosnovecká\",\n  \"Souběžná I\",\n  \"Souběžná Ii\",\n  \"Souběžná Iii\",\n  \"Souběžná Iv\",\n  \"Soudní\",\n  \"Soukalova\",\n  \"Soukenická\",\n  \"Soumarská\",\n  \"Sousední\",\n  \"Sousední\",\n  \"Sousedská\",\n  \"Sousedíkova\",\n  \"Soustružnická\",\n  \"Soustružnická\",\n  \"Souvratní\",\n  \"Součkova\",\n  \"Sovenická\",\n  \"Sovova\",\n  \"Sovákova\",\n  \"Soví Vršek\",\n  \"Spinozova\",\n  \"Spiritka\",\n  \"Splavná\",\n  \"Spodní\",\n  \"Spojařů\",\n  \"Spojenců\",\n  \"Spojená\",\n  \"Spojná\",\n  \"Spojovací\",\n  \"Spojovací\",\n  \"Spojovací\",\n  \"Spojovací\",\n  \"Spojová\",\n  \"Společná\",\n  \"Spolská\",\n  \"Spolupráce\",\n  \"Sportovců\",\n  \"Sportovců\",\n  \"Sportovní\",\n  \"Spotřebitelská\",\n  \"Spořická\",\n  \"Spořilovská\",\n  \"Spytihněvova\",\n  \"Spádná\",\n  \"Spádová\",\n  \"Spálená\",\n  \"Spálená\",\n  \"Spálený Mlýn\",\n  \"Srbova\",\n  \"Srbská\",\n  \"Srbínská\",\n  \"Srnečkova\",\n  \"Srnčí\",\n  \"Srnčí\",\n  \"Srpnová\",\n  \"Srázná\",\n  \"Stachova\",\n  \"Stadická\",\n  \"Stadionová\",\n  \"Stadiónová\",\n  \"Stallichova\",\n  \"Stamicova\",\n  \"Staniční\",\n  \"Starobylá\",\n  \"Starochodovská\",\n  \"Starochuchelská\",\n  \"Starodejvická\",\n  \"Starodubečská\",\n  \"Starodvorská\",\n  \"Staroklánovická\",\n  \"Starokolínská\",\n  \"Starokošířská\",\n  \"Starolázeňská\",\n  \"Staromlýnská\",\n  \"Staromodřanská\",\n  \"Staroměstské Nám.\",\n  \"Staroměstské Náměstí\",\n  \"Staropacká\",\n  \"Staropramenná\",\n  \"Starostrašnická\",\n  \"Starostřešovická\",\n  \"Starosuchdolská\",\n  \"Staroújezdská\",\n  \"Staročeská\",\n  \"Stará Cesta\",\n  \"Stará Náves\",\n  \"Stará Obec\",\n  \"Stará Spojovací\",\n  \"Stará Stodůlecká\",\n  \"Staré Nám.\",\n  \"Staré Náměstí\",\n  \"Staré Zámecké Schody\",\n  \"Staré Zámecké Schody\",\n  \"Starého\",\n  \"Starý Lis\",\n  \"Statenická\",\n  \"Statková\",\n  \"Stavbařů\",\n  \"Stavební\",\n  \"Stavitelská\",\n  \"Stavovská\",\n  \"Staňkova\",\n  \"Staňkovka\",\n  \"Staňkovská\",\n  \"Stehlíkova\",\n  \"Steinerova\",\n  \"Stejskalova\",\n  \"Stiessova\",\n  \"Stinkovská\",\n  \"Stochovská\",\n  \"Stodůlecká\",\n  \"Stojická\",\n  \"Stoličkova\",\n  \"Stoliňská\",\n  \"Stoupající\",\n  \"Stoupající\",\n  \"Stradonická\",\n  \"Strahovská\",\n  \"Strahovské Nádvoří\",\n  \"Strakatého\",\n  \"Strakonická\",\n  \"Strakonická\",\n  \"Strakonická\",\n  \"Strakonická\",\n  \"Strakonická\",\n  \"Strakonická\",\n  \"Strakošová\",\n  \"Strančická\",\n  \"Stratovská\",\n  \"Strašnická\",\n  \"Strašnická\",\n  \"Strašovská\",\n  \"Strašínská\",\n  \"Strmá\",\n  \"Strmý Vrch\",\n  \"Strnadova\",\n  \"Strnady\",\n  \"Strojická\",\n  \"Strojnická\",\n  \"Strojírenská\",\n  \"Stromovka\",\n  \"Stromovka\",\n  \"Stropnická\",\n  \"Stropnická\",\n  \"Stropnická\",\n  \"Strossmayerovo Nám.\",\n  \"Strossmayerovo Náměstí\",\n  \"Strouhalova\",\n  \"Stroupežnického\",\n  \"Struhařovská\",\n  \"Strunkovská\",\n  \"Stružky\",\n  \"Stružná\",\n  \"Strážkovická\",\n  \"Strážnická\",\n  \"Strážní\",\n  \"Strážovská\",\n  \"Stržná\",\n  \"Studenecká\",\n  \"Studentská\",\n  \"Studená\",\n  \"Studnická\",\n  \"Studničkova\",\n  \"Studniční\",\n  \"Studánková\",\n  \"Stulíková\",\n  \"Stupická\",\n  \"Stupkova\",\n  \"Stupská\",\n  \"Stupňová\",\n  \"Stádlecká\",\n  \"Stárkova\",\n  \"Stýblova\",\n  \"Střední\",\n  \"Středohorská\",\n  \"Středová\",\n  \"Střekovská\",\n  \"Střelecký Ostrov\",\n  \"Střelečská\",\n  \"Střelničná\",\n  \"Střelničná\",\n  \"Střemchová\",\n  \"Střešovická\",\n  \"Střešovická\",\n  \"Střimelická\",\n  \"Stříbrná\",\n  \"Stříbrského\",\n  \"Stříbrského\",\n  \"Střížkovská\",\n  \"Střížkovská\",\n  \"Střížkovská\",\n  \"Suchardova\",\n  \"Suchdolská\",\n  \"Suchdolská\",\n  \"Suchdolská\",\n  \"Suchdolské Nám.\",\n  \"Suchdolské Náměstí\",\n  \"Suchý Vršek\",\n  \"Sudkova\",\n  \"Sudoměřská\",\n  \"Sudějovická\",\n  \"Sukova\",\n  \"Sulanského\",\n  \"Sulická\",\n  \"Sulická\",\n  \"Sulova\",\n  \"Sulovická\",\n  \"Sumova\",\n  \"Suppého\",\n  \"Suttnerové\",\n  \"Sušická\",\n  \"Sušilova\",\n  \"Svahová\",\n  \"Svatavina\",\n  \"Svatojánská\",\n  \"Svatoplukova\",\n  \"Svatoslavova\",\n  \"Svatovítská\",\n  \"Svatovítská\",\n  \"Svatoňovická\",\n  \"Svažitá\",\n  \"Svijanská\",\n  \"Svitavská\",\n  \"Svitákova\",\n  \"Svobodova\",\n  \"Svobodova\",\n  \"Svojetická\",\n  \"Svojsíkova\",\n  \"Svojšická\",\n  \"Svojšovická\",\n  \"Svornosti\",\n  \"Svratecká\",\n  \"Svárovská\",\n  \"Svátkova\",\n  \"Svážná\",\n  \"Svépomoci\",\n  \"Svépomocná\",\n  \"Svépravická\",\n  \"Svépravická\",\n  \"Svídnická\",\n  \"Svěceného\",\n  \"Světická\",\n  \"Světova\",\n  \"Světská\",\n  \"Sychrovská\",\n  \"Symfonická\",\n  \"Synkovická\",\n  \"Synkovská\",\n  \"Syrská\",\n  \"Sádky\",\n  \"Sádovská\",\n  \"Sámova\",\n  \"Sárská\",\n  \"Sárská\",\n  \"Sárská\",\n  \"Sázavská\",\n  \"Sáňkařská\",\n  \"Sídlištní\",\n  \"Sídlištní\",\n  \"Sídliště\",\n  \"Súdánská\",\n  \"Sýkorčí\",\n  \"Sýkovecká\",\n  \"Tachlovická\",\n  \"Tachovská\",\n  \"Tachovské Nám.\",\n  \"Tachovské Náměstí\",\n  \"Tadrova\",\n  \"Tajovského\",\n  \"Talafúsova\",\n  \"Talichova\",\n  \"Talmberská\",\n  \"Tanvaldská\",\n  \"Tasovská\",\n  \"Tatarkova\",\n  \"Tatranská\",\n  \"Tauerova\",\n  \"Tauferova\",\n  \"Taussigova\",\n  \"Tavolníková\",\n  \"Tařicová\",\n  \"Taškentská\",\n  \"Technická\",\n  \"Technologická\",\n  \"Tehovská\",\n  \"Tejnická\",\n  \"Tejnka\",\n  \"Telčská\",\n  \"Templová\",\n  \"Tenisová\",\n  \"Teplická\",\n  \"Teplárenská\",\n  \"Teplárenská\",\n  \"Terasovitá\",\n  \"Tererova\",\n  \"Terezínská\",\n  \"Terronská\",\n  \"Tesaříkova\",\n  \"Tetínská\",\n  \"Theinova\",\n  \"Thomayerova\",\n  \"Thunovská\",\n  \"Thurnova\",\n  \"Thákurova\",\n  \"Thámova\",\n  \"Tibetská\",\n  \"Tichnova\",\n  \"Tichnova\",\n  \"Tichonická\",\n  \"Tichá\",\n  \"Tichého\",\n  \"Tigridova\",\n  \"Tikovská\",\n  \"Tilleho Nám.\",\n  \"Tilleho Náměstí\",\n  \"Tilschové\",\n  \"Tiskařská\",\n  \"Tismická\",\n  \"Tišická\",\n  \"Tlumačovská\",\n  \"Tlustého\",\n  \"Tobrucká\",\n  \"Tolstého\",\n  \"Tomanova\",\n  \"Tomická\",\n  \"Tomkova\",\n  \"Tomsova\",\n  \"Tomáškova\",\n  \"Tomášská\",\n  \"Tomíčkova\",\n  \"Topasová\",\n  \"Topolová\",\n  \"Toruňská\",\n  \"Toulovská\",\n  \"Toušeňská\",\n  \"Toušická\",\n  \"Toužimská\",\n  \"Toužimská\",\n  \"Tovarova\",\n  \"Tovačovského\",\n  \"Tovární\",\n  \"Točenská\",\n  \"Točitá\",\n  \"Trabantská\",\n  \"Trachtova\",\n  \"Trampotova\",\n  \"Travnatá\",\n  \"Travná\",\n  \"Travná\",\n  \"Trenčínská\",\n  \"Trhanovské Náměstí\",\n  \"Trmická\",\n  \"Trnavská\",\n  \"Trnavská\",\n  \"Trnitá\",\n  \"Trnkovo Nám.\",\n  \"Trnkovo Náměstí\",\n  \"Trnková\",\n  \"Trnovanská\",\n  \"Trní\",\n  \"Trocnovská\",\n  \"Troilova\",\n  \"Trojanova\",\n  \"Trojanův Mlýn\",\n  \"Trojdílná\",\n  \"Trojická\",\n  \"Trojmezní\",\n  \"Trojmezní\",\n  \"Trojská\",\n  \"Trojská\",\n  \"Trojská\",\n  \"Trojská\",\n  \"Troskovická\",\n  \"Trousilova\",\n  \"Truhlářka\",\n  \"Truhlářova\",\n  \"Truhlářská\",\n  \"Trutnovská\",\n  \"Tryskovická\",\n  \"Tryskovická\",\n  \"Trytova\",\n  \"Trávnická\",\n  \"Trávníčkova\",\n  \"Tréglova\",\n  \"Tržiště\",\n  \"Tuchoměřická\",\n  \"Tuchorazská\",\n  \"Tuchotická\",\n  \"Tuháňská\",\n  \"Tuklatská\",\n  \"Tulešická\",\n  \"Tulipánová\",\n  \"Tulkova\",\n  \"Tulská\",\n  \"Tunelářů\",\n  \"Tuniská\",\n  \"Tupolevova\",\n  \"Turgeněvova\",\n  \"Turistická\",\n  \"Turkmenská\",\n  \"Turkovická\",\n  \"Turkovská\",\n  \"Turnovská\",\n  \"Turnovského\",\n  \"Turská\",\n  \"Turínská\",\n  \"Tusarova\",\n  \"Tuřická\",\n  \"Tušimická\",\n  \"Tužebníková\",\n  \"Tvrdonická\",\n  \"Tvrdého\",\n  \"Tychonova\",\n  \"Tylišovská\",\n  \"Tylovická\",\n  \"Tylovo Nám.\",\n  \"Tylovo Náměstí\",\n  \"Tymiánová\",\n  \"Tyrkysová\",\n  \"Tyršova\",\n  \"Táboritská\",\n  \"Táborská\",\n  \"Tádžická\",\n  \"Táhlá\",\n  \"Tálínská\",\n  \"Türkova\",\n  \"Týmlova\",\n  \"Týmlova\",\n  \"Týn\",\n  \"Týnecká\",\n  \"Týnská\",\n  \"Týnská Ulička\",\n  \"Týřovická\",\n  \"Tělovýchovná\",\n  \"Těšnov\",\n  \"Těšovická\",\n  \"Těšíkova\",\n  \"Těšínská\",\n  \"Třanovského\",\n  \"Třebanická\",\n  \"Třebechovická\",\n  \"Třebenická\",\n  \"Třebešovská\",\n  \"Třebihošťská\",\n  \"Třebohostická\",\n  \"Třebonická\",\n  \"Třeboradická\",\n  \"Třebotovská\",\n  \"Třeboňská\",\n  \"Třebízského\",\n  \"Třebějická\",\n  \"Třebětínská\",\n  \"Třešňová\",\n  \"Třešňová\",\n  \"Třešňová\",\n  \"Třinecká\",\n  \"Třtinová\",\n  \"Třídomá\",\n  \"Třístoličná\",\n  \"Tůmova\",\n  \"U Akademie\",\n  \"U Akátů\",\n  \"U Albrechtova Vrchu\",\n  \"U Andělky\",\n  \"U Arborky\",\n  \"U Bakaláře\",\n  \"U Balabenky\",\n  \"U Bazénu\",\n  \"U Bažantnice\",\n  \"U Berounky\",\n  \"U Beránky\",\n  \"U Besedy\",\n  \"U Blaženky\",\n  \"U Boroviček\",\n  \"U Botiče\",\n  \"U Botiče\",\n  \"U Božích Bojovníků\",\n  \"U Branek\",\n  \"U Bruských Kasáren\",\n  \"U Brusnice\",\n  \"U Brusnice\",\n  \"U Bubce\",\n  \"U Bulhara\",\n  \"U Bulhara\",\n  \"U Bílého Mlýnku\",\n  \"U Břehu\",\n  \"U Chaloupek\",\n  \"U Chmelnice\",\n  \"U Chodovského Hřbitova\",\n  \"U Cibulky\",\n  \"U Cihelny\",\n  \"U Cikánky\",\n  \"U Cukrovaru\",\n  \"U Císařské Cesty\",\n  \"U Dejvického Rybníčku\",\n  \"U Demartinky\",\n  \"U Divadla\",\n  \"U Divadla\",\n  \"U Dobešky\",\n  \"U Dobráků\",\n  \"U Dobráků\",\n  \"U Dobřenských\",\n  \"U Domu Služeb\",\n  \"U Drahaně\",\n  \"U Druhé Baterie\",\n  \"U Druhé Baterie\",\n  \"U Drupolu\",\n  \"U Družstev\",\n  \"U Družstva Ideál\",\n  \"U Družstva Klid\",\n  \"U Družstva Práce\",\n  \"U Družstva Práce\",\n  \"U Družstva Repo\",\n  \"U Družstva Tempo\",\n  \"U Družstva Život\",\n  \"U Dráhy\",\n  \"U Dráhy\",\n  \"U Drážky\",\n  \"U Drůbežárny\",\n  \"U Dubečské Tvrze\",\n  \"U Dubu\",\n  \"U Dvojdomů\",\n  \"U Dvora\",\n  \"U Dvou Srpů\",\n  \"U Dálnice\",\n  \"U Dívčích Hradů\",\n  \"U Dívčích Hradů\",\n  \"U Děkanky\",\n  \"U Dělnického Cvičiště\",\n  \"U Dětského Domova\",\n  \"U Dětského Hřiště\",\n  \"U Elektry\",\n  \"U Elektry\",\n  \"U Elektrárny\",\n  \"U Floriána\",\n  \"U Fořta\",\n  \"U Gabrielky\",\n  \"U Garáží\",\n  \"U Golfu\",\n  \"U Gymnázia\",\n  \"U Habeše\",\n  \"U Habrovky\",\n  \"U Hadovky\",\n  \"U Harfy\",\n  \"U Hasičské Zbrojnice\",\n  \"U Hasičské Zbrojnice\",\n  \"U Havlíčkových Sadů\",\n  \"U Hellady\",\n  \"U Hercovky\",\n  \"U Hliníku\",\n  \"U Hodin\",\n  \"U Homolky\",\n  \"U Hostavického Potoka\",\n  \"U Hostivařského Nádraží\",\n  \"U Hostivařského Nádraží\",\n  \"U Hotelu\",\n  \"U Hranic\",\n  \"U Hrnčířského Rybníka\",\n  \"U Hrocha\",\n  \"U Hrušky\",\n  \"U Hráze\",\n  \"U Hudební Školy\",\n  \"U Hvozdu\",\n  \"U Hvězdy\",\n  \"U Hvězdy\",\n  \"U Háje\",\n  \"U Hájku\",\n  \"U Hájovny\",\n  \"U Házů\",\n  \"U Hřbitovů\",\n  \"U Hřiště\",\n  \"U Invalidovny\",\n  \"U Jamské\",\n  \"U Jankovky\",\n  \"U Javoru\",\n  \"U Jedličkova Ústavu\",\n  \"U Jednoty\",\n  \"U Jeslí\",\n  \"U Jezera\",\n  \"U Jezerky\",\n  \"U Jezu\",\n  \"U Jezírka\",\n  \"U Jinonického Rybníčka\",\n  \"U Jirkovské\",\n  \"U Jizby\",\n  \"U Járku\",\n  \"U Jízdárny\",\n  \"U Kabelovny\",\n  \"U Kabelovny\",\n  \"U Kaménky\",\n  \"U Kamýku\",\n  \"U Kanálky\",\n  \"U Kapliček\",\n  \"U Kapličky\",\n  \"U Karlova Stánku\",\n  \"U Kasáren\",\n  \"U Kavalírky\",\n  \"U Kazína\",\n  \"U Kašny\",\n  \"U Kaštanu\",\n  \"U Kempinku\",\n  \"U Kina\",\n  \"U Klavírky\",\n  \"U Klikovky\",\n  \"U Klimentky\",\n  \"U Kloubových Domů\",\n  \"U Klubovny\",\n  \"U Klubu\",\n  \"U Kněžské Louky\",\n  \"U Kola\",\n  \"U Kolejí\",\n  \"U Kolejí\",\n  \"U Koloděj\",\n  \"U Kolonie\",\n  \"U Koloniálu\",\n  \"U Kombinátu\",\n  \"U Konečné\",\n  \"U Koní\",\n  \"U Kosinů\",\n  \"U Kostela\",\n  \"U Kostrounku\",\n  \"U Kotlářky\",\n  \"U Koupadel\",\n  \"U Košíku\",\n  \"U Krbu\",\n  \"U Krbu\",\n  \"U Krelovy Studánky\",\n  \"U Kruhovky\",\n  \"U Královské Louky\",\n  \"U Krčské Vodárny\",\n  \"U Krčského Nádraží\",\n  \"U Kublova\",\n  \"U Kunratického Lesa\",\n  \"U Křižovatky\",\n  \"U Kříže\",\n  \"U Kříže\",\n  \"U Křížku\",\n  \"U Laboratoře\",\n  \"U Ladronky\",\n  \"U Lanové Dráhy\",\n  \"U Ledáren\",\n  \"U Lesa\",\n  \"U Lesa\",\n  \"U Lesíka\",\n  \"U Letenského Sadu\",\n  \"U Letiště\",\n  \"U Letohrádku Královny Anny\",\n  \"U Libeňského Pivovaru\",\n  \"U Libeňského Zámku\",\n  \"U Libušiných Lázní\",\n  \"U Libušské Sokolovny\",\n  \"U Lidového Domu\",\n  \"U Lip\",\n  \"U Lipové Aleje\",\n  \"U Lisu\",\n  \"U Loděnice\",\n  \"U Lomu\",\n  \"U Loskotů\",\n  \"U Louky\",\n  \"U Lužického Semináře\",\n  \"U Lázeňky\",\n  \"U Lázní\",\n  \"U Lékárny\",\n  \"U Líhní\",\n  \"U Lípy\",\n  \"U Malvazinky\",\n  \"U Malé Řeky\",\n  \"U Markéty\",\n  \"U Mateřské Školy\",\n  \"U Matěje\",\n  \"U Maří Magdaleny\",\n  \"U Meteoru\",\n  \"U Mezníku\",\n  \"U Michelské Školy\",\n  \"U Michelského Lesa\",\n  \"U Michelského Lesa\",\n  \"U Michelského Mlýna\",\n  \"U Milosrdných\",\n  \"U Mlýna\",\n  \"U Mlýna\",\n  \"U Mlýnského Rybníka\",\n  \"U Modré Školy\",\n  \"U Modřanské Školy\",\n  \"U Močálu\",\n  \"U Mrázovky\",\n  \"U Mydlárny\",\n  \"U Myslivny\",\n  \"U Městských Domů\",\n  \"U Měšťanského Pivovaru\",\n  \"U Měšťanských Škol\",\n  \"U Nadýmače\",\n  \"U Nemocenské Pojišťovny\",\n  \"U Nemocnice\",\n  \"U Nesypky\",\n  \"U Nikolajky\",\n  \"U Nové Dálnice\",\n  \"U Nové Louky\",\n  \"U Nové Školy\",\n  \"U Nového Dvora\",\n  \"U Nového Suchdola\",\n  \"U Nového Suchdola\",\n  \"U Nových Domů I\",\n  \"U Nových Domů Ii\",\n  \"U Nových Domů Iii\",\n  \"U Nových Vil\",\n  \"U Nádražní Lávky\",\n  \"U Nádraží\",\n  \"U Nádrže\",\n  \"U Náhonu\",\n  \"U Náhonu\",\n  \"U Nákladového Nádraží\",\n  \"U Nákladového Nádraží\",\n  \"U Národní Galerie\",\n  \"U Nás\",\n  \"U Obce\",\n  \"U Obecního Domu\",\n  \"U Obecního Dvora\",\n  \"U Obory\",\n  \"U Okrouhlíku\",\n  \"U Olšiček\",\n  \"U Opatrovny\",\n  \"U Ovčína\",\n  \"U Palaty\",\n  \"U Paliárky\",\n  \"U Paloučku\",\n  \"U Památníku\",\n  \"U Panské Zahrady\",\n  \"U Papírny\",\n  \"U Parku\",\n  \"U Parkánu\",\n  \"U Parního Mlýna\",\n  \"U Pastoušky\",\n  \"U Pavilónu\",\n  \"U Pazderek\",\n  \"U Pejřárny\",\n  \"U Pekařky\",\n  \"U Pekáren\",\n  \"U Pentlovky\",\n  \"U Pergamenky\",\n  \"U Pernikářky\",\n  \"U Pernštejnských\",\n  \"U Petřin\",\n  \"U Pily\",\n  \"U Plovárny\",\n  \"U Plynárny\",\n  \"U Plynárny\",\n  \"U Plátenice\",\n  \"U Podchodu\",\n  \"U Podjezdu\",\n  \"U Podolského Hřbitova\",\n  \"U Podolského Sanatoria\",\n  \"U Pohádky\",\n  \"U Polikliniky\",\n  \"U Pomníku\",\n  \"U Potoka\",\n  \"U Poustek\",\n  \"U Poštovky\",\n  \"U Pošty\",\n  \"U Pramene\",\n  \"U Prašné Brány\",\n  \"U Prašného Mostu\",\n  \"U Prašného Mostu\",\n  \"U Pražských Lomů\",\n  \"U Prefy\",\n  \"U Prioru\",\n  \"U Prknovky\",\n  \"U Prodejny\",\n  \"U Propusti\",\n  \"U Prosecké Školy\",\n  \"U Proseckého Kostela\",\n  \"U První Baterie\",\n  \"U První Baterie\",\n  \"U Prádelny\",\n  \"U Průhonu\",\n  \"U Průseku\",\n  \"U Pumpy\",\n  \"U Párníků\",\n  \"U Páté Baterie\",\n  \"U Páté Baterie\",\n  \"U Písecké Brány\",\n  \"U Pískovny\",\n  \"U Přechodu\",\n  \"U Přehrady\",\n  \"U Přejezdu\",\n  \"U Půjčovny\",\n  \"U Radiály\",\n  \"U Radnice\",\n  \"U Rajské Zahrady\",\n  \"U Rakovky\",\n  \"U Roháčových Kasáren\",\n  \"U Rokytky\",\n  \"U Rokytky\",\n  \"U Rokytky\",\n  \"U Rozkoše\",\n  \"U Roztockého Háje\",\n  \"U Rybníka\",\n  \"U Rybníčka\",\n  \"U Rybářství\",\n  \"U Rychty\",\n  \"U Rychty\",\n  \"U Ryšánky\",\n  \"U Ryšánky\",\n  \"U Sadu\",\n  \"U Sanatoria\",\n  \"U Sanopzu\",\n  \"U Santošky\",\n  \"U Schodů\",\n  \"U Sedlecké Školy\",\n  \"U Seřadiště\",\n  \"U Sila\",\n  \"U Silnice\",\n  \"U Silnice\",\n  \"U Skalky\",\n  \"U Skladu\",\n  \"U Skládky\",\n  \"U Skopců\",\n  \"U Skály\",\n  \"U Sladovny\",\n  \"U Slavie\",\n  \"U Sloupu\",\n  \"U Slovanky\",\n  \"U Slovanské Pojišťovny\",\n  \"U Sluncové\",\n  \"U Slévárny\",\n  \"U Smaltovny\",\n  \"U Smetanky\",\n  \"U Smolnic\",\n  \"U Smíchovského Hřbitova\",\n  \"U Sokolovny\",\n  \"U Soutoku\",\n  \"U Sovových Mlýnů\",\n  \"U Sparty\",\n  \"U Splavu\",\n  \"U Spojky\",\n  \"U Spojů\",\n  \"U Společenské Zahrady\",\n  \"U Sportoviště\",\n  \"U Spořitelny\",\n  \"U Stanice\",\n  \"U Staré Cihelny\",\n  \"U Staré Plynárny\",\n  \"U Staré Pošty\",\n  \"U Staré Skládky\",\n  \"U Staré Sokolovny\",\n  \"U Staré Studánky\",\n  \"U Staré Tvrze\",\n  \"U Staré Školy\",\n  \"U Staré Školy\",\n  \"U Starého Hřbitova\",\n  \"U Starého Hřiště\",\n  \"U Starého Mlýna\",\n  \"U Starého Nádraží\",\n  \"U Starého Splavu\",\n  \"U Starého Stadionu\",\n  \"U Starého Stadiónu\",\n  \"U Starého Židovského Hřbitova\",\n  \"U Starého Židovského Hřbitova\",\n  \"U Statku\",\n  \"U Stavoservisu\",\n  \"U Stojanu\",\n  \"U Strouhy\",\n  \"U Strže\",\n  \"U Studny\",\n  \"U Studánky\",\n  \"U Studánky\",\n  \"U Stárovny\",\n  \"U Státní Dráhy\",\n  \"U Státní Dráhy\",\n  \"U Stírky\",\n  \"U Střediska\",\n  \"U Střešovických Hřišť\",\n  \"U Sušičky\",\n  \"U Svahu\",\n  \"U Svatého Ducha\",\n  \"U Svobodárny\",\n  \"U Svodnice\",\n  \"U Svornosti\",\n  \"U Svépomoci\",\n  \"U Světličky\",\n  \"U Synagogy\",\n  \"U Sádek\",\n  \"U Sídliště\",\n  \"U Tabulky\",\n  \"U Technoplynu\",\n  \"U Tenisu\",\n  \"U Teplárny\",\n  \"U Topíren\",\n  \"U Továren\",\n  \"U Transformační Stanice\",\n  \"U Transformátoru\",\n  \"U Trati\",\n  \"U Trativodu\",\n  \"U Trezorky\",\n  \"U Trojice\",\n  \"U Trojského Zámku\",\n  \"U Trpce\",\n  \"U Tržnice\",\n  \"U Tvrze\",\n  \"U Tyrše\",\n  \"U Tyršovky\",\n  \"U Tyršovy Školy\",\n  \"U Třetí Baterie\",\n  \"U Třešňovky\",\n  \"U Třešňového Sadu\",\n  \"U Tůně\",\n  \"U Uhříněveské Obory\",\n  \"U Uranie\",\n  \"U Učiliště\",\n  \"U Valu\",\n  \"U Velké Skály\",\n  \"U Vesny\",\n  \"U Viktorky\",\n  \"U Vinice\",\n  \"U Viniček\",\n  \"U Vinné Révy\",\n  \"U Vinných Sklepů\",\n  \"U Vinohradské Nemocnice\",\n  \"U Vinohradského Hřbitova\",\n  \"U Vinohradského Hřbitova\",\n  \"U Vizerky\",\n  \"U Višňovky\",\n  \"U Višňovky\",\n  \"U Vlachovky\",\n  \"U Vlasačky\",\n  \"U Vlečky\",\n  \"U Vlečky\",\n  \"U Vltavy\",\n  \"U Voborníků\",\n  \"U Vodice\",\n  \"U Vodojemu\",\n  \"U Vodojemu\",\n  \"U Vodotoku\",\n  \"U Vody\",\n  \"U Vodárny\",\n  \"U Vojanky\",\n  \"U Vojenské Nemocnice\",\n  \"U Vojtěšky\",\n  \"U Vokovické Školy\",\n  \"U Vorlíků\",\n  \"U Vozovny\",\n  \"U Vrbiček\",\n  \"U Vrby\",\n  \"U Vrtilky\",\n  \"U Vršovického Hřbitova\",\n  \"U Vršovického Hřbitova\",\n  \"U Vršovického Nádraží\",\n  \"U Vysočanského Cukrovaru\",\n  \"U Vysočanského Pivovaru\",\n  \"U Václava\",\n  \"U Váhy\",\n  \"U Vápenice\",\n  \"U Vápenky\",\n  \"U Vápenné Skály\",\n  \"U Výkupního Střediska\",\n  \"U Výstavby\",\n  \"U Výstaviště\",\n  \"U Výstaviště\",\n  \"U Výzkumu\",\n  \"U Včely\",\n  \"U Větrníku\",\n  \"U Větrolamu\",\n  \"U Větrolamu\",\n  \"U Věže\",\n  \"U Waltrovky\",\n  \"U Zahradnictví\",\n  \"U Zahradního Města\",\n  \"U Zahrady\",\n  \"U Zahrádek\",\n  \"U Zahrádkářské Kolonie\",\n  \"U Zastávky\",\n  \"U Zbrojnice\",\n  \"U Zdravotního Ústavu\",\n  \"U Zeleného Ptáka\",\n  \"U Zemníku\",\n  \"U Zeměpisného Ústavu\",\n  \"U Zlaté Studně\",\n  \"U Zličína\",\n  \"U Zličína\",\n  \"U Zličínského Hřiště\",\n  \"U Zvonařky\",\n  \"U Zvoničky\",\n  \"U Záběhlického Zámku\",\n  \"U Zájezdku\",\n  \"U Zákrutu\",\n  \"U Zámeckého Parku\",\n  \"U Zámečku\",\n  \"U Zámečnice\",\n  \"U Zásobní Zahrady\",\n  \"U Zátiší\",\n  \"U Závodiště\",\n  \"U Závor\",\n  \"U Úlů\",\n  \"U Čekárny\",\n  \"U Černé Rokle\",\n  \"U Červeného Mlýnku\",\n  \"U Červeného Mlýnku\",\n  \"U Českých Loděnic\",\n  \"U Čihadel\",\n  \"U Čističky\",\n  \"U Čokoládoven\",\n  \"U Čtvrté Baterie\",\n  \"U Čtyř Domů\",\n  \"U Řempa\",\n  \"U Říčanky\",\n  \"U Šalamounky\",\n  \"U Šalamounky\",\n  \"U Šesté Baterie\",\n  \"U Šesté Baterie\",\n  \"U Školičky\",\n  \"U Školky\",\n  \"U Školního Pole\",\n  \"U Školské Zahrady\",\n  \"U Školy\",\n  \"U Štěpu\",\n  \"U Šumavy\",\n  \"U Šumavěnky\",\n  \"U Šálkovny\",\n  \"U Šíchů\",\n  \"U Šípků\",\n  \"U Železnice\",\n  \"U Železničního Mostu\",\n  \"U Železné Lávky\",\n  \"U Želivky\",\n  \"U Židovského Hřbitova\",\n  \"U Žlábku\",\n  \"U Županských\",\n  \"Uhelný Trh\",\n  \"Uherská\",\n  \"Uhříněveská\",\n  \"Ukončená\",\n  \"Ukrajinská\",\n  \"Uljanovská\",\n  \"Ulrychova\",\n  \"Ulčova\",\n  \"Umělecká\",\n  \"Ungarova\",\n  \"Unhošťská\",\n  \"Univerzitní\",\n  \"Upolínová\",\n  \"Upravená\",\n  \"Uralská\",\n  \"Urbanická\",\n  \"Urbanova\",\n  \"Urbánkova\",\n  \"Urešova\",\n  \"Uruguayská\",\n  \"Urxova\",\n  \"Utěšilova\",\n  \"Uzavřená\",\n  \"Uzbecká\",\n  \"Uzoučká\",\n  \"Učitelská\",\n  \"Učňovská\",\n  \"Užocká\",\n  \"V Aleji\",\n  \"V Alejích\",\n  \"V Americe\",\n  \"V Babyku\",\n  \"V Bambouskách\",\n  \"V Bažinách\",\n  \"V Benátkách\",\n  \"V Bezpečí\",\n  \"V Bokách I\",\n  \"V Bokách Ii\",\n  \"V Bokách Iii\",\n  \"V Borovičkách\",\n  \"V Botanice\",\n  \"V Brance\",\n  \"V Brůdku\",\n  \"V Brůdku\",\n  \"V Bytovkách\",\n  \"V Bílce\",\n  \"V Březinkách\",\n  \"V Březině\",\n  \"V Březí\",\n  \"V Břízkách\",\n  \"V Celnici\",\n  \"V Cestičkách\",\n  \"V Cestkách\",\n  \"V Chaloupkách\",\n  \"V Chaloupkách\",\n  \"V Chatách\",\n  \"V Chotejně\",\n  \"V Cibulkách\",\n  \"V Cihelně\",\n  \"V Cípu\",\n  \"V Dolinách\",\n  \"V Dolině\",\n  \"V Dolině\",\n  \"V Dolích\",\n  \"V Domcích\",\n  \"V Domově\",\n  \"V Doubcích\",\n  \"V Dílcích\",\n  \"V Edenu\",\n  \"V Haltýři\",\n  \"V Hliništi\",\n  \"V Hluboké\",\n  \"V Hodkovičkách\",\n  \"V Holešovičkách\",\n  \"V Honu\",\n  \"V Horkách\",\n  \"V Horní Stromce\",\n  \"V Hrobech\",\n  \"V Humenci\",\n  \"V Humenci\",\n  \"V Humnech\",\n  \"V Háji\",\n  \"V Hájkách\",\n  \"V Hájích\",\n  \"V Hůrkách\",\n  \"V Jahodách\",\n  \"V Javorech\",\n  \"V Javoříčku\",\n  \"V Jehličině\",\n  \"V Jehličí\",\n  \"V Jezerách\",\n  \"V Jezevčinách\",\n  \"V Jezírkách\",\n  \"V Jirchářích\",\n  \"V Jámě\",\n  \"V Kališti\",\n  \"V Kališti\",\n  \"V Kapslovně\",\n  \"V Klukovicích\",\n  \"V Kole\",\n  \"V Kolkovně\",\n  \"V Korytech\",\n  \"V Korytech\",\n  \"V Kotcích\",\n  \"V Koutku\",\n  \"V Koutě\",\n  \"V Kratinách\",\n  \"V Kruhu\",\n  \"V Kuťatech\",\n  \"V Kálku\",\n  \"V Křepelkách\",\n  \"V Křovinách\",\n  \"V Křížkách\",\n  \"V Ladech\",\n  \"V Lesíčku\",\n  \"V Lipinách\",\n  \"V Lipinách\",\n  \"V Lipkách\",\n  \"V Lipách\",\n  \"V Listnáčích\",\n  \"V Lomech\",\n  \"V Louce\",\n  \"V Luhu\",\n  \"V Lukách\",\n  \"V Lučinách\",\n  \"V Lužích\",\n  \"V Lánech\",\n  \"V Lázních\",\n  \"V Lískách\",\n  \"V Malých Domech I\",\n  \"V Malých Domech Ii\",\n  \"V Malých Domech Iii\",\n  \"V Mezihoří\",\n  \"V Milíři\",\n  \"V Mokřinách\",\n  \"V Mydlinkách\",\n  \"V Nové Hostivaři\",\n  \"V Nové Vsi\",\n  \"V Nové Vsi\",\n  \"V Nové Čtvrti\",\n  \"V Novém Hloubětíně\",\n  \"V Novém Hloubětíně\",\n  \"V Nových Bohnicích\",\n  \"V Nových Domcích\",\n  \"V Nových Vokovicích\",\n  \"V Náklích\",\n  \"V Násypu\",\n  \"V Nížinách\",\n  \"V Oblouku\",\n  \"V Občanském Domově\",\n  \"V Obůrkách\",\n  \"V Ochozu\",\n  \"V Ohradě\",\n  \"V Ohybu\",\n  \"V Okruží\",\n  \"V Okálech\",\n  \"V Olšinách\",\n  \"V Olšinách\",\n  \"V Olšině\",\n  \"V Ondřejově\",\n  \"V Opatově\",\n  \"V Osikách\",\n  \"V Ostružiní\",\n  \"V Oudolku\",\n  \"V Ořeší\",\n  \"V Pachmance\",\n  \"V Padolině\",\n  \"V Parcelách\",\n  \"V Parku\",\n  \"V Parníku\",\n  \"V Pačátkách\",\n  \"V Pařezinách\",\n  \"V Pevnosti\",\n  \"V Pevnosti\",\n  \"V Pitkovičkách\",\n  \"V Planinách\",\n  \"V Platýzu\",\n  \"V Pláni\",\n  \"V Podbabě\",\n  \"V Podhoří\",\n  \"V Podhájí\",\n  \"V Podhájí\",\n  \"V Podluží\",\n  \"V Podskalí\",\n  \"V Podvrší\",\n  \"V Podzámčí\",\n  \"V Poli\",\n  \"V Polích\",\n  \"V Potokách\",\n  \"V Potočinách\",\n  \"V Potočkách\",\n  \"V Prutinách\",\n  \"V Průhledu\",\n  \"V Průčelí\",\n  \"V Pátém\",\n  \"V Pískovně\",\n  \"V Pěšinkách\",\n  \"V Předním Hloubětíně\",\n  \"V Předním Veleslavíně\",\n  \"V Předpolí\",\n  \"V Předpolí\",\n  \"V Přelomu\",\n  \"V Přístavu\",\n  \"V Remízku\",\n  \"V Rohožníku\",\n  \"V Rohu\",\n  \"V Roháčích\",\n  \"V Rokli\",\n  \"V Roklích\",\n  \"V Rovinách\",\n  \"V Rovinách\",\n  \"V Rybníkách\",\n  \"V Rybníčkách\",\n  \"V Ráji\",\n  \"V Ráji\",\n  \"V Rákosí\",\n  \"V Sadech\",\n  \"V Sedlci\",\n  \"V Sedlci\",\n  \"V Slavětíně\",\n  \"V Soudním\",\n  \"V Stráni\",\n  \"V Středu\",\n  \"V Sudech\",\n  \"V Sídlišti\",\n  \"V Tehovičkách\",\n  \"V Tišině\",\n  \"V Trninách\",\n  \"V Třešňovce\",\n  \"V Tůních\",\n  \"V Uličce\",\n  \"V Uličkách\",\n  \"V Zahradní Čtvrti\",\n  \"V Zahradách\",\n  \"V Zahrádkách\",\n  \"V Zatáčce\",\n  \"V Zeleni\",\n  \"V Zeleném Údolí\",\n  \"V Záhorském\",\n  \"V Záhybu\",\n  \"V Zákopech\",\n  \"V Zákoutí\",\n  \"V Zálesí\",\n  \"V Zálomu\",\n  \"V Zámcích\",\n  \"V Zápolí\",\n  \"V Zátiší\",\n  \"V Zátočce\",\n  \"V Závitu\",\n  \"V Závětří\",\n  \"V Zářezu\",\n  \"V Údolí\",\n  \"V Údolí Hvězd\",\n  \"V Úhlu\",\n  \"V Úhoru\",\n  \"V Úvalu\",\n  \"V Úvoze\",\n  \"V Úzké\",\n  \"V Úžlabině\",\n  \"V Úžlabině\",\n  \"V Čeňku\",\n  \"V Štíhlách\",\n  \"V Šáreckém Údolí\",\n  \"V Žabokřiku\",\n  \"V Žáčku\",\n  \"V. P. Čkalova\",\n  \"V. P. Čkalova\",\n  \"Vachkova\",\n  \"Vackova\",\n  \"Vacovská\",\n  \"Vacínova\",\n  \"Vacínovská\",\n  \"Vajdova\",\n  \"Vajgarská\",\n  \"Valcířská\",\n  \"Valdická\",\n  \"Valdovská\",\n  \"Valdštejnská\",\n  \"Valdštejnské Nám.\",\n  \"Valdštejnské Náměstí\",\n  \"Valentinská\",\n  \"Valentinská\",\n  \"Valentova\",\n  \"Valečovská\",\n  \"Valská\",\n  \"Valtická\",\n  \"Valtínovská\",\n  \"Valčíkova\",\n  \"Valšovská\",\n  \"Vamberská\",\n  \"Vanická\",\n  \"Vaníčkova\",\n  \"Vaníčkova\",\n  \"Varhulíkové\",\n  \"Varnsdorfská\",\n  \"Varšavská\",\n  \"Vavákova\",\n  \"Vavřenova\",\n  \"Vavřinecká\",\n  \"Vazovova\",\n  \"Vačkářova\",\n  \"Vaňkova\",\n  \"Vaňkova\",\n  \"Vašátkova\",\n  \"Ve Dvoře\",\n  \"Ve Lhotce\",\n  \"Ve Lhotce\",\n  \"Ve Skalkách\",\n  \"Ve Skalách\",\n  \"Ve Skále\",\n  \"Ve Slatinách\",\n  \"Ve Smečkách\",\n  \"Ve Smrčině\",\n  \"Ve Stromořadí\",\n  \"Ve Struhách\",\n  \"Ve Struhách\",\n  \"Ve Stráni\",\n  \"Ve Studeném\",\n  \"Ve Stínu\",\n  \"Ve Střešovičkách\",\n  \"Ve Střešovičkách\",\n  \"Ve Svahu\",\n  \"Ve Vilkách\",\n  \"Ve Vilách\",\n  \"Ve Višňovce\",\n  \"Ve Vratech\",\n  \"Ve Vrbách\",\n  \"Ve Vrchu\",\n  \"Ve Vrších\",\n  \"Ve Výhledu\",\n  \"Ve Výhledu\",\n  \"Ve Výrech\",\n  \"Ve Zliči\",\n  \"Ve Štěpnici\",\n  \"Ve Žlíbku\",\n  \"Vedlejší\",\n  \"Vehlovická\",\n  \"Vejražkova\",\n  \"Vejvanovského\",\n  \"Vejvodova\",\n  \"Velebného\",\n  \"Velehradská\",\n  \"Velemínská\",\n  \"Velemínská\",\n  \"Velenická\",\n  \"Velenovského\",\n  \"Veleslavínova\",\n  \"Veleslavínská\",\n  \"Veleslavínská\",\n  \"Veletovská\",\n  \"Veletržní\",\n  \"Veletržní\",\n  \"Veleňská\",\n  \"Velešínská\",\n  \"Velfloviců\",\n  \"Velflíkova\",\n  \"Velhartická\",\n  \"Velichovská\",\n  \"Velimská\",\n  \"Velkoborská\",\n  \"Velkoosecká\",\n  \"Velkopřevorské Nám.\",\n  \"Velkopřevorské Náměstí\",\n  \"Velká Lada\",\n  \"Velká Lada\",\n  \"Velká Skála\",\n  \"Velké Kunratické\",\n  \"Veltruská\",\n  \"Veltěžská\",\n  \"Velvarská\",\n  \"Velínská\",\n  \"Venušina\",\n  \"Verdiho\",\n  \"Verdunská\",\n  \"Verneřická\",\n  \"Verneřická\",\n  \"Vernéřovská\",\n  \"Veronské Nám.\",\n  \"Veselská\",\n  \"Veská\",\n  \"Veslařský Ostrov\",\n  \"Vestavěná\",\n  \"Vestecká\",\n  \"Veverkova\",\n  \"Večerní\",\n  \"Vidimova\",\n  \"Vidimská\",\n  \"Vidlicová\",\n  \"Vidlák\",\n  \"Vidonická\",\n  \"Vidoulská\",\n  \"Vidovická\",\n  \"Vietnamská\",\n  \"Viklefova\",\n  \"Vikova\",\n  \"Viktora Huga\",\n  \"Viktorinova\",\n  \"Viktorčina\",\n  \"Vikářská\",\n  \"Vilová\",\n  \"Vilímkova\",\n  \"Vilímovská\",\n  \"Vimperské Náměstí\",\n  \"Vinařického\",\n  \"Vinařská\",\n  \"Viničná\",\n  \"Vinohradská\",\n  \"Vinohradská\",\n  \"Vinohradská\",\n  \"Vinohradská\",\n  \"Vinohradská\",\n  \"Vinohradská\",\n  \"Vinohradská\",\n  \"Vinohrady\",\n  \"Vinopalnická\",\n  \"Vinořská\",\n  \"Vinořské Nám.\",\n  \"Vinořské Náměstí\",\n  \"Vinšova\",\n  \"Violková\",\n  \"Vitošská\",\n  \"Vitíkova\",\n  \"Vitějovská\",\n  \"Vizovická\",\n  \"Višňovka\",\n  \"Višňovka\",\n  \"Višňová\",\n  \"Vlachova\",\n  \"Vladimírova\",\n  \"Vladislava Vančury\",\n  \"Vladislavova\",\n  \"Vladivostocká\",\n  \"Vladycká\",\n  \"Vlastibořská\",\n  \"Vlastina\",\n  \"Vlastina\",\n  \"Vlastislavova\",\n  \"Vlasty Buriana\",\n  \"Vlasty Hilské\",\n  \"Vlasty Průchové\",\n  \"Vlasákova\",\n  \"Vlašimská\",\n  \"Vlašská\",\n  \"Vlašská\",\n  \"Vlaštovčí\",\n  \"Vlkanovská\",\n  \"Vlkova\",\n  \"Vlkovická\",\n  \"Vlnitá\",\n  \"Vltavanů\",\n  \"Vltavanů\",\n  \"Vltavanů\",\n  \"Vltavická\",\n  \"Vltavská\",\n  \"Vltavínová\",\n  \"Vlárská\",\n  \"Vlásenická\",\n  \"Vlčická\",\n  \"Vlčkova\",\n  \"Vlčnovská\",\n  \"Vnislavova\",\n  \"Vnitřní\",\n  \"Vnoučkova\",\n  \"Vnější\",\n  \"Voborského\",\n  \"Vobrubova\",\n  \"Vocelova\",\n  \"Voctářova\",\n  \"Voctářova\",\n  \"Vodická\",\n  \"Vodičkova\",\n  \"Vodičkova\",\n  \"Vodnická\",\n  \"Vodní\",\n  \"Vodochodská\",\n  \"Vodojemská\",\n  \"Vodácká\",\n  \"Vodárenská\",\n  \"Voděradská\",\n  \"Vodňanská\",\n  \"Vodňanského\",\n  \"Vojenova\",\n  \"Vojetická\",\n  \"Vojická\",\n  \"Vojkovická\",\n  \"Vojslavická\",\n  \"Vojtova\",\n  \"Vojtíškova\",\n  \"Vojtěšská\",\n  \"Vojáčkova\",\n  \"Vokovická\",\n  \"Vokovická\",\n  \"Vokrojova\",\n  \"Vokáčova\",\n  \"Vokřínská\",\n  \"Volarská\",\n  \"Volavkova\",\n  \"Voleníkova\",\n  \"Volkova\",\n  \"Volkovova\",\n  \"Voltova\",\n  \"Volutová\",\n  \"Volyňská\",\n  \"Volšovská\",\n  \"Volšovská\",\n  \"Vondroušova\",\n  \"Vorařská\",\n  \"Voroněžská\",\n  \"Voroněžská\",\n  \"Voráčovská\",\n  \"Voršilská\",\n  \"Voskova\",\n  \"Voskovcova\",\n  \"Vosmíkových\",\n  \"Vostrovská\",\n  \"Vostrého\",\n  \"Vosátkova\",\n  \"Votavova\",\n  \"Votická\",\n  \"Votočkova\",\n  \"Votrubova\",\n  \"Votuzská\",\n  \"Vozová\",\n  \"Vozová\",\n  \"Voňkova\",\n  \"Voříškova\",\n  \"Vošahlíkova\",\n  \"Vožická\",\n  \"Vrabčí\",\n  \"Vranická\",\n  \"Vranovská\",\n  \"Vranská\",\n  \"Vratimovská\",\n  \"Vratislavova\",\n  \"Vratislavská\",\n  \"Vratičová\",\n  \"Vraňanská\",\n  \"Vrbenského\",\n  \"Vrbická\",\n  \"Vrbková\",\n  \"Vrbova\",\n  \"Vrbčanská\",\n  \"Vrchlabská\",\n  \"Vrchlického\",\n  \"Vrchlického Sady\",\n  \"Vrchovinská\",\n  \"Vrátenská\",\n  \"Vrátkovská\",\n  \"Vrázova\",\n  \"Vrážská\",\n  \"Vrútecká\",\n  \"Vršní\",\n  \"Vršovická\",\n  \"Vršovické Nám.\",\n  \"Vršovické Náměstí\",\n  \"Vršovka\",\n  \"Vsetínská\",\n  \"Vstavačová\",\n  \"Vstupní\",\n  \"Vybíralova\",\n  \"Vycpálkova\",\n  \"Vyderská\",\n  \"Vydrova\",\n  \"Vyhlídkova\",\n  \"Vykoukových\",\n  \"Vykáňská\",\n  \"Vyskočilova\",\n  \"Vysokovská\",\n  \"Vysokoškolská\",\n  \"Vysoká Cesta\",\n  \"Vysočanská\",\n  \"Vysočanská\",\n  \"Vysočanská\",\n  \"Vysočanské Nám.\",\n  \"Vysočanské Náměstí\",\n  \"Vyvýšená\",\n  \"Vyšebrodská\",\n  \"Vyšehradská\",\n  \"Vyšší\",\n  \"Vyžlovská\",\n  \"Vzdušná\",\n  \"Vzdálená\",\n  \"Vzestupná\",\n  \"Vzpoury\",\n  \"Váchalova\",\n  \"Václava Balého\",\n  \"Václava Kovaříka\",\n  \"Václava Rady\",\n  \"Václava Trojana\",\n  \"Václava Špačka\",\n  \"Václavická\",\n  \"Václavkova\",\n  \"Václavská\",\n  \"Václavské Nám.\",\n  \"Václavské Náměstí\",\n  \"Vágnerova\",\n  \"Vánková\",\n  \"Vápencová\",\n  \"Vápenná\",\n  \"Vápeníkova\",\n  \"Vášova\",\n  \"Vážská\",\n  \"Vídeňská\",\n  \"Vídeňská\",\n  \"Vídeňská\",\n  \"Vírská\",\n  \"Víta Nejedlého\",\n  \"Vítkova\",\n  \"Vítkovická\",\n  \"Vítovcova\",\n  \"Vítovcova\",\n  \"Vítězná\",\n  \"Vítězná\",\n  \"Vítězné Nám.\",\n  \"Vítězné Nám.\",\n  \"Vítězné Náměstí\",\n  \"Vítězné Náměstí\",\n  \"Východní\",\n  \"Východní Nám.\",\n  \"Východní Náměstí\",\n  \"Výchozí\",\n  \"Výhledová\",\n  \"Výhledské Nám.\",\n  \"Výhledské Náměstí\",\n  \"Výjezdní\",\n  \"Výjezdová\",\n  \"Výletní\",\n  \"Výletní\",\n  \"Výmarova\",\n  \"Výmolova\",\n  \"Výpadová\",\n  \"Výpadová\",\n  \"Výravská\",\n  \"Výrobní\",\n  \"Výstaviště\",\n  \"Výstavní\",\n  \"Výstupní\",\n  \"Výtoňská\",\n  \"Výtvarnická\",\n  \"Výtvarná\",\n  \"Výzkumníků\",\n  \"Včelařská\",\n  \"Včelničná\",\n  \"Věkova\",\n  \"Věstonická\",\n  \"Větrná\",\n  \"Větrovcova\",\n  \"Větrová\",\n  \"Větrušická\",\n  \"Vězeňská\",\n  \"Vězeňská\",\n  \"Věštínská\",\n  \"Věšínova\",\n  \"Věžická\",\n  \"Vřesovická\",\n  \"Vřesová\",\n  \"Všehrdova\",\n  \"Všejanská\",\n  \"Všelipská\",\n  \"Všerubská\",\n  \"Všestarská\",\n  \"Všetatská\",\n  \"Všeňská\",\n  \"Wagnerova\",\n  \"Waldesova\",\n  \"Washingtonova\",\n  \"Wassermannova\",\n  \"Wattova\",\n  \"Weberova\",\n  \"Weberova\",\n  \"Weilova\",\n  \"Weissova\",\n  \"Wenzigova\",\n  \"Wenzigova\",\n  \"Werichova\",\n  \"Wichterlova\",\n  \"Wiedermannova\",\n  \"Wiesenthalova\",\n  \"Wilsonova\",\n  \"Wilsonova\",\n  \"Winklerova\",\n  \"Wolfova\",\n  \"Wolkerova\",\n  \"Wuchterlova\",\n  \"Xaveriova\",\n  \"Xaverovská\",\n  \"Za Archivem\",\n  \"Za Arielem\",\n  \"Za Avií\",\n  \"Za Bažantnicí\",\n  \"Za Botičem\",\n  \"Za Brankou\",\n  \"Za Brumlovkou\",\n  \"Za Brůdkem\",\n  \"Za Břízami\",\n  \"Za Chalupami\",\n  \"Za Cukrovarem\",\n  \"Za Císařským Mlýnem\",\n  \"Za Dolejšákem\",\n  \"Za Drahou\",\n  \"Za Dvorem\",\n  \"Za Dálnicí\",\n  \"Za Dálnicí\",\n  \"Za Elektrárnou\",\n  \"Za Elektrárnou\",\n  \"Za Farou\",\n  \"Za Fořtem\",\n  \"Za Hanspaulkou\",\n  \"Za Haštalem\",\n  \"Za Hládkovem\",\n  \"Za Horou\",\n  \"Za Horou\",\n  \"Za Hospodou\",\n  \"Za Hrází\",\n  \"Za Humny\",\n  \"Za Hájem\",\n  \"Za Hájem\",\n  \"Za Hájovnou\",\n  \"Za Hřbitovem\",\n  \"Za Invalidovnou\",\n  \"Za Jalovým Dvorem\",\n  \"Za Jednotou\",\n  \"Za Kajetánkou\",\n  \"Za Kapličkou\",\n  \"Za Karlínským Přístavem\",\n  \"Za Kačabkou\",\n  \"Za Klíčovem\",\n  \"Za Knotkem\",\n  \"Za Knotkem\",\n  \"Za Kostelem\",\n  \"Za Kovárnou\",\n  \"Za Kovářským Rybníkem\",\n  \"Za Křížem\",\n  \"Za Křížkem\",\n  \"Za Lesíkem\",\n  \"Za Lidovým Domem\",\n  \"Za Luhem\",\n  \"Za Lužinami\",\n  \"Za Lány\",\n  \"Za Lázeňkou\",\n  \"Za Mlýnem\",\n  \"Za Mosty\",\n  \"Za Mosty\",\n  \"Za Mototechnou\",\n  \"Za Můstkem\",\n  \"Za Nadýmačem\",\n  \"Za Novákovou Zahradou\",\n  \"Za Návsí\",\n  \"Za Obecním Úřadem\",\n  \"Za Oborou\",\n  \"Za Opravnou\",\n  \"Za Opusem\",\n  \"Za Ovčínem\",\n  \"Za Papírnou\",\n  \"Za Parkem\",\n  \"Za Pavilónem\",\n  \"Za Pekařkou\",\n  \"Za Pekárnou\",\n  \"Za Pivovarem\",\n  \"Za Ploty\",\n  \"Za Podjezdem\",\n  \"Za Pohořelcem\",\n  \"Za Pohádkou\",\n  \"Za Potokem\",\n  \"Za Poříčskou Branou\",\n  \"Za Poříčskou Bránou\",\n  \"Za Poštou\",\n  \"Za Poštovskou Zahradou\",\n  \"Za Poštovskou Zahradou\",\n  \"Za Prodejnou\",\n  \"Za Pruhy\",\n  \"Za Průsekem\",\n  \"Za Pískovnou\",\n  \"Za Radostí\",\n  \"Za Rokytkou\",\n  \"Za Rybníkem\",\n  \"Za Rybníčky\",\n  \"Za Rybářstvím\",\n  \"Za Rájem\",\n  \"Za Sadem\",\n  \"Za Sedmidomky\",\n  \"Za Skalkou\",\n  \"Za Skalkou\",\n  \"Za Slatinami\",\n  \"Za Slovankou\",\n  \"Za Sokolovnou\",\n  \"Za Stadionem\",\n  \"Za Statkem\",\n  \"Za Statky\",\n  \"Za Stodolami\",\n  \"Za Stodolou\",\n  \"Za Strahovem\",\n  \"Za Strašnickou Vozovnou\",\n  \"Za Strašnickou Vozovnou\",\n  \"Za Strojírnami\",\n  \"Za Studánkou\",\n  \"Za Střelnicí\",\n  \"Za Sídlištěm\",\n  \"Za Teplárnou\",\n  \"Za Tratí\",\n  \"Za Tratí\",\n  \"Za Třebešínem\",\n  \"Za Vackovem\",\n  \"Za Valem\",\n  \"Za Viaduktem\",\n  \"Za Vinicí\",\n  \"Za Vlasačkou\",\n  \"Za Vodárnou\",\n  \"Za Vokovickou Vozovnou\",\n  \"Za Vokovickou Vozovnou\",\n  \"Za Větrem\",\n  \"Za Zahradami\",\n  \"Za Zahradou\",\n  \"Za Zastávkou\",\n  \"Za Zelenou Liškou\",\n  \"Za Zámečkem\",\n  \"Za Černým Mostem\",\n  \"Za Černým Mostem\",\n  \"Za Černým Mostem\",\n  \"Za Školkou\",\n  \"Za Školou\",\n  \"Za Šmatlíkem\",\n  \"Za Železnicí\",\n  \"Za Ženskými Domovy\",\n  \"Za Žižkovskou Vozovnou\",\n  \"Zacharská\",\n  \"Zachova\",\n  \"Zadní\",\n  \"Zahrada Na Baště\",\n  \"Zahradnická\",\n  \"Zahradní\",\n  \"Zahradníčkova\",\n  \"Zahradníčkova\",\n  \"Zahrádecká\",\n  \"Zahrádecká\",\n  \"Zahrádkářská\",\n  \"Zahrádkářů\",\n  \"Zaječická\",\n  \"Zaječí\",\n  \"Zaječí\",\n  \"Zakouřilova\",\n  \"Zakrytá\",\n  \"Zakšínská\",\n  \"Zalešanská\",\n  \"Zalinská\",\n  \"Zamašská\",\n  \"Zamenhofova\",\n  \"Zapadlá\",\n  \"Zapomenutá\",\n  \"Zapova\",\n  \"Zapských\",\n  \"Zastavěná\",\n  \"Zastrčená\",\n  \"Zavadilova\",\n  \"Zavátá\",\n  \"Zaříčanská\",\n  \"Zbečenská\",\n  \"Zborovská\",\n  \"Zborovská\",\n  \"Zbraslavská\",\n  \"Zbraslavská\",\n  \"Zbraslavské Nám.\",\n  \"Zbraslavské Náměstí\",\n  \"Zbrojnická\",\n  \"Zbudovská\",\n  \"Zbuzanská\",\n  \"Zbuzkova\",\n  \"Zbynická\",\n  \"Zbyslavská\",\n  \"Zbytinská\",\n  \"Zbýšovská\",\n  \"Zdaru\",\n  \"Zdařilá\",\n  \"Zderazská\",\n  \"Zdeňky Nyplové\",\n  \"Zdibská\",\n  \"Zdická\",\n  \"Zdiměřická\",\n  \"Zdislavická\",\n  \"Zdobnická\",\n  \"Zdoňovská\",\n  \"Zdíkovská\",\n  \"Zelenečská\",\n  \"Zelenečská\",\n  \"Zelenkova\",\n  \"Zelenky-Hajského\",\n  \"Zelenohorská\",\n  \"Zelená\",\n  \"Zelená\",\n  \"Zelená Louka\",\n  \"Zelený Pruh\",\n  \"Zelený Pruh\",\n  \"Zelený Pruh\",\n  \"Zelinářská\",\n  \"Zemanka\",\n  \"Zemské Právo\",\n  \"Zemědělská\",\n  \"Zengrova\",\n  \"Zenklova\",\n  \"Zenklova\",\n  \"Zeyerova Alej\",\n  \"Zhořelecká\",\n  \"Zikova\",\n  \"Zimova\",\n  \"Zimákova\",\n  \"Zkrácená\",\n  \"Zlatnice\",\n  \"Zlatnická\",\n  \"Zlatokorunská\",\n  \"Zlatá\",\n  \"Zlatá Ulička U Daliborky\",\n  \"Zlenická\",\n  \"Zlešická\",\n  \"Zlivská\",\n  \"Zličínská\",\n  \"Zličínská\",\n  \"Zlonická\",\n  \"Zlonínská\",\n  \"Zlončická\",\n  \"Zlíchovská\",\n  \"Znojemská\",\n  \"Zoubkova\",\n  \"Zrzavého\",\n  \"Ztracená\",\n  \"Zubatého\",\n  \"Zubrnická\",\n  \"Zvolenská\",\n  \"Zvolská\",\n  \"Zvolská\",\n  \"Zvonařova\",\n  \"Zvonařovská\",\n  \"Zvonařská\",\n  \"Zvoncovitá\",\n  \"Zvonická\",\n  \"Zvonková\",\n  \"Zvoníčkova\",\n  \"Zvánovická\",\n  \"Zvíkovská\",\n  \"Záblatská\",\n  \"Záblatská\",\n  \"Zábranská\",\n  \"Zábrodí\",\n  \"Záběhlická\",\n  \"Zádražanská\",\n  \"Záhornická\",\n  \"Záhorského\",\n  \"Záhořanská\",\n  \"Záhořanského\",\n  \"Záhřebská\",\n  \"Zájezdní\",\n  \"Zákolanská\",\n  \"Zákostelní\",\n  \"Zákupská\",\n  \"Zálesí\",\n  \"Zálesí\",\n  \"Zálesí\",\n  \"Záluské\",\n  \"Zálužanského\",\n  \"Zálužická\",\n  \"Zálužská\",\n  \"Zálužská\",\n  \"Zámecká\",\n  \"Zámecké Schody\",\n  \"Zámezí\",\n  \"Zámišova\",\n  \"Zámělská\",\n  \"Západní\",\n  \"Zápasnická\",\n  \"Zápolská\",\n  \"Zápotoční\",\n  \"Zápská\",\n  \"Zárubova\",\n  \"Zárybnická\",\n  \"Zárybničná\",\n  \"Zárybská\",\n  \"Zásadská\",\n  \"Zásmucká\",\n  \"Zátišská\",\n  \"Zátiší\",\n  \"Zátopkova\",\n  \"Zátoňská\",\n  \"Závadova\",\n  \"Záveská\",\n  \"Závist\",\n  \"Závišova\",\n  \"Závišova\",\n  \"Závodní\",\n  \"Závrchy\",\n  \"Závěrka\",\n  \"Zázvorkova\",\n  \"Zářijová\",\n  \"Zítkova\",\n  \"Zívrova\",\n  \"Zúžená\",\n  \"Údlická\",\n  \"Údolní\",\n  \"Údolní\",\n  \"Údolí Hvězd\",\n  \"Úhlavská\",\n  \"Úhlová\",\n  \"Újezd\",\n  \"Újezd\",\n  \"Újezdská\",\n  \"Úlibická\",\n  \"Únorová\",\n  \"Únětická\",\n  \"Únětická\",\n  \"Úpická\",\n  \"Úprkova\",\n  \"Úpská\",\n  \"Úslavská\",\n  \"Ústavní\",\n  \"Ústecká\",\n  \"Ústecká\",\n  \"Ústřední\",\n  \"Útulná\",\n  \"Útulná\",\n  \"Úvalská\",\n  \"Úvoz\",\n  \"Úvoz\",\n  \"Úvozová\",\n  \"Úzká\",\n  \"Čajkovského\",\n  \"Čakovická\",\n  \"Čakovická\",\n  \"Čankovská\",\n  \"Čapkova\",\n  \"Častavina\",\n  \"Častonická\",\n  \"Čechova\",\n  \"Čechtická\",\n  \"Čechurova\",\n  \"Čedičová\",\n  \"Čejetická\",\n  \"Čejkovická\",\n  \"Čekanková\",\n  \"Čekanková\",\n  \"Čekanovská\",\n  \"Čelakovského Sady\",\n  \"Čelakovského Sady\",\n  \"Čeljabinská\",\n  \"Čelkovická\",\n  \"Čelná\",\n  \"Čelákovická\",\n  \"Čenkovská\",\n  \"Čenovická\",\n  \"Čentická\",\n  \"Čenětická\",\n  \"Čeperská\",\n  \"Čeradická\",\n  \"Čerchovská\",\n  \"Čermákova\",\n  \"Černická\",\n  \"Černilovská\",\n  \"Černičná\",\n  \"Černochova\",\n  \"Černockého\",\n  \"Černohorského\",\n  \"Černokostelecká\",\n  \"Černokostelecká\",\n  \"Černokostelecká\",\n  \"Černomořská\",\n  \"Černotínská\",\n  \"Černovická\",\n  \"Černošická\",\n  \"Černá\",\n  \"Černého\",\n  \"Černínova\",\n  \"Černínská\",\n  \"Čerpadlová\",\n  \"Čertouská\",\n  \"Čertouská\",\n  \"Čertův Vršek\",\n  \"Červencová\",\n  \"Červenkova\",\n  \"Červená\",\n  \"Červená Báň\",\n  \"Červený Mlýn\",\n  \"Červeňanského\",\n  \"Červnová\",\n  \"Čerčanská\",\n  \"Českobratrská\",\n  \"Českobrodská\",\n  \"Českobrodská\",\n  \"Českobrodská\",\n  \"Českobrodská\",\n  \"Českobrodská\",\n  \"Českobrodská\",\n  \"Českobrodská\",\n  \"Českobrodská\",\n  \"Českodubská\",\n  \"Českolipská\",\n  \"Českolipská\",\n  \"Českomalínská\",\n  \"Českomoravská\",\n  \"Českomoravská\",\n  \"Československého Exilu\",\n  \"Československého Exilu\",\n  \"Česká\",\n  \"České Družiny\",\n  \"Českého Červeného Kříže\",\n  \"Čestlická\",\n  \"Čestmírova\",\n  \"Česákova\",\n  \"Čečelická\",\n  \"Čeňkova\",\n  \"Češovská\",\n  \"Čibuzská\",\n  \"Čihákova\",\n  \"Čiklova\",\n  \"Čiklova\",\n  \"Čimelická\",\n  \"Čimická\",\n  \"Čimická\",\n  \"Čimická\",\n  \"Čimická\",\n  \"Čirůvková\",\n  \"Čistovická\",\n  \"Čmelická\",\n  \"Čs. Armády\",\n  \"Čs. Tankistů\",\n  \"Čtyřdílná\",\n  \"Čtyřkolská\",\n  \"Čumpelíkova\",\n  \"Čuprova\",\n  \"Čábelecká\",\n  \"Čápova\",\n  \"Čáslavská\",\n  \"Čílova\",\n  \"Čílova\",\n  \"Čínská\",\n  \"Čínská\",\n  \"Čížovská\",\n  \"Ďáblická\",\n  \"Ďáblická\",\n  \"Ďáblická\",\n  \"Řadová\",\n  \"Řehořova\",\n  \"Řepečská\",\n  \"Řepná\",\n  \"Řeporyjská\",\n  \"Řeporyjská\",\n  \"Řeporyjská\",\n  \"Řeporyjské Náměstí\",\n  \"Řepová\",\n  \"Řepská\",\n  \"Řepíková\",\n  \"Řepínská\",\n  \"Řepčická\",\n  \"Řepčická\",\n  \"Řetězokovářů\",\n  \"Řetězová\",\n  \"Řevnická\",\n  \"Řevnická\",\n  \"Řeznická\",\n  \"Řezáčovo Nám.\",\n  \"Řezáčovo Náměstí\",\n  \"Řečického\",\n  \"Řešetovská\",\n  \"Řešovská\",\n  \"Řipská\",\n  \"Řipská\",\n  \"Řásnovka\",\n  \"Říjnová\",\n  \"Římovská\",\n  \"Římovská\",\n  \"Římská\",\n  \"Říčanova\",\n  \"Říčanská\",\n  \"Říční\",\n  \"Šachovská\",\n  \"Šafaříkova\",\n  \"Šafránecká\",\n  \"Šafránkova\",\n  \"Šafránová\",\n  \"Šafářova\",\n  \"Šakvická\",\n  \"Šaldova\",\n  \"Šalounova\",\n  \"Šalvějová\",\n  \"Šanovská\",\n  \"Šantrochova\",\n  \"Šatrova\",\n  \"Šatrova\",\n  \"Šebelova\",\n  \"Šeberovská\",\n  \"Šebestiánská\",\n  \"Šebkova\",\n  \"Šedivého\",\n  \"Šedova\",\n  \"Šejbalové\",\n  \"Šemberova\",\n  \"Šenovská\",\n  \"Šermířská\",\n  \"Šermířská\",\n  \"Šestajovická\",\n  \"Šestajovická\",\n  \"Šestidomí\",\n  \"Šetelíkova\",\n  \"Ševce Matouše\",\n  \"Ševčenkova\",\n  \"Ševčíkova\",\n  \"Šeříková\",\n  \"Šeříková\",\n  \"Šibřinská\",\n  \"Šikmá\",\n  \"Šimanovská\",\n  \"Šimkova\",\n  \"Šimonova\",\n  \"Šimáčkova\",\n  \"Šimůnkova\",\n  \"Šircova\",\n  \"Široká\",\n  \"Široká\",\n  \"Šiškova\",\n  \"Školní\",\n  \"Školská\",\n  \"Škroupovo Nám.\",\n  \"Škroupovo Náměstí\",\n  \"Škrétova\",\n  \"Škvorecká\",\n  \"Škábova\",\n  \"Šlechtitelská\",\n  \"Šlejnická\",\n  \"Šlikova\",\n  \"Šlitrova\",\n  \"Šluknovská\",\n  \"Šmeralova\",\n  \"Šmilovského\",\n  \"Šmolíkova\",\n  \"Šolínova\",\n  \"Šostakovičovo Nám.\",\n  \"Šostakovičovo Náměstí\",\n  \"Španielova\",\n  \"Španělská\",\n  \"Špačkova\",\n  \"Špeciánova\",\n  \"Šperlova\",\n  \"Špirkova\",\n  \"Špitálská\",\n  \"Šplechnerova\",\n  \"Šporkova\",\n  \"Špotzova\",\n  \"Špálova\",\n  \"Šrobárova\",\n  \"Šrobárova\",\n  \"Šromova\",\n  \"Štamberk\",\n  \"Štefkova\",\n  \"Štefánikova\",\n  \"Štemberova\",\n  \"Šternberkova\",\n  \"Šternova\",\n  \"Šternovská\",\n  \"Štichova\",\n  \"Štiplova\",\n  \"Štičkova\",\n  \"Štiřínská\",\n  \"Štochlova\",\n  \"Štolbova\",\n  \"Štolcova\",\n  \"Štolmířská\",\n  \"Štolmířská\",\n  \"Štorchova\",\n  \"Štorkánova\",\n  \"Štramberská\",\n  \"Štulcova\",\n  \"Štupartská\",\n  \"Štursova\",\n  \"Štverákova\",\n  \"Štychova\",\n  \"Štychova\",\n  \"Štíbrova\",\n  \"Štíhlická\",\n  \"Štítného\",\n  \"Štítová\",\n  \"Štúrova\",\n  \"Štúrova\",\n  \"Štěchovická\",\n  \"Štěpanická\",\n  \"Štěpařská\",\n  \"Štěpničná\",\n  \"Štěpánkova\",\n  \"Štěpánovská\",\n  \"Štěpánská\",\n  \"Štěpánská\",\n  \"Štěrboholská\",\n  \"Štěrková\",\n  \"Štětkova\",\n  \"Štětínská\",\n  \"Šubertova\",\n  \"Šulcova\",\n  \"Šultysova\",\n  \"Šumavská\",\n  \"Šumavského\",\n  \"Šumberova\",\n  \"Šumenská\",\n  \"Šumická\",\n  \"Šumperská\",\n  \"Šustova\",\n  \"Švabinského\",\n  \"Švecova\",\n  \"Švehlova\",\n  \"Švehlova\",\n  \"Švejcarovo Náměstí\",\n  \"Švestková\",\n  \"Švestková\",\n  \"Švestková\",\n  \"Švihovská\",\n  \"Švábky\",\n  \"Švábova\",\n  \"Švédská\",\n  \"Šárecká\",\n  \"Šárovo Kolo\",\n  \"Šárčina\",\n  \"Šátalská\",\n  \"Šífařská\",\n  \"Šímova\",\n  \"Šípková\",\n  \"Šítkova\",\n  \"Šťastného\",\n  \"Šůrova\",\n  \"Žabovřeská\",\n  \"Žacléřská\",\n  \"Žalanského\",\n  \"Žalmanova\",\n  \"Žalovská\",\n  \"Žamberská\",\n  \"Žampašská\",\n  \"Žampiónová\",\n  \"Žandovská\",\n  \"Žatecká\",\n  \"Žatecká\",\n  \"Žateckých\",\n  \"Ždírnická\",\n  \"Žehuňská\",\n  \"Žehušická\",\n  \"Želetavská\",\n  \"Železniční\",\n  \"Železničářů\",\n  \"Železnobrodská\",\n  \"Železná\",\n  \"Želivecká\",\n  \"Želivka\",\n  \"Želivská\",\n  \"Želkovická\",\n  \"Želnavská\",\n  \"Ženíškova\",\n  \"Žeretická\",\n  \"Žermanická\",\n  \"Žernosecká\",\n  \"Žernovská\",\n  \"Žerotínova\",\n  \"Žherská\",\n  \"Žichlínská\",\n  \"Židlického\",\n  \"Žilinská\",\n  \"Žilovská\",\n  \"Žinkovská\",\n  \"Žirovnická\",\n  \"Žitavská\",\n  \"Žitavského\",\n  \"Žitná\",\n  \"Žitná\",\n  \"Žitomírská\",\n  \"Živanická\",\n  \"Živcová\",\n  \"Živcových\",\n  \"Živonínská\",\n  \"Žiželická\",\n  \"Žižkova\",\n  \"Žižkovo Nám.\",\n  \"Žižkovo Náměstí\",\n  \"Žlebská\",\n  \"Žluťásková\",\n  \"Žofie Podlipské\",\n  \"Žufanova\",\n  \"Žukovského\",\n  \"Žukovského\",\n  \"Žulová\",\n  \"Županovická\",\n  \"Žvahovská\",\n  \"Žábova\",\n  \"Žákovská\",\n  \"Žárovická\",\n  \"Žíšovská\",\n  \"Žďárská\",\n];\n\n},{}],65:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_name} #{building_number}\"\n];\n\n},{}],66:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street}\"\n];\n\n},{}],67:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Pacific/Midway\",\n  \"Pacific/Pago_Pago\",\n  \"Pacific/Honolulu\",\n  \"America/Juneau\",\n  \"America/Los_Angeles\",\n  \"America/Tijuana\",\n  \"America/Denver\",\n  \"America/Phoenix\",\n  \"America/Chihuahua\",\n  \"America/Mazatlan\",\n  \"America/Chicago\",\n  \"America/Regina\",\n  \"America/Mexico_City\",\n  \"America/Mexico_City\",\n  \"America/Monterrey\",\n  \"America/Guatemala\",\n  \"America/New_York\",\n  \"America/Indiana/Indianapolis\",\n  \"America/Bogota\",\n  \"America/Lima\",\n  \"America/Lima\",\n  \"America/Halifax\",\n  \"America/Caracas\",\n  \"America/La_Paz\",\n  \"America/Santiago\",\n  \"America/St_Johns\",\n  \"America/Sao_Paulo\",\n  \"America/Argentina/Buenos_Aires\",\n  \"America/Guyana\",\n  \"America/Godthab\",\n  \"Atlantic/South_Georgia\",\n  \"Atlantic/Azores\",\n  \"Atlantic/Cape_Verde\",\n  \"Europe/Dublin\",\n  \"Europe/London\",\n  \"Europe/Lisbon\",\n  \"Europe/London\",\n  \"Africa/Casablanca\",\n  \"Africa/Monrovia\",\n  \"Etc/UTC\",\n  \"Europe/Belgrade\",\n  \"Europe/Bratislava\",\n  \"Europe/Budapest\",\n  \"Europe/Ljubljana\",\n  \"Europe/Prague\",\n  \"Europe/Sarajevo\",\n  \"Europe/Skopje\",\n  \"Europe/Warsaw\",\n  \"Europe/Zagreb\",\n  \"Europe/Brussels\",\n  \"Europe/Copenhagen\",\n  \"Europe/Madrid\",\n  \"Europe/Paris\",\n  \"Europe/Amsterdam\",\n  \"Europe/Berlin\",\n  \"Europe/Berlin\",\n  \"Europe/Rome\",\n  \"Europe/Stockholm\",\n  \"Europe/Vienna\",\n  \"Africa/Algiers\",\n  \"Europe/Bucharest\",\n  \"Africa/Cairo\",\n  \"Europe/Helsinki\",\n  \"Europe/Kiev\",\n  \"Europe/Riga\",\n  \"Europe/Sofia\",\n  \"Europe/Tallinn\",\n  \"Europe/Vilnius\",\n  \"Europe/Athens\",\n  \"Europe/Istanbul\",\n  \"Europe/Minsk\",\n  \"Asia/Jerusalem\",\n  \"Africa/Harare\",\n  \"Africa/Johannesburg\",\n  \"Europe/Moscow\",\n  \"Europe/Moscow\",\n  \"Europe/Moscow\",\n  \"Asia/Kuwait\",\n  \"Asia/Riyadh\",\n  \"Africa/Nairobi\",\n  \"Asia/Baghdad\",\n  \"Asia/Tehran\",\n  \"Asia/Muscat\",\n  \"Asia/Muscat\",\n  \"Asia/Baku\",\n  \"Asia/Tbilisi\",\n  \"Asia/Yerevan\",\n  \"Asia/Kabul\",\n  \"Asia/Yekaterinburg\",\n  \"Asia/Karachi\",\n  \"Asia/Karachi\",\n  \"Asia/Tashkent\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kathmandu\",\n  \"Asia/Dhaka\",\n  \"Asia/Dhaka\",\n  \"Asia/Colombo\",\n  \"Asia/Almaty\",\n  \"Asia/Novosibirsk\",\n  \"Asia/Rangoon\",\n  \"Asia/Bangkok\",\n  \"Asia/Bangkok\",\n  \"Asia/Jakarta\",\n  \"Asia/Krasnoyarsk\",\n  \"Asia/Shanghai\",\n  \"Asia/Chongqing\",\n  \"Asia/Hong_Kong\",\n  \"Asia/Urumqi\",\n  \"Asia/Kuala_Lumpur\",\n  \"Asia/Singapore\",\n  \"Asia/Taipei\",\n  \"Australia/Perth\",\n  \"Asia/Irkutsk\",\n  \"Asia/Ulaanbaatar\",\n  \"Asia/Seoul\",\n  \"Asia/Tokyo\",\n  \"Asia/Tokyo\",\n  \"Asia/Tokyo\",\n  \"Asia/Yakutsk\",\n  \"Australia/Darwin\",\n  \"Australia/Adelaide\",\n  \"Australia/Melbourne\",\n  \"Australia/Melbourne\",\n  \"Australia/Sydney\",\n  \"Australia/Brisbane\",\n  \"Australia/Hobart\",\n  \"Asia/Vladivostok\",\n  \"Pacific/Guam\",\n  \"Pacific/Port_Moresby\",\n  \"Asia/Magadan\",\n  \"Asia/Magadan\",\n  \"Pacific/Noumea\",\n  \"Pacific/Fiji\",\n  \"Asia/Kamchatka\",\n  \"Pacific/Majuro\",\n  \"Pacific/Auckland\",\n  \"Pacific/Auckland\",\n  \"Pacific/Tongatapu\",\n  \"Pacific/Fakaofo\",\n  \"Pacific/Apia\"\n];\n\n},{}],68:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adaptive\",\n  \"Advanced\",\n  \"Ameliorated\",\n  \"Assimilated\",\n  \"Automated\",\n  \"Balanced\",\n  \"Business-focused\",\n  \"Centralized\",\n  \"Cloned\",\n  \"Compatible\",\n  \"Configurable\",\n  \"Cross-group\",\n  \"Cross-platform\",\n  \"Customer-focused\",\n  \"Customizable\",\n  \"Decentralized\",\n  \"De-engineered\",\n  \"Devolved\",\n  \"Digitized\",\n  \"Distributed\",\n  \"Diverse\",\n  \"Down-sized\",\n  \"Enhanced\",\n  \"Enterprise-wide\",\n  \"Ergonomic\",\n  \"Exclusive\",\n  \"Expanded\",\n  \"Extended\",\n  \"Face to face\",\n  \"Focused\",\n  \"Front-line\",\n  \"Fully-configurable\",\n  \"Function-based\",\n  \"Fundamental\",\n  \"Future-proofed\",\n  \"Grass-roots\",\n  \"Horizontal\",\n  \"Implemented\",\n  \"Innovative\",\n  \"Integrated\",\n  \"Intuitive\",\n  \"Inverse\",\n  \"Managed\",\n  \"Mandatory\",\n  \"Monitored\",\n  \"Multi-channelled\",\n  \"Multi-lateral\",\n  \"Multi-layered\",\n  \"Multi-tiered\",\n  \"Networked\",\n  \"Object-based\",\n  \"Open-architected\",\n  \"Open-source\",\n  \"Operative\",\n  \"Optimized\",\n  \"Optional\",\n  \"Organic\",\n  \"Organized\",\n  \"Persevering\",\n  \"Persistent\",\n  \"Phased\",\n  \"Polarised\",\n  \"Pre-emptive\",\n  \"Proactive\",\n  \"Profit-focused\",\n  \"Profound\",\n  \"Programmable\",\n  \"Progressive\",\n  \"Public-key\",\n  \"Quality-focused\",\n  \"Reactive\",\n  \"Realigned\",\n  \"Re-contextualized\",\n  \"Re-engineered\",\n  \"Reduced\",\n  \"Reverse-engineered\",\n  \"Right-sized\",\n  \"Robust\",\n  \"Seamless\",\n  \"Secured\",\n  \"Self-enabling\",\n  \"Sharable\",\n  \"Stand-alone\",\n  \"Streamlined\",\n  \"Switchable\",\n  \"Synchronised\",\n  \"Synergistic\",\n  \"Synergized\",\n  \"Team-oriented\",\n  \"Total\",\n  \"Triple-buffered\",\n  \"Universal\",\n  \"Up-sized\",\n  \"Upgradable\",\n  \"User-centric\",\n  \"User-friendly\",\n  \"Versatile\",\n  \"Virtual\",\n  \"Visionary\",\n  \"Vision-oriented\"\n];\n\n},{}],69:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"clicks-and-mortar\",\n  \"value-added\",\n  \"vertical\",\n  \"proactive\",\n  \"robust\",\n  \"revolutionary\",\n  \"scalable\",\n  \"leading-edge\",\n  \"innovative\",\n  \"intuitive\",\n  \"strategic\",\n  \"e-business\",\n  \"mission-critical\",\n  \"sticky\",\n  \"one-to-one\",\n  \"24/7\",\n  \"end-to-end\",\n  \"global\",\n  \"B2B\",\n  \"B2C\",\n  \"granular\",\n  \"frictionless\",\n  \"virtual\",\n  \"viral\",\n  \"dynamic\",\n  \"24/365\",\n  \"best-of-breed\",\n  \"killer\",\n  \"magnetic\",\n  \"bleeding-edge\",\n  \"web-enabled\",\n  \"interactive\",\n  \"dot-com\",\n  \"sexy\",\n  \"back-end\",\n  \"real-time\",\n  \"efficient\",\n  \"front-end\",\n  \"distributed\",\n  \"seamless\",\n  \"extensible\",\n  \"turn-key\",\n  \"world-class\",\n  \"open-source\",\n  \"cross-platform\",\n  \"cross-media\",\n  \"synergistic\",\n  \"bricks-and-clicks\",\n  \"out-of-the-box\",\n  \"enterprise\",\n  \"integrated\",\n  \"impactful\",\n  \"wireless\",\n  \"transparent\",\n  \"next-generation\",\n  \"cutting-edge\",\n  \"user-centric\",\n  \"visionary\",\n  \"customized\",\n  \"ubiquitous\",\n  \"plug-and-play\",\n  \"collaborative\",\n  \"compelling\",\n  \"holistic\",\n  \"rich\",\n  \"synergies\",\n  \"web-readiness\",\n  \"paradigms\",\n  \"markets\",\n  \"partnerships\",\n  \"infrastructures\",\n  \"platforms\",\n  \"initiatives\",\n  \"channels\",\n  \"eyeballs\",\n  \"communities\",\n  \"ROI\",\n  \"solutions\",\n  \"e-tailers\",\n  \"e-services\",\n  \"action-items\",\n  \"portals\",\n  \"niches\",\n  \"technologies\",\n  \"content\",\n  \"vortals\",\n  \"supply-chains\",\n  \"convergence\",\n  \"relationships\",\n  \"architectures\",\n  \"interfaces\",\n  \"e-markets\",\n  \"e-commerce\",\n  \"systems\",\n  \"bandwidth\",\n  \"infomediaries\",\n  \"models\",\n  \"mindshare\",\n  \"deliverables\",\n  \"users\",\n  \"schemas\",\n  \"networks\",\n  \"applications\",\n  \"metrics\",\n  \"e-business\",\n  \"functionalities\",\n  \"experiences\",\n  \"web services\",\n  \"methodologies\"\n];\n\n},{}],70:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"implement\",\n  \"utilize\",\n  \"integrate\",\n  \"streamline\",\n  \"optimize\",\n  \"evolve\",\n  \"transform\",\n  \"embrace\",\n  \"enable\",\n  \"orchestrate\",\n  \"leverage\",\n  \"reinvent\",\n  \"aggregate\",\n  \"architect\",\n  \"enhance\",\n  \"incentivize\",\n  \"morph\",\n  \"empower\",\n  \"envisioneer\",\n  \"monetize\",\n  \"harness\",\n  \"facilitate\",\n  \"seize\",\n  \"disintermediate\",\n  \"synergize\",\n  \"strategize\",\n  \"deploy\",\n  \"brand\",\n  \"grow\",\n  \"target\",\n  \"syndicate\",\n  \"synthesize\",\n  \"deliver\",\n  \"mesh\",\n  \"incubate\",\n  \"engage\",\n  \"maximize\",\n  \"benchmark\",\n  \"expedite\",\n  \"reintermediate\",\n  \"whiteboard\",\n  \"visualize\",\n  \"repurpose\",\n  \"innovate\",\n  \"scale\",\n  \"unleash\",\n  \"drive\",\n  \"extend\",\n  \"engineer\",\n  \"revolutionize\",\n  \"generate\",\n  \"exploit\",\n  \"transition\",\n  \"e-enable\",\n  \"iterate\",\n  \"cultivate\",\n  \"matrix\",\n  \"productize\",\n  \"redefine\",\n  \"recontextualize\"\n];\n\n},{}],71:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"24 hour\",\n  \"24/7\",\n  \"3rd generation\",\n  \"4th generation\",\n  \"5th generation\",\n  \"6th generation\",\n  \"actuating\",\n  \"analyzing\",\n  \"asymmetric\",\n  \"asynchronous\",\n  \"attitude-oriented\",\n  \"background\",\n  \"bandwidth-monitored\",\n  \"bi-directional\",\n  \"bifurcated\",\n  \"bottom-line\",\n  \"clear-thinking\",\n  \"client-driven\",\n  \"client-server\",\n  \"coherent\",\n  \"cohesive\",\n  \"composite\",\n  \"context-sensitive\",\n  \"contextually-based\",\n  \"content-based\",\n  \"dedicated\",\n  \"demand-driven\",\n  \"didactic\",\n  \"directional\",\n  \"discrete\",\n  \"disintermediate\",\n  \"dynamic\",\n  \"eco-centric\",\n  \"empowering\",\n  \"encompassing\",\n  \"even-keeled\",\n  \"executive\",\n  \"explicit\",\n  \"exuding\",\n  \"fault-tolerant\",\n  \"foreground\",\n  \"fresh-thinking\",\n  \"full-range\",\n  \"global\",\n  \"grid-enabled\",\n  \"heuristic\",\n  \"high-level\",\n  \"holistic\",\n  \"homogeneous\",\n  \"human-resource\",\n  \"hybrid\",\n  \"impactful\",\n  \"incremental\",\n  \"intangible\",\n  \"interactive\",\n  \"intermediate\",\n  \"leading edge\",\n  \"local\",\n  \"logistical\",\n  \"maximized\",\n  \"methodical\",\n  \"mission-critical\",\n  \"mobile\",\n  \"modular\",\n  \"motivating\",\n  \"multimedia\",\n  \"multi-state\",\n  \"multi-tasking\",\n  \"national\",\n  \"needs-based\",\n  \"neutral\",\n  \"next generation\",\n  \"non-volatile\",\n  \"object-oriented\",\n  \"optimal\",\n  \"optimizing\",\n  \"radical\",\n  \"real-time\",\n  \"reciprocal\",\n  \"regional\",\n  \"responsive\",\n  \"scalable\",\n  \"secondary\",\n  \"solution-oriented\",\n  \"stable\",\n  \"static\",\n  \"systematic\",\n  \"systemic\",\n  \"system-worthy\",\n  \"tangible\",\n  \"tertiary\",\n  \"transitional\",\n  \"uniform\",\n  \"upward-trending\",\n  \"user-facing\",\n  \"value-added\",\n  \"web-enabled\",\n  \"well-modulated\",\n  \"zero administration\",\n  \"zero defect\",\n  \"zero tolerance\"\n];\n\n},{}],72:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.adjective = require(\"./adjective\");\ncompany.descriptor = require(\"./descriptor\");\ncompany.noun = require(\"./noun\");\ncompany.bs_verb = require(\"./bs_verb\");\ncompany.bs_noun = require(\"./bs_noun\");\ncompany.name = require(\"./name\");\n\n},{\"./adjective\":68,\"./bs_noun\":69,\"./bs_verb\":70,\"./descriptor\":71,\"./name\":73,\"./noun\":74,\"./suffix\":75}],73:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.man_last_name} a #{Name.man_last_name} #{suffix}\"\n];\n\n},{}],74:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ability\",\n  \"access\",\n  \"adapter\",\n  \"algorithm\",\n  \"alliance\",\n  \"analyzer\",\n  \"application\",\n  \"approach\",\n  \"architecture\",\n  \"archive\",\n  \"artificial intelligence\",\n  \"array\",\n  \"attitude\",\n  \"benchmark\",\n  \"budgetary management\",\n  \"capability\",\n  \"capacity\",\n  \"challenge\",\n  \"circuit\",\n  \"collaboration\",\n  \"complexity\",\n  \"concept\",\n  \"conglomeration\",\n  \"contingency\",\n  \"core\",\n  \"customer loyalty\",\n  \"database\",\n  \"data-warehouse\",\n  \"definition\",\n  \"emulation\",\n  \"encoding\",\n  \"encryption\",\n  \"extranet\",\n  \"firmware\",\n  \"flexibility\",\n  \"focus group\",\n  \"forecast\",\n  \"frame\",\n  \"framework\",\n  \"function\",\n  \"functionalities\",\n  \"Graphic Interface\",\n  \"groupware\",\n  \"Graphical User Interface\",\n  \"hardware\",\n  \"help-desk\",\n  \"hierarchy\",\n  \"hub\",\n  \"implementation\",\n  \"info-mediaries\",\n  \"infrastructure\",\n  \"initiative\",\n  \"installation\",\n  \"instruction set\",\n  \"interface\",\n  \"internet solution\",\n  \"intranet\",\n  \"knowledge user\",\n  \"knowledge base\",\n  \"local area network\",\n  \"leverage\",\n  \"matrices\",\n  \"matrix\",\n  \"methodology\",\n  \"middleware\",\n  \"migration\",\n  \"model\",\n  \"moderator\",\n  \"monitoring\",\n  \"moratorium\",\n  \"neural-net\",\n  \"open architecture\",\n  \"open system\",\n  \"orchestration\",\n  \"paradigm\",\n  \"parallelism\",\n  \"policy\",\n  \"portal\",\n  \"pricing structure\",\n  \"process improvement\",\n  \"product\",\n  \"productivity\",\n  \"project\",\n  \"projection\",\n  \"protocol\",\n  \"secured line\",\n  \"service-desk\",\n  \"software\",\n  \"solution\",\n  \"standardization\",\n  \"strategy\",\n  \"structure\",\n  \"success\",\n  \"superstructure\",\n  \"support\",\n  \"synergy\",\n  \"system engine\",\n  \"task-force\",\n  \"throughput\",\n  \"time-frame\",\n  \"toolset\",\n  \"utilisation\",\n  \"website\",\n  \"workforce\"\n];\n\n},{}],75:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"s.r.o.\",\n  \"a.s.\",\n  \"v.o.s.\"\n];\n\n},{}],76:[function(require,module,exports){\narguments[4][37][0].apply(exports,arguments)\n},{\"./month\":77,\"./weekday\":78,\"/Users/a/dev/faker.js/lib/locales/az/date/index.js\":37}],77:[function(require,module,exports){\n// Source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/en.xml#L1799\nmodule[\"exports\"] = {\n  wide: [\n    \"Leden\",\n    \"Únor\",\n    \"Březen\",\n    \"Duben\",\n    \"Květen\",\n    \"Červen\",\n    \"Červenec\",\n    \"Srpen\",\n    \"Září\",\n    \"Říjen\",\n    \"Listopad\",\n    \"Prosinec\"\n  ],\n  // Property \"wide_context\" is optional, if not set then \"wide\" will be used instead\n  // It is used to specify a word in context, which may differ from a stand-alone word\n  wide_context: [\n    \"Leden\",\n    \"Únor\",\n    \"Březen\",\n    \"Duben\",\n    \"Květen\",\n    \"Červen\",\n    \"Červenec\",\n    \"Srpen\",\n    \"Září\",\n    \"Říjen\",\n    \"Listopad\",\n    \"Prosinec\"\n  ],\n  abbr: [\n    \"Led\",\n    \"Úno\",\n    \"Bře\",\n    \"Dub\",\n    \"Kvě\",\n    \"Čer\",\n    \"Črc\",\n    \"Srp\",\n    \"Zář\",\n    \"Říj\",\n    \"Lis\",\n    \"Pro\"\n  ],\n  // Property \"abbr_context\" is optional, if not set then \"abbr\" will be used instead\n  // It is used to specify a word in context, which may differ from a stand-alone word\n  abbr_context: [\n    \"Led\",\n    \"Úno\",\n    \"Bře\",\n    \"Dub\",\n    \"Kvě\",\n    \"Čer\",\n    \"Črc\",\n    \"Srp\",\n    \"Zář\",\n    \"Říj\",\n    \"Lis\",\n    \"Pro\"\n  ]\n};\n\n},{}],78:[function(require,module,exports){\n// Source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/en.xml#L1847\nmodule[\"exports\"] = {\n  wide: [\n    \"Pondělí\",\n    \"Úterý\",\n    \"Středa\",\n    \"čtvrtek\",\n    \"Pátek\",\n    \"Sobota\",\n    \"Neděle\"\n  ],\n  // Property \"wide_context\" is optional, if not set then \"wide\" will be used instead\n  // It is used to specify a word in context, which may differ from a stand-alone word\n  wide_context: [\n    \"Pondělí\",\n    \"Úterý\",\n    \"Středa\",\n    \"čtvrtek\",\n    \"Pátek\",\n    \"Sobota\",\n    \"Neděle\"\n  ],\n  abbr: [\n    \"Po\",\n    \"Út\",\n    \"St\",\n    \"čt\",\n    \"Pá\",\n    \"So\",\n    \"Ne\"\n  ],\n  // Property \"abbr_context\" is optional, if not set then \"abbr\" will be used instead\n  // It is used to specify a word in context, which may differ from a stand-alone word\n  abbr_context: [\n    \"Po\",\n    \"Út\",\n    \"St\",\n    \"čt\",\n    \"Pá\",\n    \"So\",\n    \"Ne\"\n  ]\n};\n\n},{}],79:[function(require,module,exports){\nvar cz = {};\nmodule['exports'] = cz;\ncz.title = \"Czech\";\ncz.address = require(\"./address\");\ncz.company = require(\"./company\");\ncz.internet = require(\"./internet\");\ncz.lorem = require(\"./lorem\");\ncz.name = require(\"./name\");\ncz.phone_number = require(\"./phone_number\");\ncz.date = require(\"./date\");\n\n},{\"./address\":59,\"./company\":72,\"./date\":76,\"./internet\":82,\"./lorem\":83,\"./name\":88,\"./phone_number\":96}],80:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"cz\",\n  \"com\",\n  \"net\",\n  \"eu\",\n  \"org\"\n];\n\n},{}],81:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"seznam.cz\",\n  \"centrum.cz\",\n  \"volny.cz\",\n  \"atlas.cz\"\n];\n\n},{}],82:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":80,\"./free_email\":81,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],83:[function(require,module,exports){\nvar lorem = {};\nmodule['exports'] = lorem;\nlorem.words = require(\"./words\");\nlorem.supplemental = require(\"./supplemental\");\n\n},{\"./supplemental\":84,\"./words\":85}],84:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"abbas\",\n  \"abduco\",\n  \"abeo\",\n  \"abscido\",\n  \"absconditus\",\n  \"absens\",\n  \"absorbeo\",\n  \"absque\",\n  \"abstergo\",\n  \"absum\",\n  \"abundans\",\n  \"abutor\",\n  \"accedo\",\n  \"accendo\",\n  \"acceptus\",\n  \"accipio\",\n  \"accommodo\",\n  \"accusator\",\n  \"acer\",\n  \"acerbitas\",\n  \"acervus\",\n  \"acidus\",\n  \"acies\",\n  \"acquiro\",\n  \"acsi\",\n  \"adamo\",\n  \"adaugeo\",\n  \"addo\",\n  \"adduco\",\n  \"ademptio\",\n  \"adeo\",\n  \"adeptio\",\n  \"adfectus\",\n  \"adfero\",\n  \"adficio\",\n  \"adflicto\",\n  \"adhaero\",\n  \"adhuc\",\n  \"adicio\",\n  \"adimpleo\",\n  \"adinventitias\",\n  \"adipiscor\",\n  \"adiuvo\",\n  \"administratio\",\n  \"admiratio\",\n  \"admitto\",\n  \"admoneo\",\n  \"admoveo\",\n  \"adnuo\",\n  \"adopto\",\n  \"adsidue\",\n  \"adstringo\",\n  \"adsuesco\",\n  \"adsum\",\n  \"adulatio\",\n  \"adulescens\",\n  \"adultus\",\n  \"aduro\",\n  \"advenio\",\n  \"adversus\",\n  \"advoco\",\n  \"aedificium\",\n  \"aeger\",\n  \"aegre\",\n  \"aegrotatio\",\n  \"aegrus\",\n  \"aeneus\",\n  \"aequitas\",\n  \"aequus\",\n  \"aer\",\n  \"aestas\",\n  \"aestivus\",\n  \"aestus\",\n  \"aetas\",\n  \"aeternus\",\n  \"ager\",\n  \"aggero\",\n  \"aggredior\",\n  \"agnitio\",\n  \"agnosco\",\n  \"ago\",\n  \"ait\",\n  \"aiunt\",\n  \"alienus\",\n  \"alii\",\n  \"alioqui\",\n  \"aliqua\",\n  \"alius\",\n  \"allatus\",\n  \"alo\",\n  \"alter\",\n  \"altus\",\n  \"alveus\",\n  \"amaritudo\",\n  \"ambitus\",\n  \"ambulo\",\n  \"amicitia\",\n  \"amiculum\",\n  \"amissio\",\n  \"amita\",\n  \"amitto\",\n  \"amo\",\n  \"amor\",\n  \"amoveo\",\n  \"amplexus\",\n  \"amplitudo\",\n  \"amplus\",\n  \"ancilla\",\n  \"angelus\",\n  \"angulus\",\n  \"angustus\",\n  \"animadverto\",\n  \"animi\",\n  \"animus\",\n  \"annus\",\n  \"anser\",\n  \"ante\",\n  \"antea\",\n  \"antepono\",\n  \"antiquus\",\n  \"aperio\",\n  \"aperte\",\n  \"apostolus\",\n  \"apparatus\",\n  \"appello\",\n  \"appono\",\n  \"appositus\",\n  \"approbo\",\n  \"apto\",\n  \"aptus\",\n  \"apud\",\n  \"aqua\",\n  \"ara\",\n  \"aranea\",\n  \"arbitro\",\n  \"arbor\",\n  \"arbustum\",\n  \"arca\",\n  \"arceo\",\n  \"arcesso\",\n  \"arcus\",\n  \"argentum\",\n  \"argumentum\",\n  \"arguo\",\n  \"arma\",\n  \"armarium\",\n  \"armo\",\n  \"aro\",\n  \"ars\",\n  \"articulus\",\n  \"artificiose\",\n  \"arto\",\n  \"arx\",\n  \"ascisco\",\n  \"ascit\",\n  \"asper\",\n  \"aspicio\",\n  \"asporto\",\n  \"assentator\",\n  \"astrum\",\n  \"atavus\",\n  \"ater\",\n  \"atqui\",\n  \"atrocitas\",\n  \"atrox\",\n  \"attero\",\n  \"attollo\",\n  \"attonbitus\",\n  \"auctor\",\n  \"auctus\",\n  \"audacia\",\n  \"audax\",\n  \"audentia\",\n  \"audeo\",\n  \"audio\",\n  \"auditor\",\n  \"aufero\",\n  \"aureus\",\n  \"auris\",\n  \"aurum\",\n  \"aut\",\n  \"autem\",\n  \"autus\",\n  \"auxilium\",\n  \"avaritia\",\n  \"avarus\",\n  \"aveho\",\n  \"averto\",\n  \"avoco\",\n  \"baiulus\",\n  \"balbus\",\n  \"barba\",\n  \"bardus\",\n  \"basium\",\n  \"beatus\",\n  \"bellicus\",\n  \"bellum\",\n  \"bene\",\n  \"beneficium\",\n  \"benevolentia\",\n  \"benigne\",\n  \"bestia\",\n  \"bibo\",\n  \"bis\",\n  \"blandior\",\n  \"bonus\",\n  \"bos\",\n  \"brevis\",\n  \"cado\",\n  \"caecus\",\n  \"caelestis\",\n  \"caelum\",\n  \"calamitas\",\n  \"calcar\",\n  \"calco\",\n  \"calculus\",\n  \"callide\",\n  \"campana\",\n  \"candidus\",\n  \"canis\",\n  \"canonicus\",\n  \"canto\",\n  \"capillus\",\n  \"capio\",\n  \"capitulus\",\n  \"capto\",\n  \"caput\",\n  \"carbo\",\n  \"carcer\",\n  \"careo\",\n  \"caries\",\n  \"cariosus\",\n  \"caritas\",\n  \"carmen\",\n  \"carpo\",\n  \"carus\",\n  \"casso\",\n  \"caste\",\n  \"casus\",\n  \"catena\",\n  \"caterva\",\n  \"cattus\",\n  \"cauda\",\n  \"causa\",\n  \"caute\",\n  \"caveo\",\n  \"cavus\",\n  \"cedo\",\n  \"celebrer\",\n  \"celer\",\n  \"celo\",\n  \"cena\",\n  \"cenaculum\",\n  \"ceno\",\n  \"censura\",\n  \"centum\",\n  \"cerno\",\n  \"cernuus\",\n  \"certe\",\n  \"certo\",\n  \"certus\",\n  \"cervus\",\n  \"cetera\",\n  \"charisma\",\n  \"chirographum\",\n  \"cibo\",\n  \"cibus\",\n  \"cicuta\",\n  \"cilicium\",\n  \"cimentarius\",\n  \"ciminatio\",\n  \"cinis\",\n  \"circumvenio\",\n  \"cito\",\n  \"civis\",\n  \"civitas\",\n  \"clam\",\n  \"clamo\",\n  \"claro\",\n  \"clarus\",\n  \"claudeo\",\n  \"claustrum\",\n  \"clementia\",\n  \"clibanus\",\n  \"coadunatio\",\n  \"coaegresco\",\n  \"coepi\",\n  \"coerceo\",\n  \"cogito\",\n  \"cognatus\",\n  \"cognomen\",\n  \"cogo\",\n  \"cohaero\",\n  \"cohibeo\",\n  \"cohors\",\n  \"colligo\",\n  \"colloco\",\n  \"collum\",\n  \"colo\",\n  \"color\",\n  \"coma\",\n  \"combibo\",\n  \"comburo\",\n  \"comedo\",\n  \"comes\",\n  \"cometes\",\n  \"comis\",\n  \"comitatus\",\n  \"commemoro\",\n  \"comminor\",\n  \"commodo\",\n  \"communis\",\n  \"comparo\",\n  \"compello\",\n  \"complectus\",\n  \"compono\",\n  \"comprehendo\",\n  \"comptus\",\n  \"conatus\",\n  \"concedo\",\n  \"concido\",\n  \"conculco\",\n  \"condico\",\n  \"conduco\",\n  \"confero\",\n  \"confido\",\n  \"conforto\",\n  \"confugo\",\n  \"congregatio\",\n  \"conicio\",\n  \"coniecto\",\n  \"conitor\",\n  \"coniuratio\",\n  \"conor\",\n  \"conqueror\",\n  \"conscendo\",\n  \"conservo\",\n  \"considero\",\n  \"conspergo\",\n  \"constans\",\n  \"consuasor\",\n  \"contabesco\",\n  \"contego\",\n  \"contigo\",\n  \"contra\",\n  \"conturbo\",\n  \"conventus\",\n  \"convoco\",\n  \"copia\",\n  \"copiose\",\n  \"cornu\",\n  \"corona\",\n  \"corpus\",\n  \"correptius\",\n  \"corrigo\",\n  \"corroboro\",\n  \"corrumpo\",\n  \"coruscus\",\n  \"cotidie\",\n  \"crapula\",\n  \"cras\",\n  \"crastinus\",\n  \"creator\",\n  \"creber\",\n  \"crebro\",\n  \"credo\",\n  \"creo\",\n  \"creptio\",\n  \"crepusculum\",\n  \"cresco\",\n  \"creta\",\n  \"cribro\",\n  \"crinis\",\n  \"cruciamentum\",\n  \"crudelis\",\n  \"cruentus\",\n  \"crur\",\n  \"crustulum\",\n  \"crux\",\n  \"cubicularis\",\n  \"cubitum\",\n  \"cubo\",\n  \"cui\",\n  \"cuius\",\n  \"culpa\",\n  \"culpo\",\n  \"cultellus\",\n  \"cultura\",\n  \"cum\",\n  \"cunabula\",\n  \"cunae\",\n  \"cunctatio\",\n  \"cupiditas\",\n  \"cupio\",\n  \"cuppedia\",\n  \"cupressus\",\n  \"cur\",\n  \"cura\",\n  \"curatio\",\n  \"curia\",\n  \"curiositas\",\n  \"curis\",\n  \"curo\",\n  \"curriculum\",\n  \"currus\",\n  \"cursim\",\n  \"curso\",\n  \"cursus\",\n  \"curto\",\n  \"curtus\",\n  \"curvo\",\n  \"curvus\",\n  \"custodia\",\n  \"damnatio\",\n  \"damno\",\n  \"dapifer\",\n  \"debeo\",\n  \"debilito\",\n  \"decens\",\n  \"decerno\",\n  \"decet\",\n  \"decimus\",\n  \"decipio\",\n  \"decor\",\n  \"decretum\",\n  \"decumbo\",\n  \"dedecor\",\n  \"dedico\",\n  \"deduco\",\n  \"defaeco\",\n  \"defendo\",\n  \"defero\",\n  \"defessus\",\n  \"defetiscor\",\n  \"deficio\",\n  \"defigo\",\n  \"defleo\",\n  \"defluo\",\n  \"defungo\",\n  \"degenero\",\n  \"degero\",\n  \"degusto\",\n  \"deinde\",\n  \"delectatio\",\n  \"delego\",\n  \"deleo\",\n  \"delibero\",\n  \"delicate\",\n  \"delinquo\",\n  \"deludo\",\n  \"demens\",\n  \"demergo\",\n  \"demitto\",\n  \"demo\",\n  \"demonstro\",\n  \"demoror\",\n  \"demulceo\",\n  \"demum\",\n  \"denego\",\n  \"denique\",\n  \"dens\",\n  \"denuncio\",\n  \"denuo\",\n  \"deorsum\",\n  \"depereo\",\n  \"depono\",\n  \"depopulo\",\n  \"deporto\",\n  \"depraedor\",\n  \"deprecator\",\n  \"deprimo\",\n  \"depromo\",\n  \"depulso\",\n  \"deputo\",\n  \"derelinquo\",\n  \"derideo\",\n  \"deripio\",\n  \"desidero\",\n  \"desino\",\n  \"desipio\",\n  \"desolo\",\n  \"desparatus\",\n  \"despecto\",\n  \"despirmatio\",\n  \"infit\",\n  \"inflammatio\",\n  \"paens\",\n  \"patior\",\n  \"patria\",\n  \"patrocinor\",\n  \"patruus\",\n  \"pauci\",\n  \"paulatim\",\n  \"pauper\",\n  \"pax\",\n  \"peccatus\",\n  \"pecco\",\n  \"pecto\",\n  \"pectus\",\n  \"pecunia\",\n  \"pecus\",\n  \"peior\",\n  \"pel\",\n  \"ocer\",\n  \"socius\",\n  \"sodalitas\",\n  \"sol\",\n  \"soleo\",\n  \"solio\",\n  \"solitudo\",\n  \"solium\",\n  \"sollers\",\n  \"sollicito\",\n  \"solum\",\n  \"solus\",\n  \"solutio\",\n  \"solvo\",\n  \"somniculosus\",\n  \"somnus\",\n  \"sonitus\",\n  \"sono\",\n  \"sophismata\",\n  \"sopor\",\n  \"sordeo\",\n  \"sortitus\",\n  \"spargo\",\n  \"speciosus\",\n  \"spectaculum\",\n  \"speculum\",\n  \"sperno\",\n  \"spero\",\n  \"spes\",\n  \"spiculum\",\n  \"spiritus\",\n  \"spoliatio\",\n  \"sponte\",\n  \"stabilis\",\n  \"statim\",\n  \"statua\",\n  \"stella\",\n  \"stillicidium\",\n  \"stipes\",\n  \"stips\",\n  \"sto\",\n  \"strenuus\",\n  \"strues\",\n  \"studio\",\n  \"stultus\",\n  \"suadeo\",\n  \"suasoria\",\n  \"sub\",\n  \"subito\",\n  \"subiungo\",\n  \"sublime\",\n  \"subnecto\",\n  \"subseco\",\n  \"substantia\",\n  \"subvenio\",\n  \"succedo\",\n  \"succurro\",\n  \"sufficio\",\n  \"suffoco\",\n  \"suffragium\",\n  \"suggero\",\n  \"sui\",\n  \"sulum\",\n  \"sum\",\n  \"summa\",\n  \"summisse\",\n  \"summopere\",\n  \"sumo\",\n  \"sumptus\",\n  \"supellex\",\n  \"super\",\n  \"suppellex\",\n  \"supplanto\",\n  \"suppono\",\n  \"supra\",\n  \"surculus\",\n  \"surgo\",\n  \"sursum\",\n  \"suscipio\",\n  \"suspendo\",\n  \"sustineo\",\n  \"suus\",\n  \"synagoga\",\n  \"tabella\",\n  \"tabernus\",\n  \"tabesco\",\n  \"tabgo\",\n  \"tabula\",\n  \"taceo\",\n  \"tactus\",\n  \"taedium\",\n  \"talio\",\n  \"talis\",\n  \"talus\",\n  \"tam\",\n  \"tamdiu\",\n  \"tamen\",\n  \"tametsi\",\n  \"tamisium\",\n  \"tamquam\",\n  \"tandem\",\n  \"tantillus\",\n  \"tantum\",\n  \"tardus\",\n  \"tego\",\n  \"temeritas\",\n  \"temperantia\",\n  \"templum\",\n  \"temptatio\",\n  \"tempus\",\n  \"tenax\",\n  \"tendo\",\n  \"teneo\",\n  \"tener\",\n  \"tenuis\",\n  \"tenus\",\n  \"tepesco\",\n  \"tepidus\",\n  \"ter\",\n  \"terebro\",\n  \"teres\",\n  \"terga\",\n  \"tergeo\",\n  \"tergiversatio\",\n  \"tergo\",\n  \"tergum\",\n  \"termes\",\n  \"terminatio\",\n  \"tero\",\n  \"terra\",\n  \"terreo\",\n  \"territo\",\n  \"terror\",\n  \"tersus\",\n  \"tertius\",\n  \"testimonium\",\n  \"texo\",\n  \"textilis\",\n  \"textor\",\n  \"textus\",\n  \"thalassinus\",\n  \"theatrum\",\n  \"theca\",\n  \"thema\",\n  \"theologus\",\n  \"thermae\",\n  \"thesaurus\",\n  \"thesis\",\n  \"thorax\",\n  \"thymbra\",\n  \"thymum\",\n  \"tibi\",\n  \"timidus\",\n  \"timor\",\n  \"titulus\",\n  \"tolero\",\n  \"tollo\",\n  \"tondeo\",\n  \"tonsor\",\n  \"torqueo\",\n  \"torrens\",\n  \"tot\",\n  \"totidem\",\n  \"toties\",\n  \"totus\",\n  \"tracto\",\n  \"trado\",\n  \"traho\",\n  \"trans\",\n  \"tredecim\",\n  \"tremo\",\n  \"trepide\",\n  \"tres\",\n  \"tribuo\",\n  \"tricesimus\",\n  \"triduana\",\n  \"triginta\",\n  \"tripudio\",\n  \"tristis\",\n  \"triumphus\",\n  \"trucido\",\n  \"truculenter\",\n  \"tubineus\",\n  \"tui\",\n  \"tum\",\n  \"tumultus\",\n  \"tunc\",\n  \"turba\",\n  \"turbo\",\n  \"turpe\",\n  \"turpis\",\n  \"tutamen\",\n  \"tutis\",\n  \"tyrannus\",\n  \"uberrime\",\n  \"ubi\",\n  \"ulciscor\",\n  \"ullus\",\n  \"ulterius\",\n  \"ultio\",\n  \"ultra\",\n  \"umbra\",\n  \"umerus\",\n  \"umquam\",\n  \"una\",\n  \"unde\",\n  \"undique\",\n  \"universe\",\n  \"unus\",\n  \"urbanus\",\n  \"urbs\",\n  \"uredo\",\n  \"usitas\",\n  \"usque\",\n  \"ustilo\",\n  \"ustulo\",\n  \"usus\",\n  \"uter\",\n  \"uterque\",\n  \"utilis\",\n  \"utique\",\n  \"utor\",\n  \"utpote\",\n  \"utrimque\",\n  \"utroque\",\n  \"utrum\",\n  \"uxor\",\n  \"vaco\",\n  \"vacuus\",\n  \"vado\",\n  \"vae\",\n  \"valde\",\n  \"valens\",\n  \"valeo\",\n  \"valetudo\",\n  \"validus\",\n  \"vallum\",\n  \"vapulus\",\n  \"varietas\",\n  \"varius\",\n  \"vehemens\",\n  \"vel\",\n  \"velociter\",\n  \"velum\",\n  \"velut\",\n  \"venia\",\n  \"venio\",\n  \"ventito\",\n  \"ventosus\",\n  \"ventus\",\n  \"venustas\",\n  \"ver\",\n  \"verbera\",\n  \"verbum\",\n  \"vere\",\n  \"verecundia\",\n  \"vereor\",\n  \"vergo\",\n  \"veritas\",\n  \"vero\",\n  \"versus\",\n  \"verto\",\n  \"verumtamen\",\n  \"verus\",\n  \"vesco\",\n  \"vesica\",\n  \"vesper\",\n  \"vespillo\",\n  \"vester\",\n  \"vestigium\",\n  \"vestrum\",\n  \"vetus\",\n  \"via\",\n  \"vicinus\",\n  \"vicissitudo\",\n  \"victoria\",\n  \"victus\",\n  \"videlicet\",\n  \"video\",\n  \"viduata\",\n  \"viduo\",\n  \"vigilo\",\n  \"vigor\",\n  \"vilicus\",\n  \"vilis\",\n  \"vilitas\",\n  \"villa\",\n  \"vinco\",\n  \"vinculum\",\n  \"vindico\",\n  \"vinitor\",\n  \"vinum\",\n  \"vir\",\n  \"virga\",\n  \"virgo\",\n  \"viridis\",\n  \"viriliter\",\n  \"virtus\",\n  \"vis\",\n  \"viscus\",\n  \"vita\",\n  \"vitiosus\",\n  \"vitium\",\n  \"vito\",\n  \"vivo\",\n  \"vix\",\n  \"vobis\",\n  \"vociferor\",\n  \"voco\",\n  \"volaticus\",\n  \"volo\",\n  \"volubilis\",\n  \"voluntarius\",\n  \"volup\",\n  \"volutabrum\",\n  \"volva\",\n  \"vomer\",\n  \"vomica\",\n  \"vomito\",\n  \"vorago\",\n  \"vorax\",\n  \"voro\",\n  \"vos\",\n  \"votum\",\n  \"voveo\",\n  \"vox\",\n  \"vulariter\",\n  \"vulgaris\",\n  \"vulgivagus\",\n  \"vulgo\",\n  \"vulgus\",\n  \"vulnero\",\n  \"vulnus\",\n  \"vulpes\",\n  \"vulticulus\",\n  \"vultuosus\",\n  \"xiphias\"\n];\n\n},{}],85:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"alias\",\n  \"consequatur\",\n  \"aut\",\n  \"perferendis\",\n  \"sit\",\n  \"voluptatem\",\n  \"accusantium\",\n  \"doloremque\",\n  \"aperiam\",\n  \"eaque\",\n  \"ipsa\",\n  \"quae\",\n  \"ab\",\n  \"illo\",\n  \"inventore\",\n  \"veritatis\",\n  \"et\",\n  \"quasi\",\n  \"architecto\",\n  \"beatae\",\n  \"vitae\",\n  \"dicta\",\n  \"sunt\",\n  \"explicabo\",\n  \"aspernatur\",\n  \"aut\",\n  \"odit\",\n  \"aut\",\n  \"fugit\",\n  \"sed\",\n  \"quia\",\n  \"consequuntur\",\n  \"magni\",\n  \"dolores\",\n  \"eos\",\n  \"qui\",\n  \"ratione\",\n  \"voluptatem\",\n  \"sequi\",\n  \"nesciunt\",\n  \"neque\",\n  \"dolorem\",\n  \"ipsum\",\n  \"quia\",\n  \"dolor\",\n  \"sit\",\n  \"amet\",\n  \"consectetur\",\n  \"adipisci\",\n  \"velit\",\n  \"sed\",\n  \"quia\",\n  \"non\",\n  \"numquam\",\n  \"eius\",\n  \"modi\",\n  \"tempora\",\n  \"incidunt\",\n  \"ut\",\n  \"labore\",\n  \"et\",\n  \"dolore\",\n  \"magnam\",\n  \"aliquam\",\n  \"quaerat\",\n  \"voluptatem\",\n  \"ut\",\n  \"enim\",\n  \"ad\",\n  \"minima\",\n  \"veniam\",\n  \"quis\",\n  \"nostrum\",\n  \"exercitationem\",\n  \"ullam\",\n  \"corporis\",\n  \"nemo\",\n  \"enim\",\n  \"ipsam\",\n  \"voluptatem\",\n  \"quia\",\n  \"voluptas\",\n  \"sit\",\n  \"suscipit\",\n  \"laboriosam\",\n  \"nisi\",\n  \"ut\",\n  \"aliquid\",\n  \"ex\",\n  \"ea\",\n  \"commodi\",\n  \"consequatur\",\n  \"quis\",\n  \"autem\",\n  \"vel\",\n  \"eum\",\n  \"iure\",\n  \"reprehenderit\",\n  \"qui\",\n  \"in\",\n  \"ea\",\n  \"voluptate\",\n  \"velit\",\n  \"esse\",\n  \"quam\",\n  \"nihil\",\n  \"molestiae\",\n  \"et\",\n  \"iusto\",\n  \"odio\",\n  \"dignissimos\",\n  \"ducimus\",\n  \"qui\",\n  \"blanditiis\",\n  \"praesentium\",\n  \"laudantium\",\n  \"totam\",\n  \"rem\",\n  \"voluptatum\",\n  \"deleniti\",\n  \"atque\",\n  \"corrupti\",\n  \"quos\",\n  \"dolores\",\n  \"et\",\n  \"quas\",\n  \"molestias\",\n  \"excepturi\",\n  \"sint\",\n  \"occaecati\",\n  \"cupiditate\",\n  \"non\",\n  \"provident\",\n  \"sed\",\n  \"ut\",\n  \"perspiciatis\",\n  \"unde\",\n  \"omnis\",\n  \"iste\",\n  \"natus\",\n  \"error\",\n  \"similique\",\n  \"sunt\",\n  \"in\",\n  \"culpa\",\n  \"qui\",\n  \"officia\",\n  \"deserunt\",\n  \"mollitia\",\n  \"animi\",\n  \"id\",\n  \"est\",\n  \"laborum\",\n  \"et\",\n  \"dolorum\",\n  \"fuga\",\n  \"et\",\n  \"harum\",\n  \"quidem\",\n  \"rerum\",\n  \"facilis\",\n  \"est\",\n  \"et\",\n  \"expedita\",\n  \"distinctio\",\n  \"nam\",\n  \"libero\",\n  \"tempore\",\n  \"cum\",\n  \"soluta\",\n  \"nobis\",\n  \"est\",\n  \"eligendi\",\n  \"optio\",\n  \"cumque\",\n  \"nihil\",\n  \"impedit\",\n  \"quo\",\n  \"porro\",\n  \"quisquam\",\n  \"est\",\n  \"qui\",\n  \"minus\",\n  \"id\",\n  \"quod\",\n  \"maxime\",\n  \"placeat\",\n  \"facere\",\n  \"possimus\",\n  \"omnis\",\n  \"voluptas\",\n  \"assumenda\",\n  \"est\",\n  \"omnis\",\n  \"dolor\",\n  \"repellendus\",\n  \"temporibus\",\n  \"autem\",\n  \"quibusdam\",\n  \"et\",\n  \"aut\",\n  \"consequatur\",\n  \"vel\",\n  \"illum\",\n  \"qui\",\n  \"dolorem\",\n  \"eum\",\n  \"fugiat\",\n  \"quo\",\n  \"voluptas\",\n  \"nulla\",\n  \"pariatur\",\n  \"at\",\n  \"vero\",\n  \"eos\",\n  \"et\",\n  \"accusamus\",\n  \"officiis\",\n  \"debitis\",\n  \"aut\",\n  \"rerum\",\n  \"necessitatibus\",\n  \"saepe\",\n  \"eveniet\",\n  \"ut\",\n  \"et\",\n  \"voluptates\",\n  \"repudiandae\",\n  \"sint\",\n  \"et\",\n  \"molestiae\",\n  \"non\",\n  \"recusandae\",\n  \"itaque\",\n  \"earum\",\n  \"rerum\",\n  \"hic\",\n  \"tenetur\",\n  \"a\",\n  \"sapiente\",\n  \"delectus\",\n  \"ut\",\n  \"aut\",\n  \"reiciendis\",\n  \"voluptatibus\",\n  \"maiores\",\n  \"doloribus\",\n  \"asperiores\",\n  \"repellat\"\n];\n\n},{}],86:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abigail\",\n  \"Ada\",\n  \"Adalberta\",\n  \"Adéla\",\n  \"Adelaida\",\n  \"Adina\",\n  \"Adolfa\",\n  \"Adolfína\",\n  \"Adriana\",\n  \"Adriána\",\n  \"Adriena\",\n  \"Afra\",\n  \"Agáta\",\n  \"Aglaja\",\n  \"Aida\",\n  \"Alana\",\n  \"Albena\",\n  \"Alberta\",\n  \"Albertina\",\n  \"Albertýna\",\n  \"Albína\",\n  \"Alena\",\n  \"Aleška\",\n  \"Alexandra\",\n  \"Alfréda\",\n  \"Alice\",\n  \"Alida\",\n  \"Alina\",\n  \"Alma\",\n  \"Aloisie\",\n  \"Alojzije\",\n  \"Alžběta\",\n  \"Amálie\",\n  \"Amanda\",\n  \"Amáta\",\n  \"Amélie\",\n  \"Anabela\",\n  \"Anastázie\",\n  \"Anatázie\",\n  \"Anatolie\",\n  \"Anatólie\",\n  \"Anděla\",\n  \"Andělína\",\n  \"Andrea\",\n  \"Aneta\",\n  \"Anežka\",\n  \"Angela\",\n  \"Angelika\",\n  \"Anita\",\n  \"Anna\",\n  \"Anselma\",\n  \"Antonie\",\n  \"Apolena\",\n  \"Arabela\",\n  \"Aranka\",\n  \"Areta\",\n  \"Ariadna\",\n  \"Ariana\",\n  \"Ariela\",\n  \"Arleta\",\n  \"Armida\",\n  \"Arna\",\n  \"Arnolda\",\n  \"Arnoštka\",\n  \"Astrid\",\n  \"Astrida\",\n  \"Atanázie\",\n  \"Augusta\",\n  \"Augustina\",\n  \"Augustýna\",\n  \"Aura\",\n  \"Aurélie\",\n  \"Aurora\",\n  \"Babeta\",\n  \"Barbara\",\n  \"Barbora\",\n  \"Beáta\",\n  \"Beatrice\",\n  \"Bedřiška\",\n  \"Bela\",\n  \"Běla\",\n  \"Belinda\",\n  \"Benedikta\",\n  \"Berenika\",\n  \"Berit\",\n  \"Bernarda\",\n  \"Berta\",\n  \"Bertolda\",\n  \"Bianka\",\n  \"Bibiana\",\n  \"Birgit\",\n  \"Birgita\",\n  \"Blahomila\",\n  \"Blahomíra\",\n  \"Blahoslava\",\n  \"Blanka\",\n  \"Blažena\",\n  \"Bohdana\",\n  \"Bohumila\",\n  \"Bohumíra\",\n  \"Bohuna\",\n  \"Bohuslava\",\n  \"Bohuše\",\n  \"Bojana\",\n  \"Bojislava\",\n  \"Boleslava\",\n  \"Borislava\",\n  \"Bořislava\",\n  \"Božena\",\n  \"Božetěcha\",\n  \"Božidara\",\n  \"Branimíra\",\n  \"Branislava\",\n  \"Bratislava\",\n  \"Brenda\",\n  \"Brigita\",\n  \"Brita\",\n  \"Bronislava\",\n  \"Bruna\",\n  \"Brunhilda\",\n  \"Břetislava\",\n  \"Cecilie\",\n  \"Cecílie\",\n  \"Celestina\",\n  \"Celestýna\",\n  \"Celie\",\n  \"Celina\",\n  \"Ctibora\",\n  \"Ctirada\",\n  \"Ctislava\",\n  \"Cyntie\",\n  \"Cyrila\",\n  \"Čeňka\",\n  \"Čestmíra\",\n  \"Čistoslava\",\n  \"Dagmar\",\n  \"Dagmara\",\n  \"Dalibora\",\n  \"Dalida\",\n  \"Dalie\",\n  \"Dalila\",\n  \"Dalimila\",\n  \"Dalimíra\",\n  \"Damaris\",\n  \"Damiana\",\n  \"Damiána\",\n  \"Dana\",\n  \"Danica\",\n  \"Daniela\",\n  \"Danuše\",\n  \"Danuta\",\n  \"Daria\",\n  \"Darie\",\n  \"Darina\",\n  \"Darja\",\n  \"Davida\",\n  \"Debora\",\n  \"Delie\",\n  \"Denisa\",\n  \"Diana\",\n  \"Dina\",\n  \"Dita\",\n  \"Diviška\",\n  \"Dobrava\",\n  \"Dobromila\",\n  \"Dobromíra\",\n  \"Dobroslava\",\n  \"Dominika\",\n  \"Donalda\",\n  \"Donáta\",\n  \"Dora\",\n  \"Doris\",\n  \"Dorota\",\n  \"Doubrava\",\n  \"Doubravka\",\n  \"Drahomila\",\n  \"Drahomíra\",\n  \"Drahoslava\",\n  \"Drahotína\",\n  \"Drahuše\",\n  \"Dulcinea\",\n  \"Dušana\",\n  \"Edita\",\n  \"Eduarda\",\n  \"Edvarda\",\n  \"Egona\",\n  \"Ela\",\n  \"Elektra\",\n  \"Elena\",\n  \"Eleonora\",\n  \"Elfrída\",\n  \"Eliška\",\n  \"Elsa\",\n  \"Elvíra\",\n  \"Elza\",\n  \"Ema\",\n  \"Emanuela\",\n  \"Emilie\",\n  \"Emílie\",\n  \"Erika\",\n  \"Erna\",\n  \"Ervína\",\n  \"Estela\",\n  \"Ester\",\n  \"Estera\",\n  \"Etela\",\n  \"Eufrozina\",\n  \"Eufrozína\",\n  \"Eugenie\",\n  \"Eulálie\",\n  \"Eunika\",\n  \"Eusebie\",\n  \"Eva\",\n  \"Evelina\",\n  \"Evelína\",\n  \"Evženie\",\n  \"Fabiána\",\n  \"Fabie\",\n  \"Fatima\",\n  \"Faustina\",\n  \"Faustýna\",\n  \"Féba\",\n  \"Fedora\",\n  \"Felicie\",\n  \"Felície\",\n  \"Felicita\",\n  \"Ferdinanda\",\n  \"Fidelie\",\n  \"Filipa\",\n  \"Filoména\",\n  \"Flavie\",\n  \"Flora\",\n  \"Flóra\",\n  \"Florentina\",\n  \"Florentýna\",\n  \"Františka\",\n  \"Frída\",\n  \"Gabriela\",\n  \"Gaja\",\n  \"Gajana\",\n  \"Galina\",\n  \"Garika\",\n  \"Gema\",\n  \"Geralda\",\n  \"Geraldina\",\n  \"Gerarda\",\n  \"Gerardina\",\n  \"Gerda\",\n  \"Gerharda\",\n  \"Gertruda\",\n  \"Gilberta\",\n  \"Gina\",\n  \"Gisela\",\n  \"Gita\",\n  \"Gizela\",\n  \"Glorie\",\n  \"Gordana\",\n  \"Graciána\",\n  \"Gracie\",\n  \"Grácie\",\n  \"Gražina\",\n  \"Gréta\",\n  \"Griselda\",\n  \"Grizelda\",\n  \"Gudrun\",\n  \"Gustava\",\n  \"Gvendolina\",\n  \"Gvendolína\",\n  \"Halina\",\n  \"Hana\",\n  \"Háta\",\n  \"Havla\",\n  \"Heda\",\n  \"Hedvika\",\n  \"Heidrun\",\n  \"Helena\",\n  \"Helga\",\n  \"Herberta\",\n  \"Hermína\",\n  \"Herta\",\n  \"Hilda\",\n  \"Hortensie\",\n  \"Hortenzie\",\n  \"Horymíra\",\n  \"Hostimila\",\n  \"Hostimíra\",\n  \"Hostislava\",\n  \"Hvězdoslava\",\n  \"Hyacinta\",\n  \"Chranislava\",\n  \"Iboja\",\n  \"Ida\",\n  \"Ignácie\",\n  \"Ignáta\",\n  \"Ildika\",\n  \"Iljana\",\n  \"Ilona\",\n  \"Ilsa\",\n  \"Ilza\",\n  \"Ines\",\n  \"Inesa\",\n  \"Inéz\",\n  \"Ingeborg\",\n  \"Ingeborga\",\n  \"Ingrid\",\n  \"Ingrida\",\n  \"Inka\",\n  \"Irena\",\n  \"Iris\",\n  \"Irma\",\n  \"Isabela\",\n  \"Isidora\",\n  \"Isolda\",\n  \"Iva\",\n  \"Ivana\",\n  \"Iveta\",\n  \"Ivona\",\n  \"Izabela\",\n  \"Izidora\",\n  \"Izolda\",\n  \"Jadrana\",\n  \"Jadranka\",\n  \"Jakuba\",\n  \"Jakubka\",\n  \"Jana\",\n  \"Jarmila\",\n  \"Jarolíma\",\n  \"Jaromíra\",\n  \"Jaroslava\",\n  \"Jasmína\",\n  \"Jasna\",\n  \"Jasněna\",\n  \"Jelena\",\n  \"Jenovéfa\",\n  \"Jesika\",\n  \"Jindra\",\n  \"Jindřiška\",\n  \"Jiřina\",\n  \"Jitka\",\n  \"Johana\",\n  \"Jolana\",\n  \"Jolanta\",\n  \"Jordana\",\n  \"Jorga\",\n  \"Josefa\",\n  \"Josefína\",\n  \"Jovana\",\n  \"Jozefa\",\n  \"Jozefína\",\n  \"Judita\",\n  \"Juliana\",\n  \"Juliána\",\n  \"Julie\",\n  \"Justina\",\n  \"Justýna\",\n  \"Juta\",\n  \"Kamila\",\n  \"Karin\",\n  \"Karina\",\n  \"Karla\",\n  \"Karmela\",\n  \"Karmen\",\n  \"Karolina\",\n  \"Karolína\",\n  \"Kateřina\",\n  \"Katrin\",\n  \"Katrina\",\n  \"Kazi\",\n  \"Kazimíra\",\n  \"Kira\",\n  \"Klára\",\n  \"Klaudie\",\n  \"Klementina\",\n  \"Klementýna\",\n  \"Kleopatra\",\n  \"Klotylda\",\n  \"Koleta\",\n  \"Kolombína\",\n  \"Kolumbína\",\n  \"Konstance\",\n  \"Konstancie\",\n  \"Konsuela\",\n  \"Konzuela\",\n  \"Kora\",\n  \"Kordula\",\n  \"Korina\",\n  \"Kornélie\",\n  \"Krasava\",\n  \"Krasomila\",\n  \"Kristina\",\n  \"Kristýna\",\n  \"Kunhuta\",\n  \"Květa\",\n  \"Květoslava\",\n  \"Květuše\",\n  \"Lada\",\n  \"Ladislava\",\n  \"Larisa\",\n  \"Laura\",\n  \"Laurencie\",\n  \"Lea\",\n  \"Léda\",\n  \"Leila\",\n  \"Lejla\",\n  \"Lena\",\n  \"Lenka\",\n  \"Leokádie\",\n  \"Leona\",\n  \"Leonora\",\n  \"Leontina\",\n  \"Leontýna\",\n  \"Leopolda\",\n  \"Leopoldina\",\n  \"Leopoldýna\",\n  \"Leticie\",\n  \"Lia\",\n  \"Liana\",\n  \"Liběna\",\n  \"Libora\",\n  \"Liboslava\",\n  \"Libuše\",\n  \"Lidmila\",\n  \"Liliana\",\n  \"Lina\",\n  \"Linda\",\n  \"Livie\",\n  \"Ljuba\",\n  \"Lola\",\n  \"Loreta\",\n  \"Lorna\",\n  \"Lota\",\n  \"Lubomíra\",\n  \"Luboslava\",\n  \"Luciána\",\n  \"Lucie\",\n  \"Ludiše\",\n  \"Luďka\",\n  \"Ludmila\",\n  \"Ludomíra\",\n  \"Ludoslava\",\n  \"Ludvika\",\n  \"Ludvíka\",\n  \"Luisa\",\n  \"Lujza\",\n  \"Lukrécie\",\n  \"Lumíra\",\n  \"Lydie\",\n  \"Lýdie\",\n  \"Mabel\",\n  \"Mabela\",\n  \"Magda\",\n  \"Magdalena\",\n  \"Magdaléna\",\n  \"Mahulena\",\n  \"Maja\",\n  \"Mája\",\n  \"Malvína\",\n  \"Manon\",\n  \"Manona\",\n  \"Manuela\",\n  \"Marcela\",\n  \"Marcelína\",\n  \"Margit\",\n  \"Margita\",\n  \"Mariana\",\n  \"Marie\",\n  \"Marieta\",\n  \"Marika\",\n  \"Marilyn\",\n  \"Marina\",\n  \"Mariola\",\n  \"Marion\",\n  \"Marisa\",\n  \"Marita\",\n  \"Markéta\",\n  \"Marlena\",\n  \"Marta\",\n  \"Martina\",\n  \"Matylda\",\n  \"Maud\",\n  \"Maxima\",\n  \"Mečislava\",\n  \"Medea\",\n  \"Médea\",\n  \"Melánie\",\n  \"Melinda\",\n  \"Melisa\",\n  \"Melita\",\n  \"Mercedes\",\n  \"Michaela\",\n  \"Michala\",\n  \"Milada\",\n  \"Milana\",\n  \"Milena\",\n  \"Miloslava\",\n  \"Milred\",\n  \"Miluše\",\n  \"Mína\",\n  \"Mira\",\n  \"Mirabela\",\n  \"Miranda\",\n  \"Mirela\",\n  \"Miriam\",\n  \"Mirjam\",\n  \"Mirka\",\n  \"Miromila\",\n  \"Miroslava\",\n  \"Mnislava\",\n  \"Mona\",\n  \"Monika\",\n  \"Muriel\",\n  \"Muriela\",\n  \"Myrna\",\n  \"Naďa\",\n  \"Naděžda\",\n  \"Naneta\",\n  \"Narcisa\",\n  \"Natalie\",\n  \"Natálie\",\n  \"Nataša\",\n  \"Neda\",\n  \"Nela\",\n  \"Nevena\",\n  \"Nika\",\n  \"Niké\",\n  \"Nikodéma\",\n  \"Nikol\",\n  \"Nikola\",\n  \"Nila\",\n  \"Nina\",\n  \"Noema\",\n  \"Noemi\",\n  \"Nona\",\n  \"Nora\",\n  \"Norberta\",\n  \"Norma\",\n  \"Odeta\",\n  \"Ofélie\",\n  \"Oktavie\",\n  \"Oktávie\",\n  \"Oldřiška\",\n  \"Olga\",\n  \"Oliva\",\n  \"Olivie\",\n  \"Olympie\",\n  \"Ondřejka\",\n  \"Otakara\",\n  \"Otilie\",\n  \"Otýlie\",\n  \"Oxana\",\n  \"Palmira\",\n  \"Pamela\",\n  \"Paskala\",\n  \"Patricie\",\n  \"Pavla\",\n  \"Pavlína\",\n  \"Pelagie\",\n  \"Penelopa\",\n  \"Perla\",\n  \"Persida\",\n  \"Perzida\",\n  \"Petra\",\n  \"Petrana\",\n  \"Petronela\",\n  \"Petronila\",\n  \"Petruše\",\n  \"Petula\",\n  \"Pilar\",\n  \"Polyxena\",\n  \"Pravdomila\",\n  \"Pravomila\",\n  \"Pravoslav\",\n  \"Pravoslava\",\n  \"Priscila\",\n  \"Priska\",\n  \"Prokopa\",\n  \"Přibyslava\",\n  \"Radana\",\n  \"Radimíra\",\n  \"Radislava\",\n  \"Radka\",\n  \"Radmila\",\n  \"Radomila\",\n  \"Radomíra\",\n  \"Radoslava\",\n  \"Radovana\",\n  \"Radslava\",\n  \"Rafaela\",\n  \"Ráchel\",\n  \"Raisa\",\n  \"Rajsa\",\n  \"Ramona\",\n  \"Rastislava\",\n  \"Rebeka\",\n  \"Regina\",\n  \"Regína\",\n  \"Renata\",\n  \"Renáta\",\n  \"René\",\n  \"Ria\",\n  \"Riana\",\n  \"Richarda\",\n  \"Rina\",\n  \"Rita\",\n  \"Roberta\",\n  \"Robina\",\n  \"Romana\",\n  \"Rosa\",\n  \"Rosalinda\",\n  \"Rosamunda\",\n  \"Rosana\",\n  \"Rostislava\",\n  \"Rovena\",\n  \"Roxana\",\n  \"Róza\",\n  \"Rozálie\",\n  \"Rozalinda\",\n  \"Rozamunda\",\n  \"Rozana\",\n  \"Rozina\",\n  \"Rozita\",\n  \"Rozvita\",\n  \"Rudolfa\",\n  \"Rudolfina\",\n  \"Rudolfína\",\n  \"Rut\",\n  \"Rút\",\n  \"Růžena\",\n  \"Řehořka\",\n  \"Sabina\",\n  \"Sabrina\",\n  \"Salomea\",\n  \"Salomena\",\n  \"Samuela\",\n  \"Sandra\",\n  \"Sára\",\n  \"Saskia\",\n  \"Saskie\",\n  \"Saxona\",\n  \"Selena\",\n  \"Selma\",\n  \"Senta\",\n  \"Serafína\",\n  \"Serena\",\n  \"Scholastika\",\n  \"Sibyla\",\n  \"Sidonie\",\n  \"Silvána\",\n  \"Silvie\",\n  \"Simeona\",\n  \"Simona\",\n  \"Skarlet\",\n  \"Skarleta\",\n  \"Slavěna\",\n  \"Slávka\",\n  \"Slavomila\",\n  \"Slavomíra\",\n  \"Soběslava\",\n  \"Sofie\",\n  \"Sofronie\",\n  \"Solveig\",\n  \"Solveiga\",\n  \"Soňa\",\n  \"Sotira\",\n  \"Stanislava\",\n  \"Stáza\",\n  \"Stela\",\n  \"Svatava\",\n  \"Svatoslava\",\n  \"Světla\",\n  \"Světlana\",\n  \"Světluše\",\n  \"Sylva\",\n  \"Sylvie\",\n  \"Sylvie\",\n  \"Šárka\",\n  \"Šarlota\",\n  \"Šimona\",\n  \"Štěpána\",\n  \"Štěpánka\",\n  \"Tamara\",\n  \"Táňa\",\n  \"Taťána\",\n  \"Tea\",\n  \"Tekla\",\n  \"Teodora\",\n  \"Teodozie\",\n  \"Teofila\",\n  \"Tereza\",\n  \"Terezie\",\n  \"Thea\",\n  \"Theodora\",\n  \"Theodosie\",\n  \"Theofila\",\n  \"Tomáška\",\n  \"Toska\",\n  \"Ulrika\",\n  \"Una\",\n  \"Uršula\",\n  \"Václava\",\n  \"Valburga\",\n  \"Valdemara\",\n  \"Valentina\",\n  \"Valentýna\",\n  \"Valerie\",\n  \"Valérie\",\n  \"Vanda\",\n  \"Vanesa\",\n  \"Věduna\",\n  \"Veleslava\",\n  \"Velislava\",\n  \"Věnceslava\",\n  \"Vendelína\",\n  \"Vendula\",\n  \"Vendulka\",\n  \"Věnka\",\n  \"Venuše\",\n  \"Věra\",\n  \"Verona\",\n  \"Veronika\",\n  \"Věroslava\",\n  \"Věslava\",\n  \"Vesna\",\n  \"Viktorie\",\n  \"Viléma\",\n  \"Vilemína\",\n  \"Vilma\",\n  \"Vincencie\",\n  \"Viola\",\n  \"Violeta\",\n  \"Virginie\",\n  \"Virgínie\",\n  \"Víta\",\n  \"Vítězslava\",\n  \"Viviana\",\n  \"Vladana\",\n  \"Vladěna\",\n  \"Vladimíra\",\n  \"Vladislava\",\n  \"Vlasta\",\n  \"Vlastimila\",\n  \"Vlastimíra\",\n  \"Vlastislava\",\n  \"Vojmíra\",\n  \"Vojslava\",\n  \"Vojtěška\",\n  \"Voršila\",\n  \"Vratislava\",\n  \"Xaverie\",\n  \"Xenie\",\n  \"Zaida\",\n  \"Zaira\",\n  \"Zbyhněva\",\n  \"Zbyňka\",\n  \"Zbyslava\",\n  \"Zbyška\",\n  \"Zdena\",\n  \"Zdenka\",\n  \"Zdeňka\",\n  \"Zdeslava\",\n  \"Zdislava\",\n  \"Zenobie\",\n  \"Zina\",\n  \"Zinaida\",\n  \"Zita\",\n  \"Zlata\",\n  \"Zlatomíra\",\n  \"Zlatuše\",\n  \"Zoe\",\n  \"Zoja\",\n  \"Zora\",\n  \"Zoroslava\",\n  \"Zuzana\",\n  \"Zvonimíra\",\n  \"Žakelina\",\n  \"Žakelína\",\n  \"Žaneta\",\n  \"Ždana\",\n  \"Želimíra\",\n  \"Želislava\",\n  \"Želmíra\",\n  \"Žitomíra\",\n  \"Žitoslava\",\n  \"Živa\",\n  \"Živana\",\n  \"Žofie\",\n];\n\n},{}],87:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adamová\",\n  \"Adamcová\",\n  \"Adámková\",\n  \"Albrechtová\",\n  \"Ambrožová\",\n  \"Andělová\",\n  \"Andrleová\",\n  \"Antošová\",\n  \"Bajrová\",\n  \"Balážová\",\n  \"Balcarová\",\n  \"Balogová\",\n  \"Balounová\",\n  \"Baráková\",\n  \"Baranová\",\n  \"Barešová\",\n  \"Bártová\",\n  \"Bartáková\",\n  \"Bartoňová\",\n  \"Bartošová\",\n  \"Bartošková\",\n  \"Bartůněková\",\n  \"Baštová\",\n  \"Baurová\",\n  \"Bayrová\",\n  \"Bažantová\",\n  \"Bečková\",\n  \"Bečvářová\",\n  \"Bednářová\",\n  \"Bednaříková\",\n  \"Bělohlávková\",\n  \"Bendová\",\n  \"Benešová\",\n  \"Beranová\",\n  \"Beránková\",\n  \"Bergrová\",\n  \"Berková\",\n  \"Berkyová\",\n  \"Bernardová\",\n  \"Bezděková\",\n  \"Bílková\",\n  \"Bílýová\",\n  \"Bínová\",\n  \"Bittnrová\",\n  \"Blahová\",\n  \"Bláhová\",\n  \"Blažková\",\n  \"Blechová\",\n  \"Bobková\",\n  \"Bočková\",\n  \"Boháčová\",\n  \"Boháčková\",\n  \"Böhmová\",\n  \"Borovičková\",\n  \"Boučková\",\n  \"Boudová\",\n  \"Boušková\",\n  \"Brabcová\",\n  \"Brabencová\",\n  \"Bradová\",\n  \"Bradáčová\",\n  \"Braunová\",\n  \"Brázdová\",\n  \"Brázdilová\",\n  \"Brejchová\",\n  \"Březinová\",\n  \"Břízová\",\n  \"Brožová\",\n  \"Brožková\",\n  \"Brychtová\",\n  \"Bubeníková\",\n  \"Bučková\",\n  \"Buchtová\",\n  \"Burdová\",\n  \"Burešová\",\n  \"Burianová\",\n  \"Buriánková\",\n  \"Byrtusová\",\n  \"čadová\",\n  \"Cahová\",\n  \"čápová\",\n  \"čapková\",\n  \"čechová\",\n  \"čejková\",\n  \"čermáková\",\n  \"černíková\",\n  \"černochová\",\n  \"černohorskýová\",\n  \"černýová\",\n  \"červeňáková\",\n  \"červenková\",\n  \"červenýová\",\n  \"červinková\",\n  \"Chaloupková\",\n  \"Chalupová\",\n  \"Charvátová\",\n  \"Chládková\",\n  \"Chlupová\",\n  \"Chmelařová\",\n  \"Chmelíková\",\n  \"Chovancová\",\n  \"Chromýová\",\n  \"Chudobová\",\n  \"Chvátalová\",\n  \"Chvojková\",\n  \"Chytilová\",\n  \"Cibulková\",\n  \"čiháková\",\n  \"Cihlářová\",\n  \"Císařová\",\n  \"čížková\",\n  \"čonková\",\n  \"Coufalová\",\n  \"čurdová\",\n  \"Daněková\",\n  \"Danilová\",\n  \"Danišová\",\n  \"Davidová\",\n  \"Dědková\",\n  \"Demetrová\",\n  \"Dittrichová\",\n  \"Divišová\",\n  \"Dlouhýová\",\n  \"Dobešová\",\n  \"Dobiášová\",\n  \"Dobrovolnýová\",\n  \"Dočekalová\",\n  \"Dočkalová\",\n  \"Dohnalová\",\n  \"Dokoupilová\",\n  \"Dolečková\",\n  \"Dolejšová\",\n  \"Dolejšíová\",\n  \"Doležalová\",\n  \"Doležlová\",\n  \"Doskočilová\",\n  \"Dostálová\",\n  \"Doubková\",\n  \"Doubravová\",\n  \"Doušová\",\n  \"Drábková\",\n  \"Drozdová\",\n  \"Dubskýová\",\n  \"Duchoňová\",\n  \"Dudová\",\n  \"Dudková\",\n  \"Dufková\",\n  \"Dunková\",\n  \"Dušková\",\n  \"Dvořáčková\",\n  \"Dvořáková\",\n  \"Dvorskýová\",\n  \"Eliášová\",\n  \"Erbnová\",\n  \"Fabiánová\",\n  \"Fantová\",\n  \"Farkašová\",\n  \"Fejfarová\",\n  \"Fenclová\",\n  \"Ferencová\",\n  \"Ferkoová\",\n  \"Fialová\",\n  \"Fiedlrová\",\n  \"Filipová\",\n  \"Fischrová\",\n  \"Fišrová\",\n  \"Floriánová\",\n  \"Fojtíková\",\n  \"Foltýnová\",\n  \"Formanová\",\n  \"Formánková\",\n  \"Fořtová\",\n  \"Fousková\",\n  \"Francová\",\n  \"Franěková\",\n  \"Franková\",\n  \"Fridrichová\",\n  \"Frydrychová\",\n  \"Fuchsová\",\n  \"Fučíková\",\n  \"Fuksová\",\n  \"Gáborová\",\n  \"Gabrilová\",\n  \"Gajdošová\",\n  \"Gažiová\",\n  \"Gottwaldová\",\n  \"Gregorová\",\n  \"Grubrová\",\n  \"Grundzová\",\n  \"Grygarová\",\n  \"Hájková\",\n  \"Hajnýová\",\n  \"Hálová\",\n  \"Hamplová\",\n  \"Hánová\",\n  \"Hanáčková\",\n  \"Hanáková\",\n  \"Hanousková\",\n  \"Hanusová\",\n  \"Hanušová\",\n  \"Hanzalová\",\n  \"Hanzlová\",\n  \"Hanzlíková\",\n  \"Hartmanová\",\n  \"Hašková\",\n  \"Havlová\",\n  \"Havelková\",\n  \"Havlíčková\",\n  \"Havlíková\",\n  \"Havránková\",\n  \"Heczkoová\",\n  \"Hegrová\",\n  \"Hejdová\",\n  \"Hejduková\",\n  \"Hejlová\",\n  \"Hejnová\",\n  \"Hendrychová\",\n  \"Hermanová\",\n  \"Heřmanová\",\n  \"Heřmánková\",\n  \"Hladíková\",\n  \"Hladkýová\",\n  \"Hlaváčová\",\n  \"Hlaváčková\",\n  \"Hlavatýová\",\n  \"Hlávková\",\n  \"Hloušková\",\n  \"Hoffmannová\",\n  \"Hofmanová\",\n  \"Holanová\",\n  \"Holasová\",\n  \"Holcová\",\n  \"Holečková\",\n  \"Holíková\",\n  \"Holoubková\",\n  \"Holubová\",\n  \"Holýová\",\n  \"Homolová\",\n  \"Homolková\",\n  \"Horová\",\n  \"Horáčková\",\n  \"Horáková\",\n  \"Hořejšíová\",\n  \"Horkýová\",\n  \"Horňáková\",\n  \"Horníčková\",\n  \"Horníková\",\n  \"Horskýová\",\n  \"Horvátová\",\n  \"Horváthová\",\n  \"Hošková\",\n  \"Houdková\",\n  \"Houšková\",\n  \"Hovorková\",\n  \"Hrabalová\",\n  \"Hrabovskýová\",\n  \"Hradeckýová\",\n  \"Hradilová\",\n  \"Hrbáčková\",\n  \"Hrbková\",\n  \"Hrdinová\",\n  \"Hrdličková\",\n  \"Hrdýová\",\n  \"Hrnčířová\",\n  \"Hrochová\",\n  \"Hromádková\",\n  \"Hronová\",\n  \"Hrubešová\",\n  \"Hrubýová\",\n  \"Hrušková\",\n  \"Hrůzová\",\n  \"Hubáčková\",\n  \"Hudcová\",\n  \"Hudečková\",\n  \"Hůlková\",\n  \"Humlová\",\n  \"Husáková\",\n  \"Hušková\",\n  \"Hýblová\",\n  \"Hynková\",\n  \"Jahodová\",\n  \"Jakešová\",\n  \"Jaklová\",\n  \"Jakoubková\",\n  \"Jakubcová\",\n  \"Janáčková\",\n  \"Janáková\",\n  \"Janatová\",\n  \"Jančová\",\n  \"Jančíková\",\n  \"Jandová\",\n  \"Janečková\",\n  \"Janečková\",\n  \"Janíčková\",\n  \"Janíková\",\n  \"Jankůová\",\n  \"Janotová\",\n  \"Janoušková\",\n  \"Janovskýová\",\n  \"Jansová\",\n  \"Jánskýová\",\n  \"Janůová\",\n  \"Jarešová\",\n  \"Jarošová\",\n  \"Jašková\",\n  \"Javůrková\",\n  \"Jechová\",\n  \"Jedličková\",\n  \"Jelnová\",\n  \"Jelínková\",\n  \"Jeníčková\",\n  \"Jeřábková\",\n  \"Ježová\",\n  \"Ježková\",\n  \"Jílková\",\n  \"Jindrová\",\n  \"Jírová\",\n  \"Jiráková\",\n  \"Jiránková\",\n  \"Jirásková\",\n  \"Jiříková\",\n  \"Jirková\",\n  \"Jirkůová\",\n  \"Jiroušková\",\n  \"Jirsová\",\n  \"Johnová\",\n  \"Jonášová\",\n  \"Junková\",\n  \"Jurčíková\",\n  \"Jurečková\",\n  \"Juřicová\",\n  \"Juříková\",\n  \"Kabátová\",\n  \"Kačírková\",\n  \"Kadeřábková\",\n  \"Kadlcová\",\n  \"Kafková\",\n  \"Kaisrová\",\n  \"Kalová\",\n  \"Kalábová\",\n  \"Kalašová\",\n  \"Kalinová\",\n  \"Kalivodová\",\n  \"Kalousová\",\n  \"Kalousková\",\n  \"Kameníková\",\n  \"Kaňová\",\n  \"Káňová\",\n  \"Kaňková\",\n  \"Kantorová\",\n  \"Kaplanová\",\n  \"Karasová\",\n  \"Karásková\",\n  \"Karbanová\",\n  \"Karlová\",\n  \"Karlíková\",\n  \"Kasalová\",\n  \"Kašíková\",\n  \"Kašparová\",\n  \"Kašpárková\",\n  \"Kavková\",\n  \"Kazdová\",\n  \"Kindlová\",\n  \"Klečková\",\n  \"Kleinová\",\n  \"Klementová\",\n  \"Klímová\",\n  \"Klimentová\",\n  \"Klimešová\",\n  \"Kloučková\",\n  \"Kloudová\",\n  \"Knapová\",\n  \"Knotková\",\n  \"Kochová\",\n  \"Kočíová\",\n  \"Kociánová\",\n  \"Kocmanová\",\n  \"Kocourková\",\n  \"Kohoutová\",\n  \"Kohoutková\",\n  \"Koláčková\",\n  \"Kolářová\",\n  \"Kolaříková\",\n  \"Kolková\",\n  \"Kolmanová\",\n  \"Komárková\",\n  \"Komínková\",\n  \"Konečnýová\",\n  \"Koníčková\",\n  \"Kopalová\",\n  \"Kopečková\",\n  \"Kopeckýová\",\n  \"Kopečnýová\",\n  \"Kopřivová\",\n  \"Korblová\",\n  \"Kořínková\",\n  \"Kosová\",\n  \"Kosíková\",\n  \"Kosinová\",\n  \"Košťálová\",\n  \"Kostková\",\n  \"Kotasová\",\n  \"Kotková\",\n  \"Kotlárová\",\n  \"Kotrbová\",\n  \"Koubová\",\n  \"Koubková\",\n  \"Koudelová\",\n  \"Koudelková\",\n  \"Koukalová\",\n  \"Kouřilová\",\n  \"Koutnýová\",\n  \"Kováčová\",\n  \"Kovářová\",\n  \"Kovaříková\",\n  \"Kováříková\",\n  \"Kozáková\",\n  \"Kozlová\",\n  \"Krajíčková\",\n  \"Králová\",\n  \"Králíčková\",\n  \"Králíková\",\n  \"Krátkýová\",\n  \"Kratochvílová\",\n  \"Krausová\",\n  \"Krčmářová\",\n  \"Křečková\",\n  \"Krejčíová\",\n  \"Krejčíková\",\n  \"Krejčířová\",\n  \"Křenková\",\n  \"Krištofová\",\n  \"Křivánková\",\n  \"Křížová\",\n  \"Křížková\",\n  \"Kropáčková\",\n  \"Kroupová\",\n  \"Krupová\",\n  \"Krupičková\",\n  \"Krupková\",\n  \"Kubová\",\n  \"Kubánková\",\n  \"Kubátová\",\n  \"Kubcová\",\n  \"Kubelková\",\n  \"Kubešová\",\n  \"Kubicová\",\n  \"Kubíčková\",\n  \"Kubíková\",\n  \"Kubínová\",\n  \"Kubišová\",\n  \"Kučová\",\n  \"Kučerová\",\n  \"Kuchařová\",\n  \"Kuchtová\",\n  \"Kudláčková\",\n  \"Kudrnová\",\n  \"Kuklová\",\n  \"Kulhánková\",\n  \"Kulhavýová\",\n  \"Kuncová\",\n  \"Kunešová\",\n  \"Kupcová\",\n  \"Kupková\",\n  \"Kurková\",\n  \"Kužlová\",\n  \"Kvapilová\",\n  \"Kvasničková\",\n  \"Kynclová\",\n  \"Kyselová\",\n  \"Lacinová\",\n  \"Lackoová\",\n  \"Lakatošová\",\n  \"Landová\",\n  \"Langová\",\n  \"Langrová\",\n  \"Langrová\",\n  \"Látalová\",\n  \"Lavičková\",\n  \"Leová\",\n  \"Lebedová\",\n  \"Levýová\",\n  \"Líbalová\",\n  \"Linhartová\",\n  \"Lišková\",\n  \"Lorencová\",\n  \"Loudová\",\n  \"Ludvíková\",\n  \"Lukáčová\",\n  \"Lukášová\",\n  \"Lukášková\",\n  \"Lukešová\",\n  \"Macáková\",\n  \"Macková\",\n  \"Machová\",\n  \"Máchová\",\n  \"Machačová\",\n  \"Macháčová\",\n  \"Macháčková\",\n  \"Machalová\",\n  \"Machálková\",\n  \"Macurová\",\n  \"Majrová\",\n  \"Malečková\",\n  \"Málková\",\n  \"Malíková\",\n  \"Malinová\",\n  \"Malýová\",\n  \"Maňáková\",\n  \"Marečková\",\n  \"Marková\",\n  \"Marešová\",\n  \"Maříková\",\n  \"Maršálková\",\n  \"Maršíková\",\n  \"Martincová\",\n  \"Martinková\",\n  \"Martínková\",\n  \"Mašková\",\n  \"Masopustová\",\n  \"Matějíčková\",\n  \"Matějková\",\n  \"Matoušová\",\n  \"Matoušková\",\n  \"Matulová\",\n  \"Matušková\",\n  \"Matyášová\",\n  \"Matysová\",\n  \"Maxová\",\n  \"Mayrová\",\n  \"Mazánková\",\n  \"Medková\",\n  \"Melicharová\",\n  \"Menclová\",\n  \"Menšíková\",\n  \"Mertová\",\n  \"Michalová\",\n  \"Michalcová\",\n  \"Michálková\",\n  \"Michalíková\",\n  \"Michnová\",\n  \"Mičková\",\n  \"Miková\",\n  \"Míková\",\n  \"Mikešová\",\n  \"Mikoová\",\n  \"Mikulová\",\n  \"Mikulášková\",\n  \"Minářová\",\n  \"Minaříková\",\n  \"Mirgová\",\n  \"Mládková\",\n  \"Mlčochová\",\n  \"Mlejnková\",\n  \"Mojžíšová\",\n  \"Mokrýová\",\n  \"Molnárová\",\n  \"Moravcová\",\n  \"Morávková\",\n  \"Motlová\",\n  \"Motyčková\",\n  \"Moučková\",\n  \"Moudrýová\",\n  \"Mráčková\",\n  \"Mrázová\",\n  \"Mrázková\",\n  \"Mrkvičková\",\n  \"Muchová\",\n  \"Müllrová\",\n  \"Műllrová\",\n  \"Musilová\",\n  \"Mužíková\",\n  \"Myšková\",\n  \"Nagyová\",\n  \"Najmanová\",\n  \"Navrátilová\",\n  \"Nečasová\",\n  \"Nedbalová\",\n  \"Nedomová\",\n  \"Nedvědová\",\n  \"Nejedlýová\",\n  \"Němcová\",\n  \"Němečková\",\n  \"Nešporová\",\n  \"Nesvadbová\",\n  \"Neubaurová\",\n  \"Neumanová\",\n  \"Neumannová\",\n  \"Nguynová\",\n  \"Nguyen vanová\",\n  \"Nosková\",\n  \"Nováčková\",\n  \"Nováková\",\n  \"Novosadová\",\n  \"Novotnýová\",\n  \"Novýová\",\n  \"Odehnalová\",\n  \"Oláhová\",\n  \"Olivová\",\n  \"Ondrová\",\n  \"Ondráčková\",\n  \"Orságová\",\n  \"Otáhalová\",\n  \"Palečková\",\n  \"Pánková\",\n  \"Papežová\",\n  \"Pařízková\",\n  \"Pašková\",\n  \"Pátková\",\n  \"Patočková\",\n  \"Paulová\",\n  \"Pavlová\",\n  \"Pavelková\",\n  \"Pavelková\",\n  \"Pavlasová\",\n  \"Pavlicová\",\n  \"Pavlíčková\",\n  \"Pavlíková\",\n  \"Pavlůová\",\n  \"Pazderová\",\n  \"Pechová\",\n  \"Pechová\",\n  \"Pecháčková\",\n  \"Pecková\",\n  \"Pekařová\",\n  \"Pekárková\",\n  \"Pelcová\",\n  \"Pelikánová\",\n  \"Peřinová\",\n  \"Pernicová\",\n  \"Peroutková\",\n  \"Pešková\",\n  \"Pešková\",\n  \"Peštová\",\n  \"Peterková\",\n  \"Petrová\",\n  \"Petráková\",\n  \"Petrášová\",\n  \"Petříčková\",\n  \"Petříková\",\n  \"Petrůová\",\n  \"Phamová\",\n  \"Píchová\",\n  \"Pilařová\",\n  \"Pilátová\",\n  \"Píšová\",\n  \"Pivoňková\",\n  \"Plačková\",\n  \"Plachýová\",\n  \"Plšková\",\n  \"Pluhařová\",\n  \"Podzimková\",\n  \"Pohlová\",\n  \"Pokornýová\",\n  \"Poláčková\",\n  \"Poláchová\",\n  \"Poláková\",\n  \"Polanskýová\",\n  \"Polášková\",\n  \"Polívková\",\n  \"Popelková\",\n  \"Pospíchalová\",\n  \"Pospíšilová\",\n  \"Potůčková\",\n  \"Pourová\",\n  \"Prachařová\",\n  \"Prášková\",\n  \"Pražáková\",\n  \"Prchalová\",\n  \"Přibylová\",\n  \"Příhodová\",\n  \"Přikrylová\",\n  \"Procházková\",\n  \"Prokešová\",\n  \"Prokopová\",\n  \"Prošková\",\n  \"Provazníková\",\n  \"Průchová\",\n  \"Průšová\",\n  \"Pšeničková\",\n  \"Ptáčková\",\n  \"Rácová\",\n  \"Radová\",\n  \"Raková\",\n  \"Rambousková\",\n  \"Rašková\",\n  \"Ratajová\",\n  \"řeháčková\",\n  \"řeháková\",\n  \"řehořová\",\n  \"Remešová\",\n  \"řezáčová\",\n  \"Rezková\",\n  \"řezníčková\",\n  \"Richtrová\",\n  \"Richtrová\",\n  \"říhová\",\n  \"Roubalová\",\n  \"Rousová\",\n  \"Rozsypalová\",\n  \"Rudolfová\",\n  \"Růžková\",\n  \"Růžičková\",\n  \"Rybová\",\n  \"Rybářová\",\n  \"Rýdlová\",\n  \"Ryšavýová\",\n  \"Sadílková\",\n  \"šafářová\",\n  \"šafaříková\",\n  \"šafránková\",\n  \"šálková\",\n  \"Samková\",\n  \"šandová\",\n  \"šašková\",\n  \"Schejbalová\",\n  \"Schmidtová\",\n  \"Schneidrová\",\n  \"Schwarzová\",\n  \"šebková\",\n  \"šebelová\",\n  \"šebestová\",\n  \"šedová\",\n  \"šedivýová\",\n  \"Sedláčková\",\n  \"Sedláková\",\n  \"Sedlářová\",\n  \"Sehnalová\",\n  \"Seidlová\",\n  \"Seifertová\",\n  \"Sekaninová\",\n  \"Semerádová\",\n  \"šenková\",\n  \"šestáková\",\n  \"ševčíková\",\n  \"Severová\",\n  \"Sikorová\",\n  \"šilhavýová\",\n  \"šímová\",\n  \"šimáčková\",\n  \"šimáková\",\n  \"šimánková\",\n  \"šimčíková\",\n  \"šimečková\",\n  \"šimková\",\n  \"šimonová\",\n  \"šimůnková\",\n  \"šindelářová\",\n  \"šindlrová\",\n  \"šípová\",\n  \"šípková\",\n  \"šírová\",\n  \"širokýová\",\n  \"šišková\",\n  \"Siváková\",\n  \"Skáclová\",\n  \"Skalová\",\n  \"Skálová\",\n  \"Skalickýová\",\n  \"Sklenářová\",\n  \"škodová\",\n  \"Skopalová\",\n  \"Skořepová\",\n  \"škrabalová\",\n  \"Skřivánková\",\n  \"Slabýová\",\n  \"Sládková\",\n  \"Sladkýová\",\n  \"Slámová\",\n  \"Slaninová\",\n  \"Slavíčková\",\n  \"Slavíková\",\n  \"šlechtová\",\n  \"Slezáková\",\n  \"Slováčková\",\n  \"Slováková\",\n  \"Sluková\",\n  \"Smejkalová\",\n  \"šmejkalová\",\n  \"Smékalová\",\n  \"šmerdová\",\n  \"Smetanová\",\n  \"šmídová\",\n  \"Smolová\",\n  \"Smolíková\",\n  \"Smolková\",\n  \"Smrčková\",\n  \"Smržová\",\n  \"Smutnýová\",\n  \"šnajdrová\",\n  \"Sobková\",\n  \"Sobotková\",\n  \"Sochorová\",\n  \"Sojková\",\n  \"Sokolová\",\n  \"šolcová\",\n  \"Sommrová\",\n  \"Součková\",\n  \"Soukupová\",\n  \"Sovová\",\n  \"špačková\",\n  \"Spáčilová\",\n  \"špičková\",\n  \"šplíchalová\",\n  \"Spurnýová\",\n  \"šrámková\",\n  \"Srbová\",\n  \"Staněková\",\n  \"Stárková\",\n  \"Starýová\",\n  \"šťastnýová\",\n  \"štefanová\",\n  \"štefková\",\n  \"šteflová\",\n  \"Stehlíková\",\n  \"Steinrová\",\n  \"Stejskalová\",\n  \"štěpánová\",\n  \"štěpánková\",\n  \"štěrbová\",\n  \"Stiborová\",\n  \"Stoklasová\",\n  \"Straková\",\n  \"Stránskýová\",\n  \"Strejčková\",\n  \"Strnadová\",\n  \"Strouhalová\",\n  \"Stuchlíková\",\n  \"Studenýová\",\n  \"Studničková\",\n  \"Stupková\",\n  \"šubrtová\",\n  \"Suchánková\",\n  \"Suchomlová\",\n  \"Suchýová\",\n  \"Suková\",\n  \"šulcová\",\n  \"šustrová\",\n  \"švábová\",\n  \"Svačinová\",\n  \"švandová\",\n  \"švarcová\",\n  \"Svatoňová\",\n  \"Svatošová\",\n  \"švcová\",\n  \"švehlová\",\n  \"švejdová\",\n  \"švestková\",\n  \"Světlíková\",\n  \"Svitáková\",\n  \"Svobodová\",\n  \"Svozilová\",\n  \"Sýkorová\",\n  \"Synková\",\n  \"Syrovýová\",\n  \"Táborskýová\",\n  \"Tancošová\",\n  \"Teplýová\",\n  \"Tesařová\",\n  \"Tichýová\",\n  \"Tomanová\",\n  \"Tománková\",\n  \"Tomášová\",\n  \"Tomášková\",\n  \"Tomečková\",\n  \"Tomková\",\n  \"Tomešová\",\n  \"Tóthová\",\n  \"Tranová\",\n  \"Trávníčková\",\n  \"Trčková\",\n  \"Třísková\",\n  \"Trnková\",\n  \"Trojanová\",\n  \"Truhlářová\",\n  \"Tučková\",\n  \"Tůmová\",\n  \"Turečková\",\n  \"Turková\",\n  \"Tvrdíková\",\n  \"Tvrdýová\",\n  \"Uhrová\",\n  \"Uhlířová\",\n  \"Ulrichová\",\n  \"Urbanová\",\n  \"Urbancová\",\n  \"Urbánková\",\n  \"Vacková\",\n  \"Váchová\",\n  \"Václavková\",\n  \"Václavíková\",\n  \"Vaculíková\",\n  \"Vágnrová\",\n  \"Valová\",\n  \"Valášková\",\n  \"Válková\",\n  \"Valentová\",\n  \"Valešová\",\n  \"Váňová\",\n  \"Vančurová\",\n  \"Vaněčková\",\n  \"Vaněková\",\n  \"Vaníčková\",\n  \"Vargová\",\n  \"Vašáková\",\n  \"Vašková\",\n  \"Vašíčková\",\n  \"Vávrová\",\n  \"Vavříková\",\n  \"Večeřová\",\n  \"Vejvodová\",\n  \"Vernrová\",\n  \"Veselýová\",\n  \"Veverková\",\n  \"Víchová\",\n  \"Vilímková\",\n  \"Vinšová\",\n  \"Víšková\",\n  \"Vítová\",\n  \"Vitásková\",\n  \"Vítková\",\n  \"Vlachová\",\n  \"Vlasáková\",\n  \"Vlčková\",\n  \"Vlková\",\n  \"Vobořilová\",\n  \"Vodáková\",\n  \"Vodičková\",\n  \"Vodrážková\",\n  \"Vojáčková\",\n  \"Vojtová\",\n  \"Vojtěchová\",\n  \"Vojtková\",\n  \"Vojtíšková\",\n  \"Vokounová\",\n  \"Volková\",\n  \"Volfová\",\n  \"Volnýová\",\n  \"Vondrová\",\n  \"Vondráčková\",\n  \"Vondráková\",\n  \"Voráčková\",\n  \"Vorlová\",\n  \"Voříšková\",\n  \"Vorlíčková\",\n  \"Votavová\",\n  \"Votrubová\",\n  \"Vrabcová\",\n  \"Vránová\",\n  \"Vrbová\",\n  \"Vrzalová\",\n  \"Vybíralová\",\n  \"Vydrová\",\n  \"Vymazalová\",\n  \"Vyskočilová\",\n  \"Vysloužilová\",\n  \"Wagnrová\",\n  \"Waltrová\",\n  \"Webrová\",\n  \"Weissová\",\n  \"Winklrová\",\n  \"Wolfová\",\n  \"Zábranskýová\",\n  \"žáčková\",\n  \"Zachová\",\n  \"Zahrádková\",\n  \"Zahradníková\",\n  \"Zajícová\",\n  \"Zajíčková\",\n  \"žáková\",\n  \"Zálešáková\",\n  \"Zámečníková\",\n  \"Zapletalová\",\n  \"Zárubová\",\n  \"Zatloukalová\",\n  \"Zavadilová\",\n  \"Zavřlová\",\n  \"Zbořilová\",\n  \"žďárskýová\",\n  \"Zdražilová\",\n  \"Zedníková\",\n  \"Zelenková\",\n  \"Zelenýová\",\n  \"Zelinková\",\n  \"Zemanová\",\n  \"Zemánková\",\n  \"žemličková\",\n  \"Zezulová\",\n  \"žídková\",\n  \"žigová\",\n  \"Zíková\",\n  \"Zikmundová\",\n  \"Zimová\",\n  \"žižková\",\n  \"Zlámalová\",\n  \"Zoubková\",\n  \"Zouharová\",\n  \"žůrková\",\n  \"Zvěřinová\",\n];\n\n},{}],88:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.male_first_name = require(\"./male_first_name\");\nname.female_first_name = require(\"./female_first_name\");\nname.male_last_name = require(\"./male_last_name\");\nname.female_last_name = require(\"./female_last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\nname.title = require(\"./title\");\nname.name = require(\"./name\");\n\n},{\"./female_first_name\":86,\"./female_last_name\":87,\"./male_first_name\":89,\"./male_last_name\":90,\"./name\":91,\"./prefix\":92,\"./suffix\":93,\"./title\":94}],89:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abadon\",\n  \"Abdon\",\n  \"Ábel\",\n  \"Abelard\",\n  \"Abraham\",\n  \"Abrahám\",\n  \"Absolon\",\n  \"Absolón\",\n  \"Adalbert\",\n  \"Adam\",\n  \"Adin\",\n  \"Adolf\",\n  \"Adrian\",\n  \"Adrián\",\n  \"Agaton\",\n  \"Achil\",\n  \"Achiles\",\n  \"Alan\",\n  \"Alban\",\n  \"Albert\",\n  \"Albín\",\n  \"Albrecht\",\n  \"Aldo\",\n  \"Alen\",\n  \"Aleš\",\n  \"Alexandr\",\n  \"Alexej\",\n  \"Alfons\",\n  \"Alfréd\",\n  \"Alois\",\n  \"Alojz\",\n  \"Alva\",\n  \"Alvar\",\n  \"Alvin\",\n  \"Amadeus\",\n  \"Amand\",\n  \"Amát\",\n  \"Ambrož\",\n  \"Amos\",\n  \"Ámos\",\n  \"Anastáz\",\n  \"Anatol\",\n  \"Anděl\",\n  \"Andělín\",\n  \"Andrej\",\n  \"Anselm\",\n  \"Antal\",\n  \"Antonín\",\n  \"Aram\",\n  \"Ariel\",\n  \"Aristid\",\n  \"Arkád\",\n  \"Armand\",\n  \"Armin\",\n  \"Arne\",\n  \"Arnold\",\n  \"Arnošt\",\n  \"Áron\",\n  \"Árón\",\n  \"Arpád\",\n  \"Arsen\",\n  \"Artur\",\n  \"Artuš\",\n  \"Arzen\",\n  \"Atanas\",\n  \"Atanáš\",\n  \"Atila\",\n  \"August\",\n  \"Augustin\",\n  \"Augustýn\",\n  \"Aurel\",\n  \"Aurelián\",\n  \"Axel\",\n  \"Baltazar\",\n  \"Barnabáš\",\n  \"Bartoloměj\",\n  \"Basil\",\n  \"Bazil\",\n  \"Beatus\",\n  \"Bedřich\",\n  \"Benedikt\",\n  \"Benjamin\",\n  \"Benjamín\",\n  \"Bernard\",\n  \"Bertold\",\n  \"Bertram\",\n  \"Bivoj\",\n  \"Blahomil\",\n  \"Blahomír\",\n  \"Blahoslav\",\n  \"Blažej\",\n  \"Bohdan\",\n  \"Bohuchval\",\n  \"Bohumil\",\n  \"Bohumír\",\n  \"Bohun\",\n  \"Bohuslav\",\n  \"Bohuš\",\n  \"Bojan\",\n  \"Bolemír\",\n  \"Boleslav\",\n  \"Bonifác\",\n  \"Borek\",\n  \"Boris\",\n  \"Borislav\",\n  \"Bořek\",\n  \"Bořislav\",\n  \"Bořivoj\",\n  \"Božetěch\",\n  \"Božidar\",\n  \"Božislav\",\n  \"Branimír\",\n  \"Branislav\",\n  \"Bratislav\",\n  \"Bret\",\n  \"Brian\",\n  \"Brit\",\n  \"Bronislav\",\n  \"Bruno\",\n  \"Břetislav\",\n  \"Budimír\",\n  \"Budislav\",\n  \"Budivoj\",\n  \"Cecil\",\n  \"Cedrik\",\n  \"Celestin\",\n  \"Celestýn\",\n  \"César\",\n  \"Cézar\",\n  \"Ctibor\",\n  \"Ctirad\",\n  \"Ctislav\",\n  \"Cyprián\",\n  \"Cyril\",\n  \"Čeněk\",\n  \"Čestmír\",\n  \"Čistoslav\",\n  \"Dag\",\n  \"Dalibor\",\n  \"Dalimil\",\n  \"Dalimír\",\n  \"Damián\",\n  \"Dan\",\n  \"Daniel\",\n  \"Darek\",\n  \"Darius\",\n  \"David\",\n  \"Denis\",\n  \"Děpold\",\n  \"Dětmar\",\n  \"Dětřich\",\n  \"Dezider\",\n  \"Dimitrij\",\n  \"Dino\",\n  \"Dionýz\",\n  \"Dionýzos\",\n  \"Diviš\",\n  \"Dluhoš\",\n  \"Dobromil\",\n  \"Dobromír\",\n  \"Dobroslav\",\n  \"Dominik\",\n  \"Donald\",\n  \"Donát\",\n  \"Dorian\",\n  \"Dorián\",\n  \"Drahomil\",\n  \"Drahomír\",\n  \"Drahoň\",\n  \"Drahoslav\",\n  \"Drahoš\",\n  \"Drahotín\",\n  \"Drahutin\",\n  \"Dušan\",\n  \"Edgar\",\n  \"Edmond\",\n  \"Edmund\",\n  \"Eduard\",\n  \"Edvard\",\n  \"Edvin\",\n  \"Edvín\",\n  \"Egmont\",\n  \"Egon\",\n  \"Eliáš\",\n  \"Elizej\",\n  \"Elizeus\",\n  \"Elmar\",\n  \"Elvis\",\n  \"Emanuel\",\n  \"Emanuel\",\n  \"Emerich\",\n  \"Emil\",\n  \"Emilián\",\n  \"Engelbert\",\n  \"Erazim\",\n  \"Erazmus\",\n  \"Erhard\",\n  \"Erich\",\n  \"Erik\",\n  \"Ernest\",\n  \"Ernst\",\n  \"Ervín\",\n  \"Eugen\",\n  \"Eusebius\",\n  \"Evald\",\n  \"Evan\",\n  \"Evarist\",\n  \"Evžen\",\n  \"Ezechiel\",\n  \"Ezra\",\n  \"Fabián\",\n  \"Faust\",\n  \"Faustin\",\n  \"Faustýn\",\n  \"Fedor\",\n  \"Felicián\",\n  \"Felix\",\n  \"Ferdinand\",\n  \"Fidel\",\n  \"Fidelius\",\n  \"Filemon\",\n  \"Filibert\",\n  \"Filip\",\n  \"Filomen\",\n  \"Flavián\",\n  \"Flavius\",\n  \"Florentin\",\n  \"Florentýn\",\n  \"Florián\",\n  \"Fortunát\",\n  \"Fráňa\",\n  \"Franc\",\n  \"František\",\n  \"Fridolín\",\n  \"Gabin\",\n  \"Gabriel\",\n  \"Gál\",\n  \"Garik\",\n  \"Gaston\",\n  \"Gedeon\",\n  \"Gejza\",\n  \"Genadij\",\n  \"Gerald\",\n  \"Gerard\",\n  \"Gerazim\",\n  \"Gerhard\",\n  \"Géza\",\n  \"Gilbert\",\n  \"Gleb\",\n  \"Glen\",\n  \"Gorazd\",\n  \"Gordon\",\n  \"Gothard\",\n  \"Gracián\",\n  \"Grant\",\n  \"Gunter\",\n  \"Gűnter\",\n  \"Gustav\",\n  \"Hanuš\",\n  \"Harald\",\n  \"Harold\",\n  \"Haštal\",\n  \"Havel\",\n  \"Helmut\",\n  \"Herbert\",\n  \"Herman\",\n  \"Heřman\",\n  \"Hilar\",\n  \"Hilarius\",\n  \"Hjalmar\",\n  \"Homér\",\n  \"Honor\",\n  \"Honorius\",\n  \"Horác\",\n  \"Horst\",\n  \"Horymír\",\n  \"Hostimil\",\n  \"Hostimír\",\n  \"Hostislav\",\n  \"Hostivít\",\n  \"Hovard\",\n  \"Hubert\",\n  \"Hugo\",\n  \"Hvězdoslav\",\n  \"Hyacint\",\n  \"Hynek\",\n  \"Hypolit\",\n  \"Chrabroš\",\n  \"Chraniboj\",\n  \"Chranibor\",\n  \"Chranislav\",\n  \"Chrudoš\",\n  \"Chval\",\n  \"Ignác\",\n  \"Ignát\",\n  \"Igor\",\n  \"Ilja\",\n  \"Inocenc\",\n  \"Irenej\",\n  \"Ireneus\",\n  \"Irvin\",\n  \"Isidor\",\n  \"Ivan\",\n  \"Ivar\",\n  \"Ivo\",\n  \"Ivor\",\n  \"Izaiáš\",\n  \"Izák\",\n  \"Izidor\",\n  \"Izmael\",\n  \"Jacek\",\n  \"Jáchym\",\n  \"Jakub\",\n  \"Jan\",\n  \"Jarmil\",\n  \"Jarolím\",\n  \"Jaromil\",\n  \"Jaromír\",\n  \"Jaroslav\",\n  \"Jason\",\n  \"Jasoň\",\n  \"Jeremiáš\",\n  \"Jeroným\",\n  \"Jiljí\",\n  \"Jimram\",\n  \"Jindřich\",\n  \"Jiří\",\n  \"Job\",\n  \"Joel\",\n  \"Jonáš\",\n  \"Jonatan\",\n  \"Jonathan\",\n  \"Jordan\",\n  \"Josef\",\n  \"Jošt\",\n  \"Jozef\",\n  \"Jozue\",\n  \"Juda\",\n  \"Julián\",\n  \"Julius\",\n  \"Justin\",\n  \"Justýn\",\n  \"Kajetán\",\n  \"Kamil\",\n  \"Karel\",\n  \"Kasián\",\n  \"Kastor\",\n  \"Kašpar\",\n  \"Kazimír\",\n  \"Kilián\",\n  \"Kim\",\n  \"Klaudián\",\n  \"Klaudius\",\n  \"Klement\",\n  \"Kliment\",\n  \"Knut\",\n  \"Koloman\",\n  \"Kolombín\",\n  \"Kolumbán\",\n  \"Kolumbín\",\n  \"Konrád\",\n  \"Konstantin\",\n  \"Konstantýn\",\n  \"Kornel\",\n  \"Kornelius\",\n  \"Kosma\",\n  \"Kosmas\",\n  \"Krasomil\",\n  \"Krasoslav\",\n  \"Kristián\",\n  \"Kryšpín\",\n  \"Kryštof\",\n  \"Křesomysl\",\n  \"Křišťan\",\n  \"Kurt\",\n  \"Květoň\",\n  \"Květoslav\",\n  \"Květoš\",\n  \"Kvido\",\n  \"Ladislav\",\n  \"Lambert\",\n  \"Lars\",\n  \"Laurenc\",\n  \"Lazar\",\n  \"Leander\",\n  \"Leandr\",\n  \"Leo\",\n  \"Leodegar\",\n  \"Leon\",\n  \"Leonard\",\n  \"Leonid\",\n  \"Leontýn\",\n  \"Leopold\",\n  \"Leoš\",\n  \"Lešek\",\n  \"Lev\",\n  \"Libor\",\n  \"Liboslav\",\n  \"Lionel\",\n  \"Livius\",\n  \"Lorenc\",\n  \"Lotar\",\n  \"Lothar\",\n  \"Lubomír\",\n  \"Lubor\",\n  \"Luboslav\",\n  \"Luboš\",\n  \"Lucián\",\n  \"Lucius\",\n  \"Luděk\",\n  \"Ludivoj\",\n  \"Ludomír\",\n  \"Ludoslav\",\n  \"Ludvík\",\n  \"Lukáš\",\n  \"Lukrecius\",\n  \"Lumír\",\n  \"Lutibor\",\n  \"Lutobor\",\n  \"Magnus\",\n  \"Makar\",\n  \"Manfred\",\n  \"Manfréd\",\n  \"Mansvet\",\n  \"Manuel\",\n  \"Marcel\",\n  \"Marek\",\n  \"Marian\",\n  \"Marián\",\n  \"Marin\",\n  \"Mario\",\n  \"Marius\",\n  \"Martin\",\n  \"Matěj\",\n  \"Matouš\",\n  \"Matyáš\",\n  \"Max\",\n  \"Maxim\",\n  \"Maximilián\",\n  \"Maxmilián\",\n  \"Mečislav\",\n  \"Medard\",\n  \"Melichar\",\n  \"Merlin\",\n  \"Mervin\",\n  \"Metod\",\n  \"Metoděj\",\n  \"Michael\",\n  \"Michal\",\n  \"Mikoláš\",\n  \"Mikuláš\",\n  \"Milan\",\n  \"Milíč\",\n  \"Milík\",\n  \"Milivoj\",\n  \"Miloň\",\n  \"Milorad\",\n  \"Miloslav\",\n  \"Miloš\",\n  \"Milota\",\n  \"Milouš\",\n  \"Milovan\",\n  \"Milovín\",\n  \"Milutín\",\n  \"Mirek\",\n  \"Mirko\",\n  \"Miromil\",\n  \"Miron\",\n  \"Miroslav\",\n  \"Mirtil\",\n  \"Mlad\",\n  \"Mladen\",\n  \"Mnata\",\n  \"Mnislav\",\n  \"Modest\",\n  \"Mojmír\",\n  \"Mojžíš\",\n  \"Morgan\",\n  \"Moric\",\n  \"Moris\",\n  \"Mořic\",\n  \"Mstislav\",\n  \"Myron\",\n  \"Myrtil\",\n  \"Napoleon\",\n  \"Narcis\",\n  \"Natan\",\n  \"Natanael\",\n  \"Nathan\",\n  \"Nathanael\",\n  \"Něhoslav\",\n  \"Neklan\",\n  \"Nepomuk\",\n  \"Nezamysl\",\n  \"Nikita\",\n  \"Nikodém\",\n  \"Nikola\",\n  \"Nikolas\",\n  \"Norbert\",\n  \"Norman\",\n  \"Odolen\",\n  \"Odon\",\n  \"Oktavián\",\n  \"Oktavius\",\n  \"Olaf\",\n  \"Olbram\",\n  \"Oldřich\",\n  \"Oleg\",\n  \"Oliver\",\n  \"Omar\",\n  \"Ondřej\",\n  \"Orest\",\n  \"Oskar\",\n  \"Osvald\",\n  \"Ota\",\n  \"Otakar\",\n  \"Otmar\",\n  \"Oto\",\n  \"Otokar\",\n  \"Otomar\",\n  \"Ovidius\",\n  \"Palmiro\",\n  \"Pankrác\",\n  \"Pantaleon\",\n  \"Paris\",\n  \"Parsival\",\n  \"Paskal\",\n  \"Patrik\",\n  \"Pavel\",\n  \"Pavlín\",\n  \"Pelhřim\",\n  \"Perikles\",\n  \"Petr\",\n  \"Petronius\",\n  \"Pius\",\n  \"Platon\",\n  \"Platón\",\n  \"Polykarp\",\n  \"Pravdomil\",\n  \"Pravomil\",\n  \"Prokop\",\n  \"Prosper\",\n  \"Přemysl\",\n  \"Přibyslav\",\n  \"Radan\",\n  \"Radegast\",\n  \"Radek\",\n  \"Radhost\",\n  \"Radim\",\n  \"Radimír\",\n  \"Radislav\",\n  \"Radivoj\",\n  \"Radko\",\n  \"Radmil\",\n  \"Radomil\",\n  \"Radomír\",\n  \"Radoslav\",\n  \"Radoš\",\n  \"Radovan\",\n  \"Radúz\",\n  \"Radvan\",\n  \"Rafael\",\n  \"Raimund\",\n  \"Rainald\",\n  \"Rainer\",\n  \"Rainhard\",\n  \"Rainold\",\n  \"Rajko\",\n  \"Ralf\",\n  \"Ramon\",\n  \"Randolf\",\n  \"Ranek\",\n  \"Ranko\",\n  \"Rastislav\",\n  \"Ratibor\",\n  \"Ratmír\",\n  \"Redmond\",\n  \"Reginald\",\n  \"Remig\",\n  \"Remus\",\n  \"Renát\",\n  \"René\",\n  \"Richard\",\n  \"Robert\",\n  \"Robin\",\n  \"Robinson\",\n  \"Rodan\",\n  \"Roderik\",\n  \"Rodrigo\",\n  \"Roger\",\n  \"Roch\",\n  \"Roland\",\n  \"Rolf\",\n  \"Roman\",\n  \"Romeo\",\n  \"Romuald\",\n  \"Romul\",\n  \"Romulus\",\n  \"Ronald\",\n  \"Rostislav\",\n  \"Ruben\",\n  \"Rudolf\",\n  \"Rufus\",\n  \"Rupert\",\n  \"Ruprecht\",\n  \"Ruslan\",\n  \"Řehoř\",\n  \"Sába\",\n  \"Sámo\",\n  \"Samson\",\n  \"Samuel\",\n  \"Saturnin\",\n  \"Saul\",\n  \"Sáva\",\n  \"Sebastian\",\n  \"Sebastián\",\n  \"Sebestian\",\n  \"Sedrik\",\n  \"Serafín\",\n  \"Serenus\",\n  \"Sergej\",\n  \"Servác\",\n  \"Severín\",\n  \"Sidon\",\n  \"Sigfríd\",\n  \"Silvan\",\n  \"Silván\",\n  \"Silvestr\",\n  \"Silvius\",\n  \"Simeon\",\n  \"Simon\",\n  \"Sinkler\",\n  \"Sixt\",\n  \"Sixtus\",\n  \"Slávek\",\n  \"Slaviboj\",\n  \"Slavibor\",\n  \"Slavoboj\",\n  \"Slavoj\",\n  \"Slavomil\",\n  \"Slavomír\",\n  \"Smil\",\n  \"Soběslav\",\n  \"Sokrat\",\n  \"Soter\",\n  \"Spytihněv\",\n  \"Stanimír\",\n  \"Stanislav\",\n  \"Stojan\",\n  \"Stojmír\",\n  \"Svatoboj\",\n  \"Svatobor\",\n  \"Svatomír\",\n  \"Svatopluk\",\n  \"Svatoslav\",\n  \"Sven\",\n  \"Svetozar\",\n  \"Šalamoun\",\n  \"Šalomoun\",\n  \"Šavel\",\n  \"Šebastián\",\n  \"Šimon\",\n  \"Šťasta\",\n  \"Štefan\",\n  \"Štěpán\",\n  \"Tadeáš\",\n  \"Tankred\",\n  \"Taras\",\n  \"Teobald\",\n  \"Teodor\",\n  \"Teodorik\",\n  \"Teodoz\",\n  \"Teofan\",\n  \"Teofil\",\n  \"Terenc\",\n  \"Terencius\",\n  \"Theobald\",\n  \"Theodor\",\n  \"Theodorik\",\n  \"Theofan\",\n  \"Theofil\",\n  \"Tiber\",\n  \"Tiberius\",\n  \"Tibor\",\n  \"Tiburcius\",\n  \"Tichomil\",\n  \"Tichomír\",\n  \"Tichon\",\n  \"Timon\",\n  \"Timotej\",\n  \"Timoteus\",\n  \"Timur\",\n  \"Titus\",\n  \"Tobiáš\",\n  \"Tomáš\",\n  \"Tomislav\",\n  \"Tor\",\n  \"Torkvát\",\n  \"Torsten\",\n  \"Tristan\",\n  \"Udo\",\n  \"Ulrich\",\n  \"Upton\",\n  \"Urban\",\n  \"Uve\",\n  \"Václav\",\n  \"Vadim\",\n  \"Valdemar\",\n  \"Valentin\",\n  \"Valentýn\",\n  \"Valerián\",\n  \"Valter\",\n  \"Valtr\",\n  \"Vasil\",\n  \"Vavřinec\",\n  \"Veleslav\",\n  \"Velimír\",\n  \"Velislav\",\n  \"Věnceslav\",\n  \"Vendelín\",\n  \"Věnek\",\n  \"Verner\",\n  \"Věroslav\",\n  \"Vidor\",\n  \"Viktor\",\n  \"Viktorin\",\n  \"Viktorín\",\n  \"Vilém\",\n  \"Vilibald\",\n  \"Vilmar\",\n  \"Vincenc\",\n  \"Virgil\",\n  \"Virgin\",\n  \"Vít\",\n  \"Vítězslav\",\n  \"Vitold\",\n  \"Vítoslav\",\n  \"Vivian\",\n  \"Vladan\",\n  \"Vladimír\",\n  \"Vladislav\",\n  \"Vladivoj\",\n  \"Vlastimil\",\n  \"Vlastimír\",\n  \"Vlastislav\",\n  \"Vlk\",\n  \"Vojen\",\n  \"Vojmil\",\n  \"Vojmír\",\n  \"Vojslav\",\n  \"Vojtěch\",\n  \"Vok\",\n  \"Volfgang\",\n  \"Vratislav\",\n  \"Vsevolod\",\n  \"Všeboj\",\n  \"Všebor\",\n  \"Všerad\",\n  \"Všeslav\",\n  \"Xaver\",\n  \"Xaverius\",\n  \"Záboj\",\n  \"Zachar\",\n  \"Zachariáš\",\n  \"Záviš\",\n  \"Zbislav\",\n  \"Zbyhněv\",\n  \"Zbyněk\",\n  \"Zbyslav\",\n  \"Zbyšek\",\n  \"Zdeněk\",\n  \"Zderad\",\n  \"Zdeslav\",\n  \"Zdík\",\n  \"Zdirad\",\n  \"Zdislav\",\n  \"Zeno\",\n  \"Zenon\",\n  \"Zikmund\",\n  \"Zlatan\",\n  \"Zlatko\",\n  \"Zlatomír\",\n  \"Zoltán\",\n  \"Zoran\",\n  \"Zoroslav\",\n  \"Zosim\",\n  \"Zvonimír\",\n  \"Žarko\",\n  \"Ždan\",\n  \"Želibor\",\n  \"Želimír\",\n  \"Želislav\",\n  \"Želmír\",\n  \"Žitomír\",\n  \"Žitoslav\",\n  \"Živan\",\n];\n\n},{}],90:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adam\",\n  \"Adamec\",\n  \"Adámek\",\n  \"Albrecht\",\n  \"Ambrož\",\n  \"Anděl\",\n  \"Andrle\",\n  \"Antoš\",\n  \"Bajer\",\n  \"Baláž\",\n  \"Balcar\",\n  \"Balog\",\n  \"Baloun\",\n  \"Barák\",\n  \"Baran\",\n  \"Bareš\",\n  \"Bárta\",\n  \"Barták\",\n  \"Bartoň\",\n  \"Bartoš\",\n  \"Bartošek\",\n  \"Bartůněk\",\n  \"Bašta\",\n  \"Bauer\",\n  \"Bayer\",\n  \"Bažant\",\n  \"Bečka\",\n  \"Bečvář\",\n  \"Bednář\",\n  \"Bednařík\",\n  \"Bělohlávek\",\n  \"Benda\",\n  \"Beneš\",\n  \"Beran\",\n  \"Beránek\",\n  \"Berger\",\n  \"Berka\",\n  \"Berky\",\n  \"Bernard\",\n  \"Bezděk\",\n  \"Bílek\",\n  \"Bílý\",\n  \"Bína\",\n  \"Bittner\",\n  \"Blaha\",\n  \"Bláha\",\n  \"Blažek\",\n  \"Blecha\",\n  \"Bobek\",\n  \"Boček\",\n  \"Boháč\",\n  \"Boháček\",\n  \"Böhm\",\n  \"Borovička\",\n  \"Bouček\",\n  \"Bouda\",\n  \"Bouška\",\n  \"Brabec\",\n  \"Brabenec\",\n  \"Brada\",\n  \"Bradáč\",\n  \"Braun\",\n  \"Brázda\",\n  \"Brázdil\",\n  \"Brejcha\",\n  \"Březina\",\n  \"Bříza\",\n  \"Brož\",\n  \"Brožek\",\n  \"Brychta\",\n  \"Bubeník\",\n  \"Buček\",\n  \"Buchta\",\n  \"Burda\",\n  \"Bureš\",\n  \"Burian\",\n  \"Buriánek\",\n  \"Byrtus\",\n  \"čada\",\n  \"Caha\",\n  \"čáp\",\n  \"čapek\",\n  \"čech\",\n  \"čejka\",\n  \"čermák\",\n  \"černík\",\n  \"černoch\",\n  \"černohorský\",\n  \"černý\",\n  \"červeňák\",\n  \"červenka\",\n  \"červený\",\n  \"červinka\",\n  \"Chaloupka\",\n  \"Chalupa\",\n  \"Charvát\",\n  \"Chládek\",\n  \"Chlup\",\n  \"Chmelař\",\n  \"Chmelík\",\n  \"Chovanec\",\n  \"Chromý\",\n  \"Chudoba\",\n  \"Chvátal\",\n  \"Chvojka\",\n  \"Chytil\",\n  \"Cibulka\",\n  \"čihák\",\n  \"Cihlář\",\n  \"Císař\",\n  \"čížek\",\n  \"čonka\",\n  \"Coufal\",\n  \"čurda\",\n  \"Daněk\",\n  \"Daniel\",\n  \"Daniš\",\n  \"David\",\n  \"Dědek\",\n  \"Demeter\",\n  \"Dittrich\",\n  \"Diviš\",\n  \"Dlouhý\",\n  \"Dobeš\",\n  \"Dobiáš\",\n  \"Dobrovolný\",\n  \"Dočekal\",\n  \"Dočkal\",\n  \"Dohnal\",\n  \"Dokoupil\",\n  \"Doleček\",\n  \"Dolejš\",\n  \"Dolejší\",\n  \"Doležal\",\n  \"Doležel\",\n  \"Doskočil\",\n  \"Dostál\",\n  \"Doubek\",\n  \"Doubrava\",\n  \"Douša\",\n  \"Drábek\",\n  \"Drozd\",\n  \"Dubský\",\n  \"Duchoň\",\n  \"Duda\",\n  \"Dudek\",\n  \"Dufek\",\n  \"Dunka\",\n  \"Dušek\",\n  \"Dvořáček\",\n  \"Dvořák\",\n  \"Dvorský\",\n  \"Eliáš\",\n  \"Erben\",\n  \"Fabián\",\n  \"Fanta\",\n  \"Farkaš\",\n  \"Fejfar\",\n  \"Fencl\",\n  \"Ferenc\",\n  \"Ferko\",\n  \"Fiala\",\n  \"Fiedler\",\n  \"Filip\",\n  \"Fischer\",\n  \"Fišer\",\n  \"Florián\",\n  \"Fojtík\",\n  \"Foltýn\",\n  \"Forman\",\n  \"Formánek\",\n  \"Fořt\",\n  \"Fousek\",\n  \"Franc\",\n  \"Franěk\",\n  \"Frank\",\n  \"Fridrich\",\n  \"Frydrych\",\n  \"Fuchs\",\n  \"Fučík\",\n  \"Fuksa\",\n  \"Gábor\",\n  \"Gabriel\",\n  \"Gajdoš\",\n  \"Gaži\",\n  \"Gottwald\",\n  \"Gregor\",\n  \"Gruber\",\n  \"Grundza\",\n  \"Grygar\",\n  \"Hájek\",\n  \"Hajný\",\n  \"Hála\",\n  \"Hampl\",\n  \"Hána\",\n  \"Hanáček\",\n  \"Hanák\",\n  \"Hanousek\",\n  \"Hanus\",\n  \"Hanuš\",\n  \"Hanzal\",\n  \"Hanzl\",\n  \"Hanzlík\",\n  \"Hartman\",\n  \"Hašek\",\n  \"Havel\",\n  \"Havelka\",\n  \"Havlíček\",\n  \"Havlík\",\n  \"Havránek\",\n  \"Heczko\",\n  \"Heger\",\n  \"Hejda\",\n  \"Hejduk\",\n  \"Hejl\",\n  \"Hejna\",\n  \"Hendrych\",\n  \"Herman\",\n  \"Heřman\",\n  \"Heřmánek\",\n  \"Hladík\",\n  \"Hladký\",\n  \"Hlaváč\",\n  \"Hlaváček\",\n  \"Hlavatý\",\n  \"Hlávka\",\n  \"Hloušek\",\n  \"Hoffmann\",\n  \"Hofman\",\n  \"Holan\",\n  \"Holas\",\n  \"Holec\",\n  \"Holeček\",\n  \"Holík\",\n  \"Holoubek\",\n  \"Holub\",\n  \"Holý\",\n  \"Homola\",\n  \"Homolka\",\n  \"Hora\",\n  \"Horáček\",\n  \"Horák\",\n  \"Hořejší\",\n  \"Horký\",\n  \"Horňák\",\n  \"Horníček\",\n  \"Horník\",\n  \"Horský\",\n  \"Horvát\",\n  \"Horváth\",\n  \"Hošek\",\n  \"Houdek\",\n  \"Houška\",\n  \"Hovorka\",\n  \"Hrabal\",\n  \"Hrabovský\",\n  \"Hradecký\",\n  \"Hradil\",\n  \"Hrbáček\",\n  \"Hrbek\",\n  \"Hrdina\",\n  \"Hrdlička\",\n  \"Hrdý\",\n  \"Hrnčíř\",\n  \"Hroch\",\n  \"Hromádka\",\n  \"Hron\",\n  \"Hrubeš\",\n  \"Hrubý\",\n  \"Hruška\",\n  \"Hrůza\",\n  \"Hubáček\",\n  \"Hudec\",\n  \"Hudeček\",\n  \"Hůlka\",\n  \"Huml\",\n  \"Husák\",\n  \"Hušek\",\n  \"Hýbl\",\n  \"Hynek\",\n  \"Jahoda\",\n  \"Jakeš\",\n  \"Jakl\",\n  \"Jakoubek\",\n  \"Jakubec\",\n  \"Janáček\",\n  \"Janák\",\n  \"Janata\",\n  \"Janča\",\n  \"Jančík\",\n  \"Janda\",\n  \"Janeček\",\n  \"Janečka\",\n  \"Janíček\",\n  \"Janík\",\n  \"Janků\",\n  \"Janota\",\n  \"Janoušek\",\n  \"Janovský\",\n  \"Jansa\",\n  \"Jánský\",\n  \"Janů\",\n  \"Jareš\",\n  \"Jaroš\",\n  \"Jašek\",\n  \"Javůrek\",\n  \"Jech\",\n  \"Jedlička\",\n  \"Jelen\",\n  \"Jelínek\",\n  \"Jeníček\",\n  \"Jeřábek\",\n  \"Jež\",\n  \"Ježek\",\n  \"Jílek\",\n  \"Jindra\",\n  \"Jíra\",\n  \"Jirák\",\n  \"Jiránek\",\n  \"Jirásek\",\n  \"Jiřík\",\n  \"Jirka\",\n  \"Jirků\",\n  \"Jiroušek\",\n  \"Jirsa\",\n  \"John\",\n  \"Jonáš\",\n  \"Junek\",\n  \"Jurčík\",\n  \"Jurečka\",\n  \"Juřica\",\n  \"Juřík\",\n  \"Kabát\",\n  \"Kačírek\",\n  \"Kadeřábek\",\n  \"Kadlec\",\n  \"Kafka\",\n  \"Kaiser\",\n  \"Kala\",\n  \"Kaláb\",\n  \"Kalaš\",\n  \"Kalina\",\n  \"Kalivoda\",\n  \"Kalous\",\n  \"Kalousek\",\n  \"Kameník\",\n  \"Kaňa\",\n  \"Káňa\",\n  \"Kaňka\",\n  \"Kantor\",\n  \"Kaplan\",\n  \"Karas\",\n  \"Karásek\",\n  \"Karban\",\n  \"Karel\",\n  \"Karlík\",\n  \"Kasal\",\n  \"Kašík\",\n  \"Kašpar\",\n  \"Kašpárek\",\n  \"Kavka\",\n  \"Kazda\",\n  \"Kindl\",\n  \"Klečka\",\n  \"Klein\",\n  \"Klement\",\n  \"Klíma\",\n  \"Kliment\",\n  \"Klimeš\",\n  \"Klouček\",\n  \"Klouda\",\n  \"Knap\",\n  \"Knotek\",\n  \"Koch\",\n  \"Kočí\",\n  \"Kocián\",\n  \"Kocman\",\n  \"Kocourek\",\n  \"Kohout\",\n  \"Kohoutek\",\n  \"Koláček\",\n  \"Kolář\",\n  \"Kolařík\",\n  \"Kolek\",\n  \"Kolman\",\n  \"Komárek\",\n  \"Komínek\",\n  \"Konečný\",\n  \"Koníček\",\n  \"Kopal\",\n  \"Kopeček\",\n  \"Kopecký\",\n  \"Kopečný\",\n  \"Kopřiva\",\n  \"Korbel\",\n  \"Kořínek\",\n  \"Kos\",\n  \"Kosík\",\n  \"Kosina\",\n  \"Košťál\",\n  \"Kostka\",\n  \"Kotas\",\n  \"Kotek\",\n  \"Kotlár\",\n  \"Kotrba\",\n  \"Kouba\",\n  \"Koubek\",\n  \"Koudela\",\n  \"Koudelka\",\n  \"Koukal\",\n  \"Kouřil\",\n  \"Koutný\",\n  \"Kováč\",\n  \"Kovář\",\n  \"Kovařík\",\n  \"Kovářík\",\n  \"Kozák\",\n  \"Kozel\",\n  \"Krajíček\",\n  \"Král\",\n  \"Králíček\",\n  \"Králík\",\n  \"Krátký\",\n  \"Kratochvíl\",\n  \"Kraus\",\n  \"Krčmář\",\n  \"Křeček\",\n  \"Krejčí\",\n  \"Krejčík\",\n  \"Krejčíř\",\n  \"Křenek\",\n  \"Krištof\",\n  \"Křivánek\",\n  \"Kříž\",\n  \"Křížek\",\n  \"Kropáček\",\n  \"Kroupa\",\n  \"Krupa\",\n  \"Krupička\",\n  \"Krupka\",\n  \"Kuba\",\n  \"Kubánek\",\n  \"Kubát\",\n  \"Kubec\",\n  \"Kubelka\",\n  \"Kubeš\",\n  \"Kubica\",\n  \"Kubíček\",\n  \"Kubík\",\n  \"Kubín\",\n  \"Kubiš\",\n  \"Kuča\",\n  \"Kučera\",\n  \"Kuchař\",\n  \"Kuchta\",\n  \"Kudláček\",\n  \"Kudrna\",\n  \"Kukla\",\n  \"Kulhánek\",\n  \"Kulhavý\",\n  \"Kunc\",\n  \"Kuneš\",\n  \"Kupec\",\n  \"Kupka\",\n  \"Kurka\",\n  \"Kužel\",\n  \"Kvapil\",\n  \"Kvasnička\",\n  \"Kyncl\",\n  \"Kysela\",\n  \"Lacina\",\n  \"Lacko\",\n  \"Lakatoš\",\n  \"Landa\",\n  \"Lang\",\n  \"Langer\",\n  \"Langr\",\n  \"Látal\",\n  \"Lavička\",\n  \"Le\",\n  \"Lebeda\",\n  \"Levý\",\n  \"Líbal\",\n  \"Linhart\",\n  \"Liška\",\n  \"Lorenc\",\n  \"Louda\",\n  \"Ludvík\",\n  \"Lukáč\",\n  \"Lukáš\",\n  \"Lukášek\",\n  \"Lukeš\",\n  \"Macák\",\n  \"Macek\",\n  \"Mach\",\n  \"Mácha\",\n  \"Machač\",\n  \"Macháč\",\n  \"Macháček\",\n  \"Machala\",\n  \"Machálek\",\n  \"Macura\",\n  \"Majer\",\n  \"Maleček\",\n  \"Málek\",\n  \"Malík\",\n  \"Malina\",\n  \"Malý\",\n  \"Maňák\",\n  \"Mareček\",\n  \"Marek\",\n  \"Mareš\",\n  \"Mařík\",\n  \"Maršálek\",\n  \"Maršík\",\n  \"Martinec\",\n  \"Martinek\",\n  \"Martínek\",\n  \"Mašek\",\n  \"Masopust\",\n  \"Matějíček\",\n  \"Matějka\",\n  \"Matouš\",\n  \"Matoušek\",\n  \"Matula\",\n  \"Matuška\",\n  \"Matyáš\",\n  \"Matys\",\n  \"Maxa\",\n  \"Mayer\",\n  \"Mazánek\",\n  \"Medek\",\n  \"Melichar\",\n  \"Mencl\",\n  \"Menšík\",\n  \"Merta\",\n  \"Michal\",\n  \"Michalec\",\n  \"Michálek\",\n  \"Michalík\",\n  \"Michna\",\n  \"Mička\",\n  \"Mika\",\n  \"Míka\",\n  \"Mikeš\",\n  \"Miko\",\n  \"Mikula\",\n  \"Mikulášek\",\n  \"Minář\",\n  \"Minařík\",\n  \"Mirga\",\n  \"Mládek\",\n  \"Mlčoch\",\n  \"Mlejnek\",\n  \"Mojžíš\",\n  \"Mokrý\",\n  \"Molnár\",\n  \"Moravec\",\n  \"Morávek\",\n  \"Motl\",\n  \"Motyčka\",\n  \"Moučka\",\n  \"Moudrý\",\n  \"Mráček\",\n  \"Mráz\",\n  \"Mrázek\",\n  \"Mrkvička\",\n  \"Mucha\",\n  \"Müller\",\n  \"Műller\",\n  \"Musil\",\n  \"Mužík\",\n  \"Myška\",\n  \"Nagy\",\n  \"Najman\",\n  \"Navrátil\",\n  \"Nečas\",\n  \"Nedbal\",\n  \"Nedoma\",\n  \"Nedvěd\",\n  \"Nejedlý\",\n  \"Němec\",\n  \"Němeček\",\n  \"Nešpor\",\n  \"Nesvadba\",\n  \"Neubauer\",\n  \"Neuman\",\n  \"Neumann\",\n  \"Nguyen\",\n  \"Nguyen van\",\n  \"Nosek\",\n  \"Nováček\",\n  \"Novák\",\n  \"Novosad\",\n  \"Novotný\",\n  \"Nový\",\n  \"Odehnal\",\n  \"Oláh\",\n  \"Oliva\",\n  \"Ondra\",\n  \"Ondráček\",\n  \"Orság\",\n  \"Otáhal\",\n  \"Paleček\",\n  \"Pánek\",\n  \"Papež\",\n  \"Pařízek\",\n  \"Pašek\",\n  \"Pátek\",\n  \"Patočka\",\n  \"Paul\",\n  \"Pavel\",\n  \"Pavelek\",\n  \"Pavelka\",\n  \"Pavlas\",\n  \"Pavlica\",\n  \"Pavlíček\",\n  \"Pavlík\",\n  \"Pavlů\",\n  \"Pazdera\",\n  \"Pech\",\n  \"Pecha\",\n  \"Pecháček\",\n  \"Pecka\",\n  \"Pekař\",\n  \"Pekárek\",\n  \"Pelc\",\n  \"Pelikán\",\n  \"Peřina\",\n  \"Pernica\",\n  \"Peroutka\",\n  \"Pešek\",\n  \"Peška\",\n  \"Pešta\",\n  \"Peterka\",\n  \"Petr\",\n  \"Petrák\",\n  \"Petráš\",\n  \"Petříček\",\n  \"Petřík\",\n  \"Petrů\",\n  \"Pham\",\n  \"Pícha\",\n  \"Pilař\",\n  \"Pilát\",\n  \"Píša\",\n  \"Pivoňka\",\n  \"Plaček\",\n  \"Plachý\",\n  \"Plšek\",\n  \"Pluhař\",\n  \"Podzimek\",\n  \"Pohl\",\n  \"Pokorný\",\n  \"Poláček\",\n  \"Polách\",\n  \"Polák\",\n  \"Polanský\",\n  \"Polášek\",\n  \"Polívka\",\n  \"Popelka\",\n  \"Pospíchal\",\n  \"Pospíšil\",\n  \"Potůček\",\n  \"Pour\",\n  \"Prachař\",\n  \"Prášek\",\n  \"Pražák\",\n  \"Prchal\",\n  \"Přibyl\",\n  \"Příhoda\",\n  \"Přikryl\",\n  \"Procházka\",\n  \"Prokeš\",\n  \"Prokop\",\n  \"Prošek\",\n  \"Provazník\",\n  \"Průcha\",\n  \"Průša\",\n  \"Pšenička\",\n  \"Ptáček\",\n  \"Rác\",\n  \"Rada\",\n  \"Rak\",\n  \"Rambousek\",\n  \"Raška\",\n  \"Rataj\",\n  \"řeháček\",\n  \"řehák\",\n  \"řehoř\",\n  \"Remeš\",\n  \"řezáč\",\n  \"Rezek\",\n  \"řezníček\",\n  \"Richter\",\n  \"Richtr\",\n  \"říha\",\n  \"Roubal\",\n  \"Rous\",\n  \"Rozsypal\",\n  \"Rudolf\",\n  \"Růžek\",\n  \"Růžička\",\n  \"Ryba\",\n  \"Rybář\",\n  \"Rýdl\",\n  \"Ryšavý\",\n  \"Sadílek\",\n  \"šafář\",\n  \"šafařík\",\n  \"šafránek\",\n  \"šálek\",\n  \"Samek\",\n  \"šanda\",\n  \"šašek\",\n  \"Schejbal\",\n  \"Schmidt\",\n  \"Schneider\",\n  \"Schwarz\",\n  \"šebek\",\n  \"šebela\",\n  \"šebesta\",\n  \"šeda\",\n  \"šedivý\",\n  \"Sedláček\",\n  \"Sedlák\",\n  \"Sedlář\",\n  \"Sehnal\",\n  \"Seidl\",\n  \"Seifert\",\n  \"Sekanina\",\n  \"Semerád\",\n  \"šenk\",\n  \"šesták\",\n  \"ševčík\",\n  \"Severa\",\n  \"Sikora\",\n  \"šilhavý\",\n  \"šíma\",\n  \"šimáček\",\n  \"šimák\",\n  \"šimánek\",\n  \"šimčík\",\n  \"šimeček\",\n  \"šimek\",\n  \"šimon\",\n  \"šimůnek\",\n  \"šindelář\",\n  \"šindler\",\n  \"šíp\",\n  \"šípek\",\n  \"šír\",\n  \"široký\",\n  \"šiška\",\n  \"Sivák\",\n  \"Skácel\",\n  \"Skala\",\n  \"Skála\",\n  \"Skalický\",\n  \"Sklenář\",\n  \"škoda\",\n  \"Skopal\",\n  \"Skořepa\",\n  \"škrabal\",\n  \"Skřivánek\",\n  \"Slabý\",\n  \"Sládek\",\n  \"Sladký\",\n  \"Sláma\",\n  \"Slanina\",\n  \"Slavíček\",\n  \"Slavík\",\n  \"šlechta\",\n  \"Slezák\",\n  \"Slováček\",\n  \"Slovák\",\n  \"Sluka\",\n  \"Smejkal\",\n  \"šmejkal\",\n  \"Smékal\",\n  \"šmerda\",\n  \"Smetana\",\n  \"šmíd\",\n  \"Smola\",\n  \"Smolík\",\n  \"Smolka\",\n  \"Smrčka\",\n  \"Smrž\",\n  \"Smutný\",\n  \"šnajdr\",\n  \"Sobek\",\n  \"Sobotka\",\n  \"Sochor\",\n  \"Sojka\",\n  \"Sokol\",\n  \"šolc\",\n  \"Sommer\",\n  \"Souček\",\n  \"Soukup\",\n  \"Sova\",\n  \"špaček\",\n  \"Spáčil\",\n  \"špička\",\n  \"šplíchal\",\n  \"Spurný\",\n  \"šrámek\",\n  \"Srb\",\n  \"Staněk\",\n  \"Stárek\",\n  \"Starý\",\n  \"šťastný\",\n  \"štefan\",\n  \"štefek\",\n  \"štefl\",\n  \"Stehlík\",\n  \"Steiner\",\n  \"Stejskal\",\n  \"štěpán\",\n  \"štěpánek\",\n  \"štěrba\",\n  \"Stibor\",\n  \"Stoklasa\",\n  \"Straka\",\n  \"Stránský\",\n  \"Strejček\",\n  \"Strnad\",\n  \"Strouhal\",\n  \"Stuchlík\",\n  \"Studený\",\n  \"Studnička\",\n  \"Stupka\",\n  \"šubrt\",\n  \"Suchánek\",\n  \"Suchomel\",\n  \"Suchý\",\n  \"Suk\",\n  \"šulc\",\n  \"šustr\",\n  \"šváb\",\n  \"Svačina\",\n  \"švanda\",\n  \"švarc\",\n  \"Svatoň\",\n  \"Svatoš\",\n  \"švec\",\n  \"švehla\",\n  \"švejda\",\n  \"švestka\",\n  \"Světlík\",\n  \"Sviták\",\n  \"Svoboda\",\n  \"Svozil\",\n  \"Sýkora\",\n  \"Synek\",\n  \"Syrový\",\n  \"Táborský\",\n  \"Tancoš\",\n  \"Teplý\",\n  \"Tesař\",\n  \"Tichý\",\n  \"Toman\",\n  \"Tománek\",\n  \"Tomáš\",\n  \"Tomášek\",\n  \"Tomeček\",\n  \"Tomek\",\n  \"Tomeš\",\n  \"Tóth\",\n  \"Tran\",\n  \"Trávníček\",\n  \"Trčka\",\n  \"Tříska\",\n  \"Trnka\",\n  \"Trojan\",\n  \"Truhlář\",\n  \"Tuček\",\n  \"Tůma\",\n  \"Tureček\",\n  \"Turek\",\n  \"Tvrdík\",\n  \"Tvrdý\",\n  \"Uher\",\n  \"Uhlíř\",\n  \"Ulrich\",\n  \"Urban\",\n  \"Urbanec\",\n  \"Urbánek\",\n  \"Vacek\",\n  \"Vácha\",\n  \"Václavek\",\n  \"Václavík\",\n  \"Vaculík\",\n  \"Vágner\",\n  \"Vala\",\n  \"Valášek\",\n  \"Válek\",\n  \"Valenta\",\n  \"Valeš\",\n  \"Váňa\",\n  \"Vančura\",\n  \"Vaněček\",\n  \"Vaněk\",\n  \"Vaníček\",\n  \"Varga\",\n  \"Vašák\",\n  \"Vašek\",\n  \"Vašíček\",\n  \"Vávra\",\n  \"Vavřík\",\n  \"Večeřa\",\n  \"Vejvoda\",\n  \"Verner\",\n  \"Veselý\",\n  \"Veverka\",\n  \"Vícha\",\n  \"Vilímek\",\n  \"Vinš\",\n  \"Víšek\",\n  \"Vít\",\n  \"Vitásek\",\n  \"Vítek\",\n  \"Vlach\",\n  \"Vlasák\",\n  \"Vlček\",\n  \"Vlk\",\n  \"Vobořil\",\n  \"Vodák\",\n  \"Vodička\",\n  \"Vodrážka\",\n  \"Vojáček\",\n  \"Vojta\",\n  \"Vojtěch\",\n  \"Vojtek\",\n  \"Vojtíšek\",\n  \"Vokoun\",\n  \"Volek\",\n  \"Volf\",\n  \"Volný\",\n  \"Vondra\",\n  \"Vondráček\",\n  \"Vondrák\",\n  \"Voráček\",\n  \"Vorel\",\n  \"Voříšek\",\n  \"Vorlíček\",\n  \"Votava\",\n  \"Votruba\",\n  \"Vrabec\",\n  \"Vrána\",\n  \"Vrba\",\n  \"Vrzal\",\n  \"Vybíral\",\n  \"Vydra\",\n  \"Vymazal\",\n  \"Vyskočil\",\n  \"Vysloužil\",\n  \"Wagner\",\n  \"Walter\",\n  \"Weber\",\n  \"Weiss\",\n  \"Winkler\",\n  \"Wolf\",\n  \"Zábranský\",\n  \"žáček\",\n  \"Zach\",\n  \"Zahrádka\",\n  \"Zahradník\",\n  \"Zajíc\",\n  \"Zajíček\",\n  \"žák\",\n  \"Zálešák\",\n  \"Zámečník\",\n  \"Zapletal\",\n  \"Záruba\",\n  \"Zatloukal\",\n  \"Zavadil\",\n  \"Zavřel\",\n  \"Zbořil\",\n  \"žďárský\",\n  \"Zdražil\",\n  \"Zedník\",\n  \"Zelenka\",\n  \"Zelený\",\n  \"Zelinka\",\n  \"Zeman\",\n  \"Zemánek\",\n  \"žemlička\",\n  \"Zezula\",\n  \"žídek\",\n  \"žiga\",\n  \"Zíka\",\n  \"Zikmund\",\n  \"Zima\",\n  \"žižka\",\n  \"Zlámal\",\n  \"Zoubek\",\n  \"Zouhar\",\n  \"žůrek\",\n  \"Zvěřina\",\n];\n\n},{}],91:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{man_first_name} #{man_last_name}\",\n  \"#{prefix} #{woman_first_name} #{woman_last_name}\",\n  \"#{man_first_name} #{man_last_name} #{suffix}\",\n  \"#{woman_first_name} #{woman_last_name} #{suffix}\",\n  \"#{man_first_name} #{man_last_name}\",\n  \"#{man_first_name} #{man_last_name}\",\n  \"#{man_first_name} #{man_last_name}\",\n  \"#{woman_first_name} #{woman_last_name}\",\n  \"#{woman_first_name} #{woman_last_name}\",\n  \"#{woman_first_name} #{woman_last_name}\"\n];\n\n},{}],92:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ing.\",\n  \"Mgr.\",\n  \"JUDr.\",\n  \"MUDr.\"\n];\n\n},{}],93:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Phd.\"\n];\n\n},{}],94:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"descriptor\": [\n    \"Lead\",\n    \"Senior\",\n    \"Direct\",\n    \"Corporate\",\n    \"Dynamic\",\n    \"Future\",\n    \"Product\",\n    \"National\",\n    \"Regional\",\n    \"District\",\n    \"Central\",\n    \"Global\",\n    \"Customer\",\n    \"Investor\",\n    \"Dynamic\",\n    \"International\",\n    \"Legacy\",\n    \"Forward\",\n    \"Internal\",\n    \"Human\",\n    \"Chief\",\n    \"Principal\"\n  ],\n  \"level\": [\n    \"Solutions\",\n    \"Program\",\n    \"Brand\",\n    \"Security\",\n    \"Research\",\n    \"Marketing\",\n    \"Directives\",\n    \"Implementation\",\n    \"Integration\",\n    \"Functionality\",\n    \"Response\",\n    \"Paradigm\",\n    \"Tactics\",\n    \"Identity\",\n    \"Markets\",\n    \"Group\",\n    \"Division\",\n    \"Applications\",\n    \"Optimization\",\n    \"Operations\",\n    \"Infrastructure\",\n    \"Intranet\",\n    \"Communications\",\n    \"Web\",\n    \"Branding\",\n    \"Quality\",\n    \"Assurance\",\n    \"Mobility\",\n    \"Accounts\",\n    \"Data\",\n    \"Creative\",\n    \"Configuration\",\n    \"Accountability\",\n    \"Interactions\",\n    \"Factors\",\n    \"Usability\",\n    \"Metrics\"\n  ],\n  \"job\": [\n    \"Supervisor\",\n    \"Associate\",\n    \"Executive\",\n    \"Liason\",\n    \"Officer\",\n    \"Manager\",\n    \"Engineer\",\n    \"Specialist\",\n    \"Director\",\n    \"Coordinator\",\n    \"Administrator\",\n    \"Architect\",\n    \"Analyst\",\n    \"Designer\",\n    \"Planner\",\n    \"Orchestrator\",\n    \"Technician\",\n    \"Developer\",\n    \"Producer\",\n    \"Consultant\",\n    \"Assistant\",\n    \"Facilitator\",\n    \"Agent\",\n    \"Representative\",\n    \"Strategist\"\n  ]\n};\n\n},{}],95:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"601 ### ###\",\n  \"737 ### ###\",\n  \"736 ### ###\",\n  \"### ### ###\",\n  \"+420 ### ### ###\",\n  \"00420 ### ### ###\"\n];\n\n},{}],96:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":95,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],97:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###\",\n  \"##\",\n  \"#\",\n  \"##a\",\n  \"##b\",\n  \"##c\"\n];\n\n},{}],98:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_prefix} #{Name.first_name}#{city_suffix}\",\n  \"#{city_prefix} #{Name.first_name}\",\n  \"#{Name.first_name}#{city_suffix}\",\n  \"#{Name.last_name}#{city_suffix}\"\n];\n\n},{}],99:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Nord\",\n  \"Ost\",\n  \"West\",\n  \"Süd\",\n  \"Neu\",\n  \"Alt\",\n  \"Bad\"\n];\n\n},{}],100:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"stadt\",\n  \"dorf\",\n  \"land\",\n  \"scheid\",\n  \"burg\"\n];\n\n},{}],101:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ägypten\",\n  \"Äquatorialguinea\",\n  \"Äthiopien\",\n  \"Österreich\",\n  \"Afghanistan\",\n  \"Albanien\",\n  \"Algerien\",\n  \"Amerikanisch-Samoa\",\n  \"Amerikanische Jungferninseln\",\n  \"Andorra\",\n  \"Angola\",\n  \"Anguilla\",\n  \"Antarktis\",\n  \"Antigua und Barbuda\",\n  \"Argentinien\",\n  \"Armenien\",\n  \"Aruba\",\n  \"Aserbaidschan\",\n  \"Australien\",\n  \"Bahamas\",\n  \"Bahrain\",\n  \"Bangladesch\",\n  \"Barbados\",\n  \"Belarus\",\n  \"Belgien\",\n  \"Belize\",\n  \"Benin\",\n  \"die Bermudas\",\n  \"Bhutan\",\n  \"Bolivien\",\n  \"Bosnien und Herzegowina\",\n  \"Botsuana\",\n  \"Bouvetinsel\",\n  \"Brasilien\",\n  \"Britische Jungferninseln\",\n  \"Britisches Territorium im Indischen Ozean\",\n  \"Brunei Darussalam\",\n  \"Bulgarien\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Chile\",\n  \"China\",\n  \"Cookinseln\",\n  \"Costa Rica\",\n  \"Dänemark\",\n  \"Demokratische Republik Kongo\",\n  \"Demokratische Volksrepublik Korea\",\n  \"Deutschland\",\n  \"Dominica\",\n  \"Dominikanische Republik\",\n  \"Dschibuti\",\n  \"Ecuador\",\n  \"El Salvador\",\n  \"Eritrea\",\n  \"Estland\",\n  \"Färöer\",\n  \"Falklandinseln\",\n  \"Fidschi\",\n  \"Finnland\",\n  \"Frankreich\",\n  \"Französisch-Guayana\",\n  \"Französisch-Polynesien\",\n  \"Französische Gebiete im südlichen Indischen Ozean\",\n  \"Gabun\",\n  \"Gambia\",\n  \"Georgien\",\n  \"Ghana\",\n  \"Gibraltar\",\n  \"Grönland\",\n  \"Grenada\",\n  \"Griechenland\",\n  \"Guadeloupe\",\n  \"Guam\",\n  \"Guatemala\",\n  \"Guinea\",\n  \"Guinea-Bissau\",\n  \"Guyana\",\n  \"Haiti\",\n  \"Heard und McDonaldinseln\",\n  \"Honduras\",\n  \"Hongkong\",\n  \"Indien\",\n  \"Indonesien\",\n  \"Irak\",\n  \"Iran\",\n  \"Irland\",\n  \"Island\",\n  \"Israel\",\n  \"Italien\",\n  \"Jamaika\",\n  \"Japan\",\n  \"Jemen\",\n  \"Jordanien\",\n  \"Jugoslawien\",\n  \"Kaimaninseln\",\n  \"Kambodscha\",\n  \"Kamerun\",\n  \"Kanada\",\n  \"Kap Verde\",\n  \"Kasachstan\",\n  \"Katar\",\n  \"Kenia\",\n  \"Kirgisistan\",\n  \"Kiribati\",\n  \"Kleinere amerikanische Überseeinseln\",\n  \"Kokosinseln\",\n  \"Kolumbien\",\n  \"Komoren\",\n  \"Kongo\",\n  \"Kroatien\",\n  \"Kuba\",\n  \"Kuwait\",\n  \"Laos\",\n  \"Lesotho\",\n  \"Lettland\",\n  \"Libanon\",\n  \"Liberia\",\n  \"Libyen\",\n  \"Liechtenstein\",\n  \"Litauen\",\n  \"Luxemburg\",\n  \"Macau\",\n  \"Madagaskar\",\n  \"Malawi\",\n  \"Malaysia\",\n  \"Malediven\",\n  \"Mali\",\n  \"Malta\",\n  \"ehemalige jugoslawische Republik Mazedonien\",\n  \"Marokko\",\n  \"Marshallinseln\",\n  \"Martinique\",\n  \"Mauretanien\",\n  \"Mauritius\",\n  \"Mayotte\",\n  \"Mexiko\",\n  \"Mikronesien\",\n  \"Monaco\",\n  \"Mongolei\",\n  \"Montserrat\",\n  \"Mosambik\",\n  \"Myanmar\",\n  \"Nördliche Marianen\",\n  \"Namibia\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Neukaledonien\",\n  \"Neuseeland\",\n  \"Nicaragua\",\n  \"Niederländische Antillen\",\n  \"Niederlande\",\n  \"Niger\",\n  \"Nigeria\",\n  \"Niue\",\n  \"Norfolkinsel\",\n  \"Norwegen\",\n  \"Oman\",\n  \"Osttimor\",\n  \"Pakistan\",\n  \"Palau\",\n  \"Panama\",\n  \"Papua-Neuguinea\",\n  \"Paraguay\",\n  \"Peru\",\n  \"Philippinen\",\n  \"Pitcairninseln\",\n  \"Polen\",\n  \"Portugal\",\n  \"Puerto Rico\",\n  \"Réunion\",\n  \"Republik Korea\",\n  \"Republik Moldau\",\n  \"Ruanda\",\n  \"Rumänien\",\n  \"Russische Föderation\",\n  \"São Tomé und Príncipe\",\n  \"Südafrika\",\n  \"Südgeorgien und Südliche Sandwichinseln\",\n  \"Salomonen\",\n  \"Sambia\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Saudi-Arabien\",\n  \"Schweden\",\n  \"Schweiz\",\n  \"Senegal\",\n  \"Seychellen\",\n  \"Sierra Leone\",\n  \"Simbabwe\",\n  \"Singapur\",\n  \"Slowakei\",\n  \"Slowenien\",\n  \"Somalien\",\n  \"Spanien\",\n  \"Sri Lanka\",\n  \"St. Helena\",\n  \"St. Kitts und Nevis\",\n  \"St. Lucia\",\n  \"St. Pierre und Miquelon\",\n  \"St. Vincent und die Grenadinen\",\n  \"Sudan\",\n  \"Surinam\",\n  \"Svalbard und Jan Mayen\",\n  \"Swasiland\",\n  \"Syrien\",\n  \"Türkei\",\n  \"Tadschikistan\",\n  \"Taiwan\",\n  \"Tansania\",\n  \"Thailand\",\n  \"Togo\",\n  \"Tokelau\",\n  \"Tonga\",\n  \"Trinidad und Tobago\",\n  \"Tschad\",\n  \"Tschechische Republik\",\n  \"Tunesien\",\n  \"Turkmenistan\",\n  \"Turks- und Caicosinseln\",\n  \"Tuvalu\",\n  \"Uganda\",\n  \"Ukraine\",\n  \"Ungarn\",\n  \"Uruguay\",\n  \"Usbekistan\",\n  \"Vanuatu\",\n  \"Vatikanstadt\",\n  \"Venezuela\",\n  \"Vereinigte Arabische Emirate\",\n  \"Vereinigte Staaten\",\n  \"Vereinigtes Königreich\",\n  \"Vietnam\",\n  \"Wallis und Futuna\",\n  \"Weihnachtsinsel\",\n  \"Westsahara\",\n  \"Zentralafrikanische Republik\",\n  \"Zypern\"\n];\n\n},{}],102:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Deutschland\"\n];\n\n},{}],103:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.country = require(\"./country\");\naddress.street_root = require(\"./street_root\");\naddress.building_number = require(\"./building_number\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":97,\"./city\":98,\"./city_prefix\":99,\"./city_suffix\":100,\"./country\":101,\"./default_country\":102,\"./postcode\":104,\"./secondary_address\":105,\"./state\":106,\"./state_abbr\":107,\"./street_address\":108,\"./street_name\":109,\"./street_root\":110}],104:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\",\n  \"#####\"\n];\n\n},{}],105:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Apt. ###\",\n  \"Zimmer ###\",\n  \"# OG\"\n];\n\n},{}],106:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Baden-Württemberg\",\n  \"Bayern\",\n  \"Berlin\",\n  \"Brandenburg\",\n  \"Bremen\",\n  \"Hamburg\",\n  \"Hessen\",\n  \"Mecklenburg-Vorpommern\",\n  \"Niedersachsen\",\n  \"Nordrhein-Westfalen\",\n  \"Rheinland-Pfalz\",\n  \"Saarland\",\n  \"Sachsen\",\n  \"Sachsen-Anhalt\",\n  \"Schleswig-Holstein\",\n  \"Thüringen\"\n];\n\n},{}],107:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"BW\",\n  \"BY\",\n  \"BE\",\n  \"BB\",\n  \"HB\",\n  \"HH\",\n  \"HE\",\n  \"MV\",\n  \"NI\",\n  \"NW\",\n  \"RP\",\n  \"SL\",\n  \"SN\",\n  \"ST\",\n  \"SH\",\n  \"TH\"\n];\n\n},{}],108:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],109:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_root}\"\n];\n\n},{}],110:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ackerweg\",\n  \"Adalbert-Stifter-Str.\",\n  \"Adalbertstr.\",\n  \"Adolf-Baeyer-Str.\",\n  \"Adolf-Kaschny-Str.\",\n  \"Adolf-Reichwein-Str.\",\n  \"Adolfsstr.\",\n  \"Ahornweg\",\n  \"Ahrstr.\",\n  \"Akazienweg\",\n  \"Albert-Einstein-Str.\",\n  \"Albert-Schweitzer-Str.\",\n  \"Albertus-Magnus-Str.\",\n  \"Albert-Zarthe-Weg\",\n  \"Albin-Edelmann-Str.\",\n  \"Albrecht-Haushofer-Str.\",\n  \"Aldegundisstr.\",\n  \"Alexanderstr.\",\n  \"Alfred-Delp-Str.\",\n  \"Alfred-Kubin-Str.\",\n  \"Alfred-Stock-Str.\",\n  \"Alkenrather Str.\",\n  \"Allensteiner Str.\",\n  \"Alsenstr.\",\n  \"Alt Steinbücheler Weg\",\n  \"Alte Garten\",\n  \"Alte Heide\",\n  \"Alte Landstr.\",\n  \"Alte Ziegelei\",\n  \"Altenberger Str.\",\n  \"Altenhof\",\n  \"Alter Grenzweg\",\n  \"Altstadtstr.\",\n  \"Am Alten Gaswerk\",\n  \"Am Alten Schafstall\",\n  \"Am Arenzberg\",\n  \"Am Benthal\",\n  \"Am Birkenberg\",\n  \"Am Blauen Berg\",\n  \"Am Borsberg\",\n  \"Am Brungen\",\n  \"Am Büchelter Hof\",\n  \"Am Buttermarkt\",\n  \"Am Ehrenfriedhof\",\n  \"Am Eselsdamm\",\n  \"Am Falkenberg\",\n  \"Am Frankenberg\",\n  \"Am Gesundheitspark\",\n  \"Am Gierlichshof\",\n  \"Am Graben\",\n  \"Am Hagelkreuz\",\n  \"Am Hang\",\n  \"Am Heidkamp\",\n  \"Am Hemmelrather Hof\",\n  \"Am Hofacker\",\n  \"Am Hohen Ufer\",\n  \"Am Höllers Eck\",\n  \"Am Hühnerberg\",\n  \"Am Jägerhof\",\n  \"Am Junkernkamp\",\n  \"Am Kemperstiegel\",\n  \"Am Kettnersbusch\",\n  \"Am Kiesberg\",\n  \"Am Klösterchen\",\n  \"Am Knechtsgraben\",\n  \"Am Köllerweg\",\n  \"Am Köttersbach\",\n  \"Am Kreispark\",\n  \"Am Kronefeld\",\n  \"Am Küchenhof\",\n  \"Am Kühnsbusch\",\n  \"Am Lindenfeld\",\n  \"Am Märchen\",\n  \"Am Mittelberg\",\n  \"Am Mönchshof\",\n  \"Am Mühlenbach\",\n  \"Am Neuenhof\",\n  \"Am Nonnenbruch\",\n  \"Am Plattenbusch\",\n  \"Am Quettinger Feld\",\n  \"Am Rosenhügel\",\n  \"Am Sandberg\",\n  \"Am Scherfenbrand\",\n  \"Am Schokker\",\n  \"Am Silbersee\",\n  \"Am Sonnenhang\",\n  \"Am Sportplatz\",\n  \"Am Stadtpark\",\n  \"Am Steinberg\",\n  \"Am Telegraf\",\n  \"Am Thelenhof\",\n  \"Am Vogelkreuz\",\n  \"Am Vogelsang\",\n  \"Am Vogelsfeldchen\",\n  \"Am Wambacher Hof\",\n  \"Am Wasserturm\",\n  \"Am Weidenbusch\",\n  \"Am Weiher\",\n  \"Am Weingarten\",\n  \"Am Werth\",\n  \"Amselweg\",\n  \"An den Irlen\",\n  \"An den Rheinauen\",\n  \"An der Bergerweide\",\n  \"An der Dingbank\",\n  \"An der Evangelischen Kirche\",\n  \"An der Evgl. Kirche\",\n  \"An der Feldgasse\",\n  \"An der Fettehenne\",\n  \"An der Kante\",\n  \"An der Laach\",\n  \"An der Lehmkuhle\",\n  \"An der Lichtenburg\",\n  \"An der Luisenburg\",\n  \"An der Robertsburg\",\n  \"An der Schmitten\",\n  \"An der Schusterinsel\",\n  \"An der Steinrütsch\",\n  \"An St. Andreas\",\n  \"An St. Remigius\",\n  \"Andreasstr.\",\n  \"Ankerweg\",\n  \"Annette-Kolb-Str.\",\n  \"Apenrader Str.\",\n  \"Arnold-Ohletz-Str.\",\n  \"Atzlenbacher Str.\",\n  \"Auerweg\",\n  \"Auestr.\",\n  \"Auf dem Acker\",\n  \"Auf dem Blahnenhof\",\n  \"Auf dem Bohnbüchel\",\n  \"Auf dem Bruch\",\n  \"Auf dem End\",\n  \"Auf dem Forst\",\n  \"Auf dem Herberg\",\n  \"Auf dem Lehn\",\n  \"Auf dem Stein\",\n  \"Auf dem Weierberg\",\n  \"Auf dem Weiherhahn\",\n  \"Auf den Reien\",\n  \"Auf der Donnen\",\n  \"Auf der Grieße\",\n  \"Auf der Ohmer\",\n  \"Auf der Weide\",\n  \"Auf'm Berg\",\n  \"Auf'm Kamp\",\n  \"Augustastr.\",\n  \"August-Kekulé-Str.\",\n  \"A.-W.-v.-Hofmann-Str.\",\n  \"Bahnallee\",\n  \"Bahnhofstr.\",\n  \"Baltrumstr.\",\n  \"Bamberger Str.\",\n  \"Baumberger Str.\",\n  \"Bebelstr.\",\n  \"Beckers Kämpchen\",\n  \"Beerenstr.\",\n  \"Beethovenstr.\",\n  \"Behringstr.\",\n  \"Bendenweg\",\n  \"Bensberger Str.\",\n  \"Benzstr.\",\n  \"Bergische Landstr.\",\n  \"Bergstr.\",\n  \"Berliner Platz\",\n  \"Berliner Str.\",\n  \"Bernhard-Letterhaus-Str.\",\n  \"Bernhard-Lichtenberg-Str.\",\n  \"Bernhard-Ridder-Str.\",\n  \"Bernsteinstr.\",\n  \"Bertha-Middelhauve-Str.\",\n  \"Bertha-von-Suttner-Str.\",\n  \"Bertolt-Brecht-Str.\",\n  \"Berzeliusstr.\",\n  \"Bielertstr.\",\n  \"Biesenbach\",\n  \"Billrothstr.\",\n  \"Birkenbergstr.\",\n  \"Birkengartenstr.\",\n  \"Birkenweg\",\n  \"Bismarckstr.\",\n  \"Bitterfelder Str.\",\n  \"Blankenburg\",\n  \"Blaukehlchenweg\",\n  \"Blütenstr.\",\n  \"Boberstr.\",\n  \"Böcklerstr.\",\n  \"Bodelschwinghstr.\",\n  \"Bodestr.\",\n  \"Bogenstr.\",\n  \"Bohnenkampsweg\",\n  \"Bohofsweg\",\n  \"Bonifatiusstr.\",\n  \"Bonner Str.\",\n  \"Borkumstr.\",\n  \"Bornheimer Str.\",\n  \"Borsigstr.\",\n  \"Borussiastr.\",\n  \"Bracknellstr.\",\n  \"Brahmsweg\",\n  \"Brandenburger Str.\",\n  \"Breidenbachstr.\",\n  \"Breslauer Str.\",\n  \"Bruchhauser Str.\",\n  \"Brückenstr.\",\n  \"Brucknerstr.\",\n  \"Brüder-Bonhoeffer-Str.\",\n  \"Buchenweg\",\n  \"Bürgerbuschweg\",\n  \"Burgloch\",\n  \"Burgplatz\",\n  \"Burgstr.\",\n  \"Burgweg\",\n  \"Bürriger Weg\",\n  \"Burscheider Str.\",\n  \"Buschkämpchen\",\n  \"Butterheider Str.\",\n  \"Carl-Duisberg-Platz\",\n  \"Carl-Duisberg-Str.\",\n  \"Carl-Leverkus-Str.\",\n  \"Carl-Maria-von-Weber-Platz\",\n  \"Carl-Maria-von-Weber-Str.\",\n  \"Carlo-Mierendorff-Str.\",\n  \"Carl-Rumpff-Str.\",\n  \"Carl-von-Ossietzky-Str.\",\n  \"Charlottenburger Str.\",\n  \"Christian-Heß-Str.\",\n  \"Claasbruch\",\n  \"Clemens-Winkler-Str.\",\n  \"Concordiastr.\",\n  \"Cranachstr.\",\n  \"Dahlemer Str.\",\n  \"Daimlerstr.\",\n  \"Damaschkestr.\",\n  \"Danziger Str.\",\n  \"Debengasse\",\n  \"Dechant-Fein-Str.\",\n  \"Dechant-Krey-Str.\",\n  \"Deichtorstr.\",\n  \"Dhünnberg\",\n  \"Dhünnstr.\",\n  \"Dianastr.\",\n  \"Diedenhofener Str.\",\n  \"Diepental\",\n  \"Diepenthaler Str.\",\n  \"Dieselstr.\",\n  \"Dillinger Str.\",\n  \"Distelkamp\",\n  \"Dohrgasse\",\n  \"Domblick\",\n  \"Dönhoffstr.\",\n  \"Dornierstr.\",\n  \"Drachenfelsstr.\",\n  \"Dr.-August-Blank-Str.\",\n  \"Dresdener Str.\",\n  \"Driescher Hecke\",\n  \"Drosselweg\",\n  \"Dudweilerstr.\",\n  \"Dünenweg\",\n  \"Dünfelder Str.\",\n  \"Dünnwalder Grenzweg\",\n  \"Düppeler Str.\",\n  \"Dürerstr.\",\n  \"Dürscheider Weg\",\n  \"Düsseldorfer Str.\",\n  \"Edelrather Weg\",\n  \"Edmund-Husserl-Str.\",\n  \"Eduard-Spranger-Str.\",\n  \"Ehrlichstr.\",\n  \"Eichenkamp\",\n  \"Eichenweg\",\n  \"Eidechsenweg\",\n  \"Eifelstr.\",\n  \"Eifgenstr.\",\n  \"Eintrachtstr.\",\n  \"Elbestr.\",\n  \"Elisabeth-Langgässer-Str.\",\n  \"Elisabethstr.\",\n  \"Elisabeth-von-Thadden-Str.\",\n  \"Elisenstr.\",\n  \"Elsa-Brändström-Str.\",\n  \"Elsbachstr.\",\n  \"Else-Lasker-Schüler-Str.\",\n  \"Elsterstr.\",\n  \"Emil-Fischer-Str.\",\n  \"Emil-Nolde-Str.\",\n  \"Engelbertstr.\",\n  \"Engstenberger Weg\",\n  \"Entenpfuhl\",\n  \"Erbelegasse\",\n  \"Erftstr.\",\n  \"Erfurter Str.\",\n  \"Erich-Heckel-Str.\",\n  \"Erich-Klausener-Str.\",\n  \"Erich-Ollenhauer-Str.\",\n  \"Erlenweg\",\n  \"Ernst-Bloch-Str.\",\n  \"Ernst-Ludwig-Kirchner-Str.\",\n  \"Erzbergerstr.\",\n  \"Eschenallee\",\n  \"Eschenweg\",\n  \"Esmarchstr.\",\n  \"Espenweg\",\n  \"Euckenstr.\",\n  \"Eulengasse\",\n  \"Eulenkamp\",\n  \"Ewald-Flamme-Str.\",\n  \"Ewald-Röll-Str.\",\n  \"Fährstr.\",\n  \"Farnweg\",\n  \"Fasanenweg\",\n  \"Faßbacher Hof\",\n  \"Felderstr.\",\n  \"Feldkampstr.\",\n  \"Feldsiefer Weg\",\n  \"Feldsiefer Wiesen\",\n  \"Feldstr.\",\n  \"Feldtorstr.\",\n  \"Felix-von-Roll-Str.\",\n  \"Ferdinand-Lassalle-Str.\",\n  \"Fester Weg\",\n  \"Feuerbachstr.\",\n  \"Feuerdornweg\",\n  \"Fichtenweg\",\n  \"Fichtestr.\",\n  \"Finkelsteinstr.\",\n  \"Finkenweg\",\n  \"Fixheider Str.\",\n  \"Flabbenhäuschen\",\n  \"Flensburger Str.\",\n  \"Fliederweg\",\n  \"Florastr.\",\n  \"Florianweg\",\n  \"Flotowstr.\",\n  \"Flurstr.\",\n  \"Föhrenweg\",\n  \"Fontanestr.\",\n  \"Forellental\",\n  \"Fortunastr.\",\n  \"Franz-Esser-Str.\",\n  \"Franz-Hitze-Str.\",\n  \"Franz-Kail-Str.\",\n  \"Franz-Marc-Str.\",\n  \"Freiburger Str.\",\n  \"Freiheitstr.\",\n  \"Freiherr-vom-Stein-Str.\",\n  \"Freudenthal\",\n  \"Freudenthaler Weg\",\n  \"Fridtjof-Nansen-Str.\",\n  \"Friedenberger Str.\",\n  \"Friedensstr.\",\n  \"Friedhofstr.\",\n  \"Friedlandstr.\",\n  \"Friedlieb-Ferdinand-Runge-Str.\",\n  \"Friedrich-Bayer-Str.\",\n  \"Friedrich-Bergius-Platz\",\n  \"Friedrich-Ebert-Platz\",\n  \"Friedrich-Ebert-Str.\",\n  \"Friedrich-Engels-Str.\",\n  \"Friedrich-List-Str.\",\n  \"Friedrich-Naumann-Str.\",\n  \"Friedrich-Sertürner-Str.\",\n  \"Friedrichstr.\",\n  \"Friedrich-Weskott-Str.\",\n  \"Friesenweg\",\n  \"Frischenberg\",\n  \"Fritz-Erler-Str.\",\n  \"Fritz-Henseler-Str.\",\n  \"Fröbelstr.\",\n  \"Fürstenbergplatz\",\n  \"Fürstenbergstr.\",\n  \"Gabriele-Münter-Str.\",\n  \"Gartenstr.\",\n  \"Gebhardstr.\",\n  \"Geibelstr.\",\n  \"Gellertstr.\",\n  \"Georg-von-Vollmar-Str.\",\n  \"Gerhard-Domagk-Str.\",\n  \"Gerhart-Hauptmann-Str.\",\n  \"Gerichtsstr.\",\n  \"Geschwister-Scholl-Str.\",\n  \"Gezelinallee\",\n  \"Gierener Weg\",\n  \"Ginsterweg\",\n  \"Gisbert-Cremer-Str.\",\n  \"Glücksburger Str.\",\n  \"Gluckstr.\",\n  \"Gneisenaustr.\",\n  \"Goetheplatz\",\n  \"Goethestr.\",\n  \"Golo-Mann-Str.\",\n  \"Görlitzer Str.\",\n  \"Görresstr.\",\n  \"Graebestr.\",\n  \"Graf-Galen-Platz\",\n  \"Gregor-Mendel-Str.\",\n  \"Greifswalder Str.\",\n  \"Grillenweg\",\n  \"Gronenborner Weg\",\n  \"Große Kirchstr.\",\n  \"Grunder Wiesen\",\n  \"Grundermühle\",\n  \"Grundermühlenhof\",\n  \"Grundermühlenweg\",\n  \"Grüner Weg\",\n  \"Grunewaldstr.\",\n  \"Grünstr.\",\n  \"Günther-Weisenborn-Str.\",\n  \"Gustav-Freytag-Str.\",\n  \"Gustav-Heinemann-Str.\",\n  \"Gustav-Radbruch-Str.\",\n  \"Gut Reuschenberg\",\n  \"Gutenbergstr.\",\n  \"Haberstr.\",\n  \"Habichtgasse\",\n  \"Hafenstr.\",\n  \"Hagenauer Str.\",\n  \"Hahnenblecher\",\n  \"Halenseestr.\",\n  \"Halfenleimbach\",\n  \"Hallesche Str.\",\n  \"Halligstr.\",\n  \"Hamberger Str.\",\n  \"Hammerweg\",\n  \"Händelstr.\",\n  \"Hannah-Höch-Str.\",\n  \"Hans-Arp-Str.\",\n  \"Hans-Gerhard-Str.\",\n  \"Hans-Sachs-Str.\",\n  \"Hans-Schlehahn-Str.\",\n  \"Hans-von-Dohnanyi-Str.\",\n  \"Hardenbergstr.\",\n  \"Haselweg\",\n  \"Hauptstr.\",\n  \"Haus-Vorster-Str.\",\n  \"Hauweg\",\n  \"Havelstr.\",\n  \"Havensteinstr.\",\n  \"Haydnstr.\",\n  \"Hebbelstr.\",\n  \"Heckenweg\",\n  \"Heerweg\",\n  \"Hegelstr.\",\n  \"Heidberg\",\n  \"Heidehöhe\",\n  \"Heidestr.\",\n  \"Heimstättenweg\",\n  \"Heinrich-Böll-Str.\",\n  \"Heinrich-Brüning-Str.\",\n  \"Heinrich-Claes-Str.\",\n  \"Heinrich-Heine-Str.\",\n  \"Heinrich-Hörlein-Str.\",\n  \"Heinrich-Lübke-Str.\",\n  \"Heinrich-Lützenkirchen-Weg\",\n  \"Heinrichstr.\",\n  \"Heinrich-Strerath-Str.\",\n  \"Heinrich-von-Kleist-Str.\",\n  \"Heinrich-von-Stephan-Str.\",\n  \"Heisterbachstr.\",\n  \"Helenenstr.\",\n  \"Helmestr.\",\n  \"Hemmelrather Weg\",\n  \"Henry-T.-v.-Böttinger-Str.\",\n  \"Herderstr.\",\n  \"Heribertstr.\",\n  \"Hermann-Ehlers-Str.\",\n  \"Hermann-Hesse-Str.\",\n  \"Hermann-König-Str.\",\n  \"Hermann-Löns-Str.\",\n  \"Hermann-Milde-Str.\",\n  \"Hermann-Nörrenberg-Str.\",\n  \"Hermann-von-Helmholtz-Str.\",\n  \"Hermann-Waibel-Str.\",\n  \"Herzogstr.\",\n  \"Heymannstr.\",\n  \"Hindenburgstr.\",\n  \"Hirzenberg\",\n  \"Hitdorfer Kirchweg\",\n  \"Hitdorfer Str.\",\n  \"Höfer Mühle\",\n  \"Höfer Weg\",\n  \"Hohe Str.\",\n  \"Höhenstr.\",\n  \"Höltgestal\",\n  \"Holunderweg\",\n  \"Holzer Weg\",\n  \"Holzer Wiesen\",\n  \"Hornpottweg\",\n  \"Hubertusweg\",\n  \"Hufelandstr.\",\n  \"Hufer Weg\",\n  \"Humboldtstr.\",\n  \"Hummelsheim\",\n  \"Hummelweg\",\n  \"Humperdinckstr.\",\n  \"Hüscheider Gärten\",\n  \"Hüscheider Str.\",\n  \"Hütte\",\n  \"Ilmstr.\",\n  \"Im Bergischen Heim\",\n  \"Im Bruch\",\n  \"Im Buchenhain\",\n  \"Im Bühl\",\n  \"Im Burgfeld\",\n  \"Im Dorf\",\n  \"Im Eisholz\",\n  \"Im Friedenstal\",\n  \"Im Frohental\",\n  \"Im Grunde\",\n  \"Im Hederichsfeld\",\n  \"Im Jücherfeld\",\n  \"Im Kalkfeld\",\n  \"Im Kirberg\",\n  \"Im Kirchfeld\",\n  \"Im Kreuzbruch\",\n  \"Im Mühlenfeld\",\n  \"Im Nesselrader Kamp\",\n  \"Im Oberdorf\",\n  \"Im Oberfeld\",\n  \"Im Rosengarten\",\n  \"Im Rottland\",\n  \"Im Scheffengarten\",\n  \"Im Staderfeld\",\n  \"Im Steinfeld\",\n  \"Im Weidenblech\",\n  \"Im Winkel\",\n  \"Im Ziegelfeld\",\n  \"Imbach\",\n  \"Imbacher Weg\",\n  \"Immenweg\",\n  \"In den Blechenhöfen\",\n  \"In den Dehlen\",\n  \"In der Birkenau\",\n  \"In der Dasladen\",\n  \"In der Felderhütten\",\n  \"In der Hartmannswiese\",\n  \"In der Höhle\",\n  \"In der Schaafsdellen\",\n  \"In der Wasserkuhl\",\n  \"In der Wüste\",\n  \"In Holzhausen\",\n  \"Insterstr.\",\n  \"Jacob-Fröhlen-Str.\",\n  \"Jägerstr.\",\n  \"Jahnstr.\",\n  \"Jakob-Eulenberg-Weg\",\n  \"Jakobistr.\",\n  \"Jakob-Kaiser-Str.\",\n  \"Jenaer Str.\",\n  \"Johannes-Baptist-Str.\",\n  \"Johannes-Dott-Str.\",\n  \"Johannes-Popitz-Str.\",\n  \"Johannes-Wislicenus-Str.\",\n  \"Johannisburger Str.\",\n  \"Johann-Janssen-Str.\",\n  \"Johann-Wirtz-Weg\",\n  \"Josefstr.\",\n  \"Jüch\",\n  \"Julius-Doms-Str.\",\n  \"Julius-Leber-Str.\",\n  \"Kaiserplatz\",\n  \"Kaiserstr.\",\n  \"Kaiser-Wilhelm-Allee\",\n  \"Kalkstr.\",\n  \"Kämpchenstr.\",\n  \"Kämpenwiese\",\n  \"Kämper Weg\",\n  \"Kamptalweg\",\n  \"Kanalstr.\",\n  \"Kandinskystr.\",\n  \"Kantstr.\",\n  \"Kapellenstr.\",\n  \"Karl-Arnold-Str.\",\n  \"Karl-Bosch-Str.\",\n  \"Karl-Bückart-Str.\",\n  \"Karl-Carstens-Ring\",\n  \"Karl-Friedrich-Goerdeler-Str.\",\n  \"Karl-Jaspers-Str.\",\n  \"Karl-König-Str.\",\n  \"Karl-Krekeler-Str.\",\n  \"Karl-Marx-Str.\",\n  \"Karlstr.\",\n  \"Karl-Ulitzka-Str.\",\n  \"Karl-Wichmann-Str.\",\n  \"Karl-Wingchen-Str.\",\n  \"Käsenbrod\",\n  \"Käthe-Kollwitz-Str.\",\n  \"Katzbachstr.\",\n  \"Kerschensteinerstr.\",\n  \"Kiefernweg\",\n  \"Kieler Str.\",\n  \"Kieselstr.\",\n  \"Kiesweg\",\n  \"Kinderhausen\",\n  \"Kleiberweg\",\n  \"Kleine Kirchstr.\",\n  \"Kleingansweg\",\n  \"Kleinheider Weg\",\n  \"Klief\",\n  \"Kneippstr.\",\n  \"Knochenbergsweg\",\n  \"Kochergarten\",\n  \"Kocherstr.\",\n  \"Kockelsberg\",\n  \"Kolberger Str.\",\n  \"Kolmarer Str.\",\n  \"Kölner Gasse\",\n  \"Kölner Str.\",\n  \"Kolpingstr.\",\n  \"Königsberger Platz\",\n  \"Konrad-Adenauer-Platz\",\n  \"Köpenicker Str.\",\n  \"Kopernikusstr.\",\n  \"Körnerstr.\",\n  \"Köschenberg\",\n  \"Köttershof\",\n  \"Kreuzbroicher Str.\",\n  \"Kreuzkamp\",\n  \"Krummer Weg\",\n  \"Kruppstr.\",\n  \"Kuhlmannweg\",\n  \"Kump\",\n  \"Kumper Weg\",\n  \"Kunstfeldstr.\",\n  \"Küppersteger Str.\",\n  \"Kursiefen\",\n  \"Kursiefer Weg\",\n  \"Kurtekottenweg\",\n  \"Kurt-Schumacher-Ring\",\n  \"Kyllstr.\",\n  \"Langenfelder Str.\",\n  \"Längsleimbach\",\n  \"Lärchenweg\",\n  \"Legienstr.\",\n  \"Lehner Mühle\",\n  \"Leichlinger Str.\",\n  \"Leimbacher Hof\",\n  \"Leinestr.\",\n  \"Leineweberstr.\",\n  \"Leipziger Str.\",\n  \"Lerchengasse\",\n  \"Lessingstr.\",\n  \"Libellenweg\",\n  \"Lichstr.\",\n  \"Liebigstr.\",\n  \"Lindenstr.\",\n  \"Lingenfeld\",\n  \"Linienstr.\",\n  \"Lippe\",\n  \"Löchergraben\",\n  \"Löfflerstr.\",\n  \"Loheweg\",\n  \"Lohrbergstr.\",\n  \"Lohrstr.\",\n  \"Löhstr.\",\n  \"Lortzingstr.\",\n  \"Lötzener Str.\",\n  \"Löwenburgstr.\",\n  \"Lucasstr.\",\n  \"Ludwig-Erhard-Platz\",\n  \"Ludwig-Girtler-Str.\",\n  \"Ludwig-Knorr-Str.\",\n  \"Luisenstr.\",\n  \"Lupinenweg\",\n  \"Lurchenweg\",\n  \"Lützenkirchener Str.\",\n  \"Lycker Str.\",\n  \"Maashofstr.\",\n  \"Manforter Str.\",\n  \"Marc-Chagall-Str.\",\n  \"Maria-Dresen-Str.\",\n  \"Maria-Terwiel-Str.\",\n  \"Marie-Curie-Str.\",\n  \"Marienburger Str.\",\n  \"Mariendorfer Str.\",\n  \"Marienwerderstr.\",\n  \"Marie-Schlei-Str.\",\n  \"Marktplatz\",\n  \"Markusweg\",\n  \"Martin-Buber-Str.\",\n  \"Martin-Heidegger-Str.\",\n  \"Martin-Luther-Str.\",\n  \"Masurenstr.\",\n  \"Mathildenweg\",\n  \"Maurinusstr.\",\n  \"Mauspfad\",\n  \"Max-Beckmann-Str.\",\n  \"Max-Delbrück-Str.\",\n  \"Max-Ernst-Str.\",\n  \"Max-Holthausen-Platz\",\n  \"Max-Horkheimer-Str.\",\n  \"Max-Liebermann-Str.\",\n  \"Max-Pechstein-Str.\",\n  \"Max-Planck-Str.\",\n  \"Max-Scheler-Str.\",\n  \"Max-Schönenberg-Str.\",\n  \"Maybachstr.\",\n  \"Meckhofer Feld\",\n  \"Meisenweg\",\n  \"Memelstr.\",\n  \"Menchendahler Str.\",\n  \"Mendelssohnstr.\",\n  \"Merziger Str.\",\n  \"Mettlacher Str.\",\n  \"Metzer Str.\",\n  \"Michaelsweg\",\n  \"Miselohestr.\",\n  \"Mittelstr.\",\n  \"Mohlenstr.\",\n  \"Moltkestr.\",\n  \"Monheimer Str.\",\n  \"Montanusstr.\",\n  \"Montessoriweg\",\n  \"Moosweg\",\n  \"Morsbroicher Str.\",\n  \"Moselstr.\",\n  \"Moskauer Str.\",\n  \"Mozartstr.\",\n  \"Mühlenweg\",\n  \"Muhrgasse\",\n  \"Muldestr.\",\n  \"Mülhausener Str.\",\n  \"Mülheimer Str.\",\n  \"Münsters Gäßchen\",\n  \"Münzstr.\",\n  \"Müritzstr.\",\n  \"Myliusstr.\",\n  \"Nachtigallenweg\",\n  \"Nauener Str.\",\n  \"Neißestr.\",\n  \"Nelly-Sachs-Str.\",\n  \"Netzestr.\",\n  \"Neuendriesch\",\n  \"Neuenhausgasse\",\n  \"Neuenkamp\",\n  \"Neujudenhof\",\n  \"Neukronenberger Str.\",\n  \"Neustadtstr.\",\n  \"Nicolai-Hartmann-Str.\",\n  \"Niederblecher\",\n  \"Niederfeldstr.\",\n  \"Nietzschestr.\",\n  \"Nikolaus-Groß-Str.\",\n  \"Nobelstr.\",\n  \"Norderneystr.\",\n  \"Nordstr.\",\n  \"Ober dem Hof\",\n  \"Obere Lindenstr.\",\n  \"Obere Str.\",\n  \"Oberölbach\",\n  \"Odenthaler Str.\",\n  \"Oderstr.\",\n  \"Okerstr.\",\n  \"Olof-Palme-Str.\",\n  \"Ophovener Str.\",\n  \"Opladener Platz\",\n  \"Opladener Str.\",\n  \"Ortelsburger Str.\",\n  \"Oskar-Moll-Str.\",\n  \"Oskar-Schlemmer-Str.\",\n  \"Oststr.\",\n  \"Oswald-Spengler-Str.\",\n  \"Otto-Dix-Str.\",\n  \"Otto-Grimm-Str.\",\n  \"Otto-Hahn-Str.\",\n  \"Otto-Müller-Str.\",\n  \"Otto-Stange-Str.\",\n  \"Ottostr.\",\n  \"Otto-Varnhagen-Str.\",\n  \"Otto-Wels-Str.\",\n  \"Ottweilerstr.\",\n  \"Oulustr.\",\n  \"Overfeldweg\",\n  \"Pappelweg\",\n  \"Paracelsusstr.\",\n  \"Parkstr.\",\n  \"Pastor-Louis-Str.\",\n  \"Pastor-Scheibler-Str.\",\n  \"Pastorskamp\",\n  \"Paul-Klee-Str.\",\n  \"Paul-Löbe-Str.\",\n  \"Paulstr.\",\n  \"Peenestr.\",\n  \"Pescher Busch\",\n  \"Peschstr.\",\n  \"Pestalozzistr.\",\n  \"Peter-Grieß-Str.\",\n  \"Peter-Joseph-Lenné-Str.\",\n  \"Peter-Neuenheuser-Str.\",\n  \"Petersbergstr.\",\n  \"Peterstr.\",\n  \"Pfarrer-Jekel-Str.\",\n  \"Pfarrer-Klein-Str.\",\n  \"Pfarrer-Röhr-Str.\",\n  \"Pfeilshofstr.\",\n  \"Philipp-Ott-Str.\",\n  \"Piet-Mondrian-Str.\",\n  \"Platanenweg\",\n  \"Pommernstr.\",\n  \"Porschestr.\",\n  \"Poststr.\",\n  \"Potsdamer Str.\",\n  \"Pregelstr.\",\n  \"Prießnitzstr.\",\n  \"Pützdelle\",\n  \"Quarzstr.\",\n  \"Quettinger Str.\",\n  \"Rat-Deycks-Str.\",\n  \"Rathenaustr.\",\n  \"Ratherkämp\",\n  \"Ratiborer Str.\",\n  \"Raushofstr.\",\n  \"Regensburger Str.\",\n  \"Reinickendorfer Str.\",\n  \"Renkgasse\",\n  \"Rennbaumplatz\",\n  \"Rennbaumstr.\",\n  \"Reuschenberger Str.\",\n  \"Reusrather Str.\",\n  \"Reuterstr.\",\n  \"Rheinallee\",\n  \"Rheindorfer Str.\",\n  \"Rheinstr.\",\n  \"Rhein-Wupper-Platz\",\n  \"Richard-Wagner-Str.\",\n  \"Rilkestr.\",\n  \"Ringstr.\",\n  \"Robert-Blum-Str.\",\n  \"Robert-Koch-Str.\",\n  \"Robert-Medenwald-Str.\",\n  \"Rolandstr.\",\n  \"Romberg\",\n  \"Röntgenstr.\",\n  \"Roonstr.\",\n  \"Ropenstall\",\n  \"Ropenstaller Weg\",\n  \"Rosenthal\",\n  \"Rostocker Str.\",\n  \"Rotdornweg\",\n  \"Röttgerweg\",\n  \"Rückertstr.\",\n  \"Rudolf-Breitscheid-Str.\",\n  \"Rudolf-Mann-Platz\",\n  \"Rudolf-Stracke-Str.\",\n  \"Ruhlachplatz\",\n  \"Ruhlachstr.\",\n  \"Rüttersweg\",\n  \"Saalestr.\",\n  \"Saarbrücker Str.\",\n  \"Saarlauterner Str.\",\n  \"Saarstr.\",\n  \"Salamanderweg\",\n  \"Samlandstr.\",\n  \"Sanddornstr.\",\n  \"Sandstr.\",\n  \"Sauerbruchstr.\",\n  \"Schäfershütte\",\n  \"Scharnhorststr.\",\n  \"Scheffershof\",\n  \"Scheidemannstr.\",\n  \"Schellingstr.\",\n  \"Schenkendorfstr.\",\n  \"Schießbergstr.\",\n  \"Schillerstr.\",\n  \"Schlangenhecke\",\n  \"Schlebuscher Heide\",\n  \"Schlebuscher Str.\",\n  \"Schlebuschrath\",\n  \"Schlehdornstr.\",\n  \"Schleiermacherstr.\",\n  \"Schloßstr.\",\n  \"Schmalenbruch\",\n  \"Schnepfenflucht\",\n  \"Schöffenweg\",\n  \"Schöllerstr.\",\n  \"Schöne Aussicht\",\n  \"Schöneberger Str.\",\n  \"Schopenhauerstr.\",\n  \"Schubertplatz\",\n  \"Schubertstr.\",\n  \"Schulberg\",\n  \"Schulstr.\",\n  \"Schumannstr.\",\n  \"Schwalbenweg\",\n  \"Schwarzastr.\",\n  \"Sebastianusweg\",\n  \"Semmelweisstr.\",\n  \"Siebelplatz\",\n  \"Siemensstr.\",\n  \"Solinger Str.\",\n  \"Sonderburger Str.\",\n  \"Spandauer Str.\",\n  \"Speestr.\",\n  \"Sperberweg\",\n  \"Sperlingsweg\",\n  \"Spitzwegstr.\",\n  \"Sporrenberger Mühle\",\n  \"Spreestr.\",\n  \"St. Ingberter Str.\",\n  \"Starenweg\",\n  \"Stauffenbergstr.\",\n  \"Stefan-Zweig-Str.\",\n  \"Stegerwaldstr.\",\n  \"Steglitzer Str.\",\n  \"Steinbücheler Feld\",\n  \"Steinbücheler Str.\",\n  \"Steinstr.\",\n  \"Steinweg\",\n  \"Stephan-Lochner-Str.\",\n  \"Stephanusstr.\",\n  \"Stettiner Str.\",\n  \"Stixchesstr.\",\n  \"Stöckenstr.\",\n  \"Stralsunder Str.\",\n  \"Straßburger Str.\",\n  \"Stresemannplatz\",\n  \"Strombergstr.\",\n  \"Stromstr.\",\n  \"Stüttekofener Str.\",\n  \"Sudestr.\",\n  \"Sürderstr.\",\n  \"Syltstr.\",\n  \"Talstr.\",\n  \"Tannenbergstr.\",\n  \"Tannenweg\",\n  \"Taubenweg\",\n  \"Teitscheider Weg\",\n  \"Telegrafenstr.\",\n  \"Teltower Str.\",\n  \"Tempelhofer Str.\",\n  \"Theodor-Adorno-Str.\",\n  \"Theodor-Fliedner-Str.\",\n  \"Theodor-Gierath-Str.\",\n  \"Theodor-Haubach-Str.\",\n  \"Theodor-Heuss-Ring\",\n  \"Theodor-Storm-Str.\",\n  \"Theodorstr.\",\n  \"Thomas-Dehler-Str.\",\n  \"Thomas-Morus-Str.\",\n  \"Thomas-von-Aquin-Str.\",\n  \"Tönges Feld\",\n  \"Torstr.\",\n  \"Treptower Str.\",\n  \"Treuburger Str.\",\n  \"Uhlandstr.\",\n  \"Ulmenweg\",\n  \"Ulmer Str.\",\n  \"Ulrichstr.\",\n  \"Ulrich-von-Hassell-Str.\",\n  \"Umlag\",\n  \"Unstrutstr.\",\n  \"Unter dem Schildchen\",\n  \"Unterölbach\",\n  \"Unterstr.\",\n  \"Uppersberg\",\n  \"Van\\\\'t-Hoff-Str.\",\n  \"Veit-Stoß-Str.\",\n  \"Vereinsstr.\",\n  \"Viktor-Meyer-Str.\",\n  \"Vincent-van-Gogh-Str.\",\n  \"Virchowstr.\",\n  \"Voigtslach\",\n  \"Volhardstr.\",\n  \"Völklinger Str.\",\n  \"Von-Brentano-Str.\",\n  \"Von-Diergardt-Str.\",\n  \"Von-Eichendorff-Str.\",\n  \"Von-Ketteler-Str.\",\n  \"Von-Knoeringen-Str.\",\n  \"Von-Pettenkofer-Str.\",\n  \"Von-Siebold-Str.\",\n  \"Wacholderweg\",\n  \"Waldstr.\",\n  \"Walter-Flex-Str.\",\n  \"Walter-Hempel-Str.\",\n  \"Walter-Hochapfel-Str.\",\n  \"Walter-Nernst-Str.\",\n  \"Wannseestr.\",\n  \"Warnowstr.\",\n  \"Warthestr.\",\n  \"Weddigenstr.\",\n  \"Weichselstr.\",\n  \"Weidenstr.\",\n  \"Weidfeldstr.\",\n  \"Weiherfeld\",\n  \"Weiherstr.\",\n  \"Weinhäuser Str.\",\n  \"Weißdornweg\",\n  \"Weißenseestr.\",\n  \"Weizkamp\",\n  \"Werftstr.\",\n  \"Werkstättenstr.\",\n  \"Werner-Heisenberg-Str.\",\n  \"Werrastr.\",\n  \"Weyerweg\",\n  \"Widdauener Str.\",\n  \"Wiebertshof\",\n  \"Wiehbachtal\",\n  \"Wiembachallee\",\n  \"Wiesdorfer Platz\",\n  \"Wiesenstr.\",\n  \"Wilhelm-Busch-Str.\",\n  \"Wilhelm-Hastrich-Str.\",\n  \"Wilhelm-Leuschner-Str.\",\n  \"Wilhelm-Liebknecht-Str.\",\n  \"Wilhelmsgasse\",\n  \"Wilhelmstr.\",\n  \"Willi-Baumeister-Str.\",\n  \"Willy-Brandt-Ring\",\n  \"Winand-Rossi-Str.\",\n  \"Windthorststr.\",\n  \"Winkelweg\",\n  \"Winterberg\",\n  \"Wittenbergstr.\",\n  \"Wolf-Vostell-Str.\",\n  \"Wolkenburgstr.\",\n  \"Wupperstr.\",\n  \"Wuppertalstr.\",\n  \"Wüstenhof\",\n  \"Yitzhak-Rabin-Str.\",\n  \"Zauberkuhle\",\n  \"Zedernweg\",\n  \"Zehlendorfer Str.\",\n  \"Zehntenweg\",\n  \"Zeisigweg\",\n  \"Zeppelinstr.\",\n  \"Zschopaustr.\",\n  \"Zum Claashäuschen\",\n  \"Zündhütchenweg\",\n  \"Zur Alten Brauerei\",\n  \"Zur alten Fabrik\"\n];\n\n},{}],111:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"+49-1##-#######\",\n  \"+49-1###-########\"\n];\n\n},{}],112:[function(require,module,exports){\nvar cell_phone = {};\nmodule['exports'] = cell_phone;\ncell_phone.formats = require(\"./formats\");\n\n},{\"./formats\":111}],113:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.legal_form = require(\"./legal_form\");\ncompany.name = require(\"./name\");\n\n},{\"./legal_form\":114,\"./name\":115,\"./suffix\":116}],114:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"GmbH\",\n  \"AG\",\n  \"Gruppe\",\n  \"KG\",\n  \"GmbH & Co. KG\",\n  \"UG\",\n  \"OHG\"\n];\n\n},{}],115:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name}-#{Name.last_name}\",\n  \"#{Name.last_name}, #{Name.last_name} und #{Name.last_name}\"\n];\n\n},{}],116:[function(require,module,exports){\nmodule.exports=require(114)\n},{\"/Users/a/dev/faker.js/lib/locales/de/company/legal_form.js\":114}],117:[function(require,module,exports){\nvar de = {};\nmodule['exports'] = de;\nde.title = \"German\";\nde.address = require(\"./address\");\nde.company = require(\"./company\");\nde.internet = require(\"./internet\");\nde.lorem = require(\"./lorem\");\nde.name = require(\"./name\");\nde.phone_number = require(\"./phone_number\");\nde.cell_phone = require(\"./cell_phone\");\n},{\"./address\":103,\"./cell_phone\":112,\"./company\":113,\"./internet\":120,\"./lorem\":121,\"./name\":124,\"./phone_number\":130}],118:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\",\n  \"de\",\n  \"ch\"\n];\n\n},{}],119:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.com\",\n  \"hotmail.com\"\n];\n\n},{}],120:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":118,\"./free_email\":119,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],121:[function(require,module,exports){\nvar lorem = {};\nmodule['exports'] = lorem;\nlorem.words = require(\"./words\");\n\n},{\"./words\":122}],122:[function(require,module,exports){\nmodule.exports=require(85)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/words.js\":85}],123:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aaron\",\n  \"Abdul\",\n  \"Abdullah\",\n  \"Adam\",\n  \"Adrian\",\n  \"Adriano\",\n  \"Ahmad\",\n  \"Ahmed\",\n  \"Ahmet\",\n  \"Alan\",\n  \"Albert\",\n  \"Alessandro\",\n  \"Alessio\",\n  \"Alex\",\n  \"Alexander\",\n  \"Alfred\",\n  \"Ali\",\n  \"Amar\",\n  \"Amir\",\n  \"Amon\",\n  \"Andre\",\n  \"Andreas\",\n  \"Andrew\",\n  \"Angelo\",\n  \"Ansgar\",\n  \"Anthony\",\n  \"Anton\",\n  \"Antonio\",\n  \"Arda\",\n  \"Arian\",\n  \"Armin\",\n  \"Arne\",\n  \"Arno\",\n  \"Arthur\",\n  \"Artur\",\n  \"Arved\",\n  \"Arvid\",\n  \"Ayman\",\n  \"Baran\",\n  \"Baris\",\n  \"Bastian\",\n  \"Batuhan\",\n  \"Bela\",\n  \"Ben\",\n  \"Benedikt\",\n  \"Benjamin\",\n  \"Bennet\",\n  \"Bennett\",\n  \"Benno\",\n  \"Bent\",\n  \"Berat\",\n  \"Berkay\",\n  \"Bernd\",\n  \"Bilal\",\n  \"Bjarne\",\n  \"Björn\",\n  \"Bo\",\n  \"Boris\",\n  \"Brandon\",\n  \"Brian\",\n  \"Bruno\",\n  \"Bryan\",\n  \"Burak\",\n  \"Calvin\",\n  \"Can\",\n  \"Carl\",\n  \"Carlo\",\n  \"Carlos\",\n  \"Caspar\",\n  \"Cedric\",\n  \"Cedrik\",\n  \"Cem\",\n  \"Charlie\",\n  \"Chris\",\n  \"Christian\",\n  \"Christiano\",\n  \"Christoph\",\n  \"Christopher\",\n  \"Claas\",\n  \"Clemens\",\n  \"Colin\",\n  \"Collin\",\n  \"Conner\",\n  \"Connor\",\n  \"Constantin\",\n  \"Corvin\",\n  \"Curt\",\n  \"Damian\",\n  \"Damien\",\n  \"Daniel\",\n  \"Danilo\",\n  \"Danny\",\n  \"Darian\",\n  \"Dario\",\n  \"Darius\",\n  \"Darren\",\n  \"David\",\n  \"Davide\",\n  \"Davin\",\n  \"Dean\",\n  \"Deniz\",\n  \"Dennis\",\n  \"Denny\",\n  \"Devin\",\n  \"Diego\",\n  \"Dion\",\n  \"Domenic\",\n  \"Domenik\",\n  \"Dominic\",\n  \"Dominik\",\n  \"Dorian\",\n  \"Dustin\",\n  \"Dylan\",\n  \"Ecrin\",\n  \"Eddi\",\n  \"Eddy\",\n  \"Edgar\",\n  \"Edwin\",\n  \"Efe\",\n  \"Ege\",\n  \"Elia\",\n  \"Eliah\",\n  \"Elias\",\n  \"Elijah\",\n  \"Emanuel\",\n  \"Emil\",\n  \"Emilian\",\n  \"Emilio\",\n  \"Emir\",\n  \"Emirhan\",\n  \"Emre\",\n  \"Enes\",\n  \"Enno\",\n  \"Enrico\",\n  \"Eren\",\n  \"Eric\",\n  \"Erik\",\n  \"Etienne\",\n  \"Fabian\",\n  \"Fabien\",\n  \"Fabio\",\n  \"Fabrice\",\n  \"Falk\",\n  \"Felix\",\n  \"Ferdinand\",\n  \"Fiete\",\n  \"Filip\",\n  \"Finlay\",\n  \"Finley\",\n  \"Finn\",\n  \"Finnley\",\n  \"Florian\",\n  \"Francesco\",\n  \"Franz\",\n  \"Frederic\",\n  \"Frederick\",\n  \"Frederik\",\n  \"Friedrich\",\n  \"Fritz\",\n  \"Furkan\",\n  \"Fynn\",\n  \"Gabriel\",\n  \"Georg\",\n  \"Gerrit\",\n  \"Gian\",\n  \"Gianluca\",\n  \"Gino\",\n  \"Giuliano\",\n  \"Giuseppe\",\n  \"Gregor\",\n  \"Gustav\",\n  \"Hagen\",\n  \"Hamza\",\n  \"Hannes\",\n  \"Hanno\",\n  \"Hans\",\n  \"Hasan\",\n  \"Hassan\",\n  \"Hauke\",\n  \"Hendrik\",\n  \"Hennes\",\n  \"Henning\",\n  \"Henri\",\n  \"Henrick\",\n  \"Henrik\",\n  \"Henry\",\n  \"Hugo\",\n  \"Hussein\",\n  \"Ian\",\n  \"Ibrahim\",\n  \"Ilias\",\n  \"Ilja\",\n  \"Ilyas\",\n  \"Immanuel\",\n  \"Ismael\",\n  \"Ismail\",\n  \"Ivan\",\n  \"Iven\",\n  \"Jack\",\n  \"Jacob\",\n  \"Jaden\",\n  \"Jakob\",\n  \"Jamal\",\n  \"James\",\n  \"Jamie\",\n  \"Jan\",\n  \"Janek\",\n  \"Janis\",\n  \"Janne\",\n  \"Jannek\",\n  \"Jannes\",\n  \"Jannik\",\n  \"Jannis\",\n  \"Jano\",\n  \"Janosch\",\n  \"Jared\",\n  \"Jari\",\n  \"Jarne\",\n  \"Jarno\",\n  \"Jaron\",\n  \"Jason\",\n  \"Jasper\",\n  \"Jay\",\n  \"Jayden\",\n  \"Jayson\",\n  \"Jean\",\n  \"Jens\",\n  \"Jeremias\",\n  \"Jeremie\",\n  \"Jeremy\",\n  \"Jermaine\",\n  \"Jerome\",\n  \"Jesper\",\n  \"Jesse\",\n  \"Jim\",\n  \"Jimmy\",\n  \"Joe\",\n  \"Joel\",\n  \"Joey\",\n  \"Johann\",\n  \"Johannes\",\n  \"John\",\n  \"Johnny\",\n  \"Jon\",\n  \"Jona\",\n  \"Jonah\",\n  \"Jonas\",\n  \"Jonathan\",\n  \"Jonte\",\n  \"Joost\",\n  \"Jordan\",\n  \"Joris\",\n  \"Joscha\",\n  \"Joschua\",\n  \"Josef\",\n  \"Joseph\",\n  \"Josh\",\n  \"Joshua\",\n  \"Josua\",\n  \"Juan\",\n  \"Julian\",\n  \"Julien\",\n  \"Julius\",\n  \"Juri\",\n  \"Justin\",\n  \"Justus\",\n  \"Kaan\",\n  \"Kai\",\n  \"Kalle\",\n  \"Karim\",\n  \"Karl\",\n  \"Karlo\",\n  \"Kay\",\n  \"Keanu\",\n  \"Kenan\",\n  \"Kenny\",\n  \"Keno\",\n  \"Kerem\",\n  \"Kerim\",\n  \"Kevin\",\n  \"Kian\",\n  \"Kilian\",\n  \"Kim\",\n  \"Kimi\",\n  \"Kjell\",\n  \"Klaas\",\n  \"Klemens\",\n  \"Konrad\",\n  \"Konstantin\",\n  \"Koray\",\n  \"Korbinian\",\n  \"Kurt\",\n  \"Lars\",\n  \"Lasse\",\n  \"Laurence\",\n  \"Laurens\",\n  \"Laurenz\",\n  \"Laurin\",\n  \"Lean\",\n  \"Leander\",\n  \"Leandro\",\n  \"Leif\",\n  \"Len\",\n  \"Lenn\",\n  \"Lennard\",\n  \"Lennart\",\n  \"Lennert\",\n  \"Lennie\",\n  \"Lennox\",\n  \"Lenny\",\n  \"Leo\",\n  \"Leon\",\n  \"Leonard\",\n  \"Leonardo\",\n  \"Leonhard\",\n  \"Leonidas\",\n  \"Leopold\",\n  \"Leroy\",\n  \"Levent\",\n  \"Levi\",\n  \"Levin\",\n  \"Lewin\",\n  \"Lewis\",\n  \"Liam\",\n  \"Lian\",\n  \"Lias\",\n  \"Lino\",\n  \"Linus\",\n  \"Lio\",\n  \"Lion\",\n  \"Lionel\",\n  \"Logan\",\n  \"Lorenz\",\n  \"Lorenzo\",\n  \"Loris\",\n  \"Louis\",\n  \"Luan\",\n  \"Luc\",\n  \"Luca\",\n  \"Lucas\",\n  \"Lucian\",\n  \"Lucien\",\n  \"Ludwig\",\n  \"Luis\",\n  \"Luiz\",\n  \"Luk\",\n  \"Luka\",\n  \"Lukas\",\n  \"Luke\",\n  \"Lutz\",\n  \"Maddox\",\n  \"Mads\",\n  \"Magnus\",\n  \"Maik\",\n  \"Maksim\",\n  \"Malik\",\n  \"Malte\",\n  \"Manuel\",\n  \"Marc\",\n  \"Marcel\",\n  \"Marco\",\n  \"Marcus\",\n  \"Marek\",\n  \"Marian\",\n  \"Mario\",\n  \"Marius\",\n  \"Mark\",\n  \"Marko\",\n  \"Markus\",\n  \"Marlo\",\n  \"Marlon\",\n  \"Marten\",\n  \"Martin\",\n  \"Marvin\",\n  \"Marwin\",\n  \"Mateo\",\n  \"Mathis\",\n  \"Matis\",\n  \"Mats\",\n  \"Matteo\",\n  \"Mattes\",\n  \"Matthias\",\n  \"Matthis\",\n  \"Matti\",\n  \"Mattis\",\n  \"Maurice\",\n  \"Max\",\n  \"Maxim\",\n  \"Maximilian\",\n  \"Mehmet\",\n  \"Meik\",\n  \"Melvin\",\n  \"Merlin\",\n  \"Mert\",\n  \"Michael\",\n  \"Michel\",\n  \"Mick\",\n  \"Miguel\",\n  \"Mika\",\n  \"Mikail\",\n  \"Mike\",\n  \"Milan\",\n  \"Milo\",\n  \"Mio\",\n  \"Mirac\",\n  \"Mirco\",\n  \"Mirko\",\n  \"Mohamed\",\n  \"Mohammad\",\n  \"Mohammed\",\n  \"Moritz\",\n  \"Morten\",\n  \"Muhammed\",\n  \"Murat\",\n  \"Mustafa\",\n  \"Nathan\",\n  \"Nathanael\",\n  \"Nelson\",\n  \"Neo\",\n  \"Nevio\",\n  \"Nick\",\n  \"Niclas\",\n  \"Nico\",\n  \"Nicolai\",\n  \"Nicolas\",\n  \"Niels\",\n  \"Nikita\",\n  \"Niklas\",\n  \"Niko\",\n  \"Nikolai\",\n  \"Nikolas\",\n  \"Nils\",\n  \"Nino\",\n  \"Noah\",\n  \"Noel\",\n  \"Norman\",\n  \"Odin\",\n  \"Oke\",\n  \"Ole\",\n  \"Oliver\",\n  \"Omar\",\n  \"Onur\",\n  \"Oscar\",\n  \"Oskar\",\n  \"Pascal\",\n  \"Patrice\",\n  \"Patrick\",\n  \"Paul\",\n  \"Peer\",\n  \"Pepe\",\n  \"Peter\",\n  \"Phil\",\n  \"Philip\",\n  \"Philipp\",\n  \"Pierre\",\n  \"Piet\",\n  \"Pit\",\n  \"Pius\",\n  \"Quentin\",\n  \"Quirin\",\n  \"Rafael\",\n  \"Raik\",\n  \"Ramon\",\n  \"Raphael\",\n  \"Rasmus\",\n  \"Raul\",\n  \"Rayan\",\n  \"René\",\n  \"Ricardo\",\n  \"Riccardo\",\n  \"Richard\",\n  \"Rick\",\n  \"Rico\",\n  \"Robert\",\n  \"Robin\",\n  \"Rocco\",\n  \"Roman\",\n  \"Romeo\",\n  \"Ron\",\n  \"Ruben\",\n  \"Ryan\",\n  \"Said\",\n  \"Salih\",\n  \"Sam\",\n  \"Sami\",\n  \"Sammy\",\n  \"Samuel\",\n  \"Sandro\",\n  \"Santino\",\n  \"Sascha\",\n  \"Sean\",\n  \"Sebastian\",\n  \"Selim\",\n  \"Semih\",\n  \"Shawn\",\n  \"Silas\",\n  \"Simeon\",\n  \"Simon\",\n  \"Sinan\",\n  \"Sky\",\n  \"Stefan\",\n  \"Steffen\",\n  \"Stephan\",\n  \"Steve\",\n  \"Steven\",\n  \"Sven\",\n  \"Sönke\",\n  \"Sören\",\n  \"Taha\",\n  \"Tamino\",\n  \"Tammo\",\n  \"Tarik\",\n  \"Tayler\",\n  \"Taylor\",\n  \"Teo\",\n  \"Theo\",\n  \"Theodor\",\n  \"Thies\",\n  \"Thilo\",\n  \"Thomas\",\n  \"Thorben\",\n  \"Thore\",\n  \"Thorge\",\n  \"Tiago\",\n  \"Til\",\n  \"Till\",\n  \"Tillmann\",\n  \"Tim\",\n  \"Timm\",\n  \"Timo\",\n  \"Timon\",\n  \"Timothy\",\n  \"Tino\",\n  \"Titus\",\n  \"Tizian\",\n  \"Tjark\",\n  \"Tobias\",\n  \"Tom\",\n  \"Tommy\",\n  \"Toni\",\n  \"Tony\",\n  \"Torben\",\n  \"Tore\",\n  \"Tristan\",\n  \"Tyler\",\n  \"Tyron\",\n  \"Umut\",\n  \"Valentin\",\n  \"Valentino\",\n  \"Veit\",\n  \"Victor\",\n  \"Viktor\",\n  \"Vin\",\n  \"Vincent\",\n  \"Vito\",\n  \"Vitus\",\n  \"Wilhelm\",\n  \"Willi\",\n  \"William\",\n  \"Willy\",\n  \"Xaver\",\n  \"Yannic\",\n  \"Yannick\",\n  \"Yannik\",\n  \"Yannis\",\n  \"Yasin\",\n  \"Youssef\",\n  \"Yunus\",\n  \"Yusuf\",\n  \"Yven\",\n  \"Yves\",\n  \"Ömer\",\n  \"Aaliyah\",\n  \"Abby\",\n  \"Abigail\",\n  \"Ada\",\n  \"Adelina\",\n  \"Adriana\",\n  \"Aileen\",\n  \"Aimee\",\n  \"Alana\",\n  \"Alea\",\n  \"Alena\",\n  \"Alessa\",\n  \"Alessia\",\n  \"Alexa\",\n  \"Alexandra\",\n  \"Alexia\",\n  \"Alexis\",\n  \"Aleyna\",\n  \"Alia\",\n  \"Alica\",\n  \"Alice\",\n  \"Alicia\",\n  \"Alina\",\n  \"Alisa\",\n  \"Alisha\",\n  \"Alissa\",\n  \"Aliya\",\n  \"Aliyah\",\n  \"Allegra\",\n  \"Alma\",\n  \"Alyssa\",\n  \"Amalia\",\n  \"Amanda\",\n  \"Amelia\",\n  \"Amelie\",\n  \"Amina\",\n  \"Amira\",\n  \"Amy\",\n  \"Ana\",\n  \"Anabel\",\n  \"Anastasia\",\n  \"Andrea\",\n  \"Angela\",\n  \"Angelina\",\n  \"Angelique\",\n  \"Anja\",\n  \"Ann\",\n  \"Anna\",\n  \"Annabel\",\n  \"Annabell\",\n  \"Annabelle\",\n  \"Annalena\",\n  \"Anne\",\n  \"Anneke\",\n  \"Annelie\",\n  \"Annemarie\",\n  \"Anni\",\n  \"Annie\",\n  \"Annika\",\n  \"Anny\",\n  \"Anouk\",\n  \"Antonia\",\n  \"Arda\",\n  \"Ariana\",\n  \"Ariane\",\n  \"Arwen\",\n  \"Ashley\",\n  \"Asya\",\n  \"Aurelia\",\n  \"Aurora\",\n  \"Ava\",\n  \"Ayleen\",\n  \"Aylin\",\n  \"Ayse\",\n  \"Azra\",\n  \"Betty\",\n  \"Bianca\",\n  \"Bianka\",\n  \"Caitlin\",\n  \"Cara\",\n  \"Carina\",\n  \"Carla\",\n  \"Carlotta\",\n  \"Carmen\",\n  \"Carolin\",\n  \"Carolina\",\n  \"Caroline\",\n  \"Cassandra\",\n  \"Catharina\",\n  \"Catrin\",\n  \"Cecile\",\n  \"Cecilia\",\n  \"Celia\",\n  \"Celina\",\n  \"Celine\",\n  \"Ceyda\",\n  \"Ceylin\",\n  \"Chantal\",\n  \"Charleen\",\n  \"Charlotta\",\n  \"Charlotte\",\n  \"Chayenne\",\n  \"Cheyenne\",\n  \"Chiara\",\n  \"Christin\",\n  \"Christina\",\n  \"Cindy\",\n  \"Claire\",\n  \"Clara\",\n  \"Clarissa\",\n  \"Colleen\",\n  \"Collien\",\n  \"Cora\",\n  \"Corinna\",\n  \"Cosima\",\n  \"Dana\",\n  \"Daniela\",\n  \"Daria\",\n  \"Darleen\",\n  \"Defne\",\n  \"Delia\",\n  \"Denise\",\n  \"Diana\",\n  \"Dilara\",\n  \"Dina\",\n  \"Dorothea\",\n  \"Ecrin\",\n  \"Eda\",\n  \"Eileen\",\n  \"Ela\",\n  \"Elaine\",\n  \"Elanur\",\n  \"Elea\",\n  \"Elena\",\n  \"Eleni\",\n  \"Eleonora\",\n  \"Eliana\",\n  \"Elif\",\n  \"Elina\",\n  \"Elisa\",\n  \"Elisabeth\",\n  \"Ella\",\n  \"Ellen\",\n  \"Elli\",\n  \"Elly\",\n  \"Elsa\",\n  \"Emelie\",\n  \"Emely\",\n  \"Emilia\",\n  \"Emilie\",\n  \"Emily\",\n  \"Emma\",\n  \"Emmely\",\n  \"Emmi\",\n  \"Emmy\",\n  \"Enie\",\n  \"Enna\",\n  \"Enya\",\n  \"Esma\",\n  \"Estelle\",\n  \"Esther\",\n  \"Eva\",\n  \"Evelin\",\n  \"Evelina\",\n  \"Eveline\",\n  \"Evelyn\",\n  \"Fabienne\",\n  \"Fatima\",\n  \"Fatma\",\n  \"Felicia\",\n  \"Felicitas\",\n  \"Felina\",\n  \"Femke\",\n  \"Fenja\",\n  \"Fine\",\n  \"Finia\",\n  \"Finja\",\n  \"Finnja\",\n  \"Fiona\",\n  \"Flora\",\n  \"Florentine\",\n  \"Francesca\",\n  \"Franka\",\n  \"Franziska\",\n  \"Frederike\",\n  \"Freya\",\n  \"Frida\",\n  \"Frieda\",\n  \"Friederike\",\n  \"Giada\",\n  \"Gina\",\n  \"Giulia\",\n  \"Giuliana\",\n  \"Greta\",\n  \"Hailey\",\n  \"Hana\",\n  \"Hanna\",\n  \"Hannah\",\n  \"Heidi\",\n  \"Helen\",\n  \"Helena\",\n  \"Helene\",\n  \"Helin\",\n  \"Henriette\",\n  \"Henrike\",\n  \"Hermine\",\n  \"Ida\",\n  \"Ilayda\",\n  \"Imke\",\n  \"Ina\",\n  \"Ines\",\n  \"Inga\",\n  \"Inka\",\n  \"Irem\",\n  \"Isa\",\n  \"Isabel\",\n  \"Isabell\",\n  \"Isabella\",\n  \"Isabelle\",\n  \"Ivonne\",\n  \"Jacqueline\",\n  \"Jamie\",\n  \"Jamila\",\n  \"Jana\",\n  \"Jane\",\n  \"Janin\",\n  \"Janina\",\n  \"Janine\",\n  \"Janna\",\n  \"Janne\",\n  \"Jara\",\n  \"Jasmin\",\n  \"Jasmina\",\n  \"Jasmine\",\n  \"Jella\",\n  \"Jenna\",\n  \"Jennifer\",\n  \"Jenny\",\n  \"Jessica\",\n  \"Jessy\",\n  \"Jette\",\n  \"Jil\",\n  \"Jill\",\n  \"Joana\",\n  \"Joanna\",\n  \"Joelina\",\n  \"Joeline\",\n  \"Joelle\",\n  \"Johanna\",\n  \"Joleen\",\n  \"Jolie\",\n  \"Jolien\",\n  \"Jolin\",\n  \"Jolina\",\n  \"Joline\",\n  \"Jona\",\n  \"Jonah\",\n  \"Jonna\",\n  \"Josefin\",\n  \"Josefine\",\n  \"Josephin\",\n  \"Josephine\",\n  \"Josie\",\n  \"Josy\",\n  \"Joy\",\n  \"Joyce\",\n  \"Judith\",\n  \"Judy\",\n  \"Jule\",\n  \"Julia\",\n  \"Juliana\",\n  \"Juliane\",\n  \"Julie\",\n  \"Julienne\",\n  \"Julika\",\n  \"Julina\",\n  \"Juna\",\n  \"Justine\",\n  \"Kaja\",\n  \"Karina\",\n  \"Karla\",\n  \"Karlotta\",\n  \"Karolina\",\n  \"Karoline\",\n  \"Kassandra\",\n  \"Katarina\",\n  \"Katharina\",\n  \"Kathrin\",\n  \"Katja\",\n  \"Katrin\",\n  \"Kaya\",\n  \"Kayra\",\n  \"Kiana\",\n  \"Kiara\",\n  \"Kim\",\n  \"Kimberley\",\n  \"Kimberly\",\n  \"Kira\",\n  \"Klara\",\n  \"Korinna\",\n  \"Kristin\",\n  \"Kyra\",\n  \"Laila\",\n  \"Lana\",\n  \"Lara\",\n  \"Larissa\",\n  \"Laura\",\n  \"Laureen\",\n  \"Lavinia\",\n  \"Lea\",\n  \"Leah\",\n  \"Leana\",\n  \"Leandra\",\n  \"Leann\",\n  \"Lee\",\n  \"Leila\",\n  \"Lena\",\n  \"Lene\",\n  \"Leni\",\n  \"Lenia\",\n  \"Lenja\",\n  \"Lenya\",\n  \"Leona\",\n  \"Leoni\",\n  \"Leonie\",\n  \"Leonora\",\n  \"Leticia\",\n  \"Letizia\",\n  \"Levke\",\n  \"Leyla\",\n  \"Lia\",\n  \"Liah\",\n  \"Liana\",\n  \"Lili\",\n  \"Lilia\",\n  \"Lilian\",\n  \"Liliana\",\n  \"Lilith\",\n  \"Lilli\",\n  \"Lillian\",\n  \"Lilly\",\n  \"Lily\",\n  \"Lina\",\n  \"Linda\",\n  \"Lindsay\",\n  \"Line\",\n  \"Linn\",\n  \"Linnea\",\n  \"Lisa\",\n  \"Lisann\",\n  \"Lisanne\",\n  \"Liv\",\n  \"Livia\",\n  \"Liz\",\n  \"Lola\",\n  \"Loreen\",\n  \"Lorena\",\n  \"Lotta\",\n  \"Lotte\",\n  \"Louisa\",\n  \"Louise\",\n  \"Luana\",\n  \"Luca\",\n  \"Lucia\",\n  \"Lucie\",\n  \"Lucienne\",\n  \"Lucy\",\n  \"Luisa\",\n  \"Luise\",\n  \"Luka\",\n  \"Luna\",\n  \"Luzie\",\n  \"Lya\",\n  \"Lydia\",\n  \"Lyn\",\n  \"Lynn\",\n  \"Madeleine\",\n  \"Madita\",\n  \"Madleen\",\n  \"Madlen\",\n  \"Magdalena\",\n  \"Maike\",\n  \"Mailin\",\n  \"Maira\",\n  \"Maja\",\n  \"Malena\",\n  \"Malia\",\n  \"Malin\",\n  \"Malina\",\n  \"Mandy\",\n  \"Mara\",\n  \"Marah\",\n  \"Mareike\",\n  \"Maren\",\n  \"Maria\",\n  \"Mariam\",\n  \"Marie\",\n  \"Marieke\",\n  \"Mariella\",\n  \"Marika\",\n  \"Marina\",\n  \"Marisa\",\n  \"Marissa\",\n  \"Marit\",\n  \"Marla\",\n  \"Marleen\",\n  \"Marlen\",\n  \"Marlena\",\n  \"Marlene\",\n  \"Marta\",\n  \"Martha\",\n  \"Mary\",\n  \"Maryam\",\n  \"Mathilda\",\n  \"Mathilde\",\n  \"Matilda\",\n  \"Maxi\",\n  \"Maxima\",\n  \"Maxine\",\n  \"Maya\",\n  \"Mayra\",\n  \"Medina\",\n  \"Medine\",\n  \"Meike\",\n  \"Melanie\",\n  \"Melek\",\n  \"Melike\",\n  \"Melina\",\n  \"Melinda\",\n  \"Melis\",\n  \"Melisa\",\n  \"Melissa\",\n  \"Merle\",\n  \"Merve\",\n  \"Meryem\",\n  \"Mette\",\n  \"Mia\",\n  \"Michaela\",\n  \"Michelle\",\n  \"Mieke\",\n  \"Mila\",\n  \"Milana\",\n  \"Milena\",\n  \"Milla\",\n  \"Mina\",\n  \"Mira\",\n  \"Miray\",\n  \"Miriam\",\n  \"Mirja\",\n  \"Mona\",\n  \"Monique\",\n  \"Nadine\",\n  \"Nadja\",\n  \"Naemi\",\n  \"Nancy\",\n  \"Naomi\",\n  \"Natalia\",\n  \"Natalie\",\n  \"Nathalie\",\n  \"Neele\",\n  \"Nela\",\n  \"Nele\",\n  \"Nelli\",\n  \"Nelly\",\n  \"Nia\",\n  \"Nicole\",\n  \"Nika\",\n  \"Nike\",\n  \"Nikita\",\n  \"Nila\",\n  \"Nina\",\n  \"Nisa\",\n  \"Noemi\",\n  \"Nora\",\n  \"Olivia\",\n  \"Patricia\",\n  \"Patrizia\",\n  \"Paula\",\n  \"Paulina\",\n  \"Pauline\",\n  \"Penelope\",\n  \"Philine\",\n  \"Phoebe\",\n  \"Pia\",\n  \"Rahel\",\n  \"Rania\",\n  \"Rebecca\",\n  \"Rebekka\",\n  \"Riana\",\n  \"Rieke\",\n  \"Rike\",\n  \"Romina\",\n  \"Romy\",\n  \"Ronja\",\n  \"Rosa\",\n  \"Rosalie\",\n  \"Ruby\",\n  \"Sabrina\",\n  \"Sahra\",\n  \"Sally\",\n  \"Salome\",\n  \"Samantha\",\n  \"Samia\",\n  \"Samira\",\n  \"Sandra\",\n  \"Sandy\",\n  \"Sanja\",\n  \"Saphira\",\n  \"Sara\",\n  \"Sarah\",\n  \"Saskia\",\n  \"Selin\",\n  \"Selina\",\n  \"Selma\",\n  \"Sena\",\n  \"Sidney\",\n  \"Sienna\",\n  \"Silja\",\n  \"Sina\",\n  \"Sinja\",\n  \"Smilla\",\n  \"Sofia\",\n  \"Sofie\",\n  \"Sonja\",\n  \"Sophia\",\n  \"Sophie\",\n  \"Soraya\",\n  \"Stefanie\",\n  \"Stella\",\n  \"Stephanie\",\n  \"Stina\",\n  \"Sude\",\n  \"Summer\",\n  \"Susanne\",\n  \"Svea\",\n  \"Svenja\",\n  \"Sydney\",\n  \"Tabea\",\n  \"Talea\",\n  \"Talia\",\n  \"Tamara\",\n  \"Tamia\",\n  \"Tamina\",\n  \"Tanja\",\n  \"Tara\",\n  \"Tarja\",\n  \"Teresa\",\n  \"Tessa\",\n  \"Thalea\",\n  \"Thalia\",\n  \"Thea\",\n  \"Theresa\",\n  \"Tia\",\n  \"Tina\",\n  \"Tomke\",\n  \"Tuana\",\n  \"Valentina\",\n  \"Valeria\",\n  \"Valerie\",\n  \"Vanessa\",\n  \"Vera\",\n  \"Veronika\",\n  \"Victoria\",\n  \"Viktoria\",\n  \"Viola\",\n  \"Vivian\",\n  \"Vivien\",\n  \"Vivienne\",\n  \"Wibke\",\n  \"Wiebke\",\n  \"Xenia\",\n  \"Yara\",\n  \"Yaren\",\n  \"Yasmin\",\n  \"Ylvi\",\n  \"Ylvie\",\n  \"Yvonne\",\n  \"Zara\",\n  \"Zehra\",\n  \"Zeynep\",\n  \"Zoe\",\n  \"Zoey\",\n  \"Zoé\"\n];\n\n},{}],124:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.nobility_title_prefix = require(\"./nobility_title_prefix\");\nname.name = require(\"./name\");\n\n},{\"./first_name\":123,\"./last_name\":125,\"./name\":126,\"./nobility_title_prefix\":127,\"./prefix\":128}],125:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abel\",\n  \"Abicht\",\n  \"Abraham\",\n  \"Abramovic\",\n  \"Abt\",\n  \"Achilles\",\n  \"Achkinadze\",\n  \"Ackermann\",\n  \"Adam\",\n  \"Adams\",\n  \"Ade\",\n  \"Agostini\",\n  \"Ahlke\",\n  \"Ahrenberg\",\n  \"Ahrens\",\n  \"Aigner\",\n  \"Albert\",\n  \"Albrecht\",\n  \"Alexa\",\n  \"Alexander\",\n  \"Alizadeh\",\n  \"Allgeyer\",\n  \"Amann\",\n  \"Amberg\",\n  \"Anding\",\n  \"Anggreny\",\n  \"Apitz\",\n  \"Arendt\",\n  \"Arens\",\n  \"Arndt\",\n  \"Aryee\",\n  \"Aschenbroich\",\n  \"Assmus\",\n  \"Astafei\",\n  \"Auer\",\n  \"Axmann\",\n  \"Baarck\",\n  \"Bachmann\",\n  \"Badane\",\n  \"Bader\",\n  \"Baganz\",\n  \"Bahl\",\n  \"Bak\",\n  \"Balcer\",\n  \"Balck\",\n  \"Balkow\",\n  \"Balnuweit\",\n  \"Balzer\",\n  \"Banse\",\n  \"Barr\",\n  \"Bartels\",\n  \"Barth\",\n  \"Barylla\",\n  \"Baseda\",\n  \"Battke\",\n  \"Bauer\",\n  \"Bauermeister\",\n  \"Baumann\",\n  \"Baumeister\",\n  \"Bauschinger\",\n  \"Bauschke\",\n  \"Bayer\",\n  \"Beavogui\",\n  \"Beck\",\n  \"Beckel\",\n  \"Becker\",\n  \"Beckmann\",\n  \"Bedewitz\",\n  \"Beele\",\n  \"Beer\",\n  \"Beggerow\",\n  \"Beh\",\n  \"Behr\",\n  \"Behrenbruch\",\n  \"Belz\",\n  \"Bender\",\n  \"Benecke\",\n  \"Benner\",\n  \"Benninger\",\n  \"Benzing\",\n  \"Berends\",\n  \"Berger\",\n  \"Berner\",\n  \"Berning\",\n  \"Bertenbreiter\",\n  \"Best\",\n  \"Bethke\",\n  \"Betz\",\n  \"Beushausen\",\n  \"Beutelspacher\",\n  \"Beyer\",\n  \"Biba\",\n  \"Bichler\",\n  \"Bickel\",\n  \"Biedermann\",\n  \"Bieler\",\n  \"Bielert\",\n  \"Bienasch\",\n  \"Bienias\",\n  \"Biesenbach\",\n  \"Bigdeli\",\n  \"Birkemeyer\",\n  \"Bittner\",\n  \"Blank\",\n  \"Blaschek\",\n  \"Blassneck\",\n  \"Bloch\",\n  \"Blochwitz\",\n  \"Blockhaus\",\n  \"Blum\",\n  \"Blume\",\n  \"Bock\",\n  \"Bode\",\n  \"Bogdashin\",\n  \"Bogenrieder\",\n  \"Bohge\",\n  \"Bolm\",\n  \"Borgschulze\",\n  \"Bork\",\n  \"Bormann\",\n  \"Bornscheuer\",\n  \"Borrmann\",\n  \"Borsch\",\n  \"Boruschewski\",\n  \"Bos\",\n  \"Bosler\",\n  \"Bourrouag\",\n  \"Bouschen\",\n  \"Boxhammer\",\n  \"Boyde\",\n  \"Bozsik\",\n  \"Brand\",\n  \"Brandenburg\",\n  \"Brandis\",\n  \"Brandt\",\n  \"Brauer\",\n  \"Braun\",\n  \"Brehmer\",\n  \"Breitenstein\",\n  \"Bremer\",\n  \"Bremser\",\n  \"Brenner\",\n  \"Brettschneider\",\n  \"Breu\",\n  \"Breuer\",\n  \"Briesenick\",\n  \"Bringmann\",\n  \"Brinkmann\",\n  \"Brix\",\n  \"Broening\",\n  \"Brosch\",\n  \"Bruckmann\",\n  \"Bruder\",\n  \"Bruhns\",\n  \"Brunner\",\n  \"Bruns\",\n  \"Bräutigam\",\n  \"Brömme\",\n  \"Brüggmann\",\n  \"Buchholz\",\n  \"Buchrucker\",\n  \"Buder\",\n  \"Bultmann\",\n  \"Bunjes\",\n  \"Burger\",\n  \"Burghagen\",\n  \"Burkhard\",\n  \"Burkhardt\",\n  \"Burmeister\",\n  \"Busch\",\n  \"Buschbaum\",\n  \"Busemann\",\n  \"Buss\",\n  \"Busse\",\n  \"Bussmann\",\n  \"Byrd\",\n  \"Bäcker\",\n  \"Böhm\",\n  \"Bönisch\",\n  \"Börgeling\",\n  \"Börner\",\n  \"Böttner\",\n  \"Büchele\",\n  \"Bühler\",\n  \"Büker\",\n  \"Büngener\",\n  \"Bürger\",\n  \"Bürklein\",\n  \"Büscher\",\n  \"Büttner\",\n  \"Camara\",\n  \"Carlowitz\",\n  \"Carlsohn\",\n  \"Caspari\",\n  \"Caspers\",\n  \"Chapron\",\n  \"Christ\",\n  \"Cierpinski\",\n  \"Clarius\",\n  \"Cleem\",\n  \"Cleve\",\n  \"Co\",\n  \"Conrad\",\n  \"Cordes\",\n  \"Cornelsen\",\n  \"Cors\",\n  \"Cotthardt\",\n  \"Crews\",\n  \"Cronjäger\",\n  \"Crosskofp\",\n  \"Da\",\n  \"Dahm\",\n  \"Dahmen\",\n  \"Daimer\",\n  \"Damaske\",\n  \"Danneberg\",\n  \"Danner\",\n  \"Daub\",\n  \"Daubner\",\n  \"Daudrich\",\n  \"Dauer\",\n  \"Daum\",\n  \"Dauth\",\n  \"Dautzenberg\",\n  \"De\",\n  \"Decker\",\n  \"Deckert\",\n  \"Deerberg\",\n  \"Dehmel\",\n  \"Deja\",\n  \"Delonge\",\n  \"Demut\",\n  \"Dengler\",\n  \"Denner\",\n  \"Denzinger\",\n  \"Derr\",\n  \"Dertmann\",\n  \"Dethloff\",\n  \"Deuschle\",\n  \"Dieckmann\",\n  \"Diedrich\",\n  \"Diekmann\",\n  \"Dienel\",\n  \"Dies\",\n  \"Dietrich\",\n  \"Dietz\",\n  \"Dietzsch\",\n  \"Diezel\",\n  \"Dilla\",\n  \"Dingelstedt\",\n  \"Dippl\",\n  \"Dittmann\",\n  \"Dittmar\",\n  \"Dittmer\",\n  \"Dix\",\n  \"Dobbrunz\",\n  \"Dobler\",\n  \"Dohring\",\n  \"Dolch\",\n  \"Dold\",\n  \"Dombrowski\",\n  \"Donie\",\n  \"Doskoczynski\",\n  \"Dragu\",\n  \"Drechsler\",\n  \"Drees\",\n  \"Dreher\",\n  \"Dreier\",\n  \"Dreissigacker\",\n  \"Dressler\",\n  \"Drews\",\n  \"Duma\",\n  \"Dutkiewicz\",\n  \"Dyett\",\n  \"Dylus\",\n  \"Dächert\",\n  \"Döbel\",\n  \"Döring\",\n  \"Dörner\",\n  \"Dörre\",\n  \"Dück\",\n  \"Eberhard\",\n  \"Eberhardt\",\n  \"Ecker\",\n  \"Eckhardt\",\n  \"Edorh\",\n  \"Effler\",\n  \"Eggenmueller\",\n  \"Ehm\",\n  \"Ehmann\",\n  \"Ehrig\",\n  \"Eich\",\n  \"Eichmann\",\n  \"Eifert\",\n  \"Einert\",\n  \"Eisenlauer\",\n  \"Ekpo\",\n  \"Elbe\",\n  \"Eleyth\",\n  \"Elss\",\n  \"Emert\",\n  \"Emmelmann\",\n  \"Ender\",\n  \"Engel\",\n  \"Engelen\",\n  \"Engelmann\",\n  \"Eplinius\",\n  \"Erdmann\",\n  \"Erhardt\",\n  \"Erlei\",\n  \"Erm\",\n  \"Ernst\",\n  \"Ertl\",\n  \"Erwes\",\n  \"Esenwein\",\n  \"Esser\",\n  \"Evers\",\n  \"Everts\",\n  \"Ewald\",\n  \"Fahner\",\n  \"Faller\",\n  \"Falter\",\n  \"Farber\",\n  \"Fassbender\",\n  \"Faulhaber\",\n  \"Fehrig\",\n  \"Feld\",\n  \"Felke\",\n  \"Feller\",\n  \"Fenner\",\n  \"Fenske\",\n  \"Feuerbach\",\n  \"Fietz\",\n  \"Figl\",\n  \"Figura\",\n  \"Filipowski\",\n  \"Filsinger\",\n  \"Fincke\",\n  \"Fink\",\n  \"Finke\",\n  \"Fischer\",\n  \"Fitschen\",\n  \"Fleischer\",\n  \"Fleischmann\",\n  \"Floder\",\n  \"Florczak\",\n  \"Flore\",\n  \"Flottmann\",\n  \"Forkel\",\n  \"Forst\",\n  \"Frahmeke\",\n  \"Frank\",\n  \"Franke\",\n  \"Franta\",\n  \"Frantz\",\n  \"Franz\",\n  \"Franzis\",\n  \"Franzmann\",\n  \"Frauen\",\n  \"Frauendorf\",\n  \"Freigang\",\n  \"Freimann\",\n  \"Freimuth\",\n  \"Freisen\",\n  \"Frenzel\",\n  \"Frey\",\n  \"Fricke\",\n  \"Fried\",\n  \"Friedek\",\n  \"Friedenberg\",\n  \"Friedmann\",\n  \"Friedrich\",\n  \"Friess\",\n  \"Frisch\",\n  \"Frohn\",\n  \"Frosch\",\n  \"Fuchs\",\n  \"Fuhlbrügge\",\n  \"Fusenig\",\n  \"Fust\",\n  \"Förster\",\n  \"Gaba\",\n  \"Gabius\",\n  \"Gabler\",\n  \"Gadschiew\",\n  \"Gakstädter\",\n  \"Galander\",\n  \"Gamlin\",\n  \"Gamper\",\n  \"Gangnus\",\n  \"Ganzmann\",\n  \"Garatva\",\n  \"Gast\",\n  \"Gastel\",\n  \"Gatzka\",\n  \"Gauder\",\n  \"Gebhardt\",\n  \"Geese\",\n  \"Gehre\",\n  \"Gehrig\",\n  \"Gehring\",\n  \"Gehrke\",\n  \"Geiger\",\n  \"Geisler\",\n  \"Geissler\",\n  \"Gelling\",\n  \"Gens\",\n  \"Gerbennow\",\n  \"Gerdel\",\n  \"Gerhardt\",\n  \"Gerschler\",\n  \"Gerson\",\n  \"Gesell\",\n  \"Geyer\",\n  \"Ghirmai\",\n  \"Ghosh\",\n  \"Giehl\",\n  \"Gierisch\",\n  \"Giesa\",\n  \"Giesche\",\n  \"Gilde\",\n  \"Glatting\",\n  \"Goebel\",\n  \"Goedicke\",\n  \"Goldbeck\",\n  \"Goldfuss\",\n  \"Goldkamp\",\n  \"Goldkühle\",\n  \"Goller\",\n  \"Golling\",\n  \"Gollnow\",\n  \"Golomski\",\n  \"Gombert\",\n  \"Gotthardt\",\n  \"Gottschalk\",\n  \"Gotz\",\n  \"Goy\",\n  \"Gradzki\",\n  \"Graf\",\n  \"Grams\",\n  \"Grasse\",\n  \"Gratzky\",\n  \"Grau\",\n  \"Greb\",\n  \"Green\",\n  \"Greger\",\n  \"Greithanner\",\n  \"Greschner\",\n  \"Griem\",\n  \"Griese\",\n  \"Grimm\",\n  \"Gromisch\",\n  \"Gross\",\n  \"Grosser\",\n  \"Grossheim\",\n  \"Grosskopf\",\n  \"Grothaus\",\n  \"Grothkopp\",\n  \"Grotke\",\n  \"Grube\",\n  \"Gruber\",\n  \"Grundmann\",\n  \"Gruning\",\n  \"Gruszecki\",\n  \"Gröss\",\n  \"Grötzinger\",\n  \"Grün\",\n  \"Grüner\",\n  \"Gummelt\",\n  \"Gunkel\",\n  \"Gunther\",\n  \"Gutjahr\",\n  \"Gutowicz\",\n  \"Gutschank\",\n  \"Göbel\",\n  \"Göckeritz\",\n  \"Göhler\",\n  \"Görlich\",\n  \"Görmer\",\n  \"Götz\",\n  \"Götzelmann\",\n  \"Güldemeister\",\n  \"Günther\",\n  \"Günz\",\n  \"Gürbig\",\n  \"Haack\",\n  \"Haaf\",\n  \"Habel\",\n  \"Hache\",\n  \"Hackbusch\",\n  \"Hackelbusch\",\n  \"Hadfield\",\n  \"Hadwich\",\n  \"Haferkamp\",\n  \"Hahn\",\n  \"Hajek\",\n  \"Hallmann\",\n  \"Hamann\",\n  \"Hanenberger\",\n  \"Hannecker\",\n  \"Hanniske\",\n  \"Hansen\",\n  \"Hardy\",\n  \"Hargasser\",\n  \"Harms\",\n  \"Harnapp\",\n  \"Harter\",\n  \"Harting\",\n  \"Hartlieb\",\n  \"Hartmann\",\n  \"Hartwig\",\n  \"Hartz\",\n  \"Haschke\",\n  \"Hasler\",\n  \"Hasse\",\n  \"Hassfeld\",\n  \"Haug\",\n  \"Hauke\",\n  \"Haupt\",\n  \"Haverney\",\n  \"Heberstreit\",\n  \"Hechler\",\n  \"Hecht\",\n  \"Heck\",\n  \"Hedermann\",\n  \"Hehl\",\n  \"Heidelmann\",\n  \"Heidler\",\n  \"Heinemann\",\n  \"Heinig\",\n  \"Heinke\",\n  \"Heinrich\",\n  \"Heinze\",\n  \"Heiser\",\n  \"Heist\",\n  \"Hellmann\",\n  \"Helm\",\n  \"Helmke\",\n  \"Helpling\",\n  \"Hengmith\",\n  \"Henkel\",\n  \"Hennes\",\n  \"Henry\",\n  \"Hense\",\n  \"Hensel\",\n  \"Hentel\",\n  \"Hentschel\",\n  \"Hentschke\",\n  \"Hepperle\",\n  \"Herberger\",\n  \"Herbrand\",\n  \"Hering\",\n  \"Hermann\",\n  \"Hermecke\",\n  \"Herms\",\n  \"Herold\",\n  \"Herrmann\",\n  \"Herschmann\",\n  \"Hertel\",\n  \"Herweg\",\n  \"Herwig\",\n  \"Herzenberg\",\n  \"Hess\",\n  \"Hesse\",\n  \"Hessek\",\n  \"Hessler\",\n  \"Hetzler\",\n  \"Heuck\",\n  \"Heydemüller\",\n  \"Hiebl\",\n  \"Hildebrand\",\n  \"Hildenbrand\",\n  \"Hilgendorf\",\n  \"Hillard\",\n  \"Hiller\",\n  \"Hingsen\",\n  \"Hingst\",\n  \"Hinrichs\",\n  \"Hirsch\",\n  \"Hirschberg\",\n  \"Hirt\",\n  \"Hodea\",\n  \"Hoffman\",\n  \"Hoffmann\",\n  \"Hofmann\",\n  \"Hohenberger\",\n  \"Hohl\",\n  \"Hohn\",\n  \"Hohnheiser\",\n  \"Hold\",\n  \"Holdt\",\n  \"Holinski\",\n  \"Holl\",\n  \"Holtfreter\",\n  \"Holz\",\n  \"Holzdeppe\",\n  \"Holzner\",\n  \"Hommel\",\n  \"Honz\",\n  \"Hooss\",\n  \"Hoppe\",\n  \"Horak\",\n  \"Horn\",\n  \"Horna\",\n  \"Hornung\",\n  \"Hort\",\n  \"Howard\",\n  \"Huber\",\n  \"Huckestein\",\n  \"Hudak\",\n  \"Huebel\",\n  \"Hugo\",\n  \"Huhn\",\n  \"Hujo\",\n  \"Huke\",\n  \"Huls\",\n  \"Humbert\",\n  \"Huneke\",\n  \"Huth\",\n  \"Häber\",\n  \"Häfner\",\n  \"Höcke\",\n  \"Höft\",\n  \"Höhne\",\n  \"Hönig\",\n  \"Hördt\",\n  \"Hübenbecker\",\n  \"Hübl\",\n  \"Hübner\",\n  \"Hügel\",\n  \"Hüttcher\",\n  \"Hütter\",\n  \"Ibe\",\n  \"Ihly\",\n  \"Illing\",\n  \"Isak\",\n  \"Isekenmeier\",\n  \"Itt\",\n  \"Jacob\",\n  \"Jacobs\",\n  \"Jagusch\",\n  \"Jahn\",\n  \"Jahnke\",\n  \"Jakobs\",\n  \"Jakubczyk\",\n  \"Jambor\",\n  \"Jamrozy\",\n  \"Jander\",\n  \"Janich\",\n  \"Janke\",\n  \"Jansen\",\n  \"Jarets\",\n  \"Jaros\",\n  \"Jasinski\",\n  \"Jasper\",\n  \"Jegorov\",\n  \"Jellinghaus\",\n  \"Jeorga\",\n  \"Jerschabek\",\n  \"Jess\",\n  \"John\",\n  \"Jonas\",\n  \"Jossa\",\n  \"Jucken\",\n  \"Jung\",\n  \"Jungbluth\",\n  \"Jungton\",\n  \"Just\",\n  \"Jürgens\",\n  \"Kaczmarek\",\n  \"Kaesmacher\",\n  \"Kahl\",\n  \"Kahlert\",\n  \"Kahles\",\n  \"Kahlmeyer\",\n  \"Kaiser\",\n  \"Kalinowski\",\n  \"Kallabis\",\n  \"Kallensee\",\n  \"Kampf\",\n  \"Kampschulte\",\n  \"Kappe\",\n  \"Kappler\",\n  \"Karhoff\",\n  \"Karrass\",\n  \"Karst\",\n  \"Karsten\",\n  \"Karus\",\n  \"Kass\",\n  \"Kasten\",\n  \"Kastner\",\n  \"Katzinski\",\n  \"Kaufmann\",\n  \"Kaul\",\n  \"Kausemann\",\n  \"Kawohl\",\n  \"Kazmarek\",\n  \"Kedzierski\",\n  \"Keil\",\n  \"Keiner\",\n  \"Keller\",\n  \"Kelm\",\n  \"Kempe\",\n  \"Kemper\",\n  \"Kempter\",\n  \"Kerl\",\n  \"Kern\",\n  \"Kesselring\",\n  \"Kesselschläger\",\n  \"Kette\",\n  \"Kettenis\",\n  \"Keutel\",\n  \"Kick\",\n  \"Kiessling\",\n  \"Kinadeter\",\n  \"Kinzel\",\n  \"Kinzy\",\n  \"Kirch\",\n  \"Kirst\",\n  \"Kisabaka\",\n  \"Klaas\",\n  \"Klabuhn\",\n  \"Klapper\",\n  \"Klauder\",\n  \"Klaus\",\n  \"Kleeberg\",\n  \"Kleiber\",\n  \"Klein\",\n  \"Kleinert\",\n  \"Kleininger\",\n  \"Kleinmann\",\n  \"Kleinsteuber\",\n  \"Kleiss\",\n  \"Klemme\",\n  \"Klimczak\",\n  \"Klinger\",\n  \"Klink\",\n  \"Klopsch\",\n  \"Klose\",\n  \"Kloss\",\n  \"Kluge\",\n  \"Kluwe\",\n  \"Knabe\",\n  \"Kneifel\",\n  \"Knetsch\",\n  \"Knies\",\n  \"Knippel\",\n  \"Knobel\",\n  \"Knoblich\",\n  \"Knoll\",\n  \"Knorr\",\n  \"Knorscheidt\",\n  \"Knut\",\n  \"Kobs\",\n  \"Koch\",\n  \"Kochan\",\n  \"Kock\",\n  \"Koczulla\",\n  \"Koderisch\",\n  \"Koehl\",\n  \"Koehler\",\n  \"Koenig\",\n  \"Koester\",\n  \"Kofferschlager\",\n  \"Koha\",\n  \"Kohle\",\n  \"Kohlmann\",\n  \"Kohnle\",\n  \"Kohrt\",\n  \"Koj\",\n  \"Kolb\",\n  \"Koleiski\",\n  \"Kolokas\",\n  \"Komoll\",\n  \"Konieczny\",\n  \"Konig\",\n  \"Konow\",\n  \"Konya\",\n  \"Koob\",\n  \"Kopf\",\n  \"Kosenkow\",\n  \"Koster\",\n  \"Koszewski\",\n  \"Koubaa\",\n  \"Kovacs\",\n  \"Kowalick\",\n  \"Kowalinski\",\n  \"Kozakiewicz\",\n  \"Krabbe\",\n  \"Kraft\",\n  \"Kral\",\n  \"Kramer\",\n  \"Krauel\",\n  \"Kraus\",\n  \"Krause\",\n  \"Krauspe\",\n  \"Kreb\",\n  \"Krebs\",\n  \"Kreissig\",\n  \"Kresse\",\n  \"Kreutz\",\n  \"Krieger\",\n  \"Krippner\",\n  \"Krodinger\",\n  \"Krohn\",\n  \"Krol\",\n  \"Kron\",\n  \"Krueger\",\n  \"Krug\",\n  \"Kruger\",\n  \"Krull\",\n  \"Kruschinski\",\n  \"Krämer\",\n  \"Kröckert\",\n  \"Kröger\",\n  \"Krüger\",\n  \"Kubera\",\n  \"Kufahl\",\n  \"Kuhlee\",\n  \"Kuhnen\",\n  \"Kulimann\",\n  \"Kulma\",\n  \"Kumbernuss\",\n  \"Kummle\",\n  \"Kunz\",\n  \"Kupfer\",\n  \"Kupprion\",\n  \"Kuprion\",\n  \"Kurnicki\",\n  \"Kurrat\",\n  \"Kurschilgen\",\n  \"Kuschewitz\",\n  \"Kuschmann\",\n  \"Kuske\",\n  \"Kustermann\",\n  \"Kutscherauer\",\n  \"Kutzner\",\n  \"Kwadwo\",\n  \"Kähler\",\n  \"Käther\",\n  \"Köhler\",\n  \"Köhrbrück\",\n  \"Köhre\",\n  \"Kölotzei\",\n  \"König\",\n  \"Köpernick\",\n  \"Köseoglu\",\n  \"Kúhn\",\n  \"Kúhnert\",\n  \"Kühn\",\n  \"Kühnel\",\n  \"Kühnemund\",\n  \"Kühnert\",\n  \"Kühnke\",\n  \"Küsters\",\n  \"Küter\",\n  \"Laack\",\n  \"Lack\",\n  \"Ladewig\",\n  \"Lakomy\",\n  \"Lammert\",\n  \"Lamos\",\n  \"Landmann\",\n  \"Lang\",\n  \"Lange\",\n  \"Langfeld\",\n  \"Langhirt\",\n  \"Lanig\",\n  \"Lauckner\",\n  \"Lauinger\",\n  \"Laurén\",\n  \"Lausecker\",\n  \"Laux\",\n  \"Laws\",\n  \"Lax\",\n  \"Leberer\",\n  \"Lehmann\",\n  \"Lehner\",\n  \"Leibold\",\n  \"Leide\",\n  \"Leimbach\",\n  \"Leipold\",\n  \"Leist\",\n  \"Leiter\",\n  \"Leiteritz\",\n  \"Leitheim\",\n  \"Leiwesmeier\",\n  \"Lenfers\",\n  \"Lenk\",\n  \"Lenz\",\n  \"Lenzen\",\n  \"Leo\",\n  \"Lepthin\",\n  \"Lesch\",\n  \"Leschnik\",\n  \"Letzelter\",\n  \"Lewin\",\n  \"Lewke\",\n  \"Leyckes\",\n  \"Lg\",\n  \"Lichtenfeld\",\n  \"Lichtenhagen\",\n  \"Lichtl\",\n  \"Liebach\",\n  \"Liebe\",\n  \"Liebich\",\n  \"Liebold\",\n  \"Lieder\",\n  \"Lienshöft\",\n  \"Linden\",\n  \"Lindenberg\",\n  \"Lindenmayer\",\n  \"Lindner\",\n  \"Linke\",\n  \"Linnenbaum\",\n  \"Lippe\",\n  \"Lipske\",\n  \"Lipus\",\n  \"Lischka\",\n  \"Lobinger\",\n  \"Logsch\",\n  \"Lohmann\",\n  \"Lohre\",\n  \"Lohse\",\n  \"Lokar\",\n  \"Loogen\",\n  \"Lorenz\",\n  \"Losch\",\n  \"Loska\",\n  \"Lott\",\n  \"Loy\",\n  \"Lubina\",\n  \"Ludolf\",\n  \"Lufft\",\n  \"Lukoschek\",\n  \"Lutje\",\n  \"Lutz\",\n  \"Löser\",\n  \"Löwa\",\n  \"Lübke\",\n  \"Maak\",\n  \"Maczey\",\n  \"Madetzky\",\n  \"Madubuko\",\n  \"Mai\",\n  \"Maier\",\n  \"Maisch\",\n  \"Malek\",\n  \"Malkus\",\n  \"Mallmann\",\n  \"Malucha\",\n  \"Manns\",\n  \"Manz\",\n  \"Marahrens\",\n  \"Marchewski\",\n  \"Margis\",\n  \"Markowski\",\n  \"Marl\",\n  \"Marner\",\n  \"Marquart\",\n  \"Marschek\",\n  \"Martel\",\n  \"Marten\",\n  \"Martin\",\n  \"Marx\",\n  \"Marxen\",\n  \"Mathes\",\n  \"Mathies\",\n  \"Mathiszik\",\n  \"Matschke\",\n  \"Mattern\",\n  \"Matthes\",\n  \"Matula\",\n  \"Mau\",\n  \"Maurer\",\n  \"Mauroff\",\n  \"May\",\n  \"Maybach\",\n  \"Mayer\",\n  \"Mebold\",\n  \"Mehl\",\n  \"Mehlhorn\",\n  \"Mehlorn\",\n  \"Meier\",\n  \"Meisch\",\n  \"Meissner\",\n  \"Meloni\",\n  \"Melzer\",\n  \"Menga\",\n  \"Menne\",\n  \"Mensah\",\n  \"Mensing\",\n  \"Merkel\",\n  \"Merseburg\",\n  \"Mertens\",\n  \"Mesloh\",\n  \"Metzger\",\n  \"Metzner\",\n  \"Mewes\",\n  \"Meyer\",\n  \"Michallek\",\n  \"Michel\",\n  \"Mielke\",\n  \"Mikitenko\",\n  \"Milde\",\n  \"Minah\",\n  \"Mintzlaff\",\n  \"Mockenhaupt\",\n  \"Moede\",\n  \"Moedl\",\n  \"Moeller\",\n  \"Moguenara\",\n  \"Mohr\",\n  \"Mohrhard\",\n  \"Molitor\",\n  \"Moll\",\n  \"Moller\",\n  \"Molzan\",\n  \"Montag\",\n  \"Moormann\",\n  \"Mordhorst\",\n  \"Morgenstern\",\n  \"Morhelfer\",\n  \"Moritz\",\n  \"Moser\",\n  \"Motchebon\",\n  \"Motzenbbäcker\",\n  \"Mrugalla\",\n  \"Muckenthaler\",\n  \"Mues\",\n  \"Muller\",\n  \"Mulrain\",\n  \"Mächtig\",\n  \"Mäder\",\n  \"Möcks\",\n  \"Mögenburg\",\n  \"Möhsner\",\n  \"Möldner\",\n  \"Möllenbeck\",\n  \"Möller\",\n  \"Möllinger\",\n  \"Mörsch\",\n  \"Mühleis\",\n  \"Müller\",\n  \"Münch\",\n  \"Nabein\",\n  \"Nabow\",\n  \"Nagel\",\n  \"Nannen\",\n  \"Nastvogel\",\n  \"Nau\",\n  \"Naubert\",\n  \"Naumann\",\n  \"Ne\",\n  \"Neimke\",\n  \"Nerius\",\n  \"Neubauer\",\n  \"Neubert\",\n  \"Neuendorf\",\n  \"Neumair\",\n  \"Neumann\",\n  \"Neupert\",\n  \"Neurohr\",\n  \"Neuschwander\",\n  \"Newton\",\n  \"Ney\",\n  \"Nicolay\",\n  \"Niedermeier\",\n  \"Nieklauson\",\n  \"Niklaus\",\n  \"Nitzsche\",\n  \"Noack\",\n  \"Nodler\",\n  \"Nolte\",\n  \"Normann\",\n  \"Norris\",\n  \"Northoff\",\n  \"Nowak\",\n  \"Nussbeck\",\n  \"Nwachukwu\",\n  \"Nytra\",\n  \"Nöh\",\n  \"Oberem\",\n  \"Obergföll\",\n  \"Obermaier\",\n  \"Ochs\",\n  \"Oeser\",\n  \"Olbrich\",\n  \"Onnen\",\n  \"Ophey\",\n  \"Oppong\",\n  \"Orth\",\n  \"Orthmann\",\n  \"Oschkenat\",\n  \"Osei\",\n  \"Osenberg\",\n  \"Ostendarp\",\n  \"Ostwald\",\n  \"Otte\",\n  \"Otto\",\n  \"Paesler\",\n  \"Pajonk\",\n  \"Pallentin\",\n  \"Panzig\",\n  \"Paschke\",\n  \"Patzwahl\",\n  \"Paukner\",\n  \"Peselman\",\n  \"Peter\",\n  \"Peters\",\n  \"Petzold\",\n  \"Pfeiffer\",\n  \"Pfennig\",\n  \"Pfersich\",\n  \"Pfingsten\",\n  \"Pflieger\",\n  \"Pflügner\",\n  \"Philipp\",\n  \"Pichlmaier\",\n  \"Piesker\",\n  \"Pietsch\",\n  \"Pingpank\",\n  \"Pinnock\",\n  \"Pippig\",\n  \"Pitschugin\",\n  \"Plank\",\n  \"Plass\",\n  \"Platzer\",\n  \"Plauk\",\n  \"Plautz\",\n  \"Pletsch\",\n  \"Plotzitzka\",\n  \"Poehn\",\n  \"Poeschl\",\n  \"Pogorzelski\",\n  \"Pohl\",\n  \"Pohland\",\n  \"Pohle\",\n  \"Polifka\",\n  \"Polizzi\",\n  \"Pollmächer\",\n  \"Pomp\",\n  \"Ponitzsch\",\n  \"Porsche\",\n  \"Porth\",\n  \"Poschmann\",\n  \"Poser\",\n  \"Pottel\",\n  \"Prah\",\n  \"Prange\",\n  \"Prediger\",\n  \"Pressler\",\n  \"Preuk\",\n  \"Preuss\",\n  \"Prey\",\n  \"Priemer\",\n  \"Proske\",\n  \"Pusch\",\n  \"Pöche\",\n  \"Pöge\",\n  \"Raabe\",\n  \"Rabenstein\",\n  \"Rach\",\n  \"Radtke\",\n  \"Rahn\",\n  \"Ranftl\",\n  \"Rangen\",\n  \"Ranz\",\n  \"Rapp\",\n  \"Rath\",\n  \"Rau\",\n  \"Raubuch\",\n  \"Raukuc\",\n  \"Rautenkranz\",\n  \"Rehwagen\",\n  \"Reiber\",\n  \"Reichardt\",\n  \"Reichel\",\n  \"Reichling\",\n  \"Reif\",\n  \"Reifenrath\",\n  \"Reimann\",\n  \"Reinberg\",\n  \"Reinelt\",\n  \"Reinhardt\",\n  \"Reinke\",\n  \"Reitze\",\n  \"Renk\",\n  \"Rentz\",\n  \"Renz\",\n  \"Reppin\",\n  \"Restle\",\n  \"Restorff\",\n  \"Retzke\",\n  \"Reuber\",\n  \"Reumann\",\n  \"Reus\",\n  \"Reuss\",\n  \"Reusse\",\n  \"Rheder\",\n  \"Rhoden\",\n  \"Richards\",\n  \"Richter\",\n  \"Riedel\",\n  \"Riediger\",\n  \"Rieger\",\n  \"Riekmann\",\n  \"Riepl\",\n  \"Riermeier\",\n  \"Riester\",\n  \"Riethmüller\",\n  \"Rietmüller\",\n  \"Rietscher\",\n  \"Ringel\",\n  \"Ringer\",\n  \"Rink\",\n  \"Ripken\",\n  \"Ritosek\",\n  \"Ritschel\",\n  \"Ritter\",\n  \"Rittweg\",\n  \"Ritz\",\n  \"Roba\",\n  \"Rockmeier\",\n  \"Rodehau\",\n  \"Rodowski\",\n  \"Roecker\",\n  \"Roggatz\",\n  \"Rohländer\",\n  \"Rohrer\",\n  \"Rokossa\",\n  \"Roleder\",\n  \"Roloff\",\n  \"Roos\",\n  \"Rosbach\",\n  \"Roschinsky\",\n  \"Rose\",\n  \"Rosenauer\",\n  \"Rosenbauer\",\n  \"Rosenthal\",\n  \"Rosksch\",\n  \"Rossberg\",\n  \"Rossler\",\n  \"Roth\",\n  \"Rother\",\n  \"Ruch\",\n  \"Ruckdeschel\",\n  \"Rumpf\",\n  \"Rupprecht\",\n  \"Ruth\",\n  \"Ryjikh\",\n  \"Ryzih\",\n  \"Rädler\",\n  \"Räntsch\",\n  \"Rödiger\",\n  \"Röse\",\n  \"Röttger\",\n  \"Rücker\",\n  \"Rüdiger\",\n  \"Rüter\",\n  \"Sachse\",\n  \"Sack\",\n  \"Saflanis\",\n  \"Sagafe\",\n  \"Sagonas\",\n  \"Sahner\",\n  \"Saile\",\n  \"Sailer\",\n  \"Salow\",\n  \"Salzer\",\n  \"Salzmann\",\n  \"Sammert\",\n  \"Sander\",\n  \"Sarvari\",\n  \"Sattelmaier\",\n  \"Sauer\",\n  \"Sauerland\",\n  \"Saumweber\",\n  \"Savoia\",\n  \"Scc\",\n  \"Schacht\",\n  \"Schaefer\",\n  \"Schaffarzik\",\n  \"Schahbasian\",\n  \"Scharf\",\n  \"Schedler\",\n  \"Scheer\",\n  \"Schelk\",\n  \"Schellenbeck\",\n  \"Schembera\",\n  \"Schenk\",\n  \"Scherbarth\",\n  \"Scherer\",\n  \"Schersing\",\n  \"Scherz\",\n  \"Scheurer\",\n  \"Scheuring\",\n  \"Scheytt\",\n  \"Schielke\",\n  \"Schieskow\",\n  \"Schildhauer\",\n  \"Schilling\",\n  \"Schima\",\n  \"Schimmer\",\n  \"Schindzielorz\",\n  \"Schirmer\",\n  \"Schirrmeister\",\n  \"Schlachter\",\n  \"Schlangen\",\n  \"Schlawitz\",\n  \"Schlechtweg\",\n  \"Schley\",\n  \"Schlicht\",\n  \"Schlitzer\",\n  \"Schmalzle\",\n  \"Schmid\",\n  \"Schmidt\",\n  \"Schmidtchen\",\n  \"Schmitt\",\n  \"Schmitz\",\n  \"Schmuhl\",\n  \"Schneider\",\n  \"Schnelting\",\n  \"Schnieder\",\n  \"Schniedermeier\",\n  \"Schnürer\",\n  \"Schoberg\",\n  \"Scholz\",\n  \"Schonberg\",\n  \"Schondelmaier\",\n  \"Schorr\",\n  \"Schott\",\n  \"Schottmann\",\n  \"Schouren\",\n  \"Schrader\",\n  \"Schramm\",\n  \"Schreck\",\n  \"Schreiber\",\n  \"Schreiner\",\n  \"Schreiter\",\n  \"Schroder\",\n  \"Schröder\",\n  \"Schuermann\",\n  \"Schuff\",\n  \"Schuhaj\",\n  \"Schuldt\",\n  \"Schult\",\n  \"Schulte\",\n  \"Schultz\",\n  \"Schultze\",\n  \"Schulz\",\n  \"Schulze\",\n  \"Schumacher\",\n  \"Schumann\",\n  \"Schupp\",\n  \"Schuri\",\n  \"Schuster\",\n  \"Schwab\",\n  \"Schwalm\",\n  \"Schwanbeck\",\n  \"Schwandke\",\n  \"Schwanitz\",\n  \"Schwarthoff\",\n  \"Schwartz\",\n  \"Schwarz\",\n  \"Schwarzer\",\n  \"Schwarzkopf\",\n  \"Schwarzmeier\",\n  \"Schwatlo\",\n  \"Schweisfurth\",\n  \"Schwennen\",\n  \"Schwerdtner\",\n  \"Schwidde\",\n  \"Schwirkschlies\",\n  \"Schwuchow\",\n  \"Schäfer\",\n  \"Schäffel\",\n  \"Schäffer\",\n  \"Schäning\",\n  \"Schöckel\",\n  \"Schönball\",\n  \"Schönbeck\",\n  \"Schönberg\",\n  \"Schönebeck\",\n  \"Schönenberger\",\n  \"Schönfeld\",\n  \"Schönherr\",\n  \"Schönlebe\",\n  \"Schötz\",\n  \"Schüler\",\n  \"Schüppel\",\n  \"Schütz\",\n  \"Schütze\",\n  \"Seeger\",\n  \"Seelig\",\n  \"Sehls\",\n  \"Seibold\",\n  \"Seidel\",\n  \"Seiders\",\n  \"Seigel\",\n  \"Seiler\",\n  \"Seitz\",\n  \"Semisch\",\n  \"Senkel\",\n  \"Sewald\",\n  \"Siebel\",\n  \"Siebert\",\n  \"Siegling\",\n  \"Sielemann\",\n  \"Siemon\",\n  \"Siener\",\n  \"Sievers\",\n  \"Siewert\",\n  \"Sihler\",\n  \"Sillah\",\n  \"Simon\",\n  \"Sinnhuber\",\n  \"Sischka\",\n  \"Skibicki\",\n  \"Sladek\",\n  \"Slotta\",\n  \"Smieja\",\n  \"Soboll\",\n  \"Sokolowski\",\n  \"Soller\",\n  \"Sollner\",\n  \"Sommer\",\n  \"Somssich\",\n  \"Sonn\",\n  \"Sonnabend\",\n  \"Spahn\",\n  \"Spank\",\n  \"Spelmeyer\",\n  \"Spiegelburg\",\n  \"Spielvogel\",\n  \"Spinner\",\n  \"Spitzmüller\",\n  \"Splinter\",\n  \"Sporrer\",\n  \"Sprenger\",\n  \"Spöttel\",\n  \"Stahl\",\n  \"Stang\",\n  \"Stanger\",\n  \"Stauss\",\n  \"Steding\",\n  \"Steffen\",\n  \"Steffny\",\n  \"Steidl\",\n  \"Steigauf\",\n  \"Stein\",\n  \"Steinecke\",\n  \"Steinert\",\n  \"Steinkamp\",\n  \"Steinmetz\",\n  \"Stelkens\",\n  \"Stengel\",\n  \"Stengl\",\n  \"Stenzel\",\n  \"Stepanov\",\n  \"Stephan\",\n  \"Stern\",\n  \"Steuk\",\n  \"Stief\",\n  \"Stifel\",\n  \"Stoll\",\n  \"Stolle\",\n  \"Stolz\",\n  \"Storl\",\n  \"Storp\",\n  \"Stoutjesdijk\",\n  \"Stratmann\",\n  \"Straub\",\n  \"Strausa\",\n  \"Streck\",\n  \"Streese\",\n  \"Strege\",\n  \"Streit\",\n  \"Streller\",\n  \"Strieder\",\n  \"Striezel\",\n  \"Strogies\",\n  \"Strohschank\",\n  \"Strunz\",\n  \"Strutz\",\n  \"Stube\",\n  \"Stöckert\",\n  \"Stöppler\",\n  \"Stöwer\",\n  \"Stürmer\",\n  \"Suffa\",\n  \"Sujew\",\n  \"Sussmann\",\n  \"Suthe\",\n  \"Sutschet\",\n  \"Swillims\",\n  \"Szendrei\",\n  \"Sören\",\n  \"Sürth\",\n  \"Tafelmeier\",\n  \"Tang\",\n  \"Tasche\",\n  \"Taufratshofer\",\n  \"Tegethof\",\n  \"Teichmann\",\n  \"Tepper\",\n  \"Terheiden\",\n  \"Terlecki\",\n  \"Teufel\",\n  \"Theele\",\n  \"Thieke\",\n  \"Thimm\",\n  \"Thiomas\",\n  \"Thomas\",\n  \"Thriene\",\n  \"Thränhardt\",\n  \"Thust\",\n  \"Thyssen\",\n  \"Thöne\",\n  \"Tidow\",\n  \"Tiedtke\",\n  \"Tietze\",\n  \"Tilgner\",\n  \"Tillack\",\n  \"Timmermann\",\n  \"Tischler\",\n  \"Tischmann\",\n  \"Tittman\",\n  \"Tivontschik\",\n  \"Tonat\",\n  \"Tonn\",\n  \"Trampeli\",\n  \"Trauth\",\n  \"Trautmann\",\n  \"Travan\",\n  \"Treff\",\n  \"Tremmel\",\n  \"Tress\",\n  \"Tsamonikian\",\n  \"Tschiers\",\n  \"Tschirch\",\n  \"Tuch\",\n  \"Tucholke\",\n  \"Tudow\",\n  \"Tuschmo\",\n  \"Tächl\",\n  \"Többen\",\n  \"Töpfer\",\n  \"Uhlemann\",\n  \"Uhlig\",\n  \"Uhrig\",\n  \"Uibel\",\n  \"Uliczka\",\n  \"Ullmann\",\n  \"Ullrich\",\n  \"Umbach\",\n  \"Umlauft\",\n  \"Umminger\",\n  \"Unger\",\n  \"Unterpaintner\",\n  \"Urban\",\n  \"Urbaniak\",\n  \"Urbansky\",\n  \"Urhig\",\n  \"Vahlensieck\",\n  \"Van\",\n  \"Vangermain\",\n  \"Vater\",\n  \"Venghaus\",\n  \"Verniest\",\n  \"Verzi\",\n  \"Vey\",\n  \"Viellehner\",\n  \"Vieweg\",\n  \"Voelkel\",\n  \"Vogel\",\n  \"Vogelgsang\",\n  \"Vogt\",\n  \"Voigt\",\n  \"Vokuhl\",\n  \"Volk\",\n  \"Volker\",\n  \"Volkmann\",\n  \"Von\",\n  \"Vona\",\n  \"Vontein\",\n  \"Wachenbrunner\",\n  \"Wachtel\",\n  \"Wagner\",\n  \"Waibel\",\n  \"Wakan\",\n  \"Waldmann\",\n  \"Wallner\",\n  \"Wallstab\",\n  \"Walter\",\n  \"Walther\",\n  \"Walton\",\n  \"Walz\",\n  \"Wanner\",\n  \"Wartenberg\",\n  \"Waschbüsch\",\n  \"Wassilew\",\n  \"Wassiluk\",\n  \"Weber\",\n  \"Wehrsen\",\n  \"Weidlich\",\n  \"Weidner\",\n  \"Weigel\",\n  \"Weight\",\n  \"Weiler\",\n  \"Weimer\",\n  \"Weis\",\n  \"Weiss\",\n  \"Weller\",\n  \"Welsch\",\n  \"Welz\",\n  \"Welzel\",\n  \"Weniger\",\n  \"Wenk\",\n  \"Werle\",\n  \"Werner\",\n  \"Werrmann\",\n  \"Wessel\",\n  \"Wessinghage\",\n  \"Weyel\",\n  \"Wezel\",\n  \"Wichmann\",\n  \"Wickert\",\n  \"Wiebe\",\n  \"Wiechmann\",\n  \"Wiegelmann\",\n  \"Wierig\",\n  \"Wiese\",\n  \"Wieser\",\n  \"Wilhelm\",\n  \"Wilky\",\n  \"Will\",\n  \"Willwacher\",\n  \"Wilts\",\n  \"Wimmer\",\n  \"Winkelmann\",\n  \"Winkler\",\n  \"Winter\",\n  \"Wischek\",\n  \"Wischer\",\n  \"Wissing\",\n  \"Wittich\",\n  \"Wittl\",\n  \"Wolf\",\n  \"Wolfarth\",\n  \"Wolff\",\n  \"Wollenberg\",\n  \"Wollmann\",\n  \"Woytkowska\",\n  \"Wujak\",\n  \"Wurm\",\n  \"Wyludda\",\n  \"Wölpert\",\n  \"Wöschler\",\n  \"Wühn\",\n  \"Wünsche\",\n  \"Zach\",\n  \"Zaczkiewicz\",\n  \"Zahn\",\n  \"Zaituc\",\n  \"Zandt\",\n  \"Zanner\",\n  \"Zapletal\",\n  \"Zauber\",\n  \"Zeidler\",\n  \"Zekl\",\n  \"Zender\",\n  \"Zeuch\",\n  \"Zeyen\",\n  \"Zeyhle\",\n  \"Ziegler\",\n  \"Zimanyi\",\n  \"Zimmer\",\n  \"Zimmermann\",\n  \"Zinser\",\n  \"Zintl\",\n  \"Zipp\",\n  \"Zipse\",\n  \"Zschunke\",\n  \"Zuber\",\n  \"Zwiener\",\n  \"Zümsande\",\n  \"Östringer\",\n  \"Überacker\"\n];\n\n},{}],126:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{first_name} #{last_name}\",\n  \"#{first_name} #{nobility_title_prefix} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\"\n];\n\n},{}],127:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"zu\",\n  \"von\",\n  \"vom\",\n  \"von der\"\n];\n\n},{}],128:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Hr.\",\n  \"Fr.\",\n  \"Dr.\",\n  \"Prof. Dr.\"\n];\n\n},{}],129:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"(0###) #########\",\n  \"(0####) #######\",\n  \"+49-###-#######\",\n  \"+49-####-########\"\n];\n\n},{}],130:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":129,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],131:[function(require,module,exports){\nmodule.exports=require(97)\n},{\"/Users/a/dev/faker.js/lib/locales/de/address/building_number.js\":97}],132:[function(require,module,exports){\nmodule.exports=require(55)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/city.js\":55}],133:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aigen im Mühlkreis\",\n  \"Allerheiligen bei Wildon\",\n  \"Altenfelden\",\n  \"Arriach\",\n  \"Axams\",\n  \"Baumgartenberg\",\n  \"Bergern im Dunkelsteinerwald\",\n  \"Berndorf bei Salzburg\",\n  \"Bregenz\",\n  \"Breitenbach am Inn\",\n  \"Deutsch-Wagram\",\n  \"Dienten am Hochkönig\",\n  \"Dietach\",\n  \"Dornbirn\",\n  \"Dürnkrut\",\n  \"Eben im Pongau\",\n  \"Ebenthal in Kärnten\",\n  \"Eichgraben\",\n  \"Eisenstadt\",\n  \"Ellmau\",\n  \"Feistritz am Wechsel\",\n  \"Finkenberg\",\n  \"Fiss\",\n  \"Frantschach-St. Gertraud\",\n  \"Fritzens\",\n  \"Gams bei Hieflau\",\n  \"Geiersberg\",\n  \"Graz\",\n  \"Großhöflein\",\n  \"Gößnitz\",\n  \"Hartl\",\n  \"Hausleiten\",\n  \"Herzogenburg\",\n  \"Hinterhornbach\",\n  \"Hochwolkersdorf\",\n  \"Ilz\",\n  \"Ilztal\",\n  \"Innerbraz\",\n  \"Innsbruck\",\n  \"Itter\",\n  \"Jagerberg\",\n  \"Jeging\",\n  \"Johnsbach\",\n  \"Johnsdorf-Brunn\",\n  \"Jungholz\",\n  \"Kirchdorf am Inn\",\n  \"Klagenfurt\",\n  \"Kottes-Purk\",\n  \"Krumau am Kamp\",\n  \"Krumbach\",\n  \"Lavamünd\",\n  \"Lech\",\n  \"Linz\",\n  \"Ludesch\",\n  \"Lödersdorf\",\n  \"Marbach an der Donau\",\n  \"Mattsee\",\n  \"Mautern an der Donau\",\n  \"Mauterndorf\",\n  \"Mitterbach am Erlaufsee\",\n  \"Neudorf bei Passail\",\n  \"Neudorf bei Staatz\",\n  \"Neukirchen an der Enknach\",\n  \"Neustift an der Lafnitz\",\n  \"Niederleis\",\n  \"Oberndorf in Tirol\",\n  \"Oberstorcha\",\n  \"Oberwaltersdorf\",\n  \"Oed-Oehling\",\n  \"Ort im Innkreis\",\n  \"Pilgersdorf\",\n  \"Pitschgau\",\n  \"Pollham\",\n  \"Preitenegg\",\n  \"Purbach am Neusiedler See\",\n  \"Rabenwald\",\n  \"Raiding\",\n  \"Rastenfeld\",\n  \"Ratten\",\n  \"Rettenegg\",\n  \"Salzburg\",\n  \"Sankt Johann im Saggautal\",\n  \"St. Peter am Kammersberg\",\n  \"St. Pölten\",\n  \"St. Veit an der Glan\",\n  \"Taxenbach\",\n  \"Tragwein\",\n  \"Trebesing\",\n  \"Trieben\",\n  \"Turnau\",\n  \"Ungerdorf\",\n  \"Unterauersbach\",\n  \"Unterstinkenbrunn\",\n  \"Untertilliach\",\n  \"Uttendorf\",\n  \"Vals\",\n  \"Velden am Wörther See\",\n  \"Viehhofen\",\n  \"Villach\",\n  \"Vitis\",\n  \"Waidhofen an der Thaya\",\n  \"Waldkirchen am Wesen\",\n  \"Weißkirchen an der Traun\",\n  \"Wien\",\n  \"Wimpassing im Schwarzatale\",\n  \"Ybbs an der Donau\",\n  \"Ybbsitz\",\n  \"Yspertal\",\n  \"Zeillern\",\n  \"Zell am Pettenfirst\",\n  \"Zell an der Pram\",\n  \"Zerlach\",\n  \"Zwölfaxing\",\n  \"Öblarn\",\n  \"Übelbach\",\n  \"Überackern\",\n  \"Übersaxen\",\n  \"Übersbach\"\n];\n\n},{}],134:[function(require,module,exports){\nmodule.exports=require(101)\n},{\"/Users/a/dev/faker.js/lib/locales/de/address/country.js\":101}],135:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Österreich\"\n];\n\n},{}],136:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.country = require(\"./country\");\naddress.street_root = require(\"./street_root\");\naddress.building_number = require(\"./building_number\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":131,\"./city\":132,\"./city_name\":133,\"./country\":134,\"./default_country\":135,\"./postcode\":137,\"./secondary_address\":138,\"./state\":139,\"./state_abbr\":140,\"./street_address\":141,\"./street_name\":142,\"./street_root\":143}],137:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"####\"\n];\n\n},{}],138:[function(require,module,exports){\nmodule.exports=require(105)\n},{\"/Users/a/dev/faker.js/lib/locales/de/address/secondary_address.js\":105}],139:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Burgenland\",\n  \"Kärnten\",\n  \"Niederösterreich\",\n  \"Oberösterreich\",\n  \"Salzburg\",\n  \"Steiermark\",\n  \"Tirol\",\n  \"Vorarlberg\",\n  \"Wien\"\n];\n\n},{}],140:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Bgld.\",\n  \"Ktn.\",\n  \"NÖ\",\n  \"OÖ\",\n  \"Sbg.\",\n  \"Stmk.\",\n  \"T\",\n  \"Vbg.\",\n  \"W\"\n];\n\n},{}],141:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],142:[function(require,module,exports){\nmodule.exports=require(109)\n},{\"/Users/a/dev/faker.js/lib/locales/de/address/street_name.js\":109}],143:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ahorn\",\n  \"Ahorngasse (St. Andrä)\",\n  \"Alleestraße (Poysbrunn)\",\n  \"Alpenlandstraße\",\n  \"Alte Poststraße\",\n  \"Alte Ufergasse\",\n  \"Am Kronawett (Hagenbrunn)\",\n  \"Am Mühlwasser\",\n  \"Am Rebenhang\",\n  \"Am Sternweg\",\n  \"Anton Wildgans-Straße\",\n  \"Auer-von-Welsbach-Weg\",\n  \"Auf der Stift\",\n  \"Aufeldgasse\",\n  \"Bahngasse\",\n  \"Bahnhofstraße\",\n  \"Bahnstraße (Gerhaus)\",\n  \"Basteigasse\",\n  \"Berggasse\",\n  \"Bergstraße\",\n  \"Birkenweg\",\n  \"Blasiussteig\",\n  \"Blattur\",\n  \"Bruderhofgasse\",\n  \"Brunnelligasse\",\n  \"Bühelweg\",\n  \"Darnautgasse\",\n  \"Donaugasse\",\n  \"Dorfplatz (Haselbach)\",\n  \"Dr.-Oberreiter-Straße\",\n  \"Dr.Karl Holoubek-Str.\",\n  \"Drautal Bundesstraße\",\n  \"Dürnrohrer Straße\",\n  \"Ebenthalerstraße\",\n  \"Eckgrabenweg\",\n  \"Erlenstraße\",\n  \"Erlenweg\",\n  \"Eschenweg\",\n  \"Etrichgasse\",\n  \"Fassergasse\",\n  \"Feichteggerwiese\",\n  \"Feld-Weg\",\n  \"Feldgasse\",\n  \"Feldstapfe\",\n  \"Fischpointweg\",\n  \"Flachbergstraße\",\n  \"Flurweg\",\n  \"Franz Schubert-Gasse\",\n  \"Franz-Schneeweiß-Weg\",\n  \"Franz-von-Assisi-Straße\",\n  \"Fritz-Pregl-Straße\",\n  \"Fuchsgrubenweg\",\n  \"Födlerweg\",\n  \"Föhrenweg\",\n  \"Fünfhaus (Paasdorf)\",\n  \"Gabelsbergerstraße\",\n  \"Gartenstraße\",\n  \"Geigen\",\n  \"Geigergasse\",\n  \"Gemeindeaugasse\",\n  \"Gemeindeplatz\",\n  \"Georg-Aichinger-Straße\",\n  \"Glanfeldbachweg\",\n  \"Graben (Burgauberg)\",\n  \"Grub\",\n  \"Gröretgasse\",\n  \"Grünbach\",\n  \"Gösting\",\n  \"Hainschwang\",\n  \"Hans-Mauracher-Straße\",\n  \"Hart\",\n  \"Teichstraße\",\n  \"Hauptplatz\",\n  \"Hauptstraße\",\n  \"Heideweg\",\n  \"Heinrich Landauer Gasse\",\n  \"Helenengasse\",\n  \"Hermann von Gilmweg\",\n  \"Hermann-Löns-Gasse\",\n  \"Herminengasse\",\n  \"Hernstorferstraße\",\n  \"Hirsdorf\",\n  \"Hochfeistritz\",\n  \"Hochhaus Neue Donau\",\n  \"Hof\",\n  \"Hussovits Gasse\",\n  \"Höggen\",\n  \"Hütten\",\n  \"Janzgasse\",\n  \"Jochriemgutstraße\",\n  \"Johann-Strauß-Gasse\",\n  \"Julius-Raab-Straße\",\n  \"Kahlenberger Straße\",\n  \"Karl Kraft-Straße\",\n  \"Kegelprielstraße\",\n  \"Keltenberg-Eponaweg\",\n  \"Kennedybrücke\",\n  \"Kerpelystraße\",\n  \"Kindergartenstraße\",\n  \"Kinderheimgasse\",\n  \"Kirchenplatz\",\n  \"Kirchweg\",\n  \"Klagenfurter Straße\",\n  \"Klamm\",\n  \"Kleinbaumgarten\",\n  \"Klingergasse\",\n  \"Koloniestraße\",\n  \"Konrad-Duden-Gasse\",\n  \"Krankenhausstraße\",\n  \"Kubinstraße\",\n  \"Köhldorfergasse\",\n  \"Lackenweg\",\n  \"Lange Mekotte\",\n  \"Leifling\",\n  \"Leopold Frank-Straße (Pellendorf)\",\n  \"Lerchengasse (Pirka)\",\n  \"Lichtensternsiedlung V\",\n  \"Lindenhofstraße\",\n  \"Lindenweg\",\n  \"Luegstraße\",\n  \"Maierhof\",\n  \"Malerweg\",\n  \"Mitterweg\",\n  \"Mittlere Hauptstraße\",\n  \"Moosbachgasse\",\n  \"Morettigasse\",\n  \"Musikpavillon Riezlern\",\n  \"Mühlboden\",\n  \"Mühle\",\n  \"Mühlenweg\",\n  \"Neustiftgasse\",\n  \"Niederegg\",\n  \"Niedergams\",\n  \"Nordwestbahnbrücke\",\n  \"Oberbödenalm\",\n  \"Obere Berggasse\",\n  \"Oedt\",\n  \"Am Färberberg\",\n  \"Ottogasse\",\n  \"Paul Peters-Gasse\",\n  \"Perspektivstraße\",\n  \"Poppichl\",\n  \"Privatweg\",\n  \"Prixgasse\",\n  \"Pyhra\",\n  \"Radetzkystraße\",\n  \"Raiden\",\n  \"Reichensteinstraße\",\n  \"Reitbauernstraße\",\n  \"Reiterweg\",\n  \"Reitschulgasse\",\n  \"Ringweg\",\n  \"Rupertistraße\",\n  \"Römerstraße\",\n  \"Römerweg\",\n  \"Sackgasse\",\n  \"Schaunbergerstraße\",\n  \"Schloßweg\",\n  \"Schulgasse (Langeck)\",\n  \"Schönholdsiedlung\",\n  \"Seeblick\",\n  \"Seestraße\",\n  \"Semriacherstraße\",\n  \"Simling\",\n  \"Sipbachzeller Straße\",\n  \"Sonnenweg\",\n  \"Spargelfeldgasse\",\n  \"Spiesmayrweg\",\n  \"Sportplatzstraße\",\n  \"St.Ulrich\",\n  \"Steilmannstraße\",\n  \"Steingrüneredt\",\n  \"Strassfeld\",\n  \"Straßerau\",\n  \"Stöpflweg\",\n  \"Stüra\",\n  \"Taferngasse\",\n  \"Tennweg\",\n  \"Thomas Koschat-Gasse\",\n  \"Tiroler Straße\",\n  \"Torrogasse\",\n  \"Uferstraße (Schwarzau am Steinfeld)\",\n  \"Unterdörfl\",\n  \"Unterer Sonnrainweg\",\n  \"Verwaltersiedlung\",\n  \"Waldhang\",\n  \"Wasen\",\n  \"Weidenstraße\",\n  \"Weiherweg\",\n  \"Wettsteingasse\",\n  \"Wiener Straße\",\n  \"Windisch\",\n  \"Zebragasse\",\n  \"Zellerstraße\",\n  \"Ziehrerstraße\",\n  \"Zulechnerweg\",\n  \"Zwergjoch\",\n  \"Ötzbruck\"\n];\n\n},{}],144:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"+43-6##-#######\",\n  \"06##-########\",\n  \"+436#########\",\n  \"06##########\"\n];\n\n},{}],145:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":144,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],146:[function(require,module,exports){\nmodule.exports=require(113)\n},{\"./legal_form\":147,\"./name\":148,\"./suffix\":149,\"/Users/a/dev/faker.js/lib/locales/de/company/index.js\":113}],147:[function(require,module,exports){\nmodule.exports=require(114)\n},{\"/Users/a/dev/faker.js/lib/locales/de/company/legal_form.js\":114}],148:[function(require,module,exports){\nmodule.exports=require(115)\n},{\"/Users/a/dev/faker.js/lib/locales/de/company/name.js\":115}],149:[function(require,module,exports){\nmodule.exports=require(114)\n},{\"/Users/a/dev/faker.js/lib/locales/de/company/legal_form.js\":114}],150:[function(require,module,exports){\nvar de_AT = {};\nmodule['exports'] = de_AT;\nde_AT.title = \"German (Austria)\";\nde_AT.address = require(\"./address\");\nde_AT.company = require(\"./company\");\nde_AT.internet = require(\"./internet\");\nde_AT.name = require(\"./name\");\nde_AT.phone_number = require(\"./phone_number\");\nde_AT.cell_phone = require(\"./cell_phone\");\n\n},{\"./address\":136,\"./cell_phone\":145,\"./company\":146,\"./internet\":153,\"./name\":155,\"./phone_number\":161}],151:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\",\n  \"de\",\n  \"ch\",\n  \"at\"\n];\n\n},{}],152:[function(require,module,exports){\nmodule.exports=require(119)\n},{\"/Users/a/dev/faker.js/lib/locales/de/internet/free_email.js\":119}],153:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":151,\"./free_email\":152,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],154:[function(require,module,exports){\nmodule.exports=require(123)\n},{\"/Users/a/dev/faker.js/lib/locales/de/name/first_name.js\":123}],155:[function(require,module,exports){\narguments[4][124][0].apply(exports,arguments)\n},{\"./first_name\":154,\"./last_name\":156,\"./name\":157,\"./nobility_title_prefix\":158,\"./prefix\":159,\"/Users/a/dev/faker.js/lib/locales/de/name/index.js\":124}],156:[function(require,module,exports){\nmodule.exports=require(125)\n},{\"/Users/a/dev/faker.js/lib/locales/de/name/last_name.js\":125}],157:[function(require,module,exports){\nmodule.exports=require(126)\n},{\"/Users/a/dev/faker.js/lib/locales/de/name/name.js\":126}],158:[function(require,module,exports){\nmodule.exports=require(127)\n},{\"/Users/a/dev/faker.js/lib/locales/de/name/nobility_title_prefix.js\":127}],159:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Dr.\",\n  \"Prof. Dr.\"\n];\n\n},{}],160:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"01 #######\",\n  \"01#######\",\n  \"+43-1-#######\",\n  \"+431#######\",\n  \"0#### ####\",\n  \"0#########\",\n  \"+43-####-####\",\n  \"+43 ########\"\n];\n\n},{}],161:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":160,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],162:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"CH\",\n  \"CH\",\n  \"CH\",\n  \"DE\",\n  \"AT\",\n  \"US\",\n  \"LI\",\n  \"US\",\n  \"HK\",\n  \"VN\"\n];\n\n},{}],163:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Schweiz\"\n];\n\n},{}],164:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.country_code = require(\"./country_code\");\naddress.postcode = require(\"./postcode\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./country_code\":162,\"./default_country\":163,\"./postcode\":165}],165:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"1###\",\n  \"2###\",\n  \"3###\",\n  \"4###\",\n  \"5###\",\n  \"6###\",\n  \"7###\",\n  \"8###\",\n  \"9###\"\n];\n\n},{}],166:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.name = require(\"./name\");\n\n},{\"./name\":167,\"./suffix\":168}],167:[function(require,module,exports){\nmodule.exports=require(115)\n},{\"/Users/a/dev/faker.js/lib/locales/de/company/name.js\":115}],168:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AG\",\n  \"GmbH\",\n  \"und Söhne\",\n  \"und Partner\",\n  \"& Co.\",\n  \"Gruppe\",\n  \"LLC\",\n  \"Inc.\"\n];\n\n},{}],169:[function(require,module,exports){\nvar de_CH = {};\nmodule['exports'] = de_CH;\nde_CH.title = \"German (Switzerland)\";\nde_CH.address = require(\"./address\");\nde_CH.company = require(\"./company\");\nde_CH.internet = require(\"./internet\");\nde_CH.name = require(\"./name\");\nde_CH.phone_number = require(\"./phone_number\");\n\n},{\"./address\":164,\"./company\":166,\"./internet\":171,\"./name\":173,\"./phone_number\":178}],170:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"net\",\n  \"biz\",\n  \"ch\",\n  \"de\",\n  \"li\",\n  \"at\",\n  \"ch\",\n  \"ch\"\n];\n\n},{}],171:[function(require,module,exports){\nvar internet = {};\nmodule['exports'] = internet;\ninternet.domain_suffix = require(\"./domain_suffix\");\n\n},{\"./domain_suffix\":170}],172:[function(require,module,exports){\nmodule[\"exports\"] = [\n    \"Adolf\",\n    \"Adrian\",\n    \"Agnes\",\n    \"Alain\",\n    \"Albert\",\n    \"Alberto\",\n    \"Aldo\",\n    \"Alex\",\n    \"Alexander\",\n    \"Alexandre\",\n    \"Alfons\",\n    \"Alfred\",\n    \"Alice\",\n    \"Alois\",\n    \"André\",\n    \"Andrea\",\n    \"Andreas\",\n    \"Angela\",\n    \"Angelo\",\n    \"Anita\",\n    \"Anna\",\n    \"Anne\",\n    \"Anne-Marie\",\n    \"Annemarie\",\n    \"Antoine\",\n    \"Anton\",\n    \"Antonio\",\n    \"Armin\",\n    \"Arnold\",\n    \"Arthur\",\n    \"Astrid\",\n    \"Barbara\",\n    \"Beat\",\n    \"Beatrice\",\n    \"Beatrix\",\n    \"Bernadette\",\n    \"Bernard\",\n    \"Bernhard\",\n    \"Bettina\",\n    \"Brigitta\",\n    \"Brigitte\",\n    \"Bruno\",\n    \"Carlo\",\n    \"Carmen\",\n    \"Caroline\",\n    \"Catherine\",\n    \"Chantal\",\n    \"Charles\",\n    \"Charlotte\",\n    \"Christa\",\n    \"Christian\",\n    \"Christiane\",\n    \"Christina\",\n    \"Christine\",\n    \"Christoph\",\n    \"Christophe\",\n    \"Claire\",\n    \"Claude\",\n    \"Claudia\",\n    \"Claudine\",\n    \"Claudio\",\n    \"Corinne\",\n    \"Cornelia\",\n    \"Daniel\",\n    \"Daniela\",\n    \"Daniele\",\n    \"Danielle\",\n    \"David\",\n    \"Denis\",\n    \"Denise\",\n    \"Didier\",\n    \"Dieter\",\n    \"Dominik\",\n    \"Dominique\",\n    \"Dora\",\n    \"Doris\",\n    \"Edgar\",\n    \"Edith\",\n    \"Eduard\",\n    \"Edwin\",\n    \"Eliane\",\n    \"Elisabeth\",\n    \"Elsa\",\n    \"Elsbeth\",\n    \"Emil\",\n    \"Enrico\",\n    \"Eric\",\n    \"Erica\",\n    \"Erich\",\n    \"Erika\",\n    \"Ernst\",\n    \"Erwin\",\n    \"Esther\",\n    \"Eugen\",\n    \"Eva\",\n    \"Eveline\",\n    \"Evelyne\",\n    \"Fabienne\",\n    \"Felix\",\n    \"Ferdinand\",\n    \"Florence\",\n    \"Francesco\",\n    \"Francis\",\n    \"Franco\",\n    \"François\",\n    \"Françoise\",\n    \"Frank\",\n    \"Franz\",\n    \"Franziska\",\n    \"Frédéric\",\n    \"Fredy\",\n    \"Fridolin\",\n    \"Friedrich\",\n    \"Fritz\",\n    \"Gabriel\",\n    \"Gabriela\",\n    \"Gabrielle\",\n    \"Georg\",\n    \"Georges\",\n    \"Gérald\",\n    \"Gérard\",\n    \"Gerhard\",\n    \"Gertrud\",\n    \"Gianni\",\n    \"Gilbert\",\n    \"Giorgio\",\n    \"Giovanni\",\n    \"Gisela\",\n    \"Giuseppe\",\n    \"Gottfried\",\n    \"Guido\",\n    \"Guy\",\n    \"Hanna\",\n    \"Hans\",\n    \"Hans-Peter\",\n    \"Hans-Rudolf\",\n    \"Hans-Ulrich\",\n    \"Hansjörg\",\n    \"Hanspeter\",\n    \"Hansruedi\",\n    \"Hansueli\",\n    \"Harry\",\n    \"Heidi\",\n    \"Heinrich\",\n    \"Heinz\",\n    \"Helen\",\n    \"Helena\",\n    \"Helene\",\n    \"Helmut\",\n    \"Henri\",\n    \"Herbert\",\n    \"Hermann\",\n    \"Hildegard\",\n    \"Hubert\",\n    \"Hugo\",\n    \"Ingrid\",\n    \"Irene\",\n    \"Iris\",\n    \"Isabelle\",\n    \"Jacqueline\",\n    \"Jacques\",\n    \"Jakob\",\n    \"Jan\",\n    \"Janine\",\n    \"Jean\",\n    \"Jean-Claude\",\n    \"Jean-Daniel\",\n    \"Jean-François\",\n    \"Jean-Jacques\",\n    \"Jean-Louis\",\n    \"Jean-Luc\",\n    \"Jean-Marc\",\n    \"Jean-Marie\",\n    \"Jean-Paul\",\n    \"Jean-Pierre\",\n    \"Johann\",\n    \"Johanna\",\n    \"Johannes\",\n    \"John\",\n    \"Jolanda\",\n    \"Jörg\",\n    \"Josef\",\n    \"Joseph\",\n    \"Josette\",\n    \"Josiane\",\n    \"Judith\",\n    \"Julia\",\n    \"Jürg\",\n    \"Karin\",\n    \"Karl\",\n    \"Katharina\",\n    \"Klaus\",\n    \"Konrad\",\n    \"Kurt\",\n    \"Laura\",\n    \"Laurence\",\n    \"Laurent\",\n    \"Leo\",\n    \"Liliane\",\n    \"Liselotte\",\n    \"Louis\",\n    \"Luca\",\n    \"Luigi\",\n    \"Lukas\",\n    \"Lydia\",\n    \"Madeleine\",\n    \"Maja\",\n    \"Manfred\",\n    \"Manuel\",\n    \"Manuela\",\n    \"Marc\",\n    \"Marcel\",\n    \"Marco\",\n    \"Margrit\",\n    \"Margrith\",\n    \"Maria\",\n    \"Marianne\",\n    \"Mario\",\n    \"Marion\",\n    \"Markus\",\n    \"Marlène\",\n    \"Marlies\",\n    \"Marlis\",\n    \"Martha\",\n    \"Martin\",\n    \"Martina\",\n    \"Martine\",\n    \"Massimo\",\n    \"Matthias\",\n    \"Maurice\",\n    \"Max\",\n    \"Maya\",\n    \"Michael\",\n    \"Michel\",\n    \"Michele\",\n    \"Micheline\",\n    \"Monica\",\n    \"Monika\",\n    \"Monique\",\n    \"Myriam\",\n    \"Nadia\",\n    \"Nadja\",\n    \"Nathalie\",\n    \"Nelly\",\n    \"Nicolas\",\n    \"Nicole\",\n    \"Niklaus\",\n    \"Norbert\",\n    \"Olivier\",\n    \"Oskar\",\n    \"Otto\",\n    \"Paola\",\n    \"Paolo\",\n    \"Pascal\",\n    \"Patricia\",\n    \"Patrick\",\n    \"Paul\",\n    \"Peter\",\n    \"Petra\",\n    \"Philipp\",\n    \"Philippe\",\n    \"Pia\",\n    \"Pierre\",\n    \"Pierre-Alain\",\n    \"Pierre-André\",\n    \"Pius\",\n    \"Priska\",\n    \"Rainer\",\n    \"Raymond\",\n    \"Regina\",\n    \"Regula\",\n    \"Reinhard\",\n    \"Remo\",\n    \"Renata\",\n    \"Renate\",\n    \"Renato\",\n    \"Rene\",\n    \"René\",\n    \"Reto\",\n    \"Richard\",\n    \"Rita\",\n    \"Robert\",\n    \"Roberto\",\n    \"Roger\",\n    \"Roland\",\n    \"Rolf\",\n    \"Roman\",\n    \"Rosa\",\n    \"Rosemarie\",\n    \"Rosmarie\",\n    \"Rudolf\",\n    \"Ruedi\",\n    \"Ruth\",\n    \"Sabine\",\n    \"Samuel\",\n    \"Sandra\",\n    \"Sandro\",\n    \"Serge\",\n    \"Silvia\",\n    \"Silvio\",\n    \"Simon\",\n    \"Simone\",\n    \"Sonia\",\n    \"Sonja\",\n    \"Stefan\",\n    \"Stephan\",\n    \"Stéphane\",\n    \"Stéphanie\",\n    \"Susanna\",\n    \"Susanne\",\n    \"Suzanne\",\n    \"Sylvia\",\n    \"Sylvie\",\n    \"Theo\",\n    \"Theodor\",\n    \"Therese\",\n    \"Thomas\",\n    \"Toni\",\n    \"Ueli\",\n    \"Ulrich\",\n    \"Urs\",\n    \"Ursula\",\n    \"Verena\",\n    \"Véronique\",\n    \"Victor\",\n    \"Viktor\",\n    \"Vreni\",\n    \"Walter\",\n    \"Werner\",\n    \"Willi\",\n    \"Willy\",\n    \"Wolfgang\",\n    \"Yolande\",\n    \"Yves\",\n    \"Yvette\",\n    \"Yvonne\",\n\n];\n\n},{}],173:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.name = require(\"./name\");\n\n},{\"./first_name\":172,\"./last_name\":174,\"./name\":175,\"./prefix\":176}],174:[function(require,module,exports){\nmodule[\"exports\"] = [\n    \"Ackermann\",\n    \"Aebi\",\n    \"Albrecht\",\n    \"Ammann\",\n    \"Amrein\",\n    \"Arnold\",\n    \"Bachmann\",\n    \"Bader\",\n    \"Bär\",\n    \"Bättig\",\n    \"Bauer\",\n    \"Baumann\",\n    \"Baumgartner\",\n    \"Baur\",\n    \"Beck\",\n    \"Benz\",\n    \"Berger\",\n    \"Bernasconi\",\n    \"Betschart\",\n    \"Bianchi\",\n    \"Bieri\",\n    \"Blaser\",\n    \"Blum\",\n    \"Bolliger\",\n    \"Bosshard\",\n    \"Braun\",\n    \"Brun\",\n    \"Brunner\",\n    \"Bucher\",\n    \"Bühler\",\n    \"Bühlmann\",\n    \"Burri\",\n    \"Christen\",\n    \"Egger\",\n    \"Egli\",\n    \"Eichenberger\",\n    \"Erni\",\n    \"Ernst\",\n    \"Eugster\",\n    \"Fankhauser\",\n    \"Favre\",\n    \"Fehr\",\n    \"Felber\",\n    \"Felder\",\n    \"Ferrari\",\n    \"Fischer\",\n    \"Flückiger\",\n    \"Forster\",\n    \"Frei\",\n    \"Frey\",\n    \"Frick\",\n    \"Friedli\",\n    \"Fuchs\",\n    \"Furrer\",\n    \"Gasser\",\n    \"Geiger\",\n    \"Gerber\",\n    \"Gfeller\",\n    \"Giger\",\n    \"Gloor\",\n    \"Graf\",\n    \"Grob\",\n    \"Gross\",\n    \"Gut\",\n    \"Haas\",\n    \"Häfliger\",\n    \"Hafner\",\n    \"Hartmann\",\n    \"Hasler\",\n    \"Hauser\",\n    \"Hermann\",\n    \"Herzog\",\n    \"Hess\",\n    \"Hirt\",\n    \"Hodel\",\n    \"Hofer\",\n    \"Hoffmann\",\n    \"Hofmann\",\n    \"Hofstetter\",\n    \"Hotz\",\n    \"Huber\",\n    \"Hug\",\n    \"Hunziker\",\n    \"Hürlimann\",\n    \"Imhof\",\n    \"Isler\",\n    \"Iten\",\n    \"Jäggi\",\n    \"Jenni\",\n    \"Jost\",\n    \"Kägi\",\n    \"Kaiser\",\n    \"Kälin\",\n    \"Käser\",\n    \"Kaufmann\",\n    \"Keller\",\n    \"Kern\",\n    \"Kessler\",\n    \"Knecht\",\n    \"Koch\",\n    \"Kohler\",\n    \"Kuhn\",\n    \"Küng\",\n    \"Kunz\",\n    \"Lang\",\n    \"Lanz\",\n    \"Lehmann\",\n    \"Leu\",\n    \"Leunberger\",\n    \"Lüscher\",\n    \"Lustenberger\",\n    \"Lüthi\",\n    \"Lutz\",\n    \"Mäder\",\n    \"Maier\",\n    \"Marti\",\n    \"Martin\",\n    \"Maurer\",\n    \"Mayer\",\n    \"Meier\",\n    \"Meili\",\n    \"Meister\",\n    \"Merz\",\n    \"Mettler\",\n    \"Meyer\",\n    \"Michel\",\n    \"Moser\",\n    \"Müller\",\n    \"Näf\",\n    \"Ott\",\n    \"Peter\",\n    \"Pfister\",\n    \"Portmann\",\n    \"Probst\",\n    \"Rey\",\n    \"Ritter\",\n    \"Roos\",\n    \"Roth\",\n    \"Rüegg\",\n    \"Schäfer\",\n    \"Schaller\",\n    \"Schär\",\n    \"Schärer\",\n    \"Schaub\",\n    \"Scheidegger\",\n    \"Schenk\",\n    \"Scherrer\",\n    \"Schlatter\",\n    \"Schmid\",\n    \"Schmidt\",\n    \"Schneider\",\n    \"Schnyder\",\n    \"Schoch\",\n    \"Schuler\",\n    \"Schumacher\",\n    \"Schürch\",\n    \"Schwab\",\n    \"Schwarz\",\n    \"Schweizer\",\n    \"Seiler\",\n    \"Senn\",\n    \"Sidler\",\n    \"Siegrist\",\n    \"Sigrist\",\n    \"Spörri\",\n    \"Stadelmann\",\n    \"Stalder\",\n    \"Staub\",\n    \"Stauffer\",\n    \"Steffen\",\n    \"Steiger\",\n    \"Steiner\",\n    \"Steinmann\",\n    \"Stettler\",\n    \"Stocker\",\n    \"Stöckli\",\n    \"Stucki\",\n    \"Studer\",\n    \"Stutz\",\n    \"Suter\",\n    \"Sutter\",\n    \"Tanner\",\n    \"Thommen\",\n    \"Tobler\",\n    \"Vogel\",\n    \"Vogt\",\n    \"Wagner\",\n    \"Walder\",\n    \"Walter\",\n    \"Weber\",\n    \"Wegmann\",\n    \"Wehrli\",\n    \"Weibel\",\n    \"Wenger\",\n    \"Wettstein\",\n    \"Widmer\",\n    \"Winkler\",\n    \"Wirth\",\n    \"Wirz\",\n    \"Wolf\",\n    \"Wüthrich\",\n    \"Wyss\",\n    \"Zbinden\",\n    \"Zehnder\",\n    \"Ziegler\",\n    \"Zimmermann\",\n    \"Zingg\",\n    \"Zollinger\",\n    \"Zürcher\"\n];\n\n},{}],175:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\"\n];\n\n},{}],176:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Hr.\",\n  \"Fr.\",\n  \"Dr.\"\n];\n\n},{}],177:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"0800 ### ###\",\n  \"0800 ## ## ##\",\n  \"0## ### ## ##\",\n  \"0## ### ## ##\",\n  \"+41 ## ### ## ##\",\n  \"0900 ### ###\",\n  \"076 ### ## ##\",\n  \"+4178 ### ## ##\",\n  \"0041 79 ### ## ##\"\n];\n\n},{}],178:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":177,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],179:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\",\n  \"####\",\n  \"###\"\n];\n\n},{}],180:[function(require,module,exports){\nmodule.exports=require(98)\n},{\"/Users/a/dev/faker.js/lib/locales/de/address/city.js\":98}],181:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"North\",\n  \"East\",\n  \"West\",\n  \"South\",\n  \"New\",\n  \"Lake\",\n  \"Port\"\n];\n\n},{}],182:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"town\",\n  \"ton\",\n  \"land\",\n  \"ville\",\n  \"berg\",\n  \"burgh\",\n  \"borough\",\n  \"bury\",\n  \"view\",\n  \"port\",\n  \"mouth\",\n  \"stad\",\n  \"furt\",\n  \"chester\",\n  \"mouth\",\n  \"fort\",\n  \"haven\",\n  \"side\",\n  \"shire\"\n];\n\n},{}],183:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afghanistan\",\n  \"Albania\",\n  \"Algeria\",\n  \"American Samoa\",\n  \"Andorra\",\n  \"Angola\",\n  \"Anguilla\",\n  \"Antarctica (the territory South of 60 deg S)\",\n  \"Antigua and Barbuda\",\n  \"Argentina\",\n  \"Armenia\",\n  \"Aruba\",\n  \"Australia\",\n  \"Austria\",\n  \"Azerbaijan\",\n  \"Bahamas\",\n  \"Bahrain\",\n  \"Bangladesh\",\n  \"Barbados\",\n  \"Belarus\",\n  \"Belgium\",\n  \"Belize\",\n  \"Benin\",\n  \"Bermuda\",\n  \"Bhutan\",\n  \"Bolivia\",\n  \"Bosnia and Herzegovina\",\n  \"Botswana\",\n  \"Bouvet Island (Bouvetoya)\",\n  \"Brazil\",\n  \"British Indian Ocean Territory (Chagos Archipelago)\",\n  \"Brunei Darussalam\",\n  \"Bulgaria\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Cambodia\",\n  \"Cameroon\",\n  \"Canada\",\n  \"Cape Verde\",\n  \"Cayman Islands\",\n  \"Central African Republic\",\n  \"Chad\",\n  \"Chile\",\n  \"China\",\n  \"Christmas Island\",\n  \"Cocos (Keeling) Islands\",\n  \"Colombia\",\n  \"Comoros\",\n  \"Congo\",\n  \"Cook Islands\",\n  \"Costa Rica\",\n  \"Cote d'Ivoire\",\n  \"Croatia\",\n  \"Cuba\",\n  \"Cyprus\",\n  \"Czech Republic\",\n  \"Denmark\",\n  \"Djibouti\",\n  \"Dominica\",\n  \"Dominican Republic\",\n  \"Ecuador\",\n  \"Egypt\",\n  \"El Salvador\",\n  \"Equatorial Guinea\",\n  \"Eritrea\",\n  \"Estonia\",\n  \"Ethiopia\",\n  \"Faroe Islands\",\n  \"Falkland Islands (Malvinas)\",\n  \"Fiji\",\n  \"Finland\",\n  \"France\",\n  \"French Guiana\",\n  \"French Polynesia\",\n  \"French Southern Territories\",\n  \"Gabon\",\n  \"Gambia\",\n  \"Georgia\",\n  \"Germany\",\n  \"Ghana\",\n  \"Gibraltar\",\n  \"Greece\",\n  \"Greenland\",\n  \"Grenada\",\n  \"Guadeloupe\",\n  \"Guam\",\n  \"Guatemala\",\n  \"Guernsey\",\n  \"Guinea\",\n  \"Guinea-Bissau\",\n  \"Guyana\",\n  \"Haiti\",\n  \"Heard Island and McDonald Islands\",\n  \"Holy See (Vatican City State)\",\n  \"Honduras\",\n  \"Hong Kong\",\n  \"Hungary\",\n  \"Iceland\",\n  \"India\",\n  \"Indonesia\",\n  \"Iran\",\n  \"Iraq\",\n  \"Ireland\",\n  \"Isle of Man\",\n  \"Israel\",\n  \"Italy\",\n  \"Jamaica\",\n  \"Japan\",\n  \"Jersey\",\n  \"Jordan\",\n  \"Kazakhstan\",\n  \"Kenya\",\n  \"Kiribati\",\n  \"Democratic People's Republic of Korea\",\n  \"Republic of Korea\",\n  \"Kuwait\",\n  \"Kyrgyz Republic\",\n  \"Lao People's Democratic Republic\",\n  \"Latvia\",\n  \"Lebanon\",\n  \"Lesotho\",\n  \"Liberia\",\n  \"Libyan Arab Jamahiriya\",\n  \"Liechtenstein\",\n  \"Lithuania\",\n  \"Luxembourg\",\n  \"Macao\",\n  \"Macedonia\",\n  \"Madagascar\",\n  \"Malawi\",\n  \"Malaysia\",\n  \"Maldives\",\n  \"Mali\",\n  \"Malta\",\n  \"Marshall Islands\",\n  \"Martinique\",\n  \"Mauritania\",\n  \"Mauritius\",\n  \"Mayotte\",\n  \"Mexico\",\n  \"Micronesia\",\n  \"Moldova\",\n  \"Monaco\",\n  \"Mongolia\",\n  \"Montenegro\",\n  \"Montserrat\",\n  \"Morocco\",\n  \"Mozambique\",\n  \"Myanmar\",\n  \"Namibia\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Netherlands Antilles\",\n  \"Netherlands\",\n  \"New Caledonia\",\n  \"New Zealand\",\n  \"Nicaragua\",\n  \"Niger\",\n  \"Nigeria\",\n  \"Niue\",\n  \"Norfolk Island\",\n  \"Northern Mariana Islands\",\n  \"Norway\",\n  \"Oman\",\n  \"Pakistan\",\n  \"Palau\",\n  \"Palestinian Territory\",\n  \"Panama\",\n  \"Papua New Guinea\",\n  \"Paraguay\",\n  \"Peru\",\n  \"Philippines\",\n  \"Pitcairn Islands\",\n  \"Poland\",\n  \"Portugal\",\n  \"Puerto Rico\",\n  \"Qatar\",\n  \"Reunion\",\n  \"Romania\",\n  \"Russian Federation\",\n  \"Rwanda\",\n  \"Saint Barthelemy\",\n  \"Saint Helena\",\n  \"Saint Kitts and Nevis\",\n  \"Saint Lucia\",\n  \"Saint Martin\",\n  \"Saint Pierre and Miquelon\",\n  \"Saint Vincent and the Grenadines\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Sao Tome and Principe\",\n  \"Saudi Arabia\",\n  \"Senegal\",\n  \"Serbia\",\n  \"Seychelles\",\n  \"Sierra Leone\",\n  \"Singapore\",\n  \"Slovakia (Slovak Republic)\",\n  \"Slovenia\",\n  \"Solomon Islands\",\n  \"Somalia\",\n  \"South Africa\",\n  \"South Georgia and the South Sandwich Islands\",\n  \"Spain\",\n  \"Sri Lanka\",\n  \"Sudan\",\n  \"Suriname\",\n  \"Svalbard & Jan Mayen Islands\",\n  \"Swaziland\",\n  \"Sweden\",\n  \"Switzerland\",\n  \"Syrian Arab Republic\",\n  \"Taiwan\",\n  \"Tajikistan\",\n  \"Tanzania\",\n  \"Thailand\",\n  \"Timor-Leste\",\n  \"Togo\",\n  \"Tokelau\",\n  \"Tonga\",\n  \"Trinidad and Tobago\",\n  \"Tunisia\",\n  \"Turkey\",\n  \"Turkmenistan\",\n  \"Turks and Caicos Islands\",\n  \"Tuvalu\",\n  \"Uganda\",\n  \"Ukraine\",\n  \"United Arab Emirates\",\n  \"United Kingdom\",\n  \"United States of America\",\n  \"United States Minor Outlying Islands\",\n  \"Uruguay\",\n  \"Uzbekistan\",\n  \"Vanuatu\",\n  \"Venezuela\",\n  \"Vietnam\",\n  \"Virgin Islands, British\",\n  \"Virgin Islands, U.S.\",\n  \"Wallis and Futuna\",\n  \"Western Sahara\",\n  \"Yemen\",\n  \"Zambia\",\n  \"Zimbabwe\"\n];\n\n},{}],184:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AD\",\n  \"AE\",\n  \"AF\",\n  \"AG\",\n  \"AI\",\n  \"AL\",\n  \"AM\",\n  \"AO\",\n  \"AQ\",\n  \"AR\",\n  \"AS\",\n  \"AT\",\n  \"AU\",\n  \"AW\",\n  \"AX\",\n  \"AZ\",\n  \"BA\",\n  \"BB\",\n  \"BD\",\n  \"BE\",\n  \"BF\",\n  \"BG\",\n  \"BH\",\n  \"BI\",\n  \"BJ\",\n  \"BL\",\n  \"BM\",\n  \"BN\",\n  \"BO\",\n  \"BQ\",\n  \"BQ\",\n  \"BR\",\n  \"BS\",\n  \"BT\",\n  \"BV\",\n  \"BW\",\n  \"BY\",\n  \"BZ\",\n  \"CA\",\n  \"CC\",\n  \"CD\",\n  \"CF\",\n  \"CG\",\n  \"CH\",\n  \"CI\",\n  \"CK\",\n  \"CL\",\n  \"CM\",\n  \"CN\",\n  \"CO\",\n  \"CR\",\n  \"CU\",\n  \"CV\",\n  \"CW\",\n  \"CX\",\n  \"CY\",\n  \"CZ\",\n  \"DE\",\n  \"DJ\",\n  \"DK\",\n  \"DM\",\n  \"DO\",\n  \"DZ\",\n  \"EC\",\n  \"EE\",\n  \"EG\",\n  \"EH\",\n  \"ER\",\n  \"ES\",\n  \"ET\",\n  \"FI\",\n  \"FJ\",\n  \"FK\",\n  \"FM\",\n  \"FO\",\n  \"FR\",\n  \"GA\",\n  \"GB\",\n  \"GD\",\n  \"GE\",\n  \"GF\",\n  \"GG\",\n  \"GH\",\n  \"GI\",\n  \"GL\",\n  \"GM\",\n  \"GN\",\n  \"GP\",\n  \"GQ\",\n  \"GR\",\n  \"GS\",\n  \"GT\",\n  \"GU\",\n  \"GW\",\n  \"GY\",\n  \"HK\",\n  \"HM\",\n  \"HN\",\n  \"HR\",\n  \"HT\",\n  \"HU\",\n  \"ID\",\n  \"IE\",\n  \"IL\",\n  \"IM\",\n  \"IN\",\n  \"IO\",\n  \"IQ\",\n  \"IR\",\n  \"IS\",\n  \"IT\",\n  \"JE\",\n  \"JM\",\n  \"JO\",\n  \"JP\",\n  \"KE\",\n  \"KG\",\n  \"KH\",\n  \"KI\",\n  \"KM\",\n  \"KN\",\n  \"KP\",\n  \"KR\",\n  \"KW\",\n  \"KY\",\n  \"KZ\",\n  \"LA\",\n  \"LB\",\n  \"LC\",\n  \"LI\",\n  \"LK\",\n  \"LR\",\n  \"LS\",\n  \"LT\",\n  \"LU\",\n  \"LV\",\n  \"LY\",\n  \"MA\",\n  \"MC\",\n  \"MD\",\n  \"ME\",\n  \"MF\",\n  \"MG\",\n  \"MH\",\n  \"MK\",\n  \"ML\",\n  \"MM\",\n  \"MN\",\n  \"MO\",\n  \"MP\",\n  \"MQ\",\n  \"MR\",\n  \"MS\",\n  \"MT\",\n  \"MU\",\n  \"MV\",\n  \"MW\",\n  \"MX\",\n  \"MY\",\n  \"MZ\",\n  \"NA\",\n  \"NC\",\n  \"NE\",\n  \"NF\",\n  \"NG\",\n  \"NI\",\n  \"NL\",\n  \"NO\",\n  \"NP\",\n  \"NR\",\n  \"NU\",\n  \"NZ\",\n  \"OM\",\n  \"PA\",\n  \"PE\",\n  \"PF\",\n  \"PG\",\n  \"PH\",\n  \"PK\",\n  \"PL\",\n  \"PM\",\n  \"PN\",\n  \"PR\",\n  \"PS\",\n  \"PT\",\n  \"PW\",\n  \"PY\",\n  \"QA\",\n  \"RE\",\n  \"RO\",\n  \"RS\",\n  \"RU\",\n  \"RW\",\n  \"SA\",\n  \"SB\",\n  \"SC\",\n  \"SD\",\n  \"SE\",\n  \"SG\",\n  \"SH\",\n  \"SI\",\n  \"SJ\",\n  \"SK\",\n  \"SL\",\n  \"SM\",\n  \"SN\",\n  \"SO\",\n  \"SR\",\n  \"SS\",\n  \"ST\",\n  \"SV\",\n  \"SX\",\n  \"SY\",\n  \"SZ\",\n  \"TC\",\n  \"TD\",\n  \"TF\",\n  \"TG\",\n  \"TH\",\n  \"TJ\",\n  \"TK\",\n  \"TL\",\n  \"TM\",\n  \"TN\",\n  \"TO\",\n  \"TR\",\n  \"TT\",\n  \"TV\",\n  \"TW\",\n  \"TZ\",\n  \"UA\",\n  \"UG\",\n  \"UM\",\n  \"US\",\n  \"UY\",\n  \"UZ\",\n  \"VA\",\n  \"VC\",\n  \"VE\",\n  \"VG\",\n  \"VI\",\n  \"VN\",\n  \"VU\",\n  \"WF\",\n  \"WS\",\n  \"YE\",\n  \"YT\",\n  \"ZA\",\n  \"ZM\",\n  \"ZW\"\n];\n\n},{}],185:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Avon\",\n  \"Bedfordshire\",\n  \"Berkshire\",\n  \"Borders\",\n  \"Buckinghamshire\",\n  \"Cambridgeshire\"\n];\n\n},{}],186:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"United States of America\"\n];\n\n},{}],187:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.county = require(\"./county\");\naddress.country = require(\"./country\");\naddress.country_code = require(\"./country_code\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.postcode_by_state = require(\"./postcode_by_state\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.time_zone = require(\"./time_zone\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":179,\"./city\":180,\"./city_prefix\":181,\"./city_suffix\":182,\"./country\":183,\"./country_code\":184,\"./county\":185,\"./default_country\":186,\"./postcode\":188,\"./postcode_by_state\":189,\"./secondary_address\":190,\"./state\":191,\"./state_abbr\":192,\"./street_address\":193,\"./street_name\":194,\"./street_suffix\":195,\"./time_zone\":196}],188:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\",\n  \"#####-####\"\n];\n\n},{}],189:[function(require,module,exports){\nmodule.exports=require(188)\n},{\"/Users/a/dev/faker.js/lib/locales/en/address/postcode.js\":188}],190:[function(require,module,exports){\nmodule.exports=require(61)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/secondary_address.js\":61}],191:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Alabama\",\n  \"Alaska\",\n  \"Arizona\",\n  \"Arkansas\",\n  \"California\",\n  \"Colorado\",\n  \"Connecticut\",\n  \"Delaware\",\n  \"Florida\",\n  \"Georgia\",\n  \"Hawaii\",\n  \"Idaho\",\n  \"Illinois\",\n  \"Indiana\",\n  \"Iowa\",\n  \"Kansas\",\n  \"Kentucky\",\n  \"Louisiana\",\n  \"Maine\",\n  \"Maryland\",\n  \"Massachusetts\",\n  \"Michigan\",\n  \"Minnesota\",\n  \"Mississippi\",\n  \"Missouri\",\n  \"Montana\",\n  \"Nebraska\",\n  \"Nevada\",\n  \"New Hampshire\",\n  \"New Jersey\",\n  \"New Mexico\",\n  \"New York\",\n  \"North Carolina\",\n  \"North Dakota\",\n  \"Ohio\",\n  \"Oklahoma\",\n  \"Oregon\",\n  \"Pennsylvania\",\n  \"Rhode Island\",\n  \"South Carolina\",\n  \"South Dakota\",\n  \"Tennessee\",\n  \"Texas\",\n  \"Utah\",\n  \"Vermont\",\n  \"Virginia\",\n  \"Washington\",\n  \"West Virginia\",\n  \"Wisconsin\",\n  \"Wyoming\"\n];\n\n},{}],192:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AL\",\n  \"AK\",\n  \"AZ\",\n  \"AR\",\n  \"CA\",\n  \"CO\",\n  \"CT\",\n  \"DE\",\n  \"FL\",\n  \"GA\",\n  \"HI\",\n  \"ID\",\n  \"IL\",\n  \"IN\",\n  \"IA\",\n  \"KS\",\n  \"KY\",\n  \"LA\",\n  \"ME\",\n  \"MD\",\n  \"MA\",\n  \"MI\",\n  \"MN\",\n  \"MS\",\n  \"MO\",\n  \"MT\",\n  \"NE\",\n  \"NV\",\n  \"NH\",\n  \"NJ\",\n  \"NM\",\n  \"NY\",\n  \"NC\",\n  \"ND\",\n  \"OH\",\n  \"OK\",\n  \"OR\",\n  \"PA\",\n  \"RI\",\n  \"SC\",\n  \"SD\",\n  \"TN\",\n  \"TX\",\n  \"UT\",\n  \"VT\",\n  \"VA\",\n  \"WA\",\n  \"WV\",\n  \"WI\",\n  \"WY\"\n];\n\n},{}],193:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{building_number} #{street_name}\"\n];\n\n},{}],194:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.first_name} #{street_suffix}\",\n  \"#{Name.last_name} #{street_suffix}\"\n];\n\n},{}],195:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Alley\",\n  \"Avenue\",\n  \"Branch\",\n  \"Bridge\",\n  \"Brook\",\n  \"Brooks\",\n  \"Burg\",\n  \"Burgs\",\n  \"Bypass\",\n  \"Camp\",\n  \"Canyon\",\n  \"Cape\",\n  \"Causeway\",\n  \"Center\",\n  \"Centers\",\n  \"Circle\",\n  \"Circles\",\n  \"Cliff\",\n  \"Cliffs\",\n  \"Club\",\n  \"Common\",\n  \"Corner\",\n  \"Corners\",\n  \"Course\",\n  \"Court\",\n  \"Courts\",\n  \"Cove\",\n  \"Coves\",\n  \"Creek\",\n  \"Crescent\",\n  \"Crest\",\n  \"Crossing\",\n  \"Crossroad\",\n  \"Curve\",\n  \"Dale\",\n  \"Dam\",\n  \"Divide\",\n  \"Drive\",\n  \"Drive\",\n  \"Drives\",\n  \"Estate\",\n  \"Estates\",\n  \"Expressway\",\n  \"Extension\",\n  \"Extensions\",\n  \"Fall\",\n  \"Falls\",\n  \"Ferry\",\n  \"Field\",\n  \"Fields\",\n  \"Flat\",\n  \"Flats\",\n  \"Ford\",\n  \"Fords\",\n  \"Forest\",\n  \"Forge\",\n  \"Forges\",\n  \"Fork\",\n  \"Forks\",\n  \"Fort\",\n  \"Freeway\",\n  \"Garden\",\n  \"Gardens\",\n  \"Gateway\",\n  \"Glen\",\n  \"Glens\",\n  \"Green\",\n  \"Greens\",\n  \"Grove\",\n  \"Groves\",\n  \"Harbor\",\n  \"Harbors\",\n  \"Haven\",\n  \"Heights\",\n  \"Highway\",\n  \"Hill\",\n  \"Hills\",\n  \"Hollow\",\n  \"Inlet\",\n  \"Inlet\",\n  \"Island\",\n  \"Island\",\n  \"Islands\",\n  \"Islands\",\n  \"Isle\",\n  \"Isle\",\n  \"Junction\",\n  \"Junctions\",\n  \"Key\",\n  \"Keys\",\n  \"Knoll\",\n  \"Knolls\",\n  \"Lake\",\n  \"Lakes\",\n  \"Land\",\n  \"Landing\",\n  \"Lane\",\n  \"Light\",\n  \"Lights\",\n  \"Loaf\",\n  \"Lock\",\n  \"Locks\",\n  \"Locks\",\n  \"Lodge\",\n  \"Lodge\",\n  \"Loop\",\n  \"Mall\",\n  \"Manor\",\n  \"Manors\",\n  \"Meadow\",\n  \"Meadows\",\n  \"Mews\",\n  \"Mill\",\n  \"Mills\",\n  \"Mission\",\n  \"Mission\",\n  \"Motorway\",\n  \"Mount\",\n  \"Mountain\",\n  \"Mountain\",\n  \"Mountains\",\n  \"Mountains\",\n  \"Neck\",\n  \"Orchard\",\n  \"Oval\",\n  \"Overpass\",\n  \"Park\",\n  \"Parks\",\n  \"Parkway\",\n  \"Parkways\",\n  \"Pass\",\n  \"Passage\",\n  \"Path\",\n  \"Pike\",\n  \"Pine\",\n  \"Pines\",\n  \"Place\",\n  \"Plain\",\n  \"Plains\",\n  \"Plains\",\n  \"Plaza\",\n  \"Plaza\",\n  \"Point\",\n  \"Points\",\n  \"Port\",\n  \"Port\",\n  \"Ports\",\n  \"Ports\",\n  \"Prairie\",\n  \"Prairie\",\n  \"Radial\",\n  \"Ramp\",\n  \"Ranch\",\n  \"Rapid\",\n  \"Rapids\",\n  \"Rest\",\n  \"Ridge\",\n  \"Ridges\",\n  \"River\",\n  \"Road\",\n  \"Road\",\n  \"Roads\",\n  \"Roads\",\n  \"Route\",\n  \"Row\",\n  \"Rue\",\n  \"Run\",\n  \"Shoal\",\n  \"Shoals\",\n  \"Shore\",\n  \"Shores\",\n  \"Skyway\",\n  \"Spring\",\n  \"Springs\",\n  \"Springs\",\n  \"Spur\",\n  \"Spurs\",\n  \"Square\",\n  \"Square\",\n  \"Squares\",\n  \"Squares\",\n  \"Station\",\n  \"Station\",\n  \"Stravenue\",\n  \"Stravenue\",\n  \"Stream\",\n  \"Stream\",\n  \"Street\",\n  \"Street\",\n  \"Streets\",\n  \"Summit\",\n  \"Summit\",\n  \"Terrace\",\n  \"Throughway\",\n  \"Trace\",\n  \"Track\",\n  \"Trafficway\",\n  \"Trail\",\n  \"Trail\",\n  \"Tunnel\",\n  \"Tunnel\",\n  \"Turnpike\",\n  \"Turnpike\",\n  \"Underpass\",\n  \"Union\",\n  \"Unions\",\n  \"Valley\",\n  \"Valleys\",\n  \"Via\",\n  \"Viaduct\",\n  \"View\",\n  \"Views\",\n  \"Village\",\n  \"Village\",\n  \"Villages\",\n  \"Ville\",\n  \"Vista\",\n  \"Vista\",\n  \"Walk\",\n  \"Walks\",\n  \"Wall\",\n  \"Way\",\n  \"Ways\",\n  \"Well\",\n  \"Wells\"\n];\n\n},{}],196:[function(require,module,exports){\nmodule.exports=require(67)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/time_zone.js\":67}],197:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.name}\",\n  \"#{Company.name}\"\n];\n\n},{}],198:[function(require,module,exports){\nvar app = {};\nmodule['exports'] = app;\napp.name = require(\"./name\");\napp.version = require(\"./version\");\napp.author = require(\"./author\");\n\n},{\"./author\":197,\"./name\":199,\"./version\":200}],199:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Redhold\",\n  \"Treeflex\",\n  \"Trippledex\",\n  \"Kanlam\",\n  \"Bigtax\",\n  \"Daltfresh\",\n  \"Toughjoyfax\",\n  \"Mat Lam Tam\",\n  \"Otcom\",\n  \"Tres-Zap\",\n  \"Y-Solowarm\",\n  \"Tresom\",\n  \"Voltsillam\",\n  \"Biodex\",\n  \"Greenlam\",\n  \"Viva\",\n  \"Matsoft\",\n  \"Temp\",\n  \"Zoolab\",\n  \"Subin\",\n  \"Rank\",\n  \"Job\",\n  \"Stringtough\",\n  \"Tin\",\n  \"It\",\n  \"Home Ing\",\n  \"Zamit\",\n  \"Sonsing\",\n  \"Konklab\",\n  \"Alpha\",\n  \"Latlux\",\n  \"Voyatouch\",\n  \"Alphazap\",\n  \"Holdlamis\",\n  \"Zaam-Dox\",\n  \"Sub-Ex\",\n  \"Quo Lux\",\n  \"Bamity\",\n  \"Ventosanzap\",\n  \"Lotstring\",\n  \"Hatity\",\n  \"Tempsoft\",\n  \"Overhold\",\n  \"Fixflex\",\n  \"Konklux\",\n  \"Zontrax\",\n  \"Tampflex\",\n  \"Span\",\n  \"Namfix\",\n  \"Transcof\",\n  \"Stim\",\n  \"Fix San\",\n  \"Sonair\",\n  \"Stronghold\",\n  \"Fintone\",\n  \"Y-find\",\n  \"Opela\",\n  \"Lotlux\",\n  \"Ronstring\",\n  \"Zathin\",\n  \"Duobam\",\n  \"Keylex\"\n];\n\n},{}],200:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"0.#.#\",\n  \"0.##\",\n  \"#.##\",\n  \"#.#\",\n  \"#.#.#\"\n];\n\n},{}],201:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"2011-10-12\",\n  \"2012-11-12\",\n  \"2015-11-11\",\n  \"2013-9-12\"\n];\n\n},{}],202:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"1234-2121-1221-1211\",\n  \"1212-1221-1121-1234\",\n  \"1211-1221-1234-2201\",\n  \"1228-1221-1221-1431\"\n];\n\n},{}],203:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"visa\",\n  \"mastercard\",\n  \"americanexpress\",\n  \"discover\"\n];\n\n},{}],204:[function(require,module,exports){\nvar business = {};\nmodule['exports'] = business;\nbusiness.credit_card_numbers = require(\"./credit_card_numbers\");\nbusiness.credit_card_expiry_dates = require(\"./credit_card_expiry_dates\");\nbusiness.credit_card_types = require(\"./credit_card_types\");\n\n},{\"./credit_card_expiry_dates\":201,\"./credit_card_numbers\":202,\"./credit_card_types\":203}],205:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###-###-####\",\n  \"(###) ###-####\",\n  \"1-###-###-####\",\n  \"###.###.####\"\n];\n\n},{}],206:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":205,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],207:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"red\",\n  \"green\",\n  \"blue\",\n  \"yellow\",\n  \"purple\",\n  \"mint green\",\n  \"teal\",\n  \"white\",\n  \"black\",\n  \"orange\",\n  \"pink\",\n  \"grey\",\n  \"maroon\",\n  \"violet\",\n  \"turquoise\",\n  \"tan\",\n  \"sky blue\",\n  \"salmon\",\n  \"plum\",\n  \"orchid\",\n  \"olive\",\n  \"magenta\",\n  \"lime\",\n  \"ivory\",\n  \"indigo\",\n  \"gold\",\n  \"fuchsia\",\n  \"cyan\",\n  \"azure\",\n  \"lavender\",\n  \"silver\"\n];\n\n},{}],208:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Books\",\n  \"Movies\",\n  \"Music\",\n  \"Games\",\n  \"Electronics\",\n  \"Computers\",\n  \"Home\",\n  \"Garden\",\n  \"Tools\",\n  \"Grocery\",\n  \"Health\",\n  \"Beauty\",\n  \"Toys\",\n  \"Kids\",\n  \"Baby\",\n  \"Clothing\",\n  \"Shoes\",\n  \"Jewelery\",\n  \"Sports\",\n  \"Outdoors\",\n  \"Automotive\",\n  \"Industrial\"\n];\n\n},{}],209:[function(require,module,exports){\narguments[4][31][0].apply(exports,arguments)\n},{\"./color\":207,\"./department\":208,\"./product_name\":210,\"/Users/a/dev/faker.js/lib/locales/az/commerce/index.js\":31}],210:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"adjective\": [\n    \"Small\",\n    \"Ergonomic\",\n    \"Rustic\",\n    \"Intelligent\",\n    \"Gorgeous\",\n    \"Incredible\",\n    \"Fantastic\",\n    \"Practical\",\n    \"Sleek\",\n    \"Awesome\",\n    \"Generic\",\n    \"Handcrafted\",\n    \"Handmade\",\n    \"Licensed\",\n    \"Refined\",\n    \"Unbranded\",\n    \"Tasty\"\n  ],\n  \"material\": [\n    \"Steel\",\n    \"Wooden\",\n    \"Concrete\",\n    \"Plastic\",\n    \"Cotton\",\n    \"Granite\",\n    \"Rubber\",\n    \"Metal\",\n    \"Soft\",\n    \"Fresh\",\n    \"Frozen\"\n  ],\n  \"product\": [\n    \"Chair\",\n    \"Car\",\n    \"Computer\",\n    \"Keyboard\",\n    \"Mouse\",\n    \"Bike\",\n    \"Ball\",\n    \"Gloves\",\n    \"Pants\",\n    \"Shirt\",\n    \"Table\",\n    \"Shoes\",\n    \"Hat\",\n    \"Towels\",\n    \"Soap\",\n    \"Tuna\",\n    \"Chicken\",\n    \"Fish\",\n    \"Cheese\",\n    \"Bacon\",\n    \"Pizza\",\n    \"Salad\",\n    \"Sausages\",\n    \"Chips\"\n  ]\n};\n\n},{}],211:[function(require,module,exports){\nmodule.exports=require(68)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/adjective.js\":68}],212:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"clicks-and-mortar\",\n  \"value-added\",\n  \"vertical\",\n  \"proactive\",\n  \"robust\",\n  \"revolutionary\",\n  \"scalable\",\n  \"leading-edge\",\n  \"innovative\",\n  \"intuitive\",\n  \"strategic\",\n  \"e-business\",\n  \"mission-critical\",\n  \"sticky\",\n  \"one-to-one\",\n  \"24/7\",\n  \"end-to-end\",\n  \"global\",\n  \"B2B\",\n  \"B2C\",\n  \"granular\",\n  \"frictionless\",\n  \"virtual\",\n  \"viral\",\n  \"dynamic\",\n  \"24/365\",\n  \"best-of-breed\",\n  \"killer\",\n  \"magnetic\",\n  \"bleeding-edge\",\n  \"web-enabled\",\n  \"interactive\",\n  \"dot-com\",\n  \"sexy\",\n  \"back-end\",\n  \"real-time\",\n  \"efficient\",\n  \"front-end\",\n  \"distributed\",\n  \"seamless\",\n  \"extensible\",\n  \"turn-key\",\n  \"world-class\",\n  \"open-source\",\n  \"cross-platform\",\n  \"cross-media\",\n  \"synergistic\",\n  \"bricks-and-clicks\",\n  \"out-of-the-box\",\n  \"enterprise\",\n  \"integrated\",\n  \"impactful\",\n  \"wireless\",\n  \"transparent\",\n  \"next-generation\",\n  \"cutting-edge\",\n  \"user-centric\",\n  \"visionary\",\n  \"customized\",\n  \"ubiquitous\",\n  \"plug-and-play\",\n  \"collaborative\",\n  \"compelling\",\n  \"holistic\",\n  \"rich\"\n];\n\n},{}],213:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"synergies\",\n  \"web-readiness\",\n  \"paradigms\",\n  \"markets\",\n  \"partnerships\",\n  \"infrastructures\",\n  \"platforms\",\n  \"initiatives\",\n  \"channels\",\n  \"eyeballs\",\n  \"communities\",\n  \"ROI\",\n  \"solutions\",\n  \"e-tailers\",\n  \"e-services\",\n  \"action-items\",\n  \"portals\",\n  \"niches\",\n  \"technologies\",\n  \"content\",\n  \"vortals\",\n  \"supply-chains\",\n  \"convergence\",\n  \"relationships\",\n  \"architectures\",\n  \"interfaces\",\n  \"e-markets\",\n  \"e-commerce\",\n  \"systems\",\n  \"bandwidth\",\n  \"infomediaries\",\n  \"models\",\n  \"mindshare\",\n  \"deliverables\",\n  \"users\",\n  \"schemas\",\n  \"networks\",\n  \"applications\",\n  \"metrics\",\n  \"e-business\",\n  \"functionalities\",\n  \"experiences\",\n  \"web services\",\n  \"methodologies\"\n];\n\n},{}],214:[function(require,module,exports){\nmodule.exports=require(70)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/bs_verb.js\":70}],215:[function(require,module,exports){\nmodule.exports=require(71)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/descriptor.js\":71}],216:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.adjective = require(\"./adjective\");\ncompany.descriptor = require(\"./descriptor\");\ncompany.noun = require(\"./noun\");\ncompany.bs_verb = require(\"./bs_verb\");\ncompany.bs_adjective = require(\"./bs_adjective\");\ncompany.bs_noun = require(\"./bs_noun\");\ncompany.name = require(\"./name\");\n\n},{\"./adjective\":211,\"./bs_adjective\":212,\"./bs_noun\":213,\"./bs_verb\":214,\"./descriptor\":215,\"./name\":217,\"./noun\":218,\"./suffix\":219}],217:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name}-#{Name.last_name}\",\n  \"#{Name.last_name}, #{Name.last_name} and #{Name.last_name}\"\n];\n\n},{}],218:[function(require,module,exports){\nmodule.exports=require(74)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/noun.js\":74}],219:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Inc\",\n  \"and Sons\",\n  \"LLC\",\n  \"Group\"\n];\n\n},{}],220:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/34##-######-####L/\",\n  \"/37##-######-####L/\"\n];\n\n},{}],221:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/30[0-5]#-######-###L/\",\n  \"/368#-######-###L/\"\n];\n\n},{}],222:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/6011-####-####-###L/\",\n  \"/65##-####-####-###L/\",\n  \"/64[4-9]#-####-####-###L/\",\n  \"/6011-62##-####-####-###L/\",\n  \"/65##-62##-####-####-###L/\",\n  \"/64[4-9]#-62##-####-####-###L/\"\n];\n\n},{}],223:[function(require,module,exports){\nvar credit_card = {};\nmodule['exports'] = credit_card;\ncredit_card.visa = require(\"./visa\");\ncredit_card.mastercard = require(\"./mastercard\");\ncredit_card.discover = require(\"./discover\");\ncredit_card.american_express = require(\"./american_express\");\ncredit_card.diners_club = require(\"./diners_club\");\ncredit_card.jcb = require(\"./jcb\");\ncredit_card.switch = require(\"./switch\");\ncredit_card.solo = require(\"./solo\");\ncredit_card.maestro = require(\"./maestro\");\ncredit_card.laser = require(\"./laser\");\n\n},{\"./american_express\":220,\"./diners_club\":221,\"./discover\":222,\"./jcb\":224,\"./laser\":225,\"./maestro\":226,\"./mastercard\":227,\"./solo\":228,\"./switch\":229,\"./visa\":230}],224:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/3528-####-####-###L/\",\n  \"/3529-####-####-###L/\",\n  \"/35[3-8]#-####-####-###L/\"\n];\n\n},{}],225:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/6304###########L/\",\n  \"/6706###########L/\",\n  \"/6771###########L/\",\n  \"/6709###########L/\",\n  \"/6304#########{5,6}L/\",\n  \"/6706#########{5,6}L/\",\n  \"/6771#########{5,6}L/\",\n  \"/6709#########{5,6}L/\"\n];\n\n},{}],226:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/50#{9,16}L/\",\n  \"/5[6-8]#{9,16}L/\",\n  \"/56##{9,16}L/\"\n];\n\n},{}],227:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/5[1-5]##-####-####-###L/\",\n  \"/6771-89##-####-###L/\"\n];\n\n},{}],228:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/6767-####-####-###L/\",\n  \"/6767-####-####-####-#L/\",\n  \"/6767-####-####-####-##L/\"\n];\n\n},{}],229:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/6759-####-####-###L/\",\n  \"/6759-####-####-####-#L/\",\n  \"/6759-####-####-####-##L/\"\n];\n\n},{}],230:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"/4###########L/\",\n  \"/4###-####-####-###L/\"\n];\n\n},{}],231:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"utf8_unicode_ci\",\n  \"utf8_general_ci\",\n  \"utf8_bin\",\n  \"ascii_bin\",\n  \"ascii_general_ci\",\n  \"cp1250_bin\",\n  \"cp1250_general_ci\"\n];\n\n},{}],232:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"id\",\n  \"title\",\n  \"name\",\n  \"email\",\n  \"phone\",\n  \"token\",\n  \"group\",\n  \"category\",\n  \"password\",\n  \"comment\",\n  \"avatar\",\n  \"status\",\n  \"createdAt\",\n  \"updatedAt\"\n];\n\n},{}],233:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"InnoDB\",\n  \"MyISAM\",\n  \"MEMORY\",\n  \"CSV\",\n  \"BLACKHOLE\",\n  \"ARCHIVE\"\n];\n\n},{}],234:[function(require,module,exports){\nvar database = {};\nmodule['exports'] = database;\ndatabase.collation = require(\"./collation\");\ndatabase.column = require(\"./column\");\ndatabase.engine = require(\"./engine\");\ndatabase.type = require(\"./type\");\n},{\"./collation\":231,\"./column\":232,\"./engine\":233,\"./type\":235}],235:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"int\",\n  \"varchar\",\n  \"text\",\n  \"date\",\n  \"datetime\",\n  \"tinyint\",\n  \"time\",\n  \"timestamp\",\n  \"smallint\",\n  \"mediumint\",\n  \"bigint\",\n  \"decimal\",\n  \"float\",\n  \"double\",\n  \"real\",\n  \"bit\",\n  \"boolean\",\n  \"serial\",\n  \"blob\",\n  \"binary\",\n  \"enum\",\n  \"set\",\n  \"geometry\",\n  \"point\"\n];\n\n},{}],236:[function(require,module,exports){\narguments[4][37][0].apply(exports,arguments)\n},{\"./month\":237,\"./weekday\":238,\"/Users/a/dev/faker.js/lib/locales/az/date/index.js\":37}],237:[function(require,module,exports){\n// Source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/en.xml#L1799\nmodule[\"exports\"] = {\n  wide: [\n    \"January\",\n    \"February\",\n    \"March\",\n    \"April\",\n    \"May\",\n    \"June\",\n    \"July\",\n    \"August\",\n    \"September\",\n    \"October\",\n    \"November\",\n    \"December\"\n  ],\n  // Property \"wide_context\" is optional, if not set then \"wide\" will be used instead\n  // It is used to specify a word in context, which may differ from a stand-alone word\n  wide_context: [\n    \"January\",\n    \"February\",\n    \"March\",\n    \"April\",\n    \"May\",\n    \"June\",\n    \"July\",\n    \"August\",\n    \"September\",\n    \"October\",\n    \"November\",\n    \"December\"\n  ],\n  abbr: [\n    \"Jan\",\n    \"Feb\",\n    \"Mar\",\n    \"Apr\",\n    \"May\",\n    \"Jun\",\n    \"Jul\",\n    \"Aug\",\n    \"Sep\",\n    \"Oct\",\n    \"Nov\",\n    \"Dec\"\n  ],\n  // Property \"abbr_context\" is optional, if not set then \"abbr\" will be used instead\n  // It is used to specify a word in context, which may differ from a stand-alone word\n  abbr_context: [\n    \"Jan\",\n    \"Feb\",\n    \"Mar\",\n    \"Apr\",\n    \"May\",\n    \"Jun\",\n    \"Jul\",\n    \"Aug\",\n    \"Sep\",\n    \"Oct\",\n    \"Nov\",\n    \"Dec\"\n  ]\n};\n\n},{}],238:[function(require,module,exports){\n// Source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/en.xml#L1847\nmodule[\"exports\"] = {\n  wide: [\n    \"Sunday\",\n    \"Monday\",\n    \"Tuesday\",\n    \"Wednesday\",\n    \"Thursday\",\n    \"Friday\",\n    \"Saturday\"\n  ],\n  // Property \"wide_context\" is optional, if not set then \"wide\" will be used instead\n  // It is used to specify a word in context, which may differ from a stand-alone word\n  wide_context: [\n    \"Sunday\",\n    \"Monday\",\n    \"Tuesday\",\n    \"Wednesday\",\n    \"Thursday\",\n    \"Friday\",\n    \"Saturday\"\n  ],\n  abbr: [\n    \"Sun\",\n    \"Mon\",\n    \"Tue\",\n    \"Wed\",\n    \"Thu\",\n    \"Fri\",\n    \"Sat\"\n  ],\n  // Property \"abbr_context\" is optional, if not set then \"abbr\" will be used instead\n  // It is used to specify a word in context, which may differ from a stand-alone word\n  abbr_context: [\n    \"Sun\",\n    \"Mon\",\n    \"Tue\",\n    \"Wed\",\n    \"Thu\",\n    \"Fri\",\n    \"Sat\"\n  ]\n};\n\n},{}],239:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Checking\",\n  \"Savings\",\n  \"Money Market\",\n  \"Investment\",\n  \"Home Loan\",\n  \"Credit Card\",\n  \"Auto Loan\",\n  \"Personal Loan\"\n];\n\n},{}],240:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"UAE Dirham\": {\n    \"code\": \"AED\",\n    \"symbol\": \"\"\n  },\n  \"Afghani\": {\n    \"code\": \"AFN\",\n    \"symbol\": \"؋\"\n  },\n  \"Lek\": {\n    \"code\": \"ALL\",\n    \"symbol\": \"Lek\"\n  },\n  \"Armenian Dram\": {\n    \"code\": \"AMD\",\n    \"symbol\": \"\"\n  },\n  \"Netherlands Antillian Guilder\": {\n    \"code\": \"ANG\",\n    \"symbol\": \"ƒ\"\n  },\n  \"Kwanza\": {\n    \"code\": \"AOA\",\n    \"symbol\": \"\"\n  },\n  \"Argentine Peso\": {\n    \"code\": \"ARS\",\n    \"symbol\": \"$\"\n  },\n  \"Australian Dollar\": {\n    \"code\": \"AUD\",\n    \"symbol\": \"$\"\n  },\n  \"Aruban Guilder\": {\n    \"code\": \"AWG\",\n    \"symbol\": \"ƒ\"\n  },\n  \"Azerbaijanian Manat\": {\n    \"code\": \"AZN\",\n    \"symbol\": \"ман\"\n  },\n  \"Convertible Marks\": {\n    \"code\": \"BAM\",\n    \"symbol\": \"KM\"\n  },\n  \"Barbados Dollar\": {\n    \"code\": \"BBD\",\n    \"symbol\": \"$\"\n  },\n  \"Taka\": {\n    \"code\": \"BDT\",\n    \"symbol\": \"\"\n  },\n  \"Bulgarian Lev\": {\n    \"code\": \"BGN\",\n    \"symbol\": \"лв\"\n  },\n  \"Bahraini Dinar\": {\n    \"code\": \"BHD\",\n    \"symbol\": \"\"\n  },\n  \"Burundi Franc\": {\n    \"code\": \"BIF\",\n    \"symbol\": \"\"\n  },\n  \"Bermudian Dollar (customarily known as Bermuda Dollar)\": {\n    \"code\": \"BMD\",\n    \"symbol\": \"$\"\n  },\n  \"Brunei Dollar\": {\n    \"code\": \"BND\",\n    \"symbol\": \"$\"\n  },\n  \"Boliviano Mvdol\": {\n    \"code\": \"BOB BOV\",\n    \"symbol\": \"$b\"\n  },\n  \"Brazilian Real\": {\n    \"code\": \"BRL\",\n    \"symbol\": \"R$\"\n  },\n  \"Bahamian Dollar\": {\n    \"code\": \"BSD\",\n    \"symbol\": \"$\"\n  },\n  \"Pula\": {\n    \"code\": \"BWP\",\n    \"symbol\": \"P\"\n  },\n  \"Belarussian Ruble\": {\n    \"code\": \"BYR\",\n    \"symbol\": \"p.\"\n  },\n  \"Belize Dollar\": {\n    \"code\": \"BZD\",\n    \"symbol\": \"BZ$\"\n  },\n  \"Canadian Dollar\": {\n    \"code\": \"CAD\",\n    \"symbol\": \"$\"\n  },\n  \"Congolese Franc\": {\n    \"code\": \"CDF\",\n    \"symbol\": \"\"\n  },\n  \"Swiss Franc\": {\n    \"code\": \"CHF\",\n    \"symbol\": \"CHF\"\n  },\n  \"Chilean Peso Unidades de fomento\": {\n    \"code\": \"CLP CLF\",\n    \"symbol\": \"$\"\n  },\n  \"Yuan Renminbi\": {\n    \"code\": \"CNY\",\n    \"symbol\": \"¥\"\n  },\n  \"Colombian Peso Unidad de Valor Real\": {\n    \"code\": \"COP COU\",\n    \"symbol\": \"$\"\n  },\n  \"Costa Rican Colon\": {\n    \"code\": \"CRC\",\n    \"symbol\": \"₡\"\n  },\n  \"Cuban Peso Peso Convertible\": {\n    \"code\": \"CUP CUC\",\n    \"symbol\": \"₱\"\n  },\n  \"Cape Verde Escudo\": {\n    \"code\": \"CVE\",\n    \"symbol\": \"\"\n  },\n  \"Czech Koruna\": {\n    \"code\": \"CZK\",\n    \"symbol\": \"Kč\"\n  },\n  \"Djibouti Franc\": {\n    \"code\": \"DJF\",\n    \"symbol\": \"\"\n  },\n  \"Danish Krone\": {\n    \"code\": \"DKK\",\n    \"symbol\": \"kr\"\n  },\n  \"Dominican Peso\": {\n    \"code\": \"DOP\",\n    \"symbol\": \"RD$\"\n  },\n  \"Algerian Dinar\": {\n    \"code\": \"DZD\",\n    \"symbol\": \"\"\n  },\n  \"Kroon\": {\n    \"code\": \"EEK\",\n    \"symbol\": \"\"\n  },\n  \"Egyptian Pound\": {\n    \"code\": \"EGP\",\n    \"symbol\": \"£\"\n  },\n  \"Nakfa\": {\n    \"code\": \"ERN\",\n    \"symbol\": \"\"\n  },\n  \"Ethiopian Birr\": {\n    \"code\": \"ETB\",\n    \"symbol\": \"\"\n  },\n  \"Euro\": {\n    \"code\": \"EUR\",\n    \"symbol\": \"€\"\n  },\n  \"Fiji Dollar\": {\n    \"code\": \"FJD\",\n    \"symbol\": \"$\"\n  },\n  \"Falkland Islands Pound\": {\n    \"code\": \"FKP\",\n    \"symbol\": \"£\"\n  },\n  \"Pound Sterling\": {\n    \"code\": \"GBP\",\n    \"symbol\": \"£\"\n  },\n  \"Lari\": {\n    \"code\": \"GEL\",\n    \"symbol\": \"\"\n  },\n  \"Cedi\": {\n    \"code\": \"GHS\",\n    \"symbol\": \"\"\n  },\n  \"Gibraltar Pound\": {\n    \"code\": \"GIP\",\n    \"symbol\": \"£\"\n  },\n  \"Dalasi\": {\n    \"code\": \"GMD\",\n    \"symbol\": \"\"\n  },\n  \"Guinea Franc\": {\n    \"code\": \"GNF\",\n    \"symbol\": \"\"\n  },\n  \"Quetzal\": {\n    \"code\": \"GTQ\",\n    \"symbol\": \"Q\"\n  },\n  \"Guyana Dollar\": {\n    \"code\": \"GYD\",\n    \"symbol\": \"$\"\n  },\n  \"Hong Kong Dollar\": {\n    \"code\": \"HKD\",\n    \"symbol\": \"$\"\n  },\n  \"Lempira\": {\n    \"code\": \"HNL\",\n    \"symbol\": \"L\"\n  },\n  \"Croatian Kuna\": {\n    \"code\": \"HRK\",\n    \"symbol\": \"kn\"\n  },\n  \"Gourde US Dollar\": {\n    \"code\": \"HTG USD\",\n    \"symbol\": \"\"\n  },\n  \"Forint\": {\n    \"code\": \"HUF\",\n    \"symbol\": \"Ft\"\n  },\n  \"Rupiah\": {\n    \"code\": \"IDR\",\n    \"symbol\": \"Rp\"\n  },\n  \"New Israeli Sheqel\": {\n    \"code\": \"ILS\",\n    \"symbol\": \"₪\"\n  },\n  \"Indian Rupee\": {\n    \"code\": \"INR\",\n    \"symbol\": \"\"\n  },\n  \"Indian Rupee Ngultrum\": {\n    \"code\": \"INR BTN\",\n    \"symbol\": \"\"\n  },\n  \"Iraqi Dinar\": {\n    \"code\": \"IQD\",\n    \"symbol\": \"\"\n  },\n  \"Iranian Rial\": {\n    \"code\": \"IRR\",\n    \"symbol\": \"﷼\"\n  },\n  \"Iceland Krona\": {\n    \"code\": \"ISK\",\n    \"symbol\": \"kr\"\n  },\n  \"Jamaican Dollar\": {\n    \"code\": \"JMD\",\n    \"symbol\": \"J$\"\n  },\n  \"Jordanian Dinar\": {\n    \"code\": \"JOD\",\n    \"symbol\": \"\"\n  },\n  \"Yen\": {\n    \"code\": \"JPY\",\n    \"symbol\": \"¥\"\n  },\n  \"Kenyan Shilling\": {\n    \"code\": \"KES\",\n    \"symbol\": \"\"\n  },\n  \"Som\": {\n    \"code\": \"KGS\",\n    \"symbol\": \"лв\"\n  },\n  \"Riel\": {\n    \"code\": \"KHR\",\n    \"symbol\": \"៛\"\n  },\n  \"Comoro Franc\": {\n    \"code\": \"KMF\",\n    \"symbol\": \"\"\n  },\n  \"North Korean Won\": {\n    \"code\": \"KPW\",\n    \"symbol\": \"₩\"\n  },\n  \"Won\": {\n    \"code\": \"KRW\",\n    \"symbol\": \"₩\"\n  },\n  \"Kuwaiti Dinar\": {\n    \"code\": \"KWD\",\n    \"symbol\": \"\"\n  },\n  \"Cayman Islands Dollar\": {\n    \"code\": \"KYD\",\n    \"symbol\": \"$\"\n  },\n  \"Tenge\": {\n    \"code\": \"KZT\",\n    \"symbol\": \"лв\"\n  },\n  \"Kip\": {\n    \"code\": \"LAK\",\n    \"symbol\": \"₭\"\n  },\n  \"Lebanese Pound\": {\n    \"code\": \"LBP\",\n    \"symbol\": \"£\"\n  },\n  \"Sri Lanka Rupee\": {\n    \"code\": \"LKR\",\n    \"symbol\": \"₨\"\n  },\n  \"Liberian Dollar\": {\n    \"code\": \"LRD\",\n    \"symbol\": \"$\"\n  },\n  \"Lithuanian Litas\": {\n    \"code\": \"LTL\",\n    \"symbol\": \"Lt\"\n  },\n  \"Latvian Lats\": {\n    \"code\": \"LVL\",\n    \"symbol\": \"Ls\"\n  },\n  \"Libyan Dinar\": {\n    \"code\": \"LYD\",\n    \"symbol\": \"\"\n  },\n  \"Moroccan Dirham\": {\n    \"code\": \"MAD\",\n    \"symbol\": \"\"\n  },\n  \"Moldovan Leu\": {\n    \"code\": \"MDL\",\n    \"symbol\": \"\"\n  },\n  \"Malagasy Ariary\": {\n    \"code\": \"MGA\",\n    \"symbol\": \"\"\n  },\n  \"Denar\": {\n    \"code\": \"MKD\",\n    \"symbol\": \"ден\"\n  },\n  \"Kyat\": {\n    \"code\": \"MMK\",\n    \"symbol\": \"\"\n  },\n  \"Tugrik\": {\n    \"code\": \"MNT\",\n    \"symbol\": \"₮\"\n  },\n  \"Pataca\": {\n    \"code\": \"MOP\",\n    \"symbol\": \"\"\n  },\n  \"Ouguiya\": {\n    \"code\": \"MRO\",\n    \"symbol\": \"\"\n  },\n  \"Mauritius Rupee\": {\n    \"code\": \"MUR\",\n    \"symbol\": \"₨\"\n  },\n  \"Rufiyaa\": {\n    \"code\": \"MVR\",\n    \"symbol\": \"\"\n  },\n  \"Kwacha\": {\n    \"code\": \"MWK\",\n    \"symbol\": \"\"\n  },\n  \"Mexican Peso Mexican Unidad de Inversion (UDI)\": {\n    \"code\": \"MXN MXV\",\n    \"symbol\": \"$\"\n  },\n  \"Malaysian Ringgit\": {\n    \"code\": \"MYR\",\n    \"symbol\": \"RM\"\n  },\n  \"Metical\": {\n    \"code\": \"MZN\",\n    \"symbol\": \"MT\"\n  },\n  \"Naira\": {\n    \"code\": \"NGN\",\n    \"symbol\": \"₦\"\n  },\n  \"Cordoba Oro\": {\n    \"code\": \"NIO\",\n    \"symbol\": \"C$\"\n  },\n  \"Norwegian Krone\": {\n    \"code\": \"NOK\",\n    \"symbol\": \"kr\"\n  },\n  \"Nepalese Rupee\": {\n    \"code\": \"NPR\",\n    \"symbol\": \"₨\"\n  },\n  \"New Zealand Dollar\": {\n    \"code\": \"NZD\",\n    \"symbol\": \"$\"\n  },\n  \"Rial Omani\": {\n    \"code\": \"OMR\",\n    \"symbol\": \"﷼\"\n  },\n  \"Balboa US Dollar\": {\n    \"code\": \"PAB USD\",\n    \"symbol\": \"B/.\"\n  },\n  \"Nuevo Sol\": {\n    \"code\": \"PEN\",\n    \"symbol\": \"S/.\"\n  },\n  \"Kina\": {\n    \"code\": \"PGK\",\n    \"symbol\": \"\"\n  },\n  \"Philippine Peso\": {\n    \"code\": \"PHP\",\n    \"symbol\": \"Php\"\n  },\n  \"Pakistan Rupee\": {\n    \"code\": \"PKR\",\n    \"symbol\": \"₨\"\n  },\n  \"Zloty\": {\n    \"code\": \"PLN\",\n    \"symbol\": \"zł\"\n  },\n  \"Guarani\": {\n    \"code\": \"PYG\",\n    \"symbol\": \"Gs\"\n  },\n  \"Qatari Rial\": {\n    \"code\": \"QAR\",\n    \"symbol\": \"﷼\"\n  },\n  \"New Leu\": {\n    \"code\": \"RON\",\n    \"symbol\": \"lei\"\n  },\n  \"Serbian Dinar\": {\n    \"code\": \"RSD\",\n    \"symbol\": \"Дин.\"\n  },\n  \"Russian Ruble\": {\n    \"code\": \"RUB\",\n    \"symbol\": \"руб\"\n  },\n  \"Rwanda Franc\": {\n    \"code\": \"RWF\",\n    \"symbol\": \"\"\n  },\n  \"Saudi Riyal\": {\n    \"code\": \"SAR\",\n    \"symbol\": \"﷼\"\n  },\n  \"Solomon Islands Dollar\": {\n    \"code\": \"SBD\",\n    \"symbol\": \"$\"\n  },\n  \"Seychelles Rupee\": {\n    \"code\": \"SCR\",\n    \"symbol\": \"₨\"\n  },\n  \"Sudanese Pound\": {\n    \"code\": \"SDG\",\n    \"symbol\": \"\"\n  },\n  \"Swedish Krona\": {\n    \"code\": \"SEK\",\n    \"symbol\": \"kr\"\n  },\n  \"Singapore Dollar\": {\n    \"code\": \"SGD\",\n    \"symbol\": \"$\"\n  },\n  \"Saint Helena Pound\": {\n    \"code\": \"SHP\",\n    \"symbol\": \"£\"\n  },\n  \"Leone\": {\n    \"code\": \"SLL\",\n    \"symbol\": \"\"\n  },\n  \"Somali Shilling\": {\n    \"code\": \"SOS\",\n    \"symbol\": \"S\"\n  },\n  \"Surinam Dollar\": {\n    \"code\": \"SRD\",\n    \"symbol\": \"$\"\n  },\n  \"Dobra\": {\n    \"code\": \"STD\",\n    \"symbol\": \"\"\n  },\n  \"El Salvador Colon US Dollar\": {\n    \"code\": \"SVC USD\",\n    \"symbol\": \"$\"\n  },\n  \"Syrian Pound\": {\n    \"code\": \"SYP\",\n    \"symbol\": \"£\"\n  },\n  \"Lilangeni\": {\n    \"code\": \"SZL\",\n    \"symbol\": \"\"\n  },\n  \"Baht\": {\n    \"code\": \"THB\",\n    \"symbol\": \"฿\"\n  },\n  \"Somoni\": {\n    \"code\": \"TJS\",\n    \"symbol\": \"\"\n  },\n  \"Manat\": {\n    \"code\": \"TMT\",\n    \"symbol\": \"\"\n  },\n  \"Tunisian Dinar\": {\n    \"code\": \"TND\",\n    \"symbol\": \"\"\n  },\n  \"Pa'anga\": {\n    \"code\": \"TOP\",\n    \"symbol\": \"\"\n  },\n  \"Turkish Lira\": {\n    \"code\": \"TRY\",\n    \"symbol\": \"TL\"\n  },\n  \"Trinidad and Tobago Dollar\": {\n    \"code\": \"TTD\",\n    \"symbol\": \"TT$\"\n  },\n  \"New Taiwan Dollar\": {\n    \"code\": \"TWD\",\n    \"symbol\": \"NT$\"\n  },\n  \"Tanzanian Shilling\": {\n    \"code\": \"TZS\",\n    \"symbol\": \"\"\n  },\n  \"Hryvnia\": {\n    \"code\": \"UAH\",\n    \"symbol\": \"₴\"\n  },\n  \"Uganda Shilling\": {\n    \"code\": \"UGX\",\n    \"symbol\": \"\"\n  },\n  \"US Dollar\": {\n    \"code\": \"USD\",\n    \"symbol\": \"$\"\n  },\n  \"Peso Uruguayo Uruguay Peso en Unidades Indexadas\": {\n    \"code\": \"UYU UYI\",\n    \"symbol\": \"$U\"\n  },\n  \"Uzbekistan Sum\": {\n    \"code\": \"UZS\",\n    \"symbol\": \"лв\"\n  },\n  \"Bolivar Fuerte\": {\n    \"code\": \"VEF\",\n    \"symbol\": \"Bs\"\n  },\n  \"Dong\": {\n    \"code\": \"VND\",\n    \"symbol\": \"₫\"\n  },\n  \"Vatu\": {\n    \"code\": \"VUV\",\n    \"symbol\": \"\"\n  },\n  \"Tala\": {\n    \"code\": \"WST\",\n    \"symbol\": \"\"\n  },\n  \"CFA Franc BEAC\": {\n    \"code\": \"XAF\",\n    \"symbol\": \"\"\n  },\n  \"Silver\": {\n    \"code\": \"XAG\",\n    \"symbol\": \"\"\n  },\n  \"Gold\": {\n    \"code\": \"XAU\",\n    \"symbol\": \"\"\n  },\n  \"Bond Markets Units European Composite Unit (EURCO)\": {\n    \"code\": \"XBA\",\n    \"symbol\": \"\"\n  },\n  \"European Monetary Unit (E.M.U.-6)\": {\n    \"code\": \"XBB\",\n    \"symbol\": \"\"\n  },\n  \"European Unit of Account 9(E.U.A.-9)\": {\n    \"code\": \"XBC\",\n    \"symbol\": \"\"\n  },\n  \"European Unit of Account 17(E.U.A.-17)\": {\n    \"code\": \"XBD\",\n    \"symbol\": \"\"\n  },\n  \"East Caribbean Dollar\": {\n    \"code\": \"XCD\",\n    \"symbol\": \"$\"\n  },\n  \"SDR\": {\n    \"code\": \"XDR\",\n    \"symbol\": \"\"\n  },\n  \"UIC-Franc\": {\n    \"code\": \"XFU\",\n    \"symbol\": \"\"\n  },\n  \"CFA Franc BCEAO\": {\n    \"code\": \"XOF\",\n    \"symbol\": \"\"\n  },\n  \"Palladium\": {\n    \"code\": \"XPD\",\n    \"symbol\": \"\"\n  },\n  \"CFP Franc\": {\n    \"code\": \"XPF\",\n    \"symbol\": \"\"\n  },\n  \"Platinum\": {\n    \"code\": \"XPT\",\n    \"symbol\": \"\"\n  },\n  \"Codes specifically reserved for testing purposes\": {\n    \"code\": \"XTS\",\n    \"symbol\": \"\"\n  },\n  \"Yemeni Rial\": {\n    \"code\": \"YER\",\n    \"symbol\": \"﷼\"\n  },\n  \"Rand\": {\n    \"code\": \"ZAR\",\n    \"symbol\": \"R\"\n  },\n  \"Rand Loti\": {\n    \"code\": \"ZAR LSL\",\n    \"symbol\": \"\"\n  },\n  \"Rand Namibia Dollar\": {\n    \"code\": \"ZAR NAD\",\n    \"symbol\": \"\"\n  },\n  \"Zambian Kwacha\": {\n    \"code\": \"ZMK\",\n    \"symbol\": \"\"\n  },\n  \"Zimbabwe Dollar\": {\n    \"code\": \"ZWL\",\n    \"symbol\": \"\"\n  }\n};\n\n},{}],241:[function(require,module,exports){\nvar finance = {};\nmodule['exports'] = finance;\nfinance.account_type = require(\"./account_type\");\nfinance.transaction_type = require(\"./transaction_type\");\nfinance.currency = require(\"./currency\");\n\n},{\"./account_type\":239,\"./currency\":240,\"./transaction_type\":242}],242:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"deposit\",\n  \"withdrawal\",\n  \"payment\",\n  \"invoice\"\n];\n\n},{}],243:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"TCP\",\n  \"HTTP\",\n  \"SDD\",\n  \"RAM\",\n  \"GB\",\n  \"CSS\",\n  \"SSL\",\n  \"AGP\",\n  \"SQL\",\n  \"FTP\",\n  \"PCI\",\n  \"AI\",\n  \"ADP\",\n  \"RSS\",\n  \"XML\",\n  \"EXE\",\n  \"COM\",\n  \"HDD\",\n  \"THX\",\n  \"SMTP\",\n  \"SMS\",\n  \"USB\",\n  \"PNG\",\n  \"SAS\",\n  \"IB\",\n  \"SCSI\",\n  \"JSON\",\n  \"XSS\",\n  \"JBOD\"\n];\n\n},{}],244:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"auxiliary\",\n  \"primary\",\n  \"back-end\",\n  \"digital\",\n  \"open-source\",\n  \"virtual\",\n  \"cross-platform\",\n  \"redundant\",\n  \"online\",\n  \"haptic\",\n  \"multi-byte\",\n  \"bluetooth\",\n  \"wireless\",\n  \"1080p\",\n  \"neural\",\n  \"optical\",\n  \"solid state\",\n  \"mobile\"\n];\n\n},{}],245:[function(require,module,exports){\nvar hacker = {};\nmodule['exports'] = hacker;\nhacker.abbreviation = require(\"./abbreviation\");\nhacker.adjective = require(\"./adjective\");\nhacker.noun = require(\"./noun\");\nhacker.verb = require(\"./verb\");\nhacker.ingverb = require(\"./ingverb\");\n\n},{\"./abbreviation\":243,\"./adjective\":244,\"./ingverb\":246,\"./noun\":247,\"./verb\":248}],246:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"backing up\",\n  \"bypassing\",\n  \"hacking\",\n  \"overriding\",\n  \"compressing\",\n  \"copying\",\n  \"navigating\",\n  \"indexing\",\n  \"connecting\",\n  \"generating\",\n  \"quantifying\",\n  \"calculating\",\n  \"synthesizing\",\n  \"transmitting\",\n  \"programming\",\n  \"parsing\"\n];\n\n},{}],247:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"driver\",\n  \"protocol\",\n  \"bandwidth\",\n  \"panel\",\n  \"microchip\",\n  \"program\",\n  \"port\",\n  \"card\",\n  \"array\",\n  \"interface\",\n  \"system\",\n  \"sensor\",\n  \"firewall\",\n  \"hard drive\",\n  \"pixel\",\n  \"alarm\",\n  \"feed\",\n  \"monitor\",\n  \"application\",\n  \"transmitter\",\n  \"bus\",\n  \"circuit\",\n  \"capacitor\",\n  \"matrix\"\n];\n\n},{}],248:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"back up\",\n  \"bypass\",\n  \"hack\",\n  \"override\",\n  \"compress\",\n  \"copy\",\n  \"navigate\",\n  \"index\",\n  \"connect\",\n  \"generate\",\n  \"quantify\",\n  \"calculate\",\n  \"synthesize\",\n  \"input\",\n  \"transmit\",\n  \"program\",\n  \"reboot\",\n  \"parse\"\n];\n\n},{}],249:[function(require,module,exports){\nvar en = {};\nmodule['exports'] = en;\nen.title = \"English\";\nen.separator = \" & \";\nen.address = require(\"./address\");\nen.credit_card = require(\"./credit_card\");\nen.company = require(\"./company\");\nen.internet = require(\"./internet\");\nen.database = require(\"./database\");\nen.lorem = require(\"./lorem\");\nen.name = require(\"./name\");\nen.phone_number = require(\"./phone_number\");\nen.cell_phone = require(\"./cell_phone\");\nen.business = require(\"./business\");\nen.commerce = require(\"./commerce\");\nen.team = require(\"./team\");\nen.hacker = require(\"./hacker\");\nen.app = require(\"./app\");\nen.finance = require(\"./finance\");\nen.date = require(\"./date\");\nen.system = require(\"./system\");\n\n},{\"./address\":187,\"./app\":198,\"./business\":204,\"./cell_phone\":206,\"./commerce\":209,\"./company\":216,\"./credit_card\":223,\"./database\":234,\"./date\":236,\"./finance\":241,\"./hacker\":245,\"./internet\":254,\"./lorem\":255,\"./name\":259,\"./phone_number\":266,\"./system\":267,\"./team\":270}],250:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jarjan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mahdif/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sprayaga/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ruzinav/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/Skyhartman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/moscoz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kurafire/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/91bilal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/igorgarybaldi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/malykhinv/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joelhelin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kushsolitary/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/coreyweb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/snowshade/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/areus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/holdenweb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/heyimjuani/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/envex/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/unterdreht/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/collegeman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/peejfancher/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andyisonline/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ultragex/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fuck_you_two/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adellecharles/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ateneupopular/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ahmetalpbalkan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/Stievius/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kerem/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/osvaldas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/angelceballos/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thierrykoblentz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/peterlandt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/catarino/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/weglov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/brandclay/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ahmetsulek/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nicolasfolliot/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jayrobinson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/victorerixon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kolage/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michzen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/markjenkins/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nicolai_larsen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/noxdzine/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alagoon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/idiot/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mizko/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chadengle/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mutlu82/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/simobenso/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vocino/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/guiiipontes/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/soyjavi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joshaustin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tomaslau/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/VinThomas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ManikRathee/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/langate/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cemshid/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/leemunroe/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_shahedk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/enda/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/BillSKenney/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/divya/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joshhemsley/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sindresorhus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/soffes/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/9lessons/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/linux29/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/Chakintosh/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/anaami/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joreira/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shadeed9/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/scottkclark/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jedbridges/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/salleedesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marakasina/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ariil/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/BrianPurkiss/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michaelmartinho/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bublienko/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/devankoshal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ZacharyZorbas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/timmillwood/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joshuasortino/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/damenleeturks/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tomas_janousek/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/herrhaase/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/RussellBishop/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/brajeshwar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cbracco/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bermonpainter/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/abdullindenis/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/isacosta/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/suprb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/yalozhkin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chandlervdw/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iamgarth/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_victa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/commadelimited/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/roybarberuk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/axel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vladarbatov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ffbel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/syropian/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ankitind/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/traneblow/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/flashmurphy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ChrisFarina78/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/baliomega/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/saschamt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jm_denis/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/anoff/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kennyadr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chatyrko/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dingyi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mds/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/terryxlife/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aaroni/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kinday/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/prrstn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/eduardostuart/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dhilipsiva/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/GavicoInd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/baires/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rohixx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/blakesimkins/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/leeiio/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tjrus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/uberschizo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kylefoundry/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/claudioguglieri/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ripplemdk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/exentrich/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jakemoore/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joaoedumedeiros/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/poormini/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tereshenkov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/keryilmaz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/haydn_woods/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rude/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/llun/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sgaurav_baghel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jamiebrittain/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/badlittleduck/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pifagor/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/agromov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/benefritz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/erwanhesry/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/diesellaws/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jeremiaha/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/koridhandy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chaensel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andrewcohen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/smaczny/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gonzalorobaina/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nandini_m/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sydlawrence/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cdharrison/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tgerken/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lewisainslie/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/charliecwaite/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/robbschiller/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/flexrs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mattdetails/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/raquelwilson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/karsh/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mrmartineau/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/opnsrce/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hgharrygo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/maximseshuk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/uxalex/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/samihah/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chanpory/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sharvin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/josemarques/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jefffis/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/krystalfister/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lokesh_coder/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thedamianhdez/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dpmachado/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/funwatercat/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/timothycd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ivanfilipovbg/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/picard102/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marcobarbosa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/krasnoukhov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/g3d/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ademilter/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rickdt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/operatino/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bungiwan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hugomano/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/logorado/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dc_user/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/horaciobella/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/SlaapMe/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/teeragit/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iqonicd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ilya_pestov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andrewarrow/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ssiskind/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/HenryHoffman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rdsaunders/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adamsxu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/curiousoffice/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/themadray/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michigangraham/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kohette/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nickfratter/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/runningskull/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/madysondesigns/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/brenton_clarke/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jennyshen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bradenhamm/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kurtinc/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/amanruzaini/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/coreyhaggard/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/Karimmove/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aaronalfred/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wtrsld/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jitachi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/therealmarvin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pmeissner/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ooomz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chacky14/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jesseddy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shanehudson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/akmur/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/IsaryAmairani/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/arthurholcombe1/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/boxmodel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ehsandiary/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/LucasPerdidao/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shalt0ni/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/swaplord/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kaelifa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/plbabin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/guillemboti/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/arindam_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/renbyrd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thiagovernetti/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jmillspaysbills/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mikemai2awesome/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jervo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mekal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sta1ex/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/robergd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/felipecsl/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andrea211087/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/garand/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dhooyenga/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/abovefunction/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pcridesagain/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/randomlies/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/BryanHorsey/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/heykenneth/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dahparra/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/allthingssmitty/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/danvernon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/beweinreich/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/increase/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/falvarad/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alxndrustinov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/souuf/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/orkuncaylar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/AM_Kn2/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gearpixels/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bassamology/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vimarethomas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kosmar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/SULiik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mrjamesnoble/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/silvanmuhlemann/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shaneIxD/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nacho/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/yigitpinarbasi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/buzzusborne/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aaronkwhite/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rmlewisuk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/giancarlon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nbirckel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/d_nny_m_cher/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sdidonato/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/atariboy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/abotap/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/karalek/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/psdesignuk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ludwiczakpawel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nemanjaivanovic/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/baluli/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ahmadajmi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vovkasolovev/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/samgrover/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/derienzo777/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jonathansimmons/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nelsonjoyce/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/S0ufi4n3/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/xtopherpaul/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/oaktreemedia/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nateschulte/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/findingjenny/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/namankreative/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/antonyzotov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/we_social/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/leehambley/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/solid_color/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/abelcabans/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mbilderbach/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kkusaa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jordyvdboom/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/carlosgavina/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pechkinator/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vc27/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rdbannon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/croakx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/suribbles/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kerihenare/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/catadeleon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gcmorley/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/duivvv/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/saschadroste/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/victorDubugras/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wintopia/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mattbilotti/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/taylorling/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/megdraws/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/meln1ks/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mahmoudmetwally/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/Silveredge9/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/derekebradley/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/happypeter1983/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/travis_arnold/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/artem_kostenko/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adobi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/daykiine/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alek_djuric/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/scips/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/miguelmendes/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/justinrhee/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alsobrooks/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fronx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mcflydesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/santi_urso/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/allfordesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stayuber/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bertboerland/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marosholly/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adamnac/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cynthiasavard/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/muringa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/danro/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hiemil/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jackiesaik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iduuck/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/antjanus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aroon_sharma/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dshster/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thehacker/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michaelbrooksjr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ryanmclaughlin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/clubb3rry/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/taybenlor/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/xripunov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/myastro/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adityasutomo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/digitalmaverick/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hjartstrorn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/itolmach/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vaughanmoffitt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/abdots/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/isnifer/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sergeysafonov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/maz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/scrapdnb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chrismj83/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vitorleal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sokaniwaal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/zaki3d/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/illyzoren/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mocabyte/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/osmanince/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/djsherman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/davidhemphill/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/waghner/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/necodymiconer/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/praveen_vijaya/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fabbrucci/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/travishines/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kuldarkalvik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/Elt_n/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/phillapier/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/okseanjay/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/id835559/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kudretkeskin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/anjhero/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/duck4fuck/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/scott_riley/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/noufalibrahim/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/h1brd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/borges_marcos/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/devinhalladay/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ciaranr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stefooo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mikebeecham/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tonymillion/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joshuaraichur/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/irae/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/petrangr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dmitriychuta/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/charliegann/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/arashmanteghi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ainsleywagon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/svenlen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/faisalabid/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/beshur/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/carlyson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dutchnadia/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/teddyzetterlund/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/samuelkraft/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aoimedia/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/toddrew/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/codepoet_ru/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/artvavs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/benoitboucart/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jomarmen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kolmarlopez/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/creartinc/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/homka/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gaborenton/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/robinclediere/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/maximsorokin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/plasticine/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/j2deme/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/peachananr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kapaluccio/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/de_ascanio/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rikas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dawidwu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/angelcreative/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rpatey/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/popey/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rehatkathuria/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/the_purplebunny/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/1markiz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ajaxy_ru/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/brenmurrell/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dudestein/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/oskarlevinson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/victorstuber/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nehfy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vicivadeline/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/leandrovaranda/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/scottgallant/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/victor_haydin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sawrb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ryhanhassan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/amayvs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/a_brixen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/karolkrakowiak_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/herkulano/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/geran7/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cggaurav/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chris_witko/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lososina/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/polarity/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mattlat/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/brandonburke/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/constantx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/teylorfeliz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/craigelimeliah/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rachelreveley/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/reabo101/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rahmeen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ky/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rickyyean/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/j04ntoh/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/spbroma/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sebashton/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jpenico/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/francis_vega/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/oktayelipek/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kikillo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fabbianz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/larrygerard/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/BroumiYoussef/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/0therplanet/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mbilalsiddique1/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ionuss/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/grrr_nl/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/liminha/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rawdiggie/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ryandownie/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sethlouey/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pixage/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/arpitnj/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/switmer777/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/josevnclch/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kanickairaj/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/puzik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tbakdesigns/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/besbujupi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/supjoey/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lowie/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/linkibol/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/balintorosz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/imcoding/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/agustincruiz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gusoto/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thomasschrijer/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/superoutman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kalmerrautam/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gabrielizalo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gojeanyn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/davidbaldie/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_vojto/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/laurengray/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jydesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mymyboy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nellleo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marciotoledo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ninjad3m0/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/to_soham/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hasslunsford/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/muridrahhal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/levisan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/grahamkennery/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lepetitogre/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/antongenkin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nessoila/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/amandabuzard/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/safrankov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cocolero/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dss49/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/matt3224/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bluesix/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/quailandquasar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/AlbertoCococi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lepinski/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sementiy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mhudobivnik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thibaut_re/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/olgary/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shojberg/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mtolokonnikov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bereto/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/naupintos/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wegotvices/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/xadhix/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/macxim/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rodnylobos/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/madcampos/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/madebyvadim/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bartoszdawydzik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/supervova/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/markretzloff/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vonachoo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/darylws/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stevedesigner/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mylesb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/herbigt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/depaulawagner/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/geshan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gizmeedevil1991/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_scottburgess/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lisovsky/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/davidsasda/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/artd_sign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/YoungCutlass/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mgonto/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/itstotallyamy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/victorquinn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/osmond/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/oksanafrewer/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/zauerkraut/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iamkeithmason/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nitinhayaran/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lmjabreu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mandalareopens/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thinkleft/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ponchomendivil/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/juamperro/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/brunodesign1206/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/caseycavanagh/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/luxe/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dotgridline/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/spedwig/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/madewulf/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mattsapii/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/helderleal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chrisstumph/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jayphen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nsamoylov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chrisvanderkooi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/justme_timothyg/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/otozk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/prinzadi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gu5taf/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cyril_gaillard/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/d_kobelyatsky/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/daniloc/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nwdsha/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/romanbulah/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/skkirilov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dvdwinden/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dannol/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thekevinjones/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jwalter14/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/timgthomas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/buddhasource/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/uxpiper/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thatonetommy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/diansigitp/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adrienths/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/klimmka/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gkaam/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/derekcramer/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jennyyo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nerrsoft/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/xalionmalik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/edhenderson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/keyuri85/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/roxanejammet/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kimcool/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/edkf/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/matkins/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alessandroribe/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jacksonlatka/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lebronjennan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kostaspt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/karlkanall/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/moynihan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/danpliego/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/saulihirvi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wesleytrankin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fjaguero/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bowbrick/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mashaaaaal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/yassiryahya/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dparrelli/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fotomagin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aka_james/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/denisepires/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iqbalperkasa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/martinansty/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jarsen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/r_oy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/justinrob/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gabrielrosser/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/malgordon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/carlfairclough/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michaelabehsera/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pierrestoffe/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/enjoythetau/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/loganjlambert/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rpeezy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/coreyginnivan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michalhron/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/msveet/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lingeswaran/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kolsvein/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/peter576/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/reideiredale/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joeymurdah/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/raphaelnikson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mvdheuvel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/maxlinderman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jimmuirhead/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/begreative/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/frankiefreesbie/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/robturlinckx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/Talbi_ConSept/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/longlivemyword/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vanchesz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/maiklam/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hermanobrother/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rez___a/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gregsqueeb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/greenbes/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_ragzor/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/anthonysukow/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fluidbrush/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dactrtr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jehnglynn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bergmartin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hugocornejo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_kkga/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dzantievm/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sawalazar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sovesove/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jonsgotwood/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/byryan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vytautas_a/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mizhgan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cicerobr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nilshelmersson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/d33pthought/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/davecraige/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nckjrvs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alexandermayes/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jcubic/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/craigrcoles/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bagawarman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rob_thomas10/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cofla/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/maikelk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rtgibbons/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/russell_baylis/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mhesslow/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/codysanfilippo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/webtanya/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/madebybrenton/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dcalonaci/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/perfectflow/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jjsiii/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/saarabpreet/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kumarrajan12123/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iamsteffen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/themikenagle/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ceekaytweet/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/larrybolt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/conspirator/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dallasbpeters/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/n3dmax/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/terpimost/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/byrnecore/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/j_drake_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/calebjoyce/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/russoedu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hoangloi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tobysaxon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gofrasdesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dimaposnyy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tjisousa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/okandungel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/billyroshan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/oskamaya/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/motionthinks/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/knilob/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ashocka18/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marrimo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bartjo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/omnizya/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ernestsemerda/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andreas_pr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/edgarchris99/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thomasgeisen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gseguin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joannefournier/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/demersdesigns/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adammarsbar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nasirwd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/n_tassone/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/javorszky/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/themrdave/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/yecidsm/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nicollerich/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/canapud/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nicoleglynn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/judzhin_miles/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/designervzm/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kianoshp/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/evandrix/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alterchuca/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dhrubo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ma_tiax/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ssbb_me/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dorphern/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mauriolg/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bruno_mart/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mactopus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/the_winslet/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joemdesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/Shriiiiimp/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jacobbennett/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nfedoroff/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iamglimy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/allagringaus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aiiaiiaii/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/olaolusoga/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/buryaknick/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wim1k/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nicklacke/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/a1chapone/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/steynviljoen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/strikewan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ryankirkman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andrewabogado/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/doooon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jagan123/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ariffsetiawan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/elenadissi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mwarkentin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thierrymeier_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/r_garcia/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dmackerman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/borantula/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/konus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/spacewood_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ryuchi311/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/evanshajed/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tristanlegros/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shoaib253/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aislinnkelly/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/okcoker/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/timpetricola/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sunshinedgirl/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chadami/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aleclarsoniv/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nomidesigns/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/petebernardo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/scottiedude/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/millinet/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/imsoper/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/imammuht/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/benjamin_knight/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nepdud/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joki4/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lanceguyatt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bboy1895/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/amywebbb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rweve/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/haruintesettden/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ricburton/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nelshd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/batsirai/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/primozcigler/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jffgrdnr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/8d3k/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/geneseleznev/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/al_li/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/souperphly/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mslarkina/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/2fockus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cdavis565/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/xiel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/turkutuuli/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/uxward/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lebinoclard/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gauravjassal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/davidmerrique/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mdsisto/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andrewofficer/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kojourin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dnirmal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kevka/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mr_shiznit/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aluisio_azevedo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cloudstudio/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/danvierich/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alexivanichkin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fran_mchamy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/perretmagali/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/betraydan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cadikkara/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/matbeedotcom/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jeremyworboys/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bpartridge/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michaelkoper/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/silv3rgvn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alevizio/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/johnsmithagency/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lawlbwoy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vitor376/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/desastrozo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thimo_cz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jasonmarkjones/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lhausermann/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/xravil/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/guischmitt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vigobronx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/panghal0/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/miguelkooreman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/surgeonist/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/christianoliff/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/caspergrl/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iamkarna/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ipavelek/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pierre_nel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/y2graphic/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sterlingrules/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/elbuscainfo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bennyjien/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stushona/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/estebanuribe/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/embrcecreations/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/danillos/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/elliotlewis/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/charlesrpratt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vladyn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/emmeffess/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/carlosblanco_eu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/leonfedotov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rangafangs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chris_frees/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tgormtx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bryan_topham/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jpscribbles/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mighty55/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/carbontwelve/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/isaacfifth/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/iamjdeleon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/snowwrite/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/barputro/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/drewbyreese/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sachacorazzi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bistrianiosip/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/magoo04/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pehamondello/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/yayteejay/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/a_harris88/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/algunsanabria/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/zforrester/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ovall/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/carlosjgsousa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/geobikas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ah_lice/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/looneydoodle/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nerdgr8/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ddggccaa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/zackeeler/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/normanbox/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/el_fuertisimo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ismail_biltagi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/juangomezw/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jnmnrd/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/patrickcoombe/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ryanjohnson_me/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/markolschesky/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jeffgolenski/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kvasnic/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gauchomatt/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/afusinatto/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kevinoh/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/okansurreel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adamawesomeface/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/emileboudeling/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/arishi_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/juanmamartinez/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wikiziner/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/danthms/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mkginfo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/terrorpixel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/curiousonaut/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/prheemo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michaelcolenso/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/foczzi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/martip07/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thaodang17/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/johncafazza/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/robinlayfield/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/franciscoamk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/abdulhyeuk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marklamb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/edobene/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andresenfredrik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mikaeljorhult/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chrisslowik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vinciarts/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/meelford/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/elliotnolten/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/yehudab/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vijaykarthik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bfrohs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/josep_martins/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/attacks/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sur4dye/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tumski/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/instalox/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mangosango/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/paulfarino/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kazaky999/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kiwiupover/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nvkznemo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tom_even/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ratbus/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/woodsman001/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joshmedeski/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thewillbeard/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/psaikali/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joe_black/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aleinadsays/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marcusgorillius/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hota_v/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jghyllebert/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shinze/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/janpalounek/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jeremiespoken/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/her_ruu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dansowter/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/felipeapiress/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/magugzbrand2d/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/posterjob/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nathalie_fs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bobbytwoshoes/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dreizle/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jeremymouton/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/elisabethkjaer/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/notbadart/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mohanrohith/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jlsolerdeltoro/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/itskawsar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/slowspock/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/zvchkelly/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wiljanslofstra/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/craighenneberry/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/trubeatto/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/juaumlol/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/samscouto/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/BenouarradeM/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gipsy_raf/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/netonet_il/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/arkokoley/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/itsajimithing/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/smalonso/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/victordeanda/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_dwite_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/richardgarretts/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gregrwilkinson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/anatolinicolae/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lu4sh1i/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stefanotirloni/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ostirbu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/darcystonge/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/naitanamoreno/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/michaelcomiskey/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/adhiardana/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marcomano_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/davidcazalis/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/falconerie/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gregkilian/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bcrad/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bolzanmarco/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/low_res/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vlajki/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/petar_prog/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jonkspr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/akmalfikri/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mfacchinello/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/atanism/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/harry_sistalam/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/murrayswift/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bobwassermann/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gavr1l0/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/madshensel/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mr_subtle/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/deviljho_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/salimianoff/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joetruesdell/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/twittypork/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/airskylar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dnezkumar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dgajjar/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cherif_b/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/salvafc/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/louis_currie/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/deeenright/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cybind/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/eyronn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vickyshits/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sweetdelisa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/cboller1/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andresdjasso/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/melvindidit/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andysolomon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thaisselenator_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lvovenok/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/giuliusa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/belyaev_rs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/overcloacked/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kamal_chaneman/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/incubo82/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hellofeverrrr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mhaligowski/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sunlandictwin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bu7921/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/andytlaw/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jeremery/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/finchjke/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/manigm/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/umurgdk/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/scottfeltham/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ganserene/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mutu_krish/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jodytaggart/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ntfblog/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tanveerrao/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hfalucas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alxleroydeval/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kucingbelang4/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bargaorobalo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/colgruv/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stalewine/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kylefrost/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/baumannzone/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/angelcolberg/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sachingawas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jjshaw14/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ramanathan_pdy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/johndezember/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nilshoenson/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/brandonmorreale/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nutzumi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/brandonflatsoda/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sergeyalmone/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/klefue/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kirangopal/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/baumann_alex/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/matthewkay_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jay_wilburn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shesgared/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/apriendeau/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/johnriordan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wake_gs/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aleksitappura/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/emsgulam/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/xilantra/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/imomenui/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sircalebgrove/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/newbrushes/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hsinyo23/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/m4rio/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/katiemdaly/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/s4f1/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ecommerceil/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marlinjayakody/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/swooshycueb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sangdth/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/coderdiaz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bluefx_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vivekprvr/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sasha_shestakov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/eugeneeweb/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dgclegg/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/n1ght_coder/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dixchen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/blakehawksworth/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/trueblood_33/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hai_ninh_nguyen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marclgonzales/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/yesmeck/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stephcoue/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/doronmalki/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ruehldesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/anasnakawa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kijanmaharjan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/wearesavas/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stefvdham/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tweetubhai/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alecarpentier/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/fiterik/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/antonyryndya/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/d00maz/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/theonlyzeke/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/missaaamy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/carlosm/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/manekenthe/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/reetajayendra/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jeremyshimko/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/justinrgraham/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/stefanozoffoli/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/overra/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mrebay007/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/shvelo96/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/pyronite/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/thedjpetersen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/rtyukmaev/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_williamguerra/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/albertaugustin/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vikashpathak18/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kevinjohndayy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vj_demien/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/colirpixoil/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/goddardlewis/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/laasli/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jqiuss/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/heycamtaylor/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nastya_mane/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mastermindesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ccinojasso1/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/nyancecom/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sandywoodruff/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/bighanddesign/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sbtransparent/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aviddayentonbay/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/richwild/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kaysix_dizzy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/tur8le/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/seyedhossein1/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/privetwagner/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/emmandenn/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dev_essentials/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jmfsocial/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_yardenoon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mateaodviteza/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/weavermedia/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mufaddal_mw/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hafeeskhan/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ashernatali/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sulaqo/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/eddiechen/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/josecarlospsh/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vm_f/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/enricocicconi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/danmartin70/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/gmourier/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/donjain/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mrxloka/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/_pedropinho/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/eitarafa/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/oscarowusu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ralph_lam/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/panchajanyag/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/woodydotmx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/jerrybai1907/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/marshallchen_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/xamorep/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aio___/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/chaabane_wail/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/txcx/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/akashsharma39/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/falling_soul/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sainraja/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mugukamil/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/johannesneu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/markwienands/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/karthipanraj/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/balakayuriy/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/alan_zhang_/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/layerssss/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/kaspernordkvist/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/mirfanqureshi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/hanna_smi/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/VMilescu/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/aeon56/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/m_kalibry/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/sreejithexp/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dicesales/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/dhoot_amit/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/smenov/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/lonesomelemon/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vladimirdevic/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/joelcipriano/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/haligaliharun/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/buleswapnil/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/serefka/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/ifarafonow/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/vikasvinfotech/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/urrutimeoli/128.jpg\",\n  \"https://s3.amazonaws.com/uifaces/faces/twitter/areandacom/128.jpg\"\n];\n\n},{}],251:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"biz\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\"\n];\n\n},{}],252:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"example.org\",\n  \"example.com\",\n  \"example.net\"\n];\n\n},{}],253:[function(require,module,exports){\nmodule.exports=require(119)\n},{\"/Users/a/dev/faker.js/lib/locales/de/internet/free_email.js\":119}],254:[function(require,module,exports){\nvar internet = {};\nmodule['exports'] = internet;\ninternet.free_email = require(\"./free_email\");\ninternet.example_email = require(\"./example_email\");\ninternet.domain_suffix = require(\"./domain_suffix\");\ninternet.avatar_uri = require(\"./avatar_uri\");\n\n},{\"./avatar_uri\":250,\"./domain_suffix\":251,\"./example_email\":252,\"./free_email\":253}],255:[function(require,module,exports){\nmodule.exports=require(83)\n},{\"./supplemental\":256,\"./words\":257,\"/Users/a/dev/faker.js/lib/locales/cz/lorem/index.js\":83}],256:[function(require,module,exports){\nmodule.exports=require(84)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/supplemental.js\":84}],257:[function(require,module,exports){\nmodule.exports=require(85)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/words.js\":85}],258:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aaliyah\",\n  \"Aaron\",\n  \"Abagail\",\n  \"Abbey\",\n  \"Abbie\",\n  \"Abbigail\",\n  \"Abby\",\n  \"Abdiel\",\n  \"Abdul\",\n  \"Abdullah\",\n  \"Abe\",\n  \"Abel\",\n  \"Abelardo\",\n  \"Abigail\",\n  \"Abigale\",\n  \"Abigayle\",\n  \"Abner\",\n  \"Abraham\",\n  \"Ada\",\n  \"Adah\",\n  \"Adalberto\",\n  \"Adaline\",\n  \"Adam\",\n  \"Adan\",\n  \"Addie\",\n  \"Addison\",\n  \"Adela\",\n  \"Adelbert\",\n  \"Adele\",\n  \"Adelia\",\n  \"Adeline\",\n  \"Adell\",\n  \"Adella\",\n  \"Adelle\",\n  \"Aditya\",\n  \"Adolf\",\n  \"Adolfo\",\n  \"Adolph\",\n  \"Adolphus\",\n  \"Adonis\",\n  \"Adrain\",\n  \"Adrian\",\n  \"Adriana\",\n  \"Adrianna\",\n  \"Adriel\",\n  \"Adrien\",\n  \"Adrienne\",\n  \"Afton\",\n  \"Aglae\",\n  \"Agnes\",\n  \"Agustin\",\n  \"Agustina\",\n  \"Ahmad\",\n  \"Ahmed\",\n  \"Aida\",\n  \"Aidan\",\n  \"Aiden\",\n  \"Aileen\",\n  \"Aimee\",\n  \"Aisha\",\n  \"Aiyana\",\n  \"Akeem\",\n  \"Al\",\n  \"Alaina\",\n  \"Alan\",\n  \"Alana\",\n  \"Alanis\",\n  \"Alanna\",\n  \"Alayna\",\n  \"Alba\",\n  \"Albert\",\n  \"Alberta\",\n  \"Albertha\",\n  \"Alberto\",\n  \"Albin\",\n  \"Albina\",\n  \"Alda\",\n  \"Alden\",\n  \"Alec\",\n  \"Aleen\",\n  \"Alejandra\",\n  \"Alejandrin\",\n  \"Alek\",\n  \"Alena\",\n  \"Alene\",\n  \"Alessandra\",\n  \"Alessandro\",\n  \"Alessia\",\n  \"Aletha\",\n  \"Alex\",\n  \"Alexa\",\n  \"Alexander\",\n  \"Alexandra\",\n  \"Alexandre\",\n  \"Alexandrea\",\n  \"Alexandria\",\n  \"Alexandrine\",\n  \"Alexandro\",\n  \"Alexane\",\n  \"Alexanne\",\n  \"Alexie\",\n  \"Alexis\",\n  \"Alexys\",\n  \"Alexzander\",\n  \"Alf\",\n  \"Alfonso\",\n  \"Alfonzo\",\n  \"Alford\",\n  \"Alfred\",\n  \"Alfreda\",\n  \"Alfredo\",\n  \"Ali\",\n  \"Alia\",\n  \"Alice\",\n  \"Alicia\",\n  \"Alisa\",\n  \"Alisha\",\n  \"Alison\",\n  \"Alivia\",\n  \"Aliya\",\n  \"Aliyah\",\n  \"Aliza\",\n  \"Alize\",\n  \"Allan\",\n  \"Allen\",\n  \"Allene\",\n  \"Allie\",\n  \"Allison\",\n  \"Ally\",\n  \"Alphonso\",\n  \"Alta\",\n  \"Althea\",\n  \"Alva\",\n  \"Alvah\",\n  \"Alvena\",\n  \"Alvera\",\n  \"Alverta\",\n  \"Alvina\",\n  \"Alvis\",\n  \"Alyce\",\n  \"Alycia\",\n  \"Alysa\",\n  \"Alysha\",\n  \"Alyson\",\n  \"Alysson\",\n  \"Amalia\",\n  \"Amanda\",\n  \"Amani\",\n  \"Amara\",\n  \"Amari\",\n  \"Amaya\",\n  \"Amber\",\n  \"Ambrose\",\n  \"Amelia\",\n  \"Amelie\",\n  \"Amely\",\n  \"America\",\n  \"Americo\",\n  \"Amie\",\n  \"Amina\",\n  \"Amir\",\n  \"Amira\",\n  \"Amiya\",\n  \"Amos\",\n  \"Amparo\",\n  \"Amy\",\n  \"Amya\",\n  \"Ana\",\n  \"Anabel\",\n  \"Anabelle\",\n  \"Anahi\",\n  \"Anais\",\n  \"Anastacio\",\n  \"Anastasia\",\n  \"Anderson\",\n  \"Andre\",\n  \"Andreane\",\n  \"Andreanne\",\n  \"Andres\",\n  \"Andrew\",\n  \"Andy\",\n  \"Angel\",\n  \"Angela\",\n  \"Angelica\",\n  \"Angelina\",\n  \"Angeline\",\n  \"Angelita\",\n  \"Angelo\",\n  \"Angie\",\n  \"Angus\",\n  \"Anibal\",\n  \"Anika\",\n  \"Anissa\",\n  \"Anita\",\n  \"Aniya\",\n  \"Aniyah\",\n  \"Anjali\",\n  \"Anna\",\n  \"Annabel\",\n  \"Annabell\",\n  \"Annabelle\",\n  \"Annalise\",\n  \"Annamae\",\n  \"Annamarie\",\n  \"Anne\",\n  \"Annetta\",\n  \"Annette\",\n  \"Annie\",\n  \"Ansel\",\n  \"Ansley\",\n  \"Anthony\",\n  \"Antoinette\",\n  \"Antone\",\n  \"Antonetta\",\n  \"Antonette\",\n  \"Antonia\",\n  \"Antonietta\",\n  \"Antonina\",\n  \"Antonio\",\n  \"Antwan\",\n  \"Antwon\",\n  \"Anya\",\n  \"April\",\n  \"Ara\",\n  \"Araceli\",\n  \"Aracely\",\n  \"Arch\",\n  \"Archibald\",\n  \"Ardella\",\n  \"Arden\",\n  \"Ardith\",\n  \"Arely\",\n  \"Ari\",\n  \"Ariane\",\n  \"Arianna\",\n  \"Aric\",\n  \"Ariel\",\n  \"Arielle\",\n  \"Arjun\",\n  \"Arlene\",\n  \"Arlie\",\n  \"Arlo\",\n  \"Armand\",\n  \"Armando\",\n  \"Armani\",\n  \"Arnaldo\",\n  \"Arne\",\n  \"Arno\",\n  \"Arnold\",\n  \"Arnoldo\",\n  \"Arnulfo\",\n  \"Aron\",\n  \"Art\",\n  \"Arthur\",\n  \"Arturo\",\n  \"Arvel\",\n  \"Arvid\",\n  \"Arvilla\",\n  \"Aryanna\",\n  \"Asa\",\n  \"Asha\",\n  \"Ashlee\",\n  \"Ashleigh\",\n  \"Ashley\",\n  \"Ashly\",\n  \"Ashlynn\",\n  \"Ashton\",\n  \"Ashtyn\",\n  \"Asia\",\n  \"Assunta\",\n  \"Astrid\",\n  \"Athena\",\n  \"Aubree\",\n  \"Aubrey\",\n  \"Audie\",\n  \"Audra\",\n  \"Audreanne\",\n  \"Audrey\",\n  \"August\",\n  \"Augusta\",\n  \"Augustine\",\n  \"Augustus\",\n  \"Aurelia\",\n  \"Aurelie\",\n  \"Aurelio\",\n  \"Aurore\",\n  \"Austen\",\n  \"Austin\",\n  \"Austyn\",\n  \"Autumn\",\n  \"Ava\",\n  \"Avery\",\n  \"Avis\",\n  \"Axel\",\n  \"Ayana\",\n  \"Ayden\",\n  \"Ayla\",\n  \"Aylin\",\n  \"Baby\",\n  \"Bailee\",\n  \"Bailey\",\n  \"Barbara\",\n  \"Barney\",\n  \"Baron\",\n  \"Barrett\",\n  \"Barry\",\n  \"Bart\",\n  \"Bartholome\",\n  \"Barton\",\n  \"Baylee\",\n  \"Beatrice\",\n  \"Beau\",\n  \"Beaulah\",\n  \"Bell\",\n  \"Bella\",\n  \"Belle\",\n  \"Ben\",\n  \"Benedict\",\n  \"Benjamin\",\n  \"Bennett\",\n  \"Bennie\",\n  \"Benny\",\n  \"Benton\",\n  \"Berenice\",\n  \"Bernadette\",\n  \"Bernadine\",\n  \"Bernard\",\n  \"Bernardo\",\n  \"Berneice\",\n  \"Bernhard\",\n  \"Bernice\",\n  \"Bernie\",\n  \"Berniece\",\n  \"Bernita\",\n  \"Berry\",\n  \"Bert\",\n  \"Berta\",\n  \"Bertha\",\n  \"Bertram\",\n  \"Bertrand\",\n  \"Beryl\",\n  \"Bessie\",\n  \"Beth\",\n  \"Bethany\",\n  \"Bethel\",\n  \"Betsy\",\n  \"Bette\",\n  \"Bettie\",\n  \"Betty\",\n  \"Bettye\",\n  \"Beulah\",\n  \"Beverly\",\n  \"Bianka\",\n  \"Bill\",\n  \"Billie\",\n  \"Billy\",\n  \"Birdie\",\n  \"Blair\",\n  \"Blaise\",\n  \"Blake\",\n  \"Blanca\",\n  \"Blanche\",\n  \"Blaze\",\n  \"Bo\",\n  \"Bobbie\",\n  \"Bobby\",\n  \"Bonita\",\n  \"Bonnie\",\n  \"Boris\",\n  \"Boyd\",\n  \"Brad\",\n  \"Braden\",\n  \"Bradford\",\n  \"Bradley\",\n  \"Bradly\",\n  \"Brady\",\n  \"Braeden\",\n  \"Brain\",\n  \"Brandi\",\n  \"Brando\",\n  \"Brandon\",\n  \"Brandt\",\n  \"Brandy\",\n  \"Brandyn\",\n  \"Brannon\",\n  \"Branson\",\n  \"Brant\",\n  \"Braulio\",\n  \"Braxton\",\n  \"Brayan\",\n  \"Breana\",\n  \"Breanna\",\n  \"Breanne\",\n  \"Brenda\",\n  \"Brendan\",\n  \"Brenden\",\n  \"Brendon\",\n  \"Brenna\",\n  \"Brennan\",\n  \"Brennon\",\n  \"Brent\",\n  \"Bret\",\n  \"Brett\",\n  \"Bria\",\n  \"Brian\",\n  \"Briana\",\n  \"Brianne\",\n  \"Brice\",\n  \"Bridget\",\n  \"Bridgette\",\n  \"Bridie\",\n  \"Brielle\",\n  \"Brigitte\",\n  \"Brionna\",\n  \"Brisa\",\n  \"Britney\",\n  \"Brittany\",\n  \"Brock\",\n  \"Broderick\",\n  \"Brody\",\n  \"Brook\",\n  \"Brooke\",\n  \"Brooklyn\",\n  \"Brooks\",\n  \"Brown\",\n  \"Bruce\",\n  \"Bryana\",\n  \"Bryce\",\n  \"Brycen\",\n  \"Bryon\",\n  \"Buck\",\n  \"Bud\",\n  \"Buddy\",\n  \"Buford\",\n  \"Bulah\",\n  \"Burdette\",\n  \"Burley\",\n  \"Burnice\",\n  \"Buster\",\n  \"Cade\",\n  \"Caden\",\n  \"Caesar\",\n  \"Caitlyn\",\n  \"Cale\",\n  \"Caleb\",\n  \"Caleigh\",\n  \"Cali\",\n  \"Calista\",\n  \"Callie\",\n  \"Camden\",\n  \"Cameron\",\n  \"Camila\",\n  \"Camilla\",\n  \"Camille\",\n  \"Camren\",\n  \"Camron\",\n  \"Camryn\",\n  \"Camylle\",\n  \"Candace\",\n  \"Candelario\",\n  \"Candice\",\n  \"Candida\",\n  \"Candido\",\n  \"Cara\",\n  \"Carey\",\n  \"Carissa\",\n  \"Carlee\",\n  \"Carleton\",\n  \"Carley\",\n  \"Carli\",\n  \"Carlie\",\n  \"Carlo\",\n  \"Carlos\",\n  \"Carlotta\",\n  \"Carmel\",\n  \"Carmela\",\n  \"Carmella\",\n  \"Carmelo\",\n  \"Carmen\",\n  \"Carmine\",\n  \"Carol\",\n  \"Carolanne\",\n  \"Carole\",\n  \"Carolina\",\n  \"Caroline\",\n  \"Carolyn\",\n  \"Carolyne\",\n  \"Carrie\",\n  \"Carroll\",\n  \"Carson\",\n  \"Carter\",\n  \"Cary\",\n  \"Casandra\",\n  \"Casey\",\n  \"Casimer\",\n  \"Casimir\",\n  \"Casper\",\n  \"Cassandra\",\n  \"Cassandre\",\n  \"Cassidy\",\n  \"Cassie\",\n  \"Catalina\",\n  \"Caterina\",\n  \"Catharine\",\n  \"Catherine\",\n  \"Cathrine\",\n  \"Cathryn\",\n  \"Cathy\",\n  \"Cayla\",\n  \"Ceasar\",\n  \"Cecelia\",\n  \"Cecil\",\n  \"Cecile\",\n  \"Cecilia\",\n  \"Cedrick\",\n  \"Celestine\",\n  \"Celestino\",\n  \"Celia\",\n  \"Celine\",\n  \"Cesar\",\n  \"Chad\",\n  \"Chadd\",\n  \"Chadrick\",\n  \"Chaim\",\n  \"Chance\",\n  \"Chandler\",\n  \"Chanel\",\n  \"Chanelle\",\n  \"Charity\",\n  \"Charlene\",\n  \"Charles\",\n  \"Charley\",\n  \"Charlie\",\n  \"Charlotte\",\n  \"Chase\",\n  \"Chasity\",\n  \"Chauncey\",\n  \"Chaya\",\n  \"Chaz\",\n  \"Chelsea\",\n  \"Chelsey\",\n  \"Chelsie\",\n  \"Chesley\",\n  \"Chester\",\n  \"Chet\",\n  \"Cheyanne\",\n  \"Cheyenne\",\n  \"Chloe\",\n  \"Chris\",\n  \"Christ\",\n  \"Christa\",\n  \"Christelle\",\n  \"Christian\",\n  \"Christiana\",\n  \"Christina\",\n  \"Christine\",\n  \"Christop\",\n  \"Christophe\",\n  \"Christopher\",\n  \"Christy\",\n  \"Chyna\",\n  \"Ciara\",\n  \"Cicero\",\n  \"Cielo\",\n  \"Cierra\",\n  \"Cindy\",\n  \"Citlalli\",\n  \"Clair\",\n  \"Claire\",\n  \"Clara\",\n  \"Clarabelle\",\n  \"Clare\",\n  \"Clarissa\",\n  \"Clark\",\n  \"Claud\",\n  \"Claude\",\n  \"Claudia\",\n  \"Claudie\",\n  \"Claudine\",\n  \"Clay\",\n  \"Clemens\",\n  \"Clement\",\n  \"Clementina\",\n  \"Clementine\",\n  \"Clemmie\",\n  \"Cleo\",\n  \"Cleora\",\n  \"Cleta\",\n  \"Cletus\",\n  \"Cleve\",\n  \"Cleveland\",\n  \"Clifford\",\n  \"Clifton\",\n  \"Clint\",\n  \"Clinton\",\n  \"Clotilde\",\n  \"Clovis\",\n  \"Cloyd\",\n  \"Clyde\",\n  \"Coby\",\n  \"Cody\",\n  \"Colby\",\n  \"Cole\",\n  \"Coleman\",\n  \"Colin\",\n  \"Colleen\",\n  \"Collin\",\n  \"Colt\",\n  \"Colten\",\n  \"Colton\",\n  \"Columbus\",\n  \"Concepcion\",\n  \"Conner\",\n  \"Connie\",\n  \"Connor\",\n  \"Conor\",\n  \"Conrad\",\n  \"Constance\",\n  \"Constantin\",\n  \"Consuelo\",\n  \"Cooper\",\n  \"Cora\",\n  \"Coralie\",\n  \"Corbin\",\n  \"Cordelia\",\n  \"Cordell\",\n  \"Cordia\",\n  \"Cordie\",\n  \"Corene\",\n  \"Corine\",\n  \"Cornelius\",\n  \"Cornell\",\n  \"Corrine\",\n  \"Cortez\",\n  \"Cortney\",\n  \"Cory\",\n  \"Coty\",\n  \"Courtney\",\n  \"Coy\",\n  \"Craig\",\n  \"Crawford\",\n  \"Creola\",\n  \"Cristal\",\n  \"Cristian\",\n  \"Cristina\",\n  \"Cristobal\",\n  \"Cristopher\",\n  \"Cruz\",\n  \"Crystal\",\n  \"Crystel\",\n  \"Cullen\",\n  \"Curt\",\n  \"Curtis\",\n  \"Cydney\",\n  \"Cynthia\",\n  \"Cyril\",\n  \"Cyrus\",\n  \"Dagmar\",\n  \"Dahlia\",\n  \"Daija\",\n  \"Daisha\",\n  \"Daisy\",\n  \"Dakota\",\n  \"Dale\",\n  \"Dallas\",\n  \"Dallin\",\n  \"Dalton\",\n  \"Damaris\",\n  \"Dameon\",\n  \"Damian\",\n  \"Damien\",\n  \"Damion\",\n  \"Damon\",\n  \"Dan\",\n  \"Dana\",\n  \"Dandre\",\n  \"Dane\",\n  \"D'angelo\",\n  \"Dangelo\",\n  \"Danial\",\n  \"Daniela\",\n  \"Daniella\",\n  \"Danielle\",\n  \"Danika\",\n  \"Dannie\",\n  \"Danny\",\n  \"Dante\",\n  \"Danyka\",\n  \"Daphne\",\n  \"Daphnee\",\n  \"Daphney\",\n  \"Darby\",\n  \"Daren\",\n  \"Darian\",\n  \"Dariana\",\n  \"Darien\",\n  \"Dario\",\n  \"Darion\",\n  \"Darius\",\n  \"Darlene\",\n  \"Daron\",\n  \"Darrel\",\n  \"Darrell\",\n  \"Darren\",\n  \"Darrick\",\n  \"Darrin\",\n  \"Darrion\",\n  \"Darron\",\n  \"Darryl\",\n  \"Darwin\",\n  \"Daryl\",\n  \"Dashawn\",\n  \"Dasia\",\n  \"Dave\",\n  \"David\",\n  \"Davin\",\n  \"Davion\",\n  \"Davon\",\n  \"Davonte\",\n  \"Dawn\",\n  \"Dawson\",\n  \"Dax\",\n  \"Dayana\",\n  \"Dayna\",\n  \"Dayne\",\n  \"Dayton\",\n  \"Dean\",\n  \"Deangelo\",\n  \"Deanna\",\n  \"Deborah\",\n  \"Declan\",\n  \"Dedric\",\n  \"Dedrick\",\n  \"Dee\",\n  \"Deion\",\n  \"Deja\",\n  \"Dejah\",\n  \"Dejon\",\n  \"Dejuan\",\n  \"Delaney\",\n  \"Delbert\",\n  \"Delfina\",\n  \"Delia\",\n  \"Delilah\",\n  \"Dell\",\n  \"Della\",\n  \"Delmer\",\n  \"Delores\",\n  \"Delpha\",\n  \"Delphia\",\n  \"Delphine\",\n  \"Delta\",\n  \"Demarco\",\n  \"Demarcus\",\n  \"Demario\",\n  \"Demetris\",\n  \"Demetrius\",\n  \"Demond\",\n  \"Dena\",\n  \"Denis\",\n  \"Dennis\",\n  \"Deon\",\n  \"Deondre\",\n  \"Deontae\",\n  \"Deonte\",\n  \"Dereck\",\n  \"Derek\",\n  \"Derick\",\n  \"Deron\",\n  \"Derrick\",\n  \"Deshaun\",\n  \"Deshawn\",\n  \"Desiree\",\n  \"Desmond\",\n  \"Dessie\",\n  \"Destany\",\n  \"Destin\",\n  \"Destinee\",\n  \"Destiney\",\n  \"Destini\",\n  \"Destiny\",\n  \"Devan\",\n  \"Devante\",\n  \"Deven\",\n  \"Devin\",\n  \"Devon\",\n  \"Devonte\",\n  \"Devyn\",\n  \"Dewayne\",\n  \"Dewitt\",\n  \"Dexter\",\n  \"Diamond\",\n  \"Diana\",\n  \"Dianna\",\n  \"Diego\",\n  \"Dillan\",\n  \"Dillon\",\n  \"Dimitri\",\n  \"Dina\",\n  \"Dino\",\n  \"Dion\",\n  \"Dixie\",\n  \"Dock\",\n  \"Dolly\",\n  \"Dolores\",\n  \"Domenic\",\n  \"Domenica\",\n  \"Domenick\",\n  \"Domenico\",\n  \"Domingo\",\n  \"Dominic\",\n  \"Dominique\",\n  \"Don\",\n  \"Donald\",\n  \"Donato\",\n  \"Donavon\",\n  \"Donna\",\n  \"Donnell\",\n  \"Donnie\",\n  \"Donny\",\n  \"Dora\",\n  \"Dorcas\",\n  \"Dorian\",\n  \"Doris\",\n  \"Dorothea\",\n  \"Dorothy\",\n  \"Dorris\",\n  \"Dortha\",\n  \"Dorthy\",\n  \"Doug\",\n  \"Douglas\",\n  \"Dovie\",\n  \"Doyle\",\n  \"Drake\",\n  \"Drew\",\n  \"Duane\",\n  \"Dudley\",\n  \"Dulce\",\n  \"Duncan\",\n  \"Durward\",\n  \"Dustin\",\n  \"Dusty\",\n  \"Dwight\",\n  \"Dylan\",\n  \"Earl\",\n  \"Earlene\",\n  \"Earline\",\n  \"Earnest\",\n  \"Earnestine\",\n  \"Easter\",\n  \"Easton\",\n  \"Ebba\",\n  \"Ebony\",\n  \"Ed\",\n  \"Eda\",\n  \"Edd\",\n  \"Eddie\",\n  \"Eden\",\n  \"Edgar\",\n  \"Edgardo\",\n  \"Edison\",\n  \"Edmond\",\n  \"Edmund\",\n  \"Edna\",\n  \"Eduardo\",\n  \"Edward\",\n  \"Edwardo\",\n  \"Edwin\",\n  \"Edwina\",\n  \"Edyth\",\n  \"Edythe\",\n  \"Effie\",\n  \"Efrain\",\n  \"Efren\",\n  \"Eileen\",\n  \"Einar\",\n  \"Eino\",\n  \"Eladio\",\n  \"Elaina\",\n  \"Elbert\",\n  \"Elda\",\n  \"Eldon\",\n  \"Eldora\",\n  \"Eldred\",\n  \"Eldridge\",\n  \"Eleanora\",\n  \"Eleanore\",\n  \"Eleazar\",\n  \"Electa\",\n  \"Elena\",\n  \"Elenor\",\n  \"Elenora\",\n  \"Eleonore\",\n  \"Elfrieda\",\n  \"Eli\",\n  \"Elian\",\n  \"Eliane\",\n  \"Elias\",\n  \"Eliezer\",\n  \"Elijah\",\n  \"Elinor\",\n  \"Elinore\",\n  \"Elisa\",\n  \"Elisabeth\",\n  \"Elise\",\n  \"Eliseo\",\n  \"Elisha\",\n  \"Elissa\",\n  \"Eliza\",\n  \"Elizabeth\",\n  \"Ella\",\n  \"Ellen\",\n  \"Ellie\",\n  \"Elliot\",\n  \"Elliott\",\n  \"Ellis\",\n  \"Ellsworth\",\n  \"Elmer\",\n  \"Elmira\",\n  \"Elmo\",\n  \"Elmore\",\n  \"Elna\",\n  \"Elnora\",\n  \"Elody\",\n  \"Eloisa\",\n  \"Eloise\",\n  \"Elouise\",\n  \"Eloy\",\n  \"Elroy\",\n  \"Elsa\",\n  \"Else\",\n  \"Elsie\",\n  \"Elta\",\n  \"Elton\",\n  \"Elva\",\n  \"Elvera\",\n  \"Elvie\",\n  \"Elvis\",\n  \"Elwin\",\n  \"Elwyn\",\n  \"Elyse\",\n  \"Elyssa\",\n  \"Elza\",\n  \"Emanuel\",\n  \"Emelia\",\n  \"Emelie\",\n  \"Emely\",\n  \"Emerald\",\n  \"Emerson\",\n  \"Emery\",\n  \"Emie\",\n  \"Emil\",\n  \"Emile\",\n  \"Emilia\",\n  \"Emiliano\",\n  \"Emilie\",\n  \"Emilio\",\n  \"Emily\",\n  \"Emma\",\n  \"Emmalee\",\n  \"Emmanuel\",\n  \"Emmanuelle\",\n  \"Emmet\",\n  \"Emmett\",\n  \"Emmie\",\n  \"Emmitt\",\n  \"Emmy\",\n  \"Emory\",\n  \"Ena\",\n  \"Enid\",\n  \"Enoch\",\n  \"Enola\",\n  \"Enos\",\n  \"Enrico\",\n  \"Enrique\",\n  \"Ephraim\",\n  \"Era\",\n  \"Eriberto\",\n  \"Eric\",\n  \"Erica\",\n  \"Erich\",\n  \"Erick\",\n  \"Ericka\",\n  \"Erik\",\n  \"Erika\",\n  \"Erin\",\n  \"Erling\",\n  \"Erna\",\n  \"Ernest\",\n  \"Ernestina\",\n  \"Ernestine\",\n  \"Ernesto\",\n  \"Ernie\",\n  \"Ervin\",\n  \"Erwin\",\n  \"Eryn\",\n  \"Esmeralda\",\n  \"Esperanza\",\n  \"Esta\",\n  \"Esteban\",\n  \"Estefania\",\n  \"Estel\",\n  \"Estell\",\n  \"Estella\",\n  \"Estelle\",\n  \"Estevan\",\n  \"Esther\",\n  \"Estrella\",\n  \"Etha\",\n  \"Ethan\",\n  \"Ethel\",\n  \"Ethelyn\",\n  \"Ethyl\",\n  \"Ettie\",\n  \"Eudora\",\n  \"Eugene\",\n  \"Eugenia\",\n  \"Eula\",\n  \"Eulah\",\n  \"Eulalia\",\n  \"Euna\",\n  \"Eunice\",\n  \"Eusebio\",\n  \"Eva\",\n  \"Evalyn\",\n  \"Evan\",\n  \"Evangeline\",\n  \"Evans\",\n  \"Eve\",\n  \"Eveline\",\n  \"Evelyn\",\n  \"Everardo\",\n  \"Everett\",\n  \"Everette\",\n  \"Evert\",\n  \"Evie\",\n  \"Ewald\",\n  \"Ewell\",\n  \"Ezekiel\",\n  \"Ezequiel\",\n  \"Ezra\",\n  \"Fabian\",\n  \"Fabiola\",\n  \"Fae\",\n  \"Fannie\",\n  \"Fanny\",\n  \"Fatima\",\n  \"Faustino\",\n  \"Fausto\",\n  \"Favian\",\n  \"Fay\",\n  \"Faye\",\n  \"Federico\",\n  \"Felicia\",\n  \"Felicita\",\n  \"Felicity\",\n  \"Felipa\",\n  \"Felipe\",\n  \"Felix\",\n  \"Felton\",\n  \"Fermin\",\n  \"Fern\",\n  \"Fernando\",\n  \"Ferne\",\n  \"Fidel\",\n  \"Filiberto\",\n  \"Filomena\",\n  \"Finn\",\n  \"Fiona\",\n  \"Flavie\",\n  \"Flavio\",\n  \"Fleta\",\n  \"Fletcher\",\n  \"Flo\",\n  \"Florence\",\n  \"Florencio\",\n  \"Florian\",\n  \"Florida\",\n  \"Florine\",\n  \"Flossie\",\n  \"Floy\",\n  \"Floyd\",\n  \"Ford\",\n  \"Forest\",\n  \"Forrest\",\n  \"Foster\",\n  \"Frances\",\n  \"Francesca\",\n  \"Francesco\",\n  \"Francis\",\n  \"Francisca\",\n  \"Francisco\",\n  \"Franco\",\n  \"Frank\",\n  \"Frankie\",\n  \"Franz\",\n  \"Fred\",\n  \"Freda\",\n  \"Freddie\",\n  \"Freddy\",\n  \"Frederic\",\n  \"Frederick\",\n  \"Frederik\",\n  \"Frederique\",\n  \"Fredrick\",\n  \"Fredy\",\n  \"Freeda\",\n  \"Freeman\",\n  \"Freida\",\n  \"Frida\",\n  \"Frieda\",\n  \"Friedrich\",\n  \"Fritz\",\n  \"Furman\",\n  \"Gabe\",\n  \"Gabriel\",\n  \"Gabriella\",\n  \"Gabrielle\",\n  \"Gaetano\",\n  \"Gage\",\n  \"Gail\",\n  \"Gardner\",\n  \"Garett\",\n  \"Garfield\",\n  \"Garland\",\n  \"Garnet\",\n  \"Garnett\",\n  \"Garret\",\n  \"Garrett\",\n  \"Garrick\",\n  \"Garrison\",\n  \"Garry\",\n  \"Garth\",\n  \"Gaston\",\n  \"Gavin\",\n  \"Gay\",\n  \"Gayle\",\n  \"Gaylord\",\n  \"Gene\",\n  \"General\",\n  \"Genesis\",\n  \"Genevieve\",\n  \"Gennaro\",\n  \"Genoveva\",\n  \"Geo\",\n  \"Geoffrey\",\n  \"George\",\n  \"Georgette\",\n  \"Georgiana\",\n  \"Georgianna\",\n  \"Geovanni\",\n  \"Geovanny\",\n  \"Geovany\",\n  \"Gerald\",\n  \"Geraldine\",\n  \"Gerard\",\n  \"Gerardo\",\n  \"Gerda\",\n  \"Gerhard\",\n  \"Germaine\",\n  \"German\",\n  \"Gerry\",\n  \"Gerson\",\n  \"Gertrude\",\n  \"Gia\",\n  \"Gianni\",\n  \"Gideon\",\n  \"Gilbert\",\n  \"Gilberto\",\n  \"Gilda\",\n  \"Giles\",\n  \"Gillian\",\n  \"Gina\",\n  \"Gino\",\n  \"Giovani\",\n  \"Giovanna\",\n  \"Giovanni\",\n  \"Giovanny\",\n  \"Gisselle\",\n  \"Giuseppe\",\n  \"Gladyce\",\n  \"Gladys\",\n  \"Glen\",\n  \"Glenda\",\n  \"Glenna\",\n  \"Glennie\",\n  \"Gloria\",\n  \"Godfrey\",\n  \"Golda\",\n  \"Golden\",\n  \"Gonzalo\",\n  \"Gordon\",\n  \"Grace\",\n  \"Gracie\",\n  \"Graciela\",\n  \"Grady\",\n  \"Graham\",\n  \"Grant\",\n  \"Granville\",\n  \"Grayce\",\n  \"Grayson\",\n  \"Green\",\n  \"Greg\",\n  \"Gregg\",\n  \"Gregoria\",\n  \"Gregorio\",\n  \"Gregory\",\n  \"Greta\",\n  \"Gretchen\",\n  \"Greyson\",\n  \"Griffin\",\n  \"Grover\",\n  \"Guadalupe\",\n  \"Gudrun\",\n  \"Guido\",\n  \"Guillermo\",\n  \"Guiseppe\",\n  \"Gunnar\",\n  \"Gunner\",\n  \"Gus\",\n  \"Gussie\",\n  \"Gust\",\n  \"Gustave\",\n  \"Guy\",\n  \"Gwen\",\n  \"Gwendolyn\",\n  \"Hadley\",\n  \"Hailee\",\n  \"Hailey\",\n  \"Hailie\",\n  \"Hal\",\n  \"Haleigh\",\n  \"Haley\",\n  \"Halie\",\n  \"Halle\",\n  \"Hallie\",\n  \"Hank\",\n  \"Hanna\",\n  \"Hannah\",\n  \"Hans\",\n  \"Hardy\",\n  \"Harley\",\n  \"Harmon\",\n  \"Harmony\",\n  \"Harold\",\n  \"Harrison\",\n  \"Harry\",\n  \"Harvey\",\n  \"Haskell\",\n  \"Hassan\",\n  \"Hassie\",\n  \"Hattie\",\n  \"Haven\",\n  \"Hayden\",\n  \"Haylee\",\n  \"Hayley\",\n  \"Haylie\",\n  \"Hazel\",\n  \"Hazle\",\n  \"Heath\",\n  \"Heather\",\n  \"Heaven\",\n  \"Heber\",\n  \"Hector\",\n  \"Heidi\",\n  \"Helen\",\n  \"Helena\",\n  \"Helene\",\n  \"Helga\",\n  \"Hellen\",\n  \"Helmer\",\n  \"Heloise\",\n  \"Henderson\",\n  \"Henri\",\n  \"Henriette\",\n  \"Henry\",\n  \"Herbert\",\n  \"Herman\",\n  \"Hermann\",\n  \"Hermina\",\n  \"Herminia\",\n  \"Herminio\",\n  \"Hershel\",\n  \"Herta\",\n  \"Hertha\",\n  \"Hester\",\n  \"Hettie\",\n  \"Hilario\",\n  \"Hilbert\",\n  \"Hilda\",\n  \"Hildegard\",\n  \"Hillard\",\n  \"Hillary\",\n  \"Hilma\",\n  \"Hilton\",\n  \"Hipolito\",\n  \"Hiram\",\n  \"Hobart\",\n  \"Holden\",\n  \"Hollie\",\n  \"Hollis\",\n  \"Holly\",\n  \"Hope\",\n  \"Horace\",\n  \"Horacio\",\n  \"Hortense\",\n  \"Hosea\",\n  \"Houston\",\n  \"Howard\",\n  \"Howell\",\n  \"Hoyt\",\n  \"Hubert\",\n  \"Hudson\",\n  \"Hugh\",\n  \"Hulda\",\n  \"Humberto\",\n  \"Hunter\",\n  \"Hyman\",\n  \"Ian\",\n  \"Ibrahim\",\n  \"Icie\",\n  \"Ida\",\n  \"Idell\",\n  \"Idella\",\n  \"Ignacio\",\n  \"Ignatius\",\n  \"Ike\",\n  \"Ila\",\n  \"Ilene\",\n  \"Iliana\",\n  \"Ima\",\n  \"Imani\",\n  \"Imelda\",\n  \"Immanuel\",\n  \"Imogene\",\n  \"Ines\",\n  \"Irma\",\n  \"Irving\",\n  \"Irwin\",\n  \"Isaac\",\n  \"Isabel\",\n  \"Isabell\",\n  \"Isabella\",\n  \"Isabelle\",\n  \"Isac\",\n  \"Isadore\",\n  \"Isai\",\n  \"Isaiah\",\n  \"Isaias\",\n  \"Isidro\",\n  \"Ismael\",\n  \"Isobel\",\n  \"Isom\",\n  \"Israel\",\n  \"Issac\",\n  \"Itzel\",\n  \"Iva\",\n  \"Ivah\",\n  \"Ivory\",\n  \"Ivy\",\n  \"Izabella\",\n  \"Izaiah\",\n  \"Jabari\",\n  \"Jace\",\n  \"Jacey\",\n  \"Jacinthe\",\n  \"Jacinto\",\n  \"Jack\",\n  \"Jackeline\",\n  \"Jackie\",\n  \"Jacklyn\",\n  \"Jackson\",\n  \"Jacky\",\n  \"Jaclyn\",\n  \"Jacquelyn\",\n  \"Jacques\",\n  \"Jacynthe\",\n  \"Jada\",\n  \"Jade\",\n  \"Jaden\",\n  \"Jadon\",\n  \"Jadyn\",\n  \"Jaeden\",\n  \"Jaida\",\n  \"Jaiden\",\n  \"Jailyn\",\n  \"Jaime\",\n  \"Jairo\",\n  \"Jakayla\",\n  \"Jake\",\n  \"Jakob\",\n  \"Jaleel\",\n  \"Jalen\",\n  \"Jalon\",\n  \"Jalyn\",\n  \"Jamaal\",\n  \"Jamal\",\n  \"Jamar\",\n  \"Jamarcus\",\n  \"Jamel\",\n  \"Jameson\",\n  \"Jamey\",\n  \"Jamie\",\n  \"Jamil\",\n  \"Jamir\",\n  \"Jamison\",\n  \"Jammie\",\n  \"Jan\",\n  \"Jana\",\n  \"Janae\",\n  \"Jane\",\n  \"Janelle\",\n  \"Janessa\",\n  \"Janet\",\n  \"Janice\",\n  \"Janick\",\n  \"Janie\",\n  \"Janis\",\n  \"Janiya\",\n  \"Jannie\",\n  \"Jany\",\n  \"Jaquan\",\n  \"Jaquelin\",\n  \"Jaqueline\",\n  \"Jared\",\n  \"Jaren\",\n  \"Jarod\",\n  \"Jaron\",\n  \"Jarred\",\n  \"Jarrell\",\n  \"Jarret\",\n  \"Jarrett\",\n  \"Jarrod\",\n  \"Jarvis\",\n  \"Jasen\",\n  \"Jasmin\",\n  \"Jason\",\n  \"Jasper\",\n  \"Jaunita\",\n  \"Javier\",\n  \"Javon\",\n  \"Javonte\",\n  \"Jay\",\n  \"Jayce\",\n  \"Jaycee\",\n  \"Jayda\",\n  \"Jayde\",\n  \"Jayden\",\n  \"Jaydon\",\n  \"Jaylan\",\n  \"Jaylen\",\n  \"Jaylin\",\n  \"Jaylon\",\n  \"Jayme\",\n  \"Jayne\",\n  \"Jayson\",\n  \"Jazlyn\",\n  \"Jazmin\",\n  \"Jazmyn\",\n  \"Jazmyne\",\n  \"Jean\",\n  \"Jeanette\",\n  \"Jeanie\",\n  \"Jeanne\",\n  \"Jed\",\n  \"Jedediah\",\n  \"Jedidiah\",\n  \"Jeff\",\n  \"Jefferey\",\n  \"Jeffery\",\n  \"Jeffrey\",\n  \"Jeffry\",\n  \"Jena\",\n  \"Jenifer\",\n  \"Jennie\",\n  \"Jennifer\",\n  \"Jennings\",\n  \"Jennyfer\",\n  \"Jensen\",\n  \"Jerad\",\n  \"Jerald\",\n  \"Jeramie\",\n  \"Jeramy\",\n  \"Jerel\",\n  \"Jeremie\",\n  \"Jeremy\",\n  \"Jermain\",\n  \"Jermaine\",\n  \"Jermey\",\n  \"Jerod\",\n  \"Jerome\",\n  \"Jeromy\",\n  \"Jerrell\",\n  \"Jerrod\",\n  \"Jerrold\",\n  \"Jerry\",\n  \"Jess\",\n  \"Jesse\",\n  \"Jessica\",\n  \"Jessie\",\n  \"Jessika\",\n  \"Jessy\",\n  \"Jessyca\",\n  \"Jesus\",\n  \"Jett\",\n  \"Jettie\",\n  \"Jevon\",\n  \"Jewel\",\n  \"Jewell\",\n  \"Jillian\",\n  \"Jimmie\",\n  \"Jimmy\",\n  \"Jo\",\n  \"Joan\",\n  \"Joana\",\n  \"Joanie\",\n  \"Joanne\",\n  \"Joannie\",\n  \"Joanny\",\n  \"Joany\",\n  \"Joaquin\",\n  \"Jocelyn\",\n  \"Jodie\",\n  \"Jody\",\n  \"Joe\",\n  \"Joel\",\n  \"Joelle\",\n  \"Joesph\",\n  \"Joey\",\n  \"Johan\",\n  \"Johann\",\n  \"Johanna\",\n  \"Johathan\",\n  \"John\",\n  \"Johnathan\",\n  \"Johnathon\",\n  \"Johnnie\",\n  \"Johnny\",\n  \"Johnpaul\",\n  \"Johnson\",\n  \"Jolie\",\n  \"Jon\",\n  \"Jonas\",\n  \"Jonatan\",\n  \"Jonathan\",\n  \"Jonathon\",\n  \"Jordan\",\n  \"Jordane\",\n  \"Jordi\",\n  \"Jordon\",\n  \"Jordy\",\n  \"Jordyn\",\n  \"Jorge\",\n  \"Jose\",\n  \"Josefa\",\n  \"Josefina\",\n  \"Joseph\",\n  \"Josephine\",\n  \"Josh\",\n  \"Joshua\",\n  \"Joshuah\",\n  \"Josiah\",\n  \"Josiane\",\n  \"Josianne\",\n  \"Josie\",\n  \"Josue\",\n  \"Jovan\",\n  \"Jovani\",\n  \"Jovanny\",\n  \"Jovany\",\n  \"Joy\",\n  \"Joyce\",\n  \"Juana\",\n  \"Juanita\",\n  \"Judah\",\n  \"Judd\",\n  \"Jude\",\n  \"Judge\",\n  \"Judson\",\n  \"Judy\",\n  \"Jules\",\n  \"Julia\",\n  \"Julian\",\n  \"Juliana\",\n  \"Julianne\",\n  \"Julie\",\n  \"Julien\",\n  \"Juliet\",\n  \"Julio\",\n  \"Julius\",\n  \"June\",\n  \"Junior\",\n  \"Junius\",\n  \"Justen\",\n  \"Justice\",\n  \"Justina\",\n  \"Justine\",\n  \"Juston\",\n  \"Justus\",\n  \"Justyn\",\n  \"Juvenal\",\n  \"Juwan\",\n  \"Kacey\",\n  \"Kaci\",\n  \"Kacie\",\n  \"Kade\",\n  \"Kaden\",\n  \"Kadin\",\n  \"Kaela\",\n  \"Kaelyn\",\n  \"Kaia\",\n  \"Kailee\",\n  \"Kailey\",\n  \"Kailyn\",\n  \"Kaitlin\",\n  \"Kaitlyn\",\n  \"Kale\",\n  \"Kaleb\",\n  \"Kaleigh\",\n  \"Kaley\",\n  \"Kali\",\n  \"Kallie\",\n  \"Kameron\",\n  \"Kamille\",\n  \"Kamren\",\n  \"Kamron\",\n  \"Kamryn\",\n  \"Kane\",\n  \"Kara\",\n  \"Kareem\",\n  \"Karelle\",\n  \"Karen\",\n  \"Kari\",\n  \"Kariane\",\n  \"Karianne\",\n  \"Karina\",\n  \"Karine\",\n  \"Karl\",\n  \"Karlee\",\n  \"Karley\",\n  \"Karli\",\n  \"Karlie\",\n  \"Karolann\",\n  \"Karson\",\n  \"Kasandra\",\n  \"Kasey\",\n  \"Kassandra\",\n  \"Katarina\",\n  \"Katelin\",\n  \"Katelyn\",\n  \"Katelynn\",\n  \"Katharina\",\n  \"Katherine\",\n  \"Katheryn\",\n  \"Kathleen\",\n  \"Kathlyn\",\n  \"Kathryn\",\n  \"Kathryne\",\n  \"Katlyn\",\n  \"Katlynn\",\n  \"Katrina\",\n  \"Katrine\",\n  \"Kattie\",\n  \"Kavon\",\n  \"Kay\",\n  \"Kaya\",\n  \"Kaycee\",\n  \"Kayden\",\n  \"Kayla\",\n  \"Kaylah\",\n  \"Kaylee\",\n  \"Kayleigh\",\n  \"Kayley\",\n  \"Kayli\",\n  \"Kaylie\",\n  \"Kaylin\",\n  \"Keagan\",\n  \"Keanu\",\n  \"Keara\",\n  \"Keaton\",\n  \"Keegan\",\n  \"Keeley\",\n  \"Keely\",\n  \"Keenan\",\n  \"Keira\",\n  \"Keith\",\n  \"Kellen\",\n  \"Kelley\",\n  \"Kelli\",\n  \"Kellie\",\n  \"Kelly\",\n  \"Kelsi\",\n  \"Kelsie\",\n  \"Kelton\",\n  \"Kelvin\",\n  \"Ken\",\n  \"Kendall\",\n  \"Kendra\",\n  \"Kendrick\",\n  \"Kenna\",\n  \"Kennedi\",\n  \"Kennedy\",\n  \"Kenneth\",\n  \"Kennith\",\n  \"Kenny\",\n  \"Kenton\",\n  \"Kenya\",\n  \"Kenyatta\",\n  \"Kenyon\",\n  \"Keon\",\n  \"Keshaun\",\n  \"Keshawn\",\n  \"Keven\",\n  \"Kevin\",\n  \"Kevon\",\n  \"Keyon\",\n  \"Keyshawn\",\n  \"Khalid\",\n  \"Khalil\",\n  \"Kian\",\n  \"Kiana\",\n  \"Kianna\",\n  \"Kiara\",\n  \"Kiarra\",\n  \"Kiel\",\n  \"Kiera\",\n  \"Kieran\",\n  \"Kiley\",\n  \"Kim\",\n  \"Kimberly\",\n  \"King\",\n  \"Kip\",\n  \"Kira\",\n  \"Kirk\",\n  \"Kirsten\",\n  \"Kirstin\",\n  \"Kitty\",\n  \"Kobe\",\n  \"Koby\",\n  \"Kody\",\n  \"Kolby\",\n  \"Kole\",\n  \"Korbin\",\n  \"Korey\",\n  \"Kory\",\n  \"Kraig\",\n  \"Kris\",\n  \"Krista\",\n  \"Kristian\",\n  \"Kristin\",\n  \"Kristina\",\n  \"Kristofer\",\n  \"Kristoffer\",\n  \"Kristopher\",\n  \"Kristy\",\n  \"Krystal\",\n  \"Krystel\",\n  \"Krystina\",\n  \"Kurt\",\n  \"Kurtis\",\n  \"Kyla\",\n  \"Kyle\",\n  \"Kylee\",\n  \"Kyleigh\",\n  \"Kyler\",\n  \"Kylie\",\n  \"Kyra\",\n  \"Lacey\",\n  \"Lacy\",\n  \"Ladarius\",\n  \"Lafayette\",\n  \"Laila\",\n  \"Laisha\",\n  \"Lamar\",\n  \"Lambert\",\n  \"Lamont\",\n  \"Lance\",\n  \"Landen\",\n  \"Lane\",\n  \"Laney\",\n  \"Larissa\",\n  \"Laron\",\n  \"Larry\",\n  \"Larue\",\n  \"Laura\",\n  \"Laurel\",\n  \"Lauren\",\n  \"Laurence\",\n  \"Lauretta\",\n  \"Lauriane\",\n  \"Laurianne\",\n  \"Laurie\",\n  \"Laurine\",\n  \"Laury\",\n  \"Lauryn\",\n  \"Lavada\",\n  \"Lavern\",\n  \"Laverna\",\n  \"Laverne\",\n  \"Lavina\",\n  \"Lavinia\",\n  \"Lavon\",\n  \"Lavonne\",\n  \"Lawrence\",\n  \"Lawson\",\n  \"Layla\",\n  \"Layne\",\n  \"Lazaro\",\n  \"Lea\",\n  \"Leann\",\n  \"Leanna\",\n  \"Leanne\",\n  \"Leatha\",\n  \"Leda\",\n  \"Lee\",\n  \"Leif\",\n  \"Leila\",\n  \"Leilani\",\n  \"Lela\",\n  \"Lelah\",\n  \"Leland\",\n  \"Lelia\",\n  \"Lempi\",\n  \"Lemuel\",\n  \"Lenna\",\n  \"Lennie\",\n  \"Lenny\",\n  \"Lenora\",\n  \"Lenore\",\n  \"Leo\",\n  \"Leola\",\n  \"Leon\",\n  \"Leonard\",\n  \"Leonardo\",\n  \"Leone\",\n  \"Leonel\",\n  \"Leonie\",\n  \"Leonor\",\n  \"Leonora\",\n  \"Leopold\",\n  \"Leopoldo\",\n  \"Leora\",\n  \"Lera\",\n  \"Lesley\",\n  \"Leslie\",\n  \"Lesly\",\n  \"Lessie\",\n  \"Lester\",\n  \"Leta\",\n  \"Letha\",\n  \"Letitia\",\n  \"Levi\",\n  \"Lew\",\n  \"Lewis\",\n  \"Lexi\",\n  \"Lexie\",\n  \"Lexus\",\n  \"Lia\",\n  \"Liam\",\n  \"Liana\",\n  \"Libbie\",\n  \"Libby\",\n  \"Lila\",\n  \"Lilian\",\n  \"Liliana\",\n  \"Liliane\",\n  \"Lilla\",\n  \"Lillian\",\n  \"Lilliana\",\n  \"Lillie\",\n  \"Lilly\",\n  \"Lily\",\n  \"Lilyan\",\n  \"Lina\",\n  \"Lincoln\",\n  \"Linda\",\n  \"Lindsay\",\n  \"Lindsey\",\n  \"Linnea\",\n  \"Linnie\",\n  \"Linwood\",\n  \"Lionel\",\n  \"Lisa\",\n  \"Lisandro\",\n  \"Lisette\",\n  \"Litzy\",\n  \"Liza\",\n  \"Lizeth\",\n  \"Lizzie\",\n  \"Llewellyn\",\n  \"Lloyd\",\n  \"Logan\",\n  \"Lois\",\n  \"Lola\",\n  \"Lolita\",\n  \"Loma\",\n  \"Lon\",\n  \"London\",\n  \"Lonie\",\n  \"Lonnie\",\n  \"Lonny\",\n  \"Lonzo\",\n  \"Lora\",\n  \"Loraine\",\n  \"Loren\",\n  \"Lorena\",\n  \"Lorenz\",\n  \"Lorenza\",\n  \"Lorenzo\",\n  \"Lori\",\n  \"Lorine\",\n  \"Lorna\",\n  \"Lottie\",\n  \"Lou\",\n  \"Louie\",\n  \"Louisa\",\n  \"Lourdes\",\n  \"Louvenia\",\n  \"Lowell\",\n  \"Loy\",\n  \"Loyal\",\n  \"Loyce\",\n  \"Lucas\",\n  \"Luciano\",\n  \"Lucie\",\n  \"Lucienne\",\n  \"Lucile\",\n  \"Lucinda\",\n  \"Lucio\",\n  \"Lucious\",\n  \"Lucius\",\n  \"Lucy\",\n  \"Ludie\",\n  \"Ludwig\",\n  \"Lue\",\n  \"Luella\",\n  \"Luigi\",\n  \"Luis\",\n  \"Luisa\",\n  \"Lukas\",\n  \"Lula\",\n  \"Lulu\",\n  \"Luna\",\n  \"Lupe\",\n  \"Lura\",\n  \"Lurline\",\n  \"Luther\",\n  \"Luz\",\n  \"Lyda\",\n  \"Lydia\",\n  \"Lyla\",\n  \"Lynn\",\n  \"Lyric\",\n  \"Lysanne\",\n  \"Mabel\",\n  \"Mabelle\",\n  \"Mable\",\n  \"Mac\",\n  \"Macey\",\n  \"Maci\",\n  \"Macie\",\n  \"Mack\",\n  \"Mackenzie\",\n  \"Macy\",\n  \"Madaline\",\n  \"Madalyn\",\n  \"Maddison\",\n  \"Madeline\",\n  \"Madelyn\",\n  \"Madelynn\",\n  \"Madge\",\n  \"Madie\",\n  \"Madilyn\",\n  \"Madisen\",\n  \"Madison\",\n  \"Madisyn\",\n  \"Madonna\",\n  \"Madyson\",\n  \"Mae\",\n  \"Maegan\",\n  \"Maeve\",\n  \"Mafalda\",\n  \"Magali\",\n  \"Magdalen\",\n  \"Magdalena\",\n  \"Maggie\",\n  \"Magnolia\",\n  \"Magnus\",\n  \"Maia\",\n  \"Maida\",\n  \"Maiya\",\n  \"Major\",\n  \"Makayla\",\n  \"Makenna\",\n  \"Makenzie\",\n  \"Malachi\",\n  \"Malcolm\",\n  \"Malika\",\n  \"Malinda\",\n  \"Mallie\",\n  \"Mallory\",\n  \"Malvina\",\n  \"Mandy\",\n  \"Manley\",\n  \"Manuel\",\n  \"Manuela\",\n  \"Mara\",\n  \"Marc\",\n  \"Marcel\",\n  \"Marcelina\",\n  \"Marcelino\",\n  \"Marcella\",\n  \"Marcelle\",\n  \"Marcellus\",\n  \"Marcelo\",\n  \"Marcia\",\n  \"Marco\",\n  \"Marcos\",\n  \"Marcus\",\n  \"Margaret\",\n  \"Margarete\",\n  \"Margarett\",\n  \"Margaretta\",\n  \"Margarette\",\n  \"Margarita\",\n  \"Marge\",\n  \"Margie\",\n  \"Margot\",\n  \"Margret\",\n  \"Marguerite\",\n  \"Maria\",\n  \"Mariah\",\n  \"Mariam\",\n  \"Marian\",\n  \"Mariana\",\n  \"Mariane\",\n  \"Marianna\",\n  \"Marianne\",\n  \"Mariano\",\n  \"Maribel\",\n  \"Marie\",\n  \"Mariela\",\n  \"Marielle\",\n  \"Marietta\",\n  \"Marilie\",\n  \"Marilou\",\n  \"Marilyne\",\n  \"Marina\",\n  \"Mario\",\n  \"Marion\",\n  \"Marisa\",\n  \"Marisol\",\n  \"Maritza\",\n  \"Marjolaine\",\n  \"Marjorie\",\n  \"Marjory\",\n  \"Mark\",\n  \"Markus\",\n  \"Marlee\",\n  \"Marlen\",\n  \"Marlene\",\n  \"Marley\",\n  \"Marlin\",\n  \"Marlon\",\n  \"Marques\",\n  \"Marquis\",\n  \"Marquise\",\n  \"Marshall\",\n  \"Marta\",\n  \"Martin\",\n  \"Martina\",\n  \"Martine\",\n  \"Marty\",\n  \"Marvin\",\n  \"Mary\",\n  \"Maryam\",\n  \"Maryjane\",\n  \"Maryse\",\n  \"Mason\",\n  \"Mateo\",\n  \"Mathew\",\n  \"Mathias\",\n  \"Mathilde\",\n  \"Matilda\",\n  \"Matilde\",\n  \"Matt\",\n  \"Matteo\",\n  \"Mattie\",\n  \"Maud\",\n  \"Maude\",\n  \"Maudie\",\n  \"Maureen\",\n  \"Maurice\",\n  \"Mauricio\",\n  \"Maurine\",\n  \"Maverick\",\n  \"Mavis\",\n  \"Max\",\n  \"Maxie\",\n  \"Maxime\",\n  \"Maximilian\",\n  \"Maximillia\",\n  \"Maximillian\",\n  \"Maximo\",\n  \"Maximus\",\n  \"Maxine\",\n  \"Maxwell\",\n  \"May\",\n  \"Maya\",\n  \"Maybell\",\n  \"Maybelle\",\n  \"Maye\",\n  \"Maymie\",\n  \"Maynard\",\n  \"Mayra\",\n  \"Mazie\",\n  \"Mckayla\",\n  \"Mckenna\",\n  \"Mckenzie\",\n  \"Meagan\",\n  \"Meaghan\",\n  \"Meda\",\n  \"Megane\",\n  \"Meggie\",\n  \"Meghan\",\n  \"Mekhi\",\n  \"Melany\",\n  \"Melba\",\n  \"Melisa\",\n  \"Melissa\",\n  \"Mellie\",\n  \"Melody\",\n  \"Melvin\",\n  \"Melvina\",\n  \"Melyna\",\n  \"Melyssa\",\n  \"Mercedes\",\n  \"Meredith\",\n  \"Merl\",\n  \"Merle\",\n  \"Merlin\",\n  \"Merritt\",\n  \"Mertie\",\n  \"Mervin\",\n  \"Meta\",\n  \"Mia\",\n  \"Micaela\",\n  \"Micah\",\n  \"Michael\",\n  \"Michaela\",\n  \"Michale\",\n  \"Micheal\",\n  \"Michel\",\n  \"Michele\",\n  \"Michelle\",\n  \"Miguel\",\n  \"Mikayla\",\n  \"Mike\",\n  \"Mikel\",\n  \"Milan\",\n  \"Miles\",\n  \"Milford\",\n  \"Miller\",\n  \"Millie\",\n  \"Milo\",\n  \"Milton\",\n  \"Mina\",\n  \"Minerva\",\n  \"Minnie\",\n  \"Miracle\",\n  \"Mireille\",\n  \"Mireya\",\n  \"Misael\",\n  \"Missouri\",\n  \"Misty\",\n  \"Mitchel\",\n  \"Mitchell\",\n  \"Mittie\",\n  \"Modesta\",\n  \"Modesto\",\n  \"Mohamed\",\n  \"Mohammad\",\n  \"Mohammed\",\n  \"Moises\",\n  \"Mollie\",\n  \"Molly\",\n  \"Mona\",\n  \"Monica\",\n  \"Monique\",\n  \"Monroe\",\n  \"Monserrat\",\n  \"Monserrate\",\n  \"Montana\",\n  \"Monte\",\n  \"Monty\",\n  \"Morgan\",\n  \"Moriah\",\n  \"Morris\",\n  \"Mortimer\",\n  \"Morton\",\n  \"Mose\",\n  \"Moses\",\n  \"Moshe\",\n  \"Mossie\",\n  \"Mozell\",\n  \"Mozelle\",\n  \"Muhammad\",\n  \"Muriel\",\n  \"Murl\",\n  \"Murphy\",\n  \"Murray\",\n  \"Mustafa\",\n  \"Mya\",\n  \"Myah\",\n  \"Mylene\",\n  \"Myles\",\n  \"Myra\",\n  \"Myriam\",\n  \"Myrl\",\n  \"Myrna\",\n  \"Myron\",\n  \"Myrtice\",\n  \"Myrtie\",\n  \"Myrtis\",\n  \"Myrtle\",\n  \"Nadia\",\n  \"Nakia\",\n  \"Name\",\n  \"Nannie\",\n  \"Naomi\",\n  \"Naomie\",\n  \"Napoleon\",\n  \"Narciso\",\n  \"Nash\",\n  \"Nasir\",\n  \"Nat\",\n  \"Natalia\",\n  \"Natalie\",\n  \"Natasha\",\n  \"Nathan\",\n  \"Nathanael\",\n  \"Nathanial\",\n  \"Nathaniel\",\n  \"Nathen\",\n  \"Nayeli\",\n  \"Neal\",\n  \"Ned\",\n  \"Nedra\",\n  \"Neha\",\n  \"Neil\",\n  \"Nelda\",\n  \"Nella\",\n  \"Nelle\",\n  \"Nellie\",\n  \"Nels\",\n  \"Nelson\",\n  \"Neoma\",\n  \"Nestor\",\n  \"Nettie\",\n  \"Neva\",\n  \"Newell\",\n  \"Newton\",\n  \"Nia\",\n  \"Nicholas\",\n  \"Nicholaus\",\n  \"Nichole\",\n  \"Nick\",\n  \"Nicklaus\",\n  \"Nickolas\",\n  \"Nico\",\n  \"Nicola\",\n  \"Nicolas\",\n  \"Nicole\",\n  \"Nicolette\",\n  \"Nigel\",\n  \"Nikita\",\n  \"Nikki\",\n  \"Nikko\",\n  \"Niko\",\n  \"Nikolas\",\n  \"Nils\",\n  \"Nina\",\n  \"Noah\",\n  \"Noble\",\n  \"Noe\",\n  \"Noel\",\n  \"Noelia\",\n  \"Noemi\",\n  \"Noemie\",\n  \"Noemy\",\n  \"Nola\",\n  \"Nolan\",\n  \"Nona\",\n  \"Nora\",\n  \"Norbert\",\n  \"Norberto\",\n  \"Norene\",\n  \"Norma\",\n  \"Norris\",\n  \"Norval\",\n  \"Norwood\",\n  \"Nova\",\n  \"Novella\",\n  \"Nya\",\n  \"Nyah\",\n  \"Nyasia\",\n  \"Obie\",\n  \"Oceane\",\n  \"Ocie\",\n  \"Octavia\",\n  \"Oda\",\n  \"Odell\",\n  \"Odessa\",\n  \"Odie\",\n  \"Ofelia\",\n  \"Okey\",\n  \"Ola\",\n  \"Olaf\",\n  \"Ole\",\n  \"Olen\",\n  \"Oleta\",\n  \"Olga\",\n  \"Olin\",\n  \"Oliver\",\n  \"Ollie\",\n  \"Oma\",\n  \"Omari\",\n  \"Omer\",\n  \"Ona\",\n  \"Onie\",\n  \"Opal\",\n  \"Ophelia\",\n  \"Ora\",\n  \"Oral\",\n  \"Oran\",\n  \"Oren\",\n  \"Orie\",\n  \"Orin\",\n  \"Orion\",\n  \"Orland\",\n  \"Orlando\",\n  \"Orlo\",\n  \"Orpha\",\n  \"Orrin\",\n  \"Orval\",\n  \"Orville\",\n  \"Osbaldo\",\n  \"Osborne\",\n  \"Oscar\",\n  \"Osvaldo\",\n  \"Oswald\",\n  \"Oswaldo\",\n  \"Otha\",\n  \"Otho\",\n  \"Otilia\",\n  \"Otis\",\n  \"Ottilie\",\n  \"Ottis\",\n  \"Otto\",\n  \"Ova\",\n  \"Owen\",\n  \"Ozella\",\n  \"Pablo\",\n  \"Paige\",\n  \"Palma\",\n  \"Pamela\",\n  \"Pansy\",\n  \"Paolo\",\n  \"Paris\",\n  \"Parker\",\n  \"Pascale\",\n  \"Pasquale\",\n  \"Pat\",\n  \"Patience\",\n  \"Patricia\",\n  \"Patrick\",\n  \"Patsy\",\n  \"Pattie\",\n  \"Paul\",\n  \"Paula\",\n  \"Pauline\",\n  \"Paxton\",\n  \"Payton\",\n  \"Pearl\",\n  \"Pearlie\",\n  \"Pearline\",\n  \"Pedro\",\n  \"Peggie\",\n  \"Penelope\",\n  \"Percival\",\n  \"Percy\",\n  \"Perry\",\n  \"Pete\",\n  \"Peter\",\n  \"Petra\",\n  \"Peyton\",\n  \"Philip\",\n  \"Phoebe\",\n  \"Phyllis\",\n  \"Pierce\",\n  \"Pierre\",\n  \"Pietro\",\n  \"Pink\",\n  \"Pinkie\",\n  \"Piper\",\n  \"Polly\",\n  \"Porter\",\n  \"Precious\",\n  \"Presley\",\n  \"Preston\",\n  \"Price\",\n  \"Prince\",\n  \"Princess\",\n  \"Priscilla\",\n  \"Providenci\",\n  \"Prudence\",\n  \"Queen\",\n  \"Queenie\",\n  \"Quentin\",\n  \"Quincy\",\n  \"Quinn\",\n  \"Quinten\",\n  \"Quinton\",\n  \"Rachael\",\n  \"Rachel\",\n  \"Rachelle\",\n  \"Rae\",\n  \"Raegan\",\n  \"Rafael\",\n  \"Rafaela\",\n  \"Raheem\",\n  \"Rahsaan\",\n  \"Rahul\",\n  \"Raina\",\n  \"Raleigh\",\n  \"Ralph\",\n  \"Ramiro\",\n  \"Ramon\",\n  \"Ramona\",\n  \"Randal\",\n  \"Randall\",\n  \"Randi\",\n  \"Randy\",\n  \"Ransom\",\n  \"Raoul\",\n  \"Raphael\",\n  \"Raphaelle\",\n  \"Raquel\",\n  \"Rashad\",\n  \"Rashawn\",\n  \"Rasheed\",\n  \"Raul\",\n  \"Raven\",\n  \"Ray\",\n  \"Raymond\",\n  \"Raymundo\",\n  \"Reagan\",\n  \"Reanna\",\n  \"Reba\",\n  \"Rebeca\",\n  \"Rebecca\",\n  \"Rebeka\",\n  \"Rebekah\",\n  \"Reece\",\n  \"Reed\",\n  \"Reese\",\n  \"Regan\",\n  \"Reggie\",\n  \"Reginald\",\n  \"Reid\",\n  \"Reilly\",\n  \"Reina\",\n  \"Reinhold\",\n  \"Remington\",\n  \"Rene\",\n  \"Renee\",\n  \"Ressie\",\n  \"Reta\",\n  \"Retha\",\n  \"Retta\",\n  \"Reuben\",\n  \"Reva\",\n  \"Rex\",\n  \"Rey\",\n  \"Reyes\",\n  \"Reymundo\",\n  \"Reyna\",\n  \"Reynold\",\n  \"Rhea\",\n  \"Rhett\",\n  \"Rhianna\",\n  \"Rhiannon\",\n  \"Rhoda\",\n  \"Ricardo\",\n  \"Richard\",\n  \"Richie\",\n  \"Richmond\",\n  \"Rick\",\n  \"Rickey\",\n  \"Rickie\",\n  \"Ricky\",\n  \"Rico\",\n  \"Rigoberto\",\n  \"Riley\",\n  \"Rita\",\n  \"River\",\n  \"Robb\",\n  \"Robbie\",\n  \"Robert\",\n  \"Roberta\",\n  \"Roberto\",\n  \"Robin\",\n  \"Robyn\",\n  \"Rocio\",\n  \"Rocky\",\n  \"Rod\",\n  \"Roderick\",\n  \"Rodger\",\n  \"Rodolfo\",\n  \"Rodrick\",\n  \"Rodrigo\",\n  \"Roel\",\n  \"Rogelio\",\n  \"Roger\",\n  \"Rogers\",\n  \"Rolando\",\n  \"Rollin\",\n  \"Roma\",\n  \"Romaine\",\n  \"Roman\",\n  \"Ron\",\n  \"Ronaldo\",\n  \"Ronny\",\n  \"Roosevelt\",\n  \"Rory\",\n  \"Rosa\",\n  \"Rosalee\",\n  \"Rosalia\",\n  \"Rosalind\",\n  \"Rosalinda\",\n  \"Rosalyn\",\n  \"Rosamond\",\n  \"Rosanna\",\n  \"Rosario\",\n  \"Roscoe\",\n  \"Rose\",\n  \"Rosella\",\n  \"Roselyn\",\n  \"Rosemarie\",\n  \"Rosemary\",\n  \"Rosendo\",\n  \"Rosetta\",\n  \"Rosie\",\n  \"Rosina\",\n  \"Roslyn\",\n  \"Ross\",\n  \"Rossie\",\n  \"Rowan\",\n  \"Rowena\",\n  \"Rowland\",\n  \"Roxane\",\n  \"Roxanne\",\n  \"Roy\",\n  \"Royal\",\n  \"Royce\",\n  \"Rozella\",\n  \"Ruben\",\n  \"Rubie\",\n  \"Ruby\",\n  \"Rubye\",\n  \"Rudolph\",\n  \"Rudy\",\n  \"Rupert\",\n  \"Russ\",\n  \"Russel\",\n  \"Russell\",\n  \"Rusty\",\n  \"Ruth\",\n  \"Ruthe\",\n  \"Ruthie\",\n  \"Ryan\",\n  \"Ryann\",\n  \"Ryder\",\n  \"Rylan\",\n  \"Rylee\",\n  \"Ryleigh\",\n  \"Ryley\",\n  \"Sabina\",\n  \"Sabrina\",\n  \"Sabryna\",\n  \"Sadie\",\n  \"Sadye\",\n  \"Sage\",\n  \"Saige\",\n  \"Sallie\",\n  \"Sally\",\n  \"Salma\",\n  \"Salvador\",\n  \"Salvatore\",\n  \"Sam\",\n  \"Samanta\",\n  \"Samantha\",\n  \"Samara\",\n  \"Samir\",\n  \"Sammie\",\n  \"Sammy\",\n  \"Samson\",\n  \"Sandra\",\n  \"Sandrine\",\n  \"Sandy\",\n  \"Sanford\",\n  \"Santa\",\n  \"Santiago\",\n  \"Santina\",\n  \"Santino\",\n  \"Santos\",\n  \"Sarah\",\n  \"Sarai\",\n  \"Sarina\",\n  \"Sasha\",\n  \"Saul\",\n  \"Savanah\",\n  \"Savanna\",\n  \"Savannah\",\n  \"Savion\",\n  \"Scarlett\",\n  \"Schuyler\",\n  \"Scot\",\n  \"Scottie\",\n  \"Scotty\",\n  \"Seamus\",\n  \"Sean\",\n  \"Sebastian\",\n  \"Sedrick\",\n  \"Selena\",\n  \"Selina\",\n  \"Selmer\",\n  \"Serena\",\n  \"Serenity\",\n  \"Seth\",\n  \"Shad\",\n  \"Shaina\",\n  \"Shakira\",\n  \"Shana\",\n  \"Shane\",\n  \"Shanel\",\n  \"Shanelle\",\n  \"Shania\",\n  \"Shanie\",\n  \"Shaniya\",\n  \"Shanna\",\n  \"Shannon\",\n  \"Shanny\",\n  \"Shanon\",\n  \"Shany\",\n  \"Sharon\",\n  \"Shaun\",\n  \"Shawn\",\n  \"Shawna\",\n  \"Shaylee\",\n  \"Shayna\",\n  \"Shayne\",\n  \"Shea\",\n  \"Sheila\",\n  \"Sheldon\",\n  \"Shemar\",\n  \"Sheridan\",\n  \"Sherman\",\n  \"Sherwood\",\n  \"Shirley\",\n  \"Shyann\",\n  \"Shyanne\",\n  \"Sibyl\",\n  \"Sid\",\n  \"Sidney\",\n  \"Sienna\",\n  \"Sierra\",\n  \"Sigmund\",\n  \"Sigrid\",\n  \"Sigurd\",\n  \"Silas\",\n  \"Sim\",\n  \"Simeon\",\n  \"Simone\",\n  \"Sincere\",\n  \"Sister\",\n  \"Skye\",\n  \"Skyla\",\n  \"Skylar\",\n  \"Sofia\",\n  \"Soledad\",\n  \"Solon\",\n  \"Sonia\",\n  \"Sonny\",\n  \"Sonya\",\n  \"Sophia\",\n  \"Sophie\",\n  \"Spencer\",\n  \"Stacey\",\n  \"Stacy\",\n  \"Stan\",\n  \"Stanford\",\n  \"Stanley\",\n  \"Stanton\",\n  \"Stefan\",\n  \"Stefanie\",\n  \"Stella\",\n  \"Stephan\",\n  \"Stephania\",\n  \"Stephanie\",\n  \"Stephany\",\n  \"Stephen\",\n  \"Stephon\",\n  \"Sterling\",\n  \"Steve\",\n  \"Stevie\",\n  \"Stewart\",\n  \"Stone\",\n  \"Stuart\",\n  \"Summer\",\n  \"Sunny\",\n  \"Susan\",\n  \"Susana\",\n  \"Susanna\",\n  \"Susie\",\n  \"Suzanne\",\n  \"Sven\",\n  \"Syble\",\n  \"Sydnee\",\n  \"Sydney\",\n  \"Sydni\",\n  \"Sydnie\",\n  \"Sylvan\",\n  \"Sylvester\",\n  \"Sylvia\",\n  \"Tabitha\",\n  \"Tad\",\n  \"Talia\",\n  \"Talon\",\n  \"Tamara\",\n  \"Tamia\",\n  \"Tania\",\n  \"Tanner\",\n  \"Tanya\",\n  \"Tara\",\n  \"Taryn\",\n  \"Tate\",\n  \"Tatum\",\n  \"Tatyana\",\n  \"Taurean\",\n  \"Tavares\",\n  \"Taya\",\n  \"Taylor\",\n  \"Teagan\",\n  \"Ted\",\n  \"Telly\",\n  \"Terence\",\n  \"Teresa\",\n  \"Terrance\",\n  \"Terrell\",\n  \"Terrence\",\n  \"Terrill\",\n  \"Terry\",\n  \"Tess\",\n  \"Tessie\",\n  \"Tevin\",\n  \"Thad\",\n  \"Thaddeus\",\n  \"Thalia\",\n  \"Thea\",\n  \"Thelma\",\n  \"Theo\",\n  \"Theodora\",\n  \"Theodore\",\n  \"Theresa\",\n  \"Therese\",\n  \"Theresia\",\n  \"Theron\",\n  \"Thomas\",\n  \"Thora\",\n  \"Thurman\",\n  \"Tia\",\n  \"Tiana\",\n  \"Tianna\",\n  \"Tiara\",\n  \"Tierra\",\n  \"Tiffany\",\n  \"Tillman\",\n  \"Timmothy\",\n  \"Timmy\",\n  \"Timothy\",\n  \"Tina\",\n  \"Tito\",\n  \"Titus\",\n  \"Tobin\",\n  \"Toby\",\n  \"Tod\",\n  \"Tom\",\n  \"Tomas\",\n  \"Tomasa\",\n  \"Tommie\",\n  \"Toney\",\n  \"Toni\",\n  \"Tony\",\n  \"Torey\",\n  \"Torrance\",\n  \"Torrey\",\n  \"Toy\",\n  \"Trace\",\n  \"Tracey\",\n  \"Tracy\",\n  \"Travis\",\n  \"Travon\",\n  \"Tre\",\n  \"Tremaine\",\n  \"Tremayne\",\n  \"Trent\",\n  \"Trenton\",\n  \"Tressa\",\n  \"Tressie\",\n  \"Treva\",\n  \"Trever\",\n  \"Trevion\",\n  \"Trevor\",\n  \"Trey\",\n  \"Trinity\",\n  \"Trisha\",\n  \"Tristian\",\n  \"Tristin\",\n  \"Triston\",\n  \"Troy\",\n  \"Trudie\",\n  \"Trycia\",\n  \"Trystan\",\n  \"Turner\",\n  \"Twila\",\n  \"Tyler\",\n  \"Tyra\",\n  \"Tyree\",\n  \"Tyreek\",\n  \"Tyrel\",\n  \"Tyrell\",\n  \"Tyrese\",\n  \"Tyrique\",\n  \"Tyshawn\",\n  \"Tyson\",\n  \"Ubaldo\",\n  \"Ulices\",\n  \"Ulises\",\n  \"Una\",\n  \"Unique\",\n  \"Urban\",\n  \"Uriah\",\n  \"Uriel\",\n  \"Ursula\",\n  \"Vada\",\n  \"Valentin\",\n  \"Valentina\",\n  \"Valentine\",\n  \"Valerie\",\n  \"Vallie\",\n  \"Van\",\n  \"Vance\",\n  \"Vanessa\",\n  \"Vaughn\",\n  \"Veda\",\n  \"Velda\",\n  \"Vella\",\n  \"Velma\",\n  \"Velva\",\n  \"Vena\",\n  \"Verda\",\n  \"Verdie\",\n  \"Vergie\",\n  \"Verla\",\n  \"Verlie\",\n  \"Vern\",\n  \"Verna\",\n  \"Verner\",\n  \"Vernice\",\n  \"Vernie\",\n  \"Vernon\",\n  \"Verona\",\n  \"Veronica\",\n  \"Vesta\",\n  \"Vicenta\",\n  \"Vicente\",\n  \"Vickie\",\n  \"Vicky\",\n  \"Victor\",\n  \"Victoria\",\n  \"Vida\",\n  \"Vidal\",\n  \"Vilma\",\n  \"Vince\",\n  \"Vincent\",\n  \"Vincenza\",\n  \"Vincenzo\",\n  \"Vinnie\",\n  \"Viola\",\n  \"Violet\",\n  \"Violette\",\n  \"Virgie\",\n  \"Virgil\",\n  \"Virginia\",\n  \"Virginie\",\n  \"Vita\",\n  \"Vito\",\n  \"Viva\",\n  \"Vivian\",\n  \"Viviane\",\n  \"Vivianne\",\n  \"Vivien\",\n  \"Vivienne\",\n  \"Vladimir\",\n  \"Wade\",\n  \"Waino\",\n  \"Waldo\",\n  \"Walker\",\n  \"Wallace\",\n  \"Walter\",\n  \"Walton\",\n  \"Wanda\",\n  \"Ward\",\n  \"Warren\",\n  \"Watson\",\n  \"Wava\",\n  \"Waylon\",\n  \"Wayne\",\n  \"Webster\",\n  \"Weldon\",\n  \"Wellington\",\n  \"Wendell\",\n  \"Wendy\",\n  \"Werner\",\n  \"Westley\",\n  \"Weston\",\n  \"Whitney\",\n  \"Wilber\",\n  \"Wilbert\",\n  \"Wilburn\",\n  \"Wiley\",\n  \"Wilford\",\n  \"Wilfred\",\n  \"Wilfredo\",\n  \"Wilfrid\",\n  \"Wilhelm\",\n  \"Wilhelmine\",\n  \"Will\",\n  \"Willa\",\n  \"Willard\",\n  \"William\",\n  \"Willie\",\n  \"Willis\",\n  \"Willow\",\n  \"Willy\",\n  \"Wilma\",\n  \"Wilmer\",\n  \"Wilson\",\n  \"Wilton\",\n  \"Winfield\",\n  \"Winifred\",\n  \"Winnifred\",\n  \"Winona\",\n  \"Winston\",\n  \"Woodrow\",\n  \"Wyatt\",\n  \"Wyman\",\n  \"Xander\",\n  \"Xavier\",\n  \"Xzavier\",\n  \"Yadira\",\n  \"Yasmeen\",\n  \"Yasmin\",\n  \"Yasmine\",\n  \"Yazmin\",\n  \"Yesenia\",\n  \"Yessenia\",\n  \"Yolanda\",\n  \"Yoshiko\",\n  \"Yvette\",\n  \"Yvonne\",\n  \"Zachariah\",\n  \"Zachary\",\n  \"Zachery\",\n  \"Zack\",\n  \"Zackary\",\n  \"Zackery\",\n  \"Zakary\",\n  \"Zander\",\n  \"Zane\",\n  \"Zaria\",\n  \"Zechariah\",\n  \"Zelda\",\n  \"Zella\",\n  \"Zelma\",\n  \"Zena\",\n  \"Zetta\",\n  \"Zion\",\n  \"Zita\",\n  \"Zoe\",\n  \"Zoey\",\n  \"Zoie\",\n  \"Zoila\",\n  \"Zola\",\n  \"Zora\",\n  \"Zula\"\n];\n\n},{}],259:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\nname.title = require(\"./title\");\nname.name = require(\"./name\");\n\n},{\"./first_name\":258,\"./last_name\":260,\"./name\":261,\"./prefix\":262,\"./suffix\":263,\"./title\":264}],260:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abbott\",\n  \"Abernathy\",\n  \"Abshire\",\n  \"Adams\",\n  \"Altenwerth\",\n  \"Anderson\",\n  \"Ankunding\",\n  \"Armstrong\",\n  \"Auer\",\n  \"Aufderhar\",\n  \"Bahringer\",\n  \"Bailey\",\n  \"Balistreri\",\n  \"Barrows\",\n  \"Bartell\",\n  \"Bartoletti\",\n  \"Barton\",\n  \"Bashirian\",\n  \"Batz\",\n  \"Bauch\",\n  \"Baumbach\",\n  \"Bayer\",\n  \"Beahan\",\n  \"Beatty\",\n  \"Bechtelar\",\n  \"Becker\",\n  \"Bednar\",\n  \"Beer\",\n  \"Beier\",\n  \"Berge\",\n  \"Bergnaum\",\n  \"Bergstrom\",\n  \"Bernhard\",\n  \"Bernier\",\n  \"Bins\",\n  \"Blanda\",\n  \"Blick\",\n  \"Block\",\n  \"Bode\",\n  \"Boehm\",\n  \"Bogan\",\n  \"Bogisich\",\n  \"Borer\",\n  \"Bosco\",\n  \"Botsford\",\n  \"Boyer\",\n  \"Boyle\",\n  \"Bradtke\",\n  \"Brakus\",\n  \"Braun\",\n  \"Breitenberg\",\n  \"Brekke\",\n  \"Brown\",\n  \"Bruen\",\n  \"Buckridge\",\n  \"Carroll\",\n  \"Carter\",\n  \"Cartwright\",\n  \"Casper\",\n  \"Cassin\",\n  \"Champlin\",\n  \"Christiansen\",\n  \"Cole\",\n  \"Collier\",\n  \"Collins\",\n  \"Conn\",\n  \"Connelly\",\n  \"Conroy\",\n  \"Considine\",\n  \"Corkery\",\n  \"Cormier\",\n  \"Corwin\",\n  \"Cremin\",\n  \"Crist\",\n  \"Crona\",\n  \"Cronin\",\n  \"Crooks\",\n  \"Cruickshank\",\n  \"Cummerata\",\n  \"Cummings\",\n  \"Dach\",\n  \"D'Amore\",\n  \"Daniel\",\n  \"Dare\",\n  \"Daugherty\",\n  \"Davis\",\n  \"Deckow\",\n  \"Denesik\",\n  \"Dibbert\",\n  \"Dickens\",\n  \"Dicki\",\n  \"Dickinson\",\n  \"Dietrich\",\n  \"Donnelly\",\n  \"Dooley\",\n  \"Douglas\",\n  \"Doyle\",\n  \"DuBuque\",\n  \"Durgan\",\n  \"Ebert\",\n  \"Effertz\",\n  \"Eichmann\",\n  \"Emard\",\n  \"Emmerich\",\n  \"Erdman\",\n  \"Ernser\",\n  \"Fadel\",\n  \"Fahey\",\n  \"Farrell\",\n  \"Fay\",\n  \"Feeney\",\n  \"Feest\",\n  \"Feil\",\n  \"Ferry\",\n  \"Fisher\",\n  \"Flatley\",\n  \"Frami\",\n  \"Franecki\",\n  \"Friesen\",\n  \"Fritsch\",\n  \"Funk\",\n  \"Gaylord\",\n  \"Gerhold\",\n  \"Gerlach\",\n  \"Gibson\",\n  \"Gislason\",\n  \"Gleason\",\n  \"Gleichner\",\n  \"Glover\",\n  \"Goldner\",\n  \"Goodwin\",\n  \"Gorczany\",\n  \"Gottlieb\",\n  \"Goyette\",\n  \"Grady\",\n  \"Graham\",\n  \"Grant\",\n  \"Green\",\n  \"Greenfelder\",\n  \"Greenholt\",\n  \"Grimes\",\n  \"Gulgowski\",\n  \"Gusikowski\",\n  \"Gutkowski\",\n  \"Gutmann\",\n  \"Haag\",\n  \"Hackett\",\n  \"Hagenes\",\n  \"Hahn\",\n  \"Haley\",\n  \"Halvorson\",\n  \"Hamill\",\n  \"Hammes\",\n  \"Hand\",\n  \"Hane\",\n  \"Hansen\",\n  \"Harber\",\n  \"Harris\",\n  \"Hartmann\",\n  \"Harvey\",\n  \"Hauck\",\n  \"Hayes\",\n  \"Heaney\",\n  \"Heathcote\",\n  \"Hegmann\",\n  \"Heidenreich\",\n  \"Heller\",\n  \"Herman\",\n  \"Hermann\",\n  \"Hermiston\",\n  \"Herzog\",\n  \"Hessel\",\n  \"Hettinger\",\n  \"Hickle\",\n  \"Hilll\",\n  \"Hills\",\n  \"Hilpert\",\n  \"Hintz\",\n  \"Hirthe\",\n  \"Hodkiewicz\",\n  \"Hoeger\",\n  \"Homenick\",\n  \"Hoppe\",\n  \"Howe\",\n  \"Howell\",\n  \"Hudson\",\n  \"Huel\",\n  \"Huels\",\n  \"Hyatt\",\n  \"Jacobi\",\n  \"Jacobs\",\n  \"Jacobson\",\n  \"Jakubowski\",\n  \"Jaskolski\",\n  \"Jast\",\n  \"Jenkins\",\n  \"Jerde\",\n  \"Johns\",\n  \"Johnson\",\n  \"Johnston\",\n  \"Jones\",\n  \"Kassulke\",\n  \"Kautzer\",\n  \"Keebler\",\n  \"Keeling\",\n  \"Kemmer\",\n  \"Kerluke\",\n  \"Kertzmann\",\n  \"Kessler\",\n  \"Kiehn\",\n  \"Kihn\",\n  \"Kilback\",\n  \"King\",\n  \"Kirlin\",\n  \"Klein\",\n  \"Kling\",\n  \"Klocko\",\n  \"Koch\",\n  \"Koelpin\",\n  \"Koepp\",\n  \"Kohler\",\n  \"Konopelski\",\n  \"Koss\",\n  \"Kovacek\",\n  \"Kozey\",\n  \"Krajcik\",\n  \"Kreiger\",\n  \"Kris\",\n  \"Kshlerin\",\n  \"Kub\",\n  \"Kuhic\",\n  \"Kuhlman\",\n  \"Kuhn\",\n  \"Kulas\",\n  \"Kunde\",\n  \"Kunze\",\n  \"Kuphal\",\n  \"Kutch\",\n  \"Kuvalis\",\n  \"Labadie\",\n  \"Lakin\",\n  \"Lang\",\n  \"Langosh\",\n  \"Langworth\",\n  \"Larkin\",\n  \"Larson\",\n  \"Leannon\",\n  \"Lebsack\",\n  \"Ledner\",\n  \"Leffler\",\n  \"Legros\",\n  \"Lehner\",\n  \"Lemke\",\n  \"Lesch\",\n  \"Leuschke\",\n  \"Lind\",\n  \"Lindgren\",\n  \"Littel\",\n  \"Little\",\n  \"Lockman\",\n  \"Lowe\",\n  \"Lubowitz\",\n  \"Lueilwitz\",\n  \"Luettgen\",\n  \"Lynch\",\n  \"Macejkovic\",\n  \"MacGyver\",\n  \"Maggio\",\n  \"Mann\",\n  \"Mante\",\n  \"Marks\",\n  \"Marquardt\",\n  \"Marvin\",\n  \"Mayer\",\n  \"Mayert\",\n  \"McClure\",\n  \"McCullough\",\n  \"McDermott\",\n  \"McGlynn\",\n  \"McKenzie\",\n  \"McLaughlin\",\n  \"Medhurst\",\n  \"Mertz\",\n  \"Metz\",\n  \"Miller\",\n  \"Mills\",\n  \"Mitchell\",\n  \"Moen\",\n  \"Mohr\",\n  \"Monahan\",\n  \"Moore\",\n  \"Morar\",\n  \"Morissette\",\n  \"Mosciski\",\n  \"Mraz\",\n  \"Mueller\",\n  \"Muller\",\n  \"Murazik\",\n  \"Murphy\",\n  \"Murray\",\n  \"Nader\",\n  \"Nicolas\",\n  \"Nienow\",\n  \"Nikolaus\",\n  \"Nitzsche\",\n  \"Nolan\",\n  \"Oberbrunner\",\n  \"O'Connell\",\n  \"O'Conner\",\n  \"O'Hara\",\n  \"O'Keefe\",\n  \"O'Kon\",\n  \"Okuneva\",\n  \"Olson\",\n  \"Ondricka\",\n  \"O'Reilly\",\n  \"Orn\",\n  \"Ortiz\",\n  \"Osinski\",\n  \"Pacocha\",\n  \"Padberg\",\n  \"Pagac\",\n  \"Parisian\",\n  \"Parker\",\n  \"Paucek\",\n  \"Pfannerstill\",\n  \"Pfeffer\",\n  \"Pollich\",\n  \"Pouros\",\n  \"Powlowski\",\n  \"Predovic\",\n  \"Price\",\n  \"Prohaska\",\n  \"Prosacco\",\n  \"Purdy\",\n  \"Quigley\",\n  \"Quitzon\",\n  \"Rath\",\n  \"Ratke\",\n  \"Rau\",\n  \"Raynor\",\n  \"Reichel\",\n  \"Reichert\",\n  \"Reilly\",\n  \"Reinger\",\n  \"Rempel\",\n  \"Renner\",\n  \"Reynolds\",\n  \"Rice\",\n  \"Rippin\",\n  \"Ritchie\",\n  \"Robel\",\n  \"Roberts\",\n  \"Rodriguez\",\n  \"Rogahn\",\n  \"Rohan\",\n  \"Rolfson\",\n  \"Romaguera\",\n  \"Roob\",\n  \"Rosenbaum\",\n  \"Rowe\",\n  \"Ruecker\",\n  \"Runolfsdottir\",\n  \"Runolfsson\",\n  \"Runte\",\n  \"Russel\",\n  \"Rutherford\",\n  \"Ryan\",\n  \"Sanford\",\n  \"Satterfield\",\n  \"Sauer\",\n  \"Sawayn\",\n  \"Schaden\",\n  \"Schaefer\",\n  \"Schamberger\",\n  \"Schiller\",\n  \"Schimmel\",\n  \"Schinner\",\n  \"Schmeler\",\n  \"Schmidt\",\n  \"Schmitt\",\n  \"Schneider\",\n  \"Schoen\",\n  \"Schowalter\",\n  \"Schroeder\",\n  \"Schulist\",\n  \"Schultz\",\n  \"Schumm\",\n  \"Schuppe\",\n  \"Schuster\",\n  \"Senger\",\n  \"Shanahan\",\n  \"Shields\",\n  \"Simonis\",\n  \"Sipes\",\n  \"Skiles\",\n  \"Smith\",\n  \"Smitham\",\n  \"Spencer\",\n  \"Spinka\",\n  \"Sporer\",\n  \"Stamm\",\n  \"Stanton\",\n  \"Stark\",\n  \"Stehr\",\n  \"Steuber\",\n  \"Stiedemann\",\n  \"Stokes\",\n  \"Stoltenberg\",\n  \"Stracke\",\n  \"Streich\",\n  \"Stroman\",\n  \"Strosin\",\n  \"Swaniawski\",\n  \"Swift\",\n  \"Terry\",\n  \"Thiel\",\n  \"Thompson\",\n  \"Tillman\",\n  \"Torp\",\n  \"Torphy\",\n  \"Towne\",\n  \"Toy\",\n  \"Trantow\",\n  \"Tremblay\",\n  \"Treutel\",\n  \"Tromp\",\n  \"Turcotte\",\n  \"Turner\",\n  \"Ullrich\",\n  \"Upton\",\n  \"Vandervort\",\n  \"Veum\",\n  \"Volkman\",\n  \"Von\",\n  \"VonRueden\",\n  \"Waelchi\",\n  \"Walker\",\n  \"Walsh\",\n  \"Walter\",\n  \"Ward\",\n  \"Waters\",\n  \"Watsica\",\n  \"Weber\",\n  \"Wehner\",\n  \"Weimann\",\n  \"Weissnat\",\n  \"Welch\",\n  \"West\",\n  \"White\",\n  \"Wiegand\",\n  \"Wilderman\",\n  \"Wilkinson\",\n  \"Will\",\n  \"Williamson\",\n  \"Willms\",\n  \"Windler\",\n  \"Wintheiser\",\n  \"Wisoky\",\n  \"Wisozk\",\n  \"Witting\",\n  \"Wiza\",\n  \"Wolf\",\n  \"Wolff\",\n  \"Wuckert\",\n  \"Wunsch\",\n  \"Wyman\",\n  \"Yost\",\n  \"Yundt\",\n  \"Zboncak\",\n  \"Zemlak\",\n  \"Ziemann\",\n  \"Zieme\",\n  \"Zulauf\"\n];\n\n},{}],261:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{first_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{suffix}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\"\n];\n\n},{}],262:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Mr.\",\n  \"Mrs.\",\n  \"Ms.\",\n  \"Miss\",\n  \"Dr.\"\n];\n\n},{}],263:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Jr.\",\n  \"Sr.\",\n  \"I\",\n  \"II\",\n  \"III\",\n  \"IV\",\n  \"V\",\n  \"MD\",\n  \"DDS\",\n  \"PhD\",\n  \"DVM\"\n];\n\n},{}],264:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"descriptor\": [\n    \"Lead\",\n    \"Senior\",\n    \"Direct\",\n    \"Corporate\",\n    \"Dynamic\",\n    \"Future\",\n    \"Product\",\n    \"National\",\n    \"Regional\",\n    \"District\",\n    \"Central\",\n    \"Global\",\n    \"Customer\",\n    \"Investor\",\n    \"Dynamic\",\n    \"International\",\n    \"Legacy\",\n    \"Forward\",\n    \"Internal\",\n    \"Human\",\n    \"Chief\",\n    \"Principal\"\n  ],\n  \"level\": [\n    \"Solutions\",\n    \"Program\",\n    \"Brand\",\n    \"Security\",\n    \"Research\",\n    \"Marketing\",\n    \"Directives\",\n    \"Implementation\",\n    \"Integration\",\n    \"Functionality\",\n    \"Response\",\n    \"Paradigm\",\n    \"Tactics\",\n    \"Identity\",\n    \"Markets\",\n    \"Group\",\n    \"Division\",\n    \"Applications\",\n    \"Optimization\",\n    \"Operations\",\n    \"Infrastructure\",\n    \"Intranet\",\n    \"Communications\",\n    \"Web\",\n    \"Branding\",\n    \"Quality\",\n    \"Assurance\",\n    \"Mobility\",\n    \"Accounts\",\n    \"Data\",\n    \"Creative\",\n    \"Configuration\",\n    \"Accountability\",\n    \"Interactions\",\n    \"Factors\",\n    \"Usability\",\n    \"Metrics\"\n  ],\n  \"job\": [\n    \"Supervisor\",\n    \"Associate\",\n    \"Executive\",\n    \"Liaison\",\n    \"Officer\",\n    \"Manager\",\n    \"Engineer\",\n    \"Specialist\",\n    \"Director\",\n    \"Coordinator\",\n    \"Administrator\",\n    \"Architect\",\n    \"Analyst\",\n    \"Designer\",\n    \"Planner\",\n    \"Orchestrator\",\n    \"Technician\",\n    \"Developer\",\n    \"Producer\",\n    \"Consultant\",\n    \"Assistant\",\n    \"Facilitator\",\n    \"Agent\",\n    \"Representative\",\n    \"Strategist\"\n  ]\n};\n\n},{}],265:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###-###-####\",\n  \"(###) ###-####\",\n  \"1-###-###-####\",\n  \"###.###.####\",\n  \"###-###-####\",\n  \"(###) ###-####\",\n  \"1-###-###-####\",\n  \"###.###.####\",\n  \"###-###-#### x###\",\n  \"(###) ###-#### x###\",\n  \"1-###-###-#### x###\",\n  \"###.###.#### x###\",\n  \"###-###-#### x####\",\n  \"(###) ###-#### x####\",\n  \"1-###-###-#### x####\",\n  \"###.###.#### x####\",\n  \"###-###-#### x#####\",\n  \"(###) ###-#### x#####\",\n  \"1-###-###-#### x#####\",\n  \"###.###.#### x#####\"\n];\n\n},{}],266:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":265,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],267:[function(require,module,exports){\nvar system = {};\nmodule['exports'] = system;\nsystem.mimeTypes = require(\"./mimeTypes\");\n},{\"./mimeTypes\":268}],268:[function(require,module,exports){\n/*\n\nThe MIT License (MIT)\n\nCopyright (c) 2014 Jonathan Ong me@jongleberry.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\nDefinitions from mime-db v1.21.0\nFor updates check: https://github.com/jshttp/mime-db/blob/master/db.json\n\n*/\n\nmodule['exports'] = {\n  \"application/1d-interleaved-parityfec\": {\n    \"source\": \"iana\"\n  },\n  \"application/3gpdash-qoe-report+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/3gpp-ims+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/a2l\": {\n    \"source\": \"iana\"\n  },\n  \"application/activemessage\": {\n    \"source\": \"iana\"\n  },\n  \"application/alto-costmap+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-costmapfilter+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-directory+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-endpointcost+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-endpointcostparams+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-endpointprop+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-endpointpropparams+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-error+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-networkmap+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/alto-networkmapfilter+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/aml\": {\n    \"source\": \"iana\"\n  },\n  \"application/andrew-inset\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ez\"]\n  },\n  \"application/applefile\": {\n    \"source\": \"iana\"\n  },\n  \"application/applixware\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"aw\"]\n  },\n  \"application/atf\": {\n    \"source\": \"iana\"\n  },\n  \"application/atfx\": {\n    \"source\": \"iana\"\n  },\n  \"application/atom+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"atom\"]\n  },\n  \"application/atomcat+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"atomcat\"]\n  },\n  \"application/atomdeleted+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/atomicmail\": {\n    \"source\": \"iana\"\n  },\n  \"application/atomsvc+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"atomsvc\"]\n  },\n  \"application/atxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/auth-policy+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/bacnet-xdd+zip\": {\n    \"source\": \"iana\"\n  },\n  \"application/batch-smtp\": {\n    \"source\": \"iana\"\n  },\n  \"application/bdoc\": {\n    \"compressible\": false,\n    \"extensions\": [\"bdoc\"]\n  },\n  \"application/beep+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/calendar+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/calendar+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/call-completion\": {\n    \"source\": \"iana\"\n  },\n  \"application/cals-1840\": {\n    \"source\": \"iana\"\n  },\n  \"application/cbor\": {\n    \"source\": \"iana\"\n  },\n  \"application/ccmp+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/ccxml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ccxml\"]\n  },\n  \"application/cdfx+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/cdmi-capability\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdmia\"]\n  },\n  \"application/cdmi-container\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdmic\"]\n  },\n  \"application/cdmi-domain\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdmid\"]\n  },\n  \"application/cdmi-object\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdmio\"]\n  },\n  \"application/cdmi-queue\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdmiq\"]\n  },\n  \"application/cdni\": {\n    \"source\": \"iana\"\n  },\n  \"application/cea\": {\n    \"source\": \"iana\"\n  },\n  \"application/cea-2018+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/cellml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/cfw\": {\n    \"source\": \"iana\"\n  },\n  \"application/cms\": {\n    \"source\": \"iana\"\n  },\n  \"application/cnrp+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/coap-group+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/commonground\": {\n    \"source\": \"iana\"\n  },\n  \"application/conference-info+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/cpl+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/csrattrs\": {\n    \"source\": \"iana\"\n  },\n  \"application/csta+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/cstadata+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/csvm+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/cu-seeme\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cu\"]\n  },\n  \"application/cybercash\": {\n    \"source\": \"iana\"\n  },\n  \"application/dart\": {\n    \"compressible\": true\n  },\n  \"application/dash+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mdp\"]\n  },\n  \"application/dashdelta\": {\n    \"source\": \"iana\"\n  },\n  \"application/davmount+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"davmount\"]\n  },\n  \"application/dca-rft\": {\n    \"source\": \"iana\"\n  },\n  \"application/dcd\": {\n    \"source\": \"iana\"\n  },\n  \"application/dec-dx\": {\n    \"source\": \"iana\"\n  },\n  \"application/dialog-info+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/dicom\": {\n    \"source\": \"iana\"\n  },\n  \"application/dii\": {\n    \"source\": \"iana\"\n  },\n  \"application/dit\": {\n    \"source\": \"iana\"\n  },\n  \"application/dns\": {\n    \"source\": \"iana\"\n  },\n  \"application/docbook+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"dbk\"]\n  },\n  \"application/dskpp+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/dssc+der\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dssc\"]\n  },\n  \"application/dssc+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xdssc\"]\n  },\n  \"application/dvcs\": {\n    \"source\": \"iana\"\n  },\n  \"application/ecmascript\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"ecma\"]\n  },\n  \"application/edi-consent\": {\n    \"source\": \"iana\"\n  },\n  \"application/edi-x12\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"application/edifact\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"application/emergencycalldata.comment+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/emergencycalldata.deviceinfo+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/emergencycalldata.providerinfo+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/emergencycalldata.serviceinfo+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/emergencycalldata.subscriberinfo+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/emma+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"emma\"]\n  },\n  \"application/emotionml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/encaprtp\": {\n    \"source\": \"iana\"\n  },\n  \"application/epp+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/epub+zip\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"epub\"]\n  },\n  \"application/eshop\": {\n    \"source\": \"iana\"\n  },\n  \"application/exi\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"exi\"]\n  },\n  \"application/fastinfoset\": {\n    \"source\": \"iana\"\n  },\n  \"application/fastsoap\": {\n    \"source\": \"iana\"\n  },\n  \"application/fdt+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/fits\": {\n    \"source\": \"iana\"\n  },\n  \"application/font-sfnt\": {\n    \"source\": \"iana\"\n  },\n  \"application/font-tdpfr\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pfr\"]\n  },\n  \"application/font-woff\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"woff\"]\n  },\n  \"application/font-woff2\": {\n    \"compressible\": false,\n    \"extensions\": [\"woff2\"]\n  },\n  \"application/framework-attributes+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/gml+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gml\"]\n  },\n  \"application/gpx+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gpx\"]\n  },\n  \"application/gxf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gxf\"]\n  },\n  \"application/gzip\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"application/h224\": {\n    \"source\": \"iana\"\n  },\n  \"application/held+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/http\": {\n    \"source\": \"iana\"\n  },\n  \"application/hyperstudio\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"stk\"]\n  },\n  \"application/ibe-key-request+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/ibe-pkg-reply+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/ibe-pp-data\": {\n    \"source\": \"iana\"\n  },\n  \"application/iges\": {\n    \"source\": \"iana\"\n  },\n  \"application/im-iscomposing+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/index\": {\n    \"source\": \"iana\"\n  },\n  \"application/index.cmd\": {\n    \"source\": \"iana\"\n  },\n  \"application/index.obj\": {\n    \"source\": \"iana\"\n  },\n  \"application/index.response\": {\n    \"source\": \"iana\"\n  },\n  \"application/index.vnd\": {\n    \"source\": \"iana\"\n  },\n  \"application/inkml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ink\",\"inkml\"]\n  },\n  \"application/iotp\": {\n    \"source\": \"iana\"\n  },\n  \"application/ipfix\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ipfix\"]\n  },\n  \"application/ipp\": {\n    \"source\": \"iana\"\n  },\n  \"application/isup\": {\n    \"source\": \"iana\"\n  },\n  \"application/its+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/java-archive\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"jar\",\"war\",\"ear\"]\n  },\n  \"application/java-serialized-object\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"ser\"]\n  },\n  \"application/java-vm\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"class\"]\n  },\n  \"application/javascript\": {\n    \"source\": \"iana\",\n    \"charset\": \"UTF-8\",\n    \"compressible\": true,\n    \"extensions\": [\"js\"]\n  },\n  \"application/jose\": {\n    \"source\": \"iana\"\n  },\n  \"application/jose+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/jrd+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/json\": {\n    \"source\": \"iana\",\n    \"charset\": \"UTF-8\",\n    \"compressible\": true,\n    \"extensions\": [\"json\",\"map\"]\n  },\n  \"application/json-patch+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/json-seq\": {\n    \"source\": \"iana\"\n  },\n  \"application/json5\": {\n    \"extensions\": [\"json5\"]\n  },\n  \"application/jsonml+json\": {\n    \"source\": \"apache\",\n    \"compressible\": true,\n    \"extensions\": [\"jsonml\"]\n  },\n  \"application/jwk+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/jwk-set+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/jwt\": {\n    \"source\": \"iana\"\n  },\n  \"application/kpml-request+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/kpml-response+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/ld+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"jsonld\"]\n  },\n  \"application/link-format\": {\n    \"source\": \"iana\"\n  },\n  \"application/load-control+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/lost+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"lostxml\"]\n  },\n  \"application/lostsync+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/lxf\": {\n    \"source\": \"iana\"\n  },\n  \"application/mac-binhex40\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hqx\"]\n  },\n  \"application/mac-compactpro\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cpt\"]\n  },\n  \"application/macwriteii\": {\n    \"source\": \"iana\"\n  },\n  \"application/mads+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mads\"]\n  },\n  \"application/manifest+json\": {\n    \"charset\": \"UTF-8\",\n    \"compressible\": true,\n    \"extensions\": [\"webmanifest\"]\n  },\n  \"application/marc\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mrc\"]\n  },\n  \"application/marcxml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mrcx\"]\n  },\n  \"application/mathematica\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ma\",\"nb\",\"mb\"]\n  },\n  \"application/mathml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mathml\"]\n  },\n  \"application/mathml-content+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mathml-presentation+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-associated-procedure-description+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-deregister+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-envelope+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-msk+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-msk-response+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-protection-description+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-reception-report+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-register+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-register-response+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-schedule+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbms-user-service-description+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mbox\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mbox\"]\n  },\n  \"application/media-policy-dataset+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/media_control+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mediaservercontrol+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mscml\"]\n  },\n  \"application/merge-patch+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/metalink+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"metalink\"]\n  },\n  \"application/metalink4+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"meta4\"]\n  },\n  \"application/mets+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mets\"]\n  },\n  \"application/mf4\": {\n    \"source\": \"iana\"\n  },\n  \"application/mikey\": {\n    \"source\": \"iana\"\n  },\n  \"application/mods+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mods\"]\n  },\n  \"application/moss-keys\": {\n    \"source\": \"iana\"\n  },\n  \"application/moss-signature\": {\n    \"source\": \"iana\"\n  },\n  \"application/mosskey-data\": {\n    \"source\": \"iana\"\n  },\n  \"application/mosskey-request\": {\n    \"source\": \"iana\"\n  },\n  \"application/mp21\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"m21\",\"mp21\"]\n  },\n  \"application/mp4\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mp4s\",\"m4p\"]\n  },\n  \"application/mpeg4-generic\": {\n    \"source\": \"iana\"\n  },\n  \"application/mpeg4-iod\": {\n    \"source\": \"iana\"\n  },\n  \"application/mpeg4-iod-xmt\": {\n    \"source\": \"iana\"\n  },\n  \"application/mrb-consumer+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/mrb-publish+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/msc-ivr+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/msc-mixer+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/msword\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"doc\",\"dot\"]\n  },\n  \"application/mxf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mxf\"]\n  },\n  \"application/nasdata\": {\n    \"source\": \"iana\"\n  },\n  \"application/news-checkgroups\": {\n    \"source\": \"iana\"\n  },\n  \"application/news-groupinfo\": {\n    \"source\": \"iana\"\n  },\n  \"application/news-transmission\": {\n    \"source\": \"iana\"\n  },\n  \"application/nlsml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/nss\": {\n    \"source\": \"iana\"\n  },\n  \"application/ocsp-request\": {\n    \"source\": \"iana\"\n  },\n  \"application/ocsp-response\": {\n    \"source\": \"iana\"\n  },\n  \"application/octet-stream\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"bin\",\"dms\",\"lrf\",\"mar\",\"so\",\"dist\",\"distz\",\"pkg\",\"bpk\",\"dump\",\"elc\",\"deploy\",\"exe\",\"dll\",\"deb\",\"dmg\",\"iso\",\"img\",\"msi\",\"msp\",\"msm\",\"buffer\"]\n  },\n  \"application/oda\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"oda\"]\n  },\n  \"application/odx\": {\n    \"source\": \"iana\"\n  },\n  \"application/oebps-package+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"opf\"]\n  },\n  \"application/ogg\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"ogx\"]\n  },\n  \"application/omdoc+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"omdoc\"]\n  },\n  \"application/onenote\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"onetoc\",\"onetoc2\",\"onetmp\",\"onepkg\"]\n  },\n  \"application/oxps\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"oxps\"]\n  },\n  \"application/p2p-overlay+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/parityfec\": {\n    \"source\": \"iana\"\n  },\n  \"application/patch-ops-error+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xer\"]\n  },\n  \"application/pdf\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"pdf\"]\n  },\n  \"application/pdx\": {\n    \"source\": \"iana\"\n  },\n  \"application/pgp-encrypted\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"pgp\"]\n  },\n  \"application/pgp-keys\": {\n    \"source\": \"iana\"\n  },\n  \"application/pgp-signature\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"asc\",\"sig\"]\n  },\n  \"application/pics-rules\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"prf\"]\n  },\n  \"application/pidf+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/pidf-diff+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/pkcs10\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"p10\"]\n  },\n  \"application/pkcs12\": {\n    \"source\": \"iana\"\n  },\n  \"application/pkcs7-mime\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"p7m\",\"p7c\"]\n  },\n  \"application/pkcs7-signature\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"p7s\"]\n  },\n  \"application/pkcs8\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"p8\"]\n  },\n  \"application/pkix-attr-cert\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ac\"]\n  },\n  \"application/pkix-cert\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cer\"]\n  },\n  \"application/pkix-crl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"crl\"]\n  },\n  \"application/pkix-pkipath\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pkipath\"]\n  },\n  \"application/pkixcmp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pki\"]\n  },\n  \"application/pls+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pls\"]\n  },\n  \"application/poc-settings+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/postscript\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"ai\",\"eps\",\"ps\"]\n  },\n  \"application/provenance+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/prs.alvestrand.titrax-sheet\": {\n    \"source\": \"iana\"\n  },\n  \"application/prs.cww\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cww\"]\n  },\n  \"application/prs.hpub+zip\": {\n    \"source\": \"iana\"\n  },\n  \"application/prs.nprend\": {\n    \"source\": \"iana\"\n  },\n  \"application/prs.plucker\": {\n    \"source\": \"iana\"\n  },\n  \"application/prs.rdf-xml-crypt\": {\n    \"source\": \"iana\"\n  },\n  \"application/prs.xsf+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/pskc+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pskcxml\"]\n  },\n  \"application/qsig\": {\n    \"source\": \"iana\"\n  },\n  \"application/raptorfec\": {\n    \"source\": \"iana\"\n  },\n  \"application/rdap+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/rdf+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"rdf\"]\n  },\n  \"application/reginfo+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rif\"]\n  },\n  \"application/relax-ng-compact-syntax\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rnc\"]\n  },\n  \"application/remote-printing\": {\n    \"source\": \"iana\"\n  },\n  \"application/reputon+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/resource-lists+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rl\"]\n  },\n  \"application/resource-lists-diff+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rld\"]\n  },\n  \"application/rfc+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/riscos\": {\n    \"source\": \"iana\"\n  },\n  \"application/rlmi+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/rls-services+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rs\"]\n  },\n  \"application/rpki-ghostbusters\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gbr\"]\n  },\n  \"application/rpki-manifest\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mft\"]\n  },\n  \"application/rpki-roa\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"roa\"]\n  },\n  \"application/rpki-updown\": {\n    \"source\": \"iana\"\n  },\n  \"application/rsd+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"rsd\"]\n  },\n  \"application/rss+xml\": {\n    \"source\": \"apache\",\n    \"compressible\": true,\n    \"extensions\": [\"rss\"]\n  },\n  \"application/rtf\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"rtf\"]\n  },\n  \"application/rtploopback\": {\n    \"source\": \"iana\"\n  },\n  \"application/rtx\": {\n    \"source\": \"iana\"\n  },\n  \"application/samlassertion+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/samlmetadata+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/sbml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sbml\"]\n  },\n  \"application/scaip+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/scim+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/scvp-cv-request\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"scq\"]\n  },\n  \"application/scvp-cv-response\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"scs\"]\n  },\n  \"application/scvp-vp-request\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"spq\"]\n  },\n  \"application/scvp-vp-response\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"spp\"]\n  },\n  \"application/sdp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sdp\"]\n  },\n  \"application/sep+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/sep-exi\": {\n    \"source\": \"iana\"\n  },\n  \"application/session-info\": {\n    \"source\": \"iana\"\n  },\n  \"application/set-payment\": {\n    \"source\": \"iana\"\n  },\n  \"application/set-payment-initiation\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"setpay\"]\n  },\n  \"application/set-registration\": {\n    \"source\": \"iana\"\n  },\n  \"application/set-registration-initiation\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"setreg\"]\n  },\n  \"application/sgml\": {\n    \"source\": \"iana\"\n  },\n  \"application/sgml-open-catalog\": {\n    \"source\": \"iana\"\n  },\n  \"application/shf+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"shf\"]\n  },\n  \"application/sieve\": {\n    \"source\": \"iana\"\n  },\n  \"application/simple-filter+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/simple-message-summary\": {\n    \"source\": \"iana\"\n  },\n  \"application/simplesymbolcontainer\": {\n    \"source\": \"iana\"\n  },\n  \"application/slate\": {\n    \"source\": \"iana\"\n  },\n  \"application/smil\": {\n    \"source\": \"iana\"\n  },\n  \"application/smil+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"smi\",\"smil\"]\n  },\n  \"application/smpte336m\": {\n    \"source\": \"iana\"\n  },\n  \"application/soap+fastinfoset\": {\n    \"source\": \"iana\"\n  },\n  \"application/soap+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/sparql-query\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rq\"]\n  },\n  \"application/sparql-results+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"srx\"]\n  },\n  \"application/spirits-event+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/sql\": {\n    \"source\": \"iana\"\n  },\n  \"application/srgs\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gram\"]\n  },\n  \"application/srgs+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"grxml\"]\n  },\n  \"application/sru+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sru\"]\n  },\n  \"application/ssdl+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ssdl\"]\n  },\n  \"application/ssml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ssml\"]\n  },\n  \"application/tamp-apex-update\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-apex-update-confirm\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-community-update\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-community-update-confirm\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-error\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-sequence-adjust\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-sequence-adjust-confirm\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-status-query\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-status-response\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-update\": {\n    \"source\": \"iana\"\n  },\n  \"application/tamp-update-confirm\": {\n    \"source\": \"iana\"\n  },\n  \"application/tar\": {\n    \"compressible\": true\n  },\n  \"application/tei+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tei\",\"teicorpus\"]\n  },\n  \"application/thraud+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tfi\"]\n  },\n  \"application/timestamp-query\": {\n    \"source\": \"iana\"\n  },\n  \"application/timestamp-reply\": {\n    \"source\": \"iana\"\n  },\n  \"application/timestamped-data\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tsd\"]\n  },\n  \"application/ttml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/tve-trigger\": {\n    \"source\": \"iana\"\n  },\n  \"application/ulpfec\": {\n    \"source\": \"iana\"\n  },\n  \"application/urc-grpsheet+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/urc-ressheet+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/urc-targetdesc+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/urc-uisocketdesc+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vcard+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vcard+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vemmi\": {\n    \"source\": \"iana\"\n  },\n  \"application/vividence.scriptfile\": {\n    \"source\": \"apache\"\n  },\n  \"application/vnd.3gpp-prose+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp-prose-pc3ch+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp.access-transfer-events+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp.bsf+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp.mid-call+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp.pic-bw-large\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"plb\"]\n  },\n  \"application/vnd.3gpp.pic-bw-small\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"psb\"]\n  },\n  \"application/vnd.3gpp.pic-bw-var\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pvb\"]\n  },\n  \"application/vnd.3gpp.sms\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp.srvcc-ext+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp.srvcc-info+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp.state-and-event-info+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp.ussd+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp2.bcmcsinfo+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp2.sms\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.3gpp2.tcap\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tcap\"]\n  },\n  \"application/vnd.3m.post-it-notes\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pwn\"]\n  },\n  \"application/vnd.accpac.simply.aso\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"aso\"]\n  },\n  \"application/vnd.accpac.simply.imp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"imp\"]\n  },\n  \"application/vnd.acucobol\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"acu\"]\n  },\n  \"application/vnd.acucorp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"atc\",\"acutc\"]\n  },\n  \"application/vnd.adobe.air-application-installer-package+zip\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"air\"]\n  },\n  \"application/vnd.adobe.flash.movie\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.adobe.formscentral.fcdt\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fcdt\"]\n  },\n  \"application/vnd.adobe.fxp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fxp\",\"fxpl\"]\n  },\n  \"application/vnd.adobe.partial-upload\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.adobe.xdp+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xdp\"]\n  },\n  \"application/vnd.adobe.xfdf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xfdf\"]\n  },\n  \"application/vnd.aether.imp\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ah-barcode\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ahead.space\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ahead\"]\n  },\n  \"application/vnd.airzip.filesecure.azf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"azf\"]\n  },\n  \"application/vnd.airzip.filesecure.azs\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"azs\"]\n  },\n  \"application/vnd.amazon.ebook\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"azw\"]\n  },\n  \"application/vnd.americandynamics.acc\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"acc\"]\n  },\n  \"application/vnd.amiga.ami\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ami\"]\n  },\n  \"application/vnd.amundsen.maze+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.android.package-archive\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"apk\"]\n  },\n  \"application/vnd.anki\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.anser-web-certificate-issue-initiation\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cii\"]\n  },\n  \"application/vnd.anser-web-funds-transfer-initiation\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"fti\"]\n  },\n  \"application/vnd.antix.game-component\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"atx\"]\n  },\n  \"application/vnd.apache.thrift.binary\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.apache.thrift.compact\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.apache.thrift.json\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.api+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.apple.installer+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mpkg\"]\n  },\n  \"application/vnd.apple.mpegurl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"m3u8\"]\n  },\n  \"application/vnd.apple.pkpass\": {\n    \"compressible\": false,\n    \"extensions\": [\"pkpass\"]\n  },\n  \"application/vnd.arastra.swi\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.aristanetworks.swi\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"swi\"]\n  },\n  \"application/vnd.artsquare\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.astraea-software.iota\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"iota\"]\n  },\n  \"application/vnd.audiograph\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"aep\"]\n  },\n  \"application/vnd.autopackage\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.avistar+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.balsamiq.bmml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.balsamiq.bmpr\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.bekitzur-stech+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.biopax.rdf+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.blueice.multipass\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mpm\"]\n  },\n  \"application/vnd.bluetooth.ep.oob\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.bluetooth.le.oob\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.bmi\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"bmi\"]\n  },\n  \"application/vnd.businessobjects\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rep\"]\n  },\n  \"application/vnd.cab-jscript\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.canon-cpdl\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.canon-lips\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.cendio.thinlinc.clientconf\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.century-systems.tcp_stream\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.chemdraw+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdxml\"]\n  },\n  \"application/vnd.chipnuts.karaoke-mmd\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mmd\"]\n  },\n  \"application/vnd.cinderella\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdy\"]\n  },\n  \"application/vnd.cirpack.isdn-ext\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.citationstyles.style+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.claymore\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cla\"]\n  },\n  \"application/vnd.cloanto.rp9\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rp9\"]\n  },\n  \"application/vnd.clonk.c4group\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"c4g\",\"c4d\",\"c4f\",\"c4p\",\"c4u\"]\n  },\n  \"application/vnd.cluetrust.cartomobile-config\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"c11amc\"]\n  },\n  \"application/vnd.cluetrust.cartomobile-config-pkg\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"c11amz\"]\n  },\n  \"application/vnd.coffeescript\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.collection+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.collection.doc+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.collection.next+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.commerce-battelle\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.commonspace\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"csp\"]\n  },\n  \"application/vnd.contact.cmsg\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdbcmsg\"]\n  },\n  \"application/vnd.cosmocaller\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cmc\"]\n  },\n  \"application/vnd.crick.clicker\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"clkx\"]\n  },\n  \"application/vnd.crick.clicker.keyboard\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"clkk\"]\n  },\n  \"application/vnd.crick.clicker.palette\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"clkp\"]\n  },\n  \"application/vnd.crick.clicker.template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"clkt\"]\n  },\n  \"application/vnd.crick.clicker.wordbank\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"clkw\"]\n  },\n  \"application/vnd.criticaltools.wbs+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wbs\"]\n  },\n  \"application/vnd.ctc-posml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pml\"]\n  },\n  \"application/vnd.ctct.ws+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.cups-pdf\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.cups-postscript\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.cups-ppd\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ppd\"]\n  },\n  \"application/vnd.cups-raster\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.cups-raw\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.curl\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.curl.car\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"car\"]\n  },\n  \"application/vnd.curl.pcurl\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pcurl\"]\n  },\n  \"application/vnd.cyan.dean.root+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.cybank\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dart\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"dart\"]\n  },\n  \"application/vnd.data-vision.rdz\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rdz\"]\n  },\n  \"application/vnd.debian.binary-package\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dece.data\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"uvf\",\"uvvf\",\"uvd\",\"uvvd\"]\n  },\n  \"application/vnd.dece.ttml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"uvt\",\"uvvt\"]\n  },\n  \"application/vnd.dece.unspecified\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"uvx\",\"uvvx\"]\n  },\n  \"application/vnd.dece.zip\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"uvz\",\"uvvz\"]\n  },\n  \"application/vnd.denovo.fcselayout-link\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fe_launch\"]\n  },\n  \"application/vnd.desmume-movie\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dir-bi.plate-dl-nosuffix\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dm.delegation+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dna\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dna\"]\n  },\n  \"application/vnd.document+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.dolby.mlp\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mlp\"]\n  },\n  \"application/vnd.dolby.mobile.1\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dolby.mobile.2\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.doremir.scorecloud-binary-document\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dpgraph\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dpg\"]\n  },\n  \"application/vnd.dreamfactory\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dfac\"]\n  },\n  \"application/vnd.drive+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.ds-keypoint\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"kpxx\"]\n  },\n  \"application/vnd.dtg.local\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dtg.local.flash\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dtg.local.html\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.ait\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ait\"]\n  },\n  \"application/vnd.dvb.dvbj\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.esgcontainer\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.ipdcdftnotifaccess\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.ipdcesgaccess\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.ipdcesgaccess2\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.ipdcesgpdd\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.ipdcroaming\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.iptv.alfec-base\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.iptv.alfec-enhancement\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.notif-aggregate-root+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.notif-container+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.notif-generic+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.notif-ia-msglist+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.notif-ia-registration-request+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.notif-ia-registration-response+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.notif-init+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.pfr\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dvb.service\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"svc\"]\n  },\n  \"application/vnd.dxr\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.dynageo\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"geo\"]\n  },\n  \"application/vnd.dzr\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.easykaraoke.cdgdownload\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ecdis-update\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ecowin.chart\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mag\"]\n  },\n  \"application/vnd.ecowin.filerequest\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ecowin.fileupdate\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ecowin.series\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ecowin.seriesrequest\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ecowin.seriesupdate\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.emclient.accessrequest+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.enliven\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"nml\"]\n  },\n  \"application/vnd.enphase.envoy\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.eprints.data+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.epson.esf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"esf\"]\n  },\n  \"application/vnd.epson.msf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"msf\"]\n  },\n  \"application/vnd.epson.quickanime\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"qam\"]\n  },\n  \"application/vnd.epson.salt\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"slt\"]\n  },\n  \"application/vnd.epson.ssf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ssf\"]\n  },\n  \"application/vnd.ericsson.quickcall\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.eszigno3+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"es3\",\"et3\"]\n  },\n  \"application/vnd.etsi.aoc+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.asic-e+zip\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.asic-s+zip\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.cug+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvcommand+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvdiscovery+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvprofile+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvsad-bc+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvsad-cod+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvsad-npvr+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvservice+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvsync+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.iptvueprofile+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.mcid+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.mheg5\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.overload-control-policy-dataset+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.pstn+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.sci+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.simservs+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.timestamp-token\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.tsl+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.etsi.tsl.der\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.eudora.data\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ezpix-album\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ez2\"]\n  },\n  \"application/vnd.ezpix-package\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ez3\"]\n  },\n  \"application/vnd.f-secure.mobile\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.fastcopy-disk-image\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.fdf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fdf\"]\n  },\n  \"application/vnd.fdsn.mseed\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mseed\"]\n  },\n  \"application/vnd.fdsn.seed\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"seed\",\"dataless\"]\n  },\n  \"application/vnd.ffsns\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.filmit.zfc\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.fints\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.firemonkeys.cloudcell\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.flographit\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gph\"]\n  },\n  \"application/vnd.fluxtime.clip\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ftc\"]\n  },\n  \"application/vnd.font-fontforge-sfd\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.framemaker\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fm\",\"frame\",\"maker\",\"book\"]\n  },\n  \"application/vnd.frogans.fnc\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fnc\"]\n  },\n  \"application/vnd.frogans.ltf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ltf\"]\n  },\n  \"application/vnd.fsc.weblaunch\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fsc\"]\n  },\n  \"application/vnd.fujitsu.oasys\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"oas\"]\n  },\n  \"application/vnd.fujitsu.oasys2\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"oa2\"]\n  },\n  \"application/vnd.fujitsu.oasys3\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"oa3\"]\n  },\n  \"application/vnd.fujitsu.oasysgp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fg5\"]\n  },\n  \"application/vnd.fujitsu.oasysprs\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"bh2\"]\n  },\n  \"application/vnd.fujixerox.art-ex\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.fujixerox.art4\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.fujixerox.ddd\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ddd\"]\n  },\n  \"application/vnd.fujixerox.docuworks\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xdw\"]\n  },\n  \"application/vnd.fujixerox.docuworks.binder\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xbd\"]\n  },\n  \"application/vnd.fujixerox.docuworks.container\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.fujixerox.hbpl\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.fut-misnet\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.fuzzysheet\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fzs\"]\n  },\n  \"application/vnd.genomatix.tuxedo\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"txd\"]\n  },\n  \"application/vnd.geo+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.geocube+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.geogebra.file\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ggb\"]\n  },\n  \"application/vnd.geogebra.tool\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ggt\"]\n  },\n  \"application/vnd.geometry-explorer\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gex\",\"gre\"]\n  },\n  \"application/vnd.geonext\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gxt\"]\n  },\n  \"application/vnd.geoplan\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"g2w\"]\n  },\n  \"application/vnd.geospace\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"g3w\"]\n  },\n  \"application/vnd.gerber\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.globalplatform.card-content-mgt\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.globalplatform.card-content-mgt-response\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.gmx\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gmx\"]\n  },\n  \"application/vnd.google-apps.document\": {\n    \"compressible\": false,\n    \"extensions\": [\"gdoc\"]\n  },\n  \"application/vnd.google-apps.presentation\": {\n    \"compressible\": false,\n    \"extensions\": [\"gslides\"]\n  },\n  \"application/vnd.google-apps.spreadsheet\": {\n    \"compressible\": false,\n    \"extensions\": [\"gsheet\"]\n  },\n  \"application/vnd.google-earth.kml+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"kml\"]\n  },\n  \"application/vnd.google-earth.kmz\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"kmz\"]\n  },\n  \"application/vnd.gov.sk.e-form+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.gov.sk.e-form+zip\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.gov.sk.xmldatacontainer+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.grafeq\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gqf\",\"gqs\"]\n  },\n  \"application/vnd.gridmp\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.groove-account\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gac\"]\n  },\n  \"application/vnd.groove-help\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ghf\"]\n  },\n  \"application/vnd.groove-identity-message\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gim\"]\n  },\n  \"application/vnd.groove-injector\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"grv\"]\n  },\n  \"application/vnd.groove-tool-message\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gtm\"]\n  },\n  \"application/vnd.groove-tool-template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tpl\"]\n  },\n  \"application/vnd.groove-vcard\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"vcg\"]\n  },\n  \"application/vnd.hal+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.hal+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hal\"]\n  },\n  \"application/vnd.handheld-entertainment+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"zmm\"]\n  },\n  \"application/vnd.hbci\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hbci\"]\n  },\n  \"application/vnd.hcl-bireports\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.heroku+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.hhe.lesson-player\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"les\"]\n  },\n  \"application/vnd.hp-hpgl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hpgl\"]\n  },\n  \"application/vnd.hp-hpid\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hpid\"]\n  },\n  \"application/vnd.hp-hps\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hps\"]\n  },\n  \"application/vnd.hp-jlyt\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"jlt\"]\n  },\n  \"application/vnd.hp-pcl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pcl\"]\n  },\n  \"application/vnd.hp-pclxl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pclxl\"]\n  },\n  \"application/vnd.httphone\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.hydrostatix.sof-data\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sfd-hdstx\"]\n  },\n  \"application/vnd.hyperdrive+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.hzn-3d-crossword\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ibm.afplinedata\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ibm.electronic-media\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ibm.minipay\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mpy\"]\n  },\n  \"application/vnd.ibm.modcap\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"afp\",\"listafp\",\"list3820\"]\n  },\n  \"application/vnd.ibm.rights-management\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"irm\"]\n  },\n  \"application/vnd.ibm.secure-container\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sc\"]\n  },\n  \"application/vnd.iccprofile\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"icc\",\"icm\"]\n  },\n  \"application/vnd.ieee.1905\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.igloader\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"igl\"]\n  },\n  \"application/vnd.immervision-ivp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ivp\"]\n  },\n  \"application/vnd.immervision-ivu\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ivu\"]\n  },\n  \"application/vnd.ims.imsccv1p1\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ims.imsccv1p2\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ims.imsccv1p3\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ims.lis.v2.result+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.ims.lti.v2.toolconsumerprofile+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.ims.lti.v2.toolproxy+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.ims.lti.v2.toolproxy.id+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.ims.lti.v2.toolsettings+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.ims.lti.v2.toolsettings.simple+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.informedcontrol.rms+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.informix-visionary\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.infotech.project\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.infotech.project+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.innopath.wamp.notification\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.insors.igm\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"igm\"]\n  },\n  \"application/vnd.intercon.formnet\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xpw\",\"xpx\"]\n  },\n  \"application/vnd.intergeo\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"i2g\"]\n  },\n  \"application/vnd.intertrust.digibox\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.intertrust.nncp\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.intu.qbo\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"qbo\"]\n  },\n  \"application/vnd.intu.qfx\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"qfx\"]\n  },\n  \"application/vnd.iptc.g2.catalogitem+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.iptc.g2.conceptitem+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.iptc.g2.knowledgeitem+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.iptc.g2.newsitem+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.iptc.g2.newsmessage+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.iptc.g2.packageitem+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.iptc.g2.planningitem+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ipunplugged.rcprofile\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rcprofile\"]\n  },\n  \"application/vnd.irepository.package+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"irp\"]\n  },\n  \"application/vnd.is-xpr\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xpr\"]\n  },\n  \"application/vnd.isac.fcs\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fcs\"]\n  },\n  \"application/vnd.jam\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"jam\"]\n  },\n  \"application/vnd.japannet-directory-service\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.japannet-jpnstore-wakeup\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.japannet-payment-wakeup\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.japannet-registration\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.japannet-registration-wakeup\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.japannet-setstore-wakeup\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.japannet-verification\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.japannet-verification-wakeup\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.jcp.javame.midlet-rms\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rms\"]\n  },\n  \"application/vnd.jisp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"jisp\"]\n  },\n  \"application/vnd.joost.joda-archive\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"joda\"]\n  },\n  \"application/vnd.jsk.isdn-ngn\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.kahootz\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ktz\",\"ktr\"]\n  },\n  \"application/vnd.kde.karbon\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"karbon\"]\n  },\n  \"application/vnd.kde.kchart\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"chrt\"]\n  },\n  \"application/vnd.kde.kformula\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"kfo\"]\n  },\n  \"application/vnd.kde.kivio\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"flw\"]\n  },\n  \"application/vnd.kde.kontour\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"kon\"]\n  },\n  \"application/vnd.kde.kpresenter\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"kpr\",\"kpt\"]\n  },\n  \"application/vnd.kde.kspread\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ksp\"]\n  },\n  \"application/vnd.kde.kword\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"kwd\",\"kwt\"]\n  },\n  \"application/vnd.kenameaapp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"htke\"]\n  },\n  \"application/vnd.kidspiration\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"kia\"]\n  },\n  \"application/vnd.kinar\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"kne\",\"knp\"]\n  },\n  \"application/vnd.koan\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"skp\",\"skd\",\"skt\",\"skm\"]\n  },\n  \"application/vnd.kodak-descriptor\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sse\"]\n  },\n  \"application/vnd.las.las+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"lasxml\"]\n  },\n  \"application/vnd.liberty-request+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.llamagraphics.life-balance.desktop\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"lbd\"]\n  },\n  \"application/vnd.llamagraphics.life-balance.exchange+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"lbe\"]\n  },\n  \"application/vnd.lotus-1-2-3\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"123\"]\n  },\n  \"application/vnd.lotus-approach\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"apr\"]\n  },\n  \"application/vnd.lotus-freelance\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pre\"]\n  },\n  \"application/vnd.lotus-notes\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"nsf\"]\n  },\n  \"application/vnd.lotus-organizer\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"org\"]\n  },\n  \"application/vnd.lotus-screencam\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"scm\"]\n  },\n  \"application/vnd.lotus-wordpro\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"lwp\"]\n  },\n  \"application/vnd.macports.portpkg\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"portpkg\"]\n  },\n  \"application/vnd.mapbox-vector-tile\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.marlin.drm.actiontoken+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.marlin.drm.conftoken+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.marlin.drm.license+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.marlin.drm.mdcf\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.mason+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.maxmind.maxmind-db\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.mcd\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mcd\"]\n  },\n  \"application/vnd.medcalcdata\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mc1\"]\n  },\n  \"application/vnd.mediastation.cdkey\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cdkey\"]\n  },\n  \"application/vnd.meridian-slingshot\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.mfer\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mwf\"]\n  },\n  \"application/vnd.mfmp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mfm\"]\n  },\n  \"application/vnd.micro+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.micrografx.flo\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"flo\"]\n  },\n  \"application/vnd.micrografx.igx\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"igx\"]\n  },\n  \"application/vnd.microsoft.portable-executable\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.miele+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.mif\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mif\"]\n  },\n  \"application/vnd.minisoft-hp3000-save\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.mitsubishi.misty-guard.trustweb\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.mobius.daf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"daf\"]\n  },\n  \"application/vnd.mobius.dis\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dis\"]\n  },\n  \"application/vnd.mobius.mbk\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mbk\"]\n  },\n  \"application/vnd.mobius.mqy\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mqy\"]\n  },\n  \"application/vnd.mobius.msl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"msl\"]\n  },\n  \"application/vnd.mobius.plc\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"plc\"]\n  },\n  \"application/vnd.mobius.txf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"txf\"]\n  },\n  \"application/vnd.mophun.application\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mpn\"]\n  },\n  \"application/vnd.mophun.certificate\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mpc\"]\n  },\n  \"application/vnd.motorola.flexsuite\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.motorola.flexsuite.adsi\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.motorola.flexsuite.fis\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.motorola.flexsuite.gotap\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.motorola.flexsuite.kmr\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.motorola.flexsuite.ttc\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.motorola.flexsuite.wem\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.motorola.iprm\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.mozilla.xul+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"xul\"]\n  },\n  \"application/vnd.ms-3mfdocument\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-artgalry\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cil\"]\n  },\n  \"application/vnd.ms-asf\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-cab-compressed\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cab\"]\n  },\n  \"application/vnd.ms-color.iccprofile\": {\n    \"source\": \"apache\"\n  },\n  \"application/vnd.ms-excel\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"xls\",\"xlm\",\"xla\",\"xlc\",\"xlt\",\"xlw\"]\n  },\n  \"application/vnd.ms-excel.addin.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xlam\"]\n  },\n  \"application/vnd.ms-excel.sheet.binary.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xlsb\"]\n  },\n  \"application/vnd.ms-excel.sheet.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xlsm\"]\n  },\n  \"application/vnd.ms-excel.template.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xltm\"]\n  },\n  \"application/vnd.ms-fontobject\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"eot\"]\n  },\n  \"application/vnd.ms-htmlhelp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"chm\"]\n  },\n  \"application/vnd.ms-ims\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ims\"]\n  },\n  \"application/vnd.ms-lrm\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"lrm\"]\n  },\n  \"application/vnd.ms-office.activex+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-officetheme\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"thmx\"]\n  },\n  \"application/vnd.ms-opentype\": {\n    \"source\": \"apache\",\n    \"compressible\": true\n  },\n  \"application/vnd.ms-package.obfuscated-opentype\": {\n    \"source\": \"apache\"\n  },\n  \"application/vnd.ms-pki.seccat\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cat\"]\n  },\n  \"application/vnd.ms-pki.stl\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"stl\"]\n  },\n  \"application/vnd.ms-playready.initiator+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-powerpoint\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"ppt\",\"pps\",\"pot\"]\n  },\n  \"application/vnd.ms-powerpoint.addin.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ppam\"]\n  },\n  \"application/vnd.ms-powerpoint.presentation.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pptm\"]\n  },\n  \"application/vnd.ms-powerpoint.slide.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sldm\"]\n  },\n  \"application/vnd.ms-powerpoint.slideshow.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ppsm\"]\n  },\n  \"application/vnd.ms-powerpoint.template.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"potm\"]\n  },\n  \"application/vnd.ms-printdevicecapabilities+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-printing.printticket+xml\": {\n    \"source\": \"apache\"\n  },\n  \"application/vnd.ms-project\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mpp\",\"mpt\"]\n  },\n  \"application/vnd.ms-tnef\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-windows.devicepairing\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-windows.nwprinting.oob\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-windows.printerpairing\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-windows.wsd.oob\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-wmdrm.lic-chlg-req\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-wmdrm.lic-resp\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-wmdrm.meter-chlg-req\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-wmdrm.meter-resp\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ms-word.document.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"docm\"]\n  },\n  \"application/vnd.ms-word.template.macroenabled.12\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dotm\"]\n  },\n  \"application/vnd.ms-works\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wps\",\"wks\",\"wcm\",\"wdb\"]\n  },\n  \"application/vnd.ms-wpl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wpl\"]\n  },\n  \"application/vnd.ms-xpsdocument\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"xps\"]\n  },\n  \"application/vnd.msa-disk-image\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.mseq\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mseq\"]\n  },\n  \"application/vnd.msign\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.multiad.creator\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.multiad.creator.cif\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.music-niff\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.musician\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mus\"]\n  },\n  \"application/vnd.muvee.style\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"msty\"]\n  },\n  \"application/vnd.mynfc\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"taglet\"]\n  },\n  \"application/vnd.ncd.control\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ncd.reference\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nervana\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.netfpx\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.neurolanguage.nlu\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"nlu\"]\n  },\n  \"application/vnd.nintendo.nitro.rom\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nintendo.snes.rom\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nitf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ntf\",\"nitf\"]\n  },\n  \"application/vnd.noblenet-directory\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"nnd\"]\n  },\n  \"application/vnd.noblenet-sealer\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"nns\"]\n  },\n  \"application/vnd.noblenet-web\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"nnw\"]\n  },\n  \"application/vnd.nokia.catalogs\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.conml+wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.conml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.iptv.config+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.isds-radio-presets\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.landmark+wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.landmark+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.landmarkcollection+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.n-gage.ac+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.n-gage.data\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ngdat\"]\n  },\n  \"application/vnd.nokia.n-gage.symbian.install\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"n-gage\"]\n  },\n  \"application/vnd.nokia.ncd\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.pcd+wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.pcd+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.nokia.radio-preset\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rpst\"]\n  },\n  \"application/vnd.nokia.radio-presets\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rpss\"]\n  },\n  \"application/vnd.novadigm.edm\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"edm\"]\n  },\n  \"application/vnd.novadigm.edx\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"edx\"]\n  },\n  \"application/vnd.novadigm.ext\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ext\"]\n  },\n  \"application/vnd.ntt-local.content-share\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ntt-local.file-transfer\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ntt-local.ogw_remote-access\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ntt-local.sip-ta_remote\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ntt-local.sip-ta_tcp_stream\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oasis.opendocument.chart\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"odc\"]\n  },\n  \"application/vnd.oasis.opendocument.chart-template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"otc\"]\n  },\n  \"application/vnd.oasis.opendocument.database\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"odb\"]\n  },\n  \"application/vnd.oasis.opendocument.formula\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"odf\"]\n  },\n  \"application/vnd.oasis.opendocument.formula-template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"odft\"]\n  },\n  \"application/vnd.oasis.opendocument.graphics\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"odg\"]\n  },\n  \"application/vnd.oasis.opendocument.graphics-template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"otg\"]\n  },\n  \"application/vnd.oasis.opendocument.image\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"odi\"]\n  },\n  \"application/vnd.oasis.opendocument.image-template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"oti\"]\n  },\n  \"application/vnd.oasis.opendocument.presentation\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"odp\"]\n  },\n  \"application/vnd.oasis.opendocument.presentation-template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"otp\"]\n  },\n  \"application/vnd.oasis.opendocument.spreadsheet\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"ods\"]\n  },\n  \"application/vnd.oasis.opendocument.spreadsheet-template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ots\"]\n  },\n  \"application/vnd.oasis.opendocument.text\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"odt\"]\n  },\n  \"application/vnd.oasis.opendocument.text-master\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"odm\"]\n  },\n  \"application/vnd.oasis.opendocument.text-template\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ott\"]\n  },\n  \"application/vnd.oasis.opendocument.text-web\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"oth\"]\n  },\n  \"application/vnd.obn\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oftn.l10n+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.oipf.contentaccessdownload+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.contentaccessstreaming+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.cspg-hexbinary\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.dae.svg+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.dae.xhtml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.mippvcontrolmessage+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.pae.gem\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.spdiscovery+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.spdlist+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.ueprofile+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oipf.userprofile+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.olpc-sugar\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xo\"]\n  },\n  \"application/vnd.oma-scws-config\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma-scws-http-request\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma-scws-http-response\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.associated-procedure-parameter+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.drm-trigger+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.imd+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.ltkm\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.notification+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.provisioningtrigger\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.sgboot\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.sgdd+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.sgdu\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.simple-symbol-container\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.smartcard-trigger+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.sprov+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.bcast.stkm\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.cab-address-book+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.cab-feature-handler+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.cab-pcc+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.cab-subs-invite+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.cab-user-prefs+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.dcd\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.dcdc\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.dd2+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dd2\"]\n  },\n  \"application/vnd.oma.drm.risd+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.group-usage-list+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.pal+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.poc.detailed-progress-report+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.poc.final-report+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.poc.groups+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.poc.invocation-descriptor+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.poc.optimized-progress-report+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.push\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.scidm.messages+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oma.xcap-directory+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.omads-email+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.omads-file+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.omads-folder+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.omaloc-supl-init\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openblox.game+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openblox.game-binary\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openeye.oeb\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openofficeorg.extension\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"oxt\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.custom-properties+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.customxmlproperties+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.drawing+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.drawingml.chart+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.extended-properties+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml-template\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.comments+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.presentation\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"pptx\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.presprops+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.slide\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sldx\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.slide+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.slideshow\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ppsx\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.tags+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.template\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"potx\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml-template\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"xlsx\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.template\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xltx\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.theme+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.themeoverride+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.vmldrawing\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml-template\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"docx\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.template\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"dotx\"]\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-package.core-properties+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.openxmlformats-package.relationships+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oracle.resource+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.orange.indata\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.osa.netdeploy\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.osgeo.mapguide.package\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mgp\"]\n  },\n  \"application/vnd.osgi.bundle\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.osgi.dp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dp\"]\n  },\n  \"application/vnd.osgi.subsystem\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"esa\"]\n  },\n  \"application/vnd.otps.ct-kip+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.oxli.countgraph\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.pagerduty+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.palm\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pdb\",\"pqa\",\"oprc\"]\n  },\n  \"application/vnd.panoply\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.paos+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.paos.xml\": {\n    \"source\": \"apache\"\n  },\n  \"application/vnd.pawaafile\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"paw\"]\n  },\n  \"application/vnd.pcos\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.pg.format\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"str\"]\n  },\n  \"application/vnd.pg.osasli\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ei6\"]\n  },\n  \"application/vnd.piaccess.application-licence\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.picsel\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"efif\"]\n  },\n  \"application/vnd.pmi.widget\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wg\"]\n  },\n  \"application/vnd.poc.group-advertisement+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.pocketlearn\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"plf\"]\n  },\n  \"application/vnd.powerbuilder6\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pbd\"]\n  },\n  \"application/vnd.powerbuilder6-s\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.powerbuilder7\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.powerbuilder7-s\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.powerbuilder75\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.powerbuilder75-s\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.preminet\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.previewsystems.box\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"box\"]\n  },\n  \"application/vnd.proteus.magazine\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mgz\"]\n  },\n  \"application/vnd.publishare-delta-tree\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"qps\"]\n  },\n  \"application/vnd.pvi.ptid1\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ptid\"]\n  },\n  \"application/vnd.pwg-multiplexed\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.pwg-xhtml-print+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.qualcomm.brew-app-res\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.quark.quarkxpress\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"qxd\",\"qxt\",\"qwd\",\"qwt\",\"qxl\",\"qxb\"]\n  },\n  \"application/vnd.quobject-quoxdocument\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.moml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-audit+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-audit-conf+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-audit-conn+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-audit-dialog+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-audit-stream+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-conf+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-dialog+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-dialog-base+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-dialog-fax-detect+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-dialog-fax-sendrecv+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-dialog-group+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-dialog-speech+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.radisys.msml-dialog-transform+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.rainstor.data\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.rapid\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.realvnc.bed\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"bed\"]\n  },\n  \"application/vnd.recordare.musicxml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mxl\"]\n  },\n  \"application/vnd.recordare.musicxml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"musicxml\"]\n  },\n  \"application/vnd.renlearn.rlprint\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.rig.cryptonote\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cryptonote\"]\n  },\n  \"application/vnd.rim.cod\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cod\"]\n  },\n  \"application/vnd.rn-realmedia\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"rm\"]\n  },\n  \"application/vnd.rn-realmedia-vbr\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"rmvb\"]\n  },\n  \"application/vnd.route66.link66+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"link66\"]\n  },\n  \"application/vnd.rs-274x\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ruckus.download\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.s3sms\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sailingtracker.track\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"st\"]\n  },\n  \"application/vnd.sbm.cid\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sbm.mid2\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.scribus\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.3df\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.csf\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.doc\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.eml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.mht\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.net\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.ppt\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.tiff\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealed.xls\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealedmedia.softseal.html\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sealedmedia.softseal.pdf\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.seemail\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"see\"]\n  },\n  \"application/vnd.sema\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sema\"]\n  },\n  \"application/vnd.semd\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"semd\"]\n  },\n  \"application/vnd.semf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"semf\"]\n  },\n  \"application/vnd.shana.informed.formdata\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ifm\"]\n  },\n  \"application/vnd.shana.informed.formtemplate\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"itp\"]\n  },\n  \"application/vnd.shana.informed.interchange\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"iif\"]\n  },\n  \"application/vnd.shana.informed.package\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ipk\"]\n  },\n  \"application/vnd.simtech-mindmapper\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"twd\",\"twds\"]\n  },\n  \"application/vnd.siren+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.smaf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mmf\"]\n  },\n  \"application/vnd.smart.notebook\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.smart.teacher\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"teacher\"]\n  },\n  \"application/vnd.software602.filler.form+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.software602.filler.form-xml-zip\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.solent.sdkm+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sdkm\",\"sdkd\"]\n  },\n  \"application/vnd.spotfire.dxp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dxp\"]\n  },\n  \"application/vnd.spotfire.sfs\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sfs\"]\n  },\n  \"application/vnd.sss-cod\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sss-dtf\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sss-ntf\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.stardivision.calc\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sdc\"]\n  },\n  \"application/vnd.stardivision.draw\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sda\"]\n  },\n  \"application/vnd.stardivision.impress\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sdd\"]\n  },\n  \"application/vnd.stardivision.math\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"smf\"]\n  },\n  \"application/vnd.stardivision.writer\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sdw\",\"vor\"]\n  },\n  \"application/vnd.stardivision.writer-global\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sgl\"]\n  },\n  \"application/vnd.stepmania.package\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"smzip\"]\n  },\n  \"application/vnd.stepmania.stepchart\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sm\"]\n  },\n  \"application/vnd.street-stream\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sun.wadl+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.sun.xml.calc\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sxc\"]\n  },\n  \"application/vnd.sun.xml.calc.template\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"stc\"]\n  },\n  \"application/vnd.sun.xml.draw\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sxd\"]\n  },\n  \"application/vnd.sun.xml.draw.template\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"std\"]\n  },\n  \"application/vnd.sun.xml.impress\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sxi\"]\n  },\n  \"application/vnd.sun.xml.impress.template\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sti\"]\n  },\n  \"application/vnd.sun.xml.math\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sxm\"]\n  },\n  \"application/vnd.sun.xml.writer\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sxw\"]\n  },\n  \"application/vnd.sun.xml.writer.global\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sxg\"]\n  },\n  \"application/vnd.sun.xml.writer.template\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"stw\"]\n  },\n  \"application/vnd.sus-calendar\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sus\",\"susp\"]\n  },\n  \"application/vnd.svd\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"svd\"]\n  },\n  \"application/vnd.swiftview-ics\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.symbian.install\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sis\",\"sisx\"]\n  },\n  \"application/vnd.syncml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xsm\"]\n  },\n  \"application/vnd.syncml.dm+wbxml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"bdm\"]\n  },\n  \"application/vnd.syncml.dm+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xdm\"]\n  },\n  \"application/vnd.syncml.dm.notification\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.syncml.dmddf+wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.syncml.dmddf+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.syncml.dmtnds+wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.syncml.dmtnds+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.syncml.ds.notification\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.tao.intent-module-archive\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tao\"]\n  },\n  \"application/vnd.tcpdump.pcap\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pcap\",\"cap\",\"dmp\"]\n  },\n  \"application/vnd.tmd.mediaflex.api+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.tml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.tmobile-livetv\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tmo\"]\n  },\n  \"application/vnd.trid.tpt\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tpt\"]\n  },\n  \"application/vnd.triscape.mxs\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mxs\"]\n  },\n  \"application/vnd.trueapp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"tra\"]\n  },\n  \"application/vnd.truedoc\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ubisoft.webplayer\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.ufdl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ufd\",\"ufdl\"]\n  },\n  \"application/vnd.uiq.theme\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"utz\"]\n  },\n  \"application/vnd.umajin\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"umj\"]\n  },\n  \"application/vnd.unity\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"unityweb\"]\n  },\n  \"application/vnd.uoml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"uoml\"]\n  },\n  \"application/vnd.uplanet.alert\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.alert-wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.bearer-choice\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.bearer-choice-wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.cacheop\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.cacheop-wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.channel\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.channel-wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.list\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.list-wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.listcmd\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.listcmd-wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uplanet.signal\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.uri-map\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.valve.source.material\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.vcx\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"vcx\"]\n  },\n  \"application/vnd.vd-study\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.vectorworks\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.verimatrix.vcas\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.vidsoft.vidconference\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.visio\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"vsd\",\"vst\",\"vss\",\"vsw\"]\n  },\n  \"application/vnd.visionary\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"vis\"]\n  },\n  \"application/vnd.vividence.scriptfile\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.vsf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"vsf\"]\n  },\n  \"application/vnd.wap.sic\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wap.slc\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wap.wbxml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wbxml\"]\n  },\n  \"application/vnd.wap.wmlc\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wmlc\"]\n  },\n  \"application/vnd.wap.wmlscriptc\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wmlsc\"]\n  },\n  \"application/vnd.webturbo\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wtb\"]\n  },\n  \"application/vnd.wfa.p2p\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wfa.wsc\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.windows.devicepairing\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wmc\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wmf.bootstrap\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wolfram.mathematica\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wolfram.mathematica.package\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wolfram.player\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"nbp\"]\n  },\n  \"application/vnd.wordperfect\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wpd\"]\n  },\n  \"application/vnd.wqd\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wqd\"]\n  },\n  \"application/vnd.wrq-hp3000-labelled\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wt.stf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"stf\"]\n  },\n  \"application/vnd.wv.csp+wbxml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wv.csp+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.wv.ssp+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.xacml+json\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/vnd.xara\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xar\"]\n  },\n  \"application/vnd.xfdl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xfdl\"]\n  },\n  \"application/vnd.xfdl.webform\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.xmi+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.xmpie.cpkg\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.xmpie.dpkg\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.xmpie.plan\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.xmpie.ppkg\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.xmpie.xlim\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.yamaha.hv-dic\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hvd\"]\n  },\n  \"application/vnd.yamaha.hv-script\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hvs\"]\n  },\n  \"application/vnd.yamaha.hv-voice\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"hvp\"]\n  },\n  \"application/vnd.yamaha.openscoreformat\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"osf\"]\n  },\n  \"application/vnd.yamaha.openscoreformat.osfpvg+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"osfpvg\"]\n  },\n  \"application/vnd.yamaha.remote-setup\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.yamaha.smaf-audio\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"saf\"]\n  },\n  \"application/vnd.yamaha.smaf-phrase\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"spf\"]\n  },\n  \"application/vnd.yamaha.through-ngn\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.yamaha.tunnel-udpencap\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.yaoweme\": {\n    \"source\": \"iana\"\n  },\n  \"application/vnd.yellowriver-custom-menu\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cmp\"]\n  },\n  \"application/vnd.zul\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"zir\",\"zirz\"]\n  },\n  \"application/vnd.zzazz.deck+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"zaz\"]\n  },\n  \"application/voicexml+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"vxml\"]\n  },\n  \"application/vq-rtcpxr\": {\n    \"source\": \"iana\"\n  },\n  \"application/watcherinfo+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/whoispp-query\": {\n    \"source\": \"iana\"\n  },\n  \"application/whoispp-response\": {\n    \"source\": \"iana\"\n  },\n  \"application/widget\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wgt\"]\n  },\n  \"application/winhlp\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"hlp\"]\n  },\n  \"application/wita\": {\n    \"source\": \"iana\"\n  },\n  \"application/wordperfect5.1\": {\n    \"source\": \"iana\"\n  },\n  \"application/wsdl+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wsdl\"]\n  },\n  \"application/wspolicy+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wspolicy\"]\n  },\n  \"application/x-7z-compressed\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"7z\"]\n  },\n  \"application/x-abiword\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"abw\"]\n  },\n  \"application/x-ace-compressed\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ace\"]\n  },\n  \"application/x-amf\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-apple-diskimage\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"dmg\"]\n  },\n  \"application/x-authorware-bin\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"aab\",\"x32\",\"u32\",\"vox\"]\n  },\n  \"application/x-authorware-map\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"aam\"]\n  },\n  \"application/x-authorware-seg\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"aas\"]\n  },\n  \"application/x-bcpio\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"bcpio\"]\n  },\n  \"application/x-bdoc\": {\n    \"compressible\": false,\n    \"extensions\": [\"bdoc\"]\n  },\n  \"application/x-bittorrent\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"torrent\"]\n  },\n  \"application/x-blorb\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"blb\",\"blorb\"]\n  },\n  \"application/x-bzip\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"bz\"]\n  },\n  \"application/x-bzip2\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"bz2\",\"boz\"]\n  },\n  \"application/x-cbr\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cbr\",\"cba\",\"cbt\",\"cbz\",\"cb7\"]\n  },\n  \"application/x-cdlink\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"vcd\"]\n  },\n  \"application/x-cfs-compressed\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cfs\"]\n  },\n  \"application/x-chat\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"chat\"]\n  },\n  \"application/x-chess-pgn\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pgn\"]\n  },\n  \"application/x-chrome-extension\": {\n    \"extensions\": [\"crx\"]\n  },\n  \"application/x-cocoa\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"cco\"]\n  },\n  \"application/x-compress\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-conference\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"nsc\"]\n  },\n  \"application/x-cpio\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cpio\"]\n  },\n  \"application/x-csh\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"csh\"]\n  },\n  \"application/x-deb\": {\n    \"compressible\": false\n  },\n  \"application/x-debian-package\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"deb\",\"udeb\"]\n  },\n  \"application/x-dgc-compressed\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"dgc\"]\n  },\n  \"application/x-director\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"dir\",\"dcr\",\"dxr\",\"cst\",\"cct\",\"cxt\",\"w3d\",\"fgd\",\"swa\"]\n  },\n  \"application/x-doom\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wad\"]\n  },\n  \"application/x-dtbncx+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ncx\"]\n  },\n  \"application/x-dtbook+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"dtb\"]\n  },\n  \"application/x-dtbresource+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"res\"]\n  },\n  \"application/x-dvi\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"dvi\"]\n  },\n  \"application/x-envoy\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"evy\"]\n  },\n  \"application/x-eva\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"eva\"]\n  },\n  \"application/x-font-bdf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"bdf\"]\n  },\n  \"application/x-font-dos\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-font-framemaker\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-font-ghostscript\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gsf\"]\n  },\n  \"application/x-font-libgrx\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-font-linux-psf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"psf\"]\n  },\n  \"application/x-font-otf\": {\n    \"source\": \"apache\",\n    \"compressible\": true,\n    \"extensions\": [\"otf\"]\n  },\n  \"application/x-font-pcf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pcf\"]\n  },\n  \"application/x-font-snf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"snf\"]\n  },\n  \"application/x-font-speedo\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-font-sunos-news\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-font-ttf\": {\n    \"source\": \"apache\",\n    \"compressible\": true,\n    \"extensions\": [\"ttf\",\"ttc\"]\n  },\n  \"application/x-font-type1\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pfa\",\"pfb\",\"pfm\",\"afm\"]\n  },\n  \"application/x-font-vfont\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-freearc\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"arc\"]\n  },\n  \"application/x-futuresplash\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"spl\"]\n  },\n  \"application/x-gca-compressed\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gca\"]\n  },\n  \"application/x-glulx\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ulx\"]\n  },\n  \"application/x-gnumeric\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gnumeric\"]\n  },\n  \"application/x-gramps-xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gramps\"]\n  },\n  \"application/x-gtar\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gtar\"]\n  },\n  \"application/x-gzip\": {\n    \"source\": \"apache\"\n  },\n  \"application/x-hdf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"hdf\"]\n  },\n  \"application/x-httpd-php\": {\n    \"compressible\": true,\n    \"extensions\": [\"php\"]\n  },\n  \"application/x-install-instructions\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"install\"]\n  },\n  \"application/x-iso9660-image\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"iso\"]\n  },\n  \"application/x-java-archive-diff\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"jardiff\"]\n  },\n  \"application/x-java-jnlp-file\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"jnlp\"]\n  },\n  \"application/x-javascript\": {\n    \"compressible\": true\n  },\n  \"application/x-latex\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"latex\"]\n  },\n  \"application/x-lua-bytecode\": {\n    \"extensions\": [\"luac\"]\n  },\n  \"application/x-lzh-compressed\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"lzh\",\"lha\"]\n  },\n  \"application/x-makeself\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"run\"]\n  },\n  \"application/x-mie\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mie\"]\n  },\n  \"application/x-mobipocket-ebook\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"prc\",\"mobi\"]\n  },\n  \"application/x-mpegurl\": {\n    \"compressible\": false\n  },\n  \"application/x-ms-application\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"application\"]\n  },\n  \"application/x-ms-shortcut\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"lnk\"]\n  },\n  \"application/x-ms-wmd\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wmd\"]\n  },\n  \"application/x-ms-wmz\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wmz\"]\n  },\n  \"application/x-ms-xbap\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xbap\"]\n  },\n  \"application/x-msaccess\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mdb\"]\n  },\n  \"application/x-msbinder\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"obd\"]\n  },\n  \"application/x-mscardfile\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"crd\"]\n  },\n  \"application/x-msclip\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"clp\"]\n  },\n  \"application/x-msdos-program\": {\n    \"extensions\": [\"exe\"]\n  },\n  \"application/x-msdownload\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"exe\",\"dll\",\"com\",\"bat\",\"msi\"]\n  },\n  \"application/x-msmediaview\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mvb\",\"m13\",\"m14\"]\n  },\n  \"application/x-msmetafile\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wmf\",\"wmz\",\"emf\",\"emz\"]\n  },\n  \"application/x-msmoney\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mny\"]\n  },\n  \"application/x-mspublisher\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pub\"]\n  },\n  \"application/x-msschedule\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"scd\"]\n  },\n  \"application/x-msterminal\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"trm\"]\n  },\n  \"application/x-mswrite\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wri\"]\n  },\n  \"application/x-netcdf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"nc\",\"cdf\"]\n  },\n  \"application/x-ns-proxy-autoconfig\": {\n    \"compressible\": true,\n    \"extensions\": [\"pac\"]\n  },\n  \"application/x-nzb\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"nzb\"]\n  },\n  \"application/x-perl\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"pl\",\"pm\"]\n  },\n  \"application/x-pilot\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"prc\",\"pdb\"]\n  },\n  \"application/x-pkcs12\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"p12\",\"pfx\"]\n  },\n  \"application/x-pkcs7-certificates\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"p7b\",\"spc\"]\n  },\n  \"application/x-pkcs7-certreqresp\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"p7r\"]\n  },\n  \"application/x-rar-compressed\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"rar\"]\n  },\n  \"application/x-redhat-package-manager\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"rpm\"]\n  },\n  \"application/x-research-info-systems\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ris\"]\n  },\n  \"application/x-sea\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"sea\"]\n  },\n  \"application/x-sh\": {\n    \"source\": \"apache\",\n    \"compressible\": true,\n    \"extensions\": [\"sh\"]\n  },\n  \"application/x-shar\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"shar\"]\n  },\n  \"application/x-shockwave-flash\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"swf\"]\n  },\n  \"application/x-silverlight-app\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xap\"]\n  },\n  \"application/x-sql\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sql\"]\n  },\n  \"application/x-stuffit\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"sit\"]\n  },\n  \"application/x-stuffitx\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sitx\"]\n  },\n  \"application/x-subrip\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"srt\"]\n  },\n  \"application/x-sv4cpio\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sv4cpio\"]\n  },\n  \"application/x-sv4crc\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sv4crc\"]\n  },\n  \"application/x-t3vm-image\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"t3\"]\n  },\n  \"application/x-tads\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"gam\"]\n  },\n  \"application/x-tar\": {\n    \"source\": \"apache\",\n    \"compressible\": true,\n    \"extensions\": [\"tar\"]\n  },\n  \"application/x-tcl\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"tcl\",\"tk\"]\n  },\n  \"application/x-tex\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"tex\"]\n  },\n  \"application/x-tex-tfm\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"tfm\"]\n  },\n  \"application/x-texinfo\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"texinfo\",\"texi\"]\n  },\n  \"application/x-tgif\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"obj\"]\n  },\n  \"application/x-ustar\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ustar\"]\n  },\n  \"application/x-wais-source\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"src\"]\n  },\n  \"application/x-web-app-manifest+json\": {\n    \"compressible\": true,\n    \"extensions\": [\"webapp\"]\n  },\n  \"application/x-www-form-urlencoded\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"application/x-x509-ca-cert\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"der\",\"crt\",\"pem\"]\n  },\n  \"application/x-xfig\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"fig\"]\n  },\n  \"application/x-xliff+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xlf\"]\n  },\n  \"application/x-xpinstall\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"xpi\"]\n  },\n  \"application/x-xz\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xz\"]\n  },\n  \"application/x-zmachine\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"z1\",\"z2\",\"z3\",\"z4\",\"z5\",\"z6\",\"z7\",\"z8\"]\n  },\n  \"application/x400-bp\": {\n    \"source\": \"iana\"\n  },\n  \"application/xacml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xaml+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xaml\"]\n  },\n  \"application/xcap-att+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xcap-caps+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xcap-diff+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xdf\"]\n  },\n  \"application/xcap-el+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xcap-error+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xcap-ns+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xcon-conference-info+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xcon-conference-info-diff+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xenc+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xenc\"]\n  },\n  \"application/xhtml+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"xhtml\",\"xht\"]\n  },\n  \"application/xhtml-voice+xml\": {\n    \"source\": \"apache\"\n  },\n  \"application/xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"xml\",\"xsl\",\"xsd\"]\n  },\n  \"application/xml-dtd\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"dtd\"]\n  },\n  \"application/xml-external-parsed-entity\": {\n    \"source\": \"iana\"\n  },\n  \"application/xml-patch+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xmpp+xml\": {\n    \"source\": \"iana\"\n  },\n  \"application/xop+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"xop\"]\n  },\n  \"application/xproc+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xpl\"]\n  },\n  \"application/xslt+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xslt\"]\n  },\n  \"application/xspf+xml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xspf\"]\n  },\n  \"application/xv+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mxml\",\"xhvml\",\"xvml\",\"xvm\"]\n  },\n  \"application/yang\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"yang\"]\n  },\n  \"application/yin+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"yin\"]\n  },\n  \"application/zip\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"zip\"]\n  },\n  \"application/zlib\": {\n    \"source\": \"iana\"\n  },\n  \"audio/1d-interleaved-parityfec\": {\n    \"source\": \"iana\"\n  },\n  \"audio/32kadpcm\": {\n    \"source\": \"iana\"\n  },\n  \"audio/3gpp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/3gpp2\": {\n    \"source\": \"iana\"\n  },\n  \"audio/ac3\": {\n    \"source\": \"iana\"\n  },\n  \"audio/adpcm\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"adp\"]\n  },\n  \"audio/amr\": {\n    \"source\": \"iana\"\n  },\n  \"audio/amr-wb\": {\n    \"source\": \"iana\"\n  },\n  \"audio/amr-wb+\": {\n    \"source\": \"iana\"\n  },\n  \"audio/aptx\": {\n    \"source\": \"iana\"\n  },\n  \"audio/asc\": {\n    \"source\": \"iana\"\n  },\n  \"audio/atrac-advanced-lossless\": {\n    \"source\": \"iana\"\n  },\n  \"audio/atrac-x\": {\n    \"source\": \"iana\"\n  },\n  \"audio/atrac3\": {\n    \"source\": \"iana\"\n  },\n  \"audio/basic\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"au\",\"snd\"]\n  },\n  \"audio/bv16\": {\n    \"source\": \"iana\"\n  },\n  \"audio/bv32\": {\n    \"source\": \"iana\"\n  },\n  \"audio/clearmode\": {\n    \"source\": \"iana\"\n  },\n  \"audio/cn\": {\n    \"source\": \"iana\"\n  },\n  \"audio/dat12\": {\n    \"source\": \"iana\"\n  },\n  \"audio/dls\": {\n    \"source\": \"iana\"\n  },\n  \"audio/dsr-es201108\": {\n    \"source\": \"iana\"\n  },\n  \"audio/dsr-es202050\": {\n    \"source\": \"iana\"\n  },\n  \"audio/dsr-es202211\": {\n    \"source\": \"iana\"\n  },\n  \"audio/dsr-es202212\": {\n    \"source\": \"iana\"\n  },\n  \"audio/dv\": {\n    \"source\": \"iana\"\n  },\n  \"audio/dvi4\": {\n    \"source\": \"iana\"\n  },\n  \"audio/eac3\": {\n    \"source\": \"iana\"\n  },\n  \"audio/encaprtp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrc\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrc-qcp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrc0\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrc1\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcb\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcb0\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcb1\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcnw\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcnw0\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcnw1\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcwb\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcwb0\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evrcwb1\": {\n    \"source\": \"iana\"\n  },\n  \"audio/evs\": {\n    \"source\": \"iana\"\n  },\n  \"audio/fwdred\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g711-0\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g719\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g722\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g7221\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g723\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g726-16\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g726-24\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g726-32\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g726-40\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g728\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g729\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g7291\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g729d\": {\n    \"source\": \"iana\"\n  },\n  \"audio/g729e\": {\n    \"source\": \"iana\"\n  },\n  \"audio/gsm\": {\n    \"source\": \"iana\"\n  },\n  \"audio/gsm-efr\": {\n    \"source\": \"iana\"\n  },\n  \"audio/gsm-hr-08\": {\n    \"source\": \"iana\"\n  },\n  \"audio/ilbc\": {\n    \"source\": \"iana\"\n  },\n  \"audio/ip-mr_v2.5\": {\n    \"source\": \"iana\"\n  },\n  \"audio/isac\": {\n    \"source\": \"apache\"\n  },\n  \"audio/l16\": {\n    \"source\": \"iana\"\n  },\n  \"audio/l20\": {\n    \"source\": \"iana\"\n  },\n  \"audio/l24\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"audio/l8\": {\n    \"source\": \"iana\"\n  },\n  \"audio/lpc\": {\n    \"source\": \"iana\"\n  },\n  \"audio/midi\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mid\",\"midi\",\"kar\",\"rmi\"]\n  },\n  \"audio/mobile-xmf\": {\n    \"source\": \"iana\"\n  },\n  \"audio/mp4\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"mp4a\",\"m4a\"]\n  },\n  \"audio/mp4a-latm\": {\n    \"source\": \"iana\"\n  },\n  \"audio/mpa\": {\n    \"source\": \"iana\"\n  },\n  \"audio/mpa-robust\": {\n    \"source\": \"iana\"\n  },\n  \"audio/mpeg\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"mpga\",\"mp2\",\"mp2a\",\"mp3\",\"m2a\",\"m3a\"]\n  },\n  \"audio/mpeg4-generic\": {\n    \"source\": \"iana\"\n  },\n  \"audio/musepack\": {\n    \"source\": \"apache\"\n  },\n  \"audio/ogg\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"oga\",\"ogg\",\"spx\"]\n  },\n  \"audio/opus\": {\n    \"source\": \"iana\"\n  },\n  \"audio/parityfec\": {\n    \"source\": \"iana\"\n  },\n  \"audio/pcma\": {\n    \"source\": \"iana\"\n  },\n  \"audio/pcma-wb\": {\n    \"source\": \"iana\"\n  },\n  \"audio/pcmu\": {\n    \"source\": \"iana\"\n  },\n  \"audio/pcmu-wb\": {\n    \"source\": \"iana\"\n  },\n  \"audio/prs.sid\": {\n    \"source\": \"iana\"\n  },\n  \"audio/qcelp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/raptorfec\": {\n    \"source\": \"iana\"\n  },\n  \"audio/red\": {\n    \"source\": \"iana\"\n  },\n  \"audio/rtp-enc-aescm128\": {\n    \"source\": \"iana\"\n  },\n  \"audio/rtp-midi\": {\n    \"source\": \"iana\"\n  },\n  \"audio/rtploopback\": {\n    \"source\": \"iana\"\n  },\n  \"audio/rtx\": {\n    \"source\": \"iana\"\n  },\n  \"audio/s3m\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"s3m\"]\n  },\n  \"audio/silk\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sil\"]\n  },\n  \"audio/smv\": {\n    \"source\": \"iana\"\n  },\n  \"audio/smv-qcp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/smv0\": {\n    \"source\": \"iana\"\n  },\n  \"audio/sp-midi\": {\n    \"source\": \"iana\"\n  },\n  \"audio/speex\": {\n    \"source\": \"iana\"\n  },\n  \"audio/t140c\": {\n    \"source\": \"iana\"\n  },\n  \"audio/t38\": {\n    \"source\": \"iana\"\n  },\n  \"audio/telephone-event\": {\n    \"source\": \"iana\"\n  },\n  \"audio/tone\": {\n    \"source\": \"iana\"\n  },\n  \"audio/uemclip\": {\n    \"source\": \"iana\"\n  },\n  \"audio/ulpfec\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vdvi\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vmr-wb\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.3gpp.iufp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.4sb\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.audiokoz\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.celp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.cisco.nse\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.cmles.radio-events\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.cns.anp1\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.cns.inf1\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dece.audio\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"uva\",\"uvva\"]\n  },\n  \"audio/vnd.digital-winds\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"eol\"]\n  },\n  \"audio/vnd.dlna.adts\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dolby.heaac.1\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dolby.heaac.2\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dolby.mlp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dolby.mps\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dolby.pl2\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dolby.pl2x\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dolby.pl2z\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dolby.pulse.1\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.dra\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dra\"]\n  },\n  \"audio/vnd.dts\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dts\"]\n  },\n  \"audio/vnd.dts.hd\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dtshd\"]\n  },\n  \"audio/vnd.dvb.file\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.everad.plj\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.hns.audio\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.lucent.voice\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"lvp\"]\n  },\n  \"audio/vnd.ms-playready.media.pya\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"pya\"]\n  },\n  \"audio/vnd.nokia.mobile-xmf\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.nortel.vbk\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.nuera.ecelp4800\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ecelp4800\"]\n  },\n  \"audio/vnd.nuera.ecelp7470\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ecelp7470\"]\n  },\n  \"audio/vnd.nuera.ecelp9600\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ecelp9600\"]\n  },\n  \"audio/vnd.octel.sbc\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.qcelp\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.rhetorex.32kadpcm\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.rip\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rip\"]\n  },\n  \"audio/vnd.rn-realaudio\": {\n    \"compressible\": false\n  },\n  \"audio/vnd.sealedmedia.softseal.mpeg\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.vmx.cvsd\": {\n    \"source\": \"iana\"\n  },\n  \"audio/vnd.wave\": {\n    \"compressible\": false\n  },\n  \"audio/vorbis\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"audio/vorbis-config\": {\n    \"source\": \"iana\"\n  },\n  \"audio/wav\": {\n    \"compressible\": false,\n    \"extensions\": [\"wav\"]\n  },\n  \"audio/wave\": {\n    \"compressible\": false,\n    \"extensions\": [\"wav\"]\n  },\n  \"audio/webm\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"weba\"]\n  },\n  \"audio/x-aac\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"aac\"]\n  },\n  \"audio/x-aiff\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"aif\",\"aiff\",\"aifc\"]\n  },\n  \"audio/x-caf\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"caf\"]\n  },\n  \"audio/x-flac\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"flac\"]\n  },\n  \"audio/x-m4a\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"m4a\"]\n  },\n  \"audio/x-matroska\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mka\"]\n  },\n  \"audio/x-mpegurl\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"m3u\"]\n  },\n  \"audio/x-ms-wax\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wax\"]\n  },\n  \"audio/x-ms-wma\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wma\"]\n  },\n  \"audio/x-pn-realaudio\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ram\",\"ra\"]\n  },\n  \"audio/x-pn-realaudio-plugin\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"rmp\"]\n  },\n  \"audio/x-realaudio\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"ra\"]\n  },\n  \"audio/x-tta\": {\n    \"source\": \"apache\"\n  },\n  \"audio/x-wav\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wav\"]\n  },\n  \"audio/xm\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xm\"]\n  },\n  \"chemical/x-cdx\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cdx\"]\n  },\n  \"chemical/x-cif\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cif\"]\n  },\n  \"chemical/x-cmdf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cmdf\"]\n  },\n  \"chemical/x-cml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cml\"]\n  },\n  \"chemical/x-csml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"csml\"]\n  },\n  \"chemical/x-pdb\": {\n    \"source\": \"apache\"\n  },\n  \"chemical/x-xyz\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xyz\"]\n  },\n  \"font/opentype\": {\n    \"compressible\": true,\n    \"extensions\": [\"otf\"]\n  },\n  \"image/bmp\": {\n    \"source\": \"apache\",\n    \"compressible\": true,\n    \"extensions\": [\"bmp\"]\n  },\n  \"image/cgm\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"cgm\"]\n  },\n  \"image/fits\": {\n    \"source\": \"iana\"\n  },\n  \"image/g3fax\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"g3\"]\n  },\n  \"image/gif\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"gif\"]\n  },\n  \"image/ief\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ief\"]\n  },\n  \"image/jp2\": {\n    \"source\": \"iana\"\n  },\n  \"image/jpeg\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"jpeg\",\"jpg\",\"jpe\"]\n  },\n  \"image/jpm\": {\n    \"source\": \"iana\"\n  },\n  \"image/jpx\": {\n    \"source\": \"iana\"\n  },\n  \"image/ktx\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ktx\"]\n  },\n  \"image/naplps\": {\n    \"source\": \"iana\"\n  },\n  \"image/pjpeg\": {\n    \"compressible\": false\n  },\n  \"image/png\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"png\"]\n  },\n  \"image/prs.btif\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"btif\"]\n  },\n  \"image/prs.pti\": {\n    \"source\": \"iana\"\n  },\n  \"image/pwg-raster\": {\n    \"source\": \"iana\"\n  },\n  \"image/sgi\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sgi\"]\n  },\n  \"image/svg+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"svg\",\"svgz\"]\n  },\n  \"image/t38\": {\n    \"source\": \"iana\"\n  },\n  \"image/tiff\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"tiff\",\"tif\"]\n  },\n  \"image/tiff-fx\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.adobe.photoshop\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"psd\"]\n  },\n  \"image/vnd.airzip.accelerator.azv\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.cns.inf2\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.dece.graphic\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"uvi\",\"uvvi\",\"uvg\",\"uvvg\"]\n  },\n  \"image/vnd.djvu\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"djvu\",\"djv\"]\n  },\n  \"image/vnd.dvb.subtitle\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sub\"]\n  },\n  \"image/vnd.dwg\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dwg\"]\n  },\n  \"image/vnd.dxf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dxf\"]\n  },\n  \"image/vnd.fastbidsheet\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fbs\"]\n  },\n  \"image/vnd.fpx\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fpx\"]\n  },\n  \"image/vnd.fst\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fst\"]\n  },\n  \"image/vnd.fujixerox.edmics-mmr\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mmr\"]\n  },\n  \"image/vnd.fujixerox.edmics-rlc\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"rlc\"]\n  },\n  \"image/vnd.globalgraphics.pgb\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.microsoft.icon\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.mix\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.mozilla.apng\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.ms-modi\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mdi\"]\n  },\n  \"image/vnd.ms-photo\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wdp\"]\n  },\n  \"image/vnd.net-fpx\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"npx\"]\n  },\n  \"image/vnd.radiance\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.sealed.png\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.sealedmedia.softseal.gif\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.sealedmedia.softseal.jpg\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.svf\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.tencent.tap\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.valve.source.texture\": {\n    \"source\": \"iana\"\n  },\n  \"image/vnd.wap.wbmp\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wbmp\"]\n  },\n  \"image/vnd.xiff\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"xif\"]\n  },\n  \"image/vnd.zbrush.pcx\": {\n    \"source\": \"iana\"\n  },\n  \"image/webp\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"webp\"]\n  },\n  \"image/x-3ds\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"3ds\"]\n  },\n  \"image/x-cmu-raster\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ras\"]\n  },\n  \"image/x-cmx\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"cmx\"]\n  },\n  \"image/x-freehand\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"fh\",\"fhc\",\"fh4\",\"fh5\",\"fh7\"]\n  },\n  \"image/x-icon\": {\n    \"source\": \"apache\",\n    \"compressible\": true,\n    \"extensions\": [\"ico\"]\n  },\n  \"image/x-jng\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"jng\"]\n  },\n  \"image/x-mrsid-image\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sid\"]\n  },\n  \"image/x-ms-bmp\": {\n    \"source\": \"nginx\",\n    \"compressible\": true,\n    \"extensions\": [\"bmp\"]\n  },\n  \"image/x-pcx\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pcx\"]\n  },\n  \"image/x-pict\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pic\",\"pct\"]\n  },\n  \"image/x-portable-anymap\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pnm\"]\n  },\n  \"image/x-portable-bitmap\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pbm\"]\n  },\n  \"image/x-portable-graymap\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pgm\"]\n  },\n  \"image/x-portable-pixmap\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ppm\"]\n  },\n  \"image/x-rgb\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"rgb\"]\n  },\n  \"image/x-tga\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"tga\"]\n  },\n  \"image/x-xbitmap\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xbm\"]\n  },\n  \"image/x-xcf\": {\n    \"compressible\": false\n  },\n  \"image/x-xpixmap\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xpm\"]\n  },\n  \"image/x-xwindowdump\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"xwd\"]\n  },\n  \"message/cpim\": {\n    \"source\": \"iana\"\n  },\n  \"message/delivery-status\": {\n    \"source\": \"iana\"\n  },\n  \"message/disposition-notification\": {\n    \"source\": \"iana\"\n  },\n  \"message/external-body\": {\n    \"source\": \"iana\"\n  },\n  \"message/feedback-report\": {\n    \"source\": \"iana\"\n  },\n  \"message/global\": {\n    \"source\": \"iana\"\n  },\n  \"message/global-delivery-status\": {\n    \"source\": \"iana\"\n  },\n  \"message/global-disposition-notification\": {\n    \"source\": \"iana\"\n  },\n  \"message/global-headers\": {\n    \"source\": \"iana\"\n  },\n  \"message/http\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"message/imdn+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"message/news\": {\n    \"source\": \"iana\"\n  },\n  \"message/partial\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"message/rfc822\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"eml\",\"mime\"]\n  },\n  \"message/s-http\": {\n    \"source\": \"iana\"\n  },\n  \"message/sip\": {\n    \"source\": \"iana\"\n  },\n  \"message/sipfrag\": {\n    \"source\": \"iana\"\n  },\n  \"message/tracking-status\": {\n    \"source\": \"iana\"\n  },\n  \"message/vnd.si.simp\": {\n    \"source\": \"iana\"\n  },\n  \"message/vnd.wfa.wsc\": {\n    \"source\": \"iana\"\n  },\n  \"model/iges\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"igs\",\"iges\"]\n  },\n  \"model/mesh\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"msh\",\"mesh\",\"silo\"]\n  },\n  \"model/vnd.collada+xml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dae\"]\n  },\n  \"model/vnd.dwf\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dwf\"]\n  },\n  \"model/vnd.flatland.3dml\": {\n    \"source\": \"iana\"\n  },\n  \"model/vnd.gdl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gdl\"]\n  },\n  \"model/vnd.gs-gdl\": {\n    \"source\": \"apache\"\n  },\n  \"model/vnd.gs.gdl\": {\n    \"source\": \"iana\"\n  },\n  \"model/vnd.gtw\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gtw\"]\n  },\n  \"model/vnd.moml+xml\": {\n    \"source\": \"iana\"\n  },\n  \"model/vnd.mts\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"mts\"]\n  },\n  \"model/vnd.opengex\": {\n    \"source\": \"iana\"\n  },\n  \"model/vnd.parasolid.transmit.binary\": {\n    \"source\": \"iana\"\n  },\n  \"model/vnd.parasolid.transmit.text\": {\n    \"source\": \"iana\"\n  },\n  \"model/vnd.valve.source.compiled-map\": {\n    \"source\": \"iana\"\n  },\n  \"model/vnd.vtu\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"vtu\"]\n  },\n  \"model/vrml\": {\n    \"source\": \"iana\",\n    \"compressible\": false,\n    \"extensions\": [\"wrl\",\"vrml\"]\n  },\n  \"model/x3d+binary\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"x3db\",\"x3dbz\"]\n  },\n  \"model/x3d+fastinfoset\": {\n    \"source\": \"iana\"\n  },\n  \"model/x3d+vrml\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"x3dv\",\"x3dvz\"]\n  },\n  \"model/x3d+xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"x3d\",\"x3dz\"]\n  },\n  \"model/x3d-vrml\": {\n    \"source\": \"iana\"\n  },\n  \"multipart/alternative\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"multipart/appledouble\": {\n    \"source\": \"iana\"\n  },\n  \"multipart/byteranges\": {\n    \"source\": \"iana\"\n  },\n  \"multipart/digest\": {\n    \"source\": \"iana\"\n  },\n  \"multipart/encrypted\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"multipart/form-data\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"multipart/header-set\": {\n    \"source\": \"iana\"\n  },\n  \"multipart/mixed\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"multipart/parallel\": {\n    \"source\": \"iana\"\n  },\n  \"multipart/related\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"multipart/report\": {\n    \"source\": \"iana\"\n  },\n  \"multipart/signed\": {\n    \"source\": \"iana\",\n    \"compressible\": false\n  },\n  \"multipart/voice-message\": {\n    \"source\": \"iana\"\n  },\n  \"multipart/x-mixed-replace\": {\n    \"source\": \"iana\"\n  },\n  \"text/1d-interleaved-parityfec\": {\n    \"source\": \"iana\"\n  },\n  \"text/cache-manifest\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"appcache\",\"manifest\"]\n  },\n  \"text/calendar\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ics\",\"ifb\"]\n  },\n  \"text/calender\": {\n    \"compressible\": true\n  },\n  \"text/cmd\": {\n    \"compressible\": true\n  },\n  \"text/coffeescript\": {\n    \"extensions\": [\"coffee\",\"litcoffee\"]\n  },\n  \"text/css\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"css\"]\n  },\n  \"text/csv\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"csv\"]\n  },\n  \"text/csv-schema\": {\n    \"source\": \"iana\"\n  },\n  \"text/directory\": {\n    \"source\": \"iana\"\n  },\n  \"text/dns\": {\n    \"source\": \"iana\"\n  },\n  \"text/ecmascript\": {\n    \"source\": \"iana\"\n  },\n  \"text/encaprtp\": {\n    \"source\": \"iana\"\n  },\n  \"text/enriched\": {\n    \"source\": \"iana\"\n  },\n  \"text/fwdred\": {\n    \"source\": \"iana\"\n  },\n  \"text/grammar-ref-list\": {\n    \"source\": \"iana\"\n  },\n  \"text/hjson\": {\n    \"extensions\": [\"hjson\"]\n  },\n  \"text/html\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"html\",\"htm\",\"shtml\"]\n  },\n  \"text/jade\": {\n    \"extensions\": [\"jade\"]\n  },\n  \"text/javascript\": {\n    \"source\": \"iana\",\n    \"compressible\": true\n  },\n  \"text/jcr-cnd\": {\n    \"source\": \"iana\"\n  },\n  \"text/jsx\": {\n    \"compressible\": true,\n    \"extensions\": [\"jsx\"]\n  },\n  \"text/less\": {\n    \"extensions\": [\"less\"]\n  },\n  \"text/markdown\": {\n    \"source\": \"iana\"\n  },\n  \"text/mathml\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"mml\"]\n  },\n  \"text/mizar\": {\n    \"source\": \"iana\"\n  },\n  \"text/n3\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"n3\"]\n  },\n  \"text/parameters\": {\n    \"source\": \"iana\"\n  },\n  \"text/parityfec\": {\n    \"source\": \"iana\"\n  },\n  \"text/plain\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"txt\",\"text\",\"conf\",\"def\",\"list\",\"log\",\"in\",\"ini\"]\n  },\n  \"text/provenance-notation\": {\n    \"source\": \"iana\"\n  },\n  \"text/prs.fallenstein.rst\": {\n    \"source\": \"iana\"\n  },\n  \"text/prs.lines.tag\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"dsc\"]\n  },\n  \"text/raptorfec\": {\n    \"source\": \"iana\"\n  },\n  \"text/red\": {\n    \"source\": \"iana\"\n  },\n  \"text/rfc822-headers\": {\n    \"source\": \"iana\"\n  },\n  \"text/richtext\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"rtx\"]\n  },\n  \"text/rtf\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"rtf\"]\n  },\n  \"text/rtp-enc-aescm128\": {\n    \"source\": \"iana\"\n  },\n  \"text/rtploopback\": {\n    \"source\": \"iana\"\n  },\n  \"text/rtx\": {\n    \"source\": \"iana\"\n  },\n  \"text/sgml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sgml\",\"sgm\"]\n  },\n  \"text/stylus\": {\n    \"extensions\": [\"stylus\",\"styl\"]\n  },\n  \"text/t140\": {\n    \"source\": \"iana\"\n  },\n  \"text/tab-separated-values\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"tsv\"]\n  },\n  \"text/troff\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"t\",\"tr\",\"roff\",\"man\",\"me\",\"ms\"]\n  },\n  \"text/turtle\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"ttl\"]\n  },\n  \"text/ulpfec\": {\n    \"source\": \"iana\"\n  },\n  \"text/uri-list\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"uri\",\"uris\",\"urls\"]\n  },\n  \"text/vcard\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"vcard\"]\n  },\n  \"text/vnd.a\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.abc\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.curl\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"curl\"]\n  },\n  \"text/vnd.curl.dcurl\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"dcurl\"]\n  },\n  \"text/vnd.curl.mcurl\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mcurl\"]\n  },\n  \"text/vnd.curl.scurl\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"scurl\"]\n  },\n  \"text/vnd.debian.copyright\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.dmclientscript\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.dvb.subtitle\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"sub\"]\n  },\n  \"text/vnd.esmertec.theme-descriptor\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.fly\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"fly\"]\n  },\n  \"text/vnd.fmi.flexstor\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"flx\"]\n  },\n  \"text/vnd.graphviz\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"gv\"]\n  },\n  \"text/vnd.in3d.3dml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"3dml\"]\n  },\n  \"text/vnd.in3d.spot\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"spot\"]\n  },\n  \"text/vnd.iptc.newsml\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.iptc.nitf\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.latex-z\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.motorola.reflex\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.ms-mediapackage\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.net2phone.commcenter.command\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.radisys.msml-basic-layout\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.si.uricatalogue\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.sun.j2me.app-descriptor\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"jad\"]\n  },\n  \"text/vnd.trolltech.linguist\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.wap.si\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.wap.sl\": {\n    \"source\": \"iana\"\n  },\n  \"text/vnd.wap.wml\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wml\"]\n  },\n  \"text/vnd.wap.wmlscript\": {\n    \"source\": \"iana\",\n    \"extensions\": [\"wmls\"]\n  },\n  \"text/vtt\": {\n    \"charset\": \"UTF-8\",\n    \"compressible\": true,\n    \"extensions\": [\"vtt\"]\n  },\n  \"text/x-asm\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"s\",\"asm\"]\n  },\n  \"text/x-c\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"c\",\"cc\",\"cxx\",\"cpp\",\"h\",\"hh\",\"dic\"]\n  },\n  \"text/x-component\": {\n    \"source\": \"nginx\",\n    \"extensions\": [\"htc\"]\n  },\n  \"text/x-fortran\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"f\",\"for\",\"f77\",\"f90\"]\n  },\n  \"text/x-gwt-rpc\": {\n    \"compressible\": true\n  },\n  \"text/x-handlebars-template\": {\n    \"extensions\": [\"hbs\"]\n  },\n  \"text/x-java-source\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"java\"]\n  },\n  \"text/x-jquery-tmpl\": {\n    \"compressible\": true\n  },\n  \"text/x-lua\": {\n    \"extensions\": [\"lua\"]\n  },\n  \"text/x-markdown\": {\n    \"compressible\": true,\n    \"extensions\": [\"markdown\",\"md\",\"mkd\"]\n  },\n  \"text/x-nfo\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"nfo\"]\n  },\n  \"text/x-opml\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"opml\"]\n  },\n  \"text/x-pascal\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"p\",\"pas\"]\n  },\n  \"text/x-processing\": {\n    \"compressible\": true,\n    \"extensions\": [\"pde\"]\n  },\n  \"text/x-sass\": {\n    \"extensions\": [\"sass\"]\n  },\n  \"text/x-scss\": {\n    \"extensions\": [\"scss\"]\n  },\n  \"text/x-setext\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"etx\"]\n  },\n  \"text/x-sfv\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"sfv\"]\n  },\n  \"text/x-suse-ymp\": {\n    \"compressible\": true,\n    \"extensions\": [\"ymp\"]\n  },\n  \"text/x-uuencode\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"uu\"]\n  },\n  \"text/x-vcalendar\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"vcs\"]\n  },\n  \"text/x-vcard\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"vcf\"]\n  },\n  \"text/xml\": {\n    \"source\": \"iana\",\n    \"compressible\": true,\n    \"extensions\": [\"xml\"]\n  },\n  \"text/xml-external-parsed-entity\": {\n    \"source\": \"iana\"\n  },\n  \"text/yaml\": {\n    \"extensions\": [\"yaml\",\"yml\"]\n  },\n  \"video/1d-interleaved-parityfec\": {\n    \"source\": \"apache\"\n  },\n  \"video/3gpp\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"3gp\",\"3gpp\"]\n  },\n  \"video/3gpp-tt\": {\n    \"source\": \"apache\"\n  },\n  \"video/3gpp2\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"3g2\"]\n  },\n  \"video/bmpeg\": {\n    \"source\": \"apache\"\n  },\n  \"video/bt656\": {\n    \"source\": \"apache\"\n  },\n  \"video/celb\": {\n    \"source\": \"apache\"\n  },\n  \"video/dv\": {\n    \"source\": \"apache\"\n  },\n  \"video/h261\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"h261\"]\n  },\n  \"video/h263\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"h263\"]\n  },\n  \"video/h263-1998\": {\n    \"source\": \"apache\"\n  },\n  \"video/h263-2000\": {\n    \"source\": \"apache\"\n  },\n  \"video/h264\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"h264\"]\n  },\n  \"video/h264-rcdo\": {\n    \"source\": \"apache\"\n  },\n  \"video/h264-svc\": {\n    \"source\": \"apache\"\n  },\n  \"video/jpeg\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"jpgv\"]\n  },\n  \"video/jpeg2000\": {\n    \"source\": \"apache\"\n  },\n  \"video/jpm\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"jpm\",\"jpgm\"]\n  },\n  \"video/mj2\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mj2\",\"mjp2\"]\n  },\n  \"video/mp1s\": {\n    \"source\": \"apache\"\n  },\n  \"video/mp2p\": {\n    \"source\": \"apache\"\n  },\n  \"video/mp2t\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ts\"]\n  },\n  \"video/mp4\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"mp4\",\"mp4v\",\"mpg4\"]\n  },\n  \"video/mp4v-es\": {\n    \"source\": \"apache\"\n  },\n  \"video/mpeg\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"mpeg\",\"mpg\",\"mpe\",\"m1v\",\"m2v\"]\n  },\n  \"video/mpeg4-generic\": {\n    \"source\": \"apache\"\n  },\n  \"video/mpv\": {\n    \"source\": \"apache\"\n  },\n  \"video/nv\": {\n    \"source\": \"apache\"\n  },\n  \"video/ogg\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"ogv\"]\n  },\n  \"video/parityfec\": {\n    \"source\": \"apache\"\n  },\n  \"video/pointer\": {\n    \"source\": \"apache\"\n  },\n  \"video/quicktime\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"qt\",\"mov\"]\n  },\n  \"video/raw\": {\n    \"source\": \"apache\"\n  },\n  \"video/rtp-enc-aescm128\": {\n    \"source\": \"apache\"\n  },\n  \"video/rtx\": {\n    \"source\": \"apache\"\n  },\n  \"video/smpte292m\": {\n    \"source\": \"apache\"\n  },\n  \"video/ulpfec\": {\n    \"source\": \"apache\"\n  },\n  \"video/vc1\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.cctv\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.dece.hd\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"uvh\",\"uvvh\"]\n  },\n  \"video/vnd.dece.mobile\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"uvm\",\"uvvm\"]\n  },\n  \"video/vnd.dece.mp4\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.dece.pd\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"uvp\",\"uvvp\"]\n  },\n  \"video/vnd.dece.sd\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"uvs\",\"uvvs\"]\n  },\n  \"video/vnd.dece.video\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"uvv\",\"uvvv\"]\n  },\n  \"video/vnd.directv.mpeg\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.directv.mpeg-tts\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.dlna.mpeg-tts\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.dvb.file\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"dvb\"]\n  },\n  \"video/vnd.fvt\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"fvt\"]\n  },\n  \"video/vnd.hns.video\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.iptvforum.1dparityfec-1010\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.iptvforum.1dparityfec-2005\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.iptvforum.2dparityfec-1010\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.iptvforum.2dparityfec-2005\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.iptvforum.ttsavc\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.iptvforum.ttsmpeg2\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.motorola.video\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.motorola.videop\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.mpegurl\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mxu\",\"m4u\"]\n  },\n  \"video/vnd.ms-playready.media.pyv\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"pyv\"]\n  },\n  \"video/vnd.nokia.interleaved-multimedia\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.nokia.videovoip\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.objectvideo\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.sealed.mpeg1\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.sealed.mpeg4\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.sealed.swf\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.sealedmedia.softseal.mov\": {\n    \"source\": \"apache\"\n  },\n  \"video/vnd.uvvu.mp4\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"uvu\",\"uvvu\"]\n  },\n  \"video/vnd.vivo\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"viv\"]\n  },\n  \"video/webm\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"webm\"]\n  },\n  \"video/x-f4v\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"f4v\"]\n  },\n  \"video/x-fli\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"fli\"]\n  },\n  \"video/x-flv\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"flv\"]\n  },\n  \"video/x-m4v\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"m4v\"]\n  },\n  \"video/x-matroska\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"mkv\",\"mk3d\",\"mks\"]\n  },\n  \"video/x-mng\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"mng\"]\n  },\n  \"video/x-ms-asf\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"asf\",\"asx\"]\n  },\n  \"video/x-ms-vob\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"vob\"]\n  },\n  \"video/x-ms-wm\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wm\"]\n  },\n  \"video/x-ms-wmv\": {\n    \"source\": \"apache\",\n    \"compressible\": false,\n    \"extensions\": [\"wmv\"]\n  },\n  \"video/x-ms-wmx\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wmx\"]\n  },\n  \"video/x-ms-wvx\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"wvx\"]\n  },\n  \"video/x-msvideo\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"avi\"]\n  },\n  \"video/x-sgi-movie\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"movie\"]\n  },\n  \"video/x-smv\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"smv\"]\n  },\n  \"x-conference/x-cooltalk\": {\n    \"source\": \"apache\",\n    \"extensions\": [\"ice\"]\n  },\n  \"x-shader/x-fragment\": {\n    \"compressible\": true\n  },\n  \"x-shader/x-vertex\": {\n    \"compressible\": true\n  }\n}\n},{}],269:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ants\",\n  \"bats\",\n  \"bears\",\n  \"bees\",\n  \"birds\",\n  \"buffalo\",\n  \"cats\",\n  \"chickens\",\n  \"cattle\",\n  \"dogs\",\n  \"dolphins\",\n  \"ducks\",\n  \"elephants\",\n  \"fishes\",\n  \"foxes\",\n  \"frogs\",\n  \"geese\",\n  \"goats\",\n  \"horses\",\n  \"kangaroos\",\n  \"lions\",\n  \"monkeys\",\n  \"owls\",\n  \"oxen\",\n  \"penguins\",\n  \"people\",\n  \"pigs\",\n  \"rabbits\",\n  \"sheep\",\n  \"tigers\",\n  \"whales\",\n  \"wolves\",\n  \"zebras\",\n  \"banshees\",\n  \"crows\",\n  \"black cats\",\n  \"chimeras\",\n  \"ghosts\",\n  \"conspirators\",\n  \"dragons\",\n  \"dwarves\",\n  \"elves\",\n  \"enchanters\",\n  \"exorcists\",\n  \"sons\",\n  \"foes\",\n  \"giants\",\n  \"gnomes\",\n  \"goblins\",\n  \"gooses\",\n  \"griffins\",\n  \"lycanthropes\",\n  \"nemesis\",\n  \"ogres\",\n  \"oracles\",\n  \"prophets\",\n  \"sorcerors\",\n  \"spiders\",\n  \"spirits\",\n  \"vampires\",\n  \"warlocks\",\n  \"vixens\",\n  \"werewolves\",\n  \"witches\",\n  \"worshipers\",\n  \"zombies\",\n  \"druids\"\n];\n\n},{}],270:[function(require,module,exports){\nvar team = {};\nmodule['exports'] = team;\nteam.creature = require(\"./creature\");\nteam.name = require(\"./name\");\n\n},{\"./creature\":269,\"./name\":271}],271:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Address.state} #{creature}\"\n];\n\n},{}],272:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"####\",\n  \"###\",\n  \"##\"\n];\n\n},{}],273:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Australia\"\n];\n\n},{}],274:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.state_abbr = require(\"./state_abbr\");\naddress.state = require(\"./state\");\naddress.postcode = require(\"./postcode\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":272,\"./default_country\":273,\"./postcode\":275,\"./state\":276,\"./state_abbr\":277,\"./street_suffix\":278}],275:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"0###\",\n  \"2###\",\n  \"3###\",\n  \"4###\",\n  \"5###\",\n  \"6###\",\n  \"7###\"\n];\n\n},{}],276:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"New South Wales\",\n  \"Queensland\",\n  \"Northern Territory\",\n  \"South Australia\",\n  \"Western Australia\",\n  \"Tasmania\",\n  \"Australian Capital Territory\",\n  \"Victoria\"\n];\n\n},{}],277:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"NSW\",\n  \"QLD\",\n  \"NT\",\n  \"SA\",\n  \"WA\",\n  \"TAS\",\n  \"ACT\",\n  \"VIC\"\n];\n\n},{}],278:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Avenue\",\n  \"Boulevard\",\n  \"Circle\",\n  \"Circuit\",\n  \"Court\",\n  \"Crescent\",\n  \"Crest\",\n  \"Drive\",\n  \"Estate Dr\",\n  \"Grove\",\n  \"Hill\",\n  \"Island\",\n  \"Junction\",\n  \"Knoll\",\n  \"Lane\",\n  \"Loop\",\n  \"Mall\",\n  \"Manor\",\n  \"Meadow\",\n  \"Mews\",\n  \"Parade\",\n  \"Parkway\",\n  \"Pass\",\n  \"Place\",\n  \"Plaza\",\n  \"Ridge\",\n  \"Road\",\n  \"Run\",\n  \"Square\",\n  \"Station St\",\n  \"Street\",\n  \"Summit\",\n  \"Terrace\",\n  \"Track\",\n  \"Trail\",\n  \"View Rd\",\n  \"Way\"\n];\n\n},{}],279:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\n\n},{\"./suffix\":280}],280:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Pty Ltd\",\n  \"and Sons\",\n  \"Corp\",\n  \"Group\",\n  \"Brothers\",\n  \"Partners\"\n];\n\n},{}],281:[function(require,module,exports){\nvar en_AU = {};\nmodule['exports'] = en_AU;\nen_AU.title = \"Australia (English)\";\nen_AU.name = require(\"./name\");\nen_AU.company = require(\"./company\");\nen_AU.internet = require(\"./internet\");\nen_AU.address = require(\"./address\");\nen_AU.phone_number = require(\"./phone_number\");\n\n},{\"./address\":274,\"./company\":279,\"./internet\":283,\"./name\":285,\"./phone_number\":288}],282:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com.au\",\n  \"com\",\n  \"net.au\",\n  \"net\",\n  \"org.au\",\n  \"org\"\n];\n\n},{}],283:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":282,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],284:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"William\",\n  \"Jack\",\n  \"Oliver\",\n  \"Joshua\",\n  \"Thomas\",\n  \"Lachlan\",\n  \"Cooper\",\n  \"Noah\",\n  \"Ethan\",\n  \"Lucas\",\n  \"James\",\n  \"Samuel\",\n  \"Jacob\",\n  \"Liam\",\n  \"Alexander\",\n  \"Benjamin\",\n  \"Max\",\n  \"Isaac\",\n  \"Daniel\",\n  \"Riley\",\n  \"Ryan\",\n  \"Charlie\",\n  \"Tyler\",\n  \"Jake\",\n  \"Matthew\",\n  \"Xavier\",\n  \"Harry\",\n  \"Jayden\",\n  \"Nicholas\",\n  \"Harrison\",\n  \"Levi\",\n  \"Luke\",\n  \"Adam\",\n  \"Henry\",\n  \"Aiden\",\n  \"Dylan\",\n  \"Oscar\",\n  \"Michael\",\n  \"Jackson\",\n  \"Logan\",\n  \"Joseph\",\n  \"Blake\",\n  \"Nathan\",\n  \"Connor\",\n  \"Elijah\",\n  \"Nate\",\n  \"Archie\",\n  \"Bailey\",\n  \"Marcus\",\n  \"Cameron\",\n  \"Jordan\",\n  \"Zachary\",\n  \"Caleb\",\n  \"Hunter\",\n  \"Ashton\",\n  \"Toby\",\n  \"Aidan\",\n  \"Hayden\",\n  \"Mason\",\n  \"Hamish\",\n  \"Edward\",\n  \"Angus\",\n  \"Eli\",\n  \"Sebastian\",\n  \"Christian\",\n  \"Patrick\",\n  \"Andrew\",\n  \"Anthony\",\n  \"Luca\",\n  \"Kai\",\n  \"Beau\",\n  \"Alex\",\n  \"George\",\n  \"Callum\",\n  \"Finn\",\n  \"Zac\",\n  \"Mitchell\",\n  \"Jett\",\n  \"Jesse\",\n  \"Gabriel\",\n  \"Leo\",\n  \"Declan\",\n  \"Charles\",\n  \"Jasper\",\n  \"Jonathan\",\n  \"Aaron\",\n  \"Hugo\",\n  \"David\",\n  \"Christopher\",\n  \"Chase\",\n  \"Owen\",\n  \"Justin\",\n  \"Ali\",\n  \"Darcy\",\n  \"Lincoln\",\n  \"Cody\",\n  \"Phoenix\",\n  \"Sam\",\n  \"John\",\n  \"Joel\",\n  \"Isabella\",\n  \"Ruby\",\n  \"Chloe\",\n  \"Olivia\",\n  \"Charlotte\",\n  \"Mia\",\n  \"Lily\",\n  \"Emily\",\n  \"Ella\",\n  \"Sienna\",\n  \"Sophie\",\n  \"Amelia\",\n  \"Grace\",\n  \"Ava\",\n  \"Zoe\",\n  \"Emma\",\n  \"Sophia\",\n  \"Matilda\",\n  \"Hannah\",\n  \"Jessica\",\n  \"Lucy\",\n  \"Georgia\",\n  \"Sarah\",\n  \"Abigail\",\n  \"Zara\",\n  \"Eva\",\n  \"Scarlett\",\n  \"Jasmine\",\n  \"Chelsea\",\n  \"Lilly\",\n  \"Ivy\",\n  \"Isla\",\n  \"Evie\",\n  \"Isabelle\",\n  \"Maddison\",\n  \"Layla\",\n  \"Summer\",\n  \"Annabelle\",\n  \"Alexis\",\n  \"Elizabeth\",\n  \"Bella\",\n  \"Holly\",\n  \"Lara\",\n  \"Madison\",\n  \"Alyssa\",\n  \"Maya\",\n  \"Tahlia\",\n  \"Claire\",\n  \"Hayley\",\n  \"Imogen\",\n  \"Jade\",\n  \"Ellie\",\n  \"Sofia\",\n  \"Addison\",\n  \"Molly\",\n  \"Phoebe\",\n  \"Alice\",\n  \"Savannah\",\n  \"Gabriella\",\n  \"Kayla\",\n  \"Mikayla\",\n  \"Abbey\",\n  \"Eliza\",\n  \"Willow\",\n  \"Alexandra\",\n  \"Poppy\",\n  \"Samantha\",\n  \"Stella\",\n  \"Amy\",\n  \"Amelie\",\n  \"Anna\",\n  \"Piper\",\n  \"Gemma\",\n  \"Isabel\",\n  \"Victoria\",\n  \"Stephanie\",\n  \"Caitlin\",\n  \"Heidi\",\n  \"Paige\",\n  \"Rose\",\n  \"Amber\",\n  \"Audrey\",\n  \"Claudia\",\n  \"Taylor\",\n  \"Madeline\",\n  \"Angelina\",\n  \"Natalie\",\n  \"Charli\",\n  \"Lauren\",\n  \"Ashley\",\n  \"Violet\",\n  \"Mackenzie\",\n  \"Abby\",\n  \"Skye\",\n  \"Lillian\",\n  \"Alana\",\n  \"Lola\",\n  \"Leah\",\n  \"Eve\",\n  \"Kiara\"\n];\n\n},{}],285:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\n\n},{\"./first_name\":284,\"./last_name\":286}],286:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Smith\",\n  \"Jones\",\n  \"Williams\",\n  \"Brown\",\n  \"Wilson\",\n  \"Taylor\",\n  \"Johnson\",\n  \"White\",\n  \"Martin\",\n  \"Anderson\",\n  \"Thompson\",\n  \"Nguyen\",\n  \"Thomas\",\n  \"Walker\",\n  \"Harris\",\n  \"Lee\",\n  \"Ryan\",\n  \"Robinson\",\n  \"Kelly\",\n  \"King\",\n  \"Davis\",\n  \"Wright\",\n  \"Evans\",\n  \"Roberts\",\n  \"Green\",\n  \"Hall\",\n  \"Wood\",\n  \"Jackson\",\n  \"Clarke\",\n  \"Patel\",\n  \"Khan\",\n  \"Lewis\",\n  \"James\",\n  \"Phillips\",\n  \"Mason\",\n  \"Mitchell\",\n  \"Rose\",\n  \"Davies\",\n  \"Rodriguez\",\n  \"Cox\",\n  \"Alexander\",\n  \"Garden\",\n  \"Campbell\",\n  \"Johnston\",\n  \"Moore\",\n  \"Smyth\",\n  \"O'neill\",\n  \"Doherty\",\n  \"Stewart\",\n  \"Quinn\",\n  \"Murphy\",\n  \"Graham\",\n  \"Mclaughlin\",\n  \"Hamilton\",\n  \"Murray\",\n  \"Hughes\",\n  \"Robertson\",\n  \"Thomson\",\n  \"Scott\",\n  \"Macdonald\",\n  \"Reid\",\n  \"Clark\",\n  \"Ross\",\n  \"Young\",\n  \"Watson\",\n  \"Paterson\",\n  \"Morrison\",\n  \"Morgan\",\n  \"Griffiths\",\n  \"Edwards\",\n  \"Rees\",\n  \"Jenkins\",\n  \"Owen\",\n  \"Price\",\n  \"Moss\",\n  \"Richards\",\n  \"Abbott\",\n  \"Adams\",\n  \"Armstrong\",\n  \"Bahringer\",\n  \"Bailey\",\n  \"Barrows\",\n  \"Bartell\",\n  \"Bartoletti\",\n  \"Barton\",\n  \"Bauch\",\n  \"Baumbach\",\n  \"Bayer\",\n  \"Beahan\",\n  \"Beatty\",\n  \"Becker\",\n  \"Beier\",\n  \"Berge\",\n  \"Bergstrom\",\n  \"Bode\",\n  \"Bogan\",\n  \"Borer\",\n  \"Bosco\",\n  \"Botsford\",\n  \"Boyer\",\n  \"Boyle\",\n  \"Braun\",\n  \"Bruen\",\n  \"Carroll\",\n  \"Carter\",\n  \"Cartwright\",\n  \"Casper\",\n  \"Cassin\",\n  \"Champlin\",\n  \"Christiansen\",\n  \"Cole\",\n  \"Collier\",\n  \"Collins\",\n  \"Connelly\",\n  \"Conroy\",\n  \"Corkery\",\n  \"Cormier\",\n  \"Corwin\",\n  \"Cronin\",\n  \"Crooks\",\n  \"Cruickshank\",\n  \"Cummings\",\n  \"D'amore\",\n  \"Daniel\",\n  \"Dare\",\n  \"Daugherty\",\n  \"Dickens\",\n  \"Dickinson\",\n  \"Dietrich\",\n  \"Donnelly\",\n  \"Dooley\",\n  \"Douglas\",\n  \"Doyle\",\n  \"Durgan\",\n  \"Ebert\",\n  \"Emard\",\n  \"Emmerich\",\n  \"Erdman\",\n  \"Ernser\",\n  \"Fadel\",\n  \"Fahey\",\n  \"Farrell\",\n  \"Fay\",\n  \"Feeney\",\n  \"Feil\",\n  \"Ferry\",\n  \"Fisher\",\n  \"Flatley\",\n  \"Gibson\",\n  \"Gleason\",\n  \"Glover\",\n  \"Goldner\",\n  \"Goodwin\",\n  \"Grady\",\n  \"Grant\",\n  \"Greenfelder\",\n  \"Greenholt\",\n  \"Grimes\",\n  \"Gutmann\",\n  \"Hackett\",\n  \"Hahn\",\n  \"Haley\",\n  \"Hammes\",\n  \"Hand\",\n  \"Hane\",\n  \"Hansen\",\n  \"Harber\",\n  \"Hartmann\",\n  \"Harvey\",\n  \"Hayes\",\n  \"Heaney\",\n  \"Heathcote\",\n  \"Heller\",\n  \"Hermann\",\n  \"Hermiston\",\n  \"Hessel\",\n  \"Hettinger\",\n  \"Hickle\",\n  \"Hill\",\n  \"Hills\",\n  \"Hoppe\",\n  \"Howe\",\n  \"Howell\",\n  \"Hudson\",\n  \"Huel\",\n  \"Hyatt\",\n  \"Jacobi\",\n  \"Jacobs\",\n  \"Jacobson\",\n  \"Jerde\",\n  \"Johns\",\n  \"Keeling\",\n  \"Kemmer\",\n  \"Kessler\",\n  \"Kiehn\",\n  \"Kirlin\",\n  \"Klein\",\n  \"Koch\",\n  \"Koelpin\",\n  \"Kohler\",\n  \"Koss\",\n  \"Kovacek\",\n  \"Kreiger\",\n  \"Kris\",\n  \"Kuhlman\",\n  \"Kuhn\",\n  \"Kulas\",\n  \"Kunde\",\n  \"Kutch\",\n  \"Lakin\",\n  \"Lang\",\n  \"Langworth\",\n  \"Larkin\",\n  \"Larson\",\n  \"Leannon\",\n  \"Leffler\",\n  \"Little\",\n  \"Lockman\",\n  \"Lowe\",\n  \"Lynch\",\n  \"Mann\",\n  \"Marks\",\n  \"Marvin\",\n  \"Mayer\",\n  \"Mccullough\",\n  \"Mcdermott\",\n  \"Mckenzie\",\n  \"Miller\",\n  \"Mills\",\n  \"Monahan\",\n  \"Morissette\",\n  \"Mueller\",\n  \"Muller\",\n  \"Nader\",\n  \"Nicolas\",\n  \"Nolan\",\n  \"O'connell\",\n  \"O'conner\",\n  \"O'hara\",\n  \"O'keefe\",\n  \"Olson\",\n  \"O'reilly\",\n  \"Parisian\",\n  \"Parker\",\n  \"Quigley\",\n  \"Reilly\",\n  \"Reynolds\",\n  \"Rice\",\n  \"Ritchie\",\n  \"Rohan\",\n  \"Rolfson\",\n  \"Rowe\",\n  \"Russel\",\n  \"Rutherford\",\n  \"Sanford\",\n  \"Sauer\",\n  \"Schmidt\",\n  \"Schmitt\",\n  \"Schneider\",\n  \"Schroeder\",\n  \"Schultz\",\n  \"Shields\",\n  \"Smitham\",\n  \"Spencer\",\n  \"Stanton\",\n  \"Stark\",\n  \"Stokes\",\n  \"Swift\",\n  \"Tillman\",\n  \"Towne\",\n  \"Tremblay\",\n  \"Tromp\",\n  \"Turcotte\",\n  \"Turner\",\n  \"Walsh\",\n  \"Walter\",\n  \"Ward\",\n  \"Waters\",\n  \"Weber\",\n  \"Welch\",\n  \"West\",\n  \"Wilderman\",\n  \"Wilkinson\",\n  \"Williamson\",\n  \"Windler\",\n  \"Wolf\"\n];\n\n},{}],287:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"0# #### ####\",\n  \"+61 # #### ####\",\n  \"04## ### ###\",\n  \"+61 4## ### ###\"\n];\n\n},{}],288:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":287,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],289:[function(require,module,exports){\nvar en_BORK = {};\nmodule['exports'] = en_BORK;\nen_BORK.title = \"Bork (English)\";\nen_BORK.lorem = require(\"./lorem\");\n\n},{\"./lorem\":290}],290:[function(require,module,exports){\narguments[4][121][0].apply(exports,arguments)\n},{\"./words\":291,\"/Users/a/dev/faker.js/lib/locales/de/lorem/index.js\":121}],291:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Boot\",\n  \"I\",\n  \"Nu\",\n  \"Nur\",\n  \"Tu\",\n  \"Um\",\n  \"a\",\n  \"becoose-a\",\n  \"boot\",\n  \"bork\",\n  \"burn\",\n  \"chuuses\",\n  \"cumplete-a\",\n  \"cun\",\n  \"cunseqooences\",\n  \"curcoomstunces\",\n  \"dee\",\n  \"deeslikes\",\n  \"denuoonceeng\",\n  \"desures\",\n  \"du\",\n  \"eccuoont\",\n  \"ectooel\",\n  \"edfuntege-a\",\n  \"efueeds\",\n  \"egeeen\",\n  \"ell\",\n  \"ere-a\",\n  \"feend\",\n  \"foolt\",\n  \"frum\",\n  \"geefe-a\",\n  \"gesh\",\n  \"greet\",\n  \"heem\",\n  \"heppeeness\",\n  \"hes\",\n  \"hoo\",\n  \"hoomun\",\n  \"idea\",\n  \"ifer\",\n  \"in\",\n  \"incuoonter\",\n  \"injuy\",\n  \"itselff\",\n  \"ixcept\",\n  \"ixemple-a\",\n  \"ixerceese-a\",\n  \"ixpleeen\",\n  \"ixplurer\",\n  \"ixpuoond\",\n  \"ixtremely\",\n  \"knoo\",\n  \"lebureeuoos\",\n  \"lufes\",\n  \"meestekee\",\n  \"mester-booeelder\",\n  \"moost\",\n  \"mun\",\n  \"nu\",\n  \"nut\",\n  \"oobteeen\",\n  \"oocceseeunelly\",\n  \"ooccoor\",\n  \"ooff\",\n  \"oone-a\",\n  \"oor\",\n  \"peeen\",\n  \"peeenffool\",\n  \"physeecel\",\n  \"pleesoore-a\",\n  \"poorsooe-a\",\n  \"poorsooes\",\n  \"preeesing\",\n  \"prucoore-a\",\n  \"prudooces\",\n  \"reeght\",\n  \"reshunelly\",\n  \"resooltunt\",\n  \"sume-a\",\n  \"teecheengs\",\n  \"teke-a\",\n  \"thees\",\n  \"thet\",\n  \"thuse-a\",\n  \"treefiel\",\n  \"troot\",\n  \"tu\",\n  \"tueel\",\n  \"und\",\n  \"undertekes\",\n  \"unnuyeeng\",\n  \"uny\",\n  \"unyune-a\",\n  \"us\",\n  \"veell\",\n  \"veet\",\n  \"ves\",\n  \"vheech\",\n  \"vhu\",\n  \"yuoo\",\n  \"zee\",\n  \"zeere-a\"\n];\n\n},{}],292:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Canada\"\n];\n\n},{}],293:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.default_country = require(\"./default_country\");\naddress.postcode = require('./postcode.js');\n\n},{\"./default_country\":292,\"./postcode.js\":294,\"./state\":295,\"./state_abbr\":296}],294:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"?#? #?#\"\n];\n\n},{}],295:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Alberta\",\n  \"British Columbia\",\n  \"Manitoba\",\n  \"New Brunswick\",\n  \"Newfoundland and Labrador\",\n  \"Nova Scotia\",\n  \"Northwest Territories\",\n  \"Nunavut\",\n  \"Ontario\",\n  \"Prince Edward Island\",\n  \"Quebec\",\n  \"Saskatchewan\",\n  \"Yukon\"\n];\n\n},{}],296:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AB\",\n  \"BC\",\n  \"MB\",\n  \"NB\",\n  \"NL\",\n  \"NS\",\n  \"NU\",\n  \"NT\",\n  \"ON\",\n  \"PE\",\n  \"QC\",\n  \"SK\",\n  \"YT\"\n];\n\n},{}],297:[function(require,module,exports){\nvar en_CA = {};\nmodule['exports'] = en_CA;\nen_CA.title = \"Canada (English)\";\nen_CA.address = require(\"./address\");\nen_CA.internet = require(\"./internet\");\nen_CA.phone_number = require(\"./phone_number\");\n\n},{\"./address\":293,\"./internet\":300,\"./phone_number\":302}],298:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ca\",\n  \"com\",\n  \"biz\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\"\n];\n\n},{}],299:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.ca\",\n  \"hotmail.com\"\n];\n\n},{}],300:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":298,\"./free_email\":299,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],301:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###-###-####\",\n  \"(###)###-####\",\n  \"###.###.####\",\n  \"1-###-###-####\",\n  \"###-###-#### x###\",\n  \"(###)###-#### x###\",\n  \"1-###-###-#### x###\",\n  \"###.###.#### x###\",\n  \"###-###-#### x####\",\n  \"(###)###-#### x####\",\n  \"1-###-###-#### x####\",\n  \"###.###.#### x####\",\n  \"###-###-#### x#####\",\n  \"(###)###-#### x#####\",\n  \"1-###-###-#### x#####\",\n  \"###.###.#### x#####\"\n];\n\n},{}],302:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":301,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],303:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Avon\",\n  \"Bedfordshire\",\n  \"Berkshire\",\n  \"Borders\",\n  \"Buckinghamshire\",\n  \"Cambridgeshire\",\n  \"Central\",\n  \"Cheshire\",\n  \"Cleveland\",\n  \"Clwyd\",\n  \"Cornwall\",\n  \"County Antrim\",\n  \"County Armagh\",\n  \"County Down\",\n  \"County Fermanagh\",\n  \"County Londonderry\",\n  \"County Tyrone\",\n  \"Cumbria\",\n  \"Derbyshire\",\n  \"Devon\",\n  \"Dorset\",\n  \"Dumfries and Galloway\",\n  \"Durham\",\n  \"Dyfed\",\n  \"East Sussex\",\n  \"Essex\",\n  \"Fife\",\n  \"Gloucestershire\",\n  \"Grampian\",\n  \"Greater Manchester\",\n  \"Gwent\",\n  \"Gwynedd County\",\n  \"Hampshire\",\n  \"Herefordshire\",\n  \"Hertfordshire\",\n  \"Highlands and Islands\",\n  \"Humberside\",\n  \"Isle of Wight\",\n  \"Kent\",\n  \"Lancashire\",\n  \"Leicestershire\",\n  \"Lincolnshire\",\n  \"Lothian\",\n  \"Merseyside\",\n  \"Mid Glamorgan\",\n  \"Norfolk\",\n  \"North Yorkshire\",\n  \"Northamptonshire\",\n  \"Northumberland\",\n  \"Nottinghamshire\",\n  \"Oxfordshire\",\n  \"Powys\",\n  \"Rutland\",\n  \"Shropshire\",\n  \"Somerset\",\n  \"South Glamorgan\",\n  \"South Yorkshire\",\n  \"Staffordshire\",\n  \"Strathclyde\",\n  \"Suffolk\",\n  \"Surrey\",\n  \"Tayside\",\n  \"Tyne and Wear\",\n  \"Warwickshire\",\n  \"West Glamorgan\",\n  \"West Midlands\",\n  \"West Sussex\",\n  \"West Yorkshire\",\n  \"Wiltshire\",\n  \"Worcestershire\"\n];\n\n},{}],304:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"England\",\n  \"Scotland\",\n  \"Wales\",\n  \"Northern Ireland\"\n];\n\n},{}],305:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.county = require(\"./county\");\naddress.uk_country = require(\"./uk_country\");\naddress.default_country = require(\"./default_country\");\naddress.postcode = require(\"./postcode\");\n\n},{\"./county\":303,\"./default_country\":304,\"./postcode\":306,\"./uk_country\":307}],306:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"??# #??\",\n  \"??## #??\",\n];\n\n},{}],307:[function(require,module,exports){\nmodule.exports=require(304)\n},{\"/Users/a/dev/faker.js/lib/locales/en_GB/address/default_country.js\":304}],308:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"074## ######\",\n  \"075## ######\",\n  \"076## ######\",\n  \"077## ######\",\n  \"078## ######\",\n  \"079## ######\"\n];\n\n},{}],309:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":308,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],310:[function(require,module,exports){\nvar en_GB = {};\nmodule['exports'] = en_GB;\nen_GB.title = \"Great Britain (English)\";\nen_GB.address = require(\"./address\");\nen_GB.internet = require(\"./internet\");\nen_GB.phone_number = require(\"./phone_number\");\nen_GB.cell_phone = require(\"./cell_phone\");\n\n},{\"./address\":305,\"./cell_phone\":309,\"./internet\":312,\"./phone_number\":314}],311:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"co.uk\",\n  \"com\",\n  \"biz\",\n  \"info\",\n  \"name\"\n];\n\n},{}],312:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":311,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],313:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"01#### #####\",\n  \"01### ######\",\n  \"01#1 ### ####\",\n  \"011# ### ####\",\n  \"02# #### ####\",\n  \"03## ### ####\",\n  \"055 #### ####\",\n  \"056 #### ####\",\n  \"0800 ### ####\",\n  \"08## ### ####\",\n  \"09## ### ####\",\n  \"016977 ####\",\n  \"01### #####\",\n  \"0500 ######\",\n  \"0800 ######\"\n];\n\n},{}],314:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":313,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],315:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Carlow\",\n  \"Cavan\",\n  \"Clare\",\n  \"Cork\",\n  \"Donegal\",\n  \"Dublin\",\n  \"Galway\",\n  \"Kerry\",\n  \"Kildare\",\n  \"Kilkenny\",\n  \"Laois\",\n  \"Leitrim\",\n  \"Limerick\",\n  \"Longford\",\n  \"Louth\",\n  \"Mayo\",\n  \"Meath\",\n  \"Monaghan\",\n  \"Offaly\",\n  \"Roscommon\",\n  \"Sligo\",\n  \"Tipperary\",\n  \"Waterford\",\n  \"Westmeath\",\n  \"Wexford\",\n  \"Wicklow\"\n];\n\n},{}],316:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ireland\"\n];\n\n},{}],317:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.county = require(\"./county\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./county\":315,\"./default_country\":316}],318:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"082 ### ####\",\n  \"083 ### ####\",\n  \"085 ### ####\",\n  \"086 ### ####\",\n  \"087 ### ####\",\n  \"089 ### ####\"\n];\n\n},{}],319:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":318,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],320:[function(require,module,exports){\nvar en_IE = {};\nmodule['exports'] = en_IE;\nen_IE.title = \"Ireland (English)\";\nen_IE.address = require(\"./address\");\nen_IE.internet = require(\"./internet\");\nen_IE.phone_number = require(\"./phone_number\");\nen_IE.cell_phone = require(\"./cell_phone\");\n\n},{\"./address\":317,\"./cell_phone\":319,\"./internet\":322,\"./phone_number\":324}],321:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ie\",\n  \"com\",\n  \"net\",\n  \"info\",\n  \"eu\"\n];\n\n},{}],322:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":321,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],323:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"01 #######\",\n  \"021 #######\",\n  \"022 #######\",\n  \"023 #######\",\n  \"024 #######\",\n  \"025 #######\",\n  \"026 #######\",\n  \"027 #######\",\n  \"028 #######\",\n  \"029 #######\",\n  \"0402 #######\",\n  \"0404 #######\",\n  \"041 #######\",\n  \"042 #######\",\n  \"043 #######\",\n  \"044 #######\",\n  \"045 #######\",\n  \"046 #######\",\n  \"047 #######\",\n  \"049 #######\",\n  \"0504 #######\",\n  \"0505 #######\",\n  \"051 #######\",\n  \"052 #######\",\n  \"053 #######\",\n  \"056 #######\",\n  \"057 #######\",\n  \"058 #######\",\n  \"059 #######\",\n  \"061 #######\",\n  \"062 #######\",\n  \"063 #######\",\n  \"064 #######\",\n  \"065 #######\",\n  \"066 #######\",\n  \"067 #######\",\n  \"068 #######\",\n  \"069 #######\",\n  \"071 #######\",\n  \"074 #######\",\n  \"090 #######\",\n  \"091 #######\",\n  \"093 #######\",\n  \"094 #######\",\n  \"095 #######\",\n  \"096 #######\",\n  \"097 #######\",\n  \"098 #######\",\n  \"099 #######\"\n];\n\n},{}],324:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":323,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],325:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"India\",\n  \"Indian Republic\",\n  \"Bharat\",\n  \"Hindustan\"\n];\n\n},{}],326:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./default_country\":325,\"./postcode\":327,\"./state\":328,\"./state_abbr\":329}],327:[function(require,module,exports){\nmodule.exports=require(294)\n},{\"/Users/a/dev/faker.js/lib/locales/en_CA/address/postcode.js\":294}],328:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Andra Pradesh\",\n  \"Arunachal Pradesh\",\n  \"Assam\",\n  \"Bihar\",\n  \"Chhattisgarh\",\n  \"Goa\",\n  \"Gujarat\",\n  \"Haryana\",\n  \"Himachal Pradesh\",\n  \"Jammu and Kashmir\",\n  \"Jharkhand\",\n  \"Karnataka\",\n  \"Kerala\",\n  \"Madya Pradesh\",\n  \"Maharashtra\",\n  \"Manipur\",\n  \"Meghalaya\",\n  \"Mizoram\",\n  \"Nagaland\",\n  \"Orissa\",\n  \"Punjab\",\n  \"Rajasthan\",\n  \"Sikkim\",\n  \"Tamil Nadu\",\n  \"Tripura\",\n  \"Uttaranchal\",\n  \"Uttar Pradesh\",\n  \"West Bengal\",\n  \"Andaman and Nicobar Islands\",\n  \"Chandigarh\",\n  \"Dadar and Nagar Haveli\",\n  \"Daman and Diu\",\n  \"Delhi\",\n  \"Lakshadweep\",\n  \"Pondicherry\"\n];\n\n},{}],329:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AP\",\n  \"AR\",\n  \"AS\",\n  \"BR\",\n  \"CG\",\n  \"DL\",\n  \"GA\",\n  \"GJ\",\n  \"HR\",\n  \"HP\",\n  \"JK\",\n  \"JS\",\n  \"KA\",\n  \"KL\",\n  \"MP\",\n  \"MH\",\n  \"MN\",\n  \"ML\",\n  \"MZ\",\n  \"NL\",\n  \"OR\",\n  \"PB\",\n  \"RJ\",\n  \"SK\",\n  \"TN\",\n  \"TR\",\n  \"UK\",\n  \"UP\",\n  \"WB\",\n  \"AN\",\n  \"CH\",\n  \"DN\",\n  \"DD\",\n  \"LD\",\n  \"PY\"\n];\n\n},{}],330:[function(require,module,exports){\narguments[4][279][0].apply(exports,arguments)\n},{\"./suffix\":331,\"/Users/a/dev/faker.js/lib/locales/en_AU/company/index.js\":279}],331:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Pvt Ltd\",\n  \"Limited\",\n  \"Ltd\",\n  \"and Sons\",\n  \"Corp\",\n  \"Group\",\n  \"Brothers\"\n];\n\n},{}],332:[function(require,module,exports){\nvar en_IND = {};\nmodule['exports'] = en_IND;\nen_IND.title = \"India (English)\";\nen_IND.name = require(\"./name\");\nen_IND.address = require(\"./address\");\nen_IND.internet = require(\"./internet\");\nen_IND.company = require(\"./company\");\nen_IND.phone_number = require(\"./phone_number\");\n\n},{\"./address\":326,\"./company\":330,\"./internet\":335,\"./name\":337,\"./phone_number\":340}],333:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"in\",\n  \"com\",\n  \"biz\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\",\n  \"co.in\"\n];\n\n},{}],334:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.co.in\",\n  \"hotmail.com\"\n];\n\n},{}],335:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":333,\"./free_email\":334,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],336:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aadrika\",\n  \"Aanandinii\",\n  \"Aaratrika\",\n  \"Aarya\",\n  \"Arya\",\n  \"Aashritha\",\n  \"Aatmaja\",\n  \"Atmaja\",\n  \"Abhaya\",\n  \"Adwitiya\",\n  \"Agrata\",\n  \"Ahilya\",\n  \"Ahalya\",\n  \"Aishani\",\n  \"Akshainie\",\n  \"Akshata\",\n  \"Akshita\",\n  \"Akula\",\n  \"Ambar\",\n  \"Amodini\",\n  \"Amrita\",\n  \"Amritambu\",\n  \"Anala\",\n  \"Anamika\",\n  \"Ananda\",\n  \"Anandamayi\",\n  \"Ananta\",\n  \"Anila\",\n  \"Anjali\",\n  \"Anjushri\",\n  \"Anjushree\",\n  \"Annapurna\",\n  \"Anshula\",\n  \"Anuja\",\n  \"Anusuya\",\n  \"Anasuya\",\n  \"Anasooya\",\n  \"Anwesha\",\n  \"Apsara\",\n  \"Aruna\",\n  \"Asha\",\n  \"Aasa\",\n  \"Aasha\",\n  \"Aslesha\",\n  \"Atreyi\",\n  \"Atreyee\",\n  \"Avani\",\n  \"Abani\",\n  \"Avantika\",\n  \"Ayushmati\",\n  \"Baidehi\",\n  \"Vaidehi\",\n  \"Bala\",\n  \"Baala\",\n  \"Balamani\",\n  \"Basanti\",\n  \"Vasanti\",\n  \"Bela\",\n  \"Bhadra\",\n  \"Bhagirathi\",\n  \"Bhagwanti\",\n  \"Bhagwati\",\n  \"Bhamini\",\n  \"Bhanumati\",\n  \"Bhaanumati\",\n  \"Bhargavi\",\n  \"Bhavani\",\n  \"Bhilangana\",\n  \"Bilwa\",\n  \"Bilva\",\n  \"Buddhana\",\n  \"Chakrika\",\n  \"Chanda\",\n  \"Chandi\",\n  \"Chandni\",\n  \"Chandini\",\n  \"Chandani\",\n  \"Chandra\",\n  \"Chandira\",\n  \"Chandrabhaga\",\n  \"Chandrakala\",\n  \"Chandrakin\",\n  \"Chandramani\",\n  \"Chandrani\",\n  \"Chandraprabha\",\n  \"Chandraswaroopa\",\n  \"Chandravati\",\n  \"Chapala\",\n  \"Charumati\",\n  \"Charvi\",\n  \"Chatura\",\n  \"Chitrali\",\n  \"Chitramala\",\n  \"Chitrangada\",\n  \"Daksha\",\n  \"Dakshayani\",\n  \"Damayanti\",\n  \"Darshwana\",\n  \"Deepali\",\n  \"Dipali\",\n  \"Deeptimoyee\",\n  \"Deeptimayee\",\n  \"Devangana\",\n  \"Devani\",\n  \"Devasree\",\n  \"Devi\",\n  \"Daevi\",\n  \"Devika\",\n  \"Daevika\",\n  \"Dhaanyalakshmi\",\n  \"Dhanalakshmi\",\n  \"Dhana\",\n  \"Dhanadeepa\",\n  \"Dhara\",\n  \"Dharani\",\n  \"Dharitri\",\n  \"Dhatri\",\n  \"Diksha\",\n  \"Deeksha\",\n  \"Divya\",\n  \"Draupadi\",\n  \"Dulari\",\n  \"Durga\",\n  \"Durgeshwari\",\n  \"Ekaparnika\",\n  \"Elakshi\",\n  \"Enakshi\",\n  \"Esha\",\n  \"Eshana\",\n  \"Eshita\",\n  \"Gautami\",\n  \"Gayatri\",\n  \"Geeta\",\n  \"Geetanjali\",\n  \"Gitanjali\",\n  \"Gemine\",\n  \"Gemini\",\n  \"Girja\",\n  \"Girija\",\n  \"Gita\",\n  \"Hamsini\",\n  \"Harinakshi\",\n  \"Harita\",\n  \"Heema\",\n  \"Himadri\",\n  \"Himani\",\n  \"Hiranya\",\n  \"Indira\",\n  \"Jaimini\",\n  \"Jaya\",\n  \"Jyoti\",\n  \"Jyotsana\",\n  \"Kali\",\n  \"Kalinda\",\n  \"Kalpana\",\n  \"Kalyani\",\n  \"Kama\",\n  \"Kamala\",\n  \"Kamla\",\n  \"Kanchan\",\n  \"Kanishka\",\n  \"Kanti\",\n  \"Kashyapi\",\n  \"Kumari\",\n  \"Kumuda\",\n  \"Lakshmi\",\n  \"Laxmi\",\n  \"Lalita\",\n  \"Lavanya\",\n  \"Leela\",\n  \"Lila\",\n  \"Leela\",\n  \"Madhuri\",\n  \"Malti\",\n  \"Malati\",\n  \"Mandakini\",\n  \"Mandaakin\",\n  \"Mangala\",\n  \"Mangalya\",\n  \"Mani\",\n  \"Manisha\",\n  \"Manjusha\",\n  \"Meena\",\n  \"Mina\",\n  \"Meenakshi\",\n  \"Minakshi\",\n  \"Menka\",\n  \"Menaka\",\n  \"Mohana\",\n  \"Mohini\",\n  \"Nalini\",\n  \"Nikita\",\n  \"Ojaswini\",\n  \"Omana\",\n  \"Oormila\",\n  \"Urmila\",\n  \"Opalina\",\n  \"Opaline\",\n  \"Padma\",\n  \"Parvati\",\n  \"Poornima\",\n  \"Purnima\",\n  \"Pramila\",\n  \"Prasanna\",\n  \"Preity\",\n  \"Prema\",\n  \"Priya\",\n  \"Priyala\",\n  \"Pushti\",\n  \"Radha\",\n  \"Rageswari\",\n  \"Rageshwari\",\n  \"Rajinder\",\n  \"Ramaa\",\n  \"Rati\",\n  \"Rita\",\n  \"Rohana\",\n  \"Rukhmani\",\n  \"Rukmin\",\n  \"Rupinder\",\n  \"Sanya\",\n  \"Sarada\",\n  \"Sharda\",\n  \"Sarala\",\n  \"Sarla\",\n  \"Saraswati\",\n  \"Sarisha\",\n  \"Saroja\",\n  \"Shakti\",\n  \"Shakuntala\",\n  \"Shanti\",\n  \"Sharmila\",\n  \"Shashi\",\n  \"Shashikala\",\n  \"Sheela\",\n  \"Shivakari\",\n  \"Shobhana\",\n  \"Shresth\",\n  \"Shresthi\",\n  \"Shreya\",\n  \"Shreyashi\",\n  \"Shridevi\",\n  \"Shrishti\",\n  \"Shubha\",\n  \"Shubhaprada\",\n  \"Siddhi\",\n  \"Sitara\",\n  \"Sloka\",\n  \"Smita\",\n  \"Smriti\",\n  \"Soma\",\n  \"Subhashini\",\n  \"Subhasini\",\n  \"Sucheta\",\n  \"Sudeva\",\n  \"Sujata\",\n  \"Sukanya\",\n  \"Suma\",\n  \"Suma\",\n  \"Sumitra\",\n  \"Sunita\",\n  \"Suryakantam\",\n  \"Sushma\",\n  \"Swara\",\n  \"Swarnalata\",\n  \"Sweta\",\n  \"Shwet\",\n  \"Tanirika\",\n  \"Tanushree\",\n  \"Tanushri\",\n  \"Tanushri\",\n  \"Tanya\",\n  \"Tara\",\n  \"Trisha\",\n  \"Uma\",\n  \"Usha\",\n  \"Vaijayanti\",\n  \"Vaijayanthi\",\n  \"Baijayanti\",\n  \"Vaishvi\",\n  \"Vaishnavi\",\n  \"Vaishno\",\n  \"Varalakshmi\",\n  \"Vasudha\",\n  \"Vasundhara\",\n  \"Veda\",\n  \"Vedanshi\",\n  \"Vidya\",\n  \"Vimala\",\n  \"Vrinda\",\n  \"Vrund\",\n  \"Aadi\",\n  \"Aadidev\",\n  \"Aadinath\",\n  \"Aaditya\",\n  \"Aagam\",\n  \"Aagney\",\n  \"Aamod\",\n  \"Aanandaswarup\",\n  \"Anand Swarup\",\n  \"Aanjaneya\",\n  \"Anjaneya\",\n  \"Aaryan\",\n  \"Aryan\",\n  \"Aatmaj\",\n  \"Aatreya\",\n  \"Aayushmaan\",\n  \"Aayushman\",\n  \"Abhaidev\",\n  \"Abhaya\",\n  \"Abhirath\",\n  \"Abhisyanta\",\n  \"Acaryatanaya\",\n  \"Achalesvara\",\n  \"Acharyanandana\",\n  \"Acharyasuta\",\n  \"Achintya\",\n  \"Achyut\",\n  \"Adheesh\",\n  \"Adhiraj\",\n  \"Adhrit\",\n  \"Adikavi\",\n  \"Adinath\",\n  \"Aditeya\",\n  \"Aditya\",\n  \"Adityanandan\",\n  \"Adityanandana\",\n  \"Adripathi\",\n  \"Advaya\",\n  \"Agasti\",\n  \"Agastya\",\n  \"Agneya\",\n  \"Aagneya\",\n  \"Agnimitra\",\n  \"Agniprava\",\n  \"Agnivesh\",\n  \"Agrata\",\n  \"Ajit\",\n  \"Ajeet\",\n  \"Akroor\",\n  \"Akshaj\",\n  \"Akshat\",\n  \"Akshayakeerti\",\n  \"Alok\",\n  \"Aalok\",\n  \"Amaranaath\",\n  \"Amarnath\",\n  \"Amaresh\",\n  \"Ambar\",\n  \"Ameyatma\",\n  \"Amish\",\n  \"Amogh\",\n  \"Amrit\",\n  \"Anaadi\",\n  \"Anagh\",\n  \"Anal\",\n  \"Anand\",\n  \"Aanand\",\n  \"Anang\",\n  \"Anil\",\n  \"Anilaabh\",\n  \"Anilabh\",\n  \"Anish\",\n  \"Ankal\",\n  \"Anunay\",\n  \"Anurag\",\n  \"Anuraag\",\n  \"Archan\",\n  \"Arindam\",\n  \"Arjun\",\n  \"Arnesh\",\n  \"Arun\",\n  \"Ashlesh\",\n  \"Ashok\",\n  \"Atmanand\",\n  \"Atmananda\",\n  \"Avadhesh\",\n  \"Baalaaditya\",\n  \"Baladitya\",\n  \"Baalagopaal\",\n  \"Balgopal\",\n  \"Balagopal\",\n  \"Bahula\",\n  \"Bakula\",\n  \"Bala\",\n  \"Balaaditya\",\n  \"Balachandra\",\n  \"Balagovind\",\n  \"Bandhu\",\n  \"Bandhul\",\n  \"Bankim\",\n  \"Bankimchandra\",\n  \"Bhadrak\",\n  \"Bhadraksh\",\n  \"Bhadran\",\n  \"Bhagavaan\",\n  \"Bhagvan\",\n  \"Bharadwaj\",\n  \"Bhardwaj\",\n  \"Bharat\",\n  \"Bhargava\",\n  \"Bhasvan\",\n  \"Bhaasvan\",\n  \"Bhaswar\",\n  \"Bhaaswar\",\n  \"Bhaumik\",\n  \"Bhaves\",\n  \"Bheeshma\",\n  \"Bhisham\",\n  \"Bhishma\",\n  \"Bhima\",\n  \"Bhoj\",\n  \"Bhramar\",\n  \"Bhudev\",\n  \"Bhudeva\",\n  \"Bhupati\",\n  \"Bhoopati\",\n  \"Bhoopat\",\n  \"Bhupen\",\n  \"Bhushan\",\n  \"Bhooshan\",\n  \"Bhushit\",\n  \"Bhooshit\",\n  \"Bhuvanesh\",\n  \"Bhuvaneshwar\",\n  \"Bilva\",\n  \"Bodhan\",\n  \"Brahma\",\n  \"Brahmabrata\",\n  \"Brahmanandam\",\n  \"Brahmaanand\",\n  \"Brahmdev\",\n  \"Brajendra\",\n  \"Brajesh\",\n  \"Brijesh\",\n  \"Birjesh\",\n  \"Budhil\",\n  \"Chakor\",\n  \"Chakradhar\",\n  \"Chakravartee\",\n  \"Chakravarti\",\n  \"Chanakya\",\n  \"Chaanakya\",\n  \"Chandak\",\n  \"Chandan\",\n  \"Chandra\",\n  \"Chandraayan\",\n  \"Chandrabhan\",\n  \"Chandradev\",\n  \"Chandraketu\",\n  \"Chandramauli\",\n  \"Chandramohan\",\n  \"Chandran\",\n  \"Chandranath\",\n  \"Chapal\",\n  \"Charak\",\n  \"Charuchandra\",\n  \"Chaaruchandra\",\n  \"Charuvrat\",\n  \"Chatur\",\n  \"Chaturaanan\",\n  \"Chaturbhuj\",\n  \"Chetan\",\n  \"Chaten\",\n  \"Chaitan\",\n  \"Chetanaanand\",\n  \"Chidaakaash\",\n  \"Chidaatma\",\n  \"Chidambar\",\n  \"Chidambaram\",\n  \"Chidananda\",\n  \"Chinmayanand\",\n  \"Chinmayananda\",\n  \"Chiranjeev\",\n  \"Chiranjeeve\",\n  \"Chitraksh\",\n  \"Daiwik\",\n  \"Daksha\",\n  \"Damodara\",\n  \"Dandak\",\n  \"Dandapaani\",\n  \"Darshan\",\n  \"Datta\",\n  \"Dayaamay\",\n  \"Dayamayee\",\n  \"Dayaananda\",\n  \"Dayaanidhi\",\n  \"Kin\",\n  \"Deenabandhu\",\n  \"Deepan\",\n  \"Deepankar\",\n  \"Dipankar\",\n  \"Deependra\",\n  \"Dipendra\",\n  \"Deepesh\",\n  \"Dipesh\",\n  \"Deeptanshu\",\n  \"Deeptendu\",\n  \"Diptendu\",\n  \"Deeptiman\",\n  \"Deeptimoy\",\n  \"Deeptimay\",\n  \"Dev\",\n  \"Deb\",\n  \"Devadatt\",\n  \"Devagya\",\n  \"Devajyoti\",\n  \"Devak\",\n  \"Devdan\",\n  \"Deven\",\n  \"Devesh\",\n  \"Deveshwar\",\n  \"Devi\",\n  \"Devvrat\",\n  \"Dhananjay\",\n  \"Dhanapati\",\n  \"Dhanpati\",\n  \"Dhanesh\",\n  \"Dhanu\",\n  \"Dhanvin\",\n  \"Dharmaketu\",\n  \"Dhruv\",\n  \"Dhyanesh\",\n  \"Dhyaneshwar\",\n  \"Digambar\",\n  \"Digambara\",\n  \"Dinakar\",\n  \"Dinkar\",\n  \"Dinesh\",\n  \"Divaakar\",\n  \"Divakar\",\n  \"Deevakar\",\n  \"Divjot\",\n  \"Dron\",\n  \"Drona\",\n  \"Dwaipayan\",\n  \"Dwaipayana\",\n  \"Eekalabya\",\n  \"Ekalavya\",\n  \"Ekaksh\",\n  \"Ekaaksh\",\n  \"Ekaling\",\n  \"Ekdant\",\n  \"Ekadant\",\n  \"Gajaadhar\",\n  \"Gajadhar\",\n  \"Gajbaahu\",\n  \"Gajabahu\",\n  \"Ganak\",\n  \"Ganaka\",\n  \"Ganapati\",\n  \"Gandharv\",\n  \"Gandharva\",\n  \"Ganesh\",\n  \"Gangesh\",\n  \"Garud\",\n  \"Garuda\",\n  \"Gati\",\n  \"Gatik\",\n  \"Gaurang\",\n  \"Gauraang\",\n  \"Gauranga\",\n  \"Gouranga\",\n  \"Gautam\",\n  \"Gautama\",\n  \"Goutam\",\n  \"Ghanaanand\",\n  \"Ghanshyam\",\n  \"Ghanashyam\",\n  \"Giri\",\n  \"Girik\",\n  \"Girika\",\n  \"Girindra\",\n  \"Giriraaj\",\n  \"Giriraj\",\n  \"Girish\",\n  \"Gopal\",\n  \"Gopaal\",\n  \"Gopi\",\n  \"Gopee\",\n  \"Gorakhnath\",\n  \"Gorakhanatha\",\n  \"Goswamee\",\n  \"Goswami\",\n  \"Gotum\",\n  \"Gautam\",\n  \"Govinda\",\n  \"Gobinda\",\n  \"Gudakesha\",\n  \"Gudakesa\",\n  \"Gurdev\",\n  \"Guru\",\n  \"Hari\",\n  \"Harinarayan\",\n  \"Harit\",\n  \"Himadri\",\n  \"Hiranmay\",\n  \"Hiranmaya\",\n  \"Hiranya\",\n  \"Inder\",\n  \"Indra\",\n  \"Indra\",\n  \"Jagadish\",\n  \"Jagadisha\",\n  \"Jagathi\",\n  \"Jagdeep\",\n  \"Jagdish\",\n  \"Jagmeet\",\n  \"Jahnu\",\n  \"Jai\",\n  \"Javas\",\n  \"Jay\",\n  \"Jitendra\",\n  \"Jitender\",\n  \"Jyotis\",\n  \"Kailash\",\n  \"Kama\",\n  \"Kamalesh\",\n  \"Kamlesh\",\n  \"Kanak\",\n  \"Kanaka\",\n  \"Kannan\",\n  \"Kannen\",\n  \"Karan\",\n  \"Karthik\",\n  \"Kartik\",\n  \"Karunanidhi\",\n  \"Kashyap\",\n  \"Kiran\",\n  \"Kirti\",\n  \"Keerti\",\n  \"Krishna\",\n  \"Krishnadas\",\n  \"Krishnadasa\",\n  \"Kumar\",\n  \"Lai\",\n  \"Lakshman\",\n  \"Laxman\",\n  \"Lakshmidhar\",\n  \"Lakshminath\",\n  \"Lal\",\n  \"Laal\",\n  \"Mahendra\",\n  \"Mohinder\",\n  \"Mahesh\",\n  \"Maheswar\",\n  \"Mani\",\n  \"Manik\",\n  \"Manikya\",\n  \"Manoj\",\n  \"Marut\",\n  \"Mayoor\",\n  \"Meghnad\",\n  \"Meghnath\",\n  \"Mohan\",\n  \"Mukesh\",\n  \"Mukul\",\n  \"Nagabhushanam\",\n  \"Nanda\",\n  \"Narayan\",\n  \"Narendra\",\n  \"Narinder\",\n  \"Naveen\",\n  \"Navin\",\n  \"Nawal\",\n  \"Naval\",\n  \"Nimit\",\n  \"Niranjan\",\n  \"Nirbhay\",\n  \"Niro\",\n  \"Param\",\n  \"Paramartha\",\n  \"Pran\",\n  \"Pranay\",\n  \"Prasad\",\n  \"Prathamesh\",\n  \"Prayag\",\n  \"Prem\",\n  \"Puneet\",\n  \"Purushottam\",\n  \"Rahul\",\n  \"Raj\",\n  \"Rajan\",\n  \"Rajendra\",\n  \"Rajinder\",\n  \"Rajiv\",\n  \"Rakesh\",\n  \"Ramesh\",\n  \"Rameshwar\",\n  \"Ranjit\",\n  \"Ranjeet\",\n  \"Ravi\",\n  \"Ritesh\",\n  \"Rohan\",\n  \"Rohit\",\n  \"Rudra\",\n  \"Sachin\",\n  \"Sameer\",\n  \"Samir\",\n  \"Sanjay\",\n  \"Sanka\",\n  \"Sarvin\",\n  \"Satish\",\n  \"Satyen\",\n  \"Shankar\",\n  \"Shantanu\",\n  \"Shashi\",\n  \"Sher\",\n  \"Shiv\",\n  \"Siddarth\",\n  \"Siddhran\",\n  \"Som\",\n  \"Somu\",\n  \"Somnath\",\n  \"Subhash\",\n  \"Subodh\",\n  \"Suman\",\n  \"Suresh\",\n  \"Surya\",\n  \"Suryakant\",\n  \"Suryakanta\",\n  \"Sushil\",\n  \"Susheel\",\n  \"Swami\",\n  \"Swapnil\",\n  \"Tapan\",\n  \"Tara\",\n  \"Tarun\",\n  \"Tej\",\n  \"Tejas\",\n  \"Trilochan\",\n  \"Trilochana\",\n  \"Trilok\",\n  \"Trilokesh\",\n  \"Triloki\",\n  \"Triloki Nath\",\n  \"Trilokanath\",\n  \"Tushar\",\n  \"Udai\",\n  \"Udit\",\n  \"Ujjawal\",\n  \"Ujjwal\",\n  \"Umang\",\n  \"Upendra\",\n  \"Uttam\",\n  \"Vasudev\",\n  \"Vasudeva\",\n  \"Vedang\",\n  \"Vedanga\",\n  \"Vidhya\",\n  \"Vidur\",\n  \"Vidhur\",\n  \"Vijay\",\n  \"Vimal\",\n  \"Vinay\",\n  \"Vishnu\",\n  \"Bishnu\",\n  \"Vishwamitra\",\n  \"Vyas\",\n  \"Yogendra\",\n  \"Yoginder\",\n  \"Yogesh\"\n];\n\n},{}],337:[function(require,module,exports){\narguments[4][285][0].apply(exports,arguments)\n},{\"./first_name\":336,\"./last_name\":338,\"/Users/a/dev/faker.js/lib/locales/en_AU/name/index.js\":285}],338:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abbott\",\n  \"Achari\",\n  \"Acharya\",\n  \"Adiga\",\n  \"Agarwal\",\n  \"Ahluwalia\",\n  \"Ahuja\",\n  \"Arora\",\n  \"Asan\",\n  \"Bandopadhyay\",\n  \"Banerjee\",\n  \"Bharadwaj\",\n  \"Bhat\",\n  \"Butt\",\n  \"Bhattacharya\",\n  \"Bhattathiri\",\n  \"Chaturvedi\",\n  \"Chattopadhyay\",\n  \"Chopra\",\n  \"Desai\",\n  \"Deshpande\",\n  \"Devar\",\n  \"Dhawan\",\n  \"Dubashi\",\n  \"Dutta\",\n  \"Dwivedi\",\n  \"Embranthiri\",\n  \"Ganaka\",\n  \"Gandhi\",\n  \"Gill\",\n  \"Gowda\",\n  \"Guha\",\n  \"Guneta\",\n  \"Gupta\",\n  \"Iyer\",\n  \"Iyengar\",\n  \"Jain\",\n  \"Jha\",\n  \"Johar\",\n  \"Joshi\",\n  \"Kakkar\",\n  \"Kaniyar\",\n  \"Kapoor\",\n  \"Kaul\",\n  \"Kaur\",\n  \"Khan\",\n  \"Khanna\",\n  \"Khatri\",\n  \"Kocchar\",\n  \"Mahajan\",\n  \"Malik\",\n  \"Marar\",\n  \"Menon\",\n  \"Mehra\",\n  \"Mehrotra\",\n  \"Mishra\",\n  \"Mukhopadhyay\",\n  \"Nayar\",\n  \"Naik\",\n  \"Nair\",\n  \"Nambeesan\",\n  \"Namboothiri\",\n  \"Nehru\",\n  \"Pandey\",\n  \"Panicker\",\n  \"Patel\",\n  \"Patil\",\n  \"Pilla\",\n  \"Pillai\",\n  \"Pothuvaal\",\n  \"Prajapat\",\n  \"Rana\",\n  \"Reddy\",\n  \"Saini\",\n  \"Sethi\",\n  \"Shah\",\n  \"Sharma\",\n  \"Shukla\",\n  \"Singh\",\n  \"Sinha\",\n  \"Somayaji\",\n  \"Tagore\",\n  \"Talwar\",\n  \"Tandon\",\n  \"Trivedi\",\n  \"Varrier\",\n  \"Varma\",\n  \"Varman\",\n  \"Verma\"\n];\n\n},{}],339:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"+91###-###-####\",\n  \"+91##########\",\n  \"+91-###-#######\"\n];\n\n},{}],340:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":339,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],341:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"United States\",\n  \"United States of America\",\n  \"USA\"\n];\n\n},{}],342:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.default_country = require(\"./default_country\");\naddress.postcode_by_state = require(\"./postcode_by_state\");\n\n},{\"./default_country\":341,\"./postcode_by_state\":343}],343:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"AL\": \"350##\",\n  \"AK\": \"995##\",\n  \"AS\": \"967##\",\n  \"AZ\": \"850##\",\n  \"AR\": \"717##\",\n  \"CA\": \"900##\",\n  \"CO\": \"800##\",\n  \"CT\": \"061##\",\n  \"DC\": \"204##\",\n  \"DE\": \"198##\",\n  \"FL\": \"322##\",\n  \"GA\": \"301##\",\n  \"HI\": \"967##\",\n  \"ID\": \"832##\",\n  \"IL\": \"600##\",\n  \"IN\": \"463##\",\n  \"IA\": \"510##\",\n  \"KS\": \"666##\",\n  \"KY\": \"404##\",\n  \"LA\": \"701##\",\n  \"ME\": \"042##\",\n  \"MD\": \"210##\",\n  \"MA\": \"026##\",\n  \"MI\": \"480##\",\n  \"MN\": \"555##\",\n  \"MS\": \"387##\",\n  \"MO\": \"650##\",\n  \"MT\": \"590##\",\n  \"NE\": \"688##\",\n  \"NV\": \"898##\",\n  \"NH\": \"036##\",\n  \"NJ\": \"076##\",\n  \"NM\": \"880##\",\n  \"NY\": \"122##\",\n  \"NC\": \"288##\",\n  \"ND\": \"586##\",\n  \"OH\": \"444##\",\n  \"OK\": \"730##\",\n  \"OR\": \"979##\",\n  \"PA\": \"186##\",\n  \"RI\": \"029##\",\n  \"SC\": \"299##\",\n  \"SD\": \"577##\",\n  \"TN\": \"383##\",\n  \"TX\": \"798##\",\n  \"UT\": \"847##\",\n  \"VT\": \"050##\",\n  \"VA\": \"222##\",\n  \"WA\": \"990##\",\n  \"WV\": \"247##\",\n  \"WI\": \"549##\",\n  \"WY\": \"831##\"\n};\n\n},{}],344:[function(require,module,exports){\nvar en_US = {};\nmodule['exports'] = en_US;\nen_US.title = \"United States (English)\";\nen_US.internet = require(\"./internet\");\nen_US.address = require(\"./address\");\nen_US.phone_number = require(\"./phone_number\");\n\n},{\"./address\":342,\"./internet\":346,\"./phone_number\":349}],345:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"us\",\n  \"biz\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\"\n];\n\n},{}],346:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":345,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],347:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"201\",\n  \"202\",\n  \"203\",\n  \"205\",\n  \"206\",\n  \"207\",\n  \"208\",\n  \"209\",\n  \"210\",\n  \"212\",\n  \"213\",\n  \"214\",\n  \"215\",\n  \"216\",\n  \"217\",\n  \"218\",\n  \"219\",\n  \"224\",\n  \"225\",\n  \"227\",\n  \"228\",\n  \"229\",\n  \"231\",\n  \"234\",\n  \"239\",\n  \"240\",\n  \"248\",\n  \"251\",\n  \"252\",\n  \"253\",\n  \"254\",\n  \"256\",\n  \"260\",\n  \"262\",\n  \"267\",\n  \"269\",\n  \"270\",\n  \"276\",\n  \"281\",\n  \"283\",\n  \"301\",\n  \"302\",\n  \"303\",\n  \"304\",\n  \"305\",\n  \"307\",\n  \"308\",\n  \"309\",\n  \"310\",\n  \"312\",\n  \"313\",\n  \"314\",\n  \"315\",\n  \"316\",\n  \"317\",\n  \"318\",\n  \"319\",\n  \"320\",\n  \"321\",\n  \"323\",\n  \"330\",\n  \"331\",\n  \"334\",\n  \"336\",\n  \"337\",\n  \"339\",\n  \"347\",\n  \"351\",\n  \"352\",\n  \"360\",\n  \"361\",\n  \"386\",\n  \"401\",\n  \"402\",\n  \"404\",\n  \"405\",\n  \"406\",\n  \"407\",\n  \"408\",\n  \"409\",\n  \"410\",\n  \"412\",\n  \"413\",\n  \"414\",\n  \"415\",\n  \"417\",\n  \"419\",\n  \"423\",\n  \"424\",\n  \"425\",\n  \"434\",\n  \"435\",\n  \"440\",\n  \"443\",\n  \"445\",\n  \"464\",\n  \"469\",\n  \"470\",\n  \"475\",\n  \"478\",\n  \"479\",\n  \"480\",\n  \"484\",\n  \"501\",\n  \"502\",\n  \"503\",\n  \"504\",\n  \"505\",\n  \"507\",\n  \"508\",\n  \"509\",\n  \"510\",\n  \"512\",\n  \"513\",\n  \"515\",\n  \"516\",\n  \"517\",\n  \"518\",\n  \"520\",\n  \"530\",\n  \"540\",\n  \"541\",\n  \"551\",\n  \"557\",\n  \"559\",\n  \"561\",\n  \"562\",\n  \"563\",\n  \"564\",\n  \"567\",\n  \"570\",\n  \"571\",\n  \"573\",\n  \"574\",\n  \"580\",\n  \"585\",\n  \"586\",\n  \"601\",\n  \"602\",\n  \"603\",\n  \"605\",\n  \"606\",\n  \"607\",\n  \"608\",\n  \"609\",\n  \"610\",\n  \"612\",\n  \"614\",\n  \"615\",\n  \"616\",\n  \"617\",\n  \"618\",\n  \"619\",\n  \"620\",\n  \"623\",\n  \"626\",\n  \"630\",\n  \"631\",\n  \"636\",\n  \"641\",\n  \"646\",\n  \"650\",\n  \"651\",\n  \"660\",\n  \"661\",\n  \"662\",\n  \"667\",\n  \"678\",\n  \"682\",\n  \"701\",\n  \"702\",\n  \"703\",\n  \"704\",\n  \"706\",\n  \"707\",\n  \"708\",\n  \"712\",\n  \"713\",\n  \"714\",\n  \"715\",\n  \"716\",\n  \"717\",\n  \"718\",\n  \"719\",\n  \"720\",\n  \"724\",\n  \"727\",\n  \"731\",\n  \"732\",\n  \"734\",\n  \"737\",\n  \"740\",\n  \"754\",\n  \"757\",\n  \"760\",\n  \"763\",\n  \"765\",\n  \"770\",\n  \"772\",\n  \"773\",\n  \"774\",\n  \"775\",\n  \"781\",\n  \"785\",\n  \"786\",\n  \"801\",\n  \"802\",\n  \"803\",\n  \"804\",\n  \"805\",\n  \"806\",\n  \"808\",\n  \"810\",\n  \"812\",\n  \"813\",\n  \"814\",\n  \"815\",\n  \"816\",\n  \"817\",\n  \"818\",\n  \"828\",\n  \"830\",\n  \"831\",\n  \"832\",\n  \"835\",\n  \"843\",\n  \"845\",\n  \"847\",\n  \"848\",\n  \"850\",\n  \"856\",\n  \"857\",\n  \"858\",\n  \"859\",\n  \"860\",\n  \"862\",\n  \"863\",\n  \"864\",\n  \"865\",\n  \"870\",\n  \"872\",\n  \"878\",\n  \"901\",\n  \"903\",\n  \"904\",\n  \"906\",\n  \"907\",\n  \"908\",\n  \"909\",\n  \"910\",\n  \"912\",\n  \"913\",\n  \"914\",\n  \"915\",\n  \"916\",\n  \"917\",\n  \"918\",\n  \"919\",\n  \"920\",\n  \"925\",\n  \"928\",\n  \"931\",\n  \"936\",\n  \"937\",\n  \"940\",\n  \"941\",\n  \"947\",\n  \"949\",\n  \"952\",\n  \"954\",\n  \"956\",\n  \"959\",\n  \"970\",\n  \"971\",\n  \"972\",\n  \"973\",\n  \"975\",\n  \"978\",\n  \"979\",\n  \"980\",\n  \"984\",\n  \"985\",\n  \"989\"\n];\n\n},{}],348:[function(require,module,exports){\nmodule.exports=require(347)\n},{\"/Users/a/dev/faker.js/lib/locales/en_US/phone_number/area_code.js\":347}],349:[function(require,module,exports){\nvar phone_number = {};\nmodule['exports'] = phone_number;\nphone_number.area_code = require(\"./area_code\");\nphone_number.exchange_code = require(\"./exchange_code\");\n\n},{\"./area_code\":347,\"./exchange_code\":348}],350:[function(require,module,exports){\nmodule.exports=require(272)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/address/building_number.js\":272}],351:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_prefix}\"\n];\n\n},{}],352:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Bondi\",\n  \"Burleigh Heads\",\n  \"Carlton\",\n  \"Fitzroy\",\n  \"Fremantle\",\n  \"Glenelg\",\n  \"Manly\",\n  \"Noosa\",\n  \"Stones Corner\",\n  \"St Kilda\",\n  \"Surry Hills\",\n  \"Yarra Valley\"\n];\n\n},{}],353:[function(require,module,exports){\nmodule.exports=require(273)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/address/default_country.js\":273}],354:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.street_root = require(\"./street_root\");\naddress.street_name = require(\"./street_name\");\naddress.city_prefix = require(\"./city_prefix\");\naddress.city = require(\"./city\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.region = require(\"./region\");\naddress.state = require(\"./state\");\naddress.postcode = require(\"./postcode\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":350,\"./city\":351,\"./city_prefix\":352,\"./default_country\":353,\"./postcode\":355,\"./region\":356,\"./state\":357,\"./state_abbr\":358,\"./street_name\":359,\"./street_root\":360,\"./street_suffix\":361}],355:[function(require,module,exports){\nmodule.exports=require(275)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/address/postcode.js\":275}],356:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"South East Queensland\",\n  \"Wide Bay Burnett\",\n  \"Margaret River\",\n  \"Port Pirie\",\n  \"Gippsland\",\n  \"Elizabeth\",\n  \"Barossa\"\n];\n\n},{}],357:[function(require,module,exports){\nmodule.exports=require(276)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/address/state.js\":276}],358:[function(require,module,exports){\nmodule.exports=require(277)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/address/state_abbr.js\":277}],359:[function(require,module,exports){\nmodule.exports=require(109)\n},{\"/Users/a/dev/faker.js/lib/locales/de/address/street_name.js\":109}],360:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ramsay Street\",\n  \"Bonnie Doon\",\n  \"Cavill Avenue\",\n  \"Queen Street\"\n];\n\n},{}],361:[function(require,module,exports){\nmodule.exports=require(278)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/address/street_suffix.js\":278}],362:[function(require,module,exports){\nmodule.exports=require(279)\n},{\"./suffix\":363,\"/Users/a/dev/faker.js/lib/locales/en_AU/company/index.js\":279}],363:[function(require,module,exports){\nmodule.exports=require(280)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/company/suffix.js\":280}],364:[function(require,module,exports){\nvar en_au_ocker = {};\nmodule['exports'] = en_au_ocker;\nen_au_ocker.title = \"Australia Ocker (English)\";\nen_au_ocker.name = require(\"./name\");\nen_au_ocker.company = require(\"./company\");\nen_au_ocker.internet = require(\"./internet\");\nen_au_ocker.address = require(\"./address\");\nen_au_ocker.phone_number = require(\"./phone_number\");\n\n},{\"./address\":354,\"./company\":362,\"./internet\":366,\"./name\":368,\"./phone_number\":372}],365:[function(require,module,exports){\nmodule.exports=require(282)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/internet/domain_suffix.js\":282}],366:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":365,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],367:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Charlotte\",\n  \"Ava\",\n  \"Chloe\",\n  \"Emily\",\n  \"Olivia\",\n  \"Zoe\",\n  \"Lily\",\n  \"Sophie\",\n  \"Amelia\",\n  \"Sofia\",\n  \"Ella\",\n  \"Isabella\",\n  \"Ruby\",\n  \"Sienna\",\n  \"Mia+3\",\n  \"Grace\",\n  \"Emma\",\n  \"Ivy\",\n  \"Layla\",\n  \"Abigail\",\n  \"Isla\",\n  \"Hannah\",\n  \"Zara\",\n  \"Lucy\",\n  \"Evie\",\n  \"Annabelle\",\n  \"Madison\",\n  \"Alice\",\n  \"Georgia\",\n  \"Maya\",\n  \"Madeline\",\n  \"Audrey\",\n  \"Scarlett\",\n  \"Isabelle\",\n  \"Chelsea\",\n  \"Mila\",\n  \"Holly\",\n  \"Indiana\",\n  \"Poppy\",\n  \"Harper\",\n  \"Sarah\",\n  \"Alyssa\",\n  \"Jasmine\",\n  \"Imogen\",\n  \"Hayley\",\n  \"Pheobe\",\n  \"Eva\",\n  \"Evelyn\",\n  \"Mackenzie\",\n  \"Ayla\",\n  \"Oliver\",\n  \"Jack\",\n  \"Jackson\",\n  \"William\",\n  \"Ethan\",\n  \"Charlie\",\n  \"Lucas\",\n  \"Cooper\",\n  \"Lachlan\",\n  \"Noah\",\n  \"Liam\",\n  \"Alexander\",\n  \"Max\",\n  \"Isaac\",\n  \"Thomas\",\n  \"Xavier\",\n  \"Oscar\",\n  \"Benjamin\",\n  \"Aiden\",\n  \"Mason\",\n  \"Samuel\",\n  \"James\",\n  \"Levi\",\n  \"Riley\",\n  \"Harrison\",\n  \"Ryan\",\n  \"Henry\",\n  \"Jacob\",\n  \"Joshua\",\n  \"Leo\",\n  \"Zach\",\n  \"Harry\",\n  \"Hunter\",\n  \"Flynn\",\n  \"Archie\",\n  \"Tyler\",\n  \"Elijah\",\n  \"Hayden\",\n  \"Jayden\",\n  \"Blake\",\n  \"Archer\",\n  \"Ashton\",\n  \"Sebastian\",\n  \"Zachery\",\n  \"Lincoln\",\n  \"Mitchell\",\n  \"Luca\",\n  \"Nathan\",\n  \"Kai\",\n  \"Connor\",\n  \"Tom\",\n  \"Nigel\",\n  \"Matt\",\n  \"Sean\"\n];\n\n},{}],368:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.ocker_first_name = require(\"./ocker_first_name\");\n\n},{\"./first_name\":367,\"./last_name\":369,\"./ocker_first_name\":370}],369:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Smith\",\n  \"Jones\",\n  \"Williams\",\n  \"Brown\",\n  \"Wilson\",\n  \"Taylor\",\n  \"Morton\",\n  \"White\",\n  \"Martin\",\n  \"Anderson\",\n  \"Thompson\",\n  \"Nguyen\",\n  \"Thomas\",\n  \"Walker\",\n  \"Harris\",\n  \"Lee\",\n  \"Ryan\",\n  \"Robinson\",\n  \"Kelly\",\n  \"King\",\n  \"Rausch\",\n  \"Ridge\",\n  \"Connolly\",\n  \"LeQuesne\"\n];\n\n},{}],370:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Bazza\",\n  \"Bluey\",\n  \"Davo\",\n  \"Johno\",\n  \"Shano\",\n  \"Shazza\"\n];\n\n},{}],371:[function(require,module,exports){\nmodule.exports=require(287)\n},{\"/Users/a/dev/faker.js/lib/locales/en_AU/phone_number/formats.js\":287}],372:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":371,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],373:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \" s/n.\",\n  \", #\",\n  \", ##\",\n  \" #\",\n  \" ##\"\n];\n\n},{}],374:[function(require,module,exports){\nmodule.exports=require(351)\n},{\"/Users/a/dev/faker.js/lib/locales/en_au_ocker/address/city.js\":351}],375:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Parla\",\n  \"Telde\",\n  \"Baracaldo\",\n  \"San Fernando\",\n  \"Torrevieja\",\n  \"Lugo\",\n  \"Santiago de Compostela\",\n  \"Gerona\",\n  \"Cáceres\",\n  \"Lorca\",\n  \"Coslada\",\n  \"Talavera de la Reina\",\n  \"El Puerto de Santa María\",\n  \"Cornellá de Llobregat\",\n  \"Avilés\",\n  \"Palencia\",\n  \"Gecho\",\n  \"Orihuela\",\n  \"Pontevedra\",\n  \"Pozuelo de Alarcón\",\n  \"Toledo\",\n  \"El Ejido\",\n  \"Guadalajara\",\n  \"Gandía\",\n  \"Ceuta\",\n  \"Ferrol\",\n  \"Chiclana de la Frontera\",\n  \"Manresa\",\n  \"Roquetas de Mar\",\n  \"Ciudad Real\",\n  \"Rubí\",\n  \"Benidorm\",\n  \"San Sebastían de los Reyes\",\n  \"Ponferrada\",\n  \"Zamora\",\n  \"Alcalá de Guadaira\",\n  \"Fuengirola\",\n  \"Mijas\",\n  \"Sanlúcar de Barrameda\",\n  \"La Línea de la Concepción\",\n  \"Majadahonda\",\n  \"Sagunto\",\n  \"El Prat de LLobregat\",\n  \"Viladecans\",\n  \"Linares\",\n  \"Alcoy\",\n  \"Irún\",\n  \"Estepona\",\n  \"Torremolinos\",\n  \"Rivas-Vaciamadrid\",\n  \"Molina de Segura\",\n  \"Paterna\",\n  \"Granollers\",\n  \"Santa Lucía de Tirajana\",\n  \"Motril\",\n  \"Cerdañola del Vallés\",\n  \"Arrecife\",\n  \"Segovia\",\n  \"Torrelavega\",\n  \"Elda\",\n  \"Mérida\",\n  \"Ávila\",\n  \"Valdemoro\",\n  \"Cuenta\",\n  \"Collado Villalba\",\n  \"Benalmádena\",\n  \"Mollet del Vallés\",\n  \"Puertollano\",\n  \"Madrid\",\n  \"Barcelona\",\n  \"Valencia\",\n  \"Sevilla\",\n  \"Zaragoza\",\n  \"Málaga\",\n  \"Murcia\",\n  \"Palma de Mallorca\",\n  \"Las Palmas de Gran Canaria\",\n  \"Bilbao\",\n  \"Córdoba\",\n  \"Alicante\",\n  \"Valladolid\",\n  \"Vigo\",\n  \"Gijón\",\n  \"Hospitalet de LLobregat\",\n  \"La Coruña\",\n  \"Granada\",\n  \"Vitoria\",\n  \"Elche\",\n  \"Santa Cruz de Tenerife\",\n  \"Oviedo\",\n  \"Badalona\",\n  \"Cartagena\",\n  \"Móstoles\",\n  \"Jerez de la Frontera\",\n  \"Tarrasa\",\n  \"Sabadell\",\n  \"Alcalá de Henares\",\n  \"Pamplona\",\n  \"Fuenlabrada\",\n  \"Almería\",\n  \"San Sebastián\",\n  \"Leganés\",\n  \"Santander\",\n  \"Burgos\",\n  \"Castellón de la Plana\",\n  \"Alcorcón\",\n  \"Albacete\",\n  \"Getafe\",\n  \"Salamanca\",\n  \"Huelva\",\n  \"Logroño\",\n  \"Badajoz\",\n  \"San Cristróbal de la Laguna\",\n  \"León\",\n  \"Tarragona\",\n  \"Cádiz\",\n  \"Lérida\",\n  \"Marbella\",\n  \"Mataró\",\n  \"Dos Hermanas\",\n  \"Santa Coloma de Gramanet\",\n  \"Jaén\",\n  \"Algeciras\",\n  \"Torrejón de Ardoz\",\n  \"Orense\",\n  \"Alcobendas\",\n  \"Reus\",\n  \"Calahorra\",\n  \"Inca\"\n];\n\n},{}],376:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afganistán\",\n  \"Albania\",\n  \"Argelia\",\n  \"Andorra\",\n  \"Angola\",\n  \"Argentina\",\n  \"Armenia\",\n  \"Aruba\",\n  \"Australia\",\n  \"Austria\",\n  \"Azerbayán\",\n  \"Bahamas\",\n  \"Barein\",\n  \"Bangladesh\",\n  \"Barbados\",\n  \"Bielorusia\",\n  \"Bélgica\",\n  \"Belice\",\n  \"Bermuda\",\n  \"Bután\",\n  \"Bolivia\",\n  \"Bosnia Herzegovina\",\n  \"Botswana\",\n  \"Brasil\",\n  \"Bulgaria\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Camboya\",\n  \"Camerún\",\n  \"Canada\",\n  \"Cabo Verde\",\n  \"Islas Caimán\",\n  \"Chad\",\n  \"Chile\",\n  \"China\",\n  \"Isla de Navidad\",\n  \"Colombia\",\n  \"Comodos\",\n  \"Congo\",\n  \"Costa Rica\",\n  \"Costa de Marfil\",\n  \"Croacia\",\n  \"Cuba\",\n  \"Chipre\",\n  \"República Checa\",\n  \"Dinamarca\",\n  \"Dominica\",\n  \"República Dominicana\",\n  \"Ecuador\",\n  \"Egipto\",\n  \"El Salvador\",\n  \"Guinea Ecuatorial\",\n  \"Eritrea\",\n  \"Estonia\",\n  \"Etiopía\",\n  \"Islas Faro\",\n  \"Fiji\",\n  \"Finlandia\",\n  \"Francia\",\n  \"Gabón\",\n  \"Gambia\",\n  \"Georgia\",\n  \"Alemania\",\n  \"Ghana\",\n  \"Grecia\",\n  \"Groenlandia\",\n  \"Granada\",\n  \"Guadalupe\",\n  \"Guam\",\n  \"Guatemala\",\n  \"Guinea\",\n  \"Guinea-Bisau\",\n  \"Guayana\",\n  \"Haiti\",\n  \"Honduras\",\n  \"Hong Kong\",\n  \"Hungria\",\n  \"Islandia\",\n  \"India\",\n  \"Indonesia\",\n  \"Iran\",\n  \"Irak\",\n  \"Irlanda\",\n  \"Italia\",\n  \"Jamaica\",\n  \"Japón\",\n  \"Jordania\",\n  \"Kazajistan\",\n  \"Kenia\",\n  \"Kiribati\",\n  \"Corea\",\n  \"Kuwait\",\n  \"Letonia\",\n  \"Líbano\",\n  \"Liberia\",\n  \"Liechtenstein\",\n  \"Lituania\",\n  \"Luxemburgo\",\n  \"Macao\",\n  \"Macedonia\",\n  \"Madagascar\",\n  \"Malawi\",\n  \"Malasia\",\n  \"Maldivas\",\n  \"Mali\",\n  \"Malta\",\n  \"Martinica\",\n  \"Mauritania\",\n  \"Méjico\",\n  \"Micronesia\",\n  \"Moldavia\",\n  \"Mónaco\",\n  \"Mongolia\",\n  \"Montenegro\",\n  \"Montserrat\",\n  \"Marruecos\",\n  \"Mozambique\",\n  \"Namibia\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Holanda\",\n  \"Nueva Zelanda\",\n  \"Nicaragua\",\n  \"Niger\",\n  \"Nigeria\",\n  \"Noruega\",\n  \"Omán\",\n  \"Pakistan\",\n  \"Panamá\",\n  \"Papúa Nueva Guinea\",\n  \"Paraguay\",\n  \"Perú\",\n  \"Filipinas\",\n  \"Poland\",\n  \"Portugal\",\n  \"Puerto Rico\",\n  \"Rusia\",\n  \"Ruanda\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Santo Tomé y Principe\",\n  \"Arabia Saudí\",\n  \"Senegal\",\n  \"Serbia\",\n  \"Seychelles\",\n  \"Sierra Leona\",\n  \"Singapur\",\n  \"Eslovaquia\",\n  \"Eslovenia\",\n  \"Somalia\",\n  \"España\",\n  \"Sri Lanka\",\n  \"Sudán\",\n  \"Suriname\",\n  \"Suecia\",\n  \"Suiza\",\n  \"Siria\",\n  \"Taiwan\",\n  \"Tajikistan\",\n  \"Tanzania\",\n  \"Tailandia\",\n  \"Timor-Leste\",\n  \"Togo\",\n  \"Tonga\",\n  \"Trinidad y Tobago\",\n  \"Tunez\",\n  \"Turquia\",\n  \"Uganda\",\n  \"Ucrania\",\n  \"Emiratos Árabes Unidos\",\n  \"Reino Unido\",\n  \"Estados Unidos de América\",\n  \"Uruguay\",\n  \"Uzbekistan\",\n  \"Vanuatu\",\n  \"Venezuela\",\n  \"Vietnam\",\n  \"Yemen\",\n  \"Zambia\",\n  \"Zimbabwe\"\n];\n\n},{}],377:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"España\"\n];\n\n},{}],378:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.province = require(\"./province\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.time_zone = require(\"./time_zone\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":373,\"./city\":374,\"./city_prefix\":375,\"./country\":376,\"./default_country\":377,\"./postcode\":379,\"./province\":380,\"./secondary_address\":381,\"./state\":382,\"./state_abbr\":383,\"./street_address\":384,\"./street_name\":385,\"./street_suffix\":386,\"./time_zone\":387}],379:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\"\n];\n\n},{}],380:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Álava\",\n  \"Albacete\",\n  \"Alicante\",\n  \"Almería\",\n  \"Asturias\",\n  \"Ávila\",\n  \"Badajoz\",\n  \"Barcelona\",\n  \"Burgos\",\n  \"Cantabria\",\n  \"Castellón\",\n  \"Ciudad Real\",\n  \"Cuenca\",\n  \"Cáceres\",\n  \"Cádiz\",\n  \"Córdoba\",\n  \"Gerona\",\n  \"Granada\",\n  \"Guadalajara\",\n  \"Guipúzcoa\",\n  \"Huelva\",\n  \"Huesca\",\n  \"Islas Baleares\",\n  \"Jaén\",\n  \"La Coruña\",\n  \"La Rioja\",\n  \"Las Palmas\",\n  \"León\",\n  \"Lugo\",\n  \"lérida\",\n  \"Madrid\",\n  \"Murcia\",\n  \"Málaga\",\n  \"Navarra\",\n  \"Orense\",\n  \"Palencia\",\n  \"Pontevedra\",\n  \"Salamanca\",\n  \"Santa Cruz de Tenerife\",\n  \"Segovia\",\n  \"Sevilla\",\n  \"Soria\",\n  \"Tarragona\",\n  \"Teruel\",\n  \"Toledo\",\n  \"Valencia\",\n  \"Valladolid\",\n  \"Vizcaya\",\n  \"Zamora\",\n  \"Zaragoza\"\n];\n\n},{}],381:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Esc. ###\",\n  \"Puerta ###\"\n];\n\n},{}],382:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Andalucía\",\n  \"Aragón\",\n  \"Principado de Asturias\",\n  \"Baleares\",\n  \"Canarias\",\n  \"Cantabria\",\n  \"Castilla-La Mancha\",\n  \"Castilla y León\",\n  \"Cataluña\",\n  \"Comunidad Valenciana\",\n  \"Extremadura\",\n  \"Galicia\",\n  \"La Rioja\",\n  \"Comunidad de Madrid\",\n  \"Navarra\",\n  \"País Vasco\",\n  \"Región de Murcia\"\n];\n\n},{}],383:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"And\",\n  \"Ara\",\n  \"Ast\",\n  \"Bal\",\n  \"Can\",\n  \"Cbr\",\n  \"Man\",\n  \"Leo\",\n  \"Cat\",\n  \"Com\",\n  \"Ext\",\n  \"Gal\",\n  \"Rio\",\n  \"Mad\",\n  \"Nav\",\n  \"Vas\",\n  \"Mur\"\n];\n\n},{}],384:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_name}#{building_number}\",\n  \"#{street_name}#{building_number} #{secondary_address}\"\n];\n\n},{}],385:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_suffix} #{Name.first_name}\",\n  \"#{street_suffix} #{Name.first_name} #{Name.last_name}\"\n];\n\n},{}],386:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aldea\",\n  \"Apartamento\",\n  \"Arrabal\",\n  \"Arroyo\",\n  \"Avenida\",\n  \"Bajada\",\n  \"Barranco\",\n  \"Barrio\",\n  \"Bloque\",\n  \"Calle\",\n  \"Calleja\",\n  \"Camino\",\n  \"Carretera\",\n  \"Caserio\",\n  \"Colegio\",\n  \"Colonia\",\n  \"Conjunto\",\n  \"Cuesta\",\n  \"Chalet\",\n  \"Edificio\",\n  \"Entrada\",\n  \"Escalinata\",\n  \"Explanada\",\n  \"Extramuros\",\n  \"Extrarradio\",\n  \"Ferrocarril\",\n  \"Glorieta\",\n  \"Gran Subida\",\n  \"Grupo\",\n  \"Huerta\",\n  \"Jardines\",\n  \"Lado\",\n  \"Lugar\",\n  \"Manzana\",\n  \"Masía\",\n  \"Mercado\",\n  \"Monte\",\n  \"Muelle\",\n  \"Municipio\",\n  \"Parcela\",\n  \"Parque\",\n  \"Partida\",\n  \"Pasaje\",\n  \"Paseo\",\n  \"Plaza\",\n  \"Poblado\",\n  \"Polígono\",\n  \"Prolongación\",\n  \"Puente\",\n  \"Puerta\",\n  \"Quinta\",\n  \"Ramal\",\n  \"Rambla\",\n  \"Rampa\",\n  \"Riera\",\n  \"Rincón\",\n  \"Ronda\",\n  \"Rua\",\n  \"Salida\",\n  \"Sector\",\n  \"Sección\",\n  \"Senda\",\n  \"Solar\",\n  \"Subida\",\n  \"Terrenos\",\n  \"Torrente\",\n  \"Travesía\",\n  \"Urbanización\",\n  \"Vía\",\n  \"Vía Pública\"\n];\n\n},{}],387:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Pacífico/Midway\",\n  \"Pacífico/Pago_Pago\",\n  \"Pacífico/Honolulu\",\n  \"America/Juneau\",\n  \"America/Los_Angeles\",\n  \"America/Tijuana\",\n  \"America/Denver\",\n  \"America/Phoenix\",\n  \"America/Chihuahua\",\n  \"America/Mazatlan\",\n  \"America/Chicago\",\n  \"America/Regina\",\n  \"America/Mexico_City\",\n  \"America/Mexico_City\",\n  \"America/Monterrey\",\n  \"America/Guatemala\",\n  \"America/New_York\",\n  \"America/Indiana/Indianapolis\",\n  \"America/Bogota\",\n  \"America/Lima\",\n  \"America/Lima\",\n  \"America/Halifax\",\n  \"America/Caracas\",\n  \"America/La_Paz\",\n  \"America/Santiago\",\n  \"America/St_Johns\",\n  \"America/Sao_Paulo\",\n  \"America/Argentina/Buenos_Aires\",\n  \"America/Guyana\",\n  \"America/Godthab\",\n  \"Atlantic/South_Georgia\",\n  \"Atlantic/Azores\",\n  \"Atlantic/Cape_Verde\",\n  \"Europa/Dublin\",\n  \"Europa/London\",\n  \"Europa/Lisbon\",\n  \"Europa/London\",\n  \"Africa/Casablanca\",\n  \"Africa/Monrovia\",\n  \"Etc/UTC\",\n  \"Europa/Belgrade\",\n  \"Europa/Bratislava\",\n  \"Europa/Budapest\",\n  \"Europa/Ljubljana\",\n  \"Europa/Prague\",\n  \"Europa/Sarajevo\",\n  \"Europa/Skopje\",\n  \"Europa/Warsaw\",\n  \"Europa/Zagreb\",\n  \"Europa/Brussels\",\n  \"Europa/Copenhagen\",\n  \"Europa/Madrid\",\n  \"Europa/Paris\",\n  \"Europa/Amsterdam\",\n  \"Europa/Berlin\",\n  \"Europa/Berlin\",\n  \"Europa/Rome\",\n  \"Europa/Stockholm\",\n  \"Europa/Vienna\",\n  \"Africa/Algiers\",\n  \"Europa/Bucharest\",\n  \"Africa/Cairo\",\n  \"Europa/Helsinki\",\n  \"Europa/Kiev\",\n  \"Europa/Riga\",\n  \"Europa/Sofia\",\n  \"Europa/Tallinn\",\n  \"Europa/Vilnius\",\n  \"Europa/Athens\",\n  \"Europa/Istanbul\",\n  \"Europa/Minsk\",\n  \"Asia/Jerusalen\",\n  \"Africa/Harare\",\n  \"Africa/Johannesburg\",\n  \"Europa/Moscú\",\n  \"Europa/Moscú\",\n  \"Europa/Moscú\",\n  \"Asia/Kuwait\",\n  \"Asia/Riyadh\",\n  \"Africa/Nairobi\",\n  \"Asia/Baghdad\",\n  \"Asia/Tehran\",\n  \"Asia/Muscat\",\n  \"Asia/Muscat\",\n  \"Asia/Baku\",\n  \"Asia/Tbilisi\",\n  \"Asia/Yerevan\",\n  \"Asia/Kabul\",\n  \"Asia/Yekaterinburg\",\n  \"Asia/Karachi\",\n  \"Asia/Karachi\",\n  \"Asia/Tashkent\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kathmandu\",\n  \"Asia/Dhaka\",\n  \"Asia/Dhaka\",\n  \"Asia/Colombo\",\n  \"Asia/Almaty\",\n  \"Asia/Novosibirsk\",\n  \"Asia/Rangoon\",\n  \"Asia/Bangkok\",\n  \"Asia/Bangkok\",\n  \"Asia/Jakarta\",\n  \"Asia/Krasnoyarsk\",\n  \"Asia/Shanghai\",\n  \"Asia/Chongqing\",\n  \"Asia/Hong_Kong\",\n  \"Asia/Urumqi\",\n  \"Asia/Kuala_Lumpur\",\n  \"Asia/Singapore\",\n  \"Asia/Taipei\",\n  \"Australia/Perth\",\n  \"Asia/Irkutsk\",\n  \"Asia/Ulaanbaatar\",\n  \"Asia/Seoul\",\n  \"Asia/Tokyo\",\n  \"Asia/Tokyo\",\n  \"Asia/Tokyo\",\n  \"Asia/Yakutsk\",\n  \"Australia/Darwin\",\n  \"Australia/Adelaide\",\n  \"Australia/Melbourne\",\n  \"Australia/Melbourne\",\n  \"Australia/Sydney\",\n  \"Australia/Brisbane\",\n  \"Australia/Hobart\",\n  \"Asia/Vladivostok\",\n  \"Pacífico/Guam\",\n  \"Pacífico/Port_Moresby\",\n  \"Asia/Magadan\",\n  \"Asia/Magadan\",\n  \"Pacífico/Noumea\",\n  \"Pacífico/Fiji\",\n  \"Asia/Kamchatka\",\n  \"Pacífico/Majuro\",\n  \"Pacífico/Auckland\",\n  \"Pacífico/Auckland\",\n  \"Pacífico/Tongatapu\",\n  \"Pacífico/Fakaofo\",\n  \"Pacífico/Apia\"\n];\n\n},{}],388:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"6##-###-###\",\n  \"6##.###.###\",\n  \"6## ### ###\",\n  \"6########\"\n];\n\n},{}],389:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":388,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],390:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adaptativo\",\n  \"Avanzado\",\n  \"Asimilado\",\n  \"Automatizado\",\n  \"Equilibrado\",\n  \"Centrado en el negocio\",\n  \"Centralizado\",\n  \"Clonado\",\n  \"Compatible\",\n  \"Configurable\",\n  \"Multi grupo\",\n  \"Multi plataforma\",\n  \"Centrado en el usuario\",\n  \"Configurable\",\n  \"Descentralizado\",\n  \"Digitalizado\",\n  \"Distribuido\",\n  \"Diverso\",\n  \"Reducido\",\n  \"Mejorado\",\n  \"Para toda la empresa\",\n  \"Ergonomico\",\n  \"Exclusivo\",\n  \"Expandido\",\n  \"Extendido\",\n  \"Cara a cara\",\n  \"Enfocado\",\n  \"Totalmente configurable\",\n  \"Fundamental\",\n  \"Orígenes\",\n  \"Horizontal\",\n  \"Implementado\",\n  \"Innovador\",\n  \"Integrado\",\n  \"Intuitivo\",\n  \"Inverso\",\n  \"Gestionado\",\n  \"Obligatorio\",\n  \"Monitorizado\",\n  \"Multi canal\",\n  \"Multi lateral\",\n  \"Multi capa\",\n  \"En red\",\n  \"Orientado a objetos\",\n  \"Open-source\",\n  \"Operativo\",\n  \"Optimizado\",\n  \"Opcional\",\n  \"Organico\",\n  \"Organizado\",\n  \"Perseverando\",\n  \"Persistente\",\n  \"en fases\",\n  \"Polarizado\",\n  \"Pre-emptivo\",\n  \"Proactivo\",\n  \"Enfocado a benficios\",\n  \"Profundo\",\n  \"Programable\",\n  \"Progresivo\",\n  \"Public-key\",\n  \"Enfocado en la calidad\",\n  \"Reactivo\",\n  \"Realineado\",\n  \"Re-contextualizado\",\n  \"Re-implementado\",\n  \"Reducido\",\n  \"Ingenieria inversa\",\n  \"Robusto\",\n  \"Fácil\",\n  \"Seguro\",\n  \"Auto proporciona\",\n  \"Compartible\",\n  \"Intercambiable\",\n  \"Sincronizado\",\n  \"Orientado a equipos\",\n  \"Total\",\n  \"Universal\",\n  \"Mejorado\",\n  \"Actualizable\",\n  \"Centrado en el usuario\",\n  \"Amigable\",\n  \"Versatil\",\n  \"Virtual\",\n  \"Visionario\"\n];\n\n},{}],391:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"24 horas\",\n  \"24/7\",\n  \"3rd generación\",\n  \"4th generación\",\n  \"5th generación\",\n  \"6th generación\",\n  \"analizada\",\n  \"asimétrica\",\n  \"asíncrona\",\n  \"monitorizada por red\",\n  \"bidireccional\",\n  \"bifurcada\",\n  \"generada por el cliente\",\n  \"cliente servidor\",\n  \"coherente\",\n  \"cohesiva\",\n  \"compuesto\",\n  \"sensible al contexto\",\n  \"basado en el contexto\",\n  \"basado en contenido\",\n  \"dedicada\",\n  \"generado por la demanda\",\n  \"didactica\",\n  \"direccional\",\n  \"discreta\",\n  \"dinámica\",\n  \"potenciada\",\n  \"acompasada\",\n  \"ejecutiva\",\n  \"explícita\",\n  \"tolerante a fallos\",\n  \"innovadora\",\n  \"amplio ábanico\",\n  \"global\",\n  \"heurística\",\n  \"alto nivel\",\n  \"holística\",\n  \"homogénea\",\n  \"hibrida\",\n  \"incremental\",\n  \"intangible\",\n  \"interactiva\",\n  \"intermedia\",\n  \"local\",\n  \"logística\",\n  \"maximizada\",\n  \"metódica\",\n  \"misión crítica\",\n  \"móbil\",\n  \"modular\",\n  \"motivadora\",\n  \"multimedia\",\n  \"multiestado\",\n  \"multitarea\",\n  \"nacional\",\n  \"basado en necesidades\",\n  \"neutral\",\n  \"nueva generación\",\n  \"no-volátil\",\n  \"orientado a objetos\",\n  \"óptima\",\n  \"optimizada\",\n  \"radical\",\n  \"tiempo real\",\n  \"recíproca\",\n  \"regional\",\n  \"escalable\",\n  \"secundaria\",\n  \"orientada a soluciones\",\n  \"estable\",\n  \"estatica\",\n  \"sistemática\",\n  \"sistémica\",\n  \"tangible\",\n  \"terciaria\",\n  \"transicional\",\n  \"uniforme\",\n  \"valor añadido\",\n  \"vía web\",\n  \"defectos cero\",\n  \"tolerancia cero\"\n];\n\n},{}],392:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.noun = require(\"./noun\");\ncompany.descriptor = require(\"./descriptor\");\ncompany.adjective = require(\"./adjective\");\ncompany.name = require(\"./name\");\n\n},{\"./adjective\":390,\"./descriptor\":391,\"./name\":393,\"./noun\":394,\"./suffix\":395}],393:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name} y #{Name.last_name}\",\n  \"#{Name.last_name} #{Name.last_name} #{suffix}\",\n  \"#{Name.last_name}, #{Name.last_name} y #{Name.last_name} Asociados\"\n];\n\n},{}],394:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"habilidad\",\n  \"acceso\",\n  \"adaptador\",\n  \"algoritmo\",\n  \"alianza\",\n  \"analista\",\n  \"aplicación\",\n  \"enfoque\",\n  \"arquitectura\",\n  \"archivo\",\n  \"inteligencia artificial\",\n  \"array\",\n  \"actitud\",\n  \"medición\",\n  \"gestión presupuestaria\",\n  \"capacidad\",\n  \"desafío\",\n  \"circuito\",\n  \"colaboración\",\n  \"complejidad\",\n  \"concepto\",\n  \"conglomeración\",\n  \"contingencia\",\n  \"núcleo\",\n  \"fidelidad\",\n  \"base de datos\",\n  \"data-warehouse\",\n  \"definición\",\n  \"emulación\",\n  \"codificar\",\n  \"encriptar\",\n  \"extranet\",\n  \"firmware\",\n  \"flexibilidad\",\n  \"focus group\",\n  \"previsión\",\n  \"base de trabajo\",\n  \"función\",\n  \"funcionalidad\",\n  \"Interfaz Gráfica\",\n  \"groupware\",\n  \"Interfaz gráfico de usuario\",\n  \"hardware\",\n  \"Soporte\",\n  \"jerarquía\",\n  \"conjunto\",\n  \"implementación\",\n  \"infraestructura\",\n  \"iniciativa\",\n  \"instalación\",\n  \"conjunto de instrucciones\",\n  \"interfaz\",\n  \"intranet\",\n  \"base del conocimiento\",\n  \"red de area local\",\n  \"aprovechar\",\n  \"matrices\",\n  \"metodologías\",\n  \"middleware\",\n  \"migración\",\n  \"modelo\",\n  \"moderador\",\n  \"monitorizar\",\n  \"arquitectura abierta\",\n  \"sistema abierto\",\n  \"orquestar\",\n  \"paradigma\",\n  \"paralelismo\",\n  \"política\",\n  \"portal\",\n  \"estructura de precios\",\n  \"proceso de mejora\",\n  \"producto\",\n  \"productividad\",\n  \"proyecto\",\n  \"proyección\",\n  \"protocolo\",\n  \"línea segura\",\n  \"software\",\n  \"solución\",\n  \"estandardización\",\n  \"estrategia\",\n  \"estructura\",\n  \"éxito\",\n  \"superestructura\",\n  \"soporte\",\n  \"sinergia\",\n  \"mediante\",\n  \"marco de tiempo\",\n  \"caja de herramientas\",\n  \"utilización\",\n  \"website\",\n  \"fuerza de trabajo\"\n];\n\n},{}],395:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"S.L.\",\n  \"e Hijos\",\n  \"S.A.\",\n  \"Hermanos\"\n];\n\n},{}],396:[function(require,module,exports){\nvar es = {};\nmodule['exports'] = es;\nes.title = \"Spanish\";\nes.address = require(\"./address\");\nes.company = require(\"./company\");\nes.internet = require(\"./internet\");\nes.name = require(\"./name\");\nes.phone_number = require(\"./phone_number\");\nes.cell_phone = require(\"./cell_phone\");\n\n},{\"./address\":378,\"./cell_phone\":389,\"./company\":392,\"./internet\":399,\"./name\":401,\"./phone_number\":408}],397:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"es\",\n  \"info\",\n  \"com.es\",\n  \"org\"\n];\n\n},{}],398:[function(require,module,exports){\nmodule.exports=require(119)\n},{\"/Users/a/dev/faker.js/lib/locales/de/internet/free_email.js\":119}],399:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":397,\"./free_email\":398,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],400:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adán\",\n  \"Agustín\",\n  \"Alberto\",\n  \"Alejandro\",\n  \"Alfonso\",\n  \"Alfredo\",\n  \"Andrés\",\n  \"Antonio\",\n  \"Armando\",\n  \"Arturo\",\n  \"Benito\",\n  \"Benjamín\",\n  \"Bernardo\",\n  \"Carlos\",\n  \"César\",\n  \"Claudio\",\n  \"Clemente\",\n  \"Cristian\",\n  \"Cristobal\",\n  \"Daniel\",\n  \"David\",\n  \"Diego\",\n  \"Eduardo\",\n  \"Emilio\",\n  \"Enrique\",\n  \"Ernesto\",\n  \"Esteban\",\n  \"Federico\",\n  \"Felipe\",\n  \"Fernando\",\n  \"Francisco\",\n  \"Gabriel\",\n  \"Gerardo\",\n  \"Germán\",\n  \"Gilberto\",\n  \"Gonzalo\",\n  \"Gregorio\",\n  \"Guillermo\",\n  \"Gustavo\",\n  \"Hernán\",\n  \"Homero\",\n  \"Horacio\",\n  \"Hugo\",\n  \"Ignacio\",\n  \"Jacobo\",\n  \"Jaime\",\n  \"Javier\",\n  \"Jerónimo\",\n  \"Jesús\",\n  \"Joaquín\",\n  \"Jorge\",\n  \"Jorge Luis\",\n  \"José\",\n  \"José Eduardo\",\n  \"José Emilio\",\n  \"José Luis\",\n  \"José María\",\n  \"Juan\",\n  \"Juan Carlos\",\n  \"Julio\",\n  \"Julio César\",\n  \"Lorenzo\",\n  \"Lucas\",\n  \"Luis\",\n  \"Luis Miguel\",\n  \"Manuel\",\n  \"Marco Antonio\",\n  \"Marcos\",\n  \"Mariano\",\n  \"Mario\",\n  \"Martín\",\n  \"Mateo\",\n  \"Miguel\",\n  \"Miguel Ángel\",\n  \"Nicolás\",\n  \"Octavio\",\n  \"Óscar\",\n  \"Pablo\",\n  \"Patricio\",\n  \"Pedro\",\n  \"Rafael\",\n  \"Ramiro\",\n  \"Ramón\",\n  \"Raúl\",\n  \"Ricardo\",\n  \"Roberto\",\n  \"Rodrigo\",\n  \"Rubén\",\n  \"Salvador\",\n  \"Samuel\",\n  \"Sancho\",\n  \"Santiago\",\n  \"Sergio\",\n  \"Teodoro\",\n  \"Timoteo\",\n  \"Tomás\",\n  \"Vicente\",\n  \"Víctor\",\n  \"Adela\",\n  \"Adriana\",\n  \"Alejandra\",\n  \"Alicia\",\n  \"Amalia\",\n  \"Ana\",\n  \"Ana Luisa\",\n  \"Ana María\",\n  \"Andrea\",\n  \"Anita\",\n  \"Ángela\",\n  \"Antonia\",\n  \"Ariadna\",\n  \"Barbara\",\n  \"Beatriz\",\n  \"Berta\",\n  \"Blanca\",\n  \"Caridad\",\n  \"Carla\",\n  \"Carlota\",\n  \"Carmen\",\n  \"Carolina\",\n  \"Catalina\",\n  \"Cecilia\",\n  \"Clara\",\n  \"Claudia\",\n  \"Concepción\",\n  \"Conchita\",\n  \"Cristina\",\n  \"Daniela\",\n  \"Débora\",\n  \"Diana\",\n  \"Dolores\",\n  \"Lola\",\n  \"Dorotea\",\n  \"Elena\",\n  \"Elisa\",\n  \"Eloisa\",\n  \"Elsa\",\n  \"Elvira\",\n  \"Emilia\",\n  \"Esperanza\",\n  \"Estela\",\n  \"Ester\",\n  \"Eva\",\n  \"Florencia\",\n  \"Francisca\",\n  \"Gabriela\",\n  \"Gloria\",\n  \"Graciela\",\n  \"Guadalupe\",\n  \"Guillermina\",\n  \"Inés\",\n  \"Irene\",\n  \"Isabel\",\n  \"Isabela\",\n  \"Josefina\",\n  \"Juana\",\n  \"Julia\",\n  \"Laura\",\n  \"Leonor\",\n  \"Leticia\",\n  \"Lilia\",\n  \"Lorena\",\n  \"Lourdes\",\n  \"Lucia\",\n  \"Luisa\",\n  \"Luz\",\n  \"Magdalena\",\n  \"Manuela\",\n  \"Marcela\",\n  \"Margarita\",\n  \"María\",\n  \"María del Carmen\",\n  \"María Cristina\",\n  \"María Elena\",\n  \"María Eugenia\",\n  \"María José\",\n  \"María Luisa\",\n  \"María Soledad\",\n  \"María Teresa\",\n  \"Mariana\",\n  \"Maricarmen\",\n  \"Marilu\",\n  \"Marisol\",\n  \"Marta\",\n  \"Mayte\",\n  \"Mercedes\",\n  \"Micaela\",\n  \"Mónica\",\n  \"Natalia\",\n  \"Norma\",\n  \"Olivia\",\n  \"Patricia\",\n  \"Pilar\",\n  \"Ramona\",\n  \"Raquel\",\n  \"Rebeca\",\n  \"Reina\",\n  \"Rocio\",\n  \"Rosa\",\n  \"Rosalia\",\n  \"Rosario\",\n  \"Sara\",\n  \"Silvia\",\n  \"Sofia\",\n  \"Soledad\",\n  \"Sonia\",\n  \"Susana\",\n  \"Teresa\",\n  \"Verónica\",\n  \"Victoria\",\n  \"Virginia\",\n  \"Yolanda\"\n];\n\n},{}],401:[function(require,module,exports){\narguments[4][259][0].apply(exports,arguments)\n},{\"./first_name\":400,\"./last_name\":402,\"./name\":403,\"./prefix\":404,\"./suffix\":405,\"./title\":406,\"/Users/a/dev/faker.js/lib/locales/en/name/index.js\":259}],402:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abeyta\",\n  \"Abrego\",\n  \"Abreu\",\n  \"Acevedo\",\n  \"Acosta\",\n  \"Acuña\",\n  \"Adame\",\n  \"Adorno\",\n  \"Agosto\",\n  \"Aguayo\",\n  \"Águilar\",\n  \"Aguilera\",\n  \"Aguirre\",\n  \"Alanis\",\n  \"Alaniz\",\n  \"Alarcón\",\n  \"Alba\",\n  \"Alcala\",\n  \"Alcántar\",\n  \"Alcaraz\",\n  \"Alejandro\",\n  \"Alemán\",\n  \"Alfaro\",\n  \"Alicea\",\n  \"Almanza\",\n  \"Almaraz\",\n  \"Almonte\",\n  \"Alonso\",\n  \"Alonzo\",\n  \"Altamirano\",\n  \"Alva\",\n  \"Alvarado\",\n  \"Alvarez\",\n  \"Amador\",\n  \"Amaya\",\n  \"Anaya\",\n  \"Anguiano\",\n  \"Angulo\",\n  \"Aparicio\",\n  \"Apodaca\",\n  \"Aponte\",\n  \"Aragón\",\n  \"Araña\",\n  \"Aranda\",\n  \"Arce\",\n  \"Archuleta\",\n  \"Arellano\",\n  \"Arenas\",\n  \"Arevalo\",\n  \"Arguello\",\n  \"Arias\",\n  \"Armas\",\n  \"Armendáriz\",\n  \"Armenta\",\n  \"Armijo\",\n  \"Arredondo\",\n  \"Arreola\",\n  \"Arriaga\",\n  \"Arroyo\",\n  \"Arteaga\",\n  \"Atencio\",\n  \"Ávalos\",\n  \"Ávila\",\n  \"Avilés\",\n  \"Ayala\",\n  \"Baca\",\n  \"Badillo\",\n  \"Báez\",\n  \"Baeza\",\n  \"Bahena\",\n  \"Balderas\",\n  \"Ballesteros\",\n  \"Banda\",\n  \"Bañuelos\",\n  \"Barajas\",\n  \"Barela\",\n  \"Barragán\",\n  \"Barraza\",\n  \"Barrera\",\n  \"Barreto\",\n  \"Barrientos\",\n  \"Barrios\",\n  \"Batista\",\n  \"Becerra\",\n  \"Beltrán\",\n  \"Benavides\",\n  \"Benavídez\",\n  \"Benítez\",\n  \"Bermúdez\",\n  \"Bernal\",\n  \"Berríos\",\n  \"Bétancourt\",\n  \"Blanco\",\n  \"Bonilla\",\n  \"Borrego\",\n  \"Botello\",\n  \"Bravo\",\n  \"Briones\",\n  \"Briseño\",\n  \"Brito\",\n  \"Bueno\",\n  \"Burgos\",\n  \"Bustamante\",\n  \"Bustos\",\n  \"Caballero\",\n  \"Cabán\",\n  \"Cabrera\",\n  \"Cadena\",\n  \"Caldera\",\n  \"Calderón\",\n  \"Calvillo\",\n  \"Camacho\",\n  \"Camarillo\",\n  \"Campos\",\n  \"Canales\",\n  \"Candelaria\",\n  \"Cano\",\n  \"Cantú\",\n  \"Caraballo\",\n  \"Carbajal\",\n  \"Cardenas\",\n  \"Cardona\",\n  \"Carmona\",\n  \"Carranza\",\n  \"Carrasco\",\n  \"Carrasquillo\",\n  \"Carreón\",\n  \"Carrera\",\n  \"Carrero\",\n  \"Carrillo\",\n  \"Carrion\",\n  \"Carvajal\",\n  \"Casanova\",\n  \"Casares\",\n  \"Casárez\",\n  \"Casas\",\n  \"Casillas\",\n  \"Castañeda\",\n  \"Castellanos\",\n  \"Castillo\",\n  \"Castro\",\n  \"Cavazos\",\n  \"Cazares\",\n  \"Ceballos\",\n  \"Cedillo\",\n  \"Ceja\",\n  \"Centeno\",\n  \"Cepeda\",\n  \"Cerda\",\n  \"Cervantes\",\n  \"Cervántez\",\n  \"Chacón\",\n  \"Chapa\",\n  \"Chavarría\",\n  \"Chávez\",\n  \"Cintrón\",\n  \"Cisneros\",\n  \"Collado\",\n  \"Collazo\",\n  \"Colón\",\n  \"Colunga\",\n  \"Concepción\",\n  \"Contreras\",\n  \"Cordero\",\n  \"Córdova\",\n  \"Cornejo\",\n  \"Corona\",\n  \"Coronado\",\n  \"Corral\",\n  \"Corrales\",\n  \"Correa\",\n  \"Cortés\",\n  \"Cortez\",\n  \"Cotto\",\n  \"Covarrubias\",\n  \"Crespo\",\n  \"Cruz\",\n  \"Cuellar\",\n  \"Curiel\",\n  \"Dávila\",\n  \"de Anda\",\n  \"de Jesús\",\n  \"Delacrúz\",\n  \"Delafuente\",\n  \"Delagarza\",\n  \"Delao\",\n  \"Delapaz\",\n  \"Delarosa\",\n  \"Delatorre\",\n  \"Deleón\",\n  \"Delgadillo\",\n  \"Delgado\",\n  \"Delrío\",\n  \"Delvalle\",\n  \"Díaz\",\n  \"Domínguez\",\n  \"Domínquez\",\n  \"Duarte\",\n  \"Dueñas\",\n  \"Duran\",\n  \"Echevarría\",\n  \"Elizondo\",\n  \"Enríquez\",\n  \"Escalante\",\n  \"Escamilla\",\n  \"Escobar\",\n  \"Escobedo\",\n  \"Esparza\",\n  \"Espinal\",\n  \"Espino\",\n  \"Espinosa\",\n  \"Espinoza\",\n  \"Esquibel\",\n  \"Esquivel\",\n  \"Estévez\",\n  \"Estrada\",\n  \"Fajardo\",\n  \"Farías\",\n  \"Feliciano\",\n  \"Fernández\",\n  \"Ferrer\",\n  \"Fierro\",\n  \"Figueroa\",\n  \"Flores\",\n  \"Flórez\",\n  \"Fonseca\",\n  \"Franco\",\n  \"Frías\",\n  \"Fuentes\",\n  \"Gaitán\",\n  \"Galarza\",\n  \"Galindo\",\n  \"Gallardo\",\n  \"Gallegos\",\n  \"Galván\",\n  \"Gálvez\",\n  \"Gamboa\",\n  \"Gamez\",\n  \"Gaona\",\n  \"Garay\",\n  \"García\",\n  \"Garibay\",\n  \"Garica\",\n  \"Garrido\",\n  \"Garza\",\n  \"Gastélum\",\n  \"Gaytán\",\n  \"Gil\",\n  \"Girón\",\n  \"Godínez\",\n  \"Godoy\",\n  \"Gómez\",\n  \"Gonzales\",\n  \"González\",\n  \"Gollum\",\n  \"Gracia\",\n  \"Granado\",\n  \"Granados\",\n  \"Griego\",\n  \"Grijalva\",\n  \"Guajardo\",\n  \"Guardado\",\n  \"Guerra\",\n  \"Guerrero\",\n  \"Guevara\",\n  \"Guillen\",\n  \"Gurule\",\n  \"Gutiérrez\",\n  \"Guzmán\",\n  \"Haro\",\n  \"Henríquez\",\n  \"Heredia\",\n  \"Hernádez\",\n  \"Hernandes\",\n  \"Hernández\",\n  \"Herrera\",\n  \"Hidalgo\",\n  \"Hinojosa\",\n  \"Holguín\",\n  \"Huerta\",\n  \"Hurtado\",\n  \"Ibarra\",\n  \"Iglesias\",\n  \"Irizarry\",\n  \"Jaime\",\n  \"Jaimes\",\n  \"Jáquez\",\n  \"Jaramillo\",\n  \"Jasso\",\n  \"Jiménez\",\n  \"Jimínez\",\n  \"Juárez\",\n  \"Jurado\",\n  \"Laboy\",\n  \"Lara\",\n  \"Laureano\",\n  \"Leal\",\n  \"Lebrón\",\n  \"Ledesma\",\n  \"Leiva\",\n  \"Lemus\",\n  \"León\",\n  \"Lerma\",\n  \"Leyva\",\n  \"Limón\",\n  \"Linares\",\n  \"Lira\",\n  \"Llamas\",\n  \"Loera\",\n  \"Lomeli\",\n  \"Longoria\",\n  \"López\",\n  \"Lovato\",\n  \"Loya\",\n  \"Lozada\",\n  \"Lozano\",\n  \"Lucero\",\n  \"Lucio\",\n  \"Luevano\",\n  \"Lugo\",\n  \"Luna\",\n  \"Macías\",\n  \"Madera\",\n  \"Madrid\",\n  \"Madrigal\",\n  \"Maestas\",\n  \"Magaña\",\n  \"Malave\",\n  \"Maldonado\",\n  \"Manzanares\",\n  \"Mares\",\n  \"Marín\",\n  \"Márquez\",\n  \"Marrero\",\n  \"Marroquín\",\n  \"Martínez\",\n  \"Mascareñas\",\n  \"Mata\",\n  \"Mateo\",\n  \"Matías\",\n  \"Matos\",\n  \"Maya\",\n  \"Mayorga\",\n  \"Medina\",\n  \"Medrano\",\n  \"Mejía\",\n  \"Meléndez\",\n  \"Melgar\",\n  \"Mena\",\n  \"Menchaca\",\n  \"Méndez\",\n  \"Mendoza\",\n  \"Menéndez\",\n  \"Meraz\",\n  \"Mercado\",\n  \"Merino\",\n  \"Mesa\",\n  \"Meza\",\n  \"Miramontes\",\n  \"Miranda\",\n  \"Mireles\",\n  \"Mojica\",\n  \"Molina\",\n  \"Mondragón\",\n  \"Monroy\",\n  \"Montalvo\",\n  \"Montañez\",\n  \"Montaño\",\n  \"Montemayor\",\n  \"Montenegro\",\n  \"Montero\",\n  \"Montes\",\n  \"Montez\",\n  \"Montoya\",\n  \"Mora\",\n  \"Morales\",\n  \"Moreno\",\n  \"Mota\",\n  \"Moya\",\n  \"Munguía\",\n  \"Muñiz\",\n  \"Muñoz\",\n  \"Murillo\",\n  \"Muro\",\n  \"Nájera\",\n  \"Naranjo\",\n  \"Narváez\",\n  \"Nava\",\n  \"Navarrete\",\n  \"Navarro\",\n  \"Nazario\",\n  \"Negrete\",\n  \"Negrón\",\n  \"Nevárez\",\n  \"Nieto\",\n  \"Nieves\",\n  \"Niño\",\n  \"Noriega\",\n  \"Núñez\",\n  \"Ocampo\",\n  \"Ocasio\",\n  \"Ochoa\",\n  \"Ojeda\",\n  \"Olivares\",\n  \"Olivárez\",\n  \"Olivas\",\n  \"Olivera\",\n  \"Olivo\",\n  \"Olmos\",\n  \"Olvera\",\n  \"Ontiveros\",\n  \"Oquendo\",\n  \"Ordóñez\",\n  \"Orellana\",\n  \"Ornelas\",\n  \"Orosco\",\n  \"Orozco\",\n  \"Orta\",\n  \"Ortega\",\n  \"Ortiz\",\n  \"Osorio\",\n  \"Otero\",\n  \"Ozuna\",\n  \"Pabón\",\n  \"Pacheco\",\n  \"Padilla\",\n  \"Padrón\",\n  \"Páez\",\n  \"Pagan\",\n  \"Palacios\",\n  \"Palomino\",\n  \"Palomo\",\n  \"Pantoja\",\n  \"Paredes\",\n  \"Parra\",\n  \"Partida\",\n  \"Patiño\",\n  \"Paz\",\n  \"Pedraza\",\n  \"Pedroza\",\n  \"Pelayo\",\n  \"Peña\",\n  \"Perales\",\n  \"Peralta\",\n  \"Perea\",\n  \"Peres\",\n  \"Pérez\",\n  \"Pichardo\",\n  \"Piña\",\n  \"Pineda\",\n  \"Pizarro\",\n  \"Polanco\",\n  \"Ponce\",\n  \"Porras\",\n  \"Portillo\",\n  \"Posada\",\n  \"Prado\",\n  \"Preciado\",\n  \"Prieto\",\n  \"Puente\",\n  \"Puga\",\n  \"Pulido\",\n  \"Quesada\",\n  \"Quezada\",\n  \"Quiñones\",\n  \"Quiñónez\",\n  \"Quintana\",\n  \"Quintanilla\",\n  \"Quintero\",\n  \"Quiroz\",\n  \"Rael\",\n  \"Ramírez\",\n  \"Ramón\",\n  \"Ramos\",\n  \"Rangel\",\n  \"Rascón\",\n  \"Raya\",\n  \"Razo\",\n  \"Regalado\",\n  \"Rendón\",\n  \"Rentería\",\n  \"Reséndez\",\n  \"Reyes\",\n  \"Reyna\",\n  \"Reynoso\",\n  \"Rico\",\n  \"Rincón\",\n  \"Riojas\",\n  \"Ríos\",\n  \"Rivas\",\n  \"Rivera\",\n  \"Rivero\",\n  \"Robledo\",\n  \"Robles\",\n  \"Rocha\",\n  \"Rodarte\",\n  \"Rodrígez\",\n  \"Rodríguez\",\n  \"Rodríquez\",\n  \"Rojas\",\n  \"Rojo\",\n  \"Roldán\",\n  \"Rolón\",\n  \"Romero\",\n  \"Romo\",\n  \"Roque\",\n  \"Rosado\",\n  \"Rosales\",\n  \"Rosario\",\n  \"Rosas\",\n  \"Roybal\",\n  \"Rubio\",\n  \"Ruelas\",\n  \"Ruiz\",\n  \"Saavedra\",\n  \"Sáenz\",\n  \"Saiz\",\n  \"Salas\",\n  \"Salazar\",\n  \"Salcedo\",\n  \"Salcido\",\n  \"Saldaña\",\n  \"Saldivar\",\n  \"Salgado\",\n  \"Salinas\",\n  \"Samaniego\",\n  \"Sanabria\",\n  \"Sanches\",\n  \"Sánchez\",\n  \"Sandoval\",\n  \"Santacruz\",\n  \"Santana\",\n  \"Santiago\",\n  \"Santillán\",\n  \"Sarabia\",\n  \"Sauceda\",\n  \"Saucedo\",\n  \"Sedillo\",\n  \"Segovia\",\n  \"Segura\",\n  \"Sepúlveda\",\n  \"Serna\",\n  \"Serrano\",\n  \"Serrato\",\n  \"Sevilla\",\n  \"Sierra\",\n  \"Sisneros\",\n  \"Solano\",\n  \"Solís\",\n  \"Soliz\",\n  \"Solorio\",\n  \"Solorzano\",\n  \"Soria\",\n  \"Sosa\",\n  \"Sotelo\",\n  \"Soto\",\n  \"Suárez\",\n  \"Tafoya\",\n  \"Tamayo\",\n  \"Tamez\",\n  \"Tapia\",\n  \"Tejada\",\n  \"Tejeda\",\n  \"Téllez\",\n  \"Tello\",\n  \"Terán\",\n  \"Terrazas\",\n  \"Tijerina\",\n  \"Tirado\",\n  \"Toledo\",\n  \"Toro\",\n  \"Torres\",\n  \"Tórrez\",\n  \"Tovar\",\n  \"Trejo\",\n  \"Treviño\",\n  \"Trujillo\",\n  \"Ulibarri\",\n  \"Ulloa\",\n  \"Urbina\",\n  \"Ureña\",\n  \"Urías\",\n  \"Uribe\",\n  \"Urrutia\",\n  \"Vaca\",\n  \"Valadez\",\n  \"Valdés\",\n  \"Valdez\",\n  \"Valdivia\",\n  \"Valencia\",\n  \"Valentín\",\n  \"Valenzuela\",\n  \"Valladares\",\n  \"Valle\",\n  \"Vallejo\",\n  \"Valles\",\n  \"Valverde\",\n  \"Vanegas\",\n  \"Varela\",\n  \"Vargas\",\n  \"Vásquez\",\n  \"Vázquez\",\n  \"Vega\",\n  \"Vela\",\n  \"Velasco\",\n  \"Velásquez\",\n  \"Velázquez\",\n  \"Vélez\",\n  \"Véliz\",\n  \"Venegas\",\n  \"Vera\",\n  \"Verdugo\",\n  \"Verduzco\",\n  \"Vergara\",\n  \"Viera\",\n  \"Vigil\",\n  \"Villa\",\n  \"Villagómez\",\n  \"Villalobos\",\n  \"Villalpando\",\n  \"Villanueva\",\n  \"Villareal\",\n  \"Villarreal\",\n  \"Villaseñor\",\n  \"Villegas\",\n  \"Yáñez\",\n  \"Ybarra\",\n  \"Zambrano\",\n  \"Zamora\",\n  \"Zamudio\",\n  \"Zapata\",\n  \"Zaragoza\",\n  \"Zarate\",\n  \"Zavala\",\n  \"Zayas\",\n  \"Zelaya\",\n  \"Zepeda\",\n  \"Zúñiga\"\n];\n\n},{}],403:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name}\"\n];\n\n},{}],404:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Sr.\",\n  \"Sra.\",\n  \"Sta.\"\n];\n\n},{}],405:[function(require,module,exports){\nmodule.exports=require(263)\n},{\"/Users/a/dev/faker.js/lib/locales/en/name/suffix.js\":263}],406:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"descriptor\": [\n    \"Jefe\",\n    \"Senior\",\n    \"Directo\",\n    \"Corporativo\",\n    \"Dinánmico\",\n    \"Futuro\",\n    \"Producto\",\n    \"Nacional\",\n    \"Regional\",\n    \"Distrito\",\n    \"Central\",\n    \"Global\",\n    \"Cliente\",\n    \"Inversor\",\n    \"International\",\n    \"Heredado\",\n    \"Adelante\",\n    \"Interno\",\n    \"Humano\",\n    \"Gerente\",\n    \"Director\"\n  ],\n  \"level\": [\n    \"Soluciones\",\n    \"Programa\",\n    \"Marca\",\n    \"Seguridada\",\n    \"Investigación\",\n    \"Marketing\",\n    \"Normas\",\n    \"Implementación\",\n    \"Integración\",\n    \"Funcionalidad\",\n    \"Respuesta\",\n    \"Paradigma\",\n    \"Tácticas\",\n    \"Identidad\",\n    \"Mercados\",\n    \"Grupo\",\n    \"División\",\n    \"Aplicaciones\",\n    \"Optimización\",\n    \"Operaciones\",\n    \"Infraestructura\",\n    \"Intranet\",\n    \"Comunicaciones\",\n    \"Web\",\n    \"Calidad\",\n    \"Seguro\",\n    \"Mobilidad\",\n    \"Cuentas\",\n    \"Datos\",\n    \"Creativo\",\n    \"Configuración\",\n    \"Contabilidad\",\n    \"Interacciones\",\n    \"Factores\",\n    \"Usabilidad\",\n    \"Métricas\"\n  ],\n  \"job\": [\n    \"Supervisor\",\n    \"Asociado\",\n    \"Ejecutivo\",\n    \"Relacciones\",\n    \"Oficial\",\n    \"Gerente\",\n    \"Ingeniero\",\n    \"Especialista\",\n    \"Director\",\n    \"Coordinador\",\n    \"Administrador\",\n    \"Arquitecto\",\n    \"Analista\",\n    \"Diseñador\",\n    \"Planificador\",\n    \"Técnico\",\n    \"Funcionario\",\n    \"Desarrollador\",\n    \"Productor\",\n    \"Consultor\",\n    \"Asistente\",\n    \"Facilitador\",\n    \"Agente\",\n    \"Representante\",\n    \"Estratega\"\n  ]\n};\n\n},{}],407:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"9##-###-###\",\n  \"9##.###.###\",\n  \"9## ### ###\",\n  \"9########\"\n];\n\n},{}],408:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":407,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],409:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \" s/n.\",\n  \", #\",\n  \", ##\",\n  \" #\",\n  \" ##\",\n  \" ###\",\n  \" ####\"\n];\n\n},{}],410:[function(require,module,exports){\nmodule.exports=require(351)\n},{\"/Users/a/dev/faker.js/lib/locales/en_au_ocker/address/city.js\":351}],411:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aguascalientes\",\n  \"Apodaca\",\n  \"Buenavista\",\n  \"Campeche\",\n  \"Cancún\",\n  \"Cárdenas\",\n  \"Celaya\",\n  \"Chalco\",\n  \"Chetumal\",\n  \"Chicoloapan\",\n  \"Chignahuapan\",\n  \"Chihuahua\",\n  \"Chilpancingo\",\n  \"Chimalhuacán\",\n  \"Ciudad Acuña\",\n  \"Ciudad de México\",\n  \"Ciudad del Carmen\",\n  \"Ciudad López Mateos\",\n  \"Ciudad Madero\",\n  \"Ciudad Obregón\",\n  \"Ciudad Valles\",\n  \"Ciudad Victoria\",\n  \"Coatzacoalcos\",\n  \"Colima-Villa de Álvarez\",\n  \"Comitán de Dominguez\",\n  \"Córdoba\",\n  \"Cuautitlán Izcalli\",\n  \"Cuautla\",\n  \"Cuernavaca\",\n  \"Culiacán\",\n  \"Delicias\",\n  \"Durango\",\n  \"Ensenada\",\n  \"Fresnillo\",\n  \"General Escobedo\",\n  \"Gómez Palacio\",\n  \"Guadalajara\",\n  \"Guadalupe\",\n  \"Guanajuato\",\n  \"Guaymas\",\n  \"Hermosillo\",\n  \"Hidalgo del Parral\",\n  \"Iguala\",\n  \"Irapuato\",\n  \"Ixtapaluca\",\n  \"Jiutepec\",\n  \"Juárez\",\n  \"La Laguna\",\n  \"La Paz\",\n  \"La Piedad-Pénjamo\",\n  \"León\",\n  \"Los Cabos\",\n  \"Los Mochis\",\n  \"Manzanillo\",\n  \"Matamoros\",\n  \"Mazatlán\",\n  \"Mérida\",\n  \"Mexicali\",\n  \"Minatitlán\",\n  \"Miramar\",\n  \"Monclova\",\n  \"Monclova-Frontera\",\n  \"Monterrey\",\n  \"Morelia\",\n  \"Naucalpan de Juárez\",\n  \"Navojoa\",\n  \"Nezahualcóyotl\",\n  \"Nogales\",\n  \"Nuevo Laredo\",\n  \"Oaxaca\",\n  \"Ocotlán\",\n  \"Ojo de agua\",\n  \"Orizaba\",\n  \"Pachuca\",\n  \"Piedras Negras\",\n  \"Poza Rica\",\n  \"Puebla\",\n  \"Puerto Vallarta\",\n  \"Querétaro\",\n  \"Reynosa-Río Bravo\",\n  \"Rioverde-Ciudad Fernández\",\n  \"Salamanca\",\n  \"Saltillo\",\n  \"San Cristobal de las Casas\",\n  \"San Francisco Coacalco\",\n  \"San Francisco del Rincón\",\n  \"San Juan Bautista Tuxtepec\",\n  \"San Juan del Río\",\n  \"San Luis Potosí-Soledad\",\n  \"San Luis Río Colorado\",\n  \"San Nicolás de los Garza\",\n  \"San Pablo de las Salinas\",\n  \"San Pedro Garza García\",\n  \"Santa Catarina\",\n  \"Soledad de Graciano Sánchez\",\n  \"Tampico-Pánuco\",\n  \"Tapachula\",\n  \"Tecomán\",\n  \"Tehuacán\",\n  \"Tehuacán\",\n  \"Tehuantepec-Salina Cruz\",\n  \"Tepexpan\",\n  \"Tepic\",\n  \"Tetela de Ocampo\",\n  \"Texcoco de Mora\",\n  \"Tijuana\",\n  \"Tlalnepantla\",\n  \"Tlaquepaque\",\n  \"Tlaxcala-Apizaco\",\n  \"Toluca\",\n  \"Tonalá\",\n  \"Torreón\",\n  \"Tula\",\n  \"Tulancingo\",\n  \"Tulancingo de Bravo\",\n  \"Tuxtla Gutiérrez\",\n  \"Uruapan\",\n  \"Uruapan del Progreso\",\n  \"Valle de México\",\n  \"Veracruz\",\n  \"Villa de Álvarez\",\n  \"Villa Nicolás Romero\",\n  \"Villahermosa\",\n  \"Xalapa\",\n  \"Zacatecas-Guadalupe\",\n  \"Zacatlan\",\n  \"Zacatzingo\",\n  \"Zamora-Jacona\",\n  \"Zapopan\",\n  \"Zitacuaro\"\n];\n\n},{}],412:[function(require,module,exports){\nmodule.exports=require(182)\n},{\"/Users/a/dev/faker.js/lib/locales/en/address/city_suffix.js\":182}],413:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afganistán\",\n  \"Albania\",\n  \"Argelia\",\n  \"Andorra\",\n  \"Angola\",\n  \"Argentina\",\n  \"Armenia\",\n  \"Aruba\",\n  \"Australia\",\n  \"Austria\",\n  \"Azerbayán\",\n  \"Bahamas\",\n  \"Barein\",\n  \"Bangladesh\",\n  \"Barbados\",\n  \"Bielorusia\",\n  \"Bélgica\",\n  \"Belice\",\n  \"Bermuda\",\n  \"Bután\",\n  \"Bolivia\",\n  \"Bosnia Herzegovina\",\n  \"Botswana\",\n  \"Brasil\",\n  \"Bulgaria\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Camboya\",\n  \"Camerún\",\n  \"Canada\",\n  \"Cabo Verde\",\n  \"Islas Caimán\",\n  \"Chad\",\n  \"Chile\",\n  \"China\",\n  \"Isla de Navidad\",\n  \"Colombia\",\n  \"Comodos\",\n  \"Congo\",\n  \"Costa Rica\",\n  \"Costa de Marfil\",\n  \"Croacia\",\n  \"Cuba\",\n  \"Chipre\",\n  \"República Checa\",\n  \"Dinamarca\",\n  \"Dominica\",\n  \"República Dominicana\",\n  \"Ecuador\",\n  \"Egipto\",\n  \"El Salvador\",\n  \"Guinea Ecuatorial\",\n  \"Eritrea\",\n  \"Estonia\",\n  \"Etiopía\",\n  \"Islas Faro\",\n  \"Fiji\",\n  \"Finlandia\",\n  \"Francia\",\n  \"Gabón\",\n  \"Gambia\",\n  \"Georgia\",\n  \"Alemania\",\n  \"Ghana\",\n  \"Grecia\",\n  \"Groenlandia\",\n  \"Granada\",\n  \"Guadalupe\",\n  \"Guam\",\n  \"Guatemala\",\n  \"Guinea\",\n  \"Guinea-Bisau\",\n  \"Guayana\",\n  \"Haiti\",\n  \"Honduras\",\n  \"Hong Kong\",\n  \"Hungria\",\n  \"Islandia\",\n  \"India\",\n  \"Indonesia\",\n  \"Iran\",\n  \"Irak\",\n  \"Irlanda\",\n  \"Italia\",\n  \"Jamaica\",\n  \"Japón\",\n  \"Jordania\",\n  \"Kazajistan\",\n  \"Kenia\",\n  \"Kiribati\",\n  \"Corea\",\n  \"Kuwait\",\n  \"Letonia\",\n  \"Líbano\",\n  \"Liberia\",\n  \"Liechtenstein\",\n  \"Lituania\",\n  \"Luxemburgo\",\n  \"Macao\",\n  \"Macedonia\",\n  \"Madagascar\",\n  \"Malawi\",\n  \"Malasia\",\n  \"Maldivas\",\n  \"Mali\",\n  \"Malta\",\n  \"Martinica\",\n  \"Mauritania\",\n  \"México\",\n  \"Micronesia\",\n  \"Moldavia\",\n  \"Mónaco\",\n  \"Mongolia\",\n  \"Montenegro\",\n  \"Montserrat\",\n  \"Marruecos\",\n  \"Mozambique\",\n  \"Namibia\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Holanda\",\n  \"Nueva Zelanda\",\n  \"Nicaragua\",\n  \"Niger\",\n  \"Nigeria\",\n  \"Noruega\",\n  \"Omán\",\n  \"Pakistan\",\n  \"Panamá\",\n  \"Papúa Nueva Guinea\",\n  \"Paraguay\",\n  \"Perú\",\n  \"Filipinas\",\n  \"Poland\",\n  \"Portugal\",\n  \"Puerto Rico\",\n  \"Rusia\",\n  \"Ruanda\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Santo Tomé y Principe\",\n  \"Arabia Saudí\",\n  \"Senegal\",\n  \"Serbia\",\n  \"Seychelles\",\n  \"Sierra Leona\",\n  \"Singapur\",\n  \"Eslovaquia\",\n  \"Eslovenia\",\n  \"Somalia\",\n  \"España\",\n  \"Sri Lanka\",\n  \"Sudán\",\n  \"Suriname\",\n  \"Suecia\",\n  \"Suiza\",\n  \"Siria\",\n  \"Taiwan\",\n  \"Tajikistan\",\n  \"Tanzania\",\n  \"Tailandia\",\n  \"Timor-Leste\",\n  \"Togo\",\n  \"Tonga\",\n  \"Trinidad y Tobago\",\n  \"Tunez\",\n  \"Turquia\",\n  \"Uganda\",\n  \"Ucrania\",\n  \"Emiratos Árabes Unidos\",\n  \"Reino Unido\",\n  \"Estados Unidos de América\",\n  \"Uruguay\",\n  \"Uzbekistan\",\n  \"Vanuatu\",\n  \"Venezuela\",\n  \"Vietnam\",\n  \"Yemen\",\n  \"Zambia\",\n  \"Zimbabwe\"\n];\n\n},{}],414:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"México\"\n];\n\n},{}],415:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.time_zone = require(\"./time_zone\");\naddress.city = require(\"./city\");\naddress.street = require(\"./street\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n},{\"./building_number\":409,\"./city\":410,\"./city_prefix\":411,\"./city_suffix\":412,\"./country\":413,\"./default_country\":414,\"./postcode\":416,\"./secondary_address\":417,\"./state\":418,\"./state_abbr\":419,\"./street\":420,\"./street_address\":421,\"./street_name\":422,\"./street_suffix\":423,\"./time_zone\":424}],416:[function(require,module,exports){\nmodule.exports=require(379)\n},{\"/Users/a/dev/faker.js/lib/locales/es/address/postcode.js\":379}],417:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Esc. ###\",\n  \"Puerta ###\",\n  \"Edificio #\"\n];\n\n},{}],418:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aguascalientes\",\n  \"Baja California Norte\",\n  \"Baja California Sur\",\n  'Estado de México',\n  \"Campeche\",\n  \"Chiapas\",\n  \"Chihuahua\",\n  \"Coahuila\",\n  \"Colima\",\n  \"Durango\",\n  \"Guanajuato\",\n  \"Guerrero\",\n  \"Hidalgo\",\n  \"Jalisco\",\n  \"Michoacan\",\n  \"Morelos\",\n  \"Nayarit\",\n  'Nuevo León',\n  \"Oaxaca\",\n  \"Puebla\",\n  \"Querétaro\",\n  \"Quintana Roo\",\n  \"San Luis Potosí\",\n  \"Sinaloa\",\n  \"Sonora\",\n  \"Tabasco\",\n  \"Tamaulipas\",\n  \"Tlaxcala\",\n  \"Veracruz\",\n  \"Yucatán\",\n  \"Zacatecas\"\n];\n\n},{}],419:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AS\",\n  \"BC\",\n  \"BS\",\n  \"CC\",\n  \"CS\",\n  \"CH\",\n  \"CL\",\n  \"CM\",\n  \"DF\",\n  \"DG\",\n  \"GT\",\n  \"GR\",\n  \"HG\",\n  \"JC\",\n  \"MC\",\n  \"MN\",\n  \"MS\",\n  \"NT\",\n  \"NL\",\n  \"OC\",\n  \"PL\",\n  \"QT\",\n  \"QR\",\n  \"SP\",\n  \"SL\",\n  \"SR\",\n  \"TC\",\n  \"TS\",\n  \"TL\",\n  \"VZ\",\n  \"YN\",\n  \"ZS\"\n];\n\n},{}],420:[function(require,module,exports){\nmodule[\"exports\"] = [\n\t\"20 de Noviembre\",\n\t\"Cinco de Mayo\",\n\t\"Cuahutemoc\",\n\t\"Manzanares\",\n\t\"Donceles\",\n\t\"Francisco I. Madero\",\n\t\"Juárez\",\n\t\"Repúplica de Cuba\",\n\t\"Repúplica de Chile\",\n\t\"Repúplica de Argentina\",\n\t\"Repúplica de Uruguay\",\n\t\"Isabel la Católica\",\n\t\"Izazaga\",\n\t\"Eje Central\",\n\t\"Eje 6\",\n\t\"Eje 5\",\n\t\"La viga\",\n\t\"Aniceto Ortega\",\n\t\"Miguel Ángel de Quevedo\",\n\t\"Amores\",\n\t\"Coyoacán\",\n\t\"Coruña\",\n\t\"Batalla de Naco\",\n\t\"La otra banda\",\n\t\"Piedra del Comal\",\n\t\"Balcón de los edecanes\",\n\t\"Barrio la Lonja\",\n\t\"Jicolapa\",\n\t\"Zacatlán\",\n\t\"Zapata\",\n\t\"Polotitlan\",\n\t\"Calimaya\",\n\t\"Flor Marina\",\n\t\"Flor Solvestre\",\n\t\"San Miguel\",\n\t\"Naranjo\",\n\t\"Cedro\",\n\t\"Jalisco\",\n\t\"Avena\"\n];\n},{}],421:[function(require,module,exports){\nmodule.exports=require(384)\n},{\"/Users/a/dev/faker.js/lib/locales/es/address/street_address.js\":384}],422:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_suffix} #{Name.first_name}\",\n  \"#{street_suffix} #{Name.first_name} #{Name.last_name}\",\n  \"#{street_suffix} #{street}\",\n  \"#{street_suffix} #{street}\",\n  \"#{street_suffix} #{street}\",\n  \"#{street_suffix} #{street}\"\n\n];\n\n},{}],423:[function(require,module,exports){\nmodule.exports=require(386)\n},{\"/Users/a/dev/faker.js/lib/locales/es/address/street_suffix.js\":386}],424:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Pacífico/Midway\",\n  \"Pacífico/Pago_Pago\",\n  \"Pacífico/Honolulu\",\n  \"America/Juneau\",\n  \"America/Los_Angeles\",\n  \"America/Tijuana\",\n  \"America/Denver\",\n  \"America/Phoenix\",\n  \"America/Chihuahua\",\n  \"America/Mazatlan\",\n  \"America/Chicago\",\n  \"America/Regina\",\n  \"America/Mexico_City\",\n  \"America/Monterrey\",\n  \"America/Guatemala\",\n  \"America/New_York\",\n  \"America/Indiana/Indianapolis\",\n  \"America/Bogota\",\n  \"America/Lima\",\n  \"America/Lima\",\n  \"America/Halifax\",\n  \"America/Caracas\",\n  \"America/La_Paz\",\n  \"America/Santiago\",\n  \"America/St_Johns\",\n  \"America/Sao_Paulo\",\n  \"America/Argentina/Buenos_Aires\",\n  \"America/Guyana\",\n  \"America/Godthab\",\n  \"Atlantic/South_Georgia\",\n  \"Atlantic/Azores\",\n  \"Atlantic/Cape_Verde\",\n  \"Europa/Dublin\",\n  \"Europa/London\",\n  \"Europa/Lisbon\",\n  \"Europa/London\",\n  \"Africa/Casablanca\",\n  \"Africa/Monrovia\",\n  \"Etc/UTC\",\n  \"Europa/Belgrade\",\n  \"Europa/Bratislava\",\n  \"Europa/Budapest\",\n  \"Europa/Ljubljana\",\n  \"Europa/Prague\",\n  \"Europa/Sarajevo\",\n  \"Europa/Skopje\",\n  \"Europa/Warsaw\",\n  \"Europa/Zagreb\",\n  \"Europa/Brussels\",\n  \"Europa/Copenhagen\",\n  \"Europa/Madrid\",\n  \"Europa/Paris\",\n  \"Europa/Amsterdam\",\n  \"Europa/Berlin\",\n  \"Europa/Berlin\",\n  \"Europa/Rome\",\n  \"Europa/Stockholm\",\n  \"Europa/Vienna\",\n  \"Africa/Algiers\",\n  \"Europa/Bucharest\",\n  \"Africa/Cairo\",\n  \"Europa/Helsinki\",\n  \"Europa/Kiev\",\n  \"Europa/Riga\",\n  \"Europa/Sofia\",\n  \"Europa/Tallinn\",\n  \"Europa/Vilnius\",\n  \"Europa/Athens\",\n  \"Europa/Istanbul\",\n  \"Europa/Minsk\",\n  \"Asia/Jerusalen\",\n  \"Africa/Harare\",\n  \"Africa/Johannesburg\",\n  \"Europa/Moscú\",\n  \"Europa/Moscú\",\n  \"Europa/Moscú\",\n  \"Asia/Kuwait\",\n  \"Asia/Riyadh\",\n  \"Africa/Nairobi\",\n  \"Asia/Baghdad\",\n  \"Asia/Tehran\",\n  \"Asia/Muscat\",\n  \"Asia/Muscat\",\n  \"Asia/Baku\",\n  \"Asia/Tbilisi\",\n  \"Asia/Yerevan\",\n  \"Asia/Kabul\",\n  \"Asia/Yekaterinburg\",\n  \"Asia/Karachi\",\n  \"Asia/Karachi\",\n  \"Asia/Tashkent\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kolkata\",\n  \"Asia/Kathmandu\",\n  \"Asia/Dhaka\",\n  \"Asia/Dhaka\",\n  \"Asia/Colombo\",\n  \"Asia/Almaty\",\n  \"Asia/Novosibirsk\",\n  \"Asia/Rangoon\",\n  \"Asia/Bangkok\",\n  \"Asia/Bangkok\",\n  \"Asia/Jakarta\",\n  \"Asia/Krasnoyarsk\",\n  \"Asia/Shanghai\",\n  \"Asia/Chongqing\",\n  \"Asia/Hong_Kong\",\n  \"Asia/Urumqi\",\n  \"Asia/Kuala_Lumpur\",\n  \"Asia/Singapore\",\n  \"Asia/Taipei\",\n  \"Australia/Perth\",\n  \"Asia/Irkutsk\",\n  \"Asia/Ulaanbaatar\",\n  \"Asia/Seoul\",\n  \"Asia/Tokyo\",\n  \"Asia/Tokyo\",\n  \"Asia/Tokyo\",\n  \"Asia/Yakutsk\",\n  \"Australia/Darwin\",\n  \"Australia/Adelaide\",\n  \"Australia/Melbourne\",\n  \"Australia/Melbourne\",\n  \"Australia/Sydney\",\n  \"Australia/Brisbane\",\n  \"Australia/Hobart\",\n  \"Asia/Vladivostok\",\n  \"Pacífico/Guam\",\n  \"Pacífico/Port_Moresby\",\n  \"Asia/Magadan\",\n  \"Asia/Magadan\",\n  \"Pacífico/Noumea\",\n  \"Pacífico/Fiji\",\n  \"Asia/Kamchatka\",\n  \"Pacífico/Majuro\",\n  \"Pacífico/Auckland\",\n  \"Pacífico/Auckland\",\n  \"Pacífico/Tongatapu\",\n  \"Pacífico/Fakaofo\",\n  \"Pacífico/Apia\"\n];\n\n},{}],425:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"5##-###-###\",\n  \"5##.###.###\",\n  \"5## ### ###\",\n  \"5########\"\n];\n\n},{}],426:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":425,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],427:[function(require,module,exports){\nmodule[\"exports\"] = [\n   \"rojo\",\n   \"verde\",\n   \"azul\",\n   \"amarillo\",\n   \"morado\",\n   \"Menta verde\",\n   \"teal\",\n   \"blanco\",\n   \"negro\",\n   \"Naranja\",\n   \"Rosa\",\n   \"gris\",\n   \"marrón\",\n   \"violeta\",\n   \"turquesa\",\n   \"tan\",\n   \"cielo azul\",\n   \"salmón\",\n   \"ciruela\",\n   \"orquídea\",\n   \"aceituna\",\n   \"magenta\",\n   \"Lima\",\n   \"marfil\",\n   \"índigo\",\n   \"oro\",\n   \"fucsia\",\n   \"cian\",\n   \"azul\",\n   \"lavanda\",\n   \"plata\"\n];\n\n},{}],428:[function(require,module,exports){\nmodule[\"exports\"] = [\n   \"Libros\",\n   \"Películas\",\n   \"Música\",\n   \"Juegos\",\n   \"Electrónica\",\n   \"Ordenadores\",\n   \"Hogar\",\n   \"Jardín\",\n   \"Herramientas\",\n   \"Ultramarinos\",\n   \"Salud\",\n   \"Belleza\",\n   \"Juguetes\",\n   \"Kids\",\n   \"Baby\",\n   \"Ropa\",\n   \"Zapatos\",\n   \"Joyería\",\n   \"Deportes\",\n   \"Aire libre\",\n   \"Automoción\",\n   \"Industrial\"\n];\n\n},{}],429:[function(require,module,exports){\narguments[4][31][0].apply(exports,arguments)\n},{\"./color\":427,\"./department\":428,\"./product_name\":430,\"/Users/a/dev/faker.js/lib/locales/az/commerce/index.js\":31}],430:[function(require,module,exports){\nmodule[\"exports\"] = {\n\"adjective\": [\n     \"Pequeño\",\n     \"Ergonómico\",\n     \"Rústico\",\n     \"Inteligente\",\n     \"Gorgeous\",\n     \"Increíble\",\n     \"Fantástico\",\n     \"Práctica\",\n     \"Elegante\",\n     \"Increíble\",\n     \"Genérica\",\n     \"Artesanal\",\n     \"Hecho a mano\",\n     \"Licencia\",\n     \"Refinado\",\n     \"Sin marca\",\n     \"Sabrosa\"\n   ],\n\"material\": [\n     \"Acero\",\n     \"Madera\",\n     \"Hormigón\",\n     \"Plástico\",\n     \"Cotton\",\n     \"Granito\",\n     \"Caucho\",\n     \"Metal\",\n     \"Soft\",\n     \"Fresco\",\n     \"Frozen\"\n   ],\n\"product\": [\n     \"Presidente\",\n     \"Auto\",\n     \"Computadora\",\n     \"Teclado\",\n     \"Ratón\",\n     \"Bike\",\n     \"Pelota\",\n     \"Guantes\",\n     \"Pantalones\",\n     \"Camisa\",\n     \"Mesa\",\n     \"Zapatos\",\n     \"Sombrero\",\n     \"Toallas\",\n     \"Jabón\",\n     \"Tuna\",\n     \"Pollo\",\n     \"Pescado\",\n     \"Queso\",\n     \"Tocino\",\n     \"Pizza\",\n     \"Ensalada\",\n     \"Embutidos\"\n  ]\n};\n\n},{}],431:[function(require,module,exports){\nmodule.exports=require(390)\n},{\"/Users/a/dev/faker.js/lib/locales/es/company/adjective.js\":390}],432:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Clics y mortero\",\n  \"Valor añadido\",\n  \"Vertical\",\n  \"Proactivo\",\n  \"Robusto\",\n  \"Revolucionario\",\n  \"Escalable\",\n  \"De vanguardia\",\n  \"Innovador\",\n  \"Intuitivo\",\n  \"Estratégico\",\n  \"E-business\",\n  \"Misión crítica\",\n  \"Pegajosa\",\n  \"Doce y cincuenta y nueve de la noche\",\n  \"24/7\",\n  \"De extremo a extremo\",\n  \"Global\",\n  \"B2B\",\n  \"B2C\",\n  \"Granular\",\n  \"Fricción\",\n  \"Virtual\",\n  \"Viral\",\n  \"Dinámico\",\n  \"24/365\",\n  \"Mejor de su clase\",\n  \"Asesino\",\n  \"Magnética\",\n  \"Filo sangriento\",\n  \"Habilitado web\",\n  \"Interactiva\",\n  \"Punto com\",\n  \"Sexy\",\n  \"Back-end\",\n  \"Tiempo real\",\n  \"Eficiente\",\n  \"Frontal\",\n  \"Distribuida\",\n  \"Sin costura\",\n  \"Extensible\",\n  \"Llave en mano\",\n  \"Clase mundial\",\n  \"Código abierto\",\n  \"Multiplataforma\",\n  \"Cross-media\",\n  \"Sinérgico\",\n  \"ladrillos y clics\",\n  \"Fuera de la caja\",\n  \"Empresa\",\n  \"Integrado\",\n  \"Impactante\",\n  \"Inalámbrico\",\n  \"Transparente\",\n  \"Próxima generación\",\n  \"Innovador\",\n  \"User-centric\",\n  \"Visionario\",\n  \"A medida\",\n  \"Ubicua\",\n  \"Enchufa y juega\",\n  \"Colaboración\",\n  \"Convincente\",\n  \"Holístico\",\n  \"Ricos\"\n];\n\n},{}],433:[function(require,module,exports){\nmodule[\"exports\"] = [\n   \"sinergias\",\n   \"web-readiness\",\n   \"paradigmas\",\n   \"mercados\",\n   \"asociaciones\",\n   \"infraestructuras\",\n   \"plataformas\",\n   \"iniciativas\",\n   \"canales\",\n   \"ojos\",\n   \"comunidades\",\n   \"ROI\",\n   \"soluciones\",\n   \"minoristas electrónicos\",\n   \"e-servicios\",\n   \"elementos de acción\",\n   \"portales\",\n   \"nichos\",\n   \"tecnologías\",\n   \"contenido\",\n   \"vortales\",\n   \"cadenas de suministro\",\n   \"convergencia\",\n   \"relaciones\",\n   \"arquitecturas\",\n   \"interfaces\",\n   \"mercados electrónicos\",\n   \"e-commerce\",\n   \"sistemas\",\n   \"ancho de banda\",\n   \"infomediarios\",\n   \"modelos\",\n   \"Mindshare\",\n   \"entregables\",\n   \"usuarios\",\n   \"esquemas\",\n   \"redes\",\n   \"aplicaciones\",\n   \"métricas\",\n   \"e-business\",\n   \"funcionalidades\",\n   \"experiencias\",\n   \"servicios web\",\n   \"metodologías\"\n];\n\n},{}],434:[function(require,module,exports){\nmodule[\"exports\"] = [\n   \"poner en práctica\",\n   \"utilizar\",\n   \"integrar\",\n   \"racionalizar\",\n   \"optimizar\",\n   \"evolucionar\",\n   \"transformar\",\n   \"abrazar\",\n   \"habilitar\",\n   \"orquestar\",\n   \"apalancamiento\",\n   \"reinventar\",\n   \"agregado\",\n   \"arquitecto\",\n   \"mejorar\",\n   \"incentivar\",\n   \"transformarse\",\n   \"empoderar\",\n   \"Envisioneer\",\n   \"monetizar\",\n   \"arnés\",\n   \"facilitar\",\n   \"aprovechar\",\n   \"desintermediar\",\n   \"sinergia\",\n   \"estrategias\",\n   \"desplegar\",\n   \"marca\",\n   \"crecer\",\n   \"objetivo\",\n   \"sindicato\",\n   \"sintetizar\",\n   \"entregue\",\n   \"malla\",\n   \"incubar\",\n   \"enganchar\",\n   \"maximizar\",\n   \"punto de referencia\",\n   \"acelerar\",\n   \"reintermediate\",\n   \"pizarra\",\n   \"visualizar\",\n   \"reutilizar\",\n   \"innovar\",\n   \"escala\",\n   \"desatar\",\n   \"conducir\",\n   \"extender\",\n   \"ingeniero\",\n   \"revolucionar\",\n   \"generar\",\n   \"explotar\",\n   \"transición\",\n   \"e-enable\",\n   \"repetir\",\n   \"cultivar\",\n   \"matriz\",\n   \"productize\",\n   \"redefinir\",\n   \"recontextualizar\"\n]\n\n},{}],435:[function(require,module,exports){\nmodule.exports=require(391)\n},{\"/Users/a/dev/faker.js/lib/locales/es/company/descriptor.js\":391}],436:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.adjective = require(\"./adjective\");\ncompany.descriptor = require(\"./descriptor\");\ncompany.noun = require(\"./noun\");\ncompany.bs_verb = require(\"./bs_verb\");\ncompany.name = require(\"./name\");\ncompany.bs_adjective = require(\"./bs_adjective\");\ncompany.bs_noun = require(\"./bs_noun\");\n\n},{\"./adjective\":431,\"./bs_adjective\":432,\"./bs_noun\":433,\"./bs_verb\":434,\"./descriptor\":435,\"./name\":437,\"./noun\":438,\"./suffix\":439}],437:[function(require,module,exports){\nmodule.exports=require(393)\n},{\"/Users/a/dev/faker.js/lib/locales/es/company/name.js\":393}],438:[function(require,module,exports){\nmodule.exports=require(394)\n},{\"/Users/a/dev/faker.js/lib/locales/es/company/noun.js\":394}],439:[function(require,module,exports){\nmodule.exports=require(395)\n},{\"/Users/a/dev/faker.js/lib/locales/es/company/suffix.js\":395}],440:[function(require,module,exports){\nvar es_MX = {};\nmodule['exports'] = es_MX;\nes_MX.title = \"Spanish Mexico\";\nes_MX.separator = \" & \";\nes_MX.name = require(\"./name\");\nes_MX.address = require(\"./address\");\nes_MX.company = require(\"./company\");\nes_MX.internet = require(\"./internet\");\nes_MX.phone_number = require(\"./phone_number\");\nes_MX.cell_phone = require(\"./cell_phone\");\nes_MX.lorem = require(\"./lorem\");\nes_MX.commerce = require(\"./commerce\");\nes_MX.team = require(\"./team\");\n},{\"./address\":415,\"./cell_phone\":426,\"./commerce\":429,\"./company\":436,\"./internet\":443,\"./lorem\":444,\"./name\":448,\"./phone_number\":455,\"./team\":457}],441:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"mx\",\n  \"info\",\n  \"com.mx\",\n  \"org\",\n  \"gob.mx\"\n];\n\n},{}],442:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.com\",\n  \"hotmail.com\",\n  \"nearbpo.com\",\n  \"corpfolder.com\"\n];\n\n},{}],443:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":441,\"./free_email\":442,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],444:[function(require,module,exports){\narguments[4][83][0].apply(exports,arguments)\n},{\"./supplemental\":445,\"./words\":446,\"/Users/a/dev/faker.js/lib/locales/cz/lorem/index.js\":83}],445:[function(require,module,exports){\nmodule.exports=require(84)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/supplemental.js\":84}],446:[function(require,module,exports){\nmodule[\"exports\"] = [\n\"Abacalero\",\n\"Abacería\",\n\"Abacero\",\n\"Abacial\",\n\"Abaco\",\n\"Abacora\",\n\"Abacorar\",\n\"Abad\",\n\"Abada\",\n\"Abadejo\",\n\"Abadengo\",\n\"Abadernar\",\n\"Abadesa\",\n\"Abadí\",\n\"Abadía\",\n\"Abadiado\",\n\"Abadiato\",\n\"Abajadero\",\n\"Abajamiento\",\n\"Abajar\",\n\"Abajeño\",\n\"Abajera\",\n\"Abajo\",\n\"Abalada\",\n\"Abalanzar\",\n\"Abalar\",\n\"Abalaustrado\",\n\"Abaldonadamente\",\n\"Abaldonamiento\",\n\"Bastonada\",\n\"Bastonazo\",\n\"Bastoncillo\",\n\"Bastonear\",\n\"Bastonero\",\n\"Bástulo\",\n\"Basura\",\n\"Basural\",\n\"Basurear\",\n\"Basurero\",\n\"Bata\",\n\"Batacazo\",\n\"Batahola\",\n\"Batalán\",\n\"Batalla\",\n\"Batallador\",\n\"Batallar\",\n\"Batallaroso\",\n\"Batallola\",\n\"Batallón\",\n\"Batallona\",\n\"Batalloso\",\n\"Batán\",\n\"Batanar\",\n\"Batanear\",\n\"Batanero\",\n\"Batanga\",\n\"Bataola\",\n\"Batata\",\n\"Batatazo\",\n\"Batato\",\n\"Batavia\",\n\"Bátavo\",\n\"Batayola\",\n\"Batazo\",\n\"Bate\",\n\"Batea\",\n\"Bateador\",\n\"Bateaguas\",\n\"Cenagar\",\n\"Cenagoso\",\n\"Cenal\",\n\"Cenaoscuras\",\n\"Ceñar\",\n\"Cenata\",\n\"Cenca\",\n\"Cencapa\",\n\"Cencellada\",\n\"Cenceñada\",\n\"Cenceño\",\n\"Cencero\",\n\"Cencerra\",\n\"Cencerrada\",\n\"Cencerrado\",\n\"Cencerrear\",\n\"Cencerreo\",\n\"Cencerril\",\n\"Cencerrillas\",\n\"Cencerro\",\n\"Cencerrón\",\n\"Cencha\",\n\"Cencido\",\n\"Cencío\",\n\"Cencivera\",\n\"Cenco\",\n\"Cencuate\",\n\"Cendal\",\n\"Cendalí\",\n\"Céndea\",\n\"Cendolilla\",\n\"Cendra\",\n\"Cendrada\",\n\"Cendradilla\",\n\"Cendrado\",\n\"Cendrar\",\n\"Cendrazo\",\n\"Cenefa\",\n\"Cenegar\",\n\"Ceneque\",\n\"Cenero\",\n\"Cenestesia\",\n\"Desceñir\",\n\"Descensión\",\n\"Descenso\",\n\"Descentrado\",\n\"Descentralización\",\n\"Descentralizador\",\n\"Descentralizar\",\n\"Descentrar\",\n\"Descepar\",\n\"Descerar\",\n\"Descercado\",\n\"Descercador\",\n\"Descercar\",\n\"Descerco\",\n\"Descerebración\",\n\"Descerebrado\",\n\"Descerebrar\",\n\"Descerezar\",\n\"Descerrajado\",\n\"Descerrajadura\",\n\"Descerrajar\",\n\"Descerrar\",\n\"Descerrumarse\",\n\"Descervigamiento\",\n\"Descervigar\",\n\"Deschapar\",\n\"Descharchar\",\n\"Deschavetado\",\n\"Deschavetarse\",\n\"Deschuponar\",\n\"Descifrable\",\n\"Descifrador\",\n\"Desciframiento\",\n\"Descifrar\",\n\"Descifre\",\n\"Descimbramiento\",\n\"Descimbrar\",\n\"Engarbarse\",\n\"Engarberar\",\n\"Engarbullar\",\n\"Engarce\",\n\"Engarfiar\",\n\"Engargantadura\",\n\"Engargantar\",\n\"Engargante\",\n\"Engargolado\",\n\"Engargolar\",\n\"Engaritar\",\n\"Engarmarse\",\n\"Engarnio\",\n\"Engarrafador\",\n\"Engarrafar\",\n\"Engarrar\",\n\"Engarro\",\n\"Engarronar\",\n\"Engarrotar\",\n\"Engarzador\",\n\"Engarzadura\",\n\"Engarzar\",\n\"Engasgarse\",\n\"Engastador\",\n\"Engastadura\",\n\"Engastar\",\n\"Engaste\",\n\"Ficción\",\n\"Fice\",\n\"Ficha\",\n\"Fichaje\",\n\"Fichar\",\n\"Fichero\",\n\"Ficoideo\",\n\"Ficticio\",\n\"Fidalgo\",\n\"Fidecomiso\",\n\"Fidedigno\",\n\"Fideero\",\n\"Fideicomisario\",\n\"Fideicomiso\",\n\"Fideicomitente\",\n\"Fideísmo\",\n\"Fidelidad\",\n\"Fidelísimo\",\n\"Fideo\",\n\"Fido\",\n\"Fiducia\",\n\"Geminación\",\n\"Geminado\",\n\"Geminar\",\n\"Géminis\",\n\"Gémino\",\n\"Gemíparo\",\n\"Gemiquear\",\n\"Gemiqueo\",\n\"Gemir\",\n\"Gemología\",\n\"Gemológico\",\n\"Gemólogo\",\n\"Gemonias\",\n\"Gemoso\",\n\"Gemoterapia\",\n\"Gen\",\n\"Genciana\",\n\"Gencianáceo\",\n\"Gencianeo\",\n\"Gendarme\",\n\"Gendarmería\",\n\"Genealogía\",\n\"Genealógico\",\n\"Genealogista\",\n\"Genearca\",\n\"Geneático\",\n\"Generable\",\n\"Generación\",\n\"Generacional\",\n\"Generador\",\n\"General\",\n\"Generala\",\n\"Generalato\",\n\"Generalidad\",\n\"Generalísimo\",\n\"Incordio\",\n\"Incorporación\",\n\"Incorporal\",\n\"Incorporalmente\",\n\"Incorporar\",\n\"Incorporeidad\",\n\"Incorpóreo\",\n\"Incorporo\",\n\"Incorrección\",\n\"Incorrectamente\",\n\"Incorrecto\",\n\"Incorregibilidad\",\n\"Incorregible\",\n\"Incorregiblemente\",\n\"Incorrupción\",\n\"Incorruptamente\",\n\"Incorruptibilidad\",\n\"Incorruptible\",\n\"Incorrupto\",\n\"Incrasar\",\n\"Increado\",\n\"Incredibilidad\",\n\"Incrédulamente\",\n\"Incredulidad\",\n\"Incrédulo\",\n\"Increíble\",\n\"Increíblemente\",\n\"Incrementar\",\n\"Incremento\",\n\"Increpación\",\n\"Increpador\",\n\"Increpar\",\n\"Incriminación\",\n\"Incriminar\",\n\"Incristalizable\",\n\"Incruentamente\",\n\"Incruento\",\n\"Incrustación\"\n];\n\n},{}],447:[function(require,module,exports){\nmodule[\"exports\"] = [\n\"Aarón\",\n\"Abraham\",\n\"Adán\",\n\"Agustín\",\n\"Alan\",\n\"Alberto\",\n\"Alejandro\",\n\"Alexander\",\n\"Alexis\",\n\"Alfonso\",\n\"Alfredo\",\n\"Andrés\",\n\"Ángel Daniel\",\n\"Ángel Gabriel\",\n\"Antonio\",\n\"Armando\",\n\"Arturo\",\n\"Axel\",\n\"Benito\",\n\"Benjamín\",\n\"Bernardo\",\n\"Brandon\",\n\"Brayan\",\n\"Carlos\",\n\"César\",\n\"Claudio\",\n\"Clemente\",\n\"Cristian\",\n\"Cristobal\",\n\"Damián\",\n\"Daniel\",\n\"David\",\n\"Diego\",\n\"Eduardo\",\n\"Elías\",\n\"Emiliano\",\n\"Emilio\",\n\"Emilio\",\n\"Emmanuel\",\n\"Enrique\",\n\"Erick\",\n\"Ernesto\",\n\"Esteban\",\n\"Federico\",\n\"Felipe\",\n\"Fernando\",\n\"Fernando Javier\",\n\"Francisco\",\n\"Francisco Javier\",\n\"Gabriel\",\n\"Gael\",\n\"Gerardo\",\n\"Germán\",\n\"Gilberto\",\n\"Gonzalo\",\n\"Gregorio\",\n\"Guillermo\",\n\"Gustavo\",\n\"Hernán\",\n\"Homero\",\n\"Horacio\",\n\"Hugo\",\n\"Ignacio\",\n\"Iker\",\n\"Isaac\",\n\"Isaias\",\n\"Israel\",\n\"Ivan\",\n\"Jacobo\",\n\"Jaime\",\n\"Javier\",\n\"Jerónimo\",\n\"Jesús\",\n\"Joaquín\",\n\"Jorge\",\n\"Jorge Luis\",\n\"José\",\n\"José Antonio\",\n\"Jose Daniel\",\n\"José Eduardo\",\n\"José Emilio\",\n\"José Luis\",\n\"José María\",\n\"José Miguel\",\n\"Juan\",\n\"Juan Carlos\",\n\"Juan Manuel\",\n\"Juan Pablo\",\n\"Julio\",\n\"Julio César\",\n\"Kevin\",\n\"Leonardo\",\n\"Lorenzo\",\n\"Lucas\",\n\"Luis\",\n\"Luis Ángel\",\n\"Luis Fernando\",\n\"Luis Gabino\",\n\"Luis Miguel\",\n\"Manuel\",\n\"Marco Antonio\",\n\"Marcos\",\n\"Mariano\",\n\"Mario\",\n\"Martín\",\n\"Mateo\",\n\"Matías\",\n\"Mauricio\",\n\"Maximiliano\",\n\"Miguel\",\n\"Miguel Ángel\",\n\"Nicolás\",\n\"Octavio\",\n\"Óscar\",\n\"Pablo\",\n\"Patricio\",\n\"Pedro\",\n\"Rafael\",\n\"Ramiro\",\n\"Ramón\",\n\"Raúl\",\n\"Ricardo\",\n\"Roberto\",\n\"Rodrigo\",\n\"Rubén\",\n\"Salvador\",\n\"Samuel\",\n\"Sancho\",\n\"Santiago\",\n\"Saúl\",\n\"Sebastian\",\n\"Sergio\",\n\"Tadeo\",\n\"Teodoro\",\n\"Timoteo\",\n\"Tomás\",\n\"Uriel\",\n\"Vicente\",\n\"Víctor\",\n\"Victor Manuel\",\n\"Adriana\",\n\"Alejandra\",\n\"Alicia\",\n\"Amalia\",\n\"Ana\",\n\"Ana Luisa\",\n\"Ana María\",\n\"Andrea\",\n\"Ángela\",\n\"Anita\",\n\"Antonia\",\n\"Araceli\",\n\"Ariadna\",\n\"Barbara\",\n\"Beatriz\",\n\"Berta\",\n\"Blanca\",\n\"Caridad\",\n\"Carla\",\n\"Carlota\",\n\"Carmen\",\n\"Carolina\",\n\"Catalina\",\n\"Cecilia\",\n\"Clara\",\n\"Claudia\",\n\"Concepción\",\n\"Conchita\",\n\"Cristina\",\n\"Daniela\",\n\"Débora\",\n\"Diana\",\n\"Dolores\",\n\"Dorotea\",\n\"Elena\",\n\"Elisa\",\n\"Elizabeth\",\n\"Eloisa\",\n\"Elsa\",\n\"Elvira\",\n\"Emilia\",\n\"Esperanza\",\n\"Estela\",\n\"Ester\",\n\"Eva\",\n\"Florencia\",\n\"Francisca\",\n\"Gabriela\",\n\"Gloria\",\n\"Graciela\",\n\"Guadalupe\",\n\"Guillermina\",\n\"Inés\",\n\"Irene\",\n\"Isabel\",\n\"Isabela\",\n\"Josefina\",\n\"Juana\",\n\"Julia\",\n\"Laura\",\n\"Leonor\",\n\"Leticia\",\n\"Lilia\",\n\"Lola\",\n\"Lorena\",\n\"Lourdes\",\n\"Lucia\",\n\"Luisa\",\n\"Luz\",\n\"Magdalena\",\n\"Manuela\",\n\"Marcela\",\n\"Margarita\",\n\"María\",\n\"María Cristina\",\n\"María de Jesús\",\n\"María de los Ángeles\",\n\"María del Carmen\",\n\"María Elena\",\n\"María Eugenia\",\n\"María Guadalupe\",\n\"María José\",\n\"María Luisa\",\n\"María Soledad\",\n\"María Teresa\",\n\"Mariana\",\n\"Maricarmen\",\n\"Marilu\",\n\"Marisol\",\n\"Marta\",\n\"Mayte\",\n\"Mercedes\",\n\"Micaela\",\n\"Mónica\",\n\"Natalia\",\n\"Norma\",\n\"Olivia\",\n\"Patricia\",\n\"Pilar\",\n\"Ramona\",\n\"Raquel\",\n\"Rebeca\",\n\"Reina\",\n\"Rocio\",\n\"Rosa\",\n\"Rosa María\",\n\"Rosalia\",\n\"Rosario\",\n\"Sara\",\n\"Silvia\",\n\"Sofia\",\n\"Soledad\",\n\"Sonia\",\n\"Susana\",\n\"Teresa\",\n\"Verónica\",\n\"Victoria\",\n\"Virginia\",\n\"Xochitl\",\n\"Yolanda\",\n\"Abigail\",\n\"Abril\",\n\"Adela\",\n\"Alexa\",\n\"Alondra Romina\",\n\"Ana Sofía\",\n\"Ana Victoria\",\n\"Camila\",\n\"Carolina\",\n\"Daniela\",\n\"Dulce María\",\n\"Emily\",\n\"Esmeralda\",\n\"Estefanía\",\n\"Evelyn\",\n\"Fatima\",\n\"Ivanna\",\n\"Jazmin\",\n\"Jennifer\",\n\"Jimena\",\n\"Julieta\",\n\"Kimberly\",\n\"Liliana\",\n\"Lizbeth\",\n\"María Fernanda\",\n\"Melany\",\n\"Melissa\",\n\"Miranda\",\n\"Monserrat\",\n\"Naomi\",\n\"Natalia\",\n\"Nicole\",\n\"Paola\",\n\"Paulina\",\n\"Regina\",\n\"Renata\",\n\"Valentina\",\n\"Valeria\",\n\"Vanessa\",\n\"Ximena\",\n\"Ximena Guadalupe\",\n\"Yamileth\",\n\"Yaretzi\",\n\"Zoe\"\n]\n},{}],448:[function(require,module,exports){\narguments[4][259][0].apply(exports,arguments)\n},{\"./first_name\":447,\"./last_name\":449,\"./name\":450,\"./prefix\":451,\"./suffix\":452,\"./title\":453,\"/Users/a/dev/faker.js/lib/locales/en/name/index.js\":259}],449:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abeyta\",\n\"Abrego\",\n\"Abreu\",\n\"Acevedo\",\n\"Acosta\",\n\"Acuña\",\n\"Adame\",\n\"Adorno\",\n\"Agosto\",\n\"Aguayo\",\n\"Águilar\",\n\"Aguilera\",\n\"Aguirre\",\n\"Alanis\",\n\"Alaniz\",\n\"Alarcón\",\n\"Alba\",\n\"Alcala\",\n\"Alcántar\",\n\"Alcaraz\",\n\"Alejandro\",\n\"Alemán\",\n\"Alfaro\",\n\"Alicea\",\n\"Almanza\",\n\"Almaraz\",\n\"Almonte\",\n\"Alonso\",\n\"Alonzo\",\n\"Altamirano\",\n\"Alva\",\n\"Alvarado\",\n\"Alvarez\",\n\"Amador\",\n\"Amaya\",\n\"Anaya\",\n\"Anguiano\",\n\"Angulo\",\n\"Aparicio\",\n\"Apodaca\",\n\"Aponte\",\n\"Aragón\",\n\"Aranda\",\n\"Araña\",\n\"Arce\",\n\"Archuleta\",\n\"Arellano\",\n\"Arenas\",\n\"Arevalo\",\n\"Arguello\",\n\"Arias\",\n\"Armas\",\n\"Armendáriz\",\n\"Armenta\",\n\"Armijo\",\n\"Arredondo\",\n\"Arreola\",\n\"Arriaga\",\n\"Arroyo\",\n\"Arteaga\",\n\"Atencio\",\n\"Ávalos\",\n\"Ávila\",\n\"Avilés\",\n\"Ayala\",\n\"Baca\",\n\"Badillo\",\n\"Báez\",\n\"Baeza\",\n\"Bahena\",\n\"Balderas\",\n\"Ballesteros\",\n\"Banda\",\n\"Bañuelos\",\n\"Barajas\",\n\"Barela\",\n\"Barragán\",\n\"Barraza\",\n\"Barrera\",\n\"Barreto\",\n\"Barrientos\",\n\"Barrios\",\n\"Batista\",\n\"Becerra\",\n\"Beltrán\",\n\"Benavides\",\n\"Benavídez\",\n\"Benítez\",\n\"Bermúdez\",\n\"Bernal\",\n\"Berríos\",\n\"Bétancourt\",\n\"Blanco\",\n\"Bonilla\",\n\"Borrego\",\n\"Botello\",\n\"Bravo\",\n\"Briones\",\n\"Briseño\",\n\"Brito\",\n\"Bueno\",\n\"Burgos\",\n\"Bustamante\",\n\"Bustos\",\n\"Caballero\",\n\"Cabán\",\n\"Cabrera\",\n\"Cadena\",\n\"Caldera\",\n\"Calderón\",\n\"Calvillo\",\n\"Camacho\",\n\"Camarillo\",\n\"Campos\",\n\"Canales\",\n\"Candelaria\",\n\"Cano\",\n\"Cantú\",\n\"Caraballo\",\n\"Carbajal\",\n\"Cardenas\",\n\"Cardona\",\n\"Carmona\",\n\"Carranza\",\n\"Carrasco\",\n\"Carrasquillo\",\n\"Carreón\",\n\"Carrera\",\n\"Carrero\",\n\"Carrillo\",\n\"Carrion\",\n\"Carvajal\",\n\"Casanova\",\n\"Casares\",\n\"Casárez\",\n\"Casas\",\n\"Casillas\",\n\"Castañeda\",\n\"Castellanos\",\n\"Castillo\",\n\"Castro\",\n\"Cavazos\",\n\"Cazares\",\n\"Ceballos\",\n\"Cedillo\",\n\"Ceja\",\n\"Centeno\",\n\"Cepeda\",\n\"Cerda\",\n\"Cervantes\",\n\"Cervántez\",\n\"Chacón\",\n\"Chapa\",\n\"Chavarría\",\n\"Chávez\",\n\"Cintrón\",\n\"Cisneros\",\n\"Collado\",\n\"Collazo\",\n\"Colón\",\n\"Colunga\",\n\"Concepción\",\n\"Contreras\",\n\"Cordero\",\n\"Córdova\",\n\"Cornejo\",\n\"Corona\",\n\"Coronado\",\n\"Corral\",\n\"Corrales\",\n\"Correa\",\n\"Cortés\",\n\"Cortez\",\n\"Cotto\",\n\"Covarrubias\",\n\"Crespo\",\n\"Cruz\",\n\"Cuellar\",\n\"Curiel\",\n\"Dávila\",\n\"de Anda\",\n\"de Jesús\",\n\"Delacrúz\",\n\"Delafuente\",\n\"Delagarza\",\n\"Delao\",\n\"Delapaz\",\n\"Delarosa\",\n\"Delatorre\",\n\"Deleón\",\n\"Delgadillo\",\n\"Delgado\",\n\"Delrío\",\n\"Delvalle\",\n\"Díaz\",\n\"Domínguez\",\n\"Domínquez\",\n\"Duarte\",\n\"Dueñas\",\n\"Duran\",\n\"Echevarría\",\n\"Elizondo\",\n\"Enríquez\",\n\"Escalante\",\n\"Escamilla\",\n\"Escobar\",\n\"Escobedo\",\n\"Esparza\",\n\"Espinal\",\n\"Espino\",\n\"Espinosa\",\n\"Espinoza\",\n\"Esquibel\",\n\"Esquivel\",\n\"Estévez\",\n\"Estrada\",\n\"Fajardo\",\n\"Farías\",\n\"Feliciano\",\n\"Fernández\",\n\"Ferrer\",\n\"Fierro\",\n\"Figueroa\",\n\"Flores\",\n\"Flórez\",\n\"Fonseca\",\n\"Franco\",\n\"Frías\",\n\"Fuentes\",\n\"Gaitán\",\n\"Galarza\",\n\"Galindo\",\n\"Gallardo\",\n\"Gallegos\",\n\"Galván\",\n\"Gálvez\",\n\"Gamboa\",\n\"Gamez\",\n\"Gaona\",\n\"Garay\",\n\"García\",\n\"Garibay\",\n\"Garica\",\n\"Garrido\",\n\"Garza\",\n\"Gastélum\",\n\"Gaytán\",\n\"Gil\",\n\"Girón\",\n\"Godínez\",\n\"Godoy\",\n\"Gollum\",\n\"Gómez\",\n\"Gonzales\",\n\"González\",\n\"Gracia\",\n\"Granado\",\n\"Granados\",\n\"Griego\",\n\"Grijalva\",\n\"Guajardo\",\n\"Guardado\",\n\"Guerra\",\n\"Guerrero\",\n\"Guevara\",\n\"Guillen\",\n\"Gurule\",\n\"Gutiérrez\",\n\"Guzmán\",\n\"Haro\",\n\"Henríquez\",\n\"Heredia\",\n\"Hernádez\",\n\"Hernandes\",\n\"Hernández\",\n\"Herrera\",\n\"Hidalgo\",\n\"Hinojosa\",\n\"Holguín\",\n\"Huerta\",\n\"Huixtlacatl\",\n\"Hurtado\",\n\"Ibarra\",\n\"Iglesias\",\n\"Irizarry\",\n\"Jaime\",\n\"Jaimes\",\n\"Jáquez\",\n\"Jaramillo\",\n\"Jasso\",\n\"Jiménez\",\n\"Jimínez\",\n\"Juárez\",\n\"Jurado\",\n\"Kadar rodriguez\",\n\"Kamal\",\n\"Kamat\",\n\"Kanaria\",\n\"Kanea\",\n\"Kanimal\",\n\"Kano\",\n\"Kanzaki\",\n\"Kaplan\",\n\"Kara\",\n\"Karam\",\n\"Karan\",\n\"Kardache soto\",\n\"Karem\",\n\"Karen\",\n\"Khalid\",\n\"Kindelan\",\n\"Koenig\",\n\"Korta\",\n\"Korta hernandez\",\n\"Kortajarena\",\n\"Kranz sans\",\n\"Krasnova\",\n\"Krauel natera\",\n\"Kuzmina\",\n\"Kyra\",\n\"Laboy\",\n\"Lara\",\n\"Laureano\",\n\"Leal\",\n\"Lebrón\",\n\"Ledesma\",\n\"Leiva\",\n\"Lemus\",\n\"León\",\n\"Lerma\",\n\"Leyva\",\n\"Limón\",\n\"Linares\",\n\"Lira\",\n\"Llamas\",\n\"Loera\",\n\"Lomeli\",\n\"Longoria\",\n\"López\",\n\"Lovato\",\n\"Loya\",\n\"Lozada\",\n\"Lozano\",\n\"Lucero\",\n\"Lucio\",\n\"Luevano\",\n\"Lugo\",\n\"Luna\",\n\"Macías\",\n\"Madera\",\n\"Madrid\",\n\"Madrigal\",\n\"Maestas\",\n\"Magaña\",\n\"Malave\",\n\"Maldonado\",\n\"Manzanares\",\n\"Mares\",\n\"Marín\",\n\"Márquez\",\n\"Marrero\",\n\"Marroquín\",\n\"Martínez\",\n\"Mascareñas\",\n\"Mata\",\n\"Mateo\",\n\"Matías\",\n\"Matos\",\n\"Maya\",\n\"Mayorga\",\n\"Medina\",\n\"Medrano\",\n\"Mejía\",\n\"Meléndez\",\n\"Melgar\",\n\"Mena\",\n\"Menchaca\",\n\"Méndez\",\n\"Mendoza\",\n\"Menéndez\",\n\"Meraz\",\n\"Mercado\",\n\"Merino\",\n\"Mesa\",\n\"Meza\",\n\"Miramontes\",\n\"Miranda\",\n\"Mireles\",\n\"Mojica\",\n\"Molina\",\n\"Mondragón\",\n\"Monroy\",\n\"Montalvo\",\n\"Montañez\",\n\"Montaño\",\n\"Montemayor\",\n\"Montenegro\",\n\"Montero\",\n\"Montes\",\n\"Montez\",\n\"Montoya\",\n\"Mora\",\n\"Morales\",\n\"Moreno\",\n\"Mota\",\n\"Moya\",\n\"Munguía\",\n\"Muñiz\",\n\"Muñoz\",\n\"Murillo\",\n\"Muro\",\n\"Nájera\",\n\"Naranjo\",\n\"Narváez\",\n\"Nava\",\n\"Navarrete\",\n\"Navarro\",\n\"Nazario\",\n\"Negrete\",\n\"Negrón\",\n\"Nevárez\",\n\"Nieto\",\n\"Nieves\",\n\"Niño\",\n\"Noriega\",\n\"Núñez\",\n\"Ñañez\",\n\"Ocampo\",\n\"Ocasio\",\n\"Ochoa\",\n\"Ojeda\",\n\"Olivares\",\n\"Olivárez\",\n\"Olivas\",\n\"Olivera\",\n\"Olivo\",\n\"Olmos\",\n\"Olvera\",\n\"Ontiveros\",\n\"Oquendo\",\n\"Ordóñez\",\n\"Orellana\",\n\"Ornelas\",\n\"Orosco\",\n\"Orozco\",\n\"Orta\",\n\"Ortega\",\n\"Ortiz\",\n\"Osorio\",\n\"Otero\",\n\"Ozuna\",\n\"Pabón\",\n\"Pacheco\",\n\"Padilla\",\n\"Padrón\",\n\"Páez\",\n\"Pagan\",\n\"Palacios\",\n\"Palomino\",\n\"Palomo\",\n\"Pantoja\",\n\"Paredes\",\n\"Parra\",\n\"Partida\",\n\"Patiño\",\n\"Paz\",\n\"Pedraza\",\n\"Pedroza\",\n\"Pelayo\",\n\"Peña\",\n\"Perales\",\n\"Peralta\",\n\"Perea\",\n\"Peres\",\n\"Pérez\",\n\"Pichardo\",\n\"Pineda\",\n\"Piña\",\n\"Pizarro\",\n\"Polanco\",\n\"Ponce\",\n\"Porras\",\n\"Portillo\",\n\"Posada\",\n\"Prado\",\n\"Preciado\",\n\"Prieto\",\n\"Puente\",\n\"Puga\",\n\"Pulido\",\n\"Quesada\",\n\"Quevedo\",\n\"Quezada\",\n\"Quinta\",\n\"Quintairos\",\n\"Quintana\",\n\"Quintanilla\",\n\"Quintero\",\n\"Quintero cruz\",\n\"Quintero de la cruz\",\n\"Quiñones\",\n\"Quiñónez\",\n\"Quiros\",\n\"Quiroz\",\n\"Rael\",\n\"Ramírez\",\n\"Ramón\",\n\"Ramos\",\n\"Rangel\",\n\"Rascón\",\n\"Raya\",\n\"Razo\",\n\"Regalado\",\n\"Rendón\",\n\"Rentería\",\n\"Reséndez\",\n\"Reyes\",\n\"Reyna\",\n\"Reynoso\",\n\"Rico\",\n\"Rincón\",\n\"Riojas\",\n\"Ríos\",\n\"Rivas\",\n\"Rivera\",\n\"Rivero\",\n\"Robledo\",\n\"Robles\",\n\"Rocha\",\n\"Rodarte\",\n\"Rodrígez\",\n\"Rodríguez\",\n\"Rodríquez\",\n\"Rojas\",\n\"Rojo\",\n\"Roldán\",\n\"Rolón\",\n\"Romero\",\n\"Romo\",\n\"Roque\",\n\"Rosado\",\n\"Rosales\",\n\"Rosario\",\n\"Rosas\",\n\"Roybal\",\n\"Rubio\",\n\"Ruelas\",\n\"Ruiz\",\n\"Saavedra\",\n\"Sáenz\",\n\"Saiz\",\n\"Salas\",\n\"Salazar\",\n\"Salcedo\",\n\"Salcido\",\n\"Saldaña\",\n\"Saldivar\",\n\"Salgado\",\n\"Salinas\",\n\"Samaniego\",\n\"Sanabria\",\n\"Sanches\",\n\"Sánchez\",\n\"Sandoval\",\n\"Santacruz\",\n\"Santana\",\n\"Santiago\",\n\"Santillán\",\n\"Sarabia\",\n\"Sauceda\",\n\"Saucedo\",\n\"Sedillo\",\n\"Segovia\",\n\"Segura\",\n\"Sepúlveda\",\n\"Serna\",\n\"Serrano\",\n\"Serrato\",\n\"Sevilla\",\n\"Sierra\",\n\"Sisneros\",\n\"Solano\",\n\"Solís\",\n\"Soliz\",\n\"Solorio\",\n\"Solorzano\",\n\"Soria\",\n\"Sosa\",\n\"Sotelo\",\n\"Soto\",\n\"Suárez\",\n\"Tafoya\",\n\"Tamayo\",\n\"Tamez\",\n\"Tapia\",\n\"Tejada\",\n\"Tejeda\",\n\"Téllez\",\n\"Tello\",\n\"Terán\",\n\"Terrazas\",\n\"Tijerina\",\n\"Tirado\",\n\"Toledo\",\n\"Toro\",\n\"Torres\",\n\"Tórrez\",\n\"Tovar\",\n\"Trejo\",\n\"Treviño\",\n\"Trujillo\",\n\"Ulibarri\",\n\"Ulloa\",\n\"Urbina\",\n\"Ureña\",\n\"Urías\",\n\"Uribe\",\n\"Urrutia\",\n\"Vaca\",\n\"Valadez\",\n\"Valdés\",\n\"Valdez\",\n\"Valdivia\",\n\"Valencia\",\n\"Valentín\",\n\"Valenzuela\",\n\"Valladares\",\n\"Valle\",\n\"Vallejo\",\n\"Valles\",\n\"Valverde\",\n\"Vanegas\",\n\"Varela\",\n\"Vargas\",\n\"Vásquez\",\n\"Vázquez\",\n\"Vega\",\n\"Vela\",\n\"Velasco\",\n\"Velásquez\",\n\"Velázquez\",\n\"Vélez\",\n\"Véliz\",\n\"Venegas\",\n\"Vera\",\n\"Verdugo\",\n\"Verduzco\",\n\"Vergara\",\n\"Viera\",\n\"Vigil\",\n\"Villa\",\n\"Villagómez\",\n\"Villalobos\",\n\"Villalpando\",\n\"Villanueva\",\n\"Villareal\",\n\"Villarreal\",\n\"Villaseñor\",\n\"Villegas\",\n\"Xacon\",\n\"Xairo Belmonte\",\n\"Xana\",\n\"Xenia\",\n\"Xiana\",\n\"Xicoy\",\n\"Yago\",\n\"Yami\",\n\"Yanes\",\n\"Yáñez\",\n\"Ybarra\",\n\"Yebra\",\n\"Yunta\",\n\"Zabaleta\",\n\"Zamarreno\",\n\"Zamarripa\",\n\"Zambrana\",\n\"Zambrano\",\n\"Zamora\",\n\"Zamudio\",\n\"Zapata\",\n\"Zaragoza\",\n\"Zarate\",\n\"Zavala\",\n\"Zayas\",\n\"Zelaya\",\n\"Zepeda\",\n\"Zúñiga\"\n];\n\n},{}],450:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name} de #{last_name}\",\n  \"#{suffix} #{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name}\"\n];\n\n},{}],451:[function(require,module,exports){\nmodule.exports=require(404)\n},{\"/Users/a/dev/faker.js/lib/locales/es/name/prefix.js\":404}],452:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Jr.\",\n  \"Sr.\",\n  \"I\",\n  \"II\",\n  \"III\",\n  \"IV\",\n  \"V\",\n  \"MD\",\n  \"DDS\",\n  \"PhD\",\n  \"DVM\",\n  \"Ing.\",\n  \"Lic.\",\n  \"Dr.\",\n  \"Mtro.\"\n];\n\n},{}],453:[function(require,module,exports){\n module[\"exports\"] = {\n  \"descriptor\": [\n    \"Jefe\",\n    \"Senior\",\n    \"Directo\",\n    \"Corporativo\",\n    \"Dinánmico\",\n    \"Futuro\",\n    \"Producto\",\n    \"Nacional\",\n    \"Regional\",\n    \"Distrito\",\n    \"Central\",\n    \"Global\",\n    \"Cliente\",\n    \"Inversor\",\n    \"International\",\n    \"Heredado\",\n    \"Adelante\",\n    \"Interno\",\n    \"Humano\",\n    \"Gerente\",\n    \"SubGerente\",\n    \"Director\"\n  ],\n  \"level\": [\n    \"Soluciones\",\n    \"Programa\",\n    \"Marca\",\n    \"Seguridad\",\n    \"Investigación\",\n    \"Marketing\",\n    \"Normas\",\n    \"Implementación\",\n    \"Integración\",\n    \"Funcionalidad\",\n    \"Respuesta\",\n    \"Paradigma\",\n    \"Tácticas\",\n    \"Identidad\",\n    \"Mercados\",\n    \"Grupo\",\n    \"División\",\n    \"Aplicaciones\",\n    \"Optimización\",\n    \"Operaciones\",\n    \"Infraestructura\",\n    \"Intranet\",\n    \"Comunicaciones\",\n    \"Web\",\n    \"Calidad\",\n    \"Seguro\",\n    \"Mobilidad\",\n    \"Cuentas\",\n    \"Datos\",\n    \"Creativo\",\n    \"Configuración\",\n    \"Contabilidad\",\n    \"Interacciones\",\n    \"Factores\",\n    \"Usabilidad\",\n    \"Métricas\",\n  ],\n  \"job\": [\n    \"Supervisor\",\n    \"Asociado\",\n    \"Ejecutivo\",\n    \"Relacciones\",\n    \"Oficial\",\n    \"Gerente\",\n    \"Ingeniero\",\n    \"Especialista\",\n    \"Director\",\n    \"Coordinador\",\n    \"Administrador\",\n    \"Arquitecto\",\n    \"Analista\",\n    \"Diseñador\",\n    \"Planificador\",\n    \"Técnico\",\n    \"Funcionario\",\n    \"Desarrollador\",\n    \"Productor\",\n    \"Consultor\",\n    \"Asistente\",\n    \"Facilitador\",\n    \"Agente\",\n    \"Representante\",\n    \"Estratega\",\n    \"Scrum Master\",\n    \"Scrum Owner\",\n    \"Product Owner\",\n    \"Scrum Developer\"\n  ]\n};\n\n},{}],454:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"5###-###-###\",\n  \"5##.###.###\",\n  \"5## ### ###\",\n  \"5########\"\n];\n\n},{}],455:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":454,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],456:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"hormigas\",\n   \"murciélagos\",\n   \"osos\",\n   \"abejas\",\n   \"pájaros\",\n   \"búfalo\",\n   \"gatos\",\n   \"pollos\",\n   \"ganado\",\n   \"perros\",\n   \"delfines\",\n   \"patos\",\n   \"elefantes\",\n   \"peces\",\n   \"zorros\",\n   \"ranas\",\n   \"gansos\",\n   \"cabras\",\n   \"caballos\",\n   \"canguros\",\n   \"leones\",\n   \"monos\",\n   \"búhos\",\n   \"bueyes\",\n   \"pingüinos\",\n   \"pueblo\",\n   \"cerdos\",\n   \"conejos\",\n   \"ovejas\",\n   \"tigres\",\n   \"ballenas\",\n   \"lobos\",\n   \"cebras\",\n   \"almas en pena\",\n   \"cuervos\",\n   \"gatos negros\",\n   \"quimeras\",\n   \"fantasmas\",\n   \"conspiradores\",\n   \"dragones\",\n   \"enanos\",\n   \"duendes\",\n   \"encantadores\",\n   \"exorcistas\",\n   \"hijos\",\n   \"enemigos\",\n   \"gigantes\",\n   \"gnomos\",\n   \"duendes\",\n   \"gansos\",\n   \"grifos\",\n   \"licántropos\",\n   \"némesis\",\n   \"ogros\",\n   \"oráculos\",\n   \"profetas\",\n   \"hechiceros\",\n   \"arañas\",\n   \"espíritus\",\n   \"vampiros\",\n   \"brujos\",\n   \"zorras\",\n   \"hombres lobo\",\n   \"brujas\",\n   \"adoradores\",\n   \"zombies\",\n   \"druidas\"\n];\n\n},{}],457:[function(require,module,exports){\narguments[4][270][0].apply(exports,arguments)\n},{\"./creature\":456,\"./name\":458,\"/Users/a/dev/faker.js/lib/locales/en/team/index.js\":270}],458:[function(require,module,exports){\nmodule.exports=require(271)\n},{\"/Users/a/dev/faker.js/lib/locales/en/team/name.js\":271}],459:[function(require,module,exports){\nvar fa = {};\nmodule['exports'] = fa;\nfa.title = \"Farsi\";\nfa.name = require(\"./name\");\n\n},{\"./name\":461}],460:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"آونگ\",\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  \"اوستا\",\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  \"بهاره\",\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  \"پرویز\",\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  \"تاباندخت\",\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  \"جهان بانو\",\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  \"دل آرا\",\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  \"رامونا\",\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  \"زادماسب\",\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  \"ساناز\",\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  \"سوزه\",\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  \"شباهنگ\",\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  \"شهره\",\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  \"فرامرز\",\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  \"فرنود\",\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  \"کابان\",\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  \"کیارش\",\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  \"گل آذین\",\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  \"گلرو\",\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  \"لومانا\",\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  \"مژگان\",\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  \"مهرانفر\",\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  \"مینا دخت\",\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  \"نگاره\",\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  \"نیما\",\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  \"هوردخت\",\n  \"هورزاد\",\n  \"هورمند\",\n  \"هوروش\",\n  \"هوشنگ\",\n  \"هوشیار\",\n  \"هومان\",\n  \"هومن\",\n  \"هونام\",\n  \"هویدا\",\n  \"هیتاسب\",\n  \"هیرمند\",\n  \"هیما\",\n  \"هیوا\",\n  \"یادگار\",\n  \"یاسمن ( یاسمین )\",\n  \"یاشار\",\n  \"یاور\",\n  \"یزدان\",\n  \"یگانه\",\n  \"یوشیتا\"\n];\n\n},{}],461:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\n\n},{\"./first_name\":460,\"./last_name\":462,\"./prefix\":463}],462:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"فرشیدورد\",\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  \"کلباسی\",\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  \"مرادخانی\",\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  \"میرسپاسی\",\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  \"هروی\",\n  \"همایون\",\n  \"همت\",\n  \"همدانی\",\n  \"هوشیار\",\n  \"هومن\",\n  \"یاحقی\",\n  \"یادگار\",\n  \"یثربی\",\n  \"یلدا\"\n];\n\n},{}],463:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"آقای\",\n  \"خانم\",\n  \"دکتر\"\n];\n\n},{}],464:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"####\",\n  \"###\",\n  \"##\",\n  \"#\"\n];\n\n},{}],465:[function(require,module,exports){\nmodule.exports=require(55)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/city.js\":55}],466:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Paris\",\n  \"Marseille\",\n  \"Lyon\",\n  \"Toulouse\",\n  \"Nice\",\n  \"Nantes\",\n  \"Strasbourg\",\n  \"Montpellier\",\n  \"Bordeaux\",\n  \"Lille13\",\n  \"Rennes\",\n  \"Reims\",\n  \"Le Havre\",\n  \"Saint-Étienne\",\n  \"Toulon\",\n  \"Grenoble\",\n  \"Dijon\",\n  \"Angers\",\n  \"Saint-Denis\",\n  \"Villeurbanne\",\n  \"Le Mans\",\n  \"Aix-en-Provence\",\n  \"Brest\",\n  \"Nîmes\",\n  \"Limoges\",\n  \"Clermont-Ferrand\",\n  \"Tours\",\n  \"Amiens\",\n  \"Metz\",\n  \"Perpignan\",\n  \"Besançon\",\n  \"Orléans\",\n  \"Boulogne-Billancourt\",\n  \"Mulhouse\",\n  \"Rouen\",\n  \"Caen\",\n  \"Nancy\",\n  \"Saint-Denis\",\n  \"Saint-Paul\",\n  \"Montreuil\",\n  \"Argenteuil\",\n  \"Roubaix\",\n  \"Dunkerque14\",\n  \"Tourcoing\",\n  \"Nanterre\",\n  \"Avignon\",\n  \"Créteil\",\n  \"Poitiers\",\n  \"Fort-de-France\",\n  \"Courbevoie\",\n  \"Versailles\",\n  \"Vitry-sur-Seine\",\n  \"Colombes\",\n  \"Pau\",\n  \"Aulnay-sous-Bois\",\n  \"Asnières-sur-Seine\",\n  \"Rueil-Malmaison\",\n  \"Saint-Pierre\",\n  \"Antibes\",\n  \"Saint-Maur-des-Fossés\",\n  \"Champigny-sur-Marne\",\n  \"La Rochelle\",\n  \"Aubervilliers\",\n  \"Calais\",\n  \"Cannes\",\n  \"Le Tampon\",\n  \"Béziers\",\n  \"Colmar\",\n  \"Bourges\",\n  \"Drancy\",\n  \"Mérignac\",\n  \"Saint-Nazaire\",\n  \"Valence\",\n  \"Ajaccio\",\n  \"Issy-les-Moulineaux\",\n  \"Villeneuve-d'Ascq\",\n  \"Levallois-Perret\",\n  \"Noisy-le-Grand\",\n  \"Quimper\",\n  \"La Seyne-sur-Mer\",\n  \"Antony\",\n  \"Troyes\",\n  \"Neuilly-sur-Seine\",\n  \"Sarcelles\",\n  \"Les Abymes\",\n  \"Vénissieux\",\n  \"Clichy\",\n  \"Lorient\",\n  \"Pessac\",\n  \"Ivry-sur-Seine\",\n  \"Cergy\",\n  \"Cayenne\",\n  \"Niort\",\n  \"Chambéry\",\n  \"Montauban\",\n  \"Saint-Quentin\",\n  \"Villejuif\",\n  \"Hyères\",\n  \"Beauvais\",\n  \"Cholet\"\n];\n\n},{}],467:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"France\"\n];\n\n},{}],468:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.building_number = require(\"./building_number\");\naddress.street_prefix = require(\"./street_prefix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":464,\"./city\":465,\"./city_name\":466,\"./default_country\":467,\"./postcode\":469,\"./secondary_address\":470,\"./state\":471,\"./street_address\":472,\"./street_name\":473,\"./street_prefix\":474,\"./street_suffix\":475}],469:[function(require,module,exports){\nmodule.exports=require(379)\n},{\"/Users/a/dev/faker.js/lib/locales/es/address/postcode.js\":379}],470:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Apt. ###\",\n  \"# étage\"\n];\n\n},{}],471:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Alsace\",\n  \"Aquitaine\",\n  \"Auvergne\",\n  \"Basse-Normandie\",\n  \"Bourgogne\",\n  \"Bretagne\",\n  \"Centre\",\n  \"Champagne-Ardenne\",\n  \"Corse\",\n  \"Franche-Comté\",\n  \"Haute-Normandie\",\n  \"Île-de-France\",\n  \"Languedoc-Roussillon\",\n  \"Limousin\",\n  \"Lorraine\",\n  \"Midi-Pyrénées\",\n  \"Nord-Pas-de-Calais\",\n  \"Pays de la Loire\",\n  \"Picardie\",\n  \"Poitou-Charentes\",\n  \"Provence-Alpes-Côte d'Azur\",\n  \"Rhône-Alpes\"\n];\n\n},{}],472:[function(require,module,exports){\nmodule.exports=require(193)\n},{\"/Users/a/dev/faker.js/lib/locales/en/address/street_address.js\":193}],473:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_prefix} #{street_suffix}\"\n];\n\n},{}],474:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Allée, Voie\",\n  \"Rue\",\n  \"Avenue\",\n  \"Boulevard\",\n  \"Quai\",\n  \"Passage\",\n  \"Impasse\",\n  \"Place\"\n];\n\n},{}],475:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"de l'Abbaye\",\n  \"Adolphe Mille\",\n  \"d'Alésia\",\n  \"d'Argenteuil\",\n  \"d'Assas\",\n  \"du Bac\",\n  \"de Paris\",\n  \"La Boétie\",\n  \"Bonaparte\",\n  \"de la Bûcherie\",\n  \"de Caumartin\",\n  \"Charlemagne\",\n  \"du Chat-qui-Pêche\",\n  \"de la Chaussée-d'Antin\",\n  \"du Dahomey\",\n  \"Dauphine\",\n  \"Delesseux\",\n  \"du Faubourg Saint-Honoré\",\n  \"du Faubourg-Saint-Denis\",\n  \"de la Ferronnerie\",\n  \"des Francs-Bourgeois\",\n  \"des Grands Augustins\",\n  \"de la Harpe\",\n  \"du Havre\",\n  \"de la Huchette\",\n  \"Joubert\",\n  \"Laffitte\",\n  \"Lepic\",\n  \"des Lombards\",\n  \"Marcadet\",\n  \"Molière\",\n  \"Monsieur-le-Prince\",\n  \"de Montmorency\",\n  \"Montorgueil\",\n  \"Mouffetard\",\n  \"de Nesle\",\n  \"Oberkampf\",\n  \"de l'Odéon\",\n  \"d'Orsel\",\n  \"de la Paix\",\n  \"des Panoramas\",\n  \"Pastourelle\",\n  \"Pierre Charron\",\n  \"de la Pompe\",\n  \"de Presbourg\",\n  \"de Provence\",\n  \"de Richelieu\",\n  \"de Rivoli\",\n  \"des Rosiers\",\n  \"Royale\",\n  \"d'Abbeville\",\n  \"Saint-Honoré\",\n  \"Saint-Bernard\",\n  \"Saint-Denis\",\n  \"Saint-Dominique\",\n  \"Saint-Jacques\",\n  \"Saint-Séverin\",\n  \"des Saussaies\",\n  \"de Seine\",\n  \"de Solférino\",\n  \"Du Sommerard\",\n  \"de Tilsitt\",\n  \"Vaneau\",\n  \"de Vaugirard\",\n  \"de la Victoire\",\n  \"Zadkine\"\n];\n\n},{}],476:[function(require,module,exports){\nmodule.exports=require(68)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/adjective.js\":68}],477:[function(require,module,exports){\nmodule.exports=require(212)\n},{\"/Users/a/dev/faker.js/lib/locales/en/company/bs_adjective.js\":212}],478:[function(require,module,exports){\nmodule.exports=require(213)\n},{\"/Users/a/dev/faker.js/lib/locales/en/company/bs_noun.js\":213}],479:[function(require,module,exports){\nmodule.exports=require(70)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/bs_verb.js\":70}],480:[function(require,module,exports){\nmodule.exports=require(71)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/descriptor.js\":71}],481:[function(require,module,exports){\narguments[4][216][0].apply(exports,arguments)\n},{\"./adjective\":476,\"./bs_adjective\":477,\"./bs_noun\":478,\"./bs_verb\":479,\"./descriptor\":480,\"./name\":482,\"./noun\":483,\"./suffix\":484,\"/Users/a/dev/faker.js/lib/locales/en/company/index.js\":216}],482:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name} et #{Name.last_name}\"\n];\n\n},{}],483:[function(require,module,exports){\nmodule.exports=require(74)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/noun.js\":74}],484:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"SARL\",\n  \"SA\",\n  \"EURL\",\n  \"SAS\",\n  \"SEM\",\n  \"SCOP\",\n  \"GIE\",\n  \"EI\"\n];\n\n},{}],485:[function(require,module,exports){\nvar fr = {};\nmodule['exports'] = fr;\nfr.title = \"French\";\nfr.address = require(\"./address\");\nfr.company = require(\"./company\");\nfr.internet = require(\"./internet\");\nfr.lorem = require(\"./lorem\");\nfr.name = require(\"./name\");\nfr.phone_number = require(\"./phone_number\");\n\n},{\"./address\":468,\"./company\":481,\"./internet\":488,\"./lorem\":489,\"./name\":493,\"./phone_number\":499}],486:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"fr\",\n  \"eu\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\"\n];\n\n},{}],487:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.fr\",\n  \"hotmail.fr\"\n];\n\n},{}],488:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":486,\"./free_email\":487,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],489:[function(require,module,exports){\nmodule.exports=require(83)\n},{\"./supplemental\":490,\"./words\":491,\"/Users/a/dev/faker.js/lib/locales/cz/lorem/index.js\":83}],490:[function(require,module,exports){\nmodule.exports=require(84)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/supplemental.js\":84}],491:[function(require,module,exports){\nmodule.exports=require(85)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/words.js\":85}],492:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Enzo\",\n  \"Lucas\",\n  \"Mathis\",\n  \"Nathan\",\n  \"Thomas\",\n  \"Hugo\",\n  \"Théo\",\n  \"Tom\",\n  \"Louis\",\n  \"Raphaël\",\n  \"Clément\",\n  \"Léo\",\n  \"Mathéo\",\n  \"Maxime\",\n  \"Alexandre\",\n  \"Antoine\",\n  \"Yanis\",\n  \"Paul\",\n  \"Baptiste\",\n  \"Alexis\",\n  \"Gabriel\",\n  \"Arthur\",\n  \"Jules\",\n  \"Ethan\",\n  \"Noah\",\n  \"Quentin\",\n  \"Axel\",\n  \"Evan\",\n  \"Mattéo\",\n  \"Romain\",\n  \"Valentin\",\n  \"Maxence\",\n  \"Noa\",\n  \"Adam\",\n  \"Nicolas\",\n  \"Julien\",\n  \"Mael\",\n  \"Pierre\",\n  \"Rayan\",\n  \"Victor\",\n  \"Mohamed\",\n  \"Adrien\",\n  \"Kylian\",\n  \"Sacha\",\n  \"Benjamin\",\n  \"Léa\",\n  \"Clara\",\n  \"Manon\",\n  \"Chloé\",\n  \"Camille\",\n  \"Ines\",\n  \"Sarah\",\n  \"Jade\",\n  \"Lola\",\n  \"Anaïs\",\n  \"Lucie\",\n  \"Océane\",\n  \"Lilou\",\n  \"Marie\",\n  \"Eva\",\n  \"Romane\",\n  \"Lisa\",\n  \"Zoe\",\n  \"Julie\",\n  \"Mathilde\",\n  \"Louise\",\n  \"Juliette\",\n  \"Clémence\",\n  \"Célia\",\n  \"Laura\",\n  \"Lena\",\n  \"Maëlys\",\n  \"Charlotte\",\n  \"Ambre\",\n  \"Maeva\",\n  \"Pauline\",\n  \"Lina\",\n  \"Jeanne\",\n  \"Lou\",\n  \"Noémie\",\n  \"Justine\",\n  \"Louna\",\n  \"Elisa\",\n  \"Alice\",\n  \"Emilie\",\n  \"Carla\",\n  \"Maëlle\",\n  \"Alicia\",\n  \"Mélissa\"\n];\n\n},{}],493:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.title = require(\"./title\");\nname.name = require(\"./name\");\n\n},{\"./first_name\":492,\"./last_name\":494,\"./name\":495,\"./prefix\":496,\"./title\":497}],494:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Martin\",\n  \"Bernard\",\n  \"Dubois\",\n  \"Thomas\",\n  \"Robert\",\n  \"Richard\",\n  \"Petit\",\n  \"Durand\",\n  \"Leroy\",\n  \"Moreau\",\n  \"Simon\",\n  \"Laurent\",\n  \"Lefebvre\",\n  \"Michel\",\n  \"Garcia\",\n  \"David\",\n  \"Bertrand\",\n  \"Roux\",\n  \"Vincent\",\n  \"Fournier\",\n  \"Morel\",\n  \"Girard\",\n  \"Andre\",\n  \"Lefevre\",\n  \"Mercier\",\n  \"Dupont\",\n  \"Lambert\",\n  \"Bonnet\",\n  \"Francois\",\n  \"Martinez\",\n  \"Legrand\",\n  \"Garnier\",\n  \"Faure\",\n  \"Rousseau\",\n  \"Blanc\",\n  \"Guerin\",\n  \"Muller\",\n  \"Henry\",\n  \"Roussel\",\n  \"Nicolas\",\n  \"Perrin\",\n  \"Morin\",\n  \"Mathieu\",\n  \"Clement\",\n  \"Gauthier\",\n  \"Dumont\",\n  \"Lopez\",\n  \"Fontaine\",\n  \"Chevalier\",\n  \"Robin\",\n  \"Masson\",\n  \"Sanchez\",\n  \"Gerard\",\n  \"Nguyen\",\n  \"Boyer\",\n  \"Denis\",\n  \"Lemaire\",\n  \"Duval\",\n  \"Joly\",\n  \"Gautier\",\n  \"Roger\",\n  \"Roche\",\n  \"Roy\",\n  \"Noel\",\n  \"Meyer\",\n  \"Lucas\",\n  \"Meunier\",\n  \"Jean\",\n  \"Perez\",\n  \"Marchand\",\n  \"Dufour\",\n  \"Blanchard\",\n  \"Marie\",\n  \"Barbier\",\n  \"Brun\",\n  \"Dumas\",\n  \"Brunet\",\n  \"Schmitt\",\n  \"Leroux\",\n  \"Colin\",\n  \"Fernandez\",\n  \"Pierre\",\n  \"Renard\",\n  \"Arnaud\",\n  \"Rolland\",\n  \"Caron\",\n  \"Aubert\",\n  \"Giraud\",\n  \"Leclerc\",\n  \"Vidal\",\n  \"Bourgeois\",\n  \"Renaud\",\n  \"Lemoine\",\n  \"Picard\",\n  \"Gaillard\",\n  \"Philippe\",\n  \"Leclercq\",\n  \"Lacroix\",\n  \"Fabre\",\n  \"Dupuis\",\n  \"Olivier\",\n  \"Rodriguez\",\n  \"Da silva\",\n  \"Hubert\",\n  \"Louis\",\n  \"Charles\",\n  \"Guillot\",\n  \"Riviere\",\n  \"Le gall\",\n  \"Guillaume\",\n  \"Adam\",\n  \"Rey\",\n  \"Moulin\",\n  \"Gonzalez\",\n  \"Berger\",\n  \"Lecomte\",\n  \"Menard\",\n  \"Fleury\",\n  \"Deschamps\",\n  \"Carpentier\",\n  \"Julien\",\n  \"Benoit\",\n  \"Paris\",\n  \"Maillard\",\n  \"Marchal\",\n  \"Aubry\",\n  \"Vasseur\",\n  \"Le roux\",\n  \"Renault\",\n  \"Jacquet\",\n  \"Collet\",\n  \"Prevost\",\n  \"Poirier\",\n  \"Charpentier\",\n  \"Royer\",\n  \"Huet\",\n  \"Baron\",\n  \"Dupuy\",\n  \"Pons\",\n  \"Paul\",\n  \"Laine\",\n  \"Carre\",\n  \"Breton\",\n  \"Remy\",\n  \"Schneider\",\n  \"Perrot\",\n  \"Guyot\",\n  \"Barre\",\n  \"Marty\",\n  \"Cousin\"\n];\n\n},{}],495:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{last_name} #{first_name}\"\n];\n\n},{}],496:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"M\",\n  \"Mme\",\n  \"Mlle\",\n  \"Dr\",\n  \"Prof\"\n];\n\n},{}],497:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"job\": [\n    \"Superviseur\",\n    \"Executif\",\n    \"Manager\",\n    \"Ingenieur\",\n    \"Specialiste\",\n    \"Directeur\",\n    \"Coordinateur\",\n    \"Administrateur\",\n    \"Architecte\",\n    \"Analyste\",\n    \"Designer\",\n    \"Technicien\",\n    \"Developpeur\",\n    \"Producteur\",\n    \"Consultant\",\n    \"Assistant\",\n    \"Agent\",\n    \"Stagiaire\"\n  ]\n};\n\n},{}],498:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"01########\",\n  \"02########\",\n  \"03########\",\n  \"04########\",\n  \"05########\",\n  \"06########\",\n  \"07########\",\n  \"+33 1########\",\n  \"+33 2########\",\n  \"+33 3########\",\n  \"+33 4########\",\n  \"+33 5########\",\n  \"+33 6########\",\n  \"+33 7########\"\n];\n\n},{}],499:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":498,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],500:[function(require,module,exports){\nmodule.exports=require(292)\n},{\"/Users/a/dev/faker.js/lib/locales/en_CA/address/default_country.js\":292}],501:[function(require,module,exports){\narguments[4][326][0].apply(exports,arguments)\n},{\"./default_country\":500,\"./postcode\":502,\"./state\":503,\"./state_abbr\":504,\"/Users/a/dev/faker.js/lib/locales/en_IND/address/index.js\":326}],502:[function(require,module,exports){\nmodule.exports=require(294)\n},{\"/Users/a/dev/faker.js/lib/locales/en_CA/address/postcode.js\":294}],503:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Alberta\",\n  \"Colombie-Britannique\",\n  \"Manitoba\",\n  \"Nouveau-Brunswick\",\n  \"Terre-Neuve-et-Labrador\",\n  \"Nouvelle-Écosse\",\n  \"Territoires du Nord-Ouest\",\n  \"Nunavut\",\n  \"Ontario\",\n  \"Île-du-Prince-Édouard\",\n  \"Québec\",\n  \"Saskatchewan\",\n  \"Yukon\"\n];\n\n},{}],504:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AB\",\n  \"BC\",\n  \"MB\",\n  \"NB\",\n  \"NL\",\n  \"NS\",\n  \"NU\",\n  \"NT\",\n  \"ON\",\n  \"PE\",\n  \"QC\",\n  \"SK\",\n  \"YK\"\n];\n\n},{}],505:[function(require,module,exports){\nvar fr_CA = {};\nmodule['exports'] = fr_CA;\nfr_CA.title = \"Canada (French)\";\nfr_CA.address = require(\"./address\");\nfr_CA.internet = require(\"./internet\");\nfr_CA.phone_number = require(\"./phone_number\");\n\n},{\"./address\":501,\"./internet\":508,\"./phone_number\":510}],506:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"qc.ca\",\n  \"ca\",\n  \"com\",\n  \"biz\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\"\n];\n\n},{}],507:[function(require,module,exports){\nmodule.exports=require(299)\n},{\"/Users/a/dev/faker.js/lib/locales/en_CA/internet/free_email.js\":299}],508:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":506,\"./free_email\":507,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],509:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"### ###-####\",\n  \"1 ### ###-####\",\n  \"### ###-####, poste ###\"\n];\n\n},{}],510:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":509,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],511:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###\",\n  \"##\",\n  \"#\"\n];\n\n},{}],512:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_prefix} #{Name.first_name}#{city_suffix}\",\n  \"#{city_prefix} #{Name.first_name}\",\n  \"#{Name.first_name}#{city_suffix}\",\n  \"#{Name.first_name}#{city_suffix}\",\n  \"#{Name.last_name}#{city_suffix}\",\n  \"#{Name.last_name}#{city_suffix}\"\n];\n\n},{}],513:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"ზესტაფონი\",\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  \"სარფი\",\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  \"წყნეთი\",\n  \"ჭიათურა\",\n  \"ხარაგაული\",\n  \"ხაშური\",\n  \"ხელვაჩაური\",\n  \"ხობი\",\n  \"ხონი\",\n  \"ხულო\"\n];\n\n},{}],514:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ახალი\",\n  \"ძველი\",\n  \"ზემო\",\n  \"ქვემო\"\n];\n\n},{}],515:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"სოფელი\",\n  \"ძირი\",\n  \"სკარი\",\n  \"დაბა\"\n];\n\n},{}],516:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"აღდგომის კუნძული\",\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  \"ბურკინა ფასო\",\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  \"დომინიკელთა რესპუბლიკა\",\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  \"იემენი\",\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  \"კორეის რესპუბლიკა\",\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  \"მაროკო\",\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  \"ოკეანეთის\",\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  \"სამხრეთ ამერიკაშია\",\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  \"სინგაპური\",\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  \"უკრაინა\",\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  \"ჩრდილოეთ მარიანას კუნძულები\",\n  \"ჩრდილოეთი აფრიკა\",\n  \"ჩრდილოეთი კორეა\",\n  \"ჩრდილოეთი მარიანას კუნძულები\",\n  \"ცენტრალური აფრიკა\",\n  \"ცენტრალური აფრიკის რესპუბლიკა\",\n  \"წევრები\",\n  \"წმინდა ელენე\",\n  \"წმინდა ელენეს კუნძული\",\n  \"ხორვატია\",\n  \"ჯერსი\",\n  \"ჯიბუტი\",\n  \"ჰავაი\",\n  \"ჰაიტი\",\n  \"ჰერდი და მაკდონალდის კუნძულები\",\n  \"ჰონდურასი\",\n  \"ჰონკონგი\"\n];\n\n},{}],517:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"საქართველო\"\n];\n\n},{}],518:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.city = require(\"./city\");\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.city_name = require(\"./city_name\");\naddress.street_title = require(\"./street_title\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":511,\"./city\":512,\"./city_name\":513,\"./city_prefix\":514,\"./city_suffix\":515,\"./country\":516,\"./default_country\":517,\"./postcode\":519,\"./secondary_address\":520,\"./street_address\":521,\"./street_name\":522,\"./street_suffix\":523,\"./street_title\":524}],519:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"01##\"\n];\n\n},{}],520:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"კორპ. ##\",\n  \"შენობა ###\"\n];\n\n},{}],521:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],522:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_title} #{street_suffix}\"\n];\n\n},{}],523:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"გამზ.\",\n  \"გამზირი\",\n  \"ქ.\",\n  \"ქუჩა\",\n  \"ჩიხი\",\n  \"ხეივანი\"\n];\n\n},{}],524:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"აფხაზი\",\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  \"ბურკიაშვილის\",\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  \"გურამიშვილის\",\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  \"ვაჩნაძის\",\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  \"თოფურიძის\",\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  \"კაკაბეთის\",\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  \"კოჯრის\",\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  \"მანაგაძის\",\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  \"მორეტის\",\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  \"პეკინის\",\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  \"საბაშვილის\",\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  \"უბილავას\",\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  \"ყიფიანის\",\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  \"ჩიხლაძის\",\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  \"ხვამლის\",\n  \"ხვინგიას\",\n  \"ხვიჩიას\",\n  \"ხიმშიაშვილის\",\n  \"ხმელნიცკის\",\n  \"ხორნაბუჯის\",\n  \"ხრამჰესის\",\n  \"ხუციშვილის\",\n  \"ჯავახიშვილის\",\n  \"ჯაფარიძის\",\n  \"ჯიბლაძის\",\n  \"ჯორჯიაშვილის\"\n];\n\n},{}],525:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"(+995 32) 2-##-##-##\",\n  \"032-2-##-##-##\",\n  \"032-2-######\",\n  \"032-2-###-###\",\n  \"032 2 ## ## ##\",\n  \"032 2 ######\",\n  \"2 ## ## ##\",\n  \"2######\",\n  \"2 ### ###\"\n];\n\n},{}],526:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":525,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],527:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./name\":528,\"./prefix\":529,\"./suffix\":530,\"/Users/a/dev/faker.js/lib/locales/az/company/index.js\":33}],528:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{Name.first_name}\",\n  \"#{prefix} #{Name.last_name}\",\n  \"#{prefix} #{Name.last_name} #{suffix}\",\n  \"#{prefix} #{Name.first_name} #{suffix}\",\n  \"#{prefix} #{Name.last_name}-#{Name.last_name}\"\n];\n\n},{}],529:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"შპს\",\n  \"სს\",\n  \"ააიპ\",\n  \"სსიპ\"\n];\n\n},{}],530:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ჯგუფი\",\n  \"და კომპანია\",\n  \"სტუდია\",\n  \"გრუპი\"\n];\n\n},{}],531:[function(require,module,exports){\nvar ge = {};\nmodule['exports'] = ge;\nge.title = \"Georgian\";\nge.separator = \" და \";\nge.name = require(\"./name\");\nge.address = require(\"./address\");\nge.internet = require(\"./internet\");\nge.company = require(\"./company\");\nge.phone_number = require(\"./phone_number\");\nge.cell_phone = require(\"./cell_phone\");\n\n},{\"./address\":518,\"./cell_phone\":526,\"./company\":527,\"./internet\":534,\"./name\":536,\"./phone_number\":542}],532:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ge\",\n  \"com\",\n  \"net\",\n  \"org\",\n  \"com.ge\",\n  \"org.ge\"\n];\n\n},{}],533:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.com\",\n  \"posta.ge\"\n];\n\n},{}],534:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":532,\"./free_email\":533,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],535:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"ბაჩა\",\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  \"გენადი\",\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  \"გუგული\",\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  \"ელიკო\",\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  \"ზურა\",\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  \"თეიმურაზ\",\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  \"ირაკლი\",\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  \"ლაშა\",\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  \"მამია\",\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  \"მერი\",\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  \"ნაზიკო\",\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  \"ნოდარ\",\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  \"პირიმზე\",\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  \"სულა\",\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  \"ქეთინო\",\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  \"შოთა\",\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  \"ციცინო\",\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  \"ხოხია\",\n  \"ხოხიტა\",\n  \"ხუტა\",\n  \"ხუცია\",\n  \"ჯაბა\",\n  \"ჯავახი\",\n  \"ჯარჯი\",\n  \"ჯემალ\",\n  \"ჯონდო\",\n  \"ჯოტო\",\n  \"ჯუბი\",\n  \"ჯულიეტა\",\n  \"ჯუმბერ\",\n  \"ჰამლეტ\"\n];\n\n},{}],536:[function(require,module,exports){\narguments[4][493][0].apply(exports,arguments)\n},{\"./first_name\":535,\"./last_name\":537,\"./name\":538,\"./prefix\":539,\"./title\":540,\"/Users/a/dev/faker.js/lib/locales/fr/name/index.js\":493}],537:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"გამრეკელი\",\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  \"თაბაგარი\",\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  \"ლურსმანაშვილი\",\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  \"სეთური\",\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  \"ცხომარია\",\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  \"ჯავახიშვილი\",\n  \"ჯანელიძე\",\n  \"ჯაფარიძე\",\n  \"ჯაყელი\",\n  \"ჯაჯანიძე\",\n  \"ჯვარელია\",\n  \"ჯინიუზაშვილი\",\n  \"ჯუღაშვილი\"\n];\n\n},{}],538:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\"\n];\n\n},{}],539:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ბ-ნი\",\n  \"ბატონი\",\n  \"ქ-ნი\",\n  \"ქალბატონი\"\n];\n\n},{}],540:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"descriptor\": [\n    \"გენერალური\",\n    \"მთავარი\",\n    \"სტაჟიორ\",\n    \"უმცროსი\",\n    \"ყოფილი\",\n    \"წამყვანი\"\n  ],\n  \"level\": [\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  \"job\": [\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    \"პოლიციელი\",\n    \"პროგრამისტი\",\n    \"პროდიუსერი\",\n    \"პრორექტორი\",\n    \"ჟურნალისტი\",\n    \"რექტორი\",\n    \"სპეციალისტი\",\n    \"სტრატეგისტი\",\n    \"ტექნიკოსი\",\n    \"ფოტოგრაფი\",\n    \"წარმომადგენელი\"\n  ]\n};\n\n},{}],541:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"5##-###-###\",\n  \"5########\",\n  \"5## ## ## ##\",\n  \"5## ######\",\n  \"5## ### ###\",\n  \"995 5##-###-###\",\n  \"995 5########\",\n  \"995 5## ## ## ##\",\n  \"995 5## ######\",\n  \"995 5## ### ###\",\n  \"+995 5##-###-###\",\n  \"+995 5########\",\n  \"+995 5## ## ## ##\",\n  \"+995 5## ######\",\n  \"+995 5## ### ###\",\n  \"(+995) 5##-###-###\",\n  \"(+995) 5########\",\n  \"(+995) 5## ## ## ##\",\n  \"(+995) 5## ######\",\n  \"(+995) 5## ### ###\"\n];\n\n},{}],542:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":541,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],543:[function(require,module,exports){\nmodule[\"exports\"] = [  \n  \"##\",\n  \"#\"\n];\n\n},{}],544:[function(require,module,exports){\nmodule.exports=require(55)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/city.js\":55}],545:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Airmadidi\",\n  \"Ampana\",\n  \"Amurang\",\n  \"Andolo\",\n  \"Banggai\",\n  \"Bantaeng\",\n  \"Barru\",\n  \"Bau-Bau\",\n  \"Benteng\",\n  \"Bitung\",\n  \"Bolaang Uki\",\n  \"Boroko\",\n  \"Bulukumba\",\n  \"Bungku\",\n  \"Buol\",\n  \"Buranga\",\n  \"Donggala\",\n  \"Enrekang\",\n  \"Gorontalo\",\n  \"Jeneponto\",\n  \"Kawangkoan\",\n  \"Kendari\",\n  \"Kolaka\",\n  \"Kotamobagu\",\n  \"Kota Raha\",\n  \"Kwandang\",\n  \"Lasusua\",\n  \"Luwuk\",\n  \"Majene\",\n  \"Makale\",\n  \"Makassar\",\n  \"Malili\",\n  \"Mamasa\",\n  \"Mamuju\",\n  \"Manado\",\n  \"Marisa\",\n  \"Maros\",\n  \"Masamba\",\n  \"Melonguane\",\n  \"Ondong Siau\",\n  \"Palopo\",\n  \"Palu\",\n  \"Pangkajene\",\n  \"Pare-Pare\",\n  \"Parigi\",\n  \"Pasangkayu\",\n  \"Pinrang\",\n  \"Polewali\",\n  \"Poso\",\n  \"Rantepao\",\n  \"Ratahan\",\n  \"Rumbia\",\n  \"Sengkang\",\n  \"Sidenreng\",\n  \"Sigi Biromaru\",\n  \"Sinjai\",\n  \"Sunggu Minasa\",\n  \"Suwawa\",\n  \"Tahuna\",\n  \"Takalar\",\n  \"Tilamuta\",\n  \"Toli Toli\",\n  \"Tomohon\",\n  \"Tondano\",\n  \"Tutuyan\",\n  \"Unaaha\",\n  \"Wangi Wangi\",\n  \"Wanggudu\",\n  \"Watampone\",\n  \"Watan Soppeng\",\n  \"Ambarawa\",\n  \"Anyer\",\n  \"Bandung\",\n  \"Bangil\",\n  \"Banjar (Jawa Barat)\",\n  \"Banjarnegara\",\n  \"Bangkalan\",\n  \"Bantul\",\n  \"Banyumas\",\n  \"Banyuwangi\",\n  \"Batang\",\n  \"Batu\",\n  \"Bekasi\",\n  \"Blitar\",\n  \"Blora\",\n  \"Bogor\",\n  \"Bojonegoro\",\n  \"Bondowoso\",\n  \"Boyolali\",\n  \"Bumiayu\",\n  \"Brebes\",\n  \"Caruban\",\n  \"Cianjur\",\n  \"Ciamis\",\n  \"Cibinong\",\n  \"Cikampek\",\n  \"Cikarang\",\n  \"Cilacap\",\n  \"Cilegon\",\n  \"Cirebon\",\n  \"Demak\",\n  \"Depok\",\n  \"Garut\",\n  \"Gresik\",\n  \"Indramayu\",\n  \"Jakarta\",\n  \"Jember\",\n  \"Jepara\",\n  \"Jombang\",\n  \"Kajen\",\n  \"Karanganyar\",\n  \"Kebumen\",\n  \"Kediri\",\n  \"Kendal\",\n  \"Kepanjen\",\n  \"Klaten\",\n  \"Pelabuhan Ratu\",\n  \"Kraksaan\",\n  \"Kudus\",\n  \"Kuningan\",\n  \"Lamongan\",\n  \"Lumajang\",\n  \"Madiun\",\n  \"Magelang\",\n  \"Magetan\",\n  \"Majalengka\",\n  \"Malang\",\n  \"Mojokerto\",\n  \"Mojosari\",\n  \"Mungkid\",\n  \"Ngamprah\",\n  \"Nganjuk\",\n  \"Ngawi\",\n  \"Pacitan\",\n  \"Pamekasan\",\n  \"Pandeglang\",\n  \"Pare\",\n  \"Pati\",\n  \"Pasuruan\",\n  \"Pekalongan\",\n  \"Pemalang\",\n  \"Ponorogo\",\n  \"Probolinggo\",\n  \"Purbalingga\",\n  \"Purwakarta\",\n  \"Purwodadi\",\n  \"Purwokerto\",\n  \"Purworejo\",\n  \"Rangkasbitung\",\n  \"Rembang\",\n  \"Salatiga\",\n  \"Sampang\",\n  \"Semarang\",\n  \"Serang\",\n  \"Sidayu\",\n  \"Sidoarjo\",\n  \"Singaparna\",\n  \"Situbondo\",\n  \"Slawi\",\n  \"Sleman\",\n  \"Soreang\",\n  \"Sragen\",\n  \"Subang\",\n  \"Sukabumi\",\n  \"Sukoharjo\",\n  \"Sumber\",\n  \"Sumedang\",\n  \"Sumenep\",\n  \"Surabaya\",\n  \"Surakarta\",\n  \"Tasikmalaya\",\n  \"Tangerang\",\n  \"Tangerang Selatan\",\n  \"Tegal\",\n  \"Temanggung\",\n  \"Tigaraksa\",\n  \"Trenggalek\",\n  \"Tuban\",\n  \"Tulungagung\",\n  \"Ungaran\",\n  \"Wates\",\n  \"Wlingi\",\n  \"Wonogiri\",\n  \"Wonosari\",\n  \"Wonosobo\",\n  \"Yogyakarta\",\n  \"Atambua\",\n  \"Baa\",\n  \"Badung\",\n  \"Bajawa\",\n  \"Bangli\",\n  \"Bima\",\n  \"Denpasar\",\n  \"Dompu\",\n  \"Ende\",\n  \"Gianyar\",\n  \"Kalabahi\",\n  \"Karangasem\",\n  \"Kefamenanu\",\n  \"Klungkung\",\n  \"Kupang\",\n  \"Labuhan Bajo\",\n  \"Larantuka\",\n  \"Lewoleba\",\n  \"Maumere\",\n  \"Mataram\",\n  \"Mbay\",\n  \"Negara\",\n  \"Praya\",\n  \"Raba\",\n  \"Ruteng\",\n  \"Selong\",\n  \"Singaraja\",\n  \"Soe\",\n  \"Sumbawa Besar\",\n  \"Tabanan\",\n  \"Taliwang\",\n  \"Tambolaka\",\n  \"Tanjung\",\n  \"Waibakul\",\n  \"Waikabubak\",\n  \"Waingapu\",\n  \"Denpasar\",\n  \"Negara,Bali\",\n  \"Singaraja\",\n  \"Tabanan\",\n  \"Bangli\"\n];\n},{}],546:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Indonesia\"\n];\n\n},{}],547:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.building_number = require(\"./building_number\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.street_prefix = require(\"./street_prefix\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":543,\"./city\":544,\"./city_name\":545,\"./default_country\":546,\"./postcode\":548,\"./state\":549,\"./street_address\":550,\"./street_name\":551,\"./street_prefix\":552}],548:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\"\n];\n},{}],549:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aceh\",\n  \"Sumatera Utara\",\n  \"Sumatera Barat\",\n  \"Jambi\",\n  \"Bangka Belitung\",\n  \"Riau\",\n  \"Kepulauan Riau\",\n  \"Bengkulu\",\n  \"Sumatera Selatan\",\n  \"Lampung\",\n  \"Banten\",\n  \"DKI Jakarta\",\n  \"Jawa Barat\",\n  \"Jawa Tengah\",\n  \"Jawa Timur\",\n  \"Nusa Tenggara Timur\",\n  \"DI Yogyakarta\",\n  \"Bali\",\n  \"Nusa Tenggara Barat\",\n  \"Kalimantan Barat\",\n  \"Kalimantan Tengah\",\n  \"Kalimantan Selatan\",\n  \"Kalimantan Timur\",\n  \"Kalimantan Utara\",\n  \"Sulawesi Selatan\",\n  \"Sulawesi Utara\",\n  \"Gorontalo\",\n  \"Sulawesi Tengah\",\n  \"Sulawesi Barat\",\n  \"Sulawesi Tenggara\",\n  \"Maluku\",\n  \"Maluku Utara\",\n  \"Papua Barat\",\n  \"Papua\"\n];\n},{}],550:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_name} no #{building_number}\"\n];\n},{}],551:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_prefix} #{Name.first_name}\",\n  \"#{street_prefix} #{Name.last_name}\"\n];\n},{}],552:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ds.\",\n  \"Dk.\",\n  \"Gg.\",\n  \"Jln.\",\n  \"Jr.\",\n  \"Kpg.\",\n  \"Ki.\",\n  \"Psr.\"\n];\n},{}],553:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./name\":554,\"./prefix\":555,\"./suffix\":556,\"/Users/a/dev/faker.js/lib/locales/az/company/index.js\":33}],554:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{Name.last_name}\",\n  \"#{Name.last_name} #{suffix}\",\n  \"#{prefix} #{Name.last_name} #{suffix}\"\n];\n\n},{}],555:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"PT\",\n  \"CV\",\n  \"UD\",\n  \"PD\",\n  \"Perum\"\n];\n},{}],556:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"(Persero) Tbk\",\n  \"Tbk\"\n];\n},{}],557:[function(require,module,exports){\narguments[4][37][0].apply(exports,arguments)\n},{\"./month\":558,\"./weekday\":559,\"/Users/a/dev/faker.js/lib/locales/az/date/index.js\":37}],558:[function(require,module,exports){\nmodule[\"exports\"] = {\n  wide: [\n    \"Januari\",\n    \"Februari\",\n    \"Maret\",\n    \"April\",\n    \"Mei\",\n    \"Juni\",\n    \"Juli\",\n    \"Agustus\",\n    \"September\",\n    \"Oktober\",\n    \"November\",\n    \"Desember\"\n  ],\n  wide_context: [\n    \"Januari\",\n    \"Februari\",\n    \"Maret\",\n    \"April\",\n    \"Mei\",\n    \"Juni\",\n    \"Juli\",\n    \"Agustus\",\n    \"September\",\n    \"Oktober\",\n    \"November\",\n    \"Desember\"\n  ],\n  abbr: [\n    \"Jan\",\n    \"Feb\",\n    \"Mar\",\n    \"Apr\",\n    \"Mei\",\n    \"Jun\",\n    \"Jul\",\n    \"Ags\",\n    \"Sep\",\n    \"Okt\",\n    \"Nov\",\n    \"Des\"\n  ],\n  abbr_context: [\n    \"Jan\",\n    \"Feb\",\n    \"Mar\",\n    \"Apr\",\n    \"Mei\",\n    \"Jun\",\n    \"Jul\",\n    \"Ags\",\n    \"Sep\",\n    \"Okt\",\n    \"Nov\",\n    \"Des\"\n  ]\n};\n\n},{}],559:[function(require,module,exports){\nmodule[\"exports\"] = {\n  wide: [\n    \"Minggu\",\n    \"Senin\",\n    \"Selasa\",\n    \"Rabu\",\n    \"Kamis\",\n    \"Jumat\",\n    \"Sabtu\"\n  ],\n  wide_context: [\n    \"Minggu\",\n    \"Senin\",\n    \"Selasa\",\n    \"Rabu\",\n    \"Kamis\",\n    \"Jumat\",\n    \"Sabtu\"\n  ],\n  abbr: [\n    \"Min\",\n    \"Sen\",\n    \"Sel\",\n    \"Rab\",\n    \"Kam\",\n    \"Jum\",\n    \"Sab\"\n  ],\n  abbr_context: [\n    \"Min\",\n    \"Sen\",\n    \"Sel\",\n    \"Rab\",\n    \"Kam\",\n    \"Jum\",\n    \"Sab\"\n  ]\n};\n\n},{}],560:[function(require,module,exports){\nvar id = {};\nmodule['exports'] = id;\nid.title = \"Indonesia\";\nid.address = require(\"./address\");\nid.company = require(\"./company\");\nid.internet = require(\"./internet\");\nid.date = require(\"./date\");\nid.name = require(\"./name\");\nid.phone_number = require(\"./phone_number\");\n\n},{\"./address\":547,\"./company\":553,\"./date\":557,\"./internet\":563,\"./name\":566,\"./phone_number\":573}],561:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"net\",\n  \"org\",\n  \"asia\",\n  \"tv\",\n  \"biz\",\n  \"info\",\n  \"in\",\n  \"name\",\n  \"co\",\n  \"ac.id\",\n  \"sch.id\",\n  \"go.id\",\n  \"mil.id\",\n  \"co.id\",\n  \"or.id\",\n  \"web.id\",\n  \"my.id\",\n  \"biz.id\",\n  \"desa.id\"\n];\n},{}],562:[function(require,module,exports){\nmodule[\"exports\"] = [\n  'gmail.com',\n  'yahoo.com',\n  'gmail.co.id',\n  'yahoo.co.id'\n];\n},{}],563:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":561,\"./free_email\":562,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],564:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ade\",\n  \"Agnes\",\n  \"Ajeng\",\n  \"Amalia\",\n  \"Anita\",\n  \"Ayu\",\n  \"Aisyah\",\n  \"Ana\",\n  \"Ami\",\n  \"Ani\",\n  \"Azalea\",\n  \"Aurora\",\n  \"Alika\",\n  \"Anastasia\",\n  \"Amelia\",\n  \"Almira\",\n  \"Bella\",\n  \"Betania\",\n  \"Belinda\",\n  \"Citra\",\n  \"Cindy\",\n  \"Chelsea\",\n  \"Clara\",\n  \"Cornelia\",\n  \"Cinta\",\n  \"Cinthia\",\n  \"Ciaobella\",\n  \"Cici\",\n  \"Carla\",\n  \"Calista\",\n  \"Devi\",\n  \"Dewi\",\"Dian\",\n  \"Diah\",\n  \"Diana\",\n  \"Dina\",\n  \"Dinda\",\n  \"Dalima\",\n  \"Eka\",\n  \"Eva\",\n  \"Endah\",\n  \"Elisa\",\n  \"Eli\",\n  \"Ella\",\n  \"Ellis\",\n  \"Elma\",\n  \"Elvina\",\n  \"Fitria\",\n  \"Fitriani\",\n  \"Febi\",\n  \"Faizah\",\n  \"Farah\",\n  \"Farhunnisa\",\n  \"Fathonah\",\n  \"Gabriella\",\n  \"Gasti\",\n  \"Gawati\",\n  \"Genta\",\n  \"Ghaliyati\",\n  \"Gina\",\n  \"Gilda\",\n  \"Halima\",\n  \"Hesti\",\n  \"Hilda\",\n  \"Hafshah\",\n  \"Hamima\",\n  \"Hana\",\n  \"Hani\",\n  \"Hasna\",\n  \"Humaira\",\n  \"Ika\",\n  \"Indah\",\n  \"Intan\",\n  \"Irma\",\n  \"Icha\",\n  \"Ida\",\n  \"Ifa\",\n  \"Ilsa\",\n  \"Ina\",\n  \"Ira\",\n  \"Iriana\",\n  \"Jamalia\",\n  \"Janet\",\n  \"Jane\",\n  \"Julia\",\n  \"Juli\",\n  \"Jessica\",\n  \"Jasmin\",\n  \"Jelita\",\n  \"Kamaria\",\n  \"Kamila\",\n  \"Kani\",\n  \"Karen\",\n  \"Karimah\",\n  \"Kartika\",\n  \"Kasiyah\",\n  \"Keisha\",\n  \"Kezia\",\n  \"Kiandra\",\n  \"Kayla\",\n  \"Kania\",\n  \"Lala\",\n  \"Lalita\",\n  \"Latika\",\n  \"Laila\",\n  \"Laras\",\n  \"Lidya\",\n  \"Lili\",\n  \"Lintang\",\n  \"Maria\",\n  \"Mala\",\n  \"Maya\",\n  \"Maida\",\n  \"Maimunah\",\n  \"Melinda\",\n  \"Mila\",\n  \"Mutia\",\n  \"Michelle\",\n  \"Malika\",\n  \"Nadia\",\n  \"Nadine\",\n  \"Nabila\",\n  \"Natalia\",\n  \"Novi\",\n  \"Nova\",\n  \"Nurul\",\n  \"Nilam\",\n  \"Najwa\",\n  \"Olivia\",\n  \"Ophelia\",\n  \"Oni\",\n  \"Oliva\",\n  \"Padma\",\n  \"Putri\",\n  \"Paramita\",\n  \"Paris\",\n  \"Patricia\",\n  \"Paulin\",\n  \"Puput\",\n  \"Puji\",\n  \"Pia\",\n  \"Puspa\",\n  \"Puti\",\n  \"Putri\",\n  \"Padmi\",\n  \"Qori\",\n  \"Queen\",\n  \"Ratih\",\n  \"Ratna\",\n  \"Restu\",\n  \"Rini\",\n  \"Rika\",\n  \"Rina\",\n  \"Rahayu\",\n  \"Rahmi\",\n  \"Rachel\",\n  \"Rahmi\",\n  \"Raisa\",\n  \"Raina\",\n  \"Sarah\",\n  \"Sari\",\n  \"Siti\",\n  \"Siska\",\n  \"Suci\",\n  \"Syahrini\",\n  \"Septi\",\n  \"Sadina\",\n  \"Safina\",\n  \"Sakura\",\n  \"Salimah\",\n  \"Salwa\",\n  \"Salsabila\",\n  \"Samiah\",\n  \"Shania\",\n  \"Sabrina\",\n  \"Silvia\",\n  \"Shakila\",\n  \"Talia\",\n  \"Tami\",\n  \"Tira\",\n  \"Tiara\",\n  \"Titin\",\n  \"Tania\",\n  \"Tina\",\n  \"Tantri\",\n  \"Tari\",\n  \"Titi\",\n  \"Uchita\",\n  \"Unjani\",\n  \"Ulya\",\n  \"Uli\",\n  \"Ulva\",\n  \"Umi\",\n  \"Usyi\",\n  \"Vanya\",\n  \"Vanesa\",\n  \"Vivi\",\n  \"Vera\",\n  \"Vicky\",\n  \"Victoria\",\n  \"Violet\",\n  \"Winda\",\n  \"Widya\",\n  \"Wulan\",\n  \"Wirda\",\n  \"Wani\",\n  \"Yani\",\n  \"Yessi\",\n  \"Yulia\",\n  \"Yuliana\",\n  \"Yuni\",\n  \"Yunita\",\n  \"Yance\",\n  \"Zahra\",\n  \"Zalindra\",\n  \"Zaenab\",\n  \"Zulfa\",\n  \"Zizi\",\n  \"Zulaikha\",\n  \"Zamira\",\n  \"Zelda\",\n  \"Zelaya\"\n];\n},{}],565:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Agustina\",\n  \"Andriani\",\n  \"Anggraini\",\n  \"Aryani\",\n  \"Astuti\",\n  \"Fujiati\",\n  \"Farida\",\n  \"Handayani\",\n  \"Hassanah\",\n  \"Hartati\",\n  \"Hasanah\",\n  \"Haryanti\",\n  \"Hariyah\",\n  \"Hastuti\",\n  \"Halimah\",\n  \"Kusmawati\",\n  \"Kuswandari\",\n  \"Laksmiwati\",\n  \"Laksita\",\n  \"Lestari\",\n  \"Lailasari\",\n  \"Mandasari\",\n  \"Mardhiyah\",\n  \"Mayasari\",\n  \"Melani\",\n  \"Mulyani\",\n  \"Maryati\",\n  \"Nurdiyanti\",\n  \"Novitasari\",\n  \"Nuraini\",\n  \"Nasyidah\",\n  \"Nasyiah\",\n  \"Namaga\",\n  \"Palastri\",\n  \"Pudjiastuti\",\n  \"Puspasari\",\n  \"Puspita\",\n  \"Purwanti\",\n  \"Pratiwi\",\n  \"Purnawati\",\n  \"Pertiwi\",\n  \"Permata\",\n  \"Prastuti\",\n  \"Padmasari\",\n  \"Rahmawati\",\n  \"Rahayu\",\n  \"Riyanti\",\n  \"Rahimah\",\n  \"Suartini\",\n  \"Sudiati\",\n  \"Suryatmi\",\n  \"Susanti\",\n  \"Safitri\",\n  \"Oktaviani\",\n  \"Utami\",\n  \"Usamah\",\n  \"Usada\",\n  \"Uyainah\",\n  \"Yuniar\",\n  \"Yuliarti\",\n  \"Yulianti\",\n  \"Yolanda\",\n  \"Wahyuni\",\n  \"Wijayanti\",\n  \"Widiastuti\",\n  \"Winarsih\",\n  \"Wulandari\",\n  \"Wastuti\",\n  \"Zulaika\"\n];\n},{}],566:[function(require,module,exports){\narguments[4][46][0].apply(exports,arguments)\n},{\"./female_first_name\":564,\"./female_last_name\":565,\"./male_first_name\":567,\"./male_last_name\":568,\"./name\":569,\"./prefix\":570,\"./suffix\":571,\"/Users/a/dev/faker.js/lib/locales/az/name/index.js\":46}],567:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abyasa\",\n  \"Ade\",\n  \"Adhiarja\",\n  \"Adiarja\",\n  \"Adika\",\n  \"Adikara\",\n  \"Adinata\",\n  \"Aditya\",\n  \"Agus\",\n  \"Ajiman\",\n  \"Ajimat\",\n  \"Ajimin\",\n  \"Ajiono\",\n  \"Akarsana\",\n  \"Alambana\",\n  \"Among\",\n  \"Anggabaya\",\n  \"Anom\",\n  \"Argono\",\n  \"Aris\",\n  \"Arta\",\n  \"Artanto\",\n  \"Artawan\",\n  \"Arsipatra\",\n  \"Asirwada\",\n  \"Asirwanda\",\n  \"Aslijan\",\n  \"Asmadi\",\n  \"Asman\",\n  \"Asmianto\",\n  \"Asmuni\",\n  \"Aswani\",\n  \"Atma\",\n  \"Atmaja\",\n  \"Bagas\",\n  \"Bagiya\",\n  \"Bagus\",\n  \"Bagya\",\n  \"Bahuraksa\",\n  \"Bahuwarna\",\n  \"Bahuwirya\",\n  \"Bajragin\",\n  \"Bakda\",\n  \"Bakiadi\",\n  \"Bakianto\",\n  \"Bakidin\",\n  \"Bakijan\",\n  \"Bakiman\",\n  \"Bakiono\",\n  \"Bakti\",\n  \"Baktiadi\",\n  \"Baktianto\",\n  \"Baktiono\",\n  \"Bala\",\n  \"Balamantri\",\n  \"Balangga\",\n  \"Balapati\",\n  \"Balidin\",\n  \"Balijan\",\n  \"Bambang\",\n  \"Banara\",\n  \"Banawa\",\n  \"Banawi\",\n  \"Bancar\",\n  \"Budi\",\n  \"Cagak\",\n  \"Cager\",\n  \"Cahyadi\",\n  \"Cahyanto\",\n  \"Cahya\",\n  \"Cahyo\",\n  \"Cahyono\",\n  \"Caket\",\n  \"Cakrabirawa\",\n  \"Cakrabuana\",\n  \"Cakrajiya\",\n  \"Cakrawala\",\n  \"Cakrawangsa\",\n  \"Candra\",\n  \"Chandra\",\n  \"Candrakanta\",\n  \"Capa\",\n  \"Caraka\",\n  \"Carub\",\n  \"Catur\",\n  \"Caturangga\",\n  \"Cawisadi\",\n  \"Cawisono\",\n  \"Cawuk\",\n  \"Cayadi\",\n  \"Cecep\",\n  \"Cemani\",\n  \"Cemeti\",\n  \"Cemplunk\",\n  \"Cengkal\",\n  \"Cengkir\",\n  \"Dacin\",\n  \"Dadap\",\n  \"Dadi\",\n  \"Dagel\",\n  \"Daliman\",\n  \"Dalimin\",\n  \"Daliono\",\n  \"Damar\",\n  \"Damu\",\n  \"Danang\",\n  \"Daniswara\",\n  \"Danu\",\n  \"Danuja\",\n  \"Dariati\",\n  \"Darijan\",\n  \"Darimin\",\n  \"Darmaji\",\n  \"Darman\",\n  \"Darmana\",\n  \"Darmanto\",\n  \"Darsirah\",\n  \"Dartono\",\n  \"Daru\",\n  \"Daruna\",\n  \"Daryani\",\n  \"Dasa\",\n  \"Digdaya\",\n  \"Dimas\",\n  \"Dimaz\",\n  \"Dipa\",\n  \"Dirja\",\n  \"Drajat\",\n  \"Dwi\",\n  \"Dono\",\n  \"Dodo\",\n  \"Edi\",\n  \"Eka\",\n  \"Elon\",\n  \"Eluh\",\n  \"Eman\",\n  \"Emas\",\n  \"Embuh\",\n  \"Emong\",\n  \"Empluk\",\n  \"Endra\",\n  \"Enteng\",\n  \"Estiawan\",\n  \"Estiono\",\n  \"Eko\",\n  \"Edi\",\n  \"Edison\",\n  \"Edward\",\n  \"Elvin\",\n  \"Erik\",\n  \"Emil\",\n  \"Ega\",\n  \"Emin\",\n  \"Eja\",\n  \"Gada\",\n  \"Gadang\",\n  \"Gaduh\",\n  \"Gaiman\",\n  \"Galak\",\n  \"Galang\",\n  \"Galar\",\n  \"Galih\",\n  \"Galiono\",\n  \"Galuh\",\n  \"Galur\",\n  \"Gaman\",\n  \"Gamani\",\n  \"Gamanto\",\n  \"Gambira\",\n  \"Gamblang\",\n  \"Ganda\",\n  \"Gandewa\",\n  \"Gandi\",\n  \"Gandi\",\n  \"Ganep\",\n  \"Gangsa\",\n  \"Gangsar\",\n  \"Ganjaran\",\n  \"Gantar\",\n  \"Gara\",\n  \"Garan\",\n  \"Garang\",\n  \"Garda\",\n  \"Gatot\",\n  \"Gatra\",\n  \"Gilang\",\n  \"Galih\",\n  \"Ghani\",\n  \"Gading\",\n  \"Hairyanto\",\n  \"Hardana\",\n  \"Hardi\",\n  \"Harimurti\",\n  \"Harja\",\n  \"Harjasa\",\n  \"Harjaya\",\n  \"Harjo\",\n  \"Harsana\",\n  \"Harsanto\",\n  \"Harsaya\",\n  \"Hartaka\",\n  \"Hartana\",\n  \"Harto\",\n  \"Hasta\",\n  \"Heru\",\n  \"Himawan\",\n  \"Hadi\",\n  \"Halim\",\n  \"Hasim\",\n  \"Hasan\",\n  \"Hendra\",\n  \"Hendri\",\n  \"Heryanto\",\n  \"Hamzah\",\n  \"Hari\",\n  \"Imam\",\n  \"Indra\",\n  \"Irwan\",\n  \"Irsad\",\n  \"Ikhsan\",\n  \"Irfan\",\n  \"Ian\",\n  \"Ibrahim\",\n  \"Ibrani\",\n  \"Ismail\",\n  \"Irnanto\",\n  \"Ilyas\",\n  \"Ibun\",\n  \"Ivan\",\n  \"Ikin\",\n  \"Ihsan\",\n  \"Jabal\",\n  \"Jaeman\",\n  \"Jaga\",\n  \"Jagapati\",\n  \"Jagaraga\",\n  \"Jail\",\n  \"Jaiman\",\n  \"Jaka\",\n  \"Jarwa\",\n  \"Jarwadi\",\n  \"Jarwi\",\n  \"Jasmani\",\n  \"Jaswadi\",\n  \"Jati\",\n  \"Jatmiko\",\n  \"Jaya\",\n  \"Jayadi\",\n  \"Jayeng\",\n  \"Jinawi\",\n  \"Jindra\",\n  \"Joko\",\n  \"Jumadi\",\n  \"Jumari\",\n  \"Jamal\",\n  \"Jamil\",\n  \"Jais\",\n  \"Jefri\",\n  \"Johan\",\n  \"Jono\",\n  \"Kacung\",\n  \"Kajen\",\n  \"Kambali\",\n  \"Kamidin\",\n  \"Kariman\",\n  \"Karja\",\n  \"Karma\",\n  \"Karman\",\n  \"Karna\",\n  \"Karsa\",\n  \"Karsana\",\n  \"Karta\",\n  \"Kasiran\",\n  \"Kasusra\",\n  \"Kawaca\",\n  \"Kawaya\",\n  \"Kayun\",\n  \"Kemba\",\n  \"Kenari\",\n  \"Kenes\",\n  \"Kuncara\",\n  \"Kunthara\",\n  \"Kusuma\",\n  \"Kadir\",\n  \"Kala\",\n  \"Kalim\",\n  \"Kurnia\",\n  \"Kanda\",\n  \"Kardi\",\n  \"Karya\",\n  \"Kasim\",\n  \"Kairav\",\n  \"Kenzie\",\n  \"Kemal\",\n  \"Kamal\",\n  \"Koko\",\n  \"Labuh\",\n  \"Laksana\",\n  \"Lamar\",\n  \"Lanang\",\n  \"Langgeng\",\n  \"Lanjar\",\n  \"Lantar\",\n  \"Lega\",\n  \"Legawa\",\n  \"Lembah\",\n  \"Liman\",\n  \"Limar\",\n  \"Luhung\",\n  \"Lukita\",\n  \"Luluh\",\n  \"Lulut\",\n  \"Lurhur\",\n  \"Luwar\",\n  \"Luwes\",\n  \"Latif\",\n  \"Lasmanto\",\n  \"Lukman\",\n  \"Luthfi\",\n  \"Leo\",\n  \"Luis\",\n  \"Lutfan\",\n  \"Lasmono\",\n  \"Laswi\",\n  \"Mahesa\",\n  \"Makara\",\n  \"Makuta\",\n  \"Manah\",\n  \"Maras\",\n  \"Margana\",\n  \"Mariadi\",\n  \"Marsudi\",\n  \"Martaka\",\n  \"Martana\",\n  \"Martani\",\n  \"Marwata\",\n  \"Maryadi\",\n  \"Maryanto\",\n  \"Mitra\",\n  \"Mujur\",\n  \"Mulya\",\n  \"Mulyanto\",\n  \"Mulyono\",\n  \"Mumpuni\",\n  \"Muni\",\n  \"Mursita\",\n  \"Murti\",\n  \"Mustika\",\n  \"Maman\",\n  \"Mahmud\",\n  \"Mahdi\",\n  \"Mahfud\",\n  \"Malik\",\n  \"Muhammad\",\n  \"Mustofa\",\n  \"Marsito\",\n  \"Mursinin\",\n  \"Nalar\",\n  \"Naradi\",\n  \"Nardi\",\n  \"Niyaga\",\n  \"Nrima\",\n  \"Nugraha\",\n  \"Nyana\",\n  \"Narji\",\n  \"Nasab\",\n  \"Nasrullah\",\n  \"Nasim\",\n  \"Najib\",\n  \"Najam\",\n  \"Nyoman\",\n  \"Olga\",\n  \"Ozy\",\n  \"Omar\",\n  \"Opan\",\n  \"Oskar\",\n  \"Oman\",\n  \"Okto\",\n  \"Okta\",\n  \"Opung\",\n  \"Paiman\",\n  \"Panca\",\n  \"Pangeran\",\n  \"Pangestu\",\n  \"Pardi\",\n  \"Parman\",\n  \"Perkasa\",\n  \"Praba\",\n  \"Prabu\",\n  \"Prabawa\",\n  \"Prabowo\",\n  \"Prakosa\",\n  \"Pranata\",\n  \"Pranawa\",\n  \"Prasetya\",\n  \"Prasetyo\",\n  \"Prayitna\",\n  \"Prayoga\",\n  \"Prayogo\",\n  \"Purwadi\",\n  \"Purwa\",\n  \"Purwanto\",\n  \"Panji\",\n  \"Pandu\",\n  \"Paiman\",\n  \"Prima\",\n  \"Putu\",\n  \"Raden\",\n  \"Raditya\",\n  \"Raharja\",\n  \"Rama\",\n  \"Rangga\",\n  \"Reksa\",\n  \"Respati\",\n  \"Rusman\",\n  \"Rosman\",\n  \"Rahmat\",\n  \"Rahman\",\n  \"Rendy\",\n  \"Reza\",\n  \"Rizki\",\n  \"Ridwan\",\n  \"Rudi\",\n  \"Raden\",\n  \"Radit\",\n  \"Radika\",\n  \"Rafi\",\n  \"Rafid\",\n  \"Raihan\",\n  \"Salman\",\n  \"Saadat\",\n  \"Saiful\",\n  \"Surya\",\n  \"Slamet\",\n  \"Samsul\",\n  \"Soleh\",\n  \"Simon\",\n  \"Sabar\",\n  \"Sabri\",\n  \"Sidiq\",\n  \"Satya\",\n  \"Setya\",\n  \"Saka\",\n  \"Sakti\",\n  \"Taswir\",\n  \"Tedi\",\n  \"Teddy\",\n  \"Taufan\",\n  \"Taufik\",\n  \"Tomi\",\n  \"Tasnim\",\n  \"Teguh\",\n  \"Tasdik\",\n  \"Timbul\",\n  \"Tirta\",\n  \"Tirtayasa\",\n  \"Tri\",\n  \"Tugiman\",\n  \"Umar\",\n  \"Usman\",\n  \"Uda\",\n  \"Umay\",\n  \"Unggul\",\n  \"Utama\",\n  \"Umaya\",\n  \"Upik\",\n  \"Viktor\",\n  \"Vino\",\n  \"Vinsen\",\n  \"Vero\",\n  \"Vega\",\n  \"Viman\",\n  \"Virman\",\n  \"Wahyu\",\n  \"Wira\",\n  \"Wisnu\",\n  \"Wadi\",\n  \"Wardi\",\n  \"Warji\",\n  \"Waluyo\",\n  \"Wakiman\",\n  \"Wage\",\n  \"Wardaya\",\n  \"Warsa\",\n  \"Warsita\",\n  \"Warta\",\n  \"Wasis\",\n  \"Wawan\",\n  \"Xanana\",\n  \"Yahya\",\n  \"Yusuf\",\n  \"Yosef\",\n  \"Yono\",\n  \"Yoga\"\n];\n},{}],568:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adriansyah\",\n  \"Ardianto\",\n  \"Anggriawan\",\n  \"Budiman\",\n  \"Budiyanto\",\n  \"Damanik\",\n  \"Dongoran\",\n  \"Dabukke\",\n  \"Firmansyah\",\n  \"Firgantoro\",\n  \"Gunarto\",\n  \"Gunawan\",\n  \"Hardiansyah\",\n  \"Habibi\",\n  \"Hakim\",\n  \"Halim\",\n  \"Haryanto\",\n  \"Hidayat\",\n  \"Hidayanto\",\n  \"Hutagalung\",\n  \"Hutapea\",\n  \"Hutasoit\",\n  \"Irawan\",\n  \"Iswahyudi\",\n  \"Kuswoyo\",\n  \"Januar\",\n  \"Jailani\",\n  \"Kurniawan\",\n  \"Kusumo\",\n  \"Latupono\",\n  \"Lazuardi\",\n  \"Maheswara\",\n  \"Mahendra\",\n  \"Mustofa\",\n  \"Mansur\",\n  \"Mandala\",\n  \"Megantara\",\n  \"Maulana\",\n  \"Maryadi\",\n  \"Mangunsong\",\n  \"Manullang\",\n  \"Marpaung\",\n  \"Marbun\",\n  \"Narpati\",\n  \"Natsir\",\n  \"Nugroho\",\n  \"Najmudin\",\n  \"Nashiruddin\",\n  \"Nainggolan\",\n  \"Nababan\",\n  \"Napitupulu\",\n  \"Pangestu\",\n  \"Putra\",\n  \"Pranowo\",\n  \"Prabowo\",\n  \"Pratama\",\n  \"Prasetya\",\n  \"Prasetyo\",\n  \"Pradana\",\n  \"Pradipta\",\n  \"Prakasa\",\n  \"Permadi\",\n  \"Prasasta\",\n  \"Prayoga\",\n  \"Ramadan\",\n  \"Rajasa\",\n  \"Rajata\",\n  \"Saptono\",\n  \"Santoso\",\n  \"Saputra\",\n  \"Saefullah\",\n  \"Setiawan\",\n  \"Suryono\",\n  \"Suwarno\",\n  \"Siregar\",\n  \"Sihombing\",\n  \"Salahudin\",\n  \"Sihombing\",\n  \"Samosir\",\n  \"Saragih\",\n  \"Sihotang\",\n  \"Simanjuntak\",\n  \"Sinaga\",\n  \"Simbolon\",\n  \"Sitompul\",\n  \"Sitorus\",\n  \"Sirait\",\n  \"Siregar\",\n  \"Situmorang\",\n  \"Tampubolon\",\n  \"Thamrin\",\n  \"Tamba\",\n  \"Tarihoran\",\n  \"Utama\",\n  \"Uwais\",\n  \"Wahyudin\",\n  \"Waluyo\",\n  \"Wibowo\",\n  \"Winarno\",\n  \"Wibisono\",\n  \"Wijaya\",\n  \"Widodo\",\n  \"Wacana\",\n  \"Waskita\",\n  \"Wasita\",\n  \"Zulkarnain\"\n];\n},{}],569:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{male_first_name} #{male_last_name}\",\n  \"#{male_last_name} #{male_first_name}\",\n  \"#{male_first_name} #{male_first_name} #{male_last_name}\",\n  \"#{female_first_name} #{female_last_name}\",\n  \"#{female_first_name} #{male_last_name}\",\n  \"#{female_last_name} #{female_first_name}\",\n  \"#{female_first_name} #{female_first_name} #{female_last_name}\"\n];\n\n},{}],570:[function(require,module,exports){\nmodule[\"exports\"] = [];\n},{}],571:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"S.Ked\",\n  \"S.Gz\",\n  \"S.Pt\",\n  \"S.IP\",\n  \"S.E.I\",\n  \"S.E.\",\n  \"S.Kom\",\n  \"S.H.\",\n  \"S.T.\",\n  \"S.Pd\",\n  \"S.Psi\",\n  \"S.I.Kom\",\n  \"S.Sos\",\n  \"S.Farm\",\n  \"M.M.\",\n  \"M.Kom.\",\n  \"M.TI.\",\n  \"M.Pd\",\n  \"M.Farm\",\n  \"M.Ak\"\n];\n},{}],572:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"02# #### ###\",\n  \"02## #### ###\",\n  \"03## #### ###\",\n  \"04## #### ###\",\n  \"05## #### ###\",\n  \"06## #### ###\",\n  \"07## #### ###\",\n  \"09## #### ###\",\n  \"02# #### ####\",\n  \"02## #### ####\",\n  \"03## #### ####\",\n  \"04## #### ####\",\n  \"05## #### ####\",\n  \"06## #### ####\",\n  \"07## #### ####\",\n  \"09## #### ####\",\n  \"08## ### ###\",\n  \"08## #### ###\",\n  \"08## #### ####\",\n  \"(+62) 8## ### ###\",\n  \"(+62) 2# #### ###\",\n  \"(+62) 2## #### ###\",\n  \"(+62) 3## #### ###\",\n  \"(+62) 4## #### ###\",\n  \"(+62) 5## #### ###\",\n  \"(+62) 6## #### ###\",\n  \"(+62) 7## #### ###\",\n  \"(+62) 8## #### ###\",\n  \"(+62) 9## #### ###\",\n  \"(+62) 2# #### ####\",\n  \"(+62) 2## #### ####\",\n  \"(+62) 3## #### ####\",\n  \"(+62) 4## #### ####\",\n  \"(+62) 5## #### ####\",\n  \"(+62) 6## #### ####\",\n  \"(+62) 7## #### ####\",\n  \"(+62) 8## #### ####\",\n  \"(+62) 9## #### ####\"\n];\n},{}],573:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":572,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],574:[function(require,module,exports){\nmodule.exports=require(511)\n},{\"/Users/a/dev/faker.js/lib/locales/ge/address/building_number.js\":511}],575:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_prefix} #{Name.first_name} #{city_suffix}\",\n  \"#{city_prefix} #{Name.first_name}\",\n  \"#{Name.first_name} #{city_suffix}\",\n  \"#{Name.last_name} #{city_suffix}\"\n];\n\n},{}],576:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"San\",\n  \"Borgo\",\n  \"Sesto\",\n  \"Quarto\",\n  \"Settimo\"\n];\n\n},{}],577:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"a mare\",\n  \"lido\",\n  \"ligure\",\n  \"del friuli\",\n  \"salentino\",\n  \"calabro\",\n  \"veneto\",\n  \"nell'emilia\",\n  \"umbro\",\n  \"laziale\",\n  \"terme\",\n  \"sardo\"\n];\n\n},{}],578:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afghanistan\",\n  \"Albania\",\n  \"Algeria\",\n  \"American Samoa\",\n  \"Andorra\",\n  \"Angola\",\n  \"Anguilla\",\n  \"Antartide (territori a sud del 60° parallelo)\",\n  \"Antigua e Barbuda\",\n  \"Argentina\",\n  \"Armenia\",\n  \"Aruba\",\n  \"Australia\",\n  \"Austria\",\n  \"Azerbaijan\",\n  \"Bahamas\",\n  \"Bahrain\",\n  \"Bangladesh\",\n  \"Barbados\",\n  \"Bielorussia\",\n  \"Belgio\",\n  \"Belize\",\n  \"Benin\",\n  \"Bermuda\",\n  \"Bhutan\",\n  \"Bolivia\",\n  \"Bosnia e Herzegovina\",\n  \"Botswana\",\n  \"Bouvet Island (Bouvetoya)\",\n  \"Brasile\",\n  \"Territorio dell'arcipelago indiano\",\n  \"Isole Vergini Britanniche\",\n  \"Brunei Darussalam\",\n  \"Bulgaria\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Cambogia\",\n  \"Cameroon\",\n  \"Canada\",\n  \"Capo Verde\",\n  \"Isole Cayman\",\n  \"Repubblica Centrale Africana\",\n  \"Chad\",\n  \"Cile\",\n  \"Cina\",\n  \"Isola di Pasqua\",\n  \"Isola di Cocos (Keeling)\",\n  \"Colombia\",\n  \"Comoros\",\n  \"Congo\",\n  \"Isole Cook\",\n  \"Costa Rica\",\n  \"Costa d'Avorio\",\n  \"Croazia\",\n  \"Cuba\",\n  \"Cipro\",\n  \"Repubblica Ceca\",\n  \"Danimarca\",\n  \"Gibuti\",\n  \"Repubblica Dominicana\",\n  \"Equador\",\n  \"Egitto\",\n  \"El Salvador\",\n  \"Guinea Equatoriale\",\n  \"Eritrea\",\n  \"Estonia\",\n  \"Etiopia\",\n  \"Isole Faroe\",\n  \"Isole Falkland (Malvinas)\",\n  \"Fiji\",\n  \"Finlandia\",\n  \"Francia\",\n  \"Guyana Francese\",\n  \"Polinesia Francese\",\n  \"Territori Francesi del sud\",\n  \"Gabon\",\n  \"Gambia\",\n  \"Georgia\",\n  \"Germania\",\n  \"Ghana\",\n  \"Gibilterra\",\n  \"Grecia\",\n  \"Groenlandia\",\n  \"Grenada\",\n  \"Guadalupa\",\n  \"Guam\",\n  \"Guatemala\",\n  \"Guernsey\",\n  \"Guinea\",\n  \"Guinea-Bissau\",\n  \"Guyana\",\n  \"Haiti\",\n  \"Heard Island and McDonald Islands\",\n  \"Città del Vaticano\",\n  \"Honduras\",\n  \"Hong Kong\",\n  \"Ungheria\",\n  \"Islanda\",\n  \"India\",\n  \"Indonesia\",\n  \"Iran\",\n  \"Iraq\",\n  \"Irlanda\",\n  \"Isola di Man\",\n  \"Israele\",\n  \"Italia\",\n  \"Giamaica\",\n  \"Giappone\",\n  \"Jersey\",\n  \"Giordania\",\n  \"Kazakhstan\",\n  \"Kenya\",\n  \"Kiribati\",\n  \"Korea\",\n  \"Kuwait\",\n  \"Republicca Kirgiza\",\n  \"Repubblica del Laos\",\n  \"Latvia\",\n  \"Libano\",\n  \"Lesotho\",\n  \"Liberia\",\n  \"Libyan Arab Jamahiriya\",\n  \"Liechtenstein\",\n  \"Lituania\",\n  \"Lussemburgo\",\n  \"Macao\",\n  \"Macedonia\",\n  \"Madagascar\",\n  \"Malawi\",\n  \"Malesia\",\n  \"Maldive\",\n  \"Mali\",\n  \"Malta\",\n  \"Isole Marshall\",\n  \"Martinica\",\n  \"Mauritania\",\n  \"Mauritius\",\n  \"Mayotte\",\n  \"Messico\",\n  \"Micronesia\",\n  \"Moldova\",\n  \"Principato di Monaco\",\n  \"Mongolia\",\n  \"Montenegro\",\n  \"Montserrat\",\n  \"Marocco\",\n  \"Mozambico\",\n  \"Myanmar\",\n  \"Namibia\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Antille Olandesi\",\n  \"Olanda\",\n  \"Nuova Caledonia\",\n  \"Nuova Zelanda\",\n  \"Nicaragua\",\n  \"Niger\",\n  \"Nigeria\",\n  \"Niue\",\n  \"Isole Norfolk\",\n  \"Northern Mariana Islands\",\n  \"Norvegia\",\n  \"Oman\",\n  \"Pakistan\",\n  \"Palau\",\n  \"Palestina\",\n  \"Panama\",\n  \"Papua Nuova Guinea\",\n  \"Paraguay\",\n  \"Peru\",\n  \"Filippine\",\n  \"Pitcairn Islands\",\n  \"Polonia\",\n  \"Portogallo\",\n  \"Porto Rico\",\n  \"Qatar\",\n  \"Reunion\",\n  \"Romania\",\n  \"Russia\",\n  \"Rwanda\",\n  \"San Bartolomeo\",\n  \"Sant'Elena\",\n  \"Saint Kitts and Nevis\",\n  \"Saint Lucia\",\n  \"Saint Martin\",\n  \"Saint Pierre and Miquelon\",\n  \"Saint Vincent and the Grenadines\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Sao Tome and Principe\",\n  \"Arabia Saudita\",\n  \"Senegal\",\n  \"Serbia\",\n  \"Seychelles\",\n  \"Sierra Leone\",\n  \"Singapore\",\n  \"Slovenia\",\n  \"Isole Solomon\",\n  \"Somalia\",\n  \"Sud Africa\",\n  \"Georgia del sud e South Sandwich Islands\",\n  \"Spagna\",\n  \"Sri Lanka\",\n  \"Sudan\",\n  \"Suriname\",\n  \"Svalbard & Jan Mayen Islands\",\n  \"Swaziland\",\n  \"Svezia\",\n  \"Svizzera\",\n  \"Siria\",\n  \"Taiwan\",\n  \"Tajikistan\",\n  \"Tanzania\",\n  \"Tailandia\",\n  \"Timor-Leste\",\n  \"Togo\",\n  \"Tokelau\",\n  \"Tonga\",\n  \"Trinidad e Tobago\",\n  \"Tunisia\",\n  \"Turchia\",\n  \"Turkmenistan\",\n  \"Isole di Turks and Caicos\",\n  \"Tuvalu\",\n  \"Uganda\",\n  \"Ucraina\",\n  \"Emirati Arabi Uniti\",\n  \"Regno Unito\",\n  \"Stati Uniti d'America\",\n  \"United States Minor Outlying Islands\",\n  \"Isole Vergini Statunitensi\",\n  \"Uruguay\",\n  \"Uzbekistan\",\n  \"Vanuatu\",\n  \"Venezuela\",\n  \"Vietnam\",\n  \"Wallis and Futuna\",\n  \"Western Sahara\",\n  \"Yemen\",\n  \"Zambia\",\n  \"Zimbabwe\"\n];\n\n},{}],579:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Italia\"\n];\n\n},{}],580:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":574,\"./city\":575,\"./city_prefix\":576,\"./city_suffix\":577,\"./country\":578,\"./default_country\":579,\"./postcode\":581,\"./secondary_address\":582,\"./state\":583,\"./state_abbr\":584,\"./street_address\":585,\"./street_name\":586,\"./street_suffix\":587}],581:[function(require,module,exports){\nmodule.exports=require(379)\n},{\"/Users/a/dev/faker.js/lib/locales/es/address/postcode.js\":379}],582:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Appartamento ##\",\n  \"Piano #\"\n];\n\n},{}],583:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Agrigento\",\n  \"Alessandria\",\n  \"Ancona\",\n  \"Aosta\",\n  \"Arezzo\",\n  \"Ascoli Piceno\",\n  \"Asti\",\n  \"Avellino\",\n  \"Bari\",\n  \"Barletta-Andria-Trani\",\n  \"Belluno\",\n  \"Benevento\",\n  \"Bergamo\",\n  \"Biella\",\n  \"Bologna\",\n  \"Bolzano\",\n  \"Brescia\",\n  \"Brindisi\",\n  \"Cagliari\",\n  \"Caltanissetta\",\n  \"Campobasso\",\n  \"Carbonia-Iglesias\",\n  \"Caserta\",\n  \"Catania\",\n  \"Catanzaro\",\n  \"Chieti\",\n  \"Como\",\n  \"Cosenza\",\n  \"Cremona\",\n  \"Crotone\",\n  \"Cuneo\",\n  \"Enna\",\n  \"Fermo\",\n  \"Ferrara\",\n  \"Firenze\",\n  \"Foggia\",\n  \"Forlì-Cesena\",\n  \"Frosinone\",\n  \"Genova\",\n  \"Gorizia\",\n  \"Grosseto\",\n  \"Imperia\",\n  \"Isernia\",\n  \"La Spezia\",\n  \"L'Aquila\",\n  \"Latina\",\n  \"Lecce\",\n  \"Lecco\",\n  \"Livorno\",\n  \"Lodi\",\n  \"Lucca\",\n  \"Macerata\",\n  \"Mantova\",\n  \"Massa-Carrara\",\n  \"Matera\",\n  \"Messina\",\n  \"Milano\",\n  \"Modena\",\n  \"Monza e della Brianza\",\n  \"Napoli\",\n  \"Novara\",\n  \"Nuoro\",\n  \"Olbia-Tempio\",\n  \"Oristano\",\n  \"Padova\",\n  \"Palermo\",\n  \"Parma\",\n  \"Pavia\",\n  \"Perugia\",\n  \"Pesaro e Urbino\",\n  \"Pescara\",\n  \"Piacenza\",\n  \"Pisa\",\n  \"Pistoia\",\n  \"Pordenone\",\n  \"Potenza\",\n  \"Prato\",\n  \"Ragusa\",\n  \"Ravenna\",\n  \"Reggio Calabria\",\n  \"Reggio Emilia\",\n  \"Rieti\",\n  \"Rimini\",\n  \"Roma\",\n  \"Rovigo\",\n  \"Salerno\",\n  \"Medio Campidano\",\n  \"Sassari\",\n  \"Savona\",\n  \"Siena\",\n  \"Siracusa\",\n  \"Sondrio\",\n  \"Taranto\",\n  \"Teramo\",\n  \"Terni\",\n  \"Torino\",\n  \"Ogliastra\",\n  \"Trapani\",\n  \"Trento\",\n  \"Treviso\",\n  \"Trieste\",\n  \"Udine\",\n  \"Varese\",\n  \"Venezia\",\n  \"Verbano-Cusio-Ossola\",\n  \"Vercelli\",\n  \"Verona\",\n  \"Vibo Valentia\",\n  \"Vicenza\",\n  \"Viterbo\"\n];\n\n},{}],584:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AG\",\n  \"AL\",\n  \"AN\",\n  \"AO\",\n  \"AR\",\n  \"AP\",\n  \"AT\",\n  \"AV\",\n  \"BA\",\n  \"BT\",\n  \"BL\",\n  \"BN\",\n  \"BG\",\n  \"BI\",\n  \"BO\",\n  \"BZ\",\n  \"BS\",\n  \"BR\",\n  \"CA\",\n  \"CL\",\n  \"CB\",\n  \"CI\",\n  \"CE\",\n  \"CT\",\n  \"CZ\",\n  \"CH\",\n  \"CO\",\n  \"CS\",\n  \"CR\",\n  \"KR\",\n  \"CN\",\n  \"EN\",\n  \"FM\",\n  \"FE\",\n  \"FI\",\n  \"FG\",\n  \"FC\",\n  \"FR\",\n  \"GE\",\n  \"GO\",\n  \"GR\",\n  \"IM\",\n  \"IS\",\n  \"SP\",\n  \"AQ\",\n  \"LT\",\n  \"LE\",\n  \"LC\",\n  \"LI\",\n  \"LO\",\n  \"LU\",\n  \"MC\",\n  \"MN\",\n  \"MS\",\n  \"MT\",\n  \"ME\",\n  \"MI\",\n  \"MO\",\n  \"MB\",\n  \"NA\",\n  \"NO\",\n  \"NU\",\n  \"OT\",\n  \"OR\",\n  \"PD\",\n  \"PA\",\n  \"PR\",\n  \"PV\",\n  \"PG\",\n  \"PU\",\n  \"PE\",\n  \"PC\",\n  \"PI\",\n  \"PT\",\n  \"PN\",\n  \"PZ\",\n  \"PO\",\n  \"RG\",\n  \"RA\",\n  \"RC\",\n  \"RE\",\n  \"RI\",\n  \"RN\",\n  \"RM\",\n  \"RO\",\n  \"SA\",\n  \"VS\",\n  \"SS\",\n  \"SV\",\n  \"SI\",\n  \"SR\",\n  \"SO\",\n  \"TA\",\n  \"TE\",\n  \"TR\",\n  \"TO\",\n  \"OG\",\n  \"TP\",\n  \"TN\",\n  \"TV\",\n  \"TS\",\n  \"UD\",\n  \"VA\",\n  \"VE\",\n  \"VB\",\n  \"VC\",\n  \"VR\",\n  \"VV\",\n  \"VI\",\n  \"VT\"\n];\n\n},{}],585:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_name} #{building_number}\",\n  \"#{street_name} #{building_number}, #{secondary_address}\"\n];\n\n},{}],586:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_suffix} #{Name.first_name}\",\n  \"#{street_suffix} #{Name.last_name}\"\n];\n\n},{}],587:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Piazza\",\n  \"Strada\",\n  \"Via\",\n  \"Borgo\",\n  \"Contrada\",\n  \"Rotonda\",\n  \"Incrocio\"\n];\n\n},{}],588:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"24 ore\",\n  \"24/7\",\n  \"terza generazione\",\n  \"quarta generazione\",\n  \"quinta generazione\",\n  \"sesta generazione\",\n  \"asimmetrica\",\n  \"asincrona\",\n  \"background\",\n  \"bi-direzionale\",\n  \"biforcata\",\n  \"bottom-line\",\n  \"coerente\",\n  \"coesiva\",\n  \"composita\",\n  \"sensibile al contesto\",\n  \"basta sul contesto\",\n  \"basata sul contenuto\",\n  \"dedicata\",\n  \"didattica\",\n  \"direzionale\",\n  \"discreta\",\n  \"dinamica\",\n  \"eco-centrica\",\n  \"esecutiva\",\n  \"esplicita\",\n  \"full-range\",\n  \"globale\",\n  \"euristica\",\n  \"alto livello\",\n  \"olistica\",\n  \"omogenea\",\n  \"ibrida\",\n  \"impattante\",\n  \"incrementale\",\n  \"intangibile\",\n  \"interattiva\",\n  \"intermediaria\",\n  \"locale\",\n  \"logistica\",\n  \"massimizzata\",\n  \"metodica\",\n  \"mission-critical\",\n  \"mobile\",\n  \"modulare\",\n  \"motivazionale\",\n  \"multimedia\",\n  \"multi-tasking\",\n  \"nazionale\",\n  \"neutrale\",\n  \"nextgeneration\",\n  \"non-volatile\",\n  \"object-oriented\",\n  \"ottima\",\n  \"ottimizzante\",\n  \"radicale\",\n  \"real-time\",\n  \"reciproca\",\n  \"regionale\",\n  \"responsiva\",\n  \"scalabile\",\n  \"secondaria\",\n  \"stabile\",\n  \"statica\",\n  \"sistematica\",\n  \"sistemica\",\n  \"tangibile\",\n  \"terziaria\",\n  \"uniforme\",\n  \"valore aggiunto\"\n];\n\n},{}],589:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"valore aggiunto\",\n  \"verticalizzate\",\n  \"proattive\",\n  \"forti\",\n  \"rivoluzionari\",\n  \"scalabili\",\n  \"innovativi\",\n  \"intuitivi\",\n  \"strategici\",\n  \"e-business\",\n  \"mission-critical\",\n  \"24/7\",\n  \"globali\",\n  \"B2B\",\n  \"B2C\",\n  \"granulari\",\n  \"virtuali\",\n  \"virali\",\n  \"dinamiche\",\n  \"magnetiche\",\n  \"web\",\n  \"interattive\",\n  \"sexy\",\n  \"back-end\",\n  \"real-time\",\n  \"efficienti\",\n  \"front-end\",\n  \"distributivi\",\n  \"estensibili\",\n  \"mondiali\",\n  \"open-source\",\n  \"cross-platform\",\n  \"sinergiche\",\n  \"out-of-the-box\",\n  \"enterprise\",\n  \"integrate\",\n  \"di impatto\",\n  \"wireless\",\n  \"trasparenti\",\n  \"next-generation\",\n  \"cutting-edge\",\n  \"visionari\",\n  \"plug-and-play\",\n  \"collaborative\",\n  \"olistiche\",\n  \"ricche\"\n];\n\n},{}],590:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"partnerships\",\n  \"comunità\",\n  \"ROI\",\n  \"soluzioni\",\n  \"e-services\",\n  \"nicchie\",\n  \"tecnologie\",\n  \"contenuti\",\n  \"supply-chains\",\n  \"convergenze\",\n  \"relazioni\",\n  \"architetture\",\n  \"interfacce\",\n  \"mercati\",\n  \"e-commerce\",\n  \"sistemi\",\n  \"modelli\",\n  \"schemi\",\n  \"reti\",\n  \"applicazioni\",\n  \"metriche\",\n  \"e-business\",\n  \"funzionalità\",\n  \"esperienze\",\n  \"webservices\",\n  \"metodologie\"\n];\n\n},{}],591:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"implementate\",\n  \"utilizzo\",\n  \"integrate\",\n  \"ottimali\",\n  \"evolutive\",\n  \"abilitate\",\n  \"reinventate\",\n  \"aggregate\",\n  \"migliorate\",\n  \"incentivate\",\n  \"monetizzate\",\n  \"sinergizzate\",\n  \"strategiche\",\n  \"deploy\",\n  \"marchi\",\n  \"accrescitive\",\n  \"target\",\n  \"sintetizzate\",\n  \"spedizioni\",\n  \"massimizzate\",\n  \"innovazione\",\n  \"guida\",\n  \"estensioni\",\n  \"generate\",\n  \"exploit\",\n  \"transizionali\",\n  \"matrici\",\n  \"ricontestualizzate\"\n];\n\n},{}],592:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"adattiva\",\n  \"avanzata\",\n  \"migliorata\",\n  \"assimilata\",\n  \"automatizzata\",\n  \"bilanciata\",\n  \"centralizzata\",\n  \"compatibile\",\n  \"configurabile\",\n  \"cross-platform\",\n  \"decentralizzata\",\n  \"digitalizzata\",\n  \"distribuita\",\n  \"piccola\",\n  \"ergonomica\",\n  \"esclusiva\",\n  \"espansa\",\n  \"estesa\",\n  \"configurabile\",\n  \"fondamentale\",\n  \"orizzontale\",\n  \"implementata\",\n  \"innovativa\",\n  \"integrata\",\n  \"intuitiva\",\n  \"inversa\",\n  \"gestita\",\n  \"obbligatoria\",\n  \"monitorata\",\n  \"multi-canale\",\n  \"multi-laterale\",\n  \"open-source\",\n  \"operativa\",\n  \"ottimizzata\",\n  \"organica\",\n  \"persistente\",\n  \"polarizzata\",\n  \"proattiva\",\n  \"programmabile\",\n  \"progressiva\",\n  \"reattiva\",\n  \"riallineata\",\n  \"ricontestualizzata\",\n  \"ridotta\",\n  \"robusta\",\n  \"sicura\",\n  \"condivisibile\",\n  \"stand-alone\",\n  \"switchabile\",\n  \"sincronizzata\",\n  \"sinergica\",\n  \"totale\",\n  \"universale\",\n  \"user-friendly\",\n  \"versatile\",\n  \"virtuale\",\n  \"visionaria\"\n];\n\n},{}],593:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.noun = require(\"./noun\");\ncompany.descriptor = require(\"./descriptor\");\ncompany.adjective = require(\"./adjective\");\ncompany.bs_noun = require(\"./bs_noun\");\ncompany.bs_verb = require(\"./bs_verb\");\ncompany.bs_adjective = require(\"./bs_adjective\");\ncompany.name = require(\"./name\");\n\n},{\"./adjective\":588,\"./bs_adjective\":589,\"./bs_noun\":590,\"./bs_verb\":591,\"./descriptor\":592,\"./name\":594,\"./noun\":595,\"./suffix\":596}],594:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name}-#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name}, #{Name.last_name} e #{Name.last_name} #{suffix}\"\n];\n\n},{}],595:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abilità\",\n  \"Access\",\n  \"Adattatore\",\n  \"Algoritmo\",\n  \"Alleanza\",\n  \"Analizzatore\",\n  \"Applicazione\",\n  \"Approccio\",\n  \"Architettura\",\n  \"Archivio\",\n  \"Intelligenza artificiale\",\n  \"Array\",\n  \"Attitudine\",\n  \"Benchmark\",\n  \"Capacità\",\n  \"Sfida\",\n  \"Circuito\",\n  \"Collaborazione\",\n  \"Complessità\",\n  \"Concetto\",\n  \"Conglomerato\",\n  \"Contingenza\",\n  \"Core\",\n  \"Database\",\n  \"Data-warehouse\",\n  \"Definizione\",\n  \"Emulazione\",\n  \"Codifica\",\n  \"Criptazione\",\n  \"Firmware\",\n  \"Flessibilità\",\n  \"Previsione\",\n  \"Frame\",\n  \"framework\",\n  \"Funzione\",\n  \"Funzionalità\",\n  \"Interfaccia grafica\",\n  \"Hardware\",\n  \"Help-desk\",\n  \"Gerarchia\",\n  \"Hub\",\n  \"Implementazione\",\n  \"Infrastruttura\",\n  \"Iniziativa\",\n  \"Installazione\",\n  \"Set di istruzioni\",\n  \"Interfaccia\",\n  \"Soluzione internet\",\n  \"Intranet\",\n  \"Conoscenza base\",\n  \"Matrici\",\n  \"Matrice\",\n  \"Metodologia\",\n  \"Middleware\",\n  \"Migrazione\",\n  \"Modello\",\n  \"Moderazione\",\n  \"Monitoraggio\",\n  \"Moratoria\",\n  \"Rete\",\n  \"Architettura aperta\",\n  \"Sistema aperto\",\n  \"Orchestrazione\",\n  \"Paradigma\",\n  \"Parallelismo\",\n  \"Policy\",\n  \"Portale\",\n  \"Struttura di prezzo\",\n  \"Prodotto\",\n  \"Produttività\",\n  \"Progetto\",\n  \"Proiezione\",\n  \"Protocollo\",\n  \"Servizio clienti\",\n  \"Software\",\n  \"Soluzione\",\n  \"Standardizzazione\",\n  \"Strategia\",\n  \"Struttura\",\n  \"Successo\",\n  \"Sovrastruttura\",\n  \"Supporto\",\n  \"Sinergia\",\n  \"Task-force\",\n  \"Finestra temporale\",\n  \"Strumenti\",\n  \"Utilizzazione\",\n  \"Sito web\",\n  \"Forza lavoro\"\n];\n\n},{}],596:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"SPA\",\n  \"e figli\",\n  \"Group\",\n  \"s.r.l.\"\n];\n\n},{}],597:[function(require,module,exports){\nvar it = {};\nmodule['exports'] = it;\nit.title = \"Italian\";\nit.address = require(\"./address\");\nit.company = require(\"./company\");\nit.internet = require(\"./internet\");\nit.name = require(\"./name\");\nit.phone_number = require(\"./phone_number\");\n\n},{\"./address\":580,\"./company\":593,\"./internet\":600,\"./name\":602,\"./phone_number\":608}],598:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"com\",\n  \"com\",\n  \"net\",\n  \"org\",\n  \"it\",\n  \"it\",\n  \"it\"\n];\n\n},{}],599:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.com\",\n  \"hotmail.com\",\n  \"email.it\",\n  \"libero.it\",\n  \"yahoo.it\"\n];\n\n},{}],600:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":598,\"./free_email\":599,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],601:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aaron\",\n  \"Akira\",\n  \"Alberto\",\n  \"Alessandro\",\n  \"Alighieri\",\n  \"Amedeo\",\n  \"Amos\",\n  \"Anselmo\",\n  \"Antonino\",\n  \"Arcibaldo\",\n  \"Armando\",\n  \"Artes\",\n  \"Audenico\",\n  \"Ausonio\",\n  \"Bacchisio\",\n  \"Battista\",\n  \"Bernardo\",\n  \"Boris\",\n  \"Caio\",\n  \"Carlo\",\n  \"Cecco\",\n  \"Cirino\",\n  \"Cleros\",\n  \"Costantino\",\n  \"Damiano\",\n  \"Danny\",\n  \"Davide\",\n  \"Demian\",\n  \"Dimitri\",\n  \"Domingo\",\n  \"Dylan\",\n  \"Edilio\",\n  \"Egidio\",\n  \"Elio\",\n  \"Emanuel\",\n  \"Enrico\",\n  \"Ercole\",\n  \"Ermes\",\n  \"Ethan\",\n  \"Eusebio\",\n  \"Evangelista\",\n  \"Fabiano\",\n  \"Ferdinando\",\n  \"Fiorentino\",\n  \"Flavio\",\n  \"Fulvio\",\n  \"Gabriele\",\n  \"Gastone\",\n  \"Germano\",\n  \"Giacinto\",\n  \"Gianantonio\",\n  \"Gianleonardo\",\n  \"Gianmarco\",\n  \"Gianriccardo\",\n  \"Gioacchino\",\n  \"Giordano\",\n  \"Giuliano\",\n  \"Graziano\",\n  \"Guido\",\n  \"Harry\",\n  \"Iacopo\",\n  \"Ilario\",\n  \"Ione\",\n  \"Italo\",\n  \"Jack\",\n  \"Jari\",\n  \"Joey\",\n  \"Joseph\",\n  \"Kai\",\n  \"Kociss\",\n  \"Laerte\",\n  \"Lauro\",\n  \"Leonardo\",\n  \"Liborio\",\n  \"Lorenzo\",\n  \"Ludovico\",\n  \"Maggiore\",\n  \"Manuele\",\n  \"Mariano\",\n  \"Marvin\",\n  \"Matteo\",\n  \"Mauro\",\n  \"Michael\",\n  \"Mirco\",\n  \"Modesto\",\n  \"Muzio\",\n  \"Nabil\",\n  \"Nathan\",\n  \"Nick\",\n  \"Noah\",\n  \"Odino\",\n  \"Olo\",\n  \"Oreste\",\n  \"Osea\",\n  \"Pablo\",\n  \"Patrizio\",\n  \"Piererminio\",\n  \"Pierfrancesco\",\n  \"Piersilvio\",\n  \"Priamo\",\n  \"Quarto\",\n  \"Quirino\",\n  \"Radames\",\n  \"Raniero\",\n  \"Renato\",\n  \"Rocco\",\n  \"Romeo\",\n  \"Rosalino\",\n  \"Rudy\",\n  \"Sabatino\",\n  \"Samuel\",\n  \"Santo\",\n  \"Sebastian\",\n  \"Serse\",\n  \"Silvano\",\n  \"Sirio\",\n  \"Tancredi\",\n  \"Terzo\",\n  \"Timoteo\",\n  \"Tolomeo\",\n  \"Trevis\",\n  \"Ubaldo\",\n  \"Ulrico\",\n  \"Valdo\",\n  \"Neri\",\n  \"Vinicio\",\n  \"Walter\",\n  \"Xavier\",\n  \"Yago\",\n  \"Zaccaria\",\n  \"Abramo\",\n  \"Adriano\",\n  \"Alan\",\n  \"Albino\",\n  \"Alessio\",\n  \"Alighiero\",\n  \"Amerigo\",\n  \"Anastasio\",\n  \"Antimo\",\n  \"Antonio\",\n  \"Arduino\",\n  \"Aroldo\",\n  \"Arturo\",\n  \"Augusto\",\n  \"Avide\",\n  \"Baldassarre\",\n  \"Bettino\",\n  \"Bortolo\",\n  \"Caligola\",\n  \"Carmelo\",\n  \"Celeste\",\n  \"Ciro\",\n  \"Costanzo\",\n  \"Dante\",\n  \"Danthon\",\n  \"Davis\",\n  \"Demis\",\n  \"Dindo\",\n  \"Domiziano\",\n  \"Edipo\",\n  \"Egisto\",\n  \"Eliziario\",\n  \"Emidio\",\n  \"Enzo\",\n  \"Eriberto\",\n  \"Erminio\",\n  \"Ettore\",\n  \"Eustachio\",\n  \"Fabio\",\n  \"Fernando\",\n  \"Fiorenzo\",\n  \"Folco\",\n  \"Furio\",\n  \"Gaetano\",\n  \"Gavino\",\n  \"Gerlando\",\n  \"Giacobbe\",\n  \"Giancarlo\",\n  \"Gianmaria\",\n  \"Giobbe\",\n  \"Giorgio\",\n  \"Giulio\",\n  \"Gregorio\",\n  \"Hector\",\n  \"Ian\",\n  \"Ippolito\",\n  \"Ivano\",\n  \"Jacopo\",\n  \"Jarno\",\n  \"Joannes\",\n  \"Joshua\",\n  \"Karim\",\n  \"Kris\",\n  \"Lamberto\",\n  \"Lazzaro\",\n  \"Leone\",\n  \"Lino\",\n  \"Loris\",\n  \"Luigi\",\n  \"Manfredi\",\n  \"Marco\",\n  \"Marino\",\n  \"Marzio\",\n  \"Mattia\",\n  \"Max\",\n  \"Michele\",\n  \"Mirko\",\n  \"Moreno\",\n  \"Nadir\",\n  \"Nazzareno\",\n  \"Nestore\",\n  \"Nico\",\n  \"Noel\",\n  \"Odone\",\n  \"Omar\",\n  \"Orfeo\",\n  \"Osvaldo\",\n  \"Pacifico\",\n  \"Pericle\",\n  \"Pietro\",\n  \"Primo\",\n  \"Quasimodo\",\n  \"Radio\",\n  \"Raoul\",\n  \"Renzo\",\n  \"Rodolfo\",\n  \"Romolo\",\n  \"Rosolino\",\n  \"Rufo\",\n  \"Sabino\",\n  \"Sandro\",\n  \"Sasha\",\n  \"Secondo\",\n  \"Sesto\",\n  \"Silverio\",\n  \"Siro\",\n  \"Tazio\",\n  \"Teseo\",\n  \"Timothy\",\n  \"Tommaso\",\n  \"Tristano\",\n  \"Umberto\",\n  \"Ariel\",\n  \"Artemide\",\n  \"Assia\",\n  \"Azue\",\n  \"Benedetta\",\n  \"Bibiana\",\n  \"Brigitta\",\n  \"Carmela\",\n  \"Cassiopea\",\n  \"Cesidia\",\n  \"Cira\",\n  \"Clea\",\n  \"Cleopatra\",\n  \"Clodovea\",\n  \"Concetta\",\n  \"Cosetta\",\n  \"Cristyn\",\n  \"Damiana\",\n  \"Danuta\",\n  \"Deborah\",\n  \"Demi\",\n  \"Diamante\",\n  \"Diana\",\n  \"Donatella\",\n  \"Doriana\",\n  \"Edvige\",\n  \"Elda\",\n  \"Elga\",\n  \"Elsa\",\n  \"Emilia\",\n  \"Enrica\",\n  \"Erminia\",\n  \"Eufemia\",\n  \"Evita\",\n  \"Fatima\",\n  \"Felicia\",\n  \"Filomena\",\n  \"Flaviana\",\n  \"Fortunata\",\n  \"Gelsomina\",\n  \"Genziana\",\n  \"Giacinta\",\n  \"Gilda\",\n  \"Giovanna\",\n  \"Giulietta\",\n  \"Grazia\",\n  \"Guendalina\",\n  \"Helga\",\n  \"Ileana\",\n  \"Ingrid\",\n  \"Irene\",\n  \"Isabel\",\n  \"Isira\",\n  \"Ivonne\",\n  \"Jelena\",\n  \"Jole\",\n  \"Claudia\",\n  \"Kayla\",\n  \"Kristel\",\n  \"Laura\",\n  \"Lucia\",\n  \"Lia\",\n  \"Lidia\",\n  \"Lisa\",\n  \"Loredana\",\n  \"Loretta\",\n  \"Luce\",\n  \"Lucrezia\",\n  \"Luna\",\n  \"Maika\",\n  \"Marcella\",\n  \"Maria\",\n  \"Mariagiulia\",\n  \"Marianita\",\n  \"Mariapia\",\n  \"Marieva\",\n  \"Marina\",\n  \"Maristella\",\n  \"Maruska\",\n  \"Matilde\",\n  \"Mecren\",\n  \"Mercedes\",\n  \"Mietta\",\n  \"Miriana\",\n  \"Miriam\",\n  \"Monia\",\n  \"Morgana\",\n  \"Naomi\",\n  \"Nayade\",\n  \"Nicoletta\",\n  \"Ninfa\",\n  \"Noemi\",\n  \"Nunzia\",\n  \"Olimpia\",\n  \"Oretta\",\n  \"Ortensia\",\n  \"Penelope\",\n  \"Piccarda\",\n  \"Prisca\",\n  \"Rebecca\",\n  \"Rita\",\n  \"Rosalba\",\n  \"Rosaria\",\n  \"Rosita\",\n  \"Ruth\",\n  \"Samira\",\n  \"Sarita\",\n  \"Selvaggia\",\n  \"Shaira\",\n  \"Sibilla\",\n  \"Soriana\",\n  \"Thea\",\n  \"Tosca\",\n  \"Ursula\",\n  \"Vania\",\n  \"Vera\",\n  \"Vienna\",\n  \"Violante\",\n  \"Vitalba\",\n  \"Zelida\"\n];\n\n},{}],602:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\nname.name = require(\"./name\");\n\n},{\"./first_name\":601,\"./last_name\":603,\"./name\":604,\"./prefix\":605,\"./suffix\":606}],603:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Amato\",\n  \"Barbieri\",\n  \"Barone\",\n  \"Basile\",\n  \"Battaglia\",\n  \"Bellini\",\n  \"Benedetti\",\n  \"Bernardi\",\n  \"Bianc\",\n  \"Bianchi\",\n  \"Bruno\",\n  \"Caputo\",\n  \"Carbon\",\n  \"Caruso\",\n  \"Cattaneo\",\n  \"Colombo\",\n  \"Cont\",\n  \"Conte\",\n  \"Coppola\",\n  \"Costa\",\n  \"Costantin\",\n  \"D'amico\",\n  \"D'angelo\",\n  \"Damico\",\n  \"De Angelis\",\n  \"De luca\",\n  \"De rosa\",\n  \"De Santis\",\n  \"Donati\",\n  \"Esposito\",\n  \"Fabbri\",\n  \"Farin\",\n  \"Ferrara\",\n  \"Ferrari\",\n  \"Ferraro\",\n  \"Ferretti\",\n  \"Ferri\",\n  \"Fior\",\n  \"Fontana\",\n  \"Galli\",\n  \"Gallo\",\n  \"Gatti\",\n  \"Gentile\",\n  \"Giordano\",\n  \"Giuliani\",\n  \"Grassi\",\n  \"Grasso\",\n  \"Greco\",\n  \"Guerra\",\n  \"Leone\",\n  \"Lombardi\",\n  \"Lombardo\",\n  \"Longo\",\n  \"Mancini\",\n  \"Marchetti\",\n  \"Marian\",\n  \"Marini\",\n  \"Marino\",\n  \"Martinelli\",\n  \"Martini\",\n  \"Martino\",\n  \"Mazza\",\n  \"Messina\",\n  \"Milani\",\n  \"Montanari\",\n  \"Monti\",\n  \"Morelli\",\n  \"Moretti\",\n  \"Negri\",\n  \"Neri\",\n  \"Orlando\",\n  \"Pagano\",\n  \"Palmieri\",\n  \"Palumbo\",\n  \"Parisi\",\n  \"Pellegrini\",\n  \"Pellegrino\",\n  \"Piras\",\n  \"Ricci\",\n  \"Rinaldi\",\n  \"Riva\",\n  \"Rizzi\",\n  \"Rizzo\",\n  \"Romano\",\n  \"Ross\",\n  \"Rossetti\",\n  \"Ruggiero\",\n  \"Russo\",\n  \"Sala\",\n  \"Sanna\",\n  \"Santoro\",\n  \"Sartori\",\n  \"Serr\",\n  \"Silvestri\",\n  \"Sorrentino\",\n  \"Testa\",\n  \"Valentini\",\n  \"Villa\",\n  \"Vitale\",\n  \"Vitali\"\n];\n\n},{}],604:[function(require,module,exports){\nmodule.exports=require(538)\n},{\"/Users/a/dev/faker.js/lib/locales/ge/name/name.js\":538}],605:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Sig.\",\n  \"Dott.\",\n  \"Dr.\",\n  \"Ing.\"\n];\n\n},{}],606:[function(require,module,exports){\nmodule.exports=require(50)\n},{\"/Users/a/dev/faker.js/lib/locales/az/name/prefix.js\":50}],607:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"+## ### ## ## ####\",\n  \"+## ## #######\",\n  \"+## ## ########\",\n  \"+## ### #######\",\n  \"+## ### ########\",\n  \"+## #### #######\",\n  \"+## #### ########\",\n  \"0## ### ####\",\n  \"+39 0## ### ###\",\n  \"3## ### ###\",\n  \"+39 3## ### ###\"\n];\n\n},{}],608:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":607,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],609:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_prefix}#{Name.first_name}#{city_suffix}\",\n  \"#{Name.first_name}#{city_suffix}\",\n  \"#{city_prefix}#{Name.last_name}#{city_suffix}\",\n  \"#{Name.last_name}#{city_suffix}\"\n];\n\n},{}],610:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"北\",\n  \"東\",\n  \"西\",\n  \"南\",\n  \"新\",\n  \"湖\",\n  \"港\"\n];\n\n},{}],611:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"市\",\n  \"区\",\n  \"町\",\n  \"村\"\n];\n\n},{}],612:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\n\n},{\"./city\":609,\"./city_prefix\":610,\"./city_suffix\":611,\"./postcode\":613,\"./state\":614,\"./state_abbr\":615,\"./street_name\":616}],613:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###-####\"\n];\n\n},{}],614:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"大阪府\",\n  \"兵庫県\",\n  \"奈良県\",\n  \"和歌山県\",\n  \"鳥取県\",\n  \"島根県\",\n  \"岡山県\",\n  \"広島県\",\n  \"山口県\",\n  \"徳島県\",\n  \"香川県\",\n  \"愛媛県\",\n  \"高知県\",\n  \"福岡県\",\n  \"佐賀県\",\n  \"長崎県\",\n  \"熊本県\",\n  \"大分県\",\n  \"宮崎県\",\n  \"鹿児島県\",\n  \"沖縄県\"\n];\n\n},{}],615:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"1\",\n  \"2\",\n  \"3\",\n  \"4\",\n  \"5\",\n  \"6\",\n  \"7\",\n  \"8\",\n  \"9\",\n  \"10\",\n  \"11\",\n  \"12\",\n  \"13\",\n  \"14\",\n  \"15\",\n  \"16\",\n  \"17\",\n  \"18\",\n  \"19\",\n  \"20\",\n  \"21\",\n  \"22\",\n  \"23\",\n  \"24\",\n  \"25\",\n  \"26\",\n  \"27\",\n  \"28\",\n  \"29\",\n  \"30\",\n  \"31\",\n  \"32\",\n  \"33\",\n  \"34\",\n  \"35\",\n  \"36\",\n  \"37\",\n  \"38\",\n  \"39\",\n  \"40\",\n  \"41\",\n  \"42\",\n  \"43\",\n  \"44\",\n  \"45\",\n  \"46\",\n  \"47\"\n];\n\n},{}],616:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.first_name}#{street_suffix}\",\n  \"#{Name.last_name}#{street_suffix}\"\n];\n\n},{}],617:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"090-####-####\",\n  \"080-####-####\",\n  \"070-####-####\"\n];\n\n},{}],618:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":617,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],619:[function(require,module,exports){\nvar ja = {};\nmodule['exports'] = ja;\nja.title = \"Japanese\";\nja.address = require(\"./address\");\nja.phone_number = require(\"./phone_number\");\nja.cell_phone = require(\"./cell_phone\");\nja.name = require(\"./name\");\n\n},{\"./address\":612,\"./cell_phone\":618,\"./name\":621,\"./phone_number\":625}],620:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"大翔\",\n  \"蓮\",\n  \"颯太\",\n  \"樹\",\n  \"大和\",\n  \"陽翔\",\n  \"陸斗\",\n  \"太一\",\n  \"海翔\",\n  \"蒼空\",\n  \"翼\",\n  \"陽菜\",\n  \"結愛\",\n  \"結衣\",\n  \"杏\",\n  \"莉子\",\n  \"美羽\",\n  \"結菜\",\n  \"心愛\",\n  \"愛菜\",\n  \"美咲\"\n];\n\n},{}],621:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.last_name = require(\"./last_name\");\nname.first_name = require(\"./first_name\");\nname.name = require(\"./name\");\n\n},{\"./first_name\":620,\"./last_name\":622,\"./name\":623}],622:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"佐藤\",\n  \"鈴木\",\n  \"高橋\",\n  \"田中\",\n  \"渡辺\",\n  \"伊藤\",\n  \"山本\",\n  \"中村\",\n  \"小林\",\n  \"加藤\",\n  \"吉田\",\n  \"山田\",\n  \"佐々木\",\n  \"山口\",\n  \"斎藤\",\n  \"松本\",\n  \"井上\",\n  \"木村\",\n  \"林\",\n  \"清水\"\n];\n\n},{}],623:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{last_name} #{first_name}\"\n];\n\n},{}],624:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"0####-#-####\",\n  \"0###-##-####\",\n  \"0##-###-####\",\n  \"0#-####-####\"\n];\n\n},{}],625:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":624,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],626:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_name}#{city_suffix}\"\n];\n\n},{}],627:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"강화\",\n  \"수성\"\n];\n\n},{}],628:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"구\",\n  \"시\",\n  \"군\"\n];\n\n},{}],629:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.street_root = require(\"./street_root\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.street_name = require(\"./street_name\");\n\n},{\"./city\":626,\"./city_name\":627,\"./city_suffix\":628,\"./postcode\":630,\"./state\":631,\"./state_abbr\":632,\"./street_name\":633,\"./street_root\":634,\"./street_suffix\":635}],630:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###-###\"\n];\n\n},{}],631:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"강원\",\n  \"경기\",\n  \"경남\",\n  \"경북\",\n  \"광주\",\n  \"대구\",\n  \"대전\",\n  \"부산\",\n  \"서울\",\n  \"울산\",\n  \"인천\",\n  \"전남\",\n  \"전북\",\n  \"제주\",\n  \"충남\",\n  \"충북\",\n  \"세종\"\n];\n\n},{}],632:[function(require,module,exports){\nmodule.exports=require(631)\n},{\"/Users/a/dev/faker.js/lib/locales/ko/address/state.js\":631}],633:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_root}#{street_suffix}\"\n];\n\n},{}],634:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"대명\",\n  \"동탄\"\n];\n\n},{}],635:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"읍\",\n  \"면\",\n  \"동\"\n];\n\n},{}],636:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.prefix = require(\"./prefix\");\ncompany.name = require(\"./name\");\n\n},{\"./name\":637,\"./prefix\":638,\"./suffix\":639}],637:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{Name.first_name}\",\n  \"#{Name.first_name} #{suffix}\"\n];\n\n},{}],638:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"주식회사\",\n  \"한국\"\n];\n\n},{}],639:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"연구소\",\n  \"게임즈\",\n  \"그룹\",\n  \"전자\",\n  \"물산\",\n  \"코리아\"\n];\n\n},{}],640:[function(require,module,exports){\nvar ko = {};\nmodule['exports'] = ko;\nko.title = \"Korean\";\nko.address = require(\"./address\");\nko.phone_number = require(\"./phone_number\");\nko.company = require(\"./company\");\nko.internet = require(\"./internet\");\nko.lorem = require(\"./lorem\");\nko.name = require(\"./name\");\n\n},{\"./address\":629,\"./company\":636,\"./internet\":643,\"./lorem\":644,\"./name\":647,\"./phone_number\":651}],641:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"co.kr\",\n  \"com\",\n  \"biz\",\n  \"info\",\n  \"ne.kr\",\n  \"net\",\n  \"or.kr\",\n  \"org\"\n];\n\n},{}],642:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.co.kr\",\n  \"hanmail.net\",\n  \"naver.com\"\n];\n\n},{}],643:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":641,\"./free_email\":642,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],644:[function(require,module,exports){\narguments[4][121][0].apply(exports,arguments)\n},{\"./words\":645,\"/Users/a/dev/faker.js/lib/locales/de/lorem/index.js\":121}],645:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"위하여\",\n  \"필요한\",\n  \"사항은\",\n  \"법률로\",\n  \"정한다.\",\n  \"헌법에\",\n  \"의하여\",\n  \"체결·공포된\",\n  \"조약과\",\n  \"일반적으로\",\n  \"승인된\",\n  \"국제법규는\",\n  \"국내법과\",\n  \"같은\",\n  \"효력을\",\n  \"가진다.\",\n  \"다만,\",\n  \"현행범인인\",\n  \"경우와\",\n  \"장기\",\n  \"3년\",\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  \"무죄로\",\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  \"자유를\",\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  \"가진다.\"\n];\n\n},{}],646:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"서연\",\n  \"민서\",\n  \"서현\",\n  \"지우\",\n  \"서윤\",\n  \"지민\",\n  \"수빈\",\n  \"하은\",\n  \"예은\",\n  \"윤서\",\n  \"민준\",\n  \"지후\",\n  \"지훈\",\n  \"준서\",\n  \"현우\",\n  \"예준\",\n  \"건우\",\n  \"현준\",\n  \"민재\",\n  \"우진\",\n  \"은주\"\n];\n\n},{}],647:[function(require,module,exports){\narguments[4][621][0].apply(exports,arguments)\n},{\"./first_name\":646,\"./last_name\":648,\"./name\":649,\"/Users/a/dev/faker.js/lib/locales/ja/name/index.js\":621}],648:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"김\",\n  \"이\",\n  \"박\",\n  \"최\",\n  \"정\",\n  \"강\",\n  \"조\",\n  \"윤\",\n  \"장\",\n  \"임\",\n  \"오\",\n  \"한\",\n  \"신\",\n  \"서\",\n  \"권\",\n  \"황\",\n  \"안\",\n  \"송\",\n  \"류\",\n  \"홍\"\n];\n\n},{}],649:[function(require,module,exports){\nmodule.exports=require(623)\n},{\"/Users/a/dev/faker.js/lib/locales/ja/name/name.js\":623}],650:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"0#-#####-####\",\n  \"0##-###-####\",\n  \"0##-####-####\"\n];\n\n},{}],651:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":650,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],652:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#\",\n  \"##\"\n];\n\n},{}],653:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_root}#{city_suffix}\"\n];\n\n},{}],654:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Fet\",\n  \"Gjes\",\n  \"Høy\",\n  \"Inn\",\n  \"Fager\",\n  \"Lille\",\n  \"Lo\",\n  \"Mal\",\n  \"Nord\",\n  \"Nær\",\n  \"Sand\",\n  \"Sme\",\n  \"Stav\",\n  \"Stor\",\n  \"Tand\",\n  \"Ut\",\n  \"Vest\"\n];\n\n},{}],655:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"berg\",\n  \"borg\",\n  \"by\",\n  \"bø\",\n  \"dal\",\n  \"eid\",\n  \"fjell\",\n  \"fjord\",\n  \"foss\",\n  \"grunn\",\n  \"hamn\",\n  \"havn\",\n  \"helle\",\n  \"mark\",\n  \"nes\",\n  \"odden\",\n  \"sand\",\n  \"sjøen\",\n  \"stad\",\n  \"strand\",\n  \"strøm\",\n  \"sund\",\n  \"vik\",\n  \"vær\",\n  \"våg\",\n  \"ø\",\n  \"øy\",\n  \"ås\"\n];\n\n},{}],656:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"sgate\",\n  \"svei\",\n  \"s Gate\",\n  \"s Vei\",\n  \"gata\",\n  \"veien\"\n];\n\n},{}],657:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Norge\"\n];\n\n},{}],658:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_root = require(\"./city_root\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.street_prefix = require(\"./street_prefix\");\naddress.street_root = require(\"./street_root\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.common_street_suffix = require(\"./common_street_suffix\");\naddress.building_number = require(\"./building_number\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":652,\"./city\":653,\"./city_root\":654,\"./city_suffix\":655,\"./common_street_suffix\":656,\"./default_country\":657,\"./postcode\":659,\"./secondary_address\":660,\"./state\":661,\"./street_address\":662,\"./street_name\":663,\"./street_prefix\":664,\"./street_root\":665,\"./street_suffix\":666}],659:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"####\",\n  \"####\",\n  \"####\",\n  \"0###\"\n];\n\n},{}],660:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Leil. ###\",\n  \"Oppgang A\",\n  \"Oppgang B\"\n];\n\n},{}],661:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"\"\n];\n\n},{}],662:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],663:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_root}#{street_suffix}\",\n  \"#{street_prefix} #{street_root}#{street_suffix}\",\n  \"#{Name.first_name}#{common_street_suffix}\",\n  \"#{Name.last_name}#{common_street_suffix}\"\n];\n\n},{}],664:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Øvre\",\n  \"Nedre\",\n  \"Søndre\",\n  \"Gamle\",\n  \"Østre\",\n  \"Vestre\"\n];\n\n},{}],665:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Eike\",\n  \"Bjørke\",\n  \"Gran\",\n  \"Vass\",\n  \"Furu\",\n  \"Litj\",\n  \"Lille\",\n  \"Høy\",\n  \"Fosse\",\n  \"Elve\",\n  \"Ku\",\n  \"Konvall\",\n  \"Soldugg\",\n  \"Hestemyr\",\n  \"Granitt\",\n  \"Hegge\",\n  \"Rogne\",\n  \"Fiol\",\n  \"Sol\",\n  \"Ting\",\n  \"Malm\",\n  \"Klokker\",\n  \"Preste\",\n  \"Dam\",\n  \"Geiterygg\",\n  \"Bekke\",\n  \"Berg\",\n  \"Kirke\",\n  \"Kors\",\n  \"Bru\",\n  \"Blåveis\",\n  \"Torg\",\n  \"Sjø\"\n];\n\n},{}],666:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"alléen\",\n  \"bakken\",\n  \"berget\",\n  \"bråten\",\n  \"eggen\",\n  \"engen\",\n  \"ekra\",\n  \"faret\",\n  \"flata\",\n  \"gata\",\n  \"gjerdet\",\n  \"grenda\",\n  \"gropa\",\n  \"hagen\",\n  \"haugen\",\n  \"havna\",\n  \"holtet\",\n  \"høgda\",\n  \"jordet\",\n  \"kollen\",\n  \"kroken\",\n  \"lia\",\n  \"lunden\",\n  \"lyngen\",\n  \"løkka\",\n  \"marka\",\n  \"moen\",\n  \"myra\",\n  \"plassen\",\n  \"ringen\",\n  \"roa\",\n  \"røa\",\n  \"skogen\",\n  \"skrenten\",\n  \"spranget\",\n  \"stien\",\n  \"stranda\",\n  \"stubben\",\n  \"stykket\",\n  \"svingen\",\n  \"tjernet\",\n  \"toppen\",\n  \"tunet\",\n  \"vollen\",\n  \"vika\",\n  \"åsen\"\n];\n\n},{}],667:[function(require,module,exports){\narguments[4][166][0].apply(exports,arguments)\n},{\"./name\":668,\"./suffix\":669,\"/Users/a/dev/faker.js/lib/locales/de_CH/company/index.js\":166}],668:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name}-#{Name.last_name}\",\n  \"#{Name.last_name}, #{Name.last_name} og #{Name.last_name}\"\n];\n\n},{}],669:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Gruppen\",\n  \"AS\",\n  \"ASA\",\n  \"BA\",\n  \"RFH\",\n  \"og Sønner\"\n];\n\n},{}],670:[function(require,module,exports){\nvar nb_NO = {};\nmodule['exports'] = nb_NO;\nnb_NO.title = \"Norwegian\";\nnb_NO.address = require(\"./address\");\nnb_NO.company = require(\"./company\");\nnb_NO.internet = require(\"./internet\");\nnb_NO.name = require(\"./name\");\nnb_NO.phone_number = require(\"./phone_number\");\n\n},{\"./address\":658,\"./company\":667,\"./internet\":672,\"./name\":675,\"./phone_number\":682}],671:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"no\",\n  \"com\",\n  \"net\",\n  \"org\"\n];\n\n},{}],672:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":671,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],673:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Emma\",\n  \"Sara\",\n  \"Thea\",\n  \"Ida\",\n  \"Julie\",\n  \"Nora\",\n  \"Emilie\",\n  \"Ingrid\",\n  \"Hanna\",\n  \"Maria\",\n  \"Sofie\",\n  \"Anna\",\n  \"Malin\",\n  \"Amalie\",\n  \"Vilde\",\n  \"Frida\",\n  \"Andrea\",\n  \"Tuva\",\n  \"Victoria\",\n  \"Mia\",\n  \"Karoline\",\n  \"Mathilde\",\n  \"Martine\",\n  \"Linnea\",\n  \"Marte\",\n  \"Hedda\",\n  \"Marie\",\n  \"Helene\",\n  \"Silje\",\n  \"Leah\",\n  \"Maja\",\n  \"Elise\",\n  \"Oda\",\n  \"Kristine\",\n  \"Aurora\",\n  \"Kaja\",\n  \"Camilla\",\n  \"Mari\",\n  \"Maren\",\n  \"Mina\",\n  \"Selma\",\n  \"Jenny\",\n  \"Celine\",\n  \"Eline\",\n  \"Sunniva\",\n  \"Natalie\",\n  \"Tiril\",\n  \"Synne\",\n  \"Sandra\",\n  \"Madeleine\"\n];\n\n},{}],674:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Emma\",\n  \"Sara\",\n  \"Thea\",\n  \"Ida\",\n  \"Julie\",\n  \"Nora\",\n  \"Emilie\",\n  \"Ingrid\",\n  \"Hanna\",\n  \"Maria\",\n  \"Sofie\",\n  \"Anna\",\n  \"Malin\",\n  \"Amalie\",\n  \"Vilde\",\n  \"Frida\",\n  \"Andrea\",\n  \"Tuva\",\n  \"Victoria\",\n  \"Mia\",\n  \"Karoline\",\n  \"Mathilde\",\n  \"Martine\",\n  \"Linnea\",\n  \"Marte\",\n  \"Hedda\",\n  \"Marie\",\n  \"Helene\",\n  \"Silje\",\n  \"Leah\",\n  \"Maja\",\n  \"Elise\",\n  \"Oda\",\n  \"Kristine\",\n  \"Aurora\",\n  \"Kaja\",\n  \"Camilla\",\n  \"Mari\",\n  \"Maren\",\n  \"Mina\",\n  \"Selma\",\n  \"Jenny\",\n  \"Celine\",\n  \"Eline\",\n  \"Sunniva\",\n  \"Natalie\",\n  \"Tiril\",\n  \"Synne\",\n  \"Sandra\",\n  \"Madeleine\",\n  \"Markus\",\n  \"Mathias\",\n  \"Kristian\",\n  \"Jonas\",\n  \"Andreas\",\n  \"Alexander\",\n  \"Martin\",\n  \"Sander\",\n  \"Daniel\",\n  \"Magnus\",\n  \"Henrik\",\n  \"Tobias\",\n  \"Kristoffer\",\n  \"Emil\",\n  \"Adrian\",\n  \"Sebastian\",\n  \"Marius\",\n  \"Elias\",\n  \"Fredrik\",\n  \"Thomas\",\n  \"Sondre\",\n  \"Benjamin\",\n  \"Jakob\",\n  \"Oliver\",\n  \"Lucas\",\n  \"Oskar\",\n  \"Nikolai\",\n  \"Filip\",\n  \"Mats\",\n  \"William\",\n  \"Erik\",\n  \"Simen\",\n  \"Ole\",\n  \"Eirik\",\n  \"Isak\",\n  \"Kasper\",\n  \"Noah\",\n  \"Lars\",\n  \"Joakim\",\n  \"Johannes\",\n  \"Håkon\",\n  \"Sindre\",\n  \"Jørgen\",\n  \"Herman\",\n  \"Anders\",\n  \"Jonathan\",\n  \"Even\",\n  \"Theodor\",\n  \"Mikkel\",\n  \"Aksel\"\n];\n\n},{}],675:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.feminine_name = require(\"./feminine_name\");\nname.masculine_name = require(\"./masculine_name\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\nname.name = require(\"./name\");\n\n},{\"./feminine_name\":673,\"./first_name\":674,\"./last_name\":676,\"./masculine_name\":677,\"./name\":678,\"./prefix\":679,\"./suffix\":680}],676:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Johansen\",\n  \"Hansen\",\n  \"Andersen\",\n  \"Kristiansen\",\n  \"Larsen\",\n  \"Olsen\",\n  \"Solberg\",\n  \"Andresen\",\n  \"Pedersen\",\n  \"Nilsen\",\n  \"Berg\",\n  \"Halvorsen\",\n  \"Karlsen\",\n  \"Svendsen\",\n  \"Jensen\",\n  \"Haugen\",\n  \"Martinsen\",\n  \"Eriksen\",\n  \"Sørensen\",\n  \"Johnsen\",\n  \"Myhrer\",\n  \"Johannessen\",\n  \"Nielsen\",\n  \"Hagen\",\n  \"Pettersen\",\n  \"Bakke\",\n  \"Skuterud\",\n  \"Løken\",\n  \"Gundersen\",\n  \"Strand\",\n  \"Jørgensen\",\n  \"Kvarme\",\n  \"Røed\",\n  \"Sæther\",\n  \"Stensrud\",\n  \"Moe\",\n  \"Kristoffersen\",\n  \"Jakobsen\",\n  \"Holm\",\n  \"Aas\",\n  \"Lie\",\n  \"Moen\",\n  \"Andreassen\",\n  \"Vedvik\",\n  \"Nguyen\",\n  \"Jacobsen\",\n  \"Torgersen\",\n  \"Ruud\",\n  \"Krogh\",\n  \"Christiansen\",\n  \"Bjerke\",\n  \"Aalerud\",\n  \"Borge\",\n  \"Sørlie\",\n  \"Berge\",\n  \"Østli\",\n  \"Ødegård\",\n  \"Torp\",\n  \"Henriksen\",\n  \"Haukelidsæter\",\n  \"Fjeld\",\n  \"Danielsen\",\n  \"Aasen\",\n  \"Fredriksen\",\n  \"Dahl\",\n  \"Berntsen\",\n  \"Arnesen\",\n  \"Wold\",\n  \"Thoresen\",\n  \"Solheim\",\n  \"Skoglund\",\n  \"Bakken\",\n  \"Amundsen\",\n  \"Solli\",\n  \"Smogeli\",\n  \"Kristensen\",\n  \"Glosli\",\n  \"Fossum\",\n  \"Evensen\",\n  \"Eide\",\n  \"Carlsen\",\n  \"Østby\",\n  \"Vegge\",\n  \"Tangen\",\n  \"Smedsrud\",\n  \"Olstad\",\n  \"Lunde\",\n  \"Kleven\",\n  \"Huseby\",\n  \"Bjørnstad\",\n  \"Ryan\",\n  \"Rasmussen\",\n  \"Nygård\",\n  \"Nordskaug\",\n  \"Nordby\",\n  \"Mathisen\",\n  \"Hopland\",\n  \"Gran\",\n  \"Finstad\",\n  \"Edvardsen\"\n];\n\n},{}],677:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Markus\",\n  \"Mathias\",\n  \"Kristian\",\n  \"Jonas\",\n  \"Andreas\",\n  \"Alexander\",\n  \"Martin\",\n  \"Sander\",\n  \"Daniel\",\n  \"Magnus\",\n  \"Henrik\",\n  \"Tobias\",\n  \"Kristoffer\",\n  \"Emil\",\n  \"Adrian\",\n  \"Sebastian\",\n  \"Marius\",\n  \"Elias\",\n  \"Fredrik\",\n  \"Thomas\",\n  \"Sondre\",\n  \"Benjamin\",\n  \"Jakob\",\n  \"Oliver\",\n  \"Lucas\",\n  \"Oskar\",\n  \"Nikolai\",\n  \"Filip\",\n  \"Mats\",\n  \"William\",\n  \"Erik\",\n  \"Simen\",\n  \"Ole\",\n  \"Eirik\",\n  \"Isak\",\n  \"Kasper\",\n  \"Noah\",\n  \"Lars\",\n  \"Joakim\",\n  \"Johannes\",\n  \"Håkon\",\n  \"Sindre\",\n  \"Jørgen\",\n  \"Herman\",\n  \"Anders\",\n  \"Jonathan\",\n  \"Even\",\n  \"Theodor\",\n  \"Mikkel\",\n  \"Aksel\"\n];\n\n},{}],678:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{first_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{suffix}\",\n  \"#{feminine_name} #{feminine_name} #{last_name}\",\n  \"#{masculine_name} #{masculine_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name}\"\n];\n\n},{}],679:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Dr.\",\n  \"Prof.\"\n];\n\n},{}],680:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Jr.\",\n  \"Sr.\",\n  \"I\",\n  \"II\",\n  \"III\",\n  \"IV\",\n  \"V\"\n];\n\n},{}],681:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"########\",\n  \"## ## ## ##\",\n  \"### ## ###\",\n  \"+47 ## ## ## ##\"\n];\n\n},{}],682:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":681,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],683:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Bhaktapur\",\n  \"Biratnagar\",\n  \"Birendranagar\",\n  \"Birgunj\",\n  \"Butwal\",\n  \"Damak\",\n  \"Dharan\",\n  \"Gaur\",\n  \"Gorkha\",\n  \"Hetauda\",\n  \"Itahari\",\n  \"Janakpur\",\n  \"Kathmandu\",\n  \"Lahan\",\n  \"Nepalgunj\",\n  \"Pokhara\"\n];\n\n},{}],684:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Nepal\"\n];\n\n},{}],685:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.city = require(\"./city\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./city\":683,\"./default_country\":684,\"./postcode\":686,\"./state\":687}],686:[function(require,module,exports){\nmodule[\"exports\"] = [\n  0\n];\n\n},{}],687:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Baglung\",\n  \"Banke\",\n  \"Bara\",\n  \"Bardiya\",\n  \"Bhaktapur\",\n  \"Bhojupu\",\n  \"Chitwan\",\n  \"Dailekh\",\n  \"Dang\",\n  \"Dhading\",\n  \"Dhankuta\",\n  \"Dhanusa\",\n  \"Dolakha\",\n  \"Dolpha\",\n  \"Gorkha\",\n  \"Gulmi\",\n  \"Humla\",\n  \"Ilam\",\n  \"Jajarkot\",\n  \"Jhapa\",\n  \"Jumla\",\n  \"Kabhrepalanchok\",\n  \"Kalikot\",\n  \"Kapilvastu\",\n  \"Kaski\",\n  \"Kathmandu\",\n  \"Lalitpur\",\n  \"Lamjung\",\n  \"Manang\",\n  \"Mohottari\",\n  \"Morang\",\n  \"Mugu\",\n  \"Mustang\",\n  \"Myagdi\",\n  \"Nawalparasi\",\n  \"Nuwakot\",\n  \"Palpa\",\n  \"Parbat\",\n  \"Parsa\",\n  \"Ramechhap\",\n  \"Rauswa\",\n  \"Rautahat\",\n  \"Rolpa\",\n  \"Rupandehi\",\n  \"Sankhuwasabha\",\n  \"Sarlahi\",\n  \"Sindhuli\",\n  \"Sindhupalchok\",\n  \"Sunsari\",\n  \"Surket\",\n  \"Syangja\",\n  \"Tanahu\",\n  \"Terhathum\"\n];\n\n},{}],688:[function(require,module,exports){\narguments[4][279][0].apply(exports,arguments)\n},{\"./suffix\":689,\"/Users/a/dev/faker.js/lib/locales/en_AU/company/index.js\":279}],689:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Pvt Ltd\",\n  \"Group\",\n  \"Ltd\",\n  \"Limited\"\n];\n\n},{}],690:[function(require,module,exports){\nvar nep = {};\nmodule['exports'] = nep;\nnep.title = \"Nepalese\";\nnep.name = require(\"./name\");\nnep.address = require(\"./address\");\nnep.internet = require(\"./internet\");\nnep.company = require(\"./company\");\nnep.phone_number = require(\"./phone_number\");\n\n},{\"./address\":685,\"./company\":688,\"./internet\":693,\"./name\":695,\"./phone_number\":698}],691:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"np\",\n  \"com\",\n  \"info\",\n  \"net\",\n  \"org\"\n];\n\n},{}],692:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"worldlink.com.np\",\n  \"gmail.com\",\n  \"yahoo.com\",\n  \"hotmail.com\"\n];\n\n},{}],693:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":691,\"./free_email\":692,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],694:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aarav\",\n  \"Ajita\",\n  \"Amit\",\n  \"Amita\",\n  \"Amrit\",\n  \"Arijit\",\n  \"Ashmi\",\n  \"Asmita\",\n  \"Bibek\",\n  \"Bijay\",\n  \"Bikash\",\n  \"Bina\",\n  \"Bishal\",\n  \"Bishnu\",\n  \"Buddha\",\n  \"Deepika\",\n  \"Dipendra\",\n  \"Gagan\",\n  \"Ganesh\",\n  \"Khem\",\n  \"Krishna\",\n  \"Laxmi\",\n  \"Manisha\",\n  \"Nabin\",\n  \"Nikita\",\n  \"Niraj\",\n  \"Nischal\",\n  \"Padam\",\n  \"Pooja\",\n  \"Prabin\",\n  \"Prakash\",\n  \"Prashant\",\n  \"Prem\",\n  \"Purna\",\n  \"Rajendra\",\n  \"Rajina\",\n  \"Raju\",\n  \"Rakesh\",\n  \"Ranjan\",\n  \"Ratna\",\n  \"Sagar\",\n  \"Sandeep\",\n  \"Sanjay\",\n  \"Santosh\",\n  \"Sarita\",\n  \"Shilpa\",\n  \"Shirisha\",\n  \"Shristi\",\n  \"Siddhartha\",\n  \"Subash\",\n  \"Sumeet\",\n  \"Sunita\",\n  \"Suraj\",\n  \"Susan\",\n  \"Sushant\"\n];\n\n},{}],695:[function(require,module,exports){\narguments[4][285][0].apply(exports,arguments)\n},{\"./first_name\":694,\"./last_name\":696,\"/Users/a/dev/faker.js/lib/locales/en_AU/name/index.js\":285}],696:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adhikari\",\n  \"Aryal\",\n  \"Baral\",\n  \"Basnet\",\n  \"Bastola\",\n  \"Basynat\",\n  \"Bhandari\",\n  \"Bhattarai\",\n  \"Chettri\",\n  \"Devkota\",\n  \"Dhakal\",\n  \"Dongol\",\n  \"Ghale\",\n  \"Gurung\",\n  \"Gyawali\",\n  \"Hamal\",\n  \"Jung\",\n  \"KC\",\n  \"Kafle\",\n  \"Karki\",\n  \"Khadka\",\n  \"Koirala\",\n  \"Lama\",\n  \"Limbu\",\n  \"Magar\",\n  \"Maharjan\",\n  \"Niroula\",\n  \"Pandey\",\n  \"Pradhan\",\n  \"Rana\",\n  \"Raut\",\n  \"Sai\",\n  \"Shai\",\n  \"Shakya\",\n  \"Sherpa\",\n  \"Shrestha\",\n  \"Subedi\",\n  \"Tamang\",\n  \"Thapa\"\n];\n\n},{}],697:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"##-#######\",\n  \"+977-#-#######\",\n  \"+977########\"\n];\n\n},{}],698:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":697,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],699:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#\",\n  \"##\",\n  \"###\",\n  \"###a\",\n  \"###b\",\n  \"###c\",\n  \"### I\",\n  \"### II\",\n  \"### III\"\n];\n\n},{}],700:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_prefix}#{city_suffix}\",\n  \"#{city_prefix}\"\n];\n\n},{}],701:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aagte\",\n  \"Aal\",\n  \"Aalden\",\n  \"Aals\",\n  \"Aalst\",\n  \"Aalsum\",\n  \"Aanschot\",\n  \"Aarden\",\n  \"Aarle\",\n  \"Abbe\",\n  \"Abbegea\",\n  \"Abben\",\n  \"Abbestede\",\n  \"Abcoven\",\n  \"Absdale\",\n  \"Abts\",\n  \"Acht\",\n  \"Achter\",\n  \"Achterste\",\n  \"Achtmaal\",\n  \"Achttien\",\n  \"Acquoy\",\n  \"Aduard\",\n  \"Aduarder\",\n  \"Aekinga\",\n  \"Aerde\",\n  \"Aerden\",\n  \"Aerdt\",\n  \"Afferden\",\n  \"Aijen\",\n  \"Akersloot\",\n  \"Akker\",\n  \"Akkerput\",\n  \"Akkrun\",\n  \"Akmarijp\",\n  \"Aldeboarn\",\n  \"Aldegae\",\n  \"Aldtsjerk\",\n  \"Aling\",\n  \"Alkmaar\",\n  \"Allersma\",\n  \"Allinga\",\n  \"Almere\",\n  \"Alphen\",\n  \"Altena\",\n  \"Alteveer\",\n  \"Alting\",\n  \"Altweert\",\n  \"Alverna\",\n  \"Ameide\",\n  \"Amerika\",\n  \"Amerongen\",\n  \"Ammerstol\",\n  \"Ams\",\n  \"Amster\",\n  \"Andel\",\n  \"Angeren\",\n  \"Anholt\",\n  \"Anjum\",\n  \"Anke\",\n  \"Ankum\",\n  \"Anna\",\n  \"Annendaal\",\n  \"Anneville\",\n  \"Anreep\",\n  \"Ansen\",\n  \"Apeldoorn\",\n  \"Apen\",\n  \"Appel\",\n  \"Appen\",\n  \"Arcen\",\n  \"Archem\",\n  \"Arendnest\",\n  \"Arensge\",\n  \"Arkens\",\n  \"Armweide\",\n  \"Arnhem\",\n  \"Arnoud\",\n  \"Arriën\",\n  \"Arriër\",\n  \"Arum\",\n  \"Arwerd\",\n  \"Asch\",\n  \"Asenray\",\n  \"Asperen\",\n  \"Asschat\",\n  \"Assel\",\n  \"Asselt\",\n  \"Assen\",\n  \"Asten\",\n  \"Atze\",\n  \"Augs\",\n  \"Averlo\",\n  \"Avest\",\n  \"Azelo\",\n  \"Azewijn\",\n  \"Ba\",\n  \"Baaium\",\n  \"Baak\",\n  \"Baaks\",\n  \"Baal\",\n  \"Baamsum\",\n  \"Baan\",\n  \"Baard\",\n  \"Baarder\",\n  \"Baarle\",\n  \"Baarlo\",\n  \"Baars\",\n  \"Baarschot\",\n  \"Baexem\",\n  \"Baflo\",\n  \"Bahr\",\n  \"Bakel\",\n  \"Bakelse\",\n  \"Bakertand\",\n  \"Bakke\",\n  \"Bakkerom\",\n  \"Balgoij\",\n  \"Balinge\",\n  \"Ballast\",\n  \"Balleman\",\n  \"Ballum\",\n  \"Balma\",\n  \"Bane\",\n  \"Bankert\",\n  \"Bantega\",\n  \"Bare\",\n  \"Bargebek\",\n  \"Barlage\",\n  \"Barlaque\",\n  \"Barlo\",\n  \"Barnflair\",\n  \"Barrier\",\n  \"Bars\",\n  \"Basse\",\n  \"Basser\",\n  \"Baten\",\n  \"Bath\",\n  \"Bathmen\",\n  \"Bavinkel\",\n  \"Bazuin\",\n  \"Bears\",\n  \"Beckum\",\n  \"Bedaf\",\n  \"Bedum\",\n  \"Beekb\",\n  \"Beekkant\",\n  \"Beemdkant\",\n  \"Beemte\",\n  \"Beertsen\",\n  \"Beerze\",\n  \"Beerzer\",\n  \"Beesd\",\n  \"Beetgum\",\n  \"Beetgumer\",\n  \"Behelp\",\n  \"Beilen\",\n  \"Beinum\",\n  \"Beke\",\n  \"Beldert\",\n  \"Belgen\",\n  \"Belgeren\",\n  \"Belt\",\n  \"Belvert\",\n  \"Bemmel\",\n  \"Bemmer\",\n  \"Benderse\",\n  \"Beneden\",\n  \"Benne\",\n  \"Bennekom\",\n  \"Bent\",\n  \"Bente\",\n  \"Benthem\",\n  \"Berg\",\n  \"Bergakker\",\n  \"Bergen\",\n  \"Bergens\",\n  \"Bergerden\",\n  \"Bergharen\",\n  \"Berghem\",\n  \"Berghum\",\n  \"Bergstoep\",\n  \"Berik\",\n  \"Beringe\",\n  \"Berk\",\n  \"Berke\",\n  \"Berken\",\n  \"Berkt\",\n  \"Berlicum\",\n  \"Bern\",\n  \"Besse\",\n  \"Besthmen\",\n  \"Beswerd\",\n  \"Bethlehem\",\n  \"Beugt\",\n  \"Beuke\",\n  \"Beun\",\n  \"Beusb\",\n  \"Beusichem\",\n  \"Bever\",\n  \"Bidding\",\n  \"Biert\",\n  \"Bierum\",\n  \"Biessum\",\n  \"Biest\",\n  \"Biezen\",\n  \"Bigge\",\n  \"Bijster\",\n  \"Bijsteren\",\n  \"Billing\",\n  \"Bilt\",\n  \"Bingerden\",\n  \"Bisselt\",\n  \"Bissen\",\n  \"Blaker\",\n  \"Blaricum\",\n  \"Blauhûs\",\n  \"Blauw\",\n  \"Blauwe\",\n  \"Blauwen\",\n  \"Bleijen\",\n  \"Bleijs\",\n  \"Blekslage\",\n  \"Blenkert\",\n  \"Blerick\",\n  \"Blessum\",\n  \"Blije\",\n  \"Blijham\",\n  \"Blijnse\",\n  \"Blok\",\n  \"Blokken\",\n  \"Blokum\",\n  \"Boazum\",\n  \"Boberden\",\n  \"Bocholtz\",\n  \"Bocht\",\n  \"Boeiink\",\n  \"Boek\",\n  \"Boekel\",\n  \"Boekelo\",\n  \"Boekelte\",\n  \"Boekend\",\n  \"Boer\",\n  \"Boerakker\",\n  \"Boerelaan\",\n  \"Boeren\",\n  \"Boerengat\",\n  \"Boerenhol\",\n  \"Boerhaar\",\n  \"Boijl\",\n  \"Boks\",\n  \"Boksum\",\n  \"Bokt\",\n  \"Bollinga\",\n  \"Bols\",\n  \"Bolst\",\n  \"Bolt\",\n  \"Bommerig\",\n  \"Bong\",\n  \"Bonkwert\",\n  \"Bonner\",\n  \"Bonrepas\",\n  \"Bontebok\",\n  \"Boomen\",\n  \"Boord\",\n  \"Borger\",\n  \"Borgharen\",\n  \"Borgs\",\n  \"Borgweg\",\n  \"Borkel\",\n  \"Borkeld\",\n  \"Born\",\n  \"Borne\",\n  \"Borneo\",\n  \"Bornwird\",\n  \"Bos\",\n  \"Boschkens\",\n  \"Bosje\",\n  \"Bosjes\",\n  \"Boskamp\",\n  \"Boskant\",\n  \"Boskoop\",\n  \"Boslust\",\n  \"Bosschen\",\n  \"Bosscher\",\n  \"Bosven\",\n  \"Boter\",\n  \"Botshoofd\",\n  \"Boukoul\",\n  \"Bourtange\",\n  \"Boven\",\n  \"Bovenstad\",\n  \"Boxtel\",\n  \"Braak\",\n  \"Braamt\",\n  \"Brabander\",\n  \"Brakel\",\n  \"Brand\",\n  \"Brande\",\n  \"Brandt\",\n  \"Brantgum\",\n  \"Breda\",\n  \"Brede\",\n  \"Bree\",\n  \"Breede\",\n  \"Breedeweg\",\n  \"Breehees\",\n  \"Breezand\",\n  \"Brem\",\n  \"Breskens\",\n  \"Breugel\",\n  \"Breukele\",\n  \"Breyvin\",\n  \"Brielle\",\n  \"Brigdamme\",\n  \"Brij\",\n  \"Brillerij\",\n  \"Briltil\",\n  \"Brinkmans\",\n  \"Britsum\",\n  \"Britswert\",\n  \"Broek\",\n  \"Broekens\",\n  \"Broekkant\",\n  \"Brommelen\",\n  \"Brons\",\n  \"Bruchem\",\n  \"Bruggen\",\n  \"Brugger\",\n  \"Bruil\",\n  \"Bruinisse\",\n  \"Bruister\",\n  \"Brumhold\",\n  \"Brunssum\",\n  \"Brunsting\",\n  \"Bruntinge\",\n  \"Buchten\",\n  \"Buggenum\",\n  \"Buis\",\n  \"Buiten\",\n  \"Bulkenaar\",\n  \"Bult\",\n  \"Bultinge\",\n  \"Bunne\",\n  \"Bunnik\",\n  \"Burdaard\",\n  \"Burger\",\n  \"Burgh\",\n  \"Burgt\",\n  \"Burgum\",\n  \"Burgwerd\",\n  \"Burstum\",\n  \"Burum\",\n  \"Bussel\",\n  \"Busselte\",\n  \"Busser\",\n  \"Buttinge\",\n  \"Buurtje\",\n  \"Cadier\",\n  \"Cadzand\",\n  \"Calfven\",\n  \"Calslagen\",\n  \"Caluna\",\n  \"Camerig\",\n  \"Capelle\",\n  \"Carnisse\",\n  \"Cartils\",\n  \"Castelré\",\n  \"Castenray\",\n  \"Castert\",\n  \"Castricum\",\n  \"Catsop\",\n  \"Chaam\",\n  \"Clinge\",\n  \"Coevorden\",\n  \"Colmont\",\n  \"Cornjum\",\n  \"Cornwerd\",\n  \"Cottessen\",\n  \"Crapoel\",\n  \"Crau\",\n  \"Crix\",\n  \"Crob\",\n  \"Croy\",\n  \"Culemborg\",\n  \"Daarle\",\n  \"Dale\",\n  \"Dalem\",\n  \"Dalen\",\n  \"Daler\",\n  \"Dalerend\",\n  \"Dalerpeel\",\n  \"Dallinge\",\n  \"Damwâld\",\n  \"Daniken\",\n  \"Darp\",\n  \"Dassemus\",\n  \"Dearsum\",\n  \"Dedgum\",\n  \"Deelen\",\n  \"Deelse\",\n  \"Deelshurk\",\n  \"Deense\",\n  \"Deest\",\n  \"Deil\",\n  \"Deinum\",\n  \"Dekes\",\n  \"Dekkers\",\n  \"Del\",\n  \"Delden\",\n  \"Delf\",\n  \"Delft\",\n  \"Dellen\",\n  \"Delwijnen\",\n  \"Demen\",\n  \"Den \",\n  \"Deursen\",\n  \"Deuteren\",\n  \"Deventer\",\n  \"Dieden\",\n  \"Diemen\",\n  \"Diepen\",\n  \"Diependal\",\n  \"Diepswal\",\n  \"Diermen\",\n  \"Dieskant\",\n  \"Dieteren\",\n  \"Diever\",\n  \"Dijken\",\n  \"Dijker\",\n  \"Dijkster\",\n  \"Dijkwel\",\n  \"Dintelsas\",\n  \"Dinther\",\n  \"Dintherse\",\n  \"Diphoorn\",\n  \"Dirkshorn\",\n  \"Dis\",\n  \"Diunt\",\n  \"Doenrade\",\n  \"Does\",\n  \"Doeveren\",\n  \"Doezum\",\n  \"Doijum\",\n  \"Dokkum\",\n  \"Doldersum\",\n  \"Dom\",\n  \"Dommelen\",\n  \"Donderen\",\n  \"Dongen\",\n  \"Donia\",\n  \"Doniaga\",\n  \"Donzel\",\n  \"Dood\",\n  \"Doodstil\",\n  \"Doon\",\n  \"Doorn\",\n  \"Doornen\",\n  \"Doornik\",\n  \"Doorning\",\n  \"Doorwerth\",\n  \"Doosje\",\n  \"Dorkwerd\",\n  \"Dorst\",\n  \"Dorther\",\n  \"Douverge\",\n  \"Douwen\",\n  \"Draai\",\n  \"Drachten\",\n  \"Dreischor\",\n  \"Drie\",\n  \"Drieboere\",\n  \"Driehuis\",\n  \"Driene\",\n  \"Dries\",\n  \"Driewegen\",\n  \"Driezum\",\n  \"Drieën\",\n  \"Drijber\",\n  \"Drimmelen\",\n  \"Drogeham\",\n  \"Drogt\",\n  \"Dronrijp\",\n  \"Dronten\",\n  \"Druif\",\n  \"Drunen\",\n  \"Druten\",\n  \"Drylts\",\n  \"Duifhuis\",\n  \"Duinen\",\n  \"Duiven\",\n  \"Duizel\",\n  \"Duizend\",\n  \"Dulder\",\n  \"Dunsborg\",\n  \"Dussen\",\n  \"Duur\",\n  \"Duurends\",\n  \"Eagum\",\n  \"Earnewâld\",\n  \"Easterein\",\n  \"Eastermar\",\n  \"Easthim\",\n  \"Echt\",\n  \"Echten\",\n  \"Echtener\",\n  \"Echter\",\n  \"Eder\",\n  \"Eede\",\n  \"Eefsele\",\n  \"Eekt\",\n  \"Eekwerd\",\n  \"Eelde\",\n  \"Eelen\",\n  \"Eems\",\n  \"Eemster\",\n  \"Eemten\",\n  \"Een\",\n  \"Eenigen\",\n  \"Eenrum\",\n  \"Eenum\",\n  \"Eerde\",\n  \"Eersel\",\n  \"Eerste\",\n  \"Ees\",\n  \"Eesterga\",\n  \"Effen\",\n  \"Egchel\",\n  \"Egede\",\n  \"Egmond\",\n  \"Egypte\",\n  \"Eikelen\",\n  \"Eikelhof\",\n  \"Eimeren\",\n  \"Eindewege\",\n  \"Eindje\",\n  \"Ekamp\",\n  \"Elde\",\n  \"Elden\",\n  \"Eldik\",\n  \"Eldrik\",\n  \"Elft\",\n  \"Elkerzee\",\n  \"Ellemeet\",\n  \"Eller\",\n  \"Ellerhei\",\n  \"Ellersing\",\n  \"Elsen\",\n  \"Elshof\",\n  \"Elspeet\",\n  \"Elst\",\n  \"Elsteren\",\n  \"Elzet\",\n  \"Emmeloord\",\n  \"Emmen\",\n  \"Empel\",\n  \"Endepoel\",\n  \"Eng\",\n  \"Enge\",\n  \"Engel\",\n  \"Engelbert\",\n  \"Engelen\",\n  \"Engelum\",\n  \"Englum\",\n  \"Engwegen\",\n  \"Engwierum\",\n  \"Enk\",\n  \"Enschedé\",\n  \"Enspijk\",\n  \"Enumatil\",\n  \"Enzelens\",\n  \"Eper\",\n  \"Eppen\",\n  \"Erichem\",\n  \"Erlecom\",\n  \"Ermelo\",\n  \"Ermer\",\n  \"Escharen\",\n  \"Eschoten\",\n  \"Espelo\",\n  \"Essen\",\n  \"Etenaken\",\n  \"Etzenrade\",\n  \"Eursing\",\n  \"Eursinge\",\n  \"Euverem\",\n  \"Ever\",\n  \"Everd\",\n  \"Everlo\",\n  \"Everse\",\n  \"Ewer\",\n  \"Ewinkel\",\n  \"Exmorra\",\n  \"Eygels\",\n  \"Eyser\",\n  \"Ezinge\",\n  \"Ezuma\",\n  \"Faan\",\n  \"Falom\",\n  \"Farmsum\",\n  \"Fatum\",\n  \"Feerwerd\",\n  \"Fel\",\n  \"Ferwert\",\n  \"Fiemel\",\n  \"Fijfhûs\",\n  \"Finke\",\n  \"Finkum\",\n  \"Flieren\",\n  \"Flânsum\",\n  \"Fokkers\",\n  \"Follega\",\n  \"Folsgeare\",\n  \"Formerum\",\n  \"Fort\",\n  \"Fortmond\",\n  \"Foudgum\",\n  \"Fraamklap\",\n  \"Frankhuis\",\n  \"Frankrijk\",\n  \"Fransum\",\n  \"Friens\",\n  \"Frytum\",\n  \"Fûns\",\n  \"Gaag\",\n  \"Gaanderen\",\n  \"Gaar\",\n  \"Gaast\",\n  \"Gaasten\",\n  \"Gaastmar\",\n  \"Gaete\",\n  \"Gagel\",\n  \"Galder\",\n  \"Gameren\",\n  \"Gammelke\",\n  \"Ganzert\",\n  \"Gapinge\",\n  \"Garminge\",\n  \"Garnwerd\",\n  \"Garre\",\n  \"Garrels\",\n  \"Garst\",\n  \"Garyp\",\n  \"Gassel\",\n  \"Gasthuis\",\n  \"Gawege\",\n  \"Gebergte\",\n  \"Geefs\",\n  \"Geen\",\n  \"Geer\",\n  \"Gees\",\n  \"Geeuwen\",\n  \"Geffen\",\n  \"Gelders\",\n  \"Gelderse\",\n  \"Geleen\",\n  \"Gelkenes\",\n  \"Gellicum\",\n  \"Gemaal\",\n  \"Gement\",\n  \"Gemert\",\n  \"Gemonde\",\n  \"Gendt\",\n  \"Geneijgen\",\n  \"Genen\",\n  \"Gening\",\n  \"Genne\",\n  \"Gennep\",\n  \"Genooi\",\n  \"Gerheggen\",\n  \"Gerner\",\n  \"Gersloot\",\n  \"Gerven\",\n  \"Gerwen\",\n  \"Geulhem\",\n  \"Gever\",\n  \"Geverik\",\n  \"Gewande\",\n  \"Giers\",\n  \"Giessen\",\n  \"Gietelo\",\n  \"Giethmen\",\n  \"Giethoorn\",\n  \"Gijbe\",\n  \"Gijsselte\",\n  \"Gijzel\",\n  \"Gilze\",\n  \"Ginkel\",\n  \"Ginnum\",\n  \"Glaner\",\n  \"Goaiïngea\",\n  \"Godlinze\",\n  \"Goes\",\n  \"Goilberd\",\n  \"Goirle\",\n  \"Goldhoorn\",\n  \"Gooium\",\n  \"Goor\",\n  \"Gorinchem\",\n  \"Gorp\",\n  \"Gortel\",\n  \"Gouda\",\n  \"Gouderak\",\n  \"Goudseweg\",\n  \"Goënga\",\n  \"Graaf\",\n  \"Graauw\",\n  \"Gracht\",\n  \"Graet\",\n  \"Graf\",\n  \"Grafwegen\",\n  \"Gras\",\n  \"Graspeel\",\n  \"Graszode\",\n  \"Grathem\",\n  \"Grauwe\",\n  \"Grave\",\n  \"Grazen\",\n  \"Greonterp\",\n  \"Greup\",\n  \"Griete\",\n  \"Grijps\",\n  \"Grits\",\n  \"Groe\",\n  \"Groede\",\n  \"Groen\",\n  \"Groenekan\",\n  \"Groeneweg\",\n  \"Groenlo\",\n  \"Groep\",\n  \"Groes\",\n  \"Groessen\",\n  \"Groet\",\n  \"Groeve\",\n  \"Groeze\",\n  \"Gron\",\n  \"Groot\",\n  \"Groote\",\n  \"Grote\",\n  \"Grotel\",\n  \"Grou\",\n  \"Gytsjerk\",\n  \"Haaften\",\n  \"Haag\",\n  \"Haagje\",\n  \"Haaks\",\n  \"Haakswold\",\n  \"Haalderen\",\n  \"Haalweide\",\n  \"Haamstede\",\n  \"Haandrik\",\n  \"Haar\",\n  \"Haarlem\",\n  \"Haarsteeg\",\n  \"Haart\",\n  \"Haelen\",\n  \"Haerst\",\n  \"Hagestein\",\n  \"Haiink\",\n  \"Halder\",\n  \"Haler\",\n  \"Half\",\n  \"Halfmijl\",\n  \"Halfweg\",\n  \"Halle\",\n  \"Haller\",\n  \"Hallum\",\n  \"Halte\",\n  \"Halvink\",\n  \"Hamrik\",\n  \"Hamshorn\",\n  \"Handel\",\n  \"Hane\",\n  \"Hank\",\n  \"Hankate\",\n  \"Hansweert\",\n  \"Hantum\",\n  \"Hantumer\",\n  \"Harculo\",\n  \"Harde\",\n  \"Hardinx\",\n  \"Haren\",\n  \"Harener\",\n  \"Haring\",\n  \"Harke\",\n  \"Harkema\",\n  \"Harl\",\n  \"Harles\",\n  \"Harpel\",\n  \"Harre\",\n  \"Harse\",\n  \"Harskamp\",\n  \"Harssens\",\n  \"Hartwerd\",\n  \"Haspel\",\n  \"Hasselt\",\n  \"Hasselter\",\n  \"Hatte\",\n  \"Hattem\",\n  \"Hauwert\",\n  \"Havelt\",\n  \"Havelte\",\n  \"Hayum\",\n  \"Haze\",\n  \"Hazenhurk\",\n  \"Hazennest\",\n  \"Heaburgen\",\n  \"Hedel\",\n  \"Hedik\",\n  \"Heech\",\n  \"Heegher\",\n  \"Heek\",\n  \"Heelsum\",\n  \"Heems\",\n  \"Heemstede\",\n  \"Heenweg\",\n  \"Heer\",\n  \"Heerde\",\n  \"Heere\",\n  \"Heeren\",\n  \"Heers\",\n  \"Hees\",\n  \"Heesakker\",\n  \"Heesbeen\",\n  \"Heesboom\",\n  \"Heesch\",\n  \"Heesselt\",\n  \"Heet\",\n  \"Heezeren\",\n  \"Hefswal\",\n  \"Hegge\",\n  \"Hei\",\n  \"Heiakker\",\n  \"Heibloem\",\n  \"Heid\",\n  \"Heide\",\n  \"Heidekant\",\n  \"Heiden\",\n  \"Heier\",\n  \"Heihoefke\",\n  \"Heij\",\n  \"Heijen\",\n  \"Heikant\",\n  \"Heikantse\",\n  \"Heille\",\n  \"Heine\",\n  \"Heioord\",\n  \"Heister\",\n  \"Heitrak\",\n  \"Hekel\",\n  \"Hekkum\",\n  \"Hel\",\n  \"Helden\",\n  \"Helkant\",\n  \"Hell\",\n  \"Helle\",\n  \"Hellegat\",\n  \"Hellen\",\n  \"Hellevoet\",\n  \"Helling\",\n  \"Hellouw\",\n  \"Helwerd\",\n  \"Hemert\",\n  \"Hemrik\",\n  \"Hendrik\",\n  \"Henge\",\n  \"Herfte\",\n  \"Herike\",\n  \"Herk\",\n  \"Herken\",\n  \"Hermalen\",\n  \"Hernen\",\n  \"Herpen\",\n  \"Herpt\",\n  \"Hersel\",\n  \"Hersend\",\n  \"Hert\",\n  \"Herten\",\n  \"Hertme\",\n  \"Herveld\",\n  \"Herwen\",\n  \"Herwijnen\",\n  \"Herxen\",\n  \"Hesens\",\n  \"Hespe\",\n  \"Hessum\",\n  \"Heugde\",\n  \"Heukelom\",\n  \"Heukelum\",\n  \"Heult\",\n  \"Heumen\",\n  \"Heure\",\n  \"Heurne\",\n  \"Heusden\",\n  \"Heuvel\",\n  \"Heuvels\",\n  \"Heuveltje\",\n  \"Hexel\",\n  \"Heze\",\n  \"Hiaure\",\n  \"Hichtum\",\n  \"Hidaard\",\n  \"Hien\",\n  \"Hierden\",\n  \"Hieslum\",\n  \"Hijken\",\n  \"Hijum\",\n  \"Hilaard\",\n  \"Hilakker\",\n  \"Hild\",\n  \"Hill\",\n  \"Hilte\",\n  \"Hilversum\",\n  \"Hinnaard\",\n  \"Hintham\",\n  \"Hitsertse\",\n  \"Hodenpijl\",\n  \"Hoef\",\n  \"Hoefkens\",\n  \"Hoek\",\n  \"Hoekdries\",\n  \"Hoekelum\",\n  \"Hoekens\",\n  \"Hoekje\",\n  \"Hoeks\",\n  \"Hoekske\",\n  \"Hoetmans\",\n  \"Hoeve\",\n  \"Hoeven\",\n  \"Hoeves\",\n  \"Hoge\",\n  \"Hogert\",\n  \"Hogeweg\",\n  \"Holker\",\n  \"Hollum\",\n  \"Holm\",\n  \"Holset\",\n  \"Holsloot\",\n  \"Holst\",\n  \"Holt\",\n  \"Holte\",\n  \"Holten\",\n  \"Holter\",\n  \"Holthe\",\n  \"Holtien\",\n  \"Holtinge\",\n  \"Holtum\",\n  \"Holwerd\",\n  \"Holwierde\",\n  \"Holwinde\",\n  \"Hommelse\",\n  \"Hommert\",\n  \"Hommerts\",\n  \"Honderd\",\n  \"Honds\",\n  \"Hondsrug\",\n  \"Hongerige\",\n  \"Honthem\",\n  \"Hoog\",\n  \"Hoogcruts\",\n  \"Hooge\",\n  \"Hoogehaar\",\n  \"Hoogen\",\n  \"Hoogeweg\",\n  \"Hooghalen\",\n  \"Hoogmade\",\n  \"Hoogmeien\",\n  \"Hoogwatum\",\n  \"Hool\",\n  \"Hoon\",\n  \"Hoonte\",\n  \"Hoorn\",\n  \"Hoornder\",\n  \"Hoptille\",\n  \"Horck\",\n  \"Horick\",\n  \"Horn\",\n  \"Horssen\",\n  \"Horsten\",\n  \"Horzik\",\n  \"Hout\",\n  \"Houterd\",\n  \"Houtgoor\",\n  \"Houthei\",\n  \"Houthem\",\n  \"Houw\",\n  \"Houwer\",\n  \"Hugten\",\n  \"Huij\",\n  \"Huinen\",\n  \"Huinerwal\",\n  \"Huis\",\n  \"Huissen\",\n  \"Huize\",\n  \"Huizinge\",\n  \"Hul\",\n  \"Huls\",\n  \"Hulsen\",\n  \"Hulst\",\n  \"Hulten\",\n  \"Hultje\",\n  \"Humcoven\",\n  \"Hunnecum\",\n  \"Hunsel\",\n  \"Hupsel\",\n  \"Hurkske\",\n  \"Hurpesch\",\n  \"Hutten\",\n  \"Huurne\",\n  \"Höchte\",\n  \"Höfke\",\n  \"Húns\",\n  \"Idaerd\",\n  \"Idserda\",\n  \"Idsken\",\n  \"Idzegea\",\n  \"Iens\",\n  \"IJmuiden\",\n  \"IJpe\",\n  \"IJpelo\",\n  \"IJsselham\",\n  \"IJzen\",\n  \"IJzeren\",\n  \"IJzerlo\",\n  \"Illik\",\n  \"Indoornik\",\n  \"Ingwert\",\n  \"Inia\",\n  \"Itens\",\n  \"Itteren\",\n  \"Jaars\",\n  \"Jammer\",\n  \"Jannum\",\n  \"Jellum\",\n  \"Jelsum\",\n  \"Jeth\",\n  \"Jipsing\",\n  \"Jirnsum\",\n  \"Jislum\",\n  \"Jisp\",\n  \"Jistrum\",\n  \"Jonas\",\n  \"Jonen\",\n  \"Jonkers\",\n  \"Jorwert\",\n  \"Joure\",\n  \"Jous\",\n  \"Jousterp\",\n  \"Jouswerd\",\n  \"Jouwer\",\n  \"Jubbega\",\n  \"Jukwerd\",\n  \"Junne\",\n  \"Jutryp\",\n  \"Kaag\",\n  \"Kaakhorn\",\n  \"Kaard\",\n  \"Kaarschot\",\n  \"Kaat\",\n  \"Kade\",\n  \"Kadoelen\",\n  \"Kalis\",\n  \"Kalteren\",\n  \"Kameren\",\n  \"Kamp\",\n  \"Kampen\",\n  \"Kamper\",\n  \"Kamperei\",\n  \"Kampers\",\n  \"Kamperzee\",\n  \"Kantens\",\n  \"Kantje\",\n  \"Kapel\",\n  \"Kapelle\",\n  \"Kapolder\",\n  \"Kappert\",\n  \"Karre\",\n  \"Kasen\",\n  \"Kasteren\",\n  \"Kater\",\n  \"Katerveer\",\n  \"Kathagen\",\n  \"Katlijk\",\n  \"Kats\",\n  \"Katwijk\",\n  \"Kaumes\",\n  \"Kavel\",\n  \"Kaweide\",\n  \"Kedichem\",\n  \"Keegen\",\n  \"Keent\",\n  \"Keersop\",\n  \"Keinsmer\",\n  \"Keizers\",\n  \"Kekerdom\",\n  \"Kelmond\",\n  \"Kelpen\",\n  \"Kempkens\",\n  \"Kerk\",\n  \"Kerken\",\n  \"Kerkhof\",\n  \"Kerkrade\",\n  \"Kerkwerve\",\n  \"Keske\",\n  \"Kessel\",\n  \"Kesseleik\",\n  \"Ketting\",\n  \"Keulse\",\n  \"Keunen\",\n  \"Keup\",\n  \"Keuter\",\n  \"Kibbel\",\n  \"Kiel\",\n  \"Kiester\",\n  \"Kievit\",\n  \"Kijf\",\n  \"Kijfwaard\",\n  \"Kijkuit\",\n  \"Kilder\",\n  \"Kille\",\n  \"Kimswerd\",\n  \"Kinderbos\",\n  \"Kink\",\n  \"Kinnum\",\n  \"Kipper\",\n  \"Klaaswaal\",\n  \"Kladde\",\n  \"Klaren\",\n  \"Klatering\",\n  \"Klef\",\n  \"Klei\",\n  \"Klein\",\n  \"Kleinder\",\n  \"Kleine\",\n  \"Kleinge\",\n  \"Klem\",\n  \"Kletter\",\n  \"Klevers\",\n  \"Klispoel\",\n  \"Klomp\",\n  \"Klooster\",\n  \"Klosse\",\n  \"Klösse\",\n  \"Knaphof\",\n  \"Knegsel\",\n  \"Knipe\",\n  \"Knol\",\n  \"Knolle\",\n  \"Knuiters\",\n  \"Koedood\",\n  \"Koehool\",\n  \"Koekange\",\n  \"Koekanger\",\n  \"Koekoek\",\n  \"Koel\",\n  \"Koevering\",\n  \"Kokkelert\",\n  \"Kolder\",\n  \"Kolhol\",\n  \"Kolhorn\",\n  \"Kolk\",\n  \"Kollum\",\n  \"Kolonie\",\n  \"Kommer\",\n  \"Konings\",\n  \"Koog\",\n  \"Kooi\",\n  \"Kooldert\",\n  \"Kopaf\",\n  \"Korhorn\",\n  \"Korn\",\n  \"Kornhorn\",\n  \"Kort\",\n  \"Korte\",\n  \"Korteraar\",\n  \"Korteven\",\n  \"Kortgene\",\n  \"Kostvlies\",\n  \"Koude\",\n  \"Kouden\",\n  \"Koudhoorn\",\n  \"Koulen\",\n  \"Kraan\",\n  \"Kraanven\",\n  \"Kraats\",\n  \"Krabben\",\n  \"Krachtig\",\n  \"Kranen\",\n  \"Krassum\",\n  \"Kreek\",\n  \"Kreielt\",\n  \"Kreijel\",\n  \"Kreijl\",\n  \"Krewerd\",\n  \"Krim\",\n  \"Krimpen\",\n  \"Krol\",\n  \"Kruin\",\n  \"Kruishaar\",\n  \"Kruispunt\",\n  \"Kruisweg\",\n  \"Kuikhorne\",\n  \"Kuiks\",\n  \"Kuinre\",\n  \"Kuitaart\",\n  \"Kuivezand\",\n  \"Kulert\",\n  \"Kulsdom\",\n  \"Kunrade\",\n  \"Kutt\",\n  \"Kuundert\",\n  \"Kuzemer\",\n  \"Kwaal\",\n  \"Kwakel\",\n  \"Kwakkel\",\n  \"Kwartier\",\n  \"Kûkherne\",\n  \"Laag\",\n  \"Laaghalen\",\n  \"Laaghaler\",\n  \"Laak\",\n  \"Laaksum\",\n  \"Laan\",\n  \"Lage\",\n  \"Lagekant\",\n  \"Lageweg\",\n  \"Lakei\",\n  \"Laker\",\n  \"Lalle\",\n  \"Lammer\",\n  \"Lammerweg\",\n  \"Lamperen\",\n  \"Landerum\",\n  \"Landsrade\",\n  \"Lang\",\n  \"Lange\",\n  \"Langeraar\",\n  \"Langerak\",\n  \"Langereit\",\n  \"Lank\",\n  \"Lankes\",\n  \"Laren\",\n  \"Laskwerd\",\n  \"Lattrop\",\n  \"Laude\",\n  \"Lauwer\",\n  \"Ledeacker\",\n  \"Leeg\",\n  \"Leegte\",\n  \"Leek\",\n  \"Leem\",\n  \"Leen\",\n  \"Leens\",\n  \"Leensel\",\n  \"Leermens\",\n  \"Leersum\",\n  \"Leeuw\",\n  \"Leeuwerik\",\n  \"Leeuwte\",\n  \"Lege\",\n  \"Legert\",\n  \"Leiden\",\n  \"Leimuiden\",\n  \"Leker\",\n  \"Lekker\",\n  \"Lelystad\",\n  \"Lemel\",\n  \"Lemele\",\n  \"Lemmer\",\n  \"Lemselo\",\n  \"Lengel\",\n  \"Lent\",\n  \"Lenthe\",\n  \"Leons\",\n  \"Lerop\",\n  \"Lethe\",\n  \"Lettele\",\n  \"Leuke\",\n  \"Leunen\",\n  \"Leur\",\n  \"Leusden\",\n  \"Leutes\",\n  \"Leuth\",\n  \"Leuven\",\n  \"Leuvenum\",\n  \"Leveroy\",\n  \"Lexmond\",\n  \"Lhee\",\n  \"Lichtaard\",\n  \"Lichtmis\",\n  \"Liefkens\",\n  \"Liempde\",\n  \"Lienden\",\n  \"Lier\",\n  \"Lieren\",\n  \"Lierop\",\n  \"Lies\",\n  \"Lievelde\",\n  \"Lieving\",\n  \"Lijnden\",\n  \"Limbricht\",\n  \"Limmen\",\n  \"Linde\",\n  \"Lingsfort\",\n  \"Lintelo\",\n  \"Lintvelde\",\n  \"Lioessens\",\n  \"Lippen\",\n  \"Lith\",\n  \"Lithoijen\",\n  \"Lobith\",\n  \"Loc\",\n  \"Locht\",\n  \"Loenen\",\n  \"Loer\",\n  \"Loete\",\n  \"Logt\",\n  \"Loil\",\n  \"Lollum\",\n  \"Lomm\",\n  \"Lonneker\",\n  \"Loo\",\n  \"Loobrink\",\n  \"Loofaert\",\n  \"Looi\",\n  \"Looien\",\n  \"Look\",\n  \"Loon\",\n  \"Loons\",\n  \"Loonse\",\n  \"Looveer\",\n  \"Loppersum\",\n  \"Lovendaal\",\n  \"Loveren\",\n  \"Loënga\",\n  \"Lubbinge\",\n  \"Luchen\",\n  \"Luchten\",\n  \"Luissel\",\n  \"Luitert\",\n  \"Lula\",\n  \"Lunen\",\n  \"Lunteren\",\n  \"Lunters\",\n  \"Lutjegast\",\n  \"Lutjerijp\",\n  \"Lutke\",\n  \"Lutkepost\",\n  \"Lutten\",\n  \"Lutter\",\n  \"Lytse\",\n  \"Lytshuzen\",\n  \"Maagd\",\n  \"Maaijkant\",\n  \"Maalb\",\n  \"Maaldrift\",\n  \"Maalstede\",\n  \"Maar\",\n  \"Maarn\",\n  \"Maars\",\n  \"Maarssen\",\n  \"Maasband\",\n  \"Maasbree\",\n  \"Maaskant\",\n  \"Maat\",\n  \"Maatsehei\",\n  \"Macharen\",\n  \"Made\",\n  \"Magele\",\n  \"Magrette\",\n  \"Makkum\",\n  \"Mal\",\n  \"Malden\",\n  \"Mallem\",\n  \"Mamelis\",\n  \"Manen\",\n  \"Mantgum\",\n  \"Mantinge\",\n  \"Maren\",\n  \"Maria\",\n  \"Maris\",\n  \"Mark\",\n  \"Markvelde\",\n  \"Marle\",\n  \"Marrum\",\n  \"Mars\",\n  \"Marssum\",\n  \"Marsum\",\n  \"Martens\",\n  \"Marum\",\n  \"Mataram\",\n  \"Maten\",\n  \"Mathijs\",\n  \"Maurik\",\n  \"Maxet\",\n  \"Medemblik\",\n  \"Medevoort\",\n  \"Medler\",\n  \"Meed\",\n  \"Meeden\",\n  \"Meele\",\n  \"Meemortel\",\n  \"Meene\",\n  \"Meer\",\n  \"Meeren\",\n  \"Meern\",\n  \"Meerten\",\n  \"Meerven\",\n  \"Meerwijck\",\n  \"Megelsum\",\n  \"Megen\",\n  \"Meije\",\n  \"Meijel\",\n  \"Melick\",\n  \"Melis\",\n  \"Melissant\",\n  \"Menaldum\",\n  \"Mensinge\",\n  \"Menzel\",\n  \"Meppen\",\n  \"Merkel\",\n  \"Merm\",\n  \"Merselo\",\n  \"Merum\",\n  \"Mesch\",\n  \"Meteren\",\n  \"Metsla\",\n  \"Midbuul\",\n  \"Midde\",\n  \"Middel\",\n  \"Middelijk\",\n  \"Midden\",\n  \"Middenhof\",\n  \"Midlaren\",\n  \"Midlum\",\n  \"Mids\",\n  \"Midwolde\",\n  \"Miedum\",\n  \"Mildert\",\n  \"Milheeze\",\n  \"Mill\",\n  \"Mils\",\n  \"Milschot\",\n  \"Minkeloos\",\n  \"Mispel\",\n  \"Moddergat\",\n  \"Moer\",\n  \"Moeren\",\n  \"Moerslag\",\n  \"Moespot\",\n  \"Molembaix\",\n  \"Molenbaan\",\n  \"Molenbelt\",\n  \"Molengat\",\n  \"Molenhof\",\n  \"Molenperk\",\n  \"Molenrij\",\n  \"Molenstad\",\n  \"Molkwar\",\n  \"Monster\",\n  \"Montfort\",\n  \"Mook\",\n  \"Moord\",\n  \"Moorsel\",\n  \"Morige\",\n  \"Morra\",\n  \"Mortel\",\n  \"Mosbulten\",\n  \"Mosik\",\n  \"Moskou\",\n  \"Mosse\",\n  \"Mossel\",\n  \"Most\",\n  \"Muggenhol\",\n  \"Muis\",\n  \"Muizenhol\",\n  \"Mulderij\",\n  \"Mullegen\",\n  \"Munneke\",\n  \"Munnekens\",\n  \"Munniken\",\n  \"Munte\",\n  \"Murns\",\n  \"Mussel\",\n  \"Mûnein\",\n  \"Naarder\",\n  \"Nabbegat\",\n  \"Nagel\",\n  \"Nansum\",\n  \"Napels\",\n  \"Natten\",\n  \"Neder\",\n  \"Nederbiel\",\n  \"Neer\",\n  \"Neerijnen\",\n  \"Neeritter\",\n  \"Neerloon\",\n  \"Neerst\",\n  \"Negen\",\n  \"Nekke\",\n  \"Nergena\",\n  \"Nia\",\n  \"Nie\",\n  \"Niebert\",\n  \"Niehove\",\n  \"Nier\",\n  \"Niersen\",\n  \"Niesoord\",\n  \"Nieuw\",\n  \"Nieuwaal\",\n  \"Nieuwe\",\n  \"Nieuwer\",\n  \"Nieuwklap\",\n  \"Nieuwkoop\",\n  \"Nieuwolda\",\n  \"Nieuwstad\",\n  \"Niftrik\",\n  \"Nijega\",\n  \"Nijehaske\",\n  \"Nijesyl\",\n  \"Nijken\",\n  \"Nijkerker\",\n  \"Nijlân\",\n  \"Nijmegen\",\n  \"Nijnsel\",\n  \"Nijrees\",\n  \"Nijstad\",\n  \"Nijve\",\n  \"Nispense\",\n  \"Noardein\",\n  \"Noenes\",\n  \"Nolde\",\n  \"Noord\",\n  \"Noorden\",\n  \"Noorder\",\n  \"Noordhorn\",\n  \"Noordink\",\n  \"Noordkant\",\n  \"Noordse\",\n  \"Notendaal\",\n  \"Notsel\",\n  \"Noukoop\",\n  \"Nuenen\",\n  \"Nuijen\",\n  \"Nuil\",\n  \"Nuis\",\n  \"Nunhem\",\n  \"Nunspeet\",\n  \"Nuth\",\n  \"Obbicht\",\n  \"Ock\",\n  \"Oegst\",\n  \"Oekel\",\n  \"Oeken\",\n  \"Oele\",\n  \"Oensel\",\n  \"Oentsjerk\",\n  \"Oerle\",\n  \"Oete\",\n  \"Oever\",\n  \"Offinga\",\n  \"Ofwegen\",\n  \"Ohé;\",\n  \"Oijen\",\n  \"Oirlo\",\n  \"Oirs\",\n  \"Okswerd\",\n  \"Olde\",\n  \"Oldehove\",\n  \"Oldemarkt\",\n  \"Olden\",\n  \"Oldeneel\",\n  \"Oldenhave\",\n  \"Oldeouwer\",\n  \"Oldörp\",\n  \"Olen\",\n  \"Oler\",\n  \"Oling\",\n  \"Olterterp\",\n  \"Ommel\",\n  \"Ommen\",\n  \"Ommeren\",\n  \"Onder\",\n  \"Onna\",\n  \"Onsenoort\",\n  \"Onstwedde\",\n  \"Ooij\",\n  \"Ooijen\",\n  \"Oost\",\n  \"Oostappen\",\n  \"Ooste\",\n  \"Ooster\",\n  \"Oosterend\",\n  \"Oosterens\",\n  \"Oosterhof\",\n  \"Oosterik\",\n  \"Oosternie\",\n  \"Oosternij\",\n  \"Oosterse\",\n  \"Oosterzee\",\n  \"Oosthem\",\n  \"Oostindië\",\n  \"Oostrum\",\n  \"Oostum\",\n  \"Oostwold\",\n  \"Oostzaan\",\n  \"Op\",\n  \"Opende\",\n  \"Ophemert\",\n  \"Ophuis\",\n  \"Opijnen\",\n  \"Opmeeden\",\n  \"Opper\",\n  \"Opperdoes\",\n  \"Opperduit\",\n  \"Opwetten\",\n  \"Opwierde\",\n  \"Oranje\",\n  \"Orvelte\",\n  \"Osen\",\n  \"Oshaar\",\n  \"Ospel\",\n  \"Ossen\",\n  \"Ossenisse\",\n  \"Ostaaijen\",\n  \"Osterbos\",\n  \"Othene\",\n  \"Otterlo\",\n  \"Ottersum\",\n  \"Ou\",\n  \"OuBildt\",\n  \"Oude\",\n  \"Oudega\",\n  \"Oudehaske\",\n  \"Oudehorne\",\n  \"Ouden\",\n  \"Oudenrijn\",\n  \"Ouder\",\n  \"Oudeschip\",\n  \"Oudleusen\",\n  \"Oukoop\",\n  \"OuLeede\",\n  \"OuLeije\",\n  \"OuPolder\",\n  \"OuSchouw\",\n  \"OuStaten\",\n  \"OuStee\",\n  \"OuStoof\",\n  \"OuStrumpt\",\n  \"OuWaranda\",\n  \"Ouwer\",\n  \"OuWillem\",\n  \"Ouwster\",\n  \"Oventje\",\n  \"Over\",\n  \"Overa\",\n  \"Overakker\",\n  \"Overbiel\",\n  \"Overeys\",\n  \"Overgeul\",\n  \"Overheek\",\n  \"Overschot\",\n  \"Overval\",\n  \"Overwater\",\n  \"Paal\",\n  \"Paarde\",\n  \"Paarlo\",\n  \"Paauwen\",\n  \"Paddepoel\",\n  \"Padhuis\",\n  \"Paesens\",\n  \"Palestina\",\n  \"Pallert\",\n  \"Pandgat\",\n  \"Panheel\",\n  \"Pann\",\n  \"Pannerden\",\n  \"Papen\",\n  \"Papenveer\",\n  \"Park\",\n  \"Parrega\",\n  \"Partij\",\n  \"Pasop\",\n  \"Patrijzen\",\n  \"Peebos\",\n  \"Peelkant\",\n  \"Peij\",\n  \"Peizerweg\",\n  \"Pelikaan\",\n  \"Pepinus\",\n  \"Pernis\",\n  \"Pers\",\n  \"Pesaken\",\n  \"Peters\",\n  \"Petten\",\n  \"Piaam\",\n  \"Pieperij\",\n  \"Piepert\",\n  \"Piershil\",\n  \"Pieter\",\n  \"Pikesyl\",\n  \"Piksen\",\n  \"Pingjum\",\n  \"Pinkeveer\",\n  \"Pitteperk\",\n  \"Plaat\",\n  \"Plaats\",\n  \"Plak\",\n  \"Plantage\",\n  \"Plas\",\n  \"Plat\",\n  \"Plein\",\n  \"Poffert\",\n  \"Polen\",\n  \"Polle\",\n  \"Pollen\",\n  \"Ponte\",\n  \"Poonhaven\",\n  \"Poppen\",\n  \"Posterenk\",\n  \"Posthoorn\",\n  \"Pot\",\n  \"Praets\",\n  \"Prickart\",\n  \"Puiflijk\",\n  \"Punt\",\n  \"Purmer\",\n  \"Purmerend\",\n  \"Puth\",\n  \"Putse\",\n  \"Putten\",\n  \"Putters\",\n  \"Pyramide\",\n  \"Raai\",\n  \"Raak\",\n  \"Raam\",\n  \"Raar\",\n  \"Raard\",\n  \"Raayen\",\n  \"Raerd\",\n  \"Rakens\",\n  \"Rakt\",\n  \"Rand\",\n  \"Rande\",\n  \"Randen\",\n  \"Ranum\",\n  \"Raren\",\n  \"Rasquert\",\n  \"Ratte\",\n  \"Ravensgat\",\n  \"Reahûs\",\n  \"Rechteren\",\n  \"Rectum\",\n  \"Reduzum\",\n  \"Reeth\",\n  \"Reidswal\",\n  \"Reitsum\",\n  \"Remswerd\",\n  \"Renesse\",\n  \"Renkum\",\n  \"Renneborg\",\n  \"Rens\",\n  \"Respel\",\n  \"Ressen\",\n  \"Reters\",\n  \"Reth\",\n  \"Reuth\",\n  \"Reutje\",\n  \"Reuzen\",\n  \"Rewert\",\n  \"Rhaan\",\n  \"Rheder\",\n  \"Rhee\",\n  \"Rhenoy\",\n  \"Rhoon\",\n  \"Ridder\",\n  \"Riel\",\n  \"Rien\",\n  \"Riet\",\n  \"Rietven\",\n  \"Rijckholt\",\n  \"Rijen\",\n  \"Rijke\",\n  \"Rijkel\",\n  \"Rijker\",\n  \"Rijlst\",\n  \"Rijnsater\",\n  \"Rijsb\",\n  \"Rijsoord\",\n  \"Rijt\",\n  \"Rijtjes\",\n  \"Ril\",\n  \"Rimpelt\",\n  \"Rink\",\n  \"Rips\",\n  \"Rith\",\n  \"Ritsuma\",\n  \"Roeke\",\n  \"Roekel\",\n  \"Roelage\",\n  \"Roels\",\n  \"Roermond\",\n  \"Roeven\",\n  \"Roggel\",\n  \"Rohel\",\n  \"Rolaf\",\n  \"Roligt\",\n  \"Rollecate\",\n  \"Rolpaal\",\n  \"Rome\",\n  \"Rond\",\n  \"Ronduite\",\n  \"Rood\",\n  \"Roodehaan\",\n  \"Rooden\",\n  \"Roond\",\n  \"Roosteren\",\n  \"Rooth\",\n  \"Ropta\",\n  \"Roskam\",\n  \"Rothem\",\n  \"Rott\",\n  \"Rotte\",\n  \"Rotter\",\n  \"Rotting\",\n  \"Rottum\",\n  \"Rozendaal\",\n  \"Rucphen\",\n  \"Ruif\",\n  \"Ruigen\",\n  \"Ruigezand\",\n  \"Ruimel\",\n  \"Ruinen\",\n  \"Ruischer\",\n  \"Ruiten\",\n  \"Rukven\",\n  \"Rullen\",\n  \"Rumpt\",\n  \"Rund\",\n  \"Rusven\",\n  \"Rut\",\n  \"Ryptsjerk\",\n  \"Rytseterp\",\n  \"Saaksum\",\n  \"Saaxum\",\n  \"Salverd\",\n  \"Sandebuur\",\n  \"Santfort\",\n  \"Santpoort\",\n  \"Sasput\",\n  \"Sauwerd\",\n  \"Schaa\",\n  \"Schaaphok\",\n  \"Schaaps\",\n  \"Schadron\",\n  \"Schafelt\",\n  \"Schaft\",\n  \"Schagen\",\n  \"Schager\",\n  \"Schandelo\",\n  \"Schans\",\n  \"Schapers\",\n  \"Scharen\",\n  \"Scharne\",\n  \"Scharster\",\n  \"Schatkuil\",\n  \"Schaveren\",\n  \"Scheemder\",\n  \"Schelf\",\n  \"Schellach\",\n  \"Schelm\",\n  \"Schettens\",\n  \"Schey\",\n  \"Schieven\",\n  \"Schijf\",\n  \"Schijndel\",\n  \"Schillers\",\n  \"Schimmert\",\n  \"Schin\",\n  \"Schinnen\",\n  \"Schippers\",\n  \"School\",\n  \"Schoon\",\n  \"Schoonen\",\n  \"Schoor\",\n  \"Schoorl\",\n  \"Schoot\",\n  \"Schore\",\n  \"Schoter\",\n  \"Schotters\",\n  \"Schouw\",\n  \"Schouwen\",\n  \"Schouwer\",\n  \"Schraard\",\n  \"Schrap\",\n  \"Schuilen\",\n  \"Schuring\",\n  \"Schuwacht\",\n  \"Sebalde\",\n  \"Seerijp\",\n  \"Sell\",\n  \"Selmien\",\n  \"Selwerd\",\n  \"Seroos\",\n  \"Seters\",\n  \"Sibbe\",\n  \"Siberië\",\n  \"Siegers\",\n  \"Simpel\",\n  \"Sinouts\",\n  \"Sinsel\",\n  \"Sint\",\n  \"Sion\",\n  \"Sittard\",\n  \"Sjunga\",\n  \"Skarl\",\n  \"Skillaerd\",\n  \"Skou\",\n  \"Skrins\",\n  \"Skyldum\",\n  \"Slee\",\n  \"Sleen\",\n  \"Slegge\",\n  \"Slek\",\n  \"Slichten\",\n  \"Sliffert\",\n  \"Slijkwell\",\n  \"Slikken\",\n  \"Sloot\",\n  \"Sluis\",\n  \"Smakt\",\n  \"Smal\",\n  \"Smalle\",\n  \"Smeerling\",\n  \"Smelbrêge\",\n  \"Smele\",\n  \"Smilde\",\n  \"Smits\",\n  \"Sneek\",\n  \"Sneiders\",\n  \"Snelle\",\n  \"Sneps\",\n  \"Snikzwaag\",\n  \"Snipperij\",\n  \"Snoden\",\n  \"Soeter\",\n  \"Solwerd\",\n  \"Someren\",\n  \"Sopsum\",\n  \"Spaanrijt\",\n  \"Spaanse\",\n  \"Spaken\",\n  \"Spannen\",\n  \"Spannum\",\n  \"Spears\",\n  \"Spek\",\n  \"Spekklef\",\n  \"Spekt\",\n  \"Speuld\",\n  \"Speurgt\",\n  \"Spier\",\n  \"Spijk\",\n  \"Spik\",\n  \"Spits\",\n  \"Spoolde\",\n  \"Spoor\",\n  \"Sprang\",\n  \"Sprundel\",\n  \"Spurkt\",\n  \"Stad\",\n  \"Stadterij\",\n  \"Starten\",\n  \"Stations\",\n  \"Staverden\",\n  \"Stedum\",\n  \"Steeg\",\n  \"Steegh\",\n  \"Steel\",\n  \"Steen\",\n  \"Steenkamp\",\n  \"Steenoven\",\n  \"Steenpaal\",\n  \"Steensel\",\n  \"Steenvak\",\n  \"Stegen\",\n  \"Steger\",\n  \"Stegeren\",\n  \"Stein\",\n  \"Sterken\",\n  \"Sterre\",\n  \"Steurgat\",\n  \"Stevens\",\n  \"Stevert\",\n  \"Stiem\",\n  \"Stiens\",\n  \"Stitswerd\",\n  \"Stobben\",\n  \"Stokhem\",\n  \"Stokkelen\",\n  \"Stokkum\",\n  \"Stokske\",\n  \"Stokt\",\n  \"Stolpen\",\n  \"Stomme\",\n  \"Stoof\",\n  \"Stork\",\n  \"Stouten\",\n  \"Stox\",\n  \"Strand\",\n  \"Straten\",\n  \"Strateris\",\n  \"Streek\",\n  \"Strepen\",\n  \"Streukel\",\n  \"Strij\",\n  \"Strijen\",\n  \"Strijp\",\n  \"Stroet\",\n  \"Stroo\",\n  \"Stroopuit\",\n  \"Strubben\",\n  \"Strucht\",\n  \"Strype\",\n  \"Stuw\",\n  \"Sumar\",\n  \"Sumarre\",\n  \"Surhuizum\",\n  \"Susteren\",\n  \"Suttum\",\n  \"Suwâld\",\n  \"Swaenwert\",\n  \"Swalmen\",\n  \"Sweik\",\n  \"Syt\",\n  \"Sânfurd\",\n  \"Taarlo\",\n  \"Teeffelen\",\n  \"Teije\",\n  \"Teijl\",\n  \"Telgt\",\n  \"Tempel\",\n  \"Ter\",\n  \"Terband\",\n  \"Terblijt\",\n  \"Terdiek\",\n  \"Tereyken\",\n  \"Tergêft\",\n  \"Terhagen\",\n  \"Terheijl\",\n  \"Terherne\",\n  \"Terkaple\",\n  \"Terlet\",\n  \"Terlinden\",\n  \"Termaar\",\n  \"Termoors\",\n  \"Termunten\",\n  \"Termunter\",\n  \"Ternaard\",\n  \"Teroele\",\n  \"Terover\",\n  \"Tersoal\",\n  \"Tervaten\",\n  \"Tervoorst\",\n  \"Tervoort\",\n  \"Terwispel\",\n  \"Terwolde\",\n  \"Terziet\",\n  \"Teuge\",\n  \"Theetuin\",\n  \"Themaat\",\n  \"Tholen\",\n  \"Thull\",\n  \"Thuserhof\",\n  \"Tibma\",\n  \"Tiel\",\n  \"Tielse\",\n  \"Tiggelt\",\n  \"Tijnje\",\n  \"Tike\",\n  \"Til\",\n  \"Timmer\",\n  \"Tippe\",\n  \"Tjaard\",\n  \"Tjams\",\n  \"Tjerkwerd\",\n  \"Tjoene\",\n  \"Tolbert\",\n  \"Tolkamer\",\n  \"Tommel\",\n  \"Tongeren\",\n  \"Tongerlo\",\n  \"Tonsel\",\n  \"Toom\",\n  \"Toornwerd\",\n  \"Top\",\n  \"Toren\",\n  \"Toterfout\",\n  \"Toven\",\n  \"Tragel\",\n  \"Tranendal\",\n  \"Trege\",\n  \"Trent\",\n  \"Tricht\",\n  \"Triemen\",\n  \"Trimpert\",\n  \"Trintelen\",\n  \"Tritzum\",\n  \"Tronde\",\n  \"Trophorne\",\n  \"Trutjes\",\n  \"Tuil\",\n  \"Tull\",\n  \"Tungelroy\",\n  \"Turns\",\n  \"Tusschen\",\n  \"Tuut\",\n  \"Tuuthees\",\n  \"Twee\",\n  \"Tweedeweg\",\n  \"TweeTol\",\n  \"Twekkelo\",\n  \"Twello\",\n  \"Twijzel\",\n  \"Twijzeler\",\n  \"Twisk\",\n  \"Tynaarlo\",\n  \"Tytsjerk\",\n  \"Ubach\",\n  \"Ubbena\",\n  \"Ubber\",\n  \"Uddel\",\n  \"Uffelsen\",\n  \"Uffelte\",\n  \"Uit\",\n  \"Uiter\",\n  \"Uithoorn\",\n  \"Uitwierde\",\n  \"Ulfter\",\n  \"Ulicoten\",\n  \"Ulrum\",\n  \"Ulsda\",\n  \"Ulvend\",\n  \"Unga\",\n  \"Uppel\",\n  \"Usquert\",\n  \"Usselo\",\n  \"Vaals\",\n  \"Vaar\",\n  \"Vaarle\",\n  \"Vaart\",\n  \"Vaesrade\",\n  \"Valk\",\n  \"Valken\",\n  \"Valom\",\n  \"Valsteeg\",\n  \"Varik\",\n  \"Varsen\",\n  \"Varssel\",\n  \"Vebenabos\",\n  \"Vecht\",\n  \"Veecaten\",\n  \"Veele\",\n  \"Veeler\",\n  \"Veen\",\n  \"Veenhof\",\n  \"Veenhoop\",\n  \"Veenhuis\",\n  \"Veere\",\n  \"Veessen\",\n  \"Veghel\",\n  \"Veld\",\n  \"Veldbraak\",\n  \"Velde\",\n  \"Velden\",\n  \"Veldhuis\",\n  \"Veldzicht\",\n  \"Velp\",\n  \"Velsen\",\n  \"Veluwe\",\n  \"Vemde\",\n  \"Ven\",\n  \"Venbe\",\n  \"Vene\",\n  \"Venekoten\",\n  \"Venlo\",\n  \"Venne\",\n  \"Venray\",\n  \"Venweg\",\n  \"Vergelt\",\n  \"Verloren\",\n  \"Vessem\",\n  \"Vestjens\",\n  \"Vet\",\n  \"Vetterik\",\n  \"Veulen\",\n  \"Vianen\",\n  \"Viel\",\n  \"Vier\",\n  \"Vierhuis\",\n  \"Vijcie\",\n  \"Vijf\",\n  \"Vilgert\",\n  \"Vilsteren\",\n  \"Vilt\",\n  \"Vink\",\n  \"Vinkel\",\n  \"Vinken\",\n  \"Vinkepas\",\n  \"Vis\",\n  \"Visschers\",\n  \"Vissers\",\n  \"Vlaas\",\n  \"Vlake\",\n  \"Vlas\",\n  \"Vledder\",\n  \"Vleet\",\n  \"Vleuten\",\n  \"Vlie\",\n  \"Vliegert\",\n  \"Vlieghuis\",\n  \"Vlijmen\",\n  \"Vliss\",\n  \"Vlist\",\n  \"Vlodrop\",\n  \"Vloei\",\n  \"Vloet\",\n  \"Vlootkant\",\n  \"Vogelfort\",\n  \"Volthe\",\n  \"Voor\",\n  \"Voorne\",\n  \"Voorrijp\",\n  \"Voorst\",\n  \"Voorstad\",\n  \"Voorste\",\n  \"Voorster\",\n  \"Voort\",\n  \"Voortje\",\n  \"Voorweg\",\n  \"Vorchten\",\n  \"Vorst\",\n  \"Vorsten\",\n  \"Voske\",\n  \"Voskuil\",\n  \"Vosse\",\n  \"Vossebelt\",\n  \"Vosselen\",\n  \"Vossen\",\n  \"Voulwames\",\n  \"Vrachelen\",\n  \"Vragender\",\n  \"Vredepeel\",\n  \"Vree\",\n  \"Vries\",\n  \"Vriezen\",\n  \"Vrij\",\n  \"Vrijhoeve\",\n  \"Vrilk\",\n  \"Vroe\",\n  \"Vroelen\",\n  \"Vuile\",\n  \"Vuilpan\",\n  \"Vuren\",\n  \"Waaksens\",\n  \"Waal\",\n  \"Waar\",\n  \"Waard\",\n  \"Waarde\",\n  \"Waarden\",\n  \"Waarder\",\n  \"Waatskamp\",\n  \"Wachtum\",\n  \"Waddinx\",\n  \"Wadway\",\n  \"Wadwerd\",\n  \"Wagen\",\n  \"Waije\",\n  \"Walder\",\n  \"Walik\",\n  \"Walsert\",\n  \"Wammert\",\n  \"Wanneper\",\n  \"Wanroij\",\n  \"Wapen\",\n  \"Wapse\",\n  \"Wapser\",\n  \"Warf\",\n  \"Warffum\",\n  \"Warfster\",\n  \"Warmen\",\n  \"Warmond\",\n  \"Warnia\",\n  \"Warstiens\",\n  \"Warten\",\n  \"Waspik\",\n  \"Water\",\n  \"Wateren\",\n  \"Waterkant\",\n  \"Waterop\",\n  \"Waterval\",\n  \"Waver\",\n  \"Weakens\",\n  \"Wedde\",\n  \"Wedder\",\n  \"Wee\",\n  \"Weeg\",\n  \"Weende\",\n  \"Weerd\",\n  \"Weerdinge\",\n  \"Weere\",\n  \"Weert\",\n  \"Weerwille\",\n  \"Wehe\",\n  \"Wehl\",\n  \"Weidum\",\n  \"Weij\",\n  \"Weijer\",\n  \"Weijpoort\",\n  \"Weilens\",\n  \"Weimeren\",\n  \"Weipoort\",\n  \"Weite\",\n  \"Weitemans\",\n  \"Weiwerd\",\n  \"Wekerom\",\n  \"Wele\",\n  \"Wells\",\n  \"Welsum\",\n  \"Wely\",\n  \"Wenum\",\n  \"Weper\",\n  \"Wercheren\",\n  \"Weren\",\n  \"Wergea\",\n  \"Werk\",\n  \"Wernhouts\",\n  \"Wesch\",\n  \"Wessing\",\n  \"Wessinge\",\n  \"West\",\n  \"Westeneng\",\n  \"Wester\",\n  \"Westerein\",\n  \"Westerlee\",\n  \"Westernie\",\n  \"Westerse\",\n  \"Westhim\",\n  \"Westlaren\",\n  \"Westmaas\",\n  \"Westrik\",\n  \"Wetering\",\n  \"Wetsens\",\n  \"Weurt\",\n  \"Wevers\",\n  \"Weverslo\",\n  \"Wezel\",\n  \"Wezep\",\n  \"Wezup\",\n  \"Wezuper\",\n  \"Wielder\",\n  \"Wieler\",\n  \"Wielse\",\n  \"Wiene\",\n  \"Wierren\",\n  \"Wierum\",\n  \"Wiesel\",\n  \"Wieuwens\",\n  \"Wijchen\",\n  \"Wijnaldum\",\n  \"Wijnb\",\n  \"Wijnje\",\n  \"Wijster\",\n  \"Wijthmen\",\n  \"Wijzend\",\n  \"Wilderhof\",\n  \"Wildert\",\n  \"Wilgen\",\n  \"Wilp\",\n  \"Wils\",\n  \"Wilsum\",\n  \"Winde\",\n  \"Windraak\",\n  \"Winkel\",\n  \"Winkels\",\n  \"Winssen\",\n  \"Winsum\",\n  \"Wintelre\",\n  \"Winthagen\",\n  \"Wirdum\",\n  \"Wisse\",\n  \"Wissel\",\n  \"Wissen\",\n  \"Witharen\",\n  \"Withuis\",\n  \"Witman\",\n  \"Witmarsum\",\n  \"Witrijt\",\n  \"Witte\",\n  \"Wittelte\",\n  \"Witten\",\n  \"Wiuwert\",\n  \"Wjelsryp\",\n  \"Woerd\",\n  \"Woerdense\",\n  \"Woezik\",\n  \"Wognum\",\n  \"Wolfers\",\n  \"Wolfhaag\",\n  \"Wolfhagen\",\n  \"Wolfheze\",\n  \"Wolfs\",\n  \"Wolfshuis\",\n  \"Wolling\",\n  \"Wolsum\",\n  \"Wommels\",\n  \"Wonne\",\n  \"Wons\",\n  \"Woord\",\n  \"Wopereis\",\n  \"Wordragen\",\n  \"Wormer\",\n  \"Worsum\",\n  \"Woubrugge\",\n  \"Wouwse\",\n  \"Wulpenbek\",\n  \"Wyns\",\n  \"Wytgaard\",\n  \"Wâldsein\",\n  \"Wânswert\",\n  \"Yerseke\",\n  \"Yndyk\",\n  \"Zaamslag\",\n  \"Zaarvlaas\",\n  \"Zalk\",\n  \"Zand\",\n  \"Zande\",\n  \"Zandfort\",\n  \"Zandkant\",\n  \"Zandoerle\",\n  \"Zandplaat\",\n  \"Zandpol\",\n  \"Zandput\",\n  \"Zandvoort\",\n  \"Zee\",\n  \"Zeegat\",\n  \"Zeegse\",\n  \"Zeerijp\",\n  \"Zeesse\",\n  \"Zegge\",\n  \"Zeijen\",\n  \"Zeijer\",\n  \"Zeist\",\n  \"Zelder\",\n  \"Zelen\",\n  \"Zelt\",\n  \"Zenderen\",\n  \"Zethuis\",\n  \"Zeven\",\n  \"Zevenhuis\",\n  \"Zierikzee\",\n  \"Zieuwent\",\n  \"Zijder\",\n  \"Zijdewind\",\n  \"Zijp\",\n  \"Zijper\",\n  \"Zijtaart\",\n  \"Zilven\",\n  \"Zinkweg\",\n  \"Zittard\",\n  \"Zoeke\",\n  \"Zoelen\",\n  \"Zoelmond\",\n  \"Zoerte\",\n  \"Zoeter\",\n  \"Zoggel\",\n  \"Zomerven\",\n  \"Zond\",\n  \"Zorgvlied\",\n  \"Zoutkamp\",\n  \"Zuid\",\n  \"Zuider\",\n  \"Zuidhorn\",\n  \"Zuidlaren\",\n  \"Zuidwolde\",\n  \"Zuidzande\",\n  \"Zuidzijde\",\n  \"Zuilichem\",\n  \"Zundert\",\n  \"Zurich\",\n  \"Zutphen\",\n  \"Zuuk\",\n  \"Zwaag\",\n  \"Zwager\",\n  \"Zwanegat\",\n  \"Zwart\",\n  \"Zwarte\",\n  \"Zweek\",\n  \"Zwiggelte\",\n  \"Zwijn\",\n  \"Zwinderen\",\n  \"Zwolle\"\n];\n\n},{}],702:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \" aan de IJssel\",\n  \" aan de Rijn\",\n  \"ambacht\",\n  \"beek\",\n  \"berg\",\n  \"bergen\",\n  \"bosch\",\n  \"broek\",\n  \"brug\",\n  \"buren\",\n  \"burg\",\n  \"buurt\",\n  \"dam\",\n  \"dijk\",\n  \"dijke\",\n  \"donk\",\n  \"dorp\",\n  \"eind\",\n  \"enmaes\",\n  \"gat\",\n  \"geest\",\n  \"heide\",\n  \"hoek\",\n  \"horst\",\n  \"hout\",\n  \"hoven\",\n  \"huizen\",\n  \"ingen\",\n  \"kerk\",\n  \"laar\",\n  \"land\",\n  \"meer\",\n  \"recht\",\n  \"schoten\",\n  \"sluis\",\n  \"stroom\",\n  \"swaerd\",\n  \"veen\",\n  \"veld\",\n  \"vliet\",\n  \"weer\",\n  \"wier\",\n  \"wijk\",\n  \"woud\",\n  \"woude\",\n  \"zijl\",\n  \"\"\n];\n\n},{}],703:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afghanistan\",\n  \"Akrotiri\",\n  \"Albanië\",\n  \"Algerije\",\n  \"Amerikaanse Maagdeneilanden\",\n  \"Amerikaans-Samoa\",\n  \"Andorra\",\n  \"Angola\",\n  \"Anguilla\",\n  \"Antarctica\",\n  \"Antigua en Barbuda\",\n  \"Arctic Ocean\",\n  \"Argentinië\",\n  \"Armenië\",\n  \"Aruba\",\n  \"Ashmore and Cartier Islands\",\n  \"Atlantic Ocean\",\n  \"Australië\",\n  \"Azerbeidzjan\",\n  \"Bahama's\",\n  \"Bahrein\",\n  \"Bangladesh\",\n  \"Barbados\",\n  \"Belarus\",\n  \"België\",\n  \"Belize\",\n  \"Benin\",\n  \"Bermuda\",\n  \"Bhutan\",\n  \"Bolivië\",\n  \"Bosnië-Herzegovina\",\n  \"Botswana\",\n  \"Bouvet Island\",\n  \"Brazilië\",\n  \"British Indian Ocean Territory\",\n  \"Britse Maagdeneilanden\",\n  \"Brunei\",\n  \"Bulgarije\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Cambodja\",\n  \"Canada\",\n  \"Caymaneilanden\",\n  \"Centraal-Afrikaanse Republiek\",\n  \"Chili\",\n  \"China\",\n  \"Christmas Island\",\n  \"Clipperton Island\",\n  \"Cocos (Keeling) Islands\",\n  \"Colombia\",\n  \"Comoren (Unie)\",\n  \"Congo (Democratische Republiek)\",\n  \"Congo (Volksrepubliek)\",\n  \"Cook\",\n  \"Coral Sea Islands\",\n  \"Costa Rica\",\n  \"Cuba\",\n  \"Cyprus\",\n  \"Denemarken\",\n  \"Dhekelia\",\n  \"Djibouti\",\n  \"Dominica\",\n  \"Dominicaanse Republiek\",\n  \"Duitsland\",\n  \"Ecuador\",\n  \"Egypte\",\n  \"El Salvador\",\n  \"Equatoriaal-Guinea\",\n  \"Eritrea\",\n  \"Estland\",\n  \"Ethiopië\",\n  \"European Union\",\n  \"Falkland\",\n  \"Faroe Islands\",\n  \"Fiji\",\n  \"Filipijnen\",\n  \"Finland\",\n  \"Frankrijk\",\n  \"Frans-Polynesië\",\n  \"French Southern and Antarctic Lands\",\n  \"Gabon\",\n  \"Gambia\",\n  \"Gaza Strip\",\n  \"Georgië\",\n  \"Ghana\",\n  \"Gibraltar\",\n  \"Grenada\",\n  \"Griekenland\",\n  \"Groenland\",\n  \"Guam\",\n  \"Guatemala\",\n  \"Guernsey\",\n  \"Guinea\",\n  \"Guinee-Bissau\",\n  \"Guyana\",\n  \"Haïti\",\n  \"Heard Island and McDonald Islands\",\n  \"Heilige Stoel\",\n  \"Honduras\",\n  \"Hongarije\",\n  \"Hongkong\",\n  \"Ierland\",\n  \"IJsland\",\n  \"India\",\n  \"Indian Ocean\",\n  \"Indonesië\",\n  \"Irak\",\n  \"Iran\",\n  \"Isle of Man\",\n  \"Israël\",\n  \"Italië\",\n  \"Ivoorkust\",\n  \"Jamaica\",\n  \"Jan Mayen\",\n  \"Japan\",\n  \"Jemen\",\n  \"Jersey\",\n  \"Jordanië\",\n  \"Kaapverdië\",\n  \"Kameroen\",\n  \"Kazachstan\",\n  \"Kenia\",\n  \"Kirgizstan\",\n  \"Kiribati\",\n  \"Koeweit\",\n  \"Kroatië\",\n  \"Laos\",\n  \"Lesotho\",\n  \"Letland\",\n  \"Libanon\",\n  \"Liberia\",\n  \"Libië\",\n  \"Liechtenstein\",\n  \"Litouwen\",\n  \"Luxemburg\",\n  \"Macao\",\n  \"Macedonië\",\n  \"Madagaskar\",\n  \"Malawi\",\n  \"Maldiven\",\n  \"Maleisië\",\n  \"Mali\",\n  \"Malta\",\n  \"Marokko\",\n  \"Marshall Islands\",\n  \"Mauritanië\",\n  \"Mauritius\",\n  \"Mayotte\",\n  \"Mexico\",\n  \"Micronesia, Federated States of\",\n  \"Moldavië\",\n  \"Monaco\",\n  \"Mongolië\",\n  \"Montenegro\",\n  \"Montserrat\",\n  \"Mozambique\",\n  \"Myanmar\",\n  \"Namibië\",\n  \"Nauru\",\n  \"Navassa Island\",\n  \"Nederland\",\n  \"Nederlandse Antillen\",\n  \"Nepal\",\n  \"Ngwane\",\n  \"Nicaragua\",\n  \"Nieuw-Caledonië\",\n  \"Nieuw-Zeeland\",\n  \"Niger\",\n  \"Nigeria\",\n  \"Niue\",\n  \"Noordelijke Marianen\",\n  \"Noord-Korea\",\n  \"Noorwegen\",\n  \"Norfolk Island\",\n  \"Oekraïne\",\n  \"Oezbekistan\",\n  \"Oman\",\n  \"Oostenrijk\",\n  \"Pacific Ocean\",\n  \"Pakistan\",\n  \"Palau\",\n  \"Panama\",\n  \"Papoea-Nieuw-Guinea\",\n  \"Paracel Islands\",\n  \"Paraguay\",\n  \"Peru\",\n  \"Pitcairn\",\n  \"Polen\",\n  \"Portugal\",\n  \"Puerto Rico\",\n  \"Qatar\",\n  \"Roemenië\",\n  \"Rusland\",\n  \"Rwanda\",\n  \"Saint Helena\",\n  \"Saint Lucia\",\n  \"Saint Vincent en de Grenadines\",\n  \"Saint-Pierre en Miquelon\",\n  \"Salomon\",\n  \"Samoa\",\n  \"San Marino\",\n  \"São Tomé en Principe\",\n  \"Saudi-Arabië\",\n  \"Senegal\",\n  \"Servië\",\n  \"Seychellen\",\n  \"Sierra Leone\",\n  \"Singapore\",\n  \"Sint-Kitts en Nevis\",\n  \"Slovenië\",\n  \"Slowakije\",\n  \"Soedan\",\n  \"Somalië\",\n  \"South Georgia and the South Sandwich Islands\",\n  \"Southern Ocean\",\n  \"Spanje\",\n  \"Spratly Islands\",\n  \"Sri Lanka\",\n  \"Suriname\",\n  \"Svalbard\",\n  \"Syrië\",\n  \"Tadzjikistan\",\n  \"Taiwan\",\n  \"Tanzania\",\n  \"Thailand\",\n  \"Timor Leste\",\n  \"Togo\",\n  \"Tokelau\",\n  \"Tonga\",\n  \"Trinidad en Tobago\",\n  \"Tsjaad\",\n  \"Tsjechië\",\n  \"Tunesië\",\n  \"Turkije\",\n  \"Turkmenistan\",\n  \"Turks-en Caicoseilanden\",\n  \"Tuvalu\",\n  \"Uganda\",\n  \"Uruguay\",\n  \"Vanuatu\",\n  \"Venezuela\",\n  \"Verenigd Koninkrijk\",\n  \"Verenigde Arabische Emiraten\",\n  \"Verenigde Staten van Amerika\",\n  \"Vietnam\",\n  \"Wake Island\",\n  \"Wallis en Futuna\",\n  \"Wereld\",\n  \"West Bank\",\n  \"Westelijke Sahara\",\n  \"Zambia\",\n  \"Zimbabwe\",\n  \"Zuid-Afrika\",\n  \"Zuid-Korea\",\n  \"Zweden\",\n  \"Zwitserland\"\n];\n\n},{}],704:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Nederland\"\n];\n\n},{}],705:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.city = require(\"./city\");\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":699,\"./city\":700,\"./city_prefix\":701,\"./city_suffix\":702,\"./country\":703,\"./default_country\":704,\"./postcode\":706,\"./secondary_address\":707,\"./state\":708,\"./street_address\":709,\"./street_name\":710,\"./street_suffix\":711}],706:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#### ??\"\n];\n\n},{}],707:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"1 hoog\",\n  \"2 hoog\",\n  \"3 hoog\"\n];\n\n},{}],708:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Noord-Holland\",\n  \"Zuid-Holland\",\n  \"Utrecht\",\n  \"Zeeland\",\n  \"Overijssel\",\n  \"Gelderland\",\n  \"Drenthe\",\n  \"Friesland\",\n  \"Groningen\",\n  \"Noord-Brabant\",\n  \"Limburg\",\n  \"Flevoland\"\n];\n\n},{}],709:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],710:[function(require,module,exports){\nmodule.exports=require(616)\n},{\"/Users/a/dev/faker.js/lib/locales/ja/address/street_name.js\":616}],711:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"straat\",\n  \"laan\",\n  \"weg\",\n  \"plantsoen\",\n  \"park\"\n];\n\n},{}],712:[function(require,module,exports){\narguments[4][279][0].apply(exports,arguments)\n},{\"./suffix\":713,\"/Users/a/dev/faker.js/lib/locales/en_AU/company/index.js\":279}],713:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"BV\",\n  \"V.O.F.\",\n  \"Group\",\n  \"en Zonen\"\n];\n\n},{}],714:[function(require,module,exports){\nvar nl = {};\nmodule['exports'] = nl;\nnl.title = \"Dutch\";\nnl.address = require(\"./address\");\nnl.company = require(\"./company\");\nnl.internet = require(\"./internet\");\nnl.lorem = require(\"./lorem\");\nnl.name = require(\"./name\");\nnl.phone_number = require(\"./phone_number\");\n\n},{\"./address\":705,\"./company\":712,\"./internet\":717,\"./lorem\":718,\"./name\":722,\"./phone_number\":729}],715:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"nl\",\n  \"com\",\n  \"net\",\n  \"org\"\n];\n\n},{}],716:[function(require,module,exports){\nmodule.exports=require(119)\n},{\"/Users/a/dev/faker.js/lib/locales/de/internet/free_email.js\":119}],717:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":715,\"./free_email\":716,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],718:[function(require,module,exports){\nmodule.exports=require(83)\n},{\"./supplemental\":719,\"./words\":720,\"/Users/a/dev/faker.js/lib/locales/cz/lorem/index.js\":83}],719:[function(require,module,exports){\nmodule.exports=require(84)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/supplemental.js\":84}],720:[function(require,module,exports){\nmodule.exports=require(85)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/words.js\":85}],721:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Amber\",\n  \"Anna\",\n  \"Anne\",\n  \"Anouk\",\n  \"Bas\",\n  \"Bram\",\n  \"Britt\",\n  \"Daan\",\n  \"Emma\",\n  \"Eva\",\n  \"Femke\",\n  \"Finn\",\n  \"Fleur\",\n  \"Iris\",\n  \"Isa\",\n  \"Jan\",\n  \"Jasper\",\n  \"Jayden\",\n  \"Jesse\",\n  \"Johannes\",\n  \"Julia\",\n  \"Julian\",\n  \"Kevin\",\n  \"Lars\",\n  \"Lieke\",\n  \"Lisa\",\n  \"Lotte\",\n  \"Lucas\",\n  \"Luuk\",\n  \"Maud\",\n  \"Max\",\n  \"Mike\",\n  \"Milan\",\n  \"Nick\",\n  \"Niels\",\n  \"Noa\",\n  \"Rick\",\n  \"Roos\",\n  \"Ruben\",\n  \"Sander\",\n  \"Sanne\",\n  \"Sem\",\n  \"Sophie\",\n  \"Stijn\",\n  \"Sven\",\n  \"Thijs\",\n  \"Thijs\",\n  \"Thomas\",\n  \"Tim\",\n  \"Tom\"\n];\n\n},{}],722:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.tussenvoegsel = require(\"./tussenvoegsel\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\nname.name = require(\"./name\");\n\n},{\"./first_name\":721,\"./last_name\":723,\"./name\":724,\"./prefix\":725,\"./suffix\":726,\"./tussenvoegsel\":727}],723:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Bakker\",\n  \"Beek\",\n  \"Berg\",\n  \"Boer\",\n  \"Bos\",\n  \"Bosch\",\n  \"Brink\",\n  \"Broek\",\n  \"Brouwer\",\n  \"Bruin\",\n  \"Dam\",\n  \"Dekker\",\n  \"Dijk\",\n  \"Dijkstra\",\n  \"Graaf\",\n  \"Groot\",\n  \"Haan\",\n  \"Hendriks\",\n  \"Heuvel\",\n  \"Hoek\",\n  \"Jacobs\",\n  \"Jansen\",\n  \"Janssen\",\n  \"Jong\",\n  \"Klein\",\n  \"Kok\",\n  \"Koning\",\n  \"Koster\",\n  \"Leeuwen\",\n  \"Linden\",\n  \"Maas\",\n  \"Meer\",\n  \"Meijer\",\n  \"Mulder\",\n  \"Peters\",\n  \"Ruiter\",\n  \"Schouten\",\n  \"Smit\",\n  \"Smits\",\n  \"Stichting\",\n  \"Veen\",\n  \"Ven\",\n  \"Vermeulen\",\n  \"Visser\",\n  \"Vliet\",\n  \"Vos\",\n  \"Vries\",\n  \"Wal\",\n  \"Willems\",\n  \"Wit\"\n];\n\n},{}],724:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{first_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{suffix}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{tussenvoegsel} #{last_name}\",\n  \"#{first_name} #{tussenvoegsel} #{last_name}\"\n];\n\n},{}],725:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Dhr.\",\n  \"Mevr. Dr.\",\n  \"Bsc\",\n  \"Msc\",\n  \"Prof.\"\n];\n\n},{}],726:[function(require,module,exports){\nmodule.exports=require(680)\n},{\"/Users/a/dev/faker.js/lib/locales/nb_NO/name/suffix.js\":680}],727:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"van\",\n  \"van de\",\n  \"van den\",\n  \"van 't\",\n  \"van het\",\n  \"de\",\n  \"den\"\n];\n\n},{}],728:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"(####) ######\",\n  \"##########\",\n  \"06########\",\n  \"06 #### ####\"\n];\n\n},{}],729:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":728,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],730:[function(require,module,exports){\nmodule.exports=require(179)\n},{\"/Users/a/dev/faker.js/lib/locales/en/address/building_number.js\":179}],731:[function(require,module,exports){\nmodule.exports=require(55)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/city.js\":55}],732:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aleksandrów Kujawski\",\n  \"Aleksandrów Łódzki\",\n  \"Alwernia\",\n  \"Andrychów\",\n  \"Annopol\",\n  \"Augustów\",\n  \"Babimost\",\n  \"Baborów\",\n  \"Baranów Sandomierski\",\n  \"Barcin\",\n  \"Barczewo\",\n  \"Bardo\",\n  \"Barlinek\",\n  \"Bartoszyce\",\n  \"Barwice\",\n  \"Bełchatów\",\n  \"Bełżyce\",\n  \"Będzin\",\n  \"Biała\",\n  \"Biała Piska\",\n  \"Biała Podlaska\",\n  \"Biała Rawska\",\n  \"Białobrzegi\",\n  \"Białogard\",\n  \"Biały Bór\",\n  \"Białystok\",\n  \"Biecz\",\n  \"Bielawa\",\n  \"Bielsk Podlaski\",\n  \"Bielsko-Biała\",\n  \"Bieruń\",\n  \"Bierutów\",\n  \"Bieżuń\",\n  \"Biłgoraj\",\n  \"Biskupiec\",\n  \"Bisztynek\",\n  \"Blachownia\",\n  \"Błaszki\",\n  \"Błażowa\",\n  \"Błonie\",\n  \"Bobolice\",\n  \"Bobowa\",\n  \"Bochnia\",\n  \"Bodzentyn\",\n  \"Bogatynia\",\n  \"Boguchwała\",\n  \"Boguszów-Gorce\",\n  \"Bojanowo\",\n  \"Bolesławiec\",\n  \"Bolków\",\n  \"Borek Wielkopolski\",\n  \"Borne Sulinowo\",\n  \"Braniewo\",\n  \"Brańsk\",\n  \"Brodnica\",\n  \"Brok\",\n  \"Brusy\",\n  \"Brwinów\",\n  \"Brzeg\",\n  \"Brzeg Dolny\",\n  \"Brzesko\",\n  \"Brzeszcze\",\n  \"Brześć Kujawski\",\n  \"Brzeziny\",\n  \"Brzostek\",\n  \"Brzozów\",\n  \"Buk\",\n  \"Bukowno\",\n  \"Busko-Zdrój\",\n  \"Bychawa\",\n  \"Byczyna\",\n  \"Bydgoszcz\",\n  \"Bystrzyca Kłodzka\",\n  \"Bytom\",\n  \"Bytom Odrzański\",\n  \"Bytów\",\n  \"Cedynia\",\n  \"Chełm\",\n  \"Chełmek\",\n  \"Chełmno\",\n  \"Chełmża\",\n  \"Chęciny\",\n  \"Chmielnik\",\n  \"Chocianów\",\n  \"Chociwel\",\n  \"Chodecz\",\n  \"Chodzież\",\n  \"Chojna\",\n  \"Chojnice\",\n  \"Chojnów\",\n  \"Choroszcz\",\n  \"Chorzele\",\n  \"Chorzów\",\n  \"Choszczno\",\n  \"Chrzanów\",\n  \"Ciechanowiec\",\n  \"Ciechanów\",\n  \"Ciechocinek\",\n  \"Cieszanów\",\n  \"Cieszyn\",\n  \"Ciężkowice\",\n  \"Cybinka\",\n  \"Czaplinek\",\n  \"Czarna Białostocka\",\n  \"Czarna Woda\",\n  \"Czarne\",\n  \"Czarnków\",\n  \"Czchów\",\n  \"Czechowice-Dziedzice\",\n  \"Czeladź\",\n  \"Czempiń\",\n  \"Czerniejewo\",\n  \"Czersk\",\n  \"Czerwieńsk\",\n  \"Czerwionka-Leszczyny\",\n  \"Częstochowa\",\n  \"Człopa\",\n  \"Człuchów\",\n  \"Czyżew\",\n  \"Ćmielów\",\n  \"Daleszyce\",\n  \"Darłowo\",\n  \"Dąbie\",\n  \"Dąbrowa Białostocka\",\n  \"Dąbrowa Górnicza\",\n  \"Dąbrowa Tarnowska\",\n  \"Debrzno\",\n  \"Dębica\",\n  \"Dęblin\",\n  \"Dębno\",\n  \"Dobczyce\",\n  \"Dobiegniew\",\n  \"Dobra (powiat łobeski)\",\n  \"Dobra (powiat turecki)\",\n  \"Dobre Miasto\",\n  \"Dobrodzień\",\n  \"Dobrzany\",\n  \"Dobrzyń nad Wisłą\",\n  \"Dolsk\",\n  \"Drawno\",\n  \"Drawsko Pomorskie\",\n  \"Drezdenko\",\n  \"Drobin\",\n  \"Drohiczyn\",\n  \"Drzewica\",\n  \"Dukla\",\n  \"Duszniki-Zdrój\",\n  \"Dynów\",\n  \"Działdowo\",\n  \"Działoszyce\",\n  \"Działoszyn\",\n  \"Dzierzgoń\",\n  \"Dzierżoniów\",\n  \"Dziwnów\",\n  \"Elbląg\",\n  \"Ełk\",\n  \"Frampol\",\n  \"Frombork\",\n  \"Garwolin\",\n  \"Gąbin\",\n  \"Gdańsk\",\n  \"Gdynia\",\n  \"Giżycko\",\n  \"Glinojeck\",\n  \"Gliwice\",\n  \"Głogów\",\n  \"Głogów Małopolski\",\n  \"Głogówek\",\n  \"Głowno\",\n  \"Głubczyce\",\n  \"Głuchołazy\",\n  \"Głuszyca\",\n  \"Gniew\",\n  \"Gniewkowo\",\n  \"Gniezno\",\n  \"Gogolin\",\n  \"Golczewo\",\n  \"Goleniów\",\n  \"Golina\",\n  \"Golub-Dobrzyń\",\n  \"Gołańcz\",\n  \"Gołdap\",\n  \"Goniądz\",\n  \"Gorlice\",\n  \"Gorzów Śląski\",\n  \"Gorzów Wielkopolski\",\n  \"Gostynin\",\n  \"Gostyń\",\n  \"Gościno\",\n  \"Gozdnica\",\n  \"Góra\",\n  \"Góra Kalwaria\",\n  \"Górowo Iławeckie\",\n  \"Górzno\",\n  \"Grabów nad Prosną\",\n  \"Grajewo\",\n  \"Grodków\",\n  \"Grodzisk Mazowiecki\",\n  \"Grodzisk Wielkopolski\",\n  \"Grójec\",\n  \"Grudziądz\",\n  \"Grybów\",\n  \"Gryfice\",\n  \"Gryfino\",\n  \"Gryfów Śląski\",\n  \"Gubin\",\n  \"Hajnówka\",\n  \"Halinów\",\n  \"Hel\",\n  \"Hrubieszów\",\n  \"Iława\",\n  \"Iłowa\",\n  \"Iłża\",\n  \"Imielin\",\n  \"Inowrocław\",\n  \"Ińsko\",\n  \"Iwonicz-Zdrój\",\n  \"Izbica Kujawska\",\n  \"Jabłonowo Pomorskie\",\n  \"Janikowo\",\n  \"Janowiec Wielkopolski\",\n  \"Janów Lubelski\",\n  \"Jarocin\",\n  \"Jarosław\",\n  \"Jasień\",\n  \"Jasło\",\n  \"Jastarnia\",\n  \"Jastrowie\",\n  \"Jastrzębie-Zdrój\",\n  \"Jawor\",\n  \"Jaworzno\",\n  \"Jaworzyna Śląska\",\n  \"Jedlicze\",\n  \"Jedlina-Zdrój\",\n  \"Jedwabne\",\n  \"Jelcz-Laskowice\",\n  \"Jelenia Góra\",\n  \"Jeziorany\",\n  \"Jędrzejów\",\n  \"Jordanów\",\n  \"Józefów (powiat biłgorajski)\",\n  \"Józefów (powiat otwocki)\",\n  \"Jutrosin\",\n  \"Kalety\",\n  \"Kalisz\",\n  \"Kalisz Pomorski\",\n  \"Kalwaria Zebrzydowska\",\n  \"Kałuszyn\",\n  \"Kamienna Góra\",\n  \"Kamień Krajeński\",\n  \"Kamień Pomorski\",\n  \"Kamieńsk\",\n  \"Kańczuga\",\n  \"Karczew\",\n  \"Kargowa\",\n  \"Karlino\",\n  \"Karpacz\",\n  \"Kartuzy\",\n  \"Katowice\",\n  \"Kazimierz Dolny\",\n  \"Kazimierza Wielka\",\n  \"Kąty Wrocławskie\",\n  \"Kcynia\",\n  \"Kędzierzyn-Koźle\",\n  \"Kępice\",\n  \"Kępno\",\n  \"Kętrzyn\",\n  \"Kęty\",\n  \"Kielce\",\n  \"Kietrz\",\n  \"Kisielice\",\n  \"Kleczew\",\n  \"Kleszczele\",\n  \"Kluczbork\",\n  \"Kłecko\",\n  \"Kłobuck\",\n  \"Kłodawa\",\n  \"Kłodzko\",\n  \"Knurów\",\n  \"Knyszyn\",\n  \"Kobylin\",\n  \"Kobyłka\",\n  \"Kock\",\n  \"Kolbuszowa\",\n  \"Kolno\",\n  \"Kolonowskie\",\n  \"Koluszki\",\n  \"Kołaczyce\",\n  \"Koło\",\n  \"Kołobrzeg\",\n  \"Koniecpol\",\n  \"Konin\",\n  \"Konstancin-Jeziorna\",\n  \"Konstantynów Łódzki\",\n  \"Końskie\",\n  \"Koprzywnica\",\n  \"Korfantów\",\n  \"Koronowo\",\n  \"Korsze\",\n  \"Kosów Lacki\",\n  \"Kostrzyn\",\n  \"Kostrzyn nad Odrą\",\n  \"Koszalin\",\n  \"Kościan\",\n  \"Kościerzyna\",\n  \"Kowal\",\n  \"Kowalewo Pomorskie\",\n  \"Kowary\",\n  \"Koziegłowy\",\n  \"Kozienice\",\n  \"Koźmin Wielkopolski\",\n  \"Kożuchów\",\n  \"Kórnik\",\n  \"Krajenka\",\n  \"Kraków\",\n  \"Krapkowice\",\n  \"Krasnobród\",\n  \"Krasnystaw\",\n  \"Kraśnik\",\n  \"Krobia\",\n  \"Krosno\",\n  \"Krosno Odrzańskie\",\n  \"Krośniewice\",\n  \"Krotoszyn\",\n  \"Kruszwica\",\n  \"Krynica Morska\",\n  \"Krynica-Zdrój\",\n  \"Krynki\",\n  \"Krzanowice\",\n  \"Krzepice\",\n  \"Krzeszowice\",\n  \"Krzywiń\",\n  \"Krzyż Wielkopolski\",\n  \"Książ Wielkopolski\",\n  \"Kudowa-Zdrój\",\n  \"Kunów\",\n  \"Kutno\",\n  \"Kuźnia Raciborska\",\n  \"Kwidzyn\",\n  \"Lądek-Zdrój\",\n  \"Legionowo\",\n  \"Legnica\",\n  \"Lesko\",\n  \"Leszno\",\n  \"Leśna\",\n  \"Leśnica\",\n  \"Lewin Brzeski\",\n  \"Leżajsk\",\n  \"Lębork\",\n  \"Lędziny\",\n  \"Libiąż\",\n  \"Lidzbark\",\n  \"Lidzbark Warmiński\",\n  \"Limanowa\",\n  \"Lipiany\",\n  \"Lipno\",\n  \"Lipsk\",\n  \"Lipsko\",\n  \"Lubaczów\",\n  \"Lubań\",\n  \"Lubartów\",\n  \"Lubawa\",\n  \"Lubawka\",\n  \"Lubień Kujawski\",\n  \"Lubin\",\n  \"Lublin\",\n  \"Lubliniec\",\n  \"Lubniewice\",\n  \"Lubomierz\",\n  \"Luboń\",\n  \"Lubraniec\",\n  \"Lubsko\",\n  \"Lwówek\",\n  \"Lwówek Śląski\",\n  \"Łabiszyn\",\n  \"Łańcut\",\n  \"Łapy\",\n  \"Łasin\",\n  \"Łask\",\n  \"Łaskarzew\",\n  \"Łaszczów\",\n  \"Łaziska Górne\",\n  \"Łazy\",\n  \"Łeba\",\n  \"Łęczna\",\n  \"Łęczyca\",\n  \"Łęknica\",\n  \"Łobez\",\n  \"Łobżenica\",\n  \"Łochów\",\n  \"Łomianki\",\n  \"Łomża\",\n  \"Łosice\",\n  \"Łowicz\",\n  \"Łódź\",\n  \"Łuków\",\n  \"Maków Mazowiecki\",\n  \"Maków Podhalański\",\n  \"Malbork\",\n  \"Małogoszcz\",\n  \"Małomice\",\n  \"Margonin\",\n  \"Marki\",\n  \"Maszewo\",\n  \"Miasteczko Śląskie\",\n  \"Miastko\",\n  \"Michałowo\",\n  \"Miechów\",\n  \"Miejska Górka\",\n  \"Mielec\",\n  \"Mieroszów\",\n  \"Mieszkowice\",\n  \"Międzybórz\",\n  \"Międzychód\",\n  \"Międzylesie\",\n  \"Międzyrzec Podlaski\",\n  \"Międzyrzecz\",\n  \"Międzyzdroje\",\n  \"Mikołajki\",\n  \"Mikołów\",\n  \"Mikstat\",\n  \"Milanówek\",\n  \"Milicz\",\n  \"Miłakowo\",\n  \"Miłomłyn\",\n  \"Miłosław\",\n  \"Mińsk Mazowiecki\",\n  \"Mirosławiec\",\n  \"Mirsk\",\n  \"Mława\",\n  \"Młynary\",\n  \"Mogielnica\",\n  \"Mogilno\",\n  \"Mońki\",\n  \"Morąg\",\n  \"Mordy\",\n  \"Moryń\",\n  \"Mosina\",\n  \"Mrągowo\",\n  \"Mrocza\",\n  \"Mszana Dolna\",\n  \"Mszczonów\",\n  \"Murowana Goślina\",\n  \"Muszyna\",\n  \"Mysłowice\",\n  \"Myszków\",\n  \"Myszyniec\",\n  \"Myślenice\",\n  \"Myślibórz\",\n  \"Nakło nad Notecią\",\n  \"Nałęczów\",\n  \"Namysłów\",\n  \"Narol\",\n  \"Nasielsk\",\n  \"Nekla\",\n  \"Nidzica\",\n  \"Niemcza\",\n  \"Niemodlin\",\n  \"Niepołomice\",\n  \"Nieszawa\",\n  \"Nisko\",\n  \"Nowa Dęba\",\n  \"Nowa Ruda\",\n  \"Nowa Sarzyna\",\n  \"Nowa Sól\",\n  \"Nowe\",\n  \"Nowe Brzesko\",\n  \"Nowe Miasteczko\",\n  \"Nowe Miasto Lubawskie\",\n  \"Nowe Miasto nad Pilicą\",\n  \"Nowe Skalmierzyce\",\n  \"Nowe Warpno\",\n  \"Nowogard\",\n  \"Nowogrodziec\",\n  \"Nowogród\",\n  \"Nowogród Bobrzański\",\n  \"Nowy Dwór Gdański\",\n  \"Nowy Dwór Mazowiecki\",\n  \"Nowy Sącz\",\n  \"Nowy Staw\",\n  \"Nowy Targ\",\n  \"Nowy Tomyśl\",\n  \"Nowy Wiśnicz\",\n  \"Nysa\",\n  \"Oborniki\",\n  \"Oborniki Śląskie\",\n  \"Obrzycko\",\n  \"Odolanów\",\n  \"Ogrodzieniec\",\n  \"Okonek\",\n  \"Olecko\",\n  \"Olesno\",\n  \"Oleszyce\",\n  \"Oleśnica\",\n  \"Olkusz\",\n  \"Olsztyn\",\n  \"Olsztynek\",\n  \"Olszyna\",\n  \"Oława\",\n  \"Opalenica\",\n  \"Opatów\",\n  \"Opoczno\",\n  \"Opole\",\n  \"Opole Lubelskie\",\n  \"Orneta\",\n  \"Orzesze\",\n  \"Orzysz\",\n  \"Osieczna\",\n  \"Osiek\",\n  \"Ostrołęka\",\n  \"Ostroróg\",\n  \"Ostrowiec Świętokrzyski\",\n  \"Ostróda\",\n  \"Ostrów Lubelski\",\n  \"Ostrów Mazowiecka\",\n  \"Ostrów Wielkopolski\",\n  \"Ostrzeszów\",\n  \"Ośno Lubuskie\",\n  \"Oświęcim\",\n  \"Otmuchów\",\n  \"Otwock\",\n  \"Ozimek\",\n  \"Ozorków\",\n  \"Ożarów\",\n  \"Ożarów Mazowiecki\",\n  \"Pabianice\",\n  \"Paczków\",\n  \"Pajęczno\",\n  \"Pakość\",\n  \"Parczew\",\n  \"Pasłęk\",\n  \"Pasym\",\n  \"Pelplin\",\n  \"Pełczyce\",\n  \"Piaseczno\",\n  \"Piaski\",\n  \"Piastów\",\n  \"Piechowice\",\n  \"Piekary Śląskie\",\n  \"Pieniężno\",\n  \"Pieńsk\",\n  \"Pieszyce\",\n  \"Pilawa\",\n  \"Pilica\",\n  \"Pilzno\",\n  \"Piła\",\n  \"Piława Górna\",\n  \"Pińczów\",\n  \"Pionki\",\n  \"Piotrków Kujawski\",\n  \"Piotrków Trybunalski\",\n  \"Pisz\",\n  \"Piwniczna-Zdrój\",\n  \"Pleszew\",\n  \"Płock\",\n  \"Płońsk\",\n  \"Płoty\",\n  \"Pniewy\",\n  \"Pobiedziska\",\n  \"Poddębice\",\n  \"Podkowa Leśna\",\n  \"Pogorzela\",\n  \"Polanica-Zdrój\",\n  \"Polanów\",\n  \"Police\",\n  \"Polkowice\",\n  \"Połaniec\",\n  \"Połczyn-Zdrój\",\n  \"Poniatowa\",\n  \"Poniec\",\n  \"Poręba\",\n  \"Poznań\",\n  \"Prabuty\",\n  \"Praszka\",\n  \"Prochowice\",\n  \"Proszowice\",\n  \"Prószków\",\n  \"Pruchnik\",\n  \"Prudnik\",\n  \"Prusice\",\n  \"Pruszcz Gdański\",\n  \"Pruszków\",\n  \"Przasnysz\",\n  \"Przecław\",\n  \"Przedbórz\",\n  \"Przedecz\",\n  \"Przemków\",\n  \"Przemyśl\",\n  \"Przeworsk\",\n  \"Przysucha\",\n  \"Pszczyna\",\n  \"Pszów\",\n  \"Puck\",\n  \"Puławy\",\n  \"Pułtusk\",\n  \"Puszczykowo\",\n  \"Pyrzyce\",\n  \"Pyskowice\",\n  \"Pyzdry\",\n  \"Rabka-Zdrój\",\n  \"Raciąż\",\n  \"Racibórz\",\n  \"Radków\",\n  \"Radlin\",\n  \"Radłów\",\n  \"Radom\",\n  \"Radomsko\",\n  \"Radomyśl Wielki\",\n  \"Radymno\",\n  \"Radziejów\",\n  \"Radzionków\",\n  \"Radzymin\",\n  \"Radzyń Chełmiński\",\n  \"Radzyń Podlaski\",\n  \"Rajgród\",\n  \"Rakoniewice\",\n  \"Raszków\",\n  \"Rawa Mazowiecka\",\n  \"Rawicz\",\n  \"Recz\",\n  \"Reda\",\n  \"Rejowiec Fabryczny\",\n  \"Resko\",\n  \"Reszel\",\n  \"Rogoźno\",\n  \"Ropczyce\",\n  \"Różan\",\n  \"Ruciane-Nida\",\n  \"Ruda Śląska\",\n  \"Rudnik nad Sanem\",\n  \"Rumia\",\n  \"Rybnik\",\n  \"Rychwał\",\n  \"Rydułtowy\",\n  \"Rydzyna\",\n  \"Ryglice\",\n  \"Ryki\",\n  \"Rymanów\",\n  \"Ryn\",\n  \"Rypin\",\n  \"Rzepin\",\n  \"Rzeszów\",\n  \"Rzgów\",\n  \"Sandomierz\",\n  \"Sanok\",\n  \"Sejny\",\n  \"Serock\",\n  \"Sędziszów\",\n  \"Sędziszów Małopolski\",\n  \"Sępopol\",\n  \"Sępólno Krajeńskie\",\n  \"Sianów\",\n  \"Siechnice\",\n  \"Siedlce\",\n  \"Siemianowice Śląskie\",\n  \"Siemiatycze\",\n  \"Sieniawa\",\n  \"Sieradz\",\n  \"Sieraków\",\n  \"Sierpc\",\n  \"Siewierz\",\n  \"Skalbmierz\",\n  \"Skała\",\n  \"Skarszewy\",\n  \"Skaryszew\",\n  \"Skarżysko-Kamienna\",\n  \"Skawina\",\n  \"Skępe\",\n  \"Skierniewice\",\n  \"Skoczów\",\n  \"Skoki\",\n  \"Skórcz\",\n  \"Skwierzyna\",\n  \"Sława\",\n  \"Sławków\",\n  \"Sławno\",\n  \"Słomniki\",\n  \"Słubice\",\n  \"Słupca\",\n  \"Słupsk\",\n  \"Sobótka\",\n  \"Sochaczew\",\n  \"Sokołów Małopolski\",\n  \"Sokołów Podlaski\",\n  \"Sokółka\",\n  \"Solec Kujawski\",\n  \"Sompolno\",\n  \"Sopot\",\n  \"Sosnowiec\",\n  \"Sośnicowice\",\n  \"Stalowa Wola\",\n  \"Starachowice\",\n  \"Stargard Szczeciński\",\n  \"Starogard Gdański\",\n  \"Stary Sącz\",\n  \"Staszów\",\n  \"Stawiski\",\n  \"Stawiszyn\",\n  \"Stąporków\",\n  \"Stęszew\",\n  \"Stoczek Łukowski\",\n  \"Stronie Śląskie\",\n  \"Strumień\",\n  \"Stryków\",\n  \"Strzegom\",\n  \"Strzelce Krajeńskie\",\n  \"Strzelce Opolskie\",\n  \"Strzelin\",\n  \"Strzelno\",\n  \"Strzyżów\",\n  \"Sucha Beskidzka\",\n  \"Suchań\",\n  \"Suchedniów\",\n  \"Suchowola\",\n  \"Sulechów\",\n  \"Sulejów\",\n  \"Sulejówek\",\n  \"Sulęcin\",\n  \"Sulmierzyce\",\n  \"Sułkowice\",\n  \"Supraśl\",\n  \"Suraż\",\n  \"Susz\",\n  \"Suwałki\",\n  \"Swarzędz\",\n  \"Syców\",\n  \"Szadek\",\n  \"Szamocin\",\n  \"Szamotuły\",\n  \"Szczawnica\",\n  \"Szczawno-Zdrój\",\n  \"Szczebrzeszyn\",\n  \"Szczecin\",\n  \"Szczecinek\",\n  \"Szczekociny\",\n  \"Szczucin\",\n  \"Szczuczyn\",\n  \"Szczyrk\",\n  \"Szczytna\",\n  \"Szczytno\",\n  \"Szepietowo\",\n  \"Szklarska Poręba\",\n  \"Szlichtyngowa\",\n  \"Szprotawa\",\n  \"Sztum\",\n  \"Szubin\",\n  \"Szydłowiec\",\n  \"Ścinawa\",\n  \"Ślesin\",\n  \"Śmigiel\",\n  \"Śrem\",\n  \"Środa Śląska\",\n  \"Środa Wielkopolska\",\n  \"Świątniki Górne\",\n  \"Świdnica\",\n  \"Świdnik\",\n  \"Świdwin\",\n  \"Świebodzice\",\n  \"Świebodzin\",\n  \"Świecie\",\n  \"Świeradów-Zdrój\",\n  \"Świerzawa\",\n  \"Świętochłowice\",\n  \"Świnoujście\",\n  \"Tarczyn\",\n  \"Tarnobrzeg\",\n  \"Tarnogród\",\n  \"Tarnowskie Góry\",\n  \"Tarnów\",\n  \"Tczew\",\n  \"Terespol\",\n  \"Tłuszcz\",\n  \"Tolkmicko\",\n  \"Tomaszów Lubelski\",\n  \"Tomaszów Mazowiecki\",\n  \"Toruń\",\n  \"Torzym\",\n  \"Toszek\",\n  \"Trzcianka\",\n  \"Trzciel\",\n  \"Trzcińsko-Zdrój\",\n  \"Trzebiatów\",\n  \"Trzebinia\",\n  \"Trzebnica\",\n  \"Trzemeszno\",\n  \"Tuchola\",\n  \"Tuchów\",\n  \"Tuczno\",\n  \"Tuliszków\",\n  \"Turek\",\n  \"Tuszyn\",\n  \"Twardogóra\",\n  \"Tychowo\",\n  \"Tychy\",\n  \"Tyczyn\",\n  \"Tykocin\",\n  \"Tyszowce\",\n  \"Ujazd\",\n  \"Ujście\",\n  \"Ulanów\",\n  \"Uniejów\",\n  \"Ustka\",\n  \"Ustroń\",\n  \"Ustrzyki Dolne\",\n  \"Wadowice\",\n  \"Wałbrzych\",\n  \"Wałcz\",\n  \"Warka\",\n  \"Warszawa\",\n  \"Warta\",\n  \"Wasilków\",\n  \"Wąbrzeźno\",\n  \"Wąchock\",\n  \"Wągrowiec\",\n  \"Wąsosz\",\n  \"Wejherowo\",\n  \"Węgliniec\",\n  \"Węgorzewo\",\n  \"Węgorzyno\",\n  \"Węgrów\",\n  \"Wiązów\",\n  \"Wieleń\",\n  \"Wielichowo\",\n  \"Wieliczka\",\n  \"Wieluń\",\n  \"Wieruszów\",\n  \"Więcbork\",\n  \"Wilamowice\",\n  \"Wisła\",\n  \"Witkowo\",\n  \"Witnica\",\n  \"Wleń\",\n  \"Władysławowo\",\n  \"Włocławek\",\n  \"Włodawa\",\n  \"Włoszczowa\",\n  \"Wodzisław Śląski\",\n  \"Wojcieszów\",\n  \"Wojkowice\",\n  \"Wojnicz\",\n  \"Wolbórz\",\n  \"Wolbrom\",\n  \"Wolin\",\n  \"Wolsztyn\",\n  \"Wołczyn\",\n  \"Wołomin\",\n  \"Wołów\",\n  \"Woźniki\",\n  \"Wrocław\",\n  \"Wronki\",\n  \"Września\",\n  \"Wschowa\",\n  \"Wyrzysk\",\n  \"Wysoka\",\n  \"Wysokie Mazowieckie\",\n  \"Wyszków\",\n  \"Wyszogród\",\n  \"Wyśmierzyce\",\n  \"Zabłudów\",\n  \"Zabrze\",\n  \"Zagórów\",\n  \"Zagórz\",\n  \"Zakliczyn\",\n  \"Zakopane\",\n  \"Zakroczym\",\n  \"Zalewo\",\n  \"Zambrów\",\n  \"Zamość\",\n  \"Zator\",\n  \"Zawadzkie\",\n  \"Zawichost\",\n  \"Zawidów\",\n  \"Zawiercie\",\n  \"Ząbki\",\n  \"Ząbkowice Śląskie\",\n  \"Zbąszynek\",\n  \"Zbąszyń\",\n  \"Zduny\",\n  \"Zduńska Wola\",\n  \"Zdzieszowice\",\n  \"Zelów\",\n  \"Zgierz\",\n  \"Zgorzelec\",\n  \"Zielona Góra\",\n  \"Zielonka\",\n  \"Ziębice\",\n  \"Złocieniec\",\n  \"Złoczew\",\n  \"Złotoryja\",\n  \"Złotów\",\n  \"Złoty Stok\",\n  \"Zwierzyniec\",\n  \"Zwoleń\",\n  \"Żabno\",\n  \"Żagań\",\n  \"Żarki\",\n  \"Żarów\",\n  \"Żary\",\n  \"Żelechów\",\n  \"Żerków\",\n  \"Żmigród\",\n  \"Żnin\",\n  \"Żory\",\n  \"Żukowo\",\n  \"Żuromin\",\n  \"Żychlin\",\n  \"Żyrardów\",\n  \"Żywiec\"\n];\n\n},{}],733:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afganistan\",\n  \"Albania\",\n  \"Algieria\",\n  \"Andora\",\n  \"Angola\",\n  \"Antigua i Barbuda\",\n  \"Arabia Saudyjska\",\n  \"Argentyna\",\n  \"Armenia\",\n  \"Australia\",\n  \"Austria\",\n  \"Azerbejdżan\",\n  \"Bahamy\",\n  \"Bahrajn\",\n  \"Bangladesz\",\n  \"Barbados\",\n  \"Belgia\",\n  \"Belize\",\n  \"Benin\",\n  \"Bhutan\",\n  \"Białoruś\",\n  \"Birma\",\n  \"Boliwia\",\n  \"Sucre\",\n  \"Bośnia i Hercegowina\",\n  \"Botswana\",\n  \"Brazylia\",\n  \"Brunei\",\n  \"Bułgaria\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Chile\",\n  \"Chiny\",\n  \"Chorwacja\",\n  \"Cypr\",\n  \"Czad\",\n  \"Czarnogóra\",\n  \"Czechy\",\n  \"Dania\",\n  \"Demokratyczna Republika Konga\",\n  \"Dominika\",\n  \"Dominikana\",\n  \"Dżibuti\",\n  \"Egipt\",\n  \"Ekwador\",\n  \"Erytrea\",\n  \"Estonia\",\n  \"Etiopia\",\n  \"Fidżi\",\n  \"Filipiny\",\n  \"Finlandia\",\n  \"Francja\",\n  \"Gabon\",\n  \"Gambia\",\n  \"Ghana\",\n  \"Grecja\",\n  \"Grenada\",\n  \"Gruzja\",\n  \"Gujana\",\n  \"Gwatemala\",\n  \"Gwinea\",\n  \"Gwinea Bissau\",\n  \"Gwinea Równikowa\",\n  \"Haiti\",\n  \"Hiszpania\",\n  \"Holandia\",\n  \"Haga\",\n  \"Honduras\",\n  \"Indie\",\n  \"Indonezja\",\n  \"Irak\",\n  \"Iran\",\n  \"Irlandia\",\n  \"Islandia\",\n  \"Izrael\",\n  \"Jamajka\",\n  \"Japonia\",\n  \"Jemen\",\n  \"Jordania\",\n  \"Kambodża\",\n  \"Kamerun\",\n  \"Kanada\",\n  \"Katar\",\n  \"Kazachstan\",\n  \"Kenia\",\n  \"Kirgistan\",\n  \"Kiribati\",\n  \"Kolumbia\",\n  \"Komory\",\n  \"Kongo\",\n  \"Korea Południowa\",\n  \"Korea Północna\",\n  \"Kostaryka\",\n  \"Kuba\",\n  \"Kuwejt\",\n  \"Laos\",\n  \"Lesotho\",\n  \"Liban\",\n  \"Liberia\",\n  \"Libia\",\n  \"Liechtenstein\",\n  \"Litwa\",\n  \"Luksemburg\",\n  \"Łotwa\",\n  \"Macedonia\",\n  \"Madagaskar\",\n  \"Malawi\",\n  \"Malediwy\",\n  \"Malezja\",\n  \"Mali\",\n  \"Malta\",\n  \"Maroko\",\n  \"Mauretania\",\n  \"Mauritius\",\n  \"Meksyk\",\n  \"Mikronezja\",\n  \"Mołdawia\",\n  \"Monako\",\n  \"Mongolia\",\n  \"Mozambik\",\n  \"Namibia\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Niemcy\",\n  \"Niger\",\n  \"Nigeria\",\n  \"Nikaragua\",\n  \"Norwegia\",\n  \"Nowa Zelandia\",\n  \"Oman\",\n  \"Pakistan\",\n  \"Palau\",\n  \"Panama\",\n  \"Papua-Nowa Gwinea\",\n  \"Paragwaj\",\n  \"Peru\",\n  \"Polska\",\n  \"322 575\",\n  \"Portugalia\",\n  \"Republika Południowej Afryki\",\n  \"Republika Środkowoafrykańska\",\n  \"Republika Zielonego Przylądka\",\n  \"Rosja\",\n  \"Rumunia\",\n  \"Rwanda\",\n  \"Saint Kitts i Nevis\",\n  \"Saint Lucia\",\n  \"Saint Vincent i Grenadyny\",\n  \"Salwador\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Senegal\",\n  \"Serbia\",\n  \"Seszele\",\n  \"Sierra Leone\",\n  \"Singapur\",\n  \"Słowacja\",\n  \"Słowenia\",\n  \"Somalia\",\n  \"Sri Lanka\",\n  \"Stany Zjednoczone\",\n  \"Suazi\",\n  \"Sudan\",\n  \"Sudan Południowy\",\n  \"Surinam\",\n  \"Syria\",\n  \"Szwajcaria\",\n  \"Szwecja\",\n  \"Tadżykistan\",\n  \"Tajlandia\",\n  \"Tanzania\",\n  \"Timor Wschodni\",\n  \"Togo\",\n  \"Tonga\",\n  \"Trynidad i Tobago\",\n  \"Tunezja\",\n  \"Turcja\",\n  \"Turkmenistan\",\n  \"Tuvalu\",\n  \"Funafuti\",\n  \"Uganda\",\n  \"Ukraina\",\n  \"Urugwaj\",\n  2008,\n  \"Uzbekistan\",\n  \"Vanuatu\",\n  \"Watykan\",\n  \"Wenezuela\",\n  \"Węgry\",\n  \"Wielka Brytania\",\n  \"Wietnam\",\n  \"Włochy\",\n  \"Wybrzeże Kości Słoniowej\",\n  \"Wyspy Marshalla\",\n  \"Wyspy Salomona\",\n  \"Wyspy Świętego Tomasza i Książęca\",\n  \"Zambia\",\n  \"Zimbabwe\",\n  \"Zjednoczone Emiraty Arabskie\"\n];\n\n},{}],734:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Polska\"\n];\n\n},{}],735:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_prefix = require(\"./street_prefix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":730,\"./city\":731,\"./city_name\":732,\"./country\":733,\"./default_country\":734,\"./postcode\":736,\"./secondary_address\":737,\"./state\":738,\"./state_abbr\":739,\"./street_address\":740,\"./street_name\":741,\"./street_prefix\":742}],736:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"##-###\"\n];\n\n},{}],737:[function(require,module,exports){\nmodule.exports=require(61)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/secondary_address.js\":61}],738:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Dolnośląskie\",\n  \"Kujawsko-pomorskie\",\n  \"Lubelskie\",\n  \"Lubuskie\",\n  \"Łódzkie\",\n  \"Małopolskie\",\n  \"Mazowieckie\",\n  \"Opolskie\",\n  \"Podkarpackie\",\n  \"Podlaskie\",\n  \"Pomorskie\",\n  \"Śląskie\",\n  \"Świętokrzyskie\",\n  \"Warmińsko-mazurskie\",\n  \"Wielkopolskie\",\n  \"Zachodniopomorskie\"\n];\n\n},{}],739:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"DŚ\",\n  \"KP\",\n  \"LB\",\n  \"LS\",\n  \"ŁD\",\n  \"MP\",\n  \"MZ\",\n  \"OP\",\n  \"PK\",\n  \"PL\",\n  \"PM\",\n  \"ŚL\",\n  \"ŚK\",\n  \"WM\",\n  \"WP\",\n  \"ZP\"\n];\n\n},{}],740:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],741:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_prefix} #{Name.last_name}\"\n];\n\n},{}],742:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ul.\",\n  \"al.\"\n];\n\n},{}],743:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"50-###-##-##\",\n  \"51-###-##-##\",\n  \"53-###-##-##\",\n  \"57-###-##-##\",\n  \"60-###-##-##\",\n  \"66-###-##-##\",\n  \"69-###-##-##\",\n  \"72-###-##-##\",\n  \"73-###-##-##\",\n  \"78-###-##-##\",\n  \"79-###-##-##\",\n  \"88-###-##-##\"\n];\n\n},{}],744:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":743,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],745:[function(require,module,exports){\nmodule.exports=require(68)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/adjective.js\":68}],746:[function(require,module,exports){\nmodule.exports=require(212)\n},{\"/Users/a/dev/faker.js/lib/locales/en/company/bs_adjective.js\":212}],747:[function(require,module,exports){\nmodule.exports=require(213)\n},{\"/Users/a/dev/faker.js/lib/locales/en/company/bs_noun.js\":213}],748:[function(require,module,exports){\nmodule.exports=require(70)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/bs_verb.js\":70}],749:[function(require,module,exports){\nmodule.exports=require(71)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/descriptor.js\":71}],750:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.suffix = require(\"./suffix\");\ncompany.adjetive = require(\"./adjetive\");\ncompany.descriptor = require(\"./descriptor\");\ncompany.noun = require(\"./noun\");\ncompany.bs_verb = require(\"./bs_verb\");\ncompany.bs_adjective = require(\"./bs_adjective\");\ncompany.bs_noun = require(\"./bs_noun\");\ncompany.name = require(\"./name\");\n\n},{\"./adjetive\":745,\"./bs_adjective\":746,\"./bs_noun\":747,\"./bs_verb\":748,\"./descriptor\":749,\"./name\":751,\"./noun\":752,\"./suffix\":753}],751:[function(require,module,exports){\nmodule.exports=require(217)\n},{\"/Users/a/dev/faker.js/lib/locales/en/company/name.js\":217}],752:[function(require,module,exports){\nmodule.exports=require(74)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/noun.js\":74}],753:[function(require,module,exports){\nmodule.exports=require(219)\n},{\"/Users/a/dev/faker.js/lib/locales/en/company/suffix.js\":219}],754:[function(require,module,exports){\nvar pl = {};\nmodule['exports'] = pl;\npl.title = \"Polish\";\npl.name = require(\"./name\");\npl.address = require(\"./address\");\npl.company = require(\"./company\");\npl.internet = require(\"./internet\");\npl.lorem = require(\"./lorem\");\npl.phone_number = require(\"./phone_number\");\npl.cell_phone = require(\"./cell_phone\");\n\n},{\"./address\":735,\"./cell_phone\":744,\"./company\":750,\"./internet\":757,\"./lorem\":758,\"./name\":762,\"./phone_number\":768}],755:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"pl\",\n  \"com.pl\",\n  \"net\",\n  \"org\"\n];\n\n},{}],756:[function(require,module,exports){\nmodule.exports=require(119)\n},{\"/Users/a/dev/faker.js/lib/locales/de/internet/free_email.js\":119}],757:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":755,\"./free_email\":756,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],758:[function(require,module,exports){\nmodule.exports=require(83)\n},{\"./supplemental\":759,\"./words\":760,\"/Users/a/dev/faker.js/lib/locales/cz/lorem/index.js\":83}],759:[function(require,module,exports){\nmodule.exports=require(84)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/supplemental.js\":84}],760:[function(require,module,exports){\nmodule.exports=require(85)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/words.js\":85}],761:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aaron\",\n  \"Abraham\",\n  \"Adam\",\n  \"Adrian\",\n  \"Atanazy\",\n  \"Agaton\",\n  \"Alan\",\n  \"Albert\",\n  \"Aleksander\",\n  \"Aleksy\",\n  \"Alfred\",\n  \"Alwar\",\n  \"Ambroży\",\n  \"Anatol\",\n  \"Andrzej\",\n  \"Antoni\",\n  \"Apollinary\",\n  \"Apollo\",\n  \"Arkady\",\n  \"Arkadiusz\",\n  \"Archibald\",\n  \"Arystarch\",\n  \"Arnold\",\n  \"Arseniusz\",\n  \"Artur\",\n  \"August\",\n  \"Baldwin\",\n  \"Bazyli\",\n  \"Benedykt\",\n  \"Beniamin\",\n  \"Bernard\",\n  \"Bertrand\",\n  \"Bertram\",\n  \"Borys\",\n  \"Brajan\",\n  \"Bruno\",\n  \"Cezary\",\n  \"Cecyliusz\",\n  \"Karol\",\n  \"Krystian\",\n  \"Krzysztof\",\n  \"Klarencjusz\",\n  \"Klaudiusz\",\n  \"Klemens\",\n  \"Konrad\",\n  \"Konstanty\",\n  \"Konstantyn\",\n  \"Kornel\",\n  \"Korneliusz\",\n  \"Korneli\",\n  \"Cyryl\",\n  \"Cyrus\",\n  \"Damian\",\n  \"Daniel\",\n  \"Dariusz\",\n  \"Dawid\",\n  \"Dionizy\",\n  \"Demetriusz\",\n  \"Dominik\",\n  \"Donald\",\n  \"Dorian\",\n  \"Edgar\",\n  \"Edmund\",\n  \"Edward\",\n  \"Edwin\",\n  \"Efrem\",\n  \"Efraim\",\n  \"Eliasz\",\n  \"Eleazar\",\n  \"Emil\",\n  \"Emanuel\",\n  \"Erast\",\n  \"Ernest\",\n  \"Eugeniusz\",\n  \"Eustracjusz\",\n  \"Fabian\",\n  \"Feliks\",\n  \"Florian\",\n  \"Franciszek\",\n  \"Fryderyk\",\n  \"Gabriel\",\n  \"Gedeon\",\n  \"Galfryd\",\n  \"Jerzy\",\n  \"Gerald\",\n  \"Gerazym\",\n  \"Gilbert\",\n  \"Gonsalwy\",\n  \"Grzegorz\",\n  \"Gwido\",\n  \"Harald\",\n  \"Henryk\",\n  \"Herbert\",\n  \"Herman\",\n  \"Hilary\",\n  \"Horacy\",\n  \"Hubert\",\n  \"Hugo\",\n  \"Ignacy\",\n  \"Igor\",\n  \"Hilarion\",\n  \"Innocenty\",\n  \"Hipolit\",\n  \"Ireneusz\",\n  \"Erwin\",\n  \"Izaak\",\n  \"Izajasz\",\n  \"Izydor\",\n  \"Jakub\",\n  \"Jeremi\",\n  \"Jeremiasz\",\n  \"Hieronim\",\n  \"Gerald\",\n  \"Joachim\",\n  \"Jan\",\n  \"Janusz\",\n  \"Jonatan\",\n  \"Józef\",\n  \"Jozue\",\n  \"Julian\",\n  \"Juliusz\",\n  \"Justyn\",\n  \"Kalistrat\",\n  \"Kazimierz\",\n  \"Wawrzyniec\",\n  \"Laurenty\",\n  \"Laurencjusz\",\n  \"Łazarz\",\n  \"Leon\",\n  \"Leonard\",\n  \"Leonid\",\n  \"Leon\",\n  \"Ludwik\",\n  \"Łukasz\",\n  \"Lucjan\",\n  \"Magnus\",\n  \"Makary\",\n  \"Marceli\",\n  \"Marek\",\n  \"Marcin\",\n  \"Mateusz\",\n  \"Maurycy\",\n  \"Maksym\",\n  \"Maksymilian\",\n  \"Michał\",\n  \"Miron\",\n  \"Modest\",\n  \"Mojżesz\",\n  \"Natan\",\n  \"Natanael\",\n  \"Nazariusz\",\n  \"Nazary\",\n  \"Nestor\",\n  \"Mikołaj\",\n  \"Nikodem\",\n  \"Olaf\",\n  \"Oleg\",\n  \"Oliwier\",\n  \"Onufry\",\n  \"Orestes\",\n  \"Oskar\",\n  \"Ansgary\",\n  \"Osmund\",\n  \"Pankracy\",\n  \"Pantaleon\",\n  \"Patryk\",\n  \"Patrycjusz\",\n  \"Patrycy\",\n  \"Paweł\",\n  \"Piotr\",\n  \"Filemon\",\n  \"Filip\",\n  \"Platon\",\n  \"Polikarp\",\n  \"Porfiry\",\n  \"Porfiriusz\",\n  \"Prokles\",\n  \"Prokul\",\n  \"Prokop\",\n  \"Kwintyn\",\n  \"Randolf\",\n  \"Rafał\",\n  \"Rajmund\",\n  \"Reginald\",\n  \"Rajnold\",\n  \"Ryszard\",\n  \"Robert\",\n  \"Roderyk\",\n  \"Roger\",\n  \"Roland\",\n  \"Roman\",\n  \"Romeo\",\n  \"Reginald\",\n  \"Rudolf\",\n  \"Samson\",\n  \"Samuel\",\n  \"Salwator\",\n  \"Sebastian\",\n  \"Serafin\",\n  \"Sergiusz\",\n  \"Seweryn\",\n  \"Zygmunt\",\n  \"Sylwester\",\n  \"Szymon\",\n  \"Salomon\",\n  \"Spirydion\",\n  \"Stanisław\",\n  \"Szczepan\",\n  \"Stefan\",\n  \"Terencjusz\",\n  \"Teodor\",\n  \"Tomasz\",\n  \"Tymoteusz\",\n  \"Tobiasz\",\n  \"Walenty\",\n  \"Walentyn\",\n  \"Walerian\",\n  \"Walery\",\n  \"Wiktor\",\n  \"Wincenty\",\n  \"Witalis\",\n  \"Włodzimierz\",\n  \"Władysław\",\n  \"Błażej\",\n  \"Walter\",\n  \"Walgierz\",\n  \"Wacław\",\n  \"Wilfryd\",\n  \"Wilhelm\",\n  \"Ksawery\",\n  \"Ksenofont\",\n  \"Jerzy\",\n  \"Zachariasz\",\n  \"Zachary\",\n  \"Ada\",\n  \"Adelajda\",\n  \"Agata\",\n  \"Agnieszka\",\n  \"Agrypina\",\n  \"Aida\",\n  \"Aleksandra\",\n  \"Alicja\",\n  \"Alina\",\n  \"Amanda\",\n  \"Anastazja\",\n  \"Angela\",\n  \"Andżelika\",\n  \"Angelina\",\n  \"Anna\",\n  \"Hanna\",\n  \"—\",\n  \"Antonina\",\n  \"Ariadna\",\n  \"Aurora\",\n  \"Barbara\",\n  \"Beatrycze\",\n  \"Berta\",\n  \"Brygida\",\n  \"Kamila\",\n  \"Karolina\",\n  \"Karolina\",\n  \"Kornelia\",\n  \"Katarzyna\",\n  \"Cecylia\",\n  \"Karolina\",\n  \"Chloe\",\n  \"Krystyna\",\n  \"Klara\",\n  \"Klaudia\",\n  \"Klementyna\",\n  \"Konstancja\",\n  \"Koralia\",\n  \"Daria\",\n  \"Diana\",\n  \"Dina\",\n  \"Dorota\",\n  \"Edyta\",\n  \"Eleonora\",\n  \"Eliza\",\n  \"Elżbieta\",\n  \"Izabela\",\n  \"Elwira\",\n  \"Emilia\",\n  \"Estera\",\n  \"Eudoksja\",\n  \"Eudokia\",\n  \"Eugenia\",\n  \"Ewa\",\n  \"Ewelina\",\n  \"Ferdynanda\",\n  \"Florencja\",\n  \"Franciszka\",\n  \"Gabriela\",\n  \"Gertruda\",\n  \"Gloria\",\n  \"Gracja\",\n  \"Jadwiga\",\n  \"Helena\",\n  \"Henryka\",\n  \"Nadzieja\",\n  \"Ida\",\n  \"Ilona\",\n  \"Helena\",\n  \"Irena\",\n  \"Irma\",\n  \"Izabela\",\n  \"Izolda\",\n  \"Jakubina\",\n  \"Joanna\",\n  \"Janina\",\n  \"Żaneta\",\n  \"Joanna\",\n  \"Ginewra\",\n  \"Józefina\",\n  \"Judyta\",\n  \"Julia\",\n  \"Julia\",\n  \"Julita\",\n  \"Justyna\",\n  \"Kira\",\n  \"Cyra\",\n  \"Kleopatra\",\n  \"Larysa\",\n  \"Laura\",\n  \"Laurencja\",\n  \"Laurentyna\",\n  \"Lea\",\n  \"Leila\",\n  \"Eleonora\",\n  \"Liliana\",\n  \"Lilianna\",\n  \"Lilia\",\n  \"Lilla\",\n  \"Liza\",\n  \"Eliza\",\n  \"Laura\",\n  \"Ludwika\",\n  \"Luiza\",\n  \"Łucja\",\n  \"Lucja\",\n  \"Lidia\",\n  \"Amabela\",\n  \"Magdalena\",\n  \"Malwina\",\n  \"Małgorzata\",\n  \"Greta\",\n  \"Marianna\",\n  \"Maryna\",\n  \"Marta\",\n  \"Martyna\",\n  \"Maria\",\n  \"Matylda\",\n  \"Maja\",\n  \"Maja\",\n  \"Melania\",\n  \"Michalina\",\n  \"Monika\",\n  \"Nadzieja\",\n  \"Noemi\",\n  \"Natalia\",\n  \"Nikola\",\n  \"Nina\",\n  \"Olga\",\n  \"Olimpia\",\n  \"Oliwia\",\n  \"Ofelia\",\n  \"Patrycja\",\n  \"Paula\",\n  \"Pelagia\",\n  \"Penelopa\",\n  \"Filipa\",\n  \"Paulina\",\n  \"Rachela\",\n  \"Rebeka\",\n  \"Regina\",\n  \"Renata\",\n  \"Rozalia\",\n  \"Róża\",\n  \"Roksana\",\n  \"Rufina\",\n  \"Ruta\",\n  \"Sabina\",\n  \"Sara\",\n  \"Serafina\",\n  \"Sybilla\",\n  \"Sylwia\",\n  \"Zofia\",\n  \"Stella\",\n  \"Stefania\",\n  \"Zuzanna\",\n  \"Tamara\",\n  \"Tacjana\",\n  \"Tekla\",\n  \"Teodora\",\n  \"Teresa\",\n  \"Walentyna\",\n  \"Waleria\",\n  \"Wanesa\",\n  \"Wiara\",\n  \"Weronika\",\n  \"Wiktoria\",\n  \"Wirginia\",\n  \"Bibiana\",\n  \"Bibianna\",\n  \"Wanda\",\n  \"Wilhelmina\",\n  \"Ksawera\",\n  \"Ksenia\",\n  \"Zoe\"\n];\n\n},{}],762:[function(require,module,exports){\narguments[4][493][0].apply(exports,arguments)\n},{\"./first_name\":761,\"./last_name\":763,\"./name\":764,\"./prefix\":765,\"./title\":766,\"/Users/a/dev/faker.js/lib/locales/fr/name/index.js\":493}],763:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adamczak\",\n  \"Adamczyk\",\n  \"Adamek\",\n  \"Adamiak\",\n  \"Adamiec\",\n  \"Adamowicz\",\n  \"Adamski\",\n  \"Adamus\",\n  \"Aleksandrowicz\",\n  \"Andrzejczak\",\n  \"Andrzejewski\",\n  \"Antczak\",\n  \"Augustyn\",\n  \"Augustyniak\",\n  \"Bagiński\",\n  \"Balcerzak\",\n  \"Banach\",\n  \"Banasiak\",\n  \"Banasik\",\n  \"Banaś\",\n  \"Baran\",\n  \"Baranowski\",\n  \"Barański\",\n  \"Bartczak\",\n  \"Bartkowiak\",\n  \"Bartnik\",\n  \"Bartosik\",\n  \"Bednarczyk\",\n  \"Bednarek\",\n  \"Bednarski\",\n  \"Bednarz\",\n  \"Białas\",\n  \"Białek\",\n  \"Białkowski\",\n  \"Bielak\",\n  \"Bielawski\",\n  \"Bielecki\",\n  \"Bielski\",\n  \"Bieniek\",\n  \"Biernacki\",\n  \"Biernat\",\n  \"Bieńkowski\",\n  \"Bilski\",\n  \"Bober\",\n  \"Bochenek\",\n  \"Bogucki\",\n  \"Bogusz\",\n  \"Borek\",\n  \"Borkowski\",\n  \"Borowiec\",\n  \"Borowski\",\n  \"Bożek\",\n  \"Broda\",\n  \"Brzeziński\",\n  \"Brzozowski\",\n  \"Buczek\",\n  \"Buczkowski\",\n  \"Buczyński\",\n  \"Budziński\",\n  \"Budzyński\",\n  \"Bujak\",\n  \"Bukowski\",\n  \"Burzyński\",\n  \"Bąk\",\n  \"Bąkowski\",\n  \"Błaszczak\",\n  \"Błaszczyk\",\n  \"Cebula\",\n  \"Chmiel\",\n  \"Chmielewski\",\n  \"Chmura\",\n  \"Chojnacki\",\n  \"Chojnowski\",\n  \"Cholewa\",\n  \"Chrzanowski\",\n  \"Chudzik\",\n  \"Cichocki\",\n  \"Cichoń\",\n  \"Cichy\",\n  \"Ciesielski\",\n  \"Cieśla\",\n  \"Cieślak\",\n  \"Cieślik\",\n  \"Ciszewski\",\n  \"Cybulski\",\n  \"Cygan\",\n  \"Czaja\",\n  \"Czajka\",\n  \"Czajkowski\",\n  \"Czapla\",\n  \"Czarnecki\",\n  \"Czech\",\n  \"Czechowski\",\n  \"Czekaj\",\n  \"Czerniak\",\n  \"Czerwiński\",\n  \"Czyż\",\n  \"Czyżewski\",\n  \"Dec\",\n  \"Dobosz\",\n  \"Dobrowolski\",\n  \"Dobrzyński\",\n  \"Domagała\",\n  \"Domański\",\n  \"Dominiak\",\n  \"Drabik\",\n  \"Drozd\",\n  \"Drozdowski\",\n  \"Drzewiecki\",\n  \"Dróżdż\",\n  \"Dubiel\",\n  \"Duda\",\n  \"Dudek\",\n  \"Dudziak\",\n  \"Dudzik\",\n  \"Dudziński\",\n  \"Duszyński\",\n  \"Dziedzic\",\n  \"Dziuba\",\n  \"Dąbek\",\n  \"Dąbkowski\",\n  \"Dąbrowski\",\n  \"Dębowski\",\n  \"Dębski\",\n  \"Długosz\",\n  \"Falkowski\",\n  \"Fijałkowski\",\n  \"Filipek\",\n  \"Filipiak\",\n  \"Filipowicz\",\n  \"Flak\",\n  \"Flis\",\n  \"Florczak\",\n  \"Florek\",\n  \"Frankowski\",\n  \"Frąckowiak\",\n  \"Frączek\",\n  \"Frątczak\",\n  \"Furman\",\n  \"Gadomski\",\n  \"Gajda\",\n  \"Gajewski\",\n  \"Gaweł\",\n  \"Gawlik\",\n  \"Gawron\",\n  \"Gawroński\",\n  \"Gałka\",\n  \"Gałązka\",\n  \"Gil\",\n  \"Godlewski\",\n  \"Golec\",\n  \"Gołąb\",\n  \"Gołębiewski\",\n  \"Gołębiowski\",\n  \"Grabowski\",\n  \"Graczyk\",\n  \"Grochowski\",\n  \"Grudzień\",\n  \"Gruszczyński\",\n  \"Gruszka\",\n  \"Grzegorczyk\",\n  \"Grzelak\",\n  \"Grzesiak\",\n  \"Grzesik\",\n  \"Grześkowiak\",\n  \"Grzyb\",\n  \"Grzybowski\",\n  \"Grzywacz\",\n  \"Gutowski\",\n  \"Guzik\",\n  \"Gwóźdź\",\n  \"Góra\",\n  \"Góral\",\n  \"Górecki\",\n  \"Górka\",\n  \"Górniak\",\n  \"Górny\",\n  \"Górski\",\n  \"Gąsior\",\n  \"Gąsiorowski\",\n  \"Głogowski\",\n  \"Głowacki\",\n  \"Głąb\",\n  \"Hajduk\",\n  \"Herman\",\n  \"Iwański\",\n  \"Izdebski\",\n  \"Jabłoński\",\n  \"Jackowski\",\n  \"Jagielski\",\n  \"Jagiełło\",\n  \"Jagodziński\",\n  \"Jakubiak\",\n  \"Jakubowski\",\n  \"Janas\",\n  \"Janiak\",\n  \"Janicki\",\n  \"Janik\",\n  \"Janiszewski\",\n  \"Jankowiak\",\n  \"Jankowski\",\n  \"Janowski\",\n  \"Janus\",\n  \"Janusz\",\n  \"Januszewski\",\n  \"Jaros\",\n  \"Jarosz\",\n  \"Jarząbek\",\n  \"Jasiński\",\n  \"Jastrzębski\",\n  \"Jaworski\",\n  \"Jaśkiewicz\",\n  \"Jezierski\",\n  \"Jurek\",\n  \"Jurkiewicz\",\n  \"Jurkowski\",\n  \"Juszczak\",\n  \"Jóźwiak\",\n  \"Jóźwik\",\n  \"Jędrzejczak\",\n  \"Jędrzejczyk\",\n  \"Jędrzejewski\",\n  \"Kacprzak\",\n  \"Kaczmarczyk\",\n  \"Kaczmarek\",\n  \"Kaczmarski\",\n  \"Kaczor\",\n  \"Kaczorowski\",\n  \"Kaczyński\",\n  \"Kaleta\",\n  \"Kalinowski\",\n  \"Kalisz\",\n  \"Kamiński\",\n  \"Kania\",\n  \"Kaniewski\",\n  \"Kapusta\",\n  \"Karaś\",\n  \"Karczewski\",\n  \"Karpiński\",\n  \"Karwowski\",\n  \"Kasperek\",\n  \"Kasprzak\",\n  \"Kasprzyk\",\n  \"Kaszuba\",\n  \"Kawa\",\n  \"Kawecki\",\n  \"Kałuża\",\n  \"Kaźmierczak\",\n  \"Kiełbasa\",\n  \"Kisiel\",\n  \"Kita\",\n  \"Klimczak\",\n  \"Klimek\",\n  \"Kmiecik\",\n  \"Kmieć\",\n  \"Knapik\",\n  \"Kobus\",\n  \"Kogut\",\n  \"Kolasa\",\n  \"Komorowski\",\n  \"Konieczna\",\n  \"Konieczny\",\n  \"Konopka\",\n  \"Kopczyński\",\n  \"Koper\",\n  \"Kopeć\",\n  \"Korzeniowski\",\n  \"Kos\",\n  \"Kosiński\",\n  \"Kosowski\",\n  \"Kostecki\",\n  \"Kostrzewa\",\n  \"Kot\",\n  \"Kotowski\",\n  \"Kowal\",\n  \"Kowalczuk\",\n  \"Kowalczyk\",\n  \"Kowalewski\",\n  \"Kowalik\",\n  \"Kowalski\",\n  \"Koza\",\n  \"Kozak\",\n  \"Kozieł\",\n  \"Kozioł\",\n  \"Kozłowski\",\n  \"Kołakowski\",\n  \"Kołodziej\",\n  \"Kołodziejczyk\",\n  \"Kołodziejski\",\n  \"Krajewski\",\n  \"Krakowiak\",\n  \"Krawczyk\",\n  \"Krawiec\",\n  \"Kruk\",\n  \"Krukowski\",\n  \"Krupa\",\n  \"Krupiński\",\n  \"Kruszewski\",\n  \"Krysiak\",\n  \"Krzemiński\",\n  \"Krzyżanowski\",\n  \"Król\",\n  \"Królikowski\",\n  \"Książek\",\n  \"Kubacki\",\n  \"Kubiak\",\n  \"Kubica\",\n  \"Kubicki\",\n  \"Kubik\",\n  \"Kuc\",\n  \"Kucharczyk\",\n  \"Kucharski\",\n  \"Kuchta\",\n  \"Kuciński\",\n  \"Kuczyński\",\n  \"Kujawa\",\n  \"Kujawski\",\n  \"Kula\",\n  \"Kulesza\",\n  \"Kulig\",\n  \"Kulik\",\n  \"Kuliński\",\n  \"Kurek\",\n  \"Kurowski\",\n  \"Kuś\",\n  \"Kwaśniewski\",\n  \"Kwiatkowski\",\n  \"Kwiecień\",\n  \"Kwieciński\",\n  \"Kędzierski\",\n  \"Kędziora\",\n  \"Kępa\",\n  \"Kłos\",\n  \"Kłosowski\",\n  \"Lach\",\n  \"Laskowski\",\n  \"Lasota\",\n  \"Lech\",\n  \"Lenart\",\n  \"Lesiak\",\n  \"Leszczyński\",\n  \"Lewandowski\",\n  \"Lewicki\",\n  \"Leśniak\",\n  \"Leśniewski\",\n  \"Lipiński\",\n  \"Lipka\",\n  \"Lipski\",\n  \"Lis\",\n  \"Lisiecki\",\n  \"Lisowski\",\n  \"Maciejewski\",\n  \"Maciąg\",\n  \"Mackiewicz\",\n  \"Madej\",\n  \"Maj\",\n  \"Majcher\",\n  \"Majchrzak\",\n  \"Majewski\",\n  \"Majka\",\n  \"Makowski\",\n  \"Malec\",\n  \"Malicki\",\n  \"Malinowski\",\n  \"Maliszewski\",\n  \"Marchewka\",\n  \"Marciniak\",\n  \"Marcinkowski\",\n  \"Marczak\",\n  \"Marek\",\n  \"Markiewicz\",\n  \"Markowski\",\n  \"Marszałek\",\n  \"Marzec\",\n  \"Masłowski\",\n  \"Matusiak\",\n  \"Matuszak\",\n  \"Matuszewski\",\n  \"Matysiak\",\n  \"Mazur\",\n  \"Mazurek\",\n  \"Mazurkiewicz\",\n  \"Maćkowiak\",\n  \"Małecki\",\n  \"Małek\",\n  \"Maślanka\",\n  \"Michalak\",\n  \"Michalczyk\",\n  \"Michalik\",\n  \"Michalski\",\n  \"Michałek\",\n  \"Michałowski\",\n  \"Mielczarek\",\n  \"Mierzejewski\",\n  \"Mika\",\n  \"Mikołajczak\",\n  \"Mikołajczyk\",\n  \"Mikulski\",\n  \"Milczarek\",\n  \"Milewski\",\n  \"Miller\",\n  \"Misiak\",\n  \"Misztal\",\n  \"Miśkiewicz\",\n  \"Modzelewski\",\n  \"Molenda\",\n  \"Morawski\",\n  \"Motyka\",\n  \"Mroczek\",\n  \"Mroczkowski\",\n  \"Mrozek\",\n  \"Mróz\",\n  \"Mucha\",\n  \"Murawski\",\n  \"Musiał\",\n  \"Muszyński\",\n  \"Młynarczyk\",\n  \"Napierała\",\n  \"Nawrocki\",\n  \"Nawrot\",\n  \"Niedziela\",\n  \"Niedzielski\",\n  \"Niedźwiecki\",\n  \"Niemczyk\",\n  \"Niemiec\",\n  \"Niewiadomski\",\n  \"Noga\",\n  \"Nowacki\",\n  \"Nowaczyk\",\n  \"Nowak\",\n  \"Nowakowski\",\n  \"Nowicki\",\n  \"Nowiński\",\n  \"Olczak\",\n  \"Olejniczak\",\n  \"Olejnik\",\n  \"Olszewski\",\n  \"Orzechowski\",\n  \"Orłowski\",\n  \"Osiński\",\n  \"Ossowski\",\n  \"Ostrowski\",\n  \"Owczarek\",\n  \"Paczkowski\",\n  \"Pająk\",\n  \"Pakuła\",\n  \"Paluch\",\n  \"Panek\",\n  \"Partyka\",\n  \"Pasternak\",\n  \"Paszkowski\",\n  \"Pawelec\",\n  \"Pawlak\",\n  \"Pawlicki\",\n  \"Pawlik\",\n  \"Pawlikowski\",\n  \"Pawłowski\",\n  \"Pałka\",\n  \"Piasecki\",\n  \"Piechota\",\n  \"Piekarski\",\n  \"Pietras\",\n  \"Pietruszka\",\n  \"Pietrzak\",\n  \"Pietrzyk\",\n  \"Pilarski\",\n  \"Pilch\",\n  \"Piotrowicz\",\n  \"Piotrowski\",\n  \"Piwowarczyk\",\n  \"Piórkowski\",\n  \"Piątek\",\n  \"Piątkowski\",\n  \"Piłat\",\n  \"Pluta\",\n  \"Podgórski\",\n  \"Polak\",\n  \"Popławski\",\n  \"Porębski\",\n  \"Prokop\",\n  \"Prus\",\n  \"Przybylski\",\n  \"Przybysz\",\n  \"Przybył\",\n  \"Przybyła\",\n  \"Ptak\",\n  \"Puchalski\",\n  \"Pytel\",\n  \"Płonka\",\n  \"Raczyński\",\n  \"Radecki\",\n  \"Radomski\",\n  \"Rak\",\n  \"Rakowski\",\n  \"Ratajczak\",\n  \"Robak\",\n  \"Rogala\",\n  \"Rogalski\",\n  \"Rogowski\",\n  \"Rojek\",\n  \"Romanowski\",\n  \"Rosa\",\n  \"Rosiak\",\n  \"Rosiński\",\n  \"Ruciński\",\n  \"Rudnicki\",\n  \"Rudziński\",\n  \"Rudzki\",\n  \"Rusin\",\n  \"Rutkowski\",\n  \"Rybak\",\n  \"Rybarczyk\",\n  \"Rybicki\",\n  \"Rzepka\",\n  \"Różański\",\n  \"Różycki\",\n  \"Sadowski\",\n  \"Sawicki\",\n  \"Serafin\",\n  \"Siedlecki\",\n  \"Sienkiewicz\",\n  \"Sieradzki\",\n  \"Sikora\",\n  \"Sikorski\",\n  \"Sitek\",\n  \"Siwek\",\n  \"Skalski\",\n  \"Skiba\",\n  \"Skibiński\",\n  \"Skoczylas\",\n  \"Skowron\",\n  \"Skowronek\",\n  \"Skowroński\",\n  \"Skrzypczak\",\n  \"Skrzypek\",\n  \"Skóra\",\n  \"Smoliński\",\n  \"Sobczak\",\n  \"Sobczyk\",\n  \"Sobieraj\",\n  \"Sobolewski\",\n  \"Socha\",\n  \"Sochacki\",\n  \"Sokołowski\",\n  \"Sokół\",\n  \"Sosnowski\",\n  \"Sowa\",\n  \"Sowiński\",\n  \"Sołtys\",\n  \"Sołtysiak\",\n  \"Sroka\",\n  \"Stachowiak\",\n  \"Stachowicz\",\n  \"Stachura\",\n  \"Stachurski\",\n  \"Stanek\",\n  \"Staniszewski\",\n  \"Stanisławski\",\n  \"Stankiewicz\",\n  \"Stasiak\",\n  \"Staszewski\",\n  \"Stawicki\",\n  \"Stec\",\n  \"Stefaniak\",\n  \"Stefański\",\n  \"Stelmach\",\n  \"Stolarczyk\",\n  \"Stolarski\",\n  \"Strzelczyk\",\n  \"Strzelecki\",\n  \"Stępień\",\n  \"Stępniak\",\n  \"Surma\",\n  \"Suski\",\n  \"Szafrański\",\n  \"Szatkowski\",\n  \"Szczepaniak\",\n  \"Szczepanik\",\n  \"Szczepański\",\n  \"Szczerba\",\n  \"Szcześniak\",\n  \"Szczygieł\",\n  \"Szczęsna\",\n  \"Szczęsny\",\n  \"Szeląg\",\n  \"Szewczyk\",\n  \"Szostak\",\n  \"Szulc\",\n  \"Szwarc\",\n  \"Szwed\",\n  \"Szydłowski\",\n  \"Szymański\",\n  \"Szymczak\",\n  \"Szymczyk\",\n  \"Szymkowiak\",\n  \"Szyszka\",\n  \"Sławiński\",\n  \"Słowik\",\n  \"Słowiński\",\n  \"Tarnowski\",\n  \"Tkaczyk\",\n  \"Tokarski\",\n  \"Tomala\",\n  \"Tomaszewski\",\n  \"Tomczak\",\n  \"Tomczyk\",\n  \"Tracz\",\n  \"Trojanowski\",\n  \"Trzciński\",\n  \"Trzeciak\",\n  \"Turek\",\n  \"Twardowski\",\n  \"Urban\",\n  \"Urbanek\",\n  \"Urbaniak\",\n  \"Urbanowicz\",\n  \"Urbańczyk\",\n  \"Urbański\",\n  \"Walczak\",\n  \"Walkowiak\",\n  \"Warchoł\",\n  \"Wasiak\",\n  \"Wasilewski\",\n  \"Wawrzyniak\",\n  \"Wesołowski\",\n  \"Wieczorek\",\n  \"Wierzbicki\",\n  \"Wilczek\",\n  \"Wilczyński\",\n  \"Wilk\",\n  \"Winiarski\",\n  \"Witczak\",\n  \"Witek\",\n  \"Witkowski\",\n  \"Wiącek\",\n  \"Więcek\",\n  \"Więckowski\",\n  \"Wiśniewski\",\n  \"Wnuk\",\n  \"Wojciechowski\",\n  \"Wojtas\",\n  \"Wojtasik\",\n  \"Wojtczak\",\n  \"Wojtkowiak\",\n  \"Wolak\",\n  \"Woliński\",\n  \"Wolny\",\n  \"Wolski\",\n  \"Woś\",\n  \"Woźniak\",\n  \"Wrona\",\n  \"Wroński\",\n  \"Wróbel\",\n  \"Wróblewski\",\n  \"Wypych\",\n  \"Wysocki\",\n  \"Wyszyński\",\n  \"Wójcicki\",\n  \"Wójcik\",\n  \"Wójtowicz\",\n  \"Wąsik\",\n  \"Węgrzyn\",\n  \"Włodarczyk\",\n  \"Włodarski\",\n  \"Zaborowski\",\n  \"Zabłocki\",\n  \"Zagórski\",\n  \"Zając\",\n  \"Zajączkowski\",\n  \"Zakrzewski\",\n  \"Zalewski\",\n  \"Zaremba\",\n  \"Zarzycki\",\n  \"Zaręba\",\n  \"Zawada\",\n  \"Zawadzki\",\n  \"Zdunek\",\n  \"Zieliński\",\n  \"Zielonka\",\n  \"Ziółkowski\",\n  \"Zięba\",\n  \"Ziętek\",\n  \"Zwoliński\",\n  \"Zych\",\n  \"Zygmunt\",\n  \"Łapiński\",\n  \"Łuczak\",\n  \"Łukasiewicz\",\n  \"Łukasik\",\n  \"Łukaszewski\",\n  \"Śliwa\",\n  \"Śliwiński\",\n  \"Ślusarczyk\",\n  \"Świderski\",\n  \"Świerczyński\",\n  \"Świątek\",\n  \"Żak\",\n  \"Żebrowski\",\n  \"Żmuda\",\n  \"Żuk\",\n  \"Żukowski\",\n  \"Żurawski\",\n  \"Żurek\",\n  \"Żyła\"\n];\n\n},{}],764:[function(require,module,exports){\nmodule.exports=require(538)\n},{\"/Users/a/dev/faker.js/lib/locales/ge/name/name.js\":538}],765:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Pan\",\n  \"Pani\"\n];\n\n},{}],766:[function(require,module,exports){\nmodule.exports=require(264)\n},{\"/Users/a/dev/faker.js/lib/locales/en/name/title.js\":264}],767:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"12-###-##-##\",\n  \"13-###-##-##\",\n  \"14-###-##-##\",\n  \"15-###-##-##\",\n  \"16-###-##-##\",\n  \"17-###-##-##\",\n  \"18-###-##-##\",\n  \"22-###-##-##\",\n  \"23-###-##-##\",\n  \"24-###-##-##\",\n  \"25-###-##-##\",\n  \"29-###-##-##\",\n  \"32-###-##-##\",\n  \"33-###-##-##\",\n  \"34-###-##-##\",\n  \"41-###-##-##\",\n  \"42-###-##-##\",\n  \"43-###-##-##\",\n  \"44-###-##-##\",\n  \"46-###-##-##\",\n  \"48-###-##-##\",\n  \"52-###-##-##\",\n  \"54-###-##-##\",\n  \"55-###-##-##\",\n  \"56-###-##-##\",\n  \"58-###-##-##\",\n  \"59-###-##-##\",\n  \"61-###-##-##\",\n  \"62-###-##-##\",\n  \"63-###-##-##\",\n  \"65-###-##-##\",\n  \"67-###-##-##\",\n  \"68-###-##-##\",\n  \"71-###-##-##\",\n  \"74-###-##-##\",\n  \"75-###-##-##\",\n  \"76-###-##-##\",\n  \"77-###-##-##\",\n  \"81-###-##-##\",\n  \"82-###-##-##\",\n  \"83-###-##-##\",\n  \"84-###-##-##\",\n  \"85-###-##-##\",\n  \"86-###-##-##\",\n  \"87-###-##-##\",\n  \"89-###-##-##\",\n  \"91-###-##-##\",\n  \"94-###-##-##\",\n  \"95-###-##-##\"\n];\n\n},{}],768:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":767,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],769:[function(require,module,exports){\nmodule.exports=require(179)\n},{\"/Users/a/dev/faker.js/lib/locales/en/address/building_number.js\":179}],770:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Nova\",\n  \"Velha\",\n  \"Grande\",\n  \"Vila\",\n  \"Município de\"\n];\n\n},{}],771:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"do Descoberto\",\n  \"de Nossa Senhora\",\n  \"do Norte\",\n  \"do Sul\"\n];\n\n},{}],772:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afeganistão\",\n  \"Albânia\",\n  \"Algéria\",\n  \"Samoa\",\n  \"Andorra\",\n  \"Angola\",\n  \"Anguilla\",\n  \"Antigua and Barbada\",\n  \"Argentina\",\n  \"Armênia\",\n  \"Aruba\",\n  \"Austrália\",\n  \"Áustria\",\n  \"Alzerbajão\",\n  \"Bahamas\",\n  \"Barém\",\n  \"Bangladesh\",\n  \"Barbado\",\n  \"Belgrado\",\n  \"Bélgica\",\n  \"Belize\",\n  \"Benin\",\n  \"Bermuda\",\n  \"Bhutan\",\n  \"Bolívia\",\n  \"Bôsnia\",\n  \"Botuasuna\",\n  \"Bouvetoia\",\n  \"Brasil\",\n  \"Arquipélago de Chagos\",\n  \"Ilhas Virgens\",\n  \"Brunei\",\n  \"Bulgária\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Cambójia\",\n  \"Camarões\",\n  \"Canadá\",\n  \"Cabo Verde\",\n  \"Ilhas Caiman\",\n  \"República da África Central\",\n  \"Chad\",\n  \"Chile\",\n  \"China\",\n  \"Ilhas Natal\",\n  \"Ilhas Cocos\",\n  \"Colômbia\",\n  \"Comoros\",\n  \"Congo\",\n  \"Ilhas Cook\",\n  \"Costa Rica\",\n  \"Costa do Marfim\",\n  \"Croácia\",\n  \"Cuba\",\n  \"Cyprus\",\n  \"República Tcheca\",\n  \"Dinamarca\",\n  \"Djibouti\",\n  \"Dominica\",\n  \"República Dominicana\",\n  \"Equador\",\n  \"Egito\",\n  \"El Salvador\",\n  \"Guiné Equatorial\",\n  \"Eritrea\",\n  \"Estônia\",\n  \"Etiópia\",\n  \"Ilhas Faroe\",\n  \"Malvinas\",\n  \"Fiji\",\n  \"Finlândia\",\n  \"França\",\n  \"Guiné Francesa\",\n  \"Polinésia Francesa\",\n  \"Gabão\",\n  \"Gâmbia\",\n  \"Georgia\",\n  \"Alemanha\",\n  \"Gana\",\n  \"Gibraltar\",\n  \"Grécia\",\n  \"Groelândia\",\n  \"Granada\",\n  \"Guadalupe\",\n  \"Guano\",\n  \"Guatemala\",\n  \"Guernsey\",\n  \"Guiné\",\n  \"Guiné-Bissau\",\n  \"Guiana\",\n  \"Haiti\",\n  \"Heard Island and McDonald Islands\",\n  \"Vaticano\",\n  \"Honduras\",\n  \"Hong Kong\",\n  \"Hungria\",\n  \"Iceland\",\n  \"Índia\",\n  \"Indonésia\",\n  \"Irã\",\n  \"Iraque\",\n  \"Irlanda\",\n  \"Ilha de Man\",\n  \"Israel\",\n  \"Itália\",\n  \"Jamaica\",\n  \"Japão\",\n  \"Jersey\",\n  \"Jordânia\",\n  \"Cazaquistão\",\n  \"Quênia\",\n  \"Kiribati\",\n  \"Coreia do Norte\",\n  \"Coreia do Sul\",\n  \"Kuwait\",\n  \"Kyrgyz Republic\",\n  \"República Democrática de Lao People\",\n  \"Latvia\",\n  \"Líbano\",\n  \"Lesotho\",\n  \"Libéria\",\n  \"Libyan Arab Jamahiriya\",\n  \"Liechtenstein\",\n  \"Lituânia\",\n  \"Luxemburgo\",\n  \"Macao\",\n  \"Macedônia\",\n  \"Madagascar\",\n  \"Malawi\",\n  \"Malásia\",\n  \"Maldives\",\n  \"Mali\",\n  \"Malta\",\n  \"Ilhas Marshall\",\n  \"Martinica\",\n  \"Mauritânia\",\n  \"Mauritius\",\n  \"Mayotte\",\n  \"México\",\n  \"Micronésia\",\n  \"Moldova\",\n  \"Mônaco\",\n  \"Mongólia\",\n  \"Montenegro\",\n  \"Montserrat\",\n  \"Marrocos\",\n  \"Moçambique\",\n  \"Myanmar\",\n  \"Namibia\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Antilhas Holandesas\",\n  \"Holanda\",\n  \"Nova Caledonia\",\n  \"Nova Zelândia\",\n  \"Nicarágua\",\n  \"Nigéria\",\n  \"Niue\",\n  \"Ilha Norfolk\",\n  \"Northern Mariana Islands\",\n  \"Noruega\",\n  \"Oman\",\n  \"Paquistão\",\n  \"Palau\",\n  \"Território da Palestina\",\n  \"Panamá\",\n  \"Nova Guiné Papua\",\n  \"Paraguai\",\n  \"Peru\",\n  \"Filipinas\",\n  \"Polônia\",\n  \"Portugal\",\n  \"Puerto Rico\",\n  \"Qatar\",\n  \"Romênia\",\n  \"Rússia\",\n  \"Ruanda\",\n  \"São Bartolomeu\",\n  \"Santa Helena\",\n  \"Santa Lúcia\",\n  \"Saint Martin\",\n  \"Saint Pierre and Miquelon\",\n  \"Saint Vincent and the Grenadines\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Sao Tomé e Príncipe\",\n  \"Arábia Saudita\",\n  \"Senegal\",\n  \"Sérvia\",\n  \"Seychelles\",\n  \"Serra Leoa\",\n  \"Singapura\",\n  \"Eslováquia\",\n  \"Eslovênia\",\n  \"Ilhas Salomão\",\n  \"Somália\",\n  \"África do Sul\",\n  \"South Georgia and the South Sandwich Islands\",\n  \"Spanha\",\n  \"Sri Lanka\",\n  \"Sudão\",\n  \"Suriname\",\n  \"Svalbard & Jan Mayen Islands\",\n  \"Swaziland\",\n  \"Suécia\",\n  \"Suíça\",\n  \"Síria\",\n  \"Taiwan\",\n  \"Tajiquistão\",\n  \"Tanzânia\",\n  \"Tailândia\",\n  \"Timor-Leste\",\n  \"Togo\",\n  \"Tokelau\",\n  \"Tonga\",\n  \"Trinidá e Tobago\",\n  \"Tunísia\",\n  \"Turquia\",\n  \"Turcomenistão\",\n  \"Turks and Caicos Islands\",\n  \"Tuvalu\",\n  \"Uganda\",\n  \"Ucrânia\",\n  \"Emirados Árabes Unidos\",\n  \"Reino Unido\",\n  \"Estados Unidos da América\",\n  \"Estados Unidos das Ilhas Virgens\",\n  \"Uruguai\",\n  \"Uzbequistão\",\n  \"Vanuatu\",\n  \"Venezuela\",\n  \"Vietnã\",\n  \"Wallis and Futuna\",\n  \"Sahara\",\n  \"Yemen\",\n  \"Zâmbia\",\n  \"Zimbábue\"\n];\n\n},{}],773:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Brasil\"\n];\n\n},{}],774:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":769,\"./city_prefix\":770,\"./city_suffix\":771,\"./country\":772,\"./default_country\":773,\"./postcode\":775,\"./secondary_address\":776,\"./state\":777,\"./state_abbr\":778,\"./street_suffix\":779}],775:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\",\n  \"#####-###\"\n];\n\n},{}],776:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Apto. ###\",\n  \"Sobrado ##\",\n  \"Casa #\",\n  \"Lote ##\",\n  \"Quadra ##\"\n];\n\n},{}],777:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Acre\",\n  \"Alagoas\",\n  \"Amapá\",\n  \"Amazonas\",\n  \"Bahia\",\n  \"Ceará\",\n  \"Distrito Federal\",\n  \"Espírito Santo\",\n  \"Goiás\",\n  \"Maranhão\",\n  \"Mato Grosso\",\n  \"Mato Grosso do Sul\",\n  \"Minas Gerais\",\n  \"Pará\",\n  \"Paraíba\",\n  \"Paraná\",\n  \"Pernambuco\",\n  \"Piauí\",\n  \"Rio de Janeiro\",\n  \"Rio Grande do Norte\",\n  \"Rio Grande do Sul\",\n  \"Rondônia\",\n  \"Roraima\",\n  \"Santa Catarina\",\n  \"São Paulo\",\n  \"Sergipe\",\n  \"Tocantins\"\n];\n\n},{}],778:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"AC\",\n  \"AL\",\n  \"AP\",\n  \"AM\",\n  \"BA\",\n  \"CE\",\n  \"DF\",\n  \"ES\",\n  \"GO\",\n  \"MA\",\n  \"MT\",\n  \"MS\",\n  \"PA\",\n  \"PB\",\n  \"PR\",\n  \"PE\",\n  \"PI\",\n  \"RJ\",\n  \"RN\",\n  \"RS\",\n  \"RO\",\n  \"RR\",\n  \"SC\",\n  \"SP\"\n];\n\n},{}],779:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Rua\",\n  \"Avenida\",\n  \"Travessa\",\n  \"Ponte\",\n  \"Alameda\",\n  \"Marginal\",\n  \"Viela\",\n  \"Rodovia\"\n];\n\n},{}],780:[function(require,module,exports){\narguments[4][166][0].apply(exports,arguments)\n},{\"./name\":781,\"./suffix\":782,\"/Users/a/dev/faker.js/lib/locales/de_CH/company/index.js\":166}],781:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name}-#{Name.last_name}\",\n  \"#{Name.last_name}, #{Name.last_name} e #{Name.last_name}\"\n];\n\n},{}],782:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"S.A.\",\n  \"LTDA\",\n  \"e Associados\",\n  \"Comércio\"\n];\n\n},{}],783:[function(require,module,exports){\nvar pt_BR = {};\nmodule['exports'] = pt_BR;\npt_BR.title = \"Portuguese (Brazil)\";\npt_BR.address = require(\"./address\");\npt_BR.company = require(\"./company\");\npt_BR.internet = require(\"./internet\");\npt_BR.lorem = require(\"./lorem\");\npt_BR.name = require(\"./name\");\npt_BR.phone_number = require(\"./phone_number\");\n\n},{\"./address\":774,\"./company\":780,\"./internet\":786,\"./lorem\":787,\"./name\":790,\"./phone_number\":795}],784:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"br\",\n  \"com\",\n  \"biz\",\n  \"info\",\n  \"name\",\n  \"net\",\n  \"org\"\n];\n\n},{}],785:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"yahoo.com\",\n  \"hotmail.com\",\n  \"live.com\",\n  \"bol.com.br\"\n];\n\n},{}],786:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":784,\"./free_email\":785,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],787:[function(require,module,exports){\nmodule.exports=require(121)\n},{\"./words\":788,\"/Users/a/dev/faker.js/lib/locales/de/lorem/index.js\":121}],788:[function(require,module,exports){\nmodule.exports=require(85)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/words.js\":85}],789:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Alessandro\",\n  \"Alessandra\",\n  \"Alexandre\",\n  \"Aline\",\n  \"Antônio\",\n  \"Breno\",\n  \"Bruna\",\n  \"Carlos\",\n  \"Carla\",\n  \"Célia\",\n  \"Cecília\",\n  \"César\",\n  \"Danilo\",\n  \"Dalila\",\n  \"Deneval\",\n  \"Eduardo\",\n  \"Eduarda\",\n  \"Esther\",\n  \"Elísio\",\n  \"Fábio\",\n  \"Fabrício\",\n  \"Fabrícia\",\n  \"Félix\",\n  \"Felícia\",\n  \"Feliciano\",\n  \"Frederico\",\n  \"Fabiano\",\n  \"Gustavo\",\n  \"Guilherme\",\n  \"Gúbio\",\n  \"Heitor\",\n  \"Hélio\",\n  \"Hugo\",\n  \"Isabel\",\n  \"Isabela\",\n  \"Ígor\",\n  \"João\",\n  \"Joana\",\n  \"Júlio César\",\n  \"Júlio\",\n  \"Júlia\",\n  \"Janaína\",\n  \"Karla\",\n  \"Kléber\",\n  \"Lucas\",\n  \"Lorena\",\n  \"Lorraine\",\n  \"Larissa\",\n  \"Ladislau\",\n  \"Marcos\",\n  \"Meire\",\n  \"Marcelo\",\n  \"Marcela\",\n  \"Margarida\",\n  \"Mércia\",\n  \"Márcia\",\n  \"Marli\",\n  \"Morgana\",\n  \"Maria\",\n  \"Norberto\",\n  \"Natália\",\n  \"Nataniel\",\n  \"Núbia\",\n  \"Ofélia\",\n  \"Paulo\",\n  \"Paula\",\n  \"Pablo\",\n  \"Pedro\",\n  \"Raul\",\n  \"Rafael\",\n  \"Rafaela\",\n  \"Ricardo\",\n  \"Roberto\",\n  \"Roberta\",\n  \"Sílvia\",\n  \"Sílvia\",\n  \"Silas\",\n  \"Suélen\",\n  \"Sara\",\n  \"Salvador\",\n  \"Sirineu\",\n  \"Talita\",\n  \"Tertuliano\",\n  \"Vicente\",\n  \"Víctor\",\n  \"Vitória\",\n  \"Yango\",\n  \"Yago\",\n  \"Yuri\",\n  \"Washington\",\n  \"Warley\"\n];\n\n},{}],790:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\n\n},{\"./first_name\":789,\"./last_name\":791,\"./prefix\":792,\"./suffix\":793}],791:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Silva\",\n  \"Souza\",\n  \"Carvalho\",\n  \"Santos\",\n  \"Reis\",\n  \"Xavier\",\n  \"Franco\",\n  \"Braga\",\n  \"Macedo\",\n  \"Batista\",\n  \"Barros\",\n  \"Moraes\",\n  \"Costa\",\n  \"Pereira\",\n  \"Carvalho\",\n  \"Melo\",\n  \"Saraiva\",\n  \"Nogueira\",\n  \"Oliveira\",\n  \"Martins\",\n  \"Moreira\",\n  \"Albuquerque\"\n];\n\n},{}],792:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Sr.\",\n  \"Sra.\",\n  \"Srta.\",\n  \"Dr.\"\n];\n\n},{}],793:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Jr.\",\n  \"Neto\",\n  \"Filho\"\n];\n\n},{}],794:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"(##) ####-####\",\n  \"+55 (##) ####-####\",\n  \"(##) #####-####\"\n];\n\n},{}],795:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":794,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],796:[function(require,module,exports){\nmodule.exports=require(16)\n},{\"/Users/a/dev/faker.js/lib/locales/az/address/building_number.js\":16}],797:[function(require,module,exports){\nmodule.exports=require(17)\n},{\"/Users/a/dev/faker.js/lib/locales/az/address/city.js\":17}],798:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Хабаровск\",\n  \"Махачкала\",\n  \"Оренбург\",\n  \"Новокузнецк\",\n  \"Томск\",\n  \"Кемерово\",\n  \"Рязань\",\n  \"Астрахань\",\n  \"Пенза\",\n  \"Липецк\",\n  \"Тула\",\n  \"Киров\",\n  \"Чебоксары\",\n  \"Курск\",\n  \"Брянскm Магнитогорск\",\n  \"Иваново\",\n  \"Тверь\",\n  \"Ставрополь\",\n  \"Белгород\",\n  \"Сочи\"\n];\n\n},{}],799:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Босния и Герцеговина\",\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  \"Греция\",\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  \"Кипр\",\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  \"Мадагаскар\",\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  \"Пакистан\",\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  \"Словения\",\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  \"Фиджи\",\n  \"Филиппины\",\n  \"Финляндия\",\n  \"Франция\",\n  \"Французская Полинезия (не признана)\",\n  \"Хорватия\",\n  \"Центральноафриканская Республика\",\n  \"Чад\",\n  \"Черногория\",\n  \"Чехия\",\n  \"Чили\",\n  \"Швейцария\",\n  \"Швеция\",\n  \"Шри-Ланка\",\n  \"Эквадор\",\n  \"Экваториальная Гвинея\",\n  \"Эритрея\",\n  \"Эстония\",\n  \"Эфиопия\",\n  \"Южно-Африканская Республика\",\n  \"Ямайка\",\n  \"Япония\"\n];\n\n},{}],800:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Россия\"\n];\n\n},{}],801:[function(require,module,exports){\narguments[4][21][0].apply(exports,arguments)\n},{\"./building_number\":796,\"./city\":797,\"./city_name\":798,\"./country\":799,\"./default_country\":800,\"./postcode\":802,\"./secondary_address\":803,\"./state\":804,\"./street_address\":805,\"./street_name\":806,\"./street_suffix\":807,\"./street_title\":808,\"/Users/a/dev/faker.js/lib/locales/az/address/index.js\":21}],802:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"######\"\n];\n\n},{}],803:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"кв. ###\"\n];\n\n},{}],804:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Архангельская область\",\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  \"Оренбургская область\",\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  \"Усть-Ордынский Бурятский автономный округ\",\n  \"Ханты-Мансийский автономный округ\",\n  \"Чукотский автономный округ\",\n  \"Эвенкийский автономный округ\",\n  \"Ямало-Ненецкий автономный округ\",\n  \"Чеченская Республика\"\n];\n\n},{}],805:[function(require,module,exports){\nmodule.exports=require(25)\n},{\"/Users/a/dev/faker.js/lib/locales/az/address/street_address.js\":25}],806:[function(require,module,exports){\nmodule.exports=require(26)\n},{\"/Users/a/dev/faker.js/lib/locales/az/address/street_name.js\":26}],807:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ул.\",\n  \"улица\",\n  \"проспект\",\n  \"пр.\",\n  \"площадь\",\n  \"пл.\"\n];\n\n},{}],808:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Южная\",\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  \"Почтовая\",\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  \"Крупской\",\n  \"Березовая\",\n  \"Карла Маркса\",\n  \"8 Марта\",\n  \"Больничная\",\n  \"Садовый\",\n  \"Интернациональная\",\n  \"Суворова\",\n  \"Цветочная\",\n  \"Трактовая\",\n  \"Ломоносова\",\n  \"Горная\",\n  \"Космонавтов\",\n  \"Энергетиков\",\n  \"Шевченко\",\n  \"Весенняя\",\n  \"Механизаторов\",\n  \"Коммунальная\",\n  \"Лесной\",\n  \"40 лет Победы\",\n  \"Майская\"\n];\n\n},{}],809:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"красно-пурпурный\",\n  \"голубой\",\n  \"лазурный\",\n  \"лиловый\",\n  \"серебряный\"\n];\n\n},{}],810:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Книги\",\n  \"Фильмы\",\n  \"музыка\",\n  \"игры\",\n  \"Электроника\",\n  \"компьютеры\",\n  \"Дом\",\n  \"садинструмент\",\n  \"Бакалея\",\n  \"здоровье\",\n  \"красота\",\n  \"Игрушки\",\n  \"детское\",\n  \"для малышей\",\n  \"Одежда\",\n  \"обувь\",\n  \"украшения\",\n  \"Спорт\",\n  \"туризм\",\n  \"Автомобильное\",\n  \"промышленное\"\n];\n\n},{}],811:[function(require,module,exports){\narguments[4][31][0].apply(exports,arguments)\n},{\"./color\":809,\"./department\":810,\"./product_name\":812,\"/Users/a/dev/faker.js/lib/locales/az/commerce/index.js\":31}],812:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"adjective\": [\n    \"Маленький\",\n    \"Эргономичный\",\n    \"Грубый\",\n    \"Интеллектуальный\",\n    \"Великолепный\",\n    \"Невероятный\",\n    \"Фантастический\",\n    \"Практчиный\",\n    \"Лоснящийся\",\n    \"Потрясающий\"\n  ],\n  \"material\": [\n    \"Стальной\",\n    \"Деревянный\",\n    \"Бетонный\",\n    \"Пластиковый\",\n    \"Хлопковый\",\n    \"Гранитный\",\n    \"Резиновый\"\n  ],\n  \"product\": [\n    \"Стул\",\n    \"Автомобиль\",\n    \"Компьютер\",\n    \"Берет\",\n    \"Кулон\",\n    \"Стол\",\n    \"Свитер\",\n    \"Ремень\",\n    \"Ботинок\"\n  ]\n};\n\n},{}],813:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./name\":814,\"./prefix\":815,\"./suffix\":816,\"/Users/a/dev/faker.js/lib/locales/az/company/index.js\":33}],814:[function(require,module,exports){\nmodule.exports=require(34)\n},{\"/Users/a/dev/faker.js/lib/locales/az/company/name.js\":34}],815:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ИП\",\n  \"ООО\",\n  \"ЗАО\",\n  \"ОАО\",\n  \"НКО\",\n  \"ТСЖ\",\n  \"ОП\"\n];\n\n},{}],816:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Снаб\",\n  \"Торг\",\n  \"Пром\",\n  \"Трейд\",\n  \"Сбыт\"\n];\n\n},{}],817:[function(require,module,exports){\narguments[4][37][0].apply(exports,arguments)\n},{\"./month\":818,\"./weekday\":819,\"/Users/a/dev/faker.js/lib/locales/az/date/index.js\":37}],818:[function(require,module,exports){\n// source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/ru.xml#L1734\nmodule[\"exports\"] = {\n  wide: [\n    \"январь\",\n    \"февраль\",\n    \"март\",\n    \"апрель\",\n    \"май\",\n    \"июнь\",\n    \"июль\",\n    \"август\",\n    \"сентябрь\",\n    \"октябрь\",\n    \"ноябрь\",\n    \"декабрь\"\n  ],\n  wide_context: [\n    \"января\",\n    \"февраля\",\n    \"марта\",\n    \"апреля\",\n    \"мая\",\n    \"июня\",\n    \"июля\",\n    \"августа\",\n    \"сентября\",\n    \"октября\",\n    \"ноября\",\n    \"декабря\"\n  ],\n  abbr: [\n    \"янв.\",\n    \"февр.\",\n    \"март\",\n    \"апр.\",\n    \"май\",\n    \"июнь\",\n    \"июль\",\n    \"авг.\",\n    \"сент.\",\n    \"окт.\",\n    \"нояб.\",\n    \"дек.\"\n  ],\n  abbr_context: [\n    \"янв.\",\n    \"февр.\",\n    \"марта\",\n    \"апр.\",\n    \"мая\",\n    \"июня\",\n    \"июля\",\n    \"авг.\",\n    \"сент.\",\n    \"окт.\",\n    \"нояб.\",\n    \"дек.\"\n  ]\n};\n\n},{}],819:[function(require,module,exports){\n// source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/ru.xml#L1825\nmodule[\"exports\"] = {\n  wide: [\n    \"Воскресенье\",\n    \"Понедельник\",\n    \"Вторник\",\n    \"Среда\",\n    \"Четверг\",\n    \"Пятница\",\n    \"Суббота\"\n  ],\n  wide_context: [\n    \"воскресенье\",\n    \"понедельник\",\n    \"вторник\",\n    \"среда\",\n    \"четверг\",\n    \"пятница\",\n    \"суббота\"\n  ],\n  abbr: [\n    \"Вс\",\n    \"Пн\",\n    \"Вт\",\n    \"Ср\",\n    \"Чт\",\n    \"Пт\",\n    \"Сб\"\n  ],\n  abbr_context: [\n    \"вс\",\n    \"пн\",\n    \"вт\",\n    \"ср\",\n    \"чт\",\n    \"пт\",\n    \"сб\"\n  ]\n};\n\n},{}],820:[function(require,module,exports){\nvar ru = {};\nmodule['exports'] = ru;\nru.title = \"Russian\";\nru.separator = \" и \";\nru.address = require(\"./address\");\nru.internet = require(\"./internet\");\nru.name = require(\"./name\");\nru.phone_number = require(\"./phone_number\");\nru.commerce = require(\"./commerce\");\nru.company = require(\"./company\");\nru.date = require(\"./date\");\n\n},{\"./address\":801,\"./commerce\":811,\"./company\":813,\"./date\":817,\"./internet\":823,\"./name\":827,\"./phone_number\":835}],821:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"ru\",\n  \"info\",\n  \"рф\",\n  \"net\",\n  \"org\"\n];\n\n},{}],822:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"yandex.ru\",\n  \"ya.ru\",\n  \"mail.ru\",\n  \"gmail.com\",\n  \"yahoo.com\",\n  \"hotmail.com\"\n];\n\n},{}],823:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":821,\"./free_email\":822,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],824:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Елизавета\",\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  \"Татьяна\",\n  \"Ульяна\",\n  \"Юлия\"\n];\n\n},{}],825:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Орлова\",\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  \"Никитина\",\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  \"Веселова\",\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  \"Гаврилова\",\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  \"Назарова\",\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  \"Евдокимова\",\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  \"Зиновьева\",\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  \"Одинцова\",\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  \"Блохина\",\n  \"Селиверстова\",\n  \"Пестова\",\n  \"Кондратьева\",\n  \"Силина\",\n  \"Меркушева\",\n  \"Лыткина\",\n  \"Турова\"\n];\n\n},{}],826:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Евгеньевна\",\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},{}],827:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.male_first_name = require(\"./male_first_name\");\nname.male_middle_name = require(\"./male_middle_name\");\nname.male_last_name = require(\"./male_last_name\");\nname.female_first_name = require(\"./female_first_name\");\nname.female_middle_name = require(\"./female_middle_name\");\nname.female_last_name = require(\"./female_last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\nname.name = require(\"./name\");\n\n},{\"./female_first_name\":824,\"./female_last_name\":825,\"./female_middle_name\":826,\"./male_first_name\":828,\"./male_last_name\":829,\"./male_middle_name\":830,\"./name\":831,\"./prefix\":832,\"./suffix\":833}],828:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Евгений\",\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\n},{}],829:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Орлов\",\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  \"Никитин\",\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  \"Веселов\",\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  \"Гаврилов\",\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  \"Назаров\",\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  \"Евдокимов\",\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  \"Зиновьев\",\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  \"Одинцов\",\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  \"Блохин\",\n  \"Селиверстов\",\n  \"Пестов\",\n  \"Кондратьев\",\n  \"Силин\",\n  \"Меркушев\",\n  \"Лыткин\",\n  \"Туров\"\n];\n\n},{}],830:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Евгеньевич\",\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\n},{}],831:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{male_first_name} #{male_last_name}\",\n  \"#{male_last_name} #{male_first_name}\",\n  \"#{male_first_name} #{male_middle_name} #{male_last_name}\",\n  \"#{male_last_name} #{male_first_name} #{male_middle_name}\",\n  \"#{female_first_name} #{female_last_name}\",\n  \"#{female_last_name} #{female_first_name}\",\n  \"#{female_first_name} #{female_middle_name} #{female_last_name}\",\n  \"#{female_last_name} #{female_first_name} #{female_middle_name}\"\n];\n\n},{}],832:[function(require,module,exports){\nmodule.exports=require(50)\n},{\"/Users/a/dev/faker.js/lib/locales/az/name/prefix.js\":50}],833:[function(require,module,exports){\nmodule.exports=require(50)\n},{\"/Users/a/dev/faker.js/lib/locales/az/name/prefix.js\":50}],834:[function(require,module,exports){\nmodule.exports=require(52)\n},{\"/Users/a/dev/faker.js/lib/locales/az/phone_number/formats.js\":52}],835:[function(require,module,exports){\nmodule.exports=require(53)\n},{\"./formats\":834,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],836:[function(require,module,exports){\nmodule.exports=require(54)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/building_number.js\":54}],837:[function(require,module,exports){\nmodule.exports=require(55)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/city.js\":55}],838:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Bánovce nad Bebravou\",\n  \"Banská Bystrica\",\n  \"Banská Štiavnica\",\n  \"Bardejov\",\n  \"Bratislava I\",\n  \"Bratislava II\",\n  \"Bratislava III\",\n  \"Bratislava IV\",\n  \"Bratislava V\",\n  \"Brezno\",\n  \"Bytča\",\n  \"Čadca\",\n  \"Detva\",\n  \"Dolný Kubín\",\n  \"Dunajská Streda\",\n  \"Galanta\",\n  \"Gelnica\",\n  \"Hlohovec\",\n  \"Humenné\",\n  \"Ilava\",\n  \"Kežmarok\",\n  \"Komárno\",\n  \"Košice I\",\n  \"Košice II\",\n  \"Košice III\",\n  \"Košice IV\",\n  \"Košice-okolie\",\n  \"Krupina\",\n  \"Kysucké Nové Mesto\",\n  \"Levice\",\n  \"Levoča\",\n  \"Liptovský Mikuláš\",\n  \"Lučenec\",\n  \"Malacky\",\n  \"Martin\",\n  \"Medzilaborce\",\n  \"Michalovce\",\n  \"Myjava\",\n  \"Námestovo\",\n  \"Nitra\",\n  \"Nové Mesto n.Váhom\",\n  \"Nové Zámky\",\n  \"Partizánske\",\n  \"Pezinok\",\n  \"Piešťany\",\n  \"Poltár\",\n  \"Poprad\",\n  \"Považská Bystrica\",\n  \"Prešov\",\n  \"Prievidza\",\n  \"Púchov\",\n  \"Revúca\",\n  \"Rimavská Sobota\",\n  \"Rožňava\",\n  \"Ružomberok\",\n  \"Sabinov\",\n  \"Šaľa\",\n  \"Senec\",\n  \"Senica\",\n  \"Skalica\",\n  \"Snina\",\n  \"Sobrance\",\n  \"Spišská Nová Ves\",\n  \"Stará Ľubovňa\",\n  \"Stropkov\",\n  \"Svidník\",\n  \"Topoľčany\",\n  \"Trebišov\",\n  \"Trenčín\",\n  \"Trnava\",\n  \"Turčianske Teplice\",\n  \"Tvrdošín\",\n  \"Veľký Krtíš\",\n  \"Vranov nad Topľou\",\n  \"Žarnovica\",\n  \"Žiar nad Hronom\",\n  \"Žilina\",\n  \"Zlaté Moravce\",\n  \"Zvolen\"\n];\n\n},{}],839:[function(require,module,exports){\nmodule.exports=require(181)\n},{\"/Users/a/dev/faker.js/lib/locales/en/address/city_prefix.js\":181}],840:[function(require,module,exports){\nmodule.exports=require(182)\n},{\"/Users/a/dev/faker.js/lib/locales/en/address/city_suffix.js\":182}],841:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afganistan\",\n  \"Afgánsky islamský štát\",\n  \"Albánsko\",\n  \"Albánska republika\",\n  \"Alžírsko\",\n  \"Alžírska demokratická ľudová republika\",\n  \"Andorra\",\n  \"Andorrské kniežatsvo\",\n  \"Angola\",\n  \"Angolská republika\",\n  \"Antigua a Barbuda\",\n  \"Antigua a Barbuda\",\n  \"Argentína\",\n  \"Argentínska republika\",\n  \"Arménsko\",\n  \"Arménska republika\",\n  \"Austrália\",\n  \"Austrálsky zväz\",\n  \"Azerbajdžan\",\n  \"Azerbajdžanská republika\",\n  \"Bahamy\",\n  \"Bahamské spoločenstvo\",\n  \"Bahrajn\",\n  \"Bahrajnské kráľovstvo\",\n  \"Bangladéš\",\n  \"Bangladéšska ľudová republika\",\n  \"Barbados\",\n  \"Barbados\",\n  \"Belgicko\",\n  \"Belgické kráľovstvo\",\n  \"Belize\",\n  \"Belize\",\n  \"Benin\",\n  \"Beninská republika\",\n  \"Bhután\",\n  \"Bhutánske kráľovstvo\",\n  \"Bielorusko\",\n  \"Bieloruská republika\",\n  \"Bolívia\",\n  \"Bolívijská republika\",\n  \"Bosna a Hercegovina\",\n  \"Republika Bosny a Hercegoviny\",\n  \"Botswana\",\n  \"Botswanská republika\",\n  \"Brazília\",\n  \"Brazílska federatívna republika\",\n  \"Brunej\",\n  \"Brunejský sultanát\",\n  \"Bulharsko\",\n  \"Bulharská republika\",\n  \"Burkina Faso\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Burundská republika\",\n  \"Cyprus\",\n  \"Cyperská republika\",\n  \"Čad\",\n  \"Republika Čad\",\n  \"Česko\",\n  \"Česká republika\",\n  \"Čína\",\n  \"Čínska ľudová republika\",\n  \"Dánsko\",\n  \"Dánsko kráľovstvo\",\n  \"Dominika\",\n  \"Spoločenstvo Dominika\",\n  \"Dominikánska republika\",\n  \"Dominikánska republika\",\n  \"Džibutsko\",\n  \"Džibutská republika\",\n  \"Egypt\",\n  \"Egyptská arabská republika\",\n  \"Ekvádor\",\n  \"Ekvádorská republika\",\n  \"Eritrea\",\n  \"Eritrejský štát\",\n  \"Estónsko\",\n  \"Estónska republika\",\n  \"Etiópia\",\n  \"Etiópska federatívna demokratická republika\",\n  \"Fidži\",\n  \"Republika ostrovy Fidži\",\n  \"Filipíny\",\n  \"Filipínska republika\",\n  \"Fínsko\",\n  \"Fínska republika\",\n  \"Francúzsko\",\n  \"Francúzska republika\",\n  \"Gabon\",\n  \"Gabonská republika\",\n  \"Gambia\",\n  \"Gambijská republika\",\n  \"Ghana\",\n  \"Ghanská republika\",\n  \"Grécko\",\n  \"Helénska republika\",\n  \"Grenada\",\n  \"Grenada\",\n  \"Gruzínsko\",\n  \"Gruzínsko\",\n  \"Guatemala\",\n  \"Guatemalská republika\",\n  \"Guinea\",\n  \"Guinejská republika\",\n  \"Guinea-Bissau\",\n  \"Republika Guinea-Bissau\",\n  \"Guayana\",\n  \"Guayanská republika\",\n  \"Haiti\",\n  \"Republika Haiti\",\n  \"Holandsko\",\n  \"Holandské kráľovstvo\",\n  \"Honduras\",\n  \"Honduraská republika\",\n  \"Chile\",\n  \"Čílska republika\",\n  \"Chorvátsko\",\n  \"Chorvátska republika\",\n  \"India\",\n  \"Indická republika\",\n  \"Indonézia\",\n  \"Indonézska republika\",\n  \"Irak\",\n  \"Iracká republika\",\n  \"Irán\",\n  \"Iránska islamská republika\",\n  \"Island\",\n  \"Islandská republika\",\n  \"Izrael\",\n  \"Štát Izrael\",\n  \"Írsko\",\n  \"Írska republika\",\n  \"Jamajka\",\n  \"Jamajka\",\n  \"Japonsko\",\n  \"Japonsko\",\n  \"Jemen\",\n  \"Jemenská republika\",\n  \"Jordánsko\",\n  \"Jordánske hášimovské kráľovstvo\",\n  \"Južná Afrika\",\n  \"Juhoafrická republika\",\n  \"Kambodža\",\n  \"Kambodžské kráľovstvo\",\n  \"Kamerun\",\n  \"Kamerunská republika\",\n  \"Kanada\",\n  \"Kanada\",\n  \"Kapverdy\",\n  \"Kapverdská republika\",\n  \"Katar\",\n  \"Štát Katar\",\n  \"Kazachstan\",\n  \"Kazašská republika\",\n  \"Keňa\",\n  \"Kenská republika\",\n  \"Kirgizsko\",\n  \"Kirgizská republika\",\n  \"Kiribati\",\n  \"Kiribatská republika\",\n  \"Kolumbia\",\n  \"Kolumbijská republika\",\n  \"Komory\",\n  \"Komorská únia\",\n  \"Kongo\",\n  \"Konžská demokratická republika\",\n  \"Kongo (\\\"Brazzaville\\\")\",\n  \"Konžská republika\",\n  \"Kórea (\\\"Južná\\\")\",\n  \"Kórejská republika\",\n  \"Kórea (\\\"Severná\\\")\",\n  \"Kórejská ľudovodemokratická republika\",\n  \"Kostarika\",\n  \"Kostarická republika\",\n  \"Kuba\",\n  \"Kubánska republika\",\n  \"Kuvajt\",\n  \"Kuvajtský štát\",\n  \"Laos\",\n  \"Laoská ľudovodemokratická republika\",\n  \"Lesotho\",\n  \"Lesothské kráľovstvo\",\n  \"Libanon\",\n  \"Libanonská republika\",\n  \"Libéria\",\n  \"Libérijská republika\",\n  \"Líbya\",\n  \"Líbyjská arabská ľudová socialistická džamáhírija\",\n  \"Lichtenštajnsko\",\n  \"Lichtenštajnské kniežatstvo\",\n  \"Litva\",\n  \"Litovská republika\",\n  \"Lotyšsko\",\n  \"Lotyšská republika\",\n  \"Luxembursko\",\n  \"Luxemburské veľkovojvodstvo\",\n  \"Macedónsko\",\n  \"Macedónska republika\",\n  \"Madagaskar\",\n  \"Madagaskarská republika\",\n  \"Maďarsko\",\n  \"Maďarská republika\",\n  \"Malajzia\",\n  \"Malajzia\",\n  \"Malawi\",\n  \"Malawijská republika\",\n  \"Maldivy\",\n  \"Maldivská republika\",\n  \"Mali\",\n  \"Malijská republika\",\n  \"Malta\",\n  \"Malta\",\n  \"Maroko\",\n  \"Marocké kráľovstvo\",\n  \"Marshallove ostrovy\",\n  \"Republika Marshallových ostrovy\",\n  \"Mauritánia\",\n  \"Mauritánska islamská republika\",\n  \"Maurícius\",\n  \"Maurícijská republika\",\n  \"Mexiko\",\n  \"Spojené štáty mexické\",\n  \"Mikronézia\",\n  \"Mikronézske federatívne štáty\",\n  \"Mjanmarsko\",\n  \"Mjanmarský zväz\",\n  \"Moldavsko\",\n  \"Moldavská republika\",\n  \"Monako\",\n  \"Monacké kniežatstvo\",\n  \"Mongolsko\",\n  \"Mongolsko\",\n  \"Mozambik\",\n  \"Mozambická republika\",\n  \"Namíbia\",\n  \"Namíbijská republika\",\n  \"Nauru\",\n  \"Naurská republika\",\n  \"Nemecko\",\n  \"Nemecká spolková republika\",\n  \"Nepál\",\n  \"Nepálske kráľovstvo\",\n  \"Niger\",\n  \"Nigerská republika\",\n  \"Nigéria\",\n  \"Nigérijská federatívna republika\",\n  \"Nikaragua\",\n  \"Nikaragujská republika\",\n  \"Nový Zéland\",\n  \"Nový Zéland\",\n  \"Nórsko\",\n  \"Nórske kráľovstvo\",\n  \"Omán\",\n  \"Ománsky sultanát\",\n  \"Pakistan\",\n  \"Pakistanská islamská republika\",\n  \"Palau\",\n  \"Palauská republika\",\n  \"Panama\",\n  \"Panamská republika\",\n  \"Papua-Nová Guinea\",\n  \"Nezávislý štát Papua-Nová Guinea\",\n  \"Paraguaj\",\n  \"Paraguajská republika\",\n  \"Peru\",\n  \"Peruánska republika\",\n  \"Pobrežie Slonoviny\",\n  \"Republika Pobrežie Slonoviny\",\n  \"Poľsko\",\n  \"Poľská republika\",\n  \"Portugalsko\",\n  \"Portugalská republika\",\n  \"Rakúsko\",\n  \"Rakúska republika\",\n  \"Rovníková Guinea\",\n  \"Republika Rovníková Guinea\",\n  \"Rumunsko\",\n  \"Rumunsko\",\n  \"Rusko\",\n  \"Ruská federácia\",\n  \"Rwanda\",\n  \"Rwandská republika\",\n  \"Salvádor\",\n  \"Salvádorská republika\",\n  \"Samoa\",\n  \"Nezávislý štát Samoa\",\n  \"San Maríno\",\n  \"Sanmarínska republika\",\n  \"Saudská Arábia\",\n  \"Kráľovstvo Saudskej Arábie\",\n  \"Senegal\",\n  \"Senegalská republika\",\n  \"Seychely\",\n  \"Seychelská republika\",\n  \"Sierra Leone\",\n  \"Republika Sierra Leone\",\n  \"Singapur\",\n  \"Singapurska republika\",\n  \"Slovensko\",\n  \"Slovenská republika\",\n  \"Slovinsko\",\n  \"Slovinská republika\",\n  \"Somálsko\",\n  \"Somálska demokratická republika\",\n  \"Spojené arabské emiráty\",\n  \"Spojené arabské emiráty\",\n  \"Spojené štáty americké\",\n  \"Spojené štáty americké\",\n  \"Srbsko a Čierna Hora\",\n  \"Srbsko a Čierna Hora\",\n  \"Srí Lanka\",\n  \"Demokratická socialistická republika Srí Lanka\",\n  \"Stredoafrická republika\",\n  \"Stredoafrická republika\",\n  \"Sudán\",\n  \"Sudánska republika\",\n  \"Surinam\",\n  \"Surinamská republika\",\n  \"Svazijsko\",\n  \"Svazijské kráľovstvo\",\n  \"Svätá Lucia\",\n  \"Svätá Lucia\",\n  \"Svätý Krištof a Nevis\",\n  \"Federácia Svätý Krištof a Nevis\",\n  \"Sv. Tomáš a Princov Ostrov\",\n  \"Demokratická republika Svätý Tomáš a Princov Ostrov\",\n  \"Sv. Vincent a Grenadíny\",\n  \"Svätý Vincent a Grenadíny\",\n  \"Sýria\",\n  \"Sýrska arabská republika\",\n  \"Šalamúnove ostrovy\",\n  \"Šalamúnove ostrovy\",\n  \"Španielsko\",\n  \"Španielske kráľovstvo\",\n  \"Švajčiarsko\",\n  \"Švajčiarska konfederácia\",\n  \"Švédsko\",\n  \"Švédske kráľovstvo\",\n  \"Tadžikistan\",\n  \"Tadžická republika\",\n  \"Taliansko\",\n  \"Talianska republika\",\n  \"Tanzánia\",\n  \"Tanzánijská zjednotená republika\",\n  \"Thajsko\",\n  \"Thajské kráľovstvo\",\n  \"Togo\",\n  \"Tožská republika\",\n  \"Tonga\",\n  \"Tonžské kráľovstvo\",\n  \"Trinidad a Tobago\",\n  \"Republika Trinidad a Tobago\",\n  \"Tunisko\",\n  \"Tuniská republika\",\n  \"Turecko\",\n  \"Turecká republika\",\n  \"Turkménsko\",\n  \"Turkménsko\",\n  \"Tuvalu\",\n  \"Tuvalu\",\n  \"Uganda\",\n  \"Ugandská republika\",\n  \"Ukrajina\",\n  \"Uruguaj\",\n  \"Uruguajská východná republika\",\n  \"Uzbekistan\",\n  \"Vanuatu\",\n  \"Vanuatská republika\",\n  \"Vatikán\",\n  \"Svätá Stolica\",\n  \"Veľká Británia\",\n  \"Spojené kráľovstvo Veľkej Británie a Severného Írska\",\n  \"Venezuela\",\n  \"Venezuelská bolívarovská republika\",\n  \"Vietnam\",\n  \"Vietnamská socialistická republika\",\n  \"Východný Timor\",\n  \"Demokratická republika Východný Timor\",\n  \"Zambia\",\n  \"Zambijská republika\",\n  \"Zimbabwe\",\n  \"Zimbabwianska republika\"\n];\n\n},{}],842:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Slovensko\"\n];\n\n},{}],843:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.time_zone = require(\"./time_zone\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.street = require(\"./street\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":836,\"./city\":837,\"./city_name\":838,\"./city_prefix\":839,\"./city_suffix\":840,\"./country\":841,\"./default_country\":842,\"./postcode\":844,\"./secondary_address\":845,\"./state\":846,\"./state_abbr\":847,\"./street\":848,\"./street_address\":849,\"./street_name\":850,\"./time_zone\":851}],844:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\",\n  \"### ##\",\n  \"## ###\"\n];\n\n},{}],845:[function(require,module,exports){\nmodule.exports=require(61)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/secondary_address.js\":61}],846:[function(require,module,exports){\nmodule.exports=require(50)\n},{\"/Users/a/dev/faker.js/lib/locales/az/name/prefix.js\":50}],847:[function(require,module,exports){\nmodule.exports=require(50)\n},{\"/Users/a/dev/faker.js/lib/locales/az/name/prefix.js\":50}],848:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adámiho\",\n  \"Ahoj\",\n  \"Albína Brunovského\",\n  \"Albrechtova\",\n  \"Alejová\",\n  \"Alešova\",\n  \"Alibernetová\",\n  \"Alžbetínska\",\n  \"Alžbety Gwerkovej\",\n  \"Ambroseho\",\n  \"Ambrušova\",\n  \"Americká\",\n  \"Americké námestie\",\n  \"Americké námestie\",\n  \"Andreja Mráza\",\n  \"Andreja Plávku\",\n  \"Andrusovova\",\n  \"Anenská\",\n  \"Anenská\",\n  \"Antolská\",\n  \"Astronomická\",\n  \"Astrová\",\n  \"Azalková\",\n  \"Azovská\",\n  \"Babuškova\",\n  \"Bachova\",\n  \"Bajkalská\",\n  \"Bajkalská\",\n  \"Bajkalská\",\n  \"Bajkalská\",\n  \"Bajkalská\",\n  \"Bajkalská\",\n  \"Bajzova\",\n  \"Bancíkovej\",\n  \"Banícka\",\n  \"Baníkova\",\n  \"Banskobystrická\",\n  \"Banšelova\",\n  \"Bardejovská\",\n  \"Bartókova\",\n  \"Bartoňova\",\n  \"Bartoškova\",\n  \"Baštová\",\n  \"Bazová\",\n  \"Bažantia\",\n  \"Beblavého\",\n  \"Beckovská\",\n  \"Bedľová\",\n  \"Belániková\",\n  \"Belehradská\",\n  \"Belinského\",\n  \"Belopotockého\",\n  \"Beňadická\",\n  \"Bencúrova\",\n  \"Benediktiho\",\n  \"Beniakova\",\n  \"Bernolákova\",\n  \"Beskydská\",\n  \"Betliarska\",\n  \"Bezručova\",\n  \"Biela\",\n  \"Bielkova\",\n  \"Björnsonova\",\n  \"Blagoevova\",\n  \"Blatnická\",\n  \"Blumentálska\",\n  \"Blyskáčová\",\n  \"Bočná\",\n  \"Bohrova\",\n  \"Bohúňova\",\n  \"Bojnická\",\n  \"Borodáčova\",\n  \"Borská\",\n  \"Bosákova\",\n  \"Botanická\",\n  \"Bottova\",\n  \"Boženy Němcovej\",\n  \"Bôrik\",\n  \"Bradáčova\",\n  \"Bradlianska\",\n  \"Brančská\",\n  \"Bratská\",\n  \"Brestová\",\n  \"Brezovská\",\n  \"Briežky\",\n  \"Brnianska\",\n  \"Brodná\",\n  \"Brodská\",\n  \"Broskyňová\",\n  \"Břeclavská\",\n  \"Budatínska\",\n  \"Budatínska\",\n  \"Budatínska\",\n  \"Búdkova  cesta\",\n  \"Budovateľská\",\n  \"Budyšínska\",\n  \"Budyšínska\",\n  \"Buková\",\n  \"Bukureštská\",\n  \"Bulharská\",\n  \"Bulíkova\",\n  \"Bystrého\",\n  \"Bzovícka\",\n  \"Cablkova\",\n  \"Cesta na Červený most\",\n  \"Cesta na Červený most\",\n  \"Cesta na Senec\",\n  \"Cikkerova\",\n  \"Cintorínska\",\n  \"Cintulova\",\n  \"Cukrová\",\n  \"Cyrilova\",\n  \"Čajakova\",\n  \"Čajkovského\",\n  \"Čaklovská\",\n  \"Čalovská\",\n  \"Čapajevova\",\n  \"Čapkova\",\n  \"Čárskeho\",\n  \"Čavojského\",\n  \"Čečinová\",\n  \"Čelakovského\",\n  \"Čerešňová\",\n  \"Černyševského\",\n  \"Červeňova\",\n  \"Česká\",\n  \"Československých par\",\n  \"Čipkárska\",\n  \"Čmelíkova\",\n  \"Čmeľovec\",\n  \"Čulenova\",\n  \"Daliborovo námestie\",\n  \"Dankovského\",\n  \"Dargovská\",\n  \"Ďatelinová\",\n  \"Daxnerovo námestie\",\n  \"Devínska cesta\",\n  \"Dlhé diely I.\",\n  \"Dlhé diely II.\",\n  \"Dlhé diely III.\",\n  \"Dobrovičova\",\n  \"Dobrovičova\",\n  \"Dobrovského\",\n  \"Dobšinského\",\n  \"Dohnalova\",\n  \"Dohnányho\",\n  \"Doležalova\",\n  \"Dolná\",\n  \"Dolnozemská cesta\",\n  \"Domkárska\",\n  \"Domové role\",\n  \"Donnerova\",\n  \"Donovalova\",\n  \"Dostojevského rad\",\n  \"Dr. Vladimíra Clemen\",\n  \"Drevená\",\n  \"Drieňová\",\n  \"Drieňová\",\n  \"Drieňová\",\n  \"Drotárska cesta\",\n  \"Drotárska cesta\",\n  \"Drotárska cesta\",\n  \"Družicová\",\n  \"Družstevná\",\n  \"Dubnická\",\n  \"Dubová\",\n  \"Dúbravská cesta\",\n  \"Dudova\",\n  \"Dulovo námestie\",\n  \"Dulovo námestie\",\n  \"Dunajská\",\n  \"Dvořákovo nábrežie\",\n  \"Edisonova\",\n  \"Einsteinova\",\n  \"Elektrárenská\",\n  \"Exnárova\",\n  \"F. Kostku\",\n  \"Fadruszova\",\n  \"Fajnorovo nábrežie\",\n  \"Fándlyho\",\n  \"Farebná\",\n  \"Farská\",\n  \"Farského\",\n  \"Fazuľová\",\n  \"Fedinova\",\n  \"Ferienčíkova\",\n  \"Fialkové údolie\",\n  \"Fibichova\",\n  \"Filiálne nádražie\",\n  \"Flöglova\",\n  \"Floriánske námestie\",\n  \"Fraňa Kráľa\",\n  \"Francisciho\",\n  \"Francúzskych partizá\",\n  \"Františkánska\",\n  \"Františkánske námest\",\n  \"Furdekova\",\n  \"Furdekova\",\n  \"Gabčíkova\",\n  \"Gagarinova\",\n  \"Gagarinova\",\n  \"Gagarinova\",\n  \"Gajova\",\n  \"Galaktická\",\n  \"Galandova\",\n  \"Gallova\",\n  \"Galvaniho\",\n  \"Gašparíkova\",\n  \"Gaštanová\",\n  \"Gavlovičova\",\n  \"Gemerská\",\n  \"Gercenova\",\n  \"Gessayova\",\n  \"Gettingová\",\n  \"Godrova\",\n  \"Gogoľova\",\n  \"Goláňova\",\n  \"Gondova\",\n  \"Goralská\",\n  \"Gorazdova\",\n  \"Gorkého\",\n  \"Gregorovej\",\n  \"Grösslingova\",\n  \"Gruzínska\",\n  \"Gunduličova\",\n  \"Gusevova\",\n  \"Haanova\",\n  \"Haburská\",\n  \"Halašova\",\n  \"Hálkova\",\n  \"Hálova\",\n  \"Hamuliakova\",\n  \"Hanácka\",\n  \"Handlovská\",\n  \"Hany Meličkovej\",\n  \"Harmanecká\",\n  \"Hasičská\",\n  \"Hattalova\",\n  \"Havlíčkova\",\n  \"Havrania\",\n  \"Haydnova\",\n  \"Herlianska\",\n  \"Herlianska\",\n  \"Heydukova\",\n  \"Hlaváčikova\",\n  \"Hlavatého\",\n  \"Hlavné námestie\",\n  \"Hlboká cesta\",\n  \"Hlboká cesta\",\n  \"Hlivová\",\n  \"Hlučínska\",\n  \"Hodálova\",\n  \"Hodžovo námestie\",\n  \"Holekova\",\n  \"Holíčska\",\n  \"Hollého\",\n  \"Holubyho\",\n  \"Hontianska\",\n  \"Horárska\",\n  \"Horné Židiny\",\n  \"Horská\",\n  \"Horská\",\n  \"Hrad\",\n  \"Hradné údolie\",\n  \"Hrachová\",\n  \"Hraničná\",\n  \"Hrebendova\",\n  \"Hríbová\",\n  \"Hriňovská\",\n  \"Hrobákova\",\n  \"Hrobárska\",\n  \"Hroboňova\",\n  \"Hudecova\",\n  \"Humenské námestie\",\n  \"Hummelova\",\n  \"Hurbanovo námestie\",\n  \"Hurbanovo námestie\",\n  \"Hviezdoslavovo námes\",\n  \"Hýrošova\",\n  \"Chalupkova\",\n  \"Chemická\",\n  \"Chlumeckého\",\n  \"Chorvátska\",\n  \"Chorvátska\",\n  \"Iľjušinova\",\n  \"Ilkovičova\",\n  \"Inovecká\",\n  \"Inovecká\",\n  \"Iskerníková\",\n  \"Ivana Horvátha\",\n  \"Ivánska cesta\",\n  \"J.C.Hronského\",\n  \"Jabloňová\",\n  \"Jadrová\",\n  \"Jakabova\",\n  \"Jakubovo námestie\",\n  \"Jamnického\",\n  \"Jána Stanislava\",\n  \"Janáčkova\",\n  \"Jančova\",\n  \"Janíkove role\",\n  \"Jankolova\",\n  \"Jánošíkova\",\n  \"Jánoškova\",\n  \"Janotova\",\n  \"Jánska\",\n  \"Jantárová cesta\",\n  \"Jarabinková\",\n  \"Jarná\",\n  \"Jaroslavova\",\n  \"Jarošova\",\n  \"Jaseňová\",\n  \"Jasná\",\n  \"Jasovská\",\n  \"Jastrabia\",\n  \"Jašíkova\",\n  \"Javorinská\",\n  \"Javorová\",\n  \"Jazdecká\",\n  \"Jedlíkova\",\n  \"Jégého\",\n  \"Jelačičova\",\n  \"Jelenia\",\n  \"Jesenná\",\n  \"Jesenského\",\n  \"Jiráskova\",\n  \"Jiskrova\",\n  \"Jozefská\",\n  \"Junácka\",\n  \"Jungmannova\",\n  \"Jurigovo námestie\",\n  \"Jurovského\",\n  \"Jurská\",\n  \"Justičná\",\n  \"K lomu\",\n  \"K Železnej studienke\",\n  \"Kalinčiakova\",\n  \"Kamenárska\",\n  \"Kamenné námestie\",\n  \"Kapicova\",\n  \"Kapitulská\",\n  \"Kapitulský dvor\",\n  \"Kapucínska\",\n  \"Kapušianska\",\n  \"Karadžičova\",\n  \"Karadžičova\",\n  \"Karadžičova\",\n  \"Karadžičova\",\n  \"Karloveská\",\n  \"Karloveské rameno\",\n  \"Karpatská\",\n  \"Kašmírska\",\n  \"Kaštielska\",\n  \"Kaukazská\",\n  \"Kempelenova\",\n  \"Kežmarské námestie\",\n  \"Kladnianska\",\n  \"Klariská\",\n  \"Kláštorská\",\n  \"Klatovská\",\n  \"Klatovská\",\n  \"Klemensova\",\n  \"Klincová\",\n  \"Klobučnícka\",\n  \"Klokočova\",\n  \"Kľukatá\",\n  \"Kmeťovo námestie\",\n  \"Koceľova\",\n  \"Kočánkova\",\n  \"Kohútova\",\n  \"Kolárska\",\n  \"Kolískova\",\n  \"Kollárovo námestie\",\n  \"Kollárovo námestie\",\n  \"Kolmá\",\n  \"Komárňanská\",\n  \"Komárnická\",\n  \"Komárnická\",\n  \"Komenského námestie\",\n  \"Kominárska\",\n  \"Komonicová\",\n  \"Konopná\",\n  \"Konvalinková\",\n  \"Konventná\",\n  \"Kopanice\",\n  \"Kopčianska\",\n  \"Koperníkova\",\n  \"Korabinského\",\n  \"Koreničova\",\n  \"Kostlivého\",\n  \"Kostolná\",\n  \"Košická\",\n  \"Košická\",\n  \"Košická\",\n  \"Kováčska\",\n  \"Kovorobotnícka\",\n  \"Kozia\",\n  \"Koziarka\",\n  \"Kozmonautická\",\n  \"Krajná\",\n  \"Krakovská\",\n  \"Kráľovské údolie\",\n  \"Krasinského\",\n  \"Kraskova\",\n  \"Krásna\",\n  \"Krásnohorská\",\n  \"Krasovského\",\n  \"Krátka\",\n  \"Krčméryho\",\n  \"Kremnická\",\n  \"Kresánkova\",\n  \"Krivá\",\n  \"Križkova\",\n  \"Krížna\",\n  \"Krížna\",\n  \"Krížna\",\n  \"Krížna\",\n  \"Krmanova\",\n  \"Krompašská\",\n  \"Krupinská\",\n  \"Krupkova\",\n  \"Kubániho\",\n  \"Kubínska\",\n  \"Kuklovská\",\n  \"Kukučínova\",\n  \"Kukuričná\",\n  \"Kulíškova\",\n  \"Kultúrna\",\n  \"Kupeckého\",\n  \"Kúpeľná\",\n  \"Kutlíkova\",\n  \"Kutuzovova\",\n  \"Kuzmányho\",\n  \"Kvačalova\",\n  \"Kvetná\",\n  \"Kýčerského\",\n  \"Kyjevská\",\n  \"Kysucká\",\n  \"Laborecká\",\n  \"Lackova\",\n  \"Ladislava Sáru\",\n  \"Ľadová\",\n  \"Lachova\",\n  \"Ľaliová\",\n  \"Lamačská cesta\",\n  \"Lamačská cesta\",\n  \"Lamanského\",\n  \"Landererova\",\n  \"Langsfeldova\",\n  \"Ľanová\",\n  \"Laskomerského\",\n  \"Laučekova\",\n  \"Laurinská\",\n  \"Lazaretská\",\n  \"Lazaretská\",\n  \"Legerského\",\n  \"Legionárska\",\n  \"Legionárska\",\n  \"Lehockého\",\n  \"Lehockého\",\n  \"Lenardova\",\n  \"Lermontovova\",\n  \"Lesná\",\n  \"Leškova\",\n  \"Letecká\",\n  \"Letisko M.R.Štefánik\",\n  \"Letná\",\n  \"Levárska\",\n  \"Levická\",\n  \"Levočská\",\n  \"Lidická\",\n  \"Lietavská\",\n  \"Lichardova\",\n  \"Lipová\",\n  \"Lipovinová\",\n  \"Liptovská\",\n  \"Listová\",\n  \"Líščie nivy\",\n  \"Líščie údolie\",\n  \"Litovská\",\n  \"Lodná\",\n  \"Lombardiniho\",\n  \"Lomonosovova\",\n  \"Lopenícka\",\n  \"Lovinského\",\n  \"Ľubietovská\",\n  \"Ľubinská\",\n  \"Ľubľanská\",\n  \"Ľubochnianska\",\n  \"Ľubovnianska\",\n  \"Lúčna\",\n  \"Ľudové námestie\",\n  \"Ľudovíta Fullu\",\n  \"Luhačovická\",\n  \"Lužická\",\n  \"Lužná\",\n  \"Lýcejná\",\n  \"Lykovcová\",\n  \"M. Hella\",\n  \"Magnetová\",\n  \"Macharova\",\n  \"Majakovského\",\n  \"Majerníkova\",\n  \"Májkova\",\n  \"Májová\",\n  \"Makovického\",\n  \"Malá\",\n  \"Malé pálenisko\",\n  \"Malinová\",\n  \"Malý Draždiak\",\n  \"Malý trh\",\n  \"Mamateyova\",\n  \"Mamateyova\",\n  \"Mánesovo námestie\",\n  \"Mariánska\",\n  \"Marie Curie-Sklodows\",\n  \"Márie Medveďovej\",\n  \"Markova\",\n  \"Marótyho\",\n  \"Martákovej\",\n  \"Martinčekova\",\n  \"Martinčekova\",\n  \"Martinengova\",\n  \"Martinská\",\n  \"Mateja Bela\",\n  \"Matejkova\",\n  \"Matičná\",\n  \"Matúšova\",\n  \"Medená\",\n  \"Medzierka\",\n  \"Medzilaborecká\",\n  \"Merlotová\",\n  \"Mesačná\",\n  \"Mestská\",\n  \"Meteorová\",\n  \"Metodova\",\n  \"Mickiewiczova\",\n  \"Mierová\",\n  \"Michalská\",\n  \"Mikovíniho\",\n  \"Mikulášska\",\n  \"Miletičova\",\n  \"Miletičova\",\n  \"Mišíkova\",\n  \"Mišíkova\",\n  \"Mišíkova\",\n  \"Mliekárenská\",\n  \"Mlynarovičova\",\n  \"Mlynská dolina\",\n  \"Mlynská dolina\",\n  \"Mlynská dolina\",\n  \"Mlynské luhy\",\n  \"Mlynské nivy\",\n  \"Mlynské nivy\",\n  \"Mlynské nivy\",\n  \"Mlynské nivy\",\n  \"Mlynské nivy\",\n  \"Mlyny\",\n  \"Modranská\",\n  \"Mojmírova\",\n  \"Mokráň záhon\",\n  \"Mokrohájska cesta\",\n  \"Moldavská\",\n  \"Molecova\",\n  \"Moravská\",\n  \"Moskovská\",\n  \"Most SNP\",\n  \"Mostová\",\n  \"Mošovského\",\n  \"Motýlia\",\n  \"Moyzesova\",\n  \"Mozartova\",\n  \"Mraziarenská\",\n  \"Mudroňova\",\n  \"Mudroňova\",\n  \"Mudroňova\",\n  \"Muchovo námestie\",\n  \"Murgašova\",\n  \"Muškátová\",\n  \"Muštová\",\n  \"Múzejná\",\n  \"Myjavská\",\n  \"Mýtna\",\n  \"Mýtna\",\n  \"Na Baránku\",\n  \"Na Brezinách\",\n  \"Na Hrebienku\",\n  \"Na Kalvárii\",\n  \"Na Kampárke\",\n  \"Na kopci\",\n  \"Na križovatkách\",\n  \"Na lánoch\",\n  \"Na paši\",\n  \"Na piesku\",\n  \"Na Riviére\",\n  \"Na Sitine\",\n  \"Na Slavíne\",\n  \"Na stráni\",\n  \"Na Štyridsiatku\",\n  \"Na úvrati\",\n  \"Na vŕšku\",\n  \"Na výslní\",\n  \"Nábělkova\",\n  \"Nábrežie arm. gen. L\",\n  \"Nábrežná\",\n  \"Nad Dunajom\",\n  \"Nad lomom\",\n  \"Nad lúčkami\",\n  \"Nad lúčkami\",\n  \"Nad ostrovom\",\n  \"Nad Sihoťou\",\n  \"Námestie 1. mája\",\n  \"Námestie Alexandra D\",\n  \"Námestie Biely kríž\",\n  \"Námestie Hraničiarov\",\n  \"Námestie Jána Pavla\",\n  \"Námestie Ľudovíta Št\",\n  \"Námestie Martina Ben\",\n  \"Nám. M.R.Štefánika\",\n  \"Námestie slobody\",\n  \"Námestie slobody\",\n  \"Námestie SNP\",\n  \"Námestie SNP\",\n  \"Námestie sv. Františ\",\n  \"Narcisová\",\n  \"Nedbalova\",\n  \"Nekrasovova\",\n  \"Neronetová\",\n  \"Nerudova\",\n  \"Nevädzová\",\n  \"Nezábudková\",\n  \"Niťová\",\n  \"Nitrianska\",\n  \"Nížinná\",\n  \"Nobelova\",\n  \"Nobelovo námestie\",\n  \"Nová\",\n  \"Nová Rožňavská\",\n  \"Novackého\",\n  \"Nové pálenisko\",\n  \"Nové záhrady I\",\n  \"Nové záhrady II\",\n  \"Nové záhrady III\",\n  \"Nové záhrady IV\",\n  \"Nové záhrady V\",\n  \"Nové záhrady VI\",\n  \"Nové záhrady VII\",\n  \"Novinárska\",\n  \"Novobanská\",\n  \"Novohradská\",\n  \"Novosvetská\",\n  \"Novosvetská\",\n  \"Novosvetská\",\n  \"Obežná\",\n  \"Obchodná\",\n  \"Očovská\",\n  \"Odbojárov\",\n  \"Odborárska\",\n  \"Odborárske námestie\",\n  \"Odborárske námestie\",\n  \"Ohnicová\",\n  \"Okánikova\",\n  \"Okružná\",\n  \"Olbrachtova\",\n  \"Olejkárska\",\n  \"Ondavská\",\n  \"Ondrejovova\",\n  \"Oravská\",\n  \"Orechová cesta\",\n  \"Orechový rad\",\n  \"Oriešková\",\n  \"Ormisova\",\n  \"Osadná\",\n  \"Ostravská\",\n  \"Ostredková\",\n  \"Osuského\",\n  \"Osvetová\",\n  \"Otonelská\",\n  \"Ovručská\",\n  \"Ovsištské námestie\",\n  \"Pajštúnska\",\n  \"Palackého\",\n  \"Palárikova\",\n  \"Palárikova\",\n  \"Pálavská\",\n  \"Palisády\",\n  \"Palisády\",\n  \"Palisády\",\n  \"Palkovičova\",\n  \"Panenská\",\n  \"Pankúchova\",\n  \"Panónska cesta\",\n  \"Panská\",\n  \"Papánkovo námestie\",\n  \"Papraďová\",\n  \"Páričkova\",\n  \"Parková\",\n  \"Partizánska\",\n  \"Pasienky\",\n  \"Paulínyho\",\n  \"Pavlovičova\",\n  \"Pavlovova\",\n  \"Pavlovská\",\n  \"Pažického\",\n  \"Pažítková\",\n  \"Pečnianska\",\n  \"Pernecká\",\n  \"Pestovateľská\",\n  \"Peterská\",\n  \"Petzvalova\",\n  \"Pezinská\",\n  \"Piesočná\",\n  \"Piešťanská\",\n  \"Pifflova\",\n  \"Pilárikova\",\n  \"Pionierska\",\n  \"Pivoňková\",\n  \"Planckova\",\n  \"Planét\",\n  \"Plátenícka\",\n  \"Pluhová\",\n  \"Plynárenská\",\n  \"Plzenská\",\n  \"Pobrežná\",\n  \"Pod Bôrikom\",\n  \"Pod Kalváriou\",\n  \"Pod lesom\",\n  \"Pod Rovnicami\",\n  \"Pod vinicami\",\n  \"Podhorského\",\n  \"Podjavorinskej\",\n  \"Podlučinského\",\n  \"Podniková\",\n  \"Podtatranského\",\n  \"Pohronská\",\n  \"Polárna\",\n  \"Poloreckého\",\n  \"Poľná\",\n  \"Poľská\",\n  \"Poludníková\",\n  \"Porubského\",\n  \"Poštová\",\n  \"Považská\",\n  \"Povraznícka\",\n  \"Povraznícka\",\n  \"Pražská\",\n  \"Predstaničné námesti\",\n  \"Prepoštská\",\n  \"Prešernova\",\n  \"Prešovská\",\n  \"Prešovská\",\n  \"Prešovská\",\n  \"Pri Bielom kríži\",\n  \"Pri dvore\",\n  \"Pri Dynamitke\",\n  \"Pri Habánskom mlyne\",\n  \"Pri hradnej studni\",\n  \"Pri seči\",\n  \"Pri Starej Prachárni\",\n  \"Pri Starom háji\",\n  \"Pri Starom Mýte\",\n  \"Pri strelnici\",\n  \"Pri Suchom mlyne\",\n  \"Pri zvonici\",\n  \"Pribinova\",\n  \"Pribinova\",\n  \"Pribinova\",\n  \"Pribišova\",\n  \"Pribylinská\",\n  \"Priečna\",\n  \"Priekopy\",\n  \"Priemyselná\",\n  \"Priemyselná\",\n  \"Prievozská\",\n  \"Prievozská\",\n  \"Prievozská\",\n  \"Príkopova\",\n  \"Primaciálne námestie\",\n  \"Prístav\",\n  \"Prístavná\",\n  \"Prokofievova\",\n  \"Prokopa Veľkého\",\n  \"Prokopova\",\n  \"Prúdová\",\n  \"Prvosienková\",\n  \"Púpavová\",\n  \"Pustá\",\n  \"Puškinova\",\n  \"Račianska\",\n  \"Račianska\",\n  \"Račianske mýto\",\n  \"Radarová\",\n  \"Rádiová\",\n  \"Radlinského\",\n  \"Radničná\",\n  \"Radničné námestie\",\n  \"Radvanská\",\n  \"Rajská\",\n  \"Raketová\",\n  \"Rákosová\",\n  \"Rastislavova\",\n  \"Rázusovo nábrežie\",\n  \"Repná\",\n  \"Rešetkova\",\n  \"Revolučná\",\n  \"Révová\",\n  \"Revúcka\",\n  \"Rezedová\",\n  \"Riazanská\",\n  \"Riazanská\",\n  \"Ribayová\",\n  \"Riečna\",\n  \"Rigeleho\",\n  \"Rízlingová\",\n  \"Riznerova\",\n  \"Robotnícka\",\n  \"Romanova\",\n  \"Röntgenova\",\n  \"Rosná\",\n  \"Rovná\",\n  \"Rovniankova\",\n  \"Rovníková\",\n  \"Rozmarínová\",\n  \"Rožňavská\",\n  \"Rožňavská\",\n  \"Rožňavská\",\n  \"Rubinsteinova\",\n  \"Rudnayovo námestie\",\n  \"Rumančeková\",\n  \"Rusovská cesta\",\n  \"Ružičková\",\n  \"Ružinovská\",\n  \"Ružinovská\",\n  \"Ružinovská\",\n  \"Ružomberská\",\n  \"Ružová dolina\",\n  \"Ružová dolina\",\n  \"Rybárska brána\",\n  \"Rybné námestie\",\n  \"Rýdziková\",\n  \"Sabinovská\",\n  \"Sabinovská\",\n  \"Sad Janka Kráľa\",\n  \"Sadová\",\n  \"Sartorisova\",\n  \"Sasinkova\",\n  \"Seberíniho\",\n  \"Sečovská\",\n  \"Sedlárska\",\n  \"Sedmokrásková\",\n  \"Segnerova\",\n  \"Sekulská\",\n  \"Semianova\",\n  \"Senická\",\n  \"Senná\",\n  \"Schillerova\",\n  \"Schody pri starej vo\",\n  \"Sibírska\",\n  \"Sienkiewiczova\",\n  \"Silvánska\",\n  \"Sinokvetná\",\n  \"Skalická cesta\",\n  \"Skalná\",\n  \"Sklenárova\",\n  \"Sklenárska\",\n  \"Sládkovičova\",\n  \"Sladová\",\n  \"Slávičie údolie\",\n  \"Slavín\",\n  \"Slepá\",\n  \"Sliačska\",\n  \"Sliezska\",\n  \"Slivková\",\n  \"Slnečná\",\n  \"Slovanská\",\n  \"Slovinská\",\n  \"Slovnaftská\",\n  \"Slowackého\",\n  \"Smetanova\",\n  \"Smikova\",\n  \"Smolenická\",\n  \"Smolnícka\",\n  \"Smrečianska\",\n  \"Soferove schody\",\n  \"Socháňova\",\n  \"Sokolská\",\n  \"Solivarská\",\n  \"Sološnická\",\n  \"Somolického\",\n  \"Somolického\",\n  \"Sosnová\",\n  \"Spišská\",\n  \"Spojná\",\n  \"Spoločenská\",\n  \"Sputniková\",\n  \"Sreznevského\",\n  \"Srnčia\",\n  \"Stachanovská\",\n  \"Stálicová\",\n  \"Staničná\",\n  \"Stará Černicová\",\n  \"Stará Ivánska cesta\",\n  \"Stará Prievozská\",\n  \"Stará Vajnorská\",\n  \"Stará vinárska\",\n  \"Staré Grunty\",\n  \"Staré ihrisko\",\n  \"Staré záhrady\",\n  \"Starhradská\",\n  \"Starohájska\",\n  \"Staromestská\",\n  \"Staroturský chodník\",\n  \"Staviteľská\",\n  \"Stodolova\",\n  \"Stoklasová\",\n  \"Strakova\",\n  \"Strážnická\",\n  \"Strážny dom\",\n  \"Strečnianska\",\n  \"Stredná\",\n  \"Strelecká\",\n  \"Strmá cesta\",\n  \"Strojnícka\",\n  \"Stropkovská\",\n  \"Struková\",\n  \"Studená\",\n  \"Stuhová\",\n  \"Súbežná\",\n  \"Súhvezdná\",\n  \"Suché mýto\",\n  \"Suchohradská\",\n  \"Súkennícka\",\n  \"Súľovská\",\n  \"Sumbalova\",\n  \"Súmračná\",\n  \"Súťažná\",\n  \"Svätého Vincenta\",\n  \"Svätoplukova\",\n  \"Svätoplukova\",\n  \"Svätovojtešská\",\n  \"Svetlá\",\n  \"Svíbová\",\n  \"Svidnícka\",\n  \"Svoradova\",\n  \"Svrčia\",\n  \"Syslia\",\n  \"Šafárikovo námestie\",\n  \"Šafárikovo námestie\",\n  \"Šafránová\",\n  \"Šagátova\",\n  \"Šalviová\",\n  \"Šancová\",\n  \"Šancová\",\n  \"Šancová\",\n  \"Šancová\",\n  \"Šándorova\",\n  \"Šarišská\",\n  \"Šášovská\",\n  \"Šaštínska\",\n  \"Ševčenkova\",\n  \"Šintavská\",\n  \"Šípková\",\n  \"Škarniclova\",\n  \"Školská\",\n  \"Škovránčia\",\n  \"Škultétyho\",\n  \"Šoltésovej\",\n  \"Špieszova\",\n  \"Špitálska\",\n  \"Športová\",\n  \"Šrobárovo námestie\",\n  \"Šťastná\",\n  \"Štedrá\",\n  \"Štefánikova\",\n  \"Štefánikova\",\n  \"Štefánikova\",\n  \"Štefanovičova\",\n  \"Štefunkova\",\n  \"Štetinova\",\n  \"Štiavnická\",\n  \"Štúrova\",\n  \"Štyndlova\",\n  \"Šulekova\",\n  \"Šulekova\",\n  \"Šulekova\",\n  \"Šumavská\",\n  \"Šuňavcova\",\n  \"Šustekova\",\n  \"Švabinského\",\n  \"Tabaková\",\n  \"Tablicova\",\n  \"Táborská\",\n  \"Tajovského\",\n  \"Tallerova\",\n  \"Tehelná\",\n  \"Technická\",\n  \"Tekovská\",\n  \"Telocvičná\",\n  \"Tematínska\",\n  \"Teplická\",\n  \"Terchovská\",\n  \"Teslova\",\n  \"Tetmayerova\",\n  \"Thurzova\",\n  \"Tichá\",\n  \"Tilgnerova\",\n  \"Timravina\",\n  \"Tobrucká\",\n  \"Tokajícka\",\n  \"Tolstého\",\n  \"Tománkova\",\n  \"Tomášikova\",\n  \"Tomášikova\",\n  \"Tomášikova\",\n  \"Tomášikova\",\n  \"Tomášikova\",\n  \"Topoľčianska\",\n  \"Topoľová\",\n  \"Továrenská\",\n  \"Trebišovská\",\n  \"Trebišovská\",\n  \"Trebišovská\",\n  \"Trenčianska\",\n  \"Treskoňova\",\n  \"Trnavská cesta\",\n  \"Trnavská cesta\",\n  \"Trnavská cesta\",\n  \"Trnavská cesta\",\n  \"Trnavská cesta\",\n  \"Trnavské mýto\",\n  \"Tŕňová\",\n  \"Trojdomy\",\n  \"Tučkova\",\n  \"Tupolevova\",\n  \"Turbínova\",\n  \"Turčianska\",\n  \"Turnianska\",\n  \"Tvarožkova\",\n  \"Tylova\",\n  \"Tyršovo nábrežie\",\n  \"Údernícka\",\n  \"Údolná\",\n  \"Uhorková\",\n  \"Ukrajinská\",\n  \"Ulica 29. augusta\",\n  \"Ulica 29. augusta\",\n  \"Ulica 29. augusta\",\n  \"Ulica 29. augusta\",\n  \"Ulica Imricha Karvaš\",\n  \"Ulica Jozefa Krónera\",\n  \"Ulica Viktora Tegelh\",\n  \"Úprkova\",\n  \"Úradnícka\",\n  \"Uránová\",\n  \"Urbánkova\",\n  \"Ursínyho\",\n  \"Uršulínska\",\n  \"Úzka\",\n  \"V záhradách\",\n  \"Vajanského nábrežie\",\n  \"Vajnorská\",\n  \"Vajnorská\",\n  \"Vajnorská\",\n  \"Vajnorská\",\n  \"Vajnorská\",\n  \"Vajnorská\",\n  \"Vajnorská\",\n  \"Vajnorská\",\n  \"Vajnorská\",\n  \"Valašská\",\n  \"Valchárska\",\n  \"Vansovej\",\n  \"Vápenná\",\n  \"Varínska\",\n  \"Varšavská\",\n  \"Varšavská\",\n  \"Vavilovova\",\n  \"Vavrínova\",\n  \"Vazovova\",\n  \"Včelárska\",\n  \"Velehradská\",\n  \"Veltlínska\",\n  \"Ventúrska\",\n  \"Veterná\",\n  \"Veternicová\",\n  \"Vetvová\",\n  \"Viedenská cesta\",\n  \"Viedenská cesta\",\n  \"Vietnamská\",\n  \"Vígľašská\",\n  \"Vihorlatská\",\n  \"Viktorínova\",\n  \"Vilová\",\n  \"Vincenta Hložníka\",\n  \"Vínna\",\n  \"Vlastenecké námestie\",\n  \"Vlčkova\",\n  \"Vlčkova\",\n  \"Vlčkova\",\n  \"Vodný vrch\",\n  \"Votrubova\",\n  \"Vrábeľská\",\n  \"Vrakunská cesta\",\n  \"Vranovská\",\n  \"Vretenová\",\n  \"Vrchná\",\n  \"Vrútocká\",\n  \"Vyhliadka\",\n  \"Vyhnianska cesta\",\n  \"Vysoká\",\n  \"Vyšehradská\",\n  \"Vyšná\",\n  \"Wattova\",\n  \"Wilsonova\",\n  \"Wolkrova\",\n  \"Za Kasárňou\",\n  \"Za sokolovňou\",\n  \"Za Stanicou\",\n  \"Za tehelňou\",\n  \"Záborského\",\n  \"Zadunajská cesta\",\n  \"Záhorácka\",\n  \"Záhradnícka\",\n  \"Záhradnícka\",\n  \"Záhradnícka\",\n  \"Záhradnícka\",\n  \"Záhrebská\",\n  \"Záhrebská\",\n  \"Zálužická\",\n  \"Zámocká\",\n  \"Zámocké schody\",\n  \"Zámočnícka\",\n  \"Západná\",\n  \"Západný rad\",\n  \"Záporožská\",\n  \"Zátišie\",\n  \"Závodníkova\",\n  \"Zelená\",\n  \"Zelinárska\",\n  \"Zimná\",\n  \"Zlaté piesky\",\n  \"Zlaté schody\",\n  \"Znievska\",\n  \"Zohorská\",\n  \"Zochova\",\n  \"Zrinského\",\n  \"Zvolenská\",\n  \"Žabí majer\",\n  \"Žabotova\",\n  \"Žehrianska\",\n  \"Železná\",\n  \"Železničiarska\",\n  \"Žellova\",\n  \"Žiarska\",\n  \"Židovská\",\n  \"Žilinská\",\n  \"Žilinská\",\n  \"Živnostenská\",\n  \"Žižkova\",\n  \"Župné námestie\"\n];\n\n},{}],849:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],850:[function(require,module,exports){\nmodule.exports=require(66)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_name.js\":66}],851:[function(require,module,exports){\nmodule.exports=require(67)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/time_zone.js\":67}],852:[function(require,module,exports){\nmodule.exports=require(68)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/adjective.js\":68}],853:[function(require,module,exports){\nmodule.exports=require(69)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/bs_noun.js\":69}],854:[function(require,module,exports){\nmodule.exports=require(70)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/bs_verb.js\":70}],855:[function(require,module,exports){\nmodule.exports=require(71)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/descriptor.js\":71}],856:[function(require,module,exports){\nmodule.exports=require(72)\n},{\"./adjective\":852,\"./bs_noun\":853,\"./bs_verb\":854,\"./descriptor\":855,\"./name\":857,\"./noun\":858,\"./suffix\":859,\"/Users/a/dev/faker.js/lib/locales/cz/company/index.js\":72}],857:[function(require,module,exports){\nmodule.exports=require(73)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/name.js\":73}],858:[function(require,module,exports){\nmodule.exports=require(74)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/noun.js\":74}],859:[function(require,module,exports){\nmodule.exports=require(75)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/company/suffix.js\":75}],860:[function(require,module,exports){\nvar sk = {};\nmodule['exports'] = sk;\nsk.title = \"Slovakian\";\nsk.address = require(\"./address\");\nsk.company = require(\"./company\");\nsk.internet = require(\"./internet\");\nsk.lorem = require(\"./lorem\");\nsk.name = require(\"./name\");\nsk.phone_number = require(\"./phone_number\");\n\n},{\"./address\":843,\"./company\":856,\"./internet\":863,\"./lorem\":864,\"./name\":869,\"./phone_number\":877}],861:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"sk\",\n  \"com\",\n  \"net\",\n  \"eu\",\n  \"org\"\n];\n\n},{}],862:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"gmail.com\",\n  \"zoznam.sk\",\n  \"azet.sk\"\n];\n\n},{}],863:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":861,\"./free_email\":862,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],864:[function(require,module,exports){\nmodule.exports=require(83)\n},{\"./supplemental\":865,\"./words\":866,\"/Users/a/dev/faker.js/lib/locales/cz/lorem/index.js\":83}],865:[function(require,module,exports){\nmodule.exports=require(84)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/supplemental.js\":84}],866:[function(require,module,exports){\nmodule.exports=require(85)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/words.js\":85}],867:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Alexandra\",\n  \"Karina\",\n  \"Daniela\",\n  \"Andrea\",\n  \"Antónia\",\n  \"Bohuslava\",\n  \"Dáša\",\n  \"Malvína\",\n  \"Kristína\",\n  \"Nataša\",\n  \"Bohdana\",\n  \"Drahomíra\",\n  \"Sára\",\n  \"Zora\",\n  \"Tamara\",\n  \"Ema\",\n  \"Tatiana\",\n  \"Erika\",\n  \"Veronika\",\n  \"Agáta\",\n  \"Dorota\",\n  \"Vanda\",\n  \"Zoja\",\n  \"Gabriela\",\n  \"Perla\",\n  \"Ida\",\n  \"Liana\",\n  \"Miloslava\",\n  \"Vlasta\",\n  \"Lívia\",\n  \"Eleonóra\",\n  \"Etela\",\n  \"Romana\",\n  \"Zlatica\",\n  \"Anežka\",\n  \"Bohumila\",\n  \"Františka\",\n  \"Angela\",\n  \"Matilda\",\n  \"Svetlana\",\n  \"Ľubica\",\n  \"Alena\",\n  \"Soňa\",\n  \"Vieroslava\",\n  \"Zita\",\n  \"Miroslava\",\n  \"Irena\",\n  \"Milena\",\n  \"Estera\",\n  \"Justína\",\n  \"Dana\",\n  \"Danica\",\n  \"Jela\",\n  \"Jaroslava\",\n  \"Jarmila\",\n  \"Lea\",\n  \"Anastázia\",\n  \"Galina\",\n  \"Lesana\",\n  \"Hermína\",\n  \"Monika\",\n  \"Ingrida\",\n  \"Viktória\",\n  \"Blažena\",\n  \"Žofia\",\n  \"Sofia\",\n  \"Gizela\",\n  \"Viola\",\n  \"Gertrúda\",\n  \"Zina\",\n  \"Júlia\",\n  \"Juliana\",\n  \"Želmíra\",\n  \"Ela\",\n  \"Vanesa\",\n  \"Iveta\",\n  \"Vilma\",\n  \"Petronela\",\n  \"Žaneta\",\n  \"Xénia\",\n  \"Karolína\",\n  \"Lenka\",\n  \"Laura\",\n  \"Stanislava\",\n  \"Margaréta\",\n  \"Dobroslava\",\n  \"Blanka\",\n  \"Valéria\",\n  \"Paulína\",\n  \"Sidónia\",\n  \"Adriána\",\n  \"Beáta\",\n  \"Petra\",\n  \"Melánia\",\n  \"Diana\",\n  \"Berta\",\n  \"Patrícia\",\n  \"Lujza\",\n  \"Amália\",\n  \"Milota\",\n  \"Nina\",\n  \"Margita\",\n  \"Kamila\",\n  \"Dušana\",\n  \"Magdaléna\",\n  \"Oľga\",\n  \"Anna\",\n  \"Hana\",\n  \"Božena\",\n  \"Marta\",\n  \"Libuša\",\n  \"Božidara\",\n  \"Dominika\",\n  \"Hortenzia\",\n  \"Jozefína\",\n  \"Štefánia\",\n  \"Ľubomíra\",\n  \"Zuzana\",\n  \"Darina\",\n  \"Marcela\",\n  \"Milica\",\n  \"Elena\",\n  \"Helena\",\n  \"Lýdia\",\n  \"Anabela\",\n  \"Jana\",\n  \"Silvia\",\n  \"Nikola\",\n  \"Ružena\",\n  \"Nora\",\n  \"Drahoslava\",\n  \"Linda\",\n  \"Melinda\",\n  \"Rebeka\",\n  \"Rozália\",\n  \"Regína\",\n  \"Alica\",\n  \"Marianna\",\n  \"Miriama\",\n  \"Martina\",\n  \"Mária\",\n  \"Jolana\",\n  \"Ľudomila\",\n  \"Ľudmila\",\n  \"Olympia\",\n  \"Eugénia\",\n  \"Ľuboslava\",\n  \"Zdenka\",\n  \"Edita\",\n  \"Michaela\",\n  \"Stela\",\n  \"Viera\",\n  \"Natália\",\n  \"Eliška\",\n  \"Brigita\",\n  \"Valentína\",\n  \"Terézia\",\n  \"Vladimíra\",\n  \"Hedviga\",\n  \"Uršuľa\",\n  \"Alojza\",\n  \"Kvetoslava\",\n  \"Sabína\",\n  \"Dobromila\",\n  \"Klára\",\n  \"Simona\",\n  \"Aurélia\",\n  \"Denisa\",\n  \"Renáta\",\n  \"Irma\",\n  \"Agnesa\",\n  \"Klaudia\",\n  \"Alžbeta\",\n  \"Elvíra\",\n  \"Cecília\",\n  \"Emília\",\n  \"Katarína\",\n  \"Henrieta\",\n  \"Bibiána\",\n  \"Barbora\",\n  \"Marína\",\n  \"Izabela\",\n  \"Hilda\",\n  \"Otília\",\n  \"Lucia\",\n  \"Branislava\",\n  \"Bronislava\",\n  \"Ivica\",\n  \"Albína\",\n  \"Kornélia\",\n  \"Sláva\",\n  \"Slávka\",\n  \"Judita\",\n  \"Dagmara\",\n  \"Adela\",\n  \"Nadežda\",\n  \"Eva\",\n  \"Filoména\",\n  \"Ivana\",\n  \"Milada\"\n];\n\n},{}],868:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Antalová\",\n  \"Babková\",\n  \"Bahnová\",\n  \"Balážová\",\n  \"Baranová\",\n  \"Baranková\",\n  \"Bartovičová\",\n  \"Bartošová\",\n  \"Bačová\",\n  \"Bernoláková\",\n  \"Beňová\",\n  \"Biceková\",\n  \"Bieliková\",\n  \"Blahová\",\n  \"Bondrová\",\n  \"Bosáková\",\n  \"Bošková\",\n  \"Brezinová\",\n  \"Bukovská\",\n  \"Chalupková\",\n  \"Chudíková\",\n  \"Cibulová\",\n  \"Cibulková\",\n  \"Cyprichová\",\n  \"Cígerová\",\n  \"Danková\",\n  \"Daňková\",\n  \"Daňová\",\n  \"Debnárová\",\n  \"Dejová\",\n  \"Dekýšová\",\n  \"Doležalová\",\n  \"Dočolomanská\",\n  \"Droppová\",\n  \"Dubovská\",\n  \"Dudeková\",\n  \"Dulová\",\n  \"Dullová\",\n  \"Dusíková\",\n  \"Dvončová\",\n  \"Dzurjaninová\",\n  \"Dávidová\",\n  \"Fabianová\",\n  \"Fabiánová\",\n  \"Fajnorová\",\n  \"Farkašovská\",\n  \"Ficová\",\n  \"Filcová\",\n  \"Filipová\",\n  \"Finková\",\n  \"Ftoreková\",\n  \"Gašparová\",\n  \"Gašparovičová\",\n  \"Gocníková\",\n  \"Gregorová\",\n  \"Gregušová\",\n  \"Grznárová\",\n  \"Habláková\",\n  \"Habšudová\",\n  \"Haldová\",\n  \"Halušková\",\n  \"Haláková\",\n  \"Hanková\",\n  \"Hanzalová\",\n  \"Haščáková\",\n  \"Heretiková\",\n  \"Hečková\",\n  \"Hlaváčeková\",\n  \"Hlinková\",\n  \"Holubová\",\n  \"Holubyová\",\n  \"Hossová\",\n  \"Hozová\",\n  \"Hrašková\",\n  \"Hricová\",\n  \"Hrmová\",\n  \"Hrušovská\",\n  \"Hubová\",\n  \"Ihnačáková\",\n  \"Janečeková\",\n  \"Janošková\",\n  \"Jantošovičová\",\n  \"Janíková\",\n  \"Jančeková\",\n  \"Jedľovská\",\n  \"Jendeková\",\n  \"Jonatová\",\n  \"Jurinová\",\n  \"Jurkovičová\",\n  \"Juríková\",\n  \"Jánošíková\",\n  \"Kafendová\",\n  \"Kaliská\",\n  \"Karulová\",\n  \"Kenížová\",\n  \"Klapková\",\n  \"Kmeťová\",\n  \"Kolesárová\",\n  \"Kollárová\",\n  \"Kolniková\",\n  \"Kolníková\",\n  \"Kolárová\",\n  \"Korecová\",\n  \"Kostkaová\",\n  \"Kostrecová\",\n  \"Kováčová\",\n  \"Kováčiková\",\n  \"Kozová\",\n  \"Kočišová\",\n  \"Krajíčeková\",\n  \"Krajčová\",\n  \"Krajčovičová\",\n  \"Krajčírová\",\n  \"Králiková\",\n  \"Krúpová\",\n  \"Kubíková\",\n  \"Kyseľová\",\n  \"Kállayová\",\n  \"Labudová\",\n  \"Lepšíková\",\n  \"Liptáková\",\n  \"Lisická\",\n  \"Lubinová\",\n  \"Lukáčová\",\n  \"Luptáková\",\n  \"Líšková\",\n  \"Madejová\",\n  \"Majeská\",\n  \"Malachovská\",\n  \"Malíšeková\",\n  \"Mamojková\",\n  \"Marcinková\",\n  \"Mariánová\",\n  \"Masaryková\",\n  \"Maslová\",\n  \"Matiašková\",\n  \"Medveďová\",\n  \"Melcerová\",\n  \"Mečiarová\",\n  \"Michalíková\",\n  \"Mihaliková\",\n  \"Mihálová\",\n  \"Miháliková\",\n  \"Miklošková\",\n  \"Mikulíková\",\n  \"Mikušová\",\n  \"Mikúšová\",\n  \"Milotová\",\n  \"Mináčová\",\n  \"Mišíková\",\n  \"Mojžišová\",\n  \"Mokrošová\",\n  \"Morová\",\n  \"Moravčíková\",\n  \"Mydlová\",\n  \"Nemcová\",\n  \"Nováková\",\n  \"Obšutová\",\n  \"Ondrušová\",\n  \"Otčenášová\",\n  \"Pauková\",\n  \"Pavlikovská\",\n  \"Pavúková\",\n  \"Pašeková\",\n  \"Pašková\",\n  \"Pelikánová\",\n  \"Petrovická\",\n  \"Petrušková\",\n  \"Pešková\",\n  \"Plchová\",\n  \"Plekanecová\",\n  \"Podhradská\",\n  \"Podkonická\",\n  \"Poliaková\",\n  \"Pupáková\",\n  \"Raková\",\n  \"Repiská\",\n  \"Romančíková\",\n  \"Rusová\",\n  \"Ružičková\",\n  \"Rybníčeková\",\n  \"Rybárová\",\n  \"Rybáriková\",\n  \"Samsonová\",\n  \"Sedliaková\",\n  \"Senková\",\n  \"Sklenková\",\n  \"Skokanová\",\n  \"Skutecká\",\n  \"Slašťanová\",\n  \"Slobodová\",\n  \"Slobodníková\",\n  \"Slotová\",\n  \"Slováková\",\n  \"Smreková\",\n  \"Stodolová\",\n  \"Straková\",\n  \"Strnisková\",\n  \"Svrbíková\",\n  \"Sámelová\",\n  \"Sýkorová\",\n  \"Tatarová\",\n  \"Tatarková\",\n  \"Tatárová\",\n  \"Tatárkaová\",\n  \"Thomková\",\n  \"Tomečeková\",\n  \"Tomková\",\n  \"Trubenová\",\n  \"Turčoková\",\n  \"Uramová\",\n  \"Urblíková\",\n  \"Vajcíková\",\n  \"Vajdová\",\n  \"Valachová\",\n  \"Valachovičová\",\n  \"Valentová\",\n  \"Valušková\",\n  \"Vaneková\",\n  \"Veselová\",\n  \"Vicenová\",\n  \"Višňovská\",\n  \"Vlachová\",\n  \"Vojteková\",\n  \"Vydarená\",\n  \"Zajacová\",\n  \"Zimová\",\n  \"Zimková\",\n  \"Záborská\",\n  \"Zúbriková\",\n  \"Čapkovičová\",\n  \"Čaplovičová\",\n  \"Čarnogurská\",\n  \"Čierná\",\n  \"Čobrdová\",\n  \"Ďaďová\",\n  \"Ďuricová\",\n  \"Ďurišová\",\n  \"Šidlová\",\n  \"Šimonovičová\",\n  \"Škriniarová\",\n  \"Škultétyová\",\n  \"Šmajdová\",\n  \"Šoltésová\",\n  \"Šoltýsová\",\n  \"Štefanová\",\n  \"Štefanková\",\n  \"Šulcová\",\n  \"Šurková\",\n  \"Švehlová\",\n  \"Šťastná\"\n];\n\n},{}],869:[function(require,module,exports){\narguments[4][88][0].apply(exports,arguments)\n},{\"./female_first_name\":867,\"./female_last_name\":868,\"./male_first_name\":870,\"./male_last_name\":871,\"./name\":872,\"./prefix\":873,\"./suffix\":874,\"./title\":875,\"/Users/a/dev/faker.js/lib/locales/cz/name/index.js\":88}],870:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Drahoslav\",\n  \"Severín\",\n  \"Alexej\",\n  \"Ernest\",\n  \"Rastislav\",\n  \"Radovan\",\n  \"Dobroslav\",\n  \"Dalibor\",\n  \"Vincent\",\n  \"Miloš\",\n  \"Timotej\",\n  \"Gejza\",\n  \"Bohuš\",\n  \"Alfonz\",\n  \"Gašpar\",\n  \"Emil\",\n  \"Erik\",\n  \"Blažej\",\n  \"Zdenko\",\n  \"Dezider\",\n  \"Arpád\",\n  \"Valentín\",\n  \"Pravoslav\",\n  \"Jaromír\",\n  \"Roman\",\n  \"Matej\",\n  \"Frederik\",\n  \"Viktor\",\n  \"Alexander\",\n  \"Radomír\",\n  \"Albín\",\n  \"Bohumil\",\n  \"Kazimír\",\n  \"Fridrich\",\n  \"Radoslav\",\n  \"Tomáš\",\n  \"Alan\",\n  \"Branislav\",\n  \"Bruno\",\n  \"Gregor\",\n  \"Vlastimil\",\n  \"Boleslav\",\n  \"Eduard\",\n  \"Jozef\",\n  \"Víťazoslav\",\n  \"Blahoslav\",\n  \"Beňadik\",\n  \"Adrián\",\n  \"Gabriel\",\n  \"Marián\",\n  \"Emanuel\",\n  \"Miroslav\",\n  \"Benjamín\",\n  \"Hugo\",\n  \"Richard\",\n  \"Izidor\",\n  \"Zoltán\",\n  \"Albert\",\n  \"Igor\",\n  \"Július\",\n  \"Aleš\",\n  \"Fedor\",\n  \"Rudolf\",\n  \"Valér\",\n  \"Marcel\",\n  \"Ervín\",\n  \"Slavomír\",\n  \"Vojtech\",\n  \"Juraj\",\n  \"Marek\",\n  \"Jaroslav\",\n  \"Žigmund\",\n  \"Florián\",\n  \"Roland\",\n  \"Pankrác\",\n  \"Servác\",\n  \"Bonifác\",\n  \"Svetozár\",\n  \"Bernard\",\n  \"Júlia\",\n  \"Urban\",\n  \"Dušan\",\n  \"Viliam\",\n  \"Ferdinand\",\n  \"Norbert\",\n  \"Róbert\",\n  \"Medard\",\n  \"Zlatko\",\n  \"Anton\",\n  \"Vasil\",\n  \"Vít\",\n  \"Adolf\",\n  \"Vratislav\",\n  \"Alfréd\",\n  \"Alojz\",\n  \"Ján\",\n  \"Tadeáš\",\n  \"Ladislav\",\n  \"Peter\",\n  \"Pavol\",\n  \"Miloslav\",\n  \"Prokop\",\n  \"Cyril\",\n  \"Metod\",\n  \"Patrik\",\n  \"Oliver\",\n  \"Ivan\",\n  \"Kamil\",\n  \"Henrich\",\n  \"Drahomír\",\n  \"Bohuslav\",\n  \"Iľja\",\n  \"Daniel\",\n  \"Vladimír\",\n  \"Jakub\",\n  \"Krištof\",\n  \"Ignác\",\n  \"Gustáv\",\n  \"Jerguš\",\n  \"Dominik\",\n  \"Oskar\",\n  \"Vavrinec\",\n  \"Ľubomír\",\n  \"Mojmír\",\n  \"Leonard\",\n  \"Tichomír\",\n  \"Filip\",\n  \"Bartolomej\",\n  \"Ľudovít\",\n  \"Samuel\",\n  \"Augustín\",\n  \"Belo\",\n  \"Oleg\",\n  \"Bystrík\",\n  \"Ctibor\",\n  \"Ľudomil\",\n  \"Konštantín\",\n  \"Ľuboslav\",\n  \"Matúš\",\n  \"Móric\",\n  \"Ľuboš\",\n  \"Ľubor\",\n  \"Vladislav\",\n  \"Cyprián\",\n  \"Václav\",\n  \"Michal\",\n  \"Jarolím\",\n  \"Arnold\",\n  \"Levoslav\",\n  \"František\",\n  \"Dionýz\",\n  \"Maximilián\",\n  \"Koloman\",\n  \"Boris\",\n  \"Lukáš\",\n  \"Kristián\",\n  \"Vendelín\",\n  \"Sergej\",\n  \"Aurel\",\n  \"Demeter\",\n  \"Denis\",\n  \"Hubert\",\n  \"Karol\",\n  \"Imrich\",\n  \"René\",\n  \"Bohumír\",\n  \"Teodor\",\n  \"Tibor\",\n  \"Maroš\",\n  \"Martin\",\n  \"Svätopluk\",\n  \"Stanislav\",\n  \"Leopold\",\n  \"Eugen\",\n  \"Félix\",\n  \"Klement\",\n  \"Kornel\",\n  \"Milan\",\n  \"Vratko\",\n  \"Ondrej\",\n  \"Andrej\",\n  \"Edmund\",\n  \"Oldrich\",\n  \"Oto\",\n  \"Mikuláš\",\n  \"Ambróz\",\n  \"Radúz\",\n  \"Bohdan\",\n  \"Adam\",\n  \"Štefan\",\n  \"Dávid\",\n  \"Silvester\"\n];\n\n},{}],871:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Antal\",\n  \"Babka\",\n  \"Bahna\",\n  \"Bahno\",\n  \"Baláž\",\n  \"Baran\",\n  \"Baranka\",\n  \"Bartovič\",\n  \"Bartoš\",\n  \"Bača\",\n  \"Bernolák\",\n  \"Beňo\",\n  \"Bicek\",\n  \"Bielik\",\n  \"Blaho\",\n  \"Bondra\",\n  \"Bosák\",\n  \"Boška\",\n  \"Brezina\",\n  \"Bukovský\",\n  \"Chalupka\",\n  \"Chudík\",\n  \"Cibula\",\n  \"Cibulka\",\n  \"Cibuľa\",\n  \"Cyprich\",\n  \"Cíger\",\n  \"Danko\",\n  \"Daňko\",\n  \"Daňo\",\n  \"Debnár\",\n  \"Dej\",\n  \"Dekýš\",\n  \"Doležal\",\n  \"Dočolomanský\",\n  \"Droppa\",\n  \"Dubovský\",\n  \"Dudek\",\n  \"Dula\",\n  \"Dulla\",\n  \"Dusík\",\n  \"Dvonč\",\n  \"Dzurjanin\",\n  \"Dávid\",\n  \"Fabian\",\n  \"Fabián\",\n  \"Fajnor\",\n  \"Farkašovský\",\n  \"Fico\",\n  \"Filc\",\n  \"Filip\",\n  \"Finka\",\n  \"Ftorek\",\n  \"Gašpar\",\n  \"Gašparovič\",\n  \"Gocník\",\n  \"Gregor\",\n  \"Greguš\",\n  \"Grznár\",\n  \"Hablák\",\n  \"Habšuda\",\n  \"Halda\",\n  \"Haluška\",\n  \"Halák\",\n  \"Hanko\",\n  \"Hanzal\",\n  \"Haščák\",\n  \"Heretik\",\n  \"Hečko\",\n  \"Hlaváček\",\n  \"Hlinka\",\n  \"Holub\",\n  \"Holuby\",\n  \"Hossa\",\n  \"Hoza\",\n  \"Hraško\",\n  \"Hric\",\n  \"Hrmo\",\n  \"Hrušovský\",\n  \"Huba\",\n  \"Ihnačák\",\n  \"Janeček\",\n  \"Janoška\",\n  \"Jantošovič\",\n  \"Janík\",\n  \"Janček\",\n  \"Jedľovský\",\n  \"Jendek\",\n  \"Jonata\",\n  \"Jurina\",\n  \"Jurkovič\",\n  \"Jurík\",\n  \"Jánošík\",\n  \"Kafenda\",\n  \"Kaliský\",\n  \"Karul\",\n  \"Keníž\",\n  \"Klapka\",\n  \"Kmeť\",\n  \"Kolesár\",\n  \"Kollár\",\n  \"Kolnik\",\n  \"Kolník\",\n  \"Kolár\",\n  \"Korec\",\n  \"Kostka\",\n  \"Kostrec\",\n  \"Kováč\",\n  \"Kováčik\",\n  \"Koza\",\n  \"Kočiš\",\n  \"Krajíček\",\n  \"Krajči\",\n  \"Krajčo\",\n  \"Krajčovič\",\n  \"Krajčír\",\n  \"Králik\",\n  \"Krúpa\",\n  \"Kubík\",\n  \"Kyseľ\",\n  \"Kállay\",\n  \"Labuda\",\n  \"Lepšík\",\n  \"Lipták\",\n  \"Lisický\",\n  \"Lubina\",\n  \"Lukáč\",\n  \"Lupták\",\n  \"Líška\",\n  \"Madej\",\n  \"Majeský\",\n  \"Malachovský\",\n  \"Malíšek\",\n  \"Mamojka\",\n  \"Marcinko\",\n  \"Marián\",\n  \"Masaryk\",\n  \"Maslo\",\n  \"Matiaško\",\n  \"Medveď\",\n  \"Melcer\",\n  \"Mečiar\",\n  \"Michalík\",\n  \"Mihalik\",\n  \"Mihál\",\n  \"Mihálik\",\n  \"Mikloško\",\n  \"Mikulík\",\n  \"Mikuš\",\n  \"Mikúš\",\n  \"Milota\",\n  \"Mináč\",\n  \"Mišík\",\n  \"Mojžiš\",\n  \"Mokroš\",\n  \"Mora\",\n  \"Moravčík\",\n  \"Mydlo\",\n  \"Nemec\",\n  \"Nitra\",\n  \"Novák\",\n  \"Obšut\",\n  \"Ondruš\",\n  \"Otčenáš\",\n  \"Pauko\",\n  \"Pavlikovský\",\n  \"Pavúk\",\n  \"Pašek\",\n  \"Paška\",\n  \"Paško\",\n  \"Pelikán\",\n  \"Petrovický\",\n  \"Petruška\",\n  \"Peško\",\n  \"Plch\",\n  \"Plekanec\",\n  \"Podhradský\",\n  \"Podkonický\",\n  \"Poliak\",\n  \"Pupák\",\n  \"Rak\",\n  \"Repiský\",\n  \"Romančík\",\n  \"Rus\",\n  \"Ružička\",\n  \"Rybníček\",\n  \"Rybár\",\n  \"Rybárik\",\n  \"Samson\",\n  \"Sedliak\",\n  \"Senko\",\n  \"Sklenka\",\n  \"Skokan\",\n  \"Skutecký\",\n  \"Slašťan\",\n  \"Sloboda\",\n  \"Slobodník\",\n  \"Slota\",\n  \"Slovák\",\n  \"Smrek\",\n  \"Stodola\",\n  \"Straka\",\n  \"Strnisko\",\n  \"Svrbík\",\n  \"Sámel\",\n  \"Sýkora\",\n  \"Tatar\",\n  \"Tatarka\",\n  \"Tatár\",\n  \"Tatárka\",\n  \"Thomka\",\n  \"Tomeček\",\n  \"Tomka\",\n  \"Tomko\",\n  \"Truben\",\n  \"Turčok\",\n  \"Uram\",\n  \"Urblík\",\n  \"Vajcík\",\n  \"Vajda\",\n  \"Valach\",\n  \"Valachovič\",\n  \"Valent\",\n  \"Valuška\",\n  \"Vanek\",\n  \"Vesel\",\n  \"Vicen\",\n  \"Višňovský\",\n  \"Vlach\",\n  \"Vojtek\",\n  \"Vydarený\",\n  \"Zajac\",\n  \"Zima\",\n  \"Zimka\",\n  \"Záborský\",\n  \"Zúbrik\",\n  \"Čapkovič\",\n  \"Čaplovič\",\n  \"Čarnogurský\",\n  \"Čierny\",\n  \"Čobrda\",\n  \"Ďaďo\",\n  \"Ďurica\",\n  \"Ďuriš\",\n  \"Šidlo\",\n  \"Šimonovič\",\n  \"Škriniar\",\n  \"Škultéty\",\n  \"Šmajda\",\n  \"Šoltés\",\n  \"Šoltýs\",\n  \"Štefan\",\n  \"Štefanka\",\n  \"Šulc\",\n  \"Šurka\",\n  \"Švehla\",\n  \"Šťastný\"\n];\n\n},{}],872:[function(require,module,exports){\nmodule.exports=require(91)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/name/name.js\":91}],873:[function(require,module,exports){\nmodule.exports=require(92)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/name/prefix.js\":92}],874:[function(require,module,exports){\nmodule.exports=require(93)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/name/suffix.js\":93}],875:[function(require,module,exports){\nmodule.exports=require(264)\n},{\"/Users/a/dev/faker.js/lib/locales/en/name/title.js\":264}],876:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"09## ### ###\",\n  \"0## #### ####\",\n  \"0# #### ####\",\n  \"+421 ### ### ###\"\n];\n\n},{}],877:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":876,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],878:[function(require,module,exports){\nmodule.exports=require(511)\n},{\"/Users/a/dev/faker.js/lib/locales/ge/address/building_number.js\":511}],879:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_prefix}#{city_suffix}\"\n];\n\n},{}],880:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Söder\",\n  \"Norr\",\n  \"Väst\",\n  \"Öster\",\n  \"Aling\",\n  \"Ar\",\n  \"Av\",\n  \"Bo\",\n  \"Br\",\n  \"Bå\",\n  \"Ek\",\n  \"En\",\n  \"Esk\",\n  \"Fal\",\n  \"Gäv\",\n  \"Göte\",\n  \"Ha\",\n  \"Helsing\",\n  \"Karl\",\n  \"Krist\",\n  \"Kram\",\n  \"Kung\",\n  \"Kö\",\n  \"Lyck\",\n  \"Ny\"\n];\n\n},{}],881:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"stad\",\n  \"land\",\n  \"sås\",\n  \"ås\",\n  \"holm\",\n  \"tuna\",\n  \"sta\",\n  \"berg\",\n  \"löv\",\n  \"borg\",\n  \"mora\",\n  \"hamn\",\n  \"fors\",\n  \"köping\",\n  \"by\",\n  \"hult\",\n  \"torp\",\n  \"fred\",\n  \"vik\"\n];\n\n},{}],882:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"s Väg\",\n  \"s Gata\"\n];\n\n},{}],883:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Ryssland\",\n  \"Kanada\",\n  \"Kina\",\n  \"USA\",\n  \"Brasilien\",\n  \"Australien\",\n  \"Indien\",\n  \"Argentina\",\n  \"Kazakstan\",\n  \"Algeriet\",\n  \"DR Kongo\",\n  \"Danmark\",\n  \"Färöarna\",\n  \"Grönland\",\n  \"Saudiarabien\",\n  \"Mexiko\",\n  \"Indonesien\",\n  \"Sudan\",\n  \"Libyen\",\n  \"Iran\",\n  \"Mongoliet\",\n  \"Peru\",\n  \"Tchad\",\n  \"Niger\",\n  \"Angola\",\n  \"Mali\",\n  \"Sydafrika\",\n  \"Colombia\",\n  \"Etiopien\",\n  \"Bolivia\",\n  \"Mauretanien\",\n  \"Egypten\",\n  \"Tanzania\",\n  \"Nigeria\",\n  \"Venezuela\",\n  \"Namibia\",\n  \"Pakistan\",\n  \"Moçambique\",\n  \"Turkiet\",\n  \"Chile\",\n  \"Zambia\",\n  \"Marocko\",\n  \"Västsahara\",\n  \"Burma\",\n  \"Afghanistan\",\n  \"Somalia\",\n  \"Centralafrikanska republiken\",\n  \"Sydsudan\",\n  \"Ukraina\",\n  \"Botswana\",\n  \"Madagaskar\",\n  \"Kenya\",\n  \"Frankrike\",\n  \"Franska Guyana\",\n  \"Jemen\",\n  \"Thailand\",\n  \"Spanien\",\n  \"Turkmenistan\",\n  \"Kamerun\",\n  \"Papua Nya Guinea\",\n  \"Sverige\",\n  \"Uzbekistan\",\n  \"Irak\",\n  \"Paraguay\",\n  \"Zimbabwe\",\n  \"Japan\",\n  \"Tyskland\",\n  \"Kongo\",\n  \"Finland\",\n  \"Malaysia\",\n  \"Vietnam\",\n  \"Norge\",\n  \"Svalbard\",\n  \"Jan Mayen\",\n  \"Elfenbenskusten\",\n  \"Polen\",\n  \"Italien\",\n  \"Filippinerna\",\n  \"Ecuador\",\n  \"Burkina Faso\",\n  \"Nya Zeeland\",\n  \"Gabon\",\n  \"Guinea\",\n  \"Storbritannien\",\n  \"Ghana\",\n  \"Rumänien\",\n  \"Laos\",\n  \"Uganda\",\n  \"Guyana\",\n  \"Oman\",\n  \"Vitryssland\",\n  \"Kirgizistan\",\n  \"Senegal\",\n  \"Syrien\",\n  \"Kambodja\",\n  \"Uruguay\",\n  \"Tunisien\",\n  \"Surinam\",\n  \"Nepal\",\n  \"Bangladesh\",\n  \"Tadzjikistan\",\n  \"Grekland\",\n  \"Nicaragua\",\n  \"Eritrea\",\n  \"Nordkorea\",\n  \"Malawi\",\n  \"Benin\",\n  \"Honduras\",\n  \"Liberia\",\n  \"Bulgarien\",\n  \"Kuba\",\n  \"Guatemala\",\n  \"Island\",\n  \"Sydkorea\",\n  \"Ungern\",\n  \"Portugal\",\n  \"Jordanien\",\n  \"Serbien\",\n  \"Azerbajdzjan\",\n  \"Österrike\",\n  \"Förenade Arabemiraten\",\n  \"Tjeckien\",\n  \"Panama\",\n  \"Sierra Leone\",\n  \"Irland\",\n  \"Georgien\",\n  \"Sri Lanka\",\n  \"Litauen\",\n  \"Lettland\",\n  \"Togo\",\n  \"Kroatien\",\n  \"Bosnien och Hercegovina\",\n  \"Costa Rica\",\n  \"Slovakien\",\n  \"Dominikanska republiken\",\n  \"Bhutan\",\n  \"Estland\",\n  \"Danmark\",\n  \"Färöarna\",\n  \"Grönland\",\n  \"Nederländerna\",\n  \"Schweiz\",\n  \"Guinea-Bissau\",\n  \"Taiwan\",\n  \"Moldavien\",\n  \"Belgien\",\n  \"Lesotho\",\n  \"Armenien\",\n  \"Albanien\",\n  \"Salomonöarna\",\n  \"Ekvatorialguinea\",\n  \"Burundi\",\n  \"Haiti\",\n  \"Rwanda\",\n  \"Makedonien\",\n  \"Djibouti\",\n  \"Belize\",\n  \"Israel\",\n  \"El Salvador\",\n  \"Slovenien\",\n  \"Fiji\",\n  \"Kuwait\",\n  \"Swaziland\",\n  \"Timor-Leste\",\n  \"Montenegro\",\n  \"Bahamas\",\n  \"Vanuatu\",\n  \"Qatar\",\n  \"Gambia\",\n  \"Jamaica\",\n  \"Kosovo\",\n  \"Libanon\",\n  \"Cypern\",\n  \"Brunei\",\n  \"Trinidad och Tobago\",\n  \"Kap Verde\",\n  \"Samoa\",\n  \"Luxemburg\",\n  \"Komorerna\",\n  \"Mauritius\",\n  \"São Tomé och Príncipe\",\n  \"Kiribati\",\n  \"Dominica\",\n  \"Tonga\",\n  \"Mikronesiens federerade stater\",\n  \"Singapore\",\n  \"Bahrain\",\n  \"Saint Lucia\",\n  \"Andorra\",\n  \"Palau\",\n  \"Seychellerna\",\n  \"Antigua och Barbuda\",\n  \"Barbados\",\n  \"Saint Vincent och Grenadinerna\",\n  \"Grenada\",\n  \"Malta\",\n  \"Maldiverna\",\n  \"Saint Kitts och Nevis\",\n  \"Marshallöarna\",\n  \"Liechtenstein\",\n  \"San Marino\",\n  \"Tuvalu\",\n  \"Nauru\",\n  \"Monaco\",\n  \"Vatikanstaten\"\n];\n\n},{}],884:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Sverige\"\n];\n\n},{}],885:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.country = require(\"./country\");\naddress.common_street_suffix = require(\"./common_street_suffix\");\naddress.street_prefix = require(\"./street_prefix\");\naddress.street_root = require(\"./street_root\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.state = require(\"./state\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.postcode = require(\"./postcode\");\naddress.building_number = require(\"./building_number\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":878,\"./city\":879,\"./city_prefix\":880,\"./city_suffix\":881,\"./common_street_suffix\":882,\"./country\":883,\"./default_country\":884,\"./postcode\":886,\"./secondary_address\":887,\"./state\":888,\"./street_address\":889,\"./street_name\":890,\"./street_prefix\":891,\"./street_root\":892,\"./street_suffix\":893}],886:[function(require,module,exports){\nmodule.exports=require(379)\n},{\"/Users/a/dev/faker.js/lib/locales/es/address/postcode.js\":379}],887:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Lgh. ###\",\n  \"Hus ###\"\n];\n\n},{}],888:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Blekinge\",\n  \"Dalarna\",\n  \"Gotland\",\n  \"Gävleborg\",\n  \"Göteborg\",\n  \"Halland\",\n  \"Jämtland\",\n  \"Jönköping\",\n  \"Kalmar\",\n  \"Kronoberg\",\n  \"Norrbotten\",\n  \"Skaraborg\",\n  \"Skåne\",\n  \"Stockholm\",\n  \"Södermanland\",\n  \"Uppsala\",\n  \"Värmland\",\n  \"Västerbotten\",\n  \"Västernorrland\",\n  \"Västmanland\",\n  \"Älvsborg\",\n  \"Örebro\",\n  \"Östergötland\"\n];\n\n},{}],889:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],890:[function(require,module,exports){\nmodule.exports=require(663)\n},{\"/Users/a/dev/faker.js/lib/locales/nb_NO/address/street_name.js\":663}],891:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Västra\",\n  \"Östra\",\n  \"Norra\",\n  \"Södra\",\n  \"Övre\",\n  \"Undre\"\n];\n\n},{}],892:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Björk\",\n  \"Järnvägs\",\n  \"Ring\",\n  \"Skol\",\n  \"Skogs\",\n  \"Ny\",\n  \"Gran\",\n  \"Idrotts\",\n  \"Stor\",\n  \"Kyrk\",\n  \"Industri\",\n  \"Park\",\n  \"Strand\",\n  \"Skol\",\n  \"Trädgård\",\n  \"Ängs\",\n  \"Kyrko\",\n  \"Villa\",\n  \"Ek\",\n  \"Kvarn\",\n  \"Stations\",\n  \"Back\",\n  \"Furu\",\n  \"Gen\",\n  \"Fabriks\",\n  \"Åker\",\n  \"Bäck\",\n  \"Asp\"\n];\n\n},{}],893:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"vägen\",\n  \"gatan\",\n  \"gränden\",\n  \"gärdet\",\n  \"allén\"\n];\n\n},{}],894:[function(require,module,exports){\nmodule[\"exports\"] = [\n  56,\n  62,\n  59\n];\n\n},{}],895:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{common_cell_prefix}-###-####\"\n];\n\n},{}],896:[function(require,module,exports){\nvar cell_phone = {};\nmodule['exports'] = cell_phone;\ncell_phone.common_cell_prefix = require(\"./common_cell_prefix\");\ncell_phone.formats = require(\"./formats\");\n\n},{\"./common_cell_prefix\":894,\"./formats\":895}],897:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"vit\",\n  \"silver\",\n  \"grå\",\n  \"svart\",\n  \"röd\",\n  \"grön\",\n  \"blå\",\n  \"gul\",\n  \"lila\",\n  \"indigo\",\n  \"guld\",\n  \"brun\",\n  \"rosa\",\n  \"purpur\",\n  \"korall\"\n];\n\n},{}],898:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Böcker\",\n  \"Filmer\",\n  \"Musik\",\n  \"Spel\",\n  \"Elektronik\",\n  \"Datorer\",\n  \"Hem\",\n  \"Trädgård\",\n  \"Verktyg\",\n  \"Livsmedel\",\n  \"Hälsa\",\n  \"Skönhet\",\n  \"Leksaker\",\n  \"Klädsel\",\n  \"Skor\",\n  \"Smycken\",\n  \"Sport\"\n];\n\n},{}],899:[function(require,module,exports){\narguments[4][31][0].apply(exports,arguments)\n},{\"./color\":897,\"./department\":898,\"./product_name\":900,\"/Users/a/dev/faker.js/lib/locales/az/commerce/index.js\":31}],900:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"adjective\": [\n    \"Liten\",\n    \"Ergonomisk\",\n    \"Robust\",\n    \"Intelligent\",\n    \"Söt\",\n    \"Otrolig\",\n    \"Fatastisk\",\n    \"Praktisk\",\n    \"Slimmad\",\n    \"Grym\"\n  ],\n  \"material\": [\n    \"Stål\",\n    \"Metall\",\n    \"Trä\",\n    \"Betong\",\n    \"Plast\",\n    \"Bomul\",\n    \"Grnit\",\n    \"Gummi\",\n    \"Latex\"\n  ],\n  \"product\": [\n    \"Stol\",\n    \"Bil\",\n    \"Dator\",\n    \"Handskar\",\n    \"Pants\",\n    \"Shirt\",\n    \"Table\",\n    \"Shoes\",\n    \"Hat\"\n  ]\n};\n\n},{}],901:[function(require,module,exports){\narguments[4][166][0].apply(exports,arguments)\n},{\"./name\":902,\"./suffix\":903,\"/Users/a/dev/faker.js/lib/locales/de_CH/company/index.js\":166}],902:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name} #{suffix}\",\n  \"#{Name.last_name}-#{Name.last_name}\",\n  \"#{Name.last_name}, #{Name.last_name} #{suffix}\"\n];\n\n},{}],903:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Gruppen\",\n  \"AB\",\n  \"HB\",\n  \"Group\",\n  \"Investment\",\n  \"Kommanditbolag\",\n  \"Aktiebolag\"\n];\n\n},{}],904:[function(require,module,exports){\narguments[4][37][0].apply(exports,arguments)\n},{\"./month\":905,\"./weekday\":906,\"/Users/a/dev/faker.js/lib/locales/az/date/index.js\":37}],905:[function(require,module,exports){\n// Source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/en.xml#L1799\nmodule[\"exports\"] = {\n  wide: [\n    \"januari\",\n    \"februari\",\n    \"mars\",\n    \"april\",\n    \"maj\",\n    \"juni\",\n    \"juli\",\n    \"augusti\",\n    \"september\",\n    \"oktober\",\n    \"november\",\n    \"december\"\n  ],\n  abbr: [\n    \"jan\",\n    \"feb\",\n    \"mar\",\n    \"apr\",\n    \"maj\",\n    \"jun\",\n    \"jul\",\n    \"aug\",\n    \"sep\",\n    \"okt\",\n    \"nov\",\n    \"dec\"\n  ]\n};\n\n},{}],906:[function(require,module,exports){\n// Source: http://unicode.org/cldr/trac/browser/tags/release-27/common/main/en.xml#L1847\nmodule[\"exports\"] = {\n  wide: [\n    \"söndag\",\n    \"måndag\",\n    \"tisdag\",\n    \"onsdag\",\n    \"torsdag\",\n    \"fredag\",\n    \"lördag\"\n  ],\n  abbr: [\n    \"sön\",\n    \"mån\",\n    \"tis\",\n    \"ons\",\n    \"tor\",\n    \"fre\",\n    \"lör\"\n  ]\n};\n\n},{}],907:[function(require,module,exports){\nvar sv = {};\nmodule['exports'] = sv;\nsv.title = \"Swedish\";\nsv.address = require(\"./address\");\nsv.company = require(\"./company\");\nsv.internet = require(\"./internet\");\nsv.name = require(\"./name\");\nsv.phone_number = require(\"./phone_number\");\nsv.cell_phone = require(\"./cell_phone\");\nsv.commerce = require(\"./commerce\");\nsv.team = require(\"./team\");\nsv.date = require(\"./date\");\n\n},{\"./address\":885,\"./cell_phone\":896,\"./commerce\":899,\"./company\":901,\"./date\":904,\"./internet\":909,\"./name\":912,\"./phone_number\":918,\"./team\":919}],908:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"se\",\n  \"nu\",\n  \"info\",\n  \"com\",\n  \"org\"\n];\n\n},{}],909:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":908,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],910:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Erik\",\n  \"Lars\",\n  \"Karl\",\n  \"Anders\",\n  \"Per\",\n  \"Johan\",\n  \"Nils\",\n  \"Lennart\",\n  \"Emil\",\n  \"Hans\"\n];\n\n},{}],911:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Maria\",\n  \"Anna\",\n  \"Margareta\",\n  \"Elisabeth\",\n  \"Eva\",\n  \"Birgitta\",\n  \"Kristina\",\n  \"Karin\",\n  \"Elisabet\",\n  \"Marie\"\n];\n\n},{}],912:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name_women = require(\"./first_name_women\");\nname.first_name_men = require(\"./first_name_men\");\nname.last_name = require(\"./last_name\");\nname.prefix = require(\"./prefix\");\nname.title = require(\"./title\");\nname.name = require(\"./name\");\n\n},{\"./first_name_men\":910,\"./first_name_women\":911,\"./last_name\":913,\"./name\":914,\"./prefix\":915,\"./title\":916}],913:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Johansson\",\n  \"Andersson\",\n  \"Karlsson\",\n  \"Nilsson\",\n  \"Eriksson\",\n  \"Larsson\",\n  \"Olsson\",\n  \"Persson\",\n  \"Svensson\",\n  \"Gustafsson\"\n];\n\n},{}],914:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{first_name_women} #{last_name}\",\n  \"#{first_name_men} #{last_name}\",\n  \"#{first_name_women} #{last_name}\",\n  \"#{first_name_men} #{last_name}\",\n  \"#{first_name_women} #{last_name}\",\n  \"#{first_name_men} #{last_name}\",\n  \"#{prefix} #{first_name_men} #{last_name}\",\n  \"#{prefix} #{first_name_women} #{last_name}\"\n];\n\n},{}],915:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Dr.\",\n  \"Prof.\",\n  \"PhD.\"\n];\n\n},{}],916:[function(require,module,exports){\nmodule.exports=require(264)\n},{\"/Users/a/dev/faker.js/lib/locales/en/name/title.js\":264}],917:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"####-#####\",\n  \"####-######\"\n];\n\n},{}],918:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":917,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],919:[function(require,module,exports){\nvar team = {};\nmodule['exports'] = team;\nteam.suffix = require(\"./suffix\");\nteam.name = require(\"./name\");\n\n},{\"./name\":920,\"./suffix\":921}],920:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Address.city} #{suffix}\"\n];\n\n},{}],921:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"IF\",\n  \"FF\",\n  \"BK\",\n  \"HK\",\n  \"AIF\",\n  \"SK\",\n  \"FC\",\n  \"SK\",\n  \"BoIS\",\n  \"FK\",\n  \"BIS\",\n  \"FIF\",\n  \"IK\"\n];\n\n},{}],922:[function(require,module,exports){\nmodule.exports=require(97)\n},{\"/Users/a/dev/faker.js/lib/locales/de/address/building_number.js\":97}],923:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Adana\",\n  \"Adıyaman\",\n  \"Afyon\",\n  \"Ağrı\",\n  \"Amasya\",\n  \"Ankara\",\n  \"Antalya\",\n  \"Artvin\",\n  \"Aydın\",\n  \"Balıkesir\",\n  \"Bilecik\",\n  \"Bingöl\",\n  \"Bitlis\",\n  \"Bolu\",\n  \"Burdur\",\n  \"Bursa\",\n  \"Çanakkale\",\n  \"Çankırı\",\n  \"Çorum\",\n  \"Denizli\",\n  \"Diyarbakır\",\n  \"Edirne\",\n  \"Elazığ\",\n  \"Erzincan\",\n  \"Erzurum\",\n  \"Eskişehir\",\n  \"Gaziantep\",\n  \"Giresun\",\n  \"Gümüşhane\",\n  \"Hakkari\",\n  \"Hatay\",\n  \"Isparta\",\n  \"İçel (Mersin)\",\n  \"İstanbul\",\n  \"İzmir\",\n  \"Kars\",\n  \"Kastamonu\",\n  \"Kayseri\",\n  \"Kırklareli\",\n  \"Kırşehir\",\n  \"Kocaeli\",\n  \"Konya\",\n  \"Kütahya\",\n  \"Malatya\",\n  \"Manisa\",\n  \"K.maraş\",\n  \"Mardin\",\n  \"Muğla\",\n  \"Muş\",\n  \"Nevşehir\",\n  \"Niğde\",\n  \"Ordu\",\n  \"Rize\",\n  \"Sakarya\",\n  \"Samsun\",\n  \"Siirt\",\n  \"Sinop\",\n  \"Sivas\",\n  \"Tekirdağ\",\n  \"Tokat\",\n  \"Trabzon\",\n  \"Tunceli\",\n  \"Şanlıurfa\",\n  \"Uşak\",\n  \"Van\",\n  \"Yozgat\",\n  \"Zonguldak\",\n  \"Aksaray\",\n  \"Bayburt\",\n  \"Karaman\",\n  \"Kırıkkale\",\n  \"Batman\",\n  \"Şırnak\",\n  \"Bartın\",\n  \"Ardahan\",\n  \"Iğdır\",\n  \"Yalova\",\n  \"Karabük\",\n  \"Kilis\",\n  \"Osmaniye\",\n  \"Düzce\"\n];\n\n},{}],924:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Afganistan\",\n  \"Almanya\",\n  \"Amerika Birleşik Devletleri\",\n  \"Amerikan Samoa\",\n  \"Andorra\",\n  \"Angola\",\n  \"Anguilla, İngiltere\",\n  \"Antigua ve Barbuda\",\n  \"Arjantin\",\n  \"Arnavutluk\",\n  \"Aruba, Hollanda\",\n  \"Avustralya\",\n  \"Avusturya\",\n  \"Azerbaycan\",\n  \"Bahama Adaları\",\n  \"Bahreyn\",\n  \"Bangladeş\",\n  \"Barbados\",\n  \"Belçika\",\n  \"Belize\",\n  \"Benin\",\n  \"Bermuda, İngiltere\",\n  \"Beyaz Rusya\",\n  \"Bhutan\",\n  \"Birleşik Arap Emirlikleri\",\n  \"Birmanya (Myanmar)\",\n  \"Bolivya\",\n  \"Bosna Hersek\",\n  \"Botswana\",\n  \"Brezilya\",\n  \"Brunei\",\n  \"Bulgaristan\",\n  \"Burkina Faso\",\n  \"Burundi\",\n  \"Cape Verde\",\n  \"Cayman Adaları, İngiltere\",\n  \"Cebelitarık, İngiltere\",\n  \"Cezayir\",\n  \"Christmas Adası , Avusturalya\",\n  \"Cibuti\",\n  \"Çad\",\n  \"Çek Cumhuriyeti\",\n  \"Çin\",\n  \"Danimarka\",\n  \"Doğu Timor\",\n  \"Dominik Cumhuriyeti\",\n  \"Dominika\",\n  \"Ekvator\",\n  \"Ekvator Ginesi\",\n  \"El Salvador\",\n  \"Endonezya\",\n  \"Eritre\",\n  \"Ermenistan\",\n  \"Estonya\",\n  \"Etiyopya\",\n  \"Fas\",\n  \"Fiji\",\n  \"Fildişi Sahili\",\n  \"Filipinler\",\n  \"Filistin\",\n  \"Finlandiya\",\n  \"Folkland Adaları, İngiltere\",\n  \"Fransa\",\n  \"Fransız Guyanası\",\n  \"Fransız Güney Eyaletleri (Kerguelen Adaları)\",\n  \"Fransız Polinezyası\",\n  \"Gabon\",\n  \"Galler\",\n  \"Gambiya\",\n  \"Gana\",\n  \"Gine\",\n  \"Gine-Bissau\",\n  \"Grenada\",\n  \"Grönland\",\n  \"Guadalup, Fransa\",\n  \"Guam, Amerika\",\n  \"Guatemala\",\n  \"Guyana\",\n  \"Güney Afrika\",\n  \"Güney Georgia ve Güney Sandviç Adaları, İngiltere\",\n  \"Güney Kıbrıs Rum Yönetimi\",\n  \"Güney Kore\",\n  \"Gürcistan H\",\n  \"Haiti\",\n  \"Hırvatistan\",\n  \"Hindistan\",\n  \"Hollanda\",\n  \"Hollanda Antilleri\",\n  \"Honduras\",\n  \"Irak\",\n  \"İngiltere\",\n  \"İran\",\n  \"İrlanda\",\n  \"İspanya\",\n  \"İsrail\",\n  \"İsveç\",\n  \"İsviçre\",\n  \"İtalya\",\n  \"İzlanda\",\n  \"Jamaika\",\n  \"Japonya\",\n  \"Johnston Atoll, Amerika\",\n  \"K.K.T.C.\",\n  \"Kamboçya\",\n  \"Kamerun\",\n  \"Kanada\",\n  \"Kanarya Adaları\",\n  \"Karadağ\",\n  \"Katar\",\n  \"Kazakistan\",\n  \"Kenya\",\n  \"Kırgızistan\",\n  \"Kiribati\",\n  \"Kolombiya\",\n  \"Komorlar\",\n  \"Kongo\",\n  \"Kongo Demokratik Cumhuriyeti\",\n  \"Kosova\",\n  \"Kosta Rika\",\n  \"Kuveyt\",\n  \"Kuzey İrlanda\",\n  \"Kuzey Kore\",\n  \"Kuzey Maryana Adaları\",\n  \"Küba\",\n  \"Laos\",\n  \"Lesotho\",\n  \"Letonya\",\n  \"Liberya\",\n  \"Libya\",\n  \"Liechtenstein\",\n  \"Litvanya\",\n  \"Lübnan\",\n  \"Lüksemburg\",\n  \"Macaristan\",\n  \"Madagaskar\",\n  \"Makau (Makao)\",\n  \"Makedonya\",\n  \"Malavi\",\n  \"Maldiv Adaları\",\n  \"Malezya\",\n  \"Mali\",\n  \"Malta\",\n  \"Marşal Adaları\",\n  \"Martinik, Fransa\",\n  \"Mauritius\",\n  \"Mayotte, Fransa\",\n  \"Meksika\",\n  \"Mısır\",\n  \"Midway Adaları, Amerika\",\n  \"Mikronezya\",\n  \"Moğolistan\",\n  \"Moldavya\",\n  \"Monako\",\n  \"Montserrat\",\n  \"Moritanya\",\n  \"Mozambik\",\n  \"Namibia\",\n  \"Nauru\",\n  \"Nepal\",\n  \"Nijer\",\n  \"Nijerya\",\n  \"Nikaragua\",\n  \"Niue, Yeni Zelanda\",\n  \"Norveç\",\n  \"Orta Afrika Cumhuriyeti\",\n  \"Özbekistan\",\n  \"Pakistan\",\n  \"Palau Adaları\",\n  \"Palmyra Atoll, Amerika\",\n  \"Panama\",\n  \"Papua Yeni Gine\",\n  \"Paraguay\",\n  \"Peru\",\n  \"Polonya\",\n  \"Portekiz\",\n  \"Porto Riko, Amerika\",\n  \"Reunion, Fransa\",\n  \"Romanya\",\n  \"Ruanda\",\n  \"Rusya Federasyonu\",\n  \"Saint Helena, İngiltere\",\n  \"Saint Martin, Fransa\",\n  \"Saint Pierre ve Miquelon, Fransa\",\n  \"Samoa\",\n  \"San Marino\",\n  \"Santa Kitts ve Nevis\",\n  \"Santa Lucia\",\n  \"Santa Vincent ve Grenadinler\",\n  \"Sao Tome ve Principe\",\n  \"Senegal\",\n  \"Seyşeller\",\n  \"Sırbistan\",\n  \"Sierra Leone\",\n  \"Singapur\",\n  \"Slovakya\",\n  \"Slovenya\",\n  \"Solomon Adaları\",\n  \"Somali\",\n  \"Sri Lanka\",\n  \"Sudan\",\n  \"Surinam\",\n  \"Suriye\",\n  \"Suudi Arabistan\",\n  \"Svalbard, Norveç\",\n  \"Svaziland\",\n  \"Şili\",\n  \"Tacikistan\",\n  \"Tanzanya\",\n  \"Tayland\",\n  \"Tayvan\",\n  \"Togo\",\n  \"Tonga\",\n  \"Trinidad ve Tobago\",\n  \"Tunus\",\n  \"Turks ve Caicos Adaları, İngiltere\",\n  \"Tuvalu\",\n  \"Türkiye\",\n  \"Türkmenistan\",\n  \"Uganda\",\n  \"Ukrayna\",\n  \"Umman\",\n  \"Uruguay\",\n  \"Ürdün\",\n  \"Vallis ve Futuna, Fransa\",\n  \"Vanuatu\",\n  \"Venezuela\",\n  \"Vietnam\",\n  \"Virgin Adaları, Amerika\",\n  \"Virgin Adaları, İngiltere\",\n  \"Wake Adaları, Amerika\",\n  \"Yemen\",\n  \"Yeni Kaledonya, Fransa\",\n  \"Yeni Zelanda\",\n  \"Yunanistan\",\n  \"Zambiya\",\n  \"Zimbabve\"\n];\n\n},{}],925:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Türkiye\"\n];\n\n},{}],926:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city = require(\"./city\");\naddress.street_root = require(\"./street_root\");\naddress.country = require(\"./country\");\naddress.postcode = require(\"./postcode\");\naddress.default_country = require(\"./default_country\");\naddress.building_number = require(\"./building_number\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\n\n},{\"./building_number\":922,\"./city\":923,\"./country\":924,\"./default_country\":925,\"./postcode\":927,\"./street_address\":928,\"./street_name\":929,\"./street_root\":930}],927:[function(require,module,exports){\nmodule.exports=require(379)\n},{\"/Users/a/dev/faker.js/lib/locales/es/address/postcode.js\":379}],928:[function(require,module,exports){\nmodule.exports=require(65)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/street_address.js\":65}],929:[function(require,module,exports){\nmodule.exports=require(109)\n},{\"/Users/a/dev/faker.js/lib/locales/de/address/street_name.js\":109}],930:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Atatürk Bulvarı\",\n  \"Alparslan Türkeş Bulvarı\",\n  \"Ali Çetinkaya Caddesi\",\n  \"Tevfik Fikret Caddesi\",\n  \"Kocatepe Caddesi\",\n  \"İsmet Paşa Caddesi\",\n  \"30 Ağustos Caddesi\",\n  \"İsmet Attila Caddesi\",\n  \"Namık Kemal Caddesi\",\n  \"Lütfi Karadirek Caddesi\",\n  \"Sarıkaya Caddesi\",\n  \"Yunus Emre Sokak\",\n  \"Dar Sokak\",\n  \"Fatih Sokak \",\n  \"Harman Yolu Sokak \",\n  \"Ergenekon Sokak  \",\n  \"Ülkü Sokak\",\n  \"Sağlık Sokak\",\n  \"Okul Sokak\",\n  \"Harman Altı Sokak\",\n  \"Kaldırım Sokak\",\n  \"Mevlana Sokak\",\n  \"Gül Sokak\",\n  \"Sıran Söğüt Sokak\",\n  \"Güven Yaka Sokak\",\n  \"Saygılı Sokak\",\n  \"Menekşe Sokak\",\n  \"Dağınık Evler Sokak\",\n  \"Sevgi Sokak\",\n  \"Afyon Kaya Sokak\",\n  \"Oğuzhan Sokak\",\n  \"İbn-i Sina Sokak\",\n  \"Okul Sokak\",\n  \"Bahçe Sokak\",\n  \"Köypınar Sokak\",\n  \"Kekeçoğlu Sokak\",\n  \"Barış Sokak\",\n  \"Bayır Sokak\",\n  \"Kerimoğlu Sokak\",\n  \"Nalbant Sokak\",\n  \"Bandak Sokak\"\n];\n\n},{}],931:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"+90-53#-###-##-##\",\n  \"+90-54#-###-##-##\",\n  \"+90-55#-###-##-##\",\n  \"+90-50#-###-##-##\"\n];\n\n},{}],932:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":931,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],933:[function(require,module,exports){\nvar tr = {};\nmodule['exports'] = tr;\ntr.title = \"Turkish\";\ntr.address = require(\"./address\");\ntr.internet = require(\"./internet\");\ntr.lorem = require(\"./lorem\");\ntr.phone_number = require(\"./phone_number\");\ntr.cell_phone = require(\"./cell_phone\");\ntr.name = require(\"./name\");\n\n},{\"./address\":926,\"./cell_phone\":932,\"./internet\":935,\"./lorem\":936,\"./name\":939,\"./phone_number\":945}],934:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com.tr\",\n  \"com\",\n  \"biz\",\n  \"info\",\n  \"name\",\n  \"gov.tr\"\n];\n\n},{}],935:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":934,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],936:[function(require,module,exports){\nmodule.exports=require(121)\n},{\"./words\":937,\"/Users/a/dev/faker.js/lib/locales/de/lorem/index.js\":121}],937:[function(require,module,exports){\nmodule.exports=require(85)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/lorem/words.js\":85}],938:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Aba\",\n  \"Abak\",\n  \"Abaka\",\n  \"Abakan\",\n  \"Abakay\",\n  \"Abar\",\n  \"Abay\",\n  \"Abı\",\n  \"Abılay\",\n  \"Abluç\",\n  \"Abşar\",\n  \"Açığ\",\n  \"Açık\",\n  \"Açuk\",\n  \"Adalan\",\n  \"Adaldı\",\n  \"Adalmış\",\n  \"Adar\",\n  \"Adaş\",\n  \"Adberilgen\",\n  \"Adıgüzel\",\n  \"Adık\",\n  \"Adıkutlu\",\n  \"Adıkutlutaş\",\n  \"Adlı\",\n  \"Adlıbeğ\",\n  \"Adraman\",\n  \"Adsız\",\n  \"Afşar\",\n  \"Afşın\",\n  \"Ağabay\",\n  \"Ağakağan\",\n  \"Ağalak\",\n  \"Ağlamış\",\n  \"Ak\",\n  \"Akaş\",\n  \"Akata\",\n  \"Akbaş\",\n  \"Akbay\",\n  \"Akboğa\",\n  \"Akbörü\",\n  \"Akbudak\",\n  \"Akbuğra\",\n  \"Akbulak\",\n  \"Akça\",\n  \"Akçakoca\",\n  \"Akçora\",\n  \"Akdemir\",\n  \"Akdoğan\",\n  \"Akı\",\n  \"Akıbudak\",\n  \"Akım\",\n  \"Akın\",\n  \"Akınçı\",\n  \"Akkun\",\n  \"Akkunlu\",\n  \"Akkurt\",\n  \"Akkuş\",\n  \"Akpıra\",\n  \"Aksungur\",\n  \"Aktan\",\n  \"Al\",\n  \"Ala\",\n  \"Alaban\",\n  \"Alabörü\",\n  \"Aladağ\",\n  \"Aladoğan\",\n  \"Alakurt\",\n  \"Alayunt\",\n  \"Alayuntlu\",\n  \"Aldemir\",\n  \"Aldıgerey\",\n  \"Aldoğan\",\n  \"Algu\",\n  \"Alımga\",\n  \"Alka\",\n  \"Alkabölük\",\n  \"Alkaevli\",\n  \"Alkan\",\n  \"Alkaşı\",\n  \"Alkış\",\n  \"Alp\",\n  \"Alpagut\",\n  \"Alpamış\",\n  \"Alparsbeğ\",\n  \"Alparslan\",\n  \"Alpata\",\n  \"Alpay\",\n  \"Alpaya\",\n  \"Alpaykağan\",\n  \"Alpbamsı\",\n  \"Alpbilge\",\n  \"Alpdirek\",\n  \"Alpdoğan\",\n  \"Alper\",\n  \"Alperen\",\n  \"Alpertunga\",\n  \"Alpgerey\",\n  \"Alpış\",\n  \"Alpilig\",\n  \"Alpkara\",\n  \"Alpkutlu\",\n  \"Alpkülük\",\n  \"Alpşalçı\",\n  \"Alptegin\",\n  \"Alptuğrul\",\n  \"Alptunga\",\n  \"Alpturan\",\n  \"Alptutuk\",\n  \"Alpuluğ\",\n  \"Alpurungu\",\n  \"Alpurungututuk\",\n  \"Alpyörük\",\n  \"Altan\",\n  \"Altankağan\",\n  \"Altankan\",\n  \"Altay\",\n  \"Altın\",\n  \"Altınkağan\",\n  \"Altınkan\",\n  \"Altınoba\",\n  \"Altıntamgan\",\n  \"Altıntamgantarkan\",\n  \"Altıntarkan\",\n  \"Altıntay\",\n  \"Altmışkara\",\n  \"Altuga\",\n  \"Amaç\",\n  \"Amrak\",\n  \"Amul\",\n  \"Ançuk\",\n  \"Andarıman\",\n  \"Anıl\",\n  \"Ant\",\n  \"Apa\",\n  \"Apak\",\n  \"Apatarkan\",\n  \"Aprançur\",\n  \"Araboğa\",\n  \"Arademir\",\n  \"Aral\",\n  \"Arbay\",\n  \"Arbuz\",\n  \"Arçuk\",\n  \"Ardıç\",\n  \"Argıl\",\n  \"Argu\",\n  \"Argun\",\n  \"Arı\",\n  \"Arıboğa\",\n  \"Arık\",\n  \"Arıkağan\",\n  \"Arıkdoruk\",\n  \"Arınç\",\n  \"Arkın\",\n  \"Arkış\",\n  \"Armağan\",\n  \"Arnaç\",\n  \"Arpat\",\n  \"Arsal\",\n  \"Arsıl\",\n  \"Arslan\",\n  \"Arslanargun\",\n  \"Arslanbörü\",\n  \"Arslansungur\",\n  \"Arslantegin\",\n  \"Arslanyabgu\",\n  \"Arşun\",\n  \"Artıınal\",\n  \"Artuk\",\n  \"Artukaç\",\n  \"Artut\",\n  \"Aruk\",\n  \"Asartegin\",\n  \"Asığ\",\n  \"Asrı\",\n  \"Asuğ\",\n  \"Aşan\",\n  \"Aşanboğa\",\n  \"Aşantuğrul\",\n  \"Aşantudun\",\n  \"Aşıkbulmuş\",\n  \"Aşkın\",\n  \"Aştaloğul\",\n  \"Aşuk\",\n  \"Ataç\",\n  \"Atakağan\",\n  \"Atakan\",\n  \"Atalan\",\n  \"Ataldı\",\n  \"Atalmış\",\n  \"Ataman\",\n  \"Atasagun\",\n  \"Atasu\",\n  \"Atberilgen\",\n  \"Atıgay\",\n  \"Atıkutlu\",\n  \"Atıkutlutaş\",\n  \"Atıla\",\n  \"Atılgan\",\n  \"Atım\",\n  \"Atımer\",\n  \"Atış\",\n  \"Atlı\",\n  \"Atlıbeğ\",\n  \"Atlıkağan\",\n  \"Atmaca\",\n  \"Atsız\",\n  \"Atunçu\",\n  \"Avar\",\n  \"Avluç\",\n  \"Avşar\",\n  \"Ay\",\n  \"Ayaçı\",\n  \"Ayas\",\n  \"Ayaş\",\n  \"Ayaz\",\n  \"Aybalta\",\n  \"Ayban\",\n  \"Aybars\",\n  \"Aybeğ\",\n  \"Aydarkağan\",\n  \"Aydemir\",\n  \"Aydın\",\n  \"Aydınalp\",\n  \"Aydoğan\",\n  \"Aydoğdu\",\n  \"Aydoğmuş\",\n  \"Aygırak\",\n  \"Ayıtmış\",\n  \"Ayız\",\n  \"Ayızdağ\",\n  \"Aykağan\",\n  \"Aykan\",\n  \"Aykurt\",\n  \"Ayluç\",\n  \"Ayluçtarkan\",\n  \"Ayma\",\n  \"Ayruk\",\n  \"Aysılığ\",\n  \"Aytak\",\n  \"Ayyıldız\",\n  \"Azak\",\n  \"Azban\",\n  \"Azgan\",\n  \"Azganaz\",\n  \"Azıl\",\n  \"Babır\",\n  \"Babur\",\n  \"Baçara\",\n  \"Baççayman\",\n  \"Baçman\",\n  \"Badabul\",\n  \"Badruk\",\n  \"Badur\",\n  \"Bağa\",\n  \"Bağaalp\",\n  \"Bağaışbara\",\n  \"Bağan\",\n  \"Bağaşatulu\",\n  \"Bağatarkan\",\n  \"Bağatengrikağan\",\n  \"Bağatur\",\n  \"Bağaturçigşi\",\n  \"Bağaturgerey\",\n  \"Bağaturipi\",\n  \"Bağatursepi\",\n  \"Bağış\",\n  \"Bağtaş\",\n  \"Bakağul\",\n  \"Bakır\",\n  \"Bakırsokum\",\n  \"Baksı\",\n  \"Bakşı\",\n  \"Balaban\",\n  \"Balaka\",\n  \"Balakatay\",\n  \"Balamır\",\n  \"Balçar\",\n  \"Baldu\",\n  \"Balkık\",\n  \"Balta\",\n  \"Baltacı\",\n  \"Baltar\",\n  \"Baltır\",\n  \"Baltur\",\n  \"Bamsı\",\n  \"Bangu\",\n  \"Barak\",\n  \"Baraktöre\",\n  \"Baran\",\n  \"Barbeğ\",\n  \"Barboğa\",\n  \"Barbol\",\n  \"Barbulsun\",\n  \"Barça\",\n  \"Barçadoğdu\",\n  \"Barçadoğmuş\",\n  \"Barçadurdu\",\n  \"Barçadurmuş\",\n  \"Barçan\",\n  \"Barçatoyun\",\n  \"Bardıbay\",\n  \"Bargan\",\n  \"Barımtay\",\n  \"Barın\",\n  \"Barkan\",\n  \"Barkdoğdu\",\n  \"Barkdoğmuş\",\n  \"Barkdurdu\",\n  \"Barkdurmuş\",\n  \"Barkın\",\n  \"Barlas\",\n  \"Barlıbay\",\n  \"Barmaklak\",\n  \"Barmaklı\",\n  \"Barman\",\n  \"Bars\",\n  \"Barsbeğ\",\n  \"Barsboğa\",\n  \"Barsgan\",\n  \"Barskan\",\n  \"Barsurungu\",\n  \"Bartu\",\n  \"Basademir\",\n  \"Basan\",\n  \"Basanyalavaç\",\n  \"Basar\",\n  \"Basat\",\n  \"Baskın\",\n  \"Basmıl\",\n  \"Bastı\",\n  \"Bastuğrul\",\n  \"Basu\",\n  \"Basut\",\n  \"Başak\",\n  \"Başbuğ\",\n  \"Başçı\",\n  \"Başgan\",\n  \"Başkırt\",\n  \"Başkurt\",\n  \"Baştar\",\n  \"Batrak\",\n  \"Batu\",\n  \"Batuk\",\n  \"Batur\",\n  \"Baturalp\",\n  \"Bay\",\n  \"Bayançar\",\n  \"Bayankağan\",\n  \"Bayat\",\n  \"Bayazıt\",\n  \"Baybars\",\n  \"Baybayık\",\n  \"Baybiçen\",\n  \"Bayboğa\",\n  \"Baybora\",\n  \"Baybüre\",\n  \"Baydar\",\n  \"Baydemir\",\n  \"Baydur\",\n  \"Bayık\",\n  \"Bayınçur\",\n  \"Bayındır\",\n  \"Baykal\",\n  \"Baykara\",\n  \"Baykoca\",\n  \"Baykuzu\",\n  \"Baymünke\",\n  \"Bayna\",\n  \"Baynal\",\n  \"Baypüre\",\n  \"Bayrı\",\n  \"Bayraç\",\n  \"Bayrak\",\n  \"Bayram\",\n  \"Bayrın\",\n  \"Bayruk\",\n  \"Baysungur\",\n  \"Baytara\",\n  \"Baytaş\",\n  \"Bayunçur\",\n  \"Bayur\",\n  \"Bayurku\",\n  \"Bayutmuş\",\n  \"Bayuttu\",\n  \"Bazır\",\n  \"Beçeapa\",\n  \"Beçkem\",\n  \"Beğ\",\n  \"Beğarslan\",\n  \"Beğbars\",\n  \"Beğbilgeçikşin\",\n  \"Beğboğa\",\n  \"Beğçur\",\n  \"Beğdemir\",\n  \"Beğdilli\",\n  \"Beğdurmuş\",\n  \"Beğkulu\",\n  \"Beğtaş\",\n  \"Beğtegin\",\n  \"Beğtüzün\",\n  \"Begi\",\n  \"Begil\",\n  \"Begine\",\n  \"Begitutuk\",\n  \"Beglen\",\n  \"Begni\",\n  \"Bek\",\n  \"Bekazıl\",\n  \"Bekbekeç\",\n  \"Bekeç\",\n  \"Bekeçarslan\",\n  \"Bekeçarslantegin\",\n  \"Bekeçtegin\",\n  \"Beker\",\n  \"Beklemiş\",\n  \"Bektür\",\n  \"Belçir\",\n  \"Belek\",\n  \"Belgi\",\n  \"Belgüc\",\n  \"Beltir\",\n  \"Bengi\",\n  \"Bengü\",\n  \"Benlidemir\",\n  \"Berdibeğ\",\n  \"Berendey\",\n  \"Bergü\",\n  \"Berginsenge\",\n  \"Berk\",\n  \"Berke\",\n  \"Berkiş\",\n  \"Berkyaruk\",\n  \"Bermek\",\n  \"Besentegin\",\n  \"Betemir\",\n  \"Beyizçi\",\n  \"Beyrek\",\n  \"Beyrem\",\n  \"Bıçkı\",\n  \"Bıçkıcı\",\n  \"Bıdın\",\n  \"Bıtaybıkı\",\n  \"Bıtrı\",\n  \"Biçek\",\n  \"Bilge\",\n  \"Bilgebayunçur\",\n  \"Bilgebeğ\",\n  \"Bilgeçikşin\",\n  \"Bilgeışbara\",\n  \"Bilgeışbaratamgan\",\n  \"Bilgekağan\",\n  \"Bilgekan\",\n  \"Bilgekutluk\",\n  \"Bilgekülüçur\",\n  \"Bilgetaçam\",\n  \"Bilgetamgacı\",\n  \"Bilgetardu\",\n  \"Bilgetegin\",\n  \"Bilgetonyukuk\",\n  \"Bilgez\",\n  \"Bilgiç\",\n  \"Bilgin\",\n  \"Bilig\",\n  \"Biligköngülsengün\",\n  \"Bilik\",\n  \"Binbeği\",\n  \"Bindir\",\n  \"Boğa\",\n  \"Boğaç\",\n  \"Boğaçuk\",\n  \"Boldaz\",\n  \"Bolmuş\",\n  \"Bolsun\",\n  \"Bolun\",\n  \"Boncuk\",\n  \"Bongul\",\n  \"Bongulboğa\",\n  \"Bora\",\n  \"Boran\",\n  \"Borçul\",\n  \"Borlukçu\",\n  \"Bornak\",\n  \"Boyan\",\n  \"Boyankulu\",\n  \"Boylabağa\",\n  \"Boylabağatarkan\",\n  \"Boylakutlutarkan\",\n  \"Bozan\",\n  \"Bozbörü\",\n  \"Bozdoğan\",\n  \"Bozkurt\",\n  \"Bozkuş\",\n  \"Bozok\",\n  \"Bögde\",\n  \"Böge\",\n  \"Bögü\",\n  \"Bökde\",\n  \"Bökde\",\n  \"Böke\",\n  \"Bölen\",\n  \"Bölükbaşı\",\n  \"Bönek\",\n  \"Bönge\",\n  \"Börü\",\n  \"Börübars\",\n  \"Börüsengün\",\n  \"Börteçine\",\n  \"Buçan\",\n  \"Buçur\",\n  \"Budağ\",\n  \"Budak\",\n  \"Budunlu\",\n  \"Buğday\",\n  \"Buğra\",\n  \"Buğrakarakağan\",\n  \"Bukak\",\n  \"Bukaktutuk\",\n  \"Bulaçapan\",\n  \"Bulak\",\n  \"Bulan\",\n  \"Buldur\",\n  \"Bulgak\",\n  \"Bulmaz\",\n  \"Bulmuş\",\n  \"Buluç\",\n  \"Buluğ\",\n  \"Buluk\",\n  \"Buluş\",\n  \"Bulut\",\n  \"Bumın\",\n  \"Bunsuz\",\n  \"Burçak\",\n  \"Burguçan\",\n  \"Burkay\",\n  \"Burslan\",\n  \"Burulday\",\n  \"Burulgu\",\n  \"Burunduk\",\n  \"Buşulgan\",\n  \"Butak\",\n  \"Butuk\",\n  \"Buyan\",\n  \"Buyançuk\",\n  \"Buyandemir\",\n  \"Buyankara\",\n  \"Buyat\",\n  \"Buyraç\",\n  \"Buyruç\",\n  \"Buyruk\",\n  \"Buzaç\",\n  \"Buzaçtutuk\",\n  \"Büdüs\",\n  \"Büdüstudun\",\n  \"Bügü\",\n  \"Bügdüz\",\n  \"Bügdüzemen\",\n  \"Büge\",\n  \"Büğübilge\",\n  \"Bükdüz\",\n  \"Büke\",\n  \"Bükebuyraç\",\n  \"Bükebuyruç\",\n  \"Bükey\",\n  \"Büktegin\",\n  \"Büküşboğa\",\n  \"Bümen\",\n  \"Bünül\",\n  \"Büre\",\n  \"Bürgüt\",\n  \"Bürkek\",\n  \"Bürküt\",\n  \"Bürlük\",\n  \"Cebe\",\n  \"Ceyhun\",\n  \"Cılasun\",\n  \"Çaba\",\n  \"Çabdar\",\n  \"Çablı\",\n  \"Çabuş\",\n  \"Çağan\",\n  \"Çağatay\",\n  \"Çağlar\",\n  \"Çağlayan\",\n  \"Çağrı\",\n  \"Çağrıbeğ\",\n  \"Çağrıtegin\",\n  \"Çağru\",\n  \"Çalapkulu\",\n  \"Çankız\",\n  \"Çemen\",\n  \"Çemgen\",\n  \"Çeykün\",\n  \"Çıngır\",\n  \"Çiçek\",\n  \"Çiçem\",\n  \"Çiğdem\",\n  \"Çilenti\",\n  \"Çimen\",\n  \"Çobulmak\",\n  \"Çocukbörü\",\n  \"Çokramayul\",\n  \"Çolman\",\n  \"Çolpan\",\n  \"Çölü\",\n  \"Damla\",\n  \"Deniz\",\n  \"Dilek\",\n  \"Diri\",\n  \"Dizik\",\n  \"Duru\",\n  \"Dururbunsuz\",\n  \"Duygu\",\n  \"Ebin\",\n  \"Ebkızı\",\n  \"Ebren\",\n  \"Edil\",\n  \"Ediz\",\n  \"Egemen\",\n  \"Eğrim\",\n  \"Ekeç\",\n  \"Ekim\",\n  \"Ekin\",\n  \"Elkin\",\n  \"Elti\",\n  \"Engin\",\n  \"Erdem\",\n  \"Erdeni\",\n  \"Erdeniözük\",\n  \"Erdenikatun\",\n  \"Erentüz\",\n  \"Ergene\",\n  \"Ergenekatun\",\n  \"Erinç\",\n  \"Erke\",\n  \"Ermen\",\n  \"Erten\",\n  \"Ertenözük\",\n  \"Esen\",\n  \"Esenbike\",\n  \"Eser\",\n  \"Esin\",\n  \"Etil\",\n  \"Evin\",\n  \"Eyiz\",\n  \"Gelin\",\n  \"Gelincik\",\n  \"Gökbörü\",\n  \"Gökçe\",\n  \"Gökçegöl\",\n  \"Gökçen\",\n  \"Gökçiçek\",\n  \"Gökşin\",\n  \"Gönül\",\n  \"Görün\",\n  \"Gözde\",\n  \"Gülegen\",\n  \"Gülemen\",\n  \"Güler\",\n  \"Gülümser\",\n  \"Gümüş\",\n  \"Gün\",\n  \"Günay\",\n  \"Günçiçek\",\n  \"Gündoğdu\",\n  \"Gündoğmuş\",\n  \"Güneş\",\n  \"Günyaruk\",\n  \"Gürbüz\",\n  \"Güvercin\",\n  \"Güzey\",\n  \"Işığ\",\n  \"Işık\",\n  \"Işıl\",\n  \"Işılay\",\n  \"Ila\",\n  \"Ilaçın\",\n  \"Ilgın\",\n  \"Inanç\",\n  \"Irmak\",\n  \"Isığ\",\n  \"Isık\",\n  \"Iyık\",\n  \"Iyıktağ\",\n  \"İdil\",\n  \"İkeme\",\n  \"İkiçitoyun\",\n  \"İlbilge\",\n  \"İldike\",\n  \"İlgegü\",\n  \"İmrem\",\n  \"İnci\",\n  \"İnç\",\n  \"İrinç\",\n  \"İrinçköl\",\n  \"İrtiş\",\n  \"İtil\",\n  \"Kancı\",\n  \"Kançı\",\n  \"Kapgar\",\n  \"Karaca\",\n  \"Karaça\",\n  \"Karak\",\n  \"Kargılaç\",\n  \"Karlıgaç\",\n  \"Katun\",\n  \"Katunkız\",\n  \"Kayacık\",\n  \"Kayaçık\",\n  \"Kayça\",\n  \"Kaynak\",\n  \"Kazanç\",\n  \"Kazkatun\",\n  \"Kekik\",\n  \"Keklik\",\n  \"Kepez\",\n  \"Kesme\",\n  \"Keyken\",\n  \"Kezlik\",\n  \"Kımız\",\n  \"Kımızın\",\n  \"Kımızalma\",\n  \"Kımızalmıla\",\n  \"Kırçiçek\",\n  \"Kırgavul\",\n  \"Kırlangıç\",\n  \"Kıvanç\",\n  \"Kıvılcım\",\n  \"Kızdurmuş\",\n  \"Kızılalma\"\n];\n\n},{}],939:[function(require,module,exports){\narguments[4][173][0].apply(exports,arguments)\n},{\"./first_name\":938,\"./last_name\":940,\"./name\":941,\"./prefix\":942,\"/Users/a/dev/faker.js/lib/locales/de_CH/name/index.js\":173}],940:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Abacı\",\n  \"Abadan\",\n  \"Aclan\",\n  \"Adal\",\n  \"Adan\",\n  \"Adıvar\",\n  \"Akal\",\n  \"Akan\",\n  \"Akar \",\n  \"Akay\",\n  \"Akaydın\",\n  \"Akbulut\",\n  \"Akgül\",\n  \"Akışık\",\n  \"Akman\",\n  \"Akyürek\",\n  \"Akyüz\",\n  \"Akşit\",\n  \"Alnıaçık\",\n  \"Alpuğan\",\n  \"Alyanak\",\n  \"Arıcan\",\n  \"Arslanoğlu\",\n  \"Atakol\",\n  \"Atan\",\n  \"Avan\",\n  \"Ayaydın\",\n  \"Aybar\",\n  \"Aydan\",\n  \"Aykaç\",\n  \"Ayverdi\",\n  \"Ağaoğlu\",\n  \"Aşıkoğlu\",\n  \"Babacan\",\n  \"Babaoğlu\",\n  \"Bademci\",\n  \"Bakırcıoğlu\",\n  \"Balaban\",\n  \"Balcı\",\n  \"Barbarosoğlu\",\n  \"Baturalp\",\n  \"Baykam\",\n  \"Başoğlu\",\n  \"Berberoğlu\",\n  \"Beşerler\",\n  \"Beşok\",\n  \"Biçer\",\n  \"Bolatlı\",\n  \"Dalkıran\",\n  \"Dağdaş\",\n  \"Dağlaroğlu\",\n  \"Demirbaş\",\n  \"Demirel\",\n  \"Denkel\",\n  \"Dizdar \",\n  \"Doğan \",\n  \"Durak \",\n  \"Durmaz\",\n  \"Duygulu\",\n  \"Düşenkalkar\",\n  \"Egeli\",\n  \"Ekici\",\n  \"Ekşioğlu\",\n  \"Eliçin\",\n  \"Elmastaşoğlu\",\n  \"Elçiboğa\",\n  \"Erbay\",\n  \"Erberk\",\n  \"Erbulak\",\n  \"Erdoğan\",\n  \"Erez\",\n  \"Erginsoy\",\n  \"Erkekli\",\n  \"Eronat\",\n  \"Ertepınar\",\n  \"Ertürk\",\n  \"Erçetin\",\n  \"Evliyaoğlu\",\n  \"Gönültaş\",\n  \"Gümüşpala\",\n  \"Günday\",\n  \"Gürmen\",\n  \"Hakyemez\",\n  \"Hamzaoğlu\",\n  \"Ilıcalı\",\n  \"Kahveci\",\n  \"Kaplangı\",\n  \"Karabulut\",\n  \"Karaböcek\",\n  \"Karadaş\",\n  \"Karaduman\",\n  \"Karaer\",\n  \"Kasapoğlu\",\n  \"Kavaklıoğlu\",\n  \"Kaya \",\n  \"Keseroğlu\",\n  \"Keçeci\",\n  \"Kılıççı\",\n  \"Kıraç \",\n  \"Kocabıyık\",\n  \"Korol\",\n  \"Koyuncu\",\n  \"Koç\",\n  \"Koçoğlu\",\n  \"Koçyiğit\",\n  \"Kuday\",\n  \"Kulaksızoğlu\",\n  \"Kumcuoğlu\",\n  \"Kunt\",\n  \"Kunter\",\n  \"Kurutluoğlu\",\n  \"Kutlay\",\n  \"Kuzucu\",\n  \"Körmükçü\",\n  \"Köybaşı\",\n  \"Köylüoğlu\",\n  \"Küçükler\",\n  \"Limoncuoğlu\",\n  \"Mayhoş\",\n  \"Menemencioğlu\",\n  \"Mertoğlu\",\n  \"Nalbantoğlu\",\n  \"Nebioğlu\",\n  \"Numanoğlu\",\n  \"Okumuş\",\n  \"Okur\",\n  \"Oraloğlu\",\n  \"Orbay\",\n  \"Ozansoy\",\n  \"Paksüt\",\n  \"Pekkan\",\n  \"Pektemek\",\n  \"Polat\",\n  \"Poyrazoğlu\",\n  \"Poçan\",\n  \"Sadıklar\",\n  \"Samancı\",\n  \"Sandalcı\",\n  \"Sarıoğlu\",\n  \"Saygıner\",\n  \"Sepetçi\",\n  \"Sezek\",\n  \"Sinanoğlu\",\n  \"Solmaz\",\n  \"Sözeri\",\n  \"Süleymanoğlu\",\n  \"Tahincioğlu\",\n  \"Tanrıkulu\",\n  \"Tazegül\",\n  \"Taşlı\",\n  \"Taşçı\",\n  \"Tekand\",\n  \"Tekelioğlu\",\n  \"Tokatlıoğlu\",\n  \"Tokgöz\",\n  \"Topaloğlu\",\n  \"Topçuoğlu\",\n  \"Toraman\",\n  \"Tunaboylu\",\n  \"Tunçeri\",\n  \"Tuğlu\",\n  \"Tuğluk\",\n  \"Türkdoğan\",\n  \"Türkyılmaz\",\n  \"Tütüncü\",\n  \"Tüzün\",\n  \"Uca\",\n  \"Uluhan\",\n  \"Velioğlu\",\n  \"Yalçın\",\n  \"Yazıcı\",\n  \"Yetkiner\",\n  \"Yeşilkaya\",\n  \"Yıldırım \",\n  \"Yıldızoğlu\",\n  \"Yılmazer\",\n  \"Yorulmaz\",\n  \"Çamdalı\",\n  \"Çapanoğlu\",\n  \"Çatalbaş\",\n  \"Çağıran\",\n  \"Çetin\",\n  \"Çetiner\",\n  \"Çevik\",\n  \"Çörekçi\",\n  \"Önür\",\n  \"Örge\",\n  \"Öymen\",\n  \"Özberk\",\n  \"Özbey\",\n  \"Özbir\",\n  \"Özdenak\",\n  \"Özdoğan\",\n  \"Özgörkey\",\n  \"Özkara\",\n  \"Özkök \",\n  \"Öztonga\",\n  \"Öztuna\"\n];\n\n},{}],941:[function(require,module,exports){\nmodule.exports=require(538)\n},{\"/Users/a/dev/faker.js/lib/locales/ge/name/name.js\":538}],942:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Bay\",\n  \"Bayan\",\n  \"Dr.\",\n  \"Prof. Dr.\"\n];\n\n},{}],943:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"392\",\n  \"510\",\n  \"512\",\n  \"522\",\n  \"562\",\n  \"564\",\n  \"592\",\n  \"594\",\n  \"800\",\n  \"811\",\n  \"822\",\n  \"850\",\n  \"888\",\n  \"898\",\n  \"900\",\n  \"322\",\n  \"416\",\n  \"272\",\n  \"472\",\n  \"382\",\n  \"358\",\n  \"312\",\n  \"242\",\n  \"478\",\n  \"466\",\n  \"256\",\n  \"266\",\n  \"378\",\n  \"488\",\n  \"458\",\n  \"228\",\n  \"426\",\n  \"434\",\n  \"374\",\n  \"248\",\n  \"224\",\n  \"286\",\n  \"376\",\n  \"364\",\n  \"258\",\n  \"412\",\n  \"380\",\n  \"284\",\n  \"424\",\n  \"446\",\n  \"442\",\n  \"222\",\n  \"342\",\n  \"454\",\n  \"456\",\n  \"438\",\n  \"326\",\n  \"476\",\n  \"246\",\n  \"216\",\n  \"212\",\n  \"232\",\n  \"344\",\n  \"370\",\n  \"338\",\n  \"474\",\n  \"366\",\n  \"352\",\n  \"318\",\n  \"288\",\n  \"386\",\n  \"348\",\n  \"262\",\n  \"332\",\n  \"274\",\n  \"422\",\n  \"236\",\n  \"482\",\n  \"324\",\n  \"252\",\n  \"436\",\n  \"384\",\n  \"388\",\n  \"452\",\n  \"328\",\n  \"464\",\n  \"264\",\n  \"362\",\n  \"484\",\n  \"368\",\n  \"346\",\n  \"414\",\n  \"486\",\n  \"282\",\n  \"356\",\n  \"462\",\n  \"428\",\n  \"276\",\n  \"432\",\n  \"226\",\n  \"354\",\n  \"372\"\n];\n\n},{}],944:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"+90-###-###-##-##\",\n  \"+90-###-###-#-###\"\n];\n\n},{}],945:[function(require,module,exports){\nvar phone_number = {};\nmodule['exports'] = phone_number;\nphone_number.area_code = require(\"./area_code\");\nphone_number.formats = require(\"./formats\");\n\n},{\"./area_code\":943,\"./formats\":944}],946:[function(require,module,exports){\nmodule.exports=require(54)\n},{\"/Users/a/dev/faker.js/lib/locales/cz/address/building_number.js\":54}],947:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_name}\",\n  \"#{city_prefix} #{Name.male_first_name}\"\n];\n\n},{}],948:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Лисичанськ\",\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  \"Чернівці\",\n  \"Чернігів\",\n  \"Шостка\",\n  \"Ялта\"\n];\n\n},{}],949:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Південний\",\n  \"Північний\",\n  \"Східний\",\n  \"Західний\"\n];\n\n},{}],950:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"град\"\n];\n\n},{}],951:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Бутан\",\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  \"Естонія\",\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  \"Колумбія\",\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  \"Мексика\",\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  \"Польща\",\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  \"Сьєрра-Леоне\",\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  \"Швейцарія\",\n  \"Швеція\",\n  \"Шрі-Ланка\",\n  \"Ямайка\",\n  \"Японія\"\n];\n\n},{}],952:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Україна\"\n];\n\n},{}],953:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.country = require(\"./country\");\naddress.building_number = require(\"./building_number\");\naddress.street_prefix = require(\"./street_prefix\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.secondary_address = require(\"./secondary_address\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.street_title = require(\"./street_title\");\naddress.city_name = require(\"./city_name\");\naddress.city = require(\"./city\");\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":946,\"./city\":947,\"./city_name\":948,\"./city_prefix\":949,\"./city_suffix\":950,\"./country\":951,\"./default_country\":952,\"./postcode\":954,\"./secondary_address\":955,\"./state\":956,\"./street_address\":957,\"./street_name\":958,\"./street_prefix\":959,\"./street_suffix\":960,\"./street_title\":961}],954:[function(require,module,exports){\nmodule.exports=require(379)\n},{\"/Users/a/dev/faker.js/lib/locales/es/address/postcode.js\":379}],955:[function(require,module,exports){\nmodule.exports=require(803)\n},{\"/Users/a/dev/faker.js/lib/locales/ru/address/secondary_address.js\":803}],956:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Севастополь\"\n];\n\n},{}],957:[function(require,module,exports){\nmodule.exports=require(25)\n},{\"/Users/a/dev/faker.js/lib/locales/az/address/street_address.js\":25}],958:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_prefix} #{Address.street_title}\",\n  \"#{Address.street_title} #{street_suffix}\"\n];\n\n},{}],959:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"вул.\",\n  \"вулиця\",\n  \"пр.\",\n  \"проспект\",\n  \"пл.\",\n  \"площа\",\n  \"пров.\",\n  \"провулок\"\n];\n\n},{}],960:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"майдан\"\n];\n\n},{}],961:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Зелена\",\n  \"Молодіжна\",\n  \"Городоцька\",\n  \"Стрийська\",\n  \"Вузька\",\n  \"Нижанківського\",\n  \"Староміська\",\n  \"Ліста\",\n  \"Вічева\",\n  \"Брюховичів\",\n  \"Винників\",\n  \"Рудного\",\n  \"Коліївщини\"\n];\n\n},{}],962:[function(require,module,exports){\narguments[4][33][0].apply(exports,arguments)\n},{\"./name\":963,\"./prefix\":964,\"./suffix\":965,\"/Users/a/dev/faker.js/lib/locales/az/company/index.js\":33}],963:[function(require,module,exports){\nmodule.exports=require(34)\n},{\"/Users/a/dev/faker.js/lib/locales/az/company/name.js\":34}],964:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ТОВ\",\n  \"ПАТ\",\n  \"ПрАТ\",\n  \"ТДВ\",\n  \"КТ\",\n  \"ПТ\",\n  \"ДП\",\n  \"ФОП\"\n];\n\n},{}],965:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Постач\",\n  \"Торг\",\n  \"Пром\",\n  \"Трейд\",\n  \"Збут\"\n];\n\n},{}],966:[function(require,module,exports){\nvar uk = {};\nmodule['exports'] = uk;\nuk.title = \"Ukrainian\";\nuk.address = require(\"./address\");\nuk.company = require(\"./company\");\nuk.internet = require(\"./internet\");\nuk.name = require(\"./name\");\nuk.phone_number = require(\"./phone_number\");\n\n},{\"./address\":953,\"./company\":962,\"./internet\":969,\"./name\":973,\"./phone_number\":982}],967:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"cherkassy.ua\",\n  \"cherkasy.ua\",\n  \"ck.ua\",\n  \"cn.ua\",\n  \"com.ua\",\n  \"crimea.ua\",\n  \"cv.ua\",\n  \"dn.ua\",\n  \"dnepropetrovsk.ua\",\n  \"dnipropetrovsk.ua\",\n  \"donetsk.ua\",\n  \"dp.ua\",\n  \"if.ua\",\n  \"in.ua\",\n  \"ivano-frankivsk.ua\",\n  \"kh.ua\",\n  \"kharkiv.ua\",\n  \"kharkov.ua\",\n  \"kherson.ua\",\n  \"khmelnitskiy.ua\",\n  \"kiev.ua\",\n  \"kirovograd.ua\",\n  \"km.ua\",\n  \"kr.ua\",\n  \"ks.ua\",\n  \"lg.ua\",\n  \"lt.ua\",\n  \"lugansk.ua\",\n  \"lutsk.ua\",\n  \"lutsk.net\",\n  \"lviv.ua\",\n  \"mk.ua\",\n  \"net.ua\",\n  \"nikolaev.ua\",\n  \"od.ua\",\n  \"odessa.ua\",\n  \"org.ua\",\n  \"pl.ua\",\n  \"pl.ua\",\n  \"poltava.ua\",\n  \"rovno.ua\",\n  \"rv.ua\",\n  \"sebastopol.ua\",\n  \"sm.ua\",\n  \"sumy.ua\",\n  \"te.ua\",\n  \"ternopil.ua\",\n  \"ua\",\n  \"uz.ua\",\n  \"uzhgorod.ua\",\n  \"vinnica.ua\",\n  \"vn.ua\",\n  \"volyn.net\",\n  \"volyn.ua\",\n  \"yalta.ua\",\n  \"zaporizhzhe.ua\",\n  \"zhitomir.ua\",\n  \"zp.ua\",\n  \"zt.ua\",\n  \"укр\"\n];\n\n},{}],968:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"ukr.net\",\n  \"ex.ua\",\n  \"e-mail.ua\",\n  \"i.ua\",\n  \"meta.ua\",\n  \"yandex.ua\",\n  \"gmail.com\"\n];\n\n},{}],969:[function(require,module,exports){\narguments[4][43][0].apply(exports,arguments)\n},{\"./domain_suffix\":967,\"./free_email\":968,\"/Users/a/dev/faker.js/lib/locales/az/internet/index.js\":43}],970:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Антонія\",\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  \"Віра\",\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  \"Звенислава\",\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  \"Лілія\",\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  \"Наталія\",\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  \"Ромена\",\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  \"Юхима\",\n  \"Юхимія\",\n  \"Яна\",\n  \"Ярина\",\n  \"Ярослава\"\n];\n\n},{}],971:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Витребенько\",\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  \"Гриневська\",\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  \"Коваленко\",\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  \"Луцьків\",\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  \"Негода\",\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  \"Пригода\",\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  \"Сторожук\",\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  \"Шупик\",\n  \"Шухевич\",\n  \"Щербак\",\n  \"Юрчишина\",\n  \"Юхно\",\n  \"Ющик\",\n  \"Ющук\",\n  \"Яворівська\",\n  \"Ялова\",\n  \"Ялюк\",\n  \"Янюк\",\n  \"Ярмак\",\n  \"Яцишина\",\n  \"Яцьків\",\n  \"Ящук\"\n];\n\n},{}],972:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Валентинівна\",\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  \"Зеновіївна\",\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  \"Натанівна\",\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  \"Степанівна\",\n  \"Стефаніївна\",\n  \"Тарасівна\",\n  \"Тимофіївна\",\n  \"Тихонівна\",\n  \"Устимівна\",\n  \"Юріївна\",\n  \"Юхимівна\",\n  \"Ярославівна\"\n];\n\n},{}],973:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.male_first_name = require(\"./male_first_name\");\nname.male_middle_name = require(\"./male_middle_name\");\nname.male_last_name = require(\"./male_last_name\");\nname.female_first_name = require(\"./female_first_name\");\nname.female_middle_name = require(\"./female_middle_name\");\nname.female_last_name = require(\"./female_last_name\");\nname.prefix = require(\"./prefix\");\nname.suffix = require(\"./suffix\");\nname.title = require(\"./title\");\nname.name = require(\"./name\");\n\n},{\"./female_first_name\":970,\"./female_last_name\":971,\"./female_middle_name\":972,\"./male_first_name\":974,\"./male_last_name\":975,\"./male_middle_name\":976,\"./name\":977,\"./prefix\":978,\"./suffix\":979,\"./title\":980}],974:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Болеслав\",\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  \"Всеслав\",\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  \"Звенигор\",\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  \"Ладомир\",\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  \"Олександр\",\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  \"Святослав\",\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  \"Ян\",\n  \"Ярема\",\n  \"Яровид\",\n  \"Яромил\",\n  \"Яромир\",\n  \"Ярополк\",\n  \"Ярослав\"\n];\n\n},{}],975:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Верещук\",\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  \"Гриневецький\",\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  \"Кандиба\",\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  \"Лобачевський\",\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  \"Могилевський\",\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  \"Поривай\",\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  \"Сосюра\",\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  \"Червоній\",\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},{}],976:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"Валентинович\",\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  \"Зеновійович\",\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  \"Натанович\",\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  \"Степанович\",\n  \"Стефанович\",\n  \"Тарасович\",\n  \"Тимофійович\",\n  \"Тихонович\",\n  \"Устимович\",\n  \"Юрійович\",\n  \"Юхимович\",\n  \"Ярославович\"\n];\n\n},{}],977:[function(require,module,exports){\nmodule.exports=require(831)\n},{\"/Users/a/dev/faker.js/lib/locales/ru/name/name.js\":831}],978:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Пан\",\n  \"Пані\"\n];\n\n},{}],979:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"проф.\",\n  \"доц.\",\n  \"докт. пед. наук\",\n  \"докт. політ. наук\",\n  \"докт. філол. наук\",\n  \"докт. філос. наук\",\n  \"докт. і. наук\",\n  \"докт. юрид. наук\",\n  \"докт. техн. наук\",\n  \"докт. психол. наук\",\n  \"канд. пед. наук\",\n  \"канд. політ. наук\",\n  \"канд. філол. наук\",\n  \"канд. філос. наук\",\n  \"канд. і. наук\",\n  \"канд. юрид. наук\",\n  \"канд. техн. наук\",\n  \"канд. психол. наук\"\n];\n\n},{}],980:[function(require,module,exports){\nmodule[\"exports\"] = {\n  \"descriptor\": [\n    \"Головний\",\n    \"Генеральний\",\n    \"Провідний\",\n    \"Національний\",\n    \"Регіональний\",\n    \"Обласний\",\n    \"Районний\",\n    \"Глобальний\",\n    \"Міжнародний\",\n    \"Центральний\"\n  ],\n  \"level\": [\n    \"маркетинговий\",\n    \"оптимізаційний\",\n    \"страховий\",\n    \"функціональний\",\n    \"інтеграційний\",\n    \"логістичний\"\n  ],\n  \"job\": [\n    \"інженер\",\n    \"агент\",\n    \"адміністратор\",\n    \"аналітик\",\n    \"архітектор\",\n    \"дизайнер\",\n    \"керівник\",\n    \"консультант\",\n    \"координатор\",\n    \"менеджер\",\n    \"планувальник\",\n    \"помічник\",\n    \"розробник\",\n    \"спеціаліст\",\n    \"співробітник\",\n    \"технік\"\n  ]\n};\n\n},{}],981:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"(044) ###-##-##\",\n  \"(050) ###-##-##\",\n  \"(063) ###-##-##\",\n  \"(066) ###-##-##\",\n  \"(073) ###-##-##\",\n  \"(091) ###-##-##\",\n  \"(092) ###-##-##\",\n  \"(093) ###-##-##\",\n  \"(094) ###-##-##\",\n  \"(095) ###-##-##\",\n  \"(096) ###-##-##\",\n  \"(097) ###-##-##\",\n  \"(098) ###-##-##\",\n  \"(099) ###-##-##\"\n];\n\n},{}],982:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":981,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],983:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{city_root}\"\n];\n\n},{}],984:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Bắc Giang\",\n  \"Bắc Kạn\",\n  \"Bắc Ninh\",\n  \"Cao Bằng\",\n  \"Điện Biên\",\n  \"Hà Giang\",\n  \"Hà Nam\",\n  \"Hà Tây\",\n  \"Hải Dương\",\n  \"TP Hải Phòng\",\n  \"Hòa Bình\",\n  \"Hưng Yên\",\n  \"Lai Châu\",\n  \"Lào Cai\",\n  \"Lạng Sơn\",\n  \"Nam Định\",\n  \"Ninh Bình\",\n  \"Phú Thọ\",\n  \"Quảng Ninh\",\n  \"Sơn La\",\n  \"Thái Bình\",\n  \"Thái Nguyên\",\n  \"Tuyên Quang\",\n  \"Vĩnh Phúc\",\n  \"Yên Bái\",\n  \"TP Đà Nẵng\",\n  \"Bình Định\",\n  \"Đắk Lắk\",\n  \"Đắk Nông\",\n  \"Gia Lai\",\n  \"Hà Tĩnh\",\n  \"Khánh Hòa\",\n  \"Kon Tum\",\n  \"Nghệ An\",\n  \"Phú Yên\",\n  \"Quảng Bình\",\n  \"Quảng Nam\",\n  \"Quảng Ngãi\",\n  \"Quảng Trị\",\n  \"Thanh Hóa\",\n  \"Thừa Thiên Huế\",\n  \"TP TP. Hồ Chí Minh\",\n  \"An Giang\",\n  \"Bà Rịa Vũng Tàu\",\n  \"Bạc Liêu\",\n  \"Bến Tre\",\n  \"Bình Dương\",\n  \"Bình Phước\",\n  \"Bình Thuận\",\n  \"Cà Mau\",\n  \"TP Cần Thơ\",\n  \"Đồng Nai\",\n  \"Đồng Tháp\",\n  \"Hậu Giang\",\n  \"Kiên Giang\",\n  \"Lâm Đồng\",\n  \"Long An\",\n  \"Ninh Thuận\",\n  \"Sóc Trăng\",\n  \"Tây Ninh\",\n  \"Tiền Giang\",\n  \"Trà Vinh\",\n  \"Vĩnh Long\"\n];\n\n},{}],985:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Avon\",\n  \"Bedfordshire\",\n  \"Berkshire\",\n  \"Borders\",\n  \"Buckinghamshire\",\n  \"Cambridgeshire\",\n  \"Central\",\n  \"Cheshire\",\n  \"Cleveland\",\n  \"Clwyd\",\n  \"Cornwall\",\n  \"County Antrim\",\n  \"County Armagh\",\n  \"County Down\",\n  \"County Fermanagh\",\n  \"County Londonderry\",\n  \"County Tyrone\",\n  \"Cumbria\",\n  \"Derbyshire\",\n  \"Devon\",\n  \"Dorset\",\n  \"Dumfries and Galloway\",\n  \"Durham\",\n  \"Dyfed\",\n  \"East Sussex\",\n  \"Essex\",\n  \"Fife\",\n  \"Gloucestershire\",\n  \"Grampian\",\n  \"Greater Manchester\",\n  \"Gwent\",\n  \"Gwynedd County\",\n  \"Hampshire\",\n  \"Herefordshire\",\n  \"Hertfordshire\",\n  \"Highlands and Islands\",\n  \"Humberside\",\n  \"Isle of Wight\",\n  \"Kent\",\n  \"Lancashire\",\n  \"Leicestershire\",\n  \"Lincolnshire\",\n  \"Lothian\",\n  \"Merseyside\",\n  \"Mid Glamorgan\",\n  \"Norfolk\",\n  \"North Yorkshire\",\n  \"Northamptonshire\",\n  \"Northumberland\",\n  \"Nottinghamshire\",\n  \"Oxfordshire\",\n  \"Powys\",\n  \"Rutland\",\n  \"Shropshire\",\n  \"Somerset\",\n  \"South Glamorgan\",\n  \"South Yorkshire\",\n  \"Staffordshire\",\n  \"Strathclyde\",\n  \"Suffolk\",\n  \"Surrey\",\n  \"Tayside\",\n  \"Tyne and Wear\",\n  \"Việt Nam\",\n  \"Warwickshire\",\n  \"West Glamorgan\",\n  \"West Midlands\",\n  \"West Sussex\",\n  \"West Yorkshire\",\n  \"Wiltshire\",\n  \"Worcestershire\"\n];\n\n},{}],986:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Việt Nam\"\n];\n\n},{}],987:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_root = require(\"./city_root\");\naddress.city = require(\"./city\");\naddress.county = require(\"./county\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./city\":983,\"./city_root\":984,\"./county\":985,\"./default_country\":986}],988:[function(require,module,exports){\nmodule.exports=require(308)\n},{\"/Users/a/dev/faker.js/lib/locales/en_GB/cell_phone/formats.js\":308}],989:[function(require,module,exports){\narguments[4][112][0].apply(exports,arguments)\n},{\"./formats\":988,\"/Users/a/dev/faker.js/lib/locales/de/cell_phone/index.js\":112}],990:[function(require,module,exports){\nvar company = {};\nmodule['exports'] = company;\ncompany.prefix = require(\"./prefix\");\ncompany.name = require(\"./name\");\n\n},{\"./name\":991,\"./prefix\":992}],991:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{prefix} #{Name.last_name}\"\n];\n\n},{}],992:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Công ty\",\n  \"Cty TNHH\",\n  \"Cty\",\n  \"Cửa hàng\",\n  \"Trung tâm\",\n  \"Chi nhánh\"\n];\n\n},{}],993:[function(require,module,exports){\nvar vi = {};\nmodule['exports'] = vi;\nvi.title = \"Vietnamese\";\nvi.address = require(\"./address\");\nvi.internet = require(\"./internet\");\nvi.phone_number = require(\"./phone_number\");\nvi.cell_phone = require(\"./cell_phone\");\nvi.name = require(\"./name\");\nvi.company = require(\"./company\");\nvi.lorem = require(\"./lorem\");\n\n},{\"./address\":987,\"./cell_phone\":989,\"./company\":990,\"./internet\":995,\"./lorem\":996,\"./name\":999,\"./phone_number\":1003}],994:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"com\",\n  \"net\",\n  \"info\",\n  \"vn\",\n  \"com.vn\"\n];\n\n},{}],995:[function(require,module,exports){\narguments[4][171][0].apply(exports,arguments)\n},{\"./domain_suffix\":994,\"/Users/a/dev/faker.js/lib/locales/de_CH/internet/index.js\":171}],996:[function(require,module,exports){\narguments[4][121][0].apply(exports,arguments)\n},{\"./words\":997,\"/Users/a/dev/faker.js/lib/locales/de/lorem/index.js\":121}],997:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"đã\",\n  \"đang\",\n  \"ừ\",\n  \"ờ\",\n  \"á\",\n  \"không\",\n  \"biết\",\n  \"gì\",\n  \"hết\",\n  \"đâu\",\n  \"nha\",\n  \"thế\",\n  \"thì\",\n  \"là\",\n  \"đánh\",\n  \"đá\",\n  \"đập\",\n  \"phá\",\n  \"viết\",\n  \"vẽ\",\n  \"tô\",\n  \"thuê\",\n  \"mướn\",\n  \"mượn\",\n  \"mua\",\n  \"một\",\n  \"hai\",\n  \"ba\",\n  \"bốn\",\n  \"năm\",\n  \"sáu\",\n  \"bảy\",\n  \"tám\",\n  \"chín\",\n  \"mười\",\n  \"thôi\",\n  \"việc\",\n  \"nghỉ\",\n  \"làm\",\n  \"nhà\",\n  \"cửa\",\n  \"xe\",\n  \"đạp\",\n  \"ác\",\n  \"độc\",\n  \"khoảng\",\n  \"khoan\",\n  \"thuyền\",\n  \"tàu\",\n  \"bè\",\n  \"lầu\",\n  \"xanh\",\n  \"đỏ\",\n  \"tím\",\n  \"vàng\",\n  \"kim\",\n  \"chỉ\",\n  \"khâu\",\n  \"may\",\n  \"vá\",\n  \"em\",\n  \"anh\",\n  \"yêu\",\n  \"thương\",\n  \"thích\",\n  \"con\",\n  \"cái\",\n  \"bàn\",\n  \"ghế\",\n  \"tủ\",\n  \"quần\",\n  \"áo\",\n  \"nón\",\n  \"dép\",\n  \"giày\",\n  \"lỗi\",\n  \"được\",\n  \"ghét\",\n  \"giết\",\n  \"chết\",\n  \"hết\",\n  \"tôi\",\n  \"bạn\",\n  \"tui\",\n  \"trời\",\n  \"trăng\",\n  \"mây\",\n  \"gió\",\n  \"máy\",\n  \"hàng\",\n  \"hóa\",\n  \"leo\",\n  \"núi\",\n  \"bơi\",\n  \"biển\",\n  \"chìm\",\n  \"xuồng\",\n  \"nước\",\n  \"ngọt\",\n  \"ruộng\",\n  \"đồng\",\n  \"quê\",\n  \"hương\"\n];\n\n},{}],998:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Phạm\",\n  \"Nguyễn\",\n  \"Trần\",\n  \"Lê\",\n  \"Lý\",\n  \"Hoàng\",\n  \"Phan\",\n  \"Vũ\",\n  \"Tăng\",\n  \"Đặng\",\n  \"Bùi\",\n  \"Đỗ\",\n  \"Hồ\",\n  \"Ngô\",\n  \"Dương\",\n  \"Đào\",\n  \"Đoàn\",\n  \"Vương\",\n  \"Trịnh\",\n  \"Đinh\",\n  \"Lâm\",\n  \"Phùng\",\n  \"Mai\",\n  \"Tô\",\n  \"Trương\",\n  \"Hà\"\n];\n\n},{}],999:[function(require,module,exports){\nvar name = {};\nmodule['exports'] = name;\nname.first_name = require(\"./first_name\");\nname.last_name = require(\"./last_name\");\nname.name = require(\"./name\");\n\n},{\"./first_name\":998,\"./last_name\":1000,\"./name\":1001}],1000:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Nam\",\n  \"Trung\",\n  \"Thanh\",\n  \"Thị\",\n  \"Văn\",\n  \"Dương\",\n  \"Tăng\",\n  \"Quốc\",\n  \"Như\",\n  \"Phạm\",\n  \"Nguyễn\",\n  \"Trần\",\n  \"Lê\",\n  \"Lý\",\n  \"Hoàng\",\n  \"Phan\",\n  \"Vũ\",\n  \"Tăng\",\n  \"Đặng\",\n  \"Bùi\",\n  \"Đỗ\",\n  \"Hồ\",\n  \"Ngô\",\n  \"Dương\",\n  \"Đào\",\n  \"Đoàn\",\n  \"Vương\",\n  \"Trịnh\",\n  \"Đinh\",\n  \"Lâm\",\n  \"Phùng\",\n  \"Mai\",\n  \"Tô\",\n  \"Trương\",\n  \"Hà\",\n  \"Vinh\",\n  \"Nhung\",\n  \"Hòa\",\n  \"Tiến\",\n  \"Tâm\",\n  \"Bửu\",\n  \"Loan\",\n  \"Hiền\",\n  \"Hải\",\n  \"Vân\",\n  \"Kha\",\n  \"Minh\",\n  \"Nhân\",\n  \"Triệu\",\n  \"Tuân\",\n  \"Hữu\",\n  \"Đức\",\n  \"Phú\",\n  \"Khoa\",\n  \"Thắgn\",\n  \"Sơn\",\n  \"Dung\",\n  \"Tú\",\n  \"Trinh\",\n  \"Thảo\",\n  \"Sa\",\n  \"Kim\",\n  \"Long\",\n  \"Thi\",\n  \"Cường\",\n  \"Ngọc\",\n  \"Sinh\",\n  \"Khang\",\n  \"Phong\",\n  \"Thắm\",\n  \"Thu\",\n  \"Thủy\",\n  \"Nhàn\"\n];\n\n},{}],1001:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{first_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name}\",\n  \"#{first_name} #{last_name} #{last_name} #{last_name}\"\n];\n\n},{}],1002:[function(require,module,exports){\nmodule.exports=require(313)\n},{\"/Users/a/dev/faker.js/lib/locales/en_GB/phone_number/formats.js\":313}],1003:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":1002,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],1004:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#####\",\n  \"####\",\n  \"###\",\n  \"##\",\n  \"#\"\n];\n\n},{}],1005:[function(require,module,exports){\nmodule.exports=require(879)\n},{\"/Users/a/dev/faker.js/lib/locales/sv/address/city.js\":879}],1006:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"长\",\n  \"上\",\n  \"南\",\n  \"西\",\n  \"北\",\n  \"诸\",\n  \"宁\",\n  \"珠\",\n  \"武\",\n  \"衡\",\n  \"成\",\n  \"福\",\n  \"厦\",\n  \"贵\",\n  \"吉\",\n  \"海\",\n  \"太\",\n  \"济\",\n  \"安\",\n  \"吉\",\n  \"包\"\n];\n\n},{}],1007:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"沙市\",\n  \"京市\",\n  \"宁市\",\n  \"安市\",\n  \"乡县\",\n  \"海市\",\n  \"码市\",\n  \"汉市\",\n  \"阳市\",\n  \"都市\",\n  \"州市\",\n  \"门市\",\n  \"阳市\",\n  \"口市\",\n  \"原市\",\n  \"南市\",\n  \"徽市\",\n  \"林市\",\n  \"头市\"\n];\n\n},{}],1008:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"中国\"\n];\n\n},{}],1009:[function(require,module,exports){\nvar address = {};\nmodule['exports'] = address;\naddress.city_prefix = require(\"./city_prefix\");\naddress.city_suffix = require(\"./city_suffix\");\naddress.building_number = require(\"./building_number\");\naddress.street_suffix = require(\"./street_suffix\");\naddress.postcode = require(\"./postcode\");\naddress.state = require(\"./state\");\naddress.state_abbr = require(\"./state_abbr\");\naddress.city = require(\"./city\");\naddress.street_name = require(\"./street_name\");\naddress.street_address = require(\"./street_address\");\naddress.default_country = require(\"./default_country\");\n\n},{\"./building_number\":1004,\"./city\":1005,\"./city_prefix\":1006,\"./city_suffix\":1007,\"./default_country\":1008,\"./postcode\":1010,\"./state\":1011,\"./state_abbr\":1012,\"./street_address\":1013,\"./street_name\":1014,\"./street_suffix\":1015}],1010:[function(require,module,exports){\nmodule.exports=require(802)\n},{\"/Users/a/dev/faker.js/lib/locales/ru/address/postcode.js\":802}],1011:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"浙江省\",\n  \"江西省\",\n  \"广东省\",\n  \"福建省\",\n  \"台湾省\",\n  \"海南省\",\n  \"香港\",\n  \"澳门\"\n];\n\n},{}],1012:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"浙\",\n  \"赣\",\n  \"粤\",\n  \"闽\",\n  \"台\",\n  \"琼\",\n  \"港\",\n  \"澳\"\n];\n\n},{}],1013:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_name}#{building_number}号\"\n];\n\n},{}],1014:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{Name.last_name}#{street_suffix}\"\n];\n\n},{}],1015:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"巷\",\n  \"街\",\n  \"路\",\n  \"桥\",\n  \"侬\",\n  \"旁\",\n  \"中心\",\n  \"栋\"\n];\n\n},{}],1016:[function(require,module,exports){\nvar zh_CN = {};\nmodule['exports'] = zh_CN;\nzh_CN.title = \"Chinese\";\nzh_CN.address = require(\"./address\");\nzh_CN.name = require(\"./name\");\nzh_CN.phone_number = require(\"./phone_number\");\n\n},{\"./address\":1009,\"./name\":1018,\"./phone_number\":1022}],1017:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"邓\",\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  \"钟\",\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  \"雷\",\n  \"黎\",\n  \"史\",\n  \"龙\",\n  \"陶\",\n  \"贺\",\n  \"顾\",\n  \"毛\",\n  \"郝\",\n  \"龚\",\n  \"邵\",\n  \"万\",\n  \"钱\",\n  \"严\",\n  \"赖\",\n  \"覃\",\n  \"洪\",\n  \"武\",\n  \"莫\",\n  \"孔\"\n];\n\n},{}],1018:[function(require,module,exports){\narguments[4][999][0].apply(exports,arguments)\n},{\"./first_name\":1017,\"./last_name\":1019,\"./name\":1020,\"/Users/a/dev/faker.js/lib/locales/vi/name/index.js\":999}],1019:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"伟祺\",\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  \"鹏涛\",\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  \"正豪\",\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  \"鹭洋\",\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];\n\n},{}],1020:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{first_name}#{last_name}\"\n];\n\n},{}],1021:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"###-########\",\n  \"####-########\",\n  \"###########\"\n];\n\n},{}],1022:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":1021,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],1023:[function(require,module,exports){\nmodule.exports=require(464)\n},{\"/Users/a/dev/faker.js/lib/locales/fr/address/building_number.js\":464}],1024:[function(require,module,exports){\nmodule.exports=require(879)\n},{\"/Users/a/dev/faker.js/lib/locales/sv/address/city.js\":879}],1025:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"臺北\",\n  \"新北\",\n  \"桃園\",\n  \"臺中\",\n  \"臺南\",\n  \"高雄\",\n  \"基隆\",\n  \"新竹\",\n  \"嘉義\",\n  \"苗栗\",\n  \"彰化\",\n  \"南投\",\n  \"雲林\",\n  \"屏東\",\n  \"宜蘭\",\n  \"花蓮\",\n  \"臺東\",\n  \"澎湖\",\n  \"金門\",\n  \"連江\"\n];\n\n},{}],1026:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"縣\",\n  \"市\"\n];\n\n},{}],1027:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"Taiwan (R.O.C.)\"\n];\n\n},{}],1028:[function(require,module,exports){\narguments[4][1009][0].apply(exports,arguments)\n},{\"./building_number\":1023,\"./city\":1024,\"./city_prefix\":1025,\"./city_suffix\":1026,\"./default_country\":1027,\"./postcode\":1029,\"./state\":1030,\"./state_abbr\":1031,\"./street_address\":1032,\"./street_name\":1033,\"./street_suffix\":1034,\"/Users/a/dev/faker.js/lib/locales/zh_CN/address/index.js\":1009}],1029:[function(require,module,exports){\nmodule.exports=require(802)\n},{\"/Users/a/dev/faker.js/lib/locales/ru/address/postcode.js\":802}],1030:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"福建省\",\n  \"台灣省\"\n];\n\n},{}],1031:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"北\",\n  \"新北\",\n  \"桃\",\n  \"中\",\n  \"南\",\n  \"高\",\n  \"基\",\n  \"竹市\",\n  \"嘉市\",\n  \"竹縣\",\n  \"苗\",\n  \"彰\",\n  \"投\",\n  \"雲\",\n  \"嘉縣\",\n  \"宜\",\n  \"花\",\n  \"東\",\n  \"澎\",\n  \"金\",\n  \"馬\"\n];\n\n},{}],1032:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"#{street_name}#{building_number}號\"\n];\n\n},{}],1033:[function(require,module,exports){\nmodule.exports=require(1014)\n},{\"/Users/a/dev/faker.js/lib/locales/zh_CN/address/street_name.js\":1014}],1034:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"街\",\n  \"路\",\n  \"北路\",\n  \"南路\",\n  \"東路\",\n  \"西路\"\n];\n\n},{}],1035:[function(require,module,exports){\nvar zh_TW = {};\nmodule['exports'] = zh_TW;\nzh_TW.title = \"Chinese (Taiwan)\";\nzh_TW.address = require(\"./address\");\nzh_TW.name = require(\"./name\");\nzh_TW.phone_number = require(\"./phone_number\");\n\n},{\"./address\":1028,\"./name\":1037,\"./phone_number\":1041}],1036:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"鄧\",\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  \"鐘\",\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  \"雷\",\n  \"黎\",\n  \"史\",\n  \"龍\",\n  \"陶\",\n  \"賀\",\n  \"顧\",\n  \"毛\",\n  \"郝\",\n  \"龔\",\n  \"邵\",\n  \"萬\",\n  \"錢\",\n  \"嚴\",\n  \"賴\",\n  \"覃\",\n  \"洪\",\n  \"武\",\n  \"莫\",\n  \"孔\"\n];\n\n},{}],1037:[function(require,module,exports){\narguments[4][999][0].apply(exports,arguments)\n},{\"./first_name\":1036,\"./last_name\":1038,\"./name\":1039,\"/Users/a/dev/faker.js/lib/locales/vi/name/index.js\":999}],1038:[function(require,module,exports){\nmodule[\"exports\"] = [\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  \"偉祺\",\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  \"鵬濤\",\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  \"正豪\",\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  \"鷺洋\",\n  \"振家\",\n  \"樂駒\",\n  \"曉博\",\n  \"文博\",\n  \"昊焱\",\n  \"立果\",\n  \"金鑫\",\n  \"錦程\",\n  \"嘉熙\",\n  \"鵬飛\",\n  \"子默\",\n  \"思遠\",\n  \"浩軒\",\n  \"語堂\",\n  \"聰健\"\n];\n\n},{}],1039:[function(require,module,exports){\nmodule.exports=require(1020)\n},{\"/Users/a/dev/faker.js/lib/locales/zh_CN/name/name.js\":1020}],1040:[function(require,module,exports){\nmodule[\"exports\"] = [\n  \"0#-#######\",\n  \"02-########\",\n  \"09##-######\"\n];\n\n},{}],1041:[function(require,module,exports){\narguments[4][53][0].apply(exports,arguments)\n},{\"./formats\":1040,\"/Users/a/dev/faker.js/lib/locales/az/phone_number/index.js\":53}],1042:[function(require,module,exports){\n\n/**\n *\n * @namespace faker.lorem\n */\nvar Lorem = function (faker) {\n  var self = this;\n  var Helpers = faker.helpers;\n\n  /**\n   * word\n   *\n   * @method faker.lorem.word\n   * @param {number} num\n   */\n  self.word = function (num) {\n    return faker.random.arrayElement(faker.definitions.lorem.words);\n  };\n\n  /**\n   * generates a space separated list of words\n   *\n   * @method faker.lorem.words\n   * @param {number} num number of words, defaults to 3\n   */\n  self.words = function (num) {\n      if (typeof num == 'undefined') { num = 3; }\n      var words = [];\n      for (var i = 0; i < num; i++) {\n        words.push(faker.lorem.word());\n      }\n      return words.join(' ');\n  };\n\n  /**\n   * sentence\n   *\n   * @method faker.lorem.sentence\n   * @param {number} wordCount defaults to a random number between 3 and 10\n   * @param {number} range\n   */\n  self.sentence = function (wordCount, range) {\n      if (typeof wordCount == 'undefined') { wordCount = faker.random.number({ min: 3, max: 10 }); }\n      // if (typeof range == 'undefined') { range = 7; }\n\n      // strange issue with the node_min_test failing for captialize, please fix and add faker.lorem.back\n      //return  faker.lorem.words(wordCount + Helpers.randomNumber(range)).join(' ').capitalize();\n\n      var sentence = faker.lorem.words(wordCount);\n      return sentence.charAt(0).toUpperCase() + sentence.slice(1) + '.';\n  };\n\n  /**\n   * slug\n   *\n   * @method faker.lorem.slug\n   * @param {number} wordCount number of words, defaults to 3\n   */\n  self.slug = function (wordCount) {\n      var words = faker.lorem.words(wordCount);\n      return Helpers.slugify(words);\n  };\n\n  /**\n   * sentences\n   *\n   * @method faker.lorem.sentences\n   * @param {number} sentenceCount defautls to a random number between 2 and 6\n   * @param {string} separator defaults to `' '`\n   */\n  self.sentences = function (sentenceCount, separator) {\n      if (typeof sentenceCount === 'undefined') { sentenceCount = faker.random.number({ min: 2, max: 6 });}\n      if (typeof separator == 'undefined') { separator = \" \"; }\n      var sentences = [];\n      for (sentenceCount; sentenceCount > 0; sentenceCount--) {\n        sentences.push(faker.lorem.sentence());\n      }\n      return sentences.join(separator);\n  };\n\n  /**\n   * paragraph\n   *\n   * @method faker.lorem.paragraph\n   * @param {number} sentenceCount defaults to 3\n   */\n  self.paragraph = function (sentenceCount) {\n      if (typeof sentenceCount == 'undefined') { sentenceCount = 3; }\n      return faker.lorem.sentences(sentenceCount + faker.random.number(3));\n  };\n\n  /**\n   * paragraphs\n   *\n   * @method faker.lorem.paragraphs\n   * @param {number} paragraphCount defaults to 3\n   * @param {string} separator defaults to `'\\n \\r'`\n   */\n  self.paragraphs = function (paragraphCount, separator) {\n    if (typeof separator === \"undefined\") {\n      separator = \"\\n \\r\";\n    }\n    if (typeof paragraphCount == 'undefined') { paragraphCount = 3; }\n    var paragraphs = [];\n    for (paragraphCount; paragraphCount > 0; paragraphCount--) {\n        paragraphs.push(faker.lorem.paragraph());\n    }\n    return paragraphs.join(separator);\n  }\n\n  /**\n   * returns random text based on a random lorem method\n   *\n   * @method faker.lorem.text\n   * @param {number} times\n   */\n  self.text = function loremText (times) {\n    var loremMethods = ['lorem.word', 'lorem.words', 'lorem.sentence', 'lorem.sentences', 'lorem.paragraph', 'lorem.paragraphs', 'lorem.lines'];\n    var randomLoremMethod = faker.random.arrayElement(loremMethods);\n    return faker.fake('{{' + randomLoremMethod + '}}');\n  };\n\n  /**\n   * returns lines of lorem separated by `'\\n'`\n   *\n   * @method faker.lorem.lines\n   * @param {number} lineCount defaults to a random number between 1 and 5\n   */\n  self.lines = function lines (lineCount) {\n    if (typeof lineCount === 'undefined') { lineCount = faker.random.number({ min: 1, max: 5 });}\n    return faker.lorem.sentences(lineCount, '\\n')\n  };\n\n  return self;\n};\n\n\nmodule[\"exports\"] = Lorem;\n\n},{}],1043:[function(require,module,exports){\n/**\n *\n * @namespace faker.name\n */\nfunction Name (faker) {\n\n  /**\n   * firstName\n   *\n   * @method firstName\n   * @param {mixed} gender\n   * @memberof faker.name\n   */\n  this.firstName = function (gender) {\n    if (typeof faker.definitions.name.male_first_name !== \"undefined\" && typeof faker.definitions.name.female_first_name !== \"undefined\") {\n      // some locale datasets ( like ru ) have first_name split by gender. since the name.first_name field does not exist in these datasets,\n      // we must randomly pick a name from either gender array so faker.name.firstName will return the correct locale data ( and not fallback )\n      if (typeof gender !== 'number') {\n        gender = faker.random.number(1);\n      }\n      if (gender === 0) {\n        return faker.random.arrayElement(faker.locales[faker.locale].name.male_first_name)\n      } else {\n        return faker.random.arrayElement(faker.locales[faker.locale].name.female_first_name);\n      }\n    }\n    return faker.random.arrayElement(faker.definitions.name.first_name);\n  };\n\n  /**\n   * lastName\n   *\n   * @method lastName\n   * @param {mixed} gender\n   * @memberof faker.name\n   */\n  this.lastName = function (gender) {\n    if (typeof faker.definitions.name.male_last_name !== \"undefined\" && typeof faker.definitions.name.female_last_name !== \"undefined\") {\n      // some locale datasets ( like ru ) have last_name split by gender. i have no idea how last names can have genders, but also i do not speak russian\n      // see above comment of firstName method\n      if (typeof gender !== 'number') {\n        gender = faker.random.number(1);\n      }\n      if (gender === 0) {\n        return faker.random.arrayElement(faker.locales[faker.locale].name.male_last_name);\n      } else {\n        return faker.random.arrayElement(faker.locales[faker.locale].name.female_last_name);\n      }\n    }\n    return faker.random.arrayElement(faker.definitions.name.last_name);\n  };\n\n  /**\n   * findName\n   *\n   * @method findName\n   * @param {string} firstName\n   * @param {string} lastName\n   * @param {mixed} gender\n   * @memberof faker.name\n   */\n  this.findName = function (firstName, lastName, gender) {\n      var r = faker.random.number(8);\n      var prefix, suffix;\n      // in particular locales first and last names split by gender,\n      // thus we keep consistency by passing 0 as male and 1 as female\n      if (typeof gender !== 'number') {\n        gender = faker.random.number(1);\n      }\n      firstName = firstName || faker.name.firstName(gender);\n      lastName = lastName || faker.name.lastName(gender);\n      switch (r) {\n      case 0:\n          prefix = faker.name.prefix(gender);\n          if (prefix) {\n              return prefix + \" \" + firstName + \" \" + lastName;\n          }\n      case 1:\n          suffix = faker.name.suffix(gender);\n          if (suffix) {\n              return firstName + \" \" + lastName + \" \" + suffix;\n          }\n      }\n\n      return firstName + \" \" + lastName;\n  };\n\n  /**\n   * jobTitle\n   *\n   * @method jobTitle\n   * @memberof faker.name\n   */\n  this.jobTitle = function () {\n    return  faker.name.jobDescriptor() + \" \" +\n      faker.name.jobArea() + \" \" +\n      faker.name.jobType();\n  };\n  \n  /**\n   * prefix\n   *\n   * @method prefix\n   * @param {mixed} gender\n   * @memberof faker.name\n   */\n  this.prefix = function (gender) {\n    if (typeof faker.definitions.name.male_prefix !== \"undefined\" && typeof faker.definitions.name.female_prefix !== \"undefined\") {\n      if (typeof gender !== 'number') {\n        gender = faker.random.number(1);\n      }\n      if (gender === 0) {\n        return faker.random.arrayElement(faker.locales[faker.locale].name.male_prefix);\n      } else {\n        return faker.random.arrayElement(faker.locales[faker.locale].name.female_prefix);\n      }\n    }\n    return faker.random.arrayElement(faker.definitions.name.prefix);\n  };\n\n  /**\n   * suffix\n   *\n   * @method suffix\n   * @memberof faker.name\n   */\n  this.suffix = function () {\n      return faker.random.arrayElement(faker.definitions.name.suffix);\n  };\n\n  /**\n   * title\n   *\n   * @method title\n   * @memberof faker.name\n   */\n  this.title = function() {\n      var descriptor  = faker.random.arrayElement(faker.definitions.name.title.descriptor),\n          level       = faker.random.arrayElement(faker.definitions.name.title.level),\n          job         = faker.random.arrayElement(faker.definitions.name.title.job);\n\n      return descriptor + \" \" + level + \" \" + job;\n  };\n\n  /**\n   * jobDescriptor\n   *\n   * @method jobDescriptor\n   * @memberof faker.name\n   */\n  this.jobDescriptor = function () {\n    return faker.random.arrayElement(faker.definitions.name.title.descriptor);\n  };\n\n  /**\n   * jobArea\n   *\n   * @method jobArea\n   * @memberof faker.name\n   */\n  this.jobArea = function () {\n    return faker.random.arrayElement(faker.definitions.name.title.level);\n  };\n\n  /**\n   * jobType\n   *\n   * @method jobType\n   * @memberof faker.name\n   */\n  this.jobType = function () {\n    return faker.random.arrayElement(faker.definitions.name.title.job);\n  };\n\n}\n\nmodule['exports'] = Name;\n\n},{}],1044:[function(require,module,exports){\n/**\n *\n * @namespace faker.phone\n */\nvar Phone = function (faker) {\n  var self = this;\n\n  /**\n   * phoneNumber\n   *\n   * @method faker.phone.phoneNumber\n   * @param {string} format\n   */\n  self.phoneNumber = function (format) {\n      format = format || faker.phone.phoneFormats();\n      return faker.helpers.replaceSymbolWithNumber(format);\n  };\n\n  // FIXME: this is strange passing in an array index.\n  /**\n   * phoneNumberFormat\n   *\n   * @method faker.phone.phoneFormatsArrayIndex\n   * @param phoneFormatsArrayIndex\n   */\n  self.phoneNumberFormat = function (phoneFormatsArrayIndex) {\n      phoneFormatsArrayIndex = phoneFormatsArrayIndex || 0;\n      return faker.helpers.replaceSymbolWithNumber(faker.definitions.phone_number.formats[phoneFormatsArrayIndex]);\n  };\n\n  /**\n   * phoneFormats\n   *\n   * @method faker.phone.phoneFormats\n   */\n  self.phoneFormats = function () {\n    return faker.random.arrayElement(faker.definitions.phone_number.formats);\n  };\n  \n  return self;\n\n};\n\nmodule['exports'] = Phone;\n},{}],1045:[function(require,module,exports){\nvar mersenne = require('../vendor/mersenne');\n\n/**\n *\n * @namespace faker.random\n */\nfunction Random (faker, seed) {\n  // Use a user provided seed if it exists\n  if (seed) {\n    if (Array.isArray(seed) && seed.length) {\n      mersenne.seed_array(seed);\n    }\n    else {\n      mersenne.seed(seed);\n    }\n  }\n  /**\n   * returns a single random number based on a max number or range\n   *\n   * @method faker.random.number\n   * @param {mixed} options\n   */\n  this.number = function (options) {\n\n    if (typeof options === \"number\") {\n      options = {\n        max: options\n      };\n    }\n\n    options = options || {};\n\n    if (typeof options.min === \"undefined\") {\n      options.min = 0;\n    }\n\n    if (typeof options.max === \"undefined\") {\n      options.max = 99999;\n    }\n    if (typeof options.precision === \"undefined\") {\n      options.precision = 1;\n    }\n\n    // Make the range inclusive of the max value\n    var max = options.max;\n    if (max >= 0) {\n      max += options.precision;\n    }\n\n    var randomNumber = options.precision * Math.floor(\n      mersenne.rand(max / options.precision, options.min / options.precision));\n\n    return randomNumber;\n\n  }\n\n  /**\n   * takes an array and returns a random element of the array\n   *\n   * @method faker.random.arrayElement\n   * @param {array} array\n   */\n  this.arrayElement = function (array) {\n      array = array || [\"a\", \"b\", \"c\"];\n      var r = faker.random.number({ max: array.length - 1 });\n      return array[r];\n  }\n\n  /**\n   * takes an object and returns the randomly key or value\n   *\n   * @method faker.random.objectElement\n   * @param {object} object\n   * @param {mixed} field\n   */\n  this.objectElement = function (object, field) {\n      object = object || { \"foo\": \"bar\", \"too\": \"car\" };\n      var array = Object.keys(object);\n      var key = faker.random.arrayElement(array);\n\n      return field === \"key\" ? key : object[key];\n  }\n\n  /**\n   * uuid\n   *\n   * @method faker.random.uuid\n   */\n  this.uuid = function () {\n      var self = this;\n      var RFC4122_TEMPLATE = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';\n      var replacePlaceholders = function (placeholder) {\n          var random = self.number({ min: 0, max: 15 });\n          var value = placeholder == 'x' ? random : (random &0x3 | 0x8);\n          return value.toString(16);\n      };\n      return RFC4122_TEMPLATE.replace(/[xy]/g, replacePlaceholders);\n  }\n\n  /**\n   * boolean\n   *\n   * @method faker.random.boolean\n   */\n  this.boolean = function () {\n      return !!faker.random.number(1)\n  }\n\n  // TODO: have ability to return specific type of word? As in: noun, adjective, verb, etc\n  /**\n   * word\n   *\n   * @method faker.random.word\n   * @param {string} type\n   */\n  this.word = function randomWord (type) {\n\n    var wordMethods = [\n    'commerce.department',\n    'commerce.productName',\n    'commerce.productAdjective',\n    'commerce.productMaterial',\n    'commerce.product',\n    'commerce.color',\n\n    'company.catchPhraseAdjective',\n    'company.catchPhraseDescriptor',\n    'company.catchPhraseNoun',\n    'company.bsAdjective',\n    'company.bsBuzz',\n    'company.bsNoun',\n    'address.streetSuffix',\n    'address.county',\n    'address.country',\n    'address.state',\n\n    'finance.accountName',\n    'finance.transactionType',\n    'finance.currencyName',\n\n    'hacker.noun',\n    'hacker.verb',\n    'hacker.adjective',\n    'hacker.ingverb',\n    'hacker.abbreviation',\n\n    'name.jobDescriptor',\n    'name.jobArea',\n    'name.jobType'];\n\n    // randomly pick from the many faker methods that can generate words\n    var randomWordMethod = faker.random.arrayElement(wordMethods);\n    return faker.fake('{{' + randomWordMethod + '}}');\n\n  }\n\n  /**\n   * randomWords\n   *\n   * @method faker.random.words\n   * @param {number} count defaults to a random value between 1 and 3\n   */\n  this.words = function randomWords (count) {\n    var words = [];\n    if (typeof count === \"undefined\") {\n      count = faker.random.number({min:1, max: 3});\n    }\n    for (var i = 0; i<count; i++) {\n      words.push(faker.random.word());\n    }\n    return words.join(' ');\n  }\n\n  /**\n   * locale\n   *\n   * @method faker.random.image\n   */\n  this.image = function randomImage () {\n    return faker.image.image();\n  }\n\n  /**\n   * locale\n   *\n   * @method faker.random.locale\n   */\n  this.locale = function randomLocale () {\n    return faker.random.arrayElement(Object.keys(faker.locales));\n  };\n\n  /**\n   * alphaNumeric\n   *\n   * @method faker.random.alphaNumeric\n   * @param {number} count defaults to 1\n   */\n  this.alphaNumeric = function alphaNumeric(count) {\n    if (typeof count === \"undefined\") {\n      count = 1;\n    }\n\n    var wholeString = \"\";\n    for(var i = 0; i < count; i++) {\n      wholeString += faker.random.arrayElement([\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"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\"]);\n    }\n\n    return wholeString;\n  };\n\n  return this;\n\n}\n\nmodule['exports'] = Random;\n\n},{\"../vendor/mersenne\":1047}],1046:[function(require,module,exports){\n// generates fake data for many computer systems properties\n\n/**\n *\n * @namespace faker.system\n */\nfunction System (faker) {\n\n  /**\n   * generates a file name with extension or optional type\n   *\n   * @method faker.system.fileName\n   * @param {string} ext\n   * @param {string} type\n   */\n  this.fileName = function (ext, type) {\n    var str = faker.fake(\"{{random.words}}.{{system.fileExt}}\");\n    str = str.replace(/ /g, '_');\n    str = str.replace(/\\,/g, '_');\n    str = str.replace(/\\-/g, '_');\n    str = str.replace(/\\\\/g, '_');\n    str = str.replace(/\\//g, '_');\n    str = str.toLowerCase();\n    return str;\n  };\n\n  /**\n   * commonFileName\n   *\n   * @method faker.system.commonFileName\n   * @param {string} ext\n   * @param {string} type\n   */\n  this.commonFileName = function (ext, type) {\n    var str = faker.random.words() + \".\" + (ext || faker.system.commonFileExt());\n    str = str.replace(/ /g, '_');\n    str = str.replace(/\\,/g, '_');\n    str = str.replace(/\\-/g, '_');\n    str = str.replace(/\\\\/g, '_');\n    str = str.replace(/\\//g, '_');\n    str = str.toLowerCase();\n    return str;\n  };\n\n  /**\n   * mimeType\n   *\n   * @method faker.system.mimeType\n   */\n  this.mimeType = function () {\n    return faker.random.arrayElement(Object.keys(faker.definitions.system.mimeTypes));\n  };\n\n  /**\n   * returns a commonly used file type\n   *\n   * @method faker.system.commonFileType\n   */\n  this.commonFileType = function () {\n    var types = ['video', 'audio', 'image', 'text', 'application'];\n    return faker.random.arrayElement(types)\n  };\n\n  /**\n   * returns a commonly used file extension based on optional type\n   *\n   * @method faker.system.commonFileExt\n   * @param {string} type\n   */\n  this.commonFileExt = function (type) {\n    var types = [\n      'application/pdf',\n      'audio/mpeg',\n      'audio/wav',\n      'image/png',\n      'image/jpeg',\n      'image/gif',\n      'video/mp4',\n      'video/mpeg',\n      'text/html'\n    ];\n    return faker.system.fileExt(faker.random.arrayElement(types));\n  };\n\n\n  /**\n   * returns any file type available as mime-type\n   *\n   * @method faker.system.fileType\n   */\n  this.fileType = function () {\n    var types = [];\n    var mimes = faker.definitions.system.mimeTypes;\n    Object.keys(mimes).forEach(function(m){\n      var parts = m.split('/');\n      if (types.indexOf(parts[0]) === -1) {\n        types.push(parts[0]);\n      }\n    });\n    return faker.random.arrayElement(types);\n  };\n\n  /**\n   * fileExt\n   *\n   * @method faker.system.fileExt\n   * @param {string} mimeType\n   */\n  this.fileExt = function (mimeType) {\n    var exts = [];\n    var mimes = faker.definitions.system.mimeTypes;\n\n    // get specific ext by mime-type\n    if (typeof mimes[mimeType] === \"object\") {\n      return faker.random.arrayElement(mimes[mimeType].extensions);\n    }\n\n    // reduce mime-types to those with file-extensions\n    Object.keys(mimes).forEach(function(m){\n      if (mimes[m].extensions instanceof Array) {\n        mimes[m].extensions.forEach(function(ext){\n          exts.push(ext)\n        });\n      }\n    });\n    return faker.random.arrayElement(exts);\n  };\n\n  /**\n   * not yet implemented\n   *\n   * @method faker.system.directoryPath\n   */\n  this.directoryPath = function () {\n    // TODO\n  };\n\n  /**\n   * not yet implemented\n   *\n   * @method faker.system.filePath\n   */\n  this.filePath = function () {\n    // TODO\n  };\n\n  /**\n   * semver\n   *\n   * @method faker.system.semver\n   */\n  this.semver = function () {\n      return [faker.random.number(9),\n              faker.random.number(9),\n              faker.random.number(9)].join('.');\n  }\n\n}\n\nmodule['exports'] = System;\n\n},{}],1047:[function(require,module,exports){\n// this program is a JavaScript version of Mersenne Twister, with concealment and encapsulation in class,\n// an almost straight conversion from the original program, mt19937ar.c,\n// translated by y. okada on July 17, 2006.\n// and modified a little at july 20, 2006, but there are not any substantial differences.\n// in this program, procedure descriptions and comments of original source code were not removed.\n// lines commented with //c// were originally descriptions of c procedure. and a few following lines are appropriate JavaScript descriptions.\n// lines commented with /* and */ are original comments.\n// lines commented with // are additional comments in this JavaScript version.\n// before using this version, create at least one instance of MersenneTwister19937 class, and initialize the each state, given below in c comments, of all the instances.\n/*\n   A C-program for MT19937, with initialization improved 2002/1/26.\n   Coded by Takuji Nishimura and Makoto Matsumoto.\n\n   Before using, initialize the state by using init_genrand(seed)\n   or init_by_array(init_key, key_length).\n\n   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,\n   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\n   are met:\n\n     1. Redistributions of source code must retain the above copyright\n        notice, this list of conditions and the following disclaimer.\n\n     2. Redistributions in binary form must reproduce the above copyright\n        notice, this list of conditions and the following disclaimer in the\n        documentation and/or other materials provided with the distribution.\n\n     3. The names of its contributors may not be used to endorse or promote\n        products derived from this software without specific prior written\n        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 OWNER OR\n   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n\n   Any feedback is very welcome.\n   http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html\n   email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)\n*/\n\nfunction MersenneTwister19937()\n{\n\t/* constants should be scoped inside the class */\n\tvar N, M, MATRIX_A, UPPER_MASK, LOWER_MASK;\n\t/* Period parameters */\n\t//c//#define N 624\n\t//c//#define M 397\n\t//c//#define MATRIX_A 0x9908b0dfUL   /* constant vector a */\n\t//c//#define UPPER_MASK 0x80000000UL /* most significant w-r bits */\n\t//c//#define LOWER_MASK 0x7fffffffUL /* least significant r bits */\n\tN = 624;\n\tM = 397;\n\tMATRIX_A = 0x9908b0df;   /* constant vector a */\n\tUPPER_MASK = 0x80000000; /* most significant w-r bits */\n\tLOWER_MASK = 0x7fffffff; /* least significant r bits */\n\t//c//static unsigned long mt[N]; /* the array for the state vector  */\n\t//c//static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */\n\tvar mt = new Array(N);   /* the array for the state vector  */\n\tvar mti = N+1;           /* mti==N+1 means mt[N] is not initialized */\n\n\tfunction unsigned32 (n1) // returns a 32-bits unsiged integer from an operand to which applied a bit operator.\n\t{\n\t\treturn n1 < 0 ? (n1 ^ UPPER_MASK) + UPPER_MASK : n1;\n\t}\n\n\tfunction subtraction32 (n1, n2) // emulates lowerflow of a c 32-bits unsiged integer variable, instead of the operator -. these both arguments must be non-negative integers expressible using unsigned 32 bits.\n\t{\n\t\treturn n1 < n2 ? unsigned32((0x100000000 - (n2 - n1)) & 0xffffffff) : n1 - n2;\n\t}\n\n\tfunction addition32 (n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator +. these both arguments must be non-negative integers expressible using unsigned 32 bits.\n\t{\n\t\treturn unsigned32((n1 + n2) & 0xffffffff)\n\t}\n\n\tfunction multiplication32 (n1, n2) // emulates overflow of a c 32-bits unsiged integer variable, instead of the operator *. these both arguments must be non-negative integers expressible using unsigned 32 bits.\n\t{\n\t\tvar sum = 0;\n\t\tfor (var i = 0; i < 32; ++i){\n\t\t\tif ((n1 >>> i) & 0x1){\n\t\t\t\tsum = addition32(sum, unsigned32(n2 << i));\n\t\t\t}\n\t\t}\n\t\treturn sum;\n\t}\n\n\t/* initializes mt[N] with a seed */\n\t//c//void init_genrand(unsigned long s)\n\tthis.init_genrand = function (s)\n\t{\n\t\t//c//mt[0]= s & 0xffffffff;\n\t\tmt[0]= unsigned32(s & 0xffffffff);\n\t\tfor (mti=1; mti<N; mti++) {\n\t\t\tmt[mti] =\n\t\t\t//c//(1812433253 * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);\n\t\t\taddition32(multiplication32(1812433253, unsigned32(mt[mti-1] ^ (mt[mti-1] >>> 30))), mti);\n\t\t\t/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */\n\t\t\t/* In the previous versions, MSBs of the seed affect   */\n\t\t\t/* only MSBs of the array mt[].                        */\n\t\t\t/* 2002/01/09 modified by Makoto Matsumoto             */\n\t\t\t//c//mt[mti] &= 0xffffffff;\n\t\t\tmt[mti] = unsigned32(mt[mti] & 0xffffffff);\n\t\t\t/* for >32 bit machines */\n\t\t}\n\t}\n\n\t/* initialize by an array with array-length */\n\t/* init_key is the array for initializing keys */\n\t/* key_length is its length */\n\t/* slight change for C++, 2004/2/26 */\n\t//c//void init_by_array(unsigned long init_key[], int key_length)\n\tthis.init_by_array = function (init_key, key_length)\n\t{\n\t\t//c//int i, j, k;\n\t\tvar i, j, k;\n\t\t//c//init_genrand(19650218);\n\t\tthis.init_genrand(19650218);\n\t\ti=1; j=0;\n\t\tk = (N>key_length ? N : key_length);\n\t\tfor (; k; k--) {\n\t\t\t//c//mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525))\n\t\t\t//c//\t+ init_key[j] + j; /* non linear */\n\t\t\tmt[i] = addition32(addition32(unsigned32(mt[i] ^ multiplication32(unsigned32(mt[i-1] ^ (mt[i-1] >>> 30)), 1664525)), init_key[j]), j);\n\t\t\tmt[i] =\n\t\t\t//c//mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */\n\t\t\tunsigned32(mt[i] & 0xffffffff);\n\t\t\ti++; j++;\n\t\t\tif (i>=N) { mt[0] = mt[N-1]; i=1; }\n\t\t\tif (j>=key_length) j=0;\n\t\t}\n\t\tfor (k=N-1; k; k--) {\n\t\t\t//c//mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941))\n\t\t\t//c//- i; /* non linear */\n\t\t\tmt[i] = subtraction32(unsigned32((dbg=mt[i]) ^ multiplication32(unsigned32(mt[i-1] ^ (mt[i-1] >>> 30)), 1566083941)), i);\n\t\t\t//c//mt[i] &= 0xffffffff; /* for WORDSIZE > 32 machines */\n\t\t\tmt[i] = unsigned32(mt[i] & 0xffffffff);\n\t\t\ti++;\n\t\t\tif (i>=N) { mt[0] = mt[N-1]; i=1; }\n\t\t}\n\t\tmt[0] = 0x80000000; /* MSB is 1; assuring non-zero initial array */\n\t}\n\n    /* moved outside of genrand_int32() by jwatte 2010-11-17; generate less garbage */\n    var mag01 = [0x0, MATRIX_A];\n\n\t/* generates a random number on [0,0xffffffff]-interval */\n\t//c//unsigned long genrand_int32(void)\n\tthis.genrand_int32 = function ()\n\t{\n\t\t//c//unsigned long y;\n\t\t//c//static unsigned long mag01[2]={0x0UL, MATRIX_A};\n\t\tvar y;\n\t\t/* mag01[x] = x * MATRIX_A  for x=0,1 */\n\n\t\tif (mti >= N) { /* generate N words at one time */\n\t\t\t//c//int kk;\n\t\t\tvar kk;\n\n\t\t\tif (mti == N+1)   /* if init_genrand() has not been called, */\n\t\t\t\t//c//init_genrand(5489); /* a default initial seed is used */\n\t\t\t\tthis.init_genrand(5489); /* a default initial seed is used */\n\n\t\t\tfor (kk=0;kk<N-M;kk++) {\n\t\t\t\t//c//y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);\n\t\t\t\t//c//mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];\n\t\t\t\ty = unsigned32((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));\n\t\t\t\tmt[kk] = unsigned32(mt[kk+M] ^ (y >>> 1) ^ mag01[y & 0x1]);\n\t\t\t}\n\t\t\tfor (;kk<N-1;kk++) {\n\t\t\t\t//c//y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);\n\t\t\t\t//c//mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];\n\t\t\t\ty = unsigned32((mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK));\n\t\t\t\tmt[kk] = unsigned32(mt[kk+(M-N)] ^ (y >>> 1) ^ mag01[y & 0x1]);\n\t\t\t}\n\t\t\t//c//y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK);\n\t\t\t//c//mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];\n\t\t\ty = unsigned32((mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK));\n\t\t\tmt[N-1] = unsigned32(mt[M-1] ^ (y >>> 1) ^ mag01[y & 0x1]);\n\t\t\tmti = 0;\n\t\t}\n\n\t\ty = mt[mti++];\n\n\t\t/* Tempering */\n\t\t//c//y ^= (y >> 11);\n\t\t//c//y ^= (y << 7) & 0x9d2c5680;\n\t\t//c//y ^= (y << 15) & 0xefc60000;\n\t\t//c//y ^= (y >> 18);\n\t\ty = unsigned32(y ^ (y >>> 11));\n\t\ty = unsigned32(y ^ ((y << 7) & 0x9d2c5680));\n\t\ty = unsigned32(y ^ ((y << 15) & 0xefc60000));\n\t\ty = unsigned32(y ^ (y >>> 18));\n\n\t\treturn y;\n\t}\n\n\t/* generates a random number on [0,0x7fffffff]-interval */\n\t//c//long genrand_int31(void)\n\tthis.genrand_int31 = function ()\n\t{\n\t\t//c//return (genrand_int32()>>1);\n\t\treturn (this.genrand_int32()>>>1);\n\t}\n\n\t/* generates a random number on [0,1]-real-interval */\n\t//c//double genrand_real1(void)\n\tthis.genrand_real1 = function ()\n\t{\n\t\t//c//return genrand_int32()*(1.0/4294967295.0);\n\t\treturn this.genrand_int32()*(1.0/4294967295.0);\n\t\t/* divided by 2^32-1 */\n\t}\n\n\t/* generates a random number on [0,1)-real-interval */\n\t//c//double genrand_real2(void)\n\tthis.genrand_real2 = function ()\n\t{\n\t\t//c//return genrand_int32()*(1.0/4294967296.0);\n\t\treturn this.genrand_int32()*(1.0/4294967296.0);\n\t\t/* divided by 2^32 */\n\t}\n\n\t/* generates a random number on (0,1)-real-interval */\n\t//c//double genrand_real3(void)\n\tthis.genrand_real3 = function ()\n\t{\n\t\t//c//return ((genrand_int32()) + 0.5)*(1.0/4294967296.0);\n\t\treturn ((this.genrand_int32()) + 0.5)*(1.0/4294967296.0);\n\t\t/* divided by 2^32 */\n\t}\n\n\t/* generates a random number on [0,1) with 53-bit resolution*/\n\t//c//double genrand_res53(void)\n\tthis.genrand_res53 = function ()\n\t{\n\t\t//c//unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;\n\t\tvar a=this.genrand_int32()>>>5, b=this.genrand_int32()>>>6;\n\t\treturn(a*67108864.0+b)*(1.0/9007199254740992.0);\n\t}\n\t/* These real versions are due to Isaku Wada, 2002/01/09 added */\n}\n\n//  Exports: Public API\n\n//  Export the twister class\nexports.MersenneTwister19937 = MersenneTwister19937;\n\n//  Export a simplified function to generate random numbers\nvar gen = new MersenneTwister19937;\ngen.init_genrand((new Date).getTime() % 1000000000);\n\n// Added max, min range functionality, Marak Squires Sept 11 2014\nexports.rand = function(max, min) {\n    if (max === undefined)\n        {\n        min = 0;\n        max = 32768;\n        }\n    return Math.floor(gen.genrand_real2() * (max - min) + min);\n}\nexports.seed = function(S) {\n    if (typeof(S) != 'number')\n        {\n        throw new Error(\"seed(S) must take numeric argument; is \" + typeof(S));\n        }\n    gen.init_genrand(S);\n}\nexports.seed_array = function(A) {\n    if (typeof(A) != 'object')\n        {\n        throw new Error(\"seed_array(A) must take array of numbers; is \" + typeof(A));\n        }\n    gen.init_by_array(A);\n}\n\n},{}],1048:[function(require,module,exports){\n/*\n\nCopyright (c) 2012-2014 Jeffrey Mealo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and\nto permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the\nSoftware.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n------------------------------------------------------------------------------------------------------------------------\n\nBased loosely on Luka Pusic's PHP Script: http://360percents.com/posts/php-random-user-agent-generator/\n\nThe license for that script is as follows:\n\n\"THE BEER-WARE LICENSE\" (Revision 42):\n\n<pusic93@gmail.com> wrote this file. As long as you retain this notice you can do whatever you want with this stuff.\nIf we meet some day, and you think this stuff is worth it, you can buy me a beer in return. Luka Pusic\n*/\n\nfunction rnd(a, b) {\n    //calling rnd() with no arguments is identical to rnd(0, 100)\n    a = a || 0;\n    b = b || 100;\n\n    if (typeof b === 'number' && typeof a === 'number') {\n        //rnd(int min, int max) returns integer between min, max\n        return (function (min, max) {\n            if (min > max) {\n                throw new RangeError('expected min <= max; got min = ' + min + ', max = ' + max);\n            }\n            return Math.floor(Math.random() * (max - min + 1)) + min;\n        }(a, b));\n    }\n\n    if (Object.prototype.toString.call(a) === \"[object Array]\") {\n        //returns a random element from array (a), even weighting\n        return a[Math.floor(Math.random() * a.length)];\n    }\n\n    if (a && typeof a === 'object') {\n        //returns a random key from the passed object; keys are weighted by the decimal probability in their value\n        return (function (obj) {\n            var rand = rnd(0, 100) / 100, min = 0, max = 0, key, return_val;\n\n            for (key in obj) {\n                if (obj.hasOwnProperty(key)) {\n                    max = obj[key] + min;\n                    return_val = key;\n                    if (rand >= min && rand <= max) {\n                        break;\n                    }\n                    min = min + obj[key];\n                }\n            }\n\n            return return_val;\n        }(a));\n    }\n\n    throw new TypeError('Invalid arguments passed to rnd. (' + (b ? a + ', ' + b : a) + ')');\n}\n\nfunction randomLang() {\n    return rnd(['AB', 'AF', 'AN', 'AR', 'AS', 'AZ', 'BE', 'BG', 'BN', 'BO', 'BR', 'BS', 'CA', 'CE', 'CO', 'CS',\n                'CU', 'CY', 'DA', 'DE', 'EL', 'EN', 'EO', 'ES', 'ET', 'EU', 'FA', 'FI', 'FJ', 'FO', 'FR', 'FY',\n                'GA', 'GD', 'GL', 'GV', 'HE', 'HI', 'HR', 'HT', 'HU', 'HY', 'ID', 'IS', 'IT', 'JA', 'JV', 'KA',\n                'KG', 'KO', 'KU', 'KW', 'KY', 'LA', 'LB', 'LI', 'LN', 'LT', 'LV', 'MG', 'MK', 'MN', 'MO', 'MS',\n                'MT', 'MY', 'NB', 'NE', 'NL', 'NN', 'NO', 'OC', 'PL', 'PT', 'RM', 'RO', 'RU', 'SC', 'SE', 'SK',\n                'SL', 'SO', 'SQ', 'SR', 'SV', 'SW', 'TK', 'TR', 'TY', 'UK', 'UR', 'UZ', 'VI', 'VO', 'YI', 'ZH']);\n}\n\nfunction randomBrowserAndOS() {\n    var browser = rnd({\n        chrome:    .45132810566,\n        iexplorer: .27477061836,\n        firefox:   .19384170608,\n        safari:    .06186781118,\n        opera:     .01574236955\n    }),\n    os = {\n        chrome:  {win: .89,  mac: .09 , lin: .02},\n        firefox: {win: .83,  mac: .16,  lin: .01},\n        opera:   {win: .91,  mac: .03 , lin: .06},\n        safari:  {win: .04 , mac: .96  },\n        iexplorer: ['win']\n    };\n\n    return [browser, rnd(os[browser])];\n}\n\nfunction randomProc(arch) {\n    var procs = {\n        lin:['i686', 'x86_64'],\n        mac: {'Intel' : .48, 'PPC': .01, 'U; Intel':.48, 'U; PPC' :.01},\n        win:['', 'WOW64', 'Win64; x64']\n    };\n    return rnd(procs[arch]);\n}\n\nfunction randomRevision(dots) {\n    var return_val = '';\n    //generate a random revision\n    //dots = 2 returns .x.y where x & y are between 0 and 9\n    for (var x = 0; x < dots; x++) {\n        return_val += '.' + rnd(0, 9);\n    }\n    return return_val;\n}\n\nvar version_string = {\n    net: function () {\n        return [rnd(1, 4), rnd(0, 9), rnd(10000, 99999), rnd(0, 9)].join('.');\n    },\n    nt: function () {\n        return rnd(5, 6) + '.' + rnd(0, 3);\n    },\n    ie: function () {\n        return rnd(7, 11);\n    },\n    trident: function () {\n        return rnd(3, 7) + '.' + rnd(0, 1);\n    },\n    osx: function (delim) {\n        return [10, rnd(5, 10), rnd(0, 9)].join(delim || '.');\n    },\n    chrome: function () {\n        return [rnd(13, 39), 0, rnd(800, 899), 0].join('.');\n    },\n    presto: function () {\n        return '2.9.' + rnd(160, 190);\n    },\n    presto2: function () {\n        return rnd(10, 12) + '.00';\n    },\n    safari: function () {\n        return rnd(531, 538) + '.' + rnd(0, 2) + '.' + rnd(0,2);\n    }\n};\n\nvar browser = {\n    firefox: function firefox(arch) {\n        //https://developer.mozilla.org/en-US/docs/Gecko_user_agent_string_reference\n        var firefox_ver = rnd(5, 15) + randomRevision(2),\n            gecko_ver = 'Gecko/20100101 Firefox/' + firefox_ver,\n            proc = randomProc(arch),\n            os_ver = (arch === 'win') ? '(Windows NT ' + version_string.nt() + ((proc) ? '; ' + proc : '')\n            : (arch === 'mac') ? '(Macintosh; ' + proc + ' Mac OS X ' + version_string.osx()\n            : '(X11; Linux ' + proc;\n\n        return 'Mozilla/5.0 ' + os_ver + '; rv:' + firefox_ver.slice(0, -2) + ') ' + gecko_ver;\n    },\n\n    iexplorer: function iexplorer() {\n        var ver = version_string.ie();\n\n        if (ver >= 11) {\n            //http://msdn.microsoft.com/en-us/library/ie/hh869301(v=vs.85).aspx\n            return 'Mozilla/5.0 (Windows NT 6.' + rnd(1,3) + '; Trident/7.0; ' + rnd(['Touch; ', '']) + 'rv:11.0) like Gecko';\n        }\n\n        //http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx\n        return 'Mozilla/5.0 (compatible; MSIE ' + ver + '.0; Windows NT ' + version_string.nt() + '; Trident/' +\n            version_string.trident() + ((rnd(0, 1) === 1) ? '; .NET CLR ' + version_string.net() : '') + ')';\n    },\n\n    opera: function opera(arch) {\n        //http://www.opera.com/docs/history/\n        var presto_ver = ' Presto/' + version_string.presto() + ' Version/' + version_string.presto2() + ')',\n            os_ver = (arch === 'win') ? '(Windows NT ' + version_string.nt() + '; U; ' + randomLang() + presto_ver\n            : (arch === 'lin') ? '(X11; Linux ' + randomProc(arch) + '; U; ' + randomLang() + presto_ver\n            : '(Macintosh; Intel Mac OS X ' + version_string.osx() + ' U; ' + randomLang() + ' Presto/' +\n            version_string.presto() + ' Version/' + version_string.presto2() + ')';\n\n        return 'Opera/' + rnd(9, 14) + '.' + rnd(0, 99) + ' ' + os_ver;\n    },\n\n    safari: function safari(arch) {\n        var safari = version_string.safari(),\n            ver = rnd(4, 7) + '.' + rnd(0,1) + '.' + rnd(0,10),\n            os_ver = (arch === 'mac') ? '(Macintosh; ' + randomProc('mac') + ' Mac OS X '+ version_string.osx('_') + ' rv:' + rnd(2, 6) + '.0; '+ randomLang() + ') '\n            : '(Windows; U; Windows NT ' + version_string.nt() + ')';\n\n        return 'Mozilla/5.0 ' + os_ver + 'AppleWebKit/' + safari + ' (KHTML, like Gecko) Version/' + ver + ' Safari/' + safari;\n    },\n\n    chrome: function chrome(arch) {\n        var safari = version_string.safari(),\n            os_ver = (arch === 'mac') ? '(Macintosh; ' + randomProc('mac') + ' Mac OS X ' + version_string.osx('_') + ') '\n            : (arch === 'win') ? '(Windows; U; Windows NT ' + version_string.nt() + ')'\n            : '(X11; Linux ' + randomProc(arch);\n\n        return 'Mozilla/5.0 ' + os_ver + ' AppleWebKit/' + safari + ' (KHTML, like Gecko) Chrome/' + version_string.chrome() + ' Safari/' + safari;\n    }\n};\n\nexports.generate = function generate() {\n    var random = randomBrowserAndOS();\n    return browser[random[0]](random[1]);\n};\n\n},{}]},{},[1])(1)\n});"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/mockFlushable.ts",
    "content": "export function mockFlushable(waitForFlush?: boolean) {\n  let queueds: (() => void)[] = [];\n  return {\n    handler: (completion: () => void) => {\n      if (waitForFlush) {\n        queueds.push(completion);\n      } else {\n        completion();\n      }\n      return () => {};\n    },\n    flush: () => {\n      for (const queued of queueds) {\n        queued();\n      }\n      queueds = [];\n    },\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/mockFlushableWithData.ts",
    "content": "import { mockFlushable } from './mockFlushable';\n\nexport function mockFlushableWithData<T>(data: T, waitForFlush?: boolean) {\n  const flushable = mockFlushable(waitForFlush);\n  return {\n    handler: (completion: (data: T) => void) => {\n      return flushable.handler(() => {\n        completion(data);\n      });\n    },\n    flush: flushable.flush,\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/mockFlushableWithDataAndError.ts",
    "content": "import { mockFlushable } from './mockFlushable';\n\nexport function mockFlushableWithDataAndError<T>(data: T | undefined, waitForFlush?: boolean) {\n  const flushable = mockFlushable(waitForFlush);\n  return {\n    handler: (completion: (data?: T, error?: any) => void) => {\n      return flushable.handler(() => {\n        if (data === undefined) {\n          completion(undefined, new Error('No Data'));\n        }\n        if (data === null) {\n          completion(undefined, new Error('Invalid Data'));\n        }\n        completion(data);\n      });\n    },\n    flush: flushable.flush,\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/mockObject.ts",
    "content": "export function mockObject<T>(input: Partial<T> = {}): T {\n  return input as T;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/mockObjectWithSpy.ts",
    "content": "export function mockObjectWithSpy<TObject>(object: TObject): TObject {\n  if (spyOn) {\n    for (const propertyKey in object) {\n      const value = object[propertyKey];\n      if (typeof value === 'function') {\n        spyOn<Record<string, any | jasmine.Func>>(\n          object as Record<string, any | jasmine.Func>,\n          propertyKey,\n        ).and.callThrough();\n      }\n    }\n  }\n  return object;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/tapNodeWithKey.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { findNodeWithKey } from './findNodeWithKey';\nimport { getAttributeFromNode } from './getAttributeFromNode';\nimport { isRenderedElement } from './isRenderedElement';\nimport { waitFor } from './waitFor';\n\nconst DEFAULT_TIMEOUT_MS = 3000;\nconst DEFAULT_INTERVAL_MS = 10;\n\nconst rejectIfNotTappable = <T extends IComponent | IRenderedElement>(node: T | undefined): T => {\n  if (!node) {\n    throw new Error('Node not found');\n  }\n  const onTap = getAttributeFromNode(node, 'onTap');\n  const disabled = getAttributeFromNode(node, 'disabled');\n  const accessibilityStateDisabled = getAttributeFromNode(node, 'accessibilityStateDisabled');\n  const onTapDisabled = getAttributeFromNode(node, 'onTapDisabled');\n  const enabled = getAttributeFromNode(node, 'enabled') ?? true;\n  if (disabled || !enabled || onTapDisabled || accessibilityStateDisabled) {\n    throw new Error('Node is disabled');\n  }\n  if (!onTap) {\n    throw new Error('onTap handler is not set');\n  }\n  return node;\n};\n\nconst waitForNodeTappableWithKey = async (\n  node: IComponent | IRenderedElement,\n  key: string,\n  timeoutMs = 3000,\n  intervalMs = 10,\n): Promise<IComponent | IRenderedElement> => {\n  try {\n    return await waitFor(() => rejectIfNotTappable(findNodeWithKey(node, key)[0]), timeoutMs, intervalMs);\n  } catch (e) {\n    throw new Error(\n      `waitForNodeTappableWithKey failed to tap key \"${key}\" in node \"${\n        isRenderedElement(node) ? node.viewClass : node.renderer.contextId\n      }\" after ${timeoutMs}ms. ${e}`,\n    );\n  }\n};\n\nexport const tapNodeWithKey = async (\n  component: IComponent | IRenderedElement,\n  key: string,\n  timeoutMs = DEFAULT_TIMEOUT_MS,\n  intervalMs = DEFAULT_INTERVAL_MS,\n): Promise<void> => {\n  const node = await waitForNodeTappableWithKey(component, key, timeoutMs, intervalMs);\n  const onTap = getAttributeFromNode(node, 'onTap');\n  await onTap?.();\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/typeInTextFieldWithKey.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { wait } from 'valdi_core/src/utils/PromiseUtils';\nimport { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\nimport {\n  EditTextBeginEvent,\n  EditTextEndEvent,\n  EditTextEvent,\n  EditTextUnfocusReason,\n} from 'valdi_tsx/src/NativeTemplateElements';\nimport { elementTypeFind } from './elementTypeFind';\nimport { findNodeWithKey } from './findNodeWithKey';\nimport { getAttributeFromNode } from './getAttributeFromNode';\nimport { isRenderedElement } from './isRenderedElement';\nimport { waitFor } from './waitFor';\n\n/**\n * Execute an action after a short delay, to allow other synchronous actions to complete first.\n */\nconst waitAndRunNextAction = async (action: () => any): Promise<void> => {\n  await wait(1);\n  await action();\n};\n\nconst rejectIfNotTypeable = (node: IRenderedElement[]): IRenderedElement => {\n  if (!node.length) {\n    throw new Error('textfield not found');\n  }\n  if (node.length > 1) {\n    throw new Error('Multiple textfields found');\n  }\n  const textField = node[0];\n  const enaled: boolean | undefined = getAttributeFromNode(textField, 'enaled');\n\n  if (enaled === false) {\n    throw new Error('textfield is disabled');\n  }\n  return textField;\n};\n\nconst waitForTextFieldWithKey = async (\n  node: IComponent | IRenderedElement,\n  key: string,\n  timeoutMs = 3000,\n  intervalMs = 10,\n): Promise<IComponent | IRenderedElement> => {\n  try {\n    return await waitFor(\n      () => rejectIfNotTypeable(elementTypeFind(findNodeWithKey(node, key), IRenderedElementViewClass.TextField)),\n      timeoutMs,\n      intervalMs,\n    );\n  } catch (e) {\n    throw new Error(\n      `waitForTextFieldWithKey failed to type key \"${key}\" in node \"${\n        isRenderedElement(node) ? node.viewClass : node.renderer.contextId\n      }\" after ${timeoutMs}ms. ${e}`,\n    );\n  }\n};\n\ntype TextEventFunc<T, R = void> = ((event: T) => R) | undefined;\n\n/**\n * Type in a text field.\n * @param node The node or parent node contains the textfield to type in.\n * @param key The key of the textfield or parent node.\n * @param value The value to type in.\n * @param append Whether to append the value to the existing text.\n */\nexport const typeInTextFieldWithKey = async (\n  node: IComponent | IRenderedElement,\n  key: string,\n  value: string,\n  append: boolean = false,\n): Promise<void> => {\n  const textField = await waitForTextFieldWithKey(node, key);\n  // We need to get the latest value before emitting each value, because consumers may have special formatting logic\n  const getCurrentValue = () => getAttributeFromNode<string>(textField, 'value') ?? '';\n  let currentValue = '';\n  const onEditBegin: TextEventFunc<EditTextBeginEvent> = getAttributeFromNode(textField, 'onEditBegin');\n  const onEditEnd: TextEventFunc<EditTextEndEvent> = getAttributeFromNode(textField, 'onEditEnd');\n  const onChange: TextEventFunc<EditTextEvent> = getAttributeFromNode(textField, 'onChange');\n  const onWillChange: TextEventFunc<EditTextEvent, EditTextEvent | undefined> = getAttributeFromNode(\n    textField,\n    'onWillChange',\n  );\n\n  // Start editing\n  await waitAndRunNextAction(() => {\n    currentValue = getCurrentValue();\n    onEditBegin?.({\n      text: currentValue,\n      selectionStart: currentValue.length,\n      selectionEnd: currentValue.length,\n    });\n  });\n\n  // Clear the text field if not appending\n  if (!append) {\n    const event = {\n      text: '',\n      selectionStart: 0,\n      selectionEnd: 0,\n    };\n    await waitAndRunNextAction(() => onWillChange?.(event));\n    await waitAndRunNextAction(() => onChange?.(event));\n  }\n\n  // Type in the text field character by character\n  for (const char of value.split('')) {\n    currentValue = getCurrentValue();\n    currentValue += char;\n    const event = {\n      text: currentValue,\n      selectionStart: currentValue.length,\n      selectionEnd: currentValue.length,\n    };\n    await waitAndRunNextAction(() => onWillChange?.(event));\n    await waitAndRunNextAction(() => onChange?.(event));\n  }\n\n  // End editing\n  await waitAndRunNextAction(() => {\n    currentValue = getCurrentValue();\n    onEditEnd?.({\n      text: currentValue,\n      selectionStart: currentValue.length,\n      selectionEnd: currentValue.length,\n      reason: EditTextUnfocusReason.DismissKeyPress,\n    });\n  });\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/untilNextRenderComplete.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\n\nexport function untilNextRenderComplete(component: IComponent): Promise<void> {\n  return new Promise(resolve => {\n    component.renderer.onNextRenderComplete(resolve);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/untilRenderComplete.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\n\nexport function untilRenderComplete(component: IComponent): Promise<void> {\n  return new Promise(resolve => {\n    component.renderer.onRenderComplete(resolve);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/virtualNodeGetKey.ts",
    "content": "import { IRenderedVirtualNode } from 'valdi_core/src/IRenderedVirtualNode';\nimport { componentGetKey } from './componentGetKey';\n\nexport function virtualNodeGetKey(virtualNode: IRenderedVirtualNode): string {\n  const component = virtualNode.component;\n  const element = virtualNode.element;\n  return component ? componentGetKey(component) : element?.viewClass ?? 'element';\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/virtualNodeTreeDump.ts",
    "content": "import { IRenderedVirtualNode } from 'valdi_core/src/IRenderedVirtualNode';\nimport { consoleDim, consoleFgBlue, consoleFgRed, consoleFgYellow, consoleReset } from './consoleColor';\nimport { virtualNodeGetKey } from './virtualNodeGetKey';\n\n/**\n * Print recursively the tree of the virtual node\n */\nexport function virtualNodeTreeDump(\n  virtualNode: IRenderedVirtualNode | IRenderedVirtualNode[],\n  maxDepth?: number,\n  noColor?: boolean,\n) {\n  const colorValue = (value: string, color: string) => {\n    if (noColor) {\n      return value;\n    }\n    return color + value + consoleReset;\n  };\n\n  const limit = maxDepth ?? 100;\n  const recursor = (current: IRenderedVirtualNode, depth: number, looping: Map<number, boolean>) => {\n    if (depth > limit) {\n      return;\n    }\n\n    const component = current.component;\n    const element = current.element;\n\n    const key = virtualNodeGetKey(current);\n    let prefix = '';\n    for (let i = 0; i < depth; i++) {\n      if (i + 1 == depth) {\n        prefix += ' +';\n      } else {\n        if (looping.get(i)) {\n          prefix += ' |';\n        } else {\n          prefix += '  ';\n        }\n      }\n    }\n\n    const simplifiedViewModel: string[] = [];\n    const keys = component ? Object.keys(component.viewModel) : element?.getAttributeNames() ?? [];\n    keys.sort((a, b) => {\n      return a.length - b.length;\n    });\n    const maxSpace = 1000;\n    let usedSpace = 0;\n    for (const key of keys) {\n      const value = component ? component.viewModel[key] : element?.getAttribute(key);\n      const type = typeof value;\n      if (type === 'number' || type === 'string' || type === 'boolean' || type === 'function') {\n        let valueString = value.toString();\n        if (type === 'function') {\n          valueString = '<function/>';\n        }\n        const itemString = key + ': ' + valueString;\n        if (itemString.length + usedSpace > maxSpace) {\n          simplifiedViewModel.push('...');\n          break;\n        } else {\n          usedSpace += itemString.length;\n          simplifiedViewModel.push(itemString);\n        }\n      }\n    }\n\n    console.log(\n      colorValue(prefix, consoleFgYellow),\n      colorValue(key, component ? consoleFgRed : consoleFgBlue),\n      colorValue('{' + simplifiedViewModel.join(', ') + '}', consoleDim),\n    );\n\n    const children = current.children;\n    for (let i = 0; i < children.length; i++) {\n      const newLooping = new Map(looping);\n      if (i + 1 < children.length) {\n        newLooping.set(depth, true);\n      }\n      recursor(children[i], depth + 1, newLooping);\n    }\n  };\n\n  if (virtualNode instanceof Array) {\n    for (const item of virtualNode) {\n      recursor(item, 0, new Map());\n    }\n  } else {\n    recursor(virtualNode, 0, new Map());\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/waitFor.ts",
    "content": "/**\n * Return a promise that resolves when locator returns the result.\n * locator should throw Error if it cannot find the target.\n */\nexport async function waitFor<T>(locator: () => T | Promise<T>, timeoutMs = 3000, intervalMs = 10): Promise<T> {\n  let lastAttemptError: unknown | null = null;\n\n  return new Promise((resolve, reject) => {\n    let nextAttemptTimeoutId: number | null = null;\n\n    // Set a timeout to reject the promise if the locator doesn't return a value\n    const timeoutId = setTimeout(() => {\n      if (nextAttemptTimeoutId !== null) {\n        clearTimeout(nextAttemptTimeoutId);\n      }\n      // Log the stack trace to help debugging\n      reject(lastAttemptError ?? new Error('waitFor timed out'));\n    }, timeoutMs);\n\n    const check = async () => {\n      try {\n        const result = await locator();\n        clearTimeout(timeoutId);\n        resolve(result);\n      } catch (e) {\n        // ignore, and shedule the next attempt\n        nextAttemptTimeoutId = setTimeout(check, intervalMs);\n        lastAttemptError = e;\n      }\n    };\n\n    // Start the first attempt\n    void check();\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/test/util/waitForNodeWithKey.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { IRenderedElement } from 'valdi_core/src/IRenderedElement';\nimport { IRenderedElementViewClass } from 'valdi_test/test/IRenderedElementViewClass';\nimport { elementTypeFind } from './elementTypeFind';\nimport { findNodeWithKey } from './findNodeWithKey';\nimport { getAttributeFromNode } from './getAttributeFromNode';\nimport { isRenderedElement } from './isRenderedElement';\nimport { waitFor } from './waitFor';\n\ntype Node = IComponent | IRenderedElement;\n\nconst DEFAULT_TIMEOUT_MS = 3000;\nconst DEFAULT_INTERVAL_MS = 10;\n\nconst rejectIfEmpty = <T>(result: T): T => {\n  if (!result || (Array.isArray(result) && !result.length)) {\n    throw new Error('Component not found');\n  }\n  return result;\n};\n\nconst rejectIfExist = <T>(result: T): T => {\n  if (Array.isArray(result) ? result.length : result) {\n    throw new Error('Component still exists');\n  }\n  return result;\n};\n\nexport const waitForNodesWithKey = async (\n  root: Node | (() => Node),\n  key: string,\n  timeoutMs = DEFAULT_TIMEOUT_MS,\n  intervalMs = DEFAULT_INTERVAL_MS,\n): Promise<Node[]> => {\n  try {\n    return await waitFor(() => rejectIfEmpty(findNodeWithKey(root, key)), timeoutMs, intervalMs);\n  } catch (e) {\n    const resolvedNode = typeof root === 'function' ? root() : root;\n    throw new Error(\n      `waitForNodesWithKey failed to find key \"${key}\" in root \"${\n        isRenderedElement(resolvedNode) ? resolvedNode.viewClass : resolvedNode.renderer.contextId\n      }\" after ${timeoutMs}ms. ${e}`,\n    );\n  }\n};\n\nexport const waitForNodeWithKey = async (\n  root: Node | (() => Node),\n  key: string,\n  timeoutMs = DEFAULT_TIMEOUT_MS,\n  intervalMs = DEFAULT_INTERVAL_MS,\n): Promise<Node> => {\n  return (await waitForNodesWithKey(root, key, timeoutMs, intervalMs))[0];\n};\n\nexport const waitForNodeWithKeyToDisappear = async (\n  root: Node | (() => Node),\n  key: string,\n  timeoutMs = DEFAULT_TIMEOUT_MS,\n  intervalMs = DEFAULT_INTERVAL_MS,\n): Promise<void> => {\n  try {\n    await waitFor(() => rejectIfExist(findNodeWithKey(root, key)), timeoutMs, intervalMs);\n  } catch (e) {\n    const resolvedNode = typeof root === 'function' ? root() : root;\n    throw new Error(\n      `waitForNodeWithKeyToDisappear is still able to find key \"${key}\" in root \"${\n        isRenderedElement(resolvedNode) ? resolvedNode.viewClass : resolvedNode.renderer.contextId\n      }\" after ${timeoutMs}ms. ${e}`,\n    );\n  }\n};\n\nexport const waitForNodeWithAttributeValue = async (\n  root: Node | (() => Node),\n  key: string,\n  attributeKey: string,\n  attributeValue: unknown,\n  timeoutMs = DEFAULT_TIMEOUT_MS,\n  intervalMs = DEFAULT_INTERVAL_MS,\n): Promise<void> => {\n  try {\n    return await waitFor(\n      () => {\n        const node = rejectIfEmpty(findNodeWithKey(root, key))[0];\n        const currentValue = getAttributeFromNode(node, attributeKey);\n        if (currentValue !== attributeValue) {\n          throw new Error(`Attribute ${attributeKey} is not set to ${attributeValue}. Current value: ${currentValue}.`);\n        }\n      },\n      timeoutMs,\n      intervalMs,\n    );\n  } catch (e) {\n    const resolvedNode = typeof root === 'function' ? root() : root;\n    throw new Error(\n      `waitForNodeWithAttributeValue failed to wait for key \"${key}\" in root \"${\n        isRenderedElement(resolvedNode) ? resolvedNode.viewClass : resolvedNode.renderer.contextId\n      }\" after ${timeoutMs}ms. ${e}`,\n    );\n  }\n};\n\nexport const waitForElementWithAttributeValue = async (\n  elementClass: IRenderedElementViewClass,\n  root: Node | (() => Node),\n  key: string,\n  attributeKey: string,\n  attributeValue: unknown,\n  timeoutMs = DEFAULT_TIMEOUT_MS,\n  intervalMs = DEFAULT_INTERVAL_MS,\n): Promise<void> => {\n  try {\n    return await waitFor(\n      () => {\n        const elements = elementTypeFind(findNodeWithKey(root, key), elementClass);\n        if (!elements.length) {\n          throw new Error(`Could not find any ${elementClass} under key ${key}`);\n        }\n        const currentValue = getAttributeFromNode(elements[0], attributeKey);\n        if (currentValue !== attributeValue) {\n          throw new Error(`Attribute ${attributeKey} is not set to ${attributeValue}. Current value: ${currentValue}.`);\n        }\n      },\n      timeoutMs,\n      intervalMs,\n    );\n  } catch (e) {\n    const resolvedNode = typeof root === 'function' ? root() : root;\n    throw new Error(\n      `waitForElementWithAttributeValue failed to wait for key \"${key}\" in root \"${\n        isRenderedElement(resolvedNode) ? resolvedNode.viewClass : resolvedNode.renderer.contextId\n      }\" after ${timeoutMs}ms. ${e}`,\n    );\n  }\n};\n\nexport const waitForComponentWithKey = async (\n  root: Node | (() => Node),\n  key: string,\n  timeoutMs = DEFAULT_TIMEOUT_MS,\n  intervalMs = DEFAULT_INTERVAL_MS,\n): Promise<IComponent> => {\n  const found = await waitForNodeWithKey(root, key, timeoutMs, intervalMs);\n  if (isRenderedElement(found)) {\n    throw new Error(`Expected component, but got rendered element: ${found.viewClass}`);\n  }\n  return found;\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/foundation/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\",\n    \"compilerOptions\": {\n        \"noImplicitReturns\": true,\n        \"noImplicitAny\": true,\n        \"strict\": true,\n    }\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nvaldi_module(\n    name = \"jasmine\",\n    srcs = glob([\n        \"src/**/*.js\",\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"debug\",\n    disable_annotation_processing = True,\n    ios_module_name = \"SCCJasmine\",\n    ios_output_target = \"debug\",\n    module_yaml = \"module.yaml\",\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/README.md",
    "content": "## Jasmine for valdi components\n\nThis module is a mirror from npm package which contains files from `jasmine-core/lib/jasmine-core`.\nCurrent version `jasmine-core` and `@types/jasmine` you can check in the `package.json`.\nThis mirror includes minor changes for testing Valdi modules TypeScript sources. \n\nSteps to update:\n- copy from `jasmine/node_modules/@types/jasmine/index.d.ts` to `jasmine/src/jasmine.d.ts`\n- copy from `jasmine-core/lib/jasmine-core/jasmine.js` to `jasmine/src/jasmine.js`\n\n>  Then you need to update parts of logic in `jasmine.js` \nto make sure that jasmine stack trace has the right reference for the error. \n\n```\n    stackTrace.frames.forEach(function (frame) {\n-        if (frame.file && frame.file !== jasmineFile) {\n+        if (frame.file && frame.file === jasmineFile) {\n+          if (result[result.length - 1] !== jasmineMarker) {\n+            result.push(jasmineMarker);\n+          }\n+        } else {\n           result.push(frame.raw);\n-        } else if (result[result.length - 1] !== jasmineMarker) {\n-          result.push(jasmineMarker);\n         }\n       });\n \n@@ -7643,10 +7645,10 @@ getJasmineRequireObj().StackTrace = function (j$) {\n         }\n \n         fileLineColMatch = overallMatch[pattern.fileLineColIx].match(\n-          /^(.*):(\\d+):\\d+$/\n+          /^(.*):(\\d+)(?::\\d+)?$/\n         );\n         if (!fileLineColMatch) {\n-          return null;\n+          return { raw: line };\n         }\n \n         style = style || pattern.style;\n\n```\n\n- copy from `jasmine-core/lib/jasmine-core/node_boot.js` to `jasmine/src/origin_boot.js`\n\n> please make sure that there is no node.js related API used.\n\n\n`boot.js` contains Valdi related integration files.\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/module.yaml",
    "content": "output_target: debug\ndisable_code_coverage: true\ncompilation_mode: js\ndisable_annotation_processing: true\nsingle_file_codegen: true"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/package.json",
    "content": "{\n  \"name\": \"jasmine-valdi\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This module contains a mirror of jasmine lib for using it in Valdi. For details please check the README\",\n  \"dependencies\": {\n    \"@types/jasmine\": \"4.0.3\",\n    \"jasmine-core\": \"4.1.1\"\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/src/boot.js",
    "content": "const jasmineRequire = require('./jasmine', true);\nconst runJasmineOriginBoot = require('./origin_boot', true);\nconst ConsoleReporter = require('./console_reporter', true);\n\nfunction Jasmine(showColors, stackFilter, seed, specFilter) {\n  const consoleReporter = new ConsoleReporter();\n  consoleReporter.setOptions({ print: process.stdout.write, showColors: showColors, stackFilter: stackFilter });\n\n  const jasmine = runJasmineOriginBoot(jasmineRequire);\n  const env = jasmine.getEnv({ suppressLoadErrors: true });\n\n  env.configure({\n    specFilter: specFilter,\n    // Configure random seed if provided\n    ...(seed !== undefined && seed !== null ? { random: true, seed: seed } : {}),\n  });\n\n  env.addReporter(consoleReporter);\n\n  this.execute = function () {\n    env.execute();\n  };\n\n  this.addReporter = function (reporter) {\n    env.addReporter(reporter);\n  };\n}\n\nmodule.exports = Jasmine;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/src/console_reporter.js",
    "content": "function ConsoleReporter() {\n  var print = function () {},\n    showColors = false,\n    jasmineCorePath = null,\n    specCount,\n    executableSpecCount,\n    failureCount,\n    failedSpecs = [],\n    pendingSpecs = [],\n    ansi = {\n      green: '\\x1B[32m',\n      red: '\\x1B[31m',\n      yellow: '\\x1B[33m',\n      none: '\\x1B[0m',\n    },\n    failedSuites = [],\n    stackFilter = defaultStackFilter;\n\n  this.setOptions = function (options) {\n    if (options.print) {\n      print = options.print;\n    }\n    showColors = options.showColors || false;\n    if (options.jasmineCorePath) {\n      jasmineCorePath = options.jasmineCorePath;\n    }\n    if (options.stackFilter) {\n      stackFilter = options.stackFilter;\n    }\n  };\n\n  this.jasmineStarted = function (options) {\n    specCount = 0;\n    executableSpecCount = 0;\n    failureCount = 0;\n    if (options && options.order && options.order.random) {\n      print('Randomized with seed ' + options.order.seed);\n      printNewline();\n    }\n    print('Started');\n    printNewline();\n  };\n\n  this.jasmineDone = function (result) {\n    printNewline();\n    printNewline();\n    if (failedSpecs.length > 0) {\n      print('------------------');\n      print('-- Failures start:');\n    }\n    for (var i = 0; i < failedSpecs.length; i++) {\n      specFailureDetails(failedSpecs[i], i + 1);\n    }\n\n    for (i = 0; i < failedSuites.length; i++) {\n      suiteFailureDetails(failedSuites[i]);\n    }\n\n    if (result && result.failedExpectations && result.failedExpectations.length > 0) {\n      suiteFailureDetails(result);\n    }\n    if (failedSpecs.length > 0) {\n      printNewline();\n      print('-- Failures end.');\n      print('----------------');\n    }\n\n    if (pendingSpecs.length > 0) {\n      printNewline();\n      print('Pending:');\n    }\n    for (i = 0; i < pendingSpecs.length; i++) {\n      pendingSpecDetails(pendingSpecs[i], i + 1);\n    }\n\n    if (specCount > 0) {\n      printNewline();\n\n      if (executableSpecCount !== specCount) {\n        print('Ran ' + executableSpecCount + ' of ' + specCount + plural(' spec', specCount));\n        printNewline();\n      }\n      var specCounts =\n        executableSpecCount +\n        ' ' +\n        plural('spec', executableSpecCount) +\n        ', ' +\n        failureCount +\n        ' ' +\n        plural('failure', failureCount);\n\n      if (pendingSpecs.length) {\n        specCounts += ', ' + pendingSpecs.length + ' pending ' + plural('spec', pendingSpecs.length);\n      }\n\n      print(specCounts);\n    } else {\n      print('No specs found');\n    }\n\n    printNewline();\n    var seconds = result ? result.totalTime / 1000 : 0;\n    print('Finished in ' + seconds + ' ' + plural('second', seconds));\n    printNewline();\n\n    if (result && result.overallStatus === 'incomplete') {\n      print('Incomplete: ' + result.incompleteReason);\n      printNewline();\n    }\n\n    if (result && result.order && result.order.random) {\n      print('Randomized with seed ' + result.order.seed);\n      print(' (jasmine --random=true --seed=' + result.order.seed + ')');\n      printNewline();\n    }\n  };\n\n  this.specDone = function (result) {\n    specCount++;\n\n    if (result.status === 'pending') {\n      pendingSpecs.push(result);\n      executableSpecCount++;\n      print(colored('yellow', '*'));\n      return;\n    }\n\n    if (result.status === 'passed') {\n      executableSpecCount++;\n      print(colored('green', '.'));\n      return;\n    }\n\n    if (result.status === 'failed') {\n      failureCount++;\n      failedSpecs.push(result);\n      executableSpecCount++;\n      print(colored('red', 'F'));\n    }\n  };\n\n  this.suiteDone = function (result) {\n    if (result.failedExpectations && result.failedExpectations.length > 0) {\n      failureCount++;\n      failedSuites.push(result);\n    }\n  };\n\n  return this;\n\n  function printNewline() {\n    print('\\n');\n  }\n\n  function colored(color, str) {\n    return showColors ? ansi[color] + str + ansi.none : str;\n  }\n\n  function plural(str, count) {\n    return count === 1 ? str : str + 's';\n  }\n\n  function repeat(thing, times) {\n    var arr = [];\n    for (var i = 0; i < times; i++) {\n      arr.push(thing);\n    }\n    return arr;\n  }\n\n  function indent(str, spaces) {\n    var lines = (str || '').split('\\n');\n    var newArr = [];\n    for (var i = 0; i < lines.length; i++) {\n      newArr.push(repeat(' ', spaces).join('') + lines[i]);\n    }\n    return newArr.join('\\n');\n  }\n\n  function defaultStackFilter(stack) {\n    if (!stack) {\n      return '';\n    }\n\n    return stack\n      .split('\\n')\n      .filter(function (stackLine) {\n        return stackLine.indexOf(jasmineCorePath) === -1;\n      })\n      .join('\\n');\n  }\n\n  function specFailureDetails(result, failedSpecNumber) {\n    printNewline();\n    print(failedSpecNumber + ') ');\n    print(result.fullName);\n    printFailedExpectations(result);\n  }\n\n  function suiteFailureDetails(result) {\n    printNewline();\n    print('Suite error: ' + result.fullName);\n    printFailedExpectations(result);\n  }\n\n  function printFailedExpectations(result) {\n    for (var i = 0; i < result.failedExpectations.length; i++) {\n      var failedExpectation = result.failedExpectations[i];\n      printNewline();\n      print(indent('Message:', 2));\n      printNewline();\n      print(colored('red', indent(failedExpectation.message, 4)));\n      printNewline();\n      print(indent('Stack:', 2));\n      printNewline();\n      print(indent(stackFilter(failedExpectation.stack), 4));\n    }\n\n    printNewline();\n  }\n\n  function pendingSpecDetails(result, pendingSpecNumber) {\n    printNewline();\n    printNewline();\n    print(pendingSpecNumber + ') ');\n    print(result.fullName);\n    printNewline();\n    var pendingReason = 'No reason given';\n    if (result.pendingReason && result.pendingReason !== '') {\n      pendingReason = result.pendingReason;\n    }\n    print(indent(colored('yellow', pendingReason), 2));\n    printNewline();\n  }\n}\n\nmodule.exports = ConsoleReporter;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/src/jasmine-reporters/junit_reporter.js",
    "content": "/**\n * Forked from \n * https://github.com/larrymyers/jasmine-reporters\n * at 2.4.0\n * \n * https://github.com/larrymyers/jasmine-reporters/tree/491efaaafe97b7b02ab0788aeb41481cf345cd8e\n */\n/* global __phantom_writeFile */\n(function(global) {\n    var UNDEFINED,\n        exportObject;\n\n    if (typeof module !== \"undefined\" && module.exports) {\n        exportObject = exports;\n    } else {\n        exportObject = global.jasmineReporters = global.jasmineReporters || {};\n    }\n\n    function trim(str) { return str.replace(/^\\s+/, \"\" ).replace(/\\s+$/, \"\" ); }\n    function elapsed(start, end) { return (end - start)/1000; }\n    function isFailed(obj) { return obj.status === \"failed\"; }\n    function isSkipped(obj) { return obj.status === \"pending\"; }\n    function isDisabled(obj) { return obj.status === \"disabled\"; }\n    function pad(n) { return n < 10 ? \"0\"+n : n; }\n    function extend(dupe, obj) { // performs a shallow copy of all props of `obj` onto `dupe`\n        for (var prop in obj) {\n            if (obj.hasOwnProperty(prop)) {\n                dupe[prop] = obj[prop];\n            }\n        }\n        return dupe;\n    }\n    function ISODateString(d) {\n        return d.getFullYear() + \"-\" +\n            pad(d.getMonth()+1) + \"-\" +\n            pad(d.getDate()) + \"T\" +\n            pad(d.getHours()) + \":\" +\n            pad(d.getMinutes()) + \":\" +\n            pad(d.getSeconds());\n    }\n    function escapeControlChars(str) {\n        // Remove control character from Jasmine default output\n        return str.replace(/[\\x1b]/g, \"\");\n    }\n    function escapeInvalidXmlChars(str) {\n        var escaped = str.replace(/&/g, \"&amp;\")\n            .replace(/</g, \"&lt;\")\n            .replace(/>/g, \"&gt;\")\n            .replace(/\"/g, \"&quot;\")\n            .replace(/'/g, \"&apos;\");\n        return escapeControlChars(escaped);\n    }\n    function getQualifiedFilename(path, filename, separator) {\n        if (path && path.substr(-1) !== separator && filename.substr(0) !== separator) {\n            path += separator;\n        }\n        return path + filename;\n    }\n    function log(str) {\n        var con = global.console || console;\n        if (con && con.log) {\n            con.log(str);\n        }\n    }\n    /** Hooks into either process.stdout (node) or console.log, if that is not\n     *  available (see https://gist.github.com/pguillory/729616).\n     */\n    function hook_stdout(callback) {\n        var old_write;\n        var useProcess;\n        if(typeof(process)!==\"undefined\") {\n            old_write = process.stdout.write;\n            useProcess = true;\n            process.stdout.write = (function(write) {\n                return function(string, encoding, fd) {\n                    write.apply(process.stdout, arguments);\n                    callback(string, encoding, fd);\n                };\n            })(old_write);\n        }\n        else {\n            old_write = console.log.bind(console);\n            useProcess = false;\n            console.log = (function(write) {\n                return function(string) {\n                    write.apply(string);\n                    callback(string, \"utf8\");\n                };\n            })(old_write);\n        }\n        return function() {\n            if(useProcess) {\n                process.stdout.write = old_write;\n            }\n            else {\n                console.log = old_write;\n            }\n        };\n    }\n\n    /**\n     * A delegate for letting the consumer\n     * modify the suite name when it is used inside the junit report.\n     * This is useful when running a test suite against multiple capabilities\n     * because the report can have unique names for each combination of suite/spec\n     * and capability/test environment.\n     *\n     * @callback modifySuiteName\n     * @param {string} fullName\n     * @param {object} suite\n     */\n\n    /**\n     * A delegate for letting the consumer\n     * modify the report filename when it is used inside the junit report.\n     * This is useful when running a test suite against multiple capabilities\n     * because the report can have unique names for each combination of suite/spec\n     * and capability/test environment.\n     *\n     * @callback modifyReportFileName\n     * @param {string} suggestedName\n     * @param {object} suite\n     */\n\n    /**\n     * Generates JUnit XML for the given spec run. There are various options\n     * to control where the results are written, and the default values are\n     * set to create as few .xml files as possible. It is possible to save a\n     * single XML file, or an XML file for each top-level `describe`, or an\n     * XML file for each `describe` regardless of nesting.\n     *\n     * Usage:\n     *\n     * jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter(options));\n     *\n     * @param {object} [options]\n     * @param {string} [savePath] directory to save the files (default: '')\n     * @param {boolean} [consolidateAll] whether to save all test results in a\n     *   single file (default: true)\n     *   NOTE: if true, {filePrefix} is treated as the full filename (excluding\n     *     extension)\n     * @param {boolean} [consolidate] whether to save nested describes within the\n     *   same file as their parent (default: true)\n     *   NOTE: true does nothing if consolidateAll is also true.\n     *   NOTE: false also sets consolidateAll to false.\n     * @param {boolean} [useDotNotation] whether to separate suite names with\n     *   dots instead of spaces, ie \"Class.init\" not \"Class init\" (default: true)\n     * @param {boolean} [useFullTestName] whether to use the fully qualified Test\n     *   name for the TestCase name attribute, ie \"Suite Name Spec Name\" not\n     *   \"Spec Name\" (default: false)\n     * @param {string} [filePrefix] is the string value that is prepended to the\n     *   xml output file (default: junitresults-)\n     *   NOTE: if consolidateAll is true, the default is simply \"junitresults\" and\n     *     this becomes the actual filename, ie \"junitresults.xml\"\n     * @param {string} [package] is the base package for all test suits that are\n     *   handled by this report {default: none}\n     * @param {function} [modifySuiteName] a delegate for letting the consumer\n     *   modify the suite name when it is used inside the junit report.\n     *   This is useful when running a test suite against multiple capabilities\n     *   because the report can have unique names for each combination of suite/spec\n     *   and capability/test environment.\n     * @param {function} [modifyReportFileName] a delegate for letting the consumer\n     *   modify the report filename.\n     *   This is useful when running a test suite against multiple capabilities\n     *   because the report can have unique names for each combination of suite/spec\n     *   and capability/test environment.\n     * @param {string} [stylesheetPath] is the string value that specifies a path\n     *   to an XSLT stylesheet to add to the junit XML file so that it can be\n     *   opened directly in a browser. (default: none, no xml-stylesheet tag is added)\n     * @param {function} [suppressDisabled] if true, will not include `disabled=\"..\"` in XML output\n     * @param {function} [systemOut] a delegate for letting the consumer add content\n     *   to a <system-out> tag as part of each <testcase> spec output. If provided,\n     *   it is invoked with the spec object and the fully qualified suite as filename.\n     * @param {boolean} [captureStdout] enables capturing all output from stdout as spec output in the\n     * xml-output elements of the junit reports {default: false}. If a systemOut delegate is defined and captureStdout\n     * is true, the output of the spec can be accessed via spec._stdout\n     */\n    exportObject.JUnitXmlReporter = function(options) {\n        var self = this;\n        self.started = false;\n        self.finished = false;\n        // sanitize arguments\n        options = options || {};\n        self.savePath = options.savePath || \"\";\n        self.consolidate = options.consolidate === UNDEFINED ? true : options.consolidate;\n        self.consolidateAll = self.consolidate !== false && (options.consolidateAll === UNDEFINED ? true : options.consolidateAll);\n        self.useDotNotation = options.useDotNotation === UNDEFINED ? true : options.useDotNotation;\n        self.useFullTestName = options.useFullTestName === UNDEFINED ? false : options.useFullTestName;\n        if (self.consolidateAll) {\n            self.filePrefix = options.filePrefix || \"junitresults\";\n        } else {\n            self.filePrefix = typeof options.filePrefix === \"string\" ? options.filePrefix : \"junitresults-\";\n        }\n        self.package = typeof(options.package) === \"string\" ? escapeInvalidXmlChars(options.package) : UNDEFINED;\n        self.stylesheetPath = typeof(options.stylesheetPath) === \"string\" && options.stylesheetPath || UNDEFINED;\n\n        if(options.modifySuiteName && typeof options.modifySuiteName !== \"function\") {\n            throw new Error('option \"modifySuiteName\" must be a function');\n        }\n        if(options.modifyReportFileName && typeof options.modifyReportFileName !== \"function\") {\n            throw new Error('option \"modifyReportFileName\" must be a function');\n        }\n        if(options.systemOut && typeof options.systemOut !== \"function\") {\n            throw new Error('option \"systemOut\" must be a function');\n        }\n\n        self.captureStdout = options.captureStdout || false;\n        if(self.captureStdout && !options.systemOut) {\n            options.systemOut = function (spec) {\n                return spec._stdout;\n            };\n        }\n        self.removeStdoutWrapper = undefined;\n\n        var delegates = {};\n        delegates.modifySuiteName = options.modifySuiteName;\n        delegates.modifyReportFileName = options.modifyReportFileName;\n        delegates.systemOut = options.systemOut;\n\n        self.logEntries = [];\n\n        var suites = [],\n            currentSuite = null,\n            // when use use fit, jasmine never calls suiteStarted / suiteDone, so make a fake one to use\n            fakeFocusedSuite = {\n                id: \"focused\",\n                description: \"focused specs\",\n                fullName: \"focused specs\"\n            };\n\n        var __suites = {}, __specs = {};\n        function getSuite(suite) {\n            __suites[suite.id] = extend(__suites[suite.id] || {}, suite);\n            return __suites[suite.id];\n        }\n        function getSpec(spec, suite) {\n            __specs[spec.id] = extend(__specs[spec.id] || {}, spec);\n            var ret = __specs[spec.id];\n            if (suite && !ret._suite) {\n                ret._suite = suite;\n                suite._specs.push(ret);\n            }\n            return ret;\n        }\n\n        self.jasmineStarted = function() {\n            exportObject.startTime = new Date();\n            self.started = true;\n            if(self.captureStdout) {\n                self.removeStdoutWrapper = hook_stdout(function(string) {\n                    self.logEntries.push(string);\n                });\n            }\n        };\n        self.suiteStarted = function(suite) {\n            suite = getSuite(suite);\n            suite._startTime = new Date();\n            suite._specs = [];\n            suite._suites = [];\n            suite._failures = 0;\n            suite._skipped = 0;\n            suite._disabled = 0;\n            suite._parent = currentSuite;\n            if (!currentSuite) {\n                suites.push(suite);\n            } else {\n                currentSuite._suites.push(suite);\n            }\n            currentSuite = suite;\n        };\n        self.specStarted = function(spec) {\n            if (!currentSuite) {\n                // focused spec (fit) -- suiteStarted was never called\n                self.suiteStarted(fakeFocusedSuite);\n            }\n            spec = getSpec(spec, currentSuite);\n            spec._startTime = new Date();\n            spec._stdout = \"\";\n        };\n        self.specDone = function(spec) {\n            spec = getSpec(spec, currentSuite);\n            spec._endTime = new Date();\n            storeOutput(spec);\n            if (isSkipped(spec)) { spec._suite._skipped++; }\n            if (isDisabled(spec)) { spec._suite._disabled++; }\n            if (isFailed(spec)) { spec._suite._failures += spec.failedExpectations.length; }\n        };\n        self.suiteDone = function(suite) {\n            suite = getSuite(suite);\n            if (suite._parent === UNDEFINED) {\n                // disabled suite (xdescribe) -- suiteStarted was never called\n                self.suiteStarted(suite);\n            }\n            suite._endTime = new Date();\n            currentSuite = suite._parent;\n        };\n        self.jasmineDone = function() {\n            if (currentSuite) {\n                // focused spec (fit) -- suiteDone was never called\n                self.suiteDone(fakeFocusedSuite);\n            }\n            var output = \"\";\n            var testSuitesResults = { disabled: 0, failures: 0, tests: 0, time: 0 };\n            for (var i = 0; i < suites.length; i++) {\n                output += self.getOrWriteNestedOutput(suites[i]);\n                // retrieve nested suite data to include in the testsuites tag\n                var suiteResults = self.getNestedSuiteData(suites[i]);\n                for (var key in suiteResults) {\n                    testSuitesResults[key] += suiteResults[key];\n                }\n            }\n            // if we have anything to write here, write out the consolidated file\n            if (output) {\n                wrapOutputAndWriteFile(self.filePrefix, output, testSuitesResults);\n            }\n            //log(\"Specs skipped but not reported (entire suite skipped or targeted to specific specs)\", totalSpecsDefined - totalSpecsExecuted + totalSpecsDisabled);\n\n            self.finished = true;\n            // this is so phantomjs-testrunner.js can tell if we're done executing\n            exportObject.endTime = new Date();\n            if(self.removeStdoutWrapper) {\n                self.removeStdoutWrapper();\n            }\n        };\n\n        self.formatSuiteData = function(suite) {\n            return {\n                disabled: suite._disabled || 0,\n                failures: suite._failures || 0,\n                tests: suite._specs.length || 0,\n                time: (suite._endTime.getTime() - suite._startTime.getTime()) || 0\n            };\n        };\n\n        self.getNestedSuiteData = function (suite) {\n            var suiteResults = self.formatSuiteData(suite);\n            for (var i = 0; i < suite._suites.length; i++) {\n                var childSuiteResults = self.getNestedSuiteData(suite._suites[i]);\n                for (var key in suiteResults) {\n                    suiteResults[key] += childSuiteResults[key];\n                }\n            }\n            return suiteResults;\n        };\n\n        self.getOrWriteNestedOutput = function(suite) {\n            var output = suiteAsXml(suite);\n            for (var i = 0; i < suite._suites.length; i++) {\n                output += self.getOrWriteNestedOutput(suite._suites[i]);\n            }\n            if (self.consolidateAll || self.consolidate && suite._parent) {\n                return output;\n            } else {\n                // if we aren't supposed to consolidate output, just write it now\n                wrapOutputAndWriteFile(generateFilename(suite), output, self.getNestedSuiteData(suite));\n                return \"\";\n            }\n        };\n\n        self.writeFile = function(filename, text) {\n            var errors = [];\n            var path = self.savePath;\n\n            function phantomWrite(path, filename, text) {\n                // turn filename into a qualified path\n                filename = getQualifiedFilename(path, filename, window.fs_path_separator);\n                // write via a method injected by phantomjs-testrunner.js\n                __phantom_writeFile(filename, text);\n            }\n\n            function nodeWrite(path, filename, text) {\n                var fs = require(\"fs\");\n                var nodejs_path = require(\"path\");\n                require(\"mkdirp\").sync(path); // make sure the path exists\n                var filepath = nodejs_path.join(path, filename);\n                var xmlfile = fs.openSync(filepath, \"w\");\n                fs.writeSync(xmlfile, text, 0);\n                fs.closeSync(xmlfile);\n                return;\n            }\n            // Attempt writing with each possible environment.\n            // Track errors in case no write succeeds\n            try {\n                phantomWrite(path, filename, text);\n                return;\n            } catch (e) { errors.push(\"  PhantomJs attempt: \" + e.message); }\n            try {\n                nodeWrite(path, filename, text);\n                return;\n            } catch (f) { errors.push(\"  NodeJS attempt: \" + f.message); }\n\n            // If made it here, no write succeeded.  Let user know.\n            log(\"Warning: writing junit report failed for '\" + path + \"', '\" +\n                filename + \"'. Reasons:\\n\" +\n                errors.join(\"\\n\")\n            );\n        };\n\n        /******** Helper functions with closure access for simplicity ********/\n        function generateFilename(suite) {\n            return self.filePrefix + getFullyQualifiedSuiteName(suite, true) + \".xml\";\n        }\n\n        function getFullyQualifiedSuiteName(suite, isFilename) {\n            var fullName;\n            if (self.useDotNotation || isFilename) {\n                fullName = suite.description;\n                for (var parent = suite._parent; parent; parent = parent._parent) {\n                    fullName = parent.description + \".\" + fullName;\n                }\n            } else {\n                fullName = suite.fullName;\n            }\n\n            // Either remove or escape invalid XML characters\n            if (isFilename) {\n                var fileName = \"\",\n                    rFileChars = /[\\w.]/,\n                    chr;\n                while (fullName.length) {\n                    chr = fullName[0];\n                    fullName = fullName.substr(1);\n                    if (rFileChars.test(chr)) {\n                        fileName += chr;\n                    }\n                }\n                if(delegates.modifyReportFileName) {\n                    fileName = delegates.modifyReportFileName(fileName, suite);\n                }\n                return fileName;\n            } else {\n\n                if(delegates.modifySuiteName) {\n                    fullName = delegates.modifySuiteName(fullName, suite);\n                }\n\n                return escapeInvalidXmlChars(fullName);\n            }\n        }\n\n        function suiteAsXml(suite) {\n            var xml = '\\n <testsuite name=\"' + getFullyQualifiedSuiteName(suite) + '\"';\n            xml += ' timestamp=\"' + ISODateString(suite._startTime) + '\"';\n            xml += ' hostname=\"localhost\"'; // many CI systems like Jenkins don't care about this, but junit spec says it is required\n            xml += ' time=\"' + elapsed(suite._startTime, suite._endTime) + '\"';\n            xml += ' errors=\"0\"';\n            xml += ' tests=\"' + suite._specs.length + '\"';\n            xml += ' skipped=\"' + suite._skipped + '\"';\n            if (!options.suppressDisabled) {\n                xml += ' disabled=\"' + suite._disabled + '\"';\n            }\n            // Because of JUnit's flat structure, only include directly failed tests (not failures for nested suites)\n            xml += ' failures=\"' + suite._failures + '\"';\n            if (self.package) {\n                xml += ' package=\"' + self.package + '\"';\n            }\n            xml += \">\";\n\n            for (var i = 0; i < suite._specs.length; i++) {\n                xml += specAsXml(suite._specs[i]);\n            }\n            xml += \"\\n </testsuite>\";\n            return xml;\n        }\n        function specAsXml(spec) {\n            var testName = self.useFullTestName ? spec.fullName : spec.description;\n\n            var xml = '\\n  <testcase classname=\"' + getFullyQualifiedSuiteName(spec._suite) + '\"';\n            xml += ' name=\"' + escapeInvalidXmlChars(testName) + '\"';\n            xml += ' time=\"' + elapsed(spec._startTime, spec._endTime) + '\"';\n\n            var testCaseBody = \"\";\n            if (isSkipped(spec) || isDisabled(spec)) {\n                if (spec.pendingReason) {\n                    testCaseBody = '\\n   <skipped message=\"' + trim(escapeInvalidXmlChars(spec.pendingReason)) + '\" />';\n                } else {\n                    testCaseBody = \"\\n   <skipped />\";\n                }\n            } else if (isFailed(spec)) {\n                for (var i = 0, failure; i < spec.failedExpectations.length; i++) {\n                    failure = spec.failedExpectations[i];\n                    testCaseBody += '\\n   <failure type=\"' + (failure.matcherName || \"exception\") + '\"';\n                    testCaseBody += ' message=\"' + trim(escapeInvalidXmlChars(failure.message))+ '\"';\n                    testCaseBody += \">\";\n                    testCaseBody += \"<![CDATA[\" + trim(escapeControlChars(failure.stack || failure.message)) + \"]]>\";\n                    testCaseBody += \"\\n   </failure>\";\n                }\n            }\n\n            if (testCaseBody || delegates.systemOut) {\n                xml += \">\" + testCaseBody;\n                if (delegates.systemOut) {\n                    xml += \"\\n   <system-out>\" + trim(escapeInvalidXmlChars(delegates.systemOut(spec, getFullyQualifiedSuiteName(spec._suite, true)))) + \"</system-out>\";\n                }\n                xml += \"\\n  </testcase>\";\n            } else {\n                xml += \" />\";\n            }\n            return xml;\n        }\n        function storeOutput(spec) {\n            if(self.captureStdout && !isSkipped(spec)) {\n                if(!isSkipped(spec) && !isDisabled(spec)) {\n                    spec._stdout = self.logEntries.join(\"\") + \"\\n\";\n                }\n                self.logEntries.splice(0, self.logEntries.length);\n            }\n        }\n        function getPrefix(results) {\n            results = results ? results : {};\n            // To remove complexity and be more DRY about the silly preamble and <testsuites> element\n            var prefix = '<?xml version=\"1.0\" encoding=\"UTF-8\" ?>';\n            if (self.stylesheetPath) {\n                prefix += '\\n<?xml-stylesheet type=\"text/xsl\" href=\"' + self.stylesheetPath + '\" ?>';\n            }\n            prefix += \"\\n<testsuites \" + (options.suppressDisabled ? \"\" : 'disabled=\"' + results.disabled + '\" ') + 'errors=\"0\" failures=\"' + results.failures +\n                '\" tests=\"' + results.tests + '\" time=\"' + results.time/1000 + '\">';\n            return prefix;\n        }\n        var suffix = \"\\n</testsuites>\";\n        function wrapOutputAndWriteFile(filename, text, testSuitesResults) {\n            if (filename.substr(-4) !== \".xml\") { filename += \".xml\"; }\n            self.writeFile(filename, (getPrefix(testSuitesResults) + text + suffix));\n        }\n    };\n})(this);"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/src/jasmine.d.ts",
    "content": "// Type definitions for Jasmine 4.0\n// Project: http://jasmine.github.io\n// Definitions by: Boris Yankov <https://github.com/borisyankov>\n//                 Theodore Brown <https://github.com/theodorejb>\n//                 David Pärsson <https://github.com/davidparsson>\n//                 Lukas Zech <https://github.com/lukas-zech-software>\n//                 Boris Breuer <https://github.com/Engineer2B>\n//                 Chris Yungmann <https://github.com/cyungmann>\n//                 Giles Roadnight <https://github.com/Roaders>\n//                 Yaroslav Admin <https://github.com/devoto13>\n//                 Domas Trijonis <https://github.com/fdim>\n//                 Moshe Kolodny <https://github.com/kolodny>\n//                 Stephen Farrar <https://github.com/stephenfarrar>\n//                 Dominik Ehrenberg <https://github.com/djungowski>\n//                 Chives <https://github.com/chivesrs>\n//                 kirjs <https://github.com/kirjs>\n//                 Md. Enzam Hossain <https://github.com/ienzam>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n\n// For ddescribe / iit use : https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/karma-jasmine/karma-jasmine.d.ts\n\n/**\n * @deprecated Use {@link jasmine.ImplementationCallback} instead.\n */\ntype ImplementationCallback = jasmine.ImplementationCallback;\n\n/**\n * Create a group of specs (often called a suite).\n * @param description Textual description of the group\n * @param specDefinitions Function for Jasmine to invoke that will define inner suites a specs\n */\ndeclare function describe(description: string, specDefinitions: () => void): void;\n\n/**\n * A focused `describe`. If suites or specs are focused, only those that are focused will be executed.\n * @param description Textual description of the group\n * @param specDefinitions Function for Jasmine to invoke that will define inner suites a specs\n */\ndeclare function fdescribe(description: string, specDefinitions: () => void): void;\n\n/**\n * A temporarily disabled `describe`. Specs within an xdescribe will be marked pending and not executed.\n * @param description Textual description of the group\n * @param specDefinitions Function for Jasmine to invoke that will define inner suites a specs\n */\ndeclare function xdescribe(description: string, specDefinitions: () => void): void;\n\n/**\n * Define a single spec. A spec should contain one or more expectations that test the state of the code.\n * A spec whose expectations all succeed will be passing and a spec with any failures will fail.\n * @param expectation Textual description of what this spec is checking\n * @param assertion Function that contains the code of your test. If not provided the test will be pending.\n * @param timeout Custom timeout for an async spec.\n */\ndeclare function it(expectation: string, assertion?: jasmine.ImplementationCallback, timeout?: number): void;\n\n/**\n * A focused `it`. If suites or specs are focused, only those that are focused will be executed.\n * @param expectation Textual description of what this spec is checking\n * @param assertion Function that contains the code of your test. If not provided the test will be pending.\n * @param timeout Custom timeout for an async spec.\n */\ndeclare function fit(expectation: string, assertion?: jasmine.ImplementationCallback, timeout?: number): void;\n\n/**\n * A temporarily disabled `it`. The spec will report as pending and will not be executed.\n * @param expectation Textual description of what this spec is checking\n * @param assertion Function that contains the code of your test. If not provided the test will be pending.\n * @param timeout Custom timeout for an async spec.\n */\ndeclare function xit(expectation: string, assertion?: jasmine.ImplementationCallback, timeout?: number): void;\n\n/**\n * Mark a spec as pending, expectation results will be ignored.\n * If you call the function pending anywhere in the spec body, no matter the expectations, the spec will be marked pending.\n * @param reason Reason the spec is pending.\n */\ndeclare function pending(reason?: string): void;\n\n/**\n * Sets a user-defined property that will be provided to reporters as\n * part of the properties field of SpecResult.\n * @since 3.6.0\n */\ndeclare function setSpecProperty(key: string, value: unknown): void;\n\n/**\n * Sets a user-defined property that will be provided to reporters as\n * part of the properties field of SuiteResult.\n * @since 3.6.0\n */\ndeclare function setSuiteProperty(key: string, value: unknown): void;\n\n/**\n * Run some shared setup before each of the specs in the describe in which it is called.\n * @param action Function that contains the code to setup your specs.\n * @param timeout Custom timeout for an async beforeEach.\n */\ndeclare function beforeEach(action: jasmine.ImplementationCallback, timeout?: number): void;\n\n/**\n * Run some shared teardown after each of the specs in the describe in which it is called.\n * @param action Function that contains the code to teardown your specs.\n * @param timeout Custom timeout for an async afterEach.\n */\ndeclare function afterEach(action: jasmine.ImplementationCallback, timeout?: number): void;\n\n/**\n * Run some shared setup once before all of the specs in the describe are run.\n * Note: Be careful, sharing the setup from a beforeAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail.\n * @param action Function that contains the code to setup your specs.\n * @param timeout Custom timeout for an async beforeAll.\n */\ndeclare function beforeAll(action: jasmine.ImplementationCallback, timeout?: number): void;\n\n/**\n * Run some shared teardown once after all of the specs in the describe are run.\n * Note: Be careful, sharing the teardown from a afterAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail.\n * @param action Function that contains the code to teardown your specs.\n * @param timeout Custom timeout for an async afterAll\n */\ndeclare function afterAll(action: jasmine.ImplementationCallback, timeout?: number): void;\n\n/**\n * Create an expectation for a spec.\n * @checkReturnValue see https://tsetse.info/check-return-value\n * @param spy\n */\ndeclare function expect<T extends jasmine.Func>(spy: T | jasmine.Spy<T>): jasmine.FunctionMatchers<T>;\n\n/**\n * Create an expectation for a spec.\n * @checkReturnValue see https://tsetse.info/check-return-value\n * @param actual\n */\ndeclare function expect<T>(actual: ArrayLike<T>): jasmine.ArrayLikeMatchers<T>;\n\n/**\n * Create an expectation for a spec.\n * @checkReturnValue see https://tsetse.info/check-return-value\n * @param actual Actual computed value to test expectations against.\n */\ndeclare function expect<T>(actual: T): jasmine.Matchers<T>;\n\n/**\n * Create an expectation for a spec.\n */\ndeclare function expect(): jasmine.NothingMatcher;\n\n/**\n * Create an asynchronous expectation for a spec. Note that the matchers\n * that are provided by an asynchronous expectation all return promises\n * which must be either returned from the spec or waited for using `await`\n * in order for Jasmine to associate them with the correct spec.\n * @checkReturnValue see https://tsetse.info/check-return-value\n * @param actual Actual computed value to test expectations against.\n */\ndeclare function expectAsync<T, U>(actual: T | PromiseLike<T>): jasmine.AsyncMatchers<T, U>;\n\n/**\n * Explicitly mark a spec as failed.\n * @param e Reason for the failure\n */\ndeclare function fail(e?: any): void;\n\n/**\n * Action method that should be called when the async work is complete.\n */\ninterface DoneFn extends Function {\n    (): void;\n\n    /** fails the spec and indicates that it has completed. If the message is an Error, Error.message is used */\n    fail: (message?: Error | string) => void;\n}\n\n/**\n * Install a spy onto an existing object.\n * @param object The object upon which to install the `Spy`.\n * @param method The name of the method to replace with a `Spy`.\n */\ndeclare function spyOn<T, K extends keyof T = keyof T>(\n    object: T,\n    method: T[K] extends Function ? K : never,\n): jasmine.Spy<\n    T[K] extends jasmine.Func ? T[K] : T[K] extends { new (...args: infer A): infer V } ? (...args: A) => V : never\n>;\n\n/**\n * Install a spy on a property installed with `Object.defineProperty` onto an existing object.\n * @param object The object upon which to install the `Spy`.\n * @param property The name of the property to replace with a `Spy`.\n * @param accessType The access type (get|set) of the property to `Spy` on.\n */\ndeclare function spyOnProperty<T, K extends keyof T = keyof T>(\n    object: T, property: K, accessType?: \"get\"): jasmine.Spy<(this: T) => T[K]>;\ndeclare function spyOnProperty<T, K extends keyof T = keyof T>(\n    object: T, property: K, accessType: \"set\"): jasmine.Spy<(this: T, value: T[K]) => void>;\n\n/**\n * Installs spies on all writable and configurable properties of an object.\n * @param object The object upon which to install the `Spy`s.\n * @param includeNonEnumerable Whether or not to add spies to non-enumerable properties.\n */\ndeclare function spyOnAllFunctions<T>(object: T, includeNonEnumerable?: boolean): jasmine.SpyObj<T>;\n\ndeclare namespace jasmine {\n    type Func = (...args: any[]) => any;\n\n    // Use trick with prototype to allow abstract classes.\n    // More info: https://stackoverflow.com/a/38642922/2009373\n    type Constructor = Function & { prototype: any };\n\n    type ImplementationCallback = (() => PromiseLike<any>) | (() => void) | ((done: DoneFn) => void);\n\n    type ExpectedRecursive<T> =\n        | T\n        | ObjectContaining<T>\n        | AsymmetricMatcher<any>\n        | {\n              [K in keyof T]: ExpectedRecursive<T[K]> | Any;\n          };\n    type Expected<T> =\n        | T\n        | ObjectContaining<T>\n        | AsymmetricMatcher<any>\n        | Any\n        | Spy\n        | {\n              [K in keyof T]: ExpectedRecursive<T[K]>;\n          };\n    type SpyObjMethodNames<T = undefined> = T extends undefined\n        ? ReadonlyArray<string> | { [methodName: string]: any }\n        : ReadonlyArray<keyof T> | { [P in keyof T]?: T[P] extends Func ? ReturnType<T[P]> : any };\n\n    type SpyObjPropertyNames<T = undefined> = T extends undefined\n        ? ReadonlyArray<string> | { [propertyName: string]: any }\n        : ReadonlyArray<keyof T> | { [P in keyof T]?: T[P] };\n\n    /**\n     * Configuration that can be used when configuring Jasmine via {@link jasmine.Env.configure}\n     */\n    interface Configuration {\n        /**\n         * Whether to randomize spec execution order\n         * @since 3.3.0\n         * @default true\n         */\n        random?: boolean | undefined;\n        /**\n         * Seed to use as the basis of randomization.\n         * Null causes the seed to be determined randomly at the start of execution.\n         * @since 3.3.0\n         * @default null\n         */\n        seed?: number | string | null | undefined;\n        /**\n         * Whether to stop execution of the suite after the first spec failure\n         * @since 3.9.0\n         * @default false\n         */\n        stopOnSpecFailure?: boolean | undefined;\n        /**\n         * Whether to fail the spec if it ran no expectations. By default\n         * a spec that ran no expectations is reported as passed. Setting this\n         * to true will report such spec as a failure.\n         * @since 3.5.0\n         * @default false\n         */\n        failSpecWithNoExpectations?: boolean | undefined;\n        /**\n         * Whether to cause specs to only have one expectation failure.\n         * @since 3.3.0\n         * @default false\n         */\n        stopSpecOnExpectationFailure?: boolean | undefined;\n        /**\n         * Function to use to filter specs\n         * @since 3.3.0\n         * @default A function that always returns true.\n         */\n        specFilter?: SpecFilter | undefined;\n        /**\n         * Whether or not reporters should hide disabled specs from their output.\n         * Currently only supported by Jasmine's HTMLReporter\n         * @since 3.3.0\n         * @default false\n         */\n        hideDisabled?: boolean | undefined;\n        /**\n         * Set to provide a custom promise library that Jasmine will use if it needs\n         * to create a promise. If not set, it will default to whatever global Promise\n         * library is available (if any).\n         * @since 3.5.0\n         * @default undefined\n         */\n        Promise?: typeof Promise | undefined;\n        /**\n         * Clean closures when a suite is done running (done by clearing the stored function reference).\n         * This prevents memory leaks, but you won't be able to run jasmine multiple times.\n         * @since 3.10.0\n         * @default true\n         */\n        autoCleanClosures?: boolean | undefined;\n    }\n\n    /** @deprecated Please use `Configuration` instead of `EnvConfiguration`. */\n    type EnvConfiguration = Configuration;\n\n    function clock(): Clock;\n    /**\n     * @deprecated Private method that may be changed or removed in the future\n     */\n    function DiffBuilder(): DiffBuilder;\n\n    /**\n     * That will succeed if the actual value being compared is an instance of the specified class/constructor.\n     */\n    function any(aclass: Constructor | Symbol): AsymmetricMatcher<any>;\n\n    /**\n     * That will succeed if the actual value being compared is not `null` and not `undefined`.\n     */\n    function anything(): AsymmetricMatcher<any>;\n\n    /**\n     * That will succeed if the actual value being compared is `true` or anything truthy.\n     * @since 3.1.0\n     */\n    function truthy(): AsymmetricMatcher<any>;\n\n    /**\n     * That will succeed if the actual value being compared is  `null`, `undefined`, `0`, `false` or anything falsey.\n     * @since 3.1.0\n     */\n    function falsy(): AsymmetricMatcher<any>;\n\n    /**\n     * That will succeed if the actual value being compared is empty.\n     * @since 3.1.0\n     */\n    function empty(): AsymmetricMatcher<any>;\n\n    /**\n     * That will succeed if the actual value being compared is not empty.\n     * @since 3.1.0\n     */\n    function notEmpty(): AsymmetricMatcher<any>;\n\n    function arrayContaining<T>(sample: ArrayLike<T>): ArrayContaining<T>;\n    function arrayWithExactContents<T>(sample: ArrayLike<T>): ArrayContaining<T>;\n    function objectContaining<T>(sample: { [K in keyof T]?: ExpectedRecursive<T[K]> }): ObjectContaining<T>;\n    function mapContaining<K, V>(sample: Map<K, V>): AsymmetricMatcher<Map<K, V>>;\n    function setContaining<T>(sample: Set<T>): AsymmetricMatcher<Set<T>>;\n\n    function setDefaultSpyStrategy<Fn extends Func = Func>(fn?: (and: SpyAnd<Fn>) => void): void;\n    function addSpyStrategy<Fn extends Func = Func>(name: string, factory: Fn): void;\n    function createSpy<Fn extends Func>(name?: string, originalFn?: Fn): Spy<Fn>;\n    function createSpyObj(baseName: string, methodNames: SpyObjMethodNames, propertyNames?: SpyObjPropertyNames): any;\n    function createSpyObj<T>(\n        baseName: string,\n        methodNames: SpyObjMethodNames<T>,\n        propertyNames?: SpyObjPropertyNames<T>,\n    ): SpyObj<T>;\n    function createSpyObj(methodNames: SpyObjMethodNames, propertyNames?: SpyObjPropertyNames): any;\n    function createSpyObj<T>(methodNames: SpyObjMethodNames<T>, propertyNames?: SpyObjPropertyNames<T>): SpyObj<T>;\n\n    function getEnv(): Env;\n    function debugLog(msg: string): void;\n\n    function addCustomEqualityTester(equalityTester: CustomEqualityTester): void;\n\n    /**\n     * Add a custom object formatter for the current scope of specs.\n     * Note: This is only callable from within a beforeEach, it, or beforeAll.\n     * @since 3.6.0\n     * @see https://jasmine.github.io/tutorials/custom_object_formatters\n     */\n    function addCustomObjectFormatter(formatter: CustomObjectFormatter): void;\n\n    function addMatchers(matchers: CustomMatcherFactories): void;\n    function addAsyncMatchers(matchers: CustomAsyncMatcherFactories): void;\n\n    function stringMatching(str: string | RegExp): AsymmetricMatcher<string>;\n\n    function stringContaining(str: string | RegExp): AsymmetricMatcher<string>;\n    /**\n     * @deprecated Private method that may be changed or removed in the future\n     */\n    function formatErrorMsg(domain: string, usage: string): (msg: string) => string;\n\n    interface Any extends AsymmetricMatcher<any> {\n        new (expectedClass: any): any;\n        jasmineToString(prettyPrint: (value: any) => string): string;\n    }\n\n    interface AsymmetricMatcher<TValue> {\n        asymmetricMatch(other: TValue, matchersUtil?: MatchersUtil): boolean;\n        jasmineToString?(prettyPrint: (value: any) => string): string;\n    }\n\n    // taken from TypeScript lib.core.es6.d.ts, applicable to CustomMatchers.contains()\n    interface ArrayLike<T> {\n        length: number;\n        [n: number]: T;\n    }\n\n    interface ArrayContaining<T> extends AsymmetricMatcher<any> {\n        new?(sample: ArrayLike<T>): ArrayLike<T>;\n        jasmineToString(prettyPrint: (value: any) => string): string;\n    }\n\n    interface ObjectContaining<T> extends AsymmetricMatcher<T> {\n        new?(sample: { [K in keyof T]?: any }): { [K in keyof T]?: any };\n\n        jasmineToString?(prettyPrint: (value: any) => string): string;\n    }\n\n    interface Clock {\n        install(): Clock;\n        uninstall(): void;\n        /** Calls to any registered callback are triggered when the clock is ticked forward via the jasmine.clock().tick function, which takes a number of milliseconds. */\n        tick(ms: number): void;\n        mockDate(date?: Date): void;\n        withMock(func: () => void): void;\n    }\n\n    type CustomEqualityTester = (first: any, second: any) => boolean | void;\n\n    type CustomObjectFormatter = (value: unknown) => string | undefined;\n\n    interface CustomMatcher {\n        compare<T>(actual: T, expected: T, ...args: any[]): CustomMatcherResult;\n        compare(actual: any, ...expected: any[]): CustomMatcherResult;\n        negativeCompare?<T>(actual: T, expected: T, ...args: any[]): CustomMatcherResult;\n        negativeCompare?(actual: any, ...expected: any[]): CustomMatcherResult;\n    }\n\n    interface CustomAsyncMatcher {\n        compare<T>(actual: T, expected: T, ...args: any[]): PromiseLike<CustomMatcherResult>;\n        compare(actual: any, ...expected: any[]): PromiseLike<CustomMatcherResult>;\n        negativeCompare?<T>(actual: T, expected: T, ...args: any[]): PromiseLike<CustomMatcherResult>;\n        negativeCompare?(actual: any, ...expected: any[]): PromiseLike<CustomMatcherResult>;\n    }\n\n    type CustomMatcherFactory = (util: MatchersUtil) => CustomMatcher;\n\n    type CustomAsyncMatcherFactory = (util: MatchersUtil) => CustomAsyncMatcher;\n\n    interface CustomMatcherFactories {\n        [name: string]: CustomMatcherFactory;\n    }\n\n    interface CustomAsyncMatcherFactories {\n        [name: string]: CustomAsyncMatcherFactory;\n    }\n\n    interface CustomMatcherResult {\n        pass: boolean;\n        message?: string | undefined;\n    }\n\n    /**\n     * @deprecated Private type that may be changed or removed in the future\n     */\n    interface DiffBuilder {\n        setRoots(actual: any, expected: any): void;\n        recordMismatch(formatter?: (actual: any, expected: any, path?: any, prettyPrinter?: any) => string): void;\n        withPath(pathComponent: string, block: () => void): void;\n        getMessage(): string;\n    }\n\n    interface MatchersUtil {\n        equals(a: any, b: any): boolean;\n        contains<T>(\n            haystack: ArrayLike<T> | string,\n            needle: any\n        ): boolean;\n        /**\n         * @deprecated Private method that may be changed or removed in the future\n         */\n        buildFailureMessage(matcherName: string, isNot: boolean, actual: any, ...expected: any[]): string;\n\n        /**\n         * Formats a value for use in matcher failure messages and similar\n         * contexts, taking into account the current set of custom value\n         * formatters.\n         * @since 3.6.0\n         * @param value The value to pretty-print\n         * @return The pretty-printed value\n         */\n        pp(value: any): string;\n    }\n\n    interface Env {\n        addReporter(reporter: CustomReporter): void;\n        allowRespy(allow: boolean): void;\n        clearReporters(): void;\n        configuration(): Configuration;\n        configure(configuration: Configuration): void;\n        execute(runnablesToRun: Suite[] | null | undefined, onComplete: Func): void;\n        /** @async */\n        execute(runnablesToRun?: Suite[]): PromiseLike<JasmineDoneInfo>;\n        provideFallbackReporter(reporter: CustomReporter): void;\n        /**\n         * Sets a user-defined property that will be provided to reporters as\n         * part of the properties field of SpecResult.\n         * @since 3.6.0\n         */\n        setSpecProperty: typeof setSpecProperty;\n        /**\n         * Sets a user-defined property that will be provided to reporters as\n         * part of the properties field of SuiteResult.\n         * @since 3.6.0\n         */\n        setSuiteProperty: typeof setSuiteProperty;\n        topSuite(): Suite;\n    }\n\n    interface HtmlReporter {\n        new (): any;\n    }\n\n    interface HtmlSpecFilter {\n        new (): any;\n    }\n\n    interface Result {\n        type: string;\n    }\n\n    interface ExpectationResult extends Result {\n        matcherName: string;\n        message: string;\n        stack: string;\n        passed: boolean;\n        expected: any;\n        actual: any;\n    }\n\n    interface DeprecationWarning extends Result {\n        message: string;\n        stack: string;\n    }\n\n    interface Order {\n        new (options: { random: boolean; seed: number | string }): any;\n        random: boolean;\n        seed: number | string;\n        sort<T>(items: T[]): T[];\n    }\n\n    namespace errors {\n        class ExpectationFailed extends Error {\n            constructor();\n\n            stack: any;\n        }\n    }\n\n    interface Matchers<T> {\n        /**\n         * Expect the actual value to be `===` to the expected value.\n         *\n         * @param expected The expected value to compare against.\n         * @example\n         * expect(thing).toBe(realThing);\n         */\n        toBe(expected: Expected<T>): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBe(expected: Expected<T>, expectationFailOutput: any): void;\n\n        /**\n         * Expect the actual value to be equal to the expected, using deep equality comparison.\n         * @param expected Expected value.\n         * @example\n         * expect(bigObject).toEqual({ \"foo\": ['bar', 'baz'] });\n         */\n        toEqual(expected: Expected<T>): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toEqual(expected: Expected<T>, expectationFailOutput: any): void;\n\n        /**\n         * Expect the actual value to match a regular expression.\n         * @param expected Value to look for in the string.\n         * @example\n         * expect(\"my string\").toMatch(/string$/);\n         * expect(\"other string\").toMatch(\"her\");\n         */\n        toMatch(expected: string | RegExp): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toMatch(expected: string | RegExp, expectationFailOutput: any): void;\n\n        toBeDefined(): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeDefined(expectationFailOutput: any): void;\n        toBeUndefined(): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeUndefined(expectationFailOutput: any): void;\n        toBeNull(): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeNull(expectationFailOutput: any): void;\n        toBeNaN(): void;\n        toBeTruthy(): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeTruthy(expectationFailOutput: any): void;\n        toBeFalsy(): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeFalsy(expectationFailOutput: any): void;\n        toBeTrue(): void;\n        toBeFalse(): void;\n        toHaveBeenCalled(): void;\n        toHaveBeenCalledBefore(expected: Func): void;\n        toHaveBeenCalledWith(...params: any[]): void;\n        toHaveBeenCalledOnceWith(...params: any[]): void;\n        toHaveBeenCalledTimes(expected: number): void;\n        toContain(expected: any): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toContain(expected: any, expectationFailOutput: any): void;\n        toBeLessThan(expected: number): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeLessThan(expected: number, expectationFailOutput: any): void;\n        toBeLessThanOrEqual(expected: number): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeLessThanOrEqual(expected: number, expectationFailOutput: any): void;\n        toBeGreaterThan(expected: number): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeGreaterThan(expected: number, expectationFailOutput: any): void;\n        toBeGreaterThanOrEqual(expected: number): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeGreaterThanOrEqual(expected: number, expectationFailOutput: any): void;\n        toBeCloseTo(expected: number, precision?: any): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeCloseTo(expected: number, precision: any, expectationFailOutput: any): void;\n        toThrow(expected?: any): void;\n        toThrowError(message?: string | RegExp): void;\n        toThrowError(expected?: new (...args: any[]) => Error, message?: string | RegExp): void;\n        toThrowMatching(predicate: (thrown: any) => boolean): void;\n        toBeNegativeInfinity(): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeNegativeInfinity(expectationFailOutput: any): void;\n        toBePositiveInfinity(): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBePositiveInfinity(expectationFailOutput: any): void;\n        toBeInstanceOf(expected: Constructor): void;\n\n        /**\n         * Expect the actual value to be a DOM element that has the expected class.\n         * @since 3.0.0\n         * @param expected The class name to test for.\n         * @example\n         * var el = document.createElement('div');\n         * el.className = 'foo bar baz';\n         * expect(el).toHaveClass('bar');\n         */\n        toHaveClass(expected: string): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toHaveClass(expected: string, expectationFailOutput: any): void;\n\n        /**\n         * Expect the actual size to be equal to the expected, using array-like\n         * length or object keys size.\n         * @since 3.6.0\n         * @param expected The expected size\n         * @example\n         * array = [1,2];\n         * expect(array).toHaveSize(2);\n         */\n        toHaveSize(expected: number): void;\n\n        /**\n         * {@link expect} the actual (a {@link SpyObj}) spies to have been called.\n         * @since 4.1.0\n         * @example\n         * expect(mySpyObj).toHaveSpyInteractions();\n         * expect(mySpyObj).not.toHaveSpyInteractions();\n         */\n        toHaveSpyInteractions(): void;\n\n        /**\n         * Add some context for an expect.\n         * @param message Additional context to show when the matcher fails\n         * @checkReturnValue see https://tsetse.info/check-return-value\n         */\n        withContext(message: string): Matchers<T>;\n\n        /**\n         * Invert the matcher following this expect.\n         */\n        not: Matchers<T>;\n    }\n\n    interface ArrayLikeMatchers<T> extends Matchers<ArrayLike<T>> {\n        /**\n         * Expect the actual value to be `===` to the expected value.\n         *\n         * @param expected The expected value to compare against.\n         * @example\n         * expect(thing).toBe(realThing);\n         */\n        toBe(expected: Expected<ArrayLike<T>> | ArrayContaining<T>): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBe(expected: Expected<ArrayLike<T>> | ArrayContaining<T>, expectationFailOutput: any): void;\n\n        /**\n         * Expect the actual value to be equal to the expected, using deep equality comparison.\n         * @param expected Expected value.\n         * @example\n         * expect(bigObject).toEqual({ \"foo\": ['bar', 'baz'] });\n         */\n        toEqual(expected: Expected<ArrayLike<T>> | ArrayContaining<T>): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toEqual(expected: Expected<ArrayLike<T>> | ArrayContaining<T>, expectationFailOutput: any): void;\n\n        toContain(expected: Expected<T>): void;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toContain(expected: Expected<T>, expectationFailOutput: any): void;\n\n        /**\n         * Add some context for an expect.\n         * @param message Additional context to show when the matcher fails.\n         * @checkReturnValue see https://tsetse.info/check-return-value\n         */\n        withContext(message: string): ArrayLikeMatchers<T>;\n\n        /**\n         * Invert the matcher following this expect.\n         */\n        not: ArrayLikeMatchers<T>;\n    }\n\n    type MatchableArgs<Fn> = Fn extends (...args: infer P) => any ? { [K in keyof P]: Expected<P[K]> } : never;\n\n    interface FunctionMatchers<Fn extends Func> extends Matchers<any> {\n        /**\n         * Expects the actual (a spy) to have been called with the particular arguments at least once\n         * @param params The arguments to look for\n         */\n        toHaveBeenCalledWith(...params: MatchableArgs<Fn>): void;\n\n        /**\n         * Expects the actual (a spy) to have been called exactly once, and exactly with the particular arguments\n         * @param params The arguments to look for\n         */\n        toHaveBeenCalledOnceWith(...params: MatchableArgs<Fn>): void;\n\n        /**\n         * Add some context for an expect.\n         * @param message Additional context to show when the matcher fails.\n         * @checkReturnValue see https://tsetse.info/check-return-value\n         */\n        withContext(message: string): FunctionMatchers<Fn>;\n\n        /**\n         * Invert the matcher following this expect.\n         */\n        not: FunctionMatchers<Fn>;\n    }\n\n    interface NothingMatcher {\n        nothing(): void;\n    }\n\n    interface AsyncMatchers<T, U> {\n        /**\n         * Expect a promise to be pending, i.e. the promise is neither resolved nor rejected.\n         */\n        toBePending(): PromiseLike<void>;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBePending(expectationFailOutput: any): PromiseLike<void>;\n\n        /**\n         * Expect a promise to be resolved.\n         */\n        toBeResolved(): PromiseLike<void>;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeResolved(expectationFailOutput: any): PromiseLike<void>;\n\n        /**\n         * Expect a promise to be rejected.\n         */\n        toBeRejected(): PromiseLike<void>;\n        /**\n         * @deprecated expectationFailOutput is deprecated. Use withContext instead.\n         */\n        // tslint:disable-next-line unified-signatures\n        toBeRejected(expectationFailOutput: any): PromiseLike<void>;\n\n        /**\n         * Expect a promise to be resolved to a value equal to the expected, using deep equality comparison.\n         * @param expected Value that the promise is expected to resolve to.\n         */\n        toBeResolvedTo(expected: Expected<T>): PromiseLike<void>;\n\n        /**\n         * Expect a promise to be rejected with a value equal to the expected, using deep equality comparison.\n         * @param expected Value that the promise is expected to be rejected with.\n         */\n        toBeRejectedWith(expected: Expected<U>): PromiseLike<void>;\n\n        /**\n         * Expect a promise to be rejected with a value matched to the expected.\n         * @param expected Error constructor the object that was thrown needs to be an instance of. If not provided, Error will be used.\n         * @param message The message that should be set on the thrown Error.\n         */\n        toBeRejectedWithError(expected?: new (...args: any[]) => Error, message?: string | RegExp): PromiseLike<void>;\n\n        /**\n         * Expect a promise to be rejected with a value matched to the expected.\n         * @param message The message that should be set on the thrown Error.\n         */\n        toBeRejectedWithError(message?: string | RegExp): PromiseLike<void>;\n\n        /**\n         * Add some context for an expect.\n         * @param message Additional context to show when the matcher fails.\n         * @checkReturnValue see https://tsetse.info/check-return-value\n         */\n        withContext(message: string): AsyncMatchers<T, U>;\n\n        /**\n         * Fail as soon as possible if the actual is pending. Otherwise evaluate the matcher.\n         */\n        already: AsyncMatchers<T, U>;\n\n        /**\n         * Invert the matcher following this expect.\n         */\n        not: AsyncMatchers<T, U>;\n    }\n\n    interface JasmineStartedInfo {\n        totalSpecsDefined: number;\n        order: Order;\n    }\n\n    interface CustomReportExpectation {\n        matcherName: string;\n        message: string;\n        passed: boolean;\n        stack: string;\n    }\n\n    interface FailedExpectation extends CustomReportExpectation {\n        actual: string;\n        expected: string;\n    }\n\n    interface PassedExpectation extends CustomReportExpectation {}\n\n    interface DeprecatedExpectation {\n        message: string;\n    }\n\n    interface SuiteResult {\n        /**\n         * The unique id of this spec.\n         */\n        id: string;\n\n        /**\n         * The description passed to the {@link it} that created this spec.\n         */\n        description: string;\n\n        /**\n         * The full description including all ancestors of this spec.\n         */\n        fullName: string;\n\n        /**\n         * The list of expectations that failed during execution of this spec.\n         */\n        failedExpectations: FailedExpectation[];\n\n        /**\n         * The list of deprecation warnings that occurred during execution this spec.\n         */\n        deprecationWarnings: DeprecatedExpectation[];\n\n        /**\n         * Once the spec has completed, this string represents the pass/fail status of this spec.\n         */\n        status: string;\n\n        /**\n         * The time in ms used by the spec execution, including any before/afterEach.\n         */\n        duration: number | null;\n\n        /**\n         * User-supplied properties, if any, that were set using {@link Env.setSpecProperty}\n         */\n        properties: { [key: string]: unknown } | null;\n    }\n\n    interface SpecResult extends SuiteResult {\n        /**\n         * The list of expectations that passed during execution of this spec.\n         */\n        passedExpectations: PassedExpectation[];\n\n        /**\n         * If the spec is pending, this will be the reason.\n         */\n        pendingReason: string;\n\n        debugLogs: DebugLogEntry[] | null;\n    }\n\n    interface DebugLogEntry {\n        message: String;\n        timestamp: number;\n    }\n\n    interface JasmineDoneInfo {\n        overallStatus: string;\n        totalTime: number;\n        incompleteReason: string;\n        order: Order;\n        failedExpectations: ExpectationResult[];\n        deprecationWarnings: ExpectationResult[];\n    }\n\n    /** @deprecated use JasmineStartedInfo instead */\n    type SuiteInfo = JasmineStartedInfo;\n\n    /** @deprecated use SuiteResult or SpecResult instead */\n    type CustomReporterResult = SuiteResult & SpecResult;\n\n    /** @deprecated use JasmineDoneInfo instead */\n    type RunDetails = JasmineDoneInfo;\n\n    interface CustomReporter {\n        jasmineStarted?(suiteInfo: JasmineStartedInfo, done?: () => void): void | Promise<void>;\n        suiteStarted?(result: SuiteResult, done?: () => void): void | Promise<void>;\n        specStarted?(result: SpecResult, done?: () => void): void | Promise<void>;\n        specDone?(result: SpecResult, done?: () => void): void | Promise<void>;\n        suiteDone?(result: SuiteResult, done?: () => void): void | Promise<void>;\n        jasmineDone?(runDetails: JasmineDoneInfo, done?: () => void): void | Promise<void>;\n    }\n\n    interface SpecFilter {\n        /**\n         * A function that takes a spec and returns true if it should be executed or false if it should be skipped.\n         * @param spec The spec that the filter is being applied to\n         */\n        (spec: Spec): boolean;\n    }\n\n    /** @deprecated Please use `SpecFilter` instead of `SpecFunction`. */\n    type SpecFunction = (spec?: Spec) => void;\n\n    interface Spec {\n        new (attrs: any): any;\n\n        readonly id: number;\n        env: Env;\n        readonly description: string;\n        getFullName(): string;\n    }\n\n    interface Suite extends Spec {\n        parentSuite: Suite;\n        children: Array<Spec | Suite>;\n    }\n\n    interface Spy<Fn extends Func = Func> {\n        (...params: Parameters<Fn>): ReturnType<Fn>;\n\n        and: SpyAnd<Fn>;\n        calls: Calls<Fn>;\n        withArgs(...args: MatchableArgs<Fn>): Spy<Fn>;\n    }\n\n    type SpyObj<T> = T &\n        {\n            [K in keyof T]: T[K] extends Func ? T[K] & Spy<T[K]> : T[K];\n        };\n\n    /**\n     * Determines whether the provided function is a Jasmine spy.\n     * @since 2.0.0\n     * @param putativeSpy The function to check.\n     */\n    function isSpy(putativeSpy: Func): putativeSpy is Spy;\n\n    /**\n     * It's like SpyObj, but doesn't verify argument/return types for functions.\n     * Useful if TS cannot correctly infer type for complex objects.\n     */\n    type NonTypedSpyObj<T> = SpyObj<{ [K in keyof T]: T[K] extends Func ? Func : T[K] }>;\n\n    /**\n     * Obtains the promised type that a promise-returning function resolves to.\n     */\n    type PromisedReturnType<Fn extends Func> = Fn extends (...args: any[]) => PromiseLike<infer TResult>\n        ? TResult\n        : never;\n\n    /**\n     * Obtains the type that a promise-returning function can be rejected with.\n     * This is so we can use .and.rejectWith() only for functions that return a promise.\n     */\n    type PromisedRejectType<Fn extends Function> = Fn extends (...args: any[]) => PromiseLike<unknown> ? any : never;\n\n    interface SpyAnd<Fn extends Func> {\n        identity: string;\n\n        /** By chaining the spy with and.callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation. */\n        callThrough(): Spy<Fn>;\n        /** By chaining the spy with and.returnValue, all calls to the function will return a specific value. */\n        returnValue(val: ReturnType<Fn>): Spy<Fn>;\n        /** By chaining the spy with and.returnValues, all calls to the function will return specific values in order until it reaches the end of the return values list. */\n        returnValues(...values: Array<ReturnType<Fn>>): Spy<Fn>;\n        /** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied function. */\n        callFake(fn: Fn): Spy<Fn>;\n        /** Tell the spy to return a promise resolving to the specified value when invoked. */\n        resolveTo(val?: PromisedReturnType<Fn>): Spy<Fn>;\n        /** Tell the spy to return a promise rejecting with the specified value when invoked. */\n        rejectWith(val?: PromisedRejectType<Fn>): Spy<Fn>;\n        /** By chaining the spy with and.throwError, all calls to the spy will throw the specified value. */\n        throwError(msg: string | Error): Spy;\n        /** When a calling strategy is used for a spy, the original stubbing behavior can be returned at any time with and.stub. */\n        stub(): Spy;\n    }\n\n    interface Calls<Fn extends Func> {\n        /** By chaining the spy with calls.any(), will return false if the spy has not been called at all, and then true once at least one call happens. */\n        any(): boolean;\n        /** By chaining the spy with calls.count(), will return the number of times the spy was called */\n        count(): number;\n        /** By chaining the spy with calls.argsFor(), will return the arguments passed to call number index */\n        argsFor(index: number): Parameters<Fn>;\n        /** By chaining the spy with calls.allArgs(), will return the arguments to all calls */\n        allArgs(): ReadonlyArray<Parameters<Fn>>;\n        /** By chaining the spy with calls.all(), will return the context (the this) and arguments passed all calls */\n        all(): ReadonlyArray<CallInfo<Fn>>;\n        /** By chaining the spy with calls.mostRecent(), will return the context (the this) and arguments for the most recent call */\n        mostRecent(): CallInfo<Fn>;\n        /** By chaining the spy with calls.first(), will return the context (the this) and arguments for the first call */\n        first(): CallInfo<Fn>;\n        /** By chaining the spy with calls.reset(), will clears all tracking for a spy */\n        reset(): void;\n        /** Set this spy to do a shallow clone of arguments passed to each invocation. */\n        saveArgumentsByValue(): void;\n        /** Get the \"this\" object that was passed to a specific invocation of this spy. */\n        thisFor(index: number): ThisType<Fn>;\n    }\n\n    interface CallInfo<Fn extends Func> {\n        /** The context (the this) for the call */\n        object: ThisType<Fn>;\n        /** All arguments passed to the call */\n        args: Parameters<Fn>;\n        /** The return value of the call */\n        returnValue: ReturnType<Fn>;\n    }\n\n    interface Util {\n        inherit(childClass: Function, parentClass: Function): any;\n        formatException(e: any): any;\n        htmlEscape(str: string): string;\n        argsToArray(args: any): any;\n        extend(destination: any, source: any): any;\n    }\n\n    interface JsApiReporter extends CustomReporter {\n        new (): any;\n\n        started: boolean;\n        finished: boolean;\n        runDetails: JasmineDoneInfo;\n\n        status(): string;\n        suiteResults(index: number, length: number): SuiteResult[];\n        specResults(index: number, length: number): SpecResult[];\n        suites(): { [id: string]: SuiteResult };\n        specs(): SpecResult[];\n        executionTime(): number;\n    }\n\n    interface Jasmine {\n        Spec: Spec;\n        clock: Clock;\n        util: Util;\n    }\n\n    var HtmlReporter: HtmlReporter;\n    var HtmlSpecFilter: HtmlSpecFilter;\n\n    /**\n     * Default number of milliseconds Jasmine will wait for an asynchronous spec to complete.\n     */\n    var DEFAULT_TIMEOUT_INTERVAL: number;\n\n    /**\n     * Maximum number of array elements to display when pretty printing objects.\n     * This will also limit the number of keys and values displayed for an object.\n     * Elements past this number will be ellipised.\n     */\n    var MAX_PRETTY_PRINT_ARRAY_LENGTH: number;\n\n    /**\n     * Maximum number of characters to display when pretty printing objects.\n     * Characters past this number will be ellipised.\n     */\n    var MAX_PRETTY_PRINT_CHARS: number;\n\n    /**\n     * Maximum object depth the pretty printer will print to.\n     * Set this to a lower value to speed up pretty printing if you have large objects.\n     */\n    var MAX_PRETTY_PRINT_DEPTH: number;\n\n    var version: string;\n\n    interface JasmineOptions {\n        /**\n         * The path to the project's base directory. This can be absolute or relative\n         * to the current working directory. If it isn't specified, the current working\n         * directory will be used.\n         */\n        projectBaseDir?: string;\n    }\n\n    interface JasmineConfig {\n        /**\n         * Whether to fail specs that contain no expectations.\n         * @default false\n         */\n        failSpecWithNoExpectations?: boolean;\n        /**\n         * An array of helper file paths or globs that match helper files. Each path or\n         * glob will be evaluated relative to the spec directory. Helpers are loaded before specs.\n         */\n        helpers?: string[];\n        /**\n         * Specifies how to load files with names ending in .js. Valid values are\n         * \"require\" and \"import\". \"import\" should be safe in all cases, and is\n         * required if your project contains ES modules with filenames ending in .js.\n         * @default \"require\"\n         */\n        jsLoader?: \"require\" | \"import\";\n        /**\n         * Whether to run specs in a random order.\n         */\n        random?: boolean;\n        /**\n         * An array of module names to load via require() at the start of execution.\n         */\n        requires?: string[];\n        /**\n         * The directory that spec files are contained in, relative to the project base directory.\n         */\n        spec_dir?: string;\n        /**\n         * An array of spec file paths or globs that match helper files. Each path\n         * or glob will be evaluated relative to the spec directory.\n         */\n        spec_files?: string[];\n        /**\n         * Whether to stop suite execution on the first spec failure.\n         */\n        stopOnSpecFailure?: boolean;\n        /**\n         * Whether to stop each spec on the first expectation failure.\n         */\n        stopSpecOnExpectationFailure?: boolean;\n    }\n\n    interface DefaultReporterOptions {\n        timer?: any;\n        print?: (...args: any[]) => void;\n        showColors?: boolean;\n        jasmineCorePath?: string;\n    }\n}\n\ndeclare module \"jasmine\" {\n    class jasmine {\n        jasmine: jasmine.Jasmine;\n        env: jasmine.Env;\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        reportersCount: number;\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        reporter: jasmine.CustomReporter;\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        showingColors: boolean;\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        projectBaseDir: string;\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        specDir: string;\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        specFiles: string[];\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        helperFiles: string[];\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        requires: string[];\n        /**\n         * @deprecated Private property that may be changed or removed in the future\n         */\n        defaultReporterConfigured: boolean;\n\n        constructor(options?: jasmine.JasmineOptions);\n        addMatchers(matchers: jasmine.CustomMatcherFactories): void;\n        /**\n         * Add a custom reporter to the Jasmine environment.\n         */\n        addReporter(reporter: jasmine.CustomReporter): void;\n        /**\n         * Adds a spec file to the list that will be loaded when the suite is executed.\n         */\n        addSpecFile(filePath: string): void;\n        addMatchingSpecFiles(patterns: string[]): void;\n        addHelperFile(filePath: string): void;\n        addMatchingHelperFiles(patterns: string[]): void;\n        /**\n         * @deprecated Private method that may be changed or removed in the future\n         */\n        addRequires(files: string[]): void;\n        /**\n         * Configure the default reporter.\n         */\n        configureDefaultReporter(options: jasmine.DefaultReporterOptions): void;\n        execute(files?: string[], filterString?: string): Promise<jasmine.JasmineDoneInfo>;\n        exitOnCompletion: boolean;\n        loadConfig(config: jasmine.JasmineConfig): void;\n        loadConfigFile(configFilePath?: string): void;\n        /**\n         * @deprecated Private method that may be changed or removed in the future\n         */\n        loadHelpers(): Promise<void>;\n        /**\n         * @deprecated Private method that may be changed or removed in the future\n         */\n        loadSpecs(): Promise<void>;\n        /**\n         * @deprecated Private method that may be changed or removed in the future\n         */\n        loadRequires(): void;\n\n        /**\n         * Provide a fallback reporter if no other reporters have been specified.\n         */\n        provideFallbackReporter(reporter: jasmine.CustomReporter): void;\n        /**\n         * Clears all registered reporters.\n         */\n        clearReporters(): void;\n        /**\n         * Sets whether to randomize the order of specs.\n         */\n        randomizeTests(value: boolean): void;\n        /**\n         * Sets the random seed.\n         */\n        seed(value: number): void;\n        /**\n         * Sets whether to show colors in the console reporter.\n         */\n        showColors(value: boolean): void;\n        stopSpecOnExpectationFailure(value: boolean): void;\n        stopOnSpecFailure(value: boolean): void;\n        static ConsoleReporter(): any;\n\n        /**\n         * The version of jasmine-core in use\n         */\n        coreVersion(): string;\n    }\n    export = jasmine;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/src/jasmine.js",
    "content": "/*\nCopyright (c) 2008-2022 Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\n// eslint-disable-next-line no-unused-vars\nvar getJasmineRequireObj = (function(jasmineGlobal) {\n  var jasmineRequire;\n\n  if (\n    typeof module !== 'undefined' &&\n    module.exports &&\n    typeof exports !== 'undefined'\n  ) {\n    if (typeof global !== 'undefined') {\n      jasmineGlobal = global;\n    } else {\n      jasmineGlobal = {};\n    }\n    jasmineRequire = exports;\n  } else {\n    if (\n      typeof window !== 'undefined' &&\n      typeof window.toString === 'function' &&\n      window.toString() === '[object GjsGlobal]'\n    ) {\n      jasmineGlobal = window;\n    }\n    jasmineRequire = jasmineGlobal.jasmineRequire = {};\n  }\n\n  function getJasmineRequire() {\n    return jasmineRequire;\n  }\n\n  getJasmineRequire().core = function(jRequire) {\n    var j$ = {};\n\n    jRequire.base(j$, jasmineGlobal);\n    j$.util = jRequire.util(j$);\n    j$.errors = jRequire.errors();\n    j$.formatErrorMsg = jRequire.formatErrorMsg();\n    j$.Any = jRequire.Any(j$);\n    j$.Anything = jRequire.Anything(j$);\n    j$.CallTracker = jRequire.CallTracker(j$);\n    j$.MockDate = jRequire.MockDate(j$);\n    j$.getClearStack = jRequire.clearStack(j$);\n    j$.Clock = jRequire.Clock();\n    j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);\n    j$.Deprecator = jRequire.Deprecator(j$);\n    j$.Env = jRequire.Env(j$);\n    j$.StackTrace = jRequire.StackTrace(j$);\n    j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);\n    j$.ExpectationFilterChain = jRequire.ExpectationFilterChain();\n    j$.Expector = jRequire.Expector(j$);\n    j$.Expectation = jRequire.Expectation(j$);\n    j$.buildExpectationResult = jRequire.buildExpectationResult(j$);\n    j$.JsApiReporter = jRequire.JsApiReporter(j$);\n    j$.makePrettyPrinter = jRequire.makePrettyPrinter(j$);\n    j$.basicPrettyPrinter_ = j$.makePrettyPrinter();\n    j$.MatchersUtil = jRequire.MatchersUtil(j$);\n    j$.ObjectContaining = jRequire.ObjectContaining(j$);\n    j$.ArrayContaining = jRequire.ArrayContaining(j$);\n    j$.ArrayWithExactContents = jRequire.ArrayWithExactContents(j$);\n    j$.MapContaining = jRequire.MapContaining(j$);\n    j$.SetContaining = jRequire.SetContaining(j$);\n    j$.QueueRunner = jRequire.QueueRunner(j$);\n    j$.NeverSkipPolicy = jRequire.NeverSkipPolicy(j$);\n    j$.SkipAfterBeforeAllErrorPolicy = jRequire.SkipAfterBeforeAllErrorPolicy(\n      j$\n    );\n    j$.CompleteOnFirstErrorSkipPolicy = jRequire.CompleteOnFirstErrorSkipPolicy(\n      j$\n    );\n    j$.ReportDispatcher = jRequire.ReportDispatcher(j$);\n    j$.Spec = jRequire.Spec(j$);\n    j$.Spy = jRequire.Spy(j$);\n    j$.SpyFactory = jRequire.SpyFactory(j$);\n    j$.SpyRegistry = jRequire.SpyRegistry(j$);\n    j$.SpyStrategy = jRequire.SpyStrategy(j$);\n    j$.StringMatching = jRequire.StringMatching(j$);\n    j$.StringContaining = jRequire.StringContaining(j$);\n    j$.UserContext = jRequire.UserContext(j$);\n    j$.Suite = jRequire.Suite(j$);\n    j$.Timer = jRequire.Timer();\n    j$.TreeProcessor = jRequire.TreeProcessor();\n    j$.version = jRequire.version();\n    j$.Order = jRequire.Order();\n    j$.DiffBuilder = jRequire.DiffBuilder(j$);\n    j$.NullDiffBuilder = jRequire.NullDiffBuilder(j$);\n    j$.ObjectPath = jRequire.ObjectPath(j$);\n    j$.MismatchTree = jRequire.MismatchTree(j$);\n    j$.GlobalErrors = jRequire.GlobalErrors(j$);\n\n    j$.Truthy = jRequire.Truthy(j$);\n    j$.Falsy = jRequire.Falsy(j$);\n    j$.Empty = jRequire.Empty(j$);\n    j$.NotEmpty = jRequire.NotEmpty(j$);\n\n    j$.matchers = jRequire.requireMatchers(jRequire, j$);\n    j$.asyncMatchers = jRequire.requireAsyncMatchers(jRequire, j$);\n\n    return j$;\n  };\n\n  return getJasmineRequire;\n})(this);\n\ngetJasmineRequireObj().requireMatchers = function(jRequire, j$) {\n  var availableMatchers = [\n      'nothing',\n      'toBe',\n      'toBeCloseTo',\n      'toBeDefined',\n      'toBeInstanceOf',\n      'toBeFalse',\n      'toBeFalsy',\n      'toBeGreaterThan',\n      'toBeGreaterThanOrEqual',\n      'toBeLessThan',\n      'toBeLessThanOrEqual',\n      'toBeNaN',\n      'toBeNegativeInfinity',\n      'toBeNull',\n      'toBePositiveInfinity',\n      'toBeTrue',\n      'toBeTruthy',\n      'toBeUndefined',\n      'toContain',\n      'toEqual',\n      'toHaveSize',\n      'toHaveBeenCalled',\n      'toHaveBeenCalledBefore',\n      'toHaveBeenCalledOnceWith',\n      'toHaveBeenCalledTimes',\n      'toHaveBeenCalledWith',\n      'toHaveClass',\n      'toHaveSpyInteractions',\n      'toMatch',\n      'toThrow',\n      'toThrowError',\n      'toThrowMatching'\n    ],\n    matchers = {};\n\n  for (var i = 0; i < availableMatchers.length; i++) {\n    var name = availableMatchers[i];\n    matchers[name] = jRequire[name](j$);\n  }\n\n  return matchers;\n};\n\ngetJasmineRequireObj().base = function(j$, jasmineGlobal) {\n  j$.unimplementedMethod_ = function() {\n    throw new Error('unimplemented method');\n  };\n\n  /**\n   * Maximum object depth the pretty printer will print to.\n   * Set this to a lower value to speed up pretty printing if you have large objects.\n   * @name jasmine.MAX_PRETTY_PRINT_DEPTH\n   * @default 8\n   * @since 1.3.0\n   */\n  j$.MAX_PRETTY_PRINT_DEPTH = 8;\n  /**\n   * Maximum number of array elements to display when pretty printing objects.\n   * This will also limit the number of keys and values displayed for an object.\n   * Elements past this number will be ellipised.\n   * @name jasmine.MAX_PRETTY_PRINT_ARRAY_LENGTH\n   * @default 50\n   * @since 2.7.0\n   */\n  j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50;\n  /**\n   * Maximum number of characters to display when pretty printing objects.\n   * Characters past this number will be ellipised.\n   * @name jasmine.MAX_PRETTY_PRINT_CHARS\n   * @default 100\n   * @since 2.9.0\n   */\n  j$.MAX_PRETTY_PRINT_CHARS = 1000;\n  /**\n   * Default number of milliseconds Jasmine will wait for an asynchronous spec,\n   * before, or after function to complete. This can be overridden on a case by\n   * case basis by passing a time limit as the third argument to {@link it},\n   * {@link beforeEach}, {@link afterEach}, {@link beforeAll}, or\n   * {@link afterAll}. The value must be no greater than the largest number of\n   * milliseconds supported by setTimeout, which is usually 2147483647.\n   *\n   * While debugging tests, you may want to set this to a large number (or pass\n   * a large number to one of the functions mentioned above) so that Jasmine\n   * does not move on to after functions or the next spec while you're debugging.\n   * @name jasmine.DEFAULT_TIMEOUT_INTERVAL\n   * @default 5000\n   * @since 1.3.0\n   */\n  var DEFAULT_TIMEOUT_INTERVAL = 5000;\n  Object.defineProperty(j$, 'DEFAULT_TIMEOUT_INTERVAL', {\n    get: function() {\n      return DEFAULT_TIMEOUT_INTERVAL;\n    },\n    set: function(newValue) {\n      j$.util.validateTimeout(newValue, 'jasmine.DEFAULT_TIMEOUT_INTERVAL');\n      DEFAULT_TIMEOUT_INTERVAL = newValue;\n    }\n  });\n\n  j$.getGlobal = function() {\n    return jasmineGlobal;\n  };\n\n  /**\n   * Get the currently booted Jasmine Environment.\n   *\n   * @name jasmine.getEnv\n   * @since 1.3.0\n   * @function\n   * @return {Env}\n   */\n  j$.getEnv = function(options) {\n    var env = (j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options));\n    //jasmine. singletons in here (setTimeout blah blah).\n    return env;\n  };\n\n  j$.isArray_ = function(value) {\n    return j$.isA_('Array', value);\n  };\n\n  j$.isObject_ = function(value) {\n    return (\n      !j$.util.isUndefined(value) && value !== null && j$.isA_('Object', value)\n    );\n  };\n\n  j$.isString_ = function(value) {\n    return j$.isA_('String', value);\n  };\n\n  j$.isNumber_ = function(value) {\n    return j$.isA_('Number', value);\n  };\n\n  j$.isFunction_ = function(value) {\n    return j$.isA_('Function', value);\n  };\n\n  j$.isAsyncFunction_ = function(value) {\n    return j$.isA_('AsyncFunction', value);\n  };\n\n  j$.isGeneratorFunction_ = function(value) {\n    return j$.isA_('GeneratorFunction', value);\n  };\n\n  j$.isTypedArray_ = function(value) {\n    return (\n      j$.isA_('Float32Array', value) ||\n      j$.isA_('Float64Array', value) ||\n      j$.isA_('Int16Array', value) ||\n      j$.isA_('Int32Array', value) ||\n      j$.isA_('Int8Array', value) ||\n      j$.isA_('Uint16Array', value) ||\n      j$.isA_('Uint32Array', value) ||\n      j$.isA_('Uint8Array', value) ||\n      j$.isA_('Uint8ClampedArray', value)\n    );\n  };\n\n  j$.isA_ = function(typeName, value) {\n    return j$.getType_(value) === '[object ' + typeName + ']';\n  };\n\n  j$.isError_ = function(value) {\n    if (!value) {\n      return false;\n    }\n\n    if (value instanceof Error) {\n      return true;\n    }\n\n    return typeof value.stack === 'string' && typeof value.message === 'string';\n  };\n\n  j$.isAsymmetricEqualityTester_ = function(obj) {\n    return obj ? j$.isA_('Function', obj.asymmetricMatch) : false;\n  };\n\n  j$.getType_ = function(value) {\n    return Object.prototype.toString.apply(value);\n  };\n\n  j$.isDomNode = function(obj) {\n    // Node is a function, because constructors\n    return typeof jasmineGlobal.Node !== 'undefined'\n      ? obj instanceof jasmineGlobal.Node\n      : obj !== null &&\n          typeof obj === 'object' &&\n          typeof obj.nodeType === 'number' &&\n          typeof obj.nodeName === 'string';\n    // return obj.nodeType > 0;\n  };\n\n  j$.hasConstructor = function(obj, ctor) {\n    return (\n      ctor &&\n      obj !== null &&\n      typeof obj !== 'undefined' &&\n      obj.constructor === ctor\n    );\n  };\n\n  j$.isMap = function(obj) {\n    return j$.hasConstructor(obj, jasmineGlobal.Map);\n  };\n\n  j$.isSet = function(obj) {\n    return j$.hasConstructor(obj, jasmineGlobal.Set);\n  };\n\n  j$.isWeakMap = function(obj) {\n    return j$.hasConstructor(obj, jasmineGlobal.WeakMap);\n  };\n\n  j$.isURL = function(obj) {\n    return j$.hasConstructor(obj, jasmineGlobal.URL);\n  };\n\n  j$.isIterable_ = function(value) {\n    return value && !!value[Symbol.iterator];\n  };\n\n  j$.isDataView = function(obj) {\n    return j$.hasConstructor(obj, jasmineGlobal.DataView);\n  };\n\n  j$.isPromise = function(obj) {\n    return !!obj && obj.constructor === jasmineGlobal.Promise;\n  };\n\n  j$.isPromiseLike = function(obj) {\n    return !!obj && j$.isFunction_(obj.then);\n  };\n\n  j$.fnNameFor = function(func) {\n    if (func.name) {\n      return func.name;\n    }\n\n    var matches =\n      func.toString().match(/^\\s*function\\s*(\\w+)\\s*\\(/) ||\n      func.toString().match(/^\\s*\\[object\\s*(\\w+)Constructor\\]/);\n\n    return matches ? matches[1] : '<anonymous>';\n  };\n\n  j$.isPending_ = function(promise) {\n    var sentinel = {};\n    return Promise.race([promise, Promise.resolve(sentinel)]).then(\n      function(result) {\n        return result === sentinel;\n      },\n      function() {\n        return false;\n      }\n    );\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value being compared is an instance of the specified class/constructor.\n   * @name jasmine.any\n   * @since 1.3.0\n   * @function\n   * @param {Constructor} clazz - The constructor to check against.\n   */\n  j$.any = function(clazz) {\n    return new j$.Any(clazz);\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value being compared is not `null` and not `undefined`.\n   * @name jasmine.anything\n   * @since 2.2.0\n   * @function\n   */\n  j$.anything = function() {\n    return new j$.Anything();\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value being compared is `true` or anything truthy.\n   * @name jasmine.truthy\n   * @since 3.1.0\n   * @function\n   */\n  j$.truthy = function() {\n    return new j$.Truthy();\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value being compared is  `null`, `undefined`, `0`, `false` or anything falsey.\n   * @name jasmine.falsy\n   * @since 3.1.0\n   * @function\n   */\n  j$.falsy = function() {\n    return new j$.Falsy();\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value being compared is empty.\n   * @name jasmine.empty\n   * @since 3.1.0\n   * @function\n   */\n  j$.empty = function() {\n    return new j$.Empty();\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value being compared is not empty.\n   * @name jasmine.notEmpty\n   * @since 3.1.0\n   * @function\n   */\n  j$.notEmpty = function() {\n    return new j$.NotEmpty();\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value being compared contains at least the keys and values.\n   * @name jasmine.objectContaining\n   * @since 1.3.0\n   * @function\n   * @param {Object} sample - The subset of properties that _must_ be in the actual.\n   */\n  j$.objectContaining = function(sample) {\n    return new j$.ObjectContaining(sample);\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value is a `String` that matches the `RegExp` or `String`.\n   * @name jasmine.stringMatching\n   * @since 2.2.0\n   * @function\n   * @param {RegExp|String} expected\n   */\n  j$.stringMatching = function(expected) {\n    return new j$.StringMatching(expected);\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value is a `String` that contains the specified `String`.\n   * @name jasmine.stringContaining\n   * @since 3.10.0\n   * @function\n   * @param {String} expected\n   */\n  j$.stringContaining = function(expected) {\n    return new j$.StringContaining(expected);\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value is an `Array` that contains at least the elements in the sample.\n   * @name jasmine.arrayContaining\n   * @since 2.2.0\n   * @function\n   * @param {Array} sample\n   */\n  j$.arrayContaining = function(sample) {\n    return new j$.ArrayContaining(sample);\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if the actual value is an `Array` that contains all of the elements in the sample in any order.\n   * @name jasmine.arrayWithExactContents\n   * @since 2.8.0\n   * @function\n   * @param {Array} sample\n   */\n  j$.arrayWithExactContents = function(sample) {\n    return new j$.ArrayWithExactContents(sample);\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if every key/value pair in the sample passes the deep equality comparison\n   * with at least one key/value pair in the actual value being compared\n   * @name jasmine.mapContaining\n   * @since 3.5.0\n   * @function\n   * @param {Map} sample - The subset of items that _must_ be in the actual.\n   */\n  j$.mapContaining = function(sample) {\n    return new j$.MapContaining(sample);\n  };\n\n  /**\n   * Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),\n   * that will succeed if every item in the sample passes the deep equality comparison\n   * with at least one item in the actual value being compared\n   * @name jasmine.setContaining\n   * @since 3.5.0\n   * @function\n   * @param {Set} sample - The subset of items that _must_ be in the actual.\n   */\n  j$.setContaining = function(sample) {\n    return new j$.SetContaining(sample);\n  };\n\n  /**\n   * Determines whether the provided function is a Jasmine spy.\n   * @name jasmine.isSpy\n   * @since 2.0.0\n   * @function\n   * @param {Function} putativeSpy - The function to check.\n   * @return {Boolean}\n   */\n  j$.isSpy = function(putativeSpy) {\n    if (!putativeSpy) {\n      return false;\n    }\n    return (\n      putativeSpy.and instanceof j$.SpyStrategy &&\n      putativeSpy.calls instanceof j$.CallTracker\n    );\n  };\n\n  /**\n   * Logs a message for use in debugging. If the spec fails, trace messages\n   * will be included in the {@link SpecResult|result} passed to the\n   * reporter's specDone method.\n   *\n   * This method should be called only when a spec (including any associated\n   * beforeEach or afterEach functions) is running.\n   * @function\n   * @name jasmine.debugLog\n   * @since 4.0.0\n   * @param {String} msg - The message to log\n   */\n  j$.debugLog = function(msg) {\n    j$.getEnv().debugLog(msg);\n  };\n};\n\ngetJasmineRequireObj().util = function(j$) {\n  var util = {};\n\n  util.inherit = function(childClass, parentClass) {\n    var Subclass = function() {};\n    Subclass.prototype = parentClass.prototype;\n    childClass.prototype = new Subclass();\n  };\n\n  util.argsToArray = function(args) {\n    var arrayOfArgs = [];\n    for (var i = 0; i < args.length; i++) {\n      arrayOfArgs.push(args[i]);\n    }\n    return arrayOfArgs;\n  };\n\n  util.isUndefined = function(obj) {\n    return obj === void 0;\n  };\n\n  util.arrayContains = function(array, search) {\n    var i = array.length;\n    while (i--) {\n      if (array[i] === search) {\n        return true;\n      }\n    }\n    return false;\n  };\n\n  util.clone = function(obj) {\n    if (Object.prototype.toString.apply(obj) === '[object Array]') {\n      return obj.slice();\n    }\n\n    var cloned = {};\n    for (var prop in obj) {\n      if (obj.hasOwnProperty(prop)) {\n        cloned[prop] = obj[prop];\n      }\n    }\n\n    return cloned;\n  };\n\n  util.cloneArgs = function(args) {\n    var clonedArgs = [];\n    var argsAsArray = j$.util.argsToArray(args);\n    for (var i = 0; i < argsAsArray.length; i++) {\n      var str = Object.prototype.toString.apply(argsAsArray[i]),\n        primitives = /^\\[object (Boolean|String|RegExp|Number)/;\n\n      // All falsey values are either primitives, `null`, or `undefined.\n      if (!argsAsArray[i] || str.match(primitives)) {\n        clonedArgs.push(argsAsArray[i]);\n      } else if (str === '[object Date]') {\n        clonedArgs.push(new Date(argsAsArray[i].valueOf()));\n      } else {\n        clonedArgs.push(j$.util.clone(argsAsArray[i]));\n      }\n    }\n    return clonedArgs;\n  };\n\n  util.getPropertyDescriptor = function(obj, methodName) {\n    var descriptor,\n      proto = obj;\n\n    do {\n      descriptor = Object.getOwnPropertyDescriptor(proto, methodName);\n      proto = Object.getPrototypeOf(proto);\n    } while (!descriptor && proto);\n\n    return descriptor;\n  };\n\n  util.has = function(obj, key) {\n    return Object.prototype.hasOwnProperty.call(obj, key);\n  };\n\n  util.errorWithStack = function errorWithStack() {\n    // Don't throw and catch. That makes it harder for users to debug their\n    // code with exception breakpoints, and it's unnecessary since all\n    // supported environments populate new Error().stack\n    return new Error();\n  };\n\n  function callerFile() {\n    var trace = new j$.StackTrace(util.errorWithStack());\n    return trace.frames[2].file;\n  }\n\n  util.jasmineFile = (function() {\n    var result;\n\n    return function() {\n      if (!result) {\n        result = callerFile();\n      }\n\n      return result;\n    };\n  })();\n\n  function StopIteration() {}\n  StopIteration.prototype = Object.create(Error.prototype);\n  StopIteration.prototype.constructor = StopIteration;\n\n  util.validateTimeout = function(timeout, msgPrefix) {\n    // Timeouts are implemented with setTimeout, which only supports a limited\n    // range of values. The limit is unspecified, as is the behavior when it's\n    // exceeded. But on all currently supported JS runtimes, setTimeout calls\n    // the callback immediately when the timeout is greater than 2147483647\n    // (the maximum value of a signed 32 bit integer).\n    var max = 2147483647;\n\n    if (timeout > max) {\n      throw new Error(\n        (msgPrefix || 'Timeout value') + ' cannot be greater than ' + max\n      );\n    }\n  };\n\n  return util;\n};\n\ngetJasmineRequireObj().Spec = function(j$) {\n  /**\n   * @interface Spec\n   * @see Configuration#specFilter\n   * @since 2.0.0\n   */\n  function Spec(attrs) {\n    this.expectationFactory = attrs.expectationFactory;\n    this.asyncExpectationFactory = attrs.asyncExpectationFactory;\n    this.resultCallback = attrs.resultCallback || function() {};\n    /**\n     * The unique ID of this spec.\n     * @name Spec#id\n     * @readonly\n     * @type {string}\n     * @since 2.0.0\n     */\n    this.id = attrs.id;\n    /**\n     * The description passed to the {@link it} that created this spec.\n     * @name Spec#description\n     * @readonly\n     * @type {string}\n     * @since 2.0.0\n     */\n    this.description = attrs.description || '';\n    this.queueableFn = attrs.queueableFn;\n    this.beforeAndAfterFns =\n      attrs.beforeAndAfterFns ||\n      function() {\n        return { befores: [], afters: [] };\n      };\n    this.userContext =\n      attrs.userContext ||\n      function() {\n        return {};\n      };\n    this.onStart = attrs.onStart || function() {};\n    this.autoCleanClosures =\n      attrs.autoCleanClosures === undefined ? true : !!attrs.autoCleanClosures;\n    this.getSpecName =\n      attrs.getSpecName ||\n      function() {\n        return '';\n      };\n    this.expectationResultFactory =\n      attrs.expectationResultFactory || function() {};\n    this.onLateError = attrs.onLateError || function() {};\n    this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};\n    this.catchingExceptions =\n      attrs.catchingExceptions ||\n      function() {\n        return true;\n      };\n    this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;\n    this.timer = attrs.timer || new j$.Timer();\n\n    if (!this.queueableFn.fn) {\n      this.exclude();\n    }\n\n    /**\n     * @typedef SpecResult\n     * @property {Int} id - The unique id of this spec.\n     * @property {String} description - The description passed to the {@link it} that created this spec.\n     * @property {String} fullName - The full description including all ancestors of this spec.\n     * @property {Expectation[]} failedExpectations - The list of expectations that failed during execution of this spec.\n     * @property {Expectation[]} passedExpectations - The list of expectations that passed during execution of this spec.\n     * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.\n     * @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.\n     * @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.\n     * @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.\n     * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}\n     * @property {DebugLogEntry[]|null} debugLogs - Messages, if any, that were logged using {@link jasmine.debugLog} during a failing spec.\n     * @since 2.0.0\n     */\n    this.result = {\n      id: this.id,\n      description: this.description,\n      fullName: this.getFullName(),\n      failedExpectations: [],\n      passedExpectations: [],\n      deprecationWarnings: [],\n      pendingReason: '',\n      duration: null,\n      properties: null,\n      debugLogs: null\n    };\n  }\n\n  Spec.prototype.addExpectationResult = function(passed, data, isError) {\n    var expectationResult = this.expectationResultFactory(data);\n    if (passed) {\n      this.result.passedExpectations.push(expectationResult);\n    } else {\n      this.result.failedExpectations.push(expectationResult);\n\n      if (this.throwOnExpectationFailure && !isError) {\n        throw new j$.errors.ExpectationFailed();\n      }\n    }\n  };\n\n  Spec.prototype.setSpecProperty = function(key, value) {\n    this.result.properties = this.result.properties || {};\n    this.result.properties[key] = value;\n  };\n\n  Spec.prototype.expect = function(actual) {\n    return this.expectationFactory(actual, this);\n  };\n\n  Spec.prototype.expectAsync = function(actual) {\n    return this.asyncExpectationFactory(actual, this);\n  };\n\n  Spec.prototype.execute = function(onComplete, excluded, failSpecWithNoExp) {\n    var self = this;\n\n    var onStart = {\n      fn: function(done) {\n        self.timer.start();\n        self.onStart(self, done);\n      }\n    };\n\n    var complete = {\n      fn: function(done) {\n        if (self.autoCleanClosures) {\n          self.queueableFn.fn = null;\n        }\n        self.result.status = self.status(excluded, failSpecWithNoExp);\n        self.result.duration = self.timer.elapsed();\n\n        if (self.result.status !== 'failed') {\n          self.result.debugLogs = null;\n        }\n\n        self.resultCallback(self.result, done);\n      },\n      type: 'specCleanup'\n    };\n\n    var fns = this.beforeAndAfterFns();\n\n    var runnerConfig = {\n      isLeaf: true,\n      queueableFns: [...fns.befores, this.queueableFn, ...fns.afters],\n      onException: function() {\n        self.onException.apply(self, arguments);\n      },\n      onMultipleDone: function() {\n        // Issue a deprecation. Include the context ourselves and pass\n        // ignoreRunnable: true, since getting here always means that we've already\n        // moved on and the current runnable isn't the one that caused the problem.\n        self.onLateError(\n          new Error(\n            'An asynchronous spec, beforeEach, or afterEach function called its ' +\n              \"'done' callback more than once.\\n(in spec: \" +\n              self.getFullName() +\n              ')'\n          )\n        );\n      },\n      onComplete: function() {\n        if (self.result.status === 'failed') {\n          onComplete(new j$.StopExecutionError('spec failed'));\n        } else {\n          onComplete();\n        }\n      },\n      userContext: this.userContext(),\n      runnableName: this.getFullName.bind(this)\n    };\n\n    if (this.markedPending || excluded === true) {\n      runnerConfig.queueableFns = [];\n    }\n\n    runnerConfig.queueableFns.unshift(onStart);\n    runnerConfig.queueableFns.push(complete);\n\n    this.queueRunnerFactory(runnerConfig);\n  };\n\n  Spec.prototype.reset = function() {\n    this.result = {\n      id: this.id,\n      description: this.description,\n      fullName: this.getFullName(),\n      failedExpectations: [],\n      passedExpectations: [],\n      deprecationWarnings: [],\n      pendingReason: this.excludeMessage,\n      duration: null,\n      properties: null,\n      debugLogs: null\n    };\n    this.markedPending = this.markedExcluding;\n  };\n\n  Spec.prototype.onException = function onException(e) {\n    if (Spec.isPendingSpecException(e)) {\n      this.pend(extractCustomPendingMessage(e));\n      return;\n    }\n\n    if (e instanceof j$.errors.ExpectationFailed) {\n      return;\n    }\n\n    this.addExpectationResult(\n      false,\n      {\n        matcherName: '',\n        passed: false,\n        expected: '',\n        actual: '',\n        error: e\n      },\n      true\n    );\n  };\n\n  /*\n   * Marks state as pending\n   * @param {string} [message] An optional reason message\n   */\n  Spec.prototype.pend = function(message) {\n    this.markedPending = true;\n    if (message) {\n      this.result.pendingReason = message;\n    }\n  };\n\n  /*\n   * Like {@link Spec#pend}, but pending state will survive {@link Spec#reset}\n   * Useful for fit, xit, where pending state remains.\n   * @param {string} [message] An optional reason message\n   */\n  Spec.prototype.exclude = function(message) {\n    this.markedExcluding = true;\n    if (this.message) {\n      this.excludeMessage = message;\n    }\n    this.pend(message);\n  };\n\n  Spec.prototype.getResult = function() {\n    this.result.status = this.status();\n    return this.result;\n  };\n\n  Spec.prototype.status = function(excluded, failSpecWithNoExpectations) {\n    if (excluded === true) {\n      return 'excluded';\n    }\n\n    if (this.markedPending) {\n      return 'pending';\n    }\n\n    if (\n      this.result.failedExpectations.length > 0 ||\n      (failSpecWithNoExpectations &&\n        this.result.failedExpectations.length +\n          this.result.passedExpectations.length ===\n          0)\n    ) {\n      return 'failed';\n    }\n\n    return 'passed';\n  };\n\n  /**\n   * The full description including all ancestors of this spec.\n   * @name Spec#getFullName\n   * @function\n   * @returns {string}\n   * @since 2.0.0\n   */\n  Spec.prototype.getFullName = function() {\n    return this.getSpecName(this);\n  };\n\n  Spec.prototype.addDeprecationWarning = function(deprecation) {\n    if (typeof deprecation === 'string') {\n      deprecation = { message: deprecation };\n    }\n    this.result.deprecationWarnings.push(\n      this.expectationResultFactory(deprecation)\n    );\n  };\n\n  Spec.prototype.debugLog = function(msg) {\n    if (!this.result.debugLogs) {\n      this.result.debugLogs = [];\n    }\n\n    /**\n     * @typedef DebugLogEntry\n     * @property {String} message - The message that was passed to {@link jasmine.debugLog}.\n     * @property {number} timestamp - The time when the entry was added, in\n     * milliseconds from the spec's start time\n     */\n    this.result.debugLogs.push({\n      message: msg,\n      timestamp: this.timer.elapsed()\n    });\n  };\n\n  var extractCustomPendingMessage = function(e) {\n    var fullMessage = e.toString(),\n      boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),\n      boilerplateEnd =\n        boilerplateStart + Spec.pendingSpecExceptionMessage.length;\n\n    return fullMessage.slice(boilerplateEnd);\n  };\n\n  Spec.pendingSpecExceptionMessage = '=> marked Pending';\n\n  Spec.isPendingSpecException = function(e) {\n    return !!(\n      e &&\n      e.toString &&\n      e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1\n    );\n  };\n\n  /**\n   * @interface Spec\n   * @see Configuration#specFilter\n   */\n  Object.defineProperty(Spec.prototype, 'metadata', {\n    get: function() {\n      if (!this.metadata_) {\n        this.metadata_ = {\n          /**\n           * The unique ID of this spec.\n           * @name Spec#id\n           * @readonly\n           * @type {string}\n           */\n          id: this.id,\n\n          /**\n           * The description passed to the {@link it} that created this spec.\n           * @name Spec#description\n           * @readonly\n           * @type {string}\n           */\n          description: this.description,\n\n          /**\n           * The full description including all ancestors of this spec.\n           * @name Spec#getFullName\n           * @function\n           * @returns {string}\n           */\n          getFullName: this.getFullName.bind(this)\n        };\n      }\n\n      return this.metadata_;\n    }\n  });\n\n  return Spec;\n};\n\n/*jshint bitwise: false*/\n\ngetJasmineRequireObj().Order = function() {\n  function Order(options) {\n    this.random = 'random' in options ? options.random : true;\n    var seed = (this.seed = options.seed || generateSeed());\n    this.sort = this.random ? randomOrder : naturalOrder;\n\n    function naturalOrder(items) {\n      return items;\n    }\n\n    function randomOrder(items) {\n      var copy = items.slice();\n      copy.sort(function(a, b) {\n        return jenkinsHash(seed + a.id) - jenkinsHash(seed + b.id);\n      });\n      return copy;\n    }\n\n    function generateSeed() {\n      return String(Math.random()).slice(-5);\n    }\n\n    // Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function\n    // used to get a different output when the key changes slightly.\n    // We use your return to sort the children randomly in a consistent way when\n    // used in conjunction with a seed\n\n    function jenkinsHash(key) {\n      var hash, i;\n      for (hash = i = 0; i < key.length; ++i) {\n        hash += key.charCodeAt(i);\n        hash += hash << 10;\n        hash ^= hash >> 6;\n      }\n      hash += hash << 3;\n      hash ^= hash >> 11;\n      hash += hash << 15;\n      return hash;\n    }\n  }\n\n  return Order;\n};\n\ngetJasmineRequireObj().Env = function(j$) {\n  /**\n   * @class Env\n   * @since 2.0.0\n   * @classdesc The Jasmine environment.<br>\n   * _Note:_ Do not construct this directly. You can obtain the Env instance by\n   * calling {@link jasmine.getEnv}.\n   * @hideconstructor\n   */\n  function Env(options) {\n    options = options || {};\n\n    var self = this;\n    var global = options.global || j$.getGlobal();\n\n    var totalSpecsDefined = 0;\n\n    var realSetTimeout = global.setTimeout;\n    var realClearTimeout = global.clearTimeout;\n    var clearStack = j$.getClearStack(global);\n    this.clock = new j$.Clock(\n      global,\n      function() {\n        return new j$.DelayedFunctionScheduler();\n      },\n      new j$.MockDate(global)\n    );\n\n    var runnableResources = {};\n\n    var currentSpec = null;\n    var currentlyExecutingSuites = [];\n    var currentDeclarationSuite = null;\n    var hasFailures = false;\n\n    /**\n     * This represents the available options to configure Jasmine.\n     * Options that are not provided will use their default values.\n     * @see Env#configure\n     * @interface Configuration\n     * @since 3.3.0\n     */\n    var config = {\n      /**\n       * Whether to randomize spec execution order\n       * @name Configuration#random\n       * @since 3.3.0\n       * @type Boolean\n       * @default true\n       */\n      random: true,\n      /**\n       * Seed to use as the basis of randomization.\n       * Null causes the seed to be determined randomly at the start of execution.\n       * @name Configuration#seed\n       * @since 3.3.0\n       * @type (number|string)\n       * @default null\n       */\n      seed: null,\n      /**\n       * Whether to stop execution of the suite after the first spec failure\n       * @name Configuration#stopOnSpecFailure\n       * @since 3.9.0\n       * @type Boolean\n       * @default false\n       */\n      stopOnSpecFailure: false,\n      /**\n       * Whether to fail the spec if it ran no expectations. By default\n       * a spec that ran no expectations is reported as passed. Setting this\n       * to true will report such spec as a failure.\n       * @name Configuration#failSpecWithNoExpectations\n       * @since 3.5.0\n       * @type Boolean\n       * @default false\n       */\n      failSpecWithNoExpectations: false,\n      /**\n       * Whether to cause specs to only have one expectation failure.\n       * @name Configuration#stopSpecOnExpectationFailure\n       * @since 3.3.0\n       * @type Boolean\n       * @default false\n       */\n      stopSpecOnExpectationFailure: false,\n      /**\n       * A function that takes a spec and returns true if it should be executed\n       * or false if it should be skipped.\n       * @callback SpecFilter\n       * @param {Spec} spec - The spec that the filter is being applied to.\n       * @return boolean\n       */\n      /**\n       * Function to use to filter specs\n       * @name Configuration#specFilter\n       * @since 3.3.0\n       * @type SpecFilter\n       * @default A function that always returns true.\n       */\n      specFilter: function() {\n        return true;\n      },\n      /**\n       * Whether or not reporters should hide disabled specs from their output.\n       * Currently only supported by Jasmine's HTMLReporter\n       * @name Configuration#hideDisabled\n       * @since 3.3.0\n       * @type Boolean\n       * @default false\n       */\n      hideDisabled: false,\n      /**\n       * Clean closures when a suite is done running (done by clearing the stored function reference).\n       * This prevents memory leaks, but you won't be able to run jasmine multiple times.\n       * @name Configuration#autoCleanClosures\n       * @since 3.10.0\n       * @type boolean\n       * @default true\n       */\n      autoCleanClosures: true,\n      /**\n       * Whether or not to issue warnings for certain deprecated functionality\n       * every time it's used. If not set or set to false, deprecation warnings\n       * for methods that tend to be called frequently will be issued only once\n       * or otherwise throttled to to prevent the suite output from being flooded\n       * with warnings.\n       * @name Configuration#verboseDeprecations\n       * @since 3.6.0\n       * @type Boolean\n       * @default false\n       */\n      verboseDeprecations: false\n    };\n\n    var currentSuite = function() {\n      return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];\n    };\n\n    var currentRunnable = function() {\n      return currentSpec || currentSuite();\n    };\n\n    var globalErrors = null;\n\n    var installGlobalErrors = function() {\n      if (globalErrors) {\n        return;\n      }\n\n      globalErrors = new j$.GlobalErrors();\n      globalErrors.install();\n    };\n\n    if (!options.suppressLoadErrors) {\n      installGlobalErrors();\n      globalErrors.pushListener(function(\n        message,\n        filename,\n        lineno,\n        colNo,\n        err\n      ) {\n        topSuite.result.failedExpectations.push({\n          passed: false,\n          globalErrorType: 'load',\n          message: message,\n          stack: err && err.stack,\n          filename: filename,\n          lineno: lineno\n        });\n      });\n    }\n\n    /**\n     * Configure your jasmine environment\n     * @name Env#configure\n     * @since 3.3.0\n     * @argument {Configuration} configuration\n     * @function\n     */\n    this.configure = function(configuration) {\n      var booleanProps = [\n        'random',\n        'failSpecWithNoExpectations',\n        'hideDisabled',\n        'stopOnSpecFailure',\n        'stopSpecOnExpectationFailure',\n        'autoCleanClosures'\n      ];\n\n      booleanProps.forEach(function(prop) {\n        if (typeof configuration[prop] !== 'undefined') {\n          config[prop] = !!configuration[prop];\n        }\n      });\n\n      if (configuration.specFilter) {\n        config.specFilter = configuration.specFilter;\n      }\n\n      if (typeof configuration.seed !== 'undefined') {\n        config.seed = configuration.seed;\n      }\n\n      if (configuration.hasOwnProperty('verboseDeprecations')) {\n        config.verboseDeprecations = configuration.verboseDeprecations;\n        deprecator.verboseDeprecations(config.verboseDeprecations);\n      }\n    };\n\n    /**\n     * Get the current configuration for your jasmine environment\n     * @name Env#configuration\n     * @since 3.3.0\n     * @function\n     * @returns {Configuration}\n     */\n    this.configuration = function() {\n      var result = {};\n      for (var property in config) {\n        result[property] = config[property];\n      }\n      return result;\n    };\n\n    this.setDefaultSpyStrategy = function(defaultStrategyFn) {\n      if (!currentRunnable()) {\n        throw new Error(\n          'Default spy strategy must be set in a before function or a spec'\n        );\n      }\n      runnableResources[\n        currentRunnable().id\n      ].defaultStrategyFn = defaultStrategyFn;\n    };\n\n    this.addSpyStrategy = function(name, fn) {\n      if (!currentRunnable()) {\n        throw new Error(\n          'Custom spy strategies must be added in a before function or a spec'\n        );\n      }\n      runnableResources[currentRunnable().id].customSpyStrategies[name] = fn;\n    };\n\n    this.addCustomEqualityTester = function(tester) {\n      if (!currentRunnable()) {\n        throw new Error(\n          'Custom Equalities must be added in a before function or a spec'\n        );\n      }\n      runnableResources[currentRunnable().id].customEqualityTesters.push(\n        tester\n      );\n    };\n\n    this.addMatchers = function(matchersToAdd) {\n      if (!currentRunnable()) {\n        throw new Error(\n          'Matchers must be added in a before function or a spec'\n        );\n      }\n      var customMatchers =\n        runnableResources[currentRunnable().id].customMatchers;\n\n      for (var matcherName in matchersToAdd) {\n        customMatchers[matcherName] = matchersToAdd[matcherName];\n      }\n    };\n\n    this.addAsyncMatchers = function(matchersToAdd) {\n      if (!currentRunnable()) {\n        throw new Error(\n          'Async Matchers must be added in a before function or a spec'\n        );\n      }\n      var customAsyncMatchers =\n        runnableResources[currentRunnable().id].customAsyncMatchers;\n\n      for (var matcherName in matchersToAdd) {\n        customAsyncMatchers[matcherName] = matchersToAdd[matcherName];\n      }\n    };\n\n    this.addCustomObjectFormatter = function(formatter) {\n      if (!currentRunnable()) {\n        throw new Error(\n          'Custom object formatters must be added in a before function or a spec'\n        );\n      }\n\n      runnableResources[currentRunnable().id].customObjectFormatters.push(\n        formatter\n      );\n    };\n\n    j$.Expectation.addCoreMatchers(j$.matchers);\n    j$.Expectation.addAsyncCoreMatchers(j$.asyncMatchers);\n\n    var nextSpecId = 0;\n    var getNextSpecId = function() {\n      return 'spec' + nextSpecId++;\n    };\n\n    var nextSuiteId = 0;\n    var getNextSuiteId = function() {\n      return 'suite' + nextSuiteId++;\n    };\n\n    var makePrettyPrinter = function() {\n      var customObjectFormatters =\n        runnableResources[currentRunnable().id].customObjectFormatters;\n      return j$.makePrettyPrinter(customObjectFormatters);\n    };\n\n    var makeMatchersUtil = function() {\n      const cr = currentRunnable();\n\n      if (cr) {\n        const customEqualityTesters =\n          runnableResources[cr.id].customEqualityTesters;\n        return new j$.MatchersUtil({\n          customTesters: customEqualityTesters,\n          pp: makePrettyPrinter()\n        });\n      } else {\n        return new j$.MatchersUtil({ pp: j$.basicPrettyPrinter_ });\n      }\n    };\n\n    var expectationFactory = function(actual, spec) {\n      return j$.Expectation.factory({\n        matchersUtil: makeMatchersUtil(),\n        customMatchers: runnableResources[spec.id].customMatchers,\n        actual: actual,\n        addExpectationResult: addExpectationResult\n      });\n\n      function addExpectationResult(passed, result) {\n        return spec.addExpectationResult(passed, result);\n      }\n    };\n\n    function recordLateError(error) {\n      const result = expectationResultFactory({\n        error,\n        passed: false,\n        matcherName: '',\n        expected: '',\n        actual: ''\n      });\n      result.globalErrorType = 'lateError';\n      topSuite.result.failedExpectations.push(result);\n    }\n\n    function recordLateExpectation(runable, runableType, result) {\n      var delayedExpectationResult = {};\n      Object.keys(result).forEach(function(k) {\n        delayedExpectationResult[k] = result[k];\n      });\n      delayedExpectationResult.passed = false;\n      delayedExpectationResult.globalErrorType = 'lateExpectation';\n      delayedExpectationResult.message =\n        runableType +\n        ' \"' +\n        runable.getFullName() +\n        '\" ran a \"' +\n        result.matcherName +\n        '\" expectation after it finished.\\n';\n\n      if (result.message) {\n        delayedExpectationResult.message +=\n          'Message: \"' + result.message + '\"\\n';\n      }\n\n      delayedExpectationResult.message +=\n        '1. Did you forget to return or await the result of expectAsync?\\n' +\n        '2. Was done() invoked before an async operation completed?\\n' +\n        '3. Did an expectation follow a call to done()?';\n\n      topSuite.result.failedExpectations.push(delayedExpectationResult);\n    }\n\n    var asyncExpectationFactory = function(actual, spec, runableType) {\n      return j$.Expectation.asyncFactory({\n        matchersUtil: makeMatchersUtil(),\n        customAsyncMatchers: runnableResources[spec.id].customAsyncMatchers,\n        actual: actual,\n        addExpectationResult: addExpectationResult\n      });\n\n      function addExpectationResult(passed, result) {\n        if (currentRunnable() !== spec) {\n          recordLateExpectation(spec, runableType, result);\n        }\n        return spec.addExpectationResult(passed, result);\n      }\n    };\n    var suiteAsyncExpectationFactory = function(actual, suite) {\n      return asyncExpectationFactory(actual, suite, 'Suite');\n    };\n\n    var specAsyncExpectationFactory = function(actual, suite) {\n      return asyncExpectationFactory(actual, suite, 'Spec');\n    };\n\n    var defaultResourcesForRunnable = function(id, parentRunnableId) {\n      var resources = {\n        spies: [],\n        customEqualityTesters: [],\n        customMatchers: {},\n        customAsyncMatchers: {},\n        customSpyStrategies: {},\n        defaultStrategyFn: undefined,\n        customObjectFormatters: []\n      };\n\n      if (runnableResources[parentRunnableId]) {\n        resources.customEqualityTesters = j$.util.clone(\n          runnableResources[parentRunnableId].customEqualityTesters\n        );\n        resources.customMatchers = j$.util.clone(\n          runnableResources[parentRunnableId].customMatchers\n        );\n        resources.customAsyncMatchers = j$.util.clone(\n          runnableResources[parentRunnableId].customAsyncMatchers\n        );\n        resources.customObjectFormatters = j$.util.clone(\n          runnableResources[parentRunnableId].customObjectFormatters\n        );\n        resources.customSpyStrategies = j$.util.clone(\n          runnableResources[parentRunnableId].customSpyStrategies\n        );\n        resources.defaultStrategyFn =\n          runnableResources[parentRunnableId].defaultStrategyFn;\n      }\n\n      runnableResources[id] = resources;\n    };\n\n    var clearResourcesForRunnable = function(id) {\n      spyRegistry.clearSpies();\n      delete runnableResources[id];\n    };\n\n    var beforeAndAfterFns = function(targetSuite) {\n      return function() {\n        var befores = [],\n          afters = [],\n          suite = targetSuite;\n\n        while (suite) {\n          befores = befores.concat(suite.beforeFns);\n          afters = afters.concat(suite.afterFns);\n\n          suite = suite.parentSuite;\n        }\n\n        return {\n          befores: befores.reverse(),\n          afters: afters\n        };\n      };\n    };\n\n    var getSpecName = function(spec, suite) {\n      var fullName = [spec.description],\n        suiteFullName = suite.getFullName();\n\n      if (suiteFullName !== '') {\n        fullName.unshift(suiteFullName);\n      }\n      return fullName.join(' ');\n    };\n\n    // TODO: we may just be able to pass in the fn instead of wrapping here\n    var buildExpectationResult = j$.buildExpectationResult,\n      exceptionFormatter = new j$.ExceptionFormatter(),\n      expectationResultFactory = function(attrs) {\n        attrs.messageFormatter = exceptionFormatter.message;\n        attrs.stackFormatter = exceptionFormatter.stack;\n\n        return buildExpectationResult(attrs);\n      };\n\n    /**\n     * Causes a deprecation warning to be logged to the console and reported to\n     * reporters.\n     *\n     * The optional second parameter is an object that can have either of the\n     * following properties:\n     *\n     * omitStackTrace: Whether to omit the stack trace. Optional. Defaults to\n     * false. This option is ignored if the deprecation is an Error. Set this\n     * when the stack trace will not contain anything that helps the user find\n     * the source of the deprecation.\n     *\n     * ignoreRunnable: Whether to log the deprecation on the root suite, ignoring\n     * the spec or suite that's running when it happens. Optional. Defaults to\n     * false.\n     *\n     * @name Env#deprecated\n     * @since 2.99\n     * @function\n     * @param {String|Error} deprecation The deprecation message\n     * @param {Object} [options] Optional extra options, as described above\n     */\n    this.deprecated = function(deprecation, options) {\n      var runnable = currentRunnable() || topSuite;\n      deprecator.addDeprecationWarning(runnable, deprecation, options);\n    };\n\n    var queueRunnerFactory = function(options, args) {\n      if (options.isLeaf) {\n        // A spec\n        options.SkipPolicy = j$.CompleteOnFirstErrorSkipPolicy;\n      } else if (options.isReporter) {\n        // A reporter queue\n        options.SkipPolicy = j$.NeverSkipPolicy;\n      } else {\n        // A suite\n        if (config.stopOnSpecFailure) {\n          options.SkipPolicy = j$.CompleteOnFirstErrorSkipPolicy;\n        } else {\n          options.SkipPolicy = j$.SkipAfterBeforeAllErrorPolicy;\n        }\n      }\n\n      options.clearStack = options.clearStack || clearStack;\n      options.timeout = {\n        setTimeout: realSetTimeout,\n        clearTimeout: realClearTimeout\n      };\n      options.fail = self.fail;\n      options.globalErrors = globalErrors;\n      options.onException =\n        options.onException ||\n        function(e) {\n          (currentRunnable() || topSuite).onException(e);\n        };\n      options.deprecated = self.deprecated;\n\n      new j$.QueueRunner(options).execute(args);\n    };\n\n    var topSuite = new j$.Suite({\n      id: getNextSuiteId(),\n      description: 'Jasmine__TopLevel__Suite',\n      expectationFactory: expectationFactory,\n      asyncExpectationFactory: suiteAsyncExpectationFactory,\n      expectationResultFactory: expectationResultFactory,\n      autoCleanClosures: config.autoCleanClosures,\n      onLateError: recordLateError\n    });\n    var deprecator = new j$.Deprecator(topSuite);\n    currentDeclarationSuite = topSuite;\n\n    /**\n     * Provides the root suite, through which all suites and specs can be\n     * accessed.\n     * @function\n     * @name Env#topSuite\n     * @return {Suite} the root suite\n     * @since 2.0.0\n     */\n    this.topSuite = function() {\n      return topSuite.metadata;\n    };\n\n    /**\n     * This represents the available reporter callback for an object passed to {@link Env#addReporter}.\n     * @interface Reporter\n     * @see custom_reporter\n     */\n    var reporter = new j$.ReportDispatcher(\n      [\n        /**\n         * `jasmineStarted` is called after all of the specs have been loaded, but just before execution starts.\n         * @function\n         * @name Reporter#jasmineStarted\n         * @param {JasmineStartedInfo} suiteInfo Information about the full Jasmine suite that is being run\n         * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.\n         * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.\n         * @see async\n         */\n        'jasmineStarted',\n        /**\n         * When the entire suite has finished execution `jasmineDone` is called\n         * @function\n         * @name Reporter#jasmineDone\n         * @param {JasmineDoneInfo} suiteInfo Information about the full Jasmine suite that just finished running.\n         * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.\n         * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.\n         * @see async\n         */\n        'jasmineDone',\n        /**\n         * `suiteStarted` is invoked when a `describe` starts to run\n         * @function\n         * @name Reporter#suiteStarted\n         * @param {SuiteResult} result Information about the individual {@link describe} being run\n         * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.\n         * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.\n         * @see async\n         */\n        'suiteStarted',\n        /**\n         * `suiteDone` is invoked when all of the child specs and suites for a given suite have been run\n         *\n         * While jasmine doesn't require any specific functions, not defining a `suiteDone` will make it impossible for a reporter to know when a suite has failures in an `afterAll`.\n         * @function\n         * @name Reporter#suiteDone\n         * @param {SuiteResult} result\n         * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.\n         * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.\n         * @see async\n         */\n        'suiteDone',\n        /**\n         * `specStarted` is invoked when an `it` starts to run (including associated `beforeEach` functions)\n         * @function\n         * @name Reporter#specStarted\n         * @param {SpecResult} result Information about the individual {@link it} being run\n         * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.\n         * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.\n         * @see async\n         */\n        'specStarted',\n        /**\n         * `specDone` is invoked when an `it` and its associated `beforeEach` and `afterEach` functions have been run.\n         *\n         * While jasmine doesn't require any specific functions, not defining a `specDone` will make it impossible for a reporter to know when a spec has failed.\n         * @function\n         * @name Reporter#specDone\n         * @param {SpecResult} result\n         * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.\n         * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.\n         * @see async\n         */\n        'specDone'\n      ],\n      queueRunnerFactory,\n      recordLateError\n    );\n\n    /**\n     * Executes the specs.\n     *\n     * If called with no parameters or with a falsy value as the first parameter,\n     * all specs will be executed except those that are excluded by a\n     * [spec filter]{@link Configuration#specFilter} or other mechanism. If the\n     * first parameter is a list of spec/suite IDs, only those specs/suites will\n     * be run.\n     *\n     * Both parameters are optional, but a completion callback is only valid as\n     * the second parameter. To specify a completion callback but not a list of\n     * specs/suites to run, pass null or undefined as the first parameter. The\n     * completion callback is supported for backward compatibility. In most\n     * cases it will be more convenient to use the returned promise instead.\n     *\n     * execute should not be called more than once unless the env has been\n     * configured with `{autoCleanClosures: false}`.\n     *\n     * execute returns a promise. The promise will be resolved to the same\n     * {@link JasmineDoneInfo|overall result} that's passed to a reporter's\n     * `jasmineDone` method, even if the suite did not pass. To determine\n     * whether the suite passed, check the value that the promise resolves to\n     * or use a {@link Reporter}.\n     *\n     * @name Env#execute\n     * @since 2.0.0\n     * @function\n     * @param {(string[])=} runnablesToRun IDs of suites and/or specs to run\n     * @param {Function=} onComplete Function that will be called after all specs have run\n     * @return {Promise<JasmineDoneInfo>}\n     */\n    this.execute = function(runnablesToRun, onComplete) {\n      if (this._executedBefore) {\n        topSuite.reset();\n      }\n      this._executedBefore = true;\n      defaultResourcesForRunnable(topSuite.id);\n      installGlobalErrors();\n\n      if (!runnablesToRun) {\n        if (focusedRunnables.length) {\n          runnablesToRun = focusedRunnables;\n        } else {\n          runnablesToRun = [topSuite.id];\n        }\n      }\n\n      var order = new j$.Order({\n        random: config.random,\n        seed: config.seed\n      });\n\n      var processor = new j$.TreeProcessor({\n        tree: topSuite,\n        runnableIds: runnablesToRun,\n        queueRunnerFactory: queueRunnerFactory,\n        failSpecWithNoExpectations: config.failSpecWithNoExpectations,\n        nodeStart: function(suite, next) {\n          currentlyExecutingSuites.push(suite);\n          defaultResourcesForRunnable(suite.id, suite.parentSuite.id);\n          reporter.suiteStarted(suite.result, next);\n          suite.startTimer();\n        },\n        nodeComplete: function(suite, result, next) {\n          if (suite !== currentSuite()) {\n            throw new Error('Tried to complete the wrong suite');\n          }\n\n          clearResourcesForRunnable(suite.id);\n          currentlyExecutingSuites.pop();\n\n          if (result.status === 'failed') {\n            hasFailures = true;\n          }\n          suite.endTimer();\n\n          if (suite.hadBeforeAllFailure) {\n            reportChildrenOfBeforeAllFailure(suite).then(function() {\n              reporter.suiteDone(result, next);\n            });\n          } else {\n            reporter.suiteDone(result, next);\n          }\n        },\n        orderChildren: function(node) {\n          return order.sort(node.children);\n        },\n        excludeNode: function(spec) {\n          return !config.specFilter(spec);\n        }\n      });\n\n      if (!processor.processTree().valid) {\n        throw new Error(\n          'Invalid order: would cause a beforeAll or afterAll to be run multiple times'\n        );\n      }\n\n      var jasmineTimer = new j$.Timer();\n      jasmineTimer.start();\n\n      return new Promise(function(resolve) {\n        runAll(function(jasmineDoneInfo) {\n          if (onComplete) {\n            onComplete();\n          }\n\n          resolve(jasmineDoneInfo);\n        });\n      });\n\n      function runAll(done) {\n        /**\n         * Information passed to the {@link Reporter#jasmineStarted} event.\n         * @typedef JasmineStartedInfo\n         * @property {Int} totalSpecsDefined - The total number of specs defined in this suite.\n         * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.\n         * @since 2.0.0\n         */\n        reporter.jasmineStarted(\n          {\n            totalSpecsDefined: totalSpecsDefined,\n            order: order\n          },\n          function() {\n            currentlyExecutingSuites.push(topSuite);\n\n            processor.execute(function() {\n              (async function() {\n                if (topSuite.hadBeforeAllFailure) {\n                  await reportChildrenOfBeforeAllFailure(topSuite);\n                }\n\n                clearResourcesForRunnable(topSuite.id);\n                currentlyExecutingSuites.pop();\n                var overallStatus, incompleteReason;\n\n                if (\n                  hasFailures ||\n                  topSuite.result.failedExpectations.length > 0\n                ) {\n                  overallStatus = 'failed';\n                } else if (focusedRunnables.length > 0) {\n                  overallStatus = 'incomplete';\n                  incompleteReason = 'fit() or fdescribe() was found';\n                } else if (totalSpecsDefined === 0) {\n                  overallStatus = 'incomplete';\n                  incompleteReason = 'No specs found';\n                } else {\n                  overallStatus = 'passed';\n                }\n\n                /**\n                 * Information passed to the {@link Reporter#jasmineDone} event.\n                 * @typedef JasmineDoneInfo\n                 * @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'.\n                 * @property {Int} totalTime - The total time (in ms) that it took to execute the suite\n                 * @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete.\n                 * @property {Order} order - Information about the ordering (random or not) of this execution of the suite.\n                 * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.\n                 * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level.\n                 * @since 2.4.0\n                 */\n                const jasmineDoneInfo = {\n                  overallStatus: overallStatus,\n                  totalTime: jasmineTimer.elapsed(),\n                  incompleteReason: incompleteReason,\n                  order: order,\n                  failedExpectations: topSuite.result.failedExpectations,\n                  deprecationWarnings: topSuite.result.deprecationWarnings\n                };\n                reporter.jasmineDone(jasmineDoneInfo, function() {\n                  done(jasmineDoneInfo);\n                });\n              })();\n            });\n          }\n        );\n      }\n\n      async function reportChildrenOfBeforeAllFailure(suite) {\n        for (const child of suite.children) {\n          if (child instanceof j$.Suite) {\n            await new Promise(function(resolve) {\n              reporter.suiteStarted(child.result, resolve);\n            });\n            await reportChildrenOfBeforeAllFailure(child);\n\n            // Marking the suite passed is consistent with how suites that\n            // contain failed specs but no suite-level failures are reported.\n            child.result.status = 'passed';\n\n            await new Promise(function(resolve) {\n              reporter.suiteDone(child.result, resolve);\n            });\n          } else {\n            /* a spec */\n            await new Promise(function(resolve) {\n              reporter.specStarted(child.result, resolve);\n            });\n\n            child.addExpectationResult(\n              false,\n              {\n                passed: false,\n                message:\n                  'Not run because a beforeAll function failed. The ' +\n                  'beforeAll failure will be reported on the suite that ' +\n                  'caused it.'\n              },\n              true\n            );\n            child.result.status = 'failed';\n\n            await new Promise(function(resolve) {\n              reporter.specDone(child.result, resolve);\n            });\n          }\n        }\n      }\n    };\n\n    /**\n     * Add a custom reporter to the Jasmine environment.\n     * @name Env#addReporter\n     * @since 2.0.0\n     * @function\n     * @param {Reporter} reporterToAdd The reporter to be added.\n     * @see custom_reporter\n     */\n    this.addReporter = function(reporterToAdd) {\n      reporter.addReporter(reporterToAdd);\n    };\n\n    /**\n     * Provide a fallback reporter if no other reporters have been specified.\n     * @name Env#provideFallbackReporter\n     * @since 2.5.0\n     * @function\n     * @param {Reporter} reporterToAdd The reporter\n     * @see custom_reporter\n     */\n    this.provideFallbackReporter = function(reporterToAdd) {\n      reporter.provideFallbackReporter(reporterToAdd);\n    };\n\n    /**\n     * Clear all registered reporters\n     * @name Env#clearReporters\n     * @since 2.5.2\n     * @function\n     */\n    this.clearReporters = function() {\n      reporter.clearReporters();\n    };\n\n    var spyFactory = new j$.SpyFactory(\n      function getCustomStrategies() {\n        var runnable = currentRunnable();\n\n        if (runnable) {\n          return runnableResources[runnable.id].customSpyStrategies;\n        }\n\n        return {};\n      },\n      function getDefaultStrategyFn() {\n        var runnable = currentRunnable();\n\n        if (runnable) {\n          return runnableResources[runnable.id].defaultStrategyFn;\n        }\n\n        return undefined;\n      },\n      makeMatchersUtil\n    );\n\n    var spyRegistry = new j$.SpyRegistry({\n      currentSpies: function() {\n        if (!currentRunnable()) {\n          throw new Error(\n            'Spies must be created in a before function or a spec'\n          );\n        }\n        return runnableResources[currentRunnable().id].spies;\n      },\n      createSpy: function(name, originalFn) {\n        return self.createSpy(name, originalFn);\n      }\n    });\n\n    /**\n     * Configures whether Jasmine should allow the same function to be spied on\n     * more than once during the execution of a spec. By default, spying on\n     * a function that is already a spy will cause an error.\n     * @name Env#allowRespy\n     * @function\n     * @since 2.5.0\n     * @param {boolean} allow Whether to allow respying\n     */\n    this.allowRespy = function(allow) {\n      spyRegistry.allowRespy(allow);\n    };\n\n    this.spyOn = function() {\n      return spyRegistry.spyOn.apply(spyRegistry, arguments);\n    };\n\n    this.spyOnProperty = function() {\n      return spyRegistry.spyOnProperty.apply(spyRegistry, arguments);\n    };\n\n    this.spyOnAllFunctions = function() {\n      return spyRegistry.spyOnAllFunctions.apply(spyRegistry, arguments);\n    };\n\n    this.createSpy = function(name, originalFn) {\n      if (arguments.length === 1 && j$.isFunction_(name)) {\n        originalFn = name;\n        name = originalFn.name;\n      }\n\n      return spyFactory.createSpy(name, originalFn);\n    };\n\n    this.createSpyObj = function(baseName, methodNames, propertyNames) {\n      return spyFactory.createSpyObj(baseName, methodNames, propertyNames);\n    };\n\n    var ensureIsFunction = function(fn, caller) {\n      if (!j$.isFunction_(fn)) {\n        throw new Error(\n          caller + ' expects a function argument; received ' + j$.getType_(fn)\n        );\n      }\n    };\n\n    var ensureIsFunctionOrAsync = function(fn, caller) {\n      if (!j$.isFunction_(fn) && !j$.isAsyncFunction_(fn)) {\n        throw new Error(\n          caller + ' expects a function argument; received ' + j$.getType_(fn)\n        );\n      }\n    };\n\n    function ensureIsNotNested(method) {\n      var runnable = currentRunnable();\n      if (runnable !== null && runnable !== undefined) {\n        throw new Error(\n          \"'\" + method + \"' should only be used in 'describe' function\"\n        );\n      }\n    }\n\n    var suiteFactory = function(description) {\n      var suite = new j$.Suite({\n        id: getNextSuiteId(),\n        description: description,\n        parentSuite: currentDeclarationSuite,\n        timer: new j$.Timer(),\n        expectationFactory: expectationFactory,\n        asyncExpectationFactory: suiteAsyncExpectationFactory,\n        expectationResultFactory: expectationResultFactory,\n        throwOnExpectationFailure: config.stopSpecOnExpectationFailure,\n        autoCleanClosures: config.autoCleanClosures,\n        onLateError: recordLateError\n      });\n\n      return suite;\n    };\n\n    this.describe = function(description, specDefinitions) {\n      ensureIsNotNested('describe');\n      ensureIsFunction(specDefinitions, 'describe');\n      var suite = suiteFactory(description);\n      if (specDefinitions.length > 0) {\n        throw new Error('describe does not expect any arguments');\n      }\n      if (currentDeclarationSuite.markedExcluding) {\n        suite.exclude();\n      }\n      addSpecsToSuite(suite, specDefinitions);\n      if (suite.parentSuite && !suite.children.length) {\n        throw new Error(\n          'describe with no children (describe() or it()): ' +\n            suite.getFullName()\n        );\n      }\n      return suite.metadata;\n    };\n\n    this.xdescribe = function(description, specDefinitions) {\n      ensureIsNotNested('xdescribe');\n      ensureIsFunction(specDefinitions, 'xdescribe');\n      var suite = suiteFactory(description);\n      suite.exclude();\n      addSpecsToSuite(suite, specDefinitions);\n      return suite.metadata;\n    };\n\n    var focusedRunnables = [];\n\n    this.fdescribe = function(description, specDefinitions) {\n      ensureIsNotNested('fdescribe');\n      ensureIsFunction(specDefinitions, 'fdescribe');\n      var suite = suiteFactory(description);\n      suite.isFocused = true;\n\n      focusedRunnables.push(suite.id);\n      unfocusAncestor();\n      addSpecsToSuite(suite, specDefinitions);\n\n      return suite.metadata;\n    };\n\n    function addSpecsToSuite(suite, specDefinitions) {\n      var parentSuite = currentDeclarationSuite;\n      parentSuite.addChild(suite);\n      currentDeclarationSuite = suite;\n\n      var declarationError = null;\n      try {\n        specDefinitions();\n      } catch (e) {\n        declarationError = e;\n      }\n\n      if (declarationError) {\n        suite.onException(declarationError);\n      }\n\n      currentDeclarationSuite = parentSuite;\n    }\n\n    function findFocusedAncestor(suite) {\n      while (suite) {\n        if (suite.isFocused) {\n          return suite.id;\n        }\n        suite = suite.parentSuite;\n      }\n\n      return null;\n    }\n\n    function unfocusAncestor() {\n      var focusedAncestor = findFocusedAncestor(currentDeclarationSuite);\n      if (focusedAncestor) {\n        for (var i = 0; i < focusedRunnables.length; i++) {\n          if (focusedRunnables[i] === focusedAncestor) {\n            focusedRunnables.splice(i, 1);\n            break;\n          }\n        }\n      }\n    }\n\n    var specFactory = function(description, fn, suite, timeout) {\n      totalSpecsDefined++;\n      var spec = new j$.Spec({\n        id: getNextSpecId(),\n        beforeAndAfterFns: beforeAndAfterFns(suite),\n        expectationFactory: expectationFactory,\n        asyncExpectationFactory: specAsyncExpectationFactory,\n        onLateError: recordLateError,\n        resultCallback: specResultCallback,\n        getSpecName: function(spec) {\n          return getSpecName(spec, suite);\n        },\n        onStart: specStarted,\n        description: description,\n        expectationResultFactory: expectationResultFactory,\n        queueRunnerFactory: queueRunnerFactory,\n        userContext: function() {\n          return suite.clonedSharedUserContext();\n        },\n        queueableFn: {\n          fn: fn,\n          timeout: timeout || 0\n        },\n        throwOnExpectationFailure: config.stopSpecOnExpectationFailure,\n        autoCleanClosures: config.autoCleanClosures,\n        timer: new j$.Timer()\n      });\n      return spec;\n\n      function specResultCallback(result, next) {\n        clearResourcesForRunnable(spec.id);\n        currentSpec = null;\n\n        if (result.status === 'failed') {\n          hasFailures = true;\n        }\n\n        reporter.specDone(result, next);\n      }\n\n      function specStarted(spec, next) {\n        currentSpec = spec;\n        defaultResourcesForRunnable(spec.id, suite.id);\n        reporter.specStarted(spec.result, next);\n      }\n    };\n\n    this.it_ = function(description, fn, timeout) {\n      ensureIsNotNested('it');\n      // it() sometimes doesn't have a fn argument, so only check the type if\n      // it's given.\n      if (arguments.length > 1 && typeof fn !== 'undefined') {\n        ensureIsFunctionOrAsync(fn, 'it');\n      }\n\n      if (timeout) {\n        j$.util.validateTimeout(timeout);\n      }\n\n      var spec = specFactory(description, fn, currentDeclarationSuite, timeout);\n      if (currentDeclarationSuite.markedExcluding) {\n        spec.exclude();\n      }\n      currentDeclarationSuite.addChild(spec);\n\n      return spec;\n    };\n\n    this.it = function(description, fn, timeout) {\n      const spec = this.it_(description, fn, timeout);\n      return spec.metadata;\n    };\n\n    this.xit = function(description, fn, timeout) {\n      ensureIsNotNested('xit');\n      // xit(), like it(), doesn't always have a fn argument, so only check the\n      // type when needed.\n      if (arguments.length > 1 && typeof fn !== 'undefined') {\n        ensureIsFunctionOrAsync(fn, 'xit');\n      }\n      var spec = this.it_.apply(this, arguments);\n      spec.exclude('Temporarily disabled with xit');\n      return spec.metadata;\n    };\n\n    this.fit = function(description, fn, timeout) {\n      ensureIsNotNested('fit');\n      ensureIsFunctionOrAsync(fn, 'fit');\n\n      if (timeout) {\n        j$.util.validateTimeout(timeout);\n      }\n      var spec = specFactory(description, fn, currentDeclarationSuite, timeout);\n      currentDeclarationSuite.addChild(spec);\n      focusedRunnables.push(spec.id);\n      unfocusAncestor();\n      return spec.metadata;\n    };\n\n    /**\n     * Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult}\n     * @name Env#setSpecProperty\n     * @since 3.6.0\n     * @function\n     * @param {String} key The name of the property\n     * @param {*} value The value of the property\n     */\n    this.setSpecProperty = function(key, value) {\n      if (!currentRunnable() || currentRunnable() == currentSuite()) {\n        throw new Error(\n          \"'setSpecProperty' was used when there was no current spec\"\n        );\n      }\n      currentRunnable().setSpecProperty(key, value);\n    };\n\n    /**\n     * Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult}\n     * @name Env#setSuiteProperty\n     * @since 3.6.0\n     * @function\n     * @param {String} key The name of the property\n     * @param {*} value The value of the property\n     */\n    this.setSuiteProperty = function(key, value) {\n      if (!currentSuite()) {\n        throw new Error(\n          \"'setSuiteProperty' was used when there was no current suite\"\n        );\n      }\n      currentSuite().setSuiteProperty(key, value);\n    };\n\n    this.debugLog = function(msg) {\n      var maybeSpec = currentRunnable();\n\n      if (!maybeSpec || !maybeSpec.debugLog) {\n        throw new Error(\"'debugLog' was called when there was no current spec\");\n      }\n\n      maybeSpec.debugLog(msg);\n    };\n\n    this.expect = function(actual) {\n      if (!currentRunnable()) {\n        throw new Error(\n          \"'expect' was used when there was no current spec, this could be because an asynchronous test timed out\"\n        );\n      }\n\n      return currentRunnable().expect(actual);\n    };\n\n    this.expectAsync = function(actual) {\n      if (!currentRunnable()) {\n        throw new Error(\n          \"'expectAsync' was used when there was no current spec, this could be because an asynchronous test timed out\"\n        );\n      }\n\n      return currentRunnable().expectAsync(actual);\n    };\n\n    this.beforeEach = function(beforeEachFunction, timeout) {\n      ensureIsNotNested('beforeEach');\n      ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');\n\n      if (timeout) {\n        j$.util.validateTimeout(timeout);\n      }\n\n      currentDeclarationSuite.beforeEach({\n        fn: beforeEachFunction,\n        timeout: timeout || 0\n      });\n    };\n\n    this.beforeAll = function(beforeAllFunction, timeout) {\n      ensureIsNotNested('beforeAll');\n      ensureIsFunctionOrAsync(beforeAllFunction, 'beforeAll');\n\n      if (timeout) {\n        j$.util.validateTimeout(timeout);\n      }\n\n      currentDeclarationSuite.beforeAll({\n        fn: beforeAllFunction,\n        timeout: timeout || 0\n      });\n    };\n\n    this.afterEach = function(afterEachFunction, timeout) {\n      ensureIsNotNested('afterEach');\n      ensureIsFunctionOrAsync(afterEachFunction, 'afterEach');\n\n      if (timeout) {\n        j$.util.validateTimeout(timeout);\n      }\n\n      afterEachFunction.isCleanup = true;\n      currentDeclarationSuite.afterEach({\n        fn: afterEachFunction,\n        timeout: timeout || 0\n      });\n    };\n\n    this.afterAll = function(afterAllFunction, timeout) {\n      ensureIsNotNested('afterAll');\n      ensureIsFunctionOrAsync(afterAllFunction, 'afterAll');\n\n      if (timeout) {\n        j$.util.validateTimeout(timeout);\n      }\n\n      currentDeclarationSuite.afterAll({\n        fn: afterAllFunction,\n        timeout: timeout || 0\n      });\n    };\n\n    this.pending = function(message) {\n      var fullMessage = j$.Spec.pendingSpecExceptionMessage;\n      if (message) {\n        fullMessage += message;\n      }\n      throw fullMessage;\n    };\n\n    this.fail = function(error) {\n      if (!currentRunnable()) {\n        throw new Error(\n          \"'fail' was used when there was no current spec, this could be because an asynchronous test timed out\"\n        );\n      }\n\n      var message = 'Failed';\n      if (error) {\n        message += ': ';\n        if (error.message) {\n          message += error.message;\n        } else if (j$.isString_(error)) {\n          message += error;\n        } else {\n          // pretty print all kind of objects. This includes arrays.\n          message += makePrettyPrinter()(error);\n        }\n      }\n\n      currentRunnable().addExpectationResult(false, {\n        matcherName: '',\n        passed: false,\n        expected: '',\n        actual: '',\n        message: message,\n        error: error && error.message ? error : null\n      });\n\n      if (config.stopSpecOnExpectationFailure) {\n        throw new Error(message);\n      }\n    };\n\n    this.cleanup_ = function() {\n      if (globalErrors) {\n        globalErrors.uninstall();\n      }\n    };\n  }\n\n  return Env;\n};\n\ngetJasmineRequireObj().JsApiReporter = function(j$) {\n  /**\n   * @name jsApiReporter\n   * @classdesc {@link Reporter} added by default in `boot.js` to record results for retrieval in javascript code. An instance is made available as `jsApiReporter` on the global object.\n   * @class\n   * @hideconstructor\n   */\n  function JsApiReporter(options) {\n    var timer = options.timer || new j$.Timer(),\n      status = 'loaded';\n\n    this.started = false;\n    this.finished = false;\n    this.runDetails = {};\n\n    this.jasmineStarted = function() {\n      this.started = true;\n      status = 'started';\n      timer.start();\n    };\n\n    var executionTime;\n\n    this.jasmineDone = function(runDetails) {\n      this.finished = true;\n      this.runDetails = runDetails;\n      executionTime = timer.elapsed();\n      status = 'done';\n    };\n\n    /**\n     * Get the current status for the Jasmine environment.\n     * @name jsApiReporter#status\n     * @since 2.0.0\n     * @function\n     * @return {String} - One of `loaded`, `started`, or `done`\n     */\n    this.status = function() {\n      return status;\n    };\n\n    var suites = [],\n      suites_hash = {};\n\n    this.suiteStarted = function(result) {\n      suites_hash[result.id] = result;\n    };\n\n    this.suiteDone = function(result) {\n      storeSuite(result);\n    };\n\n    /**\n     * Get the results for a set of suites.\n     *\n     * Retrievable in slices for easier serialization.\n     * @name jsApiReporter#suiteResults\n     * @since 2.1.0\n     * @function\n     * @param {Number} index - The position in the suites list to start from.\n     * @param {Number} length - Maximum number of suite results to return.\n     * @return {SuiteResult[]}\n     */\n    this.suiteResults = function(index, length) {\n      return suites.slice(index, index + length);\n    };\n\n    function storeSuite(result) {\n      suites.push(result);\n      suites_hash[result.id] = result;\n    }\n\n    /**\n     * Get all of the suites in a single object, with their `id` as the key.\n     * @name jsApiReporter#suites\n     * @since 2.0.0\n     * @function\n     * @return {Object} - Map of suite id to {@link SuiteResult}\n     */\n    this.suites = function() {\n      return suites_hash;\n    };\n\n    var specs = [];\n\n    this.specDone = function(result) {\n      specs.push(result);\n    };\n\n    /**\n     * Get the results for a set of specs.\n     *\n     * Retrievable in slices for easier serialization.\n     * @name jsApiReporter#specResults\n     * @since 2.0.0\n     * @function\n     * @param {Number} index - The position in the specs list to start from.\n     * @param {Number} length - Maximum number of specs results to return.\n     * @return {SpecResult[]}\n     */\n    this.specResults = function(index, length) {\n      return specs.slice(index, index + length);\n    };\n\n    /**\n     * Get all spec results.\n     * @name jsApiReporter#specs\n     * @since 2.0.0\n     * @function\n     * @return {SpecResult[]}\n     */\n    this.specs = function() {\n      return specs;\n    };\n\n    /**\n     * Get the number of milliseconds it took for the full Jasmine suite to run.\n     * @name jsApiReporter#executionTime\n     * @since 2.0.0\n     * @function\n     * @return {Number}\n     */\n    this.executionTime = function() {\n      return executionTime;\n    };\n  }\n\n  return JsApiReporter;\n};\n\ngetJasmineRequireObj().Any = function(j$) {\n  function Any(expectedObject) {\n    if (typeof expectedObject === 'undefined') {\n      throw new TypeError(\n        'jasmine.any() expects to be passed a constructor function. ' +\n          'Please pass one or use jasmine.anything() to match any object.'\n      );\n    }\n    this.expectedObject = expectedObject;\n  }\n\n  Any.prototype.asymmetricMatch = function(other) {\n    if (this.expectedObject == String) {\n      return typeof other == 'string' || other instanceof String;\n    }\n\n    if (this.expectedObject == Number) {\n      return typeof other == 'number' || other instanceof Number;\n    }\n\n    if (this.expectedObject == Function) {\n      return typeof other == 'function' || other instanceof Function;\n    }\n\n    if (this.expectedObject == Object) {\n      return other !== null && typeof other == 'object';\n    }\n\n    if (this.expectedObject == Boolean) {\n      return typeof other == 'boolean';\n    }\n\n    /* jshint -W122 */\n    /* global Symbol */\n    if (typeof Symbol != 'undefined' && this.expectedObject == Symbol) {\n      return typeof other == 'symbol';\n    }\n    /* jshint +W122 */\n\n    return other instanceof this.expectedObject;\n  };\n\n  Any.prototype.jasmineToString = function() {\n    return '<jasmine.any(' + j$.fnNameFor(this.expectedObject) + ')>';\n  };\n\n  return Any;\n};\n\ngetJasmineRequireObj().Anything = function(j$) {\n  function Anything() {}\n\n  Anything.prototype.asymmetricMatch = function(other) {\n    return !j$.util.isUndefined(other) && other !== null;\n  };\n\n  Anything.prototype.jasmineToString = function() {\n    return '<jasmine.anything>';\n  };\n\n  return Anything;\n};\n\ngetJasmineRequireObj().ArrayContaining = function(j$) {\n  function ArrayContaining(sample) {\n    this.sample = sample;\n  }\n\n  ArrayContaining.prototype.asymmetricMatch = function(other, matchersUtil) {\n    if (!j$.isArray_(this.sample)) {\n      throw new Error(\n        'You must provide an array to arrayContaining, not ' +\n          j$.basicPrettyPrinter_(this.sample) +\n          '.'\n      );\n    }\n\n    // If the actual parameter is not an array, we can fail immediately, since it couldn't\n    // possibly be an \"array containing\" anything. However, we also want an empty sample\n    // array to match anything, so we need to double-check we aren't in that case\n    if (!j$.isArray_(other) && this.sample.length > 0) {\n      return false;\n    }\n\n    for (var i = 0; i < this.sample.length; i++) {\n      var item = this.sample[i];\n      if (!matchersUtil.contains(other, item)) {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n  ArrayContaining.prototype.jasmineToString = function(pp) {\n    return '<jasmine.arrayContaining(' + pp(this.sample) + ')>';\n  };\n\n  return ArrayContaining;\n};\n\ngetJasmineRequireObj().ArrayWithExactContents = function(j$) {\n  function ArrayWithExactContents(sample) {\n    this.sample = sample;\n  }\n\n  ArrayWithExactContents.prototype.asymmetricMatch = function(\n    other,\n    matchersUtil\n  ) {\n    if (!j$.isArray_(this.sample)) {\n      throw new Error(\n        'You must provide an array to arrayWithExactContents, not ' +\n          j$.basicPrettyPrinter_(this.sample) +\n          '.'\n      );\n    }\n\n    if (this.sample.length !== other.length) {\n      return false;\n    }\n\n    for (var i = 0; i < this.sample.length; i++) {\n      var item = this.sample[i];\n      if (!matchersUtil.contains(other, item)) {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n  ArrayWithExactContents.prototype.jasmineToString = function(pp) {\n    return '<jasmine.arrayWithExactContents(' + pp(this.sample) + ')>';\n  };\n\n  return ArrayWithExactContents;\n};\n\ngetJasmineRequireObj().Empty = function(j$) {\n  function Empty() {}\n\n  Empty.prototype.asymmetricMatch = function(other) {\n    if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) {\n      return other.length === 0;\n    }\n\n    if (j$.isMap(other) || j$.isSet(other)) {\n      return other.size === 0;\n    }\n\n    if (j$.isObject_(other)) {\n      return Object.keys(other).length === 0;\n    }\n    return false;\n  };\n\n  Empty.prototype.jasmineToString = function() {\n    return '<jasmine.empty>';\n  };\n\n  return Empty;\n};\n\ngetJasmineRequireObj().Falsy = function(j$) {\n  function Falsy() {}\n\n  Falsy.prototype.asymmetricMatch = function(other) {\n    return !other;\n  };\n\n  Falsy.prototype.jasmineToString = function() {\n    return '<jasmine.falsy>';\n  };\n\n  return Falsy;\n};\n\ngetJasmineRequireObj().MapContaining = function(j$) {\n  function MapContaining(sample) {\n    if (!j$.isMap(sample)) {\n      throw new Error(\n        'You must provide a map to `mapContaining`, not ' +\n          j$.basicPrettyPrinter_(sample)\n      );\n    }\n\n    this.sample = sample;\n  }\n\n  MapContaining.prototype.asymmetricMatch = function(other, matchersUtil) {\n    if (!j$.isMap(other)) return false;\n\n    for (const [key, value] of this.sample) {\n      // for each key/value pair in `sample`\n      // there should be at least one pair in `other` whose key and value both match\n      var hasMatch = false;\n      for (const [oKey, oValue] of other) {\n        if (\n          matchersUtil.equals(oKey, key) &&\n          matchersUtil.equals(oValue, value)\n        ) {\n          hasMatch = true;\n          break;\n        }\n      }\n\n      if (!hasMatch) {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n  MapContaining.prototype.jasmineToString = function(pp) {\n    return '<jasmine.mapContaining(' + pp(this.sample) + ')>';\n  };\n\n  return MapContaining;\n};\n\ngetJasmineRequireObj().NotEmpty = function(j$) {\n  function NotEmpty() {}\n\n  NotEmpty.prototype.asymmetricMatch = function(other) {\n    if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) {\n      return other.length !== 0;\n    }\n\n    if (j$.isMap(other) || j$.isSet(other)) {\n      return other.size !== 0;\n    }\n\n    if (j$.isObject_(other)) {\n      return Object.keys(other).length !== 0;\n    }\n\n    return false;\n  };\n\n  NotEmpty.prototype.jasmineToString = function() {\n    return '<jasmine.notEmpty>';\n  };\n\n  return NotEmpty;\n};\n\ngetJasmineRequireObj().ObjectContaining = function(j$) {\n  function ObjectContaining(sample) {\n    this.sample = sample;\n  }\n\n  function hasProperty(obj, property) {\n    if (!obj || typeof obj !== 'object') {\n      return false;\n    }\n\n    if (Object.prototype.hasOwnProperty.call(obj, property)) {\n      return true;\n    }\n\n    return hasProperty(Object.getPrototypeOf(obj), property);\n  }\n\n  ObjectContaining.prototype.asymmetricMatch = function(other, matchersUtil) {\n    if (typeof this.sample !== 'object') {\n      throw new Error(\n        \"You must provide an object to objectContaining, not '\" +\n          this.sample +\n          \"'.\"\n      );\n    }\n    if (typeof other !== 'object') {\n      return false;\n    }\n\n    for (var property in this.sample) {\n      if (\n        !hasProperty(other, property) ||\n        !matchersUtil.equals(this.sample[property], other[property])\n      ) {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n  ObjectContaining.prototype.valuesForDiff_ = function(other, pp) {\n    if (!j$.isObject_(other)) {\n      return {\n        self: this.jasmineToString(pp),\n        other: other\n      };\n    }\n\n    var filteredOther = {};\n    Object.keys(this.sample).forEach(function(k) {\n      // eq short-circuits comparison of objects that have different key sets,\n      // so include all keys even if undefined.\n      filteredOther[k] = other[k];\n    });\n\n    return {\n      self: this.sample,\n      other: filteredOther\n    };\n  };\n\n  ObjectContaining.prototype.jasmineToString = function(pp) {\n    return '<jasmine.objectContaining(' + pp(this.sample) + ')>';\n  };\n\n  return ObjectContaining;\n};\n\ngetJasmineRequireObj().SetContaining = function(j$) {\n  function SetContaining(sample) {\n    if (!j$.isSet(sample)) {\n      throw new Error(\n        'You must provide a set to `setContaining`, not ' +\n          j$.basicPrettyPrinter_(sample)\n      );\n    }\n\n    this.sample = sample;\n  }\n\n  SetContaining.prototype.asymmetricMatch = function(other, matchersUtil) {\n    if (!j$.isSet(other)) return false;\n\n    for (const item of this.sample) {\n      // for each item in `sample` there should be at least one matching item in `other`\n      // (not using `matchersUtil.contains` because it compares set members by reference,\n      // not by deep value equality)\n      var hasMatch = false;\n      for (const oItem of other) {\n        if (matchersUtil.equals(oItem, item)) {\n          hasMatch = true;\n          break;\n        }\n      }\n\n      if (!hasMatch) {\n        return false;\n      }\n    }\n\n    return true;\n  };\n\n  SetContaining.prototype.jasmineToString = function(pp) {\n    return '<jasmine.setContaining(' + pp(this.sample) + ')>';\n  };\n\n  return SetContaining;\n};\n\ngetJasmineRequireObj().StringContaining = function(j$) {\n  function StringContaining(expected) {\n    if (!j$.isString_(expected)) {\n      throw new Error('Expected is not a String');\n    }\n\n    this.expected = expected;\n  }\n\n  StringContaining.prototype.asymmetricMatch = function(other) {\n    if (!j$.isString_(other)) {\n      // Arrays, etc. don't match no matter what their indexOf returns.\n      return false;\n    }\n\n    return other.indexOf(this.expected) !== -1;\n  };\n\n  StringContaining.prototype.jasmineToString = function() {\n    return '<jasmine.stringContaining(\"' + this.expected + '\")>';\n  };\n\n  return StringContaining;\n};\n\ngetJasmineRequireObj().StringMatching = function(j$) {\n  function StringMatching(expected) {\n    if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {\n      throw new Error('Expected is not a String or a RegExp');\n    }\n\n    this.regexp = new RegExp(expected);\n  }\n\n  StringMatching.prototype.asymmetricMatch = function(other) {\n    return this.regexp.test(other);\n  };\n\n  StringMatching.prototype.jasmineToString = function() {\n    return '<jasmine.stringMatching(' + this.regexp + ')>';\n  };\n\n  return StringMatching;\n};\n\ngetJasmineRequireObj().Truthy = function(j$) {\n  function Truthy() {}\n\n  Truthy.prototype.asymmetricMatch = function(other) {\n    return !!other;\n  };\n\n  Truthy.prototype.jasmineToString = function() {\n    return '<jasmine.truthy>';\n  };\n\n  return Truthy;\n};\n\ngetJasmineRequireObj().CallTracker = function(j$) {\n  /**\n   * @namespace Spy#calls\n   * @since 2.0.0\n   */\n  function CallTracker() {\n    var calls = [];\n    var opts = {};\n\n    this.track = function(context) {\n      if (opts.cloneArgs) {\n        context.args = j$.util.cloneArgs(context.args);\n      }\n      calls.push(context);\n    };\n\n    /**\n     * Check whether this spy has been invoked.\n     * @name Spy#calls#any\n     * @since 2.0.0\n     * @function\n     * @return {Boolean}\n     */\n    this.any = function() {\n      return !!calls.length;\n    };\n\n    /**\n     * Get the number of invocations of this spy.\n     * @name Spy#calls#count\n     * @since 2.0.0\n     * @function\n     * @return {Integer}\n     */\n    this.count = function() {\n      return calls.length;\n    };\n\n    /**\n     * Get the arguments that were passed to a specific invocation of this spy.\n     * @name Spy#calls#argsFor\n     * @since 2.0.0\n     * @function\n     * @param {Integer} index The 0-based invocation index.\n     * @return {Array}\n     */\n    this.argsFor = function(index) {\n      var call = calls[index];\n      return call ? call.args : [];\n    };\n\n    /**\n     * Get the \"this\" object that was passed to a specific invocation of this spy.\n     * @name Spy#calls#thisFor\n     * @since 3.8.0\n     * @function\n     * @param {Integer} index The 0-based invocation index.\n     * @return {Object?}\n     */\n    this.thisFor = function(index) {\n      var call = calls[index];\n      return call ? call.object : undefined;\n    };\n\n    /**\n     * Get the raw calls array for this spy.\n     * @name Spy#calls#all\n     * @since 2.0.0\n     * @function\n     * @return {Spy.callData[]}\n     */\n    this.all = function() {\n      return calls;\n    };\n\n    /**\n     * Get all of the arguments for each invocation of this spy in the order they were received.\n     * @name Spy#calls#allArgs\n     * @since 2.0.0\n     * @function\n     * @return {Array}\n     */\n    this.allArgs = function() {\n      var callArgs = [];\n      for (var i = 0; i < calls.length; i++) {\n        callArgs.push(calls[i].args);\n      }\n\n      return callArgs;\n    };\n\n    /**\n     * Get the first invocation of this spy.\n     * @name Spy#calls#first\n     * @since 2.0.0\n     * @function\n     * @return {ObjecSpy.callData}\n     */\n    this.first = function() {\n      return calls[0];\n    };\n\n    /**\n     * Get the most recent invocation of this spy.\n     * @name Spy#calls#mostRecent\n     * @since 2.0.0\n     * @function\n     * @return {ObjecSpy.callData}\n     */\n    this.mostRecent = function() {\n      return calls[calls.length - 1];\n    };\n\n    /**\n     * Reset this spy as if it has never been called.\n     * @name Spy#calls#reset\n     * @since 2.0.0\n     * @function\n     */\n    this.reset = function() {\n      calls = [];\n    };\n\n    /**\n     * Set this spy to do a shallow clone of arguments passed to each invocation.\n     * @name Spy#calls#saveArgumentsByValue\n     * @since 2.5.0\n     * @function\n     */\n    this.saveArgumentsByValue = function() {\n      opts.cloneArgs = true;\n    };\n  }\n\n  return CallTracker;\n};\n\ngetJasmineRequireObj().clearStack = function(j$) {\n  var maxInlineCallCount = 10;\n\n  function messageChannelImpl(global, setTimeout) {\n    var channel = new global.MessageChannel(),\n      head = {},\n      tail = head;\n\n    var taskRunning = false;\n    channel.port1.onmessage = function() {\n      head = head.next;\n      var task = head.task;\n      delete head.task;\n\n      if (taskRunning) {\n        global.setTimeout(task, 0);\n      } else {\n        try {\n          taskRunning = true;\n          task();\n        } finally {\n          taskRunning = false;\n        }\n      }\n    };\n\n    var currentCallCount = 0;\n    return function clearStack(fn) {\n      currentCallCount++;\n\n      if (currentCallCount < maxInlineCallCount) {\n        tail = tail.next = { task: fn };\n        channel.port2.postMessage(0);\n      } else {\n        currentCallCount = 0;\n        setTimeout(fn);\n      }\n    };\n  }\n\n  function getClearStack(global) {\n    var currentCallCount = 0;\n    var realSetTimeout = global.setTimeout;\n    var setTimeoutImpl = function clearStack(fn) {\n      Function.prototype.apply.apply(realSetTimeout, [global, [fn, 0]]);\n    };\n\n    if (j$.isFunction_(global.setImmediate)) {\n      var realSetImmediate = global.setImmediate;\n      return function(fn) {\n        currentCallCount++;\n\n        if (currentCallCount < maxInlineCallCount) {\n          realSetImmediate(fn);\n        } else {\n          currentCallCount = 0;\n\n          setTimeoutImpl(fn);\n        }\n      };\n    } else if (!j$.util.isUndefined(global.MessageChannel)) {\n      return messageChannelImpl(global, setTimeoutImpl);\n    } else {\n      return setTimeoutImpl;\n    }\n  }\n\n  return getClearStack;\n};\n\ngetJasmineRequireObj().Clock = function() {\n  /* global process */\n  var NODE_JS =\n    typeof process !== 'undefined' &&\n    process.versions &&\n    typeof process.versions.node === 'string';\n\n  /**\n   * @class Clock\n   * @since 1.3.0\n   * @classdesc Jasmine's mock clock is used when testing time dependent code.<br>\n   * _Note:_ Do not construct this directly. You can get the current clock with\n   * {@link jasmine.clock}.\n   * @hideconstructor\n   */\n  function Clock(global, delayedFunctionSchedulerFactory, mockDate) {\n    var self = this,\n      realTimingFunctions = {\n        setTimeout: global.setTimeout,\n        clearTimeout: global.clearTimeout,\n        setInterval: global.setInterval,\n        clearInterval: global.clearInterval\n      },\n      fakeTimingFunctions = {\n        setTimeout: setTimeout,\n        clearTimeout: clearTimeout,\n        setInterval: setInterval,\n        clearInterval: clearInterval\n      },\n      installed = false,\n      delayedFunctionScheduler,\n      timer;\n\n    self.FakeTimeout = FakeTimeout;\n\n    /**\n     * Install the mock clock over the built-in methods.\n     * @name Clock#install\n     * @since 2.0.0\n     * @function\n     * @return {Clock}\n     */\n    self.install = function() {\n      if (!originalTimingFunctionsIntact()) {\n        throw new Error(\n          'Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?'\n        );\n      }\n      replace(global, fakeTimingFunctions);\n      timer = fakeTimingFunctions;\n      delayedFunctionScheduler = delayedFunctionSchedulerFactory();\n      installed = true;\n\n      return self;\n    };\n\n    /**\n     * Uninstall the mock clock, returning the built-in methods to their places.\n     * @name Clock#uninstall\n     * @since 2.0.0\n     * @function\n     */\n    self.uninstall = function() {\n      delayedFunctionScheduler = null;\n      mockDate.uninstall();\n      replace(global, realTimingFunctions);\n\n      timer = realTimingFunctions;\n      installed = false;\n    };\n\n    /**\n     * Execute a function with a mocked Clock\n     *\n     * The clock will be {@link Clock#install|install}ed before the function is called and {@link Clock#uninstall|uninstall}ed in a `finally` after the function completes.\n     * @name Clock#withMock\n     * @since 2.3.0\n     * @function\n     * @param {Function} closure The function to be called.\n     */\n    self.withMock = function(closure) {\n      this.install();\n      try {\n        closure();\n      } finally {\n        this.uninstall();\n      }\n    };\n\n    /**\n     * Instruct the installed Clock to also mock the date returned by `new Date()`\n     * @name Clock#mockDate\n     * @since 2.1.0\n     * @function\n     * @param {Date} [initialDate=now] The `Date` to provide.\n     */\n    self.mockDate = function(initialDate) {\n      mockDate.install(initialDate);\n    };\n\n    self.setTimeout = function(fn, delay, params) {\n      return Function.prototype.apply.apply(timer.setTimeout, [\n        global,\n        arguments\n      ]);\n    };\n\n    self.setInterval = function(fn, delay, params) {\n      return Function.prototype.apply.apply(timer.setInterval, [\n        global,\n        arguments\n      ]);\n    };\n\n    self.clearTimeout = function(id) {\n      return Function.prototype.call.apply(timer.clearTimeout, [global, id]);\n    };\n\n    self.clearInterval = function(id) {\n      return Function.prototype.call.apply(timer.clearInterval, [global, id]);\n    };\n\n    /**\n     * Tick the Clock forward, running any enqueued timeouts along the way\n     * @name Clock#tick\n     * @since 1.3.0\n     * @function\n     * @param {int} millis The number of milliseconds to tick.\n     */\n    self.tick = function(millis) {\n      if (installed) {\n        delayedFunctionScheduler.tick(millis, function(millis) {\n          mockDate.tick(millis);\n        });\n      } else {\n        throw new Error(\n          'Mock clock is not installed, use jasmine.clock().install()'\n        );\n      }\n    };\n\n    return self;\n\n    function originalTimingFunctionsIntact() {\n      return (\n        global.setTimeout === realTimingFunctions.setTimeout &&\n        global.clearTimeout === realTimingFunctions.clearTimeout &&\n        global.setInterval === realTimingFunctions.setInterval &&\n        global.clearInterval === realTimingFunctions.clearInterval\n      );\n    }\n\n    function replace(dest, source) {\n      for (var prop in source) {\n        dest[prop] = source[prop];\n      }\n    }\n\n    function setTimeout(fn, delay) {\n      if (!NODE_JS) {\n        return delayedFunctionScheduler.scheduleFunction(\n          fn,\n          delay,\n          argSlice(arguments, 2)\n        );\n      }\n\n      var timeout = new FakeTimeout();\n\n      delayedFunctionScheduler.scheduleFunction(\n        fn,\n        delay,\n        argSlice(arguments, 2),\n        false,\n        timeout\n      );\n\n      return timeout;\n    }\n\n    function clearTimeout(id) {\n      return delayedFunctionScheduler.removeFunctionWithId(id);\n    }\n\n    function setInterval(fn, interval) {\n      if (!NODE_JS) {\n        return delayedFunctionScheduler.scheduleFunction(\n          fn,\n          interval,\n          argSlice(arguments, 2),\n          true\n        );\n      }\n\n      var timeout = new FakeTimeout();\n\n      delayedFunctionScheduler.scheduleFunction(\n        fn,\n        interval,\n        argSlice(arguments, 2),\n        true,\n        timeout\n      );\n\n      return timeout;\n    }\n\n    function clearInterval(id) {\n      return delayedFunctionScheduler.removeFunctionWithId(id);\n    }\n\n    function argSlice(argsObj, n) {\n      return Array.prototype.slice.call(argsObj, n);\n    }\n  }\n\n  /**\n   * Mocks Node.js Timeout class\n   */\n  function FakeTimeout() {}\n\n  FakeTimeout.prototype.ref = function() {\n    return this;\n  };\n\n  FakeTimeout.prototype.unref = function() {\n    return this;\n  };\n\n  return Clock;\n};\n\ngetJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {\n  function CompleteOnFirstErrorSkipPolicy(queueableFns) {\n    this.queueableFns_ = queueableFns;\n    this.erroredFnIx_ = null;\n  }\n\n  CompleteOnFirstErrorSkipPolicy.prototype.skipTo = function(lastRanFnIx) {\n    let i;\n\n    for (\n      i = lastRanFnIx + 1;\n      i < this.queueableFns_.length && this.shouldSkip_(i);\n      i++\n    ) {}\n    return i;\n  };\n\n  CompleteOnFirstErrorSkipPolicy.prototype.fnErrored = function(fnIx) {\n    this.erroredFnIx_ = fnIx;\n  };\n\n  CompleteOnFirstErrorSkipPolicy.prototype.shouldSkip_ = function(fnIx) {\n    if (this.erroredFnIx_ === null) {\n      return false;\n    }\n\n    const fn = this.queueableFns_[fnIx];\n    const candidateSuite = fn.suite;\n    const errorSuite = this.queueableFns_[this.erroredFnIx_].suite;\n    const wasCleanupFn =\n      fn.type === 'afterEach' ||\n      fn.type === 'afterAll' ||\n      fn.type === 'specCleanup';\n    return (\n      !wasCleanupFn ||\n      (candidateSuite && isDescendent(candidateSuite, errorSuite))\n    );\n  };\n\n  function isDescendent(candidate, ancestor) {\n    if (!candidate.parentSuite) {\n      return false;\n    } else if (candidate.parentSuite === ancestor) {\n      return true;\n    } else {\n      return isDescendent(candidate.parentSuite, ancestor);\n    }\n  }\n\n  return CompleteOnFirstErrorSkipPolicy;\n};\n\ngetJasmineRequireObj().DelayedFunctionScheduler = function(j$) {\n  function DelayedFunctionScheduler() {\n    var self = this;\n    var scheduledLookup = [];\n    var scheduledFunctions = {};\n    var currentTime = 0;\n    var delayedFnCount = 0;\n    var deletedKeys = [];\n\n    self.tick = function(millis, tickDate) {\n      millis = millis || 0;\n      var endTime = currentTime + millis;\n\n      runScheduledFunctions(endTime, tickDate);\n    };\n\n    self.scheduleFunction = function(\n      funcToCall,\n      millis,\n      params,\n      recurring,\n      timeoutKey,\n      runAtMillis\n    ) {\n      var f;\n      if (typeof funcToCall === 'string') {\n        /* jshint evil: true */\n        f = function() {\n          return eval(funcToCall);\n        };\n        /* jshint evil: false */\n      } else {\n        f = funcToCall;\n      }\n\n      millis = millis || 0;\n      timeoutKey = timeoutKey || ++delayedFnCount;\n      runAtMillis = runAtMillis || currentTime + millis;\n\n      var funcToSchedule = {\n        runAtMillis: runAtMillis,\n        funcToCall: f,\n        recurring: recurring,\n        params: params,\n        timeoutKey: timeoutKey,\n        millis: millis\n      };\n\n      if (runAtMillis in scheduledFunctions) {\n        scheduledFunctions[runAtMillis].push(funcToSchedule);\n      } else {\n        scheduledFunctions[runAtMillis] = [funcToSchedule];\n        scheduledLookup.push(runAtMillis);\n        scheduledLookup.sort(function(a, b) {\n          return a - b;\n        });\n      }\n\n      return timeoutKey;\n    };\n\n    self.removeFunctionWithId = function(timeoutKey) {\n      deletedKeys.push(timeoutKey);\n\n      for (var runAtMillis in scheduledFunctions) {\n        var funcs = scheduledFunctions[runAtMillis];\n        var i = indexOfFirstToPass(funcs, function(func) {\n          return func.timeoutKey === timeoutKey;\n        });\n\n        if (i > -1) {\n          if (funcs.length === 1) {\n            delete scheduledFunctions[runAtMillis];\n            deleteFromLookup(runAtMillis);\n          } else {\n            funcs.splice(i, 1);\n          }\n\n          // intervals get rescheduled when executed, so there's never more\n          // than a single scheduled function with a given timeoutKey\n          break;\n        }\n      }\n    };\n\n    return self;\n\n    function indexOfFirstToPass(array, testFn) {\n      var index = -1;\n\n      for (var i = 0; i < array.length; ++i) {\n        if (testFn(array[i])) {\n          index = i;\n          break;\n        }\n      }\n\n      return index;\n    }\n\n    function deleteFromLookup(key) {\n      var value = Number(key);\n      var i = indexOfFirstToPass(scheduledLookup, function(millis) {\n        return millis === value;\n      });\n\n      if (i > -1) {\n        scheduledLookup.splice(i, 1);\n      }\n    }\n\n    function reschedule(scheduledFn) {\n      self.scheduleFunction(\n        scheduledFn.funcToCall,\n        scheduledFn.millis,\n        scheduledFn.params,\n        true,\n        scheduledFn.timeoutKey,\n        scheduledFn.runAtMillis + scheduledFn.millis\n      );\n    }\n\n    function forEachFunction(funcsToRun, callback) {\n      for (var i = 0; i < funcsToRun.length; ++i) {\n        callback(funcsToRun[i]);\n      }\n    }\n\n    function runScheduledFunctions(endTime, tickDate) {\n      tickDate = tickDate || function() {};\n      if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {\n        if (endTime >= currentTime) {\n          tickDate(endTime - currentTime);\n          currentTime = endTime;\n        }\n        return;\n      }\n\n      do {\n        deletedKeys = [];\n        var newCurrentTime = scheduledLookup.shift();\n        if (newCurrentTime >= currentTime) {\n          tickDate(newCurrentTime - currentTime);\n          currentTime = newCurrentTime;\n        }\n\n        var funcsToRun = scheduledFunctions[currentTime];\n\n        delete scheduledFunctions[currentTime];\n\n        forEachFunction(funcsToRun, function(funcToRun) {\n          if (funcToRun.recurring) {\n            reschedule(funcToRun);\n          }\n        });\n\n        forEachFunction(funcsToRun, function(funcToRun) {\n          if (j$.util.arrayContains(deletedKeys, funcToRun.timeoutKey)) {\n            // skip a timeoutKey deleted whilst we were running\n            return;\n          }\n          funcToRun.funcToCall.apply(null, funcToRun.params || []);\n        });\n        deletedKeys = [];\n      } while (\n        scheduledLookup.length > 0 &&\n        // checking first if we're out of time prevents setTimeout(0)\n        // scheduled in a funcToRun from forcing an extra iteration\n        currentTime !== endTime &&\n        scheduledLookup[0] <= endTime\n      );\n\n      // ran out of functions to call, but still time left on the clock\n      if (endTime >= currentTime) {\n        tickDate(endTime - currentTime);\n        currentTime = endTime;\n      }\n    }\n  }\n\n  return DelayedFunctionScheduler;\n};\n\ngetJasmineRequireObj().Deprecator = function(j$) {\n  function Deprecator(topSuite) {\n    this.topSuite_ = topSuite;\n    this.verbose_ = false;\n    this.toSuppress_ = [];\n  }\n\n  var verboseNote =\n    'Note: This message will be shown only once. Set the verboseDeprecations ' +\n    'config property to true to see every occurrence.';\n\n  Deprecator.prototype.verboseDeprecations = function(enabled) {\n    this.verbose_ = enabled;\n  };\n\n  // runnable is a spec or a suite.\n  // deprecation is a string or an Error.\n  // See Env#deprecated for a description of the options argument.\n  Deprecator.prototype.addDeprecationWarning = function(\n    runnable,\n    deprecation,\n    options\n  ) {\n    options = options || {};\n\n    if (!this.verbose_ && !j$.isError_(deprecation)) {\n      if (this.toSuppress_.indexOf(deprecation) !== -1) {\n        return;\n      }\n      this.toSuppress_.push(deprecation);\n    }\n\n    this.log_(runnable, deprecation, options);\n    this.report_(runnable, deprecation, options);\n  };\n\n  Deprecator.prototype.log_ = function(runnable, deprecation, options) {\n    var context;\n\n    if (j$.isError_(deprecation)) {\n      console.error(deprecation);\n      return;\n    }\n\n    if (runnable === this.topSuite_ || options.ignoreRunnable) {\n      context = '';\n    } else if (runnable.children) {\n      context = ' (in suite: ' + runnable.getFullName() + ')';\n    } else {\n      context = ' (in spec: ' + runnable.getFullName() + ')';\n    }\n\n    if (!options.omitStackTrace) {\n      context += '\\n' + this.stackTrace_();\n    }\n\n    if (!this.verbose_) {\n      context += '\\n' + verboseNote;\n    }\n\n    console.error('DEPRECATION: ' + deprecation + context);\n  };\n\n  Deprecator.prototype.stackTrace_ = function() {\n    var formatter = new j$.ExceptionFormatter();\n    return formatter.stack(j$.util.errorWithStack()).replace(/^Error\\n/m, '');\n  };\n\n  Deprecator.prototype.report_ = function(runnable, deprecation, options) {\n    if (options.ignoreRunnable) {\n      runnable = this.topSuite_;\n    }\n\n    if (j$.isError_(deprecation)) {\n      runnable.addDeprecationWarning(deprecation);\n      return;\n    }\n\n    if (!this.verbose_) {\n      deprecation += '\\n' + verboseNote;\n    }\n\n    runnable.addDeprecationWarning({\n      message: deprecation,\n      omitStackTrace: options.omitStackTrace || false\n    });\n  };\n\n  return Deprecator;\n};\n\ngetJasmineRequireObj().errors = function() {\n  function ExpectationFailed() {}\n\n  ExpectationFailed.prototype = new Error();\n  ExpectationFailed.prototype.constructor = ExpectationFailed;\n\n  return {\n    ExpectationFailed: ExpectationFailed\n  };\n};\n\ngetJasmineRequireObj().ExceptionFormatter = function(j$) {\n  var ignoredProperties = [\n    'name',\n    'message',\n    'stack',\n    'fileName',\n    'sourceURL',\n    'line',\n    'lineNumber',\n    'column',\n    'description',\n    'jasmineMessage'\n  ];\n\n  function ExceptionFormatter(options) {\n    var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile();\n    this.message = function(error) {\n      var message = '';\n\n      if (error.jasmineMessage) {\n        message += error.jasmineMessage;\n      } else if (error.name && error.message) {\n        message += error.name + ': ' + error.message;\n      } else if (error.message) {\n        message += error.message;\n      } else {\n        message += error.toString() + ' thrown';\n      }\n\n      if (error.fileName || error.sourceURL) {\n        message += ' in ' + (error.fileName || error.sourceURL);\n      }\n\n      if (error.line || error.lineNumber) {\n        message += ' (line ' + (error.line || error.lineNumber) + ')';\n      }\n\n      return message;\n    };\n\n    this.stack = function(error, { omitMessage } = {}) {\n      if (!error || !error.stack) {\n        return null;\n      }\n\n      var stackTrace = new j$.StackTrace(error);\n      var lines = filterJasmine(stackTrace);\n      var result = '';\n\n      if (stackTrace.message && !omitMessage) {\n        lines.unshift(stackTrace.message);\n      }\n\n      result += formatProperties(error);\n      result += lines.join('\\n');\n\n      return result;\n    };\n\n    function filterJasmine(stackTrace) {\n      var result = [],\n        jasmineMarker =\n          stackTrace.style === 'webkit' ? '<Jasmine>' : '    at <Jasmine>';\n\n      stackTrace.frames.forEach(function(frame) {\n        if (frame.file && frame.file === jasmineFile) {\n          if (result[result.length - 1] !== jasmineMarker) {\n            result.push(jasmineMarker);\n          }\n        } else {\n          result.push(frame.raw);\n        }\n      });\n\n      return result;\n    }\n\n    function formatProperties(error) {\n      if (!(error instanceof Object)) {\n        return;\n      }\n\n      var result = {};\n      var empty = true;\n\n      for (var prop in error) {\n        if (j$.util.arrayContains(ignoredProperties, prop)) {\n          continue;\n        }\n        result[prop] = error[prop];\n        empty = false;\n      }\n\n      if (!empty) {\n        return 'error properties: ' + j$.basicPrettyPrinter_(result) + '\\n';\n      }\n\n      return '';\n    }\n  }\n\n  return ExceptionFormatter;\n};\n\ngetJasmineRequireObj().Expectation = function(j$) {\n  /**\n   * Matchers that come with Jasmine out of the box.\n   * @namespace matchers\n   */\n  function Expectation(options) {\n    this.expector = new j$.Expector(options);\n\n    var customMatchers = options.customMatchers || {};\n    for (var matcherName in customMatchers) {\n      this[matcherName] = wrapSyncCompare(\n        matcherName,\n        customMatchers[matcherName]\n      );\n    }\n  }\n\n  /**\n   * Add some context for an {@link expect}\n   * @function\n   * @name matchers#withContext\n   * @since 3.3.0\n   * @param {String} message - Additional context to show when the matcher fails\n   * @return {matchers}\n   */\n  Expectation.prototype.withContext = function withContext(message) {\n    return addFilter(this, new ContextAddingFilter(message));\n  };\n\n  /**\n   * Invert the matcher following this {@link expect}\n   * @member\n   * @name matchers#not\n   * @since 1.3.0\n   * @type {matchers}\n   * @example\n   * expect(something).not.toBe(true);\n   */\n  Object.defineProperty(Expectation.prototype, 'not', {\n    get: function() {\n      return addFilter(this, syncNegatingFilter);\n    }\n  });\n\n  /**\n   * Asynchronous matchers that operate on an actual value which is a promise,\n   * and return a promise.\n   *\n   * Most async matchers will wait indefinitely for the promise to be resolved\n   * or rejected, resulting in a spec timeout if that never happens. If you\n   * expect that the promise will already be resolved or rejected at the time\n   * the matcher is called, you can use the {@link async-matchers#already}\n   * modifier to get a faster failure with a more helpful message.\n   *\n   * Note: Specs must await the result of each async matcher, return the\n   * promise returned by the matcher, or return a promise that's derived from\n   * the one returned by the matcher. Otherwise the matcher will not be\n   * evaluated before the spec completes.\n   *\n   * @example\n   * // Good\n   * await expectAsync(aPromise).toBeResolved();\n   * @example\n   * // Good\n   * return expectAsync(aPromise).toBeResolved();\n   * @example\n   * // Good\n   * return expectAsync(aPromise).toBeResolved()\n   *  .then(function() {\n   *    // more spec code\n   *  });\n   * @example\n   * // Bad\n   * expectAsync(aPromise).toBeResolved();\n   * @namespace async-matchers\n   */\n  function AsyncExpectation(options) {\n    this.expector = new j$.Expector(options);\n\n    var customAsyncMatchers = options.customAsyncMatchers || {};\n    for (var matcherName in customAsyncMatchers) {\n      this[matcherName] = wrapAsyncCompare(\n        matcherName,\n        customAsyncMatchers[matcherName]\n      );\n    }\n  }\n\n  /**\n   * Add some context for an {@link expectAsync}\n   * @function\n   * @name async-matchers#withContext\n   * @since 3.3.0\n   * @param {String} message - Additional context to show when the async matcher fails\n   * @return {async-matchers}\n   */\n  AsyncExpectation.prototype.withContext = function withContext(message) {\n    return addFilter(this, new ContextAddingFilter(message));\n  };\n\n  /**\n   * Invert the matcher following this {@link expectAsync}\n   * @member\n   * @name async-matchers#not\n   * @type {async-matchers}\n   * @example\n   * await expectAsync(myPromise).not.toBeResolved();\n   * @example\n   * return expectAsync(myPromise).not.toBeResolved();\n   */\n  Object.defineProperty(AsyncExpectation.prototype, 'not', {\n    get: function() {\n      return addFilter(this, asyncNegatingFilter);\n    }\n  });\n\n  /**\n   * Fail as soon as possible if the actual is pending.\n   * Otherwise evaluate the matcher.\n   * @member\n   * @name async-matchers#already\n   * @since 3.8.0\n   * @type {async-matchers}\n   * @example\n   * await expectAsync(myPromise).already.toBeResolved();\n   * @example\n   * return expectAsync(myPromise).already.toBeResolved();\n   */\n  Object.defineProperty(AsyncExpectation.prototype, 'already', {\n    get: function() {\n      return addFilter(this, expectSettledPromiseFilter);\n    }\n  });\n\n  function wrapSyncCompare(name, matcherFactory) {\n    return function() {\n      var result = this.expector.compare(name, matcherFactory, arguments);\n      this.expector.processResult(result);\n    };\n  }\n\n  function wrapAsyncCompare(name, matcherFactory) {\n    return function() {\n      var self = this;\n\n      // Capture the call stack here, before we go async, so that it will contain\n      // frames that are relevant to the user instead of just parts of Jasmine.\n      var errorForStack = j$.util.errorWithStack();\n\n      return this.expector\n        .compare(name, matcherFactory, arguments)\n        .then(function(result) {\n          self.expector.processResult(result, errorForStack);\n        });\n    };\n  }\n\n  function addCoreMatchers(prototype, matchers, wrapper) {\n    for (var matcherName in matchers) {\n      var matcher = matchers[matcherName];\n      prototype[matcherName] = wrapper(matcherName, matcher);\n    }\n  }\n\n  function addFilter(source, filter) {\n    var result = Object.create(source);\n    result.expector = source.expector.addFilter(filter);\n    return result;\n  }\n\n  function negatedFailureMessage(result, matcherName, args, matchersUtil) {\n    if (result.message) {\n      if (j$.isFunction_(result.message)) {\n        return result.message();\n      } else {\n        return result.message;\n      }\n    }\n\n    args = args.slice();\n    args.unshift(true);\n    args.unshift(matcherName);\n    return matchersUtil.buildFailureMessage.apply(matchersUtil, args);\n  }\n\n  function negate(result) {\n    result.pass = !result.pass;\n    return result;\n  }\n\n  var syncNegatingFilter = {\n    selectComparisonFunc: function(matcher) {\n      function defaultNegativeCompare() {\n        return negate(matcher.compare.apply(null, arguments));\n      }\n\n      return matcher.negativeCompare || defaultNegativeCompare;\n    },\n    buildFailureMessage: negatedFailureMessage\n  };\n\n  var asyncNegatingFilter = {\n    selectComparisonFunc: function(matcher) {\n      function defaultNegativeCompare() {\n        return matcher.compare.apply(this, arguments).then(negate);\n      }\n\n      return matcher.negativeCompare || defaultNegativeCompare;\n    },\n    buildFailureMessage: negatedFailureMessage\n  };\n\n  var expectSettledPromiseFilter = {\n    selectComparisonFunc: function(matcher) {\n      return function(actual) {\n        var matcherArgs = arguments;\n\n        return j$.isPending_(actual).then(function(isPending) {\n          if (isPending) {\n            return {\n              pass: false,\n              message:\n                'Expected a promise to be settled (via ' +\n                'expectAsync(...).already) but it was pending.'\n            };\n          } else {\n            return matcher.compare.apply(null, matcherArgs);\n          }\n        });\n      };\n    }\n  };\n\n  function ContextAddingFilter(message) {\n    this.message = message;\n  }\n\n  ContextAddingFilter.prototype.modifyFailureMessage = function(msg) {\n    var nl = msg.indexOf('\\n');\n\n    if (nl === -1) {\n      return this.message + ': ' + msg;\n    } else {\n      return this.message + ':\\n' + indent(msg);\n    }\n  };\n\n  function indent(s) {\n    return s.replace(/^/gm, '    ');\n  }\n\n  return {\n    factory: function(options) {\n      return new Expectation(options || {});\n    },\n    addCoreMatchers: function(matchers) {\n      addCoreMatchers(Expectation.prototype, matchers, wrapSyncCompare);\n    },\n    asyncFactory: function(options) {\n      return new AsyncExpectation(options || {});\n    },\n    addAsyncCoreMatchers: function(matchers) {\n      addCoreMatchers(AsyncExpectation.prototype, matchers, wrapAsyncCompare);\n    }\n  };\n};\n\ngetJasmineRequireObj().ExpectationFilterChain = function() {\n  function ExpectationFilterChain(maybeFilter, prev) {\n    this.filter_ = maybeFilter;\n    this.prev_ = prev;\n  }\n\n  ExpectationFilterChain.prototype.addFilter = function(filter) {\n    return new ExpectationFilterChain(filter, this);\n  };\n\n  ExpectationFilterChain.prototype.selectComparisonFunc = function(matcher) {\n    return this.callFirst_('selectComparisonFunc', arguments).result;\n  };\n\n  ExpectationFilterChain.prototype.buildFailureMessage = function(\n    result,\n    matcherName,\n    args,\n    matchersUtil\n  ) {\n    return this.callFirst_('buildFailureMessage', arguments).result;\n  };\n\n  ExpectationFilterChain.prototype.modifyFailureMessage = function(msg) {\n    var result = this.callFirst_('modifyFailureMessage', arguments).result;\n    return result || msg;\n  };\n\n  ExpectationFilterChain.prototype.callFirst_ = function(fname, args) {\n    var prevResult;\n\n    if (this.prev_) {\n      prevResult = this.prev_.callFirst_(fname, args);\n\n      if (prevResult.found) {\n        return prevResult;\n      }\n    }\n\n    if (this.filter_ && this.filter_[fname]) {\n      return {\n        found: true,\n        result: this.filter_[fname].apply(this.filter_, args)\n      };\n    }\n\n    return { found: false };\n  };\n\n  return ExpectationFilterChain;\n};\n\n//TODO: expectation result may make more sense as a presentation of an expectation.\ngetJasmineRequireObj().buildExpectationResult = function(j$) {\n  function buildExpectationResult(options) {\n    var messageFormatter = options.messageFormatter || function() {},\n      stackFormatter = options.stackFormatter || function() {};\n\n    /**\n     * @typedef Expectation\n     * @property {String} matcherName - The name of the matcher that was executed for this expectation.\n     * @property {String} message - The failure message for the expectation.\n     * @property {String} stack - The stack trace for the failure if available.\n     * @property {Boolean} passed - Whether the expectation passed or failed.\n     * @property {Object} expected - If the expectation failed, what was the expected value.\n     * @property {Object} actual - If the expectation failed, what actual value was produced.\n     * @property {String|undefined} globalErrorType - The type of an error that\n     * is reported on the top suite. Valid values are undefined, \"afterAll\",\n     * \"load\", \"lateExpectation\", and \"lateError\".\n     */\n    var result = {\n      matcherName: options.matcherName,\n      message: message(),\n      stack: options.omitStackTrace ? '' : stack(),\n      passed: options.passed\n    };\n\n    if (!result.passed) {\n      result.expected = options.expected;\n      result.actual = options.actual;\n\n      if (options.error && !j$.isString_(options.error)) {\n        if ('code' in options.error) {\n          result.code = options.error.code;\n        }\n\n        if (\n          options.error.code === 'ERR_ASSERTION' &&\n          options.expected === '' &&\n          options.actual === ''\n        ) {\n          result.expected = options.error.expected;\n          result.actual = options.error.actual;\n          result.matcherName = 'assert ' + options.error.operator;\n        }\n      }\n    }\n\n    return result;\n\n    function message() {\n      if (options.passed) {\n        return 'Passed.';\n      } else if (options.message) {\n        return options.message;\n      } else if (options.error) {\n        return messageFormatter(options.error);\n      }\n      return '';\n    }\n\n    function stack() {\n      if (options.passed) {\n        return '';\n      }\n\n      var error = options.error;\n      if (!error) {\n        if (options.errorForStack) {\n          error = options.errorForStack;\n        } else if (options.stack) {\n          error = options;\n        } else {\n          try {\n            throw new Error(message());\n          } catch (e) {\n            error = e;\n          }\n        }\n      }\n      // Omit the message from the stack trace because it will be\n      // included elsewhere.\n      return stackFormatter(error, { omitMessage: true });\n    }\n  }\n\n  return buildExpectationResult;\n};\n\ngetJasmineRequireObj().Expector = function(j$) {\n  function Expector(options) {\n    this.matchersUtil = options.matchersUtil || {\n      buildFailureMessage: function() {}\n    };\n    this.actual = options.actual;\n    this.addExpectationResult = options.addExpectationResult || function() {};\n    this.filters = new j$.ExpectationFilterChain();\n  }\n\n  Expector.prototype.instantiateMatcher = function(\n    matcherName,\n    matcherFactory,\n    args\n  ) {\n    this.matcherName = matcherName;\n    this.args = Array.prototype.slice.call(args, 0);\n    this.expected = this.args.slice(0);\n\n    this.args.unshift(this.actual);\n\n    var matcher = matcherFactory(this.matchersUtil);\n\n    var comparisonFunc = this.filters.selectComparisonFunc(matcher);\n    return comparisonFunc || matcher.compare;\n  };\n\n  Expector.prototype.buildMessage = function(result) {\n    var self = this;\n\n    if (result.pass) {\n      return '';\n    }\n\n    var msg = this.filters.buildFailureMessage(\n      result,\n      this.matcherName,\n      this.args,\n      this.matchersUtil,\n      defaultMessage\n    );\n    return this.filters.modifyFailureMessage(msg || defaultMessage());\n\n    function defaultMessage() {\n      if (!result.message) {\n        var args = self.args.slice();\n        args.unshift(false);\n        args.unshift(self.matcherName);\n        return self.matchersUtil.buildFailureMessage.apply(\n          self.matchersUtil,\n          args\n        );\n      } else if (j$.isFunction_(result.message)) {\n        return result.message();\n      } else {\n        return result.message;\n      }\n    }\n  };\n\n  Expector.prototype.compare = function(matcherName, matcherFactory, args) {\n    var matcherCompare = this.instantiateMatcher(\n      matcherName,\n      matcherFactory,\n      args\n    );\n    return matcherCompare.apply(null, this.args);\n  };\n\n  Expector.prototype.addFilter = function(filter) {\n    var result = Object.create(this);\n    result.filters = this.filters.addFilter(filter);\n    return result;\n  };\n\n  Expector.prototype.processResult = function(result, errorForStack) {\n    var message = this.buildMessage(result);\n\n    if (this.expected.length === 1) {\n      this.expected = this.expected[0];\n    }\n\n    this.addExpectationResult(result.pass, {\n      matcherName: this.matcherName,\n      passed: result.pass,\n      message: message,\n      error: errorForStack ? undefined : result.error,\n      errorForStack: errorForStack || undefined,\n      actual: this.actual,\n      expected: this.expected // TODO: this may need to be arrayified/sliced\n    });\n  };\n\n  return Expector;\n};\n\ngetJasmineRequireObj().formatErrorMsg = function() {\n  function generateErrorMsg(domain, usage) {\n    var usageDefinition = usage ? '\\nUsage: ' + usage : '';\n\n    return function errorMsg(msg) {\n      return domain + ' : ' + msg + usageDefinition;\n    };\n  }\n\n  return generateErrorMsg;\n};\n\ngetJasmineRequireObj().GlobalErrors = function(j$) {\n  function GlobalErrors(global) {\n    var handlers = [];\n    global = global || j$.getGlobal();\n\n    var onerror = function onerror() {\n      var handler = handlers[handlers.length - 1];\n\n      if (handler) {\n        handler.apply(null, Array.prototype.slice.call(arguments, 0));\n      } else {\n        throw arguments[0];\n      }\n    };\n\n    this.originalHandlers = {};\n    this.jasmineHandlers = {};\n    this.installOne_ = function installOne_(errorType, jasmineMessage) {\n      function taggedOnError(error) {\n        var substituteMsg;\n\n        if (j$.isError_(error)) {\n          error.jasmineMessage = jasmineMessage + ': ' + error;\n        } else {\n          if (error) {\n            substituteMsg = jasmineMessage + ': ' + error;\n          } else {\n            substituteMsg = jasmineMessage + ' with no error or message';\n          }\n\n          if (errorType === 'unhandledRejection') {\n            substituteMsg +=\n              '\\n' +\n              '(Tip: to get a useful stack trace, use ' +\n              'Promise.reject(new Error(...)) instead of Promise.reject(' +\n              (error ? '...' : '') +\n              ').)';\n          }\n\n          error = new Error(substituteMsg);\n        }\n\n        var handler = handlers[handlers.length - 1];\n\n        if (handler) {\n          handler(error);\n        } else {\n          throw error;\n        }\n      }\n\n      this.originalHandlers[errorType] = global.process.listeners(errorType);\n      this.jasmineHandlers[errorType] = taggedOnError;\n\n      global.process.removeAllListeners(errorType);\n      global.process.on(errorType, taggedOnError);\n\n      this.uninstall = function uninstall() {\n        var errorTypes = Object.keys(this.originalHandlers);\n        for (var iType = 0; iType < errorTypes.length; iType++) {\n          var errorType = errorTypes[iType];\n          global.process.removeListener(\n            errorType,\n            this.jasmineHandlers[errorType]\n          );\n          for (var i = 0; i < this.originalHandlers[errorType].length; i++) {\n            global.process.on(errorType, this.originalHandlers[errorType][i]);\n          }\n          delete this.originalHandlers[errorType];\n          delete this.jasmineHandlers[errorType];\n        }\n      };\n    };\n\n    this.install = function install() {\n      if (\n        global.process &&\n        global.process.listeners &&\n        j$.isFunction_(global.process.on)\n      ) {\n        this.installOne_('uncaughtException', 'Uncaught exception');\n        this.installOne_('unhandledRejection', 'Unhandled promise rejection');\n      } else {\n        var originalHandler = global.onerror;\n        global.onerror = onerror;\n\n        var browserRejectionHandler = function browserRejectionHandler(event) {\n          if (j$.isError_(event.reason)) {\n            event.reason.jasmineMessage =\n              'Unhandled promise rejection: ' + event.reason;\n            global.onerror(event.reason);\n          } else {\n            global.onerror('Unhandled promise rejection: ' + event.reason);\n          }\n        };\n\n        if (global.addEventListener) {\n          global.addEventListener(\n            'unhandledrejection',\n            browserRejectionHandler\n          );\n        }\n\n        this.uninstall = function uninstall() {\n          global.onerror = originalHandler;\n          if (global.removeEventListener) {\n            global.removeEventListener(\n              'unhandledrejection',\n              browserRejectionHandler\n            );\n          }\n        };\n      }\n    };\n\n    this.pushListener = function pushListener(listener) {\n      handlers.push(listener);\n    };\n\n    this.popListener = function popListener(listener) {\n      if (!listener) {\n        throw new Error('popListener expects a listener');\n      }\n\n      handlers.pop();\n    };\n  }\n\n  return GlobalErrors;\n};\n\ngetJasmineRequireObj().toBePending = function(j$) {\n  /**\n   * Expect a promise to be pending, i.e. the promise is neither resolved nor rejected.\n   * @function\n   * @async\n   * @name async-matchers#toBePending\n   * @since 3.6\n   * @example\n   * await expectAsync(aPromise).toBePending();\n   */\n  return function toBePending() {\n    return {\n      compare: function(actual) {\n        if (!j$.isPromiseLike(actual)) {\n          throw new Error('Expected toBePending to be called on a promise.');\n        }\n        var want = {};\n        return Promise.race([actual, Promise.resolve(want)]).then(\n          function(got) {\n            return { pass: want === got };\n          },\n          function() {\n            return { pass: false };\n          }\n        );\n      }\n    };\n  };\n};\n\ngetJasmineRequireObj().toBeRejected = function(j$) {\n  /**\n   * Expect a promise to be rejected.\n   * @function\n   * @async\n   * @name async-matchers#toBeRejected\n   * @since 3.1.0\n   * @example\n   * await expectAsync(aPromise).toBeRejected();\n   * @example\n   * return expectAsync(aPromise).toBeRejected();\n   */\n  return function toBeRejected() {\n    return {\n      compare: function(actual) {\n        if (!j$.isPromiseLike(actual)) {\n          throw new Error('Expected toBeRejected to be called on a promise.');\n        }\n        return actual.then(\n          function() {\n            return { pass: false };\n          },\n          function() {\n            return { pass: true };\n          }\n        );\n      }\n    };\n  };\n};\n\ngetJasmineRequireObj().toBeRejectedWith = function(j$) {\n  /**\n   * Expect a promise to be rejected with a value equal to the expected, using deep equality comparison.\n   * @function\n   * @async\n   * @name async-matchers#toBeRejectedWith\n   * @since 3.3.0\n   * @param {Object} expected - Value that the promise is expected to be rejected with\n   * @example\n   * await expectAsync(aPromise).toBeRejectedWith({prop: 'value'});\n   * @example\n   * return expectAsync(aPromise).toBeRejectedWith({prop: 'value'});\n   */\n  return function toBeRejectedWith(matchersUtil) {\n    return {\n      compare: function(actualPromise, expectedValue) {\n        if (!j$.isPromiseLike(actualPromise)) {\n          throw new Error(\n            'Expected toBeRejectedWith to be called on a promise.'\n          );\n        }\n\n        function prefix(passed) {\n          return (\n            'Expected a promise ' +\n            (passed ? 'not ' : '') +\n            'to be rejected with ' +\n            matchersUtil.pp(expectedValue)\n          );\n        }\n\n        return actualPromise.then(\n          function() {\n            return {\n              pass: false,\n              message: prefix(false) + ' but it was resolved.'\n            };\n          },\n          function(actualValue) {\n            if (matchersUtil.equals(actualValue, expectedValue)) {\n              return {\n                pass: true,\n                message: prefix(true) + '.'\n              };\n            } else {\n              return {\n                pass: false,\n                message:\n                  prefix(false) +\n                  ' but it was rejected with ' +\n                  matchersUtil.pp(actualValue) +\n                  '.'\n              };\n            }\n          }\n        );\n      }\n    };\n  };\n};\n\ngetJasmineRequireObj().toBeRejectedWithError = function(j$) {\n  /**\n   * Expect a promise to be rejected with a value matched to the expected\n   * @function\n   * @async\n   * @name async-matchers#toBeRejectedWithError\n   * @since 3.5.0\n   * @param {Error} [expected] - `Error` constructor the object that was thrown needs to be an instance of. If not provided, `Error` will be used.\n   * @param {RegExp|String} [message] - The message that should be set on the thrown `Error`\n   * @example\n   * await expectAsync(aPromise).toBeRejectedWithError(MyCustomError, 'Error message');\n   * await expectAsync(aPromise).toBeRejectedWithError(MyCustomError, /Error message/);\n   * await expectAsync(aPromise).toBeRejectedWithError(MyCustomError);\n   * await expectAsync(aPromise).toBeRejectedWithError('Error message');\n   * return expectAsync(aPromise).toBeRejectedWithError(/Error message/);\n   */\n  return function toBeRejectedWithError(matchersUtil) {\n    return {\n      compare: function(actualPromise, arg1, arg2) {\n        if (!j$.isPromiseLike(actualPromise)) {\n          throw new Error(\n            'Expected toBeRejectedWithError to be called on a promise.'\n          );\n        }\n\n        var expected = getExpectedFromArgs(arg1, arg2, matchersUtil);\n\n        return actualPromise.then(\n          function() {\n            return {\n              pass: false,\n              message: 'Expected a promise to be rejected but it was resolved.'\n            };\n          },\n          function(actualValue) {\n            return matchError(actualValue, expected, matchersUtil);\n          }\n        );\n      }\n    };\n  };\n\n  function matchError(actual, expected, matchersUtil) {\n    if (!j$.isError_(actual)) {\n      return fail(expected, 'rejected with ' + matchersUtil.pp(actual));\n    }\n\n    if (!(actual instanceof expected.error)) {\n      return fail(\n        expected,\n        'rejected with type ' + j$.fnNameFor(actual.constructor)\n      );\n    }\n\n    var actualMessage = actual.message;\n\n    if (\n      actualMessage === expected.message ||\n      typeof expected.message === 'undefined'\n    ) {\n      return pass(expected);\n    }\n\n    if (\n      expected.message instanceof RegExp &&\n      expected.message.test(actualMessage)\n    ) {\n      return pass(expected);\n    }\n\n    return fail(expected, 'rejected with ' + matchersUtil.pp(actual));\n  }\n\n  function pass(expected) {\n    return {\n      pass: true,\n      message:\n        'Expected a promise not to be rejected with ' +\n        expected.printValue +\n        ', but it was.'\n    };\n  }\n\n  function fail(expected, message) {\n    return {\n      pass: false,\n      message:\n        'Expected a promise to be rejected with ' +\n        expected.printValue +\n        ' but it was ' +\n        message +\n        '.'\n    };\n  }\n\n  function getExpectedFromArgs(arg1, arg2, matchersUtil) {\n    var error, message;\n\n    if (isErrorConstructor(arg1)) {\n      error = arg1;\n      message = arg2;\n    } else {\n      error = Error;\n      message = arg1;\n    }\n\n    return {\n      error: error,\n      message: message,\n      printValue:\n        j$.fnNameFor(error) +\n        (typeof message === 'undefined' ? '' : ': ' + matchersUtil.pp(message))\n    };\n  }\n\n  function isErrorConstructor(value) {\n    return (\n      typeof value === 'function' &&\n      (value === Error || j$.isError_(value.prototype))\n    );\n  }\n};\n\ngetJasmineRequireObj().toBeResolved = function(j$) {\n  /**\n   * Expect a promise to be resolved.\n   * @function\n   * @async\n   * @name async-matchers#toBeResolved\n   * @since 3.1.0\n   * @example\n   * await expectAsync(aPromise).toBeResolved();\n   * @example\n   * return expectAsync(aPromise).toBeResolved();\n   */\n  return function toBeResolved(matchersUtil) {\n    return {\n      compare: function(actual) {\n        if (!j$.isPromiseLike(actual)) {\n          throw new Error('Expected toBeResolved to be called on a promise.');\n        }\n\n        return actual.then(\n          function() {\n            return { pass: true };\n          },\n          function(e) {\n            return {\n              pass: false,\n              message:\n                'Expected a promise to be resolved but it was ' +\n                'rejected with ' +\n                matchersUtil.pp(e) +\n                '.'\n            };\n          }\n        );\n      }\n    };\n  };\n};\n\ngetJasmineRequireObj().toBeResolvedTo = function(j$) {\n  /**\n   * Expect a promise to be resolved to a value equal to the expected, using deep equality comparison.\n   * @function\n   * @async\n   * @name async-matchers#toBeResolvedTo\n   * @since 3.1.0\n   * @param {Object} expected - Value that the promise is expected to resolve to\n   * @example\n   * await expectAsync(aPromise).toBeResolvedTo({prop: 'value'});\n   * @example\n   * return expectAsync(aPromise).toBeResolvedTo({prop: 'value'});\n   */\n  return function toBeResolvedTo(matchersUtil) {\n    return {\n      compare: function(actualPromise, expectedValue) {\n        if (!j$.isPromiseLike(actualPromise)) {\n          throw new Error('Expected toBeResolvedTo to be called on a promise.');\n        }\n\n        function prefix(passed) {\n          return (\n            'Expected a promise ' +\n            (passed ? 'not ' : '') +\n            'to be resolved to ' +\n            matchersUtil.pp(expectedValue)\n          );\n        }\n\n        return actualPromise.then(\n          function(actualValue) {\n            if (matchersUtil.equals(actualValue, expectedValue)) {\n              return {\n                pass: true,\n                message: prefix(true) + '.'\n              };\n            } else {\n              return {\n                pass: false,\n                message:\n                  prefix(false) +\n                  ' but it was resolved to ' +\n                  matchersUtil.pp(actualValue) +\n                  '.'\n              };\n            }\n          },\n          function(e) {\n            return {\n              pass: false,\n              message:\n                prefix(false) +\n                ' but it was rejected with ' +\n                matchersUtil.pp(e) +\n                '.'\n            };\n          }\n        );\n      }\n    };\n  };\n};\n\ngetJasmineRequireObj().DiffBuilder = function(j$) {\n  return function DiffBuilder(config) {\n    var prettyPrinter = (config || {}).prettyPrinter || j$.makePrettyPrinter(),\n      mismatches = new j$.MismatchTree(),\n      path = new j$.ObjectPath(),\n      actualRoot = undefined,\n      expectedRoot = undefined;\n\n    return {\n      setRoots: function(actual, expected) {\n        actualRoot = actual;\n        expectedRoot = expected;\n      },\n\n      recordMismatch: function(formatter) {\n        mismatches.add(path, formatter);\n      },\n\n      getMessage: function() {\n        var messages = [];\n\n        mismatches.traverse(function(path, isLeaf, formatter) {\n          var actualCustom,\n            expectedCustom,\n            useCustom,\n            derefResult = dereferencePath(\n              path,\n              actualRoot,\n              expectedRoot,\n              prettyPrinter\n            ),\n            actual = derefResult.actual,\n            expected = derefResult.expected;\n\n          if (formatter) {\n            messages.push(formatter(actual, expected, path, prettyPrinter));\n            return true;\n          }\n\n          actualCustom = prettyPrinter.customFormat_(actual);\n          expectedCustom = prettyPrinter.customFormat_(expected);\n          useCustom = !(\n            j$.util.isUndefined(actualCustom) &&\n            j$.util.isUndefined(expectedCustom)\n          );\n\n          if (useCustom) {\n            messages.push(\n              wrapPrettyPrinted(actualCustom, expectedCustom, path)\n            );\n            return false; // don't recurse further\n          }\n\n          if (isLeaf) {\n            messages.push(\n              defaultFormatter(actual, expected, path, prettyPrinter)\n            );\n          }\n\n          return true;\n        });\n\n        return messages.join('\\n');\n      },\n\n      withPath: function(pathComponent, block) {\n        var oldPath = path;\n        path = path.add(pathComponent);\n        block();\n        path = oldPath;\n      }\n    };\n\n    function defaultFormatter(actual, expected, path, prettyPrinter) {\n      return wrapPrettyPrinted(\n        prettyPrinter(actual),\n        prettyPrinter(expected),\n        path\n      );\n    }\n\n    function wrapPrettyPrinted(actual, expected, path) {\n      return (\n        'Expected ' +\n        path +\n        (path.depth() ? ' = ' : '') +\n        actual +\n        ' to equal ' +\n        expected +\n        '.'\n      );\n    }\n  };\n\n  function dereferencePath(objectPath, actual, expected, pp) {\n    function handleAsymmetricExpected() {\n      if (\n        j$.isAsymmetricEqualityTester_(expected) &&\n        j$.isFunction_(expected.valuesForDiff_)\n      ) {\n        var asymmetricResult = expected.valuesForDiff_(actual, pp);\n        expected = asymmetricResult.self;\n        actual = asymmetricResult.other;\n      }\n    }\n\n    var i;\n    handleAsymmetricExpected();\n\n    for (i = 0; i < objectPath.components.length; i++) {\n      actual = actual[objectPath.components[i]];\n      expected = expected[objectPath.components[i]];\n      handleAsymmetricExpected();\n    }\n\n    return { actual: actual, expected: expected };\n  }\n};\n\ngetJasmineRequireObj().MatchersUtil = function(j$) {\n  /**\n   * @class MatchersUtil\n   * @classdesc Utilities for use in implementing matchers.<br>\n   * _Note:_ Do not construct this directly. Jasmine will construct one and\n   * pass it to matchers and asymmetric equality testers.\n   * @hideconstructor\n   */\n  function MatchersUtil(options) {\n    options = options || {};\n    this.customTesters_ = options.customTesters || [];\n    /**\n     * Formats a value for use in matcher failure messages and similar contexts,\n     * taking into account the current set of custom value formatters.\n     * @function\n     * @name MatchersUtil#pp\n     * @since 3.6.0\n     * @param {*} value The value to pretty-print\n     * @return {string} The pretty-printed value\n     */\n    this.pp = options.pp || function() {};\n  }\n\n  /**\n   * Determines whether `haystack` contains `needle`, using the same comparison\n   * logic as {@link MatchersUtil#equals}.\n   * @function\n   * @name MatchersUtil#contains\n   * @since 2.0.0\n   * @param {*} haystack The collection to search\n   * @param {*} needle The value to search for\n   * @returns {boolean} True if `needle` was found in `haystack`\n   */\n  MatchersUtil.prototype.contains = function(haystack, needle) {\n    if (!haystack) {\n      return false;\n    }\n\n    if (j$.isSet(haystack)) {\n      // Try .has() first. It should be faster in cases where\n      // needle === something in haystack. Fall back to .equals() comparison\n      // if that fails.\n      if (haystack.has(needle)) {\n        return true;\n      }\n    }\n\n    if (j$.isIterable_(haystack) && !j$.isString_(haystack)) {\n      // Arrays, Sets, etc.\n      for (const candidate of haystack) {\n        if (this.equals(candidate, needle)) {\n          return true;\n        }\n      }\n\n      return false;\n    }\n\n    if (haystack.indexOf) {\n      // Mainly strings\n      return haystack.indexOf(needle) >= 0;\n    }\n\n    if (j$.isNumber_(haystack.length)) {\n      // Objects that are shaped like arrays but aren't iterable\n      for (var i = 0; i < haystack.length; i++) {\n        if (this.equals(haystack[i], needle)) {\n          return true;\n        }\n      }\n    }\n\n    return false;\n  };\n\n  MatchersUtil.prototype.buildFailureMessage = function() {\n    var self = this;\n    var args = Array.prototype.slice.call(arguments, 0),\n      matcherName = args[0],\n      isNot = args[1],\n      actual = args[2],\n      expected = args.slice(3),\n      englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) {\n        return ' ' + s.toLowerCase();\n      });\n\n    var message =\n      'Expected ' +\n      self.pp(actual) +\n      (isNot ? ' not ' : ' ') +\n      englishyPredicate;\n\n    if (expected.length > 0) {\n      for (var i = 0; i < expected.length; i++) {\n        if (i > 0) {\n          message += ',';\n        }\n        message += ' ' + self.pp(expected[i]);\n      }\n    }\n\n    return message + '.';\n  };\n\n  MatchersUtil.prototype.asymmetricDiff_ = function(\n    a,\n    b,\n    aStack,\n    bStack,\n    diffBuilder\n  ) {\n    if (j$.isFunction_(b.valuesForDiff_)) {\n      var values = b.valuesForDiff_(a, this.pp);\n      this.eq_(values.other, values.self, aStack, bStack, diffBuilder);\n    } else {\n      diffBuilder.recordMismatch();\n    }\n  };\n\n  MatchersUtil.prototype.asymmetricMatch_ = function(\n    a,\n    b,\n    aStack,\n    bStack,\n    diffBuilder\n  ) {\n    var asymmetricA = j$.isAsymmetricEqualityTester_(a),\n      asymmetricB = j$.isAsymmetricEqualityTester_(b),\n      result;\n\n    if (asymmetricA === asymmetricB) {\n      return undefined;\n    }\n\n    if (asymmetricA) {\n      result = a.asymmetricMatch(b, this);\n      if (!result) {\n        diffBuilder.recordMismatch();\n      }\n      return result;\n    }\n\n    if (asymmetricB) {\n      result = b.asymmetricMatch(a, this);\n      if (!result) {\n        this.asymmetricDiff_(a, b, aStack, bStack, diffBuilder);\n      }\n      return result;\n    }\n  };\n\n  /**\n   * Determines whether two values are deeply equal to each other.\n   * @function\n   * @name MatchersUtil#equals\n   * @since 2.0.0\n   * @param {*} a The first value to compare\n   * @param {*} b The second value to compare\n   * @returns {boolean} True if the values are equal\n   */\n  MatchersUtil.prototype.equals = function(a, b, diffBuilder) {\n    diffBuilder = diffBuilder || j$.NullDiffBuilder();\n    diffBuilder.setRoots(a, b);\n\n    return this.eq_(a, b, [], [], diffBuilder);\n  };\n\n  // Equality function lovingly adapted from isEqual in\n  //   [Underscore](http://underscorejs.org)\n  MatchersUtil.prototype.eq_ = function(a, b, aStack, bStack, diffBuilder) {\n    var result = true,\n      self = this,\n      i;\n\n    var asymmetricResult = this.asymmetricMatch_(\n      a,\n      b,\n      aStack,\n      bStack,\n      diffBuilder\n    );\n    if (!j$.util.isUndefined(asymmetricResult)) {\n      return asymmetricResult;\n    }\n\n    for (i = 0; i < this.customTesters_.length; i++) {\n      var customTesterResult = this.customTesters_[i](a, b);\n      if (!j$.util.isUndefined(customTesterResult)) {\n        if (!customTesterResult) {\n          diffBuilder.recordMismatch();\n        }\n        return customTesterResult;\n      }\n    }\n\n    if (a instanceof Error && b instanceof Error) {\n      result = a.message == b.message;\n      if (!result) {\n        diffBuilder.recordMismatch();\n      }\n      return result;\n    }\n\n    // Identical objects are equal. `0 === -0`, but they aren't identical.\n    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).\n    if (a === b) {\n      result = a !== 0 || 1 / a == 1 / b;\n      if (!result) {\n        diffBuilder.recordMismatch();\n      }\n      return result;\n    }\n    // A strict comparison is necessary because `null == undefined`.\n    if (a === null || b === null) {\n      result = a === b;\n      if (!result) {\n        diffBuilder.recordMismatch();\n      }\n      return result;\n    }\n    var className = Object.prototype.toString.call(a);\n    if (className != Object.prototype.toString.call(b)) {\n      diffBuilder.recordMismatch();\n      return false;\n    }\n    switch (className) {\n      // Strings, numbers, dates, and booleans are compared by value.\n      case '[object String]':\n        // Primitives and their corresponding object wrappers are equivalent; thus, `\"5\"` is\n        // equivalent to `new String(\"5\")`.\n        result = a == String(b);\n        if (!result) {\n          diffBuilder.recordMismatch();\n        }\n        return result;\n      case '[object Number]':\n        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for\n        // other numeric values.\n        result =\n          a != +a ? b != +b : a === 0 && b === 0 ? 1 / a == 1 / b : a == +b;\n        if (!result) {\n          diffBuilder.recordMismatch();\n        }\n        return result;\n      case '[object Date]':\n      case '[object Boolean]':\n        // Coerce dates and booleans to numeric primitive values. Dates are compared by their\n        // millisecond representations. Note that invalid dates with millisecond representations\n        // of `NaN` are not equivalent.\n        result = +a == +b;\n        if (!result) {\n          diffBuilder.recordMismatch();\n        }\n        return result;\n      case '[object ArrayBuffer]':\n        // If we have an instance of ArrayBuffer the Uint8Array ctor\n        // will be defined as well\n        return self.eq_(\n          new Uint8Array(a),\n          new Uint8Array(b),\n          aStack,\n          bStack,\n          diffBuilder\n        );\n      // RegExps are compared by their source patterns and flags.\n      case '[object RegExp]':\n        return (\n          a.source == b.source &&\n          a.global == b.global &&\n          a.multiline == b.multiline &&\n          a.ignoreCase == b.ignoreCase\n        );\n    }\n    if (typeof a != 'object' || typeof b != 'object') {\n      diffBuilder.recordMismatch();\n      return false;\n    }\n\n    var aIsDomNode = j$.isDomNode(a);\n    var bIsDomNode = j$.isDomNode(b);\n    if (aIsDomNode && bIsDomNode) {\n      // At first try to use DOM3 method isEqualNode\n      result = a.isEqualNode(b);\n      if (!result) {\n        diffBuilder.recordMismatch();\n      }\n      return result;\n    }\n    if (aIsDomNode || bIsDomNode) {\n      diffBuilder.recordMismatch();\n      return false;\n    }\n\n    var aIsPromise = j$.isPromise(a);\n    var bIsPromise = j$.isPromise(b);\n    if (aIsPromise && bIsPromise) {\n      return a === b;\n    }\n\n    // Assume equality for cyclic structures. The algorithm for detecting cyclic\n    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.\n    var length = aStack.length;\n    while (length--) {\n      // Linear search. Performance is inversely proportional to the number of\n      // unique nested structures.\n      if (aStack[length] == a) {\n        return bStack[length] == b;\n      }\n    }\n    // Add the first object to the stack of traversed objects.\n    aStack.push(a);\n    bStack.push(b);\n    var size = 0;\n    // Recursively compare objects and arrays.\n    // Compare array lengths to determine if a deep comparison is necessary.\n    if (className == '[object Array]') {\n      var aLength = a.length;\n      var bLength = b.length;\n\n      diffBuilder.withPath('length', function() {\n        if (aLength !== bLength) {\n          diffBuilder.recordMismatch();\n          result = false;\n        }\n      });\n\n      for (i = 0; i < aLength || i < bLength; i++) {\n        diffBuilder.withPath(i, function() {\n          if (i >= bLength) {\n            diffBuilder.recordMismatch(\n              actualArrayIsLongerFormatter.bind(null, self.pp)\n            );\n            result = false;\n          } else {\n            result =\n              self.eq_(\n                i < aLength ? a[i] : void 0,\n                i < bLength ? b[i] : void 0,\n                aStack,\n                bStack,\n                diffBuilder\n              ) && result;\n          }\n        });\n      }\n      if (!result) {\n        return false;\n      }\n    } else if (j$.isMap(a) && j$.isMap(b)) {\n      if (a.size != b.size) {\n        diffBuilder.recordMismatch();\n        return false;\n      }\n\n      var keysA = [];\n      var keysB = [];\n      a.forEach(function(valueA, keyA) {\n        keysA.push(keyA);\n      });\n      b.forEach(function(valueB, keyB) {\n        keysB.push(keyB);\n      });\n\n      // For both sets of keys, check they map to equal values in both maps.\n      // Keep track of corresponding keys (in insertion order) in order to handle asymmetric obj keys.\n      var mapKeys = [keysA, keysB];\n      var cmpKeys = [keysB, keysA];\n      var mapIter, mapKey, mapValueA, mapValueB;\n      var cmpIter, cmpKey;\n      for (i = 0; result && i < mapKeys.length; i++) {\n        mapIter = mapKeys[i];\n        cmpIter = cmpKeys[i];\n\n        for (var j = 0; result && j < mapIter.length; j++) {\n          mapKey = mapIter[j];\n          cmpKey = cmpIter[j];\n          mapValueA = a.get(mapKey);\n\n          // Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches,\n          // otherwise explicitly look up the mapKey in the other Map since we want keys with unique\n          // obj identity (that are otherwise equal) to not match.\n          if (\n            j$.isAsymmetricEqualityTester_(mapKey) ||\n            (j$.isAsymmetricEqualityTester_(cmpKey) &&\n              this.eq_(mapKey, cmpKey, aStack, bStack, j$.NullDiffBuilder()))\n          ) {\n            mapValueB = b.get(cmpKey);\n          } else {\n            mapValueB = b.get(mapKey);\n          }\n          result = this.eq_(\n            mapValueA,\n            mapValueB,\n            aStack,\n            bStack,\n            j$.NullDiffBuilder()\n          );\n        }\n      }\n\n      if (!result) {\n        diffBuilder.recordMismatch();\n        return false;\n      }\n    } else if (j$.isSet(a) && j$.isSet(b)) {\n      if (a.size != b.size) {\n        diffBuilder.recordMismatch();\n        return false;\n      }\n\n      var valuesA = [];\n      a.forEach(function(valueA) {\n        valuesA.push(valueA);\n      });\n      var valuesB = [];\n      b.forEach(function(valueB) {\n        valuesB.push(valueB);\n      });\n\n      // For both sets, check they are all contained in the other set\n      var setPairs = [[valuesA, valuesB], [valuesB, valuesA]];\n      var stackPairs = [[aStack, bStack], [bStack, aStack]];\n      var baseValues, baseValue, baseStack;\n      var otherValues, otherValue, otherStack;\n      var found;\n      var prevStackSize;\n      for (i = 0; result && i < setPairs.length; i++) {\n        baseValues = setPairs[i][0];\n        otherValues = setPairs[i][1];\n        baseStack = stackPairs[i][0];\n        otherStack = stackPairs[i][1];\n        // For each value in the base set...\n        for (var k = 0; result && k < baseValues.length; k++) {\n          baseValue = baseValues[k];\n          found = false;\n          // ... test that it is present in the other set\n          for (var l = 0; !found && l < otherValues.length; l++) {\n            otherValue = otherValues[l];\n            prevStackSize = baseStack.length;\n            // compare by value equality\n            found = this.eq_(\n              baseValue,\n              otherValue,\n              baseStack,\n              otherStack,\n              j$.NullDiffBuilder()\n            );\n            if (!found && prevStackSize !== baseStack.length) {\n              baseStack.splice(prevStackSize);\n              otherStack.splice(prevStackSize);\n            }\n          }\n          result = result && found;\n        }\n      }\n\n      if (!result) {\n        diffBuilder.recordMismatch();\n        return false;\n      }\n    } else if (j$.isURL(a) && j$.isURL(b)) {\n      // URLs have no enumrable properties, so the default object comparison\n      // would consider any two URLs to be equal.\n      return a.toString() === b.toString();\n    } else {\n      // Objects with different constructors are not equivalent, but `Object`s\n      // or `Array`s from different frames are.\n      var aCtor = a.constructor,\n        bCtor = b.constructor;\n      if (\n        aCtor !== bCtor &&\n        isFunction(aCtor) &&\n        isFunction(bCtor) &&\n        a instanceof aCtor &&\n        b instanceof bCtor &&\n        !(aCtor instanceof aCtor && bCtor instanceof bCtor)\n      ) {\n        diffBuilder.recordMismatch(\n          constructorsAreDifferentFormatter.bind(null, this.pp)\n        );\n        return false;\n      }\n    }\n\n    // Deep compare objects.\n    var aKeys = MatchersUtil.keys(a, className == '[object Array]'),\n      key;\n    size = aKeys.length;\n\n    // Ensure that both objects contain the same number of properties before comparing deep equality.\n    if (MatchersUtil.keys(b, className == '[object Array]').length !== size) {\n      diffBuilder.recordMismatch(\n        objectKeysAreDifferentFormatter.bind(null, this.pp)\n      );\n      return false;\n    }\n\n    for (i = 0; i < size; i++) {\n      key = aKeys[i];\n      // Deep compare each member\n      if (!j$.util.has(b, key)) {\n        diffBuilder.recordMismatch(\n          objectKeysAreDifferentFormatter.bind(null, this.pp)\n        );\n        result = false;\n        continue;\n      }\n\n      diffBuilder.withPath(key, function() {\n        if (!self.eq_(a[key], b[key], aStack, bStack, diffBuilder)) {\n          result = false;\n        }\n      });\n    }\n\n    if (!result) {\n      return false;\n    }\n\n    // Remove the first object from the stack of traversed objects.\n    aStack.pop();\n    bStack.pop();\n\n    return result;\n  };\n\n  MatchersUtil.keys = function(obj, isArray) {\n    var allKeys = (function(o) {\n      var keys = [];\n      for (var key in o) {\n        if (j$.util.has(o, key)) {\n          keys.push(key);\n        }\n      }\n\n      var symbols = Object.getOwnPropertySymbols(o);\n      for (var i = 0; i < symbols.length; i++) {\n        if (o.propertyIsEnumerable(symbols[i])) {\n          keys.push(symbols[i]);\n        }\n      }\n\n      return keys;\n    })(obj);\n\n    if (!isArray) {\n      return allKeys;\n    }\n\n    if (allKeys.length === 0) {\n      return allKeys;\n    }\n\n    var extraKeys = [];\n    for (var i = 0; i < allKeys.length; i++) {\n      if (typeof allKeys[i] === 'symbol' || !/^[0-9]+$/.test(allKeys[i])) {\n        extraKeys.push(allKeys[i]);\n      }\n    }\n\n    return extraKeys;\n  };\n\n  function isFunction(obj) {\n    return typeof obj === 'function';\n  }\n\n  // Returns an array of [k, v] pairs for eacch property that's in objA\n  // and not in objB.\n  function extraKeysAndValues(objA, objB) {\n    return MatchersUtil.keys(objA)\n      .filter(key => !j$.util.has(objB, key))\n      .map(key => [key, objA[key]]);\n  }\n\n  function objectKeysAreDifferentFormatter(pp, actual, expected, path) {\n    var missingProperties = extraKeysAndValues(expected, actual),\n      extraProperties = extraKeysAndValues(actual, expected),\n      missingPropertiesMessage = formatKeyValuePairs(pp, missingProperties),\n      extraPropertiesMessage = formatKeyValuePairs(pp, extraProperties),\n      messages = [];\n\n    if (!path.depth()) {\n      path = 'object';\n    }\n\n    if (missingPropertiesMessage.length) {\n      messages.push(\n        'Expected ' + path + ' to have properties' + missingPropertiesMessage\n      );\n    }\n\n    if (extraPropertiesMessage.length) {\n      messages.push(\n        'Expected ' + path + ' not to have properties' + extraPropertiesMessage\n      );\n    }\n\n    return messages.join('\\n');\n  }\n\n  function constructorsAreDifferentFormatter(pp, actual, expected, path) {\n    if (!path.depth()) {\n      path = 'object';\n    }\n\n    return (\n      'Expected ' +\n      path +\n      ' to be a kind of ' +\n      j$.fnNameFor(expected.constructor) +\n      ', but was ' +\n      pp(actual) +\n      '.'\n    );\n  }\n\n  function actualArrayIsLongerFormatter(pp, actual, expected, path) {\n    return (\n      'Unexpected ' +\n      path +\n      (path.depth() ? ' = ' : '') +\n      pp(actual) +\n      ' in array.'\n    );\n  }\n\n  function formatKeyValuePairs(pp, keyValuePairs) {\n    let formatted = '';\n\n    for (const [key, value] of keyValuePairs) {\n      formatted += '\\n    ' + key.toString() + ': ' + pp(value);\n    }\n\n    return formatted;\n  }\n\n  return MatchersUtil;\n};\n\n/**\n * @interface AsymmetricEqualityTester\n * @classdesc An asymmetric equality tester is an object that can match multiple\n * objects. Examples include jasmine.any() and jasmine.stringMatching(). Jasmine\n * includes a number of built-in asymmetric equality testers, such as\n * {@link jasmine.objectContaining}. User-defined asymmetric equality testers are\n * also supported.\n *\n * Asymmetric equality testers work with any matcher, including user-defined\n * custom matchers, that uses {@link MatchersUtil#equals} or\n * {@link MatchersUtil#contains}.\n *\n * @example\n * function numberDivisibleBy(divisor) {\n *   return {\n *     asymmetricMatch: function(n) {\n *       return typeof n === 'number' && n % divisor === 0;\n *     },\n *     jasmineToString: function() {\n *       return `<a number divisible by ${divisor}>`;\n *     }\n *   };\n * }\n *\n * var actual = {\n *   n: 2,\n *   otherFields: \"don't care\"\n * };\n *\n * expect(actual).toEqual(jasmine.objectContaining({n: numberDivisibleBy(2)}));\n * @see custom_asymmetric_equality_testers\n * @since 2.0.0\n */\n/**\n * Determines whether a value matches this tester\n * @function\n * @name AsymmetricEqualityTester#asymmetricMatch\n * @param value {any} The value to test\n * @param matchersUtil {MatchersUtil} utilities for testing equality, etc\n * @return {Boolean}\n */\n/**\n * Returns a string representation of this tester to use in matcher failure messages\n * @function\n * @name AsymmetricEqualityTester#jasmineToString\n * @param pp {function} Function that takes a value and returns a pretty-printed representation\n * @return {String}\n */\n\ngetJasmineRequireObj().MismatchTree = function(j$) {\n  /*\n    To be able to apply custom object formatters at all possible levels of an\n    object graph, DiffBuilder needs to be able to know not just where the\n    mismatch occurred but also all ancestors of the mismatched value in both\n    the expected and actual object graphs. MismatchTree maintains that context\n    and provides it via the traverse method.\n   */\n  function MismatchTree(path) {\n    this.path = path || new j$.ObjectPath([]);\n    this.formatter = undefined;\n    this.children = [];\n    this.isMismatch = false;\n  }\n\n  MismatchTree.prototype.add = function(path, formatter) {\n    var key, child;\n\n    if (path.depth() === 0) {\n      this.formatter = formatter;\n      this.isMismatch = true;\n    } else {\n      key = path.components[0];\n      path = path.shift();\n      child = this.child(key);\n\n      if (!child) {\n        child = new MismatchTree(this.path.add(key));\n        this.children.push(child);\n      }\n\n      child.add(path, formatter);\n    }\n  };\n\n  MismatchTree.prototype.traverse = function(visit) {\n    var i,\n      hasChildren = this.children.length > 0;\n\n    if (this.isMismatch || hasChildren) {\n      if (visit(this.path, !hasChildren, this.formatter)) {\n        for (i = 0; i < this.children.length; i++) {\n          this.children[i].traverse(visit);\n        }\n      }\n    }\n  };\n\n  MismatchTree.prototype.child = function(key) {\n    var i, pathEls;\n\n    for (i = 0; i < this.children.length; i++) {\n      pathEls = this.children[i].path.components;\n      if (pathEls[pathEls.length - 1] === key) {\n        return this.children[i];\n      }\n    }\n  };\n\n  return MismatchTree;\n};\n\ngetJasmineRequireObj().nothing = function() {\n  /**\n   * {@link expect} nothing explicitly.\n   * @function\n   * @name matchers#nothing\n   * @since 2.8.0\n   * @example\n   * expect().nothing();\n   */\n  function nothing() {\n    return {\n      compare: function() {\n        return {\n          pass: true\n        };\n      }\n    };\n  }\n\n  return nothing;\n};\n\ngetJasmineRequireObj().NullDiffBuilder = function(j$) {\n  return function() {\n    return {\n      withPath: function(_, block) {\n        block();\n      },\n      setRoots: function() {},\n      recordMismatch: function() {}\n    };\n  };\n};\n\ngetJasmineRequireObj().ObjectPath = function(j$) {\n  function ObjectPath(components) {\n    this.components = components || [];\n  }\n\n  ObjectPath.prototype.toString = function() {\n    if (this.components.length) {\n      return '$' + map(this.components, formatPropertyAccess).join('');\n    } else {\n      return '';\n    }\n  };\n\n  ObjectPath.prototype.add = function(component) {\n    return new ObjectPath(this.components.concat([component]));\n  };\n\n  ObjectPath.prototype.shift = function() {\n    return new ObjectPath(this.components.slice(1));\n  };\n\n  ObjectPath.prototype.depth = function() {\n    return this.components.length;\n  };\n\n  function formatPropertyAccess(prop) {\n    if (typeof prop === 'number' || typeof prop === 'symbol') {\n      return '[' + prop.toString() + ']';\n    }\n\n    if (isValidIdentifier(prop)) {\n      return '.' + prop;\n    }\n\n    return \"['\" + prop + \"']\";\n  }\n\n  function map(array, fn) {\n    var results = [];\n    for (var i = 0; i < array.length; i++) {\n      results.push(fn(array[i]));\n    }\n    return results;\n  }\n\n  function isValidIdentifier(string) {\n    return /^[A-Za-z\\$_][A-Za-z0-9\\$_]*$/.test(string);\n  }\n\n  return ObjectPath;\n};\n\ngetJasmineRequireObj().requireAsyncMatchers = function(jRequire, j$) {\n  var availableMatchers = [\n      'toBePending',\n      'toBeResolved',\n      'toBeRejected',\n      'toBeResolvedTo',\n      'toBeRejectedWith',\n      'toBeRejectedWithError'\n    ],\n    matchers = {};\n\n  for (var i = 0; i < availableMatchers.length; i++) {\n    var name = availableMatchers[i];\n    matchers[name] = jRequire[name](j$);\n  }\n\n  return matchers;\n};\n\ngetJasmineRequireObj().toBe = function(j$) {\n  /**\n   * {@link expect} the actual value to be `===` to the expected value.\n   * @function\n   * @name matchers#toBe\n   * @since 1.3.0\n   * @param {Object} expected - The expected value to compare against.\n   * @example\n   * expect(thing).toBe(realThing);\n   */\n  function toBe(matchersUtil) {\n    var tip =\n      ' Tip: To check for deep equality, use .toEqual() instead of .toBe().';\n\n    return {\n      compare: function(actual, expected) {\n        var result = {\n          pass: actual === expected\n        };\n\n        if (typeof expected === 'object') {\n          result.message =\n            matchersUtil.buildFailureMessage(\n              'toBe',\n              result.pass,\n              actual,\n              expected\n            ) + tip;\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toBe;\n};\n\ngetJasmineRequireObj().toBeCloseTo = function() {\n  /**\n   * {@link expect} the actual value to be within a specified precision of the expected value.\n   * @function\n   * @name matchers#toBeCloseTo\n   * @since 1.3.0\n   * @param {Object} expected - The expected value to compare against.\n   * @param {Number} [precision=2] - The number of decimal points to check.\n   * @example\n   * expect(number).toBeCloseTo(42.2, 3);\n   */\n  function toBeCloseTo() {\n    return {\n      compare: function(actual, expected, precision) {\n        if (precision !== 0) {\n          precision = precision || 2;\n        }\n\n        if (expected === null || actual === null) {\n          throw new Error(\n            'Cannot use toBeCloseTo with null. Arguments evaluated to: ' +\n              'expect(' +\n              actual +\n              ').toBeCloseTo(' +\n              expected +\n              ').'\n          );\n        }\n\n        // Infinity is close to Infinity and -Infinity is close to -Infinity,\n        // regardless of the precision.\n        if (expected === Infinity || expected === -Infinity) {\n          return {\n            pass: actual === expected\n          };\n        }\n\n        var pow = Math.pow(10, precision + 1);\n        var delta = Math.abs(expected - actual);\n        var maxDelta = Math.pow(10, -precision) / 2;\n\n        return {\n          pass: Math.round(delta * pow) <= maxDelta * pow\n        };\n      }\n    };\n  }\n\n  return toBeCloseTo;\n};\n\ngetJasmineRequireObj().toBeDefined = function() {\n  /**\n   * {@link expect} the actual value to be defined. (Not `undefined`)\n   * @function\n   * @name matchers#toBeDefined\n   * @since 1.3.0\n   * @example\n   * expect(result).toBeDefined();\n   */\n  function toBeDefined() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: void 0 !== actual\n        };\n      }\n    };\n  }\n\n  return toBeDefined;\n};\n\ngetJasmineRequireObj().toBeFalse = function() {\n  /**\n   * {@link expect} the actual value to be `false`.\n   * @function\n   * @name matchers#toBeFalse\n   * @since 3.5.0\n   * @example\n   * expect(result).toBeFalse();\n   */\n  function toBeFalse() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: actual === false\n        };\n      }\n    };\n  }\n\n  return toBeFalse;\n};\n\ngetJasmineRequireObj().toBeFalsy = function() {\n  /**\n   * {@link expect} the actual value to be falsy\n   * @function\n   * @name matchers#toBeFalsy\n   * @since 2.0.0\n   * @example\n   * expect(result).toBeFalsy();\n   */\n  function toBeFalsy() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: !actual\n        };\n      }\n    };\n  }\n\n  return toBeFalsy;\n};\n\ngetJasmineRequireObj().toBeGreaterThan = function() {\n  /**\n   * {@link expect} the actual value to be greater than the expected value.\n   * @function\n   * @name matchers#toBeGreaterThan\n   * @since 2.0.0\n   * @param {Number} expected - The value to compare against.\n   * @example\n   * expect(result).toBeGreaterThan(3);\n   */\n  function toBeGreaterThan() {\n    return {\n      compare: function(actual, expected) {\n        return {\n          pass: actual > expected\n        };\n      }\n    };\n  }\n\n  return toBeGreaterThan;\n};\n\ngetJasmineRequireObj().toBeGreaterThanOrEqual = function() {\n  /**\n   * {@link expect} the actual value to be greater than or equal to the expected value.\n   * @function\n   * @name matchers#toBeGreaterThanOrEqual\n   * @since 2.0.0\n   * @param {Number} expected - The expected value to compare against.\n   * @example\n   * expect(result).toBeGreaterThanOrEqual(25);\n   */\n  function toBeGreaterThanOrEqual() {\n    return {\n      compare: function(actual, expected) {\n        return {\n          pass: actual >= expected\n        };\n      }\n    };\n  }\n\n  return toBeGreaterThanOrEqual;\n};\n\ngetJasmineRequireObj().toBeInstanceOf = function(j$) {\n  var usageError = j$.formatErrorMsg(\n    '<toBeInstanceOf>',\n    'expect(value).toBeInstanceOf(<ConstructorFunction>)'\n  );\n\n  /**\n   * {@link expect} the actual to be an instance of the expected class\n   * @function\n   * @name matchers#toBeInstanceOf\n   * @since 3.5.0\n   * @param {Object} expected - The class or constructor function to check for\n   * @example\n   * expect('foo').toBeInstanceOf(String);\n   * expect(3).toBeInstanceOf(Number);\n   * expect(new Error()).toBeInstanceOf(Error);\n   */\n  function toBeInstanceOf(matchersUtil) {\n    return {\n      compare: function(actual, expected) {\n        var actualType =\n            actual && actual.constructor\n              ? j$.fnNameFor(actual.constructor)\n              : matchersUtil.pp(actual),\n          expectedType = expected\n            ? j$.fnNameFor(expected)\n            : matchersUtil.pp(expected),\n          expectedMatcher,\n          pass;\n\n        try {\n          expectedMatcher = new j$.Any(expected);\n          pass = expectedMatcher.asymmetricMatch(actual);\n        } catch (error) {\n          throw new Error(\n            usageError('Expected value is not a constructor function')\n          );\n        }\n\n        if (pass) {\n          return {\n            pass: true,\n            message:\n              'Expected instance of ' +\n              actualType +\n              ' not to be an instance of ' +\n              expectedType\n          };\n        } else {\n          return {\n            pass: false,\n            message:\n              'Expected instance of ' +\n              actualType +\n              ' to be an instance of ' +\n              expectedType\n          };\n        }\n      }\n    };\n  }\n\n  return toBeInstanceOf;\n};\n\ngetJasmineRequireObj().toBeLessThan = function() {\n  /**\n   * {@link expect} the actual value to be less than the expected value.\n   * @function\n   * @name matchers#toBeLessThan\n   * @since 2.0.0\n   * @param {Number} expected - The expected value to compare against.\n   * @example\n   * expect(result).toBeLessThan(0);\n   */\n  function toBeLessThan() {\n    return {\n      compare: function(actual, expected) {\n        return {\n          pass: actual < expected\n        };\n      }\n    };\n  }\n\n  return toBeLessThan;\n};\n\ngetJasmineRequireObj().toBeLessThanOrEqual = function() {\n  /**\n   * {@link expect} the actual value to be less than or equal to the expected value.\n   * @function\n   * @name matchers#toBeLessThanOrEqual\n   * @since 2.0.0\n   * @param {Number} expected - The expected value to compare against.\n   * @example\n   * expect(result).toBeLessThanOrEqual(123);\n   */\n  function toBeLessThanOrEqual() {\n    return {\n      compare: function(actual, expected) {\n        return {\n          pass: actual <= expected\n        };\n      }\n    };\n  }\n\n  return toBeLessThanOrEqual;\n};\n\ngetJasmineRequireObj().toBeNaN = function(j$) {\n  /**\n   * {@link expect} the actual value to be `NaN` (Not a Number).\n   * @function\n   * @name matchers#toBeNaN\n   * @since 1.3.0\n   * @example\n   * expect(thing).toBeNaN();\n   */\n  function toBeNaN(matchersUtil) {\n    return {\n      compare: function(actual) {\n        var result = {\n          pass: actual !== actual\n        };\n\n        if (result.pass) {\n          result.message = 'Expected actual not to be NaN.';\n        } else {\n          result.message = function() {\n            return 'Expected ' + matchersUtil.pp(actual) + ' to be NaN.';\n          };\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toBeNaN;\n};\n\ngetJasmineRequireObj().toBeNegativeInfinity = function(j$) {\n  /**\n   * {@link expect} the actual value to be `-Infinity` (-infinity).\n   * @function\n   * @name matchers#toBeNegativeInfinity\n   * @since 2.6.0\n   * @example\n   * expect(thing).toBeNegativeInfinity();\n   */\n  function toBeNegativeInfinity(matchersUtil) {\n    return {\n      compare: function(actual) {\n        var result = {\n          pass: actual === Number.NEGATIVE_INFINITY\n        };\n\n        if (result.pass) {\n          result.message = 'Expected actual not to be -Infinity.';\n        } else {\n          result.message = function() {\n            return 'Expected ' + matchersUtil.pp(actual) + ' to be -Infinity.';\n          };\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toBeNegativeInfinity;\n};\n\ngetJasmineRequireObj().toBeNull = function() {\n  /**\n   * {@link expect} the actual value to be `null`.\n   * @function\n   * @name matchers#toBeNull\n   * @since 1.3.0\n   * @example\n   * expect(result).toBeNull();\n   */\n  function toBeNull() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: actual === null\n        };\n      }\n    };\n  }\n\n  return toBeNull;\n};\n\ngetJasmineRequireObj().toBePositiveInfinity = function(j$) {\n  /**\n   * {@link expect} the actual value to be `Infinity` (infinity).\n   * @function\n   * @name matchers#toBePositiveInfinity\n   * @since 2.6.0\n   * @example\n   * expect(thing).toBePositiveInfinity();\n   */\n  function toBePositiveInfinity(matchersUtil) {\n    return {\n      compare: function(actual) {\n        var result = {\n          pass: actual === Number.POSITIVE_INFINITY\n        };\n\n        if (result.pass) {\n          result.message = 'Expected actual not to be Infinity.';\n        } else {\n          result.message = function() {\n            return 'Expected ' + matchersUtil.pp(actual) + ' to be Infinity.';\n          };\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toBePositiveInfinity;\n};\n\ngetJasmineRequireObj().toBeTrue = function() {\n  /**\n   * {@link expect} the actual value to be `true`.\n   * @function\n   * @name matchers#toBeTrue\n   * @since 3.5.0\n   * @example\n   * expect(result).toBeTrue();\n   */\n  function toBeTrue() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: actual === true\n        };\n      }\n    };\n  }\n\n  return toBeTrue;\n};\n\ngetJasmineRequireObj().toBeTruthy = function() {\n  /**\n   * {@link expect} the actual value to be truthy.\n   * @function\n   * @name matchers#toBeTruthy\n   * @since 2.0.0\n   * @example\n   * expect(thing).toBeTruthy();\n   */\n  function toBeTruthy() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: !!actual\n        };\n      }\n    };\n  }\n\n  return toBeTruthy;\n};\n\ngetJasmineRequireObj().toBeUndefined = function() {\n  /**\n   * {@link expect} the actual value to be `undefined`.\n   * @function\n   * @name matchers#toBeUndefined\n   * @since 1.3.0\n   * @example\n   * expect(result).toBeUndefined():\n   */\n  function toBeUndefined() {\n    return {\n      compare: function(actual) {\n        return {\n          pass: void 0 === actual\n        };\n      }\n    };\n  }\n\n  return toBeUndefined;\n};\n\ngetJasmineRequireObj().toContain = function() {\n  /**\n   * {@link expect} the actual value to contain a specific value.\n   * @function\n   * @name matchers#toContain\n   * @since 2.0.0\n   * @param {Object} expected - The value to look for.\n   * @example\n   * expect(array).toContain(anElement);\n   * expect(string).toContain(substring);\n   */\n  function toContain(matchersUtil) {\n    return {\n      compare: function(actual, expected) {\n        return {\n          pass: matchersUtil.contains(actual, expected)\n        };\n      }\n    };\n  }\n\n  return toContain;\n};\n\ngetJasmineRequireObj().toEqual = function(j$) {\n  /**\n   * {@link expect} the actual value to be equal to the expected, using deep equality comparison.\n   * @function\n   * @name matchers#toEqual\n   * @since 1.3.0\n   * @param {Object} expected - Expected value\n   * @example\n   * expect(bigObject).toEqual({\"foo\": ['bar', 'baz']});\n   */\n  function toEqual(matchersUtil) {\n    return {\n      compare: function(actual, expected) {\n        var result = {\n            pass: false\n          },\n          diffBuilder = j$.DiffBuilder({ prettyPrinter: matchersUtil.pp });\n\n        result.pass = matchersUtil.equals(actual, expected, diffBuilder);\n\n        // TODO: only set error message if test fails\n        result.message = diffBuilder.getMessage();\n\n        return result;\n      }\n    };\n  }\n\n  return toEqual;\n};\n\ngetJasmineRequireObj().toHaveBeenCalled = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toHaveBeenCalled>',\n    'expect(<spyObj>).toHaveBeenCalled()'\n  );\n\n  /**\n   * {@link expect} the actual (a {@link Spy}) to have been called.\n   * @function\n   * @name matchers#toHaveBeenCalled\n   * @since 1.3.0\n   * @example\n   * expect(mySpy).toHaveBeenCalled();\n   * expect(mySpy).not.toHaveBeenCalled();\n   */\n  function toHaveBeenCalled(matchersUtil) {\n    return {\n      compare: function(actual) {\n        var result = {};\n\n        if (!j$.isSpy(actual)) {\n          throw new Error(\n            getErrorMsg(\n              'Expected a spy, but got ' + matchersUtil.pp(actual) + '.'\n            )\n          );\n        }\n\n        if (arguments.length > 1) {\n          throw new Error(\n            getErrorMsg('Does not take arguments, use toHaveBeenCalledWith')\n          );\n        }\n\n        result.pass = actual.calls.any();\n\n        result.message = result.pass\n          ? 'Expected spy ' + actual.and.identity + ' not to have been called.'\n          : 'Expected spy ' + actual.and.identity + ' to have been called.';\n\n        return result;\n      }\n    };\n  }\n\n  return toHaveBeenCalled;\n};\n\ngetJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toHaveBeenCalledBefore>',\n    'expect(<spyObj>).toHaveBeenCalledBefore(<spyObj>)'\n  );\n\n  /**\n   * {@link expect} the actual value (a {@link Spy}) to have been called before another {@link Spy}.\n   * @function\n   * @name matchers#toHaveBeenCalledBefore\n   * @since 2.6.0\n   * @param {Spy} expected - {@link Spy} that should have been called after the `actual` {@link Spy}.\n   * @example\n   * expect(mySpy).toHaveBeenCalledBefore(otherSpy);\n   */\n  function toHaveBeenCalledBefore(matchersUtil) {\n    return {\n      compare: function(firstSpy, latterSpy) {\n        if (!j$.isSpy(firstSpy)) {\n          throw new Error(\n            getErrorMsg(\n              'Expected a spy, but got ' + matchersUtil.pp(firstSpy) + '.'\n            )\n          );\n        }\n        if (!j$.isSpy(latterSpy)) {\n          throw new Error(\n            getErrorMsg(\n              'Expected a spy, but got ' + matchersUtil.pp(latterSpy) + '.'\n            )\n          );\n        }\n\n        var result = { pass: false };\n\n        if (!firstSpy.calls.count()) {\n          result.message =\n            'Expected spy ' + firstSpy.and.identity + ' to have been called.';\n          return result;\n        }\n        if (!latterSpy.calls.count()) {\n          result.message =\n            'Expected spy ' + latterSpy.and.identity + ' to have been called.';\n          return result;\n        }\n\n        var latest1stSpyCall = firstSpy.calls.mostRecent().invocationOrder;\n        var first2ndSpyCall = latterSpy.calls.first().invocationOrder;\n\n        result.pass = latest1stSpyCall < first2ndSpyCall;\n\n        if (result.pass) {\n          result.message =\n            'Expected spy ' +\n            firstSpy.and.identity +\n            ' to not have been called before spy ' +\n            latterSpy.and.identity +\n            ', but it was';\n        } else {\n          var first1stSpyCall = firstSpy.calls.first().invocationOrder;\n          var latest2ndSpyCall = latterSpy.calls.mostRecent().invocationOrder;\n\n          if (first1stSpyCall < first2ndSpyCall) {\n            result.message =\n              'Expected latest call to spy ' +\n              firstSpy.and.identity +\n              ' to have been called before first call to spy ' +\n              latterSpy.and.identity +\n              ' (no interleaved calls)';\n          } else if (latest2ndSpyCall > latest1stSpyCall) {\n            result.message =\n              'Expected first call to spy ' +\n              latterSpy.and.identity +\n              ' to have been called after latest call to spy ' +\n              firstSpy.and.identity +\n              ' (no interleaved calls)';\n          } else {\n            result.message =\n              'Expected spy ' +\n              firstSpy.and.identity +\n              ' to have been called before spy ' +\n              latterSpy.and.identity;\n          }\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toHaveBeenCalledBefore;\n};\n\ngetJasmineRequireObj().toHaveBeenCalledOnceWith = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toHaveBeenCalledOnceWith>',\n    'expect(<spyObj>).toHaveBeenCalledOnceWith(...arguments)'\n  );\n\n  /**\n   * {@link expect} the actual (a {@link Spy}) to have been called exactly once, and exactly with the particular arguments.\n   * @function\n   * @name matchers#toHaveBeenCalledOnceWith\n   * @since 3.6.0\n   * @param {...Object} - The arguments to look for\n   * @example\n   * expect(mySpy).toHaveBeenCalledOnceWith('foo', 'bar', 2);\n   */\n  function toHaveBeenCalledOnceWith(util) {\n    return {\n      compare: function() {\n        var args = Array.prototype.slice.call(arguments, 0),\n          actual = args[0],\n          expectedArgs = args.slice(1);\n\n        if (!j$.isSpy(actual)) {\n          throw new Error(\n            getErrorMsg('Expected a spy, but got ' + util.pp(actual) + '.')\n          );\n        }\n\n        var prettyPrintedCalls = actual.calls\n          .allArgs()\n          .map(function(argsForCall) {\n            return '  ' + util.pp(argsForCall);\n          });\n\n        if (\n          actual.calls.count() === 1 &&\n          util.contains(actual.calls.allArgs(), expectedArgs)\n        ) {\n          return {\n            pass: true,\n            message:\n              'Expected spy ' +\n              actual.and.identity +\n              ' to have been called 0 times, multiple times, or once, but with arguments different from:\\n' +\n              '  ' +\n              util.pp(expectedArgs) +\n              '\\n' +\n              'But the actual call was:\\n' +\n              prettyPrintedCalls.join(',\\n') +\n              '.\\n\\n'\n          };\n        }\n\n        function getDiffs() {\n          return actual.calls.allArgs().map(function(argsForCall, callIx) {\n            var diffBuilder = new j$.DiffBuilder();\n            util.equals(argsForCall, expectedArgs, diffBuilder);\n            return diffBuilder.getMessage();\n          });\n        }\n\n        function butString() {\n          switch (actual.calls.count()) {\n            case 0:\n              return 'But it was never called.\\n\\n';\n            case 1:\n              return (\n                'But the actual call was:\\n' +\n                prettyPrintedCalls.join(',\\n') +\n                '.\\n' +\n                getDiffs().join('\\n') +\n                '\\n\\n'\n              );\n            default:\n              return (\n                'But the actual calls were:\\n' +\n                prettyPrintedCalls.join(',\\n') +\n                '.\\n\\n'\n              );\n          }\n        }\n\n        return {\n          pass: false,\n          message:\n            'Expected spy ' +\n            actual.and.identity +\n            ' to have been called only once, and with given args:\\n' +\n            '  ' +\n            util.pp(expectedArgs) +\n            '\\n' +\n            butString()\n        };\n      }\n    };\n  }\n\n  return toHaveBeenCalledOnceWith;\n};\n\ngetJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toHaveBeenCalledTimes>',\n    'expect(<spyObj>).toHaveBeenCalledTimes(<Number>)'\n  );\n\n  /**\n   * {@link expect} the actual (a {@link Spy}) to have been called the specified number of times.\n   * @function\n   * @name matchers#toHaveBeenCalledTimes\n   * @since 2.4.0\n   * @param {Number} expected - The number of invocations to look for.\n   * @example\n   * expect(mySpy).toHaveBeenCalledTimes(3);\n   */\n  function toHaveBeenCalledTimes(matchersUtil) {\n    return {\n      compare: function(actual, expected) {\n        if (!j$.isSpy(actual)) {\n          throw new Error(\n            getErrorMsg(\n              'Expected a spy, but got ' + matchersUtil.pp(actual) + '.'\n            )\n          );\n        }\n\n        var args = Array.prototype.slice.call(arguments, 0),\n          result = { pass: false };\n\n        if (!j$.isNumber_(expected)) {\n          throw new Error(\n            getErrorMsg(\n              'The expected times failed is a required argument and must be a number.'\n            )\n          );\n        }\n\n        actual = args[0];\n        var calls = actual.calls.count();\n        var timesMessage = expected === 1 ? 'once' : expected + ' times';\n        result.pass = calls === expected;\n        result.message = result.pass\n          ? 'Expected spy ' +\n            actual.and.identity +\n            ' not to have been called ' +\n            timesMessage +\n            '. It was called ' +\n            calls +\n            ' times.'\n          : 'Expected spy ' +\n            actual.and.identity +\n            ' to have been called ' +\n            timesMessage +\n            '. It was called ' +\n            calls +\n            ' times.';\n        return result;\n      }\n    };\n  }\n\n  return toHaveBeenCalledTimes;\n};\n\ngetJasmineRequireObj().toHaveBeenCalledWith = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toHaveBeenCalledWith>',\n    'expect(<spyObj>).toHaveBeenCalledWith(...arguments)'\n  );\n\n  /**\n   * {@link expect} the actual (a {@link Spy}) to have been called with particular arguments at least once.\n   * @function\n   * @name matchers#toHaveBeenCalledWith\n   * @since 1.3.0\n   * @param {...Object} - The arguments to look for\n   * @example\n   * expect(mySpy).toHaveBeenCalledWith('foo', 'bar', 2);\n   */\n  function toHaveBeenCalledWith(matchersUtil) {\n    return {\n      compare: function() {\n        var args = Array.prototype.slice.call(arguments, 0),\n          actual = args[0],\n          expectedArgs = args.slice(1),\n          result = { pass: false };\n\n        if (!j$.isSpy(actual)) {\n          throw new Error(\n            getErrorMsg(\n              'Expected a spy, but got ' + matchersUtil.pp(actual) + '.'\n            )\n          );\n        }\n\n        if (!actual.calls.any()) {\n          result.message = function() {\n            return (\n              'Expected spy ' +\n              actual.and.identity +\n              ' to have been called with:\\n' +\n              '  ' +\n              matchersUtil.pp(expectedArgs) +\n              '\\nbut it was never called.'\n            );\n          };\n          return result;\n        }\n\n        if (matchersUtil.contains(actual.calls.allArgs(), expectedArgs)) {\n          result.pass = true;\n          result.message = function() {\n            return (\n              'Expected spy ' +\n              actual.and.identity +\n              ' not to have been called with:\\n' +\n              '  ' +\n              matchersUtil.pp(expectedArgs) +\n              '\\nbut it was.'\n            );\n          };\n        } else {\n          result.message = function() {\n            var prettyPrintedCalls = actual.calls\n              .allArgs()\n              .map(function(argsForCall) {\n                return '  ' + matchersUtil.pp(argsForCall);\n              });\n\n            var diffs = actual.calls\n              .allArgs()\n              .map(function(argsForCall, callIx) {\n                var diffBuilder = new j$.DiffBuilder();\n                matchersUtil.equals(argsForCall, expectedArgs, diffBuilder);\n                return (\n                  'Call ' +\n                  callIx +\n                  ':\\n' +\n                  diffBuilder.getMessage().replace(/^/gm, '  ')\n                );\n              });\n\n            return (\n              'Expected spy ' +\n              actual.and.identity +\n              ' to have been called with:\\n' +\n              '  ' +\n              matchersUtil.pp(expectedArgs) +\n              '\\n' +\n              '' +\n              'but actual calls were:\\n' +\n              prettyPrintedCalls.join(',\\n') +\n              '.\\n\\n' +\n              diffs.join('\\n')\n            );\n          };\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toHaveBeenCalledWith;\n};\n\ngetJasmineRequireObj().toHaveClass = function(j$) {\n  /**\n   * {@link expect} the actual value to be a DOM element that has the expected class\n   * @function\n   * @name matchers#toHaveClass\n   * @since 3.0.0\n   * @param {Object} expected - The class name to test for\n   * @example\n   * var el = document.createElement('div');\n   * el.className = 'foo bar baz';\n   * expect(el).toHaveClass('bar');\n   */\n  function toHaveClass(matchersUtil) {\n    return {\n      compare: function(actual, expected) {\n        if (!isElement(actual)) {\n          throw new Error(matchersUtil.pp(actual) + ' is not a DOM element');\n        }\n\n        return {\n          pass: actual.classList.contains(expected)\n        };\n      }\n    };\n  }\n\n  function isElement(maybeEl) {\n    return (\n      maybeEl && maybeEl.classList && j$.isFunction_(maybeEl.classList.contains)\n    );\n  }\n\n  return toHaveClass;\n};\n\ngetJasmineRequireObj().toHaveSize = function(j$) {\n  /**\n   * {@link expect} the actual size to be equal to the expected, using array-like length or object keys size.\n   * @function\n   * @name matchers#toHaveSize\n   * @since 3.6.0\n   * @param {Object} expected - Expected size\n   * @example\n   * array = [1,2];\n   * expect(array).toHaveSize(2);\n   */\n  function toHaveSize() {\n    return {\n      compare: function(actual, expected) {\n        var result = {\n          pass: false\n        };\n\n        if (\n          j$.isA_('WeakSet', actual) ||\n          j$.isWeakMap(actual) ||\n          j$.isDataView(actual)\n        ) {\n          throw new Error('Cannot get size of ' + actual + '.');\n        }\n\n        if (j$.isSet(actual) || j$.isMap(actual)) {\n          result.pass = actual.size === expected;\n        } else if (isLength(actual.length)) {\n          result.pass = actual.length === expected;\n        } else {\n          result.pass = Object.keys(actual).length === expected;\n        }\n\n        return result;\n      }\n    };\n  }\n\n  var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;\n  function isLength(value) {\n    return (\n      typeof value == 'number' &&\n      value > -1 &&\n      value % 1 === 0 &&\n      value <= MAX_SAFE_INTEGER\n    );\n  }\n\n  return toHaveSize;\n};\n\ngetJasmineRequireObj().toHaveSpyInteractions = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toHaveSpyInteractions>',\n    'expect(<spyObj>).toHaveSpyInteractions()'\n  );\n\n  /**\n   * {@link expect} the actual (a {@link SpyObj}) spies to have been called.\n   * @function\n   * @name matchers#toHaveSpyInteractions\n   * @since 4.1.0\n   * @example\n   * expect(mySpyObj).toHaveSpyInteractions();\n   * expect(mySpyObj).not.toHaveSpyInteractions();\n   */\n  function toHaveSpyInteractions(matchersUtil) {\n    return {\n      compare: function(actual) {\n        var result = {};\n\n        if (!j$.isObject_(actual)) {\n          throw new Error(\n            getErrorMsg('Expected a spy object, but got ' + typeof actual + '.')\n          );\n        }\n\n        if (arguments.length > 1) {\n          throw new Error(getErrorMsg('Does not take arguments'));\n        }\n\n        result.pass = false;\n        let hasSpy = false;\n        const calledSpies = [];\n        for (const spy of Object.values(actual)) {\n          if (!j$.isSpy(spy)) continue;\n          hasSpy = true;\n\n          if (spy.calls.any()) {\n            result.pass = true;\n            calledSpies.push([spy.and.identity, spy.calls.count()]);\n          }\n        }\n\n        if (!hasSpy) {\n          throw new Error(\n            getErrorMsg(\n              'Expected a spy object with spies, but object has no spies.'\n            )\n          );\n        }\n\n        let resultMessage;\n        if (result.pass) {\n          resultMessage =\n            'Expected spy object spies not to have been called, ' +\n            'but the following spies were called: ';\n          resultMessage += calledSpies\n            .map(([spyName, spyCount]) => {\n              return `${spyName} called ${spyCount} time(s)`;\n            })\n            .join(', ');\n        } else {\n          resultMessage =\n            'Expected spy object spies to have been called, ' +\n            'but no spies were called.';\n        }\n        result.message = resultMessage;\n\n        return result;\n      }\n    };\n  }\n\n  return toHaveSpyInteractions;\n};\n\ngetJasmineRequireObj().toMatch = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toMatch>',\n    'expect(<expectation>).toMatch(<string> || <regexp>)'\n  );\n\n  /**\n   * {@link expect} the actual value to match a regular expression\n   * @function\n   * @name matchers#toMatch\n   * @since 1.3.0\n   * @param {RegExp|String} expected - Value to look for in the string.\n   * @example\n   * expect(\"my string\").toMatch(/string$/);\n   * expect(\"other string\").toMatch(\"her\");\n   */\n  function toMatch() {\n    return {\n      compare: function(actual, expected) {\n        if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {\n          throw new Error(getErrorMsg('Expected is not a String or a RegExp'));\n        }\n\n        var regexp = new RegExp(expected);\n\n        return {\n          pass: regexp.test(actual)\n        };\n      }\n    };\n  }\n\n  return toMatch;\n};\n\ngetJasmineRequireObj().toThrow = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toThrow>',\n    'expect(function() {<expectation>}).toThrow()'\n  );\n\n  /**\n   * {@link expect} a function to `throw` something.\n   * @function\n   * @name matchers#toThrow\n   * @since 2.0.0\n   * @param {Object} [expected] - Value that should be thrown. If not provided, simply the fact that something was thrown will be checked.\n   * @example\n   * expect(function() { return 'things'; }).toThrow('foo');\n   * expect(function() { return 'stuff'; }).toThrow();\n   */\n  function toThrow(matchersUtil) {\n    return {\n      compare: function(actual, expected) {\n        var result = { pass: false },\n          threw = false,\n          thrown;\n\n        if (typeof actual != 'function') {\n          throw new Error(getErrorMsg('Actual is not a Function'));\n        }\n\n        try {\n          actual();\n        } catch (e) {\n          threw = true;\n          thrown = e;\n        }\n\n        if (!threw) {\n          result.message = 'Expected function to throw an exception.';\n          return result;\n        }\n\n        if (arguments.length == 1) {\n          result.pass = true;\n          result.message = function() {\n            return (\n              'Expected function not to throw, but it threw ' +\n              matchersUtil.pp(thrown) +\n              '.'\n            );\n          };\n\n          return result;\n        }\n\n        if (matchersUtil.equals(thrown, expected)) {\n          result.pass = true;\n          result.message = function() {\n            return (\n              'Expected function not to throw ' +\n              matchersUtil.pp(expected) +\n              '.'\n            );\n          };\n        } else {\n          result.message = function() {\n            return (\n              'Expected function to throw ' +\n              matchersUtil.pp(expected) +\n              ', but it threw ' +\n              matchersUtil.pp(thrown) +\n              '.'\n            );\n          };\n        }\n\n        return result;\n      }\n    };\n  }\n\n  return toThrow;\n};\n\ngetJasmineRequireObj().toThrowError = function(j$) {\n  var getErrorMsg = j$.formatErrorMsg(\n    '<toThrowError>',\n    'expect(function() {<expectation>}).toThrowError(<ErrorConstructor>, <message>)'\n  );\n\n  /**\n   * {@link expect} a function to `throw` an `Error`.\n   * @function\n   * @name matchers#toThrowError\n   * @since 2.0.0\n   * @param {Error} [expected] - `Error` constructor the object that was thrown needs to be an instance of. If not provided, `Error` will be used.\n   * @param {RegExp|String} [message] - The message that should be set on the thrown `Error`\n   * @example\n   * expect(function() { return 'things'; }).toThrowError(MyCustomError, 'message');\n   * expect(function() { return 'things'; }).toThrowError(MyCustomError, /bar/);\n   * expect(function() { return 'stuff'; }).toThrowError(MyCustomError);\n   * expect(function() { return 'other'; }).toThrowError(/foo/);\n   * expect(function() { return 'other'; }).toThrowError();\n   */\n  function toThrowError(matchersUtil) {\n    return {\n      compare: function(actual) {\n        var errorMatcher = getMatcher.apply(null, arguments),\n          thrown;\n\n        if (typeof actual != 'function') {\n          throw new Error(getErrorMsg('Actual is not a Function'));\n        }\n\n        try {\n          actual();\n          return fail('Expected function to throw an Error.');\n        } catch (e) {\n          thrown = e;\n        }\n\n        if (!j$.isError_(thrown)) {\n          return fail(function() {\n            return (\n              'Expected function to throw an Error, but it threw ' +\n              matchersUtil.pp(thrown) +\n              '.'\n            );\n          });\n        }\n\n        return errorMatcher.match(thrown);\n      }\n    };\n\n    function getMatcher() {\n      var expected, errorType;\n\n      if (arguments[2]) {\n        errorType = arguments[1];\n        expected = arguments[2];\n        if (!isAnErrorType(errorType)) {\n          throw new Error(getErrorMsg('Expected error type is not an Error.'));\n        }\n\n        return exactMatcher(expected, errorType);\n      } else if (arguments[1]) {\n        expected = arguments[1];\n\n        if (isAnErrorType(arguments[1])) {\n          return exactMatcher(null, arguments[1]);\n        } else {\n          return exactMatcher(arguments[1], null);\n        }\n      } else {\n        return anyMatcher();\n      }\n    }\n\n    function anyMatcher() {\n      return {\n        match: function(error) {\n          return pass(\n            'Expected function not to throw an Error, but it threw ' +\n              j$.fnNameFor(error) +\n              '.'\n          );\n        }\n      };\n    }\n\n    function exactMatcher(expected, errorType) {\n      if (expected && !isStringOrRegExp(expected)) {\n        if (errorType) {\n          throw new Error(\n            getErrorMsg('Expected error message is not a string or RegExp.')\n          );\n        } else {\n          throw new Error(\n            getErrorMsg('Expected is not an Error, string, or RegExp.')\n          );\n        }\n      }\n\n      function messageMatch(message) {\n        if (typeof expected == 'string') {\n          return expected == message;\n        } else {\n          return expected.test(message);\n        }\n      }\n\n      var errorTypeDescription = errorType\n        ? j$.fnNameFor(errorType)\n        : 'an exception';\n\n      function thrownDescription(thrown) {\n        var thrownName = errorType\n            ? j$.fnNameFor(thrown.constructor)\n            : 'an exception',\n          thrownMessage = '';\n\n        if (expected) {\n          thrownMessage = ' with message ' + matchersUtil.pp(thrown.message);\n        }\n\n        return thrownName + thrownMessage;\n      }\n\n      function messageDescription() {\n        if (expected === null) {\n          return '';\n        } else if (expected instanceof RegExp) {\n          return ' with a message matching ' + matchersUtil.pp(expected);\n        } else {\n          return ' with message ' + matchersUtil.pp(expected);\n        }\n      }\n\n      function matches(error) {\n        return (\n          (errorType === null || error instanceof errorType) &&\n          (expected === null || messageMatch(error.message))\n        );\n      }\n\n      return {\n        match: function(thrown) {\n          if (matches(thrown)) {\n            return pass(function() {\n              return (\n                'Expected function not to throw ' +\n                errorTypeDescription +\n                messageDescription() +\n                '.'\n              );\n            });\n          } else {\n            return fail(function() {\n              return (\n                'Expected function to throw ' +\n                errorTypeDescription +\n                messageDescription() +\n                ', but it threw ' +\n                thrownDescription(thrown) +\n                '.'\n              );\n            });\n          }\n        }\n      };\n    }\n\n    function isStringOrRegExp(potential) {\n      return potential instanceof RegExp || typeof potential == 'string';\n    }\n\n    function isAnErrorType(type) {\n      if (typeof type !== 'function') {\n        return false;\n      }\n\n      var Surrogate = function() {};\n      Surrogate.prototype = type.prototype;\n      return j$.isError_(new Surrogate());\n    }\n  }\n\n  function pass(message) {\n    return {\n      pass: true,\n      message: message\n    };\n  }\n\n  function fail(message) {\n    return {\n      pass: false,\n      message: message\n    };\n  }\n\n  return toThrowError;\n};\n\ngetJasmineRequireObj().toThrowMatching = function(j$) {\n  var usageError = j$.formatErrorMsg(\n    '<toThrowMatching>',\n    'expect(function() {<expectation>}).toThrowMatching(<Predicate>)'\n  );\n\n  /**\n   * {@link expect} a function to `throw` something matching a predicate.\n   * @function\n   * @name matchers#toThrowMatching\n   * @since 3.0.0\n   * @param {Function} predicate - A function that takes the thrown exception as its parameter and returns true if it matches.\n   * @example\n   * expect(function() { throw new Error('nope'); }).toThrowMatching(function(thrown) { return thrown.message === 'nope'; });\n   */\n  function toThrowMatching(matchersUtil) {\n    return {\n      compare: function(actual, predicate) {\n        var thrown;\n\n        if (typeof actual !== 'function') {\n          throw new Error(usageError('Actual is not a Function'));\n        }\n\n        if (typeof predicate !== 'function') {\n          throw new Error(usageError('Predicate is not a Function'));\n        }\n\n        try {\n          actual();\n          return fail('Expected function to throw an exception.');\n        } catch (e) {\n          thrown = e;\n        }\n\n        if (predicate(thrown)) {\n          return pass(\n            'Expected function not to throw an exception matching a predicate.'\n          );\n        } else {\n          return fail(function() {\n            return (\n              'Expected function to throw an exception matching a predicate, ' +\n              'but it threw ' +\n              thrownDescription(thrown) +\n              '.'\n            );\n          });\n        }\n      }\n    };\n\n    function thrownDescription(thrown) {\n      if (thrown && thrown.constructor) {\n        return (\n          j$.fnNameFor(thrown.constructor) +\n          ' with message ' +\n          matchersUtil.pp(thrown.message)\n        );\n      } else {\n        return matchersUtil.pp(thrown);\n      }\n    }\n  }\n\n  function pass(message) {\n    return {\n      pass: true,\n      message: message\n    };\n  }\n\n  function fail(message) {\n    return {\n      pass: false,\n      message: message\n    };\n  }\n\n  return toThrowMatching;\n};\n\ngetJasmineRequireObj().MockDate = function(j$) {\n  function MockDate(global) {\n    var self = this;\n    var currentTime = 0;\n\n    if (!global || !global.Date) {\n      self.install = function() {};\n      self.tick = function() {};\n      self.uninstall = function() {};\n      return self;\n    }\n\n    var GlobalDate = global.Date;\n\n    self.install = function(mockDate) {\n      if (mockDate instanceof GlobalDate) {\n        currentTime = mockDate.getTime();\n      } else {\n        if (!j$.util.isUndefined(mockDate)) {\n          throw new Error(\n            'The argument to jasmine.clock().mockDate(), if specified, ' +\n              'should be a Date instance.'\n          );\n        }\n\n        currentTime = new GlobalDate().getTime();\n      }\n\n      global.Date = FakeDate;\n    };\n\n    self.tick = function(millis) {\n      millis = millis || 0;\n      currentTime = currentTime + millis;\n    };\n\n    self.uninstall = function() {\n      currentTime = 0;\n      global.Date = GlobalDate;\n    };\n\n    createDateProperties();\n\n    return self;\n\n    function FakeDate() {\n      switch (arguments.length) {\n        case 0:\n          return new GlobalDate(currentTime);\n        case 1:\n          return new GlobalDate(arguments[0]);\n        case 2:\n          return new GlobalDate(arguments[0], arguments[1]);\n        case 3:\n          return new GlobalDate(arguments[0], arguments[1], arguments[2]);\n        case 4:\n          return new GlobalDate(\n            arguments[0],\n            arguments[1],\n            arguments[2],\n            arguments[3]\n          );\n        case 5:\n          return new GlobalDate(\n            arguments[0],\n            arguments[1],\n            arguments[2],\n            arguments[3],\n            arguments[4]\n          );\n        case 6:\n          return new GlobalDate(\n            arguments[0],\n            arguments[1],\n            arguments[2],\n            arguments[3],\n            arguments[4],\n            arguments[5]\n          );\n        default:\n          return new GlobalDate(\n            arguments[0],\n            arguments[1],\n            arguments[2],\n            arguments[3],\n            arguments[4],\n            arguments[5],\n            arguments[6]\n          );\n      }\n    }\n\n    function createDateProperties() {\n      FakeDate.prototype = GlobalDate.prototype;\n\n      FakeDate.now = function() {\n        return currentTime;\n      };\n\n      FakeDate.toSource = GlobalDate.toSource;\n      FakeDate.toString = GlobalDate.toString;\n      FakeDate.parse = GlobalDate.parse;\n      FakeDate.UTC = GlobalDate.UTC;\n    }\n  }\n\n  return MockDate;\n};\n\ngetJasmineRequireObj().NeverSkipPolicy = function(j$) {\n  function NeverSkipPolicy(queueableFns) {}\n\n  NeverSkipPolicy.prototype.skipTo = function(lastRanFnIx) {\n    return lastRanFnIx + 1;\n  };\n\n  NeverSkipPolicy.prototype.fnErrored = function(fnIx) {};\n\n  return NeverSkipPolicy;\n};\n\ngetJasmineRequireObj().makePrettyPrinter = function(j$) {\n  function SinglePrettyPrintRun(customObjectFormatters, pp) {\n    this.customObjectFormatters_ = customObjectFormatters;\n    this.ppNestLevel_ = 0;\n    this.seen = [];\n    this.length = 0;\n    this.stringParts = [];\n    this.pp_ = pp;\n  }\n\n  function hasCustomToString(value) {\n    // value.toString !== Object.prototype.toString if value has no custom toString but is from another context (e.g.\n    // iframe, web worker)\n    try {\n      return (\n        j$.isFunction_(value.toString) &&\n        value.toString !== Object.prototype.toString &&\n        value.toString() !== Object.prototype.toString.call(value)\n      );\n    } catch (e) {\n      // The custom toString() threw.\n      return true;\n    }\n  }\n\n  SinglePrettyPrintRun.prototype.format = function(value) {\n    this.ppNestLevel_++;\n    try {\n      var customFormatResult = this.applyCustomFormatters_(value);\n\n      if (customFormatResult) {\n        this.emitScalar(customFormatResult);\n      } else if (j$.util.isUndefined(value)) {\n        this.emitScalar('undefined');\n      } else if (value === null) {\n        this.emitScalar('null');\n      } else if (value === 0 && 1 / value === -Infinity) {\n        this.emitScalar('-0');\n      } else if (value === j$.getGlobal()) {\n        this.emitScalar('<global>');\n      } else if (value.jasmineToString) {\n        this.emitScalar(value.jasmineToString(this.pp_));\n      } else if (j$.isString_(value)) {\n        this.emitString(value);\n      } else if (j$.isSpy(value)) {\n        this.emitScalar('spy on ' + value.and.identity);\n      } else if (j$.isSpy(value.toString)) {\n        this.emitScalar('spy on ' + value.toString.and.identity);\n      } else if (value instanceof RegExp) {\n        this.emitScalar(value.toString());\n      } else if (typeof value === 'function') {\n        this.emitScalar('Function');\n      } else if (j$.isDomNode(value)) {\n        if (value.tagName) {\n          this.emitDomElement(value);\n        } else {\n          this.emitScalar('HTMLNode');\n        }\n      } else if (value instanceof Date) {\n        this.emitScalar('Date(' + value + ')');\n      } else if (j$.isSet(value)) {\n        this.emitSet(value);\n      } else if (j$.isMap(value)) {\n        this.emitMap(value);\n      } else if (j$.isTypedArray_(value)) {\n        this.emitTypedArray(value);\n      } else if (\n        value.toString &&\n        typeof value === 'object' &&\n        !j$.isArray_(value) &&\n        hasCustomToString(value)\n      ) {\n        try {\n          this.emitScalar(value.toString());\n        } catch (e) {\n          this.emitScalar('has-invalid-toString-method');\n        }\n      } else if (j$.util.arrayContains(this.seen, value)) {\n        this.emitScalar(\n          '<circular reference: ' +\n            (j$.isArray_(value) ? 'Array' : 'Object') +\n            '>'\n        );\n      } else if (j$.isArray_(value) || j$.isA_('Object', value)) {\n        this.seen.push(value);\n        if (j$.isArray_(value)) {\n          this.emitArray(value);\n        } else {\n          this.emitObject(value);\n        }\n        this.seen.pop();\n      } else {\n        this.emitScalar(value.toString());\n      }\n    } catch (e) {\n      if (this.ppNestLevel_ > 1 || !(e instanceof MaxCharsReachedError)) {\n        throw e;\n      }\n    } finally {\n      this.ppNestLevel_--;\n    }\n  };\n\n  SinglePrettyPrintRun.prototype.applyCustomFormatters_ = function(value) {\n    return customFormat(value, this.customObjectFormatters_);\n  };\n\n  SinglePrettyPrintRun.prototype.iterateObject = function(obj, fn) {\n    var objKeys = j$.MatchersUtil.keys(obj, j$.isArray_(obj));\n    var isGetter = function isGetter(prop) {};\n\n    if (obj.__lookupGetter__) {\n      isGetter = function isGetter(prop) {\n        var getter = obj.__lookupGetter__(prop);\n        return !j$.util.isUndefined(getter) && getter !== null;\n      };\n    }\n    var length = Math.min(objKeys.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);\n    for (var i = 0; i < length; i++) {\n      var property = objKeys[i];\n      fn(property, isGetter(property));\n    }\n\n    return objKeys.length > length;\n  };\n\n  SinglePrettyPrintRun.prototype.emitScalar = function(value) {\n    this.append(value);\n  };\n\n  SinglePrettyPrintRun.prototype.emitString = function(value) {\n    this.append(\"'\" + value + \"'\");\n  };\n\n  SinglePrettyPrintRun.prototype.emitArray = function(array) {\n    if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {\n      this.append('Array');\n      return;\n    }\n    var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);\n    this.append('[ ');\n    for (var i = 0; i < length; i++) {\n      if (i > 0) {\n        this.append(', ');\n      }\n      this.format(array[i]);\n    }\n    if (array.length > length) {\n      this.append(', ...');\n    }\n\n    var self = this;\n    var first = array.length === 0;\n    var truncated = this.iterateObject(array, function(property, isGetter) {\n      if (first) {\n        first = false;\n      } else {\n        self.append(', ');\n      }\n\n      self.formatProperty(array, property, isGetter);\n    });\n\n    if (truncated) {\n      this.append(', ...');\n    }\n\n    this.append(' ]');\n  };\n\n  SinglePrettyPrintRun.prototype.emitSet = function(set) {\n    if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {\n      this.append('Set');\n      return;\n    }\n    this.append('Set( ');\n    var size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);\n    var i = 0;\n    set.forEach(function(value, key) {\n      if (i >= size) {\n        return;\n      }\n      if (i > 0) {\n        this.append(', ');\n      }\n      this.format(value);\n\n      i++;\n    }, this);\n    if (set.size > size) {\n      this.append(', ...');\n    }\n    this.append(' )');\n  };\n\n  SinglePrettyPrintRun.prototype.emitMap = function(map) {\n    if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {\n      this.append('Map');\n      return;\n    }\n    this.append('Map( ');\n    var size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);\n    var i = 0;\n    map.forEach(function(value, key) {\n      if (i >= size) {\n        return;\n      }\n      if (i > 0) {\n        this.append(', ');\n      }\n      this.format([key, value]);\n\n      i++;\n    }, this);\n    if (map.size > size) {\n      this.append(', ...');\n    }\n    this.append(' )');\n  };\n\n  SinglePrettyPrintRun.prototype.emitObject = function(obj) {\n    var ctor = obj.constructor,\n      constructorName;\n\n    constructorName =\n      typeof ctor === 'function' && obj instanceof ctor\n        ? j$.fnNameFor(obj.constructor)\n        : 'null';\n\n    this.append(constructorName);\n\n    if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {\n      return;\n    }\n\n    var self = this;\n    this.append('({ ');\n    var first = true;\n\n    var truncated = this.iterateObject(obj, function(property, isGetter) {\n      if (first) {\n        first = false;\n      } else {\n        self.append(', ');\n      }\n\n      self.formatProperty(obj, property, isGetter);\n    });\n\n    if (truncated) {\n      this.append(', ...');\n    }\n\n    this.append(' })');\n  };\n\n  SinglePrettyPrintRun.prototype.emitTypedArray = function(arr) {\n    var constructorName = j$.fnNameFor(arr.constructor),\n      limitedArray = Array.prototype.slice.call(\n        arr,\n        0,\n        j$.MAX_PRETTY_PRINT_ARRAY_LENGTH\n      ),\n      itemsString = Array.prototype.join.call(limitedArray, ', ');\n\n    if (limitedArray.length !== arr.length) {\n      itemsString += ', ...';\n    }\n\n    this.append(constructorName + ' [ ' + itemsString + ' ]');\n  };\n\n  SinglePrettyPrintRun.prototype.emitDomElement = function(el) {\n    var tagName = el.tagName.toLowerCase(),\n      attrs = el.attributes,\n      i,\n      len = attrs.length,\n      out = '<' + tagName,\n      attr;\n\n    for (i = 0; i < len; i++) {\n      attr = attrs[i];\n      out += ' ' + attr.name;\n\n      if (attr.value !== '') {\n        out += '=\"' + attr.value + '\"';\n      }\n    }\n\n    out += '>';\n\n    if (el.childElementCount !== 0 || el.textContent !== '') {\n      out += '...</' + tagName + '>';\n    }\n\n    this.append(out);\n  };\n\n  SinglePrettyPrintRun.prototype.formatProperty = function(\n    obj,\n    property,\n    isGetter\n  ) {\n    if (typeof property === 'symbol') {\n      this.append(property.toString());\n    } else {\n      this.append(property);\n    }\n\n    this.append(': ');\n\n    if (isGetter) {\n      this.append('<getter>');\n    } else {\n      this.format(obj[property]);\n    }\n  };\n\n  SinglePrettyPrintRun.prototype.append = function(value) {\n    // This check protects us from the rare case where an object has overriden\n    // `toString()` with an invalid implementation (returning a non-string).\n    if (typeof value !== 'string') {\n      value = Object.prototype.toString.call(value);\n    }\n\n    var result = truncate(value, j$.MAX_PRETTY_PRINT_CHARS - this.length);\n    this.length += result.value.length;\n    this.stringParts.push(result.value);\n\n    if (result.truncated) {\n      throw new MaxCharsReachedError();\n    }\n  };\n\n  function truncate(s, maxlen) {\n    if (s.length <= maxlen) {\n      return { value: s, truncated: false };\n    }\n\n    s = s.substring(0, maxlen - 4) + ' ...';\n    return { value: s, truncated: true };\n  }\n\n  function MaxCharsReachedError() {\n    this.message =\n      'Exceeded ' +\n      j$.MAX_PRETTY_PRINT_CHARS +\n      ' characters while pretty-printing a value';\n  }\n\n  MaxCharsReachedError.prototype = new Error();\n\n  function customFormat(value, customObjectFormatters) {\n    var i, result;\n\n    for (i = 0; i < customObjectFormatters.length; i++) {\n      result = customObjectFormatters[i](value);\n\n      if (result !== undefined) {\n        return result;\n      }\n    }\n  }\n\n  return function(customObjectFormatters) {\n    customObjectFormatters = customObjectFormatters || [];\n\n    var pp = function(value) {\n      var prettyPrinter = new SinglePrettyPrintRun(customObjectFormatters, pp);\n      prettyPrinter.format(value);\n      return prettyPrinter.stringParts.join('');\n    };\n\n    pp.customFormat_ = function(value) {\n      return customFormat(value, customObjectFormatters);\n    };\n\n    return pp;\n  };\n};\n\ngetJasmineRequireObj().QueueRunner = function(j$) {\n  var nextid = 1;\n\n  function StopExecutionError() {}\n  StopExecutionError.prototype = new Error();\n  j$.StopExecutionError = StopExecutionError;\n\n  function once(fn, onTwice) {\n    var called = false;\n    return function(arg) {\n      if (called) {\n        if (onTwice) {\n          onTwice();\n        }\n      } else {\n        called = true;\n        // Direct call using single parameter, because cleanup/next does not need more\n        fn(arg);\n      }\n      return null;\n    };\n  }\n\n  function fallbackOnMultipleDone() {\n    console.error(\n      new Error(\n        \"An asynchronous function called its 'done' \" +\n          'callback more than once, in a QueueRunner without a onMultipleDone ' +\n          'handler.'\n      )\n    );\n  }\n\n  function emptyFn() {}\n\n  function QueueRunner(attrs) {\n    this.id_ = nextid++;\n    this.queueableFns = attrs.queueableFns || [];\n    this.onComplete = attrs.onComplete || emptyFn;\n    this.clearStack =\n      attrs.clearStack ||\n      function(fn) {\n        fn();\n      };\n    this.onException = attrs.onException || emptyFn;\n    this.onMultipleDone = attrs.onMultipleDone || fallbackOnMultipleDone;\n    this.userContext = attrs.userContext || new j$.UserContext();\n    this.timeout = attrs.timeout || {\n      setTimeout: setTimeout,\n      clearTimeout: clearTimeout\n    };\n    this.fail = attrs.fail || emptyFn;\n    this.globalErrors = attrs.globalErrors || {\n      pushListener: emptyFn,\n      popListener: emptyFn\n    };\n\n    const SkipPolicy = attrs.SkipPolicy || j$.NeverSkipPolicy;\n    this.skipPolicy_ = new SkipPolicy(this.queueableFns);\n    this.errored_ = false;\n\n    if (typeof this.onComplete !== 'function') {\n      throw new Error('invalid onComplete ' + JSON.stringify(this.onComplete));\n    }\n    this.deprecated = attrs.deprecated;\n  }\n\n  QueueRunner.prototype.execute = function() {\n    var self = this;\n    this.handleFinalError = function(message, source, lineno, colno, error) {\n      // Older browsers would send the error as the first parameter. HTML5\n      // specifies the the five parameters above. The error instance should\n      // be preffered, otherwise the call stack would get lost.\n      self.onException(error || message);\n    };\n    this.globalErrors.pushListener(this.handleFinalError);\n    this.run(0);\n  };\n\n  QueueRunner.prototype.clearTimeout = function(timeoutId) {\n    Function.prototype.apply.apply(this.timeout.clearTimeout, [\n      j$.getGlobal(),\n      [timeoutId]\n    ]);\n  };\n\n  QueueRunner.prototype.setTimeout = function(fn, timeout) {\n    return Function.prototype.apply.apply(this.timeout.setTimeout, [\n      j$.getGlobal(),\n      [fn, timeout]\n    ]);\n  };\n\n  QueueRunner.prototype.attempt = function attempt(iterativeIndex) {\n    var self = this,\n      completedSynchronously = true,\n      handleError = function handleError(error) {\n        // TODO probably shouldn't next() right away here.\n        // That makes debugging async failures much more confusing.\n        onException(error);\n      },\n      cleanup = once(function cleanup() {\n        if (timeoutId !== void 0) {\n          self.clearTimeout(timeoutId);\n        }\n        self.globalErrors.popListener(handleError);\n      }),\n      next = once(\n        function next(err) {\n          cleanup();\n\n          if (typeof err !== 'undefined') {\n            if (!(err instanceof StopExecutionError) && !err.jasmineMessage) {\n              self.fail(err);\n            }\n            self.recordError_(iterativeIndex);\n          }\n\n          function runNext() {\n            self.run(self.nextFnIx_(iterativeIndex));\n          }\n\n          if (completedSynchronously) {\n            self.setTimeout(runNext);\n          } else {\n            runNext();\n          }\n        },\n        function() {\n          try {\n            if (!timedOut) {\n              self.onMultipleDone();\n            }\n          } catch (error) {\n            // Any error we catch here is probably due to a bug in Jasmine,\n            // and it's not likely to end up anywhere useful if we let it\n            // propagate. Log it so it can at least show up when debugging.\n            console.error(error);\n          }\n        }\n      ),\n      timedOut = false,\n      queueableFn = self.queueableFns[iterativeIndex],\n      timeoutId,\n      maybeThenable;\n\n    next.fail = function nextFail() {\n      self.fail.apply(null, arguments);\n      self.recordError_(iterativeIndex);\n      next();\n    };\n\n    self.globalErrors.pushListener(handleError);\n\n    if (queueableFn.timeout !== undefined) {\n      var timeoutInterval = queueableFn.timeout || j$.DEFAULT_TIMEOUT_INTERVAL;\n      timeoutId = self.setTimeout(function() {\n        timedOut = true;\n        var error = new Error(\n          'Timeout - Async function did not complete within ' +\n            timeoutInterval +\n            'ms ' +\n            (queueableFn.timeout\n              ? '(custom timeout)'\n              : '(set by jasmine.DEFAULT_TIMEOUT_INTERVAL)')\n        );\n        // TODO Need to decide what to do about a successful completion after a\n        //   timeout. That should probably not be a deprecation, and maybe not\n        //   an error in 4.0. (But a diagnostic of some sort might be helpful.)\n        onException(error);\n        next();\n      }, timeoutInterval);\n    }\n\n    try {\n      if (queueableFn.fn.length === 0) {\n        maybeThenable = queueableFn.fn.call(self.userContext);\n\n        if (maybeThenable && j$.isFunction_(maybeThenable.then)) {\n          maybeThenable.then(\n            wrapInPromiseResolutionHandler(next),\n            onPromiseRejection\n          );\n          completedSynchronously = false;\n          return { completedSynchronously: false };\n        }\n      } else {\n        maybeThenable = queueableFn.fn.call(self.userContext, next);\n        this.diagnoseConflictingAsync_(queueableFn.fn, maybeThenable);\n        completedSynchronously = false;\n        return { completedSynchronously: false };\n      }\n    } catch (e) {\n      onException(e);\n      self.recordError_(iterativeIndex);\n    }\n\n    cleanup();\n    return { completedSynchronously: true };\n\n    function onException(e) {\n      self.onException(e);\n      self.recordError_(iterativeIndex);\n    }\n\n    function onPromiseRejection(e) {\n      onException(e);\n      next();\n    }\n  };\n\n  QueueRunner.prototype.run = function(recursiveIndex) {\n    var length = this.queueableFns.length,\n      self = this,\n      iterativeIndex;\n\n    for (\n      iterativeIndex = recursiveIndex;\n      iterativeIndex < length;\n      iterativeIndex = this.nextFnIx_(iterativeIndex)\n    ) {\n      var result = this.attempt(iterativeIndex);\n\n      if (!result.completedSynchronously) {\n        return;\n      }\n    }\n\n    this.clearStack(function() {\n      self.globalErrors.popListener(self.handleFinalError);\n\n      if (self.errored_) {\n        self.onComplete(new StopExecutionError());\n      } else {\n        self.onComplete();\n      }\n    });\n  };\n\n  QueueRunner.prototype.nextFnIx_ = function(currentFnIx) {\n    const result = this.skipPolicy_.skipTo(currentFnIx);\n\n    if (result === currentFnIx) {\n      throw new Error(\"Can't skip to the same queueable fn that just finished\");\n    }\n\n    return result;\n  };\n\n  QueueRunner.prototype.recordError_ = function(currentFnIx) {\n    this.errored_ = true;\n    this.skipPolicy_.fnErrored(currentFnIx);\n  };\n\n  QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {\n    var msg;\n\n    if (retval && j$.isFunction_(retval.then)) {\n      // Issue a warning that matches the user's code.\n      // Omit the stack trace because there's almost certainly no user code\n      // on the stack at this point.\n      if (j$.isAsyncFunction_(fn)) {\n        this.onException(\n          'An asynchronous before/it/after ' +\n            'function was defined with the async keyword but also took a ' +\n            'done callback. Either remove the done callback (recommended) or ' +\n            'remove the async keyword.'\n        );\n      } else {\n        this.onException(\n          'An asynchronous before/it/after ' +\n            'function took a done callback but also returned a promise. ' +\n            'Either remove the done callback (recommended) or change the ' +\n            'function to not return a promise.'\n        );\n      }\n\n      this.deprecated(msg, { omitStackTrace: true });\n    }\n  };\n\n  function wrapInPromiseResolutionHandler(fn) {\n    return function(maybeArg) {\n      if (j$.isError_(maybeArg)) {\n        fn(maybeArg);\n      } else {\n        fn();\n      }\n    };\n  }\n\n  return QueueRunner;\n};\n\ngetJasmineRequireObj().ReportDispatcher = function(j$) {\n  function ReportDispatcher(methods, queueRunnerFactory, onLateError) {\n    var dispatchedMethods = methods || [];\n\n    for (var i = 0; i < dispatchedMethods.length; i++) {\n      var method = dispatchedMethods[i];\n      this[method] = (function(m) {\n        return function() {\n          dispatch(m, arguments);\n        };\n      })(method);\n    }\n\n    var reporters = [];\n    var fallbackReporter = null;\n\n    this.addReporter = function(reporter) {\n      reporters.push(reporter);\n    };\n\n    this.provideFallbackReporter = function(reporter) {\n      fallbackReporter = reporter;\n    };\n\n    this.clearReporters = function() {\n      reporters = [];\n    };\n\n    return this;\n\n    function dispatch(method, args) {\n      if (reporters.length === 0 && fallbackReporter !== null) {\n        reporters.push(fallbackReporter);\n      }\n      var onComplete = args[args.length - 1];\n      args = j$.util.argsToArray(args).splice(0, args.length - 1);\n      var fns = [];\n      for (var i = 0; i < reporters.length; i++) {\n        var reporter = reporters[i];\n        addFn(fns, reporter, method, args);\n      }\n\n      queueRunnerFactory({\n        queueableFns: fns,\n        onComplete: onComplete,\n        isReporter: true,\n        onMultipleDone: function() {\n          onLateError(\n            new Error(\n              \"An asynchronous reporter callback called its 'done' callback \" +\n                'more than once.'\n            )\n          );\n        }\n      });\n    }\n\n    function addFn(fns, reporter, method, args) {\n      var fn = reporter[method];\n      if (!fn) {\n        return;\n      }\n\n      var thisArgs = j$.util.cloneArgs(args);\n      if (fn.length <= 1) {\n        fns.push({\n          fn: function() {\n            return fn.apply(reporter, thisArgs);\n          }\n        });\n      } else {\n        fns.push({\n          fn: function(done) {\n            return fn.apply(reporter, thisArgs.concat([done]));\n          }\n        });\n      }\n    }\n  }\n\n  return ReportDispatcher;\n};\n\ngetJasmineRequireObj().interface = function(jasmine, env) {\n  var jasmineInterface = {\n    /**\n     * Callback passed to parts of the Jasmine base interface.\n     *\n     * By default Jasmine assumes this function completes synchronously.\n     * If you have code that you need to test asynchronously, you can declare that you receive a `done` callback, return a Promise, or use the `async` keyword if it is supported in your environment.\n     * @callback implementationCallback\n     * @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.\n     * @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.\n     */\n\n    /**\n     * Create a group of specs (often called a suite).\n     *\n     * Calls to `describe` can be nested within other calls to compose your suite as a tree.\n     * @name describe\n     * @since 1.3.0\n     * @function\n     * @global\n     * @param {String} description Textual description of the group\n     * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs\n     */\n    describe: function(description, specDefinitions) {\n      return env.describe(description, specDefinitions);\n    },\n\n    /**\n     * A temporarily disabled [`describe`]{@link describe}\n     *\n     * Specs within an `xdescribe` will be marked pending and not executed\n     * @name xdescribe\n     * @since 1.3.0\n     * @function\n     * @global\n     * @param {String} description Textual description of the group\n     * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs\n     */\n    xdescribe: function(description, specDefinitions) {\n      return env.xdescribe(description, specDefinitions);\n    },\n\n    /**\n     * A focused [`describe`]{@link describe}\n     *\n     * If suites or specs are focused, only those that are focused will be executed\n     * @see fit\n     * @name fdescribe\n     * @since 2.1.0\n     * @function\n     * @global\n     * @param {String} description Textual description of the group\n     * @param {Function} specDefinitions Function for Jasmine to invoke that will define inner suites and specs\n     */\n    fdescribe: function(description, specDefinitions) {\n      return env.fdescribe(description, specDefinitions);\n    },\n\n    /**\n     * Define a single spec. A spec should contain one or more {@link expect|expectations} that test the state of the code.\n     *\n     * A spec whose expectations all succeed will be passing and a spec with any failures will fail.\n     * The name `it` is a pronoun for the test target, not an abbreviation of anything. It makes the\n     * spec more readable by connecting the function name `it` and the argument `description` as a\n     * complete sentence.\n     * @name it\n     * @since 1.3.0\n     * @function\n     * @global\n     * @param {String} description Textual description of what this spec is checking\n     * @param {implementationCallback} [testFunction] Function that contains the code of your test. If not provided the test will be `pending`.\n     * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec.\n     * @see async\n     */\n    it: function() {\n      return env.it.apply(env, arguments);\n    },\n\n    /**\n     * A temporarily disabled [`it`]{@link it}\n     *\n     * The spec will report as `pending` and will not be executed.\n     * @name xit\n     * @since 1.3.0\n     * @function\n     * @global\n     * @param {String} description Textual description of what this spec is checking.\n     * @param {implementationCallback} [testFunction] Function that contains the code of your test. Will not be executed.\n     */\n    xit: function() {\n      return env.xit.apply(env, arguments);\n    },\n\n    /**\n     * A focused [`it`]{@link it}\n     *\n     * If suites or specs are focused, only those that are focused will be executed.\n     * @name fit\n     * @since 2.1.0\n     * @function\n     * @global\n     * @param {String} description Textual description of what this spec is checking.\n     * @param {implementationCallback} testFunction Function that contains the code of your test.\n     * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async spec.\n     * @see async\n     */\n    fit: function() {\n      return env.fit.apply(env, arguments);\n    },\n\n    /**\n     * Run some shared setup before each of the specs in the {@link describe} in which it is called.\n     * @name beforeEach\n     * @since 1.3.0\n     * @function\n     * @global\n     * @param {implementationCallback} [function] Function that contains the code to setup your specs.\n     * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeEach.\n     * @see async\n     */\n    beforeEach: function() {\n      return env.beforeEach.apply(env, arguments);\n    },\n\n    /**\n     * Run some shared teardown after each of the specs in the {@link describe} in which it is called.\n     * @name afterEach\n     * @since 1.3.0\n     * @function\n     * @global\n     * @param {implementationCallback} [function] Function that contains the code to teardown your specs.\n     * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterEach.\n     * @see async\n     */\n    afterEach: function() {\n      return env.afterEach.apply(env, arguments);\n    },\n\n    /**\n     * Run some shared setup once before all of the specs in the {@link describe} are run.\n     *\n     * _Note:_ Be careful, sharing the setup from a beforeAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail.\n     * @name beforeAll\n     * @since 2.1.0\n     * @function\n     * @global\n     * @param {implementationCallback} [function] Function that contains the code to setup your specs.\n     * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async beforeAll.\n     * @see async\n     */\n    beforeAll: function() {\n      return env.beforeAll.apply(env, arguments);\n    },\n\n    /**\n     * Run some shared teardown once after all of the specs in the {@link describe} are run.\n     *\n     * _Note:_ Be careful, sharing the teardown from a afterAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail.\n     * @name afterAll\n     * @since 2.1.0\n     * @function\n     * @global\n     * @param {implementationCallback} [function] Function that contains the code to teardown your specs.\n     * @param {Int} [timeout={@link jasmine.DEFAULT_TIMEOUT_INTERVAL}] Custom timeout for an async afterAll.\n     * @see async\n     */\n    afterAll: function() {\n      return env.afterAll.apply(env, arguments);\n    },\n\n    /**\n     * Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult}\n     * @name setSpecProperty\n     * @since 3.6.0\n     * @function\n     * @param {String} key The name of the property\n     * @param {*} value The value of the property\n     */\n    setSpecProperty: function(key, value) {\n      return env.setSpecProperty(key, value);\n    },\n\n    /**\n     * Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult}\n     * @name setSuiteProperty\n     * @since 3.6.0\n     * @function\n     * @param {String} key The name of the property\n     * @param {*} value The value of the property\n     */\n    setSuiteProperty: function(key, value) {\n      return env.setSuiteProperty(key, value);\n    },\n\n    /**\n     * Create an expectation for a spec.\n     * @name expect\n     * @since 1.3.0\n     * @function\n     * @global\n     * @param {Object} actual - Actual computed value to test expectations against.\n     * @return {matchers}\n     */\n    expect: function(actual) {\n      return env.expect(actual);\n    },\n\n    /**\n     * Create an asynchronous expectation for a spec. Note that the matchers\n     * that are provided by an asynchronous expectation all return promises\n     * which must be either returned from the spec or waited for using `await`\n     * in order for Jasmine to associate them with the correct spec.\n     * @name expectAsync\n     * @since 3.3.0\n     * @function\n     * @global\n     * @param {Object} actual - Actual computed value to test expectations against.\n     * @return {async-matchers}\n     * @example\n     * await expectAsync(somePromise).toBeResolved();\n     * @example\n     * return expectAsync(somePromise).toBeResolved();\n     */\n    expectAsync: function(actual) {\n      return env.expectAsync(actual);\n    },\n\n    /**\n     * Mark a spec as pending, expectation results will be ignored.\n     * @name pending\n     * @since 2.0.0\n     * @function\n     * @global\n     * @param {String} [message] - Reason the spec is pending.\n     */\n    pending: function() {\n      return env.pending.apply(env, arguments);\n    },\n\n    /**\n     * Explicitly mark a spec as failed.\n     * @name fail\n     * @since 2.1.0\n     * @function\n     * @global\n     * @param {String|Error} [error] - Reason for the failure.\n     */\n    fail: function() {\n      return env.fail.apply(env, arguments);\n    },\n\n    /**\n     * Install a spy onto an existing object.\n     * @name spyOn\n     * @since 1.3.0\n     * @function\n     * @global\n     * @param {Object} obj - The object upon which to install the {@link Spy}.\n     * @param {String} methodName - The name of the method to replace with a {@link Spy}.\n     * @returns {Spy}\n     */\n    spyOn: function(obj, methodName) {\n      return env.spyOn(obj, methodName);\n    },\n\n    /**\n     * Install a spy on a property installed with `Object.defineProperty` onto an existing object.\n     * @name spyOnProperty\n     * @since 2.6.0\n     * @function\n     * @global\n     * @param {Object} obj - The object upon which to install the {@link Spy}\n     * @param {String} propertyName - The name of the property to replace with a {@link Spy}.\n     * @param {String} [accessType=get] - The access type (get|set) of the property to {@link Spy} on.\n     * @returns {Spy}\n     */\n    spyOnProperty: function(obj, methodName, accessType) {\n      return env.spyOnProperty(obj, methodName, accessType);\n    },\n\n    /**\n     * Installs spies on all writable and configurable properties of an object.\n     * @name spyOnAllFunctions\n     * @since 3.2.1\n     * @function\n     * @global\n     * @param {Object} obj - The object upon which to install the {@link Spy}s\n     * @param {boolean} includeNonEnumerable - Whether or not to add spies to non-enumerable properties\n     * @returns {Object} the spied object\n     */\n    spyOnAllFunctions: function(obj, includeNonEnumerable) {\n      return env.spyOnAllFunctions(obj, includeNonEnumerable);\n    },\n\n    jsApiReporter: new jasmine.JsApiReporter({\n      timer: new jasmine.Timer()\n    }),\n\n    /**\n     * @namespace jasmine\n     */\n    jasmine: jasmine\n  };\n\n  /**\n   * Add a custom equality tester for the current scope of specs.\n   *\n   * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.\n   * @name jasmine.addCustomEqualityTester\n   * @since 2.0.0\n   * @function\n   * @param {Function} tester - A function which takes two arguments to compare and returns a `true` or `false` comparison result if it knows how to compare them, and `undefined` otherwise.\n   * @see custom_equality\n   */\n  jasmine.addCustomEqualityTester = function(tester) {\n    env.addCustomEqualityTester(tester);\n  };\n\n  /**\n   * Add custom matchers for the current scope of specs.\n   *\n   * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.\n   * @name jasmine.addMatchers\n   * @since 2.0.0\n   * @function\n   * @param {Object} matchers - Keys from this object will be the new matcher names.\n   * @see custom_matcher\n   */\n  jasmine.addMatchers = function(matchers) {\n    return env.addMatchers(matchers);\n  };\n\n  /**\n   * Add custom async matchers for the current scope of specs.\n   *\n   * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.\n   * @name jasmine.addAsyncMatchers\n   * @since 3.5.0\n   * @function\n   * @param {Object} matchers - Keys from this object will be the new async matcher names.\n   * @see custom_matcher\n   */\n  jasmine.addAsyncMatchers = function(matchers) {\n    return env.addAsyncMatchers(matchers);\n  };\n\n  /**\n   * Add a custom object formatter for the current scope of specs.\n   *\n   * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.\n   * @name jasmine.addCustomObjectFormatter\n   * @since 3.6.0\n   * @function\n   * @param {Function} formatter - A function which takes a value to format and returns a string if it knows how to format it, and `undefined` otherwise.\n   * @see custom_object_formatters\n   */\n  jasmine.addCustomObjectFormatter = function(formatter) {\n    return env.addCustomObjectFormatter(formatter);\n  };\n\n  /**\n   * Get the currently booted mock {Clock} for this Jasmine environment.\n   * @name jasmine.clock\n   * @since 2.0.0\n   * @function\n   * @returns {Clock}\n   */\n  jasmine.clock = function() {\n    return env.clock;\n  };\n\n  /**\n   * Create a bare {@link Spy} object. This won't be installed anywhere and will not have any implementation behind it.\n   * @name jasmine.createSpy\n   * @since 1.3.0\n   * @function\n   * @param {String} [name] - Name to give the spy. This will be displayed in failure messages.\n   * @param {Function} [originalFn] - Function to act as the real implementation.\n   * @return {Spy}\n   */\n  jasmine.createSpy = function(name, originalFn) {\n    return env.createSpy(name, originalFn);\n  };\n\n  /**\n   * Create an object with multiple {@link Spy}s as its members.\n   * @name jasmine.createSpyObj\n   * @since 1.3.0\n   * @function\n   * @param {String} [baseName] - Base name for the spies in the object.\n   * @param {String[]|Object} methodNames - Array of method names to create spies for, or Object whose keys will be method names and values the {@link Spy#and#returnValue|returnValue}.\n   * @param {String[]|Object} [propertyNames] - Array of property names to create spies for, or Object whose keys will be propertynames and values the {@link Spy#and#returnValue|returnValue}.\n   * @return {Object}\n   */\n  jasmine.createSpyObj = function(baseName, methodNames, propertyNames) {\n    return env.createSpyObj(baseName, methodNames, propertyNames);\n  };\n\n  /**\n   * Add a custom spy strategy for the current scope of specs.\n   *\n   * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.\n   * @name jasmine.addSpyStrategy\n   * @since 3.5.0\n   * @function\n   * @param {String} name - The name of the strategy (i.e. what you call from `and`)\n   * @param {Function} factory - Factory function that returns the plan to be executed.\n   */\n  jasmine.addSpyStrategy = function(name, factory) {\n    return env.addSpyStrategy(name, factory);\n  };\n\n  /**\n   * Set the default spy strategy for the current scope of specs.\n   *\n   * _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.\n   * @name jasmine.setDefaultSpyStrategy\n   * @function\n   * @param {Function} defaultStrategyFn - a function that assigns a strategy\n   * @example\n   * beforeEach(function() {\n   *   jasmine.setDefaultSpyStrategy(and => and.returnValue(true));\n   * });\n   */\n  jasmine.setDefaultSpyStrategy = function(defaultStrategyFn) {\n    return env.setDefaultSpyStrategy(defaultStrategyFn);\n  };\n\n  return jasmineInterface;\n};\n\ngetJasmineRequireObj().SkipAfterBeforeAllErrorPolicy = function(j$) {\n  function SkipAfterBeforeAllErrorPolicy(queueableFns) {\n    this.queueableFns_ = queueableFns;\n    this.skipping_ = false;\n  }\n\n  SkipAfterBeforeAllErrorPolicy.prototype.skipTo = function(lastRanFnIx) {\n    if (this.skipping_) {\n      return this.nextAfterAllAfter_(lastRanFnIx);\n    } else {\n      return lastRanFnIx + 1;\n    }\n  };\n\n  SkipAfterBeforeAllErrorPolicy.prototype.nextAfterAllAfter_ = function(i) {\n    for (\n      i++;\n      i < this.queueableFns_.length &&\n      this.queueableFns_[i].type !== 'afterAll';\n      i++\n    ) {}\n    return i;\n  };\n\n  SkipAfterBeforeAllErrorPolicy.prototype.fnErrored = function(fnIx) {\n    if (this.queueableFns_[fnIx].type === 'beforeAll') {\n      this.skipping_ = true;\n      // Failures need to be reported for each contained spec. But we can't do\n      // that from here because reporting is async. This function isn't async\n      // (and can't be without greatly complicating QueueRunner). Mark the\n      // failure so that the code that reports the suite result (which is\n      // already async) can detect the failure and report the specs.\n      this.queueableFns_[fnIx].suite.hadBeforeAllFailure = true;\n    }\n  };\n\n  return SkipAfterBeforeAllErrorPolicy;\n};\n\ngetJasmineRequireObj().Spy = function(j$) {\n  var nextOrder = (function() {\n    var order = 0;\n\n    return function() {\n      return order++;\n    };\n  })();\n\n  /**\n   * @classdesc _Note:_ Do not construct this directly. Use {@link spyOn},\n   * {@link spyOnProperty}, {@link jasmine.createSpy}, or\n   * {@link jasmine.createSpyObj} instead.\n   * @class Spy\n   * @hideconstructor\n   */\n  function Spy(name, matchersUtil, optionals) {\n    const { originalFn, customStrategies, defaultStrategyFn } = optionals || {};\n\n    var numArgs = typeof originalFn === 'function' ? originalFn.length : 0,\n      wrapper = makeFunc(numArgs, function(context, args, invokeNew) {\n        return spy(context, args, invokeNew);\n      }),\n      strategyDispatcher = new SpyStrategyDispatcher(\n        {\n          name: name,\n          fn: originalFn,\n          getSpy: function() {\n            return wrapper;\n          },\n          customStrategies: customStrategies\n        },\n        matchersUtil\n      ),\n      callTracker = new j$.CallTracker(),\n      spy = function(context, args, invokeNew) {\n        /**\n         * @name Spy.callData\n         * @property {object} object - `this` context for the invocation.\n         * @property {number} invocationOrder - Order of the invocation.\n         * @property {Array} args - The arguments passed for this invocation.\n         * @property returnValue - The value that was returned from this invocation.\n         */\n        var callData = {\n          object: context,\n          invocationOrder: nextOrder(),\n          args: Array.prototype.slice.apply(args)\n        };\n\n        callTracker.track(callData);\n        var returnValue = strategyDispatcher.exec(context, args, invokeNew);\n        callData.returnValue = returnValue;\n\n        return returnValue;\n      };\n\n    function makeFunc(length, fn) {\n      switch (length) {\n        case 1:\n          return function wrap1(a) {\n            return fn(this, arguments, this instanceof wrap1);\n          };\n        case 2:\n          return function wrap2(a, b) {\n            return fn(this, arguments, this instanceof wrap2);\n          };\n        case 3:\n          return function wrap3(a, b, c) {\n            return fn(this, arguments, this instanceof wrap3);\n          };\n        case 4:\n          return function wrap4(a, b, c, d) {\n            return fn(this, arguments, this instanceof wrap4);\n          };\n        case 5:\n          return function wrap5(a, b, c, d, e) {\n            return fn(this, arguments, this instanceof wrap5);\n          };\n        case 6:\n          return function wrap6(a, b, c, d, e, f) {\n            return fn(this, arguments, this instanceof wrap6);\n          };\n        case 7:\n          return function wrap7(a, b, c, d, e, f, g) {\n            return fn(this, arguments, this instanceof wrap7);\n          };\n        case 8:\n          return function wrap8(a, b, c, d, e, f, g, h) {\n            return fn(this, arguments, this instanceof wrap8);\n          };\n        case 9:\n          return function wrap9(a, b, c, d, e, f, g, h, i) {\n            return fn(this, arguments, this instanceof wrap9);\n          };\n        default:\n          return function wrap() {\n            return fn(this, arguments, this instanceof wrap);\n          };\n      }\n    }\n\n    for (var prop in originalFn) {\n      if (prop === 'and' || prop === 'calls') {\n        throw new Error(\n          \"Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon\"\n        );\n      }\n\n      wrapper[prop] = originalFn[prop];\n    }\n\n    /**\n     * @member {SpyStrategy} - Accesses the default strategy for the spy. This strategy will be used\n     * whenever the spy is called with arguments that don't match any strategy\n     * created with {@link Spy#withArgs}.\n     * @name Spy#and\n     * @since 2.0.0\n     * @example\n     * spyOn(someObj, 'func').and.returnValue(42);\n     */\n    wrapper.and = strategyDispatcher.and;\n    /**\n     * Specifies a strategy to be used for calls to the spy that have the\n     * specified arguments.\n     * @name Spy#withArgs\n     * @since 3.0.0\n     * @function\n     * @param {...*} args - The arguments to match\n     * @type {SpyStrategy}\n     * @example\n     * spyOn(someObj, 'func').withArgs(1, 2, 3).and.returnValue(42);\n     * someObj.func(1, 2, 3); // returns 42\n     */\n    wrapper.withArgs = function() {\n      return strategyDispatcher.withArgs.apply(strategyDispatcher, arguments);\n    };\n    wrapper.calls = callTracker;\n\n    if (defaultStrategyFn) {\n      defaultStrategyFn(wrapper.and);\n    }\n\n    return wrapper;\n  }\n\n  function SpyStrategyDispatcher(strategyArgs, matchersUtil) {\n    var baseStrategy = new j$.SpyStrategy(strategyArgs);\n    var argsStrategies = new StrategyDict(function() {\n      return new j$.SpyStrategy(strategyArgs);\n    }, matchersUtil);\n\n    this.and = baseStrategy;\n\n    this.exec = function(spy, args, invokeNew) {\n      var strategy = argsStrategies.get(args);\n\n      if (!strategy) {\n        if (argsStrategies.any() && !baseStrategy.isConfigured()) {\n          throw new Error(\n            \"Spy '\" +\n              strategyArgs.name +\n              \"' received a call with arguments \" +\n              j$.basicPrettyPrinter_(Array.prototype.slice.call(args)) +\n              ' but all configured strategies specify other arguments.'\n          );\n        } else {\n          strategy = baseStrategy;\n        }\n      }\n\n      return strategy.exec(spy, args, invokeNew);\n    };\n\n    this.withArgs = function() {\n      return { and: argsStrategies.getOrCreate(arguments) };\n    };\n  }\n\n  function StrategyDict(strategyFactory, matchersUtil) {\n    this.strategies = [];\n    this.strategyFactory = strategyFactory;\n    this.matchersUtil = matchersUtil;\n  }\n\n  StrategyDict.prototype.any = function() {\n    return this.strategies.length > 0;\n  };\n\n  StrategyDict.prototype.getOrCreate = function(args) {\n    var strategy = this.get(args);\n\n    if (!strategy) {\n      strategy = this.strategyFactory();\n      this.strategies.push({\n        args: args,\n        strategy: strategy\n      });\n    }\n\n    return strategy;\n  };\n\n  StrategyDict.prototype.get = function(args) {\n    var i;\n\n    for (i = 0; i < this.strategies.length; i++) {\n      if (this.matchersUtil.equals(args, this.strategies[i].args)) {\n        return this.strategies[i].strategy;\n      }\n    }\n  };\n\n  return Spy;\n};\n\ngetJasmineRequireObj().SpyFactory = function(j$) {\n  function SpyFactory(\n    getCustomStrategies,\n    getDefaultStrategyFn,\n    getMatchersUtil\n  ) {\n    var self = this;\n\n    this.createSpy = function(name, originalFn) {\n      return j$.Spy(name, getMatchersUtil(), {\n        originalFn,\n        customStrategies: getCustomStrategies(),\n        defaultStrategyFn: getDefaultStrategyFn()\n      });\n    };\n\n    this.createSpyObj = function(baseName, methodNames, propertyNames) {\n      var baseNameIsCollection =\n        j$.isObject_(baseName) || j$.isArray_(baseName);\n\n      if (baseNameIsCollection) {\n        propertyNames = methodNames;\n        methodNames = baseName;\n        baseName = 'unknown';\n      }\n\n      var obj = {};\n      var spy, descriptor;\n\n      var methods = normalizeKeyValues(methodNames);\n      for (var i = 0; i < methods.length; i++) {\n        spy = obj[methods[i][0]] = self.createSpy(\n          baseName + '.' + methods[i][0]\n        );\n        if (methods[i].length > 1) {\n          spy.and.returnValue(methods[i][1]);\n        }\n      }\n\n      var properties = normalizeKeyValues(propertyNames);\n      for (var i = 0; i < properties.length; i++) {\n        descriptor = {\n          enumerable: true,\n          get: self.createSpy(baseName + '.' + properties[i][0] + '.get'),\n          set: self.createSpy(baseName + '.' + properties[i][0] + '.set')\n        };\n        if (properties[i].length > 1) {\n          descriptor.get.and.returnValue(properties[i][1]);\n          descriptor.set.and.returnValue(properties[i][1]);\n        }\n        Object.defineProperty(obj, properties[i][0], descriptor);\n      }\n\n      if (methods.length === 0 && properties.length === 0) {\n        throw 'createSpyObj requires a non-empty array or object of method names to create spies for';\n      }\n\n      return obj;\n    };\n  }\n\n  function normalizeKeyValues(object) {\n    var result = [];\n    if (j$.isArray_(object)) {\n      for (var i = 0; i < object.length; i++) {\n        result.push([object[i]]);\n      }\n    } else if (j$.isObject_(object)) {\n      for (var key in object) {\n        if (object.hasOwnProperty(key)) {\n          result.push([key, object[key]]);\n        }\n      }\n    }\n    return result;\n  }\n\n  return SpyFactory;\n};\n\ngetJasmineRequireObj().SpyRegistry = function(j$) {\n  var spyOnMsg = j$.formatErrorMsg('<spyOn>', 'spyOn(<object>, <methodName>)');\n  var spyOnPropertyMsg = j$.formatErrorMsg(\n    '<spyOnProperty>',\n    'spyOnProperty(<object>, <propName>, [accessType])'\n  );\n\n  function SpyRegistry(options) {\n    options = options || {};\n    var global = options.global || j$.getGlobal();\n    var createSpy = options.createSpy;\n    var currentSpies =\n      options.currentSpies ||\n      function() {\n        return [];\n      };\n\n    this.allowRespy = function(allow) {\n      this.respy = allow;\n    };\n\n    this.spyOn = function(obj, methodName) {\n      var getErrorMsg = spyOnMsg;\n\n      if (j$.util.isUndefined(obj) || obj === null) {\n        throw new Error(\n          getErrorMsg(\n            'could not find an object to spy upon for ' + methodName + '()'\n          )\n        );\n      }\n\n      if (j$.util.isUndefined(methodName) || methodName === null) {\n        throw new Error(getErrorMsg('No method name supplied'));\n      }\n\n      if (j$.util.isUndefined(obj[methodName])) {\n        throw new Error(getErrorMsg(methodName + '() method does not exist'));\n      }\n\n      if (obj[methodName] && j$.isSpy(obj[methodName])) {\n        if (this.respy) {\n          return obj[methodName];\n        } else {\n          throw new Error(\n            getErrorMsg(methodName + ' has already been spied upon')\n          );\n        }\n      }\n\n      var descriptor = Object.getOwnPropertyDescriptor(obj, methodName);\n\n      if (descriptor && !(descriptor.writable || descriptor.set)) {\n        throw new Error(\n          getErrorMsg(methodName + ' is not declared writable or has no setter')\n        );\n      }\n\n      var originalMethod = obj[methodName],\n        spiedMethod = createSpy(methodName, originalMethod),\n        restoreStrategy;\n\n      if (\n        Object.prototype.hasOwnProperty.call(obj, methodName) ||\n        (obj === global && methodName === 'onerror')\n      ) {\n        restoreStrategy = function() {\n          obj[methodName] = originalMethod;\n        };\n      } else {\n        restoreStrategy = function() {\n          if (!delete obj[methodName]) {\n            obj[methodName] = originalMethod;\n          }\n        };\n      }\n\n      currentSpies().push({\n        restoreObjectToOriginalState: restoreStrategy\n      });\n\n      obj[methodName] = spiedMethod;\n\n      return spiedMethod;\n    };\n\n    this.spyOnProperty = function(obj, propertyName, accessType) {\n      var getErrorMsg = spyOnPropertyMsg;\n\n      accessType = accessType || 'get';\n\n      if (j$.util.isUndefined(obj)) {\n        throw new Error(\n          getErrorMsg(\n            'spyOn could not find an object to spy upon for ' +\n              propertyName +\n              ''\n          )\n        );\n      }\n\n      if (j$.util.isUndefined(propertyName)) {\n        throw new Error(getErrorMsg('No property name supplied'));\n      }\n\n      var descriptor = j$.util.getPropertyDescriptor(obj, propertyName);\n\n      if (!descriptor) {\n        throw new Error(getErrorMsg(propertyName + ' property does not exist'));\n      }\n\n      if (!descriptor.configurable) {\n        throw new Error(\n          getErrorMsg(propertyName + ' is not declared configurable')\n        );\n      }\n\n      if (!descriptor[accessType]) {\n        throw new Error(\n          getErrorMsg(\n            'Property ' +\n              propertyName +\n              ' does not have access type ' +\n              accessType\n          )\n        );\n      }\n\n      if (j$.isSpy(descriptor[accessType])) {\n        if (this.respy) {\n          return descriptor[accessType];\n        } else {\n          throw new Error(\n            getErrorMsg(\n              propertyName + '#' + accessType + ' has already been spied upon'\n            )\n          );\n        }\n      }\n\n      var originalDescriptor = j$.util.clone(descriptor),\n        spy = createSpy(propertyName, descriptor[accessType]),\n        restoreStrategy;\n\n      if (Object.prototype.hasOwnProperty.call(obj, propertyName)) {\n        restoreStrategy = function() {\n          Object.defineProperty(obj, propertyName, originalDescriptor);\n        };\n      } else {\n        restoreStrategy = function() {\n          delete obj[propertyName];\n        };\n      }\n\n      currentSpies().push({\n        restoreObjectToOriginalState: restoreStrategy\n      });\n\n      descriptor[accessType] = spy;\n\n      Object.defineProperty(obj, propertyName, descriptor);\n\n      return spy;\n    };\n\n    this.spyOnAllFunctions = function(obj, includeNonEnumerable) {\n      if (j$.util.isUndefined(obj)) {\n        throw new Error(\n          'spyOnAllFunctions could not find an object to spy upon'\n        );\n      }\n\n      var pointer = obj,\n        propsToSpyOn = [],\n        properties,\n        propertiesToSkip = [];\n\n      while (\n        pointer &&\n        (!includeNonEnumerable || pointer !== Object.prototype)\n      ) {\n        properties = getProps(pointer, includeNonEnumerable);\n        properties = properties.filter(function(prop) {\n          return propertiesToSkip.indexOf(prop) === -1;\n        });\n        propertiesToSkip = propertiesToSkip.concat(properties);\n        propsToSpyOn = propsToSpyOn.concat(\n          getSpyableFunctionProps(pointer, properties)\n        );\n        pointer = Object.getPrototypeOf(pointer);\n      }\n\n      for (var i = 0; i < propsToSpyOn.length; i++) {\n        this.spyOn(obj, propsToSpyOn[i]);\n      }\n\n      return obj;\n    };\n\n    this.clearSpies = function() {\n      var spies = currentSpies();\n      for (var i = spies.length - 1; i >= 0; i--) {\n        var spyEntry = spies[i];\n        spyEntry.restoreObjectToOriginalState();\n      }\n    };\n  }\n\n  function getProps(obj, includeNonEnumerable) {\n    var enumerableProperties = Object.keys(obj);\n\n    if (!includeNonEnumerable) {\n      return enumerableProperties;\n    }\n\n    return Object.getOwnPropertyNames(obj).filter(function(prop) {\n      return (\n        prop !== 'constructor' ||\n        enumerableProperties.indexOf('constructor') > -1\n      );\n    });\n  }\n\n  function getSpyableFunctionProps(obj, propertiesToCheck) {\n    var props = [],\n      prop;\n    for (var i = 0; i < propertiesToCheck.length; i++) {\n      prop = propertiesToCheck[i];\n      if (\n        Object.prototype.hasOwnProperty.call(obj, prop) &&\n        isSpyableProp(obj, prop)\n      ) {\n        props.push(prop);\n      }\n    }\n    return props;\n  }\n\n  function isSpyableProp(obj, prop) {\n    var value, descriptor;\n    try {\n      value = obj[prop];\n    } catch (e) {\n      return false;\n    }\n    if (value instanceof Function) {\n      descriptor = Object.getOwnPropertyDescriptor(obj, prop);\n      return (descriptor.writable || descriptor.set) && descriptor.configurable;\n    }\n    return false;\n  }\n\n  return SpyRegistry;\n};\n\ngetJasmineRequireObj().SpyStrategy = function(j$) {\n  /**\n   * @interface SpyStrategy\n   */\n  function SpyStrategy(options) {\n    options = options || {};\n\n    var self = this;\n\n    /**\n     * Get the identifying information for the spy.\n     * @name SpyStrategy#identity\n     * @since 3.0.0\n     * @member\n     * @type {String}\n     */\n    this.identity = options.name || 'unknown';\n    this.originalFn = options.fn || function() {};\n    this.getSpy = options.getSpy || function() {};\n    this.plan = this._defaultPlan = function() {};\n\n    var k,\n      cs = options.customStrategies || {};\n    for (k in cs) {\n      if (j$.util.has(cs, k) && !this[k]) {\n        this[k] = createCustomPlan(cs[k]);\n      }\n    }\n\n    /**\n     * Tell the spy to return a promise resolving to the specified value when invoked.\n     * @name SpyStrategy#resolveTo\n     * @since 3.5.0\n     * @function\n     * @param {*} value The value to return.\n     */\n    this.resolveTo = function(value) {\n      self.plan = function() {\n        return Promise.resolve(value);\n      };\n      return self.getSpy();\n    };\n\n    /**\n     * Tell the spy to return a promise rejecting with the specified value when invoked.\n     * @name SpyStrategy#rejectWith\n     * @since 3.5.0\n     * @function\n     * @param {*} value The value to return.\n     */\n    this.rejectWith = function(value) {\n      self.plan = function() {\n        return Promise.reject(value);\n      };\n      return self.getSpy();\n    };\n  }\n\n  function createCustomPlan(factory) {\n    return function() {\n      var plan = factory.apply(null, arguments);\n\n      if (!j$.isFunction_(plan)) {\n        throw new Error('Spy strategy must return a function');\n      }\n\n      this.plan = plan;\n      return this.getSpy();\n    };\n  }\n\n  /**\n   * Execute the current spy strategy.\n   * @name SpyStrategy#exec\n   * @since 2.0.0\n   * @function\n   */\n  SpyStrategy.prototype.exec = function(context, args, invokeNew) {\n    var contextArgs = [context].concat(\n      args ? Array.prototype.slice.call(args) : []\n    );\n    var target = this.plan.bind.apply(this.plan, contextArgs);\n\n    return invokeNew ? new target() : target();\n  };\n\n  /**\n   * Tell the spy to call through to the real implementation when invoked.\n   * @name SpyStrategy#callThrough\n   * @since 2.0.0\n   * @function\n   */\n  SpyStrategy.prototype.callThrough = function() {\n    this.plan = this.originalFn;\n    return this.getSpy();\n  };\n\n  /**\n   * Tell the spy to return the value when invoked.\n   * @name SpyStrategy#returnValue\n   * @since 2.0.0\n   * @function\n   * @param {*} value The value to return.\n   */\n  SpyStrategy.prototype.returnValue = function(value) {\n    this.plan = function() {\n      return value;\n    };\n    return this.getSpy();\n  };\n\n  /**\n   * Tell the spy to return one of the specified values (sequentially) each time the spy is invoked.\n   * @name SpyStrategy#returnValues\n   * @since 2.1.0\n   * @function\n   * @param {...*} values - Values to be returned on subsequent calls to the spy.\n   */\n  SpyStrategy.prototype.returnValues = function() {\n    var values = Array.prototype.slice.call(arguments);\n    this.plan = function() {\n      return values.shift();\n    };\n    return this.getSpy();\n  };\n\n  /**\n   * Tell the spy to throw an error when invoked.\n   * @name SpyStrategy#throwError\n   * @since 2.0.0\n   * @function\n   * @param {Error|Object|String} something Thing to throw\n   */\n  SpyStrategy.prototype.throwError = function(something) {\n    var error = j$.isString_(something) ? new Error(something) : something;\n    this.plan = function() {\n      throw error;\n    };\n    return this.getSpy();\n  };\n\n  /**\n   * Tell the spy to call a fake implementation when invoked.\n   * @name SpyStrategy#callFake\n   * @since 2.0.0\n   * @function\n   * @param {Function} fn The function to invoke with the passed parameters.\n   */\n  SpyStrategy.prototype.callFake = function(fn) {\n    if (\n      !(\n        j$.isFunction_(fn) ||\n        j$.isAsyncFunction_(fn) ||\n        j$.isGeneratorFunction_(fn)\n      )\n    ) {\n      throw new Error(\n        'Argument passed to callFake should be a function, got ' + fn\n      );\n    }\n    this.plan = fn;\n    return this.getSpy();\n  };\n\n  /**\n   * Tell the spy to do nothing when invoked. This is the default.\n   * @name SpyStrategy#stub\n   * @since 2.0.0\n   * @function\n   */\n  SpyStrategy.prototype.stub = function(fn) {\n    this.plan = function() {};\n    return this.getSpy();\n  };\n\n  SpyStrategy.prototype.isConfigured = function() {\n    return this.plan !== this._defaultPlan;\n  };\n\n  return SpyStrategy;\n};\n\ngetJasmineRequireObj().StackTrace = function(j$) {\n  function StackTrace(error) {\n    var lines = error.stack.split('\\n').filter(function(line) {\n      return line !== '';\n    });\n\n    var extractResult = extractMessage(error.message, lines);\n\n    if (extractResult) {\n      this.message = extractResult.message;\n      lines = extractResult.remainder;\n    }\n\n    var parseResult = tryParseFrames(lines);\n    this.frames = parseResult.frames;\n    this.style = parseResult.style;\n  }\n\n  var framePatterns = [\n    // Node, Chrome, Edge\n    // e.g. \"   at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)\"\n    // Note that the \"function name\" can include a surprisingly large set of\n    // characters, including angle brackets and square brackets.\n    {\n      re: /^\\s*at ([^\\)]+) \\(([^\\)]+)\\)$/,\n      fnIx: 1,\n      fileLineColIx: 2,\n      style: 'v8'\n    },\n\n    // NodeJS alternate form, often mixed in with the Chrome style\n    // e.g. \"  at /some/path:4320:20\n    { re: /\\s*at (.+)$/, fileLineColIx: 1, style: 'v8' },\n\n    // PhantomJS on OS X, Safari, Firefox\n    // e.g. \"run@http://localhost:8888/__jasmine__/jasmine.js:4320:27\"\n    // or \"http://localhost:8888/__jasmine__/jasmine.js:4320:27\"\n    {\n      re: /^(?:(([^@\\s]+)@)|@)?([^\\s]+)$/,\n      fnIx: 2,\n      fileLineColIx: 3,\n      style: 'webkit'\n    }\n  ];\n\n  // regexes should capture the function name (if any) as group 1\n  // and the file, line, and column as group 2.\n  function tryParseFrames(lines) {\n    var style = null;\n    var frames = lines.map(function(line) {\n      var convertedLine = first(framePatterns, function(pattern) {\n        var overallMatch = line.match(pattern.re),\n          fileLineColMatch;\n        if (!overallMatch) {\n          return null;\n        }\n\n        fileLineColMatch = overallMatch[pattern.fileLineColIx].match(\n          /^(.*):(\\d+)(?::\\d+)?$/\n        );\n        if (!fileLineColMatch) {\n          return { raw: line };\n        }\n\n        style = style || pattern.style;\n        return {\n          raw: line,\n          file: fileLineColMatch[1],\n          line: parseInt(fileLineColMatch[2], 10),\n          func: overallMatch[pattern.fnIx]\n        };\n      });\n\n      return convertedLine || { raw: line };\n    });\n\n    return {\n      style: style,\n      frames: frames\n    };\n  }\n\n  function first(items, fn) {\n    var i, result;\n\n    for (i = 0; i < items.length; i++) {\n      result = fn(items[i]);\n\n      if (result) {\n        return result;\n      }\n    }\n  }\n\n  function extractMessage(message, stackLines) {\n    var len = messagePrefixLength(message, stackLines);\n\n    if (len > 0) {\n      return {\n        message: stackLines.slice(0, len).join('\\n'),\n        remainder: stackLines.slice(len)\n      };\n    }\n  }\n\n  function messagePrefixLength(message, stackLines) {\n    if (!stackLines[0].match(/^\\w*Error/)) {\n      return 0;\n    }\n\n    var messageLines = message.split('\\n');\n    var i;\n\n    for (i = 1; i < messageLines.length; i++) {\n      if (messageLines[i] !== stackLines[i]) {\n        return 0;\n      }\n    }\n\n    return messageLines.length;\n  }\n\n  return StackTrace;\n};\n\ngetJasmineRequireObj().Suite = function(j$) {\n  /**\n   * @interface Suite\n   * @see Env#topSuite\n   * @since 2.0.0\n   */\n  function Suite(attrs) {\n    this.env = attrs.env;\n    /**\n     * The unique ID of this suite.\n     * @name Suite#id\n     * @readonly\n     * @type {string}\n     * @since 2.0.0\n     */\n    this.id = attrs.id;\n    this.parentSuite = attrs.parentSuite;\n    /**\n     * The description passed to the {@link describe} that created this suite.\n     * @name Suite#description\n     * @readonly\n     * @type {string}\n     * @since 2.0.0\n     */\n    this.description = attrs.description;\n    this.expectationFactory = attrs.expectationFactory;\n    this.asyncExpectationFactory = attrs.asyncExpectationFactory;\n    this.expectationResultFactory = attrs.expectationResultFactory;\n    this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;\n    this.autoCleanClosures =\n      attrs.autoCleanClosures === undefined ? true : !!attrs.autoCleanClosures;\n    this.onLateError = attrs.onLateError;\n\n    this.beforeFns = [];\n    this.afterFns = [];\n    this.beforeAllFns = [];\n    this.afterAllFns = [];\n    this.timer = attrs.timer || new j$.Timer();\n\n    /**\n     * The suite's children.\n     * @name Suite#children\n     * @type {Array.<(Spec|Suite)>}\n     * @since 2.0.0\n     */\n    this.children = [];\n\n    this.reset();\n  }\n\n  Suite.prototype.setSuiteProperty = function(key, value) {\n    this.result.properties = this.result.properties || {};\n    this.result.properties[key] = value;\n  };\n\n  Suite.prototype.expect = function(actual) {\n    return this.expectationFactory(actual, this);\n  };\n\n  Suite.prototype.expectAsync = function(actual) {\n    return this.asyncExpectationFactory(actual, this);\n  };\n\n  /**\n   * The full description including all ancestors of this suite.\n   * @name Suite#getFullName\n   * @function\n   * @returns {string}\n   * @since 2.0.0\n   */\n  Suite.prototype.getFullName = function() {\n    var fullName = [];\n    for (\n      var parentSuite = this;\n      parentSuite;\n      parentSuite = parentSuite.parentSuite\n    ) {\n      if (parentSuite.parentSuite) {\n        fullName.unshift(parentSuite.description);\n      }\n    }\n    return fullName.join(' ');\n  };\n\n  /*\n   * Mark the suite with \"pending\" status\n   */\n  Suite.prototype.pend = function() {\n    this.markedPending = true;\n  };\n\n  /*\n   * Like {@link Suite#pend}, but pending state will survive {@link Spec#reset}\n   * Useful for fdescribe, xdescribe, where pending state should remain.\n   */\n  Suite.prototype.exclude = function() {\n    this.pend();\n    this.markedExcluding = true;\n  };\n\n  Suite.prototype.beforeEach = function(fn) {\n    this.beforeFns.unshift({ ...fn, suite: this });\n  };\n\n  Suite.prototype.beforeAll = function(fn) {\n    this.beforeAllFns.push({ ...fn, type: 'beforeAll', suite: this });\n  };\n\n  Suite.prototype.afterEach = function(fn) {\n    this.afterFns.unshift({ ...fn, suite: this, type: 'afterEach' });\n  };\n\n  Suite.prototype.afterAll = function(fn) {\n    this.afterAllFns.unshift({ ...fn, type: 'afterAll' });\n  };\n\n  Suite.prototype.startTimer = function() {\n    this.timer.start();\n  };\n\n  Suite.prototype.endTimer = function() {\n    this.result.duration = this.timer.elapsed();\n  };\n\n  function removeFns(queueableFns) {\n    for (var i = 0; i < queueableFns.length; i++) {\n      queueableFns[i].fn = null;\n    }\n  }\n\n  Suite.prototype.cleanupBeforeAfter = function() {\n    if (this.autoCleanClosures) {\n      removeFns(this.beforeAllFns);\n      removeFns(this.afterAllFns);\n      removeFns(this.beforeFns);\n      removeFns(this.afterFns);\n    }\n  };\n\n  Suite.prototype.reset = function() {\n    /**\n     * @typedef SuiteResult\n     * @property {Int} id - The unique id of this suite.\n     * @property {String} description - The description text passed to the {@link describe} that made this suite.\n     * @property {String} fullName - The full description including all ancestors of this suite.\n     * @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.\n     * @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.\n     * @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.\n     * @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach.\n     * @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSuiteProperty}\n     * @since 2.0.0\n     */\n    this.result = {\n      id: this.id,\n      description: this.description,\n      fullName: this.getFullName(),\n      failedExpectations: [],\n      deprecationWarnings: [],\n      duration: null,\n      properties: null\n    };\n    this.markedPending = this.markedExcluding;\n    this.children.forEach(function(child) {\n      child.reset();\n    });\n  };\n\n  Suite.prototype.addChild = function(child) {\n    this.children.push(child);\n  };\n\n  Suite.prototype.status = function() {\n    if (this.markedPending) {\n      return 'pending';\n    }\n\n    if (this.result.failedExpectations.length > 0) {\n      return 'failed';\n    } else {\n      return 'passed';\n    }\n  };\n\n  Suite.prototype.canBeReentered = function() {\n    return this.beforeAllFns.length === 0 && this.afterAllFns.length === 0;\n  };\n\n  Suite.prototype.getResult = function() {\n    this.result.status = this.status();\n    return this.result;\n  };\n\n  Suite.prototype.sharedUserContext = function() {\n    if (!this.sharedContext) {\n      this.sharedContext = this.parentSuite\n        ? this.parentSuite.clonedSharedUserContext()\n        : new j$.UserContext();\n    }\n\n    return this.sharedContext;\n  };\n\n  Suite.prototype.clonedSharedUserContext = function() {\n    return j$.UserContext.fromExisting(this.sharedUserContext());\n  };\n\n  Suite.prototype.onException = function() {\n    if (arguments[0] instanceof j$.errors.ExpectationFailed) {\n      return;\n    }\n\n    var data = {\n      matcherName: '',\n      passed: false,\n      expected: '',\n      actual: '',\n      error: arguments[0]\n    };\n    var failedExpectation = this.expectationResultFactory(data);\n\n    if (!this.parentSuite) {\n      failedExpectation.globalErrorType = 'afterAll';\n    }\n\n    this.result.failedExpectations.push(failedExpectation);\n  };\n\n  Suite.prototype.onMultipleDone = function() {\n    let msg;\n\n    // Issue a deprecation. Include the context ourselves and pass\n    // ignoreRunnable: true, since getting here always means that we've already\n    // moved on and the current runnable isn't the one that caused the problem.\n    if (this.parentSuite) {\n      msg =\n        \"An asynchronous beforeAll or afterAll function called its 'done' \" +\n        'callback more than once.\\n' +\n        '(in suite: ' +\n        this.getFullName() +\n        ')';\n    } else {\n      msg =\n        'A top-level beforeAll or afterAll function called its ' +\n        \"'done' callback more than once.\";\n    }\n\n    this.onLateError(new Error(msg));\n  };\n\n  Suite.prototype.addExpectationResult = function() {\n    if (isFailure(arguments)) {\n      var data = arguments[1];\n      this.result.failedExpectations.push(this.expectationResultFactory(data));\n      if (this.throwOnExpectationFailure) {\n        throw new j$.errors.ExpectationFailed();\n      }\n    }\n  };\n\n  Suite.prototype.addDeprecationWarning = function(deprecation) {\n    if (typeof deprecation === 'string') {\n      deprecation = { message: deprecation };\n    }\n    this.result.deprecationWarnings.push(\n      this.expectationResultFactory(deprecation)\n    );\n  };\n\n  Object.defineProperty(Suite.prototype, 'metadata', {\n    get: function() {\n      if (!this.metadata_) {\n        this.metadata_ = new SuiteMetadata(this);\n      }\n\n      return this.metadata_;\n    }\n  });\n\n  /**\n   * @interface Suite\n   * @see Env#topSuite\n   */\n  function SuiteMetadata(suite) {\n    this.suite_ = suite;\n    /**\n     * The unique ID of this suite.\n     * @name Suite#id\n     * @readonly\n     * @type {string}\n     */\n    this.id = suite.id;\n\n    /**\n     * The parent of this suite, or null if this is the top suite.\n     * @name Suite#parentSuite\n     * @readonly\n     * @type {Suite}\n     */\n    this.parentSuite = suite.parentSuite ? suite.parentSuite.metadata : null;\n\n    /**\n     * The description passed to the {@link describe} that created this suite.\n     * @name Suite#description\n     * @readonly\n     * @type {string}\n     */\n    this.description = suite.description;\n  }\n\n  /**\n   * The full description including all ancestors of this suite.\n   * @name Suite#getFullName\n   * @function\n   * @returns {string}\n   */\n  SuiteMetadata.prototype.getFullName = function() {\n    return this.suite_.getFullName();\n  };\n\n  /**\n   * The suite's children.\n   * @name Suite#children\n   * @type {Array.<(Spec|Suite)>}\n   */\n  Object.defineProperty(SuiteMetadata.prototype, 'children', {\n    get: function() {\n      return this.suite_.children.map(child => child.metadata);\n    }\n  });\n\n  function isFailure(args) {\n    return !args[0];\n  }\n\n  return Suite;\n};\n\ngetJasmineRequireObj().Timer = function() {\n  var defaultNow = (function(Date) {\n    return function() {\n      return new Date().getTime();\n    };\n  })(Date);\n\n  function Timer(options) {\n    options = options || {};\n\n    var now = options.now || defaultNow,\n      startTime;\n\n    this.start = function() {\n      startTime = now();\n    };\n\n    this.elapsed = function() {\n      return now() - startTime;\n    };\n  }\n\n  return Timer;\n};\n\ngetJasmineRequireObj().TreeProcessor = function() {\n  function TreeProcessor(attrs) {\n    var tree = attrs.tree,\n      runnableIds = attrs.runnableIds,\n      queueRunnerFactory = attrs.queueRunnerFactory,\n      nodeStart = attrs.nodeStart || function() {},\n      nodeComplete = attrs.nodeComplete || function() {},\n      failSpecWithNoExpectations = !!attrs.failSpecWithNoExpectations,\n      orderChildren =\n        attrs.orderChildren ||\n        function(node) {\n          return node.children;\n        },\n      excludeNode =\n        attrs.excludeNode ||\n        function(node) {\n          return false;\n        },\n      stats = { valid: true },\n      processed = false,\n      defaultMin = Infinity,\n      defaultMax = 1 - Infinity;\n\n    this.processTree = function() {\n      processNode(tree, true);\n      processed = true;\n      return stats;\n    };\n\n    this.execute = function(done) {\n      if (!processed) {\n        this.processTree();\n      }\n\n      if (!stats.valid) {\n        throw 'invalid order';\n      }\n\n      var childFns = wrapChildren(tree, 0);\n\n      queueRunnerFactory({\n        queueableFns: childFns,\n        userContext: tree.sharedUserContext(),\n        onException: function() {\n          tree.onException.apply(tree, arguments);\n        },\n        onComplete: done,\n        onMultipleDone: tree.onMultipleDone\n          ? tree.onMultipleDone.bind(tree)\n          : null\n      });\n    };\n\n    function runnableIndex(id) {\n      for (var i = 0; i < runnableIds.length; i++) {\n        if (runnableIds[i] === id) {\n          return i;\n        }\n      }\n    }\n\n    function processNode(node, parentExcluded) {\n      var executableIndex = runnableIndex(node.id);\n\n      if (executableIndex !== undefined) {\n        parentExcluded = false;\n      }\n\n      if (!node.children) {\n        var excluded = parentExcluded || excludeNode(node);\n        stats[node.id] = {\n          excluded: excluded,\n          willExecute: !excluded && !node.markedPending,\n          segments: [\n            {\n              index: 0,\n              owner: node,\n              nodes: [node],\n              min: startingMin(executableIndex),\n              max: startingMax(executableIndex)\n            }\n          ]\n        };\n      } else {\n        var hasExecutableChild = false;\n\n        var orderedChildren = orderChildren(node);\n\n        for (var i = 0; i < orderedChildren.length; i++) {\n          var child = orderedChildren[i];\n\n          processNode(child, parentExcluded);\n\n          if (!stats.valid) {\n            return;\n          }\n\n          var childStats = stats[child.id];\n\n          hasExecutableChild = hasExecutableChild || childStats.willExecute;\n        }\n\n        stats[node.id] = {\n          excluded: parentExcluded,\n          willExecute: hasExecutableChild\n        };\n\n        segmentChildren(node, orderedChildren, stats[node.id], executableIndex);\n\n        if (!node.canBeReentered() && stats[node.id].segments.length > 1) {\n          stats = { valid: false };\n        }\n      }\n    }\n\n    function startingMin(executableIndex) {\n      return executableIndex === undefined ? defaultMin : executableIndex;\n    }\n\n    function startingMax(executableIndex) {\n      return executableIndex === undefined ? defaultMax : executableIndex;\n    }\n\n    function segmentChildren(\n      node,\n      orderedChildren,\n      nodeStats,\n      executableIndex\n    ) {\n      var currentSegment = {\n          index: 0,\n          owner: node,\n          nodes: [],\n          min: startingMin(executableIndex),\n          max: startingMax(executableIndex)\n        },\n        result = [currentSegment],\n        lastMax = defaultMax,\n        orderedChildSegments = orderChildSegments(orderedChildren);\n\n      function isSegmentBoundary(minIndex) {\n        return (\n          lastMax !== defaultMax &&\n          minIndex !== defaultMin &&\n          lastMax < minIndex - 1\n        );\n      }\n\n      for (var i = 0; i < orderedChildSegments.length; i++) {\n        var childSegment = orderedChildSegments[i],\n          maxIndex = childSegment.max,\n          minIndex = childSegment.min;\n\n        if (isSegmentBoundary(minIndex)) {\n          currentSegment = {\n            index: result.length,\n            owner: node,\n            nodes: [],\n            min: defaultMin,\n            max: defaultMax\n          };\n          result.push(currentSegment);\n        }\n\n        currentSegment.nodes.push(childSegment);\n        currentSegment.min = Math.min(currentSegment.min, minIndex);\n        currentSegment.max = Math.max(currentSegment.max, maxIndex);\n        lastMax = maxIndex;\n      }\n\n      nodeStats.segments = result;\n    }\n\n    function orderChildSegments(children) {\n      var specifiedOrder = [],\n        unspecifiedOrder = [];\n\n      for (var i = 0; i < children.length; i++) {\n        var child = children[i],\n          segments = stats[child.id].segments;\n\n        for (var j = 0; j < segments.length; j++) {\n          var seg = segments[j];\n\n          if (seg.min === defaultMin) {\n            unspecifiedOrder.push(seg);\n          } else {\n            specifiedOrder.push(seg);\n          }\n        }\n      }\n\n      specifiedOrder.sort(function(a, b) {\n        return a.min - b.min;\n      });\n\n      return specifiedOrder.concat(unspecifiedOrder);\n    }\n\n    function executeNode(node, segmentNumber) {\n      if (node.children) {\n        return {\n          fn: function(done) {\n            var onStart = {\n              fn: function(next) {\n                nodeStart(node, next);\n              }\n            };\n\n            queueRunnerFactory({\n              onComplete: function() {\n                var args = Array.prototype.slice.call(arguments, [0]);\n                node.cleanupBeforeAfter();\n                nodeComplete(node, node.getResult(), function() {\n                  done.apply(undefined, args);\n                });\n              },\n              queueableFns: [onStart].concat(wrapChildren(node, segmentNumber)),\n              userContext: node.sharedUserContext(),\n              onException: function() {\n                node.onException.apply(node, arguments);\n              },\n              onMultipleDone: node.onMultipleDone\n                ? node.onMultipleDone.bind(node)\n                : null\n            });\n          }\n        };\n      } else {\n        return {\n          fn: function(done) {\n            node.execute(\n              done,\n              stats[node.id].excluded,\n              failSpecWithNoExpectations\n            );\n          }\n        };\n      }\n    }\n\n    function wrapChildren(node, segmentNumber) {\n      var result = [],\n        segmentChildren = stats[node.id].segments[segmentNumber].nodes;\n\n      for (var i = 0; i < segmentChildren.length; i++) {\n        result.push(\n          executeNode(segmentChildren[i].owner, segmentChildren[i].index)\n        );\n      }\n\n      if (!stats[node.id].willExecute) {\n        return result;\n      }\n\n      return node.beforeAllFns.concat(result).concat(node.afterAllFns);\n    }\n  }\n\n  return TreeProcessor;\n};\n\ngetJasmineRequireObj().UserContext = function(j$) {\n  function UserContext() {}\n\n  UserContext.fromExisting = function(oldContext) {\n    var context = new UserContext();\n\n    for (var prop in oldContext) {\n      if (oldContext.hasOwnProperty(prop)) {\n        context[prop] = oldContext[prop];\n      }\n    }\n\n    return context;\n  };\n\n  return UserContext;\n};\n\ngetJasmineRequireObj().version = function() {\n  return '4.1.1';\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/src/origin_boot.js",
    "content": "/*\nCopyright (c) 2008-2022 Pivotal Labs\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n*/\nmodule.exports = function(jasmineRequire) {\n  var jasmine = jasmineRequire.core(jasmineRequire);\n\n  var env = jasmine.getEnv({ suppressLoadErrors: true });\n\n  var jasmineInterface = jasmineRequire.interface(jasmine, env);\n\n  extend(global, jasmineInterface);\n\n  function extend(destination, source) {\n    for (var property in source) destination[property] = source[property];\n    return destination;\n  }\n\n  return jasmine;\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/jasmine/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\",\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/persistence/BUILD.bazel",
    "content": "load(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nts_project(\n    name = \"persistence_web\",\n    srcs = glob([\n        \"web/**/*.ts\",\n        \"src/**/*.d.ts\",\n    ]),\n    allow_js = True,\n    composite = True,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n    deps = [\n        \"//:valdi_tsx_link\",\n    ],\n)\n\nvaldi_module(\n    name = \"persistence\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCPersistence\",\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":persistence_web\"],\n    web_register_native_module_id_overrides = {\n        # persistence/src/PersistentStore.ts does require('PersistentStoreNative')\n        \"persistence/web/PersistentStoreNative.js\": \"PersistentStoreNative\",\n    },\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/coreutils\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_standalone\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/persistence/module.yaml",
    "content": "output_target: release\n\nbazel_build_file_generation_disabled: true\n\ndependencies:\n  - coreutils\n  - valdi_core\n  - valdi_standalone\n\nallowed_debug_dependencies:\n  - valdi_standalone\n\nexclude_patterns:\n  - .*\\/web\\/.*\nexclude_globs:\n  - \"**/web/**\"\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/persistence/src/PersistentStore.ts",
    "content": "import { toError } from 'valdi_core/src/utils/ErrorUtils';\nimport { makeSingleCallInterruptibleCallback } from 'valdi_core/src/utils/FunctionUtils';\nimport { PropertyList } from 'valdi_core/src/utils/PropertyList';\nimport { PersistentStoreNative } from './PersistentStoreNative';\n\ndeclare function require(path: string): any;\nconst nativeCreate: (\n  name: string,\n  disableBatchWrites: boolean,\n  userScoped: boolean,\n  maxWeight: number,\n  mockedTime: number | undefined,\n  mockedUserId: string | undefined,\n  enableEncryption: boolean | undefined,\n) => PersistentStoreNative = require('PersistentStoreNative').newPersistentStore;\n\nexport interface PersistentStoreOptions {\n  /**\n   * By default, save operations are batched to minimize the number of disk IO.\n   * This can be set to true to disable this behavior if you wish writes to\n   * happen immediately as soon as store() or remove() are called.\n   */\n  disableBatchWrites?: boolean;\n\n  /**\n   * Whether the store should be available globally across\n   * all user sessions, instead of being scoped to the user.\n   * The data will not be encrypted when this flag is set.\n   */\n  deviceGlobal?: boolean;\n\n  /**\n   * If set, the store will act like an LRU cache where items are\n   * removed as needed to ensure the accumulated weight of all\n   * items stay below this value. If you set this value to something else\n   * than undefined or zero, you should make sure you also provide the weight\n   * when calling store().\n   */\n  maxWeight?: number;\n\n  /**\n   * Set to `true` when storing sensitive data.\n   * ie: credit card info, secret keys, authentication cookies\n   *\n   * Setting to `false` is preffered for most applications as there will be some performance gains.\n   */\n  enableEncryption?: boolean;\n}\n\n/**\n * A persistent store which allows to store data which persists\n * across app sessions.\n */\nexport class PersistentStore {\n  private native: PersistentStoreNative;\n\n  /**\n   * Create a new PersistentStore with the given name.\n   */\n  constructor(readonly name: string, options?: PersistentStoreOptions) {\n    const disableBatchWrites = options?.disableBatchWrites;\n    const deviceGlobal = options?.deviceGlobal === true;\n    const mockedTime = (options as any)?.mockedTime;\n    const mockedUserId = (options as any)?.mockedUserId;\n\n    const userScoped = deviceGlobal === false;\n    this.native = nativeCreate(\n      name,\n      disableBatchWrites ?? false,\n      userScoped,\n      options?.maxWeight ?? 0,\n      mockedTime,\n      mockedUserId,\n      options?.enableEncryption,\n    );\n  }\n\n  /**\n   * Store the blob with the given key\n   */\n  store(key: string, value: ArrayBuffer, ttlSeconds?: number, weight?: number): Promise<void> {\n    return this.storeInner(key, value, ttlSeconds, weight);\n  }\n\n  /**\n   * Store the string blob with the given key\n   */\n  storeString(key: string, value: string, ttlSeconds?: number, weight?: number): Promise<void> {\n    return this.storeInner(key, value, ttlSeconds, weight);\n  }\n\n  /**\n   * Fetch the blob for the given key\n   */\n  fetch(key: string): Promise<ArrayBuffer> {\n    return this.fetchInner(key, false) as Promise<ArrayBuffer>;\n  }\n\n  /**\n   * Fetch the string blob for the given key\n   */\n  fetchString(key: string): Promise<string> {\n    return this.fetchInner(key, true) as Promise<string>;\n  }\n\n  private storeInner(key: string, value: ArrayBuffer | string, ttlSeconds?: number, weight?: number): Promise<void> {\n    return new Promise<void>((resolve, reject) => {\n      this.native.store(\n        key,\n        value,\n        ttlSeconds,\n        weight,\n        makeSingleCallInterruptibleCallback(err => {\n          if (err) {\n            reject(toError(err));\n          } else {\n            resolve();\n          }\n        }),\n      );\n    });\n  }\n\n  private fetchInner(key: string, asString: boolean): Promise<ArrayBuffer | string> {\n    return new Promise((resolve, reject) => {\n      this.native.fetch(\n        key,\n        makeSingleCallInterruptibleCallback((value, err) => {\n          if (value !== undefined) {\n            resolve(value);\n          } else {\n            reject(toError(err));\n          }\n        }),\n        asString,\n      );\n    });\n  }\n\n  /**\n   * Test whether a blob for the given key exists\n   */\n  exists(key: string): Promise<boolean> {\n    return new Promise<boolean>(resolve => {\n      this.native.exists(\n        key,\n        makeSingleCallInterruptibleCallback(value => {\n          resolve(value);\n        }),\n      );\n    });\n  }\n\n  /**\n   * Remove the blob for the given key\n   */\n  remove(key: string): Promise<void> {\n    return new Promise<void>((resolve, reject) => {\n      this.native.remove(\n        key,\n        makeSingleCallInterruptibleCallback(err => {\n          if (!err) {\n            resolve();\n          } else {\n            reject(toError(err));\n          }\n        }),\n      );\n    });\n  }\n\n  /**\n   * Remove all blobs held by this PersistentStore\n   */\n  removeAll(): Promise<void> {\n    return new Promise<void>((resolve, reject) => {\n      this.native.removeAll(\n        makeSingleCallInterruptibleCallback(err => {\n          if (!err) {\n            resolve();\n          } else {\n            reject(toError(err));\n          }\n        }),\n      );\n    });\n  }\n\n  /**\n   * Fetch all the items as a PropertyList.\n   */\n  fetchAll(): Promise<PropertyList> {\n    return new Promise<PropertyList>(resolve => {\n      this.native.fetchAll(makeSingleCallInterruptibleCallback(resolve));\n    });\n  }\n}\n\n// A helper function to create a PersistentStore.\n// This is useful for testing purposes.\nexport const createPersistentStoreUtil = {\n  createStore: (name: string, options?: PersistentStoreOptions): PersistentStore => {\n    return new PersistentStore(name, options);\n  },\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/persistence/src/PersistentStoreNative.d.ts",
    "content": "import { PropertyList } from \"valdi_core/src/utils/PropertyList\";\n\nexport interface PersistentStoreNative {\n  store(\n    key: string,\n    value: ArrayBuffer | string,\n    ttlSeconds: number | undefined,\n    weight: number | undefined,\n    completion: (error?: string) => void,\n  ): void;\n  fetch(key: string, completion: (value?: ArrayBuffer | string, error?: string) => void, asString: boolean): void;\n  fetchAll(completion: (value: PropertyList) => void): void;\n  exists(key: string, completion: (exists: boolean) => void): void;\n  remove(key: string, completion: (error?: string) => void): void;\n  removeAll(completion: (error?: string) => void): void;\n  setCurrentTime(timeSeconds: number): void;\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/persistence/test/PersistentStoreTest.ts",
    "content": "import { arrayToString, stringToArray } from 'coreutils/src/Uint8ArrayUtils';\nimport 'jasmine/src/jasmine';\nimport { PersistentStore } from 'persistence/src/PersistentStore';\n\nfunction setPersistentStoreCurrentTime(store: PersistentStore, timeSeconds: number) {\n  // Not exposing this through TypeScript to ensure it is not used outside of tests\n  (store as any).native.setCurrentTime(timeSeconds);\n}\n\nfunction bufferToString(buf: ArrayBuffer): string {\n  return arrayToString(new Uint8Array(buf));\n}\n\nfunction stringToBuffer(str: string): ArrayBuffer {\n  return stringToArray(str).buffer;\n}\n\nlet persistentStoreIndex = 0;\nfunction makePersistentStoreId(encrypted: boolean): string {\n  const index = persistentStoreIndex++;\n  return `'com.snap.valdi${encrypted ? '.encrypted.' : '.'}PersistentStoreTest_${index}'`;\n}\n\ndescribe('PersistentStore', () => {\n  it('canStoreAndRetrieve', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    const buffer = new ArrayBuffer(8);\n    const view = new Uint32Array(buffer);\n    view[0] = 42;\n    view[1] = 84;\n    await store.store('someBlob', buffer);\n\n    const buffer2 = new ArrayBuffer(8);\n    const view2 = new Uint32Array(buffer2);\n    view2[0] = 1337;\n    view2[1] = 7331;\n    await store.store('someBlob2', buffer2);\n\n    const blob = await store.fetch('someBlob');\n\n    const fetchedView = new Uint32Array(blob);\n    expect(fetchedView[0]).toBe(42);\n    expect(fetchedView[1]).toBe(84);\n\n    const blob2 = await store.fetch('someBlob2');\n\n    const fetchedView2 = new Uint32Array(blob2);\n    expect(fetchedView2[0]).toBe(1337);\n    expect(fetchedView2[1]).toBe(7331);\n  });\n\n  it('failsOnUnknownKeys', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    await expectAsync(store.fetch('badKey')).toBeRejected();\n  });\n\n  it('canReplaceEntries', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    const buffer = new ArrayBuffer(8);\n    const view = new Uint32Array(buffer);\n    view[0] = 42;\n    view[1] = 84;\n    await store.store('someBlob', buffer);\n\n    const blob = await store.fetch('someBlob');\n\n    const fetchedView = new Uint32Array(blob);\n    expect(fetchedView[0]).toBe(42);\n    expect(fetchedView[1]).toBe(84);\n\n    const buffer2 = new ArrayBuffer(8);\n    const view2 = new Uint32Array(buffer2);\n    view2[0] = 1337;\n    view2[1] = 7331;\n    await store.store('someBlob', buffer2);\n\n    const blob2 = await store.fetch('someBlob');\n\n    const fetchedView2 = new Uint32Array(blob2);\n    expect(fetchedView2[0]).toBe(1337);\n    expect(fetchedView2[1]).toBe(7331);\n  });\n\n  it('persistAcrossSessions', async () => {\n    const storeID = makePersistentStoreId(false);\n    const store1 = new PersistentStore(storeID, {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    const buffer = new ArrayBuffer(8);\n    const view = new Uint32Array(buffer);\n    view[0] = 42;\n    view[1] = 84;\n    await store1.store('someBlob', buffer);\n\n    const store2 = new PersistentStore(storeID, {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    const blob = await store2.fetch('someBlob');\n\n    const fetchedView = new Uint32Array(blob);\n    expect(fetchedView[0]).toBe(42);\n    expect(fetchedView[1]).toBe(84);\n  });\n\n  it('nameIsolateEntries', async () => {\n    const storeID = makePersistentStoreId(false);\n    const store1 = new PersistentStore(storeID, {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    const buffer = new ArrayBuffer(8);\n    const view = new Uint32Array(buffer);\n    view[0] = 42;\n    view[1] = 84;\n    await store1.store('someBlob', buffer);\n\n    const store2 = new PersistentStore(makePersistentStoreId(false), {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    await expectAsync(store2.fetch('someBlob')).toBeRejected();\n  });\n\n  it('canDelete', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    const buffer = new ArrayBuffer(8);\n    const view = new Uint32Array(buffer);\n    view[0] = 42;\n    view[1] = 84;\n    await store.store('someBlob', buffer);\n\n    // Should succeeed\n    await store.fetch('someBlob');\n\n    await store.remove('someBlob');\n\n    // this should fail\n    await expectAsync(store.fetch('someBlob')).toBeRejected();\n  });\n\n  it('canDeleteAll', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), {\n      disableBatchWrites: true,\n      deviceGlobal: true,\n    });\n\n    const buffer = new ArrayBuffer(8);\n    const view = new Uint32Array(buffer);\n    view[0] = 42;\n    view[1] = 84;\n    await store.store('someBlob', buffer);\n\n    const buffer2 = new ArrayBuffer(8);\n    const view2 = new Uint32Array(buffer2);\n    view2[0] = 1337;\n    view2[1] = 7331;\n    await store.store('someBlob2', buffer);\n\n    await store.removeAll();\n\n    await expectAsync(store.fetch('someBlob')).toBeRejected();\n    await expectAsync(store.fetch('someBlob2')).toBeRejected();\n  });\n\n  it('canStoreAndFetchWithBatchEnabled', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), { deviceGlobal: true });\n\n    const buffer = new ArrayBuffer(8);\n    const view = new Uint32Array(buffer);\n    view[0] = 42;\n    view[1] = 84;\n    const promise1 = store.store('someBlob', buffer);\n\n    const buffer2 = new ArrayBuffer(8);\n    const view2 = new Uint32Array(buffer2);\n    view2[0] = 1337;\n    view2[1] = 7331;\n    const promise2 = store.store('someBlob2', buffer2);\n\n    await promise1;\n    await promise2;\n\n    const blob = await store.fetch('someBlob');\n\n    const fetchedView = new Uint32Array(blob);\n    expect(fetchedView[0]).toBe(42);\n    expect(fetchedView[1]).toBe(84);\n\n    const blob2 = await store.fetch('someBlob2');\n\n    const fetchedView2 = new Uint32Array(blob2);\n    expect(fetchedView2[0]).toBe(1337);\n    expect(fetchedView2[1]).toBe(7331);\n  });\n\n  it('respects ttl when instance is alive', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), { deviceGlobal: true });\n    setPersistentStoreCurrentTime(store, 1);\n\n    const buffer = new ArrayBuffer(8);\n\n    await store.store('item', buffer, 1);\n    await store.store('item2', buffer, 2);\n\n    // We can fetch when it's still valid\n    await store.fetch('item');\n    await store.fetch('item2');\n\n    // advance by 1 second\n    setPersistentStoreCurrentTime(store, 2);\n\n    // This should still work, since it's not expired\n    await store.fetch('item2');\n\n    await expectAsync(store.fetch('item')).toBeRejected();\n  });\n\n  it('respects ttl when restoring instance', async () => {\n    const storeID = makePersistentStoreId(false);\n    let store = new PersistentStore(storeID, {\n      mockedTime: 1,\n      deviceGlobal: true,\n    } as any);\n\n    const buffer = new ArrayBuffer(8);\n    await store.store('item', buffer, 2);\n    await store.store('item2', buffer, 3);\n\n    store = new PersistentStore(storeID, { mockedTime: 2, deviceGlobal: true } as any);\n\n    // Should still work as the item has not expired\n    await store.fetch('item');\n    await store.fetch('item2');\n\n    store = new PersistentStore(storeID, { mockedTime: 3, deviceGlobal: true } as any);\n\n    await store.fetch('item2');\n\n    await expectAsync(store.fetch('item')).toBeRejected();\n  });\n\n  it('can restore encrypted', async () => {\n    const storeID = makePersistentStoreId(true);\n    let store = new PersistentStore(storeID, {\n      mockedUserId: '424242',\n    } as any);\n\n    const buffer = stringToBuffer('Hello world');\n\n    await store.store('item', buffer);\n\n    store = new PersistentStore(storeID, {\n      mockedUserId: '424242',\n    } as any);\n\n    const fetchedResult = await store.fetch('item');\n    const strResult = bufferToString(fetchedResult);\n\n    expect(strResult).toEqual('Hello world');\n  });\n\n  it('fails to restore encrypted if user id changes', async () => {\n    const storeID = makePersistentStoreId(true);\n    let store = new PersistentStore(storeID, {\n      mockedUserId: '424242',\n    } as any);\n\n    const buffer = stringToBuffer('Hello world');\n\n    await store.store('item', buffer);\n\n    store = new PersistentStore(storeID, {\n      mockedUserId: '434343',\n    } as any);\n\n    await expectAsync(store.fetch('item')).toBeRejected();\n  });\n\n  it('can fetchAll', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), {\n      deviceGlobal: true,\n    });\n\n    await store.removeAll();\n\n    const data1 = stringToBuffer('test1');\n    const data2 = stringToBuffer('test2');\n    const data3 = stringToBuffer('test3');\n\n    await store.store('item1', data1);\n    await store.store('item2', data2);\n    await store.store('item3', data3);\n\n    const items = await store.fetchAll();\n\n    expect(items).toEqual(['item1', data1, 'item2', data2, 'item3', data3]);\n  });\n\n  it('can use weight', async () => {\n    const store = new PersistentStore(makePersistentStoreId(false), {\n      deviceGlobal: true,\n      maxWeight: 2,\n    });\n\n    await store.removeAll();\n\n    const data1 = stringToBuffer('test1');\n    const data2 = stringToBuffer('test2');\n    const data3 = stringToBuffer('test3');\n\n    await store.store('item1', data1, undefined, 1);\n    await store.store('item2', data2, undefined, 1);\n    await store.store('item3', data3, undefined, 1);\n\n    const items = await store.fetchAll();\n\n    expect(items).toEqual(['item2', data2, 'item3', data3]);\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/persistence/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\",\n    \"compilerOptions\": {\n        \"noImplicitReturns\": true,\n        \"noImplicitAny\": true,\n        \"strict\": true\n    }\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/persistence/web/PersistentStoreNative.ts",
    "content": "import { PropertyList } from 'valdi_tsx/src/PropertyList';\nimport { PersistentStoreNative } from '../src/PersistentStoreNative';\n\nconst enc = new TextEncoder();\nconst dec = new TextDecoder();\n\nconst microtask = (fn: () => void) => { void Promise.resolve().then(fn); };\n\ntype Entry = {\n  value: ArrayBuffer | string;\n  weight?: number;\n  /** epoch seconds at which this entry expires (exclusive). undefined = no expiry */\n  expiresAt?: number;\n};\n\nconst storeMap = new Map<string, Entry>();\nlet nowOverrideSec: number | undefined;\n\nconst nowSec = () => (nowOverrideSec ?? Math.floor(Date.now() / 1000));\nconst cloneBuf = (b: ArrayBuffer) => b.slice(0);\nconst toBuf = (s: string) => enc.encode(s).buffer;\nconst toStr = (b: ArrayBuffer) => dec.decode(new Uint8Array(b));\n\nconst isExpired = (e: Entry) => e.expiresAt !== undefined && nowSec() >= e.expiresAt;\nconst sweepIfExpired = (k: string) => {\n  const e = storeMap.get(k);\n  if (e && isExpired(e)) storeMap.delete(k);\n};\n\n/* ---------- implementation ---------- */\n\nconst impl: PersistentStoreNative = {\n  store(key, value, ttlSeconds, weight, completion) {\n    microtask(() => {\n      try {\n        const entry: Entry = {\n          value: typeof value === \"string\" ? value : cloneBuf(value),\n          weight,\n          expiresAt:\n            ttlSeconds === undefined ? undefined :\n            ttlSeconds <= 0 ? nowSec() : nowSec() + Math.floor(ttlSeconds),\n        };\n        storeMap.set(key, entry);\n        completion(); // success\n      } catch (e: any) {\n        completion(String(e?.message ?? e ?? \"store failed\"));\n      }\n    });\n  },\n\n  fetch(key, completion, asString) {\n    microtask(() => {\n      sweepIfExpired(key);\n      const e = storeMap.get(key);\n      if (!e) {\n        completion(undefined, \"not found\");\n        return;\n      }\n      let v: ArrayBuffer | string = e.value;\n\n      // honor asString flag by converting if needed\n      if (asString && v instanceof ArrayBuffer) {\n        v = toStr(v);\n      } else if (!asString && typeof v === \"string\") {\n        v = toBuf(v);\n      }\n\n      completion(v, undefined);\n    });\n  },\n\n  fetchAll(completion) {\n    microtask(() => {\n      // collect keys first (no for..of, no Array.from)\n      const keys: string[] = [];\n      storeMap.forEach((_e, k) => keys.push(k));\n      for (let i = 0; i < keys.length; i++) {\n        sweepIfExpired(keys[i]);\n      }\n\n      const out: PropertyList = {};\n      // safe iteration without for..of\n      storeMap.forEach((e, k) => {\n        out[k] = e.value;\n      });\n      completion(out);\n    });\n  },\n\n  // inside setCurrentTime(...), replace the sweep loop with:\n  setCurrentTime(timeSeconds) {\n    nowOverrideSec = Math.floor(timeSeconds);\n    const keys: string[] = [];\n    storeMap.forEach((_e, k) => keys.push(k));\n    for (let i = 0; i < keys.length; i++) {\n      sweepIfExpired(keys[i]);\n    }\n  },\n\n  exists(key, completion) {\n    microtask(() => {\n      sweepIfExpired(key);\n      completion(storeMap.has(key));\n    });\n  },\n\n  remove(key, completion) {\n    microtask(() => {\n      try {\n        storeMap.delete(key);\n        completion();\n      } catch (e: any) {\n        completion(String(e?.message ?? e ?? \"remove failed\"));\n      }\n    });\n  },\n\n  removeAll(completion) {\n    microtask(() => {\n      try {\n        storeMap.clear();\n        completion();\n      } catch (e: any) {\n        completion(String(e?.message ?? e ?? \"removeAll failed\"));\n      }\n    });\n  },\n\n};\n\n/** Exported instance + setter so you can swap in a real native binding later. */\nexport let persistentStoreNative: PersistentStoreNative = impl;\nexport function setPersistentStoreNative(newImpl: PersistentStoreNative): void {\n  persistentStoreNative = newImpl;\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/persistence/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n     \"lib\": [\"DOM\", \"ES2020\"],\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": true,\n    \"allowJs\": true\n  },\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nvaldi_module(\n    name = \"source_map\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCSourceMap\",\n    ios_output_target = \"release\",\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"//src/valdi_modules/src/valdi/coreutils\",\n        \"//src/valdi_modules/src/valdi/jasmine\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/module.yaml",
    "content": "output_target: release\ndisable_code_coverage: true\n\ndependencies:\n  - coreutils\n  - jasmine\n\nallowed_debug_dependencies:\n  - jasmine\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/src/ISourceMap.d.ts",
    "content": "export interface MappedPosition {\n  fileName: string | undefined;\n  name: string | undefined;\n  line: number;\n  column: number;\n}\n\nexport interface ISourceMap {\n  resolve(line: number, column: number | undefined, name: string | undefined): MappedPosition | undefined;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/src/SourceMap.ts",
    "content": "import { binarySearch } from 'coreutils/src/ArrayUtils';\nimport { Base64 } from 'coreutils/src/Base64';\nimport { arrayToString } from 'coreutils/src/Uint8ArrayUtils';\nimport { ISourceMap, MappedPosition } from './ISourceMap';\nimport { decode } from './VLQ';\n\nexport interface SourceMapJson {\n  version?: number;\n  file?: string;\n  sourceRoot?: string;\n  sources?: string[];\n  names?: string[];\n  mappings?: string;\n  sourcesContent?: string[];\n}\n\nexport interface MappedLineEntry {\n  /**\n   * The zero-based column number in the generated code that corresponds to this mapping segment.\n   */\n  generatedColumnNumber: number;\n\n  /**\n   * The zero-based column number of the next mapped line entry\n   */\n  nextGeneratedColumnNumber: number | undefined;\n\n  /**\n   * The zero-based line number in the source code that corresponds to this mapping segment.\n   */\n  originalLineNumber: number;\n\n  /**\n   * The zero-based line number in the source code that corresponds to this mapping segment.\n   */\n  originalColumnNumber: number;\n\n  /**\n   * The original name of the code referenced by this mapping entry\n   */\n  originalName: string | undefined;\n\n  /**\n   * The name of the file that originally contained this code\n   */\n  originalFileName: string | undefined;\n}\n\nexport interface MappedLine {\n  entries: MappedLineEntry[];\n}\n\nexport class SourceMap implements ISourceMap {\n  lineOffset: number;\n\n  constructor(\n    readonly file: string | undefined,\n    readonly sourceRoot: string | undefined,\n    readonly sources: string[] | undefined,\n    readonly names: string[] | undefined,\n    readonly lines: MappedLine[],\n    readonly sourcesContent: string[] | undefined,\n    lineOffset: number = 1,\n  ) {\n    this.lineOffset = lineOffset;\n  }\n\n  resolve(line: number, column: number | undefined, name: string | undefined): MappedPosition | undefined {\n    const lineZeroIndexed = line - this.lineOffset;\n    if (lineZeroIndexed >= this.lines.length || lineZeroIndexed < 0) {\n      return undefined;\n    }\n\n    const mappedLine = this.lines[lineZeroIndexed];\n\n    let entryIndex = -1;\n    let columnOffset = 0;\n\n    if (typeof column === 'number') {\n      const columnZeroIndexed = column - 1;\n\n      entryIndex = binarySearch(mappedLine.entries, item => {\n        if (item.generatedColumnNumber > columnZeroIndexed) {\n          return 1;\n        } else if (item.generatedColumnNumber < columnZeroIndexed) {\n          if (!item.nextGeneratedColumnNumber || item.nextGeneratedColumnNumber > columnZeroIndexed) {\n            // We are within the range\n            return 0;\n          }\n\n          return -1;\n        }\n        return 0;\n      });\n\n      if (entryIndex >= 0) {\n        columnOffset = columnZeroIndexed - mappedLine.entries[entryIndex].generatedColumnNumber;\n      }\n    } else if (mappedLine.entries.length) {\n      entryIndex = 0;\n    }\n\n    if (entryIndex < 0) {\n      return undefined;\n    }\n\n    const entry = mappedLine.entries[entryIndex];\n\n    return {\n      fileName: entry.originalFileName,\n      line: entry.originalLineNumber + 1,\n      column: entry.originalColumnNumber + columnOffset + 1,\n      name: entry.originalName ?? name,\n    };\n  }\n\n  static parseFromBase64(base64String: string) {\n    const byteArray = Base64.toByteArray(base64String);\n    const jsonString = arrayToString(byteArray);\n    return SourceMap.parse(jsonString);\n  }\n\n  static parse(sourceMapJson: string): SourceMap {\n    const object = JSON.parse(sourceMapJson) as SourceMapJson;\n    if (object.version !== 3) {\n      throw new Error('SourceMap version must be 3');\n    }\n\n    if (!object.mappings) {\n      throw new Error('Missing mappings');\n    }\n\n    let sources = object.sources ?? [];\n    const names = object.names ?? [];\n\n    sources = sources.map(source => {\n      // Remove leading '/'\n      if (source.charAt(0) === '/') {\n        source = source.substr(1);\n      }\n\n      return source;\n    });\n\n    /**\n      Logic ported from https://github.com/microsoft/sourcemap-toolkit/blob/master/src/SourcemapToolkit.SourcemapParser/MappingListParser.cs\n       */\n\n    const lines: MappedLine[] = [];\n    const allMappings = object.mappings.split(';');\n\n    let generatedLineNumber = 0;\n    let generatedColumnNumber = 0;\n    let sourcesListIndex = 0;\n    let originalLineNumber = 0;\n    let originalColumnNumber = 0;\n    let namesListIndex = 0;\n\n    for (const mappings of allMappings) {\n      const segments = mappings.split(',');\n      const entries: MappedLineEntry[] = [];\n\n      for (const segment of segments) {\n        if (!segment) {\n          continue;\n        }\n\n        const fields = decode(segment);\n\n        if (fields.length !== 1 && fields.length !== 4 && fields.length !== 5) {\n          throw new Error(`Invalid mappings (found ${fields.length} fields in ${segment})`);\n        }\n\n        generatedColumnNumber += fields[0];\n\n        let originalFileName: string | undefined;\n\n        if (fields.length > 1) {\n          sourcesListIndex += fields[1];\n          originalLineNumber += fields[2];\n          originalColumnNumber += fields[3];\n\n          if (sourcesListIndex >= sources.length) {\n            throw new Error(`Out of bounds sources index ${sourcesListIndex}`);\n          }\n\n          originalFileName = sources[sourcesListIndex];\n        }\n\n        let originalName: string | undefined;\n\n        if (fields.length === 5) {\n          namesListIndex += fields[4];\n\n          if (namesListIndex >= names.length) {\n            throw new Error(`Out of bounds names index ${namesListIndex}`);\n          }\n          originalName = names[namesListIndex];\n        }\n\n        if (entries.length) {\n          entries[entries.length - 1].nextGeneratedColumnNumber = generatedColumnNumber;\n        }\n\n        entries.push({\n          generatedColumnNumber,\n          nextGeneratedColumnNumber: undefined,\n          originalColumnNumber,\n          originalLineNumber,\n          originalFileName,\n          originalName,\n        });\n      }\n\n      lines.push({ entries });\n\n      generatedLineNumber++;\n      generatedColumnNumber = 0;\n    }\n\n    return new SourceMap(object.file, object.sourceRoot, object.sources, object.names, lines, object.sourcesContent);\n  }\n}\n\nexport class LineOffsetSourceMap implements ISourceMap {\n  private readonly lineOffset: number;\n  constructor(lineOffset: number) {\n    this.lineOffset = lineOffset;\n  }\n  resolve(line: number, column: number | undefined, name: string | undefined): MappedPosition | undefined {\n    const adjustedLine = line - this.lineOffset;\n    if (adjustedLine < 0) {\n      return undefined; // If the adjusted line is negative, return undefined\n    }\n    return {\n      fileName: undefined,\n      line: adjustedLine,\n      column: column ?? 0,\n      name: undefined,\n    };\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/src/StackSymbolicator.ts",
    "content": "import { ISourceMap } from './ISourceMap';\nimport { SourceMap, LineOffsetSourceMap } from './SourceMap';\n\nexport type GetOrCreateSourceMapFunc = (\n  path: string,\n  sourceMapFactory: (\n    sourceMapContent: string | undefined,\n    sourceMapLineOffset: number | undefined,\n  ) => ISourceMap | undefined,\n) => ISourceMap | undefined;\n\nexport interface StackFrame {\n  name?: string;\n  fileName: string;\n  column?: number;\n  line?: number;\n}\n\nfunction parseJSCoreStackFrame(line: string): StackFrame {\n  let name: string | undefined;\n  let fileAndPosition: string;\n\n  const components = line.split('@');\n\n  if (components.length === 2) {\n    name = components[0];\n    fileAndPosition = components[1];\n  } else {\n    fileAndPosition = components[0];\n  }\n\n  const fileAndPositionSplit = fileAndPosition.split(':');\n  const fileName = fileAndPositionSplit[0].replace(' ', '_');\n\n  let columNumber: number | undefined;\n  let lineNumber: number | undefined;\n\n  if (fileAndPositionSplit.length > 1) {\n    lineNumber = Number.parseInt(fileAndPositionSplit[1]);\n  }\n  if (fileAndPositionSplit.length > 2) {\n    columNumber = Number.parseInt(fileAndPositionSplit[2]);\n  }\n\n  return {\n    name,\n    fileName,\n    line: lineNumber,\n    column: columNumber,\n  };\n}\n\nfunction parseQuickJSStackFrame(line: string): StackFrame {\n  const components = line.split(' ');\n  if (components.length !== 3) {\n    throw new Error('Invalid stack frame');\n  }\n\n  const name = components[1];\n  let file = components[2];\n  // Remove opening and trailing paren\n  file = file.substr(1, file.length - 2);\n\n  const fileAndLine = file.split(':');\n  const fileName = fileAndLine[0];\n\n  let lineNumber: number | undefined;\n  if (fileAndLine.length > 1) {\n    lineNumber = Number.parseInt(fileAndLine[1]);\n  }\n\n  let columnNumber: number | undefined;\n  if (fileAndLine.length > 2) {\n    columnNumber = Number.parseInt(fileAndLine[2]);\n  }\n\n  return {\n    name,\n    fileName,\n    line: lineNumber,\n    column: columnNumber,\n  };\n}\n\nexport function parseStackFrames(stack: string): StackFrame[] {\n  const frames: StackFrame[] = [];\n\n  const lines = stack.split('\\n');\n\n  for (let line of lines) {\n    line = line.trim();\n    if (!line) {\n      continue;\n    }\n\n    try {\n      if (line.startsWith('at ')) {\n        frames.push(parseQuickJSStackFrame(line));\n      } else {\n        frames.push(parseJSCoreStackFrame(line));\n      }\n    } catch (err: any) {\n      frames.push({\n        name: line,\n        fileName: `failed to symbolicate: ${err.message}`,\n      });\n    }\n  }\n\n  return frames;\n}\n\nfunction createSourceMap(\n  sourceMapContent: string | undefined,\n  sourceMapLineOffset: number | undefined,\n): ISourceMap | undefined {\n  if (!sourceMapContent) {\n    return sourceMapLineOffset !== undefined ? new LineOffsetSourceMap(sourceMapLineOffset) : undefined;\n  }\n\n  const sourceMap = SourceMap.parse(sourceMapContent);\n\n  if (sourceMapLineOffset) {\n    sourceMap.lineOffset += sourceMapLineOffset;\n  }\n\n  return sourceMap;\n}\n\nfunction symbolicateStackFrame(stackFrame: StackFrame, getOrCreateSourceMapFunc: GetOrCreateSourceMapFunc): StackFrame {\n  if (\n    !stackFrame.line ||\n    stackFrame.fileName.startsWith('<') ||\n    stackFrame.fileName.endsWith('.ts') ||\n    stackFrame.fileName.endsWith('.tsx')\n  ) {\n    return stackFrame;\n  }\n\n  const sourceMap = getOrCreateSourceMapFunc(stackFrame.fileName, createSourceMap);\n  if (!sourceMap) {\n    return stackFrame;\n  }\n\n  const resolved = sourceMap.resolve(stackFrame.line, stackFrame.column, stackFrame.name);\n  if (!resolved) {\n    return stackFrame;\n  }\n\n  const fileName = resolved.fileName ?? stackFrame.fileName;\n  const name = resolved.name ?? stackFrame.name;\n\n  return { fileName, name, line: resolved.line, column: resolved.column };\n}\n\nexport function symbolicateStackFrames(\n  stackFrames: StackFrame[],\n  getOrCreateSourceMapFunc: GetOrCreateSourceMapFunc,\n): StackFrame[] {\n  const out: StackFrame[] = [];\n\n  for (const stackFrame of stackFrames) {\n    out.push(symbolicateStackFrame(stackFrame, getOrCreateSourceMapFunc));\n  }\n\n  return out;\n}\n\nexport function symbolicateStack(stack: string, getOrCreateSourceMapFunc: GetOrCreateSourceMapFunc): string {\n  try {\n    let stackFrames = parseStackFrames(stack);\n    stackFrames = symbolicateStackFrames(stackFrames, getOrCreateSourceMapFunc);\n\n    let newStack = '';\n    for (const stackFrame of stackFrames) {\n      let name = stackFrame.name;\n      if (!name) {\n        name = '<anonymous>';\n      }\n\n      newStack += `    at ${name} (${stackFrame.fileName}`;\n      if (stackFrame.line) {\n        newStack += ':' + stackFrame.line.toString();\n        if (stackFrame.column) {\n          newStack += ':' + stackFrame.column.toString();\n        }\n      }\n\n      newStack += ')\\n';\n    }\n\n    return newStack;\n  } catch (err: any) {\n    console.error('Failed to process stack frames:', err.message, err.stack);\n    return stack;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/src/VLQ.ts",
    "content": "/**\n * Taken from Rich-Harris/vlq\n * https://github.com/Rich-Harris/vlq/blob/7a38a6c3ee616db2c9708cfd20b4cd5d398a9fd3/src/vlq.ts\n */\n\nconst charToInteger: { [char: string]: number } = {};\nconst integerToChar: { [integer: number]: string } = {};\n\n'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split('').forEach(function (char, i) {\n  charToInteger[char] = i;\n  integerToChar[i] = char;\n});\n\nexport function decode(string: string): number[] {\n  const result: number[] = [];\n  let shift = 0;\n  let value = 0;\n\n  for (let i = 0; i < string.length; i += 1) {\n    let integer = charToInteger[string[i]];\n\n    if (integer === undefined) {\n      throw new Error('Invalid character (' + string[i] + ')');\n    }\n\n    const hasContinuationBit = integer & 32;\n\n    integer &= 31;\n    value += integer << shift;\n\n    if (hasContinuationBit) {\n      shift += 5;\n    } else {\n      const shouldNegate = value & 1;\n      value >>>= 1;\n\n      if (shouldNegate) {\n        result.push(value === 0 ? -0x80000000 : -value);\n      } else {\n        result.push(value);\n      }\n\n      // reset\n      value = shift = 0;\n    }\n  }\n\n  return result;\n}\n\nexport function encode(value: number | number[]): string {\n  let result: string;\n\n  if (typeof value === 'number') {\n    result = encodeInteger(value);\n  } else {\n    result = '';\n    for (let i = 0; i < value.length; i += 1) {\n      result += encodeInteger(value[i]);\n    }\n  }\n\n  return result;\n}\n\nfunction encodeInteger(num: number): string {\n  let result = '';\n\n  if (num < 0) {\n    num = (-num << 1) | 1;\n  } else {\n    num <<= 1;\n  }\n\n  do {\n    let clamped = num & 31;\n    num >>>= 5;\n\n    if (num > 0) {\n      clamped |= 32;\n    }\n\n    result += integerToChar[clamped];\n  } while (num > 0);\n\n  return result;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/test/SourceMap.spec.ts",
    "content": "import 'jasmine/src/jasmine';\nimport { SourceMap } from 'source_map/src/SourceMap';\nimport { GetOrCreateSourceMapFunc, parseStackFrames, symbolicateStackFrames } from 'source_map/src/StackSymbolicator';\nimport { LineOffsetSourceMap } from '../src/SourceMap';\n\nconst sourceMapContent = `eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU291cmNlTWFwRXhhbXBsZS5qcyIsInNvdXJjZVJvb3QiOiIvIiwic291cmNlcyI6WyJzb3VyY2VfbWFwL3Rlc3QvU291cmNlTWFwRXhhbXBsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFRQSxTQUFnQixXQUFXLENBQUMsS0FBVTtJQUNwQyxPQUFPLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztBQUNsQyxDQUFDO0FBRkQsa0NBRUMifQ==`;\n\ndescribe('SourceMap', () => {\n  it('can be parsed', () => {\n    const sourceMap = SourceMap.parseFromBase64(sourceMapContent);\n\n    expect(sourceMap.file).toBe('SourceMapExample.js');\n    expect(sourceMap.sourceRoot).toBe('/');\n    expect(sourceMap.sources).toEqual(['source_map/test/SourceMapExample.ts']);\n\n    expect(sourceMap.lines.length).toBe(7);\n  });\n\n  it('can resolve original position', () => {\n    const sourceMap = SourceMap.parseFromBase64(sourceMapContent);\n\n    let position = sourceMap.resolve(5, 12, undefined)!;\n    expect(position).toBeTruthy();\n    expect(position.line).toBe(10);\n    expect(position.column).toBe(10);\n\n    position = sourceMap.resolve(5, 25, undefined)!;\n    expect(position).toBeTruthy();\n    expect(position.line).toBe(10);\n    expect(position.column).toBe(23);\n    expect(position.fileName).toBe('source_map/test/SourceMapExample.ts');\n  });\n\n  it('can resolve original position with offset', () => {\n    const sourceMap = SourceMap.parseFromBase64(sourceMapContent);\n\n    const position = sourceMap.resolve(5, 14, undefined)!;\n    expect(position).toBeTruthy();\n    expect(position.line).toBe(10);\n    expect(position.column).toBe(12);\n  });\n\n  it('Test LineOffsetSourceMap', () => {\n    const sourceMap = new LineOffsetSourceMap(5);\n    let position = sourceMap.resolve(10, 0, undefined)!;\n    expect(position).toBeTruthy();\n    expect(position.line).toBe(5);\n    expect(position.column).toBe(0);\n\n    position = sourceMap.resolve(420, 69, undefined)!;\n    expect(position).toBeTruthy();\n    expect(position.line).toBe(415);\n    expect(position.column).toBe(69);\n\n    position = sourceMap.resolve(420, undefined, undefined)!;\n    expect(position).toBeTruthy();\n    expect(position.line).toBe(415);\n    expect(position.column).toBe(0);\n\n    position = sourceMap.resolve(1, 0, undefined)!;\n    expect(position).toBeFalsy();\n  });\n});\n\nfunction makeGetOrCreateSourceMapFunc(sourceMaps: { [key: string]: SourceMap | undefined }): GetOrCreateSourceMapFunc {\n  return (file: string) => {\n    return sourceMaps[file];\n  };\n}\n\n// function makeError(): Error {\n//   let error: Error | undefined;\n//   try {\n//     doSomething(undefined);\n//   } catch (err: any) {\n//     error = err;\n//   }\n\n//   if (!error) {\n//     throw new Error('Error not thrown');\n//   }\n\n//   injectSourceMap();\n\n//   return error;\n// }\n\ndescribe('Symbolicator', () => {\n  it('can parse QuickJS stackframes', () => {\n    const stack = `\n    at doSomething (source_map/test/SourceMapExample:6)\n    at makeError (source_map/test/SourceMap.spec:31)\n    at call (native)\n    at <anonymous> (jasmine/src/jasmine:6423)\n    `;\n\n    const stackFrames = parseStackFrames(stack);\n    expect(stackFrames).toEqual([\n      { line: 6, column: undefined, name: 'doSomething', fileName: 'source_map/test/SourceMapExample' },\n      { line: 31, column: undefined, name: 'makeError', fileName: 'source_map/test/SourceMap.spec' },\n      { line: undefined, column: undefined, name: 'call', fileName: 'native' },\n      { line: 6423, column: undefined, name: '<anonymous>', fileName: 'jasmine/src/jasmine' },\n    ]);\n  });\n\n  it('can parse JSCore stackframes', () => {\n    const stack = `\n    doSomething@source_map/test/SourceMapExample:6:12\n    makeError@source_map/test/SourceMap.spec:31\n    [native code]\n    jasmine/src/jasmine:6423\n    `;\n\n    const stackFrames = parseStackFrames(stack);\n    expect(stackFrames).toEqual([\n      { line: 6, column: 12, name: 'doSomething', fileName: 'source_map/test/SourceMapExample' },\n      { line: 31, column: undefined, name: 'makeError', fileName: 'source_map/test/SourceMap.spec' },\n      { line: undefined, column: undefined, name: undefined, fileName: '[native_code]' },\n      { line: 6423, column: undefined, name: undefined, fileName: 'jasmine/src/jasmine' },\n    ]);\n  });\n\n  it('can symbolicate stack frames', () => {\n    const stack = `\n    at doSomething (source_map/test/SourceMapExample:5)\n    at makeError (source_map/test/SourceMap.spec:31)\n    at call (native)\n    at <anonymous> (jasmine/src/jasmine:6423)\n    `;\n\n    const stackFrames = parseStackFrames(stack);\n\n    const getOrCreateSourceMapFunc = makeGetOrCreateSourceMapFunc({\n      'source_map/test/SourceMapExample': SourceMap.parseFromBase64(sourceMapContent),\n      'source_map/test/SourceMap.spec': new SourceMap(undefined, undefined, [], [], [], []),\n    });\n\n    const symbolicatedStackFrames = symbolicateStackFrames(stackFrames, getOrCreateSourceMapFunc);\n\n    expect(symbolicatedStackFrames).toEqual([\n      { line: 10, column: 3, name: 'doSomething', fileName: 'source_map/test/SourceMapExample.ts' },\n      { line: 31, column: undefined, name: 'makeError', fileName: 'source_map/test/SourceMap.spec' },\n      { line: undefined, column: undefined, name: 'call', fileName: 'native' },\n      { line: 6423, column: undefined, name: '<anonymous>', fileName: 'jasmine/src/jasmine' },\n    ]);\n  });\n\n  // Disabling this test for now as it doesn't currently work with QuickJS and minification on.\n  // QuickJS doesn't provide the column number on thrown exceptions which prevents to resolve\n  // the symbols on minified files since those files are all laid out on a single line.\n  // it('can symbolicate errors', () => {\n  //   const error = makeError();\n\n  //   expect(error.stack).not.toContain('source_map/test/SourceMapExample.ts:10:3');\n\n  //   const symbolicatedStack = symbolicateStack(error!.stack!);\n\n  //   expect(symbolicatedStack).toContain('source_map/test/SourceMapExample.ts:10:3');\n  // });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/test/SourceMapExample.ts",
    "content": "// Make sure to update SourceMap.spec.ts with the updated source maps definition every time\n// this file changes.\n\ninterface SomeInterface {\n  key: string;\n  value: any;\n}\n\nexport function doSomething(value: any): number {\n  return value.left * value.right;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/source_map/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\",\n    \"compilerOptions\": {\n        \"noImplicitReturns\": true,\n        \"noImplicitAny\": true,\n        \"strict\": true,\n    }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/tsconfig.json",
    "content": "{\n  // If you'd like to apply a TypeScript project configuration to all bundles,\n  // go modify \"./_configs/base.tsconfig.json\".\n  \"extends\": \"./_configs/base.tsconfig.json\",\n  \"include\": [\n    // Listing NativeTemplateElements.d.ts so that the Valdi compiler processes the annotations.\n    // We don't actually want to compile anything else under the root project.\n    \"valdi_tsx/src/NativeTemplateElements.d.ts\"\n  ]\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/types/BUILD.bazel",
    "content": "filegroup(\n    name = \"types\",\n    srcs = [\n        \"Long.d.ts\",\n        \"globals.d.ts\",\n    ],\n    visibility = [\"//visibility:public\"],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/types/Long.d.ts",
    "content": "/* eslint-disable */\n// Type definitions for long.js 4.0.0\n// Project: https://github.com/dcodeIO/long.js\n// Definitions by: Peter Kooijmans <https://github.com/peterkooijmans>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// Definitions by: Denis Cappellin <https://github.com/cappellin>\n\ndeclare global {\n  class Long {\n    /**\n     * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as signed integers. See the from* functions below for more convenient ways of constructing Longs.\n     */\n    constructor(low: number, high?: number, unsigned?: boolean);\n\n    /**\n     * Maximum unsigned value.\n     */\n    static MAX_UNSIGNED_VALUE: Long;\n\n    /**\n     * Maximum signed value.\n     */\n    static MAX_VALUE: Long;\n\n    /**\n     * Minimum signed value.\n     */\n    static MIN_VALUE: Long;\n\n    /**\n     * Signed negative one.\n     */\n    static NEG_ONE: Long;\n\n    /**\n     * Signed one.\n     */\n    static ONE: Long;\n\n    /**\n     * Unsigned one.\n     */\n    static UONE: Long;\n\n    /**\n     * Unsigned zero.\n     */\n    static UZERO: Long;\n\n    /**\n     * Signed zero\n     */\n    static ZERO: Long;\n\n    /**\n     * The high 32 bits as a signed value.\n     */\n    high: number;\n\n    /**\n     * The low 32 bits as a signed value.\n     */\n    low: number;\n\n    /**\n     * Whether unsigned or not.\n     */\n    unsigned: boolean;\n\n    /**\n     * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is assumed to use 32 bits.\n     */\n    static fromBits(lowBits: number, highBits: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representing the given 32 bit integer value.\n     */\n    static fromInt(value: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.\n     */\n    static fromNumber(value: number, unsigned?: boolean): Long;\n\n    /**\n     * Returns a Long representation of the given string, written using the specified radix.\n     */\n    static fromString(str: string, unsigned?: boolean | number, radix?: number): Long;\n\n    /**\n     * Creates a Long from its byte representation.\n     */\n    static fromBytes(bytes: number[], unsigned?: boolean, le?: boolean): Long;\n\n    /**\n     * Creates a Long from its little endian byte representation.\n     */\n    static fromBytesLE(bytes: number[], unsigned?: boolean): Long;\n\n    /**\n     * Creates a Long from its little endian byte representation.\n     */\n    static fromBytesBE(bytes: number[], unsigned?: boolean): Long;\n\n    /**\n     * Tests if the specified object is a Long.\n     */\n    static isLong(obj: any): boolean;\n\n    /**\n     * Converts the specified value to a Long.\n     */\n    static fromValue(val: Long | number | string | { low: number; high: number; unsigned: boolean }): Long;\n\n    /**\n     * Returns the sum of this and the specified Long.\n     */\n    add(addend: number | Long | string): Long;\n\n    /**\n     * Returns the bitwise AND of this Long and the specified.\n     */\n    and(other: Long | number | string): Long;\n\n    /**\n     * Compares this Long's value with the specified's.\n     */\n    compare(other: Long | number | string): number;\n\n    /**\n     * Compares this Long's value with the specified's.\n     */\n    comp(other: Long | number | string): number;\n\n    /**\n     * Returns this Long divided by the specified.\n     */\n    divide(divisor: Long | number | string): Long;\n\n    /**\n     * Returns this Long divided by the specified.\n     */\n    div(divisor: Long | number | string): Long;\n\n    /**\n     * Tests if this Long's value equals the specified's.\n     */\n    equals(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value equals the specified's.\n     */\n    eq(other: Long | number | string): boolean;\n\n    /**\n     * Gets the high 32 bits as a signed integer.\n     */\n    getHighBits(): number;\n\n    /**\n     * Gets the high 32 bits as an unsigned integer.\n     */\n    getHighBitsUnsigned(): number;\n\n    /**\n     * Gets the low 32 bits as a signed integer.\n     */\n    getLowBits(): number;\n\n    /**\n     * Gets the low 32 bits as an unsigned integer.\n     */\n    getLowBitsUnsigned(): number;\n\n    /**\n     * Gets the number of bits needed to represent the absolute value of this Long.\n     */\n    getNumBitsAbs(): number;\n\n    /**\n     * Tests if this Long's value is greater than the specified's.\n     */\n    greaterThan(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than the specified's.\n     */\n    gt(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than or equal the specified's.\n     */\n    greaterThanOrEqual(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is greater than or equal the specified's.\n     */\n    gte(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is even.\n     */\n    isEven(): boolean;\n\n    /**\n     * Tests if this Long's value is negative.\n     */\n    isNegative(): boolean;\n\n    /**\n     * Tests if this Long's value is odd.\n     */\n    isOdd(): boolean;\n\n    /**\n     * Tests if this Long's value is positive.\n     */\n    isPositive(): boolean;\n\n    /**\n     * Tests if this Long's value equals zero.\n     */\n    isZero(): boolean;\n\n    /**\n     * Tests if this Long's value is less than the specified's.\n     */\n    lessThan(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than the specified's.\n     */\n    lt(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than or equal the specified's.\n     */\n    lessThanOrEqual(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value is less than or equal the specified's.\n     */\n    lte(other: Long | number | string): boolean;\n\n    /**\n     * Returns this Long modulo the specified.\n     */\n    modulo(other: Long | number | string): Long;\n\n    /**\n     * Returns this Long modulo the specified.\n     */\n    mod(other: Long | number | string): Long;\n\n    /**\n     * Returns the product of this and the specified Long.\n     */\n    multiply(multiplier: Long | number | string): Long;\n\n    /**\n     * Returns the product of this and the specified Long.\n     */\n    mul(multiplier: Long | number | string): Long;\n\n    /**\n     * Negates this Long's value.\n     */\n    negate(): Long;\n\n    /**\n     * Negates this Long's value.\n     */\n    neg(): Long;\n\n    /**\n     * Returns the bitwise NOT of this Long.\n     */\n    not(): Long;\n\n    /**\n     * Tests if this Long's value differs from the specified's.\n     */\n    notEquals(other: Long | number | string): boolean;\n\n    /**\n     * Tests if this Long's value differs from the specified's.\n     */\n    neq(other: Long | number | string): boolean;\n\n    /**\n     * Returns the bitwise OR of this Long and the specified.\n     */\n    or(other: Long | number | string): Long;\n\n    /**\n     * Returns this Long with bits shifted to the left by the given amount.\n     */\n    shiftLeft(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits shifted to the left by the given amount.\n     */\n    shl(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits arithmetically shifted to the right by the given amount.\n     */\n    shiftRight(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits arithmetically shifted to the right by the given amount.\n     */\n    shr(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits logically shifted to the right by the given amount.\n     */\n    shiftRightUnsigned(numBits: number | Long): Long;\n\n    /**\n     * Returns this Long with bits logically shifted to the right by the given amount.\n     */\n    shru(numBits: number | Long): Long;\n\n    /**\n     * Returns the difference of this and the specified Long.\n     */\n    subtract(subtrahend: number | Long | string): Long;\n\n    /**\n     * Returns the difference of this and the specified Long.\n     */\n    sub(subtrahend: number | Long | string): Long;\n\n    /**\n     * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.\n     */\n    toInt(): number;\n\n    /**\n     * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).\n     */\n    toNumber(): number;\n\n    /**\n     * Converts this Long to its byte representation.\n     */\n\n    toBytes(le?: boolean): number[];\n\n    /**\n     * Converts this Long to its little endian byte representation.\n     */\n\n    toBytesLE(): number[];\n\n    /**\n     * Converts this Long to its big endian byte representation.\n     */\n\n    toBytesBE(): number[];\n\n    /**\n     * Converts this Long to signed.\n     */\n    toSigned(): Long;\n\n    /**\n     * Converts the Long to a string written in the specified radix.\n     */\n    toString(radix?: number): string;\n\n    /**\n     * Converts this Long to unsigned.\n     */\n    toUnsigned(): Long;\n\n    /**\n     * Returns the bitwise XOR of this Long and the given one.\n     */\n    xor(other: Long | number | string): Long;\n  }\n}\n\nexport {};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/types/globals.d.ts",
    "content": "// This is a global declarations file that's referenced by valdi_core/src/Valdi.ts\n\ndeclare const module: { path: string; exports: unknown };\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/BUILD.bazel",
    "content": "load(\"@aspect_rules_js//npm:defs.bzl\", \"npm_package\")\nload(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nts_project(\n    name = \"valdi_core_web\",\n    srcs = glob([\n        \"web/**/*.ts\",\n        \"src/**/*.d.ts\",\n    ]),\n    allow_js = True,\n    composite = True,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n)\n\nnpm_package(\n    name = \"valdi_core_dts\",\n    srcs = glob([\n        \"src/**/*.d.ts\",\n        \"src/utils/**/*.d.ts\",\n    ]),\n    package = \"valdi_core\",\n    visibility = [\"//visibility:public\"],\n)\n\nvaldi_module(\n    name = \"valdi_core\",\n    srcs = glob([\n        \"src/**/*.js\",\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiCore\",\n    ios_output_target = \"release\",\n    module_yaml = \"module.yaml\",\n    single_file_codegen = False,\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":valdi_core_web\"],\n    web_register_native_module_id_overrides = {\n        \"valdi_core/web/DeviceBridge.js\": \"DeviceBridge\",\n    },\n    deps = [\n        \"//src/valdi_modules/src/valdi/coreutils\",\n        \"//src/valdi_modules/src/valdi/jasmine\",\n        \"//src/valdi_modules/src/valdi/source_map\",\n        \"//src/valdi_modules/src/valdi/valdi_tsx\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/README.md",
    "content": "# Valdi Vendors\n\n## Changes\n\nA list of changes made to the third party vendor files that will need to be replicated when updating.\n\n### Protobuf.js\n\n`Protobuf.js` has been modified to require `Long.js`, it’s important to include this change when updating `Protobuf.js`.\n\nSearch for `.configure =` to find the definition of configure, then go to that function and add the following line to the beginning of it:\n\n```js\nr.util.Long = Long\n```\n\nNOTE: `r` should match the var scope defined above it (as of this writing, it’s `var r = n`).\n\n### NPM libraries\n\n>  Note: the library files still have to be copied manually into `valdi_core/src` to be included in the valdi_modules compilation process.\n\n`valdi_core` contains a copy of the [tslib library](https://github.com/microsoft/tslib).\nThe current version you can find in the `valdi_core/package.json`\nTo update the tslib library you need to copy two files:\n- `valdi_core/node_modules/tslib/tslib.js` -> `valdi_core/src/tslib.js`\n- `valdi_core/node_modules/tslib/tslib.d.ts` -> `valdi_core/src/tslib.d.ts`\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/module.yaml",
    "content": "output_target: release\n\nbazel_build_file_generation_disabled: true\n\nweb:\n  version: 1.0.2\n  publish_config: '{ \"@snapchat:registry\": \"https://registry.npmjs.org/\"\n    }'\n  main: src/AnimationOptions.js\n  scope: snapchat\n\ndependencies:\n  - coreutils\n  - source_map\n  - jasmine\n  - valdi_tsx\n\nallowed_debug_dependencies:\n  - jasmine\n\ncompilation_mode:\n  native:\n    include_patterns:\n      - .*/src/Init\\.js\n      - .*/src/ModuleLoader\\.ts\n      - .*/src/Renderer\\.ts\n      - .*/src/JSX.*\\.ts\n      - .*/src/TsnHelper\\.ts\n      - .*/utils/Buffer\\.ts\n      - .*/utils/CallbackInternal\\.ts\n      - .*/utils/IdentifyableObject\\.ts\n      - .*/utils/PartialUtils\\.ts\n      - .*/utils/PropertyList\\.ts\n      - .*/utils/When\\.ts\n\nexclude_patterns:\n  - .*\\/web\\/.*\nexclude_globs:\n  - \"**/web/**\"\n\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/package.json",
    "content": "{\n  \"name\": \"valdi_core\",\n  \"version\": \"1.0.0\",\n  \"description\": \"package.json for maintaining versions of the npm dependencies included in the `valdi_core` Valdi module. For details please check the README.\",\n  \"dependencies\": {\n    \"tslib\": \"2.4.0\"\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/AnimationOptions.ts",
    "content": "export enum AnimationCurve {\n  Linear = 'linear',\n  EaseIn = 'easeIn',\n  EaseOut = 'easeOut',\n  EaseInOut = 'easeInOut',\n}\n\nexport type AnimationOptions = SpringAnimationOptions | PresetCurveAnimationOptions | CustomCurveAnimationOptions;\n\nexport interface BasicAnimationOptions {\n  /**\n   * The duration of the animation in seconds.\n   */\n  duration: number;\n\n  /**\n   * Whether the animation should start from the current layer state.\n   * Corresponds to CoreAnimation's beginFromCurrentState.\n   */\n  beginFromCurrentState?: boolean;\n\n  /**\n   * Whether the animation should crossfade with an alpha transition between the\n   *  previous state of the tree to the new state.\n   */\n  crossfade?: boolean;\n\n  /**\n   * A completion to call when the transition has completed\n   */\n  completion?: (wasCancelled: boolean) => void;\n}\n\nexport interface PresetCurveAnimationOptions extends BasicAnimationOptions {\n  /**\n   * The curve to use for the animation, defaults\n   * to easeInOut. Ignored when controlPoints is set.\n   */\n  curve?: AnimationCurve;\n}\n\nexport interface CustomCurveAnimationOptions extends BasicAnimationOptions {\n  /**\n   * 4 control points to control the curve.\n   * If set, curve will be ignored to use those\n   * control points instead.\n   */\n  controlPoints: Array<number>;\n}\n\nexport interface SpringAnimationOptions {\n  /**\n   * The spring stiffness coefficient. Higher values correspond to a stiffer spring that yields a greater amount of force for moving objects.\n   * Corresponds to the \"spring constant\" in the spring equation.\n   *\n   * Must be greater than 0.\n   * See: https://drive.google.com/file/d/1z5OUi8hhO4ZdgR6hkHCbwy-BRLJG8mjs/view?usp=sharing\n   */\n  stiffness: SpringStiffnessValue;\n\n  /**\n   * The damping force to apply to the spring’s motion. This is the damping coefficient in the spring equation.\n   *\n   * Must be greater than 0.\n   * See: https://drive.google.com/file/d/1z5OUi8hhO4ZdgR6hkHCbwy-BRLJG8mjs/view?usp=sharing\n   */\n  damping: SpringDampingValue;\n\n  /**\n   * Whether the animation should start from the current layer state.\n   * Corresponds to CoreAnimation's beginFromCurrentState.\n   */\n  beginFromCurrentState?: boolean;\n\n  /**\n   * A completion to call when the transition has completed\n   */\n  completion?: (wasCanceled: boolean) => void;\n}\n\n// (Taken from Principle.app)\nexport const SPRING_DEFAULT_STIFFNESS: SpringStiffnessValue = 381.47;\n// (Taken from Principle.app)\nexport const SPRING_DEFAULT_DAMPING: SpringDampingValue = 20.1;\n\nexport type SpringStiffnessValue = number;\nexport type SpringDampingValue = number;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Any.d.ts",
    "content": "/**\n * @NativeClass({\n *   marshallAsUntyped: true,\n *   ios: 'NSObject', iosImportPrefix: 'Foundation',\n *   android: 'kotlin.Any'\n * })\n */\nexport interface Any {}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/AnyRenderFunction.d.ts",
    "content": "export type AnyRenderFunction = (...args: any[]) => void;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Application.ts",
    "content": "import {\n  ApplicationCancelable,\n  observeKeyboardHeight as nativeObserveKeyboardHeight,\n  observeEnteredBackground as nativeObserveEnteredBackground,\n  observeEnteredForeground as nativeObserveEnteredForeground,\n  isForegrounded as nativeIsForegrounded,\n  isIntegrationTestEnvironment as nativeIsIntegrationTestEnvironment,\n  getAppVersion as nativeGetAppVersion,\n} from './ApplicationBridge';\nimport { getModuleLoader } from './ModuleLoaderGlobal';\n\nlet currentKeyboardHeight = 0;\nif (nativeObserveKeyboardHeight) {\n  const observeKeyboardHeight = nativeObserveKeyboardHeight((height: number) => {\n    currentKeyboardHeight = height;\n  });\n  getModuleLoader().onHotReload(module, module.path, () => {\n    observeKeyboardHeight.cancel();\n  });\n}\n\n/**\n * Public API for Application calls\n */\nexport namespace Application {\n  /**\n   * Start listening to the application entering the background\n   */\n  export function observeEnteredBackground(observe: () => void): ApplicationCancelable {\n    if (nativeObserveEnteredBackground) {\n      return nativeObserveEnteredBackground(observe);\n    } else {\n      console.error('Application.observeEnteredBackground not implemented');\n      return {\n        cancel: () => {},\n      };\n    }\n  }\n  /**\n   * Start listening to the application entering the foreground\n   */\n  export function observeEnteredForeground(observe: () => void): ApplicationCancelable {\n    if (nativeObserveEnteredForeground) {\n      return nativeObserveEnteredForeground(observe);\n    } else {\n      console.error('Application.observeEnteredForeground not implemented');\n      return {\n        cancel: () => {},\n      };\n    }\n  }\n  /**\n   * Start listening to the application's soft keyboard's height\n   */\n  export function observeKeyboardHeight(observe: (height: number) => void): ApplicationCancelable {\n    if (nativeObserveKeyboardHeight) {\n      return nativeObserveKeyboardHeight(observe);\n    } else {\n      console.error('Application.observeKeyboardHeight not implemented');\n      observe(0);\n      return {\n        cancel: () => {},\n      };\n    }\n  }\n  /**\n   * Get whether the application is currently foregrounded\n   */\n  export function isForegrounded(): boolean {\n    if (nativeIsForegrounded) {\n      return nativeIsForegrounded();\n    } else {\n      console.error('Application.isForegrounded not implemented');\n      return true;\n    }\n  }\n\n  /**\n   * Get whether the application is running in a test environment\n   * On Android this checks isCremaTestAutomationMode()\n   * On iOS this checks if XCTestCase is available\n   */\n  export function isIntegrationTestEnvironment(): boolean {\n    if (nativeIsIntegrationTestEnvironment) {\n      return nativeIsIntegrationTestEnvironment();\n    } else {\n      console.error('Application.isTestEnvironment not implemented');\n      return false;\n    }\n  }\n\n  /**\n   * Get the application version\n   * e.g.: 1.0.3\n   */\n  export function getAppVersion(): string {\n    if (nativeGetAppVersion) {\n      return nativeGetAppVersion();\n    } else {\n      console.error('Application.appVersion not implemented');\n      return '';\n    }\n  }\n\n  /**\n   * Get the current keyboard height\n   */\n  export function getKeyboardHeight(): number {\n    return currentKeyboardHeight;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ApplicationBridge.d.ts",
    "content": "export interface ApplicationCancelable {\n  cancel(): void;\n}\n\nexport function observeEnteredBackground(observe: () => void): ApplicationCancelable;\nexport function observeEnteredForeground(observe: () => void): ApplicationCancelable;\nexport function observeKeyboardHeight(observe: (height: number) => void): ApplicationCancelable;\nexport function isForegrounded(): boolean;\nexport function isIntegrationTestEnvironment(): boolean;\nexport function getAppVersion(): string;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Asset.ts",
    "content": "import { Asset } from 'valdi_tsx/src/Asset';\nimport { BackendRenderingType, LoadedAsset, LoadedAssetMetadata, ValdiRuntime } from './ValdiRuntime';\nimport { Device } from './Device';\n\nexport { Asset };\n\n/**\n * Specifies the desired output type of a given asset.\n * This will impact the underlying asset loader used to load\n * an asset.\n */\nexport const enum AssetOutputType {\n  BYTES = 0,\n  IMAGE_IOS = 1,\n  IMAGE_ANDROID = 2,\n  IMAGE_SNAP_DRAWING = 3,\n  VIDEO_IOS = 4,\n  VIDEO_ANDROID = 5,\n  ANIMATED_IMAGE = 6,\n  DUMMY = 7,\n}\n\n/**\n * This enum is similar to AssetOutputType, but is abstracted away from\n * the underlying platform used. This makes it possible to have cross-platform\n * code which expects a specific type of asset, like video, to request to load\n * a video without having to specify whether it's for iOS and Android.\n */\nexport const enum AssetType {\n  BYTES,\n  IMAGE,\n  VIDEO,\n  ANIMATED_IMAGE,\n  DUMMY,\n}\n\ndeclare const runtime: ValdiRuntime;\n\n/**\n * Make an Asset (to be set on <image/>) from an arbitrary URL\n */\nexport function makeAssetFromUrl(url: string): Asset {\n  return runtime.makeAssetFromUrl(url);\n}\n\n/**\n * Create an Asset from a bytes source.\n * The returned asset instance will retain the bytes, and can be set\n * on the src attribute of an <image>. When the src is set, the runtime\n * will asynchronously convert the bytes into a suitable representation\n * to display inside the image element.\n */\nexport function makeAssetFromBytes(bytes: ArrayBuffer | Uint8Array): Asset {\n  return runtime.makeAssetFromBytes(bytes);\n}\n\n/**\n * Make a directional Asset from a given left to right (LTR) and\n * right to left (RTL) asset. The LTR asset will be used when the\n * asset is used in a node that is in a LTR layout direction, whereas\n * the RTL asset will be used in a RTL layout direction.\n * @param ltrAsset the asset to use in a LTR layout direction\n * @param rtlAsset the asset to use in a RTL layout direction\n * @returns an Asset that can be used as a src attribute, and will\n * use either the ltr or rtl asset depending the layout direction.\n */\nexport function makeDirectionalAsset(ltrAsset: string | Asset, rtlAsset: string | Asset): Asset {\n  return runtime.makeDirectionalAsset(ltrAsset, rtlAsset);\n}\n\nexport type PlatformAssetOverrides = {\n  ios?: string | Asset;\n  android?: string | Asset;\n};\n\n/**\n * Make a platform specific Asset from a default asset `defaultAsset` and\n * iOS and/or Android assets in `platformAssetOverrides`. The iOS asset will be\n * rendered on iOS, whereas the Android asset will be used in a node rendered\n * on Android.\n * Omitting iOS or Android in `platformAssetOverrides` will mean that platform falls back\n * to the `defaultAsset`. An empty `platformAssetOverrides`, is programmer error and will\n * throw an error.\n * Unmentioned platforms (web / desktop) will use the `defaultAsset`\n * until support is added to allow overrides for those platforms.\n * @param defaultAsset the asset to use in absence of a platform override\n * matching your current rendering platform (ie. iOS, Android)\n * @param platformAssetOverrides an object containing asset overrides for specific rendering platforms\n * @returns an Asset that can be used as a src attribute, and will\n * use either the `defaultAsset` or platform specific asset depending the rendering platform,\n * and the contents of `platformAssetOverrides`.\n */\nexport function makePlatformSpecificAsset(\n  defaultAsset: string | Asset,\n  platformAssetOverrides: PlatformAssetOverrides,\n): Asset {\n  return runtime.makePlatformSpecificAsset(defaultAsset, platformAssetOverrides);\n}\n\n/**\n * Callback called whenever an asset has finished loading.\n */\nexport type AssetLoadObserver = (loadedAsset: LoadedAsset | Uint8Array | undefined, error: string | undefined) => void;\n\nexport interface AssetSubscription {\n  unsubscribe(): void;\n}\n\n/**\n * Resolve the AssetOutpuType for a given contextId and AssetType. This will query\n * the underlying render backend used within the context to resolve the AssetOutputType\n * that should be used to load a given asset.\n */\nexport function resolveAssetOutputType(contextId: number | string, assetType: AssetType): AssetOutputType {\n  switch (assetType) {\n    case AssetType.BYTES:\n      return AssetOutputType.BYTES;\n    case AssetType.IMAGE:\n      switch (runtime.getBackendRenderingTypeForContextId(contextId)) {\n        case BackendRenderingType.ANDROID:\n          return AssetOutputType.IMAGE_ANDROID;\n        case BackendRenderingType.IOS:\n          return AssetOutputType.IMAGE_IOS;\n        case BackendRenderingType.SNAP_DRAWING:\n          return AssetOutputType.IMAGE_SNAP_DRAWING;\n      }\n      break;\n    case AssetType.VIDEO:\n      switch (runtime.getBackendRenderingTypeForContextId(contextId)) {\n        case BackendRenderingType.ANDROID:\n          return AssetOutputType.VIDEO_ANDROID;\n        case BackendRenderingType.IOS:\n          return AssetOutputType.VIDEO_IOS;\n        case BackendRenderingType.SNAP_DRAWING:\n          if (Device.isIOS()) {\n            return AssetOutputType.VIDEO_IOS;\n          } else if (Device.isAndroid()) {\n            return AssetOutputType.VIDEO_ANDROID;\n          } else {\n            return AssetOutputType.DUMMY;\n          }\n      }\n      break;\n    case AssetType.ANIMATED_IMAGE:\n      return AssetOutputType.ANIMATED_IMAGE;\n    case AssetType.DUMMY:\n      return AssetOutputType.DUMMY;\n  }\n}\n\n/**\n * Append an asset load observer into a given asset.\n * This will trigger a load of the asset and populate the cache.\n * The asset will remain loaded for as long as the observer is registered.\n * The observer can be removed by calling unsubscribe() on the returned object\n * from this function. Every call of addAssetLoadObserver must have an unsubscribe()\n * call otherwise the asset will leak.\n */\nexport function addAssetLoadObserver(\n  asset: string | Asset,\n  onLoad: AssetLoadObserver,\n  outputType: AssetOutputType,\n  preferredWidth?: number,\n  preferredHeight?: number,\n): AssetSubscription {\n  const unsubscribe = runtime.addAssetLoadObserver(asset, onLoad, outputType, preferredWidth, preferredHeight);\n  return { unsubscribe };\n}\n\n/**\n * Returns the metadata reported by the LoadedAsset.\n */\nexport function getLoadedAssetMetadata(loadedAsset: LoadedAsset): LoadedAssetMetadata | undefined {\n  return runtime.getLoadedAssetMetadata(loadedAsset);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/AssetCatalog.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { Asset } from './Asset';\nimport { AssetEntry, ValdiRuntime } from './ValdiRuntime';\nimport { toCamelCase } from './utils/StringUtils';\n\nexport type GetFuncFn = (size: number) => string;\n\nexport type AssetCatalogEntry = Asset | GetFuncFn;\nexport type AssetCatalog = StringMap<AssetCatalogEntry>;\n\ndeclare const runtime: ValdiRuntime;\n\nfunction makeGetFuncFn(fontName: string): GetFuncFn {\n  return (size: number) => {\n    return `${fontName} ${size}`;\n  };\n}\n\nexport function makeCatalog(entries: AssetEntry[]): AssetCatalog {\n  const out: AssetCatalog = {};\n\n  for (const entry of entries) {\n    if (typeof entry === 'string') {\n      const components = entry.split(':');\n      const propertyName = toCamelCase(components[components.length - 1]);\n      out[propertyName] = makeGetFuncFn(entry);\n    } else {\n      const components = entry.path.split(':');\n      const propertyName = toCamelCase(components[components.length - 1]);\n      out[propertyName] = entry;\n    }\n  }\n\n  return out;\n}\n\nexport function loadCatalog(catalogPath: string): any {\n  const assets = runtime.getAssets(catalogPath);\n  return makeCatalog(assets);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/BugReporter.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\n\ninterface LogMetadataProviderInfo {\n  name: string;\n  provider: LogMetadataProvider;\n}\n\nexport interface DumpedLogs {\n  /**\n   * Arbitrary verbose data which will be printed on the app logger.\n   */\n  verbose?: any;\n\n  /**\n   * Small metadata dictionary which will be added directly to the report ticket.\n   */\n  metadata?: StringMap<string>;\n}\n\nlet sequence = 0;\nconst observers: { [key: number]: LogMetadataProviderInfo } = {};\n\nexport type LogMetadataProvider = (includeMetadata?: boolean, includeVerbose?: boolean) => DumpedLogs;\nexport type Observer = () => void;\n\n/**\n * Registers a callback which will be used to provide log metadata whenever the\n * user uses shake to report. The callback can return any js objects, arrays or\n * even a plain string. The result will be ultimately serialized in a JSON like\n * payload. The function returns an Observer which must be disposed when appropriate.\n *\n * @param name the name of the provider, which will be used to help identify where\n * the data is coming from.\n *\n * @param provider a callback which will be called when shake to report is used.\n */\nexport function registerLogMetadataProvider(name: string, provider: LogMetadataProvider): Observer {\n  const key = ++sequence;\n  observers[key] = { name, provider };\n\n  return () => {\n    delete observers[key];\n  };\n}\n\n/**\n * Call all the registed providers and return an array containing the names and the provided data.\n */\nexport function dumpLogMetadata(includeMetadata: boolean, includeVerbose: boolean): any[] {\n  const out: any[] = [];\n\n  for (const key in observers) {\n    const info = observers[key]!;\n\n    let dumpedData: DumpedLogs;\n    try {\n      dumpedData = info.provider(includeMetadata, includeVerbose);\n    } catch (err: any) {\n      dumpedData = { verbose: `Provider threw an error while providing log data: ${err.message}:\\n${err.stack}` };\n    }\n\n    out.push(info.name);\n    out.push(includeVerbose ? dumpedData.verbose : undefined);\n    out.push(includeMetadata ? dumpedData.metadata : undefined);\n  }\n\n  return out;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/BuildType.ts",
    "content": "import { ValdiRuntime } from './ValdiRuntime';\n\nexport enum BuildType {\n  Dev = 'dev',\n  Gold = 'gold',\n  Alpha = 'alpha',\n  Prod = 'prod',\n}\n\ndeclare const runtime: ValdiRuntime;\n\n/**\n * @returns The BuildType that the Valdi runtime was compiled in.\n */\nexport function getBuildType(): BuildType {\n  const buildType = runtime.buildType as BuildType;\n  if (buildType === undefined) {\n    return BuildType.Dev;\n  }\n  return buildType;\n}\n\n/**\n * Returns whether the Valdi runtime was compiled on a production like build.\n */\nexport function isProdBuild(): boolean {\n  const buildType = getBuildType();\n  return buildType == BuildType.Prod || buildType == BuildType.Alpha;\n}\n\n/**\n * Returns whether the Valdi runtime was compiled on a development build.\n */\nexport function isDevBuild(): boolean {\n  return !isProdBuild();\n}\n\nexport function isInternalBuild(): boolean {\n  const buildType = getBuildType();\n  return buildType == BuildType.Dev || buildType == BuildType.Gold || buildType == BuildType.Alpha;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/CSSModule.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { ValdiRuntime, CSSModuleNative } from './ValdiRuntime';\nimport { setObjectId } from './utils/IdentifyableObject';\n\ndeclare const runtime: ValdiRuntime;\n\nexport interface CSSRule {}\n\nexport type CSSModule = StringMap<CSSRule>;\n\nexport function makeModule(compiledCSSPath: string, ruleMapping: StringMap<string>): CSSModule {\n  const cssModule = getNativeModule(compiledCSSPath);\n\n  const target = {} as any;\n  return new Proxy(target, {\n    get(target, key) {\n      let rule = target[key];\n      if (typeof rule === 'undefined') {\n        const ruleName = ruleMapping[key as string];\n        rule = ruleName && cssModule.getRule(ruleName);\n        if (typeof rule === 'undefined') {\n          // 'null' means already fetched and not found\n          rule = null;\n        }\n        target[key] = rule;\n        setObjectId(rule);\n      }\n      return rule;\n    },\n  });\n}\n\nexport function getNativeModule(compiledCSSPath: string): CSSModuleNative {\n  const cssModule = runtime.getCSSModule(compiledCSSPath);\n  setObjectId(cssModule);\n  return cssModule;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/CancelablePromise.ts",
    "content": "/**\n * Represents a promise object that can be canceled.\n */\nexport interface CancelablePromise<T> extends PromiseLike<T> {\n  cancel?(): void;\n}\n\n/**\n * Return a CancelablePromise from an existing promise, with a cancel callback that will\n * be invoked when the cancelable promise is canceled.\n */\nexport function promiseToCancelablePromise<T>(promise: Promise<T>, onCancel: () => void): CancelablePromise<T> {\n  return {\n    cancel: onCancel,\n    then: (onfulfilled, onrejected) => {\n      return promise.then(onfulfilled, onrejected);\n    },\n  };\n}\n\nexport type PromiseOnCancelFn = () => void;\n\nexport class PromiseCanceler {\n  /**\n   * Returns whether cancel() has been called on the promise canceler.\n   */\n  get canceled(): boolean {\n    return this._canceled === true;\n  }\n\n  private _canceled?: boolean;\n  private _onCancels?: PromiseOnCancelFn | PromiseOnCancelFn[];\n\n  constructor() {}\n\n  /**\n   * Registers a cancel function that will be invoked when cancel() is called.\n   */\n  onCancel(fn: PromiseOnCancelFn): void {\n    if (this._canceled) {\n      fn();\n      return;\n    }\n\n    if (!this._onCancels) {\n      this._onCancels = fn;\n    } else {\n      if (Array.isArray(this._onCancels)) {\n        this._onCancels.push(fn);\n      } else {\n        this._onCancels = [this._onCancels, fn];\n      }\n    }\n  }\n\n  /**\n   * Mark the CancelablePromise as canceled, which will notify all the\n   * registered onCancel callbacks.\n   */\n  cancel(): void {\n    if (!this._canceled) {\n      this._canceled = true;\n\n      const onCancels = this._onCancels;\n      if (!onCancels) {\n        return;\n      }\n\n      this._onCancels = undefined;\n\n      if (Array.isArray(onCancels)) {\n        for (const onCancel of onCancels) {\n          onCancel();\n        }\n      } else {\n        onCancels();\n      }\n    }\n  }\n\n  clear() {\n    this._onCancels = undefined;\n  }\n\n  toCancelablePromise<T>(promise: Promise<T>): CancelablePromise<T> {\n    const cancelablePromise = promise as CancelablePromise<T>;\n    cancelablePromise.cancel = this.cancel.bind(this);\n    return cancelablePromise;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/CancellableAnimation.d.ts",
    "content": "export type CancelToken = number;\n\nexport const enum CancellableAnimationState {\n  Running,\n  Cancelled,\n  Finished,\n}\n\nexport interface CancellableAnimation {\n  cancel(): void;\n  getState(): CancellableAnimationState;\n  start(): Promise<boolean>;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/CancellableAnimationPromise.ts",
    "content": "import { AnimationOptions } from './AnimationOptions';\nimport { CancellableAnimation, CancellableAnimationState } from './CancellableAnimation';\nimport { IRenderer } from './IRenderer';\n\nexport class CancellableAnimationPromise implements CancellableAnimation {\n  private renderer: IRenderer;\n  private options: AnimationOptions;\n  private animations: () => void;\n  private cancelToken?: number;\n  private cancelled?: boolean;\n  private started?: boolean;\n\n  constructor(renderer: IRenderer, options: AnimationOptions, animations: () => void) {\n    this.renderer = renderer;\n    this.options = options;\n    this.animations = animations;\n  }\n\n  start(): Promise<boolean> {\n    if (this.started) {\n      throw new Error('Tried to start Animation twice');\n    }\n    this.started = true;\n    return new Promise(resolve => {\n      this.cancelToken = this.renderer.animate(\n        {\n          ...this.options,\n          completion: cancelled => {\n            this.options.completion?.(cancelled);\n            this.cancelled = cancelled;\n            resolve(cancelled);\n          },\n        },\n        this.animations,\n      );\n    });\n  }\n\n  cancel(): void {\n    if (this.cancelToken !== undefined) {\n      this.renderer.cancelAnimation(this.cancelToken);\n      this.cancelToken = undefined;\n    }\n  }\n\n  getState(): CancellableAnimationState {\n    if (this.started) {\n      return CancellableAnimationState.Running;\n    }\n    if (this.cancelled === true) {\n      return CancellableAnimationState.Cancelled;\n    }\n    return CancellableAnimationState.Finished;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/CapturedNode.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { NativeNode } from 'valdi_tsx/src/NativeNode';\nimport { NativeView } from 'valdi_tsx/src/NativeView';\nimport { ConsoleRepresentable } from './ConsoleRepresentable';\nimport { IComponent } from './IComponent';\nimport { ElementId, IRenderedElement } from './IRenderedElement';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\nimport { IRenderer } from './IRenderer';\nimport { PropertyList } from './utils/PropertyList';\nimport { computeUniqueId } from './utils/RenderedVirtualNodeUtils';\n\nexport interface IElementData {\n  readonly id: ElementId;\n  readonly tag: string;\n  readonly viewClass: string;\n  readonly attributes: StringMap<any>;\n  readonly frame: ElementFrame;\n}\n\n/**\n * An immutable implementation of IRenderedVirtualNode.\n */\nexport class CapturedRenderedVirtualNode implements IRenderedVirtualNode {\n  parent: IRenderedVirtualNode | undefined;\n  parentIndex = 0;\n  element: IRenderedElement | undefined;\n\n  private cachedUniqueId?: string;\n\n  constructor(\n    readonly key: string,\n    elementData: IElementData | undefined,\n    readonly component: IComponent | undefined,\n    readonly children: CapturedRenderedVirtualNode[],\n    readonly renderer: IRenderer,\n  ) {\n    let index = 0;\n    for (const child of children) {\n      child.parent = this;\n      child.parentIndex = index;\n      index++;\n    }\n\n    if (elementData) {\n      this.element = makeElement(elementData, this);\n    }\n  }\n\n  get uniqueId(): string {\n    if (this.cachedUniqueId) {\n      return this.cachedUniqueId;\n    }\n    this.cachedUniqueId = computeUniqueId(this);\n    return this.cachedUniqueId;\n  }\n}\n\nfunction resolveElementChildren(virtualNodeChildren: IRenderedVirtualNode[], children: IRenderedElement[]) {\n  for (const virtualNodeChild of virtualNodeChildren) {\n    if (virtualNodeChild.element) {\n      children.push(virtualNodeChild.element);\n    } else {\n      resolveElementChildren(virtualNodeChild.children, children);\n    }\n  }\n}\n\nfunction makeElement(data: IElementData, node: IRenderedVirtualNode): IRenderedElement {\n  const children: IRenderedElement[] = [];\n  resolveElementChildren(node.children, children);\n\n  return new CapturedRenderedElement(data, node, children);\n}\n\nfunction immutableError(methodName: string): Error {\n  return new Error(`Cannot use ${methodName} on CapturedRenderedElement`);\n}\n\nexport class CapturedRenderedElement implements IRenderedElement, ConsoleRepresentable {\n  parent: IRenderedElement | undefined;\n  parentIndex = 0;\n\n  constructor(\n    readonly data: IElementData,\n    readonly virtualNode: IRenderedVirtualNode,\n    readonly children: IRenderedElement[],\n  ) {}\n\n  getAttribute(name: string): any {\n    return this.data.attributes[name];\n  }\n\n  setAttribute(name: string, value: any): boolean {\n    throw immutableError('setAttribute');\n  }\n\n  setAttributes(attributes: PropertyList): boolean {\n    throw immutableError('setAttributes');\n  }\n\n  getVirtualNode(): IRenderedVirtualNode {\n    return this.virtualNode;\n  }\n\n  getAttributeNames(): string[] {\n    return Object.keys(this.data.attributes);\n  }\n\n  getNativeView(): Promise<NativeView | undefined> {\n    return new Promise((resolve, reject) => {\n      reject(immutableError('getNativeView'));\n    });\n  }\n\n  getNativeNode(): NativeNode | undefined {\n    return undefined;\n  }\n\n  takeSnapshot(): Promise<string | undefined> {\n    return new Promise((resolve, reject) => {\n      reject(immutableError('takeSnapshot'));\n    });\n  }\n\n  get frame(): ElementFrame {\n    return this.data.frame;\n  }\n\n  get emittingComponent(): IComponent | undefined {\n    let current: IRenderedVirtualNode | undefined = this.virtualNode;\n    while (current && !current.component) {\n      current = current.parent;\n    }\n\n    return current?.component;\n  }\n\n  get renderer(): IRenderer {\n    return this.virtualNode.renderer;\n  }\n\n  get id(): ElementId {\n    return this.data.id;\n  }\n\n  get tag(): string {\n    return this.data.tag;\n  }\n\n  get viewClass(): string {\n    return this.data.viewClass;\n  }\n\n  get key(): string {\n    return this.virtualNode.key;\n  }\n\n  toConsoleRepresentation() {\n    return [this.viewClass, this.data.attributes];\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/CompilerIntrinsics.ts",
    "content": "import { AnyRenderFunction } from 'valdi_core/src/AnyRenderFunction';\n\ntype GetTypeOfChildren<TViewModel> = TViewModel extends { children: any } ? TViewModel['children'] : never;\n\n/**\n * Compiler annotation to mark that a render function should be provided\n * as the slot of a component through its \"children\" view model property.\n * This function can only be called in TSX.\n * @param value the render function that should be passed as the view model \"children\" property\n */\nexport declare function $slot<T extends AnyRenderFunction>(value: T | undefined): T | undefined;\n\n/**\n * Compiler annotation to mark that an object should be treated as a named slots,\n * and provided to the component through its \"children\" view model property.\n * This function can only be called in TSX.\n * @param value the named slots object that should be passed as the view model \"children\" property.\n */\nexport declare function $namedSlots<TNamedSlots>(value: GetTypeOfChildren<TNamedSlots>): GetTypeOfChildren<TNamedSlots>;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Component.ts",
    "content": "import {\n  AnimationOptions,\n  CustomCurveAnimationOptions,\n  PresetCurveAnimationOptions,\n  SpringAnimationOptions,\n} from './AnimationOptions';\nimport { CancellableAnimation } from './CancellableAnimation';\nimport { CancellableAnimationPromise } from './CancellableAnimationPromise';\nimport { ConsoleRepresentable } from './ConsoleRepresentable';\nimport { IComponent } from './IComponent';\nimport { ComponentDisposable, IRenderer } from './IRenderer';\nimport { setTimeoutInterruptible } from './SetTimeout';\nimport { mergePartial } from './utils/PartialUtils';\n\nimport 'valdi_tsx/src/JSX';\n\nexport class Component<ViewModel = object, ComponentContext = object>\n  implements IComponent<ViewModel, ComponentContext>, ConsoleRepresentable\n{\n  readonly viewModel: Readonly<ViewModel>;\n  readonly context: Readonly<ComponentContext>;\n\n  readonly renderer: IRenderer;\n\n  constructor(renderer: IRenderer, viewModel: ViewModel, componentContext: any) {\n    this.renderer = renderer;\n    this.viewModel = viewModel;\n    this.context = componentContext;\n  }\n\n  /**\n   * Called whenever the Component is created for the first time, before\n   * it completed its first render.\n   */\n  onCreate(): void {}\n\n  /**\n   * Called during a render pass. You can override this method to make any JSX\n   * calls which will represent the UI. You need to be in an onRender() callback\n   * in order to make JSX calls.\n   */\n  onRender(): void {}\n\n  /**\n   * Called whenever the component has been destroyed, e.g. it is not part of the\n   * hierarchy anymore.\n   */\n  onDestroy(): void {}\n\n  /**\n   * Called whenever the view model has changed. This will be called right after onCreate()\n   * if the component is given an initial view model, or any time a new view model is provided.\n   */\n  onViewModelUpdate(previousViewModel?: Readonly<ViewModel>): void {}\n\n  /**\n   * @deprecated (use a StatefulComponent instead)\n   * Schedule a render for the Component, will trigger an onRender() in the future.\n   * This will typically be called automatically on your behalf, you shouldn't need this.\n   */\n  scheduleRender(): void {\n    this.renderer.renderComponent(this, undefined);\n  }\n\n  /**\n   * Registers a function or unsubscribable which will be called right after the component is destroyed.\n   * @param disposable the callback to call after the component is destroyed\n   * @returns {boolean} true if a disposable was registered to be disposed\n   */\n  registerDisposable(disposable: ComponentDisposable): true\n  registerDisposable(disposable: undefined): false\n  registerDisposable(disposable: ComponentDisposable | undefined): boolean\n  registerDisposable(disposable: ComponentDisposable | undefined): boolean {\n    if (!disposable) {\n      return false;\n    }\n    this.renderer.registerComponentDisposable(this, disposable);\n    return true;\n  }\n\n  /**\n   * Registers each function or unsubscribable in the array which will be called right after the component is destroyed.\n   * @param disposables array of callbacks to call after the component is destroyed\n   */\n  registerDisposables(disposables: ComponentDisposable[]): void {\n    disposables.forEach(this.registerDisposable.bind(this));\n  }\n\n  /**\n   * @deprecated @see registerDisposable\n   */\n  maybeRegisterDisposable(disposable: ComponentDisposable | undefined): void {\n    if (!!disposable) {\n      this.registerDisposable(disposable);\n    }\n  }\n\n  // TODO: move IDisposable into valdi_core and modify ^^^this^^^ to be able to work with IDisposables?\n  // (foundation depends on valdi_core, so can't keep it in foundation. seems like we need\n  // some utility module that valdi_core can depend on?)\n\n  // TODO: once IDisposable is accessible from valdi_core, setTimeoutDisposable could return an IDisposable\n  /** Creates a timer that will get invalidated when the component is destroyed. */\n  setTimeoutDisposable(handler: () => void, timeout?: number): number {\n    const timerId = setTimeoutInterruptible(handler, timeout);\n    this.registerDisposable(() => {\n      clearTimeout(timerId);\n    });\n    return timerId;\n  }\n\n  animate(options: AnimationOptions, animations: () => void): void;\n\n  animate(options: PresetCurveAnimationOptions, animations: () => void): void;\n\n  animate(options: CustomCurveAnimationOptions, animations: () => void): void;\n\n  animate(options: SpringAnimationOptions, animations: () => void): void;\n\n  /**\n   * Associate a set of changes with an animation\n   * @param animations a block which will be executed in a render. All element mutations\n   * belong to this renderer will be animated.\n   * @return A promise which will be resolved when the animation finishes.\n   *\n   *\n   * To get notified on animation complete, use `animatePromise` instead.\n   */\n  animate(options: AnimationOptions, animations: () => void): void {\n    void this.animatePromise(options, animations);\n  }\n\n  animatePromise(options: AnimationOptions, animations: () => void): Promise<void>;\n\n  animatePromise(options: PresetCurveAnimationOptions, animations: () => void): Promise<void>;\n\n  animatePromise(options: CustomCurveAnimationOptions, animations: () => void): Promise<void>;\n\n  animatePromise(options: SpringAnimationOptions, animations: () => void): Promise<void>;\n\n  /**\n   * Associate a set of changes with an animation\n   * @param animations a block which will be executed in a render. All element mutations\n   * belong to this renderer will be animated.\n   * @return A promise which will be resolved when the animation finishes.\n   */\n  animatePromise(options: AnimationOptions, animations: () => void): Promise<void> {\n    return new Promise(resolve => {\n      this.renderer.animate(\n        {\n          ...options,\n          completion: cancelled => {\n            options.completion?.(cancelled);\n            resolve();\n            return;\n          },\n        },\n        animations,\n      );\n    });\n  }\n\n  createAnimation(options: AnimationOptions, animations: () => void): CancellableAnimation {\n    return new CancellableAnimationPromise(this.renderer, options, animations);\n  }\n\n  /**\n   * Returns whether the Component was destroyed.\n   */\n  isDestroyed(): boolean {\n    return !this.renderer.isComponentAlive(this);\n  }\n\n  /**\n   * Returns an object to be serialized as a string representation for the component, used for debugging\n   */\n  toConsoleRepresentation() {\n    return this.viewModel;\n  }\n\n  static disallowNullViewModel = true;\n}\n\nexport class StatefulComponent<ViewModel = object, State = object, ComponentContext = object> extends Component<\n  ViewModel,\n  ComponentContext\n> {\n  state?: Readonly<State>;\n\n  /**\n   * Changes the state by merging the given partial state.\n   * Will synchronously re-render the component if the state changes.\n   */\n  setState(state: Readonly<Partial<State>>): void {\n    if (this.isDestroyed()) {\n      console.error(\n        new Error(\n          `Can't call setState on a destroyed component '${\n            (<any>this).constructor?.name\n          }'. This operation does nothing, but it signals a potential memory leak in your application. To resolve this issue, ensure you cancel all subscriptions and asynchronous tasks in the onDestroy method.`,\n        ),\n      );\n      return;\n    }\n\n    const newState = mergePartial(state, this.state);\n\n    if (newState) {\n      this.state = newState;\n      this.scheduleRender();\n    }\n  }\n\n  /**\n   * Changes the state by merging the given partial state.\n   * Will synchronously re-render the component if the state changes.\n   * Any elements mutation that happens within that setState call will be animated.\n   *\n   * To get notified on animation completion, use `setStateAnimatedPromise` instead.\n   */\n  setStateAnimated(state: Readonly<Partial<State>>, animationOptions: AnimationOptions): void {\n    void this.setStateAnimatedPromise(state, animationOptions);\n  }\n\n  /**\n   * Changes the state by merging the given partial state.\n   * Will synchronously re-render the component if the state changes.\n   * Any elements mutation that happens within that setState call will be animated.\n\n   * @return A promise which will be resolved when the animation finishes.\n   */\n  setStateAnimatedPromise(state: Readonly<Partial<State>>, animationOptions: AnimationOptions): Promise<void> {\n    if (this.isDestroyed()) {\n      console.error('Trying to call setStateAnimated on a destroyed component', (<any>this).constructor?.name);\n      return Promise.resolve();\n    }\n    // We pass animationOptions as any because the animate(...) overload that accepts AnimationOptions\n    // is hidden from us.\n    return this.animatePromise(animationOptions as any, () => {\n      this.setState(state);\n    });\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ComponentKey.d.ts",
    "content": "export interface ComponentKey {\n  key?: string;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ComponentPath.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { ComponentConstructor, IComponent } from './IComponent';\nimport { RequireFunc } from './IModuleLoader';\n\nexport interface ComponentPath {\n  filePath: string;\n  symbolName: string;\n}\n\nconst cache: StringMap<ComponentPath> = {};\n\nexport function parseComponentPath(componentPath: string): ComponentPath {\n  const cached = cache[componentPath];\n  if (cached) {\n    return cached;\n  }\n\n  const symbolSeparator = componentPath.indexOf('@');\n\n  if (symbolSeparator >= 0) {\n    let symbolName = componentPath.substring(0, symbolSeparator);\n    if (symbolName.indexOf('/') >= 0) {\n      // TODO(simon): Compat with legacy navigation on Android which automatically\n      // prepend the module name to the path\n      const components = symbolName.split('/');\n      symbolName = components[components.length - 1];\n    }\n\n    const filePath = componentPath.substring(symbolSeparator + 1);\n    const value = { filePath, symbolName };\n    cache[componentPath] = value;\n    return value;\n  }\n\n  const legacyModuleSeparator = componentPath.indexOf(':');\n  if (legacyModuleSeparator >= 0) {\n    const moduleName = componentPath.substring(0, legacyModuleSeparator);\n    const filePath = componentPath.substring(legacyModuleSeparator + 1);\n    return parseComponentPath(moduleName + '/' + filePath);\n  }\n\n  // Backward compatibility with .valdi syntax\n  if (componentPath.endsWith('.valdi')) {\n    const prefix = componentPath.substr(0, componentPath.length - '.valdi'.length);\n    const value = { filePath: `${prefix}.vue.generated`, symbolName: 'ComponentClass' };\n    cache[componentPath] = value;\n    return value;\n  }\n\n  throw Error(`Invalid componentPath ${componentPath}`);\n}\n\nexport function resolveComponentConstructor<T extends IComponent>(\n  require: RequireFunc,\n  componentPath: string | ComponentPath,\n): ComponentConstructor<T> {\n  let parsedPath: ComponentPath;\n  if (typeof componentPath === 'string') {\n    parsedPath = parseComponentPath(componentPath);\n  } else {\n    parsedPath = componentPath;\n  }\n\n  const module = require(parsedPath.filePath, true);\n  const constructor = module[parsedPath.symbolName];\n  if (!constructor) {\n    throw Error(`Could not resolve component ${parsedPath.symbolName} constructor in ${parsedPath.filePath}`);\n  }\n\n  return constructor;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ComponentPrototype.ts",
    "content": "import { PropertyList } from './utils/PropertyList';\n\nlet idSequence = 0;\n\nexport class ComponentPrototype {\n  readonly id: string;\n  readonly attributes: PropertyList | undefined;\n\n  constructor(id: string, attributes?: PropertyList) {\n    this.id = id;\n    this.attributes = attributes;\n  }\n\n  static newId(): string {\n    return '__component' + ++idSequence;\n  }\n\n  static instanceWithNewId(attributes?: PropertyList): ComponentPrototype {\n    return new ComponentPrototype(ComponentPrototype.newId(), attributes);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ComponentRef.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { IRenderedComponentHolder } from 'valdi_tsx/src/IRenderedComponentHolder';\nimport { IComponent } from './IComponent';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\n\nfunction compareComponents<ComponentT extends IComponent>(left: ComponentT, right: ComponentT): number {\n  const leftParentIndex = left.renderer.getComponentVirtualNode(left).parentIndex;\n  const rightParentIndex = right.renderer.getComponentVirtualNode(right).parentIndex;\n  return leftParentIndex - rightParentIndex;\n}\n\nexport class ComponentRef<ComponentT extends IComponent>\n  implements IRenderedComponentHolder<ComponentT, IRenderedVirtualNode>\n{\n  private componentByKey: StringMap<ComponentT> = {};\n  private componentByUniqueId: StringMap<ComponentT> = {};\n\n  private _cachedAllComponents?: ComponentT[];\n\n  all(): ComponentT[] {\n    let items = this._cachedAllComponents;\n    if (!items) {\n      const components: ComponentT[] = [];\n\n      for (const key in this.componentByUniqueId) {\n        const component = this.componentByUniqueId[key];\n        if (component) {\n          components.push(component);\n        }\n      }\n\n      if (components.length > 1) {\n        components.sort(compareComponents);\n      }\n      items = components;\n      this._cachedAllComponents = components;\n    }\n    return items;\n  }\n\n  single(): ComponentT | undefined {\n    const items = this.all();\n    if (!items.length) {\n      return undefined;\n    }\n    if (items.length > 1) {\n      throw Error(`Cannot get a single component from a ref which has ${items.length} elements`);\n    }\n\n    return items[0];\n  }\n\n  getForKey(key: string): ComponentT | undefined {\n    return this.componentByKey[key];\n  }\n\n  onComponentDidCreate(component: ComponentT, virtualNode: IRenderedVirtualNode): void {\n    this._cachedAllComponents = undefined;\n    this.componentByKey[virtualNode.key] = component;\n    this.componentByUniqueId[virtualNode.uniqueId] = component;\n  }\n  onComponentWillDestroy(component: ComponentT, virtualNode: IRenderedVirtualNode): void {\n    this._cachedAllComponents = undefined;\n    delete this.componentByKey[virtualNode.key];\n    delete this.componentByUniqueId[virtualNode.uniqueId];\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Console.ts",
    "content": "enum ConsoleLevel {\n  Debug = 0,\n  Log = 1,\n  Info = 2,\n  Warn = 3,\n  Error = 4,\n}\n\nimport { debugStringify } from './utils/StringUtils';\n\nexport class Console {\n  constructor(private readonly logFunction: (type: number, content: string) => void) {}\n\n  private submit(level: ConsoleLevel, args: any[]) {\n    const results: string[] = ['[JS]'];\n    for (const arg of args) {\n      results.push(debugStringify(arg, 20, true));\n    }\n    this.logFunction(level, results.join(' '));\n  }\n\n  debug(...args: any[]) {\n    this.submit(ConsoleLevel.Debug, args);\n  }\n  log(...args: any[]) {\n    this.submit(ConsoleLevel.Log, args);\n  }\n  info(...args: any[]) {\n    this.submit(ConsoleLevel.Info, args);\n  }\n  warn(...args: any[]) {\n    this.submit(ConsoleLevel.Warn, args);\n  }\n  error(...args: any[]) {\n    this.submit(ConsoleLevel.Error, args);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ConsoleRepresentable.d.ts",
    "content": "export interface ConsoleRepresentable {\n  toConsoleRepresentation(): any;\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Device.ts",
    "content": "import {\n  DeviceCancelable,\n  DeviceHapticFeedbackType,\n  DeviceSystemType,\n  getDeviceLocales,\n  getDisplayBottomInset,\n  getDisplayHeight,\n  getDisplayLeftInset,\n  getDisplayRightInset,\n  getDisplayScale,\n  getDisplayTopInset,\n  getDisplayWidth,\n  getLocaleUsesMetricSystem,\n  getModel,\n  getSystemType,\n  getUptimeMs as nativeGetUptimeMs,\n  getTimeZoneRawSecondsFromGMT as nativeGetTimeZoneRawSecondsFromGMT,\n  getSystemVersion,\n  getTimeZoneName,\n  getWindowHeight,\n  getWindowWidth,\n  getTimeZoneDstSecondsFromGMT as nativeGetTimeZoneDstSecondsFromGMT,\n  isDesktop,\n  isWeb,\n  observeDarkMode as nativeObserveDarkMode,\n  observeDisplaySizeChange as nativeObserveDisplaySizeChange,\n  observeDisplayInsetChange as nativeObserveDisplayInsetChange,\n  copyToClipBoard as nativeCopyToClipBoard,\n  performHapticFeedback as nativePerformHapticFeedback,\n  setBackButtonObserver as nativeSetBackButtonObserver\n} from 'valdi_core/src/DeviceBridge';\n\n/**\n * This lazy cache can be invalidated\n */\nclass DeviceCache<T> {\n  private value?: T;\n  constructor(private maker: () => T) {}\n  get(): T {\n    if (this.value === undefined) {\n      this.value = this.maker();\n    }\n    return this.value;\n  }\n  invalidate() {\n    this.value = undefined;\n  }\n}\n\n/**\n * Caching values, will be invalidate by observables\n */\nconst cacheSystemType = new DeviceCache<DeviceSystemType>(getSystemType);\nconst cacheSystemVersion = new DeviceCache<string>(getSystemVersion);\nconst cacheModel = new DeviceCache<string>(getModel);\nconst cacheDisplayWidth = new DeviceCache<number>(getDisplayWidth);\nconst cacheDisplayHeight = new DeviceCache<number>(getDisplayHeight);\nconst cacheDisplayScale = new DeviceCache<number>(getDisplayScale);\nconst cacheWindowWidth = new DeviceCache<number>(getWindowWidth);\nconst cacheWindowHeight = new DeviceCache<number>(getWindowHeight);\nconst cacheDisplayLeftInset = new DeviceCache<number>(getDisplayLeftInset);\nconst cacheDisplayRightInset = new DeviceCache<number>(getDisplayRightInset);\nconst cacheDisplayTopInset = new DeviceCache<number>(getDisplayTopInset);\nconst cacheDisplayBottomInset = new DeviceCache<number>(getDisplayBottomInset);\nconst cacheDeviceLocales = new DeviceCache<string[]>(getDeviceLocales ?? (() => []));\nconst cacheLocaleUsesMetricSystem = new DeviceCache<boolean>(getLocaleUsesMetricSystem ?? (() => false));\nconst cacheTimeZoneName = new DeviceCache<string>(getTimeZoneName ?? (() => 'unknown'));\nconst cacheIsDesktop = new DeviceCache<boolean>(isDesktop ?? (() => false));\nconst cacheIsWeb = new DeviceCache<boolean>(isWeb ?? (() => false));\nconst cacheIsRTL = new DeviceCache<boolean>(computeIsRTL);\n\n/**\n * ISO 639-1 language codes for right-to-left languages\n */\nconst RTL_LANGUAGES = ['ar', 'he', 'fa', 'ur', 'yi', 'ps', 'sd', 'ckb'];\n\n/**\n * Computes whether the device's primary locale uses RTL layout\n */\nfunction computeIsRTL(): boolean {\n  const locales = getDeviceLocales?.() ?? [];\n  if (locales.length === 0) return false;\n  const primaryLanguage = locales[0].split('-')[0].toLowerCase();\n  return RTL_LANGUAGES.includes(primaryLanguage);\n}\n\n/**\n * Dark mode last cached value\n */\nlet darkMode = false;\n\n/**\n * TimeZone to seconds cache map\n */\nconst cacheTimeZoneRawSecondsFromGMT: { [timezone: string]: number | undefined } = {};\nconst cacheTimeZoneDstSecondsFromGMT: { [timezone: string]: number | undefined } = {};\n\n/**\n * Observables to invalidate caches\n */\nconst observingInsets = nativeObserveDisplayInsetChange(() => {\n  cacheDisplayWidth.invalidate();\n  cacheDisplayHeight.invalidate();\n  cacheWindowWidth.invalidate();\n  cacheWindowHeight.invalidate();\n  cacheDisplayScale.invalidate();\n  cacheDisplayLeftInset.invalidate();\n  cacheDisplayRightInset.invalidate();\n  cacheDisplayTopInset.invalidate();\n  cacheDisplayBottomInset.invalidate();\n});\n\nconst observingDarkMode = nativeObserveDarkMode((isDark: boolean) => {\n  darkMode = isDark;\n});\n\n/**\n * Returns a DeviceCancelable that can be only called once.\n */\nfunction toSafeDeviceCancelable(cancelable: DeviceCancelable): DeviceCancelable {\n  return {\n    cancel: () => {\n      if (cancelable.cancel) {\n        cancelable.cancel();\n      }\n      cancelable.cancel = undefined as unknown as any;\n    },\n  };\n}\n\n/**\n * Public API for device calls\n */\nexport namespace Device {\n  /**\n   * Get whether the system is Android\n   */\n  export function isAndroid(): boolean {\n    return cacheSystemType.get() === DeviceSystemType.ANDROID;\n  }\n  /**\n   * Get whether the system is iOS\n   */\n  export function isIOS(): boolean {\n    return cacheSystemType.get() === DeviceSystemType.IOS;\n  }\n\n  /**\n   * Check whether the Device is running on a Desktop platform.\n   */\n  export function isDesktop() {\n    return cacheIsDesktop.get();\n  }\n\n  /**\n   * Check whether the Device is running on the Web platform.\n   */\n  export function isWeb(): boolean {\n    return cacheIsWeb.get();\n  }\n\n  /**\n   * Get whether the system is Android or iOS\n   */\n  export function getSystemType(): DeviceSystemType {\n    return cacheSystemType.get();\n  }\n\n  /**\n   * Copies text to clipboard\n   */\n  export function copyToClipBoard(text: string): void {\n    if (nativeCopyToClipBoard) {\n      nativeCopyToClipBoard(text);\n    }\n  }\n  /**\n   * Get the system version\n   * e.g.: iOS10\n   */\n  export function getSystemVersion(): string {\n    return cacheSystemVersion.get();\n  }\n  /**\n   * Get the model of the device\n   * e.g: iPhone7,1\n   */\n  export function getModel(): string {\n    return cacheModel.get();\n  }\n  /**\n   * Get the display width in density dependent pixels.\n   * To get the actual size in pixel, multiply that value\n   * by the display scale.\n   */\n  export function getDisplayWidth(): number {\n    return cacheDisplayWidth.get();\n  }\n  /**\n   * Get the display height in density dependent pixels.\n   * To get the actual size in pixel, multiply that value\n   * by the display scale.\n   */\n  export function getDisplayHeight(): number {\n    return cacheDisplayHeight.get();\n  }\n  /**\n   * Get the display scale ratio. Used to convert\n   * between dp and pixels.\n   */\n  export function getDisplayScale(): number {\n    return cacheDisplayScale.get();\n  }\n\n  /**\n   * Get the window width in density dependent pixels.\n   * To get the actual size in pixel, multiply that value\n   * by the display scale. All side bars are included in this value.\n   * In multitasking/splitscreen mode, this reports the dimensions of the\n   * window, not the dimensions of the physical screen.\n   */\n  export function getWindowWidth(): number {\n    return cacheWindowWidth.get();\n  }\n  /**\n   * Get the real screen height in density dependent pixels.\n   * To get the actual size in pixel, multiply that value\n   * by the display scale. All status/navigation bars are included in this value.\n   * In multitasking/splitscreen mode, this reports the dimensions of the\n   * window, not the dimensions of the physical screen.\n   */\n  export function getWindowHeight(): number {\n    return cacheWindowHeight.get();\n  }\n\n  /**\n   * Get the inset of the display. Some systems\n   * will render the app under some system provided\n   * transluscent elements or even hardware elements\n   * (like the iPhone X).\n   *\n   * WARNING:\n   *   Consider using <WithInsets/> or Device.observeDisplayInsetChange() instead\n   *   To ensure the inset size is correct at all times as this is a dynamic value\n   */\n  export function getDisplayLeftInset(): number {\n    return cacheDisplayLeftInset.get();\n  }\n  /**\n   * Get the inset of the display. Some systems\n   * will render the app under some system provided\n   * transluscent elements or even hardware elements\n   * (like the iPhone X).\n   *\n   * WARNING:\n   *   Consider using <WithInsets/> or Device.observeDisplayInsetChange() instead\n   *   To ensure the inset size is correct at all times as this is a dynamic value\n   */\n  export function getDisplayRightInset(): number {\n    return cacheDisplayRightInset.get();\n  }\n  /**\n   * Get the inset of the display. Some systems\n   * will render the app under some system provided\n   * transluscent elements or even hardware elements\n   * (like the iPhone X).\n   *\n   * WARNING:\n   *   Consider using <WithInsets/> or Device.observeDisplayInsetChange() instead\n   *   To ensure the inset size is correct at all times as this is a dynamic value\n   */\n  export function getDisplayTopInset(): number {\n    return cacheDisplayTopInset.get();\n  }\n  /**\n   * Get the inset of the display. Some systems\n   * will render the app under some system provided\n   * transluscent elements or even hardware elements\n   * (like the iPhone X).\n   *\n   * WARNING:\n   *   Consider using <WithInsets/> or Device.observeDisplayInsetChange() instead\n   *   To ensure the inset size is correct at all times as this is a dynamic value\n   */\n  export function getDisplayBottomInset(): number {\n    return cacheDisplayBottomInset.get();\n  }\n\n  /**\n   * List of preferred locales in ISO639-1 language format\n   * with an ISO3166-1 alpha-2 country code, separated by a hyphen\n   * ex:\n   * [\"en-US\", 'fr-FR']\n   */\n  export function getDeviceLocales(): string[] {\n    return cacheDeviceLocales.get();\n  }\n  /**\n   * Indicates whether the device's current locale uses the metric system\n   */\n  export function getLocaleUsesMetricSystem(): boolean {\n    return cacheLocaleUsesMetricSystem.get();\n  }\n\n  /**\n   * Check if the device's primary locale uses right-to-left (RTL) layout direction.\n   * This is determined by checking if the primary language code is in the list of\n   * known RTL languages (Arabic, Hebrew, Persian, Urdu, etc.)\n   */\n  export function isRTL(): boolean {\n    return cacheIsRTL.get();\n  }\n\n  /**\n   * Read the device's current timezone standard name\n   */\n  export function getTimeZoneName(): string {\n    // TODO(1102) - handle changes to the current timezone\n    return cacheTimeZoneName.get();\n  }\n\n  /**\n   * Returns the given time zone's offset from GMT in seconds. (EXCLUDING daylight savings)\n   * @param timeZoneName - the name of the time zone to query (Uses the local time zone if undefined)\n   */\n  export function getTimeZoneRawSecondsFromGMT(timeZoneName?: string): number {\n    // TODO(1102) - handle changes to the current timezone\n    const cacheKey = timeZoneName ?? '';\n    let cacheValue = cacheTimeZoneRawSecondsFromGMT[cacheKey];\n    if (cacheValue === undefined) {\n      if (nativeGetTimeZoneRawSecondsFromGMT) {\n        cacheValue = nativeGetTimeZoneRawSecondsFromGMT(timeZoneName);\n      } else {\n        console.error('Device.getTimeZoneRawSecondsFromGMT not implemented');\n        cacheValue = 0;\n      }\n    }\n    return cacheValue;\n  }\n\n  /**\n   * Returns the given time zone's offset from GMT in seconds. (INCLUDING daylight savings)\n   * @param timeZoneName - the name of the time zone to query (Uses the local time zone if undefined)\n   */\n  export function getTimeZoneDstSecondsFromGMT(timeZoneName?: string): number {\n    // TODO(1102) - handle changes to the current timezone \n    const cacheKey = timeZoneName ?? '';\n    let cacheValue = cacheTimeZoneDstSecondsFromGMT[cacheKey];\n    if (cacheValue === undefined) {\n      if (nativeGetTimeZoneDstSecondsFromGMT) {\n        cacheValue = nativeGetTimeZoneDstSecondsFromGMT(timeZoneName);\n      } else {\n        console.error('Device.getTimeZoneDstSecondsFromGMT not implemented');\n        cacheValue = 0;\n      }\n    }\n    return cacheValue;\n  }\n\n  /**\n   * Get current value of the device's uptime clock in milliseconds which measures\n   * the time since boot, excluding time spent while the device is asleep.\n   * On iOS, this clock is equivalent to mach_absolute_time and CACurrentMediaTime.\n   * On Android, this clock is equivalent to SystemClock.uptimeMillis().\n   */\n  export function getUptimeMs(): number {\n    return nativeGetUptimeMs?.() ?? 0;\n  }\n\n  /**\n   * Check if the device is currently using dark mode\n   * checkout: Device.observeDarkMode instead if possible\n   */\n  export function isDarkMode(): boolean {\n    return darkMode;\n  }\n\n  /**\n   * Start listening to the changes in the display's insets\n   * @param observe\n   */\n  export function observeDisplayInsetChange(observe: () => void): DeviceCancelable {\n    if (nativeObserveDisplayInsetChange) {\n      return toSafeDeviceCancelable(nativeObserveDisplayInsetChange(observe));\n    } else {\n      console.error('Device.observeDisplayInsetChange not implemented');\n      observe();\n      return {\n        cancel: () => {},\n      };\n    }\n  }\n\n  /**\n   * Start listening to the changes in the display's size\n   * @param observe\n   */\n  export function observeDisplaySizeChange(observe: () => void): DeviceCancelable {\n    if (nativeObserveDisplaySizeChange) {\n      return toSafeDeviceCancelable(nativeObserveDisplaySizeChange(observe));\n    } else {\n      observe();\n      return {\n        cancel: () => {},\n      };\n    }\n  }\n\n  /**\n   * Start listening to the device's dark mode changes\n   * @param observe\n   */\n  export function observeDarkMode(observe: (isDarkMode: boolean) => void): DeviceCancelable {\n    if (nativeObserveDarkMode) {\n      return toSafeDeviceCancelable(nativeObserveDarkMode(observe));\n    } else {\n      console.error('Device.observeDarkMode not implemented');\n      observe(false);\n      return {\n        cancel: () => {},\n      };\n    }\n  }\n\n  /**\n   * Set a back button observer on the current displayed ValdiRootView.\n   * Android only\n   */\n  export function setBackButtonObserver(backButtonObserver: (() => boolean) | undefined): void {\n    if (nativeSetBackButtonObserver) {\n      nativeSetBackButtonObserver(backButtonObserver);\n    }\n  }\n\n  /**\n   * Cannot be cached\n   * Performs haptic feedback on the device\n   */\n  export function performHapticFeedback(hapticType: DeviceHapticFeedbackType): void {\n    if (nativePerformHapticFeedback) {\n      nativePerformHapticFeedback(hapticType);\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/DeviceBridge.d.ts",
    "content": "export const enum DeviceSystemType {\n  IOS = 'ios',\n  ANDROID = 'android',\n}\n\nexport const enum DeviceHapticFeedbackType {\n  ACTION_SHEET = 'action_sheet',\n  SELECTION = 'selection',\n  VIBRATION = 'vibration',\n}\n\nexport interface DeviceCancelable {\n  cancel(): void;\n}\n\nexport function copyToClipBoard(text: string): void;\nexport function getSystemType(): DeviceSystemType;\nexport function getSystemVersion(): string;\nexport function getModel(): string;\nexport function getDisplayWidth(): number;\nexport function getDisplayHeight(): number;\nexport function getDisplayScale(): number;\nexport function getWindowWidth(): number;\nexport function getWindowHeight(): number;\nexport function getDisplayLeftInset(): number;\nexport function getDisplayRightInset(): number;\nexport function getDisplayTopInset(): number;\nexport function getDisplayBottomInset(): number;\nexport function getDeviceLocales(): string[];\nexport function getLocaleUsesMetricSystem(): boolean;\nexport function getTimeZoneName(): string;\nexport function getTimeZoneRawSecondsFromGMT(timeZoneName: string | undefined): number;\nexport function getTimeZoneDstSecondsFromGMT(timeZoneName: string | undefined): number;\nexport function getUptimeMs(): number;\nexport function performHapticFeedback(hapticType: DeviceHapticFeedbackType): void;\nexport function observeDisplayInsetChange(observe: () => void): DeviceCancelable;\nexport function observeDisplaySizeChange(observe: () => void): DeviceCancelable;\nexport function observeDarkMode(observe: (isDarkMode: boolean) => void): DeviceCancelable;\nexport function isDesktop(): boolean;\nexport function isWeb(): boolean;\nexport const setBackButtonObserver: ((observer: (() => boolean) | undefined) => void) | undefined;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ElementModifier.tsx",
    "content": "import { View } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Component } from './Component';\nimport { ElementRef } from './ElementRef';\nexport interface ViewModel extends View {}\n\n/**\n * ElementModifier provides an easy way to modify a View's appearance / behaviour without creating a physical\n * container view, or replicating view attributes in Component view models and pass them down through layers\n * of components. Example usage:\n *\n * <ElementModifer opacity={0.5}>\n *  { * <MyCustomComponent/> *}\n * </ElementModifer>\n *\n * This will set the opacity of the final view rendered by MyCustomComponent.\n * ElementModifier can be nested, e.g.\n *\n * <ElementModifer scaleX={2}>\n *  <ElementModifer opacity={0.5}>\n *    { * <MyCustomComponent/> *}\n *  </ElementModifer>\n * </ElementModifier>\n *\n * ElementModifier achieve this by aquiring the elementRef from your component and directly set its attributes.\n * Be careful setting duplicate attributes may result in unexpected results\n */\n//These are the attributes that's injected by parent container. Hard code the attributes here\n// until we figure more idomatic way to exclude these attributes.\nconst INJECTED_ATTRS = ['children'];\nexport class ElementModifier extends Component<ViewModel> {\n  elementRef = new ElementRef<View>();\n\n  onViewModelUpdate(): void {\n    for (const key in this.viewModel) {\n      const viewModelKey = key as keyof View;\n      if (typeof viewModelKey === 'string' && INJECTED_ATTRS.includes(viewModelKey)) {\n        continue;\n      }\n      this.elementRef.setAttribute(viewModelKey, this.viewModel[viewModelKey]);\n    }\n  }\n\n  onRender(): void {\n    <slot ref={this.elementRef} />;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ElementRef.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { IRenderedElementBase } from 'valdi_tsx/src/IRenderedElementBase';\nimport { AttributesFrom, IRenderedElement } from './IRenderedElement';\nimport { IRenderedElementAttributeApplier } from './IRenderedElementApplier';\n\nfunction compareElements<A, B>(left: IRenderedElement<A>, right: IRenderedElement<B>): number {\n  return left.parentIndex - right.parentIndex;\n}\n\n/**\n * An ElementRef can be used to keep track of rendered elements in a tree.\n *\n */\nexport class ElementRef<T = any> implements IRenderedElementAttributeApplier<T> {\n  // TODO: fix all current usages of new ElementRef and provide the right type parameter\n\n  private elementById: { [id: number]: IRenderedElement<T> } = {};\n  private elementByKey?: StringMap<IRenderedElement<T>>;\n  private attributes?: AttributesFrom<T>;\n\n  private _all?: IRenderedElement<T>[];\n  all(): IRenderedElement<T>[] {\n    let items = this._all;\n    if (!items) {\n      items = [];\n      this._all = items;\n\n      for (const elementId in this.elementById) {\n        const element = this.elementById[elementId];\n        if (element) {\n          items.push(element);\n        }\n      }\n\n      if (items.length > 1) {\n        items.sort(compareElements);\n      }\n    }\n    return items;\n  }\n\n  single(): IRenderedElement<T> | undefined {\n    const items = this.all();\n    if (!items.length) {\n      return undefined;\n    }\n    if (items.length > 1) {\n      throw Error(`Cannot get a single element from a ref which has ${items.length} elements`);\n    }\n\n    return items[0];\n  }\n\n  /**\n   * Get the element for the key used during the rendering.\n   * @param key\n   */\n  getForKey(key: string): IRenderedElement<T> | undefined {\n    let elementByKey = this.elementByKey;\n    if (!elementByKey) {\n      // This is the first time we request an element given its key.\n      // Construct the elementByKey dictionary so that subsequent\n      // lookup are fast.\n      elementByKey = {};\n      this.elementByKey = elementByKey;\n\n      for (const element of this.all()) {\n        elementByKey[element.key] = element;\n      }\n    }\n\n    return elementByKey[key];\n  }\n\n  /**\n   * Set an attribute on all elements.\n   * The attribute will be applied for any new elements which\n   * get attached to this element ref.\n   */\n  setAttribute<K extends keyof AttributesFrom<T>>(attributeName: K, attributeValue: AttributesFrom<T>[K]): void {\n    if (!this.attributes) {\n      this.attributes = {};\n    }\n\n    this.attributes[attributeName] = attributeValue;\n\n    for (const element of this.all()) {\n      element.setAttribute(attributeName, attributeValue);\n    }\n  }\n\n  /**\n   * Get an attribute that was previously set using setAttribute()\n   * @param attributeName\n   */\n  getAppliedAttribute(attributeName: keyof AttributesFrom<T>): any {\n    if (!this.attributes) {\n      return undefined;\n    }\n    return this.attributes[attributeName];\n  }\n\n  /**\n   * Set all elements at once.\n   * @param elements\n   */\n  setElements(elements: IRenderedElementBase<T>[]): void {\n    // We check the items which are new.\n    // We currently don't check for deletion. This means\n    // that using the setElements API in conjunction with\n    // the onElementCreated/Destroyed API will wield incorrect\n    // results.\n\n    for (const element of elements) {\n      if (!this.elementById[(element as IRenderedElement<T>).id]) {\n        this.onElementCreated(element);\n      }\n    }\n    this._all = elements as IRenderedElement<T>[];\n  }\n\n  onElementCreated(element: IRenderedElementBase<T>): void {\n    const typedElement = element as IRenderedElement<T>;\n    this._all = undefined;\n    this.elementById[typedElement.id] = typedElement;\n\n    if (this.attributes) {\n      for (const attributeName in this.attributes) {\n        // TODO: I'm not sure why this type coercion is required at the moment\n        const fixedAttributeName = attributeName as keyof AttributesFrom<T>;\n        const attributeValue = this.attributes[fixedAttributeName];\n        typedElement.setAttribute(fixedAttributeName, attributeValue);\n      }\n    }\n\n    if (this.elementByKey) {\n      this.elementByKey[typedElement.key] = typedElement;\n    }\n  }\n\n  onElementDestroyed(element: IRenderedElementBase<T>): void {\n    const typedElement = element as IRenderedElement<T>;\n    this._all = undefined;\n    delete this.elementById[typedElement.id];\n\n    if (this.elementByKey) {\n      delete this.elementByKey[typedElement.key];\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/EntryPointComponent.tsx",
    "content": "import { IRenderedComponentHolder } from 'valdi_tsx/src/IRenderedComponentHolder';\nimport { Component } from './Component';\nimport { ComponentPrototype } from './ComponentPrototype';\nimport { EntryPointRenderFunction } from './EntryPointRenderFunction';\nimport { ComponentConstructor, IComponent } from './IComponent';\nimport { IEntryPointComponent } from './IEntryPointComponent';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\nimport { IRootElementObserver } from './IRootElementObserver';\nimport { jsx } from './JSXBootstrap';\nimport { DaemonClientManager } from './debugging/DaemonClientManager';\nimport { DebugConsole } from './debugging/DebugConsole';\nimport { DefaultErrorBoundary } from './debugging/DefaultErrorBoundary';\n\ninterface EntryPointViewModel {\n  rootConstructorResolver: () => ComponentConstructor<IComponent>;\n  rootViewModel: any;\n  rootContext: any;\n  daemonClientManager?: DaemonClientManager;\n  enableErrorBoundary: boolean;\n}\n\nexport class EntryPointComponent\n  extends Component<EntryPointViewModel>\n  implements IEntryPointComponent, IRenderedComponentHolder<IComponent, IRenderedVirtualNode>, IRootElementObserver\n{\n  private rootConstructor: ComponentConstructor<IComponent> | undefined = undefined;\n\n  private rootPrototype: ComponentPrototype = jsx.makeComponentPrototype();\n\n  rootComponent: IComponent | undefined = undefined;\n\n  onCreate() {\n    this.renderer.addObserver(this);\n  }\n\n  onDestroy() {\n    this.renderer.removeObserver(this);\n  }\n\n  onRender() {\n    if (this.viewModel.enableErrorBoundary) {\n      <DefaultErrorBoundary>{this.renderRootComponent()}</DefaultErrorBoundary>;\n    } else {\n      this.renderRootComponent();\n    }\n  }\n\n  forwardCall(name: string, parameters: any[]): any {\n    const rootComponent = this.rootComponent;\n    if (!rootComponent) {\n      throw new Error(`Could not resolve component to call ${name}`);\n    }\n\n    const func = (rootComponent as any)[name] as (...parameters: any[]) => any;\n    if (!func) {\n      throw new Error(`Could not resolve function ${name}`);\n    }\n\n    return func.apply(rootComponent, parameters);\n  }\n\n  onComponentDidCreate(component: IComponent) {\n    this.rootComponent = component;\n  }\n\n  onComponentWillDestroy(component: IComponent) {\n    this.rootComponent = undefined;\n  }\n\n  private renderRootComponent() {\n    const viewModel = this.viewModel;\n\n    let RootConstructor = this.rootConstructor;\n    if (!RootConstructor) {\n      RootConstructor = viewModel.rootConstructorResolver();\n      this.rootConstructor = RootConstructor;\n    }\n\n    ///\n    /// <DANGER>\n    ///\n    /// Manually written \"post-processed\" TSX calls to use the setViewModelFull\n    /// api we don't currently have a way to access with the TSX syntax.\n    jsx.beginComponent(RootConstructor, this.rootPrototype, undefined, this);\n    if (!jsx.hasContext()) {\n      jsx.setContext(viewModel.rootContext);\n    }\n    jsx.setViewModelFull(viewModel.rootViewModel);\n    jsx.endComponent();\n    ///\n    /// </DANGER>\n    ///\n  }\n\n  onRootElementWillEndRender() {\n    if (this.viewModel.daemonClientManager) {\n      <DebugConsole daemonClientManager={this.viewModel.daemonClientManager} />;\n    }\n  }\n}\n\nexport function makeEntryPointRenderFunction(\n  resolveConstructor: () => ComponentConstructor<IComponent>,\n  enableErrorBoundary: boolean,\n  daemonClientManager: DaemonClientManager | undefined,\n): EntryPointRenderFunction {\n  return (rootRef, viewModel, context) => {\n    <EntryPointComponent\n      ref={rootRef}\n      rootConstructorResolver={resolveConstructor}\n      enableErrorBoundary={enableErrorBoundary}\n      daemonClientManager={daemonClientManager}\n      rootViewModel={viewModel}\n      rootContext={context}\n    />;\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/EntryPointRenderFunction.d.ts",
    "content": "import { IRenderedComponentHolder } from 'valdi_tsx/src/IRenderedComponentHolder';\nimport { ComponentConstructor, IComponent } from './IComponent';\nimport { IEntryPointComponent } from './IEntryPointComponent';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\n\nexport type EntryPointRenderFunction = (\n  rootRef: IRenderedComponentHolder<IEntryPointComponent, IRenderedVirtualNode>,\n  viewModel: any,\n  context: any,\n) => void;\n\nexport type EntryPointRenderFunctionFactory = (\n  resolveConstructor: () => ComponentConstructor<IComponent>,\n) => EntryPointRenderFunction;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/EntryPointViewModel.d.ts",
    "content": "import { ComponentConstructor, IComponent } from './IComponent';\nimport { DaemonClientManager } from './debugging/DaemonClientManager';\n\nexport interface EntryPointViewModel {\n  rootConstructor: ComponentConstructor<IComponent>;\n  rootViewModel: any;\n  rootContext: any;\n  daemonClientManager?: DaemonClientManager;\n  enableErrorBoundary: boolean;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/FunctionComponent.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\n\ninterface FunctionComponentViewModel {\n  render: () => void;\n}\nexport class FunctionComponent extends Component<FunctionComponentViewModel> {\n  onRender() {\n    this.viewModel.render();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/GeometricPath.ts",
    "content": "/**\n * A GeometricPath is a serialized data object\n * containing path instructions. It can be built\n * through the GeometricPathBuilder class.\n */\nexport type GeometricPath = Float64Array;\n\nconst enum GeometricPathComponent {\n  Move = 1,\n  Line = 2,\n  Quad = 3,\n  Cubic = 4,\n  RoundRect = 5,\n  Arc = 6,\n  Close = 7,\n}\n\n/**\n * Defines how the GeometricPath should scale relative to\n * the container view where it is being used.\n */\nexport const enum GeometricPathScaleType {\n  /**\n   * The path will scale such that the path will entirely\n   * fill the bounds of the container without expanding beyond it.\n   * Aspect ratio of the path will not be preserved.\n   * This is the default option.\n   */\n  Fill = 1,\n\n  /**\n   * The path will scale such that the path will fit within the bounds of the\n   * container. Aspect ratio of the path will be preserved.\n   */\n  Contain = 2,\n\n  /**\n   * The path will scale such that the path entirely fill the bounds of\n   * the container, with sides potentially expanding beyond it.\n   * Aspect ratio of the path will be preserved.\n   */\n  Cover = 3,\n\n  /**\n   * The path will not be scaled relative to the container. In this mode,\n   * the extentWidth and extentHeight will be treated as the absolute size\n   * of the path, and the path will be centered in the container.\n   */\n  None = 4,\n}\n\n/**\n * A GeometricPathBuilder is a utility class for building\n * GeometricPath objects that can be provided to the \"shape\" elements.\n * A path builder is created with an extent width and height, which represent\n * the coordinate space from which all the path operation values derive from.\n * Whenever the path is used into a container that has a different size than the\n * path extent, the path operations are scaled by applying a ratio between\n * the extent and the actual container size.\n */\nexport class GeometricPathBuilder {\n  private data: number[] = [];\n\n  constructor(extentWidth: number, extentHeight: number, scaleType?: GeometricPathScaleType) {\n    this.data.push(extentWidth, extentHeight, scaleType ?? GeometricPathScaleType.Fill);\n  }\n\n  /**\n   * Move the path position to given x and y.\n   */\n  moveTo(x: number, y: number): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Move, x, y);\n    return this;\n  }\n\n  /**\n   * Add a line from the current path position to the given x and y\n   */\n  lineTo(x: number, y: number): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Line, x, y);\n    return this;\n  }\n\n  /**\n   * Add a rect at the given x and y with the given width and height.\n   */\n  rectTo(x: number, y: number, width: number, height: number): GeometricPathBuilder {\n    return this.roundRectTo(x, y, width, height, 0, 0);\n  }\n\n  /**\n   * Add a round rect at the given x and y with the given width and height, with\n   * the rect corners rounded using radiusX and radiusY.\n   */\n  roundRectTo(\n    x: number,\n    y: number,\n    width: number,\n    height: number,\n    radiusX: number,\n    radiusY: number,\n  ): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.RoundRect, x, y, width, height, radiusX, radiusY);\n    return this;\n  }\n\n  /**\n   * Add a arc at the given centerX and centerY with the given radius, starting from\n   * the given startAngle and sweeping by the given sweepAngle.\n   * A positive sweepAngle extends the arc clockwise, a negative angle extends\n   * it counterclockwise.\n   */\n  arcTo(\n    centerX: number,\n    centerY: number,\n    radius: number,\n    startAngle: number,\n    sweepAngle: number,\n  ): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Arc, centerX, centerY, radius, startAngle, sweepAngle);\n    return this;\n  }\n\n  /**\n   * Add an oval at the given x and y with the given width and height.\n   */\n  ovalTo(x: number, y: number, width: number, height: number): GeometricPathBuilder {\n    return this.roundRectTo(x, y, width, height, width / 2.0, height / 2.0);\n  }\n\n  /**\n   * Add a cubic curve from the current path position to the given x and y,\n   * using controlX1 and controlY1 as the first control point of the curve,\n   * and controlX2 and controlY2 as the second control point of the curve.\n   */\n  cubicTo(\n    controlX1: number,\n    controlY1: number,\n    controlX2: number,\n    controlY2: number,\n    x: number,\n    y: number,\n  ): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Cubic, controlX1, controlY1, controlX2, controlY2, x, y);\n    return this;\n  }\n\n  /**\n   * Add a quad curve from the current path position to the given x and y,\n   * using controlX and controlY as the control point.\n   */\n  quadTo(controlX: number, controlY: number, x: number, y: number): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Quad, controlX, controlY, x, y);\n    return this;\n  }\n\n  /**\n   * Close the current path contour, connecting a line between the first point and the last point.\n   */\n  close(): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Close);\n    return this;\n  }\n\n  /**\n   * Build and return a GeometricPath object containing the path instructions.\n   * The object can be then passed as to the \"path\" property of \"shape\" element.\n   */\n  build(): GeometricPath {\n    return Float64Array.from(this.data);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Geometry.d.ts",
    "content": "export interface Point {\n  x: number;\n  y: number;\n}\n\nexport interface Size {\n  width: number;\n  height: number;\n}\n\nexport interface Vector {\n  dx: number;\n  dy: number;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IComponent.d.ts",
    "content": "import { IComponentBase } from 'valdi_tsx/src/IComponentBase';\nimport { IRenderer } from './IRenderer';\n\nexport interface IComponent<ViewModel = any, Context = any> extends IComponentBase<ViewModel, Context> {\n  readonly renderer: IRenderer;\n}\n\nexport declare type ComponentConstructor<T extends IComponent<ViewModel, Context>, ViewModel = any, Context = any> = {\n  new (renderer: IRenderer, viewModel: ViewModel, context: Context): T;\n\n  disallowNullViewModel?: boolean;\n};\n\n// type ComponentConstructor<T extends IComponent> = Function & { prototype: T };\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IComponentRenderObserver.d.ts",
    "content": "import { IComponent } from './IComponent';\n\nexport interface IComponentRenderObserver {\n  /**\n   * Called whenever one of the component starts off a new rendering pass.\n   * Note that this called just when a component initiates a completely new\n   * render, it is not called for every components being rendered as part\n   * of a single render pass.\n   *\n   * @param component the component that initiated the rendering.\n   */\n  onComponentWillRerender(component: IComponent): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IEntryPointComponent.d.ts",
    "content": "import { IComponent } from './IComponent';\n\nexport interface IEntryPointComponent extends IComponent {\n  rootComponent: IComponent | undefined;\n  forwardCall(callName: string, parameters: any[]): any;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IModuleLoader.d.ts",
    "content": "import { GetOrCreateSourceMapFunc } from 'source_map/src/StackSymbolicator';\n\nexport type RequireFunc = (path: string, disableProxy?: boolean, disableSyncDependencies?: boolean) => any;\nexport type OnHotReloadCallback = () => void;\nexport type OnHotReloadFunc = (\n  observingModule: { path: string },\n  path: string,\n  callback: OnHotReloadCallback,\n) => () => void;\nexport type OnModuleRegisteredCallback = () => void;\n\nexport interface IModuleLoader {\n  load: RequireFunc;\n  unload(paths: string[], isHotReloading: boolean, disableHotReloadDenyList: boolean): string[];\n  unloadAllUnused(modulesToKeep: string[]): string[];\n  preload(path: string, maxDepth: number): void;\n  isLoaded(path: string): boolean;\n  hasModuleFactory(path: string): boolean;\n  unregisterModule(path: string): void;\n  registerModule(path: string, factory: () => any): void;\n  onModuleRegistered(path: string, callback: OnModuleRegisteredCallback): void;\n  resolveRequire(path: string): RequireFunc;\n  getOrCreateSourceMap: GetOrCreateSourceMapFunc;\n  onHotReload: OnHotReloadFunc;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRenderedElement.d.ts",
    "content": "import { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { IRenderedElementBase } from 'valdi_tsx/src/IRenderedElementBase';\nimport { NativeNode } from 'valdi_tsx/src/NativeNode';\nimport { NativeView } from 'valdi_tsx/src/NativeView';\nimport { IComponent } from './IComponent';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\nimport { IRenderer } from './IRenderer';\nimport { PropertyList } from './utils/PropertyList';\n\nexport type ElementId = number;\n\nexport type StringKeyOf<T> = Extract<keyof T, string>;\n\nexport type AttributesFrom<T> = { [K in StringKeyOf<T>]?: T[K] };\n\n/**\n * IRenderedElement represents an element (a view, label, layout) that has been rendered.\n * Elements are used to layout and display the user interface. The IRenderedElement API\n * allows to inspect and modify the elements tree at runtime. Elements are NOT Components,\n * Components are building blocks that manages and create elements.\n */\nexport interface IRenderedElement<T = any> extends IRenderedElementBase<T> {\n  /**\n   * The generated id for this element.\n   * The id is unique within a renderer context.\n   */\n  readonly id: ElementId;\n\n  /**\n   * The key, which was either automatically generated by\n   * the renderer or manually provided.\n   */\n  readonly key: string;\n\n  /**\n   * The XML node tag, like 'view', 'layout' etc...\n   */\n  readonly tag: string;\n\n  /**\n   * The native view class name\n   */\n  readonly viewClass: string;\n\n  /**\n   * All the children elements emitted from this node.\n   */\n  readonly children: IRenderedElement[];\n\n  /**\n   * The parent node containing the current node\n   */\n  readonly parent: IRenderedElement | undefined;\n\n  /**\n   * The current node position within its siblings\n   */\n  readonly parentIndex: number;\n\n  /**\n   * The renderer responsible for rendering the element\n   */\n  readonly renderer: IRenderer;\n\n  /**\n   * The component which was responsible for rendering this element.\n   */\n  readonly emittingComponent: IComponent | undefined;\n\n  /**\n   * Get the calculated frame for this element.\n   */\n  readonly frame: ElementFrame;\n\n  getAttribute<K extends keyof AttributesFrom<T>>(name: K): AttributesFrom<T>[K];\n  setAttribute<K extends keyof AttributesFrom<T>>(name: K, value: AttributesFrom<T>[K]): boolean;\n  setAttributes(attributes: PropertyList): boolean;\n  setAttributes(attributes: AttributesFrom<T>): boolean;\n\n  /**\n   * Returns a VirtualNode representation of this node.\n   */\n  getVirtualNode(): IRenderedVirtualNode;\n\n  /**\n   * Return a copy of the attribute names held by this element.\n   */\n  getAttributeNames(): (keyof AttributesFrom<T>)[];\n\n  /**\n   * Return the backing native view instance for this element.\n   * If the element has no backing view, the returned\n   * instance will be undefined.\n   * @deprecated use {@link getNativeNode} instead\n   */\n  getNativeView(): Promise<NativeView | undefined>;\n\n  /**\n   * Return the backing native node for this element.\n   * If the element has no backing node, the returned\n   * instance will be undefined.\n   */\n  getNativeNode(): NativeNode | undefined;\n\n  /**\n   * Take a bitmap snapshot of the element\n   */\n  takeSnapshot(): Promise<string | undefined>;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRenderedElementApplier.d.ts",
    "content": "import { IRenderedElementHolder } from 'valdi_tsx/src/IRenderedElementHolder';\nimport { AttributesFrom } from './IRenderedElement';\n\nexport interface IRenderedElementAttributeApplier<T> extends IRenderedElementHolder<T> {\n  setAttribute(\n    attributeName: keyof AttributesFrom<T>,\n    attributeValue: AttributesFrom<T>[keyof AttributesFrom<T>],\n  ): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRenderedVirtualNode.d.ts",
    "content": "import { IComponent } from './IComponent';\nimport { IRenderedElement } from './IRenderedElement';\nimport { IRenderer } from './IRenderer';\n\n/**\n * IRenderedVirtualNode represents a node with the rendered virtual tree.\n * Every TSX tag will emit a virtual node, which will be either a Component or an Element.\n */\nexport interface IRenderedVirtualNode {\n  /**\n   * The key, which was either automatically generated by\n   * the renderer or manually provided.\n   */\n  readonly key: string;\n\n  /**\n   * A unique string representation of the node within the render tree\n   */\n  readonly uniqueId: string;\n\n  readonly parent: IRenderedVirtualNode | undefined;\n  readonly element: IRenderedElement | undefined;\n  readonly component: IComponent | undefined;\n  readonly children: IRenderedVirtualNode[];\n  readonly parentIndex: number;\n\n  readonly renderer: IRenderer;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRenderedVirtualNodeData.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\nimport { getNodeTag } from './utils/RenderedVirtualNodeUtils';\nimport { debugStringify } from './utils/StringUtils';\n\nexport interface IRenderedElementData {\n  readonly id: number;\n  readonly frame: ElementFrame;\n  readonly attributes?: StringMap<string>;\n}\n\nexport interface IRenderedComponentData {}\n\nexport interface IRenderedVirtualNodeData {\n  /**\n   * The key, which was either automatically generated by\n   * the renderer or manually provided.\n   */\n  readonly key: string;\n\n  readonly tag: string;\n\n  readonly element: IRenderedElementData | undefined;\n  readonly component: IRenderedComponentData | undefined;\n  readonly children: IRenderedVirtualNodeData[] | undefined;\n}\n\nexport function getPathToNode(parent: IRenderedVirtualNodeData, child: IRenderedVirtualNodeData): number[] | undefined {\n  if (parent === child) {\n    return [];\n  }\n\n  if (parent.children) {\n    let index = 0;\n    for (const childOfParent of parent.children) {\n      if (childOfParent === child) {\n        return [index];\n      }\n\n      const path = getPathToNode(childOfParent, child);\n      if (path) {\n        path.unshift(index);\n        return path;\n      }\n\n      index++;\n    }\n  }\n\n  return undefined;\n}\n\nexport function fromRenderedVirtualNode(\n  node: IRenderedVirtualNode,\n  includeAttributes: boolean,\n  onCreate?: (node: IRenderedVirtualNode, data: IRenderedVirtualNodeData) => void,\n): IRenderedVirtualNodeData {\n  let children: IRenderedVirtualNodeData[] | undefined;\n\n  if (node.children.length) {\n    children = [];\n    for (const child of node.children) {\n      children.push(fromRenderedVirtualNode(child, includeAttributes, onCreate));\n    }\n  }\n\n  let element: IRenderedElementData | undefined;\n  let component: IRenderedComponentData | undefined;\n\n  if (node.element) {\n    const renderedElement = node.element;\n    let attributes: StringMap<string> | undefined;\n\n    if (includeAttributes) {\n      attributes = {};\n      for (const attributeName of renderedElement.getAttributeNames()) {\n        const attributeValue = renderedElement.getAttribute(attributeName);\n        attributes[attributeName] = debugStringify(attributeValue, 3, true);\n      }\n    }\n\n    element = {\n      id: renderedElement.id,\n      frame: renderedElement.frame,\n      attributes,\n    };\n  }\n\n  if (node.component) {\n    component = {};\n  }\n\n  const tag = getNodeTag(node);\n\n  const data = {\n    key: node.key,\n    tag,\n    element,\n    component,\n    children,\n  };\n\n  if (onCreate) {\n    onCreate(node, data);\n  }\n\n  return data;\n}\n\nexport interface RenderedVirtualNodeDataFromRoot {\n  root: IRenderedVirtualNodeData;\n  child: IRenderedVirtualNodeData;\n}\n\nexport function getVirtualNodeDataFromRootToChild(child: IRenderedVirtualNode): RenderedVirtualNodeDataFromRoot {\n  let childData: IRenderedVirtualNodeData | undefined;\n\n  let root = child;\n  while (root.parent) {\n    root = root.parent;\n  }\n\n  const rootData = fromRenderedVirtualNode(root, false, (node, data) => {\n    if (node === child) {\n      childData = data;\n    }\n  });\n\n  return {\n    root: rootData,\n    child: childData!,\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRenderer.ts",
    "content": "import { AnimationOptions } from './AnimationOptions';\nimport { CancelToken } from './CancellableAnimation';\nimport { IComponent } from './IComponent';\nimport { IComponentRenderObserver } from './IComponentRenderObserver';\nimport { IRenderedElement } from './IRenderedElement';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\nimport { IRendererEventListener } from './IRendererEventListener';\nimport { IRootElementObserver } from './IRootElementObserver';\nimport { IRuntimeIssueObserver } from './IRuntimeIssueObserver';\n\nexport type RendererObserver = Partial<IRuntimeIssueObserver> &\n  Partial<IRootElementObserver> &\n  Partial<IComponentRenderObserver>;\n\ninterface Unsubscribable {\n  unsubscribe(): void;\n}\n\nexport type ComponentDisposable = (() => void) | Unsubscribable;\n\nexport interface IRenderer {\n  contextId: string;\n  renderComponent(component: IComponent, properties: any | undefined): void;\n  isComponentAlive(component: IComponent): boolean;\n  getRootComponent(): IComponent | undefined;\n  getComponentChildren(component: IComponent): IComponent[];\n  getComponentParent(component: IComponent): IComponent | undefined;\n  getCurrentComponentInstance(): IComponent | undefined;\n  getComponentKey(component: IComponent): string;\n  getComponentRootElements(component: IComponent, collectElementsOfChildComponents: boolean): IRenderedElement[];\n  getComponentVirtualNode(component: IComponent): IRenderedVirtualNode;\n  getElementForId(elementId: number): IRenderedElement | undefined;\n  getRootVirtualNode(): IRenderedVirtualNode | undefined;\n\n  /**\n   * Registers a function which will be called right after the component is destroyed.\n   */\n  registerComponentDisposable(component: IComponent, disposable: ComponentDisposable): void;\n\n  /**\n   * Allows to make multiple changes into a single render.\n   */\n  batchUpdates(block: () => void): void;\n\n  /**\n   * Associate a set of changes with an animation\n   * @param block a block which will be executed in a render. All element mutations\n   * belong to this renderer will be animated.\n   */\n  animate(animationOptions: AnimationOptions, block: () => void): CancelToken;\n\n  cancelAnimation(token: CancelToken): void;\n\n  /**\n   * Enqueue a callback to be called when the current render completed.\n   * If the renderer is not currently rendering, the callback will be\n   * called immediately.\n   */\n  onRenderComplete(callback: () => void): void;\n\n  /**\n   * Enqueue a callback to be called whenever the next layout pass completes,\n   * which will be after all the frames of the elements are resolved.\n   */\n  onLayoutComplete(callback: () => void): void;\n\n  /**\n   * Enqueue a callback to be called when the next render completes.\n   */\n  onNextRenderComplete(callback: () => void): void;\n\n  /**\n   * Set an event listener, which will observe render events.\n   * Used for debugging.\n   */\n  setEventListener(eventListener: IRendererEventListener): void;\n\n  /**\n   * Return the event listener that is currently set on the renderer\n   */\n  getEventListener(): IRendererEventListener | undefined;\n\n  addObserver(observer: RendererObserver): void;\n\n  removeObserver(observer: RendererObserver): void;\n\n  onUncaughtError(message: string, error: Error, sourceComponent?: IComponent): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRendererDelegate.d.ts",
    "content": "import { NativeNode } from 'valdi_tsx/src/NativeNode';\nimport { NativeView } from 'valdi_tsx/src/NativeView';\nimport { AnimationOptions } from './AnimationOptions';\nimport { CancelToken } from './CancellableAnimation';\nimport { ElementFrame } from './ValdiRuntime';\nimport { Style } from './Style';\n\nexport type VisibilityObserver = (\n  appearingElements: number[],\n  disappearingElements: number[],\n  viewportUpdates: number[],\n  eventTime: number,\n) => void;\nexport type FrameObserver = (updates: Float64Array) => void;\n\nexport interface IRendererDelegate {\n  onElementBecameRoot(id: number): void;\n  onElementMoved(id: number, parentId: number, parentIndex: number): void;\n  onElementCreated(id: number, viewClass: string): void;\n  onElementDestroyed(id: number): void;\n\n  onElementAttributeChangeAny(id: number, attributeName: string, attributeValue: any): void;\n  onElementAttributeChangeNumber(id: number, attributeName: string, value: number): void;\n  onElementAttributeChangeString(id: number, attributeName: string, value: string): void;\n  onElementAttributeChangeTrue(id: number, attributeName: string): void;\n  onElementAttributeChangeFalse(id: number, attributeName: string): void;\n  onElementAttributeChangeUndefined(id: number, attributeName: string): void;\n  onElementAttributeChangeStyle(id: number, attributeName: string, style: Style<any>): void;\n  onElementAttributeChangeFunction(id: number, attributeName: string, fn: () => void): void;\n\n  onNextLayoutComplete(callback: () => void): void;\n\n  onRenderStart(): void;\n  onRenderEnd(): void;\n\n  onAnimationStart(options: AnimationOptions, token: CancelToken): void;\n  onAnimationEnd(): void;\n  onAnimationCancel(token: CancelToken): void;\n\n  registerVisibilityObserver(observer: VisibilityObserver): void;\n  registerFrameObserver(observer: FrameObserver): void;\n\n  getNativeView(id: number, callback: (instance: NativeView | undefined) => void): void;\n  getNativeNode(id: number): NativeNode | undefined;\n  getElementFrame(id: number, callback: (instance: ElementFrame | undefined) => void): void;\n  takeElementSnapshot(id: number, callback: (snapshotBase64: string | undefined) => void): void;\n\n  onUncaughtError(message: string, error: Error): void;\n\n  onDestroyed(): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRendererEventListener.ts",
    "content": "export interface ComponentCtor {\n  name: string;\n}\n\n/**\n * The RendererEventListener can be set on a IRenderer instance\n * to be notified about important render events that occurs within the renderer.\n * The implementation of the event listener should be as lightweight as possible\n * to reduce performance overhead while rendering.\n */\nexport interface IRendererEventListener {\n  onRenderBegin(): void;\n  onRenderEnd(): void;\n\n  onComponentBegin(key: string, componentCtor: ComponentCtor): void;\n  onComponentEnd(): void;\n  onBypassComponentRender(): void;\n  onComponentViewModelPropertyChange(viewModelPropertyName: string): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRootComponentsManager.ts",
    "content": "export interface IRootComponentsManager {\n  create(contextId: string, componentPath: string, viewModel: any, componentContext: any): void;\n  render(contextId: string, viewModel: any): void;\n  destroy(contextId: string): void;\n  attributeChanged(contextId: string, nodeId: number, attributeName: string, attributeValue: any): void;\n  callComponentFunction(contextId: string, functionName: string, parameters: any[]): any;\n  onRuntimeIssue(contextId: string, isError: boolean, message: string): void;\n\n  stashData(): any;\n  restoreData(data: any): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRootElementObserver.d.ts",
    "content": "export interface IRootElementObserver {\n  onRootElementWillEndRender(): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/IRuntimeIssueObserver.d.ts",
    "content": "export interface IRuntimeIssueObserver {\n  onRuntimeIssue(isError: boolean, message: string): void;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Init.js",
    "content": "(function () {\n  function loadRootModule(jsEvaluator, path) {\n    var exports = {};\n    var module = {};\n    module.exports = exports;\n\n    const requireFunc = path => {\n      if (path === 'tslib') {\n        return loadRootModule(jsEvaluator, `valdi_core/src/tslib`);\n      } else {\n        throw new Error(`Invalid root module ${path}`);\n      }\n    };\n\n    jsEvaluator(path, requireFunc, module, exports);\n\n    return module.exports;\n  }\n\n  const jsEvaluator = runtime.loadJsModule;\n\n  const moduleLoader = loadRootModule(jsEvaluator, 'valdi_core/src/ModuleLoader');\n  const commonjsModuleLoaderType = runtime.moduleLoaderType === 'commonjs';\n  const instance = moduleLoader.create(jsEvaluator, runtime.getSourceMap, runtime.loadModule, commonjsModuleLoaderType);\n\n  const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\n  if (!isBrowser) {\n    // Valdi is probably alone in this js runtime, overwrite whatever globals you want\n    global.require = instance.load.bind(instance);\n  } else {\n    // Valdi is not alone on the web, don't overwrite require for everyone.\n    global.valdiRequire = instance.load.bind(instance);\n  }\n  global.moduleLoader = instance;\n  global.Long = instance.load('valdi_core/src/Long', true);\n\n  instance.load('valdi_core/src/PostInit', true).postInit();\n})();\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/JSX.ts",
    "content": "import { jsx } from './JSXBootstrap';\n\n// Backward compatibility shim.\nexport { jsx };\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/JSXBootstrap.ts",
    "content": "import { StringCache } from 'valdi_core/src/StringCache';\nimport { StringMap } from 'coreutils/src/StringMap';\nimport { IRenderedComponentHolder } from 'valdi_tsx/src/IRenderedComponentHolder';\nimport { IRenderedElementHolder } from 'valdi_tsx/src/IRenderedElementHolder';\nimport { AnyRenderFunction } from './AnyRenderFunction';\nimport { isDevBuild } from './BuildType';\nimport { resolveComponentConstructor } from './ComponentPath';\nimport { ComponentPrototype } from './ComponentPrototype';\nimport { ValdiRuntime } from './ValdiRuntime';\nimport { ComponentConstructor, IComponent } from './IComponent';\nimport { RequireFunc } from './IModuleLoader';\nimport { IRenderedElement } from './IRenderedElement';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\nimport { IRenderer } from './IRenderer';\nimport { JSXRendererDelegate } from './JSXRendererDelegate';\nimport { DeferredNodePrototype, NodePrototype, ViewClass } from './NodePrototype';\nimport * as RendererModule from './Renderer';\nimport { Renderer } from './Renderer';\nimport { RendererFactory } from './RendererFactory';\nimport { Style } from './Style';\nimport { CustomMessageHandler } from './debugging/CustomMessageHandler';\nimport {\n  DaemonClientManager,\n  IDaemonClientManagerListener,\n  ReceivedDaemonClientMessage,\n} from './debugging/DaemonClientManager';\nimport { DaemonClientMessageType, DumpHeapRequest, Messages } from './debugging/Messages';\nimport { toError } from './utils/ErrorUtils';\nimport { PropertyList, removeProperty } from './utils/PropertyList';\n\n/**\n * TypeScript to Native interactions\n */\n\ndeclare const runtime: ValdiRuntime;\n\nclass DummyComponent implements IComponent {\n  viewModel: any;\n\n  get renderer(): IRenderer {\n    return undefined!;\n  }\n\n  onCreate(): void {}\n  onRender(): void {}\n  onDestroy(): void {}\n  onViewModelUpdate(oldViewModel: any): void {}\n}\n\nconst getRenderer = RendererModule.getRenderer;\n\nconst ALLOWED_ROOT_ELEMENT_TYPES: string[] | undefined = isDevBuild() ? ['view', 'layout'] : undefined;\n\nclass JSXModule implements IDaemonClientManagerListener, RendererFactory {\n  private currentPlatform: number;\n  private resolvedViewClasses: StringMap<ViewClass> = {};\n  private messageHandlers: CustomMessageHandler[] = [];\n  private stringCache: StringCache;\n  private attributeCache: StringCache;\n  private injectedAttributeCache: StringCache;\n  readonly daemonClientManager: DaemonClientManager;\n\n  constructor() {\n    this.currentPlatform = runtime.getCurrentPlatform();\n    if (this.currentPlatform !== 1 && this.currentPlatform !== 2 && this.currentPlatform !== 3 && this.currentPlatform !== 4) {\n      throw Error(`Unrecognized platform type ${this.currentPlatform.toString()}`);\n    }\n\n    this.stringCache = new StringCache(runtime.internString);\n    this.attributeCache = new StringCache(runtime.getAttributeId);\n    this.injectedAttributeCache = new StringCache((str: string) => this.attributeCache.get(str.substr(1)));\n    this.daemonClientManager = new DaemonClientManager();\n\n    this.daemonClientManager.addListener(this);\n  }\n\n  // JSX render callbacks\n\n  beginRenderCustomView(\n    previousPrototype: NodePrototype | undefined,\n    iosClassName: string,\n    androidClassName: string,\n    key?: string,\n  ): NodePrototype {\n    let prototype = previousPrototype;\n    if (!prototype) {\n      prototype = this.makeNodePrototype('custom-view', ['iosClass', iosClassName, 'androidClass', androidClassName]);\n    }\n    this.beginRender(prototype, key);\n    return prototype;\n  }\n\n  getCurrentComponentInstance(): IComponent | undefined {\n    return getRenderer().getCurrentComponentInstance();\n  }\n\n  beginRender(prototype: NodePrototype, key?: string): void {\n    getRenderer().beginElement(prototype, key);\n  }\n\n  beginRenderIfNeeded(prototype: NodePrototype, key?: string): boolean {\n    return getRenderer().beginElementIfNeeded(prototype, key);\n  }\n\n  endRender() {\n    getRenderer().endElement();\n  }\n\n  setAttributeBool(name: string, value: boolean | undefined) {\n    getRenderer().setAttributeBool(name, value);\n  }\n\n  setAttributeNumber(name: string, value: number | undefined) {\n    getRenderer().setAttributeNumber(name, value);\n  }\n\n  setAttributeStyle<T>(name: string, value: Style<T> | undefined) {\n    getRenderer().setAttributeStyle(name, value);\n  }\n\n  setAttributeString(name: string, value: string | undefined) {\n    getRenderer().setAttributeString(name, value);\n  }\n\n  setAttributeFunction(name: string, value: () => void | undefined) {\n    getRenderer().setAttributeFunction(name, value);\n  }\n\n  setAttributeRef(ref: IRenderedElementHolder<any> | undefined) {\n    getRenderer().setAttributeRef(ref);\n  }\n\n  setAttribute(name: string, value: any): void {\n    getRenderer().setAttribute(name, value);\n  }\n\n  hasAttribute(name: string): boolean {\n    return getRenderer().hasAttribute(name);\n  }\n\n  setAttributes(attributes: PropertyList) {\n    getRenderer().setAttributes(attributes);\n  }\n\n  beginComponent<T extends IComponent>(\n    ctr: ComponentConstructor<T>,\n    prototype: ComponentPrototype,\n    key?: string,\n    componentRef?: IRenderedComponentHolder<T, IRenderedVirtualNode>,\n  ) {\n    getRenderer().beginComponent(ctr, prototype, key, componentRef);\n  }\n\n  /**\n   * @deprecated needed for VUE support only\n   */\n  beginComponentFromPath<T extends IComponent>(\n    require: RequireFunc,\n    componentPath: string | undefined,\n    key?: string,\n    componentRef?: IRenderedComponentHolder<T, IRenderedVirtualNode>,\n  ) {\n    if (componentPath) {\n      const ctr = resolveComponentConstructor<T>(require, componentPath);\n      getRenderer().beginComponentWithoutPrototype(ctr, key, componentRef);\n    } else {\n      getRenderer().beginComponentWithoutPrototype(DummyComponent, key, undefined);\n    }\n  }\n\n  /**\n   * @deprecated needed for VUE support only\n   */\n  beginComponentWithoutPrototype<T extends IComponent>(\n    ctr: ComponentConstructor<T>,\n    key?: string,\n    componentRef?: IRenderedComponentHolder<T, IRenderedVirtualNode>,\n  ) {\n    getRenderer().beginComponentWithoutPrototype(ctr, key, componentRef);\n  }\n\n  hasContext(): boolean {\n    return getRenderer().hasComponentContext();\n  }\n\n  setContext(context: any): void {\n    getRenderer().setComponentContext(context);\n  }\n\n  setComponentOnCreateObserver(observer?: (instance: any) => void) {\n    getRenderer().setComponentOnCreateObserver(observer);\n  }\n\n  setComponentOnDestroyObserver(observer?: (instance: any) => void) {\n    getRenderer().setComponentOnDestroyObserver(observer);\n  }\n\n  endComponent() {\n    getRenderer().endComponent();\n  }\n\n  renderFnComponent<ViewModel>(renderFn: (viewModel: ViewModel) => void, viewModel: ViewModel) {\n    renderFn(viewModel);\n  }\n\n  hasViewModelProperty(name: string): boolean {\n    return getRenderer().hasViewModelProperty(name);\n  }\n\n  setViewModelProperty(name: string, value: any) {\n    getRenderer().setViewModelProperty(name, value);\n  }\n\n  setViewModelProperties(properties?: StringMap<any>) {\n    getRenderer().setViewModelProperties(properties);\n  }\n\n  setViewModelFull(viewModel: any) {\n    getRenderer().setViewModelFull(viewModel);\n  }\n\n  hasInjectedAttribute(name: string): boolean {\n    return getRenderer().hasInjectedAttribute(name);\n  }\n\n  setInjectedAttribute(name: string, value: any) {\n    getRenderer().setInjectedAttribute(name, value);\n  }\n\n  /**\n   * Render the given slot name of the component.\n   * An ElementRef can be passed if the component wants to capture\n   * which elements were rendered inside.\n   * @param name\n   * @param component\n   * @param ref\n   */\n  renderNamedSlot<T = any>(name: string, component: IComponent, ref?: IRenderedElementHolder<T>, slotKey?: string) {\n    getRenderer().renderNamedSlot(name, component, ref, slotKey);\n  }\n\n  setNamedSlot(name: string, renderFunc: AnyRenderFunction | undefined) {\n    getRenderer().setNamedSlot(name, renderFunc);\n  }\n\n  renderUnnamedSlot<T = any>(component: IComponent, ref?: IRenderedElementHolder<T>, slotKey?: string) {\n    getRenderer().renderUnnamedSlot(component, ref, slotKey);\n  }\n\n  setUnnamedSlot(renderFunc: AnyRenderFunction | undefined) {\n    getRenderer().setUnnamedSlot(renderFunc);\n  }\n\n  setNamedSlots(namedSlots: StringMap<AnyRenderFunction | undefined>) {\n    getRenderer().setNamedSlots(namedSlots);\n  }\n\n  willEvaluate(desc: string, expression: string, line: number, column: number) {}\n\n  // Factory methods\n\n  makeNodePrototype(className: string, attributes?: PropertyList): NodePrototype {\n    if (className === 'custom-view') {\n      let androidClass: string | undefined;\n      let iosClass: string | undefined;\n      let macosClass: string | undefined;\n      if (attributes) {\n        androidClass = removeProperty(attributes, 'androidClass');\n        iosClass = removeProperty(attributes, 'iosClass');\n        macosClass = removeProperty(attributes, 'macosClass');\n        // webClass is left in attributes so WebValdiCustomView receives it via changeAttribute\n      }\n\n      // 1 = Android, 2 = iOS, 3 = MacOS, 4 = Web\n      if (this.currentPlatform === 4) {\n        return new NodePrototype(className, 'custom-view', attributes);\n      }\n      if (this.currentPlatform === 2) {\n        if (iosClass) {\n          return new NodePrototype(className, iosClass, attributes);\n        } else {\n          return new DeferredNodePrototype(className, attributes);\n        }\n      }\n      if (this.currentPlatform === 3) {\n        if (macosClass) {\n          return new NodePrototype(className, macosClass, attributes);\n        } else {\n          return new DeferredNodePrototype(className, attributes);\n        }\n      }\n      if (androidClass) {\n        return new NodePrototype(className, androidClass, attributes);\n      } else {\n        return new DeferredNodePrototype(className, attributes);\n      }\n    }\n\n    const viewClass = this.resolvedViewClasses[className];\n    if (!viewClass) {\n      throw Error(`No view class mapping registered for class ${className}`);\n    }\n\n    // TODO(simon): NodePrototype native registration to avoid marshalling\n    // const native = runtime.createNodePrototype(viewClass, attributes);\n\n    return new NodePrototype(className, viewClass, attributes);\n  }\n\n  makeComponentPrototype(attributes?: PropertyList) {\n    return ComponentPrototype.instanceWithNewId(attributes);\n  }\n\n  makeRenderer(treeId: string): Renderer {\n    return this.makeRendererWithAllowedRootElementTypes(ALLOWED_ROOT_ELEMENT_TYPES, treeId);\n  }\n\n  makeRendererWithAllowedRootElementTypes(allowedRootElementTypes: string[] | undefined, treeId: string): Renderer {\n    const useTopDownMoveOrder = typeof runtime.useTopDownMoveOrder === 'boolean' ? runtime.useTopDownMoveOrder : false;\n    return new Renderer(\n      treeId,\n      allowedRootElementTypes,\n      new JSXRendererDelegate(treeId, this.stringCache, this.attributeCache, this.injectedAttributeCache),\n      useTopDownMoveOrder,\n    );\n  }\n\n  // Native elements\n\n  registerNativeElement(className: string, iosClass: string, androidClass: string): void {\n    let viewClassName: string;\n    if (this.currentPlatform === 2) {\n      viewClassName = iosClass;\n    } else if (this.currentPlatform === 1) {\n      viewClassName = androidClass;\n    } else {\n      viewClassName = className;\n    }\n\n    // TODO(simon): ViewClass native registration to avoid marshalling\n\n    // const viewClass = runtime.getViewClass(viewClassName);\n    this.resolvedViewClasses[className] = viewClassName;\n  }\n\n  // Component registration\n\n  /**\n   * Evaluates the given function, and returns all the elements\n   * which were rendered during that call.\n   */\n  render(renderFunc: () => (() => void) | undefined): IRenderedElement[] {\n    if (!renderFunc) {\n      return [];\n    }\n\n    return getRenderer().render(renderFunc);\n  }\n\n  onDaemonClientEvent(eventType: number, daemonClient: any, payload?: any): void {\n    this.daemonClientManager.onEvent(eventType, daemonClient, payload);\n  }\n\n  addCustomMessageHandler(messageHandler: CustomMessageHandler) {\n    this.messageHandlers.push(messageHandler);\n  }\n\n  removeCustomMessageHandler(messageHandler: CustomMessageHandler) {\n    const idx = this.messageHandlers.indexOf(messageHandler);\n    if (idx >= 0) {\n      this.messageHandlers.splice(idx, 1);\n    }\n  }\n\n  // IDaemonClientManagerListener\n\n  onMessage(message: ReceivedDaemonClientMessage) {\n    if (message.message.type === DaemonClientMessageType.CUSTOM_REQUEST) {\n      const body = message.message.body;\n      for (const messageHandler of this.messageHandlers) {\n        const promise = messageHandler.messageReceived(body.identifier, body.data);\n        if (promise) {\n          // Found a handler\n          promise\n            .then(data => {\n              message.respond(requestId => Messages.customMessageResponse(requestId, { handled: true, data }));\n            })\n            .catch(err => {\n              message.respond(requestId => Messages.errorResponse(requestId, err));\n            });\n          return;\n        }\n      }\n\n      message.respond(requestId => Messages.customMessageResponse(requestId, { handled: false, data: undefined }));\n    } else if (message.message.type === DaemonClientMessageType.DUMP_HEAP_REQUEST) {\n      const dumpHeapRequest = (message.message as DumpHeapRequest).body;\n      if (!runtime.dumpHeap) {\n        message.respond(requestId => Messages.errorResponse(requestId, `Runtime does not support dumping heap`));\n        return;\n      }\n\n      const doDumpHeap = () => {\n        const memoryStatistics = runtime.dumpMemoryStatistics();\n\n        let response: (requestId: string) => string;\n        try {\n          const dumpedHeap = runtime.dumpHeap!();\n          const heapDumpJSON = runtime.bytesToString(dumpedHeap);\n          response = requestId =>\n            Messages.dumpHeapResponse(requestId, {\n              memoryUsageBytes: memoryStatistics.memoryUsageBytes,\n              heapDumpJSON,\n            });\n        } catch (err: unknown) {\n          response = requestId => Messages.errorResponse(requestId, toError(err));\n        }\n        message.respond(response);\n      };\n\n      if (dumpHeapRequest.performGC) {\n        runtime.performGC();\n        setTimeout(doDumpHeap);\n      } else {\n        doDumpHeap();\n      }\n    }\n  }\n}\n\nexport const jsx = new JSXModule();\n\njsx.registerNativeElement('layout', 'Layout', 'Layout');\njsx.registerNativeElement('view', 'SCValdiView', 'com.snap.valdi.views.ValdiView');\njsx.registerNativeElement('label', 'SCValdiLabel', 'com.snap.valdi.views.ValdiTextView');\njsx.registerNativeElement('scroll', 'SCValdiScrollView', 'com.snap.valdi.views.ValdiScrollView');\njsx.registerNativeElement('image', 'SCValdiImageView', 'com.snap.valdi.views.ValdiImageView');\njsx.registerNativeElement('video', 'SCValdiVideoView', 'com.snap.valdi.views.ValdiVideoView');\njsx.registerNativeElement('button', 'UIButton', 'android.widget.Button');\njsx.registerNativeElement('spinner', 'SCValdiSpinnerView', 'com.snap.valdi.views.ValdiSpinnerView');\njsx.registerNativeElement('blur', 'SCValdiBlurView', 'com.snap.valdi.views.ValdiView');\njsx.registerNativeElement('textfield', 'SCValdiTextField', 'com.snap.valdi.views.ValdiEditText');\njsx.registerNativeElement('textview', 'SCValdiTextView', 'com.snap.valdi.views.ValdiEditTextMultiline');\njsx.registerNativeElement('shape', 'SCValdiShapeView', 'com.snap.valdi.views.ShapeView');\njsx.registerNativeElement(\n  'animatedimage',\n  'SCValdiAnimatedContentView',\n  'com.snap.valdi.views.AnimatedImageView',\n);\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/JSXRendererDelegate.ts",
    "content": "import { StringCache } from 'valdi_core/src/StringCache';\nimport { MergeType } from 'valdi_core/src/utility_types/MergeType';\nimport { getObjectId } from 'valdi_core/src/utils/IdentifyableObject';\nimport { StringMap } from 'coreutils/src/StringMap';\nimport { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { NativeNode } from 'valdi_tsx/src/NativeNode';\nimport { NativeView } from 'valdi_tsx/src/NativeView';\nimport { AnimationCurve, AnimationOptions } from './AnimationOptions';\nimport { CancelToken } from './CancellableAnimation';\nimport { ValdiRuntime } from './ValdiRuntime';\nimport { FrameObserver, IRendererDelegate, VisibilityObserver } from './IRendererDelegate';\nimport { NativeFrameObserver, NativeVisibilityObserver } from './RenderRequest';\nimport { Style } from './Style';\nimport { Buffer } from './utils/Buffer';\n\ndeclare const runtime: ValdiRuntime;\n\nconst enum RenderRequestEntryType {\n  CREATE_ELEMENT = 1,\n  DESTROY_ELEMENT = 2,\n  SET_ROOT_ELEMENT = 3,\n  MOVE_ELEMENT_TO_PARENT = 4,\n  SET_ATTRIBUTE_UNDEFINED = 5,\n  SET_ATTRIBUTE_NULL = 6,\n  SET_ATTRIBUTE_FALSE = 7,\n  SET_ATTRIBUTE_TRUE = 8,\n  SET_ATTRIBUTE_INT = 9,\n  SET_ATTRIBUTE_DOUBLE = 10,\n  SET_ATTRIBUTE_ARRAY = 11,\n  SET_ATTRIBUTE_STYLE = 12,\n  SET_ATTRIBUTE_ATTACHED_VALUE = 13,\n  BEGIN_ANIMATIONS = 14,\n  END_ANIMATIONS = 15,\n  ON_LAYOUT_COMPLETE = 16,\n  CANCEL_ANIMATION = 17,\n}\n\nconst bufferPool = [new Buffer(512)];\n\nexport class JSXRendererDelegate implements IRendererDelegate {\n  private treeId: string;\n  private destroyed: boolean;\n  private stringCache: StringCache;\n  private attributeCache: StringCache;\n  private injectedAttributeCache: StringCache;\n\n  private buffer: Buffer;\n  private attachedValues: any[];\n  private attachedValueIndexByString: StringMap<number>;\n  private attachedValueIndexByObjectId: { [objectId: number]: number };\n  private renderStartTime?: number;\n  private pendingVisibilityObserver?: NativeVisibilityObserver;\n  private pendingFrameObserver?: NativeFrameObserver;\n\n  constructor(\n    treeId: string,\n    stringCache: StringCache,\n    attributeCache: StringCache,\n    injectedAttributeCache: StringCache,\n  ) {\n    this.treeId = treeId;\n    this.destroyed = false;\n    this.stringCache = stringCache;\n    this.attributeCache = attributeCache;\n    this.injectedAttributeCache = injectedAttributeCache;\n    this.buffer = new Buffer(512);\n    this.attachedValues = [];\n    this.attachedValueIndexByString = {};\n    this.attachedValueIndexByObjectId = {};\n  }\n\n  onDestroyed() {\n    this.destroyed = true;\n  }\n\n  onElementCreated(id: number, viewClass: string): void {\n    this.buffer.putUint32_2(RenderRequestEntryType.CREATE_ELEMENT | (id << 8), this.stringCache.get(viewClass));\n  }\n\n  onElementDestroyed(id: number): void {\n    this.buffer.putUint32(RenderRequestEntryType.DESTROY_ELEMENT | (id << 8));\n  }\n\n  onElementBecameRoot(id: number): void {\n    this.buffer.putUint32(RenderRequestEntryType.SET_ROOT_ELEMENT | (id << 8));\n  }\n\n  onElementMoved(id: number, parentId: number, parentIndex: number): void {\n    this.buffer.putUint32_3(RenderRequestEntryType.MOVE_ELEMENT_TO_PARENT | (id << 8), parentId, parentIndex);\n  }\n\n  onAnimationStart(options: MergeType<AnimationOptions>, cancelToken: CancelToken) {\n    const buffer = this.buffer;\n    buffer.putUint32(RenderRequestEntryType.BEGIN_ANIMATIONS);\n\n    buffer.putFloat64(options.duration ?? 0);\n    let curve = options.curve;\n    if (!curve) {\n      curve = AnimationCurve.EaseInOut;\n    }\n\n    switch (curve) {\n      case AnimationCurve.Linear:\n        buffer.putUint32(1);\n        break;\n      case AnimationCurve.EaseIn:\n        buffer.putUint32(2);\n        break;\n      case AnimationCurve.EaseOut:\n        buffer.putUint32(3);\n        break;\n      case AnimationCurve.EaseInOut:\n        buffer.putUint32(4);\n        break;\n    }\n\n    if (options.beginFromCurrentState) {\n      buffer.putUint32(1);\n    } else {\n      buffer.putUint32(0);\n    }\n    buffer.putUint32(options.crossfade ? 1 : 0);\n\n    buffer.putFloat64(options.stiffness ?? 0);\n    buffer.putFloat64(options.damping ?? 0);\n\n    buffer.putUint32(this.getAttachedValueIndex(options.controlPoints));\n    buffer.putUint32(this.getAttachedValueIndex(options.completion));\n    buffer.putUint32(cancelToken);\n  }\n\n  onAnimationEnd() {\n    this.buffer.putUint32(RenderRequestEntryType.END_ANIMATIONS);\n  }\n\n  onAnimationCancel(token: number) {\n    this.buffer.putUint32(RenderRequestEntryType.CANCEL_ANIMATION);\n    this.buffer.putUint32(token);\n  }\n\n  private getAttachedValueIndex(value: any): number {\n    if (typeof value === 'string') {\n      // For strings, we try to reuse them as much as possible to avoid\n      // the marshalling\n      let index = this.attachedValueIndexByString[value];\n      if (!index) {\n        const attachedValues = this.attachedValues;\n        index = attachedValues.length;\n        attachedValues.push(value);\n        this.attachedValueIndexByString[value] = index;\n      }\n      return index;\n    } else {\n      const objectId = getObjectId(value);\n      if (objectId) {\n        let index = this.attachedValueIndexByObjectId[objectId];\n        if (!index) {\n          const attachedValues = this.attachedValues;\n          index = attachedValues.length;\n          attachedValues.push(value);\n          this.attachedValueIndexByObjectId[objectId] = index;\n        }\n        return index;\n      } else {\n        // For unknown objects we have to marshall all of them individually,\n        // unless we did a linear search to find them.\n        const attachedValues = this.attachedValues;\n        const attachedValuesIndex = attachedValues.length;\n        attachedValues.push(value);\n        return attachedValuesIndex;\n      }\n    }\n  }\n\n  onElementAttributeChangeNumber(id: number, attributeName: string, value: number): void {\n    const attributeNameParam = this.attributeCache.get(attributeName);\n    const buffer = this.buffer;\n\n    buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_DOUBLE | (id << 8), attributeNameParam);\n    buffer.putFloat64(value);\n  }\n\n  onElementAttributeChangeString(id: number, attributeName: string, value: string): void {\n    const attributeNameParam = this.attributeCache.get(attributeName);\n\n    let index = this.attachedValueIndexByString[value];\n    if (!index) {\n      const attachedValues = this.attachedValues;\n      index = attachedValues.length;\n      attachedValues.push(value);\n      this.attachedValueIndexByString[value] = index;\n    }\n\n    this.buffer.putUint32_3(RenderRequestEntryType.SET_ATTRIBUTE_ATTACHED_VALUE | (id << 8), attributeNameParam, index);\n  }\n\n  onElementAttributeChangeTrue(id: number, attributeName: string): void {\n    const attributeNameParam = this.attributeCache.get(attributeName);\n    this.buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_TRUE | (id << 8), attributeNameParam);\n  }\n\n  onElementAttributeChangeFalse(id: number, attributeName: string): void {\n    const attributeNameParam = this.attributeCache.get(attributeName);\n    this.buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_FALSE | (id << 8), attributeNameParam);\n  }\n\n  onElementAttributeChangeUndefined(id: number, attributeName: string): void {\n    const attributeNameParam = this.attributeCache.get(attributeName);\n    this.buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_UNDEFINED | (id << 8), attributeNameParam);\n  }\n\n  onElementAttributeChangeStyle(id: number, attributeName: string, style: Style<any>): void {\n    const attributeNameParam = this.attributeCache.get(attributeName);\n    const index = style.toNative(runtime.createCSSRule);\n\n    this.buffer.putUint32_3(RenderRequestEntryType.SET_ATTRIBUTE_STYLE | (id << 8), attributeNameParam, index);\n  }\n\n  onElementAttributeChangeFunction(id: number, attributeName: string, fn: () => void): void {\n    const attributeNameParam = this.attributeCache.get(attributeName);\n    const attachedValues = this.attachedValues;\n    const attachedValuesIndex = attachedValues.length;\n    attachedValues.push(fn);\n\n    this.buffer.putUint32_3(\n      RenderRequestEntryType.SET_ATTRIBUTE_ATTACHED_VALUE | (id << 8),\n      attributeNameParam,\n      attachedValuesIndex,\n    );\n  }\n\n  onElementAttributeChangeAny(id: number, attributeName: string, attributeValue: any): void {\n    let attributeNameParam: number;\n\n    if (attributeName[0] === '$') {\n      attributeNameParam = this.injectedAttributeCache.get(attributeName) | (1 << 24);\n    } else {\n      attributeNameParam = this.attributeCache.get(attributeName);\n    }\n\n    const buffer = this.buffer;\n\n    if (attributeValue === undefined) {\n      buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_UNDEFINED | (id << 8), attributeNameParam);\n    } else if (attributeValue === null) {\n      buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_NULL | (id << 8), attributeNameParam);\n    } else if (typeof attributeValue === 'boolean') {\n      if (!attributeValue) {\n        buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_FALSE | (id << 8), attributeNameParam);\n      } else {\n        buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_TRUE | (id << 8), attributeNameParam);\n      }\n    } else if (typeof attributeValue === 'number') {\n      buffer.putUint32_2(RenderRequestEntryType.SET_ATTRIBUTE_DOUBLE | (id << 8), attributeNameParam);\n      buffer.putFloat64(attributeValue);\n    } else if (Array.isArray(attributeValue)) {\n      buffer.putUint32_3(\n        RenderRequestEntryType.SET_ATTRIBUTE_ARRAY | (id << 8),\n        attributeNameParam,\n        attributeValue.length,\n      );\n\n      for (const value of attributeValue) {\n        const index = this.getAttachedValueIndex(value);\n\n        buffer.putUint32(index);\n      }\n    } else if (attributeValue instanceof Style) {\n      const index = attributeValue.toNative(runtime.createCSSRule);\n\n      buffer.putUint32_3(RenderRequestEntryType.SET_ATTRIBUTE_STYLE | (id << 8), attributeNameParam, index);\n    } else {\n      const attachedValuesIndex = this.getAttachedValueIndex(attributeValue);\n\n      buffer.putUint32_3(\n        RenderRequestEntryType.SET_ATTRIBUTE_ATTACHED_VALUE | (id << 8),\n        attributeNameParam,\n        attachedValuesIndex,\n      );\n    }\n  }\n\n  onNextLayoutComplete(cb: () => void) {\n    const attachedValuesIndex = this.getAttachedValueIndex(cb);\n    this.buffer.putUint32_2(RenderRequestEntryType.ON_LAYOUT_COMPLETE, attachedValuesIndex);\n  }\n\n  onRenderStart(): void {\n    this.renderStartTime = new Date().getTime();\n    this.buffer = this.getRenderBuffer();\n  }\n\n  onRenderEnd(): void {\n    const visibilityObserver = this.pendingVisibilityObserver;\n    const frameObserver = this.pendingFrameObserver;\n\n    if (this.destroyed || (this.buffer.empty() && !visibilityObserver && !frameObserver)) {\n      this.buffer.rewind();\n      this.releaseRenderBuffer(this.buffer);\n      return;\n    }\n\n    // const renderStartTime = this.renderStartTime || 0;\n    // const renderEndTime = new Date().getTime();\n\n    const descriptor = this.buffer.inner();\n    const descriptorSize = this.buffer.size() / 4;\n    this.buffer.rewind();\n\n    const values = this.attachedValues;\n    if (values.length) {\n      this.attachedValues = [];\n      this.attachedValueIndexByString = {};\n      this.attachedValueIndexByObjectId = {};\n    }\n\n    this.pendingVisibilityObserver = undefined;\n    this.pendingFrameObserver = undefined;\n\n    // this.buffer may change in submitRawRenderRequest() if it re-enters JS code\n    const buffer = this.buffer;\n\n    runtime.submitRawRenderRequest(\n      {\n        treeId: this.treeId,\n        descriptor,\n        descriptorSize,\n        values,\n        visibilityObserver,\n        frameObserver,\n      },\n      () => {\n        this.releaseRenderBuffer(buffer);\n        // const renderDuration = new Date().getTime() - renderStartTime;\n        // console.log(\n        //   `Completed render in ${renderEndTime -\n        //     renderStartTime}ms, took ${renderDuration}ms in total (buffer size ${descriptorSize * 4} bytes, ${\n        //     values.length\n        //   } attached values)`,\n        // );\n      },\n    );\n  }\n\n  private getRenderBuffer(): Buffer {\n    return bufferPool.pop() || new Buffer(512);\n  }\n\n  private releaseRenderBuffer(buffer: Buffer) {\n    bufferPool.push(buffer);\n  }\n\n  registerVisibilityObserver(observer: VisibilityObserver) {\n    this.pendingVisibilityObserver = (\n      appearingElements,\n      disappearingElements,\n      viewportUpdates,\n      acknowledger,\n      eventTime,\n    ) => {\n      try {\n        observer(appearingElements, disappearingElements, viewportUpdates, eventTime);\n      } finally {\n        // The acknowledger is used to workaround the fact that calls between the main thread and the js threads\n        // are asynchronous.\n        acknowledger();\n      }\n    };\n  }\n\n  registerFrameObserver(observer: FrameObserver) {\n    this.pendingFrameObserver = observer;\n  }\n\n  getNativeView(id: number, callback: (view: NativeView | undefined) => void) {\n    runtime.getNativeViewForElementId(this.treeId, id, view => {\n      if (view) {\n        callback(view);\n      } else {\n        callback(undefined);\n      }\n    });\n  }\n\n  getNativeNode(id: number): NativeNode | undefined {\n    return runtime.getNativeNodeForElementId(this.treeId, id);\n  }\n\n  getElementFrame(id: number, callback: (frame: ElementFrame | undefined) => void) {\n    runtime.getFrameForElementId(this.treeId, id, callback);\n  }\n\n  takeElementSnapshot(id: number, callback: (snapshotBase64: string | undefined) => void) {\n    runtime.takeElementSnapshot(this.treeId, id, callback);\n  }\n\n  onUncaughtError(message: string, error: Error) {\n    runtime.onUncaughtError(message, error);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Lazy.tsx",
    "content": "import { StatefulComponent } from 'valdi_core/src/Component';\nimport { CSSValue, Layout } from 'valdi_tsx/src/NativeTemplateElements';\nimport { ElementRef } from './ElementRef';\n\n// Has to be provided with enough attributes to lay out from outside-in\ninterface ViewModel {\n  width?: CSSValue;\n  height?: CSSValue;\n  estimatedWidth?: number;\n  estimatedHeight?: number;\n  top?: CSSValue;\n  right?: CSSValue;\n  bottom?: CSSValue;\n  left?: CSSValue;\n  /** Default to true unless estimated size is set */\n  lazyLayout?: boolean;\n  elementRef?: ElementRef<Layout>;\n}\n\ninterface State {\n  wasEverVisible: boolean;\n}\n\n/**\n * The Lazy component renders its slot when its layout node becomes visible for the first time.\n * The component must either be provided a set of attributes that allows the underlying node\n * to have a size without rendering the children, or the estimatedWidth/estimatedHeight\n * attributes should be passed such that the node can have a placeholder size while waiting\n * for the children to render. The use of \"estimatedWidth\" and \"estimatedHeight\" makes the\n * Lazy component not use \"lazyLayout\", as the node can be resized once the children are rendered.\n */\nexport class Lazy extends StatefulComponent<ViewModel, State> {\n  state: State = {\n    wasEverVisible: false,\n  };\n\n  renderContents() {\n    if (this.state.wasEverVisible) {\n      <slot />;\n    }\n  }\n\n  private onVisibilityChanged = (isVisible: boolean) => {\n    if (this.state.wasEverVisible || !isVisible) {\n      return;\n    }\n    this.setState({ wasEverVisible: true });\n  };\n\n  onRender() {\n    const viewModel = this.viewModel;\n    const estimatedWidth = viewModel.estimatedWidth;\n    const estimatedHeight = viewModel.estimatedHeight;\n    const lazyLayout = viewModel.lazyLayout ?? (estimatedWidth === undefined && estimatedHeight === undefined);\n\n    <layout\n      width={viewModel.width}\n      height={viewModel.height}\n      left={viewModel.left}\n      top={viewModel.top}\n      right={viewModel.right}\n      bottom={viewModel.bottom}\n      estimatedWidth={estimatedWidth}\n      estimatedHeight={estimatedHeight}\n      lazyLayout={lazyLayout}\n      onVisibilityChanged={this.onVisibilityChanged}\n      ref={viewModel.elementRef}\n    >\n      {this.renderContents()}\n    </layout>;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/LocalizableStrings.ts",
    "content": "import { IUnparsedLocalizableStringResolver } from './localization/IUnparsedLocalizableStringResolver';\nimport { ExternalUnparsedLocalizableStringResolver } from './localization/ExternalUnparsedLocalizableStringResolver';\nimport { LocalizableStringsModule, LocalizableStringsModuleExports } from './localization/LocalizableStringsModule';\nimport { LocalizableStringParameterType } from './localization/LocalizableString';\nimport {\n  GetCurrentLocalesFn,\n  InlineUnparsedLocalizableStringResolver,\n} from './localization/InlineUnparsedLocalizableStringResolver';\nimport { ValdiRuntime } from './ValdiRuntime';\nimport { getCurrentLocales } from './localization/LocaleResolver';\n\ndeclare const runtime: ValdiRuntime;\n\nexport function overrideLocales(exports: any, getCurrentLocales: GetCurrentLocalesFn): void {\n  const module = LocalizableStringsModule.fromExports(exports);\n  const inlineStringResolver = module.stringResolver;\n  if (!(inlineStringResolver instanceof InlineUnparsedLocalizableStringResolver)) {\n    throw new Error('Locales can only overriden on strings using the inline localization mode');\n  }\n\n  module.stringResolver = inlineStringResolver.withCurrentLocales(getCurrentLocales);\n}\n\nexport function removeOverrideLocales(exports: any) {\n  overrideLocales(exports, getCurrentLocales);\n}\n\nexport function buildModuleWithResolver(\n  unparsedLocalizableStringsResolver: IUnparsedLocalizableStringResolver,\n  strings: string[],\n  parameterTypes: (LocalizableStringParameterType[] | undefined)[],\n): LocalizableStringsModuleExports {\n  const localizableStringsModule = new LocalizableStringsModule(unparsedLocalizableStringsResolver);\n\n  const length = strings.length;\n  for (let index = 0; index < length; index++) {\n    localizableStringsModule.add(strings[index], parameterTypes[index]);\n  }\n\n  return localizableStringsModule.exports;\n}\n\n/**\n * Builds a LocalizableStringsModuleExports using localizable strings that are found\n * within the .valdimodule of the given module.\n */\nexport function buildInlineModule(\n  module: string,\n  strings: string[],\n  parameterTypes: (LocalizableStringParameterType[] | undefined)[],\n  availableLanguages: string[],\n  filePaths: string[],\n) {\n  return buildModuleWithResolver(\n    new InlineUnparsedLocalizableStringResolver(\n      availableLanguages,\n      filePaths,\n      filePath => JSON.parse(runtime.getModuleEntry(module, filePath, true) as string),\n      getCurrentLocales,\n    ),\n    strings,\n    parameterTypes,\n  );\n}\n\n/**\n * Builds a LocalizableStringsModuleExports using localizable strings that are provided\n * externally from Localizable.strings or strings.xml files.\n */\nexport function buildExternalModule(\n  module: string,\n  strings: string[],\n  parameterTypes: (LocalizableStringParameterType[] | undefined)[],\n): LocalizableStringsModuleExports {\n  return buildModuleWithResolver(new ExternalUnparsedLocalizableStringResolver(module), strings, parameterTypes);\n}\n\n/**\n * @deprecated Legacy buildModule function\n */\nexport function buildModule(\n  module: string,\n  strings: string[],\n  parameterTypes: (LocalizableStringParameterType[] | undefined)[],\n): LocalizableStringsModuleExports {\n  return buildExternalModule(module, strings, parameterTypes);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Long.js",
    "content": "module.exports = Long;\n\n/**\n * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.\n *  See the from* functions below for more convenient ways of constructing Longs.\n * @exports Long\n * @class A Long class for representing a 64 bit two's-complement integer value.\n * @param {number} low The low (signed) 32 bits of the long\n * @param {number} high The high (signed) 32 bits of the long\n * @param {boolean=} unsigned Whether unsigned or not, defaults to signed\n * @constructor\n */\nfunction Long(low, high, unsigned) {\n\n    /**\n     * The low 32 bits as a signed value.\n     * @type {number}\n     */\n    this.low = low | 0;\n\n    /**\n     * The high 32 bits as a signed value.\n     * @type {number}\n     */\n    this.high = high | 0;\n\n    /**\n     * Whether unsigned or not.\n     * @type {boolean}\n     */\n    this.unsigned = !!unsigned;\n}\n\n// The internal representation of a long is the two given signed, 32-bit values.\n// We use 32-bit pieces because these are the size of integers on which\n// Javascript performs bit-operations.  For operations like addition and\n// multiplication, we split each number into 16 bit pieces, which can easily be\n// multiplied within Javascript's floating-point representation without overflow\n// or change in sign.\n//\n// In the algorithms below, we frequently reduce the negative case to the\n// positive case by negating the input(s) and then post-processing the result.\n// Note that we must ALWAYS check specially whether those values are MIN_VALUE\n// (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as\n// a positive number, it overflows back into a negative).  Not handling this\n// case would often result in infinite recursion.\n//\n// Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*\n// methods on which they depend.\n\n/**\n * An indicator used to reliably determine if an object is a Long or not.\n * @type {boolean}\n * @const\n * @private\n */\nLong.prototype.__isLong__;\n\nObject.defineProperty(Long.prototype, \"__isLong__\", { value: true });\n\n/**\n * @function\n * @param {*} obj Object\n * @returns {boolean}\n * @inner\n */\nfunction isLong(obj) {\n    return (obj && obj[\"__isLong__\"]) === true;\n}\n\n/**\n * Tests if the specified object is a Long.\n * @function\n * @param {*} obj Object\n * @returns {boolean}\n */\nLong.isLong = isLong;\n\n/**\n * A cache of the Long representations of small integer values.\n * @type {!Object}\n * @inner\n */\nvar INT_CACHE = {};\n\n/**\n * A cache of the Long representations of small unsigned integer values.\n * @type {!Object}\n * @inner\n */\nvar UINT_CACHE = {};\n\n/**\n * @param {number} value\n * @param {boolean=} unsigned\n * @returns {!Long}\n * @inner\n */\nfunction fromInt(value, unsigned) {\n    var obj, cachedObj, cache;\n    if (unsigned) {\n        value >>>= 0;\n        if (cache = (0 <= value && value < 256)) {\n            cachedObj = UINT_CACHE[value];\n            if (cachedObj)\n                return cachedObj;\n        }\n        obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);\n        if (cache)\n            UINT_CACHE[value] = obj;\n        return obj;\n    } else {\n        value |= 0;\n        if (cache = (-128 <= value && value < 128)) {\n            cachedObj = INT_CACHE[value];\n            if (cachedObj)\n                return cachedObj;\n        }\n        obj = fromBits(value, value < 0 ? -1 : 0, false);\n        if (cache)\n            INT_CACHE[value] = obj;\n        return obj;\n    }\n}\n\n/**\n * Returns a Long representing the given 32 bit integer value.\n * @function\n * @param {number} value The 32 bit integer in question\n * @param {boolean=} unsigned Whether unsigned or not, defaults to signed\n * @returns {!Long} The corresponding Long value\n */\nLong.fromInt = fromInt;\n\n/**\n * @param {number} value\n * @param {boolean=} unsigned\n * @returns {!Long}\n * @inner\n */\nfunction fromNumber(value, unsigned) {\n    if (isNaN(value))\n        return unsigned ? UZERO : ZERO;\n    if (unsigned) {\n        if (value < 0)\n            return UZERO;\n        if (value >= TWO_PWR_64_DBL)\n            return MAX_UNSIGNED_VALUE;\n    } else {\n        if (value <= -TWO_PWR_63_DBL)\n            return MIN_VALUE;\n        if (value + 1 >= TWO_PWR_63_DBL)\n            return MAX_VALUE;\n    }\n    if (value < 0)\n        return fromNumber(-value, unsigned).neg();\n    return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);\n}\n\n/**\n * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.\n * @function\n * @param {number} value The number in question\n * @param {boolean=} unsigned Whether unsigned or not, defaults to signed\n * @returns {!Long} The corresponding Long value\n */\nLong.fromNumber = fromNumber;\n\n/**\n * @param {number} lowBits\n * @param {number} highBits\n * @param {boolean=} unsigned\n * @returns {!Long}\n * @inner\n */\nfunction fromBits(lowBits, highBits, unsigned) {\n    return new Long(lowBits, highBits, unsigned);\n}\n\n/**\n * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is\n *  assumed to use 32 bits.\n * @function\n * @param {number} lowBits The low 32 bits\n * @param {number} highBits The high 32 bits\n * @param {boolean=} unsigned Whether unsigned or not, defaults to signed\n * @returns {!Long} The corresponding Long value\n */\nLong.fromBits = fromBits;\n\n/**\n * @function\n * @param {number} base\n * @param {number} exponent\n * @returns {number}\n * @inner\n */\nvar pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)\n\n/**\n * @param {string} str\n * @param {(boolean|number)=} unsigned\n * @param {number=} radix\n * @returns {!Long}\n * @inner\n */\nfunction fromString(str, unsigned, radix) {\n    if (str.length === 0)\n        throw Error('empty string');\n    if (str === \"NaN\" || str === \"Infinity\" || str === \"+Infinity\" || str === \"-Infinity\")\n        return ZERO;\n    if (typeof unsigned === 'number') {\n        // For goog.math.long compatibility\n        radix = unsigned,\n        unsigned = false;\n    } else {\n        unsigned = !! unsigned;\n    }\n    radix = radix || 10;\n    if (radix < 2 || 36 < radix)\n        throw RangeError('radix');\n\n    var p;\n    if ((p = str.indexOf('-')) > 0)\n        throw Error('interior hyphen');\n    else if (p === 0) {\n        return fromString(str.substring(1), unsigned, radix).neg();\n    }\n\n    // Do several (8) digits each time through the loop, so as to\n    // minimize the calls to the very expensive emulated div.\n    var radixToPower = fromNumber(pow_dbl(radix, 8));\n\n    var result = ZERO;\n    for (var i = 0; i < str.length; i += 8) {\n        var size = Math.min(8, str.length - i),\n            value = parseInt(str.substring(i, i + size), radix);\n        if (size < 8) {\n            var power = fromNumber(pow_dbl(radix, size));\n            result = result.mul(power).add(fromNumber(value));\n        } else {\n            result = result.mul(radixToPower);\n            result = result.add(fromNumber(value));\n        }\n    }\n    result.unsigned = unsigned;\n    return result;\n}\n\n/**\n * Returns a Long representation of the given string, written using the specified radix.\n * @function\n * @param {string} str The textual representation of the Long\n * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to signed\n * @param {number=} radix The radix in which the text is written (2-36), defaults to 10\n * @returns {!Long} The corresponding Long value\n */\nLong.fromString = fromString;\n\n/**\n * @function\n * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val\n * @param {boolean=} unsigned\n * @returns {!Long}\n * @inner\n */\nfunction fromValue(val, unsigned) {\n    if (typeof val === 'number')\n        return fromNumber(val, unsigned);\n    if (typeof val === 'string')\n        return fromString(val, unsigned);\n    // Throws for non-objects, converts non-instanceof Long:\n    return fromBits(val.low, val.high, typeof unsigned === 'boolean' ? unsigned : val.unsigned);\n}\n\n/**\n * Converts the specified value to a Long using the appropriate from* function for its type.\n * @function\n * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value\n * @param {boolean=} unsigned Whether unsigned or not, defaults to signed\n * @returns {!Long}\n */\nLong.fromValue = fromValue;\n\n// NOTE: the compiler should inline these constant values below and then remove these variables, so there should be\n// no runtime penalty for these.\n\n/**\n * @type {number}\n * @const\n * @inner\n */\nvar TWO_PWR_16_DBL = 1 << 16;\n\n/**\n * @type {number}\n * @const\n * @inner\n */\nvar TWO_PWR_24_DBL = 1 << 24;\n\n/**\n * @type {number}\n * @const\n * @inner\n */\nvar TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;\n\n/**\n * @type {number}\n * @const\n * @inner\n */\nvar TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;\n\n/**\n * @type {number}\n * @const\n * @inner\n */\nvar TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;\n\n/**\n * @type {!Long}\n * @const\n * @inner\n */\nvar TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);\n\n/**\n * @type {!Long}\n * @inner\n */\nvar ZERO = fromInt(0);\n\n/**\n * Signed zero.\n * @type {!Long}\n */\nLong.ZERO = ZERO;\n\n/**\n * @type {!Long}\n * @inner\n */\nvar UZERO = fromInt(0, true);\n\n/**\n * Unsigned zero.\n * @type {!Long}\n */\nLong.UZERO = UZERO;\n\n/**\n * @type {!Long}\n * @inner\n */\nvar ONE = fromInt(1);\n\n/**\n * Signed one.\n * @type {!Long}\n */\nLong.ONE = ONE;\n\n/**\n * @type {!Long}\n * @inner\n */\nvar UONE = fromInt(1, true);\n\n/**\n * Unsigned one.\n * @type {!Long}\n */\nLong.UONE = UONE;\n\n/**\n * @type {!Long}\n * @inner\n */\nvar NEG_ONE = fromInt(-1);\n\n/**\n * Signed negative one.\n * @type {!Long}\n */\nLong.NEG_ONE = NEG_ONE;\n\n/**\n * @type {!Long}\n * @inner\n */\nvar MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);\n\n/**\n * Maximum signed value.\n * @type {!Long}\n */\nLong.MAX_VALUE = MAX_VALUE;\n\n/**\n * @type {!Long}\n * @inner\n */\nvar MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);\n\n/**\n * Maximum unsigned value.\n * @type {!Long}\n */\nLong.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;\n\n/**\n * @type {!Long}\n * @inner\n */\nvar MIN_VALUE = fromBits(0, 0x80000000|0, false);\n\n/**\n * Minimum signed value.\n * @type {!Long}\n */\nLong.MIN_VALUE = MIN_VALUE;\n\n/**\n * @alias Long.prototype\n * @inner\n */\nvar LongPrototype = Long.prototype;\n\n/**\n * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.\n * @this {!Long}\n * @returns {number}\n */\nLongPrototype.toInt = function toInt() {\n    return this.unsigned ? this.low >>> 0 : this.low;\n};\n\n/**\n * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).\n * @this {!Long}\n * @returns {number}\n */\nLongPrototype.toNumber = function toNumber() {\n    if (this.unsigned)\n        return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);\n    return this.high * TWO_PWR_32_DBL + (this.low >>> 0);\n};\n\n/**\n * Converts the Long to a string written in the specified radix.\n * @this {!Long}\n * @param {number=} radix Radix (2-36), defaults to 10\n * @returns {string}\n * @override\n * @throws {RangeError} If `radix` is out of range\n */\nLongPrototype.toString = function toString(radix) {\n    radix = radix || 10;\n    if (radix < 2 || 36 < radix)\n        throw RangeError('radix');\n    if (this.isZero())\n        return '0';\n    if (this.isNegative()) { // Unsigned Longs are never negative\n        if (this.eq(MIN_VALUE)) {\n            // We need to change the Long value before it can be negated, so we remove\n            // the bottom-most digit in this base and then recurse to do the rest.\n            var radixLong = fromNumber(radix),\n                div = this.div(radixLong),\n                rem1 = div.mul(radixLong).sub(this);\n            return div.toString(radix) + rem1.toInt().toString(radix);\n        } else\n            return '-' + this.neg().toString(radix);\n    }\n\n    // Do several (6) digits each time through the loop, so as to\n    // minimize the calls to the very expensive emulated div.\n    var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),\n        rem = this;\n    var result = '';\n    while (true) {\n        var remDiv = rem.div(radixToPower),\n            intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,\n            digits = intval.toString(radix);\n        rem = remDiv;\n        if (rem.isZero())\n            return digits + result;\n        else {\n            while (digits.length < 6)\n                digits = '0' + digits;\n            result = '' + digits + result;\n        }\n    }\n};\n\n/**\n * Gets the high 32 bits as a signed integer.\n * @this {!Long}\n * @returns {number} Signed high bits\n */\nLongPrototype.getHighBits = function getHighBits() {\n    return this.high;\n};\n\n/**\n * Gets the high 32 bits as an unsigned integer.\n * @this {!Long}\n * @returns {number} Unsigned high bits\n */\nLongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {\n    return this.high >>> 0;\n};\n\n/**\n * Gets the low 32 bits as a signed integer.\n * @this {!Long}\n * @returns {number} Signed low bits\n */\nLongPrototype.getLowBits = function getLowBits() {\n    return this.low;\n};\n\n/**\n * Gets the low 32 bits as an unsigned integer.\n * @this {!Long}\n * @returns {number} Unsigned low bits\n */\nLongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {\n    return this.low >>> 0;\n};\n\n/**\n * Gets the number of bits needed to represent the absolute value of this Long.\n * @this {!Long}\n * @returns {number}\n */\nLongPrototype.getNumBitsAbs = function getNumBitsAbs() {\n    if (this.isNegative()) // Unsigned Longs are never negative\n        return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();\n    var val = this.high != 0 ? this.high : this.low;\n    for (var bit = 31; bit > 0; bit--)\n        if ((val & (1 << bit)) != 0)\n            break;\n    return this.high != 0 ? bit + 33 : bit + 1;\n};\n\n/**\n * Tests if this Long's value equals zero.\n * @this {!Long}\n * @returns {boolean}\n */\nLongPrototype.isZero = function isZero() {\n    return this.high === 0 && this.low === 0;\n};\n\n/**\n * Tests if this Long's value equals zero. This is an alias of {@link Long#isZero}.\n * @returns {boolean}\n */\nLongPrototype.eqz = LongPrototype.isZero;\n\n/**\n * Tests if this Long's value is negative.\n * @this {!Long}\n * @returns {boolean}\n */\nLongPrototype.isNegative = function isNegative() {\n    return !this.unsigned && this.high < 0;\n};\n\n/**\n * Tests if this Long's value is positive.\n * @this {!Long}\n * @returns {boolean}\n */\nLongPrototype.isPositive = function isPositive() {\n    return this.unsigned || this.high >= 0;\n};\n\n/**\n * Tests if this Long's value is odd.\n * @this {!Long}\n * @returns {boolean}\n */\nLongPrototype.isOdd = function isOdd() {\n    return (this.low & 1) === 1;\n};\n\n/**\n * Tests if this Long's value is even.\n * @this {!Long}\n * @returns {boolean}\n */\nLongPrototype.isEven = function isEven() {\n    return (this.low & 1) === 0;\n};\n\n/**\n * Tests if this Long's value equals the specified's.\n * @this {!Long}\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.equals = function equals(other) {\n    if (!isLong(other))\n        other = fromValue(other);\n    if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)\n        return false;\n    return this.high === other.high && this.low === other.low;\n};\n\n/**\n * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.eq = LongPrototype.equals;\n\n/**\n * Tests if this Long's value differs from the specified's.\n * @this {!Long}\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.notEquals = function notEquals(other) {\n    return !this.eq(/* validates */ other);\n};\n\n/**\n * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.neq = LongPrototype.notEquals;\n\n/**\n * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.ne = LongPrototype.notEquals;\n\n/**\n * Tests if this Long's value is less than the specified's.\n * @this {!Long}\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.lessThan = function lessThan(other) {\n    return this.comp(/* validates */ other) < 0;\n};\n\n/**\n * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.lt = LongPrototype.lessThan;\n\n/**\n * Tests if this Long's value is less than or equal the specified's.\n * @this {!Long}\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {\n    return this.comp(/* validates */ other) <= 0;\n};\n\n/**\n * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.lte = LongPrototype.lessThanOrEqual;\n\n/**\n * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.le = LongPrototype.lessThanOrEqual;\n\n/**\n * Tests if this Long's value is greater than the specified's.\n * @this {!Long}\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.greaterThan = function greaterThan(other) {\n    return this.comp(/* validates */ other) > 0;\n};\n\n/**\n * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.gt = LongPrototype.greaterThan;\n\n/**\n * Tests if this Long's value is greater than or equal the specified's.\n * @this {!Long}\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {\n    return this.comp(/* validates */ other) >= 0;\n};\n\n/**\n * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.gte = LongPrototype.greaterThanOrEqual;\n\n/**\n * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {boolean}\n */\nLongPrototype.ge = LongPrototype.greaterThanOrEqual;\n\n/**\n * Compares this Long's value with the specified's.\n * @this {!Long}\n * @param {!Long|number|string} other Other value\n * @returns {number} 0 if they are the same, 1 if the this is greater and -1\n *  if the given one is greater\n */\nLongPrototype.compare = function compare(other) {\n    if (!isLong(other))\n        other = fromValue(other);\n    if (this.eq(other))\n        return 0;\n    var thisNeg = this.isNegative(),\n        otherNeg = other.isNegative();\n    if (thisNeg && !otherNeg)\n        return -1;\n    if (!thisNeg && otherNeg)\n        return 1;\n    // At this point the sign bits are the same\n    if (!this.unsigned)\n        return this.sub(other).isNegative() ? -1 : 1;\n    // Both are positive if at least one is unsigned\n    return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;\n};\n\n/**\n * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.\n * @function\n * @param {!Long|number|string} other Other value\n * @returns {number} 0 if they are the same, 1 if the this is greater and -1\n *  if the given one is greater\n */\nLongPrototype.comp = LongPrototype.compare;\n\n/**\n * Negates this Long's value.\n * @this {!Long}\n * @returns {!Long} Negated Long\n */\nLongPrototype.negate = function negate() {\n    if (!this.unsigned && this.eq(MIN_VALUE))\n        return MIN_VALUE;\n    return this.not().add(ONE);\n};\n\n/**\n * Negates this Long's value. This is an alias of {@link Long#negate}.\n * @function\n * @returns {!Long} Negated Long\n */\nLongPrototype.neg = LongPrototype.negate;\n\n/**\n * Returns the sum of this and the specified Long.\n * @this {!Long}\n * @param {!Long|number|string} addend Addend\n * @returns {!Long} Sum\n */\nLongPrototype.add = function add(addend) {\n    if (!isLong(addend))\n        addend = fromValue(addend);\n\n    // Divide each number into 4 chunks of 16 bits, and then sum the chunks.\n\n    var a48 = this.high >>> 16;\n    var a32 = this.high & 0xFFFF;\n    var a16 = this.low >>> 16;\n    var a00 = this.low & 0xFFFF;\n\n    var b48 = addend.high >>> 16;\n    var b32 = addend.high & 0xFFFF;\n    var b16 = addend.low >>> 16;\n    var b00 = addend.low & 0xFFFF;\n\n    var c48 = 0, c32 = 0, c16 = 0, c00 = 0;\n    c00 += a00 + b00;\n    c16 += c00 >>> 16;\n    c00 &= 0xFFFF;\n    c16 += a16 + b16;\n    c32 += c16 >>> 16;\n    c16 &= 0xFFFF;\n    c32 += a32 + b32;\n    c48 += c32 >>> 16;\n    c32 &= 0xFFFF;\n    c48 += a48 + b48;\n    c48 &= 0xFFFF;\n    return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);\n};\n\n/**\n * Returns the difference of this and the specified Long.\n * @this {!Long}\n * @param {!Long|number|string} subtrahend Subtrahend\n * @returns {!Long} Difference\n */\nLongPrototype.subtract = function subtract(subtrahend) {\n    if (!isLong(subtrahend))\n        subtrahend = fromValue(subtrahend);\n    return this.add(subtrahend.neg());\n};\n\n/**\n * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.\n * @function\n * @param {!Long|number|string} subtrahend Subtrahend\n * @returns {!Long} Difference\n */\nLongPrototype.sub = LongPrototype.subtract;\n\n/**\n * Returns the product of this and the specified Long.\n * @this {!Long}\n * @param {!Long|number|string} multiplier Multiplier\n * @returns {!Long} Product\n */\nLongPrototype.multiply = function multiply(multiplier) {\n    if (this.isZero())\n        return ZERO;\n    if (!isLong(multiplier))\n        multiplier = fromValue(multiplier);\n\n    if (multiplier.isZero())\n        return ZERO;\n    if (this.eq(MIN_VALUE))\n        return multiplier.isOdd() ? MIN_VALUE : ZERO;\n    if (multiplier.eq(MIN_VALUE))\n        return this.isOdd() ? MIN_VALUE : ZERO;\n\n    if (this.isNegative()) {\n        if (multiplier.isNegative())\n            return this.neg().mul(multiplier.neg());\n        else\n            return this.neg().mul(multiplier).neg();\n    } else if (multiplier.isNegative())\n        return this.mul(multiplier.neg()).neg();\n\n    // If both longs are small, use float multiplication\n    if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))\n        return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);\n\n    // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.\n    // We can skip products that would overflow.\n\n    var a48 = this.high >>> 16;\n    var a32 = this.high & 0xFFFF;\n    var a16 = this.low >>> 16;\n    var a00 = this.low & 0xFFFF;\n\n    var b48 = multiplier.high >>> 16;\n    var b32 = multiplier.high & 0xFFFF;\n    var b16 = multiplier.low >>> 16;\n    var b00 = multiplier.low & 0xFFFF;\n\n    var c48 = 0, c32 = 0, c16 = 0, c00 = 0;\n    c00 += a00 * b00;\n    c16 += c00 >>> 16;\n    c00 &= 0xFFFF;\n    c16 += a16 * b00;\n    c32 += c16 >>> 16;\n    c16 &= 0xFFFF;\n    c16 += a00 * b16;\n    c32 += c16 >>> 16;\n    c16 &= 0xFFFF;\n    c32 += a32 * b00;\n    c48 += c32 >>> 16;\n    c32 &= 0xFFFF;\n    c32 += a16 * b16;\n    c48 += c32 >>> 16;\n    c32 &= 0xFFFF;\n    c32 += a00 * b32;\n    c48 += c32 >>> 16;\n    c32 &= 0xFFFF;\n    c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;\n    c48 &= 0xFFFF;\n    return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);\n};\n\n/**\n * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.\n * @function\n * @param {!Long|number|string} multiplier Multiplier\n * @returns {!Long} Product\n */\nLongPrototype.mul = LongPrototype.multiply;\n\n/**\n * Returns this Long divided by the specified. The result is signed if this Long is signed or\n *  unsigned if this Long is unsigned.\n * @this {!Long}\n * @param {!Long|number|string} divisor Divisor\n * @returns {!Long} Quotient\n */\nLongPrototype.divide = function divide(divisor) {\n    if (!isLong(divisor))\n        divisor = fromValue(divisor);\n    if (divisor.isZero())\n        throw Error('division by zero');\n\n    if (this.isZero())\n        return this.unsigned ? UZERO : ZERO;\n    var approx, rem, res;\n    if (!this.unsigned) {\n        // This section is only relevant for signed longs and is derived from the\n        // closure library as a whole.\n        if (this.eq(MIN_VALUE)) {\n            if (divisor.eq(ONE) || divisor.eq(NEG_ONE))\n                return MIN_VALUE;  // recall that -MIN_VALUE == MIN_VALUE\n            else if (divisor.eq(MIN_VALUE))\n                return ONE;\n            else {\n                // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.\n                var halfThis = this.shr(1);\n                approx = halfThis.div(divisor).shl(1);\n                if (approx.eq(ZERO)) {\n                    return divisor.isNegative() ? ONE : NEG_ONE;\n                } else {\n                    rem = this.sub(divisor.mul(approx));\n                    res = approx.add(rem.div(divisor));\n                    return res;\n                }\n            }\n        } else if (divisor.eq(MIN_VALUE))\n            return this.unsigned ? UZERO : ZERO;\n        if (this.isNegative()) {\n            if (divisor.isNegative())\n                return this.neg().div(divisor.neg());\n            return this.neg().div(divisor).neg();\n        } else if (divisor.isNegative())\n            return this.div(divisor.neg()).neg();\n        res = ZERO;\n    } else {\n        // The algorithm below has not been made for unsigned longs. It's therefore\n        // required to take special care of the MSB prior to running it.\n        if (!divisor.unsigned)\n            divisor = divisor.toUnsigned();\n        if (divisor.gt(this))\n            return UZERO;\n        if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true\n            return UONE;\n        res = UZERO;\n    }\n\n    // Repeat the following until the remainder is less than other:  find a\n    // floating-point that approximates remainder / other *from below*, add this\n    // into the result, and subtract it from the remainder.  It is critical that\n    // the approximate value is less than or equal to the real value so that the\n    // remainder never becomes negative.\n    rem = this;\n    while (rem.gte(divisor)) {\n        // Approximate the result of division. This may be a little greater or\n        // smaller than the actual value.\n        approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));\n\n        // We will tweak the approximate result by changing it in the 48-th digit or\n        // the smallest non-fractional digit, whichever is larger.\n        var log2 = Math.ceil(Math.log(approx) / Math.LN2),\n            delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),\n\n        // Decrease the approximation until it is smaller than the remainder.  Note\n        // that if it is too large, the product overflows and is negative.\n            approxRes = fromNumber(approx),\n            approxRem = approxRes.mul(divisor);\n        while (approxRem.isNegative() || approxRem.gt(rem)) {\n            approx -= delta;\n            approxRes = fromNumber(approx, this.unsigned);\n            approxRem = approxRes.mul(divisor);\n        }\n\n        // We know the answer can't be zero... and actually, zero would cause\n        // infinite recursion since we would make no progress.\n        if (approxRes.isZero())\n            approxRes = ONE;\n\n        res = res.add(approxRes);\n        rem = rem.sub(approxRem);\n    }\n    return res;\n};\n\n/**\n * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.\n * @function\n * @param {!Long|number|string} divisor Divisor\n * @returns {!Long} Quotient\n */\nLongPrototype.div = LongPrototype.divide;\n\n/**\n * Returns this Long modulo the specified.\n * @this {!Long}\n * @param {!Long|number|string} divisor Divisor\n * @returns {!Long} Remainder\n */\nLongPrototype.modulo = function modulo(divisor) {\n    if (!isLong(divisor))\n        divisor = fromValue(divisor);\n\n    return this.sub(this.div(divisor).mul(divisor));\n};\n\n/**\n * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.\n * @function\n * @param {!Long|number|string} divisor Divisor\n * @returns {!Long} Remainder\n */\nLongPrototype.mod = LongPrototype.modulo;\n\n/**\n * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.\n * @function\n * @param {!Long|number|string} divisor Divisor\n * @returns {!Long} Remainder\n */\nLongPrototype.rem = LongPrototype.modulo;\n\n/**\n * Returns the bitwise NOT of this Long.\n * @this {!Long}\n * @returns {!Long}\n */\nLongPrototype.not = function not() {\n    return fromBits(~this.low, ~this.high, this.unsigned);\n};\n\n/**\n * Returns the bitwise AND of this Long and the specified.\n * @this {!Long}\n * @param {!Long|number|string} other Other Long\n * @returns {!Long}\n */\nLongPrototype.and = function and(other) {\n    if (!isLong(other))\n        other = fromValue(other);\n    return fromBits(this.low & other.low, this.high & other.high, this.unsigned);\n};\n\n/**\n * Returns the bitwise OR of this Long and the specified.\n * @this {!Long}\n * @param {!Long|number|string} other Other Long\n * @returns {!Long}\n */\nLongPrototype.or = function or(other) {\n    if (!isLong(other))\n        other = fromValue(other);\n    return fromBits(this.low | other.low, this.high | other.high, this.unsigned);\n};\n\n/**\n * Returns the bitwise XOR of this Long and the given one.\n * @this {!Long}\n * @param {!Long|number|string} other Other Long\n * @returns {!Long}\n */\nLongPrototype.xor = function xor(other) {\n    if (!isLong(other))\n        other = fromValue(other);\n    return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);\n};\n\n/**\n * Returns this Long with bits shifted to the left by the given amount.\n * @this {!Long}\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Shifted Long\n */\nLongPrototype.shiftLeft = function shiftLeft(numBits) {\n    if (isLong(numBits))\n        numBits = numBits.toInt();\n    if ((numBits &= 63) === 0)\n        return this;\n    else if (numBits < 32)\n        return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);\n    else\n        return fromBits(0, this.low << (numBits - 32), this.unsigned);\n};\n\n/**\n * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.\n * @function\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Shifted Long\n */\nLongPrototype.shl = LongPrototype.shiftLeft;\n\n/**\n * Returns this Long with bits arithmetically shifted to the right by the given amount.\n * @this {!Long}\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Shifted Long\n */\nLongPrototype.shiftRight = function shiftRight(numBits) {\n    if (isLong(numBits))\n        numBits = numBits.toInt();\n    if ((numBits &= 63) === 0)\n        return this;\n    else if (numBits < 32)\n        return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);\n    else\n        return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);\n};\n\n/**\n * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.\n * @function\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Shifted Long\n */\nLongPrototype.shr = LongPrototype.shiftRight;\n\n/**\n * Returns this Long with bits logically shifted to the right by the given amount.\n * @this {!Long}\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Shifted Long\n */\nLongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {\n    if (isLong(numBits)) numBits = numBits.toInt();\n    if ((numBits &= 63) === 0) return this;\n    if (numBits < 32) return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >>> numBits, this.unsigned);\n    if (numBits === 32) return fromBits(this.high, 0, this.unsigned);\n    return fromBits(this.high >>> (numBits - 32), 0, this.unsigned);\n};\n\n/**\n * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.\n * @function\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Shifted Long\n */\nLongPrototype.shru = LongPrototype.shiftRightUnsigned;\n\n/**\n * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.\n * @function\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Shifted Long\n */\nLongPrototype.shr_u = LongPrototype.shiftRightUnsigned;\n\n/**\n * Returns this Long with bits rotated to the left by the given amount.\n * @this {!Long}\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Rotated Long\n */\nLongPrototype.rotateLeft = function rotateLeft(numBits) {\n    var b;\n    if (isLong(numBits)) numBits = numBits.toInt();\n    if ((numBits &= 63) === 0) return this;\n    if (numBits === 32) return fromBits(this.high, this.low, this.unsigned);\n    if (numBits < 32) {\n        b = (32 - numBits);\n        return fromBits(((this.low << numBits) | (this.high >>> b)), ((this.high << numBits) | (this.low >>> b)), this.unsigned);\n    }\n    numBits -= 32;\n    b = (32 - numBits);\n    return fromBits(((this.high << numBits) | (this.low >>> b)), ((this.low << numBits) | (this.high >>> b)), this.unsigned);\n}\n/**\n * Returns this Long with bits rotated to the left by the given amount. This is an alias of {@link Long#rotateLeft}.\n * @function\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Rotated Long\n */\nLongPrototype.rotl = LongPrototype.rotateLeft;\n\n/**\n * Returns this Long with bits rotated to the right by the given amount.\n * @this {!Long}\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Rotated Long\n */\nLongPrototype.rotateRight = function rotateRight(numBits) {\n    var b;\n    if (isLong(numBits)) numBits = numBits.toInt();\n    if ((numBits &= 63) === 0) return this;\n    if (numBits === 32) return fromBits(this.high, this.low, this.unsigned);\n    if (numBits < 32) {\n        b = (32 - numBits);\n        return fromBits(((this.high << b) | (this.low >>> numBits)), ((this.low << b) | (this.high >>> numBits)), this.unsigned);\n    }\n    numBits -= 32;\n    b = (32 - numBits);\n    return fromBits(((this.low << b) | (this.high >>> numBits)), ((this.high << b) | (this.low >>> numBits)), this.unsigned);\n}\n/**\n * Returns this Long with bits rotated to the right by the given amount. This is an alias of {@link Long#rotateRight}.\n * @function\n * @param {number|!Long} numBits Number of bits\n * @returns {!Long} Rotated Long\n */\nLongPrototype.rotr = LongPrototype.rotateRight;\n\n/**\n * Converts this Long to signed.\n * @this {!Long}\n * @returns {!Long} Signed long\n */\nLongPrototype.toSigned = function toSigned() {\n    if (!this.unsigned)\n        return this;\n    return fromBits(this.low, this.high, false);\n};\n\n/**\n * Converts this Long to unsigned.\n * @this {!Long}\n * @returns {!Long} Unsigned long\n */\nLongPrototype.toUnsigned = function toUnsigned() {\n    if (this.unsigned)\n        return this;\n    return fromBits(this.low, this.high, true);\n};\n\n/**\n * Converts this Long to its byte representation.\n * @param {boolean=} le Whether little or big endian, defaults to big endian\n * @this {!Long}\n * @returns {!Array.<number>} Byte representation\n */\nLongPrototype.toBytes = function toBytes(le) {\n    return le ? this.toBytesLE() : this.toBytesBE();\n};\n\n/**\n * Converts this Long to its little endian byte representation.\n * @this {!Long}\n * @returns {!Array.<number>} Little endian byte representation\n */\nLongPrototype.toBytesLE = function toBytesLE() {\n    var hi = this.high,\n        lo = this.low;\n    return [\n        lo        & 0xff,\n        lo >>>  8 & 0xff,\n        lo >>> 16 & 0xff,\n        lo >>> 24       ,\n        hi        & 0xff,\n        hi >>>  8 & 0xff,\n        hi >>> 16 & 0xff,\n        hi >>> 24\n    ];\n};\n\n/**\n * Converts this Long to its big endian byte representation.\n * @this {!Long}\n * @returns {!Array.<number>} Big endian byte representation\n */\nLongPrototype.toBytesBE = function toBytesBE() {\n    var hi = this.high,\n        lo = this.low;\n    return [\n        hi >>> 24       ,\n        hi >>> 16 & 0xff,\n        hi >>>  8 & 0xff,\n        hi        & 0xff,\n        lo >>> 24       ,\n        lo >>> 16 & 0xff,\n        lo >>>  8 & 0xff,\n        lo        & 0xff\n    ];\n};\n\n/**\n * Creates a Long from its byte representation.\n * @param {!Array.<number>} bytes Byte representation\n * @param {boolean=} unsigned Whether unsigned or not, defaults to signed\n * @param {boolean=} le Whether little or big endian, defaults to big endian\n * @returns {Long} The corresponding Long value\n */\nLong.fromBytes = function fromBytes(bytes, unsigned, le) {\n    return le ? Long.fromBytesLE(bytes, unsigned) : Long.fromBytesBE(bytes, unsigned);\n};\n\n/**\n * Creates a Long from its little endian byte representation.\n * @param {!Array.<number>} bytes Little endian byte representation\n * @param {boolean=} unsigned Whether unsigned or not, defaults to signed\n * @returns {Long} The corresponding Long value\n */\nLong.fromBytesLE = function fromBytesLE(bytes, unsigned) {\n    return new Long(\n        bytes[0]       |\n        bytes[1] <<  8 |\n        bytes[2] << 16 |\n        bytes[3] << 24,\n        bytes[4]       |\n        bytes[5] <<  8 |\n        bytes[6] << 16 |\n        bytes[7] << 24,\n        unsigned\n    );\n};\n\n/**\n * Creates a Long from its big endian byte representation.\n * @param {!Array.<number>} bytes Big endian byte representation\n * @param {boolean=} unsigned Whether unsigned or not, defaults to signed\n * @returns {Long} The corresponding Long value\n */\nLong.fromBytesBE = function fromBytesBE(bytes, unsigned) {\n    return new Long(\n        bytes[4] << 24 |\n        bytes[5] << 16 |\n        bytes[6] <<  8 |\n        bytes[7],\n        bytes[0] << 24 |\n        bytes[1] << 16 |\n        bytes[2] <<  8 |\n        bytes[3],\n        unsigned\n    );\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ModuleLoader.ts",
    "content": "import { StringSet } from 'coreutils/src/StringSet';\nimport { ISourceMap } from 'source_map/src/ISourceMap';\nimport { IModuleLoader, OnHotReloadCallback, OnModuleRegisteredCallback, RequireFunc } from './IModuleLoader';\nimport { ValdiRuntime } from './ValdiRuntime';\nexport { RequireFunc } from './IModuleLoader';\n\ndeclare const runtime: ValdiRuntime;\n\ntype JsEvalRetryableError = string;\nexport type JSEvalResult = JsEvalRetryableError | undefined;\nexport type JsEvaluator = (path: string, require: any, module: any, exports: any) => JSEvalResult;\nexport type SourceMapResolver = (path: string) => string | undefined;\nexport type ValdiModulePreloader = (moduleName: string, completion?: (error?: string) => void) => void;\nexport type SourceMapFactory = (\n  sourceMapContent: string | undefined,\n  sourceMapLineOffset: number | undefined,\n) => ISourceMap | undefined;\n\ninterface ResolvedPath {\n  absolutePath: string;\n  directoryPaths: string[];\n}\n\nfunction normalizePath(pathEntries: string[]): string[] {\n  const out: string[] = [];\n  for (const pathEntry of pathEntries) {\n    if (pathEntry === '..') {\n      if (out.length) {\n        // Remove last item\n        out.pop();\n      } else {\n        // Keep the '..' we went outside our root\n        out.push(pathEntry);\n      }\n    } else if (pathEntry === '.' && runtime.getCurrentPlatform() !== 4) {\n      // Omit '.' from the path on Android (1), iOS (2), MacOS (3). On Web (4) keep '.' in the path.\n      continue;\n    } else {\n      out.push(pathEntry);\n    }\n  }\n  return out;\n}\n\nfunction resolveAbsoluteImport(normalizedPathEntries: string[]): ResolvedPath {\n  if (normalizedPathEntries.length === 1) {\n    // Modules at the root are considered to be from valdi_core\n    normalizedPathEntries.unshift('valdi_core', 'src');\n  }\n\n  if (normalizedPathEntries.length > 0 && normalizedPathEntries[0].startsWith('@')) {\n    // Postfix the module name with its scope to resolve name space conflicts\n    // for scoped imports\n    const scope = normalizedPathEntries.shift();\n    const moduleName = normalizedPathEntries[0];\n    normalizedPathEntries[0] = moduleName + scope;\n  }\n\n  const absolutePath = normalizedPathEntries.join('/');\n  normalizedPathEntries.pop();\n\n  return {\n    directoryPaths: normalizedPathEntries,\n    absolutePath: absolutePath,\n  };\n}\n\nfunction resolveAbsoluteImportFromPath(path: string): ResolvedPath {\n  return resolveAbsoluteImport(normalizePath(path.split('/')));\n}\n\nfunction resolvePath(path: string, fromResolvedPath: ResolvedPath): ResolvedPath {\n  const importPathEntries = path.split('/');\n  if (importPathEntries[0] === '.' || importPathEntries[0] === '..') {\n    // Relative import\n\n    const combinedPath = fromResolvedPath.directoryPaths.slice();\n    combinedPath.push(...importPathEntries);\n    const normalized = normalizePath(combinedPath);\n    return resolveAbsoluteImport(normalized);\n  } else {\n    // Absolute import\n    const normalized = normalizePath(importPathEntries);\n    return resolveAbsoluteImport(normalized);\n  }\n}\n\nconst enum ModuleStatus {\n  UNLOADED = 0,\n  LOADING = 1,\n  LOADED = 2,\n}\n\ninterface Module {\n  resolvedPath: ResolvedPath;\n  error: Error | undefined;\n  exports: any | undefined;\n  lazyExports: (() => any) | undefined;\n  status: ModuleStatus;\n  dependents: StringSet;\n  dependencies: StringSet;\n  sourceMap: ISourceMap | undefined | null;\n  sourceMapLineOffset?: number;\n  disposables?: (() => void)[];\n}\n\nfunction isModuleUsed(jsModule: Module) {\n  for (const key in jsModule.dependents) {\n    // A module is considered used if it has dependents (other modules depend on it).\n    return true;\n  }\n  return false;\n}\n\nfunction rethrow(error: Error) {\n  throw new (error as any).constructor(error.message);\n}\n\nclass RetryableError extends Error {}\n\nexport class ModuleLoader implements IModuleLoader {\n  private jsEvaluator: JsEvaluator;\n  private sourceMapResolver: SourceMapResolver | undefined;\n  private valdiModulePreloader: ValdiModulePreloader;\n  private modules: { [path: string]: Module } = {};\n  private moduleFactory: { [path: string]: () => any } = {};\n  private moduleDenylistedForLazyLoading?: StringSet;\n  private hotReloadCallbacks: { [path: string]: OnHotReloadCallback[] } = {};\n  private moduleRegisteredCallbacks: { [path: string]: OnModuleRegisteredCallback[] } = {};\n  private preloadedValdiModules: StringSet = {};\n  private commonJsCompatible: boolean;\n\n  constructor(\n    jsEvaluator: JsEvaluator,\n    sourceMapResolver: SourceMapResolver | undefined,\n    valdiModulePreloader: ValdiModulePreloader | undefined,\n    commonJsCompatible?: boolean,\n  ) {\n    this.jsEvaluator = jsEvaluator;\n    this.sourceMapResolver = sourceMapResolver;\n    // Backward compat with previous runtime version\n    this.valdiModulePreloader = valdiModulePreloader ?? (() => {});\n    this.commonJsCompatible = commonJsCompatible === true;\n  }\n\n  getDependencies(path: string): string[] {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    const dependencies: string[] = [];\n\n    const module = this.modules[resolvedPath.absolutePath];\n    if (module) {\n      for (const key in module.dependencies) {\n        dependencies.push(key);\n      }\n    }\n\n    return dependencies;\n  }\n\n  getDependents(path: string): string[] {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    const dependents: string[] = [];\n\n    const module = this.modules[resolvedPath.absolutePath];\n    if (module) {\n      for (const key in module.dependents) {\n        dependents.push(key);\n      }\n    }\n\n    return dependents;\n  }\n\n  isLoaded(path: string): boolean {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n\n    const module = this.modules[resolvedPath.absolutePath];\n    if (!module) {\n      return false;\n    }\n    return module.status !== ModuleStatus.UNLOADED;\n  }\n\n  load(path: string, disableProxy?: boolean, disableSyncDependencies?: boolean): any {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    return this.doImport(resolvedPath, undefined, !!disableProxy, !!disableSyncDependencies);\n  }\n\n  preload(path: string, maxDepth: number): void {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    this.doPreload(resolvedPath.absolutePath, 0, maxDepth, {});\n  }\n\n  private doPreload(path: string, currentDepth: number, maxDepth: number, visitedModulePaths: StringSet) {\n    if (visitedModulePaths[path]) {\n      return;\n    }\n    visitedModulePaths[path] = true;\n\n    let module = this.modules[path];\n    if (!module) {\n      this.doImport(resolveAbsoluteImportFromPath(path), undefined, false, true);\n      module = this.modules[path]!;\n    }\n\n    if (module.lazyExports) {\n      module.lazyExports();\n    }\n\n    if (currentDepth >= maxDepth) {\n      return;\n    }\n\n    for (const dependency in module.dependencies) {\n      this.doPreload(dependency, currentDepth + 1, maxDepth, visitedModulePaths);\n    }\n  }\n\n  hasModuleFactory(path: string): boolean {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    return this.moduleFactory[resolvedPath.absolutePath] !== undefined;\n  }\n\n  registerModule(path: string, factory: () => any): void {\n    const absolutePath = resolveAbsoluteImportFromPath(path).absolutePath;\n    this.moduleFactory[absolutePath] = factory;\n\n    const callbacks = this.moduleRegisteredCallbacks[absolutePath];\n    if (callbacks) {\n      delete this.moduleRegisteredCallbacks[absolutePath];\n\n      for (const callback of callbacks) {\n        callback();\n      }\n    }\n  }\n\n  unregisterModule(path: string) {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    const absolutePath = resolvedPath.absolutePath;\n    if (this.moduleFactory[absolutePath]) {\n      delete this.moduleFactory[absolutePath];\n    }\n  }\n\n  onModuleRegistered(path: string, callback: () => void): void {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    if (this.moduleFactory[resolvedPath.absolutePath]) {\n      callback();\n    } else {\n      let callbacks = this.moduleRegisteredCallbacks[resolvedPath.absolutePath];\n      if (!callbacks) {\n        callbacks = [];\n        this.moduleRegisteredCallbacks[resolvedPath.absolutePath] = callbacks;\n      }\n      callbacks.push(callback);\n    }\n  }\n\n  unloadAllUnused(modulesToKeep: string[]): string[] {\n    const unloadedModules: StringSet = {};\n    const indexedModulesToKeep: StringSet = {};\n    for (const path of modulesToKeep) {\n      const absolutePath = resolveAbsoluteImportFromPath(path).absolutePath;\n      indexedModulesToKeep[absolutePath] = true;\n    }\n\n    // eslint-disable-next-line no-empty\n    while (this.unloadNextModule(indexedModulesToKeep, unloadedModules)) {}\n\n    const out: string[] = [];\n    for (const jsModule in unloadedModules) {\n      out.push(jsModule);\n    }\n\n    return out;\n  }\n\n  private registerModuleDisposable(path: string, disposable: () => void) {\n    const module = this.modules[path];\n    if (!module) {\n      return;\n    }\n    let disposables = module.disposables;\n    if (!disposables) {\n      disposables = [];\n      module.disposables = disposables;\n    }\n    disposables.push(disposable);\n  }\n\n  private unloadNextModule(modulesToKeep: StringSet, unloadedModules: StringSet): boolean {\n    for (const modulePath in this.modules) {\n      if (modulesToKeep[modulePath]) {\n        continue;\n      }\n      const jsModule = this.modules[modulePath];\n      if (jsModule && !isModuleUsed(jsModule)) {\n        this.doUnload(modulePath, unloadedModules);\n        return true;\n      }\n    }\n    return false;\n  }\n\n  unload(paths: string[], isHotReloading: boolean, disableHotReloadDenyList: boolean): string[] {\n    const unloadedModules: StringSet = {};\n\n    for (const path of paths) {\n      const resolvedPath = resolveAbsoluteImportFromPath(path);\n\n      this.doUnload(resolvedPath.absolutePath, unloadedModules);\n\n      if (isHotReloading && !this.commonJsCompatible) {\n        if (!this.moduleDenylistedForLazyLoading) {\n          this.moduleDenylistedForLazyLoading = {};\n        }\n        const shouldDeny = !disableHotReloadDenyList;\n        this.moduleDenylistedForLazyLoading[resolvedPath.absolutePath] = shouldDeny;\n      }\n    }\n\n    const out: string[] = [];\n    for (const jsModule in unloadedModules) {\n      out.push(jsModule);\n\n      if (isHotReloading) {\n        const callbacks = this.hotReloadCallbacks[jsModule];\n        if (callbacks) {\n          for (const callback of callbacks) {\n            callback();\n          }\n        }\n      }\n    }\n\n    return out;\n  }\n\n  onHotReload(observingModule: { path: string }, path: string, callback: OnHotReloadCallback): () => void {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    let callbacks = this.hotReloadCallbacks[resolvedPath.absolutePath];\n    if (!callbacks) {\n      callbacks = [];\n      this.hotReloadCallbacks[resolvedPath.absolutePath] = callbacks;\n    }\n\n    callbacks.push(callback);\n\n    const disposable = () => {\n      const index = callbacks.indexOf(callback);\n      if (index >= 0) {\n        callbacks.splice(index, 1);\n      }\n    };\n\n    if (observingModule.path !== path) {\n      this.registerModuleDisposable(observingModule.path, disposable);\n    } else {\n      // Module is observing itself, in this case we dispose of the callback whenever the module is hot reloaded.\n      callbacks.push(disposable);\n    }\n\n    return disposable;\n  }\n\n  resolveRequire(path: string): RequireFunc {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n\n    let module = this.modules[resolvedPath.absolutePath];\n    if (!module) {\n      this.doImport(resolvedPath, undefined, false, true);\n      module = this.modules[resolvedPath.absolutePath]!;\n    }\n\n    return this.makeRequire(module);\n  }\n\n  getOrCreateSourceMap = (path: string, sourceMapFactory: SourceMapFactory): ISourceMap | undefined => {\n    const resolvedPath = resolveAbsoluteImportFromPath(path);\n    let module = this.modules[resolvedPath.absolutePath];\n    if (!module || !module.sourceMap) {\n      // Attempt to load the module automatically if it's not in the map\n      try {\n        this.doImport(resolvedPath, undefined, true, true);\n      } catch (err: any) {\n        console.log(`Could not load module ${path}: ${err.message}`);\n      }\n\n      module = this.modules[resolvedPath.absolutePath];\n\n      if (!module) {\n        return undefined;\n      }\n    }\n\n    let sourceMap = module.sourceMap;\n\n    if (sourceMap === undefined) {\n      let resolvedSourceMapContent: string | undefined;\n      if (this.sourceMapResolver) {\n        resolvedSourceMapContent = this.sourceMapResolver(resolvedPath.absolutePath);\n      }\n\n      const resolvedSourceMap = sourceMapFactory(resolvedSourceMapContent, module.sourceMapLineOffset);\n      if (resolvedSourceMap) {\n        module.sourceMap = resolvedSourceMap;\n        sourceMap = resolvedSourceMap;\n      } else {\n        // Use null to mark a fetched source map that did not resolve to anything\n        module.sourceMap = null;\n      }\n    }\n\n    if (!sourceMap) {\n      return undefined;\n    }\n    return sourceMap;\n  };\n\n  private doUnload(path: string, unloadedModules: StringSet) {\n    const jsModule = this.modules[path];\n    if (!jsModule) {\n      return;\n    }\n\n    delete this.modules[path];\n\n    unloadedModules[path] = true;\n\n    for (const dependency in jsModule.dependencies) {\n      const importedModule = this.modules[dependency];\n      if (!importedModule) {\n        continue;\n      }\n\n      // Remove this module from the imported module's dependents\n      delete importedModule.dependents[path];\n    }\n\n    const disposables = jsModule.disposables;\n    if (disposables) {\n      for (const disposable of disposables) {\n        disposable();\n      }\n    }\n\n    for (const dependent in jsModule.dependents) {\n      this.doUnload(dependent, unloadedModules);\n    }\n  }\n\n  private syncDependencies(jsModule: Module, parent?: Module) {\n    if (!parent) {\n      return;\n    }\n\n    const parentPath = parent.resolvedPath.absolutePath;\n\n    jsModule.dependents[parentPath] = true;\n    parent.dependencies[jsModule.resolvedPath.absolutePath] = true;\n  }\n\n  private doImport(\n    resolvedModulePath: ResolvedPath,\n    parent: Module | undefined,\n    disableProxy: boolean,\n    disableSyncDependencies: boolean,\n  ): any {\n    const absolutePath = resolvedModulePath.absolutePath;\n\n    let jsModule = this.modules[absolutePath];\n    if (jsModule) {\n      if (!disableSyncDependencies) {\n        this.syncDependencies(jsModule, parent);\n      }\n\n      if (jsModule.lazyExports && jsModule.status !== ModuleStatus.LOADING) {\n        if (disableProxy || this.commonJsCompatible) {\n          return jsModule.lazyExports();\n        }\n\n        if (this.moduleDenylistedForLazyLoading && this.moduleDenylistedForLazyLoading[absolutePath]) {\n          // This module was blacklisted for lazy loading, we immediately load it instead of waiting\n          // until the proxy triggers the load.\n          jsModule.lazyExports();\n        }\n      }\n\n      return jsModule.exports;\n    }\n\n    jsModule = {\n      resolvedPath: resolvedModulePath,\n      error: undefined,\n      exports: undefined,\n      lazyExports: undefined,\n      status: ModuleStatus.UNLOADED,\n      dependents: {},\n      dependencies: {},\n      sourceMap: undefined,\n    };\n    this.modules[absolutePath] = jsModule;\n\n    try {\n      if (!disableSyncDependencies) {\n        this.syncDependencies(jsModule, parent);\n      }\n      jsModule.exports = this.makeModuleExports(jsModule);\n\n      if (jsModule.lazyExports) {\n        if (disableProxy || this.commonJsCompatible) {\n          return jsModule.lazyExports();\n        }\n\n        if (this.moduleDenylistedForLazyLoading && this.moduleDenylistedForLazyLoading[absolutePath]) {\n          // This module was blacklisted for lazy loading, we immediately load it instead of waiting\n          // until the proxy triggers the load.\n          jsModule.lazyExports();\n        }\n      }\n\n      const valdiModuleName = resolvedModulePath.directoryPaths[0];\n      if (valdiModuleName && !this.preloadedValdiModules[valdiModuleName]) {\n        this.preloadedValdiModules[valdiModuleName] = true;\n        this.valdiModulePreloader(valdiModuleName, undefined);\n      }\n    } catch (err: any) {\n      jsModule.error = err;\n      throw err;\n    }\n\n    return jsModule.exports;\n  }\n\n  private makeModuleExports(jsModule: Module): any {\n    const modulePath = jsModule.resolvedPath.absolutePath;\n    const moduleFactory = this.moduleFactory[modulePath];\n    if (moduleFactory) {\n      return moduleFactory();\n    }\n\n    const requireFunc = this.makeRequire(jsModule);\n    const jsExports = {};\n    const jsModuleObj = {\n      exports: jsExports,\n      path: modulePath,\n      sourceMapLineOffset: 0,\n    };\n\n    let exportsObj: any;\n    let didEval = false;\n\n    const lazyExports = () => {\n      if (!didEval) {\n        if (jsModule.error) {\n          rethrow(jsModule.error);\n        }\n\n        jsModule.status = ModuleStatus.LOADING;\n        try {\n          const result = this.jsEvaluator(modulePath, requireFunc, jsModuleObj, jsExports);\n          if (result) {\n            throw new RetryableError(result);\n          }\n          jsModule.status = ModuleStatus.LOADED;\n        } catch (err: any) {\n          if (!(err instanceof RetryableError)) {\n            jsModule.error = err;\n          }\n          jsModule.status = ModuleStatus.UNLOADED;\n          throw err;\n        } finally {\n          if (jsModuleObj.sourceMapLineOffset) {\n            jsModule.sourceMapLineOffset = jsModuleObj.sourceMapLineOffset;\n          }\n        }\n        didEval = true;\n        exportsObj = jsModuleObj.exports;\n      }\n      return exportsObj;\n    };\n\n    jsModule.lazyExports = lazyExports;\n\n    if (this.commonJsCompatible) {\n      return jsExports;\n    } else {\n      return new Proxy(jsExports, {\n        get(target, key) {\n          if (!didEval) {\n            lazyExports();\n          }\n\n          return exportsObj[key];\n        },\n      });\n    }\n  }\n\n  private makeRequire(jsModule: Module): RequireFunc {\n    return (path: string, disableProxy?: boolean, disableSyncDependencies?: boolean) => {\n      const resolve = resolvePath(path, jsModule.resolvedPath);\n      return this.doImport(resolve, jsModule, !!disableProxy, !!disableSyncDependencies);\n    };\n  }\n}\n\nexport function create(\n  jsEvaluator: JsEvaluator,\n  sourceMapResolver: SourceMapResolver | undefined,\n  valdiModulePreloader: ValdiModulePreloader | undefined,\n  commonJsCompatible: boolean,\n): IModuleLoader {\n  return new ModuleLoader(jsEvaluator, sourceMapResolver, valdiModulePreloader, commonJsCompatible);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ModuleLoaderGlobal.ts",
    "content": "import { IModuleLoader } from './IModuleLoader';\n\ndeclare const global: any;\n\nexport function getModuleLoader(): IModuleLoader {\n  return global.moduleLoader as IModuleLoader;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/NativeReferences.ts",
    "content": "import { ValdiRuntime } from './ValdiRuntime';\nimport { IComponent } from './IComponent';\n\ndeclare const runtime: ValdiRuntime;\n\n/**\n * By default, bridged objects from native are disposed after onDestroy()\n * is called on the root component. If you need to use a bridged object\n * for potentially longer than the lifetime of your component, you can\n * call this method to ensure the native refs won't be disposed. You should\n * call the returned disposable once you are done with the instance. It uses\n * a ref counting mecanism internally, so you can call protect as many times\n * as you want as long as they get balanced by the same number of unprotect\n * calls eventually.\n */\nexport function protectNativeRefs(component: IComponent): () => void {\n  return protectNativeRefsForContextId(component.renderer.contextId);\n}\n\n/**\n * By default, bridged objects from native are disposed after onDestroy()\n * is called on the root component. If you need to use a bridged object\n * for potentially longer that the lifetime of your component, you can\n * call this method to ensure the native refs won't be disposed. You should\n * call the returned disposable once you are done with the instance. It uses\n * a ref counting mecanism internally, so you can call protect as many times\n * as you want as long as they get balanced by the same number of unprotect\n * calls eventually.\n */\nexport function protectNativeRefsForContextId(contextId: string): () => void {\n  return runtime.protectNativeRefs(contextId);\n}\n\n/**\n * By default, bridged objects from native are disposed after onDestroy()\n * is called on the root component. If you need to use a bridged object\n * for potentially longer that the lifetime of your component, you can\n * call this method to ensure the native refs won't be disposed. You should\n * call the returned disposable once you are done with the instance. It uses\n * a ref counting mechanism internally, so you can call protect as many times\n * as you want as long as they get balanced by the same number of unprotect\n * calls eventually.\n */\nexport function protectNativeRefsForCurrentContextId(): () => void {\n  return runtime.protectNativeRefs(0);\n}\n\n/**\n * By default, bridged objects from native are disposed after onDestroy()\n * is called on the root component. If you need a bridged object to last the\n * lifetime of a Promise's resolution, use this function to keep the current\n * context alive until the promise is resolved or rejected.\n */\nexport function asyncWithProtectedRefsForCurrentContextId<T>(promise: Promise<T>): Promise<T> {\n  const dispose = protectNativeRefsForCurrentContextId();\n  return promise.finally(() => dispose());\n}\n\n/**\n * Evaluate the given block with a global native refs scope.\n * Any native references emitted while the block is evaluated\n * will be associated with the global native references, which\n * aren't destroyed when a root component is destroyed.\n */\nexport function withGlobalNativeRefs<T>(cb: () => T): T {\n  runtime.pushCurrentContext(undefined);\n  try {\n    return cb();\n  } finally {\n    runtime.popCurrentContext();\n  }\n}\n\n/**\n * Evaluate the given block with a local native refs scope tied\n * to the given context id. Any native references emitted while\n * the block is evaluated will be associated with the native\n * references on the given context.\n */\nexport function withLocalNativeRefs<T>(contextId: string, cb: () => T): T {\n  runtime.pushCurrentContext(contextId);\n  try {\n    return cb();\n  } finally {\n    runtime.popCurrentContext();\n  }\n}\n\n/**\n * a NativeReferencesContext holds the references that are exchanged between\n * TypeScript and Platform. When the NativeReferencesContext is disposed(),\n * all the references are removed, which prevents Platform call the exported\n * TypeScript functions, and prevents TypeScript to call proxied functions\n * provided from Platform. Every Valdi root view gets a NativeReferencesContext\n * by default, which is disposed when the root view gets destroyed.\n * A NativeReferencesContext is represented as Valdi::Context in C++,\n * SCValdiContext in Objective-C, and ValdiContext in Kotlin.\n */\nexport class NativeReferencesContext {\n  constructor(readonly contextId: string) {}\n\n  /**\n   * Destroy the Context, which will release all the retained references.\n   */\n  destroy() {\n    runtime.destroyContext(this.contextId);\n  }\n\n  /**\n   * Make the context as current in the given callback function.\n   * For the duration of the callback, any interactions between TypeScript\n   * and Platform that result in references being created will end up being\n   * associated with this context. For example, if TypeScript code passes\n   * \"function A\" to Kotlin while the makeCurrent() callback function is called,\n   * a reference for \"function A\" will be created and associated with this context.\n   * That reference prevents \"function A\" to be garbage collected while it might\n   * be in use by Platform. The reference will be removed as soon as either Platform\n   * releases its own reference to \"function A\", or when the context is explicitly\n   * destroyed through a destroy() call.\n   */\n  makeCurrent(cb: () => void) {\n    withLocalNativeRefs(this.contextId, cb);\n  }\n\n  /**\n   * Create a new NativeReferencesContext. The context\n   * will have to be explicitly destroyed at some point using the\n   * destroy() method.\n   */\n  static create(): NativeReferencesContext {\n    return new NativeReferencesContext(runtime.createContext());\n  }\n\n  /**\n   * Returns the NativeReferencesContext that is associated with the given component.\n   * Valdi components in a tree are all associated to the same context.\n   * The returned context should NOT be destroyed as it will be already destroyed\n   * when the root component gets destroyed.\n   */\n  static fromComponent(component: IComponent): NativeReferencesContext {\n    return new NativeReferencesContext(component.renderer.contextId);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/NodePrototype.ts",
    "content": "import { PropertyList } from './utils/PropertyList';\n\nexport type ViewClass = string;\n\nlet idSequence = 0;\n\nexport class NodePrototype {\n  readonly id: string;\n  readonly tag: string;\n  readonly viewClass: ViewClass;\n  readonly attributes: PropertyList | undefined;\n\n  constructor(tag: string, viewClass: ViewClass, attributes?: PropertyList) {\n    this.id = '__node' + ++idSequence;\n    this.tag = tag;\n    this.viewClass = viewClass;\n    this.attributes = attributes;\n  }\n}\n\nexport class DeferredNodePrototype extends NodePrototype {\n  constructor(tag: string, attributes?: PropertyList) {\n    super(tag, 'Deferred', attributes);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/PostInit.ts",
    "content": "// Initialize the globals.\n// This should be loaded right after the ModuleLoader is loaded\n\nimport { Console } from 'valdi_core/src/Console';\nimport { ValdiRuntime } from './ValdiRuntime';\nimport { ModuleLoader } from './ModuleLoader';\nimport { arePromiseUtterlyBroken, polyfillPromise } from './PromisePolyfill';\nimport {\n  __tsn_async_generator_helper,\n  __tsn_async_helper,\n  __tsn_get_async_iterator,\n  __tsn_get_iterator,\n} from './TsnHelper';\n\ndeclare const global: any;\ndeclare const runtime: ValdiRuntime;\n\nfunction setTimeout(handler: (...args: any[]) => void, timeout?: number, ...args: any[]): number {\n  return runtime.scheduleWorkItem(args.length ? handler.bind(undefined, args) : handler, timeout || 0);\n}\n\nfunction clearTimeout(handler: number): void {\n  runtime.unscheduleWorkItem(handler);\n}\n\nclass Timer {\n  private handler: (() => void) | undefined;\n  private currentTaskId: number | undefined;\n\n  constructor(handler: () => void, readonly timeout: number) {\n    this.handler = handler;\n  }\n\n  invalidate(): void {\n    this.handler = undefined;\n    if (this.currentTaskId) {\n      runtime.unscheduleWorkItem(this.currentTaskId);\n      this.currentTaskId = undefined;\n    }\n  }\n\n  schedule(): boolean {\n    if (!this.handler || this.currentTaskId) {\n      return false;\n    }\n\n    this.currentTaskId = runtime.scheduleWorkItem(() => {\n      this.tick();\n    }, this.timeout);\n\n    return true;\n  }\n\n  private tick() {\n    if (this.handler) {\n      try {\n        this.handler();\n      } catch (err: any) {\n        runtime.onUncaughtError('TimerCallback', err);\n      }\n    }\n\n    this.currentTaskId = undefined;\n\n    this.schedule();\n  }\n}\n\nfunction setInterval(handler: (...args: any[]) => void, timeout?: number, ...args: any[]): number {\n  const timer = new Timer(args.length ? handler.bind(undefined, args) : handler, timeout || 0);\n  timer.schedule();\n  return timer as any;\n}\n\nfunction clearInterval(handler: number): void {\n  const timer: Timer = handler as any;\n  if (!(timer instanceof Timer)) {\n    return;\n  }\n\n  timer.invalidate();\n}\n\nLong.prototype.valueOf = function (this: Long) {\n  if (this.greaterThan(Number.MAX_SAFE_INTEGER) || this.lessThan(Number.MIN_SAFE_INTEGER)) {\n    throw new Error(`Long value ${this.toString()} is too large to be represented as a primitive number`);\n  }\n\n  return this.toNumber();\n};\n\nexport function postInit(): void {\n  global.console = new Console(runtime.outputLog);\n\n  if (!global.realTimingFunctions) {\n    // We only configure the timing functions once to avoid messing up jasmine's internal checks\n    // when it installs the mocked jasmine.Clock.\n    global.realTimingFunctions = {\n      setTimeout: global.setTimeout,\n      clearTimeout: global.clearTimeout,\n      setInterval: global.setInterval,\n      clearInterval: global.clearInterval,\n    };\n    global.setTimeout = setTimeout;\n    global.clearTimeout = clearTimeout;\n    global.setInterval = setInterval;\n    global.clearInterval = clearInterval;\n  }\n\n  if (arePromiseUtterlyBroken(runtime.getCurrentPlatform)) {\n    polyfillPromise();\n  }\n\n  global.__tsn_async_helper = __tsn_async_helper;\n  global.__tsn_get_iterator = __tsn_get_iterator;\n  global.__tsn_get_async_iterator = __tsn_get_async_iterator;\n  global.__tsn_async_generator_helper = __tsn_async_generator_helper;\n\n  const moduleLoader = global.moduleLoader as ModuleLoader;\n  moduleLoader.onModuleRegistered('coreutils/src/unicode/UnicodeNative', () => {\n    const textCoding = moduleLoader.load('coreutils/src/unicode/TextCoding', true);\n    global.TextDecoder = textCoding.TextDecoder;\n    global.TextEncoder = textCoding.TextEncoder;\n  });\n\n  // Without this, parsing worker code that does something like:\n  // onmessage = e => { /* blah */ };\n  // fails with:\n  // ReferenceError: 'onmessage' is not defined\n  //\n  // see: src/valdi/worker/test/workers/TestWorker.ts\n  global.onmessage = () => {};\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Promise.js",
    "content": "!function(t, r) {\n    \"object\" == typeof exports && \"undefined\" != typeof module ? module.exports = r() : \"function\" == typeof define && define.amd ? define(r) : t.ES6Promise = r();\n}(this, function() {\n    \"use strict\";\n    function t(t) {\n        return \"function\" == typeof t;\n    }\n    var r = Array.isArray ? Array.isArray : function(t) {\n        return \"[object Array]\" === Object.prototype.toString.call(t);\n    }, e = 0, n = void 0, o = function(t, r) {\n        i[e] = t, i[e + 1] = r, 2 === (e += 2) && (n ? n(s) : c());\n    };\n    var i = new Array(1e3);\n    function s() {\n        for (var t = 0; t < e; t += 2) {\n            (0, i[t])(i[t + 1]), i[t] = void 0, i[t + 1] = void 0;\n        }\n        e = 0;\n    }\n    var u, c = (u = setTimeout, function() {\n        return u(s, 1);\n    });\n    function a(t, r) {\n        var e = this, n = new this.constructor(h);\n        void 0 === n[f] && T(n);\n        var i = e._state;\n        if (i) {\n            var s = arguments[i - 1];\n            o(function() {\n                return S(i, n, s, e._result);\n            });\n        } else E(e, n, t, r);\n        return n;\n    }\n    function l(t) {\n        if (t && \"object\" == typeof t && t.constructor === this) return t;\n        var r = new this(h);\n        return b(r, t), r;\n    }\n    var f = Math.random().toString(36).substring(2);\n    function h() {}\n    var _ = void 0, v = 1, p = 2, d = {\n        error: null\n    };\n    function y(t) {\n        try {\n            return t.then;\n        } catch (t) {\n            return d.error = t, d;\n        }\n    }\n    function m(r, e, n) {\n        var i, s, u, c;\n        e.constructor === r.constructor && n === a && e.constructor.resolve === l ? (u = r,\n        (c = e)._state === v ? g(u, c._result) : c._state === p ? A(u, c._result) : E(c, void 0, function(t) {\n            return b(u, t);\n        }, function(t) {\n            return A(u, t);\n        })) : n === d ? (A(r, d.error), d.error = null) : void 0 === n ? g(r, e) : t(n) ? (i = e,\n        s = n, o(function(t) {\n            var r = !1, e = function(t, r, e, n) {\n                try {\n                    t.call(r, e, n);\n                } catch (t) {\n                    return t;\n                }\n            }(s, i, function(e) {\n                r || (r = !0, i !== e ? b(t, e) : g(t, e));\n            }, function(e) {\n                r || (r = !0, A(t, e));\n            }, t._label);\n            !r && e && (r = !0, A(t, e));\n        }, r)) : g(r, e);\n    }\n    function b(t, r) {\n        var e, n;\n        t === r ? A(t, new TypeError(\"You cannot resolve a promise with itself\")) : (n = typeof (e = r),\n        null === e || \"object\" !== n && \"function\" !== n ? g(t, r) : m(t, r, y(r)));\n    }\n    function w(t) {\n        t._onerror && t._onerror(t._result), j(t);\n    }\n    function g(t, r) {\n        t._state === _ && (t._result = r, t._state = v, 0 !== t._subscribers.length && o(j, t));\n    }\n    function A(t, r) {\n        t._state === _ && (t._state = p, t._result = r, o(w, t));\n    }\n    function E(t, r, e, n) {\n        var i = t._subscribers, s = i.length;\n        t._onerror = null, i[s] = r, i[s + v] = e, i[s + p] = n, 0 === s && t._state && o(j, t);\n    }\n    function j(t) {\n        var r = t._subscribers, e = t._state;\n        if (0 !== r.length) {\n            for (var n = void 0, o = void 0, i = t._result, s = 0; s < r.length; s += 3) n = r[s],\n            o = r[s + e], n ? S(e, n, o, i) : o(i);\n            t._subscribers.length = 0;\n        }\n    }\n    function S(r, e, n, o) {\n        var i = t(n), s = void 0, u = void 0, c = void 0, a = void 0;\n        if (i) {\n            if ((s = function(t, r) {\n                try {\n                    return t(r);\n                } catch (t) {\n                    return d.error = t, d;\n                }\n            }(n, o)) === d ? (a = !0, u = s.error, s.error = null) : c = !0, e === s) return void A(e, new TypeError(\"A promises callback cannot return that same promise.\"));\n        } else s = o, c = !0;\n        e._state !== _ || (i && c ? b(e, s) : a ? A(e, u) : r === v ? g(e, s) : r === p && A(e, s));\n    }\n    var P = 0;\n    function T(t) {\n        t[f] = P++, t._state = void 0, t._result = void 0, t._subscribers = [];\n    }\n    var Y = function() {\n        function t(t, e) {\n            this._instanceConstructor = t, this.promise = new t(h), this.promise[f] || T(this.promise),\n            r(e) ? (this.length = e.length, this._remaining = e.length, this._result = new Array(this.length),\n            0 === this.length ? g(this.promise, this._result) : (this.length = this.length || 0,\n            this._enumerate(e), 0 === this._remaining && g(this.promise, this._result))) : A(this.promise, new Error(\"Array Methods must be provided an Array\"));\n        }\n        return t.prototype._enumerate = function(t) {\n            for (var r = 0; this._state === _ && r < t.length; r++) this._eachEntry(t[r], r);\n        }, t.prototype._eachEntry = function(t, r) {\n            var e = this._instanceConstructor, n = e.resolve;\n            if (n === l) {\n                var o = y(t);\n                if (o === a && t._state !== _) this._settledAt(t._state, r, t._result); else if (\"function\" != typeof o) this._remaining--,\n                this._result[r] = t; else if (e === x) {\n                    var i = new e(h);\n                    m(i, t, o), this._willSettleAt(i, r);\n                } else this._willSettleAt(new e(function(r) {\n                    return r(t);\n                }), r);\n            } else this._willSettleAt(n(t), r);\n        }, t.prototype._settledAt = function(t, r, e) {\n            var n = this.promise;\n            n._state === _ && (this._remaining--, t === p ? A(n, e) : this._result[r] = e),\n            0 === this._remaining && g(n, this._result);\n        }, t.prototype._willSettleAt = function(t, r) {\n            var e = this;\n            E(t, void 0, function(t) {\n                return e._settledAt(v, r, t);\n            }, function(t) {\n                return e._settledAt(p, r, t);\n            });\n        }, t;\n    }();\n    var x = function() {\n        function t(r) {\n            this[f] = P++, this._result = this._state = void 0, this._subscribers = [], h !== r && (\"function\" != typeof r && function() {\n                throw new TypeError(\"You must pass a resolver function as the first argument to the promise constructor\");\n            }(), this instanceof t ? function(t, r) {\n                try {\n                    r(function(r) {\n                        b(t, r);\n                    }, function(r) {\n                        A(t, r);\n                    });\n                } catch (r) {\n                    A(t, r);\n                }\n            }(this, r) : function() {\n                throw new TypeError(\"Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.\");\n            }());\n        }\n        return t.prototype.catch = function(t) {\n            return this.then(null, t);\n        }, t.prototype.finally = function(t) {\n            var r = this.constructor;\n            return this.then(function(e) {\n                return r.resolve(t()).then(function() {\n                    return e;\n                });\n            }, function(e) {\n                return r.resolve(t()).then(function() {\n                    throw e;\n                });\n            });\n        }, t;\n    }();\n    return x.prototype.then = a, x.all = function(t) {\n        return new Y(this, t).promise;\n    }, x.race = function(t) {\n        var e = this;\n        return r(t) ? new e(function(r, n) {\n            for (var o = t.length, i = 0; i < o; i++) e.resolve(t[i]).then(r, n);\n        }) : new e(function(t, r) {\n            return r(new TypeError(\"You must pass an array to race.\"));\n        });\n    }, x.resolve = l, x.reject = function(t) {\n        var r = new this(h);\n        return A(r, t), r;\n    }, x._setScheduler = function(t) {\n        n = t;\n    }, x._setAsap = function(t) {\n        o = t;\n    }, x._asap = o, x.polyfill = function() {\n        var t = void 0;\n        if (\"undefined\" != typeof global) t = global; else if (\"undefined\" != typeof self) t = self; else try {\n            t = Function(\"return this\")();\n        } catch (t) {\n            throw new Error(\"polyfill failed because global object is unavailable in this environment\");\n        }\n        delete t.Promise, t.Promise = x;\n    }, x.Promise = x, x;\n});"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/PromisePolyfill.ts",
    "content": "// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\nimport { RequireFunc } from './IModuleLoader';\nimport { setTimeoutUninterruptible } from './SetTimeout';\n\ndeclare const require: RequireFunc;\n\n/**\n * Checks whether microtasks to handle Promise fulfillments are\n * flushed when doing a native call. This will be true on older\n * versions of JavaScriptCore that had a bug with their C API.\n */\nexport function arePromiseUtterlyBroken(nativeCall: () => void): boolean {\n  let thenCalled = false;\n  // eslint-disable-next-line @typescript-eslint/no-floating-promises\n  new Promise<void>(resolve => {\n    resolve();\n  }).then(() => {\n    thenCalled = true;\n  });\n\n  nativeCall();\n\n  return thenCalled;\n}\n\nexport function polyfillPromise() {\n  const promise = require('./Promise', true);\n  // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n  // @ts-ignore\n  if (promise && promise.polyfill) {\n    // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n    // @ts-ignore\n    promise.polyfill();\n\n    if (typeof queueMicrotask !== 'undefined') {\n      const ourAsap = (callback: (arg: any) => void, arg: any) => {\n        queueMicrotask(() => {\n          callback(arg);\n        });\n      };\n      (Promise as any)._setAsap(ourAsap);\n    } else {\n      const ourAsap = (callback: (arg: any) => void, arg: any) => {\n        // eslint-disable-next-line @snap/valdi/assign-timer-id\n        setTimeoutUninterruptible(() => {\n          callback(arg);\n        }, 1);\n      };\n      (Promise as any)._setAsap(ourAsap);\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/RenderRequest.d.ts",
    "content": "/**\n * Protocol:\n * Every entry is a 32 bits integer.\n * [type][nodeId][data...]\n *\n * Create element: [1][nodeId][viewClass]\n * Destroy element: [2][nodeId]\n * Set root element: [3][nodeId]\n * Move element to parent: [4][nodeId][parentId][index]\n * Set element attribute undefined: [5][nodeId][name]\n * Set element attribute null: [6][nodeId][name]\n * Set element attribute boolean: [7][nodeId][name][value]\n * Set element attribute number: [8][nodeId][name][value 64bits]\n * Set element attribute array: [9][nodeId][name][size][valueIndexes...]\n * Set element attribute unknown: [10][nodeId][name][valueIndex]\n * Begin animation: [11][duration 64bits][curve][beginFromCurrentState][controlPointsValueIndex]\n * End animation: [12]\n */\n\nexport interface RenderRequest {\n  treeId: string;\n  descriptor: ArrayBuffer;\n  descriptorSize: number;\n  values: any[];\n  visibilityObserver?: NativeVisibilityObserver;\n  frameObserver?: NativeFrameObserver;\n}\n\nexport type NativeVisibilityObserver = (\n  disappearingElements: number[],\n  appearingElements: number[],\n  viewportUpdates: number[],\n  acknowledger: () => void,\n  eventTime: number,\n) => void;\nexport type NativeFrameObserver = (updates: Float64Array) => void;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Renderer.ts",
    "content": "import { arrayEquals } from 'coreutils/src/ArrayUtils';\nimport { StringMap } from 'coreutils/src/StringMap';\nimport { StringSet } from 'coreutils/src/StringSet';\nimport { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { EventTime } from 'valdi_tsx/src/GestureEvents';\nimport { IRenderedComponentHolder } from 'valdi_tsx/src/IRenderedComponentHolder';\nimport { IRenderedElementHolder } from 'valdi_tsx/src/IRenderedElementHolder';\nimport { NativeNode } from 'valdi_tsx/src/NativeNode';\nimport { NativeView } from 'valdi_tsx/src/NativeView';\nimport { AnimationOptions, BasicAnimationOptions, SpringAnimationOptions } from './AnimationOptions';\nimport { AnyRenderFunction } from './AnyRenderFunction';\nimport { DumpedLogs } from './BugReporter';\nimport { CancelToken } from './CancellableAnimation';\nimport { CapturedRenderedVirtualNode, IElementData } from './CapturedNode';\nimport { ComponentPrototype } from './ComponentPrototype';\nimport { ConsoleRepresentable } from './ConsoleRepresentable';\nimport { ComponentConstructor, IComponent } from './IComponent';\nimport { IRenderedElement } from './IRenderedElement';\nimport { IRenderedVirtualNode } from './IRenderedVirtualNode';\nimport { ComponentDisposable, IRenderer, RendererObserver } from './IRenderer';\nimport { IRendererDelegate } from './IRendererDelegate';\nimport { IRendererEventListener } from './IRendererEventListener';\nimport { NodePrototype } from './NodePrototype';\nimport { Style } from './Style';\nimport { MergeType } from './utility_types/MergeType';\nimport { tryReuseCallback } from './utils/CallbackInternal';\nimport { classNames } from './utils/ClassNames';\nimport { enumeratePropertyList, PropertyList, propertyListToObject } from './utils/PropertyList';\nimport { computeUniqueId } from './utils/RenderedVirtualNodeUtils';\nimport { RendererError } from './utils/RendererError';\nimport { trace } from './utils/Trace';\n\nconst EMPTY_OBJECT = Object.freeze({});\nconst EMPTY_ARRAY = Object.freeze([]) as [];\n\ninterface NodeChildren<T> {\n  childByKey: { [key: string]: T };\n  children: T[];\n  previousChildren?: T[];\n  insertionIndex: number;\n}\n\ninterface Node {\n  key: string;\n  lastRenderId: symbol;\n  children?: NodeChildren<Node>;\n  parent?: Node;\n  parentIndex: number;\n}\n\n/**\n * Represents a node inside the virtual node\n * tree that contains either a component or an element.\n */\ninterface VirtualNode extends Node {\n  children: NodeChildren<VirtualNode> | undefined;\n  parent: VirtualNode | undefined;\n\n  element?: RenderedElement;\n  component?: RenderedComponent;\n  slot?: boolean;\n\n  // The nearest parent element\n  parentElement: RenderedElement | undefined;\n  // The nearest parent component\n  parentComponent: RenderedComponent | undefined;\n\n  // Bridge instance, will be set if the virtual node was requested externally.\n  bridge?: VirtualNodeBridge;\n}\n\ninterface RenderedElement {\n  virtualNode: VirtualNode;\n\n  id: number;\n  nodePrototype: NodePrototype | undefined;\n  attributes: StringMap<any>;\n\n  wasVisibleOnce?: boolean;\n  // Bridge instance, will be set if the element was requested externally.\n  bridge?: RenderedElementBridge;\n  // Resolved children of this element\n  childrenHead: RenderedElement | undefined;\n  // Whether children are dirty and need to be resolved\n  childrenDirty: boolean;\n  // The last resolved frame\n  frame: ElementFrame | undefined;\n\n  // Siblings\n  next: RenderedElement | undefined;\n  prev: RenderedElement | undefined;\n\n  // Ordering\n  parentIndex: number | undefined;\n}\n\ninterface RenderedComponent<T extends IComponent = IComponent> {\n  virtualNode: VirtualNode;\n\n  ctr: ComponentConstructor<T>;\n  prototype: ComponentPrototype;\n\n  instance: IComponent | undefined;\n  viewModel: any | undefined;\n  needRendering: boolean;\n  viewModelChanged: boolean;\n  // Whether the component is currently rendering\n  rendering: boolean;\n\n  // Attributes to inject on the root elements\n  // of a component. Mostly there for backward\n  // compatibility with the Vue Valdi's implementation.\n  injectedAttributes: any | undefined;\n\n  rerenderScheduled?: boolean;\n\n  context?: any;\n  disposables?: ComponentDisposable[];\n\n  onCreateObserver?: (instance: any) => void;\n  onDestroyObserver?: (instance: any) => void;\n\n  componentRef: IRenderedComponentHolder<T, IRenderedVirtualNode> | undefined;\n}\n\ninterface ComponentSlotData<F extends AnyRenderFunction = AnyRenderFunction> {\n  // The node key for the slot.\n  nodeKey: string;\n  renderFunc: F;\n  // The emitted node for the slot. Will be created when the component renders its slot\n  // the first time.\n  node: VirtualNode | undefined;\n  lastParameters: Parameters<F> | undefined;\n  ref?: IRenderedElementHolder<any>;\n  // Whether the nodeKey was explicitly provided by the user\n  isKeyExplicit?: boolean;\n}\n\nconst SLOT_DATA_KEY = Symbol();\n\ninterface SlotFunction<F extends AnyRenderFunction> {\n  (...params: Parameters<F>): ReturnType<F>;\n  [SLOT_DATA_KEY]: ComponentSlotData<F>;\n}\n\nconst IS_NAMED_SLOT_KEY = Symbol();\n\ninterface NamedSlotFunctions {\n  [key: string]: SlotFunction<AnyRenderFunction> | undefined;\n  [IS_NAMED_SLOT_KEY]: boolean;\n}\n\nlet currentRenderer: Renderer | undefined;\n\nfunction getRenderedElementBridge(renderer: Renderer, renderedElement: RenderedElement): RenderedElementBridge {\n  if (renderedElement.bridge) {\n    return renderedElement.bridge;\n  }\n\n  const instance = new RenderedElementBridge(renderer, renderedElement);\n  renderedElement.bridge = instance;\n  return instance;\n}\n\nfunction getVirtualNodeBridge(renderer: Renderer, virtualNode: VirtualNode): VirtualNodeBridge {\n  if (virtualNode.bridge) {\n    return virtualNode.bridge;\n  }\n\n  const instance = new VirtualNodeBridge(renderer, virtualNode);\n  virtualNode.bridge = instance;\n  return instance;\n}\n\nfunction getVirtualNodeBridgeChildren(renderer: Renderer, node: VirtualNode, children: IRenderedVirtualNode[]) {\n  if (!node.children) {\n    return;\n  }\n\n  for (const child of node.children.children) {\n    if (child.slot) {\n      getVirtualNodeBridgeChildren(renderer, child, children);\n    } else {\n      children.push(getVirtualNodeBridge(renderer, child));\n    }\n  }\n}\n\nclass VirtualNodeBridge implements IRenderedVirtualNode {\n  renderer: Renderer;\n  private node: VirtualNode;\n\n  private cachedUniqueId?: string;\n\n  constructor(renderer: Renderer, node: VirtualNode) {\n    this.renderer = renderer;\n    this.node = node;\n  }\n\n  get key(): string {\n    return this.node.key;\n  }\n\n  get parent(): IRenderedVirtualNode | undefined {\n    let parent = this.node.parent;\n    while (parent && parent.slot) {\n      parent = parent.parent;\n    }\n\n    if (!parent || parent === this.renderer.nodeTree) {\n      return undefined;\n    }\n\n    return getVirtualNodeBridge(this.renderer, parent);\n  }\n\n  get element(): IRenderedElement | undefined {\n    if (!this.node.element) {\n      return undefined;\n    }\n\n    return getRenderedElementBridge(this.renderer, this.node.element);\n  }\n\n  get component(): IComponent | undefined {\n    if (!this.node.component) {\n      return undefined;\n    }\n\n    return this.node.component.instance;\n  }\n\n  get children(): IRenderedVirtualNode[] {\n    const out: IRenderedVirtualNode[] = [];\n\n    getVirtualNodeBridgeChildren(this.renderer, this.node, out);\n\n    return out;\n  }\n\n  get parentIndex(): number {\n    return this.node.parentIndex;\n  }\n\n  get uniqueId(): string {\n    if (this.cachedUniqueId) {\n      return this.cachedUniqueId;\n    }\n    this.cachedUniqueId = computeUniqueId(this);\n    return this.cachedUniqueId;\n  }\n}\n\nclass RenderedElementBridge implements IRenderedElement, ConsoleRepresentable {\n  readonly element: RenderedElement;\n  readonly renderer: Renderer;\n  private _children?: IRenderedElement[];\n\n  constructor(renderer: Renderer, element: RenderedElement) {\n    this.renderer = renderer;\n    this.element = element;\n  }\n\n  get tag(): string {\n    return this.element.nodePrototype!.tag;\n  }\n\n  get viewClass(): string {\n    return this.element.nodePrototype!.viewClass;\n  }\n\n  get id(): number {\n    return this.element.id;\n  }\n\n  get key(): string {\n    return this.element.virtualNode.key;\n  }\n\n  get children(): IRenderedElement[] {\n    if (!this._children) {\n      const element = this.element;\n      const renderer = this.renderer;\n      const children: IRenderedElement[] = [];\n      let child = element.childrenHead;\n      while (child) {\n        children.push(getRenderedElementBridge(renderer, child));\n        child = child.next;\n      }\n      this._children = children;\n    }\n    return this._children!;\n  }\n\n  get emittingComponent(): IComponent | undefined {\n    return this.element.virtualNode.parentComponent?.instance;\n  }\n\n  get parent(): IRenderedElement | undefined {\n    const parent = this.element.virtualNode.parentElement;\n    if (!parent) {\n      return undefined;\n    }\n    return getRenderedElementBridge(this.renderer, parent);\n  }\n\n  get parentIndex(): number {\n    return this.element.parentIndex ?? 0;\n  }\n\n  get frame(): ElementFrame {\n    return this.element.frame || { x: 0, y: 0, width: 0, height: 0 };\n  }\n\n  invalidateChildren() {\n    this._children = undefined;\n  }\n\n  getAttributeNames(): string[] {\n    return Object.keys(this.element.attributes);\n  }\n\n  getAttribute(name: string): any {\n    return this.element.attributes[name];\n  }\n\n  setAttribute(name: string, value: any): boolean {\n    if (!this.renderer.began) {\n      this.renderer.doBegin();\n      const changed = this.setAttribute(name, value);\n      this.renderer.doEnd();\n      return changed;\n    }\n\n    return this.renderer.setAttributeOnElement(this.element, name, value);\n  }\n\n  setAttributes(attributes: any): boolean {\n    if (!attributes) {\n      return false;\n    }\n\n    if (!this.renderer.began) {\n      this.renderer.doBegin();\n      const changed = this.setAttributes(attributes);\n      this.renderer.doEnd();\n      return changed;\n    }\n\n    let changed = false;\n\n    enumeratePropertyList(attributes, (key, value) => {\n      if (this.setAttribute(key, value)) {\n        changed = true;\n      }\n    });\n\n    return changed;\n  }\n\n  getNativeView(): Promise<NativeView | undefined> {\n    return new Promise(resolve => {\n      this.renderer.delegate.getNativeView(this.element.id, view => {\n        resolve(view);\n      });\n    });\n  }\n\n  getNativeNode(): NativeNode | undefined {\n    return this.renderer.delegate.getNativeNode(this.element.id);\n  }\n\n  takeSnapshot(): Promise<string | undefined> {\n    return new Promise(resolve => {\n      this.renderer.delegate.takeElementSnapshot(this.element.id, view => {\n        resolve(view);\n      });\n    });\n  }\n\n  getVirtualNode(): IRenderedVirtualNode {\n    return getVirtualNodeBridge(this.renderer, this.element.virtualNode);\n  }\n\n  toConsoleRepresentation() {\n    return [this.viewClass, this.element.attributes];\n  }\n}\n\nconst renderedComponentKey = Symbol();\nconst destroyedComponentTombstone = Symbol();\n\nfunction getNodeDescription(node: VirtualNode): string {\n  const element = node.element;\n  if (element) {\n    const nodePrototype = element.nodePrototype;\n    if (!nodePrototype) {\n      return 'root';\n    }\n\n    return `element ${nodePrototype.viewClass} with key '${node.key}'`;\n  }\n\n  const component = node.component;\n  if (component) {\n    return `component ${component.ctr.name} with key '${node.key}'`;\n  }\n\n  const slot = node.slot;\n  if (slot) {\n    return `slot with key '${node.key}''`;\n  }\n\n  return 'unknown node';\n}\n\ninterface RendererLogInfo {\n  treeId: string;\n  componentRerendersCount: number;\n  rootRendersCount: number;\n  componentsCount: number;\n  elementsCount: number;\n  slotsCount: number;\n}\n\nfunction doCaptureVirtualNode(\n  node: VirtualNode,\n  renderer: Renderer,\n  onEmit: (node: VirtualNode, emitted: CapturedRenderedVirtualNode) => void,\n): CapturedRenderedVirtualNode {\n  const generatedChildren: CapturedRenderedVirtualNode[] = [];\n\n  if (node.children) {\n    const children = node.children;\n    for (let i = 0; i < children.insertionIndex && i < children.children.length; i++) {\n      const childNode = children.children[i];\n\n      generatedChildren.push(doCaptureVirtualNode(childNode, renderer, onEmit));\n    }\n  }\n\n  let elementData: IElementData | undefined;\n  if (node.element) {\n    const nodePrototype = node.element.nodePrototype!;\n    elementData = {\n      id: node.element.id,\n      tag: nodePrototype.tag,\n      viewClass: nodePrototype.viewClass,\n      attributes: { ...node.element.attributes },\n      frame: node.element.frame || { x: 0, y: 0, width: 0, height: 0 },\n    };\n  }\n\n  const emittedNode = new CapturedRenderedVirtualNode(\n    node.key,\n    elementData,\n    node.component?.instance,\n    generatedChildren,\n    renderer,\n  );\n\n  onEmit(node, emittedNode);\n\n  return emittedNode;\n}\n\n/**\n * Build an ImmutableVirtualNode tree from the root.\n * Returns the generated node for the given node, or undefined if\n * the node was not found (should not happen unless the renderer\n * has an inccorrect state.).\n */\nfunction captureVirtualNode(\n  root: VirtualNode,\n  node: VirtualNode,\n  renderer: Renderer,\n): IRenderedVirtualNode | undefined {\n  let outNode: IRenderedVirtualNode | undefined;\n\n  if (root.children) {\n    // The root is a placeholder, it's not technically an element or component so we\n    // only explicitly visit the direct children of it.\n    for (const rootChild of root.children.children) {\n      doCaptureVirtualNode(rootChild, renderer, (visited, emitted) => {\n        if (visited === node) {\n          outNode = emitted;\n        }\n      });\n    }\n  }\n\n  return outNode;\n}\n\nfunction makeSlotFunction<F extends AnyRenderFunction>(\n  renderer: Renderer,\n  slot: ComponentSlotData<F>,\n): SlotFunction<F> {\n  const slotFunction = function (...args: Parameters<F>): ReturnType<F> {\n    slot.lastParameters = args;\n\n    renderer.beginSlot(slot);\n\n    slot.renderFunc.apply(undefined, args);\n\n    renderer.endSlot(slot);\n\n    return undefined as any;\n  } as SlotFunction<F>;\n\n  slotFunction[SLOT_DATA_KEY] = slot;\n\n  return slotFunction;\n}\n\n/**\n * TODO(simon): Remaining possible optimizations:\n *\n * - Interning ViewClass: we ask the c++ runtime for a unique object representing a view class.\n *   The view class already contains the bound attributes which allows to not have to do a lookup\n *    in the main thread.\n *\n */\n\nexport class Renderer implements IRenderer {\n  static debug = false;\n\n  contextId: string;\n\n  readonly delegate: IRendererDelegate;\n\n  // Used for resolving nested rendering.\n  private parent: Renderer | undefined;\n\n  private currentNode: VirtualNode | undefined;\n  private nodeStack: VirtualNode[] = [];\n\n  readonly nodeTree: VirtualNode;\n  private readonly elementTree: RenderedElement;\n\n  private renderId = Symbol();\n  private nodeIdSequence = 0;\n  private hasObservers = false;\n  private elementById: { [id: number]: RenderedElement } = {};\n  private pendingRenders: (() => void)[] = [];\n  private completions: (() => void)[] | undefined;\n  private componentRerendersCount = 0;\n  private rootRendersCount = 0;\n  private beginCount = 0;\n  private observers: RendererObserver[] = [];\n  private nextAnimationCancelToken: CancelToken = 0;\n  private eventListener: IRendererEventListener | undefined = undefined;\n  private allowedRootElementTypes?: StringSet;\n\n  /** Moves buffered during render; flushed in top-down order at end to avoid bottom-up attach (ANR). */\n  private pendingRootMove: { elementId: number } | undefined = undefined;\n  private pendingMovesByParent = new Map<number, Array<{ elementId: number; parentIndex: number }>>();\n  private pendingMoveElementIds = new Set<number>();\n\n  /** When true (gated by VALDI_MAX_VIEW_OPERATIONS_PROCESSING_TIME), emit moves in top-down order. */\n  private _useTopDownMoveOrder: boolean = false;\n\n  enableLog: boolean = false;\n  private logComponentsOnly = true;\n\n  get began(): boolean {\n    return this.beginCount > 0;\n  }\n\n  constructor(\n    contextId: string,\n    allowedRootElementTypes: string[] | undefined,\n    delegate: IRendererDelegate,\n    useTopDownMoveOrder?: boolean,\n  ) {\n    this.contextId = contextId;\n    this.delegate = delegate;\n    this._useTopDownMoveOrder = useTopDownMoveOrder ?? false;\n    if (allowedRootElementTypes) {\n      this.allowedRootElementTypes = {};\n      for (const allowedRootElementType of allowedRootElementTypes) {\n        this.allowedRootElementTypes[allowedRootElementType] = true;\n      }\n    }\n\n    this.nodeTree = {\n      lastRenderId: this.renderId,\n      key: '',\n      element: undefined,\n      children: undefined,\n      parent: undefined,\n      parentComponent: undefined,\n      parentElement: undefined,\n      parentIndex: 0,\n    };\n    this.elementTree = {\n      virtualNode: this.nodeTree,\n      id: 0,\n      attributes: {},\n      childrenHead: undefined,\n      childrenDirty: true,\n      nodePrototype: undefined,\n      frame: undefined,\n      next: undefined,\n      prev: undefined,\n      parentIndex: undefined,\n    };\n    this.nodeTree.element = this.elementTree;\n  }\n\n  batchUpdates(block: () => void) {\n    if (this.began) {\n      block();\n    } else {\n      try {\n        this.doBegin();\n        block();\n      } catch (err: any) {\n        this.onUncaughtError('Got an error while rendering batch update', err);\n        throw err;\n      } finally {\n        this.doEnd();\n      }\n    }\n  }\n\n  animate(options: AnimationOptions, block: () => void): CancelToken {\n    this.validateAnimationOptions(options);\n    const token = ++this.nextAnimationCancelToken;\n\n    this.batchUpdates(() => {\n      try {\n        this.beginAnimation(options, token);\n        block();\n      } finally {\n        this.endAnimation();\n      }\n    });\n    return token;\n  }\n\n  cancelAnimation(token: CancelToken) {\n    this.batchUpdates(() => {\n      this.delegate.onAnimationCancel(token);\n    });\n  }\n\n  private validateAnimationOptions(options: MergeType<AnimationOptions>) {\n    if (options.duration === undefined) {\n      this.validateSpringAnimationOptions(options);\n    } else {\n      this.validateBasicAnimationOptions(options as BasicAnimationOptions);\n    }\n  }\n\n  private validateSpringAnimationOptions(options: Partial<SpringAnimationOptions>) {\n    if (!options.stiffness || options.stiffness < 0) {\n      throw new Error(`Spring animation damping must be greater than 0. Provided: ${options.stiffness}`);\n    }\n\n    if (!options.damping || options.damping < 0) {\n      throw new Error(`Spring animation damping must be greater than 0. Provided: ${options.damping}`);\n    }\n  }\n\n  private validateBasicAnimationOptions(options: BasicAnimationOptions) {\n    if (options.duration <= 0) {\n      throw new Error(`Animation duration must be greater than 0. Provided: ${options.duration}`);\n    }\n  }\n\n  doBegin() {\n    if (this.currentNode) {\n      throw Error('Already rendering');\n    }\n\n    this.renderId = Symbol();\n    this.beginCount++;\n\n    if (this.beginCount === 1) {\n      this.parent = currentRenderer;\n      // eslint-disable-next-line @typescript-eslint/no-this-alias\n      currentRenderer = this;\n\n      this.delegate.onRenderStart();\n      if (this.eventListener) {\n        this.eventListener.onRenderBegin();\n      }\n\n      if (!this.hasObservers) {\n        this.hasObservers = true;\n        this.delegate.registerVisibilityObserver(this.elementsVisibilityChanged.bind(this));\n        this.delegate.registerFrameObserver(this.processFrameUpdates.bind(this));\n      }\n    }\n  }\n\n  renderRoot(renderFunc: () => void) {\n    this.begin();\n    try {\n      this.rootRendersCount++;\n      renderFunc();\n    } catch (err: any) {\n      this.onUncaughtError('Got an error while rendering root component', err);\n      throw err;\n    } finally {\n      this.end();\n    }\n  }\n\n  renderRootComponent<T extends IComponent<ViewModel, Context>, ViewModel = any, Context = any>(\n    ctr: ComponentConstructor<T>,\n    prototype: ComponentPrototype,\n    viewModel: ViewModel,\n    context: Context,\n  ) {\n    this.renderRoot(() => {\n      this.beginComponent(ctr, prototype);\n      if (context) {\n        this.setComponentContext(context);\n      }\n      if (viewModel) {\n        this.setViewModelProperties(viewModel);\n      }\n      this.endComponent();\n    });\n  }\n\n  dumpLogMetadata(): DumpedLogs {\n    const logInfo: RendererLogInfo = {\n      treeId: this.contextId,\n      componentRerendersCount: this.componentRerendersCount,\n      rootRendersCount: this.rootRendersCount,\n      componentsCount: 0,\n      elementsCount: 0,\n      slotsCount: 0,\n    };\n\n    if (this.nodeTree.children && this.nodeTree.children.children[0]) {\n      this.collectLogInfo(this.nodeTree.children.children[0], logInfo);\n    }\n\n    return {\n      verbose: logInfo,\n    };\n  }\n\n  begin() {\n    this.doBegin();\n\n    const node = this.nodeTree;\n    node.lastRenderId = this.renderId;\n    this.pushVirtualNode(node);\n  }\n\n  doEnd() {\n    if (currentRenderer !== this) {\n      throw Error('Unbalanced Renderer begin()/end() calls');\n    }\n\n    this.currentNode = undefined;\n\n    while (this.nodeStack.length) {\n      this.nodeStack.pop();\n    }\n\n    if (this.beginCount === 1) {\n      if (this._useTopDownMoveOrder) {\n        this.flushPendingMovesInTopDownOrder();\n      }\n      // Flush our pending nested render callbacks\n      while (this.pendingRenders.length) {\n        const pendingRender = this.pendingRenders.shift();\n        pendingRender!();\n      }\n    }\n\n    this.beginCount -= 1;\n\n    if (this.beginCount === 0) {\n      currentRenderer = this.parent;\n      this.parent = undefined;\n\n      this.delegate.onRenderEnd();\n      if (this.eventListener) {\n        this.eventListener.onRenderEnd();\n      }\n\n      if (this.completions) {\n        const completions = this.completions;\n        this.completions = undefined;\n        for (const completion of completions) {\n          completion();\n        }\n      }\n    }\n  }\n\n  end() {\n    this.popVirtualNode();\n    this.doEnd();\n  }\n\n  beginAnimation(options: AnimationOptions, token: CancelToken) {\n    this.delegate.onAnimationStart(options, token);\n  }\n\n  endAnimation() {\n    this.delegate.onAnimationEnd();\n  }\n\n  isComponentAlive(component: IComponent): boolean {\n    const renderedComponent = (component as any)[renderedComponentKey];\n    return renderedComponent && renderedComponent !== destroyedComponentTombstone;\n  }\n\n  private collectLogInfo(node: VirtualNode, logInfo: RendererLogInfo) {\n    if (node.element) {\n      logInfo.elementsCount++;\n    } else if (node.component) {\n      logInfo.componentsCount++;\n    } else if (node.slot) {\n      logInfo.slotsCount++;\n    }\n\n    if (node.children) {\n      for (const child of node.children.children) {\n        this.collectLogInfo(child, logInfo);\n      }\n    }\n  }\n\n  private resolveRenderedComponent(component: IComponent): RenderedComponent {\n    const renderedComponent: RenderedComponent | undefined | typeof destroyedComponentTombstone = (component as any)[\n      renderedComponentKey\n    ];\n    if (!renderedComponent) {\n      throw Error(`Could not resolve Component '${component.constructor.name}' in current Renderer`);\n    } else if (renderedComponent === destroyedComponentTombstone) {\n      throw Error(`Resolved destroyed Component '${component.constructor.name}' in current Renderer`);\n    }\n    return renderedComponent;\n  }\n\n  renderComponent(component: IComponent, viewModel: any | undefined): void {\n    const renderedComponent = this.resolveRenderedComponent(component);\n\n    if (this.currentNode) {\n      if (renderedComponent.needRendering) {\n        // It will already render\n        return;\n      }\n\n      // Wait until the renderer becomes available\n      if (!renderedComponent.rerenderScheduled) {\n        renderedComponent.rerenderScheduled = true;\n        this.pendingRenders.push(() => {\n          if (!this.isComponentAlive(component)) {\n            return;\n          }\n\n          renderedComponent.rerenderScheduled = false;\n          this.renderComponent(component, viewModel);\n        });\n      }\n\n      return;\n    }\n\n    // this.log('Component ', renderedComponent.ctr.name, ' asked to explicitly rerender');\n    this.componentRerendersCount++;\n\n    this.doBegin();\n    try {\n      trace(`renderComponent.${renderedComponent.ctr.name}`, () => {\n        // Force rerender since it was explicitly asked\n        renderedComponent.needRendering = true;\n\n        for (const observer of this.observers) {\n          if (observer.onComponentWillRerender) {\n            observer.onComponentWillRerender(component);\n          }\n        }\n\n        this.pushVirtualNode(renderedComponent.virtualNode);\n\n        if (viewModel) {\n          this.setViewModelProperties(viewModel);\n        }\n\n        this.endComponent();\n      });\n    } catch (e) {\n      console.log(e);\n    } finally {\n      this.doEnd();\n    }\n  }\n\n  beginElementIfNeeded(node: NodePrototype, key?: string): boolean {\n    this.beginElement(node, key);\n\n    const renderedNode = this.getCurrentNode();\n    const element = renderedNode.element!;\n    if (element.wasVisibleOnce) {\n      return true;\n    }\n\n    if (!this.hasAttribute('onVisibilityChanged')) {\n      this.setAttribute('onVisibilityChanged', () => {\n        this.rerenderLazyComponentIfNeeded(element);\n      });\n    }\n\n    this.endElement();\n\n    return false;\n  }\n\n  beginElement(nodePrototype: NodePrototype, key?: string) {\n    const currentNode = this.getCurrentNode();\n\n    const resolvedKey = key || nodePrototype.id;\n    const resolvedNode = this.resolveVirtualNode(currentNode, resolvedKey, undefined, undefined);\n\n    let justCreated = false;\n\n    if (!resolvedNode.element) {\n      const id = ++this.nodeIdSequence;\n\n      const element: RenderedElement = {\n        id,\n        attributes: {},\n        nodePrototype: nodePrototype,\n        childrenHead: undefined,\n        childrenDirty: true,\n        virtualNode: resolvedNode,\n        frame: undefined,\n        next: undefined,\n        prev: undefined,\n        parentIndex: undefined,\n      };\n\n      resolvedNode.element = element;\n\n      this.delegate.onElementCreated(id, nodePrototype.viewClass);\n\n      justCreated = true;\n\n      this.elementById[id] = element;\n    }\n\n    this.pushVirtualNode(resolvedNode);\n\n    if (justCreated && nodePrototype.attributes) {\n      enumeratePropertyList(nodePrototype.attributes, (name, value) => {\n        this.setAttributeOnElement(resolvedNode.element!, name, value);\n      });\n    }\n  }\n\n  endElement() {\n    const currentNode = this.currentNode;\n    if (currentNode && currentNode.parentElement === this.elementTree) {\n      for (const observer of this.observers) {\n        if (observer.onRootElementWillEndRender) {\n          observer.onRootElementWillEndRender();\n        }\n      }\n    }\n\n    this.popVirtualNode();\n  }\n\n  private callVisiblityChanged(elementIds: number[], visible: boolean, eventTime: EventTime) {\n    for (const elementId of elementIds) {\n      const element = this.elementById[elementId];\n      if (!element) {\n        continue;\n      }\n\n      const visibilityChanged = element.attributes['onVisibilityChanged'] as (\n        visible: boolean,\n        eventTime: EventTime,\n      ) => void;\n      if (visibilityChanged) {\n        visibilityChanged(visible, eventTime);\n      }\n    }\n  }\n\n  private callViewportChanged(viewportChanges: number[], eventTime: EventTime) {\n    const length = viewportChanges.length;\n\n    for (let i = 0; i < length; ) {\n      const elementId = viewportChanges[i++];\n      const x = viewportChanges[i++];\n      const y = viewportChanges[i++];\n      const width = viewportChanges[i++];\n      const height = viewportChanges[i++];\n\n      const element = this.elementById[elementId];\n      if (!element) {\n        continue;\n      }\n\n      const viewportChanged = element.attributes['onViewportChanged'] as (\n        viewport: ElementFrame,\n        frame: ElementFrame,\n        eventTime: EventTime,\n      ) => void;\n      if (viewportChanged) {\n        viewportChanged({ x, y, width, height }, element.frame!, eventTime);\n      }\n    }\n  }\n\n  private elementsVisibilityChanged(\n    appearingElements: number[],\n    disappearingElements: number[],\n    viewportChanges: number[],\n    eventTime: EventTime,\n  ) {\n    this.batchUpdates(() => {\n      this.callVisiblityChanged(disappearingElements, false, eventTime);\n      this.callVisiblityChanged(appearingElements, true, eventTime);\n      this.callViewportChanged(viewportChanges, eventTime);\n    });\n  }\n\n  private rerenderLazyComponentIfNeeded(element: RenderedElement) {\n    if (element.wasVisibleOnce) {\n      return;\n    }\n    element.wasVisibleOnce = true;\n    const topComponent = element.virtualNode.parentComponent;\n    if (!topComponent) {\n      console.warn('Unable to retrieve top component from appearing element');\n      return;\n    }\n\n    this.renderComponent(topComponent.instance!, undefined);\n  }\n\n  private pushVirtualNode(node: VirtualNode) {\n    // if (!this.logComponentsOnly || node.component) {\n    //   this.log('Begin ', getNodeDescription(node));\n    // }\n\n    if (node.children) {\n      node.children.insertionIndex = 0;\n    }\n    node.lastRenderId = this.renderId;\n\n    this.currentNode = node;\n    this.nodeStack.push(node);\n  }\n\n  private popVirtualNode() {\n    this.nodeStack.pop();\n    const newCurrentNode = this.nodeStack[this.nodeStack.length - 1];\n\n    const node = this.currentNode!;\n    this.currentNode = newCurrentNode;\n\n    this.processChildrenUpdate(node);\n\n    const element = node.element;\n    if (element) {\n      this.resolveElementChildren(node, element);\n    } else {\n      if (newCurrentNode !== node.parent) {\n        // We don't manage elements and our new current node is not our parent.\n        // This means this was a detached render. We need to see\n        // if we need to explicitly ask our parent element to resolve\n        // the children.\n        const parentElement = node.parentElement;\n        if (!parentElement) {\n          return;\n        }\n\n        if (\n          newCurrentNode &&\n          (newCurrentNode.element === parentElement || newCurrentNode.parentElement === parentElement)\n        ) {\n          // Our new current node is either our parentElement, or has the same parent element.\n          // It will take care of resolving the element children on its own.\n          return;\n        }\n\n        // Our new node is not going to take care of our element, so we do it ourself.\n        this.resolveElementChildren(parentElement.virtualNode, parentElement);\n      }\n    }\n    // if (!this.logComponentsOnly || node.component) {\n    //   this.log('Ended ', getNodeDescription(node));\n    // }\n  }\n\n  private throwDisallowedRootElementType(tag: string) {\n    const allowedRootElementTypes = Object.keys(this.allowedRootElementTypes!)\n      .map(v => `<${v}>`)\n      .join(', ');\n    throw new Error(`Root element must be one of: ${allowedRootElementTypes} (resolved root element is <${tag}>)`);\n  }\n\n  private onElementMoved(parentElement: RenderedElement, element: RenderedElement, index: number) {\n    const parentId = parentElement.id;\n    const id = element.id;\n    if (parentId === 0) {\n      // Root element\n      if (index !== 0) {\n        throw Error('Can only have 1 element as the root.');\n      }\n      const tag = element.nodePrototype!.tag;\n      if (this.allowedRootElementTypes && !this.allowedRootElementTypes[tag]) {\n        this.throwDisallowedRootElementType(tag);\n      }\n      if (this._useTopDownMoveOrder) {\n        this.pendingRootMove = { elementId: id };\n        this.pendingMoveElementIds.add(id);\n      } else {\n        this.delegate.onElementBecameRoot(id);\n      }\n    } else {\n      if (this._useTopDownMoveOrder) {\n        this.pendingMoveElementIds.add(id);\n        let list = this.pendingMovesByParent.get(parentId);\n        if (!list) {\n          list = [];\n          this.pendingMovesByParent.set(parentId, list);\n        }\n        list.push({ elementId: id, parentIndex: index });\n      } else {\n        this.delegate.onElementMoved(id, parentId, index);\n      }\n    }\n  }\n\n  /** Emit buffered moves in top-down order (parent attached before children) to avoid ANR. */\n  private flushPendingMovesInTopDownOrder() {\n    if (this.pendingRootMove === undefined && this.pendingMovesByParent.size === 0) {\n      return;\n    }\n\n    if (this.pendingRootMove) {\n      this.delegate.onElementBecameRoot(this.pendingRootMove.elementId);\n    }\n\n    for (const list of this.pendingMovesByParent.values()) {\n      list.sort((a, b) => a.parentIndex - b.parentIndex);\n    }\n\n    // Start BFS from the new root (if any) and from any stable parents (parents that are not\n    // being moved this pass but have children moving into them). Without including stable\n    // parents, a pass that both sets a new root and reparents nodes into non-root stable\n    // parents would drop those moves because the BFS only follows move chains from the root.\n    let queue: number[];\n    if (this.pendingRootMove) {\n      queue = [this.pendingRootMove.elementId];\n    } else {\n      queue = [];\n    }\n    for (const parentId of this.pendingMovesByParent.keys()) {\n      if (!this.pendingMoveElementIds.has(parentId)) {\n        queue.push(parentId);\n      }\n    }\n    queue.sort((a, b) => a - b);\n\n    let head = 0;\n    while (head < queue.length) {\n      const parentId = queue[head++];\n      const children = this.pendingMovesByParent.get(parentId);\n      if (!children) continue;\n      for (const m of children) {\n        this.delegate.onElementMoved(m.elementId, parentId, m.parentIndex);\n        queue.push(m.elementId);\n      }\n    }\n\n    this.pendingRootMove = undefined;\n    this.pendingMovesByParent.clear();\n    this.pendingMoveElementIds.clear();\n  }\n\n  private doElementIterate(\n    parentElement: RenderedElement,\n    vNodeChildren: NodeChildren<VirtualNode>,\n    call: (child: RenderedElement) => void,\n    tail?: RenderedElement,\n  ): RenderedElement | undefined {\n    for (const childVNode of vNodeChildren.children) {\n      const childElement = childVNode.element;\n      // If the element is a leaf\n      if (childElement) {\n        // Custom logic\n        call(childElement);\n        // Add the element at the tail of the new linked list\n        const head = parentElement.childrenHead;\n        if (!head) {\n          parentElement.childrenHead = childElement;\n        }\n        if (tail) {\n          tail.next = childElement;\n        }\n        childElement.next = undefined;\n        childElement.prev = tail;\n        tail = childElement;\n      }\n      // If the element is not a leaf, simply recurse\n      else {\n        if (childVNode.children) {\n          tail = this.doElementIterate(parentElement, childVNode.children, call, tail);\n        }\n      }\n    }\n    return tail;\n  }\n\n  // Resolve pass for when an element has children for the first time.\n  // This is a simplified pass where we just find all the direct elements and append\n  // them to the output.\n  private resolveElementChildrenInitial(parentElement: RenderedElement, vNodeChildren: NodeChildren<VirtualNode>) {\n    let index = 0;\n    this.doElementIterate(parentElement, vNodeChildren, childElement => {\n      // Keep the rendered index\n      childElement.parentIndex = index;\n      // Since this is an initial pass, we simply append elements\n      this.onElementMoved(parentElement, childElement, index);\n      index++;\n    });\n  }\n\n  private resolveElementChildrenIncremental(parentElement: RenderedElement, vNodeChildren: NodeChildren<VirtualNode>) {\n    let old = parentElement.childrenHead;\n    let index = 0;\n    parentElement.childrenHead = undefined;\n    this.doElementIterate(parentElement, vNodeChildren, childElement => {\n      // Keep the rendered index\n      childElement.parentIndex = index;\n      // Discard deleted elements\n      while (old && this.elementById[old.id] === undefined) {\n        const oldNext = old.next;\n        const oldPrev = old.prev;\n        if (oldPrev) {\n          oldPrev.next = oldNext;\n        }\n        if (oldNext) {\n          oldNext.prev = oldPrev;\n        }\n        old = old.next;\n      }\n      // if the existing element didn't change, leave it alone\n      if (childElement === old) {\n        old = old.next;\n      }\n      // if the existing element doesnt match the old one\n      else {\n        this.onElementMoved(parentElement, childElement, index);\n      }\n      // Remove the element from its previous linked list\n      const next = childElement.next;\n      const prev = childElement.prev;\n      if (next) {\n        next.prev = prev;\n      }\n      if (prev) {\n        prev.next = next;\n      }\n      // Move on\n      index++;\n    });\n  }\n\n  private resolveElementChildren(node: VirtualNode, element: RenderedElement) {\n    if (!element.childrenDirty) {\n      return;\n    }\n    // this.log('Resolving elements children update');\n    element.childrenDirty = false;\n\n    const vNodeChildren = node.children;\n    if (!vNodeChildren) {\n      // We are a leaf, we can stop here\n      return;\n    }\n\n    // This is the first time we process the children, we can do a simplified pass\n    if (!element.childrenHead) {\n      this.resolveElementChildrenInitial(element, vNodeChildren);\n    }\n    // We already had children, we do the full algorithm\n    else {\n      this.resolveElementChildrenIncremental(element, vNodeChildren);\n    }\n\n    element.bridge?.invalidateChildren();\n  }\n\n  private processChildrenUpdate(node: VirtualNode) {\n    const children = node.children;\n    if (!children) {\n      // We are a leaf node\n      return;\n    }\n\n    if (children.children === children.previousChildren) {\n      const expectedKeysLength = children.insertionIndex;\n      if (expectedKeysLength === children.children.length) {\n        // The keys did not change\n        // this.log('Children are the same ', expectedKeysLength);\n        return;\n      } else {\n        // Keys have been removed at the end\n        children.children = children.children.slice(0, expectedKeysLength);\n        // this.log('Children have been removed at the end, we now have ', expectedKeysLength, ' children');\n      }\n    }\n\n    // this.log('Children have changed, processing updates');\n\n    const childrenByKey = children.childByKey;\n    const previousChildren = children.previousChildren;\n\n    if (previousChildren) {\n      // We previously had children\n\n      // Figure out the items which have been removed\n\n      const currentRenderId = this.renderId;\n\n      for (const child of previousChildren) {\n        if (child.lastRenderId !== currentRenderId) {\n          // This item was not rendered in this pass.\n          // Delete it\n          delete childrenByKey[child.key];\n\n          // this.log('Child ', getNodeDescription(child), ' has been removed');\n          this.destroyVirtualNode(child, false);\n        }\n      }\n    }\n    children.previousChildren = children.children;\n\n    if (node.element) {\n      node.element.childrenDirty = true;\n    } else {\n      const parentElement = node.parentElement;\n      if (parentElement) {\n        parentElement.childrenDirty = true;\n      }\n    }\n  }\n\n  private insertNodeInParent(node: VirtualNode, children: NodeChildren<VirtualNode>): void {\n    const parentIndex = children.insertionIndex++;\n    node.parentIndex = parentIndex;\n\n    const childrenArray = children.children;\n    if (childrenArray !== children.previousChildren) {\n      // Children array is already dirty\n      childrenArray.push(node);\n    } else {\n      // Keys are not yet dirty, checking if they are\n      if (childrenArray[parentIndex] !== node) {\n        // A key change, we make a new set of keys\n        const newChildren = childrenArray.slice(0, parentIndex);\n        newChildren.push(node);\n        children.children = newChildren;\n        // this.log('Dirtied children at ', parentIndex, ' from ', getNodeDescription(node));\n      }\n    }\n  }\n\n  private resolveVirtualNode(\n    parent: VirtualNode,\n    resolvedKey: string,\n    componentConstructor: ComponentConstructor<IComponent> | undefined,\n    componentPrototype: ComponentPrototype | undefined,\n  ): VirtualNode {\n    let resolvedNode: VirtualNode | undefined;\n    let children = parent.children;\n    if (!children) {\n      children = {\n        childByKey: {},\n        children: [],\n        insertionIndex: 0,\n      };\n      parent.children = children;\n    } else {\n      resolvedNode = children.childByKey[resolvedKey];\n    }\n\n    const currentRenderId = this.renderId;\n\n    if (!resolvedNode) {\n      const parentElement = parent.element || parent.parentElement;\n      const parentComponent = parent.component || parent.parentComponent;\n\n      resolvedNode = {\n        key: resolvedKey,\n        lastRenderId: currentRenderId,\n        parentElement,\n        parentComponent,\n        children: undefined,\n        parent,\n        parentIndex: 0,\n      };\n      children.childByKey[resolvedKey] = resolvedNode;\n    } else {\n      const component = resolvedNode.component;\n      // Check if we are resolving a component and there is a key conflict\n      if (componentPrototype && component && componentPrototype !== component.prototype) {\n        const constructorName1 = componentConstructor?.name;\n        const constructorName2 = component.ctr.name;\n        throw Error(\n          [\n            `Duplicate Component '${constructorName1}' and '${constructorName2}' for resolved key '${resolvedKey}'.`,\n            `This can happen when two different components are added in the same parent with the same key,`,\n            `You can fix this issue by combining into a single <Component/> tag with conditional attributes instead.`,\n          ].join(' '),\n        );\n      }\n      if (resolvedNode.lastRenderId === currentRenderId || !!componentPrototype !== !!component) {\n        // This node was rendered twice in this render\n        // We need to render it with a new key\n\n        const duplicateKeyIndex = children.insertionIndex - resolvedNode.parentIndex + 1;\n        return this.resolveVirtualNode(\n          parent,\n          resolvedKey + duplicateKeyIndex,\n          componentConstructor,\n          componentPrototype,\n        );\n      }\n    }\n\n    this.insertNodeInParent(resolvedNode, children);\n\n    return resolvedNode;\n  }\n\n  private callComponentDisposables(component: RenderedComponent<IComponent>, disposables: ComponentDisposable[]) {\n    for (const disposable of disposables) {\n      try {\n        if (typeof disposable === 'function') {\n          disposable();\n        } else {\n          disposable.unsubscribe();\n        }\n      } catch (err: any) {\n        this.onUncaughtError(`Failed to call registered disposable on component ${component.ctr.name}`, err);\n      }\n    }\n  }\n\n  private destroyVirtualNode(node: VirtualNode, parentElementWasDestroyed: boolean) {\n    node.parent = undefined;\n\n    if (node.element) {\n      const element = node.element;\n      node.element = undefined;\n\n      delete this.elementById[element.id];\n\n      const bridge = element.bridge;\n      if (bridge) {\n        this.detachElementFromHolder(element, element.attributes['ref']);\n        this.detachElementFromHolder(element, element.attributes['$ref']);\n        element.bridge = undefined;\n      }\n\n      // Only notify the delegate for the first element being destroyed\n      // in the subtree.\n      if (!parentElementWasDestroyed) {\n        parentElementWasDestroyed = true;\n        this.delegate.onElementDestroyed(element.id);\n      }\n\n      element.attributes = EMPTY_OBJECT;\n    }\n\n    const children = node.children;\n    if (children) {\n      for (const child of children.children) {\n        this.destroyVirtualNode(child, parentElementWasDestroyed);\n      }\n      node.children = undefined;\n      children.childByKey = EMPTY_OBJECT;\n      children.children = EMPTY_ARRAY;\n      children.previousChildren = undefined;\n    }\n\n    if (node.component) {\n      const component = node.component;\n      node.component = undefined;\n\n      const componentInstance = component.instance;\n      if (componentInstance) {\n        if (component.componentRef) {\n          if (node.bridge) {\n            component.componentRef.onComponentWillDestroy(componentInstance, node.bridge);\n          } else {\n            // this shouldn't ever happen really\n            this.onUncaughtError(\n              `Failed to update component ref of ${component.ctr.name} before destroying`,\n              new Error(`Component's virtual node bridge doesn't exist`),\n            );\n          }\n          component.componentRef = undefined;\n        }\n\n        // this.log('Destroy component ', component.ctr.name);\n        (componentInstance as any)[renderedComponentKey] = destroyedComponentTombstone;\n\n        try {\n          // this.log('Destroying component ', component.ctr.name);\n          componentInstance.onDestroy();\n        } catch (err: any) {\n          this.onUncaughtError(`Failed to call onDestroy() on component ${component.ctr.name}`, err);\n        }\n\n        if (component.disposables) {\n          this.callComponentDisposables(component, component.disposables);\n          component.disposables = undefined;\n        }\n\n        const destroyCallback = component.onDestroyObserver;\n        if (destroyCallback) {\n          try {\n            destroyCallback(componentInstance);\n          } catch (err: any) {\n            this.onUncaughtError(`Failed to call onDestroyCallback on component ${component.ctr.name}`, err);\n          }\n        }\n\n        component.instance = undefined;\n        component.viewModel = undefined;\n        component.context = undefined;\n      }\n\n      node.bridge = undefined;\n    }\n\n    node.parentComponent = undefined;\n    node.parentElement = undefined;\n  }\n\n  private getCurrentNode(): VirtualNode {\n    const currentNode = this.currentNode;\n    if (currentNode === undefined) {\n      throw Error('Unbalanced beginElement()/endElement() or beginComponent()/endComponent() calls');\n    }\n    return currentNode;\n  }\n\n  private getCurrentElement(): RenderedElement {\n    const currentNode = this.currentNode;\n    if (!currentNode || !currentNode.element) {\n      throw Error('Unbalanced beginElement()/endElement() calls');\n    }\n\n    return currentNode.element;\n  }\n\n  private getCurrentComponent(): RenderedComponent {\n    const currentNode = this.currentNode;\n    if (!currentNode || !currentNode.component) {\n      throw Error('Unbalanced beginComponent()/endComponent() calls');\n    }\n\n    return currentNode.component;\n  }\n\n  private resolveComponentCatchingError(node: VirtualNode | undefined): IComponent | undefined {\n    while (node) {\n      if (node.component?.instance?.onError) {\n        return node.component.instance;\n      }\n\n      node = node.parent;\n    }\n\n    return undefined;\n  }\n\n  onUncaughtError(message: string, error: Error, sourceComponent?: IComponent) {\n    let lastRenderedNode: IRenderedVirtualNode | undefined;\n    let componentCatchingError: IComponent | undefined;\n\n    const currentNode = this.currentNode;\n    if (currentNode) {\n      lastRenderedNode = captureVirtualNode(this.nodeTree, currentNode, this);\n      componentCatchingError = this.resolveComponentCatchingError(currentNode);\n    } else if (sourceComponent) {\n      try {\n        const node = this.resolveRenderedComponent(sourceComponent).virtualNode;\n        componentCatchingError = this.resolveComponentCatchingError(node);\n      } catch (err: any) {\n        console.log(`onUncaughtError: ${err.message}`);\n      }\n    } else {\n      componentCatchingError = this.getRootComponent();\n    }\n\n    if (componentCatchingError?.onError) {\n      componentCatchingError.onError(new RendererError(message, error, lastRenderedNode));\n    } else {\n      this.delegate.onUncaughtError(message, error);\n    }\n  }\n\n  hasInjectedAttribute(name: string): boolean {\n    const component = this.getCurrentComponent();\n    const attributes = component.injectedAttributes;\n    if (!attributes) {\n      return false;\n    }\n    return !!attributes[name];\n  }\n\n  setInjectedAttribute(name: string, value: any) {\n    const component = this.getCurrentComponent();\n    let attributes = component.injectedAttributes;\n    if (!attributes) {\n      attributes = {};\n      component.injectedAttributes = attributes;\n    }\n\n    attributes[name] = value;\n  }\n\n  /**\n   * Set the attribute, returns whether the attribute has changed\n   */\n  setAttribute(name: string, value: any): boolean {\n    return this.setAttributeOnElement(this.getCurrentElement(), name, value);\n  }\n\n  setAttributeBool(name: string, value: boolean | undefined): boolean {\n    const element = this.getCurrentElement();\n    const attributes = element.attributes;\n    if (attributes[name] === value) {\n      return false;\n    }\n    attributes[name] = value;\n\n    if (value) {\n      this.delegate.onElementAttributeChangeTrue(element.id, name);\n    } else if (value === false) {\n      this.delegate.onElementAttributeChangeFalse(element.id, name);\n    } else {\n      this.delegate.onElementAttributeChangeUndefined(element.id, name);\n    }\n\n    return true;\n  }\n\n  setAttributeNumber(name: string, value: number | undefined): boolean {\n    const element = this.getCurrentElement();\n    const attributes = element.attributes;\n    if (attributes[name] === value) {\n      return false;\n    }\n    attributes[name] = value;\n\n    if (value || value === 0) {\n      this.delegate.onElementAttributeChangeNumber(element.id, name, value);\n    } else {\n      this.delegate.onElementAttributeChangeUndefined(element.id, name);\n    }\n\n    return true;\n  }\n\n  setAttributeString(name: string, value: string | undefined): boolean {\n    const element = this.getCurrentElement();\n    const attributes = element.attributes;\n    if (attributes[name] === value) {\n      return false;\n    }\n    attributes[name] = value;\n\n    if (value || value === '') {\n      this.delegate.onElementAttributeChangeString(element.id, name, value);\n    } else {\n      this.delegate.onElementAttributeChangeUndefined(element.id, name);\n    }\n\n    return true;\n  }\n\n  setAttributeFunction(name: string, value: () => void | undefined): boolean {\n    const element = this.getCurrentElement();\n    const attributes = element.attributes;\n    const oldValue = attributes[name];\n    const newValue = tryReuseCallback(element, oldValue, value);\n\n    if (oldValue === newValue) {\n      return false;\n    }\n    attributes[name] = newValue;\n\n    if (name === 'onVisibilityChanged' || name === 'onViewportChanged') {\n      if (newValue) {\n        this.setAttributeBool('observeVisibility', true);\n      }\n    } else if (name === 'onLayout') {\n      if (element.frame && newValue) {\n        this.onRenderComplete(() => {\n          newValue(element.frame);\n        });\n      }\n    } else {\n      if (newValue) {\n        this.delegate.onElementAttributeChangeFunction(element.id, name, newValue);\n      } else {\n        this.delegate.onElementAttributeChangeUndefined(element.id, name);\n      }\n    }\n\n    return true;\n  }\n\n  setAttributeStyle(name: string, value: Style<any> | undefined): boolean {\n    const element = this.getCurrentElement();\n    const attributes = element.attributes;\n    if (attributes[name] === value) {\n      return false;\n    }\n    attributes[name] = value;\n\n    if (value) {\n      this.delegate.onElementAttributeChangeStyle(element.id, name, value);\n    } else {\n      this.delegate.onElementAttributeChangeUndefined(element.id, name);\n    }\n    return true;\n  }\n\n  setAttributeRef(value: IRenderedElementHolder<any> | undefined): boolean {\n    const element = this.getCurrentElement();\n    const attributes = element.attributes;\n    const oldValue = attributes.ref;\n    if (oldValue === value) {\n      return false;\n    }\n    attributes.ref = value;\n\n    this.detachElementFromHolder(element, oldValue);\n\n    if (value) {\n      value.onElementCreated(getRenderedElementBridge(this, element));\n    }\n\n    return true;\n  }\n\n  /**\n   * Set the attributes en masse\n   */\n  setAttributes(attributes: PropertyList) {\n    const element = this.getCurrentElement();\n    enumeratePropertyList(attributes, (attributeKey, attributeValue) => {\n      this.setAttributeOnElement(element, attributeKey, attributeValue);\n    });\n  }\n\n  hasAttribute(name: string): boolean {\n    return !!this.getCurrentElement().attributes[name];\n  }\n\n  setAttributeOnElement(element: RenderedElement, name: string, value: any): boolean {\n    if (typeof value !== 'string' && (name === 'class' || name === '$class')) {\n      value = classNames(value);\n    }\n\n    const currentValue = element.attributes[name];\n    if (value instanceof Function) {\n      value = tryReuseCallback(element, currentValue, value);\n    }\n\n    if (currentValue !== value) {\n      if (Array.isArray(value) && Array.isArray(currentValue) && arrayEquals(value, currentValue)) {\n        // Bypass attribute notification if the arrays are the same.\n        element.attributes[name] = value;\n        return false;\n      }\n\n      this.onAttributeChange(element, name, value, currentValue);\n      return true;\n    }\n    return false;\n  }\n\n  private detachElementFromHolder(renderedNode: RenderedElement, holder?: IRenderedElementHolder<any>) {\n    if (holder?.onElementDestroyed) {\n      holder.onElementDestroyed(getRenderedElementBridge(this, renderedNode));\n    }\n  }\n\n  private onAttributeChange(renderedNode: RenderedElement, name: string, value: any, oldValue: any) {\n    renderedNode.attributes[name] = value;\n\n    if (name === 'ref' || name === '$ref') {\n      this.detachElementFromHolder(renderedNode, oldValue);\n\n      if (value && (value as IRenderedElementHolder<any>).onElementCreated) {\n        value.onElementCreated(getRenderedElementBridge(this, renderedNode));\n      }\n    } else if (name === 'onVisibilityChanged' || name == 'onViewportChanged') {\n      if (value) {\n        this.setAttributeOnElement(renderedNode, 'observeVisibility', true);\n      }\n    } else if (name === 'onLayout' || name === '$onLayout') {\n      if (renderedNode.frame && value) {\n        this.onRenderComplete(() => {\n          value(renderedNode.frame);\n        });\n      }\n    } else {\n      this.delegate.onElementAttributeChangeAny(renderedNode.id, name, value);\n    }\n  }\n\n  // Component rendering\n\n  beginComponent<T extends IComponent>(\n    ctr: ComponentConstructor<T>,\n    prototype: ComponentPrototype,\n    key?: string,\n    componentRef?: IRenderedComponentHolder<T, IRenderedVirtualNode>,\n  ) {\n    const resolvedKey = key || prototype.id;\n\n    const parent = this.getCurrentNode();\n    const resolvedNode = this.resolveVirtualNode(parent, resolvedKey, ctr, prototype);\n\n    let justCreated = false;\n\n    if (!resolvedNode.component) {\n      resolvedNode.component = {\n        instance: undefined,\n        ctr: ctr,\n        prototype: prototype,\n        needRendering: true,\n        viewModel: undefined,\n        viewModelChanged: false,\n        virtualNode: resolvedNode,\n        injectedAttributes: undefined,\n        rendering: false,\n        componentRef: componentRef,\n      };\n      justCreated = true;\n    }\n\n    this.pushVirtualNode(resolvedNode);\n\n    if (this.eventListener) {\n      this.eventListener.onComponentBegin(resolvedNode.key, ctr);\n    }\n\n    if (justCreated && prototype.attributes) {\n      this.setViewModelProperties(prototype.attributes);\n    }\n  }\n\n  /**\n   * @deprecated needed for VUE support only\n   */\n  beginComponentWithoutPrototype<T extends IComponent>(\n    ctr: ComponentConstructor<T>,\n    key?: string,\n    componentRef?: IRenderedComponentHolder<T, IRenderedVirtualNode>,\n  ) {\n    let prototype: ComponentPrototype = (ctr as any).componentPrototype;\n    if (!prototype) {\n      prototype = ComponentPrototype.instanceWithNewId();\n      (ctr as any).componentPrototype = prototype;\n    }\n    this.beginComponent(ctr, prototype, key, componentRef);\n  }\n\n  hasComponentContext(): boolean {\n    return !!this.getCurrentComponent().context;\n  }\n\n  setComponentContext(context: any) {\n    this.getCurrentComponent().context = context;\n  }\n\n  setComponentOnCreateObserver(observer?: (instance: any) => void) {\n    this.getCurrentComponent().onCreateObserver = observer;\n  }\n\n  setComponentOnDestroyObserver(observer?: (instance: any) => void) {\n    this.getCurrentComponent().onDestroyObserver = observer;\n  }\n\n  onRuntimeIssue(isError: boolean, message: string) {\n    for (const observer of this.observers) {\n      if (observer.onRuntimeIssue) {\n        observer.onRuntimeIssue(isError, message);\n      }\n    }\n  }\n\n  addObserver(observer: RendererObserver) {\n    this.observers.push(observer);\n  }\n\n  removeObserver(observer: RendererObserver) {\n    const idx = this.observers.indexOf(observer);\n    if (idx >= 0) {\n      this.observers.splice(idx, 1);\n    }\n  }\n\n  private createComponent(currentComponent: RenderedComponent): IComponent {\n    const parentComponent = currentComponent.virtualNode.parentComponent;\n    const contextExplicitlySet = currentComponent.context;\n\n    const componentCtr = currentComponent.ctr;\n\n    let viewModel = currentComponent.viewModel;\n    if (!viewModel && componentCtr.disallowNullViewModel) {\n      viewModel = {};\n      currentComponent.viewModel = viewModel;\n    }\n\n    let componentInstance: IComponent;\n    if (contextExplicitlySet || !parentComponent) {\n      componentInstance = new componentCtr(this, viewModel, contextExplicitlySet);\n    } else {\n      componentInstance = new componentCtr(this, viewModel, parentComponent.context);\n    }\n    (componentInstance as any)[renderedComponentKey] = currentComponent;\n\n    currentComponent.instance = componentInstance;\n    currentComponent.context = componentInstance.context;\n\n    // this.log('Creating component ', currentComponent.ctr.name);\n\n    try {\n      componentInstance.onCreate();\n    } catch (err: any) {\n      this.onUncaughtError(`Failed to call onCreate() on ${componentCtr.name}`, err);\n    }\n\n    const createCallback = currentComponent.onCreateObserver;\n    if (createCallback) {\n      createCallback(componentInstance);\n    }\n\n    if (currentComponent.viewModel) {\n      try {\n        componentInstance.onViewModelUpdate(undefined);\n      } catch (err: any) {\n        this.onUncaughtError(`Failed to call onViewModelUpdate() after onCreate() on ${componentCtr.name}`, err);\n      }\n      currentComponent.viewModelChanged = false;\n    }\n\n    currentComponent.componentRef?.onComponentDidCreate(\n      componentInstance,\n      getVirtualNodeBridge(this, currentComponent.virtualNode),\n    );\n\n    return componentInstance;\n  }\n\n  private skipVirtualNodeChildren(node: VirtualNode) {\n    const children = node.children;\n    if (!children) {\n      return;\n    }\n\n    // Sanity check, this should not happen\n    if (children.previousChildren !== children.children) {\n      throw Error(`Cannot skip rendering of children in node ${node.key} if the children were already dirty.`);\n    }\n\n    children.insertionIndex = children.children.length;\n  }\n\n  private doRerenderSlotIfNeeded<F extends AnyRenderFunction>(slotData: ComponentSlotData<F>) {\n    const node = slotData.node;\n    if (!node) {\n      return;\n    }\n    if (!node.parent) {\n      // Node was destroyed\n      slotData.node = undefined;\n      return;\n    }\n\n    this.pushVirtualNode(node);\n\n    slotData.renderFunc.apply(undefined, slotData.lastParameters!);\n\n    this.endSlot(slotData);\n  }\n\n  private rerenderSlots(children: any) {\n    if (children[IS_NAMED_SLOT_KEY]) {\n      const namedSlots = children as NamedSlotFunctions;\n\n      for (const name in namedSlots) {\n        const slotFunction = namedSlots[name];\n        if (slotFunction) {\n          this.doRerenderSlotIfNeeded(slotFunction[SLOT_DATA_KEY]);\n        }\n      }\n    } else {\n      const slotData = (children as SlotFunction<AnyRenderFunction>)[SLOT_DATA_KEY];\n\n      if (slotData) {\n        this.doRerenderSlotIfNeeded(slotData);\n      }\n    }\n  }\n\n  endComponent() {\n    const currentComponent = this.getCurrentComponent();\n\n    let componentInstance = currentComponent.instance;\n\n    let needRendering = currentComponent.needRendering;\n    const viewModel = currentComponent.viewModel;\n\n    if (!componentInstance) {\n      needRendering = true;\n      componentInstance = this.createComponent(currentComponent);\n    } else if (currentComponent.viewModelChanged) {\n      currentComponent.viewModelChanged = false;\n      const oldViewModel = componentInstance.viewModel;\n      componentInstance.viewModel = viewModel;\n\n      try {\n        componentInstance.onViewModelUpdate(oldViewModel);\n      } catch (err: any) {\n        this.onUncaughtError(`Failed to call onViewModelUpdate() on ${componentInstance.constructor.name}`, err);\n      }\n      // this.log('view model changed');\n    }\n\n    if (!needRendering) {\n      // this.log('Dont need to rerender ', currentComponent.ctr!!.name);\n\n      if (this.eventListener) {\n        this.eventListener.onBypassComponentRender();\n      }\n\n      this.skipVirtualNodeChildren(currentComponent.virtualNode);\n\n      const children = viewModel && viewModel.children;\n      if (children) {\n        // Rerender the slots\n        this.rerenderSlots(children);\n      }\n    } else {\n      // this.log('Need rendering component');\n      currentComponent.needRendering = false;\n      currentComponent.rendering = true;\n\n      // this.log('Rendering component ', currentComponent.ctr.name);\n\n      try {\n        componentInstance.onRender();\n      } catch (err: any) {\n        this.popToVirtualNode(currentComponent.virtualNode);\n        this.onUncaughtError(`Failed to render component '${currentComponent.ctr.name}'`, err);\n      }\n\n      currentComponent.rendering = false;\n    }\n\n    this.popVirtualNode();\n\n    if (this.eventListener) {\n      this.eventListener.onComponentEnd();\n    }\n\n    this.injectAttributesIfNeeded(currentComponent);\n  }\n\n  private injectAttributesIfNeeded(component: RenderedComponent) {\n    const injectedAttributes = component.injectedAttributes;\n    if (!injectedAttributes) {\n      return;\n    }\n\n    const children = component.virtualNode.children;\n    if (!children) {\n      return;\n    }\n\n    for (const attributeName in injectedAttributes) {\n      const attributeValue = injectedAttributes[attributeName];\n      for (const child of children.children) {\n        if (child.element) {\n          this.setAttributeOnElement(child.element, attributeName, attributeValue);\n        }\n      }\n    }\n  }\n\n  private popToVirtualNode(toNode: VirtualNode) {\n    while (this.currentNode && this.currentNode !== toNode) {\n      this.popVirtualNode();\n    }\n  }\n\n  hasViewModelProperty(name: string): boolean {\n    const currentComponent = this.getCurrentComponent();\n    const viewModel = currentComponent.viewModel;\n    if (!viewModel) {\n      return false;\n    }\n\n    return !!viewModel[name];\n  }\n\n  setViewModelProperty(name: string, value: any) {\n    const currentComponent = this.getCurrentComponent();\n    const viewModel = currentComponent.viewModel;\n    if (!viewModel) {\n      currentComponent.needRendering = true;\n      currentComponent.viewModelChanged = true;\n      currentComponent.viewModel = {};\n\n      if (value instanceof Function) {\n        value = tryReuseCallback(currentComponent, undefined, value);\n      }\n\n      currentComponent.viewModel[name] = value;\n    } else {\n      const oldValue = viewModel[name];\n      if (value instanceof Function) {\n        value = tryReuseCallback(currentComponent, oldValue, value);\n      }\n\n      if (oldValue !== value) {\n        if (currentComponent.viewModelChanged) {\n          // We have a new view model, we can store directly in it\n          viewModel[name] = value;\n        } else {\n          currentComponent.viewModel = { ...viewModel, [name]: value };\n          currentComponent.needRendering = true;\n          currentComponent.viewModelChanged = true;\n\n          if (this.eventListener) {\n            this.eventListener.onComponentViewModelPropertyChange(name);\n          }\n          // this.log('View model property ', name, ' changed for component ', currentComponent.ctr.name);\n        }\n      }\n    }\n  }\n\n  beginSlot<F extends AnyRenderFunction>(slotData: ComponentSlotData<F>) {\n    const parentNode = this.getCurrentNode();\n    const node = this.resolveVirtualNode(parentNode, slotData.nodeKey, undefined, undefined);\n    slotData.node = node;\n    node.slot = true;\n    this.pushVirtualNode(node);\n  }\n\n  endSlot<F extends AnyRenderFunction>(slotData: ComponentSlotData<F>) {\n    this.popVirtualNode();\n\n    if (slotData.ref) {\n      const elements: IRenderedElement[] = [];\n      this.collectElements(slotData.node!, elements);\n      slotData.ref.setElements(elements);\n    }\n  }\n\n  private throwInvalidSlot(component: RenderedComponent, slotName: string, slotValue: any) {\n    throw new Error(\n      [\n        `Cannot render slot '${slotName}' in component ${component.ctr.name}: `,\n        `found an existing slot value that isn't a slot function or a named slot.`,\n        `Found slot value inside the 'children' property is of type: ${typeof slotValue}`,\n      ].join(' '),\n    );\n  }\n\n  renderNamedSlot<T = any>(name: string, component: IComponent, ref?: IRenderedElementHolder<T>, slotKey?: string) {\n    const renderedComponent = this.resolveRenderedComponent(component);\n\n    const viewModel = renderedComponent.viewModel;\n    if (!viewModel) {\n      return;\n    }\n\n    const children = viewModel.children as NamedSlotFunctions | undefined;\n    if (!children) {\n      if (ref) {\n        ref.setElements([]);\n      }\n      return;\n    }\n\n    if (!children[IS_NAMED_SLOT_KEY]) {\n      if ((children as unknown as SlotFunction<AnyRenderFunction>)[SLOT_DATA_KEY]) {\n        if (name === 'default') {\n          this.renderUnnamedSlot(component, ref, slotKey);\n        }\n        return;\n      }\n\n      this.throwInvalidSlot(renderedComponent, name, children);\n    }\n\n    const slotFunction = children[name];\n\n    if (slotFunction) {\n      const slotData = slotFunction[SLOT_DATA_KEY];\n\n      if (slotKey) {\n        slotData.nodeKey = slotKey;\n        slotData.isKeyExplicit = true;\n      } else if (slotData.isKeyExplicit) {\n        slotData.isKeyExplicit = false;\n        slotData.nodeKey = `${renderedComponent.virtualNode.key}$${name}`;\n      }\n\n      if (ref) {\n        slotData.ref = ref;\n      } else if (slotData.ref) {\n        slotData.ref = undefined;\n      }\n\n      slotFunction();\n    } else if (ref) {\n      ref.setElements([]);\n    }\n  }\n\n  renderUnnamedSlot<T = any>(component: IComponent, ref?: IRenderedElementHolder<T>, slotKey?: string) {\n    const renderedComponent = this.resolveRenderedComponent(component);\n\n    const viewModel = renderedComponent.viewModel;\n    if (!viewModel) {\n      return;\n    }\n\n    const slotFunction = viewModel.children as SlotFunction<AnyRenderFunction> | undefined;\n    if (!slotFunction) {\n      if (ref) {\n        ref.setElements([]);\n      }\n      return;\n    }\n\n    const slotData = slotFunction[SLOT_DATA_KEY];\n\n    if (!slotData) {\n      if ((slotFunction as unknown as NamedSlotFunctions)[IS_NAMED_SLOT_KEY]) {\n        // Our slot is a named slot, fallback to rendering the 'default' slot value\n        this.renderNamedSlot('default', component, ref, slotKey);\n        return;\n      }\n\n      this.throwInvalidSlot(renderedComponent, 'unnamed', slotFunction);\n    }\n\n    if (slotKey) {\n      slotData.nodeKey = slotKey;\n      slotData.isKeyExplicit = true;\n    } else if (slotData.isKeyExplicit) {\n      slotData.isKeyExplicit = false;\n      slotData.nodeKey = `${renderedComponent.virtualNode.key}$unnamed`;\n    }\n\n    if (ref) {\n      slotData.ref = ref;\n    } else if (slotData.ref) {\n      slotData.ref = undefined;\n    }\n\n    slotFunction();\n  }\n\n  setNamedSlot<F extends AnyRenderFunction>(name: string, renderFunc: F | undefined) {\n    const component = this.getCurrentComponent();\n\n    let viewModel = component.viewModel;\n    if (!viewModel) {\n      viewModel = {};\n      component.viewModel = viewModel;\n      component.viewModelChanged = true;\n      component.needRendering = true;\n    }\n\n    let namedSlots = viewModel.children as NamedSlotFunctions | undefined;\n\n    if (renderFunc) {\n      if (namedSlots && !namedSlots[IS_NAMED_SLOT_KEY]) {\n        if ((namedSlots as unknown as SlotFunction<AnyRenderFunction>)[SLOT_DATA_KEY] && name !== 'default') {\n          namedSlots = { [IS_NAMED_SLOT_KEY]: true, default: namedSlots as unknown as SlotFunction<AnyRenderFunction> };\n          if (component.viewModelChanged) {\n            viewModel.children = namedSlots;\n          } else {\n            component.viewModel = { ...viewModel, children: namedSlots };\n            component.viewModelChanged = true;\n            component.needRendering = true;\n          }\n        } else {\n          namedSlots = undefined;\n        }\n      }\n\n      if (!namedSlots) {\n        namedSlots = { [IS_NAMED_SLOT_KEY]: true };\n        if (component.viewModelChanged) {\n          viewModel.children = namedSlots;\n        } else {\n          component.viewModel = { ...viewModel, children: namedSlots };\n          component.viewModelChanged = true;\n          component.needRendering = true;\n        }\n      }\n\n      let slot = namedSlots[name];\n      if (!slot) {\n        // Slot does not exist, create it\n        const slotData: ComponentSlotData<F> = {\n          nodeKey: `${component.virtualNode.key}$${name}`,\n          node: undefined,\n          renderFunc,\n          lastParameters: undefined,\n        };\n        slot = makeSlotFunction(this, slotData);\n\n        if (component.viewModelChanged) {\n          namedSlots[name] = slot;\n        } else {\n          namedSlots = { ...namedSlots, [name]: slot };\n          component.viewModel = { ...viewModel, children: namedSlots };\n          component.viewModelChanged = true;\n          component.needRendering = true;\n        }\n      } else {\n        // An existing slot exists, update it\n        slot[SLOT_DATA_KEY].renderFunc = renderFunc;\n      }\n    } else {\n      // clearing the named slot\n      if (namedSlots) {\n        const slot = namedSlots[name];\n\n        if (slot) {\n          // We have an existing slot, we can remove it\n          if (component.viewModelChanged) {\n            viewModel.children = { ...namedSlots, [name]: undefined };\n          } else {\n            component.viewModel = { ...viewModel, children: { ...namedSlots, [name]: undefined } };\n            component.viewModelChanged = true;\n            component.needRendering = true;\n          }\n        }\n      }\n    }\n  }\n\n  setUnnamedSlot<F extends AnyRenderFunction>(renderFunc: F | undefined) {\n    const component = this.getCurrentComponent();\n\n    let viewModel = component.viewModel;\n    if (!viewModel) {\n      viewModel = {};\n      component.viewModel = viewModel;\n      component.viewModelChanged = true;\n      component.needRendering = true;\n    }\n\n    let slot = viewModel.children as SlotFunction<F> | undefined;\n\n    if (renderFunc) {\n      if (slot) {\n        // An existing slot exists, attempt to update it if it's compatible\n        const slotData = slot[SLOT_DATA_KEY];\n        if (slotData) {\n          slotData.renderFunc = renderFunc;\n          return;\n        } else {\n          if ((slot as unknown as NamedSlotFunctions)[IS_NAMED_SLOT_KEY]) {\n            // We have a named slot, fallback to setting the slot as 'default'\n            this.setNamedSlot('default', renderFunc);\n            return;\n          }\n\n          // Not a slot, will fallthrough to create it\n        }\n      }\n\n      // Slot does not exist, create it\n      const slotData: ComponentSlotData<F> = {\n        nodeKey: `${component.virtualNode.key}$unnamed`,\n        node: undefined,\n        renderFunc,\n        lastParameters: undefined,\n      };\n      slot = makeSlotFunction(this, slotData);\n\n      if (component.viewModelChanged) {\n        viewModel.children = slot;\n      } else {\n        component.viewModel = { ...viewModel, children: slot };\n        component.viewModelChanged = true;\n        component.needRendering = true;\n      }\n    } else {\n      // clearing the unnamed slot\n      if (slot) {\n        // We have an existing slot, we can remove it\n        if (component.viewModelChanged) {\n          viewModel.children = undefined;\n        } else {\n          component.viewModel = { ...viewModel, children: undefined };\n          component.viewModelChanged = true;\n          component.needRendering = true;\n        }\n      }\n    }\n  }\n\n  setNamedSlots(namedSlots: StringMap<AnyRenderFunction | undefined>) {\n    for (const name in namedSlots) {\n      this.setNamedSlot(name, namedSlots[name]);\n    }\n  }\n\n  setViewModelProperties(viewModel?: PropertyList) {\n    if (!viewModel) {\n      return;\n    }\n\n    enumeratePropertyList(viewModel, (key, value) => {\n      if (key !== 'children') {\n        this.setViewModelProperty(key, value);\n      }\n    });\n  }\n\n  // Will replace the component's existing view model with the\n  // new value if it is not identical.\n  setViewModelFull(viewModel?: PropertyList) {\n    const currentComponent = this.getCurrentComponent();\n    const existingViewModel = currentComponent.viewModel;\n\n    if (existingViewModel === viewModel) {\n      return;\n    }\n\n    currentComponent.needRendering = true;\n    currentComponent.viewModelChanged = true;\n\n    if (viewModel) {\n      currentComponent.viewModel = propertyListToObject(viewModel);\n    } else {\n      if (currentComponent.ctr.disallowNullViewModel) {\n        currentComponent.viewModel = {};\n      } else {\n        currentComponent.viewModel = undefined;\n      }\n    }\n  }\n\n  render(renderFunc: () => void): IRenderedElement[] {\n    const currentNode = this.getCurrentNode();\n    const beforeIndex = currentNode.children?.insertionIndex ?? 0;\n\n    renderFunc();\n\n    const children = currentNode.children;\n\n    const out: IRenderedElement[] = [];\n\n    if (children) {\n      const afterIndex = children.insertionIndex;\n      const childrenArray = children.children;\n\n      for (let i = beforeIndex; i < afterIndex; i++) {\n        this.collectElements(childrenArray[i], out);\n      }\n    }\n\n    return out;\n  }\n\n  getRootComponent(): IComponent | undefined {\n    return this.getRootComponents()[0];\n  }\n\n  getRootComponents(): IComponent[] {\n    const nodes: IComponent[] = [];\n\n    this.collectComponentsChildren(this.nodeTree, nodes);\n\n    return nodes;\n  }\n\n  getRootElement(): IRenderedElement | undefined {\n    const out: IRenderedElement[] = [];\n    if (this.nodeTree.children) {\n      for (const node of this.nodeTree.children.children) {\n        this.collectElements(node, out);\n      }\n    }\n    return out[0];\n  }\n\n  getComponentKey(component: IComponent): string {\n    return this.resolveRenderedComponent(component).virtualNode.key || '';\n  }\n\n  getComponentChildren(component: IComponent): IComponent[] {\n    const components: IComponent[] = [];\n\n    const renderedComponent = this.resolveRenderedComponent(component);\n    this.collectComponentsChildren(renderedComponent.virtualNode, components);\n\n    return components;\n  }\n\n  getComponentParent(component: IComponent): IComponent | undefined {\n    const renderedComponent = this.resolveRenderedComponent(component);\n\n    return renderedComponent.virtualNode?.parentComponent?.instance;\n  }\n\n  public getCurrentComponentInstance(): IComponent | undefined {\n    return this.getCurrentComponent().instance;\n  }\n\n  getComponentRootElements(component: IComponent, collectElementsOfChildComponents: boolean): IRenderedElement[] {\n    const renderedComponent = this.resolveRenderedComponent(component);\n\n    const out: IRenderedElement[] = [];\n    if (collectElementsOfChildComponents) {\n      this.collectElements(renderedComponent.virtualNode, out);\n    } else {\n      const children = renderedComponent.virtualNode.children;\n      if (children) {\n        for (const child of children.children) {\n          if (child.element) {\n            out.push(getRenderedElementBridge(this, child.element));\n          }\n        }\n      }\n    }\n\n    return out;\n  }\n\n  getRootVirtualNode(): IRenderedVirtualNode | undefined {\n    if (this.nodeTree.children) {\n      for (const node of this.nodeTree.children.children) {\n        return getVirtualNodeBridge(this, node);\n      }\n    }\n\n    return undefined;\n  }\n\n  getComponentVirtualNode(component: IComponent): IRenderedVirtualNode {\n    const renderedComponent = this.resolveRenderedComponent(component);\n    const virtualNodeBridge = getVirtualNodeBridge(this, renderedComponent.virtualNode);\n    return virtualNodeBridge;\n  }\n\n  getElementForId(elementId: number): IRenderedElement | undefined {\n    const element = this.elementById[elementId];\n    if (!element) {\n      return undefined;\n    }\n\n    return getRenderedElementBridge(this, element);\n  }\n\n  onRenderComplete(callback: () => void): void {\n    if (this.began) {\n      if (!this.completions) {\n        this.completions = [];\n      }\n      this.completions.push(callback);\n    } else {\n      callback();\n    }\n  }\n\n  onLayoutComplete(callback: () => void): void {\n    if (this.began) {\n      this.delegate.onNextLayoutComplete(callback);\n    } else {\n      this.doBegin();\n      this.delegate.onNextLayoutComplete(callback);\n      this.doEnd();\n    }\n  }\n\n  onNextRenderComplete(callback: () => void): void {\n    if (!this.completions) {\n      this.completions = [];\n    }\n    this.completions.push(callback);\n  }\n\n  registerComponentDisposable(component: IComponent, disposable: ComponentDisposable) {\n    const renderedComponent = this.resolveRenderedComponent(component);\n\n    let disposables = renderedComponent.disposables;\n    if (!disposables) {\n      disposables = [];\n      renderedComponent.disposables = disposables;\n    }\n\n    disposables.push(disposable);\n  }\n\n  attributeUpdatedExternally(elementId: number, attributeName: string, attributeValue: any) {\n    const element = this.getElementById(elementId);\n    if (element) {\n      element.attributes[attributeName] = attributeValue;\n    }\n  }\n\n  setEventListener(eventListener: IRendererEventListener): void {\n    this.eventListener = eventListener;\n  }\n\n  getEventListener(): IRendererEventListener | undefined {\n    return this.eventListener;\n  }\n\n  private collectElements(node: VirtualNode, output: IRenderedElement[]) {\n    if (node.element) {\n      output.push(getRenderedElementBridge(this, node.element));\n    } else {\n      const children = node.children;\n      if (children) {\n        for (const childNode of children.children) {\n          this.collectElements(childNode, output);\n        }\n      }\n    }\n  }\n\n  private collectComponentsChildren(node: VirtualNode, output: IComponent[]) {\n    const children = node.children;\n    if (children) {\n      for (const child of children.children) {\n        if (child.component) {\n          const instance = child.component.instance;\n          if (instance) {\n            output.push(instance);\n          }\n        } else {\n          this.collectComponentsChildren(child, output);\n        }\n      }\n    }\n  }\n\n  private getElementById(elementId: number): RenderedElement | undefined {\n    return this.elementById[elementId];\n  }\n\n  private processFrameUpdates(updates: Float64Array) {\n    const elementById = this.elementById;\n    let elementsWithCallback: RenderedElement[] | undefined;\n\n    trace('processFrameUpdates', () => {\n      let i = 0;\n      while (i < updates.length) {\n        const elementId = updates[i++];\n        const x = updates[i++];\n        const y = updates[i++];\n        const width = updates[i++];\n        const height = updates[i++];\n\n        const element = elementById[elementId];\n        if (element) {\n          element.frame = { x, y, width, height };\n\n          if (element.attributes.onLayout || element.attributes.$onLayout) {\n            if (!elementsWithCallback) {\n              elementsWithCallback = [];\n            }\n            elementsWithCallback.push(element);\n          }\n        }\n      }\n    });\n\n    if (elementsWithCallback) {\n      for (const element of elementsWithCallback) {\n        let onLayout = element.attributes.onLayout;\n        if (onLayout) {\n          try {\n            onLayout(element.frame);\n          } catch (err: any) {\n            this.onUncaughtError('Failed to call onLayout', err);\n          }\n        }\n        onLayout = element.attributes.$onLayout;\n        if (onLayout) {\n          try {\n            onLayout(element.frame);\n          } catch (err: any) {\n            this.onUncaughtError('Failed to call onLayout', err);\n          }\n        }\n      }\n    }\n  }\n\n  /**\n   * Verifies the integrity of the internal data structure of the Renderer.\n   */\n  verifyIntegrity() {\n    if (this.nodeStack.length) {\n      throw Error('Node stack is not empty');\n    }\n    if (this.currentNode) {\n      throw Error('We have a current node');\n    }\n    this.doVerifyIntegrity(this.nodeTree, undefined, undefined);\n  }\n\n  private doVerifyIntegrity(\n    node: VirtualNode,\n    lastParentComponent: RenderedComponent | undefined,\n    lastParentElement: RenderedElement | undefined,\n  ) {\n    if (node.component && node.element) {\n      throw Error(`Node with key ${node.key} has both component and element!`);\n    }\n\n    if (node.parentComponent !== lastParentComponent) {\n      throw Error(`Node ${node.key} has incorrect parentComponent`);\n    }\n    if (node.parentElement !== lastParentElement) {\n      throw Error(`Node ${node.key} has incorrect parentElement`);\n    }\n\n    if (node.component) {\n      const component = node.component;\n\n      if (component.needRendering) {\n        throw Error(`needRendering is true in Component ${node.key}`);\n      }\n      if (component.viewModelChanged) {\n        throw Error(`viewModelChanged is true in Component ${node.key}`);\n      }\n      if (component.rerenderScheduled) {\n        throw Error(`rerenderScheduled is true in Component ${node.key}`);\n      }\n\n      lastParentComponent = node.component;\n    }\n\n    if (node.element) {\n      const element = node.element;\n      lastParentElement = element;\n      if (element.childrenDirty) {\n        throw Error(`Children elements are dirty for ${getNodeDescription(node)}`);\n      }\n    }\n\n    const children = node.children;\n\n    if (children) {\n      if (!children.previousChildren) {\n        throw Error('Missing previousChildKeys');\n      }\n\n      if (children.previousChildren !== children.children) {\n        throw Error('Out of sync previous child keys with childKeys');\n      }\n\n      const allKeys: StringSet = {};\n\n      let index = 0;\n      for (const child of children.children) {\n        const key = child.key;\n\n        if (child.parentIndex !== index) {\n          throw Error(`Child ${key} should have index ${index} but has ${child.parentIndex}`);\n        }\n\n        if (child.parent !== node) {\n          throw Error(`Child ${key} should have parent ${node.key} but has ${child.parent?.key}`);\n        }\n\n        if (allKeys[key]) {\n          throw Error(`Duplicate child key ${key}`);\n        }\n\n        allKeys[key] = true;\n\n        this.doVerifyIntegrity(child, lastParentComponent, lastParentElement);\n\n        index++;\n      }\n\n      for (const childKey in children.childByKey) {\n        const child = children.childByKey[childKey];\n        if (child && !allKeys[childKey]) {\n          throw Error(`Orphan child for key ${childKey}, present in childByKey but not in childKeys list`);\n        }\n      }\n    }\n  }\n\n  // private log(...messages: any[]) {\n  //   if (!this.enableLog) {\n  //     return;\n  //   }\n\n  //   let logMessage = '';\n  //   for (let i = 0; i < this.nodeStack.length; i++) {\n  //     if (!this.logComponentsOnly || this.nodeStack[i].component) {\n  //       logMessage += '  ';\n  //     }\n  //   }\n\n  //   for (const message of messages) {\n  //     if (typeof message === 'function') {\n  //       logMessage += '<function>';\n  //     } else if (message === undefined) {\n  //       logMessage += '<undefined>';\n  //     } else {\n  //       logMessage += message.toString();\n  //     }\n  //   }\n\n  //   console.log(logMessage);\n  // }\n}\n\nexport function getRenderer(): Renderer {\n  const renderer = currentRenderer;\n  if (!renderer) {\n    throw Error('Cannot call this outside of a onRender callback');\n  }\n\n  return renderer;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/RendererFactory.d.ts",
    "content": "import { Renderer } from './Renderer';\n\nexport interface RendererFactory {\n  makeRenderer(treeId: string): Renderer;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/RootComponentsManager.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { StringSet } from 'coreutils/src/StringSet';\nimport { registerLogMetadataProvider } from './BugReporter';\nimport { ComponentPath, parseComponentPath, resolveComponentConstructor } from './ComponentPath';\nimport { ComponentRef } from './ComponentRef';\nimport { makeEntryPointRenderFunction } from './EntryPointComponent';\nimport { EntryPointRenderFunction } from './EntryPointRenderFunction';\nimport { IComponent } from './IComponent';\nimport { IEntryPointComponent } from './IEntryPointComponent';\nimport { RequireFunc } from './IModuleLoader';\nimport { fromRenderedVirtualNode } from './IRenderedVirtualNodeData';\nimport { IRootComponentsManager } from './IRootComponentsManager';\nimport { getModuleLoader } from './ModuleLoaderGlobal';\nimport { withLocalNativeRefs } from './NativeReferences';\nimport { Renderer } from './Renderer';\nimport { RendererFactory } from './RendererFactory';\nimport {\n  DaemonClientManager,\n  IDaemonClientManagerListener,\n  ReceivedDaemonClientMessage,\n} from './debugging/DaemonClientManager';\nimport { DebugLevel, SubmitDebugMessageFunc } from './debugging/DebugMessage';\nimport { DaemonClientMessageType, Messages, RemoteValdiContext } from './debugging/Messages';\nimport { trace } from './utils/Trace';\n\ninterface StashedRootComponentHandle {\n  contextId: string;\n  componentPath: ComponentPath;\n  componentContext: any;\n  initialViewModel: any;\n  latestViewModel: any;\n}\n\nexport interface RootComponentHandle {\n  contextId: string;\n  renderer: Renderer;\n  componentPath: ComponentPath;\n  componentContext: any;\n  initialViewModel: any;\n  latestViewModel: any;\n  rootRef: ComponentRef<IEntryPointComponent>;\n  disposeFunction: () => void;\n  renderFunction: EntryPointRenderFunction;\n}\n\nconst requireWithoutDependencies: RequireFunc = (path, disableProxy) => {\n  return getModuleLoader().load(path, disableProxy, true);\n};\n\nexport class RootComponentsManager implements IRootComponentsManager, IDaemonClientManagerListener {\n  readonly rootComponents: StringMap<RootComponentHandle> = {};\n\n  private reloadedContextIds?: string[];\n\n  constructor(\n    readonly rendererFactory: RendererFactory,\n    readonly daemonClientManager: DaemonClientManager | undefined,\n    readonly submitDebugMessage: SubmitDebugMessageFunc,\n  ) {\n    if (daemonClientManager) {\n      daemonClientManager.addListener(this);\n    }\n  }\n\n  stashData(): any {\n    const handles: StashedRootComponentHandle[] = [];\n    for (const contextId in this.rootComponents) {\n      const rootComponentHandle = this.rootComponents[contextId]!;\n\n      handles.push({\n        contextId: rootComponentHandle.contextId,\n        componentPath: rootComponentHandle.componentPath,\n        componentContext: rootComponentHandle.componentContext,\n        initialViewModel: rootComponentHandle.initialViewModel,\n        latestViewModel: rootComponentHandle.latestViewModel,\n      });\n\n      withLocalNativeRefs(contextId, () => {\n        rootComponentHandle.disposeFunction();\n\n        try {\n          rootComponentHandle.renderer.renderRoot(() => {});\n        } catch (err: any) {\n          console.error(`Error while disposing component before hot reloading:`, err);\n        }\n      });\n    }\n\n    if (this.daemonClientManager) {\n      this.daemonClientManager.removeListener(this);\n    }\n\n    return handles;\n  }\n\n  restoreData(data: any) {\n    const handles = data as StashedRootComponentHandle[];\n    if (!Array.isArray(handles)) {\n      return;\n    }\n\n    for (const handle of handles) {\n      if (this.rootComponents[handle.contextId]) {\n        continue;\n      }\n\n      withLocalNativeRefs(handle.contextId, () => {\n        this.createWithComponentPath(\n          handle.contextId,\n          handle.componentPath,\n          handle.initialViewModel,\n          handle.componentContext,\n        );\n\n        if (handle.latestViewModel !== handle.initialViewModel) {\n          this.render(handle.contextId, handle.latestViewModel);\n        }\n\n        this.onHotReloaded(handle.contextId);\n      });\n    }\n  }\n\n  private createHandle(\n    contextId: string,\n    componentPath: ComponentPath,\n    onHotReloadSubscription: (() => void) | undefined,\n    renderFunction: EntryPointRenderFunction,\n    viewModel: any,\n    componentContext: any,\n  ): RootComponentHandle {\n    const renderer = this.rendererFactory.makeRenderer(contextId);\n\n    const observerDisposer = registerLogMetadataProvider('Valdi Runtime', renderer.dumpLogMetadata.bind(renderer));\n\n    const disposeFunction = () => {\n      if (onHotReloadSubscription) {\n        onHotReloadSubscription();\n      }\n      observerDisposer();\n      renderer.delegate.onDestroyed();\n    };\n\n    const rootRef = new ComponentRef<IEntryPointComponent>();\n\n    const handle: RootComponentHandle = {\n      contextId,\n      renderer,\n      componentPath,\n      componentContext,\n      initialViewModel: viewModel,\n      latestViewModel: viewModel,\n      rootRef,\n      disposeFunction,\n      renderFunction,\n    };\n\n    this.rootComponents[contextId] = handle;\n\n    return handle;\n  }\n\n  private renderRoot(handle: RootComponentHandle, isInitialRender: boolean) {\n    handle.renderer.renderRoot(() => {\n      const traceName = isInitialRender\n        ? `createRoot.${handle.componentPath.symbolName}`\n        : `updateRoot.${handle.componentPath.symbolName}`;\n      const viewModel = isInitialRender ? handle.initialViewModel : handle.latestViewModel;\n      trace(traceName, () => {\n        handle.renderFunction(handle.rootRef, viewModel, handle.componentContext);\n      });\n    });\n  }\n\n  private makeRenderFunction(componentPath: ComponentPath): EntryPointRenderFunction {\n    return makeEntryPointRenderFunction(\n      () => resolveComponentConstructor(requireWithoutDependencies, componentPath),\n      !!this.daemonClientManager,\n      this.daemonClientManager,\n    );\n  }\n\n  private onHotReloaded(contextId: string) {\n    let reloadedContextIds = this.reloadedContextIds;\n    if (!reloadedContextIds) {\n      reloadedContextIds = [];\n      this.reloadedContextIds = reloadedContextIds;\n      setTimeout(() => {\n        this.showHotReloadedMessage();\n      });\n    }\n\n    reloadedContextIds.push(contextId);\n  }\n\n  private showHotReloadedMessage() {\n    const reloadedContextIds = this.reloadedContextIds;\n    if (!reloadedContextIds) {\n      return;\n    }\n    this.reloadedContextIds = undefined;\n\n    const allReloadedComponentPaths: StringSet = {};\n    for (const contextId of reloadedContextIds) {\n      const handle = this.rootComponents[contextId];\n      if (!handle) {\n        continue;\n      }\n\n      const componentPath = `${handle.componentPath.symbolName}@${handle.componentPath.filePath}`;\n      allReloadedComponentPaths[componentPath] = true;\n    }\n\n    this.submitDebugMessage(\n      DebugLevel.DEBUG,\n      `Reloaded ${reloadedContextIds.length} from ${Object.keys(allReloadedComponentPaths).join(', ')}`,\n    );\n  }\n\n  private hotReload(contextId: string) {\n    const handle = this.rootComponents[contextId];\n    if (!handle) {\n      return;\n    }\n\n    withLocalNativeRefs(contextId, () => {\n      // Render once empty, so that we can destroy the whole tree\n      handle.renderer.renderRoot(() => {});\n\n      // Update the render function\n      handle.renderFunction = this.makeRenderFunction(handle.componentPath);\n\n      this.renderRoot(handle, true);\n\n      if (handle.latestViewModel !== handle.initialViewModel) {\n        this.renderRoot(handle, false);\n      }\n\n      this.onHotReloaded(contextId);\n    });\n  }\n\n  getComponentForContextId(contextId: string): IComponent | undefined {\n    const handle = this.rootComponents[contextId];\n    if (!handle) {\n      return undefined;\n    }\n    return handle.renderer.getRootComponent();\n  }\n\n  createWithRenderFunction(\n    contextId: string,\n    componentPath: ComponentPath,\n    renderFunction: EntryPointRenderFunction,\n    viewModel: any,\n    componentContext: any,\n  ): void {\n    const handle = this.createHandle(contextId, componentPath, undefined, renderFunction, viewModel, componentContext);\n    this.renderRoot(handle, true);\n  }\n\n  createWithComponentPath(contextId: string, componentPath: ComponentPath, viewModel: any, componentContext: any) {\n    const onHotReloadSubscription = getModuleLoader().onHotReload(module, componentPath.filePath, () => {\n      this.hotReload(contextId);\n    });\n    const renderFunction = this.makeRenderFunction(componentPath);\n\n    const handle = this.createHandle(\n      contextId,\n      componentPath,\n      onHotReloadSubscription,\n      renderFunction,\n      viewModel,\n      componentContext,\n    );\n\n    this.renderRoot(handle, true);\n  }\n\n  create(contextId: string, componentPath: string, viewModel: any, componentContext: any): void {\n    const parsedComponentPath = parseComponentPath(componentPath);\n    this.createWithComponentPath(contextId, parsedComponentPath, viewModel, componentContext);\n  }\n\n  // TODO: rename to something like renderWithNewViewModel\n  // (to reflect the fact that this gets callde by the runtime when the root view's\n  // view model gets set).\n  render(contextId: string, viewModel: any): void {\n    const handle = this.rootComponents[contextId];\n    if (!handle) {\n      return;\n    }\n    handle.latestViewModel = viewModel;\n\n    this.renderRoot(handle, false);\n  }\n\n  destroy(contextId: string): void {\n    const handle = this.rootComponents[contextId];\n    if (!handle) {\n      return;\n    }\n\n    trace(`destroyRoot.${handle.componentPath.symbolName}`, () => {\n      delete this.rootComponents[contextId];\n      handle.disposeFunction();\n\n      handle.renderer.renderRoot(() => {});\n    });\n  }\n\n  attributeChanged(contextId: string, nodeId: number, attributeName: string, attributeValue: any): void {\n    const handle = this.rootComponents[contextId];\n    if (!handle) {\n      return;\n    }\n\n    handle.renderer.attributeUpdatedExternally(nodeId, attributeName, attributeValue);\n  }\n\n  callComponentFunction(contextId: string, functionName: string, parameters: any[]): any {\n    const rootComponent = this.rootComponents[contextId]?.rootRef.single();\n    if (!rootComponent) {\n      throw new Error(`Could not resolve component for id ${contextId}`);\n    }\n\n    return rootComponent.forwardCall(functionName, parameters);\n  }\n\n  onRuntimeIssue(contextId: string, isError: boolean, message: string): void {\n    const handle = this.rootComponents[contextId];\n    if (!handle) {\n      return;\n    }\n\n    handle.renderer.onRuntimeIssue(isError, message);\n  }\n\n  onMessage(message: ReceivedDaemonClientMessage): void {\n    if (message.message.type === DaemonClientMessageType.LIST_CONTEXTS_REQUEST) {\n      const contexts: RemoteValdiContext[] = [];\n\n      for (const treeId in this.rootComponents) {\n        const registeredRenderer = this.rootComponents[treeId]!;\n        const entryPointComponent = registeredRenderer.rootRef.single();\n        const rootComponentName = entryPointComponent?.rootComponent?.constructor.name ?? '<undefined>';\n\n        contexts.push({\n          id: treeId,\n          rootComponentName,\n        });\n      }\n\n      message.respond(requestId => Messages.listContextsResponse(requestId, contexts));\n    } else if (message.message.type === DaemonClientMessageType.GET_CONTEXT_TREE_REQUEST) {\n      const contextId = message.message.body.id;\n      const registeredRenderer = this.rootComponents[contextId];\n      if (!registeredRenderer) {\n        message.respond(requestId => Messages.errorResponse(requestId, `No context with id ${contextId}`));\n        return;\n      }\n\n      const rootNode = registeredRenderer.renderer.getRootVirtualNode();\n      if (!rootNode) {\n        message.respond(requestId => Messages.errorResponse(requestId, `No root node`));\n        return;\n      }\n\n      const rootNodeData = fromRenderedVirtualNode(rootNode, true);\n      message.respond(requestId => Messages.getContextTreeResponse(requestId, rootNodeData));\n    } else if (message.message.type === DaemonClientMessageType.TAKE_ELEMENT_SNAPSHOT_REQUEST) {\n      const contextId = message.message.body.contextId;\n      const registeredRenderer = this.rootComponents[contextId];\n      if (!registeredRenderer) {\n        message.respond(requestId => Messages.errorResponse(requestId, `No context with id ${contextId}`));\n        return;\n      }\n\n      const elementId = message.message.body.elementId;\n\n      const element = registeredRenderer.renderer.getElementForId(elementId);\n      if (!element) {\n        message.respond(requestId => Messages.errorResponse(requestId, `No node with id ${elementId}`));\n        return;\n      }\n\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      element.takeSnapshot().then(snapshot => {\n        message.respond(requestId => Messages.takeElementSnapshotResponse(requestId, snapshot ?? ''));\n      });\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/SchedulingPageComponent.ts",
    "content": "import 'valdi_tsx/src/JSX';\nimport { StatefulComponent } from './Component';\nimport { trace } from './utils/Trace';\n\n/**\n * @see IRenderer.{strategy} for more information\n */\nexport const enum SchedulingStrategy {\n  /**\n   * Doesn't execute onCreateCritical at all\n   */\n  NoExecution = -1,\n\n  /**\n   * Called immediately upon placing in the view hierarchy after initial creation.\n   *  This is the equivalent of the original Component, but this is only recommended for unit tests, or places\n   *  where multiple strategies are required\n   */\n  Immediate = 0,\n\n  /**\n   * Called immediately after the current render ends, right after the render request has been sent to the runtime.\n   *  You can expect this to happen immediately after the render calculation finished in the valdi thread,\n   *  and will typically compete with the main thread for resources, but will happen sooner than LayoutComplete\n   *\n   * If you're looking to keep it as similar as the original onCreate while still splitting the work, this is the best option\n   *\n   * @see IRenderer.onRenderComplete\n   */\n  RenderComplete = 1,\n\n  /**\n   * Called after the layout pass has been completed, which is later than RenderComplete.\n   *  You can expect this to happen 15-30ms after the render calculation finished in the valdi thread\n   *\n   * If you're looking for maximum deferral of non-critical work, while still guaranteeing execution in time, this is the best option\n   *\n   * @see IRenderer.onLayoutComplete\n   */\n  LayoutComplete = 2,\n}\n\n/**\n * Full page components can extend this class and differentiate between critical and non-critical processes\n *  to avoid delays on their first layout\n */\nexport abstract class SchedulingPageComponent<\n  ViewModel = object,\n  State = object,\n  ComponentContext = object,\n> extends StatefulComponent<ViewModel, State, ComponentContext> {\n  /**\n   * Equivalent to a normal's Component onCreate, executed immediately upon placing in the view hiearchy after initial\n   *  creation, or after it has been destroyed. Blocks the initial render until it completes\n   *\n   * Suggested usage: prepare anything required for the first layout\n   *   consider using onCreateNonCritical to subscribe to your non critical bridge observables instead\n   */\n  abstract onCreateCritical(): void;\n\n  /**\n   * Function that will be called after the critical initial render is complete\n   *  depending on the scheduling strategy is exactly when it will happen\n   *\n   * Suggested usage: hydration of any non-critical data, or subscribing to bridge observables\n   */\n  abstract onCreateNonCritical(): void;\n\n  /**\n   * How should the non-critical onCreate be scheduled\n   * @see SchedulingStrategy\n   */\n  schedulingStrategy: SchedulingStrategy = SchedulingStrategy.RenderComplete;\n\n  private boundOnCreateCritical = this.onCreateCritical.bind(this);\n  private boundOnCreateNonCritical = () => trace('onCreateNonCritical', () => this.onCreateNonCritical.call(this));\n\n  // do not override this method, override onCreateCritical and onCreateNonCritical instead\n  onCreate(): void {\n    trace('onCreateCritical', () => {\n      this.boundOnCreateCritical();\n    });\n\n    this.scheduleWithStrategy(this.boundOnCreateNonCritical);\n  }\n\n  /**\n   * Schedule a callback with the current scheduling strategy\n   * @param callback\n   */\n  scheduleWithStrategy(callback: () => void): void {\n    if (this.schedulingStrategy === SchedulingStrategy.LayoutComplete) {\n      this.renderer.onLayoutComplete(callback);\n    } else if (this.schedulingStrategy === SchedulingStrategy.RenderComplete) {\n      this.renderer.onRenderComplete(callback);\n    } else if (this.schedulingStrategy === SchedulingStrategy.Immediate) {\n      callback();\n    } else {\n      // NoExecution\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/SetTimeout.ts",
    "content": "import { ValdiRuntime } from './ValdiRuntime';\n\ndeclare const runtime: ValdiRuntime;\n\n/**\n * setTimeout implementation that guarantees that the given callback\n * will be evaluated, even if the current context was destroyed.\n * @param handler - function to evaluate after `timeout` passes.\n * @param timeout - time interval in milliseconds only after which the function should be evaluated.\n * @returns\n */\nexport function setTimeoutUninterruptible(handler: () => void, timeout?: number): number {\n  const disposable = runtime.protectNativeRefs(0);\n  return setTimeout(() => {\n    try {\n      handler();\n    } finally {\n      disposable();\n    }\n  }, timeout);\n}\n\n/**\n * setTimeout implementation that will no-op when evaluating the given\n * callback if the context was destroyed.\n * @param handler - function to evaluate after `timeout` passes.\n * @param timeout - time interval in milliseconds only after which the function should be evaluated.\n * @returns An identifier that must be passed into `clearTimeout` to cancel the timer.\n */\nexport function setTimeoutInterruptible(handler: () => void, timeout?: number): number {\n  return runtime.scheduleWorkItem(handler, timeout, true);\n}\n\n/**\n * Wrapper around our custom setTimeoutInterruptible/setTimeoutUninterruptible calls, accepting a boolean\n * parameter that controls whether the callback should be ignored when the current context is destroyed.\n * @param interruptible - if true, the handler will not be called after the valdi context is destroyed\n * @param handler - function to evaluate after `timeout` passes.\n * @param timeout - time interval in milliseconds only after which the function should be evaluated.\n * @returns An identifier that can be passed into `clearTimeout` to cancel the timer.\n */\nexport function setTimeoutConfigurable(interruptible: boolean, handler: () => void, timeout?: number): number {\n  if (interruptible) {\n    return setTimeoutInterruptible(handler, timeout);\n  } else {\n    return setTimeoutUninterruptible(handler, timeout);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/StringCache.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\n\nexport type StringInterner = (str: string) => number;\n\nexport class StringCache {\n  private interner: StringInterner;\n  private cache: StringMap<number>;\n\n  constructor(interner: StringInterner) {\n    this.interner = interner;\n    this.cache = {};\n  }\n\n  get(str: string): number {\n    let id = this.cache[str];\n    if (id !== undefined) {\n      return id;\n    }\n\n    id = this.interner(str);\n    this.cache[str] = id;\n\n    return id;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Strings.d.ts",
    "content": "export function getLocalizedString(bundle: string, key: string): string | undefined;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Style.ts",
    "content": "import { IStyle } from 'valdi_tsx/src/IStyle';\nimport { ConsoleRepresentable } from './ConsoleRepresentable';\nimport { PropertyList } from './utils/PropertyList';\n\nexport type NativeStyle = number;\n\nexport type StyleToNativeFunc = (attributes: PropertyList) => NativeStyle;\n\n/**\n * A Style object holds a bag of attributes together and can\n * serialize them inside a native single object to avoid marshalling.\n * Using Style will be more efficient than providing all attributes\n * one by one in JSX. You should typically create your Style objects\n * only once in your JS module and re-use it.\n */\nexport class Style<T> implements IStyle<T>, ConsoleRepresentable {\n  readonly attributes: Omit<T, 'style'>;\n  private native: NativeStyle | undefined;\n\n  constructor(attributes: T) {\n    this.attributes = attributes;\n    this.native = undefined;\n  }\n\n  toNative(convertFunc: StyleToNativeFunc): NativeStyle {\n    let native = this.native;\n    if (native === undefined) {\n      native = convertFunc(this.attributes);\n      this.native = native;\n    }\n\n    return native;\n  }\n\n  /**\n   * Creates a new Style object by merging the given attributes\n   * with the attributes from this style object.\n   * @param attributes\n   */\n  extend<T2>(attributes: T2): Style<Omit<T, 'style'> & T2> {\n    if (attributes instanceof Style) {\n      return this.extend(attributes.attributes);\n    }\n    const newAttributes = { ...this.attributes, ...attributes };\n    return new Style(newAttributes);\n  }\n\n  toConsoleRepresentation(): any {\n    return this.attributes;\n  }\n\n  /**\n   * Creates a new Style object by merging the given Style\n   * with this style object.\n   * @param attributes\n   */\n  // No variadic template parameters support means we cannot make this type safe:\n  // https://github.com/microsoft/TypeScript/issues/5453\n  static merge<S1, S2>(style1: Style<S1>, style2: Style<S2>): Style<S1 & S2>;\n  static merge<S1, S2, S3>(styles1: Style<S1>, style2: Style<S2>, style3: Style<S3>): Style<S1 & S2 & S3>;\n  static merge<S1, S2, S3, S4>(\n    style1: Style<S1>,\n    style2: Style<S2>,\n    style3: Style<S3>,\n    style4: Style<S4>,\n  ): Style<S1 & S2 & S3 & S4>;\n  static merge(...styles: Style<any>[]): Style<any> {\n    const attributes = styles.reduce((c, style) => {\n      return { ...c, ...style.attributes };\n    }, {});\n    return new Style(attributes);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/SymbolicatedError.d.ts",
    "content": "export interface SymbolicatedError extends Error {\n  originalStack?: string;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Symbolicator.ts",
    "content": "import { GetOrCreateSourceMapFunc, symbolicateStack } from 'source_map/src/StackSymbolicator';\nimport { getModuleLoader } from './ModuleLoaderGlobal';\nimport { SymbolicatedError } from './SymbolicatedError';\n\nlet symbolicateStackFunction:\n  | ((stack: string, getOrCreateSourceMapFunc: GetOrCreateSourceMapFunc) => string)\n  | undefined;\ntry {\n  symbolicateStackFunction = symbolicateStack;\n} catch (err: any) {\n  console.log(`symbolicateStackFunction error: ${err.message}`);\n}\n\n/**\n * Parse and symbolicate an error stack such that lines reported\n * within the stack are mapped to the original TypeScript files.\n */\nexport function symbolicateErrorStack(stack: string): string {\n  if (!symbolicateStackFunction) {\n    return stack;\n  }\n\n  return symbolicateStackFunction(stack, getModuleLoader().getOrCreateSourceMap);\n}\n\nexport function symbolicate(error: Error | SymbolicatedError): SymbolicatedError {\n  if (!symbolicateStackFunction || !error.stack) {\n    return error;\n  }\n\n  if ((error as SymbolicatedError).originalStack) {\n    return error;\n  }\n\n  const symbolicatedStack = symbolicateErrorStack(error.stack);\n\n  const newError = new (error as any).constructor(error.message) as SymbolicatedError;\n  newError.stack = symbolicatedStack;\n  newError.originalStack = error.stack;\n\n  return newError;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/SystemFont.ts",
    "content": "export const SYSTEM_FONT_NAME = 'system';\nexport const SYSTEM_BOLD_FONT_NAME = 'system-bold';\n\nfunction makeFont(fontName: string, size: number): string {\n  return `${fontName} ${size}`;\n}\n\n/**\n * Returns a font name for the system font\n * with the given size. The return value is suitable\n * for use as a \"font\" attribute of <label>, <textview>\n * or <textfield> elements.\n */\nexport function systemFont(size: number): string {\n  return makeFont(SYSTEM_FONT_NAME, size);\n}\n\n/**\n * Returns a font name for the bold system font\n * with the given size. The return value is suitable\n * for use as a \"font\" attribute of <label>, <textview>\n * or <textfield> elements.\n */\nexport function systemBoldFont(size: number): string {\n  return makeFont(SYSTEM_BOLD_FONT_NAME, size);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/TsnHelper.ts",
    "content": "// ---- Async helper\nexport function __tsn_async_helper<T>(gen: Iterator<Promise<any>, T, any>): Promise<T> {\n  return new Promise<T>(function (resolve, reject) {\n    const step = (func: typeof gen.next, arg?: any) => {\n      try {\n        const next = func.call(gen, arg);\n        if (next.done) {\n          // finished with success, resolve the promise\n          return resolve(next.value);\n        }\n        // not finished, chain off the yielded promise and step again\n        next.value.then(\n          // keep stepping until next yield (original await) passing new value to yield\n          v => step(gen.next, v),\n          e => step(gen.throw!, e),\n        );\n      } catch (e) {\n        // finished with failure, reject the promise\n        return reject(e);\n      }\n    };\n    // keep stepping until next yield (original await)\n    step(gen.next);\n  });\n}\n\n// ---- Async generator helper\ninterface AsyncGeneratorStep {\n  await?: Promise<any>;\n  yield?: any;\n}\n\nexport function __tsn_async_generator_helper(gen: Iterator<AsyncGeneratorStep, any, any>): AsyncIterableIterator<any> {\n  return {\n    [Symbol.asyncIterator](): AsyncIterableIterator<any> {\n      return this;\n    },\n    async next(a: any): Promise<IteratorResult<any, any>> {\n      try {\n        let res = gen.next(a);\n        while (res.value?.await !== undefined) {\n          res = gen.next(await res.value.await);\n        }\n        return Promise.resolve(res.done ? res.value : res.value.yield).then(v => ({ value: v, done: res.done }));\n      } catch (e: any) {\n        return Promise.reject(e);\n      }\n    },\n    return(value?: any | PromiseLike<any>): Promise<IteratorResult<any, any>> {\n      const res = gen.return?.(value);\n      return res?.done ? Promise.resolve(res) : Promise.resolve({ done: true, value: undefined });\n    },\n    throw(e?: any): Promise<IteratorResult<any, any>> {\n      const res = gen.throw?.(e);\n      return res?.done ? Promise.resolve(res) : Promise.resolve({ done: true, value: undefined });\n    },\n  };\n}\n\n// ---- Generator to async generator adaptor\nfunction asyncGeneratorAdaptor<T>(i: Iterator<T>): AsyncIterator<T> {\n  return {\n    next(): Promise<IteratorResult<T>> {\n      return Promise.resolve(i.next());\n    },\n  };\n}\n\nexport function __tsn_get_iterator<T>(gen: Iterable<T> | AsyncIterable<T>): Iterator<T> | AsyncIterator<T> {\n  if (Symbol.iterator in (gen as Iterable<T>)) {\n    return (gen as Iterable<T>)[Symbol.iterator].call(gen);\n  } else {\n    throw new Error('Object is not iterable');\n  }\n}\n\nexport function __tsn_get_async_iterator<T>(gen: Iterable<T> | AsyncIterable<T>): Iterator<T> | AsyncIterator<T> {\n  if (Symbol.asyncIterator in (gen as Iterable<T>)) {\n    return (gen as AsyncIterable<T>)[Symbol.asyncIterator].call(gen);\n  } else if (Symbol.iterator in (gen as Iterable<T>)) {\n    const i = (gen as Iterable<T>)[Symbol.iterator].call(gen);\n    return asyncGeneratorAdaptor(i);\n  } else {\n    throw new Error('Object is not iterable');\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/TypeConverter.d.ts",
    "content": "export interface TypeConverter<TSType, IntermediateType> {\n  /**\n   * Convert the value from TypeScript into an intermediate type\n   * that can be passed to the native code.\n   */\n  toIntermediate(value: TSType): IntermediateType;\n\n  /**\n   * Conveert the value provided as an intermediate type from the\n   * native type into a value that can be used by the TypeScript code\n   */\n  toTypeScript(value: IntermediateType): TSType;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/UncaughtErrorHandler.ts",
    "content": "import { remove } from 'coreutils/src/ArrayUtils';\nimport { ValdiRuntime, ExceptionHandlerResult } from './ValdiRuntime';\nimport { IComponent } from './IComponent';\n\ndeclare const runtime: ValdiRuntime;\n\nexport const enum UncaughtErrorHandlerResult {\n  /**\n   * Keep the default behavior for unhandled errors within the runtime.\n   */\n  USE_DEFAULT,\n  /**\n   * Ignore the error. This should be used only if the error handler\n   * fully processed the error, and there is no expectation of the\n   * error being further processed by the runtime.\n   */\n  IGNORE,\n  /**\n   * Crash the application as a result of that error.\n   */\n  CRASH_APPLICATION,\n}\n\n/**\n * Callback that will be called whenever an uncaught error or an uncaught rejected\n * promise is detected within the runtime.\n */\nexport type UncaughtErrorHandler = (isHandledRejectedPromise: boolean, error: unknown) => UncaughtErrorHandlerResult;\n\ninterface ErrorHandlersProvider {\n  errorHandlersByContextId?: { [contextId: string]: UncaughtErrorHandler[] };\n  catchAllErrorHandler?: UncaughtErrorHandler;\n}\n\ndeclare const global: ErrorHandlersProvider;\n\nfunction doCallErrorHandler(\n  errorHandler: UncaughtErrorHandler,\n  isHandledRejectedPromise: boolean,\n  error: unknown,\n): number {\n  const result = errorHandler(isHandledRejectedPromise, error);\n  switch (result) {\n    case UncaughtErrorHandlerResult.USE_DEFAULT:\n      return ExceptionHandlerResult.NOTIFY;\n    case UncaughtErrorHandlerResult.IGNORE:\n      return ExceptionHandlerResult.IGNORE;\n    case UncaughtErrorHandlerResult.CRASH_APPLICATION:\n      return ExceptionHandlerResult.CRASH;\n  }\n}\n\nfunction callErrorHandlers(\n  contextId: string,\n  isHandledRejectedPromise: boolean,\n  error: unknown,\n): ExceptionHandlerResult {\n  const catchAllErrorHandler = global.catchAllErrorHandler;\n  if (catchAllErrorHandler) {\n    return doCallErrorHandler(catchAllErrorHandler, isHandledRejectedPromise, error);\n  }\n\n  if (contextId === undefined) {\n    // Runtime Backward compatibility\n    return ExceptionHandlerResult.NOTIFY;\n  }\n\n  const handlers = global.errorHandlersByContextId?.[contextId];\n  if (!handlers?.length) {\n    return ExceptionHandlerResult.NOTIFY;\n  }\n\n  const handler = handlers[handlers.length - 1];\n  return doCallErrorHandler(handler, isHandledRejectedPromise, error);\n}\n\nruntime.setUncaughtExceptionHandler((error, contextId) => {\n  return callErrorHandlers(contextId, false, error);\n});\n\nruntime.setUnhandledRejectionHandler((promiseResult, contextId) => {\n  return callErrorHandlers(contextId, true, promiseResult);\n});\n\n/**\n * Set or unset a catch all error handler which will be resolved by default\n * for any uncaught errors.\n */\nexport function setCatchAllUncaughtErrorHandler(errorHandler: UncaughtErrorHandler | undefined) {\n  global.catchAllErrorHandler = errorHandler;\n}\n\n/**\n * Register an error handler for the given contextId. The handler will be called\n * whenever an uncaught exception or an unhandled rejected promise is found.\n * @returns a dispose function, which should be called to unregister the error handler\n */\nexport function registerUncaughtErrorHandlerForContextId(\n  contextId: string,\n  errorHandler: UncaughtErrorHandler,\n): () => void {\n  if (!global.errorHandlersByContextId) {\n    global.errorHandlersByContextId = {};\n  }\n  let handlers = global.errorHandlersByContextId[contextId];\n  if (!handlers) {\n    handlers = [];\n    global.errorHandlersByContextId[contextId] = handlers;\n  }\n  handlers.push(errorHandler);\n\n  return () => {\n    if (!global.errorHandlersByContextId) {\n      return;\n    }\n    const handlers = global.errorHandlersByContextId[contextId];\n    if (handlers) {\n      if (remove(handlers, errorHandler) && handlers.length === 0) {\n        delete global.errorHandlersByContextId[contextId];\n      }\n    }\n  };\n}\n\n/**\n * Register an error handler for the given component. The handler will be called\n * whenever an uncaught exception or an unhandled rejected promise is found.\n * The error handler applies for the entire renderer tree of the component.\n * @returns a dispose function, which should be called to unregister the error handler\n */\nexport function registerUncaughtErrorHandlerForComponent(\n  component: IComponent,\n  errorHandler: UncaughtErrorHandler,\n): () => void {\n  return registerUncaughtErrorHandlerForContextId(component.renderer.contextId, errorHandler);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/Valdi.ts",
    "content": "import { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { IRenderedElementHolder } from 'valdi_tsx/src/IRenderedElementHolder';\nimport { Layout } from 'valdi_tsx/src/NativeTemplateElements';\nimport { NativeView } from 'valdi_tsx/src/NativeView';\nimport { AnimationOptions } from './AnimationOptions';\nimport { ComponentKey } from './ComponentKey';\nimport { parseComponentPath } from './ComponentPath';\nimport { ValdiRuntime, NativeViewNodeInfo } from './ValdiRuntime';\nimport { ElementRef } from './ElementRef';\nimport { ComponentConstructor, IComponent } from './IComponent';\nimport { RequireFunc } from './IModuleLoader';\nimport { IRenderedElement } from './IRenderedElement';\nimport { IRenderer } from './IRenderer';\nimport { IRootComponentsManager } from './IRootComponentsManager';\nimport { jsx } from './JSXBootstrap';\nimport { RootComponentsManager } from './RootComponentsManager';\nimport { Style } from './Style';\nimport { DaemonClientManager } from './debugging/DaemonClientManager';\nimport { mergePartial } from './utils/PartialUtils';\n\nexport interface Attributes {\n  [attribute: string]: any;\n}\n\nexport interface Element {\n  /**\n   * If the Element has not a 'for-each' attribute, this property\n   * will be set and will contain the attributes rendered from JS.\n   */\n  attributes: Attributes;\n}\n\nexport interface Elements {\n  [id: string]: Element;\n}\n\nexport interface Actions {\n  [actionName: string]: (...args: any[]) => void;\n}\n\n// Returns a formatted string of the form: \"the $0 jumped over the $1\"\nexport function formatParameterizedString(format: string, ...formatArgs: any[]): string {\n  return format.replace(/\\$(\\d+)/g, (_, is) => {\n    const index = parseInt(is, 10);\n    if (index >= formatArgs.length) {\n      throw 'not enough args provided for string: ' + format;\n    }\n    return formatArgs[index];\n  });\n}\n\ndeclare const runtime: ValdiRuntime;\n\nexport interface ActionCaller {\n  callAction(actionName: string, parameters: any[]): void;\n}\n\n/**\n * Checks whether a given Valdi module is loaded.\n * This will return true if the module is available for\n * use without having to make an asynchronous network request.\n * @param module the Valdi module to query\n */\nexport function isModuleLoaded(module: string): boolean {\n  return runtime.isModuleLoaded(module);\n}\n\n/**\n * Asynchronously loads the given Valdi module, calls the completion\n * handler when it's done. The completion handler might be called immediately\n * if the module is already loaded.\n * @param module the Valdi module to query\n * @param completion the callback which will be called when loading has completed.\n */\nexport function loadModule(module: string, completion: (error?: string) => void): void {\n  runtime.loadModule(module, completion);\n}\n\n/**\n * Retrieves the content as a Uint8Array of a file entry at the given path\n * inside the given Valdi module.\n */\nexport function getModuleFileEntryAsBytes(module: string, path: string): Uint8Array {\n  return runtime.getModuleEntry(module, path, false) as Uint8Array;\n}\n\n/**\n * Retrieves the content as a string of a file entry at the given path\n * inside the given Valdi module.\n */\nexport function getModuleFileEntryAsString(module: string, path: string): string {\n  return runtime.getModuleEntry(module, path, true) as string;\n}\n\n/**\n * Retrieves all the JS files that are available within the given Valdi module name\n */\nexport function getModuleJsPaths(module: string): string[] {\n  return runtime.getModuleJsPaths(module);\n}\n\ninterface NodeIdPathEntry {\n  id?: string;\n  forEachKey?: string;\n}\n\nexport function parseNodeIdPath(nodeIdPath: string): NodeIdPathEntry[] {\n  const paths = new Array<NodeIdPathEntry>();\n  const elements = nodeIdPath.split('.');\n  let trailingId: string | undefined = undefined;\n  for (const element of elements) {\n    const bracketStartIdx = element.indexOf('[');\n    if (bracketStartIdx > 0) {\n      const bracketEndIdx = element.indexOf(']');\n      if (bracketEndIdx === -1 || bracketStartIdx > bracketEndIdx) {\n        throw new Error(\"Invalid nodeIdPath: '\" + nodeIdPath + \"'\");\n      }\n      const id = element.substr(0, bracketStartIdx);\n      paths.push({\n        id,\n      });\n      const forEachKey = element.substr(bracketStartIdx + 1, bracketEndIdx - bracketStartIdx - 1);\n      paths.push({\n        forEachKey,\n      });\n      trailingId = id;\n    } else {\n      paths.push({\n        id: element,\n      });\n      trailingId = undefined;\n    }\n  }\n\n  // Automatically resolves labels[1] to labels[1].labels\n  if (trailingId) {\n    paths.push({\n      id: trailingId,\n    });\n  }\n\n  return paths;\n}\n\ninterface BundleAndValdiPath {\n  // DEPRECATED: Use componentPath instead\n  valdiPath?: string;\n  componentPath?: string;\n  bundleName?: string;\n}\n\ninterface CreateComponentRequest extends BundleAndValdiPath {\n  viewModel?: any;\n  context?: any;\n}\n\nexport type UpdateElementsFunction = (elements: Elements) => void;\n\n/**\n * Unique object shared across all components for a given component tree.\n * It can be provided by native code, and altered by any component in the tree to\n * inject services.\n */\nexport interface ComponentContext {}\n\nexport type ElementsSpecs = string[];\n\nexport interface ComponentClass {\n  renderTemplate: () => void;\n  componentPath: string;\n  elements: ElementsSpecs;\n}\n\ndeclare const require: RequireFunc;\n\nfunction makeActions(actionCaller: ActionCaller): Actions {\n  return new Proxy({} as Actions, {\n    get(target, key): any {\n      let value = target[key];\n\n      if (!value) {\n        value = (...args: any[]) => {\n          actionCaller.callAction(key, args);\n        };\n        target[key] = value;\n      }\n      return value;\n    },\n  }) as Actions;\n}\n\nexport type ElementRefs<T> = { [customId: string]: ElementRef<T> };\n\nexport interface InjectedAttributes {\n  $ref?: IRenderedElementHolder<Layout>;\n  $onTap?: () => void;\n  $accessibilityId?: string;\n  $marginBottom?: number;\n  $style?: Style<Layout>;\n}\n\nexport class LegacyVueComponent<\n  ViewModelType extends object = any,\n  StateType extends object = object,\n  ContextType extends ComponentContext = ComponentContext,\n> implements ActionCaller, IComponent\n{\n  viewModel: ViewModelType & ComponentKey & InjectedAttributes;\n\n  state?: StateType;\n  context: ContextType;\n\n  get componentId(): string {\n    return this.renderer.contextId;\n  }\n\n  get componentKey(): string {\n    return this.renderer.getComponentKey(this);\n  }\n\n  get parent(): IComponent | undefined {\n    return this.renderer.getComponentParent(this);\n  }\n\n  get children(): IComponent[] {\n    return this.renderer.getComponentChildren(this);\n  }\n\n  get rootElements(): IRenderedElement[] {\n    return this.renderer.getComponentRootElements(this, false);\n  }\n\n  get elementIdWithinParent(): string | undefined {\n    for (const rootElement of this.rootElements) {\n      const value = rootElement.getAttribute('$id');\n      if (value) {\n        return value;\n      }\n    }\n    return undefined;\n  }\n\n  readonly renderer: IRenderer;\n\n  get componentClass(): ComponentClass {\n    return this.constructor as any as ComponentClass;\n  }\n\n  private _actions?: Actions;\n  get actions(): Actions {\n    if (!this._actions) {\n      this._actions = makeActions(this);\n    }\n    return this._actions;\n  }\n\n  private _elements?: Elements;\n  get elements(): Elements {\n    if (!this._elements) {\n      const elements: Elements = {};\n      for (const elementId of this.componentClass.elements) {\n        const elementRef = this.elementRefs[elementId]!;\n\n        const attributesProxy = new Proxy(elementRef, {\n          get(target, key) {\n            return target.getAppliedAttribute(key);\n          },\n          set(target, attribute, attributeValue): boolean {\n            target.setAttribute(attribute, attributeValue);\n            return true;\n          },\n        });\n        elements[elementId] = { attributes: attributesProxy };\n      }\n      this._elements = elements;\n    }\n    return this._elements;\n  }\n\n  private _elementRefs?: ElementRefs<any>;\n  get elementRefs(): ElementRefs<any> {\n    if (!this._elementRefs) {\n      this._elementRefs = {};\n    }\n    return this._elementRefs;\n  }\n\n  private animationOptions?: AnimationOptions;\n\n  constructor(renderer: IRenderer, viewModel: any, context: any) {\n    this.renderer = renderer;\n    this.viewModel = viewModel;\n\n    this.context = context;\n\n    const componentClass = this.componentClass;\n    if (!componentClass.renderTemplate) {\n      // Automatically import the generated JS\n      require(parseComponentPath(componentClass.componentPath).filePath, true, true);\n    }\n\n    if (componentClass.elements.length) {\n      const elementRefs = this.elementRefs;\n      for (const elementId of componentClass.elements) {\n        elementRefs[elementId] = new ElementRef();\n      }\n    }\n  }\n\n  /**\n   * Render the template (resolve all dynamic attributes in the template)\n   * and send all changes to the runtime.\n   */\n  render(): void {\n    this.renderer.renderComponent(this, undefined);\n  }\n\n  onRender() {\n    const animationOptions = this.animationOptions;\n    if (animationOptions) {\n      this.animationOptions = undefined;\n      this.renderer.animate(animationOptions, this.onRender.bind(this));\n    } else {\n      this.componentClass.renderTemplate.apply(this);\n    }\n  }\n\n  /**\n   * Animate the view tree using the given animation options.\n   * The animations closure will be called\n   */\n  animate(options: AnimationOptions, animations: () => void): Promise<void> {\n    return new Promise(resolve => {\n      this.renderer.animate(\n        {\n          ...options,\n          completion: () => {\n            options.completion?.(false);\n            resolve();\n          },\n        },\n        () => {\n          animations();\n          this.renderer.renderComponent(this, undefined);\n        },\n      );\n    });\n  }\n\n  private stringIdsToElementIds(elementIds: string[]): number[] {\n    const out: number[] = [];\n\n    for (const elementId of elementIds) {\n      const ref = this.elementRefs[elementId];\n      if (ref) {\n        for (const realElementId of ref.all()) {\n          out.push(realElementId.id);\n        }\n      }\n    }\n    return out;\n  }\n\n  private callRuntimeElementIdMethodFromStringIds<T>(\n    stringIds: Array<string>,\n    runtimeMethod: (contextId: string, elementId: number, callback: (result: T | undefined) => void) => void,\n    callback: (result: Array<T>) => void,\n  ): void {\n    this.renderer.onRenderComplete(() => {\n      this.callRuntimeElementIdMethod(this.stringIdsToElementIds(stringIds), runtimeMethod, callback);\n    });\n  }\n\n  private callRuntimeElementIdMethod<T>(\n    elementIds: Array<number>,\n    runtimeMethod: (contextId: string, elementId: number, callback: (result: T | undefined) => void) => void,\n    callback: (result: Array<T>) => void,\n  ): void {\n    let callbackCount = 0;\n    const output: (T | undefined)[] = [];\n\n    for (let i = 0; i < elementIds.length; i++) {\n      const elementId = elementIds[i];\n      output.push(undefined);\n\n      runtimeMethod(this.componentId, elementId, result => {\n        output[i] = result;\n        callbackCount++;\n        if (callbackCount === elementIds.length) {\n          callback(output as Array<T>);\n        }\n      });\n    }\n  }\n\n  /**\n   * Returns the view frames for the given elements.\n   * It is more efficient and often more practical to use the `on-layout` attribute,\n   * which will call the given function whenever the frame of the element changes.\n   * @param elementIds\n   * @param callback\n   */\n  getElementFrames(elementIds: Array<string>, callback: (frames: Array<ElementFrame>) => void): void {\n    this.callRuntimeElementIdMethodFromStringIds(elementIds, runtime.getFrameForElementId, callback);\n  }\n\n  getElementFramesFromRawElementIds(elementIds: Array<number>, callback: (frames: Array<ElementFrame>) => void): void {\n    this.callRuntimeElementIdMethod(elementIds, runtime.getFrameForElementId, callback);\n  }\n\n  /**\n   * Returns the native view objects for the given elements. These views are only useful when passed to native.\n   * @param elementIds\n   * @param callback\n   */\n  getElementNativeViews(elementIds: Array<string>, callback: (views: Array<NativeView>) => void): void {\n    this.callRuntimeElementIdMethodFromStringIds(elementIds, runtime.getNativeViewForElementId, callback);\n  }\n\n  /**\n   * Returns the recursive layout debug info of the given elementIds in HTML format.\n   * This will give all layout attributes applied to the given elementIds and their children,\n   * and the calculated position and dimensions for them.\n   * Giving the root element id will return the whole tree.\n   * @param elementIds\n   * @param callback\n   */\n  getElementLayoutDebugInfos(elementIds: Array<string>, callback: (layoutInfos: Array<string>) => void): void {\n    this.callRuntimeElementIdMethodFromStringIds(elementIds, runtime.getLayoutDebugInfo, callback);\n  }\n\n  /**\n   * Returns the recursive native debug infos of the given elementIds.\n   * This will give all applied attributes, which includes CSS attributes, static attributes,\n   * dynamic attributes and attributes applied manually from JS.\n   * @param elementIds\n   * @param callback\n   */\n  getElementNativeDebugInfos(\n    elementIds: Array<string>,\n    callback: (nativeDebugInfos: Array<NativeViewNodeInfo>) => void,\n  ): void {\n    this.callRuntimeElementIdMethodFromStringIds(elementIds, runtime.getViewNodeDebugInfo, callback);\n  }\n\n  /**\n   * Called whenever the view model has changed on this component\n   * @param previousViewModel\n   */\n  onViewModelUpdate(previousViewModel?: ViewModelType): void {}\n\n  /**\n   * Called after a state has changed on this component.\n   * @param previousState\n   */\n  onStateUpdate(previousState?: StateType) {}\n\n  /**\n   * Called when the component is created.\n   */\n  onCreate() {}\n\n  /**\n   * Called wen the component was destroyed\n   */\n  onDestroy() {}\n\n  /**\n   * Call the action with the given name and pass\n   * the given parameters.\n   */\n  callAction(actionName: string, parameters: any[]) {\n    runtime.postMessage(this.componentId, 'callAction', {\n      action: actionName,\n      parameters,\n    });\n  }\n\n  /**\n   * setState applies the given partial state or updater to the internal state and requests\n   * a re-render. You may pass in an optional\n   * callback that is invoked after the state has been applied and the component updated.\n   */\n  setState(updater: Partial<StateType>, callback?: () => void) {\n    if (this.isDestroyed()) {\n      return;\n    }\n\n    const newState = mergePartial(updater, this.state);\n    if (newState) {\n      this.state = newState;\n      this.render();\n    }\n\n    if (callback) {\n      callback();\n    }\n  }\n\n  /**\n   * Registers a function which will be called right after the component is destroyed.\n   * @param disposable the callback to call after the component is destroyed\n   */\n  registerDisposable(disposable: () => void): void {\n    this.renderer.registerComponentDisposable(this, disposable);\n  }\n\n  /**\n   * Set an AnimationOptions to use for the next render.\n   * You can use this method as part of an onViewModelUpdate callback\n   *\n   * @param animationOptions\n   */\n  setAnimationOptionsForNextRender(animationOptions: AnimationOptions | undefined): void {\n    this.animationOptions = animationOptions;\n  }\n\n  /**\n   * Changes the state by merging the given partial state.\n   * Will synchronously re-render the component if the state changes.\n   * Any elements mutation that happens within that setState call will be animated.\n\n   * @return A promise which will be resolved when the animation finishes.\n   */\n  setStateAnimated(state: Partial<StateType>, animationOptions: AnimationOptions): Promise<void> {\n    return this.animate(animationOptions, () => {\n      this.setState(state);\n    });\n  }\n\n  /**\n   * Returns whether the Component was destroyed.\n   */\n  isDestroyed(): boolean {\n    return !this.renderer.isComponentAlive(this);\n  }\n\n  static resolveBundleAndPath(componentPath: string, bundleName?: string): BundleAndValdiPath {\n    const bundleSeparatorIdx = componentPath.indexOf(':');\n    if (bundleSeparatorIdx != -1) {\n      bundleName = componentPath.substring(0, bundleSeparatorIdx);\n      componentPath = componentPath.substring(bundleSeparatorIdx + 1);\n    }\n\n    return { bundleName: bundleName, valdiPath: componentPath };\n  }\n\n  static componentPath: string;\n\n  static setup<T extends IComponent>(\n    componentClass: ComponentConstructor<T>,\n    elements: ElementsSpecs,\n    renderTemplate: () => void,\n  ) {\n    const resolvedClass = componentClass as any as ComponentClass;\n    resolvedClass.renderTemplate = renderTemplate;\n    resolvedClass.elements = elements;\n  }\n}\n\n/**\n * StatefulComponent manages lifecycle and rendering with its own state. By default,\n * this component is re-rendered after every setState call, so consider using\n * PureComponent instead. See #setState method for more info.\n */\n// Deprecated for backward-compatibility, use Component\nexport class LegacyVueStatefulComponent<\n  ViewModelType extends object = object,\n  StateType extends object = object,\n  ContextType extends ComponentContext = ComponentContext,\n> extends LegacyVueComponent<ViewModelType, StateType, ContextType> {}\n\n/**\n * PureComponent is a component that implements shouldComponentUpdate with a shallow\n * view model and state comparison.\n */\n// Deprecated for backward-compatibility, use Component\nexport class LegacyVuePureComponent<\n  ViewModelType extends object = object,\n  StateType extends object = object,\n  ContextType extends ComponentContext = ComponentContext,\n> extends LegacyVueComponent<ViewModelType, StateType, ContextType> {}\n\ninterface NavigationPushInfo {\n  animated?: boolean;\n  newNavigationTitle?: string;\n}\n\nexport interface NavigationPush extends CreateComponentRequest, NavigationPushInfo {}\n\ninterface NavigationPresentInfo extends NavigationPushInfo {\n  wrapInNavigationController: boolean;\n}\n\ninterface NavigationPresent extends CreateComponentRequest, NavigationPresentInfo {}\n\ninterface TypedNavigationRequest<\n  ViewModelType extends object,\n  ContextType extends ComponentContext,\n  T extends LegacyVueComponent<ViewModelType, any, ContextType>,\n> {\n  componentClass: ComponentConstructor<T>;\n  viewModel?: ViewModelType;\n  context?: ContextType;\n}\n\ninterface PushComponentRequest<\n  ViewModelType extends object,\n  ContextType extends ComponentContext,\n  T extends LegacyVueComponent<ViewModelType, any, ContextType>,\n> extends TypedNavigationRequest<ViewModelType, ContextType, T>,\n    NavigationPushInfo {}\n\ninterface PresentComponentRequest<\n  ViewModelType extends object,\n  ContextType extends ComponentContext,\n  T extends LegacyVueComponent<ViewModelType, any, ContextType>,\n> extends TypedNavigationRequest<ViewModelType, ContextType, T>,\n    NavigationPresentInfo {}\n\nfunction makeCreateRequest<\n  ViewModelType extends object,\n  ContextType extends ComponentContext,\n  T extends LegacyVueComponent<ViewModelType, any, ContextType>,\n>(request: TypedNavigationRequest<ViewModelType, ContextType, T>): CreateComponentRequest {\n  const valdiPath = (request.componentClass as any).componentPath;\n  const resolvedBundleAndPath = LegacyVueComponent.resolveBundleAndPath(valdiPath);\n  return {\n    valdiPath: resolvedBundleAndPath.valdiPath,\n    bundleName: resolvedBundleAndPath.bundleName,\n    viewModel: request.viewModel,\n    context: request.context,\n  };\n}\n\nexport class Navigation {\n  private actionCaller: ActionCaller;\n\n  constructor(actionCaller: ActionCaller) {\n    this.actionCaller = actionCaller;\n  }\n\n  push(navigationPush: NavigationPush): void {\n    this.actionCaller.callAction('push', [navigationPush]);\n  }\n\n  pushTyped<\n    ViewModelType extends object,\n    ContextType extends ComponentContext,\n    T extends LegacyVueComponent<ViewModelType, any, ContextType>,\n  >(navigationPush: PushComponentRequest<ViewModelType, ContextType, T>): void {\n    const request = makeCreateRequest(navigationPush);\n\n    this.push({\n      ...request,\n      animated: navigationPush.animated,\n      newNavigationTitle: navigationPush.newNavigationTitle,\n    });\n  }\n\n  present(navigationPresent: NavigationPresent): void {\n    this.actionCaller.callAction('present', [navigationPresent]);\n  }\n\n  presentTyped<\n    ViewModelType extends object,\n    ContextType extends ComponentContext,\n    T extends LegacyVueComponent<ViewModelType, any, ContextType>,\n  >(navigationPresent: PresentComponentRequest<ViewModelType, ContextType, T>): void {\n    const request = makeCreateRequest(navigationPresent);\n    this.present({\n      ...request,\n      animated: navigationPresent.animated,\n      newNavigationTitle: navigationPresent.newNavigationTitle,\n      wrapInNavigationController: navigationPresent.wrapInNavigationController,\n    });\n  }\n\n  back(animated: boolean = true) {\n    this.actionCaller.callAction('back', [\n      {\n        animated,\n      },\n    ]);\n  }\n\n  popToSelf(animated: boolean = true) {\n    this.actionCaller.callAction('popToSelf', [\n      {\n        animated,\n      },\n    ]);\n  }\n\n  dismiss(animated: boolean = true) {\n    this.actionCaller.callAction('dismiss', [\n      {\n        animated,\n      },\n    ]);\n  }\n}\n\n/**\n * A ViewControllerComponent is a subclass of Component that exposes\n * methods that are tied to a UIViewController on iOS and ViewController\n * on Android. For those functions to work, the Component must live within\n * a ValdiViewController in native\n * .\n */\nexport class ViewControllerComponent<\n  ViewModelType extends object = any,\n  StateType extends object = object,\n  ContextType extends ComponentContext = any,\n> extends LegacyVueComponent<ViewModelType, StateType, ContextType> {\n  navigation = new Navigation(this);\n\n  setNavigationTitle(navigationTitle: string) {\n    this.callAction('setNavigationTitle', [\n      {\n        title: navigationTitle,\n      },\n    ]);\n  }\n}\n\nexport function performSyncWithMainThread(func: () => void): void {\n  runtime.performSyncWithMainThread(func);\n}\n\ninterface ProxyHandler<T> {\n  get?(target: T, property: string): any;\n  set?(target: T, property: string, value: any): boolean;\n}\n\ndeclare class Proxy<T> {\n  constructor(target: T, handler: ProxyHandler<T>);\n}\n\nlet lastRootComponentsManager: RootComponentsManager | undefined;\n\nexport function getLastRootComponentsManager(): RootComponentsManager | undefined {\n  return lastRootComponentsManager;\n}\n\nexport function makeRootComponentsManager(): IRootComponentsManager {\n  lastRootComponentsManager = new RootComponentsManager(\n    jsx,\n    runtime.isDebugEnabled ? jsx.daemonClientManager : undefined,\n    runtime.submitDebugMessage,\n  );\n  return lastRootComponentsManager;\n}\n\nexport function onDaemonClientEvent(eventType: number, daemonClient: any, payload?: any): void {\n  jsx.onDaemonClientEvent(eventType, daemonClient, payload);\n}\n\nexport function getDaemonClientManager(): DaemonClientManager {\n  return jsx.daemonClientManager;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/ValdiRuntime.d.ts",
    "content": "import { RuntimeBase } from 'coreutils/src/RuntimeBase';\nimport { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { NativeNode } from 'valdi_tsx/src/NativeNode';\nimport { NativeView } from 'valdi_tsx/src/NativeView';\nimport { Asset, PlatformAssetOverrides } from './Asset';\nimport { ElementId } from './IRenderedElement';\nimport { IRootComponentsManager } from './IRootComponentsManager';\nimport { RenderRequest } from './RenderRequest';\nimport { SubmitDebugMessageFunc } from './debugging/DebugMessage';\nimport { AnyFunction } from './utils/Callback';\nimport { PropertyList } from './utils/PropertyList';\n\nexport type CSSRuleNative = number;\nexport interface CSSModuleNative {\n  getRule(name: string): CSSRuleNative | undefined;\n}\n\nexport interface NativeViewNodeInfo {\n  id: string;\n  view: NativeView;\n  attributes: any;\n  includedInLayout: boolean;\n  frame: ElementFrame;\n  children: NativeViewNodeInfo[];\n}\n\nexport interface ColorPalette {\n  [key: string]: string;\n}\n\ninterface MessageEvent<T = unknown> {\n  readonly data: T;\n}\n\nexport type OnMessageFunc<T> = (msg: MessageEvent<T>) => void;\n\nexport interface NativeWorker {\n  postMessage<T>(data: T): void;\n  setOnMessage<T>(f: OnMessageFunc<T>): void;\n  terminate(): void;\n}\n\nexport interface RuntimeMemoryStatistics {\n  memoryUsageBytes: number;\n  objectsCount: number;\n}\n\nexport const enum ExceptionHandlerResult {\n  NOTIFY = 0,\n  IGNORE = 1,\n  CRASH = 2,\n}\n\nexport const enum BackendRenderingType {\n  IOS = 1,\n  ANDROID = 2,\n  SNAP_DRAWING = 3,\n}\n\nexport type AssetEntry = Asset | string;\n\nexport interface LoadedAsset {\n  brand?: 'LoadedAsset';\n}\n\nexport interface LoadedAssetImageMetadata {\n  type: 'image';\n  width: number;\n  height: number;\n}\n\nexport interface LoadedAssetLottieMetadata {\n  type: 'lottie';\n  width: number;\n  height: number;\n  durationMs: number;\n}\n\nexport interface LoadedAssetSkCodecMetadata {\n  type: 'skcodec';\n  width: number;\n  height: number;\n  numberOfFrames: number;\n  durationMs: number;\n}\n\nexport type LoadedAssetMetadata = LoadedAssetImageMetadata | LoadedAssetLottieMetadata | LoadedAssetSkCodecMetadata;\n\nexport interface ValdiRuntime extends RuntimeBase {\n  postMessage(contextId: string, command: string, params: any): void;\n  getFrameForElementId(\n    contextId: string,\n    elementId: ElementId,\n    callback: (frame: ElementFrame | undefined) => void,\n  ): void;\n  getNativeViewForElementId(\n    contextId: string,\n    elementId: ElementId,\n    callback: (view: NativeView | undefined) => void,\n  ): void;\n  getNativeNodeForElementId(contextId: string, elementId: ElementId): NativeNode | undefined;\n  makeOpaque(object: any): any;\n  configureCallback<F extends AnyFunction>(options: number, func: F): void;\n  getViewNodeDebugInfo(\n    contextId: string,\n    elementId: ElementId,\n    callback: (viewNode: NativeViewNodeInfo | undefined) => void,\n  ): void;\n  takeElementSnapshot(contextId: string, elementId: ElementId, callback: (snapshot: string | undefined) => void): void;\n  getLayoutDebugInfo(contextId: string, elementId: ElementId, callback: (layoutInfo: string | undefined) => void): void;\n  performSyncWithMainThread(func: () => void): void;\n  createWorker(url: string): NativeWorker;\n\n  // Rendering\n  submitRawRenderRequest(renderRequest: RenderRequest, callback: () => void): void;\n\n  createContext(manager?: IRootComponentsManager): string;\n  destroyContext(contextId: string): void;\n  setLayoutSpecs(contextId: string, width: number, height: number, rtl: boolean): void;\n  measureContext(\n    contextId: string,\n    maxWidth: number,\n    widthMode: number,\n    maxHeight: number,\n    heightMode: number,\n    rtl: boolean,\n  ): [number, number];\n\n  getCSSModule(path: string): CSSModuleNative;\n  createCSSRule(attributes: PropertyList): CSSRuleNative;\n\n  getCurrentPlatform(): number;\n  internString(str: string): number;\n  getAttributeId(attributeName: string): number;\n\n  protectNativeRefs(contextId: string | number): () => void;\n\n  getBackendRenderingTypeForContextId(contextId: string | number): BackendRenderingType;\n\n  isModuleLoaded(module: string): boolean;\n  /**\n   * Load a Valdi Module with the given module name.\n   * If the completion is null, the operation will be considered\n   * a preload operation and it might be ignored based on the\n   * configuration of the runtime.\n   */\n  loadModule(module: string, completion?: (error?: string) => void): void;\n  getModuleEntry(module: string, path: string, asString: boolean): Uint8Array | string;\n  getModuleJsPaths(module: string): string[];\n\n  trace(tag: string, callback: () => any): any;\n  makeTraceProxy(tag: string, callback: () => void): () => void;\n\n  startTraceRecording(): number;\n  stopTraceRecording(id: number): any[];\n\n  submitDebugMessage: SubmitDebugMessageFunc;\n\n  callOnMainThread(method: any, parameters: any[]): void;\n  onMainThreadIdle(cb: () => void): void;\n\n  makeAssetFromUrl(url: string): Asset;\n  makeAssetFromBytes(bytes: ArrayBuffer | Uint8Array): Asset;\n  makeDirectionalAsset(ltrAsset: string | Asset, rtlAsset: string | Asset): Asset;\n  makePlatformSpecificAsset(defaultAsset: string | Asset, platformAssetOverrides: PlatformAssetOverrides): Asset;\n  getAssets(catalogPath: string): AssetEntry[];\n  addAssetLoadObserver(\n    asset: string | Asset,\n    onLoad: (loadedAsset: LoadedAsset | Uint8Array | undefined, error: string | undefined) => void,\n    outputType: number,\n    preferredWidth: number | undefined,\n    preferredHeight: number | undefined,\n  ): () => void;\n  getLoadedAssetMetadata(loadedAsset: LoadedAsset): LoadedAssetMetadata | undefined;\n\n  setColorPalette(colorPalette: ColorPalette): void;\n\n  outputLog(type: number, content: string): void;\n\n  scheduleWorkItem(cb: () => void, delayMs?: number, interruptible?: boolean): number;\n  unscheduleWorkItem(taskId: number): void;\n\n  pushCurrentContext(contextId: string | undefined): void;\n  popCurrentContext(): void;\n  getCurrentContext(): string;\n\n  saveCurrentContext(): number;\n  restoreCurrentContext(contextId: number): void;\n\n  onUncaughtError(message: string, error: Error): void;\n  /**\n   * Registers an uncaught exception handler that will be called by the runtime\n   * when an uncaught exception is detected\n   */\n  setUncaughtExceptionHandler(cb: ((error: unknown, contextId: string) => ExceptionHandlerResult) | undefined): void;\n  /**\n   * Registers an unhandled rejection handler that will be called by the runtime\n   * when an unhandled rejected promise is detected\n   */\n  setUnhandledRejectionHandler(\n    cb: ((promiseResult: unknown, contextId: string) => ExceptionHandlerResult) | undefined,\n  ): void;\n\n  dumpMemoryStatistics(): RuntimeMemoryStatistics;\n\n  performGC(): void;\n\n  dumpHeap?(): ArrayBuffer;\n\n  isDebugEnabled: boolean;\n\n  /**\n   * Whether JS logging (console.log/warn/error/info/debug) is enabled.\n   * In non-appstore builds this is always true.\n   * In appstore builds this is controlled by the VALDI_DISABLE_JS_LOGGING COF key.\n   */\n  isLoggingEnabled: boolean;\n\n  /**\n   * When true, the renderer emits moves in top-down order (parent before children) to reduce ANR risk.\n   * Gated by VALDI_MAX_VIEW_OPERATIONS_PROCESSING_TIME (same COF as view-op throttling); true when that value > 0.\n   */\n  useTopDownMoveOrder: boolean;\n\n  buildType: string;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/WithLazyPromise.tsx",
    "content": "import { StatefulComponent } from 'valdi_core/src/Component';\nimport { toError } from 'valdi_core/src/utils/ErrorUtils';\nimport { ILazyPromise } from 'valdi_core/src/utils/LazyPromise';\nimport { ComponentConstructor, IComponent } from './IComponent';\n\n/**\n * Returns a new component constructor that will render the given component constructor\n * provided as a LazyPromise.\n */\nexport function withLazyPromise<T extends IComponent>(\n  lazyPromise: ILazyPromise<ComponentConstructor<T>>,\n): ComponentConstructor<IComponent<T['viewModel'], T['context']>, T['viewModel'], T['context']> {\n  interface State {\n    ctor?: ComponentConstructor<T>;\n  }\n\n  return class LazyPromiseComponent extends StatefulComponent<T['viewModel'], State, T['context']> {\n    state: State = {};\n\n    onCreate(): void {\n      if (lazyPromise.value === undefined) {\n        lazyPromise.promise\n          .then(value => {\n            this.onPromiseResolved(value);\n          })\n          .catch(error => {\n            this.onPromiseFailed(error);\n          });\n      } else {\n        this.setState({\n          ctor: lazyPromise.value,\n        });\n      }\n    }\n\n    onRender(): void {\n      const Ctor = this.state.ctor;\n      if (Ctor) {\n        <Ctor {...this.viewModel} children={(this.viewModel as any).children} />;\n      }\n    }\n\n    private onPromiseResolved(ctor: ComponentConstructor<T>): void {\n      if (this.isDestroyed()) {\n        return;\n      }\n\n      this.setState({ ctor });\n    }\n\n    private onPromiseFailed(error: unknown): void {\n      if (this.isDestroyed()) {\n        return;\n      }\n\n      this.renderer.onUncaughtError('LazyPromise failed to resolve', toError(error), this);\n    }\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/CustomMessageHandler.d.ts",
    "content": "export interface CustomMessageHandler {\n  /**\n   * Called whenever a custom message was received.\n   * The function should be return a promise with the response if\n   * the handler wants to handle this message, otherwise it can return\n   * undefined to let another handler handle the message.\n   */\n  messageReceived(identifier: string, body: any): Promise<any> | undefined;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/DaemonClientManager.ts",
    "content": "import { DaemonClientRequest, DaemonServerResponse } from './DaemonClientRequests';\nimport { DaemonClientMessage, DaemonClientMessageType, isAnyResponse, Messages } from './Messages';\n\nexport const enum DaemonClientEventType {\n  CONNECTED = 1,\n  DISCONNECTED = 2,\n  RECEIVED_CLIENT_PAYLOAD = 3,\n}\n\nexport const enum DaemonConnectedClientPlatformType {\n  IOS = 0,\n  ANDROID = 1,\n}\n\nexport interface DaemonConnectedClient {\n  client_id: number;\n  platform: DaemonConnectedClientPlatformType;\n  application_id?: string;\n}\n\nexport interface IDaemonClient {\n  connectionId: number;\n\n  submitRequest(payload: DaemonClientRequest, callback: (result?: DaemonServerResponse) => void): void;\n}\n\nexport class ReceivedDaemonClientMessage {\n  constructor(readonly message: DaemonClientMessage, readonly client: IDaemonClient) {}\n\n  respond(makeMessage: (requestId: string) => string) {\n    this.client.submitRequest(\n      {\n        forward_client_payload: {\n          client_id: this.message.senderClientId,\n          payload_string: makeMessage(this.message.requestId),\n        },\n      },\n      () => {},\n    );\n  }\n}\n\nexport interface IDaemonClientManagerListener {\n  onAvailabilityChanged?(available: boolean): void;\n\n  onClientConnected?(client: IDaemonClient): void;\n  onClientDisconnected?(client: IDaemonClient): void;\n  onMessage?(message: ReceivedDaemonClientMessage): void;\n}\n\nconst MESSAGE_TIMEOUT = 10000;\n\nclass PendingMessage {\n  timeout?: number;\n\n  constructor(\n    readonly client: IDaemonClient,\n    readonly requestId: string,\n    private resolve?: (message: DaemonClientMessage) => void,\n    private reject?: (error: any) => void,\n  ) {}\n\n  doResolve(message: DaemonClientMessage) {\n    const resolve = this.resolve;\n    if (resolve) {\n      this.resolve = undefined;\n      this.reject = undefined;\n      clearTimeout(this.timeout);\n\n      resolve(message);\n    }\n  }\n\n  doReject(error: any) {\n    const reject = this.reject;\n    if (reject) {\n      this.resolve = undefined;\n      this.reject = undefined;\n      clearTimeout(this.timeout);\n\n      reject(error);\n    }\n  }\n}\n\nexport class DaemonClientManager {\n  readonly daemonClients: IDaemonClient[] = [];\n  private listeners: IDaemonClientManagerListener[] = [];\n  private idSequence = 0;\n  private pendingMessages: PendingMessage[] = [];\n\n  addListener(listener: IDaemonClientManagerListener) {\n    this.listeners.push(listener);\n\n    if (this.daemonClients.length) {\n      if (listener.onAvailabilityChanged) {\n        listener.onAvailabilityChanged(true);\n      }\n\n      if (listener.onClientConnected) {\n        for (const daemonClient of this.daemonClients) {\n          listener.onClientConnected(daemonClient);\n        }\n      }\n    }\n  }\n\n  removeListener(listener: IDaemonClientManagerListener) {\n    const index = this.listeners.indexOf(listener);\n    if (index >= 0) {\n      this.listeners.splice(index, 1);\n    }\n  }\n\n  private fulfillMessage(requestId: string, onMessage: (message: PendingMessage) => void) {\n    for (let i = 0; i < this.pendingMessages.length; i++) {\n      const message = this.pendingMessages[i];\n      if (message.requestId === requestId) {\n        this.pendingMessages.splice(i, 1);\n        onMessage(message);\n      }\n    }\n  }\n\n  submitRequest(daemonClient: IDaemonClient, request: DaemonClientRequest): Promise<DaemonServerResponse> {\n    return new Promise((resolve, reject) => {\n      daemonClient.submitRequest(request, data => {\n        if (data?.error) {\n          reject(data.error.error_message);\n        } else if (!data) {\n          reject(new Error('No data returned'));\n        } else {\n          try {\n            resolve(data);\n          } catch (err: any) {\n            reject(err);\n          }\n        }\n      });\n    });\n  }\n\n  submitMessage(\n    daemonClient: IDaemonClient,\n    clientId: number,\n    makeMessage: (requestId: string) => string,\n  ): Promise<DaemonClientMessage> {\n    return new Promise((resolve, reject) => {\n      this.idSequence++;\n      const requestId = this.idSequence.toString();\n\n      const pendingMessage = new PendingMessage(daemonClient, requestId, resolve, reject);\n      this.pendingMessages.push(pendingMessage);\n\n      pendingMessage.timeout = setTimeout(() => {\n        this.fulfillMessage(requestId, message => message.doReject('Request timed out'));\n      }, MESSAGE_TIMEOUT);\n\n      this.submitRequest(daemonClient, {\n        forward_client_payload: { client_id: clientId, payload_string: makeMessage(requestId) },\n      }).catch(error => {\n        this.fulfillMessage(requestId, message => message.doReject(error));\n      });\n    });\n  }\n\n  onEvent(eventType: DaemonClientEventType, daemonClient: IDaemonClient, payload?: any) {\n    switch (eventType) {\n      case DaemonClientEventType.CONNECTED:\n        if (this.daemonClients.indexOf(daemonClient) >= 0) {\n          return;\n        }\n\n        this.daemonClients.push(daemonClient);\n\n        for (const listener of this.listeners) {\n          if (this.daemonClients.length === 1) {\n            if (listener.onAvailabilityChanged) {\n              listener.onAvailabilityChanged(true);\n            }\n          }\n\n          if (listener.onClientConnected) {\n            listener.onClientConnected(daemonClient);\n          }\n        }\n\n        break;\n      case DaemonClientEventType.DISCONNECTED: {\n        const index = this.daemonClients.indexOf(daemonClient);\n        if (index >= 0) {\n          this.daemonClients.splice(index, 1);\n\n          for (const listener of this.listeners) {\n            if (!this.daemonClients.length) {\n              if (listener.onAvailabilityChanged) {\n                listener.onAvailabilityChanged(false);\n              }\n            }\n\n            if (listener.onClientDisconnected) {\n              listener.onClientDisconnected(daemonClient);\n            }\n          }\n        }\n        break;\n      }\n      case DaemonClientEventType.RECEIVED_CLIENT_PAYLOAD: {\n        const message = Messages.parse(payload['senderClientId'], payload['payload']);\n\n        if (message.type === DaemonClientMessageType.ERROR_RESPONSE) {\n          this.fulfillMessage(message.requestId, pendingMessage => {\n            pendingMessage.doReject(message.body);\n          });\n          return;\n        }\n\n        if (isAnyResponse(message)) {\n          this.fulfillMessage(message.requestId, pendingMessage => {\n            pendingMessage.doResolve(message);\n          });\n          return;\n        }\n\n        const receivedMessage = new ReceivedDaemonClientMessage(message, daemonClient);\n\n        for (const listener of this.listeners) {\n          if (listener.onMessage) {\n            listener.onMessage(receivedMessage);\n          }\n        }\n        break;\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/DaemonClientManagerResolver.ts",
    "content": "import { jsx } from '../JSXBootstrap';\nimport { DaemonClientManager } from './DaemonClientManager';\n\nexport function getDaemonClientManager(): DaemonClientManager {\n  return jsx.daemonClientManager;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/DaemonClientRequests.d.ts",
    "content": "import { DaemonConnectedClient } from './DaemonClientManager';\n\nexport const enum DaemonClientRequestType {\n  WRITE_FILE = 'write_file',\n  READ_FILE = 'read_file',\n  READ_DIRECTORY = 'read_directory',\n  DELETE_FILE = 'delete_file',\n}\n\ninterface DaemonClientRequestBase<Type extends DaemonClientRequestType, BodyType> {\n  type: Type;\n  body: BodyType;\n}\n\nexport const enum DaemonClientReadDirectoryEntryType {\n  UNKNOWN = 0,\n  FILE = 1,\n  DIRECTORY = 2,\n}\n\nexport interface DaemonClientReadDirectoryEntry {\n  type: DaemonClientReadDirectoryEntryType;\n  filename: string;\n  absolute_path: string;\n}\n\nexport interface DaemonClientFileBody {\n  path: string;\n}\n\nexport interface DaemonClientWriteFileBody extends DaemonClientFileBody {\n  data_base64?: string;\n  data_string?: string;\n}\n\nexport interface DaemonClientReadFileBody extends DaemonClientFileBody {\n  output_format: 'base64' | 'string';\n}\n\nexport interface DaemonClientWriteFileRequest\n  extends DaemonClientRequestBase<DaemonClientRequestType.WRITE_FILE, DaemonClientWriteFileBody> {}\nexport interface DaemonClientWriteFileResponse {}\n\nexport interface DaemonClientReadFileRequest\n  extends DaemonClientRequestBase<DaemonClientRequestType.READ_FILE, DaemonClientReadFileBody> {}\nexport interface DaemonClientReadFileResponse {\n  data_base64?: string;\n  data_string?: string;\n}\n\nexport interface DaemonClientReadDirectoryRequest\n  extends DaemonClientRequestBase<DaemonClientRequestType.READ_DIRECTORY, DaemonClientFileBody> {}\nexport interface DaemonClientReadDirectoryResponse {\n  entries: DaemonClientReadDirectoryEntry[];\n}\n\nexport interface DaemonClientDeleteFileRequest\n  extends DaemonClientRequestBase<DaemonClientRequestType.DELETE_FILE, DaemonClientFileBody> {}\nexport interface DaemonClientDeleteFileResponse {}\n\nexport type DaemonClientFileRequest =\n  | DaemonClientWriteFileRequest\n  | DaemonClientReadFileRequest\n  | DaemonClientReadDirectoryRequest\n  | DaemonClientDeleteFileRequest;\n\nexport type DaemonClientFileResponse =\n  | DaemonClientWriteFileResponse\n  | DaemonClientReadFileResponse\n  | DaemonClientReadDirectoryResponse\n  | DaemonClientDeleteFileResponse;\n\nexport interface DaemonClientConfigureRequest {\n  application_id: string;\n  platform: string;\n}\n\nexport interface DaemonListConnectedClientsRequest {}\n\nexport interface DaemonForwardClientPayloadRequest {\n  client_id: number;\n  payload_string: string;\n}\n\nexport interface DaemonClientRequest {\n  configure?: DaemonClientConfigureRequest;\n  list_connected_clients?: DaemonListConnectedClientsRequest;\n  forward_client_payload?: DaemonForwardClientPayloadRequest;\n  file_manager?: DaemonClientFileRequest;\n}\n\nexport interface DaemonClientConfigureResponse {}\n\nexport interface DaemonClientListConnectedClientsResponse {\n  clients: DaemonConnectedClient[];\n}\n\nexport interface DaemonClientForwardPayloadResponse {}\n\nexport interface DaemonServerError {\n  error_message: string;\n}\n\nexport interface DaemonServerResponse {\n  configure?: DaemonClientConfigureResponse;\n  list_connected_clients?: DaemonClientListConnectedClientsResponse;\n  forward_client_payload?: DaemonClientForwardPayloadResponse;\n  file_manager?: DaemonClientFileResponse;\n  error?: DaemonServerError;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/DebugConsole.tsx",
    "content": "import { Device } from 'valdi_core/src/Device';\nimport { setTimeoutInterruptible } from 'valdi_core/src/SetTimeout';\nimport { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { Label, Layout, View } from 'valdi_tsx/src/NativeTemplateElements';\nimport { StatefulComponent } from '../Component';\nimport { IRuntimeIssueObserver } from '../IRuntimeIssueObserver';\nimport { Style } from '../Style';\nimport { when } from '../utils/When';\nimport { DaemonClientManager, IDaemonClientManagerListener } from './DaemonClientManager';\nimport { DebugButton } from './DebugConsoleButton';\nimport { RuntimeIssue, RuntimeIssueDisplayer } from './RuntimeIssueDisplayer';\n\nenum CollapseState {\n  expanded,\n  collapsed,\n  expanding,\n  collapsing,\n}\n\ninterface State {\n  reloaderAvailable: boolean; // we don't show the debug console if the reloader is not available\n  collapseState: CollapseState;\n  issues: RuntimeIssue[];\n  issueIndex: number;\n  topPadding: number;\n  bottomPadding: number;\n  rootHeight: number;\n}\n\nconst viewNodePrefix = '[ViewNode:';\n\nfunction parseRuntimeIssue(isError: boolean, message: string): RuntimeIssue {\n  let resolvedMessage = message;\n  let nodeId: number | undefined;\n\n  if (message.startsWith(viewNodePrefix)) {\n    const endIndex = message.indexOf(']');\n    if (endIndex <= 0) {\n      throw new Error('Failed to resolve closing bracket');\n    }\n    nodeId = Number.parseInt(message.substr(viewNodePrefix.length, message.length - endIndex));\n\n    resolvedMessage = message.substr(endIndex + 2);\n  }\n\n  return {\n    isError,\n    message: resolvedMessage,\n    nodeId,\n  };\n}\n\nconst headerHeight = 80;\n\nconst headerStyle = new Style<View>({\n  backgroundColor: '#FFF300',\n  width: '100%',\n  boxShadow: '0 0 3 rgba(0, 0, 0, 0.15)',\n});\n\nconst headerContainerStyle = new Style<Layout>({\n  flexDirection: 'column',\n  padding: 8,\n  paddingBottom: 30,\n  // height: headerHeight,\n});\n\nconst topHeaderTopStyle = new Style<Layout>({\n  flexDirection: 'row',\n  justifyContent: 'space-between',\n  flexGrow: 1,\n});\n\nconst headerBottomStyle = new Style<Layout>({\n  flexDirection: 'row',\n  width: '100%',\n  justifyContent: 'center',\n});\n\nconst rootStyle = new Style<Layout>({\n  width: '100%',\n  height: '100%',\n  position: 'absolute',\n  flexDirection: 'column-reverse',\n});\n\nconst issueTextSelectorStyle = new Style<Label>({\n  font: 'AvenirNext-Medium 13',\n  margin: 8,\n});\n\ninterface ViewModel {\n  daemonClientManager: DaemonClientManager;\n}\n\nexport class DebugConsole\n  extends StatefulComponent<ViewModel, State>\n  implements IDaemonClientManagerListener, IRuntimeIssueObserver\n{\n  state: State = {\n    reloaderAvailable: false,\n    collapseState: CollapseState.collapsed,\n    issues: [],\n    issueIndex: 0,\n    bottomPadding: 0,\n    topPadding: 0,\n    rootHeight: 0,\n  };\n  private pendingNewIssues?: RuntimeIssue[];\n\n  private displayHeight = Device.getDisplayHeight();\n\n  onAvailabilityChanged(available: boolean) {\n    this.setState({\n      reloaderAvailable: available,\n    });\n  }\n\n  onCreate() {\n    const observer = Device.observeDisplayInsetChange(() => this.updateDisplayMargins());\n    this.registerDisposable(observer.cancel);\n    this.updateDisplayMargins();\n\n    this.viewModel.daemonClientManager.addListener(this);\n    this.renderer.addObserver(this);\n  }\n\n  onDestroy() {\n    this.viewModel.daemonClientManager.removeListener(this);\n    this.renderer.removeObserver(this);\n  }\n\n  onRender() {\n    if (!this.state.reloaderAvailable) {\n      return;\n    }\n\n    if (!this.state.issues.length) {\n      return;\n    }\n\n    // Only render the debug component if it fits at least one third of the screen.\n    const shouldRender = this.state.rootHeight > this.displayHeight / 3.0;\n\n    const isExpanded = this.state.collapseState === CollapseState.expanded;\n\n    <layout style={rootStyle} onLayout={this.onRootLayout}>\n      <layout display={!shouldRender ? 'none' : undefined} flexGrow={isExpanded ? 1 : undefined} flexShrink={1}>\n        <view\n          style={headerStyle}\n          paddingBottom={!isExpanded ? this.state.bottomPadding : undefined}\n          paddingTop={isExpanded ? this.state.topPadding : undefined}\n        >\n          <layout style={headerContainerStyle}>\n            <layout style={topHeaderTopStyle}>\n              <DebugButton text='Dismiss' onTap={this.close} />\n              <label value={`${this.state.issues.length} Valdi Warnings`} font='AvenirNext-Demibold 13' />\n              <DebugButton\n                text={this.state.collapseState === CollapseState.expanded ? 'Collapse' : 'Expand'}\n                onTap={this.expandOrCollapse}\n              />\n            </layout>\n            {this.renderHeaderBottom()}\n          </layout>\n        </view>\n\n        {when(this.state.collapseState !== CollapseState.collapsed, () => this.renderBody())}\n      </layout>\n    </layout>;\n  }\n\n  private renderHeaderBottom() {\n    <view\n      style={headerBottomStyle}\n      height={this.state.collapseState !== CollapseState.expanded ? 0 : undefined}\n      opacity={this.state.collapseState === CollapseState.expanded ? 1.0 : 0}\n    >\n      <DebugButton onTap={this.goToPreviousIssue} text='<' />\n      <label\n        style={issueTextSelectorStyle}\n        value={`Issue ${this.state.issueIndex + 1} / ${this.state.issues.length}`}\n      />\n      <DebugButton onTap={this.goToNextIssue} text='>' />\n    </view>;\n  }\n\n  private updateDisplayMargins() {\n    const topInset = Device.getDisplayTopInset();\n    const bottomInset = Device.getDisplayBottomInset();\n\n    this.setState({ bottomPadding: bottomInset, topPadding: topInset });\n  }\n\n  private goToPreviousIssue = () => {\n    this.goToIssue(-1);\n  };\n\n  private goToNextIssue = () => {\n    this.goToIssue(1);\n  };\n\n  private onRootLayout = (rootFrame: ElementFrame) => {\n    this.setState({ rootHeight: rootFrame.height });\n  };\n\n  private goToIssue(increment: number) {\n    const issuesLength = this.state.issues.length;\n    if (!issuesLength) {\n      return;\n    }\n    let nextIssue = this.state.issueIndex + increment;\n    if (nextIssue < 0) {\n      nextIssue = issuesLength - 1;\n    } else if (nextIssue >= issuesLength) {\n      nextIssue = 0;\n    }\n    this.setState({ issueIndex: nextIssue });\n  }\n\n  private renderBody() {\n    const issue = this.state.issues[this.state.issueIndex];\n    if (!issue) {\n      return;\n    }\n\n    const isFullyExpanded = this.state.collapseState === CollapseState.expanded;\n\n    <view\n      backgroundColor='white'\n      width='100%'\n      flexGrow={1}\n      flexShrink={1}\n      padding={!isFullyExpanded ? 0 : 8}\n      height={!isFullyExpanded ? 0 : undefined}\n      marginBottom={isFullyExpanded ? this.state.bottomPadding : undefined}\n    >\n      <RuntimeIssueDisplayer issue={issue} />\n    </view>;\n  }\n\n  private expandOrCollapse = () => {\n    if (this.state.collapseState === CollapseState.collapsed) {\n      this.setState({ collapseState: CollapseState.expanding });\n      this.setStateAnimated({ collapseState: CollapseState.expanded }, { duration: 0.25 });\n    } else if (this.state.collapseState === CollapseState.expanded) {\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.setStateAnimatedPromise({ collapseState: CollapseState.collapsing }, { duration: 0.25 }).then(() => {\n        this.setState({ collapseState: CollapseState.collapsed });\n      });\n    }\n  };\n\n  private close = () => {\n    this.setState({ issues: [], issueIndex: 0 });\n  };\n\n  private flushPendingIssues() {\n    const pendingNewIssues = this.pendingNewIssues;\n    if (!pendingNewIssues) {\n      return;\n    }\n    this.pendingNewIssues = undefined;\n    this.setState({ issues: [...this.state.issues, ...pendingNewIssues] });\n  }\n\n  private appendPendingIssue(issue: RuntimeIssue) {\n    if (this.pendingNewIssues) {\n      this.pendingNewIssues.push(issue);\n      return;\n    }\n\n    this.pendingNewIssues = [issue];\n    setTimeoutInterruptible(() => {\n      this.flushPendingIssues();\n    }, 0);\n  }\n\n  onRuntimeIssue(isError: boolean, message: string) {\n    try {\n      const issue = parseRuntimeIssue(isError, message);\n      this.appendPendingIssue(issue);\n    } catch (err: any) {\n      console.error('Failed to parse runtime issue:', err);\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/DebugConsoleButton.tsx",
    "content": "import { View } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Component } from '../Component';\nimport { Style } from '../Style';\n\nexport interface ButtonViewModel {\n  text: string;\n  onTap: () => void;\n}\n\nconst buttonStyle = new Style<View>({\n  backgroundColor: 'white',\n  padding: 8,\n  borderRadius: 12,\n  justifyContent: 'center',\n  boxShadow: '0 0 3 rgba(0, 0, 0, 0.15)',\n});\n\nexport class DebugButton extends Component<ButtonViewModel> {\n  onRender() {\n    <view onTap={this.viewModel.onTap} style={buttonStyle}>\n      <label value={this.viewModel.text} font='AvenirNext-DemiBold 12' />\n    </view>;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/DebugMessage.d.ts",
    "content": "export const enum DebugLevel {\n  DEBUG = 0,\n  INFO,\n  WARN,\n  ERROR,\n}\n\nexport type SubmitDebugMessageFunc = (level: DebugLevel, message: string) => void;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/DefaultErrorBoundary.tsx",
    "content": "import { StatefulComponent } from '../Component';\nimport { ValdiRuntime } from '../ValdiRuntime';\nimport { withLazyPromise } from '../WithLazyPromise';\nimport { lazyPromise } from '../utils/LazyPromise';\nimport { RendererError } from '../utils/RendererError';\nconst ErrorComponent = withLazyPromise(lazyPromise(() => import('./ErrorComponent')).then(m => m.ErrorComponent));\n\ninterface State {\n  error?: Error;\n}\n\ndeclare const runtime: ValdiRuntime;\n\n/**\n * A component which catches errors and display an error screen\n * when an error is thrown.\n */\nexport class DefaultErrorBoundary extends StatefulComponent<{}, State> {\n  state: State = {};\n\n  onRender() {\n    const error = this.state.error;\n    if (error) {\n      <ErrorComponent error={error} />;\n    } else {\n      <slot />;\n    }\n  }\n\n  onError(error: Error) {\n    if (error instanceof RendererError) {\n      runtime.onUncaughtError(error.message, error.sourceError);\n    } else {\n      runtime.onUncaughtError(error.message, error);\n    }\n\n    if (!this.state.error) {\n      this.setState({\n        error,\n      });\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/ErrorComponent.tsx",
    "content": "import { Component } from '../Component';\nimport { IRenderedVirtualNode } from '../IRenderedVirtualNode';\nimport { getVirtualNodeDataFromRootToChild } from '../IRenderedVirtualNodeData';\nimport { symbolicate } from '../Symbolicator';\nimport { CompilerError } from '../utils/CompilerError';\nimport { RendererError } from '../utils/RendererError';\nimport { when } from '../utils/When';\nimport { colors, fonts, styles } from './Styles';\nimport { VirtualNodePathDisplayer } from './VirtualNodePathDisplayer';\n\ninterface ViewModel {\n  error: Error;\n}\n\ninterface ProcessedError {\n  errorTitle: string;\n  errorMessage: string;\n  hasStacktrace: boolean;\n  consoleMessage?: string;\n  lastRenderedNode?: IRenderedVirtualNode;\n}\n\n/**\n * Component used when there is a compilation error\n */\nexport class ErrorComponent extends Component<ViewModel> {\n  private processedError?: ProcessedError;\n\n  onViewModelUpdate() {\n    const error = this.viewModel.error;\n\n    let errorTitle: string;\n    let errorMessage: string;\n    let hasStacktrace = false;\n    let consoleMessage: string | undefined;\n    let lastRenderedNode: IRenderedVirtualNode | undefined;\n\n    if (error instanceof CompilerError) {\n      errorTitle = 'Valdi Compiler Error';\n      const errorMessageLines = error.message.split('\\n');\n      if (errorMessageLines.length > 1) {\n        errorMessage = errorMessageLines[0];\n        consoleMessage = error.message;\n      } else {\n        errorMessage = error.message;\n      }\n    } else if (error instanceof RendererError) {\n      errorTitle = `Runtime Error: ${error.message}`;\n      errorMessage = error.sourceError.message;\n      lastRenderedNode = error.lastRenderedNode;\n\n      const symbolicatedStack = symbolicate(error.sourceError);\n      if (symbolicatedStack.stack) {\n        consoleMessage = symbolicatedStack.stack;\n        hasStacktrace = true;\n      }\n    } else {\n      errorTitle = `Unknown Error`;\n      errorMessage = error.message;\n\n      const symbolicatedStack = symbolicate(error);\n      if (symbolicatedStack.stack) {\n        consoleMessage = symbolicatedStack.stack;\n        hasStacktrace = true;\n      }\n    }\n\n    this.processedError = { errorMessage, errorTitle, hasStacktrace, consoleMessage, lastRenderedNode };\n  }\n\n  onRender() {\n    const processedError = this.processedError;\n    if (!processedError) {\n      return;\n    }\n\n    <view width='100%' height='100%' backgroundColor='white' alignItems='center' justifyContent='center' padding={20}>\n      <scroll>\n        <label\n          textAlign='center'\n          numberOfLines={0}\n          font={fonts.title}\n          color={colors.errorText}\n          marginBottom={20}\n          value={processedError.errorTitle}\n        />\n        <label\n          textAlign='center'\n          numberOfLines={0}\n          style={styles.infoText}\n          value={`'${processedError.errorMessage}'`}\n        />\n        {when(processedError.lastRenderedNode, lastRenderedNode => {\n          const pair = getVirtualNodeDataFromRootToChild(lastRenderedNode);\n\n          <layout height={20} />;\n          <VirtualNodePathDisplayer node={pair.root} focusedNode={pair.child} />;\n        })}\n        {when(processedError.consoleMessage, consoleMessage => {\n          <layout marginTop={20}>\n            {when(processedError.hasStacktrace, () => {\n              <label style={styles.infoText} value='Stacktrace:' marginBottom={8} />;\n            })}\n            <view style={styles.console}>\n              <label numberOfLines={0} style={styles.consoleText} value={consoleMessage} />\n            </view>\n          </layout>;\n        })}\n      </scroll>\n    </view>;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/ErrorViewModel.d.ts",
    "content": "export interface ErrorViewModel {\n  error: Error;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/Messages.ts",
    "content": "import { IRenderedVirtualNodeData } from '../IRenderedVirtualNodeData';\n\nexport const enum DaemonClientMessageType {\n  ERROR_RESPONSE = -1,\n  LIST_CONTEXTS_REQUEST = 2,\n  LIST_CONTEXTS_RESPONSE = -2,\n  GET_CONTEXT_TREE_REQUEST = 3,\n  GET_CONTEXT_TREE_RESPONSE = -3,\n  TAKE_ELEMENT_SNAPSHOT_REQUEST = 4,\n  TAKE_ELEMENT_SNAPSHOT_RESPONSE = -4,\n  DUMP_HEAP_REQUEST = 5,\n  DUMP_HEAP_RESPONSE = -5,\n  CUSTOM_REQUEST = 1000,\n  CUSTOM_RESPONSE = -1000,\n}\n\ninterface DaemonClientMessageBase<Type extends DaemonClientMessageType, BodyType> {\n  senderClientId: number;\n  requestId: string;\n  type: Type;\n  body: BodyType;\n}\n\nexport interface ErrorBody {\n  message: string;\n  stack: string | undefined;\n}\n\nexport interface RemoteValdiContext {\n  id: string;\n  rootComponentName: string;\n}\n\nexport interface GetContextTreeBody {\n  id: string;\n}\n\nexport interface TakeElementSnapshotBody {\n  contextId: string;\n  elementId: number;\n}\n\nexport interface DumpHeapRequestBody {\n  performGC: boolean;\n}\n\nexport interface DumpHeapResponseBody {\n  memoryUsageBytes: number;\n  heapDumpJSON: string;\n}\n\nexport interface CustomMessageRequestBody {\n  identifier: string;\n  data: any;\n}\n\nexport interface CustomMessageResponseBody {\n  handled: boolean;\n  data: any | undefined;\n}\n\nexport type ErrorResponse = DaemonClientMessageBase<DaemonClientMessageType.ERROR_RESPONSE, ErrorBody>;\nexport type ListContextsRequest = DaemonClientMessageBase<DaemonClientMessageType.LIST_CONTEXTS_REQUEST, {}>;\nexport type ListContextsResponse = DaemonClientMessageBase<\n  DaemonClientMessageType.LIST_CONTEXTS_RESPONSE,\n  RemoteValdiContext[]\n>;\n\nexport type GetContextTreeRequest = DaemonClientMessageBase<\n  DaemonClientMessageType.GET_CONTEXT_TREE_REQUEST,\n  GetContextTreeBody\n>;\nexport type GetContextTreeResponse = DaemonClientMessageBase<\n  DaemonClientMessageType.GET_CONTEXT_TREE_RESPONSE,\n  IRenderedVirtualNodeData\n>;\n\nexport type DumpHeapRequest = DaemonClientMessageBase<DaemonClientMessageType.DUMP_HEAP_REQUEST, DumpHeapRequestBody>;\nexport type DumpHeapResponse = DaemonClientMessageBase<\n  DaemonClientMessageType.DUMP_HEAP_RESPONSE,\n  DumpHeapResponseBody\n>;\n\nexport type TakeElementSnapshotRequest = DaemonClientMessageBase<\n  DaemonClientMessageType.TAKE_ELEMENT_SNAPSHOT_REQUEST,\n  TakeElementSnapshotBody\n>;\nexport type TakeElementSnapshotResponse = DaemonClientMessageBase<\n  DaemonClientMessageType.TAKE_ELEMENT_SNAPSHOT_RESPONSE,\n  string\n>;\n\nexport type CustomMessageRequest = DaemonClientMessageBase<\n  DaemonClientMessageType.CUSTOM_REQUEST,\n  CustomMessageRequestBody\n>;\nexport type CustomMessageResponse = DaemonClientMessageBase<\n  DaemonClientMessageType.CUSTOM_RESPONSE,\n  CustomMessageResponseBody\n>;\n\nexport type DaemonClientMessage =\n  | ListContextsRequest\n  | ListContextsResponse\n  | GetContextTreeRequest\n  | GetContextTreeResponse\n  | TakeElementSnapshotRequest\n  | TakeElementSnapshotResponse\n  | DumpHeapRequest\n  | DumpHeapResponse\n  | CustomMessageRequest\n  | CustomMessageResponse\n  | ErrorResponse;\n\nexport function isAnyResponse(message: DaemonClientMessage): boolean {\n  return message.type < 0;\n}\n\nexport namespace Messages {\n  export function listContextsRequest(requestId: string): string {\n    return JSON.stringify({ type: DaemonClientMessageType.LIST_CONTEXTS_REQUEST, requestId, body: {} });\n  }\n\n  export function listContextsResponse(requestId: string, contexts: RemoteValdiContext[]) {\n    return JSON.stringify({ type: DaemonClientMessageType.LIST_CONTEXTS_RESPONSE, requestId, body: contexts });\n  }\n\n  export function getContextTreeRequest(requestId: string, body: GetContextTreeBody) {\n    return JSON.stringify({\n      type: DaemonClientMessageType.GET_CONTEXT_TREE_REQUEST,\n      requestId,\n      body,\n    });\n  }\n\n  export function getContextTreeResponse(requestId: string, body: IRenderedVirtualNodeData) {\n    return JSON.stringify({\n      type: DaemonClientMessageType.GET_CONTEXT_TREE_RESPONSE,\n      requestId,\n      body,\n    });\n  }\n\n  export function takeElementSnapshotRequest(requestId: string, body: TakeElementSnapshotBody) {\n    return JSON.stringify({\n      type: DaemonClientMessageType.TAKE_ELEMENT_SNAPSHOT_REQUEST,\n      requestId,\n      body,\n    });\n  }\n\n  export function takeElementSnapshotResponse(requestId: string, data: string) {\n    return JSON.stringify({\n      type: DaemonClientMessageType.TAKE_ELEMENT_SNAPSHOT_RESPONSE,\n      requestId,\n      body: data,\n    });\n  }\n\n  export function dumpHeapRequest(requestId: string, body: DumpHeapRequestBody) {\n    return JSON.stringify({\n      type: DaemonClientMessageType.DUMP_HEAP_REQUEST,\n      requestId,\n      body: body,\n    });\n  }\n\n  export function dumpHeapResponse(requestId: string, body: DumpHeapResponseBody) {\n    return JSON.stringify({\n      type: DaemonClientMessageType.DUMP_HEAP_RESPONSE,\n      requestId,\n      body: body,\n    });\n  }\n\n  export function customMessageRequest(requestId: string, body: CustomMessageRequestBody) {\n    return JSON.stringify({\n      type: DaemonClientMessageType.CUSTOM_REQUEST,\n      requestId,\n      body,\n    });\n  }\n\n  export function customMessageResponse(requestId: string, body: CustomMessageResponseBody) {\n    return JSON.stringify({\n      type: DaemonClientMessageType.CUSTOM_RESPONSE,\n      requestId,\n      body,\n    });\n  }\n\n  export function errorResponse(requestId: string, error: string | Error) {\n    let message: string;\n    let stack: string | undefined;\n    if (typeof error === 'string') {\n      message = error;\n    } else {\n      message = `${error.name}: ${error.message}`;\n      stack = error.stack;\n    }\n\n    const body: ErrorBody = {\n      message,\n      stack,\n    };\n\n    return JSON.stringify({ type: DaemonClientMessageType.ERROR_RESPONSE, requestId, body });\n  }\n\n  export function parse(senderClientId: number, jsonBlob: any): DaemonClientMessage {\n    if (typeof jsonBlob === 'string' && senderClientId) {\n      const message = JSON.parse(jsonBlob);\n      if (message.type && message.body !== undefined && message.requestId) {\n        return {\n          senderClientId: senderClientId,\n          requestId: message.requestId,\n          body: message.body,\n          type: message.type,\n        };\n      }\n    }\n\n    throw new Error(`Failed to parse message (${typeof senderClientId}, ${typeof jsonBlob})`);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/RendererEventRecorder.ts",
    "content": "import { ComponentCtor, IRendererEventListener } from '../IRendererEventListener';\n\nconst enum RendererTraceEntryType {\n  renderBegin = 1,\n  renderEnd,\n  componentBegin,\n  componentEnd,\n  bypassComponentRender,\n  componentViewModelPropertyChange,\n}\n\nexport class RendererEventsToString implements IRendererEventListener {\n  // private buffer = '';\n  private depth = 0;\n  private minDepth = 0;\n  private entries: (number | string)[] = [];\n  private componentNamesStack: string[] = [];\n\n  toString(): string {\n    const depthOffset = Math.abs(this.minDepth);\n    const entries = this.entries;\n    const length = entries.length;\n    let buffer = '';\n    let i = 0;\n    while (i < length) {\n      const depth = (entries[i++] as number) + depthOffset;\n      const content = entries[i++] as string;\n\n      for (let i = 0; i < depth; i++) {\n        buffer += '  ';\n      }\n\n      buffer += content;\n\n      buffer += '\\n';\n    }\n\n    return buffer;\n  }\n\n  private appendLine(content: string) {\n    this.entries.push(this.depth, content);\n  }\n\n  onRenderBegin(): void {\n    this.appendLine('Begin render');\n    this.depth++;\n  }\n\n  onRenderEnd(): void {\n    this.decrementDepth();\n    this.appendLine('End render');\n  }\n\n  onComponentBegin(key: string, componentCtor: ComponentCtor): void {\n    const componentName = componentCtor.name;\n    this.appendLine(`Begin ${componentName} (key: ${key})`);\n    this.componentNamesStack.push(componentName);\n    this.depth++;\n  }\n\n  onComponentEnd(): void {\n    const componentName = this.componentNamesStack.pop();\n    this.decrementDepth();\n    this.appendLine(`End ${componentName ?? '<unknown>'}`);\n  }\n\n  private decrementDepth(): void {\n    this.minDepth = Math.min(this.minDepth, --this.depth);\n  }\n\n  onBypassComponentRender(): void {\n    this.appendLine('Bypass render');\n  }\n\n  onComponentViewModelPropertyChange(viewModelPropertyName: string): void {\n    this.appendLine(`ViewModel property '${viewModelPropertyName}' changed`);\n  }\n}\n\nexport class RendererEventRecorder implements IRendererEventListener {\n  private buffer: unknown[] = [];\n  private maxBufferSize = 0;\n\n  clear() {\n    this.buffer = [];\n  }\n\n  /**\n   * Set a maximum underlying buffer size. The buffer will be automatically\n   * shrinked after render ends so that it fits within the given bounds.\n   */\n  setMaxBufferSize(maxBufferSize: number): void {\n    if (maxBufferSize !== this.maxBufferSize) {\n      this.maxBufferSize = maxBufferSize;\n      this.shrinkToMaxBufferSizeIfNeeded();\n    }\n  }\n\n  toString(): string {\n    const toStringVisitor = new RendererEventsToString();\n    this.visit(toStringVisitor);\n    return toStringVisitor.toString();\n  }\n\n  visit(visitor: IRendererEventListener): void {\n    const buffer = this.buffer;\n    const length = buffer.length;\n    let i = 0;\n    while (i < length) {\n      const type = buffer[i++] as RendererTraceEntryType;\n      switch (type) {\n        case RendererTraceEntryType.renderBegin:\n          visitor.onRenderBegin();\n          break;\n        case RendererTraceEntryType.renderEnd:\n          visitor.onRenderEnd();\n          break;\n        case RendererTraceEntryType.componentBegin:\n          {\n            const key = buffer[i++] as string;\n            const componentCtor = buffer[i++] as ComponentCtor;\n            visitor.onComponentBegin(key, componentCtor);\n          }\n          break;\n        case RendererTraceEntryType.componentEnd:\n          visitor.onComponentEnd();\n          break;\n        case RendererTraceEntryType.bypassComponentRender:\n          visitor.onBypassComponentRender();\n          break;\n        case RendererTraceEntryType.componentViewModelPropertyChange:\n          {\n            const viewModelPropertyName = buffer[i++] as string;\n            visitor.onComponentViewModelPropertyChange(viewModelPropertyName);\n          }\n          break;\n        default:\n          throw new Error(`Invalid type: ${type}`);\n      }\n    }\n  }\n\n  private shrinkToMaxBufferSizeIfNeeded(): void {\n    const buffer = this.buffer;\n    const length = buffer.length;\n    const maxBufferSize = this.maxBufferSize;\n    if (maxBufferSize) {\n      let i = 0;\n      while (length - i > maxBufferSize) {\n        const type = buffer[i++] as RendererTraceEntryType;\n        switch (type) {\n          case RendererTraceEntryType.renderBegin:\n            break;\n          case RendererTraceEntryType.renderEnd:\n            break;\n          case RendererTraceEntryType.componentBegin:\n            i += 2;\n            break;\n          case RendererTraceEntryType.componentEnd:\n            break;\n          case RendererTraceEntryType.bypassComponentRender:\n            break;\n          case RendererTraceEntryType.componentViewModelPropertyChange:\n            i++;\n            break;\n          default:\n            throw new Error(`Invalid type: ${type}`);\n        }\n      }\n\n      if (i > 0) {\n        buffer.splice(0, i);\n      }\n    }\n  }\n\n  onRenderBegin(): void {\n    this.buffer.push(RendererTraceEntryType.renderBegin);\n  }\n\n  onRenderEnd(): void {\n    this.buffer.push(RendererTraceEntryType.renderEnd);\n    this.shrinkToMaxBufferSizeIfNeeded();\n  }\n\n  onComponentBegin(key: string, componentCtor: ComponentCtor): void {\n    this.buffer.push(RendererTraceEntryType.componentBegin, key, componentCtor);\n  }\n\n  onComponentEnd(): void {\n    this.buffer.push(RendererTraceEntryType.componentEnd);\n  }\n\n  onBypassComponentRender(): void {\n    this.buffer.push(RendererTraceEntryType.bypassComponentRender);\n  }\n\n  onComponentViewModelPropertyChange(viewModelPropertyName: string): void {\n    this.buffer.push(RendererTraceEntryType.componentViewModelPropertyChange, viewModelPropertyName);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/RuntimeIssueDisplayer.tsx",
    "content": "import { Label } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Component } from '../Component';\nimport { getVirtualNodeDataFromRootToChild } from '../IRenderedVirtualNodeData';\nimport { Style } from '../Style';\nimport { when } from '../utils/When';\nimport { VirtualNodePathDisplayer } from './VirtualNodePathDisplayer';\n\nexport interface RuntimeIssue {\n  isError: boolean;\n  message: string;\n  nodeId?: number;\n}\n\nexport interface RuntimeIssueViewModel {\n  issue: RuntimeIssue;\n}\n\nconst baseTextStyle = new Style<Label>({\n  textAlign: 'center',\n  numberOfLines: 0,\n});\n\nconst errorTypeStyle = baseTextStyle.extend({\n  font: 'AvenirNext-Bold 16',\n  marginBottom: 8,\n});\n\nconst titleStyle = baseTextStyle.extend({\n  font: 'AvenirNext-DemiBold 12',\n});\n\nconst genericTextStyle = baseTextStyle.extend({\n  font: 'AvenirNext-Medium 12',\n});\n\nexport class RuntimeIssueDisplayer extends Component<RuntimeIssueViewModel> {\n  onRender() {\n    const issue = this.viewModel.issue;\n\n    <layout>\n      <layout>\n        <label\n          value={issue.isError ? 'Error' : 'Warning'}\n          color={issue.isError ? 'red' : 'orange'}\n          style={errorTypeStyle}\n        />\n        <label value={issue.message} style={titleStyle} />\n      </layout>\n      <layout marginTop={20}>\n        {when(issue.nodeId, nodeId => this.renderNodePath(nodeId))}\n        {when(!issue.nodeId, () => this.renderGenericIssue())}\n      </layout>\n    </layout>;\n  }\n\n  private renderNodePath(nodeId: number) {\n    const element = this.renderer.getElementForId(nodeId);\n    if (!element) {\n      this.renderIssue(`Could not resolve RenderedElement for id ${nodeId}`);\n      return;\n    }\n\n    const pair = getVirtualNodeDataFromRootToChild(element.getVirtualNode());\n\n    <VirtualNodePathDisplayer node={pair.root} focusedNode={pair.child} />;\n  }\n\n  private renderGenericIssue() {\n    this.renderIssue(`No further informations available to display.\n    If you feel we should be able to provide more data here, please reach out to us on Slack on #valdi!\n    `);\n  }\n\n  private renderIssue(message: string) {\n    <label style={genericTextStyle} value={message} />;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/Styles.ts",
    "content": "import { Label, View } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Style } from '../Style';\n\nexport const fonts = {\n  body: 'Menlo-Regular 12',\n  medium: 'Menlo-Bold 12',\n  title: 'Menlo-Bold 16',\n};\n\nexport const colors = {\n  errorText: '#ff0000',\n  infoText: 'white',\n  tagBracket: '#808080',\n  tagComponent: '#4EC9B0',\n  tagElement: '#569cd6',\n  comment: '#6A9955',\n\n  expression: '#C8C8C8',\n  attributeName: '#9CDCFE',\n  attributeValue: '#CE9178',\n\n  special: '#C586C0',\n};\n\nexport const styles = {\n  console: new Style<View>({\n    backgroundColor: '#1E1E1E',\n    padding: 8,\n    borderRadius: 8,\n  }),\n  mainBackground: new Style<View>({\n    backgroundColor: '#252526',\n  }),\n  consoleText: new Style<Label>({\n    color: '#D4D4D4',\n    font: fonts.body,\n  }),\n\n  infoText: new Style<Label>({\n    color: 'black',\n    font: fonts.medium,\n  }),\n\n  bodyText: new Style<Label>({\n    color: 'white',\n    font: fonts.body,\n  }),\n\n  bodyStrongText: new Style<Label>({\n    color: 'white',\n    font: fonts.medium,\n  }),\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/debugging/VirtualNodePathDisplayer.tsx",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { AttributedTextAttributes } from 'valdi_tsx/src/AttributedText';\nimport { Component } from '../Component';\nimport { getPathToNode, IRenderedVirtualNodeData } from '../IRenderedVirtualNodeData';\nimport { AttributedTextBuilder } from '../utils/AttributedTextBuilder';\nimport { colors, styles } from './Styles';\n\ninterface ViewModel {\n  node: IRenderedVirtualNodeData;\n  focusedNode?: IRenderedVirtualNodeData;\n}\n\nconst headerStyle = styles.infoText.extend({\n  marginBottom: 8,\n});\n\nexport class VirtualNodePathDisplayer extends Component<ViewModel> {\n  onRender() {\n    let title: string;\n\n    if (this.viewModel.focusedNode) {\n      if (this.viewModel.focusedNode.component) {\n        title = `Path from root to Component '${this.viewModel.focusedNode.tag}':`;\n      } else {\n        title = `Path from root to Element '${this.viewModel.focusedNode.tag}' with id ${\n          this.viewModel.focusedNode.element!.id\n        }:`;\n      }\n    } else {\n      title = 'Path from root';\n    }\n\n    <layout>\n      <label style={headerStyle} color='black' value={title} />\n      <view style={styles.console}>\n        <scroll horizontal>\n          <layout>{this.renderNodePaths()}</layout>\n        </scroll>\n      </view>\n    </layout>;\n  }\n\n  renderNodePaths() {\n    let nodePaths: number[] | undefined;\n\n    if (this.viewModel.focusedNode) {\n      nodePaths = getPathToNode(this.viewModel.node, this.viewModel.focusedNode);\n    }\n\n    this.renderNode(this.viewModel.node, 0, nodePaths);\n  }\n\n  private renderChildrenCount(label: string, count: number, indent: string) {\n    if (!count) {\n      return;\n    }\n\n    const childText = count === 1 ? 'child' : 'children';\n\n    this.appendComment(indent, `${count} ${childText} ${label}`);\n  }\n\n  private appendComment(indent: string, text: string) {\n    <label style={styles.bodyText} color={colors.comment} value={`${indent}{ /* ${text} */ }`} />;\n  }\n\n  private appendAttributes(builder: AttributedTextBuilder, attributes: StringMap<string>) {\n    for (const attributeName in attributes) {\n      builder.append(' ');\n      builder.append(attributeName, { color: colors.attributeName });\n      builder.append('=', { color: colors.expression });\n\n      let attributeValue = attributes[attributeName]!;\n      attributeValue = attributeValue.replace(/\\n/g, '');\n\n      if (Number.isNaN(parseInt(attributeValue))) {\n        attributeValue = `'${attributeValue}'`;\n      }\n\n      builder.append(attributeValue, { color: colors.attributeValue });\n    }\n  }\n\n  private renderNode(node: IRenderedVirtualNodeData, depth: number, nodePaths: number[] | undefined) {\n    let indent = '';\n    for (let i = 0; i < depth; i++) {\n      indent += '  ';\n    }\n\n    const tagStyle: AttributedTextAttributes = node.component\n      ? { color: colors.tagComponent }\n      : { color: colors.tagElement };\n\n    const isFocused = node === this.viewModel.focusedNode;\n\n    if (isFocused) {\n      this.appendComment(indent, '↓↓↓');\n    }\n\n    const shouldRenderChildren =\n      node.children && node !== this.viewModel.focusedNode && (!nodePaths || nodePaths.length);\n\n    if (!shouldRenderChildren) {\n      const textBuilder = new AttributedTextBuilder()\n        .append(indent)\n        .append('<', { color: colors.tagBracket })\n        .append(node.tag, tagStyle);\n\n      if (node.element && node.element.attributes) {\n        this.appendAttributes(textBuilder, node.element.attributes);\n      }\n\n      const text = textBuilder.append('/>', { color: colors.tagBracket }).build();\n\n      if (isFocused) {\n        <label style={styles.bodyStrongText} value={text} />;\n      } else {\n        <label style={styles.bodyText} value={text} />;\n      }\n    } else {\n      const openingTagBuilder = new AttributedTextBuilder()\n        .append(indent)\n        .append('<', { color: colors.tagBracket })\n        .append(node.tag, tagStyle);\n\n      if (node.element && node.element.attributes) {\n        this.appendAttributes(openingTagBuilder, node.element.attributes);\n      }\n\n      const openingTag = openingTagBuilder.append('>', { color: colors.tagBracket }).build();\n      const closingTag = new AttributedTextBuilder()\n        .append(indent)\n        .append('</', { color: colors.tagBracket })\n        .append(node.tag, tagStyle)\n        .append('>', { color: colors.tagBracket })\n        .build();\n\n      <label style={styles.bodyText} value={openingTag} />;\n      {\n        this.renderNodeChildren(node, depth + 1, indent, nodePaths);\n      }\n      <label style={styles.bodyText} value={closingTag} />;\n    }\n  }\n\n  private renderNodeChildren(\n    node: IRenderedVirtualNodeData,\n    newDepth: number,\n    indent: string,\n    nodePaths: number[] | undefined,\n  ) {\n    const children = node.children;\n    if (!children) {\n      return;\n    }\n\n    if (nodePaths) {\n      const index = nodePaths.shift();\n      if (index === undefined) {\n        return;\n      }\n\n      const childrenBefore = index;\n      const childrenAfter = children.length - index - 1;\n      this.renderChildrenCount('before', childrenBefore, indent);\n      this.renderNode(children[index], newDepth, nodePaths);\n      this.renderChildrenCount('after', childrenAfter, indent);\n    } else {\n      for (const child of children) {\n        this.renderNode(child, newDepth, nodePaths);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/localization/ExternalUnparsedLocalizableStringResolver.ts",
    "content": "import { IUnparsedLocalizableStringResolver } from './IUnparsedLocalizableStringResolver';\nimport { getLocalizedString } from '../Strings';\n\nexport class ExternalUnparsedLocalizableStringResolver implements IUnparsedLocalizableStringResolver {\n  constructor(readonly module: string) {}\n\n  resolveUnparsedLocalizableString(key: string): string | undefined {\n    return getLocalizedString(this.module, key);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/localization/IUnparsedLocalizableStringResolver.d.ts",
    "content": "export interface IUnparsedLocalizableStringResolver {\n  resolveUnparsedLocalizableString(key: string): string | undefined;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/localization/InlineUnparsedLocalizableStringResolver.ts",
    "content": "import { IUnparsedLocalizableStringResolver } from './IUnparsedLocalizableStringResolver';\nimport { resolveLocale } from './LocaleResolver';\nimport { Locale } from './Locale';\n\nfunction convertStringParametersToIndexes(str: string): string {\n  let argumentIndex = 0;\n  // eslint-disable-next-line no-constant-condition\n  while (true) {\n    const startIndex = str.indexOf('{');\n    if (startIndex < 0) {\n      break;\n    }\n    const endIndex = str.indexOf('}');\n    if (endIndex < 0) {\n      throw new Error(`Mismatching string parameter at ${str}`);\n    }\n\n    const prefix = str.substr(0, startIndex);\n    const suffix = str.substr(endIndex + 1);\n\n    str = `${prefix}\\$${argumentIndex}${suffix}`;\n    argumentIndex++;\n  }\n\n  return str;\n}\n\nexport interface LocalizableJsonFileEntry {\n  defaultMessage: string;\n}\n\nexport interface LocalizationJsonFile {\n  [key: string]: LocalizableJsonFileEntry | undefined;\n}\n\nexport type GetJsonFileFn = (filePath: string) => LocalizationJsonFile | undefined;\n\nexport type GetCurrentLocalesFn = () => readonly Locale[];\n\nexport interface AvailableLocalization {\n  language: string;\n  path: string;\n}\n\nexport class InlineUnparsedLocalizableStringResolver implements IUnparsedLocalizableStringResolver {\n  private localizationJsonFile: LocalizationJsonFile | undefined;\n\n  constructor(\n    readonly availableLocales: string[],\n    readonly filePaths: string[],\n    readonly getJsonFileContentFn: GetJsonFileFn,\n    readonly getCurrentLocalesFn: GetCurrentLocalesFn,\n  ) {\n    if (availableLocales.length !== filePaths.length) {\n      throw new Error('Mismatched availableLocales and filePaths');\n    }\n  }\n\n  withCurrentLocales(getCurrentLocales: GetCurrentLocalesFn): InlineUnparsedLocalizableStringResolver {\n    return new InlineUnparsedLocalizableStringResolver(\n      this.availableLocales,\n      this.filePaths,\n      this.getJsonFileContentFn,\n      getCurrentLocales,\n    );\n  }\n\n  resolveUnparsedLocalizableString(key: string): string | undefined {\n    const message = this.resolveLocalizationJsonFile()[key]?.defaultMessage;\n    if (!message) {\n      return undefined;\n    }\n\n    return convertStringParametersToIndexes(message);\n  }\n\n  private resolveLocalizationJsonFile(): LocalizationJsonFile {\n    if (!this.localizationJsonFile) {\n      const currentLocales = this.getCurrentLocalesFn();\n      const index = resolveLocale(currentLocales, this.availableLocales.map(Locale.parse));\n      if (index < 0) {\n        throw new Error(\n          `Could not resolve locale with current locale [${currentLocales.join(\n            ', ',\n          )}] and available locales [${this.availableLocales.join(', ')}]`,\n        );\n      }\n\n      const filePath = this.filePaths[index];\n      const jsonFile = this.getJsonFileContentFn(filePath);\n      if (!jsonFile) {\n        throw new Error(`Could not resolve localization JSON file at ${filePath}`);\n      }\n      this.localizationJsonFile = jsonFile;\n    }\n\n    return this.localizationJsonFile;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/localization/Locale.ts",
    "content": "export class Locale {\n  readonly language: string;\n  readonly region: string | undefined;\n\n  constructor(language: string, region: string | undefined) {\n    this.language = language.toLowerCase();\n    this.region = region?.toLocaleUpperCase();\n  }\n\n  toString(): string {\n    if (this.region) {\n      return `${this.language}-${this.region}`;\n    } else {\n      return this.language;\n    }\n  }\n\n  static parse(input: string): Locale {\n    const components = input.split('-');\n    return new Locale(components[0], components[1]);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/localization/LocaleResolver.ts",
    "content": "import { Device } from '../Device';\nimport { Locale } from './Locale';\n\nexport function getCurrentLocales(): Locale[] {\n  const locales = Device.getDeviceLocales();\n  if (locales.length) {\n    return locales.map(Locale.parse);\n  }\n\n  if (typeof Intl !== 'undefined') {\n    const intlLocale = Intl.DateTimeFormat().resolvedOptions().locale;\n    return [Locale.parse(intlLocale)];\n  }\n\n  return [];\n}\n\nconst LOCALE_PRIORITY_MULTIPLER = 100000;\n\nconst enum LocaleScore {\n  MISMATCH = 0,\n  FALLBACK,\n  MATCH_LANGUAGE,\n  MATCH_LANGUAGE_AND_REGION,\n}\n\nfunction isFallbackLocale(locale: Locale): boolean {\n  return locale.language === 'en';\n}\n\n/**\n * Score is computed such that:\n * - When language matches, the \"currentLocales\" order defines the priority\n * - Language and region match will score higher than just language match only\n * for locales at the same index in the \"currentLocales\" array.\n * - Fallback language scores higher than mismatch\n * - Mismatch scores 0\n */\nfunction computeLocaleScore(currentLocale: Locale, candidateLocale: Locale, currentLocalePriority: number): number {\n  if (currentLocale.language === candidateLocale.language) {\n    const premul = LOCALE_PRIORITY_MULTIPLER * currentLocalePriority;\n    if (currentLocale.region === candidateLocale.region) {\n      return premul + LocaleScore.MATCH_LANGUAGE_AND_REGION;\n    } else {\n      return premul + LocaleScore.MATCH_LANGUAGE;\n    }\n  }\n\n  if (isFallbackLocale(candidateLocale)) {\n    return LocaleScore.FALLBACK;\n  }\n\n  return LocaleScore.MISMATCH;\n}\n\nexport function resolveLocale(currentLocales: readonly Locale[], candidateLocales: readonly Locale[]): number {\n  let bestLocaleIndex: number = -1;\n  let bestLocaleScore = LocaleScore.MISMATCH;\n  let localeIndex = 0;\n\n  for (const candidateLocale of candidateLocales) {\n    if (currentLocales.length > 0) {\n      let currentLocalePriority = currentLocales.length;\n      for (const currentLocale of currentLocales) {\n        const score = computeLocaleScore(currentLocale, candidateLocale, currentLocalePriority);\n        if (score > bestLocaleScore) {\n          bestLocaleIndex = localeIndex;\n          bestLocaleScore = score;\n        }\n        currentLocalePriority--;\n      }\n    } else if (isFallbackLocale(candidateLocale)) {\n      return localeIndex;\n    }\n\n    localeIndex++;\n  }\n\n  return bestLocaleIndex;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/localization/LocalizableString.ts",
    "content": "import { formatNumber } from 'valdi_core/src/utils/NumberUtils';\n\nexport type LocalizableStringPart = string | number;\n\nexport enum LocalizableStringParameterType {\n  STRING = 0,\n  NUMBER = 1,\n}\n\nexport class LocalizableString {\n  /**\n   * The original, not parsed string\n   */\n\n  readonly original: string;\n\n  /**\n   * The deconstructed parts of the localizable strings.\n   * When the value is a number, it represents the argument index that should be\n   * used to build the output string. When the value is a string, it represents\n   * a constant part.\n   */\n  readonly parts: readonly LocalizableStringPart[];\n\n  constructor(original: string, parts: readonly LocalizableStringPart[]) {\n    this.original = original;\n    this.parts = parts;\n  }\n\n  format(types: LocalizableStringParameterType[], args: any[]): string {\n    const out: string[] = [];\n\n    for (const part of this.parts) {\n      if (typeof part === 'number') {\n        if (part < 0 || part >= types.length || part >= args.length) {\n          throw new Error(`Out of bounds argument ${part} in localizable string ${this.original}`);\n        }\n\n        const type = types[part];\n        const arg = args[part];\n\n        if (arg === undefined) {\n          out.push('<undefined>');\n        } else if (arg === null) {\n          out.push('<null>');\n        } else {\n          switch (type) {\n            case LocalizableStringParameterType.NUMBER:\n              out.push(formatNumber(arg));\n              break;\n            case LocalizableStringParameterType.STRING:\n              out.push(arg.toString());\n              break;\n          }\n        }\n      } else {\n        out.push(part);\n      }\n    }\n\n    return out.join('');\n  }\n\n  static parse(input: string): LocalizableString {\n    const tokens = input.split(/\\$(\\d+)/g);\n    const parts: LocalizableStringPart[] = [];\n\n    for (const token of tokens) {\n      const arg = parseInt(token, 10);\n      // Checks if the entire token is an integer.\n      if (isNaN(arg) || token !== arg.toString()) {\n        parts.push(token);\n      } else {\n        parts.push(arg);\n      }\n    }\n\n    return new LocalizableString(input, parts);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/localization/LocalizableStringsModule.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { toCamelCase } from '../utils/StringUtils';\nimport { IUnparsedLocalizableStringResolver } from './IUnparsedLocalizableStringResolver';\nimport { LocalizableString, LocalizableStringParameterType } from './LocalizableString';\n\nconst EXPORT_KEY = Symbol();\n\nexport interface LocalizableStringsModuleExports {\n  [key: string]: (...formatArgs: any[]) => string;\n}\n\nexport class LocalizableStringsModule {\n  exports: LocalizableStringsModuleExports;\n\n  get stringResolver(): IUnparsedLocalizableStringResolver {\n    return this._stringResolver;\n  }\n\n  set stringResolver(value: IUnparsedLocalizableStringResolver) {\n    if (this._stringResolver !== value) {\n      this._stringResolver = value;\n      this.cache = {};\n    }\n  }\n\n  private _stringResolver: IUnparsedLocalizableStringResolver;\n  private cache: StringMap<LocalizableString> = {};\n\n  constructor(stringResolver: IUnparsedLocalizableStringResolver) {\n    this._stringResolver = stringResolver;\n    this.exports = {};\n    (this.exports as any)[EXPORT_KEY] = this;\n  }\n\n  add(key: string, parameterTypes: LocalizableStringParameterType[] | undefined): void {\n    const property = toCamelCase(key);\n\n    if (!parameterTypes) {\n      this.exports[property] = (): string => {\n        return this.getOrCreateLocalizableString(key).original;\n      };\n    } else {\n      this.exports[property] = (...formatArgs: any[]): string => {\n        return this.getOrCreateLocalizableString(key).format(parameterTypes, formatArgs);\n      };\n    }\n  }\n\n  private getOrCreateLocalizableString(key: string): LocalizableString {\n    let localizableString = this.cache[key];\n    if (!localizableString) {\n      const str = this._stringResolver.resolveUnparsedLocalizableString(key) || key;\n      localizableString = LocalizableString.parse(str);\n      this.cache[key] = localizableString;\n    }\n\n    return localizableString;\n  }\n\n  static fromExports(exports: LocalizableStringsModuleExports): LocalizableStringsModule {\n    const module = (exports as any)[EXPORT_KEY] as LocalizableStringsModule;\n    if (!module) {\n      throw new Error('Not an exports object');\n    }\n\n    return module;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/GlobalProviderSource.ts",
    "content": "import { IProviderSource } from './IProviderSource';\nimport { ProviderSourceHead, ProviderSourceList } from './ProviderSource';\n\nexport type GlobalProviderSourceId = number;\n\ntype GlobalProviderSourceIndex = { [key: GlobalProviderSourceId]: IProviderSource | undefined };\n\ninterface GlobalProviderSourceStore {\n  index: GlobalProviderSourceIndex;\n  sequence: number;\n}\n\ninterface GlobalProviderSourceStoreAccessor {\n  $globalProviderSourceStore?: GlobalProviderSourceStore;\n}\n\ndeclare const global: GlobalProviderSourceStoreAccessor;\n\nfunction getOrCreateGlobalProviderSourceStore(): GlobalProviderSourceStore {\n  let store = global.$globalProviderSourceStore;\n  if (!store) {\n    store = {\n      index: {},\n      sequence: 0,\n    };\n    global.$globalProviderSourceStore = store;\n  }\n  return store;\n}\n\n/**\n * Retrieves a previously registered global ProviderSource by its id.\n */\nexport function getGlobalProviderSource(globalProviderSourceId: GlobalProviderSourceId): IProviderSource | undefined {\n  return getOrCreateGlobalProviderSourceStore().index[globalProviderSourceId];\n}\n\n/**\n * Retrieves a known previously registered global ProviderSource by its id\n */\nexport function getGlobalProviderSourceOrThrow(globalProviderSourceId: GlobalProviderSourceId): IProviderSource {\n  const globalProviderSource = getGlobalProviderSource(globalProviderSourceId);\n  if (!globalProviderSource) {\n    throw new Error(`Could not resolve global ProviderSource with ${globalProviderSourceId}`);\n  }\n  return globalProviderSource;\n}\n\n/**\n * Register a ProviderSource as part of the global ProviderSource.\n * @returns the generated id for the Global ProviderSource\n */\nexport function registerGlobalProviderSource(providerSource: IProviderSource): GlobalProviderSourceId {\n  const store = getOrCreateGlobalProviderSourceStore();\n\n  const id = ++store.sequence;\n  store.index[id] = providerSource;\n\n  return id;\n}\n\n/**\n * @ExportFunction\n * Unregister a previously registered global ProviderSource, making it unreachable through the getGlobalProviderSource() API.\n */\nexport function unregisterGlobalProviderSource(globalProviderSourceId: GlobalProviderSourceId) {\n  const store = getOrCreateGlobalProviderSourceStore();\n  delete store.index[globalProviderSourceId];\n}\n\n/**\n * Create and register a Global ProviderSource, which can later be retrieved through the getGlobalProviderSource() method\n * @param parentGlobalProviderSourceId if provided, the newly created ProviderSource will inherit from the given parent ProviderSource\n * @param builder A builder function which will be called with the starting ProviderSource. The builder should set any values it wants\n * to set in the ProviderSource and return the result.\n * @returns The id for the newly created global ProviderSource\n */\nexport function createGlobalProviderSource(\n  parentGlobalProviderSourceId: GlobalProviderSourceId | undefined,\n  builder: (source: IProviderSource) => IProviderSource,\n): GlobalProviderSourceId {\n  let startingProviderSource: IProviderSource;\n  if (parentGlobalProviderSourceId) {\n    startingProviderSource = getGlobalProviderSourceOrThrow(parentGlobalProviderSourceId);\n  } else {\n    startingProviderSource = new ProviderSourceHead();\n  }\n\n  const providerSource = builder(startingProviderSource);\n  return registerGlobalProviderSource(providerSource);\n}\n\n/**\n * @ExportFunction\n * Combine a list of Global ProviderSource into a new global ProviderSource.\n */\nexport function combineGlobalProviderSource(globalProviderSourceIds: GlobalProviderSourceId[]): GlobalProviderSourceId {\n  const providerSources = globalProviderSourceIds.map(getGlobalProviderSourceOrThrow);\n  return registerGlobalProviderSource(new ProviderSourceList(providerSources));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/IProviderSource.d.ts",
    "content": "import { ProviderKey } from './ProviderKey';\n\n/**\n * a ProviderSource holds the source of data for the providers.\n */\nexport interface IProviderSource {\n  /**\n   * Returns the value for the given provider.\n   * Throws if the value cannot be retrieved.\n   */\n  getValue<T>(key: ProviderKey<T>): T;\n\n  /**\n   * Returns whether the ProviderSource can provide the value\n   * with the given key\n   */\n  hasValue<T>(key: ProviderKey<T>): boolean;\n\n  /**\n   * Associate the provider with the given value and return a new ProviderSource\n   * that can provide the given value when queried through getValue()\n   */\n  withValue<T>(key: ProviderKey<T>, value: T): IProviderSource;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/ProviderComponent.d.ts",
    "content": "import { ComponentConstructor, IComponent } from '../IComponent';\nimport { IProviderSource } from './IProviderSource';\nimport { ProviderKey } from './ProviderKey';\n\nexport interface ProviderSourceComponent<ViewModel> extends IComponent<ViewModel> {\n  $getProviderSource(): IProviderSource | undefined;\n}\n\nexport type ProviderValue<TValue> = Readonly<TValue>;\n\nexport interface ProviderViewModel<TValue> {\n  value: ProviderValue<TValue>;\n}\n\nexport interface ProviderComponent<TValue> extends ProviderSourceComponent<ProviderViewModel<TValue>> {}\n\nexport interface ProviderConstructor<TValue>\n  extends ComponentConstructor<ProviderComponent<TValue>, ProviderViewModel<TValue>> {\n  getProviderKey(): ProviderKey<TValue>;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/ProviderKey.ts",
    "content": "export type ProviderKeyName = string;\n\nexport interface ProviderKey<TValue> {\n  keyName: ProviderKeyName;\n  brand?: TValue;\n}\n\n/**\n * Create a ProviderKey with the given name.\n */\nexport function createProviderKey<TValue>(name: ProviderKeyName): ProviderKey<TValue> {\n  return {\n    keyName: name,\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/ProviderSource.ts",
    "content": "import { IProviderSource } from './IProviderSource';\nimport { ProviderKey } from './ProviderKey';\n\n/**\n * An implementation of IProviderSource that holds a provider and a value,\n * and contains a pointer to its parent. When resolving values,\n * the ProviderSource goes up the chain until it finds a match\n * for the given provider.\n */\nclass ProviderSourceWithValue<TValue> implements IProviderSource {\n  constructor(readonly parent: IProviderSource, readonly key: ProviderKey<TValue>, readonly value: TValue) {}\n\n  getValue<T>(key: ProviderKey<T>): T {\n    if (this.key.keyName === key.keyName) {\n      return this.value as unknown as T;\n    }\n\n    return this.parent.getValue(key);\n  }\n\n  hasValue<T>(key: ProviderKey<T>): boolean {\n    if (this.key.keyName === key.keyName) {\n      return true;\n    }\n\n    return this.parent.hasValue(key);\n  }\n\n  withValue<T>(key: ProviderKey<T>, value: T): IProviderSource {\n    return new ProviderSourceWithValue(this, key, value);\n  }\n}\n\n/**\n * A IProviderSource implementation that acts as the header for the ProviderSource\n * list. It can create new sources with associated values through the withValue() API.\n */\nexport class ProviderSourceHead implements IProviderSource {\n  constructor() {}\n\n  getValue<T>(key: ProviderKey<T>): T {\n    throw new Error(`Could not resolve Value for Provider Key '${key.keyName}'`);\n  }\n\n  hasValue<T>(key: ProviderKey<T>): boolean {\n    return false;\n  }\n\n  withValue<T>(key: ProviderKey<T>, value: T): IProviderSource {\n    return new ProviderSourceWithValue(this, key, value);\n  }\n}\n\nexport class ProviderSourceList implements IProviderSource {\n  constructor(readonly providerSources: IProviderSource[]) {}\n\n  getValue<T>(key: ProviderKey<T>): T {\n    for (const providerSource of this.providerSources) {\n      if (providerSource.hasValue(key)) {\n        return providerSource.getValue(key);\n      }\n    }\n    throw new Error(`Could not resolve Value for Provider Key '${key.keyName}'`);\n  }\n\n  hasValue<T>(key: ProviderKey<T>): boolean {\n    for (const providerSource of this.providerSources) {\n      if (providerSource.hasValue(key)) {\n        return true;\n      }\n    }\n    return false;\n  }\n\n  withValue<T>(key: ProviderKey<T>, value: T): IProviderSource {\n    return new ProviderSourceWithValue(this, key, value);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/WithGlobalProviderSource.tsx",
    "content": "import { StatefulComponent } from '../Component';\nimport { getGlobalProviderSource, GlobalProviderSourceId } from './GlobalProviderSource';\nimport { IProviderSource } from './IProviderSource';\nimport { ProviderSourceComponent } from './ProviderComponent';\n\ninterface ViewModel {\n  globalProviderSourceId: GlobalProviderSourceId;\n}\n\ninterface State {\n  slotKey: number;\n  providerSource?: IProviderSource;\n}\n\n/**\n * WithGlobalProviderSource is a component that will expose a global ProviderSource to its\n * slot, making any dependencies included in the ProviderSource to be accessible within that subtree.\n */\nexport class WithGlobalProviderSource\n  extends StatefulComponent<ViewModel, State>\n  implements ProviderSourceComponent<ViewModel>\n{\n  state: State = {\n    slotKey: 0,\n  };\n\n  onViewModelUpdate() {\n    const newProviderSource = getGlobalProviderSource(this.viewModel.globalProviderSourceId);\n\n    if (!newProviderSource) {\n      throw new Error(`Could not resolve global ProviderSource with id ${this.viewModel.globalProviderSourceId}`);\n    }\n\n    if (newProviderSource !== this.state.providerSource) {\n      this.setState({\n        slotKey: this.state.slotKey + 1,\n        providerSource: newProviderSource,\n      });\n    }\n  }\n\n  onRender(): void {\n    <slot key={this.state.slotKey.toString()} />;\n  }\n\n  $getProviderSource(): IProviderSource | undefined {\n    return this.state.providerSource;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/createProvider.tsx",
    "content": "import { StatefulComponent } from '../Component';\nimport { IProviderSource } from './IProviderSource';\nimport { ProviderComponent, ProviderConstructor, ProviderViewModel } from './ProviderComponent';\nimport { createProviderKey, ProviderKey, ProviderKeyName } from './ProviderKey';\nimport { ProviderSourceHead } from './ProviderSource';\nimport { resolveProviderSource } from './resolveProviderSource';\n\ninterface ProviderComponentState {\n  providerValueKey: number;\n  providerSource?: IProviderSource;\n}\n\n/**\n * \"Creates and returns a Provider Component class that can be rendered to implicitly provide dependency to children components.\n * The returned class should be stored globally at the top of a TypeScript module.\n * To provide a dependency, you can render a Provider component with its value like <TestProvider value={testValue}>.\n * Whenever you re-render a Provider component with a new value, it will trigger a full re-render for all children components,\n * tearing down any children that were rendered with the previously provided value.\n * For more information about how to consume a provider dependency, please see the withProviders function.\n * For details and examples, please read the docs at ../../../../../../../docs/docs/advanced-provider\"\n *\n * @param providerKeyName A Unique name key for the provider which uniquely identifies the provider\n */\nexport function createProviderComponentWithKeyName<TValue>(\n  providerKeyName: ProviderKeyName,\n): ProviderConstructor<TValue> {\n  const key = createProviderKey<TValue>(providerKeyName);\n  return createProviderComponent(key);\n}\n\n/**\n * \"Creates and returns a Provider Component class that can be rendered to implicitly provide dependency to children components.\n * The returned class should be stored globally at the top of a TypeScript module.\n * To provide a dependency, you can render a Provider component with its value like <TestProvider value={testValue}>.\n * Whenever you re-render a Provider component with a new value, it will trigger a full re-render for all children components,\n * tearing down any children that were rendered with the previously provided value.\n * For more information about how to consume a provider dependency, please see the withProviders function.\n * For details and examples, please read the docs at ../../../../../../../docs/docs/advanced-provider\"\n *\n * @param providerKey The ProviderKey which was returned from a previous call of createProviderKey()\n */\nexport function createProviderComponent<TValue>(providerKey: ProviderKey<TValue>): ProviderConstructor<TValue> {\n  class Provider\n    extends StatefulComponent<ProviderViewModel<TValue>, ProviderComponentState>\n    implements ProviderComponent<TValue>\n  {\n    public state: ProviderComponentState = { providerValueKey: 0 };\n\n    private startingProviderSource: IProviderSource | undefined;\n\n    public onCreate(): void {\n      super.onCreate();\n\n      let providerSource = resolveProviderSource();\n      if (!providerSource) {\n        providerSource = new ProviderSourceHead();\n      }\n      this.startingProviderSource = providerSource;\n\n      this.state = {\n        providerValueKey: 0,\n        providerSource: providerSource,\n      };\n    }\n\n    public onViewModelUpdate(): void {\n      const providerSource = this.startingProviderSource!;\n\n      let { providerValueKey } = this.state;\n      const subProviderSource = providerSource.withValue(providerKey, this.viewModel.value);\n\n      this.setState({ providerValueKey: ++providerValueKey, providerSource: subProviderSource });\n    }\n\n    public $getProviderSource(): IProviderSource | undefined {\n      return this.state.providerSource;\n    }\n\n    onRender(): void {\n      <slot key={this.state.providerValueKey.toString()} />;\n    }\n\n    static getProviderKey(): ProviderKey<TValue> {\n      return providerKey;\n    }\n  }\n\n  Object.defineProperty(Provider, 'name', { value: `${providerKey.keyName}Provider` });\n\n  return Provider;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/resolveProviderSource.ts",
    "content": "import { IComponent } from '../IComponent';\nimport { jsx } from '../JSXBootstrap';\nimport { IProviderSource } from './IProviderSource';\nimport { ProviderComponent } from './ProviderComponent';\n\nfunction findProviderSource(currentComponent: IComponent | undefined): IProviderSource | undefined {\n  while (currentComponent) {\n    const providerComponent = currentComponent as ProviderComponent<any>;\n    if (providerComponent.$getProviderSource) {\n      const providerSource = providerComponent.$getProviderSource();\n      if (providerSource) {\n        return providerSource;\n      }\n    }\n\n    currentComponent = currentComponent.renderer.getComponentParent(currentComponent);\n  }\n\n  return undefined;\n}\n\nexport function resolveProviderSource(): IProviderSource | undefined {\n  const currentComponent = jsx.getCurrentComponentInstance();\n  if (!currentComponent) {\n    throw new Error('Cannot resolve Provider Source: there are no components being currently rendered');\n  }\n\n  return findProviderSource(jsx.getCurrentComponentInstance());\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/resolveProviderValue.ts",
    "content": "import { ProviderKey } from './ProviderKey';\nimport { resolveProviderSource } from './resolveProviderSource';\n\nexport function resolveProviderValue<TValue>(key: ProviderKey<TValue>): TValue {\n  const providerSource = resolveProviderSource();\n  if (!providerSource) {\n    throw new Error(\n      'No ProviderSource found in the tree. Please render a Provider component within this component tree',\n    );\n  }\n  return providerSource.getValue(key);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/provider/withProviders.tsx",
    "content": "import { Component } from '../Component';\nimport { ComponentConstructor, IComponent } from '../IComponent';\nimport { ProviderConstructor } from './ProviderComponent';\nimport { ProviderKey } from './ProviderKey';\nimport { resolveProviderValue } from './resolveProviderValue';\n\ntype ProviderValues<TProvidersValues> = {\n  providersValues: TProvidersValues;\n};\n\nexport type ProvidersValuesViewModel<TProvidersValues extends Array<unknown>> = ProviderValues<TProvidersValues>;\nexport type ProvidersConsumptionComponent<TOutViewModel> = IComponent<TOutViewModel>;\n\ntype GetProvidersValues<TProviderKeys> = {\n  [Key in keyof TProviderKeys]: TProviderKeys[Key] extends ProviderKey<infer TProviderValue> ? TProviderValue : never;\n};\n\ntype GetOutViewModel<TInViewModel> = Omit<TInViewModel, 'providersValues'>;\n\n/**\n * Creates and returns a wrapper component/higher order component, which provides access to the provider's values.\n * To consume providers values you should pass needed providers to this function.\n * Then, you need to extend your view model from `ProvidersValuesViewModel` with the correct types of needed providers\n * Result of this function will be a wrapper/higher order component which will have the similar view model as your\n * original component but under the hood will pass an additional property as part of view model - providersValues.\n * This property represents actual providers values which will be resolved from the top/closest parent Provider components\n * How to create provider dependency, please see `createProvider` function.\n * For details and examples, please read the docs ../../../../../../../docs/docs/advanced-provider\n *\n * @param providerKeys The Provider Keys that were previously returned from a createProviderKey() call\n */\nexport function withProviderKeys<TProviderKeys extends readonly ProviderKey<any>[]>(\n  ...providerSourceKeys: TProviderKeys\n) {\n  return function <\n    TInViewModel extends ProviderValues<GetProvidersValues<TProviderKeys>>,\n    TOutViewModel extends GetOutViewModel<TInViewModel>,\n  >(\n    ComponentForConsume: ComponentConstructor<IComponent<TInViewModel>, TInViewModel>,\n  ): ComponentConstructor<IComponent<TOutViewModel>, TOutViewModel> {\n    return class ProvidersConsumptionComponent extends Component<TOutViewModel> {\n      providersValues = new Array<ProvidersValuesViewModel<unknown[]>>();\n\n      onCreate(): void {\n        this.providersValues = providerSourceKeys.map(resolveProviderValue);\n      }\n\n      onRender(): void {\n        <ComponentForConsume\n          {...(this.viewModel as TInViewModel & TOutViewModel)}\n          providersValues={this.providersValues}\n          children={(this.viewModel as any).children}\n        />;\n      }\n    };\n  };\n}\n\n/**\n * Creates and returns a wrapper component/higher order component, which provides access to the provider's values.\n * To consume providers values you should pass needed providers to this function.\n * Then, you need to extend your view model from `ProvidersValuesViewModel` with the correct types of needed providers\n * Result of this function will be a wrapper/higher order component which will have the similar view model as your\n * original component but under the hood will pass an additional property as part of view model - providersValues.\n * This property represents actual providers values which will be resolved from the top/closest parent Provider components\n * How to create provider dependency, please see `createProvider` function.\n * For details and examples, please read the docs ../../../../../../../docs/docs/advanced-provider\n *\n * @param providers The Provider Component classes that were previously returned from a createProvider() call\n */\nexport function withProviders<TProviders extends readonly ProviderConstructor<any>[]>(...providers: TProviders) {\n  const providerKeys = providers.map(provider => provider.getProviderKey());\n  return withProviderKeys(...providerKeys);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/slot/DetachedSlot.ts",
    "content": "import { IComponent } from '../IComponent';\n\nexport interface IDetachedSlotRenderer extends IComponent {}\n\n/**\n * a DetachedSlot allows to render elements and components into\n * a slot hosted by a component in an arbitrary location in the tree.\n * A DetachedSlot allows to disassociate the elements being rendered,\n * and where those elements are rendered. After a DetachedSlot is created,\n * a DetachedSlotRenderer should be created and rendered in the tree.\n * The DetachedSlotRenderer will render the slot in the subtree\n * where it is rendered. A separate component could then use the slot to set\n * the render function that should be evaluated by the DetachedSlotRenderer.\n */\nexport class DetachedSlot {\n  private renderers: IDetachedSlotRenderer[] = [];\n  private renderFn?: () => void;\n\n  /**\n   * Sets the render function that should be rendered inside the DetachedSlotRenderer.\n   * If no DetachedSlotRenderer were created, this call will be a no-op until a\n   * DetachedSlotRenderer is created with this Zone.\n   * @param fn the render function to evaluate inside the DetachedSlotRenderer.\n   */\n  slotted(fn: () => void) {\n    this.renderFn = fn;\n\n    for (const renderer of this.renderers) {\n      renderer.renderer.renderComponent(renderer, undefined);\n    }\n  }\n\n  attachRenderer(renderer: IDetachedSlotRenderer): void {\n    this.renderers.push(renderer);\n  }\n\n  detachRenderer(renderer: IDetachedSlotRenderer): void {\n    const index = this.renderers.indexOf(renderer);\n    if (index >= 0) {\n      this.renderers.splice(index, 1);\n    }\n  }\n\n  onRendererReady(renderer: IDetachedSlotRenderer) {\n    if (this.renderFn) {\n      this.renderFn();\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/slot/DetachedSlotRenderer.tsx",
    "content": "import { Component } from '../Component';\nimport { DetachedSlot, IDetachedSlotRenderer } from './DetachedSlot';\n\ninterface ViewModel {\n  detachedSlot: DetachedSlot;\n}\n\n/**\n * DetachedSlotRenderer is a component that can render a render function\n * sets into a DetachedSlot.\n */\nexport class DetachedSlotRenderer extends Component<ViewModel> implements IDetachedSlotRenderer {\n  onViewModelUpdate(previousViewModel?: ViewModel) {\n    if (previousViewModel) {\n      previousViewModel.detachedSlot.detachRenderer(this);\n    }\n\n    this.viewModel.detachedSlot.attachRenderer(this);\n  }\n\n  onDestroy() {\n    this.viewModel.detachedSlot.detachRenderer(this);\n  }\n\n  onRender() {\n    this.viewModel.detachedSlot.onRendererReady(this);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/tslib.d.ts",
    "content": "/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n\n/**\n * Used to shim class extends.\n *\n * @param d The derived class.\n * @param b The base class.\n */\nexport declare function __extends(d: Function, b: Function): void;\n\n/**\n * Copy the values of all of the enumerable own properties from one or more source objects to a\n * target object. Returns the target object.\n *\n * @param t The target object to copy to.\n * @param sources One or more source objects from which to copy properties\n */\nexport declare function __assign(t: any, ...sources: any[]): any;\n\n/**\n * Performs a rest spread on an object.\n *\n * @param t The source value.\n * @param propertyNames The property names excluded from the rest spread.\n */\nexport declare function __rest(t: any, propertyNames: (string | symbol)[]): any;\n\n/**\n * Applies decorators to a target object\n *\n * @param decorators The set of decorators to apply.\n * @param target The target object.\n * @param key If specified, the own property to apply the decorators to.\n * @param desc The property descriptor, defaults to fetching the descriptor from the target object.\n * @experimental\n */\nexport declare function __decorate(decorators: Function[], target: any, key?: string | symbol, desc?: any): any;\n\n/**\n * Creates an observing function decorator from a parameter decorator.\n *\n * @param paramIndex The parameter index to apply the decorator to.\n * @param decorator The parameter decorator to apply. Note that the return value is ignored.\n * @experimental\n */\nexport declare function __param(paramIndex: number, decorator: Function): Function;\n\n/**\n * Applies decorators to a class or class member, following the native ECMAScript decorator specification.\n * @param ctor For non-field class members, the class constructor. Otherwise, `null`.\n * @param descriptorIn The `PropertyDescriptor` to use when unable to look up the property from `ctor`.\n * @param decorators The decorators to apply\n * @param contextIn The `DecoratorContext` to clone for each decorator application.\n * @param initializers An array of field initializer mutation functions into which new initializers are written.\n * @param extraInitializers An array of extra initializer functions into which new initializers are written.\n */\nexport declare function __esDecorate(ctor: Function | null, descriptorIn: object | null, decorators: Function[], contextIn: object, initializers: Function[] | null, extraInitializers: Function[]): void;\n\n/**\n * Runs field initializers or extra initializers generated by `__esDecorate`.\n * @param thisArg The `this` argument to use.\n * @param initializers The array of initializers to evaluate.\n * @param value The initial value to pass to the initializers.\n */\nexport declare function __runInitializers(thisArg: unknown, initializers: Function[], value?: any): any;\n\n/**\n * Converts a computed property name into a `string` or `symbol` value.\n */\nexport declare function __propKey(x: any): string | symbol;\n\n/**\n * Assigns the name of a function derived from the left-hand side of an assignment.\n * @param f The function to rename.\n * @param name The new name for the function.\n * @param prefix A prefix (such as `\"get\"` or `\"set\"`) to insert before the name.\n */\nexport declare function __setFunctionName(f: Function, name: string | symbol, prefix?: string): Function;\n\n/**\n * Creates a decorator that sets metadata.\n *\n * @param metadataKey The metadata key\n * @param metadataValue The metadata value\n * @experimental\n */\nexport declare function __metadata(metadataKey: any, metadataValue: any): Function;\n\n/**\n * Converts a generator function into a pseudo-async function, by treating each `yield` as an `await`.\n *\n * @param thisArg The reference to use as the `this` value in the generator function\n * @param _arguments The optional arguments array\n * @param P The optional promise constructor argument, defaults to the `Promise` property of the global object.\n * @param generator The generator function\n */\nexport declare function __awaiter(thisArg: any, _arguments: any, P: Function, generator: Function): any;\n\n/**\n * Creates an Iterator object using the body as the implementation.\n *\n * @param thisArg The reference to use as the `this` value in the function\n * @param body The generator state-machine based implementation.\n *\n * @see [./docs/generator.md]\n */\nexport declare function __generator(thisArg: any, body: Function): any;\n\n/**\n * Creates bindings for all enumerable properties of `m` on `exports`\n *\n * @param m The source object\n * @param exports The `exports` object.\n */\nexport declare function __exportStar(m: any, o: any): void;\n\n/**\n * Creates a value iterator from an `Iterable` or `ArrayLike` object.\n *\n * @param o The object.\n * @throws {TypeError} If `o` is neither `Iterable`, nor an `ArrayLike`.\n */\nexport declare function __values(o: any): any;\n\n/**\n * Reads values from an `Iterable` or `ArrayLike` object and returns the resulting array.\n *\n * @param o The object to read from.\n * @param n The maximum number of arguments to read, defaults to `Infinity`.\n */\nexport declare function __read(o: any, n?: number): any[];\n\n/**\n * Creates an array from iterable spread.\n *\n * @param args The Iterable objects to spread.\n * @deprecated since TypeScript 4.2 - Use `__spreadArray`\n */\nexport declare function __spread(...args: any[][]): any[];\n\n/**\n * Creates an array from array spread.\n *\n * @param args The ArrayLikes to spread into the resulting array.\n * @deprecated since TypeScript 4.2 - Use `__spreadArray`\n */\nexport declare function __spreadArrays(...args: any[][]): any[];\n\n/**\n * Spreads the `from` array into the `to` array.\n *\n * @param pack Replace empty elements with `undefined`.\n */\nexport declare function __spreadArray(to: any[], from: any[], pack?: boolean): any[];\n\n/**\n * Creates an object that signals to `__asyncGenerator` that it shouldn't be yielded,\n * and instead should be awaited and the resulting value passed back to the generator.\n *\n * @param v The value to await.\n */\nexport declare function __await(v: any): any;\n\n/**\n * Converts a generator function into an async generator function, by using `yield __await`\n * in place of normal `await`.\n *\n * @param thisArg The reference to use as the `this` value in the generator function\n * @param _arguments The optional arguments array\n * @param generator The generator function\n */\nexport declare function __asyncGenerator(thisArg: any, _arguments: any, generator: Function): any;\n\n/**\n * Used to wrap a potentially async iterator in such a way so that it wraps the result\n * of calling iterator methods of `o` in `__await` instances, and then yields the awaited values.\n *\n * @param o The potentially async iterator.\n * @returns A synchronous iterator yielding `__await` instances on every odd invocation\n *          and returning the awaited `IteratorResult` passed to `next` every even invocation.\n */\nexport declare function __asyncDelegator(o: any): any;\n\n/**\n * Creates a value async iterator from an `AsyncIterable`, `Iterable` or `ArrayLike` object.\n *\n * @param o The object.\n * @throws {TypeError} If `o` is neither `AsyncIterable`, `Iterable`, nor an `ArrayLike`.\n */\nexport declare function __asyncValues(o: any): any;\n\n/**\n * Creates a `TemplateStringsArray` frozen object from the `cooked` and `raw` arrays.\n *\n * @param cooked The cooked possibly-sparse array.\n * @param raw The raw string content.\n */\nexport declare function __makeTemplateObject(cooked: string[], raw: string[]): TemplateStringsArray;\n\n/**\n * Used to shim default and named imports in ECMAScript Modules transpiled to CommonJS.\n *\n * ```js\n * import Default, { Named, Other } from \"mod\";\n * // or\n * import { default as Default, Named, Other } from \"mod\";\n * ```\n *\n * @param mod The CommonJS module exports object.\n */\nexport declare function __importStar<T>(mod: T): T;\n\n/**\n * Used to shim default imports in ECMAScript Modules transpiled to CommonJS.\n *\n * ```js\n * import Default from \"mod\";\n * ```\n *\n * @param mod The CommonJS module exports object.\n */\nexport declare function __importDefault<T>(mod: T): T | { default: T };\n\n/**\n * Emulates reading a private instance field.\n *\n * @param receiver The instance from which to read the private field.\n * @param state A WeakMap containing the private field value for an instance.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n *\n * @throws {TypeError} If `state` doesn't have an entry for `receiver`.\n */\nexport declare function __classPrivateFieldGet<T extends object, V>(\n    receiver: T,\n    state: { has(o: T): boolean, get(o: T): V | undefined },\n    kind?: \"f\"\n): V;\n\n/**\n * Emulates reading a private static field.\n *\n * @param receiver The object from which to read the private static field.\n * @param state The class constructor containing the definition of the static field.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n * @param f The descriptor that holds the static field value.\n *\n * @throws {TypeError} If `receiver` is not `state`.\n */\nexport declare function __classPrivateFieldGet<T extends new (...args: any[]) => unknown, V>(\n    receiver: T,\n    state: T,\n    kind: \"f\",\n    f: { value: V }\n): V;\n\n/**\n * Emulates evaluating a private instance \"get\" accessor.\n *\n * @param receiver The instance on which to evaluate the private \"get\" accessor.\n * @param state A WeakSet used to verify an instance supports the private \"get\" accessor.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n * @param f The \"get\" accessor function to evaluate.\n *\n * @throws {TypeError} If `state` doesn't have an entry for `receiver`.\n */\nexport declare function __classPrivateFieldGet<T extends object, V>(\n    receiver: T,\n    state: { has(o: T): boolean },\n    kind: \"a\",\n    f: () => V\n): V;\n\n/**\n * Emulates evaluating a private static \"get\" accessor.\n *\n * @param receiver The object on which to evaluate the private static \"get\" accessor.\n * @param state The class constructor containing the definition of the static \"get\" accessor.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n * @param f The \"get\" accessor function to evaluate.\n *\n * @throws {TypeError} If `receiver` is not `state`.\n */\nexport declare function __classPrivateFieldGet<T extends new (...args: any[]) => unknown, V>(\n    receiver: T,\n    state: T,\n    kind: \"a\",\n    f: () => V\n): V;\n\n/**\n * Emulates reading a private instance method.\n *\n * @param receiver The instance from which to read a private method.\n * @param state A WeakSet used to verify an instance supports the private method.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n * @param f The function to return as the private instance method.\n *\n * @throws {TypeError} If `state` doesn't have an entry for `receiver`.\n */\nexport declare function __classPrivateFieldGet<T extends object, V extends (...args: any[]) => unknown>(\n    receiver: T,\n    state: { has(o: T): boolean },\n    kind: \"m\",\n    f: V\n): V;\n\n/**\n * Emulates reading a private static method.\n *\n * @param receiver The object from which to read the private static method.\n * @param state The class constructor containing the definition of the static method.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n * @param f The function to return as the private static method.\n *\n * @throws {TypeError} If `receiver` is not `state`.\n */\nexport declare function __classPrivateFieldGet<T extends new (...args: any[]) => unknown, V extends (...args: any[]) => unknown>(\n    receiver: T,\n    state: T,\n    kind: \"m\",\n    f: V\n): V;\n\n/**\n * Emulates writing to a private instance field.\n *\n * @param receiver The instance on which to set a private field value.\n * @param state A WeakMap used to store the private field value for an instance.\n * @param value The value to store in the private field.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n *\n * @throws {TypeError} If `state` doesn't have an entry for `receiver`.\n */\nexport declare function __classPrivateFieldSet<T extends object, V>(\n    receiver: T,\n    state: { has(o: T): boolean, set(o: T, value: V): unknown },\n    value: V,\n    kind?: \"f\"\n): V;\n\n/**\n * Emulates writing to a private static field.\n *\n * @param receiver The object on which to set the private static field.\n * @param state The class constructor containing the definition of the private static field.\n * @param value The value to store in the private field.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n * @param f The descriptor that holds the static field value.\n *\n * @throws {TypeError} If `receiver` is not `state`.\n */\nexport declare function __classPrivateFieldSet<T extends new (...args: any[]) => unknown, V>(\n    receiver: T,\n    state: T,\n    value: V,\n    kind: \"f\",\n    f: { value: V }\n): V;\n\n/**\n * Emulates writing to a private instance \"set\" accessor.\n *\n * @param receiver The instance on which to evaluate the private instance \"set\" accessor.\n * @param state A WeakSet used to verify an instance supports the private \"set\" accessor.\n * @param value The value to store in the private accessor.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n * @param f The \"set\" accessor function to evaluate.\n *\n * @throws {TypeError} If `state` doesn't have an entry for `receiver`.\n */\nexport declare function __classPrivateFieldSet<T extends object, V>(\n    receiver: T,\n    state: { has(o: T): boolean },\n    value: V,\n    kind: \"a\",\n    f: (v: V) => void\n): V;\n\n/**\n * Emulates writing to a private static \"set\" accessor.\n *\n * @param receiver The object on which to evaluate the private static \"set\" accessor.\n * @param state The class constructor containing the definition of the static \"set\" accessor.\n * @param value The value to store in the private field.\n * @param kind Either `\"f\"` for a field, `\"a\"` for an accessor, or `\"m\"` for a method.\n * @param f The \"set\" accessor function to evaluate.\n *\n * @throws {TypeError} If `receiver` is not `state`.\n */\nexport declare function __classPrivateFieldSet<T extends new (...args: any[]) => unknown, V>(\n    receiver: T,\n    state: T,\n    value: V,\n    kind: \"a\",\n    f: (v: V) => void\n): V;\n\n/**\n * Checks for the existence of a private field/method/accessor.\n *\n * @param state The class constructor containing the static member, or the WeakMap or WeakSet associated with a private instance member.\n * @param receiver The object for which to test the presence of the private member.\n */\nexport declare function __classPrivateFieldIn(\n    state: (new (...args: any[]) => unknown) | { has(o: any): boolean },\n    receiver: unknown,\n): boolean;\n\n/**\n * Creates a re-export binding on `object` with key `objectKey` that references `target[key]`.\n *\n * @param object The local `exports` object.\n * @param target The object to re-export from.\n * @param key The property key of `target` to re-export.\n * @param objectKey The property key to re-export as. Defaults to `key`.\n */\nexport declare function __createBinding(object: object, target: object, key: PropertyKey, objectKey?: PropertyKey): void;\n\n/**\n * Adds a disposable resource to a resource-tracking environment object.\n * @param env A resource-tracking environment object.\n * @param value Either a Disposable or AsyncDisposable object, `null`, or `undefined`.\n * @param async When `true`, `AsyncDisposable` resources can be added. When `false`, `AsyncDisposable` resources cannot be added.\n * @returns The {@link value} argument.\n *\n * @throws {TypeError} If {@link value} is not an object, or if either `Symbol.dispose` or `Symbol.asyncDispose` are not\n * defined, or if {@link value} does not have an appropriate `Symbol.dispose` or `Symbol.asyncDispose` method.\n */\nexport declare function __addDisposableResource<T>(env: { stack: { value?: unknown, dispose?: Function, async: boolean }[]; error: unknown; hasError: boolean; }, value: T, async: boolean): T;\n\n/**\n * Disposes all resources in a resource-tracking environment object.\n * @param env A resource-tracking environment object.\n * @returns A {@link Promise} if any resources in the environment were marked as `async` when added; otherwise, `void`.\n *\n * @throws {SuppressedError} if an error thrown during disposal would have suppressed a prior error from disposal or the\n * error recorded in the resource-tracking environment object.\n * @seealso {@link __addDisposableResource}\n */\nexport declare function __disposeResources(env: { stack: { value?: unknown, dispose?: Function, async: boolean }[]; error: unknown; hasError: boolean; }): any;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/tslib.js",
    "content": "/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global global, define, Symbol, Reflect, Promise, SuppressedError */\nvar __extends;\nvar __assign;\nvar __rest;\nvar __decorate;\nvar __param;\nvar __esDecorate;\nvar __runInitializers;\nvar __propKey;\nvar __setFunctionName;\nvar __metadata;\nvar __awaiter;\nvar __generator;\nvar __exportStar;\nvar __values;\nvar __read;\nvar __spread;\nvar __spreadArrays;\nvar __spreadArray;\nvar __await;\nvar __asyncGenerator;\nvar __asyncDelegator;\nvar __asyncValues;\nvar __makeTemplateObject;\nvar __importStar;\nvar __importDefault;\nvar __classPrivateFieldGet;\nvar __classPrivateFieldSet;\nvar __classPrivateFieldIn;\nvar __createBinding;\nvar __addDisposableResource;\nvar __disposeResources;\n(function (factory) {\n    var root = typeof global === \"object\" ? global : typeof self === \"object\" ? self : typeof this === \"object\" ? this : {};\n    if (typeof define === \"function\" && define.amd) {\n        define(\"tslib\", [\"exports\"], function (exports) { factory(createExporter(root, createExporter(exports))); });\n    }\n    else if (typeof module === \"object\" && typeof module.exports === \"object\") {\n        factory(createExporter(root, createExporter(module.exports)));\n    }\n    else {\n        factory(createExporter(root));\n    }\n    function createExporter(exports, previous) {\n        if (exports !== root) {\n            if (typeof Object.create === \"function\") {\n                Object.defineProperty(exports, \"__esModule\", { value: true });\n            }\n            else {\n                exports.__esModule = true;\n            }\n        }\n        return function (id, v) { return exports[id] = previous ? previous(id, v) : v; };\n    }\n})\n(function (exporter) {\n    var extendStatics = Object.setPrototypeOf ||\n        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n\n    __extends = function (d, b) {\n        if (typeof b !== \"function\" && b !== null)\n            throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n        extendStatics(d, b);\n        function __() { this.constructor = d; }\n        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n    };\n\n    __assign = Object.assign || function (t) {\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\n            s = arguments[i];\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n        }\n        return t;\n    };\n\n    __rest = function (s, e) {\n        var t = {};\n        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n            t[p] = s[p];\n        if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n            for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n                if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n                    t[p[i]] = s[p[i]];\n            }\n        return t;\n    };\n\n    __decorate = function (decorators, target, key, desc) {\n        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n        if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n        else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n        return c > 3 && r && Object.defineProperty(target, key, r), r;\n    };\n\n    __param = function (paramIndex, decorator) {\n        return function (target, key) { decorator(target, key, paramIndex); }\n    };\n\n    __esDecorate = function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n        function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n        var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n        var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n        var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n        var _, done = false;\n        for (var i = decorators.length - 1; i >= 0; i--) {\n            var context = {};\n            for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n            for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n            context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n            var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n            if (kind === \"accessor\") {\n                if (result === void 0) continue;\n                if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n                if (_ = accept(result.get)) descriptor.get = _;\n                if (_ = accept(result.set)) descriptor.set = _;\n                if (_ = accept(result.init)) initializers.unshift(_);\n            }\n            else if (_ = accept(result)) {\n                if (kind === \"field\") initializers.unshift(_);\n                else descriptor[key] = _;\n            }\n        }\n        if (target) Object.defineProperty(target, contextIn.name, descriptor);\n        done = true;\n    };\n\n    __runInitializers = function (thisArg, initializers, value) {\n        var useValue = arguments.length > 2;\n        for (var i = 0; i < initializers.length; i++) {\n            value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n        }\n        return useValue ? value : void 0;\n    };\n\n    __propKey = function (x) {\n        return typeof x === \"symbol\" ? x : \"\".concat(x);\n    };\n\n    __setFunctionName = function (f, name, prefix) {\n        if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n        return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n    };\n\n    __metadata = function (metadataKey, metadataValue) {\n        if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n    };\n\n    __awaiter = function (thisArg, _arguments, P, generator) {\n        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n        return new (P || (P = Promise))(function (resolve, reject) {\n            function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n            function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n            step((generator = generator.apply(thisArg, _arguments || [])).next());\n        });\n    };\n\n    __generator = function (thisArg, body) {\n        var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n        return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n        function verb(n) { return function (v) { return step([n, v]); }; }\n        function step(op) {\n            if (f) throw new TypeError(\"Generator is already executing.\");\n            while (g && (g = 0, op[0] && (_ = 0)), _) try {\n                if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n                if (y = 0, t) op = [op[0] & 2, t.value];\n                switch (op[0]) {\n                    case 0: case 1: t = op; break;\n                    case 4: _.label++; return { value: op[1], done: false };\n                    case 5: _.label++; y = op[1]; op = [0]; continue;\n                    case 7: op = _.ops.pop(); _.trys.pop(); continue;\n                    default:\n                        if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n                        if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n                        if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n                        if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n                        if (t[2]) _.ops.pop();\n                        _.trys.pop(); continue;\n                }\n                op = body.call(thisArg, _);\n            } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n            if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n        }\n    };\n\n    __exportStar = function(m, o) {\n        for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n    };\n\n    __createBinding = Object.create ? (function(o, m, k, k2) {\n        if (k2 === undefined) k2 = k;\n        var desc = Object.getOwnPropertyDescriptor(m, k);\n        if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n            desc = { enumerable: true, get: function() { return m[k]; } };\n        }\n        Object.defineProperty(o, k2, desc);\n    }) : (function(o, m, k, k2) {\n        if (k2 === undefined) k2 = k;\n        o[k2] = m[k];\n    });\n\n    __values = function (o) {\n        var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n        if (m) return m.call(o);\n        if (o && typeof o.length === \"number\") return {\n            next: function () {\n                if (o && i >= o.length) o = void 0;\n                return { value: o && o[i++], done: !o };\n            }\n        };\n        throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n    };\n\n    __read = function (o, n) {\n        var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n        if (!m) return o;\n        var i = m.call(o), r, ar = [], e;\n        try {\n            while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n        }\n        catch (error) { e = { error: error }; }\n        finally {\n            try {\n                if (r && !r.done && (m = i[\"return\"])) m.call(i);\n            }\n            finally { if (e) throw e.error; }\n        }\n        return ar;\n    };\n\n    /** @deprecated */\n    __spread = function () {\n        for (var ar = [], i = 0; i < arguments.length; i++)\n            ar = ar.concat(__read(arguments[i]));\n        return ar;\n    };\n\n    /** @deprecated */\n    __spreadArrays = function () {\n        for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n        for (var r = Array(s), k = 0, i = 0; i < il; i++)\n            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n                r[k] = a[j];\n        return r;\n    };\n\n    __spreadArray = function (to, from, pack) {\n        if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n            if (ar || !(i in from)) {\n                if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n                ar[i] = from[i];\n            }\n        }\n        return to.concat(ar || Array.prototype.slice.call(from));\n    };\n\n    __await = function (v) {\n        return this instanceof __await ? (this.v = v, this) : new __await(v);\n    };\n\n    __asyncGenerator = function (thisArg, _arguments, generator) {\n        if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n        var g = generator.apply(thisArg, _arguments || []), i, q = [];\n        return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n        function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n        function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n        function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r);  }\n        function fulfill(value) { resume(\"next\", value); }\n        function reject(value) { resume(\"throw\", value); }\n        function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n    };\n\n    __asyncDelegator = function (o) {\n        var i, p;\n        return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n        function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n    };\n\n    __asyncValues = function (o) {\n        if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n        var m = o[Symbol.asyncIterator], i;\n        return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n        function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n        function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n    };\n\n    __makeTemplateObject = function (cooked, raw) {\n        if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n        return cooked;\n    };\n\n    var __setModuleDefault = Object.create ? (function(o, v) {\n        Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n    }) : function(o, v) {\n        o[\"default\"] = v;\n    };\n\n    __importStar = function (mod) {\n        if (mod && mod.__esModule) return mod;\n        var result = {};\n        if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n        __setModuleDefault(result, mod);\n        return result;\n    };\n\n    __importDefault = function (mod) {\n        return (mod && mod.__esModule) ? mod : { \"default\": mod };\n    };\n\n    __classPrivateFieldGet = function (receiver, state, kind, f) {\n        if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n        if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n        return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n    };\n\n    __classPrivateFieldSet = function (receiver, state, value, kind, f) {\n        if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n        if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n        if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n        return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n    };\n\n    __classPrivateFieldIn = function (state, receiver) {\n        if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n        return typeof state === \"function\" ? receiver === state : state.has(receiver);\n    };\n\n    __addDisposableResource = function (env, value, async) {\n        if (value !== null && value !== void 0) {\n            if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n            var dispose;\n            if (async) {\n                if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n                dispose = value[Symbol.asyncDispose];\n            }\n            if (dispose === void 0) {\n                if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n                dispose = value[Symbol.dispose];\n            }\n            if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n            env.stack.push({ value: value, dispose: dispose, async: async });\n        }\n        else if (async) {\n            env.stack.push({ async: true });\n        }\n        return value;\n    };\n\n    var _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n        var e = new Error(message);\n        return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n    };\n\n    __disposeResources = function (env) {\n        function fail(e) {\n            env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n            env.hasError = true;\n        }\n        function next() {\n            while (env.stack.length) {\n                var rec = env.stack.pop();\n                try {\n                    var result = rec.dispose && rec.dispose.call(rec.value);\n                    if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n                }\n                catch (e) {\n                    fail(e);\n                }\n            }\n            if (env.hasError) throw env.error;\n        }\n        return next();\n    };\n\n    exporter(\"__extends\", __extends);\n    exporter(\"__assign\", __assign);\n    exporter(\"__rest\", __rest);\n    exporter(\"__decorate\", __decorate);\n    exporter(\"__param\", __param);\n    exporter(\"__esDecorate\", __esDecorate);\n    exporter(\"__runInitializers\", __runInitializers);\n    exporter(\"__propKey\", __propKey);\n    exporter(\"__setFunctionName\", __setFunctionName);\n    exporter(\"__metadata\", __metadata);\n    exporter(\"__awaiter\", __awaiter);\n    exporter(\"__generator\", __generator);\n    exporter(\"__exportStar\", __exportStar);\n    exporter(\"__createBinding\", __createBinding);\n    exporter(\"__values\", __values);\n    exporter(\"__read\", __read);\n    exporter(\"__spread\", __spread);\n    exporter(\"__spreadArrays\", __spreadArrays);\n    exporter(\"__spreadArray\", __spreadArray);\n    exporter(\"__await\", __await);\n    exporter(\"__asyncGenerator\", __asyncGenerator);\n    exporter(\"__asyncDelegator\", __asyncDelegator);\n    exporter(\"__asyncValues\", __asyncValues);\n    exporter(\"__makeTemplateObject\", __makeTemplateObject);\n    exporter(\"__importStar\", __importStar);\n    exporter(\"__importDefault\", __importDefault);\n    exporter(\"__classPrivateFieldGet\", __classPrivateFieldGet);\n    exporter(\"__classPrivateFieldSet\", __classPrivateFieldSet);\n    exporter(\"__classPrivateFieldIn\", __classPrivateFieldIn);\n    exporter(\"__addDisposableResource\", __addDisposableResource);\n    exporter(\"__disposeResources\", __disposeResources);\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utility_types/MergeType.d.ts",
    "content": "/**\n * Merge a type union (of objects) into a single object type.\n *\n * See: https://dev.to/lucianbc/union-type-merging-in-typescript-9al\n *\n * Useful when working with a union type object as a \"collapsed\" bag of all possible properties (that are optional).\n * We use this for an AllAnimationOptions type.\n * */\nexport type MergeType<T extends object> = {\n  [k in CommonKeys<T>]: PickTypeOf<T, k>;\n} & {\n  [k in NonCommonKeys<T>]?: PickTypeOf<T, k>;\n};\n\n/**\n * Machinery necessary to implement the MergeType type.\n *\n * See: https://dev.to/lucianbc/union-type-merging-in-typescript-9al\n *\n */\nexport type CommonKeys<T extends object> = keyof T;\n\nexport type AllKeys<T> = T extends any ? keyof T : never;\n\nexport type Subtract<A, C> = A extends C ? never : A;\nexport type NonCommonKeys<T extends object> = Subtract<AllKeys<T>, CommonKeys<T>>;\n\nexport type PickType<T, K extends AllKeys<T>> = T extends { [k in K]?: any } ? T[K] : undefined;\n\nexport type PickTypeOf<T, K extends string | number | symbol> = K extends AllKeys<T> ? PickType<T, K> : never;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/AttributedTextBuilder.ts",
    "content": "import {\n  AttributedText,\n  AttributedTextAttributes,\n  AttributedTextChunk,\n  AttributedTextEntryType,\n  AttributedTextOnTap,\n  AttributedTextOnLayout,\n} from 'valdi_tsx/src/AttributedText';\nimport { AttributedTextInlineImageAttachment } from 'valdi_tsx/src/AttributedTextInlineImageAttachment';\nimport { LabelTextDecoration } from 'valdi_tsx/src/NativeTemplateElements';\nimport { AnyFunction } from './Callback';\n\nexport type { AttributedText };\n\n/**\n * Association of a string content and optional a set of attributes.\n */\nexport interface AttributedTextStyled {\n  content: string;\n  attributes?: AttributedTextAttributes;\n}\n\n/**\n * Builder for creating AttributedText.\n * The value returned by build() can be used as the value\n * of label elements.\n */\nexport class AttributedTextBuilder {\n  private components: AttributedTextChunk[] = [];\n\n  /**\n   * Append a string to the AttributedText.\n   */\n  appendText(text: string): AttributedTextBuilder {\n    this.appendEntry(AttributedTextEntryType.Content, text);\n    return this;\n  }\n\n  /**\n   * Convenience method to append a single string associated with a set of text attributes.\n   */\n  append(text: string, attributes?: AttributedTextAttributes): AttributedTextBuilder {\n    if (attributes) {\n      const popCount = this.pushStyle(attributes);\n\n      this.appendText(text);\n\n      this.popCount(popCount);\n    } else {\n      this.appendText(text);\n    }\n\n    return this;\n  }\n\n  /**\n   * Convenience method to append a single string associated with a set of text attributes.\n   */\n  appendStyled(styled: AttributedTextStyled): AttributedTextBuilder {\n    this.append(styled.content, styled.attributes);\n    return this;\n  }\n\n  /**\n   * Push the given font attributes, evaluate the callback, and pop all the evaluated attributes.\n   */\n  withStyle(attributes: AttributedTextAttributes, cb: (builder: AttributedTextBuilder) => void): AttributedTextBuilder {\n    const popCount = this.pushStyle(attributes);\n\n    cb(this);\n\n    this.popCount(popCount);\n    return this;\n  }\n\n  /**\n   * Push a Font on the Style stack, which will make all subsequent added strings\n   * use this font, until pop() is called\n   */\n  pushFont(font: string): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushFont, font);\n    return this;\n  }\n\n  /**\n   * Push a Color on the Style stack, which will make all subsequent added strings\n   * use this color, until pop() is called\n   */\n  pushColor(color: string): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushColor, color);\n    return this;\n  }\n\n  /**\n   * Push a TextDecoration on the Style stack, which will make all subsequent added strings\n   * use this color, until pop() is called\n   */\n  pushTextDecoration(textDecoration: LabelTextDecoration): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushTextDecoration, textDecoration);\n    return this;\n  }\n\n  /**\n   * Push an onTap on the Style stack, which will make all subsequent added strings\n   * be tappable.\n   */\n  pushOnTap(onTap: AttributedTextOnTap): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushOnTap, onTap);\n    return this;\n  }\n\n  /**\n   * Push an onLayout callback on the Style stack.\n   */\n  pushOnLayout(onLayout: AttributedTextOnLayout): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushOnLayout, onLayout);\n    return this;\n  }\n\n  /**\n   * Push an outline color on the Style stack.\n   */\n  pushOutlineColor(outlineColor: string): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushOutlineColor, outlineColor);\n    return this;\n  }\n\n  /**\n   * Push an outline width on the Style stack.\n   */\n  pushOutlineWidth(outlineWidth: number): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushOutlineWidth, outlineWidth);\n    return this;\n  }\n\n  /**\n   * Push an outer outline color on the Style stack.\n   */\n  pushOuterOutlineColor(outerOutlineColor: string): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushOuterOutlineColor, outerOutlineColor);\n    return this;\n  }\n\n  /**\n   * Push an outer outline width on the Style stack.\n   */\n  pushOuterOutlineWidth(outerOutlineWidth: number): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushOuterOutlineWidth, outerOutlineWidth);\n    return this;\n  }\n\n  /**\n   * Push an inline image attachment on the Style stack.\n   * Used for embedding images (like rendered LaTeX) inline with text.\n   */\n  pushInlineImage(attachment: AttributedTextInlineImageAttachment): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.PushInlineImage, attachment);\n    return this;\n  }\n\n  /**\n   * Append an inline image as an attributed text attachment.\n   * The image will be rendered inline with surrounding text using native text layout\n   * (NSTextAttachment on iOS, ReplacementSpan on Android).\n   *\n   * @param attachment The image attachment configuration including dimensions and image data\n   * @param placeholderChar Character to use as placeholder in the text (default: U+FFFC Object Replacement Character)\n   */\n  appendInlineImage(attachment: AttributedTextInlineImageAttachment, placeholderChar: string = '\\uFFFC'): AttributedTextBuilder {\n    this.pushInlineImage(attachment);\n    this.appendText(placeholderChar);\n    this.pop();\n    return this;\n  }\n\n  /**\n   * Pop the Style that is on the top of the Style stack. Every pushFont/pushColor/pushTextDecoration\n   * needs to have a matching pop() call.\n   */\n  pop(): AttributedTextBuilder {\n    this.components.push(AttributedTextEntryType.Pop);\n    return this;\n  }\n\n  private appendEntry(type: AttributedTextEntryType, value: string | AnyFunction | number) {\n    this.components.push(type, value);\n  }\n\n  private pushStyle(attributes: AttributedTextAttributes): number {\n    let popCount = 0;\n    if (attributes.color) {\n      this.pushColor(attributes.color);\n      popCount++;\n    }\n\n    if (attributes.font) {\n      this.pushFont(attributes.font);\n      popCount++;\n    }\n\n    if (attributes.textDecoration) {\n      this.pushTextDecoration(attributes.textDecoration);\n      popCount++;\n    }\n\n    if (attributes.onTap) {\n      this.pushOnTap(attributes.onTap);\n      popCount++;\n    }\n\n    if (attributes.onLayout) {\n      this.pushOnLayout(attributes.onLayout);\n      popCount++;\n    }\n\n    if (attributes.outlineColor) {\n      this.pushOutlineColor(attributes.outlineColor);\n      popCount++;\n    }\n\n    if (attributes.outlineWidth) {\n      this.pushOutlineWidth(attributes.outlineWidth);\n      popCount++;\n    }\n\n    if (attributes.outerOutlineColor) {\n      this.pushOuterOutlineColor(attributes.outerOutlineColor);\n      popCount++;\n    }\n\n    if (attributes.outerOutlineWidth) {\n      this.pushOuterOutlineWidth(attributes.outerOutlineWidth);\n      popCount++;\n    }\n\n    return popCount;\n  }\n\n  private popCount(count: number) {\n    for (let i = 0; i < count; i++) {\n      this.pop();\n    }\n  }\n\n  build(): AttributedText {\n    return [...this.components];\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/Buffer.ts",
    "content": "/**\n * A Buffer which extends automatically and can\n * store arbitary bytes.\n */\nexport class Buffer {\n  private array: DataView;\n  private pos: number;\n\n  constructor(initialCapacity: number) {\n    const buffer = new ArrayBuffer(initialCapacity);\n    this.array = new DataView(buffer);\n    this.pos = 0;\n  }\n\n  inner(): ArrayBuffer {\n    return this.array.buffer;\n  }\n\n  empty(): boolean {\n    return !this.pos;\n  }\n\n  /**\n   * Reset the position of the buffer, but does not\n   * clear it.\n   */\n  rewind() {\n    this.pos = 0;\n  }\n\n  size(): number {\n    return this.pos;\n  }\n\n  private ensureCapacity(desiredCapacity: number): DataView {\n    const array = this.array;\n    if (desiredCapacity < array.byteLength) {\n      return array;\n    }\n\n    const newBuffer = new ArrayBuffer(Math.max(array.byteLength * 2, desiredCapacity));\n    // Copy the buffers\n    new Uint8Array(newBuffer).set(new Uint8Array(array.buffer));\n\n    const newArray = new DataView(newBuffer);\n    this.array = newArray;\n    return newArray;\n  }\n\n  putUint32(value: number) {\n    const pos = this.pos;\n    const array = this.ensureCapacity(pos + 4);\n    array.setUint32(pos, value, true);\n    this.pos = pos + 4;\n  }\n\n  putUint32_2(value1: number, value2: number) {\n    const pos = this.pos;\n    const array = this.ensureCapacity(pos + 8);\n    array.setUint32(pos, value1, true);\n    array.setUint32(pos + 4, value2, true);\n    this.pos = pos + 8;\n  }\n\n  putUint32_3(value1: number, value2: number, value3: number) {\n    const pos = this.pos;\n    const array = this.ensureCapacity(pos + 12);\n    array.setUint32(pos, value1, true);\n    array.setUint32(pos + 4, value2, true);\n    array.setUint32(pos + 8, value3, true);\n    this.pos = pos + 12;\n  }\n\n  putUint32_4(value1: number, value2: number, value3: number, value4: number) {\n    const pos = this.pos;\n    const array = this.ensureCapacity(pos + 16);\n    array.setUint32(pos, value1, true);\n    array.setUint32(pos + 4, value2, true);\n    array.setUint32(pos + 8, value3, true);\n    array.setUint32(pos + 12, value4, true);\n    this.pos = pos + 16;\n  }\n\n  putUint32_5(value1: number, value2: number, value3: number, value4: number, value5: number) {\n    const pos = this.pos;\n    const array = this.ensureCapacity(pos + 20);\n    array.setUint32(pos, value1, true);\n    array.setUint32(pos + 4, value2, true);\n    array.setUint32(pos + 8, value3, true);\n    array.setUint32(pos + 12, value4, true);\n    array.setUint32(pos + 16, value5, true);\n    this.pos = pos + 20;\n  }\n\n  putFloat64(value: number) {\n    const pos = this.pos;\n    const array = this.ensureCapacity(pos + 8);\n    array.setFloat64(pos, value, true);\n    this.pos = pos + 8;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/Callback.ts",
    "content": "export const OWNER_KEY = Symbol();\nexport const CALLBACK_KEY = Symbol();\n\nexport type AnyFunction = (...args: any[]) => any;\n\n/**\n * A Callback is a function type that can be updated and\n * passed through view model properties or element attributes\n * without causing a component re-render or element update.\n * The callback instance stays stable across renders, only the\n * backing callable is updated.\n *\n * It is well suited to represent a callback on which the\n * component that receives it does not need to be re-rendered\n * whenever the backing callable changes, which is typical for\n * touch callbacks like `onTap` or `onDrag`.\n */\nexport interface Callback<F extends AnyFunction> {\n  (...params: Parameters<F>): ReturnType<F>;\n  [OWNER_KEY]: any;\n  [CALLBACK_KEY]: F;\n}\n\n/**\n * Creates a reusable Callback object from the given arrow function.\n * When called, the returned Callback will call the given arrow function.\n * When passed as a view model property or element attribute, the Callback\n * object will be merged with the previous Callback object for the property\n * or attribute if there was one, preventing re-render or element update.\n *\n * @param callback The function that should be called whenever the returned Callback\n * object is called.\n */\nexport function createReusableCallback<F extends AnyFunction>(callback: F): Callback<F> {\n  const fn: Callback<F> = function (this: any, ...args: Parameters<F>): ReturnType<F> {\n    return fn[CALLBACK_KEY].apply(this, args);\n  } as any;\n\n  fn[CALLBACK_KEY] = callback;\n\n  return fn;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/CallbackInternal.ts",
    "content": "import { AnyFunction, Callback, CALLBACK_KEY, OWNER_KEY } from './Callback';\n\n/**\n * Assign an owner to the given function if it is a callback object, or merge\n * the callback objects if both the given value and previous value are\n * callback objects with the same owner. The owner is an opaque instance\n * that represents who emitted the callback. Only the owner can mutate\n * its callback object.\n *\n * This is a private function used by the framework and shouldn't be used\n * by consumers.\n *\n * @param owner\n * @param previousValue\n * @param newValue\n */\nexport function tryReuseCallback(\n  owner: any,\n  previousValue: any,\n  newValue: ((...params: any[]) => void) | Callback<AnyFunction> | undefined,\n): ((...params: any[]) => void) | undefined {\n  if (!newValue) {\n    return undefined;\n  }\n\n  const newCallback = newValue as Callback<AnyFunction>;\n  if (!newCallback[CALLBACK_KEY]) {\n    // Not a Callback object\n    return newValue;\n  }\n\n  if (newCallback[OWNER_KEY]) {\n    // The callback already has an owner assigned\n    return newCallback;\n  }\n\n  if (previousValue instanceof Function) {\n    const previousCallback = previousValue as Callback<AnyFunction>;\n    if (previousCallback[OWNER_KEY] === owner) {\n      // If owner match, we can update the callback directly\n      previousCallback[CALLBACK_KEY] = newCallback[CALLBACK_KEY];\n      return previousCallback;\n    }\n  }\n\n  newCallback[OWNER_KEY] = owner;\n  return newCallback;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/ClassNames.ts",
    "content": "const hasOwn = {}.hasOwnProperty;\n\n/**\n * classnames takes a list of arguments and constructs a class name string.\n * Arguments may be strings, numbers, arrays or objects. Strings and numbers\n * are applied directly, arrays are recursively called per item, and objects\n * have their keys applied as classnames only if the value evalutes to true.\n *\n * e.g.,\n * import cx from 'common/src/classnames'\n * class=\"{{ cx('button', { 'enabled': viewModel.enabled }) }}\" results in 'button enabled'\n * if viewModel.enabled is true.\n */\nexport function classNames(...args: any[]): string {\n  const classes: string[] = [];\n  for (const arg of args) {\n    if (!arg) {\n      continue;\n    }\n    const type = typeof arg;\n    if (type === 'string' || type === 'number') {\n      classes.push(arg);\n    } else if (Array.isArray(arg) && arg.length) {\n      // eslint-disable-next-line prefer-spread\n      const inner = classNames.apply(null, arg);\n      if (inner) {\n        classes.push(inner);\n      }\n    } else if (type === 'object') {\n      for (const key in arg) {\n        if (hasOwn.call(arg, key) && arg[key]) {\n          classes.push(key);\n        }\n      }\n    }\n  }\n  return classes.join(' ');\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/CompilerError.ts",
    "content": "export class CompilerError extends Error {}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/ComponentUtils.ts",
    "content": "import { ElementRefs, LegacyVueComponent } from 'valdi_core/src/Valdi';\nimport { ComponentConstructor, IComponent } from 'valdi_core/src/IComponent';\n\nexport interface KeyedItem<T> {\n  readonly key: string;\n  readonly item: T;\n}\n\nfunction doGetChildComponentsOfType<T extends IComponent>(\n  component: IComponent,\n  clazz: ComponentConstructor<T>,\n  recursive: boolean,\n  out: T[],\n): void {\n  const children = component.renderer.getComponentChildren(component);\n\n  for (const child of children) {\n    if (child instanceof clazz) {\n      out.push(child);\n    }\n  }\n\n  if (recursive) {\n    for (const child of children) {\n      doGetChildComponentsOfType(child, clazz, recursive, out);\n    }\n  }\n}\n\n/**\n * Helper function for safely getting a child component by its id.\n */\nexport function getChildComponent<T extends IComponent>(\n  component: LegacyVueComponent,\n  elementId: string,\n): T | undefined {\n  return component.elementRefs[elementId].single()?.emittingComponent as T;\n}\n\n/**\n * Returns a list of keyed components containing each component in a for-each.\n */\nexport function getForEachComponents<ComponentT extends IComponent, ElementT = any>(\n  elementRefs: ElementRefs<ElementT>,\n  componentClass: ComponentConstructor<ComponentT>,\n  customId: string,\n): KeyedItem<ComponentT>[] {\n  const keyedComponents: KeyedItem<ComponentT>[] = [];\n\n  for (const element of elementRefs[customId].all()) {\n    if (element.emittingComponent instanceof componentClass) {\n      keyedComponents.push({\n        key: element.renderer.getComponentKey(element.emittingComponent),\n        item: element.emittingComponent,\n      });\n    }\n  }\n  return keyedComponents;\n}\n\n/**\n * Returns a list of child components of the given type, optionally recursive.\n */\nexport function getChildComponentsOfType<T extends IComponent>(\n  component: IComponent,\n  clazz: ComponentConstructor<T>,\n  recursive = false,\n): T[] {\n  const components: T[] = [];\n  doGetChildComponentsOfType(component, clazz, recursive, components);\n  return components;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/EditTextUtils.ts",
    "content": "import { EditTextEvent } from 'valdi_tsx/src/NativeTemplateElements';\n\nexport namespace EditTextUtils {\n  /**\n   * Create a new EditTextEvent with a modified text content\n   * and make the best-effort to update to the selection\n   */\n  export function makeUpdatedEvent(from: EditTextEvent, newText: string): EditTextEvent {\n    const originalText = from.text;\n    const updatedText = newText;\n\n    let updatedSelectionStart = from.selectionStart;\n    let updatedSelectionEnd = from.selectionEnd;\n\n    const diffChange = updatedText.length - originalText.length;\n\n    // TODO - this is very simple diffing, should probably use a Meiyer algorithm here\n    if (diffChange !== 0) {\n      let firstChange = 0;\n      for (let i = 0; i < originalText.length; i++) {\n        if (originalText[i] !== updatedText[i]) {\n          firstChange = i;\n          break;\n        }\n      }\n\n      if (firstChange <= updatedSelectionStart) {\n        updatedSelectionStart += diffChange;\n      }\n\n      if (firstChange <= updatedSelectionEnd) {\n        updatedSelectionEnd += diffChange;\n      }\n    }\n\n    return {\n      text: updatedText,\n      selectionStart: updatedSelectionStart,\n      selectionEnd: updatedSelectionEnd,\n    };\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/ErrorUtils.ts",
    "content": "/**\n * Returns an Error object from an opaque error object.\n * @param error\n */\nexport function toError(error: any): Error {\n  if (error instanceof Error) {\n    return error;\n  }\n  if (error.message) {\n    return new Error(error.message);\n  }\n  if (typeof error === 'string') {\n    return new Error(error);\n  }\n  if (typeof error === 'object') {\n    return new Error(JSON.stringify(error));\n  }\n  return new Error(error);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/FunctionUtils.ts",
    "content": "import { ValdiRuntime } from '../ValdiRuntime';\nimport { AnyFunction } from './Callback';\n\ndeclare const runtime: ValdiRuntime;\n\nexport const enum CallbackOptions {\n  /**\n   * Mark that the function has no specific export behavior.\n   */\n  None = 0,\n  /**\n   * Mark that when the exported function is called on the main thread, it should\n   * lock the JS thread until completion\n   */\n  SyncWithMainThread = 1 << 0,\n  /**\n   * Mark that when the exported function is called after its associated Valdi\n   * Context is destroyed, its call should be ignored instead of emitting an error.\n   */\n  Interruptible = 1 << 1,\n  /**\n   * Mark that when the exported is called once, its underlying function reference\n   * should be torn down, which will prevent the function to be called again, as well\n   * as help clearing out memory earlier.\n   */\n  SingleCall = 1 << 2,\n}\n\n/**\n * Returns a new configured callback with the given options. The options will impact\n * how the callback will be exported when it is passed to native or platform code.\n * @param options The list of options to set on the callback provided as an union.\n * @param fn The callback to configure\n * @returns A new callback configured with the given options.\n */\nexport function makeConfiguredCallback<F extends AnyFunction>(options: CallbackOptions, fn: F): F {\n  if (options === CallbackOptions.None) {\n    return fn;\n  }\n\n  const cb = ((...args: unknown[]): unknown => {\n    return fn(...args);\n  }) as F;\n  runtime.configureCallback(options, cb);\n  return cb;\n}\n\n/**\n * Mark a function as required to run on the main thread meaning that:\n * - it will pause all other javascript and runtime logic until finished\n */\nexport function makeMainThreadCallback<F extends AnyFunction>(fn: F): F {\n  return makeConfiguredCallback(CallbackOptions.SyncWithMainThread, fn);\n}\n\n/**\n * Mark a function as interruptible meaning that:\n * - if the valdi context is destroyed\n * - it will not be called and won't trigger an error\n */\nexport function makeInterruptibleCallback<F extends AnyFunction>(fn: F): F {\n  return makeConfiguredCallback(CallbackOptions.Interruptible, fn);\n}\n\n/**\n * Mark a function that can be called only once, and which will not emit an error\n * if it called after the associated Valdi Context was destroyed.\n */\nexport function makeSingleCallInterruptibleCallback<F extends AnyFunction>(fn: F): F {\n  return makeConfiguredCallback(CallbackOptions.SingleCall | CallbackOptions.Interruptible, fn);\n}\n\n/**\n * Helper function to make a call optionally interruptible\n * @see makeInterruptibleCallback\n */\nexport function makeInterruptibleCallbackOptionally<F extends AnyFunction>(interruptible: boolean, fn: F): F {\n  if (interruptible) {\n    return makeInterruptibleCallback(fn);\n  } else {\n    return fn;\n  }\n}\n\n/**\n * Mark a function that it can be called only once.\n * When the returned function is passed to native or platform code,\n * and later called by native or platform code, the reference of the\n * given TypeScript function will be torn down after the call. This can\n * help clearing out memory earlier.\n */\nexport function makeSingleCallCallback<F extends AnyFunction>(fn: F): F {\n  return makeConfiguredCallback(CallbackOptions.SingleCall, fn);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/GeometricPathBuilder.ts",
    "content": "import { GeometricPath } from 'valdi_tsx/src/GeometricPath';\n\nexport type { GeometricPath };\n\nconst enum GeometricPathComponent {\n  Move = 1,\n  Line = 2,\n  Quad = 3,\n  Cubic = 4,\n  RoundRect = 5,\n  Arc = 6,\n  Close = 7,\n}\n\n/**\n * Defines how the GeometricPath should scale relative to\n * the container view where it is being used.\n */\nexport const enum GeometricPathScaleType {\n  /**\n   * The path will scale such that the path will entirely\n   * fill the bounds of the container without expanding beyond it.\n   * Aspect ratio of the path will not be preserved.\n   * This is the default option.\n   */\n  Fill = 1,\n\n  /**\n   * The path will scale such that the path will fit within the bounds of the\n   * container. Aspect ratio of the path will be preserved.\n   */\n  Contain = 2,\n\n  /**\n   * The path will scale such that the path entirely fill the bounds of\n   * the container, with sides potentially expanding beyond it.\n   * Aspect ratio of the path will be preserved.\n   */\n  Cover = 3,\n\n  /**\n   * The path will not be scaled relative to the container. In this mode,\n   * the extentWidth and extentHeight will be treated as the absolute size\n   * of the path, and the path will be centered in the container.\n   */\n  None = 4,\n}\n\n/**\n * A GeometricPathBuilder is a utility class for building\n * GeometricPath objects that can be provided to the \"shape\" elements.\n * A path builder is created with an extent width and height, which represent\n * the coordinate space from which all the path operation values derive from.\n * Whenever the path is used into a container that has a different size than the\n * path extent, the path operations are scaled by applying a ratio between\n * the extent and the actual container size.\n */\nexport class GeometricPathBuilder {\n  private data: number[] = [];\n\n  constructor(extentWidth: number, extentHeight: number, scaleType?: GeometricPathScaleType) {\n    this.data.push(extentWidth, extentHeight, scaleType ?? GeometricPathScaleType.Fill);\n  }\n\n  /**\n   * Move the path position to given x and y.\n   */\n  moveTo(x: number, y: number): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Move, x, y);\n    return this;\n  }\n\n  /**\n   * Add a line from the current path position to the given x and y\n   */\n  lineTo(x: number, y: number): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Line, x, y);\n    return this;\n  }\n\n  /**\n   * Add a rect at the given x and y with the given width and height.\n   */\n  rectTo(x: number, y: number, width: number, height: number): GeometricPathBuilder {\n    return this.roundRectTo(x, y, width, height, 0, 0);\n  }\n\n  /**\n   * Add a round rect at the given x and y with the given width and height, with\n   * the rect corners rounded using radiusX and radiusY.\n   */\n  roundRectTo(\n    x: number,\n    y: number,\n    width: number,\n    height: number,\n    radiusX: number,\n    radiusY: number,\n  ): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.RoundRect, x, y, width, height, radiusX, radiusY);\n    return this;\n  }\n\n  /**\n   * Add a arc at the given centerX and centerY with the given radius, starting from\n   * the given startAngle and sweeping by the given sweepAngle.\n   * A positive sweepAngle extends the arc clockwise, a negative angle extends\n   * it counterclockwise.\n   */\n  arcTo(\n    centerX: number,\n    centerY: number,\n    radius: number,\n    startAngle: number,\n    sweepAngle: number,\n  ): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Arc, centerX, centerY, radius, startAngle, sweepAngle);\n    return this;\n  }\n\n  /**\n   * Add an oval at the given x and y with the given width and height.\n   */\n  ovalTo(x: number, y: number, width: number, height: number): GeometricPathBuilder {\n    return this.roundRectTo(x, y, width, height, width / 2.0, height / 2.0);\n  }\n\n  /**\n   * Add a cubic curve from the current path position to the given x and y,\n   * using controlX1 and controlY1 as the first control point of the curve,\n   * and controlX2 and controlY2 as the second control point of the curve.\n   */\n  cubicTo(\n    x: number,\n    y: number,\n    controlX1: number,\n    controlY1: number,\n    controlX2: number,\n    controlY2: number,\n  ): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Cubic, x, y, controlX1, controlY1, controlX2, controlY2);\n    return this;\n  }\n\n  /**\n   * Add a quad curve from the current path position to the given x and y,\n   * using controlX and controlY as the control point.\n   */\n  quadTo(x: number, y: number, controlX: number, controlY: number): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Quad, x, y, controlX, controlY);\n    return this;\n  }\n\n  /**\n   * Close the current path contour, connecting a line between the first point and the last point.\n   */\n  close(): GeometricPathBuilder {\n    this.data.push(GeometricPathComponent.Close);\n    return this;\n  }\n\n  /**\n   * Build and return a GeometricPath object containing the path instructions.\n   * The object can be then passed as to the \"path\" property of \"shape\" element.\n   */\n  build(): GeometricPath {\n    return Float64Array.from(this.data);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/IdentifyableObject.ts",
    "content": "export interface IdentifyableObject {\n  $objectId: number;\n}\n\nlet idSequence = 0;\n\nexport function setObjectId(object: any) {\n  if (!object) {\n    return;\n  }\n\n  (object as IdentifyableObject).$objectId = ++idSequence;\n}\n\nexport function getObjectId(object: any): number | undefined {\n  if (!object) {\n    return undefined;\n  }\n\n  return (object as IdentifyableObject).$objectId;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/ImageFilter.ts",
    "content": "import { ImageFilter } from 'valdi_tsx/src/ImageFilter';\n\nexport type { ImageFilter };\n\nconst enum FilterType {\n  Blur = 1,\n  ColorMatrix = 2,\n}\n\nfunction clampRatio(ratio: number): number {\n  return Math.min(Math.max(ratio, 0), 1.0);\n}\n\nexport namespace ImageFilters {\n  /**\n   * Applies a blur filter to the image\n   * @param radius\n   * @returns\n   */\n  export function blur(radius: number): ImageFilter {\n    return [FilterType.Blur, radius];\n  }\n\n  /**\n   * Applies a color matrix filter to the image\n   * @returns\n   */\n  export function colorMatrix(\n    red1: number,\n    red2: number,\n    red3: number,\n    red4: number,\n    redBias: number,\n    green1: number,\n    green2: number,\n    green3: number,\n    green4: number,\n    greenBias: number,\n    blue1: number,\n    blue2: number,\n    blue3: number,\n    blue4: number,\n    blueBias: number,\n    alpha1: number,\n    alpha2: number,\n    alpha3: number,\n    alpha4: number,\n    alphaBias: number,\n  ): ImageFilter {\n    return [\n      FilterType.ColorMatrix,\n      red1,\n      red2,\n      red3,\n      red4,\n      redBias,\n      green1,\n      green2,\n      green3,\n      green4,\n      greenBias,\n      blue1,\n      blue2,\n      blue3,\n      blue4,\n      blueBias,\n      alpha1,\n      alpha2,\n      alpha3,\n      alpha4,\n      alphaBias,\n    ];\n  }\n\n  /**\n   * Invert the image colors\n   */\n  export function invert(): ImageFilter {\n    return colorMatrix(-1, 0, 0, 0, 1, 0, -1, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, 1, 0);\n  }\n\n  /**\n   * Applies a grayscale filter to the image\n   * @param intensity the intensity of the grayscale effect between 0 to 1\n   * @returns\n   */\n  export function grayscale(intensity: number = 1): ImageFilter {\n    const cv = 1.0 - clampRatio(intensity);\n\n    return colorMatrix(\n      0.2126 + 0.7874 * cv,\n      0.7152 - 0.7152 * cv,\n      0.0722 - 0.0722 * cv,\n      0,\n      0,\n      0.2126 - 0.2126 * cv,\n      0.7152 + 0.2848 * cv,\n      0.0722 - 0.0722 * cv,\n      0,\n      0,\n      0.2126 - 0.2126 * cv,\n      0.7152 - 0.7152 * cv,\n      0.0722 + 0.9278 * cv,\n      0,\n      0,\n      0,\n      0,\n      0,\n      1,\n      0,\n    );\n  }\n\n  /**\n   * Applies a sepia filter to the image\n   * @param intensity the intensity of the sepia effect between 0 to 1\n   * @returns\n   */\n  export function sepia(intensity: number = 1) {\n    const cv = 1.0 - clampRatio(intensity);\n\n    return colorMatrix(\n      0.393 + 0.607 * cv,\n      0.769 - 0.769 * cv,\n      0.189 - 0.189 * cv,\n      0,\n      0,\n      0.349 - 0.349 * cv,\n      0.686 + 0.314 * cv,\n      0.168 - 0.168 * cv,\n      0,\n      0,\n      0.272 - 0.272 * cv,\n      0.534 - 0.534 * cv,\n      0.131 + 0.869 * cv,\n      0,\n      0,\n      0,\n      0,\n      0,\n      1,\n      0,\n    );\n  }\n\n  /**\n   * Adjusts the brightness of the image\n   * @param value\n   * @returns\n   */\n  export function brightness(value: number) {\n    return colorMatrix(value, 0, 0, 0, 0, 0, value, 0, 0, 0, 0, 0, value, 0, 0, 0, 0, 0, 1, 0);\n  }\n\n  /**\n   * Adjusts the contrast of the image\n   * @param value\n   * @returns\n   */\n  export function contrast(value: number) {\n    const n = 0.5 * (1 - value);\n\n    return colorMatrix(value, 0, 0, 0, n, 0, value, 0, 0, n, 0, 0, value, 0, n, 0, 0, 0, 1, 0);\n  }\n\n  /**\n   * Compose a list of filters into a new filter\n   * @param filters\n   * @returns a new filter containing all the given filters\n   */\n  export function compose(...filters: ImageFilter[]): ImageFilter {\n    const out: ImageFilter = [];\n    for (const filter of filters) {\n      out.push(...filter);\n    }\n    return out;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/KeepAliveCallback.ts",
    "content": "import { AnyFunction } from './Callback';\n\nexport type KeepAlive = number;\nexport function beginKeepAlive(): KeepAlive {\n  // Janky workaround, would require a runtime change to make this work better.\n  return setInterval(() => {}, 100000);\n}\n\nexport function endKeepAlive(keepAlive: KeepAlive) {\n  clearInterval(keepAlive);\n}\n\n/**\n * Make a callback that will keep the runtime alive until the callback is called.\n * This can be used in particular for CLI apps which perform asynchronous work.\n * The return value of makeKeepAliveCallback() can be passed to the async services\n * so that the main JS task queue doesn't get empty, which would make the CLI exit.\n */\nexport function makeKeepAliveCallback<F extends AnyFunction>(callback: F): F {\n  let keepAlive = beginKeepAlive();\n\n  const fn: F = function (this: any, ...args: Parameters<F>): ReturnType<F> {\n    endKeepAlive(keepAlive);\n    return callback.apply(this, args);\n  } as F;\n\n  return fn;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/LazyPromise.ts",
    "content": "export interface ILazyPromise<T> {\n  /**\n   * Returns the cached result of the promise if available,\n   * or undefined otherwise.\n   */\n  value: T | undefined;\n\n  /**\n   * Returns a promise that will resolve the underlying value.\n   * This will trigger the load if the promise was not loaded yet.\n   */\n  promise: Promise<T>;\n\n  then<F>(cb: (value: T) => F): ILazyPromise<F>;\n}\n\nclass LazyPromise<T> implements ILazyPromise<T> {\n  value: T | undefined = undefined;\n\n  get promise(): Promise<T> {\n    const value = this.value;\n    if (value !== undefined) {\n      return Promise.resolve(value);\n    }\n\n    return this.importFn!().then(v => {\n      this.value = v;\n      this.importFn = undefined;\n      return v;\n    });\n  }\n\n  private importFn: (() => Promise<T>) | undefined;\n\n  constructor(importFn: () => Promise<T>) {\n    this.importFn = importFn;\n  }\n\n  then<F>(cb: (value: T) => F): ILazyPromise<F> {\n    return new LazyPromise<F>(() => this.promise.then(cb));\n  }\n}\n\n/**\n * Create a Lazy Promise from a promise provider.\n * A lazy promise will only be executed when the underlying promise\n * is retrieved from the returned ILazyPromise instance.\n */\nexport function lazyPromise<T>(promiseFn: () => Promise<T>): ILazyPromise<T> {\n  return new LazyPromise(promiseFn);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/NumberUtils.ts",
    "content": "import { getModuleLoader } from '../ModuleLoaderGlobal';\n\n// We rely on a native number formatter to be set in Android to get around `toLocaleString()` being unavailable in quickjs.\nlet nativeNumberFormatter: ((value: number, fractionalDigits: number) => string) | undefined = undefined;\n\ntry {\n  nativeNumberFormatter = getModuleLoader().load('NumberFormatting').formatNumber;\n} catch (e: any) {\n  // no-op; this module is only present on Android\n}\n\n// We rely on a native currency formatter to be set in Android to get around `Intl.NumberFormat` being unavailable in quickjs.\nlet nativeNumberWithCurrencyFormatter: ((value: number, currencyCode: string, minimumFractionDigits?: number, maximumFractionDigits?: number, localeIdentifier?: string) => string) | undefined = undefined;\n\ntry {\n  nativeNumberWithCurrencyFormatter = getModuleLoader().load('NumberFormatting').formatNumberWithCurrency;\n} catch (e: any) {\n  // no-op; this module is only present on Android\n}\n\nexport function formatNumber(value: number, numFractionalDigits: number = -1): string {\n  if (nativeNumberFormatter) {\n    return nativeNumberFormatter(value, numFractionalDigits);\n  }\n\n  let options: any;\n  if (numFractionalDigits !== -1) {\n    options = {\n      minimumFractionDigits: numFractionalDigits,\n      maximumFractionDigits: numFractionalDigits,\n    };\n  }\n\n  return value.toLocaleString(undefined, options);\n}\n\n/**\n * Sanitizes a locale identifier to be compatible with Intl.NumberFormat.\n *\n * Handles various input formats:\n * - [language] (e.g., \"en\")\n * - [language]_[region] (e.g., \"en_US\")\n * - [language]-[script] (e.g., \"zh-Hans\")\n * - [language]-[script]_[region] (e.g., \"zh-Hans_HK\")\n * - Any of the above with @[extension] suffix (e.g., \"en_GB@rg=US\")\n *\n * Returns a BCP 47 compliant locale string (uses hyphens as separators).\n */\nfunction sanitizeLocaleIdentifier(localeIdentifier: string): string {\n  // Remove custom extensions (e.g., \"@rg=US\")\n  const withoutExtension = localeIdentifier.split('@')[0];\n\n  // Convert underscores to hyphens for BCP 47 compatibility\n  // Apple uses underscore before region (e.g., \"en_US\"), but Intl expects hyphens (\"en-US\")\n  return withoutExtension.replace(/_/g, '-');\n}\n\nexport function formatNumberWithCurrency(\n  value: number,\n  currencyCode: string,\n  options?: { minimumFractionDigits?: number; maximumFractionDigits?: number; localeIdentifier?: string },\n): string {\n  if (nativeNumberWithCurrencyFormatter) {\n    return nativeNumberWithCurrencyFormatter(value, currencyCode, options?.minimumFractionDigits, options?.maximumFractionDigits, options?.localeIdentifier);\n  }\n\n  // Use the provided localeIdentifier if available, otherwise fall back to undefined (device locale)\n  // This ensures currency formatting uses the correct locale from the price data.\n  const locale = options?.localeIdentifier ? sanitizeLocaleIdentifier(options.localeIdentifier) : undefined;\n\n  return new Intl.NumberFormat(locale, {\n    style: 'currency',\n    currency: currencyCode,\n    minimumFractionDigits: options?.minimumFractionDigits,\n    maximumFractionDigits: options?.maximumFractionDigits,\n  }).format(value);\n}\n\n/**\n * Convenience function to have javascript numbers converted to Long in native\n */\nexport function serializeLong(value: number | Long): Long {\n  if (typeof value === 'number') {\n    return Long.fromNumber(value);\n  }\n  return value;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/OnIdle.ts",
    "content": "import { ValdiRuntime } from '../ValdiRuntime';\nimport { setTimeoutInterruptible } from '../SetTimeout';\nimport { makeInterruptibleCallback } from './FunctionUtils';\n\ndeclare const runtime: ValdiRuntime;\n\n/**\n * Call the given function when the main thread and the js thread\n * have both finished processing any tasks they may have enqueued.\n * Note: will not be called if the component's context has been destroyed\n * @param cb\n */\nexport function onIdleInterruptible(cb: () => void) {\n  setTimeoutInterruptible(() => {\n    runtime.onMainThreadIdle(makeInterruptibleCallback(cb));\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/Optional.ts",
    "content": "\n/**\n * @ExportModel\n * Wrapper to use with Observables to avoid emitting / handling null values.\n */\nexport interface Optional<T> {\n\treadonly data: T | undefined;\n};\n\nexport const EMPTY_OPTIONAL: Readonly<Optional<any>> = { data: undefined };"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/PartialUtils.ts",
    "content": "/**\n * Merges a partial into the given object.\n * Returns undefined if the partial did not\n * cause into to be mutated, otherwise returns\n * a new object with the partial merged.\n */\nexport function mergePartial<T>(partial: Partial<T>, into: T | undefined): T | undefined {\n  if (!into) {\n    return <T>{ ...partial };\n  }\n  let objectCopy: T | undefined;\n  for (const key in partial) {\n    const newValue = partial[key];\n    const oldValue = into[key];\n\n    if (oldValue !== newValue) {\n      if (!objectCopy) {\n        objectCopy = { ...into };\n      }\n      objectCopy[key] = newValue!;\n    }\n  }\n\n  return objectCopy;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/PromiseUtils.ts",
    "content": "import { setTimeoutInterruptible } from '../SetTimeout';\n\nexport type PromiseLikeFunction<T> = (cb: (data?: T, err?: any) => void) => void;\n\n/**\n * Makes a Promise from a PromiseLikeFunction\n * @param fn\n */\nexport function promisify<T>(fn: PromiseLikeFunction<T>): Promise<T> {\n  return new Promise((resolve, reject) => {\n    fn((data, err) => {\n      if (data) {\n        resolve(data);\n      } else if (err) {\n        reject(err);\n      } else {\n        reject(new Error('No data returned'));\n      }\n    });\n  });\n}\n\n/**\n * Converts a synchronous producer of a value to a Promise, taking\n * in account failures in case of thrown exceptions.\n * @param fn\n */\nexport function promisifyProducer<T>(fn: () => T): Promise<T> {\n  return new Promise((resolve, reject) => {\n    try {\n      const result = fn();\n      resolve(result);\n    } catch (err: any) {\n      reject(err);\n    }\n  });\n}\n\n/**\n * Converts a setTimeout into a promise, resolving it after the given\n * provided delay in milliseconds.\n */\nexport function wait(delayMs: number): Promise<void> {\n  return new Promise(resolve => {\n    // eslint-disable-next-line @snap/valdi/assign-timer-id\n    setTimeout(() => {\n      resolve();\n    }, delayMs);\n  });\n}\n\n/**\n * Converts a setTimeoutInterruptible into a promise, resolving it after the given\n * provided delay in milliseconds.\n */\nexport function waitInterruptible(delayMs: number): Promise<void> {\n  return new Promise(resolve => {\n    // eslint-disable-next-line @snap/valdi/assign-timer-id\n    setTimeoutInterruptible(() => {\n      resolve();\n    }, delayMs);\n  });\n}\n\n/**\n * Ensures that only one promise is performing at once.\n */\nexport class PromiseDeduper<T> {\n  private promise: Promise<T> | null = null;\n\n  get isPerforming(): boolean {\n    return this.promise !== null;\n  }\n\n  /**\n   * Returns the in-flight promise if possible, otherwise asks the provider for a new\n   * promise to consider in-flight and returns it.\n   */\n  performIfNeeded(provider: () => Promise<T>): Promise<T> {\n    if (!this.promise) {\n      this.promise = provider()\n        .then(result => {\n          this.promise = null;\n          return result;\n        })\n        .catch(err => {\n          this.promise = null;\n          return Promise.reject(err);\n        });\n    }\n    return this.promise;\n  }\n}\n\n/**\n * Caches and returns a promise (in-flight and resolved) until invalidated.\n */\nexport class PromiseCache<T> {\n  private promise: Promise<T> | null = null;\n\n  invalidate(): void {\n    this.promise = null;\n  }\n\n  performIfNeeded(provider: () => Promise<T>): Promise<T> {\n    if (!this.promise) {\n      this.promise = provider();\n    }\n    return this.promise;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/PropertyList.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { PropertyList } from 'valdi_tsx/src/PropertyList';\n\nexport type { PropertyList };\n\nexport function enumeratePropertyList(\n  propertyList: PropertyList,\n  enumerator: (name: string, value: any) => void,\n): void {\n  if (Array.isArray(propertyList)) {\n    const length = propertyList.length;\n    for (let i = 0; i + 1 < length; ) {\n      const key = propertyList[i++];\n      const value = propertyList[i++];\n      enumerator(key as string, value);\n    }\n  } else {\n    for (const key in propertyList) {\n      const value = propertyList[key];\n      enumerator(key, value);\n    }\n  }\n}\n\nexport function removeProperty(propertyList: PropertyList, property: string): any | undefined {\n  if (Array.isArray(propertyList)) {\n    const index = propertyList.indexOf(property);\n    if (index < 0 || index + 1 == propertyList.length) {\n      return undefined;\n    }\n    const value = propertyList[index + 1];\n    propertyList.splice(index, 2);\n    return value;\n  } else {\n    const value = propertyList[property];\n    delete propertyList[property];\n    return value;\n  }\n}\n\nexport function hasProperty(propertyList: PropertyList, property: string): boolean {\n  if (Array.isArray(propertyList)) {\n    // Array form alternates [key, value, key, value]. Only check keys.\n    const length = propertyList.length;\n    for (let i = 0; i + 1 < length; i += 2) {\n      if (propertyList[i] === property) return true;\n    }\n    return false;\n  }\n  return property in propertyList;\n}\n\nexport function propertyListToObject(propertyList: PropertyList): StringMap<any> {\n  if (!Array.isArray(propertyList)) {\n    return propertyList;\n  }\n\n  const out: StringMap<any> = {};\n  const length = propertyList.length;\n  for (let i = 0; i + 1 < length; ) {\n    const key = propertyList[i++];\n    const value = propertyList[i++];\n    out[key as string] = value;\n  }\n\n  return out;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/PropertyListTest.ts",
    "content": "import 'jasmine/src/jasmine';\nimport { hasProperty } from './PropertyList';\n\ndescribe('PropertyList', () => {\n  it('hasProperty only checks keys for array property lists', () => {\n    const list = ['firstKey', 'targetProperty', 'secondKey', 'secondValue'];\n    expect(hasProperty(list, 'targetProperty')).toBeFalse();\n  });\n\n  it('hasProperty returns true when key exists', () => {\n    const list = ['firstKey', 'firstValue', 'targetProperty', 456];\n    expect(hasProperty(list, 'targetProperty')).toBeTrue();\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/RenderedElementUtils.ts",
    "content": "import { ElementFrame } from 'valdi_tsx/src/Geometry';\nimport { Point, Size } from '../Geometry';\nimport { IRenderedElement } from '../IRenderedElement';\n\nexport namespace RenderedElementUtils {\n  /**\n   * Compute a relative position within the element tree by recursively looking through the parents\n   */\n  export function relativePositionTo(parent: IRenderedElement, child: IRenderedElement): Point | undefined {\n    let current: IRenderedElement | undefined = child;\n    const position = { x: 0, y: 0 };\n    while (current) {\n      if (current == parent) {\n        return position;\n      }\n      const contentOffsetX = current.getAttribute('contentOffsetX') ?? 0;\n      const contentOffsetY = current.getAttribute('contentOffsetY') ?? 0;\n      const translationX = current.getAttribute('translationX') ?? 0;\n      const translationY = current.getAttribute('translationY') ?? 0;\n      position.x += current.frame.x - contentOffsetX + translationX;\n      position.y += current.frame.y - contentOffsetY + translationY;\n      current = current.parent;\n    }\n    return undefined;\n  }\n  /**\n   * Check if a relative position is within the bounds of a frame\n   */\n  export function frameContainsPosition(frame: ElementFrame, position: Point): boolean {\n    if (position.x > frame.width || position.y > frame.height) {\n      return false;\n    }\n    if (position.x < 0 || position.y < 0) {\n      return false;\n    }\n    return true;\n  }\n  /**\n   * Extract the origin of an element frame\n   */\n  export function framePosition(frame: ElementFrame): Point {\n    return frame;\n  }\n  /**\n   * Extract the size of an element frame\n   */\n  export function frameSize(frame: ElementFrame): Size {\n    return frame;\n  }\n\n  /**\n   * Get the root element of the tree by walking up the parent chain.\n   * Returns undefined if the element is undefined.\n   */\n  export function rootElement(element: IRenderedElement | undefined): IRenderedElement | undefined {\n    let current = element;\n    while (current?.parent) {\n      current = current.parent;\n    }\n    return current;\n  }\n\n  /**\n   * Get the nearest ancestor with a valid (non-zero) frame width by walking up the parent chain.\n   * This is useful when the actual root element may have a zero-width frame.\n   * Returns undefined if no element with a valid frame width is found.\n   */\n  export function rootElementWithFrame(element: IRenderedElement | undefined): IRenderedElement | undefined {\n    let current = element;\n    let lastWithValidWidth: IRenderedElement | undefined;\n\n    while (current) {\n      if (current.frame?.width) {\n        lastWithValidWidth = current;\n      }\n      if (!current.parent) {\n        break;\n      }\n      current = current.parent;\n    }\n\n    return lastWithValidWidth;\n  }\n\n  /**\n   * Compute the absolute position of an element by walking up to the root of the tree.\n   * This accounts for contentOffset and translation attributes at each level.\n   * Returns {x: 0, y: 0} if the element has no frame.\n   */\n  export function absolutePosition(element: IRenderedElement | undefined): Point {\n    const position = { x: 0, y: 0 };\n    let current = element;\n\n    while (current) {\n      if (!current.frame) {\n        break;\n      }\n      // Only subtract contentOffset if it belongs to a parent (affecting the current element's position)\n      // The element's own contentOffset does not affect its own absolute frame position\n      const isTargetElement = current === element;\n      const contentOffsetX = isTargetElement ? 0 : (current.getAttribute('contentOffsetX') ?? 0);\n      const contentOffsetY = isTargetElement ? 0 : (current.getAttribute('contentOffsetY') ?? 0);\n      const translationX = current.getAttribute('translationX') ?? 0;\n      const translationY = current.getAttribute('translationY') ?? 0;\n      position.x += current.frame.x - contentOffsetX + translationX;\n      position.y += current.frame.y - contentOffsetY + translationY;\n      current = current.parent;\n    }\n\n    return position;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/RenderedVirtualNodeUtils.ts",
    "content": "import { IRenderedVirtualNode } from 'valdi_core/src/IRenderedVirtualNode';\n\nfunction outputXMLAttributeValue(value: any): string {\n  if (value === undefined) {\n    return '<undefined>';\n  } else if (value === null) {\n    return '<null>';\n  } else if (typeof value === 'function') {\n    return '<function>';\n  } else if (Array.isArray(value)) {\n    const values = value.map(outputXMLAttributeValue).join(', ');\n    return `[${values}]`;\n  } else if (value.toString) {\n    return value.toString();\n  } else {\n    return '<unknown>';\n  }\n}\n\nfunction outputXML(virtualNode: IRenderedVirtualNode, indent: string, output: string[], recursive: boolean) {\n  output.push(indent);\n  output.push('<');\n\n  const xmlTag = getNodeTag(virtualNode);\n  output.push(xmlTag);\n\n  if (virtualNode.element) {\n    const element = virtualNode.element;\n\n    for (const attributeName of element.getAttributeNames()) {\n      const attributeValue = outputXMLAttributeValue(element.getAttribute(attributeName));\n\n      output.push(' ');\n      output.push(attributeName);\n      output.push('=\"');\n      output.push(attributeValue.toString());\n      output.push('\"');\n    }\n  }\n\n  if (virtualNode.children.length && recursive) {\n    output.push('>\\n');\n    const childIndent = indent + '  ';\n\n    for (const child of virtualNode.children) {\n      outputXML(child, childIndent, output, recursive);\n    }\n\n    output.push(indent);\n    output.push('</');\n    output.push(xmlTag);\n    output.push('>\\n');\n  } else {\n    output.push('/>\\n');\n  }\n}\n\nexport function getNodeTag(virtualNode: IRenderedVirtualNode): string {\n  if (virtualNode.element) {\n    return virtualNode.element.tag;\n  } else if (virtualNode.component) {\n    return (virtualNode.component as any).constructor.name;\n  }\n  return 'undefined';\n}\n\nexport function toXML(virtualNode: IRenderedVirtualNode, recursive: boolean): string {\n  const allStrings: string[] = [];\n  outputXML(virtualNode, '', allStrings, recursive);\n\n  return allStrings.join('');\n}\n\nexport function computeUniqueId(virtualNode: IRenderedVirtualNode): string {\n  const parts: (string | number)[] = [];\n  let current: IRenderedVirtualNode | undefined = virtualNode;\n  while (current !== undefined) {\n    const element = current.element;\n    if (element !== undefined) {\n      parts.push(element.id);\n      break;\n    }\n    parts.push(current.key);\n    current = current.parent;\n  }\n  return parts.join('/');\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/RendererError.ts",
    "content": "import { IRenderedVirtualNode } from '../IRenderedVirtualNode';\n\nexport class RendererError extends Error {\n  constructor(\n    message: string,\n    readonly sourceError: Error,\n    readonly lastRenderedNode: IRenderedVirtualNode | undefined,\n  ) {\n    super(message);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/Stopwatch.ts",
    "content": "export type DurationMills = number;\nexport type DurationMicros = number;\n\nexport class Duration {\n  readonly milliseconds: DurationMills;\n\n  constructor(milliseconds: DurationMills) {\n    this.milliseconds = milliseconds;\n  }\n\n  get seconds(): number {\n    return this.milliseconds / 1000.0;\n  }\n\n  get microseconds(): number {\n    return this.milliseconds * 1000.0;\n  }\n\n  subtracting(other: Duration): Duration {\n    return new Duration(this.milliseconds - other.milliseconds);\n  }\n\n  adding(other: Duration): Duration {\n    return new Duration(this.milliseconds + other.milliseconds);\n  }\n\n  toString(): string {\n    let current = this.microseconds;\n    let unit = 'us';\n    let precision = 0;\n    if (current > 1000) {\n      current /= 1000;\n      unit = 'ms';\n      precision = 2;\n    }\n    if (current > 1000) {\n      current /= 1000;\n      unit = 's';\n      precision = 3;\n    }\n\n    return `${current.toFixed(precision)}${unit}`;\n  }\n}\n\nexport class Stopwatch {\n  private startTime: DurationMills;\n  private endTime: DurationMills;\n\n  constructor() {\n    this.startTime = 0;\n    this.endTime = 0;\n  }\n\n  static createAndStart(): Stopwatch {\n    const stopwatch = new Stopwatch();\n    stopwatch.start();\n    return stopwatch;\n  }\n\n  start() {\n    this.startTime = performance.now();\n    this.endTime = 0;\n  }\n\n  stop() {\n    this.endTime = performance.now();\n  }\n\n  pause() {\n    this.endTime = performance.now();\n  }\n\n  resume() {\n    this.startTime = performance.now() - (this.endTime - this.startTime);\n    this.endTime = 0;\n  }\n\n  elapsedMicros(): DurationMills {\n    return this.elapsedMs() * 1000.0;\n  }\n\n  elapsedMs(): number {\n    const endTime = this.endTime || performance.now();\n    return endTime - this.startTime;\n  }\n\n  elapsed(): Duration {\n    return new Duration(this.elapsedMs());\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/StringUtils.ts",
    "content": "import { symbolicate } from '../Symbolicator';\n\nexport function toCamelCase(snakeCaseString: string): string {\n  const components = snakeCaseString.split('_');\n  let out = '';\n\n  for (const component of components) {\n    if (!component) {\n      continue;\n    }\n\n    if (!out) {\n      out = component;\n    } else {\n      if (component.length === 1) {\n        out += component.toUpperCase();\n      } else {\n        out += component[0].toUpperCase() + component.substr(1);\n      }\n    }\n  }\n\n  return out;\n}\n\nexport function capitalize(str: string): string {\n  if (str.length == 0) {\n    return str;\n  }\n  return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nexport function debugStringify(object: any, maxDepth: number, pretty: boolean): string {\n  if (object === undefined) {\n    return 'undefined';\n  }\n  if (typeof object === 'string') {\n    return object;\n  }\n  const alreadyVisited = new Set();\n  return stringifyInnerSafely(object, alreadyVisited, 0, maxDepth, pretty);\n}\n\nfunction stringifyIndent(depth: number) {\n  let indent = '';\n  for (let i = 0; i < depth; i++) {\n    indent += '  ';\n  }\n  return '\\n' + indent;\n}\n\nfunction stringifyInnerSafely(\n  object: any,\n  alreadyVisited: Set<any>,\n  currentDepth: number,\n  maxDepth: number,\n  pretty: boolean,\n) {\n  try {\n    return stringifyInner(object, alreadyVisited, currentDepth, maxDepth, pretty);\n  } catch (e: any) {\n    if (e) {\n      return `<failure ${e.message}/>`;\n    } else {\n      return `<failure unknown/>`;\n    }\n  }\n}\n\nfunction stringifyInner(\n  object: any,\n  alreadyVisited: Set<any>,\n  currentDepth: number,\n  maxDepth: number,\n  pretty: boolean,\n): string {\n  if (currentDepth >= maxDepth) {\n    return '...';\n  }\n\n  if (object === undefined) {\n    return 'undefined';\n  }\n  if (object === null) {\n    return 'null';\n  }\n  if (object === true) {\n    return 'true';\n  }\n  if (object === false) {\n    return 'false';\n  }\n\n  const type = typeof object;\n  if (type === 'string') {\n    return `\\\"${object}\\\"`;\n  }\n  if (type === 'number' && typeof object.toString === 'function') {\n    return object.toString();\n  }\n  if (type === 'function') {\n    if ((object as any).componentPath) {\n      return `<function ${object.name} -> ${object.componentPath}/>`;\n    } else {\n      return `<function ${object.name}/>`;\n    }\n  }\n  if (object instanceof Date && typeof object.toISOString === 'function') {\n    return `<date ${object.toISOString()}/>`;\n  }\n  if (object instanceof Error) {\n    const symbolicatedError = symbolicate(object);\n    let errorString = `${symbolicatedError.name}:${symbolicatedError.message}`;\n\n    if (symbolicatedError.stack) {\n      errorString += '\\n';\n      errorString += symbolicatedError.stack;\n    }\n    return errorString;\n  }\n\n  if (alreadyVisited.has(object)) {\n    return `<circular ${type}/>`;\n  }\n  alreadyVisited.add(object);\n\n  const indentCurrent = pretty ? stringifyIndent(currentDepth) : '';\n  const indentNext = pretty ? stringifyIndent(currentDepth + 1) : '';\n  const ellipsisAfter = 50;\n\n  if (Array.isArray(object)) {\n    if (object.length <= 0) {\n      return '[]';\n    }\n    const parts = [];\n    for (const item of object) {\n      parts.push(stringifyInnerSafely(item, alreadyVisited, currentDepth + 1, maxDepth, pretty));\n      if (parts.length >= ellipsisAfter) {\n        parts.push(`... ${object.length - ellipsisAfter} more item(s) ...`);\n        break;\n      }\n    }\n    return `[${indentNext}${parts.join(',' + indentNext)}${indentCurrent}]`;\n  }\n\n  if (object instanceof Map) {\n    if (object.size <= 0) {\n      return 'Map{}';\n    }\n    const parts = [];\n    for (const key of Array.from(object.keys())) {\n      const value = object.get(key);\n      const str = stringifyInnerSafely(value, alreadyVisited, currentDepth + 1, maxDepth, pretty);\n      parts.push(`${key}: ${str}`);\n      if (parts.length >= ellipsisAfter) {\n        parts.push(`... ${object.size - ellipsisAfter} more item(s) ...`);\n        break;\n      }\n    }\n    return `Map{${indentNext}${parts.join(',' + indentNext)}${indentCurrent}}`;\n  }\n\n  if (object instanceof Set) {\n    if (object.size <= 0) {\n      return 'Set()';\n    }\n    const parts = [];\n    for (const item of Array.from(object)) {\n      parts.push(stringifyInnerSafely(item, alreadyVisited, currentDepth + 1, maxDepth, pretty));\n      if (parts.length >= ellipsisAfter) {\n        parts.push(`... ${object.size - ellipsisAfter} more item(s) ...`);\n        break;\n      }\n    }\n    return `Set(${indentNext}${parts.join(',' + indentNext)}${indentCurrent})`;\n  }\n\n  if (typeof object.toConsoleRepresentation === 'function') {\n    const naming = object.constructor?.name ?? '';\n    const debug = stringifyInnerSafely(\n      object.toConsoleRepresentation(),\n      alreadyVisited,\n      currentDepth,\n      maxDepth,\n      pretty,\n    );\n    return `<${naming} ...${debug}/>`;\n  }\n\n  if (object.toString !== Object.prototype.toString && typeof object.toString === 'function') {\n    return object.toString();\n  }\n\n  if (type === 'object') {\n    let prefix = '';\n    let postfix = '';\n    const name = object.constructor?.name;\n    if (name !== undefined && name !== 'Object') {\n      prefix = '<' + name + ' ...';\n      postfix = '/>';\n    }\n    const keys = Object.keys(object);\n    if (keys.length <= 0) {\n      return `${prefix}{}${postfix}`;\n    }\n    const parts = [];\n    for (const key of keys) {\n      const value = object[key];\n      const str = stringifyInnerSafely(value, alreadyVisited, currentDepth + 1, maxDepth, pretty);\n      parts.push(`${key}: ${str}`);\n      if (parts.length >= ellipsisAfter) {\n        parts.push(`... ${keys.length - ellipsisAfter} more item(s) ...`);\n        break;\n      }\n    }\n    return `${prefix}{${indentNext}${parts.join(',' + indentNext)}${indentCurrent}}${postfix}`;\n  }\n\n  if (typeof object.toString === 'function') {\n    return object.toString();\n  }\n\n  return `<unknown ${type}>`;\n}\n\nexport function titleCase(str: string): string {\n  return str\n    .toLocaleLowerCase()\n    .split(' ')\n    .map(subString => {\n      return `${subString.charAt(0).toLocaleUpperCase()}${subString.slice(1)}`;\n    })\n    .join(' ');\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/TestUtils.ts",
    "content": "export type ValdiGlobalTestSuiteDoneHandler = {\n  __onValdiTestSuiteDone: () => void;\n};\ndeclare const global: ValdiGlobalTestSuiteDoneHandler;\n\nconst callbacks: Array<() => void> = [];\n\nglobal.__onValdiTestSuiteDone = () => callbacks.forEach(callback => callback());\n\n/**\n * Registers a callback to be called when a Jasmine test suite is done.\n * Use that to clear any global state that was potentially polluted by test runs.\n *\n * @param callback\n */\nexport function registerValdiTestSuiteDoneCallback(callback: () => void): void {\n  callbacks.push(callback);\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/TimeUtils.ts",
    "content": "/**\n * Takes in a number representing milliseconds and returns the length of time in \"HH:MM:SS\" format in the form of a string\n * @param ms The number of milliseconds\n * @returns A string showing the length of time represented by ms in \"HH:MM:SS\" format\n */\nexport function formatDurationMs(ms: number): string {\n  const seconds = ms / 1000;\n  return formatDurationSeconds(seconds);\n}\n\n/**\n * Takes in a number representing seconds and returns the length of time in \"HH:MM:SS\" format in the form of a string\n * @param seconds The number of seconds\n * @returns A string showing the length of time represented by seconds in \"HH:MM:SS\" format\n */\nexport function formatDurationSeconds(seconds: number): string {\n  const h = Math.floor(seconds / 3600);\n  const m = Math.floor((seconds % 3600) / 60);\n  const s = Math.round(seconds % 60);\n  return [h, m > 9 ? m : h ? `0${m}` : m || '0', s > 9 ? s : `0${s}`].filter(Boolean).join(':');\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/Trace.ts",
    "content": "import { ValdiRuntime } from 'valdi_core/src/ValdiRuntime';\n\ndeclare const runtime: ValdiRuntime;\n\nexport interface RecordedTrace {\n  trace: string;\n  startMicros: number;\n  endMicros: number;\n  threadId: number;\n}\n\n/**\n * Start recording traces happening in the Valdi Runtime.\n * It is absolutely essential that this call is eventually followed\n * by \"stopTraceRecording\", or the memory will keep growing.\n *\n * The function returns an identifier which should be passed in\n * to \"stopTraceRecording\"\n */\nexport function startTraceRecording(): number {\n  return runtime.startTraceRecording();\n}\n\n/**\n * Stop recording the traces from a previous startTraceRecording call.\n * Returns the captured traces.\n */\nexport function stopTraceRecording(id: number): RecordedTrace[] {\n  const result = runtime.stopTraceRecording(id);\n\n  const out: RecordedTrace[] = [];\n\n  for (let i = 0; i < result.length; ) {\n    const trace = result[i++];\n    const startMicros = result[i++];\n    const endMicros = result[i++];\n    const threadId = result[i++];\n\n    out.push({ trace, startMicros, endMicros, threadId });\n  }\n\n  return out;\n}\n\n/**\n * Execute the given function and associate it with a traced label\n * @param tag the trace tag to use\n * @param func to function to evaluate\n */\nexport function trace<T>(tag: string, func: () => T): T {\n  if (!runtime.trace) {\n    return func();\n  } else {\n    return runtime.trace(tag, func);\n  }\n}\n\nconst TRACE_PROXY_KEY = '$trace-proxy-target';\n\nfunction makeProxyFunction(tag: string, fn: (...params: any[]) => any): (...params: any[]) => any {\n  const proxyFunction = runtime.makeTraceProxy(tag, fn);\n  Object.defineProperty(proxyFunction, 'name', { value: fn.name });\n  (proxyFunction as any)[TRACE_PROXY_KEY] = fn;\n  return proxyFunction;\n}\n\nfunction makeTraceProxyFunctionForProperty(\n  target: any,\n  propertyName: string,\n  propertyDescriptor: PropertyDescriptor,\n): ((...params: any[]) => any) | undefined {\n  if (propertyDescriptor.get || propertyDescriptor.set || !propertyDescriptor.writable) {\n    return undefined;\n  }\n\n  const propertyValue = propertyDescriptor.value;\n\n  if (!(typeof propertyValue === 'function')) {\n    return undefined;\n  }\n  const ctor = target.constructor;\n\n  if (propertyValue === ctor) {\n    return undefined;\n  }\n\n  if (propertyValue[TRACE_PROXY_KEY]) {\n    return undefined;\n  }\n\n  const currentClassName = ctor?.name;\n  const tag = currentClassName ? `${currentClassName}.${propertyName}` : `<anon>.${propertyName}`;\n\n  return makeProxyFunction(tag, propertyValue);\n}\n\n/**\n * Setup the given object class so that calling its methods\n * will automatically trace the calls.\n * @param objectClass\n * @returns\n */\nexport function installTraceProxy(objectClass: new (...input: any[]) => any) {\n  if (!runtime.makeTraceProxy) {\n    return;\n  }\n\n  let current = objectClass.prototype;\n  while (current) {\n    if (\n      current === Object.prototype ||\n      current === Array.prototype ||\n      current === Function.prototype ||\n      current === Number.prototype\n    ) {\n      break;\n    }\n\n    const propertyNames = Object.getOwnPropertyNames(current);\n    for (const propertyName of propertyNames) {\n      const propertyDescriptor = Object.getOwnPropertyDescriptor(current, propertyName);\n      if (!propertyDescriptor) {\n        continue;\n      }\n\n      const fn = makeTraceProxyFunctionForProperty(current, propertyName, propertyDescriptor);\n      if (fn) {\n        current[propertyName] = fn;\n      }\n    }\n\n    current = Object.getPrototypeOf(current);\n  }\n}\n\n/**\n * Install trace proxies on all the methods of the given class.\n */\nexport function Trace(cls: new (...input: any[]) => any): void {\n  installTraceProxy(cls);\n}\n\n/**\n * Install a trace proxy on a single method.\n */\nexport function TraceMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n  if (!runtime.makeTraceProxy) {\n    return;\n  }\n\n  const fn = makeTraceProxyFunctionForProperty(target, propertyKey, descriptor);\n  if (fn) {\n    descriptor.value = fn;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/UuidUtils.ts",
    "content": "export function uuidBytesToString(bytes: Uint8Array): string {\n  let out = '';\n  for (let i = 0; i < 16; i++) {\n    if (i === 4 || i === 6 || i === 8 || i === 10) {\n      out += '-';\n    }\n    out += byteToString(bytes[i]);\n  }\n  return out;\n}\n\nfunction byteToString(byte: number): string {\n  const out = byte.toString(16);\n  if (out.length < 2) {\n    return '0' + out;\n  }\n  return out;\n}\n\nexport function uuidToString(lowBits: Long, highBits: Long): string {\n  const bytes = new Uint8Array([...highBits.toBytes(), ...lowBits.toBytes()]);\n  return uuidBytesToString(bytes);\n}\n\n/**\n * Converts a string to a UUID object, containg low and high bits\n * @param str - The string to convert\n */\nexport function stringToUUID(str: string): { lowBits: Long; highBits: Long } {\n  const UUID_SIZE = 16;\n  const lowBytes = [UUID_SIZE / 2];\n  const highBytes = [UUID_SIZE / 2];\n\n  let strIndex = 0;\n  for (let i = 0; i < UUID_SIZE / 2; i++) {\n    const byteHex = str.slice(strIndex, strIndex + 2);\n    highBytes[i] = Number.parseInt(byteHex, 16);\n\n    strIndex += 2;\n    if (str[strIndex] === '-') {\n      strIndex++;\n    }\n  }\n  for (let i = 0; i < UUID_SIZE / 2; i++) {\n    const byteHex = str.slice(strIndex, strIndex + 2);\n    lowBytes[i] = Number.parseInt(byteHex, 16);\n\n    strIndex += 2;\n    if (str[strIndex] === '-') {\n      strIndex++;\n    }\n  }\n  return {\n    highBits: Long.fromBytes(highBytes),\n    lowBits: Long.fromBytes(lowBytes),\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/When.ts",
    "content": "type NotFalse<Type> = Type extends false ? never : Type;\n\n/** Evaluates and returns the output of `fn` when `val` is truthy, otherwise returns `undefined`. */\nexport function when<In, Out>(val: In, fn: (val: NotFalse<NonNullable<In>>) => Out | undefined) {\n  if (!val) {\n    return undefined;\n  }\n  return fn(val as NotFalse<NonNullable<In>>);\n}\n\n/** Evaluates and returns the output of `fn` when `val` is not undefined and not null, otherwise returns `undefined`. */\nexport function whenDefined<In, Out>(val: In, fn: (val: NonNullable<In>) => Out | undefined) {\n  if (val === undefined || val === null) {\n    return undefined;\n  }\n\n  return fn(val!);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/src/utils/WithRequired.ts",
    "content": "export type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/tsconfig.json",
    "content": "{\n  \"extends\": \"../_configs/base.tsconfig.json\",\n  \"compilerOptions\": {\n    \"noImplicitReturns\": true,\n    \"noImplicitAny\": true,\n    \"strict\": true,\n    \"jsx\": \"preserve\"\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/web/ApplicationBridge.ts",
    "content": "import { ApplicationCancelable } from \"../src/ApplicationBridge\";\n\nconst noopCancelable: ApplicationCancelable = { cancel() {} };\n\n// minimal Node env shim so TS stops complaining (no runtime dependency)\ndeclare const process:\n  | undefined\n  | { env?: Record<string, string | undefined> };\n\n/**\n * Fires when your app “enters background”.\n * Stub: no-ops; returns a cancelable for API compatibility.\n */\nexport function observeEnteredBackground(_observe: () => void): ApplicationCancelable {\n  // You could hook document.visibilityState === 'hidden' here if desired.\n  return noopCancelable;\n}\n\n/**\n * Fires when your app “enters foreground”.\n * Stub: no-ops; returns a cancelable for API compatibility.\n */\nexport function observeEnteredForeground(_observe: () => void): ApplicationCancelable {\n  // You could hook document.visibilityState === 'visible' here if desired.\n  return noopCancelable;\n}\n\n/**\n * Observe keyboard height.\n * Stub: immediately reports 0 and returns a no-op cancelable.\n */\nexport function observeKeyboardHeight(observe: (height: number) => void): ApplicationCancelable {\n  try {\n    observe(0);\n  } catch {\n    /* ignore */\n  }\n  return noopCancelable;\n}\n\n/**\n * Whether the app is foregrounded.\n * Stub: returns true in browsers when visible; otherwise true.\n */\nexport function isForegrounded(): boolean {\n  if (typeof document !== 'undefined' && typeof document.visibilityState === 'string') {\n    return document.visibilityState === 'visible';\n  }\n  return true;\n}\n\n/**\n * Whether we’re in an integration-test environment.\n * Stub: checks a couple of common flags, else false.\n */\nexport function isIntegrationTestEnvironment(): boolean {\n  // Jest / Playwright / custom env flags\n  if (typeof process !== 'undefined' && process.env) {\n    if (process.env.JEST_WORKER_ID || process.env.PLAYWRIGHT === '1' || process.env.INTEGRATION_TEST === '1') {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * App version string.\n * Stub: tries a few sources, falls back to \"0.0.0\".\n * - global __APP_VERSION__ (inject via bundler DefinePlugin/Vite define)\n * - npm_package_version (when running via npm scripts in Node)\n */\ndeclare const __APP_VERSION__: string | undefined; // optional build-time define\nexport function getAppVersion(): string {\n  // Build-time injected\n  if (typeof __APP_VERSION__ === 'string' && __APP_VERSION__) return __APP_VERSION__;\n\n  // NPM-provided var during scripts (Node)\n  if (typeof process !== 'undefined' && process.env?.npm_package_version) {\n    return process.env.npm_package_version!;\n  }\n\n  return \"0.0.0\";\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/web/DeviceBridge.ts",
    "content": "import { DeviceCancelable, DeviceHapticFeedbackType, DeviceSystemType } from \"../src/DeviceBridge\";\n\n\nconst noopCancelable: DeviceCancelable = { cancel() {} };\n\n// --- helpers ---\n\nconst isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst ua = isBrowser ? navigator.userAgent : '';\nconst isIOS =\n  /\\b(iPad|iPhone|iPod)\\b/.test(ua) ||\n  // iPadOS 13+ identifies as Mac with touch\n  (/\\bMacintosh\\b/.test(ua) && isBrowser && 'ontouchend' in window);\nconst isAndroid = /\\bAndroid\\b/i.test(ua);\n\nconst DPR = isBrowser && window.devicePixelRatio ? window.devicePixelRatio : 1;\n\nfunction on<K extends keyof WindowEventMap>(\n  type: K,\n  fn: (ev: WindowEventMap[K]) => void\n): DeviceCancelable {\n  if (!isBrowser) return noopCancelable;\n  window.addEventListener(type, fn as EventListener);\n  return { cancel: () => window.removeEventListener(type, fn as EventListener) };\n}\n\nfunction getSafeAreaInset(side: 'top' | 'right' | 'bottom' | 'left'): number {\n  if (!isBrowser || !window.getComputedStyle) return 0;\n  // Read CSS env(safe-area-inset-*) via a temporary element\n  const el = document.createElement('div');\n  el.style.cssText = `\n    position: absolute;\n    ${side}: 0;\n    width: 0;height: 0;\n    padding-${side}: env(safe-area-inset-${side});\n    visibility: hidden;\n  `;\n  document.body.appendChild(el);\n  const px = getComputedStyle(el).getPropertyValue(`padding-${side}`).trim();\n  el.remove();\n  const n = parseFloat(px || '0');\n  return Number.isFinite(n) ? n : 0;\n}\n\n// --- API ---\n\nexport function copyToClipBoard(text: string): void {\n  if (!isBrowser) return;\n  if (navigator.clipboard?.writeText) {\n    navigator.clipboard.writeText(text).catch(() => {\n      /* ignore */\n    });\n  } else {\n    // Fallback\n    const el = document.createElement('textarea');\n    el.value = text;\n    el.setAttribute('readonly', '');\n    el.style.position = 'fixed';\n    el.style.opacity = '0';\n    document.body.appendChild(el);\n    el.select();\n    try {\n      document.execCommand('copy');\n    } catch {\n      /* ignore */\n    }\n    document.body.removeChild(el);\n  }\n}\n\nexport function getSystemType(): DeviceSystemType {\n  if (isIOS) return DeviceSystemType.IOS;\n  if (isAndroid) return DeviceSystemType.ANDROID;\n  // default heuristic: desktops → pretend iOS/Android? pick IOS arbitrarily.\n  return DeviceSystemType.IOS;\n}\n\nexport function getSystemVersion(): string {\n  if (!isBrowser) return '0.0';\n  // Basic UA scrape (best-effort)\n  const mIOS = ua.match(/OS (\\d+[_\\.\\d]*) like Mac OS X/);\n  if (mIOS) return mIOS[1].replace(/_/g, '.');\n  const mAndroid = ua.match(/Android (\\d+([._]\\d+)*)/i);\n  if (mAndroid) return mAndroid[1].replace(/_/g, '.');\n  return '0.0';\n}\n\nexport function getModel(): string {\n  // Browsers generally don’t expose model; return empty or generic\n  if (!isBrowser) return '';\n  if (isIOS) return 'iOS Device';\n  if (isAndroid) return 'Android Device';\n  return 'Desktop';\n}\n\n// Physical display size in CSS pixels * devicePixelRatio (approx)\nexport function getDisplayWidth(): number {\n  if (!isBrowser) return 0;\n  return Math.round((window.screen?.width || window.innerWidth || 0) * DPR);\n}\n\nexport function getDisplayHeight(): number {\n  if (!isBrowser) return 0;\n  return Math.round((window.screen?.height || window.innerHeight || 0) * DPR);\n}\n\nexport function getDisplayScale(): number {\n  return DPR;\n}\n\nexport function getWindowWidth(): number {\n  if (!isBrowser) return 0;\n  return Math.max(0, Math.floor(window.innerWidth));\n}\n\nexport function getWindowHeight(): number {\n  if (!isBrowser) return 0;\n  return Math.max(0, Math.floor(window.innerHeight));\n}\n\nexport function getDisplayLeftInset(): number {\n  return isBrowser ? getSafeAreaInset('left') : 0;\n}\n\nexport function getDisplayRightInset(): number {\n  return isBrowser ? getSafeAreaInset('right') : 0;\n}\n\nexport function getDisplayTopInset(): number {\n  return isBrowser ? getSafeAreaInset('top') : 0;\n}\n\nexport function getDisplayBottomInset(): number {\n  return isBrowser ? getSafeAreaInset('bottom') : 0;\n}\n\nexport function getDeviceLocales(): string[] {\n  if (!isBrowser) return [];\n  const langs = (navigator as any).languages as string[] | undefined;\n  const lang = navigator.language;\n  const arr = langs && langs.length ? langs : (lang ? [lang] : []);\n  return arr.map(s => s.replace('_', '-'));\n}\n\nexport function getLocaleUsesMetricSystem(): boolean {\n  // Non-metric: US, LR, MM\n  const NON_METRIC = new Set(['US', 'LR', 'MM']);\n  const locale = getDeviceLocales()[0] || 'en-US';\n  try {\n    // Try Intl.Locale for region\n    // @ts-ignore - older TS may not have Intl.Locale in lib\n    const loc = (Intl as any).Locale ? new (Intl as any).Locale(locale) : null;\n    const region = loc?.maximized?.region || loc?.region || locale.split('-')[1];\n    if (!region) return true;\n    return !NON_METRIC.has(String(region).toUpperCase());\n  } catch {\n    return true;\n  }\n}\n\nexport function getTimeZoneName(): string {\n  if (!isBrowser) return 'UTC';\n  return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';\n}\n\nexport function getTimeZoneRawSecondsFromGMT(timeZoneName: string | undefined): number {\n  // Stub: return the current zone’s *standard* offset approx (ignoring DST).\n  try {\n    const now = new Date();\n    // Try to approximate “standard” by checking January (likely standard time)\n    const jan = new Date(now.getFullYear(), 0, 1);\n    const fmt = new Intl.DateTimeFormat('en-US', {\n      timeZone: timeZoneName || getTimeZoneName(),\n      timeZoneName: 'shortOffset',\n    });\n    // e.g., \"GMT-7\" → parse\n    const parts = fmt.formatToParts(jan);\n    const off = parts.find(p => p.type === 'timeZoneName')?.value || 'GMT+0';\n    const m = off.match(/GMT([+-])(\\d{1,2})(?::(\\d{2}))?/i);\n    if (!m) return 0;\n    const sign = m[1] === '-' ? -1 : 1;\n    const h = parseInt(m[2], 10);\n    const mins = m[3] ? parseInt(m[3], 10) : 0;\n    return sign * (h * 3600 + mins * 60);\n  } catch {\n    return -new Date().getTimezoneOffset() * 60;\n  }\n}\n\nexport function getTimeZoneDstSecondsFromGMT(timeZoneName: string | undefined): number {\n  // Stub: difference between “now” and “standard” offsets for the timezone.\n  try {\n    const std = getTimeZoneRawSecondsFromGMT(timeZoneName);\n    const fmt = new Intl.DateTimeFormat('en-US', {\n      timeZone: timeZoneName || getTimeZoneName(),\n      timeZoneName: 'shortOffset',\n    });\n    const parts = fmt.formatToParts(new Date());\n    const off = parts.find(p => p.type === 'timeZoneName')?.value || 'GMT+0';\n    const m = off.match(/GMT([+-])(\\d{1,2})(?::(\\d{2}))?/i);\n    if (!m) return 0;\n    const sign = m[1] === '-' ? -1 : 1;\n    const h = parseInt(m[2], 10);\n    const mins = m[3] ? parseInt(m[3], 10) : 0;\n    const cur = sign * (h * 3600 + mins * 60);\n    return cur - std;\n  } catch {\n    return 0;\n  }\n}\n\nconst startTime = Date.now();\nexport function getUptimeMs(): number {\n  if (typeof performance !== 'undefined' && performance.now) return performance.now();\n  return Date.now() - startTime;\n}\n\nexport function performHapticFeedback(_hapticType: DeviceHapticFeedbackType): void {\n  // Browsers don’t have rich haptics; vibrate if available.\n  if (isBrowser && navigator.vibrate) {\n    navigator.vibrate(10);\n  }\n}\n\nexport function observeDisplayInsetChange(observe: () => void): DeviceCancelable {\n  // Approximate: fire on resize and orientation changes\n  const c1 = on('resize', observe);\n  const c2 = on('orientationchange' as any, observe as any);\n  return { cancel: () => { c1.cancel(); c2.cancel(); } };\n}\n\nexport function observeDisplaySizeChange(observe: () => void): DeviceCancelable {\n  return on('resize', observe);\n}\n\nexport function observeDarkMode(observe: (isDarkMode: boolean) => void): DeviceCancelable {\n  if (!isBrowser || !window.matchMedia) return noopCancelable;\n  const mq = window.matchMedia('(prefers-color-scheme: dark)');\n  const handler = () => {\n    try { observe(mq.matches); } catch { /* ignore */ }\n  };\n  handler();\n  mq.addEventListener?.('change', handler);\n  // Safari < 14 fallback\n  // @ts-ignore\n  mq.addListener?.(handler);\n  return {\n    cancel: () => {\n      mq.removeEventListener?.('change', handler);\n      // @ts-ignore\n      mq.removeListener?.(handler);\n    }\n  };\n}\n\nexport function isDesktop(): boolean {\n  if (!isBrowser) return true;\n  return !(isIOS || isAndroid);\n}\n\nexport function isWeb(): boolean {\n  return isBrowser;\n}\n\n// On web there is no native back button; some apps emulate via history.\n// Keep undefined to honor your API shape.\nexport const setBackButtonObserver: ((observer: (() => boolean) | undefined) => void) | undefined = undefined;"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/web/Strings.ts",
    "content": "export function getLocalizedString(bundle: string, key: string): string | undefined {     \n  console.log({ getLocalizedString: \"getLocalizedString\", bundle, key });\n  return `${bundle}.${key}`;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_core/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n     \"lib\": [\"DOM\", \"ES2020\"],\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": true,\n    \"allowJs\": true\n  },\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/BUILD.bazel",
    "content": "load(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n# Example of including additional ts sources that get transpiled\n# and bundled into the node module target for this valdi module\nts_project(\n    name = \"valdi_http_web\",\n    srcs = glob([\n        \"web/**/*.ts\",\n        \"src/**/*.d.ts\",\n    ]) + [\n        \"//src/valdi_modules/src/valdi/coreutils:coreutils_dts\",\n    ],\n    allow_js = True,\n    composite = True,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n)\n\nvaldi_module(\n    name = \"valdi_http\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiHTTP\",\n    ios_output_target = \"release\",\n    native_deps = [\"@valdi//src/valdi_modules/src/cpp/valdi_http:valdi_http_cpp\"],\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":valdi_http_web\"],\n    web_register_native_module_id_overrides = {\n        \"valdi_http/web/WebHTTPClient.js\": \"valdi_http/src/NativeHTTPClient\",\n    },\n    deps = [\n        \"//src/valdi_modules/src/valdi/coreutils\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/module.yaml",
    "content": "output_target: release\n\nbazel_build_file_generation_disabled: true\n\ndependencies:\n  - coreutils\n  - valdi_core\n\nexclude_patterns:\n  - .*\\/web\\/.*\nexclude_globs:\n  - \"**/web/**\"\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/src/HTTPClient.ts",
    "content": "import { CancelablePromise, promiseToCancelablePromise } from 'valdi_core/src/CancelablePromise';\nimport { StringMap } from 'coreutils/src/StringMap';\nimport { HTTPMethod, HTTPRequest, HTTPResponse } from './HTTPTypes';\nimport { IHTTPClient } from './IHTTPClient';\nimport { performRequest } from './NativeHTTPClient';\n\nfunction makeURL(baseUrl: string | undefined, pathOrUrl: string): string {\n  if (pathOrUrl.indexOf('://') >= 0) {\n    return pathOrUrl;\n  }\n  if (!baseUrl) {\n    throw new Error('baseUrl should be specified when providing a relative path');\n  }\n\n  if (!baseUrl.endsWith('/')) {\n    baseUrl += '/';\n  }\n  if (pathOrUrl.startsWith('/')) {\n    pathOrUrl = pathOrUrl.substring(1);\n  }\n  return baseUrl + pathOrUrl;\n}\n\nexport class HTTPClient implements IHTTPClient {\n  constructor(readonly baseUrl?: string | undefined) {}\n\n  perform(\n    pathOrUrl: string,\n    method: HTTPMethod,\n    headers: StringMap<string> | undefined,\n    body: ArrayBuffer | Uint8Array | undefined,\n  ): CancelablePromise<HTTPResponse> {\n    let cancelFn: (() => void) | undefined;\n    const promise = new Promise<HTTPResponse>((resolve, reject) => {\n      try {\n        const request: HTTPRequest = {\n          url: makeURL(this.baseUrl, pathOrUrl),\n          method,\n          headers,\n          body,\n        };\n\n        cancelFn = performRequest(request, (response, error) => {\n          if (response) {\n            resolve(response);\n          } else {\n            reject(error);\n          }\n        });\n      } catch (err: unknown) {\n        reject(err);\n      }\n    });\n\n    return promiseToCancelablePromise(promise, () => cancelFn?.());\n  }\n\n  get(pathOrUrl: string, headers?: StringMap<string> | undefined): CancelablePromise<HTTPResponse> {\n    return this.perform(pathOrUrl, HTTPMethod.GET, headers, undefined);\n  }\n\n  put(\n    pathOrUrl: string,\n    body?: ArrayBuffer | Uint8Array | undefined,\n    headers?: StringMap<string> | undefined,\n  ): CancelablePromise<HTTPResponse> {\n    return this.perform(pathOrUrl, HTTPMethod.PUT, headers, body);\n  }\n\n  post(\n    pathOrUrl: string,\n    body?: ArrayBuffer | Uint8Array | undefined,\n    headers?: StringMap<string> | undefined,\n  ): CancelablePromise<HTTPResponse> {\n    return this.perform(pathOrUrl, HTTPMethod.POST, headers, body);\n  }\n\n  delete(pathOrUrl: string, headers: StringMap<string> | undefined): CancelablePromise<HTTPResponse> {\n    return this.perform(pathOrUrl, HTTPMethod.DELETE, headers, undefined);\n  }\n\n  head(pathOrUrl: string, headers: StringMap<string> | undefined): CancelablePromise<HTTPResponse> {\n    return this.perform(pathOrUrl, HTTPMethod.HEAD, headers, undefined);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/src/HTTPTypes.d.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\n\nexport const enum HTTPMethod {\n  GET = 'GET',\n  POST = 'POST',\n  DELETE = 'DELETE',\n  PUT = 'PUT',\n  HEAD = 'HEAD',\n}\n\nexport interface HTTPRequest {\n  url: string;\n  method: HTTPMethod;\n  headers?: StringMap<string>;\n  body?: ArrayBuffer | Uint8Array;\n  priority?: number;\n}\n\nexport interface HTTPResponse {\n  headers: StringMap<string>;\n  statusCode: number;\n  body?: Uint8Array;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/src/IHTTPClient.d.ts",
    "content": "import { CancelablePromise } from 'valdi_core/src/CancelablePromise';\nimport { StringMap } from 'coreutils/src/StringMap';\nimport { HTTPResponse } from './HTTPTypes';\n\nexport interface IHTTPClient {\n  get(pathOrUrl: string, headers?: StringMap<string> | undefined): CancelablePromise<HTTPResponse>;\n\n  put(\n    pathOrUrl: string,\n    body?: ArrayBuffer | Uint8Array | undefined,\n    headers?: StringMap<string> | undefined,\n  ): CancelablePromise<HTTPResponse>;\n\n  post(\n    pathOrUrl: string,\n    body?: ArrayBuffer | Uint8Array | undefined,\n    headers?: StringMap<string> | undefined,\n  ): CancelablePromise<HTTPResponse>;\n\n  delete(pathOrUrl: string, headers: StringMap<string> | undefined): CancelablePromise<HTTPResponse>;\n\n  head(pathOrUrl: string, headers: StringMap<string> | undefined): CancelablePromise<HTTPResponse>;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/src/NativeHTTPClient.d.ts",
    "content": "import { HTTPRequest, HTTPResponse } from './HTTPTypes';\n\nexport function performRequest(\n  request: HTTPRequest,\n  completion: (response: HTTPResponse | undefined, error: unknown | undefined) => void,\n): () => void;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/tsconfig.json",
    "content": "{\n    \"extends\": \"../_configs/base.tsconfig.json\",\n    \"compilerOptions\": {\n        \"noImplicitReturns\": true,\n        \"noImplicitAny\": true,\n        \"strict\": true,\n    }\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/web/WebHTTPClient.ts",
    "content": "import { StringMap } from '../../coreutils/src/StringMap';\nimport { HTTPRequest, HTTPResponse } from '../src/HTTPTypes';\n\nexport function performRequest(\n  request: HTTPRequest,\n  completion: (response: HTTPResponse | undefined, error: unknown | undefined) => void,\n): () => void {\n  let done = false;\n  const completeOnce = (resp?: HTTPResponse, err?: unknown) => {\n    if (done) return;\n    done = true;\n    try { completion(resp, err); } catch { /* swallow in stub */ }\n  };\n\n  // If fetch exists, use it; otherwise stub a success response.\n  let abortCtrl: AbortController | undefined;\n\n  if (typeof fetch === \"function\") {\n    try {\n      if (typeof AbortController !== \"undefined\") abortCtrl = new AbortController();\n    } catch { /* older envs */ }\n\n    // Prepare headers as a plain object (works across environments)\n    const headersObj: Record<string, string> = {};\n    if (request.headers) {\n      for (const k in request.headers) {\n        if (Object.prototype.hasOwnProperty.call(request.headers, k)) {\n          const v = request.headers[k];\n          if (typeof v === \"string\") headersObj[k] = v;\n        }\n      }\n    }\n\n    // Prepare body\n    let body: BodyInit | undefined;\n    if (request.body != null) {\n      if (request.body instanceof Uint8Array) body = request.body;\n      else if (typeof ArrayBuffer !== \"undefined\" && request.body instanceof ArrayBuffer) {\n        body = new Uint8Array(request.body);\n      }\n    }\n\n    // priority is ignored in this stub\n\n    fetch(request.url, {\n      method: request.method,         // string literal from const enum\n      headers: headersObj,\n      body,\n      signal: abortCtrl?.signal,\n    })\n      .then((res) => {\n        // Build response headers map\n        const respHeaders: StringMap<string> = {};\n        if (res.headers && typeof res.headers.forEach === \"function\") {\n          res.headers.forEach((value, key) => {\n            respHeaders[key] = value;\n          });\n        }\n\n        // Get body as bytes (optional)\n        return res.arrayBuffer()\n          .then((ab) => {\n            completeOnce({ headers: respHeaders, statusCode: res.status, body: new Uint8Array(ab) }, undefined);\n          })\n          .catch(() => {\n            // Some responses may not have a body\n            completeOnce({ headers: respHeaders, statusCode: res.status }, undefined);\n          });\n      })\n      .catch((err) => {\n        completeOnce(undefined, err);\n      });\n  } else {\n    // No fetch: deliver a tiny successful response on the next microtask\n    Promise.resolve().then(() =>\n      completeOnce({ headers: {}, statusCode: 200, body: new Uint8Array(0) }, undefined)\n    );\n  }\n\n  // Return cancel function\n  return () => {\n    done = true;\n    if (abortCtrl) {\n      try { abortCtrl.abort(); } catch { /* ignore */ }\n    }\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_http/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"lib\": [\"DOM\", \"ES2020\"],\n    \"module\": \"commonjs\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": true,\n    \"allowJs\": true\n  },\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_image_generator/BUILD.bazel",
    "content": "load(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"valdi_image_generator\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]),\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/drawing\",\n        \"@valdi//src/valdi_modules/src/valdi/file_system\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_standalone\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_image_generator/module.yaml",
    "content": "dependencies:\n  - drawing\n  - file_system\n  - valdi_core\n  - valdi_standalone\n\noutput_target: debug\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_image_generator/src/ImageGenerator.ts",
    "content": "import { createBitmap } from 'drawing/src/BitmapFactory';\nimport { BitmapAlphaType, BitmapColorType, BitmapInfo, IBitmap, ImageEncoding } from 'drawing/src/IBitmap';\nimport { createManagedContext } from 'drawing/src/ManagedContextFactory';\nimport { beginKeepAlive, endKeepAlive } from 'valdi_core/src/utils/KeepAliveCallback';\nimport { onIdleInterruptible } from 'valdi_core/src/utils/OnIdle';\n\nfunction waitForIdle(): Promise<void> {\n  return new Promise(resolve => {\n    onIdleInterruptible(resolve);\n  });\n}\n\nfunction withKeepAlive(cb: () => Promise<void>): Promise<void> {\n  let keepAlive = beginKeepAlive();\n  return cb().finally(() => endKeepAlive(keepAlive));\n}\n\n/**\n * Evaluate a render function and render it as a bitmap with the provided BitmapInfo\n */\nexport async function renderAsBitmap(bitmapInfo: BitmapInfo, renderFn: () => void): Promise<IBitmap> {\n  const context = createManagedContext();\n  context.render(renderFn);\n  await context.layout(bitmapInfo.width, bitmapInfo.height, false);\n\n  await withKeepAlive(async () => {\n    await waitForIdle();\n    await context.onAllAssetsLoaded();\n  });\n\n  try {\n    const { frame } = await context.draw();\n\n    const bitmap = createBitmap(bitmapInfo);\n    frame.rasterInto(bitmap, true);\n    frame.dispose();\n\n    return bitmap;\n  } finally {\n    context.dispose();\n  }\n}\n\nexport interface GenerateImageParams {\n  width: number;\n  height: number;\n  imageEncoding: ImageEncoding;\n  encodeQuality: number;\n}\n\n/**\n * Evaluate a render function function and render it as an encoded image with the given generate params\n */\nexport async function renderImage(params: GenerateImageParams, renderFn: () => void): Promise<ArrayBuffer> {\n  const bitmap = await renderAsBitmap(\n    {\n      width: params.width,\n      height: params.height,\n      colorType: BitmapColorType.RGBA8888,\n      alphaType: BitmapAlphaType.Premul,\n      rowBytes: params.width * 4,\n    },\n    renderFn,\n  );\n\n  return bitmap.encode(params.imageEncoding, params.encodeQuality);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_image_generator/src/main.ts",
    "content": "import { ImageEncoding } from 'drawing/src/IBitmap';\nimport { ArgumentsParser } from 'valdi_standalone/src/ArgumentsParser';\nimport { getStandaloneRuntime } from 'valdi_standalone/src/ValdiStandalone';\nimport { renderImage } from './ImageGenerator';\nimport { fs } from 'file_system/src/FileSystem';\n\nexport function imageGeneratorMain(renderFn: () => void) {\n  const argumentsParser = new ArgumentsParser('valdi_image_generator', getStandaloneRuntime().arguments);\n  const width = argumentsParser.addNumber('--width', 'The width of the generated image', true);\n  const height = argumentsParser.addNumber('--height', 'The heigt of the generated image', true);\n  const output = argumentsParser.addString('--output', 'The output file of the image', true);\n  const format = argumentsParser.addString('--format', 'The image format, can be either png, webp or jpg', true);\n  const quality = argumentsParser.addNumber('--quality', 'The image quality', true);\n\n  argumentsParser.parse();\n\n  let resolvedFormat: ImageEncoding;\n\n  if (format.value === 'png') {\n    resolvedFormat = ImageEncoding.PNG;\n  } else if (format.value == 'webp') {\n    resolvedFormat = ImageEncoding.WEB;\n  } else if (format.value == 'png') {\n    resolvedFormat = ImageEncoding.PNG;\n  } else {\n    argumentsParser.printDescription();\n    throw new Error('Invalid image format');\n  }\n\n  renderImage(\n    {\n      width: width.value!,\n      height: height.value!,\n      imageEncoding: resolvedFormat,\n      encodeQuality: quality.value!,\n    },\n    renderFn,\n  )\n    .then(image => {\n      fs.writeFileSync(output.value!, image);\n    })\n    .catch(err => {\n      console.error(err);\n      getStandaloneRuntime().exit(1);\n    });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/BUILD.bazel",
    "content": "load(\"@valdi//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\nvaldi_module(\n    name = \"valdi_navigation\",\n    srcs = glob([\n        \"src/**/*.ts\",\n        \"src/**/*.tsx\",\n        \"test/**/*.ts\",\n        \"test/**/*.tsx\",\n    ]),\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiNavigation\",\n    ios_output_target = \"release\",\n    single_file_codegen = False,\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/foundation\",\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/module.yaml",
    "content": "dependencies:\n  - foundation\n  - valdi_core\n\noutput_target: release\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/src/INavigator.ts",
    "content": "// @NativeClass({ marshallAsUntyped: false, ios: 'SCValdiINavigatorPageConfig', iosImportPrefix: 'valdi_core', android: 'com.snap.valdi.navigation.INavigatorPageConfig'})\nexport interface INavigatorPageConfig {\n  componentPath: string;\n  componentViewModel: any;\n  componentContext: any;\n  showPlatformNavigationBar?: boolean;\n  wrapInPlatformNavigationController?: boolean;\n  platformNavigationTitle?: string;\n  // Keeps the source page partially visible.\n  isPartiallyHiding?: boolean;\n  // Android only: enable using the gesture touch adjustments\n  enableGestureAdjustCoordinates?: boolean;\n}\n\n/**\n * The visible state of the page in the navigation stack.\n */\nexport const enum INavigatorPageVisibility {\n  HIDDEN = 0,\n  VISIBLE = 1,\n}\n\n/**\n * The bridge interface that provides the implementation underlying all the operations exposed via NavigationController.\n * @NativeInterface({ marshallAsUntyped: false, ios: 'SCValdiINavigator', iosImportPrefix: 'valdi_core', android: 'com.snap.valdi.navigation.INavigator'})\n */\nexport interface INavigator {\n  pushComponent(page: INavigatorPageConfig, animated: boolean): void;\n  pop(animated: boolean): void;\n  popToRoot(animated: boolean): void;\n  popToSelf(animated: boolean): void;\n\n  presentComponent(page: INavigatorPageConfig, animated: boolean): void;\n  dismiss(animated: boolean): void;\n\n  forceDisableDismissalGesture(forceDisable: boolean): void;\n  setBackButtonObserver?(observer: (() => void) | undefined): void;\n  setOnPausePopAfterDelay?(delayMs: number | undefined): void;\n  setPageVisibilityObserver?(observer: ((visibility: INavigatorPageVisibility) => void) | undefined): void;\n}\n\n// this is a bit of a hack for the purposes of a JS-only navigator implementation that has\n// to prevent context and viewModel from being made opaque.\nexport interface JSOnlyINavigator {\n  __shouldDisableMakeOpaque?: boolean;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/src/NavigationComponent.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\nimport { INavigator } from './INavigator';\nimport { NavigationController, NavigationOptions } from './NavigationController';\n\nexport interface NavigationPageContext {\n  navigator: INavigator;\n  pageNavigationOptions?: NavigationOptions;\n}\n\nexport interface INavigationComponent extends IComponent {\n  navigationController: NavigationController;\n}\n\n/**\n * Resolves the NavigationController from the current component.\n * Will throw if the navigator cannot be resolved\n * @param component\n */\nexport function getNavigationController(component: IComponent): NavigationController {\n  const navigationComponent = getNavigationComponent(component);\n  return navigationComponent.navigationController;\n}\n\nexport function getNavigationComponent(component: IComponent): INavigationComponent {\n  const navigationComponent = component as INavigationComponent;\n  if (navigationComponent.navigationController) {\n    return navigationComponent;\n  }\n  const parent = component.renderer.getComponentParent(component);\n  if (!parent) {\n    throw new Error('Could not resolve navigator');\n  }\n  return getNavigationComponent(parent);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/src/NavigationController.ts",
    "content": "import { ComponentConstructor, IComponent } from 'valdi_core/src/IComponent';\nimport { makePropertiesOpaque, WithOpaqueProperties } from 'foundation/src/makePropertiesOpaque';\nimport { INavigator, INavigatorPageConfig, INavigatorPageVisibility, JSOnlyINavigator } from './INavigator';\n\ntype WithComponentPath<T> = T & { componentPath: string };\n\nexport interface NavigationOptions extends InternalNavigationOptions {\n  /**\n   * Whether to animate the transition.\n   */\n  animated?: boolean;\n\n  /**\n   * The page container's background color. Will be SemanticColor.Background.MAIN by default.\n   */\n  pageBackgroundColor?: string;\n\n  /** Whether to keep the source page partially visible. */\n  isPartiallyHiding?: boolean;\n}\n\nexport interface NavigationPushOptions extends NavigationOptions {}\n\nexport interface NavigationPresentOptions extends NavigationOptions {\n  /**\n   * iOS-only: Pass true here to make the container view controller that gets created for the presented page be wrapped\n   * in a UINavigationController instance before presenting. This is required if you'd like to use push/pop navigation operations\n   * from this presented page.\n   */\n  wrapInPlatformNavigationController?: boolean;\n}\n\nfunction verifyPage<T extends IComponent<ViewModel, Context>, ViewModel, Context>(\n  ctr: ComponentConstructor<T, ViewModel, Context>,\n): asserts ctr is WithComponentPath<typeof ctr> {\n  if (!(ctr as any).componentPath) {\n    throw new Error('Attempting to navigate with a Component that has not been decorated with @NavigationPage');\n  }\n}\n\nexport type BackButtonObserver = () => void;\nexport type PageVisibilityObserver = (visibility: INavigatorPageVisibility) => void;\n\ninterface OnPausePopAfterDelay {\n  delayMs: number | undefined;\n}\n\n/**\n * Components should use this class to perform various operations related to navigation, like easily presenting\n * some other Component as a new modal \"page\".\n */\nexport class NavigationController {\n  constructor(private navigator: INavigator) {\n    if (!navigator) {\n      throw new Error('Attempting to create a NavigationController with a missing navigator');\n    }\n  }\n\n  /**\n   * Pushes a Component as a new page onto the current navigation stack.\n   *\n   * Important: on iOS this requires the containing view controller to be within a UINavigationController.\n   * In the future we'll have SIGPresentation/mochi manage this automatically.\n   *\n   * @param componentClass The Component class that describes the pushed page. Must be annotated with the NavigationPage annotation.\n   * @param viewModel View model to pass into the component when it's created.\n   * @param context Context to pass into the component when it's created. A `navigator: INavigator` will be injected automatically, you shouldn't pass it manually.\n   * @param options Misc. options to configure the transition and/or page.\n   */\n  push<ViewModel, Context, ProvidedContext extends Omit<Context, 'navigator'>>(\n    componentClass: ComponentConstructor<IComponent<ViewModel, Context>, ViewModel, Context>,\n    viewModel: ViewModel,\n    context: ProvidedContext,\n    options: NavigationPushOptions = { animated: true },\n  ) {\n    const page = this.makePage(componentClass, viewModel, context, options);\n    this.navigator.pushComponent(page, options.animated ?? true);\n  }\n\n  /**\n   * Goes back one step in the current navigation stack.\n   *\n   * Important: on iOS this requires the containing view controller to be within a UINavigationController.\n   * In the future we'll have the default navigator manage this automatically using SIGPresentation/mochi.\n   */\n  pop(animated: boolean = true) {\n    this.navigator.pop(animated);\n  }\n\n  /**\n   * Unwinds the navigation stack to the page that is managed by this INavigator instance.\n   *\n   * Important: on iOS this requires the containing view controller to be within a UINavigationController.\n   * In the future we'll have the default navigator manage this automatically using SIGPresentation/mochi.\n   */\n  popToSelf(animated: boolean = true) {\n    this.navigator.popToSelf(animated);\n  }\n\n  /**\n   * Unwinds the navigation stack to the root page.\n   *\n   * Important: on iOS this requires the containing view controller to be within a UINavigationController.\n   * In the future we'll have the default navigator manage this automatically using SIGPresentation/mochi.\n   */\n  popToRoot(animated: boolean = true) {\n    this.navigator.popToRoot(animated);\n  }\n\n  /**\n   * Presents a Component using a modal presentation.\n   *\n   * @param componentClass The Component class that describes the presented page. Must be annotated with the NavigationPage annotation.\n   * @param viewModel View model to pass into the component when it's created.\n   * @param context Context to pass into the component when it's created. A `navigator: INavigator` will be injected automatically, you shouldn't pass it manually.\n   * @param options Misc. options to configure the transition and/or page.\n   */\n  present<ViewModel, Context, ProvidedContext extends Omit<Context, 'navigator'>>(\n    componentClass: ComponentConstructor<IComponent<ViewModel, Context>, ViewModel, Context>,\n    viewModel: ViewModel,\n    context: ProvidedContext,\n    options: NavigationPresentOptions = { animated: true },\n  ) {\n    const page = this.makePage(componentClass, viewModel, context, options);\n    page.wrapInPlatformNavigationController = options.wrapInPlatformNavigationController ?? true;\n    this.navigator.presentComponent(page, options.animated ?? true);\n  }\n\n  /**\n   * Dismisses the Component that was presenting using a modal presentation (and any Components that it might've presented too).\n   */\n  dismiss(animated: boolean) {\n    this.navigator.dismiss(animated);\n  }\n\n  private makePage<\n    T extends IComponent<ViewModel, Context>,\n    ViewModel,\n    Context,\n    ProvidedContext extends Omit<Context, 'navigator'>,\n  >(\n    componentClass: ComponentConstructor<T, ViewModel, Context>,\n    viewModel: ViewModel,\n    context: ProvidedContext,\n    options: NavigationOptions,\n  ): INavigatorPageConfig {\n    const componentCtr = componentClass;\n    let processedViewModel: ViewModel | WithOpaqueProperties<ViewModel>;\n    let processedContext: Context | WithOpaqueProperties<Context>;\n    if ((this.navigator as JSOnlyINavigator)?.__shouldDisableMakeOpaque) {\n      processedViewModel = viewModel;\n      const enhancedContext = { ...(context ?? {}), pageNavigationOptions: options };\n      processedContext = enhancedContext;\n    } else {\n      processedViewModel = makePropertiesOpaque(viewModel);\n      const enhancedContext = { ...context, pageNavigationOptions: options };\n      processedContext = makePropertiesOpaque(enhancedContext);\n    }\n\n    verifyPage(componentCtr);\n    return {\n      componentPath: componentCtr.componentPath,\n      componentViewModel: processedViewModel,\n      componentContext: processedContext,\n      showPlatformNavigationBar: options.showPlatformNavigationBar,\n      platformNavigationTitle: options.platformNavigationTitle,\n      isPartiallyHiding: options.isPartiallyHiding,\n    };\n  }\n\n  private disableDismissalCount = 0;\n  /**\n   * Disable the interactive dismissal gesture.\n   *\n   * Returns back a function that should be called to reenable the gesture back again.\n   *\n   * Note: This method maintains an internal count of how many \"disable\" requests are currently\n   * \"active\", since different parts of your UI logic might want to disable the gesture for\n   * different reasons. The interactive dismissal gesture will be reenabled once the count goes\n   * back down to zero.\n   */\n  disableDismissalGesture(): () => void {\n    this.disableDismissalCount += 1;\n    this.navigator.forceDisableDismissalGesture(true);\n    return () => {\n      this.disableDismissalCount -= 1;\n      const shouldReenable = this.disableDismissalCount === 0;\n      this.navigator.forceDisableDismissalGesture(!shouldReenable);\n    };\n  }\n\n  private backButtonObservers: BackButtonObserver[] = [];\n  private registeredNavigatorBackButtonObserver = false;\n\n  private updateNavigatorBackButtonObserverIfNeeded() {\n    if (this.backButtonObservers.length) {\n      if (!this.registeredNavigatorBackButtonObserver) {\n        this.registeredNavigatorBackButtonObserver = true;\n        if (this.navigator.setBackButtonObserver) {\n          this.navigator.setBackButtonObserver(this.onBackButtonPressed);\n        }\n      }\n    } else {\n      if (this.registeredNavigatorBackButtonObserver) {\n        this.registeredNavigatorBackButtonObserver = false;\n        if (this.navigator.setBackButtonObserver) {\n          this.navigator.setBackButtonObserver(undefined);\n        }\n      }\n    }\n  }\n\n  /**\n   * Android-only: Register a callback that can handle the back button press. Registering\n   * a callback will prevent the default handling of the back button press.\n   */\n  registerBackButtonObserver(observer: BackButtonObserver): () => void {\n    this.backButtonObservers.push(observer);\n    this.updateNavigatorBackButtonObserverIfNeeded();\n\n    return () => {\n      const index = this.backButtonObservers.indexOf(observer);\n      if (index >= 0) {\n        this.backButtonObservers.splice(index, 1);\n        this.updateNavigatorBackButtonObserverIfNeeded();\n      }\n    };\n  }\n\n  addPageVisibilityObserver(observer: PageVisibilityObserver) {\n    this.pageVisibilityObservers.add(observer);\n    if (!this.addedVisibilityObserver) {\n      // native will notify of the latest visibility upon setting the observer\n      this.navigator.setPageVisibilityObserver?.(this.onPageVisibilityChange);\n    } else if (this.latestVisibility !== undefined) {\n      // otherwise notify using the locally cached value\n      observer(this.latestVisibility);\n    }\n  }\n\n  removePageVisibilityObserver(observer: PageVisibilityObserver) {\n    this.pageVisibilityObservers.delete(observer);\n  }\n\n  private onBackButtonPressed = () => {\n    for (const observer of this.backButtonObservers) {\n      observer();\n    }\n  };\n\n  private onPageVisibilityChange = (visibility: INavigatorPageVisibility) => {\n    this.latestVisibility = visibility;\n    for (const observer of this.pageVisibilityObservers) {\n      observer(visibility);\n    }\n  };\n\n  private addedVisibilityObserver = false;\n  private latestVisibility: INavigatorPageVisibility | undefined;\n  private onPausePopAfterDelay: OnPausePopAfterDelay[] = [];\n  private currentOnPausePopAfterDelay: number | undefined;\n  private pageVisibilityObservers = new Set<PageVisibilityObserver>();\n\n  private updateOnPausePopAfterDelay() {\n    let newOnPausePopAfterDelay: number | undefined;\n    if (this.onPausePopAfterDelay.length) {\n      newOnPausePopAfterDelay = this.onPausePopAfterDelay[this.onPausePopAfterDelay.length - 1].delayMs;\n    }\n\n    if (newOnPausePopAfterDelay !== this.currentOnPausePopAfterDelay) {\n      this.currentOnPausePopAfterDelay = newOnPausePopAfterDelay;\n      if (this.navigator.setOnPausePopAfterDelay) {\n        this.navigator.setOnPausePopAfterDelay(newOnPausePopAfterDelay);\n      }\n    }\n  }\n\n  /**\n   * Android-only: Sets the number of millis that the screen will wait before being dismissed after the app has been backgrounded.\n   */\n  registerOnPausePopAfterDelay(delayMs: number | undefined): () => void {\n    const entry: OnPausePopAfterDelay = {\n      delayMs: delayMs,\n    };\n\n    this.onPausePopAfterDelay.push(entry);\n\n    this.updateOnPausePopAfterDelay();\n\n    return () => {\n      const index = this.onPausePopAfterDelay.indexOf(entry);\n      if (index >= 0) {\n        this.onPausePopAfterDelay.splice(index, 1);\n        this.updateOnPausePopAfterDelay();\n      }\n    };\n  }\n}\n\n////////////////////////////////////////////////////////////////\n\ninterface InternalNavigationOptions {\n  /**\n   * iOS and, really, internal-only: whether to show the standard iOS navigation bar\n   */\n  showPlatformNavigationBar?: boolean;\n  /**\n   * iOS and, really, internal-only: what title to display in the standard iOS navigation bar\n   */\n  platformNavigationTitle?: string;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/src/NavigationPage.ts",
    "content": "import { IComponent } from 'valdi_core/src/IComponent';\n\nexport type AnyFunction<A = any> = (...input: any[]) => A;\nexport type AnyConstructor<A = object> = new (...input: any[]) => A;\n\nexport type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>;\n\n/**\n * This annotation injects the componentPath static property into the class.\n *\n * The componentPath static property is used by the NavigationController to create an instance\n * of the class that a given page was configured with.\n */\nexport const NavigationPage =\n  (module: { path: string; exports: unknown }) =>\n  <T extends AnyConstructor<IComponent>>(base: T) => {\n    const newClass = class extends base {\n      static componentPath: string;\n    };\n\n    Object.defineProperty(newClass, 'componentPath', {\n      enumerable: false,\n      get() {\n        const exports = module.exports as any;\n        for (const exportedPropertyName in exports) {\n          const property = exports[exportedPropertyName];\n\n          if (newClass === property || Object.prototype.isPrototypeOf.call(newClass, property)) {\n            return `${exportedPropertyName}@${module.path}`;\n          }\n        }\n        throw new Error(`Could not resolve componentPath of ctor '${base.name}'`);\n      },\n    });\n    Object.defineProperty(newClass, 'name', { value: base.name });\n\n    return newClass;\n  };\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/src/NavigationPageComponent.ts",
    "content": "import { Component, StatefulComponent } from 'valdi_core/src/Component';\nimport { INavigator } from './INavigator';\nimport { NavigationController, NavigationOptions } from './NavigationController';\nimport { INavigationComponent, NavigationPageContext } from './NavigationComponent';\n\n/**\n * Subclass this component and implement `onRenderPageContent` instead of `onRender` to render the page content.\n */\nexport abstract class NavigationPageComponent<\n    ViewModel,\n    ComponentContext extends NavigationPageContext = {\n      navigator: INavigator;\n    },\n  >\n  extends Component<ViewModel, ComponentContext>\n  implements INavigationComponent\n{\n  static componentPath: string;\n  navigationController: NavigationController = new NavigationController(this.context.navigator);\n}\n\n/**\n * Subclass this component and implement `onRenderPageContent` instead of `onRender` to render the page content.\n */\nexport abstract class NavigationPageStatefulComponent<\n    ViewModel,\n    State,\n    ComponentContext extends NavigationPageContext = {\n      navigator: INavigator;\n    },\n  >\n  extends StatefulComponent<ViewModel, State, ComponentContext>\n  implements INavigationComponent\n{\n  static componentPath: string;\n  navigationController: NavigationController = new NavigationController(this.context.navigator);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/src/NavigationRoot.tsx",
    "content": "import { Component } from 'valdi_core/src/Component';\nimport { NavigationPageContext } from 'valdi_navigation/src/NavigationComponent';\nimport { NavigationController } from 'valdi_navigation/src/NavigationController';\nimport { INavigator } from './INavigator';\nimport { NavigationView } from './NavigationView';\nimport { $slot } from 'valdi_core/src/CompilerIntrinsics';\n\nexport interface NavigationRootViewModel {\n  children?: (navigationController: NavigationController) => void;\n}\n\nexport class NavigationRoot extends Component<NavigationRootViewModel, NavigationPageContext> {\n  private _navigationController?: NavigationController;\n\n  private renderChildrenWithNavigator(navigator: INavigator) {\n    if (!this._navigationController) {\n      this._navigationController = new NavigationController(navigator);\n    }\n    this.viewModel?.children?.(this._navigationController);\n  }\n\n  onRender(): void {\n    if (this.context?.navigator) {\n      this.renderChildrenWithNavigator(this.context.navigator);\n    } else {\n      <NavigationView>\n        {$slot(navigator => {\n          this.renderChildrenWithNavigator(navigator);\n        })}\n      </NavigationView>;\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/src/NavigationView.tsx",
    "content": "import { StatefulComponent } from 'valdi_core/src/Component';\nimport { parseComponentPath, resolveComponentConstructor } from 'valdi_core/src/ComponentPath';\nimport { ComponentRef } from 'valdi_core/src/ComponentRef';\nimport { ElementRef } from 'valdi_core/src/ElementRef';\nimport { IComponent } from 'valdi_core/src/IComponent';\nimport { getModuleLoader } from 'valdi_core/src/ModuleLoaderGlobal';\nimport { Style } from 'valdi_core/src/Style';\nimport { DefaultErrorBoundary } from 'valdi_core/src/debugging/DefaultErrorBoundary';\nimport { onIdleInterruptible } from 'valdi_core/src/utils/OnIdle';\nimport { when } from 'valdi_core/src/utils/When';\nimport { SerialTaskQueue } from 'coreutils/src/SerialTaskQueue';\nimport { StringSet } from 'coreutils/src/StringSet';\nimport { Lazy } from 'foundation/src/Lazy';\nimport { INavigator, INavigatorPageConfig, JSOnlyINavigator } from './INavigator';\nimport { NavigationPageContext } from './NavigationComponent';\nimport { Layout, View } from 'valdi_tsx/src/NativeTemplateElements';\nimport { Device } from 'valdi_core/src/Device';\n\nexport interface NavigationViewContext {\n  hideBackButton: boolean;\n}\n\ninterface ReloadableComponentData {\n  componentPath: string;\n  viewModel: any;\n  context: any;\n}\n\ninterface ComponentStackEntry {\n  key: string;\n  renderFn: () => void;\n  reloadableData: ReloadableComponentData | undefined;\n  title: string;\n  ref: ComponentRef<IComponent>;\n  viewContainerRef: ElementRef<View>;\n  occlusionViewRef: ElementRef<View>;\n  navigator: INavigator;\n  hotReloadObserver: (() => void) | undefined;\n  isModal: boolean;\n  isTransparent: boolean;\n}\n\ninterface State {\n  stack: ComponentStackEntry[];\n}\n\nconst ANIMATION_DURATION = 0.25;\n\nconst enum AnimationType {\n  MODAL,\n  PUSH_POP,\n}\n\nexport interface NavigationViewModel {\n  children?: (navigator: INavigator) => void;\n}\n\nexport class NavigationView extends StatefulComponent<NavigationViewModel, State, NavigationViewContext> {\n  state: State = { stack: [] };\n\n  private keySequence = 0;\n  private scheduledRebuild = false;\n  private hotReloadedComponents: StringSet = {};\n  private containerRef = new ElementRef<Layout>();\n  private taskQueue = new SerialTaskQueue();\n\n  onCreate() {\n    const key = (++this.keySequence).toString();\n    const navigator = new NavigationViewNavigator(this);\n    const entry: ComponentStackEntry = {\n      key,\n      reloadableData: undefined,\n      renderFn: () => {\n        this.viewModel.children?.(navigator);\n      },\n      title: '',\n      isModal: false,\n      hotReloadObserver: undefined,\n      navigator,\n      ref: new ComponentRef(),\n      viewContainerRef: new ElementRef(),\n      occlusionViewRef: new ElementRef(),\n      isTransparent: false,\n    };\n\n    this.appendEntry(entry, false);\n\n    Device.setBackButtonObserver(this.onBackButtonPressed);\n  }\n\n  onDestroy() {\n    Device.setBackButtonObserver(undefined);\n\n    for (const item of this.state.stack) {\n      this.teardownStackEntry(item);\n    }\n  }\n\n  onRender() {\n    <view backgroundColor=\"white\" width={'100%'} height={'100%'}>\n      <layout style={style.itemContainer} ref={this.containerRef}>\n        {this.renderNavigationStack()}\n      </layout>\n    </view>;\n  }\n\n  private onBackButtonPressed = () => {\n    this.pop(true);\n    return true;\n  }\n\n  private renderNavigationStack() {\n    const topItem = this.getCurrentItem();\n    for (const item of this.state.stack) {\n      <view key={item.key} style={style.item} ref={item.viewContainerRef}>\n        <DefaultErrorBoundary>\n          {item.renderFn()}\n          {this.setupItem(item.ref)}\n        </DefaultErrorBoundary>\n        {when(item !== topItem, () => {\n          <view style={style.occlusionOverlay} ref={item.occlusionViewRef} />;\n        })}\n      </view>;\n    }\n  }\n\n  private setupItem(ref: ComponentRef<IComponent>) {\n    const component = ref.single();\n    if (!component) {\n      return;\n    }\n\n    const elements = this.renderer.getComponentRootElements(component, false);\n    for (const element of elements) {\n      element.setAttribute('$width', '100%');\n      element.setAttribute('$height', '100%');\n    }\n  }\n\n  private getCurrentItem(): ComponentStackEntry {\n    return this.state.stack[this.state.stack.length - 1];\n  }\n\n  pushComponent(\n    componentPath: string,\n    viewModel: any,\n    context: any,\n    title: string,\n    isModal: boolean,\n    isTransparent: boolean,\n    animated: boolean,\n  ) {\n    const newEntry = this.makeEntry(componentPath, viewModel, context, title, isModal, isTransparent);\n\n    this.appendEntry(newEntry, animated);\n  }\n\n  private appendEntry(newEntry: ComponentStackEntry, animated: boolean) {\n    this.taskQueue.enqueueTask(done => {\n      if (animated && this.state.stack.length > 0) {\n        const previousEntry = this.getCurrentItem();\n\n        // Render with the item at the right\n        this.renderer.batchUpdates(() => {\n          this.setState({ stack: [...this.state.stack, newEntry] });\n\n          this.applyTransitionFromState(previousEntry, AnimationType.PUSH_POP, [newEntry]);\n        });\n\n        // eslint-disable-next-line @typescript-eslint/no-floating-promises\n        this.animatePromise({ duration: ANIMATION_DURATION }, () => {\n          this.applyTransitionToState(previousEntry, [newEntry]);\n        }).then(() => {\n          this.updateStackNonAnimated(this.state.stack);\n          done();\n        });\n      } else {\n        this.updateStackNonAnimated([...this.state.stack, newEntry]);\n        done();\n      }\n    });\n  }\n\n  private applyTransitionFromState(\n    leftEntry: ComponentStackEntry,\n    animationType: AnimationType,\n    rightEntries: ComponentStackEntry[],\n  ) {\n    const containerFrame = this.containerRef.single()!.frame;\n\n    for (const rightEntry of rightEntries) {\n      rightEntry.viewContainerRef.setAttribute('opacity', 1.0);\n\n      switch (animationType) {\n        case AnimationType.PUSH_POP:\n          if (rightEntry.isModal) {\n            rightEntry.viewContainerRef.setAttribute('translationY', containerFrame.height);\n          } else {\n            rightEntry.viewContainerRef.setAttribute('translationX', containerFrame.width);\n          }\n          break;\n        case AnimationType.MODAL:\n          rightEntry.viewContainerRef.setAttribute('translationY', containerFrame.height);\n          break;\n      }\n    }\n\n    leftEntry.viewContainerRef.setAttribute('opacity', 1.0);\n    leftEntry.viewContainerRef.setAttribute('translationX', 0);\n    leftEntry.occlusionViewRef.setAttribute('opacity', 0);\n  }\n\n  private applyTransitionToState(leftEntry: ComponentStackEntry, rightEntries: ComponentStackEntry[]) {\n    const containerFrame = this.containerRef.single()!.frame;\n\n    let hasModal = false;\n    for (const rightEntry of rightEntries) {\n      rightEntry.viewContainerRef.setAttribute('opacity', 1.0);\n\n      if (rightEntry.isModal) {\n        hasModal = true;\n        rightEntry.viewContainerRef.setAttribute('translationY', 0);\n      } else {\n        rightEntry.viewContainerRef.setAttribute('translationX', 0);\n      }\n    }\n\n    leftEntry.viewContainerRef.setAttribute('opacity', 1.0);\n\n    if (hasModal) {\n      leftEntry.viewContainerRef.setAttribute('translationX', 0);\n    } else {\n      leftEntry.viewContainerRef.setAttribute('translationX', -containerFrame.width / 6);\n    }\n\n    leftEntry.occlusionViewRef.setAttribute('opacity', 1.0);\n  }\n\n  private makeEntry(\n    componentPath: string,\n    viewModel: any,\n    context: any,\n    title: string,\n    isModal: boolean,\n    isTransparent: boolean,\n  ): ComponentStackEntry {\n    const parsedComponentPath = parseComponentPath(componentPath);\n    const moduleLoader = getModuleLoader();\n    const requireFunc = moduleLoader.load.bind(moduleLoader);\n    const ctor = new Lazy(() => resolveComponentConstructor(requireFunc, parsedComponentPath));\n\n    const hotReloadObserver = getModuleLoader().onHotReload(module, parsedComponentPath.filePath, () => {\n      this.hotReloadedComponents[componentPath] = true;\n\n      if (!this.scheduledRebuild) {\n        this.scheduledRebuild = true;\n\n        onIdleInterruptible(() => {\n          if (this.isDestroyed()) {\n            return;\n          }\n\n          this.scheduledRebuild = false;\n          this.rebuildStack();\n        });\n      }\n    });\n\n    const key = (++this.keySequence).toString();\n\n    const navigator = new NavigationViewNavigator(this);\n    const contextWithNavigator = { ...context, navigator };\n\n    const ref = new ComponentRef();\n    const renderFn = () => {\n      <ctor.target context={contextWithNavigator} ref={ref} {...viewModel} />;\n    };\n\n    return {\n      key,\n      reloadableData: {\n        componentPath,\n        viewModel,\n        context: contextWithNavigator,\n      },\n      renderFn,\n      title,\n      isModal,\n      hotReloadObserver,\n      navigator,\n      ref,\n      viewContainerRef: new ElementRef(),\n      occlusionViewRef: new ElementRef(),\n      isTransparent,\n    };\n  }\n\n  private indexOfNavigator(navigator: INavigator): number {\n    for (let i = 0; i < this.state.stack.length; i++) {\n      const entry = this.state.stack[i];\n      if (entry.navigator === navigator) {\n        return i;\n      }\n    }\n\n    return -1;\n  }\n\n  popToNavigator(navigator: INavigator, animated: boolean) {\n    this.taskQueue.enqueueTask(done => {\n      const index = this.indexOfNavigator(navigator);\n      if (index > 0) {\n        this.doPop(this.state.stack[index], AnimationType.PUSH_POP, animated, done);\n      } else {\n        done();\n      }\n    });\n  }\n\n  dismissNavigator(navigator: INavigator, animated: boolean) {\n    this.taskQueue.enqueueTask(done => {\n      let index = this.indexOfNavigator(navigator);\n\n      if (index < 0) {\n        done();\n        return;\n      }\n\n      while (index > 0 && !this.state.stack[index].isModal) {\n        index--;\n      }\n\n      this.doPop(this.state.stack[index], AnimationType.MODAL, animated, done);\n    });\n  }\n\n  pop(animated: boolean) {\n    this.taskQueue.enqueueTask(done => {\n      if (this.state.stack.length > 1) {\n        const itemToRemove = this.getCurrentItem();\n        this.doPop(itemToRemove, AnimationType.PUSH_POP, animated, done);\n      }\n    });\n  }\n\n  private doPop(atItem: ComponentStackEntry, animationType: AnimationType, animated: boolean, done: () => void) {\n    const itemsToRemove: ComponentStackEntry[] = [];\n    const itemIndex = this.state.stack.indexOf(atItem);\n    const newTopItem = this.state.stack[itemIndex - 1];\n\n    for (let i = itemIndex; i < this.state.stack.length; i++) {\n      itemsToRemove.push(this.state.stack[i]);\n    }\n\n    for (const itemToRemove of itemsToRemove) {\n      this.teardownStackEntry(itemToRemove);\n    }\n\n    if (animated) {\n      this.renderer.batchUpdates(() => {\n        this.applyTransitionToState(newTopItem, itemsToRemove);\n      });\n\n      // eslint-disable-next-line @typescript-eslint/no-floating-promises\n      this.animatePromise({ duration: ANIMATION_DURATION }, () => {\n        this.applyTransitionFromState(newTopItem, animationType, itemsToRemove);\n      }).then(() => {\n        const index = this.state.stack.indexOf(atItem);\n        if (index >= 0) {\n          const newStack = this.state.stack.slice(0, itemIndex);\n          this.updateStackNonAnimated(newStack);\n        }\n        done();\n      });\n    } else {\n      this.updateStackNonAnimated(this.state.stack.slice(0, itemIndex));\n      done();\n    }\n  }\n\n  private teardownStackEntry(entry: ComponentStackEntry) {\n    entry.hotReloadObserver?.();\n  }\n\n  private rebuildStack() {\n    const newStack: ComponentStackEntry[] = [];\n\n    for (const entry of this.state.stack) {\n      if (entry.reloadableData && this.hotReloadedComponents[entry.reloadableData.componentPath]) {\n        this.teardownStackEntry(entry);\n        newStack.push(\n          this.makeEntry(\n            entry.reloadableData.componentPath,\n            entry.reloadableData.viewModel,\n            entry.reloadableData.context,\n            entry.title,\n            entry.isModal,\n            entry.isTransparent,\n          ),\n        );\n      } else {\n        newStack.push(entry);\n      }\n    }\n\n    this.hotReloadedComponents = {};\n\n    this.updateStackNonAnimated(newStack);\n  }\n\n  private updateStackNonAnimated(newStack: ComponentStackEntry[]) {\n    this.renderer.batchUpdates(() => {\n      this.setState({ stack: newStack });\n\n      const activeItem = this.getCurrentItem();\n\n      const stack = this.state.stack;\n      let index = stack.length;\n      let previousIsTransparent = false;\n      while (index > 0) {\n        index--;\n\n        const item = stack[index];\n        if (item === activeItem || previousIsTransparent) {\n          item.viewContainerRef.setAttribute('translationX', 0);\n          item.viewContainerRef.setAttribute('opacity', 1.0);\n          previousIsTransparent = item.isTransparent;\n        } else {\n          const containerWidth = this.containerRef.single()!.frame.width;\n          // Put the container outside of bounds so its not inflated\n          item.viewContainerRef.setAttribute('translationX', containerWidth * 10000);\n          item.viewContainerRef.setAttribute('opacity', 0.0);\n          previousIsTransparent = false;\n        }\n      }\n    });\n  }\n}\n\nconst style = {\n  itemContainer: new Style<Layout>({\n    width: '100%',\n    flexGrow: 1,\n  }),\n  item: new Style<View>({\n    position: 'absolute',\n    width: '100%',\n    height: '100%',\n  }),\n  occlusionOverlay: new Style<View>({\n    backgroundColor: 'rgba(0, 0, 0, 0.2)',\n    position: 'absolute',\n    width: '100%',\n    height: '100%',\n  }),\n};\n\nclass NavigationViewNavigator implements INavigator, JSOnlyINavigator {\n  constructor(private navigationView: NavigationView) {}\n\n  // tslint:disable-next-line: variable-name\n  __shouldDisableMakeOpaque = true;\n\n  private hasTransparentBackground(page: INavigatorPageConfig): boolean {\n    const componentContext = page.componentContext as NavigationPageContext;\n    if (!componentContext) {\n      return false;\n    }\n    return componentContext.pageNavigationOptions?.pageBackgroundColor === 'transparent';\n  }\n\n  pushComponent(page: INavigatorPageConfig, animated: boolean): void {\n    this.navigationView.pushComponent(\n      page.componentPath,\n      page.componentViewModel,\n      page.componentContext,\n      page.platformNavigationTitle ?? '',\n      /* isModal */ false,\n      this.hasTransparentBackground(page),\n      animated,\n    );\n  }\n\n  pop(animated: boolean): void {\n    this.navigationView.popToNavigator(this, animated);\n  }\n\n  popToRoot(animated: boolean): void {\n    // TODO: Actual implementation. Could pop until the next isModal (without including it)\n    throw new Error('popToRoot is not currently implemented in the desktop app navigation');\n  }\n\n  popToSelf(animated: boolean): void {\n    // TODO: Actual implementation.\n    throw new Error('popToSelf is not currently implemented in the desktop app navigation');\n  }\n\n  presentComponent(page: INavigatorPageConfig, animated: boolean): void {\n    this.navigationView.pushComponent(\n      page.componentPath,\n      page.componentViewModel,\n      page.componentContext,\n      page.platformNavigationTitle ?? '',\n      /* isModal */ true,\n      this.hasTransparentBackground(page),\n      animated,\n    );\n  }\n\n  dismiss(animated: boolean): void {\n    this.navigationView.dismissNavigator(this, animated);\n  }\n\n  forceDisableDismissalGesture(forceDisable: boolean): void {\n    console.error('forceDisableDismissalGesture is not implemented in the desktop app navigation');\n  }\n\n  setBackButtonObserver(observer: (() => void) | undefined): void {\n    // setBackButtonObserver is not implemented in the desktop app navigation\n  }\n\n  setOnPausePopAfterDelay(delayMs: number | undefined): void {\n    // setOnPausePopAfterDelay is not implemented in the desktop app navigation\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_navigation/tsconfig.json",
    "content": "{\n  \"extends\": \"../_configs/base.tsconfig.json\",\n  \"compilerOptions\": {\n    \"noImplicitReturns\": true,\n    \"noImplicitAny\": true,\n    \"strict\": true,\n    \"jsx\": \"preserve\",\n    \"paths\": {\n      \"valdi_navigation/*\": [\"./*\"],\n      \"foundation/*\": [\"../foundation/*\"],\n      \"valdi_core/*\": [\"../valdi_core/*\"],\n      \"coreutils/*\": [\"../coreutils/*\"],\n      \"valdi_tsx/*\": [\"../valdi_tsx/*\"],\n      \"valdi_test/*\": [\"../valdi_test/*\"]\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/BUILD.bazel",
    "content": "load(\"@aspect_rules_js//js:defs.bzl\", \"js_library\", \"js_test\")\nload(\"@aspect_rules_ts//ts:defs.bzl\", \"ts_project\")\nload(\"@valdi_npm//:defs.bzl\", \"npm_link_all_packages\")\nload(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\n# Symlink parent src type definitions into web directory so they're accessible at ../src/\ngenrule(\n    name = \"web_src_types\",\n    srcs = [\n        \"src/types.d.ts\",\n        \"src/ValdiProtobuf.d.ts\",\n    ],\n    outs = [\n        \"web/src_symlink/types.d.ts\",\n        \"web/src_symlink/ValdiProtobuf.d.ts\",\n    ],\n    cmd = \"cp $(SRCS) $(@D)/web/src_symlink/\",\n)\n\n# Web code - production and tests compiled together\nts_project(\n    name = \"valdi_protobuf_web_compiled\",\n    srcs = glob(\n        [\n            \"web/**/*.ts\",\n            \"web/**/*.d.ts\",\n        ],\n        exclude = [\n            \"**/*.js\",\n            \"web/node_modules/**\",\n            \"web/src_symlink/**\",  # Exclude the generated symlink\n        ],\n    ) + [\n        \":web_src_types\",\n    ],\n    allow_js = True,\n    composite = True,\n    declaration = True,\n    out_dir = \"web\",\n    resolve_json_module = True,\n    root_dir = \"web\",\n    supports_workers = -1,\n    transpiler = \"tsc\",\n    tsconfig = \"web/tsconfig.json\",\n    deps = [\n        \"//bzl/valdi/npm:node_modules/@protobuf-ts/runtime\",\n    ],\n)\n\n# Expose compiled files at web/ path for valdi_module consumption\njs_library(\n    name = \"valdi_protobuf_web\",\n    srcs = [\":valdi_protobuf_web_compiled\"],\n    visibility = [\"//visibility:public\"],\n)\n\n# Export proto files for web tests\njs_library(\n    name = \"proto_files\",\n    srcs = [\"test/proto.protodecl\"],\n)\n\nvaldi_module(\n    name = \"valdi_protobuf\",\n    srcs = glob(\n        [\n            \"src/**/*.js\",\n            \"src/**/*.ts\",\n            \"src/**/*.tsx\",\n            \"test/**/*.js\",\n            \"test/**/*.ts\",\n            \"test/**/*.tsx\",\n        ],\n        exclude = [\n            \"**/scripts/**\",\n            \"**/proto/**\",\n            \"**/headless/**\",  # web-only code, included via web_deps\n        ],\n    ) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    ios_module_name = \"SCCValdiProtobuf\",\n    ios_output_target = \"release\",\n    module_yaml = \"module.yaml\",\n    protodecl_srcs = [\"test/proto.protodecl\"],\n    single_file_codegen = False,\n    visibility = [\"//visibility:public\"],\n    web_deps = [\":valdi_protobuf_web\"],\n    web_register_native_module_id_overrides = {\n        # Runtime looks up by valdi_core path when loaded from protodecl; ValdiProtobufModule also require('ValdiProtobuf')\n        \"valdi_protobuf/web/ValdiProtobuf.js\": \"valdi_core/src/ValdiProtobuf,ValdiProtobuf\",\n    },\n    deps = [\n        \"//src/valdi_modules/src/valdi/coreutils\",\n        \"//src/valdi_modules/src/valdi/valdi_core\",\n        \"//src/valdi_modules/src/valdi/valdi_standalone\",\n    ],\n)\n\n# Link npm packages for web build and tests\nnpm_link_all_packages(name = \"node_modules\")\n\n# Web tests - require npm packages so only work in valdi workspace\njs_test(\n    name = \"valdi_protobuf_web_test\",\n    data = [\n        \":node_modules/jest\",\n        \":proto_files\",\n        \":valdi_protobuf_web_compiled\",\n    ],\n    entry_point = \"web/test/run_tests.js\",\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/module.yaml",
    "content": "bazel_build_file_generation_disabled: true\n\nweb:\n  version: 1.0.3\n  publish_config: '{ \"@snapchat:registry\": \"https://registry.npmjs.org/\"\n    }'\n  main: src/Arena.js\n  scope: snapchat\n\ndependencies:\n  - coreutils\n  - valdi_core\n  - valdi_standalone\nexclude_patterns:\n  - .*\\/scripts\\/.*\n  - .*\\/proto\\/.*\n  - .*\\/web\\/.*\n  - .*\\/node_modules\\/.*\nexclude_globs:\n  - \"**/scripts/**\"\n  - \"**/proto/**\"\n  - \"**/web/**\"\n  - \"**/node_modules/**\"\n\noutput_target: release\n\nallowed_debug_dependencies:\n  - valdi_standalone\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/package.json",
    "content": "{\n  \"name\": \"valdi_protobuf\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Protobuf support for Valdi\",\n  \"dependencies\": {\n    \"@types/jest\": \"^29.5.14\",\n    \"jest\": \"^29.7.0\"\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/proto/test.proto",
    "content": "syntax = \"proto3\";\npackage test;\n\nimport \"module/test3.proto\";\n\nenum Enum {\n  VALUE_0 = 0;\n  VALUE_1 = 1;\n}\n\n/**\nTest\nmultiline\ncomment\n*/\nmessage OtherMessage {\n  string value = 1;\n}\n\n// Test comment\n// another line\nmessage Message {\n  int32 int32 = 1;\n  int64 int64 = 2;\n  uint32 uint32 = 3;\n  uint64 uint64 = 4;\n  sint32 sint32 = 5;\n  sint64 sint64 = 6;\n  fixed32 fixed32 = 7;\n  fixed64 fixed64 = 8;\n  sfixed32 sfixed32 = 9;\n  sfixed64 sfixed64 = 10;\n  float float = 11;\n  double double = 12;\n  bool bool = 13;\n  string string = 14;\n  bytes bytes = 15;\n  Enum enum = 16;\n  Message self_message = 17;\n  OtherMessage other_message = 18;\n}\n\nmessage RepeatedMessage {\n  repeated int32 int32 = 1;\n  repeated int64 int64 = 2;\n  repeated uint32 uint32 = 3;\n  repeated uint64 uint64 = 4;\n  repeated sint32 sint32 = 5;\n  repeated sint64 sint64 = 6;\n  repeated fixed32 fixed32 = 7;\n  repeated fixed64 fixed64 = 8;\n  repeated sfixed32 sfixed32 = 9;\n  repeated sfixed64 sfixed64 = 10;\n  repeated float float = 11;\n  repeated double double = 12;\n  repeated bool bool = 13;\n  repeated string string = 14;\n  repeated bytes bytes = 15;\n  repeated Enum enum = 16;\n  repeated RepeatedMessage self_message = 17;\n  repeated OtherMessage other_message = 18;\n}\n\nmessage ParentMessage {\n  ChildMessage child_message = 1;\n  ChildEnum child_enum = 2;\n\n  message ChildMessage {\n    string value = 1;\n  }\n\n  // Comment for child enum\n  enum ChildEnum {\n    // Comment for value 0\n    VALUE_0 = 0;\n    // Comment for value 1\n    VALUE_1 = 1;\n  }\n}\n\nmessage OneOfMessage {\n  oneof strings {\n    string string_0 = 1;\n    string string_1 = 2;\n  }\n  oneof messages {\n    OtherMessage message_0 = 3;\n    OtherMessage message_1 = 4;\n  }\n  oneof bytes {\n    bytes bytes_0 = 5;\n    bytes bytes_1 = 6;\n  }\n}\n\nmessage OldMessage {\n  string old_value = 1;\n}\nmessage NewMessage {\n  string old_value = 1;\n  string new_value = 2;\n}\n\nmessage OldEnumMessage {\n  enum OldEnum {\n    VALUE_0 = 0;\n    VALUE_1 = 1;\n  }\n  OldEnum value = 1;\n  repeated OldEnum repeated_value = 2;\n  map<string, OldEnum> mapped_value = 3;\n}\n\nmessage NewEnumMessage {\n  enum NewEnum {\n    VALUE_0 = 0;\n    VALUE_1 = 1;\n    VALUE_2 = 200;\n    VALUE_3 = 300;\n  }\n  NewEnum value = 1;\n  repeated NewEnum repeated_value = 2;\n  map<string, NewEnum> mapped_value = 3;\n}\n\nmessage MapMessage {\n  map<string, string> stringToString = 1;\n  map<string, int32> stringToNumber = 2;\n  map<string, int64> stringToSignedLong = 3;\n  map<string, uint64> stringToUnsignedLong = 4;\n  map<string, double> stringToDouble = 5;\n  map<string, OtherMessage> stringToMessage = 6;\n  map<int32, string> intToString = 7;\n  map<int64, string> longToString = 8;\n}\n\nmessage ExternalMessages {\n  test3.Message3 other_message = 1;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/proto/test2.proto",
    "content": "syntax = \"proto3\";\npackage test2;\n\nmessage Message2 {\n  string value = 1;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/proto/test3.proto",
    "content": "syntax = \"proto3\";\npackage test3;\n\nmessage Message3 {\n  string value = 1;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/proto/test4.proto",
    "content": "syntax = \"proto3\";\npackage package_with_underscores;\n\nmessage Message_With_Underscores {\n  int32 field_underscore = 1;\n  int32 field_underscore_again = 2;\n  Enum_With_Underscores enum_value = 3;\n  Message_With_Underscores message_value = 4;\n}\n\nenum Enum_With_Underscores {\n  ENUM_VALUE_0 = 0;\n  ENUM_VALUE_1 = 1;\n  E2NUM_VALUE_WITH_NUMBER = 2;\n}\n\nmessage M3ssage1WithNumb3r2 {\n  int32 fie1ld = 1;\n  int32 field2 = 2;\n  int32 field_3 = 3;\n  int32 a4_fiel4d = 4;\n  int32 a5a_fiel5d = 5;\n  Enum_With_Underscores enum = 6;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/scripts/generate_test_protos.py",
    "content": "#!/usr/bin/env python3\n\nimport argparse\nimport os\nimport subprocess\nfrom sys import platform\n\nSCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))\nPROTO_CONFIG_NAME = 'proto_config.yaml'\nMODULE_OUT_NAME = 'proto.js'\nDECLARATION_OUT_NAME = 'proto.d.ts'\nBIN_OUT_NAME = 'proto.protodecl'\nMODULE_NAME = 'valdi_protobuf'\n\nSCRIPTS_DIR = os.path.join(SCRIPT_DIR, '../../../../scripts')\nJS_V2_DIR = os.path.join(SCRIPTS_DIR, 'protobuf-native')\nJS_V2_INDEX_PATH = os.path.join(JS_V2_DIR, 'src/index.ts')\n\nPROTO_DIR = os.path.join(SCRIPT_DIR, 'snap_protos/src/proto')\n\nPROTOC_BIN_PATH = os.path.join(SCRIPT_DIR, '../../../tools/protoc')\n\ndef main():\n    parser = argparse.ArgumentParser()\n    args = parser.parse_args()\n\n    module_path = os.path.join(SCRIPT_DIR, '..')\n    filter_config_path = os.path.join(module_path, PROTO_CONFIG_NAME)\n    module_out = os.path.join(module_path, 'test', MODULE_OUT_NAME)\n    declaration_out = os.path.join(module_path, 'test', DECLARATION_OUT_NAME)\n    bin_out = os.path.join(module_path, 'test', BIN_OUT_NAME)\n    bin_relative_path = os.path.join(MODULE_NAME, 'test', BIN_OUT_NAME)\n\n    if not os.path.isfile(filter_config_path):\n        print('No proto config found for module \"{}\"'.format(args.module))\n        print('Add \"{}\" to the module root directory to enable proto generation'.format(PROTO_CONFIG_NAME))\n        return\n\n    js_dir = JS_V2_DIR\n    js_index_path = JS_V2_INDEX_PATH\n    node = os.path.join(JS_V2_DIR, 'node_modules', '.bin', 'ts-node')\n\n    subprocess.call(['npm', '--prefix', js_dir, 'install', js_dir])\n    subprocess.call([node, js_index_path, '--protoc-bin', PROTOC_BIN_PATH, '--proto-dir', PROTO_DIR, '--filter-config',\n                      filter_config_path, '--module-out', module_out, '--declaration-out', declaration_out,\n                      '--bin-out', bin_out, '--bin-relative-path', bin_relative_path])\n    print('Wrote \"{}\"'.format(os.path.relpath(module_out)))\n    print('Wrote \"{}\"'.format(os.path.relpath(declaration_out)))\n    print('Wrote \"{}\"'.format(os.path.relpath(bin_out)))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/Arena.ts",
    "content": "import { makeSingleCallInterruptibleCallback } from 'valdi_core/src/utils/FunctionUtils';\nimport { getProtobufModule } from './ValdiProtobufModule';\nimport { IArena, IMessage, IMessageConstructor, JSONPrintOptions } from './types';\nimport { ValdiProtobufModule, INativeMessageArena, INativeMessageIndex } from './ValdiProtobuf';\n\n/**\n * Specifies how the Arena should decode messages.\n */\nexport const enum DecodingMode {\n  /**\n   * Parsing will be eager, meaning that nested messages will be parsed immediately\n   * when the decode() call is made. This will provide worse performance than lazy,\n   * but will validate that the message could be decoded immediately.\n   * Use this option if you are decoding a message from an untrusted source, like\n   * a local disk cache. The arena will use the EAGER decoding mode when decoding\n   * a message asynchronously, even if LAZY is set.\n   *\n   * This is the default option.\n   */\n  EAGER = 0,\n\n  /**\n   * Parsing will be lazy, meaning that nested messages\n   * will be parsed when they are first accessed. This will provide\n   * the best performance if the TypeScript code does not visit\n   * every single sub messages that the decoded message contains.\n   * If one of the nested messages is malformated, parse errors will\n   * occur only when the nested message is accessed, as opposed to when\n   * the decode() call is made. Use this option if you are decoding a message\n   * from a trusted source, like a remote RPC call from a known endpoint.\n   */\n  LAZY = 1,\n}\n\n/**\n * Specifies how the Arena should encode messages.\n */\nexport const enum EncodingMode {\n  /**\n   * Ignore fields that have a zero value which will reduce\n   * the encoded message size.\n   *\n   * This is the default option.\n   */\n  IGNORE_ZERO_FIELDS = 0,\n\n  /**\n   * Include all fields in the payload output, regardless if they\n   * have a zero size.\n   */\n  INCLUDE_ALL_FIELDS = 1,\n}\n\nexport class Arena implements IArena {\n  private protobuf: ValdiProtobufModule;\n  private $native: INativeMessageArena;\n\n  constructor(decodingMode?: DecodingMode, encodingMode?: EncodingMode) {\n    this.protobuf = getProtobufModule();\n    const eagerDecoding = decodingMode !== DecodingMode.LAZY;\n    const includeAllFields = encodingMode === EncodingMode.INCLUDE_ALL_FIELDS;\n    this.$native = this.protobuf.createArena(eagerDecoding, includeAllFields);\n  }\n\n  createMessage(constructor: IMessageConstructor): IMessage {\n    const messageIndex = this.protobuf.createMessage(\n      this.$native,\n      constructor.messageFactory,\n      constructor.descriptorIndex,\n    );\n    return this.getMessageInstance(constructor, messageIndex);\n  }\n\n  decodeMessage(constructor: IMessageConstructor, data: Uint8Array): IMessage {\n    const messageIndex = this.protobuf.decodeMessage(\n      this.$native,\n      constructor.messageFactory,\n      constructor.descriptorIndex,\n      data,\n    );\n    return this.getMessageInstance(constructor, messageIndex);\n  }\n\n  decodeMessageAsync(constructor: IMessageConstructor, data: Uint8Array): Promise<IMessage<any>> {\n    return new Promise((resolve, reject) => {\n      this.protobuf.decodeMessageAsync(\n        this.$native,\n        constructor.messageFactory,\n        constructor.descriptorIndex,\n        data,\n        makeSingleCallInterruptibleCallback((data, error) => {\n          if (data !== undefined) {\n            resolve(this.getMessageInstance(constructor, data));\n          } else {\n            reject(new Error(error));\n          }\n        }),\n      );\n    });\n  }\n\n  decodeMessageDebugJSONAsync(constructor: IMessageConstructor, data: string): Promise<IMessage<any>> {\n    return new Promise((resolve, reject) => {\n      this.protobuf.decodeMessageDebugJSONAsync(\n        this.$native,\n        constructor.messageFactory,\n        constructor.descriptorIndex,\n        data,\n        makeSingleCallInterruptibleCallback((data, error) => {\n          if (data !== undefined) {\n            resolve(this.getMessageInstance(constructor, data));\n          } else {\n            reject(new Error(error));\n          }\n        }),\n      );\n    });\n  }\n\n  encodeMessage(message: IMessage): Uint8Array {\n    return this.protobuf.encodeMessage(this.$native, message.$index);\n  }\n\n  encodeMessageAsync(message: IMessage<any>): Promise<Uint8Array> {\n    return new Promise((resolve, reject) => {\n      this.protobuf.encodeMessageAsync(\n        this.$native,\n        message.$index,\n        makeSingleCallInterruptibleCallback((data, error) => {\n          if (data !== undefined) {\n            resolve(data);\n          } else {\n            reject(new Error(error));\n          }\n        }),\n      );\n    });\n  }\n\n  batchEncodeMessageAsync(messages: readonly IMessage<any>[]): Promise<Uint8Array[]> {\n    const messageIndexes = messages.map(fn => fn.$index);\n    return new Promise((resolve, reject) => {\n      this.protobuf.batchEncodeMessageAsync(\n        this.$native,\n        messageIndexes,\n        makeSingleCallInterruptibleCallback((data, error) => {\n          if (data !== undefined) {\n            resolve(data);\n          } else {\n            reject(new Error(error));\n          }\n        }),\n      );\n    });\n  }\n\n  encodeMessageToJSON(message: IMessage<any>, printOptions: JSONPrintOptions | undefined): string {\n    return this.protobuf.encodeMessageToJSON(this.$native, message.$index, printOptions ?? 0);\n  }\n\n  getMessageFields(message: IMessage): any[] {\n    return this.protobuf.getMessageFields(this.$native, message.$index);\n  }\n\n  setMessageField(message: IMessage, fieldIndex: number, totalFieldsLength: number, fieldValue: any): void {\n    this.protobuf.setMessageField(this.$native, message.$index, fieldIndex, fieldValue);\n  }\n\n  getMessageInstance(constructor: IMessageConstructor, messageIndex: INativeMessageIndex): IMessage {\n    return new constructor(this, messageIndex);\n  }\n\n  copyMessage(message: IMessage): IMessage {\n    const otherArena = message.$arena;\n    if (!(otherArena instanceof Arena)) {\n      throw Error('Can only copy messages from an Arena instance');\n    }\n\n    const messageIndex = this.protobuf.copyMessage(this.$native, message.$index, otherArena.$native);\n    return this.getMessageInstance(message.constructor as IMessageConstructor, messageIndex);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/Descriptor.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { makeMessageFields } from './FieldFactory';\nimport { Message } from './Message';\nimport { IArena, IDescriptor, IDescriptorPool, IMessage, IMessageConstructor } from './types';\nimport { IField, INativeMessageFactory } from './ValdiProtobuf';\n\nexport default class Descriptor implements IDescriptor {\n  private messageConstructor: IMessageConstructor | undefined;\n\n  private _fields: readonly IField[] | undefined;\n\n  get fields(): readonly IField[] {\n    let fields = this._fields;\n    if (!fields) {\n      fields = this.descriptorPool.getFieldsForDescriptorIndex(this.index);\n      this._fields = fields;\n    }\n    return fields;\n  }\n\n  constructor(\n    readonly namespace: string,\n    readonly messageName: string,\n    readonly index: number,\n    private readonly descriptorPool: IDescriptorPool,\n  ) {}\n\n  setProperties(arena: IArena, message: IMessage, properties: StringMap<any>) {\n    for (const field of this.fields) {\n      const value = properties[field.name];\n      if (value) {\n        (message as any)[field.name] = value;\n      }\n    }\n  }\n\n  getConstructor(): IMessageConstructor {\n    let messageConstructor = this.messageConstructor;\n    if (!messageConstructor) {\n      const index = this.index;\n      const messageFactory: INativeMessageFactory = this.descriptorPool.nativeMessageFactory;\n      const fields = this.fields;\n\n      class NewMessage extends Message<any> {\n        static descriptorIndex: number = index;\n        static messageFactory: INativeMessageFactory = messageFactory;\n        static fields = fields;\n      }\n\n      Object.defineProperty(NewMessage, 'name', { value: this.messageName });\n\n      const messageFields = makeMessageFields(this.descriptorPool, fields);\n\n      let fieldIndex = 0;\n      for (const messageField of messageFields) {\n        const fieldName = fields[fieldIndex].name;\n        try {\n          Object.defineProperty(NewMessage.prototype, fieldName, {\n            enumerable: true,\n            get: messageField.get,\n            set: messageField.set,\n          });\n        } catch (err: any) {\n          throw Error(\n            `Failed to set field at index ${fieldIndex} named '${fieldName}' on message ${this.messageName}: ${err}`,\n          );\n        }\n\n        fieldIndex += 1;\n      }\n\n      messageConstructor = NewMessage;\n      this.messageConstructor = messageConstructor;\n    }\n\n    return messageConstructor;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/FieldFactory.ts",
    "content": "import { lazyMap } from 'coreutils/src/ArrayUtils';\nimport { StringMap } from 'coreutils/src/StringMap';\nimport {\n  FieldValue,\n  FieldValues,\n  IArena,\n  IDescriptorPool,\n  IMessage,\n  IMessageFactory,\n  MapFieldMapKey,\n  MapFieldMapValue,\n  NonRepeatedFieldValues,\n} from './types';\nimport { defaultValueForField } from './utils/misc';\nimport {\n  FieldModifier,\n  FieldType,\n  IField,\n  INativeMessageIndex,\n  NativeFieldValues,\n  NonRepeatedNativeFieldValues,\n} from './ValdiProtobuf';\n\n// Use a value outside the bounds of a 32-bit integer to avoid\n// any possible conflicts with enum values, since enum values can\n// only be 32-bit integers.\nconst UNRECOGNIZED_ENUM_VALUE = 0xffffffffff;\n\ntype ValueConverter<T1, T2> = (arena: IArena, message: IMessage | undefined, value: T1) => T2;\ntype Preprocessor<T> = (arena: IArena, value: T) => T;\ntype Postprocessor<T> = (value: T) => T;\n\ninterface MapEntry {\n  key: MapFieldMapKey;\n  value: MapFieldMapValue;\n}\n\ninterface ValueConverterPair<JSType extends FieldValues, NativeType extends NativeFieldValues> {\n  readonly toNative: ValueConverter<JSType, NativeType>;\n  readonly fromNative: ValueConverter<NativeType, JSType> | undefined;\n  readonly preprocess: Preprocessor<JSType> | undefined;\n  /**\n   * Transforms only the in-memory JS value, used for ensuring the in-memory value for enums always\n   * maps to an enum value when setting unkown values\n   */\n  readonly postprocess: Postprocessor<JSType> | undefined;\n}\n\n// Key where the array containing the cached JS fields will be set on the IMessage instance\nconst JS_FIELDS_KEY = Symbol('fields');\n\nconst NOOP: ValueConverterPair<any, any> = {\n  toNative: (arena, message, value) => value,\n  fromNative: (arena, message, value) => value,\n  preprocess: undefined,\n  postprocess: undefined,\n};\n\nfunction preprocessMessage(arena: IArena, messageFactory: IMessageFactory, message: IMessage): IMessage {\n  const messageArena = message.$arena;\n\n  if (messageArena !== arena) {\n    if (messageArena === undefined) {\n      const newMessage = arena.createMessage(messageFactory.getConstructor());\n      messageFactory.setProperties(arena, newMessage, message as StringMap<any>);\n      return newMessage;\n    } else {\n      // Message comes from a different arena, we need to copy it.\n      return arena.copyMessage(message);\n    }\n  }\n\n  return message;\n}\n\nfunction messageValueConverterPair(messageFactory: IMessageFactory): ValueConverterPair<IMessage, INativeMessageIndex> {\n  return {\n    toNative(arena, message, value) {\n      return value.$index;\n    },\n    fromNative(arena, message, value) {\n      return arena.getMessageInstance(messageFactory.getConstructor(), value);\n    },\n    preprocess(arena: IArena, value: IMessage) {\n      return preprocessMessage(arena, messageFactory, value);\n    },\n    postprocess: undefined,\n  };\n}\n\nfunction lazyEnumValueSet(field: IField): () => { [key: number]: boolean } {\n  let values: { [key: number]: boolean } | undefined;\n  return () => {\n    if (!values) {\n      values = {};\n      for (const enumValue of field.enumValues ?? []) {\n        values[enumValue] = true;\n      }\n    }\n    return values;\n  };\n}\n\nfunction enumValueConverterPair(field: IField): ValueConverterPair<number, number> {\n  const enumValues = lazyEnumValueSet(field);\n  return {\n    toNative: NOOP.toNative,\n    fromNative: (arena, message, value) => (enumValues()[value] ? value : UNRECOGNIZED_ENUM_VALUE),\n    postprocess: value => (enumValues()[value] ? value : UNRECOGNIZED_ENUM_VALUE),\n    preprocess: NOOP.preprocess,\n  };\n}\n\nfunction preprocessRepeated<JSType extends NonRepeatedFieldValues>(\n  arena: IArena,\n  itemPreprocessor: Preprocessor<JSType>,\n  items: JSType[],\n): JSType[] {\n  return lazyMap(items, item => itemPreprocessor(arena, item));\n}\n\nfunction repeatedValueConverterPair<\n  JSType extends NonRepeatedFieldValues,\n  NativeType extends NonRepeatedNativeFieldValues,\n>(\n  itemConverter: ValueConverterPair<JSType, NativeType> | undefined,\n): ValueConverterPair<ReadonlyArray<JSType>, ReadonlyArray<NativeType>> | undefined {\n  let preprocess: Preprocessor<ReadonlyArray<JSType>> | undefined;\n  let postprocess: Postprocessor<ReadonlyArray<JSType>> | undefined;\n\n  const itemPreprocessor = itemConverter?.preprocess;\n  if (itemPreprocessor) {\n    preprocess = (message, values) => preprocessRepeated(message, itemPreprocessor, values as JSType[]);\n  }\n\n  const itemPostProcessor = itemConverter?.postprocess;\n  if (itemPostProcessor) {\n    postprocess = values => values.map(itemPostProcessor);\n  }\n\n  if (itemConverter) {\n    let fromNative: ValueConverter<ReadonlyArray<NativeType>, ReadonlyArray<JSType>> | undefined;\n    const itemConverterFromNative = itemConverter.fromNative;\n\n    if (itemConverterFromNative) {\n      fromNative = (arena, message, values) => values.map(item => itemConverterFromNative(arena, message, item));\n    }\n\n    return {\n      toNative(arena, message, values) {\n        return values.map(item => itemConverter.toNative(arena, message, item));\n      },\n\n      fromNative,\n      preprocess,\n      postprocess,\n    };\n  } else {\n    if (preprocess || postprocess) {\n      return {\n        toNative: NOOP.toNative,\n        fromNative: undefined,\n        preprocess,\n        postprocess,\n      };\n    } else {\n      return undefined;\n    }\n  }\n}\n\nfunction mapValueConverterPair<JSType extends NonRepeatedFieldValues, NativeType extends NonRepeatedNativeFieldValues>(\n  itemConverter: ValueConverterPair<JSType, NativeType> | undefined,\n): ValueConverterPair<ReadonlyMap<MapFieldMapKey, JSType>, ReadonlyArray<NativeType>> {\n  const itemPreprocessor = itemConverter?.preprocess;\n  if (!itemPreprocessor) {\n    throw Error('Map should always have a preprocessor');\n  }\n  const itemFromNative = itemConverter.fromNative;\n  if (!itemFromNative) {\n    throw Error('Map should always have a fromNative');\n  }\n\n  const cacheKey = Symbol();\n\n  const itemPostProcessor = itemConverter.postprocess;\n  return {\n    toNative(arena, message, value) {\n      const previousEntries: MapEntry[] | undefined = message && ((message as any)[cacheKey] as MapEntry[]);\n      if (previousEntries) {\n        // Clear out our values, so we can make the messages orphan\n        for (const entry of previousEntries) {\n          entry.value = undefined!;\n        }\n      }\n\n      let newEntries: MapEntry[] | undefined;\n      const entries: NativeType[] = [];\n\n      for (const [mapKey, mapValue] of Array.from(value)) {\n        if (mapValue === undefined) {\n          continue;\n        }\n\n        const convertedValue = itemPreprocessor(arena, (<MapEntry>{ key: mapKey, value: mapValue }) as any) as any;\n        entries.push(itemConverter.toNative(arena, message, convertedValue));\n\n        if (message) {\n          const convertedMapValue = convertedValue.value;\n          if (convertedMapValue.$arena) {\n            // This is a Message, keep track of it so we can mark it orphan next time we set it\n            if (!newEntries) {\n              newEntries = [];\n            }\n            newEntries.push(convertedValue);\n          }\n        }\n      }\n\n      if (message && newEntries !== previousEntries) {\n        (message as any)[cacheKey] = newEntries;\n      }\n\n      return entries;\n    },\n\n    fromNative(arena, message, values) {\n      const out = new Map();\n      if (!values) {\n        return out;\n      }\n\n      let newEntries: MapEntry[] | undefined;\n\n      for (const value of values) {\n        if (value === undefined) {\n          continue;\n        }\n\n        const item = itemFromNative(arena, message, value) as any as MapEntry;\n\n        const mapKey = item.key;\n        const mapValue = item.value;\n        out.set(mapKey, mapValue);\n\n        if ((mapValue as IMessage).$arena) {\n          if (!newEntries) {\n            newEntries = [];\n          }\n          newEntries.push(item);\n        }\n      }\n\n      (message as any)[cacheKey] = newEntries;\n\n      return out;\n    },\n    preprocess: undefined,\n    postprocess: itemPostProcessor\n      ? value =>\n          new Map(\n            Array.from(value.entries()).map(([key, value]) => {\n              return [key, itemPostProcessor(value)];\n            }),\n          )\n      : undefined,\n  };\n}\n\nfunction valueConverterPairForField(\n  field: IField,\n  descriptorPool: IDescriptorPool,\n): ValueConverterPair<any, any> | undefined {\n  let itemConverter: ValueConverterPair<any, any> | undefined;\n\n  if (field.type === FieldType.MESSAGE) {\n    if (field.otherDescriptorIndex === undefined) {\n      throw new Error('Message field must have an other descriptor index');\n    }\n\n    const messageFactory = descriptorPool.getDescriptorForIndex(field.otherDescriptorIndex);\n    itemConverter = messageValueConverterPair(messageFactory);\n\n    // If this message field is a map, check to see if its value type is an enum\n    // If so, pass through the enum value converter's postprocess through so the\n    // in-memory Map value can have its values updated to unknown on set if needed\n    if (field.modifier === FieldModifier.MAP) {\n      const valueField: IField = messageFactory.fields[1];\n      if (valueField?.type === FieldType.ENUM) {\n        const enumValueConverter = enumValueConverterPair(valueField);\n        itemConverter = { ...itemConverter, postprocess: enumValueConverter.postprocess };\n      }\n    }\n  } else if (field.type === FieldType.ENUM) {\n    itemConverter = enumValueConverterPair(field);\n  }\n\n  switch (field.modifier) {\n    case FieldModifier.REPEATED:\n      return repeatedValueConverterPair(itemConverter);\n    case FieldModifier.MAP:\n      return mapValueConverterPair(itemConverter);\n    case FieldModifier.NONE:\n      return itemConverter;\n  }\n}\n\nexport interface IMessageField {\n  get(this: IMessage): any;\n  set(this: IMessage, value: any | undefined): void;\n  toNativeDirect(arena: IArena, value: any): any;\n}\n\nfunction resolveFields(\n  message: IMessage,\n  converters: readonly (ValueConverterPair<FieldValues, NativeFieldValues> | undefined)[],\n): FieldValue[] {\n  let jsFields = (message as any)[JS_FIELDS_KEY] as any[];\n  if (!jsFields) {\n    const arena = message.$arena;\n    jsFields = arena.getMessageFields(message);\n    (message as any)[JS_FIELDS_KEY] = jsFields;\n\n    let index = 0;\n    for (const converter of converters) {\n      const fromNative = converter?.fromNative;\n      if (fromNative) {\n        const unconvertedValue = jsFields[index];\n        if (unconvertedValue !== undefined) {\n          jsFields[index] = fromNative(arena, message, unconvertedValue);\n        }\n      }\n\n      index++;\n    }\n  }\n\n  return jsFields;\n}\n\nfunction clearOneOfFields(fields: readonly IField[], jsFields: FieldValue[], currentField: IField) {\n  for (let i = 0; i < fields.length; i++) {\n    const field = fields[i];\n    if (field === currentField || field.oneOfFieldIndex !== currentField.oneOfFieldIndex) {\n      continue;\n    }\n\n    jsFields[i] = undefined;\n  }\n}\n\nfunction makeMessageField(\n  fields: readonly IField[],\n  converters: readonly (ValueConverterPair<FieldValues, NativeFieldValues> | undefined)[],\n  index: number,\n): IMessageField {\n  const field = fields[index];\n  const converter = converters[index];\n  const defaultValue = defaultValueForField(fields[index]);\n\n  function get(this: IMessage): any {\n    const value = resolveFields(this, converters)[index];\n    if (value !== undefined) {\n      return value;\n    }\n    return defaultValue;\n  }\n\n  if (converter) {\n    // Field using a converter\n    return {\n      get,\n      set(this: IMessage, value: any) {\n        if (converter.preprocess && value !== undefined) {\n          value = converter.preprocess(this.$arena, value);\n        }\n\n        const jsFields = resolveFields(this, converters);\n\n        const currentValue = jsFields[index];\n\n        if (currentValue !== value) {\n          jsFields[index] = converter.postprocess ? converter.postprocess(value) : value;\n\n          let nativeValue: NativeFieldValues | undefined;\n          if (value !== undefined) {\n            nativeValue = converter.toNative(this.$arena, this, value);\n          }\n\n          this.$arena.setMessageField(this, field.index, converters.length, nativeValue);\n\n          if (field.oneOfFieldIndex !== undefined) {\n            clearOneOfFields(fields, jsFields, field);\n          }\n        }\n      },\n      toNativeDirect(arena: IArena, value: any) {\n        if (converter.preprocess) {\n          value = converter.preprocess(arena, value);\n        }\n        return converter.toNative(arena, undefined, value);\n      },\n    };\n  } else {\n    // Field without a converter, can use faster branch\n    return {\n      get,\n      set(this: IMessage, value: any) {\n        const jsFields = resolveFields(this, converters);\n\n        const currentValue = jsFields[index];\n\n        if (currentValue !== value) {\n          jsFields[index] = value;\n\n          this.$arena.setMessageField(this, field.index, converters.length, value);\n\n          if (field.oneOfFieldIndex !== undefined) {\n            clearOneOfFields(fields, jsFields, field);\n          }\n        }\n      },\n      toNativeDirect(arena: IArena, value: any) {\n        return value;\n      },\n    };\n  }\n}\n\nexport function makeMessageFields(descriptorPool: IDescriptorPool, fields: readonly IField[]): IMessageField[] {\n  const converters = fields.map(field => valueConverterPairForField(field, descriptorPool));\n\n  const messageFields: IMessageField[] = [];\n  for (let i = 0; i < fields.length; i++) {\n    messageFields.push(makeMessageField(fields, converters, i));\n  }\n\n  return messageFields;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/Message.ts",
    "content": "import { ConsoleRepresentable } from 'valdi_core/src/ConsoleRepresentable';\nimport { IArena, IMessage, IMessageConstructor, JSONPrintOptions } from './types';\nimport { INativeMessageIndex } from './ValdiProtobuf';\n\nfunction toPlainObjectImpl(value: any): any {\n  if (value === undefined) {\n    return undefined;\n  }\n\n  if (value.toPlainObject) {\n    return value.toPlainObject();\n  }\n\n  if (Array.isArray(value)) {\n    return value.map(v => toPlainObjectImpl(v));\n  }\n\n  if (value instanceof Map) {\n    const map = new Map();\n    value.forEach((mapValue, mapKey) => {\n      map.set(mapKey, toPlainObjectImpl(mapValue));\n    });\n    return map;\n  }\n\n  return value;\n}\n\n/**\n * Base class for all message types\n */\nexport class Message<MessageProps = {}> implements IMessage<MessageProps>, ConsoleRepresentable {\n  /**\n   * Creates a new Mesage instance using an existing native instance\n   * inside the given arena.\n   */\n  constructor(readonly $arena: IArena, readonly $index: INativeMessageIndex) {}\n\n  /**\n   * Encode this message into buffer.\n   */\n  encode(): Uint8Array {\n    return this.$arena.encodeMessage(this as IMessage<MessageProps>);\n  }\n\n  /**\n   * Asynchronously encode this message into buffer.\n   */\n  encodeAsync(): Promise<Uint8Array> {\n    return this.$arena.encodeMessageAsync(this as IMessage<MessageProps>);\n  }\n\n  /**\n   * Creates a deep copy of this message into the given Arena.\n   * If the arena is not provided, the copy will be hosted\n   * into the same arena as this message.\n   */\n  clone<T extends IMessage<MessageProps>>(this: T, arena?: IArena): T {\n    const targetArena = arena ?? this.$arena;\n    return targetArena.copyMessage(this as IMessage<MessageProps>) as T;\n  }\n\n  /**\n   * Eagerly recursively read the content of the message\n   */\n  toPlainObject(): MessageProps {\n    const out: any = {};\n    for (const field of (this.constructor as IMessageConstructor).fields) {\n      const fieldName = field.name;\n      const value = (this as any)[fieldName];\n\n      if (value !== undefined) {\n        out[fieldName] = toPlainObjectImpl(value);\n      }\n    }\n    return out;\n  }\n\n  /**\n   * Converts this message into its JSON equivalent.\n   * Converting to JSON for anything other than debugging is discouraged, as such there is no exposed\n   * function for converting JSON into message instances.\n   * For more details on Protobuf JSON formatting:\n   * https://protobuf.dev/programming-guides/proto3/#json\n   */\n  toDebugJSON(options?: JSONPrintOptions): string {\n    return this.$arena.encodeMessageToJSON(this as IMessage<MessageProps>, options);\n  }\n\n  /**\n   * Allow a full easy display in the console logs\n   */\n  toConsoleRepresentation() {\n    return this.toPlainObject();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/ProtobufBuilder.ts",
    "content": "import { trace } from 'valdi_core/src/utils/Trace';\nimport { Arena } from './Arena';\nimport Descriptor from './Descriptor';\nimport { IArena, IDescriptor, IDescriptorPool, IMessage, IMessageNamespace } from './types';\nimport { ValdiProtobufModule, IField, INativeMessageFactory, INativeNamespaceEntries } from './ValdiProtobuf';\nimport { getProtobufModule } from './ValdiProtobufModule';\n\nfunction createMessageNamespace(descriptor: IDescriptor): IMessageNamespace {\n  function createMessage(arena: IArena | undefined, value?: any): IMessage {\n    if (!arena) {\n      throw Error('Must provide an Arena instance');\n    }\n\n    const message = arena.createMessage(descriptor.getConstructor());\n    if (value) {\n      descriptor.setProperties(arena, message, value);\n    }\n\n    return message;\n  }\n  return {\n    create: createMessage,\n    decode: (arena: IArena | undefined, data: Uint8Array): IMessage => {\n      if (!arena) {\n        throw Error('Must provide an Arena instance');\n      }\n\n      return arena.decodeMessage(descriptor.getConstructor(), data);\n    },\n    decodeAsync: (arena: IArena | undefined, data: Uint8Array): Promise<IMessage> => {\n      if (!arena) {\n        throw Error('Must provide an Arena instance');\n      }\n\n      return arena.decodeMessageAsync(descriptor.getConstructor(), data);\n    },\n\n    decodeDebugJSONAsync: (arena: IArena | undefined, json: string): Promise<IMessage> => {\n      if (!arena) {\n        throw Error('Must provide an Arena instance');\n      }\n\n      return arena.decodeMessageDebugJSONAsync(descriptor.getConstructor(), json);\n    },\n\n    encode: (value: IMessage | any): Uint8Array => {\n      if (value.encode) {\n        return value.encode();\n      }\n      const arena = new Arena();\n      const instance = createMessage(arena, value);\n      return instance.encode();\n    },\n\n    encodeAsync: (value: IMessage | any): Promise<Uint8Array> => {\n      if (value.encodeAsync) {\n        return value.encodeAsync();\n      }\n      const arena = new Arena();\n      const instance = createMessage(arena, value);\n      return instance.encodeAsync();\n    },\n  };\n}\n\nclass DescriptorPool implements IDescriptorPool {\n  private protobuf: ValdiProtobufModule;\n  readonly namespaces: Record<string, any>;\n\n  private descriptors: (IDescriptor | undefined)[] = [];\n\n  get descriptorsLength(): number {\n    return this.descriptorNames.length;\n  }\n\n  private packageNamespaceById: { [key: number]: Record<string, any> } = {};\n  private messageNamespaceById: { [key: number]: IMessageNamespace } = {};\n\n  constructor(\n    readonly nativeMessageFactory: INativeMessageFactory,\n    readonly descriptorNames: string[],\n    rootNamespaceEntries: INativeNamespaceEntries,\n  ) {\n    this.protobuf = getProtobufModule();\n    if (!rootNamespaceEntries) {\n      const errorMessage = `Your client branch is more recent than your iOS/android checkout. Please update your iOS or android checkout and rebuild the app.`;\n      console.error(errorMessage);\n      throw new Error(errorMessage);\n    }\n    this.namespaces = this.createPackageNamespace(rootNamespaceEntries);\n  }\n\n  private createPackageNamespace(entries: INativeNamespaceEntries): Record<string, any> {\n    const output: Record<string, any> = {};\n    let i = 0;\n    const length = entries.length;\n    while (i < length) {\n      const typeEntry = entries[i++] as number;\n      const name = entries[i++] as string;\n\n      const id = typeEntry >> 1;\n      const isMessage = !!(typeEntry & 1);\n\n      if (isMessage) {\n        this.insertMessageNamespace(name, id, output);\n      } else {\n        this.insertPackageNamespace(name, id, output);\n      }\n    }\n\n    return output;\n  }\n\n  private doDefineGetter(name: string, output: Record<string, any>, getter: () => any) {\n    const descriptor = Object.getOwnPropertyDescriptor(output, name);\n    if (!descriptor || !descriptor.get) {\n      // New property, we can assign it directly\n      Object.defineProperty(output, name, {\n        enumerable: true,\n        configurable: true,\n        get: getter,\n      });\n    } else {\n      // Property already exist. We need to merge it\n      const key = Symbol();\n      const previousGetter = descriptor.get;\n      Object.defineProperty(output, name, {\n        enumerable: true,\n        configurable: true,\n        get: () => {\n          let value = (output as any)[key];\n          if (!value) {\n            value = { ...previousGetter(), ...getter() };\n            (output as any)[key] = value;\n          }\n\n          return value;\n        },\n      });\n    }\n  }\n\n  private insertPackageNamespace(name: string, id: number, output: Record<string, any>) {\n    this.doDefineGetter(name, output, () => {\n      let resolvedNamespace = this.packageNamespaceById[id];\n      if (!resolvedNamespace) {\n        const namespaceEntries = this.protobuf.getNamespaceEntries(this.nativeMessageFactory, id);\n        resolvedNamespace = this.createPackageNamespace(namespaceEntries);\n        this.packageNamespaceById[id] = resolvedNamespace;\n      }\n      return resolvedNamespace;\n    });\n  }\n\n  private insertMessageNamespace(name: string, id: number, output: Record<string, any>) {\n    this.doDefineGetter(name, output, () => {\n      let resolvedNamespace = this.messageNamespaceById[id];\n      if (!resolvedNamespace) {\n        resolvedNamespace = createMessageNamespace(this.getDescriptorForIndex(id));\n        this.messageNamespaceById[id] = resolvedNamespace;\n      }\n      return resolvedNamespace;\n    });\n  }\n\n  getDescriptorForIndex(index: number): IDescriptor {\n    let descriptor = this.descriptors[index];\n\n    if (!descriptor) {\n      const nameSplit = this.descriptorNames[index].split('.');\n      const name = nameSplit[nameSplit.length - 1];\n      const namespaceKeyEntries = nameSplit.slice(0, nameSplit.length - 1);\n      const namespaceKey = namespaceKeyEntries.join('.');\n\n      descriptor = new Descriptor(namespaceKey, name, index, this);\n      this.descriptors[index] = descriptor;\n    }\n\n    return descriptor;\n  }\n\n  getFieldsForDescriptorIndex(descriptorIndex: number): readonly IField[] {\n    return this.protobuf.getFieldsForMessageDescriptor(this.nativeMessageFactory, descriptorIndex);\n  }\n\n  getMessageNamespace(messagePath: string): IMessageNamespace | undefined {\n    const components = messagePath.split('.');\n    let current = this.namespaces;\n\n    for (const component of components) {\n      current = current[component];\n      if (!current) {\n        return undefined;\n      }\n    }\n\n    if (current && current.decodeAsync) {\n      // Found our namespace\n      return current as IMessageNamespace;\n    }\n\n    return undefined;\n  }\n}\n\n/**\n * Load and return a Protobuf DescriptorPool from the content of proto files.\n * This will parse the given proto file as a string and return a descriptor\n * that allows to interact with the Protobuf messages.\n * The \"filename\" is used to identify the file internally and does not need\n * to match a file on disk.\n */\nexport function loadDescriptorPoolFromProtoFiles(filename: string, protoFilesContent: string): IDescriptorPool {\n  const protobuf = getProtobufModule();\n  if (!protobuf.parseAndLoadMessages) {\n    throw new Error('Parsing Proto files is not available in this build type');\n  }\n\n  return trace(`Protobuf.loadFromProtos`, () => {\n    const result = protobuf.parseAndLoadMessages!(filename, protoFilesContent);\n    return new DescriptorPool(result.factory, result.descriptorNames, result.rootNamespaceEntries);\n  });\n}\n\n/**\n * Load and return the Protobuf message namespaces from a path.\n */\nexport function load(path: string): any {\n  return trace(`Protobuf.load.${path}`, () => {\n    const result = getProtobufModule().loadMessages(path);\n    if (result.namespaces) {\n      return result.namespaces;\n    } else {\n      return new DescriptorPool(result.factory, result.descriptorNames, result.rootNamespaceEntries).namespaces;\n    }\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/ValdiProtobuf.d.ts",
    "content": "type OpaqueNativeObject<K> = {} & { __TYPE__: K };\n\nexport type INativeMessageFactory = {};\nexport type INativeMessageIndex = number;\n\nexport type INativeMessageArena = {};\n\nexport type NonRepeatedNativeFieldValues = number | boolean | Long | string | Uint8Array | INativeMessageIndex;\nexport type RepeatedNativeFieldValues = ReadonlyArray<NonRepeatedNativeFieldValues>;\nexport type NativeFieldValues = NonRepeatedNativeFieldValues | RepeatedNativeFieldValues;\nexport type NativeFieldValue<T extends NativeFieldValues = NativeFieldValues> = T extends RepeatedNativeFieldValues\n  ? T\n  : T extends INativeMessageIndex\n  ? T | undefined\n  : T;\n\nexport const enum FieldType {\n  DOUBLE = 1,\n  FLOAT = 2,\n  INT64 = 3,\n  UINT64 = 4,\n  INT32 = 5,\n  FIXED64 = 6,\n  FIXED32 = 7,\n  BOOL = 8,\n  STRING = 9,\n  GROUP = 10, // deprecated\n  MESSAGE = 11,\n  BYTES = 12,\n  UINT32 = 13,\n  ENUM = 14,\n  SFIXED32 = 15,\n  SFIXED64 = 16,\n  SINT32 = 17,\n  SINT64 = 18,\n}\n\nexport const enum FieldModifier {\n  NONE = 0,\n  REPEATED = 1,\n  MAP = 2,\n}\n\nexport interface IField {\n  name: string;\n  index: number;\n  type: FieldType;\n  modifier: FieldModifier;\n  otherDescriptorIndex?: number;\n  oneOfFieldIndex?: number;\n  enumValues?: number[];\n}\n\nexport interface INativeDescriptor {\n  fullName: string;\n}\n\nexport type INativeNamespaceEntries = (string | number)[];\n\nexport interface ILoadMessageResult {\n  factory: INativeMessageFactory;\n  rootNamespaceEntries: INativeNamespaceEntries;\n  descriptorNames: string[];\n  namespaces?: any;\n}\n\nexport interface ValdiProtobufModule {\n  createArena(eagerDecoding: boolean, ignoreAllFieldsDuringEncoding: boolean): INativeMessageArena;\n\n  loadMessages(path: string): ILoadMessageResult;\n\n  parseAndLoadMessages?(filename: string, protoFilesContent: string): ILoadMessageResult;\n\n  getFieldsForMessageDescriptor(factory: INativeMessageFactory, messageDescriptorIndex: number): IField[];\n\n  getNamespaceEntries(factory: INativeMessageFactory, namespaceId: number): INativeNamespaceEntries;\n\n  createMessage(\n    arena: INativeMessageArena,\n    factory: INativeMessageFactory,\n    messageDescriptorIndex: number,\n  ): INativeMessageIndex;\n\n  decodeMessage(\n    arena: INativeMessageArena,\n    factory: INativeMessageFactory,\n    messageDescriptorIndex: number,\n    data: Uint8Array,\n  ): INativeMessageIndex;\n\n  decodeMessageAsync(\n    arena: INativeMessageArena,\n    factory: INativeMessageFactory,\n    messageDescriptorIndex: number,\n    data: Uint8Array,\n    callback: (messageIndex: INativeMessageIndex | undefined, error: string | undefined) => void,\n  ): void;\n\n  decodeMessageDebugJSONAsync(\n    arena: INativeMessageArena,\n    factory: INativeMessageFactory,\n    messageDescriptorIndex: number,\n    data: string,\n    callback: (messageIndex: INativeMessageIndex | undefined, error: string | undefined) => void,\n  ): void;\n\n  encodeMessage(arena: INativeMessageArena, messageIndex: INativeMessageIndex): Uint8Array;\n\n  encodeMessageAsync(\n    arena: INativeMessageArena,\n    messageIndex: INativeMessageIndex,\n    callback: (data: Uint8Array | undefined, error: string | undefined) => void,\n  ): void;\n\n  batchEncodeMessageAsync(\n    arena: INativeMessageArena,\n    messageIndexes: INativeMessageIndex[],\n    callback: (data: Uint8Array[] | undefined, error: string | undefined) => void,\n  ): void;\n\n  encodeMessageToJSON(arena: INativeMessageArena, messageIndex: INativeMessageIndex, options: number): string;\n\n  setMessageField(\n    arena: INativeMessageArena,\n    messageIndex: INativeMessageIndex,\n    fieldIndex: number,\n    value: NativeFieldValues,\n  ): void;\n\n  getMessageFields(arena: INativeMessageArena, messageIndex: INativeMessageIndex): NativeFieldValues[];\n\n  copyMessage(\n    arena: INativeMessageArena,\n    messageIndex: INativeMessageIndex,\n    fromArena: INativeMessageArena,\n  ): INativeMessageIndex;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/ValdiProtobufModule.ts",
    "content": "import { RequireFunc } from 'valdi_core/src/IModuleLoader';\nimport { ValdiProtobufModule } from './ValdiProtobuf';\n\ndeclare const require: RequireFunc;\n\nlet protobufModule: ValdiProtobufModule | undefined;\n\nexport function setProtobufModule(module: ValdiProtobufModule | undefined) {\n  protobufModule = module;\n}\n\nexport function getProtobufModule(): ValdiProtobufModule {\n  if (!protobufModule) {\n    protobufModule = require('ValdiProtobuf', true) as ValdiProtobufModule;\n  }\n\n  return protobufModule;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/types.d.ts",
    "content": "import { StringMap } from 'coreutils/src/StringMap';\nimport { IField, INativeMessageFactory, INativeMessageIndex } from './ValdiProtobuf';\n\nexport type MapFieldMapKey = string | number;\nexport type MapFieldMapValue = NonRepeatedFieldValues;\nexport type MapFieldValue = ReadonlyMap<MapFieldMapKey, MapFieldMapValue>;\nexport type NonRepeatedFieldValues = boolean | string | Uint8Array | number | Long | IMessage;\nexport type RepeatedFieldValues = ReadonlyArray<NonRepeatedFieldValues>;\nexport type FieldValues = NonRepeatedFieldValues | RepeatedFieldValues | MapFieldValue;\nexport type FieldValue<T extends FieldValues = FieldValues> = T extends RepeatedFieldValues\n  ? T\n  : T extends IMessage\n  ? T | undefined\n  : T;\n\nexport const enum JSONPrintOptions {\n  /**\n  Whether to add spaces, line breaks and indentation to make the JSON output\n  easy to read.\n  */\n  PRETTY = 1 << 0,\n  /**\n   * Whether to always print primitive fields. By default proto3 primitive\n   * fields with default values will be omitted in JSON output. For example, an\n   * int32 field set to 0 will be omitted. Set this flag to true will override\n   * the default behavior and print primitive fields regardless of their values.\n   */\n  ALWAYS_PRINT_PRIMITIVE_FIELDS = 1 << 1,\n\n  /**\n   * Whether to always print enums as ints. By default they are rendered as\n   * strings.\n   */\n  ALWAYS_PRINT_ENUMS_AS_INTS = 1 << 2,\n}\n\nexport interface IMessage<MessageProps = any> {\n  readonly $arena: IArena;\n  readonly $index: INativeMessageIndex;\n\n  /**\n   * Encode the message into a buffer\n   */\n  encode(): Uint8Array;\n\n  /**\n   * Asynchronously encode the message into a buffer\n   */\n  encodeAsync(): Promise<Uint8Array>;\n\n  /**\n   * Creates a deep copy of this message into the given Arena.\n   * If the arena is not provided, the copy will be hosted\n   * into the same arena as this message.\n   */\n  clone<T extends IMessage>(this: T, arena?: IArena): T;\n\n  /**\n   * Converts this Protobuf Message into a plain JS object\n   * containing all properties from this message.\n   * This is a recursive call and can be expensive, use\n   * only if you truly need it.\n   */\n  toPlainObject(): MessageProps;\n\n  /**\n   * Converts this message into its JSON equivalent.\n   * Converting to JSON for anything other than debugging is discouraged, as such there is no exposed\n   * function for converting JSON into message instances.\n   * For more details on Protobuf JSON formatting:\n   * https://protobuf.dev/programming-guides/proto3/#json\n   */\n  toDebugJSON(options?: JSONPrintOptions): string;\n}\n\nexport interface IArena {\n  createMessage(constructor: IMessageConstructor): IMessage;\n  decodeMessage(constructor: IMessageConstructor, data: Uint8Array): IMessage;\n  decodeMessageAsync(constructor: IMessageConstructor, data: Uint8Array): Promise<IMessage>;\n  encodeMessage(message: IMessage): Uint8Array;\n  encodeMessageAsync(message: IMessage): Promise<Uint8Array>;\n  decodeMessageDebugJSONAsync(constructor: IMessageConstructor, data: string): Promise<IMessage>;\n  /**\n   * Asynchronously encode a list of messages into a single batch.\n   * This can be more efficient than asynchronously encoding each message\n   * individually, especially if each message is fairly small.\n   */\n  batchEncodeMessageAsync(messages: readonly IMessage[]): Promise<Uint8Array[]>;\n  encodeMessageToJSON(message: IMessage, printOptions: JSONPrintOptions | undefined): string;\n  getMessageFields(message: IMessage): any[];\n  setMessageField(message: IMessage, fieldIndex: number, totalFieldsLength: number, fieldValue: any): void;\n  getMessageInstance(constructor: IMessageConstructor, messageIndex: INativeMessageIndex): IMessage;\n  copyMessage(message: IMessage): IMessage;\n}\n\nexport type IMessageConstructor = {\n  new (arena: IArena, messageIndex: INativeMessageIndex): IMessage;\n\n  descriptorIndex: number;\n  messageFactory: INativeMessageFactory;\n  fields: readonly IField[];\n};\n\nexport interface IMessageFactory {\n  getConstructor(): IMessageConstructor;\n  setProperties(arena: IArena, message: IMessage, properties: StringMap<FieldValues>): void;\n}\n\nexport interface IDescriptor extends IMessageFactory {\n  readonly namespace: string;\n  readonly messageName: string;\n  readonly index: number;\n  readonly fields: readonly IField[];\n}\n\nexport interface IDescriptorPool {\n  /**\n   * All the message constructors keyed by the namespace.\n   * If a message is on \"com.snapchat.MyMessage\", the \"MyMessage\"\n   * class will be nested on the namespace object for key \"com\",\n   * then another namespace object for the key \"snapchat\", and then\n   * at key \"MyMessage\".\n   */\n  readonly namespaces: Record<string, any>;\n  readonly nativeMessageFactory: INativeMessageFactory;\n  readonly descriptorsLength: number;\n\n  getFieldsForDescriptorIndex(descriptorIndex: number): readonly IField[];\n\n  getDescriptorForIndex(index: number): IDescriptor;\n\n  /**\n   * Retrieve the message namespace instance from its message path.\n   * If a message is called MyMessage in a package my_package, it\n   * can be retrieved by passing my_package.MyMessage\n   */\n  getMessageNamespace(messagePath: string): IMessageNamespace | undefined;\n}\n\n/**\n * Represents the namespace exposed for each generated Protobuf Message type.\n * Exposes methods allowing to interact with the message.\n */\nexport interface IMessageNamespace {\n  create: (arena: IArena, properties?: StringMap<FieldValues>) => IMessage;\n  decode: (arena: IArena, buffer: Uint8Array) => IMessage;\n  decodeAsync: (arena: IArena, buffer: Uint8Array) => Promise<IMessage>;\n  encode: (value: IMessage | StringMap<FieldValues>) => Uint8Array;\n  encodeAsync: (value: StringMap<FieldValues>) => Promise<Uint8Array>;\n  decodeDebugJSONAsync(arena: IArena, json: string): Promise<IMessage>;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/src/utils/misc.ts",
    "content": "import { FieldValue } from '../types';\nimport { FieldModifier, FieldType, IField } from '../ValdiProtobuf';\n\nexport type DefaultValueFactory = () => FieldValue;\n\nconst defaultMap = new Map();\nconst defaultBytes = new Uint8Array([]);\nconst defaultArray: any[] = [];\nconst defaultString = '';\nconst defaultUnsigned64 = Long.fromNumber(0, true);\nconst defaultSigned64 = Long.fromNumber(0, false);\n\nObject.freeze(defaultMap);\nObject.freeze(defaultBytes);\nObject.freeze(defaultArray);\nObject.freeze(defaultUnsigned64);\nObject.freeze(defaultSigned64);\n\nexport function defaultValueForField(field: IField): FieldValue {\n  switch (field.modifier) {\n    case FieldModifier.REPEATED:\n      return defaultArray;\n    case FieldModifier.MAP:\n      return defaultMap;\n  }\n  switch (field.type) {\n    case FieldType.BOOL:\n      return false;\n    case FieldType.STRING:\n      return defaultString;\n    case FieldType.GROUP:\n    case FieldType.MESSAGE:\n      return undefined;\n    case FieldType.BYTES:\n      return defaultBytes;\n    case FieldType.UINT64:\n    case FieldType.FIXED64:\n      return defaultUnsigned64;\n    case FieldType.INT64:\n    case FieldType.SFIXED64:\n    case FieldType.SINT64:\n      return defaultSigned64;\n    case FieldType.DOUBLE:\n    case FieldType.FLOAT:\n    case FieldType.INT32:\n    case FieldType.FIXED32:\n    case FieldType.UINT32:\n    case FieldType.ENUM:\n    case FieldType.SFIXED32:\n    case FieldType.SINT32:\n      return 0;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/test/Test.spec.ts",
    "content": "import { Arena, DecodingMode } from 'valdi_protobuf/src/Arena';\nimport { loadDescriptorPoolFromProtoFiles } from 'valdi_protobuf/src/ProtobufBuilder';\nimport { IArena, IMessage } from 'valdi_protobuf/src/types';\nimport 'jasmine/src/jasmine';\nimport { package_with_underscores, test } from './proto';\n\ninterface MessageFactory<InterfaceType, MessageType> {\n  create(arena: IArena, properties: InterfaceType): MessageType;\n  decode(arena: IArena, buffer: Uint8Array): MessageType;\n}\n\nfunction testMessage<InterfaceType, MessageType extends IMessage & InterfaceType>(\n  factory: MessageFactory<InterfaceType, MessageType>,\n  message: InterfaceType,\n  validator: (message: MessageType) => void,\n  updater?: (message: MessageType, arena: IArena) => void,\n): void {\n  try {\n    const updateAndValidate = (arena: Arena, instance: MessageType) => {\n      updater?.(instance, arena);\n      validator(instance);\n      // Test after a encode/encode\n      validator(factory.decode(arena, instance.encode()));\n      // Test after a clone\n      validator(instance.clone());\n    };\n\n    // Encode first to capture the original state\n    const arena = new Arena();\n    const encoded = factory.create(arena, message).encode();\n\n    // Test using a message that was created through \"create\"\n    updateAndValidate(arena, factory.create(arena, message));\n    // // Test using a message that was created through \"decode\"\n    updateAndValidate(arena, factory.decode(arena, encoded));\n    // Test using an arena with lazy decode mode\n    const eagerArena = new Arena(DecodingMode.LAZY);\n    updateAndValidate(eagerArena, factory.decode(eagerArena, encoded));\n  } catch (err: any) {\n    console.error('Got error:', err);\n    throw err;\n  }\n}\n\nconst INT32_MIN = -2147483648;\nconst INT32_MAX = 0x7fffffff;\nconst UINT32_MIN = 0;\nconst UINT32_MAX = 0xffffffff;\nconst INT64_MIN = Long.MIN_VALUE;\nconst INT64_MAX = Long.MAX_VALUE;\nconst UINT64_MAX = Long.MAX_UNSIGNED_VALUE;\nconst UINT64_MIN = Long.fromNumber(0, true);\n\ndescribe('Valdi Proto Runtime', () => {\n  describe('signed 32-bit fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.int32).toEqual(0);\n        expect(x.sint32).toEqual(0);\n        expect(x.sfixed32).toEqual(0);\n      });\n    });\n    it('positive values', () => {\n      testMessage(\n        test.Message,\n        {\n          int32: 1,\n          sint32: 2,\n          sfixed32: 3,\n        },\n        x => {\n          expect(x.int32).toEqual(1);\n          expect(x.sint32).toEqual(2);\n          expect(x.sfixed32).toEqual(3);\n        },\n      );\n    });\n    it('negative values', () => {\n      testMessage(\n        test.Message,\n        {\n          int32: -1,\n          sint32: -2,\n          sfixed32: -3,\n        },\n        x => {\n          expect(x.int32).toEqual(-1);\n          expect(x.sint32).toEqual(-2);\n          expect(x.sfixed32).toEqual(-3);\n        },\n      );\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.int32).toEqual([]);\n        expect(x.sint32).toEqual([]);\n        expect(x.sfixed32).toEqual([]);\n      });\n    });\n    it('repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          int32: [1, -3],\n          sint32: [3, -4],\n          sfixed32: [INT32_MAX, INT32_MIN],\n        },\n        x => {\n          expect(x.int32).toEqual([1, -3]);\n          expect(x.sint32).toEqual([3, -4]);\n          expect(x.sfixed32).toEqual([INT32_MAX, INT32_MIN]);\n        },\n      );\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        {\n          int32: 1,\n          sint32: 2,\n          sfixed32: 3,\n        },\n        x => {\n          expect(x.int32).toEqual(2);\n          expect(x.sint32).toEqual(3);\n          expect(x.sfixed32).toEqual(4);\n        },\n        x => {\n          x.int32 += 1;\n          x.sint32 += 1;\n          x.sfixed32 += 1;\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        {\n          int32: 1,\n          sint32: 2,\n          sfixed32: 3,\n        },\n        x => {\n          expect(x.int32).toEqual(0);\n          expect(x.sint32).toEqual(0);\n          expect(x.sfixed32).toEqual(0);\n        },\n        x => {\n          x.int32 = undefined as any;\n          x.sint32 = undefined as any;\n          x.sfixed32 = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          int32: [1],\n          sint32: [2],\n          sfixed32: [3],\n        },\n        x => {\n          expect(x.int32).toEqual([1, 101]);\n          expect(x.sint32).toEqual([2, 102]);\n          expect(x.sfixed32).toEqual([3, INT32_MAX, INT32_MIN]);\n        },\n        x => {\n          x.int32 = [...x.int32, 101];\n          x.sint32 = [...x.sint32, 102];\n          x.sfixed32 = [...x.sfixed32, INT32_MAX, INT32_MIN];\n        },\n      );\n    });\n  });\n\n  describe('unsigned 32-bit fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.uint32).toEqual(0);\n        expect(x.fixed32).toEqual(0);\n      });\n    });\n    it('normal values', () => {\n      testMessage(\n        test.Message,\n        {\n          uint32: 1,\n          fixed32: 2,\n        },\n        x => {\n          expect(x.uint32).toEqual(1);\n          expect(x.fixed32).toEqual(2);\n        },\n      );\n    });\n    it('large values', () => {\n      testMessage(\n        test.Message,\n        {\n          uint32: UINT32_MAX,\n          fixed32: UINT32_MAX,\n        },\n        x => {\n          expect(x.uint32).toEqual(UINT32_MAX);\n          expect(x.fixed32).toEqual(UINT32_MAX);\n        },\n      );\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.uint32).toEqual([]);\n        expect(x.fixed32).toEqual([]);\n      });\n    });\n    it('repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          uint32: [1, 2],\n          fixed32: [UINT32_MAX, UINT32_MIN],\n        },\n        x => {\n          expect(x.uint32).toEqual([1, 2]);\n          expect(x.fixed32).toEqual([UINT32_MAX, UINT32_MIN]);\n        },\n      );\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        {\n          uint32: 1,\n          fixed32: 2,\n        },\n        x => {\n          expect(x.uint32).toEqual(2);\n          expect(x.fixed32).toEqual(3);\n        },\n        x => {\n          x.uint32 += 1;\n          x.fixed32 += 1;\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        {\n          uint32: 1,\n          fixed32: 2,\n        },\n        x => {\n          expect(x.uint32).toEqual(0);\n          expect(x.fixed32).toEqual(0);\n        },\n        x => {\n          x.uint32 = undefined as any;\n          x.fixed32 = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          uint32: [1],\n          fixed32: [2],\n        },\n        x => {\n          expect(x.uint32).toEqual([1, 101]);\n          expect(x.fixed32).toEqual([2, UINT32_MAX]);\n        },\n        x => {\n          x.uint32 = [...x.uint32, 101];\n          x.fixed32 = [...x.fixed32, UINT32_MAX];\n        },\n      );\n    });\n  });\n\n  describe('long limits', () => {\n    it('supports min unsigned 64bits', () => {\n      testMessage(\n        test.Message,\n        { uint64: Long.fromNumber(1) },\n        x => {\n          expect(x.uint64).toEqual(UINT64_MIN);\n        },\n        x => {\n          x.uint64 = UINT64_MIN;\n        },\n      );\n    });\n    it('supports max unsigned 64bits', () => {\n      testMessage(\n        test.Message,\n        { uint64: Long.fromNumber(1) },\n        x => {\n          expect(x.uint64).toEqual(UINT64_MAX);\n        },\n        x => {\n          x.uint64 = UINT64_MAX;\n        },\n      );\n    });\n    it('supports min signed 64 bits', () => {\n      testMessage(\n        test.Message,\n        { int64: Long.fromNumber(1), sint64: Long.fromNumber(1) },\n        x => {\n          expect(x.int64).toEqual(INT64_MIN);\n          expect(x.sint64).toEqual(INT64_MIN);\n        },\n        x => {\n          x.int64 = INT64_MIN;\n          x.sint64 = INT64_MIN;\n        },\n      );\n    });\n    it('supports max signed 64 bits', () => {\n      testMessage(\n        test.Message,\n        { int64: Long.fromNumber(1), sint64: Long.fromNumber(1) },\n        x => {\n          expect(x.int64).toEqual(INT64_MAX);\n          expect(x.sint64).toEqual(INT64_MAX);\n        },\n        x => {\n          x.int64 = INT64_MAX;\n          x.sint64 = INT64_MAX;\n        },\n      );\n    });\n  });\n\n  describe('signed 64-bit fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.int64).toEqual(Long.fromNumber(0, false));\n        expect(x.sint64).toEqual(Long.fromNumber(0, false));\n        expect(x.sfixed64).toEqual(Long.fromNumber(0, false));\n      });\n    });\n    it('positive values', () => {\n      testMessage(\n        test.Message,\n        {\n          int64: Long.fromNumber(1, false),\n          sint64: Long.fromNumber(2, false),\n          sfixed64: Long.fromNumber(3, false),\n        },\n        x => {\n          expect(x.int64).toEqual(Long.fromNumber(1, false));\n          expect(x.sint64).toEqual(Long.fromNumber(2, false));\n          expect(x.sfixed64).toEqual(Long.fromNumber(3, false));\n        },\n      );\n    });\n    it('negative values', () => {\n      testMessage(\n        test.Message,\n        {\n          int64: Long.fromNumber(-1, false),\n          sint64: Long.fromNumber(-2, false),\n          sfixed64: Long.fromNumber(-3, false),\n        },\n        x => {\n          expect(x.int64).toEqual(Long.fromNumber(-1, false));\n          expect(x.sint64).toEqual(Long.fromNumber(-2, false));\n          expect(x.sfixed64).toEqual(Long.fromNumber(-3, false));\n        },\n      );\n    });\n    it('large values', () => {\n      testMessage(\n        test.Message,\n        {\n          int64: INT64_MAX,\n          sfixed64: INT64_MIN,\n        },\n        x => {\n          expect(x.int64).toEqual(INT64_MAX);\n          expect(x.sfixed64.toString()).toEqual(INT64_MIN.toString());\n        },\n      );\n      testMessage(\n        test.Message,\n        {\n          int64: Long.fromNumber(UINT32_MAX, false),\n          sfixed64: Long.fromNumber(UINT32_MIN, false),\n        },\n        x => {\n          expect(x.int64).toEqual(Long.fromNumber(UINT32_MAX, false));\n          expect(x.sfixed64).toEqual(Long.fromNumber(UINT32_MIN, false));\n        },\n      );\n      testMessage(\n        test.Message,\n        {\n          int64: Long.fromNumber(INT32_MAX, false),\n          sfixed64: Long.fromNumber(INT32_MIN, false),\n        },\n        x => {\n          expect(x.int64).toEqual(Long.fromNumber(INT32_MAX, false));\n          expect(x.sfixed64).toEqual(Long.fromNumber(INT32_MIN, false));\n        },\n      );\n      testMessage(\n        test.Message,\n        {\n          int64: Long.fromNumber(UINT32_MAX + 1, false),\n          sfixed64: Long.fromNumber(UINT32_MIN - 1, false),\n        },\n        x => {\n          expect(x.int64).toEqual(Long.fromNumber(UINT32_MAX + 1, false));\n          expect(x.sfixed64).toEqual(Long.fromNumber(UINT32_MIN - 1, false));\n        },\n      );\n      testMessage(\n        test.Message,\n        {\n          int64: Long.fromNumber(INT32_MAX + 1, false),\n          sfixed64: Long.fromNumber(INT32_MIN - 1, false),\n        },\n        x => {\n          expect(x.int64).toEqual(Long.fromNumber(INT32_MAX + 1, false));\n          expect(x.sfixed64).toEqual(Long.fromNumber(INT32_MIN - 1, false));\n        },\n      );\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.int64).toEqual([]);\n        expect(x.sint64).toEqual([]);\n        expect(x.sfixed64).toEqual([]);\n      });\n    });\n    it('repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          int64: [Long.fromNumber(1, false), Long.fromNumber(2, false)],\n          sint64: [Long.fromNumber(3, false), Long.fromNumber(4, false)],\n          sfixed64: [Long.fromNumber(5, false), Long.fromNumber(6, false)],\n        },\n        x => {\n          expect(x.int64).toEqual([Long.fromNumber(1, false), Long.fromNumber(2, false)]);\n          expect(x.sint64).toEqual([Long.fromNumber(3, false), Long.fromNumber(4, false)]);\n          expect(x.sfixed64).toEqual([Long.fromNumber(5, false), Long.fromNumber(6, false)]);\n        },\n      );\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        {\n          int64: Long.fromNumber(1, false),\n          sint64: Long.fromNumber(2, false),\n          sfixed64: Long.fromNumber(3, false),\n        },\n        x => {\n          expect(x.int64).toEqual(Long.fromNumber(2, false));\n          expect(x.sint64).toEqual(Long.fromNumber(3, false));\n          expect(x.sfixed64).toEqual(Long.fromNumber(4, false));\n        },\n        x => {\n          x.int64 = Long.fromNumber(2, false);\n          x.sint64 = Long.fromNumber(3, false);\n          x.sfixed64 = Long.fromNumber(4, false);\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        {\n          int64: Long.fromNumber(1, false),\n          sint64: Long.fromNumber(2, false),\n          sfixed64: Long.fromNumber(3, false),\n        },\n        x => {\n          expect(x.int64).toEqual(Long.fromNumber(0, false));\n          expect(x.sint64).toEqual(Long.fromNumber(0, false));\n          expect(x.sfixed64).toEqual(Long.fromNumber(0, false));\n        },\n        x => {\n          x.int64 = undefined as any;\n          x.sint64 = undefined as any;\n          x.sfixed64 = undefined as any;\n        },\n      );\n    });\n\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          int64: [Long.fromNumber(1, false)],\n          sint64: [Long.fromNumber(2, false)],\n          sfixed64: [Long.fromNumber(3, false)],\n        },\n        x => {\n          expect(x.int64).toEqual([Long.fromNumber(1, false), Long.fromNumber(101, false)]);\n          expect(x.sint64).toEqual([Long.fromNumber(2, false), Long.fromNumber(102, false)]);\n          expect(x.sfixed64).toEqual([Long.fromNumber(3, false), INT64_MIN, INT64_MAX]);\n        },\n        x => {\n          x.int64 = [...x.int64, Long.fromNumber(101, false)];\n          x.sint64 = [...x.sint64, Long.fromNumber(102, false)];\n          x.sfixed64 = [...x.sfixed64, INT64_MIN, INT64_MAX];\n        },\n      );\n    });\n  });\n\n  describe('unsigned 64-bit fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.uint64).toEqual(Long.fromNumber(0, true));\n        expect(x.fixed64).toEqual(Long.fromNumber(0, true));\n      });\n    });\n    it('normal values', () => {\n      testMessage(\n        test.Message,\n        {\n          uint64: Long.fromNumber(1, true),\n          fixed64: Long.fromNumber(2, true),\n        },\n        x => {\n          expect(x.uint64).toEqual(Long.fromNumber(1, true));\n          expect(x.fixed64).toEqual(Long.fromNumber(2, true));\n        },\n      );\n    });\n    it('large values', () => {\n      testMessage(\n        test.Message,\n        {\n          uint64: Long.fromBits(UINT32_MAX, UINT32_MAX, true),\n          fixed64: Long.fromBits(UINT32_MAX, UINT32_MAX, true),\n        },\n        x => {\n          expect(x.uint64).toEqual(Long.fromBits(UINT32_MAX, UINT32_MAX, true));\n          expect(x.fixed64).toEqual(Long.fromBits(UINT32_MAX, UINT32_MAX, true));\n        },\n      );\n      testMessage(\n        test.Message,\n        {\n          uint64: Long.fromNumber(UINT32_MAX + 1, true),\n          fixed64: Long.fromNumber(UINT32_MAX + 1, true),\n        },\n        x => {\n          expect(x.uint64).toEqual(Long.fromNumber(UINT32_MAX + 1, true));\n          expect(x.fixed64).toEqual(Long.fromNumber(UINT32_MAX + 1, true));\n        },\n      );\n      testMessage(\n        test.Message,\n        {\n          uint64: Long.fromNumber(INT32_MAX + 1, true),\n          fixed64: Long.fromNumber(INT32_MAX + 1, true),\n        },\n        x => {\n          expect(x.uint64).toEqual(Long.fromNumber(INT32_MAX + 1, true));\n          expect(x.fixed64).toEqual(Long.fromNumber(INT32_MAX + 1, true));\n        },\n      );\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.uint64).toEqual([]);\n        expect(x.fixed64).toEqual([]);\n      });\n    });\n    it('normal repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          uint64: [Long.fromNumber(1, true), Long.fromNumber(2, true)],\n          fixed64: [Long.fromNumber(3, true), Long.fromNumber(4, true)],\n        },\n        x => {\n          expect(x.uint64).toEqual([Long.fromNumber(1, true), Long.fromNumber(2, true)]);\n          expect(x.fixed64).toEqual([Long.fromNumber(3, true), Long.fromNumber(4, true)]);\n        },\n      );\n    });\n    it('large repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          uint64: [Long.fromBits(UINT32_MAX, UINT32_MAX, true)],\n          fixed64: [Long.fromBits(UINT32_MAX, UINT32_MAX, true)],\n        },\n        x => {\n          expect(x.uint64).toEqual([Long.fromBits(UINT32_MAX, UINT32_MAX, true)]);\n          expect(x.fixed64).toEqual([Long.fromBits(UINT32_MAX, UINT32_MAX, true)]);\n        },\n      );\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        {\n          uint64: Long.fromNumber(1, true),\n          fixed64: Long.fromNumber(2, true),\n        },\n        x => {\n          expect(x.uint64).toEqual(Long.fromNumber(2, true));\n          expect(x.fixed64).toEqual(Long.fromNumber(3, true));\n        },\n        x => {\n          x.uint64 = Long.fromNumber(2, true);\n          x.fixed64 = Long.fromNumber(3, true);\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        {\n          uint64: Long.fromNumber(1, true),\n          fixed64: Long.fromNumber(2, true),\n        },\n        x => {\n          expect(x.uint64).toEqual(Long.fromNumber(0, true));\n          expect(x.fixed64).toEqual(Long.fromNumber(0, true));\n        },\n        x => {\n          x.uint64 = undefined as any;\n          x.fixed64 = undefined as any;\n        },\n      );\n    });\n\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          uint64: [Long.fromNumber(1, true)],\n          fixed64: [Long.fromNumber(2, true)],\n        },\n        x => {\n          expect(x.uint64).toEqual([Long.fromNumber(1, true), Long.fromNumber(101, true)]);\n          expect(x.fixed64).toEqual([Long.fromNumber(2, true), UINT64_MIN, UINT64_MAX]);\n        },\n        x => {\n          x.uint64 = [...x.uint64, Long.fromNumber(101, true)];\n          x.fixed64 = [...x.fixed64, UINT64_MIN, UINT64_MAX];\n        },\n      );\n    });\n  });\n\n  describe('float fields', () => {\n    function floor(value: number, decimals: number): number {\n      const pow = Math.pow(10, decimals);\n      return Math.floor(value * pow) / pow;\n    }\n    function ceil(value: number, decimals: number): number {\n      const pow = Math.pow(10, decimals);\n      return Math.ceil(value * pow) / pow;\n    }\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.float).toEqual(0);\n      });\n    });\n    it('positive values', () => {\n      testMessage(test.Message, { float: 1 }, x => {\n        expect(x.float).toEqual(1);\n      });\n      testMessage(test.Message, { float: 100.123 }, x => {\n        expect(floor(x.float, 3)).toEqual(100.123);\n      });\n    });\n    it('negative values', () => {\n      testMessage(test.Message, { float: -1 }, x => {\n        expect(x.float).toEqual(-1);\n      });\n      testMessage(test.Message, { float: -100.123 }, x => {\n        expect(ceil(x.float, 3)).toEqual(-100.123);\n      });\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.float).toEqual([]);\n      });\n    });\n    it('repeated values', () => {\n      testMessage(test.RepeatedMessage, { float: [1.1, -2.2] }, x => {\n        expect(x.float.length).toEqual(2);\n        expect(floor(x.float[0], 2)).toEqual(1.1);\n        expect(ceil(x.float[1], 2)).toEqual(-2.2);\n      });\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        { float: 1.1 },\n        x => {\n          expect(floor(x.float, 1)).toEqual(2.2);\n        },\n        x => {\n          x.float *= 2;\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        { float: 1.1 },\n        x => {\n          expect(x.float).toEqual(0);\n        },\n        x => {\n          x.float = undefined as any;\n        },\n      );\n      testMessage(\n        test.Message,\n        { float: 1.1 },\n        x => {\n          expect(x.float).toEqual(0);\n        },\n        x => {\n          x.float = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { float: [1.1] },\n        x => {\n          expect(x.float.length).toEqual(2);\n          expect(floor(x.float[0], 2)).toEqual(1.1);\n          expect(floor(x.float[1], 2)).toEqual(2.2);\n        },\n        x => {\n          x.float = [...x.float, 2.2];\n        },\n      );\n    });\n  });\n\n  describe('double fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.double).toEqual(0);\n      });\n    });\n    it('positive values', () => {\n      testMessage(test.Message, { double: 1 }, x => {\n        expect(x.double).toEqual(1);\n      });\n      testMessage(test.Message, { double: 100.123 }, x => {\n        expect(x.double).toEqual(100.123);\n      });\n    });\n    it('negative values', () => {\n      testMessage(test.Message, { double: -1 }, x => {\n        expect(x.double).toEqual(-1);\n      });\n      testMessage(test.Message, { double: -100.123 }, x => {\n        expect(x.double).toEqual(-100.123);\n      });\n    });\n    it('large values', () => {\n      testMessage(test.Message, { double: UINT32_MAX }, x => {\n        expect(x.double).toEqual(UINT32_MAX);\n      });\n      testMessage(test.Message, { double: -UINT32_MAX }, x => {\n        expect(x.double).toEqual(-UINT32_MAX);\n      });\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.double).toEqual([]);\n      });\n    });\n    it('normal repeated values', () => {\n      testMessage(test.RepeatedMessage, { double: [1.1, 2.2] }, x => {\n        expect(x.double).toEqual([1.1, 2.2]);\n      });\n    });\n    it('large repeated values', () => {\n      testMessage(test.RepeatedMessage, { double: [UINT32_MAX, -UINT32_MAX] }, x => {\n        expect(x.double).toEqual([UINT32_MAX, -UINT32_MAX]);\n      });\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        { double: 1.1 },\n        x => {\n          expect(x.double).toEqual(2.2);\n        },\n        x => {\n          x.double *= 2;\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        { double: 1 },\n        x => {\n          expect(x.double).toEqual(0);\n        },\n        x => {\n          x.double = undefined as any;\n        },\n      );\n      testMessage(\n        test.Message,\n        { double: 1 },\n        x => {\n          expect(x.double).toEqual(0);\n        },\n        x => {\n          x.double = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { double: [1.1] },\n        x => {\n          expect(x.double).toEqual([1.1, 2.2]);\n        },\n        x => {\n          x.double = [...x.double, 2.2];\n        },\n      );\n    });\n  });\n\n  describe('bool fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.bool).toEqual(false);\n      });\n    });\n    it('normal values', () => {\n      testMessage(test.Message, { bool: true }, x => {\n        expect(x.bool).toEqual(true);\n      });\n      testMessage(test.Message, { bool: false }, x => {\n        expect(x.bool).toEqual(false);\n      });\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.bool).toEqual([]);\n      });\n    });\n    it('repeated values', () => {\n      testMessage(test.RepeatedMessage, { bool: [false, true] }, x => {\n        expect(x.bool).toEqual([false, true]);\n      });\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        { bool: false },\n        x => {\n          expect(x.bool).toEqual(true);\n        },\n        x => {\n          x.bool = !x.bool;\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        { bool: true },\n        x => {\n          expect(x.bool).toEqual(false);\n        },\n        x => {\n          x.bool = undefined as any;\n        },\n      );\n      testMessage(\n        test.Message,\n        { bool: true },\n        x => {\n          expect(x.bool).toEqual(false);\n        },\n        x => {\n          x.bool = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { bool: [false] },\n        x => {\n          expect(x.bool).toEqual([false, true]);\n        },\n        x => {\n          x.bool = [...x.bool, true];\n        },\n      );\n    });\n  });\n\n  describe('string fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.string).toEqual('');\n      });\n    });\n    it('empty values', () => {\n      testMessage(test.Message, { string: '' }, x => {\n        expect(x.string).toEqual('');\n      });\n    });\n    it('normal values', () => {\n      testMessage(test.Message, { string: 'abc123' }, x => {\n        expect(x.string).toEqual('abc123');\n      });\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.string).toEqual([]);\n      });\n    });\n    it('repeated values', () => {\n      testMessage(test.RepeatedMessage, { string: ['value1', 'value2', ''] }, x => {\n        expect(x.string).toEqual(['value1', 'value2', '']);\n      });\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        { string: 'value1' },\n        x => {\n          expect(x.string).toEqual('value2');\n        },\n        x => {\n          x.string = 'value2';\n        },\n      );\n      testMessage(\n        test.Message,\n        { string: 'value1' },\n        x => {\n          expect(x.string).toEqual('');\n        },\n        x => {\n          x.string = '';\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        { string: 'value1' },\n        x => {\n          expect(x.string).toEqual('');\n        },\n        x => {\n          x.string = undefined as any;\n        },\n      );\n      testMessage(\n        test.Message,\n        { string: 'value1' },\n        x => {\n          expect(x.string).toEqual('');\n        },\n        x => {\n          x.string = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { string: ['value1'] },\n        x => {\n          expect(x.string).toEqual(['value1', 'value2', 'value3']);\n        },\n        x => {\n          x.string = [...x.string, 'value2', 'value3'];\n        },\n      );\n    });\n  });\n\n  describe('bytes fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.bytes).toEqual(new Uint8Array([]));\n      });\n    });\n    it('normal values', () => {\n      testMessage(test.Message, { bytes: new Uint8Array([0, 1, 2, 3]) }, x => {\n        expect(x.bytes).toEqual(new Uint8Array([0, 1, 2, 3]));\n      });\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.bytes).toEqual([]);\n      });\n    });\n    it('repeated values', () => {\n      testMessage(test.RepeatedMessage, { bytes: [new Uint8Array([1, 2]), new Uint8Array([3, 4])] }, x => {\n        expect(x.bytes).toEqual([new Uint8Array([1, 2]), new Uint8Array([3, 4])]);\n      });\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        { bytes: new Uint8Array([0, 1]) },\n        x => {\n          expect(x.bytes).toEqual(new Uint8Array([0, 1, 2, 3]));\n        },\n        x => {\n          x.bytes = new Uint8Array([0, 1, 2, 3]);\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        { bytes: new Uint8Array([0, 1]) },\n        x => {\n          expect(x.bytes).toEqual(new Uint8Array([]));\n        },\n        x => {\n          x.bytes = undefined as any;\n        },\n      );\n      testMessage(\n        test.Message,\n        { bytes: new Uint8Array([0, 1]) },\n        x => {\n          expect(x.bytes).toEqual(new Uint8Array([]));\n        },\n        x => {\n          x.bytes = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { bytes: [new Uint8Array([0, 1])] },\n        x => {\n          expect(x.bytes).toEqual([new Uint8Array([0, 1]), new Uint8Array([2, 3])]);\n        },\n        x => {\n          x.bytes = [...x.bytes, new Uint8Array([2, 3])];\n        },\n      );\n    });\n  });\n\n  describe('enum fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.enum).toEqual(test.Enum.VALUE_0);\n      });\n    });\n    it('normal values', () => {\n      testMessage(test.Message, { enum: test.Enum.VALUE_0 }, x => {\n        expect(x.enum).toEqual(test.Enum.VALUE_0);\n      });\n      testMessage(test.Message, { enum: test.Enum.VALUE_1 }, x => {\n        expect(x.enum).toEqual(test.Enum.VALUE_1);\n      });\n    });\n    it('unknown values', () => {\n      testMessage(test.Message, { enum: 100 as unknown as test.Enum }, x => {\n        expect(x.enum).toEqual(test.Enum.$UNRECOGNIZED_VALUE);\n      });\n    });\n    it('setting unknown values should be preserved', () => {\n      const arena = new Arena();\n      const newMessage = test.NewEnumMessage.create(arena, {\n        value: test.NewEnumMessage.NewEnum.VALUE_2,\n        repeatedValue: [\n          test.NewEnumMessage.NewEnum.VALUE_1,\n          test.NewEnumMessage.NewEnum.VALUE_2,\n          test.NewEnumMessage.NewEnum.VALUE_3,\n        ],\n        mappedValue: new Map([\n          ['a', test.NewEnumMessage.NewEnum.VALUE_1],\n          ['b', test.NewEnumMessage.NewEnum.VALUE_2],\n          ['c', test.NewEnumMessage.NewEnum.VALUE_3],\n        ]),\n      });\n\n      const oldMessage = test.OldEnumMessage.decode(arena, newMessage.encode());\n      expect(oldMessage.value).toEqual(test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE);\n      expect(oldMessage.repeatedValue).toEqual([\n        test.OldEnumMessage.OldEnum.VALUE_1,\n        test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE,\n        test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE,\n      ]);\n      expect(oldMessage.mappedValue).toEqual(\n        new Map([\n          ['a', test.OldEnumMessage.OldEnum.VALUE_1],\n          ['b', test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE],\n          ['c', test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE],\n        ]),\n      );\n\n      let decodedNewMessage = test.NewEnumMessage.decode(arena, oldMessage.encode());\n      expect(decodedNewMessage.value).toEqual(test.NewEnumMessage.NewEnum.VALUE_2);\n      expect(decodedNewMessage.repeatedValue).toEqual([\n        test.NewEnumMessage.NewEnum.VALUE_1,\n        test.NewEnumMessage.NewEnum.VALUE_2,\n        test.NewEnumMessage.NewEnum.VALUE_3,\n      ]);\n      expect(decodedNewMessage.mappedValue).toEqual(\n        new Map([\n          ['a', test.NewEnumMessage.NewEnum.VALUE_1],\n          ['b', test.NewEnumMessage.NewEnum.VALUE_2],\n          ['c', test.NewEnumMessage.NewEnum.VALUE_3],\n        ]),\n      );\n\n      oldMessage.value = test.NewEnumMessage.NewEnum.VALUE_3 as any;\n      expect(oldMessage.value).toEqual(test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE);\n      oldMessage.repeatedValue = [test.NewEnumMessage.NewEnum.VALUE_2, test.NewEnumMessage.NewEnum.VALUE_3] as any;\n      expect(oldMessage.repeatedValue).toEqual([\n        test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE,\n        test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE,\n      ]);\n      oldMessage.mappedValue = new Map([\n        ['a', test.NewEnumMessage.NewEnum.VALUE_1 as any],\n        ['b', test.NewEnumMessage.NewEnum.VALUE_2 as any],\n        ['c', test.NewEnumMessage.NewEnum.VALUE_3 as any],\n      ]);\n      expect(oldMessage.mappedValue).toEqual(\n        new Map([\n          ['a', test.OldEnumMessage.OldEnum.VALUE_1],\n          ['b', test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE],\n          ['c', test.OldEnumMessage.OldEnum.$UNRECOGNIZED_VALUE],\n        ]),\n      );\n\n      decodedNewMessage = test.NewEnumMessage.decode(arena, oldMessage.encode());\n      expect(decodedNewMessage.value).toEqual(test.NewEnumMessage.NewEnum.VALUE_3);\n      expect(decodedNewMessage.repeatedValue).toEqual([\n        test.NewEnumMessage.NewEnum.VALUE_2,\n        test.NewEnumMessage.NewEnum.VALUE_3,\n      ]);\n      expect(decodedNewMessage.mappedValue).toEqual(\n        new Map([\n          ['a', test.NewEnumMessage.NewEnum.VALUE_1],\n          ['b', test.NewEnumMessage.NewEnum.VALUE_2],\n          ['c', test.NewEnumMessage.NewEnum.VALUE_3],\n        ]),\n      );\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.enum).toEqual([]);\n      });\n    });\n    it('normal repeated values', () => {\n      testMessage(test.RepeatedMessage, { enum: [test.Enum.VALUE_1, test.Enum.VALUE_0] }, x => {\n        expect(x.enum).toEqual([test.Enum.VALUE_1, test.Enum.VALUE_0]);\n      });\n    });\n    it('unknown repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { enum: [test.Enum.VALUE_1, test.Enum.VALUE_0, 100 as unknown as test.Enum] },\n        x => {\n          expect(x.enum).toEqual([test.Enum.VALUE_1, test.Enum.VALUE_0, test.Enum.$UNRECOGNIZED_VALUE]);\n        },\n      );\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        { enum: test.Enum.VALUE_0 },\n        x => {\n          expect(x.enum).toEqual(test.Enum.VALUE_1);\n        },\n        x => {\n          x.enum = test.Enum.VALUE_1;\n        },\n      );\n    });\n    it('setting unknown values', () => {\n      testMessage(\n        test.Message,\n        { enum: test.Enum.VALUE_1 },\n        x => {\n          expect(x.enum).toEqual(test.Enum.$UNRECOGNIZED_VALUE);\n        },\n        x => {\n          x.enum = 100 as unknown as test.Enum;\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        { enum: test.Enum.VALUE_0 },\n        x => {\n          expect(x.enum).toEqual(test.Enum.VALUE_0);\n        },\n        x => {\n          x.enum = undefined as any;\n        },\n      );\n      testMessage(\n        test.Message,\n        { enum: test.Enum.VALUE_0 },\n        x => {\n          expect(x.enum).toEqual(test.Enum.VALUE_0);\n        },\n        x => {\n          x.enum = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { enum: [test.Enum.VALUE_0] },\n        x => {\n          expect(x.enum).toEqual([test.Enum.VALUE_0, test.Enum.VALUE_1]);\n        },\n        x => {\n          x.enum = [...x.enum, test.Enum.VALUE_1];\n        },\n      );\n    });\n    it('setting repeated unknown values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { enum: [test.Enum.VALUE_0] },\n        x => {\n          expect(x.enum).toEqual([test.Enum.VALUE_0, test.Enum.$UNRECOGNIZED_VALUE]);\n        },\n        x => {\n          x.enum = [...x.enum, 100 as unknown as test.Enum];\n        },\n      );\n    });\n  });\n\n  describe('message fields', () => {\n    it('default values', () => {\n      testMessage(test.Message, {}, x => {\n        expect(x.selfMessage).toBeFalsy();\n        expect(x.otherMessage).toBeFalsy();\n      });\n    });\n    it('normal values', () => {\n      testMessage(\n        test.Message,\n        {\n          selfMessage: { int32: 1 },\n          otherMessage: { value: 'value' },\n        },\n        x => {\n          expect(x.selfMessage!.int32).toEqual(1);\n          expect(x.otherMessage!.value).toEqual('value');\n        },\n      );\n    });\n    it('default repeated values', () => {\n      testMessage(test.RepeatedMessage, {}, x => {\n        expect(x.selfMessage).toEqual([]);\n        expect(x.otherMessage).toEqual([]);\n      });\n    });\n    it('repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          selfMessage: [{ int32: [1] }, { int32: [2] }],\n          otherMessage: [{ value: 'value1' }, { value: 'value2' }],\n        },\n        x => {\n          expect(x.selfMessage.length).toEqual(2);\n          expect(x.selfMessage[0].int32).toEqual([1]);\n          expect(x.selfMessage[1].int32).toEqual([2]);\n          expect(x.otherMessage.length).toEqual(2);\n          expect(x.otherMessage[0].value).toEqual('value1');\n          expect(x.otherMessage[1].value).toEqual('value2');\n        },\n      );\n    });\n    it('setting values', () => {\n      testMessage(\n        test.Message,\n        {},\n        x => {\n          expect(x.selfMessage!.int32).toEqual(1);\n        },\n        (x, arena) => {\n          x.selfMessage = test.Message.create(arena, { int32: 1 });\n        },\n      );\n      testMessage(\n        test.Message,\n        {},\n        x => {\n          expect(x.otherMessage!.value).toEqual('value');\n        },\n        (x, arena) => {\n          x.otherMessage = test.OtherMessage.create(arena, { value: 'value' });\n        },\n      );\n    });\n    it('setting null values', () => {\n      testMessage(\n        test.Message,\n        {\n          selfMessage: { int32: 100 },\n          otherMessage: { value: 'value' },\n        },\n        x => {\n          expect(x.selfMessage).toBeFalsy();\n          expect(x.otherMessage).toBeFalsy();\n        },\n        x => {\n          x.selfMessage = undefined;\n          x.otherMessage = undefined as any;\n        },\n      );\n    });\n    it('setting repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {},\n        x => {\n          expect(x.selfMessage[0].int32).toEqual([1]);\n        },\n        (x, arena) => {\n          x.selfMessage = [test.RepeatedMessage.create(arena, { int32: [1] })];\n        },\n      );\n      testMessage(\n        test.RepeatedMessage,\n        {},\n        x => {\n          expect(x.otherMessage[0].value).toEqual('value');\n        },\n        (x, arena) => {\n          x.otherMessage = [test.OtherMessage.create(arena, { value: 'value' })];\n        },\n      );\n      testMessage(\n        test.RepeatedMessage,\n        {\n          otherMessage: [{ value: 'abc' }],\n        },\n        x => {\n          expect(x.otherMessage[0].value).toEqual('value');\n        },\n        (x, arena) => {\n          x.otherMessage = [test.OtherMessage.create(arena, { value: 'value' })];\n        },\n      );\n    });\n    it('mutating repeated values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          otherMessage: [{ value: 'value' }],\n        },\n        x => {\n          expect(x.otherMessage[0].value).toEqual('abc');\n        },\n        x => {\n          x.otherMessage[0].value = 'abc';\n        },\n      );\n    });\n    it('highly nested values', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          int32: [-10],\n          selfMessage: [\n            {\n              int32: [-20],\n              selfMessage: [\n                {\n                  int32: [1],\n                  otherMessage: [{ value: 'value' }],\n                },\n                {\n                  int32: [2],\n                  otherMessage: [{ value: 'value2' }],\n                },\n              ],\n              otherMessage: [{ value: 'value3' }],\n            },\n          ],\n        },\n        x => {\n          expect(x.int32).toEqual([-10]);\n          expect(x.selfMessage[0].int32).toEqual([-20]);\n          expect(x.selfMessage[0].selfMessage[0].int32).toEqual([1]);\n          expect(x.selfMessage[0].selfMessage[0].otherMessage[0].value).toEqual('test');\n          expect(x.selfMessage[0].selfMessage[1].int32).toEqual([2, 3]);\n          expect(x.selfMessage[0].selfMessage[1].otherMessage[0].value).toEqual('abc1');\n          expect(x.selfMessage[0].otherMessage[0].value).toEqual('value3');\n          expect(x.otherMessage[0].value).toEqual('abc2');\n        },\n        (x, arena) => {\n          x.selfMessage[0].selfMessage[1].int32 = [2, 3];\n          x.selfMessage[0].selfMessage[0].otherMessage = [test.OtherMessage.create(arena, { value: 'test' })];\n          x.selfMessage[0].selfMessage[1].otherMessage[0].value = 'abc1';\n          x.otherMessage = [test.OtherMessage.create(arena, { value: 'abc2' })];\n        },\n      );\n    });\n    it('updating fields on a referenced message', () => {\n      const arena = new Arena();\n      const otherMessage = test.OtherMessage.create(arena, { value: 'value' });\n      const message1 = test.Message.create(arena, { otherMessage });\n\n      const expectValue = (value: string) => {\n        expect(otherMessage.value).toEqual(value);\n        expect(message1.otherMessage?.value).toEqual(value);\n        expect(test.Message.decode(arena, message1.encode()).otherMessage?.value).toEqual(value);\n        expect(test.OtherMessage.decode(arena, otherMessage.encode()).value).toEqual(value);\n      };\n\n      expectValue('value');\n      otherMessage.value = 'value2';\n      expectValue('value2');\n      otherMessage.value = 'value3';\n      expectValue('value3');\n    });\n    it('reordering repeated fields', () => {\n      testMessage(\n        test.RepeatedMessage,\n        {\n          otherMessage: [{ value: 'value1' }, { value: 'value2' }],\n        },\n        x => {\n          expect(x.otherMessage[0].value).toEqual('value2');\n          expect(x.otherMessage[1].value).toEqual('value1');\n        },\n        x => {\n          const [v0, v1] = x.otherMessage;\n          x.otherMessage = [v1, v0];\n        },\n      );\n    });\n    it('reusing repeated field values', () => {\n      const arena = new Arena();\n      const message = test.RepeatedMessage.decode(\n        arena,\n        test.RepeatedMessage.create(arena, {\n          otherMessage: [\n            test.OtherMessage.create(arena, { value: 'value1' }),\n            test.OtherMessage.create(arena, { value: 'value2' }),\n          ],\n        }).encode(),\n      );\n\n      const otherMessage1 = message.otherMessage[0];\n      const otherMessage2 = message.otherMessage[1];\n      message.otherMessage = [otherMessage2];\n      const decoded1 = test.RepeatedMessage.decode(arena, message.encode());\n      expect(decoded1.otherMessage.length).toEqual(1);\n      expect(decoded1.otherMessage[0].value).toEqual('value2');\n\n      const message2 = test.RepeatedMessage.create(arena, { otherMessage: [otherMessage2.clone(), otherMessage1] });\n      const decoded2 = test.RepeatedMessage.decode(arena, message2.encode());\n      expect(decoded2.otherMessage.length).toEqual(2);\n      expect(decoded2.otherMessage[0].value).toEqual('value2');\n      expect(decoded2.otherMessage[1].value).toEqual('value1');\n    });\n  });\n\n  describe('one-of fields', () => {\n    it('default values', () => {\n      testMessage(test.OneOfMessage, {}, x => {\n        expect(x.string0).toEqual('');\n        expect(x.string1).toEqual('');\n        expect(x.message0).toBeFalsy();\n        expect(x.message1).toBeFalsy();\n        expect(x.bytes0).toEqual(new Uint8Array([]));\n        expect(x.bytes1).toEqual(new Uint8Array([]));\n      });\n    });\n\n    it('should always serialize default values', () => {\n      testMessage(\n        test.OneOfMessage,\n        {\n          message1: {},\n        },\n        x => {\n          expect(x.string0).toEqual('');\n          expect(x.string1).toEqual('');\n          expect(x.message0).toBeFalsy();\n          expect(x.message1).toBeTruthy();\n          expect(x.bytes0).toEqual(new Uint8Array([]));\n          expect(x.bytes1).toEqual(new Uint8Array([]));\n        },\n      );\n    });\n\n    it('normal values', () => {\n      testMessage(\n        test.OneOfMessage,\n        {\n          string0: 'value',\n          message0: { value: 'abc' },\n          bytes0: new Uint8Array([1, 2, 3, 4]),\n        },\n        x => {\n          expect(x.string0).toEqual('value');\n          expect(x.string1).toEqual('');\n          expect(x.message0!.value).toEqual('abc');\n          expect(x.message1).toBeFalsy();\n          expect(x.bytes0).toEqual(new Uint8Array([1, 2, 3, 4]));\n          expect(x.bytes1).toEqual(new Uint8Array([]));\n        },\n      );\n    });\n    it('updating values should clear others', () => {\n      testMessage(\n        test.OneOfMessage,\n        {\n          string0: 'value',\n          message0: { value: 'abc' },\n          bytes0: new Uint8Array([1, 2, 3, 4]),\n        },\n        x => {\n          expect(x.string0).toEqual('');\n          expect(x.string1).toEqual('abc');\n          expect(x.message0).toBeFalsy();\n          expect(x.message1?.value).toEqual('def');\n          expect(x.bytes0).toEqual(new Uint8Array([]));\n          expect(x.bytes1).toEqual(new Uint8Array([5, 6, 7, 8]));\n        },\n        (x, arena) => {\n          x.string1 = 'abc';\n          x.message1 = test.OtherMessage.create(arena, { value: 'def' });\n          x.bytes1 = new Uint8Array([5, 6, 7, 8]);\n        },\n      );\n    });\n  });\n\n  describe('map fields', () => {\n    it('default values', () => {\n      testMessage(test.MapMessage, {}, x => {\n        expect(x.stringToString.values.length).toEqual(0);\n        expect(x.stringToNumber.values.length).toEqual(0);\n        expect(x.stringToUnsignedLong.values.length).toEqual(0);\n        expect(x.stringToSignedLong.values.length).toEqual(0);\n        expect(x.stringToMessage.values.length).toEqual(0);\n      });\n    });\n    it('string to string', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToString: new Map([['a', 'b']]),\n        },\n        x => {\n          expect(x.stringToString).toEqual(new Map([['a', 'b']]));\n        },\n      );\n    });\n    it('updating string to string', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToString: new Map([['a', 'b']]),\n        },\n        x => {\n          expect(x.stringToString).toEqual(\n            new Map([\n              ['a', 'e'],\n              ['c', 'd'],\n            ]),\n          );\n        },\n        x => {\n          x.stringToString = new Map([\n            ['a', 'e'],\n            ['c', 'd'],\n          ]);\n        },\n      );\n    });\n    it('string to number', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToNumber: new Map([['a', 1]]),\n        },\n        x => {\n          expect(x.stringToNumber).toEqual(new Map([['a', 1]]));\n        },\n      );\n    });\n    it('updating string to string', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToNumber: new Map([['a', 1]]),\n        },\n        x => {\n          expect(x.stringToNumber).toEqual(\n            new Map([\n              ['a', 2],\n              ['b', 3],\n            ]),\n          );\n        },\n        x => {\n          x.stringToNumber = new Map([\n            ['a', 2],\n            ['b', 3],\n          ]);\n        },\n      );\n    });\n    it('string to long', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToUnsignedLong: new Map([['a', Long.fromNumber(123, true)]]),\n          stringToSignedLong: new Map([['a', Long.fromNumber(123, false)]]),\n        },\n        x => {\n          expect(x.stringToUnsignedLong).toEqual(new Map([['a', Long.fromNumber(123, true)]]));\n          expect(x.stringToSignedLong).toEqual(new Map([['a', Long.fromNumber(123, false)]]));\n        },\n      );\n    });\n    it('updating string to long', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToUnsignedLong: new Map([['a', Long.fromNumber(123, true)]]),\n          stringToSignedLong: new Map([['a', Long.fromNumber(123, false)]]),\n        },\n        x => {\n          expect(x.stringToUnsignedLong).toEqual(\n            new Map([\n              ['a', Long.fromNumber(2, true)],\n              ['b', Long.fromNumber(3, true)],\n            ]),\n          );\n          expect(x.stringToSignedLong).toEqual(\n            new Map([\n              ['a', Long.fromNumber(2, false)],\n              ['b', Long.fromNumber(3, false)],\n            ]),\n          );\n        },\n        x => {\n          x.stringToUnsignedLong = new Map([\n            ['a', Long.fromNumber(2, true)],\n            ['b', Long.fromNumber(3, true)],\n          ]);\n          x.stringToSignedLong = new Map([\n            ['a', Long.fromNumber(2, false)],\n            ['b', Long.fromNumber(3, false)],\n          ]);\n        },\n      );\n    });\n    it('string to double', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToDouble: new Map([['a', 123.123]]),\n        },\n        x => {\n          expect(x.stringToDouble).toEqual(new Map([['a', 123.123]]));\n        },\n      );\n    });\n    it('updating string to double', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToDouble: new Map([['a', 123.123]]),\n        },\n        x => {\n          expect(x.stringToDouble).toEqual(\n            new Map([\n              ['a', 123.234],\n              ['b', 100.543],\n            ]),\n          );\n        },\n        x => {\n          x.stringToDouble = new Map([\n            ['a', 123.234],\n            ['b', 100.543],\n          ]);\n        },\n      );\n    });\n    it('string to message', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToMessage: new Map([['a', { value: '123' }]]),\n        },\n        x => {\n          expect(x.stringToMessage.size).toEqual(1);\n          expect(x.stringToMessage.get('a')?.value).toEqual('123');\n        },\n      );\n    });\n    it('updating string to message', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToMessage: new Map([['a', { value: '123' }]]),\n        },\n        x => {\n          expect(x.stringToMessage.size).toEqual(2);\n          expect(x.stringToMessage.get('a')?.value).toEqual('234');\n          expect(x.stringToMessage.get('b')?.value).toEqual('xyz');\n        },\n        (x, arena) => {\n          x.stringToMessage = new Map([\n            ['a', test.OtherMessage.create(arena, { value: '234' })],\n            ['b', test.OtherMessage.create(arena, { value: 'xyz' })],\n          ]);\n        },\n      );\n    });\n    it('appending message to string to message', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          stringToMessage: new Map([['a', { value: '123' }]]),\n        },\n        x => {\n          expect(x.stringToMessage.size).toEqual(2);\n          expect(x.stringToMessage.get('a')?.value).toEqual('123');\n          expect(x.stringToMessage.get('b')?.value).toEqual('456');\n        },\n        x => {\n          const originalMessage = x.stringToMessage.get('a')!;\n          const newMessage = test.OtherMessage.create(x.$arena, { value: '456' });\n\n          x.stringToMessage = new Map([\n            ['a', originalMessage],\n            ['b', newMessage],\n          ]);\n        },\n      );\n    });\n    it('updating string to message values through reference', () => {\n      const arena = new Arena();\n      const otherMessage = test.OtherMessage.create(arena, { value: '123' });\n      const x = test.MapMessage.create(arena, {\n        stringToMessage: new Map([['a', otherMessage]]),\n      });\n      expect(x.stringToMessage.get('a')!.value).toEqual('123');\n      otherMessage.value = '234';\n      expect(x.stringToMessage.get('a')!.value).toEqual('234');\n      otherMessage.value = '345';\n      const decoded = test.MapMessage.decode(arena, x.encode());\n      expect(x.stringToMessage.get('a')!.value).toEqual('345');\n      otherMessage.value = '456';\n      expect(x.stringToMessage.get('a')!.value).toEqual('456');\n      expect(decoded.stringToMessage.get('a')!.value).toEqual('345');\n    });\n    it('int to string', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          intToString: new Map([[100, 'b']]),\n        },\n        x => {\n          expect(x.intToString).toEqual(new Map([[100, 'b']]));\n        },\n      );\n    });\n    it('updating int to string', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          intToString: new Map([[100, 'a']]),\n        },\n        x => {\n          expect(x.intToString).toEqual(\n            new Map([\n              [100, 'b'],\n              [200, 'c'],\n            ]),\n          );\n        },\n        x => {\n          x.intToString = new Map([\n            [100, 'b'],\n            [200, 'c'],\n          ]);\n        },\n      );\n    });\n    it('long to string', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          longToString: new Map([[Long.fromNumber(100, true), 'b']]),\n        },\n        x => {\n          const keys = Array.from(x.longToString.keys());\n          expect(x.longToString.get(keys[0])).toEqual('b');\n        },\n      );\n    });\n    it('updating long to string', () => {\n      testMessage(\n        test.MapMessage,\n        {\n          longToString: new Map([[Long.fromNumber(100, true), 'a']]),\n        },\n        x => {\n          const keys = Array.from(x.longToString.keys());\n          expect(x.longToString.get(keys[0])).toEqual('b');\n        },\n        x => {\n          const keys = Array.from(x.longToString.keys());\n          const newMap = new Map(x.longToString);\n          newMap.set(keys[0], 'b');\n          x.longToString = newMap;\n        },\n      );\n    });\n    it('should be mutable', () => {\n      testMessage(\n        test.MapMessage,\n        { stringToString: new Map([['a', 'abc']]) },\n        x => {\n          expect(x.stringToString.get('a')).toEqual('123');\n          expect(x.stringToString.get('b')).toEqual('def');\n          expect(x.stringToDouble.get('c')).toEqual(100.123);\n        },\n        x => {\n          const newStringToString = new Map(x.stringToString);\n          const newStringToDouble = new Map(x.stringToDouble);\n\n          newStringToString.set('a', '123');\n          newStringToString.set('b', 'def');\n          newStringToDouble.set('c', 100.123);\n\n          x.stringToString = newStringToString;\n          x.stringToDouble = newStringToDouble;\n        },\n      );\n    });\n  });\n\n  describe('repeated fields', () => {\n    it('should be mutable', () => {\n      testMessage(\n        test.RepeatedMessage,\n        { string: ['abc'] },\n        x => {\n          expect(x.string).toEqual(['abc', '123']);\n          expect(x.double).toEqual([100.123, 200.123]);\n        },\n        x => {\n          x.string = [...x.string, '123'];\n          x.double = [...x.double, 100.123, 200.123];\n        },\n      );\n    });\n  });\n\n  it('nested messages and enums should work', () => {\n    const arena = new Arena();\n    const child = test.ParentMessage.ChildMessage.create(arena, {});\n    expect(child).toBeTruthy();\n\n    testMessage(test.ParentMessage.ChildMessage, { value: 'val' }, x => {\n      expect(x.value).toEqual('val');\n    });\n    testMessage(\n      test.ParentMessage,\n      {\n        childEnum: test.ParentMessage.ChildEnum.VALUE_1,\n        childMessage: { value: 'val' },\n      },\n      x => {\n        expect(x.childEnum).toEqual(test.ParentMessage.ChildEnum.VALUE_1);\n        expect(x.childMessage!.value).toEqual('val');\n      },\n    );\n  });\n\n  describe('external messages', () => {\n    it('messages from another file', () => {\n      testMessage(\n        test.ExternalMessages,\n        {\n          otherMessage: { value: 'abc' },\n        },\n        x => {\n          expect(x.otherMessage!.value).toEqual('abc');\n        },\n      );\n    });\n  });\n\n  it('unknown fields should be preserved', () => {\n    const arena = new Arena();\n    const newMessage = test.NewMessage.create(arena, { oldValue: 'old', newValue: 'new' });\n    const oldMessage = test.OldMessage.decode(arena, newMessage.encode());\n    expect(oldMessage.oldValue).toEqual('old');\n    oldMessage.oldValue = 'old2';\n    const decodedNewMessage = test.NewMessage.decode(arena, oldMessage.encode());\n    expect(decodedNewMessage.oldValue).toEqual('old2');\n    expect(decodedNewMessage.newValue).toEqual('new');\n  });\n\n  describe('message properties', () => {\n    it('message destructuring should work correctly', () => {\n      const arena = new Arena();\n      const message = test.Message.create(arena, { int32: 1, string: 'a' });\n      const { int32, string } = message;\n      expect(int32).toEqual(1);\n      expect(string).toEqual('a');\n    });\n    it('message keys should contain all available fields', () => {\n      const arena = new Arena();\n      const message = test.ParentMessage.create(arena);\n      const allKeys = [];\n      for (const key in message) {\n        if (!key.startsWith('$')) {\n          allKeys.push(key);\n        }\n      }\n      const keySet = new Set(allKeys);\n      expect(keySet.size).toEqual(2);\n      expect(keySet.has('childMessage')).toBeTruthy();\n      expect(keySet.has('childEnum')).toBeTruthy();\n    });\n  });\n\n  describe('bad inputs', () => {\n    it('decoding bad data should throw', () => {\n      const arena = new Arena();\n      expect(() => test.Message.decode(arena, new Uint8Array([0, 1, 2, 3]))).toThrow();\n      expect(() => test.Message.decode(arena, undefined as any)).toThrow();\n      expect(() => test.Message.decode(arena, null as any)).toThrow();\n      expect(() => test.Message.decode(arena, 'abc' as any)).toThrow();\n      expect(() => test.Message.decode(arena, 123 as any)).toThrow();\n      expect(() => test.Message.decode(arena, {} as any)).toThrow();\n    });\n  });\n\n  describe('multiple arenas', () => {\n    it('setting message value from a different arena', () => {\n      const message1 = test.Message.create(new Arena(), { int32: 100 });\n      const message2 = test.Message.create(new Arena(), { int32: 200 });\n      message1.selfMessage = message2;\n      expect(message1.selfMessage?.int32).toEqual(message2.int32);\n    });\n    it('create message with field from a different arena', () => {\n      const message = test.Message.create(new Arena(), {\n        int32: 100,\n        selfMessage: test.Message.create(new Arena(), {\n          int32: 200,\n        }),\n      });\n      expect(message.int32).toEqual(100);\n      expect(message.selfMessage?.int32).toEqual(200);\n    });\n    it('setting cloned message value from a different arena', () => {\n      const message1 = test.Message.create(new Arena(), { int32: 100 });\n      const message2 = test.Message.create(new Arena(), { int32: 200 });\n      message1.selfMessage = message2.clone();\n      expect(message1.selfMessage?.int32).toEqual(message2.int32);\n    });\n    it('setting cloned message value from the same arena', () => {\n      const message1 = test.Message.create(new Arena(), { int32: 100 });\n      const message2 = test.Message.create(new Arena(), { int32: 200 });\n      message1.selfMessage = message2.clone(message1.$arena);\n      expect(message1.selfMessage?.int32).toEqual(message2.int32);\n    });\n  });\n\n  describe('to plain object conversion', () => {\n    it('can copy values', () => {\n      const message = test.Message.create(new Arena(), { uint32: 42, string: 'hello' });\n      const newMessage = message.toPlainObject() as test.IMessage;\n\n      expect((newMessage as any).prototype).toBeUndefined();\n      expect(newMessage.uint32).toBe(42);\n      expect(newMessage.string).toBe('hello');\n      expect(newMessage).not.toEqual(message);\n    });\n\n    it('responds to Object.keys()', () => {\n      const message = test.Message.create(new Arena(), {});\n\n      const newMessage = message.toPlainObject();\n      expect(Object.keys(newMessage)).toEqual([\n        'int32',\n        'int64',\n        'uint32',\n        'uint64',\n        'sint32',\n        'sint64',\n        'fixed32',\n        'fixed64',\n        'sfixed32',\n        'sfixed64',\n        'float',\n        'double',\n        'bool',\n        'string',\n        'bytes',\n        'enum',\n      ]);\n    });\n\n    it('can be copied through spread', () => {\n      const message = test.Message.create(new Arena(), { uint32: 42, string: 'hello' });\n      const newMessage = message.toPlainObject();\n\n      const newMessage2 = { ...newMessage };\n\n      expect(newMessage).not.toBe(newMessage2);\n      expect(newMessage).toEqual(newMessage2);\n    });\n\n    it('copies sub messages', () => {\n      const message = test.Message.create(new Arena(), { uint32: 42, selfMessage: { string: 'hello' } });\n      const newMessage = message.toPlainObject() as test.IMessage;\n\n      expect(newMessage.uint32).toBe(42);\n      expect(newMessage.selfMessage).toBeTruthy();\n      expect((newMessage.selfMessage! as any).prototype).toBeUndefined();\n      expect(newMessage.selfMessage!.string).toBe('hello');\n    });\n\n    it('copies repeated messages', () => {\n      const message = test.RepeatedMessage.create(new Arena(), {\n        uint32: [1, 2],\n        selfMessage: [test.RepeatedMessage.create(new Arena(), { string: ['foo', 'bar'] })],\n      });\n      const newMessage = message.toPlainObject() as test.IRepeatedMessage;\n\n      expect(newMessage.uint32).toEqual([1, 2]);\n      expect(newMessage.selfMessage).toBeTruthy();\n      expect((newMessage.selfMessage! as any).prototype).toBeUndefined();\n      expect(newMessage.selfMessage!.length).toBe(1);\n      expect((newMessage.selfMessage![0] as any).prototype).toBeUndefined();\n      expect(newMessage.selfMessage![0].string).toEqual(['foo', 'bar']);\n    });\n\n    it('copies map messages', () => {\n      const message = test.MapMessage.create(new Arena(), {\n        stringToMessage: new Map([['foo', test.OtherMessage.create(new Arena(), { value: 'bar' })]]),\n      });\n      const newMessage = message.toPlainObject() as test.IMapMessage;\n\n      expect(newMessage.stringToMessage).toBeTruthy();\n      expect(newMessage.stringToMessage?.size).toEqual(1);\n      expect((newMessage.stringToMessage?.get('foo') as any).prototype).toBeUndefined();\n      expect(newMessage.stringToMessage?.get('foo')).toEqual({ value: 'bar' });\n    });\n  });\n\n  describe('underscores in names', () => {\n    it('package, message, and field names', () => {\n      testMessage(\n        package_with_underscores.Message_With_Underscores,\n        {\n          fieldUnderscore: 1,\n          fieldUnderscoreAgain: 2,\n          enumValue: package_with_underscores.Enum_With_Underscores.ENUM_VALUE_0,\n        },\n        msg => {\n          expect(msg.fieldUnderscore).toEqual(100);\n          expect(msg.fieldUnderscoreAgain).toEqual(200);\n          expect(msg.enumValue).toEqual(package_with_underscores.Enum_With_Underscores.ENUM_VALUE_1);\n          expect(msg.messageValue?.fieldUnderscore).toEqual(1);\n        },\n        (msg, arena) => {\n          msg.fieldUnderscore = 100;\n          msg.fieldUnderscoreAgain = 200;\n          msg.enumValue = package_with_underscores.Enum_With_Underscores.ENUM_VALUE_1;\n          msg.messageValue = package_with_underscores.Message_With_Underscores.create(arena, {\n            fieldUnderscore: 1,\n          });\n        },\n      );\n    });\n  });\n  it('field names with numbers', () => {\n    testMessage(\n      package_with_underscores.M3ssage1WithNumb3r2,\n      {\n        fie1ld: 1,\n        field2: 2,\n        field3: 3,\n        a4Fiel4d: 4,\n        a5aFiel5d: 5,\n        enum: package_with_underscores.Enum_With_Underscores.E2NUM_VALUE_WITH_NUMBER,\n      },\n      msg => {\n        expect(msg.fie1ld).toEqual(100);\n        expect(msg.field2).toEqual(200);\n        expect(msg.field3).toEqual(300);\n        expect(msg.a4Fiel4d).toEqual(400);\n        expect(msg.a5aFiel5d).toEqual(500);\n        expect(msg.enum).toEqual(package_with_underscores.Enum_With_Underscores.E2NUM_VALUE_WITH_NUMBER);\n      },\n      msg => {\n        msg.fie1ld = 100;\n        msg.field2 = 200;\n        msg.field3 = 300;\n        msg.a4Fiel4d = 400;\n        msg.a5aFiel5d = 500;\n      },\n    );\n  });\n  describe('async', () => {\n    it('can encode async', async () => {\n      const arena = new Arena();\n\n      const message = test.Message.create(arena, {\n        bool: true,\n        sfixed32: 42,\n        string: 'Hello World',\n      });\n\n      const encoded = await message.encodeAsync();\n\n      const decoded = test.Message.decode(arena, encoded);\n\n      expect(decoded.bool).toEqual(true);\n      expect(decoded.sfixed32).toEqual(42);\n      expect(decoded.string).toEqual('Hello World');\n    });\n\n    it('can decode async', async () => {\n      const encoded = test.Message.encode({\n        bool: true,\n        sfixed32: 42,\n        string: 'Hello World',\n      });\n\n      const arena = new Arena();\n      const decoded = await test.Message.decodeAsync(arena, encoded);\n\n      expect(decoded.bool).toEqual(true);\n      expect(decoded.sfixed32).toEqual(42);\n      expect(decoded.string).toEqual('Hello World');\n    });\n\n    it('can encode async in batch', async () => {\n      const arena = new Arena();\n\n      const message1 = test.Message.create(arena, {\n        bool: true,\n        sfixed32: 1,\n        string: 'Hello World',\n      });\n      const message2 = test.Message.create(arena, {\n        bool: false,\n        sfixed32: 2,\n        string: 'Goodbye',\n      });\n      const message3 = test.Message.create(arena, {\n        bool: true,\n        sfixed32: 3,\n        string: 'And Hello Again',\n      });\n\n      const decoded = await arena.batchEncodeMessageAsync([message1, message2, message3]);\n\n      expect(decoded.length).toBe(3);\n\n      const decodedMessages = await Promise.all([\n        test.Message.decodeAsync(arena, decoded[0]),\n        test.Message.decodeAsync(arena, decoded[1]),\n        test.Message.decodeAsync(arena, decoded[2]),\n      ]);\n\n      expect(decodedMessages.length).toBe(3);\n\n      expect(decodedMessages[0].bool).toBe(true);\n      expect(decodedMessages[0].sfixed32).toBe(1);\n      expect(decodedMessages[0].string).toBe('Hello World');\n\n      expect(decodedMessages[1].bool).toBe(false);\n      expect(decodedMessages[1].sfixed32).toBe(2);\n      expect(decodedMessages[1].string).toBe('Goodbye');\n\n      expect(decodedMessages[2].bool).toBe(true);\n      expect(decodedMessages[2].sfixed32).toBe(3);\n      expect(decodedMessages[2].string).toBe('And Hello Again');\n    });\n  });\n\n  describe('JSON', () => {\n    it('can convert message to JSON', () => {\n      const arena = new Arena();\n      const message = test.Message.create(arena, {\n        int32: 42,\n        int64: Long.fromNumber(42000000, false),\n        double: 90.5,\n        float: Infinity,\n        otherMessage: test.OtherMessage.create(arena, {\n          value: 'This is a string',\n        }),\n      });\n\n      const json = message.toDebugJSON();\n      const parsedJson = JSON.parse(json);\n\n      expect(parsedJson).toEqual({\n        int32: 42,\n        double: 90.5,\n        float: 'Infinity',\n        int64: '42000000',\n        otherMessage: {\n          value: 'This is a string',\n        },\n      });\n    });\n\n    it('can parse from JSON', async () => {\n      const arena = new Arena();\n      const message = await test.Message.decodeDebugJSONAsync(\n        arena,\n        '{\"int32\": 42, \"double\": 90.5, \"otherMessage\": { \"value\": \"This is a string\" }}',\n      );\n\n      expect(message.int32).toBe(42);\n      expect(message.double).toBe(90.5);\n      expect(message.otherMessage).toBeDefined();\n      expect(message.otherMessage!.value).toBe('This is a string');\n    });\n  });\n\n  describe('Reflection', () => {\n    it('can parse and load proto files', () => {\n      interface MyTestMessage {\n        title: string;\n        count: number;\n      }\n\n      const descriptor = loadDescriptorPoolFromProtoFiles(\n        'my_test.proto',\n        `\n      syntax = \"proto3\";\n      package my_test;\n\n      message MyTestMessage {\n        string title = 1;\n        int32 count = 2;\n      }\n      `,\n      );\n\n      const messageNamespace = descriptor.getMessageNamespace('my_test.MyTestMessage');\n      expect(messageNamespace).toBeDefined();\n      const message = messageNamespace!.create(new Arena(), {\n        title: 'Hello World',\n        count: 42,\n      }) as unknown as MyTestMessage;\n\n      expect(message.title).toBe('Hello World');\n      expect(message.count).toBe(42);\n    });\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/test/proto.d.ts",
    "content": "import { IArena } from \"valdi_protobuf/src/types\";\nimport { Message as ProtobufMessage } from \"valdi_protobuf/src/Message\";\n\n/**\n * Generated by generate_protos.py\n * DO NOT EDIT!\n */\n\nexport namespace test {\n  export const enum Enum {\n    VALUE_0 = 0,\n    VALUE_1 = 1,\n    /** Unrecognized value */\n    $UNRECOGNIZED_VALUE = 0xffffffffff\n  }\n\n  /**\n   * Test\n   * multiline\n   * comment\n   */\n  export class OtherMessage extends ProtobufMessage<IOtherMessage> {\n    private constructor();\n\n    public get value(): string;\n    public set value(value: string);\n\n    /**\n     * Creates a new OtherMessage from properties\n     * Returns a clone if a OtherMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: OtherMessage | IOtherMessage): OtherMessage;\n    /** Decode a buffer into a OtherMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): OtherMessage;\n    /** Asynchronously decode a buffer into a OtherMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<OtherMessage>;\n    /**\n     * Encodes the provided OtherMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: OtherMessage | IOtherMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided OtherMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: OtherMessage | IOtherMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a OtherMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<OtherMessage>;\n  }\n\n  /** Interface for creating OtherMessage instances */\n  export interface IOtherMessage {\n    value?: string;\n  }\n\n  /**\n   * Test comment\n   * another line\n   */\n  export class Message extends ProtobufMessage<IMessage> {\n    private constructor();\n\n    public get int32(): number;\n    public set int32(value: number);\n\n    public get int64(): Long;\n    public set int64(value: Long);\n\n    public get uint32(): number;\n    public set uint32(value: number);\n\n    public get uint64(): Long;\n    public set uint64(value: Long);\n\n    public get sint32(): number;\n    public set sint32(value: number);\n\n    public get sint64(): Long;\n    public set sint64(value: Long);\n\n    public get fixed32(): number;\n    public set fixed32(value: number);\n\n    public get fixed64(): Long;\n    public set fixed64(value: Long);\n\n    public get sfixed32(): number;\n    public set sfixed32(value: number);\n\n    public get sfixed64(): Long;\n    public set sfixed64(value: Long);\n\n    public get float(): number;\n    public set float(value: number);\n\n    public get double(): number;\n    public set double(value: number);\n\n    public get bool(): boolean;\n    public set bool(value: boolean);\n\n    public get string(): string;\n    public set string(value: string);\n\n    public get bytes(): Uint8Array;\n    public set bytes(value: Uint8Array);\n\n    public get enum(): test.Enum;\n    public set enum(value: test.Enum);\n\n    public get selfMessage(): test.Message | undefined;\n    public set selfMessage(value: test.Message | undefined);\n\n    public get otherMessage(): test.OtherMessage | undefined;\n    public set otherMessage(value: test.OtherMessage | undefined);\n\n    /**\n     * Creates a new Message from properties\n     * Returns a clone if a Message instance is provided\n     */\n    public static create(arena: IArena, properties?: Message | IMessage): Message;\n    /** Decode a buffer into a Message */\n    public static decode(arena: IArena, buffer: Uint8Array): Message;\n    /** Asynchronously decode a buffer into a Message */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<Message>;\n    /**\n     * Encodes the provided Message into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: Message | IMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided Message into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: Message | IMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a Message.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<Message>;\n  }\n\n  /** Interface for creating Message instances */\n  export interface IMessage {\n    int32?: number;\n    int64?: Long;\n    uint32?: number;\n    uint64?: Long;\n    sint32?: number;\n    sint64?: Long;\n    fixed32?: number;\n    fixed64?: Long;\n    sfixed32?: number;\n    sfixed64?: Long;\n    float?: number;\n    double?: number;\n    bool?: boolean;\n    string?: string;\n    bytes?: Uint8Array;\n    enum?: test.Enum;\n    selfMessage?: test.IMessage;\n    otherMessage?: test.IOtherMessage;\n  }\n\n  export class RepeatedMessage extends ProtobufMessage<IRepeatedMessage> {\n    private constructor();\n\n    public get int32(): readonly number[];\n    public set int32(value: readonly number[]);\n\n    public get int64(): readonly Long[];\n    public set int64(value: readonly Long[]);\n\n    public get uint32(): readonly number[];\n    public set uint32(value: readonly number[]);\n\n    public get uint64(): readonly Long[];\n    public set uint64(value: readonly Long[]);\n\n    public get sint32(): readonly number[];\n    public set sint32(value: readonly number[]);\n\n    public get sint64(): readonly Long[];\n    public set sint64(value: readonly Long[]);\n\n    public get fixed32(): readonly number[];\n    public set fixed32(value: readonly number[]);\n\n    public get fixed64(): readonly Long[];\n    public set fixed64(value: readonly Long[]);\n\n    public get sfixed32(): readonly number[];\n    public set sfixed32(value: readonly number[]);\n\n    public get sfixed64(): readonly Long[];\n    public set sfixed64(value: readonly Long[]);\n\n    public get float(): readonly number[];\n    public set float(value: readonly number[]);\n\n    public get double(): readonly number[];\n    public set double(value: readonly number[]);\n\n    public get bool(): readonly boolean[];\n    public set bool(value: readonly boolean[]);\n\n    public get string(): readonly string[];\n    public set string(value: readonly string[]);\n\n    public get bytes(): readonly Uint8Array[];\n    public set bytes(value: readonly Uint8Array[]);\n\n    public get enum(): readonly test.Enum[];\n    public set enum(value: readonly test.Enum[]);\n\n    public get selfMessage(): readonly test.RepeatedMessage[];\n    public set selfMessage(value: readonly test.RepeatedMessage[]);\n\n    public get otherMessage(): readonly test.OtherMessage[];\n    public set otherMessage(value: readonly test.OtherMessage[]);\n\n    /**\n     * Creates a new RepeatedMessage from properties\n     * Returns a clone if a RepeatedMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: RepeatedMessage | IRepeatedMessage): RepeatedMessage;\n    /** Decode a buffer into a RepeatedMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): RepeatedMessage;\n    /** Asynchronously decode a buffer into a RepeatedMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<RepeatedMessage>;\n    /**\n     * Encodes the provided RepeatedMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: RepeatedMessage | IRepeatedMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided RepeatedMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: RepeatedMessage | IRepeatedMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a RepeatedMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<RepeatedMessage>;\n  }\n\n  /** Interface for creating RepeatedMessage instances */\n  export interface IRepeatedMessage {\n    int32?: readonly number[];\n    int64?: readonly Long[];\n    uint32?: readonly number[];\n    uint64?: readonly Long[];\n    sint32?: readonly number[];\n    sint64?: readonly Long[];\n    fixed32?: readonly number[];\n    fixed64?: readonly Long[];\n    sfixed32?: readonly number[];\n    sfixed64?: readonly Long[];\n    float?: readonly number[];\n    double?: readonly number[];\n    bool?: readonly boolean[];\n    string?: readonly string[];\n    bytes?: readonly Uint8Array[];\n    enum?: readonly test.Enum[];\n    selfMessage?: readonly test.IRepeatedMessage[];\n    otherMessage?: readonly test.IOtherMessage[];\n  }\n\n  export class ParentMessage extends ProtobufMessage<IParentMessage> {\n    private constructor();\n\n    public get childMessage(): test.ParentMessage.ChildMessage | undefined;\n    public set childMessage(value: test.ParentMessage.ChildMessage | undefined);\n\n    public get childEnum(): test.ParentMessage.ChildEnum;\n    public set childEnum(value: test.ParentMessage.ChildEnum);\n\n    /**\n     * Creates a new ParentMessage from properties\n     * Returns a clone if a ParentMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: ParentMessage | IParentMessage): ParentMessage;\n    /** Decode a buffer into a ParentMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): ParentMessage;\n    /** Asynchronously decode a buffer into a ParentMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<ParentMessage>;\n    /**\n     * Encodes the provided ParentMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: ParentMessage | IParentMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided ParentMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: ParentMessage | IParentMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a ParentMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<ParentMessage>;\n  }\n\n  /** Interface for creating ParentMessage instances */\n  export interface IParentMessage {\n    childMessage?: test.ParentMessage.IChildMessage;\n    childEnum?: test.ParentMessage.ChildEnum;\n  }\n\n  export namespace ParentMessage {\n    /** Comment for child enum */\n    export const enum ChildEnum {\n      /** Comment for value 0 */\n      VALUE_0 = 0,\n      /** Comment for value 1 */\n      VALUE_1 = 1,\n      /** Unrecognized value */\n      $UNRECOGNIZED_VALUE = 0xffffffffff\n    }\n\n    export class ChildMessage extends ProtobufMessage<IChildMessage> {\n      private constructor();\n\n      public get value(): string;\n      public set value(value: string);\n\n      /**\n       * Creates a new ChildMessage from properties\n       * Returns a clone if a ChildMessage instance is provided\n       */\n      public static create(arena: IArena, properties?: ChildMessage | IChildMessage): ChildMessage;\n      /** Decode a buffer into a ChildMessage */\n      public static decode(arena: IArena, buffer: Uint8Array): ChildMessage;\n      /** Asynchronously decode a buffer into a ChildMessage */\n      public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<ChildMessage>;\n      /**\n       * Encodes the provided ChildMessage into a buffer.\n       * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n       */\n      public static encode(value: ChildMessage | IChildMessage): Uint8Array;\n      /**\n       * Asynchronously encodes the provided ChildMessage into a buffer.\n       * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n       */\n      public static encodeAsync(value: ChildMessage | IChildMessage): Promise<Uint8Array>;\n      /**\n       * Asynchronously decode a JSON string into a ChildMessage.\n       * This is discouraged and should be used as a debug option only.\n       */\n      public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<ChildMessage>;\n    }\n\n    /** Interface for creating ChildMessage instances */\n    export interface IChildMessage {\n      value?: string;\n    }\n  }\n\n  export class OneOfMessage extends ProtobufMessage<IOneOfMessage> {\n    private constructor();\n\n    public get string0(): string;\n    public set string0(value: string);\n\n    public get string1(): string;\n    public set string1(value: string);\n\n    public get message0(): test.OtherMessage | undefined;\n    public set message0(value: test.OtherMessage | undefined);\n\n    public get message1(): test.OtherMessage | undefined;\n    public set message1(value: test.OtherMessage | undefined);\n\n    public get bytes0(): Uint8Array;\n    public set bytes0(value: Uint8Array);\n\n    public get bytes1(): Uint8Array;\n    public set bytes1(value: Uint8Array);\n\n    /**\n     * Creates a new OneOfMessage from properties\n     * Returns a clone if a OneOfMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: OneOfMessage | IOneOfMessage): OneOfMessage;\n    /** Decode a buffer into a OneOfMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): OneOfMessage;\n    /** Asynchronously decode a buffer into a OneOfMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<OneOfMessage>;\n    /**\n     * Encodes the provided OneOfMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: OneOfMessage | IOneOfMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided OneOfMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: OneOfMessage | IOneOfMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a OneOfMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<OneOfMessage>;\n  }\n\n  /** Interface for creating OneOfMessage instances */\n  export interface IOneOfMessage {\n    string0?: string;\n    string1?: string;\n    message0?: test.IOtherMessage;\n    message1?: test.IOtherMessage;\n    bytes0?: Uint8Array;\n    bytes1?: Uint8Array;\n  }\n\n  export class OldMessage extends ProtobufMessage<IOldMessage> {\n    private constructor();\n\n    public get oldValue(): string;\n    public set oldValue(value: string);\n\n    /**\n     * Creates a new OldMessage from properties\n     * Returns a clone if a OldMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: OldMessage | IOldMessage): OldMessage;\n    /** Decode a buffer into a OldMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): OldMessage;\n    /** Asynchronously decode a buffer into a OldMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<OldMessage>;\n    /**\n     * Encodes the provided OldMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: OldMessage | IOldMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided OldMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: OldMessage | IOldMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a OldMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<OldMessage>;\n  }\n\n  /** Interface for creating OldMessage instances */\n  export interface IOldMessage {\n    oldValue?: string;\n  }\n\n  export class NewMessage extends ProtobufMessage<INewMessage> {\n    private constructor();\n\n    public get oldValue(): string;\n    public set oldValue(value: string);\n\n    public get newValue(): string;\n    public set newValue(value: string);\n\n    /**\n     * Creates a new NewMessage from properties\n     * Returns a clone if a NewMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: NewMessage | INewMessage): NewMessage;\n    /** Decode a buffer into a NewMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): NewMessage;\n    /** Asynchronously decode a buffer into a NewMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<NewMessage>;\n    /**\n     * Encodes the provided NewMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: NewMessage | INewMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided NewMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: NewMessage | INewMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a NewMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<NewMessage>;\n  }\n\n  /** Interface for creating NewMessage instances */\n  export interface INewMessage {\n    oldValue?: string;\n    newValue?: string;\n  }\n\n  export class OldEnumMessage extends ProtobufMessage<IOldEnumMessage> {\n    private constructor();\n\n    public get value(): test.OldEnumMessage.OldEnum;\n    public set value(value: test.OldEnumMessage.OldEnum);\n\n    public get repeatedValue(): readonly test.OldEnumMessage.OldEnum[];\n    public set repeatedValue(value: readonly test.OldEnumMessage.OldEnum[]);\n\n    public get mappedValue(): ReadonlyMap<string, test.OldEnumMessage.OldEnum>;\n    public set mappedValue(value: ReadonlyMap<string, test.OldEnumMessage.OldEnum>);\n\n    /**\n     * Creates a new OldEnumMessage from properties\n     * Returns a clone if a OldEnumMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: OldEnumMessage | IOldEnumMessage): OldEnumMessage;\n    /** Decode a buffer into a OldEnumMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): OldEnumMessage;\n    /** Asynchronously decode a buffer into a OldEnumMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<OldEnumMessage>;\n    /**\n     * Encodes the provided OldEnumMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: OldEnumMessage | IOldEnumMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided OldEnumMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: OldEnumMessage | IOldEnumMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a OldEnumMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<OldEnumMessage>;\n  }\n\n  /** Interface for creating OldEnumMessage instances */\n  export interface IOldEnumMessage {\n    value?: test.OldEnumMessage.OldEnum;\n    repeatedValue?: readonly test.OldEnumMessage.OldEnum[];\n    mappedValue?: ReadonlyMap<string, test.OldEnumMessage.OldEnum>;\n  }\n\n  export namespace OldEnumMessage {\n    export const enum OldEnum {\n      VALUE_0 = 0,\n      VALUE_1 = 1,\n      /** Unrecognized value */\n      $UNRECOGNIZED_VALUE = 0xffffffffff\n    }\n  }\n\n  export class NewEnumMessage extends ProtobufMessage<INewEnumMessage> {\n    private constructor();\n\n    public get value(): test.NewEnumMessage.NewEnum;\n    public set value(value: test.NewEnumMessage.NewEnum);\n\n    public get repeatedValue(): readonly test.NewEnumMessage.NewEnum[];\n    public set repeatedValue(value: readonly test.NewEnumMessage.NewEnum[]);\n\n    public get mappedValue(): ReadonlyMap<string, test.NewEnumMessage.NewEnum>;\n    public set mappedValue(value: ReadonlyMap<string, test.NewEnumMessage.NewEnum>);\n\n    /**\n     * Creates a new NewEnumMessage from properties\n     * Returns a clone if a NewEnumMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: NewEnumMessage | INewEnumMessage): NewEnumMessage;\n    /** Decode a buffer into a NewEnumMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): NewEnumMessage;\n    /** Asynchronously decode a buffer into a NewEnumMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<NewEnumMessage>;\n    /**\n     * Encodes the provided NewEnumMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: NewEnumMessage | INewEnumMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided NewEnumMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: NewEnumMessage | INewEnumMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a NewEnumMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<NewEnumMessage>;\n  }\n\n  /** Interface for creating NewEnumMessage instances */\n  export interface INewEnumMessage {\n    value?: test.NewEnumMessage.NewEnum;\n    repeatedValue?: readonly test.NewEnumMessage.NewEnum[];\n    mappedValue?: ReadonlyMap<string, test.NewEnumMessage.NewEnum>;\n  }\n\n  export namespace NewEnumMessage {\n    export const enum NewEnum {\n      VALUE_0 = 0,\n      VALUE_1 = 1,\n      VALUE_2 = 200,\n      VALUE_3 = 300,\n      /** Unrecognized value */\n      $UNRECOGNIZED_VALUE = 0xffffffffff\n    }\n  }\n\n  export class MapMessage extends ProtobufMessage<IMapMessage> {\n    private constructor();\n\n    public get stringToString(): ReadonlyMap<string, string>;\n    public set stringToString(value: ReadonlyMap<string, string>);\n\n    public get stringToNumber(): ReadonlyMap<string, number>;\n    public set stringToNumber(value: ReadonlyMap<string, number>);\n\n    public get stringToSignedLong(): ReadonlyMap<string, Long>;\n    public set stringToSignedLong(value: ReadonlyMap<string, Long>);\n\n    public get stringToUnsignedLong(): ReadonlyMap<string, Long>;\n    public set stringToUnsignedLong(value: ReadonlyMap<string, Long>);\n\n    public get stringToDouble(): ReadonlyMap<string, number>;\n    public set stringToDouble(value: ReadonlyMap<string, number>);\n\n    public get stringToMessage(): ReadonlyMap<string, test.OtherMessage>;\n    public set stringToMessage(value: ReadonlyMap<string, test.OtherMessage>);\n\n    public get intToString(): ReadonlyMap<number, string>;\n    public set intToString(value: ReadonlyMap<number, string>);\n\n    public get longToString(): ReadonlyMap<Long, string>;\n    public set longToString(value: ReadonlyMap<Long, string>);\n\n    /**\n     * Creates a new MapMessage from properties\n     * Returns a clone if a MapMessage instance is provided\n     */\n    public static create(arena: IArena, properties?: MapMessage | IMapMessage): MapMessage;\n    /** Decode a buffer into a MapMessage */\n    public static decode(arena: IArena, buffer: Uint8Array): MapMessage;\n    /** Asynchronously decode a buffer into a MapMessage */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<MapMessage>;\n    /**\n     * Encodes the provided MapMessage into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: MapMessage | IMapMessage): Uint8Array;\n    /**\n     * Asynchronously encodes the provided MapMessage into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: MapMessage | IMapMessage): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a MapMessage.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<MapMessage>;\n  }\n\n  /** Interface for creating MapMessage instances */\n  export interface IMapMessage {\n    stringToString?: ReadonlyMap<string, string>;\n    stringToNumber?: ReadonlyMap<string, number>;\n    stringToSignedLong?: ReadonlyMap<string, Long>;\n    stringToUnsignedLong?: ReadonlyMap<string, Long>;\n    stringToDouble?: ReadonlyMap<string, number>;\n    stringToMessage?: ReadonlyMap<string, test.IOtherMessage>;\n    intToString?: ReadonlyMap<number, string>;\n    longToString?: ReadonlyMap<Long, string>;\n  }\n\n  export class ExternalMessages extends ProtobufMessage<IExternalMessages> {\n    private constructor();\n\n    public get otherMessage(): test3.Message3 | undefined;\n    public set otherMessage(value: test3.Message3 | undefined);\n\n    /**\n     * Creates a new ExternalMessages from properties\n     * Returns a clone if a ExternalMessages instance is provided\n     */\n    public static create(arena: IArena, properties?: ExternalMessages | IExternalMessages): ExternalMessages;\n    /** Decode a buffer into a ExternalMessages */\n    public static decode(arena: IArena, buffer: Uint8Array): ExternalMessages;\n    /** Asynchronously decode a buffer into a ExternalMessages */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<ExternalMessages>;\n    /**\n     * Encodes the provided ExternalMessages into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: ExternalMessages | IExternalMessages): Uint8Array;\n    /**\n     * Asynchronously encodes the provided ExternalMessages into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: ExternalMessages | IExternalMessages): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a ExternalMessages.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<ExternalMessages>;\n  }\n\n  /** Interface for creating ExternalMessages instances */\n  export interface IExternalMessages {\n    otherMessage?: test3.IMessage3;\n  }\n}\nimport __test__ = test;\n\nexport namespace test3 {\n  export class Message3 extends ProtobufMessage<IMessage3> {\n    private constructor();\n\n    public get value(): string;\n    public set value(value: string);\n\n    /**\n     * Creates a new Message3 from properties\n     * Returns a clone if a Message3 instance is provided\n     */\n    public static create(arena: IArena, properties?: Message3 | IMessage3): Message3;\n    /** Decode a buffer into a Message3 */\n    public static decode(arena: IArena, buffer: Uint8Array): Message3;\n    /** Asynchronously decode a buffer into a Message3 */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<Message3>;\n    /**\n     * Encodes the provided Message3 into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: Message3 | IMessage3): Uint8Array;\n    /**\n     * Asynchronously encodes the provided Message3 into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: Message3 | IMessage3): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a Message3.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<Message3>;\n  }\n\n  /** Interface for creating Message3 instances */\n  export interface IMessage3 {\n    value?: string;\n  }\n}\nimport __test3__ = test3;\n\nexport namespace test2 {\n  export class Message2 extends ProtobufMessage<IMessage2> {\n    private constructor();\n\n    public get value(): string;\n    public set value(value: string);\n\n    /**\n     * Creates a new Message2 from properties\n     * Returns a clone if a Message2 instance is provided\n     */\n    public static create(arena: IArena, properties?: Message2 | IMessage2): Message2;\n    /** Decode a buffer into a Message2 */\n    public static decode(arena: IArena, buffer: Uint8Array): Message2;\n    /** Asynchronously decode a buffer into a Message2 */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<Message2>;\n    /**\n     * Encodes the provided Message2 into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: Message2 | IMessage2): Uint8Array;\n    /**\n     * Asynchronously encodes the provided Message2 into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: Message2 | IMessage2): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a Message2.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<Message2>;\n  }\n\n  /** Interface for creating Message2 instances */\n  export interface IMessage2 {\n    value?: string;\n  }\n}\nimport __test2__ = test2;\n\nexport namespace package_with_underscores {\n  export const enum Enum_With_Underscores {\n    ENUM_VALUE_0 = 0,\n    ENUM_VALUE_1 = 1,\n    E2NUM_VALUE_WITH_NUMBER = 2,\n    /** Unrecognized value */\n    $UNRECOGNIZED_VALUE = 0xffffffffff\n  }\n\n  export class Message_With_Underscores extends ProtobufMessage<IMessage_With_Underscores> {\n    private constructor();\n\n    public get fieldUnderscore(): number;\n    public set fieldUnderscore(value: number);\n\n    public get fieldUnderscoreAgain(): number;\n    public set fieldUnderscoreAgain(value: number);\n\n    public get enumValue(): package_with_underscores.Enum_With_Underscores;\n    public set enumValue(value: package_with_underscores.Enum_With_Underscores);\n\n    public get messageValue(): package_with_underscores.Message_With_Underscores | undefined;\n    public set messageValue(value: package_with_underscores.Message_With_Underscores | undefined);\n\n    /**\n     * Creates a new Message_With_Underscores from properties\n     * Returns a clone if a Message_With_Underscores instance is provided\n     */\n    public static create(arena: IArena, properties?: Message_With_Underscores | IMessage_With_Underscores): Message_With_Underscores;\n    /** Decode a buffer into a Message_With_Underscores */\n    public static decode(arena: IArena, buffer: Uint8Array): Message_With_Underscores;\n    /** Asynchronously decode a buffer into a Message_With_Underscores */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<Message_With_Underscores>;\n    /**\n     * Encodes the provided Message_With_Underscores into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: Message_With_Underscores | IMessage_With_Underscores): Uint8Array;\n    /**\n     * Asynchronously encodes the provided Message_With_Underscores into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: Message_With_Underscores | IMessage_With_Underscores): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a Message_With_Underscores.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<Message_With_Underscores>;\n  }\n\n  /** Interface for creating Message_With_Underscores instances */\n  export interface IMessage_With_Underscores {\n    fieldUnderscore?: number;\n    fieldUnderscoreAgain?: number;\n    enumValue?: package_with_underscores.Enum_With_Underscores;\n    messageValue?: package_with_underscores.IMessage_With_Underscores;\n  }\n\n  export class M3ssage1WithNumb3r2 extends ProtobufMessage<IM3ssage1WithNumb3r2> {\n    private constructor();\n\n    public get fie1ld(): number;\n    public set fie1ld(value: number);\n\n    public get field2(): number;\n    public set field2(value: number);\n\n    public get field3(): number;\n    public set field3(value: number);\n\n    public get a4Fiel4d(): number;\n    public set a4Fiel4d(value: number);\n\n    public get a5aFiel5d(): number;\n    public set a5aFiel5d(value: number);\n\n    public get enum(): package_with_underscores.Enum_With_Underscores;\n    public set enum(value: package_with_underscores.Enum_With_Underscores);\n\n    /**\n     * Creates a new M3ssage1WithNumb3r2 from properties\n     * Returns a clone if a M3ssage1WithNumb3r2 instance is provided\n     */\n    public static create(arena: IArena, properties?: M3ssage1WithNumb3r2 | IM3ssage1WithNumb3r2): M3ssage1WithNumb3r2;\n    /** Decode a buffer into a M3ssage1WithNumb3r2 */\n    public static decode(arena: IArena, buffer: Uint8Array): M3ssage1WithNumb3r2;\n    /** Asynchronously decode a buffer into a M3ssage1WithNumb3r2 */\n    public static decodeAsync(arena: IArena, buffer: Uint8Array): Promise<M3ssage1WithNumb3r2>;\n    /**\n     * Encodes the provided M3ssage1WithNumb3r2 into a buffer.\n     * Calls encode() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encode(value: M3ssage1WithNumb3r2 | IM3ssage1WithNumb3r2): Uint8Array;\n    /**\n     * Asynchronously encodes the provided M3ssage1WithNumb3r2 into a buffer.\n     * Calls encodeAsync() if an instance is provided, otherwise creates a new message with the given properties then calls encode() on it\n     */\n    public static encodeAsync(value: M3ssage1WithNumb3r2 | IM3ssage1WithNumb3r2): Promise<Uint8Array>;\n    /**\n     * Asynchronously decode a JSON string into a M3ssage1WithNumb3r2.\n     * This is discouraged and should be used as a debug option only.\n     */\n    public static decodeDebugJSONAsync(arena: IArena, json: string): Promise<M3ssage1WithNumb3r2>;\n  }\n\n  /** Interface for creating M3ssage1WithNumb3r2 instances */\n  export interface IM3ssage1WithNumb3r2 {\n    fie1ld?: number;\n    field2?: number;\n    field3?: number;\n    a4Fiel4d?: number;\n    a5aFiel5d?: number;\n    enum?: package_with_underscores.Enum_With_Underscores;\n  }\n}\nimport __package_with_underscores__ = package_with_underscores;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/test/proto.js",
    "content": "module.exports = require('valdi_protobuf/src/ProtobufBuilder').load('valdi_protobuf/test/proto.protodecl');"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/test/proto_config.yaml",
    "content": "repositories:\n- path: ../proto\n  input_path: .\n  output_path: module\n\nfiles:\n  - path: module/test.proto\n    types:\n      - name: Message\n      - name: RepeatedMessage\n      - name: ParentMessage\n      - name: OneOfMessage\n      - name: OldMessage\n      - name: NewMessage\n      - name: ExternalMessages\n      - name: MapMessage\n      - name: OldEnumMessage\n      - name: NewEnumMessage\n  - path: module/test2.proto\n    types:\n      - name: Message2\n  - path: module/test4.proto\n    types:\n      - name: Message_With_Underscores\n      - name: M3ssage1WithNumb3r2"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/tsconfig.json",
    "content": "{\n  \"extends\": \"../_configs/base.tsconfig.json\",\n  \"compilerOptions\": {\n    \"noImplicitReturns\": true,\n    \"noImplicitAny\": true,\n    \"strict\": true\n  }\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/Message.ts",
    "content": "import { IArena, IMessage, IMessageConstructor, JSONPrintOptions } from './src_symlink/types';\nimport { INativeMessageIndex } from './src_symlink/ValdiProtobuf';\n\n// Minimal ConsoleRepresentable interface for web\ninterface ConsoleRepresentable {\n  toConsoleRepresentation(): any;\n}\n\nfunction toPlainObjectImpl(value: any): any {\n  if (value == null) {\n    return value;\n  }\n\n  if (value.toPlainObject) {\n    return value.toPlainObject();\n  }\n\n  if (Array.isArray(value)) {\n    return value.map(v => toPlainObjectImpl(v));\n  }\n\n  if (value instanceof Map) {\n    const map = new Map();\n    value.forEach((mapValue, mapKey) => {\n      map.set(mapKey, toPlainObjectImpl(mapValue));\n    });\n    return map;\n  }\n\n  return value;\n}\n\n/**\n * Base class for all message types\n */\nexport class Message<MessageProps = {}> implements IMessage<MessageProps>, ConsoleRepresentable {\n  /**\n   * Creates a new Mesage instance using an existing native instance\n   * inside the given arena.\n   */\n  constructor(readonly $arena: IArena, readonly $index: INativeMessageIndex) {}\n\n  /**\n   * Encode this message into buffer.\n   */\n  encode(): Uint8Array {\n    return this.$arena.encodeMessage(this as IMessage<MessageProps>);\n  }\n\n  /**\n   * Asynchronously encode this message into buffer.\n   */\n  encodeAsync(): Promise<Uint8Array> {\n    return this.$arena.encodeMessageAsync(this as IMessage<MessageProps>);\n  }\n\n  /**\n   * Creates a deep copy of this message into the given Arena.\n   * If the arena is not provided, the copy will be hosted\n   * into the same arena as this message.\n   */\n  clone<T extends IMessage<MessageProps>>(this: T, arena?: IArena): T {\n    const targetArena = arena ?? this.$arena;\n    return targetArena.copyMessage(this as IMessage<MessageProps>) as T;\n  }\n\n  /**\n   * Eagerly recursively read the content of the message\n   */\n  toPlainObject(): MessageProps {\n    const out: any = {};\n    const fields = (this.constructor as IMessageConstructor).fields;\n    if (!fields) {\n      return out;\n    }\n    for (const field of fields) {\n      const fieldName = field.name;\n      const value = (this as any)[fieldName];\n\n      if (value !== undefined) {\n        out[fieldName] = toPlainObjectImpl(value);\n      }\n    }\n    return out;\n  }\n\n  /**\n   * Converts this message into its JSON equivalent.\n   * Converting to JSON for anything other than debugging is discouraged, as such there is no exposed\n   * function for converting JSON into message instances.\n   * For more details on Protobuf JSON formatting:\n   * https://protobuf.dev/programming-guides/proto3/#json\n   */\n  toDebugJSON(options?: JSONPrintOptions): string {\n    return this.$arena.encodeMessageToJSON(this as IMessage<MessageProps>, options);\n  }\n\n  /**\n   * Allow a full easy display in the console logs\n   */\n  toConsoleRepresentation() {\n    return this.toPlainObject();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/ValdiProtobuf.ts",
    "content": "import type { ValdiProtobufModule } from './src_symlink/ValdiProtobuf';\n\n// Re-export types needed by headless modules\nexport { FieldType } from './src_symlink/ValdiProtobuf';\n\n// Re-export @protobuf-ts/runtime types for tests (web/ is excluded from Valdi compiler checks)\nexport { ScalarType, RepeatType } from '@protobuf-ts/runtime';\nexport type {\n  ValdiProtobufModule,\n  IField,\n  ILoadMessageResult,\n  INativeMessageArena,\n  INativeMessageFactory,\n  INativeNamespaceEntries,\n  INativeMessageIndex,\n  NativeFieldValues,\n} from './src_symlink/ValdiProtobuf';\n\n/** Webpack's require.context typing (used by Bazel/webpack builds) */\ninterface WebpackRequireContext {\n  <T = any>(path: string): T;\n  keys(): string[];\n  resolve(path: string): string;\n  id: string;\n}\n\ninterface WebpackRequire {\n  context(path: string, recursive: boolean, regExp: RegExp): WebpackRequireContext;\n}\ndeclare const require: WebpackRequire;\n\n\n// Lazily obtain a webpack context, without ever touching bare `require` at top level\nfunction getWebpackContext(): WebpackRequireContext | undefined {\n  return require.context('../../../src', true, /\\.protodecl\\.js$/);\n}\n\n/**\n * Loads the compiled protodecl JS (bytes) and returns the raw buffer.\n * The VALDIPRO header (if present) is stripped by DescriptorDatabase.\n *\n * @param path e.g. \"proto.protodecl\" (without \".js\")\n */\nfunction loadFn(path: string): Uint8Array {\n  const context = getWebpackContext();\n  if (!context) {\n    throw new Error(\n      \"require.context is unavailable. Ensure your bundler provides it or swap in a custom loader.\"\n    );\n  }\n\n  // NOTE: your regex is /\\.protodecl\\.js$/, so `path` should include `.protodecl`\n  // ex: \"proto.protodecl\" -> \"./proto.protodecl.js\"\n  const mod: any = context(`./${path}.js`);\n  const b64: string = mod?.default ?? mod;\n  return Uint8Array.from(atob(b64), c => c.charCodeAt(0));\n}\n\n/* ---------- Headless module wiring ---------- */\n\nimport { HeadlessValdiProtobufModule } from './headless/HeadlessValdiProtobufModule';\n\nconst moduleInstance: ValdiProtobufModule = new HeadlessValdiProtobufModule(loadFn);\n\n/* Re-export as named functions (mirrors the original CommonJS export) */\nexport const createArena = moduleInstance.createArena.bind(moduleInstance);\nexport const loadMessages = moduleInstance.loadMessages.bind(moduleInstance);\nexport const parseAndLoadMessages = moduleInstance.parseAndLoadMessages?.bind(moduleInstance);\nexport const getFieldsForMessageDescriptor =\n  moduleInstance.getFieldsForMessageDescriptor.bind(moduleInstance);\nexport const getNamespaceEntries = moduleInstance.getNamespaceEntries.bind(moduleInstance);\nexport const createMessage = moduleInstance.createMessage.bind(moduleInstance);\nexport const decodeMessage = moduleInstance.decodeMessage.bind(moduleInstance);\nexport const decodeMessageAsync = moduleInstance.decodeMessageAsync.bind(moduleInstance);\nexport const decodeMessageDebugJSONAsync =\n  moduleInstance.decodeMessageDebugJSONAsync.bind(moduleInstance);\nexport const encodeMessage = moduleInstance.encodeMessage.bind(moduleInstance);\nexport const encodeMessageAsync = moduleInstance.encodeMessageAsync.bind(moduleInstance);\nexport const batchEncodeMessageAsync = moduleInstance.batchEncodeMessageAsync.bind(moduleInstance);\nexport const encodeMessageToJSON = moduleInstance.encodeMessageToJSON.bind(moduleInstance);\nexport const setMessageField = moduleInstance.setMessageField.bind(moduleInstance);\nexport const getMessageFields = moduleInstance.getMessageFields.bind(moduleInstance);\nexport const copyMessage = moduleInstance.copyMessage.bind(moduleInstance);\n\n/* Optionally export the instance (handy for testing / DI) */\nexport const valdiProtobufModule: ValdiProtobufModule = moduleInstance;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/headless/DescriptorDatabase.ts",
    "content": "import {\n  DescriptorProto,\n  EnumDescriptorProto,\n  FieldDescriptorProto,\n  FieldDescriptorProto_Label as FieldLabel,\n  FieldDescriptorProto_Type as FieldType,\n  FileDescriptorProto,\n  FileDescriptorSet,\n  FileDescriptorSetType,\n} from './descriptor';\nimport { FullyQualifiedName } from './FullyQualifiedName';\nimport {\n  MessageType,\n  ScalarType,\n  RepeatType,\n  PartialFieldInfo,\n  IMessageType,\n  EnumInfo,\n} from '@protobuf-ts/runtime';\n\nexport interface RegisteredDescriptor {\n  name: FullyQualifiedName;\n  isEnum: boolean;\n}\n\ninterface MapType {\n  keyType: ScalarType;\n  valueType: string;\n  valueKind: 'scalar' | 'enum' | 'message';\n  valueScalarType?: ScalarType;\n}\n\ninterface PendingField {\n  fieldInfo: PartialFieldInfo;\n  typeName?: string; // For message/enum fields, the type name to resolve later\n}\n\ninterface PendingMessageType {\n  typeName: string;\n  fields: PendingField[];\n  messageType?: MessageType<any>;\n}\n\nexport class DescriptorDatabase {\n  private allDescriptors: RegisteredDescriptor[] = [];\n  private messageTypes: Map<string, MessageType<any>> = new Map();\n  private enumInfos: Map<string, EnumInfo> = new Map();\n  private pendingMessageTypes: Map<string, PendingMessageType> = new Map();\n  private mapTypeByName: Map<string, MapType> = new Map();\n\n  constructor() {}\n\n  /**\n   * Resolves all pending message types by creating MessageType instances.\n   * Must be called after all file descriptors have been added.\n   */\n  resolve(): void {\n    // Create MessageType instances for all pending types\n    for (const [typeName, pending] of this.pendingMessageTypes) {\n      if (!pending.messageType) {\n        this.createMessageType(typeName, pending);\n      }\n    }\n    this.pendingMessageTypes.clear();\n  }\n\n  private createMessageType(typeName: string, pending: PendingMessageType): MessageType<any> {\n    // Check if already created (to handle circular references)\n    if (pending.messageType) {\n      return pending.messageType;\n    }\n\n    // Resolve fields\n    const resolvedFields: PartialFieldInfo[] = pending.fields.map(pf => {\n      const info = pf.fieldInfo as any;\n      \n      if (info.kind === 'message' && pf.typeName) {\n        // Resolve message type reference\n        info.T = () => this.getMessageType(pf.typeName!);\n      } else if (info.kind === 'enum' && pf.typeName) {\n        // Resolve enum type reference\n        info.T = () => this.getEnumInfo(pf.typeName!);\n      } else if (info.kind === 'map' && pf.typeName) {\n        // Resolve map value type if it's a message or enum\n        const mapType = this.mapTypeByName.get(pf.typeName);\n        if (mapType && info.V) {\n          if (info.V.kind === 'message') {\n            info.V.T = () => this.getMessageType(mapType.valueType);\n          } else if (info.V.kind === 'enum') {\n            info.V.T = () => this.getEnumInfo(mapType.valueType);\n          }\n        }\n      }\n      \n      return info as PartialFieldInfo;\n    });\n\n    // Create the MessageType\n    const messageType = new MessageType<any>(typeName, resolvedFields);\n    pending.messageType = messageType;\n    this.messageTypes.set(typeName, messageType);\n    \n    return messageType;\n  }\n\n  getMessageType(typeName: string): IMessageType<any> {\n    const existing = this.messageTypes.get(typeName);\n    if (existing) {\n      return existing;\n    }\n\n    // Check if it's pending\n    const pending = this.pendingMessageTypes.get(typeName);\n    if (pending) {\n      return this.createMessageType(typeName, pending);\n    }\n\n    throw new Error(`Unknown message type: ${typeName}`);\n  }\n\n  getEnumInfo(typeName: string): EnumInfo {\n    const info = this.enumInfos.get(typeName);\n    if (!info) {\n      throw new Error(`Unknown enum type: ${typeName}`);\n    }\n    return info;\n  }\n\n  getAllTypeNames(): FullyQualifiedName[] {\n    return this.allDescriptors.map(d => d.name);\n  }\n\n  getAllMessageDescriptorTypeNames(): FullyQualifiedName[] {\n    return this.allDescriptors.filter(d => !d.isEnum).map(d => d.name);\n  }\n\n  getAllDescriptors(): readonly RegisteredDescriptor[] {\n    return this.allDescriptors;\n  }\n\n  addFileDescriptor(fileDescriptor: FileDescriptorProto): void {\n    const packageName = fileDescriptor.package;\n    const currentPackage = packageName ? FullyQualifiedName.fromString(packageName) : undefined;\n\n    if (fileDescriptor.messageType) {\n      for (const messageType of fileDescriptor.messageType) {\n        this.addDescriptor(currentPackage, messageType);\n      }\n    }\n\n    if (fileDescriptor.enumType) {\n      for (const enumType of fileDescriptor.enumType) {\n        this.addEnumDescriptor(currentPackage, enumType);\n      }\n    }\n  }\n\n  private toTypeNameString(typeName: string | undefined): string {\n    if (!typeName) {\n      throw new Error('Expected type name');\n    }\n    return typeName.startsWith('.') ? typeName.substring(1) : typeName;\n  }\n\n  private fieldTypeToScalarType(fieldType: FieldType): ScalarType | undefined {\n    switch (fieldType) {\n      case FieldType.DOUBLE:\n        return ScalarType.DOUBLE;\n      case FieldType.FLOAT:\n        return ScalarType.FLOAT;\n      case FieldType.INT64:\n        return ScalarType.INT64;\n      case FieldType.UINT64:\n        return ScalarType.UINT64;\n      case FieldType.INT32:\n        return ScalarType.INT32;\n      case FieldType.FIXED64:\n        return ScalarType.FIXED64;\n      case FieldType.FIXED32:\n        return ScalarType.FIXED32;\n      case FieldType.BOOL:\n        return ScalarType.BOOL;\n      case FieldType.STRING:\n        return ScalarType.STRING;\n      case FieldType.BYTES:\n        return ScalarType.BYTES;\n      case FieldType.UINT32:\n        return ScalarType.UINT32;\n      case FieldType.SFIXED32:\n        return ScalarType.SFIXED32;\n      case FieldType.SFIXED64:\n        return ScalarType.SFIXED64;\n      case FieldType.SINT32:\n        return ScalarType.SINT32;\n      case FieldType.SINT64:\n        return ScalarType.SINT64;\n      default:\n        return undefined; // MESSAGE, ENUM, GROUP\n    }\n  }\n\n  private toFieldInfo(fieldDescriptor: FieldDescriptorProto): PendingField {\n    const isRepeated = fieldDescriptor.label === FieldLabel.REPEATED;\n    const fieldType = fieldDescriptor.type ?? FieldType.UNSPECIFIED$;\n    const scalarType = this.fieldTypeToScalarType(fieldType);\n\n    if (scalarType !== undefined) {\n      // Scalar field\n      return {\n        fieldInfo: {\n          kind: 'scalar',\n          no: fieldDescriptor.number,\n          name: fieldDescriptor.name,\n          T: scalarType,\n          repeat: isRepeated ? RepeatType.PACKED : RepeatType.NO,\n        } as PartialFieldInfo,\n      };\n    } else if (fieldType === FieldType.MESSAGE) {\n      const typeName = this.toTypeNameString(fieldDescriptor.typeName);\n      \n      // Check if this is a map field\n      const mapType = this.mapTypeByName.get(typeName);\n      if (mapType) {\n        // Map field\n        const mapValue: any = mapType.valueKind === 'scalar'\n          ? { kind: 'scalar', T: mapType.valueScalarType! }\n          : mapType.valueKind === 'message'\n            ? { kind: 'message', T: () => this.getMessageType(mapType.valueType) }\n            : { kind: 'enum', T: () => this.getEnumInfo(mapType.valueType) };\n\n        return {\n          fieldInfo: {\n            kind: 'map',\n            no: fieldDescriptor.number,\n            name: fieldDescriptor.name,\n            K: mapType.keyType,\n            V: mapValue,\n          } as PartialFieldInfo,\n          typeName,\n        };\n      }\n\n      // Regular message field\n      return {\n        fieldInfo: {\n          kind: 'message',\n          no: fieldDescriptor.number,\n          name: fieldDescriptor.name,\n          T: () => { throw new Error('Not resolved yet'); }, // Placeholder\n          repeat: isRepeated ? RepeatType.UNPACKED : RepeatType.NO,\n        } as PartialFieldInfo,\n        typeName,\n      };\n    } else if (fieldType === FieldType.ENUM) {\n      const typeName = this.toTypeNameString(fieldDescriptor.typeName);\n      return {\n        fieldInfo: {\n          kind: 'enum',\n          no: fieldDescriptor.number,\n          name: fieldDescriptor.name,\n          T: () => { throw new Error('Not resolved yet'); }, // Placeholder\n          repeat: isRepeated ? RepeatType.PACKED : RepeatType.NO,\n        } as PartialFieldInfo,\n        typeName,\n      };\n    } else if (fieldType === FieldType.GROUP) {\n      throw new Error('Groups are not supported');\n    }\n\n    throw new Error(`Unknown field type: ${fieldType}`);\n  }\n\n  private createMapType(descriptorProto: DescriptorProto): MapType {\n    let keyType: ScalarType | undefined;\n    let valueType: string | undefined;\n    let valueKind: 'scalar' | 'enum' | 'message' = 'scalar';\n    let valueScalarType: ScalarType | undefined;\n\n    if (descriptorProto.field) {\n      for (const field of descriptorProto.field) {\n        const fType = field.type ?? FieldType.UNSPECIFIED$;\n        if (field.name === 'key') {\n          keyType = this.fieldTypeToScalarType(fType);\n        } else if (field.name === 'value') {\n          valueScalarType = this.fieldTypeToScalarType(fType);\n          if (valueScalarType !== undefined) {\n            valueKind = 'scalar';\n            valueType = '';\n          } else if (fType === FieldType.MESSAGE) {\n            valueKind = 'message';\n            valueType = this.toTypeNameString(field.typeName);\n          } else if (fType === FieldType.ENUM) {\n            valueKind = 'enum';\n            valueType = this.toTypeNameString(field.typeName);\n          }\n        }\n      }\n    }\n\n    if (keyType === undefined || valueType === undefined) {\n      throw new Error(`Could not resolve map type in: ${JSON.stringify(descriptorProto, null, 2)}`);\n    }\n\n    return { keyType, valueType, valueKind, valueScalarType };\n  }\n\n  private rebuildFullyQualifiedNameFromFull(fullName: string): FullyQualifiedName {\n    const parts = fullName.split('.');\n    let parent: FullyQualifiedName | undefined = undefined;\n    let full = '';\n\n    for (let i = 0; i < parts.length - 1; i++) {\n      full = i === 0 ? parts[i] : `${full}.${parts[i]}`;\n      parent = {\n        symbolName: parts[i],\n        fullName: full,\n        parent: parent,\n      };\n    }\n\n    return {\n      symbolName: parts[parts.length - 1],\n      fullName,\n      parent,\n    };\n  }\n\n  private addDescriptor(\n    parentPackage: FullyQualifiedName | undefined,\n    descriptorProto: DescriptorProto,\n  ): void {\n    const name = descriptorProto.name ?? '';\n    if (!name) return; // Skip descriptors without names\n    const childPackage = new FullyQualifiedName(parentPackage, name);\n    const typeName = childPackage.fullName;\n\n    // Check if this is a map entry type\n    if (descriptorProto.options?.mapEntry) {\n      const mapType = this.createMapType(descriptorProto);\n      this.mapTypeByName.set(typeName, mapType);\n      return;\n    }\n\n    // Process nested types FIRST so map entries are registered before we process fields\n    if (descriptorProto.nestedType) {\n      for (const nestedType of descriptorProto.nestedType) {\n        this.addDescriptor(childPackage, nestedType);\n      }\n    }\n\n    // Now collect fields (after nested types are registered)\n    const pendingFields: PendingField[] = [];\n    if (descriptorProto.field) {\n      for (const fieldDescriptor of descriptorProto.field) {\n        pendingFields.push(this.toFieldInfo(fieldDescriptor));\n      }\n    }\n\n    // Register as pending\n    this.pendingMessageTypes.set(typeName, {\n      typeName,\n      fields: pendingFields,\n    });\n\n    const fixedFQN = this.rebuildFullyQualifiedNameFromFull(typeName);\n    this.allDescriptors.push({ name: fixedFQN, isEnum: false });\n\n    if (descriptorProto.enumType) {\n      for (const nestedEnum of descriptorProto.enumType) {\n        this.addEnumDescriptor(childPackage, nestedEnum);\n      }\n    }\n  }\n\n  private addEnumDescriptor(\n    parentPackage: FullyQualifiedName | undefined,\n    enumDescriptor: EnumDescriptorProto,\n  ): void {\n    const name = enumDescriptor.name ?? '';\n    if (!name) return; // Skip enum descriptors without names\n    const values = enumDescriptor.value;\n    const childPackage = new FullyQualifiedName(parentPackage, name);\n    const typeName = childPackage.fullName;\n\n    // Create enum object (bidirectional mapping)\n    const enumObj: { [key: number]: string; [k: string]: number | string } = {};\n    for (const value of values) {\n      const valueName = value.name ?? '';\n      const valueNumber = value.number ?? 0;\n      if (!valueName) continue;\n      enumObj[valueName] = valueNumber;\n      enumObj[valueNumber] = valueName;\n    }\n\n    // Create EnumInfo tuple: [typeName, enumObject]\n    const enumInfo: EnumInfo = [typeName, enumObj];\n    this.enumInfos.set(typeName, enumInfo);\n\n    this.allDescriptors.push({ name: childPackage, isEnum: true });\n  }\n\n  /**\n   * Validates that a string contains only valid package name characters.\n   */\n  private isValidPackageName(name: string): boolean {\n    return /^[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*$/.test(name);\n  }\n\n  getDescriptorSetFromBuffer(buffer: Uint8Array): Uint8Array {\n    if (buffer.length >= 8) {\n      const tagBytes = buffer.subarray(0, 8);\n      const tag = String.fromCharCode(\n        tagBytes[0], tagBytes[1], tagBytes[2], tagBytes[3],\n        tagBytes[4], tagBytes[5], tagBytes[6], tagBytes[7]\n      );\n      if (tag === 'VALDIPRO') {\n        const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n        const indexSize = view.getUint32(8, true);\n        return buffer.subarray(12 + indexSize);\n      }\n    }\n    return buffer;\n  }\n\n  addFileDescriptorSet(buffer: Uint8Array): void {\n    const fileDescriptorSet = FileDescriptorSetType.fromBinary(this.getDescriptorSetFromBuffer(buffer));\n\n    if (fileDescriptorSet.file) {\n      for (const file of fileDescriptorSet.file) {\n        if (file.package && !this.isValidPackageName(file.package)) {\n          continue;\n        }\n        if (file.name && /[\\x00-\\x1F]/.test(file.name)) {\n          continue;\n        }\n        this.addFileDescriptor(file);\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/headless/FullyQualifiedName.ts",
    "content": "export class FullyQualifiedName {\n  readonly fullName: string;\n\n  constructor(readonly parent: FullyQualifiedName | undefined, readonly symbolName: string) {\n    if (parent) {\n      this.fullName = `${parent.fullName}.${symbolName}`;\n    } else {\n      this.fullName = symbolName;\n    }\n  }\n\n  static fromString(str: string): FullyQualifiedName {\n    let currentQualifiedName: FullyQualifiedName | undefined;\n    let position = 0;\n\n    for (;;) {\n      const nextDot = str.indexOf('.', position);\n      if (nextDot >= str.length) {\n        currentQualifiedName = new FullyQualifiedName(currentQualifiedName, str.substring(position, nextDot));\n        position = nextDot + 1;\n      } else {\n        return new FullyQualifiedName(currentQualifiedName, str.substring(position));\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/headless/HeadlessValdiProtobufModule.ts",
    "content": "import {\n  ValdiProtobufModule,\n  IField,\n  ILoadMessageResult,\n  INativeMessageArena,\n  INativeMessageFactory,\n  INativeNamespaceEntries,\n  NativeFieldValues,\n} from '../ValdiProtobuf';\nimport { DescriptorDatabase } from './DescriptorDatabase';\nimport { generateMonkeyPatchedNamespace } from './NamespaceGenerator';\n\nconst DUMMY_ARENA: INativeMessageArena = {};\n\nexport class HeadlessValdiProtobufModule implements ValdiProtobufModule {\n  constructor(private readonly loadProtoDeclFn: (path: string) => Uint8Array) {}\n\n  createArena(eagerDecoding: boolean, ignoreAllFieldsDuringEncoding: boolean): INativeMessageArena {\n    return DUMMY_ARENA;\n  }\n\n  loadMessages(path: string): ILoadMessageResult {\n    const protoDeclContent = this.loadProtoDeclFn(path);\n    const database = new DescriptorDatabase();\n    database.addFileDescriptorSet(protoDeclContent);\n    database.resolve();\n\n    const allMessageNames = database.getAllMessageDescriptorTypeNames();\n\n    const namespace = generateMonkeyPatchedNamespace(database, allMessageNames);\n\n    return {\n      factory: {},\n      namespaces: namespace,\n      rootNamespaceEntries: [],\n      descriptorNames: allMessageNames.map(n => n.fullName),\n    };\n  }\n\n  getFieldsForMessageDescriptor(factory: INativeMessageFactory, messageDescriptorIndex: number): IField[] {\n    throw new Error('Method not implemented.');\n  }\n\n  getNamespaceEntries(factory: INativeMessageFactory, namespaceId: number): INativeNamespaceEntries {\n    throw new Error('Method not implemented.');\n  }\n\n  createMessage(arena: INativeMessageArena, factory: INativeMessageFactory, messageDescriptorIndex: number): number {\n    throw new Error('Method not implemented.');\n  }\n\n  decodeMessage(\n    arena: INativeMessageArena,\n    factory: INativeMessageFactory,\n    messageDescriptorIndex: number,\n    data: Uint8Array,\n  ): number {\n    throw new Error('Method not implemented.');\n  }\n  decodeMessageAsync(\n    arena: INativeMessageArena,\n    factory: INativeMessageFactory,\n    messageDescriptorIndex: number,\n    data: Uint8Array,\n    callback: (messageIndex: number | undefined, error: string | undefined) => void,\n  ): void {\n    throw new Error('Method not implemented.');\n  }\n  decodeMessageDebugJSONAsync(\n    arena: INativeMessageArena,\n    factory: INativeMessageFactory,\n    messageDescriptorIndex: number,\n    data: string,\n    callback: (messageIndex: number | undefined, error: string | undefined) => void,\n  ): void {\n    throw new Error('Method not implemented.');\n  }\n  encodeMessage(arena: INativeMessageArena, messageIndex: number): Uint8Array {\n    throw new Error('Method not implemented.');\n  }\n  encodeMessageAsync(\n    arena: INativeMessageArena,\n    messageIndex: number,\n    callback: (data: Uint8Array | undefined, error: string | undefined) => void,\n  ): void {\n    throw new Error('Method not implemented.');\n  }\n  batchEncodeMessageAsync(\n    arena: INativeMessageArena,\n    messageIndexes: number[],\n    callback: (data: Uint8Array[] | undefined, error: string | undefined) => void,\n  ): void {\n    throw new Error('Method not implemented.');\n  }\n  encodeMessageToJSON(arena: INativeMessageArena, messageIndex: number, options: number): string {\n    throw new Error('Method not implemented.');\n  }\n  setMessageField(\n    arena: INativeMessageArena,\n    messageIndex: number,\n    fieldIndex: number,\n    value: NativeFieldValues,\n  ): void {\n    throw new Error('Method not implemented.');\n  }\n  getMessageFields(arena: INativeMessageArena, messageIndex: number): NativeFieldValues[] {\n    throw new Error('Method not implemented.');\n  }\n  copyMessage(arena: INativeMessageArena, messageIndex: number, fromArena: INativeMessageArena): number {\n    throw new Error('Method not implemented.');\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/headless/NamespaceGenerator.ts",
    "content": "import { Message as ValdiMessage } from '../Message';\nimport { IArena, IMessage, IMessageNamespace, JSONPrintOptions } from '../src_symlink/types';\nimport { FullyQualifiedName } from './FullyQualifiedName';\nimport { IMessageType, PbLong, PbULong } from '@protobuf-ts/runtime';\nimport { DescriptorDatabase } from './DescriptorDatabase';\nimport { INativeMessageIndex } from '../src_symlink/ValdiProtobuf';\n\n// Monkey-patch PbLong to accept Long objects from long.js\n// @protobuf-ts uses PbLong.from() to convert values to their internal long representation\n// We extend it to handle Long objects by converting them to string/number first\nconst originalPbLongFrom = PbLong.from;\nconst originalPbULongFrom = PbULong.from;\n\nPbLong.from = function(value: any): any {\n  // If it's a Long object, convert it to a primitive\n  if (value && typeof value === 'object' && 'low' in value && 'high' in value && 'unsigned' in value) {\n    const num = value.toNumber?.();\n    if (num !== undefined && Number.isSafeInteger(num)) {\n      return originalPbLongFrom.call(this, num);\n    }\n    return originalPbLongFrom.call(this, value.toString?.() ?? value);\n  }\n  return originalPbLongFrom.call(this, value);\n};\n\nPbULong.from = function(value: any): any {\n  // If it's a Long object, convert it to a primitive\n  if (value && typeof value === 'object' && 'low' in value && 'high' in value && 'unsigned' in value) {\n    const num = value.toNumber?.();\n    if (num !== undefined && Number.isSafeInteger(num) && num >= 0) {\n      return originalPbULongFrom.call(this, num);\n    }\n    return originalPbULongFrom.call(this, value.toString?.() ?? value);\n  }\n  return originalPbULongFrom.call(this, value);\n};\n\nexport interface IMonkeyPatchedProtobufJsNamespace {\n  [key: string]: IMessageNamespace | IMonkeyPatchedProtobufJsNamespace;\n}\n\n// Dummy arena/index for web messages that don't use native arena\nconst DUMMY_ARENA = {} as unknown as IArena;\nconst DUMMY_INDEX: INativeMessageIndex = -1 as INativeMessageIndex;\n\n/** Extract underlying data from a value (handles both wrapper and plain objects) */\nfunction unwrapData(value: any): any {\n  return value instanceof ProtobufTsMessageWrapper ? value._data : value;\n}\n\n/**\n * Wrapper class that makes @protobuf-ts messages compatible with Valdi's message interface.\n */\nexport class ProtobufTsMessageWrapper<MessageProps = {}> extends ValdiMessage<MessageProps> {\n  readonly _messageType: IMessageType<any>;\n  readonly _data: any;\n\n  constructor(messageType: IMessageType<any>, data: any) {\n    super(DUMMY_ARENA, DUMMY_INDEX);\n    this._messageType = messageType;\n    this._data = data;\n    Object.assign(this, data);\n  }\n\n  override encode(): Uint8Array {\n    return this._messageType.toBinary(this._data);\n  }\n\n  override encodeAsync(): Promise<Uint8Array> {\n    return Promise.resolve(this.encode());\n  }\n\n  override clone<T extends IMessage<MessageProps>>(this: T, arena?: IArena): T {\n    const wrapper = this as unknown as ProtobufTsMessageWrapper<MessageProps>;\n    const clonedData = wrapper._messageType.clone(wrapper._data);\n    return new ProtobufTsMessageWrapper(wrapper._messageType, clonedData) as unknown as T;\n  }\n\n  override toPlainObject(): MessageProps {\n    return this._data as MessageProps;\n  }\n\n  override toDebugJSON(options?: JSONPrintOptions): string {\n    const obj = this.toPlainObject();\n    return options && (options & JSONPrintOptions.PRETTY) !== 0\n      ? JSON.stringify(obj, null, 2)\n      : JSON.stringify(obj);\n  }\n}\n\nfunction resolveTargetNamespace(\n  current: IMonkeyPatchedProtobufJsNamespace,\n  fqn: FullyQualifiedName\n): IMonkeyPatchedProtobufJsNamespace {\n  if (fqn.parent) {\n    const parent = resolveTargetNamespace(current, fqn.parent);\n    if (!parent[fqn.symbolName]) {\n      parent[fqn.symbolName] = {};\n    }\n    return parent[fqn.symbolName] as IMonkeyPatchedProtobufJsNamespace;\n  }\n  if (!current[fqn.symbolName]) {\n    current[fqn.symbolName] = {};\n  }\n  return current[fqn.symbolName] as IMonkeyPatchedProtobufJsNamespace;\n}\n\nfunction populateNamespaceFromMessageType(\n  messageType: IMessageType<any>,\n  namespace: IMessageNamespace\n): void {\n  namespace.create = (_arena: IArena | undefined, value?: any): IMessage => {\n    const data = messageType.create(value);\n    return new ProtobufTsMessageWrapper(messageType, data) as unknown as IMessage;\n  };\n\n  namespace.decode = (_arena: IArena | undefined, data: Uint8Array): IMessage => {\n    const decoded = messageType.fromBinary(data);\n    return new ProtobufTsMessageWrapper(messageType, decoded) as unknown as IMessage;\n  };\n\n  namespace.decodeAsync = (_arena: IArena | undefined, data: Uint8Array): Promise<IMessage> => {\n    const decoded = messageType.fromBinary(data);\n    return Promise.resolve(new ProtobufTsMessageWrapper(messageType, decoded) as unknown as IMessage);\n  };\n\n  namespace.decodeDebugJSONAsync = (_arena: IArena | undefined, json: string): Promise<IMessage> => {\n    const parsed = JSON.parse(json);\n    const decoded = messageType.fromJson(parsed);\n    return Promise.resolve(new ProtobufTsMessageWrapper(messageType, decoded) as unknown as IMessage);\n  };\n\n  namespace.encode = (value: IMessage | any): Uint8Array => {\n    const unwrapped = unwrapData(value);\n    const normalized = messageType.create(unwrapped);\n    return messageType.toBinary(normalized);\n  };\n\n  namespace.encodeAsync = (value: IMessage | any): Promise<Uint8Array> => {\n    return Promise.resolve(namespace.encode(value));\n  };\n}\n\nexport function generateMonkeyPatchedNamespace(\n  db: DescriptorDatabase,\n  types: readonly FullyQualifiedName[],\n): IMonkeyPatchedProtobufJsNamespace {\n  const out: IMonkeyPatchedProtobufJsNamespace = {};\n\n  for (const type of types) {\n    const messageType = db.getMessageType(type.fullName);\n    const namespace = resolveTargetNamespace(out, type);\n    populateNamespaceFromMessageType(messageType, namespace as unknown as IMessageNamespace);\n  }\n\n  return out;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/headless/descriptor.ts",
    "content": "/**\n * This file contains protobuf descriptor types copied from @protobuf-ts/plugin-framework.\n * We duplicate these types locally instead of importing from the package because:\n *\n * 1. @protobuf-ts/plugin-framework has a hard dependency on the TypeScript compiler package\n *    (typescript ^3.9), which is ~15MB and not browser-safe.\n *\n * 2. The plugin-framework is designed for building protoc plugins (code generation tools),\n *    not for browser runtime use. It pulls in TypeScript for AST manipulation.\n *\n * 3. When webpack bundles the code, it tries to include the entire TypeScript compiler,\n *    which fails with \"Cannot find module\" errors for Node.js-specific modules.\n *\n * 4. The descriptor types themselves only depend on @protobuf-ts/runtime (which IS\n *    browser-safe), so we can safely copy just the types we need.\n *\n * SOURCE: @protobuf-ts/plugin-framework v2.11.0\n *         node_modules/@protobuf-ts/plugin-framework/build/es2015/google/protobuf/descriptor.js\n *\n * NOTE: This is a minimal subset - only types used by DescriptorDatabase are included.\n * If you need additional descriptor types, copy from the source package.\n */\n\nimport { MessageType } from \"@protobuf-ts/runtime\";\n\n// ============================================================================\n// Type definitions (interfaces used by DescriptorDatabase)\n// ============================================================================\n\nexport type DescriptorProto = {\n  name?: string;\n  field?: FieldDescriptorProto[];\n  nestedType?: DescriptorProto[];\n  enumType?: EnumDescriptorProto[];\n  options?: MessageOptions;\n};\n\nexport type EnumDescriptorProto = {\n  name?: string;\n  value: { name?: string; number?: number }[];\n};\n\nexport type FieldDescriptorProto = {\n  name?: string;\n  number?: number;\n  label?: FieldDescriptorProto_Label;\n  type?: FieldDescriptorProto_Type;\n  typeName?: string;\n};\n\nexport type FileDescriptorProto = {\n  name?: string;\n  package?: string;\n  messageType?: DescriptorProto[];\n  enumType?: EnumDescriptorProto[];\n};\n\nexport type FileDescriptorSet = {\n  file?: FileDescriptorProto[];\n};\n\nexport type MessageOptions = {\n  mapEntry?: boolean;\n};\n\n// ============================================================================\n// Enums (used for field type/label checking)\n// ============================================================================\n\nexport enum FieldDescriptorProto_Type {\n    UNSPECIFIED$ = 0,\n    DOUBLE = 1,\n    FLOAT = 2,\n    INT64 = 3,\n    UINT64 = 4,\n    INT32 = 5,\n    FIXED64 = 6,\n    FIXED32 = 7,\n    BOOL = 8,\n    STRING = 9,\n    GROUP = 10,\n    MESSAGE = 11,\n    BYTES = 12,\n    UINT32 = 13,\n    ENUM = 14,\n    SFIXED32 = 15,\n    SFIXED64 = 16,\n    SINT32 = 17,\n    SINT64 = 18,\n}\n\nexport enum FieldDescriptorProto_Label {\n    UNSPECIFIED$ = 0,\n    OPTIONAL = 1,\n    REQUIRED = 2,\n    REPEATED = 3,\n}\n\n// ============================================================================\n// MessageType instances (needed for binary decoding via fromBinary)\n// ============================================================================\n\nclass FileDescriptorSet$Type extends MessageType<FileDescriptorSet> {\n    constructor() {\n        super(\"google.protobuf.FileDescriptorSet\", [\n            { no: 1, name: \"file\", kind: \"message\", repeat: 2, T: () => FileDescriptorProtoType }\n        ]);\n    }\n}\nexport const FileDescriptorSetType = new FileDescriptorSet$Type();\n\nclass FileDescriptorProto$Type extends MessageType<FileDescriptorProto> {\n    constructor() {\n        super(\"google.protobuf.FileDescriptorProto\", [\n            { no: 1, name: \"name\", kind: \"scalar\", opt: true, T: 9 },\n            { no: 2, name: \"package\", kind: \"scalar\", opt: true, T: 9 },\n            { no: 4, name: \"message_type\", kind: \"message\", repeat: 2, T: () => DescriptorProtoType },\n            { no: 5, name: \"enum_type\", kind: \"message\", repeat: 2, T: () => EnumDescriptorProtoType },\n        ]);\n    }\n}\nexport const FileDescriptorProtoType = new FileDescriptorProto$Type();\n\nclass DescriptorProto$Type extends MessageType<DescriptorProto> {\n    constructor() {\n        super(\"google.protobuf.DescriptorProto\", [\n            { no: 1, name: \"name\", kind: \"scalar\", opt: true, T: 9 },\n            { no: 2, name: \"field\", kind: \"message\", repeat: 2, T: () => FieldDescriptorProtoType },\n            { no: 3, name: \"nested_type\", kind: \"message\", repeat: 2, T: () => DescriptorProtoType },\n            { no: 4, name: \"enum_type\", kind: \"message\", repeat: 2, T: () => EnumDescriptorProtoType },\n            { no: 7, name: \"options\", kind: \"message\", T: () => MessageOptionsType },\n        ]);\n    }\n}\nexport const DescriptorProtoType = new DescriptorProto$Type();\n\nclass FieldDescriptorProto$Type extends MessageType<FieldDescriptorProto> {\n    constructor() {\n        super(\"google.protobuf.FieldDescriptorProto\", [\n            { no: 1, name: \"name\", kind: \"scalar\", opt: true, T: 9 },\n            { no: 3, name: \"number\", kind: \"scalar\", opt: true, T: 5 },\n            { no: 4, name: \"label\", kind: \"enum\", opt: true, T: () => [\"google.protobuf.FieldDescriptorProto.Label\", FieldDescriptorProto_Label, \"LABEL_\"] },\n            { no: 5, name: \"type\", kind: \"enum\", opt: true, T: () => [\"google.protobuf.FieldDescriptorProto.Type\", FieldDescriptorProto_Type, \"TYPE_\"] },\n            { no: 6, name: \"type_name\", kind: \"scalar\", opt: true, T: 9 },\n        ]);\n    }\n}\nexport const FieldDescriptorProtoType = new FieldDescriptorProto$Type();\n\nclass EnumDescriptorProto$Type extends MessageType<EnumDescriptorProto> {\n    constructor() {\n        super(\"google.protobuf.EnumDescriptorProto\", [\n            { no: 1, name: \"name\", kind: \"scalar\", opt: true, T: 9 },\n            { no: 2, name: \"value\", kind: \"message\", repeat: 2, T: () => EnumValueDescriptorProtoType },\n        ]);\n    }\n}\nexport const EnumDescriptorProtoType = new EnumDescriptorProto$Type();\n\nclass EnumValueDescriptorProto$Type extends MessageType<{ name?: string; number?: number }> {\n    constructor() {\n        super(\"google.protobuf.EnumValueDescriptorProto\", [\n            { no: 1, name: \"name\", kind: \"scalar\", opt: true, T: 9 },\n            { no: 2, name: \"number\", kind: \"scalar\", opt: true, T: 5 },\n        ]);\n    }\n}\nexport const EnumValueDescriptorProtoType = new EnumValueDescriptorProto$Type();\n\nclass MessageOptions$Type extends MessageType<MessageOptions> {\n    constructor() {\n        super(\"google.protobuf.MessageOptions\", [\n            { no: 7, name: \"map_entry\", kind: \"scalar\", opt: true, T: 8 },\n        ]);\n    }\n}\nexport const MessageOptionsType = new MessageOptions$Type();\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/test/DescriptorDatabase.spec.ts",
    "content": "// @ts-nocheck\nimport { getLoadedDescriptorDatabase } from './DescriptorDatabaseTestUtils';\nimport { ScalarType } from '@protobuf-ts/runtime';\n\ndescribe('DescriptorDatabase', () => {\n  it('can load type names', () => {\n    const database = getLoadedDescriptorDatabase();\n\n    expect(database.getAllTypeNames().map(t => t.fullName)).toEqual([\n      'test3.Message3',\n      'test.OtherMessage',\n      'test.Message',\n      'test.RepeatedMessage',\n      'test.ParentMessage.ChildMessage',\n      'test.ParentMessage',\n      'test.ParentMessage.ChildEnum',\n      'test.OneOfMessage',\n      'test.OldMessage',\n      'test.NewMessage',\n      'test.OldEnumMessage',\n      'test.OldEnumMessage.OldEnum',\n      'test.NewEnumMessage',\n      'test.NewEnumMessage.NewEnum',\n      'test.MapMessage',\n      'test.ExternalMessages',\n      'test.Enum',\n      'test2.Message2',\n      'package_with_underscores.Message_With_Underscores',\n      'package_with_underscores.M3ssage1WithNumb3r2',\n      'package_with_underscores.Enum_With_Underscores',\n    ]);\n\n    const message = database.getMessageType('test.Message');\n    expect(message).toBeTruthy();\n\n    const nestedMessage = database.getMessageType('test.ParentMessage.ChildMessage');\n    expect(nestedMessage).toBeTruthy();\n\n    const underscorePackage = database.getMessageType('package_with_underscores.Message_With_Underscores');\n    expect(underscorePackage).toBeTruthy();\n  });\n\n  it('can load root enum type', () => {\n    const database = getLoadedDescriptorDatabase();\n    const enumInfo = database.getEnumInfo('test.Enum');\n    // EnumInfo is [typeName, enumObject]\n    const enumObj = enumInfo[1];\n    expect(enumObj['VALUE_0']).toBe(0);\n    expect(enumObj['VALUE_1']).toBe(1);\n  });\n\n  it('can load nested enum type', () => {\n    const database = getLoadedDescriptorDatabase();\n    const enumInfo = database.getEnumInfo('test.ParentMessage.ChildEnum');\n    const enumObj = enumInfo[1];\n    expect(enumObj['VALUE_0']).toBe(0);\n    expect(enumObj['VALUE_1']).toBe(1);\n  });\n\n  it('can load message', () => {\n    const database = getLoadedDescriptorDatabase();\n    const messageType = database.getMessageType('test.Message');\n\n    // Find int32 field\n    const int32Field = messageType.fields.find(f => f.name === 'int32');\n    expect(int32Field).toBeTruthy();\n    expect(int32Field!.no).toBe(1);\n    expect(int32Field!.kind).toBe('scalar');\n    if (int32Field!.kind === 'scalar') {\n      expect(int32Field!.T).toBe(ScalarType.INT32);\n    }\n\n    // Find otherMessage field\n    const otherMessageField = messageType.fields.find(f => f.name === 'otherMessage');\n    expect(otherMessageField).toBeTruthy();\n    expect(otherMessageField!.no).toBe(18);\n    expect(otherMessageField!.kind).toBe('message');\n  });\n\n  it('can load nested message', () => {\n    const database = getLoadedDescriptorDatabase();\n    const messageType = database.getMessageType('test.ParentMessage.ChildMessage');\n\n    const valueField = messageType.fields.find(f => f.name === 'value');\n    expect(valueField).toBeTruthy();\n    expect(valueField!.no).toBe(1);\n    expect(valueField!.kind).toBe('scalar');\n    if (valueField!.kind === 'scalar') {\n      expect(valueField!.T).toBe(ScalarType.STRING);\n    }\n  });\n\n  it('can load repeated message', () => {\n    const database = getLoadedDescriptorDatabase();\n    const messageType = database.getMessageType('test.RepeatedMessage');\n\n    const int32Field = messageType.fields.find(f => f.name === 'int32');\n    expect(int32Field).toBeTruthy();\n    expect(int32Field!.no).toBe(1);\n    expect(int32Field!.kind).toBe('scalar');\n    // Check if repeated (repeat !== RepeatType.NO which is 0)\n    expect(int32Field!.repeat).not.toBe(0);\n  });\n\n  it('can load map message', () => {\n    const database = getLoadedDescriptorDatabase();\n    const messageType = database.getMessageType('test.MapMessage');\n\n    const stringToStringField = messageType.fields.find(f => f.name === 'stringToString');\n    expect(stringToStringField).toBeTruthy();\n    expect(stringToStringField!.no).toBe(1);\n    expect(stringToStringField!.kind).toBe('map');\n    if (stringToStringField!.kind === 'map') {\n      expect(stringToStringField!.K).toBe(ScalarType.STRING);\n      expect(stringToStringField!.V.kind).toBe('scalar');\n    }\n\n    const stringToDoubleField = messageType.fields.find(f => f.name === 'stringToDouble');\n    expect(stringToDoubleField).toBeTruthy();\n    expect(stringToDoubleField!.no).toBe(5);\n    expect(stringToDoubleField!.kind).toBe('map');\n    if (stringToDoubleField!.kind === 'map') {\n      expect(stringToDoubleField!.K).toBe(ScalarType.STRING);\n      expect(stringToDoubleField!.V.kind).toBe('scalar');\n    }\n\n    const longToStringField = messageType.fields.find(f => f.name === 'longToString');\n    expect(longToStringField).toBeTruthy();\n    expect(longToStringField!.no).toBe(8);\n    expect(longToStringField!.kind).toBe('map');\n    if (longToStringField!.kind === 'map') {\n      expect(longToStringField!.K).toBe(ScalarType.INT64);\n      expect(longToStringField!.V.kind).toBe('scalar');\n    }\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/test/DescriptorDatabaseTestUtils.ts",
    "content": "import { DescriptorDatabase } from '../headless/DescriptorDatabase';\n\n// Node fs/path imports - using require to avoid needing @types/node in tsconfig\ndeclare function require(name: string): any;\ndeclare const __dirname: string;\nconst fs = require('fs');\nconst path = require('path');\n\nexport function getLoadedDescriptorDatabase(): DescriptorDatabase {\n  // Load proto.protodecl from the test directory\n    // Path is relative to compiled location in web/test/, goes up 2 levels to valdi_protobuf/, then to test/\n    const protoDeclPath = path.join(__dirname, '../../test/proto.protodecl');\n  const protoDeclContent = fs.readFileSync(protoDeclPath);\n  const database = new DescriptorDatabase();\n  database.addFileDescriptorSet(new Uint8Array(protoDeclContent));\n  database.resolve();\n  return database;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/test/NamespaceGenerator.spec.ts",
    "content": "// @ts-nocheck\nimport { IArena, IMessage, IMessageNamespace } from '../src_symlink/types';\nimport {\n  generateMonkeyPatchedNamespace,\n  ProtobufTsMessageWrapper,\n} from '../headless/NamespaceGenerator';\nimport { Message as ValdiMessage } from '../Message';\nimport { getLoadedDescriptorDatabase } from './DescriptorDatabaseTestUtils';\n\n// Import extracted types (interfaces + const enums) without native dependencies\n// const enums are inlined at compile time, so no runtime module load\nimport { test } from './proto-types';\n\n// Extended interface that includes the actual runtime methods\ninterface IRuntimeMessage extends IMessage {\n  encode(): Uint8Array;\n}\n\n// Mock Arena for web tests - the namespace generator ignores it anyway\nclass MockArena implements IArena {\n  createMessage(): never { throw new Error('Not implemented'); }\n  decodeMessage(): never { throw new Error('Not implemented'); }\n  decodeMessageAsync(): never { throw new Error('Not implemented'); }\n  decodeMessageDebugJSONAsync(): never { throw new Error('Not implemented'); }\n  encodeMessage(): never { throw new Error('Not implemented'); }\n  encodeMessageAsync(): never { throw new Error('Not implemented'); }\n  batchEncodeMessageAsync(): never { throw new Error('Not implemented'); }\n  encodeMessageToJSON(): never { throw new Error('Not implemented'); }\n  getMessageFields(): never { throw new Error('Not implemented'); }\n  setMessageField(): never { throw new Error('Not implemented'); }\n  getMessageInstance(): never { throw new Error('Not implemented'); }\n  copyMessage(): never { throw new Error('Not implemented'); }\n}\n\n// Base64 encoding (ported from coreutils/src/Base64.ts)\nconst lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nfunction tripletToBase64(num: number): string {\n  return lookup[(num >> 18) & 0x3f] + lookup[(num >> 12) & 0x3f] + lookup[(num >> 6) & 0x3f] + lookup[num & 0x3f];\n}\nconst Base64 = {\n  fromByteArray(uint8: Uint8Array): string {\n    const len = uint8.length;\n    const extraBytes = len % 3;\n    const parts: string[] = [];\n    for (let i = 0, len2 = len - extraBytes; i < len2; i += 3) {\n      const tmp = ((uint8[i] << 16) & 0xff0000) + ((uint8[i + 1] << 8) & 0xff00) + (uint8[i + 2] & 0xff);\n      parts.push(tripletToBase64(tmp));\n    }\n    if (extraBytes === 1) {\n      const tmp = uint8[len - 1];\n      parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==');\n    } else if (extraBytes === 2) {\n      const tmp = (uint8[len - 2] << 8) + uint8[len - 1];\n      parts.push(lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3f] + lookup[(tmp << 2) & 0x3f] + '=');\n    }\n    return parts.join('');\n  }\n};\n\ninterface TypedMessageNamespace<I> {\n  create: (arena: IArena, properties?: I) => I & IRuntimeMessage;\n  decode: (arena: IArena, buffer: Uint8Array) => I & IRuntimeMessage;\n}\n\nfunction getTypedMessageNamespace<I>(getNamespace: (input: any) => any): TypedMessageNamespace<I> {\n  const database = getLoadedDescriptorDatabase();\n  const namespace = generateMonkeyPatchedNamespace(database, database.getAllMessageDescriptorTypeNames()) as any;\n\n  const messageNamespace = getNamespace(namespace);\n  if (!messageNamespace) {\n    throw new Error('Could not resolve namespace');\n  }\n  return getNamespace(namespace) as unknown as TypedMessageNamespace<I>;\n}\n\ndescribe('NamespaceGenerator', () => {\n  it('can generate monkey patched js namespaces', () => {\n    const database = getLoadedDescriptorDatabase();\n    const namespace = generateMonkeyPatchedNamespace(database, database.getAllMessageDescriptorTypeNames()) as any;\n    const Message = namespace.test?.Message as IMessageNamespace;\n\n    expect(Message).toBeTruthy();\n    expect(Message.create).toBeTruthy();\n    expect(Message.decodeAsync).toBeTruthy();\n    expect(Message.encode).toBeTruthy();\n    expect(Message.encodeAsync).toBeTruthy();\n    expect(Message.decodeDebugJSONAsync).toBeTruthy();\n\n    const message = Message.create(new MockArena(), {\n      int32: 42,\n      string: 'Hello World',\n    });\n\n    expect((message as test.IMessage).int32).toEqual(42);\n    expect((message as test.IMessage).string).toEqual('Hello World');\n\n    const encoded = message.encode();\n    expect(Base64.fromByteArray(encoded)).toBe('CCpyC0hlbGxvIFdvcmxk');\n\n    const decodedMessage = Message.decode(message.$arena, encoded);\n    expect((decodedMessage as test.IMessage).int32).toEqual(42);\n    expect((decodedMessage as test.IMessage).string).toEqual('Hello World');\n  });\n\n  it('ensures messages inherit Valdi messages', () => {\n    const database = getLoadedDescriptorDatabase();\n    const namespace = generateMonkeyPatchedNamespace(database, database.getAllMessageDescriptorTypeNames()) as any;\n    const Message = namespace.test?.Message as IMessageNamespace;\n\n    expect(Message).toBeTruthy();\n\n    const message = Message.create(new MockArena(), {});\n    expect(message instanceof ProtobufTsMessageWrapper).toBe(true);\n    expect(message instanceof ValdiMessage).toBe(true);\n  });\n\n  it('can encode and decode message from monkey patched js namespace', () => {\n    const Message = getTypedMessageNamespace<test.IMessage>(namespace => namespace.test?.Message);\n\n    const message = Message.create(new MockArena(), {\n      int32: 42,\n      string: 'Hello World',\n    });\n\n    expect(message.int32).toEqual(42);\n    expect(message.string).toEqual('Hello World');\n\n    const encoded = message.encode();\n    expect(Base64.fromByteArray(encoded)).toBe('CCpyC0hlbGxvIFdvcmxk');\n\n    const decodedMessage = Message.decode(new MockArena(), encoded);\n    expect((decodedMessage as test.IMessage).int32).toEqual(42);\n    expect((decodedMessage as test.IMessage).string).toEqual('Hello World');\n  });\n\n  it('supports nested messages in monkey patched js namespace', () => {\n    const ParentMessage = getTypedMessageNamespace<test.IParentMessage>(\n      namespace => namespace.test?.ParentMessage,\n    );\n\n    const parentMessage = ParentMessage.create(new MockArena(), {\n      childMessage: {\n        value: 'Hello World',\n      },\n      childEnum: test.ParentMessage.ChildEnum.VALUE_1,\n    });\n\n    expect(parentMessage.childEnum).toBe(test.ParentMessage.ChildEnum.VALUE_1);\n    expect(parentMessage.childMessage?.value).toBe('Hello World');\n  });\n\n  // Does not yet work\n  xit('supports nested map messages in monkey patched js namespace', () => {\n    const MapMessage = getTypedMessageNamespace<test.IMapMessage>(\n      namespace => namespace.test?.MapMessage,\n    );\n\n    const message = MapMessage.create(new MockArena(), {\n      stringToDouble: new Map([\n        ['key1', 0],\n        ['key2', 1],\n      ]),\n      stringToMessage: new Map([\n        [\n          'message',\n          {\n            value: 'Hello World',\n          },\n        ],\n      ]),\n    });\n\n    expect(message.stringToDouble instanceof Map).toBe(true);\n    expect(message.stringToMessage instanceof Map).toBe(true);\n\n    expect(message.stringToDouble?.get('key1')).toBe(0);\n    expect(message.stringToDouble?.get('key2')).toBe(1);\n\n    const nestedMessage = message.stringToMessage?.get('message');\n    expect(nestedMessage).toBeDefined();\n    expect(nestedMessage instanceof ValdiMessage).toBeTruthy();\n    expect((nestedMessage as any)?.value).toBe('Hello World');\n\n    const encoded = message.encode();\n    expect(Base64.fromByteArray(encoded)).toBe('');\n  });\n});\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/test/README.md",
    "content": "# Valdi Protobuf Web Tests\n\n## Type Definitions\n\nThe web tests need to reference proto message types without pulling in native Valdi dependencies (like `IArena`, `ProtobufMessage`, etc.) that don't work in a web environment.\n\n### File Structure\n\n- **`proto-types.d.ts`** - Auto-generated TypeScript type definitions (interfaces and enums only)\n  - Extracted from `../../test/proto.d.ts`\n  - Contains ONLY pure type definitions (interfaces and enums)\n  - All `class` declarations and native imports are removed\n  - **DO NOT EDIT MANUALLY** - regenerate using `extract_types.py`\n\n- **`extract_types.py`** - Python script to extract pure types from `test/proto.d.ts`\n  - Automatically filters out class declarations and native imports\n  - Preserves all interfaces, enums, and namespaces\n  - Auto-adds `Long` import if needed\n\n### Regenerating Types\n\nWhen the proto definitions in `../../proto/*.proto` change and `../../test/proto.d.ts` is regenerated:\n\n```bash\ncd web/test\npython3 extract_types.py > proto-types.d.ts\n```\n\n### Why Not Use test/proto.d.ts Directly?\n\nThe file `../../test/proto.d.ts` is generated for native Valdi and includes:\n- `import { IArena } from \"valdi_protobuf/src/types\"`  (native only)\n- `import { Message as ProtobufMessage } from \"valdi_protobuf/src/Message\"` (native only)\n- `export class Message extends ProtobufMessage<IMessage>` (native runtime classes)\n\n**Why not use `import type { test } from '../../test/proto'`?**\n\nTypeScript's `import type` only works for pure type annotations. We also use **enum values** at runtime (e.g., `test.ParentMessage.ChildEnum.VALUE_1`), which `import type` doesn't allow.\n\n**How does proto-types.d.ts avoid runtime module loads?**\n\nThe extracted types use `const enum` instead of regular `enum`. TypeScript inlines `const enum` values at compile time:\n\n```typescript\n// Source:\nchildEnum: test.ParentMessage.ChildEnum.VALUE_1\n\n// Compiled JS:\nchildEnum: 1  // <-- inlined literal, no module load!\n```\n\nSo we get:\n- ✅ Type safety for interfaces\n- ✅ Runtime enum values (inlined at compile time)  \n- ✅ No runtime dependencies on native modules\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/test/extract_types.py",
    "content": "#!/usr/bin/env python3\n\"\"\"\nExtract pure type definitions (interfaces and enums) from test/proto.d.ts\nfor web-compatible usage without native dependencies.\n\"\"\"\n\nimport re\n\ndef extract_pure_types(input_file):\n    with open(input_file, 'r') as f:\n        lines = f.readlines()\n    \n    output = []\n    skip_until_depth = None  # When set, skip until we return to this depth\n    depth = 0\n    in_namespace = False\n    \n    for line in lines:\n        stripped = line.strip()\n        \n        # Skip imports with 'from'\n        if stripped.startswith('import ') and ' from ' in line:\n            continue\n        \n        # Skip \"Generated by\" comments\n        if 'Generated by' in line or 'DO NOT EDIT!' in line:\n            continue\n        \n        # Track brace depth\n        depth += line.count('{') - line.count('}')\n        \n        # If we're skipping (inside a class), check if we've exited\n        if skip_until_depth is not None:\n            if depth <= skip_until_depth:\n                skip_until_depth = None\n            continue\n        \n        # Check if this is a class declaration - start skipping\n        if re.search(r'\\bexport class \\w+', line):\n            skip_until_depth = depth - 1  # Skip until we exit this class\n            continue\n        \n        # Keep namespaces, interfaces, and enums\n        if (re.search(r'\\bexport (namespace|interface|const enum) \\w+', line) or\n            stripped.startswith('export namespace ')):\n            output.append(line)\n            continue\n        \n        # If we're at top level or in a namespace/interface/enum, keep the line\n        # This includes field definitions, comments, closing braces, etc.\n        if skip_until_depth is None:\n            # Skip empty lines at the start\n            if not output and not stripped:\n                continue\n            output.append(line)\n    \n    return ''.join(output)\n\nif __name__ == '__main__':\n    input_file = '../../test/proto.d.ts'\n    output = extract_pure_types(input_file)\n    \n    # Check if Long type is used\n    needs_long_import = 'Long' in output or ': Long' in output\n    \n    # Add header\n    header = \"\"\"/**\n * Web-compatible type definitions extracted from test/proto.d.ts\n * \n * This file contains ONLY pure type definitions (interfaces and enums).\n * All class declarations and native dependencies have been removed.\n * \n * Generated by extract_types.py - DO NOT EDIT MANUALLY\n * To regenerate: cd web/test && python3 extract_types.py > proto-types.d.ts\n */\n\n\"\"\"\n    \n    # Add Long import if needed\n    if needs_long_import:\n        header += \"import Long from 'long';\\n\\n\"\n    \n    print(header + output)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/test/proto-types.d.ts",
    "content": "/**\n * Web-compatible type definitions extracted from test/proto.d.ts\n * \n * This file contains ONLY pure type definitions (interfaces and enums).\n * All class declarations and native dependencies have been removed.\n * \n * Generated by extract_types.py - DO NOT EDIT MANUALLY\n * To regenerate: cd web/test && python3 extract_types.py > proto-types.d.ts\n */\n\nimport Long from 'long';\n\n/**\n */\n\nexport namespace test {\n  export const enum Enum {\n    VALUE_0 = 0,\n    VALUE_1 = 1,\n    /** Unrecognized value */\n    $UNRECOGNIZED_VALUE = 0xffffffffff\n  }\n\n  /**\n   * Test\n   * multiline\n   * comment\n   */\n\n  /** Interface for creating OtherMessage instances */\n  export interface IOtherMessage {\n    value?: string;\n  }\n\n  /**\n   * Test comment\n   * another line\n   */\n\n  /** Interface for creating Message instances */\n  export interface IMessage {\n    int32?: number;\n    int64?: Long;\n    uint32?: number;\n    uint64?: Long;\n    sint32?: number;\n    sint64?: Long;\n    fixed32?: number;\n    fixed64?: Long;\n    sfixed32?: number;\n    sfixed64?: Long;\n    float?: number;\n    double?: number;\n    bool?: boolean;\n    string?: string;\n    bytes?: Uint8Array;\n    enum?: test.Enum;\n    selfMessage?: test.IMessage;\n    otherMessage?: test.IOtherMessage;\n  }\n\n\n  /** Interface for creating RepeatedMessage instances */\n  export interface IRepeatedMessage {\n    int32?: readonly number[];\n    int64?: readonly Long[];\n    uint32?: readonly number[];\n    uint64?: readonly Long[];\n    sint32?: readonly number[];\n    sint64?: readonly Long[];\n    fixed32?: readonly number[];\n    fixed64?: readonly Long[];\n    sfixed32?: readonly number[];\n    sfixed64?: readonly Long[];\n    float?: readonly number[];\n    double?: readonly number[];\n    bool?: readonly boolean[];\n    string?: readonly string[];\n    bytes?: readonly Uint8Array[];\n    enum?: readonly test.Enum[];\n    selfMessage?: readonly test.IRepeatedMessage[];\n    otherMessage?: readonly test.IOtherMessage[];\n  }\n\n\n  /** Interface for creating ParentMessage instances */\n  export interface IParentMessage {\n    childMessage?: test.ParentMessage.IChildMessage;\n    childEnum?: test.ParentMessage.ChildEnum;\n  }\n\n  export namespace ParentMessage {\n    /** Comment for child enum */\n    export const enum ChildEnum {\n      /** Comment for value 0 */\n      VALUE_0 = 0,\n      /** Comment for value 1 */\n      VALUE_1 = 1,\n      /** Unrecognized value */\n      $UNRECOGNIZED_VALUE = 0xffffffffff\n    }\n\n\n    /** Interface for creating ChildMessage instances */\n    export interface IChildMessage {\n      value?: string;\n    }\n  }\n\n\n  /** Interface for creating OneOfMessage instances */\n  export interface IOneOfMessage {\n    string0?: string;\n    string1?: string;\n    message0?: test.IOtherMessage;\n    message1?: test.IOtherMessage;\n    bytes0?: Uint8Array;\n    bytes1?: Uint8Array;\n  }\n\n\n  /** Interface for creating OldMessage instances */\n  export interface IOldMessage {\n    oldValue?: string;\n  }\n\n\n  /** Interface for creating NewMessage instances */\n  export interface INewMessage {\n    oldValue?: string;\n    newValue?: string;\n  }\n\n\n  /** Interface for creating OldEnumMessage instances */\n  export interface IOldEnumMessage {\n    value?: test.OldEnumMessage.OldEnum;\n    repeatedValue?: readonly test.OldEnumMessage.OldEnum[];\n    mappedValue?: ReadonlyMap<string, test.OldEnumMessage.OldEnum>;\n  }\n\n  export namespace OldEnumMessage {\n    export const enum OldEnum {\n      VALUE_0 = 0,\n      VALUE_1 = 1,\n      /** Unrecognized value */\n      $UNRECOGNIZED_VALUE = 0xffffffffff\n    }\n  }\n\n\n  /** Interface for creating NewEnumMessage instances */\n  export interface INewEnumMessage {\n    value?: test.NewEnumMessage.NewEnum;\n    repeatedValue?: readonly test.NewEnumMessage.NewEnum[];\n    mappedValue?: ReadonlyMap<string, test.NewEnumMessage.NewEnum>;\n  }\n\n  export namespace NewEnumMessage {\n    export const enum NewEnum {\n      VALUE_0 = 0,\n      VALUE_1 = 1,\n      VALUE_2 = 200,\n      VALUE_3 = 300,\n      /** Unrecognized value */\n      $UNRECOGNIZED_VALUE = 0xffffffffff\n    }\n  }\n\n\n  /** Interface for creating MapMessage instances */\n  export interface IMapMessage {\n    stringToString?: ReadonlyMap<string, string>;\n    stringToNumber?: ReadonlyMap<string, number>;\n    stringToSignedLong?: ReadonlyMap<string, Long>;\n    stringToUnsignedLong?: ReadonlyMap<string, Long>;\n    stringToDouble?: ReadonlyMap<string, number>;\n    stringToMessage?: ReadonlyMap<string, test.IOtherMessage>;\n    intToString?: ReadonlyMap<number, string>;\n    longToString?: ReadonlyMap<Long, string>;\n  }\n\n\n  /** Interface for creating ExternalMessages instances */\n  export interface IExternalMessages {\n    otherMessage?: test3.IMessage3;\n  }\n}\nimport __test__ = test;\n\nexport namespace test3 {\n\n  /** Interface for creating Message3 instances */\n  export interface IMessage3 {\n    value?: string;\n  }\n}\nimport __test3__ = test3;\n\nexport namespace test2 {\n\n  /** Interface for creating Message2 instances */\n  export interface IMessage2 {\n    value?: string;\n  }\n}\nimport __test2__ = test2;\n\nexport namespace package_with_underscores {\n  export const enum Enum_With_Underscores {\n    ENUM_VALUE_0 = 0,\n    ENUM_VALUE_1 = 1,\n    E2NUM_VALUE_WITH_NUMBER = 2,\n    /** Unrecognized value */\n    $UNRECOGNIZED_VALUE = 0xffffffffff\n  }\n\n\n  /** Interface for creating Message_With_Underscores instances */\n  export interface IMessage_With_Underscores {\n    fieldUnderscore?: number;\n    fieldUnderscoreAgain?: number;\n    enumValue?: package_with_underscores.Enum_With_Underscores;\n    messageValue?: package_with_underscores.IMessage_With_Underscores;\n  }\n\n\n  /** Interface for creating M3ssage1WithNumb3r2 instances */\n  export interface IM3ssage1WithNumb3r2 {\n    fie1ld?: number;\n    field2?: number;\n    field3?: number;\n    a4Fiel4d?: number;\n    a5aFiel5d?: number;\n    enum?: package_with_underscores.Enum_With_Underscores;\n  }\n}\nimport __package_with_underscores__ = package_with_underscores;\n\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/test/run_tests.js",
    "content": "#!/usr/bin/env node\n/**\n * Test runner for web protobuf tests using Jest\n */\n\nconst { spawnSync } = require('child_process');\nconst path = require('path');\nconst fs = require('fs');\n\n// Bazel runfiles helper\nconst runfiles = process.env.RUNFILES_DIR ||  process.env.RUNFILES;\nif (!runfiles) {\n  console.error('RUNFILES_DIR not set');\n  process.exit(1);\n}\n\n// Add node_modules to NODE_PATH so Jest can resolve dependencies\n// Try multiple possible runfiles paths (local workspace vs external workspace referencing valdi)\nconst possiblePaths = [\n  path.join(runfiles, 'valdi/src/valdi_modules/src/valdi/valdi_protobuf/node_modules'), // Local valdi workspace\n  path.join(runfiles, '_main~local_repos~valdi/src/valdi_modules/src/valdi/valdi_protobuf/node_modules'), // External workspace referencing valdi\n];\n\nlet nodeModulesPath = null;\nfor (const p of possiblePaths) {\n  if (fs.existsSync(p)) {\n    nodeModulesPath = p;\n    break;\n  }\n}\n\nif (!nodeModulesPath) {\n  console.error(`Could not find node_modules in any of: ${possiblePaths.join(', ')}`);\n  process.exit(1);\n}\n\nprocess.env.NODE_PATH = nodeModulesPath + (process.env.NODE_PATH ? ':' + process.env.NODE_PATH : '');\nrequire('module').Module._initPaths();\n\n// Find jest binary via runfiles\nconst jestBin = path.join(nodeModulesPath, 'jest/bin/jest.js');\n\nif (!fs.existsSync(jestBin)) {\n  console.error(`Jest binary not found at: ${jestBin}`);\n  process.exit(1);\n}\n\n// The compiled test files are in the dist output directory\n// Only test files from valdi_protobuf/web/test (out_dir is \"web\" so compiled files are at web/test)\nconst testDir = path.join(runfiles, 'valdi/src/valdi_modules/src/valdi/valdi_protobuf/web/test');\n\nif (!fs.existsSync(testDir)) {\n  console.error(`Test directory not found: ${testDir}`);\n  process.exit(1);\n}\n\n// List test files explicitly - only .spec.js files in test/\nconst testFiles = fs.readdirSync(testDir)\n  .filter(f => f.endsWith('.spec.js'))\n  .map(f => path.join(testDir, f));\n\nif (testFiles.length === 0) {\n  console.error(`No .spec.js files found in ${testDir}`);\n  process.exit(1);\n}\n\nconsole.log('Running tests:', testFiles);\n\n// Run jest on the compiled test files directly\n// Create a temp jest config to prevent auto-discovery\nconst jestConfig = {\n  testEnvironment: 'node',\n  testPathIgnorePatterns: [],  // Don't ignore anything\n  roots: [testDir],  // Only search in test directory\n  testMatch: ['**/*.spec.js'],  // Only match .spec.js files\n};\nconst configPath = path.join(testDir, 'jest.config.json');\nfs.writeFileSync(configPath, JSON.stringify(jestConfig));\n\nconsole.log('Running tests:', testFiles);\nconst result = spawnSync('node', [\n  jestBin,\n  '--config', configPath,\n  '--verbose',\n  '--runTestsByPath',  // Only run the exact paths provided\n  ...testFiles  // Pass test files directly\n], {\n  stdio: 'inherit',\n  cwd: testDir  // Run from test directory\n});\n\n// Clean up config\ntry {\n  fs.unlinkSync(configPath);\n} catch (e) {\n  // Ignore cleanup errors\n}\n\nprocess.exit(result.status || 0);\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/test/run_tests.sh",
    "content": "#!/bin/bash\n# Run Jest tests for valdi_protobuf web\nset -e\n\n# Find the runfiles directory\nif [[ -n \"$RUNFILES_DIR\" ]]; then\n    RUNFILES=\"$RUNFILES_DIR\"\nelif [[ -d \"${BASH_SOURCE[0]}.runfiles\" ]]; then\n    RUNFILES=\"${BASH_SOURCE[0]}.runfiles\"\nelse\n    echo \"Cannot find runfiles directory\"\n    exit 1\nfi\n\n# Find node binary - try common locations\nNODE_BIN=\"\"\nfor path in /opt/homebrew/bin/node /usr/local/bin/node /usr/bin/node; do\n    if [[ -x \"$path\" ]]; then\n        NODE_BIN=\"$path\"\n        break\n    fi\ndone\nif [[ -z \"$NODE_BIN\" ]]; then\n    echo \"Could not find node binary in standard locations\"\n    exit 1\nfi\n\n# The valdi external repo name\nVALDI_REPO=\"_main~local_repos~valdi\"\n\n# Path to node_modules in runfiles\nNODE_MODULES_DIR=\"$RUNFILES/$VALDI_REPO/bzl/valdi/npm/node_modules\"\n\n# Test directory\nTEST_DIR=\"$RUNFILES/$VALDI_REPO/src/valdi_modules/src/valdi/valdi_protobuf\"\n\n# Jest binary\nJEST_BIN=\"$NODE_MODULES_DIR/jest/bin/jest.js\"\n\nif [[ ! -f \"$JEST_BIN\" ]]; then\n    echo \"Could not find jest binary at: $JEST_BIN\"\n    echo \"Looking in runfiles: $RUNFILES\"\n    ls -la \"$RUNFILES\" || true\n    exit 1\nfi\n\n# Set NODE_PATH to allow jest to find its dependencies\nexport NODE_PATH=\"$NODE_MODULES_DIR\"\n\n# Create a minimal jest config to avoid filesystem scanning\nJEST_CONFIG=$(cat <<EOF\n{\n  \"rootDir\": \"$TEST_DIR\",\n  \"testMatch\": [\"**/web/test/*.spec.js\"],\n  \"testEnvironment\": \"node\",\n  \"moduleDirectories\": [\"node_modules\", \"$NODE_MODULES_DIR\"],\n  \"watchman\": false,\n  \"haste\": {\n    \"enableSymlinks\": true\n  }\n}\nEOF\n)\n\n# Run jest\ncd \"$TEST_DIR\"\n\"$NODE_BIN\" \"$JEST_BIN\" \\\n    --config=\"$JEST_CONFIG\" \\\n    --verbose\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_protobuf/web/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"target\": \"ES2020\",\n    \"module\": \"commonjs\",\n    \"moduleResolution\": \"node\",\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"composite\": true,\n    \"declaration\": true,\n    \"allowJs\": true,\n    \"resolveJsonModule\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"lib\": [\"DOM\", \"ES2020\"],\n    \"typeRoots\": [\n      \"../../../../../../bzl/valdi/npm/node_modules/@types\"\n    ],\n    \"paths\": {\n      \"@protobuf-ts/runtime\": [\"../../../../../../bzl/valdi/npm/node_modules/@protobuf-ts/runtime\"]\n    }\n  },\n  \"include\": [\n    \"./**/*.ts\",\n    \"./**/*.d.ts\"\n  ],\n  \"exclude\": [\n    \"**/*.js\",\n    \"**/node_modules/**\",\n    \"node_modules\",\n    \"src_symlink\"\n  ]\n}"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/BUILD.bazel",
    "content": "load(\"//bzl/valdi:valdi_module.bzl\", \"valdi_module\")\n\n####################\n## THIS IS AN AUTOGENERATED FILE\n##\n## Regenerate using ./scripts/regenerate_valdi_modules_build_bazel_files.sh\n####################\n\nvaldi_module(\n    name = \"valdi_rxjs\",\n    srcs = glob(\n        [\n            \"src/**/*.ts\",\n            \"src/**/*.tsx\",\n        ],\n        exclude = [\n            \"**/node_modules/**\",\n            \"**/observable/dom/**\",\n            \"**/observable/bindNodeCallback.ts\",\n        ],\n    ) + [\n        \"tsconfig.json\",\n    ],\n    android_output_target = \"release\",\n    disable_annotation_processing = True,\n    ios_module_name = \"SCCValdiRxjs\",\n    ios_output_target = \"release\",\n    module_yaml = \"module.yaml\",\n    single_file_codegen = False,\n    visibility = [\"//visibility:public\"],\n    deps = [\n        \"@valdi//src/valdi_modules/src/valdi/valdi_core\",\n    ],\n)\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/README.md",
    "content": "# RxJS for Valdi components\n\nThis module is a mirror from npm package which contains files from `rx/src/internal`.\nFiles which are specific to the web platform were removed:\n- `rx/src/internal/ajax`\n- `rx/src/internal/observable/dom`\n- `rx/src/internal/observable/bindNodeCallback.ts`\n\nThe `useDeprecatedSynchronousErrorHandling` code path has been removed and `errorContext` wrapping has been removed from `Observable.ts` and `Subject.ts` to ameliorate stack overflow problems on Android. \n\nCurrent version rxjs you can check in the `package.json`\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/module.yaml",
    "content": "disable_hotreload: true\ndisable_annotation_processing: true\ndisable_dependency_verification: true\ndisable_code_coverage: true\n\nexclude_patterns:\n  # NOTE: to keep the bundle size down, we strip out mostly everything from RxJS we don't need.\n  # If you are building a new feature that requires an excluded operator, feel free to\n  # add it to the whitelist below.\n\n  - .*\\/node_modules.*\n  # observable BLACKLIST\n  - .*\\/observable\\/dom\\/.* # ajax and websocket observables; adds ~10kb\n  - .*\\/observable\\/bindNodeCallback\\.ts # we're not in nodeland\n\nexclude_globs:\n  - \"**/node_modules/**\"\n  - \"**/observable/dom/**\"\n  - \"**/observable/bindNodeCallback.ts\"\n\noutput_target: release\n\ndependencies:\n  - valdi_core\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/package.json",
    "content": "{\n  \"name\": \"rxjs-valdi\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This module contains a mirror of rxjs lib for using it in Valdi. For details please check the README\",\n  \"dependencies\": {\n    \"rxjs\": \"7.5.5\"\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/AnyCatcher.ts",
    "content": "/*\n * Note that we cannot apply the `internal` tag here because the declaration\n * needs to survive the `stripInternal` option. Otherwise, `AnyCatcher` will\n * be `any` in the `.d.ts` files.\n */\ndeclare const anyCatcherSymbol: unique symbol;\n\n/**\n * This is just a type that we're using to identify `any` being passed to\n * function overloads. This is used because of situations like {@link forkJoin},\n * where it could return an `Observable<T[]>` or an `Observable<{ [key: K]: T }>`,\n * so `forkJoin(any)` would mean we need to return `Observable<unknown>`.\n */\nexport type AnyCatcher = typeof anyCatcherSymbol;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/AsyncSubject.ts",
    "content": "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\n\n/**\n * A variant of Subject that only emits a value when it completes. It will emit\n * its latest value to all its observers on completion.\n *\n * @class AsyncSubject<T>\n */\nexport class AsyncSubject<T> extends Subject<T> {\n  private _value: T | null = null;\n  private _hasValue = false;\n  private _isComplete = false;\n\n  /** @internal */\n  protected _checkFinalizedStatuses(subscriber: Subscriber<T>) {\n    const { hasError, _hasValue, _value, thrownError, isStopped, _isComplete } = this;\n    if (hasError) {\n      subscriber.error(thrownError);\n    } else if (isStopped || _isComplete) {\n      _hasValue && subscriber.next(_value!);\n      subscriber.complete();\n    }\n  }\n\n  next(value: T): void {\n    if (!this.isStopped) {\n      this._value = value;\n      this._hasValue = true;\n    }\n  }\n\n  complete(): void {\n    const { _hasValue, _value, _isComplete } = this;\n    if (!_isComplete) {\n      this._isComplete = true;\n      _hasValue && super.next(_value!);\n      super.complete();\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/BehaviorSubject.ts",
    "content": "import { Subject } from './Subject';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\n\n/**\n * A variant of Subject that requires an initial value and emits its current\n * value whenever it is subscribed to.\n *\n * @class BehaviorSubject<T>\n */\nexport class BehaviorSubject<T> extends Subject<T> {\n  constructor(private _value: T) {\n    super();\n  }\n\n  get value(): T {\n    return this.getValue();\n  }\n\n  /** @internal */\n  protected _subscribe(subscriber: Subscriber<T>): Subscription {\n    const subscription = super._subscribe(subscriber);\n    !subscription.closed && subscriber.next(this._value);\n    return subscription;\n  }\n\n  getValue(): T {\n    const { hasError, thrownError, _value } = this;\n    if (hasError) {\n      throw thrownError;\n    }\n    this._throwIfClosed();\n    return _value;\n  }\n\n  next(value: T): void {\n    super.next((this._value = value));\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/Notification.ts",
    "content": "import { PartialObserver, ObservableNotification, CompleteNotification, NextNotification, ErrorNotification } from './types';\nimport { Observable } from './Observable';\nimport { EMPTY } from './observable/empty';\nimport { of } from './observable/of';\nimport { throwError } from './observable/throwError';\nimport { isFunction } from './util/isFunction';\n\n// TODO: When this enum is removed, replace it with a type alias. See #4556.\n/**\n * @deprecated Use a string literal instead. `NotificationKind` will be replaced with a type alias in v8.\n * It will not be replaced with a const enum as those are not compatible with isolated modules.\n */\nexport enum NotificationKind {\n  NEXT = 'N',\n  ERROR = 'E',\n  COMPLETE = 'C',\n}\n\n/**\n * Represents a push-based event or value that an {@link Observable} can emit.\n * This class is particularly useful for operators that manage notifications,\n * like {@link materialize}, {@link dematerialize}, {@link observeOn}, and\n * others. Besides wrapping the actual delivered value, it also annotates it\n * with metadata of, for instance, what type of push message it is (`next`,\n * `error`, or `complete`).\n *\n * @see {@link materialize}\n * @see {@link dematerialize}\n * @see {@link observeOn}\n * @deprecated It is NOT recommended to create instances of `Notification` directly.\n * Rather, try to create POJOs matching the signature outlined in {@link ObservableNotification}.\n * For example: `{ kind: 'N', value: 1 }`, `{ kind: 'E', error: new Error('bad') }`, or `{ kind: 'C' }`.\n * Will be removed in v8.\n */\nexport class Notification<T> {\n  /**\n   * A value signifying that the notification will \"next\" if observed. In truth,\n   * This is really synonymous with just checking `kind === \"N\"`.\n   * @deprecated Will be removed in v8. Instead, just check to see if the value of `kind` is `\"N\"`.\n   */\n  readonly hasValue: boolean;\n\n  /**\n   * Creates a \"Next\" notification object.\n   * @param kind Always `'N'`\n   * @param value The value to notify with if observed.\n   * @deprecated Internal implementation detail. Use {@link Notification#createNext createNext} instead.\n   */\n  constructor(kind: 'N', value?: T);\n  /**\n   * Creates an \"Error\" notification object.\n   * @param kind Always `'E'`\n   * @param value Always `undefined`\n   * @param error The error to notify with if observed.\n   * @deprecated Internal implementation detail. Use {@link Notification#createError createError} instead.\n   */\n  constructor(kind: 'E', value: undefined, error: any);\n  /**\n   * Creates a \"completion\" notification object.\n   * @param kind Always `'C'`\n   * @deprecated Internal implementation detail. Use {@link Notification#createComplete createComplete} instead.\n   */\n  constructor(kind: 'C');\n  constructor(public readonly kind: 'N' | 'E' | 'C', public readonly value?: T, public readonly error?: any) {\n    this.hasValue = kind === 'N';\n  }\n\n  /**\n   * Executes the appropriate handler on a passed `observer` given the `kind` of notification.\n   * If the handler is missing it will do nothing. Even if the notification is an error, if\n   * there is no error handler on the observer, an error will not be thrown, it will noop.\n   * @param observer The observer to notify.\n   */\n  observe(observer: PartialObserver<T>): void {\n    return observeNotification(this as ObservableNotification<T>, observer);\n  }\n\n  /**\n   * Executes a notification on the appropriate handler from a list provided.\n   * If a handler is missing for the kind of notification, nothing is called\n   * and no error is thrown, it will be a noop.\n   * @param next A next handler\n   * @param error An error handler\n   * @param complete A complete handler\n   * @deprecated Replaced with {@link Notification#observe observe}. Will be removed in v8.\n   */\n  do(next: (value: T) => void, error: (err: any) => void, complete: () => void): void;\n  /**\n   * Executes a notification on the appropriate handler from a list provided.\n   * If a handler is missing for the kind of notification, nothing is called\n   * and no error is thrown, it will be a noop.\n   * @param next A next handler\n   * @param error An error handler\n   * @deprecated Replaced with {@link Notification#observe observe}. Will be removed in v8.\n   */\n  do(next: (value: T) => void, error: (err: any) => void): void;\n  /**\n   * Executes the next handler if the Notification is of `kind` `\"N\"`. Otherwise\n   * this will not error, and it will be a noop.\n   * @param next The next handler\n   * @deprecated Replaced with {@link Notification#observe observe}. Will be removed in v8.\n   */\n  do(next: (value: T) => void): void;\n  do(nextHandler: (value: T) => void, errorHandler?: (err: any) => void, completeHandler?: () => void): void {\n    const { kind, value, error } = this;\n    return kind === 'N' ? nextHandler?.(value!) : kind === 'E' ? errorHandler?.(error) : completeHandler?.();\n  }\n\n  /**\n   * Executes a notification on the appropriate handler from a list provided.\n   * If a handler is missing for the kind of notification, nothing is called\n   * and no error is thrown, it will be a noop.\n   * @param next A next handler\n   * @param error An error handler\n   * @param complete A complete handler\n   * @deprecated Replaced with {@link Notification#observe observe}. Will be removed in v8.\n   */\n  accept(next: (value: T) => void, error: (err: any) => void, complete: () => void): void;\n  /**\n   * Executes a notification on the appropriate handler from a list provided.\n   * If a handler is missing for the kind of notification, nothing is called\n   * and no error is thrown, it will be a noop.\n   * @param next A next handler\n   * @param error An error handler\n   * @deprecated Replaced with {@link Notification#observe observe}. Will be removed in v8.\n   */\n  accept(next: (value: T) => void, error: (err: any) => void): void;\n  /**\n   * Executes the next handler if the Notification is of `kind` `\"N\"`. Otherwise\n   * this will not error, and it will be a noop.\n   * @param next The next handler\n   * @deprecated Replaced with {@link Notification#observe observe}. Will be removed in v8.\n   */\n  accept(next: (value: T) => void): void;\n\n  /**\n   * Executes the appropriate handler on a passed `observer` given the `kind` of notification.\n   * If the handler is missing it will do nothing. Even if the notification is an error, if\n   * there is no error handler on the observer, an error will not be thrown, it will noop.\n   * @param observer The observer to notify.\n   * @deprecated Replaced with {@link Notification#observe observe}. Will be removed in v8.\n   */\n  accept(observer: PartialObserver<T>): void;\n  accept(nextOrObserver: PartialObserver<T> | ((value: T) => void), error?: (err: any) => void, complete?: () => void) {\n    return isFunction((nextOrObserver as any)?.next)\n      ? this.observe(nextOrObserver as PartialObserver<T>)\n      : this.do(nextOrObserver as (value: T) => void, error as any, complete as any);\n  }\n\n  /**\n   * Returns a simple Observable that just delivers the notification represented\n   * by this Notification instance.\n   *\n   * @deprecated Will be removed in v8. To convert a `Notification` to an {@link Observable},\n   * use {@link of} and {@link dematerialize}: `of(notification).pipe(dematerialize())`.\n   */\n  toObservable(): Observable<T> {\n    const { kind, value, error } = this;\n    // Select the observable to return by `kind`\n    const result =\n      kind === 'N'\n        ? // Next kind. Return an observable of that value.\n          of(value!)\n        : //\n        kind === 'E'\n        ? // Error kind. Return an observable that emits the error.\n          throwError(() => error)\n        : //\n        kind === 'C'\n        ? // Completion kind. Kind is \"C\", return an observable that just completes.\n          EMPTY\n        : // Unknown kind, return falsy, so we error below.\n          0;\n    if (!result) {\n      // TODO: consider removing this check. The only way to cause this would be to\n      // use the Notification constructor directly in a way that is not type-safe.\n      // and direct use of the Notification constructor is deprecated.\n      throw new TypeError(`Unexpected notification kind ${kind}`);\n    }\n    return result;\n  }\n\n  private static completeNotification = new Notification('C') as Notification<never> & CompleteNotification;\n  /**\n   * A shortcut to create a Notification instance of the type `next` from a\n   * given value.\n   * @param {T} value The `next` value.\n   * @return {Notification<T>} The \"next\" Notification representing the\n   * argument.\n   * @nocollapse\n   * @deprecated It is NOT recommended to create instances of `Notification` directly.\n   * Rather, try to create POJOs matching the signature outlined in {@link ObservableNotification}.\n   * For example: `{ kind: 'N', value: 1 }`, `{ kind: 'E', error: new Error('bad') }`, or `{ kind: 'C' }`.\n   * Will be removed in v8.\n   */\n  static createNext<T>(value: T) {\n    return new Notification('N', value) as Notification<T> & NextNotification<T>;\n  }\n\n  /**\n   * A shortcut to create a Notification instance of the type `error` from a\n   * given error.\n   * @param {any} [err] The `error` error.\n   * @return {Notification<T>} The \"error\" Notification representing the\n   * argument.\n   * @nocollapse\n   * @deprecated It is NOT recommended to create instances of `Notification` directly.\n   * Rather, try to create POJOs matching the signature outlined in {@link ObservableNotification}.\n   * For example: `{ kind: 'N', value: 1 }`, `{ kind: 'E', error: new Error('bad') }`, or `{ kind: 'C' }`.\n   * Will be removed in v8.\n   */\n  static createError(err?: any) {\n    return new Notification('E', undefined, err) as Notification<never> & ErrorNotification;\n  }\n\n  /**\n   * A shortcut to create a Notification instance of the type `complete`.\n   * @return {Notification<any>} The valueless \"complete\" Notification.\n   * @nocollapse\n   * @deprecated It is NOT recommended to create instances of `Notification` directly.\n   * Rather, try to create POJOs matching the signature outlined in {@link ObservableNotification}.\n   * For example: `{ kind: 'N', value: 1 }`, `{ kind: 'E', error: new Error('bad') }`, or `{ kind: 'C' }`.\n   * Will be removed in v8.\n   */\n  static createComplete(): Notification<never> & CompleteNotification {\n    return Notification.completeNotification;\n  }\n}\n\n/**\n * Executes the appropriate handler on a passed `observer` given the `kind` of notification.\n * If the handler is missing it will do nothing. Even if the notification is an error, if\n * there is no error handler on the observer, an error will not be thrown, it will noop.\n * @param notification The notification object to observe.\n * @param observer The observer to notify.\n */\nexport function observeNotification<T>(notification: ObservableNotification<T>, observer: PartialObserver<T>) {\n  const { kind, value, error } = notification as any;\n  if (typeof kind !== 'string') {\n    throw new TypeError('Invalid notification, missing \"kind\"');\n  }\n  kind === 'N' ? observer.next?.(value!) : kind === 'E' ? observer.error?.(error) : observer.complete?.();\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/NotificationFactories.ts",
    "content": "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n  return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification<T>(value: T) {\n  return createNotification('N', value, undefined) as NextNotification<T>;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n  return {\n    kind,\n    value,\n    error,\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/Observable.ts",
    "content": "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable<T>\n */\nexport class Observable<T> implements Subscribable<T> {\n  /**\n   * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n   */\n  source: Observable<any> | undefined;\n\n  /**\n   * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n   */\n  operator: Operator<any, T> | undefined;\n\n  /**\n   * @constructor\n   * @param {Function} subscribe the function that is called when the Observable is\n   * initially subscribed to. This function is given a Subscriber, to which new values\n   * can be `next`ed, or an `error` method can be called to raise an error, or\n   * `complete` can be called to notify of a successful completion.\n   */\n  constructor(subscribe?: (this: Observable<T>, subscriber: Subscriber<T>) => TeardownLogic) {\n    if (subscribe) {\n      this._subscribe = subscribe;\n    }\n  }\n\n  // HACK: Since TypeScript inherits static properties too, we have to\n  // fight against TypeScript here so Subject can have a different static create signature\n  /**\n   * Creates a new Observable by calling the Observable constructor\n   * @owner Observable\n   * @method create\n   * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n   * @return {Observable} a new observable\n   * @nocollapse\n   * @deprecated Use `new Observable()` instead. Will be removed in v8.\n   */\n  static create: (...args: any[]) => any = <T>(subscribe?: (subscriber: Subscriber<T>) => TeardownLogic) => {\n    return new Observable<T>(subscribe);\n  };\n\n  /**\n   * Creates a new Observable, with this Observable instance as the source, and the passed\n   * operator defined as the new observable's operator.\n   * @method lift\n   * @param operator the operator defining the operation to take on the observable\n   * @return a new observable with the Operator applied\n   * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n   * If you have implemented an operator using `lift`, it is recommended that you create an\n   * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n   * scratch\" section here: https://rxjs.dev/guide/operators\n   */\n  lift<R>(operator?: Operator<T, R>): Observable<R> {\n    const observable = new Observable<R>();\n    observable.source = this;\n    observable.operator = operator;\n    return observable;\n  }\n\n  subscribe(observer?: Partial<Observer<T>>): Subscription;\n  subscribe(next: (value: T) => void): Subscription;\n  /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n  subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n  /**\n   * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n   *\n   * <span class=\"informal\">Use it when you have all these Observables, but still nothing is happening.</span>\n   *\n   * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n   * might be for example a function that you passed to Observable's constructor, but most of the time it is\n   * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n   * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n   * the thought.\n   *\n   * Apart from starting the execution of an Observable, this method allows you to listen for values\n   * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n   * of the following ways.\n   *\n   * The first way is creating an object that implements {@link Observer} interface. It should have methods\n   * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n   * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n   * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n   * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n   * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n   * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n   * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n   * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n   * an `error` method to avoid missing thrown errors.\n   *\n   * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n   * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n   * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n   * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n   * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n   * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n   *\n   * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n   * and you also handled emissions internally by using operators (e.g. using `tap`).\n   *\n   * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n   * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n   * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n   * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n   *\n   * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n   * It is an Observable itself that decides when these functions will be called. For example {@link of}\n   * by default emits all its values synchronously. Always check documentation for how given Observable\n   * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n   *\n   * ## Examples\n   *\n   * Subscribe with an {@link guide/observer Observer}\n   *\n   * ```ts\n   * import { of } from 'valdi_rxjs';\n   *\n   * const sumObserver = {\n   *   sum: 0,\n   *   next(value) {\n   *     console.log('Adding: ' + value);\n   *     this.sum = this.sum + value;\n   *   },\n   *   error() {\n   *     // We actually could just remove this method,\n   *     // since we do not really care about errors right now.\n   *   },\n   *   complete() {\n   *     console.log('Sum equals: ' + this.sum);\n   *   }\n   * };\n   *\n   * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n   *   .subscribe(sumObserver);\n   *\n   * // Logs:\n   * // 'Adding: 1'\n   * // 'Adding: 2'\n   * // 'Adding: 3'\n   * // 'Sum equals: 6'\n   * ```\n   *\n   * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n   *\n   * ```ts\n   * import { of } from 'valdi_rxjs'\n   *\n   * let sum = 0;\n   *\n   * of(1, 2, 3).subscribe(\n   *   value => {\n   *     console.log('Adding: ' + value);\n   *     sum = sum + value;\n   *   },\n   *   undefined,\n   *   () => console.log('Sum equals: ' + sum)\n   * );\n   *\n   * // Logs:\n   * // 'Adding: 1'\n   * // 'Adding: 2'\n   * // 'Adding: 3'\n   * // 'Sum equals: 6'\n   * ```\n   *\n   * Cancel a subscription\n   *\n   * ```ts\n   * import { interval } from 'valdi_rxjs';\n   *\n   * const subscription = interval(1000).subscribe({\n   *   next(num) {\n   *     console.log(num)\n   *   },\n   *   complete() {\n   *     // Will not be called, even when cancelling subscription.\n   *     console.log('completed!');\n   *   }\n   * });\n   *\n   * setTimeout(() => {\n   *   subscription.unsubscribe();\n   *   console.log('unsubscribed!');\n   * }, 2500);\n   *\n   * // Logs:\n   * // 0 after 1s\n   * // 1 after 2s\n   * // 'unsubscribed!' after 2.5s\n   * ```\n   *\n   * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n   * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n   * Observable.\n   * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n   * the error will be thrown asynchronously as unhandled.\n   * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n   * @return {Subscription} a subscription reference to the registered handlers\n   * @method subscribe\n   */\n  subscribe(\n    observerOrNext?: Partial<Observer<T>> | ((value: T) => void) | null,\n    error?: ((error: any) => void) | null,\n    complete?: (() => void) | null\n  ): Subscription {\n    const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n    const { operator, source } = this;\n      subscriber.add(\n        operator\n          ? // We're dealing with a subscription in the\n            // operator chain to one of our lifted operators.\n            operator.call(subscriber, source)\n          : source\n          ? // If `source` has a value, but `operator` does not, something that\n            // had intimate knowledge of our API, like our `Subject`, must have\n            // set it. We're going to just call `_subscribe` directly.\n            this._subscribe(subscriber)\n          : // In all other cases, we're likely wrapping a user-provided initializer\n            // function, so we need to catch errors and handle them appropriately.\n            this._trySubscribe(subscriber)\n      );\n\n    return subscriber;\n  }\n\n  /** @internal */\n  protected _trySubscribe(sink: Subscriber<T>): TeardownLogic {\n    try {\n      return this._subscribe(sink);\n    } catch (err) {\n      // We don't need to return anything in this case,\n      // because it's just going to try to `add()` to a subscription\n      // above.\n      sink.error(err);\n    }\n  }\n\n  /**\n   * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n   * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n   *\n   * **WARNING**: Only use this with observables you *know* will complete. If the source\n   * observable does not complete, you will end up with a promise that is hung up, and\n   * potentially all of the state of an async function hanging out in memory. To avoid\n   * this situation, look into adding something like {@link timeout}, {@link take},\n   * {@link takeWhile}, or {@link takeUntil} amongst others.\n   *\n   * ## Example\n   *\n   * ```ts\n   * import { interval, take } from 'valdi_rxjs';\n   *\n   * const source$ = interval(1000).pipe(take(4));\n   *\n   * async function getTotal() {\n   *   let total = 0;\n   *\n   *   await source$.forEach(value => {\n   *     total += value;\n   *     console.log('observable -> ' + value);\n   *   });\n   *\n   *   return total;\n   * }\n   *\n   * getTotal().then(\n   *   total => console.log('Total: ' + total)\n   * );\n   *\n   * // Expected:\n   * // 'observable -> 0'\n   * // 'observable -> 1'\n   * // 'observable -> 2'\n   * // 'observable -> 3'\n   * // 'Total: 6'\n   * ```\n   *\n   * @param next a handler for each value emitted by the observable\n   * @return a promise that either resolves on observable completion or\n   *  rejects with the handled error\n   */\n  forEach(next: (value: T) => void): Promise<void>;\n\n  /**\n   * @param next a handler for each value emitted by the observable\n   * @param promiseCtor a constructor function used to instantiate the Promise\n   * @return a promise that either resolves on observable completion or\n   *  rejects with the handled error\n   * @deprecated Passing a Promise constructor will no longer be available\n   * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n   * little benefit. If you need this functionality, it is recommended that you either\n   * polyfill Promise, or you create an adapter to convert the returned native promise\n   * to whatever promise implementation you wanted. Will be removed in v8.\n   */\n  forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise<void>;\n\n  forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise<void> {\n    promiseCtor = getPromiseCtor(promiseCtor);\n\n    return new promiseCtor<void>((resolve, reject) => {\n      const subscriber = new SafeSubscriber<T>({\n        next: (value) => {\n          try {\n            next(value);\n          } catch (err) {\n            reject(err);\n            subscriber.unsubscribe();\n          }\n        },\n        error: reject,\n        complete: resolve,\n      });\n      this.subscribe(subscriber);\n    }) as Promise<void>;\n  }\n\n  /** @internal */\n  protected _subscribe(subscriber: Subscriber<any>): TeardownLogic {\n    return this.source?.subscribe(subscriber);\n  }\n\n  /**\n   * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n   * @method Symbol.observable\n   * @return {Observable} this instance of the observable\n   */\n  [Symbol_observable]() {\n    return this;\n  }\n\n  /* tslint:disable:max-line-length */\n  pipe(): Observable<T>;\n  pipe<A>(op1: OperatorFunction<T, A>): Observable<A>;\n  pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;\n  pipe<A, B, C>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>): Observable<C>;\n  pipe<A, B, C, D>(\n    op1: OperatorFunction<T, A>,\n    op2: OperatorFunction<A, B>,\n    op3: OperatorFunction<B, C>,\n    op4: OperatorFunction<C, D>\n  ): Observable<D>;\n  pipe<A, B, C, D, E>(\n    op1: OperatorFunction<T, A>,\n    op2: OperatorFunction<A, B>,\n    op3: OperatorFunction<B, C>,\n    op4: OperatorFunction<C, D>,\n    op5: OperatorFunction<D, E>\n  ): Observable<E>;\n  pipe<A, B, C, D, E, F>(\n    op1: OperatorFunction<T, A>,\n    op2: OperatorFunction<A, B>,\n    op3: OperatorFunction<B, C>,\n    op4: OperatorFunction<C, D>,\n    op5: OperatorFunction<D, E>,\n    op6: OperatorFunction<E, F>\n  ): Observable<F>;\n  pipe<A, B, C, D, E, F, G>(\n    op1: OperatorFunction<T, A>,\n    op2: OperatorFunction<A, B>,\n    op3: OperatorFunction<B, C>,\n    op4: OperatorFunction<C, D>,\n    op5: OperatorFunction<D, E>,\n    op6: OperatorFunction<E, F>,\n    op7: OperatorFunction<F, G>\n  ): Observable<G>;\n  pipe<A, B, C, D, E, F, G, H>(\n    op1: OperatorFunction<T, A>,\n    op2: OperatorFunction<A, B>,\n    op3: OperatorFunction<B, C>,\n    op4: OperatorFunction<C, D>,\n    op5: OperatorFunction<D, E>,\n    op6: OperatorFunction<E, F>,\n    op7: OperatorFunction<F, G>,\n    op8: OperatorFunction<G, H>\n  ): Observable<H>;\n  pipe<A, B, C, D, E, F, G, H, I>(\n    op1: OperatorFunction<T, A>,\n    op2: OperatorFunction<A, B>,\n    op3: OperatorFunction<B, C>,\n    op4: OperatorFunction<C, D>,\n    op5: OperatorFunction<D, E>,\n    op6: OperatorFunction<E, F>,\n    op7: OperatorFunction<F, G>,\n    op8: OperatorFunction<G, H>,\n    op9: OperatorFunction<H, I>\n  ): Observable<I>;\n  pipe<A, B, C, D, E, F, G, H, I>(\n    op1: OperatorFunction<T, A>,\n    op2: OperatorFunction<A, B>,\n    op3: OperatorFunction<B, C>,\n    op4: OperatorFunction<C, D>,\n    op5: OperatorFunction<D, E>,\n    op6: OperatorFunction<E, F>,\n    op7: OperatorFunction<F, G>,\n    op8: OperatorFunction<G, H>,\n    op9: OperatorFunction<H, I>,\n    ...operations: OperatorFunction<any, any>[]\n  ): Observable<unknown>;\n  /* tslint:enable:max-line-length */\n\n  /**\n   * Used to stitch together functional operators into a chain.\n   * @method pipe\n   * @return {Observable} the Observable result of all of the operators having\n   * been called in the order they were passed in.\n   *\n   * ## Example\n   *\n   * ```ts\n   * import { interval, filter, map, scan } from 'valdi_rxjs';\n   *\n   * interval(1000)\n   *   .pipe(\n   *     filter(x => x % 2 === 0),\n   *     map(x => x + x),\n   *     scan((acc, x) => acc + x)\n   *   )\n   *   .subscribe(x => console.log(x));\n   * ```\n   */\n  pipe(...operations: OperatorFunction<any, any>[]): Observable<any> {\n    return pipeFromArray(operations)(this);\n  }\n\n  /* tslint:disable:max-line-length */\n  /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n  toPromise(): Promise<T | undefined>;\n  /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n  toPromise(PromiseCtor: typeof Promise): Promise<T | undefined>;\n  /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n  toPromise(PromiseCtor: PromiseConstructorLike): Promise<T | undefined>;\n  /* tslint:enable:max-line-length */\n\n  /**\n   * Subscribe to this Observable and get a Promise resolving on\n   * `complete` with the last emission (if any).\n   *\n   * **WARNING**: Only use this with observables you *know* will complete. If the source\n   * observable does not complete, you will end up with a promise that is hung up, and\n   * potentially all of the state of an async function hanging out in memory. To avoid\n   * this situation, look into adding something like {@link timeout}, {@link take},\n   * {@link takeWhile}, or {@link takeUntil} amongst others.\n   *\n   * @method toPromise\n   * @param [promiseCtor] a constructor function used to instantiate\n   * the Promise\n   * @return A Promise that resolves with the last value emit, or\n   * rejects on an error. If there were no emissions, Promise\n   * resolves with undefined.\n   * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n   */\n  toPromise(promiseCtor?: PromiseConstructorLike): Promise<T | undefined> {\n    promiseCtor = getPromiseCtor(promiseCtor);\n\n    return new promiseCtor((resolve, reject) => {\n      let value: T | undefined;\n      this.subscribe(\n        (x: T) => (value = x),\n        (err: any) => reject(err),\n        () => resolve(value)\n      );\n    }) as Promise<T | undefined>;\n  }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n  return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver<T>(value: any): value is Observer<T> {\n  return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber<T>(value: any): value is Subscriber<T> {\n  return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/Operator.ts",
    "content": "import { Subscriber } from './Subscriber';\nimport { TeardownLogic } from './types';\n\n/***\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\nexport interface Operator<T, R> {\n  call(subscriber: Subscriber<R>, source: any): TeardownLogic;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/ReplaySubject.ts",
    "content": "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple fo exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject<T> extends Subject<T> {\n  private _buffer: (T | number)[] = [];\n  private _infiniteTimeWindow = true;\n\n  /**\n   * @param bufferSize The size of the buffer to replay on subscription\n   * @param windowTime The amount of time the buffered items will say buffered\n   * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n   * calculate the amount of time something has been buffered.\n   */\n  constructor(\n    private _bufferSize = Infinity,\n    private _windowTime = Infinity,\n    private _timestampProvider: TimestampProvider = dateTimestampProvider\n  ) {\n    super();\n    this._infiniteTimeWindow = _windowTime === Infinity;\n    this._bufferSize = Math.max(1, _bufferSize);\n    this._windowTime = Math.max(1, _windowTime);\n  }\n\n  next(value: T): void {\n    const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n    if (!isStopped) {\n      _buffer.push(value);\n      !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n    }\n    this._trimBuffer();\n    super.next(value);\n  }\n\n  /** @internal */\n  protected _subscribe(subscriber: Subscriber<T>): Subscription {\n    this._throwIfClosed();\n    this._trimBuffer();\n\n    const subscription = this._innerSubscribe(subscriber);\n\n    const { _infiniteTimeWindow, _buffer } = this;\n    // We use a copy here, so reentrant code does not mutate our array while we're\n    // emitting it to a new subscriber.\n    const copy = _buffer.slice();\n    for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n      subscriber.next(copy[i] as T);\n    }\n\n    this._checkFinalizedStatuses(subscriber);\n\n    return subscription;\n  }\n\n  private _trimBuffer() {\n    const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n    // If we don't have an infinite buffer size, and we're over the length,\n    // use splice to truncate the old buffer values off. Note that we have to\n    // double the size for instances where we're not using an infinite time window\n    // because we're storing the values and the timestamps in the same array.\n    const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n    _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n    // Now, if we're not in an infinite time window, remove all values where the time is\n    // older than what is allowed.\n    if (!_infiniteTimeWindow) {\n      const now = _timestampProvider.now();\n      let last = 0;\n      // Search the array for the first timestamp that isn't expired and\n      // truncate the buffer up to that point.\n      for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n        last = i;\n      }\n      last && _buffer.splice(0, last + 1);\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/Scheduler.ts",
    "content": "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n *   now(): number;\n *   schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n  public static now: () => number = dateTimestampProvider.now;\n\n  constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n    this.now = now;\n  }\n\n  /**\n   * A getter method that returns a number representing the current time\n   * (at the time this function was called) according to the scheduler's own\n   * internal clock.\n   * @return {number} A number that represents the current time. May or may not\n   * have a relation to wall-clock time. May or may not refer to a time unit\n   * (e.g. milliseconds).\n   */\n  public now: () => number;\n\n  /**\n   * Schedules a function, `work`, for execution. May happen at some point in\n   * the future, according to the `delay` parameter, if specified. May be passed\n   * some context object, `state`, which will be passed to the `work` function.\n   *\n   * The given arguments will be processed an stored as an Action object in a\n   * queue of actions.\n   *\n   * @param {function(state: ?T): ?Subscription} work A function representing a\n   * task, or some unit of work to be executed by the Scheduler.\n   * @param {number} [delay] Time to wait before executing the work, where the\n   * time unit is implicit and defined by the Scheduler itself.\n   * @param {T} [state] Some contextual data that the `work` function uses when\n   * called by the Scheduler.\n   * @return {Subscription} A subscription in order to be able to unsubscribe\n   * the scheduled work.\n   */\n  public schedule<T>(work: (this: SchedulerAction<T>, state?: T) => void, delay: number = 0, state?: T): Subscription {\n    return new this.schedulerActionCtor<T>(this, work).schedule(state, delay);\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/Subject.ts",
    "content": "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject<T> extends Observable<T> implements SubscriptionLike {\n  closed = false;\n\n  private currentObservers: Observer<T>[] | null = null;\n\n  /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n  observers: Observer<T>[] = [];\n  /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n  isStopped = false;\n  /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n  hasError = false;\n  /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n  thrownError: any = null;\n\n  /**\n   * Creates a \"subject\" by basically gluing an observer to an observable.\n   *\n   * @nocollapse\n   * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n   */\n  static create: (...args: any[]) => any = <T>(destination: Observer<T>, source: Observable<T>): AnonymousSubject<T> => {\n    return new AnonymousSubject<T>(destination, source);\n  };\n\n  constructor() {\n    // NOTE: This must be here to obscure Observable's constructor.\n    super();\n  }\n\n  /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n  lift<R>(operator: Operator<T, R>): Observable<R> {\n    const subject = new AnonymousSubject(this, this);\n    subject.operator = operator as any;\n    return subject as any;\n  }\n\n  /** @internal */\n  protected _throwIfClosed() {\n    if (this.closed) {\n      throw new ObjectUnsubscribedError();\n    }\n  }\n\n  next(value: T) {\n      this._throwIfClosed();\n      if (!this.isStopped) {\n        if (!this.currentObservers) {\n          this.currentObservers = Array.from(this.observers);\n        }\n        for (const observer of this.currentObservers) {\n          observer.next(value);\n        }\n      }\n  }\n\n  error(err: any) {\n      this._throwIfClosed();\n      if (!this.isStopped) {\n        this.hasError = this.isStopped = true;\n        this.thrownError = err;\n        const { observers } = this;\n        while (observers.length) {\n          observers.shift()!.error(err);\n        }\n      }\n  }\n\n  complete() {\n      this._throwIfClosed();\n      if (!this.isStopped) {\n        this.isStopped = true;\n        const { observers } = this;\n        while (observers.length) {\n          observers.shift()!.complete();\n        }\n      }\n  }\n\n  unsubscribe() {\n    this.isStopped = this.closed = true;\n    this.observers = this.currentObservers = null!;\n  }\n\n  get observed() {\n    return this.observers?.length > 0;\n  }\n\n  /** @internal */\n  protected _trySubscribe(subscriber: Subscriber<T>): TeardownLogic {\n    this._throwIfClosed();\n    return super._trySubscribe(subscriber);\n  }\n\n  /** @internal */\n  protected _subscribe(subscriber: Subscriber<T>): Subscription {\n    this._throwIfClosed();\n    this._checkFinalizedStatuses(subscriber);\n    return this._innerSubscribe(subscriber);\n  }\n\n  /** @internal */\n  protected _innerSubscribe(subscriber: Subscriber<any>) {\n    const { hasError, isStopped, observers } = this;\n    if (hasError || isStopped) {\n      return EMPTY_SUBSCRIPTION;\n    }\n    this.currentObservers = null;\n    observers.push(subscriber);\n    return new Subscription(() => {\n      this.currentObservers = null;\n      arrRemove(observers, subscriber);\n    });\n  }\n\n  /** @internal */\n  protected _checkFinalizedStatuses(subscriber: Subscriber<any>) {\n    const { hasError, thrownError, isStopped } = this;\n    if (hasError) {\n      subscriber.error(thrownError);\n    } else if (isStopped) {\n      subscriber.complete();\n    }\n  }\n\n  /**\n   * Creates a new Observable with this Subject as the source. You can do this\n   * to create customize Observer-side logic of the Subject and conceal it from\n   * code that uses the Observable.\n   * @return {Observable} Observable that the Subject casts to\n   */\n  asObservable(): Observable<T> {\n    const observable: any = new Observable<T>();\n    observable.source = this;\n    return observable;\n  }\n}\n\n/**\n * @class AnonymousSubject<T>\n */\nexport class AnonymousSubject<T> extends Subject<T> {\n  constructor(\n    /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n    public destination?: Observer<T>,\n    source?: Observable<T>\n  ) {\n    super();\n    this.source = source;\n  }\n\n  next(value: T) {\n    this.destination?.next?.(value);\n  }\n\n  error(err: any) {\n    this.destination?.error?.(err);\n  }\n\n  complete() {\n    this.destination?.complete?.();\n  }\n\n  /** @internal */\n  protected _subscribe(subscriber: Subscriber<T>): Subscription {\n    return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/Subscriber.ts",
    "content": "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber<T>\n */\nexport class Subscriber<T> extends Subscription implements Observer<T> {\n  /**\n   * A static factory for a Subscriber, given a (potentially partial) definition\n   * of an Observer.\n   * @param next The `next` callback of an Observer.\n   * @param error The `error` callback of an\n   * Observer.\n   * @param complete The `complete` callback of an\n   * Observer.\n   * @return A Subscriber wrapping the (partially defined)\n   * Observer represented by the given arguments.\n   * @nocollapse\n   * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n   * method, and there is no reason to be creating instances of `Subscriber` directly.\n   * If you have a specific use case, please file an issue.\n   */\n  static create<T>(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber<T> {\n    return new SafeSubscriber(next, error, complete);\n  }\n\n  /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n  protected isStopped: boolean = false;\n  /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n  protected destination: Subscriber<any> | Observer<any>; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n  /**\n   * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n   * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n   */\n  constructor(destination?: Subscriber<any> | Observer<any>) {\n    super();\n    if (destination) {\n      this.destination = destination;\n      // Automatically chain subscriptions together here.\n      // if destination is a Subscription, then it is a Subscriber.\n      if (isSubscription(destination)) {\n        destination.add(this);\n      }\n    } else {\n      this.destination = EMPTY_OBSERVER;\n    }\n  }\n\n  /**\n   * The {@link Observer} callback to receive notifications of type `next` from\n   * the Observable, with a value. The Observable may call this method 0 or more\n   * times.\n   * @param {T} [value] The `next` value.\n   * @return {void}\n   */\n  next(value?: T): void {\n    if (this.isStopped) {\n      handleStoppedNotification(nextNotification(value), this);\n    } else {\n      this._next(value!);\n    }\n  }\n\n  /**\n   * The {@link Observer} callback to receive notifications of type `error` from\n   * the Observable, with an attached `Error`. Notifies the Observer that\n   * the Observable has experienced an error condition.\n   * @param {any} [err] The `error` exception.\n   * @return {void}\n   */\n  error(err?: any): void {\n    if (this.isStopped) {\n      handleStoppedNotification(errorNotification(err), this);\n    } else {\n      this.isStopped = true;\n      this._error(err);\n    }\n  }\n\n  /**\n   * The {@link Observer} callback to receive a valueless notification of type\n   * `complete` from the Observable. Notifies the Observer that the Observable\n   * has finished sending push-based notifications.\n   * @return {void}\n   */\n  complete(): void {\n    if (this.isStopped) {\n      handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n    } else {\n      this.isStopped = true;\n      this._complete();\n    }\n  }\n\n  unsubscribe(): void {\n    if (!this.closed) {\n      this.isStopped = true;\n      super.unsubscribe();\n      this.destination = null!;\n    }\n  }\n\n  protected _next(value: T): void {\n    this.destination.next(value);\n  }\n\n  protected _error(err: any): void {\n    try {\n      this.destination.error(err);\n    } finally {\n      this.unsubscribe();\n    }\n  }\n\n  protected _complete(): void {\n    try {\n      this.destination.complete();\n    } finally {\n      this.unsubscribe();\n    }\n  }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind<Fn extends (...args: any[]) => any>(fn: Fn, thisArg: any): Fn {\n  return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver<T> implements Observer<T> {\n  constructor(private partialObserver: Partial<Observer<T>>) {}\n\n  next(value: T): void {\n    const { partialObserver } = this;\n    if (partialObserver.next) {\n      try {\n        partialObserver.next(value);\n      } catch (error) {\n        handleUnhandledError(error);\n      }\n    }\n  }\n\n  error(err: any): void {\n    const { partialObserver } = this;\n    if (partialObserver.error) {\n      try {\n        partialObserver.error(err);\n      } catch (error) {\n        handleUnhandledError(error);\n      }\n    } else {\n      handleUnhandledError(err);\n    }\n  }\n\n  complete(): void {\n    const { partialObserver } = this;\n    if (partialObserver.complete) {\n      try {\n        partialObserver.complete();\n      } catch (error) {\n        handleUnhandledError(error);\n      }\n    }\n  }\n}\n\nexport class SafeSubscriber<T> extends Subscriber<T> {\n  constructor(\n    observerOrNext?: Partial<Observer<T>> | ((value: T) => void) | null,\n    error?: ((e?: any) => void) | null,\n    complete?: (() => void) | null\n  ) {\n    super();\n\n    let partialObserver: Partial<Observer<T>>;\n    if (isFunction(observerOrNext) || !observerOrNext) {\n      // The first argument is a function, not an observer. The next\n      // two arguments *could* be observers, or they could be empty.\n      partialObserver = {\n        next: observerOrNext ?? undefined,\n        error: error ?? undefined,\n        complete: complete ?? undefined,\n      };\n    } else {\n      // The first argument is a partial observer.\n      let context: any;\n      if (this && config.useDeprecatedNextContext) {\n        // This is a deprecated path that made `this.unsubscribe()` available in\n        // next handler functions passed to subscribe. This only exists behind a flag\n        // now, as it is *very* slow.\n        context = Object.create(observerOrNext);\n        context.unsubscribe = () => this.unsubscribe();\n        partialObserver = {\n          next: observerOrNext.next && bind(observerOrNext.next, context),\n          error: observerOrNext.error && bind(observerOrNext.error, context),\n          complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n        };\n      } else {\n        // The \"normal\" path. Just use the partial observer directly.\n        partialObserver = observerOrNext;\n      }\n    }\n\n    // Wrap the partial observer to ensure it's a full observer, and\n    // make sure proper error handling is accounted for.\n    this.destination = new ConsumerObserver(partialObserver);\n  }\n}\n\nfunction handleUnhandledError(error: any) {\n  if (config.useDeprecatedSynchronousErrorHandling) {\n    captureError(error);\n  } else {\n    // Ideal path, we report this as an unhandled error,\n    // which is thrown on a new call stack.\n    reportUnhandledError(error);\n  }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n  throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification<any>, subscriber: Subscriber<any>) {\n  const { onStoppedNotification } = config;\n  onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly<Observer<any>> & { closed: true } = {\n  closed: true,\n  next: noop,\n  error: defaultErrorHandler,\n  complete: noop,\n};\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/Subscription.ts",
    "content": "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n  /** @nocollapse */\n  public static EMPTY = (() => {\n    const empty = new Subscription();\n    empty.closed = true;\n    return empty;\n  })();\n\n  /**\n   * A flag to indicate whether this Subscription has already been unsubscribed.\n   */\n  public closed = false;\n\n  private _parentage: Subscription[] | Subscription | null = null;\n\n  /**\n   * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n   * list occurs in the {@link #add} and {@link #remove} methods.\n   */\n  private _finalizers: Exclude<TeardownLogic, void>[] | null = null;\n\n  /**\n   * @param initialTeardown A function executed first as part of the finalization\n   * process that is kicked off when {@link #unsubscribe} is called.\n   */\n  constructor(private initialTeardown?: () => void) {}\n\n  /**\n   * Disposes the resources held by the subscription. May, for instance, cancel\n   * an ongoing Observable execution or cancel any other type of work that\n   * started when the Subscription was created.\n   * @return {void}\n   */\n  unsubscribe(): void {\n    let errors: any[] | undefined;\n\n    if (!this.closed) {\n      this.closed = true;\n\n      // Remove this from it's parents.\n      const { _parentage } = this;\n      if (_parentage) {\n        this._parentage = null;\n        if (Array.isArray(_parentage)) {\n          for (const parent of _parentage) {\n            parent.remove(this);\n          }\n        } else {\n          _parentage.remove(this);\n        }\n      }\n\n      const { initialTeardown: initialFinalizer } = this;\n      if (isFunction(initialFinalizer)) {\n        try {\n          initialFinalizer();\n        } catch (e) {\n          errors = e instanceof UnsubscriptionError ? e.errors : [e];\n        }\n      }\n\n      const { _finalizers } = this;\n      if (_finalizers) {\n        this._finalizers = null;\n        for (const finalizer of _finalizers) {\n          try {\n            execFinalizer(finalizer);\n          } catch (err) {\n            errors = errors ?? [];\n            if (err instanceof UnsubscriptionError) {\n              errors = [...errors, ...err.errors];\n            } else {\n              errors.push(err);\n            }\n          }\n        }\n      }\n\n      if (errors) {\n        throw new UnsubscriptionError(errors);\n      }\n    }\n  }\n\n  /**\n   * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n   * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n   * because it has already been unsubscribed, then whatever finalizer is passed to it\n   * will automatically be executed (unless the finalizer itself is also a closed subscription).\n   *\n   * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n   * subscription to a any subscription will result in no operation. (A noop).\n   *\n   * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n   * operation at all. (A noop).\n   *\n   * `Subscription` instances that are added to this instance will automatically remove themselves\n   * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n   * will need to be removed manually with {@link #remove}\n   *\n   * @param teardown The finalization logic to add to this subscription.\n   */\n  add(teardown: TeardownLogic): void {\n    // Only add the finalizer if it's not undefined\n    // and don't add a subscription to itself.\n    if (teardown && teardown !== this) {\n      if (this.closed) {\n        // If this subscription is already closed,\n        // execute whatever finalizer is handed to it automatically.\n        execFinalizer(teardown);\n      } else {\n        if (teardown instanceof Subscription) {\n          // We don't add closed subscriptions, and we don't add the same subscription\n          // twice. Subscription unsubscribe is idempotent.\n          if (teardown.closed || teardown._hasParent(this)) {\n            return;\n          }\n          teardown._addParent(this);\n        }\n        (this._finalizers = this._finalizers ?? []).push(teardown);\n      }\n    }\n  }\n\n  /**\n   * Checks to see if a this subscription already has a particular parent.\n   * This will signal that this subscription has already been added to the parent in question.\n   * @param parent the parent to check for\n   */\n  private _hasParent(parent: Subscription) {\n    const { _parentage } = this;\n    return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n  }\n\n  /**\n   * Adds a parent to this subscription so it can be removed from the parent if it\n   * unsubscribes on it's own.\n   *\n   * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n   * @param parent The parent subscription to add\n   */\n  private _addParent(parent: Subscription) {\n    const { _parentage } = this;\n    this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n  }\n\n  /**\n   * Called on a child when it is removed via {@link #remove}.\n   * @param parent The parent to remove\n   */\n  private _removeParent(parent: Subscription) {\n    const { _parentage } = this;\n    if (_parentage === parent) {\n      this._parentage = null;\n    } else if (Array.isArray(_parentage)) {\n      arrRemove(_parentage, parent);\n    }\n  }\n\n  /**\n   * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n   *\n   * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n   * from every other `Subscription` they have been added to. This means that using the `remove` method\n   * is not a common thing and should be used thoughtfully.\n   *\n   * If you add the same finalizer instance of a function or an unsubscribable object to a `Subcription` instance\n   * more than once, you will need to call `remove` the same number of times to remove all instances.\n   *\n   * All finalizer instances are removed to free up memory upon unsubscription.\n   *\n   * @param teardown The finalizer to remove from this subscription\n   */\n  remove(teardown: Exclude<TeardownLogic, void>): void {\n    const { _finalizers } = this;\n    _finalizers && arrRemove(_finalizers, teardown);\n\n    if (teardown instanceof Subscription) {\n      teardown._removeParent(this);\n    }\n  }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n  return (\n    value instanceof Subscription ||\n    (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n  );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n  if (isFunction(finalizer)) {\n    finalizer();\n  } else {\n    finalizer.unsubscribe();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/config.ts",
    "content": "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n  onUnhandledError: null,\n  onStoppedNotification: null,\n  Promise: undefined,\n  useDeprecatedSynchronousErrorHandling: false,\n  useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n  /**\n   * A registration point for unhandled errors from RxJS. These are errors that\n   * cannot were not handled by consuming code in the usual subscription path. For\n   * example, if you have this configured, and you subscribe to an observable without\n   * providing an error handler, errors from that subscription will end up here. This\n   * will _always_ be called asynchronously on another job in the runtime. This is because\n   * we do not want errors thrown in this user-configured handler to interfere with the\n   * behavior of the library.\n   */\n  onUnhandledError: ((err: any) => void) | null;\n\n  /**\n   * A registration point for notifications that cannot be sent to subscribers because they\n   * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n   * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n   * might want a different behavior. For example, with sources that attempt to report errors\n   * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n   * This will _always_ be called asynchronously on another job in the runtime. This is because\n   * we do not want errors thrown in this user-configured handler to interfere with the\n   * behavior of the library.\n   */\n  onStoppedNotification: ((notification: ObservableNotification<any>, subscriber: Subscriber<any>) => void) | null;\n\n  /**\n   * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n   * methods.\n   *\n   * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n   * Promise constructor. If you need a Promise implementation other than native promises,\n   * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n   */\n  Promise?: PromiseConstructorLike;\n\n  /**\n   * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n   * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n   * call in a try/catch block. It also enables producer interference, a nasty bug\n   * where a multicast can be broken for all observers by a downstream consumer with\n   * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n   * FOR MIGRATION REASONS.\n   *\n   * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n   * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n   * behaviors described above. Will be removed in v8.\n   */\n  useDeprecatedSynchronousErrorHandling: boolean;\n\n  /**\n   * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n   * `unsubscribe()` via `this` context in `next` functions created in observers passed\n   * to `subscribe`.\n   *\n   * This is being removed because the performance was severely problematic, and it could also cause\n   * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n   * their `this` context overwritten.\n   *\n   * @deprecated As of version 8, RxJS will no longer support altering the\n   * context of next functions provided as part of an observer to Subscribe. Instead,\n   * you will have access to a subscription or a signal or token that will allow you to do things like\n   * unsubscribe and test closed status. Will be removed in v8.\n   */\n  useDeprecatedNextContext: boolean;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/firstValueFrom.ts",
    "content": "import { Observable } from './Observable';\nimport { EmptyError } from './util/EmptyError';\nimport { SafeSubscriber } from './Subscriber';\n\nexport interface FirstValueFromConfig<T> {\n  defaultValue: T;\n}\n\nexport function firstValueFrom<T, D>(source: Observable<T>, config: FirstValueFromConfig<D>): Promise<T | D>;\nexport function firstValueFrom<T>(source: Observable<T>): Promise<T>;\n\n/**\n * Converts an observable to a promise by subscribing to the observable,\n * and returning a promise that will resolve as soon as the first value\n * arrives from the observable. The subscription will then be closed.\n *\n * If the observable stream completes before any values were emitted, the\n * returned promise will reject with {@link EmptyError} or will resolve\n * with the default value if a default was specified.\n *\n * If the observable stream emits an error, the returned promise will reject\n * with that error.\n *\n * **WARNING**: Only use this with observables you *know* will emit at least one value,\n * *OR* complete. If the source observable does not emit one value or complete, you will\n * end up with a promise that is hung up, and potentially all of the state of an\n * async function hanging out in memory. To avoid this situation, look into adding\n * something like {@link timeout}, {@link take}, {@link takeWhile}, or {@link takeUntil}\n * amongst others.\n *\n * ## Example\n *\n * Wait for the first value from a stream and emit it from a promise in\n * an async function\n *\n * ```ts\n * import { interval, firstValueFrom } from 'valdi_rxjs';\n *\n * async function execute() {\n *   const source$ = interval(2000);\n *   const firstNumber = await firstValueFrom(source$);\n *   console.log(`The first number is ${ firstNumber }`);\n * }\n *\n * execute();\n *\n * // Expected output:\n * // 'The first number is 0'\n * ```\n *\n * @see {@link lastValueFrom}\n *\n * @param source the observable to convert to a promise\n * @param config a configuration object to define the `defaultValue` to use if the source completes without emitting a value\n */\nexport function firstValueFrom<T, D>(source: Observable<T>, config?: FirstValueFromConfig<D>): Promise<T | D> {\n  const hasConfig = typeof config === 'object';\n  return new Promise<T | D>((resolve, reject) => {\n    const subscriber = new SafeSubscriber<T>({\n      next: (value) => {\n        resolve(value);\n        subscriber.unsubscribe();\n      },\n      error: reject,\n      complete: () => {\n        if (hasConfig) {\n          resolve(config!.defaultValue);\n        } else {\n          reject(new EmptyError());\n        }\n      },\n    });\n    source.subscribe(subscriber);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/firstValueWhere.ts",
    "content": "import { Observable } from './Observable';\nimport { EmptyError } from './util/EmptyError';\nimport { SafeSubscriber } from './Subscriber';\nimport { filter } from './operators/filter';\nimport { firstValueFrom } from './firstValueFrom';\nimport { timeout } from './operators/timeout';\n\nexport function firstValueWhere<T>(source: Observable<T>, predicate: (value: T) => boolean, timeoutMs?: number): Promise<T>;\n\n/**\n * Converts an observable to a promise by subscribing to the observable,\n * and returning a promise that will resolve as soon as the first value\n * that satisfies the provided predicate arrives from the observable. \n * The subscription will then be closed.\n *\n * The function filters the observable stream using the provided predicate\n * function and returns a promise that resolves with the first emitted value\n * that passes the predicate test. A timeout can be specified to prevent\n * the promise from hanging indefinitely.\n *\n * If the observable stream completes before any values that satisfy the \n * predicate were emitted, the returned promise will reject with {@link EmptyError}.\n *\n * If the specified timeout is reached before a value that satisfies the\n * predicate is emitted, the returned promise will reject with a timeout error.\n *\n * If the observable stream emits an error, the returned promise will reject\n * with that error.\n *\n * **WARNING**: Only use this with observables you *know* will emit at least one value\n * that satisfies the predicate, *OR* complete, within the specified timeout period. \n * If the source observable does not emit a value that passes the predicate test, \n * complete, or timeout, you will end up with a promise that is hung up, and potentially \n * all of the state of an async function hanging out in memory.\n *\n * ## Example\n *\n * Wait for the first odd number from a stream and emit it from a promise in\n * an async function\n *\n * ```ts\n * import { interval, firstValueWhere } from 'valdi_rxjs';\n *\n * async function execute() {\n *   const source$ = interval(1000); // emits 0, 1, 2, 3, 4, ...\n *   const firstOddNumber = await firstValueWhere(source$, x => x % 2 === 1, 5000);\n *   console.log(`The first odd number is ${ firstOddNumber }`);\n * }\n *\n * execute();\n *\n * // Expected output:\n * // 'The first odd number is 1'\n * ```\n *\n * @see {@link firstValueFrom}\n * @see {@link filter}\n * @see {@link timeout}\n *\n * @param source the observable to convert to a promise\n * @param predicate a function that takes a value and returns true if the value should be emitted\n * @param timeoutMs the timeout in milliseconds after which the promise will reject if no matching value is found\n */\nexport function firstValueWhere<T>(source: Observable<T>, predicate: (value: T) => boolean, timeoutMs?: number): Promise<T> {\n  if (timeoutMs !== undefined) {\n    return firstValueFrom(source.pipe(filter(predicate), timeout(timeoutMs)));\n  }\n  return firstValueFrom(source.pipe(filter(predicate)));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/index.ts",
    "content": "/* Observable */\nexport { Observable } from './Observable';\n\n/* Subjects */\nexport { Subject } from './Subject';\nexport { BehaviorSubject } from './BehaviorSubject';\nexport { ReplaySubject } from './ReplaySubject';\n\n/* Subscription */\nexport { Subscription } from './Subscription';\nexport { Subscriber } from './Subscriber';\n\n/* Utils */\nexport { pipe } from './util/pipe';\nexport { firstValueFrom } from './firstValueFrom';\nexport { share } from './operators/share';\nexport { shareReplay } from './operators/shareReplay';\nexport { skip } from './operators/skip';\n\nexport { map } from './operators/map';\nexport { tap } from './operators/tap';\nexport { filter } from './operators/filter';\nexport { switchMap } from './operators/switchMap';\nexport { distinctUntilChanged } from './operators/distinctUntilChanged';\n\nexport { combineLatest } from './observable/combineLatest';\nexport { of } from './observable/of';\nexport { catchError } from './operators/catchError';\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/lastValueFrom.ts",
    "content": "import { Observable } from './Observable';\nimport { EmptyError } from './util/EmptyError';\n\nexport interface LastValueFromConfig<T> {\n  defaultValue: T;\n}\n\nexport function lastValueFrom<T, D>(source: Observable<T>, config: LastValueFromConfig<D>): Promise<T | D>;\nexport function lastValueFrom<T>(source: Observable<T>): Promise<T>;\n\n/**\n * Converts an observable to a promise by subscribing to the observable,\n * waiting for it to complete, and resolving the returned promise with the\n * last value from the observed stream.\n *\n * If the observable stream completes before any values were emitted, the\n * returned promise will reject with {@link EmptyError} or will resolve\n * with the default value if a default was specified.\n *\n * If the observable stream emits an error, the returned promise will reject\n * with that error.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * ## Example\n *\n * Wait for the last value from a stream and emit it from a promise in\n * an async function\n *\n * ```ts\n * import { interval, take, lastValueFrom } from 'valdi_rxjs';\n *\n * async function execute() {\n *   const source$ = interval(2000).pipe(take(10));\n *   const finalNumber = await lastValueFrom(source$);\n *   console.log(`The final number is ${ finalNumber }`);\n * }\n *\n * execute();\n *\n * // Expected output:\n * // 'The final number is 9'\n * ```\n *\n * @see {@link firstValueFrom}\n *\n * @param source the observable to convert to a promise\n * @param config a configuration object to define the `defaultValue` to use if the source completes without emitting a value\n */\nexport function lastValueFrom<T, D>(source: Observable<T>, config?: LastValueFromConfig<D>): Promise<T | D> {\n  const hasConfig = typeof config === 'object';\n  return new Promise<T | D>((resolve, reject) => {\n    let _hasValue = false;\n    let _value: T;\n    source.subscribe({\n      next: (value) => {\n        _value = value;\n        _hasValue = true;\n      },\n      error: reject,\n      complete: () => {\n        if (_hasValue) {\n          resolve(_value);\n        } else if (hasConfig) {\n          resolve(config!.defaultValue);\n        } else {\n          reject(new EmptyError());\n        }\n      },\n    });\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/ConnectableObservable.ts",
    "content": "import { Subject } from '../Subject';\nimport { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { Subscription } from '../Subscription';\nimport { refCount as higherOrderRefCount } from '../operators/refCount';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { hasLift } from '../util/lift';\n\n/**\n * @class ConnectableObservable<T>\n * @deprecated Will be removed in v8. Use {@link connectable} to create a connectable observable.\n * If you are using the `refCount` method of `ConnectableObservable`, use the {@link share} operator\n * instead.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport class ConnectableObservable<T> extends Observable<T> {\n  protected _subject: Subject<T> | null = null;\n  protected _refCount: number = 0;\n  protected _connection: Subscription | null = null;\n\n  /**\n   * @param source The source observable\n   * @param subjectFactory The factory that creates the subject used internally.\n   * @deprecated Will be removed in v8. Use {@link connectable} to create a connectable observable.\n   * `new ConnectableObservable(source, factory)` is equivalent to\n   * `connectable(source, { connector: factory })`.\n   * When the `refCount()` method is needed, the {@link share} operator should be used instead:\n   * `new ConnectableObservable(source, factory).refCount()` is equivalent to\n   * `source.pipe(share({ connector: factory }))`.\n   * Details: https://rxjs.dev/deprecations/multicasting\n   */\n  constructor(public source: Observable<T>, protected subjectFactory: () => Subject<T>) {\n    super();\n    // If we have lift, monkey patch that here. This is done so custom observable\n    // types will compose through multicast. Otherwise the resulting observable would\n    // simply be an instance of `ConnectableObservable`.\n    if (hasLift(source)) {\n      this.lift = source.lift;\n    }\n  }\n\n  /** @internal */\n  protected _subscribe(subscriber: Subscriber<T>) {\n    return this.getSubject().subscribe(subscriber);\n  }\n\n  protected getSubject(): Subject<T> {\n    const subject = this._subject;\n    if (!subject || subject.isStopped) {\n      this._subject = this.subjectFactory();\n    }\n    return this._subject!;\n  }\n\n  protected _teardown() {\n    this._refCount = 0;\n    const { _connection } = this;\n    this._subject = this._connection = null;\n    _connection?.unsubscribe();\n  }\n\n  /**\n   * @deprecated {@link ConnectableObservable} will be removed in v8. Use {@link connectable} instead.\n   * Details: https://rxjs.dev/deprecations/multicasting\n   */\n  connect(): Subscription {\n    let connection = this._connection;\n    if (!connection) {\n      connection = this._connection = new Subscription();\n      const subject = this.getSubject();\n      connection.add(\n        this.source.subscribe(\n          createOperatorSubscriber(\n            subject as any,\n            undefined,\n            () => {\n              this._teardown();\n              subject.complete();\n            },\n            (err) => {\n              this._teardown();\n              subject.error(err);\n            },\n            () => this._teardown()\n          )\n        )\n      );\n\n      if (connection.closed) {\n        this._connection = null;\n        connection = Subscription.EMPTY;\n      }\n    }\n    return connection;\n  }\n\n  /**\n   * @deprecated {@link ConnectableObservable} will be removed in v8. Use the {@link share} operator instead.\n   * Details: https://rxjs.dev/deprecations/multicasting\n   */\n  refCount(): Observable<T> {\n    return higherOrderRefCount()(this) as Observable<T>;\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/bindCallback.ts",
    "content": "/* @prettier */\nimport { SchedulerLike } from '../types';\nimport { Observable } from '../Observable';\nimport { bindCallbackInternals } from './bindCallbackInternals';\n\nexport function bindCallback(\n  callbackFunc: (...args: any[]) => void,\n  resultSelector: (...args: any[]) => any,\n  scheduler?: SchedulerLike\n): (...args: any[]) => Observable<any>;\n\n// args is the arguments array and we push the callback on the rest tuple since the rest parameter must be last (only item) in a parameter list\nexport function bindCallback<A extends readonly unknown[], R extends readonly unknown[]>(\n  callbackFunc: (...args: [...A, (...res: R) => void]) => void,\n  schedulerLike?: SchedulerLike\n): (...arg: A) => Observable<R extends [] ? void : R extends [any] ? R[0] : R>;\n\n/**\n * Converts a callback API to a function that returns an Observable.\n *\n * <span class=\"informal\">Give it a function `f` of type `f(x, callback)` and\n * it will return a function `g` that when called as `g(x)` will output an\n * Observable.</span>\n *\n * `bindCallback` is not an operator because its input and output are not\n * Observables. The input is a function `func` with some parameters. The\n * last parameter must be a callback function that `func` calls when it is\n * done.\n *\n * The output of `bindCallback` is a function that takes the same parameters\n * as `func`, except the last one (the callback). When the output function\n * is called with arguments it will return an Observable. If function `func`\n * calls its callback with one argument, the Observable will emit that value.\n * If on the other hand the callback is called with multiple values the resulting\n * Observable will emit an array with said values as arguments.\n *\n * It is **very important** to remember that input function `func` is not called\n * when the output function is, but rather when the Observable returned by the output\n * function is subscribed. This means if `func` makes an AJAX request, that request\n * will be made every time someone subscribes to the resulting Observable, but not before.\n *\n * The last optional parameter - `scheduler` - can be used to control when the call\n * to `func` happens after someone subscribes to Observable, as well as when results\n * passed to callback will be emitted. By default, the subscription to an Observable calls `func`\n * synchronously, but using {@link asyncScheduler} as the last parameter will defer the call to `func`,\n * just like wrapping the call in `setTimeout` with a timeout of `0` would. If you were to use the async Scheduler\n * and call `subscribe` on the output Observable, all function calls that are currently executing\n * will end before `func` is invoked.\n *\n * By default, results passed to the callback are emitted immediately after `func` invokes the callback.\n * In particular, if the callback is called synchronously, then the subscription of the resulting Observable\n * will call the `next` function synchronously as well.  If you want to defer that call,\n * you may use {@link asyncScheduler} just as before.  This means that by using `Scheduler.async` you can\n * ensure that `func` always calls its callback asynchronously, thus avoiding terrifying Zalgo.\n *\n * Note that the Observable created by the output function will always emit a single value\n * and then complete immediately. If `func` calls the callback multiple times, values from subsequent\n * calls will not appear in the stream. If you need to listen for multiple calls,\n *  you probably want to use {@link fromEvent} or {@link fromEventPattern} instead.\n *\n * If `func` depends on some context (`this` property) and is not already bound, the context of `func`\n * will be the context that the output function has at call time. In particular, if `func`\n * is called as a method of some objec and if `func` is not already bound, in order to preserve the context\n * it is recommended that the context of the output function is set to that object as well.\n *\n * If the input function calls its callback in the \"node style\" (i.e. first argument to callback is\n * optional error parameter signaling whether the call failed or not), {@link bindNodeCallback}\n * provides convenient error handling and probably is a better choice.\n * `bindCallback` will treat such functions the same as any other and error parameters\n * (whether passed or not) will always be interpreted as regular callback argument.\n *\n * ## Examples\n *\n * ### Convert jQuery's getJSON to an Observable API\n * ```ts\n * import { bindCallback } from 'valdi_rxjs';\n * import * as jQuery from 'jquery';\n *\n * // Suppose we have jQuery.getJSON('/my/url', callback)\n * const getJSONAsObservable = bindCallback(jQuery.getJSON);\n * const result = getJSONAsObservable('/my/url');\n * result.subscribe(x => console.log(x), e => console.error(e));\n * ```\n *\n * ### Receive an array of arguments passed to a callback\n * ```ts\n * import { bindCallback } from 'valdi_rxjs';\n *\n * const someFunction = (cb) => {\n *   cb(5, 'some string', {someProperty: 'someValue'})\n * };\n *\n * const boundSomeFunction = bindCallback(someFunction);\n * boundSomeFunction(12, 10).subscribe(values => {\n *   console.log(values); // [22, 2]\n * });\n * ```\n *\n * ### Compare behaviour with and without async Scheduler\n * ```ts\n * import { bindCallback, asyncScheduler } from 'valdi_rxjs';\n *\n * function iCallMyCallbackSynchronously(cb) {\n *   cb();\n * }\n *\n * const boundSyncFn = bindCallback(iCallMyCallbackSynchronously);\n * const boundAsyncFn = bindCallback(iCallMyCallbackSynchronously, null, asyncScheduler);\n *\n * boundSyncFn().subscribe(() => console.log('I was sync!'));\n * boundAsyncFn().subscribe(() => console.log('I was async!'));\n * console.log('This happened...');\n *\n * // Logs:\n * // I was sync!\n * // This happened...\n * // I was async!\n * ```\n *\n * ### Use bindCallback on an object method\n * ```ts\n * import { bindCallback } from 'valdi_rxjs';\n *\n * const boundMethod = bindCallback(someObject.methodWithCallback);\n * boundMethod\n *   .call(someObject) // make sure methodWithCallback has access to someObject\n *   .subscribe(subscriber);\n * ```\n *\n * @see {@link bindNodeCallback}\n * @see {@link from}\n *\n * @param {function} func A function with a callback as the last parameter.\n * @param {SchedulerLike} [scheduler] The scheduler on which to schedule the\n * callbacks.\n * @return {function(...params: *): Observable} A function which returns the\n * Observable that delivers the same values the callback would deliver.\n */\nexport function bindCallback(\n  callbackFunc: (...args: [...any[], (...res: any) => void]) => void,\n  resultSelector?: ((...args: any[]) => any) | SchedulerLike,\n  scheduler?: SchedulerLike\n): (...args: any[]) => Observable<unknown> {\n  return bindCallbackInternals(false, callbackFunc, resultSelector, scheduler);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/bindCallbackInternals.ts",
    "content": "import { SchedulerLike } from '../types';\nimport { isScheduler } from '../util/isScheduler';\nimport { Observable } from '../Observable';\nimport { subscribeOn } from '../operators/subscribeOn';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { observeOn } from '../operators/observeOn';\nimport { AsyncSubject } from '../AsyncSubject';\n\nexport function bindCallbackInternals(\n  isNodeStyle: boolean,\n  callbackFunc: any,\n  resultSelector?: any,\n  scheduler?: SchedulerLike\n): (...args: any[]) => Observable<unknown> {\n  if (resultSelector) {\n    if (isScheduler(resultSelector)) {\n      scheduler = resultSelector;\n    } else {\n      // The user provided a result selector.\n      return function (this: any, ...args: any[]) {\n        return (bindCallbackInternals(isNodeStyle, callbackFunc, scheduler) as any)\n          .apply(this, args)\n          .pipe(mapOneOrManyArgs(resultSelector as any));\n      };\n    }\n  }\n\n  // If a scheduler was passed, use our `subscribeOn` and `observeOn` operators\n  // to compose that behavior for the user.\n  if (scheduler) {\n    return function (this: any, ...args: any[]) {\n      return (bindCallbackInternals(isNodeStyle, callbackFunc) as any)\n        .apply(this, args)\n        .pipe(subscribeOn(scheduler!), observeOn(scheduler!));\n    };\n  }\n\n  return function (this: any, ...args: any[]): Observable<any> {\n    // We're using AsyncSubject, because it emits when it completes,\n    // and it will play the value to all late-arriving subscribers.\n    const subject = new AsyncSubject<any>();\n\n    // If this is true, then we haven't called our function yet.\n    let uninitialized = true;\n    return new Observable((subscriber) => {\n      // Add our subscriber to the subject.\n      const subs = subject.subscribe(subscriber);\n\n      if (uninitialized) {\n        uninitialized = false;\n        // We're going to execute the bound function\n        // This bit is to signal that we are hitting the callback asychronously.\n        // Because we don't have any anti-\"Zalgo\" gaurantees with whatever\n        // function we are handed, we use this bit to figure out whether or not\n        // we are getting hit in a callback synchronously during our call.\n        let isAsync = false;\n\n        // This is used to signal that the callback completed synchronously.\n        let isComplete = false;\n\n        // Call our function that has a callback. If at any time during this\n        // call, an error is thrown, it will be caught by the Observable\n        // subscription process and sent to the consumer.\n        callbackFunc.apply(\n          // Pass the appropriate `this` context.\n          this,\n          [\n            // Pass the arguments.\n            ...args,\n            // And our callback handler.\n            (...results: any[]) => {\n              if (isNodeStyle) {\n                // If this is a node callback, shift the first value off of the\n                // results and check it, as it is the error argument. By shifting,\n                // we leave only the argument(s) we want to pass to the consumer.\n                const err = results.shift();\n                if (err != null) {\n                  subject.error(err);\n                  // If we've errored, we can stop processing this function\n                  // as there's nothing else to do. Just return to escape.\n                  return;\n                }\n              }\n              // If we have one argument, notify the consumer\n              // of it as a single value, otherwise, if there's more than one, pass\n              // them as an array. Note that if there are no arguments, `undefined`\n              // will be emitted.\n              subject.next(1 < results.length ? results : results[0]);\n              // Flip this flag, so we know we can complete it in the synchronous\n              // case below.\n              isComplete = true;\n              // If we're not asynchronous, we need to defer the `complete` call\n              // until after the call to the function is over. This is because an\n              // error could be thrown in the function after it calls our callback,\n              // and if that is the case, if we complete here, we are unable to notify\n              // the consumer than an error occured.\n              if (isAsync) {\n                subject.complete();\n              }\n            },\n          ]\n        );\n        // If we flipped `isComplete` during the call, we resolved synchronously,\n        // notify complete, because we skipped it in the callback to wait\n        // to make sure there were no errors during the call.\n        if (isComplete) {\n          subject.complete();\n        }\n\n        // We're no longer synchronous. If the callback is called at this point\n        // we can notify complete on the spot.\n        isAsync = true;\n      }\n\n      // Return the subscription fron adding our subscriber to the subject.\n      return subs;\n    });\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/combineLatest.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservableInput, SchedulerLike, ObservedValueOf, ObservableInputTuple } from '../types';\nimport { argsArgArrayOrObject } from '../util/argsArgArrayOrObject';\nimport { Subscriber } from '../Subscriber';\nimport { from } from './from';\nimport { identity } from '../util/identity';\nimport { Subscription } from '../Subscription';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { popResultSelector, popScheduler } from '../util/args';\nimport { createObject } from '../util/createObject';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { AnyCatcher } from '../AnyCatcher';\nimport { executeSchedule } from '../util/executeSchedule';\n\n// combineLatest(any)\n// We put this first because we need to catch cases where the user has supplied\n// _exactly `any`_ as the argument. Since `any` literally matches _anything_,\n// we don't want it to randomly hit one of the other type signatures below,\n// as we have no idea at build-time what type we should be returning when given an any.\n\n/**\n * You have passed `any` here, we can't figure out if it is\n * an array or an object, so you're getting `unknown`. Use better types.\n * @param arg Something typed as `any`\n */\nexport function combineLatest<T extends AnyCatcher>(arg: T): Observable<unknown>;\n\n// combineLatest([a, b, c])\nexport function combineLatest(sources: []): Observable<never>;\nexport function combineLatest<A extends readonly unknown[]>(sources: readonly [...ObservableInputTuple<A>]): Observable<A>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled` and `combineLatestAll`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function combineLatest<A extends readonly unknown[], R>(\n  sources: readonly [...ObservableInputTuple<A>],\n  resultSelector: (...values: A) => R,\n  scheduler: SchedulerLike\n): Observable<R>;\nexport function combineLatest<A extends readonly unknown[], R>(\n  sources: readonly [...ObservableInputTuple<A>],\n  resultSelector: (...values: A) => R\n): Observable<R>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled` and `combineLatestAll`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function combineLatest<A extends readonly unknown[]>(\n  sources: readonly [...ObservableInputTuple<A>],\n  scheduler: SchedulerLike\n): Observable<A>;\n\n// combineLatest(a, b, c)\n/** @deprecated Pass an array of sources instead. The rest-parameters signature will be removed in v8. Details: https://rxjs.dev/deprecations/array-argument */\nexport function combineLatest<A extends readonly unknown[]>(...sources: [...ObservableInputTuple<A>]): Observable<A>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled` and `combineLatestAll`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function combineLatest<A extends readonly unknown[], R>(\n  ...sourcesAndResultSelectorAndScheduler: [...ObservableInputTuple<A>, (...values: A) => R, SchedulerLike]\n): Observable<R>;\n/** @deprecated Pass an array of sources instead. The rest-parameters signature will be removed in v8. Details: https://rxjs.dev/deprecations/array-argument */\nexport function combineLatest<A extends readonly unknown[], R>(\n  ...sourcesAndResultSelector: [...ObservableInputTuple<A>, (...values: A) => R]\n): Observable<R>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled` and `combineLatestAll`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function combineLatest<A extends readonly unknown[]>(\n  ...sourcesAndScheduler: [...ObservableInputTuple<A>, SchedulerLike]\n): Observable<A>;\n\n// combineLatest({a, b, c})\nexport function combineLatest(sourcesObject: { [K in any]: never }): Observable<never>;\nexport function combineLatest<T extends Record<string, ObservableInput<any>>>(\n  sourcesObject: T\n): Observable<{ [K in keyof T]: ObservedValueOf<T[K]> }>;\n\n/**\n * Combines multiple Observables to create an Observable whose values are\n * calculated from the latest values of each of its input Observables.\n *\n * <span class=\"informal\">Whenever any input Observable emits a value, it\n * computes a formula using the latest values from all the inputs, then emits\n * the output of that formula.</span>\n *\n * ![](combineLatest.png)\n *\n * `combineLatest` combines the values from all the Observables passed in the\n * observables array. This is done by subscribing to each Observable in order and,\n * whenever any Observable emits, collecting an array of the most recent\n * values from each Observable. So if you pass `n` Observables to this operator,\n * the returned Observable will always emit an array of `n` values, in an order\n * corresponding to the order of the passed Observables (the value from the first Observable\n * will be at index 0 of the array and so on).\n *\n * Static version of `combineLatest` accepts an array of Observables. Note that an array of\n * Observables is a good choice, if you don't know beforehand how many Observables\n * you will combine. Passing an empty array will result in an Observable that\n * completes immediately.\n *\n * To ensure the output array always has the same length, `combineLatest` will\n * actually wait for all input Observables to emit at least once,\n * before it starts emitting results. This means if some Observable emits\n * values before other Observables started emitting, all these values but the last\n * will be lost. On the other hand, if some Observable does not emit a value but\n * completes, resulting Observable will complete at the same moment without\n * emitting anything, since it will now be impossible to include a value from the\n * completed Observable in the resulting array. Also, if some input Observable does\n * not emit any value and never completes, `combineLatest` will also never emit\n * and never complete, since, again, it will wait for all streams to emit some\n * value.\n *\n * If at least one Observable was passed to `combineLatest` and all passed Observables\n * emitted something, the resulting Observable will complete when all combined\n * streams complete. So even if some Observable completes, the result of\n * `combineLatest` will still emit values when other Observables do. In case\n * of a completed Observable, its value from now on will always be the last\n * emitted value. On the other hand, if any Observable errors, `combineLatest`\n * will error immediately as well, and all other Observables will be unsubscribed.\n *\n * ## Examples\n *\n * Combine two timer Observables\n *\n * ```ts\n * import { timer, combineLatest } from 'valdi_rxjs';\n *\n * const firstTimer = timer(0, 1000); // emit 0, 1, 2... after every second, starting from now\n * const secondTimer = timer(500, 1000); // emit 0, 1, 2... after every second, starting 0,5s from now\n * const combinedTimers = combineLatest([firstTimer, secondTimer]);\n * combinedTimers.subscribe(value => console.log(value));\n * // Logs\n * // [0, 0] after 0.5s\n * // [1, 0] after 1s\n * // [1, 1] after 1.5s\n * // [2, 1] after 2s\n * ```\n *\n * Combine a dictionary of Observables\n *\n * ```ts\n * import { of, delay, startWith, combineLatest } from 'valdi_rxjs';\n *\n * const observables = {\n *   a: of(1).pipe(delay(1000), startWith(0)),\n *   b: of(5).pipe(delay(5000), startWith(0)),\n *   c: of(10).pipe(delay(10000), startWith(0))\n * };\n * const combined = combineLatest(observables);\n * combined.subscribe(value => console.log(value));\n * // Logs\n * // { a: 0, b: 0, c: 0 } immediately\n * // { a: 1, b: 0, c: 0 } after 1s\n * // { a: 1, b: 5, c: 0 } after 5s\n * // { a: 1, b: 5, c: 10 } after 10s\n * ```\n *\n * Combine an array of Observables\n *\n * ```ts\n * import { of, delay, startWith, combineLatest } from 'valdi_rxjs';\n *\n * const observables = [1, 5, 10].map(\n *   n => of(n).pipe(\n *     delay(n * 1000), // emit 0 and then emit n after n seconds\n *     startWith(0)\n *   )\n * );\n * const combined = combineLatest(observables);\n * combined.subscribe(value => console.log(value));\n * // Logs\n * // [0, 0, 0] immediately\n * // [1, 0, 0] after 1s\n * // [1, 5, 0] after 5s\n * // [1, 5, 10] after 10s\n * ```\n *\n * Use map operator to dynamically calculate the Body-Mass Index\n *\n * ```ts\n * import { of, combineLatest, map } from 'valdi_rxjs';\n *\n * const weight = of(70, 72, 76, 79, 75);\n * const height = of(1.76, 1.77, 1.78);\n * const bmi = combineLatest([weight, height]).pipe(\n *   map(([w, h]) => w / (h * h)),\n * );\n * bmi.subscribe(x => console.log('BMI is ' + x));\n *\n * // With output to console:\n * // BMI is 24.212293388429753\n * // BMI is 23.93948099205209\n * // BMI is 23.671253629592222\n * ```\n *\n * @see {@link combineLatestAll}\n * @see {@link merge}\n * @see {@link withLatestFrom}\n *\n * @param {ObservableInput} [observables] An array of input Observables to combine with each other.\n * An array of Observables must be given as the first argument.\n * @param {function} [project] An optional function to project the values from\n * the combined latest values into a new value on the output Observable.\n * @param {SchedulerLike} [scheduler=null] The {@link SchedulerLike} to use for subscribing to\n * each input Observable.\n * @return {Observable} An Observable of projected values from the most recent\n * values from each input Observable, or an array of the most recent values from\n * each input Observable.\n */\nexport function combineLatest<O extends ObservableInput<any>, R>(...args: any[]): Observable<R> | Observable<ObservedValueOf<O>[]> {\n  const scheduler = popScheduler(args);\n  const resultSelector = popResultSelector(args);\n\n  const { args: observables, keys } = argsArgArrayOrObject(args);\n\n  if (observables.length === 0) {\n    // If no observables are passed, or someone has passed an ampty array\n    // of observables, or even an empty object POJO, we need to just\n    // complete (EMPTY), but we have to honor the scheduler provided if any.\n    return from([], scheduler as any);\n  }\n\n  const result = new Observable<ObservedValueOf<O>[]>(\n    combineLatestInit(\n      observables as ObservableInput<ObservedValueOf<O>>[],\n      scheduler,\n      keys\n        ? // A handler for scrubbing the array of args into a dictionary.\n          (values) => createObject(keys, values)\n        : // A passthrough to just return the array\n          identity\n    )\n  );\n\n  return resultSelector ? (result.pipe(mapOneOrManyArgs(resultSelector)) as Observable<R>) : result;\n}\n\nexport function combineLatestInit(\n  observables: ObservableInput<any>[],\n  scheduler?: SchedulerLike,\n  valueTransform: (values: any[]) => any = identity\n) {\n  return (subscriber: Subscriber<any>) => {\n    // The outer subscription. We're capturing this in a function\n    // because we may have to schedule it.\n    maybeSchedule(\n      scheduler,\n      () => {\n        const { length } = observables;\n        // A store for the values each observable has emitted so far. We match observable to value on index.\n        const values = new Array(length);\n        // The number of currently active subscriptions, as they complete, we decrement this number to see if\n        // we are all done combining values, so we can complete the result.\n        let active = length;\n        // The number of inner sources that still haven't emitted the first value\n        // We need to track this because all sources need to emit one value in order\n        // to start emitting values.\n        let remainingFirstValues = length;\n        // The loop to kick off subscription. We're keying everything on index `i` to relate the observables passed\n        // in to the slot in the output array or the key in the array of keys in the output dictionary.\n        for (let i = 0; i < length; i++) {\n          maybeSchedule(\n            scheduler,\n            () => {\n              const source = from(observables[i], scheduler as any);\n              let hasFirstValue = false;\n              source.subscribe(\n                createOperatorSubscriber(\n                  subscriber,\n                  (value) => {\n                    // When we get a value, record it in our set of values.\n                    values[i] = value;\n                    if (!hasFirstValue) {\n                      // If this is our first value, record that.\n                      hasFirstValue = true;\n                      remainingFirstValues--;\n                    }\n                    if (!remainingFirstValues) {\n                      // We're not waiting for any more\n                      // first values, so we can emit!\n                      subscriber.next(valueTransform(values.slice()));\n                    }\n                  },\n                  () => {\n                    if (!--active) {\n                      // We only complete the result if we have no more active\n                      // inner observables.\n                      subscriber.complete();\n                    }\n                  }\n                )\n              );\n            },\n            subscriber\n          );\n        }\n      },\n      subscriber\n    );\n  };\n}\n\n/**\n * A small utility to handle the couple of locations where we want to schedule if a scheduler was provided,\n * but we don't if there was no scheduler.\n */\nfunction maybeSchedule(scheduler: SchedulerLike | undefined, execute: () => void, subscription: Subscription) {\n  if (scheduler) {\n    executeSchedule(subscription, scheduler, execute);\n  } else {\n    execute();\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/concat.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservableInputTuple, SchedulerLike } from '../types';\nimport { concatAll } from '../operators/concatAll';\nimport { popScheduler } from '../util/args';\nimport { from } from './from';\n\nexport function concat<T extends readonly unknown[]>(...inputs: [...ObservableInputTuple<T>]): Observable<T[number]>;\nexport function concat<T extends readonly unknown[]>(\n  ...inputsAndScheduler: [...ObservableInputTuple<T>, SchedulerLike]\n): Observable<T[number]>;\n\n/**\n * Creates an output Observable which sequentially emits all values from the first given\n * Observable and then moves on to the next.\n *\n * <span class=\"informal\">Concatenates multiple Observables together by\n * sequentially emitting their values, one Observable after the other.</span>\n *\n * ![](concat.png)\n *\n * `concat` joins multiple Observables together, by subscribing to them one at a time and\n * merging their results into the output Observable. You can pass either an array of\n * Observables, or put them directly as arguments. Passing an empty array will result\n * in Observable that completes immediately.\n *\n * `concat` will subscribe to first input Observable and emit all its values, without\n * changing or affecting them in any way. When that Observable completes, it will\n * subscribe to then next Observable passed and, again, emit its values. This will be\n * repeated, until the operator runs out of Observables. When last input Observable completes,\n * `concat` will complete as well. At any given moment only one Observable passed to operator\n * emits values. If you would like to emit values from passed Observables concurrently, check out\n * {@link merge} instead, especially with optional `concurrent` parameter. As a matter of fact,\n * `concat` is an equivalent of `merge` operator with `concurrent` parameter set to `1`.\n *\n * Note that if some input Observable never completes, `concat` will also never complete\n * and Observables following the one that did not complete will never be subscribed. On the other\n * hand, if some Observable simply completes immediately after it is subscribed, it will be\n * invisible for `concat`, which will just move on to the next Observable.\n *\n * If any Observable in chain errors, instead of passing control to the next Observable,\n * `concat` will error immediately as well. Observables that would be subscribed after\n * the one that emitted error, never will.\n *\n * If you pass to `concat` the same Observable many times, its stream of values\n * will be \"replayed\" on every subscription, which means you can repeat given Observable\n * as many times as you like. If passing the same Observable to `concat` 1000 times becomes tedious,\n * you can always use {@link repeat}.\n *\n * ## Examples\n *\n * Concatenate a timer counting from 0 to 3 with a synchronous sequence from 1 to 10\n *\n * ```ts\n * import { interval, take, range, concat } from 'valdi_rxjs';\n *\n * const timer = interval(1000).pipe(take(4));\n * const sequence = range(1, 10);\n * const result = concat(timer, sequence);\n * result.subscribe(x => console.log(x));\n *\n * // results in:\n * // 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3 -immediate-> 1 ... 10\n * ```\n *\n * Concatenate 3 Observables\n *\n * ```ts\n * import { interval, take, concat } from 'valdi_rxjs';\n *\n * const timer1 = interval(1000).pipe(take(10));\n * const timer2 = interval(2000).pipe(take(6));\n * const timer3 = interval(500).pipe(take(10));\n *\n * const result = concat(timer1, timer2, timer3);\n * result.subscribe(x => console.log(x));\n *\n * // results in the following:\n * // (Prints to console sequentially)\n * // -1000ms-> 0 -1000ms-> 1 -1000ms-> ... 9\n * // -2000ms-> 0 -2000ms-> 1 -2000ms-> ... 5\n * // -500ms-> 0 -500ms-> 1 -500ms-> ... 9\n * ```\n *\n * Concatenate the same Observable to repeat it\n *\n * ```ts\n * import { interval, take, concat } from 'valdi_rxjs';\n *\n * const timer = interval(1000).pipe(take(2));\n *\n * concat(timer, timer) // concatenating the same Observable!\n *   .subscribe({\n *     next: value => console.log(value),\n *     complete: () => console.log('...and it is done!')\n *   });\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 0 after 3s\n * // 1 after 4s\n * // '...and it is done!' also after 4s\n * ```\n *\n * @see {@link concatAll}\n * @see {@link concatMap}\n * @see {@link concatMapTo}\n * @see {@link startWith}\n * @see {@link endWith}\n *\n * @param args Input Observables to concatenate.\n */\nexport function concat(...args: any[]): Observable<unknown> {\n  return concatAll()(from(args, popScheduler(args)));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/connectable.ts",
    "content": "import { Connectable, ObservableInput, SubjectLike } from '../types';\nimport { Subject } from '../Subject';\nimport { Subscription } from '../Subscription';\nimport { Observable } from '../Observable';\nimport { defer } from './defer';\n\nexport interface ConnectableConfig<T> {\n  /**\n   * A factory function used to create the Subject through which the source\n   * is multicast. By default this creates a {@link Subject}.\n   */\n  connector: () => SubjectLike<T>;\n  /**\n   * If true, the resulting observable will reset internal state upon disconnetion\n   * and return to a \"cold\" state. This allows the resulting observable to be\n   * reconnected.\n   * If false, upon disconnection, the connecting subject will remain the\n   * connecting subject, meaning the resulting observable will not go \"cold\" again,\n   * and subsequent repeats or resubscriptions will resubscribe to that same subject.\n   */\n  resetOnDisconnect?: boolean;\n}\n\n/**\n * The default configuration for `connectable`.\n */\nconst DEFAULT_CONFIG: ConnectableConfig<unknown> = {\n  connector: () => new Subject<unknown>(),\n  resetOnDisconnect: true,\n};\n\n/**\n * Creates an observable that multicasts once `connect()` is called on it.\n *\n * @param source The observable source to make connectable.\n * @param config The configuration object for `connectable`.\n * @returns A \"connectable\" observable, that has a `connect()` method, that you must call to\n * connect the source to all consumers through the subject provided as the connector.\n */\nexport function connectable<T>(source: ObservableInput<T>, config: ConnectableConfig<T> = DEFAULT_CONFIG): Connectable<T> {\n  // The subscription representing the connection.\n  let connection: Subscription | null = null;\n  const { connector, resetOnDisconnect = true } = config;\n  let subject = connector();\n\n  const result: any = new Observable<T>((subscriber) => {\n    return subject.subscribe(subscriber);\n  });\n\n  // Define the `connect` function. This is what users must call\n  // in order to \"connect\" the source to the subject that is\n  // multicasting it.\n  result.connect = () => {\n    if (!connection || connection.closed) {\n      connection = defer(() => source).subscribe(subject);\n      if (resetOnDisconnect) {\n        connection.add(() => (subject = connector()));\n      }\n    }\n    return connection;\n  };\n\n  return result;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/defer.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservedValueOf, ObservableInput } from '../types';\nimport { innerFrom } from './innerFrom';\n\n/**\n * Creates an Observable that, on subscribe, calls an Observable factory to\n * make an Observable for each new Observer.\n *\n * <span class=\"informal\">Creates the Observable lazily, that is, only when it\n * is subscribed.\n * </span>\n *\n * ![](defer.png)\n *\n * `defer` allows you to create an Observable only when the Observer\n * subscribes. It waits until an Observer subscribes to it, calls the given\n * factory function to get an Observable -- where a factory function typically\n * generates a new Observable -- and subscribes the Observer to this Observable.\n * In case the factory function returns a falsy value, then EMPTY is used as\n * Observable instead. Last but not least, an exception during the factory\n * function call is transferred to the Observer by calling `error`.\n *\n * ## Example\n *\n * Subscribe to either an Observable of clicks or an Observable of interval, at random\n *\n * ```ts\n * import { defer, fromEvent, interval } from 'valdi_rxjs';\n *\n * const clicksOrInterval = defer(() => {\n *   return Math.random() > 0.5\n *     ? fromEvent(document, 'click')\n *     : interval(1000);\n * });\n * clicksOrInterval.subscribe(x => console.log(x));\n *\n * // Results in the following behavior:\n * // If the result of Math.random() is greater than 0.5 it will listen\n * // for clicks anywhere on the \"document\"; when document is clicked it\n * // will log a MouseEvent object to the console. If the result is less\n * // than 0.5 it will emit ascending numbers, one every second(1000ms).\n * ```\n *\n * @see {@link Observable}\n *\n * @param {function(): ObservableInput} observableFactory The Observable\n * factory function to invoke for each Observer that subscribes to the output\n * Observable. May also return a Promise, which will be converted on the fly\n * to an Observable.\n * @return {Observable} An Observable whose Observers' subscriptions trigger\n * an invocation of the given Observable factory function.\n */\nexport function defer<R extends ObservableInput<any>>(observableFactory: () => R): Observable<ObservedValueOf<R>> {\n  return new Observable<ObservedValueOf<R>>((subscriber) => {\n    innerFrom(observableFactory()).subscribe(subscriber);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/empty.ts",
    "content": "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * <span class=\"informal\">Just emits 'complete', and nothing else.</span>\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'valdi_rxjs';\n *\n * EMPTY.subscribe({\n *   next: () => console.log('Next'),\n *   complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'valdi_rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'valdi_rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n *   mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable<never>((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n  return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n  return new Observable<never>((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/forkJoin.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservedValueOf, ObservableInputTuple, ObservableInput } from '../types';\nimport { argsArgArrayOrObject } from '../util/argsArgArrayOrObject';\nimport { innerFrom } from './innerFrom';\nimport { popResultSelector } from '../util/args';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { createObject } from '../util/createObject';\nimport { AnyCatcher } from '../AnyCatcher';\n\n// forkJoin(any)\n// We put this first because we need to catch cases where the user has supplied\n// _exactly `any`_ as the argument. Since `any` literally matches _anything_,\n// we don't want it to randomly hit one of the other type signatures below,\n// as we have no idea at build-time what type we should be returning when given an any.\n\n/**\n * You have passed `any` here, we can't figure out if it is\n * an array or an object, so you're getting `unknown`. Use better types.\n * @param arg Something typed as `any`\n */\nexport function forkJoin<T extends AnyCatcher>(arg: T): Observable<unknown>;\n\n// forkJoin(null | undefined)\nexport function forkJoin(scheduler: null | undefined): Observable<never>;\n\n// forkJoin([a, b, c])\nexport function forkJoin(sources: readonly []): Observable<never>;\nexport function forkJoin<A extends readonly unknown[]>(sources: readonly [...ObservableInputTuple<A>]): Observable<A>;\nexport function forkJoin<A extends readonly unknown[], R>(\n  sources: readonly [...ObservableInputTuple<A>],\n  resultSelector: (...values: A) => R\n): Observable<R>;\n\n// forkJoin(a, b, c)\n/** @deprecated Pass an array of sources instead. The rest-parameters signature will be removed in v8. Details: https://rxjs.dev/deprecations/array-argument */\nexport function forkJoin<A extends readonly unknown[]>(...sources: [...ObservableInputTuple<A>]): Observable<A>;\n/** @deprecated Pass an array of sources instead. The rest-parameters signature will be removed in v8. Details: https://rxjs.dev/deprecations/array-argument */\nexport function forkJoin<A extends readonly unknown[], R>(\n  ...sourcesAndResultSelector: [...ObservableInputTuple<A>, (...values: A) => R]\n): Observable<R>;\n\n// forkJoin({a, b, c})\nexport function forkJoin(sourcesObject: { [K in any]: never }): Observable<never>;\nexport function forkJoin<T extends Record<string, ObservableInput<any>>>(\n  sourcesObject: T\n): Observable<{ [K in keyof T]: ObservedValueOf<T[K]> }>;\n\n/**\n * Accepts an `Array` of {@link ObservableInput} or a dictionary `Object` of {@link ObservableInput} and returns\n * an {@link Observable} that emits either an array of values in the exact same order as the passed array,\n * or a dictionary of values in the same shape as the passed dictionary.\n *\n * <span class=\"informal\">Wait for Observables to complete and then combine last values they emitted;\n * complete immediately if an empty array is passed.</span>\n *\n * ![](forkJoin.png)\n *\n * `forkJoin` is an operator that takes any number of input observables which can be passed either as an array\n * or a dictionary of input observables. If no input observables are provided (e.g. an empty array is passed),\n * then the resulting stream will complete immediately.\n *\n * `forkJoin` will wait for all passed observables to emit and complete and then it will emit an array or an object with last\n * values from corresponding observables.\n *\n * If you pass an array of `n` observables to the operator, then the resulting\n * array will have `n` values, where the first value is the last one emitted by the first observable,\n * second value is the last one emitted by the second observable and so on.\n *\n * If you pass a dictionary of observables to the operator, then the resulting\n * objects will have the same keys as the dictionary passed, with their last values they have emitted\n * located at the corresponding key.\n *\n * That means `forkJoin` will not emit more than once and it will complete after that. If you need to emit combined\n * values not only at the end of the lifecycle of passed observables, but also throughout it, try out {@link combineLatest}\n * or {@link zip} instead.\n *\n * In order for the resulting array to have the same length as the number of input observables, whenever any of\n * the given observables completes without emitting any value, `forkJoin` will complete at that moment as well\n * and it will not emit anything either, even if it already has some last values from other observables.\n * Conversely, if there is an observable that never completes, `forkJoin` will never complete either,\n * unless at any point some other observable completes without emitting a value, which brings us back to\n * the previous case. Overall, in order for `forkJoin` to emit a value, all given observables\n * have to emit something at least once and complete.\n *\n * If any given observable errors at some point, `forkJoin` will error as well and immediately unsubscribe\n * from the other observables.\n *\n * Optionally `forkJoin` accepts a `resultSelector` function, that will be called with values which normally\n * would land in the emitted array. Whatever is returned by the `resultSelector`, will appear in the output\n * observable instead. This means that the default `resultSelector` can be thought of as a function that takes\n * all its arguments and puts them into an array. Note that the `resultSelector` will be called only\n * when `forkJoin` is supposed to emit a result.\n *\n * ## Examples\n *\n * Use `forkJoin` with a dictionary of observable inputs\n *\n * ```ts\n * import { forkJoin, of, timer } from 'valdi_rxjs';\n *\n * const observable = forkJoin({\n *   foo: of(1, 2, 3, 4),\n *   bar: Promise.resolve(8),\n *   baz: timer(4000)\n * });\n * observable.subscribe({\n *  next: value => console.log(value),\n *  complete: () => console.log('This is how it ends!'),\n * });\n *\n * // Logs:\n * // { foo: 4, bar: 8, baz: 0 } after 4 seconds\n * // 'This is how it ends!' immediately after\n * ```\n *\n * Use `forkJoin` with an array of observable inputs\n *\n * ```ts\n * import { forkJoin, of, timer } from 'valdi_rxjs';\n *\n * const observable = forkJoin([\n *   of(1, 2, 3, 4),\n *   Promise.resolve(8),\n *   timer(4000)\n * ]);\n * observable.subscribe({\n *  next: value => console.log(value),\n *  complete: () => console.log('This is how it ends!'),\n * });\n *\n * // Logs:\n * // [4, 8, 0] after 4 seconds\n * // 'This is how it ends!' immediately after\n * ```\n *\n * @see {@link combineLatest}\n * @see {@link zip}\n *\n * @param {...ObservableInput} args Any number of Observables provided either as an array or as an arguments\n * passed directly to the operator.\n * @param {function} [project] Function that takes values emitted by input Observables and returns value\n * that will appear in resulting Observable instead of default array.\n * @return {Observable} Observable emitting either an array of last values emitted by passed Observables\n * or value from project function.\n */\nexport function forkJoin(...args: any[]): Observable<any> {\n  const resultSelector = popResultSelector(args);\n  const { args: sources, keys } = argsArgArrayOrObject(args);\n  const result = new Observable((subscriber) => {\n    const { length } = sources;\n    if (!length) {\n      subscriber.complete();\n      return;\n    }\n    const values = new Array(length);\n    let remainingCompletions = length;\n    let remainingEmissions = length;\n    for (let sourceIndex = 0; sourceIndex < length; sourceIndex++) {\n      let hasValue = false;\n      innerFrom(sources[sourceIndex]).subscribe(\n        createOperatorSubscriber(\n          subscriber,\n          (value) => {\n            if (!hasValue) {\n              hasValue = true;\n              remainingEmissions--;\n            }\n            values[sourceIndex] = value;\n          },\n          () => remainingCompletions--,\n          undefined,\n          () => {\n            if (!remainingCompletions || !hasValue) {\n              if (!remainingEmissions) {\n                subscriber.next(keys ? createObject(keys, values) : values);\n              }\n              subscriber.complete();\n            }\n          }\n        )\n      );\n    }\n  });\n  return resultSelector ? result.pipe(mapOneOrManyArgs(resultSelector)) : result;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/from.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservableInput, SchedulerLike, ObservedValueOf } from '../types';\nimport { scheduled } from '../scheduled/scheduled';\nimport { innerFrom } from './innerFrom';\n\nexport function from<O extends ObservableInput<any>>(input: O): Observable<ObservedValueOf<O>>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function from<O extends ObservableInput<any>>(input: O, scheduler: SchedulerLike | undefined): Observable<ObservedValueOf<O>>;\n\n/**\n * Creates an Observable from an Array, an array-like object, a Promise, an iterable object, or an Observable-like object.\n *\n * <span class=\"informal\">Converts almost anything to an Observable.</span>\n *\n * ![](from.png)\n *\n * `from` converts various other objects and data types into Observables. It also converts a Promise, an array-like, or an\n * <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#iterable\" target=\"_blank\">iterable</a>\n * object into an Observable that emits the items in that promise, array, or iterable. A String, in this context, is treated\n * as an array of characters. Observable-like objects (contains a function named with the ES2015 Symbol for Observable) can also be\n * converted through this operator.\n *\n * ## Examples\n *\n * Converts an array to an Observable\n *\n * ```ts\n * import { from } from 'valdi_rxjs';\n *\n * const array = [10, 20, 30];\n * const result = from(array);\n *\n * result.subscribe(x => console.log(x));\n *\n * // Logs:\n * // 10\n * // 20\n * // 30\n * ```\n *\n * Convert an infinite iterable (from a generator) to an Observable\n *\n * ```ts\n * import { from, take } from 'valdi_rxjs';\n *\n * function* generateDoubles(seed) {\n *    let i = seed;\n *    while (true) {\n *      yield i;\n *      i = 2 * i; // double it\n *    }\n * }\n *\n * const iterator = generateDoubles(3);\n * const result = from(iterator).pipe(take(10));\n *\n * result.subscribe(x => console.log(x));\n *\n * // Logs:\n * // 3\n * // 6\n * // 12\n * // 24\n * // 48\n * // 96\n * // 192\n * // 384\n * // 768\n * // 1536\n * ```\n *\n * With `asyncScheduler`\n *\n * ```ts\n * import { from, asyncScheduler } from 'valdi_rxjs';\n *\n * console.log('start');\n *\n * const array = [10, 20, 30];\n * const result = from(array, asyncScheduler);\n *\n * result.subscribe(x => console.log(x));\n *\n * console.log('end');\n *\n * // Logs:\n * // 'start'\n * // 'end'\n * // 10\n * // 20\n * // 30\n * ```\n *\n * @see {@link fromEvent}\n * @see {@link fromEventPattern}\n *\n * @param {ObservableInput<T>} A subscription object, a Promise, an Observable-like,\n * an Array, an iterable, or an array-like object to be converted.\n * @param {SchedulerLike} An optional {@link SchedulerLike} on which to schedule the emission of values.\n * @return {Observable<T>}\n */\nexport function from<T>(input: ObservableInput<T>, scheduler?: SchedulerLike): Observable<T> {\n  return scheduler ? scheduled(input, scheduler) : innerFrom(input);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/fromEvent.ts",
    "content": "import { innerFrom } from './innerFrom';\nimport { Observable } from '../Observable';\nimport { mergeMap } from '../operators/mergeMap';\nimport { isArrayLike } from '../util/isArrayLike';\nimport { isFunction } from '../util/isFunction';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\n\n// These constants are used to create handler registry functions using array mapping below.\nconst nodeEventEmitterMethods = ['addListener', 'removeListener'] as const;\nconst eventTargetMethods = ['addEventListener', 'removeEventListener'] as const;\nconst jqueryMethods = ['on', 'off'] as const;\n\nexport interface NodeStyleEventEmitter {\n  addListener(eventName: string | symbol, handler: NodeEventHandler): this;\n  removeListener(eventName: string | symbol, handler: NodeEventHandler): this;\n}\n\nexport type NodeEventHandler = (...args: any[]) => void;\n\n// For APIs that implement `addListener` and `removeListener` methods that may\n// not use the same arguments or return EventEmitter values\n// such as React Native\nexport interface NodeCompatibleEventEmitter {\n  addListener(eventName: string, handler: NodeEventHandler): void | {};\n  removeListener(eventName: string, handler: NodeEventHandler): void | {};\n}\n\n// Use handler types like those in @types/jquery. See:\n// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/847731ba1d7fa6db6b911c0e43aa0afe596e7723/types/jquery/misc.d.ts#L6395\nexport interface JQueryStyleEventEmitter<TContext, T> {\n  on(eventName: string, handler: (this: TContext, t: T, ...args: any[]) => any): void;\n  off(eventName: string, handler: (this: TContext, t: T, ...args: any[]) => any): void;\n}\n\nexport interface EventListenerObject<E> {\n  handleEvent(evt: E): void;\n}\n\nexport interface HasEventTargetAddRemove<E> {\n  addEventListener(\n    type: string,\n    listener: ((evt: E) => void) | EventListenerObject<E> | null,\n    options?: boolean | AddEventListenerOptions,\n  ): void;\n  removeEventListener(\n    type: string,\n    listener: ((evt: E) => void) | EventListenerObject<E> | null,\n    options?: EventListenerOptions | boolean,\n  ): void;\n}\n\nexport interface EventListenerOptions {\n  capture?: boolean;\n  passive?: boolean;\n  once?: boolean;\n}\n\nexport interface AddEventListenerOptions extends EventListenerOptions {\n  once?: boolean;\n  passive?: boolean;\n}\n\nexport function fromEvent<T>(\n  target: HasEventTargetAddRemove<T> | ArrayLike<HasEventTargetAddRemove<T>>,\n  eventName: string,\n): Observable<T>;\nexport function fromEvent<T, R>(\n  target: HasEventTargetAddRemove<T> | ArrayLike<HasEventTargetAddRemove<T>>,\n  eventName: string,\n  resultSelector: (event: T) => R,\n): Observable<R>;\nexport function fromEvent<T>(\n  target: HasEventTargetAddRemove<T> | ArrayLike<HasEventTargetAddRemove<T>>,\n  eventName: string,\n  options: EventListenerOptions,\n): Observable<T>;\nexport function fromEvent<T, R>(\n  target: HasEventTargetAddRemove<T> | ArrayLike<HasEventTargetAddRemove<T>>,\n  eventName: string,\n  options: EventListenerOptions,\n  resultSelector: (event: T) => R,\n): Observable<R>;\n\nexport function fromEvent(\n  target: NodeStyleEventEmitter | ArrayLike<NodeStyleEventEmitter>,\n  eventName: string,\n): Observable<unknown>;\n/** @deprecated Do not specify explicit type parameters. Signatures with type parameters that cannot be inferred will be removed in v8. */\nexport function fromEvent<T>(\n  target: NodeStyleEventEmitter | ArrayLike<NodeStyleEventEmitter>,\n  eventName: string,\n): Observable<T>;\nexport function fromEvent<R>(\n  target: NodeStyleEventEmitter | ArrayLike<NodeStyleEventEmitter>,\n  eventName: string,\n  resultSelector: (...args: any[]) => R,\n): Observable<R>;\n\nexport function fromEvent(\n  target: NodeCompatibleEventEmitter | ArrayLike<NodeCompatibleEventEmitter>,\n  eventName: string,\n): Observable<unknown>;\n/** @deprecated Do not specify explicit type parameters. Signatures with type parameters that cannot be inferred will be removed in v8. */\nexport function fromEvent<T>(\n  target: NodeCompatibleEventEmitter | ArrayLike<NodeCompatibleEventEmitter>,\n  eventName: string,\n): Observable<T>;\nexport function fromEvent<R>(\n  target: NodeCompatibleEventEmitter | ArrayLike<NodeCompatibleEventEmitter>,\n  eventName: string,\n  resultSelector: (...args: any[]) => R,\n): Observable<R>;\n\nexport function fromEvent<T>(\n  target: JQueryStyleEventEmitter<any, T> | ArrayLike<JQueryStyleEventEmitter<any, T>>,\n  eventName: string,\n): Observable<T>;\nexport function fromEvent<T, R>(\n  target: JQueryStyleEventEmitter<any, T> | ArrayLike<JQueryStyleEventEmitter<any, T>>,\n  eventName: string,\n  resultSelector: (value: T, ...args: any[]) => R,\n): Observable<R>;\n\n/**\n * Creates an Observable that emits events of a specific type coming from the\n * given event target.\n *\n * <span class=\"informal\">Creates an Observable from DOM events, or Node.js\n * EventEmitter events or others.</span>\n *\n * ![](fromEvent.png)\n *\n * `fromEvent` accepts as a first argument event target, which is an object with methods\n * for registering event handler functions. As a second argument it takes string that indicates\n * type of event we want to listen for. `fromEvent` supports selected types of event targets,\n * which are described in detail below. If your event target does not match any of the ones listed,\n * you should use {@link fromEventPattern}, which can be used on arbitrary APIs.\n * When it comes to APIs supported by `fromEvent`, their methods for adding and removing event\n * handler functions have different names, but they all accept a string describing event type\n * and function itself, which will be called whenever said event happens.\n *\n * Every time resulting Observable is subscribed, event handler function will be registered\n * to event target on given event type. When that event fires, value\n * passed as a first argument to registered function will be emitted by output Observable.\n * When Observable is unsubscribed, function will be unregistered from event target.\n *\n * Note that if event target calls registered function with more than one argument, second\n * and following arguments will not appear in resulting stream. In order to get access to them,\n * you can pass to `fromEvent` optional project function, which will be called with all arguments\n * passed to event handler. Output Observable will then emit value returned by project function,\n * instead of the usual value.\n *\n * Remember that event targets listed below are checked via duck typing. It means that\n * no matter what kind of object you have and no matter what environment you work in,\n * you can safely use `fromEvent` on that object if it exposes described methods (provided\n * of course they behave as was described above). So for example if Node.js library exposes\n * event target which has the same method names as DOM EventTarget, `fromEvent` is still\n * a good choice.\n *\n * If the API you use is more callback then event handler oriented (subscribed\n * callback function fires only once and thus there is no need to manually\n * unregister it), you should use {@link bindCallback} or {@link bindNodeCallback}\n * instead.\n *\n * `fromEvent` supports following types of event targets:\n *\n * **DOM EventTarget**\n *\n * This is an object with `addEventListener` and `removeEventListener` methods.\n *\n * In the browser, `addEventListener` accepts - apart from event type string and event\n * handler function arguments - optional third parameter, which is either an object or boolean,\n * both used for additional configuration how and when passed function will be called. When\n * `fromEvent` is used with event target of that type, you can provide this values\n * as third parameter as well.\n *\n * **Node.js EventEmitter**\n *\n * An object with `addListener` and `removeListener` methods.\n *\n * **JQuery-style event target**\n *\n * An object with `on` and `off` methods\n *\n * **DOM NodeList**\n *\n * List of DOM Nodes, returned for example by `document.querySelectorAll` or `Node.childNodes`.\n *\n * Although this collection is not event target in itself, `fromEvent` will iterate over all Nodes\n * it contains and install event handler function in every of them. When returned Observable\n * is unsubscribed, function will be removed from all Nodes.\n *\n * **DOM HtmlCollection**\n *\n * Just as in case of NodeList it is a collection of DOM nodes. Here as well event handler function is\n * installed and removed in each of elements.\n *\n *\n * ## Examples\n *\n * Emit clicks happening on the DOM document\n *\n * ```ts\n * import { fromEvent } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * clicks.subscribe(x => console.log(x));\n *\n * // Results in:\n * // MouseEvent object logged to console every time a click\n * // occurs on the document.\n * ```\n *\n * Use `addEventListener` with capture option\n *\n * ```ts\n * import { fromEvent } from 'valdi_rxjs';\n *\n * const clicksInDocument = fromEvent(document, 'click', true); // note optional configuration parameter\n *                                                              // which will be passed to addEventListener\n * const clicksInDiv = fromEvent(someDivInDocument, 'click');\n *\n * clicksInDocument.subscribe(() => console.log('document'));\n * clicksInDiv.subscribe(() => console.log('div'));\n *\n * // By default events bubble UP in DOM tree, so normally\n * // when we would click on div in document\n * // \"div\" would be logged first and then \"document\".\n * // Since we specified optional `capture` option, document\n * // will catch event when it goes DOWN DOM tree, so console\n * // will log \"document\" and then \"div\".\n * ```\n *\n * @see {@link bindCallback}\n * @see {@link bindNodeCallback}\n * @see {@link fromEventPattern}\n *\n * @param {FromEventTarget<T>} target The DOM EventTarget, Node.js\n * EventEmitter, JQuery-like event target, NodeList or HTMLCollection to attach the event handler to.\n * @param {string} eventName The event name of interest, being emitted by the\n * `target`.\n * @param {EventListenerOptions} [options] Options to pass through to addEventListener\n * @return {Observable<T>}\n */\nexport function fromEvent<T>(\n  target: any,\n  eventName: string,\n  options?: EventListenerOptions | ((...args: any[]) => T),\n  resultSelector?: (...args: any[]) => T,\n): Observable<T> {\n  if (isFunction(options)) {\n    resultSelector = options;\n    options = undefined;\n  }\n  if (resultSelector) {\n    return fromEvent<T>(target, eventName, options as EventListenerOptions).pipe(mapOneOrManyArgs(resultSelector));\n  }\n\n  // Figure out our add and remove methods. In order to do this,\n  // we are going to analyze the target in a preferred order, if\n  // the target matches a given signature, we take the two \"add\" and \"remove\"\n  // method names and apply them to a map to create opposite versions of the\n  // same function. This is because they all operate in duplicate pairs,\n  // `addListener(name, handler)`, `removeListener(name, handler)`, for example.\n  // The call only differs by method name, as to whether or not you're adding or removing.\n  const [add, remove] =\n    // If it is an EventTarget, we need to use a slightly different method than the other two patterns.\n    isEventTarget(target)\n      ? eventTargetMethods.map(\n          methodName => (handler: any) => target[methodName](eventName, handler, options as EventListenerOptions),\n        )\n      : // In all other cases, the call pattern is identical with the exception of the method names.\n      isNodeStyleEventEmitter(target)\n      ? nodeEventEmitterMethods.map(toCommonHandlerRegistry(target, eventName))\n      : isJQueryStyleEventEmitter(target)\n      ? jqueryMethods.map(toCommonHandlerRegistry(target, eventName))\n      : [];\n\n  // If add is falsy, it's because we didn't match a pattern above.\n  // Check to see if it is an ArrayLike, because if it is, we want to\n  // try to apply fromEvent to all of it's items. We do this check last,\n  // because there are may be some types that are both ArrayLike *and* implement\n  // event registry points, and we'd rather delegate to that when possible.\n  if (!add) {\n    if (isArrayLike(target)) {\n      return mergeMap((subTarget: any) => fromEvent(subTarget, eventName, options as EventListenerOptions))(\n        innerFrom(target),\n      ) as Observable<T>;\n    }\n  }\n\n  // If add is falsy and we made it here, it's because we didn't\n  // match any valid target objects above.\n  if (!add) {\n    throw new TypeError('Invalid event target');\n  }\n\n  return new Observable<T>(subscriber => {\n    // The handler we are going to register. Forwards the event object, by itself, or\n    // an array of arguments to the event handler, if there is more than one argument,\n    // to the consumer.\n    const handler = (...args: any[]) => subscriber.next(1 < args.length ? args : args[0]);\n    // Do the work of adding the handler to the target.\n    add(handler);\n    // When we finalize, we want to remove the handler and free up memory.\n    return () => remove!(handler);\n  });\n}\n\n/**\n * Used to create `add` and `remove` functions to register and unregister event handlers\n * from a target in the most common handler pattern, where there are only two arguments.\n * (e.g.  `on(name, fn)`, `off(name, fn)`, `addListener(name, fn)`, or `removeListener(name, fn)`)\n * @param target The target we're calling methods on\n * @param eventName The event name for the event we're creating register or unregister functions for\n */\nfunction toCommonHandlerRegistry(target: any, eventName: string) {\n  return (methodName: string) => (handler: any) => target[methodName](eventName, handler);\n}\n\n/**\n * Checks to see if the target implements the required node-style EventEmitter methods\n * for adding and removing event handlers.\n * @param target the object to check\n */\nfunction isNodeStyleEventEmitter(target: any): target is NodeStyleEventEmitter {\n  return isFunction(target.addListener) && isFunction(target.removeListener);\n}\n\n/**\n * Checks to see if the target implements the required jQuery-style EventEmitter methods\n * for adding and removing event handlers.\n * @param target the object to check\n */\nfunction isJQueryStyleEventEmitter(target: any): target is JQueryStyleEventEmitter<any, any> {\n  return isFunction(target.on) && isFunction(target.off);\n}\n\n/**\n * Checks to see if the target implements the required EventTarget methods\n * for adding and removing event handlers.\n * @param target the object to check\n */\nfunction isEventTarget(target: any): target is HasEventTargetAddRemove<any> {\n  return isFunction(target.addEventListener) && isFunction(target.removeEventListener);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/fromEventPattern.ts",
    "content": "import { Observable } from '../Observable';\nimport { isFunction } from '../util/isFunction';\nimport { NodeEventHandler } from './fromEvent';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\n\n/* tslint:disable:max-line-length */\nexport function fromEventPattern<T>(\n  addHandler: (handler: NodeEventHandler) => any,\n  removeHandler?: (handler: NodeEventHandler, signal?: any) => void\n): Observable<T>;\nexport function fromEventPattern<T>(\n  addHandler: (handler: NodeEventHandler) => any,\n  removeHandler?: (handler: NodeEventHandler, signal?: any) => void,\n  resultSelector?: (...args: any[]) => T\n): Observable<T>;\n/* tslint:enable:max-line-length */\n\n/**\n * Creates an Observable from an arbitrary API for registering event handlers.\n *\n * <span class=\"informal\">When that method for adding event handler was something {@link fromEvent}\n * was not prepared for.</span>\n *\n * ![](fromEventPattern.png)\n *\n * `fromEventPattern` allows you to convert into an Observable any API that supports registering handler functions\n * for events. It is similar to {@link fromEvent}, but far\n * more flexible. In fact, all use cases of {@link fromEvent} could be easily handled by\n * `fromEventPattern` (although in slightly more verbose way).\n *\n * This operator accepts as a first argument an `addHandler` function, which will be injected with\n * handler parameter. That handler is actually an event handler function that you now can pass\n * to API expecting it. `addHandler` will be called whenever Observable\n * returned by the operator is subscribed, so registering handler in API will not\n * necessarily happen when `fromEventPattern` is called.\n *\n * After registration, every time an event that we listen to happens,\n * Observable returned by `fromEventPattern` will emit value that event handler\n * function was called with. Note that if event handler was called with more\n * than one argument, second and following arguments will not appear in the Observable.\n *\n * If API you are using allows to unregister event handlers as well, you can pass to `fromEventPattern`\n * another function - `removeHandler` - as a second parameter. It will be injected\n * with the same handler function as before, which now you can use to unregister\n * it from the API. `removeHandler` will be called when consumer of resulting Observable\n * unsubscribes from it.\n *\n * In some APIs unregistering is actually handled differently. Method registering an event handler\n * returns some kind of token, which is later used to identify which function should\n * be unregistered or it itself has method that unregisters event handler.\n * If that is the case with your API, make sure token returned\n * by registering method is returned by `addHandler`. Then it will be passed\n * as a second argument to `removeHandler`, where you will be able to use it.\n *\n * If you need access to all event handler parameters (not only the first one),\n * or you need to transform them in any way, you can call `fromEventPattern` with optional\n * third parameter - project function which will accept all arguments passed to\n * event handler when it is called. Whatever is returned from project function will appear on\n * resulting stream instead of usual event handlers first argument. This means\n * that default project can be thought of as function that takes its first parameter\n * and ignores the rest.\n *\n * ## Examples\n *\n * Emits clicks happening on the DOM document\n *\n * ```ts\n * import { fromEventPattern } from 'valdi_rxjs';\n *\n * function addClickHandler(handler) {\n *   document.addEventListener('click', handler);\n * }\n *\n * function removeClickHandler(handler) {\n *   document.removeEventListener('click', handler);\n * }\n *\n * const clicks = fromEventPattern(\n *   addClickHandler,\n *   removeClickHandler\n * );\n * clicks.subscribe(x => console.log(x));\n *\n * // Whenever you click anywhere in the browser, DOM MouseEvent\n * // object will be logged.\n * ```\n *\n * Use with API that returns cancellation token\n *\n * ```ts\n * import { fromEventPattern } from 'valdi_rxjs';\n *\n * const token = someAPI.registerEventHandler(function() {});\n * someAPI.unregisterEventHandler(token); // this APIs cancellation method accepts\n *                                        // not handler itself, but special token.\n *\n * const someAPIObservable = fromEventPattern(\n *   function(handler) { return someAPI.registerEventHandler(handler); }, // Note that we return the token here...\n *   function(handler, token) { someAPI.unregisterEventHandler(token); }  // ...to then use it here.\n * );\n * ```\n *\n * Use with project function\n *\n * ```ts\n * import { fromEventPattern } from 'valdi_rxjs';\n *\n * someAPI.registerEventHandler((eventType, eventMessage) => {\n *   console.log(eventType, eventMessage); // Logs 'EVENT_TYPE' 'EVENT_MESSAGE' to console.\n * });\n *\n * const someAPIObservable = fromEventPattern(\n *   handler => someAPI.registerEventHandler(handler),\n *   handler => someAPI.unregisterEventHandler(handler)\n *   (eventType, eventMessage) => eventType + ' --- ' + eventMessage // without that function only 'EVENT_TYPE'\n * );                                                                // would be emitted by the Observable\n *\n * someAPIObservable.subscribe(value => console.log(value));\n *\n * // Logs:\n * // 'EVENT_TYPE --- EVENT_MESSAGE'\n * ```\n *\n * @see {@link fromEvent}\n * @see {@link bindCallback}\n * @see {@link bindNodeCallback}\n *\n * @param {function(handler: Function): any} addHandler A function that takes\n * a `handler` function as argument and attaches it somehow to the actual\n * source of events.\n * @param {function(handler: Function, token?: any): void} [removeHandler] A function that\n * takes a `handler` function as an argument and removes it from the event source. If `addHandler`\n * returns some kind of token, `removeHandler` function will have it as a second parameter.\n * @param {function(...args: any): T} [project] A function to\n * transform results. It takes the arguments from the event handler and\n * should return a single value.\n * @return {Observable<T>} Observable which, when an event happens, emits first parameter\n * passed to registered event handler. Alternatively it emits whatever project function returns\n * at that moment.\n */\nexport function fromEventPattern<T>(\n  addHandler: (handler: NodeEventHandler) => any,\n  removeHandler?: (handler: NodeEventHandler, signal?: any) => void,\n  resultSelector?: (...args: any[]) => T\n): Observable<T | T[]> {\n  if (resultSelector) {\n    return fromEventPattern<T>(addHandler, removeHandler).pipe(mapOneOrManyArgs(resultSelector));\n  }\n\n  return new Observable<T | T[]>((subscriber) => {\n    const handler = (...e: T[]) => subscriber.next(e.length === 1 ? e[0] : e);\n    const retValue = addHandler(handler);\n    return isFunction(removeHandler) ? () => removeHandler(handler, retValue) : undefined;\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/fromSubscribable.ts",
    "content": "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { Subscribable } from '../types';\n\n/**\n * Used to convert a subscribable to an observable.\n *\n * Currently, this is only used within internals.\n *\n * TODO: Discuss ObservableInput supporting \"Subscribable\".\n * https://github.com/ReactiveX/rxjs/issues/5909\n *\n * @param subscribable A subscribable\n */\nexport function fromSubscribable<T>(subscribable: Subscribable<T>) {\n  return new Observable((subscriber: Subscriber<T>) => subscribable.subscribe(subscriber));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/generate.ts",
    "content": "import { Observable } from '../Observable';\nimport { identity } from '../util/identity';\nimport { ObservableInput, SchedulerLike } from '../types';\nimport { isScheduler } from '../util/isScheduler';\nimport { defer } from './defer';\nimport { scheduleIterable } from '../scheduled/scheduleIterable';\n\ntype ConditionFunc<S> = (state: S) => boolean;\ntype IterateFunc<S> = (state: S) => S;\ntype ResultFunc<S, T> = (state: S) => T;\n\nexport interface GenerateBaseOptions<S> {\n  /**\n   * Initial state.\n   */\n  initialState: S;\n  /**\n   * Condition function that accepts state and returns boolean.\n   * When it returns false, the generator stops.\n   * If not specified, a generator never stops.\n   */\n  condition?: ConditionFunc<S>;\n  /**\n   * Iterate function that accepts state and returns new state.\n   */\n  iterate: IterateFunc<S>;\n  /**\n   * SchedulerLike to use for generation process.\n   * By default, a generator starts immediately.\n   */\n  scheduler?: SchedulerLike;\n}\n\nexport interface GenerateOptions<T, S> extends GenerateBaseOptions<S> {\n  /**\n   * Result selection function that accepts state and returns a value to emit.\n   */\n  resultSelector: ResultFunc<S, T>;\n}\n\n/**\n * Generates an observable sequence by running a state-driven loop\n * producing the sequence's elements, using the specified scheduler\n * to send out observer messages.\n *\n * ![](generate.png)\n *\n * ## Examples\n *\n * Produces sequence of numbers\n *\n * ```ts\n * import { generate } from 'valdi_rxjs';\n *\n * const result = generate(0, x => x < 3, x => x + 1, x => x);\n *\n * result.subscribe(x => console.log(x));\n *\n * // Logs:\n * // 0\n * // 1\n * // 2\n * ```\n *\n * Use `asapScheduler`\n *\n * ```ts\n * import { generate, asapScheduler } from 'valdi_rxjs';\n *\n * const result = generate(1, x => x < 5, x => x * 2, x => x + 1, asapScheduler);\n *\n * result.subscribe(x => console.log(x));\n *\n * // Logs:\n * // 2\n * // 3\n * // 5\n * ```\n *\n * @see {@link from}\n * @see {@link Observable}\n *\n * @param {S} initialState Initial state.\n * @param {function (state: S): boolean} condition Condition to terminate generation (upon returning false).\n * @param {function (state: S): S} iterate Iteration step function.\n * @param {function (state: S): T} resultSelector Selector function for results produced in the sequence. (deprecated)\n * @param {SchedulerLike} [scheduler] A {@link SchedulerLike} on which to run the generator loop. If not provided, defaults to emit immediately.\n * @returns {Observable<T>} The generated sequence.\n * @deprecated Instead of passing separate arguments, use the options argument. Signatures taking separate arguments will be removed in v8.\n */\nexport function generate<T, S>(\n  initialState: S,\n  condition: ConditionFunc<S>,\n  iterate: IterateFunc<S>,\n  resultSelector: ResultFunc<S, T>,\n  scheduler?: SchedulerLike\n): Observable<T>;\n\n/**\n * Generates an Observable by running a state-driven loop\n * that emits an element on each iteration.\n *\n * <span class=\"informal\">Use it instead of nexting values in a for loop.</span>\n *\n * ![](generate.png)\n *\n * `generate` allows you to create a stream of values generated with a loop very similar to\n * a traditional for loop. The first argument of `generate` is a beginning value. The second argument\n * is a function that accepts this value and tests if some condition still holds. If it does,\n * then the loop continues, if not, it stops. The third value is a function which takes the\n * previously defined value and modifies it in some way on each iteration. Note how these three parameters\n * are direct equivalents of three expressions in a traditional for loop: the first expression\n * initializes some state (for example, a numeric index), the second tests if the loop can perform the next\n * iteration (for example, if the index is lower than 10) and the third states how the defined value\n * will be modified on every step (for example, the index will be incremented by one).\n *\n * Return value of a `generate` operator is an Observable that on each loop iteration\n * emits a value. First of all, the condition function is ran. If it returns true, then the Observable\n * emits the currently stored value (initial value at the first iteration) and finally updates\n * that value with iterate function. If at some point the condition returns false, then the Observable\n * completes at that moment.\n *\n * Optionally you can pass a fourth parameter to `generate` - a result selector function which allows you\n * to immediately map the value that would normally be emitted by an Observable.\n *\n * If you find three anonymous functions in `generate` call hard to read, you can provide\n * a single object to the operator instead where the object has the properties: `initialState`,\n * `condition`, `iterate` and `resultSelector`, which should have respective values that you\n * would normally pass to `generate`. `resultSelector` is still optional, but that form\n * of calling `generate` allows you to omit `condition` as well. If you omit it, that means\n * condition always holds, or in other words the resulting Observable will never complete.\n *\n * Both forms of `generate` can optionally accept a scheduler. In case of a multi-parameter call,\n * scheduler simply comes as a last argument (no matter if there is a `resultSelector`\n * function or not). In case of a single-parameter call, you can provide it as a\n * `scheduler` property on the object passed to the operator. In both cases, a scheduler decides when\n * the next iteration of the loop will happen and therefore when the next value will be emitted\n * by the Observable. For example, to ensure that each value is pushed to the Observer\n * on a separate task in the event loop, you could use the `async` scheduler. Note that\n * by default (when no scheduler is passed) values are simply emitted synchronously.\n *\n *\n * ## Examples\n *\n * Use with condition and iterate functions\n *\n * ```ts\n * import { generate } from 'valdi_rxjs';\n *\n * const result = generate(0, x => x < 3, x => x + 1);\n *\n * result.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('Complete!')\n * });\n *\n * // Logs:\n * // 0\n * // 1\n * // 2\n * // 'Complete!'\n * ```\n *\n * Use with condition, iterate and resultSelector functions\n *\n * ```ts\n * import { generate } from 'valdi_rxjs';\n *\n * const result = generate(0, x => x < 3, x => x + 1, x => x * 1000);\n *\n * result.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('Complete!')\n * });\n *\n * // Logs:\n * // 0\n * // 1000\n * // 2000\n * // 'Complete!'\n * ```\n *\n * Use with options object\n *\n * ```ts\n * import { generate } from 'valdi_rxjs';\n *\n * const result = generate({\n *   initialState: 0,\n *   condition(value) { return value < 3; },\n *   iterate(value) { return value + 1; },\n *   resultSelector(value) { return value * 1000; }\n * });\n *\n * result.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('Complete!')\n * });\n *\n * // Logs:\n * // 0\n * // 1000\n * // 2000\n * // 'Complete!'\n * ```\n *\n * Use options object without condition function\n *\n * ```ts\n * import { generate } from 'valdi_rxjs';\n *\n * const result = generate({\n *   initialState: 0,\n *   iterate(value) { return value + 1; },\n *   resultSelector(value) { return value * 1000; }\n * });\n *\n * result.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('Complete!') // This will never run\n * });\n *\n * // Logs:\n * // 0\n * // 1000\n * // 2000\n * // 3000\n * // ...and never stops.\n * ```\n *\n * @see {@link from}\n *\n * @param {S} initialState Initial state.\n * @param {function (state: S): boolean} condition Condition to terminate generation (upon returning false).\n * @param {function (state: S): S} iterate Iteration step function.\n * @param {function (state: S): T} [resultSelector] Selector function for results produced in the sequence.\n * @param {Scheduler} [scheduler] A {@link Scheduler} on which to run the generator loop. If not provided, defaults to emitting immediately.\n * @return {Observable<T>} The generated sequence.\n * @deprecated Instead of passing separate arguments, use the options argument. Signatures taking separate arguments will be removed in v8.\n */\nexport function generate<S>(\n  initialState: S,\n  condition: ConditionFunc<S>,\n  iterate: IterateFunc<S>,\n  scheduler?: SchedulerLike\n): Observable<S>;\n\n/**\n * Generates an observable sequence by running a state-driven loop\n * producing the sequence's elements, using the specified scheduler\n * to send out observer messages.\n * The overload accepts options object that might contain initial state, iterate,\n * condition and scheduler.\n *\n * ![](generate.png)\n *\n * ## Examples\n *\n * Use options object with condition function\n *\n * ```ts\n * import { generate } from 'valdi_rxjs';\n *\n * const result = generate({\n *   initialState: 0,\n *   condition: x => x < 3,\n *   iterate: x => x + 1\n * });\n *\n * result.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('Complete!')\n * });\n *\n * // Logs:\n * // 0\n * // 1\n * // 2\n * // 'Complete!'\n * ```\n *\n * @see {@link from}\n * @see {@link Observable}\n *\n * @param {GenerateBaseOptions<S>} options Object that must contain initialState, iterate and might contain condition and scheduler.\n * @returns {Observable<S>} The generated sequence.\n */\nexport function generate<S>(options: GenerateBaseOptions<S>): Observable<S>;\n\n/**\n * Generates an observable sequence by running a state-driven loop\n * producing the sequence's elements, using the specified scheduler\n * to send out observer messages.\n * The overload accepts options object that might contain initial state, iterate,\n * condition, result selector and scheduler.\n *\n * ![](generate.png)\n *\n * ## Examples\n *\n * Use options object with condition and iterate function\n *\n * ```ts\n * import { generate } from 'valdi_rxjs';\n *\n * const result = generate({\n *   initialState: 0,\n *   condition: x => x < 3,\n *   iterate: x => x + 1,\n *   resultSelector: x => x\n * });\n *\n * result.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('Complete!')\n * });\n *\n * // Logs:\n * // 0\n * // 1\n * // 2\n * // 'Complete!'\n * ```\n *\n * @see {@link from}\n * @see {@link Observable}\n *\n * @param {GenerateOptions<T, S>} options Object that must contain initialState, iterate, resultSelector and might contain condition and scheduler.\n * @returns {Observable<T>} The generated sequence.\n */\nexport function generate<T, S>(options: GenerateOptions<T, S>): Observable<T>;\n\nexport function generate<T, S>(\n  initialStateOrOptions: S | GenerateOptions<T, S>,\n  condition?: ConditionFunc<S>,\n  iterate?: IterateFunc<S>,\n  resultSelectorOrScheduler?: ResultFunc<S, T> | SchedulerLike,\n  scheduler?: SchedulerLike\n): Observable<T> {\n  let resultSelector: ResultFunc<S, T>;\n  let initialState: S;\n\n  // TODO: Remove this as we move away from deprecated signatures\n  // and move towards a configuration object argument.\n  if (arguments.length === 1) {\n    // If we only have one argument, we can assume it is a configuration object.\n    // Note that folks not using TypeScript may trip over this.\n    ({\n      initialState,\n      condition,\n      iterate,\n      resultSelector = identity as ResultFunc<S, T>,\n      scheduler,\n    } = initialStateOrOptions as GenerateOptions<T, S>);\n  } else {\n    // Deprecated arguments path. Figure out what the user\n    // passed and set it here.\n    initialState = initialStateOrOptions as S;\n    if (!resultSelectorOrScheduler || isScheduler(resultSelectorOrScheduler)) {\n      resultSelector = identity as ResultFunc<S, T>;\n      scheduler = resultSelectorOrScheduler as SchedulerLike;\n    } else {\n      resultSelector = resultSelectorOrScheduler as ResultFunc<S, T>;\n    }\n  }\n\n  // The actual generator used to \"generate\" values.\n  function* gen() {\n    for (let state = initialState; !condition || condition(state); state = iterate!(state)) {\n      yield resultSelector(state);\n    }\n  }\n\n  // We use `defer` because we want to defer the creation of the iterator from the iterable.\n  return defer(\n    (scheduler\n      ? // If a scheduler was provided, use `scheduleIterable` to ensure that iteration/generation\n        // happens on the scheduler.\n        () => scheduleIterable(gen(), scheduler!)\n      : // Otherwise, if there's no scheduler, we can just use the generator function directly in\n        // `defer` and executing it will return the generator (which is iterable).\n        gen) as () => ObservableInput<T>\n  );\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/iif.ts",
    "content": "import { Observable } from '../Observable';\nimport { defer } from './defer';\nimport { ObservableInput } from '../types';\n\n/**\n * Checks a boolean at subscription time, and chooses between one of two observable sources\n *\n * `iif` expects a function that returns a boolean (the `condition` function), and two sources,\n * the `trueResult` and the `falseResult`, and returns an Observable.\n *\n * At the moment of subscription, the `condition` function is called. If the result is `true`, the\n * subscription will be to the source passed as the `trueResult`, otherwise, the subscription will be\n * to the source passed as the `falseResult`.\n *\n * If you need to check more than two options to choose between more than one observable, have a look at the {@link defer} creation method.\n *\n * ## Examples\n *\n * Change at runtime which Observable will be subscribed\n *\n * ```ts\n * import { iif, of } from 'valdi_rxjs';\n *\n * let subscribeToFirst;\n * const firstOrSecond = iif(\n *   () => subscribeToFirst,\n *   of('first'),\n *   of('second')\n * );\n *\n * subscribeToFirst = true;\n * firstOrSecond.subscribe(value => console.log(value));\n *\n * // Logs:\n * // 'first'\n *\n * subscribeToFirst = false;\n * firstOrSecond.subscribe(value => console.log(value));\n *\n * // Logs:\n * // 'second'\n * ```\n *\n * Control access to an Observable\n *\n * ```ts\n * import { iif, of, EMPTY } from 'valdi_rxjs';\n *\n * let accessGranted;\n * const observableIfYouHaveAccess = iif(\n *   () => accessGranted,\n *   of('It seems you have an access...'),\n *   EMPTY\n * );\n *\n * accessGranted = true;\n * observableIfYouHaveAccess.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('The end')\n * });\n *\n * // Logs:\n * // 'It seems you have an access...'\n * // 'The end'\n *\n * accessGranted = false;\n * observableIfYouHaveAccess.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('The end')\n * });\n *\n * // Logs:\n * // 'The end'\n * ```\n *\n * @see {@link defer}\n *\n * @param condition Condition which Observable should be chosen.\n * @param trueResult An Observable that will be subscribed if condition is true.\n * @param falseResult An Observable that will be subscribed if condition is false.\n * @return An observable that proxies to `trueResult` or `falseResult`, depending on the result of the `condition` function.\n */\nexport function iif<T, F>(condition: () => boolean, trueResult: ObservableInput<T>, falseResult: ObservableInput<F>): Observable<T | F> {\n  return defer(() => (condition() ? trueResult : falseResult));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/innerFrom.ts",
    "content": "import { isArrayLike } from '../util/isArrayLike';\nimport { isPromise } from '../util/isPromise';\nimport { Observable } from '../Observable';\nimport { ObservableInput, ReadableStreamLike } from '../types';\nimport { isInteropObservable } from '../util/isInteropObservable';\nimport { isAsyncIterable } from '../util/isAsyncIterable';\nimport { createInvalidObservableTypeError } from '../util/throwUnobservableError';\nimport { isIterable } from '../util/isIterable';\nimport { isReadableStreamLike, readableStreamLikeToAsyncGenerator } from '../util/isReadableStreamLike';\nimport { Subscriber } from '../Subscriber';\nimport { isFunction } from '../util/isFunction';\nimport { reportUnhandledError } from '../util/reportUnhandledError';\nimport { observable as Symbol_observable } from '../symbol/observable';\n\nexport function innerFrom<T>(input: ObservableInput<T>): Observable<T> {\n  if (input instanceof Observable) {\n    return input;\n  }\n  if (input != null) {\n    if (isInteropObservable(input)) {\n      return fromInteropObservable(input);\n    }\n    if (isArrayLike(input)) {\n      return fromArrayLike(input);\n    }\n    if (isPromise(input)) {\n      return fromPromise(input);\n    }\n    if (isAsyncIterable(input)) {\n      return fromAsyncIterable(input);\n    }\n    if (isIterable(input)) {\n      return fromIterable(input);\n    }\n    if (isReadableStreamLike(input)) {\n      return fromReadableStreamLike(input);\n    }\n  }\n\n  throw createInvalidObservableTypeError(input);\n}\n\n/**\n * Creates an RxJS Observable from an object that implements `Symbol.observable`.\n * @param obj An object that properly implements `Symbol.observable`.\n */\nexport function fromInteropObservable<T>(obj: any) {\n  return new Observable((subscriber: Subscriber<T>) => {\n    const obs = obj[Symbol_observable]();\n    if (isFunction(obs.subscribe)) {\n      return obs.subscribe(subscriber);\n    }\n    // Should be caught by observable subscribe function error handling.\n    throw new TypeError('Provided object does not correctly implement Symbol.observable');\n  });\n}\n\n/**\n * Synchronously emits the values of an array like and completes.\n * This is exported because there are creation functions and operators that need to\n * make direct use of the same logic, and there's no reason to make them run through\n * `from` conditionals because we *know* they're dealing with an array.\n * @param array The array to emit values from\n */\nexport function fromArrayLike<T>(array: ArrayLike<T>) {\n  return new Observable((subscriber: Subscriber<T>) => {\n    // Loop over the array and emit each value. Note two things here:\n    // 1. We're making sure that the subscriber is not closed on each loop.\n    //    This is so we don't continue looping over a very large array after\n    //    something like a `take`, `takeWhile`, or other synchronous unsubscription\n    //    has already unsubscribed.\n    // 2. In this form, reentrant code can alter that array we're looping over.\n    //    This is a known issue, but considered an edge case. The alternative would\n    //    be to copy the array before executing the loop, but this has\n    //    performance implications.\n    for (let i = 0; i < array.length && !subscriber.closed; i++) {\n      subscriber.next(array[i]);\n    }\n    subscriber.complete();\n  });\n}\n\nexport function fromPromise<T>(promise: PromiseLike<T>) {\n  return new Observable((subscriber: Subscriber<T>) => {\n    promise\n      .then(\n        (value) => {\n          if (!subscriber.closed) {\n            subscriber.next(value);\n            subscriber.complete();\n          }\n        },\n        (err: any) => subscriber.error(err)\n      )\n      .then(null, reportUnhandledError);\n  });\n}\n\nexport function fromIterable<T>(iterable: Iterable<T>) {\n  return new Observable((subscriber: Subscriber<T>) => {\n    for (const value of Array.from(iterable)) {\n      subscriber.next(value);\n      if (subscriber.closed) {\n        return;\n      }\n    }\n    subscriber.complete();\n  });\n}\n\nexport function fromAsyncIterable<T>(asyncIterable: AsyncIterable<T>) {\n  return new Observable((subscriber: Subscriber<T>) => {\n    process(asyncIterable, subscriber).catch((err) => subscriber.error(err));\n  });\n}\n\nexport function fromReadableStreamLike<T>(readableStream: ReadableStreamLike<T>) {\n  return fromAsyncIterable(readableStreamLikeToAsyncGenerator(readableStream));\n}\n\nasync function process<T>(asyncIterable: AsyncIterable<T>, subscriber: Subscriber<T>) {\n  for await (const value of asyncIterable) {\n    subscriber.next(value);\n    // A side-effect may have closed our subscriber,\n    // check before the next iteration.\n    if (subscriber.closed) {\n      return;\n    }\n  }\n  subscriber.complete();\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/interval.ts",
    "content": "import { Observable } from '../Observable';\nimport { asyncScheduler } from '../scheduler/async';\nimport { SchedulerLike } from '../types';\nimport { timer } from './timer';\n\n/**\n * Creates an Observable that emits sequential numbers every specified\n * interval of time, on a specified {@link SchedulerLike}.\n *\n * <span class=\"informal\">Emits incremental numbers periodically in time.</span>\n *\n * ![](interval.png)\n *\n * `interval` returns an Observable that emits an infinite sequence of\n * ascending integers, with a constant interval of time of your choosing\n * between those emissions. The first emission is not sent immediately, but\n * only after the first period has passed. By default, this operator uses the\n * `async` {@link SchedulerLike} to provide a notion of time, but you may pass any\n * {@link SchedulerLike} to it.\n *\n * ## Example\n *\n * Emits ascending numbers, one every second (1000ms) up to the number 3\n *\n * ```ts\n * import { interval, take } from 'valdi_rxjs';\n *\n * const numbers = interval(1000);\n *\n * const takeFourNumbers = numbers.pipe(take(4));\n *\n * takeFourNumbers.subscribe(x => console.log('Next: ', x));\n *\n * // Logs:\n * // Next: 0\n * // Next: 1\n * // Next: 2\n * // Next: 3\n * ```\n *\n * @see {@link timer}\n * @see {@link delay}\n *\n * @param {number} [period=0] The interval size in milliseconds (by default)\n * or the time unit determined by the scheduler's clock.\n * @param {SchedulerLike} [scheduler=async] The {@link SchedulerLike} to use for scheduling\n * the emission of values, and providing a notion of \"time\".\n * @return {Observable} An Observable that emits a sequential number each time\n * interval.\n */\nexport function interval(period = 0, scheduler: SchedulerLike = asyncScheduler): Observable<number> {\n  if (period < 0) {\n    // We cannot schedule an interval in the past.\n    period = 0;\n  }\n\n  return timer(period, period, scheduler);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/merge.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservableInput, ObservableInputTuple, SchedulerLike } from '../types';\nimport { mergeAll } from '../operators/mergeAll';\nimport { innerFrom } from './innerFrom';\nimport { EMPTY } from './empty';\nimport { popNumber, popScheduler } from '../util/args';\nimport { from } from './from';\n\nexport function merge<A extends readonly unknown[]>(...sources: [...ObservableInputTuple<A>]): Observable<A[number]>;\nexport function merge<A extends readonly unknown[]>(...sourcesAndConcurrency: [...ObservableInputTuple<A>, number?]): Observable<A[number]>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled` and `mergeAll`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function merge<A extends readonly unknown[]>(\n  ...sourcesAndScheduler: [...ObservableInputTuple<A>, SchedulerLike?]\n): Observable<A[number]>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled` and `mergeAll`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function merge<A extends readonly unknown[]>(\n  ...sourcesAndConcurrencyAndScheduler: [...ObservableInputTuple<A>, number?, SchedulerLike?]\n): Observable<A[number]>;\n\n/**\n * Creates an output Observable which concurrently emits all values from every\n * given input Observable.\n *\n * <span class=\"informal\">Flattens multiple Observables together by blending\n * their values into one Observable.</span>\n *\n * ![](merge.png)\n *\n * `merge` subscribes to each given input Observable (as arguments), and simply\n * forwards (without doing any transformation) all the values from all the input\n * Observables to the output Observable. The output Observable only completes\n * once all input Observables have completed. Any error delivered by an input\n * Observable will be immediately emitted on the output Observable.\n *\n * ## Examples\n *\n * Merge together two Observables: 1s interval and clicks\n *\n * ```ts\n * import { merge, fromEvent, interval } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const timer = interval(1000);\n * const clicksOrTimer = merge(clicks, timer);\n * clicksOrTimer.subscribe(x => console.log(x));\n *\n * // Results in the following:\n * // timer will emit ascending values, one every second(1000ms) to console\n * // clicks logs MouseEvents to console everytime the \"document\" is clicked\n * // Since the two streams are merged you see these happening\n * // as they occur.\n * ```\n *\n * Merge together 3 Observables, but run only 2 concurrently\n *\n * ```ts\n * import { interval, take, merge } from 'valdi_rxjs';\n *\n * const timer1 = interval(1000).pipe(take(10));\n * const timer2 = interval(2000).pipe(take(6));\n * const timer3 = interval(500).pipe(take(10));\n *\n * const concurrent = 2; // the argument\n * const merged = merge(timer1, timer2, timer3, concurrent);\n * merged.subscribe(x => console.log(x));\n *\n * // Results in the following:\n * // - First timer1 and timer2 will run concurrently\n * // - timer1 will emit a value every 1000ms for 10 iterations\n * // - timer2 will emit a value every 2000ms for 6 iterations\n * // - after timer1 hits its max iteration, timer2 will\n * //   continue, and timer3 will start to run concurrently with timer2\n * // - when timer2 hits its max iteration it terminates, and\n * //   timer3 will continue to emit a value every 500ms until it is complete\n * ```\n *\n * @see {@link mergeAll}\n * @see {@link mergeMap}\n * @see {@link mergeMapTo}\n * @see {@link mergeScan}\n *\n * @param {...ObservableInput} observables Input Observables to merge together.\n * @param {number} [concurrent=Infinity] Maximum number of input\n * Observables being subscribed to concurrently.\n * @param {SchedulerLike} [scheduler=null] The {@link SchedulerLike} to use for managing\n * concurrency of input Observables.\n * @return {Observable} an Observable that emits items that are the result of\n * every input Observable.\n */\nexport function merge(...args: (ObservableInput<unknown> | number | SchedulerLike)[]): Observable<unknown> {\n  const scheduler = popScheduler(args);\n  const concurrent = popNumber(args, Infinity);\n  const sources = args as ObservableInput<unknown>[];\n  return !sources.length\n    ? // No source provided\n      EMPTY\n    : sources.length === 1\n    ? // One source? Just return it.\n      innerFrom(sources[0])\n    : // Merge all sources\n      mergeAll(concurrent)(from(sources, scheduler));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/never.ts",
    "content": "import { Observable } from '../Observable';\nimport { noop } from '../util/noop';\n\n/**\n * An Observable that emits no items to the Observer and never completes.\n *\n * ![](never.png)\n *\n * A simple Observable that emits neither values nor errors nor the completion\n * notification. It can be used for testing purposes or for composing with other\n * Observables. Please note that by never emitting a complete notification, this\n * Observable keeps the subscription from being disposed automatically.\n * Subscriptions need to be manually disposed.\n *\n * ##  Example\n *\n * Emit the number 7, then never emit anything else (not even complete)\n *\n * ```ts\n * import { NEVER, startWith } from 'valdi_rxjs';\n *\n * const info = () => console.log('Will not be called');\n *\n * const result = NEVER.pipe(startWith(7));\n * result.subscribe({\n *   next: x => console.log(x),\n *   error: info,\n *   complete: info\n * });\n * ```\n *\n * @see {@link Observable}\n * @see {@link EMPTY}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const NEVER = new Observable<never>(noop);\n\n/**\n * @deprecated Replaced with the {@link NEVER} constant. Will be removed in v8.\n */\nexport function never() {\n  return NEVER;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/of.ts",
    "content": "import { SchedulerLike, ValueFromArray } from '../types';\nimport { Observable } from '../Observable';\nimport { popScheduler } from '../util/args';\nimport { from } from './from';\n\n// Devs are more likely to pass null or undefined than they are a scheduler\n// without accompanying values. To make things easier for (naughty) devs who\n// use the `strictNullChecks: false` TypeScript compiler option, these\n// overloads with explicit null and undefined values are included.\n\nexport function of(value: null): Observable<null>;\nexport function of(value: undefined): Observable<undefined>;\n\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function of(scheduler: SchedulerLike): Observable<never>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function of<A extends readonly unknown[]>(...valuesAndScheduler: [...A, SchedulerLike]): Observable<ValueFromArray<A>>;\n\nexport function of(): Observable<never>;\n/** @deprecated Do not specify explicit type parameters. Signatures with type parameters that cannot be inferred will be removed in v8. */\nexport function of<T>(): Observable<T>;\nexport function of<T>(value: T): Observable<T>;\nexport function of<A extends readonly unknown[]>(...values: A): Observable<ValueFromArray<A>>;\n\n/**\n * Converts the arguments to an observable sequence.\n *\n * <span class=\"informal\">Each argument becomes a `next` notification.</span>\n *\n * ![](of.png)\n *\n * Unlike {@link from}, it does not do any flattening and emits each argument in whole\n * as a separate `next` notification.\n *\n * ## Examples\n *\n * Emit the values `10, 20, 30`\n *\n * ```ts\n * import { of } from 'valdi_rxjs';\n *\n * of(10, 20, 30)\n *   .subscribe({\n *     next: value => console.log('next:', value),\n *     error: err => console.log('error:', err),\n *     complete: () => console.log('the end'),\n *   });\n *\n * // Outputs\n * // next: 10\n * // next: 20\n * // next: 30\n * // the end\n * ```\n *\n * Emit the array `[1, 2, 3]`\n *\n * ```ts\n * import { of } from 'valdi_rxjs';\n *\n * of([1, 2, 3])\n *   .subscribe({\n *     next: value => console.log('next:', value),\n *     error: err => console.log('error:', err),\n *     complete: () => console.log('the end'),\n *   });\n *\n * // Outputs\n * // next: [1, 2, 3]\n * // the end\n * ```\n *\n * @see {@link from}\n * @see {@link range}\n *\n * @param {...T} values A comma separated list of arguments you want to be emitted\n * @return {Observable} An Observable that emits the arguments\n * described above and then completes.\n */\nexport function of<T>(...args: Array<T | SchedulerLike>): Observable<T> {\n  const scheduler = popScheduler(args);\n  return from(args as T[], scheduler);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/onErrorResumeNext.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservableInputTuple } from '../types';\nimport { EMPTY } from './empty';\nimport { onErrorResumeNext as onErrorResumeNextWith } from '../operators/onErrorResumeNext';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\n\n/* tslint:disable:max-line-length */\nexport function onErrorResumeNext<A extends readonly unknown[]>(sources: [...ObservableInputTuple<A>]): Observable<A[number]>;\nexport function onErrorResumeNext<A extends readonly unknown[]>(...sources: [...ObservableInputTuple<A>]): Observable<A[number]>;\n\n/* tslint:enable:max-line-length */\n\n/**\n * When any of the provided Observable emits a complete or an error notification, it immediately subscribes to the next one\n * that was passed.\n *\n * <span class=\"informal\">Execute series of Observables no matter what, even if it means swallowing errors.</span>\n *\n * ![](onErrorResumeNext.png)\n *\n * `onErrorResumeNext` will subscribe to each observable source it is provided, in order.\n * If the source it's subscribed to emits an error or completes, it will move to the next source\n * without error.\n *\n * If `onErrorResumeNext` is provided no arguments, or a single, empty array, it will return {@link EMPTY}.\n *\n * `onErrorResumeNext` is basically {@link concat}, only it will continue, even if one of its\n * sources emits an error.\n *\n * Note that there is no way to handle any errors thrown by sources via the result of\n * `onErrorResumeNext`. If you want to handle errors thrown in any given source, you can\n * always use the {@link catchError} operator on them before passing them into `onErrorResumeNext`.\n *\n * ## Example\n *\n * Subscribe to the next Observable after map fails\n *\n * ```ts\n * import { onErrorResumeNext, of, map } from 'valdi_rxjs';\n *\n * onErrorResumeNext(\n *   of(1, 2, 3, 0).pipe(\n *     map(x => {\n *       if (x === 0) {\n *         throw Error();\n *       }\n *       return 10 / x;\n *     })\n *   ),\n *   of(1, 2, 3)\n * )\n * .subscribe({\n *   next: value => console.log(value),\n *   error: err => console.log(err),     // Will never be called.\n *   complete: () => console.log('done')\n * });\n *\n * // Logs:\n * // 10\n * // 5\n * // 3.3333333333333335\n * // 1\n * // 2\n * // 3\n * // 'done'\n * ```\n *\n * @see {@link concat}\n * @see {@link catchError}\n *\n * @param {...ObservableInput} sources Observables (or anything that *is* observable) passed either directly or as an array.\n * @return {Observable} An Observable that concatenates all sources, one after the other,\n * ignoring all errors, such that any error causes it to move on to the next source.\n */\nexport function onErrorResumeNext<A extends readonly unknown[]>(\n  ...sources: [[...ObservableInputTuple<A>]] | [...ObservableInputTuple<A>]\n): Observable<A[number]> {\n  return onErrorResumeNextWith(argsOrArgArray(sources))(EMPTY);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/pairs.ts",
    "content": "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\nimport { from } from './from';\n\n/**\n * @deprecated Use `from(Object.entries(obj))` instead. Will be removed in v8.\n */\nexport function pairs<T>(arr: readonly T[], scheduler?: SchedulerLike): Observable<[string, T]>;\n/**\n * @deprecated Use `from(Object.entries(obj))` instead. Will be removed in v8.\n */\nexport function pairs<O extends Record<string, unknown>>(obj: O, scheduler?: SchedulerLike): Observable<[keyof O, O[keyof O]]>;\n/**\n * @deprecated Use `from(Object.entries(obj))` instead. Will be removed in v8.\n */\nexport function pairs<T>(iterable: Iterable<T>, scheduler?: SchedulerLike): Observable<[string, T]>;\n/**\n * @deprecated Use `from(Object.entries(obj))` instead. Will be removed in v8.\n */\nexport function pairs(\n  n: number | bigint | boolean | ((...args: any[]) => any) | symbol,\n  scheduler?: SchedulerLike\n): Observable<[never, never]>;\n\n/**\n * Convert an object into an Observable of `[key, value]` pairs.\n *\n * <span class=\"informal\">Turn entries of an object into a stream.</span>\n *\n * ![](pairs.png)\n *\n * `pairs` takes an arbitrary object and returns an Observable that emits arrays. Each\n * emitted array has exactly two elements - the first is a key from the object\n * and the second is a value corresponding to that key. Keys are extracted from\n * an object via `Object.keys` function, which means that they will be only\n * enumerable keys that are present on an object directly - not ones inherited\n * via prototype chain.\n *\n * By default, these arrays are emitted synchronously. To change that you can\n * pass a {@link SchedulerLike} as a second argument to `pairs`.\n *\n * ## Example\n *\n * Converts an object to an Observable\n *\n * ```ts\n * import { pairs } from 'valdi_rxjs';\n *\n * const obj = {\n *   foo: 42,\n *   bar: 56,\n *   baz: 78\n * };\n *\n * pairs(obj).subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('Complete!')\n * });\n *\n * // Logs:\n * // ['foo', 42]\n * // ['bar', 56]\n * // ['baz', 78]\n * // 'Complete!'\n * ```\n *\n * ### Object.entries required\n *\n * In IE, you will need to polyfill `Object.entries` in order to use this.\n * [MDN has a polyfill here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries)\n *\n * @param {Object} obj The object to inspect and turn into an\n * Observable sequence.\n * @param {Scheduler} [scheduler] An optional IScheduler to schedule\n * when resulting Observable will emit values.\n * @returns {(Observable<Array<string|T>>)} An observable sequence of\n * [key, value] pairs from the object.\n * @deprecated Use `from(Object.entries(obj))` instead. Will be removed in v8.\n */\nexport function pairs(obj: any, scheduler?: SchedulerLike) {\n  return from(Object.entries(obj), scheduler as any);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/partition.ts",
    "content": "import { not } from '../util/not';\nimport { filter } from '../operators/filter';\nimport { ObservableInput } from '../types';\nimport { Observable } from '../Observable';\nimport { innerFrom } from './innerFrom';\n\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function partition<T, U extends T, A>(\n  source: ObservableInput<T>,\n  predicate: (this: A, value: T, index: number) => value is U,\n  thisArg: A\n): [Observable<U>, Observable<Exclude<T, U>>];\nexport function partition<T, U extends T>(\n  source: ObservableInput<T>,\n  predicate: (value: T, index: number) => value is U\n): [Observable<U>, Observable<Exclude<T, U>>];\n\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function partition<T, A>(\n  source: ObservableInput<T>,\n  predicate: (this: A, value: T, index: number) => boolean,\n  thisArg: A\n): [Observable<T>, Observable<T>];\nexport function partition<T>(source: ObservableInput<T>, predicate: (value: T, index: number) => boolean): [Observable<T>, Observable<T>];\n\n/**\n * Splits the source Observable into two, one with values that satisfy a\n * predicate, and another with values that don't satisfy the predicate.\n *\n * <span class=\"informal\">It's like {@link filter}, but returns two Observables:\n * one like the output of {@link filter}, and the other with values that did not\n * pass the condition.</span>\n *\n * ![](partition.png)\n *\n * `partition` outputs an array with two Observables that partition the values\n * from the source Observable through the given `predicate` function. The first\n * Observable in that array emits source values for which the predicate argument\n * returns true. The second Observable emits source values for which the\n * predicate returns false. The first behaves like {@link filter} and the second\n * behaves like {@link filter} with the predicate negated.\n *\n * ## Example\n *\n * Partition a set of numbers into odds and evens observables\n *\n * ```ts\n * import { of, partition } from 'valdi_rxjs';\n *\n * const observableValues = of(1, 2, 3, 4, 5, 6);\n * const [evens$, odds$] = partition(observableValues, value => value % 2 === 0);\n *\n * odds$.subscribe(x => console.log('odds', x));\n * evens$.subscribe(x => console.log('evens', x));\n *\n * // Logs:\n * // odds 1\n * // odds 3\n * // odds 5\n * // evens 2\n * // evens 4\n * // evens 6\n * ```\n *\n * @see {@link filter}\n *\n * @param {function(value: T, index: number): boolean} predicate A function that\n * evaluates each value emitted by the source Observable. If it returns `true`,\n * the value is emitted on the first Observable in the returned array, if\n * `false` the value is emitted on the second Observable in the array. The\n * `index` parameter is the number `i` for the i-th source emission that has\n * happened since the subscription, starting from the number `0`.\n * @param {any} [thisArg] An optional argument to determine the value of `this`\n * in the `predicate` function.\n * @return {[Observable<T>, Observable<T>]} An array with two Observables: one\n * with values that passed the predicate, and another with values that did not\n * pass the predicate.\n */\nexport function partition<T>(\n  source: ObservableInput<T>,\n  predicate: (this: any, value: T, index: number) => boolean,\n  thisArg?: any\n): [Observable<T>, Observable<T>] {\n  return [filter(predicate, thisArg)(innerFrom(source)), filter(not(predicate, thisArg))(innerFrom(source))] as [\n    Observable<T>,\n    Observable<T>\n  ];\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/race.ts",
    "content": "import { Observable } from '../Observable';\nimport { innerFrom } from './innerFrom';\nimport { Subscription } from '../Subscription';\nimport { ObservableInput, ObservableInputTuple } from '../types';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { Subscriber } from '../Subscriber';\n\nexport function race<T extends readonly unknown[]>(inputs: [...ObservableInputTuple<T>]): Observable<T[number]>;\nexport function race<T extends readonly unknown[]>(...inputs: [...ObservableInputTuple<T>]): Observable<T[number]>;\n\n/**\n * Returns an observable that mirrors the first source observable to emit an item.\n *\n * ![](race.png)\n *\n * `race` returns an observable, that when subscribed to, subscribes to all source observables immediately.\n * As soon as one of the source observables emits a value, the result unsubscribes from the other sources.\n * The resulting observable will forward all notifications, including error and completion, from the \"winning\"\n * source observable.\n *\n * If one of the used source observable throws an errors before a first notification\n * the race operator will also throw an error, no matter if another source observable\n * could potentially win the race.\n *\n * `race` can be useful for selecting the response from the fastest network connection for\n * HTTP or WebSockets. `race` can also be useful for switching observable context based on user\n * input.\n *\n * ## Example\n *\n * Subscribes to the observable that was the first to start emitting.\n *\n * ```ts\n * import { interval, map, race } from 'valdi_rxjs';\n *\n * const obs1 = interval(7000).pipe(map(() => 'slow one'));\n * const obs2 = interval(3000).pipe(map(() => 'fast one'));\n * const obs3 = interval(5000).pipe(map(() => 'medium one'));\n *\n * race(obs1, obs2, obs3)\n *   .subscribe(winner => console.log(winner));\n *\n * // Outputs\n * // a series of 'fast one'\n * ```\n *\n * @param {...Observables} ...observables sources used to race for which Observable emits first.\n * @return {Observable} an Observable that mirrors the output of the first Observable to emit an item.\n */\nexport function race<T>(...sources: (ObservableInput<T> | ObservableInput<T>[])[]): Observable<any> {\n  sources = argsOrArgArray(sources);\n  // If only one source was passed, just return it. Otherwise return the race.\n  return sources.length === 1 ? innerFrom(sources[0] as ObservableInput<T>) : new Observable<T>(raceInit(sources as ObservableInput<T>[]));\n}\n\n/**\n * An observable initializer function for both the static version and the\n * operator version of race.\n * @param sources The sources to race\n */\nexport function raceInit<T>(sources: ObservableInput<T>[]) {\n  return (subscriber: Subscriber<T>) => {\n    let subscriptions: Subscription[] = [];\n\n    // Subscribe to all of the sources. Note that we are checking `subscriptions` here\n    // Is is an array of all actively \"racing\" subscriptions, and it is `null` after the\n    // race has been won. So, if we have racer that synchronously \"wins\", this loop will\n    // stop before it subscribes to any more.\n    for (let i = 0; subscriptions && !subscriber.closed && i < sources.length; i++) {\n      subscriptions.push(\n        innerFrom(sources[i] as ObservableInput<T>).subscribe(\n          createOperatorSubscriber(subscriber, (value) => {\n            if (subscriptions) {\n              // We're still racing, but we won! So unsubscribe\n              // all other subscriptions that we have, except this one.\n              for (let s = 0; s < subscriptions.length; s++) {\n                s !== i && subscriptions[s].unsubscribe();\n              }\n              subscriptions = null!;\n            }\n            subscriber.next(value);\n          })\n        )\n      );\n    }\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/range.ts",
    "content": "import { SchedulerLike } from '../types';\nimport { Observable } from '../Observable';\nimport { EMPTY } from './empty';\n\nexport function range(start: number, count?: number): Observable<number>;\n\n/**\n * @deprecated The `scheduler` parameter will be removed in v8. Use `range(start, count).pipe(observeOn(scheduler))` instead. Details: Details: https://rxjs.dev/deprecations/scheduler-argument\n */\nexport function range(start: number, count: number | undefined, scheduler: SchedulerLike): Observable<number>;\n\n/**\n * Creates an Observable that emits a sequence of numbers within a specified\n * range.\n *\n * <span class=\"informal\">Emits a sequence of numbers in a range.</span>\n *\n * ![](range.png)\n *\n * `range` operator emits a range of sequential integers, in order, where you\n * select the `start` of the range and its `length`. By default, uses no\n * {@link SchedulerLike} and just delivers the notifications synchronously, but may use\n * an optional {@link SchedulerLike} to regulate those deliveries.\n *\n * ## Example\n *\n * Produce a range of numbers\n *\n * ```ts\n * import { range } from 'valdi_rxjs';\n *\n * const numbers = range(1, 3);\n *\n * numbers.subscribe({\n *   next: value => console.log(value),\n *   complete: () => console.log('Complete!')\n * });\n *\n * // Logs:\n * // 1\n * // 2\n * // 3\n * // 'Complete!'\n * ```\n *\n * @see {@link timer}\n * @see {@link interval}\n *\n * @param {number} [start=0] The value of the first integer in the sequence.\n * @param {number} count The number of sequential integers to generate.\n * @param {SchedulerLike} [scheduler] A {@link SchedulerLike} to use for scheduling\n * the emissions of the notifications.\n * @return {Observable} An Observable of numbers that emits a finite range of\n * sequential integers.\n */\nexport function range(start: number, count?: number, scheduler?: SchedulerLike): Observable<number> {\n  if (count == null) {\n    // If one argument was passed, it's the count, not the start.\n    count = start;\n    start = 0;\n  }\n\n  if (count <= 0) {\n    // No count? We're going nowhere. Return EMPTY.\n    return EMPTY;\n  }\n\n  // Where the range should stop.\n  const end = count + start;\n\n  return new Observable(\n    scheduler\n      ? // The deprecated scheduled path.\n        (subscriber) => {\n          let n = start;\n          return scheduler.schedule(function () {\n            if (n < end) {\n              subscriber.next(n++);\n              this.schedule();\n            } else {\n              subscriber.complete();\n            }\n          });\n        }\n      : // Standard synchronous range.\n        (subscriber) => {\n          let n = start;\n          while (n < end && !subscriber.closed) {\n            subscriber.next(n++);\n          }\n          subscriber.complete();\n        }\n  );\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/throwError.ts",
    "content": "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { SchedulerLike } from '../types';\nimport { isFunction } from '../util/isFunction';\n\n/**\n * Creates an observable that will create an error instance and push it to the consumer as an error\n * immediately upon subscription.\n *\n * <span class=\"informal\">Just errors and does nothing else</span>\n *\n * ![](throw.png)\n *\n * This creation function is useful for creating an observable that will create an error and error every\n * time it is subscribed to. Generally, inside of most operators when you might want to return an errored\n * observable, this is unnecessary. In most cases, such as in the inner return of {@link concatMap},\n * {@link mergeMap}, {@link defer}, and many others, you can simply throw the error, and RxJS will pick\n * that up and notify the consumer of the error.\n *\n * ## Example\n *\n * Create a simple observable that will create a new error with a timestamp and log it\n * and the message every time you subscribe to it\n *\n * ```ts\n * import { throwError } from 'valdi_rxjs';\n *\n * let errorCount = 0;\n *\n * const errorWithTimestamp$ = throwError(() => {\n *   const error: any = new Error(`This is error number ${ ++errorCount }`);\n *   error.timestamp = Date.now();\n *   return error;\n * });\n *\n * errorWithTimestamp$.subscribe({\n *   error: err => console.log(err.timestamp, err.message)\n * });\n *\n * errorWithTimestamp$.subscribe({\n *   error: err => console.log(err.timestamp, err.message)\n * });\n *\n * // Logs the timestamp and a new error message for each subscription\n * ```\n *\n * ### Unnecessary usage\n *\n * Using `throwError` inside of an operator or creation function\n * with a callback, is usually not necessary\n *\n * ```ts\n * import { of, concatMap, timer, throwError } from 'valdi_rxjs';\n *\n * const delays$ = of(1000, 2000, Infinity, 3000);\n *\n * delays$.pipe(\n *   concatMap(ms => {\n *     if (ms < 10000) {\n *       return timer(ms);\n *     } else {\n *       // This is probably overkill.\n *       return throwError(() => new Error(`Invalid time ${ ms }`));\n *     }\n *   })\n * )\n * .subscribe({\n *   next: console.log,\n *   error: console.error\n * });\n * ```\n *\n * You can just throw the error instead\n *\n * ```ts\n * import { of, concatMap, timer } from 'valdi_rxjs';\n *\n * const delays$ = of(1000, 2000, Infinity, 3000);\n *\n * delays$.pipe(\n *   concatMap(ms => {\n *     if (ms < 10000) {\n *       return timer(ms);\n *     } else {\n *       // Cleaner and easier to read for most folks.\n *       throw new Error(`Invalid time ${ ms }`);\n *     }\n *   })\n * )\n * .subscribe({\n *   next: console.log,\n *   error: console.error\n * });\n * ```\n *\n * @param errorFactory A factory function that will create the error instance that is pushed.\n */\nexport function throwError(errorFactory: () => any): Observable<never>;\n\n/**\n * Returns an observable that will error with the specified error immediately upon subscription.\n *\n * @param error The error instance to emit\n * @deprecated Support for passing an error value will be removed in v8. Instead, pass a factory function to `throwError(() => new Error('test'))`. This is\n * because it will create the error at the moment it should be created and capture a more appropriate stack trace. If\n * for some reason you need to create the error ahead of time, you can still do that: `const err = new Error('test'); throwError(() => err);`.\n */\nexport function throwError(error: any): Observable<never>;\n\n/**\n * Notifies the consumer of an error using a given scheduler by scheduling it at delay `0` upon subscription.\n *\n * @param errorOrErrorFactory An error instance or error factory\n * @param scheduler A scheduler to use to schedule the error notification\n * @deprecated The `scheduler` parameter will be removed in v8.\n * Use `throwError` in combination with {@link observeOn}: `throwError(() => new Error('test')).pipe(observeOn(scheduler));`.\n * Details: https://rxjs.dev/deprecations/scheduler-argument\n */\nexport function throwError(errorOrErrorFactory: any, scheduler: SchedulerLike): Observable<never>;\n\nexport function throwError(errorOrErrorFactory: any, scheduler?: SchedulerLike): Observable<never> {\n  const errorFactory = isFunction(errorOrErrorFactory) ? errorOrErrorFactory : () => errorOrErrorFactory;\n  const init = (subscriber: Subscriber<never>) => subscriber.error(errorFactory());\n  return new Observable(scheduler ? (subscriber) => scheduler.schedule(init as any, 0, subscriber) : init);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/timer.ts",
    "content": "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\nimport { async as asyncScheduler } from '../scheduler/async';\nimport { isScheduler } from '../util/isScheduler';\nimport { isValidDate } from '../util/isDate';\n\n/**\n * Creates an observable that will wait for a specified time period, or exact date, before\n * emitting the number 0.\n *\n * <span class=\"informal\">Used to emit a notification after a delay.</span>\n *\n * This observable is useful for creating delays in code, or racing against other values\n * for ad-hoc timeouts.\n *\n * The `delay` is specified by default in milliseconds, however providing a custom scheduler could\n * create a different behavior.\n *\n * ## Examples\n *\n * Wait 3 seconds and start another observable\n *\n * You might want to use `timer` to delay subscription to an\n * observable by a set amount of time. Here we use a timer with\n * {@link concatMapTo} or {@link concatMap} in order to wait\n * a few seconds and start a subscription to a source.\n *\n * ```ts\n * import { of, timer, concatMap } from 'valdi_rxjs';\n *\n * // This could be any observable\n * const source = of(1, 2, 3);\n *\n * timer(3000)\n *   .pipe(concatMap(() => source))\n *   .subscribe(console.log);\n * ```\n *\n * Take all values until the start of the next minute\n *\n * Using a `Date` as the trigger for the first emission, you can\n * do things like wait until midnight to fire an event, or in this case,\n * wait until a new minute starts (chosen so the example wouldn't take\n * too long to run) in order to stop watching a stream. Leveraging\n * {@link takeUntil}.\n *\n * ```ts\n * import { interval, takeUntil, timer } from 'valdi_rxjs';\n *\n * // Build a Date object that marks the\n * // next minute.\n * const currentDate = new Date();\n * const startOfNextMinute = new Date(\n *   currentDate.getFullYear(),\n *   currentDate.getMonth(),\n *   currentDate.getDate(),\n *   currentDate.getHours(),\n *   currentDate.getMinutes() + 1\n * );\n *\n * // This could be any observable stream\n * const source = interval(1000);\n *\n * const result = source.pipe(\n *   takeUntil(timer(startOfNextMinute))\n * );\n *\n * result.subscribe(console.log);\n * ```\n *\n * ### Known Limitations\n *\n * - The {@link asyncScheduler} uses `setTimeout` which has limitations for how far in the future it can be scheduled.\n *\n * - If a `scheduler` is provided that returns a timestamp other than an epoch from `now()`, and\n * a `Date` object is passed to the `dueTime` argument, the calculation for when the first emission\n * should occur will be incorrect. In this case, it would be best to do your own calculations\n * ahead of time, and pass a `number` in as the `dueTime`.\n *\n * @param due If a `number`, the amount of time in milliseconds to wait before emitting.\n * If a `Date`, the exact time at which to emit.\n * @param scheduler The scheduler to use to schedule the delay. Defaults to {@link asyncScheduler}.\n */\nexport function timer(due: number | Date, scheduler?: SchedulerLike): Observable<0>;\n\n/**\n * Creates an observable that starts an interval after a specified delay, emitting incrementing numbers -- starting at `0` --\n * on each interval after words.\n *\n * The `delay` and `intervalDuration` are specified by default in milliseconds, however providing a custom scheduler could\n * create a different behavior.\n *\n * ## Example\n *\n * ### Start an interval that starts right away\n *\n * Since {@link interval} waits for the passed delay before starting,\n * sometimes that's not ideal. You may want to start an interval immediately.\n * `timer` works well for this. Here we have both side-by-side so you can\n * see them in comparison.\n *\n * Note that this observable will never complete.\n *\n * ```ts\n * import { timer, interval } from 'valdi_rxjs';\n *\n * timer(0, 1000).subscribe(n => console.log('timer', n));\n * interval(1000).subscribe(n => console.log('interval', n));\n * ```\n *\n * ### Known Limitations\n *\n * - The {@link asyncScheduler} uses `setTimeout` which has limitations for how far in the future it can be scheduled.\n *\n * - If a `scheduler` is provided that returns a timestamp other than an epoch from `now()`, and\n * a `Date` object is passed to the `dueTime` argument, the calculation for when the first emission\n * should occur will be incorrect. In this case, it would be best to do your own calculations\n * ahead of time, and pass a `number` in as the `startDue`.\n * @param startDue If a `number`, is the time to wait before starting the interval.\n * If a `Date`, is the exact time at which to start the interval.\n * @param intervalDuration The delay between each value emitted in the interval. Passing a\n * negative number here will result in immediate completion after the first value is emitted, as though\n * no `intervalDuration` was passed at all.\n * @param scheduler The scheduler to use to schedule the delay. Defaults to {@link asyncScheduler}.\n */\nexport function timer(startDue: number | Date, intervalDuration: number, scheduler?: SchedulerLike): Observable<number>;\n\n/**\n * @deprecated The signature allowing `undefined` to be passed for `intervalDuration` will be removed in v8. Use the `timer(dueTime, scheduler?)` signature instead.\n */\nexport function timer(dueTime: number | Date, unused: undefined, scheduler?: SchedulerLike): Observable<0>;\n\nexport function timer(\n  dueTime: number | Date = 0,\n  intervalOrScheduler?: number | SchedulerLike,\n  scheduler: SchedulerLike = asyncScheduler\n): Observable<number> {\n  // Since negative intervalDuration is treated as though no\n  // interval was specified at all, we start with a negative number.\n  let intervalDuration = -1;\n\n  if (intervalOrScheduler != null) {\n    // If we have a second argument, and it's a scheduler,\n    // override the scheduler we had defaulted. Otherwise,\n    // it must be an interval.\n    if (isScheduler(intervalOrScheduler)) {\n      scheduler = intervalOrScheduler;\n    } else {\n      // Note that this *could* be negative, in which case\n      // it's like not passing an intervalDuration at all.\n      intervalDuration = intervalOrScheduler;\n    }\n  }\n\n  return new Observable((subscriber) => {\n    // If a valid date is passed, calculate how long to wait before\n    // executing the first value... otherwise, if it's a number just schedule\n    // that many milliseconds (or scheduler-specified unit size) in the future.\n    let due = isValidDate(dueTime) ? +dueTime - scheduler!.now() : dueTime;\n\n    if (due < 0) {\n      // Ensure we don't schedule in the future.\n      due = 0;\n    }\n\n    // The incrementing value we emit.\n    let n = 0;\n\n    // Start the timer.\n    return scheduler.schedule(function () {\n      if (!subscriber.closed) {\n        // Emit the next value and increment.\n        subscriber.next(n++);\n\n        if (0 <= intervalDuration) {\n          // If we have a interval after the initial timer,\n          // reschedule with the period.\n          this.schedule(undefined, intervalDuration);\n        } else {\n          // We didn't have an interval. So just complete.\n          subscriber.complete();\n        }\n      }\n    }, due);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/using.ts",
    "content": "import { Observable } from '../Observable';\nimport { Unsubscribable, ObservableInput, ObservedValueOf } from '../types';\nimport { innerFrom } from './innerFrom';\nimport { EMPTY } from './empty';\n\n/**\n * Creates an Observable that uses a resource which will be disposed at the same time as the Observable.\n *\n * <span class=\"informal\">Use it when you catch yourself cleaning up after an Observable.</span>\n *\n * `using` is a factory operator, which accepts two functions. First function returns a disposable resource.\n * It can be an arbitrary object that implements `unsubscribe` method. Second function will be injected with\n * that object and should return an Observable. That Observable can use resource object during its execution.\n * Both functions passed to `using` will be called every time someone subscribes - neither an Observable nor\n * resource object will be shared in any way between subscriptions.\n *\n * When Observable returned by `using` is subscribed, Observable returned from the second function will be subscribed\n * as well. All its notifications (nexted values, completion and error events) will be emitted unchanged by the output\n * Observable. If however someone unsubscribes from the Observable or source Observable completes or errors by itself,\n * the `unsubscribe` method on resource object will be called. This can be used to do any necessary clean up, which\n * otherwise would have to be handled by hand. Note that complete or error notifications are not emitted when someone\n * cancels subscription to an Observable via `unsubscribe`, so `using` can be used as a hook, allowing you to make\n * sure that all resources which need to exist during an Observable execution will be disposed at appropriate time.\n *\n * @see {@link defer}\n *\n * @param {function(): ISubscription} resourceFactory A function which creates any resource object\n * that implements `unsubscribe` method.\n * @param {function(resource: ISubscription): Observable<T>} observableFactory A function which\n * creates an Observable, that can use injected resource object.\n * @return {Observable<T>} An Observable that behaves the same as Observable returned by `observableFactory`, but\n * which - when completed, errored or unsubscribed - will also call `unsubscribe` on created resource object.\n */\nexport function using<T extends ObservableInput<any>>(\n  resourceFactory: () => Unsubscribable | void,\n  observableFactory: (resource: Unsubscribable | void) => T | void\n): Observable<ObservedValueOf<T>> {\n  return new Observable<ObservedValueOf<T>>((subscriber) => {\n    const resource = resourceFactory();\n    const result = observableFactory(resource);\n    const source = result ? innerFrom(result) : EMPTY;\n    source.subscribe(subscriber);\n    return () => {\n      // NOTE: Optional chaining did not work here.\n      // Related TS Issue: https://github.com/microsoft/TypeScript/issues/40818\n      if (resource) {\n        resource.unsubscribe();\n      }\n    };\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/observable/zip.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservableInputTuple } from '../types';\nimport { innerFrom } from './innerFrom';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { EMPTY } from './empty';\nimport { createOperatorSubscriber } from '../operators/OperatorSubscriber';\nimport { popResultSelector } from '../util/args';\n\nexport function zip<A extends readonly unknown[]>(sources: [...ObservableInputTuple<A>]): Observable<A>;\nexport function zip<A extends readonly unknown[], R>(\n  sources: [...ObservableInputTuple<A>],\n  resultSelector: (...values: A) => R\n): Observable<R>;\nexport function zip<A extends readonly unknown[]>(...sources: [...ObservableInputTuple<A>]): Observable<A>;\nexport function zip<A extends readonly unknown[], R>(\n  ...sourcesAndResultSelector: [...ObservableInputTuple<A>, (...values: A) => R]\n): Observable<R>;\n\n/**\n * Combines multiple Observables to create an Observable whose values are calculated from the values, in order, of each\n * of its input Observables.\n *\n * If the last parameter is a function, this function is used to compute the created value from the input values.\n * Otherwise, an array of the input values is returned.\n *\n * ## Example\n *\n * Combine age and name from different sources\n *\n * ```ts\n * import { of, zip, map } from 'valdi_rxjs';\n *\n * const age$ = of(27, 25, 29);\n * const name$ = of('Foo', 'Bar', 'Beer');\n * const isDev$ = of(true, true, false);\n *\n * zip(age$, name$, isDev$).pipe(\n *   map(([age, name, isDev]) => ({ age, name, isDev }))\n * )\n * .subscribe(x => console.log(x));\n *\n * // Outputs\n * // { age: 27, name: 'Foo', isDev: true }\n * // { age: 25, name: 'Bar', isDev: true }\n * // { age: 29, name: 'Beer', isDev: false }\n * ```\n *\n * @param sources\n * @return {Observable<R>}\n */\nexport function zip(...args: unknown[]): Observable<unknown> {\n  const resultSelector = popResultSelector(args);\n\n  const sources = argsOrArgArray(args) as Observable<unknown>[];\n\n  return sources.length\n    ? new Observable<unknown[]>((subscriber) => {\n        // A collection of buffers of values from each source.\n        // Keyed by the same index with which the sources were passed in.\n        let buffers: unknown[][] = sources.map(() => []);\n\n        // An array of flags of whether or not the sources have completed.\n        // This is used to check to see if we should complete the result.\n        // Keyed by the same index with which the sources were passed in.\n        let completed = sources.map(() => false);\n\n        // When everything is done, release the arrays above.\n        subscriber.add(() => {\n          buffers = completed = null!;\n        });\n\n        // Loop over our sources and subscribe to each one. The index `i` is\n        // especially important here, because we use it in closures below to\n        // access the related buffers and completion properties\n        for (let sourceIndex = 0; !subscriber.closed && sourceIndex < sources.length; sourceIndex++) {\n          innerFrom(sources[sourceIndex]).subscribe(\n            createOperatorSubscriber(\n              subscriber,\n              (value) => {\n                buffers[sourceIndex].push(value);\n                // if every buffer has at least one value in it, then we\n                // can shift out the oldest value from each buffer and emit\n                // them as an array.\n                if (buffers.every((buffer) => buffer.length)) {\n                  const result: any = buffers.map((buffer) => buffer.shift()!);\n                  // Emit the array. If theres' a result selector, use that.\n                  subscriber.next(resultSelector ? resultSelector(...result) : result);\n                  // If any one of the sources is both complete and has an empty buffer\n                  // then we complete the result. This is because we cannot possibly have\n                  // any more values to zip together.\n                  if (buffers.some((buffer, i) => !buffer.length && completed[i])) {\n                    subscriber.complete();\n                  }\n                }\n              },\n              () => {\n                // This source completed. Mark it as complete so we can check it later\n                // if we have to.\n                completed[sourceIndex] = true;\n                // But, if this complete source has nothing in its buffer, then we\n                // can complete the result, because we can't possibly have any more\n                // values from this to zip together with the other values.\n                !buffers[sourceIndex].length && subscriber.complete();\n              }\n            )\n          );\n        }\n\n        // When everything is done, release the arrays above.\n        return () => {\n          buffers = completed = null!;\n        };\n      })\n    : EMPTY;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/OperatorSubscriber.ts",
    "content": "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber<T>(\n  destination: Subscriber<any>,\n  onNext?: (value: T) => void,\n  onComplete?: () => void,\n  onError?: (err: any) => void,\n  onFinalize?: () => void\n): Subscriber<T> {\n  return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber<T> extends Subscriber<T> {\n  /**\n   * Creates an instance of an `OperatorSubscriber`.\n   * @param destination The downstream subscriber.\n   * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n   * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n   * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n   * and send to the `destination` error handler.\n   * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n   * this handler are sent to the `destination` error handler.\n   * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n   * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n   * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n   * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n   * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n   * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n   */\n  constructor(\n    destination: Subscriber<any>,\n    onNext?: (value: T) => void,\n    onComplete?: () => void,\n    onError?: (err: any) => void,\n    private onFinalize?: () => void,\n    private shouldUnsubscribe?: () => boolean\n  ) {\n    // It's important - for performance reasons - that all of this class's\n    // members are initialized and that they are always initialized in the same\n    // order. This will ensure that all OperatorSubscriber instances have the\n    // same hidden class in V8. This, in turn, will help keep the number of\n    // hidden classes involved in property accesses within the base class as\n    // low as possible. If the number of hidden classes involved exceeds four,\n    // the property accesses will become megamorphic and performance penalties\n    // will be incurred - i.e. inline caches won't be used.\n    //\n    // The reasons for ensuring all instances have the same hidden class are\n    // further discussed in this blog post from Benedikt Meurer:\n    // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n    super(destination);\n    this._next = onNext\n      ? function (this: OperatorSubscriber<T>, value: T) {\n          try {\n            onNext(value);\n          } catch (err) {\n            destination.error(err);\n          }\n        }\n      : super._next;\n    this._error = onError\n      ? function (this: OperatorSubscriber<T>, err: any) {\n          try {\n            onError(err);\n          } catch (err) {\n            // Send any errors that occur down stream.\n            destination.error(err);\n          } finally {\n            // Ensure finalization.\n            this.unsubscribe();\n          }\n        }\n      : super._error;\n    this._complete = onComplete\n      ? function (this: OperatorSubscriber<T>) {\n          try {\n            onComplete();\n          } catch (err) {\n            // Send any errors that occur down stream.\n            destination.error(err);\n          } finally {\n            // Ensure finalization.\n            this.unsubscribe();\n          }\n        }\n      : super._complete;\n  }\n\n  unsubscribe() {\n    if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n      const { closed } = this;\n      super.unsubscribe();\n      // Execute additional teardown if we have any and we didn't already do so.\n      !closed && this.onFinalize?.();\n    }\n  }\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/audit.ts",
    "content": "import { Subscriber } from '../Subscriber';\nimport { MonoTypeOperatorFunction, ObservableInput } from '../types';\n\nimport { operate } from '../util/lift';\nimport { innerFrom } from '../observable/innerFrom';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Ignores source values for a duration determined by another Observable, then\n * emits the most recent value from the source Observable, then repeats this\n * process.\n *\n * <span class=\"informal\">It's like {@link auditTime}, but the silencing\n * duration is determined by a second Observable.</span>\n *\n * ![](audit.svg)\n *\n * `audit` is similar to `throttle`, but emits the last value from the silenced\n * time window, instead of the first value. `audit` emits the most recent value\n * from the source Observable on the output Observable as soon as its internal\n * timer becomes disabled, and ignores source values while the timer is enabled.\n * Initially, the timer is disabled. As soon as the first source value arrives,\n * the timer is enabled by calling the `durationSelector` function with the\n * source value, which returns the \"duration\" Observable. When the duration\n * Observable emits a value, the timer is disabled, then the most\n * recent source value is emitted on the output Observable, and this process\n * repeats for the next source value.\n *\n * ## Example\n *\n * Emit clicks at a rate of at most one click per second\n *\n * ```ts\n * import { fromEvent, audit, interval } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(audit(ev => interval(1000)));\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link auditTime}\n * @see {@link debounce}\n * @see {@link delayWhen}\n * @see {@link sample}\n * @see {@link throttle}\n *\n * @param durationSelector A function\n * that receives a value from the source Observable, for computing the silencing\n * duration, returned as an Observable or a Promise.\n * @return A function that returns an Observable that performs rate-limiting of\n * emissions from the source Observable.\n */\nexport function audit<T>(durationSelector: (value: T) => ObservableInput<any>): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    let hasValue = false;\n    let lastValue: T | null = null;\n    let durationSubscriber: Subscriber<any> | null = null;\n    let isComplete = false;\n\n    const endDuration = () => {\n      durationSubscriber?.unsubscribe();\n      durationSubscriber = null;\n      if (hasValue) {\n        hasValue = false;\n        const value = lastValue!;\n        lastValue = null;\n        subscriber.next(value);\n      }\n      isComplete && subscriber.complete();\n    };\n\n    const cleanupDuration = () => {\n      durationSubscriber = null;\n      isComplete && subscriber.complete();\n    };\n\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => {\n          hasValue = true;\n          lastValue = value;\n          if (!durationSubscriber) {\n            innerFrom(durationSelector(value)).subscribe(\n              (durationSubscriber = createOperatorSubscriber(subscriber, endDuration, cleanupDuration))\n            );\n          }\n        },\n        () => {\n          isComplete = true;\n          (!hasValue || !durationSubscriber || durationSubscriber.closed) && subscriber.complete();\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/auditTime.ts",
    "content": "import { asyncScheduler } from '../scheduler/async';\nimport { audit } from './audit';\nimport { timer } from '../observable/timer';\nimport { MonoTypeOperatorFunction, SchedulerLike } from '../types';\n\n/**\n * Ignores source values for `duration` milliseconds, then emits the most recent\n * value from the source Observable, then repeats this process.\n *\n * <span class=\"informal\">When it sees a source value, it ignores that plus\n * the next ones for `duration` milliseconds, and then it emits the most recent\n * value from the source.</span>\n *\n * ![](auditTime.png)\n *\n * `auditTime` is similar to `throttleTime`, but emits the last value from the\n * silenced time window, instead of the first value. `auditTime` emits the most\n * recent value from the source Observable on the output Observable as soon as\n * its internal timer becomes disabled, and ignores source values while the\n * timer is enabled. Initially, the timer is disabled. As soon as the first\n * source value arrives, the timer is enabled. After `duration` milliseconds (or\n * the time unit determined internally by the optional `scheduler`) has passed,\n * the timer is disabled, then the most recent source value is emitted on the\n * output Observable, and this process repeats for the next source value.\n * Optionally takes a {@link SchedulerLike} for managing timers.\n *\n * ## Example\n *\n * Emit clicks at a rate of at most one click per second\n *\n * ```ts\n * import { fromEvent, auditTime } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(auditTime(1000));\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link audit}\n * @see {@link debounceTime}\n * @see {@link delay}\n * @see {@link sampleTime}\n * @see {@link throttleTime}\n *\n * @param {number} duration Time to wait before emitting the most recent source\n * value, measured in milliseconds or the time unit determined internally\n * by the optional `scheduler`.\n * @param {SchedulerLike} [scheduler=async] The {@link SchedulerLike} to use for\n * managing the timers that handle the rate-limiting behavior.\n * @return A function that returns an Observable that performs rate-limiting of\n * emissions from the source Observable.\n */\nexport function auditTime<T>(duration: number, scheduler: SchedulerLike = asyncScheduler): MonoTypeOperatorFunction<T> {\n  return audit(() => timer(duration, scheduler));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/buffer.ts",
    "content": "import { Observable } from '../Observable';\nimport { OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { noop } from '../util/noop';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Buffers the source Observable values until `closingNotifier` emits.\n *\n * <span class=\"informal\">Collects values from the past as an array, and emits\n * that array only when another Observable emits.</span>\n *\n * ![](buffer.png)\n *\n * Buffers the incoming Observable values until the given `closingNotifier`\n * Observable emits a value, at which point it emits the buffer on the output\n * Observable and starts a new buffer internally, awaiting the next time\n * `closingNotifier` emits.\n *\n * ## Example\n *\n * On every click, emit array of most recent interval events\n *\n * ```ts\n * import { fromEvent, interval, buffer } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const intervalEvents = interval(1000);\n * const buffered = intervalEvents.pipe(buffer(clicks));\n * buffered.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link bufferCount}\n * @see {@link bufferTime}\n * @see {@link bufferToggle}\n * @see {@link bufferWhen}\n * @see {@link window}\n *\n * @param {Observable<any>} closingNotifier An Observable that signals the\n * buffer to be emitted on the output Observable.\n * @return A function that returns an Observable of buffers, which are arrays\n * of values.\n */\nexport function buffer<T>(closingNotifier: Observable<any>): OperatorFunction<T, T[]> {\n  return operate((source, subscriber) => {\n    // The current buffered values.\n    let currentBuffer: T[] = [];\n\n    // Subscribe to our source.\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => currentBuffer.push(value),\n        () => {\n          subscriber.next(currentBuffer);\n          subscriber.complete();\n        }\n      )\n    );\n\n    // Subscribe to the closing notifier.\n    closingNotifier.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        () => {\n          // Start a new buffer and emit the previous one.\n          const b = currentBuffer;\n          currentBuffer = [];\n          subscriber.next(b);\n        },\n        noop\n      )\n    );\n\n    return () => {\n      // Ensure buffered values are released on finalization.\n      currentBuffer = null!;\n    };\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/bufferCount.ts",
    "content": "import { OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { arrRemove } from '../util/arrRemove';\n\n/**\n * Buffers the source Observable values until the size hits the maximum\n * `bufferSize` given.\n *\n * <span class=\"informal\">Collects values from the past as an array, and emits\n * that array only when its size reaches `bufferSize`.</span>\n *\n * ![](bufferCount.png)\n *\n * Buffers a number of values from the source Observable by `bufferSize` then\n * emits the buffer and clears it, and starts a new buffer each\n * `startBufferEvery` values. If `startBufferEvery` is not provided or is\n * `null`, then new buffers are started immediately at the start of the source\n * and when each buffer closes and is emitted.\n *\n * ## Examples\n *\n * Emit the last two click events as an array\n *\n * ```ts\n * import { fromEvent, bufferCount } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const buffered = clicks.pipe(bufferCount(2));\n * buffered.subscribe(x => console.log(x));\n * ```\n *\n * On every click, emit the last two click events as an array\n *\n * ```ts\n * import { fromEvent, bufferCount } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const buffered = clicks.pipe(bufferCount(2, 1));\n * buffered.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link buffer}\n * @see {@link bufferTime}\n * @see {@link bufferToggle}\n * @see {@link bufferWhen}\n * @see {@link pairwise}\n * @see {@link windowCount}\n *\n * @param {number} bufferSize The maximum size of the buffer emitted.\n * @param {number} [startBufferEvery] Interval at which to start a new buffer.\n * For example if `startBufferEvery` is `2`, then a new buffer will be started\n * on every other value from the source. A new buffer is started at the\n * beginning of the source by default.\n * @return A function that returns an Observable of arrays of buffered values.\n */\nexport function bufferCount<T>(bufferSize: number, startBufferEvery: number | null = null): OperatorFunction<T, T[]> {\n  // If no `startBufferEvery` value was supplied, then we're\n  // opening and closing on the bufferSize itself.\n  startBufferEvery = startBufferEvery ?? bufferSize;\n\n  return operate((source, subscriber) => {\n    let buffers: T[][] = [];\n    let count = 0;\n\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => {\n          let toEmit: T[][] | null = null;\n\n          // Check to see if we need to start a buffer.\n          // This will start one at the first value, and then\n          // a new one every N after that.\n          if (count++ % startBufferEvery! === 0) {\n            buffers.push([]);\n          }\n\n          // Push our value into our active buffers.\n          for (const buffer of buffers) {\n            buffer.push(value);\n            // Check to see if we're over the bufferSize\n            // if we are, record it so we can emit it later.\n            // If we emitted it now and removed it, it would\n            // mutate the `buffers` array while we're looping\n            // over it.\n            if (bufferSize <= buffer.length) {\n              toEmit = toEmit ?? [];\n              toEmit.push(buffer);\n            }\n          }\n\n          if (toEmit) {\n            // We have found some buffers that are over the\n            // `bufferSize`. Emit them, and remove them from our\n            // buffers list.\n            for (const buffer of toEmit) {\n              arrRemove(buffers, buffer);\n              subscriber.next(buffer);\n            }\n          }\n        },\n        () => {\n          // When the source completes, emit all of our\n          // active buffers.\n          for (const buffer of buffers) {\n            subscriber.next(buffer);\n          }\n          subscriber.complete();\n        },\n        // Pass all errors through to consumer.\n        undefined,\n        () => {\n          // Clean up our memory when we finalize\n          buffers = null!;\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/bufferTime.ts",
    "content": "import { Subscription } from '../Subscription';\nimport { OperatorFunction, SchedulerLike } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { arrRemove } from '../util/arrRemove';\nimport { asyncScheduler } from '../scheduler/async';\nimport { popScheduler } from '../util/args';\nimport { executeSchedule } from '../util/executeSchedule';\n\n/* tslint:disable:max-line-length */\nexport function bufferTime<T>(bufferTimeSpan: number, scheduler?: SchedulerLike): OperatorFunction<T, T[]>;\nexport function bufferTime<T>(\n  bufferTimeSpan: number,\n  bufferCreationInterval: number | null | undefined,\n  scheduler?: SchedulerLike\n): OperatorFunction<T, T[]>;\nexport function bufferTime<T>(\n  bufferTimeSpan: number,\n  bufferCreationInterval: number | null | undefined,\n  maxBufferSize: number,\n  scheduler?: SchedulerLike\n): OperatorFunction<T, T[]>;\n/* tslint:enable:max-line-length */\n\n/**\n * Buffers the source Observable values for a specific time period.\n *\n * <span class=\"informal\">Collects values from the past as an array, and emits\n * those arrays periodically in time.</span>\n *\n * ![](bufferTime.png)\n *\n * Buffers values from the source for a specific time duration `bufferTimeSpan`.\n * Unless the optional argument `bufferCreationInterval` is given, it emits and\n * resets the buffer every `bufferTimeSpan` milliseconds. If\n * `bufferCreationInterval` is given, this operator opens the buffer every\n * `bufferCreationInterval` milliseconds and closes (emits and resets) the\n * buffer every `bufferTimeSpan` milliseconds. When the optional argument\n * `maxBufferSize` is specified, the buffer will be closed either after\n * `bufferTimeSpan` milliseconds or when it contains `maxBufferSize` elements.\n *\n * ## Examples\n *\n * Every second, emit an array of the recent click events\n *\n * ```ts\n * import { fromEvent, bufferTime } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const buffered = clicks.pipe(bufferTime(1000));\n * buffered.subscribe(x => console.log(x));\n * ```\n *\n * Every 5 seconds, emit the click events from the next 2 seconds\n *\n * ```ts\n * import { fromEvent, bufferTime } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const buffered = clicks.pipe(bufferTime(2000, 5000));\n * buffered.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link buffer}\n * @see {@link bufferCount}\n * @see {@link bufferToggle}\n * @see {@link bufferWhen}\n * @see {@link windowTime}\n *\n * @param {number} bufferTimeSpan The amount of time to fill each buffer array.\n * @param {number} [bufferCreationInterval] The interval at which to start new\n * buffers.\n * @param {number} [maxBufferSize] The maximum buffer size.\n * @param {SchedulerLike} [scheduler=async] The scheduler on which to schedule the\n * intervals that determine buffer boundaries.\n * @return A function that returns an Observable of arrays of buffered values.\n */\nexport function bufferTime<T>(bufferTimeSpan: number, ...otherArgs: any[]): OperatorFunction<T, T[]> {\n  const scheduler = popScheduler(otherArgs) ?? asyncScheduler;\n  const bufferCreationInterval = (otherArgs[0] as number) ?? null;\n  const maxBufferSize = (otherArgs[1] as number) || Infinity;\n\n  return operate((source, subscriber) => {\n    // The active buffers, their related subscriptions, and removal functions.\n    let bufferRecords: { buffer: T[]; subs: Subscription }[] | null = [];\n    // If true, it means that every time we emit a buffer, we want to start a new buffer\n    // this is only really used for when *just* the buffer time span is passed.\n    let restartOnEmit = false;\n\n    /**\n     * Does the work of emitting the buffer from the record, ensuring that the\n     * record is removed before the emission so reentrant code (from some custom scheduling, perhaps)\n     * does not alter the buffer. Also checks to see if a new buffer needs to be started\n     * after the emit.\n     */\n    const emit = (record: { buffer: T[]; subs: Subscription }) => {\n      const { buffer, subs } = record;\n      subs.unsubscribe();\n      arrRemove(bufferRecords, record);\n      subscriber.next(buffer);\n      restartOnEmit && startBuffer();\n    };\n\n    /**\n     * Called every time we start a new buffer. This does\n     * the work of scheduling a job at the requested bufferTimeSpan\n     * that will emit the buffer (if it's not unsubscribed before then).\n     */\n    const startBuffer = () => {\n      if (bufferRecords) {\n        const subs = new Subscription();\n        subscriber.add(subs);\n        const buffer: T[] = [];\n        const record = {\n          buffer,\n          subs,\n        };\n        bufferRecords.push(record);\n        executeSchedule(subs, scheduler, () => emit(record), bufferTimeSpan);\n      }\n    };\n\n    if (bufferCreationInterval !== null && bufferCreationInterval >= 0) {\n      // The user passed both a bufferTimeSpan (required), and a creation interval\n      // That means we need to start new buffers on the interval, and those buffers need\n      // to wait the required time span before emitting.\n      executeSchedule(subscriber, scheduler, startBuffer, bufferCreationInterval, true);\n    } else {\n      restartOnEmit = true;\n    }\n\n    startBuffer();\n\n    const bufferTimeSubscriber = createOperatorSubscriber(\n      subscriber,\n      (value: T) => {\n        // Copy the records, so if we need to remove one we\n        // don't mutate the array. It's hard, but not impossible to\n        // set up a buffer time that could mutate the array and\n        // cause issues here.\n        const recordsCopy = bufferRecords!.slice();\n        for (const record of recordsCopy) {\n          // Loop over all buffers and\n          const { buffer } = record;\n          buffer.push(value);\n          // If the buffer is over the max size, we need to emit it.\n          maxBufferSize <= buffer.length && emit(record);\n        }\n      },\n      () => {\n        // The source completed, emit all of the active\n        // buffers we have before we complete.\n        while (bufferRecords?.length) {\n          subscriber.next(bufferRecords.shift()!.buffer);\n        }\n        bufferTimeSubscriber?.unsubscribe();\n        subscriber.complete();\n        subscriber.unsubscribe();\n      },\n      // Pass all errors through to consumer.\n      undefined,\n      // Clean up\n      () => (bufferRecords = null)\n    );\n\n    source.subscribe(bufferTimeSubscriber);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/bufferToggle.ts",
    "content": "import { Subscription } from '../Subscription';\nimport { OperatorFunction, ObservableInput } from '../types';\nimport { operate } from '../util/lift';\nimport { innerFrom } from '../observable/innerFrom';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\nimport { arrRemove } from '../util/arrRemove';\n\n/**\n * Buffers the source Observable values starting from an emission from\n * `openings` and ending when the output of `closingSelector` emits.\n *\n * <span class=\"informal\">Collects values from the past as an array. Starts\n * collecting only when `opening` emits, and calls the `closingSelector`\n * function to get an Observable that tells when to close the buffer.</span>\n *\n * ![](bufferToggle.png)\n *\n * Buffers values from the source by opening the buffer via signals from an\n * Observable provided to `openings`, and closing and sending the buffers when\n * a Subscribable or Promise returned by the `closingSelector` function emits.\n *\n * ## Example\n *\n * Every other second, emit the click events from the next 500ms\n *\n * ```ts\n * import { fromEvent, interval, bufferToggle, EMPTY } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const openings = interval(1000);\n * const buffered = clicks.pipe(bufferToggle(openings, i =>\n *   i % 2 ? interval(500) : EMPTY\n * ));\n * buffered.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link buffer}\n * @see {@link bufferCount}\n * @see {@link bufferTime}\n * @see {@link bufferWhen}\n * @see {@link windowToggle}\n *\n * @param openings A Subscribable or Promise of notifications to start new\n * buffers.\n * @param closingSelector A function that takes\n * the value emitted by the `openings` observable and returns a Subscribable or Promise,\n * which, when it emits, signals that the associated buffer should be emitted\n * and cleared.\n * @return A function that returns an Observable of arrays of buffered values.\n */\nexport function bufferToggle<T, O>(\n  openings: ObservableInput<O>,\n  closingSelector: (value: O) => ObservableInput<any>\n): OperatorFunction<T, T[]> {\n  return operate((source, subscriber) => {\n    const buffers: T[][] = [];\n\n    // Subscribe to the openings notifier first\n    innerFrom(openings).subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (openValue) => {\n          const buffer: T[] = [];\n          buffers.push(buffer);\n          // We use this composite subscription, so that\n          // when the closing notifier emits, we can tear it down.\n          const closingSubscription = new Subscription();\n\n          const emitBuffer = () => {\n            arrRemove(buffers, buffer);\n            subscriber.next(buffer);\n            closingSubscription.unsubscribe();\n          };\n\n          // The line below will add the subscription to the parent subscriber *and* the closing subscription.\n          closingSubscription.add(innerFrom(closingSelector(openValue)).subscribe(createOperatorSubscriber(subscriber, emitBuffer, noop)));\n        },\n        noop\n      )\n    );\n\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => {\n          // Value from our source. Add it to all pending buffers.\n          for (const buffer of buffers) {\n            buffer.push(value);\n          }\n        },\n        () => {\n          // Source complete. Emit all pending buffers.\n          while (buffers.length > 0) {\n            subscriber.next(buffers.shift()!);\n          }\n          subscriber.complete();\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/bufferWhen.ts",
    "content": "import { Subscriber } from '../Subscriber';\nimport { ObservableInput, OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { noop } from '../util/noop';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\n\n/**\n * Buffers the source Observable values, using a factory function of closing\n * Observables to determine when to close, emit, and reset the buffer.\n *\n * <span class=\"informal\">Collects values from the past as an array. When it\n * starts collecting values, it calls a function that returns an Observable that\n * tells when to close the buffer and restart collecting.</span>\n *\n * ![](bufferWhen.png)\n *\n * Opens a buffer immediately, then closes the buffer when the observable\n * returned by calling `closingSelector` function emits a value. When it closes\n * the buffer, it immediately opens a new buffer and repeats the process.\n *\n * ## Example\n *\n * Emit an array of the last clicks every [1-5] random seconds\n *\n * ```ts\n * import { fromEvent, bufferWhen, interval } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const buffered = clicks.pipe(\n *   bufferWhen(() => interval(1000 + Math.random() * 4000))\n * );\n * buffered.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link buffer}\n * @see {@link bufferCount}\n * @see {@link bufferTime}\n * @see {@link bufferToggle}\n * @see {@link windowWhen}\n *\n * @param {function(): Observable} closingSelector A function that takes no\n * arguments and returns an Observable that signals buffer closure.\n * @return A function that returns an Observable of arrays of buffered values.\n */\nexport function bufferWhen<T>(closingSelector: () => ObservableInput<any>): OperatorFunction<T, T[]> {\n  return operate((source, subscriber) => {\n    // The buffer we keep and emit.\n    let buffer: T[] | null = null;\n    // A reference to the subscriber used to subscribe to\n    // the closing notifier. We need to hold this so we can\n    // end the subscription after the first notification.\n    let closingSubscriber: Subscriber<T> | null = null;\n\n    // Ends the previous closing notifier subscription, so it\n    // terminates after the first emission, then emits\n    // the current buffer  if there is one, starts a new buffer, and starts a\n    // new closing notifier.\n    const openBuffer = () => {\n      // Make sure to finalize the closing subscription, we only cared\n      // about one notification.\n      closingSubscriber?.unsubscribe();\n      // emit the buffer if we have one, and start a new buffer.\n      const b = buffer;\n      buffer = [];\n      b && subscriber.next(b);\n\n      // Get a new closing notifier and subscribe to it.\n      innerFrom(closingSelector()).subscribe((closingSubscriber = createOperatorSubscriber(subscriber, openBuffer, noop)));\n    };\n\n    // Start the first buffer.\n    openBuffer();\n\n    // Subscribe to our source.\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        // Add every new value to the current buffer.\n        (value) => buffer?.push(value),\n        // When we complete, emit the buffer if we have one,\n        // then complete the result.\n        () => {\n          buffer && subscriber.next(buffer);\n          subscriber.complete();\n        },\n        // Pass all errors through to consumer.\n        undefined,\n        // Release memory on finalization\n        () => (buffer = closingSubscriber = null!)\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/catchError.ts",
    "content": "import { Observable } from '../Observable';\n\nimport { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';\nimport { Subscription } from '../Subscription';\nimport { innerFrom } from '../observable/innerFrom';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { operate } from '../util/lift';\n\n/* tslint:disable:max-line-length */\nexport function catchError<T, O extends ObservableInput<any>>(\n  selector: (err: any, caught: Observable<T>) => O\n): OperatorFunction<T, T | ObservedValueOf<O>>;\n/* tslint:enable:max-line-length */\n\n/**\n * Catches errors on the observable to be handled by returning a new observable or throwing an error.\n *\n * <span class=\"informal\">\n * It only listens to the error channel and ignores notifications.\n * Handles errors from the source observable, and maps them to a new observable.\n * The error may also be rethrown, or a new error can be thrown to emit an error from the result.\n * </span>\n *\n * ![](catch.png)\n *\n * This operator handles errors, but forwards along all other events to the resulting observable.\n * If the source observable terminates with an error, it will map that error to a new observable,\n * subscribe to it, and forward all of its events to the resulting observable.\n *\n * ## Examples\n *\n * Continue with a different Observable when there's an error\n *\n * ```ts\n * import { of, map, catchError } from 'valdi_rxjs';\n *\n * of(1, 2, 3, 4, 5)\n *   .pipe(\n *     map(n => {\n *       if (n === 4) {\n *         throw 'four!';\n *       }\n *       return n;\n *     }),\n *     catchError(err => of('I', 'II', 'III', 'IV', 'V'))\n *   )\n *   .subscribe(x => console.log(x));\n *   // 1, 2, 3, I, II, III, IV, V\n * ```\n *\n * Retry the caught source Observable again in case of error, similar to `retry()` operator\n *\n * ```ts\n * import { of, map, catchError, take } from 'valdi_rxjs';\n *\n * of(1, 2, 3, 4, 5)\n *   .pipe(\n *     map(n => {\n *       if (n === 4) {\n *         throw 'four!';\n *       }\n *       return n;\n *     }),\n *     catchError((err, caught) => caught),\n *     take(30)\n *   )\n *   .subscribe(x => console.log(x));\n *   // 1, 2, 3, 1, 2, 3, ...\n * ```\n *\n * Throw a new error when the source Observable throws an error\n *\n * ```ts\n * import { of, map, catchError } from 'valdi_rxjs';\n *\n * of(1, 2, 3, 4, 5)\n *   .pipe(\n *     map(n => {\n *       if (n === 4) {\n *         throw 'four!';\n *       }\n *       return n;\n *     }),\n *     catchError(err => {\n *       throw 'error in source. Details: ' + err;\n *     })\n *   )\n *   .subscribe({\n *     next: x => console.log(x),\n *     error: err => console.log(err)\n *   });\n *   // 1, 2, 3, error in source. Details: four!\n * ```\n *\n * @see {@link onErrorResumeNext}\n * @see {@link repeat}\n * @see {@link repeatWhen}\n * @see {@link retry }\n * @see {@link retryWhen}\n *\n * @param {function} selector a function that takes as arguments `err`, which is the error, and `caught`, which\n * is the source observable, in case you'd like to \"retry\" that observable by returning it again. Whatever observable\n * is returned by the `selector` will be used to continue the observable chain.\n * @return A function that returns an Observable that originates from either\n * the source or the Observable returned by the `selector` function.\n */\nexport function catchError<T, O extends ObservableInput<any>>(\n  selector: (err: any, caught: Observable<T>) => O\n): OperatorFunction<T, T | ObservedValueOf<O>> {\n  return operate((source, subscriber) => {\n    let innerSub: Subscription | null = null;\n    let syncUnsub = false;\n    let handledResult: Observable<ObservedValueOf<O>>;\n\n    innerSub = source.subscribe(\n      createOperatorSubscriber(subscriber, undefined, undefined, (err) => {\n        handledResult = innerFrom(selector(err, catchError(selector)(source)));\n        if (innerSub) {\n          innerSub.unsubscribe();\n          innerSub = null;\n          handledResult.subscribe(subscriber);\n        } else {\n          // We don't have an innerSub yet, that means the error was synchronous\n          // because the subscribe call hasn't returned yet.\n          syncUnsub = true;\n        }\n      })\n    );\n\n    if (syncUnsub) {\n      // We have a synchronous error, we need to make sure to\n      // finalize right away. This ensures that callbacks in the `finalize` operator are called\n      // at the right time, and that finalization occurs at the expected\n      // time between the source error and the subscription to the\n      // next observable.\n      innerSub.unsubscribe();\n      innerSub = null;\n      handledResult!.subscribe(subscriber);\n    }\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/combineAll.ts",
    "content": "import { combineLatestAll } from './combineLatestAll';\n\n/**\n * @deprecated Renamed to {@link combineLatestAll}. Will be removed in v8.\n */\nexport const combineAll = combineLatestAll;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/combineLatest.ts",
    "content": "import { combineLatestInit } from '../observable/combineLatest';\nimport { ObservableInput, ObservableInputTuple, OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { pipe } from '../util/pipe';\nimport { popResultSelector } from '../util/args';\n\n/** @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. */\nexport function combineLatest<T, A extends readonly unknown[], R>(\n  sources: [...ObservableInputTuple<A>],\n  project: (...values: [T, ...A]) => R\n): OperatorFunction<T, R>;\n/** @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. */\nexport function combineLatest<T, A extends readonly unknown[], R>(sources: [...ObservableInputTuple<A>]): OperatorFunction<T, [T, ...A]>;\n\n/** @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. */\nexport function combineLatest<T, A extends readonly unknown[], R>(\n  ...sourcesAndProject: [...ObservableInputTuple<A>, (...values: [T, ...A]) => R]\n): OperatorFunction<T, R>;\n/** @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8. */\nexport function combineLatest<T, A extends readonly unknown[], R>(...sources: [...ObservableInputTuple<A>]): OperatorFunction<T, [T, ...A]>;\n\n/**\n * @deprecated Replaced with {@link combineLatestWith}. Will be removed in v8.\n */\nexport function combineLatest<T, R>(...args: (ObservableInput<any> | ((...values: any[]) => R))[]): OperatorFunction<T, unknown> {\n  const resultSelector = popResultSelector(args);\n  return resultSelector\n    ? pipe(combineLatest(...(args as Array<ObservableInput<any>>)), mapOneOrManyArgs(resultSelector))\n    : operate((source, subscriber) => {\n        combineLatestInit([source, ...argsOrArgArray(args)])(subscriber);\n      });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/combineLatestAll.ts",
    "content": "import { combineLatest } from '../observable/combineLatest';\nimport { OperatorFunction, ObservableInput } from '../types';\nimport { joinAllInternals } from './joinAllInternals';\n\nexport function combineLatestAll<T>(): OperatorFunction<ObservableInput<T>, T[]>;\nexport function combineLatestAll<T>(): OperatorFunction<any, T[]>;\nexport function combineLatestAll<T, R>(project: (...values: T[]) => R): OperatorFunction<ObservableInput<T>, R>;\nexport function combineLatestAll<R>(project: (...values: Array<any>) => R): OperatorFunction<any, R>;\n\n/**\n * Flattens an Observable-of-Observables by applying {@link combineLatest} when the Observable-of-Observables completes.\n *\n * `combineLatestAll` takes an Observable of Observables, and collects all Observables from it. Once the outer Observable completes,\n * it subscribes to all collected Observables and combines their values using the {@link combineLatest} strategy, such that:\n *\n * * Every time an inner Observable emits, the output Observable emits\n * * When the returned observable emits, it emits all of the latest values by:\n *    * If a `project` function is provided, it is called with each recent value from each inner Observable in whatever order they\n *      arrived, and the result of the `project` function is what is emitted by the output Observable.\n *    * If there is no `project` function, an array of all the most recent values is emitted by the output Observable.\n *\n * ## Example\n *\n * Map two click events to a finite interval Observable, then apply `combineLatestAll`\n *\n * ```ts\n * import { fromEvent, map, interval, take, combineLatestAll } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const higherOrder = clicks.pipe(\n *   map(() => interval(Math.random() * 2000).pipe(take(3))),\n *   take(2)\n * );\n * const result = higherOrder.pipe(combineLatestAll());\n *\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link combineLatest}\n * @see {@link combineLatestWith}\n * @see {@link mergeAll}\n *\n * @param project optional function to map the most recent values from each inner Observable into a new result.\n * Takes each of the most recent values from each collected inner Observable as arguments, in order.\n * @return A function that returns an Observable that flattens Observables\n * emitted by the source Observable.\n */\nexport function combineLatestAll<R>(project?: (...values: Array<any>) => R) {\n  return joinAllInternals(combineLatest, project);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/combineLatestWith.ts",
    "content": "import { ObservableInputTuple, OperatorFunction, Cons } from '../types';\nimport { combineLatest } from './combineLatest';\n\n/**\n * Create an observable that combines the latest values from all passed observables and the source\n * into arrays and emits them.\n *\n * Returns an observable, that when subscribed to, will subscribe to the source observable and all\n * sources provided as arguments. Once all sources emit at least one value, all of the latest values\n * will be emitted as an array. After that, every time any source emits a value, all of the latest values\n * will be emitted as an array.\n *\n * This is a useful operator for eagerly calculating values based off of changed inputs.\n *\n * ## Example\n *\n * Simple concatenation of values from two inputs\n *\n * ```ts\n * import { fromEvent, combineLatestWith, map } from 'valdi_rxjs';\n *\n * // Setup: Add two inputs to the page\n * const input1 = document.createElement('input');\n * document.body.appendChild(input1);\n * const input2 = document.createElement('input');\n * document.body.appendChild(input2);\n *\n * // Get streams of changes\n * const input1Changes$ = fromEvent(input1, 'change');\n * const input2Changes$ = fromEvent(input2, 'change');\n *\n * // Combine the changes by adding them together\n * input1Changes$.pipe(\n *   combineLatestWith(input2Changes$),\n *   map(([e1, e2]) => (<HTMLInputElement>e1.target).value + ' - ' + (<HTMLInputElement>e2.target).value)\n * )\n * .subscribe(x => console.log(x));\n * ```\n *\n * @param otherSources the other sources to subscribe to.\n * @return A function that returns an Observable that emits the latest\n * emissions from both source and provided Observables.\n */\nexport function combineLatestWith<T, A extends readonly unknown[]>(\n  ...otherSources: [...ObservableInputTuple<A>]\n): OperatorFunction<T, Cons<T, A>> {\n  return combineLatest(...otherSources);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/concat.ts",
    "content": "import { ObservableInputTuple, OperatorFunction, SchedulerLike } from '../types';\nimport { operate } from '../util/lift';\nimport { concatAll } from './concatAll';\nimport { popScheduler } from '../util/args';\nimport { from } from '../observable/from';\n\n/** @deprecated Replaced with {@link concatWith}. Will be removed in v8. */\nexport function concat<T, A extends readonly unknown[]>(...sources: [...ObservableInputTuple<A>]): OperatorFunction<T, T | A[number]>;\n/** @deprecated Replaced with {@link concatWith}. Will be removed in v8. */\nexport function concat<T, A extends readonly unknown[]>(\n  ...sourcesAndScheduler: [...ObservableInputTuple<A>, SchedulerLike]\n): OperatorFunction<T, T | A[number]>;\n\n/**\n * @deprecated Replaced with {@link concatWith}. Will be removed in v8.\n */\nexport function concat<T, R>(...args: any[]): OperatorFunction<T, R> {\n  const scheduler = popScheduler(args);\n  return operate((source, subscriber) => {\n    concatAll()(from([source, ...args], scheduler)).subscribe(subscriber);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/concatAll.ts",
    "content": "import { mergeAll } from './mergeAll';\nimport { OperatorFunction, ObservableInput, ObservedValueOf } from '../types';\n\n/**\n * Converts a higher-order Observable into a first-order Observable by\n * concatenating the inner Observables in order.\n *\n * <span class=\"informal\">Flattens an Observable-of-Observables by putting one\n * inner Observable after the other.</span>\n *\n * ![](concatAll.svg)\n *\n * Joins every Observable emitted by the source (a higher-order Observable), in\n * a serial fashion. It subscribes to each inner Observable only after the\n * previous inner Observable has completed, and merges all of their values into\n * the returned observable.\n *\n * __Warning:__ If the source Observable emits Observables quickly and\n * endlessly, and the inner Observables it emits generally complete slower than\n * the source emits, you can run into memory issues as the incoming Observables\n * collect in an unbounded buffer.\n *\n * Note: `concatAll` is equivalent to `mergeAll` with concurrency parameter set\n * to `1`.\n *\n * ## Example\n *\n * For each click event, tick every second from 0 to 3, with no concurrency\n *\n * ```ts\n * import { fromEvent, map, interval, take, concatAll } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const higherOrder = clicks.pipe(\n *   map(() => interval(1000).pipe(take(4)))\n * );\n * const firstOrder = higherOrder.pipe(concatAll());\n * firstOrder.subscribe(x => console.log(x));\n *\n * // Results in the following:\n * // (results are not concurrent)\n * // For every click on the \"document\" it will emit values 0 to 3 spaced\n * // on a 1000ms interval\n * // one click = 1000ms-> 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3\n * ```\n *\n * @see {@link combineLatestAll}\n * @see {@link concat}\n * @see {@link concatMap}\n * @see {@link concatMapTo}\n * @see {@link exhaustAll}\n * @see {@link mergeAll}\n * @see {@link switchAll}\n * @see {@link switchMap}\n * @see {@link zipAll}\n *\n * @return A function that returns an Observable emitting values from all the\n * inner Observables concatenated.\n */\nexport function concatAll<O extends ObservableInput<any>>(): OperatorFunction<O, ObservedValueOf<O>> {\n  return mergeAll(1);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/concatMap.ts",
    "content": "import { mergeMap } from './mergeMap';\nimport { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';\nimport { isFunction } from '../util/isFunction';\n\n/* tslint:disable:max-line-length */\nexport function concatMap<T, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O\n): OperatorFunction<T, ObservedValueOf<O>>;\n/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */\nexport function concatMap<T, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  resultSelector: undefined\n): OperatorFunction<T, ObservedValueOf<O>>;\n/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */\nexport function concatMap<T, R, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R\n): OperatorFunction<T, R>;\n/* tslint:enable:max-line-length */\n\n/**\n * Projects each source value to an Observable which is merged in the output\n * Observable, in a serialized fashion waiting for each one to complete before\n * merging the next.\n *\n * <span class=\"informal\">Maps each value to an Observable, then flattens all of\n * these inner Observables using {@link concatAll}.</span>\n *\n * ![](concatMap.png)\n *\n * Returns an Observable that emits items based on applying a function that you\n * supply to each item emitted by the source Observable, where that function\n * returns an (so-called \"inner\") Observable. Each new inner Observable is\n * concatenated with the previous inner Observable.\n *\n * __Warning:__ if source values arrive endlessly and faster than their\n * corresponding inner Observables can complete, it will result in memory issues\n * as inner Observables amass in an unbounded buffer waiting for their turn to\n * be subscribed to.\n *\n * Note: `concatMap` is equivalent to `mergeMap` with concurrency parameter set\n * to `1`.\n *\n * ## Example\n *\n * For each click event, tick every second from 0 to 3, with no concurrency\n *\n * ```ts\n * import { fromEvent, concatMap, interval, take } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(\n *   concatMap(ev => interval(1000).pipe(take(4)))\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following:\n * // (results are not concurrent)\n * // For every click on the \"document\" it will emit values 0 to 3 spaced\n * // on a 1000ms interval\n * // one click = 1000ms-> 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3\n * ```\n *\n * @see {@link concat}\n * @see {@link concatAll}\n * @see {@link concatMapTo}\n * @see {@link exhaustMap}\n * @see {@link mergeMap}\n * @see {@link switchMap}\n *\n * @param {function(value: T, ?index: number): ObservableInput} project A function\n * that, when applied to an item emitted by the source Observable, returns an\n * Observable.\n * @return A function that returns an Observable that emits the result of\n * applying the projection function (and the optional deprecated\n * `resultSelector`) to each item emitted by the source Observable and taking\n * values from each projected inner Observable sequentially.\n */\nexport function concatMap<T, R, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R\n): OperatorFunction<T, ObservedValueOf<O> | R> {\n  return isFunction(resultSelector) ? mergeMap(project, resultSelector, 1) : mergeMap(project, 1);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/concatMapTo.ts",
    "content": "import { concatMap } from './concatMap';\nimport { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';\nimport { isFunction } from '../util/isFunction';\n\n/** @deprecated Will be removed in v9. Use {@link concatMap} instead: `concatMap(() => result)` */\nexport function concatMapTo<O extends ObservableInput<unknown>>(observable: O): OperatorFunction<unknown, ObservedValueOf<O>>;\n/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */\nexport function concatMapTo<O extends ObservableInput<unknown>>(\n  observable: O,\n  resultSelector: undefined\n): OperatorFunction<unknown, ObservedValueOf<O>>;\n/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */\nexport function concatMapTo<T, R, O extends ObservableInput<unknown>>(\n  observable: O,\n  resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R\n): OperatorFunction<T, R>;\n\n/**\n * Projects each source value to the same Observable which is merged multiple\n * times in a serialized fashion on the output Observable.\n *\n * <span class=\"informal\">It's like {@link concatMap}, but maps each value\n * always to the same inner Observable.</span>\n *\n * ![](concatMapTo.png)\n *\n * Maps each source value to the given Observable `innerObservable` regardless\n * of the source value, and then flattens those resulting Observables into one\n * single Observable, which is the output Observable. Each new `innerObservable`\n * instance emitted on the output Observable is concatenated with the previous\n * `innerObservable` instance.\n *\n * __Warning:__ if source values arrive endlessly and faster than their\n * corresponding inner Observables can complete, it will result in memory issues\n * as inner Observables amass in an unbounded buffer waiting for their turn to\n * be subscribed to.\n *\n * Note: `concatMapTo` is equivalent to `mergeMapTo` with concurrency parameter\n * set to `1`.\n *\n * ## Example\n *\n * For each click event, tick every second from 0 to 3, with no concurrency\n *\n * ```ts\n * import { fromEvent, concatMapTo, interval, take } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(\n *   concatMapTo(interval(1000).pipe(take(4)))\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following:\n * // (results are not concurrent)\n * // For every click on the \"document\" it will emit values 0 to 3 spaced\n * // on a 1000ms interval\n * // one click = 1000ms-> 0 -1000ms-> 1 -1000ms-> 2 -1000ms-> 3\n * ```\n *\n * @see {@link concat}\n * @see {@link concatAll}\n * @see {@link concatMap}\n * @see {@link mergeMapTo}\n * @see {@link switchMapTo}\n *\n * @param {ObservableInput} innerObservable An Observable to replace each value from\n * the source Observable.\n * @return A function that returns an Observable of values merged together by\n * joining the passed Observable with itself, one after the other, for each\n * value emitted from the source.\n * @deprecated Will be removed in v9. Use {@link concatMap} instead: `concatMap(() => result)`\n */\nexport function concatMapTo<T, R, O extends ObservableInput<unknown>>(\n  innerObservable: O,\n  resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R\n): OperatorFunction<T, ObservedValueOf<O> | R> {\n  return isFunction(resultSelector) ? concatMap(() => innerObservable, resultSelector) : concatMap(() => innerObservable);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/concatWith.ts",
    "content": "import { ObservableInputTuple, OperatorFunction } from '../types';\nimport { concat } from './concat';\n\n/**\n * Emits all of the values from the source observable, then, once it completes, subscribes\n * to each observable source provided, one at a time, emitting all of their values, and not subscribing\n * to the next one until it completes.\n *\n * `concat(a$, b$, c$)` is the same as `a$.pipe(concatWith(b$, c$))`.\n *\n * ## Example\n *\n * Listen for one mouse click, then listen for all mouse moves.\n *\n * ```ts\n * import { fromEvent, map, take, concatWith } from 'valdi_rxjs';\n *\n * const clicks$ = fromEvent(document, 'click');\n * const moves$ = fromEvent(document, 'mousemove');\n *\n * clicks$.pipe(\n *   map(() => 'click'),\n *   take(1),\n *   concatWith(\n *     moves$.pipe(\n *       map(() => 'move')\n *     )\n *   )\n * )\n * .subscribe(x => console.log(x));\n *\n * // 'click'\n * // 'move'\n * // 'move'\n * // 'move'\n * // ...\n * ```\n *\n * @param otherSources Other observable sources to subscribe to, in sequence, after the original source is complete.\n * @return A function that returns an Observable that concatenates\n * subscriptions to the source and provided Observables subscribing to the next\n * only once the current subscription completes.\n */\nexport function concatWith<T, A extends readonly unknown[]>(\n  ...otherSources: [...ObservableInputTuple<A>]\n): OperatorFunction<T, T | A[number]> {\n  return concat(...otherSources);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/connect.ts",
    "content": "import { OperatorFunction, ObservableInput, ObservedValueOf, SubjectLike } from '../types';\nimport { Observable } from '../Observable';\nimport { Subject } from '../Subject';\nimport { from } from '../observable/from';\nimport { operate } from '../util/lift';\nimport { fromSubscribable } from '../observable/fromSubscribable';\n\n/**\n * An object used to configure {@link connect} operator.\n */\nexport interface ConnectConfig<T> {\n  /**\n   * A factory function used to create the Subject through which the source\n   * is multicast. By default, this creates a {@link Subject}.\n   */\n  connector: () => SubjectLike<T>;\n}\n\n/**\n * The default configuration for `connect`.\n */\nconst DEFAULT_CONFIG: ConnectConfig<unknown> = {\n  connector: () => new Subject<unknown>(),\n};\n\n/**\n * Creates an observable by multicasting the source within a function that\n * allows the developer to define the usage of the multicast prior to connection.\n *\n * This is particularly useful if the observable source you wish to multicast could\n * be synchronous or asynchronous. This sets it apart from {@link share}, which, in the\n * case of totally synchronous sources will fail to share a single subscription with\n * multiple consumers, as by the time the subscription to the result of {@link share}\n * has returned, if the source is synchronous its internal reference count will jump from\n * 0 to 1 back to 0 and reset.\n *\n * To use `connect`, you provide a `selector` function that will give you\n * a multicast observable that is not yet connected. You then use that multicast observable\n * to create a resulting observable that, when subscribed, will set up your multicast. This is\n * generally, but not always, accomplished with {@link merge}.\n *\n * Note that using a {@link takeUntil} inside of `connect`'s `selector` _might_ mean you were looking\n * to use the {@link takeWhile} operator instead.\n *\n * When you subscribe to the result of `connect`, the `selector` function will be called. After\n * the `selector` function returns, the observable it returns will be subscribed to, _then_ the\n * multicast will be connected to the source.\n *\n * ## Example\n *\n * Sharing a totally synchronous observable\n *\n * ```ts\n * import { of, tap, connect, merge, map, filter } from 'valdi_rxjs';\n *\n * const source$ = of(1, 2, 3, 4, 5).pipe(\n *   tap({\n *     subscribe: () => console.log('subscription started'),\n *     next: n => console.log(`source emitted ${ n }`)\n *   })\n * );\n *\n * source$.pipe(\n *   // Notice in here we're merging 3 subscriptions to `shared$`.\n *   connect(shared$ => merge(\n *     shared$.pipe(map(n => `all ${ n }`)),\n *     shared$.pipe(filter(n => n % 2 === 0), map(n => `even ${ n }`)),\n *     shared$.pipe(filter(n => n % 2 === 1), map(n => `odd ${ n }`))\n *   ))\n * )\n * .subscribe(console.log);\n *\n * // Expected output: (notice only one subscription)\n * 'subscription started'\n * 'source emitted 1'\n * 'all 1'\n * 'odd 1'\n * 'source emitted 2'\n * 'all 2'\n * 'even 2'\n * 'source emitted 3'\n * 'all 3'\n * 'odd 3'\n * 'source emitted 4'\n * 'all 4'\n * 'even 4'\n * 'source emitted 5'\n * 'all 5'\n * 'odd 5'\n * ```\n *\n * @param selector A function used to set up the multicast. Gives you a multicast observable\n * that is not yet connected. With that, you're expected to create and return\n * and Observable, that when subscribed to, will utilize the multicast observable.\n * After this function is executed -- and its return value subscribed to -- the\n * operator will subscribe to the source, and the connection will be made.\n * @param config The configuration object for `connect`.\n */\nexport function connect<T, O extends ObservableInput<unknown>>(\n  selector: (shared: Observable<T>) => O,\n  config: ConnectConfig<T> = DEFAULT_CONFIG\n): OperatorFunction<T, ObservedValueOf<O>> {\n  const { connector } = config;\n  return operate((source, subscriber) => {\n    const subject = connector();\n    from(selector(fromSubscribable(subject))).subscribe(subscriber);\n    subscriber.add(source.subscribe(subject));\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/count.ts",
    "content": "import { OperatorFunction } from '../types';\nimport { reduce } from './reduce';\n\n/**\n * Counts the number of emissions on the source and emits that number when the\n * source completes.\n *\n * <span class=\"informal\">Tells how many values were emitted, when the source\n * completes.</span>\n *\n * ![](count.png)\n *\n * `count` transforms an Observable that emits values into an Observable that\n * emits a single value that represents the number of values emitted by the\n * source Observable. If the source Observable terminates with an error, `count`\n * will pass this error notification along without emitting a value first. If\n * the source Observable does not terminate at all, `count` will neither emit\n * a value nor terminate. This operator takes an optional `predicate` function\n * as argument, in which case the output emission will represent the number of\n * source values that matched `true` with the `predicate`.\n *\n * ## Examples\n *\n * Counts how many seconds have passed before the first click happened\n *\n * ```ts\n * import { interval, fromEvent, takeUntil, count } from 'valdi_rxjs';\n *\n * const seconds = interval(1000);\n * const clicks = fromEvent(document, 'click');\n * const secondsBeforeClick = seconds.pipe(takeUntil(clicks));\n * const result = secondsBeforeClick.pipe(count());\n * result.subscribe(x => console.log(x));\n * ```\n *\n * Counts how many odd numbers are there between 1 and 7\n *\n * ```ts\n * import { range, count } from 'valdi_rxjs';\n *\n * const numbers = range(1, 7);\n * const result = numbers.pipe(count(i => i % 2 === 1));\n * result.subscribe(x => console.log(x));\n * // Results in:\n * // 4\n * ```\n *\n * @see {@link max}\n * @see {@link min}\n * @see {@link reduce}\n *\n * @param predicate A function that is used to analyze the value and the index and\n * determine whether or not to increment the count. Return `true` to increment the count,\n * and return `false` to keep the count the same.\n * If the predicate is not provided, every value will be counted.\n * @return A function that returns an Observable that emits one number that\n * represents the count of emissions.\n */\nexport function count<T>(predicate?: (value: T, index: number) => boolean): OperatorFunction<T, number> {\n  return reduce((total, value, i) => (!predicate || predicate(value, i) ? total + 1 : total), 0);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/debounce.ts",
    "content": "import { Subscriber } from '../Subscriber';\nimport { MonoTypeOperatorFunction, ObservableInput } from '../types';\nimport { operate } from '../util/lift';\nimport { noop } from '../util/noop';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\n\n/**\n * Emits a notification from the source Observable only after a particular time span\n * determined by another Observable has passed without another source emission.\n *\n * <span class=\"informal\">It's like {@link debounceTime}, but the time span of\n * emission silence is determined by a second Observable.</span>\n *\n * ![](debounce.svg)\n *\n * `debounce` delays notifications emitted by the source Observable, but drops previous\n * pending delayed emissions if a new notification arrives on the source Observable.\n * This operator keeps track of the most recent notification from the source\n * Observable, and spawns a duration Observable by calling the\n * `durationSelector` function. The notification is emitted only when the duration\n * Observable emits a next notification, and if no other notification was emitted on\n * the source Observable since the duration Observable was spawned. If a new\n * notification appears before the duration Observable emits, the previous notification will\n * not be emitted and a new duration is scheduled from `durationSelector` is scheduled.\n * If the completing event happens during the scheduled duration the last cached notification\n * is emitted before the completion event is forwarded to the output observable.\n * If the error event happens during the scheduled duration or after it only the error event is\n * forwarded to the output observable. The cache notification is not emitted in this case.\n *\n * Like {@link debounceTime}, this is a rate-limiting operator, and also a\n * delay-like operator since output emissions do not necessarily occur at the\n * same time as they did on the source Observable.\n *\n * ## Example\n *\n * Emit the most recent click after a burst of clicks\n *\n * ```ts\n * import { fromEvent, scan, debounce, interval } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(\n *   scan(i => ++i, 1),\n *   debounce(i => interval(200 * i))\n * );\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link audit}\n * @see {@link auditTime}\n * @see {@link debounceTime}\n * @see {@link delay}\n * @see {@link sample}\n * @see {@link sampleTime}\n * @see {@link throttle}\n * @see {@link throttleTime}\n *\n * @param durationSelector A function\n * that receives a value from the source Observable, for computing the timeout\n * duration for each source value, returned as an Observable or a Promise.\n * @return A function that returns an Observable that delays the emissions of\n * the source Observable by the specified duration Observable returned by\n * `durationSelector`, and may drop some values if they occur too frequently.\n */\nexport function debounce<T>(durationSelector: (value: T) => ObservableInput<any>): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    let hasValue = false;\n    let lastValue: T | null = null;\n    // The subscriber/subscription for the current debounce, if there is one.\n    let durationSubscriber: Subscriber<any> | null = null;\n\n    const emit = () => {\n      // Unsubscribe any current debounce subscription we have,\n      // we only cared about the first notification from it, and we\n      // want to clean that subscription up as soon as possible.\n      durationSubscriber?.unsubscribe();\n      durationSubscriber = null;\n      if (hasValue) {\n        // We have a value! Free up memory first, then emit the value.\n        hasValue = false;\n        const value = lastValue!;\n        lastValue = null;\n        subscriber.next(value);\n      }\n    };\n\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value: T) => {\n          // Cancel any pending debounce duration. We don't\n          // need to null it out here yet tho, because we're just going\n          // to create another one in a few lines.\n          durationSubscriber?.unsubscribe();\n          hasValue = true;\n          lastValue = value;\n          // Capture our duration subscriber, so we can unsubscribe it when we're notified\n          // and we're going to emit the value.\n          durationSubscriber = createOperatorSubscriber(subscriber, emit, noop);\n          // Subscribe to the duration.\n          innerFrom(durationSelector(value)).subscribe(durationSubscriber);\n        },\n        () => {\n          // Source completed.\n          // Emit any pending debounced values then complete\n          emit();\n          subscriber.complete();\n        },\n        // Pass all errors through to consumer\n        undefined,\n        () => {\n          // Finalization.\n          lastValue = durationSubscriber = null;\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/debounceTime.ts",
    "content": "import { asyncScheduler } from '../scheduler/async';\nimport { Subscription } from '../Subscription';\nimport { MonoTypeOperatorFunction, SchedulerAction, SchedulerLike } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Emits a notification from the source Observable only after a particular time span\n * has passed without another source emission.\n *\n * <span class=\"informal\">It's like {@link delay}, but passes only the most\n * recent notification from each burst of emissions.</span>\n *\n * ![](debounceTime.png)\n *\n * `debounceTime` delays notifications emitted by the source Observable, but drops\n * previous pending delayed emissions if a new notification arrives on the source\n * Observable. This operator keeps track of the most recent notification from the\n * source Observable, and emits that only when `dueTime` has passed\n * without any other notification appearing on the source Observable. If a new value\n * appears before `dueTime` silence occurs, the previous notification will be dropped\n * and will not be emitted and a new `dueTime` is scheduled.\n * If the completing event happens during `dueTime` the last cached notification\n * is emitted before the completion event is forwarded to the output observable.\n * If the error event happens during `dueTime` or after it only the error event is\n * forwarded to the output observable. The cache notification is not emitted in this case.\n *\n * This is a rate-limiting operator, because it is impossible for more than one\n * notification to be emitted in any time window of duration `dueTime`, but it is also\n * a delay-like operator since output emissions do not occur at the same time as\n * they did on the source Observable. Optionally takes a {@link SchedulerLike} for\n * managing timers.\n *\n * ## Example\n *\n * Emit the most recent click after a burst of clicks\n *\n * ```ts\n * import { fromEvent, debounceTime } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(debounceTime(1000));\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link audit}\n * @see {@link auditTime}\n * @see {@link debounce}\n * @see {@link sample}\n * @see {@link sampleTime}\n * @see {@link throttle}\n * @see {@link throttleTime}\n *\n * @param {number} dueTime The timeout duration in milliseconds (or the time\n * unit determined internally by the optional `scheduler`) for the window of\n * time required to wait for emission silence before emitting the most recent\n * source value.\n * @param {SchedulerLike} [scheduler=async] The {@link SchedulerLike} to use for\n * managing the timers that handle the timeout for each value.\n * @return A function that returns an Observable that delays the emissions of\n * the source Observable by the specified `dueTime`, and may drop some values\n * if they occur too frequently.\n */\nexport function debounceTime<T>(dueTime: number, scheduler: SchedulerLike = asyncScheduler): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    let activeTask: Subscription | null = null;\n    let lastValue: T | null = null;\n    let lastTime: number | null = null;\n\n    const emit = () => {\n      if (activeTask) {\n        // We have a value! Free up memory first, then emit the value.\n        activeTask.unsubscribe();\n        activeTask = null;\n        const value = lastValue!;\n        lastValue = null;\n        subscriber.next(value);\n      }\n    };\n    function emitWhenIdle(this: SchedulerAction<unknown>) {\n      // This is called `dueTime` after the first value\n      // but we might have received new values during this window!\n\n      const targetTime = lastTime! + dueTime;\n      const now = scheduler.now();\n      if (now < targetTime) {\n        // On that case, re-schedule to the new target\n        activeTask = this.schedule(undefined, targetTime - now);\n        subscriber.add(activeTask);\n        return;\n      }\n\n      emit();\n    }\n\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value: T) => {\n          lastValue = value;\n          lastTime = scheduler.now();\n\n          // Only set up a task if it's not already up\n          if (!activeTask) {\n            activeTask = scheduler.schedule(emitWhenIdle, dueTime);\n            subscriber.add(activeTask);\n          }\n        },\n        () => {\n          // Source completed.\n          // Emit any pending debounced values then complete\n          emit();\n          subscriber.complete();\n        },\n        // Pass all errors through to consumer.\n        undefined,\n        () => {\n          // Finalization.\n          lastValue = activeTask = null;\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/defaultIfEmpty.ts",
    "content": "import { OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Emits a given value if the source Observable completes without emitting any\n * `next` value, otherwise mirrors the source Observable.\n *\n * <span class=\"informal\">If the source Observable turns out to be empty, then\n * this operator will emit a default value.</span>\n *\n * ![](defaultIfEmpty.png)\n *\n * `defaultIfEmpty` emits the values emitted by the source Observable or a\n * specified default value if the source Observable is empty (completes without\n * having emitted any `next` value).\n *\n * ## Example\n *\n * If no clicks happen in 5 seconds, then emit 'no clicks'\n *\n * ```ts\n * import { fromEvent, takeUntil, interval, defaultIfEmpty } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const clicksBeforeFive = clicks.pipe(takeUntil(interval(5000)));\n * const result = clicksBeforeFive.pipe(defaultIfEmpty('no clicks'));\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link empty}\n * @see {@link last}\n *\n * @param defaultValue The default value used if the source\n * Observable is empty.\n * @return A function that returns an Observable that emits either the\n * specified `defaultValue` if the source Observable emits no items, or the\n * values emitted by the source Observable.\n */\nexport function defaultIfEmpty<T, R>(defaultValue: R): OperatorFunction<T, T | R> {\n  return operate((source, subscriber) => {\n    let hasValue = false;\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => {\n          hasValue = true;\n          subscriber.next(value);\n        },\n        () => {\n          if (!hasValue) {\n            subscriber.next(defaultValue!);\n          }\n          subscriber.complete();\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/delay.ts",
    "content": "import { asyncScheduler } from '../scheduler/async';\nimport { MonoTypeOperatorFunction, SchedulerLike } from '../types';\nimport { delayWhen } from './delayWhen';\nimport { timer } from '../observable/timer';\n\n/**\n * Delays the emission of items from the source Observable by a given timeout or\n * until a given Date.\n *\n * <span class=\"informal\">Time shifts each item by some specified amount of\n * milliseconds.</span>\n *\n * ![](delay.svg)\n *\n * If the delay argument is a Number, this operator time shifts the source\n * Observable by that amount of time expressed in milliseconds. The relative\n * time intervals between the values are preserved.\n *\n * If the delay argument is a Date, this operator time shifts the start of the\n * Observable execution until the given date occurs.\n *\n * ## Examples\n *\n * Delay each click by one second\n *\n * ```ts\n * import { fromEvent, delay } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const delayedClicks = clicks.pipe(delay(1000)); // each click emitted after 1 second\n * delayedClicks.subscribe(x => console.log(x));\n * ```\n *\n * Delay all clicks until a future date happens\n *\n * ```ts\n * import { fromEvent, delay } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const date = new Date('March 15, 2050 12:00:00'); // in the future\n * const delayedClicks = clicks.pipe(delay(date)); // click emitted only after that date\n * delayedClicks.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link delayWhen}\n * @see {@link throttle}\n * @see {@link throttleTime}\n * @see {@link debounce}\n * @see {@link debounceTime}\n * @see {@link sample}\n * @see {@link sampleTime}\n * @see {@link audit}\n * @see {@link auditTime}\n *\n * @param {number|Date} due The delay duration in milliseconds (a `number`) or\n * a `Date` until which the emission of the source items is delayed.\n * @param {SchedulerLike} [scheduler=async] The {@link SchedulerLike} to use for\n * managing the timers that handle the time-shift for each item.\n * @return A function that returns an Observable that delays the emissions of\n * the source Observable by the specified timeout or Date.\n */\nexport function delay<T>(due: number | Date, scheduler: SchedulerLike = asyncScheduler): MonoTypeOperatorFunction<T> {\n  const duration = timer(due, scheduler);\n  return delayWhen(() => duration);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/delayWhen.ts",
    "content": "import { Observable } from '../Observable';\nimport { MonoTypeOperatorFunction } from '../types';\nimport { concat } from '../observable/concat';\nimport { take } from './take';\nimport { ignoreElements } from './ignoreElements';\nimport { mapTo } from './mapTo';\nimport { mergeMap } from './mergeMap';\n\n/** @deprecated The `subscriptionDelay` parameter will be removed in v8. */\nexport function delayWhen<T>(\n  delayDurationSelector: (value: T, index: number) => Observable<any>,\n  subscriptionDelay: Observable<any>\n): MonoTypeOperatorFunction<T>;\nexport function delayWhen<T>(delayDurationSelector: (value: T, index: number) => Observable<any>): MonoTypeOperatorFunction<T>;\n\n/**\n * Delays the emission of items from the source Observable by a given time span\n * determined by the emissions of another Observable.\n *\n * <span class=\"informal\">It's like {@link delay}, but the time span of the\n * delay duration is determined by a second Observable.</span>\n *\n * ![](delayWhen.png)\n *\n * `delayWhen` time shifts each emitted value from the source Observable by a\n * time span determined by another Observable. When the source emits a value,\n * the `delayDurationSelector` function is called with the source value as\n * argument, and should return an Observable, called the \"duration\" Observable.\n * The source value is emitted on the output Observable only when the duration\n * Observable emits a value or completes.\n * The completion of the notifier triggering the emission of the source value\n * is deprecated behavior and will be removed in future versions.\n *\n * Optionally, `delayWhen` takes a second argument, `subscriptionDelay`, which\n * is an Observable. When `subscriptionDelay` emits its first value or\n * completes, the source Observable is subscribed to and starts behaving like\n * described in the previous paragraph. If `subscriptionDelay` is not provided,\n * `delayWhen` will subscribe to the source Observable as soon as the output\n * Observable is subscribed.\n *\n * ## Example\n *\n * Delay each click by a random amount of time, between 0 and 5 seconds\n *\n * ```ts\n * import { fromEvent, delayWhen, interval } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const delayedClicks = clicks.pipe(\n *   delayWhen(() => interval(Math.random() * 5000))\n * );\n * delayedClicks.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link delay}\n * @see {@link throttle}\n * @see {@link throttleTime}\n * @see {@link debounce}\n * @see {@link debounceTime}\n * @see {@link sample}\n * @see {@link sampleTime}\n * @see {@link audit}\n * @see {@link auditTime}\n *\n * @param {function(value: T, index: number): Observable} delayDurationSelector A function that\n * returns an Observable for each value emitted by the source Observable, which\n * is then used to delay the emission of that item on the output Observable\n * until the Observable returned from this function emits a value.\n * @param {Observable} subscriptionDelay An Observable that triggers the\n * subscription to the source Observable once it emits any value.\n * @return A function that returns an Observable that delays the emissions of\n * the source Observable by an amount of time specified by the Observable\n * returned by `delayDurationSelector`.\n */\nexport function delayWhen<T>(\n  delayDurationSelector: (value: T, index: number) => Observable<any>,\n  subscriptionDelay?: Observable<any>\n): MonoTypeOperatorFunction<T> {\n  if (subscriptionDelay) {\n    // DEPRECATED PATH\n    return (source: Observable<T>) =>\n      concat(subscriptionDelay.pipe(take(1), ignoreElements()), source.pipe(delayWhen(delayDurationSelector)));\n  }\n\n  return mergeMap((value, index) => delayDurationSelector(value, index).pipe(take(1), mapTo(value)));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/dematerialize.ts",
    "content": "import { observeNotification } from '../Notification';\nimport { OperatorFunction, ObservableNotification, ValueFromNotification } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Converts an Observable of {@link ObservableNotification} objects into the emissions\n * that they represent.\n *\n * <span class=\"informal\">Unwraps {@link ObservableNotification} objects as actual `next`,\n * `error` and `complete` emissions. The opposite of {@link materialize}.</span>\n *\n * ![](dematerialize.png)\n *\n * `dematerialize` is assumed to operate an Observable that only emits\n * {@link ObservableNotification} objects as `next` emissions, and does not emit any\n * `error`. Such Observable is the output of a `materialize` operation. Those\n * notifications are then unwrapped using the metadata they contain, and emitted\n * as `next`, `error`, and `complete` on the output Observable.\n *\n * Use this operator in conjunction with {@link materialize}.\n *\n * ## Example\n *\n * Convert an Observable of Notifications to an actual Observable\n *\n * ```ts\n * import { NextNotification, ErrorNotification, of, dematerialize } from 'valdi_rxjs';\n *\n * const notifA: NextNotification<string> = { kind: 'N', value: 'A' };\n * const notifB: NextNotification<string> = { kind: 'N', value: 'B' };\n * const notifE: ErrorNotification = { kind: 'E', error: new TypeError('x.toUpperCase is not a function') };\n *\n * const materialized = of(notifA, notifB, notifE);\n *\n * const upperCase = materialized.pipe(dematerialize());\n * upperCase.subscribe({\n *   next: x => console.log(x),\n *   error: e => console.error(e)\n * });\n *\n * // Results in:\n * // A\n * // B\n * // TypeError: x.toUpperCase is not a function\n * ```\n *\n * @see {@link materialize}\n *\n * @return A function that returns an Observable that emits items and\n * notifications embedded in Notification objects emitted by the source\n * Observable.\n */\nexport function dematerialize<N extends ObservableNotification<any>>(): OperatorFunction<N, ValueFromNotification<N>> {\n  return operate((source, subscriber) => {\n    source.subscribe(createOperatorSubscriber(subscriber, (notification) => observeNotification(notification, subscriber)));\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/distinct.ts",
    "content": "import { Observable } from '../Observable';\nimport { MonoTypeOperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\n\n/**\n * Returns an Observable that emits all items emitted by the source Observable that are distinct by comparison from previous items.\n *\n * If a `keySelector` function is provided, then it will project each value from the source observable into a new value that it will\n * check for equality with previously projected values. If the `keySelector` function is not provided, it will use each value from the\n * source observable directly with an equality check against previous values.\n *\n * In JavaScript runtimes that support `Set`, this operator will use a `Set` to improve performance of the distinct value checking.\n *\n * In other runtimes, this operator will use a minimal implementation of `Set` that relies on an `Array` and `indexOf` under the\n * hood, so performance will degrade as more values are checked for distinction. Even in newer browsers, a long-running `distinct`\n * use might result in memory leaks. To help alleviate this in some scenarios, an optional `flushes` parameter is also provided so\n * that the internal `Set` can be \"flushed\", basically clearing it of values.\n *\n * ## Examples\n *\n * A simple example with numbers\n *\n * ```ts\n * import { of, distinct } from 'valdi_rxjs';\n *\n * of(1, 1, 2, 2, 2, 1, 2, 3, 4, 3, 2, 1)\n *   .pipe(distinct())\n *   .subscribe(x => console.log(x));\n *\n * // Outputs\n * // 1\n * // 2\n * // 3\n * // 4\n * ```\n *\n * An example using the `keySelector` function\n *\n * ```ts\n * import { of, distinct } from 'valdi_rxjs';\n *\n * of(\n *   { age: 4, name: 'Foo'},\n *   { age: 7, name: 'Bar'},\n *   { age: 5, name: 'Foo'}\n * )\n * .pipe(distinct(({ name }) => name))\n * .subscribe(x => console.log(x));\n *\n * // Outputs\n * // { age: 4, name: 'Foo' }\n * // { age: 7, name: 'Bar' }\n * ```\n * @see {@link distinctUntilChanged}\n * @see {@link distinctUntilKeyChanged}\n *\n * @param {function} [keySelector] Optional function to select which value you want to check as distinct.\n * @param {Observable} [flushes] Optional Observable for flushing the internal HashSet of the operator.\n * @return A function that returns an Observable that emits items from the\n * source Observable with distinct values.\n */\nexport function distinct<T, K>(keySelector?: (value: T) => K, flushes?: Observable<any>): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    const distinctKeys = new Set();\n    source.subscribe(\n      createOperatorSubscriber(subscriber, (value) => {\n        const key = keySelector ? keySelector(value) : value;\n        if (!distinctKeys.has(key)) {\n          distinctKeys.add(key);\n          subscriber.next(value);\n        }\n      })\n    );\n\n    flushes?.subscribe(createOperatorSubscriber(subscriber, () => distinctKeys.clear(), noop));\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/distinctUntilChanged.ts",
    "content": "import { MonoTypeOperatorFunction } from '../types';\nimport { identity } from '../util/identity';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Returns a result {@link Observable} that emits all values pushed by the source observable if they\n * are distinct in comparison to the last value the result observable emitted.\n *\n * 1. It will always emit the first value from the source.\n * 2. For all subsequent values pushed by the source, they will be compared to the previously emitted values\n *    using the provided `comparator` or an `===` equality check.\n * 3. If the value pushed by the source is determined to be unequal by this check, that value is emitted and\n *    becomes the new \"previously emitted value\" internally.\n *\n * ## Examples\n *\n * A very basic example with no `comparator`. Note that `1` is emitted more than once,\n * because it's distinct in comparison to the _previously emitted_ value,\n * not in comparison to _all other emitted values_.\n *\n * ```ts\n * import { of, distinctUntilChanged } from 'valdi_rxjs';\n *\n * of(1, 1, 1, 2, 2, 2, 1, 1, 3, 3)\n *   .pipe(distinctUntilChanged())\n *   .subscribe(console.log);\n * // Logs: 1, 2, 1, 3\n * ```\n *\n * With a `comparator`, you can do custom comparisons. Let's say\n * you only want to emit a value when all of its components have\n * changed:\n *\n * ```ts\n * import { of, distinctUntilChanged } from 'valdi_rxjs';\n *\n * const totallyDifferentBuilds$ = of(\n *   { engineVersion: '1.1.0', transmissionVersion: '1.2.0' },\n *   { engineVersion: '1.1.0', transmissionVersion: '1.4.0' },\n *   { engineVersion: '1.3.0', transmissionVersion: '1.4.0' },\n *   { engineVersion: '1.3.0', transmissionVersion: '1.5.0' },\n *   { engineVersion: '2.0.0', transmissionVersion: '1.5.0' }\n * ).pipe(\n *   distinctUntilChanged((prev, curr) => {\n *     return (\n *       prev.engineVersion === curr.engineVersion ||\n *       prev.transmissionVersion === curr.transmissionVersion\n *     );\n *   })\n * );\n *\n * totallyDifferentBuilds$.subscribe(console.log);\n *\n * // Logs:\n * // { engineVersion: '1.1.0', transmissionVersion: '1.2.0' }\n * // { engineVersion: '1.3.0', transmissionVersion: '1.4.0' }\n * // { engineVersion: '2.0.0', transmissionVersion: '1.5.0' }\n * ```\n *\n * You can also provide a custom `comparator` to check that emitted\n * changes are only in one direction. Let's say you only want to get\n * the next record temperature:\n *\n * ```ts\n * import { of, distinctUntilChanged } from 'valdi_rxjs';\n *\n * const temps$ = of(30, 31, 20, 34, 33, 29, 35, 20);\n *\n * const recordHighs$ = temps$.pipe(\n *   distinctUntilChanged((prevHigh, temp) => {\n *     // If the current temp is less than\n *     // or the same as the previous record,\n *     // the record hasn't changed.\n *     return temp <= prevHigh;\n *   })\n * );\n *\n * recordHighs$.subscribe(console.log);\n * // Logs: 30, 31, 34, 35\n * ```\n *\n * @param comparator A function used to compare the previous and current values for\n * equality. Defaults to a `===` check.\n * @return A function that returns an Observable that emits items from the\n * source Observable with distinct values.\n */\nexport function distinctUntilChanged<T>(comparator?: (previous: T, current: T) => boolean): MonoTypeOperatorFunction<T>;\n\n/**\n * Returns a result {@link Observable} that emits all values pushed by the source observable if they\n * are distinct in comparison to the last value the result observable emitted.\n *\n * 1. It will always emit the first value from the source.\n * 2. The `keySelector` will be run against all values, including the first value.\n * 3. For all values after the first, the selected key will be compared against the key selected from\n *    the previously emitted value using the `comparator`.\n * 4. If the keys are determined to be unequal by this check, the value (not the key), is emitted\n *    and the selected key from that value is saved for future comparisons against other keys.\n *\n * ## Example\n *\n * Selecting update events only when the `updatedBy` field shows\n * the account changed hands...\n *\n * ```ts\n * import { of, distinctUntilChanged } from 'valdi_rxjs';\n *\n * // A stream of updates to a given account\n * const accountUpdates$ = of(\n *   { updatedBy: 'blesh', data: [] },\n *   { updatedBy: 'blesh', data: [] },\n *   { updatedBy: 'ncjamieson', data: [] },\n *   { updatedBy: 'ncjamieson', data: [] },\n *   { updatedBy: 'blesh', data: [] }\n * );\n *\n * // We only want the events where it changed hands\n * const changedHands$ = accountUpdates$.pipe(\n *   distinctUntilChanged(undefined, update => update.updatedBy)\n * );\n *\n * changedHands$.subscribe(console.log);\n * // Logs:\n * // { updatedBy: 'blesh', data: Array[0] }\n * // { updatedBy: 'ncjamieson', data: Array[0] }\n * // { updatedBy: 'blesh', data: Array[0] }\n * ```\n *\n * @param comparator A function used to compare the previous and current keys for\n * equality. Defaults to a `===` check.\n * @param keySelector Used to select a key value to be passed to the `comparator`.\n * @return A function that returns an Observable that emits items from the\n * source Observable with distinct values.\n */\nexport function distinctUntilChanged<T, K>(\n  comparator: (previous: K, current: K) => boolean,\n  keySelector: (value: T) => K\n): MonoTypeOperatorFunction<T>;\n\nexport function distinctUntilChanged<T, K>(\n  comparator?: (previous: K, current: K) => boolean,\n  keySelector: (value: T) => K = identity as (value: T) => K\n): MonoTypeOperatorFunction<T> {\n  // We've been allowing `null` do be passed as the `compare`, so we can't do\n  // a default value for the parameter, because that will only work\n  // for `undefined`.\n  comparator = comparator ?? defaultCompare;\n\n  return operate((source, subscriber) => {\n    // The previous key, used to compare against keys selected\n    // from new arrivals to determine \"distinctiveness\".\n    let previousKey: K;\n    // Whether or not this is the first value we've gotten.\n    let first = true;\n\n    source.subscribe(\n      createOperatorSubscriber(subscriber, (value) => {\n        // We always call the key selector.\n        const currentKey = keySelector(value);\n\n        // If it's the first value, we always emit it.\n        // Otherwise, we compare this key to the previous key, and\n        // if the comparer returns false, we emit.\n        if (first || !comparator!(previousKey, currentKey)) {\n          // Update our state *before* we emit the value\n          // as emission can be the source of re-entrant code\n          // in functional libraries like this. We only really\n          // need to do this if it's the first value, or if the\n          // key we're tracking in previous needs to change.\n          first = false;\n          previousKey = currentKey;\n\n          // Emit the value!\n          subscriber.next(value);\n        }\n      })\n    );\n  });\n}\n\nfunction defaultCompare(a: any, b: any) {\n  return a === b;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/distinctUntilKeyChanged.ts",
    "content": "import { distinctUntilChanged } from './distinctUntilChanged';\nimport { MonoTypeOperatorFunction } from '../types';\n\n/* tslint:disable:max-line-length */\nexport function distinctUntilKeyChanged<T>(key: keyof T): MonoTypeOperatorFunction<T>;\nexport function distinctUntilKeyChanged<T, K extends keyof T>(key: K, compare: (x: T[K], y: T[K]) => boolean): MonoTypeOperatorFunction<T>;\n/* tslint:enable:max-line-length */\n\n/**\n * Returns an Observable that emits all items emitted by the source Observable that are distinct by comparison from the previous item,\n * using a property accessed by using the key provided to check if the two items are distinct.\n *\n * If a comparator function is provided, then it will be called for each item to test for whether or not that value should be emitted.\n *\n * If a comparator function is not provided, an equality check is used by default.\n *\n * ## Examples\n *\n * An example comparing the name of persons\n *\n * ```ts\n * import { of, distinctUntilKeyChanged } from 'valdi_rxjs';\n *\n * of(\n *   { age: 4, name: 'Foo' },\n *   { age: 7, name: 'Bar' },\n *   { age: 5, name: 'Foo' },\n *   { age: 6, name: 'Foo' }\n * ).pipe(\n *   distinctUntilKeyChanged('name')\n * )\n * .subscribe(x => console.log(x));\n *\n * // displays:\n * // { age: 4, name: 'Foo' }\n * // { age: 7, name: 'Bar' }\n * // { age: 5, name: 'Foo' }\n * ```\n *\n * An example comparing the first letters of the name\n *\n * ```ts\n * import { of, distinctUntilKeyChanged } from 'valdi_rxjs';\n *\n * of(\n *   { age: 4, name: 'Foo1' },\n *   { age: 7, name: 'Bar' },\n *   { age: 5, name: 'Foo2' },\n *   { age: 6, name: 'Foo3' }\n * ).pipe(\n *   distinctUntilKeyChanged('name', (x, y) => x.substring(0, 3) === y.substring(0, 3))\n * )\n * .subscribe(x => console.log(x));\n *\n * // displays:\n * // { age: 4, name: 'Foo1' }\n * // { age: 7, name: 'Bar' }\n * // { age: 5, name: 'Foo2' }\n * ```\n *\n * @see {@link distinct}\n * @see {@link distinctUntilChanged}\n *\n * @param {string} key String key for object property lookup on each item.\n * @param {function} [compare] Optional comparison function called to test if an item is distinct from the previous item in the source.\n * @return A function that returns an Observable that emits items from the\n * source Observable with distinct values based on the key specified.\n */\nexport function distinctUntilKeyChanged<T, K extends keyof T>(key: K, compare?: (x: T[K], y: T[K]) => boolean): MonoTypeOperatorFunction<T> {\n  return distinctUntilChanged((x: T, y: T) => compare ? compare(x[key], y[key]) : x[key] === y[key]);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/elementAt.ts",
    "content": "import { ArgumentOutOfRangeError } from '../util/ArgumentOutOfRangeError';\nimport { Observable } from '../Observable';\nimport { OperatorFunction } from '../types';\nimport { filter } from './filter';\nimport { throwIfEmpty } from './throwIfEmpty';\nimport { defaultIfEmpty } from './defaultIfEmpty';\nimport { take } from './take';\n\n/**\n * Emits the single value at the specified `index` in a sequence of emissions\n * from the source Observable.\n *\n * <span class=\"informal\">Emits only the i-th value, then completes.</span>\n *\n * ![](elementAt.png)\n *\n * `elementAt` returns an Observable that emits the item at the specified\n * `index` in the source Observable, or a default value if that `index` is out\n * of range and the `default` argument is provided. If the `default` argument is\n * not given and the `index` is out of range, the output Observable will emit an\n * `ArgumentOutOfRangeError` error.\n *\n * ## Example\n *\n * Emit only the third click event\n *\n * ```ts\n * import { fromEvent, elementAt } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(elementAt(2));\n * result.subscribe(x => console.log(x));\n *\n * // Results in:\n * // click 1 = nothing\n * // click 2 = nothing\n * // click 3 = MouseEvent object logged to console\n * ```\n *\n * @see {@link first}\n * @see {@link last}\n * @see {@link skip}\n * @see {@link single}\n * @see {@link take}\n *\n * @throws {ArgumentOutOfRangeError} When using `elementAt(i)`, it delivers an\n * ArgumentOutOfRangeError to the Observer's `error` callback if `i < 0` or the\n * Observable has completed before emitting the i-th `next` notification.\n *\n * @param {number} index Is the number `i` for the i-th source emission that has\n * happened since the subscription, starting from the number `0`.\n * @param {T} [defaultValue] The default value returned for missing indices.\n * @return A function that returns an Observable that emits a single item, if\n * it is found. Otherwise, it will emit the default value if given. If not, it\n * emits an error.\n */\nexport function elementAt<T, D = T>(index: number, defaultValue?: D): OperatorFunction<T, T | D> {\n  if (index < 0) {\n    throw new ArgumentOutOfRangeError();\n  }\n  const hasDefaultValue = arguments.length >= 2;\n  return (source: Observable<T>) =>\n    source.pipe(\n      filter((v, i) => i === index),\n      take(1),\n      hasDefaultValue ? defaultIfEmpty(defaultValue!) : throwIfEmpty(() => new ArgumentOutOfRangeError())\n    );\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/endWith.ts",
    "content": "/** prettier */\nimport { Observable } from '../Observable';\nimport { concat } from '../observable/concat';\nimport { of } from '../observable/of';\nimport { MonoTypeOperatorFunction, SchedulerLike, OperatorFunction, ValueFromArray } from '../types';\n\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled` and `concatAll`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function endWith<T>(scheduler: SchedulerLike): MonoTypeOperatorFunction<T>;\n/** @deprecated The `scheduler` parameter will be removed in v8. Use `scheduled` and `concatAll`. Details: https://rxjs.dev/deprecations/scheduler-argument */\nexport function endWith<T, A extends unknown[] = T[]>(\n  ...valuesAndScheduler: [...A, SchedulerLike]\n): OperatorFunction<T, T | ValueFromArray<A>>;\n\nexport function endWith<T, A extends unknown[] = T[]>(...values: A): OperatorFunction<T, T | ValueFromArray<A>>;\n\n/**\n * Returns an observable that will emit all values from the source, then synchronously emit\n * the provided value(s) immediately after the source completes.\n *\n * NOTE: Passing a last argument of a Scheduler is _deprecated_, and may result in incorrect\n * types in TypeScript.\n *\n * This is useful for knowing when an observable ends. Particularly when paired with an\n * operator like {@link takeUntil}\n *\n * ![](endWith.png)\n *\n * ## Example\n *\n * Emit values to know when an interval starts and stops. The interval will\n * stop when a user clicks anywhere on the document.\n *\n * ```ts\n * import { interval, map, fromEvent, startWith, takeUntil, endWith } from 'valdi_rxjs';\n *\n * const ticker$ = interval(5000).pipe(\n *   map(() => 'tick')\n * );\n *\n * const documentClicks$ = fromEvent(document, 'click');\n *\n * ticker$.pipe(\n *   startWith('interval started'),\n *   takeUntil(documentClicks$),\n *   endWith('interval ended by click')\n * )\n * .subscribe(x => console.log(x));\n *\n * // Result (assuming a user clicks after 15 seconds)\n * // 'interval started'\n * // 'tick'\n * // 'tick'\n * // 'tick'\n * // 'interval ended by click'\n * ```\n *\n * @see {@link startWith}\n * @see {@link concat}\n * @see {@link takeUntil}\n *\n * @param values Items you want the modified Observable to emit last.\n * @return A function that returns an Observable that emits all values from the\n * source, then synchronously emits the provided value(s) immediately after the\n * source completes.\n */\nexport function endWith<T>(...values: Array<T | SchedulerLike>): MonoTypeOperatorFunction<T> {\n  return (source: Observable<T>) => concat(source, of(...values)) as Observable<T>;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/every.ts",
    "content": "import { Observable } from '../Observable';\nimport { Falsy, OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\nexport function every<T>(predicate: BooleanConstructor): OperatorFunction<T, Exclude<T, Falsy> extends never ? false : boolean>;\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function every<T>(\n  predicate: BooleanConstructor,\n  thisArg: any\n): OperatorFunction<T, Exclude<T, Falsy> extends never ? false : boolean>;\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function every<T, A>(\n  predicate: (this: A, value: T, index: number, source: Observable<T>) => boolean,\n  thisArg: A\n): OperatorFunction<T, boolean>;\nexport function every<T>(predicate: (value: T, index: number, source: Observable<T>) => boolean): OperatorFunction<T, boolean>;\n\n/**\n * Returns an Observable that emits whether or not every item of the source satisfies the condition specified.\n *\n * <span class=\"informal\">If all values pass predicate before the source completes, emits true before completion,\n * otherwise emit false, then complete.</span>\n *\n * ![](every.png)\n *\n * ## Example\n *\n * A simple example emitting true if all elements are less than 5, false otherwise\n *\n * ```ts\n * import { of, every } from 'valdi_rxjs';\n *\n * of(1, 2, 3, 4, 5, 6)\n *   .pipe(every(x => x < 5))\n *   .subscribe(x => console.log(x)); // -> false\n * ```\n *\n * @param {function} predicate A function for determining if an item meets a specified condition.\n * @param {any} [thisArg] Optional object to use for `this` in the callback.\n * @return A function that returns an Observable of booleans that determines if\n * all items of the source Observable meet the condition specified.\n */\nexport function every<T>(\n  predicate: (value: T, index: number, source: Observable<T>) => boolean,\n  thisArg?: any\n): OperatorFunction<T, boolean> {\n  return operate((source, subscriber) => {\n    let index = 0;\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => {\n          if (!predicate.call(thisArg, value, index++, source)) {\n            subscriber.next(false);\n            subscriber.complete();\n          }\n        },\n        () => {\n          subscriber.next(true);\n          subscriber.complete();\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/exhaust.ts",
    "content": "import { exhaustAll } from './exhaustAll';\n\n/**\n * @deprecated Renamed to {@link exhaustAll}. Will be removed in v8.\n */\nexport const exhaust = exhaustAll;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/exhaustAll.ts",
    "content": "import { Subscription } from '../Subscription';\nimport { OperatorFunction, ObservableInput, ObservedValueOf } from '../types';\nimport { operate } from '../util/lift';\nimport { innerFrom } from '../observable/innerFrom';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Converts a higher-order Observable into a first-order Observable by dropping\n * inner Observables while the previous inner Observable has not yet completed.\n *\n * <span class=\"informal\">Flattens an Observable-of-Observables by dropping the\n * next inner Observables while the current inner is still executing.</span>\n *\n * ![](exhaust.png)\n *\n * `exhaustAll` subscribes to an Observable that emits Observables, also known as a\n * higher-order Observable. Each time it observes one of these emitted inner\n * Observables, the output Observable begins emitting the items emitted by that\n * inner Observable. So far, it behaves like {@link mergeAll}. However,\n * `exhaustAll` ignores every new inner Observable if the previous Observable has\n * not yet completed. Once that one completes, it will accept and flatten the\n * next inner Observable and repeat this process.\n *\n * ## Example\n *\n * Run a finite timer for each click, only if there is no currently active timer\n *\n * ```ts\n * import { fromEvent, map, interval, take, exhaustAll } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const higherOrder = clicks.pipe(\n *   map(() => interval(1000).pipe(take(5)))\n * );\n * const result = higherOrder.pipe(exhaustAll());\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link combineLatestAll}\n * @see {@link concatAll}\n * @see {@link switchAll}\n * @see {@link switchMap}\n * @see {@link mergeAll}\n * @see {@link exhaustMap}\n * @see {@link zipAll}\n *\n * @return A function that returns an Observable that takes a source of\n * Observables and propagates the first Observable exclusively until it\n * completes before subscribing to the next.\n */\nexport function exhaustAll<O extends ObservableInput<any>>(): OperatorFunction<O, ObservedValueOf<O>> {\n  return operate((source, subscriber) => {\n    let isComplete = false;\n    let innerSub: Subscription | null = null;\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (inner) => {\n          if (!innerSub) {\n            innerSub = innerFrom(inner).subscribe(\n              createOperatorSubscriber(subscriber, undefined, () => {\n                innerSub = null;\n                isComplete && subscriber.complete();\n              })\n            );\n          }\n        },\n        () => {\n          isComplete = true;\n          !innerSub && subscriber.complete();\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/exhaustMap.ts",
    "content": "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';\nimport { map } from './map';\nimport { innerFrom } from '../observable/innerFrom';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/* tslint:disable:max-line-length */\nexport function exhaustMap<T, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O\n): OperatorFunction<T, ObservedValueOf<O>>;\n/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */\nexport function exhaustMap<T, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  resultSelector: undefined\n): OperatorFunction<T, ObservedValueOf<O>>;\n/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */\nexport function exhaustMap<T, I, R>(\n  project: (value: T, index: number) => ObservableInput<I>,\n  resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R\n): OperatorFunction<T, R>;\n/* tslint:enable:max-line-length */\n\n/**\n * Projects each source value to an Observable which is merged in the output\n * Observable only if the previous projected Observable has completed.\n *\n * <span class=\"informal\">Maps each value to an Observable, then flattens all of\n * these inner Observables using {@link exhaust}.</span>\n *\n * ![](exhaustMap.png)\n *\n * Returns an Observable that emits items based on applying a function that you\n * supply to each item emitted by the source Observable, where that function\n * returns an (so-called \"inner\") Observable. When it projects a source value to\n * an Observable, the output Observable begins emitting the items emitted by\n * that projected Observable. However, `exhaustMap` ignores every new projected\n * Observable if the previous projected Observable has not yet completed. Once\n * that one completes, it will accept and flatten the next projected Observable\n * and repeat this process.\n *\n * ## Example\n *\n * Run a finite timer for each click, only if there is no currently active timer\n *\n * ```ts\n * import { fromEvent, exhaustMap, interval, take } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(\n *   exhaustMap(() => interval(1000).pipe(take(5)))\n * );\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link concatMap}\n * @see {@link exhaust}\n * @see {@link mergeMap}\n * @see {@link switchMap}\n *\n * @param {function(value: T, ?index: number): ObservableInput} project A function\n * that, when applied to an item emitted by the source Observable, returns an\n * Observable.\n * @return A function that returns an Observable containing projected\n * Observables of each item of the source, ignoring projected Observables that\n * start before their preceding Observable has completed.\n */\nexport function exhaustMap<T, R, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  resultSelector?: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R\n): OperatorFunction<T, ObservedValueOf<O> | R> {\n  if (resultSelector) {\n    // DEPRECATED PATH\n    return (source: Observable<T>) =>\n      source.pipe(exhaustMap((a, i) => innerFrom(project(a, i)).pipe(map((b: any, ii: any) => resultSelector(a, b, i, ii)))));\n  }\n  return operate((source, subscriber) => {\n    let index = 0;\n    let innerSub: Subscriber<T> | null = null;\n    let isComplete = false;\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (outerValue) => {\n          if (!innerSub) {\n            innerSub = createOperatorSubscriber(subscriber, undefined, () => {\n              innerSub = null;\n              isComplete && subscriber.complete();\n            });\n            innerFrom(project(outerValue, index++)).subscribe(innerSub);\n          }\n        },\n        () => {\n          isComplete = true;\n          !innerSub && subscriber.complete();\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/expand.ts",
    "content": "import { OperatorFunction, ObservableInput, ObservedValueOf, SchedulerLike } from '../types';\nimport { operate } from '../util/lift';\nimport { mergeInternals } from './mergeInternals';\n\n/* tslint:disable:max-line-length */\nexport function expand<T, O extends ObservableInput<unknown>>(\n  project: (value: T, index: number) => O,\n  concurrent?: number,\n  scheduler?: SchedulerLike\n): OperatorFunction<T, ObservedValueOf<O>>;\n/**\n * @deprecated The `scheduler` parameter will be removed in v8. If you need to schedule the inner subscription,\n * use `subscribeOn` within the projection function: `expand((value) => fn(value).pipe(subscribeOn(scheduler)))`.\n * Details: Details: https://rxjs.dev/deprecations/scheduler-argument\n */\nexport function expand<T, O extends ObservableInput<unknown>>(\n  project: (value: T, index: number) => O,\n  concurrent: number | undefined,\n  scheduler: SchedulerLike\n): OperatorFunction<T, ObservedValueOf<O>>;\n/* tslint:enable:max-line-length */\n\n/**\n * Recursively projects each source value to an Observable which is merged in\n * the output Observable.\n *\n * <span class=\"informal\">It's similar to {@link mergeMap}, but applies the\n * projection function to every source value as well as every output value.\n * It's recursive.</span>\n *\n * ![](expand.png)\n *\n * Returns an Observable that emits items based on applying a function that you\n * supply to each item emitted by the source Observable, where that function\n * returns an Observable, and then merging those resulting Observables and\n * emitting the results of this merger. *Expand* will re-emit on the output\n * Observable every source value. Then, each output value is given to the\n * `project` function which returns an inner Observable to be merged on the\n * output Observable. Those output values resulting from the projection are also\n * given to the `project` function to produce new output values. This is how\n * *expand* behaves recursively.\n *\n * ## Example\n *\n * Start emitting the powers of two on every click, at most 10 of them\n *\n * ```ts\n * import { fromEvent, map, expand, of, delay, take } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const powersOfTwo = clicks.pipe(\n *   map(() => 1),\n *   expand(x => of(2 * x).pipe(delay(1000))),\n *   take(10)\n * );\n * powersOfTwo.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link mergeMap}\n * @see {@link mergeScan}\n *\n * @param {function(value: T, index: number) => Observable} project A function\n * that, when applied to an item emitted by the source or the output Observable,\n * returns an Observable.\n * @param {number} [concurrent=Infinity] Maximum number of input\n * Observables being subscribed to concurrently.\n * @param {SchedulerLike} [scheduler=null] The {@link SchedulerLike} to use for subscribing to\n * each projected inner Observable.\n * @return A function that returns an Observable that emits the source values\n * and also result of applying the projection function to each value emitted on\n * the output Observable and merging the results of the Observables obtained\n * from this transformation.\n */\nexport function expand<T, O extends ObservableInput<unknown>>(\n  project: (value: T, index: number) => O,\n  concurrent = Infinity,\n  scheduler?: SchedulerLike\n): OperatorFunction<T, ObservedValueOf<O>> {\n  concurrent = (concurrent || 0) < 1 ? Infinity : concurrent;\n  return operate((source, subscriber) =>\n    mergeInternals(\n      // General merge params\n      source,\n      subscriber,\n      project,\n      concurrent,\n\n      // onBeforeNext\n      undefined,\n\n      // Expand-specific\n      true, // Use expand path\n      scheduler // Inner subscription scheduler\n    )\n  );\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/filter.ts",
    "content": "import { OperatorFunction, MonoTypeOperatorFunction, TruthyTypesOf } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function filter<T, S extends T, A>(predicate: (this: A, value: T, index: number) => value is S, thisArg: A): OperatorFunction<T, S>;\nexport function filter<T, S extends T>(predicate: (value: T, index: number) => value is S): OperatorFunction<T, S>;\nexport function filter<T>(predicate: BooleanConstructor): OperatorFunction<T, TruthyTypesOf<T>>;\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function filter<T, A>(predicate: (this: A, value: T, index: number) => boolean, thisArg: A): MonoTypeOperatorFunction<T>;\nexport function filter<T>(predicate: (value: T, index: number) => boolean): MonoTypeOperatorFunction<T>;\n\n/**\n * Filter items emitted by the source Observable by only emitting those that\n * satisfy a specified predicate.\n *\n * <span class=\"informal\">Like\n * [Array.prototype.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter),\n * it only emits a value from the source if it passes a criterion function.</span>\n *\n * ![](filter.png)\n *\n * Similar to the well-known `Array.prototype.filter` method, this operator\n * takes values from the source Observable, passes them through a `predicate`\n * function and only emits those values that yielded `true`.\n *\n * ## Example\n *\n * Emit only click events whose target was a DIV element\n *\n * ```ts\n * import { fromEvent, filter } from 'valdi_rxjs';\n *\n * const div = document.createElement('div');\n * div.style.cssText = 'width: 200px; height: 200px; background: #09c;';\n * document.body.appendChild(div);\n *\n * const clicks = fromEvent(document, 'click');\n * const clicksOnDivs = clicks.pipe(filter(ev => (<HTMLElement>ev.target).tagName === 'DIV'));\n * clicksOnDivs.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link distinct}\n * @see {@link distinctUntilChanged}\n * @see {@link distinctUntilKeyChanged}\n * @see {@link ignoreElements}\n * @see {@link partition}\n * @see {@link skip}\n *\n * @param predicate A function that\n * evaluates each value emitted by the source Observable. If it returns `true`,\n * the value is emitted, if `false` the value is not passed to the output\n * Observable. The `index` parameter is the number `i` for the i-th source\n * emission that has happened since the subscription, starting from the number\n * `0`.\n * @param thisArg An optional argument to determine the value of `this`\n * in the `predicate` function.\n * @return A function that returns an Observable that emits items from the\n * source Observable that satisfy the specified `predicate`.\n */\nexport function filter<T>(predicate: (value: T, index: number) => boolean, thisArg?: any): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    // An index passed to our predicate function on each call.\n    let index = 0;\n\n    // Subscribe to the source, all errors and completions are\n    // forwarded to the consumer.\n    source.subscribe(\n      // Call the predicate with the appropriate `this` context,\n      // if the predicate returns `true`, then send the value\n      // to the consumer.\n      createOperatorSubscriber(subscriber, (value) => predicate.call(thisArg, value, index++) && subscriber.next(value))\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/finalize.ts",
    "content": "import { MonoTypeOperatorFunction } from '../types';\nimport { operate } from '../util/lift';\n\n/**\n * Returns an Observable that mirrors the source Observable, but will call a specified function when\n * the source terminates on complete or error.\n * The specified function will also be called when the subscriber explicitly unsubscribes.\n *\n * ## Examples\n *\n * Execute callback function when the observable completes\n *\n * ```ts\n * import { interval, take, finalize } from 'valdi_rxjs';\n *\n * // emit value in sequence every 1 second\n * const source = interval(1000);\n * const example = source.pipe(\n *   take(5), //take only the first 5 values\n *   finalize(() => console.log('Sequence complete')) // Execute when the observable completes\n * );\n * const subscribe = example.subscribe(val => console.log(val));\n *\n * // results:\n * // 0\n * // 1\n * // 2\n * // 3\n * // 4\n * // 'Sequence complete'\n * ```\n *\n * Execute callback function when the subscriber explicitly unsubscribes\n *\n * ```ts\n * import { interval, finalize, tap, noop, timer } from 'valdi_rxjs';\n *\n * const source = interval(100).pipe(\n *   finalize(() => console.log('[finalize] Called')),\n *   tap({\n *     next: () => console.log('[next] Called'),\n *     error: () => console.log('[error] Not called'),\n *     complete: () => console.log('[tap complete] Not called')\n *   })\n * );\n *\n * const sub = source.subscribe({\n *   next: x => console.log(x),\n *   error: noop,\n *   complete: () => console.log('[complete] Not called')\n * });\n *\n * timer(150).subscribe(() => sub.unsubscribe());\n *\n * // results:\n * // '[next] Called'\n * // 0\n * // '[finalize] Called'\n * ```\n *\n * @param {function} callback Function to be called when source terminates.\n * @return A function that returns an Observable that mirrors the source, but\n * will call the specified function on termination.\n */\nexport function finalize<T>(callback: () => void): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    // TODO: This try/finally was only added for `useDeprecatedSynchronousErrorHandling`.\n    // REMOVE THIS WHEN THAT HOT GARBAGE IS REMOVED IN V8.\n    try {\n      source.subscribe(subscriber);\n    } finally {\n      subscriber.add(callback);\n    }\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/find.ts",
    "content": "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction, TruthyTypesOf } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\nexport function find<T>(predicate: BooleanConstructor): OperatorFunction<T, TruthyTypesOf<T>>;\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function find<T, S extends T, A>(\n  predicate: (this: A, value: T, index: number, source: Observable<T>) => value is S,\n  thisArg: A\n): OperatorFunction<T, S | undefined>;\nexport function find<T, S extends T>(\n  predicate: (value: T, index: number, source: Observable<T>) => value is S\n): OperatorFunction<T, S | undefined>;\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function find<T, A>(\n  predicate: (this: A, value: T, index: number, source: Observable<T>) => boolean,\n  thisArg: A\n): OperatorFunction<T, T | undefined>;\nexport function find<T>(predicate: (value: T, index: number, source: Observable<T>) => boolean): OperatorFunction<T, T | undefined>;\n/**\n * Emits only the first value emitted by the source Observable that meets some\n * condition.\n *\n * <span class=\"informal\">Finds the first value that passes some test and emits\n * that.</span>\n *\n * ![](find.png)\n *\n * `find` searches for the first item in the source Observable that matches the\n * specified condition embodied by the `predicate`, and returns the first\n * occurrence in the source. Unlike {@link first}, the `predicate` is required\n * in `find`, and does not emit an error if a valid value is not found\n * (emits `undefined` instead).\n *\n * ## Example\n *\n * Find and emit the first click that happens on a DIV element\n *\n * ```ts\n * import { fromEvent, find } from 'valdi_rxjs';\n *\n * const div = document.createElement('div');\n * div.style.cssText = 'width: 200px; height: 200px; background: #09c;';\n * document.body.appendChild(div);\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(find(ev => (<HTMLElement>ev.target).tagName === 'DIV'));\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link filter}\n * @see {@link first}\n * @see {@link findIndex}\n * @see {@link take}\n *\n * @param {function(value: T, index: number, source: Observable<T>): boolean} predicate\n * A function called with each item to test for condition matching.\n * @param {any} [thisArg] An optional argument to determine the value of `this`\n * in the `predicate` function.\n * @return A function that returns an Observable that emits the first item that\n * matches the condition.\n */\nexport function find<T>(\n  predicate: (value: T, index: number, source: Observable<T>) => boolean,\n  thisArg?: any\n): OperatorFunction<T, T | undefined> {\n  return operate(createFind(predicate, thisArg, 'value'));\n}\n\nexport function createFind<T>(\n  predicate: (value: T, index: number, source: Observable<T>) => boolean,\n  thisArg: any,\n  emit: 'value' | 'index'\n) {\n  const findIndex = emit === 'index';\n  return (source: Observable<T>, subscriber: Subscriber<any>) => {\n    let index = 0;\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => {\n          const i = index++;\n          if (predicate.call(thisArg, value, i, source)) {\n            subscriber.next(findIndex ? i : value);\n            subscriber.complete();\n          }\n        },\n        () => {\n          subscriber.next(findIndex ? -1 : undefined);\n          subscriber.complete();\n        }\n      )\n    );\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/findIndex.ts",
    "content": "import { Observable } from '../Observable';\nimport { Falsy, OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createFind } from './find';\n\nexport function findIndex<T>(predicate: BooleanConstructor): OperatorFunction<T, T extends Falsy ? -1 : number>;\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function findIndex<T>(predicate: BooleanConstructor, thisArg: any): OperatorFunction<T, T extends Falsy ? -1 : number>;\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function findIndex<T, A>(\n  predicate: (this: A, value: T, index: number, source: Observable<T>) => boolean,\n  thisArg: A\n): OperatorFunction<T, number>;\nexport function findIndex<T>(predicate: (value: T, index: number, source: Observable<T>) => boolean): OperatorFunction<T, number>;\n\n/**\n * Emits only the index of the first value emitted by the source Observable that\n * meets some condition.\n *\n * <span class=\"informal\">It's like {@link find}, but emits the index of the\n * found value, not the value itself.</span>\n *\n * ![](findIndex.png)\n *\n * `findIndex` searches for the first item in the source Observable that matches\n * the specified condition embodied by the `predicate`, and returns the\n * (zero-based) index of the first occurrence in the source. Unlike\n * {@link first}, the `predicate` is required in `findIndex`, and does not emit\n * an error if a valid value is not found.\n *\n * ## Example\n *\n * Emit the index of first click that happens on a DIV element\n *\n * ```ts\n * import { fromEvent, findIndex } from 'valdi_rxjs';\n *\n * const div = document.createElement('div');\n * div.style.cssText = 'width: 200px; height: 200px; background: #09c;';\n * document.body.appendChild(div);\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(findIndex(ev => (<HTMLElement>ev.target).tagName === 'DIV'));\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link filter}\n * @see {@link find}\n * @see {@link first}\n * @see {@link take}\n *\n * @param {function(value: T, index: number, source: Observable<T>): boolean} predicate\n * A function called with each item to test for condition matching.\n * @param {any} [thisArg] An optional argument to determine the value of `this`\n * in the `predicate` function.\n * @return A function that returns an Observable that emits the index of the\n * first item that matches the condition.\n */\nexport function findIndex<T>(\n  predicate: (value: T, index: number, source: Observable<T>) => boolean,\n  thisArg?: any\n): OperatorFunction<T, number> {\n  return operate(createFind(predicate, thisArg, 'index'));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/first.ts",
    "content": "import { Observable } from '../Observable';\nimport { EmptyError } from '../util/EmptyError';\nimport { OperatorFunction, TruthyTypesOf } from '../types';\nimport { filter } from './filter';\nimport { take } from './take';\nimport { defaultIfEmpty } from './defaultIfEmpty';\nimport { throwIfEmpty } from './throwIfEmpty';\nimport { identity } from '../util/identity';\n\nexport function first<T, D = T>(predicate?: null, defaultValue?: D): OperatorFunction<T, T | D>;\nexport function first<T>(predicate: BooleanConstructor): OperatorFunction<T, TruthyTypesOf<T>>;\nexport function first<T, D>(predicate: BooleanConstructor, defaultValue: D): OperatorFunction<T, TruthyTypesOf<T> | D>;\nexport function first<T, S extends T>(\n  predicate: (value: T, index: number, source: Observable<T>) => value is S,\n  defaultValue?: S\n): OperatorFunction<T, S>;\nexport function first<T, S extends T, D>(\n  predicate: (value: T, index: number, source: Observable<T>) => value is S,\n  defaultValue: D\n): OperatorFunction<T, S | D>;\nexport function first<T, D = T>(\n  predicate: (value: T, index: number, source: Observable<T>) => boolean,\n  defaultValue?: D\n): OperatorFunction<T, T | D>;\n\n/**\n * Emits only the first value (or the first value that meets some condition)\n * emitted by the source Observable.\n *\n * <span class=\"informal\">Emits only the first value. Or emits only the first\n * value that passes some test.</span>\n *\n * ![](first.png)\n *\n * If called with no arguments, `first` emits the first value of the source\n * Observable, then completes. If called with a `predicate` function, `first`\n * emits the first value of the source that matches the specified condition. Throws an error if\n * `defaultValue` was not provided and a matching element is not found.\n *\n * ## Examples\n *\n * Emit only the first click that happens on the DOM\n *\n * ```ts\n * import { fromEvent, first } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(first());\n * result.subscribe(x => console.log(x));\n * ```\n *\n * Emits the first click that happens on a DIV\n *\n * ```ts\n * import { fromEvent, first } from 'valdi_rxjs';\n *\n * const div = document.createElement('div');\n * div.style.cssText = 'width: 200px; height: 200px; background: #09c;';\n * document.body.appendChild(div);\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(first(ev => (<HTMLElement>ev.target).tagName === 'DIV'));\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link filter}\n * @see {@link find}\n * @see {@link take}\n *\n * @throws {EmptyError} Delivers an EmptyError to the Observer's `error`\n * callback if the Observable completes before any `next` notification was sent.\n * This is how `first()` is different from {@link take}(1) which completes instead.\n *\n * @param {function(value: T, index: number, source: Observable<T>): boolean} [predicate]\n * An optional function called with each item to test for condition matching.\n * @param {D} [defaultValue] The default value emitted in case no valid value\n * was found on the source.\n * @return A function that returns an Observable that emits the first item that\n * matches the condition.\n */\nexport function first<T, D>(\n  predicate?: ((value: T, index: number, source: Observable<T>) => boolean) | null,\n  defaultValue?: D\n): OperatorFunction<T, T | D> {\n  const hasDefaultValue = arguments.length >= 2;\n  return (source: Observable<T>) =>\n    source.pipe(\n      predicate ? filter((v, i) => predicate(v, i, source)) : identity,\n      take(1),\n      hasDefaultValue ? defaultIfEmpty(defaultValue!) : throwIfEmpty(() => new EmptyError())\n    );\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/flatMap.ts",
    "content": "import { mergeMap } from './mergeMap';\n\n/**\n * @deprecated Renamed to {@link mergeMap}. Will be removed in v8.\n */\nexport const flatMap = mergeMap;\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/groupBy.ts",
    "content": "import { Observable } from '../Observable';\nimport { innerFrom } from '../observable/innerFrom';\nimport { Subject } from '../Subject';\nimport { ObservableInput, Observer, OperatorFunction, SubjectLike } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber, OperatorSubscriber } from './OperatorSubscriber';\n\nexport interface BasicGroupByOptions<K, T> {\n  element?: undefined;\n  duration?: (grouped: GroupedObservable<K, T>) => ObservableInput<any>;\n  connector?: () => SubjectLike<T>;\n}\n\nexport interface GroupByOptionsWithElement<K, E, T> {\n  element: (value: T) => E;\n  duration?: (grouped: GroupedObservable<K, E>) => ObservableInput<any>;\n  connector?: () => SubjectLike<E>;\n}\n\nexport function groupBy<T, K>(key: (value: T) => K, options: BasicGroupByOptions<K, T>): OperatorFunction<T, GroupedObservable<K, T>>;\n\nexport function groupBy<T, K, E>(\n  key: (value: T) => K,\n  options: GroupByOptionsWithElement<K, E, T>\n): OperatorFunction<T, GroupedObservable<K, E>>;\n\nexport function groupBy<T, K extends T>(\n  key: (value: T) => value is K\n): OperatorFunction<T, GroupedObservable<true, K> | GroupedObservable<false, Exclude<T, K>>>;\n\nexport function groupBy<T, K>(key: (value: T) => K): OperatorFunction<T, GroupedObservable<K, T>>;\n\n/**\n * @deprecated use the options parameter instead.\n */\nexport function groupBy<T, K>(\n  key: (value: T) => K,\n  element: void,\n  duration: (grouped: GroupedObservable<K, T>) => Observable<any>\n): OperatorFunction<T, GroupedObservable<K, T>>;\n\n/**\n * @deprecated use the options parameter instead.\n */\nexport function groupBy<T, K, R>(\n  key: (value: T) => K,\n  element?: (value: T) => R,\n  duration?: (grouped: GroupedObservable<K, R>) => Observable<any>\n): OperatorFunction<T, GroupedObservable<K, R>>;\n\n/**\n * Groups the items emitted by an Observable according to a specified criterion,\n * and emits these grouped items as `GroupedObservables`, one\n * {@link GroupedObservable} per group.\n *\n * ![](groupBy.png)\n *\n * When the Observable emits an item, a key is computed for this item with the key function.\n *\n * If a {@link GroupedObservable} for this key exists, this {@link GroupedObservable} emits. Otherwise, a new\n * {@link GroupedObservable} for this key is created and emits.\n *\n * A {@link GroupedObservable} represents values belonging to the same group represented by a common key. The common\n * key is available as the `key` field of a {@link GroupedObservable} instance.\n *\n * The elements emitted by {@link GroupedObservable}s are by default the items emitted by the Observable, or elements\n * returned by the element function.\n *\n * ## Examples\n *\n * Group objects by `id` and return as array\n *\n * ```ts\n * import { of, groupBy, mergeMap, reduce } from 'valdi_rxjs';\n *\n * of(\n *   { id: 1, name: 'JavaScript' },\n *   { id: 2, name: 'Parcel' },\n *   { id: 2, name: 'webpack' },\n *   { id: 1, name: 'TypeScript' },\n *   { id: 3, name: 'TSLint' }\n * ).pipe(\n *   groupBy(p => p.id),\n *   mergeMap(group$ => group$.pipe(reduce((acc, cur) => [...acc, cur], [])))\n * )\n * .subscribe(p => console.log(p));\n *\n * // displays:\n * // [{ id: 1, name: 'JavaScript' }, { id: 1, name: 'TypeScript'}]\n * // [{ id: 2, name: 'Parcel' }, { id: 2, name: 'webpack'}]\n * // [{ id: 3, name: 'TSLint' }]\n * ```\n *\n * Pivot data on the `id` field\n *\n * ```ts\n * import { of, groupBy, mergeMap, reduce, map } from 'valdi_rxjs';\n *\n * of(\n *   { id: 1, name: 'JavaScript' },\n *   { id: 2, name: 'Parcel' },\n *   { id: 2, name: 'webpack' },\n *   { id: 1, name: 'TypeScript' },\n *   { id: 3, name: 'TSLint' }\n * ).pipe(\n *   groupBy(p => p.id, { element: p => p.name }),\n *   mergeMap(group$ => group$.pipe(reduce((acc, cur) => [...acc, cur], [`${ group$.key }`]))),\n *   map(arr => ({ id: parseInt(arr[0], 10), values: arr.slice(1) }))\n * )\n * .subscribe(p => console.log(p));\n *\n * // displays:\n * // { id: 1, values: [ 'JavaScript', 'TypeScript' ] }\n * // { id: 2, values: [ 'Parcel', 'webpack' ] }\n * // { id: 3, values: [ 'TSLint' ] }\n * ```\n *\n * @param key A function that extracts the key\n * for each item.\n * @param element A function that extracts the\n * return element for each item.\n * @param duration\n * A function that returns an Observable to determine how long each group should\n * exist.\n * @param connector Factory function to create an\n * intermediate Subject through which grouped elements are emitted.\n * @return A function that returns an Observable that emits GroupedObservables,\n * each of which corresponds to a unique key value and each of which emits\n * those items from the source Observable that share that key value.\n *\n * @deprecated Use the options parameter instead.\n */\nexport function groupBy<T, K, R>(\n  key: (value: T) => K,\n  element?: (value: T) => R,\n  duration?: (grouped: GroupedObservable<K, R>) => Observable<any>,\n  connector?: () => Subject<R>\n): OperatorFunction<T, GroupedObservable<K, R>>;\n\n// Impl\nexport function groupBy<T, K, R>(\n  keySelector: (value: T) => K,\n  elementOrOptions?: ((value: any) => any) | void | BasicGroupByOptions<K, T> | GroupByOptionsWithElement<K, R, T>,\n  duration?: (grouped: GroupedObservable<any, any>) => ObservableInput<any>,\n  connector?: () => SubjectLike<any>\n): OperatorFunction<T, GroupedObservable<K, R>> {\n  return operate((source, subscriber) => {\n    let element: ((value: any) => any) | void;\n    if (!elementOrOptions || typeof elementOrOptions === 'function') {\n      element = elementOrOptions;\n    } else {\n      ({ duration, element, connector } = elementOrOptions);\n    }\n\n    // A lookup for the groups that we have so far.\n    const groups = new Map<K, SubjectLike<any>>();\n\n    // Used for notifying all groups and the subscriber in the same way.\n    const notify = (cb: (group: Observer<any>) => void) => {\n      groups.forEach(cb);\n      cb(subscriber);\n    };\n\n    // Used to handle errors from the source, AND errors that occur during the\n    // next call from the source.\n    const handleError = (err: any) => notify((consumer) => consumer.error(err));\n\n    // The number of actively subscribed groups\n    let activeGroups = 0;\n\n    // Whether or not teardown was attempted on this subscription.\n    let teardownAttempted = false;\n\n    // Capturing a reference to this, because we need a handle to it\n    // in `createGroupedObservable` below. This is what we use to\n    // subscribe to our source observable. This sometimes needs to be unsubscribed\n    // out-of-band with our `subscriber` which is the downstream subscriber, or destination,\n    // in cases where a user unsubscribes from the main resulting subscription, but\n    // still has groups from this subscription subscribed and would expect values from it\n    // Consider:  `source.pipe(groupBy(fn), take(2))`.\n    const groupBySourceSubscriber = new OperatorSubscriber(\n      subscriber,\n      (value: T) => {\n        // Because we have to notify all groups of any errors that occur in here,\n        // we have to add our own try/catch to ensure that those errors are propagated.\n        // OperatorSubscriber will only send the error to the main subscriber.\n        try {\n          const key = keySelector(value);\n\n          let group = groups.get(key);\n          if (!group) {\n            // Create our group subject\n            groups.set(key, (group = connector ? connector() : new Subject<any>()));\n\n            // Emit the grouped observable. Note that we can't do a simple `asObservable()` here,\n            // because the grouped observable has special semantics around reference counting\n            // to ensure we don't sever our connection to the source prematurely.\n            const grouped = createGroupedObservable(key, group);\n            subscriber.next(grouped);\n\n            if (duration) {\n              const durationSubscriber = createOperatorSubscriber(\n                // Providing the group here ensures that it is disposed of -- via `unsubscribe` --\n                // wnen the duration subscription is torn down. That is important, because then\n                // if someone holds a handle to the grouped observable and tries to subscribe to it\n                // after the connection to the source has been severed, they will get an\n                // `ObjectUnsubscribedError` and know they can't possibly get any notifications.\n                group as any,\n                () => {\n                  // Our duration notified! We can complete the group.\n                  // The group will be removed from the map in the finalization phase.\n                  group!.complete();\n                  durationSubscriber?.unsubscribe();\n                },\n                // Completions are also sent to the group, but just the group.\n                undefined,\n                // Errors on the duration subscriber are sent to the group\n                // but only the group. They are not sent to the main subscription.\n                undefined,\n                // Finalization: Remove this group from our map.\n                () => groups.delete(key)\n              );\n\n              // Start our duration notifier.\n              groupBySourceSubscriber.add(innerFrom(duration(grouped)).subscribe(durationSubscriber));\n            }\n          }\n\n          // Send the value to our group.\n          group.next(element ? element(value) : value);\n        } catch (err) {\n          handleError(err);\n        }\n      },\n      // Source completes.\n      () => notify((consumer) => consumer.complete()),\n      // Error from the source.\n      handleError,\n      // Free up memory.\n      // When the source subscription is _finally_ torn down, release the subjects and keys\n      // in our groups Map, they may be quite large and we don't want to keep them around if we\n      // don't have to.\n      () => groups.clear(),\n      () => {\n        teardownAttempted = true;\n        // We only kill our subscription to the source if we have\n        // no active groups. As stated above, consider this scenario:\n        // source$.pipe(groupBy(fn), take(2)).\n        return activeGroups === 0;\n      }\n    );\n\n    // Subscribe to the source\n    source.subscribe(groupBySourceSubscriber);\n\n    /**\n     * Creates the actual grouped observable returned.\n     * @param key The key of the group\n     * @param groupSubject The subject that fuels the group\n     */\n    function createGroupedObservable(key: K, groupSubject: SubjectLike<any>) {\n      const result: any = new Observable<T>((groupSubscriber) => {\n        activeGroups++;\n        const innerSub = groupSubject.subscribe(groupSubscriber);\n        return () => {\n          innerSub.unsubscribe();\n          // We can kill the subscription to our source if we now have no more\n          // active groups subscribed, and a finalization was already attempted on\n          // the source.\n          --activeGroups === 0 && teardownAttempted && groupBySourceSubscriber.unsubscribe();\n        };\n      });\n      result.key = key;\n      return result;\n    }\n  });\n}\n\n/**\n * An observable of values that is the emitted by the result of a {@link groupBy} operator,\n * contains a `key` property for the grouping.\n */\nexport interface GroupedObservable<K, T> extends Observable<T> {\n  /**\n   * The key value for the grouped notifications.\n   */\n  readonly key: K;\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/ignoreElements.ts",
    "content": "import { OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\n\n/**\n * Ignores all items emitted by the source Observable and only passes calls of `complete` or `error`.\n *\n * ![](ignoreElements.png)\n *\n * The `ignoreElements` operator suppresses all items emitted by the source Observable,\n * but allows its termination notification (either `error` or `complete`) to pass through unchanged.\n *\n * If you do not care about the items being emitted by an Observable, but you do want to be notified\n * when it completes or when it terminates with an error, you can apply the `ignoreElements` operator\n * to the Observable, which will ensure that it will never call its observers’ `next` handlers.\n *\n * ## Example\n *\n * Ignore all `next` emissions from the source\n *\n * ```ts\n * import { of, ignoreElements } from 'valdi_rxjs';\n *\n * of('you', 'talking', 'to', 'me')\n *   .pipe(ignoreElements())\n *   .subscribe({\n *     next: word => console.log(word),\n *     error: err => console.log('error:', err),\n *     complete: () => console.log('the end'),\n *   });\n *\n * // result:\n * // 'the end'\n * ```\n *\n * @return A function that returns an empty Observable that only calls\n * `complete` or `error`, based on which one is called by the source\n * Observable.\n */\nexport function ignoreElements(): OperatorFunction<unknown, never> {\n  return operate((source, subscriber) => {\n    source.subscribe(createOperatorSubscriber(subscriber, noop));\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/isEmpty.ts",
    "content": "import { OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Emits `false` if the input Observable emits any values, or emits `true` if the\n * input Observable completes without emitting any values.\n *\n * <span class=\"informal\">Tells whether any values are emitted by an Observable.</span>\n *\n * ![](isEmpty.png)\n *\n * `isEmpty` transforms an Observable that emits values into an Observable that\n * emits a single boolean value representing whether or not any values were\n * emitted by the source Observable. As soon as the source Observable emits a\n * value, `isEmpty` will emit a `false` and complete.  If the source Observable\n * completes having not emitted anything, `isEmpty` will emit a `true` and\n * complete.\n *\n * A similar effect could be achieved with {@link count}, but `isEmpty` can emit\n * a `false` value sooner.\n *\n * ## Examples\n *\n * Emit `false` for a non-empty Observable\n *\n * ```ts\n * import { Subject, isEmpty } from 'valdi_rxjs';\n *\n * const source = new Subject<string>();\n * const result = source.pipe(isEmpty());\n *\n * source.subscribe(x => console.log(x));\n * result.subscribe(x => console.log(x));\n *\n * source.next('a');\n * source.next('b');\n * source.next('c');\n * source.complete();\n *\n * // Outputs\n * // 'a'\n * // false\n * // 'b'\n * // 'c'\n * ```\n *\n * Emit `true` for an empty Observable\n *\n * ```ts\n * import { EMPTY, isEmpty } from 'valdi_rxjs';\n *\n * const result = EMPTY.pipe(isEmpty());\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // true\n * ```\n *\n * @see {@link count}\n * @see {@link EMPTY}\n *\n * @return A function that returns an Observable that emits boolean value\n * indicating whether the source Observable was empty or not.\n */\nexport function isEmpty<T>(): OperatorFunction<T, boolean> {\n  return operate((source, subscriber) => {\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        () => {\n          subscriber.next(false);\n          subscriber.complete();\n        },\n        () => {\n          subscriber.next(true);\n          subscriber.complete();\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/joinAllInternals.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservableInput, OperatorFunction } from '../types';\nimport { identity } from '../util/identity';\nimport { mapOneOrManyArgs } from '../util/mapOneOrManyArgs';\nimport { pipe } from '../util/pipe';\nimport { mergeMap } from './mergeMap';\nimport { toArray } from './toArray';\n\n/**\n * Collects all of the inner sources from source observable. Then, once the\n * source completes, joins the values using the given static.\n *\n * This is used for {@link combineLatestAll} and {@link zipAll} which both have the\n * same behavior of collecting all inner observables, then operating on them.\n *\n * @param joinFn The type of static join to apply to the sources collected\n * @param project The projection function to apply to the values, if any\n */\nexport function joinAllInternals<T, R>(joinFn: (sources: ObservableInput<T>[]) => Observable<T>, project?: (...args: any[]) => R) {\n  return pipe(\n    // Collect all inner sources into an array, and emit them when the\n    // source completes.\n    toArray() as OperatorFunction<ObservableInput<T>, ObservableInput<T>[]>,\n    // Run the join function on the collected array of inner sources.\n    mergeMap((sources) => joinFn(sources)),\n    // If a projection function was supplied, apply it to each result.\n    project ? mapOneOrManyArgs(project) : (identity as any)\n  );\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/last.ts",
    "content": "import { Observable } from '../Observable';\nimport { EmptyError } from '../util/EmptyError';\nimport { OperatorFunction, TruthyTypesOf } from '../types';\nimport { filter } from './filter';\nimport { takeLast } from './takeLast';\nimport { throwIfEmpty } from './throwIfEmpty';\nimport { defaultIfEmpty } from './defaultIfEmpty';\nimport { identity } from '../util/identity';\n\nexport function last<T>(predicate: BooleanConstructor): OperatorFunction<T, TruthyTypesOf<T>>;\nexport function last<T, D>(predicate: BooleanConstructor, defaultValue: D): OperatorFunction<T, TruthyTypesOf<T> | D>;\nexport function last<T, D = T>(predicate?: null, defaultValue?: D): OperatorFunction<T, T | D>;\nexport function last<T, S extends T>(\n  predicate: (value: T, index: number, source: Observable<T>) => value is S,\n  defaultValue?: S\n): OperatorFunction<T, S>;\nexport function last<T, D = T>(\n  predicate: (value: T, index: number, source: Observable<T>) => boolean,\n  defaultValue?: D\n): OperatorFunction<T, T | D>;\n\n/**\n * Returns an Observable that emits only the last item emitted by the source Observable.\n * It optionally takes a predicate function as a parameter, in which case, rather than emitting\n * the last item from the source Observable, the resulting Observable will emit the last item\n * from the source Observable that satisfies the predicate.\n *\n * ![](last.png)\n *\n * It will throw an error if the source completes without notification or one that matches the predicate. It\n * returns the last value or if a predicate is provided last value that matches the predicate. It returns the\n * given default value if no notification is emitted or matches the predicate.\n *\n * ## Examples\n *\n * Last alphabet from the sequence\n *\n * ```ts\n * import { from, last } from 'valdi_rxjs';\n *\n * const source = from(['x', 'y', 'z']);\n * const result = source.pipe(last());\n *\n * result.subscribe(value => console.log(`Last alphabet: ${ value }`));\n *\n * // Outputs\n * // Last alphabet: z\n * ```\n *\n * Default value when the value in the predicate is not matched\n *\n * ```ts\n * import { from, last } from 'valdi_rxjs';\n *\n * const source = from(['x', 'y', 'z']);\n * const result = source.pipe(last(char => char === 'a', 'not found'));\n *\n * result.subscribe(value => console.log(`'a' is ${ value }.`));\n *\n * // Outputs\n * // 'a' is not found.\n * ```\n *\n * @see {@link skip}\n * @see {@link skipUntil}\n * @see {@link skipLast}\n * @see {@link skipWhile}\n *\n * @throws {EmptyError} Delivers an EmptyError to the Observer's `error`\n * callback if the Observable completes before any `next` notification was sent.\n * @param {function} [predicate] - The condition any source emitted item has to satisfy.\n * @param {any} [defaultValue] - An optional default value to provide if last\n * predicate isn't met or no values were emitted.\n * @return A function that returns an Observable that emits only the last item\n * satisfying the given condition from the source, or a NoSuchElementException\n * if no such items are emitted.\n * @throws - Throws if no items that match the predicate are emitted by the source Observable.\n */\nexport function last<T, D>(\n  predicate?: ((value: T, index: number, source: Observable<T>) => boolean) | null,\n  defaultValue?: D\n): OperatorFunction<T, T | D> {\n  const hasDefaultValue = arguments.length >= 2;\n  return (source: Observable<T>) =>\n    source.pipe(\n      predicate ? filter((v, i) => predicate(v, i, source)) : identity,\n      takeLast(1),\n      hasDefaultValue ? defaultIfEmpty(defaultValue!) : throwIfEmpty(() => new EmptyError())\n    );\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/map.ts",
    "content": "import { OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\nexport function map<T, R>(project: (value: T, index: number) => R): OperatorFunction<T, R>;\n/** @deprecated Use a closure instead of a `thisArg`. Signatures accepting a `thisArg` will be removed in v8. */\nexport function map<T, R, A>(project: (this: A, value: T, index: number) => R, thisArg: A): OperatorFunction<T, R>;\n\n/**\n * Applies a given `project` function to each value emitted by the source\n * Observable, and emits the resulting values as an Observable.\n *\n * <span class=\"informal\">Like [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map),\n * it passes each source value through a transformation function to get\n * corresponding output values.</span>\n *\n * ![](map.png)\n *\n * Similar to the well known `Array.prototype.map` function, this operator\n * applies a projection to each value and emits that projection in the output\n * Observable.\n *\n * ## Example\n *\n * Map every click to the `clientX` position of that click\n *\n * ```ts\n * import { fromEvent, map } from 'valdi_rxjs';\n *\n * const clicks = fromEvent<PointerEvent>(document, 'click');\n * const positions = clicks.pipe(map(ev => ev.clientX));\n *\n * positions.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link mapTo}\n * @see {@link pluck}\n *\n * @param {function(value: T, index: number): R} project The function to apply\n * to each `value` emitted by the source Observable. The `index` parameter is\n * the number `i` for the i-th emission that has happened since the\n * subscription, starting from the number `0`.\n * @param {any} [thisArg] An optional argument to define what `this` is in the\n * `project` function.\n * @return A function that returns an Observable that emits the values from the\n * source Observable transformed by the given `project` function.\n */\nexport function map<T, R>(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction<T, R> {\n  return operate((source, subscriber) => {\n    // The index of the value from the source. Used with projection.\n    let index = 0;\n    // Subscribe to the source, all errors and completions are sent along\n    // to the consumer.\n    source.subscribe(\n      createOperatorSubscriber(subscriber, (value: T) => {\n        // Call the projection function with the appropriate this context,\n        // and send the resulting value to the consumer.\n        subscriber.next(project.call(thisArg, value, index++));\n      })\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/materialize.ts",
    "content": "import { Notification } from '../Notification';\nimport { OperatorFunction, ObservableNotification } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Represents all of the notifications from the source Observable as `next`\n * emissions marked with their original types within {@link Notification}\n * objects.\n *\n * <span class=\"informal\">Wraps `next`, `error` and `complete` emissions in\n * {@link Notification} objects, emitted as `next` on the output Observable.\n * </span>\n *\n * ![](materialize.png)\n *\n * `materialize` returns an Observable that emits a `next` notification for each\n * `next`, `error`, or `complete` emission of the source Observable. When the\n * source Observable emits `complete`, the output Observable will emit `next` as\n * a Notification of type \"complete\", and then it will emit `complete` as well.\n * When the source Observable emits `error`, the output will emit `next` as a\n * Notification of type \"error\", and then `complete`.\n *\n * This operator is useful for producing metadata of the source Observable, to\n * be consumed as `next` emissions. Use it in conjunction with\n * {@link dematerialize}.\n *\n * ## Example\n *\n * Convert a faulty Observable to an Observable of Notifications\n *\n * ```ts\n * import { of, materialize, map } from 'valdi_rxjs';\n *\n * const letters = of('a', 'b', 13, 'd');\n * const upperCase = letters.pipe(map((x: any) => x.toUpperCase()));\n * const materialized = upperCase.pipe(materialize());\n *\n * materialized.subscribe(x => console.log(x));\n *\n * // Results in the following:\n * // - Notification { kind: 'N', value: 'A', error: undefined, hasValue: true }\n * // - Notification { kind: 'N', value: 'B', error: undefined, hasValue: true }\n * // - Notification { kind: 'E', value: undefined, error: TypeError { message: x.toUpperCase is not a function }, hasValue: false }\n * ```\n *\n * @see {@link Notification}\n * @see {@link dematerialize}\n *\n * @return A function that returns an Observable that emits\n * {@link Notification} objects that wrap the original emissions from the\n * source Observable with metadata.\n */\nexport function materialize<T>(): OperatorFunction<T, Notification<T> & ObservableNotification<T>> {\n  return operate((source, subscriber) => {\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => {\n          subscriber.next(Notification.createNext(value));\n        },\n        () => {\n          subscriber.next(Notification.createComplete());\n          subscriber.complete();\n        },\n        (err) => {\n          subscriber.next(Notification.createError(err));\n          subscriber.complete();\n        }\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/max.ts",
    "content": "import { reduce } from './reduce';\nimport { MonoTypeOperatorFunction } from '../types';\nimport { isFunction } from '../util/isFunction';\n\n/**\n * The Max operator operates on an Observable that emits numbers (or items that can be compared with a provided function),\n * and when source Observable completes it emits a single item: the item with the largest value.\n *\n * ![](max.png)\n *\n * ## Examples\n *\n * Get the maximal value of a series of numbers\n *\n * ```ts\n * import { of, max } from 'valdi_rxjs';\n *\n * of(5, 4, 7, 2, 8)\n *   .pipe(max())\n *   .subscribe(x => console.log(x));\n *\n * // Outputs\n * // 8\n * ```\n *\n * Use a comparer function to get the maximal item\n *\n * ```ts\n * import { of, max } from 'valdi_rxjs';\n *\n * of(\n *   { age: 7, name: 'Foo' },\n *   { age: 5, name: 'Bar' },\n *   { age: 9, name: 'Beer' }\n * ).pipe(\n *   max((a, b) => a.age < b.age ? -1 : 1)\n * )\n * .subscribe(x => console.log(x.name));\n *\n * // Outputs\n * // 'Beer'\n * ```\n *\n * @see {@link min}\n *\n * @param {Function} [comparer] - Optional comparer function that it will use instead of its default to compare the\n * value of two items.\n * @return A function that returns an Observable that emits item with the\n * largest value.\n */\nexport function max<T>(comparer?: (x: T, y: T) => number): MonoTypeOperatorFunction<T> {\n  return reduce(isFunction(comparer) ? (x, y) => (comparer(x, y) > 0 ? x : y) : (x, y) => (x > y ? x : y));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/merge.ts",
    "content": "import { ObservableInput, ObservableInputTuple, OperatorFunction, SchedulerLike } from '../types';\nimport { operate } from '../util/lift';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { mergeAll } from './mergeAll';\nimport { popNumber, popScheduler } from '../util/args';\nimport { from } from '../observable/from';\n\n/** @deprecated Replaced with {@link mergeWith}. Will be removed in v8. */\nexport function merge<T, A extends readonly unknown[]>(...sources: [...ObservableInputTuple<A>]): OperatorFunction<T, T | A[number]>;\n/** @deprecated Replaced with {@link mergeWith}. Will be removed in v8. */\nexport function merge<T, A extends readonly unknown[]>(\n  ...sourcesAndConcurrency: [...ObservableInputTuple<A>, number]\n): OperatorFunction<T, T | A[number]>;\n/** @deprecated Replaced with {@link mergeWith}. Will be removed in v8. */\nexport function merge<T, A extends readonly unknown[]>(\n  ...sourcesAndScheduler: [...ObservableInputTuple<A>, SchedulerLike]\n): OperatorFunction<T, T | A[number]>;\n/** @deprecated Replaced with {@link mergeWith}. Will be removed in v8. */\nexport function merge<T, A extends readonly unknown[]>(\n  ...sourcesAndConcurrencyAndScheduler: [...ObservableInputTuple<A>, number, SchedulerLike]\n): OperatorFunction<T, T | A[number]>;\n\nexport function merge<T>(...args: unknown[]): OperatorFunction<T, unknown> {\n  const scheduler = popScheduler(args);\n  const concurrent = popNumber(args, Infinity);\n  args = argsOrArgArray(args);\n\n  return operate((source, subscriber) => {\n    mergeAll(concurrent)(from([source, ...(args as ObservableInput<T>[])], scheduler)).subscribe(subscriber);\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/mergeAll.ts",
    "content": "import { mergeMap } from './mergeMap';\nimport { identity } from '../util/identity';\nimport { OperatorFunction, ObservableInput, ObservedValueOf } from '../types';\n\n/**\n * Converts a higher-order Observable into a first-order Observable which\n * concurrently delivers all values that are emitted on the inner Observables.\n *\n * <span class=\"informal\">Flattens an Observable-of-Observables.</span>\n *\n * ![](mergeAll.png)\n *\n * `mergeAll` subscribes to an Observable that emits Observables, also known as\n * a higher-order Observable. Each time it observes one of these emitted inner\n * Observables, it subscribes to that and delivers all the values from the\n * inner Observable on the output Observable. The output Observable only\n * completes once all inner Observables have completed. Any error delivered by\n * a inner Observable will be immediately emitted on the output Observable.\n *\n * ## Examples\n *\n * Spawn a new interval Observable for each click event, and blend their outputs as one Observable\n *\n * ```ts\n * import { fromEvent, map, interval, mergeAll } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const higherOrder = clicks.pipe(map(() => interval(1000)));\n * const firstOrder = higherOrder.pipe(mergeAll());\n *\n * firstOrder.subscribe(x => console.log(x));\n * ```\n *\n * Count from 0 to 9 every second for each click, but only allow 2 concurrent timers\n *\n * ```ts\n * import { fromEvent, map, interval, take, mergeAll } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const higherOrder = clicks.pipe(\n *   map(() => interval(1000).pipe(take(10)))\n * );\n * const firstOrder = higherOrder.pipe(mergeAll(2));\n *\n * firstOrder.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link combineLatestAll}\n * @see {@link concatAll}\n * @see {@link exhaustAll}\n * @see {@link merge}\n * @see {@link mergeMap}\n * @see {@link mergeMapTo}\n * @see {@link mergeScan}\n * @see {@link switchAll}\n * @see {@link switchMap}\n * @see {@link zipAll}\n *\n * @param {number} [concurrent=Infinity] Maximum number of inner\n * Observables being subscribed to concurrently.\n * @return A function that returns an Observable that emits values coming from\n * all the inner Observables emitted by the source Observable.\n */\nexport function mergeAll<O extends ObservableInput<any>>(concurrent: number = Infinity): OperatorFunction<O, ObservedValueOf<O>> {\n  return mergeMap(identity, concurrent);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/mergeInternals.ts",
    "content": "import { Observable } from '../Observable';\nimport { innerFrom } from '../observable/innerFrom';\nimport { Subscriber } from '../Subscriber';\nimport { ObservableInput, SchedulerLike } from '../types';\nimport { executeSchedule } from '../util/executeSchedule';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * A process embodying the general \"merge\" strategy. This is used in\n * `mergeMap` and `mergeScan` because the logic is otherwise nearly identical.\n * @param source The original source observable\n * @param subscriber The consumer subscriber\n * @param project The projection function to get our inner sources\n * @param concurrent The number of concurrent inner subscriptions\n * @param onBeforeNext Additional logic to apply before nexting to our consumer\n * @param expand If `true` this will perform an \"expand\" strategy, which differs only\n * in that it recurses, and the inner subscription must be schedule-able.\n * @param innerSubScheduler A scheduler to use to schedule inner subscriptions,\n * this is to support the expand strategy, mostly, and should be deprecated\n */\nexport function mergeInternals<T, R>(\n  source: Observable<T>,\n  subscriber: Subscriber<R>,\n  project: (value: T, index: number) => ObservableInput<R>,\n  concurrent: number,\n  onBeforeNext?: (innerValue: R) => void,\n  expand?: boolean,\n  innerSubScheduler?: SchedulerLike,\n  additionalFinalizer?: () => void\n) {\n  // Buffered values, in the event of going over our concurrency limit\n  const buffer: T[] = [];\n  // The number of active inner subscriptions.\n  let active = 0;\n  // An index to pass to our accumulator function\n  let index = 0;\n  // Whether or not the outer source has completed.\n  let isComplete = false;\n\n  /**\n   * Checks to see if we can complete our result or not.\n   */\n  const checkComplete = () => {\n    // If the outer has completed, and nothing is left in the buffer,\n    // and we don't have any active inner subscriptions, then we can\n    // Emit the state and complete.\n    if (isComplete && !buffer.length && !active) {\n      subscriber.complete();\n    }\n  };\n\n  // If we're under our concurrency limit, just start the inner subscription, otherwise buffer and wait.\n  const outerNext = (value: T) => (active < concurrent ? doInnerSub(value) : buffer.push(value));\n\n  const doInnerSub = (value: T) => {\n    // If we're expanding, we need to emit the outer values and the inner values\n    // as the inners will \"become outers\" in a way as they are recursively fed\n    // back to the projection mechanism.\n    expand && subscriber.next(value as any);\n\n    // Increment the number of active subscriptions so we can track it\n    // against our concurrency limit later.\n    active++;\n\n    // A flag used to show that the inner observable completed.\n    // This is checked during finalization to see if we should\n    // move to the next item in the buffer, if there is on.\n    let innerComplete = false;\n\n    // Start our inner subscription.\n    innerFrom(project(value, index++)).subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (innerValue) => {\n          // `mergeScan` has additional handling here. For example\n          // taking the inner value and updating state.\n          onBeforeNext?.(innerValue);\n\n          if (expand) {\n            // If we're expanding, then just recurse back to our outer\n            // handler. It will emit the value first thing.\n            outerNext(innerValue as any);\n          } else {\n            // Otherwise, emit the inner value.\n            subscriber.next(innerValue);\n          }\n        },\n        () => {\n          // Flag that we have completed, so we know to check the buffer\n          // during finalization.\n          innerComplete = true;\n        },\n        // Errors are passed to the destination.\n        undefined,\n        () => {\n          // During finalization, if the inner completed (it wasn't errored or\n          // cancelled), then we want to try the next item in the buffer if\n          // there is one.\n          if (innerComplete) {\n            // We have to wrap this in a try/catch because it happens during\n            // finalization, possibly asynchronously, and we want to pass\n            // any errors that happen (like in a projection function) to\n            // the outer Subscriber.\n            try {\n              // INNER SOURCE COMPLETE\n              // Decrement the active count to ensure that the next time\n              // we try to call `doInnerSub`, the number is accurate.\n              active--;\n              // If we have more values in the buffer, try to process those\n              // Note that this call will increment `active` ahead of the\n              // next conditional, if there were any more inner subscriptions\n              // to start.\n              while (buffer.length && active < concurrent) {\n                const bufferedValue = buffer.shift()!;\n                // Particularly for `expand`, we need to check to see if a scheduler was provided\n                // for when we want to start our inner subscription. Otherwise, we just start\n                // are next inner subscription.\n                if (innerSubScheduler) {\n                  executeSchedule(subscriber, innerSubScheduler, () => doInnerSub(bufferedValue));\n                } else {\n                  doInnerSub(bufferedValue);\n                }\n              }\n              // Check to see if we can complete, and complete if so.\n              checkComplete();\n            } catch (err) {\n              subscriber.error(err);\n            }\n          }\n        }\n      )\n    );\n  };\n\n  // Subscribe to our source observable.\n  source.subscribe(\n    createOperatorSubscriber(subscriber, outerNext, () => {\n      // Outer completed, make a note of it, and check to see if we can complete everything.\n      isComplete = true;\n      checkComplete();\n    })\n  );\n\n  // Additional finalization (for when the destination is torn down).\n  // Other finalization is added implicitly via subscription above.\n  return () => {\n    additionalFinalizer?.();\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/mergeMap.ts",
    "content": "import { ObservableInput, OperatorFunction, ObservedValueOf } from '../types';\nimport { map } from './map';\nimport { innerFrom } from '../observable/innerFrom';\nimport { operate } from '../util/lift';\nimport { mergeInternals } from './mergeInternals';\nimport { isFunction } from '../util/isFunction';\n\n/* tslint:disable:max-line-length */\nexport function mergeMap<T, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  concurrent?: number\n): OperatorFunction<T, ObservedValueOf<O>>;\n/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */\nexport function mergeMap<T, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  resultSelector: undefined,\n  concurrent?: number\n): OperatorFunction<T, ObservedValueOf<O>>;\n/** @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead. Details: https://rxjs.dev/deprecations/resultSelector */\nexport function mergeMap<T, R, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R,\n  concurrent?: number\n): OperatorFunction<T, R>;\n/* tslint:enable:max-line-length */\n\n/**\n * Projects each source value to an Observable which is merged in the output\n * Observable.\n *\n * <span class=\"informal\">Maps each value to an Observable, then flattens all of\n * these inner Observables using {@link mergeAll}.</span>\n *\n * ![](mergeMap.png)\n *\n * Returns an Observable that emits items based on applying a function that you\n * supply to each item emitted by the source Observable, where that function\n * returns an Observable, and then merging those resulting Observables and\n * emitting the results of this merger.\n *\n * ## Example\n *\n * Map and flatten each letter to an Observable ticking every 1 second\n *\n * ```ts\n * import { of, mergeMap, interval, map } from 'valdi_rxjs';\n *\n * const letters = of('a', 'b', 'c');\n * const result = letters.pipe(\n *   mergeMap(x => interval(1000).pipe(map(i => x + i)))\n * );\n *\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following:\n * // a0\n * // b0\n * // c0\n * // a1\n * // b1\n * // c1\n * // continues to list a, b, c every second with respective ascending integers\n * ```\n *\n * @see {@link concatMap}\n * @see {@link exhaustMap}\n * @see {@link merge}\n * @see {@link mergeAll}\n * @see {@link mergeMapTo}\n * @see {@link mergeScan}\n * @see {@link switchMap}\n *\n * @param {function(value: T, ?index: number): ObservableInput} project A function\n * that, when applied to an item emitted by the source Observable, returns an\n * Observable.\n * @param {number} [concurrent=Infinity] Maximum number of input\n * Observables being subscribed to concurrently.\n * @return A function that returns an Observable that emits the result of\n * applying the projection function (and the optional deprecated\n * `resultSelector`) to each item emitted by the source Observable and merging\n * the results of the Observables obtained from this transformation.\n */\nexport function mergeMap<T, R, O extends ObservableInput<any>>(\n  project: (value: T, index: number) => O,\n  resultSelector?: ((outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R) | number,\n  concurrent: number = Infinity\n): OperatorFunction<T, ObservedValueOf<O> | R> {\n  if (isFunction(resultSelector)) {\n    // DEPRECATED PATH\n    return mergeMap((a, i) => map((b: any, ii: number) => resultSelector(a, b, i, ii))(innerFrom(project(a, i))), concurrent);\n  } else if (typeof resultSelector === 'number') {\n    concurrent = resultSelector;\n  }\n\n  return operate((source, subscriber) => mergeInternals(source, subscriber, project, concurrent));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/mergeMapTo.ts",
    "content": "import { OperatorFunction, ObservedValueOf, ObservableInput } from '../types';\nimport { mergeMap } from './mergeMap';\nimport { isFunction } from '../util/isFunction';\n\n/** @deprecated Will be removed in v9. Use {@link mergeMap} instead: `mergeMap(() => result)` */\nexport function mergeMapTo<O extends ObservableInput<unknown>>(\n  innerObservable: O,\n  concurrent?: number\n): OperatorFunction<unknown, ObservedValueOf<O>>;\n/**\n * @deprecated The `resultSelector` parameter will be removed in v8. Use an inner `map` instead.\n * Details: https://rxjs.dev/deprecations/resultSelector\n */\nexport function mergeMapTo<T, R, O extends ObservableInput<unknown>>(\n  innerObservable: O,\n  resultSelector: (outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R,\n  concurrent?: number\n): OperatorFunction<T, R>;\n/* tslint:enable:max-line-length */\n\n/**\n * Projects each source value to the same Observable which is merged multiple\n * times in the output Observable.\n *\n * <span class=\"informal\">It's like {@link mergeMap}, but maps each value always\n * to the same inner Observable.</span>\n *\n * ![](mergeMapTo.png)\n *\n * Maps each source value to the given Observable `innerObservable` regardless\n * of the source value, and then merges those resulting Observables into one\n * single Observable, which is the output Observable.\n *\n * ## Example\n *\n * For each click event, start an interval Observable ticking every 1 second\n *\n * ```ts\n * import { fromEvent, mergeMapTo, interval } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const result = clicks.pipe(mergeMapTo(interval(1000)));\n *\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link concatMapTo}\n * @see {@link merge}\n * @see {@link mergeAll}\n * @see {@link mergeMap}\n * @see {@link mergeScan}\n * @see {@link switchMapTo}\n *\n * @param {ObservableInput} innerObservable An Observable to replace each value from\n * the source Observable.\n * @param {number} [concurrent=Infinity] Maximum number of input\n * Observables being subscribed to concurrently.\n * @return A function that returns an Observable that emits items from the\n * given `innerObservable`.\n * @deprecated Will be removed in v9. Use {@link mergeMap} instead: `mergeMap(() => result)`\n */\nexport function mergeMapTo<T, R, O extends ObservableInput<unknown>>(\n  innerObservable: O,\n  resultSelector?: ((outerValue: T, innerValue: ObservedValueOf<O>, outerIndex: number, innerIndex: number) => R) | number,\n  concurrent: number = Infinity\n): OperatorFunction<T, ObservedValueOf<O> | R> {\n  if (isFunction(resultSelector)) {\n    return mergeMap(() => innerObservable, resultSelector, concurrent);\n  }\n  if (typeof resultSelector === 'number') {\n    concurrent = resultSelector;\n  }\n  return mergeMap(() => innerObservable, concurrent);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/mergeScan.ts",
    "content": "import { ObservableInput, OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { mergeInternals } from './mergeInternals';\n\n/**\n * Applies an accumulator function over the source Observable where the\n * accumulator function itself returns an Observable, then each intermediate\n * Observable returned is merged into the output Observable.\n *\n * <span class=\"informal\">It's like {@link scan}, but the Observables returned\n * by the accumulator are merged into the outer Observable.</span>\n *\n * The first parameter of the `mergeScan` is an `accumulator` function which is\n * being called every time the source Observable emits a value. `mergeScan` will\n * subscribe to the value returned by the `accumulator` function and will emit\n * values to the subscriber emitted by inner Observable.\n *\n * The `accumulator` function is being called with three parameters passed to it:\n * `acc`, `value` and `index`. The `acc` parameter is used as the state parameter\n * whose value is initially set to the `seed` parameter (the second parameter\n * passed to the `mergeScan` operator).\n *\n * `mergeScan` internally keeps the value of the `acc` parameter: as long as the\n * source Observable emits without inner Observable emitting, the `acc` will be\n * set to `seed`. The next time the inner Observable emits a value, `mergeScan`\n * will internally remember it and it will be passed to the `accumulator`\n * function as `acc` parameter the next time source emits.\n *\n * The `value` parameter of the `accumulator` function is the value emitted by the\n * source Observable, while the `index` is a number which represent the order of the\n * current emission by the source Observable. It starts with 0.\n *\n * The last parameter to the `mergeScan` is the `concurrent` value which defaults\n * to Infinity. It represents the maximum number of inner Observable subscriptions\n * at a time.\n *\n * ## Example\n *\n * Count the number of click events\n *\n * ```ts\n * import { fromEvent, map, mergeScan, of } from 'valdi_rxjs';\n *\n * const click$ = fromEvent(document, 'click');\n * const one$ = click$.pipe(map(() => 1));\n * const seed = 0;\n * const count$ = one$.pipe(\n *   mergeScan((acc, one) => of(acc + one), seed)\n * );\n *\n * count$.subscribe(x => console.log(x));\n *\n * // Results:\n * // 1\n * // 2\n * // 3\n * // 4\n * // ...and so on for each click\n * ```\n *\n * @see {@link scan}\n * @see {@link switchScan}\n *\n * @param {function(acc: R, value: T): Observable<R>} accumulator\n * The accumulator function called on each source value.\n * @param seed The initial accumulation value.\n * @param {number} [concurrent=Infinity] Maximum number of\n * input Observables being subscribed to concurrently.\n * @return A function that returns an Observable of the accumulated values.\n */\nexport function mergeScan<T, R>(\n  accumulator: (acc: R, value: T, index: number) => ObservableInput<R>,\n  seed: R,\n  concurrent = Infinity\n): OperatorFunction<T, R> {\n  return operate((source, subscriber) => {\n    // The accumulated state.\n    let state = seed;\n\n    return mergeInternals(\n      source,\n      subscriber,\n      (value, index) => accumulator(state, value, index),\n      concurrent,\n      (value) => {\n        state = value;\n      },\n      false,\n      undefined,\n      () => (state = null!)\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/mergeWith.ts",
    "content": "import { ObservableInputTuple, OperatorFunction } from '../types';\nimport { merge } from './merge';\n\n/**\n * Merge the values from all observables to a single observable result.\n *\n * Creates an observable, that when subscribed to, subscribes to the source\n * observable, and all other sources provided as arguments. All values from\n * every source are emitted from the resulting subscription.\n *\n * When all sources complete, the resulting observable will complete.\n *\n * When any source errors, the resulting observable will error.\n *\n * ## Example\n *\n * Joining all outputs from multiple user input event streams\n *\n * ```ts\n * import { fromEvent, map, mergeWith } from 'valdi_rxjs';\n *\n * const clicks$ = fromEvent(document, 'click').pipe(map(() => 'click'));\n * const mousemoves$ = fromEvent(document, 'mousemove').pipe(map(() => 'mousemove'));\n * const dblclicks$ = fromEvent(document, 'dblclick').pipe(map(() => 'dblclick'));\n *\n * mousemoves$\n *   .pipe(mergeWith(clicks$, dblclicks$))\n *   .subscribe(x => console.log(x));\n *\n * // result (assuming user interactions)\n * // 'mousemove'\n * // 'mousemove'\n * // 'mousemove'\n * // 'click'\n * // 'click'\n * // 'dblclick'\n * ```\n *\n * @see {@link merge}\n *\n * @param otherSources the sources to combine the current source with.\n * @return A function that returns an Observable that merges the values from\n * all given Observables.\n */\nexport function mergeWith<T, A extends readonly unknown[]>(\n  ...otherSources: [...ObservableInputTuple<A>]\n): OperatorFunction<T, T | A[number]> {\n  return merge(...otherSources);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/min.ts",
    "content": "import { reduce } from './reduce';\nimport { MonoTypeOperatorFunction } from '../types';\nimport { isFunction } from '../util/isFunction';\n\n/**\n * The Min operator operates on an Observable that emits numbers (or items that can be compared with a provided function),\n * and when source Observable completes it emits a single item: the item with the smallest value.\n *\n * ![](min.png)\n *\n * ## Examples\n *\n * Get the minimal value of a series of numbers\n *\n * ```ts\n * import { of, min } from 'valdi_rxjs';\n *\n * of(5, 4, 7, 2, 8)\n *   .pipe(min())\n *   .subscribe(x => console.log(x));\n *\n * // Outputs\n * // 2\n * ```\n *\n * Use a comparer function to get the minimal item\n *\n * ```ts\n * import { of, min } from 'valdi_rxjs';\n *\n * of(\n *   { age: 7, name: 'Foo' },\n *   { age: 5, name: 'Bar' },\n *   { age: 9, name: 'Beer' }\n * ).pipe(\n *   min((a, b) => a.age < b.age ? -1 : 1)\n * )\n * .subscribe(x => console.log(x.name));\n *\n * // Outputs\n * // 'Bar'\n * ```\n *\n * @see {@link max}\n *\n * @param {Function} [comparer] - Optional comparer function that it will use instead of its default to compare the\n * value of two items.\n * @return A function that returns an Observable that emits item with the\n * smallest value.\n */\nexport function min<T>(comparer?: (x: T, y: T) => number): MonoTypeOperatorFunction<T> {\n  return reduce(isFunction(comparer) ? (x, y) => (comparer(x, y) < 0 ? x : y) : (x, y) => (x < y ? x : y));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/multicast.ts",
    "content": "import { Subject } from '../Subject';\nimport { Observable } from '../Observable';\nimport { ConnectableObservable } from '../observable/ConnectableObservable';\nimport { OperatorFunction, UnaryFunction, ObservedValueOf, ObservableInput } from '../types';\nimport { isFunction } from '../util/isFunction';\nimport { connect } from './connect';\n\n/**\n * An operator that creates a {@link ConnectableObservable}, that when connected,\n * with the `connect` method, will use the provided subject to multicast the values\n * from the source to all consumers.\n *\n * @param subject The subject to multicast through.\n * @return A function that returns a {@link ConnectableObservable}\n * @deprecated Will be removed in v8. To create a connectable observable, use {@link connectable}.\n * If you're using {@link refCount} after `multicast`, use the {@link share} operator instead.\n * `multicast(subject), refCount()` is equivalent to\n * `share({ connector: () => subject, resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false })`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function multicast<T>(subject: Subject<T>): UnaryFunction<Observable<T>, ConnectableObservable<T>>;\n\n/**\n * Because this is deprecated in favor of the {@link connect} operator, and was otherwise poorly documented,\n * rather than duplicate the effort of documenting the same behavior, please see documentation for the\n * {@link connect} operator.\n *\n * @param subject The subject used to multicast.\n * @param selector A setup function to setup the multicast\n * @return A function that returns an observable that mirrors the observable returned by the selector.\n * @deprecated Will be removed in v8. Use the {@link connect} operator instead.\n * `multicast(subject, selector)` is equivalent to\n * `connect(selector, { connector: () => subject })`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function multicast<T, O extends ObservableInput<any>>(\n  subject: Subject<T>,\n  selector: (shared: Observable<T>) => O\n): OperatorFunction<T, ObservedValueOf<O>>;\n\n/**\n * An operator that creates a {@link ConnectableObservable}, that when connected,\n * with the `connect` method, will use the provided subject to multicast the values\n * from the source to all consumers.\n *\n * @param subjectFactory A factory that will be called to create the subject. Passing a function here\n * will cause the underlying subject to be \"reset\" on error, completion, or refCounted unsubscription of\n * the source.\n * @return A function that returns a {@link ConnectableObservable}\n * @deprecated Will be removed in v8. To create a connectable observable, use {@link connectable}.\n * If you're using {@link refCount} after `multicast`, use the {@link share} operator instead.\n * `multicast(() => new BehaviorSubject('test')), refCount()` is equivalent to\n * `share({ connector: () => new BehaviorSubject('test') })`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function multicast<T>(subjectFactory: () => Subject<T>): UnaryFunction<Observable<T>, ConnectableObservable<T>>;\n\n/**\n * Because this is deprecated in favor of the {@link connect} operator, and was otherwise poorly documented,\n * rather than duplicate the effort of documenting the same behavior, please see documentation for the\n * {@link connect} operator.\n *\n * @param subjectFactory A factory that creates the subject used to multicast.\n * @param selector A function to setup the multicast and select the output.\n * @return A function that returns an observable that mirrors the observable returned by the selector.\n * @deprecated Will be removed in v8. Use the {@link connect} operator instead.\n * `multicast(subjectFactory, selector)` is equivalent to\n * `connect(selector, { connector: subjectFactory })`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function multicast<T, O extends ObservableInput<any>>(\n  subjectFactory: () => Subject<T>,\n  selector: (shared: Observable<T>) => O\n): OperatorFunction<T, ObservedValueOf<O>>;\n\n/**\n * @deprecated Will be removed in v8. Use the {@link connectable} observable, the {@link connect} operator or the\n * {@link share} operator instead. See the overloads below for equivalent replacement examples of this operator's\n * behaviors.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function multicast<T, R>(\n  subjectOrSubjectFactory: Subject<T> | (() => Subject<T>),\n  selector?: (source: Observable<T>) => Observable<R>\n): OperatorFunction<T, R> {\n  const subjectFactory = isFunction(subjectOrSubjectFactory) ? subjectOrSubjectFactory : () => subjectOrSubjectFactory;\n\n  if (isFunction(selector)) {\n    // If a selector function is provided, then we're a \"normal\" operator that isn't\n    // going to return a ConnectableObservable. We can use `connect` to do what we\n    // need to do.\n    return connect(selector, {\n      connector: subjectFactory,\n    });\n  }\n\n  return (source: Observable<T>) => new ConnectableObservable<any>(source, subjectFactory);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/observeOn.ts",
    "content": "/** @prettier */\nimport { MonoTypeOperatorFunction, SchedulerLike } from '../types';\nimport { executeSchedule } from '../util/executeSchedule';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Re-emits all notifications from source Observable with specified scheduler.\n *\n * <span class=\"informal\">Ensure a specific scheduler is used, from outside of an Observable.</span>\n *\n * `observeOn` is an operator that accepts a scheduler as a first parameter, which will be used to reschedule\n * notifications emitted by the source Observable. It might be useful, if you do not have control over\n * internal scheduler of a given Observable, but want to control when its values are emitted nevertheless.\n *\n * Returned Observable emits the same notifications (nexted values, complete and error events) as the source Observable,\n * but rescheduled with provided scheduler. Note that this doesn't mean that source Observables internal\n * scheduler will be replaced in any way. Original scheduler still will be used, but when the source Observable emits\n * notification, it will be immediately scheduled again - this time with scheduler passed to `observeOn`.\n * An anti-pattern would be calling `observeOn` on Observable that emits lots of values synchronously, to split\n * that emissions into asynchronous chunks. For this to happen, scheduler would have to be passed into the source\n * Observable directly (usually into the operator that creates it). `observeOn` simply delays notifications a\n * little bit more, to ensure that they are emitted at expected moments.\n *\n * As a matter of fact, `observeOn` accepts second parameter, which specifies in milliseconds with what delay notifications\n * will be emitted. The main difference between {@link delay} operator and `observeOn` is that `observeOn`\n * will delay all notifications - including error notifications - while `delay` will pass through error\n * from source Observable immediately when it is emitted. In general it is highly recommended to use `delay` operator\n * for any kind of delaying of values in the stream, while using `observeOn` to specify which scheduler should be used\n * for notification emissions in general.\n *\n * ## Example\n *\n * Ensure values in subscribe are called just before browser repaint\n *\n * ```ts\n * import { interval, observeOn, animationFrameScheduler } from 'valdi_rxjs';\n *\n * const someDiv = document.createElement('div');\n * someDiv.style.cssText = 'width: 200px;background: #09c';\n * document.body.appendChild(someDiv);\n * const intervals = interval(10);      // Intervals are scheduled\n *                                      // with async scheduler by default...\n * intervals.pipe(\n *   observeOn(animationFrameScheduler) // ...but we will observe on animationFrame\n * )                                    // scheduler to ensure smooth animation.\n * .subscribe(val => {\n *   someDiv.style.height = val + 'px';\n * });\n * ```\n *\n * @see {@link delay}\n *\n * @param scheduler Scheduler that will be used to reschedule notifications from source Observable.\n * @param delay Number of milliseconds that states with what delay every notification should be rescheduled.\n * @return A function that returns an Observable that emits the same\n * notifications as the source Observable, but with provided scheduler.\n */\nexport function observeOn<T>(scheduler: SchedulerLike, delay = 0): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    source.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        (value) => executeSchedule(subscriber, scheduler, () => subscriber.next(value), delay),\n        () => executeSchedule(subscriber, scheduler, () => subscriber.complete(), delay),\n        (err) => executeSchedule(subscriber, scheduler, () => subscriber.error(err), delay)\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/onErrorResumeNext.ts",
    "content": "import { Observable } from '../Observable';\nimport { ObservableInputTuple, OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { innerFrom } from '../observable/innerFrom';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { noop } from '../util/noop';\n\nexport function onErrorResumeNext<T, A extends readonly unknown[]>(\n  sources: [...ObservableInputTuple<A>]\n): OperatorFunction<T, T | A[number]>;\nexport function onErrorResumeNext<T, A extends readonly unknown[]>(\n  ...sources: [...ObservableInputTuple<A>]\n): OperatorFunction<T, T | A[number]>;\n\n/**\n * When any of the provided Observable emits an complete or error notification, it immediately subscribes to the next one\n * that was passed.\n *\n * <span class=\"informal\">Execute series of Observables, subscribes to next one on error or complete.</span>\n *\n * ![](onErrorResumeNext.png)\n *\n * `onErrorResumeNext` is an operator that accepts a series of Observables, provided either directly as\n * arguments or as an array. If no single Observable is provided, returned Observable will simply behave the same\n * as the source.\n *\n * `onErrorResumeNext` returns an Observable that starts by subscribing and re-emitting values from the source Observable.\n * When its stream of values ends - no matter if Observable completed or emitted an error - `onErrorResumeNext`\n * will subscribe to the first Observable that was passed as an argument to the method. It will start re-emitting\n * its values as well and - again - when that stream ends, `onErrorResumeNext` will proceed to subscribing yet another\n * Observable in provided series, no matter if previous Observable completed or ended with an error. This will\n * be happening until there is no more Observables left in the series, at which point returned Observable will\n * complete - even if the last subscribed stream ended with an error.\n *\n * `onErrorResumeNext` can be therefore thought of as version of {@link concat} operator, which is more permissive\n * when it comes to the errors emitted by its input Observables. While `concat` subscribes to the next Observable\n * in series only if previous one successfully completed, `onErrorResumeNext` subscribes even if it ended with\n * an error.\n *\n * Note that you do not get any access to errors emitted by the Observables. In particular do not\n * expect these errors to appear in error callback passed to {@link Observable#subscribe}. If you want to take\n * specific actions based on what error was emitted by an Observable, you should try out {@link catchError} instead.\n *\n *\n * ## Example\n *\n * Subscribe to the next Observable after map fails\n *\n * ```ts\n * import { of, onErrorResumeNext, map } from 'valdi_rxjs';\n *\n * of(1, 2, 3, 0)\n *   .pipe(\n *     map(x => {\n *       if (x === 0) {\n *         throw Error();\n *       }\n *\n *       return 10 / x;\n *     }),\n *     onErrorResumeNext(of(1, 2, 3))\n *   )\n *   .subscribe({\n *     next: val => console.log(val),\n *     error: err => console.log(err),          // Will never be called.\n *     complete: () => console.log('that\\'s it!')\n *   });\n *\n * // Logs:\n * // 10\n * // 5\n * // 3.3333333333333335\n * // 1\n * // 2\n * // 3\n * // 'that's it!'\n * ```\n *\n * @see {@link concat}\n * @see {@link catchError}\n *\n * @param {...ObservableInput} sources Observables passed either directly or as an array.\n * @return A function that returns an Observable that emits values from source\n * Observable, but - if it errors - subscribes to the next passed Observable\n * and so on, until it completes or runs out of Observables.\n */\nexport function onErrorResumeNext<T, A extends readonly unknown[]>(\n  ...sources: [[...ObservableInputTuple<A>]] | [...ObservableInputTuple<A>]\n): OperatorFunction<T, T | A[number]> {\n  // For some reason, TS 4.1 RC gets the inference wrong here and infers the\n  // result to be `A[number][]` - completely dropping the ObservableInput part\n  // of the type. This makes no sense whatsoever. As a workaround, the type is\n  // asserted explicitly.\n  const nextSources = argsOrArgArray(sources) as unknown as ObservableInputTuple<A>;\n\n  return operate((source, subscriber) => {\n    const remaining = [source, ...nextSources];\n    const subscribeNext = () => {\n      if (!subscriber.closed) {\n        if (remaining.length > 0) {\n          let nextSource: Observable<A[number]>;\n          try {\n            nextSource = innerFrom<T | A[number]>(remaining.shift()!);\n          } catch (err) {\n            subscribeNext();\n            return;\n          }\n\n          // Here we have to use one of our Subscribers, or it does not wire up\n          // The `closed` property of upstream Subscribers synchronously, that\n          // would result in situation were we could not stop a synchronous firehose\n          // with something like `take(3)`.\n          const innerSub = createOperatorSubscriber(subscriber, undefined, noop, noop);\n          nextSource.subscribe(innerSub);\n          innerSub.add(subscribeNext);\n        } else {\n          subscriber.complete();\n        }\n      }\n    };\n\n    subscribeNext();\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/pairwise.ts",
    "content": "import { OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Groups pairs of consecutive emissions together and emits them as an array of\n * two values.\n *\n * <span class=\"informal\">Puts the current value and previous value together as\n * an array, and emits that.</span>\n *\n * ![](pairwise.png)\n *\n * The Nth emission from the source Observable will cause the output Observable\n * to emit an array [(N-1)th, Nth] of the previous and the current value, as a\n * pair. For this reason, `pairwise` emits on the second and subsequent\n * emissions from the source Observable, but not on the first emission, because\n * there is no previous value in that case.\n *\n * ## Example\n *\n * On every click (starting from the second), emit the relative distance to the previous click\n *\n * ```ts\n * import { fromEvent, pairwise, map } from 'valdi_rxjs';\n *\n * const clicks = fromEvent<PointerEvent>(document, 'click');\n * const pairs = clicks.pipe(pairwise());\n * const distance = pairs.pipe(\n *   map(([first, second]) => {\n *     const x0 = first.clientX;\n *     const y0 = first.clientY;\n *     const x1 = second.clientX;\n *     const y1 = second.clientY;\n *     return Math.sqrt(Math.pow(x0 - x1, 2) + Math.pow(y0 - y1, 2));\n *   })\n * );\n *\n * distance.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link buffer}\n * @see {@link bufferCount}\n *\n * @return A function that returns an Observable of pairs (as arrays) of\n * consecutive values from the source Observable.\n */\nexport function pairwise<T>(): OperatorFunction<T, [T, T]> {\n  return operate((source, subscriber) => {\n    let prev: T;\n    let hasPrev = false;\n    source.subscribe(\n      createOperatorSubscriber(subscriber, (value) => {\n        const p = prev;\n        prev = value;\n        hasPrev && subscriber.next([p, value]);\n        hasPrev = true;\n      })\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/pluck.ts",
    "content": "import { map } from './map';\nimport { OperatorFunction } from '../types';\n\n/* tslint:disable:max-line-length */\nexport function pluck<T, K1 extends keyof T>(k1: K1): OperatorFunction<T, T[K1]>;\nexport function pluck<T, K1 extends keyof T, K2 extends keyof T[K1]>(k1: K1, k2: K2): OperatorFunction<T, T[K1][K2]>;\nexport function pluck<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2]>(\n  k1: K1,\n  k2: K2,\n  k3: K3\n): OperatorFunction<T, T[K1][K2][K3]>;\nexport function pluck<T, K1 extends keyof T, K2 extends keyof T[K1], K3 extends keyof T[K1][K2], K4 extends keyof T[K1][K2][K3]>(\n  k1: K1,\n  k2: K2,\n  k3: K3,\n  k4: K4\n): OperatorFunction<T, T[K1][K2][K3][K4]>;\nexport function pluck<\n  T,\n  K1 extends keyof T,\n  K2 extends keyof T[K1],\n  K3 extends keyof T[K1][K2],\n  K4 extends keyof T[K1][K2][K3],\n  K5 extends keyof T[K1][K2][K3][K4]\n>(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5): OperatorFunction<T, T[K1][K2][K3][K4][K5]>;\nexport function pluck<\n  T,\n  K1 extends keyof T,\n  K2 extends keyof T[K1],\n  K3 extends keyof T[K1][K2],\n  K4 extends keyof T[K1][K2][K3],\n  K5 extends keyof T[K1][K2][K3][K4],\n  K6 extends keyof T[K1][K2][K3][K4][K5]\n>(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5, k6: K6): OperatorFunction<T, T[K1][K2][K3][K4][K5][K6]>;\nexport function pluck<\n  T,\n  K1 extends keyof T,\n  K2 extends keyof T[K1],\n  K3 extends keyof T[K1][K2],\n  K4 extends keyof T[K1][K2][K3],\n  K5 extends keyof T[K1][K2][K3][K4],\n  K6 extends keyof T[K1][K2][K3][K4][K5]\n>(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5, k6: K6, ...rest: string[]): OperatorFunction<T, unknown>;\nexport function pluck<T>(...properties: string[]): OperatorFunction<T, unknown>;\n/* tslint:enable:max-line-length */\n\n/**\n * Maps each source value to its specified nested property.\n *\n * <span class=\"informal\">Like {@link map}, but meant only for picking one of\n * the nested properties of every emitted value.</span>\n *\n * ![](pluck.png)\n *\n * Given a list of strings or numbers describing a path to a property, retrieves\n * the value of a specified nested property from all values in the source\n * Observable. If a property can't be resolved, it will return `undefined` for\n * that value.\n *\n * ## Example\n *\n * Map every click to the tagName of the clicked target element\n *\n * ```ts\n * import { fromEvent, pluck } from 'valdi_rxjs';\n *\n * const clicks = fromEvent(document, 'click');\n * const tagNames = clicks.pipe(pluck('target', 'tagName'));\n *\n * tagNames.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link map}\n *\n * @param properties The nested properties to pluck from each source\n * value.\n * @return A function that returns an Observable of property values from the\n * source values.\n * @deprecated Use {@link map} and optional chaining: `pluck('foo', 'bar')` is `map(x => x?.foo?.bar)`. Will be removed in v8.\n */\nexport function pluck<T, R>(...properties: Array<string | number | symbol>): OperatorFunction<T, R> {\n  const length = properties.length;\n  if (length === 0) {\n    throw new Error('list of properties cannot be empty.');\n  }\n  return map((x) => {\n    let currentProp: any = x;\n    for (let i = 0; i < length; i++) {\n      const p = currentProp?.[properties[i]];\n      if (typeof p !== 'undefined') {\n        currentProp = p;\n      } else {\n        return undefined;\n      }\n    }\n    return currentProp;\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/publish.ts",
    "content": "import { Observable } from '../Observable';\nimport { Subject } from '../Subject';\nimport { multicast } from './multicast';\nimport { ConnectableObservable } from '../observable/ConnectableObservable';\nimport { MonoTypeOperatorFunction, OperatorFunction, UnaryFunction, ObservableInput, ObservedValueOf } from '../types';\nimport { connect } from './connect';\n\n/**\n * Returns a connectable observable that, when connected, will multicast\n * all values through a single underlying {@link Subject} instance.\n *\n * @deprecated Will be removed in v8. To create a connectable observable, use {@link connectable}.\n * `source.pipe(publish())` is equivalent to\n * `connectable(source, { connector: () => new Subject(), resetOnDisconnect: false })`.\n * If you're using {@link refCount} after `publish`, use {@link share} operator instead.\n * `source.pipe(publish(), refCount())` is equivalent to\n * `source.pipe(share({ resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false }))`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function publish<T>(): UnaryFunction<Observable<T>, ConnectableObservable<T>>;\n\n/**\n * Returns an observable, that when subscribed to, creates an underlying {@link Subject},\n * provides an observable view of it to a `selector` function, takes the observable result of\n * that selector function and subscribes to it, sending its values to the consumer, _then_ connects\n * the subject to the original source.\n *\n * @param selector A function used to setup multicasting prior to automatic connection.\n *\n * @deprecated Will be removed in v8. Use the {@link connect} operator instead.\n * `publish(selector)` is equivalent to `connect(selector)`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function publish<T, O extends ObservableInput<any>>(selector: (shared: Observable<T>) => O): OperatorFunction<T, ObservedValueOf<O>>;\n\n/**\n * Returns a ConnectableObservable, which is a variety of Observable that waits until its connect method is called\n * before it begins emitting items to those Observers that have subscribed to it.\n *\n * <span class=\"informal\">Makes a cold Observable hot</span>\n *\n * ![](publish.png)\n *\n * ## Examples\n *\n * Make `source$` hot by applying `publish` operator, then merge each inner observable into a single one\n * and subscribe\n *\n * ```ts\n * import { zip, interval, of, map, publish, merge, tap } from 'valdi_rxjs';\n *\n * const source$ = zip(interval(2000), of(1, 2, 3, 4, 5, 6, 7, 8, 9))\n *   .pipe(map(([, number]) => number));\n *\n * source$\n *   .pipe(\n *     publish(multicasted$ =>\n *       merge(\n *         multicasted$.pipe(tap(x => console.log('Stream 1:', x))),\n *         multicasted$.pipe(tap(x => console.log('Stream 2:', x))),\n *         multicasted$.pipe(tap(x => console.log('Stream 3:', x)))\n *       )\n *     )\n *   )\n *   .subscribe();\n *\n * // Results every two seconds\n * // Stream 1: 1\n * // Stream 2: 1\n * // Stream 3: 1\n * // ...\n * // Stream 1: 9\n * // Stream 2: 9\n * // Stream 3: 9\n * ```\n *\n * @see {@link publishLast}\n * @see {@link publishReplay}\n * @see {@link publishBehavior}\n *\n * @param {Function} [selector] - Optional selector function which can use the multicasted source sequence as many times\n * as needed, without causing multiple subscriptions to the source sequence.\n * Subscribers to the given source will receive all notifications of the source from the time of the subscription on.\n * @return A function that returns a ConnectableObservable that upon connection\n * causes the source Observable to emit items to its Observers.\n * @deprecated Will be removed in v8. Use the {@link connectable} observable, the {@link connect} operator or the\n * {@link share} operator instead. See the overloads below for equivalent replacement examples of this operator's\n * behaviors.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function publish<T, R>(selector?: OperatorFunction<T, R>): MonoTypeOperatorFunction<T> | OperatorFunction<T, R> {\n  return selector ? (source) => connect(selector)(source) : (source) => multicast(new Subject<T>())(source);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/publishBehavior.ts",
    "content": "import { Observable } from '../Observable';\nimport { BehaviorSubject } from '../BehaviorSubject';\nimport { ConnectableObservable } from '../observable/ConnectableObservable';\nimport { UnaryFunction } from '../types';\n\n/**\n * Creates a {@link ConnectableObservable} that utilizes a {@link BehaviorSubject}.\n *\n * @param initialValue The initial value passed to the {@link BehaviorSubject}.\n * @return A function that returns a {@link ConnectableObservable}\n * @deprecated Will be removed in v8. To create a connectable observable that uses a\n * {@link BehaviorSubject} under the hood, use {@link connectable}.\n * `source.pipe(publishBehavior(initValue))` is equivalent to\n * `connectable(source, { connector: () => new BehaviorSubject(initValue), resetOnDisconnect: false })`.\n * If you're using {@link refCount} after `publishBehavior`, use the {@link share} operator instead.\n * `source.pipe(publishBehavior(initValue), refCount())` is equivalent to\n * `source.pipe(share({ connector: () => new BehaviorSubject(initValue), resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false  }))`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function publishBehavior<T>(initialValue: T): UnaryFunction<Observable<T>, ConnectableObservable<T>> {\n  // Note that this has *never* supported the selector function.\n  return (source) => {\n    const subject = new BehaviorSubject<T>(initialValue);\n    return new ConnectableObservable(source, () => subject);\n  };\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/publishReplay.ts",
    "content": "import { Observable } from '../Observable';\nimport { ReplaySubject } from '../ReplaySubject';\nimport { multicast } from './multicast';\nimport { MonoTypeOperatorFunction, OperatorFunction, TimestampProvider, ObservableInput, ObservedValueOf } from '../types';\nimport { isFunction } from '../util/isFunction';\n\n/**\n * Creates a {@link ConnectableObservable} that uses a {@link ReplaySubject}\n * internally.\n *\n * @param bufferSize The buffer size for the underlying {@link ReplaySubject}.\n * @param windowTime The window time for the underlying {@link ReplaySubject}.\n * @param timestampProvider The timestamp provider for the underlying {@link ReplaySubject}.\n * @deprecated Will be removed in v8. To create a connectable observable that uses a\n * {@link ReplaySubject} under the hood, use {@link connectable}.\n * `source.pipe(publishReplay(size, time, scheduler))` is equivalent to\n * `connectable(source, { connector: () => new ReplaySubject(size, time, scheduler), resetOnDisconnect: false })`.\n * If you're using {@link refCount} after `publishReplay`, use the {@link share} operator instead.\n * `publishReplay(size, time, scheduler), refCount()` is equivalent to\n * `share({ connector: () => new ReplaySubject(size, time, scheduler), resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false })`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function publishReplay<T>(\n  bufferSize?: number,\n  windowTime?: number,\n  timestampProvider?: TimestampProvider\n): MonoTypeOperatorFunction<T>;\n\n/**\n * Creates an observable, that when subscribed to, will create a {@link ReplaySubject},\n * and pass an observable from it (using [asObservable](api/index/class/Subject#asObservable)) to\n * the `selector` function, which then returns an observable that is subscribed to before\n * \"connecting\" the source to the internal `ReplaySubject`.\n *\n * Since this is deprecated, for additional details see the documentation for {@link connect}.\n *\n * @param bufferSize The buffer size for the underlying {@link ReplaySubject}.\n * @param windowTime The window time for the underlying {@link ReplaySubject}.\n * @param selector A function used to setup the multicast.\n * @param timestampProvider The timestamp provider for the underlying {@link ReplaySubject}.\n * @deprecated Will be removed in v8. Use the {@link connect} operator instead.\n * `source.pipe(publishReplay(size, window, selector, scheduler))` is equivalent to\n * `source.pipe(connect(selector, { connector: () => new ReplaySubject(size, window, scheduler) }))`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function publishReplay<T, O extends ObservableInput<any>>(\n  bufferSize: number | undefined,\n  windowTime: number | undefined,\n  selector: (shared: Observable<T>) => O,\n  timestampProvider?: TimestampProvider\n): OperatorFunction<T, ObservedValueOf<O>>;\n\n/**\n * Creates a {@link ConnectableObservable} that uses a {@link ReplaySubject}\n * internally.\n *\n * @param bufferSize The buffer size for the underlying {@link ReplaySubject}.\n * @param windowTime The window time for the underlying {@link ReplaySubject}.\n * @param selector Passing `undefined` here determines that this operator will return a {@link ConnectableObservable}.\n * @param timestampProvider The timestamp provider for the underlying {@link ReplaySubject}.\n * @deprecated Will be removed in v8. To create a connectable observable that uses a\n * {@link ReplaySubject} under the hood, use {@link connectable}.\n * `source.pipe(publishReplay(size, time, scheduler))` is equivalent to\n * `connectable(source, { connector: () => new ReplaySubject(size, time, scheduler), resetOnDisconnect: false })`.\n * If you're using {@link refCount} after `publishReplay`, use the {@link share} operator instead.\n * `publishReplay(size, time, scheduler), refCount()` is equivalent to\n * `share({ connector: () => new ReplaySubject(size, time, scheduler), resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false })`.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function publishReplay<T, O extends ObservableInput<any>>(\n  bufferSize: number | undefined,\n  windowTime: number | undefined,\n  selector: undefined,\n  timestampProvider: TimestampProvider\n): OperatorFunction<T, ObservedValueOf<O>>;\n\n/**\n * @deprecated Will be removed in v8. Use the {@link connectable} observable, the {@link connect} operator or the\n * {@link share} operator instead. See the overloads below for equivalent replacement examples of this operator's\n * behaviors.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function publishReplay<T, R>(\n  bufferSize?: number,\n  windowTime?: number,\n  selectorOrScheduler?: TimestampProvider | OperatorFunction<T, R>,\n  timestampProvider?: TimestampProvider\n) {\n  if (selectorOrScheduler && !isFunction(selectorOrScheduler)) {\n    timestampProvider = selectorOrScheduler;\n  }\n  const selector = isFunction(selectorOrScheduler) ? selectorOrScheduler : undefined;\n  // Note, we're passing `selector!` here, because at runtime, `undefined` is an acceptable argument\n  // but it makes our TypeScript signature for `multicast` unhappy (as it should, because it's gross).\n  return (source: Observable<T>) => multicast(new ReplaySubject<T>(bufferSize, windowTime, timestampProvider), selector!)(source);\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/race.ts",
    "content": "import { ObservableInputTuple, OperatorFunction } from '../types';\nimport { argsOrArgArray } from '../util/argsOrArgArray';\nimport { raceWith } from './raceWith';\n\n/** @deprecated Replaced with {@link raceWith}. Will be removed in v8. */\nexport function race<T, A extends readonly unknown[]>(otherSources: [...ObservableInputTuple<A>]): OperatorFunction<T, T | A[number]>;\n/** @deprecated Replaced with {@link raceWith}. Will be removed in v8. */\nexport function race<T, A extends readonly unknown[]>(...otherSources: [...ObservableInputTuple<A>]): OperatorFunction<T, T | A[number]>;\n\n/**\n * Returns an Observable that mirrors the first source Observable to emit a next,\n * error or complete notification from the combination of this Observable and supplied Observables.\n * @param args Sources used to race for which Observable emits first.\n * @return A function that returns an Observable that mirrors the output of the\n * first Observable to emit an item.\n * @deprecated Replaced with {@link raceWith}. Will be removed in v8.\n */\nexport function race<T>(...args: any[]): OperatorFunction<T, unknown> {\n  return raceWith(...argsOrArgArray(args));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/raceWith.ts",
    "content": "import { OperatorFunction, ObservableInputTuple } from '../types';\nimport { raceInit } from '../observable/race';\nimport { operate } from '../util/lift';\nimport { identity } from '../util/identity';\n\n/**\n * Creates an Observable that mirrors the first source Observable to emit a next,\n * error or complete notification from the combination of the Observable to which\n * the operator is applied and supplied Observables.\n *\n * ## Example\n *\n * ```ts\n * import { interval, map, raceWith } from 'valdi_rxjs';\n *\n * const obs1 = interval(7000).pipe(map(() => 'slow one'));\n * const obs2 = interval(3000).pipe(map(() => 'fast one'));\n * const obs3 = interval(5000).pipe(map(() => 'medium one'));\n *\n * obs1\n *   .pipe(raceWith(obs2, obs3))\n *   .subscribe(winner => console.log(winner));\n *\n * // Outputs\n * // a series of 'fast one'\n * ```\n *\n * @param otherSources Sources used to race for which Observable emits first.\n * @return A function that returns an Observable that mirrors the output of the\n * first Observable to emit an item.\n */\nexport function raceWith<T, A extends readonly unknown[]>(\n  ...otherSources: [...ObservableInputTuple<A>]\n): OperatorFunction<T, T | A[number]> {\n  return !otherSources.length\n    ? identity\n    : operate((source, subscriber) => {\n        raceInit<T | A[number]>([source, ...otherSources])(subscriber);\n      });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/reduce.ts",
    "content": "import { scanInternals } from './scanInternals';\nimport { OperatorFunction } from '../types';\nimport { operate } from '../util/lift';\n\nexport function reduce<V, A = V>(accumulator: (acc: A | V, value: V, index: number) => A): OperatorFunction<V, V | A>;\nexport function reduce<V, A>(accumulator: (acc: A, value: V, index: number) => A, seed: A): OperatorFunction<V, A>;\nexport function reduce<V, A, S = A>(accumulator: (acc: A | S, value: V, index: number) => A, seed: S): OperatorFunction<V, A>;\n\n/**\n * Applies an accumulator function over the source Observable, and returns the\n * accumulated result when the source completes, given an optional seed value.\n *\n * <span class=\"informal\">Combines together all values emitted on the source,\n * using an accumulator function that knows how to join a new source value into\n * the accumulation from the past.</span>\n *\n * ![](reduce.png)\n *\n * Like\n * [Array.prototype.reduce()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce),\n * `reduce` applies an `accumulator` function against an accumulation and each\n * value of the source Observable (from the past) to reduce it to a single\n * value, emitted on the output Observable. Note that `reduce` will only emit\n * one value, only when the source Observable completes. It is equivalent to\n * applying operator {@link scan} followed by operator {@link last}.\n *\n * Returns an Observable that applies a specified `accumulator` function to each\n * item emitted by the source Observable. If a `seed` value is specified, then\n * that value will be used as the initial value for the accumulator. If no seed\n * value is specified, the first item of the source is used as the seed.\n *\n * ## Example\n *\n * Count the number of click events that happened in 5 seconds\n *\n * ```ts\n * import { fromEvent, takeUntil, interval, map, reduce } from 'valdi_rxjs';\n *\n * const clicksInFiveSeconds = fromEvent(document, 'click')\n *   .pipe(takeUntil(interval(5000)));\n *\n * const ones = clicksInFiveSeconds.pipe(map(() => 1));\n * const seed = 0;\n * const count = ones.pipe(reduce((acc, one) => acc + one, seed));\n *\n * count.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link count}\n * @see {@link expand}\n * @see {@link mergeScan}\n * @see {@link scan}\n *\n * @param {function(acc: A, value: V, index: number): A} accumulator The accumulator function\n * called on each source value.\n * @param {A} [seed] The initial accumulation value.\n * @return A function that returns an Observable that emits a single value that\n * is the result of accumulating the values emitted by the source Observable.\n */\nexport function reduce<V, A>(accumulator: (acc: V | A, value: V, index: number) => A, seed?: any): OperatorFunction<V, V | A> {\n  return operate(scanInternals(accumulator, seed, arguments.length >= 2, false, true));\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/refCount.ts",
    "content": "import { ConnectableObservable } from '../observable/ConnectableObservable';\nimport { Subscription } from '../Subscription';\nimport { MonoTypeOperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Make a {@link ConnectableObservable} behave like a ordinary observable and automates the way\n * you can connect to it.\n *\n * Internally it counts the subscriptions to the observable and subscribes (only once) to the source if\n * the number of subscriptions is larger than 0. If the number of subscriptions is smaller than 1, it\n * unsubscribes from the source. This way you can make sure that everything before the *published*\n * refCount has only a single subscription independently of the number of subscribers to the target\n * observable.\n *\n * Note that using the {@link share} operator is exactly the same as using the `multicast(() => new Subject())` operator\n * (making the observable hot) and the *refCount* operator in a sequence.\n *\n * ![](refCount.png)\n *\n * ## Example\n *\n * In the following example there are two intervals turned into connectable observables\n * by using the *publish* operator. The first one uses the *refCount* operator, the\n * second one does not use it. You will notice that a connectable observable does nothing\n * until you call its connect function.\n *\n * ```ts\n * import { interval, tap, publish, refCount } from 'valdi_rxjs';\n *\n * // Turn the interval observable into a ConnectableObservable (hot)\n * const refCountInterval = interval(400).pipe(\n *   tap(num => console.log(`refCount ${ num }`)),\n *   publish(),\n *   refCount()\n * );\n *\n * const publishedInterval = interval(400).pipe(\n *   tap(num => console.log(`publish ${ num }`)),\n *   publish()\n * );\n *\n * refCountInterval.subscribe();\n * refCountInterval.subscribe();\n * // 'refCount 0' -----> 'refCount 1' -----> etc\n * // All subscriptions will receive the same value and the tap (and\n * // every other operator) before the `publish` operator will be executed\n * // only once per event independently of the number of subscriptions.\n *\n * publishedInterval.subscribe();\n * // Nothing happens until you call .connect() on the observable.\n * ```\n *\n * @return A function that returns an Observable that automates the connection\n * to ConnectableObservable.\n * @see {@link ConnectableObservable}\n * @see {@link share}\n * @see {@link publish}\n * @deprecated Replaced with the {@link share} operator. How `share` is used\n * will depend on the connectable observable you created just prior to the\n * `refCount` operator.\n * Details: https://rxjs.dev/deprecations/multicasting\n */\nexport function refCount<T>(): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    let connection: Subscription | null = null;\n\n    (source as any)._refCount++;\n\n    const refCounter = createOperatorSubscriber(subscriber, undefined, undefined, undefined, () => {\n      if (!source || (source as any)._refCount <= 0 || 0 < --(source as any)._refCount) {\n        connection = null;\n        return;\n      }\n\n      ///\n      // Compare the local RefCountSubscriber's connection Subscription to the\n      // connection Subscription on the shared ConnectableObservable. In cases\n      // where the ConnectableObservable source synchronously emits values, and\n      // the RefCountSubscriber's downstream Observers synchronously unsubscribe,\n      // execution continues to here before the RefCountOperator has a chance to\n      // supply the RefCountSubscriber with the shared connection Subscription.\n      // For example:\n      // ```\n      // range(0, 10).pipe(\n      //   publish(),\n      //   refCount(),\n      //   take(5),\n      // )\n      // .subscribe();\n      // ```\n      // In order to account for this case, RefCountSubscriber should only dispose\n      // the ConnectableObservable's shared connection Subscription if the\n      // connection Subscription exists, *and* either:\n      //   a. RefCountSubscriber doesn't have a reference to the shared connection\n      //      Subscription yet, or,\n      //   b. RefCountSubscriber's connection Subscription reference is identical\n      //      to the shared connection Subscription\n      ///\n\n      const sharedConnection = (source as any)._connection;\n      const conn = connection;\n      connection = null;\n\n      if (sharedConnection && (!conn || sharedConnection === conn)) {\n        sharedConnection.unsubscribe();\n      }\n\n      subscriber.unsubscribe();\n    });\n\n    source.subscribe(refCounter);\n\n    if (!refCounter.closed) {\n      connection = (source as ConnectableObservable<T>).connect();\n    }\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/repeat.ts",
    "content": "import { Subscription } from '../Subscription';\nimport { EMPTY } from '../observable/empty';\nimport { operate } from '../util/lift';\nimport { MonoTypeOperatorFunction, ObservableInput } from '../types';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\nimport { innerFrom } from '../observable/innerFrom';\nimport { timer } from '../observable/timer';\n\nexport interface RepeatConfig {\n  /**\n   * The number of times to repeat the source. Defaults to `Infinity`.\n   */\n  count?: number;\n\n  /**\n   * If a `number`, will delay the repeat of the source by that number of milliseconds.\n   * If a function, it will provide the number of times the source has been subscribed to,\n   * and the return value should be a valid observable input that will notify when the source\n   * should be repeated. If the notifier observable is empty, the result will complete.\n   */\n  delay?: number | ((count: number) => ObservableInput<any>);\n}\n\n/**\n * Returns an Observable that will resubscribe to the source stream when the source stream completes.\n *\n * <span class=\"informal\">Repeats all values emitted on the source. It's like {@link retry}, but for non error cases.</span>\n *\n * ![](repeat.png)\n *\n * Repeat will output values from a source until the source completes, then it will resubscribe to the\n * source a specified number of times, with a specified delay. Repeat can be particularly useful in\n * combination with closing operators like {@link take}, {@link takeUntil}, {@link first}, or {@link takeWhile},\n * as it can be used to restart a source again from scratch.\n *\n * Repeat is very similar to {@link retry}, where {@link retry} will resubscribe to the source in the error case, but\n * `repeat` will resubscribe if the source completes.\n *\n * Note that `repeat` will _not_ catch errors. Use {@link retry} for that.\n *\n * - `repeat(0)` returns an empty observable\n * - `repeat()` will repeat forever\n * - `repeat({ delay: 200 })` will repeat forever, with a delay of 200ms between repetitions.\n * - `repeat({ count: 2, delay: 400 })` will repeat twice, with a delay of 400ms between repetitions.\n * - `repeat({ delay: (count) => timer(count * 1000) })` will repeat forever, but will have a delay that grows by one second for each repetition.\n *\n * ## Example\n *\n * Repeat a message stream\n *\n * ```ts\n * import { of, repeat } from 'valdi_rxjs';\n *\n * const source = of('Repeat message');\n * const result = source.pipe(repeat(3));\n *\n * result.subscribe(x => console.log(x));\n *\n * // Results\n * // 'Repeat message'\n * // 'Repeat message'\n * // 'Repeat message'\n * ```\n *\n * Repeat 3 values, 2 times\n *\n * ```ts\n * import { interval, take, repeat } from 'valdi_rxjs';\n *\n * const source = interval(1000);\n * const result = source.pipe(take(3), repeat(2));\n *\n * result.subscribe(x => console.log(x));\n *\n * // Results every second\n * // 0\n * // 1\n * // 2\n * // 0\n * // 1\n * // 2\n * ```\n *\n * Defining two complex repeats with delays on the same source.\n * Note that the second repeat cannot be called until the first\n * repeat as exhausted it's count.\n *\n * ```ts\n * import { defer, of, repeat } from 'valdi_rxjs';\n *\n * const source = defer(() => {\n *    return of(`Hello, it is ${new Date()}`)\n * });\n *\n * source.pipe(\n *    // Repeat 3 times with a delay of 1 second between repetitions\n *    repeat({\n *      count: 3,\n *      delay: 1000,\n *    }),\n *\n *    // *Then* repeat forever, but with an exponential step-back\n *    // maxing out at 1 minute.\n *    repeat({\n *      delay: (count) => timer(Math.min(60000, 2 ^ count * 1000))\n *    })\n * )\n * ```\n *\n * @see {@link repeatWhen}\n * @see {@link retry}\n *\n * @param count The number of times the source Observable items are repeated, a count of 0 will yield\n * an empty Observable.\n */\nexport function repeat<T>(countOrConfig?: number | RepeatConfig): MonoTypeOperatorFunction<T> {\n  let count = Infinity;\n  let delay: RepeatConfig['delay'];\n\n  if (countOrConfig != null) {\n    if (typeof countOrConfig === 'object') {\n      ({ count = Infinity, delay } = countOrConfig);\n    } else {\n      count = countOrConfig;\n    }\n  }\n\n  return count <= 0\n    ? () => EMPTY\n    : operate((source, subscriber) => {\n        let soFar = 0;\n        let sourceSub: Subscription | null;\n\n        const resubscribe = () => {\n          sourceSub?.unsubscribe();\n          sourceSub = null;\n          if (delay != null) {\n            const notifier = typeof delay === 'number' ? timer(delay) : innerFrom(delay(soFar));\n            const notifierSubscriber = createOperatorSubscriber(subscriber, () => {\n              notifierSubscriber.unsubscribe();\n              subscribeToSource();\n            });\n            notifier.subscribe(notifierSubscriber);\n          } else {\n            subscribeToSource();\n          }\n        };\n\n        const subscribeToSource = () => {\n          let syncUnsub = false;\n          sourceSub = source.subscribe(\n            createOperatorSubscriber(subscriber, undefined, () => {\n              if (++soFar < count) {\n                if (sourceSub) {\n                  resubscribe();\n                } else {\n                  syncUnsub = true;\n                }\n              } else {\n                subscriber.complete();\n              }\n            })\n          );\n\n          if (syncUnsub) {\n            resubscribe();\n          }\n        };\n\n        subscribeToSource();\n      });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/repeatWhen.ts",
    "content": "import { Observable } from '../Observable';\nimport { Subject } from '../Subject';\nimport { Subscription } from '../Subscription';\n\nimport { MonoTypeOperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Returns an Observable that mirrors the source Observable with the exception of a `complete`. If the source\n * Observable calls `complete`, this method will emit to the Observable returned from `notifier`. If that Observable\n * calls `complete` or `error`, then this method will call `complete` or `error` on the child subscription. Otherwise\n * this method will resubscribe to the source Observable.\n *\n * ![](repeatWhen.png)\n *\n * ## Example\n *\n * Repeat a message stream on click\n *\n * ```ts\n * import { of, fromEvent, repeatWhen } from 'valdi_rxjs';\n *\n * const source = of('Repeat message');\n * const documentClick$ = fromEvent(document, 'click');\n *\n * const result = source.pipe(repeatWhen(() => documentClick$));\n *\n * result.subscribe(data => console.log(data))\n * ```\n *\n * @see {@link repeat}\n * @see {@link retry}\n * @see {@link retryWhen}\n *\n * @param {function(notifications: Observable): Observable} notifier - Receives an Observable of notifications with\n * which a user can `complete` or `error`, aborting the repetition.\n * @return A function that returns an Observable that that mirrors the source\n * Observable with the exception of a `complete`.\n * @deprecated Will be removed in v9 or v10. Use {@link repeat}'s `delay` option instead.\n */\nexport function repeatWhen<T>(notifier: (notifications: Observable<void>) => Observable<any>): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    let innerSub: Subscription | null;\n    let syncResub = false;\n    let completions$: Subject<void>;\n    let isNotifierComplete = false;\n    let isMainComplete = false;\n\n    /**\n     * Checks to see if we can complete the result, completes it, and returns `true` if it was completed.\n     */\n    const checkComplete = () => isMainComplete && isNotifierComplete && (subscriber.complete(), true);\n    /**\n     * Gets the subject to send errors through. If it doesn't exist,\n     * we know we need to setup the notifier.\n     */\n    const getCompletionSubject = () => {\n      if (!completions$) {\n        completions$ = new Subject();\n\n        // If the call to `notifier` throws, it will be caught by the OperatorSubscriber\n        // In the main subscription -- in `subscribeForRepeatWhen`.\n        notifier(completions$).subscribe(\n          createOperatorSubscriber(\n            subscriber,\n            () => {\n              if (innerSub) {\n                subscribeForRepeatWhen();\n              } else {\n                // If we don't have an innerSub yet, that's because the inner subscription\n                // call hasn't even returned yet. We've arrived here synchronously.\n                // So we flag that we want to resub, such that we can ensure finalization\n                // happens before we resubscribe.\n                syncResub = true;\n              }\n            },\n            () => {\n              isNotifierComplete = true;\n              checkComplete();\n            }\n          )\n        );\n      }\n      return completions$;\n    };\n\n    const subscribeForRepeatWhen = () => {\n      isMainComplete = false;\n\n      innerSub = source.subscribe(\n        createOperatorSubscriber(subscriber, undefined, () => {\n          isMainComplete = true;\n          // Check to see if we are complete, and complete if so.\n          // If we are not complete. Get the subject. This calls the `notifier` function.\n          // If that function fails, it will throw and `.next()` will not be reached on this\n          // line. The thrown error is caught by the _complete handler in this\n          // `OperatorSubscriber` and handled appropriately.\n          !checkComplete() && getCompletionSubject().next();\n        })\n      );\n\n      if (syncResub) {\n        // Ensure that the inner subscription is torn down before\n        // moving on to the next subscription in the synchronous case.\n        // If we don't do this here, all inner subscriptions will not be\n        // torn down until the entire observable is done.\n        innerSub.unsubscribe();\n        // It is important to null this out. Not only to free up memory, but\n        // to make sure code above knows we are in a subscribing state to\n        // handle synchronous resubscription.\n        innerSub = null;\n        // We may need to do this multiple times, so reset the flags.\n        syncResub = false;\n        // Resubscribe\n        subscribeForRepeatWhen();\n      }\n    };\n\n    // Start the subscription\n    subscribeForRepeatWhen();\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/sample.ts",
    "content": "import { Observable } from '../Observable';\nimport { MonoTypeOperatorFunction } from '../types';\nimport { operate } from '../util/lift';\nimport { noop } from '../util/noop';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Emits the most recently emitted value from the source Observable whenever\n * another Observable, the `notifier`, emits.\n *\n * <span class=\"informal\">It's like {@link sampleTime}, but samples whenever\n * the `notifier` Observable emits something.</span>\n *\n * ![](sample.png)\n *\n * Whenever the `notifier` Observable emits a value, `sample`\n * looks at the source Observable and emits whichever value it has most recently\n * emitted since the previous sampling, unless the source has not emitted\n * anything since the previous sampling. The `notifier` is subscribed to as soon\n * as the output Observable is subscribed.\n *\n * ## Example\n *\n * On every click, sample the most recent `seconds` timer\n *\n * ```ts\n * import { fromEvent, interval, sample } from 'valdi_rxjs';\n *\n * const seconds = interval(1000);\n * const clicks = fromEvent(document, 'click');\n * const result = seconds.pipe(sample(clicks));\n *\n * result.subscribe(x => console.log(x));\n * ```\n *\n * @see {@link audit}\n * @see {@link debounce}\n * @see {@link sampleTime}\n * @see {@link throttle}\n *\n * @param notifier The Observable to use for sampling the\n * source Observable.\n * @return A function that returns an Observable that emits the results of\n * sampling the values emitted by the source Observable whenever the notifier\n * Observable emits value or completes.\n */\nexport function sample<T>(notifier: Observable<any>): MonoTypeOperatorFunction<T> {\n  return operate((source, subscriber) => {\n    let hasValue = false;\n    let lastValue: T | null = null;\n    source.subscribe(\n      createOperatorSubscriber(subscriber, (value) => {\n        hasValue = true;\n        lastValue = value;\n      })\n    );\n    notifier.subscribe(\n      createOperatorSubscriber(\n        subscriber,\n        () => {\n          if (hasValue) {\n            hasValue = false;\n            const value = lastValue!;\n            lastValue = null;\n            subscriber.next(value);\n          }\n        },\n        noop\n      )\n    );\n  });\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/share.ts",
    "content": "import { Observable } from '../Observable';\nimport { from } from '../observable/from';\nimport { take } from './take';\nimport { Subject } from '../Subject';\nimport { SafeSubscriber } from '../Subscriber';\nimport { Subscription } from '../Subscription';\nimport { MonoTypeOperatorFunction, SubjectLike } from '../types';\nimport { operate } from '../util/lift';\n\nexport interface ShareConfig<T> {\n  /**\n   * The factory used to create the subject that will connect the source observable to\n   * multicast consumers.\n   */\n  connector?: () => SubjectLike<T>;\n  /**\n   * If true, the resulting observable will reset internal state on error from source and return to a \"cold\" state. This\n   * allows the resulting observable to be \"retried\" in the event of an error.\n   * If false, when an error comes from the source it will push the error into the connecting subject, and the subject\n   * will remain the connecting subject, meaning the resulting observable will not go \"cold\" again, and subsequent retries\n   * or resubscriptions will resubscribe to that same subject. In all cases, RxJS subjects will emit the same error again, however\n   * {@link ReplaySubject} will also push its buffered values before pushing the error.\n   * It is also possible to pass a notifier factory returning an observable instead which grants more fine-grained\n   * control over how and when the reset should happen. This allows behaviors like conditional or delayed resets.\n   */\n  resetOnError?: boolean | ((error: any) => Observable<any>);\n  /**\n   * If true, the resulting observable will reset internal state on completion from source and return to a \"cold\" state. This\n   * allows the resulting observable to be \"repeated\" after it is done.\n   * If false, when the source completes, it will push the completion through the connecting subject, and the subject\n   * will remain the connecting subject, meaning the resulting observable will not go \"cold\" again, and subsequent repeats\n   * or resubscriptions will resubscribe to that same subject.\n   * It is also possible to pass a notifier factory returning an observable instead which grants more fine-grained\n   * control over how and when the reset should happen. This allows behaviors like conditional or delayed resets.\n   */\n  resetOnComplete?: boolean | (() => Observable<any>);\n  /**\n   * If true, when the number of subscribers to the resulting observable reaches zero due to those subscribers unsubscribing, the\n   * internal state will be reset and the resulting observable will return to a \"cold\" state. This means that the next\n   * time the resulting observable is subscribed to, a new subject will be created and the source will be subscribed to\n   * again.\n   * If false, when the number of subscribers to the resulting observable reaches zero due to unsubscription, the subject\n   * will remain connected to the source, and new subscriptions to the result will be connected through that same subject.\n   * It is also possible to pass a notifier factory returning an observable instead which grants more fine-grained\n   * control over how and when the reset should happen. This allows behaviors like conditional or delayed resets.\n   */\n  resetOnRefCountZero?: boolean | (() => Observable<any>);\n}\n\nexport function share<T>(): MonoTypeOperatorFunction<T>;\n\nexport function share<T>(options: ShareConfig<T>): MonoTypeOperatorFunction<T>;\n\n/**\n * Returns a new Observable that multicasts (shares) the original Observable. As long as there is at least one\n * Subscriber this Observable will be subscribed and emitting data. When all subscribers have unsubscribed it will\n * unsubscribe from the source Observable. Because the Observable is multicasting it makes the stream `hot`.\n * This is an alias for `multicast(() => new Subject()), refCount()`.\n *\n * The subscription to the underlying source Observable can be reset (unsubscribe and resubscribe for new subscribers),\n * if the subscriber count to the shared observable drops to 0, or if the source Observable errors or completes. It is\n * possible to use notifier factories for the resets to allow for behaviors like conditional or delayed resets. Please\n * note that resetting on error or complete of the source Observable does not behave like a transparent retry or restart\n * of the source because the error or complete will be forwarded to all subscribers and their subscription will be\n * closed. Only new subscribers after a reset on error or complete happened will cause a fresh subscription to the\n * source. To achieve transparent retries or restarts pipe the source through appropriate operators before sharing.\n *\n * ![](share.png)\n *\n * ## Example\n *\n * Generate new multicast Observable from the `source` Observable value\n *\n * ```ts\n * import { interval, tap, map, take, share } from 'valdi_rxjs';\n *\n * const source = interval(1000).pipe(\n *   tap(x => console.log('Processing: ', x)),\n *   map(x => x * x),\n *   take(6),\n *   share()\n * );\n *\n * source.subscribe(x => console.log('subscription 1: ', x));\n * source.subscribe(x => console.log('subscription 2: ', x));\n *\n * // Logs:\n * // Processing: 0\n * // subscription 1: 0\n * // subscription 2: 0\n * // Processing: 1\n * // subscription 1: 1\n * // subscription 2: 1\n * // Processing: 2\n * // subscription 1: 4\n * // subscription 2: 4\n * // Processing: 3\n * // subscription 1: 9\n * // subscription 2: 9\n * // Processing: 4\n * // subscription 1: 16\n * // subscription 2: 16\n * // Processing: 5\n * // subscription 1: 25\n * // subscription 2: 25\n * ```\n *\n * ## Example with notifier factory: Delayed reset\n *\n * ```ts\n * import { interval, take, share, timer } from 'valdi_rxjs';\n *\n * const source = interval(1000).pipe(\n *   take(3),\n *   share({\n *     resetOnRefCountZero: () => timer(1000)\n *   })\n * );\n *\n * const subscriptionOne = source.subscribe(x => console.log('subscription 1: ', x));\n * setTimeout(() => subscriptionOne.unsubscribe(), 1300);\n *\n * setTimeout(() => source.subscribe(x => console.log('subscription 2: ', x)), 1700);\n *\n * setTimeout(() => source.subscribe(x => console.log('subscription 3: ', x)), 5000);\n *\n * // Logs:\n * // subscription 1:  0\n * // (subscription 1 unsubscribes here)\n * // (subscription 2 subscribes here ~400ms later, source was not reset)\n * // subscription 2:  1\n * // subscription 2:  2\n * // (subscription 2 unsubscribes here)\n * // (subscription 3 subscribes here ~2000ms later, source did reset before)\n * // subscription 3:  0\n * // subscription 3:  1\n * // subscription 3:  2\n * ```\n *\n * @see {@link shareReplay}\n *\n * @return A function that returns an Observable that mirrors the source.\n */\nexport function share<T>(options: ShareConfig<T> = {}): MonoTypeOperatorFunction<T> {\n  const {\n    connector = () => new Subject<T>(),\n    resetOnError = true,\n    resetOnComplete = true,\n    resetOnRefCountZero = true,\n  } = options;\n  // It's necessary to use a wrapper here, as the _operator_ must be\n  // referentially transparent. Otherwise, it cannot be used in calls to the\n  // static `pipe` function - to create a partial pipeline.\n  //\n  // The _operator function_ - the function returned by the _operator_ - will\n  // not be referentially transparent - as it shares its source - but the\n  // _operator function_ is called when the complete pipeline is composed via a\n  // call to a source observable's `pipe` method - not when the static `pipe`\n  // function is called.\n  return wrapperSource => {\n    let connection: SafeSubscriber<T> | null = null;\n    let resetConnection: Subscription | null = null;\n    let subject: SubjectLike<T> | null = null;\n    let refCount = 0;\n    let hasCompleted = false;\n    let hasErrored = false;\n\n    const cancelReset = () => {\n      resetConnection?.unsubscribe();\n      resetConnection = null;\n    };\n    // Used to reset the internal state to a \"cold\"\n    // state, as though it had never been subscribed to.\n    const reset = () => {\n      cancelReset();\n      connection = subject = null;\n      hasCompleted = hasErrored = false;\n    };\n    const resetAndUnsubscribe = () => {\n      // We need to capture the connection before\n      // we reset (if we need to reset).\n      const conn = connection;\n      reset();\n      conn?.unsubscribe();\n    };\n\n    return operate<T, T>((source, subscriber) => {\n      refCount++;\n      if (!hasErrored && !hasCompleted) {\n        cancelReset();\n      }\n\n      // Create the subject if we don't have one yet. Grab a local reference to\n      // it as well, which avoids non-null assertations when using it and, if we\n      // connect to it now, then error/complete need a reference after it was\n      // reset.\n      const dest = (subject = subject ?? connector());\n\n      // Add the finalization directly to the subscriber - instead of returning it -\n      // so that the handling of the subscriber's unsubscription will be wired\n      // up _before_ the subscription to the source occurs. This is done so that\n      // the assignment to the source connection's `closed` property will be seen\n      // by synchronous firehose sources.\n      subscriber.add(() => {\n        refCount--;\n\n        // If we're resetting on refCount === 0, and it's 0, we only want to do\n        // that on \"unsubscribe\", really. Resetting on error or completion is a different\n        // configuration.\n        if (refCount === 0 && !hasErrored && !hasCompleted) {\n          resetConnection = handleReset(resetAndUnsubscribe, resetOnRefCountZero);\n        }\n      });\n\n      // The following line adds the subscription to the subscriber passed.\n      // Basically, `subscriber === dest.subscribe(subscriber)` is `true`.\n      dest.subscribe(subscriber);\n\n      if (!connection) {\n        // We need to create a subscriber here - rather than pass an observer and\n        // assign the returned subscription to connection - because it's possible\n        // for reentrant subscriptions to the shared observable to occur and in\n        // those situations we want connection to be already-assigned so that we\n        // don't create another connection to the source.\n        connection = new SafeSubscriber({\n          next: value => dest.next(value),\n          error: err => {\n            hasErrored = true;\n            cancelReset();\n            resetConnection = handleReset(reset, resetOnError, err);\n            dest.error(err);\n          },\n          complete: () => {\n            hasCompleted = true;\n            cancelReset();\n            resetConnection = handleReset(reset, resetOnComplete);\n            dest.complete();\n          },\n        });\n        from(source).subscribe(connection);\n      }\n    })(wrapperSource);\n  };\n}\n\nfunction handleReset<T extends unknown[] = never[]>(\n  reset: () => void,\n  on: boolean | ((...args: T) => Observable<any>),\n  ...args: T\n): Subscription | null {\n  if (on === true) {\n    reset();\n\n    return null;\n  }\n\n  if (on === false) {\n    return null;\n  }\n\n  return on(...args)\n    .pipe(take(1))\n    .subscribe(() => reset());\n}\n"
  },
  {
    "path": "src/valdi_modules/src/valdi/valdi_rxjs/src/operators/skipLast.ts",
    "content": "import { MonoTypeOperatorFunction } from '../types';\nimport { identity } from '../util/identity';\nimport { operate } from '../util/lift';\nimport { createOperatorSubscriber } from './OperatorSubscriber';\n\n/**\n * Skip a specified number of values before the completion of an observable.\n *\n * ![](skipLast.png)\n *\n * Returns an observable that will emit values as soon as it can, given a number of\n * skipped values. For example, if you `skipLast(3)` on a source, when the source\n * emits its fourth value, the first value the source emitted will finally be emitted\n * from the returned observable, as it is no longer part of what needs to be skipped.\n *\n * All values emitted by the result of `skipLast(N)` will be delayed by `N` emissions,\n * as each value is held in a buffer until enough values have been emitted that that\n * the buffered value may finally be sent to the consumer.\n *\n * After subscribing, unsubscribing will not result in the emission of the buffered\n * skipped values.\n *\n * ## Example\n *\n * Skip the last 2 values of an observable with many values\n *\n * ```ts\n * import { of, skipLast } from 'valdi_rxjs';\n *\n * const numbers = of(1, 2, 3, 4, 5);\n * const skipLastTwo = numbers.pipe(skipLast(2));\n * skipLastTwo.subscribe(x => console.log(x));\n *\n * // Results in:\n * // 1 2 3\n * // (4 and 5 are skipped)\n * ```\n *\n * @see {@link skip}\n * @see {@link skipUntil}\n * @see {@link skipWhile}\n * @see {@link take}\n *\n * @param skipCount Number of elements to skip from the end of the source Observable.\n * @return A function that returns an Observable that skips the last `count`\n * values emitted by the source Observable.\n */\nexport function skipLast<T>(skipCount: number): MonoTypeOperatorFunction<T> {\n  return skipCount <= 0\n    ? // For skipCounts less than or equal to zero, we are just mirroring the source.\n      identity\n    : operate((source, subscriber) => {\n        // A ring buffer to hold the values while we wait to see\n        // if we can emit it or it's part of the \"skipped\" last values.\n        // Note that it is the _same size_ as the skip count.\n        let ring: T[] = new Array(skipCount);\n        // The number of values seen so far. This is used to get\n        // the index of the current value when it arrives.\n        let seen = 0;\n        source.subscribe(\n          createOperatorSubscriber(subscriber, (value) => {\n            // Get the index of the value we have right now\n            // relative to all other values we've seen, then\n            // increment `seen`. This ensures we've moved to\n            // the next slot in our ring buffer.\n            const valueIndex = seen++;\n            if (valueIndex < skipCount) {\n              // If we haven't seen enough values to fill our buffer yet,\n              // Then we aren't to a number of seen values where we can\n              // emit anything, so let's just start by filling the ring buffer.\n              ring[valueIndex] = value;\n            } else {\n              // We are traversing over the ring array in such\n              // a way that when we get to the end, we loop back\n              // and go to the start.\n              const index = valueIndex % skipCount;\n              // Pull the oldest value out so we can emit it,\n              // and stuff the new value in it's place.\n              const oldValue = ring[index];\n              ring[index] = value;\n              // Emit the old value. It is important that this happens\n              // after we swap the value in the buffer, if it happens\n              // before we swap the value in the buffer, then a synchronous\n              // source can get the buffer out of whack.\n              subscriber.next(oldValue);\n            }\n          })\n        );\n\n        return () => {\n          // Release our values in memory\n          ring = null!;\n        };\n      });\n}\n"
  },
  {
    "path": "third-party/backward/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/bazel_features/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/boost/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/boost/WORKSPACE",
    "content": ""
  },
  {
    "path": "third-party/boost/patches/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/build_bazel_rules_android/patches/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/djinni-support-lib/src/.gitignore",
    "content": ""
  },
  {
    "path": "third-party/fmt/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/harfbuzz/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/icu/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/jsoncpp/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/libjpeg_turbo/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/libpng/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/ocmock/BUILD",
    "content": ""
  },
  {
    "path": "third-party/phmap/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/protobuf_cpp/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/resvg/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/resvg/resvg_libs/WORKSPACE",
    "content": ""
  },
  {
    "path": "third-party/rules_android_ndk/patches/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/rules_kotlin/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/rules_swift/patches/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/skia_user_config/WORKSPACE",
    "content": ""
  },
  {
    "path": "third-party/test262/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/websocketpp/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/xxhash/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/yoga/src/android/Dummy.cpp",
    "content": ""
  },
  {
    "path": "third-party/zlib/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/zlib_chromium/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/zlib_chromium/patches/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/zlib_skia/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/zoo/BUILD.bazel",
    "content": ""
  },
  {
    "path": "third-party/zstd/BUILD.bazel",
    "content": ""
  },
  {
    "path": "valdi/src/valdi/android/dummy.cpp",
    "content": ""
  },
  {
    "path": "valdi/vscode_debugger/src/test/common/sourceMapRepository.test.ts",
    "content": ""
  },
  {
    "path": "valdi/vscode_debugger/testWorkspace/web/empty2.js",
    "content": ""
  },
  {
    "path": "valdi_core/src/valdi_core/cpp/Marshalling/CppGeneratedExportedFunction.cpp",
    "content": ""
  }
]